From a722adb774af1185463a0d413ade687ac26b1cb7 Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 10 Dec 2024 02:29:19 +0800 Subject: [PATCH 001/940] core/txpool: remove unused parameter `local` (#30871) --- core/txpool/legacypool/legacypool.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 89ff86df02..70be7034ee 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -626,7 +626,7 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro // validateTx checks whether a transaction is valid according to the consensus // rules and adheres to some heuristic limits of the local node (price and size). -func (pool *LegacyPool) validateTx(tx *types.Transaction, local bool) error { +func (pool *LegacyPool) validateTx(tx *types.Transaction) error { opts := &txpool.ValidationOptionsWithState{ State: pool.currentState, @@ -682,7 +682,7 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e isLocal := local || pool.locals.containsTx(tx) // If the transaction fails basic validation, discard it - if err := pool.validateTx(tx, isLocal); err != nil { + if err := pool.validateTx(tx); err != nil { log.Trace("Discarding invalid transaction", "hash", hash, "err", err) invalidTxMeter.Mark(1) return false, err From a91dcf3ee5526bcf51b1301d67b397691baf7093 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 10 Dec 2024 10:10:49 +0800 Subject: [PATCH 002/940] core/state: enable partial-functional reader (snapshot integration pt 3) (#30650) It's a pull request based on https://github.com/ethereum/go-ethereum/pull/30643 In this pull request, the partial functional state reader is enabled if **legacy snapshot is not enabled**. The tracked flat states in pathdb will be used to serve the state retrievals, as the second implementation to fasten the state access. This pull request should be a noop change in normal cases. --- core/state/database.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/state/database.go b/core/state/database.go index fff7f1519f..faf4954650 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -179,10 +179,19 @@ func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) { // is optional and may be partially useful if it's not fully // generated. if db.snap != nil { + // If standalone state snapshot is available (hash scheme), + // then construct the legacy snap reader. snap := db.snap.Snapshot(stateRoot) if snap != nil { readers = append(readers, newFlatReader(snap)) } + } else { + // If standalone state snapshot is not available, try to construct + // the state reader with database. + reader, err := db.triedb.StateReader(stateRoot) + if err == nil { + readers = append(readers, newFlatReader(reader)) // state reader is optional + } } // Set up the trie reader, which is expected to always be available // as the gatekeeper unless the state is corrupted. From 75f847390f5a44614f26c255db67e76cb0f4c308 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Tue, 10 Dec 2024 09:43:24 +0100 Subject: [PATCH 003/940] cmd/evm: consolidate evm output switches (#30849) This PR attempts to clean up some ambiguities and quirks from recent changes to evm flag handling. This PR mainly focuses on `evm run` subcommand, to use the same flags for configuring tracing/output options as `statetest/blocktest` does. Additionally, it adds quite a lot of tests for expected outputs of the various subcommands, to avoid accidental changes. --------- Co-authored-by: Felix Lange --- cmd/evm/internal/t8ntool/transition.go | 1 - cmd/evm/main.go | 18 +- cmd/evm/runner.go | 17 +- cmd/evm/t8n_test.go | 264 ++++--- cmd/evm/testdata/evmrun/1.out.1.txt | 0 cmd/evm/testdata/evmrun/1.out.2.txt | 3 + cmd/evm/testdata/evmrun/2.out.1.txt | 0 cmd/evm/testdata/evmrun/2.out.2.txt | 6 + cmd/evm/testdata/evmrun/3.out.1.txt | 13 + cmd/evm/testdata/evmrun/3.out.2.txt | 9 + cmd/evm/testdata/evmrun/4.out.1.txt | 13 + cmd/evm/testdata/evmrun/4.out.2.txt | 6 + cmd/evm/testdata/evmrun/5.out.1.txt | 0 cmd/evm/testdata/evmrun/5.out.2.txt | 16 + cmd/evm/testdata/evmrun/6.out.1.txt | 9 + cmd/evm/testdata/evmrun/6.out.2.txt | 1 + cmd/evm/testdata/evmrun/7.out.1.txt | 9 + cmd/evm/testdata/evmrun/7.out.2.txt | 925 +++++++++++++++++++++++++ cmd/evm/testdata/evmrun/8.out.1.txt | 9 + cmd/evm/testdata/evmrun/8.out.2.txt | 916 ++++++++++++++++++++++++ cmd/evm/testdata/statetest.json | 57 ++ eth/tracers/api.go | 1 - eth/tracers/logger/logger.go | 15 +- eth/tracers/tracers_test.go | 2 +- 24 files changed, 2188 insertions(+), 122 deletions(-) create mode 100644 cmd/evm/testdata/evmrun/1.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/1.out.2.txt create mode 100644 cmd/evm/testdata/evmrun/2.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/2.out.2.txt create mode 100644 cmd/evm/testdata/evmrun/3.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/3.out.2.txt create mode 100644 cmd/evm/testdata/evmrun/4.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/4.out.2.txt create mode 100644 cmd/evm/testdata/evmrun/5.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/5.out.2.txt create mode 100644 cmd/evm/testdata/evmrun/6.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/6.out.2.txt create mode 100644 cmd/evm/testdata/evmrun/7.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/7.out.2.txt create mode 100644 cmd/evm/testdata/evmrun/8.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/8.out.2.txt create mode 100755 cmd/evm/testdata/statetest.json diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index d8665d22d3..231576fa42 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -97,7 +97,6 @@ func Transition(ctx *cli.Context) error { DisableStack: ctx.Bool(TraceDisableStackFlag.Name), EnableMemory: ctx.Bool(TraceEnableMemoryFlag.Name), EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name), - Debug: true, } getTracer = func(txIndex int, txHash common.Hash, _ *params.ChainConfig) (*tracers.Tracer, io.WriteCloser, error) { traceFile, err := os.Create(filepath.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String()))) diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 6e0345ce63..0e6f6fa5be 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -239,10 +239,20 @@ func tracerFromFlags(ctx *cli.Context) *tracing.Hooks { EnableReturnData: !ctx.Bool(TraceDisableReturnDataFlag.Name), } switch { - case ctx.Bool(TraceFlag.Name) && ctx.String(TraceFormatFlag.Name) == "struct": - return logger.NewStreamingStructLogger(config, os.Stderr).Hooks() - case ctx.Bool(TraceFlag.Name) && ctx.String(TraceFormatFlag.Name) == "json": - return logger.NewJSONLogger(config, os.Stderr) + case ctx.Bool(TraceFlag.Name): + switch format := ctx.String(TraceFormatFlag.Name); format { + case "struct": + return logger.NewStreamingStructLogger(config, os.Stderr).Hooks() + case "json": + return logger.NewJSONLogger(config, os.Stderr) + case "md", "markdown": + return logger.NewMarkdownLogger(config, os.Stderr).Hooks() + default: + fmt.Fprintf(os.Stderr, "unknown trace format: %q\n", format) + os.Exit(1) + return nil + } + // Deprecated ways of configuring tracing. case ctx.Bool(MachineFlag.Name): return logger.NewJSONLogger(config, os.Stderr) case ctx.Bool(DebugFlag.Name): diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 59ad8687d5..c67d3657e2 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -39,7 +39,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm/runtime" - "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/triedb" @@ -66,6 +65,7 @@ var runCommand = &cli.Command{ SenderFlag, ValueFlag, StatDumpFlag, + DumpFlag, }, traceFlags), } @@ -197,14 +197,6 @@ func timedExec(bench bool, execFunc func() ([]byte, uint64, error)) ([]byte, exe } func runCmd(ctx *cli.Context) error { - logconfig := &logger.Config{ - EnableMemory: !ctx.Bool(TraceDisableMemoryFlag.Name), - DisableStack: ctx.Bool(TraceDisableStackFlag.Name), - DisableStorage: ctx.Bool(TraceDisableStorageFlag.Name), - EnableReturnData: !ctx.Bool(TraceDisableReturnDataFlag.Name), - Debug: ctx.Bool(DebugFlag.Name), - } - var ( tracer *tracing.Hooks prestate *state.StateDB @@ -215,12 +207,7 @@ func runCmd(ctx *cli.Context) error { blobHashes []common.Hash // TODO (MariusVanDerWijden) implement blob hashes in state tests blobBaseFee = new(big.Int) // TODO (MariusVanDerWijden) implement blob fee in state tests ) - if ctx.Bool(MachineFlag.Name) { - tracer = logger.NewJSONLogger(logconfig, os.Stdout) - } else if ctx.Bool(DebugFlag.Name) { - tracer = logger.NewStreamingStructLogger(logconfig, os.Stderr).Hooks() - } - + tracer = tracerFromFlags(ctx) initialGas := ctx.Uint64(GasFlag.Name) genesisConfig := new(core.Genesis) genesisConfig.GasLimit = initialGas diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index 65723694f9..85caf010b3 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -341,98 +341,6 @@ func lineIterator(path string) func() (string, error) { } } -// 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 @@ -672,6 +580,88 @@ func TestB11r(t *testing.T) { } } +func TestEvmRun(t *testing.T) { + t.Parallel() + tt := cmdtest.NewTestCmd(t, nil) + for i, tc := range []struct { + input []string + wantStdout string + wantStderr string + }{ + { // json tracing + input: []string{"run", "--trace", "--trace.format=json", "6040"}, + wantStdout: "./testdata/evmrun/1.out.1.txt", + wantStderr: "./testdata/evmrun/1.out.2.txt", + }, + { // Same as above, using the deprecated --json + input: []string{"run", "--json", "6040"}, + wantStdout: "./testdata/evmrun/1.out.1.txt", + wantStderr: "./testdata/evmrun/1.out.2.txt", + }, + { // default tracing (struct) + input: []string{"run", "--trace", "0x6040"}, + wantStdout: "./testdata/evmrun/2.out.1.txt", + wantStderr: "./testdata/evmrun/2.out.2.txt", + }, + { // default tracing (struct), plus alloc-dump + input: []string{"run", "--trace", "--dump", "0x6040"}, + wantStdout: "./testdata/evmrun/3.out.1.txt", + //wantStderr: "./testdata/evmrun/3.out.2.txt", + }, + { // json-tracing, plus alloc-dump + input: []string{"run", "--trace", "--trace.format=json", "--dump", "0x6040"}, + wantStdout: "./testdata/evmrun/4.out.1.txt", + //wantStderr: "./testdata/evmrun/4.out.2.txt", + }, + { // md-tracing + input: []string{"run", "--trace", "--trace.format=md", "0x6040"}, + wantStdout: "./testdata/evmrun/5.out.1.txt", + wantStderr: "./testdata/evmrun/5.out.2.txt", + }, + { // statetest subcommand + input: []string{"statetest", "./testdata/statetest.json"}, + wantStdout: "./testdata/evmrun/6.out.1.txt", + wantStderr: "./testdata/evmrun/6.out.2.txt", + }, + { // statetest subcommand with output + input: []string{"statetest", "--trace", "--trace.format=md", "./testdata/statetest.json"}, + wantStdout: "./testdata/evmrun/7.out.1.txt", + wantStderr: "./testdata/evmrun/7.out.2.txt", + }, + { // statetest subcommand with output + input: []string{"statetest", "--trace", "--trace.format=json", "./testdata/statetest.json"}, + wantStdout: "./testdata/evmrun/8.out.1.txt", + wantStderr: "./testdata/evmrun/8.out.2.txt", + }, + } { + tt.Logf("args: go run ./cmd/evm %v\n", strings.Join(tc.input, " ")) + tt.Run("evm-test", tc.input...) + + haveStdOut := tt.Output() + tt.WaitExit() + haveStdErr := tt.StderrText() + + if have, wantFile := haveStdOut, tc.wantStdout; wantFile != "" { + want, err := os.ReadFile(wantFile) + if err != nil { + t.Fatalf("test %d: could not read expected output: %v", i, err) + } + if string(haveStdOut) != string(want) { + t.Fatalf("test %d, output wrong, have \n%v\nwant\n%v\n", i, string(have), string(want)) + } + } + if have, wantFile := haveStdErr, tc.wantStderr; wantFile != "" { + want, err := os.ReadFile(wantFile) + if err != nil { + t.Fatalf("test %d: could not read expected output: %v", i, err) + } + if have != string(want) { + t.Fatalf("test %d, output wrong\nhave %q\nwant %q\n", i, have, string(want)) + } + } + } +} + // cmpJson compares the JSON in two byte slices. func cmpJson(a, b []byte) (bool, error) { var j, j2 interface{} @@ -683,3 +673,93 @@ func cmpJson(a, b []byte) (bool, error) { } return reflect.DeepEqual(j2, j), nil } + +// TestEVMTracing is a test that checks the tracing-output from evm. +func TestEVMTracing(t *testing.T) { + t.Parallel() + tt := cmdtest.NewTestCmd(t, nil) + for i, tc := range []struct { + base string + input []string + expectedTraces []string + }{ + { + base: "./testdata/31", + input: []string{"t8n", + "--input.alloc=./testdata/31/alloc.json", "--input.txs=./testdata/31/txs.json", + "--input.env=./testdata/31/env.json", "--state.fork=Cancun", + "--trace", + }, + expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl"}, + }, + { + base: "./testdata/31", + input: []string{"t8n", + "--input.alloc=./testdata/31/alloc.json", "--input.txs=./testdata/31/txs.json", + "--input.env=./testdata/31/env.json", "--state.fork=Cancun", + "--trace.tracer", ` +{ + result: function(){ + return "hello world" + }, + fault: function(){} +}`, + }, + expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json"}, + }, + { + base: "./testdata/32", + input: []string{"t8n", + "--input.alloc=./testdata/32/alloc.json", "--input.txs=./testdata/32/txs.json", + "--input.env=./testdata/32/env.json", "--state.fork=Paris", + "--trace", "--trace.callframes", + }, + expectedTraces: []string{"trace-0-0x47806361c0fa084be3caa18afe8c48156747c01dbdfc1ee11b5aecdbe4fcf23e.jsonl"}, + }, + // TODO, make it possible to run tracers on statetests, e.g: + //{ + // base: "./testdata/31", + // input: []string{"statetest", "--trace", "--trace.tracer", `{ + // result: function(){ + // return "hello world" + // }, + // fault: function(){} + //}`, "./testdata/statetest.json"}, + // expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json"}, + // }, + } { + // Place the output somewhere we can find it + outdir := t.TempDir() + args := append(tc.input, "--output.basedir", outdir) + + tt.Run("evm-test", args...) + tt.Logf("args: go run ./cmd/evm %v\n", args) + tt.WaitExit() + //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) + } + } + } +} diff --git a/cmd/evm/testdata/evmrun/1.out.1.txt b/cmd/evm/testdata/evmrun/1.out.1.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cmd/evm/testdata/evmrun/1.out.2.txt b/cmd/evm/testdata/evmrun/1.out.2.txt new file mode 100644 index 0000000000..97d6c36c60 --- /dev/null +++ b/cmd/evm/testdata/evmrun/1.out.2.txt @@ -0,0 +1,3 @@ +{"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":0,"gas":"0x2540be3fd","gasCost":"0x0","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"STOP"} +{"output":"","gasUsed":"0x3"} diff --git a/cmd/evm/testdata/evmrun/2.out.1.txt b/cmd/evm/testdata/evmrun/2.out.1.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cmd/evm/testdata/evmrun/2.out.2.txt b/cmd/evm/testdata/evmrun/2.out.2.txt new file mode 100644 index 0000000000..4f31d87ccb --- /dev/null +++ b/cmd/evm/testdata/evmrun/2.out.2.txt @@ -0,0 +1,6 @@ +PUSH1 pc=00000000 gas=10000000000 cost=3 + +STOP pc=00000002 gas=9999999997 cost=0 +Stack: +00000000 0x40 + diff --git a/cmd/evm/testdata/evmrun/3.out.1.txt b/cmd/evm/testdata/evmrun/3.out.1.txt new file mode 100644 index 0000000000..44956f54f6 --- /dev/null +++ b/cmd/evm/testdata/evmrun/3.out.1.txt @@ -0,0 +1,13 @@ +{ + "root": "b444481d1367188172f8c6091e948aaa68bae763fd26d6b9e994306a66bf69f9", + "accounts": { + "pre(0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142)": { + "balance": "0", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x3e48ef54b89079a075f3b8fc253c657a86b110a7aed3568c1517b10edf2c3eb6", + "code": "0x6040", + "key": "0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142" + } + } +} diff --git a/cmd/evm/testdata/evmrun/3.out.2.txt b/cmd/evm/testdata/evmrun/3.out.2.txt new file mode 100644 index 0000000000..58e8cbfde7 --- /dev/null +++ b/cmd/evm/testdata/evmrun/3.out.2.txt @@ -0,0 +1,9 @@ +PUSH1 pc=00000000 gas=10000000000 cost=3 + +STOP pc=00000002 gas=9999999997 cost=0 +Stack: +00000000 0x40 + +INFO [12-03|10:37:15.827] Trie dumping started root=b44448..bf69f9 +WARN [12-03|10:37:15.827] Dump incomplete due to missing preimages missing=1 +INFO [12-03|10:37:15.827] Trie dumping complete accounts=1 elapsed="163.513µs" diff --git a/cmd/evm/testdata/evmrun/4.out.1.txt b/cmd/evm/testdata/evmrun/4.out.1.txt new file mode 100644 index 0000000000..44956f54f6 --- /dev/null +++ b/cmd/evm/testdata/evmrun/4.out.1.txt @@ -0,0 +1,13 @@ +{ + "root": "b444481d1367188172f8c6091e948aaa68bae763fd26d6b9e994306a66bf69f9", + "accounts": { + "pre(0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142)": { + "balance": "0", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x3e48ef54b89079a075f3b8fc253c657a86b110a7aed3568c1517b10edf2c3eb6", + "code": "0x6040", + "key": "0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142" + } + } +} diff --git a/cmd/evm/testdata/evmrun/4.out.2.txt b/cmd/evm/testdata/evmrun/4.out.2.txt new file mode 100644 index 0000000000..20441964e6 --- /dev/null +++ b/cmd/evm/testdata/evmrun/4.out.2.txt @@ -0,0 +1,6 @@ +{"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":0,"gas":"0x2540be3fd","gasCost":"0x0","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"STOP"} +{"output":"","gasUsed":"0x3"} +INFO [12-03|10:38:33.360] Trie dumping started root=b44448..bf69f9 +WARN [12-03|10:38:33.361] Dump incomplete due to missing preimages missing=1 +INFO [12-03|10:38:33.361] Trie dumping complete accounts=1 elapsed="240.811µs" diff --git a/cmd/evm/testdata/evmrun/5.out.1.txt b/cmd/evm/testdata/evmrun/5.out.1.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cmd/evm/testdata/evmrun/5.out.2.txt b/cmd/evm/testdata/evmrun/5.out.2.txt new file mode 100644 index 0000000000..356f731f07 --- /dev/null +++ b/cmd/evm/testdata/evmrun/5.out.2.txt @@ -0,0 +1,16 @@ +Pre-execution info: + - from: `0x000000000000000000000000000073656E646572` + - to: `0x0000000000000000000000007265636569766572` + - data: `` + - gas: `10000000000` + - value: `0` wei + +| Pc | Op | Cost | Refund | Stack | +|-------|-------------|------|-----------|-----------| +| 0 | PUSH1 | 3 | 0 | [] | +| 2 | STOP | 0 | 0 | [0x40] | + +Post-execution info: + - output: `` + - consumed gas: `3` + - error: `` diff --git a/cmd/evm/testdata/evmrun/6.out.1.txt b/cmd/evm/testdata/evmrun/6.out.1.txt new file mode 100644 index 0000000000..dc22c2ef3a --- /dev/null +++ b/cmd/evm/testdata/evmrun/6.out.1.txt @@ -0,0 +1,9 @@ +[ + { + "name": "00000006-naivefuzz-0", + "pass": false, + "stateRoot": "0xad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458", + "fork": "London", + "error": "post state root mismatch: got ad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458, want 0000000000000000000000000000000000000000000000000000000000000000" + } +] diff --git a/cmd/evm/testdata/evmrun/6.out.2.txt b/cmd/evm/testdata/evmrun/6.out.2.txt new file mode 100644 index 0000000000..2d841c4e34 --- /dev/null +++ b/cmd/evm/testdata/evmrun/6.out.2.txt @@ -0,0 +1 @@ +{"stateRoot": "0xad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458"} diff --git a/cmd/evm/testdata/evmrun/7.out.1.txt b/cmd/evm/testdata/evmrun/7.out.1.txt new file mode 100644 index 0000000000..dc22c2ef3a --- /dev/null +++ b/cmd/evm/testdata/evmrun/7.out.1.txt @@ -0,0 +1,9 @@ +[ + { + "name": "00000006-naivefuzz-0", + "pass": false, + "stateRoot": "0xad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458", + "fork": "London", + "error": "post state root mismatch: got ad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458, want 0000000000000000000000000000000000000000000000000000000000000000" + } +] diff --git a/cmd/evm/testdata/evmrun/7.out.2.txt b/cmd/evm/testdata/evmrun/7.out.2.txt new file mode 100644 index 0000000000..d81d96c6f6 --- /dev/null +++ b/cmd/evm/testdata/evmrun/7.out.2.txt @@ -0,0 +1,925 @@ +Pre-execution info: + - from: `0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B` + - to: `0x00000000000000000000000000000000000000f1` + - data: `0x81fbe24d1e33d7944b2e62ee0ff24811bbbcf8cb311e5617c80623dec4477cc14849fc042b9bbaebca9f03f66cca76c46353c5a68c2e134ef75f8c2425d9702f3a4bd3c5527e93d27579bdbd7d237eaa1c0278fce26479aaf11fb8d00e7478` + - gas: `737811` + - value: `1` wei + +| Pc | Op | Cost | Refund | Stack | +|-------|-------------|------|-----------|-----------| +| 0 | PUSH1 | 3 | 0 | [] | +| 2 | PUSH1 | 3 | 0 | [0x2] | +| 4 | SSTORE | 22100 | 0 | [0x2,0x3] | +| 5 | PUSH1 | 3 | 0 | [] | +| 7 | PUSH1 | 3 | 0 | [0x0] | +| 9 | PUSH1 | 3 | 0 | [0x0,0x0] | +| 11 | PUSH1 | 3 | 0 |[0x0,0x0,0x0] | +| 13 | PUSH1 | 3 | 0 |[0x0,0x0,0x0,0x0] | +| 15 | PUSH1 | 3 | 0 |[0x0,0x0,0x0,0x0,0x0] | +| 17 | GAS | 2 | 0 |[0x0,0x0,0x0,0x0,0x0,0x4] | +| 18 | CALLCODE | 704504 | 0 |[0x0,0x0,0x0,0x0,0x0,0x4,0xaeba5] | +| 19 | POP | 2 | 0 | [0x1] | +| 20 | PUSH32 | 3 | 0 | [] | +| 53 | PUSH1 | 3 | 0 |[0x600254506003545060016003557f7f6008545060006004557f60016004556000] | +| 55 | MSTORE | 6 | 0 |[0x600254506003545060016003557f7f6008545060006004557f60016004556000,0x0] | +| 56 | PUSH32 | 3 | 0 | [] | +| 89 | PUSH1 | 3 | 0 |[0x60045560006000600060006000606000527ff96000527f5af250600060006000] | +| 91 | MSTORE | 6 | 0 |[0x60045560006000600060006000606000527ff96000527f5af250600060006000,0x20] | +| 92 | PUSH32 | 3 | 0 | [] | +| 125 | PUSH1 | 3 | 0 |[0x606000527e60f45af45060006000600060006020527f600060f55a6020527ff1] | +| 127 | MSTORE | 6 | 0 |[0x606000527e60f45af45060006000600060006020527f600060f55a6020527ff1,0x40] | +| 128 | PUSH32 | 3 | 0 | [] | +| 161 | PUSH1 | 3 | 0 |[0x50f001075205846a44a283446020527f8ca2600060006040527f600060006004] | +| 163 | MSTORE | 6 | 0 |[0x50f001075205846a44a283446020527f8ca2600060006040527f600060006004,0x60] | +| 164 | PUSH32 | 3 | 0 | [] | +| 197 | PUSH1 | 3 | 0 |[0x5af4506040527f519930847f3b631c54a49b5f600354503260406060527f527f] | +| 199 | MSTORE | 6 | 0 |[0x5af4506040527f519930847f3b631c54a49b5f600354503260406060527f527f,0x80] | +| 200 | PUSH32 | 3 | 0 | [] | +| 233 | PUSH1 | 3 | 0 |[0x77306b60006000600060006060527f6000600c5af15060006000600060006080] | +| 235 | MSTORE | 6 | 0 |[0x77306b60006000600060006060527f6000600c5af15060006000600060006080,0xa0] | +| 236 | PUSH32 | 3 | 0 | [] | +| 269 | PUSH1 | 3 | 0 |[0x527f60f85af450506060527f066001600255606080527f035450600060005560] | +| 271 | MSTORE | 6 | 0 |[0x527f60f85af450506060527f066001600255606080527f035450600060005560,0xc0] | +| 272 | PUSH31 | 3 | 0 | [] | +| 304 | PUSH1 | 3 | 0 |[0x6060a0527f01556c3394fff4607f7f1684317b6080527f387b9f60a0527f19] | +| 306 | MSTORE | 6 | 0 |[0x6060a0527f01556c3394fff4607f7f1684317b6080527f387b9f60a0527f19,0xe0] | +| 307 | PUSH32 | 3 | 0 | [] | +| 340 | PUSH2 | 3 | 0 |[0x20700184809d60c0527f60015450011899016e6009ff60026001556000527f9f] | +| 343 | MSTORE | 6 | 0 |[0x20700184809d60c0527f60015450011899016e6009ff60026001556000527f9f,0x100] | +| 344 | PUSH32 | 3 | 0 | [] | +| 377 | PUSH2 | 3 | 0 |[0x60a05260c0527f7f600060e0527f527f9981600160045582600eff6000600060] | +| 380 | MSTORE | 6 | 0 |[0x60a05260c0527f7f600060e0527f527f9981600160045582600eff6000600060,0x120] | +| 381 | PUSH31 | 3 | 0 | [] | +| 413 | PUSH2 | 3 | 0 |[0x600060f65af45060006060e052610100527f7f6060c0527f20527e60006000] | +| 416 | MSTORE | 6 | 0 |[0x600060f65af45060006060e052610100527f7f6060c0527f20527e60006000,0x140] | +| 417 | PUSH32 | 3 | 0 | [] | +| 450 | PUSH2 | 3 | 0 |[0x6020527f60f75af4501d7f1903166660006000610120527f60610100527e6000] | +| 453 | MSTORE | 6 | 0 |[0x6020527f60f75af4501d7f1903166660006000610120527f60610100527e6000,0x160] | +| 454 | PUSH32 | 3 | 0 | [] | +| 487 | PUSH2 | 3 | 0 |[0x600060e0527f60046040527f5af150600060006000604052610140527f7f6000] | +| 490 | MSTORE | 6 | 0 |[0x600060e0527f60046040527f5af150600060006000604052610140527f7f6000,0x180] | +| 491 | PUSH32 | 3 | 0 | [] | +| 524 | PUSH2 | 3 | 0 |[0x6009610120527f5af4503c95138e5b8f610100527f7f605a6000536060610160] | +| 527 | MSTORE | 6 | 0 |[0x6009610120527f5af4503c95138e5b8f610100527f7f605a6000536060610160,0x1a0] | +| 528 | PUSH32 | 3 | 0 | [] | +| 561 | PUSH2 | 3 | 0 |[0x527f527f6031600153606b60610140527f02536010606060527f035360456061] | +| 564 | MSTORE | 6 | 0 |[0x527f527f6031600153606b60610140527f02536010606060527f035360456061,0x1c0] | +| 565 | PUSH32 | 3 | 0 | [] | +| 598 | PUSH2 | 3 | 0 |[0x120610180527f527f04536060600553600160608052610160527f7e527f6006] | +| 601 | MSTORE | 6 | 0 |[0x120610180527f527f04536060600553600160608052610160527f7e527f6006,0x1e0] | +| 602 | PUSH32 | 3 | 0 | [] | +| 635 | PUSH2 | 3 | 0 |[0x536060600753606101a0527f02600853606080610140527f527f556009536060] | +| 638 | MSTORE | 6 | 0 |[0x536060600753606101a0527f02600853606080610140527f527f556009536060,0x200] | +| 639 | PUSH32 | 3 | 0 | [] | +| 672 | PUSH2 | 3 | 0 |[0x610180527f600a53600160a06101c0527f527f600b536060600c6020527f5360] | +| 675 | MSTORE | 6 | 0 |[0x610180527f600a53600160a06101c0527f527f600b536060600c6020527f5360,0x220] | +| 676 | PUSH31 | 3 | 0 | [] | +| 708 | PUSH2 | 3 | 0 |[0x60610160527f0d53606101a0527f55606101e0527f0e60a0527f536060600f] | +| 711 | MSTORE | 6 | 0 |[0x60610160527f0d53606101a0527f55606101e0527f0e60a0527f536060600f,0x240] | +| 712 | PUSH32 | 3 | 0 | [] | +| 745 | PUSH2 | 3 | 0 |[0x536060c0527f01601053606060115360026101806101610200527fc0527f527f] | +| 748 | MSTORE | 6 | 0 |[0x536060c0527f01601053606060115360026101806101610200527fc0527f527f,0x260] | +| 749 | PUSH32 | 3 | 0 | [] | +| 782 | PUSH2 | 3 | 0 |[0x601253606040527f55601353606060c0527f60145360e0527f6000610220527f] | +| 785 | MSTORE | 6 | 0 |[0x601253606040527f55601353606060c0527f60145360e0527f6000610220527f,0x280] | +| 786 | PUSH32 | 3 | 0 | [] | +| 819 | PUSH2 | 3 | 0 |[0x6015536101e0527f60606101a0527f601653600060175360f360185360196060] | +| 822 | MSTORE | 6 | 0 |[0x6015536101e0527f60606101a0527f601653600060175360f360185360196060,0x2a0] | +| 823 | PUSH32 | 3 | 0 | [] | +| 856 | PUSH2 | 3 | 0 |[0x610240527f605260006060e052610200527f610100527f7f806101c0527f5360] | +| 859 | MSTORE | 7 | 0 |[0x610240527f605260006060e052610200527f610100527f7f806101c0527f5360,0x2c0] | +| 860 | PUSH32 | 3 | 0 | [] | +| 893 | PUSH2 | 3 | 0 |[0xf360815360610260527f8260006000f060006000600060610220527e845af450] | +| 896 | MSTORE | 6 | 0 |[0xf360815360610260527f8260006000f060006000600060610220527e845af450,0x2e0] | +| 897 | PUSH32 | 3 | 0 | [] | +| 930 | PUSH2 | 3 | 0 |[0x506000600061016101e0610280527f527f20527f60610100527e600060006003] | +| 933 | MSTORE | 6 | 0 |[0x506000600061016101e0610280527f527f20527f60610100527e600060006003,0x300] | +| 934 | PUSH32 | 3 | 0 | [] | +| 967 | PUSH2 | 3 | 0 |[0x610240527f5af15060005450c760006102a0527f6002551309f562610200527f] | +| 970 | MSTORE | 6 | 0 |[0x610240527f5af15060005450c760006102a0527f6002551309f562610200527f,0x320] | +| 971 | PUSH32 | 3 | 0 | [] | +| 1004 | PUSH2 | 3 | 0 |[0x66a486610140527f6b00610260527f1d457161016102c0527f20527f60005450] | +| 1007 | MSTORE | 6 | 0 |[0x66a486610140527f6b00610260527f1d457161016102c0527f20527f60005450,0x340] | +| 1008 | PUSH32 | 3 | 0 | [] | +| 1041 | PUSH2 | 3 | 0 |[0x1c641d373c7f60045450610220527f6000600155610280527f6102e0527f6005] | +| 1044 | MSTORE | 6 | 0 |[0x1c641d373c7f60045450610220527f6000600155610280527f6102e0527f6005,0x360] | +| 1045 | PUSH32 | 3 | 0 | [] | +| 1078 | PUSH2 | 3 | 0 |[0x54610160527f50600160025560085450610140527f60006002610240527f6103] | +| 1081 | MSTORE | 6 | 0 |[0x54610160527f50600160025560085450610140527f60006002610240527f6103,0x380] | +| 1082 | PUSH31 | 3 | 0 | [] | +| 1114 | PUSH2 | 3 | 0 |[0x527f6102a0527f557fd86000606000527e600060610180527e600060005af1] | +| 1117 | MSTORE | 6 | 0 |[0x527f6102a0527f557fd86000606000527e600060610180527e600060005af1,0x3a0] | +| 1118 | PUSH32 | 3 | 0 | [] | +| 1151 | PUSH2 | 3 | 0 |[0x508612610320527f17145147356102c0527f610260527f610160527f5198a37e] | +| 1154 | MSTORE | 6 | 0 |[0x508612610320527f17145147356102c0527f610260527f610160527f5198a37e,0x3c0] | +| 1155 | PUSH32 | 3 | 0 | [] | +| 1188 | PUSH2 | 3 | 0 |[0x127a7efa7c600052610340527f6101a0527f606020527f6102e0527f60602053] | +| 1191 | MSTORE | 7 | 0 |[0x127a7efa7c600052610340527f6101a0527f606020527f6102e0527f60602053,0x3e0] | +| 1192 | PUSH32 | 3 | 0 | [] | +| 1225 | PUSH2 | 3 | 0 |[0x60610280527ff760215360ff60610360527f225360610180527fdb6023536037] | +| 1228 | MSTORE | 6 | 0 |[0x60610280527ff760215360ff60610360527f225360610180527fdb6023536037,0x400] | +| 1229 | PUSH32 | 3 | 0 | [] | +| 1262 | PUSH2 | 3 | 0 |[0x60610300527f6101c0527f24536075606102610380527fa0527f2553609f6060] | +| 1265 | MSTORE | 6 | 0 |[0x60610300527f6101c0527f24536075606102610380527fa0527f2553609f6060,0x420] | +| 1266 | PUSH32 | 3 | 0 | [] | +| 1299 | PUSH2 | 3 | 0 |[0x40527f265360fe60275360610320527f8f60286101a0526103a0527f7f536061] | +| 1302 | MSTORE | 6 | 0 |[0x40527f265360fe60275360610320527f8f60286101a0526103a0527f7f536061,0x440] | +| 1303 | PUSH32 | 3 | 0 | [] | +| 1336 | PUSH2 | 3 | 0 |[0x1e0527f6102c0527f0b6029536060602a53600060610340527f2b536103c052] | +| 1339 | MSTORE | 6 | 0 |[0x1e0527f6102c0527f0b6029536060602a53600060610340527f2b536103c052,0x460] | +| 1340 | PUSH32 | 3 | 0 | [] | +| 1373 | PUSH2 | 3 | 0 |[0x7f6060602c53606052606060805360006061016102e0527f610200527fc05261] | +| 1376 | MSTORE | 6 | 0 |[0x7f6060602c53606052606060805360006061016102e0527f610200527fc05261,0x480] | +| 1377 | PUSH32 | 3 | 0 | [] | +| 1410 | PUSH2 | 3 | 0 |[0x36103e0527f60527f7f81536060608253602d60835360536084536060608553] | +| 1413 | MSTORE | 6 | 0 |[0x36103e0527f60527f7f81536060608253602d60835360536084536060608553,0x4a0] | +| 1414 | PUSH32 | 3 | 0 | [] | +| 1447 | PUSH2 | 3 | 0 |[0x60fd61030052610400527f7f6086610380527f536060610220527f6087536101] | +| 1450 | MSTORE | 6 | 0 |[0x60fd61030052610400527f7f6086610380527f536060610220527f6087536101,0x4c0] | +| 1451 | PUSH32 | 3 | 0 | [] | +| 1484 | PUSH2 | 3 | 0 |[0xe0527f602e608853605360610420527f89536060608a61036103a0527f20527f] | +| 1487 | MSTORE | 7 | 0 |[0xe0527f602e608853605360610420527f89536060608a61036103a0527f20527f,0x4e0] | +| 1488 | PUSH32 | 3 | 0 | [] | +| 1521 | PUSH2 | 3 | 0 |[0x53602f608b536060608c610240527f53610440527f6000608d5360f361020052] | +| 1524 | MSTORE | 6 | 0 |[0x53602f608b536060608c610240527f53610440527f6000608d5360f361020052,0x500] | +| 1525 | PUSH32 | 3 | 0 | [] | +| 1558 | PUSH2 | 3 | 0 |[0x60606103c0527f610220610340527f53608e610221610460527f536053610222] | +| 1561 | MSTORE | 6 | 0 |[0x60606103c0527f610220610340527f53608e610221610460527f536053610222,0x520] | +| 1562 | PUSH32 | 3 | 0 | [] | +| 1595 | PUSH2 | 3 | 0 |[0x536060610260527f610223536103e0527f600061022453606061610480527f03] | +| 1598 | MSTORE | 6 | 0 |[0x536060610260527f610223536103e0527f600061022453606061610480527f03,0x540] | +| 1599 | PUSH32 | 3 | 0 | [] | +| 1632 | PUSH2 | 3 | 0 |[0x60527f61022553608f61022653606061022753600061610400527f0261028061] | +| 1635 | MSTORE | 6 | 0 |[0x60527f61022553608f61022653606061022753600061610400527f0261028061,0x560] | +| 1636 | PUSH32 | 3 | 0 | [] | +| 1669 | PUSH2 | 3 | 0 |[0x4a0527f527f28536060610229610380527f53600061022a5360f561022b5360] | +| 1672 | MSTORE | 6 | 0 |[0x4a0527f527f28536060610229610380527f53600061022a5360f561022b5360,0x580] | +| 1673 | PUSH32 | 3 | 0 | [] | +| 1706 | PUSH2 | 3 | 0 |[0x610420526104c0527f7f6061022c53600061022d536102a0527f60606103a052] | +| 1709 | MSTORE | 7 | 0 |[0x610420526104c0527f7f6061022c53600061022d536102a0527f60606103a052,0x5a0] | +| 1710 | PUSH32 | 3 | 0 | [] | +| 1743 | PUSH2 | 3 | 0 |[0x7f61022e53600061026104e0527f2f610440527f536060610230536000610231] | +| 1746 | MSTORE | 6 | 0 |[0x7f61022e53600061026104e0527f2f610440527f536060610230536000610231,0x5c0] | +| 1747 | PUSH32 | 3 | 0 | [] | +| 1780 | PUSH2 | 3 | 0 |[0x53606061023253600061026103c0610500527f527fc0527f61610460527f0233] | +| 1783 | MSTORE | 6 | 0 |[0x53606061023253600061026103c0610500527f527fc0527f61610460527f0233,0x5e0] | +| 1784 | PUSH32 | 3 | 0 | [] | +| 1817 | PUSH2 | 3 | 0 |[0x53606061023453600061023553608561023653610520527f605a610237536061] | +| 1820 | MSTORE | 6 | 0 |[0x53606061023453600061023553608561023653610520527f605a610237536061,0x600] | +| 1821 | PUSH32 | 3 | 0 | [] | +| 1854 | PUSH2 | 3 | 0 |[0x3e052610480527f7ff261026102e0526038610300536053610540527f610301] | +| 1857 | MSTORE | 6 | 0 |[0x3e052610480527f7ff261026102e0526038610300536053610540527f610301,0x620] | +| 1858 | PUSH32 | 3 | 0 | [] | +| 1891 | PUSH2 | 3 | 0 |[0x536060610302536050610303536104a0527f60610400527f6161030453610560] | +| 1894 | MSTORE | 7 | 0 |[0x536060610302536050610303536104a0527f60610400527f6161030453610560,0x640] | +| 1895 | PUSH32 | 3 | 0 | [] | +| 1928 | PUSH2 | 3 | 0 |[0x527f6002610305536039610306536053610307536060616104c0527f03085360] | +| 1931 | MSTORE | 6 | 0 |[0x527f6002610305536039610306536053610307536060616104c0527f03085360,0x660] | +| 1932 | PUSH32 | 3 | 0 | [] | +| 1965 | PUSH2 | 3 | 0 |[0x5061610580527f610420527f030953606161030a53600261030b53603a61030c] | +| 1968 | MSTORE | 6 | 0 |[0x5061610580527f610420527f030953606161030a53600261030b53603a61030c,0x680] | +| 1969 | PUSH32 | 3 | 0 | [] | +| 2002 | PUSH2 | 3 | 0 |[0x536104e0527f606105a0527f5361030d53606161030e610440527f5360026103] | +| 2005 | MSTORE | 6 | 0 |[0x536104e0527f606105a0527f5361030d53606161030e610440527f5360026103,0x6a0] | +| 2006 | PUSH32 | 3 | 0 | [] | +| 2039 | PUSH2 | 3 | 0 |[0xf53603b61031053606061616105c0527f0500527f03115360006103125360f3] | +| 2042 | MSTORE | 6 | 0 |[0xf53603b61031053606061616105c0527f0500527f03115360006103125360f3,0x6c0] | +| 2043 | PUSH32 | 3 | 0 | [] | +| 2076 | PUSH2 | 3 | 0 |[0x61031353616104605260036104805360146105e0527f61048153610520527f60] | +| 2079 | MSTORE | 7 | 0 |[0x61031353616104605260036104805360146105e0527f61048153610520527f60,0x6e0] | +| 2080 | PUSH32 | 3 | 0 | [] | +| 2113 | PUSH2 | 3 | 0 |[0x60610482536000610483536060610484536000610485610600527f5360f06104] | +| 2116 | MSTORE | 6 | 0 |[0x60610482536000610483536060610484536000610485610600527f5360f06104,0x700] | +| 2117 | PUSH32 | 3 | 0 | [] | +| 2150 | PUSH2 | 3 | 0 |[0x86536060610540527f610487536000610488536060610489536000610620527f] | +| 2153 | MSTORE | 6 | 0 |[0x86536060610540527f610487536000610488536060610489536000610620527f,0x720] | +| 2154 | PUSH32 | 3 | 0 | [] | +| 2187 | PUSH2 | 3 | 0 |[0x61048a53606061048b5360006104610560527f8c53606061048d53600061048e] | +| 2190 | MSTORE | 6 | 0 |[0x61048a53606061048b5360006104610560527f8c53606061048d53600061048e,0x740] | +| 2191 | PUSH32 | 3 | 0 | [] | +| 2224 | PUSH2 | 3 | 0 |[0x610640527f53608461048f53605a6104905360f4610491536105805260606105] | +| 2227 | MSTORE | 7 | 0 |[0x610640527f53608461048f53605a6104905360f4610491536105805260606105,0x760] | +| 2228 | PUSH32 | 3 | 0 | [] | +| 2261 | PUSH2 | 3 | 0 |[0xa053605061610660527f05a15360616105a25360046105a35360926105a45360] | +| 2264 | MSTORE | 6 | 0 |[0xa053605061610660527f05a15360616105a25360046105a35360926105a45360,0x780] | +| 2265 | PUSH32 | 3 | 0 | [] | +| 2298 | PUSH2 | 3 | 0 |[0x536105a55360606105a6610680527f5360506105a75360616105a85360046105] | +| 2301 | MSTORE | 6 | 0 |[0x536105a55360606105a6610680527f5360506105a75360616105a85360046105,0x7a0] | +| 2302 | PUSH32 | 3 | 0 | [] | +| 2335 | PUSH2 | 3 | 0 |[0xa95360936105aa5360536105ab53606106a0527f616105ac5360046105ad5360] | +| 2338 | MSTORE | 6 | 0 |[0xa95360936105aa5360536105ab53606106a0527f616105ac5360046105ad5360,0x7c0] | +| 2339 | PUSH32 | 3 | 0 | [] | +| 2372 | PUSH2 | 3 | 0 |[0x946105ae5360606105af5360006105b05360f3616106c05260056106e05360b1] | +| 2375 | MSTORE | 7 | 0 |[0x946105ae5360606105af5360006105b05360f3616106c05260056106e05360b1,0x7e0] | +| 2376 | PUSH32 | 3 | 0 | [] | +| 2409 | PUSH2 | 3 | 0 |[0x6106e15360536106e25360606106e35360006106e45360616106e55360056106] | +| 2412 | MSTORE | 6 | 0 |[0x6106e15360536106e25360606106e35360006106e45360616106e55360056106,0x800] | +| 2413 | PUSH32 | 3 | 0 | [] | +| 2446 | PUSH2 | 3 | 0 |[0xe65360b26106e75360606106e85360006106e95360606106ea5360006106eb53] | +| 2449 | MSTORE | 6 | 0 |[0xe65360b26106e75360606106e85360006106e95360606106ea5360006106eb53,0x820] | +| 2450 | PUSH32 | 3 | 0 | [] | +| 2483 | PUSH2 | 3 | 0 |[0x60f56106ec5360606106ed5360006106ee5360606106ef5360006106f0536060] | +| 2486 | MSTORE | 6 | 0 |[0x60f56106ec5360606106ed5360006106ee5360606106ef5360006106f0536060,0x840] | +| 2487 | PUSH32 | 3 | 0 | [] | +| 2520 | PUSH2 | 3 | 0 |[0x6106f15360006106f25360606106f35360006106f45360606106f55360006106] | +| 2523 | MSTORE | 7 | 0 |[0x6106f15360006106f25360606106f35360006106f45360606106f55360006106,0x860] | +| 2524 | PUSH32 | 3 | 0 | [] | +| 2557 | PUSH2 | 3 | 0 |[0xf65360856106f753605a6106f85360f16106f95360506106fa5360506106fb53] | +| 2560 | MSTORE | 6 | 0 |[0xf65360856106f753605a6106f85360f16106f95360506106fa5360506106fb53,0x880] | +| 2561 | PUSH1 | 3 | 0 | [] | +| 2563 | PUSH2 | 3 | 0 | [0x61] | +| 2566 | MSTORE8 | 6 | 0 |[0x61,0x8a0] | +| 2567 | PUSH1 | 3 | 0 | [] | +| 2569 | PUSH2 | 3 | 0 | [0x6] | +| 2572 | MSTORE8 | 3 | 0 |[0x6,0x8a1] | +| 2573 | PUSH1 | 3 | 0 | [] | +| 2575 | PUSH2 | 3 | 0 | [0xfc] | +| 2578 | MSTORE8 | 3 | 0 |[0xfc,0x8a2] | +| 2579 | PUSH1 | 3 | 0 | [] | +| 2581 | PUSH2 | 3 | 0 | [0x60] | +| 2584 | MSTORE8 | 3 | 0 |[0x60,0x8a3] | +| 2585 | PUSH1 | 3 | 0 | [] | +| 2587 | PUSH2 | 3 | 0 | [0x0] | +| 2590 | MSTORE8 | 3 | 0 |[0x0,0x8a4] | +| 2591 | PUSH1 | 3 | 0 | [] | +| 2593 | PUSH2 | 3 | 0 | [0xf3] | +| 2596 | MSTORE8 | 3 | 0 |[0xf3,0x8a5] | +| 2597 | PUSH2 | 3 | 0 | [] | +| 2600 | PUSH1 | 3 | 0 | [0x8a6] | +| 2602 | PUSH1 | 3 | 0 |[0x8a6,0x0] | +| 2604 | CREATE | 32000 | 0 |[0x8a6,0x0,0x0] | +| 0 | PUSH1 | 3 | 0 | [] | +| 2 | SLOAD | 2100 | 0 | [0x2] | +| 3 | POP | 2 | 0 | [0x0] | +| 4 | PUSH1 | 3 | 0 | [] | +| 6 | SLOAD | 2100 | 0 | [0x3] | +| 7 | POP | 2 | 0 | [0x0] | +| 8 | PUSH1 | 3 | 0 | [] | +| 10 | PUSH1 | 3 | 0 | [0x1] | +| 12 | SSTORE | 20000 | 0 | [0x1,0x3] | +| 13 | PUSH32 | 3 | 0 | [] | +| 46 | PUSH1 | 3 | 0 |[0x7f6008545060006004557f600160045560006004556000600060006000600060] | +| 48 | MSTORE | 6 | 0 |[0x7f6008545060006004557f600160045560006004556000600060006000600060,0x0] | +| 49 | PUSH32 | 3 | 0 | [] | +| 82 | PUSH1 | 3 | 0 |[0xf96000527f5af250600060006000606000527e60f45af4506000600060006000] | +| 84 | MSTORE | 6 | 0 |[0xf96000527f5af250600060006000606000527e60f45af4506000600060006000,0x20] | +| 85 | PUSH32 | 3 | 0 | [] | +| 118 | PUSH1 | 3 | 0 |[0x600060f55a6020527ff150f001075205846a44a283446020527f8ca260006000] | +| 120 | MSTORE | 6 | 0 |[0x600060f55a6020527ff150f001075205846a44a283446020527f8ca260006000,0x40] | +| 121 | PUSH32 | 3 | 0 | [] | +| 154 | PUSH1 | 3 | 0 |[0x6000600060045af4506040527f519930847f3b631c54a49b5f60035450326040] | +| 156 | MSTORE | 6 | 0 |[0x6000600060045af4506040527f519930847f3b631c54a49b5f60035450326040,0x60] | +| 157 | PUSH32 | 3 | 0 | [] | +| 190 | PUSH1 | 3 | 0 |[0x527f77306b60006000600060006060527f6000600c5af1506000600060006000] | +| 192 | MSTORE | 6 | 0 |[0x527f77306b60006000600060006060527f6000600c5af1506000600060006000,0x80] | +| 193 | PUSH32 | 3 | 0 | [] | +| 226 | PUSH1 | 3 | 0 |[0x60f85af450506060527f066001600255606080527f0354506000600055600060] | +| 228 | MSTORE | 6 | 0 |[0x60f85af450506060527f066001600255606080527f0354506000600055600060,0xa0] | +| 229 | PUSH32 | 3 | 0 | [] | +| 262 | PUSH1 | 3 | 0 |[0x1556c3394fff4607f7f1684317b6080527f387b9f60a0527f1920700184809d] | +| 264 | MSTORE | 6 | 0 |[0x1556c3394fff4607f7f1684317b6080527f387b9f60a0527f1920700184809d,0xc0] | +| 265 | PUSH32 | 3 | 0 | [] | +| 298 | PUSH1 | 3 | 0 |[0x60015450011899016e6009ff60026001556000527f9f60a05260c0527f7f6000] | +| 300 | MSTORE | 6 | 0 |[0x60015450011899016e6009ff60026001556000527f9f60a05260c0527f7f6000,0xe0] | +| 301 | PUSH32 | 3 | 0 | [] | +| 334 | PUSH2 | 3 | 0 |[0x527f9981600160045582600eff600060006000600060f65af45060006060e052] | +| 337 | MSTORE | 6 | 0 |[0x527f9981600160045582600eff600060006000600060f65af45060006060e052,0x100] | +| 338 | PUSH32 | 3 | 0 | [] | +| 371 | PUSH2 | 3 | 0 |[0x7f6060c0527f20527e600060006020527f60f75af4501d7f1903166660006000] | +| 374 | MSTORE | 6 | 0 |[0x7f6060c0527f20527e600060006020527f60f75af4501d7f1903166660006000,0x120] | +| 375 | PUSH32 | 3 | 0 | [] | +| 408 | PUSH2 | 3 | 0 |[0x60610100527e6000600060e0527f60046040527f5af150600060006000604052] | +| 411 | MSTORE | 6 | 0 |[0x60610100527e6000600060e0527f60046040527f5af150600060006000604052,0x140] | +| 412 | PUSH32 | 3 | 0 | [] | +| 445 | PUSH2 | 3 | 0 |[0x7f60006009610120527f5af4503c95138e5b8f610100527f7f605a6000536060] | +| 448 | MSTORE | 6 | 0 |[0x7f60006009610120527f5af4503c95138e5b8f610100527f7f605a6000536060,0x160] | +| 449 | PUSH32 | 3 | 0 | [] | +| 482 | PUSH2 | 3 | 0 |[0x527f6031600153606b60610140527f02536010606060527f0353604560610120] | +| 485 | MSTORE | 6 | 0 |[0x527f6031600153606b60610140527f02536010606060527f0353604560610120,0x180] | +| 486 | PUSH32 | 3 | 0 | [] | +| 519 | PUSH2 | 3 | 0 |[0x527f04536060600553600160608052610160527f7e527f600653606060075360] | +| 522 | MSTORE | 6 | 0 |[0x527f04536060600553600160608052610160527f7e527f600653606060075360,0x1a0] | +| 523 | PUSH32 | 3 | 0 | [] | +| 556 | PUSH2 | 3 | 0 |[0x2600853606080610140527f527f556009536060610180527f600a53600160a0] | +| 559 | MSTORE | 6 | 0 |[0x2600853606080610140527f527f556009536060610180527f600a53600160a0,0x1c0] | +| 560 | PUSH32 | 3 | 0 | [] | +| 593 | PUSH2 | 3 | 0 |[0x527f600b536060600c6020527f53600060610160527f0d53606101a0527f5560] | +| 596 | MSTORE | 6 | 0 |[0x527f600b536060600c6020527f53600060610160527f0d53606101a0527f5560,0x1e0] | +| 597 | PUSH32 | 3 | 0 | [] | +| 630 | PUSH2 | 3 | 0 |[0xe60a0527f536060600f536060c0527f01601053606060115360026101806101] | +| 633 | MSTORE | 6 | 0 |[0xe60a0527f536060600f536060c0527f01601053606060115360026101806101,0x200] | +| 634 | PUSH32 | 3 | 0 | [] | +| 667 | PUSH2 | 3 | 0 |[0xc0527f527f601253606040527f55601353606060c0527f60145360e0527f6000] | +| 670 | MSTORE | 6 | 0 |[0xc0527f527f601253606040527f55601353606060c0527f60145360e0527f6000,0x220] | +| 671 | PUSH32 | 3 | 0 | [] | +| 704 | PUSH2 | 3 | 0 |[0x6015536101e0527f60606101a0527f601653600060175360f360185360196060] | +| 707 | MSTORE | 6 | 0 |[0x6015536101e0527f60606101a0527f601653600060175360f360185360196060,0x240] | +| 708 | PUSH32 | 3 | 0 | [] | +| 741 | PUSH2 | 3 | 0 |[0x605260006060e052610200527f610100527f7f806101c0527f5360f360815360] | +| 744 | MSTORE | 6 | 0 |[0x605260006060e052610200527f610100527f7f806101c0527f5360f360815360,0x260] | +| 745 | PUSH32 | 3 | 0 | [] | +| 778 | PUSH2 | 3 | 0 |[0x8260006000f060006000600060610220527e845af450506000600061016101e0] | +| 781 | MSTORE | 6 | 0 |[0x8260006000f060006000600060610220527e845af450506000600061016101e0,0x280] | +| 782 | PUSH32 | 3 | 0 | [] | +| 815 | PUSH2 | 3 | 0 |[0x527f20527f60610100527e600060006003610240527f5af15060005450c76000] | +| 818 | MSTORE | 6 | 0 |[0x527f20527f60610100527e600060006003610240527f5af15060005450c76000,0x2a0] | +| 819 | PUSH32 | 3 | 0 | [] | +| 852 | PUSH2 | 3 | 0 |[0x6002551309f562610200527f66a486610140527f6b00610260527f1d45716101] | +| 855 | MSTORE | 7 | 0 |[0x6002551309f562610200527f66a486610140527f6b00610260527f1d45716101,0x2c0] | +| 856 | PUSH32 | 3 | 0 | [] | +| 889 | PUSH2 | 3 | 0 |[0x20527f600054501c641d373c7f60045450610220527f6000600155610280527f] | +| 892 | MSTORE | 6 | 0 |[0x20527f600054501c641d373c7f60045450610220527f6000600155610280527f,0x2e0] | +| 893 | PUSH32 | 3 | 0 | [] | +| 926 | PUSH2 | 3 | 0 |[0x600554610160527f50600160025560085450610140527f60006002610240527f] | +| 929 | MSTORE | 6 | 0 |[0x600554610160527f50600160025560085450610140527f60006002610240527f,0x300] | +| 930 | PUSH32 | 3 | 0 | [] | +| 963 | PUSH2 | 3 | 0 |[0x6102a0527f557fd86000606000527e600060610180527e600060005af1508612] | +| 966 | MSTORE | 6 | 0 |[0x6102a0527f557fd86000606000527e600060610180527e600060005af1508612,0x320] | +| 967 | PUSH32 | 3 | 0 | [] | +| 1000 | PUSH2 | 3 | 0 |[0x17145147356102c0527f610260527f610160527f5198a37e127a7efa7c600052] | +| 1003 | MSTORE | 6 | 0 |[0x17145147356102c0527f610260527f610160527f5198a37e127a7efa7c600052,0x340] | +| 1004 | PUSH32 | 3 | 0 | [] | +| 1037 | PUSH2 | 3 | 0 |[0x6101a0527f606020527f6102e0527f6060205360610280527ff760215360ff60] | +| 1040 | MSTORE | 6 | 0 |[0x6101a0527f606020527f6102e0527f6060205360610280527ff760215360ff60,0x360] | +| 1041 | PUSH32 | 3 | 0 | [] | +| 1074 | PUSH2 | 3 | 0 |[0x225360610180527fdb602353603760610300527f6101c0527f24536075606102] | +| 1077 | MSTORE | 6 | 0 |[0x225360610180527fdb602353603760610300527f6101c0527f24536075606102,0x380] | +| 1078 | PUSH32 | 3 | 0 | [] | +| 1111 | PUSH2 | 3 | 0 |[0xa0527f2553609f606040527f265360fe60275360610320527f8f60286101a052] | +| 1114 | MSTORE | 6 | 0 |[0xa0527f2553609f606040527f265360fe60275360610320527f8f60286101a052,0x3a0] | +| 1115 | PUSH32 | 3 | 0 | [] | +| 1148 | PUSH2 | 3 | 0 |[0x7f53606101e0527f6102c0527f0b6029536060602a53600060610340527f2b53] | +| 1151 | MSTORE | 6 | 0 |[0x7f53606101e0527f6102c0527f0b6029536060602a53600060610340527f2b53,0x3c0] | +| 1152 | PUSH32 | 3 | 0 | [] | +| 1185 | PUSH2 | 3 | 0 |[0x6060602c53606052606060805360006061016102e0527f610200527fc0526103] | +| 1188 | MSTORE | 7 | 0 |[0x6060602c53606052606060805360006061016102e0527f610200527fc0526103,0x3e0] | +| 1189 | PUSH32 | 3 | 0 | [] | +| 1222 | PUSH2 | 3 | 0 |[0x60527f7f81536060608253602d6083536053608453606060855360fd61030052] | +| 1225 | MSTORE | 6 | 0 |[0x60527f7f81536060608253602d6083536053608453606060855360fd61030052,0x400] | +| 1226 | PUSH32 | 3 | 0 | [] | +| 1259 | PUSH2 | 3 | 0 |[0x7f6086610380527f536060610220527f6087536101e0527f602e608853605360] | +| 1262 | MSTORE | 6 | 0 |[0x7f6086610380527f536060610220527f6087536101e0527f602e608853605360,0x420] | +| 1263 | PUSH32 | 3 | 0 | [] | +| 1296 | PUSH2 | 3 | 0 |[0x89536060608a61036103a0527f20527f53602f608b536060608c610240527f53] | +| 1299 | MSTORE | 6 | 0 |[0x89536060608a61036103a0527f20527f53602f608b536060608c610240527f53,0x440] | +| 1300 | PUSH32 | 3 | 0 | [] | +| 1333 | PUSH2 | 3 | 0 |[0x6000608d5360f36102005260606103c0527f610220610340527f53608e610221] | +| 1336 | MSTORE | 6 | 0 |[0x6000608d5360f36102005260606103c0527f610220610340527f53608e610221,0x460] | +| 1337 | PUSH32 | 3 | 0 | [] | +| 1370 | PUSH2 | 3 | 0 |[0x536053610222536060610260527f610223536103e0527f600061022453606061] | +| 1373 | MSTORE | 6 | 0 |[0x536053610222536060610260527f610223536103e0527f600061022453606061,0x480] | +| 1374 | PUSH32 | 3 | 0 | [] | +| 1407 | PUSH2 | 3 | 0 |[0x360527f61022553608f61022653606061022753600061610400527f02610280] | +| 1410 | MSTORE | 6 | 0 |[0x360527f61022553608f61022653606061022753600061610400527f02610280,0x4a0] | +| 1411 | PUSH32 | 3 | 0 | [] | +| 1444 | PUSH2 | 3 | 0 |[0x527f28536060610229610380527f53600061022a5360f561022b536061042052] | +| 1447 | MSTORE | 6 | 0 |[0x527f28536060610229610380527f53600061022a5360f561022b536061042052,0x4c0] | +| 1448 | PUSH32 | 3 | 0 | [] | +| 1481 | PUSH2 | 3 | 0 |[0x7f6061022c53600061022d536102a0527f60606103a0527f61022e5360006102] | +| 1484 | MSTORE | 7 | 0 |[0x7f6061022c53600061022d536102a0527f60606103a0527f61022e5360006102,0x4e0] | +| 1485 | PUSH32 | 3 | 0 | [] | +| 1518 | PUSH2 | 3 | 0 |[0x2f610440527f53606061023053600061023153606061023253600061026103c0] | +| 1521 | MSTORE | 6 | 0 |[0x2f610440527f53606061023053600061023153606061023253600061026103c0,0x500] | +| 1522 | PUSH32 | 3 | 0 | [] | +| 1555 | PUSH2 | 3 | 0 |[0x527fc0527f61610460527f023353606061023453600061023553608561023653] | +| 1558 | MSTORE | 6 | 0 |[0x527fc0527f61610460527f023353606061023453600061023553608561023653,0x520] | +| 1559 | PUSH32 | 3 | 0 | [] | +| 1592 | PUSH2 | 3 | 0 |[0x605a61023753606103e052610480527f7ff261026102e0526038610300536053] | +| 1595 | MSTORE | 6 | 0 |[0x605a61023753606103e052610480527f7ff261026102e0526038610300536053,0x540] | +| 1596 | PUSH32 | 3 | 0 | [] | +| 1629 | PUSH2 | 3 | 0 |[0x610301536060610302536050610303536104a0527f60610400527f6161030453] | +| 1632 | MSTORE | 6 | 0 |[0x610301536060610302536050610303536104a0527f60610400527f6161030453,0x560] | +| 1633 | PUSH32 | 3 | 0 | [] | +| 1666 | PUSH2 | 3 | 0 |[0x6002610305536039610306536053610307536060616104c0527f030853605061] | +| 1669 | MSTORE | 6 | 0 |[0x6002610305536039610306536053610307536060616104c0527f030853605061,0x580] | +| 1670 | PUSH32 | 3 | 0 | [] | +| 1703 | PUSH2 | 3 | 0 |[0x610420527f030953606161030a53600261030b53603a61030c536104e0527f60] | +| 1706 | MSTORE | 7 | 0 |[0x610420527f030953606161030a53600261030b53603a61030c536104e0527f60,0x5a0] | +| 1707 | PUSH32 | 3 | 0 | [] | +| 1740 | PUSH2 | 3 | 0 |[0x5361030d53606161030e610440527f53600261030f53603b6103105360606161] | +| 1743 | MSTORE | 6 | 0 |[0x5361030d53606161030e610440527f53600261030f53603b6103105360606161,0x5c0] | +| 1744 | PUSH32 | 3 | 0 | [] | +| 1777 | PUSH2 | 3 | 0 |[0x500527f03115360006103125360f36103135361610460526003610480536014] | +| 1780 | MSTORE | 6 | 0 |[0x500527f03115360006103125360f36103135361610460526003610480536014,0x5e0] | +| 1781 | PUSH32 | 3 | 0 | [] | +| 1814 | PUSH2 | 3 | 0 |[0x61048153610520527f6060610482536000610483536060610484536000610485] | +| 1817 | MSTORE | 6 | 0 |[0x61048153610520527f6060610482536000610483536060610484536000610485,0x600] | +| 1818 | PUSH32 | 3 | 0 | [] | +| 1851 | PUSH2 | 3 | 0 |[0x5360f0610486536060610540527f610487536000610488536060610489536000] | +| 1854 | MSTORE | 6 | 0 |[0x5360f0610486536060610540527f610487536000610488536060610489536000,0x620] | +| 1855 | PUSH32 | 3 | 0 | [] | +| 1888 | PUSH2 | 3 | 0 |[0x61048a53606061048b5360006104610560527f8c53606061048d53600061048e] | +| 1891 | MSTORE | 7 | 0 |[0x61048a53606061048b5360006104610560527f8c53606061048d53600061048e,0x640] | +| 1892 | PUSH32 | 3 | 0 | [] | +| 1925 | PUSH2 | 3 | 0 |[0x53608461048f53605a6104905360f4610491536105805260606105a053605061] | +| 1928 | MSTORE | 6 | 0 |[0x53608461048f53605a6104905360f4610491536105805260606105a053605061,0x660] | +| 1929 | PUSH32 | 3 | 0 | [] | +| 1962 | PUSH2 | 3 | 0 |[0x5a15360616105a25360046105a35360926105a45360536105a55360606105a6] | +| 1965 | MSTORE | 6 | 0 |[0x5a15360616105a25360046105a35360926105a45360536105a55360606105a6,0x680] | +| 1966 | PUSH32 | 3 | 0 | [] | +| 1999 | PUSH2 | 3 | 0 |[0x5360506105a75360616105a85360046105a95360936105aa5360536105ab5360] | +| 2002 | MSTORE | 6 | 0 |[0x5360506105a75360616105a85360046105a95360936105aa5360536105ab5360,0x6a0] | +| 2003 | PUSH32 | 3 | 0 | [] | +| 2036 | PUSH2 | 3 | 0 |[0x616105ac5360046105ad5360946105ae5360606105af5360006105b05360f361] | +| 2039 | MSTORE | 6 | 0 |[0x616105ac5360046105ad5360946105ae5360606105af5360006105b05360f361,0x6c0] | +| 2040 | PUSH1 | 3 | 0 | [] | +| 2042 | PUSH2 | 3 | 0 | [0x5] | +| 2045 | MSTORE8 | 7 | 0 |[0x5,0x6e0] | +| 2046 | PUSH1 | 3 | 0 | [] | +| 2048 | PUSH2 | 3 | 0 | [0xb1] | +| 2051 | MSTORE8 | 3 | 0 |[0xb1,0x6e1] | +| 2052 | PUSH1 | 3 | 0 | [] | +| 2054 | PUSH2 | 3 | 0 | [0x53] | +| 2057 | MSTORE8 | 3 | 0 |[0x53,0x6e2] | +| 2058 | PUSH1 | 3 | 0 | [] | +| 2060 | PUSH2 | 3 | 0 | [0x60] | +| 2063 | MSTORE8 | 3 | 0 |[0x60,0x6e3] | +| 2064 | PUSH1 | 3 | 0 | [] | +| 2066 | PUSH2 | 3 | 0 | [0x0] | +| 2069 | MSTORE8 | 3 | 0 |[0x0,0x6e4] | +| 2070 | PUSH1 | 3 | 0 | [] | +| 2072 | PUSH2 | 3 | 0 | [0x61] | +| 2075 | MSTORE8 | 3 | 0 |[0x61,0x6e5] | +| 2076 | PUSH1 | 3 | 0 | [] | +| 2078 | PUSH2 | 3 | 0 | [0x5] | +| 2081 | MSTORE8 | 3 | 0 |[0x5,0x6e6] | +| 2082 | PUSH1 | 3 | 0 | [] | +| 2084 | PUSH2 | 3 | 0 | [0xb2] | +| 2087 | MSTORE8 | 3 | 0 |[0xb2,0x6e7] | +| 2088 | PUSH1 | 3 | 0 | [] | +| 2090 | PUSH2 | 3 | 0 | [0x60] | +| 2093 | MSTORE8 | 3 | 0 |[0x60,0x6e8] | +| 2094 | PUSH1 | 3 | 0 | [] | +| 2096 | PUSH2 | 3 | 0 | [0x0] | +| 2099 | MSTORE8 | 3 | 0 |[0x0,0x6e9] | +| 2100 | PUSH1 | 3 | 0 | [] | +| 2102 | PUSH2 | 3 | 0 | [0x60] | +| 2105 | MSTORE8 | 3 | 0 |[0x60,0x6ea] | +| 2106 | PUSH1 | 3 | 0 | [] | +| 2108 | PUSH2 | 3 | 0 | [0x0] | +| 2111 | MSTORE8 | 3 | 0 |[0x0,0x6eb] | +| 2112 | PUSH1 | 3 | 0 | [] | +| 2114 | PUSH2 | 3 | 0 | [0xf5] | +| 2117 | MSTORE8 | 3 | 0 |[0xf5,0x6ec] | +| 2118 | PUSH1 | 3 | 0 | [] | +| 2120 | PUSH2 | 3 | 0 | [0x60] | +| 2123 | MSTORE8 | 3 | 0 |[0x60,0x6ed] | +| 2124 | PUSH1 | 3 | 0 | [] | +| 2126 | PUSH2 | 3 | 0 | [0x0] | +| 2129 | MSTORE8 | 3 | 0 |[0x0,0x6ee] | +| 2130 | PUSH1 | 3 | 0 | [] | +| 2132 | PUSH2 | 3 | 0 | [0x60] | +| 2135 | MSTORE8 | 3 | 0 |[0x60,0x6ef] | +| 2136 | PUSH1 | 3 | 0 | [] | +| 2138 | PUSH2 | 3 | 0 | [0x0] | +| 2141 | MSTORE8 | 3 | 0 |[0x0,0x6f0] | +| 2142 | PUSH1 | 3 | 0 | [] | +| 2144 | PUSH2 | 3 | 0 | [0x60] | +| 2147 | MSTORE8 | 3 | 0 |[0x60,0x6f1] | +| 2148 | PUSH1 | 3 | 0 | [] | +| 2150 | PUSH2 | 3 | 0 | [0x0] | +| 2153 | MSTORE8 | 3 | 0 |[0x0,0x6f2] | +| 2154 | PUSH1 | 3 | 0 | [] | +| 2156 | PUSH2 | 3 | 0 | [0x60] | +| 2159 | MSTORE8 | 3 | 0 |[0x60,0x6f3] | +| 2160 | PUSH1 | 3 | 0 | [] | +| 2162 | PUSH2 | 3 | 0 | [0x0] | +| 2165 | MSTORE8 | 3 | 0 |[0x0,0x6f4] | +| 2166 | PUSH1 | 3 | 0 | [] | +| 2168 | PUSH2 | 3 | 0 | [0x60] | +| 2171 | MSTORE8 | 3 | 0 |[0x60,0x6f5] | +| 2172 | PUSH1 | 3 | 0 | [] | +| 2174 | PUSH2 | 3 | 0 | [0x0] | +| 2177 | MSTORE8 | 3 | 0 |[0x0,0x6f6] | +| 2178 | PUSH1 | 3 | 0 | [] | +| 2180 | PUSH2 | 3 | 0 | [0x85] | +| 2183 | MSTORE8 | 3 | 0 |[0x85,0x6f7] | +| 2184 | PUSH1 | 3 | 0 | [] | +| 2186 | PUSH2 | 3 | 0 | [0x5a] | +| 2189 | MSTORE8 | 3 | 0 |[0x5a,0x6f8] | +| 2190 | PUSH1 | 3 | 0 | [] | +| 2192 | PUSH2 | 3 | 0 | [0xf1] | +| 2195 | MSTORE8 | 3 | 0 |[0xf1,0x6f9] | +| 2196 | PUSH1 | 3 | 0 | [] | +| 2198 | PUSH2 | 3 | 0 | [0x50] | +| 2201 | MSTORE8 | 3 | 0 |[0x50,0x6fa] | +| 2202 | PUSH1 | 3 | 0 | [] | +| 2204 | PUSH2 | 3 | 0 | [0x50] | +| 2207 | MSTORE8 | 3 | 0 |[0x50,0x6fb] | +| 2208 | PUSH2 | 3 | 0 | [] | +| 2211 | PUSH1 | 3 | 0 | [0x6fc] | +| 2213 | RETURN | 0 | 0 |[0x6fc,0x0] | +| 2605 | PUSH1 | 3 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba] | +| 2607 | PUSH1 | 3 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x0] | +| 2609 | PUSH1 | 3 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x0,0x0] | +| 2611 | PUSH1 | 3 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x0,0x0,0x0] | +| 2613 | PUSH1 | 3 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x0,0x0,0x0,0x0] | +| 2615 | DUP6 | 3 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x0,0x0,0x0,0x0,0x0] | +| 2616 | GAS | 2 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x0,0x0,0x0,0x0,0x0,0x7dce2faf43218578e3fcf2ad22df9918a89e2fba] | +| 2617 | CALL | 295218 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x0,0x0,0x0,0x0,0x0,0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x4937e] | +| 0 | PUSH32 | 3 | 0 | [] | +| 33 | PUSH1 | 3 | 0 |[0x6008545060006004557f600160045560006004556000600060006000600060f9] | +| 35 | MSTORE | 6 | 0 |[0x6008545060006004557f600160045560006004556000600060006000600060f9,0x0] | +| 36 | PUSH32 | 3 | 0 | [] | +| 69 | PUSH1 | 3 | 0 |[0x5af250600060006000606000527e60f45af4506000600060006000600060f55a] | +| 71 | MSTORE | 6 | 0 |[0x5af250600060006000606000527e60f45af4506000600060006000600060f55a,0x20] | +| 72 | PUSH32 | 3 | 0 | [] | +| 105 | PUSH1 | 3 | 0 |[0xf150f001075205846a44a283446020527f8ca2600060006000600060045af450] | +| 107 | MSTORE | 6 | 0 |[0xf150f001075205846a44a283446020527f8ca2600060006000600060045af450,0x40] | +| 108 | PUSH32 | 3 | 0 | [] | +| 141 | PUSH1 | 3 | 0 |[0x519930847f3b631c54a49b5f60035450326040527f77306b6000600060006000] | +| 143 | MSTORE | 6 | 0 |[0x519930847f3b631c54a49b5f60035450326040527f77306b6000600060006000,0x60] | +| 144 | PUSH32 | 3 | 0 | [] | +| 177 | PUSH1 | 3 | 0 |[0x6000600c5af150600060006000600060f85af450506060527f06600160025560] | +| 179 | MSTORE | 6 | 0 |[0x6000600c5af150600060006000600060f85af450506060527f06600160025560,0x80] | +| 180 | PUSH32 | 3 | 0 | [] | +| 213 | PUSH1 | 3 | 0 |[0x35450600060005560006001556c3394fff4607f7f1684317b6080527f387b9f] | +| 215 | MSTORE | 6 | 0 |[0x35450600060005560006001556c3394fff4607f7f1684317b6080527f387b9f,0xa0] | +| 216 | PUSH32 | 3 | 0 | [] | +| 249 | PUSH1 | 3 | 0 |[0x1920700184809d60015450011899016e6009ff60026001556000527f9f60a052] | +| 251 | MSTORE | 6 | 0 |[0x1920700184809d60015450011899016e6009ff60026001556000527f9f60a052,0xc0] | +| 252 | PUSH32 | 3 | 0 | [] | +| 285 | PUSH1 | 3 | 0 |[0x7f6000527f9981600160045582600eff600060006000600060f65af450600060] | +| 287 | MSTORE | 6 | 0 |[0x7f6000527f9981600160045582600eff600060006000600060f65af450600060,0xe0] | +| 288 | PUSH32 | 3 | 0 | [] | +| 321 | PUSH2 | 3 | 0 |[0x6060c0527f20527e600060006020527f60f75af4501d7f190316666000600060] | +| 324 | MSTORE | 6 | 0 |[0x6060c0527f20527e600060006020527f60f75af4501d7f190316666000600060,0x100] | +| 325 | PUSH31 | 3 | 0 | [] | +| 357 | PUSH2 | 3 | 0 |[0x6000600060e0527f60046040527f5af1506000600060006040527f60006009] | +| 360 | MSTORE | 6 | 0 |[0x6000600060e0527f60046040527f5af1506000600060006040527f60006009,0x120] | +| 361 | PUSH32 | 3 | 0 | [] | +| 394 | PUSH2 | 3 | 0 |[0x5af4503c95138e5b8f610100527f7f605a6000536060527f6031600153606b60] | +| 397 | MSTORE | 6 | 0 |[0x5af4503c95138e5b8f610100527f7f605a6000536060527f6031600153606b60,0x140] | +| 398 | PUSH32 | 3 | 0 | [] | +| 431 | PUSH2 | 3 | 0 |[0x2536010606060527f0353604560610120527f04536060600553600160608052] | +| 434 | MSTORE | 6 | 0 |[0x2536010606060527f0353604560610120527f04536060600553600160608052,0x160] | +| 435 | PUSH32 | 3 | 0 | [] | +| 468 | PUSH2 | 3 | 0 |[0x7e527f60065360606007536002600853606080610140527f527f556009536060] | +| 471 | MSTORE | 6 | 0 |[0x7e527f60065360606007536002600853606080610140527f527f556009536060,0x180] | +| 472 | PUSH32 | 3 | 0 | [] | +| 505 | PUSH2 | 3 | 0 |[0x600a53600160a0527f600b536060600c6020527f53600060610160527f0d5360] | +| 508 | MSTORE | 6 | 0 |[0x600a53600160a0527f600b536060600c6020527f53600060610160527f0d5360,0x1a0] | +| 509 | PUSH32 | 3 | 0 | [] | +| 542 | PUSH2 | 3 | 0 |[0x55600e60a0527f536060600f536060c0527f0160105360606011536002610180] | +| 545 | MSTORE | 6 | 0 |[0x55600e60a0527f536060600f536060c0527f0160105360606011536002610180,0x1c0] | +| 546 | PUSH32 | 3 | 0 | [] | +| 579 | PUSH2 | 3 | 0 |[0x527f601253606040527f55601353606060c0527f60145360e0527f6000601553] | +| 582 | MSTORE | 6 | 0 |[0x527f601253606040527f55601353606060c0527f60145360e0527f6000601553,0x1e0] | +| 583 | PUSH32 | 3 | 0 | [] | +| 616 | PUSH2 | 3 | 0 |[0x60606101a0527f601653600060175360f360185360196060605260006060e052] | +| 619 | MSTORE | 6 | 0 |[0x60606101a0527f601653600060175360f360185360196060605260006060e052,0x200] | +| 620 | PUSH32 | 3 | 0 | [] | +| 653 | PUSH2 | 3 | 0 |[0x610100527f7f806101c0527f5360f3608153608260006000f060006000600060] | +| 656 | MSTORE | 6 | 0 |[0x610100527f7f806101c0527f5360f3608153608260006000f060006000600060,0x220] | +| 657 | PUSH31 | 3 | 0 | [] | +| 689 | PUSH2 | 3 | 0 |[0x845af450506000600061016101e0527f20527f60610100527e600060006003] | +| 692 | MSTORE | 6 | 0 |[0x845af450506000600061016101e0527f20527f60610100527e600060006003,0x240] | +| 693 | PUSH32 | 3 | 0 | [] | +| 726 | PUSH2 | 3 | 0 |[0x5af15060005450c760006002551309f562610200527f66a486610140527f6b00] | +| 729 | MSTORE | 6 | 0 |[0x5af15060005450c760006002551309f562610200527f66a486610140527f6b00,0x260] | +| 730 | PUSH32 | 3 | 0 | [] | +| 763 | PUSH2 | 3 | 0 |[0x1d4571610120527f600054501c641d373c7f60045450610220527f6000600155] | +| 766 | MSTORE | 6 | 0 |[0x1d4571610120527f600054501c641d373c7f60045450610220527f6000600155,0x280] | +| 767 | PUSH32 | 3 | 0 | [] | +| 800 | PUSH2 | 3 | 0 |[0x600554610160527f50600160025560085450610140527f60006002610240527f] | +| 803 | MSTORE | 6 | 0 |[0x600554610160527f50600160025560085450610140527f60006002610240527f,0x2a0] | +| 804 | PUSH32 | 3 | 0 | [] | +| 837 | PUSH2 | 3 | 0 |[0x557fd86000606000527e600060610180527e600060005af15086121714514735] | +| 840 | MSTORE | 7 | 0 |[0x557fd86000606000527e600060610180527e600060005af15086121714514735,0x2c0] | +| 841 | PUSH32 | 3 | 0 | [] | +| 874 | PUSH2 | 3 | 0 |[0x610260527f610160527f5198a37e127a7efa7c6000526101a0527f606020527f] | +| 877 | MSTORE | 6 | 0 |[0x610260527f610160527f5198a37e127a7efa7c6000526101a0527f606020527f,0x2e0] | +| 878 | PUSH32 | 3 | 0 | [] | +| 911 | PUSH2 | 3 | 0 |[0x6060205360610280527ff760215360ff60225360610180527fdb602353603760] | +| 914 | MSTORE | 6 | 0 |[0x6060205360610280527ff760215360ff60225360610180527fdb602353603760,0x300] | +| 915 | PUSH32 | 3 | 0 | [] | +| 948 | PUSH2 | 3 | 0 |[0x6101c0527f24536075606102a0527f2553609f606040527f265360fe60275360] | +| 951 | MSTORE | 6 | 0 |[0x6101c0527f24536075606102a0527f2553609f606040527f265360fe60275360,0x320] | +| 952 | PUSH32 | 3 | 0 | [] | +| 985 | PUSH2 | 3 | 0 |[0x8f60286101a0527f53606101e0527f6102c0527f0b6029536060602a53600060] | +| 988 | MSTORE | 6 | 0 |[0x8f60286101a0527f53606101e0527f6102c0527f0b6029536060602a53600060,0x340] | +| 989 | PUSH32 | 3 | 0 | [] | +| 1022 | PUSH2 | 3 | 0 |[0x2b536060602c53606052606060805360006061016102e0527f610200527fc052] | +| 1025 | MSTORE | 6 | 0 |[0x2b536060602c53606052606060805360006061016102e0527f610200527fc052,0x360] | +| 1026 | PUSH32 | 3 | 0 | [] | +| 1059 | PUSH2 | 3 | 0 |[0x7f81536060608253602d6083536053608453606060855360fd610300527f6086] | +| 1062 | MSTORE | 6 | 0 |[0x7f81536060608253602d6083536053608453606060855360fd610300527f6086,0x380] | +| 1063 | PUSH32 | 3 | 0 | [] | +| 1096 | PUSH2 | 3 | 0 |[0x536060610220527f6087536101e0527f602e60885360536089536060608a6103] | +| 1099 | MSTORE | 6 | 0 |[0x536060610220527f6087536101e0527f602e60885360536089536060608a6103,0x3a0] | +| 1100 | PUSH32 | 3 | 0 | [] | +| 1133 | PUSH2 | 3 | 0 |[0x20527f53602f608b536060608c610240527f536000608d5360f3610200526060] | +| 1136 | MSTORE | 6 | 0 |[0x20527f53602f608b536060608c610240527f536000608d5360f3610200526060,0x3c0] | +| 1137 | PUSH32 | 3 | 0 | [] | +| 1170 | PUSH2 | 3 | 0 |[0x610220610340527f53608e610221536053610222536060610260527f61022353] | +| 1173 | MSTORE | 7 | 0 |[0x610220610340527f53608e610221536053610222536060610260527f61022353,0x3e0] | +| 1174 | PUSH32 | 3 | 0 | [] | +| 1207 | PUSH2 | 3 | 0 |[0x6000610224536060610360527f61022553608f61022653606061022753600061] | +| 1210 | MSTORE | 6 | 0 |[0x6000610224536060610360527f61022553608f61022653606061022753600061,0x400] | +| 1211 | PUSH32 | 3 | 0 | [] | +| 1244 | PUSH2 | 3 | 0 |[0x2610280527f28536060610229610380527f53600061022a5360f561022b5360] | +| 1247 | MSTORE | 6 | 0 |[0x2610280527f28536060610229610380527f53600061022a5360f561022b5360,0x420] | +| 1248 | PUSH32 | 3 | 0 | [] | +| 1281 | PUSH2 | 3 | 0 |[0x6061022c53600061022d536102a0527f60606103a0527f61022e53600061022f] | +| 1284 | MSTORE | 6 | 0 |[0x6061022c53600061022d536102a0527f60606103a0527f61022e53600061022f,0x440] | +| 1285 | PUSH32 | 3 | 0 | [] | +| 1318 | PUSH2 | 3 | 0 |[0x53606061023053600061023153606061023253600061026103c0527fc0527f61] | +| 1321 | MSTORE | 6 | 0 |[0x53606061023053600061023153606061023253600061026103c0527fc0527f61,0x460] | +| 1322 | PUSH32 | 3 | 0 | [] | +| 1355 | PUSH2 | 3 | 0 |[0x23353606061023453600061023553608561023653605a61023753606103e052] | +| 1358 | MSTORE | 6 | 0 |[0x23353606061023453600061023553608561023653605a61023753606103e052,0x480] | +| 1359 | PUSH32 | 3 | 0 | [] | +| 1392 | PUSH2 | 3 | 0 |[0x7ff261026102e052603861030053605361030153606061030253605061030353] | +| 1395 | MSTORE | 6 | 0 |[0x7ff261026102e052603861030053605361030153606061030253605061030353,0x4a0] | +| 1396 | PUSH32 | 3 | 0 | [] | +| 1429 | PUSH2 | 3 | 0 |[0x60610400527f6161030453600261030553603961030653605361030753606061] | +| 1432 | MSTORE | 6 | 0 |[0x60610400527f6161030453600261030553603961030653605361030753606061,0x4c0] | +| 1433 | PUSH32 | 3 | 0 | [] | +| 1466 | PUSH2 | 3 | 0 |[0x30853605061610420527f030953606161030a53600261030b53603a61030c53] | +| 1469 | MSTORE | 7 | 0 |[0x30853605061610420527f030953606161030a53600261030b53603a61030c53,0x4e0] | +| 1470 | PUSH32 | 3 | 0 | [] | +| 1503 | PUSH2 | 3 | 0 |[0x605361030d53606161030e610440527f53600261030f53603b61031053606061] | +| 1506 | MSTORE | 6 | 0 |[0x605361030d53606161030e610440527f53600261030f53603b61031053606061,0x500] | +| 1507 | PUSH32 | 3 | 0 | [] | +| 1540 | PUSH2 | 3 | 0 |[0x3115360006103125360f3610313536161046052600361048053601461048153] | +| 1543 | MSTORE | 6 | 0 |[0x3115360006103125360f3610313536161046052600361048053601461048153,0x520] | +| 1544 | PUSH32 | 3 | 0 | [] | +| 1577 | PUSH2 | 3 | 0 |[0x60606104825360006104835360606104845360006104855360f0610486536060] | +| 1580 | MSTORE | 6 | 0 |[0x60606104825360006104835360606104845360006104855360f0610486536060,0x540] | +| 1581 | PUSH32 | 3 | 0 | [] | +| 1614 | PUSH2 | 3 | 0 |[0x61048753600061048853606061048953600061048a53606061048b5360006104] | +| 1617 | MSTORE | 6 | 0 |[0x61048753600061048853606061048953600061048a53606061048b5360006104,0x560] | +| 1618 | PUSH32 | 3 | 0 | [] | +| 1651 | PUSH2 | 3 | 0 |[0x8c53606061048d53600061048e53608461048f53605a6104905360f461049153] | +| 1654 | MSTORE | 6 | 0 |[0x8c53606061048d53600061048e53608461048f53605a6104905360f461049153,0x580] | +| 1655 | PUSH1 | 3 | 0 | [] | +| 1657 | PUSH2 | 3 | 0 | [0x60] | +| 1660 | MSTORE8 | 7 | 0 |[0x60,0x5a0] | +| 1661 | PUSH1 | 3 | 0 | [] | +| 1663 | PUSH2 | 3 | 0 | [0x50] | +| 1666 | MSTORE8 | 3 | 0 |[0x50,0x5a1] | +| 1667 | PUSH1 | 3 | 0 | [] | +| 1669 | PUSH2 | 3 | 0 | [0x61] | +| 1672 | MSTORE8 | 3 | 0 |[0x61,0x5a2] | +| 1673 | PUSH1 | 3 | 0 | [] | +| 1675 | PUSH2 | 3 | 0 | [0x4] | +| 1678 | MSTORE8 | 3 | 0 |[0x4,0x5a3] | +| 1679 | PUSH1 | 3 | 0 | [] | +| 1681 | PUSH2 | 3 | 0 | [0x92] | +| 1684 | MSTORE8 | 3 | 0 |[0x92,0x5a4] | +| 1685 | PUSH1 | 3 | 0 | [] | +| 1687 | PUSH2 | 3 | 0 | [0x53] | +| 1690 | MSTORE8 | 3 | 0 |[0x53,0x5a5] | +| 1691 | PUSH1 | 3 | 0 | [] | +| 1693 | PUSH2 | 3 | 0 | [0x60] | +| 1696 | MSTORE8 | 3 | 0 |[0x60,0x5a6] | +| 1697 | PUSH1 | 3 | 0 | [] | +| 1699 | PUSH2 | 3 | 0 | [0x50] | +| 1702 | MSTORE8 | 3 | 0 |[0x50,0x5a7] | +| 1703 | PUSH1 | 3 | 0 | [] | +| 1705 | PUSH2 | 3 | 0 | [0x61] | +| 1708 | MSTORE8 | 3 | 0 |[0x61,0x5a8] | +| 1709 | PUSH1 | 3 | 0 | [] | +| 1711 | PUSH2 | 3 | 0 | [0x4] | +| 1714 | MSTORE8 | 3 | 0 |[0x4,0x5a9] | +| 1715 | PUSH1 | 3 | 0 | [] | +| 1717 | PUSH2 | 3 | 0 | [0x93] | +| 1720 | MSTORE8 | 3 | 0 |[0x93,0x5aa] | +| 1721 | PUSH1 | 3 | 0 | [] | +| 1723 | PUSH2 | 3 | 0 | [0x53] | +| 1726 | MSTORE8 | 3 | 0 |[0x53,0x5ab] | +| 1727 | PUSH1 | 3 | 0 | [] | +| 1729 | PUSH2 | 3 | 0 | [0x61] | +| 1732 | MSTORE8 | 3 | 0 |[0x61,0x5ac] | +| 1733 | PUSH1 | 3 | 0 | [] | +| 1735 | PUSH2 | 3 | 0 | [0x4] | +| 1738 | MSTORE8 | 3 | 0 |[0x4,0x5ad] | +| 1739 | PUSH1 | 3 | 0 | [] | +| 1741 | PUSH2 | 3 | 0 | [0x94] | +| 1744 | MSTORE8 | 3 | 0 |[0x94,0x5ae] | +| 1745 | PUSH1 | 3 | 0 | [] | +| 1747 | PUSH2 | 3 | 0 | [0x60] | +| 1750 | MSTORE8 | 3 | 0 |[0x60,0x5af] | +| 1751 | PUSH1 | 3 | 0 | [] | +| 1753 | PUSH2 | 3 | 0 | [0x0] | +| 1756 | MSTORE8 | 3 | 0 |[0x0,0x5b0] | +| 1757 | PUSH1 | 3 | 0 | [] | +| 1759 | PUSH2 | 3 | 0 | [0xf3] | +| 1762 | MSTORE8 | 3 | 0 |[0xf3,0x5b1] | +| 1763 | PUSH1 | 3 | 0 | [] | +| 1765 | PUSH2 | 3 | 0 | [0x0] | +| 1768 | PUSH1 | 3 | 0 |[0x0,0x5b2] | +| 1770 | PUSH1 | 3 | 0 |[0x0,0x5b2,0x0] | +| 1772 | CREATE2 | 32276 | 0 |[0x0,0x5b2,0x0,0x0] | +| 0 | PUSH1 | 3 | 0 | [] | +| 2 | SLOAD | 2100 | 0 | [0x8] | +| 3 | POP | 2 | 0 | [0x0] | +| 4 | PUSH1 | 3 | 0 | [] | +| 6 | PUSH1 | 3 | 0 | [0x0] | +| 8 | SSTORE | 2200 | 0 | [0x0,0x4] | +| 9 | PUSH32 | 3 | 0 | [] | +| 42 | PUSH1 | 3 | 0 |[0x600160045560006004556000600060006000600060f95af25060006000600060] | +| 44 | MSTORE | 6 | 0 |[0x600160045560006004556000600060006000600060f95af25060006000600060,0x0] | +| 45 | PUSH31 | 3 | 0 | [] | +| 77 | PUSH1 | 3 | 0 |[0x60f45af4506000600060006000600060f55af150f001075205846a44a28344] | +| 79 | MSTORE | 6 | 0 |[0x60f45af4506000600060006000600060f55af150f001075205846a44a28344,0x20] | +| 80 | PUSH32 | 3 | 0 | [] | +| 113 | PUSH1 | 3 | 0 |[0x8ca2600060006000600060045af450519930847f3b631c54a49b5f6003545032] | +| 115 | MSTORE | 6 | 0 |[0x8ca2600060006000600060045af450519930847f3b631c54a49b5f6003545032,0x40] | +| 116 | PUSH32 | 3 | 0 | [] | +| 149 | PUSH1 | 3 | 0 |[0x77306b60006000600060006000600c5af150600060006000600060f85af45050] | +| 151 | MSTORE | 6 | 0 |[0x77306b60006000600060006000600c5af150600060006000600060f85af45050,0x60] | +| 152 | PUSH32 | 3 | 0 | [] | +| 185 | PUSH1 | 3 | 0 |[0x6600160025560035450600060005560006001556c3394fff4607f7f1684317b] | +| 187 | MSTORE | 6 | 0 |[0x6600160025560035450600060005560006001556c3394fff4607f7f1684317b,0x80] | +| 188 | PUSH32 | 3 | 0 | [] | +| 221 | PUSH1 | 3 | 0 |[0x387b9f1920700184809d60015450011899016e6009ff60026001556000527f9f] | +| 223 | MSTORE | 6 | 0 |[0x387b9f1920700184809d60015450011899016e6009ff60026001556000527f9f,0xa0] | +| 224 | PUSH32 | 3 | 0 | [] | +| 257 | PUSH1 | 3 | 0 |[0x6000527f9981600160045582600eff600060006000600060f65af45060006060] | +| 259 | MSTORE | 6 | 0 |[0x6000527f9981600160045582600eff600060006000600060f65af45060006060,0xc0] | +| 260 | PUSH32 | 3 | 0 | [] | +| 293 | PUSH1 | 3 | 0 |[0x20527e600060006020527f60f75af4501d7f1903166660006000600060006000] | +| 295 | MSTORE | 6 | 0 |[0x20527e600060006020527f60f75af4501d7f1903166660006000600060006000,0xe0] | +| 296 | PUSH32 | 3 | 0 | [] | +| 329 | PUSH2 | 3 | 0 |[0x60046040527f5af1506000600060006040527f600060095af4503c95138e5b8f] | +| 332 | MSTORE | 6 | 0 |[0x60046040527f5af1506000600060006040527f600060095af4503c95138e5b8f,0x100] | +| 333 | PUSH32 | 3 | 0 | [] | +| 366 | PUSH2 | 3 | 0 |[0x7f605a6000536060527f6031600153606b6002536010606060527f0353604560] | +| 369 | MSTORE | 6 | 0 |[0x7f605a6000536060527f6031600153606b6002536010606060527f0353604560,0x120] | +| 370 | PUSH32 | 3 | 0 | [] | +| 403 | PUSH2 | 3 | 0 |[0x45360606005536001606080527e527f60065360606007536002600853606080] | +| 406 | MSTORE | 6 | 0 |[0x45360606005536001606080527e527f60065360606007536002600853606080,0x140] | +| 407 | PUSH32 | 3 | 0 | [] | +| 440 | PUSH2 | 3 | 0 |[0x527f556009536060600a53600160a0527f600b536060600c6020527f53600060] | +| 443 | MSTORE | 6 | 0 |[0x527f556009536060600a53600160a0527f600b536060600c6020527f53600060,0x160] | +| 444 | PUSH32 | 3 | 0 | [] | +| 477 | PUSH2 | 3 | 0 |[0xd536055600e60a0527f536060600f536060c0527f0160105360606011536002] | +| 480 | MSTORE | 6 | 0 |[0xd536055600e60a0527f536060600f536060c0527f0160105360606011536002,0x180] | +| 481 | PUSH32 | 3 | 0 | [] | +| 514 | PUSH2 | 3 | 0 |[0x601253606040527f55601353606060c0527f60145360e0527f60006015536060] | +| 517 | MSTORE | 6 | 0 |[0x601253606040527f55601353606060c0527f60145360e0527f60006015536060,0x1a0] | +| 518 | PUSH32 | 3 | 0 | [] | +| 551 | PUSH2 | 3 | 0 |[0x601653600060175360f360185360196060605260006060e052610100527f7f80] | +| 554 | MSTORE | 6 | 0 |[0x601653600060175360f360185360196060605260006060e052610100527f7f80,0x1c0] | +| 555 | PUSH32 | 3 | 0 | [] | +| 588 | PUSH2 | 3 | 0 |[0x5360f3608153608260006000f06000600060006000845af45050600060006101] | +| 591 | MSTORE | 6 | 0 |[0x5360f3608153608260006000f06000600060006000845af45050600060006101,0x1e0] | +| 592 | PUSH32 | 3 | 0 | [] | +| 625 | PUSH2 | 3 | 0 |[0x20527f60610100527e6000600060035af15060005450c760006002551309f562] | +| 628 | MSTORE | 6 | 0 |[0x20527f60610100527e6000600060035af15060005450c760006002551309f562,0x200] | +| 629 | PUSH32 | 3 | 0 | [] | +| 662 | PUSH2 | 3 | 0 |[0x66a486610140527f6b001d4571610120527f600054501c641d373c7f60045450] | +| 665 | MSTORE | 6 | 0 |[0x66a486610140527f6b001d4571610120527f600054501c641d373c7f60045450,0x220] | +| 666 | PUSH32 | 3 | 0 | [] | +| 699 | PUSH2 | 3 | 0 |[0x6000600155600554610160527f50600160025560085450610140527f60006002] | +| 702 | MSTORE | 6 | 0 |[0x6000600155600554610160527f50600160025560085450610140527f60006002,0x240] | +| 703 | PUSH32 | 3 | 0 | [] | +| 736 | PUSH2 | 3 | 0 |[0x557fd86000606000527e600060610180527e600060005af15086121714514735] | +| 739 | MSTORE | 6 | 0 |[0x557fd86000606000527e600060610180527e600060005af15086121714514735,0x260] | +| 740 | PUSH32 | 3 | 0 | [] | +| 773 | PUSH2 | 3 | 0 |[0x610160527f5198a37e127a7efa7c6000526101a0527f606020527f6060205360] | +| 776 | MSTORE | 6 | 0 |[0x610160527f5198a37e127a7efa7c6000526101a0527f606020527f6060205360,0x280] | +| 777 | PUSH32 | 3 | 0 | [] | +| 810 | PUSH2 | 3 | 0 |[0xf760215360ff60225360610180527fdb6023536037606101c0527f2453607560] | +| 813 | MSTORE | 6 | 0 |[0xf760215360ff60225360610180527fdb6023536037606101c0527f2453607560,0x2a0] | +| 814 | PUSH32 | 3 | 0 | [] | +| 847 | PUSH2 | 3 | 0 |[0x2553609f606040527f265360fe602753608f60286101a0527f53606101e0527f] | +| 850 | MSTORE | 7 | 0 |[0x2553609f606040527f265360fe602753608f60286101a0527f53606101e0527f,0x2c0] | +| 851 | PUSH32 | 3 | 0 | [] | +| 884 | PUSH2 | 3 | 0 |[0xb6029536060602a536000602b536060602c5360605260606080536000606101] | +| 887 | MSTORE | 6 | 0 |[0xb6029536060602a536000602b536060602c5360605260606080536000606101,0x2e0] | +| 888 | PUSH32 | 3 | 0 | [] | +| 921 | PUSH2 | 3 | 0 |[0x610200527fc0527f81536060608253602d6083536053608453606060855360fd] | +| 924 | MSTORE | 6 | 0 |[0x610200527fc0527f81536060608253602d6083536053608453606060855360fd,0x300] | +| 925 | PUSH32 | 3 | 0 | [] | +| 958 | PUSH2 | 3 | 0 |[0x6086536060610220527f6087536101e0527f602e60885360536089536060608a] | +| 961 | MSTORE | 6 | 0 |[0x6086536060610220527f6087536101e0527f602e60885360536089536060608a,0x320] | +| 962 | PUSH32 | 3 | 0 | [] | +| 995 | PUSH2 | 3 | 0 |[0x53602f608b536060608c610240527f536000608d5360f3610200526060610220] | +| 998 | MSTORE | 6 | 0 |[0x53602f608b536060608c610240527f536000608d5360f3610200526060610220,0x340] | +| 999 | PUSH32 | 3 | 0 | [] | +| 1032 | PUSH2 | 3 | 0 |[0x53608e610221536053610222536060610260527f610223536000610224536060] | +| 1035 | MSTORE | 6 | 0 |[0x53608e610221536053610222536060610260527f610223536000610224536060,0x360] | +| 1036 | PUSH32 | 3 | 0 | [] | +| 1069 | PUSH2 | 3 | 0 |[0x61022553608f6102265360606102275360006102610280527f28536060610229] | +| 1072 | MSTORE | 6 | 0 |[0x61022553608f6102265360606102275360006102610280527f28536060610229,0x380] | +| 1073 | PUSH32 | 3 | 0 | [] | +| 1106 | PUSH2 | 3 | 0 |[0x53600061022a5360f561022b53606061022c53600061022d536102a0527f6060] | +| 1109 | MSTORE | 6 | 0 |[0x53600061022a5360f561022b53606061022c53600061022d536102a0527f6060,0x3a0] | +| 1110 | PUSH32 | 3 | 0 | [] | +| 1143 | PUSH2 | 3 | 0 |[0x61022e53600061022f5360606102305360006102315360606102325360006102] | +| 1146 | MSTORE | 6 | 0 |[0x61022e53600061022f5360606102305360006102315360606102325360006102,0x3c0] | +| 1147 | PUSH32 | 3 | 0 | [] | +| 1180 | PUSH2 | 3 | 0 |[0xc0527f61023353606061023453600061023553608561023653605a6102375360] | +| 1183 | MSTORE | 7 | 0 |[0xc0527f61023353606061023453600061023553608561023653605a6102375360,0x3e0] | +| 1184 | PUSH32 | 3 | 0 | [] | +| 1217 | PUSH2 | 3 | 0 |[0xf261026102e05260386103005360536103015360606103025360506103035360] | +| 1220 | MSTORE | 6 | 0 |[0xf261026102e05260386103005360536103015360606103025360506103035360,0x400] | +| 1221 | PUSH32 | 3 | 0 | [] | +| 1254 | PUSH2 | 3 | 0 |[0x6161030453600261030553603961030653605361030753606061030853605061] | +| 1257 | MSTORE | 6 | 0 |[0x6161030453600261030553603961030653605361030753606061030853605061,0x420] | +| 1258 | PUSH32 | 3 | 0 | [] | +| 1291 | PUSH2 | 3 | 0 |[0x30953606161030a53600261030b53603a61030c53605361030d53606161030e] | +| 1294 | MSTORE | 6 | 0 |[0x30953606161030a53600261030b53603a61030c53605361030d53606161030e,0x440] | +| 1295 | PUSH32 | 3 | 0 | [] | +| 1328 | PUSH2 | 3 | 0 |[0x53600261030f53603b6103105360606103115360006103125360f36103135361] | +| 1331 | MSTORE | 6 | 0 |[0x53600261030f53603b6103105360606103115360006103125360f36103135361,0x460] | +| 1332 | PUSH1 | 3 | 0 | [] | +| 1334 | PUSH2 | 3 | 0 | [0x3] | +| 1337 | MSTORE8 | 6 | 0 |[0x3,0x480] | +| 1338 | PUSH1 | 3 | 0 | [] | +| 1340 | PUSH2 | 3 | 0 | [0x14] | +| 1343 | MSTORE8 | 3 | 0 |[0x14,0x481] | +| 1344 | PUSH1 | 3 | 0 | [] | +| 1346 | PUSH2 | 3 | 0 | [0x60] | +| 1349 | MSTORE8 | 3 | 0 |[0x60,0x482] | +| 1350 | PUSH1 | 3 | 0 | [] | +| 1352 | PUSH2 | 3 | 0 | [0x0] | +| 1355 | MSTORE8 | 3 | 0 |[0x0,0x483] | +| 1356 | PUSH1 | 3 | 0 | [] | +| 1358 | PUSH2 | 3 | 0 | [0x60] | +| 1361 | MSTORE8 | 3 | 0 |[0x60,0x484] | +| 1362 | PUSH1 | 3 | 0 | [] | +| 1364 | PUSH2 | 3 | 0 | [0x0] | +| 1367 | MSTORE8 | 3 | 0 |[0x0,0x485] | +| 1368 | PUSH1 | 3 | 0 | [] | +| 1370 | PUSH2 | 3 | 0 | [0xf0] | +| 1373 | MSTORE8 | 3 | 0 |[0xf0,0x486] | +| 1374 | PUSH1 | 3 | 0 | [] | +| 1376 | PUSH2 | 3 | 0 | [0x60] | +| 1379 | MSTORE8 | 3 | 0 |[0x60,0x487] | +| 1380 | PUSH1 | 3 | 0 | [] | +| 1382 | PUSH2 | 3 | 0 | [0x0] | +| 1385 | MSTORE8 | 3 | 0 |[0x0,0x488] | +| 1386 | PUSH1 | 3 | 0 | [] | +| 1388 | PUSH2 | 3 | 0 | [0x60] | +| 1391 | MSTORE8 | 3 | 0 |[0x60,0x489] | +| 1392 | PUSH1 | 3 | 0 | [] | +| 1394 | PUSH2 | 3 | 0 | [0x0] | +| 1397 | MSTORE8 | 3 | 0 |[0x0,0x48a] | +| 1398 | PUSH1 | 3 | 0 | [] | +| 1400 | PUSH2 | 3 | 0 | [0x60] | +| 1403 | MSTORE8 | 3 | 0 |[0x60,0x48b] | +| 1404 | PUSH1 | 3 | 0 | [] | +| 1406 | PUSH2 | 3 | 0 | [0x0] | +| 1409 | MSTORE8 | 3 | 0 |[0x0,0x48c] | +| 1410 | PUSH1 | 3 | 0 | [] | +| 1412 | PUSH2 | 3 | 0 | [0x60] | +| 1415 | MSTORE8 | 3 | 0 |[0x60,0x48d] | +| 1416 | PUSH1 | 3 | 0 | [] | +| 1418 | PUSH2 | 3 | 0 | [0x0] | +| 1421 | MSTORE8 | 3 | 0 |[0x0,0x48e] | +| 1422 | PUSH1 | 3 | 0 | [] | +| 1424 | PUSH2 | 3 | 0 | [0x84] | +| 1427 | MSTORE8 | 3 | 0 |[0x84,0x48f] | +| 1428 | PUSH1 | 3 | 0 | [] | +| 1430 | PUSH2 | 3 | 0 | [0x5a] | +| 1433 | MSTORE8 | 3 | 0 |[0x5a,0x490] | +| 1434 | PUSH1 | 3 | 0 | [] | +| 1436 | PUSH2 | 3 | 0 | [0xf4] | +| 1439 | MSTORE8 | 3 | 0 |[0xf4,0x491] | +| 1440 | PUSH1 | 3 | 0 | [] | +| 1442 | PUSH2 | 3 | 0 | [0x50] | +| 1445 | MSTORE8 | 3 | 0 |[0x50,0x492] | +| 1446 | PUSH1 | 3 | 0 | [] | +| 1448 | PUSH2 | 3 | 0 | [0x50] | +| 1451 | MSTORE8 | 3 | 0 |[0x50,0x493] | +| 1452 | PUSH2 | 3 | 0 | [] | +| 1455 | PUSH1 | 3 | 0 | [0x494] | +| 1457 | RETURN | 0 | 0 |[0x494,0x0] | +| 1773 | PUSH1 | 3 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26] | +| 1775 | PUSH1 | 3 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x0] | +| 1777 | PUSH1 | 3 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x0,0x0] | +| 1779 | PUSH1 | 3 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x0,0x0,0x0] | +| 1781 | PUSH1 | 3 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x0,0x0,0x0,0x0] | +| 1783 | DUP6 | 3 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x0,0x0,0x0,0x0,0x0] | +| 1784 | GAS | 2 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x0,0x0,0x0,0x0,0x0,0x94a843a7335fc63be036fbdecc40b1365f3c5f26] | +| 1785 | CALL | 22413 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x0,0x0,0x0,0x0,0x0,0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x58ef] | +| 0 | PUSH1 | 3 | 0 | [] | +| 2 | PUSH1 | 3 | 0 | [0x1] | +| 4 | SSTORE | 20000 | 0 | [0x1,0x4] | +| 5 | PUSH1 | 3 | 0 | [] | +| 7 | PUSH1 | 3 | 0 | [0x0] | +| 9 | SSTORE | 100 | 19900 | [0x0,0x4] | +| 10 | PUSH1 | 3 | 19900 | [] | +| 12 | PUSH1 | 3 | 19900 | [0x0] | +| 14 | PUSH1 | 3 | 19900 | [0x0,0x0] | +| 16 | PUSH1 | 3 | 19900 |[0x0,0x0,0x0] | +| 18 | PUSH1 | 3 | 19900 |[0x0,0x0,0x0,0x0] | +| 20 | PUSH1 | 3 | 19900 |[0x0,0x0,0x0,0x0,0x0] | +| 22 | GAS | 2 | 19900 |[0x0,0x0,0x0,0x0,0x0,0xf9] | +| 23 | CALLCODE | 100 | 19900 |[0x0,0x0,0x0,0x0,0x0,0xf9,0x885] | +Error: out of gas: out of gas +| 1786 | POP | 2 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26,0x0] | +| 1787 | POP | 2 | 0 |[0x94a843a7335fc63be036fbdecc40b1365f3c5f26] | +| 1788 | STOP | 0 | 0 | [] | +| 2618 | POP | 2 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba,0x1] | +| 2619 | POP | 2 | 0 |[0x7dce2faf43218578e3fcf2ad22df9918a89e2fba] | +| 2620 | STOP | 0 | 0 | [] | + +Post-execution info: + - output: `` + - consumed gas: `732781` + - error: `` +{"stateRoot": "0xad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458"} diff --git a/cmd/evm/testdata/evmrun/8.out.1.txt b/cmd/evm/testdata/evmrun/8.out.1.txt new file mode 100644 index 0000000000..dc22c2ef3a --- /dev/null +++ b/cmd/evm/testdata/evmrun/8.out.1.txt @@ -0,0 +1,9 @@ +[ + { + "name": "00000006-naivefuzz-0", + "pass": false, + "stateRoot": "0xad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458", + "fork": "London", + "error": "post state root mismatch: got ad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458, want 0000000000000000000000000000000000000000000000000000000000000000" + } +] diff --git a/cmd/evm/testdata/evmrun/8.out.2.txt b/cmd/evm/testdata/evmrun/8.out.2.txt new file mode 100644 index 0000000000..3e6e162e29 --- /dev/null +++ b/cmd/evm/testdata/evmrun/8.out.2.txt @@ -0,0 +1,916 @@ +{"pc":0,"op":96,"gas":"0xb4213","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":96,"gas":"0xb4210","gasCost":"0x3","memSize":0,"stack":["0x2"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":4,"op":85,"gas":"0xb420d","gasCost":"0x5654","memSize":0,"stack":["0x2","0x3"],"depth":1,"refund":0,"opName":"SSTORE"} +{"pc":5,"op":96,"gas":"0xaebb9","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":7,"op":96,"gas":"0xaebb6","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":9,"op":96,"gas":"0xaebb3","gasCost":"0x3","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":11,"op":96,"gas":"0xaebb0","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":13,"op":96,"gas":"0xaebad","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":15,"op":96,"gas":"0xaebaa","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":17,"op":90,"gas":"0xaeba7","gasCost":"0x2","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0x4"],"depth":1,"refund":0,"opName":"GAS"} +{"pc":18,"op":242,"gas":"0xaeba5","gasCost":"0xabff8","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0x4","0xaeba5"],"depth":1,"refund":0,"opName":"CALLCODE"} +{"output":"","gasUsed":"0xf"} +{"pc":19,"op":80,"gas":"0xaeb32","gasCost":"0x2","memSize":0,"stack":["0x1"],"depth":1,"refund":0,"opName":"POP"} +{"pc":20,"op":127,"gas":"0xaeb30","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":53,"op":96,"gas":"0xaeb2d","gasCost":"0x3","memSize":0,"stack":["0x600254506003545060016003557f7f6008545060006004557f60016004556000"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":55,"op":82,"gas":"0xaeb2a","gasCost":"0x6","memSize":0,"stack":["0x600254506003545060016003557f7f6008545060006004557f60016004556000","0x0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":56,"op":127,"gas":"0xaeb24","gasCost":"0x3","memSize":32,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":89,"op":96,"gas":"0xaeb21","gasCost":"0x3","memSize":32,"stack":["0x60045560006000600060006000606000527ff96000527f5af250600060006000"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":91,"op":82,"gas":"0xaeb1e","gasCost":"0x6","memSize":32,"stack":["0x60045560006000600060006000606000527ff96000527f5af250600060006000","0x20"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":92,"op":127,"gas":"0xaeb18","gasCost":"0x3","memSize":64,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":125,"op":96,"gas":"0xaeb15","gasCost":"0x3","memSize":64,"stack":["0x606000527e60f45af45060006000600060006020527f600060f55a6020527ff1"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":127,"op":82,"gas":"0xaeb12","gasCost":"0x6","memSize":64,"stack":["0x606000527e60f45af45060006000600060006020527f600060f55a6020527ff1","0x40"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":128,"op":127,"gas":"0xaeb0c","gasCost":"0x3","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":161,"op":96,"gas":"0xaeb09","gasCost":"0x3","memSize":96,"stack":["0x50f001075205846a44a283446020527f8ca2600060006040527f600060006004"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":163,"op":82,"gas":"0xaeb06","gasCost":"0x6","memSize":96,"stack":["0x50f001075205846a44a283446020527f8ca2600060006040527f600060006004","0x60"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":164,"op":127,"gas":"0xaeb00","gasCost":"0x3","memSize":128,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":197,"op":96,"gas":"0xaeafd","gasCost":"0x3","memSize":128,"stack":["0x5af4506040527f519930847f3b631c54a49b5f600354503260406060527f527f"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":199,"op":82,"gas":"0xaeafa","gasCost":"0x6","memSize":128,"stack":["0x5af4506040527f519930847f3b631c54a49b5f600354503260406060527f527f","0x80"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":200,"op":127,"gas":"0xaeaf4","gasCost":"0x3","memSize":160,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":233,"op":96,"gas":"0xaeaf1","gasCost":"0x3","memSize":160,"stack":["0x77306b60006000600060006060527f6000600c5af15060006000600060006080"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":235,"op":82,"gas":"0xaeaee","gasCost":"0x6","memSize":160,"stack":["0x77306b60006000600060006060527f6000600c5af15060006000600060006080","0xa0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":236,"op":127,"gas":"0xaeae8","gasCost":"0x3","memSize":192,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":269,"op":96,"gas":"0xaeae5","gasCost":"0x3","memSize":192,"stack":["0x527f60f85af450506060527f066001600255606080527f035450600060005560"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":271,"op":82,"gas":"0xaeae2","gasCost":"0x6","memSize":192,"stack":["0x527f60f85af450506060527f066001600255606080527f035450600060005560","0xc0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":272,"op":126,"gas":"0xaeadc","gasCost":"0x3","memSize":224,"stack":[],"depth":1,"refund":0,"opName":"PUSH31"} +{"pc":304,"op":96,"gas":"0xaead9","gasCost":"0x3","memSize":224,"stack":["0x6060a0527f01556c3394fff4607f7f1684317b6080527f387b9f60a0527f19"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":306,"op":82,"gas":"0xaead6","gasCost":"0x6","memSize":224,"stack":["0x6060a0527f01556c3394fff4607f7f1684317b6080527f387b9f60a0527f19","0xe0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":307,"op":127,"gas":"0xaead0","gasCost":"0x3","memSize":256,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":340,"op":97,"gas":"0xaeacd","gasCost":"0x3","memSize":256,"stack":["0x20700184809d60c0527f60015450011899016e6009ff60026001556000527f9f"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":343,"op":82,"gas":"0xaeaca","gasCost":"0x6","memSize":256,"stack":["0x20700184809d60c0527f60015450011899016e6009ff60026001556000527f9f","0x100"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":344,"op":127,"gas":"0xaeac4","gasCost":"0x3","memSize":288,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":377,"op":97,"gas":"0xaeac1","gasCost":"0x3","memSize":288,"stack":["0x60a05260c0527f7f600060e0527f527f9981600160045582600eff6000600060"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":380,"op":82,"gas":"0xaeabe","gasCost":"0x6","memSize":288,"stack":["0x60a05260c0527f7f600060e0527f527f9981600160045582600eff6000600060","0x120"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":381,"op":126,"gas":"0xaeab8","gasCost":"0x3","memSize":320,"stack":[],"depth":1,"refund":0,"opName":"PUSH31"} +{"pc":413,"op":97,"gas":"0xaeab5","gasCost":"0x3","memSize":320,"stack":["0x600060f65af45060006060e052610100527f7f6060c0527f20527e60006000"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":416,"op":82,"gas":"0xaeab2","gasCost":"0x6","memSize":320,"stack":["0x600060f65af45060006060e052610100527f7f6060c0527f20527e60006000","0x140"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":417,"op":127,"gas":"0xaeaac","gasCost":"0x3","memSize":352,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":450,"op":97,"gas":"0xaeaa9","gasCost":"0x3","memSize":352,"stack":["0x6020527f60f75af4501d7f1903166660006000610120527f60610100527e6000"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":453,"op":82,"gas":"0xaeaa6","gasCost":"0x6","memSize":352,"stack":["0x6020527f60f75af4501d7f1903166660006000610120527f60610100527e6000","0x160"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":454,"op":127,"gas":"0xaeaa0","gasCost":"0x3","memSize":384,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":487,"op":97,"gas":"0xaea9d","gasCost":"0x3","memSize":384,"stack":["0x600060e0527f60046040527f5af150600060006000604052610140527f7f6000"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":490,"op":82,"gas":"0xaea9a","gasCost":"0x6","memSize":384,"stack":["0x600060e0527f60046040527f5af150600060006000604052610140527f7f6000","0x180"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":491,"op":127,"gas":"0xaea94","gasCost":"0x3","memSize":416,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":524,"op":97,"gas":"0xaea91","gasCost":"0x3","memSize":416,"stack":["0x6009610120527f5af4503c95138e5b8f610100527f7f605a6000536060610160"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":527,"op":82,"gas":"0xaea8e","gasCost":"0x6","memSize":416,"stack":["0x6009610120527f5af4503c95138e5b8f610100527f7f605a6000536060610160","0x1a0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":528,"op":127,"gas":"0xaea88","gasCost":"0x3","memSize":448,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":561,"op":97,"gas":"0xaea85","gasCost":"0x3","memSize":448,"stack":["0x527f527f6031600153606b60610140527f02536010606060527f035360456061"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":564,"op":82,"gas":"0xaea82","gasCost":"0x6","memSize":448,"stack":["0x527f527f6031600153606b60610140527f02536010606060527f035360456061","0x1c0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":565,"op":127,"gas":"0xaea7c","gasCost":"0x3","memSize":480,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":598,"op":97,"gas":"0xaea79","gasCost":"0x3","memSize":480,"stack":["0x120610180527f527f04536060600553600160608052610160527f7e527f6006"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":601,"op":82,"gas":"0xaea76","gasCost":"0x6","memSize":480,"stack":["0x120610180527f527f04536060600553600160608052610160527f7e527f6006","0x1e0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":602,"op":127,"gas":"0xaea70","gasCost":"0x3","memSize":512,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":635,"op":97,"gas":"0xaea6d","gasCost":"0x3","memSize":512,"stack":["0x536060600753606101a0527f02600853606080610140527f527f556009536060"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":638,"op":82,"gas":"0xaea6a","gasCost":"0x6","memSize":512,"stack":["0x536060600753606101a0527f02600853606080610140527f527f556009536060","0x200"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":639,"op":127,"gas":"0xaea64","gasCost":"0x3","memSize":544,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":672,"op":97,"gas":"0xaea61","gasCost":"0x3","memSize":544,"stack":["0x610180527f600a53600160a06101c0527f527f600b536060600c6020527f5360"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":675,"op":82,"gas":"0xaea5e","gasCost":"0x6","memSize":544,"stack":["0x610180527f600a53600160a06101c0527f527f600b536060600c6020527f5360","0x220"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":676,"op":126,"gas":"0xaea58","gasCost":"0x3","memSize":576,"stack":[],"depth":1,"refund":0,"opName":"PUSH31"} +{"pc":708,"op":97,"gas":"0xaea55","gasCost":"0x3","memSize":576,"stack":["0x60610160527f0d53606101a0527f55606101e0527f0e60a0527f536060600f"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":711,"op":82,"gas":"0xaea52","gasCost":"0x6","memSize":576,"stack":["0x60610160527f0d53606101a0527f55606101e0527f0e60a0527f536060600f","0x240"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":712,"op":127,"gas":"0xaea4c","gasCost":"0x3","memSize":608,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":745,"op":97,"gas":"0xaea49","gasCost":"0x3","memSize":608,"stack":["0x536060c0527f01601053606060115360026101806101610200527fc0527f527f"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":748,"op":82,"gas":"0xaea46","gasCost":"0x6","memSize":608,"stack":["0x536060c0527f01601053606060115360026101806101610200527fc0527f527f","0x260"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":749,"op":127,"gas":"0xaea40","gasCost":"0x3","memSize":640,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":782,"op":97,"gas":"0xaea3d","gasCost":"0x3","memSize":640,"stack":["0x601253606040527f55601353606060c0527f60145360e0527f6000610220527f"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":785,"op":82,"gas":"0xaea3a","gasCost":"0x6","memSize":640,"stack":["0x601253606040527f55601353606060c0527f60145360e0527f6000610220527f","0x280"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":786,"op":127,"gas":"0xaea34","gasCost":"0x3","memSize":672,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":819,"op":97,"gas":"0xaea31","gasCost":"0x3","memSize":672,"stack":["0x6015536101e0527f60606101a0527f601653600060175360f360185360196060"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":822,"op":82,"gas":"0xaea2e","gasCost":"0x6","memSize":672,"stack":["0x6015536101e0527f60606101a0527f601653600060175360f360185360196060","0x2a0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":823,"op":127,"gas":"0xaea28","gasCost":"0x3","memSize":704,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":856,"op":97,"gas":"0xaea25","gasCost":"0x3","memSize":704,"stack":["0x610240527f605260006060e052610200527f610100527f7f806101c0527f5360"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":859,"op":82,"gas":"0xaea22","gasCost":"0x7","memSize":704,"stack":["0x610240527f605260006060e052610200527f610100527f7f806101c0527f5360","0x2c0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":860,"op":127,"gas":"0xaea1b","gasCost":"0x3","memSize":736,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":893,"op":97,"gas":"0xaea18","gasCost":"0x3","memSize":736,"stack":["0xf360815360610260527f8260006000f060006000600060610220527e845af450"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":896,"op":82,"gas":"0xaea15","gasCost":"0x6","memSize":736,"stack":["0xf360815360610260527f8260006000f060006000600060610220527e845af450","0x2e0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":897,"op":127,"gas":"0xaea0f","gasCost":"0x3","memSize":768,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":930,"op":97,"gas":"0xaea0c","gasCost":"0x3","memSize":768,"stack":["0x506000600061016101e0610280527f527f20527f60610100527e600060006003"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":933,"op":82,"gas":"0xaea09","gasCost":"0x6","memSize":768,"stack":["0x506000600061016101e0610280527f527f20527f60610100527e600060006003","0x300"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":934,"op":127,"gas":"0xaea03","gasCost":"0x3","memSize":800,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":967,"op":97,"gas":"0xaea00","gasCost":"0x3","memSize":800,"stack":["0x610240527f5af15060005450c760006102a0527f6002551309f562610200527f"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":970,"op":82,"gas":"0xae9fd","gasCost":"0x6","memSize":800,"stack":["0x610240527f5af15060005450c760006102a0527f6002551309f562610200527f","0x320"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":971,"op":127,"gas":"0xae9f7","gasCost":"0x3","memSize":832,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1004,"op":97,"gas":"0xae9f4","gasCost":"0x3","memSize":832,"stack":["0x66a486610140527f6b00610260527f1d457161016102c0527f20527f60005450"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1007,"op":82,"gas":"0xae9f1","gasCost":"0x6","memSize":832,"stack":["0x66a486610140527f6b00610260527f1d457161016102c0527f20527f60005450","0x340"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1008,"op":127,"gas":"0xae9eb","gasCost":"0x3","memSize":864,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1041,"op":97,"gas":"0xae9e8","gasCost":"0x3","memSize":864,"stack":["0x1c641d373c7f60045450610220527f6000600155610280527f6102e0527f6005"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1044,"op":82,"gas":"0xae9e5","gasCost":"0x6","memSize":864,"stack":["0x1c641d373c7f60045450610220527f6000600155610280527f6102e0527f6005","0x360"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1045,"op":127,"gas":"0xae9df","gasCost":"0x3","memSize":896,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1078,"op":97,"gas":"0xae9dc","gasCost":"0x3","memSize":896,"stack":["0x54610160527f50600160025560085450610140527f60006002610240527f6103"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1081,"op":82,"gas":"0xae9d9","gasCost":"0x6","memSize":896,"stack":["0x54610160527f50600160025560085450610140527f60006002610240527f6103","0x380"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1082,"op":126,"gas":"0xae9d3","gasCost":"0x3","memSize":928,"stack":[],"depth":1,"refund":0,"opName":"PUSH31"} +{"pc":1114,"op":97,"gas":"0xae9d0","gasCost":"0x3","memSize":928,"stack":["0x527f6102a0527f557fd86000606000527e600060610180527e600060005af1"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1117,"op":82,"gas":"0xae9cd","gasCost":"0x6","memSize":928,"stack":["0x527f6102a0527f557fd86000606000527e600060610180527e600060005af1","0x3a0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1118,"op":127,"gas":"0xae9c7","gasCost":"0x3","memSize":960,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1151,"op":97,"gas":"0xae9c4","gasCost":"0x3","memSize":960,"stack":["0x508612610320527f17145147356102c0527f610260527f610160527f5198a37e"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1154,"op":82,"gas":"0xae9c1","gasCost":"0x6","memSize":960,"stack":["0x508612610320527f17145147356102c0527f610260527f610160527f5198a37e","0x3c0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1155,"op":127,"gas":"0xae9bb","gasCost":"0x3","memSize":992,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1188,"op":97,"gas":"0xae9b8","gasCost":"0x3","memSize":992,"stack":["0x127a7efa7c600052610340527f6101a0527f606020527f6102e0527f60602053"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1191,"op":82,"gas":"0xae9b5","gasCost":"0x7","memSize":992,"stack":["0x127a7efa7c600052610340527f6101a0527f606020527f6102e0527f60602053","0x3e0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1192,"op":127,"gas":"0xae9ae","gasCost":"0x3","memSize":1024,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1225,"op":97,"gas":"0xae9ab","gasCost":"0x3","memSize":1024,"stack":["0x60610280527ff760215360ff60610360527f225360610180527fdb6023536037"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1228,"op":82,"gas":"0xae9a8","gasCost":"0x6","memSize":1024,"stack":["0x60610280527ff760215360ff60610360527f225360610180527fdb6023536037","0x400"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1229,"op":127,"gas":"0xae9a2","gasCost":"0x3","memSize":1056,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1262,"op":97,"gas":"0xae99f","gasCost":"0x3","memSize":1056,"stack":["0x60610300527f6101c0527f24536075606102610380527fa0527f2553609f6060"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1265,"op":82,"gas":"0xae99c","gasCost":"0x6","memSize":1056,"stack":["0x60610300527f6101c0527f24536075606102610380527fa0527f2553609f6060","0x420"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1266,"op":127,"gas":"0xae996","gasCost":"0x3","memSize":1088,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1299,"op":97,"gas":"0xae993","gasCost":"0x3","memSize":1088,"stack":["0x40527f265360fe60275360610320527f8f60286101a0526103a0527f7f536061"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1302,"op":82,"gas":"0xae990","gasCost":"0x6","memSize":1088,"stack":["0x40527f265360fe60275360610320527f8f60286101a0526103a0527f7f536061","0x440"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1303,"op":127,"gas":"0xae98a","gasCost":"0x3","memSize":1120,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1336,"op":97,"gas":"0xae987","gasCost":"0x3","memSize":1120,"stack":["0x1e0527f6102c0527f0b6029536060602a53600060610340527f2b536103c052"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1339,"op":82,"gas":"0xae984","gasCost":"0x6","memSize":1120,"stack":["0x1e0527f6102c0527f0b6029536060602a53600060610340527f2b536103c052","0x460"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1340,"op":127,"gas":"0xae97e","gasCost":"0x3","memSize":1152,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1373,"op":97,"gas":"0xae97b","gasCost":"0x3","memSize":1152,"stack":["0x7f6060602c53606052606060805360006061016102e0527f610200527fc05261"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1376,"op":82,"gas":"0xae978","gasCost":"0x6","memSize":1152,"stack":["0x7f6060602c53606052606060805360006061016102e0527f610200527fc05261","0x480"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1377,"op":127,"gas":"0xae972","gasCost":"0x3","memSize":1184,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1410,"op":97,"gas":"0xae96f","gasCost":"0x3","memSize":1184,"stack":["0x36103e0527f60527f7f81536060608253602d60835360536084536060608553"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1413,"op":82,"gas":"0xae96c","gasCost":"0x6","memSize":1184,"stack":["0x36103e0527f60527f7f81536060608253602d60835360536084536060608553","0x4a0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1414,"op":127,"gas":"0xae966","gasCost":"0x3","memSize":1216,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1447,"op":97,"gas":"0xae963","gasCost":"0x3","memSize":1216,"stack":["0x60fd61030052610400527f7f6086610380527f536060610220527f6087536101"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1450,"op":82,"gas":"0xae960","gasCost":"0x6","memSize":1216,"stack":["0x60fd61030052610400527f7f6086610380527f536060610220527f6087536101","0x4c0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1451,"op":127,"gas":"0xae95a","gasCost":"0x3","memSize":1248,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1484,"op":97,"gas":"0xae957","gasCost":"0x3","memSize":1248,"stack":["0xe0527f602e608853605360610420527f89536060608a61036103a0527f20527f"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1487,"op":82,"gas":"0xae954","gasCost":"0x7","memSize":1248,"stack":["0xe0527f602e608853605360610420527f89536060608a61036103a0527f20527f","0x4e0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1488,"op":127,"gas":"0xae94d","gasCost":"0x3","memSize":1280,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1521,"op":97,"gas":"0xae94a","gasCost":"0x3","memSize":1280,"stack":["0x53602f608b536060608c610240527f53610440527f6000608d5360f361020052"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1524,"op":82,"gas":"0xae947","gasCost":"0x6","memSize":1280,"stack":["0x53602f608b536060608c610240527f53610440527f6000608d5360f361020052","0x500"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1525,"op":127,"gas":"0xae941","gasCost":"0x3","memSize":1312,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1558,"op":97,"gas":"0xae93e","gasCost":"0x3","memSize":1312,"stack":["0x60606103c0527f610220610340527f53608e610221610460527f536053610222"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1561,"op":82,"gas":"0xae93b","gasCost":"0x6","memSize":1312,"stack":["0x60606103c0527f610220610340527f53608e610221610460527f536053610222","0x520"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1562,"op":127,"gas":"0xae935","gasCost":"0x3","memSize":1344,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1595,"op":97,"gas":"0xae932","gasCost":"0x3","memSize":1344,"stack":["0x536060610260527f610223536103e0527f600061022453606061610480527f03"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1598,"op":82,"gas":"0xae92f","gasCost":"0x6","memSize":1344,"stack":["0x536060610260527f610223536103e0527f600061022453606061610480527f03","0x540"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1599,"op":127,"gas":"0xae929","gasCost":"0x3","memSize":1376,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1632,"op":97,"gas":"0xae926","gasCost":"0x3","memSize":1376,"stack":["0x60527f61022553608f61022653606061022753600061610400527f0261028061"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1635,"op":82,"gas":"0xae923","gasCost":"0x6","memSize":1376,"stack":["0x60527f61022553608f61022653606061022753600061610400527f0261028061","0x560"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1636,"op":127,"gas":"0xae91d","gasCost":"0x3","memSize":1408,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1669,"op":97,"gas":"0xae91a","gasCost":"0x3","memSize":1408,"stack":["0x4a0527f527f28536060610229610380527f53600061022a5360f561022b5360"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1672,"op":82,"gas":"0xae917","gasCost":"0x6","memSize":1408,"stack":["0x4a0527f527f28536060610229610380527f53600061022a5360f561022b5360","0x580"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1673,"op":127,"gas":"0xae911","gasCost":"0x3","memSize":1440,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1706,"op":97,"gas":"0xae90e","gasCost":"0x3","memSize":1440,"stack":["0x610420526104c0527f7f6061022c53600061022d536102a0527f60606103a052"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1709,"op":82,"gas":"0xae90b","gasCost":"0x7","memSize":1440,"stack":["0x610420526104c0527f7f6061022c53600061022d536102a0527f60606103a052","0x5a0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1710,"op":127,"gas":"0xae904","gasCost":"0x3","memSize":1472,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1743,"op":97,"gas":"0xae901","gasCost":"0x3","memSize":1472,"stack":["0x7f61022e53600061026104e0527f2f610440527f536060610230536000610231"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1746,"op":82,"gas":"0xae8fe","gasCost":"0x6","memSize":1472,"stack":["0x7f61022e53600061026104e0527f2f610440527f536060610230536000610231","0x5c0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1747,"op":127,"gas":"0xae8f8","gasCost":"0x3","memSize":1504,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1780,"op":97,"gas":"0xae8f5","gasCost":"0x3","memSize":1504,"stack":["0x53606061023253600061026103c0610500527f527fc0527f61610460527f0233"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1783,"op":82,"gas":"0xae8f2","gasCost":"0x6","memSize":1504,"stack":["0x53606061023253600061026103c0610500527f527fc0527f61610460527f0233","0x5e0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1784,"op":127,"gas":"0xae8ec","gasCost":"0x3","memSize":1536,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1817,"op":97,"gas":"0xae8e9","gasCost":"0x3","memSize":1536,"stack":["0x53606061023453600061023553608561023653610520527f605a610237536061"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1820,"op":82,"gas":"0xae8e6","gasCost":"0x6","memSize":1536,"stack":["0x53606061023453600061023553608561023653610520527f605a610237536061","0x600"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1821,"op":127,"gas":"0xae8e0","gasCost":"0x3","memSize":1568,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1854,"op":97,"gas":"0xae8dd","gasCost":"0x3","memSize":1568,"stack":["0x3e052610480527f7ff261026102e0526038610300536053610540527f610301"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1857,"op":82,"gas":"0xae8da","gasCost":"0x6","memSize":1568,"stack":["0x3e052610480527f7ff261026102e0526038610300536053610540527f610301","0x620"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1858,"op":127,"gas":"0xae8d4","gasCost":"0x3","memSize":1600,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1891,"op":97,"gas":"0xae8d1","gasCost":"0x3","memSize":1600,"stack":["0x536060610302536050610303536104a0527f60610400527f6161030453610560"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1894,"op":82,"gas":"0xae8ce","gasCost":"0x7","memSize":1600,"stack":["0x536060610302536050610303536104a0527f60610400527f6161030453610560","0x640"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1895,"op":127,"gas":"0xae8c7","gasCost":"0x3","memSize":1632,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1928,"op":97,"gas":"0xae8c4","gasCost":"0x3","memSize":1632,"stack":["0x527f6002610305536039610306536053610307536060616104c0527f03085360"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1931,"op":82,"gas":"0xae8c1","gasCost":"0x6","memSize":1632,"stack":["0x527f6002610305536039610306536053610307536060616104c0527f03085360","0x660"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1932,"op":127,"gas":"0xae8bb","gasCost":"0x3","memSize":1664,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":1965,"op":97,"gas":"0xae8b8","gasCost":"0x3","memSize":1664,"stack":["0x5061610580527f610420527f030953606161030a53600261030b53603a61030c"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":1968,"op":82,"gas":"0xae8b5","gasCost":"0x6","memSize":1664,"stack":["0x5061610580527f610420527f030953606161030a53600261030b53603a61030c","0x680"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":1969,"op":127,"gas":"0xae8af","gasCost":"0x3","memSize":1696,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2002,"op":97,"gas":"0xae8ac","gasCost":"0x3","memSize":1696,"stack":["0x536104e0527f606105a0527f5361030d53606161030e610440527f5360026103"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2005,"op":82,"gas":"0xae8a9","gasCost":"0x6","memSize":1696,"stack":["0x536104e0527f606105a0527f5361030d53606161030e610440527f5360026103","0x6a0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2006,"op":127,"gas":"0xae8a3","gasCost":"0x3","memSize":1728,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2039,"op":97,"gas":"0xae8a0","gasCost":"0x3","memSize":1728,"stack":["0xf53603b61031053606061616105c0527f0500527f03115360006103125360f3"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2042,"op":82,"gas":"0xae89d","gasCost":"0x6","memSize":1728,"stack":["0xf53603b61031053606061616105c0527f0500527f03115360006103125360f3","0x6c0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2043,"op":127,"gas":"0xae897","gasCost":"0x3","memSize":1760,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2076,"op":97,"gas":"0xae894","gasCost":"0x3","memSize":1760,"stack":["0x61031353616104605260036104805360146105e0527f61048153610520527f60"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2079,"op":82,"gas":"0xae891","gasCost":"0x7","memSize":1760,"stack":["0x61031353616104605260036104805360146105e0527f61048153610520527f60","0x6e0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2080,"op":127,"gas":"0xae88a","gasCost":"0x3","memSize":1792,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2113,"op":97,"gas":"0xae887","gasCost":"0x3","memSize":1792,"stack":["0x60610482536000610483536060610484536000610485610600527f5360f06104"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2116,"op":82,"gas":"0xae884","gasCost":"0x6","memSize":1792,"stack":["0x60610482536000610483536060610484536000610485610600527f5360f06104","0x700"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2117,"op":127,"gas":"0xae87e","gasCost":"0x3","memSize":1824,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2150,"op":97,"gas":"0xae87b","gasCost":"0x3","memSize":1824,"stack":["0x86536060610540527f610487536000610488536060610489536000610620527f"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2153,"op":82,"gas":"0xae878","gasCost":"0x6","memSize":1824,"stack":["0x86536060610540527f610487536000610488536060610489536000610620527f","0x720"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2154,"op":127,"gas":"0xae872","gasCost":"0x3","memSize":1856,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2187,"op":97,"gas":"0xae86f","gasCost":"0x3","memSize":1856,"stack":["0x61048a53606061048b5360006104610560527f8c53606061048d53600061048e"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2190,"op":82,"gas":"0xae86c","gasCost":"0x6","memSize":1856,"stack":["0x61048a53606061048b5360006104610560527f8c53606061048d53600061048e","0x740"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2191,"op":127,"gas":"0xae866","gasCost":"0x3","memSize":1888,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2224,"op":97,"gas":"0xae863","gasCost":"0x3","memSize":1888,"stack":["0x610640527f53608461048f53605a6104905360f4610491536105805260606105"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2227,"op":82,"gas":"0xae860","gasCost":"0x7","memSize":1888,"stack":["0x610640527f53608461048f53605a6104905360f4610491536105805260606105","0x760"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2228,"op":127,"gas":"0xae859","gasCost":"0x3","memSize":1920,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2261,"op":97,"gas":"0xae856","gasCost":"0x3","memSize":1920,"stack":["0xa053605061610660527f05a15360616105a25360046105a35360926105a45360"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2264,"op":82,"gas":"0xae853","gasCost":"0x6","memSize":1920,"stack":["0xa053605061610660527f05a15360616105a25360046105a35360926105a45360","0x780"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2265,"op":127,"gas":"0xae84d","gasCost":"0x3","memSize":1952,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2298,"op":97,"gas":"0xae84a","gasCost":"0x3","memSize":1952,"stack":["0x536105a55360606105a6610680527f5360506105a75360616105a85360046105"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2301,"op":82,"gas":"0xae847","gasCost":"0x6","memSize":1952,"stack":["0x536105a55360606105a6610680527f5360506105a75360616105a85360046105","0x7a0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2302,"op":127,"gas":"0xae841","gasCost":"0x3","memSize":1984,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2335,"op":97,"gas":"0xae83e","gasCost":"0x3","memSize":1984,"stack":["0xa95360936105aa5360536105ab53606106a0527f616105ac5360046105ad5360"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2338,"op":82,"gas":"0xae83b","gasCost":"0x6","memSize":1984,"stack":["0xa95360936105aa5360536105ab53606106a0527f616105ac5360046105ad5360","0x7c0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2339,"op":127,"gas":"0xae835","gasCost":"0x3","memSize":2016,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2372,"op":97,"gas":"0xae832","gasCost":"0x3","memSize":2016,"stack":["0x946105ae5360606105af5360006105b05360f3616106c05260056106e05360b1"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2375,"op":82,"gas":"0xae82f","gasCost":"0x7","memSize":2016,"stack":["0x946105ae5360606105af5360006105b05360f3616106c05260056106e05360b1","0x7e0"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2376,"op":127,"gas":"0xae828","gasCost":"0x3","memSize":2048,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2409,"op":97,"gas":"0xae825","gasCost":"0x3","memSize":2048,"stack":["0x6106e15360536106e25360606106e35360006106e45360616106e55360056106"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2412,"op":82,"gas":"0xae822","gasCost":"0x6","memSize":2048,"stack":["0x6106e15360536106e25360606106e35360006106e45360616106e55360056106","0x800"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2413,"op":127,"gas":"0xae81c","gasCost":"0x3","memSize":2080,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2446,"op":97,"gas":"0xae819","gasCost":"0x3","memSize":2080,"stack":["0xe65360b26106e75360606106e85360006106e95360606106ea5360006106eb53"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2449,"op":82,"gas":"0xae816","gasCost":"0x6","memSize":2080,"stack":["0xe65360b26106e75360606106e85360006106e95360606106ea5360006106eb53","0x820"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2450,"op":127,"gas":"0xae810","gasCost":"0x3","memSize":2112,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2483,"op":97,"gas":"0xae80d","gasCost":"0x3","memSize":2112,"stack":["0x60f56106ec5360606106ed5360006106ee5360606106ef5360006106f0536060"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2486,"op":82,"gas":"0xae80a","gasCost":"0x6","memSize":2112,"stack":["0x60f56106ec5360606106ed5360006106ee5360606106ef5360006106f0536060","0x840"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2487,"op":127,"gas":"0xae804","gasCost":"0x3","memSize":2144,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2520,"op":97,"gas":"0xae801","gasCost":"0x3","memSize":2144,"stack":["0x6106f15360006106f25360606106f35360006106f45360606106f55360006106"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2523,"op":82,"gas":"0xae7fe","gasCost":"0x7","memSize":2144,"stack":["0x6106f15360006106f25360606106f35360006106f45360606106f55360006106","0x860"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2524,"op":127,"gas":"0xae7f7","gasCost":"0x3","memSize":2176,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"} +{"pc":2557,"op":97,"gas":"0xae7f4","gasCost":"0x3","memSize":2176,"stack":["0xf65360856106f753605a6106f85360f16106f95360506106fa5360506106fb53"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2560,"op":82,"gas":"0xae7f1","gasCost":"0x6","memSize":2176,"stack":["0xf65360856106f753605a6106f85360f16106f95360506106fa5360506106fb53","0x880"],"depth":1,"refund":0,"opName":"MSTORE"} +{"pc":2561,"op":96,"gas":"0xae7eb","gasCost":"0x3","memSize":2208,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2563,"op":97,"gas":"0xae7e8","gasCost":"0x3","memSize":2208,"stack":["0x61"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2566,"op":83,"gas":"0xae7e5","gasCost":"0x6","memSize":2208,"stack":["0x61","0x8a0"],"depth":1,"refund":0,"opName":"MSTORE8"} +{"pc":2567,"op":96,"gas":"0xae7df","gasCost":"0x3","memSize":2240,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2569,"op":97,"gas":"0xae7dc","gasCost":"0x3","memSize":2240,"stack":["0x6"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2572,"op":83,"gas":"0xae7d9","gasCost":"0x3","memSize":2240,"stack":["0x6","0x8a1"],"depth":1,"refund":0,"opName":"MSTORE8"} +{"pc":2573,"op":96,"gas":"0xae7d6","gasCost":"0x3","memSize":2240,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2575,"op":97,"gas":"0xae7d3","gasCost":"0x3","memSize":2240,"stack":["0xfc"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2578,"op":83,"gas":"0xae7d0","gasCost":"0x3","memSize":2240,"stack":["0xfc","0x8a2"],"depth":1,"refund":0,"opName":"MSTORE8"} +{"pc":2579,"op":96,"gas":"0xae7cd","gasCost":"0x3","memSize":2240,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2581,"op":97,"gas":"0xae7ca","gasCost":"0x3","memSize":2240,"stack":["0x60"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2584,"op":83,"gas":"0xae7c7","gasCost":"0x3","memSize":2240,"stack":["0x60","0x8a3"],"depth":1,"refund":0,"opName":"MSTORE8"} +{"pc":2585,"op":96,"gas":"0xae7c4","gasCost":"0x3","memSize":2240,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2587,"op":97,"gas":"0xae7c1","gasCost":"0x3","memSize":2240,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2590,"op":83,"gas":"0xae7be","gasCost":"0x3","memSize":2240,"stack":["0x0","0x8a4"],"depth":1,"refund":0,"opName":"MSTORE8"} +{"pc":2591,"op":96,"gas":"0xae7bb","gasCost":"0x3","memSize":2240,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2593,"op":97,"gas":"0xae7b8","gasCost":"0x3","memSize":2240,"stack":["0xf3"],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2596,"op":83,"gas":"0xae7b5","gasCost":"0x3","memSize":2240,"stack":["0xf3","0x8a5"],"depth":1,"refund":0,"opName":"MSTORE8"} +{"pc":2597,"op":97,"gas":"0xae7b2","gasCost":"0x3","memSize":2240,"stack":[],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":2600,"op":96,"gas":"0xae7af","gasCost":"0x3","memSize":2240,"stack":["0x8a6"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2602,"op":96,"gas":"0xae7ac","gasCost":"0x3","memSize":2240,"stack":["0x8a6","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2604,"op":240,"gas":"0xae7a9","gasCost":"0x7d00","memSize":2240,"stack":["0x8a6","0x0","0x0"],"depth":1,"refund":0,"opName":"CREATE"} +{"pc":0,"op":96,"gas":"0xa40ff","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":84,"gas":"0xa40fc","gasCost":"0x834","memSize":0,"stack":["0x2"],"depth":2,"refund":0,"opName":"SLOAD"} +{"pc":3,"op":80,"gas":"0xa38c8","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":2,"refund":0,"opName":"POP"} +{"pc":4,"op":96,"gas":"0xa38c6","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":6,"op":84,"gas":"0xa38c3","gasCost":"0x834","memSize":0,"stack":["0x3"],"depth":2,"refund":0,"opName":"SLOAD"} +{"pc":7,"op":80,"gas":"0xa308f","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":2,"refund":0,"opName":"POP"} +{"pc":8,"op":96,"gas":"0xa308d","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":10,"op":96,"gas":"0xa308a","gasCost":"0x3","memSize":0,"stack":["0x1"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":12,"op":85,"gas":"0xa3087","gasCost":"0x4e20","memSize":0,"stack":["0x1","0x3"],"depth":2,"refund":0,"opName":"SSTORE"} +{"pc":13,"op":127,"gas":"0x9e267","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":46,"op":96,"gas":"0x9e264","gasCost":"0x3","memSize":0,"stack":["0x7f6008545060006004557f600160045560006004556000600060006000600060"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":48,"op":82,"gas":"0x9e261","gasCost":"0x6","memSize":0,"stack":["0x7f6008545060006004557f600160045560006004556000600060006000600060","0x0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":49,"op":127,"gas":"0x9e25b","gasCost":"0x3","memSize":32,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":82,"op":96,"gas":"0x9e258","gasCost":"0x3","memSize":32,"stack":["0xf96000527f5af250600060006000606000527e60f45af4506000600060006000"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":84,"op":82,"gas":"0x9e255","gasCost":"0x6","memSize":32,"stack":["0xf96000527f5af250600060006000606000527e60f45af4506000600060006000","0x20"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":85,"op":127,"gas":"0x9e24f","gasCost":"0x3","memSize":64,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":118,"op":96,"gas":"0x9e24c","gasCost":"0x3","memSize":64,"stack":["0x600060f55a6020527ff150f001075205846a44a283446020527f8ca260006000"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":120,"op":82,"gas":"0x9e249","gasCost":"0x6","memSize":64,"stack":["0x600060f55a6020527ff150f001075205846a44a283446020527f8ca260006000","0x40"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":121,"op":127,"gas":"0x9e243","gasCost":"0x3","memSize":96,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":154,"op":96,"gas":"0x9e240","gasCost":"0x3","memSize":96,"stack":["0x6000600060045af4506040527f519930847f3b631c54a49b5f60035450326040"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":156,"op":82,"gas":"0x9e23d","gasCost":"0x6","memSize":96,"stack":["0x6000600060045af4506040527f519930847f3b631c54a49b5f60035450326040","0x60"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":157,"op":127,"gas":"0x9e237","gasCost":"0x3","memSize":128,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":190,"op":96,"gas":"0x9e234","gasCost":"0x3","memSize":128,"stack":["0x527f77306b60006000600060006060527f6000600c5af1506000600060006000"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":192,"op":82,"gas":"0x9e231","gasCost":"0x6","memSize":128,"stack":["0x527f77306b60006000600060006060527f6000600c5af1506000600060006000","0x80"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":193,"op":127,"gas":"0x9e22b","gasCost":"0x3","memSize":160,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":226,"op":96,"gas":"0x9e228","gasCost":"0x3","memSize":160,"stack":["0x60f85af450506060527f066001600255606080527f0354506000600055600060"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":228,"op":82,"gas":"0x9e225","gasCost":"0x6","memSize":160,"stack":["0x60f85af450506060527f066001600255606080527f0354506000600055600060","0xa0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":229,"op":127,"gas":"0x9e21f","gasCost":"0x3","memSize":192,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":262,"op":96,"gas":"0x9e21c","gasCost":"0x3","memSize":192,"stack":["0x1556c3394fff4607f7f1684317b6080527f387b9f60a0527f1920700184809d"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":264,"op":82,"gas":"0x9e219","gasCost":"0x6","memSize":192,"stack":["0x1556c3394fff4607f7f1684317b6080527f387b9f60a0527f1920700184809d","0xc0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":265,"op":127,"gas":"0x9e213","gasCost":"0x3","memSize":224,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":298,"op":96,"gas":"0x9e210","gasCost":"0x3","memSize":224,"stack":["0x60015450011899016e6009ff60026001556000527f9f60a05260c0527f7f6000"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":300,"op":82,"gas":"0x9e20d","gasCost":"0x6","memSize":224,"stack":["0x60015450011899016e6009ff60026001556000527f9f60a05260c0527f7f6000","0xe0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":301,"op":127,"gas":"0x9e207","gasCost":"0x3","memSize":256,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":334,"op":97,"gas":"0x9e204","gasCost":"0x3","memSize":256,"stack":["0x527f9981600160045582600eff600060006000600060f65af45060006060e052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":337,"op":82,"gas":"0x9e201","gasCost":"0x6","memSize":256,"stack":["0x527f9981600160045582600eff600060006000600060f65af45060006060e052","0x100"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":338,"op":127,"gas":"0x9e1fb","gasCost":"0x3","memSize":288,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":371,"op":97,"gas":"0x9e1f8","gasCost":"0x3","memSize":288,"stack":["0x7f6060c0527f20527e600060006020527f60f75af4501d7f1903166660006000"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":374,"op":82,"gas":"0x9e1f5","gasCost":"0x6","memSize":288,"stack":["0x7f6060c0527f20527e600060006020527f60f75af4501d7f1903166660006000","0x120"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":375,"op":127,"gas":"0x9e1ef","gasCost":"0x3","memSize":320,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":408,"op":97,"gas":"0x9e1ec","gasCost":"0x3","memSize":320,"stack":["0x60610100527e6000600060e0527f60046040527f5af150600060006000604052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":411,"op":82,"gas":"0x9e1e9","gasCost":"0x6","memSize":320,"stack":["0x60610100527e6000600060e0527f60046040527f5af150600060006000604052","0x140"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":412,"op":127,"gas":"0x9e1e3","gasCost":"0x3","memSize":352,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":445,"op":97,"gas":"0x9e1e0","gasCost":"0x3","memSize":352,"stack":["0x7f60006009610120527f5af4503c95138e5b8f610100527f7f605a6000536060"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":448,"op":82,"gas":"0x9e1dd","gasCost":"0x6","memSize":352,"stack":["0x7f60006009610120527f5af4503c95138e5b8f610100527f7f605a6000536060","0x160"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":449,"op":127,"gas":"0x9e1d7","gasCost":"0x3","memSize":384,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":482,"op":97,"gas":"0x9e1d4","gasCost":"0x3","memSize":384,"stack":["0x527f6031600153606b60610140527f02536010606060527f0353604560610120"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":485,"op":82,"gas":"0x9e1d1","gasCost":"0x6","memSize":384,"stack":["0x527f6031600153606b60610140527f02536010606060527f0353604560610120","0x180"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":486,"op":127,"gas":"0x9e1cb","gasCost":"0x3","memSize":416,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":519,"op":97,"gas":"0x9e1c8","gasCost":"0x3","memSize":416,"stack":["0x527f04536060600553600160608052610160527f7e527f600653606060075360"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":522,"op":82,"gas":"0x9e1c5","gasCost":"0x6","memSize":416,"stack":["0x527f04536060600553600160608052610160527f7e527f600653606060075360","0x1a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":523,"op":127,"gas":"0x9e1bf","gasCost":"0x3","memSize":448,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":556,"op":97,"gas":"0x9e1bc","gasCost":"0x3","memSize":448,"stack":["0x2600853606080610140527f527f556009536060610180527f600a53600160a0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":559,"op":82,"gas":"0x9e1b9","gasCost":"0x6","memSize":448,"stack":["0x2600853606080610140527f527f556009536060610180527f600a53600160a0","0x1c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":560,"op":127,"gas":"0x9e1b3","gasCost":"0x3","memSize":480,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":593,"op":97,"gas":"0x9e1b0","gasCost":"0x3","memSize":480,"stack":["0x527f600b536060600c6020527f53600060610160527f0d53606101a0527f5560"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":596,"op":82,"gas":"0x9e1ad","gasCost":"0x6","memSize":480,"stack":["0x527f600b536060600c6020527f53600060610160527f0d53606101a0527f5560","0x1e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":597,"op":127,"gas":"0x9e1a7","gasCost":"0x3","memSize":512,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":630,"op":97,"gas":"0x9e1a4","gasCost":"0x3","memSize":512,"stack":["0xe60a0527f536060600f536060c0527f01601053606060115360026101806101"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":633,"op":82,"gas":"0x9e1a1","gasCost":"0x6","memSize":512,"stack":["0xe60a0527f536060600f536060c0527f01601053606060115360026101806101","0x200"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":634,"op":127,"gas":"0x9e19b","gasCost":"0x3","memSize":544,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":667,"op":97,"gas":"0x9e198","gasCost":"0x3","memSize":544,"stack":["0xc0527f527f601253606040527f55601353606060c0527f60145360e0527f6000"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":670,"op":82,"gas":"0x9e195","gasCost":"0x6","memSize":544,"stack":["0xc0527f527f601253606040527f55601353606060c0527f60145360e0527f6000","0x220"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":671,"op":127,"gas":"0x9e18f","gasCost":"0x3","memSize":576,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":704,"op":97,"gas":"0x9e18c","gasCost":"0x3","memSize":576,"stack":["0x6015536101e0527f60606101a0527f601653600060175360f360185360196060"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":707,"op":82,"gas":"0x9e189","gasCost":"0x6","memSize":576,"stack":["0x6015536101e0527f60606101a0527f601653600060175360f360185360196060","0x240"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":708,"op":127,"gas":"0x9e183","gasCost":"0x3","memSize":608,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":741,"op":97,"gas":"0x9e180","gasCost":"0x3","memSize":608,"stack":["0x605260006060e052610200527f610100527f7f806101c0527f5360f360815360"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":744,"op":82,"gas":"0x9e17d","gasCost":"0x6","memSize":608,"stack":["0x605260006060e052610200527f610100527f7f806101c0527f5360f360815360","0x260"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":745,"op":127,"gas":"0x9e177","gasCost":"0x3","memSize":640,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":778,"op":97,"gas":"0x9e174","gasCost":"0x3","memSize":640,"stack":["0x8260006000f060006000600060610220527e845af450506000600061016101e0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":781,"op":82,"gas":"0x9e171","gasCost":"0x6","memSize":640,"stack":["0x8260006000f060006000600060610220527e845af450506000600061016101e0","0x280"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":782,"op":127,"gas":"0x9e16b","gasCost":"0x3","memSize":672,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":815,"op":97,"gas":"0x9e168","gasCost":"0x3","memSize":672,"stack":["0x527f20527f60610100527e600060006003610240527f5af15060005450c76000"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":818,"op":82,"gas":"0x9e165","gasCost":"0x6","memSize":672,"stack":["0x527f20527f60610100527e600060006003610240527f5af15060005450c76000","0x2a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":819,"op":127,"gas":"0x9e15f","gasCost":"0x3","memSize":704,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":852,"op":97,"gas":"0x9e15c","gasCost":"0x3","memSize":704,"stack":["0x6002551309f562610200527f66a486610140527f6b00610260527f1d45716101"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":855,"op":82,"gas":"0x9e159","gasCost":"0x7","memSize":704,"stack":["0x6002551309f562610200527f66a486610140527f6b00610260527f1d45716101","0x2c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":856,"op":127,"gas":"0x9e152","gasCost":"0x3","memSize":736,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":889,"op":97,"gas":"0x9e14f","gasCost":"0x3","memSize":736,"stack":["0x20527f600054501c641d373c7f60045450610220527f6000600155610280527f"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":892,"op":82,"gas":"0x9e14c","gasCost":"0x6","memSize":736,"stack":["0x20527f600054501c641d373c7f60045450610220527f6000600155610280527f","0x2e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":893,"op":127,"gas":"0x9e146","gasCost":"0x3","memSize":768,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":926,"op":97,"gas":"0x9e143","gasCost":"0x3","memSize":768,"stack":["0x600554610160527f50600160025560085450610140527f60006002610240527f"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":929,"op":82,"gas":"0x9e140","gasCost":"0x6","memSize":768,"stack":["0x600554610160527f50600160025560085450610140527f60006002610240527f","0x300"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":930,"op":127,"gas":"0x9e13a","gasCost":"0x3","memSize":800,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":963,"op":97,"gas":"0x9e137","gasCost":"0x3","memSize":800,"stack":["0x6102a0527f557fd86000606000527e600060610180527e600060005af1508612"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":966,"op":82,"gas":"0x9e134","gasCost":"0x6","memSize":800,"stack":["0x6102a0527f557fd86000606000527e600060610180527e600060005af1508612","0x320"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":967,"op":127,"gas":"0x9e12e","gasCost":"0x3","memSize":832,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1000,"op":97,"gas":"0x9e12b","gasCost":"0x3","memSize":832,"stack":["0x17145147356102c0527f610260527f610160527f5198a37e127a7efa7c600052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1003,"op":82,"gas":"0x9e128","gasCost":"0x6","memSize":832,"stack":["0x17145147356102c0527f610260527f610160527f5198a37e127a7efa7c600052","0x340"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1004,"op":127,"gas":"0x9e122","gasCost":"0x3","memSize":864,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1037,"op":97,"gas":"0x9e11f","gasCost":"0x3","memSize":864,"stack":["0x6101a0527f606020527f6102e0527f6060205360610280527ff760215360ff60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1040,"op":82,"gas":"0x9e11c","gasCost":"0x6","memSize":864,"stack":["0x6101a0527f606020527f6102e0527f6060205360610280527ff760215360ff60","0x360"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1041,"op":127,"gas":"0x9e116","gasCost":"0x3","memSize":896,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1074,"op":97,"gas":"0x9e113","gasCost":"0x3","memSize":896,"stack":["0x225360610180527fdb602353603760610300527f6101c0527f24536075606102"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1077,"op":82,"gas":"0x9e110","gasCost":"0x6","memSize":896,"stack":["0x225360610180527fdb602353603760610300527f6101c0527f24536075606102","0x380"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1078,"op":127,"gas":"0x9e10a","gasCost":"0x3","memSize":928,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1111,"op":97,"gas":"0x9e107","gasCost":"0x3","memSize":928,"stack":["0xa0527f2553609f606040527f265360fe60275360610320527f8f60286101a052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1114,"op":82,"gas":"0x9e104","gasCost":"0x6","memSize":928,"stack":["0xa0527f2553609f606040527f265360fe60275360610320527f8f60286101a052","0x3a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1115,"op":127,"gas":"0x9e0fe","gasCost":"0x3","memSize":960,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1148,"op":97,"gas":"0x9e0fb","gasCost":"0x3","memSize":960,"stack":["0x7f53606101e0527f6102c0527f0b6029536060602a53600060610340527f2b53"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1151,"op":82,"gas":"0x9e0f8","gasCost":"0x6","memSize":960,"stack":["0x7f53606101e0527f6102c0527f0b6029536060602a53600060610340527f2b53","0x3c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1152,"op":127,"gas":"0x9e0f2","gasCost":"0x3","memSize":992,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1185,"op":97,"gas":"0x9e0ef","gasCost":"0x3","memSize":992,"stack":["0x6060602c53606052606060805360006061016102e0527f610200527fc0526103"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1188,"op":82,"gas":"0x9e0ec","gasCost":"0x7","memSize":992,"stack":["0x6060602c53606052606060805360006061016102e0527f610200527fc0526103","0x3e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1189,"op":127,"gas":"0x9e0e5","gasCost":"0x3","memSize":1024,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1222,"op":97,"gas":"0x9e0e2","gasCost":"0x3","memSize":1024,"stack":["0x60527f7f81536060608253602d6083536053608453606060855360fd61030052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1225,"op":82,"gas":"0x9e0df","gasCost":"0x6","memSize":1024,"stack":["0x60527f7f81536060608253602d6083536053608453606060855360fd61030052","0x400"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1226,"op":127,"gas":"0x9e0d9","gasCost":"0x3","memSize":1056,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1259,"op":97,"gas":"0x9e0d6","gasCost":"0x3","memSize":1056,"stack":["0x7f6086610380527f536060610220527f6087536101e0527f602e608853605360"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1262,"op":82,"gas":"0x9e0d3","gasCost":"0x6","memSize":1056,"stack":["0x7f6086610380527f536060610220527f6087536101e0527f602e608853605360","0x420"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1263,"op":127,"gas":"0x9e0cd","gasCost":"0x3","memSize":1088,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1296,"op":97,"gas":"0x9e0ca","gasCost":"0x3","memSize":1088,"stack":["0x89536060608a61036103a0527f20527f53602f608b536060608c610240527f53"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1299,"op":82,"gas":"0x9e0c7","gasCost":"0x6","memSize":1088,"stack":["0x89536060608a61036103a0527f20527f53602f608b536060608c610240527f53","0x440"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1300,"op":127,"gas":"0x9e0c1","gasCost":"0x3","memSize":1120,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1333,"op":97,"gas":"0x9e0be","gasCost":"0x3","memSize":1120,"stack":["0x6000608d5360f36102005260606103c0527f610220610340527f53608e610221"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1336,"op":82,"gas":"0x9e0bb","gasCost":"0x6","memSize":1120,"stack":["0x6000608d5360f36102005260606103c0527f610220610340527f53608e610221","0x460"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1337,"op":127,"gas":"0x9e0b5","gasCost":"0x3","memSize":1152,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1370,"op":97,"gas":"0x9e0b2","gasCost":"0x3","memSize":1152,"stack":["0x536053610222536060610260527f610223536103e0527f600061022453606061"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1373,"op":82,"gas":"0x9e0af","gasCost":"0x6","memSize":1152,"stack":["0x536053610222536060610260527f610223536103e0527f600061022453606061","0x480"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1374,"op":127,"gas":"0x9e0a9","gasCost":"0x3","memSize":1184,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1407,"op":97,"gas":"0x9e0a6","gasCost":"0x3","memSize":1184,"stack":["0x360527f61022553608f61022653606061022753600061610400527f02610280"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1410,"op":82,"gas":"0x9e0a3","gasCost":"0x6","memSize":1184,"stack":["0x360527f61022553608f61022653606061022753600061610400527f02610280","0x4a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1411,"op":127,"gas":"0x9e09d","gasCost":"0x3","memSize":1216,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1444,"op":97,"gas":"0x9e09a","gasCost":"0x3","memSize":1216,"stack":["0x527f28536060610229610380527f53600061022a5360f561022b536061042052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1447,"op":82,"gas":"0x9e097","gasCost":"0x6","memSize":1216,"stack":["0x527f28536060610229610380527f53600061022a5360f561022b536061042052","0x4c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1448,"op":127,"gas":"0x9e091","gasCost":"0x3","memSize":1248,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1481,"op":97,"gas":"0x9e08e","gasCost":"0x3","memSize":1248,"stack":["0x7f6061022c53600061022d536102a0527f60606103a0527f61022e5360006102"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1484,"op":82,"gas":"0x9e08b","gasCost":"0x7","memSize":1248,"stack":["0x7f6061022c53600061022d536102a0527f60606103a0527f61022e5360006102","0x4e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1485,"op":127,"gas":"0x9e084","gasCost":"0x3","memSize":1280,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1518,"op":97,"gas":"0x9e081","gasCost":"0x3","memSize":1280,"stack":["0x2f610440527f53606061023053600061023153606061023253600061026103c0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1521,"op":82,"gas":"0x9e07e","gasCost":"0x6","memSize":1280,"stack":["0x2f610440527f53606061023053600061023153606061023253600061026103c0","0x500"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1522,"op":127,"gas":"0x9e078","gasCost":"0x3","memSize":1312,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1555,"op":97,"gas":"0x9e075","gasCost":"0x3","memSize":1312,"stack":["0x527fc0527f61610460527f023353606061023453600061023553608561023653"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1558,"op":82,"gas":"0x9e072","gasCost":"0x6","memSize":1312,"stack":["0x527fc0527f61610460527f023353606061023453600061023553608561023653","0x520"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1559,"op":127,"gas":"0x9e06c","gasCost":"0x3","memSize":1344,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1592,"op":97,"gas":"0x9e069","gasCost":"0x3","memSize":1344,"stack":["0x605a61023753606103e052610480527f7ff261026102e0526038610300536053"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1595,"op":82,"gas":"0x9e066","gasCost":"0x6","memSize":1344,"stack":["0x605a61023753606103e052610480527f7ff261026102e0526038610300536053","0x540"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1596,"op":127,"gas":"0x9e060","gasCost":"0x3","memSize":1376,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1629,"op":97,"gas":"0x9e05d","gasCost":"0x3","memSize":1376,"stack":["0x610301536060610302536050610303536104a0527f60610400527f6161030453"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1632,"op":82,"gas":"0x9e05a","gasCost":"0x6","memSize":1376,"stack":["0x610301536060610302536050610303536104a0527f60610400527f6161030453","0x560"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1633,"op":127,"gas":"0x9e054","gasCost":"0x3","memSize":1408,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1666,"op":97,"gas":"0x9e051","gasCost":"0x3","memSize":1408,"stack":["0x6002610305536039610306536053610307536060616104c0527f030853605061"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1669,"op":82,"gas":"0x9e04e","gasCost":"0x6","memSize":1408,"stack":["0x6002610305536039610306536053610307536060616104c0527f030853605061","0x580"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1670,"op":127,"gas":"0x9e048","gasCost":"0x3","memSize":1440,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1703,"op":97,"gas":"0x9e045","gasCost":"0x3","memSize":1440,"stack":["0x610420527f030953606161030a53600261030b53603a61030c536104e0527f60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1706,"op":82,"gas":"0x9e042","gasCost":"0x7","memSize":1440,"stack":["0x610420527f030953606161030a53600261030b53603a61030c536104e0527f60","0x5a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1707,"op":127,"gas":"0x9e03b","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1740,"op":97,"gas":"0x9e038","gasCost":"0x3","memSize":1472,"stack":["0x5361030d53606161030e610440527f53600261030f53603b6103105360606161"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1743,"op":82,"gas":"0x9e035","gasCost":"0x6","memSize":1472,"stack":["0x5361030d53606161030e610440527f53600261030f53603b6103105360606161","0x5c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1744,"op":127,"gas":"0x9e02f","gasCost":"0x3","memSize":1504,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1777,"op":97,"gas":"0x9e02c","gasCost":"0x3","memSize":1504,"stack":["0x500527f03115360006103125360f36103135361610460526003610480536014"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1780,"op":82,"gas":"0x9e029","gasCost":"0x6","memSize":1504,"stack":["0x500527f03115360006103125360f36103135361610460526003610480536014","0x5e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1781,"op":127,"gas":"0x9e023","gasCost":"0x3","memSize":1536,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1814,"op":97,"gas":"0x9e020","gasCost":"0x3","memSize":1536,"stack":["0x61048153610520527f6060610482536000610483536060610484536000610485"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1817,"op":82,"gas":"0x9e01d","gasCost":"0x6","memSize":1536,"stack":["0x61048153610520527f6060610482536000610483536060610484536000610485","0x600"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1818,"op":127,"gas":"0x9e017","gasCost":"0x3","memSize":1568,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1851,"op":97,"gas":"0x9e014","gasCost":"0x3","memSize":1568,"stack":["0x5360f0610486536060610540527f610487536000610488536060610489536000"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1854,"op":82,"gas":"0x9e011","gasCost":"0x6","memSize":1568,"stack":["0x5360f0610486536060610540527f610487536000610488536060610489536000","0x620"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1855,"op":127,"gas":"0x9e00b","gasCost":"0x3","memSize":1600,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1888,"op":97,"gas":"0x9e008","gasCost":"0x3","memSize":1600,"stack":["0x61048a53606061048b5360006104610560527f8c53606061048d53600061048e"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1891,"op":82,"gas":"0x9e005","gasCost":"0x7","memSize":1600,"stack":["0x61048a53606061048b5360006104610560527f8c53606061048d53600061048e","0x640"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1892,"op":127,"gas":"0x9dffe","gasCost":"0x3","memSize":1632,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1925,"op":97,"gas":"0x9dffb","gasCost":"0x3","memSize":1632,"stack":["0x53608461048f53605a6104905360f4610491536105805260606105a053605061"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1928,"op":82,"gas":"0x9dff8","gasCost":"0x6","memSize":1632,"stack":["0x53608461048f53605a6104905360f4610491536105805260606105a053605061","0x660"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1929,"op":127,"gas":"0x9dff2","gasCost":"0x3","memSize":1664,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1962,"op":97,"gas":"0x9dfef","gasCost":"0x3","memSize":1664,"stack":["0x5a15360616105a25360046105a35360926105a45360536105a55360606105a6"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1965,"op":82,"gas":"0x9dfec","gasCost":"0x6","memSize":1664,"stack":["0x5a15360616105a25360046105a35360926105a45360536105a55360606105a6","0x680"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1966,"op":127,"gas":"0x9dfe6","gasCost":"0x3","memSize":1696,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1999,"op":97,"gas":"0x9dfe3","gasCost":"0x3","memSize":1696,"stack":["0x5360506105a75360616105a85360046105a95360936105aa5360536105ab5360"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2002,"op":82,"gas":"0x9dfe0","gasCost":"0x6","memSize":1696,"stack":["0x5360506105a75360616105a85360046105a95360936105aa5360536105ab5360","0x6a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":2003,"op":127,"gas":"0x9dfda","gasCost":"0x3","memSize":1728,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":2036,"op":97,"gas":"0x9dfd7","gasCost":"0x3","memSize":1728,"stack":["0x616105ac5360046105ad5360946105ae5360606105af5360006105b05360f361"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2039,"op":82,"gas":"0x9dfd4","gasCost":"0x6","memSize":1728,"stack":["0x616105ac5360046105ad5360946105ae5360606105af5360006105b05360f361","0x6c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":2040,"op":96,"gas":"0x9dfce","gasCost":"0x3","memSize":1760,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2042,"op":97,"gas":"0x9dfcb","gasCost":"0x3","memSize":1760,"stack":["0x5"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2045,"op":83,"gas":"0x9dfc8","gasCost":"0x7","memSize":1760,"stack":["0x5","0x6e0"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2046,"op":96,"gas":"0x9dfc1","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2048,"op":97,"gas":"0x9dfbe","gasCost":"0x3","memSize":1792,"stack":["0xb1"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2051,"op":83,"gas":"0x9dfbb","gasCost":"0x3","memSize":1792,"stack":["0xb1","0x6e1"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2052,"op":96,"gas":"0x9dfb8","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2054,"op":97,"gas":"0x9dfb5","gasCost":"0x3","memSize":1792,"stack":["0x53"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2057,"op":83,"gas":"0x9dfb2","gasCost":"0x3","memSize":1792,"stack":["0x53","0x6e2"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2058,"op":96,"gas":"0x9dfaf","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2060,"op":97,"gas":"0x9dfac","gasCost":"0x3","memSize":1792,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2063,"op":83,"gas":"0x9dfa9","gasCost":"0x3","memSize":1792,"stack":["0x60","0x6e3"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2064,"op":96,"gas":"0x9dfa6","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2066,"op":97,"gas":"0x9dfa3","gasCost":"0x3","memSize":1792,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2069,"op":83,"gas":"0x9dfa0","gasCost":"0x3","memSize":1792,"stack":["0x0","0x6e4"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2070,"op":96,"gas":"0x9df9d","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2072,"op":97,"gas":"0x9df9a","gasCost":"0x3","memSize":1792,"stack":["0x61"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2075,"op":83,"gas":"0x9df97","gasCost":"0x3","memSize":1792,"stack":["0x61","0x6e5"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2076,"op":96,"gas":"0x9df94","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2078,"op":97,"gas":"0x9df91","gasCost":"0x3","memSize":1792,"stack":["0x5"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2081,"op":83,"gas":"0x9df8e","gasCost":"0x3","memSize":1792,"stack":["0x5","0x6e6"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2082,"op":96,"gas":"0x9df8b","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2084,"op":97,"gas":"0x9df88","gasCost":"0x3","memSize":1792,"stack":["0xb2"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2087,"op":83,"gas":"0x9df85","gasCost":"0x3","memSize":1792,"stack":["0xb2","0x6e7"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2088,"op":96,"gas":"0x9df82","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2090,"op":97,"gas":"0x9df7f","gasCost":"0x3","memSize":1792,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2093,"op":83,"gas":"0x9df7c","gasCost":"0x3","memSize":1792,"stack":["0x60","0x6e8"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2094,"op":96,"gas":"0x9df79","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2096,"op":97,"gas":"0x9df76","gasCost":"0x3","memSize":1792,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2099,"op":83,"gas":"0x9df73","gasCost":"0x3","memSize":1792,"stack":["0x0","0x6e9"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2100,"op":96,"gas":"0x9df70","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2102,"op":97,"gas":"0x9df6d","gasCost":"0x3","memSize":1792,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2105,"op":83,"gas":"0x9df6a","gasCost":"0x3","memSize":1792,"stack":["0x60","0x6ea"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2106,"op":96,"gas":"0x9df67","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2108,"op":97,"gas":"0x9df64","gasCost":"0x3","memSize":1792,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2111,"op":83,"gas":"0x9df61","gasCost":"0x3","memSize":1792,"stack":["0x0","0x6eb"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2112,"op":96,"gas":"0x9df5e","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2114,"op":97,"gas":"0x9df5b","gasCost":"0x3","memSize":1792,"stack":["0xf5"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2117,"op":83,"gas":"0x9df58","gasCost":"0x3","memSize":1792,"stack":["0xf5","0x6ec"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2118,"op":96,"gas":"0x9df55","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2120,"op":97,"gas":"0x9df52","gasCost":"0x3","memSize":1792,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2123,"op":83,"gas":"0x9df4f","gasCost":"0x3","memSize":1792,"stack":["0x60","0x6ed"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2124,"op":96,"gas":"0x9df4c","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2126,"op":97,"gas":"0x9df49","gasCost":"0x3","memSize":1792,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2129,"op":83,"gas":"0x9df46","gasCost":"0x3","memSize":1792,"stack":["0x0","0x6ee"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2130,"op":96,"gas":"0x9df43","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2132,"op":97,"gas":"0x9df40","gasCost":"0x3","memSize":1792,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2135,"op":83,"gas":"0x9df3d","gasCost":"0x3","memSize":1792,"stack":["0x60","0x6ef"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2136,"op":96,"gas":"0x9df3a","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2138,"op":97,"gas":"0x9df37","gasCost":"0x3","memSize":1792,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2141,"op":83,"gas":"0x9df34","gasCost":"0x3","memSize":1792,"stack":["0x0","0x6f0"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2142,"op":96,"gas":"0x9df31","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2144,"op":97,"gas":"0x9df2e","gasCost":"0x3","memSize":1792,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2147,"op":83,"gas":"0x9df2b","gasCost":"0x3","memSize":1792,"stack":["0x60","0x6f1"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2148,"op":96,"gas":"0x9df28","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2150,"op":97,"gas":"0x9df25","gasCost":"0x3","memSize":1792,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2153,"op":83,"gas":"0x9df22","gasCost":"0x3","memSize":1792,"stack":["0x0","0x6f2"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2154,"op":96,"gas":"0x9df1f","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2156,"op":97,"gas":"0x9df1c","gasCost":"0x3","memSize":1792,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2159,"op":83,"gas":"0x9df19","gasCost":"0x3","memSize":1792,"stack":["0x60","0x6f3"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2160,"op":96,"gas":"0x9df16","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2162,"op":97,"gas":"0x9df13","gasCost":"0x3","memSize":1792,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2165,"op":83,"gas":"0x9df10","gasCost":"0x3","memSize":1792,"stack":["0x0","0x6f4"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2166,"op":96,"gas":"0x9df0d","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2168,"op":97,"gas":"0x9df0a","gasCost":"0x3","memSize":1792,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2171,"op":83,"gas":"0x9df07","gasCost":"0x3","memSize":1792,"stack":["0x60","0x6f5"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2172,"op":96,"gas":"0x9df04","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2174,"op":97,"gas":"0x9df01","gasCost":"0x3","memSize":1792,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2177,"op":83,"gas":"0x9defe","gasCost":"0x3","memSize":1792,"stack":["0x0","0x6f6"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2178,"op":96,"gas":"0x9defb","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2180,"op":97,"gas":"0x9def8","gasCost":"0x3","memSize":1792,"stack":["0x85"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2183,"op":83,"gas":"0x9def5","gasCost":"0x3","memSize":1792,"stack":["0x85","0x6f7"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2184,"op":96,"gas":"0x9def2","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2186,"op":97,"gas":"0x9deef","gasCost":"0x3","memSize":1792,"stack":["0x5a"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2189,"op":83,"gas":"0x9deec","gasCost":"0x3","memSize":1792,"stack":["0x5a","0x6f8"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2190,"op":96,"gas":"0x9dee9","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2192,"op":97,"gas":"0x9dee6","gasCost":"0x3","memSize":1792,"stack":["0xf1"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2195,"op":83,"gas":"0x9dee3","gasCost":"0x3","memSize":1792,"stack":["0xf1","0x6f9"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2196,"op":96,"gas":"0x9dee0","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2198,"op":97,"gas":"0x9dedd","gasCost":"0x3","memSize":1792,"stack":["0x50"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2201,"op":83,"gas":"0x9deda","gasCost":"0x3","memSize":1792,"stack":["0x50","0x6fa"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2202,"op":96,"gas":"0x9ded7","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2204,"op":97,"gas":"0x9ded4","gasCost":"0x3","memSize":1792,"stack":["0x50"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2207,"op":83,"gas":"0x9ded1","gasCost":"0x3","memSize":1792,"stack":["0x50","0x6fb"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":2208,"op":97,"gas":"0x9dece","gasCost":"0x3","memSize":1792,"stack":[],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":2211,"op":96,"gas":"0x9decb","gasCost":"0x3","memSize":1792,"stack":["0x6fc"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2213,"op":243,"gas":"0x9dec8","gasCost":"0x0","memSize":1792,"stack":["0x6fc","0x0"],"depth":2,"refund":0,"opName":"RETURN"} +{"output":"7f6008545060006004557f600160045560006004556000600060006000600060f96000527f5af250600060006000606000527e60f45af4506000600060006000600060f55a6020527ff150f001075205846a44a283446020527f8ca2600060006000600060045af4506040527f519930847f3b631c54a49b5f60035450326040527f77306b60006000600060006060527f6000600c5af150600060006000600060f85af450506060527f066001600255606080527f035450600060005560006001556c3394fff4607f7f1684317b6080527f387b9f60a0527f1920700184809d60015450011899016e6009ff60026001556000527f9f60a05260c0527f7f6000527f9981600160045582600eff600060006000600060f65af45060006060e0527f6060c0527f20527e600060006020527f60f75af4501d7f190316666000600060610100527e6000600060e0527f60046040527f5af1506000600060006040527f60006009610120527f5af4503c95138e5b8f610100527f7f605a6000536060527f6031600153606b60610140527f02536010606060527f0353604560610120527f04536060600553600160608052610160527f7e527f60065360606007536002600853606080610140527f527f556009536060610180527f600a53600160a0527f600b536060600c6020527f53600060610160527f0d53606101a0527f55600e60a0527f536060600f536060c0527f01601053606060115360026101806101c0527f527f601253606040527f55601353606060c0527f60145360e0527f60006015536101e0527f60606101a0527f601653600060175360f360185360196060605260006060e052610200527f610100527f7f806101c0527f5360f3608153608260006000f060006000600060610220527e845af450506000600061016101e0527f20527f60610100527e600060006003610240527f5af15060005450c760006002551309f562610200527f66a486610140527f6b00610260527f1d4571610120527f600054501c641d373c7f60045450610220527f6000600155610280527f600554610160527f50600160025560085450610140527f60006002610240527f6102a0527f557fd86000606000527e600060610180527e600060005af150861217145147356102c0527f610260527f610160527f5198a37e127a7efa7c6000526101a0527f606020527f6102e0527f6060205360610280527ff760215360ff60225360610180527fdb602353603760610300527f6101c0527f24536075606102a0527f2553609f606040527f265360fe60275360610320527f8f60286101a0527f53606101e0527f6102c0527f0b6029536060602a53600060610340527f2b536060602c53606052606060805360006061016102e0527f610200527fc052610360527f7f81536060608253602d6083536053608453606060855360fd610300527f6086610380527f536060610220527f6087536101e0527f602e60885360536089536060608a61036103a0527f20527f53602f608b536060608c610240527f536000608d5360f36102005260606103c0527f610220610340527f53608e610221536053610222536060610260527f610223536103e0527f6000610224536060610360527f61022553608f61022653606061022753600061610400527f02610280527f28536060610229610380527f53600061022a5360f561022b5360610420527f6061022c53600061022d536102a0527f60606103a0527f61022e53600061022f610440527f53606061023053600061023153606061023253600061026103c0527fc0527f61610460527f023353606061023453600061023553608561023653605a61023753606103e052610480527f7ff261026102e0526038610300536053610301536060610302536050610303536104a0527f60610400527f61610304536002610305536039610306536053610307536060616104c0527f030853605061610420527f030953606161030a53600261030b53603a61030c536104e0527f605361030d53606161030e610440527f53600261030f53603b61031053606061610500527f03115360006103125360f3610313536161046052600361048053601461048153610520527f60606104825360006104835360606104845360006104855360f0610486536060610540527f61048753600061048853606061048953600061048a53606061048b5360006104610560527f8c53606061048d53600061048e53608461048f53605a6104905360f4610491536105805260606105a05360506105a15360616105a25360046105a35360926105a45360536105a55360606105a65360506105a75360616105a85360046105a95360936105aa5360536105ab5360616105ac5360046105ad5360946105ae5360606105af5360006105b05360f36105b15360006105b260006000f560006000600060006000855af15050","gasUsed":"0x5d717"} +{"pc":2605,"op":96,"gas":"0x49392","gasCost":"0x3","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2607,"op":96,"gas":"0x4938f","gasCost":"0x3","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2609,"op":96,"gas":"0x4938c","gasCost":"0x3","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2611,"op":96,"gas":"0x49389","gasCost":"0x3","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2613,"op":96,"gas":"0x49386","gasCost":"0x3","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2615,"op":133,"gas":"0x49383","gasCost":"0x3","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x0","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"DUP6"} +{"pc":2616,"op":90,"gas":"0x49380","gasCost":"0x2","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x0","0x0","0x0","0x0","0x0","0x7dce2faf43218578e3fcf2ad22df9918a89e2fba"],"depth":1,"refund":0,"opName":"GAS"} +{"pc":2617,"op":241,"gas":"0x4937e","gasCost":"0x48132","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x0","0x0","0x0","0x0","0x0","0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x4937e"],"depth":1,"refund":0,"opName":"CALL"} +{"pc":0,"op":127,"gas":"0x480ce","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":33,"op":96,"gas":"0x480cb","gasCost":"0x3","memSize":0,"stack":["0x6008545060006004557f600160045560006004556000600060006000600060f9"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":35,"op":82,"gas":"0x480c8","gasCost":"0x6","memSize":0,"stack":["0x6008545060006004557f600160045560006004556000600060006000600060f9","0x0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":36,"op":127,"gas":"0x480c2","gasCost":"0x3","memSize":32,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":69,"op":96,"gas":"0x480bf","gasCost":"0x3","memSize":32,"stack":["0x5af250600060006000606000527e60f45af4506000600060006000600060f55a"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":71,"op":82,"gas":"0x480bc","gasCost":"0x6","memSize":32,"stack":["0x5af250600060006000606000527e60f45af4506000600060006000600060f55a","0x20"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":72,"op":127,"gas":"0x480b6","gasCost":"0x3","memSize":64,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":105,"op":96,"gas":"0x480b3","gasCost":"0x3","memSize":64,"stack":["0xf150f001075205846a44a283446020527f8ca2600060006000600060045af450"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":107,"op":82,"gas":"0x480b0","gasCost":"0x6","memSize":64,"stack":["0xf150f001075205846a44a283446020527f8ca2600060006000600060045af450","0x40"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":108,"op":127,"gas":"0x480aa","gasCost":"0x3","memSize":96,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":141,"op":96,"gas":"0x480a7","gasCost":"0x3","memSize":96,"stack":["0x519930847f3b631c54a49b5f60035450326040527f77306b6000600060006000"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":143,"op":82,"gas":"0x480a4","gasCost":"0x6","memSize":96,"stack":["0x519930847f3b631c54a49b5f60035450326040527f77306b6000600060006000","0x60"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":144,"op":127,"gas":"0x4809e","gasCost":"0x3","memSize":128,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":177,"op":96,"gas":"0x4809b","gasCost":"0x3","memSize":128,"stack":["0x6000600c5af150600060006000600060f85af450506060527f06600160025560"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":179,"op":82,"gas":"0x48098","gasCost":"0x6","memSize":128,"stack":["0x6000600c5af150600060006000600060f85af450506060527f06600160025560","0x80"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":180,"op":127,"gas":"0x48092","gasCost":"0x3","memSize":160,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":213,"op":96,"gas":"0x4808f","gasCost":"0x3","memSize":160,"stack":["0x35450600060005560006001556c3394fff4607f7f1684317b6080527f387b9f"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":215,"op":82,"gas":"0x4808c","gasCost":"0x6","memSize":160,"stack":["0x35450600060005560006001556c3394fff4607f7f1684317b6080527f387b9f","0xa0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":216,"op":127,"gas":"0x48086","gasCost":"0x3","memSize":192,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":249,"op":96,"gas":"0x48083","gasCost":"0x3","memSize":192,"stack":["0x1920700184809d60015450011899016e6009ff60026001556000527f9f60a052"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":251,"op":82,"gas":"0x48080","gasCost":"0x6","memSize":192,"stack":["0x1920700184809d60015450011899016e6009ff60026001556000527f9f60a052","0xc0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":252,"op":127,"gas":"0x4807a","gasCost":"0x3","memSize":224,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":285,"op":96,"gas":"0x48077","gasCost":"0x3","memSize":224,"stack":["0x7f6000527f9981600160045582600eff600060006000600060f65af450600060"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":287,"op":82,"gas":"0x48074","gasCost":"0x6","memSize":224,"stack":["0x7f6000527f9981600160045582600eff600060006000600060f65af450600060","0xe0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":288,"op":127,"gas":"0x4806e","gasCost":"0x3","memSize":256,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":321,"op":97,"gas":"0x4806b","gasCost":"0x3","memSize":256,"stack":["0x6060c0527f20527e600060006020527f60f75af4501d7f190316666000600060"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":324,"op":82,"gas":"0x48068","gasCost":"0x6","memSize":256,"stack":["0x6060c0527f20527e600060006020527f60f75af4501d7f190316666000600060","0x100"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":325,"op":126,"gas":"0x48062","gasCost":"0x3","memSize":288,"stack":[],"depth":2,"refund":0,"opName":"PUSH31"} +{"pc":357,"op":97,"gas":"0x4805f","gasCost":"0x3","memSize":288,"stack":["0x6000600060e0527f60046040527f5af1506000600060006040527f60006009"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":360,"op":82,"gas":"0x4805c","gasCost":"0x6","memSize":288,"stack":["0x6000600060e0527f60046040527f5af1506000600060006040527f60006009","0x120"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":361,"op":127,"gas":"0x48056","gasCost":"0x3","memSize":320,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":394,"op":97,"gas":"0x48053","gasCost":"0x3","memSize":320,"stack":["0x5af4503c95138e5b8f610100527f7f605a6000536060527f6031600153606b60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":397,"op":82,"gas":"0x48050","gasCost":"0x6","memSize":320,"stack":["0x5af4503c95138e5b8f610100527f7f605a6000536060527f6031600153606b60","0x140"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":398,"op":127,"gas":"0x4804a","gasCost":"0x3","memSize":352,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":431,"op":97,"gas":"0x48047","gasCost":"0x3","memSize":352,"stack":["0x2536010606060527f0353604560610120527f04536060600553600160608052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":434,"op":82,"gas":"0x48044","gasCost":"0x6","memSize":352,"stack":["0x2536010606060527f0353604560610120527f04536060600553600160608052","0x160"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":435,"op":127,"gas":"0x4803e","gasCost":"0x3","memSize":384,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":468,"op":97,"gas":"0x4803b","gasCost":"0x3","memSize":384,"stack":["0x7e527f60065360606007536002600853606080610140527f527f556009536060"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":471,"op":82,"gas":"0x48038","gasCost":"0x6","memSize":384,"stack":["0x7e527f60065360606007536002600853606080610140527f527f556009536060","0x180"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":472,"op":127,"gas":"0x48032","gasCost":"0x3","memSize":416,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":505,"op":97,"gas":"0x4802f","gasCost":"0x3","memSize":416,"stack":["0x600a53600160a0527f600b536060600c6020527f53600060610160527f0d5360"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":508,"op":82,"gas":"0x4802c","gasCost":"0x6","memSize":416,"stack":["0x600a53600160a0527f600b536060600c6020527f53600060610160527f0d5360","0x1a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":509,"op":127,"gas":"0x48026","gasCost":"0x3","memSize":448,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":542,"op":97,"gas":"0x48023","gasCost":"0x3","memSize":448,"stack":["0x55600e60a0527f536060600f536060c0527f0160105360606011536002610180"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":545,"op":82,"gas":"0x48020","gasCost":"0x6","memSize":448,"stack":["0x55600e60a0527f536060600f536060c0527f0160105360606011536002610180","0x1c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":546,"op":127,"gas":"0x4801a","gasCost":"0x3","memSize":480,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":579,"op":97,"gas":"0x48017","gasCost":"0x3","memSize":480,"stack":["0x527f601253606040527f55601353606060c0527f60145360e0527f6000601553"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":582,"op":82,"gas":"0x48014","gasCost":"0x6","memSize":480,"stack":["0x527f601253606040527f55601353606060c0527f60145360e0527f6000601553","0x1e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":583,"op":127,"gas":"0x4800e","gasCost":"0x3","memSize":512,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":616,"op":97,"gas":"0x4800b","gasCost":"0x3","memSize":512,"stack":["0x60606101a0527f601653600060175360f360185360196060605260006060e052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":619,"op":82,"gas":"0x48008","gasCost":"0x6","memSize":512,"stack":["0x60606101a0527f601653600060175360f360185360196060605260006060e052","0x200"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":620,"op":127,"gas":"0x48002","gasCost":"0x3","memSize":544,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":653,"op":97,"gas":"0x47fff","gasCost":"0x3","memSize":544,"stack":["0x610100527f7f806101c0527f5360f3608153608260006000f060006000600060"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":656,"op":82,"gas":"0x47ffc","gasCost":"0x6","memSize":544,"stack":["0x610100527f7f806101c0527f5360f3608153608260006000f060006000600060","0x220"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":657,"op":126,"gas":"0x47ff6","gasCost":"0x3","memSize":576,"stack":[],"depth":2,"refund":0,"opName":"PUSH31"} +{"pc":689,"op":97,"gas":"0x47ff3","gasCost":"0x3","memSize":576,"stack":["0x845af450506000600061016101e0527f20527f60610100527e600060006003"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":692,"op":82,"gas":"0x47ff0","gasCost":"0x6","memSize":576,"stack":["0x845af450506000600061016101e0527f20527f60610100527e600060006003","0x240"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":693,"op":127,"gas":"0x47fea","gasCost":"0x3","memSize":608,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":726,"op":97,"gas":"0x47fe7","gasCost":"0x3","memSize":608,"stack":["0x5af15060005450c760006002551309f562610200527f66a486610140527f6b00"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":729,"op":82,"gas":"0x47fe4","gasCost":"0x6","memSize":608,"stack":["0x5af15060005450c760006002551309f562610200527f66a486610140527f6b00","0x260"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":730,"op":127,"gas":"0x47fde","gasCost":"0x3","memSize":640,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":763,"op":97,"gas":"0x47fdb","gasCost":"0x3","memSize":640,"stack":["0x1d4571610120527f600054501c641d373c7f60045450610220527f6000600155"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":766,"op":82,"gas":"0x47fd8","gasCost":"0x6","memSize":640,"stack":["0x1d4571610120527f600054501c641d373c7f60045450610220527f6000600155","0x280"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":767,"op":127,"gas":"0x47fd2","gasCost":"0x3","memSize":672,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":800,"op":97,"gas":"0x47fcf","gasCost":"0x3","memSize":672,"stack":["0x600554610160527f50600160025560085450610140527f60006002610240527f"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":803,"op":82,"gas":"0x47fcc","gasCost":"0x6","memSize":672,"stack":["0x600554610160527f50600160025560085450610140527f60006002610240527f","0x2a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":804,"op":127,"gas":"0x47fc6","gasCost":"0x3","memSize":704,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":837,"op":97,"gas":"0x47fc3","gasCost":"0x3","memSize":704,"stack":["0x557fd86000606000527e600060610180527e600060005af15086121714514735"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":840,"op":82,"gas":"0x47fc0","gasCost":"0x7","memSize":704,"stack":["0x557fd86000606000527e600060610180527e600060005af15086121714514735","0x2c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":841,"op":127,"gas":"0x47fb9","gasCost":"0x3","memSize":736,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":874,"op":97,"gas":"0x47fb6","gasCost":"0x3","memSize":736,"stack":["0x610260527f610160527f5198a37e127a7efa7c6000526101a0527f606020527f"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":877,"op":82,"gas":"0x47fb3","gasCost":"0x6","memSize":736,"stack":["0x610260527f610160527f5198a37e127a7efa7c6000526101a0527f606020527f","0x2e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":878,"op":127,"gas":"0x47fad","gasCost":"0x3","memSize":768,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":911,"op":97,"gas":"0x47faa","gasCost":"0x3","memSize":768,"stack":["0x6060205360610280527ff760215360ff60225360610180527fdb602353603760"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":914,"op":82,"gas":"0x47fa7","gasCost":"0x6","memSize":768,"stack":["0x6060205360610280527ff760215360ff60225360610180527fdb602353603760","0x300"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":915,"op":127,"gas":"0x47fa1","gasCost":"0x3","memSize":800,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":948,"op":97,"gas":"0x47f9e","gasCost":"0x3","memSize":800,"stack":["0x6101c0527f24536075606102a0527f2553609f606040527f265360fe60275360"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":951,"op":82,"gas":"0x47f9b","gasCost":"0x6","memSize":800,"stack":["0x6101c0527f24536075606102a0527f2553609f606040527f265360fe60275360","0x320"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":952,"op":127,"gas":"0x47f95","gasCost":"0x3","memSize":832,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":985,"op":97,"gas":"0x47f92","gasCost":"0x3","memSize":832,"stack":["0x8f60286101a0527f53606101e0527f6102c0527f0b6029536060602a53600060"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":988,"op":82,"gas":"0x47f8f","gasCost":"0x6","memSize":832,"stack":["0x8f60286101a0527f53606101e0527f6102c0527f0b6029536060602a53600060","0x340"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":989,"op":127,"gas":"0x47f89","gasCost":"0x3","memSize":864,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1022,"op":97,"gas":"0x47f86","gasCost":"0x3","memSize":864,"stack":["0x2b536060602c53606052606060805360006061016102e0527f610200527fc052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1025,"op":82,"gas":"0x47f83","gasCost":"0x6","memSize":864,"stack":["0x2b536060602c53606052606060805360006061016102e0527f610200527fc052","0x360"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1026,"op":127,"gas":"0x47f7d","gasCost":"0x3","memSize":896,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1059,"op":97,"gas":"0x47f7a","gasCost":"0x3","memSize":896,"stack":["0x7f81536060608253602d6083536053608453606060855360fd610300527f6086"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1062,"op":82,"gas":"0x47f77","gasCost":"0x6","memSize":896,"stack":["0x7f81536060608253602d6083536053608453606060855360fd610300527f6086","0x380"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1063,"op":127,"gas":"0x47f71","gasCost":"0x3","memSize":928,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1096,"op":97,"gas":"0x47f6e","gasCost":"0x3","memSize":928,"stack":["0x536060610220527f6087536101e0527f602e60885360536089536060608a6103"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1099,"op":82,"gas":"0x47f6b","gasCost":"0x6","memSize":928,"stack":["0x536060610220527f6087536101e0527f602e60885360536089536060608a6103","0x3a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1100,"op":127,"gas":"0x47f65","gasCost":"0x3","memSize":960,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1133,"op":97,"gas":"0x47f62","gasCost":"0x3","memSize":960,"stack":["0x20527f53602f608b536060608c610240527f536000608d5360f3610200526060"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1136,"op":82,"gas":"0x47f5f","gasCost":"0x6","memSize":960,"stack":["0x20527f53602f608b536060608c610240527f536000608d5360f3610200526060","0x3c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1137,"op":127,"gas":"0x47f59","gasCost":"0x3","memSize":992,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1170,"op":97,"gas":"0x47f56","gasCost":"0x3","memSize":992,"stack":["0x610220610340527f53608e610221536053610222536060610260527f61022353"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1173,"op":82,"gas":"0x47f53","gasCost":"0x7","memSize":992,"stack":["0x610220610340527f53608e610221536053610222536060610260527f61022353","0x3e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1174,"op":127,"gas":"0x47f4c","gasCost":"0x3","memSize":1024,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1207,"op":97,"gas":"0x47f49","gasCost":"0x3","memSize":1024,"stack":["0x6000610224536060610360527f61022553608f61022653606061022753600061"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1210,"op":82,"gas":"0x47f46","gasCost":"0x6","memSize":1024,"stack":["0x6000610224536060610360527f61022553608f61022653606061022753600061","0x400"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1211,"op":127,"gas":"0x47f40","gasCost":"0x3","memSize":1056,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1244,"op":97,"gas":"0x47f3d","gasCost":"0x3","memSize":1056,"stack":["0x2610280527f28536060610229610380527f53600061022a5360f561022b5360"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1247,"op":82,"gas":"0x47f3a","gasCost":"0x6","memSize":1056,"stack":["0x2610280527f28536060610229610380527f53600061022a5360f561022b5360","0x420"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1248,"op":127,"gas":"0x47f34","gasCost":"0x3","memSize":1088,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1281,"op":97,"gas":"0x47f31","gasCost":"0x3","memSize":1088,"stack":["0x6061022c53600061022d536102a0527f60606103a0527f61022e53600061022f"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1284,"op":82,"gas":"0x47f2e","gasCost":"0x6","memSize":1088,"stack":["0x6061022c53600061022d536102a0527f60606103a0527f61022e53600061022f","0x440"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1285,"op":127,"gas":"0x47f28","gasCost":"0x3","memSize":1120,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1318,"op":97,"gas":"0x47f25","gasCost":"0x3","memSize":1120,"stack":["0x53606061023053600061023153606061023253600061026103c0527fc0527f61"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1321,"op":82,"gas":"0x47f22","gasCost":"0x6","memSize":1120,"stack":["0x53606061023053600061023153606061023253600061026103c0527fc0527f61","0x460"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1322,"op":127,"gas":"0x47f1c","gasCost":"0x3","memSize":1152,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1355,"op":97,"gas":"0x47f19","gasCost":"0x3","memSize":1152,"stack":["0x23353606061023453600061023553608561023653605a61023753606103e052"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1358,"op":82,"gas":"0x47f16","gasCost":"0x6","memSize":1152,"stack":["0x23353606061023453600061023553608561023653605a61023753606103e052","0x480"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1359,"op":127,"gas":"0x47f10","gasCost":"0x3","memSize":1184,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1392,"op":97,"gas":"0x47f0d","gasCost":"0x3","memSize":1184,"stack":["0x7ff261026102e052603861030053605361030153606061030253605061030353"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1395,"op":82,"gas":"0x47f0a","gasCost":"0x6","memSize":1184,"stack":["0x7ff261026102e052603861030053605361030153606061030253605061030353","0x4a0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1396,"op":127,"gas":"0x47f04","gasCost":"0x3","memSize":1216,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1429,"op":97,"gas":"0x47f01","gasCost":"0x3","memSize":1216,"stack":["0x60610400527f6161030453600261030553603961030653605361030753606061"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1432,"op":82,"gas":"0x47efe","gasCost":"0x6","memSize":1216,"stack":["0x60610400527f6161030453600261030553603961030653605361030753606061","0x4c0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1433,"op":127,"gas":"0x47ef8","gasCost":"0x3","memSize":1248,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1466,"op":97,"gas":"0x47ef5","gasCost":"0x3","memSize":1248,"stack":["0x30853605061610420527f030953606161030a53600261030b53603a61030c53"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1469,"op":82,"gas":"0x47ef2","gasCost":"0x7","memSize":1248,"stack":["0x30853605061610420527f030953606161030a53600261030b53603a61030c53","0x4e0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1470,"op":127,"gas":"0x47eeb","gasCost":"0x3","memSize":1280,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1503,"op":97,"gas":"0x47ee8","gasCost":"0x3","memSize":1280,"stack":["0x605361030d53606161030e610440527f53600261030f53603b61031053606061"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1506,"op":82,"gas":"0x47ee5","gasCost":"0x6","memSize":1280,"stack":["0x605361030d53606161030e610440527f53600261030f53603b61031053606061","0x500"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1507,"op":127,"gas":"0x47edf","gasCost":"0x3","memSize":1312,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1540,"op":97,"gas":"0x47edc","gasCost":"0x3","memSize":1312,"stack":["0x3115360006103125360f3610313536161046052600361048053601461048153"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1543,"op":82,"gas":"0x47ed9","gasCost":"0x6","memSize":1312,"stack":["0x3115360006103125360f3610313536161046052600361048053601461048153","0x520"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1544,"op":127,"gas":"0x47ed3","gasCost":"0x3","memSize":1344,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1577,"op":97,"gas":"0x47ed0","gasCost":"0x3","memSize":1344,"stack":["0x60606104825360006104835360606104845360006104855360f0610486536060"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1580,"op":82,"gas":"0x47ecd","gasCost":"0x6","memSize":1344,"stack":["0x60606104825360006104835360606104845360006104855360f0610486536060","0x540"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1581,"op":127,"gas":"0x47ec7","gasCost":"0x3","memSize":1376,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1614,"op":97,"gas":"0x47ec4","gasCost":"0x3","memSize":1376,"stack":["0x61048753600061048853606061048953600061048a53606061048b5360006104"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1617,"op":82,"gas":"0x47ec1","gasCost":"0x6","memSize":1376,"stack":["0x61048753600061048853606061048953600061048a53606061048b5360006104","0x560"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1618,"op":127,"gas":"0x47ebb","gasCost":"0x3","memSize":1408,"stack":[],"depth":2,"refund":0,"opName":"PUSH32"} +{"pc":1651,"op":97,"gas":"0x47eb8","gasCost":"0x3","memSize":1408,"stack":["0x8c53606061048d53600061048e53608461048f53605a6104905360f461049153"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1654,"op":82,"gas":"0x47eb5","gasCost":"0x6","memSize":1408,"stack":["0x8c53606061048d53600061048e53608461048f53605a6104905360f461049153","0x580"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":1655,"op":96,"gas":"0x47eaf","gasCost":"0x3","memSize":1440,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1657,"op":97,"gas":"0x47eac","gasCost":"0x3","memSize":1440,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1660,"op":83,"gas":"0x47ea9","gasCost":"0x7","memSize":1440,"stack":["0x60","0x5a0"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1661,"op":96,"gas":"0x47ea2","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1663,"op":97,"gas":"0x47e9f","gasCost":"0x3","memSize":1472,"stack":["0x50"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1666,"op":83,"gas":"0x47e9c","gasCost":"0x3","memSize":1472,"stack":["0x50","0x5a1"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1667,"op":96,"gas":"0x47e99","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1669,"op":97,"gas":"0x47e96","gasCost":"0x3","memSize":1472,"stack":["0x61"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1672,"op":83,"gas":"0x47e93","gasCost":"0x3","memSize":1472,"stack":["0x61","0x5a2"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1673,"op":96,"gas":"0x47e90","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1675,"op":97,"gas":"0x47e8d","gasCost":"0x3","memSize":1472,"stack":["0x4"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1678,"op":83,"gas":"0x47e8a","gasCost":"0x3","memSize":1472,"stack":["0x4","0x5a3"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1679,"op":96,"gas":"0x47e87","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1681,"op":97,"gas":"0x47e84","gasCost":"0x3","memSize":1472,"stack":["0x92"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1684,"op":83,"gas":"0x47e81","gasCost":"0x3","memSize":1472,"stack":["0x92","0x5a4"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1685,"op":96,"gas":"0x47e7e","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1687,"op":97,"gas":"0x47e7b","gasCost":"0x3","memSize":1472,"stack":["0x53"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1690,"op":83,"gas":"0x47e78","gasCost":"0x3","memSize":1472,"stack":["0x53","0x5a5"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1691,"op":96,"gas":"0x47e75","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1693,"op":97,"gas":"0x47e72","gasCost":"0x3","memSize":1472,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1696,"op":83,"gas":"0x47e6f","gasCost":"0x3","memSize":1472,"stack":["0x60","0x5a6"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1697,"op":96,"gas":"0x47e6c","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1699,"op":97,"gas":"0x47e69","gasCost":"0x3","memSize":1472,"stack":["0x50"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1702,"op":83,"gas":"0x47e66","gasCost":"0x3","memSize":1472,"stack":["0x50","0x5a7"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1703,"op":96,"gas":"0x47e63","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1705,"op":97,"gas":"0x47e60","gasCost":"0x3","memSize":1472,"stack":["0x61"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1708,"op":83,"gas":"0x47e5d","gasCost":"0x3","memSize":1472,"stack":["0x61","0x5a8"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1709,"op":96,"gas":"0x47e5a","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1711,"op":97,"gas":"0x47e57","gasCost":"0x3","memSize":1472,"stack":["0x4"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1714,"op":83,"gas":"0x47e54","gasCost":"0x3","memSize":1472,"stack":["0x4","0x5a9"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1715,"op":96,"gas":"0x47e51","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1717,"op":97,"gas":"0x47e4e","gasCost":"0x3","memSize":1472,"stack":["0x93"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1720,"op":83,"gas":"0x47e4b","gasCost":"0x3","memSize":1472,"stack":["0x93","0x5aa"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1721,"op":96,"gas":"0x47e48","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1723,"op":97,"gas":"0x47e45","gasCost":"0x3","memSize":1472,"stack":["0x53"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1726,"op":83,"gas":"0x47e42","gasCost":"0x3","memSize":1472,"stack":["0x53","0x5ab"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1727,"op":96,"gas":"0x47e3f","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1729,"op":97,"gas":"0x47e3c","gasCost":"0x3","memSize":1472,"stack":["0x61"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1732,"op":83,"gas":"0x47e39","gasCost":"0x3","memSize":1472,"stack":["0x61","0x5ac"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1733,"op":96,"gas":"0x47e36","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1735,"op":97,"gas":"0x47e33","gasCost":"0x3","memSize":1472,"stack":["0x4"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1738,"op":83,"gas":"0x47e30","gasCost":"0x3","memSize":1472,"stack":["0x4","0x5ad"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1739,"op":96,"gas":"0x47e2d","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1741,"op":97,"gas":"0x47e2a","gasCost":"0x3","memSize":1472,"stack":["0x94"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1744,"op":83,"gas":"0x47e27","gasCost":"0x3","memSize":1472,"stack":["0x94","0x5ae"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1745,"op":96,"gas":"0x47e24","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1747,"op":97,"gas":"0x47e21","gasCost":"0x3","memSize":1472,"stack":["0x60"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1750,"op":83,"gas":"0x47e1e","gasCost":"0x3","memSize":1472,"stack":["0x60","0x5af"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1751,"op":96,"gas":"0x47e1b","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1753,"op":97,"gas":"0x47e18","gasCost":"0x3","memSize":1472,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1756,"op":83,"gas":"0x47e15","gasCost":"0x3","memSize":1472,"stack":["0x0","0x5b0"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1757,"op":96,"gas":"0x47e12","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1759,"op":97,"gas":"0x47e0f","gasCost":"0x3","memSize":1472,"stack":["0xf3"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1762,"op":83,"gas":"0x47e0c","gasCost":"0x3","memSize":1472,"stack":["0xf3","0x5b1"],"depth":2,"refund":0,"opName":"MSTORE8"} +{"pc":1763,"op":96,"gas":"0x47e09","gasCost":"0x3","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1765,"op":97,"gas":"0x47e06","gasCost":"0x3","memSize":1472,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":1768,"op":96,"gas":"0x47e03","gasCost":"0x3","memSize":1472,"stack":["0x0","0x5b2"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1770,"op":96,"gas":"0x47e00","gasCost":"0x3","memSize":1472,"stack":["0x0","0x5b2","0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1772,"op":245,"gas":"0x47dfd","gasCost":"0x7e14","memSize":1472,"stack":["0x0","0x5b2","0x0","0x0"],"depth":2,"refund":0,"opName":"CREATE2"} +{"pc":0,"op":96,"gas":"0x3efea","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":84,"gas":"0x3efe7","gasCost":"0x834","memSize":0,"stack":["0x8"],"depth":3,"refund":0,"opName":"SLOAD"} +{"pc":3,"op":80,"gas":"0x3e7b3","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":3,"refund":0,"opName":"POP"} +{"pc":4,"op":96,"gas":"0x3e7b1","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":6,"op":96,"gas":"0x3e7ae","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":8,"op":85,"gas":"0x3e7ab","gasCost":"0x898","memSize":0,"stack":["0x0","0x4"],"depth":3,"refund":0,"opName":"SSTORE"} +{"pc":9,"op":127,"gas":"0x3df13","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":42,"op":96,"gas":"0x3df10","gasCost":"0x3","memSize":0,"stack":["0x600160045560006004556000600060006000600060f95af25060006000600060"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":44,"op":82,"gas":"0x3df0d","gasCost":"0x6","memSize":0,"stack":["0x600160045560006004556000600060006000600060f95af25060006000600060","0x0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":45,"op":126,"gas":"0x3df07","gasCost":"0x3","memSize":32,"stack":[],"depth":3,"refund":0,"opName":"PUSH31"} +{"pc":77,"op":96,"gas":"0x3df04","gasCost":"0x3","memSize":32,"stack":["0x60f45af4506000600060006000600060f55af150f001075205846a44a28344"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":79,"op":82,"gas":"0x3df01","gasCost":"0x6","memSize":32,"stack":["0x60f45af4506000600060006000600060f55af150f001075205846a44a28344","0x20"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":80,"op":127,"gas":"0x3defb","gasCost":"0x3","memSize":64,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":113,"op":96,"gas":"0x3def8","gasCost":"0x3","memSize":64,"stack":["0x8ca2600060006000600060045af450519930847f3b631c54a49b5f6003545032"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":115,"op":82,"gas":"0x3def5","gasCost":"0x6","memSize":64,"stack":["0x8ca2600060006000600060045af450519930847f3b631c54a49b5f6003545032","0x40"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":116,"op":127,"gas":"0x3deef","gasCost":"0x3","memSize":96,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":149,"op":96,"gas":"0x3deec","gasCost":"0x3","memSize":96,"stack":["0x77306b60006000600060006000600c5af150600060006000600060f85af45050"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":151,"op":82,"gas":"0x3dee9","gasCost":"0x6","memSize":96,"stack":["0x77306b60006000600060006000600c5af150600060006000600060f85af45050","0x60"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":152,"op":127,"gas":"0x3dee3","gasCost":"0x3","memSize":128,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":185,"op":96,"gas":"0x3dee0","gasCost":"0x3","memSize":128,"stack":["0x6600160025560035450600060005560006001556c3394fff4607f7f1684317b"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":187,"op":82,"gas":"0x3dedd","gasCost":"0x6","memSize":128,"stack":["0x6600160025560035450600060005560006001556c3394fff4607f7f1684317b","0x80"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":188,"op":127,"gas":"0x3ded7","gasCost":"0x3","memSize":160,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":221,"op":96,"gas":"0x3ded4","gasCost":"0x3","memSize":160,"stack":["0x387b9f1920700184809d60015450011899016e6009ff60026001556000527f9f"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":223,"op":82,"gas":"0x3ded1","gasCost":"0x6","memSize":160,"stack":["0x387b9f1920700184809d60015450011899016e6009ff60026001556000527f9f","0xa0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":224,"op":127,"gas":"0x3decb","gasCost":"0x3","memSize":192,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":257,"op":96,"gas":"0x3dec8","gasCost":"0x3","memSize":192,"stack":["0x6000527f9981600160045582600eff600060006000600060f65af45060006060"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":259,"op":82,"gas":"0x3dec5","gasCost":"0x6","memSize":192,"stack":["0x6000527f9981600160045582600eff600060006000600060f65af45060006060","0xc0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":260,"op":127,"gas":"0x3debf","gasCost":"0x3","memSize":224,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":293,"op":96,"gas":"0x3debc","gasCost":"0x3","memSize":224,"stack":["0x20527e600060006020527f60f75af4501d7f1903166660006000600060006000"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":295,"op":82,"gas":"0x3deb9","gasCost":"0x6","memSize":224,"stack":["0x20527e600060006020527f60f75af4501d7f1903166660006000600060006000","0xe0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":296,"op":127,"gas":"0x3deb3","gasCost":"0x3","memSize":256,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":329,"op":97,"gas":"0x3deb0","gasCost":"0x3","memSize":256,"stack":["0x60046040527f5af1506000600060006040527f600060095af4503c95138e5b8f"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":332,"op":82,"gas":"0x3dead","gasCost":"0x6","memSize":256,"stack":["0x60046040527f5af1506000600060006040527f600060095af4503c95138e5b8f","0x100"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":333,"op":127,"gas":"0x3dea7","gasCost":"0x3","memSize":288,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":366,"op":97,"gas":"0x3dea4","gasCost":"0x3","memSize":288,"stack":["0x7f605a6000536060527f6031600153606b6002536010606060527f0353604560"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":369,"op":82,"gas":"0x3dea1","gasCost":"0x6","memSize":288,"stack":["0x7f605a6000536060527f6031600153606b6002536010606060527f0353604560","0x120"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":370,"op":127,"gas":"0x3de9b","gasCost":"0x3","memSize":320,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":403,"op":97,"gas":"0x3de98","gasCost":"0x3","memSize":320,"stack":["0x45360606005536001606080527e527f60065360606007536002600853606080"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":406,"op":82,"gas":"0x3de95","gasCost":"0x6","memSize":320,"stack":["0x45360606005536001606080527e527f60065360606007536002600853606080","0x140"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":407,"op":127,"gas":"0x3de8f","gasCost":"0x3","memSize":352,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":440,"op":97,"gas":"0x3de8c","gasCost":"0x3","memSize":352,"stack":["0x527f556009536060600a53600160a0527f600b536060600c6020527f53600060"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":443,"op":82,"gas":"0x3de89","gasCost":"0x6","memSize":352,"stack":["0x527f556009536060600a53600160a0527f600b536060600c6020527f53600060","0x160"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":444,"op":127,"gas":"0x3de83","gasCost":"0x3","memSize":384,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":477,"op":97,"gas":"0x3de80","gasCost":"0x3","memSize":384,"stack":["0xd536055600e60a0527f536060600f536060c0527f0160105360606011536002"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":480,"op":82,"gas":"0x3de7d","gasCost":"0x6","memSize":384,"stack":["0xd536055600e60a0527f536060600f536060c0527f0160105360606011536002","0x180"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":481,"op":127,"gas":"0x3de77","gasCost":"0x3","memSize":416,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":514,"op":97,"gas":"0x3de74","gasCost":"0x3","memSize":416,"stack":["0x601253606040527f55601353606060c0527f60145360e0527f60006015536060"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":517,"op":82,"gas":"0x3de71","gasCost":"0x6","memSize":416,"stack":["0x601253606040527f55601353606060c0527f60145360e0527f60006015536060","0x1a0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":518,"op":127,"gas":"0x3de6b","gasCost":"0x3","memSize":448,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":551,"op":97,"gas":"0x3de68","gasCost":"0x3","memSize":448,"stack":["0x601653600060175360f360185360196060605260006060e052610100527f7f80"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":554,"op":82,"gas":"0x3de65","gasCost":"0x6","memSize":448,"stack":["0x601653600060175360f360185360196060605260006060e052610100527f7f80","0x1c0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":555,"op":127,"gas":"0x3de5f","gasCost":"0x3","memSize":480,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":588,"op":97,"gas":"0x3de5c","gasCost":"0x3","memSize":480,"stack":["0x5360f3608153608260006000f06000600060006000845af45050600060006101"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":591,"op":82,"gas":"0x3de59","gasCost":"0x6","memSize":480,"stack":["0x5360f3608153608260006000f06000600060006000845af45050600060006101","0x1e0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":592,"op":127,"gas":"0x3de53","gasCost":"0x3","memSize":512,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":625,"op":97,"gas":"0x3de50","gasCost":"0x3","memSize":512,"stack":["0x20527f60610100527e6000600060035af15060005450c760006002551309f562"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":628,"op":82,"gas":"0x3de4d","gasCost":"0x6","memSize":512,"stack":["0x20527f60610100527e6000600060035af15060005450c760006002551309f562","0x200"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":629,"op":127,"gas":"0x3de47","gasCost":"0x3","memSize":544,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":662,"op":97,"gas":"0x3de44","gasCost":"0x3","memSize":544,"stack":["0x66a486610140527f6b001d4571610120527f600054501c641d373c7f60045450"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":665,"op":82,"gas":"0x3de41","gasCost":"0x6","memSize":544,"stack":["0x66a486610140527f6b001d4571610120527f600054501c641d373c7f60045450","0x220"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":666,"op":127,"gas":"0x3de3b","gasCost":"0x3","memSize":576,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":699,"op":97,"gas":"0x3de38","gasCost":"0x3","memSize":576,"stack":["0x6000600155600554610160527f50600160025560085450610140527f60006002"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":702,"op":82,"gas":"0x3de35","gasCost":"0x6","memSize":576,"stack":["0x6000600155600554610160527f50600160025560085450610140527f60006002","0x240"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":703,"op":127,"gas":"0x3de2f","gasCost":"0x3","memSize":608,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":736,"op":97,"gas":"0x3de2c","gasCost":"0x3","memSize":608,"stack":["0x557fd86000606000527e600060610180527e600060005af15086121714514735"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":739,"op":82,"gas":"0x3de29","gasCost":"0x6","memSize":608,"stack":["0x557fd86000606000527e600060610180527e600060005af15086121714514735","0x260"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":740,"op":127,"gas":"0x3de23","gasCost":"0x3","memSize":640,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":773,"op":97,"gas":"0x3de20","gasCost":"0x3","memSize":640,"stack":["0x610160527f5198a37e127a7efa7c6000526101a0527f606020527f6060205360"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":776,"op":82,"gas":"0x3de1d","gasCost":"0x6","memSize":640,"stack":["0x610160527f5198a37e127a7efa7c6000526101a0527f606020527f6060205360","0x280"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":777,"op":127,"gas":"0x3de17","gasCost":"0x3","memSize":672,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":810,"op":97,"gas":"0x3de14","gasCost":"0x3","memSize":672,"stack":["0xf760215360ff60225360610180527fdb6023536037606101c0527f2453607560"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":813,"op":82,"gas":"0x3de11","gasCost":"0x6","memSize":672,"stack":["0xf760215360ff60225360610180527fdb6023536037606101c0527f2453607560","0x2a0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":814,"op":127,"gas":"0x3de0b","gasCost":"0x3","memSize":704,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":847,"op":97,"gas":"0x3de08","gasCost":"0x3","memSize":704,"stack":["0x2553609f606040527f265360fe602753608f60286101a0527f53606101e0527f"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":850,"op":82,"gas":"0x3de05","gasCost":"0x7","memSize":704,"stack":["0x2553609f606040527f265360fe602753608f60286101a0527f53606101e0527f","0x2c0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":851,"op":127,"gas":"0x3ddfe","gasCost":"0x3","memSize":736,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":884,"op":97,"gas":"0x3ddfb","gasCost":"0x3","memSize":736,"stack":["0xb6029536060602a536000602b536060602c5360605260606080536000606101"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":887,"op":82,"gas":"0x3ddf8","gasCost":"0x6","memSize":736,"stack":["0xb6029536060602a536000602b536060602c5360605260606080536000606101","0x2e0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":888,"op":127,"gas":"0x3ddf2","gasCost":"0x3","memSize":768,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":921,"op":97,"gas":"0x3ddef","gasCost":"0x3","memSize":768,"stack":["0x610200527fc0527f81536060608253602d6083536053608453606060855360fd"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":924,"op":82,"gas":"0x3ddec","gasCost":"0x6","memSize":768,"stack":["0x610200527fc0527f81536060608253602d6083536053608453606060855360fd","0x300"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":925,"op":127,"gas":"0x3dde6","gasCost":"0x3","memSize":800,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":958,"op":97,"gas":"0x3dde3","gasCost":"0x3","memSize":800,"stack":["0x6086536060610220527f6087536101e0527f602e60885360536089536060608a"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":961,"op":82,"gas":"0x3dde0","gasCost":"0x6","memSize":800,"stack":["0x6086536060610220527f6087536101e0527f602e60885360536089536060608a","0x320"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":962,"op":127,"gas":"0x3ddda","gasCost":"0x3","memSize":832,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":995,"op":97,"gas":"0x3ddd7","gasCost":"0x3","memSize":832,"stack":["0x53602f608b536060608c610240527f536000608d5360f3610200526060610220"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":998,"op":82,"gas":"0x3ddd4","gasCost":"0x6","memSize":832,"stack":["0x53602f608b536060608c610240527f536000608d5360f3610200526060610220","0x340"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":999,"op":127,"gas":"0x3ddce","gasCost":"0x3","memSize":864,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1032,"op":97,"gas":"0x3ddcb","gasCost":"0x3","memSize":864,"stack":["0x53608e610221536053610222536060610260527f610223536000610224536060"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1035,"op":82,"gas":"0x3ddc8","gasCost":"0x6","memSize":864,"stack":["0x53608e610221536053610222536060610260527f610223536000610224536060","0x360"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1036,"op":127,"gas":"0x3ddc2","gasCost":"0x3","memSize":896,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1069,"op":97,"gas":"0x3ddbf","gasCost":"0x3","memSize":896,"stack":["0x61022553608f6102265360606102275360006102610280527f28536060610229"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1072,"op":82,"gas":"0x3ddbc","gasCost":"0x6","memSize":896,"stack":["0x61022553608f6102265360606102275360006102610280527f28536060610229","0x380"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1073,"op":127,"gas":"0x3ddb6","gasCost":"0x3","memSize":928,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1106,"op":97,"gas":"0x3ddb3","gasCost":"0x3","memSize":928,"stack":["0x53600061022a5360f561022b53606061022c53600061022d536102a0527f6060"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1109,"op":82,"gas":"0x3ddb0","gasCost":"0x6","memSize":928,"stack":["0x53600061022a5360f561022b53606061022c53600061022d536102a0527f6060","0x3a0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1110,"op":127,"gas":"0x3ddaa","gasCost":"0x3","memSize":960,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1143,"op":97,"gas":"0x3dda7","gasCost":"0x3","memSize":960,"stack":["0x61022e53600061022f5360606102305360006102315360606102325360006102"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1146,"op":82,"gas":"0x3dda4","gasCost":"0x6","memSize":960,"stack":["0x61022e53600061022f5360606102305360006102315360606102325360006102","0x3c0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1147,"op":127,"gas":"0x3dd9e","gasCost":"0x3","memSize":992,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1180,"op":97,"gas":"0x3dd9b","gasCost":"0x3","memSize":992,"stack":["0xc0527f61023353606061023453600061023553608561023653605a6102375360"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1183,"op":82,"gas":"0x3dd98","gasCost":"0x7","memSize":992,"stack":["0xc0527f61023353606061023453600061023553608561023653605a6102375360","0x3e0"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1184,"op":127,"gas":"0x3dd91","gasCost":"0x3","memSize":1024,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1217,"op":97,"gas":"0x3dd8e","gasCost":"0x3","memSize":1024,"stack":["0xf261026102e05260386103005360536103015360606103025360506103035360"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1220,"op":82,"gas":"0x3dd8b","gasCost":"0x6","memSize":1024,"stack":["0xf261026102e05260386103005360536103015360606103025360506103035360","0x400"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1221,"op":127,"gas":"0x3dd85","gasCost":"0x3","memSize":1056,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1254,"op":97,"gas":"0x3dd82","gasCost":"0x3","memSize":1056,"stack":["0x6161030453600261030553603961030653605361030753606061030853605061"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1257,"op":82,"gas":"0x3dd7f","gasCost":"0x6","memSize":1056,"stack":["0x6161030453600261030553603961030653605361030753606061030853605061","0x420"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1258,"op":127,"gas":"0x3dd79","gasCost":"0x3","memSize":1088,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1291,"op":97,"gas":"0x3dd76","gasCost":"0x3","memSize":1088,"stack":["0x30953606161030a53600261030b53603a61030c53605361030d53606161030e"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1294,"op":82,"gas":"0x3dd73","gasCost":"0x6","memSize":1088,"stack":["0x30953606161030a53600261030b53603a61030c53605361030d53606161030e","0x440"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1295,"op":127,"gas":"0x3dd6d","gasCost":"0x3","memSize":1120,"stack":[],"depth":3,"refund":0,"opName":"PUSH32"} +{"pc":1328,"op":97,"gas":"0x3dd6a","gasCost":"0x3","memSize":1120,"stack":["0x53600261030f53603b6103105360606103115360006103125360f36103135361"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1331,"op":82,"gas":"0x3dd67","gasCost":"0x6","memSize":1120,"stack":["0x53600261030f53603b6103105360606103115360006103125360f36103135361","0x460"],"depth":3,"refund":0,"opName":"MSTORE"} +{"pc":1332,"op":96,"gas":"0x3dd61","gasCost":"0x3","memSize":1152,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1334,"op":97,"gas":"0x3dd5e","gasCost":"0x3","memSize":1152,"stack":["0x3"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1337,"op":83,"gas":"0x3dd5b","gasCost":"0x6","memSize":1152,"stack":["0x3","0x480"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1338,"op":96,"gas":"0x3dd55","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1340,"op":97,"gas":"0x3dd52","gasCost":"0x3","memSize":1184,"stack":["0x14"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1343,"op":83,"gas":"0x3dd4f","gasCost":"0x3","memSize":1184,"stack":["0x14","0x481"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1344,"op":96,"gas":"0x3dd4c","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1346,"op":97,"gas":"0x3dd49","gasCost":"0x3","memSize":1184,"stack":["0x60"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1349,"op":83,"gas":"0x3dd46","gasCost":"0x3","memSize":1184,"stack":["0x60","0x482"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1350,"op":96,"gas":"0x3dd43","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1352,"op":97,"gas":"0x3dd40","gasCost":"0x3","memSize":1184,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1355,"op":83,"gas":"0x3dd3d","gasCost":"0x3","memSize":1184,"stack":["0x0","0x483"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1356,"op":96,"gas":"0x3dd3a","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1358,"op":97,"gas":"0x3dd37","gasCost":"0x3","memSize":1184,"stack":["0x60"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1361,"op":83,"gas":"0x3dd34","gasCost":"0x3","memSize":1184,"stack":["0x60","0x484"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1362,"op":96,"gas":"0x3dd31","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1364,"op":97,"gas":"0x3dd2e","gasCost":"0x3","memSize":1184,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1367,"op":83,"gas":"0x3dd2b","gasCost":"0x3","memSize":1184,"stack":["0x0","0x485"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1368,"op":96,"gas":"0x3dd28","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1370,"op":97,"gas":"0x3dd25","gasCost":"0x3","memSize":1184,"stack":["0xf0"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1373,"op":83,"gas":"0x3dd22","gasCost":"0x3","memSize":1184,"stack":["0xf0","0x486"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1374,"op":96,"gas":"0x3dd1f","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1376,"op":97,"gas":"0x3dd1c","gasCost":"0x3","memSize":1184,"stack":["0x60"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1379,"op":83,"gas":"0x3dd19","gasCost":"0x3","memSize":1184,"stack":["0x60","0x487"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1380,"op":96,"gas":"0x3dd16","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1382,"op":97,"gas":"0x3dd13","gasCost":"0x3","memSize":1184,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1385,"op":83,"gas":"0x3dd10","gasCost":"0x3","memSize":1184,"stack":["0x0","0x488"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1386,"op":96,"gas":"0x3dd0d","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1388,"op":97,"gas":"0x3dd0a","gasCost":"0x3","memSize":1184,"stack":["0x60"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1391,"op":83,"gas":"0x3dd07","gasCost":"0x3","memSize":1184,"stack":["0x60","0x489"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1392,"op":96,"gas":"0x3dd04","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1394,"op":97,"gas":"0x3dd01","gasCost":"0x3","memSize":1184,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1397,"op":83,"gas":"0x3dcfe","gasCost":"0x3","memSize":1184,"stack":["0x0","0x48a"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1398,"op":96,"gas":"0x3dcfb","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1400,"op":97,"gas":"0x3dcf8","gasCost":"0x3","memSize":1184,"stack":["0x60"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1403,"op":83,"gas":"0x3dcf5","gasCost":"0x3","memSize":1184,"stack":["0x60","0x48b"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1404,"op":96,"gas":"0x3dcf2","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1406,"op":97,"gas":"0x3dcef","gasCost":"0x3","memSize":1184,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1409,"op":83,"gas":"0x3dcec","gasCost":"0x3","memSize":1184,"stack":["0x0","0x48c"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1410,"op":96,"gas":"0x3dce9","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1412,"op":97,"gas":"0x3dce6","gasCost":"0x3","memSize":1184,"stack":["0x60"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1415,"op":83,"gas":"0x3dce3","gasCost":"0x3","memSize":1184,"stack":["0x60","0x48d"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1416,"op":96,"gas":"0x3dce0","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1418,"op":97,"gas":"0x3dcdd","gasCost":"0x3","memSize":1184,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1421,"op":83,"gas":"0x3dcda","gasCost":"0x3","memSize":1184,"stack":["0x0","0x48e"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1422,"op":96,"gas":"0x3dcd7","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1424,"op":97,"gas":"0x3dcd4","gasCost":"0x3","memSize":1184,"stack":["0x84"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1427,"op":83,"gas":"0x3dcd1","gasCost":"0x3","memSize":1184,"stack":["0x84","0x48f"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1428,"op":96,"gas":"0x3dcce","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1430,"op":97,"gas":"0x3dccb","gasCost":"0x3","memSize":1184,"stack":["0x5a"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1433,"op":83,"gas":"0x3dcc8","gasCost":"0x3","memSize":1184,"stack":["0x5a","0x490"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1434,"op":96,"gas":"0x3dcc5","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1436,"op":97,"gas":"0x3dcc2","gasCost":"0x3","memSize":1184,"stack":["0xf4"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1439,"op":83,"gas":"0x3dcbf","gasCost":"0x3","memSize":1184,"stack":["0xf4","0x491"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1440,"op":96,"gas":"0x3dcbc","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1442,"op":97,"gas":"0x3dcb9","gasCost":"0x3","memSize":1184,"stack":["0x50"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1445,"op":83,"gas":"0x3dcb6","gasCost":"0x3","memSize":1184,"stack":["0x50","0x492"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1446,"op":96,"gas":"0x3dcb3","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1448,"op":97,"gas":"0x3dcb0","gasCost":"0x3","memSize":1184,"stack":["0x50"],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1451,"op":83,"gas":"0x3dcad","gasCost":"0x3","memSize":1184,"stack":["0x50","0x493"],"depth":3,"refund":0,"opName":"MSTORE8"} +{"pc":1452,"op":97,"gas":"0x3dcaa","gasCost":"0x3","memSize":1184,"stack":[],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":1455,"op":96,"gas":"0x3dca7","gasCost":"0x3","memSize":1184,"stack":["0x494"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":1457,"op":243,"gas":"0x3dca4","gasCost":"0x0","memSize":1184,"stack":["0x494","0x0"],"depth":3,"refund":0,"opName":"RETURN"} +{"output":"600160045560006004556000600060006000600060f95af250600060006000600060f45af4506000600060006000600060f55af150f001075205846a44a283448ca2600060006000600060045af450519930847f3b631c54a49b5f600354503277306b60006000600060006000600c5af150600060006000600060f85af4505006600160025560035450600060005560006001556c3394fff4607f7f1684317b387b9f1920700184809d60015450011899016e6009ff60026001556000527f9f6000527f9981600160045582600eff600060006000600060f65af4506000606020527e600060006020527f60f75af4501d7f190316666000600060006000600060046040527f5af1506000600060006040527f600060095af4503c95138e5b8f7f605a6000536060527f6031600153606b6002536010606060527f0353604560045360606005536001606080527e527f60065360606007536002600853606080527f556009536060600a53600160a0527f600b536060600c6020527f536000600d536055600e60a0527f536060600f536060c0527f0160105360606011536002601253606040527f55601353606060c0527f60145360e0527f60006015536060601653600060175360f360185360196060605260006060e052610100527f7f805360f3608153608260006000f06000600060006000845af4505060006000610120527f60610100527e6000600060035af15060005450c760006002551309f56266a486610140527f6b001d4571610120527f600054501c641d373c7f600454506000600155600554610160527f50600160025560085450610140527f60006002557fd86000606000527e600060610180527e600060005af15086121714514735610160527f5198a37e127a7efa7c6000526101a0527f606020527f6060205360f760215360ff60225360610180527fdb6023536037606101c0527f24536075602553609f606040527f265360fe602753608f60286101a0527f53606101e0527f0b6029536060602a536000602b536060602c5360605260606080536000606101610200527fc0527f81536060608253602d6083536053608453606060855360fd6086536060610220527f6087536101e0527f602e60885360536089536060608a53602f608b536060608c610240527f536000608d5360f361020052606061022053608e610221536053610222536060610260527f61022353600061022453606061022553608f6102265360606102275360006102610280527f2853606061022953600061022a5360f561022b53606061022c53600061022d536102a0527f606061022e53600061022f5360606102305360006102315360606102325360006102c0527f61023353606061023453600061023553608561023653605a6102375360f261026102e052603861030053605361030153606061030253605061030353606161030453600261030553603961030653605361030753606061030853605061030953606161030a53600261030b53603a61030c53605361030d53606161030e53600261030f53603b6103105360606103115360006103125360f36103135361031460006000f06000600060006000845af45050","gasUsed":"0x3a6e6"} +{"pc":1773,"op":96,"gas":"0x5903","gasCost":"0x3","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1775,"op":96,"gas":"0x5900","gasCost":"0x3","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1777,"op":96,"gas":"0x58fd","gasCost":"0x3","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1779,"op":96,"gas":"0x58fa","gasCost":"0x3","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x0","0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1781,"op":96,"gas":"0x58f7","gasCost":"0x3","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x0","0x0","0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":1783,"op":133,"gas":"0x58f4","gasCost":"0x3","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x0","0x0","0x0","0x0","0x0"],"depth":2,"refund":0,"opName":"DUP6"} +{"pc":1784,"op":90,"gas":"0x58f1","gasCost":"0x2","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x0","0x0","0x0","0x0","0x0","0x94a843a7335fc63be036fbdecc40b1365f3c5f26"],"depth":2,"refund":0,"opName":"GAS"} +{"pc":1785,"op":241,"gas":"0x58ef","gasCost":"0x578d","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x0","0x0","0x0","0x0","0x0","0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x58ef"],"depth":2,"refund":0,"opName":"CALL"} +{"pc":0,"op":96,"gas":"0x5729","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":96,"gas":"0x5726","gasCost":"0x3","memSize":0,"stack":["0x1"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":4,"op":85,"gas":"0x5723","gasCost":"0x4e20","memSize":0,"stack":["0x1","0x4"],"depth":3,"refund":0,"opName":"SSTORE"} +{"pc":5,"op":96,"gas":"0x903","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":7,"op":96,"gas":"0x900","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH1"} +{"pc":9,"op":85,"gas":"0x8fd","gasCost":"0x64","memSize":0,"stack":["0x0","0x4"],"depth":3,"refund":19900,"opName":"SSTORE"} +{"pc":10,"op":96,"gas":"0x899","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":19900,"opName":"PUSH1"} +{"pc":12,"op":96,"gas":"0x896","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":3,"refund":19900,"opName":"PUSH1"} +{"pc":14,"op":96,"gas":"0x893","gasCost":"0x3","memSize":0,"stack":["0x0","0x0"],"depth":3,"refund":19900,"opName":"PUSH1"} +{"pc":16,"op":96,"gas":"0x890","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0"],"depth":3,"refund":19900,"opName":"PUSH1"} +{"pc":18,"op":96,"gas":"0x88d","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":3,"refund":19900,"opName":"PUSH1"} +{"pc":20,"op":96,"gas":"0x88a","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":3,"refund":19900,"opName":"PUSH1"} +{"pc":22,"op":90,"gas":"0x887","gasCost":"0x2","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xf9"],"depth":3,"refund":19900,"opName":"GAS"} +{"pc":23,"op":242,"gas":"0x885","gasCost":"0x64","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xf9","0x885"],"depth":3,"refund":19900,"opName":"CALLCODE","error":"out of gas: out of gas"} +{"output":"","gasUsed":"0x5729","error":"out of gas: out of gas"} +{"pc":1786,"op":80,"gas":"0x162","gasCost":"0x2","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26","0x0"],"depth":2,"refund":0,"opName":"POP"} +{"pc":1787,"op":80,"gas":"0x160","gasCost":"0x2","memSize":1472,"stack":["0x94a843a7335fc63be036fbdecc40b1365f3c5f26"],"depth":2,"refund":0,"opName":"POP"} +{"pc":1788,"op":0,"gas":"0x15e","gasCost":"0x0","memSize":1472,"stack":[],"depth":2,"refund":0,"opName":"STOP"} +{"output":"","gasUsed":"0x47f70"} +{"pc":2618,"op":80,"gas":"0x13aa","gasCost":"0x2","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba","0x1"],"depth":1,"refund":0,"opName":"POP"} +{"pc":2619,"op":80,"gas":"0x13a8","gasCost":"0x2","memSize":2240,"stack":["0x7dce2faf43218578e3fcf2ad22df9918a89e2fba"],"depth":1,"refund":0,"opName":"POP"} +{"pc":2620,"op":0,"gas":"0x13a6","gasCost":"0x0","memSize":2240,"stack":[],"depth":1,"refund":0,"opName":"STOP"} +{"output":"","gasUsed":"0xb2e6d"} +{"stateRoot": "0xad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458"} diff --git a/cmd/evm/testdata/statetest.json b/cmd/evm/testdata/statetest.json new file mode 100755 index 0000000000..3b2a91987a --- /dev/null +++ b/cmd/evm/testdata/statetest.json @@ -0,0 +1,57 @@ +{ + "00000006-naivefuzz-0": { + "env": { + "currentCoinbase": "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty": "0x200000", + "currentGasLimit": "0x26e1f476fe1e22", + "currentNumber": "0x1", + "currentTimestamp": "0x3e8", + "previousHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "currentBaseFee": "0x10" + }, + "pre": { + "0x00000000000000000000000000000000000000f1": { + "code": "0x60026003556000600060006000600060045af2507f600254506003545060016003557f7f6008545060006004557f600160045560006000527f60045560006000600060006000606000527ff96000527f5af2506000600060006020527f606000527e60f45af45060006000600060006020527f600060f55a6020527ff16040527f50f001075205846a44a283446020527f8ca2600060006040527f6000600060046060527f5af4506040527f519930847f3b631c54a49b5f600354503260406060527f527f6080527f77306b60006000600060006060527f6000600c5af1506000600060006000608060a0527f527f60f85af450506060527f066001600255606080527f03545060006000556060c0527e6060a0527f01556c3394fff4607f7f1684317b6080527f387b9f60a0527f1960e0527f20700184809d60c0527f60015450011899016e6009ff60026001556000527f9f610100527f60a05260c0527f7f600060e0527f527f9981600160045582600eff6000600060610120527e600060f65af45060006060e052610100527f7f6060c0527f20527e60006000610140527f6020527f60f75af4501d7f1903166660006000610120527f60610100527e6000610160527f600060e0527f60046040527f5af150600060006000604052610140527f7f6000610180527f6009610120527f5af4503c95138e5b8f610100527f7f605a60005360606101606101a0527f527f527f6031600153606b60610140527f02536010606060527f0353604560616101c0527f0120610180527f527f04536060600553600160608052610160527f7e527f60066101e0527f536060600753606101a0527f02600853606080610140527f527f556009536060610200527f610180527f600a53600160a06101c0527f527f600b536060600c6020527f5360610220527e60610160527f0d53606101a0527f55606101e0527f0e60a0527f536060600f610240527f536060c0527f01601053606060115360026101806101610200527fc0527f527f610260527f601253606040527f55601353606060c0527f60145360e0527f6000610220527f610280527f6015536101e0527f60606101a0527f601653600060175360f3601853601960606102a0527f610240527f605260006060e052610200527f610100527f7f806101c0527f53606102c0527ff360815360610260527f8260006000f060006000600060610220527e845af4506102e0527f506000600061016101e0610280527f527f20527f60610100527e600060006003610300527f610240527f5af15060005450c760006102a0527f6002551309f562610200527f610320527f66a486610140527f6b00610260527f1d457161016102c0527f20527f60005450610340527f1c641d373c7f60045450610220527f6000600155610280527f6102e0527f6005610360527f54610160527f50600160025560085450610140527f60006002610240527f6103610380527e527f6102a0527f557fd86000606000527e600060610180527e600060005af16103a0527f508612610320527f17145147356102c0527f610260527f610160527f5198a37e6103c0527f127a7efa7c600052610340527f6101a0527f606020527f6102e0527f606020536103e0527f60610280527ff760215360ff60610360527f225360610180527fdb6023536037610400527f60610300527f6101c0527f24536075606102610380527fa0527f2553609f6060610420527f40527f265360fe60275360610320527f8f60286101a0526103a0527f7f536061610440527f01e0527f6102c0527f0b6029536060602a53600060610340527f2b536103c052610460527f7f6060602c53606052606060805360006061016102e0527f610200527fc05261610480527f036103e0527f60527f7f81536060608253602d608353605360845360606085536104a0527f60fd61030052610400527f7f6086610380527f536060610220527f60875361016104c0527fe0527f602e608853605360610420527f89536060608a61036103a0527f20527f6104e0527f53602f608b536060608c610240527f53610440527f6000608d5360f361020052610500527f60606103c0527f610220610340527f53608e610221610460527f536053610222610520527f536060610260527f610223536103e0527f600061022453606061610480527f03610540527f60527f61022553608f61022653606061022753600061610400527f0261028061610560527f04a0527f527f28536060610229610380527f53600061022a5360f561022b5360610580527f610420526104c0527f7f6061022c53600061022d536102a0527f60606103a0526105a0527f7f61022e53600061026104e0527f2f610440527f5360606102305360006102316105c0527f53606061023253600061026103c0610500527f527fc0527f61610460527f02336105e0527f53606061023453600061023553608561023653610520527f605a610237536061610600527f03e052610480527f7ff261026102e0526038610300536053610540527f610301610620527f536060610302536050610303536104a0527f60610400527f6161030453610560610640527f527f6002610305536039610306536053610307536060616104c0527f03085360610660527f5061610580527f610420527f030953606161030a53600261030b53603a61030c610680527f536104e0527f606105a0527f5361030d53606161030e610440527f53600261036106a0527f0f53603b61031053606061616105c0527f0500527f03115360006103125360f36106c0527f61031353616104605260036104805360146105e0527f61048153610520527f606106e0527f60610482536000610483536060610484536000610485610600527f5360f06104610700527f86536060610540527f610487536000610488536060610489536000610620527f610720527f61048a53606061048b5360006104610560527f8c53606061048d53600061048e610740527f610640527f53608461048f53605a6104905360f4610491536105805260606105610760527fa053605061610660527f05a15360616105a25360046105a35360926105a45360610780527f536105a55360606105a6610680527f5360506105a75360616105a853600461056107a0527fa95360936105aa5360536105ab53606106a0527f616105ac5360046105ad53606107c0527f946105ae5360606105af5360006105b05360f3616106c05260056106e05360b16107e0527f6106e15360536106e25360606106e35360006106e45360616106e55360056106610800527fe65360b26106e75360606106e85360006106e95360606106ea5360006106eb53610820527f60f56106ec5360606106ed5360006106ee5360606106ef5360006106f0536060610840527f6106f15360006106f25360606106f35360006106f45360606106f55360006106610860527ff65360856106f753605a6106f85360f16106f95360506106fa5360506106fb536108805260616108a05360066108a15360fc6108a25360606108a35360006108a45360f36108a5536108a660006000f060006000600060006000855af15050", + "storage": {}, + "balance": "0x0", + "nonce": "0x0" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "code": "0x", + "storage": {}, + "balance": "0xffffffffff", + "nonce": "0x0" + } + }, + "transaction": { + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "gasPrice": "0x10", + "nonce": "0x0", + "to": "0x00000000000000000000000000000000000000f1", + "data": [ + "0x81fbe24d1e33d7944b2e62ee0ff24811bbbcf8cb311e5617c80623dec4477cc14849fc042b9bbaebca9f03f66cca76c46353c5a68c2e134ef75f8c2425d9702f3a4bd3c5527e93d27579bdbd7d237eaa1c0278fce26479aaf11fb8d00e7478" + ], + "gasLimit": [ + "0xb9a0b" + ], + "value": [ + "0x01" + ], + "secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + }, + "out": "0x", + "post": { + "London": [ + { + "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logs": "0x0000000000000000000000000000000000000000000000000000000000000000", + "indexes": { + "data": 0, + "gas": 0, + "value": 0 + } + } + ] + } + } +} \ No newline at end of file diff --git a/eth/tracers/api.go b/eth/tracers/api.go index c15c5c4eb2..c9bf5a4223 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -758,7 +758,6 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block logConfig = config.Config txHash = config.TxHash } - logConfig.Debug = true // Execute transaction, either tracing all or just the requested one var ( diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 51b1512d03..dc9e6e62b7 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -45,9 +45,7 @@ type Config struct { DisableStack bool // disable stack capture DisableStorage bool // disable storage capture EnableReturnData bool // enable return data capture - Debug bool // print output during capture end Limit int // maximum size of output, but zero means unlimited - // Chain overrides, can be used to execute a trace using future fork rules Overrides *params.ChainConfig `json:"overrides,omitempty"` } @@ -324,12 +322,13 @@ func (l *StructLogger) OnExit(depth int, output []byte, gasUsed uint64, err erro } l.output = output l.err = err - if l.cfg.Debug { - fmt.Printf("%#x\n", output) - if err != nil { - fmt.Printf(" error: %v\n", err) - } - } + // TODO @holiman, should we output the per-scope output? + //if l.cfg.Debug { + // fmt.Printf("%#x\n", output) + // if err != nil { + // fmt.Printf(" error: %v\n", err) + // } + //} } func (l *StructLogger) GetResult() (json.RawMessage, error) { diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 13c36379e7..a72dbf6ee6 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -88,7 +88,7 @@ func BenchmarkTransactionTraceV2(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - tracer := logger.NewStructLogger(&logger.Config{Debug: false}).Hooks() + tracer := logger.NewStructLogger(&logger.Config{}).Hooks() tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) evm.Config.Tracer = tracer From 4ecf08584c413dd759c3241703f69c95bda6f84f Mon Sep 17 00:00:00 2001 From: Zheyuan He Date: Tue, 10 Dec 2024 20:10:17 +0800 Subject: [PATCH 004/940] core/vm: remove unnecessary comment (#30887) --- core/vm/instructions.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 47eb62be08..9b9a31a855 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -501,7 +501,6 @@ func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by } func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - // pop value of the stack mStart, val := scope.Stack.pop(), scope.Stack.pop() scope.Memory.Set32(mStart.Uint64(), &val) return nil, nil From 9045b79bc266a547c5b9e923e8db4286e74c240c Mon Sep 17 00:00:00 2001 From: Martin HS Date: Tue, 10 Dec 2024 13:27:29 +0100 Subject: [PATCH 005/940] metrics, cmd/geth: change init-process of metrics (#30814) This PR modifies how the metrics library handles `Enabled`: previously, the package `init` decided whether to serve real metrics or just dummy-types. This has several drawbacks: - During pkg init, we need to determine whether metrics are enabled or not. So we first hacked in a check if certain geth-specific commandline-flags were enabled. Then we added a similar check for geth-env-vars. Then we almost added a very elaborate check for toml-config-file, plus toml parsing. - Using "real" types and dummy types interchangeably means that everything is hidden behind interfaces. This has a performance penalty, and also it just adds a lot of code. This PR removes the interface stuff, uses concrete types, and allows for the setting of Enabled to happen later. It is still assumed that `metrics.Enable()` is invoked early on. The somewhat 'heavy' operations, such as ticking meters and exp-decay, now checks the enable-flag to prevent resource leak. The change may be large, but it's mostly pretty trivial, and from the last time I gutted the metrics, I ensured that we have fairly good test coverage. --------- Co-authored-by: Felix Lange --- cmd/geth/chaincmd.go | 11 +- cmd/geth/config.go | 24 ++ cmd/geth/main.go | 7 - cmd/utils/flags.go | 105 ++++---- core/rawdb/freezer_table.go | 12 +- core/state/trie_prefetcher.go | 28 +-- core/txpool/txpool.go | 4 +- eth/downloader/queue.go | 2 +- eth/handler.go | 2 +- eth/protocols/eth/handler.go | 2 +- eth/protocols/eth/handshake.go | 2 +- eth/protocols/eth/metrics.go | 12 +- eth/protocols/snap/handler.go | 2 +- ethdb/leveldb/leveldb.go | 28 +-- ethdb/pebble/pebble.go | 28 +-- metrics/counter.go | 94 ++----- metrics/counter_float64.go | 103 ++------ metrics/counter_float_64_test.go | 68 ++--- metrics/counter_test.go | 38 +-- metrics/debug.go | 8 +- metrics/ewma.go | 64 ++--- metrics/ewma_test.go | 14 +- metrics/exp/exp.go | 22 +- metrics/gauge.go | 84 +++---- metrics/gauge_float64.go | 65 ++--- metrics/gauge_info.go | 50 ++-- metrics/graphite.go | 117 --------- metrics/graphite_test.go | 22 -- metrics/healthcheck.go | 44 +--- metrics/histogram.go | 23 +- metrics/inactive.go | 48 ---- metrics/influxdb/influxdb.go | 16 +- metrics/influxdb/influxdb_test.go | 2 +- metrics/init_test.go | 2 +- metrics/log.go | 18 +- metrics/meter.go | 156 +++++------- metrics/meter_test.go | 12 +- metrics/metrics.go | 59 ++--- metrics/metrics_test.go | 71 ++---- metrics/opentsdb.go | 14 +- metrics/prometheus/collector.go | 22 +- metrics/prometheus/collector_test.go | 2 +- metrics/registry.go | 39 ++- metrics/registry_test.go | 18 +- metrics/resetting_sample.go | 2 +- metrics/resetting_timer.go | 90 +++---- metrics/sample.go | 356 +++++++++++++-------------- metrics/sample_test.go | 14 +- metrics/syslog.go | 16 +- metrics/timer.go | 104 +++----- metrics/writer.go | 16 +- p2p/discover/metrics.go | 4 +- p2p/discover/table.go | 4 +- p2p/metrics.go | 35 +-- p2p/peer.go | 2 +- p2p/tracker/tracker.go | 4 +- p2p/transport.go | 2 +- triedb/pathdb/states.go | 2 +- 58 files changed, 779 insertions(+), 1436 deletions(-) delete mode 100644 metrics/graphite.go delete mode 100644 metrics/graphite_test.go delete mode 100644 metrics/inactive.go diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index f6dc1cf4bf..48564eb5eb 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -38,7 +38,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/era" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" "github.com/urfave/cli/v2" ) @@ -282,14 +281,12 @@ func importChain(ctx *cli.Context) error { if ctx.Args().Len() < 1 { utils.Fatalf("This command requires an argument.") } - // Start metrics export if enabled - utils.SetupMetrics(ctx) - // Start system runtime metrics collection - go metrics.CollectProcessMetrics(3 * time.Second) - - stack, _ := makeConfigNode(ctx) + stack, cfg := makeConfigNode(ctx) defer stack.Close() + // Start metrics export if enabled + utils.SetupMetrics(&cfg.Metrics) + chain, db := utils.MakeChain(ctx, stack, false) defer db.Close() diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 17ed9fb606..ecee2bfd80 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -192,6 +192,9 @@ func makeFullNode(ctx *cli.Context) *node.Node { cfg.Eth.OverrideVerkle = &v } + // Start metrics export if enabled + utils.SetupMetrics(&cfg.Metrics) + backend, eth := utils.RegisterEthService(stack, &cfg.Eth) // Create gauge with geth system and build information @@ -325,6 +328,27 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) { if ctx.IsSet(utils.MetricsInfluxDBOrganizationFlag.Name) { cfg.Metrics.InfluxDBOrganization = ctx.String(utils.MetricsInfluxDBOrganizationFlag.Name) } + // Sanity-check the commandline flags. It is fine if some unused fields is part + // of the toml-config, but we expect the commandline to only contain relevant + // arguments, otherwise it indicates an error. + var ( + enableExport = ctx.Bool(utils.MetricsEnableInfluxDBFlag.Name) + enableExportV2 = ctx.Bool(utils.MetricsEnableInfluxDBV2Flag.Name) + ) + if enableExport || enableExportV2 { + v1FlagIsSet := ctx.IsSet(utils.MetricsInfluxDBUsernameFlag.Name) || + ctx.IsSet(utils.MetricsInfluxDBPasswordFlag.Name) + + v2FlagIsSet := ctx.IsSet(utils.MetricsInfluxDBTokenFlag.Name) || + ctx.IsSet(utils.MetricsInfluxDBOrganizationFlag.Name) || + ctx.IsSet(utils.MetricsInfluxDBBucketFlag.Name) + + if enableExport && v2FlagIsSet { + utils.Fatalf("Flags --influxdb.metrics.organization, --influxdb.metrics.token, --influxdb.metrics.bucket are only available for influxdb-v2") + } else if enableExportV2 && v1FlagIsSet { + utils.Fatalf("Flags --influxdb.metrics.username, --influxdb.metrics.password are only available for influxdb-v1") + } + } } func setAccountManagerBackends(conf *node.Config, am *accounts.Manager, keydir string) error { diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 1527e180fb..9d9256862b 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -34,7 +34,6 @@ import ( "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/node" "go.uber.org/automaxprocs/maxprocs" @@ -325,12 +324,6 @@ func prepare(ctx *cli.Context) { ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096)) } } - - // Start metrics export if enabled - utils.SetupMetrics(ctx) - - // Start system runtime metrics collection - go metrics.CollectProcessMetrics(3 * time.Second) } // geth is the main entry point into the system if no special subcommand is run. diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 9f309286bd..8ef39e88de 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1968,67 +1968,56 @@ func RegisterFullSyncTester(stack *node.Node, eth *eth.Ethereum, target common.H log.Info("Registered full-sync tester", "hash", target) } -func SetupMetrics(ctx *cli.Context) { - if metrics.Enabled { - log.Info("Enabling metrics collection") - - var ( - enableExport = ctx.Bool(MetricsEnableInfluxDBFlag.Name) - enableExportV2 = ctx.Bool(MetricsEnableInfluxDBV2Flag.Name) - ) - - if enableExport || enableExportV2 { - CheckExclusive(ctx, MetricsEnableInfluxDBFlag, MetricsEnableInfluxDBV2Flag) - - v1FlagIsSet := ctx.IsSet(MetricsInfluxDBUsernameFlag.Name) || - ctx.IsSet(MetricsInfluxDBPasswordFlag.Name) - - v2FlagIsSet := ctx.IsSet(MetricsInfluxDBTokenFlag.Name) || - ctx.IsSet(MetricsInfluxDBOrganizationFlag.Name) || - ctx.IsSet(MetricsInfluxDBBucketFlag.Name) - - if enableExport && v2FlagIsSet { - Fatalf("Flags --influxdb.metrics.organization, --influxdb.metrics.token, --influxdb.metrics.bucket are only available for influxdb-v2") - } else if enableExportV2 && v1FlagIsSet { - Fatalf("Flags --influxdb.metrics.username, --influxdb.metrics.password are only available for influxdb-v1") - } - } - - var ( - endpoint = ctx.String(MetricsInfluxDBEndpointFlag.Name) - database = ctx.String(MetricsInfluxDBDatabaseFlag.Name) - username = ctx.String(MetricsInfluxDBUsernameFlag.Name) - password = ctx.String(MetricsInfluxDBPasswordFlag.Name) - - token = ctx.String(MetricsInfluxDBTokenFlag.Name) - bucket = ctx.String(MetricsInfluxDBBucketFlag.Name) - organization = ctx.String(MetricsInfluxDBOrganizationFlag.Name) - ) - - if enableExport { - tagsMap := SplitTagsFlag(ctx.String(MetricsInfluxDBTagsFlag.Name)) - - log.Info("Enabling metrics export to InfluxDB") - - go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap) - } else if enableExportV2 { - tagsMap := SplitTagsFlag(ctx.String(MetricsInfluxDBTagsFlag.Name)) - - log.Info("Enabling metrics export to InfluxDB (v2)") - - go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "geth.", tagsMap) - } - - if ctx.IsSet(MetricsHTTPFlag.Name) { - address := net.JoinHostPort(ctx.String(MetricsHTTPFlag.Name), fmt.Sprintf("%d", ctx.Int(MetricsPortFlag.Name))) - log.Info("Enabling stand-alone metrics HTTP endpoint", "address", address) - exp.Setup(address) - } else if ctx.IsSet(MetricsPortFlag.Name) { - log.Warn(fmt.Sprintf("--%s specified without --%s, metrics server will not start.", MetricsPortFlag.Name, MetricsHTTPFlag.Name)) - } +// SetupMetrics configures the metrics system. +func SetupMetrics(cfg *metrics.Config) { + if !cfg.Enabled { + return } + log.Info("Enabling metrics collection") + metrics.Enable() + + // InfluxDB exporter. + var ( + enableExport = cfg.EnableInfluxDB + enableExportV2 = cfg.EnableInfluxDBV2 + ) + if cfg.EnableInfluxDB && cfg.EnableInfluxDBV2 { + Fatalf("Flags %v can't be used at the same time", strings.Join([]string{MetricsEnableInfluxDBFlag.Name, MetricsEnableInfluxDBV2Flag.Name}, ", ")) + } + var ( + endpoint = cfg.InfluxDBEndpoint + database = cfg.InfluxDBDatabase + username = cfg.InfluxDBUsername + password = cfg.InfluxDBPassword + + token = cfg.InfluxDBToken + bucket = cfg.InfluxDBBucket + organization = cfg.InfluxDBOrganization + tagsMap = SplitTagsFlag(cfg.InfluxDBTags) + ) + if enableExport { + log.Info("Enabling metrics export to InfluxDB") + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap) + } else if enableExportV2 { + tagsMap := SplitTagsFlag(cfg.InfluxDBTags) + log.Info("Enabling metrics export to InfluxDB (v2)") + go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "geth.", tagsMap) + } + + // Expvar exporter. + if cfg.HTTP != "" { + address := net.JoinHostPort(cfg.HTTP, fmt.Sprintf("%d", cfg.Port)) + log.Info("Enabling stand-alone metrics HTTP endpoint", "address", address) + exp.Setup(address) + } else if cfg.HTTP == "" && cfg.Port != 0 { + log.Warn(fmt.Sprintf("--%s specified without --%s, metrics server will not start.", MetricsPortFlag.Name, MetricsHTTPFlag.Name)) + } + + // Enable system metrics collection. + go metrics.CollectProcessMetrics(3 * time.Second) } +// SplitTagsFlag parses a comma-separated list of k=v metrics tags. func SplitTagsFlag(tagsFlag string) map[string]string { tags := strings.Split(tagsFlag, ",") tagsMap := map[string]string{} diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go index a8ed17b371..38c47dc223 100644 --- a/core/rawdb/freezer_table.go +++ b/core/rawdb/freezer_table.go @@ -113,10 +113,10 @@ type freezerTable struct { headId uint32 // number of the currently active head file tailId uint32 // number of the earliest file - headBytes int64 // Number of bytes written to the head file - readMeter metrics.Meter // Meter for measuring the effective amount of data read - writeMeter metrics.Meter // Meter for measuring the effective amount of data written - sizeGauge metrics.Gauge // Gauge for tracking the combined size of all freezer tables + headBytes int64 // Number of bytes written to the head file + readMeter *metrics.Meter // Meter for measuring the effective amount of data read + writeMeter *metrics.Meter // Meter for measuring the effective amount of data written + sizeGauge *metrics.Gauge // Gauge for tracking the combined size of all freezer tables logger log.Logger // Logger with database path and table name embedded lock sync.RWMutex // Mutex protecting the data file descriptors @@ -124,13 +124,13 @@ type freezerTable struct { // newFreezerTable opens the given path as a freezer table. func newFreezerTable(path, name string, disableSnappy, readonly bool) (*freezerTable, error) { - return newTable(path, name, metrics.NilMeter{}, metrics.NilMeter{}, metrics.NilGauge{}, freezerTableSize, disableSnappy, readonly) + return newTable(path, name, metrics.NewInactiveMeter(), metrics.NewInactiveMeter(), metrics.NewGauge(), freezerTableSize, disableSnappy, readonly) } // newTable opens a freezer table, creating the data and index files if they are // non-existent. Both files are truncated to the shortest common length to ensure // they don't go out of sync. -func newTable(path string, name string, readMeter metrics.Meter, writeMeter metrics.Meter, sizeGauge metrics.Gauge, maxFilesize uint32, noCompression, readonly bool) (*freezerTable, error) { +func newTable(path string, name string, readMeter, writeMeter *metrics.Meter, sizeGauge *metrics.Gauge, maxFilesize uint32, noCompression, readonly bool) (*freezerTable, error) { // Ensure the containing directory exists and open the indexEntry file if err := os.MkdirAll(path, 0755); err != nil { return nil, err diff --git a/core/state/trie_prefetcher.go b/core/state/trie_prefetcher.go index 5b64583432..6f492cf9f2 100644 --- a/core/state/trie_prefetcher.go +++ b/core/state/trie_prefetcher.go @@ -47,21 +47,21 @@ type triePrefetcher struct { term chan struct{} // Channel to signal interruption noreads bool // Whether to ignore state-read-only prefetch requests - deliveryMissMeter metrics.Meter + deliveryMissMeter *metrics.Meter - accountLoadReadMeter metrics.Meter - accountLoadWriteMeter metrics.Meter - accountDupReadMeter metrics.Meter - accountDupWriteMeter metrics.Meter - accountDupCrossMeter metrics.Meter - accountWasteMeter metrics.Meter + accountLoadReadMeter *metrics.Meter + accountLoadWriteMeter *metrics.Meter + accountDupReadMeter *metrics.Meter + accountDupWriteMeter *metrics.Meter + accountDupCrossMeter *metrics.Meter + accountWasteMeter *metrics.Meter - storageLoadReadMeter metrics.Meter - storageLoadWriteMeter metrics.Meter - storageDupReadMeter metrics.Meter - storageDupWriteMeter metrics.Meter - storageDupCrossMeter metrics.Meter - storageWasteMeter metrics.Meter + storageLoadReadMeter *metrics.Meter + storageLoadWriteMeter *metrics.Meter + storageDupReadMeter *metrics.Meter + storageDupWriteMeter *metrics.Meter + storageDupCrossMeter *metrics.Meter + storageWasteMeter *metrics.Meter } func newTriePrefetcher(db Database, root common.Hash, namespace string, noreads bool) *triePrefetcher { @@ -111,7 +111,7 @@ func (p *triePrefetcher) terminate(async bool) { // report aggregates the pre-fetching and usage metrics and reports them. func (p *triePrefetcher) report() { - if !metrics.Enabled { + if !metrics.Enabled() { return } for _, fetcher := range p.fetchers { diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index ce455e806e..d54cf4968b 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -126,7 +126,7 @@ func (p *TxPool) reserver(id int, subpool SubPool) AddressReserver { return ErrAlreadyReserved } p.reservations[addr] = subpool - if metrics.Enabled { + if metrics.Enabled() { m := fmt.Sprintf("%s/%d", reservationsGaugeName, id) metrics.GetOrRegisterGauge(m, nil).Inc(1) } @@ -143,7 +143,7 @@ func (p *TxPool) reserver(id int, subpool SubPool) AddressReserver { return errors.New("address not owned") } delete(p.reservations, addr) - if metrics.Enabled { + if metrics.Enabled() { m := fmt.Sprintf("%s/%d", reservationsGaugeName, id) metrics.GetOrRegisterGauge(m, nil).Dec(1) } diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 6c9175a95a..a1c114f057 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -882,7 +882,7 @@ func (q *queue) DeliverReceipts(id string, receiptList [][]*types.Receipt, recei // to access the queue, so they already need a lock anyway. func (q *queue) deliver(id string, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque[int64, *types.Header], pendPool map[string]*fetchRequest, - reqTimer metrics.Timer, resInMeter metrics.Meter, resDropMeter metrics.Meter, + reqTimer *metrics.Timer, resInMeter, resDropMeter *metrics.Meter, results int, validate func(index int, header *types.Header) error, reconstruct func(index int, result *fetchResult)) (int, error) { // Short circuit if the data was never requested diff --git a/eth/handler.go b/eth/handler.go index 583dc2835d..9820118173 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -366,7 +366,7 @@ func (h *handler) runSnapExtension(peer *snap.Peer, handler snap.Handler) error defer h.decHandlers() if err := h.peers.registerSnapExtension(peer); err != nil { - if metrics.Enabled { + if metrics.Enabled() { if peer.Inbound() { snap.IngressRegistrationErrorMeter.Mark(1) } else { diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index dc32559c47..28db93a209 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -190,7 +190,7 @@ func handleMessage(backend Backend, peer *Peer) error { var handlers = eth68 // Track the amount of time it takes to serve the request and run the handler - if metrics.Enabled { + if metrics.Enabled() { h := fmt.Sprintf("%s/%s/%d/%#02x", p2p.HandleHistName, ProtocolName, peer.Version(), msg.Code) defer func(start time.Time) { sampler := func() metrics.Sample { diff --git a/eth/protocols/eth/handshake.go b/eth/protocols/eth/handshake.go index ea16a85b1e..68cf846925 100644 --- a/eth/protocols/eth/handshake.go +++ b/eth/protocols/eth/handshake.go @@ -112,7 +112,7 @@ func (p *Peer) readStatus(network uint64, status *StatusPacket, genesis common.H // markError registers the error with the corresponding metric. func markError(p *Peer, err error) { - if !metrics.Enabled { + if !metrics.Enabled() { return } m := meters.get(p.Inbound()) diff --git a/eth/protocols/eth/metrics.go b/eth/protocols/eth/metrics.go index 5e0aee39f8..adfa84936d 100644 --- a/eth/protocols/eth/metrics.go +++ b/eth/protocols/eth/metrics.go @@ -41,23 +41,23 @@ func (h *bidirectionalMeters) get(ingress bool) *hsMeters { type hsMeters struct { // peerError measures the number of errors related to incorrect peer // behaviour, such as invalid message code, size, encoding, etc. - peerError metrics.Meter + peerError *metrics.Meter // timeoutError measures the number of timeouts. - timeoutError metrics.Meter + timeoutError *metrics.Meter // networkIDMismatch measures the number of network id mismatch errors. - networkIDMismatch metrics.Meter + networkIDMismatch *metrics.Meter // protocolVersionMismatch measures the number of differing protocol // versions. - protocolVersionMismatch metrics.Meter + protocolVersionMismatch *metrics.Meter // genesisMismatch measures the number of differing genesises. - genesisMismatch metrics.Meter + genesisMismatch *metrics.Meter // forkidRejected measures the number of differing forkids. - forkidRejected metrics.Meter + forkidRejected *metrics.Meter } // newHandshakeMeters registers and returns handshake meters for the given diff --git a/eth/protocols/snap/handler.go b/eth/protocols/snap/handler.go index 8164973c20..924aff7ac9 100644 --- a/eth/protocols/snap/handler.go +++ b/eth/protocols/snap/handler.go @@ -132,7 +132,7 @@ func HandleMessage(backend Backend, peer *Peer) error { defer msg.Discard() start := time.Now() // Track the amount of time it takes to serve the request and run the handler - if metrics.Enabled { + if metrics.Enabled() { h := fmt.Sprintf("%s/%s/%d/%#02x", p2p.HandleHistName, ProtocolName, peer.Version(), msg.Code) defer func(start time.Time) { sampler := func() metrics.Sample { diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index ce7d823561..f18503c941 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -62,21 +62,21 @@ type Database struct { fn string // filename for reporting db *leveldb.DB // LevelDB instance - compTimeMeter metrics.Meter // Meter for measuring the total time spent in database compaction - compReadMeter metrics.Meter // Meter for measuring the data read during compaction - compWriteMeter metrics.Meter // Meter for measuring the data written during compaction - writeDelayNMeter metrics.Meter // Meter for measuring the write delay number due to database compaction - writeDelayMeter metrics.Meter // Meter for measuring the write delay duration due to database compaction - diskSizeGauge metrics.Gauge // Gauge for tracking the size of all the levels in the database - diskReadMeter metrics.Meter // Meter for measuring the effective amount of data read - diskWriteMeter metrics.Meter // Meter for measuring the effective amount of data written - memCompGauge metrics.Gauge // Gauge for tracking the number of memory compaction - level0CompGauge metrics.Gauge // Gauge for tracking the number of table compaction in level0 - nonlevel0CompGauge metrics.Gauge // Gauge for tracking the number of table compaction in non0 level - seekCompGauge metrics.Gauge // Gauge for tracking the number of table compaction caused by read opt - manualMemAllocGauge metrics.Gauge // Gauge to track the amount of memory that has been manually allocated (not a part of runtime/GC) + compTimeMeter *metrics.Meter // Meter for measuring the total time spent in database compaction + compReadMeter *metrics.Meter // Meter for measuring the data read during compaction + compWriteMeter *metrics.Meter // Meter for measuring the data written during compaction + writeDelayNMeter *metrics.Meter // Meter for measuring the write delay number due to database compaction + writeDelayMeter *metrics.Meter // Meter for measuring the write delay duration due to database compaction + diskSizeGauge *metrics.Gauge // Gauge for tracking the size of all the levels in the database + diskReadMeter *metrics.Meter // Meter for measuring the effective amount of data read + diskWriteMeter *metrics.Meter // Meter for measuring the effective amount of data written + memCompGauge *metrics.Gauge // Gauge for tracking the number of memory compaction + level0CompGauge *metrics.Gauge // Gauge for tracking the number of table compaction in level0 + nonlevel0CompGauge *metrics.Gauge // Gauge for tracking the number of table compaction in non0 level + seekCompGauge *metrics.Gauge // Gauge for tracking the number of table compaction caused by read opt + manualMemAllocGauge *metrics.Gauge // Gauge to track the amount of memory that has been manually allocated (not a part of runtime/GC) - levelsGauge []metrics.Gauge // Gauge for tracking the number of tables in levels + levelsGauge []*metrics.Gauge // Gauge for tracking the number of tables in levels quitLock sync.Mutex // Mutex protecting the quit channel access quitChan chan chan error // Quit channel to stop the metrics collection before closing the database diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index a9151a3bb5..8d6fcd2d51 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -58,21 +58,21 @@ type Database struct { fn string // filename for reporting db *pebble.DB // Underlying pebble storage engine - compTimeMeter metrics.Meter // Meter for measuring the total time spent in database compaction - compReadMeter metrics.Meter // Meter for measuring the data read during compaction - compWriteMeter metrics.Meter // Meter for measuring the data written during compaction - writeDelayNMeter metrics.Meter // Meter for measuring the write delay number due to database compaction - writeDelayMeter metrics.Meter // Meter for measuring the write delay duration due to database compaction - diskSizeGauge metrics.Gauge // Gauge for tracking the size of all the levels in the database - diskReadMeter metrics.Meter // Meter for measuring the effective amount of data read - diskWriteMeter metrics.Meter // Meter for measuring the effective amount of data written - memCompGauge metrics.Gauge // Gauge for tracking the number of memory compaction - level0CompGauge metrics.Gauge // Gauge for tracking the number of table compaction in level0 - nonlevel0CompGauge metrics.Gauge // Gauge for tracking the number of table compaction in non0 level - seekCompGauge metrics.Gauge // Gauge for tracking the number of table compaction caused by read opt - manualMemAllocGauge metrics.Gauge // Gauge for tracking amount of non-managed memory currently allocated + compTimeMeter *metrics.Meter // Meter for measuring the total time spent in database compaction + compReadMeter *metrics.Meter // Meter for measuring the data read during compaction + compWriteMeter *metrics.Meter // Meter for measuring the data written during compaction + writeDelayNMeter *metrics.Meter // Meter for measuring the write delay number due to database compaction + writeDelayMeter *metrics.Meter // Meter for measuring the write delay duration due to database compaction + diskSizeGauge *metrics.Gauge // Gauge for tracking the size of all the levels in the database + diskReadMeter *metrics.Meter // Meter for measuring the effective amount of data read + diskWriteMeter *metrics.Meter // Meter for measuring the effective amount of data written + memCompGauge *metrics.Gauge // Gauge for tracking the number of memory compaction + level0CompGauge *metrics.Gauge // Gauge for tracking the number of table compaction in level0 + nonlevel0CompGauge *metrics.Gauge // Gauge for tracking the number of table compaction in non0 level + seekCompGauge *metrics.Gauge // Gauge for tracking the number of table compaction caused by read opt + manualMemAllocGauge *metrics.Gauge // Gauge for tracking amount of non-managed memory currently allocated - levelsGauge []metrics.Gauge // Gauge for tracking the number of tables in levels + levelsGauge []*metrics.Gauge // Gauge for tracking the number of tables in levels quitLock sync.RWMutex // Mutex protecting the quit channel and the closed flag quitChan chan chan error // Quit channel to stop the metrics collection before closing the database diff --git a/metrics/counter.go b/metrics/counter.go index dbe8e16a90..0f373b0d92 100644 --- a/metrics/counter.go +++ b/metrics/counter.go @@ -4,109 +4,55 @@ import ( "sync/atomic" ) -type CounterSnapshot interface { - Count() int64 -} - -// Counter hold an int64 value that can be incremented and decremented. -type Counter interface { - Clear() - Dec(int64) - Inc(int64) - Snapshot() CounterSnapshot -} - // GetOrRegisterCounter returns an existing Counter or constructs and registers -// a new StandardCounter. -func GetOrRegisterCounter(name string, r Registry) Counter { - if nil == r { +// a new Counter. +func GetOrRegisterCounter(name string, r Registry) *Counter { + if r == nil { r = DefaultRegistry } - return r.GetOrRegister(name, NewCounter).(Counter) + return r.GetOrRegister(name, NewCounter).(*Counter) } -// GetOrRegisterCounterForced returns an existing Counter or constructs and registers a -// new Counter no matter the global switch is enabled or not. -// Be sure to unregister the counter from the registry once it is of no use to -// allow for garbage collection. -func GetOrRegisterCounterForced(name string, r Registry) Counter { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewCounterForced).(Counter) +// NewCounter constructs a new Counter. +func NewCounter() *Counter { + return new(Counter) } -// NewCounter constructs a new StandardCounter. -func NewCounter() Counter { - if !Enabled { - return NilCounter{} - } - return new(StandardCounter) -} - -// NewCounterForced constructs a new StandardCounter and returns it no matter if -// the global switch is enabled or not. -func NewCounterForced() Counter { - return new(StandardCounter) -} - -// NewRegisteredCounter constructs and registers a new StandardCounter. -func NewRegisteredCounter(name string, r Registry) Counter { +// NewRegisteredCounter constructs and registers a new Counter. +func NewRegisteredCounter(name string, r Registry) *Counter { c := NewCounter() - if nil == r { + if r == nil { r = DefaultRegistry } r.Register(name, c) return c } -// NewRegisteredCounterForced constructs and registers a new StandardCounter -// and launches a goroutine no matter the global switch is enabled or not. -// Be sure to unregister the counter from the registry once it is of no use to -// allow for garbage collection. -func NewRegisteredCounterForced(name string, r Registry) Counter { - c := NewCounterForced() - if nil == r { - r = DefaultRegistry - } - r.Register(name, c) - return c -} - -// counterSnapshot is a read-only copy of another Counter. -type counterSnapshot int64 +// CounterSnapshot is a read-only copy of a Counter. +type CounterSnapshot int64 // Count returns the count at the time the snapshot was taken. -func (c counterSnapshot) Count() int64 { return int64(c) } +func (c CounterSnapshot) Count() int64 { return int64(c) } -// NilCounter is a no-op Counter. -type NilCounter struct{} - -func (NilCounter) Clear() {} -func (NilCounter) Dec(i int64) {} -func (NilCounter) Inc(i int64) {} -func (NilCounter) Snapshot() CounterSnapshot { return (*emptySnapshot)(nil) } - -// StandardCounter is the standard implementation of a Counter and uses the -// sync/atomic package to manage a single int64 value. -type StandardCounter atomic.Int64 +// Counter hold an int64 value that can be incremented and decremented. +type Counter atomic.Int64 // Clear sets the counter to zero. -func (c *StandardCounter) Clear() { +func (c *Counter) Clear() { (*atomic.Int64)(c).Store(0) } // Dec decrements the counter by the given amount. -func (c *StandardCounter) Dec(i int64) { +func (c *Counter) Dec(i int64) { (*atomic.Int64)(c).Add(-i) } // Inc increments the counter by the given amount. -func (c *StandardCounter) Inc(i int64) { +func (c *Counter) Inc(i int64) { (*atomic.Int64)(c).Add(i) } // Snapshot returns a read-only copy of the counter. -func (c *StandardCounter) Snapshot() CounterSnapshot { - return counterSnapshot((*atomic.Int64)(c).Load()) +func (c *Counter) Snapshot() CounterSnapshot { + return CounterSnapshot((*atomic.Int64)(c).Load()) } diff --git a/metrics/counter_float64.go b/metrics/counter_float64.go index 15c81494ef..91c4215c4d 100644 --- a/metrics/counter_float64.go +++ b/metrics/counter_float64.go @@ -5,114 +5,57 @@ import ( "sync/atomic" ) -type CounterFloat64Snapshot interface { - Count() float64 -} - -// CounterFloat64 holds a float64 value that can be incremented and decremented. -type CounterFloat64 interface { - Clear() - Dec(float64) - Inc(float64) - Snapshot() CounterFloat64Snapshot -} - -// GetOrRegisterCounterFloat64 returns an existing CounterFloat64 or constructs and registers -// a new StandardCounterFloat64. -func GetOrRegisterCounterFloat64(name string, r Registry) CounterFloat64 { +// GetOrRegisterCounterFloat64 returns an existing *CounterFloat64 or constructs and registers +// a new CounterFloat64. +func GetOrRegisterCounterFloat64(name string, r Registry) *CounterFloat64 { if nil == r { r = DefaultRegistry } - return r.GetOrRegister(name, NewCounterFloat64).(CounterFloat64) + return r.GetOrRegister(name, NewCounterFloat64).(*CounterFloat64) } -// GetOrRegisterCounterFloat64Forced returns an existing CounterFloat64 or constructs and registers a -// new CounterFloat64 no matter the global switch is enabled or not. -// Be sure to unregister the counter from the registry once it is of no use to -// allow for garbage collection. -func GetOrRegisterCounterFloat64Forced(name string, r Registry) CounterFloat64 { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewCounterFloat64Forced).(CounterFloat64) +// NewCounterFloat64 constructs a new CounterFloat64. +func NewCounterFloat64() *CounterFloat64 { + return new(CounterFloat64) } -// NewCounterFloat64 constructs a new StandardCounterFloat64. -func NewCounterFloat64() CounterFloat64 { - if !Enabled { - return NilCounterFloat64{} - } - return &StandardCounterFloat64{} -} - -// NewCounterFloat64Forced constructs a new StandardCounterFloat64 and returns it no matter if -// the global switch is enabled or not. -func NewCounterFloat64Forced() CounterFloat64 { - return &StandardCounterFloat64{} -} - -// NewRegisteredCounterFloat64 constructs and registers a new StandardCounterFloat64. -func NewRegisteredCounterFloat64(name string, r Registry) CounterFloat64 { +// NewRegisteredCounterFloat64 constructs and registers a new CounterFloat64. +func NewRegisteredCounterFloat64(name string, r Registry) *CounterFloat64 { c := NewCounterFloat64() - if nil == r { + if r == nil { r = DefaultRegistry } r.Register(name, c) return c } -// NewRegisteredCounterFloat64Forced constructs and registers a new StandardCounterFloat64 -// and launches a goroutine no matter the global switch is enabled or not. -// Be sure to unregister the counter from the registry once it is of no use to -// allow for garbage collection. -func NewRegisteredCounterFloat64Forced(name string, r Registry) CounterFloat64 { - c := NewCounterFloat64Forced() - if nil == r { - r = DefaultRegistry - } - r.Register(name, c) - return c -} - -// counterFloat64Snapshot is a read-only copy of another CounterFloat64. -type counterFloat64Snapshot float64 +// CounterFloat64Snapshot is a read-only copy of a float64 counter. +type CounterFloat64Snapshot float64 // Count returns the value at the time the snapshot was taken. -func (c counterFloat64Snapshot) Count() float64 { return float64(c) } +func (c CounterFloat64Snapshot) Count() float64 { return float64(c) } -type NilCounterFloat64 struct{} - -func (NilCounterFloat64) Clear() {} -func (NilCounterFloat64) Count() float64 { return 0.0 } -func (NilCounterFloat64) Dec(i float64) {} -func (NilCounterFloat64) Inc(i float64) {} -func (NilCounterFloat64) Snapshot() CounterFloat64Snapshot { return NilCounterFloat64{} } - -// StandardCounterFloat64 is the standard implementation of a CounterFloat64 and uses the -// atomic to manage a single float64 value. -type StandardCounterFloat64 struct { - floatBits atomic.Uint64 -} +// CounterFloat64 holds a float64 value that can be incremented and decremented. +type CounterFloat64 atomic.Uint64 // Clear sets the counter to zero. -func (c *StandardCounterFloat64) Clear() { - c.floatBits.Store(0) +func (c *CounterFloat64) Clear() { + (*atomic.Uint64)(c).Store(0) } // Dec decrements the counter by the given amount. -func (c *StandardCounterFloat64) Dec(v float64) { - atomicAddFloat(&c.floatBits, -v) +func (c *CounterFloat64) Dec(v float64) { + atomicAddFloat((*atomic.Uint64)(c), -v) } // Inc increments the counter by the given amount. -func (c *StandardCounterFloat64) Inc(v float64) { - atomicAddFloat(&c.floatBits, v) +func (c *CounterFloat64) Inc(v float64) { + atomicAddFloat((*atomic.Uint64)(c), v) } // Snapshot returns a read-only copy of the counter. -func (c *StandardCounterFloat64) Snapshot() CounterFloat64Snapshot { - v := math.Float64frombits(c.floatBits.Load()) - return counterFloat64Snapshot(v) +func (c *CounterFloat64) Snapshot() CounterFloat64Snapshot { + return CounterFloat64Snapshot(math.Float64frombits((*atomic.Uint64)(c).Load())) } func atomicAddFloat(fbits *atomic.Uint64, v float64) { diff --git a/metrics/counter_float_64_test.go b/metrics/counter_float_64_test.go index c21bd3307f..618cbbbc2b 100644 --- a/metrics/counter_float_64_test.go +++ b/metrics/counter_float_64_test.go @@ -32,61 +32,35 @@ func BenchmarkCounterFloat64Parallel(b *testing.B) { } } -func TestCounterFloat64Clear(t *testing.T) { +func TestCounterFloat64(t *testing.T) { c := NewCounterFloat64() - c.Inc(1.0) - c.Clear() if count := c.Snapshot().Count(); count != 0 { - t.Errorf("c.Count(): 0 != %v\n", count) + t.Errorf("wrong count: %v", count) } -} - -func TestCounterFloat64Dec1(t *testing.T) { - c := NewCounterFloat64() c.Dec(1.0) if count := c.Snapshot().Count(); count != -1.0 { - t.Errorf("c.Count(): -1.0 != %v\n", count) + t.Errorf("wrong count: %v", count) } -} - -func TestCounterFloat64Dec2(t *testing.T) { - c := NewCounterFloat64() - c.Dec(2.0) - if count := c.Snapshot().Count(); count != -2.0 { - t.Errorf("c.Count(): -2.0 != %v\n", count) - } -} - -func TestCounterFloat64Inc1(t *testing.T) { - c := NewCounterFloat64() - c.Inc(1.0) - if count := c.Snapshot().Count(); count != 1.0 { - t.Errorf("c.Count(): 1.0 != %v\n", count) - } -} - -func TestCounterFloat64Inc2(t *testing.T) { - c := NewCounterFloat64() - c.Inc(2.0) - if count := c.Snapshot().Count(); count != 2.0 { - t.Errorf("c.Count(): 2.0 != %v\n", count) - } -} - -func TestCounterFloat64Snapshot(t *testing.T) { - c := NewCounterFloat64() - c.Inc(1.0) snapshot := c.Snapshot() - c.Inc(1.0) - if count := snapshot.Count(); count != 1.0 { - t.Errorf("c.Count(): 1.0 != %v\n", count) + c.Dec(2.0) + if count := c.Snapshot().Count(); count != -3.0 { + t.Errorf("wrong count: %v", count) } -} - -func TestCounterFloat64Zero(t *testing.T) { - c := NewCounterFloat64() - if count := c.Snapshot().Count(); count != 0 { - t.Errorf("c.Count(): 0 != %v\n", count) + c.Inc(1.0) + if count := c.Snapshot().Count(); count != -2.0 { + t.Errorf("wrong count: %v", count) + } + c.Inc(2.0) + if count := c.Snapshot().Count(); count != 0.0 { + t.Errorf("wrong count: %v", count) + } + if count := snapshot.Count(); count != -1.0 { + t.Errorf("snapshot count wrong: %v", count) + } + c.Inc(1.0) + c.Clear() + if count := c.Snapshot().Count(); count != 0.0 { + t.Errorf("wrong count: %v", count) } } diff --git a/metrics/counter_test.go b/metrics/counter_test.go index 1b15b23f21..bf0ca6bae4 100644 --- a/metrics/counter_test.go +++ b/metrics/counter_test.go @@ -19,35 +19,26 @@ func TestCounterClear(t *testing.T) { } } -func TestCounterDec1(t *testing.T) { +func TestCounter(t *testing.T) { c := NewCounter() + if count := c.Snapshot().Count(); count != 0 { + t.Errorf("wrong count: %v", count) + } c.Dec(1) if count := c.Snapshot().Count(); count != -1 { - t.Errorf("c.Count(): -1 != %v\n", count) + t.Errorf("wrong count: %v", count) } -} - -func TestCounterDec2(t *testing.T) { - c := NewCounter() c.Dec(2) - if count := c.Snapshot().Count(); count != -2 { - t.Errorf("c.Count(): -2 != %v\n", count) + if count := c.Snapshot().Count(); count != -3 { + t.Errorf("wrong count: %v", count) } -} - -func TestCounterInc1(t *testing.T) { - c := NewCounter() c.Inc(1) - if count := c.Snapshot().Count(); count != 1 { - t.Errorf("c.Count(): 1 != %v\n", count) + if count := c.Snapshot().Count(); count != -2 { + t.Errorf("wrong count: %v", count) } -} - -func TestCounterInc2(t *testing.T) { - c := NewCounter() c.Inc(2) - if count := c.Snapshot().Count(); count != 2 { - t.Errorf("c.Count(): 2 != %v\n", count) + if count := c.Snapshot().Count(); count != 0 { + t.Errorf("wrong count: %v", count) } } @@ -61,13 +52,6 @@ func TestCounterSnapshot(t *testing.T) { } } -func TestCounterZero(t *testing.T) { - c := NewCounter() - if count := c.Snapshot().Count(); count != 0 { - t.Errorf("c.Count(): 0 != %v\n", count) - } -} - func TestGetOrRegisterCounter(t *testing.T) { r := NewRegistry() NewRegisteredCounter("foo", r).Inc(47) diff --git a/metrics/debug.go b/metrics/debug.go index 9dfee1a866..5d0d3992f1 100644 --- a/metrics/debug.go +++ b/metrics/debug.go @@ -8,13 +8,13 @@ import ( var ( debugMetrics struct { GCStats struct { - LastGC Gauge - NumGC Gauge + LastGC *Gauge + NumGC *Gauge Pause Histogram //PauseQuantiles Histogram - PauseTotal Gauge + PauseTotal *Gauge } - ReadGCStats Timer + ReadGCStats *Timer } gcStats debug.GCStats ) diff --git a/metrics/ewma.go b/metrics/ewma.go index 1d7a4f00cf..194527a798 100644 --- a/metrics/ewma.go +++ b/metrics/ewma.go @@ -7,56 +7,36 @@ import ( "time" ) -type EWMASnapshot interface { - Rate() float64 -} +// EWMASnapshot is a read-only copy of an EWMA. +type EWMASnapshot float64 -// EWMAs continuously calculate an exponentially-weighted moving average -// based on an outside source of clock ticks. -type EWMA interface { - Snapshot() EWMASnapshot - Tick() - Update(int64) -} +// Rate returns the rate of events per second at the time the snapshot was +// taken. +func (a EWMASnapshot) Rate() float64 { return float64(a) } // NewEWMA constructs a new EWMA with the given alpha. -func NewEWMA(alpha float64) EWMA { - return &StandardEWMA{alpha: alpha} +func NewEWMA(alpha float64) *EWMA { + return &EWMA{alpha: alpha} } // NewEWMA1 constructs a new EWMA for a one-minute moving average. -func NewEWMA1() EWMA { +func NewEWMA1() *EWMA { return NewEWMA(1 - math.Exp(-5.0/60.0/1)) } // NewEWMA5 constructs a new EWMA for a five-minute moving average. -func NewEWMA5() EWMA { +func NewEWMA5() *EWMA { return NewEWMA(1 - math.Exp(-5.0/60.0/5)) } // NewEWMA15 constructs a new EWMA for a fifteen-minute moving average. -func NewEWMA15() EWMA { +func NewEWMA15() *EWMA { return NewEWMA(1 - math.Exp(-5.0/60.0/15)) } -// ewmaSnapshot is a read-only copy of another EWMA. -type ewmaSnapshot float64 - -// Rate returns the rate of events per second at the time the snapshot was -// taken. -func (a ewmaSnapshot) Rate() float64 { return float64(a) } - -// NilEWMA is a no-op EWMA. -type NilEWMA struct{} - -func (NilEWMA) Snapshot() EWMASnapshot { return (*emptySnapshot)(nil) } -func (NilEWMA) Tick() {} -func (NilEWMA) Update(n int64) {} - -// StandardEWMA is the standard implementation of an EWMA and tracks the number -// of uncounted events and processes them on each tick. It uses the -// sync/atomic package to manage uncounted events. -type StandardEWMA struct { +// EWMA continuously calculate an exponentially-weighted moving average +// based on an outside source of clock ticks. +type EWMA struct { uncounted atomic.Int64 alpha float64 rate atomic.Uint64 @@ -65,27 +45,27 @@ type StandardEWMA struct { } // Snapshot returns a read-only copy of the EWMA. -func (a *StandardEWMA) Snapshot() EWMASnapshot { +func (a *EWMA) Snapshot() EWMASnapshot { r := math.Float64frombits(a.rate.Load()) * float64(time.Second) - return ewmaSnapshot(r) + return EWMASnapshot(r) } -// Tick ticks the clock to update the moving average. It assumes it is called +// tick ticks the clock to update the moving average. It assumes it is called // every five seconds. -func (a *StandardEWMA) Tick() { +func (a *EWMA) tick() { // Optimization to avoid mutex locking in the hot-path. if a.init.Load() { a.updateRate(a.fetchInstantRate()) return } - // Slow-path: this is only needed on the first Tick() and preserves transactional updating + // Slow-path: this is only needed on the first tick() and preserves transactional updating // of init and rate in the else block. The first conditional is needed below because // a different thread could have set a.init = 1 between the time of the first atomic load and when // the lock was acquired. a.mutex.Lock() if a.init.Load() { // The fetchInstantRate() uses atomic loading, which is unnecessary in this critical section - // but again, this section is only invoked on the first successful Tick() operation. + // but again, this section is only invoked on the first successful tick() operation. a.updateRate(a.fetchInstantRate()) } else { a.init.Store(true) @@ -94,18 +74,18 @@ func (a *StandardEWMA) Tick() { a.mutex.Unlock() } -func (a *StandardEWMA) fetchInstantRate() float64 { +func (a *EWMA) fetchInstantRate() float64 { count := a.uncounted.Swap(0) return float64(count) / float64(5*time.Second) } -func (a *StandardEWMA) updateRate(instantRate float64) { +func (a *EWMA) updateRate(instantRate float64) { currentRate := math.Float64frombits(a.rate.Load()) currentRate += a.alpha * (instantRate - currentRate) a.rate.Store(math.Float64bits(currentRate)) } // Update adds n uncounted events. -func (a *StandardEWMA) Update(n int64) { +func (a *EWMA) Update(n int64) { a.uncounted.Add(n) } diff --git a/metrics/ewma_test.go b/metrics/ewma_test.go index 9a91b43db8..4b9bde3a4b 100644 --- a/metrics/ewma_test.go +++ b/metrics/ewma_test.go @@ -12,7 +12,7 @@ func BenchmarkEWMA(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { a.Update(1) - a.Tick() + a.tick() } } @@ -23,7 +23,7 @@ func BenchmarkEWMAParallel(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { a.Update(1) - a.Tick() + a.tick() } }) } @@ -31,7 +31,7 @@ func BenchmarkEWMAParallel(b *testing.B) { func TestEWMA1(t *testing.T) { a := NewEWMA1() a.Update(3) - a.Tick() + a.tick() for i, want := range []float64{0.6, 0.22072766470286553, 0.08120116994196772, 0.029872241020718428, 0.01098938333324054, 0.004042768199451294, 0.0014872513059998212, @@ -49,7 +49,7 @@ func TestEWMA1(t *testing.T) { func TestEWMA5(t *testing.T) { a := NewEWMA5() a.Update(3) - a.Tick() + a.tick() for i, want := range []float64{ 0.6, 0.49123845184678905, 0.4021920276213837, 0.32928698165641596, 0.269597378470333, 0.2207276647028654, 0.18071652714732128, @@ -67,7 +67,7 @@ func TestEWMA5(t *testing.T) { func TestEWMA15(t *testing.T) { a := NewEWMA15() a.Update(3) - a.Tick() + a.tick() for i, want := range []float64{ 0.6, 0.5613041910189706, 0.5251039914257684, 0.4912384518467888184678905, 0.459557003018789, 0.4299187863442732, 0.4021920276213831, @@ -82,8 +82,8 @@ func TestEWMA15(t *testing.T) { } } -func elapseMinute(a EWMA) { +func elapseMinute(a *EWMA) { for i := 0; i < 12; i++ { - a.Tick() + a.tick() } } diff --git a/metrics/exp/exp.go b/metrics/exp/exp.go index 7e3f82a075..5213979aa2 100644 --- a/metrics/exp/exp.go +++ b/metrics/exp/exp.go @@ -146,7 +146,7 @@ func (exp *exp) publishHistogram(name string, metric metrics.Histogram) { exp.getFloat(name + ".999-percentile").Set(ps[4]) } -func (exp *exp) publishMeter(name string, metric metrics.Meter) { +func (exp *exp) publishMeter(name string, metric *metrics.Meter) { m := metric.Snapshot() exp.getInt(name + ".count").Set(m.Count()) exp.getFloat(name + ".one-minute").Set(m.Rate1()) @@ -155,7 +155,7 @@ func (exp *exp) publishMeter(name string, metric metrics.Meter) { exp.getFloat(name + ".mean").Set(m.RateMean()) } -func (exp *exp) publishTimer(name string, metric metrics.Timer) { +func (exp *exp) publishTimer(name string, metric *metrics.Timer) { t := metric.Snapshot() ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) exp.getInt(name + ".count").Set(t.Count()) @@ -174,7 +174,7 @@ func (exp *exp) publishTimer(name string, metric metrics.Timer) { exp.getFloat(name + ".mean-rate").Set(t.RateMean()) } -func (exp *exp) publishResettingTimer(name string, metric metrics.ResettingTimer) { +func (exp *exp) publishResettingTimer(name string, metric *metrics.ResettingTimer) { t := metric.Snapshot() ps := t.Percentiles([]float64{0.50, 0.75, 0.95, 0.99}) exp.getInt(name + ".count").Set(int64(t.Count())) @@ -188,23 +188,23 @@ func (exp *exp) publishResettingTimer(name string, metric metrics.ResettingTimer func (exp *exp) syncToExpvar() { exp.registry.Each(func(name string, i interface{}) { switch i := i.(type) { - case metrics.Counter: + case *metrics.Counter: exp.publishCounter(name, i.Snapshot()) - case metrics.CounterFloat64: + case *metrics.CounterFloat64: exp.publishCounterFloat64(name, i.Snapshot()) - case metrics.Gauge: + case *metrics.Gauge: exp.publishGauge(name, i.Snapshot()) - case metrics.GaugeFloat64: + case *metrics.GaugeFloat64: exp.publishGaugeFloat64(name, i.Snapshot()) - case metrics.GaugeInfo: + case *metrics.GaugeInfo: exp.publishGaugeInfo(name, i.Snapshot()) case metrics.Histogram: exp.publishHistogram(name, i) - case metrics.Meter: + case *metrics.Meter: exp.publishMeter(name, i) - case metrics.Timer: + case *metrics.Timer: exp.publishTimer(name, i) - case metrics.ResettingTimer: + case *metrics.ResettingTimer: exp.publishResettingTimer(name, i) default: panic(fmt.Sprintf("unsupported type for '%s': %T", name, i)) diff --git a/metrics/gauge.go b/metrics/gauge.go index 6d10bbf856..ba7843e03b 100644 --- a/metrics/gauge.go +++ b/metrics/gauge.go @@ -2,97 +2,69 @@ package metrics import "sync/atomic" -// GaugeSnapshot contains a readonly int64. -type GaugeSnapshot interface { - Value() int64 -} +// GaugeSnapshot is a read-only copy of a Gauge. +type GaugeSnapshot int64 -// Gauge holds an int64 value that can be set arbitrarily. -type Gauge interface { - Snapshot() GaugeSnapshot - Update(int64) - UpdateIfGt(int64) - Dec(int64) - Inc(int64) -} +// Value returns the value at the time the snapshot was taken. +func (g GaugeSnapshot) Value() int64 { return int64(g) } // GetOrRegisterGauge returns an existing Gauge or constructs and registers a -// new StandardGauge. -func GetOrRegisterGauge(name string, r Registry) Gauge { - if nil == r { +// new Gauge. +func GetOrRegisterGauge(name string, r Registry) *Gauge { + if r == nil { r = DefaultRegistry } - return r.GetOrRegister(name, NewGauge).(Gauge) + return r.GetOrRegister(name, NewGauge).(*Gauge) } -// NewGauge constructs a new StandardGauge. -func NewGauge() Gauge { - if !Enabled { - return NilGauge{} - } - return &StandardGauge{} +// NewGauge constructs a new Gauge. +func NewGauge() *Gauge { + return &Gauge{} } -// NewRegisteredGauge constructs and registers a new StandardGauge. -func NewRegisteredGauge(name string, r Registry) Gauge { +// NewRegisteredGauge constructs and registers a new Gauge. +func NewRegisteredGauge(name string, r Registry) *Gauge { c := NewGauge() - if nil == r { + if r == nil { r = DefaultRegistry } r.Register(name, c) return c } -// gaugeSnapshot is a read-only copy of another Gauge. -type gaugeSnapshot int64 - -// Value returns the value at the time the snapshot was taken. -func (g gaugeSnapshot) Value() int64 { return int64(g) } - -// NilGauge is a no-op Gauge. -type NilGauge struct{} - -func (NilGauge) Snapshot() GaugeSnapshot { return (*emptySnapshot)(nil) } -func (NilGauge) Update(v int64) {} -func (NilGauge) UpdateIfGt(v int64) {} -func (NilGauge) Dec(i int64) {} -func (NilGauge) Inc(i int64) {} - -// StandardGauge is the standard implementation of a Gauge and uses the -// sync/atomic package to manage a single int64 value. -type StandardGauge struct { - value atomic.Int64 -} +// Gauge holds an int64 value that can be set arbitrarily. +type Gauge atomic.Int64 // Snapshot returns a read-only copy of the gauge. -func (g *StandardGauge) Snapshot() GaugeSnapshot { - return gaugeSnapshot(g.value.Load()) +func (g *Gauge) Snapshot() GaugeSnapshot { + return GaugeSnapshot((*atomic.Int64)(g).Load()) } // Update updates the gauge's value. -func (g *StandardGauge) Update(v int64) { - g.value.Store(v) +func (g *Gauge) Update(v int64) { + (*atomic.Int64)(g).Store(v) } // UpdateIfGt updates the gauge's value if v is larger then the current value. -func (g *StandardGauge) UpdateIfGt(v int64) { +func (g *Gauge) UpdateIfGt(v int64) { + value := (*atomic.Int64)(g) for { - exist := g.value.Load() + exist := value.Load() if exist >= v { break } - if g.value.CompareAndSwap(exist, v) { + if value.CompareAndSwap(exist, v) { break } } } // Dec decrements the gauge's current value by the given amount. -func (g *StandardGauge) Dec(i int64) { - g.value.Add(-i) +func (g *Gauge) Dec(i int64) { + (*atomic.Int64)(g).Add(-i) } // Inc increments the gauge's current value by the given amount. -func (g *StandardGauge) Inc(i int64) { - g.value.Add(i) +func (g *Gauge) Inc(i int64) { + (*atomic.Int64)(g).Add(i) } diff --git a/metrics/gauge_float64.go b/metrics/gauge_float64.go index c1c3c6b6e6..05b401ef9c 100644 --- a/metrics/gauge_float64.go +++ b/metrics/gauge_float64.go @@ -5,35 +5,28 @@ import ( "sync/atomic" ) -type GaugeFloat64Snapshot interface { - Value() float64 -} - -// GaugeFloat64 hold a float64 value that can be set arbitrarily. -type GaugeFloat64 interface { - Snapshot() GaugeFloat64Snapshot - Update(float64) -} - // GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a -// new StandardGaugeFloat64. -func GetOrRegisterGaugeFloat64(name string, r Registry) GaugeFloat64 { +// new GaugeFloat64. +func GetOrRegisterGaugeFloat64(name string, r Registry) *GaugeFloat64 { if nil == r { r = DefaultRegistry } - return r.GetOrRegister(name, NewGaugeFloat64()).(GaugeFloat64) + return r.GetOrRegister(name, NewGaugeFloat64()).(*GaugeFloat64) } -// NewGaugeFloat64 constructs a new StandardGaugeFloat64. -func NewGaugeFloat64() GaugeFloat64 { - if !Enabled { - return NilGaugeFloat64{} - } - return &StandardGaugeFloat64{} +// GaugeFloat64Snapshot is a read-only copy of a GaugeFloat64. +type GaugeFloat64Snapshot float64 + +// Value returns the value at the time the snapshot was taken. +func (g GaugeFloat64Snapshot) Value() float64 { return float64(g) } + +// NewGaugeFloat64 constructs a new GaugeFloat64. +func NewGaugeFloat64() *GaugeFloat64 { + return new(GaugeFloat64) } -// NewRegisteredGaugeFloat64 constructs and registers a new StandardGaugeFloat64. -func NewRegisteredGaugeFloat64(name string, r Registry) GaugeFloat64 { +// NewRegisteredGaugeFloat64 constructs and registers a new GaugeFloat64. +func NewRegisteredGaugeFloat64(name string, r Registry) *GaugeFloat64 { c := NewGaugeFloat64() if nil == r { r = DefaultRegistry @@ -42,32 +35,16 @@ func NewRegisteredGaugeFloat64(name string, r Registry) GaugeFloat64 { return c } -// gaugeFloat64Snapshot is a read-only copy of another GaugeFloat64. -type gaugeFloat64Snapshot float64 - -// Value returns the value at the time the snapshot was taken. -func (g gaugeFloat64Snapshot) Value() float64 { return float64(g) } - -// NilGaugeFloat64 is a no-op Gauge. -type NilGaugeFloat64 struct{} - -func (NilGaugeFloat64) Snapshot() GaugeFloat64Snapshot { return NilGaugeFloat64{} } -func (NilGaugeFloat64) Update(v float64) {} -func (NilGaugeFloat64) Value() float64 { return 0.0 } - -// StandardGaugeFloat64 is the standard implementation of a GaugeFloat64 and uses -// atomic to manage a single float64 value. -type StandardGaugeFloat64 struct { - floatBits atomic.Uint64 -} +// GaugeFloat64 hold a float64 value that can be set arbitrarily. +type GaugeFloat64 atomic.Uint64 // Snapshot returns a read-only copy of the gauge. -func (g *StandardGaugeFloat64) Snapshot() GaugeFloat64Snapshot { - v := math.Float64frombits(g.floatBits.Load()) - return gaugeFloat64Snapshot(v) +func (g *GaugeFloat64) Snapshot() GaugeFloat64Snapshot { + v := math.Float64frombits((*atomic.Uint64)(g).Load()) + return GaugeFloat64Snapshot(v) } // Update updates the gauge's value. -func (g *StandardGaugeFloat64) Update(v float64) { - g.floatBits.Store(math.Float64bits(v)) +func (g *GaugeFloat64) Update(v float64) { + (*atomic.Uint64)(g).Store(math.Float64bits(v)) } diff --git a/metrics/gauge_info.go b/metrics/gauge_info.go index 0010edc324..2f78455649 100644 --- a/metrics/gauge_info.go +++ b/metrics/gauge_info.go @@ -5,16 +5,6 @@ import ( "sync" ) -type GaugeInfoSnapshot interface { - Value() GaugeInfoValue -} - -// GaugeInfo holds a GaugeInfoValue value that can be set arbitrarily. -type GaugeInfo interface { - Update(GaugeInfoValue) - Snapshot() GaugeInfoSnapshot -} - // GaugeInfoValue is a mapping of keys to values type GaugeInfoValue map[string]string @@ -24,26 +14,23 @@ func (val GaugeInfoValue) String() string { } // GetOrRegisterGaugeInfo returns an existing GaugeInfo or constructs and registers a -// new StandardGaugeInfo. -func GetOrRegisterGaugeInfo(name string, r Registry) GaugeInfo { +// new GaugeInfo. +func GetOrRegisterGaugeInfo(name string, r Registry) *GaugeInfo { if nil == r { r = DefaultRegistry } - return r.GetOrRegister(name, NewGaugeInfo()).(GaugeInfo) + return r.GetOrRegister(name, NewGaugeInfo()).(*GaugeInfo) } -// NewGaugeInfo constructs a new StandardGaugeInfo. -func NewGaugeInfo() GaugeInfo { - if !Enabled { - return NilGaugeInfo{} - } - return &StandardGaugeInfo{ +// NewGaugeInfo constructs a new GaugeInfo. +func NewGaugeInfo() *GaugeInfo { + return &GaugeInfo{ value: GaugeInfoValue{}, } } -// NewRegisteredGaugeInfo constructs and registers a new StandardGaugeInfo. -func NewRegisteredGaugeInfo(name string, r Registry) GaugeInfo { +// NewRegisteredGaugeInfo constructs and registers a new GaugeInfo. +func NewRegisteredGaugeInfo(name string, r Registry) *GaugeInfo { c := NewGaugeInfo() if nil == r { r = DefaultRegistry @@ -53,31 +40,24 @@ func NewRegisteredGaugeInfo(name string, r Registry) GaugeInfo { } // gaugeInfoSnapshot is a read-only copy of another GaugeInfo. -type gaugeInfoSnapshot GaugeInfoValue +type GaugeInfoSnapshot GaugeInfoValue // Value returns the value at the time the snapshot was taken. -func (g gaugeInfoSnapshot) Value() GaugeInfoValue { return GaugeInfoValue(g) } +func (g GaugeInfoSnapshot) Value() GaugeInfoValue { return GaugeInfoValue(g) } -type NilGaugeInfo struct{} - -func (NilGaugeInfo) Snapshot() GaugeInfoSnapshot { return NilGaugeInfo{} } -func (NilGaugeInfo) Update(v GaugeInfoValue) {} -func (NilGaugeInfo) Value() GaugeInfoValue { return GaugeInfoValue{} } - -// StandardGaugeInfo is the standard implementation of a GaugeInfo and uses -// sync.Mutex to manage a single string value. -type StandardGaugeInfo struct { +// GaugeInfo maintains a set of key/value mappings. +type GaugeInfo struct { mutex sync.Mutex value GaugeInfoValue } // Snapshot returns a read-only copy of the gauge. -func (g *StandardGaugeInfo) Snapshot() GaugeInfoSnapshot { - return gaugeInfoSnapshot(g.value) +func (g *GaugeInfo) Snapshot() GaugeInfoSnapshot { + return GaugeInfoSnapshot(g.value) } // Update updates the gauge's value. -func (g *StandardGaugeInfo) Update(v GaugeInfoValue) { +func (g *GaugeInfo) Update(v GaugeInfoValue) { g.mutex.Lock() defer g.mutex.Unlock() g.value = v diff --git a/metrics/graphite.go b/metrics/graphite.go deleted file mode 100644 index aba752e0ed..0000000000 --- a/metrics/graphite.go +++ /dev/null @@ -1,117 +0,0 @@ -package metrics - -import ( - "bufio" - "fmt" - "log" - "net" - "strconv" - "strings" - "time" -) - -// GraphiteConfig provides a container with configuration parameters for -// the Graphite exporter -type GraphiteConfig struct { - Addr *net.TCPAddr // Network address to connect to - Registry Registry // Registry to be exported - FlushInterval time.Duration // Flush interval - DurationUnit time.Duration // Time conversion unit for durations - Prefix string // Prefix to be prepended to metric names - Percentiles []float64 // Percentiles to export from timers and histograms -} - -// Graphite is a blocking exporter function which reports metrics in r -// to a graphite server located at addr, flushing them every d duration -// and prepending metric names with prefix. -func Graphite(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) { - GraphiteWithConfig(GraphiteConfig{ - Addr: addr, - Registry: r, - FlushInterval: d, - DurationUnit: time.Nanosecond, - Prefix: prefix, - Percentiles: []float64{0.5, 0.75, 0.95, 0.99, 0.999}, - }) -} - -// GraphiteWithConfig is a blocking exporter function just like Graphite, -// but it takes a GraphiteConfig instead. -func GraphiteWithConfig(c GraphiteConfig) { - log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015") - for range time.Tick(c.FlushInterval) { - if err := graphite(&c); nil != err { - log.Println(err) - } - } -} - -// GraphiteOnce performs a single submission to Graphite, returning a -// non-nil error on failed connections. This can be used in a loop -// similar to GraphiteWithConfig for custom error handling. -func GraphiteOnce(c GraphiteConfig) error { - log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015") - return graphite(&c) -} - -func graphite(c *GraphiteConfig) error { - now := time.Now().Unix() - du := float64(c.DurationUnit) - conn, err := net.DialTCP("tcp", nil, c.Addr) - if nil != err { - return err - } - defer conn.Close() - w := bufio.NewWriter(conn) - c.Registry.Each(func(name string, i interface{}) { - switch metric := i.(type) { - case Counter: - fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, metric.Snapshot().Count(), now) - case CounterFloat64: - fmt.Fprintf(w, "%s.%s.count %f %d\n", c.Prefix, name, metric.Snapshot().Count(), now) - case Gauge: - fmt.Fprintf(w, "%s.%s.value %d %d\n", c.Prefix, name, metric.Snapshot().Value(), now) - case GaugeFloat64: - fmt.Fprintf(w, "%s.%s.value %f %d\n", c.Prefix, name, metric.Snapshot().Value(), now) - case GaugeInfo: - fmt.Fprintf(w, "%s.%s.value %s %d\n", c.Prefix, name, metric.Snapshot().Value().String(), now) - case Histogram: - h := metric.Snapshot() - ps := h.Percentiles(c.Percentiles) - fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, h.Count(), now) - fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, h.Min(), now) - fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, h.Max(), now) - fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, h.Mean(), now) - fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, h.StdDev(), now) - for psIdx, psKey := range c.Percentiles { - key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1) - fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now) - } - case Meter: - m := metric.Snapshot() - fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now) - fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, m.Rate1(), now) - fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, m.Rate5(), now) - fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, m.Rate15(), now) - fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, m.RateMean(), now) - case Timer: - t := metric.Snapshot() - ps := t.Percentiles(c.Percentiles) - fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, t.Count(), now) - fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, t.Min()/int64(du), now) - fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, t.Max()/int64(du), now) - fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, t.Mean()/du, now) - fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, t.StdDev()/du, now) - for psIdx, psKey := range c.Percentiles { - key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1) - fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now) - } - fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, t.Rate1(), now) - fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, t.Rate5(), now) - fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, t.Rate15(), now) - fmt.Fprintf(w, "%s.%s.mean-rate %.2f %d\n", c.Prefix, name, t.RateMean(), now) - } - w.Flush() - }) - return nil -} diff --git a/metrics/graphite_test.go b/metrics/graphite_test.go deleted file mode 100644 index c797c781df..0000000000 --- a/metrics/graphite_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package metrics - -import ( - "net" - "time" -) - -func ExampleGraphite() { - addr, _ := net.ResolveTCPAddr("net", ":2003") - go Graphite(DefaultRegistry, 1*time.Second, "some.prefix", addr) -} - -func ExampleGraphiteWithConfig() { - addr, _ := net.ResolveTCPAddr("net", ":2003") - go GraphiteWithConfig(GraphiteConfig{ - Addr: addr, - Registry: DefaultRegistry, - FlushInterval: 1 * time.Second, - DurationUnit: time.Millisecond, - Percentiles: []float64{0.5, 0.75, 0.99, 0.999}, - }) -} diff --git a/metrics/healthcheck.go b/metrics/healthcheck.go index adcd15ab58..435e5e0bf9 100644 --- a/metrics/healthcheck.go +++ b/metrics/healthcheck.go @@ -1,61 +1,35 @@ package metrics -// Healthcheck holds an error value describing an arbitrary up/down status. -type Healthcheck interface { - Check() - Error() error - Healthy() - Unhealthy(error) -} - // NewHealthcheck constructs a new Healthcheck which will use the given // function to update its status. -func NewHealthcheck(f func(Healthcheck)) Healthcheck { - if !Enabled { - return NilHealthcheck{} - } - return &StandardHealthcheck{nil, f} +func NewHealthcheck(f func(*Healthcheck)) *Healthcheck { + return &Healthcheck{nil, f} } -// NilHealthcheck is a no-op. -type NilHealthcheck struct{} - -// Check is a no-op. -func (NilHealthcheck) Check() {} - -// Error is a no-op. -func (NilHealthcheck) Error() error { return nil } - -// Healthy is a no-op. -func (NilHealthcheck) Healthy() {} - -// Unhealthy is a no-op. -func (NilHealthcheck) Unhealthy(error) {} - -// StandardHealthcheck is the standard implementation of a Healthcheck and +// Healthcheck is the standard implementation of a Healthcheck and // stores the status and a function to call to update the status. -type StandardHealthcheck struct { +type Healthcheck struct { err error - f func(Healthcheck) + f func(*Healthcheck) } // Check runs the healthcheck function to update the healthcheck's status. -func (h *StandardHealthcheck) Check() { +func (h *Healthcheck) Check() { h.f(h) } // Error returns the healthcheck's status, which will be nil if it is healthy. -func (h *StandardHealthcheck) Error() error { +func (h *Healthcheck) Error() error { return h.err } // Healthy marks the healthcheck as healthy. -func (h *StandardHealthcheck) Healthy() { +func (h *Healthcheck) Healthy() { h.err = nil } // Unhealthy marks the healthcheck as unhealthy. The error is stored and // may be retrieved by the Error method. -func (h *StandardHealthcheck) Unhealthy(err error) { +func (h *Healthcheck) Unhealthy(err error) { h.err = err } diff --git a/metrics/histogram.go b/metrics/histogram.go index 10259a2463..7c27bcc928 100644 --- a/metrics/histogram.go +++ b/metrics/histogram.go @@ -1,7 +1,16 @@ package metrics type HistogramSnapshot interface { - SampleSnapshot + Count() int64 + Max() int64 + Mean() float64 + Min() int64 + Percentile(float64) float64 + Percentiles([]float64) []float64 + Size() int + StdDev() float64 + Sum() int64 + Variance() float64 } // Histogram calculates distribution statistics from a series of int64 values. @@ -31,10 +40,7 @@ func GetOrRegisterHistogramLazy(name string, r Registry, s func() Sample) Histog // NewHistogram constructs a new StandardHistogram from a Sample. func NewHistogram(s Sample) Histogram { - if !Enabled { - return NilHistogram{} - } - return &StandardHistogram{sample: s} + return &StandardHistogram{s} } // NewRegisteredHistogram constructs and registers a new StandardHistogram from @@ -48,13 +54,6 @@ func NewRegisteredHistogram(name string, r Registry, s Sample) Histogram { return c } -// NilHistogram is a no-op Histogram. -type NilHistogram struct{} - -func (NilHistogram) Clear() {} -func (NilHistogram) Snapshot() HistogramSnapshot { return (*emptySnapshot)(nil) } -func (NilHistogram) Update(v int64) {} - // StandardHistogram is the standard implementation of a Histogram and uses a // Sample to bound its memory use. type StandardHistogram struct { diff --git a/metrics/inactive.go b/metrics/inactive.go deleted file mode 100644 index 1f47f0210a..0000000000 --- a/metrics/inactive.go +++ /dev/null @@ -1,48 +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 metrics - -// compile-time checks that interfaces are implemented. -var ( - _ SampleSnapshot = (*emptySnapshot)(nil) - _ HistogramSnapshot = (*emptySnapshot)(nil) - _ CounterSnapshot = (*emptySnapshot)(nil) - _ GaugeSnapshot = (*emptySnapshot)(nil) - _ MeterSnapshot = (*emptySnapshot)(nil) - _ EWMASnapshot = (*emptySnapshot)(nil) - _ TimerSnapshot = (*emptySnapshot)(nil) -) - -type emptySnapshot struct{} - -func (*emptySnapshot) Count() int64 { return 0 } -func (*emptySnapshot) Max() int64 { return 0 } -func (*emptySnapshot) Mean() float64 { return 0.0 } -func (*emptySnapshot) Min() int64 { return 0 } -func (*emptySnapshot) Percentile(p float64) float64 { return 0.0 } -func (*emptySnapshot) Percentiles(ps []float64) []float64 { return make([]float64, len(ps)) } -func (*emptySnapshot) Size() int { return 0 } -func (*emptySnapshot) StdDev() float64 { return 0.0 } -func (*emptySnapshot) Sum() int64 { return 0 } -func (*emptySnapshot) Values() []int64 { return []int64{} } -func (*emptySnapshot) Variance() float64 { return 0.0 } -func (*emptySnapshot) Value() int64 { return 0 } -func (*emptySnapshot) Rate() float64 { return 0.0 } -func (*emptySnapshot) Rate1() float64 { return 0.0 } -func (*emptySnapshot) Rate5() float64 { return 0.0 } -func (*emptySnapshot) Rate15() float64 { return 0.0 } -func (*emptySnapshot) RateMean() float64 { return 0.0 } diff --git a/metrics/influxdb/influxdb.go b/metrics/influxdb/influxdb.go index 5c8501fd9d..11f6c3ad22 100644 --- a/metrics/influxdb/influxdb.go +++ b/metrics/influxdb/influxdb.go @@ -8,31 +8,31 @@ import ( func readMeter(namespace, name string, i interface{}) (string, map[string]interface{}) { switch metric := i.(type) { - case metrics.Counter: + case *metrics.Counter: measurement := fmt.Sprintf("%s%s.count", namespace, name) fields := map[string]interface{}{ "value": metric.Snapshot().Count(), } return measurement, fields - case metrics.CounterFloat64: + case *metrics.CounterFloat64: measurement := fmt.Sprintf("%s%s.count", namespace, name) fields := map[string]interface{}{ "value": metric.Snapshot().Count(), } return measurement, fields - case metrics.Gauge: + case *metrics.Gauge: measurement := fmt.Sprintf("%s%s.gauge", namespace, name) fields := map[string]interface{}{ "value": metric.Snapshot().Value(), } return measurement, fields - case metrics.GaugeFloat64: + case *metrics.GaugeFloat64: measurement := fmt.Sprintf("%s%s.gauge", namespace, name) fields := map[string]interface{}{ "value": metric.Snapshot().Value(), } return measurement, fields - case metrics.GaugeInfo: + case *metrics.GaugeInfo: ms := metric.Snapshot() measurement := fmt.Sprintf("%s%s.gauge", namespace, name) fields := map[string]interface{}{ @@ -62,7 +62,7 @@ func readMeter(namespace, name string, i interface{}) (string, map[string]interf "p9999": ps[6], } return measurement, fields - case metrics.Meter: + case *metrics.Meter: ms := metric.Snapshot() measurement := fmt.Sprintf("%s%s.meter", namespace, name) fields := map[string]interface{}{ @@ -73,7 +73,7 @@ func readMeter(namespace, name string, i interface{}) (string, map[string]interf "mean": ms.RateMean(), } return measurement, fields - case metrics.Timer: + case *metrics.Timer: ms := metric.Snapshot() ps := ms.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999}) @@ -97,7 +97,7 @@ func readMeter(namespace, name string, i interface{}) (string, map[string]interf "meanrate": ms.RateMean(), } return measurement, fields - case metrics.ResettingTimer: + case *metrics.ResettingTimer: ms := metric.Snapshot() if ms.Count() == 0 { break diff --git a/metrics/influxdb/influxdb_test.go b/metrics/influxdb/influxdb_test.go index 5879af7cf6..547da138b8 100644 --- a/metrics/influxdb/influxdb_test.go +++ b/metrics/influxdb/influxdb_test.go @@ -33,7 +33,7 @@ import ( ) func TestMain(m *testing.M) { - metrics.Enabled = true + metrics.Enable() os.Exit(m.Run()) } diff --git a/metrics/init_test.go b/metrics/init_test.go index 43401e833c..af75bee425 100644 --- a/metrics/init_test.go +++ b/metrics/init_test.go @@ -1,5 +1,5 @@ package metrics func init() { - Enabled = true + metricsEnabled = true } diff --git a/metrics/log.go b/metrics/log.go index 3b9773faa7..3380bbf9c4 100644 --- a/metrics/log.go +++ b/metrics/log.go @@ -21,25 +21,21 @@ func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) { for range time.Tick(freq) { r.Each(func(name string, i interface{}) { switch metric := i.(type) { - case Counter: + case *Counter: l.Printf("counter %s\n", name) l.Printf(" count: %9d\n", metric.Snapshot().Count()) - case CounterFloat64: + case *CounterFloat64: l.Printf("counter %s\n", name) l.Printf(" count: %f\n", metric.Snapshot().Count()) - case Gauge: + case *Gauge: l.Printf("gauge %s\n", name) l.Printf(" value: %9d\n", metric.Snapshot().Value()) - case GaugeFloat64: + case *GaugeFloat64: l.Printf("gauge %s\n", name) l.Printf(" value: %f\n", metric.Snapshot().Value()) - case GaugeInfo: + case *GaugeInfo: l.Printf("gauge %s\n", name) l.Printf(" value: %s\n", metric.Snapshot().Value()) - case Healthcheck: - metric.Check() - l.Printf("healthcheck %s\n", name) - l.Printf(" error: %v\n", metric.Error()) case Histogram: h := metric.Snapshot() ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) @@ -54,7 +50,7 @@ func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) { l.Printf(" 95%%: %12.2f\n", ps[2]) l.Printf(" 99%%: %12.2f\n", ps[3]) l.Printf(" 99.9%%: %12.2f\n", ps[4]) - case Meter: + case *Meter: m := metric.Snapshot() l.Printf("meter %s\n", name) l.Printf(" count: %9d\n", m.Count()) @@ -62,7 +58,7 @@ func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) { l.Printf(" 5-min rate: %12.2f\n", m.Rate5()) l.Printf(" 15-min rate: %12.2f\n", m.Rate15()) l.Printf(" mean rate: %12.2f\n", m.RateMean()) - case Timer: + case *Timer: t := metric.Snapshot() ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) l.Printf("timer %s\n", name) diff --git a/metrics/meter.go b/metrics/meter.go index 432838f4ef..194bd1f304 100644 --- a/metrics/meter.go +++ b/metrics/meter.go @@ -7,114 +7,78 @@ import ( "time" ) -type MeterSnapshot interface { - Count() int64 - Rate1() float64 - Rate5() float64 - Rate15() float64 - RateMean() float64 -} - -// Meters count events to produce exponentially-weighted moving average rates -// at one-, five-, and fifteen-minutes and a mean rate. -type Meter interface { - Mark(int64) - Snapshot() MeterSnapshot - Stop() -} - // GetOrRegisterMeter returns an existing Meter or constructs and registers a -// new StandardMeter. +// new Meter. // Be sure to unregister the meter from the registry once it is of no use to // allow for garbage collection. -func GetOrRegisterMeter(name string, r Registry) Meter { - if nil == r { +func GetOrRegisterMeter(name string, r Registry) *Meter { + if r == nil { r = DefaultRegistry } - return r.GetOrRegister(name, NewMeter).(Meter) + return r.GetOrRegister(name, NewMeter).(*Meter) } -// NewMeter constructs a new StandardMeter and launches a goroutine. +// NewMeter constructs a new Meter and launches a goroutine. // Be sure to call Stop() once the meter is of no use to allow for garbage collection. -func NewMeter() Meter { - if !Enabled { - return NilMeter{} - } - m := newStandardMeter() - arbiter.Lock() - defer arbiter.Unlock() - arbiter.meters[m] = struct{}{} - if !arbiter.started { - arbiter.started = true - go arbiter.tick() - } +func NewMeter() *Meter { + m := newMeter() + arbiter.add(m) return m } // NewInactiveMeter returns a meter but does not start any goroutines. This // method is mainly intended for testing. -func NewInactiveMeter() Meter { - if !Enabled { - return NilMeter{} - } - m := newStandardMeter() - return m +func NewInactiveMeter() *Meter { + return newMeter() } -// NewRegisteredMeter constructs and registers a new StandardMeter +// NewRegisteredMeter constructs and registers a new Meter // and launches a goroutine. // Be sure to unregister the meter from the registry once it is of no use to // allow for garbage collection. -func NewRegisteredMeter(name string, r Registry) Meter { +func NewRegisteredMeter(name string, r Registry) *Meter { return GetOrRegisterMeter(name, r) } -// meterSnapshot is a read-only copy of the meter's internal values. -type meterSnapshot struct { +// MeterSnapshot is a read-only copy of the meter's internal values. +type MeterSnapshot struct { count int64 rate1, rate5, rate15, rateMean float64 } // Count returns the count of events at the time the snapshot was taken. -func (m *meterSnapshot) Count() int64 { return m.count } +func (m *MeterSnapshot) Count() int64 { return m.count } // Rate1 returns the one-minute moving average rate of events per second at the // time the snapshot was taken. -func (m *meterSnapshot) Rate1() float64 { return m.rate1 } +func (m *MeterSnapshot) Rate1() float64 { return m.rate1 } // Rate5 returns the five-minute moving average rate of events per second at // the time the snapshot was taken. -func (m *meterSnapshot) Rate5() float64 { return m.rate5 } +func (m *MeterSnapshot) Rate5() float64 { return m.rate5 } // Rate15 returns the fifteen-minute moving average rate of events per second // at the time the snapshot was taken. -func (m *meterSnapshot) Rate15() float64 { return m.rate15 } +func (m *MeterSnapshot) Rate15() float64 { return m.rate15 } // RateMean returns the meter's mean rate of events per second at the time the // snapshot was taken. -func (m *meterSnapshot) RateMean() float64 { return m.rateMean } +func (m *MeterSnapshot) RateMean() float64 { return m.rateMean } -// NilMeter is a no-op Meter. -type NilMeter struct{} - -func (NilMeter) Count() int64 { return 0 } -func (NilMeter) Mark(n int64) {} -func (NilMeter) Snapshot() MeterSnapshot { return (*emptySnapshot)(nil) } -func (NilMeter) Stop() {} - -// StandardMeter is the standard implementation of a Meter. -type StandardMeter struct { +// Meter count events to produce exponentially-weighted moving average rates +// at one-, five-, and fifteen-minutes and a mean rate. +type Meter struct { count atomic.Int64 uncounted atomic.Int64 // not yet added to the EWMAs rateMean atomic.Uint64 - a1, a5, a15 EWMA + a1, a5, a15 *EWMA startTime time.Time stopped atomic.Bool } -func newStandardMeter() *StandardMeter { - return &StandardMeter{ +func newMeter() *Meter { + return &Meter{ a1: NewEWMA1(), a5: NewEWMA5(), a15: NewEWMA15(), @@ -123,22 +87,20 @@ func newStandardMeter() *StandardMeter { } // Stop stops the meter, Mark() will be a no-op if you use it after being stopped. -func (m *StandardMeter) Stop() { +func (m *Meter) Stop() { if stopped := m.stopped.Swap(true); !stopped { - arbiter.Lock() - delete(arbiter.meters, m) - arbiter.Unlock() + arbiter.remove(m) } } // Mark records the occurrence of n events. -func (m *StandardMeter) Mark(n int64) { +func (m *Meter) Mark(n int64) { m.uncounted.Add(n) } // Snapshot returns a read-only copy of the meter. -func (m *StandardMeter) Snapshot() MeterSnapshot { - return &meterSnapshot{ +func (m *Meter) Snapshot() *MeterSnapshot { + return &MeterSnapshot{ count: m.count.Load() + m.uncounted.Load(), rate1: m.a1.Snapshot().Rate(), rate5: m.a5.Snapshot().Rate(), @@ -147,7 +109,7 @@ func (m *StandardMeter) Snapshot() MeterSnapshot { } } -func (m *StandardMeter) tick() { +func (m *Meter) tick() { // Take the uncounted values, add to count n := m.uncounted.Swap(0) count := m.count.Add(n) @@ -157,33 +119,51 @@ func (m *StandardMeter) tick() { m.a5.Update(n) m.a15.Update(n) // And trigger them to calculate the rates - m.a1.Tick() - m.a5.Tick() - m.a15.Tick() + m.a1.tick() + m.a5.tick() + m.a15.tick() } -// meterArbiter ticks meters every 5s from a single goroutine. +var arbiter = meterTicker{meters: make(map[*Meter]struct{})} + +// meterTicker ticks meters every 5s from a single goroutine. // meters are references in a set for future stopping. -type meterArbiter struct { - sync.RWMutex +type meterTicker struct { + mu sync.RWMutex + started bool - meters map[*StandardMeter]struct{} - ticker *time.Ticker + meters map[*Meter]struct{} } -var arbiter = meterArbiter{ticker: time.NewTicker(5 * time.Second), meters: make(map[*StandardMeter]struct{})} - -// tick meters on the scheduled interval -func (ma *meterArbiter) tick() { - for range ma.ticker.C { - ma.tickMeters() +// add adds another *Meter ot the arbiter, and starts the arbiter ticker. +func (ma *meterTicker) add(m *Meter) { + ma.mu.Lock() + defer ma.mu.Unlock() + ma.meters[m] = struct{}{} + if !ma.started { + ma.started = true + go ma.loop() } } -func (ma *meterArbiter) tickMeters() { - ma.RLock() - defer ma.RUnlock() - for meter := range ma.meters { - meter.tick() +// remove removes a meter from the set of ticked meters. +func (ma *meterTicker) remove(m *Meter) { + ma.mu.Lock() + delete(ma.meters, m) + ma.mu.Unlock() +} + +// loop ticks meters on a 5 second interval. +func (ma *meterTicker) loop() { + ticker := time.NewTicker(5 * time.Second) + for range ticker.C { + if !metricsEnabled { + continue + } + ma.mu.RLock() + for meter := range ma.meters { + meter.tick() + } + ma.mu.RUnlock() } } diff --git a/metrics/meter_test.go b/metrics/meter_test.go index 019c4d765b..e3f39684bd 100644 --- a/metrics/meter_test.go +++ b/metrics/meter_test.go @@ -28,18 +28,12 @@ func TestGetOrRegisterMeter(t *testing.T) { } func TestMeterDecay(t *testing.T) { - ma := meterArbiter{ - ticker: time.NewTicker(time.Millisecond), - meters: make(map[*StandardMeter]struct{}), - } - defer ma.ticker.Stop() - m := newStandardMeter() - ma.meters[m] = struct{}{} + m := newMeter() m.Mark(1) - ma.tickMeters() + m.tick() rateMean := m.Snapshot().RateMean() time.Sleep(100 * time.Millisecond) - ma.tickMeters() + m.tick() if m.Snapshot().RateMean() >= rateMean { t.Error("m.RateMean() didn't decrease") } diff --git a/metrics/metrics.go b/metrics/metrics.go index c7fe5c7333..a9d6623173 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -6,52 +6,29 @@ package metrics import ( - "os" "runtime/metrics" "runtime/pprof" - "strconv" - "strings" - "syscall" "time" - - "github.com/ethereum/go-ethereum/log" ) -// Enabled is checked by the constructor functions for all of the -// standard metrics. If it is true, the metric returned is a stub. +var ( + metricsEnabled = false +) + +// Enabled is checked by functions that are deemed 'expensive', e.g. if a +// meter-type does locking and/or non-trivial math operations during update. +func Enabled() bool { + return metricsEnabled +} + +// Enable enables the metrics system. +// The Enabled-flag is expected to be set, once, during startup, but toggling off and on +// is not supported. // -// This global kill-switch helps quantify the observer effect and makes -// for less cluttered pprof profiles. -var Enabled = 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"} - -// 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() { - for _, enabler := range enablerEnvVars { - if val, found := syscall.Getenv(enabler); found && !Enabled { - if enable, _ := strconv.ParseBool(val); enable { // ignore error, flag parser will choke on it later - log.Info("Enabling metrics collection") - Enabled = true - } - } - } - for _, arg := range os.Args { - flag := strings.TrimLeft(arg, "-") - - for _, enabler := range enablerFlags { - if !Enabled && flag == enabler { - log.Info("Enabling metrics collection") - Enabled = true - } - } - } +// Enable is not safe to call concurrently. You need to call this as early as possible in +// the program, before any metrics collection will happen. +func Enable() { + metricsEnabled = true } var threadCreateProfile = pprof.Lookup("threadcreate") @@ -128,7 +105,7 @@ func readRuntimeStats(v *runtimeStats) { // CollectProcessMetrics periodically collects various metrics about the running process. func CollectProcessMetrics(refresh time.Duration) { // Short circuit if the metrics system is disabled - if !Enabled { + if !metricsEnabled { return } diff --git a/metrics/metrics_test.go b/metrics/metrics_test.go index 2861d5f2ca..dc144f2425 100644 --- a/metrics/metrics_test.go +++ b/metrics/metrics_test.go @@ -7,8 +7,6 @@ import ( "time" ) -const FANOUT = 128 - func TestReadRuntimeValues(t *testing.T) { var v runtimeStats readRuntimeStats(&v) @@ -16,60 +14,23 @@ func TestReadRuntimeValues(t *testing.T) { } func BenchmarkMetrics(b *testing.B) { - r := NewRegistry() - c := NewRegisteredCounter("counter", r) - cf := NewRegisteredCounterFloat64("counterfloat64", r) - g := NewRegisteredGauge("gauge", r) - gf := NewRegisteredGaugeFloat64("gaugefloat64", r) - h := NewRegisteredHistogram("histogram", r, NewUniformSample(100)) - m := NewRegisteredMeter("meter", r) - t := NewRegisteredTimer("timer", r) + var ( + r = NewRegistry() + c = NewRegisteredCounter("counter", r) + cf = NewRegisteredCounterFloat64("counterfloat64", r) + g = NewRegisteredGauge("gauge", r) + gf = NewRegisteredGaugeFloat64("gaugefloat64", r) + h = NewRegisteredHistogram("histogram", r, NewUniformSample(100)) + m = NewRegisteredMeter("meter", r) + t = NewRegisteredTimer("timer", r) + ) RegisterDebugGCStats(r) b.ResetTimer() - ch := make(chan bool) - - wgD := &sync.WaitGroup{} - /* - wgD.Add(1) + var wg sync.WaitGroup + wg.Add(128) + for i := 0; i < 128; i++ { go func() { - defer wgD.Done() - //log.Println("go CaptureDebugGCStats") - for { - select { - case <-ch: - //log.Println("done CaptureDebugGCStats") - return - default: - CaptureDebugGCStatsOnce(r) - } - } - }() - //*/ - - wgW := &sync.WaitGroup{} - /* - wgW.Add(1) - go func() { - defer wgW.Done() - //log.Println("go Write") - for { - select { - case <-ch: - //log.Println("done Write") - return - default: - WriteOnce(r, io.Discard) - } - } - }() - //*/ - - wg := &sync.WaitGroup{} - wg.Add(FANOUT) - for i := 0; i < FANOUT; i++ { - go func(i int) { defer wg.Done() - //log.Println("go", i) for i := 0; i < b.N; i++ { c.Inc(1) cf.Inc(1.0) @@ -79,13 +40,9 @@ func BenchmarkMetrics(b *testing.B) { m.Mark(1) t.Update(1) } - //log.Println("done", i) - }(i) + }() } wg.Wait() - close(ch) - wgD.Wait() - wgW.Wait() } func Example() { diff --git a/metrics/opentsdb.go b/metrics/opentsdb.go index e81690f943..57af3d025e 100644 --- a/metrics/opentsdb.go +++ b/metrics/opentsdb.go @@ -64,15 +64,15 @@ func (c *OpenTSDBConfig) writeRegistry(w io.Writer, now int64, shortHostname str c.Registry.Each(func(name string, i interface{}) { switch metric := i.(type) { - case Counter: + case *Counter: fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, metric.Snapshot().Count(), shortHostname) - case CounterFloat64: + case *CounterFloat64: fmt.Fprintf(w, "put %s.%s.count %d %f host=%s\n", c.Prefix, name, now, metric.Snapshot().Count(), shortHostname) - case Gauge: + case *Gauge: fmt.Fprintf(w, "put %s.%s.value %d %d host=%s\n", c.Prefix, name, now, metric.Snapshot().Value(), shortHostname) - case GaugeFloat64: + case *GaugeFloat64: fmt.Fprintf(w, "put %s.%s.value %d %f host=%s\n", c.Prefix, name, now, metric.Snapshot().Value(), shortHostname) - case GaugeInfo: + case *GaugeInfo: fmt.Fprintf(w, "put %s.%s.value %d %s host=%s\n", c.Prefix, name, now, metric.Snapshot().Value().String(), shortHostname) case Histogram: h := metric.Snapshot() @@ -87,14 +87,14 @@ func (c *OpenTSDBConfig) writeRegistry(w io.Writer, now int64, shortHostname str fmt.Fprintf(w, "put %s.%s.95-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[2], shortHostname) fmt.Fprintf(w, "put %s.%s.99-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[3], shortHostname) fmt.Fprintf(w, "put %s.%s.999-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[4], shortHostname) - case Meter: + case *Meter: m := metric.Snapshot() fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, m.Count(), shortHostname) fmt.Fprintf(w, "put %s.%s.one-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate1(), shortHostname) fmt.Fprintf(w, "put %s.%s.five-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate5(), shortHostname) fmt.Fprintf(w, "put %s.%s.fifteen-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate15(), shortHostname) fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, m.RateMean(), shortHostname) - case Timer: + case *Timer: t := metric.Snapshot() ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, t.Count(), shortHostname) diff --git a/metrics/prometheus/collector.go b/metrics/prometheus/collector.go index 353336763b..31b8c51b65 100644 --- a/metrics/prometheus/collector.go +++ b/metrics/prometheus/collector.go @@ -51,23 +51,23 @@ func newCollector() *collector { // metric type is not supported/known. func (c *collector) Add(name string, i any) error { switch m := i.(type) { - case metrics.Counter: + case *metrics.Counter: c.addCounter(name, m.Snapshot()) - case metrics.CounterFloat64: + case *metrics.CounterFloat64: c.addCounterFloat64(name, m.Snapshot()) - case metrics.Gauge: + case *metrics.Gauge: c.addGauge(name, m.Snapshot()) - case metrics.GaugeFloat64: + case *metrics.GaugeFloat64: c.addGaugeFloat64(name, m.Snapshot()) - case metrics.GaugeInfo: + case *metrics.GaugeInfo: c.addGaugeInfo(name, m.Snapshot()) case metrics.Histogram: c.addHistogram(name, m.Snapshot()) - case metrics.Meter: + case *metrics.Meter: c.addMeter(name, m.Snapshot()) - case metrics.Timer: + case *metrics.Timer: c.addTimer(name, m.Snapshot()) - case metrics.ResettingTimer: + case *metrics.ResettingTimer: c.addResettingTimer(name, m.Snapshot()) default: return fmt.Errorf("unknown prometheus metric type %T", i) @@ -106,11 +106,11 @@ func (c *collector) addHistogram(name string, m metrics.HistogramSnapshot) { c.buff.WriteRune('\n') } -func (c *collector) addMeter(name string, m metrics.MeterSnapshot) { +func (c *collector) addMeter(name string, m *metrics.MeterSnapshot) { c.writeGaugeCounter(name, m.Count()) } -func (c *collector) addTimer(name string, m metrics.TimerSnapshot) { +func (c *collector) addTimer(name string, m *metrics.TimerSnapshot) { pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999} ps := m.Percentiles(pv) c.writeSummaryCounter(name, m.Count()) @@ -121,7 +121,7 @@ func (c *collector) addTimer(name string, m metrics.TimerSnapshot) { c.buff.WriteRune('\n') } -func (c *collector) addResettingTimer(name string, m metrics.ResettingTimerSnapshot) { +func (c *collector) addResettingTimer(name string, m *metrics.ResettingTimerSnapshot) { if m.Count() <= 0 { return } diff --git a/metrics/prometheus/collector_test.go b/metrics/prometheus/collector_test.go index ea17aac458..a8585d1226 100644 --- a/metrics/prometheus/collector_test.go +++ b/metrics/prometheus/collector_test.go @@ -27,7 +27,7 @@ import ( ) func TestMain(m *testing.M) { - metrics.Enabled = true + metrics.Enable() os.Exit(m.Run()) } diff --git a/metrics/registry.go b/metrics/registry.go index ca4741feef..527da6238d 100644 --- a/metrics/registry.go +++ b/metrics/registry.go @@ -1,6 +1,7 @@ package metrics import ( + "errors" "fmt" "reflect" "sort" @@ -8,14 +9,10 @@ import ( "sync" ) -// DuplicateMetric is the error returned by Registry. Register when a metric +// ErrDuplicateMetric 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 - -func (err DuplicateMetric) Error() string { - return fmt.Sprintf("duplicate metric: %s", string(err)) -} +var ErrDuplicateMetric = errors.New("duplicate metric") // A Registry holds references to a set of metrics by name and can iterate // over them, calling callback functions provided by the user. @@ -114,13 +111,13 @@ 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 ErrDuplicateMetric // if a metric by the given name is already registered. func (r *StandardRegistry) Register(name string, i interface{}) error { // fast path _, ok := r.metrics.Load(name) if ok { - return DuplicateMetric(name) + return fmt.Errorf("%w: %v", ErrDuplicateMetric, name) } if v := reflect.ValueOf(i); v.Kind() == reflect.Func { @@ -128,7 +125,7 @@ func (r *StandardRegistry) Register(name string, i interface{}) error { } _, loaded, _ := r.loadOrRegister(name, i) if loaded { - return DuplicateMetric(name) + return fmt.Errorf("%w: %v", ErrDuplicateMetric, name) } return nil } @@ -136,7 +133,7 @@ func (r *StandardRegistry) Register(name string, i interface{}) error { // RunHealthchecks run all registered healthchecks. func (r *StandardRegistry) RunHealthchecks() { r.metrics.Range(func(key, value any) bool { - if h, ok := value.(Healthcheck); ok { + if h, ok := value.(*Healthcheck); ok { h.Check() } return true @@ -149,15 +146,15 @@ func (r *StandardRegistry) GetAll() map[string]map[string]interface{} { r.Each(func(name string, i interface{}) { values := make(map[string]interface{}) switch metric := i.(type) { - case Counter: + case *Counter: values["count"] = metric.Snapshot().Count() - case CounterFloat64: + case *CounterFloat64: values["count"] = metric.Snapshot().Count() - case Gauge: + case *Gauge: values["value"] = metric.Snapshot().Value() - case GaugeFloat64: + case *GaugeFloat64: values["value"] = metric.Snapshot().Value() - case Healthcheck: + case *Healthcheck: values["error"] = nil metric.Check() if err := metric.Error(); nil != err { @@ -176,14 +173,14 @@ func (r *StandardRegistry) GetAll() map[string]map[string]interface{} { values["95%"] = ps[2] values["99%"] = ps[3] values["99.9%"] = ps[4] - case Meter: + case *Meter: m := metric.Snapshot() values["count"] = m.Count() values["1m.rate"] = m.Rate1() values["5m.rate"] = m.Rate5() values["15m.rate"] = m.Rate15() values["mean.rate"] = m.RateMean() - case Timer: + case *Timer: t := metric.Snapshot() ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) values["count"] = t.Count() @@ -214,7 +211,7 @@ func (r *StandardRegistry) Unregister(name string) { func (r *StandardRegistry) loadOrRegister(name string, i interface{}) (interface{}, bool, bool) { switch i.(type) { - case Counter, CounterFloat64, Gauge, GaugeFloat64, GaugeInfo, Healthcheck, Histogram, Meter, Timer, ResettingTimer: + case *Counter, *CounterFloat64, *Gauge, *GaugeFloat64, *GaugeInfo, *Healthcheck, Histogram, *Meter, *Timer, *ResettingTimer: default: return nil, false, false } @@ -326,9 +323,7 @@ func (r *PrefixedRegistry) Unregister(name string) { } var ( - DefaultRegistry = NewRegistry() - EphemeralRegistry = NewRegistry() - AccountingRegistry = NewRegistry() // registry used in swarm + DefaultRegistry = NewRegistry() ) // Each call the given function for each registered metric. @@ -347,7 +342,7 @@ func GetOrRegister(name string, i interface{}) interface{} { return DefaultRegistry.GetOrRegister(name, i) } -// Register the given metric under the given name. Returns a DuplicateMetric +// Register the given metric under the given name. Returns a ErrDuplicateMetric // if a metric by the given name is already registered. func Register(name string, i interface{}) error { return DefaultRegistry.Register(name, i) diff --git a/metrics/registry_test.go b/metrics/registry_test.go index 75012dd4ac..bdc58fee6c 100644 --- a/metrics/registry_test.go +++ b/metrics/registry_test.go @@ -47,7 +47,7 @@ func TestRegistry(t *testing.T) { if name != "foo" { t.Fatal(name) } - if _, ok := iface.(Counter); !ok { + if _, ok := iface.(*Counter); !ok { t.Fatal(iface) } }) @@ -73,7 +73,7 @@ func TestRegistryDuplicate(t *testing.T) { i := 0 r.Each(func(name string, iface interface{}) { i++ - if _, ok := iface.(Counter); !ok { + if _, ok := iface.(*Counter); !ok { t.Fatal(iface) } }) @@ -85,11 +85,11 @@ func TestRegistryDuplicate(t *testing.T) { func TestRegistryGet(t *testing.T) { r := NewRegistry() r.Register("foo", NewCounter()) - if count := r.Get("foo").(Counter).Snapshot().Count(); count != 0 { + if count := r.Get("foo").(*Counter).Snapshot().Count(); count != 0 { t.Fatal(count) } - r.Get("foo").(Counter).Inc(1) - if count := r.Get("foo").(Counter).Snapshot().Count(); count != 1 { + r.Get("foo").(*Counter).Inc(1) + if count := r.Get("foo").(*Counter).Snapshot().Count(); count != 1 { t.Fatal(count) } } @@ -100,7 +100,7 @@ func TestRegistryGetOrRegister(t *testing.T) { // First metric wins with GetOrRegister _ = r.GetOrRegister("foo", NewCounter()) m := r.GetOrRegister("foo", NewGauge()) - if _, ok := m.(Counter); !ok { + if _, ok := m.(*Counter); !ok { t.Fatal(m) } @@ -110,7 +110,7 @@ func TestRegistryGetOrRegister(t *testing.T) { if name != "foo" { t.Fatal(name) } - if _, ok := iface.(Counter); !ok { + if _, ok := iface.(*Counter); !ok { t.Fatal(iface) } }) @@ -125,7 +125,7 @@ func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) { // First metric wins with GetOrRegister _ = r.GetOrRegister("foo", NewCounter) m := r.GetOrRegister("foo", NewGauge) - if _, ok := m.(Counter); !ok { + if _, ok := m.(*Counter); !ok { t.Fatal(m) } @@ -135,7 +135,7 @@ func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) { if name != "foo" { t.Fatal(name) } - if _, ok := iface.(Counter); !ok { + if _, ok := iface.(*Counter); !ok { t.Fatal(iface) } }) diff --git a/metrics/resetting_sample.go b/metrics/resetting_sample.go index c38ffcd3ec..730ef93416 100644 --- a/metrics/resetting_sample.go +++ b/metrics/resetting_sample.go @@ -17,7 +17,7 @@ type resettingSample struct { } // Snapshot returns a read-only copy of the sample with the original reset. -func (rs *resettingSample) Snapshot() SampleSnapshot { +func (rs *resettingSample) Snapshot() *sampleSnapshot { s := rs.Sample.Snapshot() rs.Sample.Clear() return s diff --git a/metrics/resetting_timer.go b/metrics/resetting_timer.go index 6802e3fcea..1b3e87bc3d 100644 --- a/metrics/resetting_timer.go +++ b/metrics/resetting_timer.go @@ -5,36 +5,17 @@ import ( "time" ) -// Initial slice capacity for the values stored in a ResettingTimer -const InitialResettingTimerSliceCap = 10 - -type ResettingTimerSnapshot interface { - Count() int - Mean() float64 - Max() int64 - Min() int64 - Percentiles([]float64) []float64 -} - -// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval. -type ResettingTimer interface { - Snapshot() ResettingTimerSnapshot - Time(func()) - Update(time.Duration) - UpdateSince(time.Time) -} - // GetOrRegisterResettingTimer returns an existing ResettingTimer or constructs and registers a -// new StandardResettingTimer. -func GetOrRegisterResettingTimer(name string, r Registry) ResettingTimer { +// new ResettingTimer. +func GetOrRegisterResettingTimer(name string, r Registry) *ResettingTimer { if nil == r { r = DefaultRegistry } - return r.GetOrRegister(name, NewResettingTimer).(ResettingTimer) + return r.GetOrRegister(name, NewResettingTimer).(*ResettingTimer) } -// NewRegisteredResettingTimer constructs and registers a new StandardResettingTimer. -func NewRegisteredResettingTimer(name string, r Registry) ResettingTimer { +// NewRegisteredResettingTimer constructs and registers a new ResettingTimer. +func NewRegisteredResettingTimer(name string, r Registry) *ResettingTimer { c := NewResettingTimer() if nil == r { r = DefaultRegistry @@ -43,33 +24,15 @@ func NewRegisteredResettingTimer(name string, r Registry) ResettingTimer { return c } -// NewResettingTimer constructs a new StandardResettingTimer -func NewResettingTimer() ResettingTimer { - if !Enabled { - return NilResettingTimer{} - } - return &StandardResettingTimer{ - values: make([]int64, 0, InitialResettingTimerSliceCap), +// NewResettingTimer constructs a new ResettingTimer +func NewResettingTimer() *ResettingTimer { + return &ResettingTimer{ + values: make([]int64, 0, 10), } } -// NilResettingTimer is a no-op ResettingTimer. -type NilResettingTimer struct{} - -func (NilResettingTimer) Values() []int64 { return nil } -func (n NilResettingTimer) Snapshot() ResettingTimerSnapshot { return n } -func (NilResettingTimer) Time(f func()) { f() } -func (NilResettingTimer) Update(time.Duration) {} -func (NilResettingTimer) Percentiles([]float64) []float64 { return nil } -func (NilResettingTimer) Mean() float64 { return 0.0 } -func (NilResettingTimer) Max() int64 { return 0 } -func (NilResettingTimer) Min() int64 { return 0 } -func (NilResettingTimer) UpdateSince(time.Time) {} -func (NilResettingTimer) Count() int { return 0 } - -// StandardResettingTimer is the standard implementation of a ResettingTimer. -// and Meter. -type StandardResettingTimer struct { +// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval. +type ResettingTimer struct { values []int64 sum int64 // sum is a running count of the total sum, used later to calculate mean @@ -77,28 +40,31 @@ type StandardResettingTimer struct { } // Snapshot resets the timer and returns a read-only copy of its contents. -func (t *StandardResettingTimer) Snapshot() ResettingTimerSnapshot { +func (t *ResettingTimer) Snapshot() *ResettingTimerSnapshot { t.mutex.Lock() defer t.mutex.Unlock() - snapshot := &resettingTimerSnapshot{} + snapshot := &ResettingTimerSnapshot{} if len(t.values) > 0 { snapshot.mean = float64(t.sum) / float64(len(t.values)) snapshot.values = t.values - t.values = make([]int64, 0, InitialResettingTimerSliceCap) + t.values = make([]int64, 0, 10) } t.sum = 0 return snapshot } // Record the duration of the execution of the given function. -func (t *StandardResettingTimer) Time(f func()) { +func (t *ResettingTimer) Time(f func()) { ts := time.Now() f() t.Update(time.Since(ts)) } // Record the duration of an event. -func (t *StandardResettingTimer) Update(d time.Duration) { +func (t *ResettingTimer) Update(d time.Duration) { + if !metricsEnabled { + return + } t.mutex.Lock() defer t.mutex.Unlock() t.values = append(t.values, int64(d)) @@ -106,12 +72,12 @@ func (t *StandardResettingTimer) Update(d time.Duration) { } // Record the duration of an event that started at a time and ends now. -func (t *StandardResettingTimer) UpdateSince(ts time.Time) { +func (t *ResettingTimer) UpdateSince(ts time.Time) { t.Update(time.Since(ts)) } -// resettingTimerSnapshot is a point-in-time copy of another ResettingTimer. -type resettingTimerSnapshot struct { +// ResettingTimerSnapshot is a point-in-time copy of another ResettingTimer. +type ResettingTimerSnapshot struct { values []int64 mean float64 max int64 @@ -121,20 +87,20 @@ type resettingTimerSnapshot struct { } // Count return the length of the values from snapshot. -func (t *resettingTimerSnapshot) Count() int { +func (t *ResettingTimerSnapshot) Count() int { return len(t.values) } // Percentiles returns the boundaries for the input percentiles. // note: this method is not thread safe -func (t *resettingTimerSnapshot) Percentiles(percentiles []float64) []float64 { +func (t *ResettingTimerSnapshot) Percentiles(percentiles []float64) []float64 { t.calc(percentiles) return t.thresholdBoundaries } // Mean returns the mean of the snapshotted values // note: this method is not thread safe -func (t *resettingTimerSnapshot) Mean() float64 { +func (t *ResettingTimerSnapshot) Mean() float64 { if !t.calculated { t.calc(nil) } @@ -144,7 +110,7 @@ func (t *resettingTimerSnapshot) Mean() float64 { // Max returns the max of the snapshotted values // note: this method is not thread safe -func (t *resettingTimerSnapshot) Max() int64 { +func (t *ResettingTimerSnapshot) Max() int64 { if !t.calculated { t.calc(nil) } @@ -153,14 +119,14 @@ func (t *resettingTimerSnapshot) Max() int64 { // Min returns the min of the snapshotted values // note: this method is not thread safe -func (t *resettingTimerSnapshot) Min() int64 { +func (t *ResettingTimerSnapshot) Min() int64 { if !t.calculated { t.calc(nil) } return t.min } -func (t *resettingTimerSnapshot) calc(percentiles []float64) { +func (t *ResettingTimerSnapshot) calc(percentiles []float64) { scores := CalculatePercentiles(t.values, percentiles) t.thresholdBoundaries = scores if len(t.values) == 0 { diff --git a/metrics/sample.go b/metrics/sample.go index 17b2bee28f..dc8167809f 100644 --- a/metrics/sample.go +++ b/metrics/sample.go @@ -10,178 +10,21 @@ import ( const rescaleThreshold = time.Hour -type SampleSnapshot interface { - Count() int64 - Max() int64 - Mean() float64 - Min() int64 - Percentile(float64) float64 - Percentiles([]float64) []float64 - Size() int - StdDev() float64 - Sum() int64 - Variance() float64 -} - -// Samples maintain a statistically-significant selection of values from +// Sample maintains a statistically-significant selection of values from // a stream. type Sample interface { - Snapshot() SampleSnapshot + Snapshot() *sampleSnapshot Clear() Update(int64) } -// ExpDecaySample is an exponentially-decaying sample using a forward-decaying -// priority reservoir. See Cormode et al's "Forward Decay: A Practical Time -// Decay Model for Streaming Systems". -// -// -type ExpDecaySample struct { - alpha float64 - count int64 - mutex sync.Mutex - reservoirSize int - t0, t1 time.Time - values *expDecaySampleHeap - rand *rand.Rand -} +var ( + _ Sample = (*ExpDecaySample)(nil) + _ Sample = (*UniformSample)(nil) + _ Sample = (*resettingSample)(nil) +) -// NewExpDecaySample constructs a new exponentially-decaying sample with the -// given reservoir size and alpha. -func NewExpDecaySample(reservoirSize int, alpha float64) Sample { - if !Enabled { - return NilSample{} - } - s := &ExpDecaySample{ - alpha: alpha, - reservoirSize: reservoirSize, - t0: time.Now(), - values: newExpDecaySampleHeap(reservoirSize), - } - s.t1 = s.t0.Add(rescaleThreshold) - return s -} - -// SetRand sets the random source (useful in tests) -func (s *ExpDecaySample) SetRand(prng *rand.Rand) Sample { - s.rand = prng - return s -} - -// Clear clears all samples. -func (s *ExpDecaySample) Clear() { - s.mutex.Lock() - defer s.mutex.Unlock() - s.count = 0 - s.t0 = time.Now() - s.t1 = s.t0.Add(rescaleThreshold) - s.values.Clear() -} - -// Snapshot returns a read-only copy of the sample. -func (s *ExpDecaySample) Snapshot() SampleSnapshot { - s.mutex.Lock() - defer s.mutex.Unlock() - var ( - samples = s.values.Values() - values = make([]int64, len(samples)) - max int64 = math.MinInt64 - min int64 = math.MaxInt64 - sum int64 - ) - for i, item := range samples { - v := item.v - values[i] = v - sum += v - if v > max { - max = v - } - if v < min { - min = v - } - } - return newSampleSnapshotPrecalculated(s.count, values, min, max, sum) -} - -// Update samples a new value. -func (s *ExpDecaySample) Update(v int64) { - s.update(time.Now(), v) -} - -// update samples a new value at a particular timestamp. This is a method all -// its own to facilitate testing. -func (s *ExpDecaySample) update(t time.Time, v int64) { - s.mutex.Lock() - defer s.mutex.Unlock() - s.count++ - if s.values.Size() == s.reservoirSize { - s.values.Pop() - } - var f64 float64 - if s.rand != nil { - f64 = s.rand.Float64() - } else { - f64 = rand.Float64() - } - s.values.Push(expDecaySample{ - k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / f64, - v: v, - }) - if t.After(s.t1) { - values := s.values.Values() - t0 := s.t0 - s.values.Clear() - s.t0 = t - s.t1 = s.t0.Add(rescaleThreshold) - for _, v := range values { - v.k = v.k * math.Exp(-s.alpha*s.t0.Sub(t0).Seconds()) - s.values.Push(v) - } - } -} - -// NilSample is a no-op Sample. -type NilSample struct{} - -func (NilSample) Clear() {} -func (NilSample) Snapshot() SampleSnapshot { return (*emptySnapshot)(nil) } -func (NilSample) Update(v 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 -// values, [0, 10], a 50% percentile will land between them. -// -// Note: As a side-effect, this method will also sort the slice of values. -// Note2: The input format for percentiles is NOT percent! To express 50%, use 0.5, not 50. -func CalculatePercentiles(values []int64, ps []float64) []float64 { - scores := make([]float64, len(ps)) - size := len(values) - if size == 0 { - return scores - } - slices.Sort(values) - for i, p := range ps { - pos := p * float64(size+1) - - if pos < 1.0 { - scores[i] = float64(values[0]) - } else if pos >= float64(size) { - scores[i] = float64(values[size-1]) - } else { - lower := float64(values[int(pos)-1]) - upper := float64(values[int(pos)]) - scores[i] = lower + (pos-math.Floor(pos))*(upper-lower) - } - } - return scores -} - -// sampleSnapshot is a read-only copy of another Sample. +// sampleSnapshot is a read-only copy of a Sample. type sampleSnapshot struct { count int64 values []int64 @@ -259,9 +102,6 @@ func (s *sampleSnapshot) Percentiles(ps []float64) []float64 { // Size returns the size of the sample at the time the snapshot was taken. func (s *sampleSnapshot) Size() int { return len(s.values) } -// Snapshot returns the snapshot. -func (s *sampleSnapshot) Snapshot() SampleSnapshot { return s } - // StdDev returns the standard deviation of values at the time the snapshot was // taken. func (s *sampleSnapshot) StdDev() float64 { @@ -276,9 +116,7 @@ func (s *sampleSnapshot) Sum() int64 { return s.sum } // Values returns a copy of the values in the sample. func (s *sampleSnapshot) Values() []int64 { - values := make([]int64, len(s.values)) - copy(values, s.values) - return values + return slices.Clone(s.values) } // Variance returns the variance of values at the time the snapshot was taken. @@ -289,6 +127,149 @@ func (s *sampleSnapshot) Variance() float64 { return s.variance } +// ExpDecaySample is an exponentially-decaying sample using a forward-decaying +// priority reservoir. See Cormode et al's "Forward Decay: A Practical Time +// Decay Model for Streaming Systems". +// +// +type ExpDecaySample struct { + alpha float64 + count int64 + mutex sync.Mutex + reservoirSize int + t0, t1 time.Time + values *expDecaySampleHeap + rand *rand.Rand +} + +// NewExpDecaySample constructs a new exponentially-decaying sample with the +// given reservoir size and alpha. +func NewExpDecaySample(reservoirSize int, alpha float64) Sample { + s := &ExpDecaySample{ + alpha: alpha, + reservoirSize: reservoirSize, + t0: time.Now(), + values: newExpDecaySampleHeap(reservoirSize), + } + s.t1 = s.t0.Add(rescaleThreshold) + return s +} + +// SetRand sets the random source (useful in tests) +func (s *ExpDecaySample) SetRand(prng *rand.Rand) Sample { + s.rand = prng + return s +} + +// Clear clears all samples. +func (s *ExpDecaySample) Clear() { + s.mutex.Lock() + defer s.mutex.Unlock() + s.count = 0 + s.t0 = time.Now() + s.t1 = s.t0.Add(rescaleThreshold) + s.values.Clear() +} + +// Snapshot returns a read-only copy of the sample. +func (s *ExpDecaySample) Snapshot() *sampleSnapshot { + s.mutex.Lock() + defer s.mutex.Unlock() + var ( + samples = s.values.Values() + values = make([]int64, len(samples)) + max int64 = math.MinInt64 + min int64 = math.MaxInt64 + sum int64 + ) + for i, item := range samples { + v := item.v + values[i] = v + sum += v + if v > max { + max = v + } + if v < min { + min = v + } + } + return newSampleSnapshotPrecalculated(s.count, values, min, max, sum) +} + +// Update samples a new value. +func (s *ExpDecaySample) Update(v int64) { + if !metricsEnabled { + return + } + s.update(time.Now(), v) +} + +// update samples a new value at a particular timestamp. This is a method all +// its own to facilitate testing. +func (s *ExpDecaySample) update(t time.Time, v int64) { + s.mutex.Lock() + defer s.mutex.Unlock() + s.count++ + if s.values.Size() == s.reservoirSize { + s.values.Pop() + } + var f64 float64 + if s.rand != nil { + f64 = s.rand.Float64() + } else { + f64 = rand.Float64() + } + s.values.Push(expDecaySample{ + k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / f64, + v: v, + }) + if t.After(s.t1) { + values := s.values.Values() + t0 := s.t0 + s.values.Clear() + s.t0 = t + s.t1 = s.t0.Add(rescaleThreshold) + for _, v := range values { + v.k = v.k * math.Exp(-s.alpha*s.t0.Sub(t0).Seconds()) + s.values.Push(v) + } + } +} + +// 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 +// values, [0, 10], a 50% percentile will land between them. +// +// Note: As a side-effect, this method will also sort the slice of values. +// Note2: The input format for percentiles is NOT percent! To express 50%, use 0.5, not 50. +func CalculatePercentiles(values []int64, ps []float64) []float64 { + scores := make([]float64, len(ps)) + size := len(values) + if size == 0 { + return scores + } + slices.Sort(values) + for i, p := range ps { + pos := p * float64(size+1) + + if pos < 1.0 { + scores[i] = float64(values[0]) + } else if pos >= float64(size) { + scores[i] = float64(values[size-1]) + } else { + lower := float64(values[int(pos)-1]) + upper := float64(values[int(pos)]) + scores[i] = lower + (pos-math.Floor(pos))*(upper-lower) + } + } + return scores +} + // SampleVariance returns the variance of the slice of int64. func SampleVariance(mean float64, values []int64) float64 { if len(values) == 0 { @@ -302,7 +283,7 @@ func SampleVariance(mean float64, values []int64) float64 { return sum / float64(len(values)) } -// A uniform sample using Vitter's Algorithm R. +// UniformSample implements a uniform sample using Vitter's Algorithm R. // // type UniformSample struct { @@ -316,9 +297,6 @@ type UniformSample struct { // NewUniformSample constructs a new uniform sample with the given reservoir // size. func NewUniformSample(reservoirSize int) Sample { - if !Enabled { - return NilSample{} - } return &UniformSample{ reservoirSize: reservoirSize, values: make([]int64, 0, reservoirSize), @@ -336,14 +314,13 @@ func (s *UniformSample) Clear() { s.mutex.Lock() defer s.mutex.Unlock() s.count = 0 - s.values = make([]int64, 0, s.reservoirSize) + clear(s.values) } // Snapshot returns a read-only copy of the sample. -func (s *UniformSample) Snapshot() SampleSnapshot { +func (s *UniformSample) Snapshot() *sampleSnapshot { s.mutex.Lock() - values := make([]int64, len(s.values)) - copy(values, s.values) + values := slices.Clone(s.values) count := s.count s.mutex.Unlock() return newSampleSnapshot(count, values) @@ -351,21 +328,24 @@ func (s *UniformSample) Snapshot() SampleSnapshot { // Update samples a new value. func (s *UniformSample) Update(v int64) { + if !metricsEnabled { + return + } s.mutex.Lock() defer s.mutex.Unlock() s.count++ if len(s.values) < s.reservoirSize { s.values = append(s.values, v) + return + } + var r int64 + if s.rand != nil { + r = s.rand.Int63n(s.count) } else { - var r int64 - if s.rand != nil { - r = s.rand.Int63n(s.count) - } else { - r = rand.Int63n(s.count) - } - if r < int64(len(s.values)) { - s.values[int(r)] = v - } + r = rand.Int63n(s.count) + } + if r < int64(len(s.values)) { + s.values[int(r)] = v } } diff --git a/metrics/sample_test.go b/metrics/sample_test.go index c855671ae2..6619eb1e9e 100644 --- a/metrics/sample_test.go +++ b/metrics/sample_test.go @@ -86,7 +86,7 @@ func TestExpDecaySample(t *testing.T) { if have, want := snap.Size(), min(tc.updates, tc.reservoirSize); have != want { t.Errorf("unexpected size: have %d want %d", have, want) } - values := snap.(*sampleSnapshot).values + values := snap.values if have, want := len(values), min(tc.updates, tc.reservoirSize); have != want { t.Errorf("unexpected values length: have %d want %d", have, want) } @@ -111,8 +111,7 @@ func TestExpDecaySampleNanosecondRegression(t *testing.T) { for i := 0; i < 1000; i++ { sw.Update(20) } - s := sw.Snapshot() - v := s.(*sampleSnapshot).values + v := sw.Snapshot().values avg := float64(0) for i := 0; i < len(v); i++ { avg += float64(v[i]) @@ -166,7 +165,7 @@ func TestUniformSample(t *testing.T) { if size := s.Size(); size != 100 { t.Errorf("s.Size(): 100 != %v\n", size) } - values := s.(*sampleSnapshot).values + values := s.values if l := len(values); l != 100 { t.Errorf("len(s.Values()): 100 != %v\n", l) @@ -184,8 +183,7 @@ func TestUniformSampleIncludesTail(t *testing.T) { for i := 0; i < max; i++ { sw.Update(int64(i)) } - s := sw.Snapshot() - v := s.(*sampleSnapshot).values + v := sw.Snapshot().values sum := 0 exp := (max - 1) * max / 2 for i := 0; i < len(v); i++ { @@ -220,7 +218,7 @@ func benchmarkSample(b *testing.B, s Sample) { } } -func testExpDecaySampleStatistics(t *testing.T, s SampleSnapshot) { +func testExpDecaySampleStatistics(t *testing.T, s *sampleSnapshot) { if sum := s.Sum(); sum != 496598 { t.Errorf("s.Sum(): 496598 != %v\n", sum) } @@ -251,7 +249,7 @@ func testExpDecaySampleStatistics(t *testing.T, s SampleSnapshot) { } } -func testUniformSampleStatistics(t *testing.T, s SampleSnapshot) { +func testUniformSampleStatistics(t *testing.T, s *sampleSnapshot) { if count := s.Count(); count != 10000 { t.Errorf("s.Count(): 10000 != %v\n", count) } diff --git a/metrics/syslog.go b/metrics/syslog.go index fd856d6973..0bc4ed0da5 100644 --- a/metrics/syslog.go +++ b/metrics/syslog.go @@ -15,17 +15,17 @@ func Syslog(r Registry, d time.Duration, w *syslog.Writer) { for range time.Tick(d) { r.Each(func(name string, i interface{}) { switch metric := i.(type) { - case Counter: + case *Counter: w.Info(fmt.Sprintf("counter %s: count: %d", name, metric.Snapshot().Count())) - case CounterFloat64: + case *CounterFloat64: w.Info(fmt.Sprintf("counter %s: count: %f", name, metric.Snapshot().Count())) - case Gauge: + case *Gauge: w.Info(fmt.Sprintf("gauge %s: value: %d", name, metric.Snapshot().Value())) - case GaugeFloat64: + case *GaugeFloat64: w.Info(fmt.Sprintf("gauge %s: value: %f", name, metric.Snapshot().Value())) - case GaugeInfo: + case *GaugeInfo: w.Info(fmt.Sprintf("gauge %s: value: %s", name, metric.Snapshot().Value())) - case Healthcheck: + case *Healthcheck: metric.Check() w.Info(fmt.Sprintf("healthcheck %s: error: %v", name, metric.Error())) case Histogram: @@ -45,7 +45,7 @@ func Syslog(r Registry, d time.Duration, w *syslog.Writer) { ps[3], ps[4], )) - case Meter: + case *Meter: m := metric.Snapshot() w.Info(fmt.Sprintf( "meter %s: count: %d 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f", @@ -56,7 +56,7 @@ func Syslog(r Registry, d time.Duration, w *syslog.Writer) { m.Rate15(), m.RateMean(), )) - case Timer: + case *Timer: t := metric.Snapshot() ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) w.Info(fmt.Sprintf( diff --git a/metrics/timer.go b/metrics/timer.go index fc2a88f508..9df15c967a 100644 --- a/metrics/timer.go +++ b/metrics/timer.go @@ -5,47 +5,30 @@ import ( "time" ) -type TimerSnapshot interface { - HistogramSnapshot - MeterSnapshot -} - -// Timer capture the duration and rate of events. -type Timer interface { - Snapshot() TimerSnapshot - Stop() - Time(func()) - UpdateSince(time.Time) - Update(time.Duration) -} - // GetOrRegisterTimer returns an existing Timer or constructs and registers a -// new StandardTimer. +// new Timer. // Be sure to unregister the meter from the registry once it is of no use to // allow for garbage collection. -func GetOrRegisterTimer(name string, r Registry) Timer { +func GetOrRegisterTimer(name string, r Registry) *Timer { if nil == r { r = DefaultRegistry } - return r.GetOrRegister(name, NewTimer).(Timer) + return r.GetOrRegister(name, NewTimer).(*Timer) } -// NewCustomTimer constructs a new StandardTimer from a Histogram and a Meter. +// NewCustomTimer constructs a new Timer from a Histogram and a Meter. // Be sure to call Stop() once the timer is of no use to allow for garbage collection. -func NewCustomTimer(h Histogram, m Meter) Timer { - if !Enabled { - return NilTimer{} - } - return &StandardTimer{ +func NewCustomTimer(h Histogram, m *Meter) *Timer { + return &Timer{ histogram: h, meter: m, } } -// NewRegisteredTimer constructs and registers a new StandardTimer. +// NewRegisteredTimer constructs and registers a new Timer. // Be sure to unregister the meter from the registry once it is of no use to // allow for garbage collection. -func NewRegisteredTimer(name string, r Registry) Timer { +func NewRegisteredTimer(name string, r Registry) *Timer { c := NewTimer() if nil == r { r = DefaultRegistry @@ -54,60 +37,47 @@ func NewRegisteredTimer(name string, r Registry) Timer { return c } -// NewTimer constructs a new StandardTimer using an exponentially-decaying +// NewTimer constructs a new Timer using an exponentially-decaying // sample with the same reservoir size and alpha as UNIX load averages. // Be sure to call Stop() once the timer is of no use to allow for garbage collection. -func NewTimer() Timer { - if !Enabled { - return NilTimer{} - } - return &StandardTimer{ +func NewTimer() *Timer { + return &Timer{ histogram: NewHistogram(NewExpDecaySample(1028, 0.015)), meter: NewMeter(), } } -// NilTimer is a no-op Timer. -type NilTimer struct{} - -func (NilTimer) Snapshot() TimerSnapshot { return (*emptySnapshot)(nil) } -func (NilTimer) Stop() {} -func (NilTimer) Time(f func()) { f() } -func (NilTimer) Update(time.Duration) {} -func (NilTimer) UpdateSince(time.Time) {} - -// StandardTimer is the standard implementation of a Timer and uses a Histogram -// and Meter. -type StandardTimer struct { +// Timer captures the duration and rate of events, using a Histogram and a Meter. +type Timer struct { histogram Histogram - meter Meter + meter *Meter mutex sync.Mutex } // Snapshot returns a read-only copy of the timer. -func (t *StandardTimer) Snapshot() TimerSnapshot { +func (t *Timer) Snapshot() *TimerSnapshot { t.mutex.Lock() defer t.mutex.Unlock() - return &timerSnapshot{ + return &TimerSnapshot{ histogram: t.histogram.Snapshot(), meter: t.meter.Snapshot(), } } // Stop stops the meter. -func (t *StandardTimer) Stop() { +func (t *Timer) Stop() { t.meter.Stop() } // Time record the duration of the execution of the given function. -func (t *StandardTimer) Time(f func()) { +func (t *Timer) Time(f func()) { ts := time.Now() f() t.Update(time.Since(ts)) } // Update the duration of an event, in nanoseconds. -func (t *StandardTimer) Update(d time.Duration) { +func (t *Timer) Update(d time.Duration) { t.mutex.Lock() defer t.mutex.Unlock() t.histogram.Update(d.Nanoseconds()) @@ -116,67 +86,67 @@ func (t *StandardTimer) Update(d time.Duration) { // 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) { +func (t *Timer) UpdateSince(ts time.Time) { t.Update(time.Since(ts)) } -// timerSnapshot is a read-only copy of another Timer. -type timerSnapshot struct { +// TimerSnapshot is a read-only copy of another Timer. +type TimerSnapshot struct { histogram HistogramSnapshot - meter MeterSnapshot + meter *MeterSnapshot } // Count returns the number of events recorded at the time the snapshot was // taken. -func (t *timerSnapshot) Count() int64 { return t.histogram.Count() } +func (t *TimerSnapshot) Count() int64 { return t.histogram.Count() } // Max returns the maximum value at the time the snapshot was taken. -func (t *timerSnapshot) Max() int64 { return t.histogram.Max() } +func (t *TimerSnapshot) Max() int64 { return t.histogram.Max() } // Size returns the size of the sample at the time the snapshot was taken. -func (t *timerSnapshot) Size() int { return t.histogram.Size() } +func (t *TimerSnapshot) Size() int { return t.histogram.Size() } // Mean returns the mean value at the time the snapshot was taken. -func (t *timerSnapshot) Mean() float64 { return t.histogram.Mean() } +func (t *TimerSnapshot) Mean() float64 { return t.histogram.Mean() } // Min returns the minimum value at the time the snapshot was taken. -func (t *timerSnapshot) Min() int64 { return t.histogram.Min() } +func (t *TimerSnapshot) Min() int64 { return t.histogram.Min() } // Percentile returns an arbitrary percentile of sampled values at the time the // snapshot was taken. -func (t *timerSnapshot) Percentile(p float64) float64 { +func (t *TimerSnapshot) Percentile(p float64) float64 { return t.histogram.Percentile(p) } // Percentiles returns a slice of arbitrary percentiles of sampled values at // the time the snapshot was taken. -func (t *timerSnapshot) Percentiles(ps []float64) []float64 { +func (t *TimerSnapshot) Percentiles(ps []float64) []float64 { return t.histogram.Percentiles(ps) } // Rate1 returns the one-minute moving average rate of events per second at the // time the snapshot was taken. -func (t *timerSnapshot) Rate1() float64 { return t.meter.Rate1() } +func (t *TimerSnapshot) Rate1() float64 { return t.meter.Rate1() } // Rate5 returns the five-minute moving average rate of events per second at // the time the snapshot was taken. -func (t *timerSnapshot) Rate5() float64 { return t.meter.Rate5() } +func (t *TimerSnapshot) Rate5() float64 { return t.meter.Rate5() } // Rate15 returns the fifteen-minute moving average rate of events per second // at the time the snapshot was taken. -func (t *timerSnapshot) Rate15() float64 { return t.meter.Rate15() } +func (t *TimerSnapshot) Rate15() float64 { return t.meter.Rate15() } // RateMean returns the meter's mean rate of events per second at the time the // snapshot was taken. -func (t *timerSnapshot) RateMean() float64 { return t.meter.RateMean() } +func (t *TimerSnapshot) RateMean() float64 { return t.meter.RateMean() } // StdDev returns the standard deviation of the values at the time the snapshot // was taken. -func (t *timerSnapshot) StdDev() float64 { return t.histogram.StdDev() } +func (t *TimerSnapshot) StdDev() float64 { return t.histogram.StdDev() } // Sum returns the sum at the time the snapshot was taken. -func (t *timerSnapshot) Sum() int64 { return t.histogram.Sum() } +func (t *TimerSnapshot) Sum() int64 { return t.histogram.Sum() } // Variance returns the variance of the values at the time the snapshot was // taken. -func (t *timerSnapshot) Variance() float64 { return t.histogram.Variance() } +func (t *TimerSnapshot) Variance() float64 { return t.histogram.Variance() } diff --git a/metrics/writer.go b/metrics/writer.go index c211c5046b..2a41f8e1fe 100644 --- a/metrics/writer.go +++ b/metrics/writer.go @@ -26,22 +26,22 @@ func WriteOnce(r Registry, w io.Writer) { slices.SortFunc(namedMetrics, namedMetric.cmp) for _, namedMetric := range namedMetrics { switch metric := namedMetric.m.(type) { - case Counter: + case *Counter: fmt.Fprintf(w, "counter %s\n", namedMetric.name) fmt.Fprintf(w, " count: %9d\n", metric.Snapshot().Count()) - case CounterFloat64: + case *CounterFloat64: fmt.Fprintf(w, "counter %s\n", namedMetric.name) fmt.Fprintf(w, " count: %f\n", metric.Snapshot().Count()) - case Gauge: + case *Gauge: fmt.Fprintf(w, "gauge %s\n", namedMetric.name) fmt.Fprintf(w, " value: %9d\n", metric.Snapshot().Value()) - case GaugeFloat64: + case *GaugeFloat64: fmt.Fprintf(w, "gauge %s\n", namedMetric.name) fmt.Fprintf(w, " value: %f\n", metric.Snapshot().Value()) - case GaugeInfo: + case *GaugeInfo: fmt.Fprintf(w, "gauge %s\n", namedMetric.name) fmt.Fprintf(w, " value: %s\n", metric.Snapshot().Value().String()) - case Healthcheck: + case *Healthcheck: metric.Check() fmt.Fprintf(w, "healthcheck %s\n", namedMetric.name) fmt.Fprintf(w, " error: %v\n", metric.Error()) @@ -59,7 +59,7 @@ func WriteOnce(r Registry, w io.Writer) { fmt.Fprintf(w, " 95%%: %12.2f\n", ps[2]) fmt.Fprintf(w, " 99%%: %12.2f\n", ps[3]) fmt.Fprintf(w, " 99.9%%: %12.2f\n", ps[4]) - case Meter: + case *Meter: m := metric.Snapshot() fmt.Fprintf(w, "meter %s\n", namedMetric.name) fmt.Fprintf(w, " count: %9d\n", m.Count()) @@ -67,7 +67,7 @@ func WriteOnce(r Registry, w io.Writer) { fmt.Fprintf(w, " 5-min rate: %12.2f\n", m.Rate5()) fmt.Fprintf(w, " 15-min rate: %12.2f\n", m.Rate15()) fmt.Fprintf(w, " mean rate: %12.2f\n", m.RateMean()) - case Timer: + case *Timer: t := metric.Snapshot() ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) fmt.Fprintf(w, "timer %s\n", namedMetric.name) diff --git a/p2p/discover/metrics.go b/p2p/discover/metrics.go index 9261ae1376..5d4c953c90 100644 --- a/p2p/discover/metrics.go +++ b/p2p/discover/metrics.go @@ -34,7 +34,7 @@ const ( ) var ( - bucketsCounter []metrics.Counter + bucketsCounter []*metrics.Counter ingressTrafficMeter = metrics.NewRegisteredMeter(ingressMeterName, nil) egressTrafficMeter = metrics.NewRegisteredMeter(egressMeterName, nil) ) @@ -53,7 +53,7 @@ type meteredUdpConn struct { func newMeteredConn(conn UDPConn) UDPConn { // Short circuit if metrics are disabled - if !metrics.Enabled { + if !metrics.Enabled() { return conn } return &meteredUdpConn{udpConn: conn} diff --git a/p2p/discover/table.go b/p2p/discover/table.go index cbe2972541..392279f905 100644 --- a/p2p/discover/table.go +++ b/p2p/discover/table.go @@ -570,7 +570,7 @@ func (tab *Table) nodeAdded(b *bucket, n *tableNode) { if tab.nodeAddedHook != nil { tab.nodeAddedHook(b, n) } - if metrics.Enabled { + if metrics.Enabled() { bucketsCounter[b.index].Inc(1) } } @@ -580,7 +580,7 @@ func (tab *Table) nodeRemoved(b *bucket, n *tableNode) { if tab.nodeRemovedHook != nil { tab.nodeRemovedHook(b, n) } - if metrics.Enabled { + if metrics.Enabled() { bucketsCounter[b.index].Dec(1) } } diff --git a/p2p/metrics.go b/p2p/metrics.go index a2ae213b70..1fd0f26db3 100644 --- a/p2p/metrics.go +++ b/p2p/metrics.go @@ -37,19 +37,19 @@ const ( ) var ( - activePeerGauge metrics.Gauge = metrics.NilGauge{} - activeInboundPeerGauge metrics.Gauge = metrics.NilGauge{} - activeOutboundPeerGauge metrics.Gauge = metrics.NilGauge{} + activePeerGauge = metrics.NewRegisteredGauge("p2p/peers", nil) + activeInboundPeerGauge = metrics.NewRegisteredGauge("p2p/peers/inbound", nil) + activeOutboundPeerGauge = metrics.NewRegisteredGauge("p2p/peers/outbound", nil) ingressTrafficMeter = metrics.NewRegisteredMeter("p2p/ingress", nil) egressTrafficMeter = metrics.NewRegisteredMeter("p2p/egress", nil) // general ingress/egress connection meters - serveMeter metrics.Meter = metrics.NilMeter{} - serveSuccessMeter metrics.Meter = metrics.NilMeter{} - dialMeter metrics.Meter = metrics.NilMeter{} - dialSuccessMeter metrics.Meter = metrics.NilMeter{} - dialConnectionError metrics.Meter = metrics.NilMeter{} + serveMeter = metrics.NewRegisteredMeter("p2p/serves", nil) + serveSuccessMeter = metrics.NewRegisteredMeter("p2p/serves/success", nil) + dialMeter = metrics.NewRegisteredMeter("p2p/dials", nil) + dialSuccessMeter = metrics.NewRegisteredMeter("p2p/dials/success", nil) + dialConnectionError = metrics.NewRegisteredMeter("p2p/dials/error/connection", nil) // handshake error meters dialTooManyPeers = metrics.NewRegisteredMeter("p2p/dials/error/saturated", nil) @@ -61,25 +61,10 @@ var ( dialProtoHandshakeError = metrics.NewRegisteredMeter("p2p/dials/error/rlpx/proto", nil) ) -func init() { - if !metrics.Enabled { - return - } - - activePeerGauge = metrics.NewRegisteredGauge("p2p/peers", nil) - activeInboundPeerGauge = metrics.NewRegisteredGauge("p2p/peers/inbound", nil) - activeOutboundPeerGauge = metrics.NewRegisteredGauge("p2p/peers/outbound", nil) - serveMeter = metrics.NewRegisteredMeter("p2p/serves", nil) - serveSuccessMeter = metrics.NewRegisteredMeter("p2p/serves/success", nil) - dialMeter = metrics.NewRegisteredMeter("p2p/dials", nil) - dialSuccessMeter = metrics.NewRegisteredMeter("p2p/dials/success", nil) - dialConnectionError = metrics.NewRegisteredMeter("p2p/dials/error/connection", nil) -} - // markDialError matches errors that occur while setting up a dial connection // to the corresponding meter. func markDialError(err error) { - if !metrics.Enabled { + if !metrics.Enabled() { return } if err2 := errors.Unwrap(err); err2 != nil { @@ -113,7 +98,7 @@ type meteredConn struct { // connection meter and also increases the metered peer count. If the metrics // system is disabled, function returns the original connection. func newMeteredConn(conn net.Conn) net.Conn { - if !metrics.Enabled { + if !metrics.Enabled() { return conn } return &meteredConn{Conn: conn} diff --git a/p2p/peer.go b/p2p/peer.go index c3834965cc..30be151a2f 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -357,7 +357,7 @@ func (p *Peer) handle(msg Msg) error { if err != nil { return fmt.Errorf("msg code out of range: %v", msg.Code) } - if metrics.Enabled { + if metrics.Enabled() { m := fmt.Sprintf("%s/%s/%d/%#02x", ingressMeterName, proto.Name, proto.Version, msg.Code-proto.offset) metrics.GetOrRegisterMeter(m, nil).Mark(int64(msg.meterSize)) metrics.GetOrRegisterMeter(m+"/packets", nil).Mark(1) diff --git a/p2p/tracker/tracker.go b/p2p/tracker/tracker.go index 6a733b9ba5..5b72eb2b88 100644 --- a/p2p/tracker/tracker.go +++ b/p2p/tracker/tracker.go @@ -84,7 +84,7 @@ func New(protocol string, timeout time.Duration) *Tracker { // Track adds a network request to the tracker to wait for a response to arrive // or until the request it cancelled or times out. func (t *Tracker) Track(peer string, version uint, reqCode uint64, resCode uint64, id uint64) { - if !metrics.Enabled { + if !metrics.Enabled() { return } t.lock.Lock() @@ -163,7 +163,7 @@ func (t *Tracker) schedule() { // Fulfil fills a pending request, if any is available, reporting on various metrics. func (t *Tracker) Fulfil(peer string, version uint, code uint64, id uint64) { - if !metrics.Enabled { + if !metrics.Enabled() { return } t.lock.Lock() diff --git a/p2p/transport.go b/p2p/transport.go index 5fc7686feb..360e73a0de 100644 --- a/p2p/transport.go +++ b/p2p/transport.go @@ -98,7 +98,7 @@ func (t *rlpxTransport) WriteMsg(msg Msg) error { // Set metrics. msg.meterSize = size - if metrics.Enabled && msg.meterCap.Name != "" { // don't meter non-subprotocol messages + if metrics.Enabled() && msg.meterCap.Name != "" { // don't meter non-subprotocol messages m := fmt.Sprintf("%s/%s/%d/%#02x", egressMeterName, msg.meterCap.Name, msg.meterCap.Version, msg.meterCode) metrics.GetOrRegisterMeter(m, nil).Mark(int64(msg.meterSize)) metrics.GetOrRegisterMeter(m+"/packets", nil).Mark(1) diff --git a/triedb/pathdb/states.go b/triedb/pathdb/states.go index e1611b3ebc..6e633db272 100644 --- a/triedb/pathdb/states.go +++ b/triedb/pathdb/states.go @@ -43,7 +43,7 @@ func (c *counter) add(size int) { } // report uploads the cached statistics to meters. -func (c *counter) report(count metrics.Meter, size metrics.Meter) { +func (c *counter) report(count, size *metrics.Meter) { count.Mark(int64(c.n)) size.Mark(int64(c.size)) } From 4ed36ea1f877fc992db0fbd0b10a129bf0dca64d Mon Sep 17 00:00:00 2001 From: Hteev Oli Date: Tue, 10 Dec 2024 21:22:43 +0800 Subject: [PATCH 006/940] build: update to Go 1.23.4 (#30872) --- build/checksums.txt | 98 ++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index b835215850..b8061c9244 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,56 +5,56 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/ ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz -# version:golang 1.23.3 +# version:golang 1.23.4 # https://go.dev/dl/ -8d6a77332487557c6afa2421131b50f83db4ae3c579c3bc72e670ee1f6968599 go1.23.3.src.tar.gz -bdbf2a243ed4a121c9988684e5b15989cb244c1ff9e41ca823d0187b5c859114 go1.23.3.aix-ppc64.tar.gz -b79c77bbdf61e6e486aa6bea9286f3f7969c28e2ff7686ce10c334f746bfb724 go1.23.3.darwin-amd64.pkg -c7e024d5c0bc81845070f23598caf02f05b8ae88fd4ad2cd3e236ddbea833ad2 go1.23.3.darwin-amd64.tar.gz -3e764df0db8f3c7470b9ff641954a380510a4822613c06bd5a195fd083f4731d go1.23.3.darwin-arm64.pkg -31e119fe9bde6e105407a32558d5b5fa6ca11e2bd17f8b7b2f8a06aba16a0632 go1.23.3.darwin-arm64.tar.gz -3872c9a98331050a242afe63fa6abc8fc313aca83dcaefda318e903309ac0c8d go1.23.3.dragonfly-amd64.tar.gz -69479fa016ec5b4605885643ce0c2dd5c583e02353978feb6de38c961863b9cc go1.23.3.freebsd-386.tar.gz -bf1de22a900646ef4f79480ed88337856d47089cc610f87e6fef46f6b8db0e1f go1.23.3.freebsd-amd64.tar.gz -e461f866479bc36bdd4cfec32bfecb1bb243152268a1b3223de109410dec3407 go1.23.3.freebsd-arm.tar.gz -24154b4018a45540aefeb6b5b9ffdcc8d9a8cdb78cd7fec262787b89fed19997 go1.23.3.freebsd-arm64.tar.gz -218f3f1532e61dd65c330c2a5fc85bec18cc3690489763e62ffa9bb9fc85a68e go1.23.3.freebsd-riscv64.tar.gz -24e3f34858b8687c31f5e5ab9e46d27fb613b0d50a94261c500cebb2d79c0672 go1.23.3.illumos-amd64.tar.gz -3d7b00191a43c50d28e0903a0c576104bc7e171a8670de419d41111c08dfa299 go1.23.3.linux-386.tar.gz -a0afb9744c00648bafb1b90b4aba5bdb86f424f02f9275399ce0c20b93a2c3a8 go1.23.3.linux-amd64.tar.gz -1f7cbd7f668ea32a107ecd41b6488aaee1f5d77a66efd885b175494439d4e1ce go1.23.3.linux-arm64.tar.gz -5f0332754beffc65af65a7b2da76e9dd997567d0d81b6f4f71d3588dc7b4cb00 go1.23.3.linux-armv6l.tar.gz -1d0161a8946c7d99f717bad23631738408511f9f87e78d852224a023d8882ad8 go1.23.3.linux-loong64.tar.gz -e924a7c9027f521f8a3563541ed0f89a4db3ef005b6b71263415b38e0b46e63a go1.23.3.linux-mips.tar.gz -4cdf8c38165627f032c2b17cdd95e4aafff40d75fc873824d4c94914284098ca go1.23.3.linux-mips64.tar.gz -5e49347e7325d2e268fb14040529b704e66eed77154cc73a919e9167d8527a2f go1.23.3.linux-mips64le.tar.gz -142eabc17cee99403e895383ed7a6b7b40e740e8c2f73b79352bb9d1242fbd98 go1.23.3.linux-mipsle.tar.gz -96ad61ba6b6cc0f5adfd75e65231c61e7db26d8236f01117023899528164d1b0 go1.23.3.linux-ppc64.tar.gz -e3b926c81e8099d3cee6e6e270b85b39c3bd44263f8d3df29aacb4d7e00507c8 go1.23.3.linux-ppc64le.tar.gz -324e03b6f59be841dfbaeabc466224b0f0905f5ad3a225b7c0703090e6c4b1a5 go1.23.3.linux-riscv64.tar.gz -6bd72fcef72b046b6282c2d1f2c38f31600e4fe9361fcd8341500c754fb09c38 go1.23.3.linux-s390x.tar.gz -5df382337fe2e4ea6adaafa823da5e083513a97534a38f89d691dd6f599084ca go1.23.3.netbsd-386.tar.gz -9ae7cb6095a3e91182ac03547167e230fddd4941ed02dbdb6af663b2a53d9db7 go1.23.3.netbsd-amd64.tar.gz -4a452c4134a9bea6213d8925d322f26b01c0eccda1330585bb2b241c76a0c3ea go1.23.3.netbsd-arm.tar.gz -8ff3b5184d840148dbca061c04dca35a7070dc894255d3b755066bd76a7094dc go1.23.3.netbsd-arm64.tar.gz -5b6940922e68ac1162a704a8b583fb4f039f955bfe97c35a56c40269cbcff9b1 go1.23.3.openbsd-386.tar.gz -6ae4aeb6a88f3754b10ecec90422a30fb8bf86c3187be2be9408d67a5a235ace go1.23.3.openbsd-amd64.tar.gz -e5eae226391b60c4d1ea1022663f55b225c6d7bab67f31fbafd5dd7a04684006 go1.23.3.openbsd-arm.tar.gz -e12b2c04535e0bf5561d54831122b410d708519c1ec2c56b0c2350b15243c331 go1.23.3.openbsd-arm64.tar.gz -599818e4062166d7a112f6f3fcca2dd4e2cdd3111fe48f9757bd8debf38c7f52 go1.23.3.openbsd-ppc64.tar.gz -9ca4db8cab2a07d561f5b2a9397793684ab3b22326add1fe8cda8a545a1693db go1.23.3.openbsd-riscv64.tar.gz -8fca1ec2aced936e0170605378ee7f0acb38f002490321f67fc83728ee281967 go1.23.3.plan9-386.tar.gz -22d663692224fc1933a97f61d9fe49815e3b9ef1c2be97046505683fdf2e23c7 go1.23.3.plan9-amd64.tar.gz -d0417a702d0e776d57e450fa2ce1ce7efa199a636644776862dbf946c409a462 go1.23.3.plan9-arm.tar.gz -b5d9db1c02e0ca266a142eb687bd7749890c30872b09a4a0ffcd491425039754 go1.23.3.solaris-amd64.tar.gz -14b7baf4af2046013b74dfac6e9a0a7403f15ee9940a16890bc028dfd32c49ac go1.23.3.windows-386.msi -23da9089ea6c5612d718f13c26e9bfc9aaaabe222838075346a8191d48f9dfe5 go1.23.3.windows-386.zip -614f0e3eed82245dfb4356d4e8d5b96abecca6a4c4f0168c0e389e4dd6284db8 go1.23.3.windows-amd64.msi -81968b563642096b8a7521171e2be6e77ff6f44032f7493b7bdec9d33f44f31d go1.23.3.windows-amd64.zip -c9951eecad732c59dfde6dc4803fa9253eb074663c61035c8d856f4d2eb146cb go1.23.3.windows-arm.msi -1a7db02be47deada42082d21d63eba0013f93375cfa0e7768962f1295a469022 go1.23.3.windows-arm.zip -a74e3e195219af4330b93c71cd4b736b709a5654a07cc37eebe181c4984afb82 go1.23.3.windows-arm64.msi -dbdfa868b1a3f8c62950373e4975d83f90dd8b869a3907319af8384919bcaffe go1.23.3.windows-arm64.zip +ad345ac421e90814293a9699cca19dd5238251c3f687980bbcae28495b263531 go1.23.4.src.tar.gz +459a09504f7ebf2cbcee6ac282c8f34f97651217b1feae64557dcdd392b9bb62 go1.23.4.aix-ppc64.tar.gz +0f4e569b2d38cb75cb2efcaf56beb42778ab5e46d89318fef39060fe36d7b9b7 go1.23.4.darwin-amd64.pkg +6700067389a53a1607d30aa8d6e01d198230397029faa0b109e89bc871ab5a0e go1.23.4.darwin-amd64.tar.gz +19c054eaf40c5fac65b027f7443c01382e493d3c8c42cf8b2504832ebddce037 go1.23.4.darwin-arm64.pkg +87d2bb0ad4fe24d2a0685a55df321e0efe4296419a9b3de03369dbe60b8acd3a go1.23.4.darwin-arm64.tar.gz +5e73dc89b44626677ec9d9aa4257d6d2ef1245502bc36a99385284910d0ade0a go1.23.4.dragonfly-amd64.tar.gz +8df26b1e71234756c1f0e82cfffba3f427c5a91a251844ada2c7694a6986c546 go1.23.4.freebsd-386.tar.gz +7de078d94d2af50ee9506ef7df85e4d12d4018b23e0b2cbcbc61d686f549b41a go1.23.4.freebsd-amd64.tar.gz +3f23e0a01cfe24e4160124cd7ab02bdd188264652074abdbce401c93f41e58a4 go1.23.4.freebsd-arm.tar.gz +986a20e7c94431f03b44b3c415abc698c7b4edc2ae8431f7ecae1c2429d4cfa2 go1.23.4.freebsd-arm64.tar.gz +25e39f005f977778ce963fc43089510fe7514f3cfc0358eab584de4ce9f181fb go1.23.4.freebsd-riscv64.tar.gz +7e1d52f93da68c3bab39e3d83f89944d7d151208e54fdc30b0eda2a3812661d7 go1.23.4.illumos-amd64.tar.gz +4a4a0e7587ef8c8a326439b957027f2791795e2d29d4ae3885b4091a48f843bc go1.23.4.linux-386.tar.gz +6924efde5de86fe277676e929dc9917d466efa02fb934197bc2eba35d5680971 go1.23.4.linux-amd64.tar.gz +16e5017863a7f6071363782b1b8042eb12c6ca4f4cd71528b2123f0a1275b13e go1.23.4.linux-arm64.tar.gz +1f1dda0dc7ce0b2295f57258ec5ef0803fd31b9ed0aa20e2e9222334e5755de1 go1.23.4.linux-armv6l.tar.gz +4f469179a335a1a7bb9f991ad0c567f3d3eeb9b412ecd192206ab5c3e1a52b5a go1.23.4.linux-loong64.tar.gz +86b68185bcc43ea07190e95137c3442f062acc7ae10c3f1cf900fbe23e07df24 go1.23.4.linux-mips.tar.gz +3a19245eec76533b3d01c90f3a40a38d63684028f0fd54d442dc9a9d03197891 go1.23.4.linux-mips64.tar.gz +b53a06fc8455f6a875329e8d2e24d39db298122c9cce6e948117022191f6c613 go1.23.4.linux-mips64le.tar.gz +66120a8105b8ba6559f4e6a13b1e39b433fb8032df9d1744e4486876fa1723ce go1.23.4.linux-mipsle.tar.gz +33be2bfb27f2821a65e9f6aba744c85ea7c5e233e16bac27bb3ec253bcd4e970 go1.23.4.linux-ppc64.tar.gz +65a303ef51e48ff77e004a6a5b4db6ce59495cd59c6af51b54bf4f786c01a1b9 go1.23.4.linux-ppc64le.tar.gz +7c40e9e0d722cef14ede765159ba297f4c6e3093bb106f10fbccf8564780049a go1.23.4.linux-riscv64.tar.gz +74aab82bf4eca7c26c830a5b0e2a31d193a4d5ba47045526b92473cc7188d7d7 go1.23.4.linux-s390x.tar.gz +dba009d8bf9928cb5a1e31fcbe0eb41335cce4fe63755d95cef6b5987df4ed5a go1.23.4.netbsd-386.tar.gz +54b081cc36355aa5ecb6db9544cf7e77366a7b08ce96cb98a45d043e393660c7 go1.23.4.netbsd-amd64.tar.gz +f05fec348c7c9f07e1ad4e436db4122e98de99ebcfbf6ac6176869785f334a02 go1.23.4.netbsd-arm.tar.gz +317878da2bface5a57a8eaf5c1fe2b40b1c82d8172a10453ad3eea36f6946bdb go1.23.4.netbsd-arm64.tar.gz +0d84350dfd72c505c6ad474e51676b04e95ffb748c614bd5bf8510026873059b go1.23.4.openbsd-386.tar.gz +cc62f5a14ea3d573d8edbce1833f70a8f99ca048a9db0fcc9e738fd48e950505 go1.23.4.openbsd-amd64.tar.gz +326aba6cf5bb9348fa3e41217abd2c84eac92608684e2fe8c5474fdab23a0db9 go1.23.4.openbsd-arm.tar.gz +51ea2a2588bf3da8e1476f3e2bd4d6724d74126e99f9c6ea9af4ebe389e64de6 go1.23.4.openbsd-arm64.tar.gz +44c5c82ab23e40225b2ba1e7d19150a5973ea58e93b4931e426e6e6f0d108872 go1.23.4.openbsd-ppc64.tar.gz +5fa31fc13d1e3c123a5e96ba38683fa2c947baed23ac9c7c341afcfe007c8993 go1.23.4.openbsd-riscv64.tar.gz +e5952fc93eeaa0094ef09a0e72a9f06f0621ce841a39f9637fb5b9062e77d67a go1.23.4.plan9-386.tar.gz +fb2a9ee3ae5a77e734862e257a9395b43e707ac45e060dfa84c5a40688e73170 go1.23.4.plan9-amd64.tar.gz +e1b95563b19fdebd6ea0d20c07641e69580976fa754e586c831ad7a3ae987140 go1.23.4.plan9-arm.tar.gz +088c282509fc9e1a8f29fc0dd16fe486854d05b8ceba08d077d17d11d6979a41 go1.23.4.solaris-amd64.tar.gz +e5865c1bfc3fee5d003819b2e2c800f598fe9994931bac63f573e8d05a10d91f go1.23.4.windows-386.msi +e544e0e356147ba998e267002bd0f2c4bf3370d495467a55baf2c63595a2026d go1.23.4.windows-386.zip +5f8cc5991eb8f4f96b6c611d839453cd11c9a2c3f23672a4188342c97ee159fa go1.23.4.windows-amd64.msi +16c59ac9196b63afb872ce9b47f945b9821a3e1542ec125f16f6085a1c0f3c39 go1.23.4.windows-amd64.zip +fc77c0531406d092c5356167e45c05a22d16bea84e3fa555e0f03af085c11763 go1.23.4.windows-arm.msi +1012cfd8ca7241c2beecb5c345dd61f01897c6f6baca80ea1bfed357035c868a go1.23.4.windows-arm.zip +8347c1aa4e1e67954d12830f88dbe44bd7ac0ec134bb472783dbfb5a3a8865d0 go1.23.4.windows-arm64.msi +db69cae5006753c785345c3215ad941f8b6224e2f81fec471c42d6857bee0e6f go1.23.4.windows-arm64.zip # version:golangci 1.61.0 # https://github.com/golangci/golangci-lint/releases/ From 330190e476e2a2de4aac712551629a4134f802d5 Mon Sep 17 00:00:00 2001 From: Darren Kelly <107671032+darrenvechain@users.noreply.github.com> Date: Tue, 10 Dec 2024 13:30:24 +0000 Subject: [PATCH 007/940] accounts/abi: support unpacking solidity errors (#30738) This PR adds the error fragments to `func (abi ABI) getArguments` which allows typed decoding of errors. --- accounts/abi/abi.go | 7 +++++-- accounts/abi/abi_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index c7bc2b4541..f75278c8b1 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -84,7 +84,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { func (abi ABI) getArguments(name string, data []byte) (Arguments, error) { // since there can't be naming collisions with contracts and events, - // we need to decide whether we're calling a method or an event + // we need to decide whether we're calling a method, event or an error var args Arguments if method, ok := abi.Methods[name]; ok { if len(data)%32 != 0 { @@ -95,8 +95,11 @@ func (abi ABI) getArguments(name string, data []byte) (Arguments, error) { if event, ok := abi.Events[name]; ok { args = event.Inputs } + if err, ok := abi.Errors[name]; ok { + args = err.Inputs + } if args == nil { - return nil, fmt.Errorf("abi: could not locate named method or event: %s", name) + return nil, fmt.Errorf("abi: could not locate named method, event or error: %s", name) } return args, nil } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index fc290cfe84..db9a4c55a5 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testrand" ) const jsondata = ` @@ -317,6 +318,38 @@ func TestCustomErrors(t *testing.T) { check("MyError", "MyError(uint256)") } +func TestCustomErrorUnpackIntoInterface(t *testing.T) { + t.Parallel() + errorName := "MyError" + json := fmt.Sprintf(`[{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"%s","type":"error"}]`, errorName) + abi, err := JSON(strings.NewReader(json)) + if err != nil { + t.Fatal(err) + } + type MyError struct { + Sender common.Address + Balance *big.Int + } + + sender := testrand.Address() + balance := new(big.Int).SetBytes(testrand.Bytes(8)) + encoded, err := abi.Errors[errorName].Inputs.Pack(sender, balance) + if err != nil { + t.Fatal(err) + } + result := MyError{} + err = abi.UnpackIntoInterface(&result, errorName, encoded) + if err != nil { + t.Fatal(err) + } + if result.Sender != sender { + t.Errorf("expected %x got %x", sender, result.Sender) + } + if result.Balance.Cmp(balance) != 0 { + t.Errorf("expected %v got %v", balance, result.Balance) + } +} + func TestMultiPack(t *testing.T) { t.Parallel() abi, err := JSON(strings.NewReader(jsondata)) From c7e740f40ca93cd2b8681b97af71e0b20207ca09 Mon Sep 17 00:00:00 2001 From: gitglorythegreat Date: Wed, 11 Dec 2024 18:05:59 +0800 Subject: [PATCH 008/940] core/state: remove pointless wrapper functions (#30891) --- core/state/access_list.go | 5 +---- core/state/statedb_test.go | 14 +++----------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/core/state/access_list.go b/core/state/access_list.go index 90e5590748..a58c2b20ea 100644 --- a/core/state/access_list.go +++ b/core/state/access_list.go @@ -139,10 +139,7 @@ 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) - }) + return slices.EqualFunc(al.slots, other.slots, maps.Equal) } // PrettyPrint prints the contents of the access list in a human-readable form diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 57886e6e03..37141e90b0 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -650,11 +650,7 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { { have := state.transientStorage want := checkstate.transientStorage - eq := maps.EqualFunc(have, want, - func(a Storage, b Storage) bool { - return maps.Equal(a, b) - }) - if !eq { + if !maps.EqualFunc(have, want, maps.Equal) { return fmt.Errorf("transient storage differs ,have\n%v\nwant\n%v", have.PrettyPrint(), want.PrettyPrint()) @@ -1034,12 +1030,8 @@ func testMissingTrieNodes(t *testing.T, scheme string) { func TestStateDBAccessList(t *testing.T) { // Some helpers - addr := func(a string) common.Address { - return common.HexToAddress(a) - } - slot := func(a string) common.Hash { - return common.HexToHash(a) - } + addr := common.HexToAddress + slot := common.HexToHash db := NewDatabaseForTesting() state, _ := New(types.EmptyRootHash, db) From c1c250714842768687e8a4abe0dd9f57ca9dcc53 Mon Sep 17 00:00:00 2001 From: lorenzo <31852651+lorenzo-dev1@users.noreply.github.com> Date: Thu, 12 Dec 2024 12:33:42 +0100 Subject: [PATCH 009/940] p2p: fix DiscReason encoding/decoding (#30855) This fixes an issue where the disconnect message was not wrapped in a list. The specification requires it to be a list like any other message. In order to remain compatible with legacy geth versions, we now accept both encodings when parsing a disconnect message. --------- Co-authored-by: Felix Lange --- p2p/peer.go | 25 ++++++++++++++++++++++--- p2p/peer_error.go | 5 ++++- p2p/transport.go | 24 ++++++++++-------------- p2p/transport_test.go | 10 ++++++++-- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/p2p/peer.go b/p2p/peer.go index 30be151a2f..a01df63d0c 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -345,9 +345,7 @@ func (p *Peer) handle(msg Msg) error { case msg.Code == discMsg: // This is the last message. We don't need to discard or // check errors because, the connection will be closed after it. - var m struct{ R DiscReason } - rlp.Decode(msg.Payload, &m) - return m.R + return decodeDisconnectMessage(msg.Payload) case msg.Code < baseProtocolLength: // ignore other base protocol messages return msg.Discard() @@ -372,6 +370,27 @@ func (p *Peer) handle(msg Msg) error { return nil } +// decodeDisconnectMessage decodes the payload of discMsg. +func decodeDisconnectMessage(r io.Reader) (reason DiscReason) { + s := rlp.NewStream(r, 100) + k, _, err := s.Kind() + if err != nil { + return DiscInvalid + } + if k == rlp.List { + s.List() + err = s.Decode(&reason) + } else { + // Legacy path: some implementations, including geth, used to send the disconnect + // reason as a byte array by accident. + err = s.Decode(&reason) + } + if err != nil { + reason = DiscInvalid + } + return reason +} + func countMatchingProtocols(protocols []Protocol, caps []Cap) int { n := 0 for _, cap := range caps { diff --git a/p2p/peer_error.go b/p2p/peer_error.go index ebc59de251..dcdadf7fe3 100644 --- a/p2p/peer_error.go +++ b/p2p/peer_error.go @@ -70,6 +70,8 @@ const ( DiscSelf DiscReadTimeout DiscSubprotocolError = DiscReason(0x10) + + DiscInvalid = 0xff ) var discReasonToString = [...]string{ @@ -86,10 +88,11 @@ var discReasonToString = [...]string{ DiscSelf: "connected to self", DiscReadTimeout: "read timeout", DiscSubprotocolError: "subprotocol error", + DiscInvalid: "invalid disconnect reason", } func (d DiscReason) String() string { - if len(discReasonToString) <= int(d) { + if len(discReasonToString) <= int(d) || discReasonToString[d] == "" { return fmt.Sprintf("unknown disconnect reason %d", d) } return discReasonToString[d] diff --git a/p2p/transport.go b/p2p/transport.go index 360e73a0de..87d3013f11 100644 --- a/p2p/transport.go +++ b/p2p/transport.go @@ -113,15 +113,14 @@ func (t *rlpxTransport) close(err error) { // Tell the remote end why we're disconnecting if possible. // We only bother doing this if the underlying connection supports // setting a timeout tough. - if t.conn != nil { - if r, ok := err.(DiscReason); ok && r != DiscNetworkError { - deadline := time.Now().Add(discWriteTimeout) - if err := t.conn.SetWriteDeadline(deadline); err == nil { - // Connection supports write deadline. - t.wbuf.Reset() - rlp.Encode(&t.wbuf, []DiscReason{r}) - t.conn.Write(discMsg, t.wbuf.Bytes()) - } + if reason, ok := err.(DiscReason); ok && reason != DiscNetworkError { + // We do not use the WriteMsg func since we want a custom deadline + deadline := time.Now().Add(discWriteTimeout) + if err := t.conn.SetWriteDeadline(deadline); err == nil { + // Connection supports write deadline. + t.wbuf.Reset() + rlp.Encode(&t.wbuf, []any{reason}) + t.conn.Write(discMsg, t.wbuf.Bytes()) } } t.conn.Close() @@ -163,11 +162,8 @@ func readProtocolHandshake(rw MsgReader) (*protoHandshake, error) { if msg.Code == discMsg { // Disconnect before protocol handshake is valid according to the // spec and we send it ourself if the post-handshake checks fail. - // We can't return the reason directly, though, because it is echoed - // back otherwise. Wrap it in a string instead. - var reason [1]DiscReason - rlp.Decode(msg.Payload, &reason) - return nil, reason[0] + r := decodeDisconnectMessage(msg.Payload) + return nil, r } if msg.Code != handshakeMsg { return nil, fmt.Errorf("expected handshake, got %x", msg.Code) diff --git a/p2p/transport_test.go b/p2p/transport_test.go index 01695cd3af..777be1bd0d 100644 --- a/p2p/transport_test.go +++ b/p2p/transport_test.go @@ -97,7 +97,7 @@ func TestProtocolHandshake(t *testing.T) { return } - if err := ExpectMsg(rlpx, discMsg, []DiscReason{DiscQuitting}); err != nil { + if err := ExpectMsg(rlpx, discMsg, []any{DiscQuitting}); err != nil { t.Errorf("error receiving disconnect: %v", err) } }() @@ -112,7 +112,13 @@ func TestProtocolHandshakeErrors(t *testing.T) { }{ { code: discMsg, - msg: []DiscReason{DiscQuitting}, + msg: []any{DiscQuitting}, + err: DiscQuitting, + }, + { + // legacy disconnect encoding as byte array + code: discMsg, + msg: []byte{byte(DiscQuitting)}, err: DiscQuitting, }, { From 88cbfab332c96edfbe99d161d9df6a40721bd786 Mon Sep 17 00:00:00 2001 From: Antony Denyer Date: Thu, 12 Dec 2024 11:39:03 +0000 Subject: [PATCH 010/940] internal/ethapi: add block override to estimateGas (#30695) Add block overrides to `eth_estimateGas` to align consistency with `eth_call`. https://github.com/ethereum/go-ethereum/issues/27800#issuecomment-1658186166 Fixes https://github.com/ethereum/go-ethereum/issues/28175 --------- Co-authored-by: Sina Mahmoodi --- .gitignore | 1 + eth/gasestimator/gasestimator.go | 13 +- eth/tracers/api.go | 5 +- eth/tracers/api_test.go | 35 +-- graphql/graphql.go | 4 +- internal/ethapi/api.go | 191 +------------ internal/ethapi/api_test.go | 323 +++++++++++----------- internal/ethapi/override/override.go | 195 +++++++++++++ internal/ethapi/override/override_test.go | 125 +++++++++ internal/ethapi/simulate.go | 9 +- internal/ethapi/simulate_test.go | 13 +- internal/ethapi/transaction_args.go | 2 +- internal/web3ext/web3ext.go | 4 +- 13 files changed, 545 insertions(+), 375 deletions(-) create mode 100644 internal/ethapi/override/override.go create mode 100644 internal/ethapi/override/override_test.go diff --git a/.gitignore b/.gitignore index ac0f4efdfb..7000fedd25 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ profile.cov # IdeaIDE .idea +*.iml # VS Code .vscode diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index 9b24bfbf96..a6c4718cf4 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -28,6 +28,7 @@ import ( "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/internal/ethapi/override" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" ) @@ -38,10 +39,11 @@ import ( // these together, it would be excessively hard to test. Splitting the parts out // allows testing without needing a proper live chain. type Options struct { - Config *params.ChainConfig // Chain configuration for hard fork selection - Chain core.ChainContext // Chain context to access past block hashes - Header *types.Header // Header defining the block context to execute in - State *state.StateDB // Pre-state on top of which to estimate the gas + Config *params.ChainConfig // Chain configuration for hard fork selection + Chain core.ChainContext // Chain context to access past block hashes + Header *types.Header // Header defining the block context to execute in + State *state.StateDB // Pre-state on top of which to estimate the gas + BlockOverrides *override.BlockOverrides // Block overrides to apply during the estimation ErrorRatio float64 // Allowed overestimation ratio for faster estimation termination } @@ -220,6 +222,9 @@ func run(ctx context.Context, call *core.Message, opts *Options) (*core.Executio evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil) dirtyState = opts.State.Copy() ) + if opts.BlockOverrides != nil { + opts.BlockOverrides.Apply(&evmContext) + } // Lower the basefee to 0 to avoid breaking EVM // invariants (basefee < feecap). if call.GasPrice.Sign() == 0 { diff --git a/eth/tracers/api.go b/eth/tracers/api.go index c9bf5a4223..22163030de 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -39,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/internal/ethapi/override" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" @@ -163,8 +164,8 @@ type TraceConfig struct { // field to override the state for tracing. type TraceCallConfig struct { TraceConfig - StateOverrides *ethapi.StateOverride - BlockOverrides *ethapi.BlockOverrides + StateOverrides *override.StateOverride + BlockOverrides *override.BlockOverrides TxIndex *hexutil.Uint } diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index e786853ede..13a7b0aaae 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -44,6 +44,7 @@ import ( "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/internal/ethapi/override" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" ) @@ -454,7 +455,7 @@ func TestTraceCall(t *testing.T) { Input: &hexutil.Bytes{0x43}, // blocknumber }, config: &TraceCallConfig{ - BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, + BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, }, expectErr: nil, expect: ` {"gas":53018,"failed":false,"returnValue":"","structLogs":[ @@ -698,8 +699,8 @@ func TestTracingWithOverrides(t *testing.T) { Value: (*hexutil.Big)(big.NewInt(1000)), }, config: &TraceCallConfig{ - StateOverrides: ðapi.StateOverride{ - randomAccounts[0].addr: ethapi.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))}, + StateOverrides: &override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))}, }, }, want: `{"gas":21000,"failed":false,"returnValue":""}`, @@ -740,8 +741,8 @@ func TestTracingWithOverrides(t *testing.T) { }, config: &TraceCallConfig{ //Tracer: &tracer, - StateOverrides: ðapi.StateOverride{ - randomAccounts[2].addr: ethapi.OverrideAccount{ + StateOverrides: &override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{ Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033")), StateDiff: newStates([]common.Hash{{}}, []common.Hash{common.BigToHash(big.NewInt(123))}), }, @@ -757,7 +758,7 @@ func TestTracingWithOverrides(t *testing.T) { Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")), }, config: &TraceCallConfig{ - BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, + BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, }, want: `{"gas":59537,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000001337"}`, }, @@ -777,7 +778,7 @@ func TestTracingWithOverrides(t *testing.T) { }, // blocknumber }, config: &TraceCallConfig{ - BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, + BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, }, want: `{"gas":72666,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}`, }, @@ -807,8 +808,8 @@ func TestTracingWithOverrides(t *testing.T) { Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), // }, config: &TraceCallConfig{ - StateOverrides: ðapi.StateOverride{ - randomAccounts[2].addr: ethapi.OverrideAccount{ + StateOverrides: &override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{ Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060325760003560e01c806366e41cb7146037578063f8a8fd6d14603f575b600080fd5b603d6057565b005b60456062565b60405190815260200160405180910390f35b610539600090815580fd5b60006001600081905550306001600160a01b03166366e41cb76040518163ffffffff1660e01b8152600401600060405180830381600087803b15801560a657600080fd5b505af192505050801560b6575060015b60e9573d80801560e1576040519150601f19603f3d011682016040523d82523d6000602084013e60e6565b606091505b50505b506000549056fea26469706673582212205ce45de745a5308f713cb2f448589177ba5a442d1a2eff945afaa8915961b4d064736f6c634300080c0033")), }, }, @@ -823,8 +824,8 @@ func TestTracingWithOverrides(t *testing.T) { Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), // }, config: &TraceCallConfig{ - StateOverrides: ðapi.StateOverride{ - randomAccounts[2].addr: ethapi.OverrideAccount{ + StateOverrides: &override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{ Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060325760003560e01c806366e41cb7146037578063f8a8fd6d14603f575b600080fd5b603d6057565b005b60456062565b60405190815260200160405180910390f35b610539600090815580fd5b60006001600081905550306001600160a01b03166366e41cb76040518163ffffffff1660e01b8152600401600060405180830381600087803b15801560a657600080fd5b505af192505050801560b6575060015b60e9573d80801560e1576040519150601f19603f3d011682016040523d82523d6000602084013e60e6565b606091505b50505b506000549056fea26469706673582212205ce45de745a5308f713cb2f448589177ba5a442d1a2eff945afaa8915961b4d064736f6c634300080c0033")), State: newStates([]common.Hash{{}}, []common.Hash{{}}), }, @@ -841,8 +842,8 @@ func TestTracingWithOverrides(t *testing.T) { Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), // }, config: &TraceCallConfig{ - StateOverrides: ðapi.StateOverride{ - storageAccount: ethapi.OverrideAccount{ + StateOverrides: &override.StateOverride{ + storageAccount: override.OverrideAccount{ Code: newRPCBytes([]byte{ // SLOAD(3) + SLOAD(4) (which is 0x77) byte(vm.PUSH1), 0x04, @@ -876,8 +877,8 @@ func TestTracingWithOverrides(t *testing.T) { Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), // }, config: &TraceCallConfig{ - StateOverrides: ðapi.StateOverride{ - storageAccount: ethapi.OverrideAccount{ + StateOverrides: &override.StateOverride{ + storageAccount: override.OverrideAccount{ Code: newRPCBytes([]byte{ // SLOAD(3) + SLOAD(4) (which is now 0x11 + 0x00) byte(vm.PUSH1), 0x04, @@ -914,8 +915,8 @@ func TestTracingWithOverrides(t *testing.T) { Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), // }, config: &TraceCallConfig{ - StateOverrides: ðapi.StateOverride{ - storageAccount: ethapi.OverrideAccount{ + StateOverrides: &override.StateOverride{ + storageAccount: override.OverrideAccount{ Code: newRPCBytes([]byte{ // SLOAD(3) + SLOAD(4) (which is now 0x11 + 0x44) byte(vm.PUSH1), 0x04, diff --git a/graphql/graphql.go b/graphql/graphql.go index 57dfd14ecd..6e364de6d9 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -1208,7 +1208,7 @@ func (b *Block) Call(ctx context.Context, args struct { func (b *Block) EstimateGas(ctx context.Context, args struct { Data ethapi.TransactionArgs }) (hexutil.Uint64, error) { - return ethapi.DoEstimateGas(ctx, b.r.backend, args.Data, *b.numberOrHash, nil, b.r.backend.RPCGasCap()) + return ethapi.DoEstimateGas(ctx, b.r.backend, args.Data, *b.numberOrHash, nil, nil, b.r.backend.RPCGasCap()) } type Pending struct { @@ -1272,7 +1272,7 @@ func (p *Pending) EstimateGas(ctx context.Context, args struct { Data ethapi.TransactionArgs }) (hexutil.Uint64, error) { latestBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) - return ethapi.DoEstimateGas(ctx, p.r.backend, args.Data, latestBlockNr, nil, p.r.backend.RPCGasCap()) + return ethapi.DoEstimateGas(ctx, p.r.backend, args.Data, latestBlockNr, nil, nil, p.r.backend.RPCGasCap()) } // Resolver is the top-level object in the GraphQL hierarchy. diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 067d07ba7a..de75c697ef 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -35,19 +35,18 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core" "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/gasestimator" "github.com/ethereum/go-ethereum/eth/tracers/logger" + "github.com/ethereum/go-ethereum/internal/ethapi/override" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" - "github.com/holiman/uint256" ) // estimateGasErrorRatio is the amount of overestimation eth_estimateGas is @@ -621,171 +620,6 @@ func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rp return result, nil } -// OverrideAccount indicates the overriding fields of account during the execution -// 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 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"` - 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(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 { - statedb.SetNonce(addr, uint64(*account.Nonce)) - } - // Override account(contract) code. - if account.Code != nil { - statedb.SetCode(addr, *account.Code) - } - // Override account balance. - if account.Balance != nil { - 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 { - statedb.SetStorage(addr, account.State) - } - // Apply state diff into specified accounts. - if account.StateDiff != nil { - 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. - statedb.Finalise(false) - return nil -} - -// BlockOverrides is a set of header fields to override. -type BlockOverrides struct { - 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 (o *BlockOverrides) Apply(blockCtx *vm.BlockContext) { - if o == nil { - return - } - if o.Number != nil { - blockCtx.BlockNumber = o.Number.ToInt() - } - if o.Difficulty != nil { - blockCtx.Difficulty = o.Difficulty.ToInt() - } - if o.Time != nil { - blockCtx.Time = uint64(*o.Time) - } - if o.GasLimit != nil { - blockCtx.GasLimit = uint64(*o.GasLimit) - } - if o.FeeRecipient != nil { - blockCtx.Coinbase = *o.FeeRecipient - } - if o.PrevRandao != nil { - blockCtx.Random = o.PrevRandao - } - if o.BaseFeePerGas != nil { - blockCtx.BaseFee = o.BaseFeePerGas.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 @@ -818,7 +652,7 @@ func (context *ChainContext) GetHeader(hash common.Hash, number uint64) *types.H return header } -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) { +func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) if blockOverrides != nil { blockOverrides.Apply(&blockCtx) @@ -897,7 +731,7 @@ func applyMessageWithEVM(ctx context.Context, evm *vm.EVM, msg *core.Message, ti return result, nil } -func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { +func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) @@ -913,7 +747,7 @@ 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 (api *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 *override.StateOverride, blockOverrides *override.BlockOverrides) (hexutil.Bytes, error) { if blockNrOrHash == nil { latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) blockNrOrHash = &latest @@ -972,7 +806,7 @@ func (api *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrO // 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 & // non-zero) and `gasCap` (if non-zero). -func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, gasCap uint64) (hexutil.Uint64, error) { +func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, gasCap uint64) (hexutil.Uint64, error) { // Retrieve the base state and mutate it with any overrides state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { @@ -983,11 +817,12 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr } // Construct the gas estimator option from the user input opts := &gasestimator.Options{ - Config: b.ChainConfig(), - Chain: NewChainContext(ctx, b), - Header: header, - State: state, - ErrorRatio: estimateGasErrorRatio, + Config: b.ChainConfig(), + Chain: NewChainContext(ctx, b), + Header: header, + BlockOverrides: blockOverrides, + State: state, + ErrorRatio: estimateGasErrorRatio, } // 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. @@ -1016,12 +851,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 (api *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 *override.StateOverride, blockOverrides *override.BlockOverrides) (hexutil.Uint64, error) { bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) if blockNrOrHash != nil { bNrOrHash = *blockNrOrHash } - return DoEstimateGas(ctx, api.b, args, bNrOrHash, overrides, api.b.RPCGasCap()) + return DoEstimateGas(ctx, api.b, args, bNrOrHash, overrides, blockOverrides, api.b.RPCGasCap()) } // RPCMarshalHeader converts the given header to the RPC output . diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 1f5f2dd1d5..ae2ec9f0f0 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -24,7 +24,6 @@ import ( "encoding/json" "errors" "fmt" - "maps" "math/big" "os" "path/filepath" @@ -34,6 +33,9 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/internal/ethapi/override" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" @@ -55,7 +57,6 @@ 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" ) @@ -640,6 +641,17 @@ func TestEstimateGas(t *testing.T) { signer = types.HomesteadSigner{} randomAccounts = newAccounts(2) ) + packRevert := func(revertMessage string) []byte { + var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4] + stringType, _ := abi.NewType("string", "", nil) + args := abi.Arguments{ + {Type: stringType}, + } + encodedMessage, _ := args.Pack(revertMessage) + + return append(revertSelector, encodedMessage...) + } + api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) { // Transfer from account[0] to account[1] // value: 1000 wei @@ -648,14 +660,16 @@ func TestEstimateGas(t *testing.T) { b.AddTx(tx) b.SetPoS() })) + var testSuite = []struct { - blockNumber rpc.BlockNumber - call TransactionArgs - overrides StateOverride - expectErr error - want uint64 + blockNumber rpc.BlockNumber + call TransactionArgs + overrides override.StateOverride + blockOverrides override.BlockOverrides + expectErr error + want uint64 }{ - // simple transfer on latest block + //simple transfer on latest block { blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ @@ -687,8 +701,8 @@ func TestEstimateGas(t *testing.T) { { blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{}, - overrides: StateOverride{ - randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))}, + overrides: override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))}, }, expectErr: nil, want: 53000, @@ -700,8 +714,8 @@ func TestEstimateGas(t *testing.T) { To: &randomAccounts[1].addr, Value: (*hexutil.Big)(big.NewInt(1000)), }, - overrides: StateOverride{ - randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(0))}, + overrides: override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(0))}, }, expectErr: core.ErrInsufficientFunds, }, @@ -758,16 +772,65 @@ func TestEstimateGas(t *testing.T) { }, want: 21000, }, + // // SPDX-License-Identifier: GPL-3.0 + //pragma solidity >=0.8.2 <0.9.0; + // + //contract BlockOverridesTest { + // function call() public view returns (uint256) { + // return block.number; + // } + // + // function estimate() public view { + // revert(string.concat("block ", uint2str(block.number))); + // } + // + // function uint2str(uint256 _i) internal pure returns (string memory str) { + // if (_i == 0) { + // return "0"; + // } + // uint256 j = _i; + // uint256 length; + // while (j != 0) { + // length++; + // j /= 10; + // } + // bytes memory bstr = new bytes(length); + // uint256 k = length; + // j = _i; + // while (j != 0) { + // bstr[--k] = bytes1(uint8(48 + (j % 10))); + // j /= 10; + // } + // str = string(bstr); + // } + //} + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: &accounts[1].addr, + Data: hex2Bytes("0x3592d016"), //estimate + }, + overrides: override.StateOverride{ + accounts[1].addr: override.OverrideAccount{ + Code: hex2Bytes("608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806328b5e32b146100385780633592d0161461004b575b5f5ffd5b4360405190815260200160405180910390f35b610053610055565b005b61005e4361009d565b60405160200161006e91906101a5565b60408051601f198184030181529082905262461bcd60e51b8252610094916004016101cd565b60405180910390fd5b6060815f036100c35750506040805180820190915260018152600360fc1b602082015290565b815f5b81156100ec57806100d681610216565b91506100e59050600a83610242565b91506100c6565b5f8167ffffffffffffffff81111561010657610106610255565b6040519080825280601f01601f191660200182016040528015610130576020820181803683370190505b508593509050815b831561019c57610149600a85610269565b61015490603061027c565b60f81b8261016183610295565b92508281518110610174576101746102aa565b60200101906001600160f81b03191690815f1a905350610195600a85610242565b9350610138565b50949350505050565b650313637b1b5960d51b81525f82518060208501600685015e5f920160060191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161022757610227610202565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f826102505761025061022e565b500490565b634e487b7160e01b5f52604160045260245ffd5b5f826102775761027761022e565b500690565b8082018082111561028f5761028f610202565b92915050565b5f816102a3576102a3610202565b505f190190565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220a253cad1e2e3523b8c053c1d0cd1e39d7f3bafcedd73440a244872701f05dab264736f6c634300081c0033"), + }, + }, + blockOverrides: override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))}, + expectErr: newRevertError(packRevert("block 11")), + }, } for i, tc := range testSuite { - result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides) + result, err := api.EstimateGas(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) continue } if !errors.Is(err, tc.expectErr) { - t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err) + if !reflect.DeepEqual(err, tc.expectErr) { + t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err) + } } continue } @@ -818,9 +881,9 @@ func TestCall(t *testing.T) { var testSuite = []struct { name string blockNumber rpc.BlockNumber - overrides StateOverride + overrides override.StateOverride call TransactionArgs - blockOverrides BlockOverrides + blockOverrides override.BlockOverrides expectErr error want string }{ @@ -880,8 +943,8 @@ func TestCall(t *testing.T) { To: &randomAccounts[1].addr, Value: (*hexutil.Big)(big.NewInt(1000)), }, - overrides: StateOverride{ - randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))}, + overrides: override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))}, }, want: "0x", }, @@ -920,27 +983,60 @@ func TestCall(t *testing.T) { To: &randomAccounts[2].addr, Data: hex2Bytes("8381f58a"), // call number() }, - overrides: StateOverride{ - randomAccounts[2].addr: OverrideAccount{ + overrides: override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{ Code: hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033"), StateDiff: map[common.Hash]common.Hash{{}: common.BigToHash(big.NewInt(123))}, }, }, want: "0x000000000000000000000000000000000000000000000000000000000000007b", }, - // Block overrides should work + // // SPDX-License-Identifier: GPL-3.0 + //pragma solidity >=0.8.2 <0.9.0; + // + //contract BlockOverridesTest { + // function call() public view returns (uint256) { + // return block.number; + // } + // + // function estimate() public view { + // revert(string.concat("block ", uint2str(block.number))); + // } + // + // function uint2str(uint256 _i) internal pure returns (string memory str) { + // if (_i == 0) { + // return "0"; + // } + // uint256 j = _i; + // uint256 length; + // while (j != 0) { + // length++; + // j /= 10; + // } + // bytes memory bstr = new bytes(length); + // uint256 k = length; + // j = _i; + // while (j != 0) { + // bstr[--k] = bytes1(uint8(48 + (j % 10))); + // j /= 10; + // } + // str = string(bstr); + // } + //} { - name: "block-override", + name: "block-override-with-state-override", blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ From: &accounts[1].addr, - Input: &hexutil.Bytes{ - 0x43, // NUMBER - 0x60, 0x00, 0x52, // MSTORE offset 0 - 0x60, 0x20, 0x60, 0x00, 0xf3, + To: &accounts[2].addr, + Data: hex2Bytes("0x28b5e32b"), //call + }, + overrides: override.StateOverride{ + accounts[2].addr: override.OverrideAccount{ + Code: hex2Bytes("608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806328b5e32b146100385780633592d0161461004b575b5f5ffd5b4360405190815260200160405180910390f35b610053610055565b005b61005e4361009d565b60405160200161006e91906101a5565b60408051601f198184030181529082905262461bcd60e51b8252610094916004016101cd565b60405180910390fd5b6060815f036100c35750506040805180820190915260018152600360fc1b602082015290565b815f5b81156100ec57806100d681610216565b91506100e59050600a83610242565b91506100c6565b5f8167ffffffffffffffff81111561010657610106610255565b6040519080825280601f01601f191660200182016040528015610130576020820181803683370190505b508593509050815b831561019c57610149600a85610269565b61015490603061027c565b60f81b8261016183610295565b92508281518110610174576101746102aa565b60200101906001600160f81b03191690815f1a905350610195600a85610242565b9350610138565b50949350505050565b650313637b1b5960d51b81525f82518060208501600685015e5f920160060191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161022757610227610202565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f826102505761025061022e565b500490565b634e487b7160e01b5f52604160045260245ffd5b5f826102775761027761022e565b500690565b8082018082111561028f5761028f610202565b92915050565b5f816102a3576102a3610202565b505f190190565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220a253cad1e2e3523b8c053c1d0cd1e39d7f3bafcedd73440a244872701f05dab264736f6c634300081c0033"), }, }, - blockOverrides: BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))}, + blockOverrides: override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))}, want: "0x000000000000000000000000000000000000000000000000000000000000000b", }, // Clear storage trie @@ -963,8 +1059,8 @@ func TestCall(t *testing.T) { // } Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"), }, - overrides: StateOverride{ - dad: OverrideAccount{ + overrides: override.StateOverride{ + dad: override.OverrideAccount{ State: map[common.Hash]common.Hash{}, }, }, @@ -991,7 +1087,7 @@ func TestCall(t *testing.T) { BlobHashes: []common.Hash{{0x01, 0x22}}, BlobFeeCap: (*hexutil.Big)(big.NewInt(1)), }, - overrides: StateOverride{ + overrides: override.StateOverride{ randomAccounts[2].addr: { Code: hex2Bytes("60004960005260206000f3"), }, @@ -1017,8 +1113,8 @@ func TestCall(t *testing.T) { // } Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"), }, - overrides: StateOverride{ - dad: OverrideAccount{ + overrides: override.StateOverride{ + dad: override.OverrideAccount{ State: map[common.Hash]common.Hash{}, }, }, @@ -1172,8 +1268,8 @@ func TestSimulateV1(t *testing.T) { name: "simple", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(1000))}, + StateOverrides: &override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(1000))}, }, Calls: []TransactionArgs{{ From: &randomAccounts[0].addr, @@ -1215,8 +1311,8 @@ func TestSimulateV1(t *testing.T) { name: "simple-multi-block", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(2000))}, + StateOverrides: &override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(2000))}, }, Calls: []TransactionArgs{ { @@ -1230,8 +1326,8 @@ func TestSimulateV1(t *testing.T) { }, }, }, { - StateOverrides: &StateOverride{ - randomAccounts[3].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(0))}, + StateOverrides: &override.StateOverride{ + randomAccounts[3].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(0))}, }, Calls: []TransactionArgs{ { @@ -1289,8 +1385,8 @@ func TestSimulateV1(t *testing.T) { name: "evm-error", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - randomAccounts[2].addr: OverrideAccount{Code: hex2Bytes("f3")}, + StateOverrides: &override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{Code: hex2Bytes("f3")}, }, Calls: []TransactionArgs{{ From: &randomAccounts[0].addr, @@ -1316,7 +1412,7 @@ func TestSimulateV1(t *testing.T) { name: "block-overrides", tag: latest, blocks: []simBlock{{ - BlockOverrides: &BlockOverrides{ + BlockOverrides: &override.BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(11)), FeeRecipient: &cac, }, @@ -1331,7 +1427,7 @@ func TestSimulateV1(t *testing.T) { }, }, }, { - BlockOverrides: &BlockOverrides{ + BlockOverrides: &override.BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(12)), }, Calls: []TransactionArgs{{ @@ -1374,7 +1470,7 @@ func TestSimulateV1(t *testing.T) { name: "block-number-order", tag: latest, blocks: []simBlock{{ - BlockOverrides: &BlockOverrides{ + BlockOverrides: &override.BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(12)), }, Calls: []TransactionArgs{{ @@ -1386,7 +1482,7 @@ func TestSimulateV1(t *testing.T) { }, }}, }, { - BlockOverrides: &BlockOverrides{ + BlockOverrides: &override.BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(11)), }, Calls: []TransactionArgs{{ @@ -1406,8 +1502,8 @@ func TestSimulateV1(t *testing.T) { name: "storage-contract", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - randomAccounts[2].addr: OverrideAccount{ + StateOverrides: &override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{ Code: hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033"), }, }, @@ -1448,8 +1544,8 @@ func TestSimulateV1(t *testing.T) { name: "logs", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - randomAccounts[2].addr: OverrideAccount{ + StateOverrides: &override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{ // Yul code: // object "Test" { // code { @@ -1490,8 +1586,8 @@ func TestSimulateV1(t *testing.T) { name: "ecrecover-override", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - randomAccounts[2].addr: OverrideAccount{ + StateOverrides: &override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{ // Yul code that returns ecrecover(0, 0, 0, 0). // object "Test" { // code { @@ -1518,7 +1614,7 @@ func TestSimulateV1(t *testing.T) { // } Code: hex2Bytes("6040516000815260006020820152600060408201526000606082015260208160808360015afa60008103603157600080fd5b601482f3"), }, - common.BytesToAddress([]byte{0x01}): OverrideAccount{ + common.BytesToAddress([]byte{0x01}): override.OverrideAccount{ // Yul code that returns the address of the caller. // object "Test" { // code { @@ -1555,8 +1651,8 @@ func TestSimulateV1(t *testing.T) { name: "precompile-move", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - sha256Address: OverrideAccount{ + StateOverrides: &override.StateOverride{ + sha256Address: override.OverrideAccount{ // Yul code that returns the calldata. // object "Test" { // code { @@ -1610,8 +1706,8 @@ func TestSimulateV1(t *testing.T) { name: "transfer-logs", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - randomAccounts[0].addr: OverrideAccount{ + StateOverrides: &override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{ Balance: newRPCBalance(big.NewInt(100)), // Yul code that transfers 100 wei to address passed in calldata: // object "Test" { @@ -1753,8 +1849,8 @@ func TestSimulateV1(t *testing.T) { name: "validation-checks-from-contract", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ - randomAccounts[2].addr: OverrideAccount{ + StateOverrides: &override.StateOverride{ + randomAccounts[2].addr: override.OverrideAccount{ Balance: newRPCBalance(big.NewInt(2098640803896784)), Code: hex2Bytes("00"), Nonce: newUint64(1), @@ -1788,11 +1884,11 @@ func TestSimulateV1(t *testing.T) { name: "validation-checks-success", tag: latest, blocks: []simBlock{{ - BlockOverrides: &BlockOverrides{ + BlockOverrides: &override.BlockOverrides{ BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)), }, - StateOverrides: &StateOverride{ - randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(10000000))}, + StateOverrides: &override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(10000000))}, }, Calls: []TransactionArgs{{ From: &randomAccounts[0].addr, @@ -1821,7 +1917,7 @@ func TestSimulateV1(t *testing.T) { name: "clear-storage", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ + StateOverrides: &override.StateOverride{ randomAccounts[2].addr: { Code: newBytes(genesis.Alloc[bab].Code), StateDiff: map[common.Hash]common.Hash{ @@ -1843,7 +1939,7 @@ func TestSimulateV1(t *testing.T) { To: &bab, }}, }, { - StateOverrides: &StateOverride{ + StateOverrides: &override.StateOverride{ randomAccounts[2].addr: { State: map[common.Hash]common.Hash{ common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(5)), @@ -1890,10 +1986,10 @@ func TestSimulateV1(t *testing.T) { name: "blockhash-opcode", tag: latest, blocks: []simBlock{{ - BlockOverrides: &BlockOverrides{ + BlockOverrides: &override.BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(12)), }, - StateOverrides: &StateOverride{ + StateOverrides: &override.StateOverride{ randomAccounts[2].addr: { Code: hex2Bytes("600035804060008103601057600080fd5b5050"), }, @@ -1915,7 +2011,7 @@ func TestSimulateV1(t *testing.T) { Input: uint256ToBytes(uint256.NewInt(10)), }}, }, { - BlockOverrides: &BlockOverrides{ + BlockOverrides: &override.BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(16)), }, Calls: []TransactionArgs{{ @@ -2005,7 +2101,7 @@ func TestSimulateV1(t *testing.T) { name: "basefee-non-validation", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ + StateOverrides: &override.StateOverride{ randomAccounts[2].addr: { // Yul code: // object "Test" { @@ -2040,7 +2136,7 @@ func TestSimulateV1(t *testing.T) { }, }, }, { - BlockOverrides: &BlockOverrides{ + BlockOverrides: &override.BlockOverrides{ BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)), }, Calls: []TransactionArgs{{ @@ -2113,7 +2209,7 @@ func TestSimulateV1(t *testing.T) { name: "basefee-validation-mode", tag: latest, blocks: []simBlock{{ - StateOverrides: &StateOverride{ + StateOverrides: &override.StateOverride{ randomAccounts[2].addr: { // Yul code: // object "Test" { @@ -3286,97 +3382,6 @@ func TestRPCGetBlockReceipts(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 testRPCResponseWithFile(t *testing.T, testid int, result interface{}, rpc string, file string) { data, err := json.MarshalIndent(result, "", " ") if err != nil { diff --git a/internal/ethapi/override/override.go b/internal/ethapi/override/override.go new file mode 100644 index 0000000000..70b6210275 --- /dev/null +++ b/internal/ethapi/override/override.go @@ -0,0 +1,195 @@ +// 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 override + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "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/holiman/uint256" +) + +// OverrideAccount indicates the overriding fields of account during the execution +// 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 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"` + 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(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 { + statedb.SetNonce(addr, uint64(*account.Nonce)) + } + // Override account(contract) code. + if account.Code != nil { + statedb.SetCode(addr, *account.Code) + } + // Override account balance. + if account.Balance != nil { + 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 { + statedb.SetStorage(addr, account.State) + } + // Apply state diff into specified accounts. + if account.StateDiff != nil { + 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. + statedb.Finalise(false) + return nil +} + +// BlockOverrides is a set of header fields to override. +type BlockOverrides struct { + 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 (o *BlockOverrides) Apply(blockCtx *vm.BlockContext) { + if o == nil { + return + } + if o.Number != nil { + blockCtx.BlockNumber = o.Number.ToInt() + } + if o.Difficulty != nil { + blockCtx.Difficulty = o.Difficulty.ToInt() + } + if o.Time != nil { + blockCtx.Time = uint64(*o.Time) + } + if o.GasLimit != nil { + blockCtx.GasLimit = uint64(*o.GasLimit) + } + if o.FeeRecipient != nil { + blockCtx.Coinbase = *o.FeeRecipient + } + if o.PrevRandao != nil { + blockCtx.Random = o.PrevRandao + } + if o.BaseFeePerGas != nil { + blockCtx.BaseFee = o.BaseFeePerGas.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 +} diff --git a/internal/ethapi/override/override_test.go b/internal/ethapi/override/override_test.go new file mode 100644 index 0000000000..07ed6442b2 --- /dev/null +++ b/internal/ethapi/override/override_test.go @@ -0,0 +1,125 @@ +// 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 override + +import ( + "maps" + "testing" + + "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/vm" + "github.com/ethereum/go-ethereum/triedb" +) + +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 hex2Bytes(str string) *hexutil.Bytes { + rpcBytes := hexutil.Bytes(common.FromHex(str)) + return &rpcBytes +} diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index f6647c7ba4..5bd0079a93 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -33,6 +33,7 @@ import ( "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/internal/ethapi/override" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" @@ -49,8 +50,8 @@ const ( // simBlock is a batch of calls to be simulated sequentially. type simBlock struct { - BlockOverrides *BlockOverrides - StateOverrides *StateOverride + BlockOverrides *override.BlockOverrides + StateOverrides *override.StateOverride Calls []TransactionArgs } @@ -303,7 +304,7 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) { ) for _, block := range blocks { if block.BlockOverrides == nil { - block.BlockOverrides = new(BlockOverrides) + block.BlockOverrides = new(override.BlockOverrides) } if block.BlockOverrides.Number == nil { n := new(big.Int).Add(prevNumber, big.NewInt(1)) @@ -323,7 +324,7 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) { 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)}} + b := simBlock{BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(n), Time: (*hexutil.Uint64)(&t)}} prevTimestamp = t res = append(res, b) } diff --git a/internal/ethapi/simulate_test.go b/internal/ethapi/simulate_test.go index 37883924ac..52ae40cad0 100644 --- a/internal/ethapi/simulate_test.go +++ b/internal/ethapi/simulate_test.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi/override" ) func TestSimulateSanitizeBlockOrder(t *testing.T) { @@ -45,37 +46,37 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) { { baseNumber: 10, baseTimestamp: 50, - blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(13), Time: newUint64(70)}}, {}}, + blocks: []simBlock{{BlockOverrides: &override.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)}}, {}}, + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11)}}, {BlockOverrides: &override.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)}}}, + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13)}}, {BlockOverrides: &override.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)}}}, + blocks: []simBlock{{BlockOverrides: &override.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)}}}, + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &override.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)}}}, + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(61)}}}, err: "block timestamps must be in order: 61 <= 61", }, } { diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 91e05544dc..2a0508b147 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -160,7 +160,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas BlobHashes: args.BlobHashes, } latestBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) - estimated, err := DoEstimateGas(ctx, b, callArgs, latestBlockNr, nil, b.RPCGasCap()) + estimated, err := DoEstimateGas(ctx, b, callArgs, latestBlockNr, nil, nil, b.RPCGasCap()) if err != nil { return err } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 0c346bbf79..8ac8f44958 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -503,8 +503,8 @@ web3._extend({ new web3._extend.Method({ name: 'estimateGas', call: 'eth_estimateGas', - params: 3, - inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputBlockNumberFormatter, null], + params: 4, + inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputBlockNumberFormatter, null, null], outputFormatter: web3._extend.utils.toDecimal }), new web3._extend.Method({ From 804d45cc2eddd92ee4b9940875e4a6914ec5256f Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 13 Dec 2024 08:46:12 -0300 Subject: [PATCH 011/940] p2p: DNS resolution for static nodes (#30822) Closes #23210 # Context When deploying Geth in Kubernetes with ReplicaSets, we encountered two DNS-related issues affecting node connectivity. First, during startup, Geth tries to resolve DNS names for static nodes too early in the config unmarshaling phase. If peer nodes aren't ready yet (which is common in Kubernetes rolling deployments), this causes an immediate failure: ``` INFO [11-26|10:03:42.816] Starting Geth on Ethereum mainnet... INFO [11-26|10:03:42.817] Bumping default cache on mainnet provided=1024 updated=4096 Fatal: config.toml, line 81: (p2p.Config.StaticNodes) lookup idontexist.geth.node: no such host ``` The second issue comes up when pods get rescheduled to different nodes - their IPs change but peers keep using the initially resolved IP, never updating the DNS mapping. This PR adds proper DNS support for enode:// URLs by deferring resolution to connection time. It also handles DNS failures gracefully instead of failing fatally during startup, making it work better in container environments where IPs are dynamic and peers come and go during rollouts. --------- Co-authored-by: Felix Lange --- p2p/dial.go | 143 ++++++++++++++++++++++++++++++++-------- p2p/dial_test.go | 29 ++++++++ p2p/enode/node.go | 22 +++++++ p2p/enode/node_test.go | 19 ++++++ p2p/enode/urlv4.go | 38 ++++++----- p2p/enode/urlv4_test.go | 23 +++---- p2p/peer_test.go | 30 ++++----- 7 files changed, 228 insertions(+), 76 deletions(-) diff --git a/p2p/dial.go b/p2p/dial.go index 24d4dc2e89..225709427c 100644 --- a/p2p/dial.go +++ b/p2p/dial.go @@ -24,6 +24,7 @@ import ( "fmt" mrand "math/rand" "net" + "net/netip" "sync" "sync/atomic" "time" @@ -31,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common/mclock" "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" ) @@ -77,6 +79,7 @@ var ( errRecentlyDialed = errors.New("recently dialed") errNetRestrict = errors.New("not contained in netrestrict list") errNoPort = errors.New("node does not provide TCP port") + errNoResolvedIP = errors.New("node does not provide a resolved IP") ) // dialer creates outbound connections and submits them into Server. @@ -90,16 +93,17 @@ var ( // to create peer connections to nodes arriving through the iterator. type dialScheduler struct { dialConfig - setupFunc dialSetupFunc - wg sync.WaitGroup - cancel context.CancelFunc - ctx context.Context - nodesIn chan *enode.Node - doneCh chan *dialTask - addStaticCh chan *enode.Node - remStaticCh chan *enode.Node - addPeerCh chan *conn - remPeerCh chan *conn + setupFunc dialSetupFunc + dnsLookupFunc func(ctx context.Context, network string, name string) ([]netip.Addr, error) + wg sync.WaitGroup + cancel context.CancelFunc + ctx context.Context + nodesIn chan *enode.Node + doneCh chan *dialTask + addStaticCh chan *enode.Node + remStaticCh chan *enode.Node + addPeerCh chan *conn + remPeerCh chan *conn // Everything below here belongs to loop and // should only be accessed by code on the loop goroutine. @@ -159,18 +163,19 @@ func (cfg dialConfig) withDefaults() dialConfig { func newDialScheduler(config dialConfig, it enode.Iterator, setupFunc dialSetupFunc) *dialScheduler { cfg := config.withDefaults() d := &dialScheduler{ - dialConfig: cfg, - historyTimer: mclock.NewAlarm(cfg.clock), - setupFunc: setupFunc, - dialing: make(map[enode.ID]*dialTask), - static: make(map[enode.ID]*dialTask), - peers: make(map[enode.ID]struct{}), - doneCh: make(chan *dialTask), - nodesIn: make(chan *enode.Node), - addStaticCh: make(chan *enode.Node), - remStaticCh: make(chan *enode.Node), - addPeerCh: make(chan *conn), - remPeerCh: make(chan *conn), + dialConfig: cfg, + historyTimer: mclock.NewAlarm(cfg.clock), + setupFunc: setupFunc, + dnsLookupFunc: net.DefaultResolver.LookupNetIP, + dialing: make(map[enode.ID]*dialTask), + static: make(map[enode.ID]*dialTask), + peers: make(map[enode.ID]struct{}), + doneCh: make(chan *dialTask), + nodesIn: make(chan *enode.Node), + addStaticCh: make(chan *enode.Node), + remStaticCh: make(chan *enode.Node), + addPeerCh: make(chan *conn), + remPeerCh: make(chan *conn), } d.lastStatsLog = d.clock.Now() d.ctx, d.cancel = context.WithCancel(context.Background()) @@ -274,7 +279,7 @@ loop: case node := <-d.addStaticCh: id := node.ID() _, exists := d.static[id] - d.log.Trace("Adding static node", "id", id, "ip", node.IPAddr(), "added", !exists) + d.log.Trace("Adding static node", "id", id, "endpoint", nodeEndpointForLog(node), "added", !exists) if exists { continue loop } @@ -433,10 +438,68 @@ func (d *dialScheduler) removeFromStaticPool(idx int) { task.staticPoolIndex = -1 } +// dnsResolveHostname updates the given node from its DNS hostname. +// This is used to resolve static dial targets. +func (d *dialScheduler) dnsResolveHostname(n *enode.Node) (*enode.Node, error) { + if n.Hostname() == "" { + return n, nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + foundIPs, err := d.dnsLookupFunc(ctx, "ip", n.Hostname()) + if err != nil { + return n, err + } + + // Check for IP updates. + var ( + nodeIP4, nodeIP6 netip.Addr + foundIP4, foundIP6 netip.Addr + ) + n.Load((*enr.IPv4Addr)(&nodeIP4)) + n.Load((*enr.IPv6Addr)(&nodeIP6)) + for _, ip := range foundIPs { + if ip.Is4() && !foundIP4.IsValid() { + foundIP4 = ip + } + if ip.Is6() && !foundIP6.IsValid() { + foundIP6 = ip + } + } + + if !foundIP4.IsValid() && !foundIP6.IsValid() { + // Lookup failed. + return n, errNoResolvedIP + } + if foundIP4 == nodeIP4 && foundIP6 == nodeIP6 { + // No updates necessary. + d.log.Trace("Node DNS lookup had no update", "id", n.ID(), "name", n.Hostname(), "ip", foundIP4, "ip6", foundIP6) + return n, nil + } + + // Update the node. Note this invalidates the ENR signature, because we use SignNull + // to create a modified copy. But this should be OK, since we just use the node as a + // dial target. And nodes will usually only have a DNS hostname if they came from a + // enode:// URL, which has no signature anyway. If it ever becomes a problem, the + // resolved IP could also be stored into dialTask instead of the node. + rec := n.Record() + if foundIP4.IsValid() { + rec.Set(enr.IPv4Addr(foundIP4)) + } + if foundIP6.IsValid() { + rec.Set(enr.IPv6Addr(foundIP6)) + } + rec.SetSeq(n.Seq()) // ensure seq not bumped by update + newNode := enode.SignNull(rec, n.ID()).WithHostname(n.Hostname()) + d.log.Debug("Node updated from DNS lookup", "id", n.ID(), "name", n.Hostname(), "ip", newNode.IP()) + return newNode, nil +} + // startDial runs the given dial task in a separate goroutine. func (d *dialScheduler) startDial(task *dialTask) { node := task.dest() - d.log.Trace("Starting p2p dial", "id", node.ID(), "ip", node.IPAddr(), "flag", task.flags) + d.log.Trace("Starting p2p dial", "id", node.ID(), "endpoint", nodeEndpointForLog(node), "flag", task.flags) hkey := string(node.ID().Bytes()) d.history.add(hkey, d.clock.Now().Add(dialHistoryExpiration)) d.dialing[node.ID()] = task @@ -473,14 +536,29 @@ func (t *dialTask) dest() *enode.Node { } func (t *dialTask) run(d *dialScheduler) { - if t.needResolve() && !t.resolve(d) { - return + if t.isStatic() { + // Resolve DNS. + if n := t.dest(); n.Hostname() != "" { + resolved, err := d.dnsResolveHostname(n) + if err != nil { + d.log.Warn("DNS lookup of static node failed", "id", n.ID(), "name", n.Hostname(), "err", err) + } else { + t.destPtr.Store(resolved) + } + } + // Try resolving node ID through the DHT if there is no IP address. + if !t.dest().IPAddr().IsValid() { + if !t.resolve(d) { + return // DHT resolve failed, skip dial. + } + } } 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 { + var dialErr *dialError + if errors.As(err, &dialErr) && t.isStatic() { if t.resolve(d) { t.dial(d, t.dest()) } @@ -488,8 +566,8 @@ func (t *dialTask) run(d *dialScheduler) { } } -func (t *dialTask) needResolve() bool { - return t.flags&staticDialedConn != 0 && !t.dest().IPAddr().IsValid() +func (t *dialTask) isStatic() bool { + return t.flags&staticDialedConn != 0 } // resolve attempts to find the current endpoint for the destination @@ -553,3 +631,10 @@ func cleanupDialErr(err error) error { } return err } + +func nodeEndpointForLog(n *enode.Node) string { + if n.Hostname() != "" { + return n.Hostname() + } + return n.IPAddr().String() +} diff --git a/p2p/dial_test.go b/p2p/dial_test.go index 13908f11ea..f18dacce2a 100644 --- a/p2p/dial_test.go +++ b/p2p/dial_test.go @@ -22,6 +22,7 @@ import ( "fmt" "math/rand" "net" + "net/netip" "reflect" "sync" "testing" @@ -394,6 +395,34 @@ func TestDialSchedResolve(t *testing.T) { }) } +func TestDialSchedDNSHostname(t *testing.T) { + t.Parallel() + + config := dialConfig{ + maxActiveDials: 1, + maxDialPeers: 1, + } + node := newNode(uintID(0x01), ":30303").WithHostname("node-hostname") + resolved := newNode(uintID(0x01), "1.2.3.4:30303").WithHostname("node-hostname") + runDialTest(t, config, []dialTestRound{ + { + update: func(d *dialScheduler) { + d.dnsLookupFunc = func(ctx context.Context, network string, name string) ([]netip.Addr, error) { + if name != "node-hostname" { + t.Error("wrong hostname in DNS lookup:", name) + } + result := []netip.Addr{netip.MustParseAddr("1.2.3.4")} + return result, nil + } + d.addStatic(node) + }, + wantNewDials: []*enode.Node{ + resolved, + }, + }, + }) +} + // ------- // Code below here is the framework for the tests above. diff --git a/p2p/enode/node.go b/p2p/enode/node.go index 4d93d3f6be..d6f2ac7ff5 100644 --- a/p2p/enode/node.go +++ b/p2p/enode/node.go @@ -37,6 +37,10 @@ var errMissingPrefix = errors.New("missing 'enr:' prefix for base64-encoded reco type Node struct { r enr.Record id ID + + // hostname tracks the DNS name of the node. + hostname string + // endpoint information ip netip.Addr udp uint16 @@ -77,6 +81,8 @@ func newNodeWithID(r *enr.Record, id ID) *Node { n.setIP4(ip4) case valid6: n.setIP6(ip6) + default: + n.setIPv4Ports() } return n } @@ -103,6 +109,10 @@ func localityScore(ip netip.Addr) int { func (n *Node) setIP4(ip netip.Addr) { n.ip = ip + n.setIPv4Ports() +} + +func (n *Node) setIPv4Ports() { n.Load((*enr.UDP)(&n.udp)) n.Load((*enr.TCP)(&n.tcp)) } @@ -184,6 +194,18 @@ func (n *Node) TCP() int { return int(n.tcp) } +// WithHostname adds a DNS hostname to the node. +func (n *Node) WithHostname(hostname string) *Node { + cpy := *n + cpy.hostname = hostname + return &cpy +} + +// Hostname returns the DNS name assigned by WithHostname. +func (n *Node) Hostname() string { + return n.hostname +} + // UDPEndpoint returns the announced UDP endpoint. func (n *Node) UDPEndpoint() (netip.AddrPort, bool) { if !n.ip.IsValid() || n.ip.IsUnspecified() || n.udp == 0 { diff --git a/p2p/enode/node_test.go b/p2p/enode/node_test.go index f38c77415e..e9fe631f34 100644 --- a/p2p/enode/node_test.go +++ b/p2p/enode/node_test.go @@ -74,6 +74,7 @@ func TestNodeEndpoints(t *testing.T) { wantUDP int wantTCP int wantQUIC int + wantDNS string } tests := []endpointTest{ { @@ -90,6 +91,7 @@ func TestNodeEndpoints(t *testing.T) { r.Set(enr.UDP(9000)) return SignNull(&r, id) }(), + wantUDP: 9000, }, { name: "tcp-only", @@ -98,6 +100,7 @@ func TestNodeEndpoints(t *testing.T) { r.Set(enr.TCP(9000)) return SignNull(&r, id) }(), + wantTCP: 9000, }, { name: "quic-only", @@ -268,6 +271,19 @@ func TestNodeEndpoints(t *testing.T) { wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), wantQUIC: 9001, }, + { + name: "dns-only", + node: func() *Node { + var r enr.Record + r.Set(enr.UDP(30303)) + r.Set(enr.TCP(30303)) + n := SignNull(&r, id).WithHostname("example.com") + return n + }(), + wantTCP: 30303, + wantUDP: 30303, + wantDNS: "example.com", + }, } for _, test := range tests { @@ -284,6 +300,9 @@ func TestNodeEndpoints(t *testing.T) { if quic, _ := test.node.QUICEndpoint(); test.wantQUIC != int(quic.Port()) { t.Errorf("node has wrong QUIC port %d, want %d", quic.Port(), test.wantQUIC) } + if test.wantDNS != test.node.Hostname() { + t.Errorf("node has wrong DNS name %s, want %s", test.node.Hostname(), test.wantDNS) + } }) } } diff --git a/p2p/enode/urlv4.go b/p2p/enode/urlv4.go index a55dfa6632..b455cd4533 100644 --- a/p2p/enode/urlv4.go +++ b/p2p/enode/urlv4.go @@ -33,7 +33,6 @@ import ( var ( incompleteNodeURL = regexp.MustCompile("(?i)^(?:enode://)?([0-9a-f]+)$") - lookupIPFunc = net.LookupIP ) // MustParseV4 parses a node URL. It panics if the URL is not valid. @@ -126,20 +125,9 @@ func parseComplete(rawurl string) (*Node, error) { if id, err = parsePubkey(u.User.String()); err != nil { return nil, fmt.Errorf("invalid public key (%v)", err) } - // Parse the IP address. + + // Parse the IP and ports. ip := net.ParseIP(u.Hostname()) - if ip == nil { - ips, err := lookupIPFunc(u.Hostname()) - if err != nil { - return nil, err - } - ip = ips[0] - } - // Ensure the IP is 4 bytes long for IPv4 addresses. - if ipv4 := ip.To4(); ipv4 != nil { - ip = ipv4 - } - // Parse the port numbers. if tcpPort, err = strconv.ParseUint(u.Port(), 10, 16); err != nil { return nil, errors.New("invalid port") } @@ -151,7 +139,13 @@ func parseComplete(rawurl string) (*Node, error) { return nil, errors.New("invalid discport in query") } } - return NewV4(id, ip, int(tcpPort), int(udpPort)), nil + + // Create the node. + node := NewV4(id, ip, int(tcpPort), int(udpPort)) + if ip == nil && u.Hostname() != "" { + node = node.WithHostname(u.Hostname()) + } + return node, nil } // parsePubkey parses a hex-encoded secp256k1 public key. @@ -181,15 +175,23 @@ func (n *Node) URLv4() string { nodeid = fmt.Sprintf("%s.%x", scheme, n.id[:]) } u := url.URL{Scheme: "enode"} - if !n.ip.IsValid() { - u.Host = nodeid - } else { + if n.Hostname() != "" { + // For nodes with a DNS name: include DNS name, TCP port, and optional UDP port + u.User = url.User(nodeid) + u.Host = fmt.Sprintf("%s:%d", n.Hostname(), n.TCP()) + if n.UDP() != n.TCP() { + u.RawQuery = "discport=" + strconv.Itoa(n.UDP()) + } + } else if n.ip.IsValid() { + // For IP-based nodes: include IP address, TCP port, and optional UDP port addr := net.TCPAddr{IP: n.IP(), Port: n.TCP()} u.User = url.User(nodeid) u.Host = addr.String() if n.UDP() != n.TCP() { u.RawQuery = "discport=" + strconv.Itoa(n.UDP()) } + } else { + u.Host = nodeid } return u.String() } diff --git a/p2p/enode/urlv4_test.go b/p2p/enode/urlv4_test.go index 33de96cc57..f39d5a2deb 100644 --- a/p2p/enode/urlv4_test.go +++ b/p2p/enode/urlv4_test.go @@ -18,7 +18,6 @@ package enode import ( "crypto/ecdsa" - "errors" "net" "reflect" "strings" @@ -28,15 +27,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" ) -func init() { - lookupIPFunc = func(name string) ([]net.IP, error) { - if name == "node.example.org" { - return []net.IP{{33, 44, 55, 66}}, nil - } - return nil, errors.New("no such host") - } -} - var parseNodeTests = []struct { input string wantError string @@ -70,10 +60,6 @@ var parseNodeTests = []struct { wantError: enr.ErrInvalidSig.Error(), }, // Complete node URLs with IP address and ports - { - input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@invalid.:3", - wantError: `no such host`, - }, { input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo", wantError: `invalid port`, @@ -91,6 +77,15 @@ var parseNodeTests = []struct { 52150, ), }, + { + input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@valid.:3", + wantResult: NewV4( + hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), + nil, + 3, + 3, + ).WithHostname("valid."), + }, { input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150", wantResult: NewV4( diff --git a/p2p/peer_test.go b/p2p/peer_test.go index 4308bbd2eb..dea72875fe 100644 --- a/p2p/peer_test.go +++ b/p2p/peer_test.go @@ -60,22 +60,22 @@ func uintID(i uint16) enode.ID { // newNode creates a node record with the given address. func newNode(id enode.ID, addr string) *enode.Node { var r enr.Record - if addr != "" { - // Set the port if present. - if strings.Contains(addr, ":") { - hs, ps, err := net.SplitHostPort(addr) - if err != nil { - panic(fmt.Errorf("invalid address %q", addr)) - } - port, err := strconv.Atoi(ps) - if err != nil { - panic(fmt.Errorf("invalid port in %q", addr)) - } - r.Set(enr.TCP(port)) - r.Set(enr.UDP(port)) - addr = hs + // Set the port if present. + if strings.Contains(addr, ":") { + hs, ps, err := net.SplitHostPort(addr) + if err != nil { + panic(fmt.Errorf("invalid address %q", addr)) } - // Set the IP. + port, err := strconv.Atoi(ps) + if err != nil { + panic(fmt.Errorf("invalid port in %q", addr)) + } + r.Set(enr.TCP(port)) + r.Set(enr.UDP(port)) + addr = hs + } + // Set the IP. + if addr != "" { ip := net.ParseIP(addr) if ip == nil { panic(fmt.Errorf("invalid IP %q", addr)) From f808d7357ed4076b224a8c6fe47893ce022f9409 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Mon, 16 Dec 2024 03:29:37 -0700 Subject: [PATCH 012/940] all: implement eip-7702 set code tx (#30078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR implements EIP-7702: "Set EOA account code". Specification: https://eips.ethereum.org/EIPS/eip-7702 > Add a new transaction type that adds a list of `[chain_id, address, nonce, y_parity, r, s]` authorization tuples. For each tuple, write a delegation designator `(0xef0100 ++ address)` to the signing account’s code. All code reading operations must load the code pointed to by the designator. --------- Co-authored-by: Mario Vega Co-authored-by: Martin Holst Swende Co-authored-by: Felix Lange --- accounts/external/backend.go | 2 +- cmd/evm/eofparse.go | 2 +- cmd/evm/eofparse_test.go | 2 +- cmd/evm/internal/t8ntool/execution.go | 4 +- cmd/evm/internal/t8ntool/gen_execresult.go | 4 +- cmd/evm/internal/t8ntool/transaction.go | 2 +- cmd/evm/t8n_test.go | 8 + cmd/evm/testdata/1/exp.json | 3 +- cmd/evm/testdata/13/exp2.json | 3 +- cmd/evm/testdata/14/exp.json | 3 +- cmd/evm/testdata/14/exp2.json | 3 +- cmd/evm/testdata/14/exp_berlin.json | 3 +- cmd/evm/testdata/19/exp_arrowglacier.json | 3 +- cmd/evm/testdata/19/exp_grayglacier.json | 25 +- cmd/evm/testdata/19/exp_london.json | 3 +- cmd/evm/testdata/23/exp.json | 3 +- cmd/evm/testdata/24/exp.json | 3 +- cmd/evm/testdata/25/exp.json | 3 +- cmd/evm/testdata/26/exp.json | 3 +- cmd/evm/testdata/28/exp.json | 3 +- cmd/evm/testdata/29/exp.json | 3 +- cmd/evm/testdata/3/exp.json | 3 +- cmd/evm/testdata/30/exp.json | 5 +- cmd/evm/testdata/33/README.md | 1 + cmd/evm/testdata/33/alloc.json | 30 +++ cmd/evm/testdata/33/env.json | 14 ++ cmd/evm/testdata/33/exp.json | 62 +++++ cmd/evm/testdata/33/txs.json | 37 +++ cmd/evm/testdata/5/exp.json | 3 +- core/bench_test.go | 2 +- core/blockchain_test.go | 94 ++++++++ core/error.go | 18 ++ core/state/journal.go | 19 +- core/state/state_object.go | 7 +- core/state/statedb.go | 5 +- core/state/statedb_hooked.go | 11 +- core/state_processor_test.go | 25 +- core/state_transition.go | 107 ++++++++- core/txpool/validation.go | 2 +- core/types/gen_authorization.go | 75 ++++++ core/types/receipt.go | 4 +- core/types/transaction.go | 12 + core/types/transaction_marshalling.go | 92 +++++++ core/types/transaction_signing.go | 77 +++++- core/types/tx_setcode.go | 226 ++++++++++++++++++ core/types/tx_setcode_test.go | 70 ++++++ core/verkle_witness_test.go | 4 +- core/vm/eips.go | 68 ++++++ core/vm/eof_validation_test.go | 16 +- core/vm/evm.go | 39 ++- core/vm/interface.go | 4 +- core/vm/interpreter.go | 2 + core/vm/jump_table.go | 17 +- core/vm/operations_acl.go | 68 ++++++ core/vm/runtime/runtime_test.go | 80 +++++++ .../testdata/prestate_tracer/setcode_tx.json | 82 +++++++ eth/tracers/native/prestate.go | 9 + graphql/graphql.go | 4 +- internal/ethapi/api.go | 61 +++-- internal/ethapi/api_test.go | 23 +- internal/ethapi/transaction_args.go | 27 +++ params/protocol_params.go | 9 +- tests/gen_stauthorization.go | 74 ++++++ tests/gen_sttransaction.go | 6 + tests/state_test_util.go | 37 +++ tests/transaction_test_util.go | 2 +- 66 files changed, 1606 insertions(+), 115 deletions(-) create mode 100644 cmd/evm/testdata/33/README.md create mode 100644 cmd/evm/testdata/33/alloc.json create mode 100644 cmd/evm/testdata/33/env.json create mode 100644 cmd/evm/testdata/33/exp.json create mode 100644 cmd/evm/testdata/33/txs.json create mode 100644 core/types/gen_authorization.go create mode 100644 core/types/tx_setcode.go create mode 100644 core/types/tx_setcode_test.go create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json create mode 100644 tests/gen_stauthorization.go diff --git a/accounts/external/backend.go b/accounts/external/backend.go index 62322753da..42eaf661cc 100644 --- a/accounts/external/backend.go +++ b/accounts/external/backend.go @@ -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, types.BlobTxType: + case types.DynamicFeeTxType, types.BlobTxType, types.SetCodeTxType: args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap()) args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap()) default: diff --git a/cmd/evm/eofparse.go b/cmd/evm/eofparse.go index df8581146a..92182a53b3 100644 --- a/cmd/evm/eofparse.go +++ b/cmd/evm/eofparse.go @@ -36,7 +36,7 @@ var jt vm.JumpTable const initcode = "INITCODE" func init() { - jt = vm.NewPragueEOFInstructionSetForTesting() + jt = vm.NewEOFInstructionSetForTesting() } var ( diff --git a/cmd/evm/eofparse_test.go b/cmd/evm/eofparse_test.go index 9b17039f5b..cda4b38fc9 100644 --- a/cmd/evm/eofparse_test.go +++ b/cmd/evm/eofparse_test.go @@ -43,7 +43,7 @@ func FuzzEofParsing(f *testing.F) { // And do the fuzzing f.Fuzz(func(t *testing.T, data []byte) { var ( - jt = vm.NewPragueEOFInstructionSetForTesting() + jt = vm.NewEOFInstructionSetForTesting() c vm.Container ) cpy := common.CopyBytes(data) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 7a0de86a11..aef497885e 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -70,11 +70,11 @@ type ExecutionResult struct { CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"` CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"` RequestsHash *common.Hash `json:"requestsHash,omitempty"` - Requests [][]byte `json:"requests,omitempty"` + Requests [][]byte `json:"requests"` } type executionResultMarshaling struct { - Requests []hexutil.Bytes `json:"requests,omitempty"` + Requests []hexutil.Bytes `json:"requests"` } type ommer struct { diff --git a/cmd/evm/internal/t8ntool/gen_execresult.go b/cmd/evm/internal/t8ntool/gen_execresult.go index 0da94f5ca2..38310b9f2b 100644 --- a/cmd/evm/internal/t8ntool/gen_execresult.go +++ b/cmd/evm/internal/t8ntool/gen_execresult.go @@ -31,7 +31,7 @@ func (e ExecutionResult) MarshalJSON() ([]byte, error) { CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"` CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"` RequestsHash *common.Hash `json:"requestsHash,omitempty"` - Requests []hexutil.Bytes `json:"requests,omitempty"` + Requests []hexutil.Bytes `json:"requests"` } var enc ExecutionResult enc.StateRoot = e.StateRoot @@ -74,7 +74,7 @@ func (e *ExecutionResult) UnmarshalJSON(input []byte) error { CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"` CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"` RequestsHash *common.Hash `json:"requestsHash,omitempty"` - Requests []hexutil.Bytes `json:"requests,omitempty"` + Requests []hexutil.Bytes `json:"requests"` } var dec ExecutionResult if err := json.Unmarshal(input, &dec); err != nil { diff --git a/cmd/evm/internal/t8ntool/transaction.go b/cmd/evm/internal/t8ntool/transaction.go index 7f66ba4d85..64e21b24fd 100644 --- a/cmd/evm/internal/t8ntool/transaction.go +++ b/cmd/evm/internal/t8ntool/transaction.go @@ -133,7 +133,7 @@ func Transaction(ctx *cli.Context) error { r.Address = sender } // Check intrinsic gas - if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, + if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.AuthList(), tx.To() == nil, chainConfig.IsHomestead(new(big.Int)), chainConfig.IsIstanbul(new(big.Int)), chainConfig.IsShanghai(new(big.Int), 0)); err != nil { r.Error = err results = append(results, r) diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index 85caf010b3..27c6c43164 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -287,6 +287,14 @@ func TestT8n(t *testing.T) { output: t8nOutput{alloc: true, result: true}, expOut: "exp.json", }, + { // Prague test, EIP-7702 transaction + base: "./testdata/33", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "Prague", "", + }, + output: t8nOutput{alloc: true, result: true}, + expOut: "exp.json", + }, } { args := []string{"t8n"} args = append(args, tc.output.get()...) diff --git a/cmd/evm/testdata/1/exp.json b/cmd/evm/testdata/1/exp.json index d1351e5b76..50662f35ea 100644 --- a/cmd/evm/testdata/1/exp.json +++ b/cmd/evm/testdata/1/exp.json @@ -40,6 +40,7 @@ } ], "currentDifficulty": "0x20000", - "gasUsed": "0x5208" + "gasUsed": "0x5208", + "requests": null } } diff --git a/cmd/evm/testdata/13/exp2.json b/cmd/evm/testdata/13/exp2.json index babce35929..6415a4f1f4 100644 --- a/cmd/evm/testdata/13/exp2.json +++ b/cmd/evm/testdata/13/exp2.json @@ -37,6 +37,7 @@ ], "currentDifficulty": "0x20000", "gasUsed": "0x109a0", - "currentBaseFee": "0x36b" + "currentBaseFee": "0x36b", + "requests": null } } diff --git a/cmd/evm/testdata/14/exp.json b/cmd/evm/testdata/14/exp.json index 26d49173ce..300217ee34 100644 --- a/cmd/evm/testdata/14/exp.json +++ b/cmd/evm/testdata/14/exp.json @@ -8,6 +8,7 @@ "currentDifficulty": "0x2000020000000", "receipts": [], "gasUsed": "0x0", - "currentBaseFee": "0x500" + "currentBaseFee": "0x500", + "requests": null } } diff --git a/cmd/evm/testdata/14/exp2.json b/cmd/evm/testdata/14/exp2.json index cd75b47d5a..6d139e371d 100644 --- a/cmd/evm/testdata/14/exp2.json +++ b/cmd/evm/testdata/14/exp2.json @@ -8,6 +8,7 @@ "receipts": [], "currentDifficulty": "0x1ff8020000000", "gasUsed": "0x0", - "currentBaseFee": "0x500" + "currentBaseFee": "0x500", + "requests": null } } diff --git a/cmd/evm/testdata/14/exp_berlin.json b/cmd/evm/testdata/14/exp_berlin.json index 5c00ef130a..c952d0f517 100644 --- a/cmd/evm/testdata/14/exp_berlin.json +++ b/cmd/evm/testdata/14/exp_berlin.json @@ -8,6 +8,7 @@ "receipts": [], "currentDifficulty": "0x1ff9000000000", "gasUsed": "0x0", - "currentBaseFee": "0x500" + "currentBaseFee": "0x500", + "requests": null } } diff --git a/cmd/evm/testdata/19/exp_arrowglacier.json b/cmd/evm/testdata/19/exp_arrowglacier.json index dd49f7d02e..0822fcc290 100644 --- a/cmd/evm/testdata/19/exp_arrowglacier.json +++ b/cmd/evm/testdata/19/exp_arrowglacier.json @@ -8,6 +8,7 @@ "currentDifficulty": "0x2000000200000", "receipts": [], "gasUsed": "0x0", - "currentBaseFee": "0x500" + "currentBaseFee": "0x500", + "requests": null } } diff --git a/cmd/evm/testdata/19/exp_grayglacier.json b/cmd/evm/testdata/19/exp_grayglacier.json index 86fd8e6c13..e80c9eb000 100644 --- a/cmd/evm/testdata/19/exp_grayglacier.json +++ b/cmd/evm/testdata/19/exp_grayglacier.json @@ -1,13 +1,14 @@ { - "result": { - "stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc", - "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "receipts": [], - "currentDifficulty": "0x2000000004000", - "gasUsed": "0x0", - "currentBaseFee": "0x500" - } -} \ No newline at end of file + "result": { + "stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc", + "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": [], + "currentDifficulty": "0x2000000004000", + "gasUsed": "0x0", + "currentBaseFee": "0x500", + "requests": null + } +} diff --git a/cmd/evm/testdata/19/exp_london.json b/cmd/evm/testdata/19/exp_london.json index 9e9a17da90..a17f684484 100644 --- a/cmd/evm/testdata/19/exp_london.json +++ b/cmd/evm/testdata/19/exp_london.json @@ -8,6 +8,7 @@ "currentDifficulty": "0x2000080000000", "receipts": [], "gasUsed": "0x0", - "currentBaseFee": "0x500" + "currentBaseFee": "0x500", + "requests": null } } diff --git a/cmd/evm/testdata/23/exp.json b/cmd/evm/testdata/23/exp.json index 22dde0a27c..7f36165e35 100644 --- a/cmd/evm/testdata/23/exp.json +++ b/cmd/evm/testdata/23/exp.json @@ -21,6 +21,7 @@ } ], "currentDifficulty": "0x20000", - "gasUsed": "0x520b" + "gasUsed": "0x520b", + "requests": null } } diff --git a/cmd/evm/testdata/24/exp.json b/cmd/evm/testdata/24/exp.json index ac571d149b..8f380c662b 100644 --- a/cmd/evm/testdata/24/exp.json +++ b/cmd/evm/testdata/24/exp.json @@ -51,6 +51,7 @@ ], "currentDifficulty": null, "gasUsed": "0x10306", - "currentBaseFee": "0x500" + "currentBaseFee": "0x500", + "requests": null } } diff --git a/cmd/evm/testdata/25/exp.json b/cmd/evm/testdata/25/exp.json index 1cb521794c..a674633762 100644 --- a/cmd/evm/testdata/25/exp.json +++ b/cmd/evm/testdata/25/exp.json @@ -34,6 +34,7 @@ ], "currentDifficulty": null, "gasUsed": "0x5208", - "currentBaseFee": "0x460" + "currentBaseFee": "0x460", + "requests": null } } diff --git a/cmd/evm/testdata/26/exp.json b/cmd/evm/testdata/26/exp.json index 4815e5cb65..d6275270f0 100644 --- a/cmd/evm/testdata/26/exp.json +++ b/cmd/evm/testdata/26/exp.json @@ -15,6 +15,7 @@ "currentDifficulty": null, "gasUsed": "0x0", "currentBaseFee": "0x500", - "withdrawalsRoot": "0x4921c0162c359755b2ae714a0978a1dad2eb8edce7ff9b38b9b6fc4cbc547eb5" + "withdrawalsRoot": "0x4921c0162c359755b2ae714a0978a1dad2eb8edce7ff9b38b9b6fc4cbc547eb5", + "requests": null } } diff --git a/cmd/evm/testdata/28/exp.json b/cmd/evm/testdata/28/exp.json index 75c715e972..b86c2d8def 100644 --- a/cmd/evm/testdata/28/exp.json +++ b/cmd/evm/testdata/28/exp.json @@ -42,6 +42,7 @@ "currentBaseFee": "0x9", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "currentExcessBlobGas": "0x0", - "blobGasUsed": "0x20000" + "blobGasUsed": "0x20000", + "requests": null } } diff --git a/cmd/evm/testdata/29/exp.json b/cmd/evm/testdata/29/exp.json index c4c001ec14..7fbdc18283 100644 --- a/cmd/evm/testdata/29/exp.json +++ b/cmd/evm/testdata/29/exp.json @@ -40,6 +40,7 @@ "currentBaseFee": "0x9", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "currentExcessBlobGas": "0x0", - "blobGasUsed": "0x0" + "blobGasUsed": "0x0", + "requests": null } } diff --git a/cmd/evm/testdata/3/exp.json b/cmd/evm/testdata/3/exp.json index 7230dca2cf..831c078591 100644 --- a/cmd/evm/testdata/3/exp.json +++ b/cmd/evm/testdata/3/exp.json @@ -34,6 +34,7 @@ } ], "currentDifficulty": "0x20000", - "gasUsed": "0x521f" + "gasUsed": "0x521f", + "requests": null } } diff --git a/cmd/evm/testdata/30/exp.json b/cmd/evm/testdata/30/exp.json index f0b19c6b3d..a206c3bbdf 100644 --- a/cmd/evm/testdata/30/exp.json +++ b/cmd/evm/testdata/30/exp.json @@ -59,6 +59,7 @@ "currentBaseFee": "0x7", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "currentExcessBlobGas": "0x0", - "blobGasUsed": "0x0" + "blobGasUsed": "0x0", + "requests": null } -} \ No newline at end of file +} diff --git a/cmd/evm/testdata/33/README.md b/cmd/evm/testdata/33/README.md new file mode 100644 index 0000000000..24bea566e5 --- /dev/null +++ b/cmd/evm/testdata/33/README.md @@ -0,0 +1 @@ +This test sets some EIP-7702 delegations and calls them. diff --git a/cmd/evm/testdata/33/alloc.json b/cmd/evm/testdata/33/alloc.json new file mode 100644 index 0000000000..6874a6b339 --- /dev/null +++ b/cmd/evm/testdata/33/alloc.json @@ -0,0 +1,30 @@ +{ + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "nonce": "0x00", + "balance": "0x0de0b6b3a7640000", + "code": "0x600060006000600060007310000000000000000000000000000000000000015af1600155600060006000600060007310000000000000000000000000000000000000025af16002553d600060003e600051600355", + "storage": { + "0x01": "0x0100", + "0x02": "0x0100", + "0x03": "0x0100" + } + }, + "0x000000000000000000000000000000000000aaaa": { + "nonce": "0x00", + "balance": "0x4563918244f40000", + "code": "0x58808080600173703c4b2bd70c169f5717101caee543299fc946c75af100", + "storage": {} + }, + "0x000000000000000000000000000000000000bbbb": { + "nonce": "0x00", + "balance": "0x29a2241af62c0000", + "code": "0x6042805500", + "storage": {} + }, + "0x71562b71999873DB5b286dF957af199Ec94617F7": { + "nonce": "0x00", + "balance": "0x6124fee993bc0000", + "code": "0x", + "storage": {} + } +} diff --git a/cmd/evm/testdata/33/env.json b/cmd/evm/testdata/33/env.json new file mode 100644 index 0000000000..70bb7f9812 --- /dev/null +++ b/cmd/evm/testdata/33/env.json @@ -0,0 +1,14 @@ +{ + "currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentGasLimit": "71794957647893862", + "currentNumber": "1", + "currentTimestamp": "1000", + "currentRandom": "0", + "currentDifficulty": "0", + "blockHashes": {}, + "ommers": [], + "currentBaseFee": "7", + "parentUncleHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "withdrawals": [], + "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000" +} diff --git a/cmd/evm/testdata/33/exp.json b/cmd/evm/testdata/33/exp.json new file mode 100644 index 0000000000..ae82ef3efa --- /dev/null +++ b/cmd/evm/testdata/33/exp.json @@ -0,0 +1,62 @@ +{ + "alloc": { + "0x000000000000000000000000000000000000aaaa": { + "code": "0x58808080600173703c4b2bd70c169f5717101caee543299fc946c75af100", + "balance": "0x4563918244f40000" + }, + "0x000000000000000000000000000000000000bbbb": { + "code": "0x6042805500", + "balance": "0x29a2241af62c0000" + }, + "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": { + "balance": "0x2bf52" + }, + "0x703c4b2bd70c169f5717101caee543299fc946c7": { + "code": "0xef0100000000000000000000000000000000000000bbbb", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000042": "0x0000000000000000000000000000000000000000000000000000000000000042" + }, + "balance": "0x1", + "nonce": "0x1" + }, + "0x71562b71999873db5b286df957af199ec94617f7": { + "code": "0xef0100000000000000000000000000000000000000aaaa", + "balance": "0x6124fee993afa30e", + "nonce": "0x2" + }, + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "code": "0x600060006000600060007310000000000000000000000000000000000000015af1600155600060006000600060007310000000000000000000000000000000000000025af16002553d600060003e600051600355", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000100", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000100", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000100" + }, + "balance": "0xde0b6b3a7640000" + } + }, + "result": { + "stateRoot": "0x9fdcacd4510e93c4488e537dc51578b5c6d505771db64a2610036eeb4be7b26f", + "txRoot": "0x5d13a0b074e80388dc754da92b22922313a63417b3e25a10f324935e09697a53", + "receiptsRoot": "0x504c5d86c34391f70d210e6c482615b391db4bdb9f43479366399d9c5599850a", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","receipts": [{ + "type": "0x4", + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0x15fa9", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","logs": null,"transactionHash": "0x0417aab7c1d8a3989190c3167c132876ce9b8afd99262c5a0f9d06802de3d7ef", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0x15fa9", + "effectiveGasPrice": null, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x0" + } + ], + "currentDifficulty": null, + "gasUsed": "0x15fa9", + "currentBaseFee": "0x7", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "requests": [] +} +} diff --git a/cmd/evm/testdata/33/txs.json b/cmd/evm/testdata/33/txs.json new file mode 100644 index 0000000000..9c4db138c8 --- /dev/null +++ b/cmd/evm/testdata/33/txs.json @@ -0,0 +1,37 @@ +[ + { + "type": "0x4", + "chainId": "0x1", + "nonce": "0x0", + "to": "0x71562b71999873db5b286df957af199ec94617f7", + "gas": "0x7a120", + "gasPrice": null, + "maxPriorityFeePerGas": "0x2", + "maxFeePerGas": "0x12a05f200", + "value": "0x0", + "input": "0x", + "accessList": [], + "authorizationList": [ + { + "chainId": "0x1", + "address": "0x000000000000000000000000000000000000aaaa", + "nonce": "0x1", + "v": "0x1", + "r": "0xf7e3e597fc097e71ed6c26b14b25e5395bc8510d58b9136af439e12715f2d721", + "s": "0x6cf7c3d7939bfdb784373effc0ebb0bd7549691a513f395e3cdabf8602724987" + }, + { + "chainId": "0x0", + "address": "0x000000000000000000000000000000000000bbbb", + "nonce": "0x0", + "v": "0x1", + "r": "0x5011890f198f0356a887b0779bde5afa1ed04e6acb1e3f37f8f18c7b6f521b98", + "s": "0x56c3fa3456b103f3ef4a0acb4b647b9cab9ec4bc68fbcdf1e10b49fb2bcbcf61" + } + ], + "secretKey": "0xb71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291", + "v": "0x0", + "r": "0x0", + "s": "0x0" + } +] diff --git a/cmd/evm/testdata/5/exp.json b/cmd/evm/testdata/5/exp.json index 7d715672c5..00af8b084d 100644 --- a/cmd/evm/testdata/5/exp.json +++ b/cmd/evm/testdata/5/exp.json @@ -18,6 +18,7 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "receipts": [], "currentDifficulty": "0x20000", - "gasUsed": "0x0" + "gasUsed": "0x0", + "requests": null } } diff --git a/core/bench_test.go b/core/bench_test.go index 6d518e8d3b..d376830318 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -90,7 +90,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) { data := make([]byte, nbytes) return func(i int, gen *BlockGen) { toaddr := common.Address{} - gas, _ := IntrinsicGas(data, nil, false, false, false, false) + gas, _ := IntrinsicGas(data, nil, nil, false, false, false, false) signer := gen.Signer() gasPrice := big.NewInt(0) if gen.header.BaseFee != nil { diff --git a/core/blockchain_test.go b/core/blockchain_test.go index dc391bb520..a54a907766 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -17,6 +17,7 @@ package core import ( + "bytes" "errors" "fmt" gomath "math" @@ -36,6 +37,7 @@ import ( "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/core/vm/program" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/ethdb" @@ -4232,3 +4234,95 @@ func TestPragueRequests(t *testing.T) { t.Fatalf("block %d: failed to insert into chain: %v", n, err) } } + +// TestEIP7702 deploys two delegation designations and calls them. It writes one +// value to storage which is verified after. +func TestEIP7702(t *testing.T) { + var ( + config = *params.MergedTestChainConfig + signer = types.LatestSigner(&config) + engine = beacon.NewFaker() + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") + bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb") + funds = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) + ) + gspec := &Genesis{ + Config: &config, + Alloc: types.GenesisAlloc{ + addr1: {Balance: funds}, + addr2: {Balance: funds}, + aa: { // The address 0xAAAA calls into addr2 + Code: program.New().Call(nil, addr2, 1, 0, 0, 0, 0).Bytes(), + Nonce: 0, + Balance: big.NewInt(0), + }, + bb: { // The address 0xBBBB sstores 42 into slot 42. + Code: program.New().Sstore(0x42, 0x42).Bytes(), + Nonce: 0, + Balance: big.NewInt(0), + }, + }, + } + + // Sign authorization tuples. + // The way the auths are combined, it becomes + // 1. tx -> addr1 which is delegated to 0xaaaa + // 2. addr1:0xaaaa calls into addr2:0xbbbb + // 3. addr2:0xbbbb writes to storage + auth1, _ := types.SignAuth(types.Authorization{ + ChainID: gspec.Config.ChainID.Uint64(), + Address: aa, + Nonce: 1, + }, key1) + auth2, _ := types.SignAuth(types.Authorization{ + ChainID: 0, + Address: bb, + Nonce: 0, + }, key2) + + _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { + b.SetCoinbase(aa) + txdata := &types.SetCodeTx{ + ChainID: gspec.Config.ChainID.Uint64(), + Nonce: 0, + To: addr1, + Gas: 500000, + GasFeeCap: uint256.MustFromBig(newGwei(5)), + GasTipCap: uint256.NewInt(2), + AuthList: []types.Authorization{auth1, auth2}, + } + tx := types.MustSignNewTx(key1, signer, txdata) + b.AddTx(tx) + }) + chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, 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) + } + + // Verify delegation designations were deployed. + state, _ := chain.State() + code, want := state.GetCode(addr1), types.AddressToDelegation(auth1.Address) + if !bytes.Equal(code, want) { + t.Fatalf("addr1 code incorrect: got %s, want %s", common.Bytes2Hex(code), common.Bytes2Hex(want)) + } + code, want = state.GetCode(addr2), types.AddressToDelegation(auth2.Address) + if !bytes.Equal(code, want) { + t.Fatalf("addr2 code incorrect: got %s, want %s", common.Bytes2Hex(code), common.Bytes2Hex(want)) + } + // Verify delegation executed the correct code. + var ( + fortyTwo = common.BytesToHash([]byte{0x42}) + actual = state.GetState(addr2, fortyTwo) + ) + if actual.Cmp(fortyTwo) != 0 { + t.Fatalf("addr2 storage wrong: expected %d, got %d", fortyTwo, actual) + } +} diff --git a/core/error.go b/core/error.go index 161538fe43..82f7ddcf5d 100644 --- a/core/error.go +++ b/core/error.go @@ -103,6 +103,8 @@ var ( // ErrSenderNoEOA is returned if the sender of a transaction is a contract. ErrSenderNoEOA = errors.New("sender not an eoa") + // -- EIP-4844 errors -- + // ErrBlobFeeCapTooLow is returned if the transaction fee cap is less than the // blob gas fee of the block. ErrBlobFeeCapTooLow = errors.New("max fee per blob gas less than block blob gas fee") @@ -112,4 +114,20 @@ var ( // ErrBlobTxCreate is returned if a blob transaction has no explicit to field. ErrBlobTxCreate = errors.New("blob transaction of type create") + + // -- EIP-7702 errors -- + + // Message validation errors: + ErrEmptyAuthList = errors.New("EIP-7702 transaction with empty auth list") + ErrSetCodeTxCreate = errors.New("EIP-7702 transaction cannot be used to create contract") +) + +// EIP-7702 state transition errors. +// Note these are just informational, and do not cause tx execution abort. +var ( + ErrAuthorizationWrongChainID = errors.New("EIP-7702 authorization chain ID mismatch") + ErrAuthorizationNonceOverflow = errors.New("EIP-7702 authorization nonce > 64 bit") + ErrAuthorizationInvalidSignature = errors.New("EIP-7702 authorization has invalid signature") + ErrAuthorizationDestinationHasCode = errors.New("EIP-7702 authorization destination is a contract") + ErrAuthorizationNonceMismatch = errors.New("EIP-7702 authorization nonce does not match current account nonce") ) diff --git a/core/state/journal.go b/core/state/journal.go index a2fea6b6ec..13332dbd79 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -23,7 +23,7 @@ import ( "sort" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/holiman/uint256" ) @@ -192,8 +192,11 @@ func (j *journal) balanceChange(addr common.Address, previous *uint256.Int) { }) } -func (j *journal) setCode(address common.Address) { - j.append(codeChange{account: address}) +func (j *journal) setCode(address common.Address, prevCode []byte) { + j.append(codeChange{ + account: address, + prevCode: prevCode, + }) } func (j *journal) nonceChange(address common.Address, prev uint64) { @@ -256,7 +259,8 @@ type ( origvalue common.Hash } codeChange struct { - account common.Address + account common.Address + prevCode []byte } // Changes to other state values. @@ -377,7 +381,7 @@ func (ch nonceChange) copy() journalEntry { } func (ch codeChange) revert(s *StateDB) { - s.getStateObject(ch.account).setCode(types.EmptyCodeHash, nil) + s.getStateObject(ch.account).setCode(crypto.Keccak256Hash(ch.prevCode), ch.prevCode) } func (ch codeChange) dirtied() *common.Address { @@ -385,7 +389,10 @@ func (ch codeChange) dirtied() *common.Address { } func (ch codeChange) copy() journalEntry { - return codeChange{account: ch.account} + return codeChange{ + account: ch.account, + prevCode: ch.prevCode, + } } func (ch storageChange) revert(s *StateDB) { diff --git a/core/state/state_object.go b/core/state/state_object.go index 2d542e5005..76a3aba92c 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "maps" + "slices" "time" "github.com/ethereum/go-ethereum/common" @@ -541,9 +542,11 @@ func (s *stateObject) CodeSize() int { return size } -func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { - s.db.journal.setCode(s.address) +func (s *stateObject) SetCode(codeHash common.Hash, code []byte) (prev []byte) { + prev = slices.Clone(s.code) + s.db.journal.setCode(s.address, prev) s.setCode(codeHash, code) + return prev } func (s *stateObject) setCode(codeHash common.Hash, code []byte) { diff --git a/core/state/statedb.go b/core/state/statedb.go index b0603db7f0..d279ccfdfe 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -439,11 +439,12 @@ func (s *StateDB) SetNonce(addr common.Address, nonce uint64) { } } -func (s *StateDB) SetCode(addr common.Address, code []byte) { +func (s *StateDB) SetCode(addr common.Address, code []byte) (prev []byte) { stateObject := s.getOrNewStateObject(addr) if stateObject != nil { - stateObject.SetCode(crypto.Keccak256Hash(code), code) + return stateObject.SetCode(crypto.Keccak256Hash(code), code) } + return nil } func (s *StateDB) SetState(addr common.Address, key, value common.Hash) common.Hash { diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 26d0217099..31bdd06b46 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -182,11 +182,16 @@ func (s *hookedStateDB) SetNonce(address common.Address, nonce uint64) { } } -func (s *hookedStateDB) SetCode(address common.Address, code []byte) { - s.inner.SetCode(address, code) +func (s *hookedStateDB) SetCode(address common.Address, code []byte) []byte { + prev := s.inner.SetCode(address, code) if s.hooks.OnCodeChange != nil { - s.hooks.OnCodeChange(address, types.EmptyCodeHash, nil, crypto.Keccak256Hash(code), code) + prevHash := types.EmptyCodeHash + if len(prev) != 0 { + prevHash = crypto.Keccak256Hash(prev) + } + s.hooks.OnCodeChange(address, prevHash, prev, crypto.Keccak256Hash(code), code) } + return prev } func (s *hookedStateDB) SetState(address common.Address, key common.Hash, value common.Hash) common.Hash { diff --git a/core/state_processor_test.go b/core/state_processor_test.go index f3d2304690..e8d8c2ca2e 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -63,6 +63,7 @@ func TestStateProcessorErrors(t *testing.T) { TerminalTotalDifficulty: big.NewInt(0), ShanghaiTime: new(uint64), CancunTime: new(uint64), + PragueTime: new(uint64), } signer = types.LatestSigner(config) key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") @@ -110,6 +111,21 @@ func TestStateProcessorErrors(t *testing.T) { } return tx } + var mkSetCodeTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, authlist []types.Authorization) *types.Transaction { + tx, err := types.SignTx(types.NewTx(&types.SetCodeTx{ + Nonce: nonce, + GasTipCap: uint256.MustFromBig(gasTipCap), + GasFeeCap: uint256.MustFromBig(gasFeeCap), + Gas: gasLimit, + To: to, + Value: new(uint256.Int), + AuthList: authlist, + }), signer, key1) + if err != nil { + t.Fatal(err) + } + return tx + } { // Tests against a 'recent' chain definition var ( @@ -251,6 +267,13 @@ func TestStateProcessorErrors(t *testing.T) { }, want: "could not apply tx 0 [0x6c11015985ce82db691d7b2d017acda296db88b811c3c60dc71449c76256c716]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 1, baseFee: 875000000", }, + { // ErrEmptyAuthList + txs: []*types.Transaction{ + mkSetCodeTx(0, common.Address{}, params.TxGas, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), nil), + }, + want: "could not apply tx 0 [0xc18d10f4c809dbdfa1a074c3300de9bc4b7f16a20f0ec667f6f67312b71b956a]: EIP-7702 transaction with empty auth list (sender 0x71562b71999873DB5b286dF957af199Ec94617F7)", + }, + // ErrSetCodeTxCreate cannot be tested: it is impossible to create a SetCode-tx with nil `to`. } { block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config, false) _, err := blockchain.InsertChain(types.Blocks{block}) @@ -337,7 +360,7 @@ func TestStateProcessorErrors(t *testing.T) { txs: []*types.Transaction{ mkDynamicTx(0, common.Address{}, params.TxGas-1000, big.NewInt(0), big.NewInt(0)), }, - want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: sender not an eoa: address 0x71562b71999873DB5b286dF957af199Ec94617F7, codehash: 0x9280914443471259d4570a8661015ae4a5b80186dbc619658fb494bebc3da3d1", + want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: sender not an eoa: address 0x71562b71999873DB5b286dF957af199Ec94617F7, len(code): 4", }, } { block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config, false) diff --git a/core/state_transition.go b/core/state_transition.go index ea7e3df2ff..58728e470e 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -67,7 +67,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, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { +func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.Authorization, isContractCreation, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { // Set the starting gas for the raw transaction var gas uint64 if isContractCreation && isHomestead { @@ -113,6 +113,9 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation, gas += uint64(len(accessList)) * params.TxAccessListAddressGas gas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas } + if authList != nil { + gas += uint64(len(authList)) * params.CallNewAccountGas + } return gas, nil } @@ -140,6 +143,7 @@ type Message struct { AccessList types.AccessList BlobGasFeeCap *big.Int BlobHashes []common.Hash + AuthList []types.Authorization // When SkipNonceChecks is true, the message nonce is not checked against the // account nonce in state. @@ -162,6 +166,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In Value: tx.Value(), Data: tx.Data(), AccessList: tx.AccessList(), + AuthList: tx.AuthList(), SkipNonceChecks: false, SkipFromEOACheck: false, BlobHashes: tx.BlobHashes(), @@ -303,10 +308,10 @@ func (st *stateTransition) preCheck() error { } if !msg.SkipFromEOACheck { // Make sure the sender is an EOA - codeHash := st.state.GetCodeHash(msg.From) - if codeHash != (common.Hash{}) && codeHash != types.EmptyCodeHash { - return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA, - msg.From.Hex(), codeHash) + code := st.state.GetCode(msg.From) + _, delegated := types.ParseDelegation(code) + if len(code) > 0 && !delegated { + return fmt.Errorf("%w: address %v, len(code): %d", ErrSenderNoEOA, msg.From.Hex(), len(code)) } } // Make sure that transaction gasFeeCap is greater than the baseFee (post london) @@ -366,6 +371,15 @@ func (st *stateTransition) preCheck() error { } } } + // Check that EIP-7702 authorization list signatures are well formed. + if msg.AuthList != nil { + if msg.To == nil { + return fmt.Errorf("%w (sender %v)", ErrSetCodeTxCreate, msg.From) + } + if len(msg.AuthList) == 0 { + return fmt.Errorf("%w (sender %v)", ErrEmptyAuthList, msg.From) + } + } return st.buyGas() } @@ -403,7 +417,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { ) // Check clauses 4-5, subtract intrinsic gas if everything is correct - gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) + gas, err := IntrinsicGas(msg.Data, msg.AccessList, msg.AuthList, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) if err != nil { return nil, err } @@ -449,8 +463,27 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { if contractCreation { ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, value) } else { - // Increment the nonce for the next transaction - st.state.SetNonce(msg.From, st.state.GetNonce(sender.Address())+1) + // Increment the nonce for the next transaction. + st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1) + + // Apply EIP-7702 authorizations. + if msg.AuthList != nil { + for _, auth := range msg.AuthList { + // Note errors are ignored, we simply skip invalid authorizations here. + st.applyAuthorization(msg, &auth) + } + } + + // Perform convenience warming of sender's delegation target. Although the + // sender is already warmed in Prepare(..), it's possible a delegation to + // the account was deployed during this transaction. To handle correctly, + // simply wait until the final state of delegations is determined before + // performing the resolution and warming. + if addr, ok := types.ParseDelegation(st.state.GetCode(*msg.To)); ok { + st.state.AddAddressToAccessList(addr) + } + + // Execute the transaction's call. ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value) } @@ -494,6 +527,64 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { }, nil } +// validateAuthorization validates an EIP-7702 authorization against the state. +func (st *stateTransition) validateAuthorization(auth *types.Authorization) (authority common.Address, err error) { + // Verify chain ID is 0 or equal to current chain ID. + if auth.ChainID != 0 && st.evm.ChainConfig().ChainID.Uint64() != auth.ChainID { + return authority, ErrAuthorizationWrongChainID + } + // Limit nonce to 2^64-1 per EIP-2681. + if auth.Nonce+1 < auth.Nonce { + return authority, ErrAuthorizationNonceOverflow + } + // Validate signature values and recover authority. + authority, err = auth.Authority() + if err != nil { + return authority, fmt.Errorf("%w: %v", ErrAuthorizationInvalidSignature, err) + } + // Check the authority account + // 1) doesn't have code or has exisiting delegation + // 2) matches the auth's nonce + // + // Note it is added to the access list even if the authorization is invalid. + st.state.AddAddressToAccessList(authority) + code := st.state.GetCode(authority) + if _, ok := types.ParseDelegation(code); len(code) != 0 && !ok { + return authority, ErrAuthorizationDestinationHasCode + } + if have := st.state.GetNonce(authority); have != auth.Nonce { + return authority, ErrAuthorizationNonceMismatch + } + return authority, nil +} + +// applyAuthorization applies an EIP-7702 code delegation to the state. +func (st *stateTransition) applyAuthorization(msg *Message, auth *types.Authorization) error { + authority, err := st.validateAuthorization(auth) + if err != nil { + return err + } + + // If the account already exists in state, refund the new account cost + // charged in the intrinsic calculation. + if st.state.Exist(authority) { + st.state.AddRefund(params.CallNewAccountGas - params.TxAuthTupleGas) + } + + // Update nonce and account code. + st.state.SetNonce(authority, auth.Nonce+1) + if auth.Address == (common.Address{}) { + // Delegation to zero address means clear. + st.state.SetCode(authority, nil) + return nil + } + + // Otherwise install delegation to auth.Address. + st.state.SetCode(authority, types.AddressToDelegation(auth.Address)) + + return nil +} + func (st *stateTransition) refundGas(refundQuotient uint64) uint64 { // Apply refund counter, capped to a refund quotient refund := st.gasUsed() / refundQuotient diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 33b383d5cf..908945471d 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -108,7 +108,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types } // Ensure the transaction has more gas than the bare minimum needed to cover // the transaction metadata - intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, opts.Config.IsIstanbul(head.Number), opts.Config.IsShanghai(head.Number, head.Time)) + intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.AuthList(), tx.To() == nil, true, opts.Config.IsIstanbul(head.Number), opts.Config.IsShanghai(head.Number, head.Time)) if err != nil { return err } diff --git a/core/types/gen_authorization.go b/core/types/gen_authorization.go new file mode 100644 index 0000000000..b598b64ff7 --- /dev/null +++ b/core/types/gen_authorization.go @@ -0,0 +1,75 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package types + +import ( + "encoding/json" + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/holiman/uint256" +) + +var _ = (*authorizationMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (a Authorization) MarshalJSON() ([]byte, error) { + type Authorization struct { + ChainID hexutil.Uint64 `json:"chainId" gencodec:"required"` + Address common.Address `json:"address" gencodec:"required"` + Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` + V hexutil.Uint64 `json:"v" gencodec:"required"` + R uint256.Int `json:"r" gencodec:"required"` + S uint256.Int `json:"s" gencodec:"required"` + } + var enc Authorization + enc.ChainID = hexutil.Uint64(a.ChainID) + enc.Address = a.Address + enc.Nonce = hexutil.Uint64(a.Nonce) + enc.V = hexutil.Uint64(a.V) + enc.R = a.R + enc.S = a.S + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (a *Authorization) UnmarshalJSON(input []byte) error { + type Authorization struct { + ChainID *hexutil.Uint64 `json:"chainId" gencodec:"required"` + Address *common.Address `json:"address" gencodec:"required"` + Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` + V *hexutil.Uint64 `json:"v" gencodec:"required"` + R *uint256.Int `json:"r" gencodec:"required"` + S *uint256.Int `json:"s" gencodec:"required"` + } + var dec Authorization + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.ChainID == nil { + return errors.New("missing required field 'chainId' for Authorization") + } + a.ChainID = uint64(*dec.ChainID) + if dec.Address == nil { + return errors.New("missing required field 'address' for Authorization") + } + a.Address = *dec.Address + if dec.Nonce == nil { + return errors.New("missing required field 'nonce' for Authorization") + } + a.Nonce = uint64(*dec.Nonce) + if dec.V == nil { + return errors.New("missing required field 'v' for Authorization") + } + a.V = uint8(*dec.V) + if dec.R == nil { + return errors.New("missing required field 'r' for Authorization") + } + a.R = *dec.R + if dec.S == nil { + return errors.New("missing required field 's' for Authorization") + } + a.S = *dec.S + return nil +} diff --git a/core/types/receipt.go b/core/types/receipt.go index 4f96fde59c..47f16d950a 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -204,7 +204,7 @@ func (r *Receipt) decodeTyped(b []byte) error { return errShortTypedReceipt } switch b[0] { - case DynamicFeeTxType, AccessListTxType, BlobTxType: + case DynamicFeeTxType, AccessListTxType, BlobTxType, SetCodeTxType: var data receiptRLP err := rlp.DecodeBytes(b[1:], &data) if err != nil { @@ -312,7 +312,7 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { } w.WriteByte(r.Type) switch r.Type { - case AccessListTxType, DynamicFeeTxType, BlobTxType: + case AccessListTxType, DynamicFeeTxType, BlobTxType, SetCodeTxType: rlp.Encode(w, data) default: // For unsupported types, write nothing. Since this is for diff --git a/core/types/transaction.go b/core/types/transaction.go index ea6f5ad6b9..b5fb3e2db2 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -48,6 +48,7 @@ const ( AccessListTxType = 0x01 DynamicFeeTxType = 0x02 BlobTxType = 0x03 + SetCodeTxType = 0x04 ) // Transaction is an Ethereum transaction. @@ -205,6 +206,8 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) { inner = new(DynamicFeeTx) case BlobTxType: inner = new(BlobTx) + case SetCodeTxType: + inner = new(SetCodeTx) default: return nil, ErrTxTypeNotSupported } @@ -471,6 +474,15 @@ func (tx *Transaction) WithBlobTxSidecar(sideCar *BlobTxSidecar) *Transaction { return cpy } +// AuthList returns the authorizations list of the transaction. +func (tx *Transaction) AuthList() []Authorization { + setcodetx, ok := tx.inner.(*SetCodeTx) + if !ok { + return nil + } + return setcodetx.AuthList +} + // 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. diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index 4d5b2bcdd4..4176a8220c 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -43,6 +43,7 @@ type txJSON struct { Input *hexutil.Bytes `json:"input"` AccessList *AccessList `json:"accessList,omitempty"` BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` + AuthorizationList []Authorization `json:"authorizationList,omitempty"` V *hexutil.Big `json:"v"` R *hexutil.Big `json:"r"` S *hexutil.Big `json:"s"` @@ -153,6 +154,22 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) { enc.Commitments = itx.Sidecar.Commitments enc.Proofs = itx.Sidecar.Proofs } + case *SetCodeTx: + enc.ChainID = (*hexutil.Big)(new(big.Int).SetUint64(itx.ChainID)) + enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) + enc.To = tx.To() + enc.Gas = (*hexutil.Uint64)(&itx.Gas) + enc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap.ToBig()) + enc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap.ToBig()) + enc.Value = (*hexutil.Big)(itx.Value.ToBig()) + enc.Input = (*hexutil.Bytes)(&itx.Data) + enc.AccessList = &itx.AccessList + enc.AuthorizationList = itx.AuthList + enc.V = (*hexutil.Big)(itx.V.ToBig()) + enc.R = (*hexutil.Big)(itx.R.ToBig()) + enc.S = (*hexutil.Big)(itx.S.ToBig()) + yparity := itx.V.Uint64() + enc.YParity = (*hexutil.Uint64)(&yparity) } return json.Marshal(&enc) } @@ -409,6 +426,81 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { } } + case SetCodeTxType: + var itx SetCodeTx + inner = &itx + if dec.ChainID == nil { + return errors.New("missing required field 'chainId' in transaction") + } + itx.ChainID = dec.ChainID.ToInt().Uint64() + if dec.Nonce == nil { + return errors.New("missing required field 'nonce' in transaction") + } + itx.Nonce = uint64(*dec.Nonce) + if dec.To == nil { + return errors.New("missing required field 'to' in transaction") + } + itx.To = *dec.To + if dec.Gas == nil { + return errors.New("missing required field 'gas' for txdata") + } + itx.Gas = uint64(*dec.Gas) + if dec.MaxPriorityFeePerGas == nil { + return errors.New("missing required field 'maxPriorityFeePerGas' for txdata") + } + itx.GasTipCap = uint256.MustFromBig((*big.Int)(dec.MaxPriorityFeePerGas)) + if dec.MaxFeePerGas == nil { + return errors.New("missing required field 'maxFeePerGas' for txdata") + } + itx.GasFeeCap = uint256.MustFromBig((*big.Int)(dec.MaxFeePerGas)) + if dec.Value == nil { + return errors.New("missing required field 'value' in transaction") + } + itx.Value = uint256.MustFromBig((*big.Int)(dec.Value)) + if dec.Input == nil { + return errors.New("missing required field 'input' in transaction") + } + itx.Data = *dec.Input + if dec.AccessList != nil { + itx.AccessList = *dec.AccessList + } + if dec.AuthorizationList == nil { + return errors.New("missing required field 'authorizationList' in transaction") + } + itx.AuthList = dec.AuthorizationList + + // signature R + var overflow bool + if dec.R == nil { + return errors.New("missing required field 'r' in transaction") + } + itx.R, overflow = uint256.FromBig((*big.Int)(dec.R)) + if overflow { + return errors.New("'r' value overflows uint256") + } + // signature S + if dec.S == nil { + return errors.New("missing required field 's' in transaction") + } + itx.S, overflow = uint256.FromBig((*big.Int)(dec.S)) + if overflow { + return errors.New("'s' value overflows uint256") + } + // signature V + vbig, err := dec.yParityValue() + if err != nil { + return err + } + itx.V, overflow = uint256.FromBig(vbig) + if overflow { + return errors.New("'v' value overflows uint256") + } + if itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 { + if err := sanityCheckSignature(vbig, itx.R.ToBig(), itx.S.ToBig(), false); err != nil { + return err + } + } + default: return ErrTxTypeNotSupported } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 73011e238b..78fa2fc8ef 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -40,6 +40,8 @@ type sigCache struct { func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer { var signer Signer switch { + case config.IsPrague(blockNumber, blockTime): + signer = NewPragueSigner(config.ChainID) case config.IsCancun(blockNumber, blockTime): signer = NewCancunSigner(config.ChainID) case config.IsLondon(blockNumber): @@ -67,6 +69,8 @@ func LatestSigner(config *params.ChainConfig) Signer { var signer Signer if config.ChainID != nil { switch { + case config.PragueTime != nil: + signer = NewPragueSigner(config.ChainID) case config.CancunTime != nil: signer = NewCancunSigner(config.ChainID) case config.LondonBlock != nil: @@ -94,7 +98,7 @@ func LatestSigner(config *params.ChainConfig) Signer { func LatestSignerForChainID(chainID *big.Int) Signer { var signer Signer if chainID != nil { - signer = NewCancunSigner(chainID) + signer = NewPragueSigner(chainID) } else { signer = HomesteadSigner{} } @@ -174,6 +178,77 @@ type Signer interface { Equal(Signer) bool } +type pragueSigner struct{ cancunSigner } + +// NewPragueSigner returns a signer that accepts +// - EIP-7702 set code transactions +// - EIP-4844 blob transactions +// - EIP-1559 dynamic fee transactions +// - EIP-2930 access list transactions, +// - EIP-155 replay protected transactions, and +// - legacy Homestead transactions. +func NewPragueSigner(chainId *big.Int) Signer { + signer, _ := NewCancunSigner(chainId).(cancunSigner) + return pragueSigner{signer} +} + +func (s pragueSigner) Sender(tx *Transaction) (common.Address, error) { + if tx.Type() != SetCodeTxType { + return s.cancunSigner.Sender(tx) + } + V, R, S := tx.RawSignatureValues() + + // Set code txs are defined to use 0 and 1 as their recovery + // id, add 27 to become equivalent to unprotected Homestead signatures. + V = new(big.Int).Add(V, big.NewInt(27)) + if tx.ChainId().Cmp(s.chainId) != 0 { + return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) + } + return recoverPlain(s.Hash(tx), R, S, V, true) +} + +func (s pragueSigner) Equal(s2 Signer) bool { + x, ok := s2.(pragueSigner) + return ok && x.chainId.Cmp(s.chainId) == 0 +} + +func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { + txdata, ok := tx.inner.(*SetCodeTx) + if !ok { + return s.cancunSigner.SignatureValues(tx, sig) + } + // Check that chain ID of tx matches the signer. We also accept ID zero here, + // because it indicates that the chain ID was not specified in the tx. + if txdata.ChainID != 0 && new(big.Int).SetUint64(txdata.ChainID).Cmp(s.chainId) != 0 { + return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) + } + R, S, _ = decodeSignature(sig) + V = big.NewInt(int64(sig[64])) + return R, S, V, nil +} + +// Hash returns the hash to be signed by the sender. +// It does not uniquely identify the transaction. +func (s pragueSigner) Hash(tx *Transaction) common.Hash { + if tx.Type() != SetCodeTxType { + return s.cancunSigner.Hash(tx) + } + return prefixedRlpHash( + tx.Type(), + []interface{}{ + s.chainId, + tx.Nonce(), + tx.GasTipCap(), + tx.GasFeeCap(), + tx.Gas(), + tx.To(), + tx.Value(), + tx.Data(), + tx.AccessList(), + tx.AuthList(), + }) +} + type cancunSigner struct{ londonSigner } // NewCancunSigner returns a signer that accepts diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go new file mode 100644 index 0000000000..0fea9a63a7 --- /dev/null +++ b/core/types/tx_setcode.go @@ -0,0 +1,226 @@ +// 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" + "crypto/ecdsa" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + "github.com/holiman/uint256" +) + +// DelegationPrefix is used by code to denote the account is delegating to +// another account. +var DelegationPrefix = []byte{0xef, 0x01, 0x00} + +// ParseDelegation tries to parse the address from a delegation slice. +func ParseDelegation(b []byte) (common.Address, bool) { + if len(b) != 23 || !bytes.HasPrefix(b, DelegationPrefix) { + return common.Address{}, false + } + return common.BytesToAddress(b[len(DelegationPrefix):]), true +} + +// AddressToDelegation adds the delegation prefix to the specified address. +func AddressToDelegation(addr common.Address) []byte { + return append(DelegationPrefix, addr.Bytes()...) +} + +// SetCodeTx implements the EIP-7702 transaction type which temporarily installs +// the code at the signer's address. +type SetCodeTx struct { + ChainID uint64 + Nonce uint64 + GasTipCap *uint256.Int // a.k.a. maxPriorityFeePerGas + GasFeeCap *uint256.Int // a.k.a. maxFeePerGas + Gas uint64 + To common.Address + Value *uint256.Int + Data []byte + AccessList AccessList + AuthList []Authorization + + // Signature values + V *uint256.Int `json:"v" gencodec:"required"` + R *uint256.Int `json:"r" gencodec:"required"` + S *uint256.Int `json:"s" gencodec:"required"` +} + +//go:generate go run github.com/fjl/gencodec -type Authorization -field-override authorizationMarshaling -out gen_authorization.go + +// Authorization is an authorization from an account to deploy code at its address. +type Authorization struct { + ChainID uint64 `json:"chainId" gencodec:"required"` + Address common.Address `json:"address" gencodec:"required"` + Nonce uint64 `json:"nonce" gencodec:"required"` + V uint8 `json:"v" gencodec:"required"` + R uint256.Int `json:"r" gencodec:"required"` + S uint256.Int `json:"s" gencodec:"required"` +} + +// field type overrides for gencodec +type authorizationMarshaling struct { + ChainID hexutil.Uint64 + Nonce hexutil.Uint64 + V hexutil.Uint64 +} + +// SignAuth signs the provided authorization. +func SignAuth(auth Authorization, prv *ecdsa.PrivateKey) (Authorization, error) { + sighash := auth.sigHash() + sig, err := crypto.Sign(sighash[:], prv) + if err != nil { + return Authorization{}, err + } + return auth.withSignature(sig), nil +} + +// withSignature updates the signature of an Authorization to be equal the +// decoded signature provided in sig. +func (a *Authorization) withSignature(sig []byte) Authorization { + r, s, _ := decodeSignature(sig) + return Authorization{ + ChainID: a.ChainID, + Address: a.Address, + Nonce: a.Nonce, + V: sig[64], + R: *uint256.MustFromBig(r), + S: *uint256.MustFromBig(s), + } +} + +func (a *Authorization) sigHash() common.Hash { + return prefixedRlpHash(0x05, []any{ + a.ChainID, + a.Address, + a.Nonce, + }) +} + +// Authority recovers the the authorizing account of an authorization. +func (a *Authorization) Authority() (common.Address, error) { + sighash := a.sigHash() + if !crypto.ValidateSignatureValues(a.V, a.R.ToBig(), a.S.ToBig(), true) { + return common.Address{}, ErrInvalidSig + } + // encode the signature in uncompressed format + var sig [crypto.SignatureLength]byte + a.R.WriteToSlice(sig[:32]) + a.S.WriteToSlice(sig[32:64]) + sig[64] = a.V + // recover the public key from the signature + pub, err := crypto.Ecrecover(sighash[:], sig[:]) + if err != nil { + return common.Address{}, err + } + if len(pub) == 0 || pub[0] != 4 { + return common.Address{}, errors.New("invalid public key") + } + var addr common.Address + copy(addr[:], crypto.Keccak256(pub[1:])[12:]) + return addr, nil +} + +// copy creates a deep copy of the transaction data and initializes all fields. +func (tx *SetCodeTx) copy() TxData { + cpy := &SetCodeTx{ + Nonce: tx.Nonce, + To: tx.To, + Data: common.CopyBytes(tx.Data), + Gas: tx.Gas, + // These are copied below. + AccessList: make(AccessList, len(tx.AccessList)), + AuthList: make([]Authorization, len(tx.AuthList)), + Value: new(uint256.Int), + ChainID: tx.ChainID, + GasTipCap: new(uint256.Int), + GasFeeCap: new(uint256.Int), + V: new(uint256.Int), + R: new(uint256.Int), + S: new(uint256.Int), + } + copy(cpy.AccessList, tx.AccessList) + copy(cpy.AuthList, tx.AuthList) + if tx.Value != nil { + cpy.Value.Set(tx.Value) + } + if tx.GasTipCap != nil { + cpy.GasTipCap.Set(tx.GasTipCap) + } + if tx.GasFeeCap != nil { + cpy.GasFeeCap.Set(tx.GasFeeCap) + } + if tx.V != nil { + cpy.V.Set(tx.V) + } + if tx.R != nil { + cpy.R.Set(tx.R) + } + if tx.S != nil { + cpy.S.Set(tx.S) + } + return cpy +} + +// accessors for innerTx. +func (tx *SetCodeTx) txType() byte { return SetCodeTxType } +func (tx *SetCodeTx) chainID() *big.Int { return big.NewInt(int64(tx.ChainID)) } +func (tx *SetCodeTx) accessList() AccessList { return tx.AccessList } +func (tx *SetCodeTx) data() []byte { return tx.Data } +func (tx *SetCodeTx) gas() uint64 { return tx.Gas } +func (tx *SetCodeTx) gasFeeCap() *big.Int { return tx.GasFeeCap.ToBig() } +func (tx *SetCodeTx) gasTipCap() *big.Int { return tx.GasTipCap.ToBig() } +func (tx *SetCodeTx) gasPrice() *big.Int { return tx.GasFeeCap.ToBig() } +func (tx *SetCodeTx) value() *big.Int { return tx.Value.ToBig() } +func (tx *SetCodeTx) nonce() uint64 { return tx.Nonce } +func (tx *SetCodeTx) to() *common.Address { tmp := tx.To; return &tmp } + +func (tx *SetCodeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { + if baseFee == nil { + return dst.Set(tx.GasFeeCap.ToBig()) + } + tip := dst.Sub(tx.GasFeeCap.ToBig(), baseFee) + if tip.Cmp(tx.GasTipCap.ToBig()) > 0 { + tip.Set(tx.GasTipCap.ToBig()) + } + return tip.Add(tip, baseFee) +} + +func (tx *SetCodeTx) rawSignatureValues() (v, r, s *big.Int) { + return tx.V.ToBig(), tx.R.ToBig(), tx.S.ToBig() +} + +func (tx *SetCodeTx) setSignatureValues(chainID, v, r, s *big.Int) { + tx.ChainID = chainID.Uint64() + tx.V.SetFromBig(v) + tx.R.SetFromBig(r) + tx.S.SetFromBig(s) +} + +func (tx *SetCodeTx) encode(b *bytes.Buffer) error { + return rlp.Encode(b, tx) +} + +func (tx *SetCodeTx) decode(input []byte) error { + return rlp.DecodeBytes(input, tx) +} diff --git a/core/types/tx_setcode_test.go b/core/types/tx_setcode_test.go new file mode 100644 index 0000000000..d0544573cf --- /dev/null +++ b/core/types/tx_setcode_test.go @@ -0,0 +1,70 @@ +// 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 ( + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +// TestParseDelegation tests a few possible delegation designator values and +// ensures they are parsed correctly. +func TestParseDelegation(t *testing.T) { + addr := common.Address{0x42} + for _, tt := range []struct { + val []byte + want *common.Address + }{ + { // simple correct delegation + val: append(DelegationPrefix, addr.Bytes()...), + want: &addr, + }, + { // wrong address size + val: append(DelegationPrefix, addr.Bytes()[0:19]...), + }, + { // short address + val: append(DelegationPrefix, 0x42), + }, + { // long address + val: append(append(DelegationPrefix, addr.Bytes()...), 0x42), + }, + { // wrong prefix size + val: append(DelegationPrefix[:2], addr.Bytes()...), + }, + { // wrong prefix + val: append([]byte{0xef, 0x01, 0x01}, addr.Bytes()...), + }, + { // wrong prefix + val: append([]byte{0xef, 0x00, 0x00}, addr.Bytes()...), + }, + { // no prefix + val: addr.Bytes(), + }, + { // no address + val: DelegationPrefix, + }, + } { + got, ok := ParseDelegation(tt.val) + if ok && tt.want == nil { + t.Fatalf("expected fail, got %s", got.Hex()) + } + if !ok && tt.want != nil { + t.Fatalf("failed to parse, want %s", tt.want.Hex()) + } + } +} diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go index 45b317d3c0..5088231207 100644 --- a/core/verkle_witness_test.go +++ b/core/verkle_witness_test.go @@ -83,12 +83,12 @@ var ( func TestProcessVerkle(t *testing.T) { var ( code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`) - intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, true, true, true, true) + intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, 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) + intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, nil, true, true, true, true) signer = types.LatestSigner(testVerkleChainConfig) testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain diff --git a/core/vm/eips.go b/core/vm/eips.go index 71d51f81ef..a51a18dc60 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -23,6 +23,8 @@ import ( "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" "github.com/holiman/uint256" ) @@ -40,6 +42,7 @@ var activators = map[int]func(*JumpTable){ 1344: enable1344, 1153: enable1153, 4762: enable4762, + 7702: enable7702, } // EnableEIP enables the given EIP on the config. @@ -703,3 +706,68 @@ func enableEOF(jt *JumpTable) { memorySize: memoryExtCall, } } + +// opExtCodeCopyEIP7702 implements the EIP-7702 variation of opExtCodeCopy. +func opExtCodeCopyEIP7702(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 + } + code := interpreter.evm.StateDB.GetCode(common.Address(a.Bytes20())) + if _, ok := types.ParseDelegation(code); ok { + code = types.DelegationPrefix[:2] + } + codeCopy := getData(code, uint64CodeOffset, length.Uint64()) + scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) + + return nil, nil +} + +// opExtCodeSizeEIP7702 implements the EIP-7702 variation of opExtCodeSize. +func opExtCodeSizeEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + slot := scope.Stack.peek() + code := interpreter.evm.StateDB.GetCode(common.Address(slot.Bytes20())) + if _, ok := types.ParseDelegation(code); ok { + code = types.DelegationPrefix[:2] + } + slot.SetUint64(uint64(len(code))) + return nil, nil +} + +// opExtCodeHashEIP7702 implements the EIP-7702 variation of opExtCodeHash. +func opExtCodeHashEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + slot := scope.Stack.peek() + addr := common.Address(slot.Bytes20()) + if interpreter.evm.StateDB.Empty(addr) { + slot.Clear() + return nil, nil + } + code := interpreter.evm.StateDB.GetCode(addr) + if _, ok := types.ParseDelegation(code); ok { + // If the code is a delegation, return the prefix without version. + slot.SetBytes(crypto.Keccak256(types.DelegationPrefix[:2])) + } else { + // Otherwise, return normal code hash. + slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(addr).Bytes()) + } + return nil, nil +} + +// enable7702 the EIP-7702 changes to support delegation designators. +func enable7702(jt *JumpTable) { + jt[EXTCODECOPY].execute = opExtCodeCopyEIP7702 + jt[EXTCODESIZE].execute = opExtCodeSizeEIP7702 + jt[EXTCODEHASH].execute = opExtCodeHashEIP7702 + + jt[CALL].dynamicGas = gasCallEIP7702 + jt[CALLCODE].dynamicGas = gasCallCodeEIP7702 + jt[STATICCALL].dynamicGas = gasStaticCallEIP7702 + jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP7702 +} diff --git a/core/vm/eof_validation_test.go b/core/vm/eof_validation_test.go index 6680ca3a5d..afb856a32c 100644 --- a/core/vm/eof_validation_test.go +++ b/core/vm/eof_validation_test.go @@ -251,7 +251,7 @@ func TestValidateCode(t *testing.T) { data: make([]byte, 0), subContainers: make([]*Container, 0), } - _, err := validateCode(test.code, test.section, container, &pragueEOFInstructionSet, false) + _, err := validateCode(test.code, test.section, container, &eofInstructionSet, false) if !errors.Is(err, test.err) { t.Errorf("test %d (%s): unexpected error (want: %v, got: %v)", i, common.Bytes2Hex(test.code), test.err, err) } @@ -277,7 +277,7 @@ func BenchmarkRJUMPI(b *testing.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := validateCode(code, 0, container, &pragueEOFInstructionSet, false) + _, err := validateCode(code, 0, container, &eofInstructionSet, false) if err != nil { b.Fatal(err) } @@ -309,7 +309,7 @@ func BenchmarkRJUMPV(b *testing.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := validateCode(code, 0, container, &pragueEOFInstructionSet, false) + _, err := validateCode(code, 0, container, &pragueInstructionSet, false) if err != nil { b.Fatal(err) } @@ -357,7 +357,7 @@ func BenchmarkEOFValidation(b *testing.B) { if err := container2.UnmarshalBinary(bin, true); err != nil { b.Fatal(err) } - if err := container2.ValidateCode(&pragueEOFInstructionSet, false); err != nil { + if err := container2.ValidateCode(&pragueInstructionSet, false); err != nil { b.Fatal(err) } } @@ -412,7 +412,7 @@ func BenchmarkEOFValidation2(b *testing.B) { if err := container2.UnmarshalBinary(bin, true); err != nil { b.Fatal(err) } - if err := container2.ValidateCode(&pragueEOFInstructionSet, false); err != nil { + if err := container2.ValidateCode(&pragueInstructionSet, false); err != nil { b.Fatal(err) } } @@ -468,7 +468,7 @@ func BenchmarkEOFValidation3(b *testing.B) { if err := container2.UnmarshalBinary(bin, true); err != nil { b.Fatal(err) } - if err := container2.ValidateCode(&pragueEOFInstructionSet, false); err != nil { + if err := container2.ValidateCode(&pragueInstructionSet, false); err != nil { b.Fatal(err) } } @@ -494,7 +494,7 @@ func BenchmarkRJUMPI_2(b *testing.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := validateCode(code, 0, container, &pragueEOFInstructionSet, false) + _, err := validateCode(code, 0, container, &pragueInstructionSet, false) if err != nil { b.Fatal(err) } @@ -512,6 +512,6 @@ func FuzzValidate(f *testing.F) { f.Fuzz(func(_ *testing.T, code []byte, maxStack uint16) { var container Container container.types = append(container.types, &functionMetadata{inputs: 0, outputs: 0x80, maxStackHeight: maxStack}) - validateCode(code, 0, &container, &pragueEOFInstructionSet, true) + validateCode(code, 0, &container, &pragueInstructionSet, true) }) } diff --git a/core/vm/evm.go b/core/vm/evm.go index 07e4a272fa..1a0215459c 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -217,7 +217,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas } 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) + code := evm.resolveCode(addr) if len(code) == 0 { ret, err = nil, nil // gas is unchanged } else { @@ -225,7 +225,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // If the account has no code, we can abort here // The depth-check is already done, and precompiles handled above contract := NewContract(caller, AccountRef(addrCopy), value, gas) - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code) + contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), code) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } @@ -285,7 +285,7 @@ func (evm *EVM) CallCode(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(caller.Address()), value, gas) - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) + contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy)) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } @@ -332,7 +332,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by addrCopy := addr // Initialise a new contract and make initialise the delegate values contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) + contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy)) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } @@ -387,7 +387,7 @@ 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) - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) + contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(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 // when we're in Homestead this also counts for code storage gas errors. @@ -567,6 +567,35 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment * return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2) } +// resolveCode returns the code associated with the provided account. After +// Prague, it can also resolve code pointed to by a delegation designator. +func (evm *EVM) resolveCode(addr common.Address) []byte { + code := evm.StateDB.GetCode(addr) + if !evm.chainRules.IsPrague { + return code + } + if target, ok := types.ParseDelegation(code); ok { + // Note we only follow one level of delegation. + return evm.StateDB.GetCode(target) + } + return code +} + +// resolveCodeHash returns the code hash associated with the provided address. +// After Prague, it can also resolve code hash of the account pointed to by a +// delegation designator. Although this is not accessible in the EVM it is used +// internally to associate jumpdest analysis to code. +func (evm *EVM) resolveCodeHash(addr common.Address) common.Hash { + if evm.chainRules.IsPrague { + code := evm.StateDB.GetCode(addr) + if target, ok := types.ParseDelegation(code); ok { + // Note we only follow one level of delegation. + return evm.StateDB.GetCodeHash(target) + } + } + return evm.StateDB.GetCodeHash(addr) +} + // ChainConfig returns the environment's chain configuration func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } diff --git a/core/vm/interface.go b/core/vm/interface.go index 9229f4d2cd..011541dde3 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -42,7 +42,9 @@ type StateDB interface { GetCodeHash(common.Address) common.Hash GetCode(common.Address) []byte - SetCode(common.Address, []byte) + + // SetCode sets the new code for the address, and returns the previous code, if any. + SetCode(common.Address, []byte) []byte GetCodeSize(common.Address) int AddRefund(uint64) diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index c408994401..996ed6e56a 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -109,6 +109,8 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter { case evm.chainRules.IsVerkle: // TODO replace with proper instruction set when fork is specified table = &verkleInstructionSet + case evm.chainRules.IsPrague: + table = &pragueInstructionSet case evm.chainRules.IsCancun: table = &cancunInstructionSet case evm.chainRules.IsShanghai: diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 658014f24c..6610fa7f9a 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -61,7 +61,8 @@ var ( shanghaiInstructionSet = newShanghaiInstructionSet() cancunInstructionSet = newCancunInstructionSet() verkleInstructionSet = newVerkleInstructionSet() - pragueEOFInstructionSet = newPragueEOFInstructionSet() + pragueInstructionSet = newPragueInstructionSet() + eofInstructionSet = newEOFInstructionSetForTesting() ) // JumpTable contains the EVM opcodes supported at a given fork. @@ -91,16 +92,22 @@ func newVerkleInstructionSet() JumpTable { return validate(instructionSet) } -func NewPragueEOFInstructionSetForTesting() JumpTable { - return newPragueEOFInstructionSet() +func NewEOFInstructionSetForTesting() JumpTable { + return newEOFInstructionSetForTesting() } -func newPragueEOFInstructionSet() JumpTable { - instructionSet := newCancunInstructionSet() +func newEOFInstructionSetForTesting() JumpTable { + instructionSet := newPragueInstructionSet() enableEOF(&instructionSet) return validate(instructionSet) } +func newPragueInstructionSet() JumpTable { + instructionSet := newCancunInstructionSet() + enable7702(&instructionSet) // EIP-7702 Setcode transaction type + return validate(instructionSet) +} + func newCancunInstructionSet() JumpTable { instructionSet := newShanghaiInstructionSet() enable4844(&instructionSet) // EIP-4844 (BLOBHASH opcode) diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index b993b651ff..ff3875868f 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -22,6 +22,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/core/types" "github.com/ethereum/go-ethereum/params" ) @@ -242,3 +243,70 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { } return gasFunc } + +var ( + gasCallEIP7702 = makeCallVariantGasCallEIP7702(gasCall) + gasDelegateCallEIP7702 = makeCallVariantGasCallEIP7702(gasDelegateCall) + gasStaticCallEIP7702 = makeCallVariantGasCallEIP7702(gasStaticCall) + gasCallCodeEIP7702 = makeCallVariantGasCallEIP7702(gasCallCode) +) + +func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc { + return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var ( + total uint64 // total dynamic gas used + addr = common.Address(stack.Back(1).Bytes20()) + ) + + // Check slot presence in the access list + if !evm.StateDB.AddressInAccessList(addr) { + evm.StateDB.AddAddressToAccessList(addr) + // The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost, so + // the cost to charge for cold access, if any, is Cold - Warm + coldCost := params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929 + // Charge the remaining difference here already, to correctly calculate available + // gas for call + if !contract.UseGas(coldCost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { + return 0, ErrOutOfGas + } + total += coldCost + } + + // Check if code is a delegation and if so, charge for resolution. + if target, ok := types.ParseDelegation(evm.StateDB.GetCode(addr)); ok { + var cost uint64 + if evm.StateDB.AddressInAccessList(target) { + cost = params.WarmStorageReadCostEIP2929 + } else { + evm.StateDB.AddAddressToAccessList(target) + cost = params.ColdAccountAccessCostEIP2929 + } + if !contract.UseGas(cost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { + return 0, ErrOutOfGas + } + total += cost + } + + // Now call the old calculator, which takes into account + // - create new account + // - transfer value + // - memory expansion + // - 63/64ths rule + old, err := oldCalculator(evm, contract, stack, mem, memorySize) + if err != nil { + return old, err + } + + // Temporarily add the gas charge back to the contract and return value. By + // adding it to the return, it will be charged outside of this function, as + // part of the dynamic gas. This will ensure it is correctly reported to + // tracers. + contract.Gas += total + + var overflow bool + if total, overflow = math.SafeAdd(old, total); overflow { + return 0, ErrGasUintOverflow + } + return total, nil + } +} diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 0e774a01c2..6074e9a096 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -866,3 +866,83 @@ func BenchmarkTracerStepVsCallFrame(b *testing.B) { benchmarkNonModifyingCode(10000000, code, "tracer-step-10M", stepTracer, b) benchmarkNonModifyingCode(10000000, code, "tracer-call-frame-10M", callFrameTracer, b) } + +// TestDelegatedAccountAccessCost tests that calling an account with an EIP-7702 +// delegation designator incurs the correct amount of gas based on the tracer. +func TestDelegatedAccountAccessCost(t *testing.T) { + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + statedb.SetCode(common.HexToAddress("0xff"), types.AddressToDelegation(common.HexToAddress("0xaa"))) + statedb.SetCode(common.HexToAddress("0xaa"), program.New().Return(0, 0).Bytes()) + + for i, tc := range []struct { + code []byte + step int + want uint64 + }{ + { // CALL(0xff) + code: []byte{ + byte(vm.PUSH1), 0x0, + byte(vm.DUP1), byte(vm.DUP1), byte(vm.DUP1), byte(vm.DUP1), + byte(vm.PUSH1), 0xff, byte(vm.DUP1), byte(vm.CALL), byte(vm.POP), + }, + step: 7, + want: 5455, + }, + { // CALLCODE(0xff) + code: []byte{ + byte(vm.PUSH1), 0x0, + byte(vm.DUP1), byte(vm.DUP1), byte(vm.DUP1), byte(vm.DUP1), + byte(vm.PUSH1), 0xff, byte(vm.DUP1), byte(vm.CALLCODE), byte(vm.POP), + }, + step: 7, + want: 5455, + }, + { // DELEGATECALL(0xff) + code: []byte{ + byte(vm.PUSH1), 0x0, + byte(vm.DUP1), byte(vm.DUP1), byte(vm.DUP1), + byte(vm.PUSH1), 0xff, byte(vm.DUP1), byte(vm.DELEGATECALL), byte(vm.POP), + }, + step: 6, + want: 5455, + }, + { // STATICCALL(0xff) + code: []byte{ + byte(vm.PUSH1), 0x0, + byte(vm.DUP1), byte(vm.DUP1), byte(vm.DUP1), + byte(vm.PUSH1), 0xff, byte(vm.DUP1), byte(vm.STATICCALL), byte(vm.POP), + }, + step: 6, + want: 5455, + }, + { // SELFDESTRUCT(0xff): should not be affected by resolution + code: []byte{ + byte(vm.PUSH1), 0xff, byte(vm.SELFDESTRUCT), + }, + step: 1, + want: 7600, + }, + } { + var step = 0 + var have = uint64(0) + Execute(tc.code, nil, &Config{ + ChainConfig: params.MergedTestChainConfig, + State: statedb, + EVMConfig: vm.Config{ + Tracer: &tracing.Hooks{ + OnOpcode: func(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { + // Uncomment to investigate failures: + t.Logf("%d: %v %d", step, vm.OpCode(op).String(), cost) + if step == tc.step { + have = cost + } + step++ + }, + }, + }, + }) + if want := tc.want; have != want { + t.Fatalf("testcase %d, gas report wrong, step %d, have %d want %d", i, tc.step, have, want) + } + } +} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json new file mode 100644 index 0000000000..b7d5ee1c54 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json @@ -0,0 +1,82 @@ +{ + "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" + }, + "0x000000000000000000000000000000000000aaaa": { + "code": "0x6000600060006000600173703c4b2bd70c169f5717101caee543299fc946c75af1", + "balance": "0x0" + }, + "0x000000000000000000000000000000000000bbbb": { + "code": "0x6042604255", + "balance": "0x0" + }, + "0x703c4b2bd70c169f5717101caee543299fc946c7": { + "balance": "0xde0b6b3a7640000" + }, + "0x71562b71999873db5b286df957af199ec94617f7": { + "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, + "pragueTime": 0, + "terminalTotalDifficulty": 0 + } + }, + "context": { + "number": "316", + "difficulty": "0", + "timestamp": "1709626785", + "gasLimit": "15654443", + "miner": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "7" + }, + "input": "04f90126820539800285012a05f2008307a1209471562b71999873db5b286df957af199ec94617f78080c0f8baf85c82053994000000000000000000000000000000000000aaaa0101a07ed17af7d2d2b9ba7d797a202125bf505b9a0f962a67b3b61b56783d8faf7461a001b73b6e586edc706dce6c074eaec28692fa6359fb3446a2442f36777e1c0669f85a8094000000000000000000000000000000000000bbbb8001a05011890f198f0356a887b0779bde5afa1ed04e6acb1e3f37f8f18c7b6f521b98a056c3fa3456b103f3ef4a0acb4b647b9cab9ec4bc68fbcdf1e10b49fb2bcbcf6101a0167b0ecfc343a497095c22ee4270d3cc3b971cc3599fc73bbff727e0d2ed432da01c003c72306807492bf1150e39b2f79da23b49a4e83eb6e9209ae30d3572368f", + "result": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x272e0528" + }, + "0x703c4b2bd70c169f5717101caee543299fc946c7": { + "balance": "0xde0b6b3a7640000", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000042": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0x71562b71999873db5b286df957af199ec94617f7": { + "balance": "0xde0b6b3a7640000" + } + } +} diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 9706eb43f6..5776275c2b 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -159,6 +159,15 @@ func (t *prestateTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction t.lookupAccount(from) t.lookupAccount(t.to) t.lookupAccount(env.Coinbase) + + // Add accounts with authorizations to the prestate before they get applied. + for _, auth := range tx.AuthList() { + addr, err := auth.Authority() + if err != nil { + continue + } + t.lookupAccount(addr) + } } func (t *prestateTracer) OnTxEnd(receipt *types.Receipt, err error) { diff --git a/graphql/graphql.go b/graphql/graphql.go index 6e364de6d9..7af1adbb4a 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -318,7 +318,7 @@ func (t *Transaction) MaxFeePerGas(ctx context.Context) *hexutil.Big { return nil } switch tx.Type() { - case types.DynamicFeeTxType, types.BlobTxType: + case types.DynamicFeeTxType, types.BlobTxType, types.SetCodeTxType: return (*hexutil.Big)(tx.GasFeeCap()) default: return nil @@ -331,7 +331,7 @@ func (t *Transaction) MaxPriorityFeePerGas(ctx context.Context) *hexutil.Big { return nil } switch tx.Type() { - case types.DynamicFeeTxType, types.BlobTxType: + case types.DynamicFeeTxType, types.BlobTxType, types.SetCodeTxType: return (*hexutil.Big)(tx.GasTipCap()) default: return nil diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index de75c697ef..3f9ce46ddb 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -937,28 +937,29 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *param // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction type RPCTransaction struct { - BlockHash *common.Hash `json:"blockHash"` - BlockNumber *hexutil.Big `json:"blockNumber"` - From common.Address `json:"from"` - Gas hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` - GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` - MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` - Hash common.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` - Nonce hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` - TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` - Value *hexutil.Big `json:"value"` - Type hexutil.Uint64 `json:"type"` - Accesses *types.AccessList `json:"accessList,omitempty"` - ChainID *hexutil.Big `json:"chainId,omitempty"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - YParity *hexutil.Uint64 `json:"yParity,omitempty"` + BlockHash *common.Hash `json:"blockHash"` + BlockNumber *hexutil.Big `json:"blockNumber"` + From common.Address `json:"from"` + Gas hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` + GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` + MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` + Hash common.Hash `json:"hash"` + Input hexutil.Bytes `json:"input"` + Nonce hexutil.Uint64 `json:"nonce"` + To *common.Address `json:"to"` + TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` + Value *hexutil.Big `json:"value"` + Type hexutil.Uint64 `json:"type"` + Accesses *types.AccessList `json:"accessList,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` + BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` + AuthorizationList []types.Authorization `json:"authorizationList,omitempty"` + V *hexutil.Big `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` + YParity *hexutil.Uint64 `json:"yParity,omitempty"` } // newRPCTransaction returns a transaction that will serialize to the RPC @@ -1033,6 +1034,22 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber } result.MaxFeePerBlobGas = (*hexutil.Big)(tx.BlobGasFeeCap()) result.BlobVersionedHashes = tx.BlobHashes() + + case types.SetCodeTxType: + al := tx.AccessList() + yparity := hexutil.Uint64(v.Sign()) + result.Accesses = &al + result.ChainID = (*hexutil.Big)(tx.ChainId()) + result.YParity = &yparity + result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap()) + result.GasTipCap = (*hexutil.Big)(tx.GasTipCap()) + // if the transaction has been mined, compute the effective gas price + if baseFee != nil && blockHash != (common.Hash{}) { + result.GasPrice = (*hexutil.Big)(effectiveGasPrice(tx, baseFee)) + } else { + result.GasPrice = (*hexutil.Big)(tx.GasFeeCap()) + } + result.AuthorizationList = tx.AuthList() } return result } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index ae2ec9f0f0..0303a0a6ea 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -629,12 +629,13 @@ func TestEstimateGas(t *testing.T) { t.Parallel() // Initialize test accounts var ( - accounts = newAccounts(2) + accounts = newAccounts(4) 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), Code: append(types.DelegationPrefix, accounts[3].addr.Bytes()...)}, }, } genBlocks = 10 @@ -819,6 +820,26 @@ func TestEstimateGas(t *testing.T) { blockOverrides: override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))}, expectErr: newRevertError(packRevert("block 11")), }, + // Should be able to send to an EIP-7702 delegated account. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: &accounts[2].addr, + Value: (*hexutil.Big)(big.NewInt(1)), + }, + want: 21000, + }, + // Should be able to send as EIP-7702 delegated account. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[2].addr, + To: &accounts[1].addr, + Value: (*hexutil.Big)(big.NewInt(1)), + }, + want: 21000, + }, } for i, tc := range testSuite { result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides) diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 2a0508b147..3942540b04 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -72,6 +72,9 @@ type TransactionArgs struct { Commitments []kzg4844.Commitment `json:"commitments"` Proofs []kzg4844.Proof `json:"proofs"` + // For SetCodeTxType + AuthorizationList []types.Authorization `json:"authorizationList"` + // This configures whether blobs are allowed to be passed. blobSidecarAllowed bool } @@ -473,6 +476,8 @@ func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck, skipEoA func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { usedType := types.LegacyTxType switch { + case args.AuthorizationList != nil || defaultType == types.SetCodeTxType: + usedType = types.SetCodeTxType case args.BlobHashes != nil || defaultType == types.BlobTxType: usedType = types.BlobTxType case args.MaxFeePerGas != nil || defaultType == types.DynamicFeeTxType: @@ -486,6 +491,28 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { } var data types.TxData switch usedType { + case types.SetCodeTxType: + al := types.AccessList{} + if args.AccessList != nil { + al = *args.AccessList + } + authList := []types.Authorization{} + if args.AuthorizationList != nil { + authList = args.AuthorizationList + } + data = &types.SetCodeTx{ + To: *args.To, + ChainID: args.ChainID.ToInt().Uint64(), + 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, + AuthList: authList, + } + case types.BlobTxType: al := types.AccessList{} if args.AccessList != nil { diff --git a/params/protocol_params.go b/params/protocol_params.go index 90e7487cff..4d2baf8054 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -90,10 +90,11 @@ const ( 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. - TxDataNonZeroGasFrontier uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions. - TxDataNonZeroGasEIP2028 uint64 = 16 // Per byte of non zero data attached to a transaction after EIP 2028 (part in Istanbul) - TxAccessListAddressGas uint64 = 2400 // Per address specified in EIP 2930 access list - TxAccessListStorageKeyGas uint64 = 1900 // Per storage key specified in EIP 2930 access list + TxDataNonZeroGasFrontier uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions. + TxDataNonZeroGasEIP2028 uint64 = 16 // Per byte of non zero data attached to a transaction after EIP 2028 (part in Istanbul) + TxAccessListAddressGas uint64 = 2400 // Per address specified in EIP 2930 access list + TxAccessListStorageKeyGas uint64 = 1900 // Per storage key specified in EIP 2930 access list + TxAuthTupleGas uint64 = 12500 // Per auth tuple code specified in EIP-7702 // These have been changed during the course of the chain CallGasFrontier uint64 = 40 // Once per CALL operation & message call transaction. diff --git a/tests/gen_stauthorization.go b/tests/gen_stauthorization.go new file mode 100644 index 0000000000..fbafd6fdea --- /dev/null +++ b/tests/gen_stauthorization.go @@ -0,0 +1,74 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package tests + +import ( + "encoding/json" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" +) + +var _ = (*stAuthorizationMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (s stAuthorization) MarshalJSON() ([]byte, error) { + type stAuthorization struct { + ChainID math.HexOrDecimal64 + Address common.Address `json:"address" gencodec:"required"` + Nonce math.HexOrDecimal64 `json:"nonce" gencodec:"required"` + V math.HexOrDecimal64 `json:"v" gencodec:"required"` + R *math.HexOrDecimal256 `json:"r" gencodec:"required"` + S *math.HexOrDecimal256 `json:"s" gencodec:"required"` + } + var enc stAuthorization + enc.ChainID = math.HexOrDecimal64(s.ChainID) + enc.Address = s.Address + enc.Nonce = math.HexOrDecimal64(s.Nonce) + enc.V = math.HexOrDecimal64(s.V) + enc.R = (*math.HexOrDecimal256)(s.R) + enc.S = (*math.HexOrDecimal256)(s.S) + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (s *stAuthorization) UnmarshalJSON(input []byte) error { + type stAuthorization struct { + ChainID *math.HexOrDecimal64 + Address *common.Address `json:"address" gencodec:"required"` + Nonce *math.HexOrDecimal64 `json:"nonce" gencodec:"required"` + V *math.HexOrDecimal64 `json:"v" gencodec:"required"` + R *math.HexOrDecimal256 `json:"r" gencodec:"required"` + S *math.HexOrDecimal256 `json:"s" gencodec:"required"` + } + var dec stAuthorization + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.ChainID != nil { + s.ChainID = uint64(*dec.ChainID) + } + if dec.Address == nil { + return errors.New("missing required field 'address' for stAuthorization") + } + s.Address = *dec.Address + if dec.Nonce == nil { + return errors.New("missing required field 'nonce' for stAuthorization") + } + s.Nonce = uint64(*dec.Nonce) + if dec.V == nil { + return errors.New("missing required field 'v' for stAuthorization") + } + s.V = uint8(*dec.V) + if dec.R == nil { + return errors.New("missing required field 'r' for stAuthorization") + } + s.R = (*big.Int)(dec.R) + if dec.S == nil { + return errors.New("missing required field 's' for stAuthorization") + } + s.S = (*big.Int)(dec.S) + return nil +} diff --git a/tests/gen_sttransaction.go b/tests/gen_sttransaction.go index 9b5aecbfe6..b25ce76166 100644 --- a/tests/gen_sttransaction.go +++ b/tests/gen_sttransaction.go @@ -30,6 +30,7 @@ func (s stTransaction) MarshalJSON() ([]byte, error) { Sender *common.Address `json:"sender"` BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` BlobGasFeeCap *math.HexOrDecimal256 `json:"maxFeePerBlobGas,omitempty"` + AuthorizationList []*stAuthorization `json:"authorizationList,omitempty"` } var enc stTransaction enc.GasPrice = (*math.HexOrDecimal256)(s.GasPrice) @@ -50,6 +51,7 @@ func (s stTransaction) MarshalJSON() ([]byte, error) { enc.Sender = s.Sender enc.BlobVersionedHashes = s.BlobVersionedHashes enc.BlobGasFeeCap = (*math.HexOrDecimal256)(s.BlobGasFeeCap) + enc.AuthorizationList = s.AuthorizationList return json.Marshal(&enc) } @@ -69,6 +71,7 @@ func (s *stTransaction) UnmarshalJSON(input []byte) error { Sender *common.Address `json:"sender"` BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` BlobGasFeeCap *math.HexOrDecimal256 `json:"maxFeePerBlobGas,omitempty"` + AuthorizationList []*stAuthorization `json:"authorizationList,omitempty"` } var dec stTransaction if err := json.Unmarshal(input, &dec); err != nil { @@ -116,5 +119,8 @@ func (s *stTransaction) UnmarshalJSON(input []byte) error { if dec.BlobGasFeeCap != nil { s.BlobGasFeeCap = (*big.Int)(dec.BlobGasFeeCap) } + if dec.AuthorizationList != nil { + s.AuthorizationList = dec.AuthorizationList + } return nil } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 6884ae7ed5..e735ce2fb8 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -123,6 +123,7 @@ type stTransaction struct { Sender *common.Address `json:"sender"` BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` BlobGasFeeCap *big.Int `json:"maxFeePerBlobGas,omitempty"` + AuthorizationList []*stAuthorization `json:"authorizationList,omitempty"` } type stTransactionMarshaling struct { @@ -135,6 +136,27 @@ type stTransactionMarshaling struct { BlobGasFeeCap *math.HexOrDecimal256 } +//go:generate go run github.com/fjl/gencodec -type stAuthorization -field-override stAuthorizationMarshaling -out gen_stauthorization.go + +// Authorization is an authorization from an account to deploy code at it's address. +type stAuthorization struct { + ChainID uint64 + Address common.Address `json:"address" gencodec:"required"` + Nonce uint64 `json:"nonce" gencodec:"required"` + V uint8 `json:"v" gencodec:"required"` + R *big.Int `json:"r" gencodec:"required"` + S *big.Int `json:"s" gencodec:"required"` +} + +// field type overrides for gencodec +type stAuthorizationMarshaling struct { + ChainID math.HexOrDecimal64 + Nonce math.HexOrDecimal64 + V math.HexOrDecimal64 + R *math.HexOrDecimal256 + S *math.HexOrDecimal256 +} + // GetChainConfig takes a fork definition and returns a chain config. // The fork definition can be // - a plain forkname, e.g. `Byzantium`, @@ -419,6 +441,20 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess if gasPrice == nil { return nil, errors.New("no gas price provided") } + var authList []types.Authorization + if tx.AuthorizationList != nil { + authList = make([]types.Authorization, len(tx.AuthorizationList)) + for i, auth := range tx.AuthorizationList { + authList[i] = types.Authorization{ + ChainID: auth.ChainID, + Address: auth.Address, + Nonce: auth.Nonce, + V: auth.V, + R: *uint256.MustFromBig(auth.R), + S: *uint256.MustFromBig(auth.S), + } + } + } msg := &core.Message{ From: from, @@ -433,6 +469,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess AccessList: accessList, BlobHashes: tx.BlobVersionedHashes, BlobGasFeeCap: tx.BlobGasFeeCap, + AuthList: authList, } return msg, nil } diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index d3dbbd5db2..4da27ff943 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -59,7 +59,7 @@ func (tt *TransactionTest) Run(config *params.ChainConfig) error { return nil, nil, err } // Intrinsic gas - requiredGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, isHomestead, isIstanbul, false) + requiredGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.AuthList(), tx.To() == nil, isHomestead, isIstanbul, false) if err != nil { return nil, nil, err } From bc1ec69008174aa2f5fd3642adeafb0459d2464b Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Mon, 16 Dec 2024 21:10:08 +0800 Subject: [PATCH 013/940] trie/pathdb: state iterator (snapshot integration pt 4) (#30654) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this pull request, the state iterator is implemented. It's mostly a copy-paste from the original state snapshot package, but still has some important changes to highlight here: (a) The iterator for the disk layer consists of a diff iterator and a disk iterator. Originally, the disk layer in the state snapshot was a wrapper around the disk, and its corresponding iterator was also a wrapper around the disk iterator. However, due to structural differences, the disk layer iterator is divided into two parts: - The disk iterator, which traverses the content stored on disk. - The diff iterator, which traverses the aggregated state buffer. Checkout `BinaryIterator` and `FastIterator` for more details. (b) The staleness management is improved in the diffAccountIterator and diffStorageIterator Originally, in the `diffAccountIterator`, the layer’s staleness had to be checked within the Next function to ensure the iterator remained usable. Additionally, a read lock on the associated diff layer was required to first retrieve the account blob. This read lock protection is essential to prevent concurrent map read/write. Afterward, a staleness check was performed to ensure the retrieved data was not outdated. The entire logic can be simplified as follows: a loadAccount callback is provided to retrieve account data. If the corresponding state is immutable (e.g., diff layers in the path database), the staleness check can be skipped, and a single account data retrieval is sufficient. However, if the corresponding state is mutable (e.g., the disk layer in the path database), the callback can operate as follows: ```go func(hash common.Hash) ([]byte, error) { dl.lock.RLock() defer dl.lock.RUnlock() if dl.stale { return nil, errSnapshotStale } return dl.buffer.states.mustAccount(hash) } ``` The callback solution can eliminate the complexity for managing concurrency with the read lock for atomic operation. --- triedb/pathdb/database.go | 12 + triedb/pathdb/holdable_iterator.go | 97 ++ triedb/pathdb/holdable_iterator_test.go | 176 ++++ triedb/pathdb/iterator.go | 369 +++++++ triedb/pathdb/iterator_binary.go | 344 +++++++ triedb/pathdb/iterator_fast.go | 380 ++++++++ triedb/pathdb/iterator_test.go | 1162 +++++++++++++++++++++++ triedb/pathdb/reader.go | 11 + triedb/pathdb/states.go | 28 +- triedb/pathdb/states_test.go | 118 +-- 10 files changed, 2634 insertions(+), 63 deletions(-) create mode 100644 triedb/pathdb/holdable_iterator.go create mode 100644 triedb/pathdb/holdable_iterator_test.go create mode 100644 triedb/pathdb/iterator.go create mode 100644 triedb/pathdb/iterator_binary.go create mode 100644 triedb/pathdb/iterator_fast.go create mode 100644 triedb/pathdb/iterator_test.go diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index cfbdb01c49..914b17de5b 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -555,3 +555,15 @@ func (db *Database) StorageHistory(address common.Address, slot common.Hash, sta func (db *Database) HistoryRange() (uint64, uint64, error) { return historyRange(db.freezer) } + +// AccountIterator creates a new account iterator for the specified root hash and +// seeks to a starting account hash. +func (db *Database) AccountIterator(root common.Hash, seek common.Hash) (AccountIterator, error) { + return newFastAccountIterator(db, root, seek) +} + +// StorageIterator creates a new storage iterator for the specified root hash and +// account. The iterator will be moved to the specific start position. +func (db *Database) StorageIterator(root common.Hash, account common.Hash, seek common.Hash) (StorageIterator, error) { + return newFastStorageIterator(db, root, account, seek) +} diff --git a/triedb/pathdb/holdable_iterator.go b/triedb/pathdb/holdable_iterator.go new file mode 100644 index 0000000000..1f8e6b7068 --- /dev/null +++ b/triedb/pathdb/holdable_iterator.go @@ -0,0 +1,97 @@ +// 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 ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" +) + +// holdableIterator is a wrapper of underlying database iterator. It extends +// the basic iterator interface by adding Hold which can hold the element +// locally where the iterator is currently located and serve it up next time. +type holdableIterator struct { + it ethdb.Iterator + key []byte + val []byte + atHeld bool +} + +// newHoldableIterator initializes the holdableIterator with the given iterator. +func newHoldableIterator(it ethdb.Iterator) *holdableIterator { + return &holdableIterator{it: it} +} + +// Hold holds the element locally where the iterator is currently located which +// can be served up next time. +func (it *holdableIterator) Hold() { + if it.it.Key() == nil { + return // nothing to hold + } + it.key = common.CopyBytes(it.it.Key()) + it.val = common.CopyBytes(it.it.Value()) + it.atHeld = false +} + +// Next moves the iterator to the next key/value pair. It returns whether the +// iterator is exhausted. +func (it *holdableIterator) Next() bool { + if !it.atHeld && it.key != nil { + it.atHeld = true + } else if it.atHeld { + it.atHeld = false + it.key = nil + it.val = nil + } + if it.key != nil { + return true // shifted to locally held value + } + return it.it.Next() +} + +// Error returns any accumulated error. Exhausting all the key/value pairs +// is not considered to be an error. +func (it *holdableIterator) Error() error { return it.it.Error() } + +// Release releases associated resources. Release should always succeed and can +// be called multiple times without causing error. +func (it *holdableIterator) Release() { + it.atHeld = false + it.key = nil + it.val = nil + it.it.Release() +} + +// Key returns the key of the current key/value pair, or nil if done. The caller +// should not modify the contents of the returned slice, and its contents may +// change on the next call to Next. +func (it *holdableIterator) Key() []byte { + if it.key != nil { + return it.key + } + return it.it.Key() +} + +// Value returns the value of the current key/value pair, or nil if done. The +// caller should not modify the contents of the returned slice, and its contents +// may change on the next call to Next. +func (it *holdableIterator) Value() []byte { + if it.val != nil { + return it.val + } + return it.it.Value() +} diff --git a/triedb/pathdb/holdable_iterator_test.go b/triedb/pathdb/holdable_iterator_test.go new file mode 100644 index 0000000000..2abc92e154 --- /dev/null +++ b/triedb/pathdb/holdable_iterator_test.go @@ -0,0 +1,176 @@ +// 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 ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/ethdb/memorydb" +) + +func TestIteratorHold(t *testing.T) { + // Create the key-value data store + var ( + content = map[string]string{"k1": "v1", "k2": "v2", "k3": "v3"} + order = []string{"k1", "k2", "k3"} + db = rawdb.NewMemoryDatabase() + ) + for key, val := range content { + if err := db.Put([]byte(key), []byte(val)); err != nil { + t.Fatalf("failed to insert item %s:%s into database: %v", key, val, err) + } + } + // Iterate over the database with the given configs and verify the results + it, idx := newHoldableIterator(db.NewIterator(nil, nil)), 0 + + // Nothing should be affected for calling Discard on non-initialized iterator + it.Hold() + + for it.Next() { + if len(content) <= idx { + t.Errorf("more items than expected: checking idx=%d (key %q), expecting len=%d", idx, it.Key(), len(order)) + break + } + if !bytes.Equal(it.Key(), []byte(order[idx])) { + t.Errorf("item %d: key mismatch: have %s, want %s", idx, string(it.Key()), order[idx]) + } + if !bytes.Equal(it.Value(), []byte(content[order[idx]])) { + t.Errorf("item %d: value mismatch: have %s, want %s", idx, string(it.Value()), content[order[idx]]) + } + // Should be safe to call discard multiple times + it.Hold() + it.Hold() + + // Shift iterator to the discarded element + it.Next() + if !bytes.Equal(it.Key(), []byte(order[idx])) { + t.Errorf("item %d: key mismatch: have %s, want %s", idx, string(it.Key()), order[idx]) + } + if !bytes.Equal(it.Value(), []byte(content[order[idx]])) { + t.Errorf("item %d: value mismatch: have %s, want %s", idx, string(it.Value()), content[order[idx]]) + } + + // Discard/Next combo should work always + it.Hold() + it.Next() + if !bytes.Equal(it.Key(), []byte(order[idx])) { + t.Errorf("item %d: key mismatch: have %s, want %s", idx, string(it.Key()), order[idx]) + } + if !bytes.Equal(it.Value(), []byte(content[order[idx]])) { + t.Errorf("item %d: value mismatch: have %s, want %s", idx, string(it.Value()), content[order[idx]]) + } + idx++ + } + if err := it.Error(); err != nil { + t.Errorf("iteration failed: %v", err) + } + if idx != len(order) { + t.Errorf("iteration terminated prematurely: have %d, want %d", idx, len(order)) + } + db.Close() +} + +func TestReopenIterator(t *testing.T) { + var ( + content = map[common.Hash]string{ + common.HexToHash("a1"): "v1", + common.HexToHash("a2"): "v2", + common.HexToHash("a3"): "v3", + common.HexToHash("a4"): "v4", + common.HexToHash("a5"): "v5", + common.HexToHash("a6"): "v6", + } + order = []common.Hash{ + common.HexToHash("a1"), + common.HexToHash("a2"), + common.HexToHash("a3"), + common.HexToHash("a4"), + common.HexToHash("a5"), + common.HexToHash("a6"), + } + db = rawdb.NewMemoryDatabase() + + reopen = func(db ethdb.KeyValueStore, iter *holdableIterator) *holdableIterator { + if !iter.Next() { + iter.Release() + return newHoldableIterator(memorydb.New().NewIterator(nil, nil)) + } + next := iter.Key() + iter.Release() + return newHoldableIterator(db.NewIterator(rawdb.SnapshotAccountPrefix, next[1:])) + } + ) + for key, val := range content { + rawdb.WriteAccountSnapshot(db, key, []byte(val)) + } + checkVal := func(it *holdableIterator, index int) { + if !bytes.Equal(it.Key(), append(rawdb.SnapshotAccountPrefix, order[index].Bytes()...)) { + t.Fatalf("Unexpected data entry key, want %v got %v", order[index], it.Key()) + } + if !bytes.Equal(it.Value(), []byte(content[order[index]])) { + t.Fatalf("Unexpected data entry key, want %v got %v", []byte(content[order[index]]), it.Value()) + } + } + // Iterate over the database with the given configs and verify the results + dbIter := db.NewIterator(rawdb.SnapshotAccountPrefix, nil) + iter, idx := newHoldableIterator(rawdb.NewKeyLengthIterator(dbIter, 1+common.HashLength)), -1 + + idx++ + iter.Next() + checkVal(iter, idx) + + iter = reopen(db, iter) + idx++ + iter.Next() + checkVal(iter, idx) + + // reopen twice + iter = reopen(db, iter) + iter = reopen(db, iter) + idx++ + iter.Next() + checkVal(iter, idx) + + // reopen iterator with held value + iter.Next() + iter.Hold() + iter = reopen(db, iter) + idx++ + iter.Next() + checkVal(iter, idx) + + // reopen twice iterator with held value + iter.Next() + iter.Hold() + iter = reopen(db, iter) + iter = reopen(db, iter) + idx++ + iter.Next() + checkVal(iter, idx) + + // shift to the end and reopen + iter.Next() // the end + iter = reopen(db, iter) + iter.Next() + if iter.Key() != nil { + t.Fatal("Unexpected iterated entry") + } +} diff --git a/triedb/pathdb/iterator.go b/triedb/pathdb/iterator.go new file mode 100644 index 0000000000..980f228cf5 --- /dev/null +++ b/triedb/pathdb/iterator.go @@ -0,0 +1,369 @@ +// 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 ( + "bytes" + "fmt" + "sort" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" +) + +// Iterator is an iterator to step over all the accounts or the specific +// storage in a snapshot which may or may not be composed of multiple layers. +type Iterator interface { + // Next steps the iterator forward one element, returning false if exhausted, + // or an error if iteration failed for some reason (e.g. root being iterated + // becomes stale and garbage collected). + Next() bool + + // Error returns any failure that occurred during iteration, which might have + // caused a premature iteration exit (e.g. layer stack becoming stale). + Error() error + + // Hash returns the hash of the account or storage slot the iterator is + // currently at. + Hash() common.Hash + + // Release releases associated resources. Release should always succeed and + // can be called multiple times without causing error. + Release() +} + +// AccountIterator is an iterator to step over all the accounts in a snapshot, +// which may or may not be composed of multiple layers. +type AccountIterator interface { + Iterator + + // Account returns the RLP encoded slim account the iterator is currently at. + // An error will be returned if the iterator becomes invalid + Account() []byte +} + +// StorageIterator is an iterator to step over the specific storage in a snapshot, +// which may or may not be composed of multiple layers. +type StorageIterator interface { + Iterator + + // Slot returns the storage slot the iterator is currently at. An error will + // be returned if the iterator becomes invalid + Slot() []byte +} + +type ( + // loadAccount is the function to retrieve the account from the associated + // layer. An error will be returned if the associated layer is stale. + loadAccount func(hash common.Hash) ([]byte, error) + + // loadStorage is the function to retrieve the storage slot from the associated + // layer. An error will be returned if the associated layer is stale. + loadStorage func(addrHash common.Hash, slotHash common.Hash) ([]byte, error) +) + +// diffAccountIterator is an account iterator that steps over the accounts (both +// live and deleted) contained within a state set. Higher order iterators will +// use the deleted accounts to skip deeper iterators. +// +// This iterator could be created from the diff layer or the disk layer (the +// aggregated state buffer). +type diffAccountIterator struct { + curHash common.Hash // The current hash the iterator is positioned on + keys []common.Hash // Keys left in the layer to iterate + fail error // Any failures encountered (stale) + loadFn loadAccount // Function to retrieve the account from with supplied hash +} + +// newDiffAccountIterator creates an account iterator over the given state set. +func newDiffAccountIterator(seek common.Hash, states *stateSet, fn loadAccount) AccountIterator { + // Seek out the requested starting account + hashes := states.accountList() + index := sort.Search(len(hashes), func(i int) bool { + return bytes.Compare(seek[:], hashes[i][:]) <= 0 + }) + // Assemble and returned the already seeked iterator + return &diffAccountIterator{ + keys: hashes[index:], + loadFn: fn, + } +} + +// Next steps the iterator forward one element, returning false if exhausted. +func (it *diffAccountIterator) Next() bool { + // If the iterator was already stale, consider it a programmer error. Although + // we could just return false here, triggering this path would probably mean + // somebody forgot to check for Error, so lets blow up instead of undefined + // behavior that's hard to debug. + if it.fail != nil { + panic(fmt.Sprintf("called Next of failed iterator: %v", it.fail)) + } + // Stop iterating if all keys were exhausted + if len(it.keys) == 0 { + return false + } + // Iterator seems to be still alive, retrieve and cache the live hash + it.curHash = it.keys[0] + + // key cached, shift the iterator and notify the user of success + it.keys = it.keys[1:] + return true +} + +// Error returns any failure that occurred during iteration, which might have +// caused a premature iteration exit (e.g. the linked state set becoming stale). +func (it *diffAccountIterator) Error() error { + return it.fail +} + +// Hash returns the hash of the account the iterator is currently at. +func (it *diffAccountIterator) Hash() common.Hash { + return it.curHash +} + +// Account returns the RLP encoded slim account the iterator is currently at. +// This method may fail if the associated state goes stale. An error will +// be set to it.fail just in case. +// +// Note the returned account is not a copy, please don't modify it. +func (it *diffAccountIterator) Account() []byte { + blob, err := it.loadFn(it.curHash) + if err != nil { + it.fail = err + return nil + } + return blob +} + +// Release is a noop for diff account iterators as there are no held resources. +func (it *diffAccountIterator) Release() {} + +// diskAccountIterator is an account iterator that steps over the persistent +// accounts within the database. +// +// To simplify, the staleness of the persistent state is not tracked. The disk +// iterator is not intended to be used alone. It should always be wrapped with +// a diff iterator, as the bottom-most disk layer uses both the in-memory +// aggregated buffer and the persistent disk layer as the data sources. The +// staleness of the diff iterator is sufficient to invalidate the iterator pair. +type diskAccountIterator struct { + it ethdb.Iterator +} + +// newDiskAccountIterator creates an account iterator over the persistent state. +func newDiskAccountIterator(db ethdb.KeyValueStore, seek common.Hash) AccountIterator { + pos := common.TrimRightZeroes(seek[:]) + return &diskAccountIterator{ + it: db.NewIterator(rawdb.SnapshotAccountPrefix, pos), + } +} + +// Next steps the iterator forward one element, returning false if exhausted. +func (it *diskAccountIterator) Next() bool { + // If the iterator was already exhausted, don't bother + if it.it == nil { + return false + } + // Try to advance the iterator and release it if we reached the end + for { + if !it.it.Next() { + it.it.Release() + it.it = nil + return false + } + if len(it.it.Key()) == len(rawdb.SnapshotAccountPrefix)+common.HashLength { + break + } + } + return true +} + +// Error returns any failure that occurred during iteration, which might have +// caused a premature iteration exit. (e.g, any error occurred in the database) +func (it *diskAccountIterator) Error() error { + if it.it == nil { + return nil // Iterator is exhausted and released + } + return it.it.Error() +} + +// Hash returns the hash of the account the iterator is currently at. +func (it *diskAccountIterator) Hash() common.Hash { + return common.BytesToHash(it.it.Key()) // The prefix will be truncated +} + +// Account returns the RLP encoded slim account the iterator is currently at. +func (it *diskAccountIterator) Account() []byte { + return it.it.Value() +} + +// Release releases the database snapshot held during iteration. +func (it *diskAccountIterator) Release() { + // The iterator is auto-released on exhaustion, so make sure it's still alive + if it.it != nil { + it.it.Release() + it.it = nil + } +} + +// diffStorageIterator is a storage iterator that steps over the specific storage +// (both live and deleted) contained within a state set. Higher order iterators +// will use the deleted slot to skip deeper iterators. +// +// This iterator could be created from the diff layer or the disk layer (the +// aggregated state buffer). +type diffStorageIterator struct { + curHash common.Hash // The current slot hash the iterator is positioned on + account common.Hash // The account hash the storage slots belonging to + keys []common.Hash // Keys left in the layer to iterate + fail error // Any failures encountered (stale) + loadFn loadStorage // Function to retrieve the storage slot from with supplied hash +} + +// newDiffStorageIterator creates a storage iterator over a single diff layer. +func newDiffStorageIterator(account common.Hash, seek common.Hash, states *stateSet, fn loadStorage) StorageIterator { + hashes := states.storageList(account) + index := sort.Search(len(hashes), func(i int) bool { + return bytes.Compare(seek[:], hashes[i][:]) <= 0 + }) + // Assemble and returned the already seeked iterator + return &diffStorageIterator{ + account: account, + keys: hashes[index:], + loadFn: fn, + } +} + +// Next steps the iterator forward one element, returning false if exhausted. +func (it *diffStorageIterator) Next() bool { + // If the iterator was already stale, consider it a programmer error. Although + // we could just return false here, triggering this path would probably mean + // somebody forgot to check for Error, so lets blow up instead of undefined + // behavior that's hard to debug. + if it.fail != nil { + panic(fmt.Sprintf("called Next of failed iterator: %v", it.fail)) + } + // Stop iterating if all keys were exhausted + if len(it.keys) == 0 { + return false + } + // Iterator seems to be still alive, retrieve and cache the live hash + it.curHash = it.keys[0] + + // key cached, shift the iterator and notify the user of success + it.keys = it.keys[1:] + return true +} + +// Error returns any failure that occurred during iteration, which might have +// caused a premature iteration exit (e.g. the state set becoming stale). +func (it *diffStorageIterator) Error() error { + return it.fail +} + +// Hash returns the hash of the storage slot the iterator is currently at. +func (it *diffStorageIterator) Hash() common.Hash { + return it.curHash +} + +// Slot returns the raw storage slot value the iterator is currently at. +// This method may fail if the associated state goes stale. An error will +// be set to it.fail just in case. +// +// Note the returned slot is not a copy, please don't modify it. +func (it *diffStorageIterator) Slot() []byte { + storage, err := it.loadFn(it.account, it.curHash) + if err != nil { + it.fail = err + return nil + } + return storage +} + +// Release is a noop for diff account iterators as there are no held resources. +func (it *diffStorageIterator) Release() {} + +// diskStorageIterator is a storage iterator that steps over the persistent +// storage slots contained within the database. +// +// To simplify, the staleness of the persistent state is not tracked. The disk +// iterator is not intended to be used alone. It should always be wrapped with +// a diff iterator, as the bottom-most disk layer uses both the in-memory +// aggregated buffer and the persistent disk layer as the data sources. The +// staleness of the diff iterator is sufficient to invalidate the iterator pair. +type diskStorageIterator struct { + account common.Hash + it ethdb.Iterator +} + +// StorageIterator creates a storage iterator over the persistent state. +func newDiskStorageIterator(db ethdb.KeyValueStore, account common.Hash, seek common.Hash) StorageIterator { + pos := common.TrimRightZeroes(seek[:]) + return &diskStorageIterator{ + account: account, + it: db.NewIterator(append(rawdb.SnapshotStoragePrefix, account.Bytes()...), pos), + } +} + +// Next steps the iterator forward one element, returning false if exhausted. +func (it *diskStorageIterator) Next() bool { + // If the iterator was already exhausted, don't bother + if it.it == nil { + return false + } + // Try to advance the iterator and release it if we reached the end + for { + if !it.it.Next() { + it.it.Release() + it.it = nil + return false + } + if len(it.it.Key()) == len(rawdb.SnapshotStoragePrefix)+common.HashLength+common.HashLength { + break + } + } + return true +} + +// Error returns any failure that occurred during iteration, which might have +// caused a premature iteration exit (e.g. the error occurred in the database). +func (it *diskStorageIterator) Error() error { + if it.it == nil { + return nil // Iterator is exhausted and released + } + return it.it.Error() +} + +// Hash returns the hash of the storage slot the iterator is currently at. +func (it *diskStorageIterator) Hash() common.Hash { + return common.BytesToHash(it.it.Key()) // The prefix will be truncated +} + +// Slot returns the raw storage slot content the iterator is currently at. +func (it *diskStorageIterator) Slot() []byte { + return it.it.Value() +} + +// Release releases the database snapshot held during iteration. +func (it *diskStorageIterator) Release() { + // The iterator is auto-released on exhaustion, so make sure it's still alive + if it.it != nil { + it.it.Release() + it.it = nil + } +} diff --git a/triedb/pathdb/iterator_binary.go b/triedb/pathdb/iterator_binary.go new file mode 100644 index 0000000000..dec31e8f3f --- /dev/null +++ b/triedb/pathdb/iterator_binary.go @@ -0,0 +1,344 @@ +// 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 ( + "bytes" + + "github.com/ethereum/go-ethereum/common" +) + +// binaryIterator is a simplistic iterator to step over the accounts or storage +// in a snapshot, which may or may not be composed of multiple layers. Performance +// wise this iterator is slow, it's meant for cross validating the fast one. +// +// This iterator cannot be used on its own; it should be wrapped with an outer +// iterator, such as accountBinaryIterator or storageBinaryIterator. +// +// This iterator can only traverse the keys of the entries stored in the layers, +// but cannot obtain the corresponding values. Besides, the deleted entry will +// also be traversed, the outer iterator must check the emptiness before returning. +type binaryIterator struct { + a Iterator + b Iterator + aDone bool + bDone bool + k common.Hash + fail error +} + +// initBinaryAccountIterator creates a simplistic iterator to step over all the +// accounts in a slow, but easily verifiable way. Note this function is used +// for initialization, use `newBinaryAccountIterator` as the API. +func (dl *diskLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator { + // Create two iterators for state buffer and the persistent state in disk + // respectively and combine them as a binary iterator. + l := &binaryIterator{ + // The account loader function is unnecessary; the account key list + // produced by the supplied buffer alone is sufficient for iteration. + // + // The account key list for iteration is deterministic once the iterator + // is constructed, no matter the referenced disk layer is stale or not + // later. + a: newDiffAccountIterator(seek, dl.buffer.states, nil), + b: newDiskAccountIterator(dl.db.diskdb, seek), + } + l.aDone = !l.a.Next() + l.bDone = !l.b.Next() + return l +} + +// initBinaryAccountIterator creates a simplistic iterator to step over all the +// accounts in a slow, but easily verifiable way. Note this function is used +// for initialization, use `newBinaryAccountIterator` as the API. +func (dl *diffLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator { + parent, ok := dl.parent.(*diffLayer) + if !ok { + l := &binaryIterator{ + // The account loader function is unnecessary; the account key list + // produced by the supplied state set alone is sufficient for iteration. + // + // The account key list for iteration is deterministic once the iterator + // is constructed, no matter the referenced disk layer is stale or not + // later. + a: newDiffAccountIterator(seek, dl.states.stateSet, nil), + b: dl.parent.(*diskLayer).initBinaryAccountIterator(seek), + } + l.aDone = !l.a.Next() + l.bDone = !l.b.Next() + return l + } + l := &binaryIterator{ + // The account loader function is unnecessary; the account key list + // produced by the supplied state set alone is sufficient for iteration. + // + // The account key list for iteration is deterministic once the iterator + // is constructed, no matter the referenced disk layer is stale or not + // later. + a: newDiffAccountIterator(seek, dl.states.stateSet, nil), + b: parent.initBinaryAccountIterator(seek), + } + l.aDone = !l.a.Next() + l.bDone = !l.b.Next() + return l +} + +// initBinaryStorageIterator creates a simplistic iterator to step over all the +// storage slots in a slow, but easily verifiable way. Note this function is used +// for initialization, use `newBinaryStorageIterator` as the API. +func (dl *diskLayer) initBinaryStorageIterator(account common.Hash, seek common.Hash) *binaryIterator { + // Create two iterators for state buffer and the persistent state in disk + // respectively and combine them as a binary iterator. + l := &binaryIterator{ + // The storage loader function is unnecessary; the storage key list + // produced by the supplied buffer alone is sufficient for iteration. + // + // The storage key list for iteration is deterministic once the iterator + // is constructed, no matter the referenced disk layer is stale or not + // later. + a: newDiffStorageIterator(account, seek, dl.buffer.states, nil), + b: newDiskStorageIterator(dl.db.diskdb, account, seek), + } + l.aDone = !l.a.Next() + l.bDone = !l.b.Next() + return l +} + +// initBinaryStorageIterator creates a simplistic iterator to step over all the +// storage slots in a slow, but easily verifiable way. Note this function is used +// for initialization, use `newBinaryStorageIterator` as the API. +func (dl *diffLayer) initBinaryStorageIterator(account common.Hash, seek common.Hash) *binaryIterator { + parent, ok := dl.parent.(*diffLayer) + if !ok { + l := &binaryIterator{ + // The storage loader function is unnecessary; the storage key list + // produced by the supplied state set alone is sufficient for iteration. + // + // The storage key list for iteration is deterministic once the iterator + // is constructed, no matter the referenced disk layer is stale or not + // later. + a: newDiffStorageIterator(account, seek, dl.states.stateSet, nil), + b: dl.parent.(*diskLayer).initBinaryStorageIterator(account, seek), + } + l.aDone = !l.a.Next() + l.bDone = !l.b.Next() + return l + } + l := &binaryIterator{ + // The storage loader function is unnecessary; the storage key list + // produced by the supplied state set alone is sufficient for iteration. + // + // The storage key list for iteration is deterministic once the iterator + // is constructed, no matter the referenced disk layer is stale or not + // later. + a: newDiffStorageIterator(account, seek, dl.states.stateSet, nil), + b: parent.initBinaryStorageIterator(account, seek), + } + l.aDone = !l.a.Next() + l.bDone = !l.b.Next() + return l +} + +// Next advances the iterator by one element, returning false if both iterators +// are exhausted. Note that the entry pointed to by the iterator may be null +// (e.g., when an account is deleted but still accessible for iteration). +// The outer iterator must verify emptiness before terminating the iteration. +// +// There’s no need to check for errors in the two iterators, as we only iterate +// through the entries without retrieving their values. +func (it *binaryIterator) Next() bool { + if it.aDone && it.bDone { + return false + } + for { + if it.aDone { + it.k = it.b.Hash() + it.bDone = !it.b.Next() + return true + } + if it.bDone { + it.k = it.a.Hash() + it.aDone = !it.a.Next() + return true + } + nextA, nextB := it.a.Hash(), it.b.Hash() + if diff := bytes.Compare(nextA[:], nextB[:]); diff < 0 { + it.aDone = !it.a.Next() + it.k = nextA + return true + } else if diff == 0 { + // Now we need to advance one of them + it.aDone = !it.a.Next() + continue + } + it.bDone = !it.b.Next() + it.k = nextB + return true + } +} + +// Error returns any failure that occurred during iteration, which might have +// caused a premature iteration exit (e.g. snapshot stack becoming stale). +func (it *binaryIterator) Error() error { + return it.fail +} + +// Hash returns the hash of the account the iterator is currently at. +func (it *binaryIterator) Hash() common.Hash { + return it.k +} + +// Release recursively releases all the iterators in the stack. +func (it *binaryIterator) Release() { + it.a.Release() + it.b.Release() +} + +// accountBinaryIterator is a wrapper around a binary iterator that adds functionality +// to retrieve account data from the associated layer at the current position. +type accountBinaryIterator struct { + *binaryIterator + layer layer +} + +// newBinaryAccountIterator creates a simplistic account iterator to step over +// all the accounts in a slow, but easily verifiable way. +// +// nolint:all +func (dl *diskLayer) newBinaryAccountIterator(seek common.Hash) AccountIterator { + return &accountBinaryIterator{ + binaryIterator: dl.initBinaryAccountIterator(seek), + layer: dl, + } +} + +// newBinaryAccountIterator creates a simplistic account iterator to step over +// all the accounts in a slow, but easily verifiable way. +func (dl *diffLayer) newBinaryAccountIterator(seek common.Hash) AccountIterator { + return &accountBinaryIterator{ + binaryIterator: dl.initBinaryAccountIterator(seek), + layer: dl, + } +} + +// Next steps the iterator forward one element, returning false if exhausted, +// or an error if iteration failed for some reason (e.g. the linked layer is +// stale during the iteration). +func (it *accountBinaryIterator) Next() bool { + for { + if !it.binaryIterator.Next() { + return false + } + // Retrieve the account data referenced by the current iterator, the + // associated layers might be outdated due to chain progressing, + // the relative error will be set to it.fail just in case. + // + // Skip the null account which was deleted before and move to the + // next account. + if len(it.Account()) != 0 { + return true + } + // it.fail might be set if error occurs by calling it.Account(). + // Stop iteration if so. + if it.fail != nil { + return false + } + } +} + +// Account returns the RLP encoded slim account the iterator is currently at, or +// nil if the iterated snapshot stack became stale (you can check Error after +// to see if it failed or not). +// +// Note the returned account is not a copy, please don't modify it. +func (it *accountBinaryIterator) Account() []byte { + blob, err := it.layer.account(it.k, 0) + if err != nil { + it.fail = err + return nil + } + return blob +} + +// storageBinaryIterator is a wrapper around a binary iterator that adds functionality +// to retrieve storage slot data from the associated layer at the current position. +type storageBinaryIterator struct { + *binaryIterator + account common.Hash + layer layer +} + +// newBinaryStorageIterator creates a simplistic account iterator to step over +// all the storage slots in a slow, but easily verifiable way. +// +// nolint:all +func (dl *diskLayer) newBinaryStorageIterator(account common.Hash, seek common.Hash) StorageIterator { + return &storageBinaryIterator{ + binaryIterator: dl.initBinaryStorageIterator(account, seek), + account: account, + layer: dl, + } +} + +// newBinaryStorageIterator creates a simplistic account iterator to step over +// all the storage slots in a slow, but easily verifiable way. +func (dl *diffLayer) newBinaryStorageIterator(account common.Hash, seek common.Hash) StorageIterator { + return &storageBinaryIterator{ + binaryIterator: dl.initBinaryStorageIterator(account, seek), + account: account, + layer: dl, + } +} + +// Next steps the iterator forward one element, returning false if exhausted, +// or an error if iteration failed for some reason (e.g. the linked layer is +// stale during the iteration). +func (it *storageBinaryIterator) Next() bool { + for { + if !it.binaryIterator.Next() { + return false + } + // Retrieve the storage data referenced by the current iterator, the + // associated layers might be outdated due to chain progressing, + // the relative error will be set to it.fail just in case. + // + // Skip the null storage which was deleted before and move to the + // next account. + if len(it.Slot()) != 0 { + return true + } + // it.fail might be set if error occurs by calling it.Slot(). + // Stop iteration if so. + if it.fail != nil { + return false + } + } +} + +// Slot returns the raw storage slot data the iterator is currently at, or +// nil if the iterated snapshot stack became stale (you can check Error after +// to see if it failed or not). +// +// Note the returned slot is not a copy, please don't modify it. +func (it *storageBinaryIterator) Slot() []byte { + blob, err := it.layer.storage(it.account, it.k, 0) + if err != nil { + it.fail = err + return nil + } + return blob +} diff --git a/triedb/pathdb/iterator_fast.go b/triedb/pathdb/iterator_fast.go new file mode 100644 index 0000000000..217b211fcc --- /dev/null +++ b/triedb/pathdb/iterator_fast.go @@ -0,0 +1,380 @@ +// 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 ( + "bytes" + "fmt" + "slices" + "sort" + + "github.com/ethereum/go-ethereum/common" +) + +// 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 { + it Iterator + priority int +} + +func (it *weightedIterator) Cmp(other *weightedIterator) int { + // Order the iterators primarily by the account hashes + hashI := it.it.Hash() + hashJ := other.it.Hash() + + switch bytes.Compare(hashI[:], hashJ[:]) { + case -1: + return -1 + case 1: + return 1 + } + // Same account/storage-slot in multiple layers, split by priority + if it.priority < other.priority { + return -1 + } + if it.priority > other.priority { + return 1 + } + return 0 +} + +// fastIterator is a more optimized multi-layer iterator which maintains a +// direct mapping of all iterators leading down to the bottom layer. +type fastIterator struct { + curAccount []byte + curSlot []byte + + iterators []*weightedIterator + initiated bool + account bool + fail error +} + +// newFastIterator creates a new hierarchical account or storage iterator with one +// element per diff layer. The returned combo iterator can be used to walk over +// the entire layer stack simultaneously. +func newFastIterator(db *Database, root common.Hash, account common.Hash, seek common.Hash, accountIterator bool) (*fastIterator, error) { + current := db.tree.get(root) + if current == nil { + return nil, fmt.Errorf("unknown layer: %x", root) + } + fi := &fastIterator{ + account: accountIterator, + } + for depth := 0; current != nil; depth++ { + if accountIterator { + switch dl := current.(type) { + case *diskLayer: + fi.iterators = append(fi.iterators, &weightedIterator{ + // The state set in the disk layer is mutable, and the entire state becomes stale + // if a diff layer above is merged into it. Therefore, staleness must be checked, + // and the storage slot should be retrieved with read lock protection. + it: newDiffAccountIterator(seek, dl.buffer.states, func(hash common.Hash) ([]byte, error) { + dl.lock.RLock() + defer dl.lock.RUnlock() + + if dl.stale { + return nil, errSnapshotStale + } + return dl.buffer.states.mustAccount(hash) + }), + priority: depth, + }) + fi.iterators = append(fi.iterators, &weightedIterator{ + it: newDiskAccountIterator(dl.db.diskdb, seek), + priority: depth + 1, + }) + case *diffLayer: + // The state set in diff layer is immutable and will never be stale, + // so the read lock protection is unnecessary. + fi.iterators = append(fi.iterators, &weightedIterator{ + it: newDiffAccountIterator(seek, dl.states.stateSet, dl.states.mustAccount), + priority: depth, + }) + } + } else { + switch dl := current.(type) { + case *diskLayer: + fi.iterators = append(fi.iterators, &weightedIterator{ + // The state set in the disk layer is mutable, and the entire state becomes stale + // if a diff layer above is merged into it. Therefore, staleness must be checked, + // and the storage slot should be retrieved with read lock protection. + it: newDiffStorageIterator(account, seek, dl.buffer.states, func(addrHash common.Hash, slotHash common.Hash) ([]byte, error) { + dl.lock.RLock() + defer dl.lock.RUnlock() + + if dl.stale { + return nil, errSnapshotStale + } + return dl.buffer.states.mustStorage(addrHash, slotHash) + }), + priority: depth, + }) + fi.iterators = append(fi.iterators, &weightedIterator{ + it: newDiskStorageIterator(dl.db.diskdb, account, seek), + priority: depth + 1, + }) + case *diffLayer: + // The state set in diff layer is immutable and will never be stale, + // so the read lock protection is unnecessary. + fi.iterators = append(fi.iterators, &weightedIterator{ + it: newDiffStorageIterator(account, seek, dl.states.stateSet, dl.states.mustStorage), + priority: depth, + }) + } + } + current = current.parentLayer() + } + fi.init() + return fi, nil +} + +// init walks over all the iterators and resolves any clashes between them, after +// which it prepares the stack for step-by-step iteration. +func (fi *fastIterator) init() { + // Track which account hashes are iterators positioned on + var positioned = make(map[common.Hash]int) + + // Position all iterators and track how many remain live + for i := 0; i < len(fi.iterators); i++ { + // Retrieve the first element and if it clashes with a previous iterator, + // advance either the current one or the old one. Repeat until nothing is + // clashing anymore. + it := fi.iterators[i] + for { + // If the iterator is exhausted, drop it off the end + if !it.it.Next() { + it.it.Release() + last := len(fi.iterators) - 1 + + fi.iterators[i] = fi.iterators[last] + fi.iterators[last] = nil + fi.iterators = fi.iterators[:last] + + i-- + break + } + // The iterator is still alive, check for collisions with previous ones + hash := it.it.Hash() + if other, exist := positioned[hash]; !exist { + positioned[hash] = i + break + } else { + // Iterators collide, one needs to be progressed, use priority to + // determine which. + // + // This whole else-block can be avoided, if we instead + // do an initial priority-sort of the iterators. If we do that, + // then we'll only wind up here if a lower-priority (preferred) iterator + // has the same value, and then we will always just continue. + // However, it costs an extra sort, so it's probably not better + if fi.iterators[other].priority < it.priority { + // The 'it' should be progressed + continue + } else { + // The 'other' should be progressed, swap them + it = fi.iterators[other] + fi.iterators[other], fi.iterators[i] = fi.iterators[i], fi.iterators[other] + continue + } + } + } + } + // Re-sort the entire list + slices.SortFunc(fi.iterators, func(a, b *weightedIterator) int { return a.Cmp(b) }) + fi.initiated = false +} + +// Next steps the iterator forward one element, returning false if exhausted. +func (fi *fastIterator) Next() bool { + if len(fi.iterators) == 0 { + return false + } + if !fi.initiated { + // Don't forward first time -- we had to 'Next' once in order to + // do the sorting already + fi.initiated = true + if fi.account { + fi.curAccount = fi.iterators[0].it.(AccountIterator).Account() + } else { + fi.curSlot = fi.iterators[0].it.(StorageIterator).Slot() + } + if innerErr := fi.iterators[0].it.Error(); innerErr != nil { + fi.fail = innerErr + return false + } + if fi.curAccount != nil || fi.curSlot != nil { + return true + } + // Implicit else: we've hit a nil-account or nil-slot, and need to + // fall through to the loop below to land on something non-nil + } + // If an account or a slot is deleted in one of the layers, the key will + // still be there, but the actual value will be nil. However, the iterator + // should not export nil-values (but instead simply omit the key), so we + // need to loop here until we either + // - get a non-nil value, + // - hit an error, + // - or exhaust the iterator + for { + if !fi.next(0) { + return false // exhausted + } + if fi.account { + fi.curAccount = fi.iterators[0].it.(AccountIterator).Account() + } else { + fi.curSlot = fi.iterators[0].it.(StorageIterator).Slot() + } + if innerErr := fi.iterators[0].it.Error(); innerErr != nil { + fi.fail = innerErr + return false // error + } + if fi.curAccount != nil || fi.curSlot != nil { + break // non-nil value found + } + } + return true +} + +// next handles the next operation internally and should be invoked when we know +// that two elements in the list may have the same value. +// +// For example, if the iterated hashes become [2,3,5,5,8,9,10], then we should +// invoke next(3), which will call Next on elem 3 (the second '5') and will +// cascade along the list, applying the same operation if needed. +func (fi *fastIterator) next(idx int) bool { + // If this particular iterator got exhausted, remove it and return true (the + // next one is surely not exhausted yet, otherwise it would have been removed + // already). + if it := fi.iterators[idx].it; !it.Next() { + it.Release() + + fi.iterators = append(fi.iterators[:idx], fi.iterators[idx+1:]...) + return len(fi.iterators) > 0 + } + // If there's no one left to cascade into, return + if idx == len(fi.iterators)-1 { + return true + } + // We next-ed the iterator at 'idx', now we may have to re-sort that element + var ( + cur, next = fi.iterators[idx], fi.iterators[idx+1] + curHash, nextHash = cur.it.Hash(), next.it.Hash() + ) + if diff := bytes.Compare(curHash[:], nextHash[:]); diff < 0 { + // It is still in correct place + return true + } else if diff == 0 && cur.priority < next.priority { + // So still in correct place, but we need to iterate on the next + fi.next(idx + 1) + return true + } + // At this point, the iterator is in the wrong location, but the remaining + // list is sorted. Find out where to move the item. + clash := -1 + index := sort.Search(len(fi.iterators), func(n int) bool { + // The iterator always advances forward, so anything before the old slot + // is known to be behind us, so just skip them altogether. This actually + // is an important clause since the sort order got invalidated. + if n < idx { + return false + } + if n == len(fi.iterators)-1 { + // Can always place an elem last + return true + } + nextHash := fi.iterators[n+1].it.Hash() + if diff := bytes.Compare(curHash[:], nextHash[:]); diff < 0 { + return true + } else if diff > 0 { + return false + } + // The elem we're placing it next to has the same value, + // so whichever winds up on n+1 will need further iteration + clash = n + 1 + + return cur.priority < fi.iterators[n+1].priority + }) + fi.move(idx, index) + if clash != -1 { + fi.next(clash) + } + return true +} + +// move advances an iterator to another position in the list. +func (fi *fastIterator) move(index, newpos int) { + elem := fi.iterators[index] + copy(fi.iterators[index:], fi.iterators[index+1:newpos+1]) + fi.iterators[newpos] = elem +} + +// Error returns any failure that occurred during iteration, which might have +// caused a premature iteration exit (e.g. snapshot stack becoming stale). +func (fi *fastIterator) Error() error { + return fi.fail +} + +// Hash returns the current key +func (fi *fastIterator) Hash() common.Hash { + return fi.iterators[0].it.Hash() +} + +// Account returns the current account blob. +// Note the returned account is not a copy, please don't modify it. +func (fi *fastIterator) Account() []byte { + return fi.curAccount +} + +// Slot returns the current storage slot. +// Note the returned slot is not a copy, please don't modify it. +func (fi *fastIterator) Slot() []byte { + return fi.curSlot +} + +// Release iterates over all the remaining live layer iterators and releases each +// of them individually. +func (fi *fastIterator) Release() { + for _, it := range fi.iterators { + it.it.Release() + } + fi.iterators = nil +} + +// Debug is a convenience helper during testing +func (fi *fastIterator) Debug() { + for _, it := range fi.iterators { + fmt.Printf("[p=%v v=%v] ", it.priority, it.it.Hash()[0]) + } + fmt.Println() +} + +// newFastAccountIterator creates a new hierarchical account iterator with one +// element per diff layer. The returned combo iterator can be used to walk over +// the entire snapshot diff stack simultaneously. +func newFastAccountIterator(db *Database, root common.Hash, seek common.Hash) (AccountIterator, error) { + return newFastIterator(db, root, common.Hash{}, seek, true) +} + +// newFastStorageIterator creates a new hierarchical storage iterator with one +// element per diff layer. The returned combo iterator can be used to walk over +// the entire snapshot diff stack simultaneously. +func newFastStorageIterator(db *Database, root common.Hash, account common.Hash, seek common.Hash) (StorageIterator, error) { + return newFastIterator(db, root, account, seek, false) +} diff --git a/triedb/pathdb/iterator_test.go b/triedb/pathdb/iterator_test.go new file mode 100644 index 0000000000..48b5870b5b --- /dev/null +++ b/triedb/pathdb/iterator_test.go @@ -0,0 +1,1162 @@ +// 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 ( + "bytes" + "encoding/binary" + "fmt" + "math/rand" + "testing" + + "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/internal/testrand" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/holiman/uint256" +) + +type verifyContent int + +const ( + verifyNothing verifyContent = iota + verifyAccount + verifyStorage +) + +func verifyIterator(t *testing.T, expCount int, it Iterator, verify verifyContent) { + t.Helper() + + var ( + count = 0 + last = common.Hash{} + ) + for it.Next() { + hash := it.Hash() + if bytes.Compare(last[:], hash[:]) >= 0 { + t.Errorf("wrong order: %x >= %x", last, hash) + } + count++ + if verify == verifyAccount && len(it.(AccountIterator).Account()) == 0 { + t.Errorf("iterator returned nil-value for hash %x", hash) + } else if verify == verifyStorage && len(it.(StorageIterator).Slot()) == 0 { + t.Errorf("iterator returned nil-value for hash %x", hash) + } + last = hash + } + if count != expCount { + t.Errorf("iterator count mismatch: have %d, want %d", count, expCount) + } + if err := it.Error(); err != nil { + t.Errorf("iterator failed: %v", err) + } +} + +// randomAccount generates a random account and returns it RLP encoded. +func randomAccount() []byte { + a := &types.StateAccount{ + Balance: uint256.NewInt(rand.Uint64()), + Nonce: rand.Uint64(), + Root: testrand.Hash(), + CodeHash: types.EmptyCodeHash[:], + } + data, _ := rlp.EncodeToBytes(a) + return data +} + +// randomAccountSet generates a set of random accounts with the given strings as +// the account address hashes. +func randomAccountSet(hashes ...string) map[common.Hash][]byte { + accounts := make(map[common.Hash][]byte) + for _, hash := range hashes { + accounts[common.HexToHash(hash)] = randomAccount() + } + return accounts +} + +// randomStorageSet generates a set of random slots with the given strings as +// the slot addresses. +func randomStorageSet(accounts []string, hashes [][]string, nilStorage [][]string) map[common.Hash]map[common.Hash][]byte { + storages := make(map[common.Hash]map[common.Hash][]byte) + for index, account := range accounts { + storages[common.HexToHash(account)] = make(map[common.Hash][]byte) + + if index < len(hashes) { + hashes := hashes[index] + for _, hash := range hashes { + storages[common.HexToHash(account)][common.HexToHash(hash)] = testrand.Bytes(32) + } + } + if index < len(nilStorage) { + nils := nilStorage[index] + for _, hash := range nils { + storages[common.HexToHash(account)][common.HexToHash(hash)] = nil + } + } + } + return storages +} + +// TestAccountIteratorBasics tests some simple single-layer(diff and disk) iteration +func TestAccountIteratorBasics(t *testing.T) { + var ( + accounts = make(map[common.Hash][]byte) + storage = make(map[common.Hash]map[common.Hash][]byte) + ) + // Fill up a parent + for i := 0; i < 100; i++ { + hash := testrand.Hash() + data := testrand.Bytes(32) + accounts[hash] = data + + if rand.Intn(2) == 0 { + accStorage := make(map[common.Hash][]byte) + accStorage[testrand.Hash()] = testrand.Bytes(32) + storage[hash] = accStorage + } + } + states := newStates(accounts, storage) + it := newDiffAccountIterator(common.Hash{}, states, nil) + verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator + + // TODO reenable these tests once the persistent state iteration + // is implemented. + + //db := rawdb.NewMemoryDatabase() + //batch := db.NewBatch() + //states.write(db, batch, nil, nil) + //batch.Write() + //it = newDiskAccountIterator(db, common.Hash{}) + //verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator +} + +// TestStorageIteratorBasics tests some simple single-layer(diff and disk) iteration for storage +func TestStorageIteratorBasics(t *testing.T) { + var ( + nilStorage = make(map[common.Hash]int) + accounts = make(map[common.Hash][]byte) + storage = make(map[common.Hash]map[common.Hash][]byte) + ) + // Fill some random data + for i := 0; i < 10; i++ { + hash := testrand.Hash() + accounts[hash] = testrand.Bytes(32) + + accStorage := make(map[common.Hash][]byte) + var nilstorage int + for i := 0; i < 100; i++ { + if rand.Intn(2) == 0 { + accStorage[testrand.Hash()] = testrand.Bytes(32) + } else { + accStorage[testrand.Hash()] = nil // delete slot + nilstorage += 1 + } + } + storage[hash] = accStorage + nilStorage[hash] = nilstorage + } + states := newStates(accounts, storage) + for account := range accounts { + it := newDiffStorageIterator(account, common.Hash{}, states, nil) + verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator + } + + // TODO reenable these tests once the persistent state iteration + // is implemented. + + //db := rawdb.NewMemoryDatabase() + //batch := db.NewBatch() + //states.write(db, batch, nil, nil) + //batch.Write() + //for account := range accounts { + // it := newDiskStorageIterator(db, account, common.Hash{}) + // verifyIterator(t, 100-nilStorage[account], it, verifyNothing) // Nil is allowed for single layer iterator + //} +} + +type testIterator struct { + values []byte +} + +func newTestIterator(values ...byte) *testIterator { + return &testIterator{values} +} + +func (ti *testIterator) Seek(common.Hash) { + panic("implement me") +} + +func (ti *testIterator) Next() bool { + ti.values = ti.values[1:] + return len(ti.values) > 0 +} + +func (ti *testIterator) Error() error { + return nil +} + +func (ti *testIterator) Hash() common.Hash { + return common.BytesToHash([]byte{ti.values[0]}) +} + +func (ti *testIterator) Account() []byte { + return nil +} + +func (ti *testIterator) Slot() []byte { + return nil +} + +func (ti *testIterator) Release() {} + +func TestFastIteratorBasics(t *testing.T) { + type testCase struct { + lists [][]byte + expKeys []byte + } + for i, tc := range []testCase{ + {lists: [][]byte{{0, 1, 8}, {1, 2, 8}, {2, 9}, {4}, + {7, 14, 15}, {9, 13, 15, 16}}, + expKeys: []byte{0, 1, 2, 4, 7, 8, 9, 13, 14, 15, 16}}, + {lists: [][]byte{{0, 8}, {1, 2, 8}, {7, 14, 15}, {8, 9}, + {9, 10}, {10, 13, 15, 16}}, + expKeys: []byte{0, 1, 2, 7, 8, 9, 10, 13, 14, 15, 16}}, + } { + var iterators []*weightedIterator + for i, data := range tc.lists { + it := newTestIterator(data...) + iterators = append(iterators, &weightedIterator{it, i}) + } + fi := &fastIterator{ + iterators: iterators, + initiated: false, + } + count := 0 + for fi.Next() { + if got, exp := fi.Hash()[31], tc.expKeys[count]; exp != got { + t.Errorf("tc %d, [%d]: got %d exp %d", i, count, got, exp) + } + count++ + } + } +} + +// TestAccountIteratorTraversal tests some simple multi-layer iteration. +func TestAccountIteratorTraversal(t *testing.T) { + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + // Stack three diff layers on top with various overlaps + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 0, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil)) + + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 0, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil)) + + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 0, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil)) + + // Verify the single and multi-layer iterators + head := db.tree.get(common.HexToHash("0x04")) + + // singleLayer: 0xcc, 0xf0, 0xff + it := newDiffAccountIterator(common.Hash{}, head.(*diffLayer).states.stateSet, nil) + verifyIterator(t, 3, it, verifyNothing) + + // binaryIterator: 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xf0, 0xff + verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount) + + // fastIterator: 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xf0, 0xff + it, _ = db.AccountIterator(common.HexToHash("0x04"), common.Hash{}) + verifyIterator(t, 7, it, verifyAccount) + it.Release() + + // TODO reenable these tests once the persistent state iteration + // is implemented. + + // Test after persist some bottom-most layers into the disk, + // the functionalities still work. + //db.tree.cap(common.HexToHash("0x04"), 2) + + //head = db.tree.get(common.HexToHash("0x04")) + //verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount) + // + //it, _ = db.AccountIterator(common.HexToHash("0x04"), common.Hash{}) + //verifyIterator(t, 7, it, verifyAccount) + //it.Release() +} + +func TestStorageIteratorTraversal(t *testing.T) { + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + // Stack three diff layers on top with various overlaps + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 0, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil), nil, nil)) + + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 0, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04", "0x05", "0x06"}}, nil), nil, nil)) + + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 0, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil), nil, nil)) + + // Verify the single and multi-layer iterators + head := db.tree.get(common.HexToHash("0x04")) + + // singleLayer: 0x1, 0x2, 0x3 + diffIter := newDiffStorageIterator(common.HexToHash("0xaa"), common.Hash{}, head.(*diffLayer).states.stateSet, nil) + verifyIterator(t, 3, diffIter, verifyNothing) + + // binaryIterator: 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 + verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}), verifyStorage) + + // fastIterator: 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 + it, _ := db.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) + verifyIterator(t, 6, it, verifyStorage) + it.Release() + + // TODO reenable these tests once the persistent state iteration + // is implemented. + + // Test after persist some bottom-most layers into the disk, + // the functionalities still work. + //db.tree.cap(common.HexToHash("0x04"), 2) + //verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage) + // + //it, _ = db.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) + //verifyIterator(t, 6, it, verifyStorage) + //it.Release() +} + +// TestAccountIteratorTraversalValues tests some multi-layer iteration, where we +// also expect the correct values to show up. +func TestAccountIteratorTraversalValues(t *testing.T) { + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + // Create a batch of account sets to seed subsequent layers with + var ( + a = make(map[common.Hash][]byte) + b = make(map[common.Hash][]byte) + c = make(map[common.Hash][]byte) + d = make(map[common.Hash][]byte) + e = make(map[common.Hash][]byte) + f = make(map[common.Hash][]byte) + g = make(map[common.Hash][]byte) + h = make(map[common.Hash][]byte) + ) + for i := byte(2); i < 0xff; i++ { + a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i)) + if i > 20 && i%2 == 0 { + b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i)) + } + if i%4 == 0 { + c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i)) + } + if i%7 == 0 { + d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i)) + } + if i%8 == 0 { + e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i)) + } + if i > 50 || i < 85 { + f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i)) + } + if i%64 == 0 { + g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i)) + } + if i%128 == 0 { + h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i)) + } + } + // Assemble a stack of snapshots from the account layers + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(a, nil, nil, nil)) + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(b, nil, nil, nil)) + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(c, nil, nil, nil)) + db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(d, nil, nil, nil)) + db.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), 6, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(e, nil, nil, nil)) + db.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), 7, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(f, nil, nil, nil)) + db.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), 8, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(g, nil, nil, nil)) + db.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), 9, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(h, nil, nil, nil)) + + // binaryIterator + r, _ := db.StateReader(common.HexToHash("0x09")) + head := db.tree.get(common.HexToHash("0x09")) + it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + for it.Next() { + hash := it.Hash() + want, err := r.(*reader).AccountRLP(hash) + if err != nil { + t.Fatalf("failed to retrieve expected account: %v", err) + } + if have := it.Account(); !bytes.Equal(want, have) { + t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) + } + } + it.Release() + + // fastIterator + it, _ = db.AccountIterator(common.HexToHash("0x09"), common.Hash{}) + for it.Next() { + hash := it.Hash() + want, err := r.(*reader).AccountRLP(hash) + if err != nil { + t.Fatalf("failed to retrieve expected account: %v", err) + } + if have := it.Account(); !bytes.Equal(want, have) { + t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) + } + } + it.Release() + + // TODO reenable these tests once the persistent state iteration + // is implemented. + + // Test after persist some bottom-most layers into the disk, + // the functionalities still work. + //db.tree.cap(common.HexToHash("0x09"), 2) + // + //it, _ = db.AccountIterator(common.HexToHash("0x09"), common.Hash{}) + //for it.Next() { + // hash := it.Hash() + // account, err := head.Account(hash) + // if err != nil { + // t.Fatalf("failed to retrieve expected account: %v", err) + // } + // want, _ := rlp.EncodeToBytes(account) + // if have := it.Account(); !bytes.Equal(want, have) { + // t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) + // } + //} + //it.Release() +} + +func TestStorageIteratorTraversalValues(t *testing.T) { + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + wrapStorage := func(storage map[common.Hash][]byte) map[common.Hash]map[common.Hash][]byte { + return map[common.Hash]map[common.Hash][]byte{ + common.HexToHash("0xaa"): storage, + } + } + // Create a batch of storage sets to seed subsequent layers with + var ( + a = make(map[common.Hash][]byte) + b = make(map[common.Hash][]byte) + c = make(map[common.Hash][]byte) + d = make(map[common.Hash][]byte) + e = make(map[common.Hash][]byte) + f = make(map[common.Hash][]byte) + g = make(map[common.Hash][]byte) + h = make(map[common.Hash][]byte) + ) + for i := byte(2); i < 0xff; i++ { + a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i)) + if i > 20 && i%2 == 0 { + b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i)) + } + if i%4 == 0 { + c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i)) + } + if i%7 == 0 { + d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i)) + } + if i%8 == 0 { + e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i)) + } + if i > 50 || i < 85 { + f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i)) + } + if i%64 == 0 { + g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i)) + } + if i%128 == 0 { + h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i)) + } + } + // Assemble a stack of snapshots from the account layers + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(a), nil, nil)) + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(b), nil, nil)) + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(c), nil, nil)) + db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(d), nil, nil)) + db.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), 6, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(e), nil, nil)) + db.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), 7, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(f), nil, nil)) + db.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), 8, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(g), nil, nil)) + db.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), 9, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(h), nil, nil)) + + // binaryIterator + r, _ := db.StateReader(common.HexToHash("0x09")) + head := db.tree.get(common.HexToHash("0x09")) + it := head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}) + for it.Next() { + hash := it.Hash() + want, err := r.Storage(common.HexToHash("0xaa"), hash) + if err != nil { + t.Fatalf("failed to retrieve expected account: %v", err) + } + if have := it.Slot(); !bytes.Equal(want, have) { + t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) + } + } + it.Release() + + // fastIterator + it, _ = db.StorageIterator(common.HexToHash("0x09"), common.HexToHash("0xaa"), common.Hash{}) + for it.Next() { + hash := it.Hash() + want, err := r.Storage(common.HexToHash("0xaa"), hash) + if err != nil { + t.Fatalf("failed to retrieve expected storage slot: %v", err) + } + if have := it.Slot(); !bytes.Equal(want, have) { + t.Fatalf("hash %x: slot mismatch: have %x, want %x", hash, have, want) + } + } + it.Release() + + // TODO reenable these tests once the persistent state iteration + // is implemented. + + // Test after persist some bottom-most layers into the disk, + // the functionalities still work. + //db.tree.cap(common.HexToHash("0x09"), 2) + // + //it, _ = db.StorageIterator(common.HexToHash("0x09"), common.HexToHash("0xaa"), common.Hash{}) + //for it.Next() { + // hash := it.Hash() + // want, err := head.Storage(common.HexToHash("0xaa"), hash) + // if err != nil { + // t.Fatalf("failed to retrieve expected slot: %v", err) + // } + // if have := it.Slot(); !bytes.Equal(want, have) { + // t.Fatalf("hash %x: slot mismatch: have %x, want %x", hash, have, want) + // } + //} + //it.Release() +} + +// This testcase is notorious, all layers contain the exact same 200 accounts. +func TestAccountIteratorLargeTraversal(t *testing.T) { + // Create a custom account factory to recreate the same addresses + makeAccounts := func(num int) map[common.Hash][]byte { + accounts := make(map[common.Hash][]byte) + for i := 0; i < num; i++ { + h := common.Hash{} + binary.BigEndian.PutUint64(h[:], uint64(i+1)) + accounts[h] = randomAccount() + } + return accounts + } + // Build up a large stack of snapshots + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + for i := 1; i < 128; i++ { + parent := types.EmptyRootHash + if i == 1 { + parent = common.HexToHash(fmt.Sprintf("0x%02x", i)) + } + db.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), parent, uint64(i), trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(makeAccounts(200), nil, nil, nil)) + } + // Iterate the entire stack and ensure everything is hit only once + head := db.tree.get(common.HexToHash("0x80")) + verifyIterator(t, 200, newDiffAccountIterator(common.Hash{}, head.(*diffLayer).states.stateSet, nil), verifyNothing) + verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount) + + it, _ := db.AccountIterator(common.HexToHash("0x80"), common.Hash{}) + verifyIterator(t, 200, it, verifyAccount) + it.Release() + + // TODO reenable these tests once the persistent state iteration + // is implemented. + + // Test after persist some bottom-most layers into the disk, + // the functionalities still work. + //db.tree.cap(common.HexToHash("0x80"), 2) + // + //verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount) + // + //it, _ = db.AccountIterator(common.HexToHash("0x80"), common.Hash{}) + //verifyIterator(t, 200, it, verifyAccount) + //it.Release() +} + +// TestAccountIteratorFlattening tests what happens when we +// - have a live iterator on child C (parent C1 -> C2 .. CN) +// - flattens C2 all the way into CN +// - continues iterating +func TestAccountIteratorFlattening(t *testing.T) { + config := &Config{ + WriteBufferSize: 10 * 1024, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + // Create a stack of diffs on top + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil)) + + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil)) + + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil)) + + // Create a binary iterator and flatten the data from underneath it + head := db.tree.get(common.HexToHash("0x04")) + bit := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + defer bit.Release() + + // Create a fast iterator and flatten the data from underneath it + fit, _ := db.AccountIterator(common.HexToHash("0x04"), common.Hash{}) + defer fit.Release() + + if err := db.tree.cap(common.HexToHash("0x04"), 1); err != nil { + t.Fatalf("failed to flatten snapshot stack: %v", err) + } + verifyIterator(t, 7, bit, verifyAccount) + verifyIterator(t, 7, fit, verifyAccount) +} + +func TestAccountIteratorSeek(t *testing.T) { + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil)) + + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil)) + + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil)) + + // Account set is now + // 02: aa, ee, f0, ff + // 03: aa, bb, dd, ee, f0 (, f0), ff + // 04: aa, bb, cc, dd, ee, f0 (, f0), ff (, ff) + // Construct various iterators and ensure their traversal is correct + it, _ := db.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xdd")) + defer it.Release() + verifyIterator(t, 3, it, verifyAccount) // expected: ee, f0, ff + + it, _ = db.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xaa")) + defer it.Release() + verifyIterator(t, 4, it, verifyAccount) // expected: aa, ee, f0, ff + + it, _ = db.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xff")) + defer it.Release() + verifyIterator(t, 1, it, verifyAccount) // expected: ff + + it, _ = db.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xff1")) + defer it.Release() + verifyIterator(t, 0, it, verifyAccount) // expected: nothing + + it, _ = db.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xbb")) + defer it.Release() + verifyIterator(t, 6, it, verifyAccount) // expected: bb, cc, dd, ee, f0, ff + + it, _ = db.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xef")) + defer it.Release() + verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff + + it, _ = db.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xf0")) + defer it.Release() + verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff + + it, _ = db.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xff")) + defer it.Release() + verifyIterator(t, 1, it, verifyAccount) // expected: ff + + it, _ = db.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xff1")) + defer it.Release() + verifyIterator(t, 0, it, verifyAccount) // expected: nothing +} + +func TestStorageIteratorSeek(t *testing.T) { + t.Run("fast", func(t *testing.T) { + testStorageIteratorSeek(t, func(db *Database, root, account, seek common.Hash) StorageIterator { + it, _ := db.StorageIterator(root, account, seek) + return it + }) + }) + t.Run("binary", func(t *testing.T) { + testStorageIteratorSeek(t, func(db *Database, root, account, seek common.Hash) StorageIterator { + return db.tree.get(root).(*diffLayer).newBinaryStorageIterator(account, seek) + }) + }) +} + +func testStorageIteratorSeek(t *testing.T, newIterator func(db *Database, root, account, seek common.Hash) StorageIterator) { + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + // Stack three diff layers on top with various overlaps + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil), nil, nil)) + + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x05", "0x06"}}, nil), nil, nil)) + + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x05", "0x08"}}, nil), nil, nil)) + + // Account set is now + // 02: 01, 03, 05 + // 03: 01, 02, 03, 05 (, 05), 06 + // 04: 01(, 01), 02, 03, 05(, 05, 05), 06, 08 + // Construct various iterators and ensure their traversal is correct + it := newIterator(db, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x01")) + defer it.Release() + verifyIterator(t, 3, it, verifyStorage) // expected: 01, 03, 05 + + it = newIterator(db, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x02")) + defer it.Release() + verifyIterator(t, 2, it, verifyStorage) // expected: 03, 05 + + it = newIterator(db, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x5")) + defer it.Release() + verifyIterator(t, 1, it, verifyStorage) // expected: 05 + + it = newIterator(db, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x6")) + defer it.Release() + verifyIterator(t, 0, it, verifyStorage) // expected: nothing + + it = newIterator(db, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x01")) + defer it.Release() + verifyIterator(t, 6, it, verifyStorage) // expected: 01, 02, 03, 05, 06, 08 + + it = newIterator(db, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x05")) + defer it.Release() + verifyIterator(t, 3, it, verifyStorage) // expected: 05, 06, 08 + + it = newIterator(db, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x08")) + defer it.Release() + verifyIterator(t, 1, it, verifyStorage) // expected: 08 + + it = newIterator(db, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x09")) + defer it.Release() + verifyIterator(t, 0, it, verifyStorage) // expected: nothing +} + +// TestAccountIteratorDeletions tests that the iterator behaves correct when there are +// deleted accounts (where the Account() value is nil). The iterator +// should not output any accounts or nil-values for those cases. +func TestAccountIteratorDeletions(t *testing.T) { + t.Run("fast", func(t *testing.T) { + testAccountIteratorDeletions(t, func(db *Database, root, seek common.Hash) AccountIterator { + it, _ := db.AccountIterator(root, seek) + return it + }) + }) + t.Run("binary", func(t *testing.T) { + testAccountIteratorDeletions(t, func(db *Database, root, seek common.Hash) AccountIterator { + return db.tree.get(root).(*diffLayer).newBinaryAccountIterator(seek) + }) + }) +} + +func testAccountIteratorDeletions(t *testing.T, newIterator func(db *Database, root, seek common.Hash) AccountIterator) { + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + // Stack three diff layers on top with various overlaps + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0x11", "0x22", "0x33"), nil, nil, nil)) + + deleted := common.HexToHash("0x22") + accounts := randomAccountSet("0x11", "0x33") + accounts[deleted] = nil + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(accounts, nil, nil, nil)) + + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0x33", "0x44", "0x55"), nil, nil, nil)) + + // The output should be 11,33,44,55 + it := newIterator(db, common.HexToHash("0x04"), common.Hash{}) + // Do a quick check + verifyIterator(t, 4, it, verifyAccount) + it.Release() + + // And a more detailed verification that we indeed do not see '0x22' + it = newIterator(db, common.HexToHash("0x04"), common.Hash{}) + defer it.Release() + for it.Next() { + hash := it.Hash() + if it.Account() == nil { + t.Errorf("iterator returned nil-value for hash %x", hash) + } + if hash == deleted { + t.Errorf("expected deleted elem %x to not be returned by iterator", deleted) + } + } +} + +func TestStorageIteratorDeletions(t *testing.T) { + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + // Stack three diff layers on top with various overlaps + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil), nil, nil)) + + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x04", "0x06"}}, [][]string{{"0x01", "0x03"}}), nil, nil)) + + // The output should be 02,04,05,06 + it, _ := db.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.Hash{}) + verifyIterator(t, 4, it, verifyStorage) + it.Release() + + // The output should be 04,05,06 + it, _ = db.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.HexToHash("0x03")) + verifyIterator(t, 3, it, verifyStorage) + it.Release() + + // Destruct the whole storage + accounts := map[common.Hash][]byte{ + common.HexToHash("0xaa"): nil, + } + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(accounts, randomStorageSet([]string{"0xaa"}, nil, [][]string{{"0x02", "0x04", "0x05", "0x06"}}), nil, nil)) + + it, _ = db.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) + verifyIterator(t, 0, it, verifyStorage) + it.Release() + + // Re-insert the slots of the same account + db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 4, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x07", "0x08", "0x09"}}, nil), nil, nil)) + + // The output should be 07,08,09 + it, _ = db.StorageIterator(common.HexToHash("0x05"), common.HexToHash("0xaa"), common.Hash{}) + verifyIterator(t, 3, it, verifyStorage) + it.Release() + + // Destruct the whole storage but re-create the account in the same layer + db.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), 5, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, [][]string{{"0x07", "0x08", "0x09"}}), nil, nil)) + + it, _ = db.StorageIterator(common.HexToHash("0x06"), common.HexToHash("0xaa"), common.Hash{}) + verifyIterator(t, 2, it, verifyStorage) // The output should be 11,12 + it.Release() + + verifyIterator(t, 2, db.tree.get(common.HexToHash("0x06")).(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}), verifyStorage) +} + +// TestStaleIterator tests if the iterator could correctly terminate the iteration +// if the associated layers are outdated. +func TestStaleIterator(t *testing.T) { + testStaleIterator(t, func(db *Database, hash common.Hash) Iterator { + it, _ := db.StorageIterator(hash, common.HexToHash("0xaa"), common.Hash{}) + return it + }) + testStaleIterator(t, func(db *Database, hash common.Hash) Iterator { + head := db.tree.get(hash) + return head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}) + }) +} + +func testStaleIterator(t *testing.T, newIter func(db *Database, hash common.Hash) Iterator) { + config := &Config{ + WriteBufferSize: 16 * 1024 * 1024, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + // [02 (disk), 03] + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01"}}, nil), nil, nil)) + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02"}}, nil), nil, nil)) + db.tree.cap(common.HexToHash("0x03"), 1) + + // [02 (disk), 03, 04] + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x03"}}, nil), nil, nil)) + iter := newIter(db, common.HexToHash("0x04")) + + // [04 (disk), 05] + db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04"}}, nil), nil, nil)) + db.tree.cap(common.HexToHash("0x05"), 1) + + // Iterator can't finish the traversal as the layer 02 has becoming stale. + for iter.Next() { + } + err := iter.Error() + t.Log(err) + if err == nil { + t.Fatalf("Expected iterator error is not reported") + } +} + +// 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. +// +// The value-fetching benchmark is easy on the binary iterator, since it never has to reach +// down at any depth for retrieving the values -- all are on the topmost layer +// +// BenchmarkAccountIteratorTraversal/binary_iterator_keys-8 759984 1566 ns/op +// BenchmarkAccountIteratorTraversal/binary_iterator_values-8 150028 7900 ns/op +// BenchmarkAccountIteratorTraversal/fast_iterator_keys-8 172809 7006 ns/op +// BenchmarkAccountIteratorTraversal/fast_iterator_values-8 165112 7658 ns/op +func BenchmarkAccountIteratorTraversal(b *testing.B) { + // Create a custom account factory to recreate the same addresses + makeAccounts := func(num int) map[common.Hash][]byte { + accounts := make(map[common.Hash][]byte) + for i := 0; i < num; i++ { + h := common.Hash{} + binary.BigEndian.PutUint64(h[:], uint64(i+1)) + accounts[h] = randomAccount() + } + return accounts + } + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + for i := 1; i <= 100; i++ { + parent := types.EmptyRootHash + if i == 1 { + parent = common.HexToHash(fmt.Sprintf("0x%02x", i)) + } + db.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), parent, uint64(i), trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(200), nil, nil, nil)) + } + // We call this once before the benchmark, so the creation of + // sorted accountlists are not included in the results. + head := db.tree.get(common.HexToHash("0x65")) + head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + + b.Run("binary iterator keys", func(b *testing.B) { + for i := 0; i < b.N; i++ { + got := 0 + it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + for it.Next() { + got++ + } + if exp := 200; got != exp { + b.Errorf("iterator len wrong, expected %d, got %d", exp, got) + } + } + }) + b.Run("binary iterator values", func(b *testing.B) { + for i := 0; i < b.N; i++ { + got := 0 + it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + for it.Next() { + got++ + head.(*diffLayer).account(it.Hash(), 0) + } + if exp := 200; got != exp { + b.Errorf("iterator len wrong, expected %d, got %d", exp, got) + } + } + }) + b.Run("fast iterator keys", func(b *testing.B) { + for i := 0; i < b.N; i++ { + it, _ := db.AccountIterator(common.HexToHash("0x65"), common.Hash{}) + defer it.Release() + + got := 0 + for it.Next() { + got++ + } + if exp := 200; got != exp { + b.Errorf("iterator len wrong, expected %d, got %d", exp, got) + } + } + }) + b.Run("fast iterator values", func(b *testing.B) { + for i := 0; i < b.N; i++ { + it, _ := db.AccountIterator(common.HexToHash("0x65"), common.Hash{}) + defer it.Release() + + got := 0 + for it.Next() { + got++ + it.Account() + } + if exp := 200; got != exp { + b.Errorf("iterator len wrong, expected %d, got %d", exp, got) + } + } + }) +} + +// BenchmarkAccountIteratorLargeBaselayer is a pretty realistic benchmark, where +// the baselayer is a lot larger than the upper layer. +// +// This is heavy on the binary iterator, which in most cases will have to +// call recursively 100 times for the majority of the values +// +// BenchmarkAccountIteratorLargeBaselayer/binary_iterator_(keys)-6 514 1971999 ns/op +// BenchmarkAccountIteratorLargeBaselayer/binary_iterator_(values)-6 61 18997492 ns/op +// BenchmarkAccountIteratorLargeBaselayer/fast_iterator_(keys)-6 10000 114385 ns/op +// BenchmarkAccountIteratorLargeBaselayer/fast_iterator_(values)-6 4047 296823 ns/op +func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { + // Create a custom account factory to recreate the same addresses + makeAccounts := func(num int) map[common.Hash][]byte { + accounts := make(map[common.Hash][]byte) + for i := 0; i < num; i++ { + h := common.Hash{} + binary.BigEndian.PutUint64(h[:], uint64(i+1)) + accounts[h] = randomAccount() + } + return accounts + } + config := &Config{ + WriteBufferSize: 0, + } + db := New(rawdb.NewMemoryDatabase(), config, false) + // db.WaitGeneration() + + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(2000), nil, nil, nil)) + for i := 2; i <= 100; i++ { + db.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), uint64(i), trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(20), nil, nil, nil)) + } + // We call this once before the benchmark, so the creation of + // sorted accountlists are not included in the results. + head := db.tree.get(common.HexToHash("0x65")) + head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + + b.Run("binary iterator (keys)", func(b *testing.B) { + for i := 0; i < b.N; i++ { + got := 0 + it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + for it.Next() { + got++ + } + if exp := 2000; got != exp { + b.Errorf("iterator len wrong, expected %d, got %d", exp, got) + } + } + }) + b.Run("binary iterator (values)", func(b *testing.B) { + for i := 0; i < b.N; i++ { + got := 0 + it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + for it.Next() { + got++ + v := it.Hash() + head.(*diffLayer).account(v, 0) + } + if exp := 2000; got != exp { + b.Errorf("iterator len wrong, expected %d, got %d", exp, got) + } + } + }) + b.Run("fast iterator (keys)", func(b *testing.B) { + for i := 0; i < b.N; i++ { + it, _ := db.AccountIterator(common.HexToHash("0x65"), common.Hash{}) + defer it.Release() + + got := 0 + for it.Next() { + got++ + } + if exp := 2000; got != exp { + b.Errorf("iterator len wrong, expected %d, got %d", exp, got) + } + } + }) + b.Run("fast iterator (values)", func(b *testing.B) { + for i := 0; i < b.N; i++ { + it, _ := db.AccountIterator(common.HexToHash("0x65"), common.Hash{}) + defer it.Release() + + got := 0 + for it.Next() { + it.Account() + got++ + } + if exp := 2000; got != exp { + b.Errorf("iterator len wrong, expected %d, got %d", exp, got) + } + } + }) +} + +/* +func BenchmarkBinaryAccountIteration(b *testing.B) { + benchmarkAccountIteration(b, func(snap snapshot) AccountIterator { + return snap.(*diffLayer).newBinaryAccountIterator() + }) +} + +func BenchmarkFastAccountIteration(b *testing.B) { + benchmarkAccountIteration(b, newFastAccountIterator) +} + +func benchmarkAccountIteration(b *testing.B, iterator func(snap snapshot) AccountIterator) { + // Create a diff stack and randomize the accounts across them + layers := make([]map[common.Hash][]byte, 128) + for i := 0; i < len(layers); i++ { + layers[i] = make(map[common.Hash][]byte) + } + for i := 0; i < b.N; i++ { + depth := rand.Intn(len(layers)) + layers[depth][randomHash()] = randomAccount() + } + stack := snapshot(emptyLayer()) + for _, layer := range layers { + stack = stack.Update(common.Hash{}, layer, nil, nil) + } + // Reset the timers and report all the stats + it := iterator(stack) + + b.ResetTimer() + b.ReportAllocs() + + for it.Next() { + } +} +*/ diff --git a/triedb/pathdb/reader.go b/triedb/pathdb/reader.go index 4bba813b14..a404409035 100644 --- a/triedb/pathdb/reader.go +++ b/triedb/pathdb/reader.go @@ -86,6 +86,17 @@ func (r *reader) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, return blob, nil } +// AccountRLP directly retrieves the account associated with a particular hash. +// An error will be returned if the read operation exits abnormally. Specifically, +// if the layer is already stale. +// +// Note: +// - the returned account data is not a copy, please don't modify it +// - no error will be returned if the requested account is not found in database +func (r *reader) AccountRLP(hash common.Hash) ([]byte, error) { + return r.layer.account(hash, 0) +} + // Account directly retrieves the account associated with a particular hash in // the slim data format. An error will be returned if the read operation exits // abnormally. Specifically, if the layer is already stale. diff --git a/triedb/pathdb/states.go b/triedb/pathdb/states.go index 6e633db272..81d34da5df 100644 --- a/triedb/pathdb/states.go +++ b/triedb/pathdb/states.go @@ -98,6 +98,17 @@ func (s *stateSet) account(hash common.Hash) ([]byte, bool) { return nil, false // account is unknown in this set } +// mustAccount returns the account data associated with the specified address +// hash. The difference is this function will return an error if the account +// is not found. +func (s *stateSet) mustAccount(hash common.Hash) ([]byte, error) { + // If the account is known locally, return it + if data, ok := s.accountData[hash]; ok { + return data, nil + } + return nil, fmt.Errorf("account is not found, %x", hash) +} + // storage returns the storage slot associated with the specified address hash // and storage key hash. func (s *stateSet) storage(accountHash, storageHash common.Hash) ([]byte, bool) { @@ -110,6 +121,19 @@ func (s *stateSet) storage(accountHash, storageHash common.Hash) ([]byte, bool) return nil, false // storage is unknown in this set } +// mustStorage returns the storage slot associated with the specified address +// hash and storage key hash. The difference is this function will return an +// error if the storage slot is not found. +func (s *stateSet) mustStorage(accountHash, storageHash common.Hash) ([]byte, error) { + // If the account is known locally, try to resolve the slot locally + if storage, ok := s.storageData[accountHash]; ok { + if data, ok := storage[storageHash]; ok { + return data, nil + } + } + return nil, fmt.Errorf("storage slot is not found, %x %x", accountHash, storageHash) +} + // check sanitizes accounts and storage slots to ensure the data validity. // Additionally, it computes the total memory size occupied by the maps. func (s *stateSet) check() uint64 { @@ -132,8 +156,6 @@ func (s *stateSet) check() uint64 { // the deleted ones. // // Note, the returned slice is not a copy, so do not modify it. -// -// nolint:unused func (s *stateSet) accountList() []common.Hash { // If an old list already exists, return it s.listLock.RLock() @@ -160,8 +182,6 @@ func (s *stateSet) accountList() []common.Hash { // storage slot. // // Note, the returned slice is not a copy, so do not modify it. -// -// nolint:unused func (s *stateSet) storageList(accountHash common.Hash) []common.Hash { s.listLock.RLock() if _, ok := s.storageData[accountHash]; !ok { diff --git a/triedb/pathdb/states_test.go b/triedb/pathdb/states_test.go index 4557fa958d..f097e90e81 100644 --- a/triedb/pathdb/states_test.go +++ b/triedb/pathdb/states_test.go @@ -28,39 +28,39 @@ import ( func TestStatesMerge(t *testing.T) { a := newStates( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa0}, - common.Hash{0xb}: {0xb0}, - common.Hash{0xc}: {0xc0}, + {0xa}: {0xa0}, + {0xb}: {0xb0}, + {0xc}: {0xc0}, }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x10}, common.Hash{0x2}: {0x20}, }, - common.Hash{0xb}: { + {0xb}: { common.Hash{0x1}: {0x10}, }, - common.Hash{0xc}: { + {0xc}: { common.Hash{0x1}: {0x10}, }, }, ) b := newStates( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa1}, - common.Hash{0xb}: {0xb1}, - common.Hash{0xc}: nil, // delete account + {0xa}: {0xa1}, + {0xb}: {0xb1}, + {0xc}: nil, // delete account }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x11}, common.Hash{0x2}: nil, // delete slot common.Hash{0x3}: {0x31}, }, - common.Hash{0xb}: { + {0xb}: { common.Hash{0x1}: {0x11}, }, - common.Hash{0xc}: { + {0xc}: { common.Hash{0x1}: nil, // delete slot }, }, @@ -116,39 +116,39 @@ func TestStatesMerge(t *testing.T) { func TestStatesRevert(t *testing.T) { a := newStates( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa0}, - common.Hash{0xb}: {0xb0}, - common.Hash{0xc}: {0xc0}, + {0xa}: {0xa0}, + {0xb}: {0xb0}, + {0xc}: {0xc0}, }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x10}, common.Hash{0x2}: {0x20}, }, - common.Hash{0xb}: { + {0xb}: { common.Hash{0x1}: {0x10}, }, - common.Hash{0xc}: { + {0xc}: { common.Hash{0x1}: {0x10}, }, }, ) b := newStates( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa1}, - common.Hash{0xb}: {0xb1}, - common.Hash{0xc}: nil, + {0xa}: {0xa1}, + {0xb}: {0xb1}, + {0xc}: nil, }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x11}, common.Hash{0x2}: nil, common.Hash{0x3}: {0x31}, }, - common.Hash{0xb}: { + {0xb}: { common.Hash{0x1}: {0x11}, }, - common.Hash{0xc}: { + {0xc}: { common.Hash{0x1}: nil, }, }, @@ -156,20 +156,20 @@ func TestStatesRevert(t *testing.T) { a.merge(b) a.revertTo( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa0}, - common.Hash{0xb}: {0xb0}, - common.Hash{0xc}: {0xc0}, + {0xa}: {0xa0}, + {0xb}: {0xb0}, + {0xc}: {0xc0}, }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x10}, common.Hash{0x2}: {0x20}, common.Hash{0x3}: nil, }, - common.Hash{0xb}: { + {0xb}: { common.Hash{0x1}: {0x10}, }, - common.Hash{0xc}: { + {0xc}: { common.Hash{0x1}: {0x10}, }, }, @@ -227,14 +227,14 @@ func TestStateRevertAccountNullMarker(t *testing.T) { a := newStates(nil, nil) // empty initial state b := newStates( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa}, + {0xa}: {0xa}, }, nil, ) a.merge(b) // create account 0xa a.revertTo( map[common.Hash][]byte{ - common.Hash{0xa}: nil, + {0xa}: nil, }, nil, ) // revert the transition b @@ -253,13 +253,13 @@ func TestStateRevertAccountNullMarker(t *testing.T) { // entry in the set. func TestStateRevertStorageNullMarker(t *testing.T) { a := newStates(map[common.Hash][]byte{ - common.Hash{0xa}: {0xa}, + {0xa}: {0xa}, }, nil) // initial state with account 0xa b := newStates( nil, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x1}, }, }, @@ -268,7 +268,7 @@ func TestStateRevertStorageNullMarker(t *testing.T) { a.revertTo( nil, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: nil, }, }, @@ -286,10 +286,10 @@ func TestStateRevertStorageNullMarker(t *testing.T) { func TestStatesEncode(t *testing.T) { s := newStates( map[common.Hash][]byte{ - common.Hash{0x1}: {0x1}, + {0x1}: {0x1}, }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0x1}: { + {0x1}: { common.Hash{0x1}: {0x1}, }, }, @@ -313,18 +313,18 @@ func TestStatesEncode(t *testing.T) { func TestStateWithOriginEncode(t *testing.T) { s := NewStateSetWithOrigin( map[common.Hash][]byte{ - common.Hash{0x1}: {0x1}, + {0x1}: {0x1}, }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0x1}: { + {0x1}: { common.Hash{0x1}: {0x1}, }, }, map[common.Address][]byte{ - common.Address{0x1}: {0x1}, + {0x1}: {0x1}, }, map[common.Address]map[common.Hash][]byte{ - common.Address{0x1}: { + {0x1}: { common.Hash{0x1}: {0x1}, }, }, @@ -359,19 +359,19 @@ func TestStateSizeTracking(t *testing.T) { a := newStates( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa0}, // common.HashLength+1 - common.Hash{0xb}: {0xb0}, // common.HashLength+1 - common.Hash{0xc}: {0xc0}, // common.HashLength+1 + {0xa}: {0xa0}, // common.HashLength+1 + {0xb}: {0xb0}, // common.HashLength+1 + {0xc}: {0xc0}, // common.HashLength+1 }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x10}, // 2*common.HashLength+1 common.Hash{0x2}: {0x20}, // 2*common.HashLength+1 }, - common.Hash{0xb}: { + {0xb}: { common.Hash{0x1}: {0x10, 0x11, 0x12}, // 2*common.HashLength+3 }, - common.Hash{0xc}: { + {0xc}: { common.Hash{0x1}: {0x10}, // 2*common.HashLength+1 }, }, @@ -386,21 +386,21 @@ func TestStateSizeTracking(t *testing.T) { 3*2*common.HashLength /* storage data of 0xc */ b := newStates( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa1, 0xa1}, // common.HashLength+2 - common.Hash{0xb}: {0xb1, 0xb1, 0xb1}, // common.HashLength+3 - common.Hash{0xc}: nil, // common.HashLength, account deletion + {0xa}: {0xa1, 0xa1}, // common.HashLength+2 + {0xb}: {0xb1, 0xb1, 0xb1}, // common.HashLength+3 + {0xc}: nil, // common.HashLength, account deletion }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x11, 0x11, 0x11}, // 2*common.HashLength+3 common.Hash{0x3}: {0x31, 0x31}, // 2*common.HashLength+2, slot creation }, - common.Hash{0xb}: { + {0xb}: { common.Hash{0x1}: {0x11, 0x11}, // 2*common.HashLength+2 common.Hash{0x2}: {0x22, 0x22}, // 2*common.HashLength+2, slot creation }, // The storage of 0xc is entirely removed - common.Hash{0xc}: { + {0xc}: { common.Hash{0x1}: nil, // 2*common.HashLength, slot deletion common.Hash{0x2}: nil, // 2*common.HashLength, slot deletion common.Hash{0x3}: nil, // 2*common.HashLength, slot deletion @@ -424,21 +424,21 @@ func TestStateSizeTracking(t *testing.T) { // Revert the set to original status a.revertTo( map[common.Hash][]byte{ - common.Hash{0xa}: {0xa0}, - common.Hash{0xb}: {0xb0}, - common.Hash{0xc}: {0xc0}, + {0xa}: {0xa0}, + {0xb}: {0xb0}, + {0xc}: {0xc0}, }, map[common.Hash]map[common.Hash][]byte{ - common.Hash{0xa}: { + {0xa}: { common.Hash{0x1}: {0x10}, common.Hash{0x2}: {0x20}, common.Hash{0x3}: nil, // revert slot creation }, - common.Hash{0xb}: { + {0xb}: { common.Hash{0x1}: {0x10, 0x11, 0x12}, common.Hash{0x2}: nil, // revert slot creation }, - common.Hash{0xc}: { + {0xc}: { common.Hash{0x1}: {0x10}, common.Hash{0x2}: {0x20}, // resurrected slot common.Hash{0x3}: {0x30}, // resurrected slot From 5c58612e12a5131233be5efc9aa9ff55aac4538a Mon Sep 17 00:00:00 2001 From: Martin HS Date: Tue, 17 Dec 2024 08:58:26 +0100 Subject: [PATCH 014/940] core/vm, go.mod: update uint256 and use faster method to write to memory (#30868) Updates geth to use the latest uint256, and use faster memory-writer --- core/vm/memory.go | 3 +-- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core/vm/memory.go b/core/vm/memory.go index 1ddd8d1ead..5e11e83748 100644 --- a/core/vm/memory.go +++ b/core/vm/memory.go @@ -73,8 +73,7 @@ func (m *Memory) Set32(offset uint64, val *uint256.Int) { panic("invalid memory: store empty") } // Fill in relevant bits - b32 := val.Bytes32() - copy(m.store[offset:], b32[:]) + val.PutUint256(m.store[offset:]) } // Resize resizes the memory to size diff --git a/go.mod b/go.mod index b33c30f41d..0f000636c3 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/hashicorp/go-bexpr v0.1.10 github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 github.com/holiman/bloomfilter/v2 v2.0.3 - github.com/holiman/uint256 v1.3.1 + github.com/holiman/uint256 v1.3.2 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 diff --git a/go.sum b/go.sum index b61121664f..e79fc6941c 100644 --- a/go.sum +++ b/go.sum @@ -306,8 +306,8 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8 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.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/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= From 3c208cdea82acff878c7675312a97a638997e1fc Mon Sep 17 00:00:00 2001 From: maskpp Date: Tue, 17 Dec 2024 16:12:10 +0800 Subject: [PATCH 015/940] accounts/abi/bind: make it possible to wait for tx hash (#30079) This change adds methods which makes it possible for to wait for a transaction with a specific hash when deploying contracts during abi bind interaction. --------- Co-authored-by: Marius van der Wijden --- accounts/abi/bind/util.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/accounts/abi/bind/util.go b/accounts/abi/bind/util.go index b931fbb04d..c83116e9a1 100644 --- a/accounts/abi/bind/util.go +++ b/accounts/abi/bind/util.go @@ -30,12 +30,18 @@ import ( // WaitMined waits for tx to be mined on the blockchain. // It stops waiting when the context is canceled. func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) { + return WaitMinedHash(ctx, b, tx.Hash()) +} + +// WaitMinedHash waits for a transaction with the provided hash to be mined on the blockchain. +// It stops waiting when the context is canceled. +func WaitMinedHash(ctx context.Context, b DeployBackend, hash common.Hash) (*types.Receipt, error) { queryTicker := time.NewTicker(time.Second) defer queryTicker.Stop() - logger := log.New("hash", tx.Hash()) + logger := log.New("hash", hash) for { - receipt, err := b.TransactionReceipt(ctx, tx.Hash()) + receipt, err := b.TransactionReceipt(ctx, hash) if err == nil { return receipt, nil } @@ -61,7 +67,13 @@ func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) ( if tx.To() != nil { return common.Address{}, errors.New("tx is not contract creation") } - receipt, err := WaitMined(ctx, b, tx) + return WaitDeployedHash(ctx, b, tx.Hash()) +} + +// WaitDeployedHash waits for a contract deployment transaction with the provided hash and returns the on-chain +// contract address when it is mined. It stops waiting when ctx is canceled. +func WaitDeployedHash(ctx context.Context, b DeployBackend, hash common.Hash) (common.Address, error) { + receipt, err := WaitMinedHash(ctx, b, hash) if err != nil { return common.Address{}, err } From 71c28d8d2b2049738660a56effcfd0c70f8012d9 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 17 Dec 2024 15:16:17 +0100 Subject: [PATCH 016/940] core: fixes for Prague fork in GenerateChain (#30924) Adding some missing functionality I noticed while updating the hivechain tool for the Prague fork: - we forgot to process the parent block hash - added `ConsensusLayerRequests` to get the requests list of the block --- core/chain_makers.go | 65 +++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/core/chain_makers.go b/core/chain_makers.go index 97c785d52b..26714845eb 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -293,6 +293,41 @@ func (b *BlockGen) OffsetTime(seconds int64) { b.header.Difficulty = b.engine.CalcDifficulty(b.cm, b.header.Time, b.parent.Header()) } +// ConsensusLayerRequests returns the EIP-7685 requests which have accumulated so far. +func (b *BlockGen) ConsensusLayerRequests() [][]byte { + return b.collectRequests(true) +} + +func (b *BlockGen) collectRequests(readonly bool) (requests [][]byte) { + statedb := b.statedb + if readonly { + // The system contracts clear themselves on a system-initiated read. + // When reading the requests mid-block, we don't want this behavior, so fork + // off the statedb before executing the system calls. + statedb = statedb.Copy() + } + + if b.cm.config.IsPrague(b.header.Number, b.header.Time) { + requests = [][]byte{} + // EIP-6110 deposits + var blockLogs []*types.Log + for _, r := range b.receipts { + blockLogs = append(blockLogs, r.Logs...) + } + if err := ParseDepositLogs(&requests, blockLogs, b.cm.config); err != nil { + panic(fmt.Sprintf("failed to parse deposit log: %v", err)) + } + // create EVM for system calls + blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase) + evm := vm.NewEVM(blockContext, statedb, b.cm.config, vm.Config{}) + // EIP-7002 + ProcessWithdrawalQueue(&requests, evm) + // EIP-7251 + ProcessConsolidationQueue(&requests, evm) + } + return requests +} + // GenerateChain creates a chain of n blocks. The first block's // parent will be the provided parent. db is used to store // intermediate states and should contain the parent's state trie. @@ -330,6 +365,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse b.header.Difficulty = big.NewInt(0) } } + // Mutate the state and block according to any hard-fork specs if daoBlock := config.DAOForkBlock; daoBlock != nil { limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) @@ -342,30 +378,21 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 { misc.ApplyDAOHardFork(statedb) } + + if config.IsPrague(b.header.Number, b.header.Time) { + // EIP-2935 + blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) + blockContext.Random = &common.Hash{} // enable post-merge instruction set + evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) + ProcessParentBlockHash(b.header.ParentHash, evm) + } + // Execute any user modifications to the block if gen != nil { gen(i, b) } - var requests [][]byte - if config.IsPrague(b.header.Number, b.header.Time) { - requests = [][]byte{} - // EIP-6110 deposits - var blockLogs []*types.Log - for _, r := range b.receipts { - blockLogs = append(blockLogs, r.Logs...) - } - if err := ParseDepositLogs(&requests, blockLogs, config); err != nil { - panic(fmt.Sprintf("failed to parse deposit log: %v", err)) - } - // create EVM for system calls - blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) - evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) - // EIP-7002 - ProcessWithdrawalQueue(&requests, evm) - // EIP-7251 - ProcessConsolidationQueue(&requests, evm) - } + requests := b.collectRequests(false) if requests != nil { reqHash := types.CalcRequestsHash(requests) b.header.RequestsHash = &reqHash From feaf1c95b13b78f06d93a840dde1585eba0e5608 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 15:26:03 +0100 Subject: [PATCH 017/940] build(deps): bump golang.org/x/crypto from 0.26.0 to 0.31.0 (#30921) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.26.0 to 0.31.0. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 0f000636c3..35018fbe08 100644 --- a/go.mod +++ b/go.mod @@ -64,11 +64,11 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/urfave/cli/v2 v2.25.7 go.uber.org/automaxprocs v1.5.2 - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.31.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/sync v0.10.0 golang.org/x/sys v0.28.0 - golang.org/x/text v0.17.0 + golang.org/x/text v0.21.0 golang.org/x/time v0.5.0 golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d google.golang.org/protobuf v1.34.2 diff --git a/go.sum b/go.sum index e79fc6941c..ded07f4867 100644 --- a/go.sum +++ b/go.sum @@ -528,8 +528,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= 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= @@ -698,8 +698,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 5b9a3ea9d2930eb2228c5203d1afe40776e70af3 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Tue, 17 Dec 2024 18:37:29 +0100 Subject: [PATCH 018/940] core/vm: make all opcodes proper type (#30925) Noticed this omission while doing some work on goevmlab. We don't properly type some of the opcodes, but apparently implicit casting works in all the internal usecases. --- core/vm/opcodes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index 162be8f6c8..0820b20fb1 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -164,7 +164,7 @@ const ( // 0x80 range - dups. const ( - DUP1 = 0x80 + iota + DUP1 OpCode = 0x80 + iota DUP2 DUP3 DUP4 @@ -184,7 +184,7 @@ const ( // 0x90 range - swaps. const ( - SWAP1 = 0x90 + iota + SWAP1 OpCode = 0x90 + iota SWAP2 SWAP3 SWAP4 From 06dfb42365a33b4d47af9731892de2eb4e3b6f19 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 17 Dec 2024 19:47:10 +0100 Subject: [PATCH 019/940] core/types, internal/ethapi: fixes for prague RPC encoding (#30926) Fixing some issues I found while regenerating RPC tests for Prague: - Authorization signature values were not encoded as hex - `requestsRoot` in block should be `requestsHash` - `authorizationList` should work for `eth_call` --- core/types/block.go | 2 +- core/types/gen_authorization.go | 16 ++++++++-------- core/types/gen_header_json.go | 4 ++-- core/types/tx_setcode.go | 2 ++ internal/ethapi/api.go | 2 +- internal/ethapi/transaction_args.go | 1 + 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/core/types/block.go b/core/types/block.go index ad6c86398d..c3db4d89e8 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -105,7 +105,7 @@ type Header struct { 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"` + RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"` } // field type overrides for gencodec diff --git a/core/types/gen_authorization.go b/core/types/gen_authorization.go index b598b64ff7..cc8fe138ea 100644 --- a/core/types/gen_authorization.go +++ b/core/types/gen_authorization.go @@ -20,16 +20,16 @@ func (a Authorization) MarshalJSON() ([]byte, error) { Address common.Address `json:"address" gencodec:"required"` Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` V hexutil.Uint64 `json:"v" gencodec:"required"` - R uint256.Int `json:"r" gencodec:"required"` - S uint256.Int `json:"s" gencodec:"required"` + R hexutil.U256 `json:"r" gencodec:"required"` + S hexutil.U256 `json:"s" gencodec:"required"` } var enc Authorization enc.ChainID = hexutil.Uint64(a.ChainID) enc.Address = a.Address enc.Nonce = hexutil.Uint64(a.Nonce) enc.V = hexutil.Uint64(a.V) - enc.R = a.R - enc.S = a.S + enc.R = hexutil.U256(a.R) + enc.S = hexutil.U256(a.S) return json.Marshal(&enc) } @@ -40,8 +40,8 @@ func (a *Authorization) UnmarshalJSON(input []byte) error { Address *common.Address `json:"address" gencodec:"required"` Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` V *hexutil.Uint64 `json:"v" gencodec:"required"` - R *uint256.Int `json:"r" gencodec:"required"` - S *uint256.Int `json:"s" gencodec:"required"` + R *hexutil.U256 `json:"r" gencodec:"required"` + S *hexutil.U256 `json:"s" gencodec:"required"` } var dec Authorization if err := json.Unmarshal(input, &dec); err != nil { @@ -66,10 +66,10 @@ func (a *Authorization) UnmarshalJSON(input []byte) error { if dec.R == nil { return errors.New("missing required field 'r' for Authorization") } - a.R = *dec.R + a.R = uint256.Int(*dec.R) if dec.S == nil { return errors.New("missing required field 's' for Authorization") } - a.S = *dec.S + a.S = uint256.Int(*dec.S) return nil } diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index 322c5d5642..0af12500bd 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -36,7 +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"` + RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"` Hash common.Hash `json:"hash"` } var enc Header @@ -88,7 +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"` + RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"` } var dec Header if err := json.Unmarshal(input, &dec); err != nil { diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index 0fea9a63a7..b251cd1812 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -83,6 +83,8 @@ type authorizationMarshaling struct { ChainID hexutil.Uint64 Nonce hexutil.Uint64 V hexutil.Uint64 + R hexutil.U256 + S hexutil.U256 } // SignAuth signs the provided authorization. diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 3f9ce46ddb..a983d4ecc9 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -895,7 +895,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { result["parentBeaconBlockRoot"] = head.ParentBeaconRoot } if head.RequestsHash != nil { - result["requestsRoot"] = head.RequestsHash + result["requestsHash"] = head.RequestsHash } return result } diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 3942540b04..89d1595681 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -466,6 +466,7 @@ func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck, skipEoA AccessList: accessList, BlobGasFeeCap: (*big.Int)(args.BlobFeeCap), BlobHashes: args.BlobHashes, + AuthList: args.AuthorizationList, SkipNonceChecks: skipNonceCheck, SkipFromEOACheck: skipEoACheck, } From 1321a4252544c6451ed1867f6d2714f0fd6b30a9 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Wed, 18 Dec 2024 00:18:36 +0100 Subject: [PATCH 020/940] cmd/evm: make evm statetest accept non-json files (#30927) This fixes a regression introduced recently. Without this fix, it's not possible to use statetests without `.json` suffix. This is problematic for goevmlab `minimizer`, which appends the suffix `.min` during processing. --- cmd/evm/blockrunner.go | 2 +- cmd/evm/main.go | 11 ++++++++--- cmd/evm/staterunner.go | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cmd/evm/blockrunner.go b/cmd/evm/blockrunner.go index 2cb0531e28..9a04807b33 100644 --- a/cmd/evm/blockrunner.go +++ b/cmd/evm/blockrunner.go @@ -50,7 +50,7 @@ func blockTestCmd(ctx *cli.Context) error { return errors.New("path argument required") } var ( - collected = collectJSONFiles(path) + collected = collectFiles(path) results []testResult ) for _, fname := range collected { diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 0e6f6fa5be..2079425416 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -262,10 +262,15 @@ func tracerFromFlags(ctx *cli.Context) *tracing.Hooks { } } -// collectJSONFiles walks the given path and accumulates all files with json -// extension. -func collectJSONFiles(path string) []string { +// collectFiles walks the given path. If the path is a directory, it will +// return a list of all accumulates all files with json extension. +// Otherwise (if path points to a file), it will return the path. +func collectFiles(path string) []string { var out []string + if info, err := os.Stat(path); err == nil && !info.IsDir() { + // User explicitly pointed out a file, ignore extension. + return []string{path} + } err := filepath.Walk(path, func(path string, info fs.FileInfo, err error) error { if err != nil { return err diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 323b7d60ab..4c2dfeabc6 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -63,7 +63,7 @@ func stateTestCmd(ctx *cli.Context) error { // If path is provided, run the tests at that path. if len(path) != 0 { var ( - collected = collectJSONFiles(path) + collected = collectFiles(path) results []testResult ) for _, fname := range collected { From 9d4b29f291652c1f681afd616d4427bfedf08c7a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 18 Dec 2024 19:10:53 +0100 Subject: [PATCH 021/940] core/types: updates for EIP-7702 API functions (#30933) Here I am proposing two small changes to the exported API for EIP-7702: (1) `Authorization` has a very generic name, but it is in fact only used for one niche use case: authorizing code in a `SetCodeTx`. So I propose calling it `SetCodeAuthorization` instead. The signing function is renamed to `SignSetCode` instead of `SignAuth`. (2) The signing function for authorizations should take key as the first parameter, and the authorization second. The key will almost always be in a variable, while the authorization can be given as a literal. --- core/blockchain_test.go | 10 +++--- core/state_processor_test.go | 2 +- core/state_transition.go | 8 ++--- core/types/gen_authorization.go | 48 +++++++++++++-------------- core/types/transaction.go | 2 +- core/types/transaction_marshalling.go | 34 +++++++++---------- core/types/tx_setcode.go | 36 +++++++++----------- internal/ethapi/api.go | 46 ++++++++++++------------- internal/ethapi/transaction_args.go | 4 +-- tests/state_test_util.go | 6 ++-- 10 files changed, 95 insertions(+), 101 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index a54a907766..fc0e3d8446 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -4273,16 +4273,16 @@ func TestEIP7702(t *testing.T) { // 1. tx -> addr1 which is delegated to 0xaaaa // 2. addr1:0xaaaa calls into addr2:0xbbbb // 3. addr2:0xbbbb writes to storage - auth1, _ := types.SignAuth(types.Authorization{ + auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{ ChainID: gspec.Config.ChainID.Uint64(), Address: aa, Nonce: 1, - }, key1) - auth2, _ := types.SignAuth(types.Authorization{ + }) + auth2, _ := types.SignSetCode(key2, types.SetCodeAuthorization{ ChainID: 0, Address: bb, Nonce: 0, - }, key2) + }) _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { b.SetCoinbase(aa) @@ -4293,7 +4293,7 @@ func TestEIP7702(t *testing.T) { Gas: 500000, GasFeeCap: uint256.MustFromBig(newGwei(5)), GasTipCap: uint256.NewInt(2), - AuthList: []types.Authorization{auth1, auth2}, + AuthList: []types.SetCodeAuthorization{auth1, auth2}, } tx := types.MustSignNewTx(key1, signer, txdata) b.AddTx(tx) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index e8d8c2ca2e..2f841eb64a 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -111,7 +111,7 @@ func TestStateProcessorErrors(t *testing.T) { } return tx } - var mkSetCodeTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, authlist []types.Authorization) *types.Transaction { + var mkSetCodeTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, authlist []types.SetCodeAuthorization) *types.Transaction { tx, err := types.SignTx(types.NewTx(&types.SetCodeTx{ Nonce: nonce, GasTipCap: uint256.MustFromBig(gasTipCap), diff --git a/core/state_transition.go b/core/state_transition.go index 58728e470e..1f6abed91d 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -67,7 +67,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, authList []types.Authorization, isContractCreation, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { +func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.SetCodeAuthorization, isContractCreation, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { // Set the starting gas for the raw transaction var gas uint64 if isContractCreation && isHomestead { @@ -143,7 +143,7 @@ type Message struct { AccessList types.AccessList BlobGasFeeCap *big.Int BlobHashes []common.Hash - AuthList []types.Authorization + AuthList []types.SetCodeAuthorization // When SkipNonceChecks is true, the message nonce is not checked against the // account nonce in state. @@ -528,7 +528,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { } // validateAuthorization validates an EIP-7702 authorization against the state. -func (st *stateTransition) validateAuthorization(auth *types.Authorization) (authority common.Address, err error) { +func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) { // Verify chain ID is 0 or equal to current chain ID. if auth.ChainID != 0 && st.evm.ChainConfig().ChainID.Uint64() != auth.ChainID { return authority, ErrAuthorizationWrongChainID @@ -559,7 +559,7 @@ func (st *stateTransition) validateAuthorization(auth *types.Authorization) (aut } // applyAuthorization applies an EIP-7702 code delegation to the state. -func (st *stateTransition) applyAuthorization(msg *Message, auth *types.Authorization) error { +func (st *stateTransition) applyAuthorization(msg *Message, auth *types.SetCodeAuthorization) error { authority, err := st.validateAuthorization(auth) if err != nil { return err diff --git a/core/types/gen_authorization.go b/core/types/gen_authorization.go index cc8fe138ea..c9ab3590bf 100644 --- a/core/types/gen_authorization.go +++ b/core/types/gen_authorization.go @@ -14,8 +14,8 @@ import ( var _ = (*authorizationMarshaling)(nil) // MarshalJSON marshals as JSON. -func (a Authorization) MarshalJSON() ([]byte, error) { - type Authorization struct { +func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { + type SetCodeAuthorization struct { ChainID hexutil.Uint64 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` @@ -23,19 +23,19 @@ func (a Authorization) MarshalJSON() ([]byte, error) { R hexutil.U256 `json:"r" gencodec:"required"` S hexutil.U256 `json:"s" gencodec:"required"` } - var enc Authorization - enc.ChainID = hexutil.Uint64(a.ChainID) - enc.Address = a.Address - enc.Nonce = hexutil.Uint64(a.Nonce) - enc.V = hexutil.Uint64(a.V) - enc.R = hexutil.U256(a.R) - enc.S = hexutil.U256(a.S) + var enc SetCodeAuthorization + enc.ChainID = hexutil.Uint64(s.ChainID) + enc.Address = s.Address + enc.Nonce = hexutil.Uint64(s.Nonce) + enc.V = hexutil.Uint64(s.V) + enc.R = hexutil.U256(s.R) + enc.S = hexutil.U256(s.S) return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. -func (a *Authorization) UnmarshalJSON(input []byte) error { - type Authorization struct { +func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { + type SetCodeAuthorization struct { ChainID *hexutil.Uint64 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` @@ -43,33 +43,33 @@ func (a *Authorization) UnmarshalJSON(input []byte) error { R *hexutil.U256 `json:"r" gencodec:"required"` S *hexutil.U256 `json:"s" gencodec:"required"` } - var dec Authorization + var dec SetCodeAuthorization if err := json.Unmarshal(input, &dec); err != nil { return err } if dec.ChainID == nil { - return errors.New("missing required field 'chainId' for Authorization") + return errors.New("missing required field 'chainId' for SetCodeAuthorization") } - a.ChainID = uint64(*dec.ChainID) + s.ChainID = uint64(*dec.ChainID) if dec.Address == nil { - return errors.New("missing required field 'address' for Authorization") + return errors.New("missing required field 'address' for SetCodeAuthorization") } - a.Address = *dec.Address + s.Address = *dec.Address if dec.Nonce == nil { - return errors.New("missing required field 'nonce' for Authorization") + return errors.New("missing required field 'nonce' for SetCodeAuthorization") } - a.Nonce = uint64(*dec.Nonce) + s.Nonce = uint64(*dec.Nonce) if dec.V == nil { - return errors.New("missing required field 'v' for Authorization") + return errors.New("missing required field 'v' for SetCodeAuthorization") } - a.V = uint8(*dec.V) + s.V = uint8(*dec.V) if dec.R == nil { - return errors.New("missing required field 'r' for Authorization") + return errors.New("missing required field 'r' for SetCodeAuthorization") } - a.R = uint256.Int(*dec.R) + s.R = uint256.Int(*dec.R) if dec.S == nil { - return errors.New("missing required field 's' for Authorization") + return errors.New("missing required field 's' for SetCodeAuthorization") } - a.S = uint256.Int(*dec.S) + s.S = uint256.Int(*dec.S) return nil } diff --git a/core/types/transaction.go b/core/types/transaction.go index b5fb3e2db2..24b110fa18 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -475,7 +475,7 @@ func (tx *Transaction) WithBlobTxSidecar(sideCar *BlobTxSidecar) *Transaction { } // AuthList returns the authorizations list of the transaction. -func (tx *Transaction) AuthList() []Authorization { +func (tx *Transaction) AuthList() []SetCodeAuthorization { setcodetx, ok := tx.inner.(*SetCodeTx) if !ok { return nil diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index 4176a8220c..993d633c6f 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -31,23 +31,23 @@ import ( type txJSON struct { Type hexutil.Uint64 `json:"type"` - ChainID *hexutil.Big `json:"chainId,omitempty"` - Nonce *hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` - Gas *hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` - MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` - MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` - Value *hexutil.Big `json:"value"` - Input *hexutil.Bytes `json:"input"` - AccessList *AccessList `json:"accessList,omitempty"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - AuthorizationList []Authorization `json:"authorizationList,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - YParity *hexutil.Uint64 `json:"yParity,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` + Nonce *hexutil.Uint64 `json:"nonce"` + To *common.Address `json:"to"` + Gas *hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` + MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` + Value *hexutil.Big `json:"value"` + Input *hexutil.Bytes `json:"input"` + AccessList *AccessList `json:"accessList,omitempty"` + BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` + AuthorizationList []SetCodeAuthorization `json:"authorizationList,omitempty"` + V *hexutil.Big `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` + YParity *hexutil.Uint64 `json:"yParity,omitempty"` // Blob transaction sidecar encoding: Blobs []kzg4844.Blob `json:"blobs,omitempty"` diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index b251cd1812..1be90df615 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -58,7 +58,7 @@ type SetCodeTx struct { Value *uint256.Int Data []byte AccessList AccessList - AuthList []Authorization + AuthList []SetCodeAuthorization // Signature values V *uint256.Int `json:"v" gencodec:"required"` @@ -66,10 +66,10 @@ type SetCodeTx struct { S *uint256.Int `json:"s" gencodec:"required"` } -//go:generate go run github.com/fjl/gencodec -type Authorization -field-override authorizationMarshaling -out gen_authorization.go +//go:generate go run github.com/fjl/gencodec -type SetCodeAuthorization -field-override authorizationMarshaling -out gen_authorization.go -// Authorization is an authorization from an account to deploy code at its address. -type Authorization struct { +// SetCodeAuthorization is an authorization from an account to deploy code at its address. +type SetCodeAuthorization struct { ChainID uint64 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` @@ -87,31 +87,25 @@ type authorizationMarshaling struct { S hexutil.U256 } -// SignAuth signs the provided authorization. -func SignAuth(auth Authorization, prv *ecdsa.PrivateKey) (Authorization, error) { +// SignSetCode creates a signed the SetCode authorization. +func SignSetCode(prv *ecdsa.PrivateKey, auth SetCodeAuthorization) (SetCodeAuthorization, error) { sighash := auth.sigHash() sig, err := crypto.Sign(sighash[:], prv) if err != nil { - return Authorization{}, err + return SetCodeAuthorization{}, err } - return auth.withSignature(sig), nil -} - -// withSignature updates the signature of an Authorization to be equal the -// decoded signature provided in sig. -func (a *Authorization) withSignature(sig []byte) Authorization { r, s, _ := decodeSignature(sig) - return Authorization{ - ChainID: a.ChainID, - Address: a.Address, - Nonce: a.Nonce, + return SetCodeAuthorization{ + ChainID: auth.ChainID, + Address: auth.Address, + Nonce: auth.Nonce, V: sig[64], R: *uint256.MustFromBig(r), S: *uint256.MustFromBig(s), - } + }, nil } -func (a *Authorization) sigHash() common.Hash { +func (a *SetCodeAuthorization) sigHash() common.Hash { return prefixedRlpHash(0x05, []any{ a.ChainID, a.Address, @@ -120,7 +114,7 @@ func (a *Authorization) sigHash() common.Hash { } // Authority recovers the the authorizing account of an authorization. -func (a *Authorization) Authority() (common.Address, error) { +func (a *SetCodeAuthorization) Authority() (common.Address, error) { sighash := a.sigHash() if !crypto.ValidateSignatureValues(a.V, a.R.ToBig(), a.S.ToBig(), true) { return common.Address{}, ErrInvalidSig @@ -152,7 +146,7 @@ func (tx *SetCodeTx) copy() TxData { Gas: tx.Gas, // These are copied below. AccessList: make(AccessList, len(tx.AccessList)), - AuthList: make([]Authorization, len(tx.AuthList)), + AuthList: make([]SetCodeAuthorization, len(tx.AuthList)), Value: new(uint256.Int), ChainID: tx.ChainID, GasTipCap: new(uint256.Int), diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index a983d4ecc9..2ba27f43a8 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -937,29 +937,29 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *param // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction type RPCTransaction struct { - BlockHash *common.Hash `json:"blockHash"` - BlockNumber *hexutil.Big `json:"blockNumber"` - From common.Address `json:"from"` - Gas hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` - GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` - MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` - Hash common.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` - Nonce hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` - TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` - Value *hexutil.Big `json:"value"` - Type hexutil.Uint64 `json:"type"` - Accesses *types.AccessList `json:"accessList,omitempty"` - ChainID *hexutil.Big `json:"chainId,omitempty"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - AuthorizationList []types.Authorization `json:"authorizationList,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - YParity *hexutil.Uint64 `json:"yParity,omitempty"` + BlockHash *common.Hash `json:"blockHash"` + BlockNumber *hexutil.Big `json:"blockNumber"` + From common.Address `json:"from"` + Gas hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` + GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` + MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` + Hash common.Hash `json:"hash"` + Input hexutil.Bytes `json:"input"` + Nonce hexutil.Uint64 `json:"nonce"` + To *common.Address `json:"to"` + TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` + Value *hexutil.Big `json:"value"` + Type hexutil.Uint64 `json:"type"` + Accesses *types.AccessList `json:"accessList,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` + BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` + AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"` + V *hexutil.Big `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` + YParity *hexutil.Uint64 `json:"yParity,omitempty"` } // newRPCTransaction returns a transaction that will serialize to the RPC diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 89d1595681..a9b563de74 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -73,7 +73,7 @@ type TransactionArgs struct { Proofs []kzg4844.Proof `json:"proofs"` // For SetCodeTxType - AuthorizationList []types.Authorization `json:"authorizationList"` + AuthorizationList []types.SetCodeAuthorization `json:"authorizationList"` // This configures whether blobs are allowed to be passed. blobSidecarAllowed bool @@ -497,7 +497,7 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { if args.AccessList != nil { al = *args.AccessList } - authList := []types.Authorization{} + authList := []types.SetCodeAuthorization{} if args.AuthorizationList != nil { authList = args.AuthorizationList } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index e735ce2fb8..266bd7fd23 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -441,11 +441,11 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess if gasPrice == nil { return nil, errors.New("no gas price provided") } - var authList []types.Authorization + var authList []types.SetCodeAuthorization if tx.AuthorizationList != nil { - authList = make([]types.Authorization, len(tx.AuthorizationList)) + authList = make([]types.SetCodeAuthorization, len(tx.AuthorizationList)) for i, auth := range tx.AuthorizationList { - authList[i] = types.Authorization{ + authList[i] = types.SetCodeAuthorization{ ChainID: auth.ChainID, Address: auth.Address, Nonce: auth.Nonce, From 73a4ecf675f6714e1fdf49904ce9426841de2e02 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 18 Dec 2024 19:46:15 +0100 Subject: [PATCH 022/940] core/types: rename SetCodeAuthorization 'v' to 'yParity' The API spec requires the name yParity. --- core/types/gen_authorization.go | 6 +++--- core/types/tx_setcode.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/types/gen_authorization.go b/core/types/gen_authorization.go index c9ab3590bf..be5467c50d 100644 --- a/core/types/gen_authorization.go +++ b/core/types/gen_authorization.go @@ -19,7 +19,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { ChainID hexutil.Uint64 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` - V hexutil.Uint64 `json:"v" gencodec:"required"` + V hexutil.Uint64 `json:"yParity" gencodec:"required"` R hexutil.U256 `json:"r" gencodec:"required"` S hexutil.U256 `json:"s" gencodec:"required"` } @@ -39,7 +39,7 @@ func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { ChainID *hexutil.Uint64 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` - V *hexutil.Uint64 `json:"v" gencodec:"required"` + V *hexutil.Uint64 `json:"yParity" gencodec:"required"` R *hexutil.U256 `json:"r" gencodec:"required"` S *hexutil.U256 `json:"s" gencodec:"required"` } @@ -60,7 +60,7 @@ func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { } s.Nonce = uint64(*dec.Nonce) if dec.V == nil { - return errors.New("missing required field 'v' for SetCodeAuthorization") + return errors.New("missing required field 'yParity' for SetCodeAuthorization") } s.V = uint8(*dec.V) if dec.R == nil { diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index 1be90df615..f14ae3bc9d 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -73,7 +73,7 @@ type SetCodeAuthorization struct { ChainID uint64 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` - V uint8 `json:"v" gencodec:"required"` + V uint8 `json:"yParity" gencodec:"required"` R uint256.Int `json:"r" gencodec:"required"` S uint256.Int `json:"s" gencodec:"required"` } From f861535f1ecc59ad279c35f77f3962efc14dcf98 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 18 Dec 2024 20:17:49 +0100 Subject: [PATCH 023/940] cmd/evm: update tests for SetCodeAuthorization JSON encoding change (#30936) Fixing a regression introduced by 73a4ecf675f6, which I accidentally pushed to the master branch directly. --- cmd/evm/testdata/33/txs.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/evm/testdata/33/txs.json b/cmd/evm/testdata/33/txs.json index 9c4db138c8..c96cdb03ea 100644 --- a/cmd/evm/testdata/33/txs.json +++ b/cmd/evm/testdata/33/txs.json @@ -16,7 +16,7 @@ "chainId": "0x1", "address": "0x000000000000000000000000000000000000aaaa", "nonce": "0x1", - "v": "0x1", + "yParity": "0x1", "r": "0xf7e3e597fc097e71ed6c26b14b25e5395bc8510d58b9136af439e12715f2d721", "s": "0x6cf7c3d7939bfdb784373effc0ebb0bd7549691a513f395e3cdabf8602724987" }, @@ -24,7 +24,7 @@ "chainId": "0x0", "address": "0x000000000000000000000000000000000000bbbb", "nonce": "0x0", - "v": "0x1", + "yParity": "0x1", "r": "0x5011890f198f0356a887b0779bde5afa1ed04e6acb1e3f37f8f18c7b6f521b98", "s": "0x56c3fa3456b103f3ef4a0acb4b647b9cab9ec4bc68fbcdf1e10b49fb2bcbcf61" } From f1e6372eeadf02f46e0930eeb58910b84f3655dd Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 19 Dec 2024 10:06:33 +0100 Subject: [PATCH 024/940] core, core/types: rename AuthList to SetCodeAuthorizations (#30935) As a follow-up to #30933, I propose to also use the SetCode prefix in our internal APIs for the authorization list. --- cmd/evm/internal/t8ntool/transaction.go | 2 +- core/state_transition.go | 64 ++++++++++++------------- core/txpool/validation.go | 2 +- core/types/transaction.go | 4 +- core/types/transaction_signing.go | 2 +- eth/tracers/native/prestate.go | 2 +- internal/ethapi/api.go | 2 +- internal/ethapi/transaction_args.go | 30 ++++++------ tests/state_test_util.go | 26 +++++----- tests/transaction_test_util.go | 2 +- 10 files changed, 68 insertions(+), 68 deletions(-) diff --git a/cmd/evm/internal/t8ntool/transaction.go b/cmd/evm/internal/t8ntool/transaction.go index 64e21b24fd..6dac4301dd 100644 --- a/cmd/evm/internal/t8ntool/transaction.go +++ b/cmd/evm/internal/t8ntool/transaction.go @@ -133,7 +133,7 @@ func Transaction(ctx *cli.Context) error { r.Address = sender } // Check intrinsic gas - if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.AuthList(), tx.To() == nil, + if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, chainConfig.IsHomestead(new(big.Int)), chainConfig.IsIstanbul(new(big.Int)), chainConfig.IsShanghai(new(big.Int), 0)); err != nil { r.Error = err results = append(results, r) diff --git a/core/state_transition.go b/core/state_transition.go index 1f6abed91d..93d72d16b7 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -131,19 +131,19 @@ func toWordSize(size uint64) uint64 { // A Message contains the data derived from a single transaction that is relevant to state // processing. type Message struct { - To *common.Address - From common.Address - Nonce uint64 - Value *big.Int - GasLimit uint64 - GasPrice *big.Int - GasFeeCap *big.Int - GasTipCap *big.Int - Data []byte - AccessList types.AccessList - BlobGasFeeCap *big.Int - BlobHashes []common.Hash - AuthList []types.SetCodeAuthorization + To *common.Address + From common.Address + Nonce uint64 + Value *big.Int + GasLimit uint64 + GasPrice *big.Int + GasFeeCap *big.Int + GasTipCap *big.Int + Data []byte + AccessList types.AccessList + BlobGasFeeCap *big.Int + BlobHashes []common.Hash + SetCodeAuthorizations []types.SetCodeAuthorization // When SkipNonceChecks is true, the message nonce is not checked against the // account nonce in state. @@ -157,20 +157,20 @@ type Message struct { // 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(), - AuthList: tx.AuthList(), - SkipNonceChecks: false, - SkipFromEOACheck: 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(), + SetCodeAuthorizations: tx.SetCodeAuthorizations(), + SkipNonceChecks: false, + SkipFromEOACheck: false, + BlobHashes: tx.BlobHashes(), + BlobGasFeeCap: tx.BlobGasFeeCap(), } // If baseFee provided, set gasPrice to effectiveGasPrice. if baseFee != nil { @@ -372,11 +372,11 @@ func (st *stateTransition) preCheck() error { } } // Check that EIP-7702 authorization list signatures are well formed. - if msg.AuthList != nil { + if msg.SetCodeAuthorizations != nil { if msg.To == nil { return fmt.Errorf("%w (sender %v)", ErrSetCodeTxCreate, msg.From) } - if len(msg.AuthList) == 0 { + if len(msg.SetCodeAuthorizations) == 0 { return fmt.Errorf("%w (sender %v)", ErrEmptyAuthList, msg.From) } } @@ -417,7 +417,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { ) // Check clauses 4-5, subtract intrinsic gas if everything is correct - gas, err := IntrinsicGas(msg.Data, msg.AccessList, msg.AuthList, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) + gas, err := IntrinsicGas(msg.Data, msg.AccessList, msg.SetCodeAuthorizations, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) if err != nil { return nil, err } @@ -467,8 +467,8 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1) // Apply EIP-7702 authorizations. - if msg.AuthList != nil { - for _, auth := range msg.AuthList { + if msg.SetCodeAuthorizations != nil { + for _, auth := range msg.SetCodeAuthorizations { // Note errors are ignored, we simply skip invalid authorizations here. st.applyAuthorization(msg, &auth) } diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 908945471d..412418dcc9 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -108,7 +108,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types } // Ensure the transaction has more gas than the bare minimum needed to cover // the transaction metadata - intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.AuthList(), tx.To() == nil, true, opts.Config.IsIstanbul(head.Number), opts.Config.IsShanghai(head.Number, head.Time)) + intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, true, opts.Config.IsIstanbul(head.Number), opts.Config.IsShanghai(head.Number, head.Time)) if err != nil { return err } diff --git a/core/types/transaction.go b/core/types/transaction.go index 24b110fa18..35dc1ea3f9 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -474,8 +474,8 @@ func (tx *Transaction) WithBlobTxSidecar(sideCar *BlobTxSidecar) *Transaction { return cpy } -// AuthList returns the authorizations list of the transaction. -func (tx *Transaction) AuthList() []SetCodeAuthorization { +// SetCodeAuthorizations returns the authorizations list of the transaction. +func (tx *Transaction) SetCodeAuthorizations() []SetCodeAuthorization { setcodetx, ok := tx.inner.(*SetCodeTx) if !ok { return nil diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 78fa2fc8ef..d72643b4a8 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -245,7 +245,7 @@ func (s pragueSigner) Hash(tx *Transaction) common.Hash { tx.Value(), tx.Data(), tx.AccessList(), - tx.AuthList(), + tx.SetCodeAuthorizations(), }) } diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 5776275c2b..e04b77f61f 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -161,7 +161,7 @@ func (t *prestateTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction t.lookupAccount(env.Coinbase) // Add accounts with authorizations to the prestate before they get applied. - for _, auth := range tx.AuthList() { + for _, auth := range tx.SetCodeAuthorizations() { addr, err := auth.Authority() if err != nil { continue diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 2ba27f43a8..d9cec560ea 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1049,7 +1049,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber } else { result.GasPrice = (*hexutil.Big)(tx.GasFeeCap()) } - result.AuthorizationList = tx.AuthList() + result.AuthorizationList = tx.SetCodeAuthorizations() } return result } diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index a9b563de74..a39a6666f4 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -454,21 +454,21 @@ func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck, skipEoA accessList = *args.AccessList } 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, - AuthList: args.AuthorizationList, - SkipNonceChecks: skipNonceCheck, - SkipFromEOACheck: skipEoACheck, + 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, + SetCodeAuthorizations: args.AuthorizationList, + SkipNonceChecks: skipNonceCheck, + SkipFromEOACheck: skipEoACheck, } } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 266bd7fd23..6e66bbaa72 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -457,19 +457,19 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess } msg := &core.Message{ - From: from, - To: to, - Nonce: tx.Nonce, - Value: value, - GasLimit: gasLimit, - GasPrice: gasPrice, - GasFeeCap: tx.MaxFeePerGas, - GasTipCap: tx.MaxPriorityFeePerGas, - Data: data, - AccessList: accessList, - BlobHashes: tx.BlobVersionedHashes, - BlobGasFeeCap: tx.BlobGasFeeCap, - AuthList: authList, + From: from, + To: to, + Nonce: tx.Nonce, + Value: value, + GasLimit: gasLimit, + GasPrice: gasPrice, + GasFeeCap: tx.MaxFeePerGas, + GasTipCap: tx.MaxPriorityFeePerGas, + Data: data, + AccessList: accessList, + BlobHashes: tx.BlobVersionedHashes, + BlobGasFeeCap: tx.BlobGasFeeCap, + SetCodeAuthorizations: authList, } return msg, nil } diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 4da27ff943..55b76df89c 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -59,7 +59,7 @@ func (tt *TransactionTest) Run(config *params.ChainConfig) error { return nil, nil, err } // Intrinsic gas - requiredGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.AuthList(), tx.To() == nil, isHomestead, isIstanbul, false) + requiredGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, isHomestead, isIstanbul, false) if err != nil { return nil, nil, err } From 341647f1865dab437a690dc1424ba71495de2dd8 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 19 Dec 2024 16:03:05 +0100 Subject: [PATCH 025/940] params: update system contracts for prague devnet-5 (#30938) --- params/protocol_params.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/params/protocol_params.go b/params/protocol_params.go index 4d2baf8054..b46e8d66b2 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -200,14 +200,14 @@ var ( BeaconRootsCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500") // EIP-2935 - Serve historical block hashes from state - HistoryStorageAddress = common.HexToAddress("0x0aae40965e6800cd9b1f4b05ff21581047e3f91e") - HistoryStorageCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500") + HistoryStorageAddress = common.HexToAddress("0x0F792be4B0c0cb4DAE440Ef133E90C0eCD48CCCC") + HistoryStorageCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500") // EIP-7002 - Execution layer triggerable withdrawals - WithdrawalQueueAddress = common.HexToAddress("0x09Fc772D0857550724b07B850a4323f39112aAaA") - WithdrawalQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460c7573615156028575f545f5260205ff35b36603814156101f05760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f057600182026001905f5b5f821115608057810190830284830290049160010191906065565b9093900434106101f057600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160db575060105b5f5b81811461017f5780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160dd565b9101809214610191579060025561019c565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101c957505f5b6001546002828201116101de5750505f6101e4565b01600290035b5f555f600155604c025ff35b5f5ffd") + WithdrawalQueueAddress = common.HexToAddress("0x0c15F14308530b7CDB8460094BbB9cC28b9AaaAA") + WithdrawalQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd") // EIP-7251 - Increase the MAX_EFFECTIVE_BALANCE - ConsolidationQueueAddress = common.HexToAddress("0x01aBEa29659e5e97C95107F20bb753cD3e09bBBb") - ConsolidationQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460cf573615156028575f545f5260205ff35b366060141561019a5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f821115608057810190830284830290049160010191906065565b90939004341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060011160e3575060015b5f5b8181146101295780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160e5565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd") + ConsolidationQueueAddress = common.HexToAddress("0x00431F263cE400f4455c2dCf564e53007Ca4bbBb") + ConsolidationQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd") ) From f4e8e877f6df3fe7d39f07d3c1852c3b43e2451c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=92?= <47621124+ronething-bot@users.noreply.github.com> Date: Thu, 2 Jan 2025 09:48:25 +0800 Subject: [PATCH 026/940] internal/flags: update copyright year to 2025 (#30976) --- internal/flags/helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/flags/helpers.go b/internal/flags/helpers.go index fd706869f1..170b67b310 100644 --- a/internal/flags/helpers.go +++ b/internal/flags/helpers.go @@ -40,7 +40,7 @@ func NewApp(usage string) *cli.App { app.EnableBashCompletion = true app.Version = version.WithCommit(git.Commit, git.Date) app.Usage = usage - app.Copyright = "Copyright 2013-2024 The go-ethereum Authors" + app.Copyright = "Copyright 2013-2025 The go-ethereum Authors" app.Before = func(ctx *cli.Context) error { MigrateGlobalFlags(ctx) return nil From 0feb999d3fd190cc67c59fc91b7094e54ff8e1a2 Mon Sep 17 00:00:00 2001 From: gitglorythegreat Date: Thu, 2 Jan 2025 21:04:06 +0800 Subject: [PATCH 027/940] crypto/bn256: fix MulScalar (#30974) The `a` parameter should be used in the `MulScalar` function. The upstream cloudflare and google repos have already merged fixes. Reference: * https://cs.opensource.google/go/x/crypto/+/8d7daa0c54b357f3071e11eaef7efc4e19a417e2 * https://github.com/cloudflare/bn256/pull/33 --- crypto/bn256/cloudflare/gfp12.go | 4 ++-- crypto/bn256/google/gfp12.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/bn256/cloudflare/gfp12.go b/crypto/bn256/cloudflare/gfp12.go index 93fb368a7b..767350701f 100644 --- a/crypto/bn256/cloudflare/gfp12.go +++ b/crypto/bn256/cloudflare/gfp12.go @@ -105,8 +105,8 @@ func (e *gfP12) Mul(a, b *gfP12) *gfP12 { } func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 { - e.x.Mul(&e.x, b) - e.y.Mul(&e.y, b) + e.x.Mul(&a.x, b) + e.y.Mul(&a.y, b) return e } diff --git a/crypto/bn256/google/gfp12.go b/crypto/bn256/google/gfp12.go index f084eddf21..2b0151ebcc 100644 --- a/crypto/bn256/google/gfp12.go +++ b/crypto/bn256/google/gfp12.go @@ -125,8 +125,8 @@ func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 { } func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 { - e.x.Mul(e.x, b, pool) - e.y.Mul(e.y, b, pool) + e.x.Mul(a.x, b, pool) + e.y.Mul(a.y, b, pool) return e } From 85ffbde427bd89be55bc54078d5d2158d325fba1 Mon Sep 17 00:00:00 2001 From: gitglorythegreat Date: Thu, 2 Jan 2025 21:06:47 +0800 Subject: [PATCH 028/940] all: use cmp.Compare (#30958) --- cmd/devp2p/dns_route53.go | 9 ++------- cmd/devp2p/nodeset.go | 9 ++------- core/state/snapshot/iterator_fast.go | 9 ++------- p2p/protocol.go | 9 ++------- triedb/pathdb/iterator_fast.go | 9 ++------- 5 files changed, 10 insertions(+), 35 deletions(-) diff --git a/cmd/devp2p/dns_route53.go b/cmd/devp2p/dns_route53.go index a6125b8263..86907688f3 100644 --- a/cmd/devp2p/dns_route53.go +++ b/cmd/devp2p/dns_route53.go @@ -17,6 +17,7 @@ package main import ( + "cmp" "context" "errors" "fmt" @@ -292,13 +293,7 @@ func sortChanges(changes []types.Change) { if a.Action == b.Action { return strings.Compare(*a.ResourceRecordSet.Name, *b.ResourceRecordSet.Name) } - if score[string(a.Action)] < score[string(b.Action)] { - return -1 - } - if score[string(a.Action)] > score[string(b.Action)] { - return 1 - } - return 0 + return cmp.Compare(score[string(a.Action)], score[string(b.Action)]) }) } diff --git a/cmd/devp2p/nodeset.go b/cmd/devp2p/nodeset.go index 4fa862de14..4a6df6cdfe 100644 --- a/cmd/devp2p/nodeset.go +++ b/cmd/devp2p/nodeset.go @@ -18,6 +18,7 @@ package main import ( "bytes" + "cmp" "encoding/json" "fmt" "os" @@ -104,13 +105,7 @@ func (ns nodeSet) topN(n int) nodeSet { byscore = append(byscore, v) } slices.SortFunc(byscore, func(a, b nodeJSON) int { - if a.Score > b.Score { - return -1 - } - if a.Score < b.Score { - return 1 - } - return 0 + return cmp.Compare(b.Score, a.Score) }) result := make(nodeSet, n) for _, v := range byscore[:n] { diff --git a/core/state/snapshot/iterator_fast.go b/core/state/snapshot/iterator_fast.go index 7f7ba876ff..61fc434178 100644 --- a/core/state/snapshot/iterator_fast.go +++ b/core/state/snapshot/iterator_fast.go @@ -18,6 +18,7 @@ package snapshot import ( "bytes" + "cmp" "fmt" "slices" "sort" @@ -45,13 +46,7 @@ func (it *weightedIterator) Cmp(other *weightedIterator) int { return 1 } // Same account/storage-slot in multiple layers, split by priority - if it.priority < other.priority { - return -1 - } - if it.priority > other.priority { - return 1 - } - return 0 + return cmp.Compare(it.priority, other.priority) } // fastIterator is a more optimized multi-layer iterator which maintains a diff --git a/p2p/protocol.go b/p2p/protocol.go index 9bb6785a22..de3127e233 100644 --- a/p2p/protocol.go +++ b/p2p/protocol.go @@ -17,6 +17,7 @@ package p2p import ( + "cmp" "fmt" "strings" @@ -81,13 +82,7 @@ func (cap Cap) String() string { // Cmp defines the canonical sorting order of capabilities. func (cap Cap) Cmp(other Cap) int { if cap.Name == other.Name { - if cap.Version < other.Version { - return -1 - } - if cap.Version > other.Version { - return 1 - } - return 0 + return cmp.Compare(cap.Version, other.Version) } return strings.Compare(cap.Name, other.Name) } diff --git a/triedb/pathdb/iterator_fast.go b/triedb/pathdb/iterator_fast.go index 217b211fcc..966e37a7cb 100644 --- a/triedb/pathdb/iterator_fast.go +++ b/triedb/pathdb/iterator_fast.go @@ -18,6 +18,7 @@ package pathdb import ( "bytes" + "cmp" "fmt" "slices" "sort" @@ -45,13 +46,7 @@ func (it *weightedIterator) Cmp(other *weightedIterator) int { return 1 } // Same account/storage-slot in multiple layers, split by priority - if it.priority < other.priority { - return -1 - } - if it.priority > other.priority { - return 1 - } - return 0 + return cmp.Compare(it.priority, other.priority) } // fastIterator is a more optimized multi-layer iterator which maintains a From 06883c16861fc034e1471c4f911cd309612b1f7f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 2 Jan 2025 18:37:58 +0100 Subject: [PATCH 029/940] eth/tracers/logger: skip system calls (#30923) This commit makes it so that the struct logger will not emit logs while system calls are being executed. This will make it consistent with the JSON and MD loggers. It is as it stands hard to distinguish when system calls are being processed vs when a tx is being processed. --------- Co-authored-by: Sina Mahmoodi --- eth/tracers/logger/logger.go | 64 +++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index dc9e6e62b7..07de871f14 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -217,6 +217,7 @@ type StructLogger struct { interrupt atomic.Bool // Atomic flag to signal execution interruption reason error // Textual reason for the interruption + skip bool // skip processing hooks. } // NewStreamingStructLogger returns a new streaming logger. @@ -240,10 +241,12 @@ func NewStructLogger(cfg *Config) *StructLogger { func (l *StructLogger) Hooks() *tracing.Hooks { return &tracing.Hooks{ - OnTxStart: l.OnTxStart, - OnTxEnd: l.OnTxEnd, - OnExit: l.OnExit, - OnOpcode: l.OnOpcode, + OnTxStart: l.OnTxStart, + OnTxEnd: l.OnTxEnd, + OnSystemCallStartV2: l.OnSystemCallStart, + OnSystemCallEnd: l.OnSystemCallEnd, + OnExit: l.OnExit, + OnOpcode: l.OnOpcode, } } @@ -255,6 +258,10 @@ func (l *StructLogger) OnOpcode(pc uint64, opcode byte, gas, cost uint64, scope if l.interrupt.Load() { return } + // Processing a system call. + if l.skip { + return + } // check if already accumulated the size of the response. if l.cfg.Limit != 0 && l.resultSize > l.cfg.Limit { return @@ -320,6 +327,9 @@ func (l *StructLogger) OnExit(depth int, output []byte, gasUsed uint64, err erro if depth != 0 { return } + if l.skip { + return + } l.output = output l.err = err // TODO @holiman, should we output the per-scope output? @@ -360,6 +370,13 @@ func (l *StructLogger) Stop(err error) { func (l *StructLogger) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { l.env = env } +func (l *StructLogger) OnSystemCallStart(env *tracing.VMContext) { + l.skip = true +} + +func (l *StructLogger) OnSystemCallEnd() { + l.skip = false +} func (l *StructLogger) OnTxEnd(receipt *types.Receipt, err error) { if err != nil { @@ -389,9 +406,10 @@ func WriteTrace(writer io.Writer, logs []StructLog) { } type mdLogger struct { - out io.Writer - cfg *Config - env *tracing.VMContext + out io.Writer + cfg *Config + env *tracing.VMContext + skip bool } // NewMarkdownLogger creates a logger which outputs information in a format adapted @@ -406,11 +424,13 @@ func NewMarkdownLogger(cfg *Config, writer io.Writer) *mdLogger { func (t *mdLogger) Hooks() *tracing.Hooks { return &tracing.Hooks{ - OnTxStart: t.OnTxStart, - OnEnter: t.OnEnter, - OnExit: t.OnExit, - OnOpcode: t.OnOpcode, - OnFault: t.OnFault, + OnTxStart: t.OnTxStart, + OnSystemCallStartV2: t.OnSystemCallStart, + OnSystemCallEnd: t.OnSystemCallEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnOpcode: t.OnOpcode, + OnFault: t.OnFault, } } @@ -418,7 +438,18 @@ func (t *mdLogger) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from t.env = env } +func (t *mdLogger) OnSystemCallStart(env *tracing.VMContext) { + t.skip = true +} + +func (t *mdLogger) OnSystemCallEnd() { + t.skip = false +} + func (t *mdLogger) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + if t.skip { + return + } if depth != 0 { return } @@ -446,6 +477,9 @@ func (t *mdLogger) OnEnter(depth int, typ byte, from common.Address, to common.A } func (t *mdLogger) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if t.skip { + return + } if depth == 0 { fmt.Fprintf(t.out, "\nPost-execution info:\n"+ " - output: `%#x`\n"+ @@ -457,6 +491,9 @@ func (t *mdLogger) OnExit(depth int, output []byte, gasUsed uint64, err error, r // 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) { + if t.skip { + return + } stack := scope.StackData() fmt.Fprintf(t.out, "| %4d | %10v | %3d |%10v |", pc, vm.OpCode(op).String(), cost, t.env.StateDB.GetRefund()) @@ -477,6 +514,9 @@ func (t *mdLogger) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing. } func (t *mdLogger) OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error) { + if t.skip { + return + } fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err) } From a9ab53d751b018ee493b909d520eb5f3daba6734 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 3 Jan 2025 13:15:06 +0100 Subject: [PATCH 030/940] internal/ethapi: update default simulation timestamp increment to 12 (#30981) Update the default timestamp increment to 12s for `eth_simulate` endpoint --- internal/ethapi/simulate.go | 2 +- internal/ethapi/simulate_test.go | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 5bd0079a93..130eaa9724 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -45,7 +45,7 @@ const ( maxSimulateBlocks = 256 // timestampIncrement is the default increment between block timestamps. - timestampIncrement = 1 + timestampIncrement = 12 ) // simBlock is a batch of calls to be simulated sequentially. diff --git a/internal/ethapi/simulate_test.go b/internal/ethapi/simulate_test.go index 52ae40cad0..c747b76477 100644 --- a/internal/ethapi/simulate_test.go +++ b/internal/ethapi/simulate_test.go @@ -41,19 +41,19 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) { baseNumber: 10, baseTimestamp: 50, blocks: []simBlock{{}, {}, {}}, - expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 53}}, + expected: []result{{number: 11, timestamp: 62}, {number: 12, timestamp: 74}, {number: 13, timestamp: 86}}, }, { baseNumber: 10, baseTimestamp: 50, - blocks: []simBlock{{BlockOverrides: &override.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}}, + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(80)}}, {}}, + expected: []result{{number: 11, timestamp: 62}, {number: 12, timestamp: 74}, {number: 13, timestamp: 80}, {number: 14, timestamp: 92}}, }, { baseNumber: 10, baseTimestamp: 50, blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11)}}, {BlockOverrides: &override.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}}, + expected: []result{{number: 11, timestamp: 62}, {number: 12, timestamp: 74}, {number: 13, timestamp: 86}, {number: 14, timestamp: 98}, {number: 15, timestamp: 110}}, }, { baseNumber: 10, @@ -64,8 +64,8 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) { { baseNumber: 10, baseTimestamp: 50, - blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(52)}}}, - err: "block timestamps must be in order: 52 <= 52", + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(74)}}}, + err: "block timestamps must be in order: 74 <= 74", }, { baseNumber: 10, @@ -76,8 +76,8 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) { { baseNumber: 10, baseTimestamp: 50, - blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(61)}}}, - err: "block timestamps must be in order: 61 <= 61", + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(72)}}}, + err: "block timestamps must be in order: 72 <= 72", }, } { sim := &simulator{base: &types.Header{Number: big.NewInt(int64(tc.baseNumber)), Time: tc.baseTimestamp}} From c5a8d3485191d15363b9817da1afcac3fce5ddeb Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 6 Jan 2025 07:52:01 +0100 Subject: [PATCH 031/940] core/rawdb: fix panic in freezer (#30973) Fixes an issue where the node panics when an LStat fails with something other than os.ErrNotExist closes https://github.com/ethereum/go-ethereum/issues/30968 --- core/rawdb/freezer.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index d6370cee33..c5a72eff7e 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -87,6 +87,10 @@ func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize ui ) // Ensure the datadir is not a symbolic link if it exists. if info, err := os.Lstat(datadir); !os.IsNotExist(err) { + if info == nil { + log.Warn("Could not Lstat the database", "path", datadir) + return nil, errors.New("lstat failed") + } if info.Mode()&os.ModeSymlink != 0 { log.Warn("Symbolic link ancient database is not supported", "path", datadir) return nil, errSymlinkDatadir From 6897a4a9e0c825c01b63971ee1fe6b9fbc2b4cd3 Mon Sep 17 00:00:00 2001 From: georgehao Date: Mon, 6 Jan 2025 23:28:28 +0800 Subject: [PATCH 032/940] core/types: improve printList in DeriveSha test (#30969) --- core/types/hashing_test.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/core/types/hashing_test.go b/core/types/hashing_test.go index a6949414f3..c846ecd0c5 100644 --- a/core/types/hashing_test.go +++ b/core/types/hashing_test.go @@ -111,7 +111,7 @@ func TestFuzzDeriveSha(t *testing.T) { exp := types.DeriveSha(newDummy(i), trie.NewEmpty(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil))) got := types.DeriveSha(newDummy(i), trie.NewStackTrie(nil)) if !bytes.Equal(got[:], exp[:]) { - printList(newDummy(seed)) + printList(t, newDummy(seed)) t.Fatalf("seed %d: got %x exp %x", seed, got, exp) } } @@ -192,15 +192,21 @@ func (d *dummyDerivableList) EncodeIndex(i int, w *bytes.Buffer) { io.CopyN(w, mrand.New(src), size) } -func printList(l types.DerivableList) { - fmt.Printf("list length: %d\n", l.Len()) - fmt.Printf("{\n") +func printList(t *testing.T, l types.DerivableList) { + var buf bytes.Buffer + _, _ = fmt.Fprintf(&buf, "list length: %d, ", l.Len()) + buf.WriteString("list: [") for i := 0; i < l.Len(); i++ { - var buf bytes.Buffer - l.EncodeIndex(i, &buf) - fmt.Printf("\"%#x\",\n", buf.Bytes()) + var itemBuf bytes.Buffer + l.EncodeIndex(i, &itemBuf) + if i == l.Len()-1 { + _, _ = fmt.Fprintf(&buf, "\"%#x\"", itemBuf.Bytes()) + } else { + _, _ = fmt.Fprintf(&buf, "\"%#x\",", itemBuf.Bytes()) + } } - fmt.Printf("},\n") + buf.WriteString("]") + t.Log(buf.String()) } type flatList []string From 92980746339dcaf397a0367dca0ddf3d27664d28 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Mon, 6 Jan 2025 16:31:53 +0100 Subject: [PATCH 033/940] eth/protocols/eth: prevent hanging dispatch (#30918) This PR attempts to fix a strange test-failure (timeout) observed on a windows-32 platform. https://ci.appveyor.com/project/ethereum/go-ethereum/builds/51174391/job/d8ascanwwltrlqd5 A goroutine is stuck trying to deliver a response: ``` goroutine 9632 [select, 29 minutes]: github.com/ethereum/go-ethereum/eth/protocols/eth.(*Peer).dispatchResponse(0x314f100, 0x3e5f6d0, 0x3acbb84) C:/projects/go-ethereum/eth/protocols/eth/dispatcher.go:172 +0x2a5 github.com/ethereum/go-ethereum/eth/protocols/eth.handleBlockHeaders({0x12abe68, 0x30021b8}, {0x12a815c, 0x40b41c0}, 0x314f100) C:/projects/go-ethereum/eth/protocols/eth/handlers.go:301 +0x173 github.com/ethereum/go-ethereum/eth/protocols/eth.handleMessage({0x12abe68, 0x30021b8}, 0x314f100) C:/projects/go-ethereum/eth/protocols/eth/handler.go:205 +0x4f6 github.com/ethereum/go-ethereum/eth/protocols/eth.Handle({0x12abe68, 0x30021b8}, 0x314f100) C:/projects/go-ethereum/eth/protocols/eth/handler.go:149 +0x33 github.com/ethereum/go-ethereum/eth.testSnapSyncDisabling.func1(0x314f100) C:/projects/go-ethereum/eth/sync_test.go:65 +0x33 github.com/ethereum/go-ethereum/eth.(*handler).runEthPeer(0x30021b8, 0x314f100, 0x427f648) C:/projects/go-ethereum/eth/handler.go:355 +0xe65 created by github.com/ethereum/go-ethereum/eth.testSnapSyncDisabling in goroutine 11 C:/projects/go-ethereum/eth/sync_test.go:64 +0x54f FAIL github.com/ethereum/go-ethereum/eth 1800.138s ``` --------- Co-authored-by: Gary Rong --- eth/protocols/eth/dispatcher.go | 2 ++ eth/sync_test.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/eth/protocols/eth/dispatcher.go b/eth/protocols/eth/dispatcher.go index 146eec3f60..cba40596fc 100644 --- a/eth/protocols/eth/dispatcher.go +++ b/eth/protocols/eth/dispatcher.go @@ -174,6 +174,8 @@ func (p *Peer) dispatchResponse(res *Response, metadata func() interface{}) erro return <-res.Done // Response delivered, return any errors case <-res.Req.cancel: return nil // Request cancelled, silently discard response + case <-p.term: + return errDisconnected } } diff --git a/eth/sync_test.go b/eth/sync_test.go index 57eea73790..cad3a4732e 100644 --- a/eth/sync_test.go +++ b/eth/sync_test.go @@ -88,7 +88,7 @@ func testSnapSyncDisabling(t *testing.T, ethVer uint, snapVer uint) { if err := empty.handler.downloader.BeaconSync(ethconfig.SnapSync, full.chain.CurrentBlock(), nil); err != nil { t.Fatal("sync failed:", err) } - empty.handler.enableSyncedFeatures() + time.Sleep(time.Second * 5) // Downloader internally has to wait a timer (3s) to be expired before exiting if empty.handler.snapSync.Load() { t.Fatalf("snap sync not disabled after successful synchronisation") From e75f354ae7c29d70f100477afa3600cbeff9f5b4 Mon Sep 17 00:00:00 2001 From: Savely <136869149+savvar9991@users.noreply.github.com> Date: Tue, 7 Jan 2025 20:31:10 +1100 Subject: [PATCH 034/940] cmd/clef: fix JS issues in documentation (#30980) Fixes a couple of js-flaws in the docs --- cmd/clef/rules.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/clef/rules.md b/cmd/clef/rules.md index cc4a645596..3cd1bb52c6 100644 --- a/cmd/clef/rules.md +++ b/cmd/clef/rules.md @@ -7,7 +7,7 @@ It enables usecases like the following: * I want to auto-approve transactions with contract `CasinoDapp`, with up to `0.05 ether` in value to maximum `1 ether` per 24h period * I want to auto-approve transaction to contract `EthAlarmClock` with `data`=`0xdeadbeef`, if `value=0`, `gas < 44k` and `gasPrice < 40Gwei` -The two main features that are required for this to work well are; +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 management and credentials; how to provide auto-unlock without exposing keys unnecessarily. @@ -29,10 +29,10 @@ function asBig(str) { // Approve transactions to a certain contract if the value is below a certain limit function ApproveTx(req) { - var limit = big.Newint("0xb1a2bc2ec50000") + var limit = new BigNumber("0xb1a2bc2ec50000") var value = asBig(req.transaction.value); - if (req.transaction.to.toLowerCase() == "0xae967917c465db8578ca9024c205720b1a3651a9") && value.lt(limit)) { + if (req.transaction.to.toLowerCase() == "0xae967917c465db8578ca9024c205720b1a3651a9" && value.lt(limit)) { return "Approve" } // If we return "Reject", it will be rejected. From 5065e6c9356276e8fa877536ab82f25fb9fa5c86 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 7 Jan 2025 13:49:13 +0300 Subject: [PATCH 035/940] triedb/pathdb: fix tester generator (#30972) This change fixes is a rare bug in test generator: If the run is very unlucky it can use `modifyAccountOp` / `deleteAccountOp` without creating any account, leading to have a trie root same as the parent. This change makes the first operation always be a creation. --- triedb/pathdb/database_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index 648230df15..3b35370c84 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -222,7 +222,12 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode dirties = make(map[common.Hash]struct{}) ) for i := 0; i < 20; i++ { - switch rand.Intn(opLen) { + // Start with account creation always + op := createAccountOp + if i > 0 { + op = rand.Intn(opLen) + } + switch op { case createAccountOp: // account creation addr := testrand.Address() From 033de2a05bdbea87b4efc5156511afe42c38fd55 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 8 Jan 2025 14:22:37 +0100 Subject: [PATCH 036/940] README: remove private network section from readme (#31005) --- README.md | 125 ++++-------------------------------------------------- 1 file changed, 9 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 27842008aa..45b80e86a6 100644 --- a/README.md +++ b/README.md @@ -54,14 +54,14 @@ on how you can run your own `geth` instance. Minimum: -* CPU with 2+ cores -* 4GB RAM +* CPU with 4+ cores +* 8GB RAM * 1TB free storage space to sync the Mainnet * 8 MBit/sec download Internet service Recommended: -* Fast CPU with 4+ cores +* Fast CPU with 8+ cores * 16GB+ RAM * High-performance SSD with at least 1TB of free space * 25+ MBit/sec download Internet service @@ -138,8 +138,6 @@ export your existing configuration: $ geth --your-favourite-flags dumpconfig ``` -*Note: This works only with `geth` v1.6.0 and above.* - #### Docker quick start One of the quickest ways to get Ethereum up and running on your machine is by using @@ -187,7 +185,6 @@ HTTP based JSON-RPC API options: * `--ws.api` API's offered over the WS-RPC interface (default: `eth,net,web3`) * `--ws.origins` Origins from which to accept WebSocket requests * `--ipcdisable` Disable the IPC-RPC server - * `--ipcapi` API's offered over the IPC-RPC interface (default: `admin,debug,eth,miner,net,personal,txpool,web3`) * `--ipcpath` Filename for IPC socket/pipe within the datadir (explicit paths escape it) You'll need to use your own programming environments' capabilities (libraries, tools, etc) to @@ -206,118 +203,14 @@ APIs!** Maintaining your own private network is more involved as a lot of configurations taken for granted in the official networks need to be manually set up. -#### Defining the private genesis state +Unfortunately since [the Merge](https://ethereum.org/en/roadmap/merge/) it is no longer possible +to easily set up a network of geth nodes without also setting up a corresponding beacon chain. -First, you'll need to create the genesis state of your networks, which all nodes need to be -aware of and agree upon. This consists of a small JSON file (e.g. call it `genesis.json`): +There are three different solutions depending on your use case: -```json -{ - "config": { - "chainId": , - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0 - }, - "alloc": {}, - "coinbase": "0x0000000000000000000000000000000000000000", - "difficulty": "0x20000", - "extraData": "", - "gasLimit": "0x2fefd8", - "nonce": "0x0000000000000042", - "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x00" -} -``` - -The above fields should be fine for most purposes, although we'd recommend changing -the `nonce` to some random value so you prevent unknown remote nodes from being able -to connect to you. If you'd like to pre-fund some accounts for easier testing, create -the accounts and populate the `alloc` field with their addresses. - -```json -"alloc": { - "0x0000000000000000000000000000000000000001": { - "balance": "111111111" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "222222222" - } -} -``` - -With the genesis state defined in the above JSON file, you'll need to initialize **every** -`geth` node with it prior to starting it up to ensure all blockchain parameters are correctly -set: - -```shell -$ geth init path/to/genesis.json -``` - -#### Creating the rendezvous point - -With all nodes that you want to run initialized to the desired genesis state, you'll need to -start a bootstrap node that others can use to find each other in your network and/or over -the internet. The clean way is to configure and run a dedicated bootnode: - -```shell -# Use the devp2p tool to create a node file. -# The devp2p tool is also part of the 'alltools' distribution bundle. -$ devp2p key generate node1.key -# file node1.key is created. -$ devp2p key to-enr -ip 10.2.3.4 -udp 30303 -tcp 30303 node1.key -# Prints the ENR for use in --bootnode flag of other nodes. -# Note this method requires knowing the IP/ports ahead of time. -$ geth --nodekey=node1.key -``` - -With the bootnode online, it will display an [`enode` URL](https://ethereum.org/en/developers/docs/networking-layer/network-addresses/#enode) -that other nodes can use to connect to it and exchange peer information. Make sure to -replace the displayed IP address information (most probably `[::]`) with your externally -accessible IP to get the actual `enode` URL. - -*Note: You could previously use the `bootnode` utility to start a stripped down version of geth. This is not possible anymore.* - -#### Starting up your member nodes - -With the bootnode operational and externally reachable (you can try -`telnet ` to ensure it's indeed reachable), start every subsequent `geth` -node pointed to the bootnode for peer discovery via the `--bootnodes` flag. It will -probably also be desirable to keep the data directory of your private network separated, so -do also specify a custom `--datadir` flag. - -```shell -$ geth --datadir=path/to/custom/data/folder --bootnodes= -``` - -*Note: Since your network will be completely cut off from the main and test networks, you'll -also need to configure a miner to process transactions and create new blocks for you.* - -#### Running a private miner - - -In a private network setting a single CPU miner instance is more than enough for -practical purposes as it can produce a stable stream of blocks at the correct intervals -without needing heavy resources (consider running on a single thread, no need for multiple -ones either). To start a `geth` instance for mining, run it with all your usual flags, extended -by: - -```shell -$ geth --mine --miner.threads=1 --miner.etherbase=0x0000000000000000000000000000000000000000 -``` - -Which will start mining blocks and transactions on a single CPU thread, crediting all -proceedings to the account specified by `--miner.etherbase`. You can further tune the mining -by changing the default gas limit blocks converge to (`--miner.targetgaslimit`) and the price -transactions are accepted at (`--miner.gasprice`). + * If you are looking for a simple way to test smart contracts from go in your CI, you can use the [Simulated Backend](https://geth.ethereum.org/docs/developers/dapp-developer/native-bindings#blockchain-simulator). + * If you want a convenient single node environment for testing, you can use our [Dev Mode](https://geth.ethereum.org/docs/developers/dapp-developer/dev-mode). + * If you are looking for a multiple node test network, you can set one up quite easily with [Kurtosis](https://geth.ethereum.org/docs/fundamentals/kurtosis). ## Contribution From 82e963e5c981e36dc4b607dd0685c64cf4aabea8 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 10 Jan 2025 20:51:19 +0800 Subject: [PATCH 037/940] triedb/pathdb: configure different node hasher in pathdb (#31008) As the node hash scheme in verkle and merkle are totally different, the original default node hasher in pathdb is no longer suitable. Therefore, this pull request configures different node hasher respectively. --- core/genesis.go | 12 ++++- core/state/stateupdate.go | 5 +- core/types/hashes.go | 11 ---- internal/ethapi/override/override_test.go | 3 +- trie/trie_reader.go | 4 -- triedb/pathdb/database.go | 62 +++++++++++++++++------ triedb/pathdb/database_test.go | 4 +- triedb/pathdb/journal.go | 15 +++--- triedb/pathdb/layertree.go | 5 +- 9 files changed, 71 insertions(+), 50 deletions(-) diff --git a/core/genesis.go b/core/genesis.go index 85ef049ba6..347789cf0c 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -127,8 +127,12 @@ 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. + emptyRoot := types.EmptyRootHash + if isVerkle { + emptyRoot = types.EmptyVerkleHash + } db := rawdb.NewMemoryDatabase() - statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb.NewDatabase(db, config), nil)) + statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil)) if err != nil { return common.Hash{}, err } @@ -148,7 +152,11 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (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) { - statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb, nil)) + emptyRoot := types.EmptyRootHash + if triedb.IsVerkle() { + emptyRoot = types.EmptyVerkleHash + } + statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil)) if err != nil { return common.Hash{}, err } diff --git a/core/state/stateupdate.go b/core/state/stateupdate.go index a320b72f11..45de660ca5 100644 --- a/core/state/stateupdate.go +++ b/core/state/stateupdate.go @@ -20,7 +20,6 @@ import ( "maps" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/triedb" ) @@ -133,8 +132,8 @@ func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common } } return &stateUpdate{ - originRoot: types.TrieRootHash(originRoot), - root: types.TrieRootHash(root), + originRoot: originRoot, + root: root, accounts: accounts, accountsOrigin: accountsOrigin, storages: storages, diff --git a/core/types/hashes.go b/core/types/hashes.go index 55506d63d0..05cfaeed74 100644 --- a/core/types/hashes.go +++ b/core/types/hashes.go @@ -19,7 +19,6 @@ package types import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" ) var ( @@ -47,13 +46,3 @@ var ( // EmptyVerkleHash is the known hash of an empty verkle trie. EmptyVerkleHash = common.Hash{} ) - -// TrieRootHash returns the hash itself if it's non-empty or the predefined -// emptyHash one instead. -func TrieRootHash(hash common.Hash) common.Hash { - if hash == (common.Hash{}) { - log.Error("Zero trie root hash!") - return EmptyRootHash - } - return hash -} diff --git a/internal/ethapi/override/override_test.go b/internal/ethapi/override/override_test.go index 07ed6442b2..02a17c1331 100644 --- a/internal/ethapi/override/override_test.go +++ b/internal/ethapi/override/override_test.go @@ -24,6 +24,7 @@ import ( "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/core/vm" "github.com/ethereum/go-ethereum/triedb" ) @@ -36,7 +37,7 @@ 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) + statedb, err := state.New(types.EmptyRootHash, db) if err != nil { t.Fatalf("failed to create statedb: %v", err) } diff --git a/trie/trie_reader.go b/trie/trie_reader.go index 4b8ba808df..a42cdb0cf9 100644 --- a/trie/trie_reader.go +++ b/trie/trie_reader.go @@ -19,7 +19,6 @@ package trie 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/triedb/database" ) @@ -34,9 +33,6 @@ type trieReader struct { // newTrieReader initializes the trie reader with the given node reader. func newTrieReader(stateRoot, owner common.Hash, db database.NodeDatabase) (*trieReader, error) { if stateRoot == (common.Hash{}) || stateRoot == types.EmptyRootHash { - if stateRoot == (common.Hash{}) { - log.Error("Zero state root hash!") - } return &trieReader{owner: owner}, nil } reader, err := db.NodeReader(stateRoot) diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index 914b17de5b..c31f1d44f4 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/ethereum/go-verkle" ) const ( @@ -148,6 +149,29 @@ var Defaults = &Config{ // ReadOnly is the config in order to open database in read only mode. var ReadOnly = &Config{ReadOnly: true} +// nodeHasher is the function to compute the hash of supplied node blob. +type nodeHasher func([]byte) (common.Hash, error) + +// merkleNodeHasher computes the hash of the given merkle node. +func merkleNodeHasher(blob []byte) (common.Hash, error) { + if len(blob) == 0 { + return types.EmptyRootHash, nil + } + return crypto.Keccak256Hash(blob), nil +} + +// verkleNodeHasher computes the hash of the given verkle node. +func verkleNodeHasher(blob []byte) (common.Hash, error) { + if len(blob) == 0 { + return types.EmptyVerkleHash, nil + } + n, err := verkle.ParseNode(blob, 0) + if err != nil { + return common.Hash{}, err + } + return n.Commit().Bytes(), nil +} + // Database is a multiple-layered structure for maintaining in-memory states // along with its dirty trie nodes. It consists of one persistent base layer // backed by a key-value store, on top of which arbitrarily many in-memory diff @@ -164,9 +188,10 @@ 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 - isVerkle bool // Flag if database is used for verkle tree + 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 + hasher nodeHasher // Trie node hasher config *Config // Configuration for database diskdb ethdb.Database // Persistent storage for matured trie nodes @@ -184,19 +209,21 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { } config = config.sanitize() + db := &Database{ + readOnly: config.ReadOnly, + isVerkle: isVerkle, + config: config, + diskdb: diskdb, + hasher: merkleNodeHasher, + } // 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, - config: config, - diskdb: diskdb, + db.diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix)) + db.hasher = verkleNodeHasher } // Construct the layer tree by resolving the in-disk singleton state // and in-memory layer journal. @@ -277,6 +304,8 @@ func (db *Database) repairHistory() error { // // The passed in maps(nodes, states) will be retained to avoid copying everything. // Therefore, these maps must not be changed afterwards. +// +// The supplied parentRoot and root must be a valid trie hash value. func (db *Database) Update(root common.Hash, parentRoot common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *StateSetWithOrigin) error { // Hold the lock to prevent concurrent mutations. db.lock.Lock() @@ -350,10 +379,9 @@ func (db *Database) Enable(root common.Hash) error { return errDatabaseReadOnly } // Ensure the provided state root matches the stored one. - root = types.TrieRootHash(root) - stored := types.EmptyRootHash - if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { - stored = crypto.Keccak256Hash(blob) + stored, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil)) + if err != nil { + return err } if stored != root { return fmt.Errorf("state root mismatch: stored %x, synced %x", stored, root) @@ -389,6 +417,8 @@ 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. +// +// The supplied root must be a valid trie hash value. func (db *Database) Recover(root common.Hash) error { db.lock.Lock() defer db.lock.Unlock() @@ -401,7 +431,6 @@ func (db *Database) Recover(root common.Hash) error { return errors.New("state rollback is non-supported") } // Short circuit if the target state is not recoverable - root = types.TrieRootHash(root) if !db.Recoverable(root) { return errStateUnrecoverable } @@ -434,9 +463,10 @@ func (db *Database) Recover(root common.Hash) error { } // Recoverable returns the indicator if the specified state is recoverable. +// +// The supplied root must be a valid trie hash value. func (db *Database) Recoverable(root common.Hash) bool { // Ensure the requested state is a known state. - root = types.TrieRootHash(root) id := rawdb.ReadStateID(db.diskdb, root) if id == nil { return false diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index 3b35370c84..a6b1d3c045 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -458,8 +458,8 @@ func TestDatabaseRecoverable(t *testing.T) { // Initial state should be recoverable {types.EmptyRootHash, true}, - // Initial state should be recoverable - {common.Hash{}, true}, + // common.Hash{} is not a valid state root for revert + {common.Hash{}, false}, // Layers below current disk layer are recoverable {tester.roots[index-1], true}, diff --git a/triedb/pathdb/journal.go b/triedb/pathdb/journal.go index 779a262fdd..267d675bc2 100644 --- a/triedb/pathdb/journal.go +++ b/triedb/pathdb/journal.go @@ -26,7 +26,6 @@ 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/log" "github.com/ethereum/go-ethereum/rlp" ) @@ -93,9 +92,9 @@ 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. - var root = types.EmptyRootHash - if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { - root = crypto.Keccak256Hash(blob) + root, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil)) + if err != nil { + log.Crit("Failed to compute node hash", "err", err) } // Load the layers by resolving the journal head, err := db.loadJournal(root) @@ -236,6 +235,8 @@ func (dl *diffLayer) journal(w io.Writer) error { // This is meant to be used during shutdown to persist the layer without // flattening everything down (bad for reorgs). And this function will mark the // database as read-only to prevent all following mutation to disk. +// +// The supplied root must be a valid trie hash value. func (db *Database) Journal(root common.Hash) error { // Retrieve the head layer to journal from. l := db.tree.get(root) @@ -265,9 +266,9 @@ func (db *Database) Journal(root common.Hash) error { } // Secondly write out the state root in disk, ensure all layers // on top are continuous with disk. - diskRoot := types.EmptyRootHash - if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { - diskRoot = crypto.Keccak256Hash(blob) + diskRoot, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil)) + if err != nil { + return err } if err := rlp.Encode(journal, diskRoot); err != nil { return err diff --git a/triedb/pathdb/layertree.go b/triedb/pathdb/layertree.go index cf6b14e744..0bd086c2f3 100644 --- a/triedb/pathdb/layertree.go +++ b/triedb/pathdb/layertree.go @@ -22,7 +22,6 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/trie/trienode" ) @@ -62,7 +61,7 @@ func (tree *layerTree) get(root common.Hash) layer { tree.lock.RLock() defer tree.lock.RUnlock() - return tree.layers[types.TrieRootHash(root)] + return tree.layers[root] } // forEach iterates the stored layers inside and applies the @@ -92,7 +91,6 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6 // // Although we could silently ignore this internally, it should be the caller's // responsibility to avoid even attempting to insert such a layer. - root, parentRoot = types.TrieRootHash(root), types.TrieRootHash(parentRoot) if root == parentRoot { return errors.New("layer cycle") } @@ -112,7 +110,6 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6 // are crossed. All diffs beyond the permitted number are flattened downwards. func (tree *layerTree) cap(root common.Hash, layers int) error { // Retrieve the head layer to cap from - root = types.TrieRootHash(root) l := tree.get(root) if l == nil { return fmt.Errorf("triedb layer [%#x] missing", root) From c0882429f032da58620bcaa610007939aa7e0adb Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 13 Jan 2025 15:26:10 +0800 Subject: [PATCH 038/940] build: upgrade golangci-lint to v1.63.4 (#31019) This PR upgrades `golangci-lint` to v1.63.4 and fixes a warn message which is reported by v1.63.4: ```text WARN [config_reader] The configuration option `run.skip-dirs-use-default` is deprecated, please use `issues.exclude-dirs-use-default`. ``` Also fixes 2 warnings which are reported by v1.63.4: ```text core/txpool/blobpool/blobpool.go:1754:12: S1005: unnecessary assignment to the blank identifier (gosimple) for acct, _ := range p.index { ^ core/txpool/legacypool/legacypool.go:1989:19: S1005: unnecessary assignment to the blank identifier (gosimple) for localSender, _ := range pool.locals.accounts { ^ ``` --- .golangci.yml | 6 +-- build/checksums.txt | 60 ++++++++++++++-------------- core/txpool/blobpool/blobpool.go | 2 +- core/txpool/legacypool/legacypool.go | 2 +- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index e355e6f9d1..b63251055b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,9 +3,6 @@ run: timeout: 20m tests: true - # default is true. Enables skipping of directories: - # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ - skip-dirs-use-default: true linters: disable-all: true @@ -54,6 +51,9 @@ linters-settings: exclude: [""] issues: + # default is true. Enables skipping of directories: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + exclude-dirs-use-default: true exclude-files: - core/genesis_alloc.go exclude-rules: diff --git a/build/checksums.txt b/build/checksums.txt index b8061c9244..b0b7a73a3b 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -56,37 +56,37 @@ fc77c0531406d092c5356167e45c05a22d16bea84e3fa555e0f03af085c11763 go1.23.4.windo 8347c1aa4e1e67954d12830f88dbe44bd7ac0ec134bb472783dbfb5a3a8865d0 go1.23.4.windows-arm64.msi db69cae5006753c785345c3215ad941f8b6224e2f81fec471c42d6857bee0e6f go1.23.4.windows-arm64.zip -# version:golangci 1.61.0 +# version:golangci 1.63.4 # https://github.com/golangci/golangci-lint/releases/ -# https://github.com/golangci/golangci-lint/releases/download/v1.61.0/ -5c280ef3284f80c54fd90d73dc39ca276953949da1db03eb9dd0fbf868cc6e55 golangci-lint-1.61.0-darwin-amd64.tar.gz -544334890701e4e04a6e574bc010bea8945205c08c44cced73745a6378012d36 golangci-lint-1.61.0-darwin-arm64.tar.gz -e885a6f561092055930ebd298914d80e8fd2e10d2b1e9942836c2c6a115301fa golangci-lint-1.61.0-freebsd-386.tar.gz -b13f6a3f11f65e7ff66b734d7554df3bbae0f485768848424e7554ed289e19c2 golangci-lint-1.61.0-freebsd-amd64.tar.gz -cd8e7bbe5b8f33ed1597aa1cc588da96a3b9f22e1b9ae60d93511eae1a0ee8c5 golangci-lint-1.61.0-freebsd-armv6.tar.gz -7ade524dbd88bd250968f45e190af90e151fa5ee63dd6aa7f7bb90e8155db61d golangci-lint-1.61.0-freebsd-armv7.tar.gz -0fe3cd8a1ed8d9f54f48670a5af3df056d6040d94017057f0f4d65c930660ad9 golangci-lint-1.61.0-illumos-amd64.tar.gz -b463fc5053a612abd26393ebaff1d85d7d56058946f4f0f7bf25ed44ea899415 golangci-lint-1.61.0-linux-386.tar.gz -77cb0af99379d9a21d5dc8c38364d060e864a01bd2f3e30b5e8cc550c3a54111 golangci-lint-1.61.0-linux-amd64.tar.gz -af60ac05566d9351615cb31b4cc070185c25bf8cbd9b09c1873aa5ec6f3cc17e golangci-lint-1.61.0-linux-arm64.tar.gz -1f307f2fcc5d7d674062a967a0d83a7091e300529aa237ec6ad2b3dd14c897f5 golangci-lint-1.61.0-linux-armv6.tar.gz -3ad8cbaae75a547450844811300f99c4cd290277398e43d22b9eb1792d15af4c golangci-lint-1.61.0-linux-armv7.tar.gz -9be2ca67d961d7699079739cf6f7c8291c5183d57e34d1677de21ca19d0bd3ed golangci-lint-1.61.0-linux-loong64.tar.gz -90d005e1648115ebf0861b408eab9c936079a24763e883058b0a227cd3135d31 golangci-lint-1.61.0-linux-mips64.tar.gz -6d2ed4f49407115460b8c10ccfc40fd177e0887a48864a2879dd16e84ba2a48c golangci-lint-1.61.0-linux-mips64le.tar.gz -633089589af5a58b7430afb6eee107d4e9c99e8d91711ddc219eb13a07e8d3b8 golangci-lint-1.61.0-linux-ppc64le.tar.gz -4c1a097d9e0d1b4a8144dae6a1f5583a38d662f3bdc1498c4e954b6ed856be98 golangci-lint-1.61.0-linux-riscv64.tar.gz -30581d3c987d287b7064617f1a2694143e10dffc40bc25be6636006ee82d7e1c golangci-lint-1.61.0-linux-s390x.tar.gz -42530bf8100bd43c07f5efe6d92148ba6c5a7a712d510c6f24be85af6571d5eb golangci-lint-1.61.0-netbsd-386.tar.gz -b8bb07c920f6601edf718d5e82ec0784fd590b0992b42b6ec18da99f26013ed4 golangci-lint-1.61.0-netbsd-amd64.tar.gz -353a51527c60bd0776b0891b03f247c791986f625fca689d121972c624e54198 golangci-lint-1.61.0-netbsd-arm64.tar.gz -957a6272c3137910514225704c5dac0723b9c65eb7d9587366a997736e2d7580 golangci-lint-1.61.0-netbsd-armv6.tar.gz -a89eb28ff7f18f5cd52b914739360fa95cf2f643de4adeca46e26bec3a07e8d8 golangci-lint-1.61.0-netbsd-armv7.tar.gz -d8d74c43600b271393000717a4ed157d7a15bb85bab7db2efad9b63a694d4634 golangci-lint-1.61.0-windows-386.zip -e7bc2a81929a50f830244d6d2e657cce4f19a59aff49fa9000176ff34fda64ce golangci-lint-1.61.0-windows-amd64.zip -ed97c221596dd771e3dd9344872c140340bee2e819cd7a90afa1de752f1f2e0f golangci-lint-1.61.0-windows-arm64.zip -4b365233948b13d02d45928a5c390045e00945e919747b9887b5f260247541ae golangci-lint-1.61.0-windows-armv6.zip -595538fb64d152173959d28f6235227f9cd969a828e5af0c4e960d02af4ffd0e golangci-lint-1.61.0-windows-armv7.zip +# https://github.com/golangci/golangci-lint/releases/download/v1.63.4/ +878d017cc360e4fb19510d39852c8189852e3c48e7ce0337577df73507c97d68 golangci-lint-1.63.4-darwin-amd64.tar.gz +a2b630c2ac8466393f0ccbbede4462387b6c190697a70bc2298c6d2123f21bbf golangci-lint-1.63.4-darwin-arm64.tar.gz +8938b74aa92888e561a1c5a4c175110b92f84e7d24733703e6d9ebc39e9cd5f8 golangci-lint-1.63.4-freebsd-386.tar.gz +054903339d620df2e760b978920100986e3b03bcb058f669d520a71dac9c34ed golangci-lint-1.63.4-freebsd-amd64.tar.gz +a19d499f961a02608348e8b626537a88edfaab6e1b6534f1eff742b5d6d750e4 golangci-lint-1.63.4-freebsd-armv6.tar.gz +00d616f0fb275b780ce4d26604bdd7fdbfe6bc9c63acd5a0b31498e1f7511108 golangci-lint-1.63.4-freebsd-armv7.tar.gz +d453688e0eabded3c1a97ff5a2777bb0df5a18851efdaaaf6b472e3e5713c33e golangci-lint-1.63.4-illumos-amd64.tar.gz +6b1bec847fc9f347d53712d05606a49d55d0e3b5c1bacadfed2393f3503de0e9 golangci-lint-1.63.4-linux-386.tar.gz +01abb14a4df47b5ca585eff3c34b105023cba92ec34ff17212dbb83855581690 golangci-lint-1.63.4-linux-amd64.tar.gz +51f0c79d19a92353e0465fb30a4901a0644a975d34e6f399ad2eebc0160bbb24 golangci-lint-1.63.4-linux-arm64.tar.gz +8d0a43f41e8424fbae10f7aa2dc29999f98112817c6dba63d7dc76832940a673 golangci-lint-1.63.4-linux-armv6.tar.gz +1045a047b31e9302c9160c7b0f199f4ac1bd02a1b221a2d9521bd3507f0cf671 golangci-lint-1.63.4-linux-armv7.tar.gz +933fe10ab50ce3bb0806e15a4ae69fe20f0549abf91dea0161236000ca706e67 golangci-lint-1.63.4-linux-loong64.tar.gz +45798630cbad5642862766051199fa862ef3c33d569cab12f01cac4f68e2ddd5 golangci-lint-1.63.4-linux-mips64.tar.gz +86ae25335ddb24975d2c915c1af0c7fad70dce99d0b4614fa4bee392de714aa2 golangci-lint-1.63.4-linux-mips64le.tar.gz +33dabd11aaba4b602938da98bcf49aabab55019557e0115cdc3dbcc3009768fa golangci-lint-1.63.4-linux-ppc64le.tar.gz +4e7a81230a663bcdf30bba5689ce96040abc76994dbc2003dce32c8dca8c06f3 golangci-lint-1.63.4-linux-riscv64.tar.gz +21370b49c7c47f4d9b8f982c952f940b01e65710174c3b4dad7b6452d58f92ec golangci-lint-1.63.4-linux-s390x.tar.gz +255866a6464c7e11bb7edd8e6e6ad54f11e1f01b82ba9ca229698ac788cd9724 golangci-lint-1.63.4-netbsd-386.tar.gz +2798c040ac658bda97224f204795199c81ac97bb207b21c02b664aaed380d5d2 golangci-lint-1.63.4-netbsd-amd64.tar.gz +b910eecffd0064103837e7e1abe870deb8ade22331e6dffe319f430d49399c8e golangci-lint-1.63.4-netbsd-arm64.tar.gz +df2693ef37147b457c3e2089614537dd2ae2e18e53641e756a5b404f4c72d3fa golangci-lint-1.63.4-netbsd-armv6.tar.gz +a28a533366974bd7834c4516cd6075bff3419a508d1ed7aa63ae8182768b352e golangci-lint-1.63.4-netbsd-armv7.tar.gz +368932775fb5c620b324dabf018155f3365f5e33c5af5b26e9321db373f96eea golangci-lint-1.63.4-windows-386.zip +184d13c2b8f5441576bec2a0d8ba7b2d45445595cf796b879a73bcc98c39f8c1 golangci-lint-1.63.4-windows-amd64.zip +4fabf175d5b05ef0858ded49527948eebac50e9093814979fd84555a75fb80a6 golangci-lint-1.63.4-windows-arm64.zip +e92be3f3ff30d4a849fb4b9a4c8d56837dee45269cb405a3ecad52fa034c781b golangci-lint-1.63.4-windows-armv6.zip +c71d348653b8f7fbb109bb10c1a481722bc6b0b2b6e731b897f99ac869f7653e golangci-lint-1.63.4-windows-armv7.zip # This is the builder on PPA that will build Go itself (inception-y), don't modify! # diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 02d339f99c..4ab14bbcc0 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1751,7 +1751,7 @@ func (p *BlobPool) Clear() { // The transaction addition may attempt to reserve the sender addr which // can't happen until Clear releases the reservation lock. Clear cannot // acquire the subpool lock until the transaction addition is completed. - for acct, _ := range p.index { + for acct := range p.index { p.reserve(acct, false) } p.lookup = newLookup() diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 70be7034ee..71cca7d1db 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1986,7 +1986,7 @@ func (pool *LegacyPool) Clear() { senderAddr, _ := types.Sender(pool.signer, tx) pool.reserve(senderAddr, false) } - for localSender, _ := range pool.locals.accounts { + for localSender := range pool.locals.accounts { pool.reserve(localSender, false) } From f460f019e9d81808bf8a15b7d7f1134ab456fb4f Mon Sep 17 00:00:00 2001 From: Martin Redmond <21436+reds@users.noreply.github.com> Date: Mon, 13 Jan 2025 10:12:15 -0500 Subject: [PATCH 039/940] eth/tracers/logger: return revert reason (#31013) Fix the error comparison in tracer to prevent dropping revert reason data --------- Co-authored-by: Martin Co-authored-by: rjl493456442 --- eth/tracers/logger/logger.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 07de871f14..596ee97146 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -19,6 +19,7 @@ package logger import ( "encoding/hex" "encoding/json" + "errors" "fmt" "io" "maps" @@ -350,7 +351,7 @@ func (l *StructLogger) GetResult() (json.RawMessage, error) { returnData := common.CopyBytes(l.output) // Return data when successful and revert reason when reverted, otherwise empty. returnVal := fmt.Sprintf("%x", returnData) - if failed && l.err != vm.ErrExecutionReverted { + if failed && !errors.Is(l.err, vm.ErrExecutionReverted) { returnVal = "" } return json.Marshal(&ExecutionResult{ From 8752785a9889a09abc6dd7354b9747caecdafa97 Mon Sep 17 00:00:00 2001 From: dashangcun <907225865@qq.com> Date: Mon, 13 Jan 2025 18:00:25 +0100 Subject: [PATCH 040/940] cmd/devp2p/internal/ethtest: using slices.SortFunc to simplify the code (#31012) Co-authored-by: Felix Lange --- cmd/devp2p/internal/ethtest/chain.go | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/cmd/devp2p/internal/ethtest/chain.go b/cmd/devp2p/internal/ethtest/chain.go index 2a70e0328f..222c66d4df 100644 --- a/cmd/devp2p/internal/ethtest/chain.go +++ b/cmd/devp2p/internal/ethtest/chain.go @@ -28,7 +28,6 @@ import ( "os" "path/filepath" "slices" - "sort" "strings" "github.com/ethereum/go-ethereum/common" @@ -41,6 +40,7 @@ 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/maps" ) // Chain is a lightweight blockchain-like store which can read a hivechain @@ -166,11 +166,8 @@ func (c *Chain) RootAt(height int) common.Hash { // GetSender returns the address associated with account at the index in the // pre-funded accounts list. func (c *Chain) GetSender(idx int) (common.Address, uint64) { - var accounts Addresses - for addr := range c.senders { - accounts = append(accounts, addr) - } - sort.Sort(accounts) + accounts := maps.Keys(c.senders) + slices.SortFunc(accounts, common.Address.Cmp) addr := accounts[idx] return addr, c.senders[addr].Nonce } @@ -260,22 +257,6 @@ func loadGenesis(genesisFile string) (core.Genesis, error) { return gen, nil } -type Addresses []common.Address - -func (a Addresses) Len() int { - return len(a) -} - -func (a Addresses) Less(i, j int) bool { - return bytes.Compare(a[i][:], a[j][:]) < 0 -} - -func (a Addresses) Swap(i, j int) { - tmp := a[i] - a[i] = a[j] - a[j] = tmp -} - func blocksFromFile(chainfile string, gblock *types.Block) ([]*types.Block, error) { // Load chain.rlp. fh, err := os.Open(chainfile) From fcf5204a02c8b80ad3c53274374a14ef45d83e2d Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Mon, 13 Jan 2025 19:33:49 +0100 Subject: [PATCH 041/940] core/txpool/legacypool: fix flaky test TestAllowedTxSize (#30975) - it was failing because the maximum data length (previously `dataSize`) was set to `txMaxSize - 213` but should had been `txMaxSize - 103` and the last call `dataSize+1+uint64(rand.Intn(10*txMaxSize)))` would sometimes fail depending on rand.Intn. - Maximal transaction data size comment (invalid) replaced by code logic to find the maximum tx length without its data length - comments and variable naming improved for clarity - 3rd pool add test replaced to add just 1 above the maximum length, which is important to ensure the logic is correct --- core/txpool/legacypool/legacypool_test.go | 31 ++++++++++------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 39673d176d..abbde8cae3 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -1243,33 +1243,28 @@ func TestAllowedTxSize(t *testing.T) { account := crypto.PubkeyToAddress(key.PublicKey) testAddBalance(pool, account, big.NewInt(1000000000)) - // Compute maximal data size for transactions (lower bound). - // - // It is assumed the fields in the transaction (except of the data) are: - // - nonce <= 32 bytes - // - gasTip <= 32 bytes - // - gasLimit <= 32 bytes - // - recipient == 20 bytes - // - value <= 32 bytes - // - signature == 65 bytes - // All those fields are summed up to at most 213 bytes. - baseSize := uint64(213) - dataSize := txMaxSize - baseSize + // Find the maximum data length for the kind of transaction which will + // be generated in the pool.addRemoteSync calls below. + const largeDataLength = txMaxSize - 200 // enough to have a 5 bytes RLP encoding of the data length number + txWithLargeData := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, largeDataLength) + maxTxLengthWithoutData := txWithLargeData.Size() - largeDataLength // 103 bytes + maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130953 bytes + // Try adding a transaction with maximal allowed size - tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, dataSize) + tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength) if err := pool.addRemoteSync(tx); err != nil { t.Fatalf("failed to add transaction of size %d, close to maximal: %v", int(tx.Size()), err) } // Try adding a transaction with random allowed size - if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentHead.Load().GasLimit, big.NewInt(1), key, uint64(rand.Intn(int(dataSize))))); err != nil { + if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentHead.Load().GasLimit, big.NewInt(1), key, uint64(rand.Intn(int(maxTxDataLength+1))))); err != nil { t.Fatalf("failed to add transaction of random allowed size: %v", err) } - // Try adding a transaction of minimal not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, txMaxSize)); err == nil { + // Try adding a transaction above maximum size by one + if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength+1)); err == nil { t.Fatalf("expected rejection on slightly oversize transaction") } - // Try adding a transaction of random not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, dataSize+1+uint64(rand.Intn(10*txMaxSize)))); err == nil { + // Try adding a transaction above maximum size by more than one + if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength+1+uint64(rand.Intn(10*txMaxSize)))); err == nil { t.Fatalf("expected rejection on oversize transaction") } // Run some sanity checks on the pool internals From 864e717b56e80a4970700fd50fe10188b98d670d Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Mon, 13 Jan 2025 19:35:49 +0100 Subject: [PATCH 042/940] core: remove unused function parameters (#31001) --- core/blockchain_test.go | 17 ++++------------- core/state_transition.go | 4 ++-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index fc0e3d8446..f2a9b953a1 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -2535,7 +2535,7 @@ func testReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T, scheme strin } // Benchmarks large blocks with value transfers to non-existing accounts -func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) { +func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address) { var ( signer = types.HomesteadSigner{} testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") @@ -2598,10 +2598,7 @@ func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) { recipientFn := func(nonce uint64) common.Address { return common.BigToAddress(new(big.Int).SetUint64(1337 + nonce)) } - dataFn := func(nonce uint64) []byte { - return nil - } - benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn) } func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) { @@ -2615,10 +2612,7 @@ func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) { recipientFn := func(nonce uint64) common.Address { return common.BigToAddress(new(big.Int).SetUint64(1337)) } - dataFn := func(nonce uint64) []byte { - return nil - } - benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn) } func BenchmarkBlockChain_1x1000Executions(b *testing.B) { @@ -2632,10 +2626,7 @@ func BenchmarkBlockChain_1x1000Executions(b *testing.B) { recipientFn := func(nonce uint64) common.Address { return common.BigToAddress(new(big.Int).SetUint64(0xc0de)) } - dataFn := func(nonce uint64) []byte { - return nil - } - benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn) } // Tests that importing a some old blocks, where all blocks are before the diff --git a/core/state_transition.go b/core/state_transition.go index 93d72d16b7..009b679b27 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -470,7 +470,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { if msg.SetCodeAuthorizations != nil { for _, auth := range msg.SetCodeAuthorizations { // Note errors are ignored, we simply skip invalid authorizations here. - st.applyAuthorization(msg, &auth) + st.applyAuthorization(&auth) } } @@ -559,7 +559,7 @@ func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorizatio } // applyAuthorization applies an EIP-7702 code delegation to the state. -func (st *stateTransition) applyAuthorization(msg *Message, auth *types.SetCodeAuthorization) error { +func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization) error { authority, err := st.validateAuthorization(auth) if err != nil { return err From 37c0e6992e02190c4e6a3bc9d70c19967f8931db Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 14 Jan 2025 18:49:30 +0800 Subject: [PATCH 043/940] cmd, core, miner: rework genesis setup (#30907) This pull request refactors the genesis setup function, the major changes are highlighted here: **(a) Triedb is opened in verkle mode if `EnableVerkleAtGenesis` is configured in chainConfig or the database has been initialized previously with `EnableVerkleAtGenesis` configured**. A new config field `EnableVerkleAtGenesis` has been added in the chainConfig. This field must be configured with True if Geth wants to initialize the genesis in Verkle mode. In the verkle devnet-7, the verkle transition is activated at genesis. Therefore, the verkle rules should be used since the genesis. In production networks (mainnet and public testnets), verkle activation always occurs after the genesis block. Therefore, this flag is only made for devnet and should be deprecated later. Besides, verkle transition at non-genesis block hasn't been implemented yet, it should be done in the following PRs. **(b) The genesis initialization condition has been simplified** There is a special mode supported by the Geth is that: Geth can be initialized with an existing chain segment, which can fasten the node sync process by retaining the chain freezer folder. Originally, if the triedb is regarded as uninitialized and the genesis block can be found in the chain freezer, the genesis block along with genesis state will be committed. This condition has been simplified to checking the presence of chain config in key-value store. The existence of chain config can represent the genesis has been committed. --- cmd/geth/chaincmd.go | 3 +- cmd/utils/history_test.go | 2 +- core/blockchain.go | 31 +++--- core/genesis.go | 202 +++++++++++++++++++++--------------- core/genesis_test.go | 41 ++++---- core/verkle_witness_test.go | 2 + miner/miner_test.go | 2 +- params/config.go | 27 +++++ triedb/database.go | 10 -- triedb/hashdb/database.go | 6 -- triedb/pathdb/database.go | 15 --- 11 files changed, 191 insertions(+), 150 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 48564eb5eb..bbadb1cc19 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -230,11 +230,10 @@ func initGenesis(ctx *cli.Context) error { triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) defer triedb.Close() - _, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + _, 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", "chaindata", "hash", hash) return nil diff --git a/cmd/utils/history_test.go b/cmd/utils/history_test.go index 1074a358ec..07cf71234e 100644 --- a/cmd/utils/history_test.go +++ b/cmd/utils/history_test.go @@ -170,7 +170,7 @@ func TestHistoryImportAndExport(t *testing.T) { db2.Close() }) - genesis.MustCommit(db2, triedb.NewDatabase(db, triedb.HashDefaults)) + genesis.MustCommit(db2, triedb.NewDatabase(db2, triedb.HashDefaults)) imported, err := core.NewBlockChain(db2, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil) if err != nil { t.Fatalf("unable to initialize chain: %v", err) diff --git a/core/blockchain.go b/core/blockchain.go index 0fe4812626..b056b7ed0c 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -269,14 +269,19 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis cacheConfig = defaultCacheConfig } // Open trie database with provided config - triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(genesis != nil && genesis.IsVerkle())) + enableVerkle, err := EnableVerkleAtGenesis(db, genesis) + if err != nil { + return nil, err + } + triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(enableVerkle)) - // Setup the genesis block, commit the provided genesis specification - // to database if the genesis block is not present yet, or load the - // stored one from database. - chainConfig, genesisHash, genesisErr := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides) - if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok { - return nil, genesisErr + // Write the supplied genesis to the database if it has not been initialized + // yet. The corresponding chain config will be returned, either from the + // provided genesis or from the locally stored configuration if the genesis + // has already been initialized. + chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides) + if err != nil { + return nil, err } log.Info("") log.Info(strings.Repeat("-", 153)) @@ -303,7 +308,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis vmConfig: vmConfig, logger: vmConfig.Tracer, } - var err error bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped) if err != nil { return nil, err @@ -453,16 +457,15 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis } // Rewind the chain in case of an incompatible config upgrade. - if compat, ok := genesisErr.(*params.ConfigCompatError); ok { - log.Warn("Rewinding chain to upgrade configuration", "err", compat) - if compat.RewindToTime > 0 { - bc.SetHeadWithTimestamp(compat.RewindToTime) + if compatErr != nil { + log.Warn("Rewinding chain to upgrade configuration", "err", compatErr) + if compatErr.RewindToTime > 0 { + bc.SetHeadWithTimestamp(compatErr.RewindToTime) } else { - bc.SetHead(compat.RewindToBlock) + bc.SetHead(compatErr.RewindToBlock) } rawdb.WriteChainConfig(db, genesisHash, chainConfig) } - // Start tx indexer if it's enabled. if txLookupLimit != nil { bc.txIndexer = newTxIndexer(*txLookupLimit, bc) diff --git a/core/genesis.go b/core/genesis.go index 347789cf0c..02cdc74d86 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -247,6 +247,24 @@ type ChainOverrides struct { OverrideVerkle *uint64 } +// apply applies the chain overrides on the supplied chain config. +func (o *ChainOverrides) apply(cfg *params.ChainConfig) (*params.ChainConfig, error) { + if o == nil || cfg == nil { + return cfg, nil + } + cpy := *cfg + if o.OverrideCancun != nil { + cpy.CancunTime = o.OverrideCancun + } + if o.OverrideVerkle != nil { + cpy.VerkleTime = o.OverrideVerkle + } + if err := cpy.CheckConfigForkOrder(); err != nil { + return nil, err + } + return &cpy, nil +} + // SetupGenesisBlock writes or updates the genesis block in db. // The block that will be used is: // @@ -258,109 +276,102 @@ type ChainOverrides struct { // The stored chain configuration will be updated if it is compatible (i.e. does not // specify a fork block below the local head block). In case of a conflict, the // error is a *params.ConfigCompatError and the new, unwritten config is returned. -// -// The returned chain configuration is never nil. -func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { +func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { return SetupGenesisBlockWithOverride(db, triedb, genesis, nil) } -func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, error) { +func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { + // Sanitize the supplied genesis, ensuring it has the associated chain + // config attached. if genesis != nil && genesis.Config == nil { - return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig + return nil, common.Hash{}, nil, errGenesisNoConfig } - applyOverrides := func(config *params.ChainConfig) { - if config != nil { - if overrides != nil && overrides.OverrideCancun != nil { - config.CancunTime = overrides.OverrideCancun - } - if overrides != nil && overrides.OverrideVerkle != nil { - config.VerkleTime = overrides.OverrideVerkle - } - } - } - // Just commit the new block if there is no stored genesis block. - stored := rawdb.ReadCanonicalHash(db, 0) - if (stored == common.Hash{}) { + // Commit the genesis if the database is empty + ghash := rawdb.ReadCanonicalHash(db, 0) + if (ghash == common.Hash{}) { if genesis == nil { log.Info("Writing default main-net genesis block") genesis = DefaultGenesisBlock() } else { log.Info("Writing custom genesis block") } + chainCfg, err := overrides.apply(genesis.Config) + if err != nil { + return nil, common.Hash{}, nil, err + } + genesis.Config = chainCfg - applyOverrides(genesis.Config) block, err := genesis.Commit(db, triedb) if err != nil { - return genesis.Config, common.Hash{}, err + return nil, common.Hash{}, nil, err } - return genesis.Config, block.Hash(), nil + return chainCfg, block.Hash(), nil, nil } - // The genesis block is present(perhaps in ancient database) while the - // state database is not initialized yet. It can happen that the node - // is initialized with an external ancient store. Commit genesis state - // in this case. - header := rawdb.ReadHeader(db, stored, 0) - if header.Root != types.EmptyRootHash && !triedb.Initialized(header.Root) { + // Commit the genesis if the genesis block exists in the ancient database + // but the key-value database is empty without initializing the genesis + // fields. This scenario can occur when the node is created from scratch + // with an existing ancient store. + storedCfg := rawdb.ReadChainConfig(db, ghash) + if storedCfg == nil { + // Ensure the stored genesis block matches with the given genesis. Private + // networks must explicitly specify the genesis in the config file, mainnet + // genesis will be used as default and the initialization will always fail. if genesis == nil { + log.Info("Writing default main-net genesis block") genesis = DefaultGenesisBlock() + } else { + log.Info("Writing custom genesis block") } - applyOverrides(genesis.Config) - // Ensure the stored genesis matches with the given one. - hash := genesis.ToBlock().Hash() - if hash != stored { - return genesis.Config, hash, &GenesisMismatchError{stored, hash} + chainCfg, err := overrides.apply(genesis.Config) + if err != nil { + return nil, common.Hash{}, nil, err + } + genesis.Config = chainCfg + + if hash := genesis.ToBlock().Hash(); hash != ghash { + return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} } block, err := genesis.Commit(db, triedb) if err != nil { - return genesis.Config, hash, err + return nil, common.Hash{}, nil, err } - return genesis.Config, block.Hash(), nil + return chainCfg, block.Hash(), nil, nil } - // Check whether the genesis block is already written. + // The genesis block has already been committed previously. Verify that the + // provided genesis with chain overrides matches the existing one, and update + // the stored chain config if necessary. if genesis != nil { - applyOverrides(genesis.Config) - hash := genesis.ToBlock().Hash() - if hash != stored { - return genesis.Config, hash, &GenesisMismatchError{stored, hash} + chainCfg, err := overrides.apply(genesis.Config) + if err != nil { + return nil, common.Hash{}, nil, err + } + genesis.Config = chainCfg + + if hash := genesis.ToBlock().Hash(); hash != ghash { + return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} } - } - // Get the existing chain configuration. - newcfg := genesis.configOrDefault(stored) - applyOverrides(newcfg) - if err := newcfg.CheckConfigForkOrder(); err != nil { - return newcfg, common.Hash{}, err - } - storedcfg := rawdb.ReadChainConfig(db, stored) - if storedcfg == nil { - log.Warn("Found genesis block without chain config") - rawdb.WriteChainConfig(db, stored, newcfg) - return newcfg, stored, nil - } - storedData, _ := json.Marshal(storedcfg) - // Special case: if a private network is being used (no genesis and also no - // mainnet hash in the database), we must not apply the `configOrDefault` - // chain config as that would be AllProtocolChanges (applying any new fork - // on top of an existing private network genesis block). In that case, only - // apply the overrides. - if genesis == nil && stored != params.MainnetGenesisHash { - newcfg = storedcfg - applyOverrides(newcfg) } // Check config compatibility and write the config. Compatibility errors // are returned to the caller unless we're already at block zero. head := rawdb.ReadHeadHeader(db) if head == nil { - return newcfg, stored, errors.New("missing head header") + return nil, common.Hash{}, nil, errors.New("missing head header") } - compatErr := storedcfg.CheckCompatible(newcfg, head.Number.Uint64(), head.Time) + newCfg := genesis.chainConfigOrDefault(ghash, storedCfg) + + // TODO(rjl493456442) better to define the comparator of chain config + // and short circuit if the chain config is not changed. + compatErr := storedCfg.CheckCompatible(newCfg, head.Number.Uint64(), head.Time) if compatErr != nil && ((head.Number.Uint64() != 0 && compatErr.RewindToBlock != 0) || (head.Time != 0 && compatErr.RewindToTime != 0)) { - return newcfg, stored, compatErr + return newCfg, ghash, compatErr, nil } - // Don't overwrite if the old is identical to the new - if newData, _ := json.Marshal(newcfg); !bytes.Equal(storedData, newData) { - rawdb.WriteChainConfig(db, stored, newcfg) + // Don't overwrite if the old is identical to the new. It's useful + // for the scenarios that database is opened in the read-only mode. + storedData, _ := json.Marshal(storedCfg) + if newData, _ := json.Marshal(newCfg); !bytes.Equal(storedData, newData) { + rawdb.WriteChainConfig(db, ghash, newCfg) } - return newcfg, stored, nil + return newCfg, ghash, nil, nil } // LoadChainConfig loads the stored chain config if it is already present in @@ -396,7 +407,10 @@ func LoadChainConfig(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, return params.MainnetChainConfig, nil } -func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { +// chainConfigOrDefault retrieves the attached chain configuration. If the genesis +// object is null, it returns the default chain configuration based on the given +// genesis hash, or the locally stored config if it's not a pre-defined network. +func (g *Genesis) chainConfigOrDefault(ghash common.Hash, stored *params.ChainConfig) *params.ChainConfig { switch { case g != nil: return g.Config @@ -407,14 +421,14 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { case ghash == params.SepoliaGenesisHash: return params.SepoliaChainConfig default: - return params.AllEthashProtocolChanges + return stored } } // IsVerkle indicates whether the state is already stored in a verkle // tree at genesis time. func (g *Genesis) IsVerkle() bool { - return g.Config.IsVerkle(new(big.Int).SetUint64(g.Number), g.Timestamp) + return g.Config.IsVerkleGenesis() } // ToBlock returns the genesis block according to genesis specification. @@ -494,7 +508,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo } config := g.Config if config == nil { - config = params.AllEthashProtocolChanges + return nil, errors.New("invalid genesis without chain config") } if err := config.CheckConfigForkOrder(); err != nil { return nil, err @@ -514,16 +528,17 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo if err != nil { return nil, err } - rawdb.WriteGenesisStateSpec(db, block.Hash(), blob) - rawdb.WriteTd(db, block.Hash(), block.NumberU64(), block.Difficulty()) - rawdb.WriteBlock(db, block) - rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) - rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) - rawdb.WriteHeadBlockHash(db, block.Hash()) - rawdb.WriteHeadFastBlockHash(db, block.Hash()) - rawdb.WriteHeadHeaderHash(db, block.Hash()) - rawdb.WriteChainConfig(db, block.Hash(), config) - return block, nil + batch := db.NewBatch() + rawdb.WriteGenesisStateSpec(batch, block.Hash(), blob) + rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), block.Difficulty()) + rawdb.WriteBlock(batch, block) + rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), nil) + rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64()) + rawdb.WriteHeadBlockHash(batch, block.Hash()) + rawdb.WriteHeadFastBlockHash(batch, block.Hash()) + rawdb.WriteHeadHeaderHash(batch, block.Hash()) + rawdb.WriteChainConfig(batch, block.Hash(), config) + return block, batch.Write() } // MustCommit writes the genesis block and state to db, panicking on error. @@ -536,6 +551,29 @@ func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types. return block } +// EnableVerkleAtGenesis indicates whether the verkle fork should be activated +// at genesis. This is a temporary solution only for verkle devnet testing, where +// verkle fork is activated at genesis, and the configured activation date has +// already passed. +// +// In production networks (mainnet and public testnets), verkle activation always +// occurs after the genesis block, making this function irrelevant in those cases. +func EnableVerkleAtGenesis(db ethdb.Database, genesis *Genesis) (bool, error) { + if genesis != nil { + if genesis.Config == nil { + return false, errGenesisNoConfig + } + return genesis.Config.EnableVerkleAtGenesis, nil + } + if ghash := rawdb.ReadCanonicalHash(db, 0); ghash != (common.Hash{}) { + chainCfg := rawdb.ReadChainConfig(db, ghash) + if chainCfg != nil { + return chainCfg.EnableVerkleAtGenesis, nil + } + } + return false, nil +} + // DefaultGenesisBlock returns the Ethereum main net genesis block. func DefaultGenesisBlock() *Genesis { return &Genesis{ diff --git a/core/genesis_test.go b/core/genesis_test.go index 3ec87474e5..964ef928c7 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -54,23 +54,23 @@ func testSetupGenesis(t *testing.T, scheme string) { oldcustomg.Config = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(2)} tests := []struct { - name string - fn func(ethdb.Database) (*params.ChainConfig, common.Hash, error) - wantConfig *params.ChainConfig - wantHash common.Hash - wantErr error + name string + fn func(ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) + wantConfig *params.ChainConfig + wantHash common.Hash + wantErr error + wantCompactErr *params.ConfigCompatError }{ { name: "genesis without ChainConfig", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), new(Genesis)) }, - wantErr: errGenesisNoConfig, - wantConfig: params.AllEthashProtocolChanges, + wantErr: errGenesisNoConfig, }, { name: "no block in DB, genesis == nil", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil) }, wantHash: params.MainnetGenesisHash, @@ -78,7 +78,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, { name: "mainnet block in DB, genesis == nil", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { DefaultGenesisBlock().MustCommit(db, triedb.NewDatabase(db, newDbConfig(scheme))) return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil) }, @@ -87,7 +87,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, { name: "custom block in DB, genesis == nil", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) customg.Commit(db, tdb) return SetupGenesisBlock(db, tdb, nil) @@ -97,18 +97,16 @@ func testSetupGenesis(t *testing.T, scheme string) { }, { name: "custom block in DB, genesis == sepolia", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) customg.Commit(db, tdb) return SetupGenesisBlock(db, tdb, DefaultSepoliaGenesisBlock()) }, - wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash}, - wantHash: params.SepoliaGenesisHash, - wantConfig: params.SepoliaChainConfig, + wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash}, }, { name: "compatible config in DB", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) oldcustomg.Commit(db, tdb) return SetupGenesisBlock(db, tdb, &customg) @@ -118,7 +116,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, { name: "incompatible config in DB", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { // Commit the 'old' genesis block with Homestead transition at #2. // Advance to block #4, past the homestead transition block of customg. tdb := triedb.NewDatabase(db, newDbConfig(scheme)) @@ -135,7 +133,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, wantHash: customghash, wantConfig: customg.Config, - wantErr: ¶ms.ConfigCompatError{ + wantCompactErr: ¶ms.ConfigCompatError{ What: "Homestead fork block", StoredBlock: big.NewInt(2), NewBlock: big.NewInt(3), @@ -146,12 +144,16 @@ func testSetupGenesis(t *testing.T, scheme string) { for _, test := range tests { db := rawdb.NewMemoryDatabase() - config, hash, err := test.fn(db) + config, hash, compatErr, err := test.fn(db) // Check the return values. if !reflect.DeepEqual(err, test.wantErr) { spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true} t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(err), spew.NewFormatter(test.wantErr)) } + if !reflect.DeepEqual(compatErr, test.wantCompactErr) { + spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true} + t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(compatErr), spew.NewFormatter(test.wantCompactErr)) + } if !reflect.DeepEqual(config, test.wantConfig) { t.Errorf("%s:\nreturned %v\nwant %v", test.name, config, test.wantConfig) } @@ -279,6 +281,7 @@ func TestVerkleGenesisCommit(t *testing.T) { PragueTime: &verkleTime, VerkleTime: &verkleTime, TerminalTotalDifficulty: big.NewInt(0), + EnableVerkleAtGenesis: true, Ethash: nil, Clique: nil, } diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go index 5088231207..02e94963c4 100644 --- a/core/verkle_witness_test.go +++ b/core/verkle_witness_test.go @@ -57,6 +57,7 @@ var ( ShanghaiTime: u64(0), VerkleTime: u64(0), TerminalTotalDifficulty: common.Big0, + EnableVerkleAtGenesis: true, // TODO uncomment when proof generation is merged // ProofInBlocks: true, } @@ -77,6 +78,7 @@ var ( ShanghaiTime: u64(0), VerkleTime: u64(0), TerminalTotalDifficulty: common.Big0, + EnableVerkleAtGenesis: true, } ) diff --git a/miner/miner_test.go b/miner/miner_test.go index b92febdd12..04d84e2e1d 100644 --- a/miner/miner_test.go +++ b/miner/miner_test.go @@ -145,7 +145,7 @@ func createMiner(t *testing.T) *Miner { chainDB := rawdb.NewMemoryDatabase() triedb := triedb.NewDatabase(chainDB, nil) genesis := minerTestGenesisBlock(15, 11_500_000, common.HexToAddress("12345")) - chainConfig, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis) + chainConfig, _, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis) if err != nil { t.Fatalf("can't create new chain config: %v", err) } diff --git a/params/config.go b/params/config.go index 9b3b92484a..f1e139608c 100644 --- a/params/config.go +++ b/params/config.go @@ -326,6 +326,19 @@ type ChainConfig struct { DepositContractAddress common.Address `json:"depositContractAddress,omitempty"` + // EnableVerkleAtGenesis is a flag that specifies whether the network uses + // the Verkle tree starting from the genesis block. If set to true, the + // genesis state will be committed using the Verkle tree, eliminating the + // need for any Verkle transition later. + // + // This is a temporary flag only for verkle devnet testing, where verkle is + // activated at genesis, and the configured activation date has already passed. + // + // In production networks (mainnet and public testnets), verkle activation + // always occurs after the genesis block, making this flag irrelevant in + // those cases. + EnableVerkleAtGenesis bool `json:"enableVerkleAtGenesis,omitempty"` + // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` @@ -525,6 +538,20 @@ func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time) } +// IsVerkleGenesis checks whether the verkle fork is activated at the genesis block. +// +// Verkle mode is considered enabled if the verkle fork time is configured, +// regardless of whether the local time has surpassed the fork activation time. +// This is a temporary workaround for verkle devnet testing, where verkle is +// activated at genesis, and the configured activation date has already passed. +// +// In production networks (mainnet and public testnets), verkle activation +// always occurs after the genesis block, making this function irrelevant in +// those cases. +func (c *ChainConfig) IsVerkleGenesis() bool { + return c.EnableVerkleAtGenesis +} + // 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) diff --git a/triedb/database.go b/triedb/database.go index b448d7cd07..f8ccc5ad33 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -64,10 +64,6 @@ type backend interface { // state. An error will be returned if the specified state is not available. StateReader(root common.Hash) (database.StateReader, error) - // Initialized returns an indicator if the state data is already initialized - // according to the state scheme. - Initialized(genesisRoot common.Hash) bool - // Size returns the current storage size of the diff layers on top of the // disk layer and the storage size of the nodes cached in the disk layer. // @@ -178,12 +174,6 @@ func (db *Database) Size() (common.StorageSize, common.StorageSize, common.Stora return diffs, nodes, preimages } -// Initialized returns an indicator if the state data is already initialized -// according to the state scheme. -func (db *Database) Initialized(genesisRoot common.Hash) bool { - return db.backend.Initialized(genesisRoot) -} - // Scheme returns the node scheme used in the database. func (db *Database) Scheme() string { if db.config.PathDB != nil { diff --git a/triedb/hashdb/database.go b/triedb/hashdb/database.go index fb718f4e74..38392aa519 100644 --- a/triedb/hashdb/database.go +++ b/triedb/hashdb/database.go @@ -532,12 +532,6 @@ func (c *cleaner) Delete(key []byte) error { panic("not implemented") } -// Initialized returns an indicator if state data is already initialized -// in hash-based scheme by checking the presence of genesis state. -func (db *Database) Initialized(genesisRoot common.Hash) bool { - return rawdb.HasLegacyTrieNode(db.diskdb, genesisRoot) -} - // Update inserts the dirty nodes in provided nodeset into database and link the // account trie with multiple storage tries if necessary. func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet) error { diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index c31f1d44f4..b0d84eb879 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -529,21 +529,6 @@ func (db *Database) Size() (diffs common.StorageSize, nodes common.StorageSize) return diffs, nodes } -// Initialized returns an indicator if the state data is already -// initialized in path-based scheme. -func (db *Database) Initialized(genesisRoot common.Hash) bool { - var inited bool - db.tree.forEach(func(layer layer) { - if layer.rootHash() != types.EmptyRootHash { - inited = true - } - }) - if !inited { - inited = rawdb.ReadSnapSyncStatusFlag(db.diskdb) != rawdb.StateSyncUnknown - } - return inited -} - // modifyAllowed returns the indicator if mutation is allowed. This function // assumes the db.lock is already held. func (db *Database) modifyAllowed() error { From 1843f2776603ed1b66bfe78916d61267f80201e7 Mon Sep 17 00:00:00 2001 From: georgehao Date: Tue, 14 Jan 2025 21:16:15 +0800 Subject: [PATCH 044/940] all: fix some typos in comments and names (#31023) --- accounts/accounts.go | 4 +++- cmd/devp2p/internal/ethtest/protocol.go | 1 + cmd/devp2p/internal/v4test/discv4tests.go | 18 ++++++++-------- consensus/clique/snapshot_test.go | 1 - core/tracing/hooks.go | 2 +- core/txpool/legacypool/legacypool2_test.go | 6 +++--- core/types/deposit.go | 2 +- core/vm/eof_validation.go | 6 +++--- core/vm/program/program.go | 5 +++-- crypto/blake2b/blake2b.go | 8 +++---- crypto/bn256/gnark/pairing.go | 2 +- crypto/ecies/ecies.go | 12 +++++------ eth/tracers/dir.go | 2 +- eth/tracers/internal/util.go | 1 + internal/era/builder.go | 3 ++- internal/jsre/jsre.go | 25 +++++++++++++++++++--- internal/reexec/reexec.go | 1 + metrics/exp/exp.go | 1 + metrics/gauge_info.go | 2 +- metrics/log.go | 2 +- metrics/metrics.go | 1 + metrics/resetting_timer.go | 6 +++--- metrics/syslog.go | 2 +- p2p/discover/v5wire/encoding_test.go | 12 +++++------ params/protocol_params.go | 2 +- signer/core/api.go | 2 +- signer/core/uiapi.go | 2 +- 27 files changed, 79 insertions(+), 52 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index b995498a6d..7bd911577a 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -214,7 +214,9 @@ const ( // of starting any background processes such as automatic key derivation. WalletOpened - // WalletDropped + // WalletDropped is fired when a wallet is removed or disconnected, either via USB + // or due to a filesystem event in the keystore. This event indicates that the wallet + // is no longer available for operations. WalletDropped ) diff --git a/cmd/devp2p/internal/ethtest/protocol.go b/cmd/devp2p/internal/ethtest/protocol.go index f5f5f7e489..5c2f7d9e48 100644 --- a/cmd/devp2p/internal/ethtest/protocol.go +++ b/cmd/devp2p/internal/ethtest/protocol.go @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . + package ethtest import ( diff --git a/cmd/devp2p/internal/v4test/discv4tests.go b/cmd/devp2p/internal/v4test/discv4tests.go index ca556851b4..963df6cdbc 100644 --- a/cmd/devp2p/internal/v4test/discv4tests.go +++ b/cmd/devp2p/internal/v4test/discv4tests.go @@ -194,7 +194,7 @@ func PingExtraData(t *utesting.T) { } } -// This test sends a PING packet with additional data and wrong 'from' field +// PingExtraDataWrongFrom sends a PING packet with additional data and wrong 'from' field // and expects a PONG response. func PingExtraDataWrongFrom(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -215,7 +215,7 @@ func PingExtraDataWrongFrom(t *utesting.T) { } } -// This test sends a PING packet with an expiration in the past. +// PingPastExpiration sends a PING packet with an expiration in the past. // The remote node should not respond. func PingPastExpiration(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -234,7 +234,7 @@ func PingPastExpiration(t *utesting.T) { } } -// This test sends an invalid packet. The remote node should not respond. +// WrongPacketType sends an invalid packet. The remote node should not respond. func WrongPacketType(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) defer te.close() @@ -252,7 +252,7 @@ func WrongPacketType(t *utesting.T) { } } -// This test verifies that the default behaviour of ignoring 'from' fields is unaffected by +// BondThenPingWithWrongFrom verifies that the default behaviour of ignoring 'from' fields is unaffected by // the bonding process. After bonding, it pings the target with a different from endpoint. func BondThenPingWithWrongFrom(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -289,7 +289,7 @@ waitForPong: } } -// This test just sends FINDNODE. The remote node should not reply +// FindnodeWithoutEndpointProof sends FINDNODE. The remote node should not reply // because the endpoint proof has not completed. func FindnodeWithoutEndpointProof(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -332,7 +332,7 @@ func BasicFindnode(t *utesting.T) { } } -// This test sends an unsolicited NEIGHBORS packet after the endpoint proof, then sends +// UnsolicitedNeighbors sends an unsolicited NEIGHBORS packet after the endpoint proof, then sends // FINDNODE to read the remote table. The remote node should not return the node contained // in the unsolicited NEIGHBORS packet. func UnsolicitedNeighbors(t *utesting.T) { @@ -373,7 +373,7 @@ func UnsolicitedNeighbors(t *utesting.T) { } } -// This test sends FINDNODE with an expiration timestamp in the past. +// FindnodePastExpiration sends FINDNODE with an expiration timestamp in the past. // The remote node should not respond. func FindnodePastExpiration(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -426,7 +426,7 @@ func bond(t *utesting.T, te *testenv) { } } -// This test attempts to perform a traffic amplification attack against a +// FindnodeAmplificationInvalidPongHash attempts to perform a traffic amplification attack against a // 'victim' endpoint using FINDNODE. In this attack scenario, the attacker // attempts to complete the endpoint proof non-interactively by sending a PONG // with mismatching reply token from the 'victim' endpoint. The attack works if @@ -478,7 +478,7 @@ func FindnodeAmplificationInvalidPongHash(t *utesting.T) { } } -// This test attempts to perform a traffic amplification attack using FINDNODE. +// FindnodeAmplificationWrongIP attempts to perform a traffic amplification attack using FINDNODE. // The attack works if the remote node does not verify the IP address of FINDNODE // against the endpoint verification proof done by PING/PONG. func FindnodeAmplificationWrongIP(t *utesting.T) { diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go index 6c46d1db4f..a83d6ca736 100644 --- a/consensus/clique/snapshot_test.go +++ b/consensus/clique/snapshot_test.go @@ -467,7 +467,6 @@ func (tt *cliqueTest) run(t *testing.T) { for j := 0; j < len(batches)-1; j++ { if k, err := chain.InsertChain(batches[j]); err != nil { t.Fatalf("failed to import batch %d, block %d: %v", j, k, err) - break } } if _, err = chain.InsertChain(batches[len(batches)-1]); err != tt.failure { diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 728f15069b..4343edfe86 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -293,7 +293,7 @@ const ( 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 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 diff --git a/core/txpool/legacypool/legacypool2_test.go b/core/txpool/legacypool/legacypool2_test.go index 1377479da1..8af9624994 100644 --- a/core/txpool/legacypool/legacypool2_test.go +++ b/core/txpool/legacypool/legacypool2_test.go @@ -162,12 +162,12 @@ func TestTransactionZAttack(t *testing.T) { var ivpendingNum int pendingtxs, _ := pool.Content() for account, txs := range pendingtxs { - cur_balance := new(big.Int).Set(pool.currentState.GetBalance(account).ToBig()) + curBalance := new(big.Int).Set(pool.currentState.GetBalance(account).ToBig()) for _, tx := range txs { - if cur_balance.Cmp(tx.Value()) <= 0 { + if curBalance.Cmp(tx.Value()) <= 0 { ivpendingNum++ } else { - cur_balance.Sub(cur_balance, tx.Value()) + curBalance.Sub(curBalance, tx.Value()) } } } diff --git a/core/types/deposit.go b/core/types/deposit.go index 3bba2c7aa4..8015f29ca7 100644 --- a/core/types/deposit.go +++ b/core/types/deposit.go @@ -24,7 +24,7 @@ const ( depositRequestSize = 192 ) -// UnpackIntoDeposit unpacks a serialized DepositEvent. +// DepositLogToRequest unpacks a serialized DepositEvent. func DepositLogToRequest(data []byte) ([]byte, error) { if len(data) != 576 { return nil, fmt.Errorf("deposit wrong length: want 576, have %d", len(data)) diff --git a/core/vm/eof_validation.go b/core/vm/eof_validation.go index fa534edce9..514f9fb58c 100644 --- a/core/vm/eof_validation.go +++ b/core/vm/eof_validation.go @@ -109,8 +109,8 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable, return nil, err } case RJUMPV: - max_size := int(code[i+1]) - length := max_size + 1 + maxSize := int(code[i+1]) + length := maxSize + 1 if len(code) <= i+length { return nil, fmt.Errorf("%w: jump table truncated, op %s, pos %d", errTruncatedImmediate, op, i) } @@ -120,7 +120,7 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable, return nil, err } } - i += 2 * max_size + i += 2 * maxSize case CALLF: arg, _ := parseUint16(code[i+1:]) if arg >= len(container.types) { diff --git a/core/vm/program/program.go b/core/vm/program/program.go index acc7fd25fc..3b00bbae6f 100644 --- a/core/vm/program/program.go +++ b/core/vm/program/program.go @@ -19,6 +19,7 @@ // - There are not package guarantees. We might iterate heavily on this package, and do backwards-incompatible changes without warning // - There are no quality-guarantees. These utilities may produce evm-code that is non-functional. YMMV. // - There are no stability-guarantees. The utility will `panic` if the inputs do not align / make sense. + package program import ( @@ -204,7 +205,7 @@ func (p *Program) StaticCall(gas *uint256.Int, address, inOffset, inSize, outOff return p.Op(vm.STATICCALL) } -// StaticCall is a convenience function to make a callcode. If 'gas' is nil, the opcode GAS will +// CallCode is a convenience function to make a callcode. If 'gas' is nil, the opcode GAS will // be used to provide all gas. func (p *Program) CallCode(gas *uint256.Int, address, value, inOffset, inSize, outOffset, outSize any) *Program { if outOffset == outSize && inSize == outSize && inOffset == outSize { @@ -263,7 +264,7 @@ func (p *Program) InputAddressToStack(inputOffset uint32) *Program { return p.Op(vm.AND) } -// MStore stores the provided data (into the memory area starting at memStart). +// Mstore stores the provided data (into the memory area starting at memStart). func (p *Program) Mstore(data []byte, memStart uint32) *Program { var idx = 0 // We need to store it in chunks of 32 bytes diff --git a/crypto/blake2b/blake2b.go b/crypto/blake2b/blake2b.go index 7ecaab8139..c24a88b99d 100644 --- a/crypto/blake2b/blake2b.go +++ b/crypto/blake2b/blake2b.go @@ -23,13 +23,13 @@ import ( ) const ( - // The blocksize of BLAKE2b in bytes. + // BlockSize the blocksize of BLAKE2b in bytes. BlockSize = 128 - // The hash size of BLAKE2b-512 in bytes. + // Size the hash size of BLAKE2b-512 in bytes. Size = 64 - // The hash size of BLAKE2b-384 in bytes. + // Size384 the hash size of BLAKE2b-384 in bytes. Size384 = 48 - // The hash size of BLAKE2b-256 in bytes. + // Size256 the hash size of BLAKE2b-256 in bytes. Size256 = 32 ) diff --git a/crypto/bn256/gnark/pairing.go b/crypto/bn256/gnark/pairing.go index 39e8a657f4..439ce0a39d 100644 --- a/crypto/bn256/gnark/pairing.go +++ b/crypto/bn256/gnark/pairing.go @@ -4,7 +4,7 @@ import ( "github.com/consensys/gnark-crypto/ecc/bn254" ) -// Computes the following relation: ∏ᵢ e(Pᵢ, Qᵢ) =? 1 +// PairingCheck computes the following relation: ∏ᵢ e(Pᵢ, Qᵢ) =? 1 // // To explain why gnark returns a (bool, error): // diff --git a/crypto/ecies/ecies.go b/crypto/ecies/ecies.go index 1b6c9e97c1..76f934c72d 100644 --- a/crypto/ecies/ecies.go +++ b/crypto/ecies/ecies.go @@ -60,12 +60,12 @@ type PublicKey struct { Params *ECIESParams } -// Export an ECIES public key as an ECDSA public key. +// ExportECDSA exports an ECIES public key as an ECDSA public key. func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey { return &ecdsa.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y} } -// Import an ECDSA public key as an ECIES public key. +// ImportECDSAPublic imports an ECDSA public key as an ECIES public key. func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey { return &PublicKey{ X: pub.X, @@ -81,20 +81,20 @@ type PrivateKey struct { D *big.Int } -// Export an ECIES private key as an ECDSA private key. +// ExportECDSA exports an ECIES private key as an ECDSA private key. func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey { pub := &prv.PublicKey pubECDSA := pub.ExportECDSA() return &ecdsa.PrivateKey{PublicKey: *pubECDSA, D: prv.D} } -// Import an ECDSA private key as an ECIES private key. +// ImportECDSA imports an ECDSA private key as an ECIES private key. func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey { pub := ImportECDSAPublic(&prv.PublicKey) return &PrivateKey{*pub, prv.D} } -// Generate an elliptic curve public / private keypair. If params is nil, +// GenerateKey generates 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) { sk, err := ecdsa.GenerateKey(curve, rand) @@ -119,7 +119,7 @@ func MaxSharedKeyLength(pub *PublicKey) int { return (pub.Curve.Params().BitSize + 7) / 8 } -// ECDH key agreement method used to establish secret keys for encryption. +// GenerateShared ECDH key agreement method used to establish secret keys for encryption. func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) { if prv.PublicKey.Curve != pub.Curve { return nil, ErrInvalidCurve diff --git a/eth/tracers/dir.go b/eth/tracers/dir.go index 55bcb44d23..1cdfab5454 100644 --- a/eth/tracers/dir.go +++ b/eth/tracers/dir.go @@ -34,7 +34,7 @@ type Context struct { TxHash common.Hash // Hash of the transaction being traced (zero if dangling call) } -// The set of methods that must be exposed by a tracer +// Tracer represents 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. diff --git a/eth/tracers/internal/util.go b/eth/tracers/internal/util.go index 347af43d51..cff6295566 100644 --- a/eth/tracers/internal/util.go +++ b/eth/tracers/internal/util.go @@ -13,6 +13,7 @@ // // 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 ( diff --git a/internal/era/builder.go b/internal/era/builder.go index 75782a08c2..33261555ba 100644 --- a/internal/era/builder.go +++ b/internal/era/builder.go @@ -12,7 +12,8 @@ // 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 . +// along with go-ethereum. If not, see . + package era import ( diff --git a/internal/jsre/jsre.go b/internal/jsre/jsre.go index f6e21d2ef7..0dfeae8e1b 100644 --- a/internal/jsre/jsre.go +++ b/internal/jsre/jsre.go @@ -67,7 +67,19 @@ type evalReq struct { done chan bool } -// runtime must be stopped with Stop() after use and cannot be used after stopping +// New creates and initializes a new JavaScript runtime environment (JSRE). +// The runtime is configured with the provided assetPath for loading scripts and +// an output writer for logging or printing results. +// +// The returned JSRE must be stopped by calling Stop() after use to release resources. +// Attempting to use the JSRE after stopping it will result in undefined behavior. +// +// Parameters: +// - assetPath: The path to the directory containing script assets. +// - output: The writer used for logging or printing runtime output. +// +// Returns: +// - A pointer to the newly created JSRE instance. func New(assetPath string, output io.Writer) *JSRE { re := &JSRE{ assetPath: assetPath, @@ -251,8 +263,15 @@ func (re *JSRE) Stop(waitForCallbacks bool) { } } -// Exec(file) loads and runs the contents of a file -// if a relative path is given, the jsre's assetPath is used +// Exec loads and executes the contents of a JavaScript file. +// If a relative path is provided, the file is resolved relative to the JSRE's assetPath. +// The file is read, compiled, and executed in the JSRE's runtime environment. +// +// Parameters: +// - file: The path to the JavaScript file to execute. Can be an absolute path or relative to assetPath. +// +// Returns: +// - error: An error if the file cannot be read, compiled, or executed. func (re *JSRE) Exec(file string) error { code, err := os.ReadFile(common.AbsolutePath(re.assetPath, file)) if err != nil { diff --git a/internal/reexec/reexec.go b/internal/reexec/reexec.go index af8d347986..7dc6d9222e 100644 --- a/internal/reexec/reexec.go +++ b/internal/reexec/reexec.go @@ -7,6 +7,7 @@ // we require because of the forking limitations of using Go. Handlers can be // registered with a name and the argv 0 of the exec of the binary will be used // to find and execute custom init paths. + package reexec import ( diff --git a/metrics/exp/exp.go b/metrics/exp/exp.go index 5213979aa2..85cabca6b1 100644 --- a/metrics/exp/exp.go +++ b/metrics/exp/exp.go @@ -1,5 +1,6 @@ // Hook go-metrics into expvar // on any /debug/metrics request, load all vars from the registry into expvar, and execute regular expvar handler + package exp import ( diff --git a/metrics/gauge_info.go b/metrics/gauge_info.go index 2f78455649..1862ed55c5 100644 --- a/metrics/gauge_info.go +++ b/metrics/gauge_info.go @@ -39,7 +39,7 @@ func NewRegisteredGaugeInfo(name string, r Registry) *GaugeInfo { return c } -// gaugeInfoSnapshot is a read-only copy of another GaugeInfo. +// GaugeInfoSnapshot is a read-only copy of another GaugeInfo. type GaugeInfoSnapshot GaugeInfoValue // Value returns the value at the time the snapshot was taken. diff --git a/metrics/log.go b/metrics/log.go index 3380bbf9c4..08f3effb81 100644 --- a/metrics/log.go +++ b/metrics/log.go @@ -12,7 +12,7 @@ func Log(r Registry, freq time.Duration, l Logger) { LogScaled(r, freq, time.Nanosecond, l) } -// Output each metric in the given registry periodically using the given +// LogScaled outputs each metric in the given registry periodically using the given // logger. Print timings in `scale` units (eg time.Millisecond) rather than nanos. func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) { du := float64(scale) diff --git a/metrics/metrics.go b/metrics/metrics.go index a9d6623173..c4c43b7576 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -3,6 +3,7 @@ // // // Coda Hale's original work: + package metrics import ( diff --git a/metrics/resetting_timer.go b/metrics/resetting_timer.go index 1b3e87bc3d..66458bdb91 100644 --- a/metrics/resetting_timer.go +++ b/metrics/resetting_timer.go @@ -53,14 +53,14 @@ func (t *ResettingTimer) Snapshot() *ResettingTimerSnapshot { return snapshot } -// Record the duration of the execution of the given function. +// Time records the duration of the execution of the given function. func (t *ResettingTimer) Time(f func()) { ts := time.Now() f() t.Update(time.Since(ts)) } -// Record the duration of an event. +// Update records the duration of an event. func (t *ResettingTimer) Update(d time.Duration) { if !metricsEnabled { return @@ -71,7 +71,7 @@ func (t *ResettingTimer) Update(d time.Duration) { t.sum += int64(d) } -// Record the duration of an event that started at a time and ends now. +// UpdateSince records the duration of an event that started at a time and ends now. func (t *ResettingTimer) UpdateSince(ts time.Time) { t.Update(time.Since(ts)) } diff --git a/metrics/syslog.go b/metrics/syslog.go index 0bc4ed0da5..b265328f87 100644 --- a/metrics/syslog.go +++ b/metrics/syslog.go @@ -9,7 +9,7 @@ import ( "time" ) -// Output each metric in the given registry to syslog periodically using +// Syslog outputs each metric in the given registry to syslog periodically using // the given syslogger. func Syslog(r Registry, d time.Duration, w *syslog.Writer) { for range time.Tick(d) { diff --git a/p2p/discover/v5wire/encoding_test.go b/p2p/discover/v5wire/encoding_test.go index c66a0da9d3..df97e40e89 100644 --- a/p2p/discover/v5wire/encoding_test.go +++ b/p2p/discover/v5wire/encoding_test.go @@ -249,20 +249,20 @@ func TestHandshake_BadHandshakeAttack(t *testing.T) { net.nodeA.expectDecode(t, WhoareyouPacket, whoareyou) // A -> B FINDNODE - incorrect_challenge := &Whoareyou{ + incorrectChallenge := &Whoareyou{ IDNonce: [16]byte{5, 6, 7, 8, 9, 6, 11, 12}, RecordSeq: challenge.RecordSeq, Node: challenge.Node, sent: challenge.sent, } - incorrect_findnode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, incorrect_challenge, &Findnode{}) - incorrect_findnode2 := make([]byte, len(incorrect_findnode)) - copy(incorrect_findnode2, incorrect_findnode) + incorrectFindNode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, incorrectChallenge, &Findnode{}) + incorrectFindNode2 := make([]byte, len(incorrectFindNode)) + copy(incorrectFindNode2, incorrectFindNode) - net.nodeB.expectDecodeErr(t, errInvalidNonceSig, incorrect_findnode) + net.nodeB.expectDecodeErr(t, errInvalidNonceSig, incorrectFindNode) // Reject new findnode as previous handshake is now deleted. - net.nodeB.expectDecodeErr(t, errUnexpectedHandshake, incorrect_findnode2) + net.nodeB.expectDecodeErr(t, errUnexpectedHandshake, incorrectFindNode2) // The findnode packet is again rejected even with a valid challenge this time. findnode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, challenge, &Findnode{}) diff --git a/params/protocol_params.go b/params/protocol_params.go index b46e8d66b2..030083aa9a 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -179,7 +179,7 @@ const ( HistoryServeWindow = 8192 // Number of blocks to serve historical block hashes for, EIP-2935. ) -// Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations +// Bls12381MultiExpDiscountTable gas discount table for BLS12-381 G1 and G2 multi exponentiation operations var Bls12381MultiExpDiscountTable = [128]uint64{1200, 888, 764, 641, 594, 547, 500, 453, 438, 423, 408, 394, 379, 364, 349, 334, 330, 326, 322, 318, 314, 310, 306, 302, 298, 294, 289, 285, 281, 277, 273, 269, 268, 266, 265, 263, 262, 260, 259, 257, 256, 254, 253, 251, 250, 248, 247, 245, 244, 242, 241, 239, 238, 236, 235, 233, 232, 231, 229, 228, 226, 225, 223, 222, 221, 220, 219, 219, 218, 217, 216, 216, 215, 214, 213, 213, 212, 211, 211, 210, 209, 208, 208, 207, 206, 205, 205, 204, 203, 202, 202, 201, 200, 199, 199, 198, 197, 196, 196, 195, 194, 193, 193, 192, 191, 191, 190, 189, 188, 188, 187, 186, 185, 185, 184, 183, 182, 182, 181, 180, 179, 179, 178, 177, 176, 176, 175, 174} // Difficulty parameters. diff --git a/signer/core/api.go b/signer/core/api.go index def2d6041f..12acf925f0 100644 --- a/signer/core/api.go +++ b/signer/core/api.go @@ -664,7 +664,7 @@ func (api *SignerAPI) SignGnosisSafeTx(ctx context.Context, signerAddress common return &gnosisTx, nil } -// Returns the external api version. This method does not require user acceptance. Available methods are +// Version returns the external api version. This method does not require user acceptance. Available methods are // available via enumeration anyway, and this info does not contain user-specific data func (api *SignerAPI) Version(ctx context.Context) (string, error) { return ExternalAPIVersion, nil diff --git a/signer/core/uiapi.go b/signer/core/uiapi.go index 43edfe7d97..2f511c7e19 100644 --- a/signer/core/uiapi.go +++ b/signer/core/uiapi.go @@ -48,7 +48,7 @@ func NewUIServerAPI(extapi *SignerAPI) *UIServerAPI { return &UIServerAPI{extapi, extapi.am} } -// List available accounts. As opposed to the external API definition, this method delivers +// ListAccounts lists available accounts. As opposed to the external API definition, this method delivers // the full Account object and not only Address. // Example call // {"jsonrpc":"2.0","method":"clef_listAccounts","params":[], "id":4} From 04a336aee8a911504b2bacc3fb755d726829b235 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 14 Jan 2025 14:42:18 +0100 Subject: [PATCH 045/940] core/types: change SetCodeTx.ChainID to uint256 (#30982) We still need to decide how to handle non-specfic `chainId` in the JSON encoding of authorizations. With `chainId` being a uint64, the previous implementation just used value zero. However, it might actually be more correct to use the value `null` for this case. --- core/blockchain_test.go | 5 ++--- core/state_transition.go | 4 ++-- core/types/gen_authorization.go | 8 ++++---- core/types/transaction_marshalling.go | 16 +++++++++++----- core/types/transaction_signing.go | 2 +- core/types/tx_blob.go | 6 +++--- core/types/tx_dynamic_fee.go | 6 +++--- core/types/tx_setcode.go | 16 ++++++++-------- internal/ethapi/transaction_args.go | 2 +- tests/gen_stauthorization.go | 11 ++++++----- tests/state_test_util.go | 6 +++--- 11 files changed, 44 insertions(+), 38 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index f2a9b953a1..7805a7c6e8 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -4265,12 +4265,11 @@ func TestEIP7702(t *testing.T) { // 2. addr1:0xaaaa calls into addr2:0xbbbb // 3. addr2:0xbbbb writes to storage auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{ - ChainID: gspec.Config.ChainID.Uint64(), + ChainID: *uint256.MustFromBig(gspec.Config.ChainID), Address: aa, Nonce: 1, }) auth2, _ := types.SignSetCode(key2, types.SetCodeAuthorization{ - ChainID: 0, Address: bb, Nonce: 0, }) @@ -4278,7 +4277,7 @@ func TestEIP7702(t *testing.T) { _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { b.SetCoinbase(aa) txdata := &types.SetCodeTx{ - ChainID: gspec.Config.ChainID.Uint64(), + ChainID: uint256.MustFromBig(gspec.Config.ChainID), Nonce: 0, To: addr1, Gas: 500000, diff --git a/core/state_transition.go b/core/state_transition.go index 009b679b27..b6203e6aae 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -529,8 +529,8 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { // validateAuthorization validates an EIP-7702 authorization against the state. func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) { - // Verify chain ID is 0 or equal to current chain ID. - if auth.ChainID != 0 && st.evm.ChainConfig().ChainID.Uint64() != auth.ChainID { + // Verify chain ID is null or equal to current chain ID. + if !auth.ChainID.IsZero() && auth.ChainID.CmpBig(st.evm.ChainConfig().ChainID) != 0 { return authority, ErrAuthorizationWrongChainID } // Limit nonce to 2^64-1 per EIP-2681. diff --git a/core/types/gen_authorization.go b/core/types/gen_authorization.go index be5467c50d..57069cbb1f 100644 --- a/core/types/gen_authorization.go +++ b/core/types/gen_authorization.go @@ -16,7 +16,7 @@ var _ = (*authorizationMarshaling)(nil) // MarshalJSON marshals as JSON. func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { type SetCodeAuthorization struct { - ChainID hexutil.Uint64 `json:"chainId" gencodec:"required"` + ChainID hexutil.U256 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` V hexutil.Uint64 `json:"yParity" gencodec:"required"` @@ -24,7 +24,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { S hexutil.U256 `json:"s" gencodec:"required"` } var enc SetCodeAuthorization - enc.ChainID = hexutil.Uint64(s.ChainID) + enc.ChainID = hexutil.U256(s.ChainID) enc.Address = s.Address enc.Nonce = hexutil.Uint64(s.Nonce) enc.V = hexutil.Uint64(s.V) @@ -36,7 +36,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { type SetCodeAuthorization struct { - ChainID *hexutil.Uint64 `json:"chainId" gencodec:"required"` + ChainID *hexutil.U256 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` V *hexutil.Uint64 `json:"yParity" gencodec:"required"` @@ -50,7 +50,7 @@ func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' for SetCodeAuthorization") } - s.ChainID = uint64(*dec.ChainID) + s.ChainID = uint256.Int(*dec.ChainID) if dec.Address == nil { return errors.New("missing required field 'address' for SetCodeAuthorization") } diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index 993d633c6f..1bbb97a3ec 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -155,7 +155,7 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) { enc.Proofs = itx.Sidecar.Proofs } case *SetCodeTx: - enc.ChainID = (*hexutil.Big)(new(big.Int).SetUint64(itx.ChainID)) + enc.ChainID = (*hexutil.Big)(itx.ChainID.ToBig()) enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) enc.To = tx.To() enc.Gas = (*hexutil.Uint64)(&itx.Gas) @@ -353,7 +353,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' in transaction") } - itx.ChainID = uint256.MustFromBig((*big.Int)(dec.ChainID)) + var overflow bool + itx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt()) + if overflow { + return errors.New("'chainId' value overflows uint256") + } if dec.Nonce == nil { return errors.New("missing required field 'nonce' in transaction") } @@ -395,7 +399,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { itx.BlobHashes = dec.BlobVersionedHashes // signature R - var overflow bool if dec.R == nil { return errors.New("missing required field 'r' in transaction") } @@ -432,7 +435,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' in transaction") } - itx.ChainID = dec.ChainID.ToInt().Uint64() + var overflow bool + itx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt()) + if overflow { + return errors.New("'chainId' value overflows uint256") + } if dec.Nonce == nil { return errors.New("missing required field 'nonce' in transaction") } @@ -470,7 +477,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { itx.AuthList = dec.AuthorizationList // signature R - var overflow bool if dec.R == nil { return errors.New("missing required field 'r' in transaction") } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index d72643b4a8..4d70f37bd3 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -219,7 +219,7 @@ func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big } // Check that chain ID of tx matches the signer. We also accept ID zero here, // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID != 0 && new(big.Int).SetUint64(txdata.ChainID).Cmp(s.chainId) != 0 { + if txdata.ChainID != nil && txdata.ChainID.CmpBig(s.chainId) != 0 { return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) } R, S, _ = decodeSignature(sig) diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go index ce1f287caa..88251ab957 100644 --- a/core/types/tx_blob.go +++ b/core/types/tx_blob.go @@ -47,9 +47,9 @@ type BlobTx struct { Sidecar *BlobTxSidecar `rlp:"-"` // Signature values - V *uint256.Int `json:"v" gencodec:"required"` - R *uint256.Int `json:"r" gencodec:"required"` - S *uint256.Int `json:"s" gencodec:"required"` + V *uint256.Int + R *uint256.Int + S *uint256.Int } // BlobTxSidecar contains the blobs of a blob transaction. diff --git a/core/types/tx_dynamic_fee.go b/core/types/tx_dynamic_fee.go index 8b5b514fde..981755cf70 100644 --- a/core/types/tx_dynamic_fee.go +++ b/core/types/tx_dynamic_fee.go @@ -37,9 +37,9 @@ type DynamicFeeTx struct { AccessList AccessList // Signature values - V *big.Int `json:"v" gencodec:"required"` - R *big.Int `json:"r" gencodec:"required"` - S *big.Int `json:"s" gencodec:"required"` + V *big.Int + R *big.Int + S *big.Int } // copy creates a deep copy of the transaction data and initializes all fields. diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index f14ae3bc9d..0fb5362c26 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -49,7 +49,7 @@ func AddressToDelegation(addr common.Address) []byte { // SetCodeTx implements the EIP-7702 transaction type which temporarily installs // the code at the signer's address. type SetCodeTx struct { - ChainID uint64 + ChainID *uint256.Int Nonce uint64 GasTipCap *uint256.Int // a.k.a. maxPriorityFeePerGas GasFeeCap *uint256.Int // a.k.a. maxFeePerGas @@ -61,16 +61,16 @@ type SetCodeTx struct { AuthList []SetCodeAuthorization // Signature values - V *uint256.Int `json:"v" gencodec:"required"` - R *uint256.Int `json:"r" gencodec:"required"` - S *uint256.Int `json:"s" gencodec:"required"` + V *uint256.Int + R *uint256.Int + S *uint256.Int } //go:generate go run github.com/fjl/gencodec -type SetCodeAuthorization -field-override authorizationMarshaling -out gen_authorization.go // SetCodeAuthorization is an authorization from an account to deploy code at its address. type SetCodeAuthorization struct { - ChainID uint64 `json:"chainId" gencodec:"required"` + ChainID uint256.Int `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` V uint8 `json:"yParity" gencodec:"required"` @@ -80,7 +80,7 @@ type SetCodeAuthorization struct { // field type overrides for gencodec type authorizationMarshaling struct { - ChainID hexutil.Uint64 + ChainID hexutil.U256 Nonce hexutil.Uint64 V hexutil.Uint64 R hexutil.U256 @@ -180,7 +180,7 @@ func (tx *SetCodeTx) copy() TxData { // accessors for innerTx. func (tx *SetCodeTx) txType() byte { return SetCodeTxType } -func (tx *SetCodeTx) chainID() *big.Int { return big.NewInt(int64(tx.ChainID)) } +func (tx *SetCodeTx) chainID() *big.Int { return tx.ChainID.ToBig() } func (tx *SetCodeTx) accessList() AccessList { return tx.AccessList } func (tx *SetCodeTx) data() []byte { return tx.Data } func (tx *SetCodeTx) gas() uint64 { return tx.Gas } @@ -207,7 +207,7 @@ func (tx *SetCodeTx) rawSignatureValues() (v, r, s *big.Int) { } func (tx *SetCodeTx) setSignatureValues(chainID, v, r, s *big.Int) { - tx.ChainID = chainID.Uint64() + tx.ChainID = uint256.MustFromBig(chainID) tx.V.SetFromBig(v) tx.R.SetFromBig(r) tx.S.SetFromBig(s) diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index a39a6666f4..175ac13a0f 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -503,7 +503,7 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { } data = &types.SetCodeTx{ To: *args.To, - ChainID: args.ChainID.ToInt().Uint64(), + ChainID: uint256.MustFromBig(args.ChainID.ToInt()), Nonce: uint64(*args.Nonce), Gas: uint64(*args.Gas), GasFeeCap: uint256.MustFromBig((*big.Int)(args.MaxFeePerGas)), diff --git a/tests/gen_stauthorization.go b/tests/gen_stauthorization.go index fbafd6fdea..4f2c50bd9f 100644 --- a/tests/gen_stauthorization.go +++ b/tests/gen_stauthorization.go @@ -16,7 +16,7 @@ var _ = (*stAuthorizationMarshaling)(nil) // MarshalJSON marshals as JSON. func (s stAuthorization) MarshalJSON() ([]byte, error) { type stAuthorization struct { - ChainID math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce math.HexOrDecimal64 `json:"nonce" gencodec:"required"` V math.HexOrDecimal64 `json:"v" gencodec:"required"` @@ -24,7 +24,7 @@ func (s stAuthorization) MarshalJSON() ([]byte, error) { S *math.HexOrDecimal256 `json:"s" gencodec:"required"` } var enc stAuthorization - enc.ChainID = math.HexOrDecimal64(s.ChainID) + enc.ChainID = (*math.HexOrDecimal256)(s.ChainID) enc.Address = s.Address enc.Nonce = math.HexOrDecimal64(s.Nonce) enc.V = math.HexOrDecimal64(s.V) @@ -36,7 +36,7 @@ func (s stAuthorization) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (s *stAuthorization) UnmarshalJSON(input []byte) error { type stAuthorization struct { - ChainID *math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *math.HexOrDecimal64 `json:"nonce" gencodec:"required"` V *math.HexOrDecimal64 `json:"v" gencodec:"required"` @@ -47,9 +47,10 @@ func (s *stAuthorization) UnmarshalJSON(input []byte) error { if err := json.Unmarshal(input, &dec); err != nil { return err } - if dec.ChainID != nil { - s.ChainID = uint64(*dec.ChainID) + if dec.ChainID == nil { + return errors.New("missing required field 'chainId' for stAuthorization") } + s.ChainID = (*big.Int)(dec.ChainID) if dec.Address == nil { return errors.New("missing required field 'address' for stAuthorization") } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 6e66bbaa72..740ebd4afd 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -140,7 +140,7 @@ type stTransactionMarshaling struct { // Authorization is an authorization from an account to deploy code at it's address. type stAuthorization struct { - ChainID uint64 + ChainID *big.Int `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` V uint8 `json:"v" gencodec:"required"` @@ -150,7 +150,7 @@ type stAuthorization struct { // field type overrides for gencodec type stAuthorizationMarshaling struct { - ChainID math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 Nonce math.HexOrDecimal64 V math.HexOrDecimal64 R *math.HexOrDecimal256 @@ -446,7 +446,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess authList = make([]types.SetCodeAuthorization, len(tx.AuthorizationList)) for i, auth := range tx.AuthorizationList { authList[i] = types.SetCodeAuthorization{ - ChainID: auth.ChainID, + ChainID: *uint256.MustFromBig(auth.ChainID), Address: auth.Address, Nonce: auth.Nonce, V: auth.V, From 8dfad579e961f4fdd718fdcf435ad68f4d6d67df Mon Sep 17 00:00:00 2001 From: jwasinger Date: Tue, 14 Jan 2025 23:26:24 +0800 Subject: [PATCH 046/940] eth/gasprice: ensure cache purging goroutine terminates with subscription (#31025) --- eth/gasprice/gasprice.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index fe2e4d408a..4fd3df7428 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -120,16 +120,23 @@ func NewOracle(backend OracleBackend, params Config, startPrice *big.Int) *Oracl cache := lru.NewCache[cacheKey, processedFees](2048) headEvent := make(chan core.ChainHeadEvent, 1) - backend.SubscribeChainHeadEvent(headEvent) - go func() { - var lastHead common.Hash - for ev := range headEvent { - if ev.Header.ParentHash != lastHead { - cache.Purge() + sub := backend.SubscribeChainHeadEvent(headEvent) + if sub != nil { // the gasprice testBackend doesn't support subscribing to head events + go func() { + var lastHead common.Hash + for { + select { + case ev := <-headEvent: + if ev.Header.ParentHash != lastHead { + cache.Purge() + } + lastHead = ev.Header.Hash() + case <-sub.Err(): + return + } } - lastHead = ev.Header.Hash() - } - }() + }() + } return &Oracle{ backend: backend, From 9b68875d68b409eb2efdb68a4b623aaacc10a5b6 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:45:20 +0100 Subject: [PATCH 047/940] beacon/engine: check for empty requests (#31010) According to https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#engine_newpayloadv4: > Elements of the list MUST be ordered by request_type in ascending order. Elements with empty request_data MUST be excluded from the list. --------- Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> --- eth/catalyst/api.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 3e45ad9e4f..91b6511f71 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -638,6 +638,9 @@ func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHas return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadV4 must only be called for prague payloads")) } requests := convertRequests(executionRequests) + if err := validateRequests(requests); err != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) + } return api.newPayload(params, versionedHashes, beaconRoot, requests, false) } @@ -727,6 +730,9 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV4(params engine.ExecutableData, v return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadWithWitnessV4 must only be called for prague payloads")) } requests := convertRequests(executionRequests) + if err := validateRequests(requests); err != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) + } return api.newPayload(params, versionedHashes, beaconRoot, requests, true) } @@ -1287,3 +1293,20 @@ func convertRequests(hex []hexutil.Bytes) [][]byte { } return req } + +// validateRequests checks that requests are ordered by their type and are not empty. +func validateRequests(requests [][]byte) error { + var last byte + for _, req := range requests { + // No empty requests. + if len(req) < 2 { + return fmt.Errorf("empty request: %v", req) + } + // Check that requests are ordered by their type. + if req[0] < last { + return fmt.Errorf("invalid request order: %v", req) + } + last = req[0] + } + return nil +} From 9e4f08c25dd0cb4b3d7bd992cadc5218f8623cea Mon Sep 17 00:00:00 2001 From: georgehao Date: Thu, 16 Jan 2025 21:36:45 +0800 Subject: [PATCH 048/940] core: use sync.Once for SenderCacher initialization (#31029) This changes the SenderCacher so its goroutines will only be started on first use. Avoids starting them when package core is just imported but core.BlockChain isn't used. --- core/blockchain.go | 2 +- core/sender_cacher.go | 13 +++++++++++-- core/txpool/legacypool/legacypool.go | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index b056b7ed0c..4ced94bb68 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1619,7 +1619,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness return nil, 0, nil } // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) - SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain) + SenderCacher().RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain) var ( stats = insertStats{startTime: mclock.Now()} diff --git a/core/sender_cacher.go b/core/sender_cacher.go index 4be53619eb..73bd5c85f2 100644 --- a/core/sender_cacher.go +++ b/core/sender_cacher.go @@ -18,12 +18,21 @@ package core import ( "runtime" + "sync" "github.com/ethereum/go-ethereum/core/types" ) -// SenderCacher is a concurrent transaction sender recoverer and cacher. -var SenderCacher = newTxSenderCacher(runtime.NumCPU()) +// senderCacherOnce is used to ensure that the SenderCacher is initialized only once. +var senderCacherOnce = sync.OnceValue(func() *txSenderCacher { + return newTxSenderCacher(runtime.NumCPU()) +}) + +// SenderCacher returns the singleton instance of SenderCacher, initializing it if called for the first time. +// This function is thread-safe and ensures that initialization happens only once. +func SenderCacher() *txSenderCacher { + return senderCacherOnce() +} // txSenderCacherRequest is a request for recovering transaction senders with a // specific signature scheme and caching it into the transactions themselves. diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 71cca7d1db..55899c18fb 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1440,7 +1440,7 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) { // Inject any transactions discarded due to reorgs log.Debug("Reinjecting stale transactions", "count", len(reinject)) - core.SenderCacher.Recover(pool.signer, reinject) + core.SenderCacher().Recover(pool.signer, reinject) pool.addTxsLocked(reinject, false) } From 47d17acdc96a7043b04f6c540a5c9ce57cff204a Mon Sep 17 00:00:00 2001 From: jwasinger Date: Thu, 16 Jan 2025 21:40:15 +0800 Subject: [PATCH 049/940] core/txpool/legacypool: ensure pending nonces are reset by SubPool.Clear (#31020) closes https://github.com/ethereum/go-ethereum/issues/30842 --- core/txpool/legacypool/legacypool.go | 1 + ethclient/simulated/backend_test.go | 51 +++++++++++++- ethclient/simulated/rollback_test.go | 102 +++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 ethclient/simulated/rollback_test.go diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 55899c18fb..3d780ad373 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1994,6 +1994,7 @@ func (pool *LegacyPool) Clear() { pool.priced = newPricedList(pool.all) pool.pending = make(map[common.Address]*list) pool.queue = make(map[common.Address]*list) + pool.pendingNonces = newNoncer(pool.currentState) if !pool.config.NoLocals && pool.config.Journal != "" { pool.journal = newTxJournal(pool.config.Journal) diff --git a/ethclient/simulated/backend_test.go b/ethclient/simulated/backend_test.go index 37f4dbbf7b..8efe93e243 100644 --- a/ethclient/simulated/backend_test.go +++ b/ethclient/simulated/backend_test.go @@ -19,11 +19,15 @@ package simulated import ( "context" "crypto/ecdsa" + "crypto/sha256" "math/big" "math/rand" "testing" "time" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/holiman/uint256" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -34,8 +38,10 @@ import ( var _ bind.ContractBackend = (Client)(nil) var ( - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - testAddr = crypto.PubkeyToAddress(testKey.PublicKey) + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + testAddr = crypto.PubkeyToAddress(testKey.PublicKey) + testKey2, _ = crypto.HexToECDSA("7ee346e3f7efc685250053bfbafbfc880d58dc6145247053d4fb3cb0f66dfcb2") + testAddr2 = crypto.PubkeyToAddress(testKey2.PublicKey) ) func simTestBackend(testAddr common.Address) *Backend { @@ -46,6 +52,46 @@ func simTestBackend(testAddr common.Address) *Backend { ) } +func newBlobTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) { + client := sim.Client() + + testBlob := &kzg4844.Blob{0x00} + testBlobCommit, _ := kzg4844.BlobToCommitment(testBlob) + testBlobProof, _ := kzg4844.ComputeBlobProof(testBlob, testBlobCommit) + testBlobVHash := kzg4844.CalcBlobHashV1(sha256.New(), &testBlobCommit) + + head, _ := client.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei)) + gasPriceU256, _ := uint256.FromBig(gasPrice) + gasTipCapU256, _ := uint256.FromBig(big.NewInt(params.GWei)) + + addr := crypto.PubkeyToAddress(key.PublicKey) + chainid, _ := client.ChainID(context.Background()) + nonce, err := client.PendingNonceAt(context.Background(), addr) + if err != nil { + return nil, err + } + + chainidU256, _ := uint256.FromBig(chainid) + tx := types.NewTx(&types.BlobTx{ + ChainID: chainidU256, + GasTipCap: gasTipCapU256, + GasFeeCap: gasPriceU256, + BlobFeeCap: uint256.NewInt(1), + Gas: 21000, + Nonce: nonce, + To: addr, + AccessList: nil, + BlobHashes: []common.Hash{testBlobVHash}, + Sidecar: &types.BlobTxSidecar{ + Blobs: []kzg4844.Blob{*testBlob}, + Commitments: []kzg4844.Commitment{testBlobCommit}, + Proofs: []kzg4844.Proof{testBlobProof}, + }, + }) + return types.SignTx(tx, types.LatestSignerForChainID(chainid), key) +} + func newTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) { client := sim.Client() @@ -66,6 +112,7 @@ func newTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) { Gas: 21000, To: &addr, }) + return types.SignTx(tx, types.LatestSignerForChainID(chainid), key) } diff --git a/ethclient/simulated/rollback_test.go b/ethclient/simulated/rollback_test.go new file mode 100644 index 0000000000..8fc9f5bc86 --- /dev/null +++ b/ethclient/simulated/rollback_test.go @@ -0,0 +1,102 @@ +package simulated + +import ( + "context" + "crypto/ecdsa" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/core/types" +) + +// TestTransactionRollbackBehavior tests that calling Rollback on the simulated backend doesn't prevent subsequent +// addition of new transactions +func TestTransactionRollbackBehavior(t *testing.T) { + sim := NewBackend( + types.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000000000)}, + testAddr2: {Balance: big.NewInt(10000000000000000)}, + }, + ) + defer sim.Close() + client := sim.Client() + + btx0 := testSendSignedTx(t, testKey, sim, true) + tx0 := testSendSignedTx(t, testKey2, sim, false) + tx1 := testSendSignedTx(t, testKey2, sim, false) + + sim.Rollback() + + if pendingStateHasTx(client, btx0) || pendingStateHasTx(client, tx0) || pendingStateHasTx(client, tx1) { + t.Fatalf("all transactions were not rolled back") + } + + btx2 := testSendSignedTx(t, testKey, sim, true) + tx2 := testSendSignedTx(t, testKey2, sim, false) + tx3 := testSendSignedTx(t, testKey2, sim, false) + + sim.Commit() + + if !pendingStateHasTx(client, btx2) || !pendingStateHasTx(client, tx2) || !pendingStateHasTx(client, tx3) { + t.Fatalf("all post-rollback transactions were not included") + } +} + +// testSendSignedTx sends a signed transaction to the simulated backend. +// It does not commit the block. +func testSendSignedTx(t *testing.T, key *ecdsa.PrivateKey, sim *Backend, isBlobTx bool) *types.Transaction { + t.Helper() + client := sim.Client() + ctx := context.Background() + + var ( + err error + signedTx *types.Transaction + ) + if isBlobTx { + signedTx, err = newBlobTx(sim, key) + } else { + signedTx, err = newTx(sim, key) + } + if err != nil { + t.Fatalf("failed to create transaction: %v", err) + } + + if err = client.SendTransaction(ctx, signedTx); err != nil { + t.Fatalf("failed to send transaction: %v", err) + } + + return signedTx +} + +// pendingStateHasTx returns true if a given transaction was successfully included as of the latest pending state. +func pendingStateHasTx(client Client, tx *types.Transaction) bool { + ctx := context.Background() + + var ( + receipt *types.Receipt + err error + ) + + // Poll for receipt with timeout + deadline := time.Now().Add(2 * time.Second) + for time.Now().Before(deadline) { + receipt, err = client.TransactionReceipt(ctx, tx.Hash()) + if err == nil && receipt != nil { + break + } + time.Sleep(100 * time.Millisecond) + } + + if err != nil { + return false + } + if receipt == nil { + return false + } + if receipt.Status != types.ReceiptStatusSuccessful { + return false + } + return true +} From 4d94bd83b20ce430e435f3107f29632c627cfb26 Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Thu, 16 Jan 2025 09:58:16 -0500 Subject: [PATCH 050/940] core/tracing: document `OnCodeChange` now being called from SelfDestruct (#31007) Co-authored-by: Sina M <1591639+s1na@users.noreply.github.com> --- core/tracing/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/tracing/CHANGELOG.md b/core/tracing/CHANGELOG.md index e8aa3a9e2e..270e0a30bf 100644 --- a/core/tracing/CHANGELOG.md +++ b/core/tracing/CHANGELOG.md @@ -9,6 +9,14 @@ All notable changes to the tracing interface will be documented in this file. - `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.12] + +This release contains a change in behavior for `OnCodeChange` hook. + +### `OnCodeChange` change + +The `OnCodeChange` hook is now called when the code of a contract is removed due to a selfdestruct. Previously, no code change was emitted on such occasions. + ## [v1.14.4] This release contained only minor extensions to the tracing interface. From a7f9523ae1182aeb5fecd54042f264fc196ba03b Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 17 Jan 2025 09:59:02 +0800 Subject: [PATCH 051/940] all: implement state history v2 (#30107) This pull request delivers the new version of the state history, where the raw storage key is used instead of the hash. Before the cancun fork, it's supported by protocol to destruct a specific account and therefore, all the storage slot owned by it should be wiped in the same transition. Technically, storage wiping should be performed through storage iteration, and only the storage key hash will be available for traversal if the state snapshot is not available. Therefore, the storage key hash is chosen as the identifier in the old version state history. Fortunately, account self-destruction has been deprecated by the protocol since the Cancun fork, and there are no empty accounts eligible for deletion under EIP-158. Therefore, we can conclude that no storage wiping should occur after the Cancun fork. In this case, it makes no sense to keep using hash. Besides, another big reason for making this change is the current format state history is unusable if verkle is activated. Verkle tree has a different key derivation scheme (merkle uses keccak256), the preimage of key hash must be provided in order to make verkle rollback functional. This pull request is a prerequisite for landing verkle. Additionally, the raw storage key is more human-friendly for those who want to manually check the history, even though Solidity already performs some hashing to derive the storage location. --- This pull request doesn't bump the database version, as I believe the database should still be compatible if users degrade from the new geth version to old one, the only side effect is the persistent new version state history will be unusable. --------- Co-authored-by: Zsolt Felfoldi --- cmd/evm/internal/t8ntool/execution.go | 4 +- cmd/evm/runner.go | 2 +- cmd/geth/dbcmd.go | 3 +- core/blockchain.go | 2 +- core/blockchain_test.go | 2 +- core/chain_makers.go | 4 +- core/genesis.go | 4 +- core/state/state_object.go | 12 +++- core/state/state_test.go | 6 +- core/state/statedb.go | 25 ++++--- core/state/statedb_fuzz_test.go | 2 +- core/state/statedb_hooked_test.go | 2 +- core/state/statedb_test.go | 29 ++++---- core/state/stateupdate.go | 86 +++++++++++++++-------- core/state/sync_test.go | 2 +- core/state/trie_prefetcher_test.go | 2 +- core/txpool/blobpool/blobpool_test.go | 12 ++-- eth/api_debug_test.go | 6 +- eth/state_accessor.go | 2 +- tests/state_test_util.go | 4 +- triedb/pathdb/buffer.go | 2 +- triedb/pathdb/database_test.go | 79 +++++++++++++++------ triedb/pathdb/difflayer_test.go | 6 +- triedb/pathdb/disklayer.go | 2 +- triedb/pathdb/execute.go | 40 +++++++---- triedb/pathdb/history.go | 44 +++++++----- triedb/pathdb/history_inspect.go | 8 ++- triedb/pathdb/history_test.go | 13 ++-- triedb/pathdb/iterator_test.go | 98 +++++++++++++-------------- triedb/pathdb/journal.go | 3 +- triedb/pathdb/states.go | 21 ++++-- triedb/pathdb/states_test.go | 30 +++++++- triedb/states.go | 3 +- 33 files changed, 356 insertions(+), 204 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index aef497885e..7c17a251f0 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -379,7 +379,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } // Commit block - root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber)) + root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber), chainConfig.IsCancun(vmContext.BlockNumber, vmContext.Time)) if err != nil { return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err)) } @@ -437,7 +437,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB } } // Commit and re-open to start with a clean state. - root, _ := statedb.Commit(0, false) + root, _ := statedb.Commit(0, false, false) statedb, _ = state.New(root, sdb) return statedb } diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index c67d3657e2..b2cf28353b 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -336,7 +336,7 @@ func runCmd(ctx *cli.Context) error { output, stats, err := timedExec(bench, execFunc) if ctx.Bool(DumpFlag.Name) { - root, err := runtimeConfig.State.Commit(genesisConfig.Number, true) + root, err := runtimeConfig.State.Commit(genesisConfig.Number, true, false) if err != nil { fmt.Printf("Failed to commit changes %v\n", err) return err diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go index 7622246050..cd41c57c75 100644 --- a/cmd/geth/dbcmd.go +++ b/cmd/geth/dbcmd.go @@ -829,8 +829,7 @@ func inspectAccount(db *triedb.Database, start uint64, end uint64, address commo 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) + stats, err := db.StorageHistory(address, slot, start, end) if err != nil { return err } diff --git a/core/blockchain.go b/core/blockchain.go index 4ced94bb68..6aac541ba0 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1471,7 +1471,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. log.Crit("Failed to write block into disk", "err", err) } // Commit all cached state changes into underlying memory database. - root, err := statedb.Commit(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number())) + root, err := statedb.Commit(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number()), bc.chainConfig.IsCancun(block.Number(), block.Time())) if err != nil { return err } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 7805a7c6e8..84f1b9740c 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -181,7 +181,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { blockchain.chainmu.MustLock() rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTd(block.ParentHash(), block.NumberU64()-1))) rawdb.WriteBlock(blockchain.db, block) - statedb.Commit(block.NumberU64(), false) + statedb.Commit(block.NumberU64(), false, false) blockchain.chainmu.Unlock() } return nil diff --git a/core/chain_makers.go b/core/chain_makers.go index 26714845eb..5298874a40 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -405,7 +405,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse } // Write state changes to db - root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number)) + root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number), config.IsCancun(b.header.Number, b.header.Time)) if err != nil { panic(fmt.Sprintf("state write error: %v", err)) } @@ -510,7 +510,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine } // Write state changes to DB. - root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number)) + root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number), config.IsCancun(b.header.Number, b.header.Time)) if err != nil { panic(fmt.Sprintf("state write error: %v", err)) } diff --git a/core/genesis.go b/core/genesis.go index 02cdc74d86..68d945e37e 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -146,7 +146,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { statedb.SetState(addr, key, value) } } - return statedb.Commit(0, false) + return statedb.Commit(0, false, false) } // flushAlloc is very similar with hash, but the main difference is all the @@ -172,7 +172,7 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, e statedb.SetState(addr, key, value) } } - root, err := statedb.Commit(0, false) + root, err := statedb.Commit(0, false, false) if err != nil { return common.Hash{}, err } diff --git a/core/state/state_object.go b/core/state/state_object.go index 76a3aba92c..a6979bd361 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -399,10 +399,16 @@ func (s *stateObject) commitStorage(op *accountUpdate) { op.storages = make(map[common.Hash][]byte) } op.storages[hash] = encode(val) - if op.storagesOrigin == nil { - op.storagesOrigin = make(map[common.Hash][]byte) + + if op.storagesOriginByKey == nil { + op.storagesOriginByKey = make(map[common.Hash][]byte) } - op.storagesOrigin[hash] = encode(s.originStorage[key]) + if op.storagesOriginByHash == nil { + op.storagesOriginByHash = make(map[common.Hash][]byte) + } + origin := encode(s.originStorage[key]) + op.storagesOriginByKey[key] = origin + op.storagesOriginByHash[hash] = origin // Overwrite the clean value of storage slots s.originStorage[key] = val diff --git a/core/state/state_test.go b/core/state/state_test.go index 6f54300c37..b443411f1b 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -56,7 +56,7 @@ func TestDump(t *testing.T) { // write some of them to the trie s.state.updateStateObject(obj1) s.state.updateStateObject(obj2) - root, _ := s.state.Commit(0, false) + root, _ := s.state.Commit(0, false, false) // check that DumpToCollector contains the state objects that are in trie s.state, _ = New(root, tdb) @@ -116,7 +116,7 @@ func TestIterativeDump(t *testing.T) { // write some of them to the trie s.state.updateStateObject(obj1) s.state.updateStateObject(obj2) - root, _ := s.state.Commit(0, false) + root, _ := s.state.Commit(0, false, false) s.state, _ = New(root, tdb) b := &bytes.Buffer{} @@ -142,7 +142,7 @@ func TestNull(t *testing.T) { var value common.Hash s.state.SetState(address, common.Hash{}, value) - s.state.Commit(0, false) + s.state.Commit(0, false, false) if value := s.state.GetState(address, common.Hash{}); value != (common.Hash{}) { t.Errorf("expected empty current value, got %x", value) diff --git a/core/state/statedb.go b/core/state/statedb.go index d279ccfdfe..0310ee6973 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1051,7 +1051,7 @@ func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root // 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() (map[common.Hash]*accountDelete, []*trienode.NodeSet, error) { +func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*accountDelete, []*trienode.NodeSet, error) { var ( nodes []*trienode.NodeSet buf = crypto.NewKeccakState() @@ -1080,6 +1080,9 @@ func (s *StateDB) handleDestruction() (map[common.Hash]*accountDelete, []*trieno if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsVerkle() { continue } + if noStorageWiping { + return nil, nil, fmt.Errorf("unexpected storage wiping, %x", addr) + } // Remove storage slots belonging to the account. storages, storagesOrigin, set, err := s.deleteStorage(addr, addrHash, prev.Root) if err != nil { @@ -1101,7 +1104,7 @@ func (s *StateDB) GetTrie() 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) { +func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool) (*stateUpdate, error) { // Short circuit in case any database failure occurred earlier. if s.dbErr != nil { return nil, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) @@ -1155,7 +1158,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool) (*stateUpdate, error) { // 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() + deletes, delNodes, err := s.handleDestruction(noStorageWiping) if err != nil { return nil, err } @@ -1252,13 +1255,14 @@ func (s *StateDB) commit(deleteEmptyObjects bool) (*stateUpdate, error) { origin := s.originalRoot s.originalRoot = root - return newStateUpdate(origin, root, deletes, updates, nodes), nil + + return newStateUpdate(noStorageWiping, origin, root, deletes, updates, nodes), nil } // 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) +func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (*stateUpdate, error) { + ret, err := s.commit(deleteEmptyObjects, noStorageWiping) if err != nil { return nil, err } @@ -1310,8 +1314,13 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool) (*stateU // // The associated block number of the state transition is also provided // for more chain context. -func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, error) { - ret, err := s.commitAndFlush(block, deleteEmptyObjects) +// +// noStorageWiping is a flag indicating whether storage wiping is permitted. +// Since self-destruction was deprecated with the Cancun fork and there are +// no empty accounts left that could be deleted by EIP-158, storage wiping +// should not occur. +func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, error) { + ret, err := s.commitAndFlush(block, deleteEmptyObjects, noStorageWiping) if err != nil { return common.Hash{}, err } diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go index 7cbfd9b9d7..ed99cf687c 100644 --- a/core/state/statedb_fuzz_test.go +++ b/core/state/statedb_fuzz_test.go @@ -228,7 +228,7 @@ func (test *stateTest) run() bool { } else { state.IntermediateRoot(true) // call intermediateRoot at the transaction boundary } - ret, err := state.commitAndFlush(0, true) // call commit at the block boundary + ret, err := state.commitAndFlush(0, true, false) // call commit at the block boundary if err != nil { panic(err) } diff --git a/core/state/statedb_hooked_test.go b/core/state/statedb_hooked_test.go index 5f82ed06d0..874a275993 100644 --- a/core/state/statedb_hooked_test.go +++ b/core/state/statedb_hooked_test.go @@ -71,7 +71,7 @@ func TestBurn(t *testing.T) { hooked.AddBalance(addC, uint256.NewInt(200), tracing.BalanceChangeUnspecified) hooked.Finalise(true) - s.Commit(0, false) + s.Commit(0, false, false) if have, want := burned, uint256.NewInt(600); !have.Eq(want) { t.Fatalf("burn-count wrong, have %v want %v", have, want) } diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 37141e90b0..67eb9cbdc6 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -119,7 +119,7 @@ func TestIntermediateLeaks(t *testing.T) { } // Commit and cross check the databases. - transRoot, err := transState.Commit(0, false) + transRoot, err := transState.Commit(0, false, false) if err != nil { t.Fatalf("failed to commit transition state: %v", err) } @@ -127,7 +127,7 @@ func TestIntermediateLeaks(t *testing.T) { t.Errorf("can not commit trie %v to persistent database", transRoot.Hex()) } - finalRoot, err := finalState.Commit(0, false) + finalRoot, err := finalState.Commit(0, false, false) if err != nil { t.Fatalf("failed to commit final state: %v", err) } @@ -240,7 +240,7 @@ func TestCopyWithDirtyJournal(t *testing.T) { obj.data.Root = common.HexToHash("0xdeadbeef") orig.updateStateObject(obj) } - root, _ := orig.Commit(0, true) + root, _ := orig.Commit(0, true, false) orig, _ = New(root, db) // modify all in memory without finalizing @@ -293,7 +293,7 @@ func TestCopyObjectState(t *testing.T) { 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) + orig.Commit(0, true, false) 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) @@ -696,7 +696,7 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { func TestTouchDelete(t *testing.T) { s := newStateEnv() s.state.getOrNewStateObject(common.Address{}) - root, _ := s.state.Commit(0, false) + root, _ := s.state.Commit(0, false, false) s.state, _ = New(root, s.state.db) snapshot := s.state.Snapshot() @@ -784,7 +784,7 @@ 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 - root, _ := state.Commit(0, false) + root, _ := state.Commit(0, false, 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) @@ -898,11 +898,11 @@ func TestCommitCopy(t *testing.T) { if val := state.GetCommittedState(addr, skey1); val != (common.Hash{}) { t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{}) } - root, _ := state.Commit(0, true) + root, _ := state.Commit(0, true, false) state, _ = New(root, db) state.SetState(addr, skey2, sval2) - state.Commit(1, true) + state.Commit(1, true, false) // Copy the committed state database, the copied one is not fully functional. copied := state.Copy() @@ -943,7 +943,7 @@ func TestDeleteCreateRevert(t *testing.T) { addr := common.BytesToAddress([]byte("so")) state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified) - root, _ := state.Commit(0, false) + root, _ := state.Commit(0, false, false) state, _ = New(root, state.db) // Simulate self-destructing in one transaction, then create-reverting in another @@ -955,7 +955,7 @@ func TestDeleteCreateRevert(t *testing.T) { state.RevertToSnapshot(id) // Commit the entire state and make sure we don't crash and have the correct state - root, _ = state.Commit(0, true) + root, _ = state.Commit(0, true, false) state, _ = New(root, state.db) if state.getStateObject(addr) != nil { @@ -998,7 +998,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) { a2 := common.BytesToAddress([]byte("another")) state.SetBalance(a2, uint256.NewInt(100), tracing.BalanceChangeUnspecified) state.SetCode(a2, []byte{1, 2, 4}) - root, _ = state.Commit(0, false) + root, _ = state.Commit(0, false, false) t.Logf("root: %x", root) // force-flush tdb.Commit(root, false) @@ -1022,7 +1022,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) { } // Modify the state state.SetBalance(addr, uint256.NewInt(2), tracing.BalanceChangeUnspecified) - root, err := state.Commit(0, false) + root, err := state.Commit(0, false, false) if err == nil { t.Fatalf("expected error, got root :%x", root) } @@ -1213,7 +1213,7 @@ func TestFlushOrderDataLoss(t *testing.T) { state.SetState(common.Address{a}, common.Hash{a, s}, common.Hash{a, s}) } } - root, err := state.Commit(0, false) + root, err := state.Commit(0, false, false) if err != nil { t.Fatalf("failed to commit state trie: %v", err) } @@ -1288,8 +1288,7 @@ func TestDeleteStorage(t *testing.T) { value := common.Hash(uint256.NewInt(uint64(10 * i)).Bytes32()) state.SetState(addr, slot, value) } - root, _ := state.Commit(0, true) - + root, _ := state.Commit(0, true, false) // Init phase done, create two states, one with snap and one without fastState, _ := New(root, NewDatabase(tdb, snaps)) slowState, _ := New(root, NewDatabase(tdb, nil)) diff --git a/core/state/stateupdate.go b/core/state/stateupdate.go index 45de660ca5..75c4ca028c 100644 --- a/core/state/stateupdate.go +++ b/core/state/stateupdate.go @@ -32,34 +32,56 @@ type contractCode struct { // 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. - storages map[common.Hash][]byte // storages stores mutated slots, the value should be nil. - storagesOrigin map[common.Hash][]byte // storagesOrigin stores the original values of mutated slots in prefix-zero-trimmed RLP format. + address common.Address // address is the unique account identifier + origin []byte // origin is the original value of account data in slim-RLP encoding. + + // storages stores mutated slots, the value should be nil. + storages map[common.Hash][]byte + + // storagesOrigin stores the original values of mutated slots in + // prefix-zero-trimmed RLP format. The map key refers to the **HASH** + // of the raw storage slot key. + storagesOrigin map[common.Hash][]byte } // 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. + 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. + + // storagesOriginByKey and storagesOriginByHash both store the original values + // of mutated slots in prefix-zero-trimmed RLP format. The difference is that + // storagesOriginByKey uses the **raw** storage slot key as the map ID, while + // storagesOriginByHash uses the **hash** of the storage slot key instead. + storagesOriginByKey map[common.Hash][]byte + storagesOriginByHash map[common.Hash][]byte } // 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 - 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 + originRoot common.Hash // hash of the state before applying mutation + root common.Hash // hash of the state after applying mutation + 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 stores mutated slots in 'prefix-zero-trimmed' RLP format. + // The value is keyed by account hash and **storage slot key hash**. + storages map[common.Hash]map[common.Hash][]byte + + // storagesOrigin stores the original values of mutated slots in + // 'prefix-zero-trimmed' RLP format. + // (a) the value is keyed by account hash and **storage slot key** if rawStorageKey is true; + // (b) the value is keyed by account hash and **storage slot key hash** if rawStorageKey is false; + storagesOrigin map[common.Address]map[common.Hash][]byte + rawStorageKey bool + + codes map[common.Address]contractCode // codes contains the set of dirty codes + nodes *trienode.MergedNodeSet // Aggregated dirty nodes caused by state changes } // empty returns a flag indicating the state transition is empty or not. @@ -67,10 +89,13 @@ 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 { +// newStateUpdate constructs a state update object by identifying the differences +// between two states through state execution. It combines the specified account +// deletions and account updates to create a complete state update. +// +// rawStorageKey is a flag indicating whether to use the raw storage slot key or +// the hash of the slot key for constructing state update object. +func newStateUpdate(rawStorageKey bool, originRoot common.Hash, root common.Hash, deletes map[common.Hash]*accountDelete, updates map[common.Hash]*accountUpdate, nodes *trienode.MergedNodeSet) *stateUpdate { var ( accounts = make(map[common.Hash][]byte) accountsOrigin = make(map[common.Address][]byte) @@ -78,13 +103,14 @@ func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common storagesOrigin = make(map[common.Address]map[common.Hash][]byte) codes = make(map[common.Address]contractCode) ) - // Due to the fact that some accounts could be destructed and resurrected - // within the same block, the deletions must be aggregated first. + // Since some accounts might be destroyed and recreated within the same + // block, deletions must be aggregated first. for addrHash, op := range deletes { addr := op.address accounts[addrHash] = nil accountsOrigin[addr] = op.origin + // If storage wiping exists, the hash of the storage slot key must be used if len(op.storages) > 0 { storages[addrHash] = op.storages } @@ -118,12 +144,16 @@ func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common } // Aggregate the storage original values. If the slot is already present // in aggregated storagesOrigin set, skip it. - if len(op.storagesOrigin) > 0 { + storageOriginSet := op.storagesOriginByHash + if rawStorageKey { + storageOriginSet = op.storagesOriginByKey + } + if len(storageOriginSet) > 0 { origin, exist := storagesOrigin[addr] if !exist { - storagesOrigin[addr] = op.storagesOrigin + storagesOrigin[addr] = storageOriginSet } else { - for key, slot := range op.storagesOrigin { + for key, slot := range storageOriginSet { if _, found := origin[key]; !found { origin[key] = slot } @@ -138,6 +168,7 @@ func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common accountsOrigin: accountsOrigin, storages: storages, storagesOrigin: storagesOrigin, + rawStorageKey: rawStorageKey, codes: codes, nodes: nodes, } @@ -153,5 +184,6 @@ func (sc *stateUpdate) stateSet() *triedb.StateSet { AccountsOrigin: sc.accountsOrigin, Storages: sc.storages, StoragesOrigin: sc.storagesOrigin, + RawStorageKey: sc.rawStorageKey, } } diff --git a/core/state/sync_test.go b/core/state/sync_test.go index efa56f8860..5c8b5a90f7 100644 --- a/core/state/sync_test.go +++ b/core/state/sync_test.go @@ -79,7 +79,7 @@ func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, c } accounts = append(accounts, acc) } - root, _ := state.Commit(0, false) + root, _ := state.Commit(0, false, false) // Return the generated state return db, sdb, nodeDb, root, accounts diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go index d96727704c..4d1b627c4d 100644 --- a/core/state/trie_prefetcher_test.go +++ b/core/state/trie_prefetcher_test.go @@ -83,7 +83,7 @@ func TestVerklePrefetcher(t *testing.T) { 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) + root, _ := state.Commit(0, true, false) state, _ = New(root, sdb) sRoot := state.GetStorageRoot(addr) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index e4441bec5d..3d90ec4412 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -650,7 +650,7 @@ func TestOpenDrops(t *testing.T) { 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.Commit(0, true) + statedb.Commit(0, true, false) chain := &testBlockChain{ config: params.MainnetChainConfig, @@ -769,7 +769,7 @@ func TestOpenIndex(t *testing.T) { // Create a blob pool out of the pre-seeded data statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) - statedb.Commit(0, true) + statedb.Commit(0, true, false) chain := &testBlockChain{ config: params.MainnetChainConfig, @@ -871,7 +871,7 @@ func TestOpenHeap(t *testing.T) { 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.Commit(0, true) + statedb.Commit(0, true, false) chain := &testBlockChain{ config: params.MainnetChainConfig, @@ -951,7 +951,7 @@ func TestOpenCap(t *testing.T) { 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.Commit(0, true) + statedb.Commit(0, true, false) chain := &testBlockChain{ config: params.MainnetChainConfig, @@ -1393,7 +1393,7 @@ func TestAdd(t *testing.T) { store.Put(blob) } } - statedb.Commit(0, true) + statedb.Commit(0, true, false) store.Close() // Create a blob pool out of the pre-seeded dats @@ -1519,7 +1519,7 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) { statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) pool.add(tx) } - statedb.Commit(0, true) + statedb.Commit(0, true, false) defer pool.Close() // Benchmark assembling the pending diff --git a/eth/api_debug_test.go b/eth/api_debug_test.go index cfb8829b5c..02b85f69fd 100644 --- a/eth/api_debug_test.go +++ b/eth/api_debug_test.go @@ -82,7 +82,7 @@ func TestAccountRange(t *testing.T) { m[addr] = true } } - root, _ := sdb.Commit(0, true) + root, _ := sdb.Commit(0, true, false) sdb, _ = state.New(root, statedb) trie, err := statedb.OpenTrie(root) @@ -140,7 +140,7 @@ func TestEmptyAccountRange(t *testing.T) { st, _ = state.New(types.EmptyRootHash, statedb) ) // Commit(although nothing to flush) and re-init the statedb - st.Commit(0, true) + st.Commit(0, true, false) st, _ = state.New(types.EmptyRootHash, statedb) results := st.RawDump(&state.DumpConfig{ @@ -183,7 +183,7 @@ func TestStorageRangeAt(t *testing.T) { for _, entry := range storage { sdb.SetState(addr, *entry.Key, entry.Value) } - root, _ := sdb.Commit(0, false) + root, _ := sdb.Commit(0, false, false) sdb, _ = state.New(root, db) // Check a few combinations of limit and start/end. diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 0749d73791..99ed28d96a 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -152,7 +152,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u return nil, nil, fmt.Errorf("processing block %d failed: %v", current.NumberU64(), err) } // Finalize the state so any modifications are written to the trie - root, err := statedb.Commit(current.NumberU64(), eth.blockchain.Config().IsEIP158(current.Number())) + root, err := statedb.Commit(current.NumberU64(), eth.blockchain.Config().IsEIP158(current.Number()), eth.blockchain.Config().IsCancun(current.Number(), current.Time())) if err != nil { return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w", current.NumberU64(), current.Root().Hex(), err) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 740ebd4afd..e658b62ebf 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -339,7 +339,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh st.StateDB.AddBalance(block.Coinbase(), new(uint256.Int), tracing.BalanceChangeUnspecified) // Commit state mutations into database. - root, _ = st.StateDB.Commit(block.NumberU64(), config.IsEIP158(block.Number())) + root, _ = st.StateDB.Commit(block.NumberU64(), config.IsEIP158(block.Number()), config.IsCancun(block.Number(), block.Time())) if tracer := evm.Config.Tracer; tracer != nil && tracer.OnTxEnd != nil { receipt := &types.Receipt{GasUsed: vmRet.UsedGas} tracer.OnTxEnd(receipt, nil) @@ -512,7 +512,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo } } // Commit and re-open to start with a clean state. - root, _ := statedb.Commit(0, false) + root, _ := statedb.Commit(0, false, false) // If snapshot is requested, initialize the snapshotter and use it in state. var snaps *snapshot.Tree diff --git a/triedb/pathdb/buffer.go b/triedb/pathdb/buffer.go index 68e136f193..dea8875bda 100644 --- a/triedb/pathdb/buffer.go +++ b/triedb/pathdb/buffer.go @@ -46,7 +46,7 @@ func newBuffer(limit int, nodes *nodeSet, states *stateSet, layers uint64) *buff nodes = newNodeSet(nil) } if states == nil { - states = newStates(nil, nil) + states = newStates(nil, nil, false) } return &buffer{ layers: layers, diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index a6b1d3c045..f4b3fcec23 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -91,29 +91,47 @@ func newCtx(stateRoot common.Hash) *genctx { } } +func (ctx *genctx) storageOriginSet(rawStorageKey bool, t *tester) map[common.Address]map[common.Hash][]byte { + if !rawStorageKey { + return ctx.storageOrigin + } + set := make(map[common.Address]map[common.Hash][]byte) + for addr, storage := range ctx.storageOrigin { + subset := make(map[common.Hash][]byte) + for hash, val := range storage { + key := t.hashPreimage(hash) + subset[key] = val + } + set[addr] = subset + } + return set +} + type tester struct { db *Database roots []common.Hash - preimages map[common.Hash]common.Address - accounts map[common.Hash][]byte - storages map[common.Hash]map[common.Hash][]byte + preimages map[common.Hash][]byte + + // current state set + accounts map[common.Hash][]byte + storages map[common.Hash]map[common.Hash][]byte // state snapshots snapAccounts map[common.Hash]map[common.Hash][]byte snapStorages map[common.Hash]map[common.Hash]map[common.Hash][]byte } -func newTester(t *testing.T, historyLimit uint64) *tester { +func newTester(t *testing.T, historyLimit uint64, isVerkle bool) *tester { var ( disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) db = New(disk, &Config{ StateHistory: historyLimit, CleanCacheSize: 16 * 1024, WriteBufferSize: 16 * 1024, - }, false) + }, isVerkle) obj = &tester{ db: db, - preimages: make(map[common.Hash]common.Address), + preimages: make(map[common.Hash][]byte), accounts: make(map[common.Hash][]byte), storages: make(map[common.Hash]map[common.Hash][]byte), snapAccounts: make(map[common.Hash]map[common.Hash][]byte), @@ -125,7 +143,8 @@ func newTester(t *testing.T, historyLimit uint64) *tester { if len(obj.roots) != 0 { parent = obj.roots[len(obj.roots)-1] } - root, nodes, states := obj.generate(parent) + root, nodes, states := obj.generate(parent, i > 6) + if err := db.Update(root, parent, uint64(i), nodes, states); err != nil { panic(fmt.Errorf("failed to update state changes, err: %w", err)) } @@ -134,6 +153,14 @@ func newTester(t *testing.T, historyLimit uint64) *tester { return obj } +func (t *tester) accountPreimage(hash common.Hash) common.Address { + return common.BytesToAddress(t.preimages[hash]) +} + +func (t *tester) hashPreimage(hash common.Hash) common.Hash { + return common.BytesToHash(t.preimages[hash]) +} + func (t *tester) release() { t.db.Close() t.db.diskdb.Close() @@ -141,7 +168,7 @@ func (t *tester) release() { func (t *tester) randAccount() (common.Address, []byte) { for addrHash, account := range t.accounts { - return t.preimages[addrHash], account + return t.accountPreimage(addrHash), account } return common.Address{}, nil } @@ -154,7 +181,9 @@ func (t *tester) generateStorage(ctx *genctx, addr common.Address) common.Hash { ) for i := 0; i < 10; i++ { v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32))) - hash := testrand.Hash() + key := testrand.Bytes(32) + hash := crypto.Keccak256Hash(key) + t.preimages[hash] = key storage[hash] = v origin[hash] = nil @@ -183,7 +212,9 @@ func (t *tester) mutateStorage(ctx *genctx, addr common.Address, root common.Has } for i := 0; i < 3; i++ { v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32))) - hash := testrand.Hash() + key := testrand.Bytes(32) + hash := crypto.Keccak256Hash(key) + t.preimages[hash] = key storage[hash] = v origin[hash] = nil @@ -216,7 +247,7 @@ func (t *tester) clearStorage(ctx *genctx, addr common.Address, root common.Hash return root } -func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNodeSet, *StateSetWithOrigin) { +func (t *tester) generate(parent common.Hash, rawStorageKey bool) (common.Hash, *trienode.MergedNodeSet, *StateSetWithOrigin) { var ( ctx = newCtx(parent) dirties = make(map[common.Hash]struct{}) @@ -232,9 +263,12 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode // account creation addr := testrand.Address() addrHash := crypto.Keccak256Hash(addr.Bytes()) + + // short circuit if the account was already existent if _, ok := t.accounts[addrHash]; ok { continue } + // short circuit if the account has been modified within the same transition if _, ok := dirties[addrHash]; ok { continue } @@ -243,7 +277,7 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode root := t.generateStorage(ctx, addr) ctx.accounts[addrHash] = types.SlimAccountRLP(generateAccount(root)) ctx.accountOrigin[addr] = nil - t.preimages[addrHash] = addr + t.preimages[addrHash] = addr.Bytes() case modifyAccountOp: // account mutation @@ -252,6 +286,8 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode continue } addrHash := crypto.Keccak256Hash(addr.Bytes()) + + // short circuit if the account has been modified within the same transition if _, ok := dirties[addrHash]; ok { continue } @@ -271,6 +307,8 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode continue } addrHash := crypto.Keccak256Hash(addr.Bytes()) + + // short circuit if the account has been modified within the same transition if _, ok := dirties[addrHash]; ok { continue } @@ -314,7 +352,8 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode delete(t.storages, addrHash) } } - return root, ctx.nodes, NewStateSetWithOrigin(ctx.accounts, ctx.storages, ctx.accountOrigin, ctx.storageOrigin) + storageOrigin := ctx.storageOriginSet(rawStorageKey, t) + return root, ctx.nodes, NewStateSetWithOrigin(ctx.accounts, ctx.storages, ctx.accountOrigin, storageOrigin, rawStorageKey) } // lastHash returns the latest root hash, or empty if nothing is cached. @@ -409,7 +448,7 @@ func TestDatabaseRollback(t *testing.T) { }() // Verify state histories - tester := newTester(t, 0) + tester := newTester(t, 0, false) defer tester.release() if err := tester.verifyHistory(); err != nil { @@ -443,7 +482,7 @@ func TestDatabaseRecoverable(t *testing.T) { }() var ( - tester = newTester(t, 0) + tester = newTester(t, 0, false) index = tester.bottomIndex() ) defer tester.release() @@ -487,7 +526,7 @@ func TestDisable(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0) + tester := newTester(t, 0, false) defer tester.release() stored := crypto.Keccak256Hash(rawdb.ReadAccountTrieNode(tester.db.diskdb, nil)) @@ -529,7 +568,7 @@ func TestCommit(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0) + tester := newTester(t, 0, false) defer tester.release() if err := tester.db.Commit(tester.lastHash(), false); err != nil { @@ -559,7 +598,7 @@ func TestJournal(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0) + tester := newTester(t, 0, false) defer tester.release() if err := tester.db.Journal(tester.lastHash()); err != nil { @@ -589,7 +628,7 @@ func TestCorruptedJournal(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0) + tester := newTester(t, 0, false) defer tester.release() if err := tester.db.Journal(tester.lastHash()); err != nil { @@ -637,7 +676,7 @@ func TestTailTruncateHistory(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 10) + tester := newTester(t, 10, false) defer tester.release() tester.db.Close() diff --git a/triedb/pathdb/difflayer_test.go b/triedb/pathdb/difflayer_test.go index 7176d9964d..83ed833486 100644 --- a/triedb/pathdb/difflayer_test.go +++ b/triedb/pathdb/difflayer_test.go @@ -76,7 +76,7 @@ func benchmarkSearch(b *testing.B, depth int, total int) { nblob = common.CopyBytes(blob) } } - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil)) + return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil, false)) } var layer layer layer = emptyLayer() @@ -118,7 +118,7 @@ func BenchmarkPersist(b *testing.B) { ) nodes[common.Hash{}][string(path)] = node } - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil)) + return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil, false)) } for i := 0; i < b.N; i++ { b.StopTimer() @@ -156,7 +156,7 @@ func BenchmarkJournal(b *testing.B) { ) nodes[common.Hash{}][string(path)] = node } - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil)) + return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil, false)) } var layer layer layer = emptyLayer() diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index 003431b19b..5e678dbdee 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -316,7 +316,7 @@ func (dl *diskLayer) revert(h *history) (*diskLayer, error) { // 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 := apply(dl.db, h.meta.parent, h.meta.root, h.accounts, h.storages) + nodes, err := apply(dl.db, h.meta.parent, h.meta.root, h.meta.version != stateHistoryV0, h.accounts, h.storages) if err != nil { return nil, err } diff --git a/triedb/pathdb/execute.go b/triedb/pathdb/execute.go index e24d0710f3..80cecb82e7 100644 --- a/triedb/pathdb/execute.go +++ b/triedb/pathdb/execute.go @@ -30,11 +30,12 @@ import ( // 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 + prevRoot common.Hash + postRoot common.Hash + accounts map[common.Address][]byte + storages map[common.Address]map[common.Hash][]byte + nodes *trienode.MergedNodeSet + rawStorageKey bool // TODO (rjl493456442) abstract out the state hasher // for supporting verkle tree. @@ -43,18 +44,19 @@ type context struct { // apply processes the given state diffs, updates the corresponding post-state // and returns the trie nodes that have been modified. -func apply(db database.NodeDatabase, 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) { +func apply(db database.NodeDatabase, prevRoot common.Hash, postRoot common.Hash, rawStorageKey bool, 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(), + prevRoot: prevRoot, + postRoot: postRoot, + accounts: accounts, + storages: storages, + accountTrie: tr, + rawStorageKey: rawStorageKey, + nodes: trienode.NewMergedNodeSet(), } for addr, account := range accounts { var err error @@ -109,11 +111,15 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) return err } for key, val := range ctx.storages[addr] { + tkey := key + if ctx.rawStorageKey { + tkey = h.hash(key.Bytes()) + } var err error if len(val) == 0 { - err = st.Delete(key.Bytes()) + err = st.Delete(tkey.Bytes()) } else { - err = st.Update(key.Bytes(), val) + err = st.Update(tkey.Bytes(), val) } if err != nil { return err @@ -166,7 +172,11 @@ func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) if len(val) != 0 { return errors.New("expect storage deletion") } - if err := st.Delete(key.Bytes()); err != nil { + tkey := key + if ctx.rawStorageKey { + tkey = h.hash(key.Bytes()) + } + if err := st.Delete(tkey.Bytes()); err != nil { return err } } diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index e1cd981153..9fb7d9e153 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -68,7 +68,8 @@ const ( slotIndexSize = common.HashLength + 5 // The length of encoded slot index historyMetaSize = 9 + 2*common.HashLength // The length of encoded history meta - stateHistoryVersion = uint8(0) // initial version of state history structure. + stateHistoryV0 = uint8(0) // initial version of state history structure + stateHistoryV1 = uint8(1) // use the storage slot raw key as the identifier instead of the key hash ) // Each state history entry is consisted of five elements: @@ -169,15 +170,18 @@ func (i *accountIndex) decode(blob []byte) { // slotIndex describes the metadata belonging to a storage slot. type slotIndex struct { - hash common.Hash // The hash of slot key - length uint8 // The length of storage slot, up to 32 bytes defined in protocol - offset uint32 // The offset of item in storage slot data table + // the identifier of the storage slot. Specifically + // in v0, it's the hash of the raw storage slot key (32 bytes); + // in v1, it's the raw storage slot key (32 bytes); + id common.Hash + length uint8 // The length of storage slot, up to 32 bytes defined in protocol + offset uint32 // The offset of item in storage slot data table } // encode packs slot index into byte stream. func (i *slotIndex) encode() []byte { var buf [slotIndexSize]byte - copy(buf[:common.HashLength], i.hash.Bytes()) + copy(buf[:common.HashLength], i.id.Bytes()) buf[common.HashLength] = i.length binary.BigEndian.PutUint32(buf[common.HashLength+1:], i.offset) return buf[:] @@ -185,7 +189,7 @@ func (i *slotIndex) encode() []byte { // decode unpack slot index from the byte stream. func (i *slotIndex) decode(blob []byte) { - i.hash = common.BytesToHash(blob[:common.HashLength]) + i.id = common.BytesToHash(blob[:common.HashLength]) i.length = blob[common.HashLength] i.offset = binary.BigEndian.Uint32(blob[common.HashLength+1:]) } @@ -214,7 +218,7 @@ func (m *meta) decode(blob []byte) error { return errors.New("no version tag") } switch blob[0] { - case stateHistoryVersion: + case stateHistoryV0, stateHistoryV1: if len(blob) != historyMetaSize { return fmt.Errorf("invalid state history meta, len: %d", len(blob)) } @@ -242,7 +246,7 @@ type history struct { } // newHistory constructs the state history object with provided state change set. -func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte) *history { +func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *history { var ( accountList = maps.Keys(accounts) storageList = make(map[common.Address][]common.Hash) @@ -254,9 +258,13 @@ func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map slices.SortFunc(slist, common.Hash.Cmp) storageList[addr] = slist } + version := stateHistoryV0 + if rawStorageKey { + version = stateHistoryV1 + } return &history{ meta: &meta{ - version: stateHistoryVersion, + version: version, parent: parent, root: root, block: block, @@ -289,7 +297,7 @@ func (h *history) encode() ([]byte, []byte, []byte, []byte) { // Encode storage slots in order for _, slotHash := range h.storageList[addr] { sIndex := slotIndex{ - hash: slotHash, + id: slotHash, length: uint8(len(slots[slotHash])), offset: uint32(len(storageData)), } @@ -377,7 +385,7 @@ func (r *decoder) readAccount(pos int) (accountIndex, []byte, error) { // readStorage parses the storage slots from the byte stream with specified account. func (r *decoder) readStorage(accIndex accountIndex) ([]common.Hash, map[common.Hash][]byte, error) { var ( - last common.Hash + last *common.Hash count = int(accIndex.storageSlots) list = make([]common.Hash, 0, count) storage = make(map[common.Hash][]byte, count) @@ -402,8 +410,10 @@ func (r *decoder) readStorage(accIndex accountIndex) ([]common.Hash, map[common. } index.decode(r.storageIndexes[start:end]) - if bytes.Compare(last.Bytes(), index.hash.Bytes()) >= 0 { - return nil, nil, errors.New("storage slot is not in order") + if last != nil { + if bytes.Compare(last.Bytes(), index.id.Bytes()) >= 0 { + return nil, nil, fmt.Errorf("storage slot is not in order, last: %x, current: %x", *last, index.id) + } } if index.offset != r.lastSlotDataRead { return nil, nil, errors.New("storage data buffer is gapped") @@ -412,10 +422,10 @@ func (r *decoder) readStorage(accIndex accountIndex) ([]common.Hash, map[common. if uint32(len(r.storageData)) < sEnd { return nil, nil, errors.New("storage data buffer is corrupted") } - storage[index.hash] = r.storageData[r.lastSlotDataRead:sEnd] - list = append(list, index.hash) + storage[index.id] = r.storageData[r.lastSlotDataRead:sEnd] + list = append(list, index.id) - last = index.hash + last = &index.id r.lastSlotIndexRead = end r.lastSlotDataRead = sEnd } @@ -498,7 +508,7 @@ func writeHistory(writer ethdb.AncientWriter, dl *diffLayer) error { } var ( start = time.Now() - history = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states.accountOrigin, dl.states.storageOrigin) + history = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states.accountOrigin, dl.states.storageOrigin, dl.states.rawStorageKey) ) accountData, storageData, accountIndex, storageIndex := history.encode() dataSize := common.StorageSize(len(accountData) + len(storageData)) diff --git a/triedb/pathdb/history_inspect.go b/triedb/pathdb/history_inspect.go index 240474da37..7dbe5959dc 100644 --- a/triedb/pathdb/history_inspect.go +++ b/triedb/pathdb/history_inspect.go @@ -21,6 +21,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" ) @@ -109,12 +110,17 @@ func accountHistory(freezer ethdb.AncientReader, address common.Address, start, // 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) { + slotHash := crypto.Keccak256Hash(slot.Bytes()) return inspectHistory(freezer, start, end, func(h *history, stats *HistoryStats) { slots, exists := h.storages[address] if !exists { return } - blob, exists := slots[slot] + key := slotHash + if h.meta.version != stateHistoryV0 { + key = slot + } + blob, exists := slots[key] if !exists { return } diff --git a/triedb/pathdb/history_test.go b/triedb/pathdb/history_test.go index d430706dee..953f023530 100644 --- a/triedb/pathdb/history_test.go +++ b/triedb/pathdb/history_test.go @@ -49,9 +49,9 @@ func randomStateSet(n int) (map[common.Address][]byte, map[common.Address]map[co return accounts, storages } -func makeHistory() *history { +func makeHistory(rawStorageKey bool) *history { accounts, storages := randomStateSet(3) - return newHistory(testrand.Hash(), types.EmptyRootHash, 0, accounts, storages) + return newHistory(testrand.Hash(), types.EmptyRootHash, 0, accounts, storages, rawStorageKey) } func makeHistories(n int) []*history { @@ -62,7 +62,7 @@ func makeHistories(n int) []*history { for i := 0; i < n; i++ { root := testrand.Hash() accounts, storages := randomStateSet(3) - h := newHistory(root, parent, uint64(i), accounts, storages) + h := newHistory(root, parent, uint64(i), accounts, storages, false) parent = root result = append(result, h) } @@ -70,10 +70,15 @@ func makeHistories(n int) []*history { } func TestEncodeDecodeHistory(t *testing.T) { + testEncodeDecodeHistory(t, false) + testEncodeDecodeHistory(t, true) +} + +func testEncodeDecodeHistory(t *testing.T, rawStorageKey bool) { var ( m meta dec history - obj = makeHistory() + obj = makeHistory(rawStorageKey) ) // check if meta data can be correctly encode/decode blob := obj.meta.encode() diff --git a/triedb/pathdb/iterator_test.go b/triedb/pathdb/iterator_test.go index 48b5870b5b..05a166d1b6 100644 --- a/triedb/pathdb/iterator_test.go +++ b/triedb/pathdb/iterator_test.go @@ -131,7 +131,7 @@ func TestAccountIteratorBasics(t *testing.T) { storage[hash] = accStorage } } - states := newStates(accounts, storage) + states := newStates(accounts, storage, false) it := newDiffAccountIterator(common.Hash{}, states, nil) verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator @@ -171,7 +171,7 @@ func TestStorageIteratorBasics(t *testing.T) { storage[hash] = accStorage nilStorage[hash] = nilstorage } - states := newStates(accounts, storage) + states := newStates(accounts, storage, false) for account := range accounts { it := newDiffStorageIterator(account, common.Hash{}, states, nil) verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator @@ -267,13 +267,13 @@ func TestAccountIteratorTraversal(t *testing.T) { // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 0, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil, false)) db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 0, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil, false)) db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 0, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil, false)) // Verify the single and multi-layer iterators head := db.tree.get(common.HexToHash("0x04")) @@ -314,13 +314,13 @@ func TestStorageIteratorTraversal(t *testing.T) { // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 0, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil), nil, nil, false)) db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 0, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04", "0x05", "0x06"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04", "0x05", "0x06"}}, nil), nil, nil, false)) db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 0, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil), nil, nil, false)) // Verify the single and multi-layer iterators head := db.tree.get(common.HexToHash("0x04")) @@ -395,14 +395,14 @@ func TestAccountIteratorTraversalValues(t *testing.T) { } } // Assemble a stack of snapshots from the account layers - db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(a, nil, nil, nil)) - db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(b, nil, nil, nil)) - db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(c, nil, nil, nil)) - db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(d, nil, nil, nil)) - db.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), 6, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(e, nil, nil, nil)) - db.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), 7, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(f, nil, nil, nil)) - db.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), 8, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(g, nil, nil, nil)) - db.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), 9, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(h, nil, nil, nil)) + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(a, nil, nil, nil, false)) + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(b, nil, nil, nil, false)) + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(c, nil, nil, nil, false)) + db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(d, nil, nil, nil, false)) + db.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), 6, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(e, nil, nil, nil, false)) + db.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), 7, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(f, nil, nil, nil, false)) + db.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), 8, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(g, nil, nil, nil, false)) + db.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), 9, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(h, nil, nil, nil, false)) // binaryIterator r, _ := db.StateReader(common.HexToHash("0x09")) @@ -504,14 +504,14 @@ func TestStorageIteratorTraversalValues(t *testing.T) { } } // Assemble a stack of snapshots from the account layers - db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(a), nil, nil)) - db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(b), nil, nil)) - db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(c), nil, nil)) - db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(d), nil, nil)) - db.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), 6, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(e), nil, nil)) - db.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), 7, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(f), nil, nil)) - db.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), 8, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(g), nil, nil)) - db.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), 9, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(h), nil, nil)) + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(a), nil, nil, false)) + db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(b), nil, nil, false)) + db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(c), nil, nil, false)) + db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(d), nil, nil, false)) + db.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), 6, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(e), nil, nil, false)) + db.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), 7, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(f), nil, nil, false)) + db.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), 8, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(g), nil, nil, false)) + db.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), 9, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa"), wrapStorage(h), nil, nil, false)) // binaryIterator r, _ := db.StateReader(common.HexToHash("0x09")) @@ -588,7 +588,7 @@ func TestAccountIteratorLargeTraversal(t *testing.T) { parent = common.HexToHash(fmt.Sprintf("0x%02x", i)) } db.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), parent, uint64(i), trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(makeAccounts(200), nil, nil, nil)) + NewStateSetWithOrigin(makeAccounts(200), nil, nil, nil, false)) } // Iterate the entire stack and ensure everything is hit only once head := db.tree.get(common.HexToHash("0x80")) @@ -626,13 +626,13 @@ func TestAccountIteratorFlattening(t *testing.T) { // Create a stack of diffs on top db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil, false)) db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil, false)) db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil, false)) // Create a binary iterator and flatten the data from underneath it head := db.tree.get(common.HexToHash("0x04")) @@ -658,13 +658,13 @@ func TestAccountIteratorSeek(t *testing.T) { // db.WaitGeneration() db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil, false)) db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xbb", "0xdd", "0xf0"), nil, nil, nil, false)) db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xcc", "0xf0", "0xff"), nil, nil, nil, false)) // Account set is now // 02: aa, ee, f0, ff @@ -731,13 +731,13 @@ func testStorageIteratorSeek(t *testing.T, newIterator func(db *Database, root, // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil), nil, nil, false)) db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x05", "0x06"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x05", "0x06"}}, nil), nil, nil, false)) db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x05", "0x08"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x05", "0x08"}}, nil), nil, nil, false)) // Account set is now // 02: 01, 03, 05 @@ -803,16 +803,16 @@ func testAccountIteratorDeletions(t *testing.T, newIterator func(db *Database, r // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0x11", "0x22", "0x33"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0x11", "0x22", "0x33"), nil, nil, nil, false)) deleted := common.HexToHash("0x22") accounts := randomAccountSet("0x11", "0x33") accounts[deleted] = nil db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(accounts, nil, nil, nil)) + NewStateSetWithOrigin(accounts, nil, nil, nil, false)) db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0x33", "0x44", "0x55"), nil, nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0x33", "0x44", "0x55"), nil, nil, nil, false)) // The output should be 11,33,44,55 it := newIterator(db, common.HexToHash("0x04"), common.Hash{}) @@ -843,10 +843,10 @@ func TestStorageIteratorDeletions(t *testing.T) { // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil), nil, nil, false)) db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x04", "0x06"}}, [][]string{{"0x01", "0x03"}}), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x04", "0x06"}}, [][]string{{"0x01", "0x03"}}), nil, nil, false)) // The output should be 02,04,05,06 it, _ := db.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.Hash{}) @@ -863,7 +863,7 @@ func TestStorageIteratorDeletions(t *testing.T) { common.HexToHash("0xaa"): nil, } db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(accounts, randomStorageSet([]string{"0xaa"}, nil, [][]string{{"0x02", "0x04", "0x05", "0x06"}}), nil, nil)) + NewStateSetWithOrigin(accounts, randomStorageSet([]string{"0xaa"}, nil, [][]string{{"0x02", "0x04", "0x05", "0x06"}}), nil, nil, false)) it, _ = db.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) verifyIterator(t, 0, it, verifyStorage) @@ -871,7 +871,7 @@ func TestStorageIteratorDeletions(t *testing.T) { // Re-insert the slots of the same account db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 4, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x07", "0x08", "0x09"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x07", "0x08", "0x09"}}, nil), nil, nil, false)) // The output should be 07,08,09 it, _ = db.StorageIterator(common.HexToHash("0x05"), common.HexToHash("0xaa"), common.Hash{}) @@ -880,7 +880,7 @@ func TestStorageIteratorDeletions(t *testing.T) { // Destruct the whole storage but re-create the account in the same layer db.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), 5, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, [][]string{{"0x07", "0x08", "0x09"}}), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, [][]string{{"0x07", "0x08", "0x09"}}), nil, nil, false)) it, _ = db.StorageIterator(common.HexToHash("0x06"), common.HexToHash("0xaa"), common.Hash{}) verifyIterator(t, 2, it, verifyStorage) // The output should be 11,12 @@ -911,19 +911,19 @@ func testStaleIterator(t *testing.T, newIter func(db *Database, hash common.Hash // [02 (disk), 03] db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01"}}, nil), nil, nil, false)) db.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 2, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02"}}, nil), nil, nil, false)) db.tree.cap(common.HexToHash("0x03"), 1) // [02 (disk), 03, 04] db.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 3, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x03"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x03"}}, nil), nil, nil, false)) iter := newIter(db, common.HexToHash("0x04")) // [04 (disk), 05] db.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), 3, trienode.NewMergedNodeSet(), - NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04"}}, nil), nil, nil)) + NewStateSetWithOrigin(randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04"}}, nil), nil, nil, false)) db.tree.cap(common.HexToHash("0x05"), 1) // Iterator can't finish the traversal as the layer 02 has becoming stale. @@ -969,7 +969,7 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) { if i == 1 { parent = common.HexToHash(fmt.Sprintf("0x%02x", i)) } - db.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), parent, uint64(i), trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(200), nil, nil, nil)) + db.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), parent, uint64(i), trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(200), nil, nil, nil, false)) } // We call this once before the benchmark, so the creation of // sorted accountlists are not included in the results. @@ -1059,9 +1059,9 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { db := New(rawdb.NewMemoryDatabase(), config, false) // db.WaitGeneration() - db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(2000), nil, nil, nil)) + db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(2000), nil, nil, nil, false)) for i := 2; i <= 100; i++ { - db.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), uint64(i), trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(20), nil, nil, nil)) + db.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), uint64(i), trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(20), nil, nil, nil, false)) } // We call this once before the benchmark, so the creation of // sorted accountlists are not included in the results. diff --git a/triedb/pathdb/journal.go b/triedb/pathdb/journal.go index 267d675bc2..79a7a22e0b 100644 --- a/triedb/pathdb/journal.go +++ b/triedb/pathdb/journal.go @@ -45,7 +45,8 @@ var ( // - Version 0: initial version // - Version 1: storage.Incomplete field is removed // - Version 2: add post-modification state values -const journalVersion uint64 = 2 +// - Version 3: a flag has been added to indicate whether the storage slot key is the raw key or a hash +const journalVersion uint64 = 3 // loadJournal tries to parse the layer journal from the disk. func (db *Database) loadJournal(diskRoot common.Hash) (layer, error) { diff --git a/triedb/pathdb/states.go b/triedb/pathdb/states.go index 81d34da5df..969782e3c4 100644 --- a/triedb/pathdb/states.go +++ b/triedb/pathdb/states.go @@ -65,6 +65,8 @@ type stateSet struct { accountListSorted []common.Hash // List of account for iteration. If it exists, it's sorted, otherwise it's nil storageListSorted map[common.Hash][]common.Hash // List of storage slots for iterated retrievals, one per account. Any existing lists are sorted if non-nil + rawStorageKey bool // indicates whether the storage set uses the raw slot key or the hash + // Lock for guarding the two lists above. These lists might be accessed // concurrently and lock protection is essential to avoid concurrent // slice or map read/write. @@ -72,7 +74,7 @@ type stateSet struct { } // newStates constructs the state set with the provided account and storage data. -func newStates(accounts map[common.Hash][]byte, storages map[common.Hash]map[common.Hash][]byte) *stateSet { +func newStates(accounts map[common.Hash][]byte, storages map[common.Hash]map[common.Hash][]byte, rawStorageKey bool) *stateSet { // Don't panic for the lazy callers, initialize the nil maps instead. if accounts == nil { accounts = make(map[common.Hash][]byte) @@ -83,6 +85,7 @@ func newStates(accounts map[common.Hash][]byte, storages map[common.Hash]map[com s := &stateSet{ accountData: accounts, storageData: storages, + rawStorageKey: rawStorageKey, storageListSorted: make(map[common.Hash][]common.Hash), } s.size = s.check() @@ -330,6 +333,9 @@ func (s *stateSet) updateSize(delta int) { // encode serializes the content of state set into the provided writer. func (s *stateSet) encode(w io.Writer) error { // Encode accounts + if err := rlp.Encode(w, s.rawStorageKey); err != nil { + return err + } type accounts struct { AddrHashes []common.Hash Accounts [][]byte @@ -367,6 +373,9 @@ func (s *stateSet) encode(w io.Writer) error { // decode deserializes the content from the rlp stream into the state set. func (s *stateSet) decode(r *rlp.Stream) error { + if err := r.Decode(&s.rawStorageKey); err != nil { + return fmt.Errorf("load diff raw storage key flag: %v", err) + } type accounts struct { AddrHashes []common.Hash Accounts [][]byte @@ -435,23 +444,23 @@ func (s *stateSet) dbsize() int { type StateSetWithOrigin struct { *stateSet - // AccountOrigin represents the account data before the state transition, + // accountOrigin represents the account data before the state transition, // corresponding to both the accountData and destructSet. It's keyed by the // account address. The nil value means the account was not present before. accountOrigin map[common.Address][]byte - // StorageOrigin represents the storage data before the state transition, + // storageOrigin represents the storage data before the state transition, // corresponding to storageData and deleted slots of destructSet. It's keyed // by the account address and slot key hash. The nil value means the slot was // not present. storageOrigin map[common.Address]map[common.Hash][]byte - // Memory size of the state data (accountOrigin and storageOrigin) + // memory size of the state data (accountOrigin and storageOrigin) size uint64 } // NewStateSetWithOrigin constructs the state set with the provided data. -func NewStateSetWithOrigin(accounts map[common.Hash][]byte, storages map[common.Hash]map[common.Hash][]byte, accountOrigin map[common.Address][]byte, storageOrigin map[common.Address]map[common.Hash][]byte) *StateSetWithOrigin { +func NewStateSetWithOrigin(accounts map[common.Hash][]byte, storages map[common.Hash]map[common.Hash][]byte, accountOrigin map[common.Address][]byte, storageOrigin map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *StateSetWithOrigin { // Don't panic for the lazy callers, initialize the nil maps instead. if accountOrigin == nil { accountOrigin = make(map[common.Address][]byte) @@ -471,7 +480,7 @@ func NewStateSetWithOrigin(accounts map[common.Hash][]byte, storages map[common. size += 2*common.HashLength + len(data) } } - set := newStates(accounts, storages) + set := newStates(accounts, storages, rawStorageKey) return &StateSetWithOrigin{ stateSet: set, accountOrigin: accountOrigin, diff --git a/triedb/pathdb/states_test.go b/triedb/pathdb/states_test.go index f097e90e81..30eb6ad6c8 100644 --- a/triedb/pathdb/states_test.go +++ b/triedb/pathdb/states_test.go @@ -44,6 +44,7 @@ func TestStatesMerge(t *testing.T) { common.Hash{0x1}: {0x10}, }, }, + false, ) b := newStates( map[common.Hash][]byte{ @@ -64,6 +65,7 @@ func TestStatesMerge(t *testing.T) { common.Hash{0x1}: nil, // delete slot }, }, + false, ) a.merge(b) @@ -132,6 +134,7 @@ func TestStatesRevert(t *testing.T) { common.Hash{0x1}: {0x10}, }, }, + false, ) b := newStates( map[common.Hash][]byte{ @@ -152,6 +155,7 @@ func TestStatesRevert(t *testing.T) { common.Hash{0x1}: nil, }, }, + false, ) a.merge(b) a.revertTo( @@ -224,12 +228,13 @@ func TestStatesRevert(t *testing.T) { // before and was created during transition w, reverting w will retain an x=nil // entry in the set. func TestStateRevertAccountNullMarker(t *testing.T) { - a := newStates(nil, nil) // empty initial state + a := newStates(nil, nil, false) // empty initial state b := newStates( map[common.Hash][]byte{ {0xa}: {0xa}, }, nil, + false, ) a.merge(b) // create account 0xa a.revertTo( @@ -254,7 +259,7 @@ func TestStateRevertAccountNullMarker(t *testing.T) { func TestStateRevertStorageNullMarker(t *testing.T) { a := newStates(map[common.Hash][]byte{ {0xa}: {0xa}, - }, nil) // initial state with account 0xa + }, nil, false) // initial state with account 0xa b := newStates( nil, @@ -263,6 +268,7 @@ func TestStateRevertStorageNullMarker(t *testing.T) { common.Hash{0x1}: {0x1}, }, }, + false, ) a.merge(b) // create slot 0x1 a.revertTo( @@ -284,6 +290,11 @@ func TestStateRevertStorageNullMarker(t *testing.T) { } func TestStatesEncode(t *testing.T) { + testStatesEncode(t, false) + testStatesEncode(t, true) +} + +func testStatesEncode(t *testing.T, rawStorageKey bool) { s := newStates( map[common.Hash][]byte{ {0x1}: {0x1}, @@ -293,6 +304,7 @@ func TestStatesEncode(t *testing.T) { common.Hash{0x1}: {0x1}, }, }, + rawStorageKey, ) buf := bytes.NewBuffer(nil) if err := s.encode(buf); err != nil { @@ -308,9 +320,17 @@ func TestStatesEncode(t *testing.T) { if !reflect.DeepEqual(s.storageData, dec.storageData) { t.Fatal("Unexpected storage data") } + if s.rawStorageKey != dec.rawStorageKey { + t.Fatal("Unexpected rawStorageKey flag") + } } func TestStateWithOriginEncode(t *testing.T) { + testStateWithOriginEncode(t, false) + testStateWithOriginEncode(t, true) +} + +func testStateWithOriginEncode(t *testing.T, rawStorageKey bool) { s := NewStateSetWithOrigin( map[common.Hash][]byte{ {0x1}: {0x1}, @@ -328,6 +348,7 @@ func TestStateWithOriginEncode(t *testing.T) { common.Hash{0x1}: {0x1}, }, }, + rawStorageKey, ) buf := bytes.NewBuffer(nil) if err := s.encode(buf); err != nil { @@ -349,6 +370,9 @@ func TestStateWithOriginEncode(t *testing.T) { if !reflect.DeepEqual(s.storageOrigin, dec.storageOrigin) { t.Fatal("Unexpected storage origin data") } + if s.rawStorageKey != dec.rawStorageKey { + t.Fatal("Unexpected rawStorageKey flag") + } } func TestStateSizeTracking(t *testing.T) { @@ -375,6 +399,7 @@ func TestStateSizeTracking(t *testing.T) { common.Hash{0x1}: {0x10}, // 2*common.HashLength+1 }, }, + false, ) if a.size != uint64(expSizeA) { t.Fatalf("Unexpected size, want: %d, got: %d", expSizeA, a.size) @@ -406,6 +431,7 @@ func TestStateSizeTracking(t *testing.T) { common.Hash{0x3}: nil, // 2*common.HashLength, slot deletion }, }, + false, ) if b.size != uint64(expSizeB) { t.Fatalf("Unexpected size, want: %d, got: %d", expSizeB, b.size) diff --git a/triedb/states.go b/triedb/states.go index fa432e0704..9fabdb088d 100644 --- a/triedb/states.go +++ b/triedb/states.go @@ -27,6 +27,7 @@ type StateSet struct { AccountsOrigin map[common.Address][]byte // Original values of mutated accounts in 'slim RLP' encoding Storages map[common.Hash]map[common.Hash][]byte // Mutated storage slots in 'prefix-zero-trimmed' RLP format StoragesOrigin map[common.Address]map[common.Hash][]byte // Original values of mutated storage slots in 'prefix-zero-trimmed' RLP format + RawStorageKey bool // Flag whether the storage set uses the raw slot key or the hash } // NewStateSet initializes an empty state set. @@ -45,5 +46,5 @@ func (set *StateSet) internal() *pathdb.StateSetWithOrigin { if set == nil { return nil } - return pathdb.NewStateSetWithOrigin(set.Accounts, set.Storages, set.AccountsOrigin, set.StoragesOrigin) + return pathdb.NewStateSetWithOrigin(set.Accounts, set.Storages, set.AccountsOrigin, set.StoragesOrigin, set.RawStorageKey) } From ea31bd9faf733277def247d0f19184c9fc844483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 17 Jan 2025 16:54:19 +0100 Subject: [PATCH 052/940] ethdb/memorydb: faster DeleteRange (#31038) This PR replaces the iterator based DeleteRange implementation of memorydb with a simpler and much faster loop that directly deletes keys in the order of iteration instead of unnecessarily collecting keys in memory and sorting them. --------- Co-authored-by: Martin HS --- ethdb/memorydb/memorydb.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ethdb/memorydb/memorydb.go b/ethdb/memorydb/memorydb.go index c6fba39cfd..a797275e92 100644 --- a/ethdb/memorydb/memorydb.go +++ b/ethdb/memorydb/memorydb.go @@ -18,7 +18,6 @@ package memorydb import ( - "bytes" "errors" "sort" "strings" @@ -125,12 +124,15 @@ func (db *Database) Delete(key []byte) error { // DeleteRange deletes all of the keys (and values) in the range [start,end) // (inclusive on start, exclusive on end). func (db *Database) DeleteRange(start, end []byte) error { - it := db.NewIterator(nil, start) - defer it.Release() + db.lock.Lock() + defer db.lock.Unlock() + if db.db == nil { + return errMemorydbClosed + } - for it.Next() && bytes.Compare(end, it.Key()) > 0 { - if err := db.Delete(it.Key()); err != nil { - return err + for key := range db.db { + if key >= string(start) && key < string(end) { + delete(db.db, key) } } return nil From cc814d6b7be48d193d3ecfbb45769ce587efc508 Mon Sep 17 00:00:00 2001 From: Cedrick Date: Mon, 20 Jan 2025 08:39:55 +0100 Subject: [PATCH 053/940] cmd/abigen: require either `--abi` or `--combined-json` (#31045) This PR addresses issue #30768 , which highlights that running cmd/abigen/abigen --pkg my_package example.json (erroneously omitting the --abi flag) generates an empty binding, when it should fail explicitly. --------- Co-authored-by: jwasinger --- cmd/abigen/main.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 0149dec527..8ee3130b5b 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -98,6 +98,9 @@ func abigen(c *cli.Context) error { if c.String(pkgFlag.Name) == "" { utils.Fatalf("No destination package specified (--pkg)") } + if c.String(abiFlag.Name) == "" && c.String(jsonFlag.Name) == "" { + utils.Fatalf("Either contract ABI source (--abi) or combined-json (--combined-json) are required") + } var lang bind.Lang switch c.String(langFlag.Name) { case "go": From 17199daa76590b581dfcc28d500fcbb6105c7e69 Mon Sep 17 00:00:00 2001 From: Shude Li Date: Mon, 20 Jan 2025 17:12:36 +0800 Subject: [PATCH 054/940] core/types: correct chainId check for pragueSigner (#31032) Use zero value check for the pragueSigner This aligns with cancunSigner and londonSigner as well. --- core/types/transaction_signing.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 4d70f37bd3..030fc472a0 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -219,7 +219,7 @@ func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big } // Check that chain ID of tx matches the signer. We also accept ID zero here, // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID != nil && txdata.ChainID.CmpBig(s.chainId) != 0 { + if txdata.ChainID.Sign() != 0 && txdata.ChainID.CmpBig(s.chainId) != 0 { return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) } R, S, _ = decodeSignature(sig) @@ -287,7 +287,7 @@ func (s cancunSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big } // Check that chain ID of tx matches the signer. We also accept ID zero here, // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID.Sign() != 0 && txdata.ChainID.ToBig().Cmp(s.chainId) != 0 { + if txdata.ChainID.Sign() != 0 && txdata.ChainID.CmpBig(s.chainId) != 0 { return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) } R, S, _ = decodeSignature(sig) From 448e16ad543e9b9be244b1bfdad3cdc009cbd6f0 Mon Sep 17 00:00:00 2001 From: levisyin Date: Tue, 21 Jan 2025 00:04:29 +0800 Subject: [PATCH 055/940] build: upgrade -dlgo version to Go 1.23.5 (#31037) --- build/checksums.txt | 98 ++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index b0b7a73a3b..7270492ec9 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,56 +5,56 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/ ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz -# version:golang 1.23.4 +# version:golang 1.23.5 # https://go.dev/dl/ -ad345ac421e90814293a9699cca19dd5238251c3f687980bbcae28495b263531 go1.23.4.src.tar.gz -459a09504f7ebf2cbcee6ac282c8f34f97651217b1feae64557dcdd392b9bb62 go1.23.4.aix-ppc64.tar.gz -0f4e569b2d38cb75cb2efcaf56beb42778ab5e46d89318fef39060fe36d7b9b7 go1.23.4.darwin-amd64.pkg -6700067389a53a1607d30aa8d6e01d198230397029faa0b109e89bc871ab5a0e go1.23.4.darwin-amd64.tar.gz -19c054eaf40c5fac65b027f7443c01382e493d3c8c42cf8b2504832ebddce037 go1.23.4.darwin-arm64.pkg -87d2bb0ad4fe24d2a0685a55df321e0efe4296419a9b3de03369dbe60b8acd3a go1.23.4.darwin-arm64.tar.gz -5e73dc89b44626677ec9d9aa4257d6d2ef1245502bc36a99385284910d0ade0a go1.23.4.dragonfly-amd64.tar.gz -8df26b1e71234756c1f0e82cfffba3f427c5a91a251844ada2c7694a6986c546 go1.23.4.freebsd-386.tar.gz -7de078d94d2af50ee9506ef7df85e4d12d4018b23e0b2cbcbc61d686f549b41a go1.23.4.freebsd-amd64.tar.gz -3f23e0a01cfe24e4160124cd7ab02bdd188264652074abdbce401c93f41e58a4 go1.23.4.freebsd-arm.tar.gz -986a20e7c94431f03b44b3c415abc698c7b4edc2ae8431f7ecae1c2429d4cfa2 go1.23.4.freebsd-arm64.tar.gz -25e39f005f977778ce963fc43089510fe7514f3cfc0358eab584de4ce9f181fb go1.23.4.freebsd-riscv64.tar.gz -7e1d52f93da68c3bab39e3d83f89944d7d151208e54fdc30b0eda2a3812661d7 go1.23.4.illumos-amd64.tar.gz -4a4a0e7587ef8c8a326439b957027f2791795e2d29d4ae3885b4091a48f843bc go1.23.4.linux-386.tar.gz -6924efde5de86fe277676e929dc9917d466efa02fb934197bc2eba35d5680971 go1.23.4.linux-amd64.tar.gz -16e5017863a7f6071363782b1b8042eb12c6ca4f4cd71528b2123f0a1275b13e go1.23.4.linux-arm64.tar.gz -1f1dda0dc7ce0b2295f57258ec5ef0803fd31b9ed0aa20e2e9222334e5755de1 go1.23.4.linux-armv6l.tar.gz -4f469179a335a1a7bb9f991ad0c567f3d3eeb9b412ecd192206ab5c3e1a52b5a go1.23.4.linux-loong64.tar.gz -86b68185bcc43ea07190e95137c3442f062acc7ae10c3f1cf900fbe23e07df24 go1.23.4.linux-mips.tar.gz -3a19245eec76533b3d01c90f3a40a38d63684028f0fd54d442dc9a9d03197891 go1.23.4.linux-mips64.tar.gz -b53a06fc8455f6a875329e8d2e24d39db298122c9cce6e948117022191f6c613 go1.23.4.linux-mips64le.tar.gz -66120a8105b8ba6559f4e6a13b1e39b433fb8032df9d1744e4486876fa1723ce go1.23.4.linux-mipsle.tar.gz -33be2bfb27f2821a65e9f6aba744c85ea7c5e233e16bac27bb3ec253bcd4e970 go1.23.4.linux-ppc64.tar.gz -65a303ef51e48ff77e004a6a5b4db6ce59495cd59c6af51b54bf4f786c01a1b9 go1.23.4.linux-ppc64le.tar.gz -7c40e9e0d722cef14ede765159ba297f4c6e3093bb106f10fbccf8564780049a go1.23.4.linux-riscv64.tar.gz -74aab82bf4eca7c26c830a5b0e2a31d193a4d5ba47045526b92473cc7188d7d7 go1.23.4.linux-s390x.tar.gz -dba009d8bf9928cb5a1e31fcbe0eb41335cce4fe63755d95cef6b5987df4ed5a go1.23.4.netbsd-386.tar.gz -54b081cc36355aa5ecb6db9544cf7e77366a7b08ce96cb98a45d043e393660c7 go1.23.4.netbsd-amd64.tar.gz -f05fec348c7c9f07e1ad4e436db4122e98de99ebcfbf6ac6176869785f334a02 go1.23.4.netbsd-arm.tar.gz -317878da2bface5a57a8eaf5c1fe2b40b1c82d8172a10453ad3eea36f6946bdb go1.23.4.netbsd-arm64.tar.gz -0d84350dfd72c505c6ad474e51676b04e95ffb748c614bd5bf8510026873059b go1.23.4.openbsd-386.tar.gz -cc62f5a14ea3d573d8edbce1833f70a8f99ca048a9db0fcc9e738fd48e950505 go1.23.4.openbsd-amd64.tar.gz -326aba6cf5bb9348fa3e41217abd2c84eac92608684e2fe8c5474fdab23a0db9 go1.23.4.openbsd-arm.tar.gz -51ea2a2588bf3da8e1476f3e2bd4d6724d74126e99f9c6ea9af4ebe389e64de6 go1.23.4.openbsd-arm64.tar.gz -44c5c82ab23e40225b2ba1e7d19150a5973ea58e93b4931e426e6e6f0d108872 go1.23.4.openbsd-ppc64.tar.gz -5fa31fc13d1e3c123a5e96ba38683fa2c947baed23ac9c7c341afcfe007c8993 go1.23.4.openbsd-riscv64.tar.gz -e5952fc93eeaa0094ef09a0e72a9f06f0621ce841a39f9637fb5b9062e77d67a go1.23.4.plan9-386.tar.gz -fb2a9ee3ae5a77e734862e257a9395b43e707ac45e060dfa84c5a40688e73170 go1.23.4.plan9-amd64.tar.gz -e1b95563b19fdebd6ea0d20c07641e69580976fa754e586c831ad7a3ae987140 go1.23.4.plan9-arm.tar.gz -088c282509fc9e1a8f29fc0dd16fe486854d05b8ceba08d077d17d11d6979a41 go1.23.4.solaris-amd64.tar.gz -e5865c1bfc3fee5d003819b2e2c800f598fe9994931bac63f573e8d05a10d91f go1.23.4.windows-386.msi -e544e0e356147ba998e267002bd0f2c4bf3370d495467a55baf2c63595a2026d go1.23.4.windows-386.zip -5f8cc5991eb8f4f96b6c611d839453cd11c9a2c3f23672a4188342c97ee159fa go1.23.4.windows-amd64.msi -16c59ac9196b63afb872ce9b47f945b9821a3e1542ec125f16f6085a1c0f3c39 go1.23.4.windows-amd64.zip -fc77c0531406d092c5356167e45c05a22d16bea84e3fa555e0f03af085c11763 go1.23.4.windows-arm.msi -1012cfd8ca7241c2beecb5c345dd61f01897c6f6baca80ea1bfed357035c868a go1.23.4.windows-arm.zip -8347c1aa4e1e67954d12830f88dbe44bd7ac0ec134bb472783dbfb5a3a8865d0 go1.23.4.windows-arm64.msi -db69cae5006753c785345c3215ad941f8b6224e2f81fec471c42d6857bee0e6f go1.23.4.windows-arm64.zip +a6f3f4bbd3e6bdd626f79b668f212fbb5649daf75084fb79b678a0ae4d97423b go1.23.5.src.tar.gz +8d8bc7d1b362dd91426da9352741db298ff73e3e0a3ccbe6f607f80ba17647a4 go1.23.5.aix-ppc64.tar.gz +d8b310b0b6bd6a630307579165cfac8a37571483c7d6804a10dd73bbefb0827f go1.23.5.darwin-amd64.tar.gz +d2b06bf0b8299e0187dfe2d8ad39bd3dd96a6d93fe4d1cfd42c7872452f4a0a2 go1.23.5.darwin-amd64.pkg +047bfce4fbd0da6426bd30cd19716b35a466b1c15a45525ce65b9824acb33285 go1.23.5.darwin-arm64.tar.gz +f819ed94939e08a5016b9a607ec84ebbde6cb3fe59750c59d97aa300c3fd02df go1.23.5.darwin-arm64.pkg +2dec52821e1f04a538d00b2cafe70fa506f2eea94a551bfe3ce1238f1bd4966f go1.23.5.dragonfly-amd64.tar.gz +7204e7bc62913b12f18c61afe0bc1a92fd192c0e45a54125978592296cb84e49 go1.23.5.freebsd-386.tar.gz +90a119995ebc3e36082874df5fa8fe6da194946679d01ae8bef33c87aab99391 go1.23.5.freebsd-amd64.tar.gz +255d26d873e41ff2fc278013bb2e5f25cf2ebe8d0ec84c07e3bb1436216020d3 go1.23.5.freebsd-arm.tar.gz +2785d9122654980b59ca38305a11b34f2a1e12d9f7eb41d52efc137c1fc29e61 go1.23.5.freebsd-arm64.tar.gz +8f66a94018ab666d56868f61c579aa81e549ac9700979ce6004445d315be2d37 go1.23.5.freebsd-riscv64.tar.gz +4b7a69928385ec512a4e77a547e24118adbb92301d2be36187ff0852ba9e6303 go1.23.5.illumos-amd64.tar.gz +6ecf6a41d0925358905fa2641db0e1c9037aa5b5bcd26ca6734caf50d9196417 go1.23.5.linux-386.tar.gz +cbcad4a6482107c7c7926df1608106c189417163428200ce357695cc7e01d091 go1.23.5.linux-amd64.tar.gz +47c84d332123883653b70da2db7dd57d2a865921ba4724efcdf56b5da7021db0 go1.23.5.linux-arm64.tar.gz +04e0b5cf5c216f0aa1bf8204d49312ad0845800ab0702dfe4357c0b1241027a3 go1.23.5.linux-armv6l.tar.gz +e1d14ac2207c78d52b76ba086da18a004c70aeb58cba72cd9bef0da7d1602786 go1.23.5.linux-loong64.tar.gz +d9e937f2fac4fc863850fb4cc31ae76d5495029a62858ef09c78604472d354c0 go1.23.5.linux-mips.tar.gz +59710d0782abafd47e40d1cf96aafa596bbdee09ac7c61062404604f49bd523e go1.23.5.linux-mips64.tar.gz +bc528cd836b4aa6701a42093ed390ef9929639a0e2818759887dc5539e517cab go1.23.5.linux-mips64le.tar.gz +a0404764ea1fd4a175dc5193622b15be6ed1ab59cbfa478f5ae24531bafb6cbd go1.23.5.linux-mipsle.tar.gz +db110284a0c91d4545273f210ca95b9f89f6e3ac90f39eb819033a6b96f25897 go1.23.5.linux-ppc64.tar.gz +db268bf5710b5b1b82ab38722ba6e4427d9e4942aed78c7d09195a9dff329613 go1.23.5.linux-ppc64le.tar.gz +d9da15778442464f32acfa777ac731fd4d47362b233b83a0932380cb6d2d5dc8 go1.23.5.linux-riscv64.tar.gz +14924b917d35311eb130e263f34931043d4f9dc65f20684301bf8f60a72edcdf go1.23.5.linux-s390x.tar.gz +7b8074102e7f039bd6473c44f58cb323c98dcda48df98ad1f78aaa2664769c8f go1.23.5.netbsd-386.tar.gz +1a466b9c8900e66664b15c07548ecb156e8274cf1028ac5da84134728e6dbbed go1.23.5.netbsd-amd64.tar.gz +901c9e72038926e37a4dbde8f03d1d81fcb9992850901a3da1da5a25ef93e65b go1.23.5.netbsd-arm.tar.gz +221f69a7c3a920e3666633ee0b4e5c810176982e74339ba4693226996dc636e4 go1.23.5.netbsd-arm64.tar.gz +42e46cbf73febb8e6ddf848765ce1c39573736383b132402cdc487eb6be3ad06 go1.23.5.openbsd-386.tar.gz +f49e81fce17aab21800fab7c4b10c97ab02f8a9c807fdf8641ccf2f87d69289f go1.23.5.openbsd-amd64.tar.gz +d8bd7269d4670a46e702b64822254a654824347c35923ef1c444d2e8687381ea go1.23.5.openbsd-arm.tar.gz +9cb259adff431d4d28b18e3348e26fe07ea10380675051dcfd740934b5e8b9f2 go1.23.5.openbsd-arm64.tar.gz +72a03223c98fcecfb06e57c3edd584f99fb7f6574a42f59348473f354be1f379 go1.23.5.openbsd-ppc64.tar.gz +c06432b859afb36657207382b7bac03f961b8fafc18176b501d239575a9ace64 go1.23.5.openbsd-riscv64.tar.gz +b1f9b12b269ab5cd4aa7ae3dd3075c2407c1ea8bb1211e6835261f98931201cc go1.23.5.plan9-386.tar.gz +45b4026a103e2f6cd436e2b7ad24b24a40dd22c9903519b98b45c535574fa01a go1.23.5.plan9-amd64.tar.gz +6e28e26f8c1e8620006490260aa5743198843aa0003c400cb65cbf5e743b21c7 go1.23.5.plan9-arm.tar.gz +0496c9969f208bd597f3e63fb27068ce1c7ed776618da1007fcc1c8be83ca413 go1.23.5.solaris-amd64.tar.gz +8441605a005ea74c28d8c02ca5f2708c17b4df7e91796148b9f8760caafb05c1 go1.23.5.windows-386.zip +39962346d8d0cb0cc8716489ee33b08d7a220c24a9e45423487876dd4acbdac6 go1.23.5.windows-386.msi +96d74945d7daeeb98a7978d0cf099321d7eb821b45f5c510373d545162d39c20 go1.23.5.windows-amd64.zip +03e11a988a18ad7e3f9038cef836330af72ba0a454a502cda7b7faee07a0dd8a go1.23.5.windows-amd64.msi +0005b31dcf9732c280a5cceb6aa1c5ab8284bc2541d0256c221256080acf2a09 go1.23.5.windows-arm.zip +a8442de35cbac230db8c4b20e363055671f2295dc4d6b2b2dfec66b89a3c4bce go1.23.5.windows-arm.msi +4f20c2d8a5a387c227e3ef48c5506b22906139d8afd8d66a78ef3de8dda1d1c3 go1.23.5.windows-arm64.zip +6f54fb46b669345c734936c521f7e0f55555e63ed6e11efbbaaed06f9514773c go1.23.5.windows-arm64.msi # version:golangci 1.63.4 # https://github.com/golangci/golangci-lint/releases/ From 530adfc8e3ef9c8b6356facecdec10b30fb81d7d Mon Sep 17 00:00:00 2001 From: Shude Li Date: Tue, 21 Jan 2025 00:06:39 +0800 Subject: [PATCH 056/940] core/types: initialize ChainID in SetCodeTx copy method (#31054) --- core/types/tx_setcode.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index 0fb5362c26..894bac10a3 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -148,7 +148,7 @@ func (tx *SetCodeTx) copy() TxData { AccessList: make(AccessList, len(tx.AccessList)), AuthList: make([]SetCodeAuthorization, len(tx.AuthList)), Value: new(uint256.Int), - ChainID: tx.ChainID, + ChainID: new(uint256.Int), GasTipCap: new(uint256.Int), GasFeeCap: new(uint256.Int), V: new(uint256.Int), @@ -160,6 +160,9 @@ func (tx *SetCodeTx) copy() TxData { if tx.Value != nil { cpy.Value.Set(tx.Value) } + if tx.ChainID != nil { + cpy.ChainID.Set(tx.ChainID) + } if tx.GasTipCap != nil { cpy.GasTipCap.Set(tx.GasTipCap) } From e25cedf16debb0ab76adaf376f6df808aee8f029 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Tue, 21 Jan 2025 11:42:05 +0800 Subject: [PATCH 057/940] core/txpool: terminate subpool reset goroutine if pool was closed (#31030) if the pool terminates before `resetDone` can be read, then the go-routine will hang. --- core/txpool/txpool.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index d54cf4968b..182706d63c 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -224,7 +224,10 @@ func (p *TxPool) loop(head *types.Header, chain BlockChain) { for _, subpool := range p.subpools { subpool.Reset(oldHead, newHead) } - resetDone <- newHead + select { + case resetDone <- newHead: + case <-p.term: + } }(oldHead, newHead) // If the reset operation was explicitly requested, consider it From 2bf4a8ff73fc387592383dcba4175c422825b6b9 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Tue, 21 Jan 2025 08:35:03 +0100 Subject: [PATCH 058/940] cmd/evm: refactor handling output-files for `t8n` (#30854) As part of trying to make the inputs and outputs of the evm subcommands more streamlined and aligned, this PR modifies how `evm t8n` manages output-files. Previously, we do a kind of wonky thing where between each transaction, we invoke a `getTracer` closure. In that closure, we create a new output-file, a tracer, and then make the tracer stream output to the file. We also fiddle a bit to ensure that the file becomes properly closed. It is a kind of hacky solution we have in place. This PR changes it, so that from the execution-pipeline point of view, we have just a regular tracer. No fiddling with re-setting it or closing files. That particular tracer, however, is a bit special: it takes care of creating new files per transaction (in the tx-start-hook) and closing (on tx-end-hook). Also instantiating the right type of underlying tracer, which can be a json-logger or a custom tracer. --------- Co-authored-by: Gary Rong --- cmd/evm/internal/t8ntool/execution.go | 52 +----- cmd/evm/internal/t8ntool/file_tracer.go | 152 ++++++++++++++++++ cmd/evm/internal/t8ntool/transaction.go | 6 +- cmd/evm/internal/t8ntool/transition.go | 77 ++++----- cmd/evm/main.go | 4 +- cmd/evm/t8n_test.go | 32 ++-- cmd/evm/testdata/31/README.md | 10 ++ ...47543268a5aaf2a6b32a69d2c6d978c45dcfb.json | 2 +- ...3641ef5a8bbdb10ac69f466083a6789c77fb8.json | 1 + ...641ef5a8bbdb10ac69f466083a6789c77fb8.jsonl | 6 + ...86f5a9a08f7ef183da72c23bb3b2374530128.json | 1 + ...6f5a9a08f7ef183da72c23bb3b2374530128.jsonl | 6 + cmd/evm/testdata/31/txs.json | 24 +++ core/vm/evm.go | 5 - 14 files changed, 260 insertions(+), 118 deletions(-) create mode 100644 cmd/evm/internal/t8ntool/file_tracer.go create mode 100644 cmd/evm/testdata/31/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.json create mode 100644 cmd/evm/testdata/31/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.jsonl create mode 100644 cmd/evm/testdata/31/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.json create mode 100644 cmd/evm/testdata/31/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.jsonl diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 7c17a251f0..9ff5a05290 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -17,9 +17,7 @@ package t8ntool import ( - "encoding/json" "fmt" - "io" "math/big" "github.com/ethereum/go-ethereum/common" @@ -35,7 +33,6 @@ import ( "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" @@ -130,9 +127,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, chainConfig *params.ChainConfig) (*tracers.Tracer, io.WriteCloser, error)) (*state.StateDB, *ExecutionResult, []byte, error) { +func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, txIt txIterator, miningReward int64) (*state.StateDB, *ExecutionResult, []byte, error) { // Capture errors for BLOCKHASH operation, if we haven't been supplied the // required blockhashes var hashError error @@ -241,23 +236,13 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, continue } } - tracer, traceOutput, err := getTracerFn(txIndex, tx.Hash(), chainConfig) - if err != nil { - return nil, nil, nil, err - } - // TODO (rjl493456442) it's a bit weird to reset the tracer in the - // middle of block execution, please improve it somehow. - if tracer != nil { - evm.SetTracer(tracer.Hooks) - } statedb.SetTxContext(tx.Hash(), txIndex) - var ( snapshot = statedb.Snapshot() prevGas = gaspool.Gas() ) - if tracer != nil && tracer.OnTxStart != nil { - tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) + if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxStart != nil { + evm.Config.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) } // (ret []byte, usedGas uint64, failed bool, err error) msgResult, err := core.ApplyMessage(evm, msg, gaspool) @@ -266,13 +251,8 @@ 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) - } + if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxEnd != nil { + evm.Config.Tracer.OnTxEnd(nil, err) } continue } @@ -316,13 +296,8 @@ 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) - } + if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxEnd != nil { + evm.Config.Tracer.OnTxEnd(receipt, nil) } } @@ -468,16 +443,3 @@ 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/file_tracer.go b/cmd/evm/internal/t8ntool/file_tracer.go new file mode 100644 index 0000000000..38fc35bd32 --- /dev/null +++ b/cmd/evm/internal/t8ntool/file_tracer.go @@ -0,0 +1,152 @@ +// Copyright 2024 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" + "fmt" + "io" + "math/big" + "os" + "path/filepath" + + "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/log" +) + +// fileWritingTracer wraps either a tracer or a logger. On tx start, +// it instantiates a tracer/logger, creates a new file to direct output to, +// and on tx end it closes the file. +type fileWritingTracer struct { + txIndex int // transaction counter + inner *tracing.Hooks // inner hooks + destination io.WriteCloser // the currently open file (if any) + baseDir string // baseDir to write output-files to + suffix string // suffix is the suffix to use when creating files + + // for custom tracing + getResult func() (json.RawMessage, error) +} + +func (l *fileWritingTracer) Write(p []byte) (n int, err error) { + if l.destination != nil { + return l.destination.Write(p) + } + log.Warn("Tracer wrote to non-existing output") + // It is tempting to return an error here, however, the json encoder + // will no retry writing to an io.Writer once it has returned an error once. + // Therefore, we must squash the error. + return n, nil +} + +// newFileWriter creates a set of hooks which wraps inner hooks (typically a logger), +// and writes the output to a file, one file per transaction. +func newFileWriter(baseDir string, innerFn func(out io.Writer) *tracing.Hooks) *tracing.Hooks { + t := &fileWritingTracer{ + baseDir: baseDir, + suffix: "jsonl", + } + t.inner = innerFn(t) // instantiate the inner tracer + return t.hooks() +} + +// newResultWriter creates a set of hooks wraps and invokes an underlying tracer, +// and writes the result (getResult-output) to file, one per transaction. +func newResultWriter(baseDir string, tracer *tracers.Tracer) *tracing.Hooks { + t := &fileWritingTracer{ + baseDir: baseDir, + getResult: tracer.GetResult, + inner: tracer.Hooks, + suffix: "json", + } + return t.hooks() +} + +// OnTxStart creates a new output-file specific for this transaction, and invokes +// the inner OnTxStart handler. +func (l *fileWritingTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + // Open a new file, or print a warning log if it's failed + fname := filepath.Join(l.baseDir, fmt.Sprintf("trace-%d-%v.%v", l.txIndex, tx.Hash().String(), l.suffix)) + traceFile, err := os.Create(fname) + if err != nil { + log.Warn("Failed creating trace-file", "err", err) + } else { + log.Info("Created tracing-file", "path", fname) + l.destination = traceFile + } + if l.inner != nil && l.inner.OnTxStart != nil { + l.inner.OnTxStart(env, tx, from) + } +} + +// OnTxEnd writes result (if getResult exist), closes any currently open output-file, +// and invokes the inner OnTxEnd handler. +func (l *fileWritingTracer) OnTxEnd(receipt *types.Receipt, err error) { + if l.inner != nil && l.inner.OnTxEnd != nil { + l.inner.OnTxEnd(receipt, err) + } + if l.getResult != nil && l.destination != nil { + if result, err := l.getResult(); result != nil { + json.NewEncoder(l.destination).Encode(result) + } else { + log.Warn("Error obtaining tracer result", "err", err) + } + l.destination.Close() + l.destination = nil + } + l.txIndex++ +} + +func (l *fileWritingTracer) hooks() *tracing.Hooks { + return &tracing.Hooks{ + OnTxStart: l.OnTxStart, + OnTxEnd: l.OnTxEnd, + OnEnter: func(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + if l.inner != nil && l.inner.OnEnter != nil { + l.inner.OnEnter(depth, typ, from, to, input, gas, value) + } + }, + OnExit: func(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if l.inner != nil && l.inner.OnExit != nil { + l.inner.OnExit(depth, output, gasUsed, err, reverted) + } + }, + OnOpcode: func(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { + if l.inner != nil && l.inner.OnOpcode != nil { + l.inner.OnOpcode(pc, op, gas, cost, scope, rData, depth, err) + } + }, + OnFault: func(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error) { + if l.inner != nil && l.inner.OnFault != nil { + l.inner.OnFault(pc, op, gas, cost, scope, depth, err) + } + }, + OnSystemCallStart: func() { + if l.inner != nil && l.inner.OnSystemCallStart != nil { + l.inner.OnSystemCallStart() + } + }, + OnSystemCallEnd: func() { + if l.inner != nil && l.inner.OnSystemCallEnd != nil { + l.inner.OnSystemCallEnd() + } + }, + } +} diff --git a/cmd/evm/internal/t8ntool/transaction.go b/cmd/evm/internal/t8ntool/transaction.go index 6dac4301dd..d8650beca6 100644 --- a/cmd/evm/internal/t8ntool/transaction.go +++ b/cmd/evm/internal/t8ntool/transaction.go @@ -64,12 +64,10 @@ func (r *result) MarshalJSON() ([]byte, error) { } func Transaction(ctx *cli.Context) error { - var ( - err error - ) // We need to load the transactions. May be either in stdin input or in files. // Check if anything needs to be read from stdin var ( + err error txStr = ctx.String(InputTxsFlag.Name) inputData = &input{} chainConfig *params.ChainConfig @@ -82,6 +80,7 @@ func Transaction(ctx *cli.Context) error { } // Set the chain id chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name)) + var body hexutil.Bytes if txStr == stdinSelector { decoder := json.NewDecoder(os.Stdin) @@ -107,6 +106,7 @@ func Transaction(ctx *cli.Context) error { } } signer := types.MakeSigner(chainConfig, new(big.Int), 0) + // We now have the transactions in 'body', which is supposed to be an // rlp list of transactions it, err := rlp.NewListIterator([]byte(body)) diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 231576fa42..e946ccddd5 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -82,58 +82,10 @@ type input struct { } func Transition(ctx *cli.Context) error { - var getTracer = func(txIndex int, txHash common.Hash, chainConfig *params.ChainConfig) (*tracers.Tracer, io.WriteCloser, error) { - return nil, nil, nil - } - baseDir, err := createBasedir(ctx) if err != nil { return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err)) } - - if ctx.Bool(TraceFlag.Name) { // JSON opcode tracing - // Configure the EVM logger - logConfig := &logger.Config{ - DisableStack: ctx.Bool(TraceDisableStackFlag.Name), - EnableMemory: ctx.Bool(TraceEnableMemoryFlag.Name), - EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name), - } - getTracer = func(txIndex int, txHash common.Hash, _ *params.ChainConfig) (*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, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) - } - 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, chainConfig *params.ChainConfig) (*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, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) - } - tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config, chainConfig) - if err != nil { - return nil, nil, NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %w", err)) - } - return tracer, traceFile, nil - } - } // We need to load three things: alloc, env and transactions. May be either in // stdin input or in files. // Check if anything needs to be read from stdin @@ -179,6 +131,7 @@ func Transition(ctx *cli.Context) error { chainConfig = cConf vmConfig.ExtraEips = extraEips } + // Set the chain id chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name)) @@ -197,8 +150,34 @@ func Transition(ctx *cli.Context) error { if err := applyCancunChecks(&prestate.Env, chainConfig); err != nil { return err } + + // Configure tracer + if ctx.IsSet(TraceTracerFlag.Name) { // Custom tracing + config := json.RawMessage(ctx.String(TraceTracerConfigFlag.Name)) + tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), + nil, config, chainConfig) + if err != nil { + return NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %v", err)) + } + vmConfig.Tracer = newResultWriter(baseDir, tracer) + } else if ctx.Bool(TraceFlag.Name) { // JSON opcode tracing + logConfig := &logger.Config{ + DisableStack: ctx.Bool(TraceDisableStackFlag.Name), + EnableMemory: ctx.Bool(TraceEnableMemoryFlag.Name), + EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name), + } + if ctx.Bool(TraceEnableCallFramesFlag.Name) { + vmConfig.Tracer = newFileWriter(baseDir, func(out io.Writer) *tracing.Hooks { + return logger.NewJSONLoggerWithCallFrames(logConfig, out) + }) + } else { + vmConfig.Tracer = newFileWriter(baseDir, func(out io.Writer) *tracing.Hooks { + return logger.NewJSONLogger(logConfig, out) + }) + } + } // Run the test and aggregate the result - s, result, body, err := prestate.Apply(vmConfig, chainConfig, txIt, ctx.Int64(RewardFlag.Name), getTracer) + s, result, body, err := prestate.Apply(vmConfig, chainConfig, txIt, ctx.Int64(RewardFlag.Name)) if err != nil { return err } diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 2079425416..61e46aa50e 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -83,8 +83,8 @@ var ( } TraceFormatFlag = &cli.StringFlag{ Name: "trace.format", - Usage: "Trace output format to use (struct|json)", - Value: "struct", + Usage: "Trace output format to use (json|struct|md)", + Value: "json", Category: traceCategory, } TraceDisableMemoryFlag = &cli.BoolFlag{ diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index 27c6c43164..985dac968d 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -606,18 +606,18 @@ func TestEvmRun(t *testing.T) { wantStdout: "./testdata/evmrun/1.out.1.txt", wantStderr: "./testdata/evmrun/1.out.2.txt", }, - { // default tracing (struct) - input: []string{"run", "--trace", "0x6040"}, + { // Struct tracing + input: []string{"run", "--trace", "--trace.format=struct", "0x6040"}, wantStdout: "./testdata/evmrun/2.out.1.txt", wantStderr: "./testdata/evmrun/2.out.2.txt", }, - { // default tracing (struct), plus alloc-dump - input: []string{"run", "--trace", "--dump", "0x6040"}, + { // struct-tracing, plus alloc-dump + input: []string{"run", "--trace", "--trace.format=struct", "--dump", "0x6040"}, wantStdout: "./testdata/evmrun/3.out.1.txt", //wantStderr: "./testdata/evmrun/3.out.2.txt", }, - { // json-tracing, plus alloc-dump - input: []string{"run", "--trace", "--trace.format=json", "--dump", "0x6040"}, + { // json-tracing (default), plus alloc-dump + input: []string{"run", "--trace", "--dump", "0x6040"}, wantStdout: "./testdata/evmrun/4.out.1.txt", //wantStderr: "./testdata/evmrun/4.out.2.txt", }, @@ -698,7 +698,10 @@ func TestEVMTracing(t *testing.T) { "--input.env=./testdata/31/env.json", "--state.fork=Cancun", "--trace", }, - expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl"}, + //expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl"}, + expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl", + "trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.jsonl", + "trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.jsonl"}, }, { base: "./testdata/31", @@ -706,14 +709,17 @@ func TestEVMTracing(t *testing.T) { "--input.alloc=./testdata/31/alloc.json", "--input.txs=./testdata/31/txs.json", "--input.env=./testdata/31/env.json", "--state.fork=Cancun", "--trace.tracer", ` -{ - result: function(){ - return "hello world" - }, - fault: function(){} +{ count: 0, + result: function(){ + this.count = this.count + 1; + return "hello world " + this.count + }, + fault: function(){} }`, }, - expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json"}, + expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json", + "trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.json", + "trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.json"}, }, { base: "./testdata/32", diff --git a/cmd/evm/testdata/31/README.md b/cmd/evm/testdata/31/README.md index 305e4f52da..b337c1eb62 100644 --- a/cmd/evm/testdata/31/README.md +++ b/cmd/evm/testdata/31/README.md @@ -1 +1,11 @@ This test does some EVM execution, and can be used to test the tracers and trace-outputs. +This test should yield three output-traces, in separate files + +For example: +``` +[user@work evm]$ go run . t8n --input.alloc ./testdata/31/alloc.json --input.txs ./testdata/31/txs.json --input.env ./testdata/31/env.json --state.fork Cancun --output.basedir /tmp --trace +INFO [12-06|09:53:32.123] Created tracing-file path=/tmp/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl +INFO [12-06|09:53:32.124] Created tracing-file path=/tmp/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.jsonl +INFO [12-06|09:53:32.125] Created tracing-file path=/tmp/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.jsonl +``` + diff --git a/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json b/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json index cd4bc1ab64..dfa1d7c7cb 100644 --- a/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json +++ b/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json @@ -1 +1 @@ -"hello world" +"hello world 1" diff --git a/cmd/evm/testdata/31/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.json b/cmd/evm/testdata/31/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.json new file mode 100644 index 0000000000..25980291c7 --- /dev/null +++ b/cmd/evm/testdata/31/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.json @@ -0,0 +1 @@ +"hello world 2" diff --git a/cmd/evm/testdata/31/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.jsonl b/cmd/evm/testdata/31/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.jsonl new file mode 100644 index 0000000000..26e5c7ee4e --- /dev/null +++ b/cmd/evm/testdata/31/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.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/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.json b/cmd/evm/testdata/31/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.json new file mode 100644 index 0000000000..242587bd83 --- /dev/null +++ b/cmd/evm/testdata/31/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.json @@ -0,0 +1 @@ +"hello world 3" diff --git a/cmd/evm/testdata/31/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.jsonl b/cmd/evm/testdata/31/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.jsonl new file mode 100644 index 0000000000..26e5c7ee4e --- /dev/null +++ b/cmd/evm/testdata/31/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.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 index 473c1526f4..da8f5761f6 100644 --- a/cmd/evm/testdata/31/txs.json +++ b/cmd/evm/testdata/31/txs.json @@ -10,5 +10,29 @@ "r" : "0x0", "s" : "0x0", "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + }, + { + "gas": "0x186a0", + "gasPrice": "0x600", + "input": "0x", + "nonce": "0x1", + "to": "0x1111111111111111111111111111111111111111", + "value": "0x1", + "v" : "0x0", + "r" : "0x0", + "s" : "0x0", + "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + }, + { + "gas": "0x186a0", + "gasPrice": "0x600", + "input": "0x", + "nonce": "0x2", + "to": "0x1111111111111111111111111111111111111111", + "value": "0x1", + "v" : "0x0", + "r" : "0x0", + "s" : "0x0", + "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" } ] diff --git a/core/vm/evm.go b/core/vm/evm.go index 1a0215459c..1e52215b7e 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -133,11 +133,6 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon return evm } -// SetTracer sets the tracer for following state transition. -func (evm *EVM) SetTracer(tracer *tracing.Hooks) { - evm.Config.Tracer = tracer -} - // SetPrecompiles sets the precompiled contracts for the EVM. // This method is only used through RPC calls. // It is not thread-safe. From 6c10996bf5664ea2a7f7020bcb4d97a848dbf48a Mon Sep 17 00:00:00 2001 From: jwasinger Date: Tue, 21 Jan 2025 20:11:05 +0800 Subject: [PATCH 059/940] eth/filters: ensure API timeoutLoop terminates with event system (#31056) Discovered from failing test introduced https://github.com/ethereum/go-ethereum/pull/31033 . We should ensure `timeoutLoop` terminates if the filter event system is terminated. --- eth/filters/api.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eth/filters/api.go b/eth/filters/api.go index f46dd39dd8..e3057a2af2 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -90,7 +90,11 @@ func (api *FilterAPI) timeoutLoop(timeout time.Duration) { ticker := time.NewTicker(timeout) defer ticker.Stop() for { - <-ticker.C + select { + case <-ticker.C: + case <-api.events.chainSub.Err(): + return + } api.filtersMu.Lock() for id, f := range api.filters { select { From 4af9af419d71bd4510e7e4257c05e4ce41131096 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 21 Jan 2025 22:23:46 +0100 Subject: [PATCH 060/940] go.mod: remove toolchain line (#31057) We have our own system for downloading the toolchain, and really don't want Go's to get in the way of that. We may switch to Go's builtin toolchain support, but not now. --- go.mod | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.mod b/go.mod index 35018fbe08..20526956df 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/ethereum/go-ethereum 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.2 From c43faa3d9d88337824e8210e1835cfd82c15cd96 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 21 Jan 2025 15:02:17 -0700 Subject: [PATCH 061/940] cmd/evm: restore --bench flag to evm statetest (#31055) Refactoring of the `evm` command moved where some commands were valid. One command, `--bench`, used to work in `evm statetest`. The pluming is still in place. This PR puts the `--bench` flag in the place the trace flags were moved, and adds tests to validate the bench flag operates in `run` and `statetest` --------- Co-authored-by: Felix Lange --- cmd/evm/staterunner.go | 1 + cmd/evm/t8n_test.go | 56 ++++++++++++++++++++++++++++ cmd/evm/testdata/evmrun/10.out.1.txt | 15 ++++++++ cmd/evm/testdata/evmrun/10.out.2.txt | 0 cmd/evm/testdata/evmrun/9.out.1.txt | 0 cmd/evm/testdata/evmrun/9.out.2.txt | 4 ++ 6 files changed, 76 insertions(+) create mode 100644 cmd/evm/testdata/evmrun/10.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/10.out.2.txt create mode 100644 cmd/evm/testdata/evmrun/9.out.1.txt create mode 100644 cmd/evm/testdata/evmrun/9.out.2.txt diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 4c2dfeabc6..8f81a95315 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -51,6 +51,7 @@ var stateTestCommand = &cli.Command{ Usage: "Executes the given state tests. Filenames can be fed via standard input (batch mode) or as an argument (one-off execution).", ArgsUsage: "", Flags: slices.Concat([]cli.Flag{ + BenchFlag, DumpFlag, HumanReadableFlag, RunFlag, diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index 985dac968d..46146be787 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -24,6 +24,7 @@ import ( "os" "path/filepath" "reflect" + "regexp" "strings" "testing" @@ -670,6 +671,61 @@ func TestEvmRun(t *testing.T) { } } +func TestEvmRunRegEx(t *testing.T) { + t.Parallel() + tt := cmdtest.NewTestCmd(t, nil) + for i, tc := range []struct { + input []string + wantStdout string + wantStderr string + }{ + { // json tracing + input: []string{"run", "--bench", "6040"}, + wantStdout: "./testdata/evmrun/9.out.1.txt", + wantStderr: "./testdata/evmrun/9.out.2.txt", + }, + { // statetest subcommand + input: []string{"statetest", "--bench", "./testdata/statetest.json"}, + wantStdout: "./testdata/evmrun/10.out.1.txt", + wantStderr: "./testdata/evmrun/10.out.2.txt", + }, + } { + tt.Logf("args: go run ./cmd/evm %v\n", strings.Join(tc.input, " ")) + tt.Run("evm-test", tc.input...) + + haveStdOut := tt.Output() + tt.WaitExit() + haveStdErr := tt.StderrText() + + if have, wantFile := haveStdOut, tc.wantStdout; wantFile != "" { + want, err := os.ReadFile(wantFile) + if err != nil { + t.Fatalf("test %d: could not read expected output: %v", i, err) + } + re, err := regexp.Compile(string(want)) + if err != nil { + t.Fatalf("test %d: could not compile regular expression: %v", i, err) + } + if !re.Match(have) { + t.Fatalf("test %d, output wrong, have \n%v\nwant\n%v\n", i, string(have), re) + } + } + if have, wantFile := haveStdErr, tc.wantStderr; wantFile != "" { + want, err := os.ReadFile(wantFile) + if err != nil { + t.Fatalf("test %d: could not read expected output: %v", i, err) + } + re, err := regexp.Compile(string(want)) + if err != nil { + t.Fatalf("test %d: could not compile regular expression: %v", i, err) + } + if !re.MatchString(have) { + t.Fatalf("test %d, output wrong, have \n%v\nwant\n%v\n", i, have, re) + } + } + } +} + // cmpJson compares the JSON in two byte slices. func cmpJson(a, b []byte) (bool, error) { var j, j2 interface{} diff --git a/cmd/evm/testdata/evmrun/10.out.1.txt b/cmd/evm/testdata/evmrun/10.out.1.txt new file mode 100644 index 0000000000..5f94bdd261 --- /dev/null +++ b/cmd/evm/testdata/evmrun/10.out.1.txt @@ -0,0 +1,15 @@ +\[ + \{ + "name": "00000006-naivefuzz-0", + "pass": false, + "stateRoot": "0xad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458", + "fork": "London", + "error": "post state root mismatch: got ad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458, want 0000000000000000000000000000000000000000000000000000000000000000", + "benchStats": \{ + "time": \d+, + "allocs": \d+, + "bytesAllocated": \d+, + "gasUsed": \d+ + \} + \} +\] \ No newline at end of file diff --git a/cmd/evm/testdata/evmrun/10.out.2.txt b/cmd/evm/testdata/evmrun/10.out.2.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cmd/evm/testdata/evmrun/9.out.1.txt b/cmd/evm/testdata/evmrun/9.out.1.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cmd/evm/testdata/evmrun/9.out.2.txt b/cmd/evm/testdata/evmrun/9.out.2.txt new file mode 100644 index 0000000000..90def283e0 --- /dev/null +++ b/cmd/evm/testdata/evmrun/9.out.2.txt @@ -0,0 +1,4 @@ +EVM gas used: \d+ +execution time: \d+\.\d+.s +allocations: \d+ +allocated bytes: \d+ From 218b697f053b3e09c4a60d27feeb32af30acab58 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 22 Jan 2025 09:29:34 +0100 Subject: [PATCH 062/940] p2p: support configuring NAT in TOML file (#31041) This is an alternative for #27407 with a solution based on gencodec. With the PR, one can now configure like this: ``` # config.toml [Node.P2P] NAT = "extip:33.33.33.33" ``` ```shell $ geth --config config.toml ... INFO [01-17|16:37:31.436] Started P2P networking self=enode://2290...ab@33.33.33.33:30303 ``` --- go.mod | 14 ++-- go.sum | 24 +++---- p2p/config.go | 144 +++++++++++++++++++++++++++++++++++++++ p2p/config_toml.go | 165 +++++++++++++++++++++++++++++++++++++++++++++ p2p/nat/nat.go | 15 +++-- p2p/nat/natpmp.go | 4 ++ p2p/server.go | 99 --------------------------- 7 files changed, 342 insertions(+), 123 deletions(-) create mode 100644 p2p/config.go create mode 100644 p2p/config_toml.go diff --git a/go.mod b/go.mod index 20526956df..51f9f1bda7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ethereum/go-ethereum -go 1.22 +go 1.22.0 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 @@ -25,7 +25,7 @@ require ( github.com/ethereum/go-verkle v0.2.2 github.com/fatih/color v1.16.0 github.com/ferranbt/fastssz v0.1.2 - github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e + github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4 github.com/fsnotify/fsnotify v1.6.0 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff github.com/gofrs/flock v0.8.1 @@ -62,13 +62,13 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/urfave/cli/v2 v2.25.7 go.uber.org/automaxprocs v1.5.2 - golang.org/x/crypto v0.31.0 + golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/sync v0.10.0 - golang.org/x/sys v0.28.0 + golang.org/x/sys v0.29.0 golang.org/x/text v0.21.0 golang.org/x/time v0.5.0 - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d + golang.org/x/tools v0.29.0 google.golang.org/protobuf v1.34.2 gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/yaml.v3 v3.0.1 @@ -138,8 +138,8 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/net v0.34.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index ded07f4867..8a280398d0 100644 --- a/go.sum +++ b/go.sum @@ -172,8 +172,8 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk= github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs= -github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e h1:bBLctRc7kr01YGvaDfgLbTwjFNW5jdp5y5rj8XXBHfY= -github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4 h1:HhaRPDFEB1BrvBF+UCUnhyY9y5dtuBxy0myn+7sFjAw= +github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4/go.mod h1:Um1dFHPONZGTHog1qD1NaWjXJW/SPB38wPv0O8uZ2fI= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -528,8 +528,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= 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= @@ -563,8 +563,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/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.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 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= @@ -601,8 +601,8 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -684,8 +684,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.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= @@ -750,8 +750,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= 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= diff --git a/p2p/config.go b/p2p/config.go new file mode 100644 index 0000000000..14492a2e55 --- /dev/null +++ b/p2p/config.go @@ -0,0 +1,144 @@ +// Copyright 2025 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 p2p + +import ( + "crypto/ecdsa" + "fmt" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/p2p/netutil" +) + +//go:generate go run github.com/fjl/gencodec -type Config -field-override configMarshaling -formats toml -out config_toml.go + +// Config holds Server options. +type Config struct { + // This field must be set to a valid secp256k1 private key. + PrivateKey *ecdsa.PrivateKey `toml:"-"` + + // MaxPeers is the maximum number of peers that can be + // connected. It must be greater than zero. + MaxPeers int + + // MaxPendingPeers is the maximum number of peers that can be pending in the + // handshake phase, counted separately for inbound and outbound connections. + // Zero defaults to preset values. + MaxPendingPeers int `toml:",omitempty"` + + // DialRatio controls the ratio of inbound to dialed connections. + // Example: a DialRatio of 2 allows 1/2 of connections to be dialed. + // Setting DialRatio to zero defaults it to 3. + DialRatio int `toml:",omitempty"` + + // NoDiscovery can be used to disable the peer discovery mechanism. + // Disabling is useful for protocol debugging (manual topology). + NoDiscovery bool + + // DiscoveryV4 specifies whether V4 discovery should be started. + DiscoveryV4 bool `toml:",omitempty"` + + // DiscoveryV5 specifies whether the new topic-discovery based V5 discovery + // protocol should be started or not. + DiscoveryV5 bool `toml:",omitempty"` + + // Name sets the node name of this server. + Name string `toml:"-"` + + // BootstrapNodes are used to establish connectivity + // with the rest of the network. + BootstrapNodes []*enode.Node + + // BootstrapNodesV5 are used to establish connectivity + // with the rest of the network using the V5 discovery + // protocol. + BootstrapNodesV5 []*enode.Node `toml:",omitempty"` + + // Static nodes are used as pre-configured connections which are always + // maintained and re-connected on disconnects. + StaticNodes []*enode.Node + + // Trusted nodes are used as pre-configured connections which are always + // allowed to connect, even above the peer limit. + TrustedNodes []*enode.Node + + // Connectivity can be restricted to certain IP networks. + // If this option is set to a non-nil value, only hosts which match one of the + // IP networks contained in the list are considered. + NetRestrict *netutil.Netlist `toml:",omitempty"` + + // NodeDatabase is the path to the database containing the previously seen + // live nodes in the network. + NodeDatabase string `toml:",omitempty"` + + // Protocols should contain the protocols supported + // by the server. Matching protocols are launched for + // each peer. + Protocols []Protocol `toml:"-" json:"-"` + + // If ListenAddr is set to a non-nil address, the server + // will listen for incoming connections. + // + // If the port is zero, the operating system will pick a port. The + // ListenAddr field will be updated with the actual address when + // the server is started. + ListenAddr string + + // If DiscAddr is set to a non-nil value, the server will use ListenAddr + // for TCP and DiscAddr for the UDP discovery protocol. + DiscAddr string + + // If set to a non-nil value, the given NAT port mapper + // is used to make the listening port available to the + // Internet. + NAT nat.Interface `toml:",omitempty"` + + // If Dialer is set to a non-nil value, the given Dialer + // is used to dial outbound peer connections. + Dialer NodeDialer `toml:"-"` + + // If NoDial is true, the server will not dial any peers. + NoDial bool `toml:",omitempty"` + + // If EnableMsgEvents is set then the server will emit PeerEvents + // whenever a message is sent to or received from a peer + EnableMsgEvents bool + + // Logger is a custom logger to use with the p2p.Server. + Logger log.Logger `toml:"-"` + + clock mclock.Clock +} + +type configMarshaling struct { + NAT configNAT +} + +type configNAT struct { + nat.Interface +} + +func (w *configNAT) UnmarshalText(input []byte) error { + n, err := nat.Parse(string(input)) + if err != nil { + return fmt.Errorf("invalid NAT specification: %v", err) + } + w.Interface = n + return nil +} diff --git a/p2p/config_toml.go b/p2p/config_toml.go new file mode 100644 index 0000000000..8a255e62fb --- /dev/null +++ b/p2p/config_toml.go @@ -0,0 +1,165 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package p2p + +import ( + "crypto/ecdsa" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/p2p/netutil" +) + +var _ = (*configMarshaling)(nil) + +// MarshalTOML marshals as TOML. +func (c Config) MarshalTOML() (interface{}, error) { + type Config struct { + PrivateKey *ecdsa.PrivateKey `toml:"-"` + MaxPeers int + MaxPendingPeers int `toml:",omitempty"` + DialRatio int `toml:",omitempty"` + NoDiscovery bool + DiscoveryV4 bool `toml:",omitempty"` + DiscoveryV5 bool `toml:",omitempty"` + Name string `toml:"-"` + BootstrapNodes []*enode.Node + BootstrapNodesV5 []*enode.Node `toml:",omitempty"` + StaticNodes []*enode.Node + TrustedNodes []*enode.Node + NetRestrict *netutil.Netlist `toml:",omitempty"` + NodeDatabase string `toml:",omitempty"` + Protocols []Protocol `toml:"-" json:"-"` + ListenAddr string + DiscAddr string + NAT nat.Interface `toml:",omitempty"` + Dialer NodeDialer `toml:"-"` + NoDial bool `toml:",omitempty"` + EnableMsgEvents bool + Logger log.Logger `toml:"-"` + } + var enc Config + enc.PrivateKey = c.PrivateKey + enc.MaxPeers = c.MaxPeers + enc.MaxPendingPeers = c.MaxPendingPeers + enc.DialRatio = c.DialRatio + enc.NoDiscovery = c.NoDiscovery + enc.DiscoveryV4 = c.DiscoveryV4 + enc.DiscoveryV5 = c.DiscoveryV5 + enc.Name = c.Name + enc.BootstrapNodes = c.BootstrapNodes + enc.BootstrapNodesV5 = c.BootstrapNodesV5 + enc.StaticNodes = c.StaticNodes + enc.TrustedNodes = c.TrustedNodes + enc.NetRestrict = c.NetRestrict + enc.NodeDatabase = c.NodeDatabase + enc.Protocols = c.Protocols + enc.ListenAddr = c.ListenAddr + enc.DiscAddr = c.DiscAddr + enc.NAT = c.NAT + enc.Dialer = c.Dialer + enc.NoDial = c.NoDial + enc.EnableMsgEvents = c.EnableMsgEvents + enc.Logger = c.Logger + return &enc, nil +} + +// UnmarshalTOML unmarshals from TOML. +func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { + type Config struct { + PrivateKey *ecdsa.PrivateKey `toml:"-"` + MaxPeers *int + MaxPendingPeers *int `toml:",omitempty"` + DialRatio *int `toml:",omitempty"` + NoDiscovery *bool + DiscoveryV4 *bool `toml:",omitempty"` + DiscoveryV5 *bool `toml:",omitempty"` + Name *string `toml:"-"` + BootstrapNodes []*enode.Node + BootstrapNodesV5 []*enode.Node `toml:",omitempty"` + StaticNodes []*enode.Node + TrustedNodes []*enode.Node + NetRestrict *netutil.Netlist `toml:",omitempty"` + NodeDatabase *string `toml:",omitempty"` + Protocols []Protocol `toml:"-" json:"-"` + ListenAddr *string + DiscAddr *string + NAT *configNAT `toml:",omitempty"` + Dialer NodeDialer `toml:"-"` + NoDial *bool `toml:",omitempty"` + EnableMsgEvents *bool + Logger log.Logger `toml:"-"` + } + var dec Config + if err := unmarshal(&dec); err != nil { + return err + } + if dec.PrivateKey != nil { + c.PrivateKey = dec.PrivateKey + } + if dec.MaxPeers != nil { + c.MaxPeers = *dec.MaxPeers + } + if dec.MaxPendingPeers != nil { + c.MaxPendingPeers = *dec.MaxPendingPeers + } + if dec.DialRatio != nil { + c.DialRatio = *dec.DialRatio + } + if dec.NoDiscovery != nil { + c.NoDiscovery = *dec.NoDiscovery + } + if dec.DiscoveryV4 != nil { + c.DiscoveryV4 = *dec.DiscoveryV4 + } + if dec.DiscoveryV5 != nil { + c.DiscoveryV5 = *dec.DiscoveryV5 + } + if dec.Name != nil { + c.Name = *dec.Name + } + if dec.BootstrapNodes != nil { + c.BootstrapNodes = dec.BootstrapNodes + } + if dec.BootstrapNodesV5 != nil { + c.BootstrapNodesV5 = dec.BootstrapNodesV5 + } + if dec.StaticNodes != nil { + c.StaticNodes = dec.StaticNodes + } + if dec.TrustedNodes != nil { + c.TrustedNodes = dec.TrustedNodes + } + if dec.NetRestrict != nil { + c.NetRestrict = dec.NetRestrict + } + if dec.NodeDatabase != nil { + c.NodeDatabase = *dec.NodeDatabase + } + if dec.Protocols != nil { + c.Protocols = dec.Protocols + } + if dec.ListenAddr != nil { + c.ListenAddr = *dec.ListenAddr + } + if dec.DiscAddr != nil { + c.DiscAddr = *dec.DiscAddr + } + if dec.NAT != nil { + c.NAT = dec.NAT + } + if dec.Dialer != nil { + c.Dialer = dec.Dialer + } + if dec.NoDial != nil { + c.NoDial = *dec.NoDial + } + if dec.EnableMsgEvents != nil { + c.EnableMsgEvents = *dec.EnableMsgEvents + } + if dec.Logger != nil { + c.Logger = dec.Logger + } + return nil +} diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index c656044268..f7fe8196c9 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -133,8 +133,9 @@ func Map(m Interface, c <-chan struct{}, protocol string, extport, intport int, // Mapping operations will not return an error but won't actually do anything. type ExtIP net.IP -func (n ExtIP) ExternalIP() (net.IP, error) { return net.IP(n), nil } -func (n ExtIP) String() string { return fmt.Sprintf("ExtIP(%v)", net.IP(n)) } +func (n ExtIP) ExternalIP() (net.IP, error) { return net.IP(n), nil } +func (n ExtIP) String() string { return fmt.Sprintf("ExtIP(%v)", net.IP(n)) } +func (n ExtIP) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("extip:%v", net.IP(n))), nil } // These do nothing. @@ -148,7 +149,7 @@ func (ExtIP) DeleteMapping(string, int, int) error { return nil } func Any() Interface { // TODO: attempt to discover whether the local machine has an // Internet-class address. Return ExtIP in this case. - return startautodisc("UPnP or NAT-PMP", func() Interface { + return startautodisc("any", func() Interface { found := make(chan Interface, 2) go func() { found <- discoverUPnP() }() go func() { found <- discoverPMP() }() @@ -164,7 +165,7 @@ func Any() Interface { // UPnP returns a port mapper that uses UPnP. It will attempt to // discover the address of your router using UDP broadcasts. func UPnP() Interface { - return startautodisc("UPnP", discoverUPnP) + return startautodisc("upnp", discoverUPnP) } // PMP returns a port mapper that uses NAT-PMP. The provided gateway @@ -174,7 +175,7 @@ func PMP(gateway net.IP) Interface { if gateway != nil { return &pmp{gw: gateway, c: natpmp.NewClient(gateway)} } - return startautodisc("NAT-PMP", discoverPMP) + return startautodisc("natpmp", discoverPMP) } // autodisc represents a port mapping mechanism that is still being @@ -228,6 +229,10 @@ func (n *autodisc) String() string { return n.found.String() } +func (n *autodisc) MarshalText() ([]byte, error) { + return []byte(n.what), nil +} + // wait blocks until auto-discovery has been performed. func (n *autodisc) wait() error { n.once.Do(func() { diff --git a/p2p/nat/natpmp.go b/p2p/nat/natpmp.go index 94ef1f4b68..b8f59ee890 100644 --- a/p2p/nat/natpmp.go +++ b/p2p/nat/natpmp.go @@ -70,6 +70,10 @@ func (n *pmp) DeleteMapping(protocol string, extport, intport int) (err error) { return err } +func (n *pmp) MarshalText() ([]byte, error) { + return []byte(fmt.Sprintf("natpmp:%v", n.gw)), nil +} + func discoverPMP() Interface { // run external address lookups on all potential gateways gws := potentialGateways() diff --git a/p2p/server.go b/p2p/server.go index 172f0667eb..c1564352e5 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -39,7 +39,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" - "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/netutil" ) @@ -72,104 +71,6 @@ var ( errProtoHandshakeError = errors.New("rlpx proto error") ) -// Config holds Server options. -type Config struct { - // This field must be set to a valid secp256k1 private key. - PrivateKey *ecdsa.PrivateKey `toml:"-"` - - // MaxPeers is the maximum number of peers that can be - // connected. It must be greater than zero. - MaxPeers int - - // MaxPendingPeers is the maximum number of peers that can be pending in the - // handshake phase, counted separately for inbound and outbound connections. - // Zero defaults to preset values. - MaxPendingPeers int `toml:",omitempty"` - - // DialRatio controls the ratio of inbound to dialed connections. - // Example: a DialRatio of 2 allows 1/2 of connections to be dialed. - // Setting DialRatio to zero defaults it to 3. - DialRatio int `toml:",omitempty"` - - // NoDiscovery can be used to disable the peer discovery mechanism. - // Disabling is useful for protocol debugging (manual topology). - NoDiscovery bool - - // DiscoveryV4 specifies whether V4 discovery should be started. - DiscoveryV4 bool `toml:",omitempty"` - - // DiscoveryV5 specifies whether the new topic-discovery based V5 discovery - // protocol should be started or not. - DiscoveryV5 bool `toml:",omitempty"` - - // Name sets the node name of this server. - Name string `toml:"-"` - - // BootstrapNodes are used to establish connectivity - // with the rest of the network. - BootstrapNodes []*enode.Node - - // BootstrapNodesV5 are used to establish connectivity - // with the rest of the network using the V5 discovery - // protocol. - BootstrapNodesV5 []*enode.Node `toml:",omitempty"` - - // Static nodes are used as pre-configured connections which are always - // maintained and re-connected on disconnects. - StaticNodes []*enode.Node - - // Trusted nodes are used as pre-configured connections which are always - // allowed to connect, even above the peer limit. - TrustedNodes []*enode.Node - - // Connectivity can be restricted to certain IP networks. - // If this option is set to a non-nil value, only hosts which match one of the - // IP networks contained in the list are considered. - NetRestrict *netutil.Netlist `toml:",omitempty"` - - // NodeDatabase is the path to the database containing the previously seen - // live nodes in the network. - NodeDatabase string `toml:",omitempty"` - - // Protocols should contain the protocols supported - // by the server. Matching protocols are launched for - // each peer. - Protocols []Protocol `toml:"-" json:"-"` - - // If ListenAddr is set to a non-nil address, the server - // will listen for incoming connections. - // - // If the port is zero, the operating system will pick a port. The - // ListenAddr field will be updated with the actual address when - // the server is started. - ListenAddr string - - // If DiscAddr is set to a non-nil value, the server will use ListenAddr - // for TCP and DiscAddr for the UDP discovery protocol. - DiscAddr string - - // If set to a non-nil value, the given NAT port mapper - // is used to make the listening port available to the - // Internet. - NAT nat.Interface `toml:",omitempty"` - - // If Dialer is set to a non-nil value, the given Dialer - // is used to dial outbound peer connections. - Dialer NodeDialer `toml:"-"` - - // If NoDial is true, the server will not dial any peers. - NoDial bool `toml:",omitempty"` - - // If EnableMsgEvents is set then the server will emit PeerEvents - // whenever a message is sent to or received from a peer - EnableMsgEvents bool - - // Logger is a custom logger to use with the p2p.Server. - Logger log.Logger `toml:",omitempty"` - - clock mclock.Clock -} - // Server manages all peer connections. type Server struct { // Config fields may not be modified while the server is running. From d10c61ca44418a0fd7688658b66584ccf78190e8 Mon Sep 17 00:00:00 2001 From: ucwong Date: Wed, 22 Jan 2025 12:53:01 +0000 Subject: [PATCH 063/940] go.mod: gencodec stable v0.1.0 (#31062) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 51f9f1bda7..cd1b989e7c 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/ethereum/go-verkle v0.2.2 github.com/fatih/color v1.16.0 github.com/ferranbt/fastssz v0.1.2 - github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4 + github.com/fjl/gencodec v0.1.0 github.com/fsnotify/fsnotify v1.6.0 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff github.com/gofrs/flock v0.8.1 diff --git a/go.sum b/go.sum index 8a280398d0..2e51046d82 100644 --- a/go.sum +++ b/go.sum @@ -172,8 +172,8 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk= github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs= -github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4 h1:HhaRPDFEB1BrvBF+UCUnhyY9y5dtuBxy0myn+7sFjAw= -github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4/go.mod h1:Um1dFHPONZGTHog1qD1NaWjXJW/SPB38wPv0O8uZ2fI= +github.com/fjl/gencodec v0.1.0 h1:B3K0xPfc52cw52BBgUbSPxYo+HlLfAgWMVKRWXUXBcs= +github.com/fjl/gencodec v0.1.0/go.mod h1:Um1dFHPONZGTHog1qD1NaWjXJW/SPB38wPv0O8uZ2fI= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= From a840e9b59f28427d3c65de9f028853e075438201 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Wed, 22 Jan 2025 21:06:36 +0800 Subject: [PATCH 064/940] triedb/pathdb: fix state revert on v2 history (#31060) State history v2 has been shipped and will take effect after the Cancun fork. However, the state revert function does not differentiate between v1 and v2, instead blindly using the storage map key for state reversion. This mismatch between the keys of the live state set and the state history can trigger a panic: `non-existent storage slot for reverting`. This flaw has been fixed in this PR. --- triedb/pathdb/database_test.go | 43 +++++++++++++++++----------------- triedb/pathdb/disklayer.go | 22 ++++------------- triedb/pathdb/history.go | 41 ++++++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 44 deletions(-) diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index f4b3fcec23..c85d7832ee 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -73,10 +73,10 @@ 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 - storageOrigin map[common.Address]map[common.Hash][]byte + accounts map[common.Hash][]byte // Keyed by the hash of account address + storages map[common.Hash]map[common.Hash][]byte // Keyed by the hash of account address and the hash of storage key + accountOrigin map[common.Address][]byte // Keyed by the account address + storageOrigin map[common.Address]map[common.Hash][]byte // Keyed by the account address and the hash of storage key nodes *trienode.MergedNodeSet } @@ -113,22 +113,23 @@ type tester struct { preimages map[common.Hash][]byte // current state set - accounts map[common.Hash][]byte - storages map[common.Hash]map[common.Hash][]byte + accounts map[common.Hash][]byte // Keyed by the hash of account address + storages map[common.Hash]map[common.Hash][]byte // Keyed by the hash of account address and the hash of storage key // state snapshots - snapAccounts map[common.Hash]map[common.Hash][]byte - snapStorages map[common.Hash]map[common.Hash]map[common.Hash][]byte + snapAccounts map[common.Hash]map[common.Hash][]byte // Keyed by the hash of account address + snapStorages map[common.Hash]map[common.Hash]map[common.Hash][]byte // Keyed by the hash of account address and the hash of storage key } -func newTester(t *testing.T, historyLimit uint64, isVerkle bool) *tester { +func newTester(t *testing.T, historyLimit uint64, isVerkle bool, layers int) *tester { var ( disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) db = New(disk, &Config{ StateHistory: historyLimit, - CleanCacheSize: 16 * 1024, - WriteBufferSize: 16 * 1024, + CleanCacheSize: 256 * 1024, + WriteBufferSize: 256 * 1024, }, isVerkle) + obj = &tester{ db: db, preimages: make(map[common.Hash][]byte), @@ -138,7 +139,7 @@ func newTester(t *testing.T, historyLimit uint64, isVerkle bool) *tester { snapStorages: make(map[common.Hash]map[common.Hash]map[common.Hash][]byte), } ) - for i := 0; i < 12; i++ { + for i := 0; i < layers; i++ { var parent = types.EmptyRootHash if len(obj.roots) != 0 { parent = obj.roots[len(obj.roots)-1] @@ -264,11 +265,11 @@ func (t *tester) generate(parent common.Hash, rawStorageKey bool) (common.Hash, addr := testrand.Address() addrHash := crypto.Keccak256Hash(addr.Bytes()) - // short circuit if the account was already existent + // Short circuit if the account was already existent if _, ok := t.accounts[addrHash]; ok { continue } - // short circuit if the account has been modified within the same transition + // Short circuit if the account has been modified within the same transition if _, ok := dirties[addrHash]; ok { continue } @@ -448,7 +449,7 @@ func TestDatabaseRollback(t *testing.T) { }() // Verify state histories - tester := newTester(t, 0, false) + tester := newTester(t, 0, false, 32) defer tester.release() if err := tester.verifyHistory(); err != nil { @@ -482,7 +483,7 @@ func TestDatabaseRecoverable(t *testing.T) { }() var ( - tester = newTester(t, 0, false) + tester = newTester(t, 0, false, 12) index = tester.bottomIndex() ) defer tester.release() @@ -526,7 +527,7 @@ func TestDisable(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0, false) + tester := newTester(t, 0, false, 32) defer tester.release() stored := crypto.Keccak256Hash(rawdb.ReadAccountTrieNode(tester.db.diskdb, nil)) @@ -568,7 +569,7 @@ func TestCommit(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0, false) + tester := newTester(t, 0, false, 12) defer tester.release() if err := tester.db.Commit(tester.lastHash(), false); err != nil { @@ -598,7 +599,7 @@ func TestJournal(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0, false) + tester := newTester(t, 0, false, 12) defer tester.release() if err := tester.db.Journal(tester.lastHash()); err != nil { @@ -628,7 +629,7 @@ func TestCorruptedJournal(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0, false) + tester := newTester(t, 0, false, 12) defer tester.release() if err := tester.db.Journal(tester.lastHash()); err != nil { @@ -676,7 +677,7 @@ func TestTailTruncateHistory(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 10, false) + tester := newTester(t, 10, false, 12) defer tester.release() tester.db.Close() diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index 5e678dbdee..184f6430a2 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -295,24 +295,6 @@ func (dl *diskLayer) revert(h *history) (*diskLayer, error) { if dl.id == 0 { return nil, fmt.Errorf("%w: zero state id", errStateUnrecoverable) } - var ( - buff = crypto.NewKeccakState() - hashes = make(map[common.Address]common.Hash) - accounts = make(map[common.Hash][]byte) - storages = make(map[common.Hash]map[common.Hash][]byte) - ) - for addr, blob := range h.accounts { - hash := crypto.HashData(buff, addr.Bytes()) - hashes[addr] = hash - accounts[hash] = blob - } - for addr, storage := range h.storages { - hash, ok := hashes[addr] - if !ok { - panic(fmt.Errorf("storage history with no account %x", addr)) - } - storages[hash] = storage - } // 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. @@ -320,6 +302,10 @@ func (dl *diskLayer) revert(h *history) (*diskLayer, error) { if err != nil { return nil, err } + // Derive the state modification set from the history, keyed by the hash + // of the account address and the storage key. + accounts, storages := h.stateSet() + // Mark the diskLayer as stale before applying any mutations on top. dl.lock.Lock() defer dl.lock.Unlock() diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index 9fb7d9e153..d8fb99ade4 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -26,6 +26,7 @@ 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" "github.com/ethereum/go-ethereum/log" "golang.org/x/exp/maps" @@ -68,8 +69,9 @@ const ( slotIndexSize = common.HashLength + 5 // The length of encoded slot index historyMetaSize = 9 + 2*common.HashLength // The length of encoded history meta - stateHistoryV0 = uint8(0) // initial version of state history structure - stateHistoryV1 = uint8(1) // use the storage slot raw key as the identifier instead of the key hash + stateHistoryV0 = uint8(0) // initial version of state history structure + stateHistoryV1 = uint8(1) // use the storage slot raw key as the identifier instead of the key hash + historyVersion = stateHistoryV1 // the default state history version ) // Each state history entry is consisted of five elements: @@ -258,9 +260,9 @@ func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map slices.SortFunc(slist, common.Hash.Cmp) storageList[addr] = slist } - version := stateHistoryV0 - if rawStorageKey { - version = stateHistoryV1 + version := historyVersion + if !rawStorageKey { + version = stateHistoryV0 } return &history{ meta: &meta{ @@ -276,6 +278,35 @@ func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map } } +// stateSet returns the state set, keyed by the hash of the account address +// and the hash of the storage slot key. +func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) { + var ( + buff = crypto.NewKeccakState() + accounts = make(map[common.Hash][]byte) + storages = make(map[common.Hash]map[common.Hash][]byte) + ) + for addr, blob := range h.accounts { + addrHash := crypto.HashData(buff, addr.Bytes()) + accounts[addrHash] = blob + + storage, exist := h.storages[addr] + if !exist { + continue + } + if h.meta.version == stateHistoryV0 { + storages[addrHash] = storage + } else { + subset := make(map[common.Hash][]byte) + for key, slot := range storage { + subset[crypto.HashData(buff, key.Bytes())] = slot + } + storages[addrHash] = subset + } + } + return accounts, storages +} + // encode serializes the state history and returns four byte streams represent // concatenated account/storage data, account/storage indexes respectively. func (h *history) encode() ([]byte, []byte, []byte, []byte) { From d3cc61895109fcb267c0b6da81606c0498c82751 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Thu, 23 Jan 2025 10:17:12 +0100 Subject: [PATCH 065/940] trie: reduce allocations in stacktrie (#30743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR uses various tweaks and tricks to make the stacktrie near alloc-free. ``` [user@work go-ethereum]$ benchstat stacktrie.1 stacktrie.7 goos: linux goarch: amd64 pkg: github.com/ethereum/go-ethereum/trie cpu: 12th Gen Intel(R) Core(TM) i7-1270P │ stacktrie.1 │ stacktrie.7 │ │ sec/op │ sec/op vs base │ Insert100K-8 106.97m ± 8% 88.21m ± 34% -17.54% (p=0.000 n=10) │ stacktrie.1 │ stacktrie.7 │ │ B/op │ B/op vs base │ Insert100K-8 13199.608Ki ± 0% 3.424Ki ± 3% -99.97% (p=0.000 n=10) │ stacktrie.1 │ stacktrie.7 │ │ allocs/op │ allocs/op vs base │ Insert100K-8 553428.50 ± 0% 22.00 ± 5% -100.00% (p=0.000 n=10) ``` Also improves derivesha: ``` goos: linux goarch: amd64 pkg: github.com/ethereum/go-ethereum/core/types cpu: 12th Gen Intel(R) Core(TM) i7-1270P │ derivesha.1 │ derivesha.2 │ │ sec/op │ sec/op vs base │ DeriveSha200/stack_trie-8 477.8µ ± 2% 430.0µ ± 12% -10.00% (p=0.000 n=10) │ derivesha.1 │ derivesha.2 │ │ B/op │ B/op vs base │ DeriveSha200/stack_trie-8 45.17Ki ± 0% 25.65Ki ± 0% -43.21% (p=0.000 n=10) │ derivesha.1 │ derivesha.2 │ │ allocs/op │ allocs/op vs base │ DeriveSha200/stack_trie-8 1259.0 ± 0% 232.0 ± 0% -81.57% (p=0.000 n=10) ``` --------- Co-authored-by: Gary Rong --- trie/bytepool.go | 64 ++++++++++++++++++++++++++++++++++++ trie/encoding.go | 12 +++++++ trie/hasher.go | 8 +++++ trie/node.go | 35 ++++++++++++-------- trie/node_enc.go | 39 +++++++++++++++++++--- trie/stacktrie.go | 73 +++++++++++++++++++++++++++++------------- trie/stacktrie_test.go | 46 ++++++++++++++++++++++++++ 7 files changed, 238 insertions(+), 39 deletions(-) create mode 100644 trie/bytepool.go diff --git a/trie/bytepool.go b/trie/bytepool.go new file mode 100644 index 0000000000..4f9c5672fd --- /dev/null +++ b/trie/bytepool.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 trie + +// bytesPool is a pool for byte slices. It is safe for concurrent use. +type bytesPool struct { + c chan []byte + w int +} + +// newBytesPool creates a new bytesPool. The sliceCap sets the capacity of +// newly allocated slices, and the nitems determines how many items the pool +// will hold, at maximum. +func newBytesPool(sliceCap, nitems int) *bytesPool { + return &bytesPool{ + c: make(chan []byte, nitems), + w: sliceCap, + } +} + +// Get returns a slice. Safe for concurrent use. +func (bp *bytesPool) Get() []byte { + select { + case b := <-bp.c: + return b + default: + return make([]byte, 0, bp.w) + } +} + +// GetWithSize returns a slice with specified byte slice size. +func (bp *bytesPool) GetWithSize(s int) []byte { + b := bp.Get() + if cap(b) < s { + return make([]byte, s) + } + return b[:s] +} + +// Put returns a slice to the pool. Safe for concurrent use. This method +// will ignore slices that are too small or too large (>3x the cap) +func (bp *bytesPool) Put(b []byte) { + if c := cap(b); c < bp.w || c > 3*bp.w { + return + } + select { + case bp.c <- b: + default: + } +} diff --git a/trie/encoding.go b/trie/encoding.go index 3284d3f8f0..4cd29f531a 100644 --- a/trie/encoding.go +++ b/trie/encoding.go @@ -104,6 +104,18 @@ func keybytesToHex(str []byte) []byte { return nibbles } +// writeHexKey writes the hexkey into the given slice. +// OBS! This method omits the termination flag. +// OBS! The dst slice must be at least 2x as large as the key +func writeHexKey(dst []byte, key []byte) []byte { + _ = dst[2*len(key)-1] + for i, b := range key { + dst[i*2] = b / 16 + dst[i*2+1] = b % 16 + } + return dst[:2*len(key)] +} + // hexToKeybytes turns hex nibbles into key bytes. // This can only be used for keys of even length. func hexToKeybytes(hex []byte) []byte { diff --git a/trie/hasher.go b/trie/hasher.go index abf654c709..28f7f3d0c3 100644 --- a/trie/hasher.go +++ b/trie/hasher.go @@ -188,6 +188,14 @@ func (h *hasher) hashData(data []byte) hashNode { return n } +// hashDataTo hashes the provided data to the given destination buffer. The caller +// must ensure that the dst buffer is of appropriate size. +func (h *hasher) hashDataTo(dst, data []byte) { + h.sha.Reset() + h.sha.Write(data) + h.sha.Read(dst) +} + // proofHash is used to construct trie proofs, and returns the 'collapsed' // node (for later RLP encoding) as well as the hashed node -- unless the // node is smaller than 32 bytes, in which case it will be returned as is. diff --git a/trie/node.go b/trie/node.go index 15bbf62f1c..ecc2de192d 100644 --- a/trie/node.go +++ b/trie/node.go @@ -45,6 +45,27 @@ type ( } hashNode []byte valueNode []byte + + // fullnodeEncoder is a type used exclusively for encoding fullNode. + // Briefly instantiating a fullnodeEncoder and initializing with + // existing slices is less memory intense than using the fullNode type. + fullnodeEncoder struct { + Children [17][]byte + } + + // extNodeEncoder is a type used exclusively for encoding extension node. + // Briefly instantiating a extNodeEncoder and initializing with existing + // slices is less memory intense than using the shortNode type. + extNodeEncoder struct { + Key []byte + Val []byte + } + + // leafNodeEncoder is a type used exclusively for encoding leaf node. + leafNodeEncoder struct { + Key []byte + Val []byte + } ) // nilValueNode is used when collapsing internal trie nodes for hashing, since @@ -89,6 +110,7 @@ func (n *fullNode) fstring(ind string) string { } return resp + fmt.Sprintf("\n%s] ", ind) } + func (n *shortNode) fstring(ind string) string { return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" ")) } @@ -99,19 +121,6 @@ func (n valueNode) fstring(ind string) string { return fmt.Sprintf("%x ", []byte(n)) } -// rawNode is a simple binary blob used to differentiate between collapsed trie -// nodes and already encoded RLP binary blobs (while at the same time store them -// in the same cache fields). -type rawNode []byte - -func (n rawNode) cache() (hashNode, bool) { panic("this should never end up in a live trie") } -func (n rawNode) fstring(ind string) string { panic("this should never end up in a live trie") } - -func (n rawNode) EncodeRLP(w io.Writer) error { - _, err := w.Write(n) - return err -} - // mustDecodeNode is a wrapper of decodeNode and panic if any error is encountered. func mustDecodeNode(hash, buf []byte) node { n, err := decodeNode(hash, buf) diff --git a/trie/node_enc.go b/trie/node_enc.go index 1b2eca682f..c95587eeab 100644 --- a/trie/node_enc.go +++ b/trie/node_enc.go @@ -40,6 +40,20 @@ func (n *fullNode) encode(w rlp.EncoderBuffer) { w.ListEnd(offset) } +func (n *fullnodeEncoder) encode(w rlp.EncoderBuffer) { + offset := w.List() + for _, c := range n.Children { + if c == nil { + w.Write(rlp.EmptyString) + } else if len(c) < 32 { + w.Write(c) // rawNode + } else { + w.WriteBytes(c) // hashNode + } + } + w.ListEnd(offset) +} + func (n *shortNode) encode(w rlp.EncoderBuffer) { offset := w.List() w.WriteBytes(n.Key) @@ -51,6 +65,27 @@ func (n *shortNode) encode(w rlp.EncoderBuffer) { w.ListEnd(offset) } +func (n *extNodeEncoder) encode(w rlp.EncoderBuffer) { + offset := w.List() + w.WriteBytes(n.Key) + + if n.Val == nil { + w.Write(rlp.EmptyString) + } else if len(n.Val) < 32 { + w.Write(n.Val) // rawNode + } else { + w.WriteBytes(n.Val) // hashNode + } + w.ListEnd(offset) +} + +func (n *leafNodeEncoder) encode(w rlp.EncoderBuffer) { + offset := w.List() + w.WriteBytes(n.Key) // Compact format key + w.WriteBytes(n.Val) // Value node, must be non-nil + w.ListEnd(offset) +} + func (n hashNode) encode(w rlp.EncoderBuffer) { w.WriteBytes(n) } @@ -58,7 +93,3 @@ func (n hashNode) encode(w rlp.EncoderBuffer) { func (n valueNode) encode(w rlp.EncoderBuffer) { w.WriteBytes(n) } - -func (n rawNode) encode(w rlp.EncoderBuffer) { - w.Write(n) -} diff --git a/trie/stacktrie.go b/trie/stacktrie.go index d194cbf0ae..2b7366c3c5 100644 --- a/trie/stacktrie.go +++ b/trie/stacktrie.go @@ -27,6 +27,7 @@ import ( var ( stPool = sync.Pool{New: func() any { return new(stNode) }} + bPool = newBytesPool(32, 100) _ = types.TrieHasher((*StackTrie)(nil)) ) @@ -47,6 +48,8 @@ type StackTrie struct { h *hasher last []byte onTrieNode OnTrieNode + kBuf []byte // buf space used for hex-key during insertions + pBuf []byte // buf space used for path during insertions } // NewStackTrie allocates and initializes an empty trie. The committed nodes @@ -56,6 +59,17 @@ func NewStackTrie(onTrieNode OnTrieNode) *StackTrie { root: stPool.Get().(*stNode), h: newHasher(false), onTrieNode: onTrieNode, + kBuf: make([]byte, 64), + pBuf: make([]byte, 64), + } +} + +func (t *StackTrie) grow(key []byte) { + if cap(t.kBuf) < 2*len(key) { + t.kBuf = make([]byte, 2*len(key)) + } + if cap(t.pBuf) < 2*len(key) { + t.pBuf = make([]byte, 2*len(key)) } } @@ -64,7 +78,8 @@ func (t *StackTrie) Update(key, value []byte) error { if len(value) == 0 { return errors.New("trying to insert empty (deletion)") } - k := t.TrieKey(key) + t.grow(key) + k := writeHexKey(t.kBuf, key) if bytes.Compare(t.last, k) >= 0 { return errors.New("non-ascending key order") } @@ -73,7 +88,7 @@ func (t *StackTrie) Update(key, value []byte) error { } else { t.last = append(t.last[:0], k...) // reuse key slice } - t.insert(t.root, k, value, nil) + t.insert(t.root, k, value, t.pBuf[:0]) return nil } @@ -129,6 +144,12 @@ const ( ) func (n *stNode) reset() *stNode { + if n.typ == hashedNode { + // On hashnodes, we 'own' the val: it is guaranteed to be not held + // by external caller. Hence, when we arrive here, we can put it back + // into the pool + bPool.Put(n.val) + } n.key = n.key[:0] n.val = nil for i := range n.children { @@ -150,8 +171,12 @@ func (n *stNode) getDiffIndex(key []byte) int { return len(n.key) } -// Helper function to that inserts a (key, value) pair into -// the trie. +// Helper function to that inserts a (key, value) pair into the trie. +// +// - The key is not retained by this method, but always copied if needed. +// - The value is retained by this method, as long as the leaf that it represents +// remains unhashed. However: it is never modified. +// - The path is not retained by this method. func (t *StackTrie) insert(st *stNode, key, value []byte, path []byte) { switch st.typ { case branchNode: /* Branch */ @@ -283,7 +308,7 @@ func (t *StackTrie) insert(st *stNode, key, value []byte, path []byte) { case emptyNode: /* Empty */ st.typ = leafNode - st.key = key + st.key = append(st.key, key...) // deep-copy the key as it's volatile st.val = value case hashedNode: @@ -318,35 +343,33 @@ func (t *StackTrie) hash(st *stNode, path []byte) { return case branchNode: - var nodes fullNode + var nodes fullnodeEncoder for i, child := range st.children { if child == nil { - nodes.Children[i] = nilValueNode continue } t.hash(child, append(path, byte(i))) + nodes.Children[i] = child.val + } + nodes.encode(t.h.encbuf) + blob = t.h.encodedBytes() - if len(child.val) < 32 { - nodes.Children[i] = rawNode(child.val) - } else { - nodes.Children[i] = hashNode(child.val) + for i, child := range st.children { + if child == nil { + continue } st.children[i] = nil stPool.Put(child.reset()) // Release child back to pool. } - nodes.encode(t.h.encbuf) - blob = t.h.encodedBytes() case extNode: // recursively hash and commit child as the first step t.hash(st.children[0], append(path, st.key...)) // encode the extension node - n := shortNode{Key: hexToCompactInPlace(st.key)} - if len(st.children[0].val) < 32 { - n.Val = rawNode(st.children[0].val) - } else { - n.Val = hashNode(st.children[0].val) + n := extNodeEncoder{ + Key: hexToCompactInPlace(st.key), + Val: st.children[0].val, } n.encode(t.h.encbuf) blob = t.h.encodedBytes() @@ -356,8 +379,10 @@ func (t *StackTrie) hash(st *stNode, path []byte) { case leafNode: st.key = append(st.key, byte(16)) - n := shortNode{Key: hexToCompactInPlace(st.key), Val: valueNode(st.val)} - + n := leafNodeEncoder{ + Key: hexToCompactInPlace(st.key), + Val: st.val, + } n.encode(t.h.encbuf) blob = t.h.encodedBytes() @@ -368,15 +393,19 @@ func (t *StackTrie) hash(st *stNode, path []byte) { st.typ = hashedNode st.key = st.key[:0] + st.val = nil // Release reference to potentially externally held slice. + // 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) + st.val = bPool.GetWithSize(len(blob)) + copy(st.val, blob) return } // Write the hash to the 'val'. We allocate a new val here to not mutate // input values. - st.val = t.h.hashData(blob) + st.val = bPool.GetWithSize(32) + t.h.hashDataTo(st.val, blob) // 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 diff --git a/trie/stacktrie_test.go b/trie/stacktrie_test.go index f053b5112d..7e342e64bf 100644 --- a/trie/stacktrie_test.go +++ b/trie/stacktrie_test.go @@ -18,6 +18,7 @@ package trie import ( "bytes" + "encoding/binary" "math/big" "testing" @@ -398,3 +399,48 @@ func TestStackTrieErrors(t *testing.T) { assert.NotNil(t, s.Update([]byte{0x10}, []byte{0xb}), "out of order insert") assert.NotNil(t, s.Update([]byte{0xaa}, []byte{0xb}), "repeat insert same key") } + +func BenchmarkInsert100K(b *testing.B) { + var num = 100_000 + var key = make([]byte, 8) + var val = make([]byte, 20) + var hash common.Hash + b.ReportAllocs() + for i := 0; i < b.N; i++ { + s := NewStackTrie(nil) + var k uint64 + for j := 0; j < num; j++ { + binary.BigEndian.PutUint64(key, k) + if err := s.Update(key, val); err != nil { + b.Fatal(err) + } + k += 1024 + } + if hash == (common.Hash{}) { + hash = s.Hash() + } else { + if hash != s.Hash() && false { + b.Fatalf("hash wrong, have %x want %x", s.Hash(), hash) + } + } + } +} + +func TestInsert100K(t *testing.T) { + var num = 100_000 + var key = make([]byte, 8) + var val = make([]byte, 20) + s := NewStackTrie(nil) + var k uint64 + for j := 0; j < num; j++ { + binary.BigEndian.PutUint64(key, k) + if err := s.Update(key, val); err != nil { + t.Fatal(err) + } + k += 1024 + } + want := common.HexToHash("0xb0071bd257342925d9d8a9f002b9d2b646a35437aa8b089628ab56e428d29a1a") + if have := s.Hash(); have != want { + t.Fatalf("hash wrong, have %x want %x", have, want) + } +} From 33756802f60f0e38744ec7f6e1fda7f8efc43b19 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 23 Jan 2025 20:38:09 +0100 Subject: [PATCH 066/940] eth/catalyst: fail on duplicate request types (#31071) Refer to: https://github.com/ethereum/execution-apis/pull/623 --- eth/catalyst/api.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 91b6511f71..37d962d070 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -1303,7 +1303,8 @@ func validateRequests(requests [][]byte) error { return fmt.Errorf("empty request: %v", req) } // Check that requests are ordered by their type. - if req[0] < last { + // Each type must appear only once. + if req[0] <= last { return fmt.Errorf("invalid request order: %v", req) } last = req[0] From f700ed9eb6b8295daf442a6f83def48820de8c82 Mon Sep 17 00:00:00 2001 From: Michael de Hoog Date: Thu, 23 Jan 2025 23:59:33 -1000 Subject: [PATCH 067/940] accounts/usbwallet: fix ledger access for latest firmware and add Ledger Flex (#31004) The latest firmware for Ledger Nano S Plus now returns `0x5000` for it's product ID, which doesn't match any of the product IDs enumerated in `hub.go`. This PR removes the assumption about the interfaces exposed, and simply checks the upper byte for a match. Also adds support for the `0x0007` / `0x7000` product ID (Ledger Flex). --- accounts/usbwallet/hub.go | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index e22dffe971..81457b7da2 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -73,7 +73,7 @@ func NewLedgerHub() (*Hub, error) { return newHub(LedgerScheme, 0x2c97, []uint16{ // Device definitions taken from - // https://github.com/LedgerHQ/ledger-live/blob/38012bc8899e0f07149ea9cfe7e64b2c146bc92b/libs/ledgerjs/packages/devices/src/index.ts + // https://github.com/LedgerHQ/ledger-live/blob/595cb73b7e6622dbbcfc11867082ddc886f1bf01/libs/ledgerjs/packages/devices/src/index.ts // Original product IDs 0x0000, /* Ledger Blue */ @@ -81,18 +81,14 @@ func NewLedgerHub() (*Hub, error) { 0x0004, /* Ledger Nano X */ 0x0005, /* Ledger Nano S Plus */ 0x0006, /* Ledger Nano FTS */ + 0x0007, /* Ledger Flex */ - 0x0015, /* HID + U2F + WebUSB Ledger Blue */ - 0x1015, /* HID + U2F + WebUSB Ledger Nano S */ - 0x4015, /* HID + U2F + WebUSB Ledger Nano X */ - 0x5015, /* HID + U2F + WebUSB Ledger Nano S Plus */ - 0x6015, /* HID + U2F + WebUSB Ledger Nano FTS */ - - 0x0011, /* HID + WebUSB Ledger Blue */ - 0x1011, /* HID + WebUSB Ledger Nano S */ - 0x4011, /* HID + WebUSB Ledger Nano X */ - 0x5011, /* HID + WebUSB Ledger Nano S Plus */ - 0x6011, /* HID + WebUSB Ledger Nano FTS */ + 0x0000, /* WebUSB Ledger Blue */ + 0x1000, /* WebUSB Ledger Nano S */ + 0x4000, /* WebUSB Ledger Nano X */ + 0x5000, /* WebUSB Ledger Nano S Plus */ + 0x6000, /* WebUSB Ledger Nano FTS */ + 0x7000, /* WebUSB Ledger Flex */ }, 0xffa0, 0, newLedgerDriver) } @@ -185,8 +181,11 @@ func (hub *Hub) refreshWallets() { for _, info := range infos { for _, id := range hub.productIDs { + // We check both the raw ProductID (legacy) and just the upper byte, as Ledger + // uses `MMII`, encoding a model (MM) and an interface bitfield (II) + mmOnly := info.ProductID & 0xff00 // Windows and Macos use UsageID matching, Linux uses Interface matching - if info.ProductID == id && (info.UsagePage == hub.usageID || info.Interface == hub.endpointID) { + if (info.ProductID == id || mmOnly == id) && (info.UsagePage == hub.usageID || info.Interface == hub.endpointID) { devices = append(devices, info) break } From 3003a13440e801174f0035037a7c83462d67a8ea Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:38:17 +0100 Subject: [PATCH 068/940] core/vm: implement EIP-2537 spec updates (#30978) Reference: - Remove MUL precompiles: https://github.com/ethereum/EIPs/pull/8945 - Pricing change for pairing operation: https://github.com/ethereum/EIPs/pull/9098 - Pricing change for add, mapping and mul operations: https://github.com/ethereum/EIPs/pull/9097 - Pricing change for MSM operations: https://github.com/ethereum/EIPs/pull/9116 --------- Co-authored-by: Marius van der Wijden --- core/vm/contracts.go | 102 +-- core/vm/contracts_test.go | 56 +- core/vm/testdata/precompiles/blsG1Add.json | 276 ++++--- core/vm/testdata/precompiles/blsG1Mul.json | 749 ++--------------- .../testdata/precompiles/blsG1MultiExp.json | 373 +++++---- core/vm/testdata/precompiles/blsG2Add.json | 276 ++++--- core/vm/testdata/precompiles/blsG2Mul.json | 759 ++---------------- .../testdata/precompiles/blsG2MultiExp.json | 326 ++++---- core/vm/testdata/precompiles/blsMapG1.json | 36 + core/vm/testdata/precompiles/blsMapG2.json | 235 +++--- core/vm/testdata/precompiles/blsPairing.json | 242 +++--- .../testdata/precompiles/fail-blsG1Mul.json | 23 +- .../precompiles/fail-blsG1MultiExp.json | 5 + .../testdata/precompiles/fail-blsG2Mul.json | 23 +- .../precompiles/fail-blsG2MultiExp.json | 5 + .../testdata/precompiles/fail-blsMapG1.json | 15 +- .../testdata/precompiles/fail-blsMapG2.json | 13 +- .../testdata/precompiles/fail-blsPairing.json | 5 + params/protocol_params.go | 19 +- tests/fuzzers/bls12381/bls12381_fuzz.go | 50 -- tests/fuzzers/bls12381/bls12381_test.go | 24 - tests/fuzzers/bls12381/precompile_fuzzer.go | 18 +- .../testdata/fuzz_g1_mul_seed_corpus.zip | Bin 37687 -> 0 bytes .../testdata/fuzz_g2_mul_seed_corpus.zip | Bin 48203 -> 0 bytes tests/state_test.go | 4 + 25 files changed, 1278 insertions(+), 2356 deletions(-) delete mode 100644 tests/fuzzers/bls12381/testdata/fuzz_g1_mul_seed_corpus.zip delete mode 100644 tests/fuzzers/bls12381/testdata/fuzz_g2_mul_seed_corpus.zip diff --git a/core/vm/contracts.go b/core/vm/contracts.go index f54d5ab86e..06849e65ad 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -129,14 +129,12 @@ var PrecompiledContractsPrague = PrecompiledContracts{ 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{0x0c}): &bls12381G1MultiExp{}, + common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{}, + common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExp{}, + common.BytesToAddress([]byte{0x0f}): &bls12381Pairing{}, + common.BytesToAddress([]byte{0x10}): &bls12381MapG1{}, + common.BytesToAddress([]byte{0x11}): &bls12381MapG2{}, } var PrecompiledContractsBLS = PrecompiledContractsPrague @@ -750,44 +748,6 @@ func (c *bls12381G1Add) Run(input []byte) ([]byte, error) { return encodePointG1(p0), nil } -// bls12381G1Mul implements EIP-2537 G1Mul precompile. -type bls12381G1Mul struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G1Mul) RequiredGas(input []byte) uint64 { - return params.Bls12381G1MulGas -} - -func (c *bls12381G1Mul) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 G1Mul precompile. - // > G1 multiplication call expects `160` bytes as an input that is interpreted as byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). - // > Output is an encoding of multiplication operation result - single G1 point (`128` bytes). - if len(input) != 160 { - return nil, errBLS12381InvalidInputLength - } - var err error - var p0 *bls12381.G1Affine - - // Decode G1 point - 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 := new(bls12381.G1Affine) - r.ScalarMultiplication(p0, e) - - // Encode the G1 point into 128 bytes - return encodePointG1(r), nil -} - // bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile. type bls12381G1MultiExp struct{} @@ -801,10 +761,10 @@ func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 { } // Lookup discount value for G1 point, scalar value pair length var discount uint64 - if dLen := len(params.Bls12381MultiExpDiscountTable); k < dLen { - discount = params.Bls12381MultiExpDiscountTable[k-1] + if dLen := len(params.Bls12381G1MultiExpDiscountTable); k < dLen { + discount = params.Bls12381G1MultiExpDiscountTable[k-1] } else { - discount = params.Bls12381MultiExpDiscountTable[dLen-1] + discount = params.Bls12381G1MultiExpDiscountTable[dLen-1] } // Calculate gas and return the result return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000 @@ -885,44 +845,6 @@ func (c *bls12381G2Add) Run(input []byte) ([]byte, error) { return encodePointG2(r), nil } -// bls12381G2Mul implements EIP-2537 G2Mul precompile. -type bls12381G2Mul struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G2Mul) RequiredGas(input []byte) uint64 { - return params.Bls12381G2MulGas -} - -func (c *bls12381G2Mul) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 G2MUL precompile logic. - // > G2 multiplication call expects `288` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). - // > Output is an encoding of multiplication operation result - single G2 point (`256` bytes). - if len(input) != 288 { - return nil, errBLS12381InvalidInputLength - } - var err error - var p0 *bls12381.G2Affine - - // Decode G2 point - 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 := new(bls12381.G2Affine) - r.ScalarMultiplication(p0, e) - - // Encode the G2 point into 256 bytes - return encodePointG2(r), nil -} - // bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile. type bls12381G2MultiExp struct{} @@ -936,10 +858,10 @@ func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 { } // Lookup discount value for G2 point, scalar value pair length var discount uint64 - if dLen := len(params.Bls12381MultiExpDiscountTable); k < dLen { - discount = params.Bls12381MultiExpDiscountTable[k-1] + if dLen := len(params.Bls12381G2MultiExpDiscountTable); k < dLen { + discount = params.Bls12381G2MultiExpDiscountTable[k-1] } else { - discount = params.Bls12381MultiExpDiscountTable[dLen-1] + discount = params.Bls12381G2MultiExpDiscountTable[dLen-1] } // Calculate gas and return the result return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000 diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index fff5c966f3..b627f2ada5 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -59,14 +59,12 @@ var allPrecompiles = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{}, - common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1Mul{}, - common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G1MultiExp{}, - common.BytesToAddress([]byte{0x0f, 0x0d}): &bls12381G2Add{}, - common.BytesToAddress([]byte{0x0f, 0x0e}): &bls12381G2Mul{}, - common.BytesToAddress([]byte{0x0f, 0x0f}): &bls12381G2MultiExp{}, - common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381Pairing{}, - common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{}, - common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{}, + common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1MultiExp{}, + common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G2Add{}, + common.BytesToAddress([]byte{0x0f, 0x0d}): &bls12381G2MultiExp{}, + common.BytesToAddress([]byte{0x0f, 0x0e}): &bls12381Pairing{}, + common.BytesToAddress([]byte{0x0f, 0x0f}): &bls12381MapG1{}, + common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381MapG2{}, } // EIP-152 test vectors @@ -306,38 +304,36 @@ func benchJson(name, addr string, b *testing.B) { func TestPrecompiledBLS12381G1Add(t *testing.T) { testJson("blsG1Add", "f0a", t) } func TestPrecompiledBLS12381G1Mul(t *testing.T) { testJson("blsG1Mul", "f0b", t) } -func TestPrecompiledBLS12381G1MultiExp(t *testing.T) { testJson("blsG1MultiExp", "f0c", t) } -func TestPrecompiledBLS12381G2Add(t *testing.T) { testJson("blsG2Add", "f0d", t) } -func TestPrecompiledBLS12381G2Mul(t *testing.T) { testJson("blsG2Mul", "f0e", t) } -func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp", "f0f", t) } -func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "f10", t) } -func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "f11", t) } -func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "f12", t) } +func TestPrecompiledBLS12381G1MultiExp(t *testing.T) { testJson("blsG1MultiExp", "f0b", t) } +func TestPrecompiledBLS12381G2Add(t *testing.T) { testJson("blsG2Add", "f0c", t) } +func TestPrecompiledBLS12381G2Mul(t *testing.T) { testJson("blsG2Mul", "f0d", t) } +func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp", "f0d", t) } +func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "f0e", t) } +func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "f0f", t) } +func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "f10", t) } 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) } -func BenchmarkPrecompiledBLS12381G2Add(b *testing.B) { benchJson("blsG2Add", "f0d", b) } -func BenchmarkPrecompiledBLS12381G2Mul(b *testing.B) { benchJson("blsG2Mul", "f0e", b) } -func BenchmarkPrecompiledBLS12381G2MultiExp(b *testing.B) { benchJson("blsG2MultiExp", "f0f", b) } -func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairing", "f10", b) } -func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "f11", b) } -func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "f12", b) } +func BenchmarkPrecompiledBLS12381G1MultiExp(b *testing.B) { benchJson("blsG1MultiExp", "f0b", b) } +func BenchmarkPrecompiledBLS12381G2Add(b *testing.B) { benchJson("blsG2Add", "f0c", b) } +func BenchmarkPrecompiledBLS12381G2MultiExp(b *testing.B) { benchJson("blsG2MultiExp", "f0d", b) } +func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairing", "f0e", b) } +func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "f0f", b) } +func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "f10", b) } // Failure tests func TestPrecompiledBLS12381G1AddFail(t *testing.T) { testJsonFail("blsG1Add", "f0a", t) } func TestPrecompiledBLS12381G1MulFail(t *testing.T) { testJsonFail("blsG1Mul", "f0b", t) } -func TestPrecompiledBLS12381G1MultiExpFail(t *testing.T) { testJsonFail("blsG1MultiExp", "f0c", t) } -func TestPrecompiledBLS12381G2AddFail(t *testing.T) { testJsonFail("blsG2Add", "f0d", t) } -func TestPrecompiledBLS12381G2MulFail(t *testing.T) { testJsonFail("blsG2Mul", "f0e", t) } -func TestPrecompiledBLS12381G2MultiExpFail(t *testing.T) { testJsonFail("blsG2MultiExp", "f0f", t) } -func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPairing", "f10", t) } -func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "f11", t) } -func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "f12", t) } +func TestPrecompiledBLS12381G1MultiExpFail(t *testing.T) { testJsonFail("blsG1MultiExp", "f0b", t) } +func TestPrecompiledBLS12381G2AddFail(t *testing.T) { testJsonFail("blsG2Add", "f0c", t) } +func TestPrecompiledBLS12381G2MulFail(t *testing.T) { testJsonFail("blsG2Mul", "f0d", t) } +func TestPrecompiledBLS12381G2MultiExpFail(t *testing.T) { testJsonFail("blsG2MultiExp", "f0d", t) } +func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPairing", "f0e", t) } +func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "f0f", t) } +func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "f10", t) } func loadJson(name string) ([]precompiledTest, error) { data, err := os.ReadFile(fmt.Sprintf("testdata/precompiles/%v.json", name)) diff --git a/core/vm/testdata/precompiles/blsG1Add.json b/core/vm/testdata/precompiles/blsG1Add.json index 14a6b16df8..991e440db7 100644 --- a/core/vm/testdata/precompiles/blsG1Add.json +++ b/core/vm/testdata/precompiles/blsG1Add.json @@ -1,730 +1,786 @@ [ - { - "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", - "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", - "Name": "bls_g1add_(g1+g1=2*g1)", - "Gas": 500, - "NoBenchmark": false - }, { "Input": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d280000000000000000000000000000000009ece308f9d1f0131765212deca99697b112d61f9be9a5f1f3780a51335b3ff981747a0b2ca2179b96d2c0c9024e522400000000000000000000000000000000032b80d3a6f5b09f8a84623389c5f80ca69a0cddabc3097f9d9c27310fd43be6e745256c634af45ca3473b0590ae30d1", "Expected": "0000000000000000000000000000000010e7791fb972fe014159aa33a98622da3cdc98ff707965e536d8636b5fcc5ac7a91a8c46e59a00dca575af0f18fb13dc0000000000000000000000000000000016ba437edcc6551e30c10512367494bfb6b01cc6681e8a4c3cd2501832ab5c4abc40b4578b85cbaffbf0bcd70d67c6e2", "Name": "bls_g1add_(2*g1+3*g1=5*g1)", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Expected": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", "Name": "bls_g1add_(inf+g1=g1)", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g1add_(inf+inf=inf)", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7", "Expected": "000000000000000000000000000000001466e1373ae4a7e7ba885c5f0c3ccfa48cdb50661646ac6b779952f466ac9fc92730dcaed9be831cd1f8c4fefffd5209000000000000000000000000000000000c1fb750d2285d4ca0378e1e8cdbf6044151867c34a711b73ae818aee6dbe9e886f53d7928cc6ed9c851e0422f609b11", "Name": "matter_g1_add_0", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed2000000000000000000000000000000000441e7f7f96198e4c23bd5eb16f1a7f045dbc8c53219ab2bcea91d3a027e2dfe659feac64905f8b9add7e4bfc91bec2b0000000000000000000000000000000005fc51bb1b40c87cd4292d4b66f8ca5ce4ef9abd2b69d4464b4879064203bda7c9fc3f896a3844ebc713f7bb20951d95", "Expected": "0000000000000000000000000000000016b8ab56b45a9294466809b8e858c1ad15ad0d52cfcb62f8f5753dc94cee1de6efaaebce10701e3ec2ecaa9551024ea600000000000000000000000000000000124571eec37c0b1361023188d66ec17c1ec230d31b515e0e81e599ec19e40c8a7c8cdea9735bc3d8b4e37ca7e5dd71f6", "Name": "matter_g1_add_1", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f00000000000000000000000000000000114c3f11ba0b47551fa28f09f148936d6b290dc9f2d0534a83c32b0b849ab921ce6bcaa4ff3c917707798d9c74f2084f00000000000000000000000000000000149dc028207fb04a7795d94ea65e21f9952e445000eb954531ee519efde6901675d3d2446614d243efb77a9cfe0ca3ae", "Expected": "0000000000000000000000000000000002ce7a08719448494857102da464bc65a47c95c77819af325055a23ac50b626df4732daf63feb9a663d71b7c9b8f2c510000000000000000000000000000000016117e87e9b55bd4bd5763d69d5240d30745e014b9aef87c498f9a9e3286ec4d5927df7cd5a2e54ac4179e78645acf27", "Name": "matter_g1_add_2", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e4000000000000000000000000000000000c3d564ac1fe12f18f528c3750583ab6af8973bff3eded7bb4778c32805d9b17846cc7c687af0f46bc87de7748ab72980000000000000000000000000000000002f164c131cbd5afc85692c246157d38dc4bbb2959d2edfa6daf0a8b17c7a898aad53b400e8bdc2b29bf6688ee863db7", "Expected": "0000000000000000000000000000000015510826f50b88fa369caf062ecdf8b03a67e660a35b219b44437a5583b5a9adf76991dce7bff9afc50257f847299504000000000000000000000000000000000a83e879895a1b47dbd6cd25ce8b719e7490cfe021614f7539e841fc2f9c09f071e386676de60b6579aa4bf6d37b13dd", "Name": "matter_g1_add_3", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d30000000000000000000000000000000019fe3a64361fea14936ff0b3e630471494d0c0b9423e6a004184a2965221c18849b5ed0eb2708a587323d8d6c6735a90000000000000000000000000000000000340823d314703e5efeb0a65c23069199d7dfff8793aaacb98cdcd6177fc8e61ab3294c57bf13b4406266715752ef3e6", "Expected": "00000000000000000000000000000000010b1c96d3910f56b0bf54da5ae8c7ab674a07f8143b61fed660e7309e626dc73eaa2b11886cdb82e2b6735e7802cc860000000000000000000000000000000002dabbbedd72872c2c012e7e893d2f3df1834c43873315488d814ddd6bfcca6758a18aa6bd02a0f3aed962cb51f0a222", "Name": "matter_g1_add_4", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90000000000000000000000000000000001461565b03a86df363d1854b4af74879115dffabeddfa879e2c8db9aa414fb291a076c3bdf0beee82d9c094ea8dc381a000000000000000000000000000000000e19d51ab619ee2daf25ea5bfa51eb217eabcfe0b5cb0358fd2fa105fd7cb0f5203816b990df6fda4e0e8d541be9bcf6", "Expected": "000000000000000000000000000000000cb40d0bf86a627d3973f1e7846484ffd0bc4943b42a54ff9527c285fed3c056b947a9b6115824cabafe13cd1af8181c00000000000000000000000000000000076255fc12f1a9dbd232025815238baaa6a3977fd87594e8d1606caec0d37b916e1e43ee2d2953d75a40a7ba416df237", "Name": "matter_g1_add_5", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1b0000000000000000000000000000000019cabba3e09ad34cc3d125e0eb41b527aa48a4562c2b7637467b2dbc71c373897d50eed1bc75b2bde8904ece5626d6e400000000000000000000000000000000056b0746f820cff527358c86479dc924a10b9f7cae24cd495625a4159c8b71a8c3ad1a15ebf22d3561cd4b74e8a6e48b", "Expected": "000000000000000000000000000000000e115e0b61c1f1b25cc10a7b3bd21cf696b1433a0c366c2e1bca3c26b09482c6eced8c8ecfa69ce6b9b3b4419779262e00000000000000000000000000000000077b85daf61b9f947e81633e3bc64e697bc6c1d873f2c21e5c4c3a11302d4d5ef4c3ff5519564729aaf2a50a3c9f1196", "Name": "matter_g1_add_6", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442a0000000000000000000000000000000011f649ee35ff8114060fc5e4df9ac828293f6212a9857ca31cb3e9ce49aa1212154a9808f1e763bc989b6d5ba7cf09390000000000000000000000000000000019af81eca7452f58c1a6e99fab50dc0d5eeebc7712153e717a14a31cffdfd0a923dbd585e652704a174905605a2e8b9d", "Expected": "000000000000000000000000000000000013e37a8950a659265b285c6fb56930fb77759d9d40298acac2714b97b83ec7692a7d1c4ccb83f074384db9eedd809c0000000000000000000000000000000003215d524d6419214568ba42a31502f2a58a97d0139c66908e9d71755f5a7666567aafe30ea84d89308f06768f28a648", "Name": "matter_g1_add_7", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795000000000000000000000000000000000d713e148769fac2efd380886f8566c6d4662dd38317bb7e68744c4339efaedbab88435ce3dc289afaa7ecb37df37a5300000000000000000000000000000000129d9cd031b31c77a4e68093dcdbb585feba786207aa115d9cf120fe4f19ca31a0dca9c692bd0f53721d60a55c333129", "Expected": "00000000000000000000000000000000029405b9615e14bdac8b5666bbc5f3843d4bca17c97bed66d164f1b58d2a148f0f506d645d665a40e60d53fe29375ed400000000000000000000000000000000162761f1712814e474beb2289cc50519253d680699b530c2a6477f727ccc75a19681b82e490f441f91a3c611eeb0e9e2", "Name": "matter_g1_add_8", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a1900000000000000000000000000000000006d92bcb599edca426ff4ceeb154ebf133c2dea210c7db0441f74bd37c8d239149c8b5056ace0bfefb1db04b42664f530000000000000000000000000000000008522fc155eef6d5746283808091f91b427f2a96ac248850f9e3d7aadd14848101c965663fd4a63aea1153d71918435a", "Expected": "000000000000000000000000000000000cfaa8df9437c0b6f344a0c8dcbc7529a07aec0d7632ace89af6796b6b960b014f78dd10e987a993fb8a95cc909822ec0000000000000000000000000000000007475f115f6eb35f78ba9a2b71a44ccb6bbc1e980b8cd369c5c469565f3fb798bc907353cf47f524ba715deaedf379cb", "Name": "matter_g1_add_9", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac9430000000000000000000000000000000016380d03b7c5cc3301ffcb2cf7c28c9bde54fc22ba2b36ec293739d8eb674678c8e6461e34c1704747817c8f8341499a000000000000000000000000000000000ec6667aa5c6a769a64c180d277a341926376c39376480dc69fcad9a8d3b540238eb39d05aaa8e3ca15fc2c3ab696047", "Expected": "0000000000000000000000000000000011541d798b4b5069e2541fa5410dad03fd02784332e72658c7b0fa96c586142a967addc11a7a82bfcee33bd5d07066b900000000000000000000000000000000195b3fcb94ab7beb908208283b4e5d19c0af90fca4c76268f3c703859dea7d038aca976927f48839ebc7310869c724aa", "Name": "matter_g1_add_10", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e00000000000000000000000000000000065eb0770ab40199658bf87db6c6b52cd8c6c843a3e40dd60433d4d79971ff31296c9e00a5d553df7c81ade533379f4b0000000000000000000000000000000017a6f6137ddd90c15cf5e415f040260e15287d8d2254c6bfee88938caec9e5a048ff34f10607d1345ba1f09f30441ef4", "Expected": "0000000000000000000000000000000006b0853b3d41fc2d7b27da0bb2d6eb76be32530b59f8f537d227a6eb78364c7c0760447494a8bba69ef4b256dbef750200000000000000000000000000000000166e55ba2d20d94da474d4a085c14245147705e252e2a76ae696c7e37d75cde6a77fea738cef045182d5e628924dc0bb", "Name": "matter_g1_add_11", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276b0000000000000000000000000000000006a3f7eb0e42567210cc1ba5e6f8c42d02f1eef325b6483fef49ba186f59ab69ca2284715b736086d2a0a1f0ea224b40000000000000000000000000000000000bc08427fda31a6cfbe657a8c71c73894a33700e93e411d42f1471160c403b939b535070b68d60a4dc50e47493da63dc", "Expected": "000000000000000000000000000000000c35d4cd5d43e9cf52c15d46fef521666a1e1ab9f0b4a77b8e78882e9fab40f3f988597f202c5bd176c011a56a1887d4000000000000000000000000000000000ae2b5c24928a00c02daddf03fade45344f250dcf4c12eda06c39645b4d56147cb239d95b06fd719d4dc20fe332a6fce", "Name": "matter_g1_add_12", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a578768100000000000000000000000000000000068e79aea45b7199ec4b6f26e01e88ec76533743639ce76df66937fff9e7de3edf6700d227f10f43e073afcc63e2eddc00000000000000000000000000000000039c0b6d9e9681401aeb57a94cedc0709a0eff423ace9253eb00ae75e21cabeb626b52ef4368e6a4592aed9689c6fca4", "Expected": "0000000000000000000000000000000013bad27dafa20f03863454c30bd5ae6b202c9c7310875da302d4693fc1c2b78cca502b1ff851b183c4b2564c5d3eb4dc0000000000000000000000000000000000552b322b3d672704382b5d8b214c225b4f7868f9c5ae0766b7cdb181f97ed90a4892235915ffbc0daf3e14ec98a606", "Name": "matter_g1_add_13", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f7680000000000000000000000000000000000adac9bb98bb6f35a8f941dbff39dfd307b6a4d5756ccae103c814564e3d3993a8866ff91581ccdd7686c1dce0b19f700000000000000000000000000000000083d235e0579032ca47f65b6ae007ce8ffd2f1a890ce3bc45ebd0df6673ad530d2f42125d543cb0c51ba0c28345729d8", "Expected": "000000000000000000000000000000000b5513e42f5217490f395a8cb3673a4fc35142575f770af75ecf7a4fcd97eee215c4298fc4feab51915137cbdb814839000000000000000000000000000000000e9d4db04b233b0b12a7ff620faefef906aeb2b15481ce1609dad50eb6a7d0c09a850375599c501296219fb7b288e305", "Name": "matter_g1_add_14", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931d000000000000000000000000000000000d5bb4fa8b494c0adf4b695477d4a05f0ce48f7f971ef53952f685e9fb69dc8db1603e4a58292ddab7129bb5911d6cea0000000000000000000000000000000004a568c556641f0e0a2f44124b77ba70e4e560d7e030f1a21eff41eeec0d3c437b43488c535cdabf19a70acc777bacca", "Expected": "000000000000000000000000000000000c27ef4ebf37fd629370508f4cd062b74faa355b305d2ee60c7f4d67dd741363f18a7bbd368cdb17e848f372a5e33a6f0000000000000000000000000000000000ed833df28988944115502f554636e0b436cccf845341e21191e82d5b662482f32c24df492da4c605a0f9e0f8b00604", "Name": "matter_g1_add_15", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000091ee883cb9ea2c933f6645f0f4c535a826d95b6da6847b4fe2349342bd4bd496e0dd546df7a7a17a4b9fb8349e5064f000000000000000000000000000000000902d7e72242a5e6b068ca82d0cb71dc0f51335dbd302941045319f9a06777518b56a6e0b0b0c9fd8f1edf6b114ad331", "Expected": "00000000000000000000000000000000122cce99f623944dfebffcdf6b0a0a3696162f35053e5952dddc2537421c60da9fe931579d1c4fc2e31082b6c25f96b500000000000000000000000000000000011366ffa91dc0b7da8b7c1839ea84d49299310f5c1ca244012eed0dd363dbcf4ad5813b8e3fb49361ef05ea8cb18ffe", "Name": "matter_g1_add_16", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000043c4ff154778330b4d5457b7811b551dbbf9701b402230411c527282fb5d2ba12cb445709718d5999e79fdd74c0a67000000000000000000000000000000000013a80ede40df002b72f6b33b1f0e3862d505efbe0721dce495d18920d542c98cdd2daf5164dbd1a2fee917ba943debe0000000000000000000000000000000000d3d4f11bc79b8425b77d25698b7e151d360ebb22c3a6afdb227de72fe432dcd6f0276b4fd3f1fcc2da5b59865053930000000000000000000000000000000015ac432071dc23148765f198ed7ea2234662745a96032c215cd9d7cf0ad8dafb8d52f209983fe98aaa2243ecc2073f1b", "Expected": "000000000000000000000000000000000113ccf11264ff04448f8c58b279a6a49acb386750c2051eab2c90fa8b8e03d7c5b9e87eccf36b4b3f79446b80be7b1d0000000000000000000000000000000004358a1fabfe803f4c787a671196b593981a837ee78587225fb21d5a883b98a15b912862763b94d18b971cb7e37dbcf0", "Name": "matter_g1_add_17", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009f9a78a70b9973c43182ba54bb6e363c6984d5f7920c1d347c5ff82e6093e73f4fb5e3cd985c9ddf9af936b16200e880000000000000000000000000000000008d7489c2d78f17b2b9b1d535f21588d8761b8fb323b08fa9af8a60f39b26e98af76aa883522f21e083c8a14c2e7edb600000000000000000000000000000000034f725766897ed76394145da2f02c92c66794a51fd5ae07bd7cc60c013d7a48ebf1b07faf669dfed74d82d07e48d1150000000000000000000000000000000018f4926a3d0f740988da25379199ecb849250239ad7efcfef7ffaa43bc1373166c0448cc30dcdbd75ceb71f76f883ea7", "Expected": "00000000000000000000000000000000167336aeeb9e447348156936849d518faee314c291c84d732fa3c1bd3951559230d94230e37a08e28e689e9d1fef05770000000000000000000000000000000005366535f7a68996e066ab80c55bb372a15fb0ed6634585b88fe7cafbf818fbfebbf6f6ddd9ca0ff72137594a1e84b35", "Name": "matter_g1_add_18", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010fcfe8af8403a52400bf79e1bd0058f66b9cab583afe554aa1d82a3e794fffad5f0e19d385263b2dd9ef69d1154f10a000000000000000000000000000000000aba6a0b58b49f7c6c2802afd2a5ed1320bf062c7b93135f3c0ed7a1d7b1ee27b2b986cde732a60fa585ca6ab7cc154b00000000000000000000000000000000079e5a154cf84190b6c735bc8cd968559182166568649b813732e4fb4c5c428c8b38e8265d4ef04990c49aa1381f51c8000000000000000000000000000000000ae08e682ef92b4986a5ac5d4f094ad0919c826a97efe8d8120a96877766eae5828803804a0cae67df9822fd18622aae", "Expected": "000000000000000000000000000000000a3d66cf87b1ce8c5683d71a6de4bf829d094041240f56d9071aa84ff189a06940e8e1935127e23a970c78ca73c28bf6000000000000000000000000000000000b2adda87740873c0c59e3ebde44d33834773f0fe69e2f5e7ede99c4f928978a5caaede7262e45fd22136a394b3f7858", "Name": "matter_g1_add_19", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013c5ebfb853f0c8741f12057b6b845c4cdbf72aecbeafc8f5b5978f186eead8685f2f3f125e536c465ade1a00f212b0900000000000000000000000000000000082543b58a13354d0cce5dc3fb1d91d1de6d5927290b2ff51e4e48f40cdf2d490730843b53a92865140153888d73d4af0000000000000000000000000000000008cefd0fd289d6964a962051c2c2ad98dab178612663548370dd5f007c5264fece368468d3ca8318a381b443c68c4cc7000000000000000000000000000000000708d118d44c1cb5609667fd51df9e58cacce8b65565ef20ad1649a3e1b9453e4fb37af67c95387de008d4c2114e5b95", "Expected": "0000000000000000000000000000000004b2311897264fe08972d62872d3679225d9880a16f2f3d7dd59412226e5e3f4f2aa8a69d283a2dc5b93e022293f0ee1000000000000000000000000000000000f03e18cef3f9a86e6b842272f2c7ee48d0ad23bfc7f1d5a9a796d88e5d5ac31326db5fe90de8f0690c70ae6e0155039", "Name": "matter_g1_add_20", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000053a12f6a1cb64272c34e042b7922fabe879275b837ba3b116adfe1eb2a6dc1c1fa6df40c779a7cdb8ed8689b8bc5ba800000000000000000000000000000000097ec91c728ae2d290489909bbee1a30048a7fa90bcfd96fe1d9297545867cbfee0939f20f1791329460a4fe1ac719290000000000000000000000000000000008e5afc16d909eb9d8bdaaf229ad291f34f7baf5247bbd4cc938278f1349adb4b0f0aacd14799c01d0ca2ed38c937d600000000000000000000000000000000006cf972c64e20403c82fee901c90eaa5547460d57cce2565fd091ff9bc55e24584595c9182298f148882d6949c36c9d5", "Expected": "000000000000000000000000000000000caf46f480ae2ea8e700f7913c505d5150c4629c9137e917357d2a4ba8a7a1c63b8f6e2978293755952fbed7f0ad8d6d0000000000000000000000000000000002e62e715b72eebbc7c366a2390318f73e69203a9533e72340aab568f65105129ffc9889a8bc00a692494d93688c7ec0", "Name": "matter_g1_add_21", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001354dd8a230fde7c983dcf06fa9ac075b3ab8f56cdd9f15bf870afce2ae6e7c65ba91a1df6255b6f640bb51d7fed302500000000000000000000000000000000130f139ca118869de846d1d938521647b7d27a95b127bbc53578c7b66d88d541adb525e7028a147bf332607bd760deac0000000000000000000000000000000013a6439e0ec0fabe93f6c772e102b96b1f692971d7181c386f7f8a360daca6e5f99772e1a736f1e72a17148d90b08efe0000000000000000000000000000000010f27477f3171dcf74498e940fc324596ef5ec6792be590028c2963385d84ef8c4bbb12c6eb3f06b1afb6809a2cb0358", "Expected": "000000000000000000000000000000000dea57d1fc19f994e6bdda9478a400b0ada23aed167bfe7a16ef79b6aa020403a04d554303c0b2a9c5a38f85cf6f3800000000000000000000000000000000000b8d76ccd41ba81a835775185bbf1d6bf94b031d94d5c78b3b97beb24cf246b0c25c4c309e2c06ae9896ed800169eeee", "Name": "matter_g1_add_22", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f76a6dc6da31a399b93f4431bfabb3e48d86745eaa4b24d6337305006e3c7fc7bfcc85c85e2f3514cd389fec4e70580000000000000000000000000000000010e4280374c532ed0df44ac0bac82572f839afcfb8b696eea617d5bd1261288dfa90a7190200687d470992fb4827ff320000000000000000000000000000000005728a219d128bc0a1f851f228e2bf604a72400c393cfb0d3484456b6b28a2c5061198656f0e106bbe257d849be159040000000000000000000000000000000011f6d08baa91fb2c8b36191d5b2318e355f8964cc8112838394ba1ded84b075de58d90452601dcfc9aa8a275cfec695d", "Expected": "0000000000000000000000000000000012e6d6c518c15cfd3020181ff3f829e29140b3b507b99251cc7f31795128adec817750296bce413bac18b9a80f69ca5000000000000000000000000000000000131ee9b748f6f1eb790adeb9edd0e79d89a9908368f5a6bb82ee0c913061cdfffe75d9ba411a49aa3f9194ee6d4d08a9", "Name": "matter_g1_add_23", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009439f061c7d5fada6e5431c77fd093222285c98449951f6a6c4c8f225b316144875bc764be5ca51c7895773a9f1a640000000000000000000000000000000000ebdef273e2288c784c061bef6a45cd49b0306ac1e9faab263c6ff73dea4627189c8f10a823253d86a8752769cc4f8f200000000000000000000000000000000171696781ba195f330241584e42fb112adf9b8437b54ad17d410892b45c7d334e8734e25862604d1b679097590b8ab0a000000000000000000000000000000001879328fdf0d1fb79afd920e0b0a386828be5b8e0e6024dfeea800ffcb5c65f9044061af26d639d4dcc27bcb5ba1481a", "Expected": "00000000000000000000000000000000111c416d5bd018a77f3317e3fbf4b03d8e19658f2b810dc9c17863310dfb09e1c4ffdbb7c98951d357f1c3d93c5d0745000000000000000000000000000000000af0a252bff336d5eb3a406778557ef67d91776a9c788be9a76cff7727f519a70fc7809f1a50a58d29185cb9722624fd", "Name": "matter_g1_add_24", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001478ee0ffebf22708a6ab88855081daba5ee2f279b5a2ee5f5f8aec8f97649c8d5634fec3f8b28ad60981e6f29a091b10000000000000000000000000000000011efaeec0b1a4057b1e0053263afe40158790229c5bfb08062c90a252f59eca36085ab35e4cbc70483d29880c5c2f8c2000000000000000000000000000000000231b0d6189a4faad082ce4a69398c1734fcf35d222b7bce22b14571033a1066b049ae3cd3bd6c8cec5bec743955cdd600000000000000000000000000000000037375237fb71536564ea693ab316ae11722aadd7cab12b17b926c8a31bd13c4565619e8c894bffb960e632896856bbe", "Expected": "000000000000000000000000000000000d2b9c677417f4e9b38af6393718f55a27dbd23c730796c50472bc476ebf52172559b10f6ceb81e644ec2d0a41b3bb01000000000000000000000000000000001697f241ff6eceb05d9ada4be7d7078ecbbffa64dd4fb43ead0692eef270cb7cc31513ee4bf38a1b1154fe008a8b836a", "Name": "matter_g1_add_25", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000150d43c64cb1dbb7b981f455e90b740918e2d63453ca17d8eeecb68e662d2581f8aa1aea5b095cd8fc2a941d6e2728390000000000000000000000000000000006dc2ccb10213d3f6c3f10856888cb2bf6f1c7fcb2a17d6e63596c29281682cafd4c72696ecd6af3cce31c440144ebd10000000000000000000000000000000015653d1c5184736cdc78838be953390d12b307d268b394136b917b0462d5e31b8f1b9d96cce8f7a1203c2cae93db6a4000000000000000000000000000000000060efeece033ac711d500c1156e4b6dce3243156170c94bc948fd7beae7b28a31463a44872ca22ca49dc5d4d4dd27d1c", "Expected": "0000000000000000000000000000000003996050756117eeab27a5e4fa9acdde2a1161d6fbfff2601a1c7329f900e93a29f55a8073f85be8f7c2a4d0323e95cc00000000000000000000000000000000010b195a132c1cba2f1a6a73f2507baa079e9b5cb8894ea78bebc16d4151ee56fe562b16e2741f3ab1e8640cdad83180", "Name": "matter_g1_add_26", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f46bb86e827aa9c0c570d93f4d7d6986668c0099e4853927571199e1ce9e756d9db951f5b0325acafb2bf6e8fec2a1b0000000000000000000000000000000006d38cc6cc1a950a18e92e16287f201af4c014aba1a17929dd407d0440924ce5f08fad8fe0c50f7f733b285bf282acfc0000000000000000000000000000000018adb42928304cbc310a229306a205e7c21cdb31b9e5daf0ff6bb9437acee80cd8cf02b35dab823155d60f8a83fde5cc0000000000000000000000000000000018b57460c81cab43235be79c8c90dcda40fafcaf69e4e767133aee56308a6df07eac71275597dd8ed6607ffb9151ed9a", "Expected": "0000000000000000000000000000000003c7a7ee3d1b73cf1f0213404363bf3c0de4425ab97d679ed51448e877b7537400f148f14eba588ed241fea34e56d465000000000000000000000000000000000c581b5070e6bb8582b7ee2cd312dfeb5aaf0b0da95cf5a22a505ffba21fc204e26a5e17311d1f47113653ff13349f57", "Name": "matter_g1_add_27", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010cde0dbf4e18009c94ba648477624bbfb3732481d21663dd13cea914d6c54ec060557010ebe333d5e4b266e1563c631000000000000000000000000000000000fb24d3d4063fd054cd5b7288498f107114ff323226aca58d3336444fc79c010db15094ceda6eb99770c168d459f0da00000000000000000000000000000000001da65df8574a864ab454e5f2fa929405501bb73c3162a600979a1145586079361c89839cc0c5a07f1135c94bf059f9c0000000000000000000000000000000002560df402c0550662a2c4c463ad428ab6e60297fbc42a6484107e397ae016b58494d1c46ac4952027aa8c0896c50be3", "Expected": "000000000000000000000000000000000d7a539b679e5858271a6f9cf20108410eb5d5d2b1a905e09a8aa20318efbe9175450385d78389f08f836f5634f7a2f0000000000000000000000000000000000fb624e5f6c4c814b7d73eb63b70237c5de7d90d19ac81cac776d86171a8d307d3cc8c56da14f444fe8cf329ab7e63dd", "Name": "matter_g1_add_28", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008c0a4c543b7506e9718658902982b4ab7926cd90d4986eceb17b149d8f5122334903300ad419b90c2cb56dc6d2fe976000000000000000000000000000000000824e1631f054b666893784b1e7edb44b9a53596f718a6e5ba606dc1020cb6e269e9edf828de1768df0dd8ab8440e0530000000000000000000000000000000005311c11f4d0bb8542f3b60247c1441656608e5ac5c363f4d62127cecb88800a771767cf23a0e7c45f698ffa5015061f0000000000000000000000000000000018f7f1d23c8b0566a6a1fcb58d3a5c6fd422573840eb04660c3c6ba65762ed1becc756ac6300e9ce4f5bfb962e963419", "Expected": "0000000000000000000000000000000000849bbc7b0226b18abbcb4c9a9e78dca2f5f75a2cbb983bd95ff3a95b427b1a01fd909ce36384c49eb88ffb8ff77bb000000000000000000000000000000000087d8d28d92305b5313ca533a6b47f454ddce1c2d0fa3574b255128ef0b145fa4158beb07e4f0d50d6b7b90ea8a8ea8a", "Name": "matter_g1_add_29", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000159d94fb0cf6f4e3e26bdeb536d1ee9c511a29d32944da43420e86c3b5818e0f482a7a8af72880d4825a50fee6bc8cd8000000000000000000000000000000000c2ffe6be05eccd9170b6c181966bb8c1c3ed10e763613112238cabb41370e2a5bb5fef967f4f8f2af944dbef09d265e000000000000000000000000000000000c8e293f730253128399e5c39ab18c3f040b6cd9df10d794a28d2a428a9256ea1a71cf53022bd1be11f501805e0ddda40000000000000000000000000000000003e60c2291be46900930f710969f79f27e76cf710efefc243236428db2fed93719edeeb64ada0edf6346a0411f2a4cb8", "Expected": "00000000000000000000000000000000191084201608f706ea1f7c51dd5b593dda87b15d2c594b52829db66ce3beab6b30899d1d285bdb9590335949ceda5f050000000000000000000000000000000000d3460622c7f1d849658a20a7ae7b05e5afae1f01e871cad52ef632cc831b0529a3066f7b81248a7728d231e51fc4ad", "Name": "matter_g1_add_30", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad6242000000000000000000000000000000000353d6521a17474856ad69582ce225f27d60f5a8319bea8cefded2c3f6b862d76fe633c77ed8ccdf99d2b10430253fc80000000000000000000000000000000013267db8fdf8f488a2806fead5cffdcbb7b1b4b7681a2b67d322cd7f5985c65d088c70cdc2638e679ed678cae3cc63c80000000000000000000000000000000007757233ad6d38d488c3d9d8252b41e4ab7ee54e4ef4bbf171402df57c14f9977dd3583c6c8f9b5171b368d61f082447", "Expected": "000000000000000000000000000000000c06fef6639ab7dceb44dc648ca6a7d614739e40e6486ee9fc01ecc55af580d98abc026c630a95878da7b6d5701d755c0000000000000000000000000000000007c9a7f2bc7fa1f65c9e3a1e463eb4e3283e47bb5490938edb12abf6c8f5a9b56d8ce7a81a60df67db8c399a9a1df1d4", "Name": "matter_g1_add_31", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff17000000000000000000000000000000001975bc52669187f27a86096ae6bf2d60178706105d15bce8fe782759f14e449bc97cb1570e87eec5f12214a9ae0e0170000000000000000000000000000000000ca6106d6e6487a3b6f00fc2af769d21cb3b83b5dc03db19e4824fc28fd9b3d9f7a986e79f05c02b3a914ff26c7a78d6", "Expected": "0000000000000000000000000000000002fbf4fba68ae416b42a99f3b26916dea464d662cebce55f4545481e5ab92d3c40f3e189504b54db4c9cd51ecdd60e8d0000000000000000000000000000000008e81e094c6d4ded718ef63c5edfacb2d258f48ccfa37562950c607299bb2dca18e680a620dff8c72dedc89b4e9d4759", "Name": "matter_g1_add_32", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c8129292540000000000000000000000000000000013a3d49e58274c2b4a534b95b7071b6d2f42b17b887bf128627c0f8894c19d3d69c1a419373ca4bd1bb6d4efc78e1d3f00000000000000000000000000000000109f6168a719add6ea1a14f9dc95345e325d6b0e56da2f4ecff8408536446894069fa61e81bdaebfc96b13b402fad865000000000000000000000000000000001806aa27c576f4c4fa8a6db49d577cd8f257a8450e89b061cbc7773c0b5434f06bacf12b479abf6847f537c4cbefcb46", "Expected": "0000000000000000000000000000000014e0bd4397b90a3f96240daf835d5fb05da28a64538f4bf42d9e7925a571f831c6e663910aa37dcc265ddd7938d83045000000000000000000000000000000001695d405d4f8ba385ebf4ad25fb3f34c65977217e90d6e5ed5085b3e5b0b143194f82e6c25766d28ad6c63114ca9dcdf", "Name": "matter_g1_add_33", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda0000000000000000000000000000000014a461f829e0a76ba89f42eb57dffb4f5544df2008163bd0ea1af824f7ff910b27418a0e4f86cb8046dc1f3139cab9af0000000000000000000000000000000019d3623a7866933e2d73214ceb2e56097a1b047db5943c3ecb846890aa02250126e90fc76a729a952cef895bd154cc7d000000000000000000000000000000000e87c376bbd695a356ef72226ac7ef6a550d99e9693d8485770a686e568ae28c038ee201d3f2ea38362046236ade91cd", "Expected": "000000000000000000000000000000000ffeab47985bd9b3e10ce27c6636bbda336dcf540cd37eccc3faec2adff2d97dd126633bd83a7d3c8c73c3623bdf0ba2000000000000000000000000000000001992eca4b1e924b360d57ca98b543ab496a8b55bd288d23f03bcc1b22f6bc76d95b12f47c3e305812097253c73b876dd", "Name": "matter_g1_add_34", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000016404bd07b6c6480af2d23301940e61817ee2e61fc625c100b31e1b324c369a583b61048dd57ab97b80b1fe6cd64c5c300000000000000000000000000000000163aaecf83d6c77a5d7417e73f5cf9d71a6aedfd194b2f3b53c608d06a228190f4f79ac57b029d77504c72744df4ecc0000000000000000000000000000000000416e6f9ca188d16daa2c28acd6a594f8fcb990eaa26e60ca2a34dfcad7ad76c425b241acedf674d48d298d0df0f824d", "Expected": "000000000000000000000000000000001812bcb26fa05e0ab5176e703699ab16f5ef8917a33a9626ae6ff20f2a6f4a9d5e2afe3a11f57061cbaa992e1f30477f000000000000000000000000000000000680acf0b632cb48017cb80baa93753d030aa4b49957178d8a10d1d1a27bbdc89ac6811a91868b2c181c5c0b9b6caf86", "Name": "matter_g1_add_35", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a0300000000000000000000000000000000053ee41f6a51c49b069f12de32e3e6b0b355cd2c3ba87a149c7de86136a5d9c5b7b59f2d1237964e548d1b62ec36c8db000000000000000000000000000000000aba7362eee717d03ef2d4f0fef2763822115fcc8fb9e2e8243683b6c1cde799ebc78f23812e557de2cc38e2b4a2e56700000000000000000000000000000000170833db69b3f067cf5c4c4690857e6711c9e3fcad91ca7cd045e9d2f38c7b31236960e8718f5dd4c8bfb4de76c6c9b9", "Expected": "00000000000000000000000000000000196ffe76a4b726fa8dd720cc1cd04c040724cb18ec10915e312eaa90d124100b08f0ce3a7fc888f46914319a3d7581f4000000000000000000000000000000000e2612357059ca6dbb64efb98ef19370560c9e83e2aad7ab2d9015e2444fe4d8c796b5577584aac9f63258beb5ae863c", "Name": "matter_g1_add_36", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000009cd91a281b96a881b20946fda164a987243c052378fcd8fee3926b75576dfa1d29a0aaca4b653da4e61da8257721808000000000000000000000000000000000a98ae36c690f2e3be8100f43678be5a1064390e210328dd23f61f5a496b87398db2798580edeabc6273fb9537fa12880000000000000000000000000000000009aedf77bb969592c6552ae0121a1c74de78ba222b6cd08623c7a34708a12763b5ff7969cf761ccd25adc1b65da0f02d", "Expected": "00000000000000000000000000000000072334ec8349fc38b99d6dea0b4259c03cd96c1438c90ef0da6321df2495892de031a53c23838ca2b260774fa09b5461000000000000000000000000000000000e4535767c2477c4f87c087540c836eeffcd0c45960841f9c3561a8a5f8e61ab98b183b11192b8e7ea1c9c7717336243", "Name": "matter_g1_add_37", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000011bf87b12734a6360d3dda4b452deede34470fba8e62a68f79153cc288a8e7fed98c74af862883b9861d2195a58262e00000000000000000000000000000000015c3c056ec904ce865d073f8f70ef2d4b5adb5b9238deaa5e167d32f45cad4901aa6d87efa2338c633e7853ce4c19185000000000000000000000000000000000a15f1aa6e662f21d7127351a1655821c943c4cf590e3c9e60c9ab968b4a835f87fb8d87eee6331ee4e194e5f1ea91f4", "Expected": "000000000000000000000000000000000140fb6dcf872d0a3bff3e32a0cb4a7fb7e60ee4fb476bb120c4ce068e169d72e1c167d7fda321280d5855983d5a9af800000000000000000000000000000000108f54a4ec3ba26dd614f4d94c5c82652583906986158ad40ffea54c17703fa4b0bd7806633e1c0318d06e8dc7d41cde", "Name": "matter_g1_add_38", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000f26fdf1af1b8ad442ef4494627c815ca01ae84510944788b87f4aa2c8600ed310b9579318bc617a689b916bb7731dcb000000000000000000000000000000000307841cb33e0f188103a83334a828fa864cea09c264d5f4343246f64ab244add4610c9ccd64c001816e5074fe84013f000000000000000000000000000000000e15bbeb6fff7f1435097828f5d64c448bbc800f31a5b7428436dcffd68abc92682f2b01744d7c60540e0cd1b57ab5d4", "Expected": "000000000000000000000000000000000a1b50660ed9120fff1e5c4abb401e4691a09f41780ca188cea4b1c2d77002f08ce28eb1caa41ee3fe73169e3651bb7f00000000000000000000000000000000125439ac3b45c698a98063ab911364bd3c6dd2a69435d00d6edf89fc5566b33038e960a125e5e52141abb605587942fe", "Name": "matter_g1_add_39", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a370000000000000000000000000000000003d2c7fe67cada2213e842ac5ec0dec8ec205b762f2a9c05fa12fa120c80eba30676834f0560d11ce9939fe210ad6c6300000000000000000000000000000000013866438b089d39de5a3ca2a624d72c241a54cbdcf5b2a67ebdd2db8373b112a814e74662bd52e37748ffbfc21782a5000000000000000000000000000000000d55454a22d5c2ef82611ef9cb6533e2f08668577764afc5bb9b7dfe32abd5d333147774fb1001dd24889775de57d305", "Expected": "000000000000000000000000000000000037b4e8846b423335711ac12f91e2419de772216509d6b9deb9c27fd1c1ee5851b3e032bf3bcac3dd8e93f3dce8a91b00000000000000000000000000000000113a1bf4be1103e858c3be282effafd5e2384f4d1073350f7073b0a415ecf9e7a3bfb55c951c0b2c25c6bab35454ecf0", "Name": "matter_g1_add_40", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000b02ca2b0e6e0989ea917719b89caf1aa84b959e45b6238813bf02f40db95fbb3bf43d3017c3f9c57eab1be617f180320000000000000000000000000000000017440fd557df23286da15f9a96bb88cfbc79589b1c157af13baf02c65227dc0a5bdec6f2f300083ff91dae395ed8cb75000000000000000000000000000000000ad09b4290842cc599d346110fdb39ededbb1d651568579564e274465f07b8f77eeaf00fece0c10db69c2125de8ab394", "Expected": "0000000000000000000000000000000007c158b4e21566742f7e4e39a672bd383e27864505acef4ef8c26f8b0a9db418f9c088b555b8e9eb25acf9859b1207b40000000000000000000000000000000016e06a1ace89f992d582af0de7662ef91c0a98f574306f6f6d0d8d5e80166638d2deef70105cce2e9b20faa9d6315510", "Name": "matter_g1_add_41", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c187229000000000000000000000000000000000096713619bf088bd9e12752cab83e9cdd58296ada8d338c86a749f00ba014087a3836ce10adaaf2e815f431235bff4f0000000000000000000000000000000000d7ccc3a4efdfe1a92a88e453933b8216016091f1b9d575faf18a5b3abf90daf077813167a3f4acce7359472dee544bb00000000000000000000000000000000128008c075ab176100e755cbb8de5b9ff0e9a78114f862d26ed030d9c1d1dea1c21ec8ae4d82a84d3ff5ae4c1cd6f339", "Expected": "000000000000000000000000000000000b84f9de79c748e37797c629cb78b86b4b736b199f161b30147b5dacf6eabe0b54afce40d5dacfe9a8ee8da5ef5b49de0000000000000000000000000000000010277ad094bb9a3b96379b1366dd90125b51a21ebeb4f776a81d9d9c1f37ab58c32a884a26fa32c83783ed0eef42b820", "Name": "matter_g1_add_42", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a90000000000000000000000000000000002b03f02b45aa15b39e030c4b88c89a285dff5c4bbfe16f643f3f87d91db774f8ab7019285fda0b236ff7eec16496e5e00000000000000000000000000000000008da4a93d5ffcdaa0adc736a59f0c187ae3bf11ecb5e9e6f6aedea976a47757739042200b4c4593c2dd5db555425531000000000000000000000000000000000a6fdb2d4160c6c35223daa6fa10d0b1073de07fe4f2eba28e65ed049ff8d8852ed0538b30759fe7a0d944009ddf9a6f", "Expected": "000000000000000000000000000000000d740bd1effd8674250618af0358ad0b83bbc787f0264af9c2ada72fa5431be909e82155da1de0211f46fb307e9949f0000000000000000000000000000000000ddf62c91d587a14b64feef07da52c081b40fbbf9a0f2eae8b66022e0850fc94de6a467e7e4f580c7f2c806f6c6ed8cf", "Name": "matter_g1_add_43", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb00000000000000000000000000000000185e8671e2ddb8e36380e39fe4eafefbac9769935603c28caac7d3f7f0f3e8ad14e925024b55aeb67d68b219875c9d790000000000000000000000000000000003258d7931a1d72ab6344c7e96c0dbd435a7909fe68cc679c08ca9b62f7a6a04863082cbcfdbe9a736625d895e4f3bdb0000000000000000000000000000000009ee3e470e2b2cebc955ba3444b7e478f887138e36c13bd68490689122627269ea5e7ce22dd9c69792394a24187103d6", "Expected": "000000000000000000000000000000000af674691f5d87655f0066188fac5013f31b4169a0181d3feb7ac3beae0d9a3429d4125f099ee344f644a2de8b941f9f00000000000000000000000000000000042a9603b8e4a6c37d59ede3a1398f5f80c5298da66de575a204ee28811d9f7c7c0dd40cef3769bd72a2156b9eb620c8", "Name": "matter_g1_add_44", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e2700000000000000000000000000000000123f973ab6bd3c2e5b0512a0c77ea0ac3003fd891e1262137f9444cd07b927b564e618205ba09220320ea1aa4564e820000000000000000000000000000000001833807f1ced52399305419450355499a63411837ee61ad681559d59561db18511eb1e8ad3161e7fe30016b560d18b8f00000000000000000000000000000000198b11b31586e17964a4a4ccdee85703163d2106481833e71f26327a589bafb43578d08d87f6cb19c7a04b4ca92392bf", "Expected": "000000000000000000000000000000001081c3359a0fadfe7850ce878182859e3dd77028772da7bcac9f6451ac6455739c22627889673db626bbea70aa3648d50000000000000000000000000000000000f4e8766f976fa49a0b05ef3f06f56d92fe6452ff05c3fac455f9c16efadf1b81a44d2921bed73511dda81d6fc7478e", "Name": "matter_g1_add_45", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000002ec930fb58c898ede931384c5a5f9edd2f5c70b8c3794edb83a12f23be5400949f95e81c96c666c1a72dffb50b811580000000000000000000000000000000007dc719ae9e3f1e11d3ed4747a546a7b973ccb1967adb1b3066645a8bde9632bcfa3530e768f088ddbc022b169e67cbf000000000000000000000000000000000bbf9cf884b19c84045da1cead7dcd9fdbf39d764ff1ad60d83ed1e4fd0ce0554f0fb618203952cf02a7c4ba466c66b8", "Expected": "000000000000000000000000000000000f60d66fd1ed5eb04f9619d6458c522cc49f5ace111aff2b61903b112559972f80ac615591463abf2b944c4f99d4c03e000000000000000000000000000000000001a1abfa869be2cda6bd7e05454a8735e1b638db7e1b3715708539c2d14ade53069c7e68b36d3b08cff80837028b7d", "Name": "matter_g1_add_46", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f100000000000000000000000000000000033f481fc62ab0a249561d180da39ff641a540c9c109cde41946a0e85d18c9d60b41dbcdec370c5c9f22a9ee9de00ccd0000000000000000000000000000000014b78c66c4acecdd913ba73cc4ab573c64b404a9494d29d4a2ba02393d9b8fdaba47bb7e76d32586df3a00e03ae2896700000000000000000000000000000000025c371cd8b72592a45dc521336a891202c5f96954812b1095ba2ea6bb11aad7b6941a44d68fe9b44e4e5fd06bd541d4", "Expected": "0000000000000000000000000000000015b164c854a2277658f5d08e04887d896a082c6c20895c8809ed4b349da8492d6fa0333ace6059a1f0d37e92ae9bad30000000000000000000000000000000001510d176ddba09ab60bb452188c2705ef154f449bed26abf0255897673a625637b5761355b17676748f67844a61d4e9f", "Name": "matter_g1_add_47", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be10000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe900000000000000000000000000000000104ee0990ba4194916f670f44e254200971b67a18ed45b25c17be49df66e4f9b934bac8c1552ecc25bdaa3af55952076000000000000000000000000000000000591094d9d89afe025ca1832d7f3e60444f83e72403a434b42216b6c4213980d29e4ef0c64ae497006de550c1faa9425", "Expected": "0000000000000000000000000000000006db0cc24ffec8aa11aecc43e9b76a418daac51d51f3de437090c1bcaabace19f7f8b5ceb6277d6b32b7f3b239a90c4700000000000000000000000000000000069e01f60ca7468c6b9a247c79d18cf3d88bf5d1d62c76abf9237408edeba05dea744205ac5b501920f519bb847bb711", "Name": "matter_g1_add_48", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000fa57c1436615442bbb049d08ac46e501c07736cd239298752bb94d1904bd38cc687759987cadd99bd3c4d45ba07193a0000000000000000000000000000000004840d028d0c0f056aeb37b7a8505325081e9822ef26046f2da72f2155c20987dd51f4b5577c5395e24288b71d2ce5140000000000000000000000000000000015f231a233e997633c1d6492e0df358fb658ae29d0f53928c8a0578484c899a699178ca3223772210063aa08991c3fff", "Expected": "000000000000000000000000000000000fa72bf2d7d564cc4982b9f2cdca743d2ac14f0f1be4218dbafb8b93a9277e55273487a5d2857fd3f731ac4ee469a6a1000000000000000000000000000000000fce44f886453c6ca5ebde9af41d2be92d1126e9897d72978a179dd7eebeed6242b6e9718604ab0c9369529a0426a575", "Name": "matter_g1_add_49", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b600000000000000000000000000000000175bdd42583cbbf733242510c152380525aff7649273acef1ec20569804ffba7f029ca06878dbafde84540cece1738220000000000000000000000000000000004877b97faa1d05d61ab65001110bf190d442cabcd6d4d1b9c1f0e513309aebd278f84a80354dfdef875769d00ec2c7500000000000000000000000000000000187066cccb5008bc2ffd0bcd1b227a5a0fe0cd4984316ba3cfd5113c4632a04c56cbda8d48993bd0dd50e9b7ce2b7ee9", "Expected": "0000000000000000000000000000000019ecd38afacc6b281b2515270157328e18039d51574bae0f7e0ef16c3f6da89f55ddee9e3bbb450ad51fe11edfd9f18d00000000000000000000000000000000088a5e292761bbf7a914a9f723de099035e91bd3c1fe9cd50728a4ceaa4fd3953683f30aa8e70ba0eb23919092aa9e22", "Name": "matter_g1_add_50", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000cbf7a31e6fef4f4664bca4bc87ec7c0b12ced7224300aa4e1a6a7cbdedfcef07482b5d20fa607e3f03fdd6dd03fd10c000000000000000000000000000000001881f5aba0603b0a256e03e5dc507598dd63682ce80a29e0fa141b2afdadf6168e98221e4ee45d378cee0416baaadc49000000000000000000000000000000000070d255101319dd3a0f8ca3a0856188428c09de15475d6b70d70a405e45ab379a5b1f2e55f84bd7fe5dd12aeedce670", "Expected": "0000000000000000000000000000000011ccd455d5e3eba94567a17bcd777559b4ff1afa66fd6f05f99c69937404290a2f1c83cfd6c2c25886ebff4934332c0e0000000000000000000000000000000010920aa3d5974df25530610ef466adce3d51fd6a508d4b1111739c586dfd7ba9040836e075fd812fe111d92f25b67f51", "Name": "matter_g1_add_51", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa0000000000000000000000000000000005aa892b0a056ff61706430f1daa3f0263dc01337eadabd8a7fd58152affd9aaa329e8c11ea98692134d9718cb4119bf000000000000000000000000000000000b53e5339f25bcd31afd091362874b5042c0b762ed7425341331630addbc4dccc299936e1acdf89823c36867d46c6f28000000000000000000000000000000000fc3c6b522268511dd52826dd1aee707413d925ee51aeb0e5d69c0e3eb697fabbc14783b5007e240cc0c53c299a40ada", "Expected": "00000000000000000000000000000000060773b9b8f3babdba3db27089b7be3e6e287a635dbae19576039d34ae18a0e6413278bfa280570f6329ae05cdb693fd00000000000000000000000000000000075fb9527f99a8c8db41e67baaf1deafffd2c134badb1b3478a26b5501b31dca858fad6f0d52f412d5631ecfa72eece4", "Name": "matter_g1_add_52", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a0300000000000000000000000000000000166ce33c0482b5957c6e746c16908ba579d6402b230bc977d3ff29ac2a4a800748d9c14608f2519e2ac4d1fe4daf29b2000000000000000000000000000000001693f4ebab3fed548784264196fb01cf55311399f47cdad74a9543bda5d1ca682a00ee04bb0b3954d5a0f00ceef97a750000000000000000000000000000000017f4019c23bd68e84d889857c417b17aa96c780fec3c1ed6ca75100cc70c97a8bb8272ad4c6de896d76dc2a1b09c7a61", "Expected": "000000000000000000000000000000000a3ea8afdc83794f18f9a9427bcd60a355196925d38fdf74ab09d4a08279647b2da6f1fbe30948a785497d6c6dddc2a9000000000000000000000000000000001263c88f1ca3e574cafac21641432d45ee01e1b05eba95716565922abe28c7f0fb004c255afcbfa10cf7959bbe6b00d7", "Name": "matter_g1_add_53", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f6046300000000000000000000000000000000148b5454f9b9868aefd2accc3318ddabfe618c5026e8c04f8a6bce76cd88e350bebcd779f2021fe7ceda3e8b4d438a0b0000000000000000000000000000000005d5602e05499a435effff3812744b582b0cd7c68f1c88faa3c268515c8b14f3c041b8ae322fe526b2406e7c25d84e61000000000000000000000000000000001038eaf49e74e19111e4456ebba01dc4d22c7e23a303d5dec821da832e90a1b07b1a6b8034137f1bfdcddeb58053a170", "Expected": "0000000000000000000000000000000019258ea5023ce73343dcd201ec9be68ec1ee1cb4e5b9964309d801c2bc523343c8ebc4f8393a403c7881e5928f29db14000000000000000000000000000000001423bf52daefb432162ce2bd9ef78b256ff3b24d0a84766b87119489fd56ecf6156b2884c8a7e1220e493469723cd7f8", "Name": "matter_g1_add_54", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a00000000000000000000000000000000016d2c22eabd4a06a5ae67b890a25fbede7d0e96c625b80329b19be6aa861f44b6e85778130d0bdf69f2abd491ee9751a0000000000000000000000000000000002626f28d421d9d1c28f5e1eb5a51ada9610dbdd62cd33c4078d2fdfc18dbd092e2847cf705ba5fcd8c1a60c1cc34a3b0000000000000000000000000000000001f7b8cfdb7e406c920f5fdecae45fb4be736f209480ccb455f972c6b1a1aebdd5ba116903c46ded72ce37cd8836e871", "Expected": "00000000000000000000000000000000081d674f5b9c7c64673c39fe33f4f3d77271e826dcb4dfd2591062e47c931237e8539ef9c886c9e112eccc50da4f63fd00000000000000000000000000000000141b700695839110ed4ced5f8a3f4fd64a8086805358ab4a5abd2705592e616cd95ff01271212ca9014dcb68d8157ba0", "Name": "matter_g1_add_55", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000f1afe9b199362f51cc84edb1d3cf2faf8e5bc0a734a646851ab83e213f73a3734114f255b611ec18db75694dcb0df91000000000000000000000000000000000259e307eacb1bc45a13811b02a7aeaaf4dc2bb405dcd88069bb6ec1c08a78905516169bd3440a36921764df0ef3a85b000000000000000000000000000000001263372b675124f6cc19ca16842ba069c5697dbf57730875fe72c864a81189d7d16fe126b5d24953a0524f96dbac5183", "Expected": "000000000000000000000000000000001908aa3a640817e31a4213156fbd4fd39ab39eb931091670a0e06399def71a689e67286f90d38ce9f97cb85f6488d9c8000000000000000000000000000000000764e46b6b82aa2f8862d28e9d543a751a9de855645377b9633cc098c2110ec6ed4fd30f0044ea5868c93f950f6cfd24", "Name": "matter_g1_add_56", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000019275491a51599736722295659dd5589f4e3f558e3d45137a66b4c8066c7514ae66ec35c862cd00bce809db528040c04000000000000000000000000000000000a138203c916cb8425663db3bbff37f239a5745be885784b8e035a4f40c47954c48873f6d5aa06d579e213282fe789fa0000000000000000000000000000000016897b8adbc3a3a0dccd809f7311ba1f84f76e218c58af243c0aa29a1bb150ed719191d1ced802d4372e717c1c97570a", "Expected": "0000000000000000000000000000000004ad79769fd10081ebaaed9e2131de5d8738d9ef143b6d0fa6e106bd82cfd53bbc9fab08c422aa03d03896a0fb2460d0000000000000000000000000000000000bb79356c2d477dfbcb1b0e417df7cb79affbe151c1f03fa60b1372d7d82fd53b2160afdd88be1bf0e9dc99596366055", "Name": "matter_g1_add_57", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000a896c5a84cbd03e52ae77000eb0285f5704993664a744a89ff6b346efd2efec1a519b67229a3b87e1f80e6aa17e29460000000000000000000000000000000019f60f2cf585bdbc36947f760a15fa16c54cf46435cc5707def410202a3f4fa61b577ab2481e058b0345982d3e3d1666000000000000000000000000000000000a70b7bbc55e1f3e11e9eb7efd79d4e396742de48d911ddff8dd0a7cf10422423d5e68021948e1448e92c2e07c194776", "Expected": "000000000000000000000000000000000a87e7e115ccdf3c2c1a2716491d449c3f8329e73d264088f4af444d43cf05f8be0410da273ce7eeb32969830195b7e70000000000000000000000000000000010a973d6e4bd85105bf311eb0dcfdc0a5d38dba1c099206b60f2e2df4791fd58846bf19d83769506e1561212920b4895", "Name": "matter_g1_add_58", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000001450bddfa14033ed8cdb94386715013ed9b2c4f9d65944e9d32c0b3545a085113e173e5afcfccb78878414a464d318400000000000000000000000000000000109bd6e0636a7f96ffe2ce8e109171efaacfcd60189c7050259ddedd15dd257e11f2585bbd84e4a3f4d8fc5fbc0289cf0000000000000000000000000000000019b420d778da53aed81b48f2c9b9eb399e771edd5e124a41577452b409ca2503e2798cd25d791f489352fc7b7268ae23", "Expected": "00000000000000000000000000000000162bd29f2de10002c1c446bd9583e89751fb91703ad564e7951d41673e28d214729aa9b4b9875c397989df197c912d5f0000000000000000000000000000000004d393181871c93714afab6c33c16f68ec391fbfcad606ac65cc1d070949c099e21f710e2fe0dd4e4f50f99ea2167a7e", "Name": "matter_g1_add_59", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f35556500000000000000000000000000000000120935947070451885bf0c328bd83def193831ab9353844a01130074f16a1ff4d20df8459b5ad6a57d5f1959d37aae920000000000000000000000000000000012bb529b45ad7875784b62a7281d025002f15e7f86cc33555e7472df60da2cb15d37c8bf628142818c0711ee9047fb4d000000000000000000000000000000000baa801623312d95e2b51ce86373fea516007e468f265d974c2327c1779830db180bed6dbe8a64f0959aad26eaafb8d9", "Expected": "0000000000000000000000000000000010c4b328d264893099d89ba81b0765d0642bf36b0ac043be090c7b4f7987d21a906228c3c208c4ec5123d577efb0771f0000000000000000000000000000000016d08ce3bf755da7d4bae5f4b06b37845c17a717329c547e941be93325a04e9a5095d3f6e6c6f9ec3b1a740f59d88919", "Name": "matter_g1_add_60", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce00000000000000000000000000000000144f438d86d1d808d528ea60c5d343b427124af6e43d4d9652368ddc508daab32fd9c9425cba44fba72e3449e366b1700000000000000000000000000000000002c9e50f37ff0db2676637be8a6275fce7948ae700df1e9e6a0861a8af942b6032cca2c3be8b8d95d4b4b36171b4b0d400000000000000000000000000000000050f1a9b2416bbda35bac9c8fdd4a91c12e7ee8e035973f79bd35e418fd88fa603761e2b36736c13f1d7a582984bd15e", "Expected": "000000000000000000000000000000000f798f8d5c21cbce7e9cfcbb708c3800bf5c22773ec5b44590cdbb6f720ccddf05a9f5d5e6a51f704f7c295c291df29f000000000000000000000000000000001483903fde5a968dba6924dfac3933cd39f757e2f89120f4ca9d03aaaf9e18252bdb5c5d3939471666b8a42aeb31b4ed", "Name": "matter_g1_add_61", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ec000000000000000000000000000000000332cdc97c1611c043dac5fd0014cfeaee4879fee3f1ad36cddf43d76162108e2dc71f181407171da0ceec4165bcd9760000000000000000000000000000000015b96a13732a726bad5860446a8f7e3f40458e865229bd924181aa671d16b2df2171669a3faa3977f0ee27920a2c5270", "Expected": "0000000000000000000000000000000001c762175f885a8d7cb0be11866bd370c97fb50d4277ab15b5531dacd08da0145e037d82be3a46a4ee4116305b807de6000000000000000000000000000000000bb6c4065723eaf84d432c9fde8ce05f80de7fe3baed26cf9d1662939baac9320da69c7fe956acdd085f725178fe1b97", "Name": "matter_g1_add_62", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000b4e7355aea3488234552d3dddfa2d1ad3164056407770e6c54f764193c9dc044cb7f2b157a1c4153b2045867d6f99c50000000000000000000000000000000003ebca978ea429eedad3a2c782816929724fc7529fbf78ea5738f2ca049aab56c1773f625df2698433d55db7f5fc8ca2000000000000000000000000000000000d2477f57b21ed471a40566f99b7c2d84ce6b82eaf83a6c87a7c21f3242959c8423d4113b7fd8449277b363303bb17b0", "Expected": "00000000000000000000000000000000071dc0f985703bd8335093779de651b524c02faca5fc967766abd3f6f59176d2046d7a14d18c0b757b8c9802e44ebcd300000000000000000000000000000000154e5cb66be8979ee276e8e0f240557e3f7dc074c497293af589256652da21d66a6e6b00ca5bfa6f89963fbd5bc6cf48", "Name": "matter_g1_add_63", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679000000000000000000000000000000001461afe277bf0e1754c12a8aabbe60262758941281f23496c2eeb714f8c01fd3793faf15139ae173be6c3ff5d534d2bc00000000000000000000000000000000148ad14901be55baa302fa166e5d81cc741d67a98a7052618d77294c12aea56e2d04b7e497662debc714096c433e844e", "Expected": "0000000000000000000000000000000012c4dd169f55dfb5634bc4866f7cbd110648b5392ace6042b5f64aba3278f24085227521b7834864f00d01ec9998dd6800000000000000000000000000000000102d7a495850195424677853da01d70caeb6c0af5270bcfffbc2d4252c0f3680518cd8d2a0a6dbbbc7b52923a5b26562", "Name": "matter_g1_add_64", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c0000000000000000000000000000000002218b4498c91e0fe66417fe835e03c2896d858a10338e92a461c9d76bcecd66df209771ae02c7dcace119596018f83c000000000000000000000000000000001990233c0bae1c21ba9b0e18e09b03aeb3680539c2b2ef8c9a95a3e94cf6e7c344730bf7a499d0f9f1b77345926fef2d", "Expected": "0000000000000000000000000000000010c50bd0f5169ebd65ee1f9cd2341fa18dd5254b33d2f7da0c644327677fe99b5d655dd5bfdb705b50d4df9cfce33d1400000000000000000000000000000000088e47ffbbc80c69ec3c5f2abe644a483f62df3e7c17aa2ff025553d1aaf3c884a44506eff069f4c41d622df84bbafa1", "Name": "matter_g1_add_65", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f7000000000000000000000000000000000160e0f540d64a3cedba9cf1e97b727be716bbfa97fbf980686c86e086833dc7a3028758be237de7be488e1c1c368fe100000000000000000000000000000000108250b265bd78f5e52f14ef11515d80af71e4d201389693a5c3ef202cf9d974628421d73666ead30481547582f7abaf", "Expected": "00000000000000000000000000000000168af33c85ae6e650375ed29b91218198edd9135683f6a1428211acdcbf16bdf86f0a95575e47ee0969587a10fa9f3c90000000000000000000000000000000012d9f5d692c870b3da951b6d07797c186a8ddc89b9f08a1c0b8f0f119f10ca0b155e8df5424cf48900ad3bf09ce6872a", "Name": "matter_g1_add_66", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d20000000000000000000000000000000002fa19b32a825608ab46b5c681c16ae23ebefd804bb06079059e3f2c7686fe1a74c9406f8581d29ff78f39221d995bfd000000000000000000000000000000000b41ea8a18c64de43301320eaf52d923a1f1d36812c92c6e8b34420eff031e05a037eed47b9fe701fd6a03eb045f2ca7", "Expected": "000000000000000000000000000000000b99587f721a490b503a973591b2bb76152919269d80347aeba85d2912b864a3f67b868c34aee834ecc8cd82ac1373db0000000000000000000000000000000007767bb0ca3047eee40b83bf14d444e63d98e9fc6c4121bdf04ea7148bcfaf3819b70dcebd9a941134e5c649da8f8d80", "Name": "matter_g1_add_67", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531f0000000000000000000000000000000002a540b681a6113a54249c0bbb47faf7c79e8da746260f71fbf83e60f18c17e5d6c8a7474badafee646fe74217a86ca4000000000000000000000000000000000fe2db7736129b35dc4958ffd0de7115359857fb9480b03a751c4fceb9ae1b2b05855398badffc517ae52c67f6394e2a", "Expected": "000000000000000000000000000000000bc719a8397a035fc3587d32d7ef4b4cfd63d4a5619ab78301d59659208f86df9e247e5d12650acc51a3bca3827063a900000000000000000000000000000000150d5519380a65b1909b0d84da374484675d99b00b254d03e423e634a012b286e3fe074e9b0a7bb24ff52d327249a01b", "Name": "matter_g1_add_68", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e787900000000000000000000000000000000019d917eb431ce0c066f80742fe7b48f5e008cffa55ee5d02a2a585cc7a105a32bbf47bdff44f8a855ade38184a8279e0000000000000000000000000000000012ee762e29d91a4fc70bc7a2fb296a1dcdd05c90368286cca352b3d5fffc76e3b838e14ea005773c461075beddf414d8", "Expected": "0000000000000000000000000000000008197403ab10f32d873974c937ef4c27fbdb0f505c4df8ac96504705d4851cf951fb0263335e477063884527b21edf160000000000000000000000000000000005396f1affa20ca8530b519a4d5d400969f0c8c8731ecc0944e8086388e89a7ff7c16d9a2a90780972c4762b88a0f0af", "Name": "matter_g1_add_69", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a000000000000000000000000000000000d280fe0b8297311751de20adf5e2d9e97f0c1bfe0cd430514cfddbafd5cdcb8c61bd8af4176cc3394f51f2de64b152400000000000000000000000000000000039f511e890187f28c7a0b2bd695ae665e89b0544c325a44b9109da52cc6908d81e1a27163a353ab275d683860c2e007", "Expected": "0000000000000000000000000000000002baea63055f72646189bdd133153dd83026f95afad5ce2cffbee3f74c8d47d5480094b2b58b0936c78aa33cd9a8f72f0000000000000000000000000000000013e600456a2d76f5a760059e0ba987b881c6bc10d6161f388d7a9d8b2031921054edfec46afbd80b1364d8e8f6a5a7a2", "Name": "matter_g1_add_70", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f50000000000000000000000000000000015bad24d12b5d68558e961a17dbc3e1686e1b918e6192ebe6f3f71c925177e61d0162e018ac81126099effa0cadfa185000000000000000000000000000000000de73182569184b3d79dcfa8c27f46ec7a31fe8a3fd73fe26eec37a088461192bdbcf4d4b37b33b6177d6fde015d1631", "Expected": "000000000000000000000000000000000ced641c930387432d512861eefbf2d6131017154f99a0d3d24da880dfd2aaae91c2d9634053fab8b85fc11a7884d30600000000000000000000000000000000122071c0e87fae5031c850dccc4777c3ec9d8463bbc4ed84364d4261bc9d38f696a4320d53eea926a75ed9fcc9789a07", "Name": "matter_g1_add_71", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b256730000000000000000000000000000000015cdf7dafedce64aba34e1f18c57b28f297629c07ee96b732029b545cf5ea6afdf926daa6a48d1250c67aa2a8b797d370000000000000000000000000000000004867352f86267dbe8e32806e4ed02f1487e036051068f8e06d02e8dea6d3773b422e065d2db27c89ea69246d0185351", "Expected": "000000000000000000000000000000000e2c633351d627a075acd1e373bec96ba41b047f0307201f4b7c9978c1a72243d0b18113604cc421b8f66d76ec9b1360000000000000000000000000000000000844e258d602bf9aaa35ce46c4c91c80dd9337053d8ab22c1163a0571fcd1488a2ef57476e2b66dd9c26963b28284d11", "Name": "matter_g1_add_72", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc300000000000000000000000000000000077eb801bcde78e9dd73b58d2429a907ea0f5600a8005093d471be373bba23ea70bf828c766ccced6a46db84b440053f00000000000000000000000000000000101af9df2939089d72e42fe2dc3de3e32be8f4526a2263ebd872d0080ed4a152107bb3d2f56176bf72d5ae8bd0c30a3f", "Expected": "0000000000000000000000000000000010205c6be10a5fc5390b0e5ae47a8a822c8e9a7a96f113d081cde477ec0de7bf0e8385e61780b2335e4297edb35bcc6d000000000000000000000000000000001796af180463ed70cf330791c8201ee3f0fe52993f64819291bda33017285fcc3a515669b3d48a411276c849fa021f6f", "Name": "matter_g1_add_73", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a0000000000000000000000000000000019b09bb7dddd11c5d0e304dac120b920601dd3a3505e478c88850cc701c17eb02aa7bfb20e4017a62fc4fb544d4f9e8f00000000000000000000000000000000048ad536cf89576d4cce83ef065bc16c47f1a28ae27bd71d30d8f2177a9c6f8b2ed0cdf872ead71bc5a1252bccb4a7e0", "Expected": "000000000000000000000000000000000fb047098a1996a625cd19021f81ea79895e038756878d8772aaee9b6bbb66930e474dcc04579ad58f4877b742a890900000000000000000000000000000000017da74a4caefc55794a36eda7938371f42265cc1f2d87d41883152db82873daeb59642e8e663afddd4f24536a1f52b3f", "Name": "matter_g1_add_74", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa30000000000000000000000000000000005f84f9afa2a4a80ea1be03770cb26ac94bec65cf9cb3412a07683df41bb267c2b561b744b34779635218527484633e30000000000000000000000000000000013ce1d1764961d1b0dff236c1f64eabec2ce5a8526edf6b0bccb9ea412e5a91880db24510435cf297fcc1b774b318b65", "Expected": "000000000000000000000000000000000f4ca788dc52b7c8c0cb3419ab62c26db9fb434321fc6830837333c2bb53b9f31138eecccc3c33461297f99a810e24ad0000000000000000000000000000000006785d4f9cdf42264c00fdc4452883b9050eb56e2f6e46c7b8fc8d937dfe4d3ad5072d969a47c4811b36d3887256d0b9", "Name": "matter_g1_add_75", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c8000000000000000000000000000000000f0dd7a15dfc39dc2df47cf09761498b0b363157d8443356e768567f5a6d5913c2a67f12d93df2dcf50756bb686836b100000000000000000000000000000000055914dbda5b115222e738d94fbd430440c99bcc6d2c6cf7225c77756ffadf765b2d83447d395e876b5f6134563ed914", "Expected": "000000000000000000000000000000000ac0f0f62202d09cede55ca77b7344b46fd831b41015eb357cac07f0fa49c2564c2e9d5c591630226677446a9100757c000000000000000000000000000000000ca21d0128ef933fc1a48c1b4967f56912513e63a416d86ad40c0a4590b2edf88e4e8a286338b8b176d8b341ea480277", "Name": "matter_g1_add_76", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb211000000000000000000000000000000000a6ff5f01a97c0f3c89ac0a460861dc9040f00693bfae22d81ea9a46b6c570436f0688ed0deef5cdcc5e2142f195b5c000000000000000000000000000000000193a17880edffe5b2ebedf0dc25e479cac3b136db9b6b24009ea0a9ca526d6dd9714d10d64c999d4334baa081b9f2fbe", "Expected": "000000000000000000000000000000000b728d4ae4b45fae9a9e242524e95e44f175356726da50f46236f690eec17fdd5edce5df1253383378dc8f9c1fee98ae00000000000000000000000000000000131d28a5eab968c45ddc86b82f220dcdeab7c009c7c61986ee4e55045c024e1bcbe76a4e35000b5699ccec5858ba427e", "Name": "matter_g1_add_77", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a000000000000000000000000000000000b35fcf625cde78fba1b70904acb97d7eb449d968e8013855d44292e9c3b0df3cfbcace6f292ec3c7717e25490bb4c67000000000000000000000000000000000af57abd87df55034c32dbe68bd1c0b47139fc2c3a8887b7c151e57b57c9002070337c8dcb2ce2687f9f007d48dd68c1", "Expected": "00000000000000000000000000000000178a19966b5b0fa70c138be7f5ea51d5399c7b8dcc5171cbef82ecb1451aeccbd1ed29170a27f404ebf6daa2ec99bd69000000000000000000000000000000000b1b748494806175030f6b5e2977c58982bd6ec6662d69237f0521351653c772a40035f2504ac8949fb448a901379fd6", "Name": "matter_g1_add_78", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b00000000000000000000000000000000177a51fcc81580ccb7a8873fa93eaf860ca8fedde13cdf3eb53f11e66a1c1e934b82ee9251f711c5c479f33a22770c47000000000000000000000000000000000a0edc9a58f4bb414aa0aeec7bfa6076fb62bdbaee987192c18855adf4e813e7103b943e1dddc24754acfa90600a5750", "Expected": "0000000000000000000000000000000019195049a2d457709e284c84c72a211224efc4d7d46d25c9a537eea94149b06506df02a2a4e0a6428263e9605eaaacb500000000000000000000000000000000061139f9a70ce7cd87ed3a701163bde247382295f557b47a3a0a880d2780f015e8ac753eb3243f9ad138f92c3a2257c5", "Name": "matter_g1_add_79", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d000000000000000000000000000000001552982822e0b64a6204b27da0e192873bb5bd2997784ff0b6ed53801b402501a665c17f0a379fd946ab1adfae43c6af000000000000000000000000000000000938359655fe135dd2a390f83e27273feb68387ba94f2b6f7c15389f8272d64231ebe9c8271de90ff2358d935359ba85", "Expected": "00000000000000000000000000000000168f958a40e85341d90012e134976d1a5839e807948410cc0c81a50961552c052bb784c50da4c734f6aa583777c22b28000000000000000000000000000000000d26998bac6ec11bc5fcf6fe7262c984d6500cd5b21af979048b940e20054f8d759f8a011f3e09d01d10f9cf8ab150e1", "Name": "matter_g1_add_80", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d50000000000000000000000000000000000d94885dcc21b0b98821b6861a4d094e9eb5d5adcf7ca4275c5b759abbf9a9910f3b38073183d54a0569ecbbc1e9826400000000000000000000000000000000034a54b4bbb3f128608a866f5f5c554cf6ad7899f6650ca663a5bd5f1a3e4471e35a2440644c0e4e0a56080936b46d12", "Expected": "000000000000000000000000000000000d4734ab1bbcf9e30cf142a7aa9e8cde1b3c88d92397b8d7d48c7a7402561feee58a810abf67776e1890489efe7f8ec20000000000000000000000000000000005be9e4af0c0c183c43601339f162345f7c013f5941167cd925057e91c4641e19091a20123a36f2e803142833c0bc1ef", "Name": "matter_g1_add_81", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000014f16cbb17e7f63284d8a75968a4c8fc8ee7f37233ed656d696477c507c23e7c7eaf54001f44c93deb14c298aa6f94c00000000000000000000000000000000169bde83e861889c50b2138c76531a5866235d515a6fee4da7aaf8e8b903f2848a9fe7bbd55eac7f1c58ce3a88e7249d", "Expected": "000000000000000000000000000000001400f774b2d932c6b990da6e1b3493685e8f51d429e0c53e9af1b4a2d3876781b790bca4a1bc28ce0240ea21be24a2350000000000000000000000000000000004993fcf5723b7e02095d4ba73ff3194bbe36027bc9099b57084c91c7e7d50b76331bfb06d3c678d3e401bc3f7fcc577", "Name": "matter_g1_add_82", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000009acc4b4678b4b645fde47d1b75a5dda8caf6696ad2bf312dd5c12d7f3ab50b95152f5fe59842650c8a1a785f345c3ab000000000000000000000000000000000b672989004fe54f4d645e40cd29a21418151134fd2b90a68185040ceff141ced7f7ece1fdd9137c32589fa04b105a0e", "Expected": "000000000000000000000000000000000fcb0ab180a69b0a230d9dba98099fdce4969f82fc7e7ad93352a7c8dd448bb0ba9c7d62f53d5dc80506bc36190d9bc700000000000000000000000000000000047b7306f4a53c21d42993c50f2365486d02dac495f2dee4f8971a4af308396fce6c90f3cfde857bf7a2c6bf5d0d8aa7", "Name": "matter_g1_add_83", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f6000000000000000000000000000000000198e12ade128447a240e03e024183c401d605cab1ed81f0f5bb7bc4c7cc9c889a2a01f59c0e37a0767a927719e5a95d000000000000000000000000000000001946e39fee9b76ce552108b339b9b24d11e43d3275ac19d2d4bc745c409bdc3f7c473a60c4d3a4d2cc3b598ae0d66880", "Expected": "00000000000000000000000000000000050b45f896fa40099cda8b1f20ab88644915c16f926589cd709e00149b12922347fa7122175424cd44e8875f217b9ad7000000000000000000000000000000001122b7e9b1509efe5616368b14085bdd36fb7adb85cd5a7f23e327548986f5298c045a602b6ee1265d53a4432a4a3c0e", "Name": "matter_g1_add_84", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac47388620000000000000000000000000000000009c48aa2681b3005b24075bb3a122ac100cbaca872f761f4398edaba9dd9da6d04d4a4925028297dfe5f77c2b0b5c821000000000000000000000000000000000ea95c646fb68aa458e69c267a6ca640a6a24d40bdca0161246e4521d13c46facfc1ac86dfc0a804cfa6665cebeec822", "Expected": "0000000000000000000000000000000005325a499aec678ada9eb673d366fe0475e885d5188e2fb687a96949e8f782852fba962197976b868ec083c512bfb66b000000000000000000000000000000000c4d6fcacc8d82401882bee355b37930d83e3cea2e4a7bc133e65a3e0af919b25fc3f30c333873da9406845ce42dbb87", "Name": "matter_g1_add_85", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae80000000000000000000000000000000008e8799a6cc0339e94e861692c81eee53e8a7b326523d5344b416bfbce04290585ef56018834cfd93d234bfa2943369f000000000000000000000000000000000fa1b01aab0878adad693ec769fb68640931c355b3802c51d4a3772300be5b16ceecdc8328a229b3b9f3639170db96f8", "Expected": "000000000000000000000000000000000685ec14da61c48bcb697966aca9e27601db43f0fb1f32e026fb33738eecfbb7012aa1ca3acf36a21fa846730245add70000000000000000000000000000000003fc52a1c3342b12271bbc178545bb20e96e8f1fde673e51f3d27ab5cb42e60aca49c6077e0f687be59b2d25cda9718e", "Name": "matter_g1_add_86", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000bb3a76287fb98fe668cb0a5de603c768340ee6b7f9f686a22da3a86926d8734d2c565c41f94f08fa3ef0e665f4ccb520000000000000000000000000000000016c02dbfb307c96d5b9c144672fe62f3e9cd78991844f246945ee484cbdef2a4c1b001a017cafb3acc57b35f7c08dc44", "Expected": "00000000000000000000000000000000021796fd6ef624eed7049b8a5c50415cc86104b2367f2966eb3a9f5b7c4833b9470ef558457426f87756d526d94d8dfe000000000000000000000000000000000f492dca3f0a89102b503d7a7d5b197946348e195954d23b8ab9ab7704b3bccecaa2123b8386662f95cd4cfdbbb7a64d", "Name": "matter_g1_add_87", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f00000000000000000000000000000000127420ff97df415e336cf3e24c39c161fad630c45c7ccef80f1831c4f5ed54da12f2c49a161e72bc70285fa0498e46d00000000000000000000000000000000013e605c21014f72364f8bff392ce64a10078ea537237fa282d5dd252ba1677b84b8c15d7925e54a4ab36f1feb13d3064", "Expected": "000000000000000000000000000000000ae916770455b0a63717e81802f5a7fcfbcc3e260b7adeca02a61a520c338d495eea29c4f070fd6efc1b8d23eb285e4c00000000000000000000000000000000134784e092744df573ba78f7d6f3cf1ed19491a0fc7ddfa02d3ca043bcf102fd40c33ac44b03a947308e3cc7af41c2df", "Name": "matter_g1_add_88", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab40000000000000000000000000000000016f41e8b098839944adc12481e5f965657a4faedd4f4cdea51a9597a6a0356989e791a686d3d2ee6232ab93683259c6b000000000000000000000000000000000d27b4a56b2cc2216e61eb41061f9a586a704652704906f7fe0eab869ba00d34205ea66f7a02d337d08b916598494e52", "Expected": "0000000000000000000000000000000012842c9d7f4309f6e40124a071d317f5597de419db0d5a8e5324a517f7b61dfdeea2fb4503ad7cdd8deb8aaa5c412554000000000000000000000000000000000ace4d9f98ee6e8a4416ef14d64f26dc49e102e69eced46ef829a352e58e8c1a7e1f083e3f4fc07f24ccd1685dedf215", "Name": "matter_g1_add_89", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000019e7c8d182e3b674dfa21539613f7de5d4872d4f4732307a5c6d95ada7e81a01bc25bda34e0b46634e0b0b32cd47e8ec0000000000000000000000000000000008149237de73ab46d5c20dfd85b07f593c0caf2e2e364335450e3ebb478a9f6b9ac0af89174dffd92eda2783a5271f01", "Expected": "000000000000000000000000000000000875289fdaead079a283aafe4de7035c88662642b6bba389b17583f8e3b5801dada6e46bd897af961997665e6ed4a55700000000000000000000000000000000050a6b9c1db35865df0a042d27a042ff4b8d3bec2fba6a3a28a71c5a574620dc05cda0e70932ce9b8966e4592220c147", "Name": "matter_g1_add_90", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a6000000000000000000000000000000000c0f33f2d76366af661d6fa58a8b5aab207d35ce03899e495f7ddccedf201d9816f270468b207413a2ca70380c798fc60000000000000000000000000000000002a7dc7e2b163e65cadf93b5d682982288c8f36d08b1db8e0b1cb40cd3c7231f3f1672da42b4679f35db2076a8de5b42", "Expected": "0000000000000000000000000000000019ea92820dcd442358db359146797aa82beff6154946b1ea14dccae05e8252b776b817dc044a20764e3514cd22799c0b000000000000000000000000000000000ed929fef2cb11e8b6b9b5d52bfde82080eda747f0c82f33b9cb87019476f0c128e6b918a4486172dee2884ba538ae5d", "Name": "matter_g1_add_91", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000118fb45274a6b0ca9fe2654821e3b30caa46444f7c64b1921cf16dfd56a43916947d4fb6968d718a59a30ed38d65ce3000000000000000000000000000000000110e8e73e640bbea6927cd770baaf887c8e0e0c58260bca489c39b6dd7a24ab8c0c0a2495133d8ff8c7afb9790b37faa", "Expected": "0000000000000000000000000000000009452bd0a167683e30c673ffd4e750c66a81edf309a8d2d6dd915c358b30b0ffc001c4165b1b17bf157a0f966bfd91d00000000000000000000000000000000015df0b1ee359dd3e35a7b2c33edbb8e92b18804ae3359a369c6a529f5561298e6be9a3498c9477f33353124af7e91968", "Name": "matter_g1_add_92", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000005dcb54cdf9635db275540c16307fc9f07b4ca5cd91e3977e4b95b58e8103e40ed9fa74752b2a43d95b6acb6f5fcbf440000000000000000000000000000000007ef8457752a47864ef2698176a53990e4822421ecf83b2716251e3ce69151ab2767d4a6611a0a6e0e40a57164ffb94e", "Expected": "0000000000000000000000000000000011f1ac702a06699dd64b63ebdd8b5381578f63b603c63c3a47413fe764af239ab7024712320f3ea3daefa6bd3cd3dfe9000000000000000000000000000000000918bb83a22b4fc66247e007c17155c4c2ec6326131c10fe04a5f9b82ddeca3d21c7c397a70a3949fda4d766540c85ff", "Name": "matter_g1_add_93", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c35850000000000000000000000000000000006d3335e092616363e94436bb68be89667c706564ba687f4a3494fcf7da62fd9ad8ae68cb76524926c261983711a14ad000000000000000000000000000000000f085a3d013592c402a380e2e8d9019864a775e7b8e8b94603c8cc1eb1def1e91075fd5675f76534397e2a7d76c2331e", "Expected": "000000000000000000000000000000000344951ccb5e60d1838f7793fcf8b765f5f252b69e1cfdb4bd3c20692c8ffa01afbda6950974a65f6ac74afb9da5942e0000000000000000000000000000000014f5f0e6b99a04d1c5c2adf96c53dd41f8c01aab8db4f0e6d7fc5eab27f6c03c429632db4e1c21467c09d8a54066a4d3", "Name": "matter_g1_add_94", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b0000000000000000000000000000000019e2ed6e9757e2339d013078fac91c966045f7a1416a56135d75e603c2021a8bebf4acbf6c0d5ba911f66510e9a7ad1a0000000000000000000000000000000008b8585444ffb3bd4fb6ee23e8128142aa72fd574a506151a0eea8979cbd694e03897caba63771b0490d46063bc5bb57", "Expected": "000000000000000000000000000000000a449fb0da911c544887b24860bc5fcaaf054041cc80f16bbb44c796520bee454d0d06f84fd5aa179a44fd4fac9f144a000000000000000000000000000000000fca81401349089caaef9156a86c64271c77235c9efd136dcfad9894450b076cb3dd1a05bfa1e62ef904435eee5d2250", "Name": "matter_g1_add_95", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b767f399e4ebea34fd6b6b7f32a77f4a36841a12fc79e68910a963175d28cb634eeb8dc6e0533c662223c36b728cce2000000000000000000000000000000000cb3827fd6ac2c84f24f64789adac53439b4eba89409e12fbca0917faa6b7109aa831d16ca03191a124738228095ed65000000000000000000000000000000000f4a256b4288386545957a3ba28278c0ce69a8a412febfed1f952ca13e673822bacb6b7751ea75893b680ea363aab66400000000000000000000000000000000152379d006e74798199f83b0c6c22a98440ef653d7f0a8c5e3026bcdabec8be59a3cc291ba05860bd0639c5c5f5bee26", "Expected": "000000000000000000000000000000000c427721953e139d4f12ad2a3f8f91a4caa49875a87001b619c8a6e909a7da8ddd9dd026bf56d5f85d49fd17527106a800000000000000000000000000000000018add2816914ef51a289e707ba0224fcf0b7bcfa4001487e90dbdce53f1b596e1f5872de32fcee6f63bce4484ccbef7", "Name": "matter_g1_add_96", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000150b75e9e9c03ada40b607f3d648bd6c40269aba3a1a992986dc005c9fde80bb1605266add0819641a0ca702d67bceed00000000000000000000000000000000083b43df032654f2dce90c8049ae4872a39f9cd860f08512930f43898e0f1e5625a5620818788797f3ca68134bc27d220000000000000000000000000000000012dae9aee13ed6ad52fe664bf7d2d0a1f134f0951d0d7ce5184e223bde164f6860967f9aaaa44fa6654d77d026c52d2a000000000000000000000000000000000f71889d64ec2f7da7319994883eb8bd1c753e6cdd3495036b630c35f07118a1bc10568c411ecbdf468a9cdaa9b4811b", "Expected": "000000000000000000000000000000000275b8efb3a3e43e2a24d0cda238154520f0a2b265f168bfc502b9cd4a07b930756961ae7e4fe3f01a5473d36ce3356200000000000000000000000000000000113403d5a968f01ba127dd8ef6c8d7b783a10d039a6b69c617032eba7122e9297f3ce2360c829ae64fdc9794695bf173", "Name": "matter_g1_add_97", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cba419694214e95a3605a9b748854d16c8e6e1ee151c907487d8189acfac1361b790a5e78f43593152027295adf8df400000000000000000000000000000000110813ff6e0ddf3427e2a514d3f0bfbadcaf9dbf039e0f93fb9643d1e62bc2469fe84cd9ff0d585bdd1037255bbe54850000000000000000000000000000000004e9dd69012ab596b5d3f1f8e4593b448685fcec4ab3394008178b137b762ddf9150cbb8dbb74c8af45bd8baab9a6c4f000000000000000000000000000000001132b66a2127885774062732127951f051c9c3c9b5aba02406e3f3cd4ecfe2dbf6614ebaca3bfe9efbe4f6e5b15ba0f5", "Expected": "000000000000000000000000000000000594c808954bb930bd038806500c9e3fd6460a83554e945baeeec2354a3805f046c76aea62c249080f16ae8e70f8fa6b00000000000000000000000000000000046924a32fb3f2df9a52615e45eeea2fa3ac0e2ccd38458194ada6b4d993ecdc0f441e41d0ea37599254a06aef68b9ae", "Name": "matter_g1_add_98", - "Gas": 500, + "Gas": 375, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000106df8eba767e90cce0eabdaacc24d8e226c6865012ef8cb1460de5a319d443fdc6b4f4e58fb668943e0528b1809da10000000000000000000000000000000019789f464c95c179af18704c0b67b881991880f75ee7b03b9feafa3eafcd0f7d30a17fdd9cf439ff7fe683adca2083b50000000000000000000000000000000017a81b957a12adf474a2913e8636f169ea9cd10be62c16b88f95f5caf661f158a032a9f7d249fdf2765caa1564bed0570000000000000000000000000000000017fbf2abc62dc2678b65d509e19c9c9c5d961c72565649a078da8dff98be6236ef314e9ff8022f639ff565353345c230", "Expected": "00000000000000000000000000000000002c8bc5f39b2c9fea01372429e92a9c945fad152da67174f4e478fdead734d50f6e2da867c235f1f2f11bdfee67d2a7000000000000000000000000000000000c1dd27aad9f5d48c4824da3071daedf0c7a0e2a0b0ed39c50c9d25e61334a9c96765e049542ccaa00e0eccb316eec08", "Name": "matter_g1_add_99", - "Gas": 500, + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Name": "bls_g1add_g1+p1", + "Expected": "000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a870025", + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Name": "bls_g1add_p1+g1", + "Expected": "000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a870025", + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Name": "bls_g1add_g1_wrong_order+g1", + "Expected": "000000000000000000000000000000000abe7ae4ae2b092a5cc1779b1f5605d904fa6ec59b0f084907d1f5e4d2663e117a3810e027210a72186159a21271df3e0000000000000000000000000000000001e1669f00e10205f2e2f1195d65c21022f6a9a6de21f329756309815281a4434b2864d34ebcbc1d7e7cfaaee3feeea2", + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1add_(g1+0=g1)", + "Expected": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1add_(p1+0=p1)", + "Expected": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000114d1d6855d545a8aa7d76c8cf2e21f267816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca", + "Name": "bls_g1add_(g1-g1=0)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca9426000000000000000000000000000000000195e911162921ba5ed055b496420f197693d36569ec34c63d7c0529a097d49e543070afba4b707e878e53c2b779208a", + "Name": "bls_g1add_(p1-p1=0)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Name": "bls_g1add_(g1+g1=2*g1)", + "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", + "Gas": 375, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Name": "bls_g1add_(p1+p1=2*p1)", + "Expected": "0000000000000000000000000000000015222cddbabdd764c4bee0b3720322a65ff4712c86fc4b1588d0c209210a0884fa9468e855d261c483091b2bf7de6a630000000000000000000000000000000009f9edb99bc3b75d7489735c98b16ab78b9386c5f7a1f76c7e96ac6eb5bbde30dbca31a74ec6e0f0b12229eecea33c39", + "Gas": 375, "NoBenchmark": false } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/blsG1Mul.json b/core/vm/testdata/precompiles/blsG1Mul.json index 0e166a29ca..3ed24adf2a 100644 --- a/core/vm/testdata/precompiles/blsG1Mul.json +++ b/core/vm/testdata/precompiles/blsG1Mul.json @@ -1,730 +1,79 @@ [ + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1mul_(g1+g1=2*g1)", + "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1mul_(p1+p1=2*p1)", + "Expected": "0000000000000000000000000000000015222cddbabdd764c4bee0b3720322a65ff4712c86fc4b1588d0c209210a0884fa9468e855d261c483091b2bf7de6a630000000000000000000000000000000009f9edb99bc3b75d7489735c98b16ab78b9386c5f7a1f76c7e96ac6eb5bbde30dbca31a74ec6e0f0b12229eecea33c39", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g1mul_(1*g1=g1)", + "Expected": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g1mul_(1*p1=p1)", + "Expected": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Gas": 12000, + "NoBenchmark": false + }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", - "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g1mul_(0*g1=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1mul_(0*p1=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Gas": 12000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", - "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g1mul_(x*inf=inf)", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "Name": "bls_g1mul_(1*g1=g1)", "Gas": 12000, "NoBenchmark": false }, { - "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000011", - "Expected": "000000000000000000000000000000001098f178f84fc753a76bb63709e9be91eec3ff5f7f3a5f4836f34fe8a1a6d6c5578d8fd820573cef3a01e2bfef3eaf3a000000000000000000000000000000000ea923110b733b531006075f796cc9368f2477fe26020f465468efbb380ce1f8eebaf5c770f31d320f9bd378dc758436", - "Name": "bls_g1mul_(17*g1)", + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", + "Name": "bls_g1mul_random*g1", + "Expected": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4", "Gas": 12000, "NoBenchmark": false }, { - "Input": "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e", - "Expected": "000000000000000000000000000000000f1f230329be03ac700ba718bc43c8ee59a4b2d1e20c7de95b22df14e7867eae4658ed2f2dfed4f775d4dcedb4235cf00000000000000000000000000000000012924104fdb82fb074cfc868bdd22012694b5bae2c0141851a5d6a97d8bc6f22ecb2f6ddec18cba6483f2e73faa5b942", - "Name": "matter_g1_mul_0", + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", + "Name": "bls_g1mul_random*p1", + "Expected": "0000000000000000000000000000000006ee9c9331228753bcb148d0ca8623447701bb0aa6eafb0340aa7f81543923474e00f2a225de65c62dd1d8303270220c0000000000000000000000000000000018dd7be47eb4e80985d7a0d2cc96c8b004250b36a5c3ec0217705d453d3ecc6d0d3d1588722da51b40728baba1e93804", "Gas": 12000, "NoBenchmark": false }, { - "Input": "00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed24d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d", - "Expected": "00000000000000000000000000000000195592b927f3f1783a0c7b5117702cb09fa4f95bb2d35aa2a70fe89ba84aa4f385bdb2bfd4e1aaffbb0bfa002ac0e51b000000000000000000000000000000000607f070f4ae567633d019a63d0411a07d767bd7b6fe258c3ba1e720279e94c31f23166b806eabdb830bb632b003ca8b", - "Name": "matter_g1_mul_1", + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e19a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g1mul_random*g1_unnormalized_scalar", + "Expected": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4", "Gas": 12000, "NoBenchmark": false }, { - "Input": "0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1", - "Expected": "0000000000000000000000000000000014f9bc24d65e3a2d046dbae935781596fb277359ba785808fd9ff7fd135ba8c1ddc27d97a16cc844427afbf4f8fc75a60000000000000000000000000000000017e3a485f84e2f2bdcf3255fe939945abe60dca5e0ae55eae9675dcc8d73e06d00b440a27ab4dc21c37f0bd492d70cf4", - "Name": "matter_g1_mul_2", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e44c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a", - "Expected": "000000000000000000000000000000000827517654873d535010e589eaf22f646cf7626144ca04738286de1f1d345342d5ae0eab9cd37ced9a3db90e569301720000000000000000000000000000000002a474c2443d71b0231d2b2b874a6aeac0452dd75da88e6f27949edafc7d094cb1577a79f4e643db42edcaecc17d66da", - "Name": "matter_g1_mul_3", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d38964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89", - "Expected": "000000000000000000000000000000000d7e5794c88c549970383454d98f9b7cebb7fdf8545256f1a5e42a61aa1d61193f02075dc6314b650da14f3776da6ead0000000000000000000000000000000002054faff236d38d2307aa6cbbc696d50f5b3ffead1be2df97a05ebbcbc9e02eaf153f311a1e141eb95d411c0ec6e981", - "Name": "matter_g1_mul_4", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944", - "Expected": "000000000000000000000000000000000ff16ff83b45eae09d858f8fe443c3f0e0b7418a87ac27bb00f7eea343d20a4a7f5c0fcc56da9b792fe12bd38d0d43c600000000000000000000000000000000042a815a4a5dca00bd1791889491c882a21f0fe0a53809d83740407455cf9c980c5547961f9ebe61871a4896dace7fbd", - "Name": "matter_g1_mul_5", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1baaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1", - "Expected": "0000000000000000000000000000000009e425f5bdc7df5c2a72303918e5a3c7d2fdeeb071179c533f83cdcf38dbbdb1ec5f4ebc85f3ed80757641ee3f8a8637000000000000000000000000000000000819a3e81e9ac2baacdc778225129e16344107517157ab2a7bc5e3480938585c55fd2dd7185f52251f5ab191f162cf5d", - "Name": "matter_g1_mul_6", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442adac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c", - "Expected": "0000000000000000000000000000000015e6bea7ecf15d91bde67231f794397502c087960fab36d905137ce2608172b5a5def065cf7ee567ca7fb08a22adecf80000000000000000000000000000000001eed472d6138fbc56e10edb62563c086fdeb9acf6de957f2367db7f1c80d2c23197c09039ed55e65cb56de9fb9be64d", - "Name": "matter_g1_mul_7", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108", - "Expected": "000000000000000000000000000000000220a71ad70fcf7e47df60381fbd1aba33c03a3f8537ba2029ad8e99b63c8677e0183f0b5bb2a5e1b23bc56693adb45c0000000000000000000000000000000017f26ac6ffc79ded7c08e08673336402f47ab48ef9ee2e46e3265e5cbb790cfc86f41bd1b578c5891eb052d11197c850", - "Name": "matter_g1_mul_8", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f8187672", - "Expected": "0000000000000000000000000000000006b27724c4898b4f71be9727b773709a7905997d06a41ee618b7dcf864d7457bb3241046f0139c1d678b6ba6226f090f000000000000000000000000000000000b20cabf58f9c29897e20e91a9b482f5f867bef45ce0941cb8850aaa2022182298a1a24655a4b905f436520cc42a30cd", - "Name": "matter_g1_mul_9", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea", - "Expected": "0000000000000000000000000000000004745f9877b3a0851df5bb770a54c69d5355cdadddc9d961e2bfdb3d0531d3d0f780f462335289be29ad4c62cb1250a00000000000000000000000000000000011034a094f59212c29e3f91c48df670e7a4021e4586645d250ee74a90f4b7b51510a5048dba3b555511c327ed211f81f", - "Name": "matter_g1_mul_10", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76", - "Expected": "000000000000000000000000000000000841c1538c1a3b54418c1c5557a5815c9ed74f6e1c8ed70e1ad424220dc522c530e2e48affe6cb3190abb25af84b91a300000000000000000000000000000000167490a2aa6c8796736cbd364a4d18007ecfee403bde5dc13c611a214610e85af314ddddbf05ea129e027e0ae8d89b36", - "Name": "matter_g1_mul_11", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276bdd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c", - "Expected": "000000000000000000000000000000000ea1f952d65dbb9a40209aa89e367d9d75e1b4c3a70a609efda5fbe7f5c5483163671da425545d3f1afb817c6d8c59a0000000000000000000000000000000000cd537dc11cc63dd15c8ff74d15961390eaee59b2d5697b18c1ea6d534d71551f5e195e8a0793140d821dde97dc77623", - "Name": "matter_g1_mul_12", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a57876817010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a", - "Expected": "0000000000000000000000000000000004c92b7cf9199f47008dd561e624c822a067c57fdea9d016f79e6c7956dda9df0e36b4e78715f3da1319af9f4f1fb160000000000000000000000000000000000d2851d68617567ad5308f69dc5dbbf37603c2ba48cb3759b70fc4301fdce3bdc9fca076e2ae09562396c1b8558ccdcc", - "Name": "matter_g1_mul_13", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f76894c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a659054", - "Expected": "0000000000000000000000000000000006ed98add25d64f7488ed270e0899ee3633c84b73de26557c552017e7cda4cba1228c15e87efb5a740284dddb8cc80de000000000000000000000000000000000b363e14b0285fbd24eaacfe80b992d8df1abfe83991cc55b0484076385374bc87d9c7860177f06143c600503ac54577", - "Name": "matter_g1_mul_14", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931db3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746", - "Expected": "00000000000000000000000000000000164671460621354cd352d93ca7de51828b3e6db0a37d2894a0ac475a5facdbc3ca5909d3bd7553271dadaa68b7474e2c00000000000000000000000000000000188827c6e2f4e9796c71703ba53ba2ded71bd6e8280e047fb6ea440b8dcafa7c4252d26bee1780ac67790e0d603c8ca7", - "Name": "matter_g1_mul_15", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d507f80a5e502f63375d672379584e11e41d58d2ed58f3e5c3f67d9ea1138493cf", - "Expected": "00000000000000000000000000000000023b2129ac67abc79966102ba223b982d40ca83e9b1ce33dff681c751b3f0c692f8bf19fa0394eae190767899829d1d10000000000000000000000000000000015449c6b5ee2c9f8b28e9732c9ebf6ffee5048263f7b5050a5ac9a76b034931a5c034f91d24b461636f5b116e37a26a5", - "Name": "matter_g1_mul_16", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000043c4ff154778330b4d5457b7811b551dbbf9701b402230411c527282fb5d2ba12cb445709718d5999e79fdd74c0a67000000000000000000000000000000000013a80ede40df002b72f6b33b1f0e3862d505efbe0721dce495d18920d542c98cdd2daf5164dbd1a2fee917ba943debebb169138f94093d5c1c6b253cc001ce8baf78858dae053173fa812d2d1c800da", - "Expected": "0000000000000000000000000000000004edac7b03b5861d178bb4aa34e795c776fd95e7c0980f19d111ef208ca4854f73a3ddc219bb6bca173dec67b0e863a00000000000000000000000000000000004dbff672368f86e048c3e33cbe90aba570484b4ca2221f7f6adaa1738c369f4c02c0a10118e84ea8e53cfbaa10fa48b", - "Name": "matter_g1_mul_17", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000009f9a78a70b9973c43182ba54bb6e363c6984d5f7920c1d347c5ff82e6093e73f4fb5e3cd985c9ddf9af936b16200e880000000000000000000000000000000008d7489c2d78f17b2b9b1d535f21588d8761b8fb323b08fa9af8a60f39b26e98af76aa883522f21e083c8a14c2e7edb6e40608bdaf3e7764358a64a920cbb33ab4d571c7b3092e1ae11d9697f82ed833", - "Expected": "00000000000000000000000000000000169d637c52c31e4c62c9563a508869f7bb5adc7defedb5f4ba9f3eabe517fa8c0be2e44d656e50903dcab67a6a44984d00000000000000000000000000000000192b39d5cddac36940d896a738e25c25217768e1d0ca712968718b8fd9ad492bae63063b3cb168368c3df196306b6a1e", - "Name": "matter_g1_mul_18", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000010fcfe8af8403a52400bf79e1bd0058f66b9cab583afe554aa1d82a3e794fffad5f0e19d385263b2dd9ef69d1154f10a000000000000000000000000000000000aba6a0b58b49f7c6c2802afd2a5ed1320bf062c7b93135f3c0ed7a1d7b1ee27b2b986cde732a60fa585ca6ab7cc154bd411519f2a33b07f65e7d721950e0f0d5161c71a402810e46817627a17c56c0f", - "Expected": "000000000000000000000000000000001608c3bfb131eae485545b7d19b8f42de18dcea6a0db3279eac2b7c008fbead54046bf13dd63835abe9c63110e12526c000000000000000000000000000000000abb41b2f17cfcc2292c5bf559b38af3b25db40121c6a5627997f65765eee1743c204f1161abe3f71ac1fe4de6aec1d7", - "Name": "matter_g1_mul_19", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000013c5ebfb853f0c8741f12057b6b845c4cdbf72aecbeafc8f5b5978f186eead8685f2f3f125e536c465ade1a00f212b0900000000000000000000000000000000082543b58a13354d0cce5dc3fb1d91d1de6d5927290b2ff51e4e48f40cdf2d490730843b53a92865140153888d73d4af6bb3f9e512311699f110a5e6ae57e0a7d2caaa8f94e41ca71e4af069a93d08cc", - "Expected": "0000000000000000000000000000000016e3125ae97a2b1184e2c6dfe5d9459ac567c686e65674f3b0513df6de5e80d1efbff3c254e509eec3f951b0835b5829000000000000000000000000000000001889481258d3e898ed4e4a43e74c0eda5ba26c0b7525973ca86b896969240ac5928ba58bc86ec17a47f2469d023682dc", - "Name": "matter_g1_mul_20", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000053a12f6a1cb64272c34e042b7922fabe879275b837ba3b116adfe1eb2a6dc1c1fa6df40c779a7cdb8ed8689b8bc5ba800000000000000000000000000000000097ec91c728ae2d290489909bbee1a30048a7fa90bcfd96fe1d9297545867cbfee0939f20f1791329460a4fe1ac719292a0c988d97e86dccaeb8bd4e27f9e30fad5d5742202cdde17d800642db633c52", - "Expected": "0000000000000000000000000000000017d8c0aa81ca6a1e4de8d0b8b3a13b1d6350f79ee8439da97a5d564d435f4d40bde99138b67284beffbb176daee92352000000000000000000000000000000000a04e0bee6b9681db56604a6dd5e41c072e84f8ee9cb4054410eb610472b96c09802a1d70e325c40c7ab7e248eb2e3e4", - "Name": "matter_g1_mul_21", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001354dd8a230fde7c983dcf06fa9ac075b3ab8f56cdd9f15bf870afce2ae6e7c65ba91a1df6255b6f640bb51d7fed302500000000000000000000000000000000130f139ca118869de846d1d938521647b7d27a95b127bbc53578c7b66d88d541adb525e7028a147bf332607bd760deac0b299c14892e0519b0accfa17e1a758c8aae54794fb61549f1396395c967e1b1", - "Expected": "00000000000000000000000000000000089ae9fc5cdba1a24ca87fe4f1207d1a36c494d842eed330069f988d3bc8554af1deee3a5c59b5e74729097acc1185fb00000000000000000000000000000000002fd95001da3011b48067d351ec8667c2b2390b23fa0948896725292311dbae71b51d6d5d57e173970bc992d11fdd11", - "Name": "matter_g1_mul_22", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000003f76a6dc6da31a399b93f4431bfabb3e48d86745eaa4b24d6337305006e3c7fc7bfcc85c85e2f3514cd389fec4e70580000000000000000000000000000000010e4280374c532ed0df44ac0bac82572f839afcfb8b696eea617d5bd1261288dfa90a7190200687d470992fb4827ff327064d43d6802ad4c3794705065f870263fef19b81604839c9dea8648388094e9", - "Expected": "000000000000000000000000000000000548e7564e09c2bad9859dd63dd1045878c9b257015558b18cf5911d1763325e411c1fb8af52e8766fa7adae83eea12700000000000000000000000000000000111235351d136905fd19fa726eb6626085875c33c98067a01fde9688a5b2c289cb8e3f5d6a85d0829200a355c82f423e", - "Name": "matter_g1_mul_23", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000009439f061c7d5fada6e5431c77fd093222285c98449951f6a6c4c8f225b316144875bc764be5ca51c7895773a9f1a640000000000000000000000000000000000ebdef273e2288c784c061bef6a45cd49b0306ac1e9faab263c6ff73dea4627189c8f10a823253d86a8752769cc4f8f2686285a0e22f177fe3adbfc435e9c1786752dcf3c11b723539789b0cdeb0647b", - "Expected": "00000000000000000000000000000000165504769c7ab0d28b39f38f3bd09cd47c63b74c57d39935d1c03e262f9da0e8b0b9264b0d8e2908423fe5c74288c208000000000000000000000000000000001680df1d577bbbb66ffa10258bca54b74cd90a7b3f3d50472e70e18ef54b7a4412e9eb93e39b9b312e3e8e00a52e4067", - "Name": "matter_g1_mul_24", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001478ee0ffebf22708a6ab88855081daba5ee2f279b5a2ee5f5f8aec8f97649c8d5634fec3f8b28ad60981e6f29a091b10000000000000000000000000000000011efaeec0b1a4057b1e0053263afe40158790229c5bfb08062c90a252f59eca36085ab35e4cbc70483d29880c5c2f8c23176b6724cf984632daf95c869d56838ab2baef94be3a4bd15df2dd8e49a90a6", - "Expected": "00000000000000000000000000000000087a52e8eadd5461e202a640024fa17e201a9f0a2984be3fecfdeef86abed72d059e8879d0be8789f2a6db0d2cf55d3400000000000000000000000000000000196fe307db05207661a5a5f8f7fb24d8fea18ef91941ea7febbc18819f49f73aef9dd1bdf4fd605e031dc04f16fa92e3", - "Name": "matter_g1_mul_25", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000150d43c64cb1dbb7b981f455e90b740918e2d63453ca17d8eeecb68e662d2581f8aa1aea5b095cd8fc2a941d6e2728390000000000000000000000000000000006dc2ccb10213d3f6c3f10856888cb2bf6f1c7fcb2a17d6e63596c29281682cafd4c72696ecd6af3cce31c440144ebd1d76db3dcb659eaf6c086be6b414a494dea4bd30aef8450ae639f473148c05b36", - "Expected": "000000000000000000000000000000000301caf675cd5359bcc274b6141bb6ac53ab6a86a38ad4f8c3233cc9c1a77723eb0de4a2014e556185947dc1ef6624e3000000000000000000000000000000000136d286e623637f12c8b86cd9fad2bed8479ace5189e064a4e12e6e641447dfb0399757026126ad2d169c05011f5031", - "Name": "matter_g1_mul_26", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000f46bb86e827aa9c0c570d93f4d7d6986668c0099e4853927571199e1ce9e756d9db951f5b0325acafb2bf6e8fec2a1b0000000000000000000000000000000006d38cc6cc1a950a18e92e16287f201af4c014aba1a17929dd407d0440924ce5f08fad8fe0c50f7f733b285bf282acfc9915646de2449b3cb78d142b6018f3da7a16769722ec2c7185aedafe2699a8bc", - "Expected": "0000000000000000000000000000000004ce73cde58c9af5d1f76e100849b0ba3d3cc6491e76b39cf4d7b681fed0686396440f6a721f73b31fb14b4c7624c176000000000000000000000000000000000e26b15c1051d7b049e82476a30545cfa4bf0a2075681d7028797c528712c7fba7a59145c9dd9ca9f5e9b1ac8a68b126", - "Name": "matter_g1_mul_27", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000010cde0dbf4e18009c94ba648477624bbfb3732481d21663dd13cea914d6c54ec060557010ebe333d5e4b266e1563c631000000000000000000000000000000000fb24d3d4063fd054cd5b7288498f107114ff323226aca58d3336444fc79c010db15094ceda6eb99770c168d459f0da05061073223f066e35242772385c67aaefb3f7ea7df244d73369db1ea0b208792", - "Expected": "00000000000000000000000000000000028a89c904f63eb8e68096bd2001458a4b9b32556c93fab5e52ab26ed73d62f0489d6bf1906a62c8148d50d30222a65f0000000000000000000000000000000007e54f21e2ac6d5287289ed9e2a15d457b5dac22ef36c19cb28a6cf9a0d11c981bf6549ddaf7ddc0a59b3d3a4698d975", - "Name": "matter_g1_mul_28", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000008c0a4c543b7506e9718658902982b4ab7926cd90d4986eceb17b149d8f5122334903300ad419b90c2cb56dc6d2fe976000000000000000000000000000000000824e1631f054b666893784b1e7edb44b9a53596f718a6e5ba606dc1020cb6e269e9edf828de1768df0dd8ab8440e053f396ee22209271ea0bda10fb5e2584e7536e8bb1d00a0dd7b852b0aa653cd86c", - "Expected": "0000000000000000000000000000000008c39ee7c8d86a56ad1a9dbe005b4f0d44849d6fea6bbeb0732de725ad561befd49d465a134bd1a63a39eadbb6e0bce1000000000000000000000000000000000d5c892c92817fa24afb0a0fb319ad21e309edfb6300397a215e34eb3aadf91cb41b4ab1c5273bfea6eaf33982c75eba", - "Name": "matter_g1_mul_29", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000159d94fb0cf6f4e3e26bdeb536d1ee9c511a29d32944da43420e86c3b5818e0f482a7a8af72880d4825a50fee6bc8cd8000000000000000000000000000000000c2ffe6be05eccd9170b6c181966bb8c1c3ed10e763613112238cabb41370e2a5bb5fef967f4f8f2af944dbef09d265ef0d3d4cf46265fc0f69e093181f8b02114e492485696c671b648450c4fcd97aa", - "Expected": "000000000000000000000000000000000ba1650840e24c0f99ddd10a6c3341661e5c96b2e95cb6bda3340e7a0167c906e2f0ccbac6f0be2d7dbb3f9370a5ec960000000000000000000000000000000011638a3d9a81c0fe2ebb547808db758c7cfa8648b4835fb8c4931fd622da3a001fbce9a21d61f98f35b1e907913ffd25", - "Name": "matter_g1_mul_30", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad6242000000000000000000000000000000000353d6521a17474856ad69582ce225f27d60f5a8319bea8cefded2c3f6b862d76fe633c77ed8ccdf99d2b10430253fc8915b717562844d59623bc582f1a95fc678cf0d39af32560c6c06e3a74023c89c", - "Expected": "0000000000000000000000000000000000eccc25cfd8c5a58b330a74b92af0c2b932772eacfe898ff3d391fad5dfba52a3940e8edfc9bef5c4de670207c8585100000000000000000000000000000000095ae48a94c92c332915b0c07511bb0d54c316ff3a0dd2509a18a21320b506bbefa76a459260efdf4c045404f02e114d", - "Name": "matter_g1_mul_31", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff17d5c1c9fa11c36b86430cbb1f3ec10ebbe3787d0f5641d6d7fb96c810eda202dd", - "Expected": "0000000000000000000000000000000017a7f3b439a98885994a6832b6394b0ec9968f665b5810da58e3ece3d8e8694c482a15d3129732b43d4b7008660f19c000000000000000000000000000000000195299086d3b9448b26fe830522d520d132ed59744e677e6eb114ba7d7045019a0d0386cf817701ca3afad2a0487a689", - "Name": "matter_g1_mul_32", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c8129292540000000000000000000000000000000013a3d49e58274c2b4a534b95b7071b6d2f42b17b887bf128627c0f8894c19d3d69c1a419373ca4bd1bb6d4efc78e1d3fc00eb20fe7c292f3ad820a074d8b3d8d24506612752d8677c2d6ca24f556cc45", - "Expected": "00000000000000000000000000000000063c123a3cdb92469e7e57a18eaf3e7cab1d85d64cbcb52499d2e611e6ba71c717b0ebaf4cc9208b18c925a5ec167b78000000000000000000000000000000000fa5e78ae10ed8a4dee9440bfc7637d903404749681f85bcb62444d921c4fd809a646ffe3bb7c70dc906d07c62381415", - "Name": "matter_g1_mul_33", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda0000000000000000000000000000000014a461f829e0a76ba89f42eb57dffb4f5544df2008163bd0ea1af824f7ff910b27418a0e4f86cb8046dc1f3139cab9aff661d7b30fb11bef70e15b257d7073885468a380862202b2d705a84827644b5b", - "Expected": "00000000000000000000000000000000192b1497c71eb894a7509bbdaf308428e4d5899edb15f9e6e45a88340f55e1b76ee0901a830b66114deccda63a913a6b0000000000000000000000000000000017d58bd474a61ca0ceb23ec392dc08abe5697b8394fd60440cf787f15cddab36aa99c2ec2341bcc06dc1771b5f0fa139", - "Name": "matter_g1_mul_34", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000016404bd07b6c6480af2d23301940e61817ee2e61fc625c100b31e1b324c369a583b61048dd57ab97b80b1fe6cd64c5c3346ce87c847376c8967cc18297e6007dcfacb6424e1d273930f38bb0e88fc5ca", - "Expected": "0000000000000000000000000000000015f72ad769cbaa2bbce0aecef9559b825ba4ec17ec5be2d9f0dbc7184383eb3e201de5163e71f1e71655acd5ee1fb30000000000000000000000000000000000194d27d9045b9760e66b578af24b282d9aeb28eb51206d2e18dc04bcb6df90553a846736afd92b23aa004f8de90bbf9f", - "Name": "matter_g1_mul_35", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a0300000000000000000000000000000000053ee41f6a51c49b069f12de32e3e6b0b355cd2c3ba87a149c7de86136a5d9c5b7b59f2d1237964e548d1b62ec36c8db39a142c443a666499a880aa1cb9f523411bbc8e5554de099ab485b6c2c2e57cc", - "Expected": "00000000000000000000000000000000146f12001844bb0ec185e773175634f2e56bfa7190caa851ad16443b629b375ce3967b0c936d30dac2f126343722ce5e00000000000000000000000000000000080e8e90ed0d259ad803269711e511577769f7886b425f9b7857dc90ab36438cbd7435f6eecf2328f5fb6eb56f370163", - "Name": "matter_g1_mul_36", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000009cd91a281b96a881b20946fda164a987243c052378fcd8fee3926b75576dfa1d29a0aaca4b653da4e61da82577218082c01b7795c2d16b5bbbb1e107be36cc91b25130888956b0cdd344de9b4659447", - "Expected": "000000000000000000000000000000001344d2c2bc5ef45dc69597e948ed6021d84f7bf2c36119869a3f84288f3bdd6fc3a0de2b9e2564a930c2207c1ee36a0e000000000000000000000000000000000dc4d15ae09642ffa17d77510fb1ad4bf9e06084e9d352f4e234ea35f33458df4f23a209e29da42c41fb9a3cec3e8242", - "Name": "matter_g1_mul_37", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000011bf87b12734a6360d3dda4b452deede34470fba8e62a68f79153cc288a8e7fed98c74af862883b9861d2195a58262e0c712943d8795a6104f024b9701c70b09cdee9494755bbab0576e2c7f7c9d4828", - "Expected": "00000000000000000000000000000000084f2ed8573d5d04e41909d5c8ed3feb88f572726fc86d17d466276342f01503f7c8552498f8a7e96c875c4928b808f2000000000000000000000000000000000b618ca81b6ee891690099459634e011b5f59fb5c96488b0205139a65c77f15af135b3528a5ca3b794e7b2991d2434d6", - "Name": "matter_g1_mul_38", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000f26fdf1af1b8ad442ef4494627c815ca01ae84510944788b87f4aa2c8600ed310b9579318bc617a689b916bb7731dcbd4d77f6246c57d398c57848db8d3f986c475a41a23d424cd3cc2b362c1b99f2a", - "Expected": "0000000000000000000000000000000014733ee8425f42a30010366e4585cbbbdde6ed602a639bd299e63c113db3d797fa01075e24a042a060a043c9e1fa79f40000000000000000000000000000000013b44e1932681d238c52e959e1e3daa7a2e1ac67252ebea0cae90e8249f85b61812b9e09203d38d96f4916837b3693c8", - "Name": "matter_g1_mul_39", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a370000000000000000000000000000000003d2c7fe67cada2213e842ac5ec0dec8ec205b762f2a9c05fa12fa120c80eba30676834f0560d11ce9939fe210ad6c6341776ed9d1029918af4c5113a6110139b8bd7f938caa204373a28ddaa51430eb", - "Expected": "000000000000000000000000000000000ba15476a1346fbe9be2720721b592ce7c111b95f0b8738495e6c28487e12fcad60006314dfe68789e60f4df2db14eec000000000000000000000000000000000b44b9a9f695c94ad206717daa3128b672924d0db83ae0d47b62b3c79428f6fe151a65a39ae411e18b128d6796b67bbc", - "Name": "matter_g1_mul_40", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000b02ca2b0e6e0989ea917719b89caf1aa84b959e45b6238813bf02f40db95fbb3bf43d3017c3f9c57eab1be617f18032fa64411438542922a7bac10806efaa633d31d37c0b223314a8b6221155b9c425", - "Expected": "00000000000000000000000000000000070dfc697f7068180a7a792604d7b8453dbd393c993be9829a263ad5864c3575d3fb235692ab12a4dfa4221bc6e0c6d600000000000000000000000000000000123a9d9b83e2ca7c95de9602116b1e14d48175073e1fe766458e3fd4b6676f120adfcc5c497febe2f7ff68b1e3508e3c", - "Name": "matter_g1_mul_41", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c187229000000000000000000000000000000000096713619bf088bd9e12752cab83e9cdd58296ada8d338c86a749f00ba014087a3836ce10adaaf2e815f431235bff4f0e7002f41c6acab677a0ad023bad2a61b11c1b7221d944018b5ce60bb61e87e96", - "Expected": "000000000000000000000000000000000dcad6e29cda2332dff09377460c7a2b9d908ee53ab13f648cd892bf68a44ffcc8cd5d501f8b068f506b506d01d3f4430000000000000000000000000000000003aa625a60932474ca3f914a3e0aa8384533723f824b12c686a64863a734d96ba13670c8b355b52b0c01b49fbffb6149", - "Name": "matter_g1_mul_42", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a90000000000000000000000000000000002b03f02b45aa15b39e030c4b88c89a285dff5c4bbfe16f643f3f87d91db774f8ab7019285fda0b236ff7eec16496e5ec26e55f09b787c0542878e4d720027d9ea465f829a4e0164cf618c5d9cde49bc", - "Expected": "00000000000000000000000000000000023909bac6048bff0373d27a06dbbb8aba8ddbada93f4fea65c983598307f3c3a8cbe163462484ebb88165c6b6da41590000000000000000000000000000000002162d8a498670158c23daebb724168b5379d9124b064de871674a3ecd15e6b546366287563928a1e279fb1eb2ea0ba4", - "Name": "matter_g1_mul_43", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb00000000000000000000000000000000185e8671e2ddb8e36380e39fe4eafefbac9769935603c28caac7d3f7f0f3e8ad14e925024b55aeb67d68b219875c9d79bba67cc47e38a129ab1140fbcf0386ddba2feefc919aacdce6059a27a1e2efca", - "Expected": "000000000000000000000000000000000f79050036c4bb6c6b8e91abb300dc49a75b32faaaeb258661c905b4d936f4096d59de89b911de294603a0e3443fada5000000000000000000000000000000000985105497cd87d5ae2698479da55f6be9bc2cf5a2093b651d7305b67e36343debaf19c266ccb55c23f3de55bdae23a6", - "Name": "matter_g1_mul_44", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e2700000000000000000000000000000000123f973ab6bd3c2e5b0512a0c77ea0ac3003fd891e1262137f9444cd07b927b564e618205ba09220320ea1aa4564e820705fb566367d9fc142c4194b0525c16672b843aac1160f9056ebb115e80d377a", - "Expected": "0000000000000000000000000000000017901e77745a98c09d6740597c40f27df841cca6dd95653a1da6d8eb1c57d5ebffa6a7b894369b6b419c61462697080b0000000000000000000000000000000001732540a1bfa4a1a851106209ce4807d7c0a33816d3742ad5e2729229f3403940e03b93121b79bb94c24f7e60539ece", - "Name": "matter_g1_mul_45", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000002ec930fb58c898ede931384c5a5f9edd2f5c70b8c3794edb83a12f23be5400949f95e81c96c666c1a72dffb50b81158f7bfd990cc4dac62a0d730f56b4eb1c1ad77ca9cd58b089c23c2f6efa00b7fa4", - "Expected": "000000000000000000000000000000000f990d646495fff77d090f4a69b8af0e1762982b53ef8ae9bb955ad8b894942b85c7726587c9fd956ad58eb9e3ca25630000000000000000000000000000000007b7315e1f93cfba8076cf539aae01fd3bbe1cf92daa168a6fd6a2e7c969d35c51fe7eba04f1e0dd3e2020635f2c4f09", - "Name": "matter_g1_mul_46", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f100000000000000000000000000000000033f481fc62ab0a249561d180da39ff641a540c9c109cde41946a0e85d18c9d60b41dbcdec370c5c9f22a9ee9de00ccd807c5a41ae2baa1e10ebee15363d1d4569f731d77a418998108f5dfae0e90556", - "Expected": "000000000000000000000000000000000de9d7e58919ba6386f32af53ccf36cb0b834855ac8dcc19af3c3c9522c3db2985e51ba36067b61181cb0fe8b47d853a0000000000000000000000000000000010ff0800ed1b4067f8c920462f7abd7361dac2371716f7b8648d64a71cc7d53265db6d80b26b9efddd572a2273ab1b17", - "Name": "matter_g1_mul_47", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be10000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe9a7e300bcb3c740fd1f693d4c8915c4c46dcb627f6de6e4847f123623cd23bac7", - "Expected": "0000000000000000000000000000000011a11cc098144fe9bd42ec8845be76b6cae4b3001a79f4bbbf9f20e8ac8bca5b37ef8006c958318c3894aac7d6bf77e8000000000000000000000000000000000d5c1e6b78c40a356a35bfabfd66a81924d2eae6d428b5caacf8f3992ab980640e857e756e649ca83f5aa4bda7cd00b7", - "Name": "matter_g1_mul_48", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000fa57c1436615442bbb049d08ac46e501c07736cd239298752bb94d1904bd38cc687759987cadd99bd3c4d45ba07193ab473df5e282565a0783d23e65e283a103ebbddb5c884183cceb62fc32d0e9602", - "Expected": "0000000000000000000000000000000002e72f4568780fb41858edc3f5796f7936a30ee9ddc7b5034d9341614d301c7906238bfde3bcb77f063fe652a43b88270000000000000000000000000000000006f971f4a8ac554df7ae7ecdfab724410f1948af994d760c5f5977961f891ba4f4e76b27c3f0e5a1471ad017e91a9af7", - "Name": "matter_g1_mul_49", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b600000000000000000000000000000000175bdd42583cbbf733242510c152380525aff7649273acef1ec20569804ffba7f029ca06878dbafde84540cece173822a048ef7cf5d1f6f625ee3aba091147c389ebebc5b8f3d285e16ef4e8afe5c013", - "Expected": "0000000000000000000000000000000014b9ef8878af80f824748389d608bc9d0ffbca96230ed590d8e351586607a614f2658e348ac172f3184c1e5fde50f550000000000000000000000000000000000630f0556407c140d0a05b10ea65de48e4866e040455ebcd54fb6ed6996a6a3ac7a94a6818ba424936fa505c2c364124", - "Name": "matter_g1_mul_50", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000cbf7a31e6fef4f4664bca4bc87ec7c0b12ced7224300aa4e1a6a7cbdedfcef07482b5d20fa607e3f03fdd6dd03fd10ca9b63c6bf36997118d58600c1e429c105a379b9e8b0de934ab9f433a4fa63dc8", - "Expected": "000000000000000000000000000000000e66c8be115a941ef7adf4490faea39149a3d812c29d4afb36febe3f813c7390a715f838dda90cd73556f89abf3949120000000000000000000000000000000015d85c185cb86af3ca1c526ffa6e9459a9c699c5a4d57278f33b14691e980e0f86b9239e626fc4064890cb610f10e496", - "Name": "matter_g1_mul_51", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa0000000000000000000000000000000005aa892b0a056ff61706430f1daa3f0263dc01337eadabd8a7fd58152affd9aaa329e8c11ea98692134d9718cb4119bff228da17f49667c113d2bc2a2c8a338f80be68496f5145b4be21a5786ca6d46b", - "Expected": "0000000000000000000000000000000009db6ac72cdcf1f69c6593bc183aaa2b3980ff78a4417e23243f81243987ec6f2636641c9e9c738c7af2a1e9f94149d0000000000000000000000000000000000ca7537c04c06607e42403e84e7d9e55b2a06c730ec342f16d03689bb684918e85f637e7a6279d95cb7774f106139d0f", - "Name": "matter_g1_mul_52", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a0300000000000000000000000000000000166ce33c0482b5957c6e746c16908ba579d6402b230bc977d3ff29ac2a4a800748d9c14608f2519e2ac4d1fe4daf29b29431e18a462fba704216b516e819fb3392e315b0c92a7411a329cdafeb511244", - "Expected": "000000000000000000000000000000000620b092ea8cb718ae9669da4ff2faf639fb5e657b7759fdf292e6d841b51545afbabf95a98601847f64fc7367f872ff000000000000000000000000000000000a14bfc0e328310d62f116652b1de3a18282b122e0e3965619a099466986a546b73696274e12bd395224018a48b3d80d", - "Name": "matter_g1_mul_53", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f6046300000000000000000000000000000000148b5454f9b9868aefd2accc3318ddabfe618c5026e8c04f8a6bce76cd88e350bebcd779f2021fe7ceda3e8b4d438a0b2051041bd2f12f6e6e29924139770fe209b7bbdbcd6c0bcabbf5021a7dff2d83", - "Expected": "000000000000000000000000000000000a633928be3f3bb4c94cf4d8d7a8169779f8bd4bad31ede895937e8e8b0ddea956d255776141541ef5791aa3a0bc6d360000000000000000000000000000000003dc3b703753a7b8ccf7676b04cac8021aa311233a99e8d5290655d2f84555dedff62f9f81322307b538c3f3458f6313", - "Name": "matter_g1_mul_54", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a00000000000000000000000000000000016d2c22eabd4a06a5ae67b890a25fbede7d0e96c625b80329b19be6aa861f44b6e85778130d0bdf69f2abd491ee9751ab96df57a600dc3b5aabff5b1034886d24f6fcf035bcacaaec738deb2cfb8f852", - "Expected": "0000000000000000000000000000000014911a8b41cb65cb7ccb940a472cfa58861f1a506a4f719888eb35d48ed9774ea0a0dc3ba38760253bedb4a1acd0963a00000000000000000000000000000000031388c90440f22cc63a1e9450256e5cfcf2f7448641ac66b43d542c4b77e9c590b957efdb1c6d75846b3faccf033276", - "Name": "matter_g1_mul_55", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000f1afe9b199362f51cc84edb1d3cf2faf8e5bc0a734a646851ab83e213f73a3734114f255b611ec18db75694dcb0df9178176412b07eb7f423f23ffeaa0ee642590e0b7016bc063f3fffa93e1e35484c", - "Expected": "000000000000000000000000000000001968070c01f0aeeb42ab71730f5b78ec122c10ca9dac1764ff5e916fc85a5eb5ed406c03263c57858fb03b15ac0035550000000000000000000000000000000012ecfee330e1cc8006c73e9d41ac1947b67f8704d12faf8c0c05c2519dca68be7bdf88a58eb4825b35a1d270554d6ce9", - "Name": "matter_g1_mul_56", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000019275491a51599736722295659dd5589f4e3f558e3d45137a66b4c8066c7514ae66ec35c862cd00bce809db528040c049c4b5627d84e153f3a4ecc14ddd6baaf1d62253a0f88d3af51be18d991976da0", - "Expected": "000000000000000000000000000000001469e7ab4c3740701927da2b0e34508a73387aea671857b042dabbc65cb849f8c8ed0b7f8c8e37f80aeee98ba953f4e4000000000000000000000000000000000674212f9f8e1419608ccf1a0447533fbd6fda87a35cb9fb39c8a7daf5d12f450c12bfac9e9f872b2643b1f8f201439a", - "Name": "matter_g1_mul_57", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000a896c5a84cbd03e52ae77000eb0285f5704993664a744a89ff6b346efd2efec1a519b67229a3b87e1f80e6aa17e29462ed270764791aff081f1dc8051d22b8e18803a7e310393f21bb4a495a445cd45", - "Expected": "0000000000000000000000000000000009c756aec59a68832728b1133a69f0794f6a082e2f0f161e488078bec7420a0da19e812def625df9b12aa36d94d8a38600000000000000000000000000000000014aa28b18771ca07b7627446eb60d53bf4837541da661a0e5cadcfeaf58f5a650a39ac304f48e45d9b714cead9ba5d2", - "Name": "matter_g1_mul_58", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000001450bddfa14033ed8cdb94386715013ed9b2c4f9d65944e9d32c0b3545a085113e173e5afcfccb78878414a464d3184fbfb7606b64eef0460b8f33a0be54451fb655ce0b81db89eb7862f392450354f", - "Expected": "00000000000000000000000000000000153548fb1d7f1721c7fbdfeb167e1c060a90aab8f7b6572f4a2707de91b03a7b5e68f792a18d940167ae83d1380d6653000000000000000000000000000000000113bb747eab3987cd195e9eb755735698993332d517890f4e3285bf7274f8579ffcf84908a4758f0bb932021f2c76d6", - "Name": "matter_g1_mul_59", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f35556500000000000000000000000000000000120935947070451885bf0c328bd83def193831ab9353844a01130074f16a1ff4d20df8459b5ad6a57d5f1959d37aae928a29fcc442d0c2446697e94dc47181dca7a314f9073c06aba6dc55aa79978d7d", - "Expected": "0000000000000000000000000000000014ca98181489c96227f8052a77730ab446615cb7b2b00a600cdd7defe8b3ee1cd53a6d98892ffccda5fd4916e0cf5886000000000000000000000000000000001567c3207cbd42c0445ea96b464dbd9099b85f5df1932d152436c936623d92fdeb009e69919368134501fa9363a0b1c4", - "Name": "matter_g1_mul_60", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce00000000000000000000000000000000144f438d86d1d808d528ea60c5d343b427124af6e43d4d9652368ddc508daab32fd9c9425cba44fba72e3449e366b170d5b468797b4af1978983faebe59a28f34956dacf5b7f65d25548bcedb518f45a", - "Expected": "00000000000000000000000000000000139d093364c313d400603dba5a79479d566245a397f88aae748e110e09e7ab6dd271b8c37a90b86f6b48490ec1d0d8f3000000000000000000000000000000001099d4cb400f2d786dd2dd5d162580d2113c8405f51e8a619a6894d86a7f7ceb237289808acffa274069c24ee27c860c", - "Name": "matter_g1_mul_61", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ecdbc6afcdd409e5d50d7b655580f1144de77f3efe5d6268032eccab7deaaad997", - "Expected": "000000000000000000000000000000001247d4d3b1625ffccd350a9fc9759295637e91d9167d9bc72bbc1b60b1abb71dc29595b49ee1edc778f5219416bcd0cf000000000000000000000000000000000dfc69cdd0e4e126208b76a4e5fb8d032ae93031dde7da9bb1358507d4480881576c5d7cb7f0b3fa3032c0151650f2da", - "Name": "matter_g1_mul_62", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000b4e7355aea3488234552d3dddfa2d1ad3164056407770e6c54f764193c9dc044cb7f2b157a1c4153b2045867d6f99c5807347519f114e78f99617f6b147ca833bff7be962c9b1e1f32b5babe6067d7a", - "Expected": "000000000000000000000000000000000150849c60273de83f9ce2016238c273359ecf486adeacc4450e1d1a6cb79fc0d0fb38974489375d5763da8a5f4e743e00000000000000000000000000000000157ec6c2dd68dc5fb3cef4e935fedb74e1f0e856f1d75890bf995a08ed6b53b52e2e0d412ae190365b139101e7fe040f", - "Name": "matter_g1_mul_63", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679830630695c8dabe9aded1b5365bf93770aab7e9ef4140a2bbde2f0a7b109724d", - "Expected": "00000000000000000000000000000000024b59fbec5240fbdf3fb4e565bbec20f26edbc2a1bf7ecaaeb5278ed9fe13d1e360fa298e2d3f9b2880b00aff827f620000000000000000000000000000000013ca56975d9fd667bab347ed67fb96a433d57836ca4069976e12459152e1369154bd095a15980880e21fd02b1d7e3156", - "Name": "matter_g1_mul_64", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c184ef5eceadfd77b3a4092696ec34d0551c88e434567638623740b7d5f9e3616", - "Expected": "000000000000000000000000000000000aaff66eca5ddce81533afa27e2db1c25a2c6f0dc1dd7c2236d4c89cb9d2539e109cd1362dbfee86397156c3703d44e60000000000000000000000000000000013598d8ef4470998aec290e941576f5e94d696f7f0be40e3131b516a1679c5b0eba74dc9ae00ecb8f115e4613a50f3bb", - "Name": "matter_g1_mul_65", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f7a80d9efab033e920061cee8f8d7ea6023cc05f08340642613628b39e7b7fd0af", - "Expected": "00000000000000000000000000000000163cf5475fae000c38e59754cd29f1290ab2d6550552e9186555d1ce2960b7dca5834e0347699d2869b8c9bc42f6f717000000000000000000000000000000000b21bd3bfe50e0536135a910359527f80c130a08029c24f990c82f02727def21973a20a2021c95aaa3a7c8a980b44f33", - "Name": "matter_g1_mul_66", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d245111c860f6f5725f99b225c53b9fe1a70150e7ce922bfe214900aaa2790d145", - "Expected": "000000000000000000000000000000000bc3667c38602e7e1c018cc62933c013a9e78c375b50ba06f0c3d34fead5ec8a9658702a0856625a712520ac99afde230000000000000000000000000000000015c6b5487a52b41ae1a4634c8675f7b847aa5d319ee9eec0c92fc06d8e92e1cacc90ee394f8c90ce3e2c00307f53dec6", - "Name": "matter_g1_mul_67", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531fc07041840216d60ff445cf53b273a46016c8ecefefb53550f8bafc79966f863a", - "Expected": "000000000000000000000000000000001358e1724cb3ec4028a63e4252eff164defaa41b21042037ea9a1e06bc1a0a1e838afc1965ee665de3da0163d22682420000000000000000000000000000000019828e11831e3e4216d843ed3446345edb357b2082b7947fe71932dfd894543928ddddd8649d32b4f1349f63f60bf095", - "Name": "matter_g1_mul_68", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e787929b031b82dc8c9f4ea9524793b54207d4e13a548d73297f2aa6241aff57abfd0", - "Expected": "00000000000000000000000000000000130e09c096ce8ba86ae71a817426d929c7f9f8bfe00e76668b0041e935d1531d6f58e5eb743df3cf86fe88bdfda8c8a300000000000000000000000000000000187b25d8216fa3851bb6fbace998bf3f23dea80dd6e1cd94bb6a72d335702694804c6ef3d350519c5e781f941bb72f92", - "Name": "matter_g1_mul_69", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a63d26ae92119c7b06d83d7e2922e06559b1740eae315c6623d3e543c9bf54258", - "Expected": "0000000000000000000000000000000011e61e5158d9a7c59a5007732a76e27d14602e15159e8f62bd13be8b44c96736af5a77495c3da55c8244af6e60eb4f2c0000000000000000000000000000000008deda8447009898c89c6766e8add105892992585724d520c38d0d4f8c833f88d8c331e11b291b6def6847bfa9629d2b", - "Name": "matter_g1_mul_70", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f57a02c61a7a75342ee7f0745886c0ea2a73c21500aef8078d21d20b7216c2990e", - "Expected": "000000000000000000000000000000001182f2e45f06a729f82442ddb372f2eb8dbfccf12edd8df0764072c9f14cbe001893d932e89b948a643981ea8aa4fa41000000000000000000000000000000000910335dbdbef74b844a6f3b879d14c23c711ff2362213636ddab7eb1a44cd4b687659f8dd521c134b56bc4eed0ec5bc", - "Name": "matter_g1_mul_71", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b2567381b0c87102055dc2901826875d5e85a794befd93fccca2b9c0a1f70ef5610d83", - "Expected": "0000000000000000000000000000000019576d68ce66218d4c9e2e6fa9985451eea46ce60b11a74cf5ea9dbb9d0e8741d11436dfd77b0a8b490f4882cc5b416b00000000000000000000000000000000088ba5153e91738f7524034a2609848652a7e416fc68537ab2c16b6699f69695c62e5724dfda2f3b4f90277f5005bfa7", - "Name": "matter_g1_mul_72", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc3ebf66fce49c6beb12737fe05e3adc0a51ecfa9144ccf6253088dd1a7a483de07", - "Expected": "0000000000000000000000000000000005720fd4bff4da704edb7e317e3d41f1d1f45e3c1f22c1b98ee0b6875af414f6f58793e8ffd5c89bcec2af711973ca1600000000000000000000000000000000051441e34eed472766186a44b2028d86eebadd597cb7e3fa4f935d30aa043f11fb18670b31f0a3b8aa23bc8f05361064", - "Name": "matter_g1_mul_73", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a0305523dc79dc4b905e65587fbd095ed57aa42403d2df5dd489db8f50c99e9b6", - "Expected": "00000000000000000000000000000000141a0eb238edd1cdb670737d94f658fef728691620f9c6d98e34ed8bd166b38ae6912b5bd90ea21b091766ad27d689480000000000000000000000000000000002d0e7d2584586ab2f08cbd419df3defab53a287ca467b6b081e474711a23608831c1507bac4f328750731b99a06c6da", - "Name": "matter_g1_mul_74", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa3ac23d04ee3acc757aae6795532ce4c9f34534e506a4d843a26b052a040c79659", - "Expected": "000000000000000000000000000000001227b7021e9d3dc8bcbf5b346fc503f7f8576965769c5e22bb70056eef03c84b8c80290ae9ce20345770290c55549bce00000000000000000000000000000000188ddbbfb4ad2d34a8d3dc0ec92b70b63caa73ad7dea0cc9740bac2309b4bb11107912bd086379746e9a9bcd26d4db58", - "Name": "matter_g1_mul_75", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c88586d7ad8fc3e4fb42981a4415224c0d976ebe1c342e9bc1cd66d35168bae33d", - "Expected": "00000000000000000000000000000000187cb196679b6baf78a7908c37d7f31a9fcefa90b7cf165d0748a358e6dd86fc5c2d91ff1c4429a563b5962b821cbb01000000000000000000000000000000000d94711dc6efed34385579532f59964ab18b9debeac96044f3eec14cb36965f380d21d39c246e972aa2d5891ce417e9f", - "Name": "matter_g1_mul_76", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb2116e7db0fbd2a7327c85054b4c0de9727dc0b051058f8bb4ecb1dcc7f825781712", - "Expected": "000000000000000000000000000000001405c27eb28f58e7f66988a300df376f3536723e2ba5934d843ae629669485015c90a8da60ef5c00c63c0b08a00203a70000000000000000000000000000000000a62dc83ce27987849070a6022ab6a06186e2527f39ae94d5a23d2e4d234a465d50e03b0d7d175ed7f53ced0c3bbc8f", - "Name": "matter_g1_mul_77", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a85cc8d88273d4aa822f44a447cc22f5a58c420bcfe757a459772825619669a72", - "Expected": "00000000000000000000000000000000142fa228919f71f75df073927d03d9204b36a5177b4ab7bc995b59ff312034f7ff916635e27abbe775379aafc24a35c30000000000000000000000000000000014429fb137cf912995ca785902877e6675105b252a64282412798f883063824fc31cd79b356ea4e4822363b948ec27d1", - "Name": "matter_g1_mul_78", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b5b6e462d809f8bf1a62f276dcb27e42d9aa0ce33fc4e149e87181aca70a4ccc6", - "Expected": "000000000000000000000000000000000cf0aa7969ec44cc21bc8cca97fc8a581aecb63054c4fa3b7b69d28e0e2e901fa51c42a629145d9126e63aefe7978c8b00000000000000000000000000000000199d565f26b9c6496a4115eefc75f1066480f498a50314b396685a3ade8e50ab03c7f56316be2bcc02dff8b11ad5e4d9", - "Name": "matter_g1_mul_79", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d535b53ab5f1c596eb966f57867e021d0f3b099e17bf384479c959794b17d6a4b", - "Expected": "0000000000000000000000000000000000bf4256ce2a2a976e35a9eb266d11dc53d043f6fcafb47eee06e120457ea56decab47ef22b251c6cce17df9a7d91e3300000000000000000000000000000000152c438e11fe1d661eea7c631e04e02eb9204ebe52cbceca1ab6a9b4c889a1ebdda01d7505df29fe2204ef5787749a63", - "Name": "matter_g1_mul_80", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d506e0512ecbc5a1b02ab19bc9bee4d3d9c721278e07b7a6e389c4d6443232a4035", - "Expected": "0000000000000000000000000000000007754a49dcdde1354412d3fe2e108675fde8a1df069c86be54c4bec46338a0952aeed50842c2486ac652202c26a1861c00000000000000000000000000000000023fe3f5e6786e339002e14ac5c9fdaac3c012526b33da9ed314cdb145f9279a71e306f5d51243a0f0dcdf59bc5d55ed", - "Name": "matter_g1_mul_81", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad51a79fd15e80b694122dddb01f836460b3eff99e61ea6309d6b395c94fb5a43dff", - "Expected": "00000000000000000000000000000000141464b4326b0353aa99674bbd98853b926aa580c1e03673297bcbe9094eb1d795331d16d883e0583ed0551f064d7a0f0000000000000000000000000000000002dbbfb86c4d313bdbc8ebd266c190e38645016aca22261665dc850b0d7db8b240aacebec8af097724e5291ff43e6f90", - "Name": "matter_g1_mul_82", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a9251bd012914a96253926fdaabec06944ffcdb4637a05e3e78a9bcf1b21b68b9dd9b", - "Expected": "00000000000000000000000000000000118ab56a65ca63becc8aea3f11b370c705f32418d51fb1b1ab64bdb8f0125de2a760cf21e7ffd4d99e9d7cde1368791c00000000000000000000000000000000047674c8f3627527dbb41f51fa52c0fe3a921d07466cb2b5484e4c8094556cae247347a0a1a98499510d1ce5067480ac", - "Name": "matter_g1_mul_83", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f6a300c7e1041d94df0e0201e1135fa6eafc98bd33b2dfbe4c59b546a52538c07d", - "Expected": "0000000000000000000000000000000000d76cf9fa103355e6f5cd4baa3420e694f252249aa6171569b70cb43c906eae9b60bb79b41af8dc714bd917638bf538000000000000000000000000000000000b9272015e64f292d7b76867714a55d7223bb026f354b20109e81122fa13fd0426bb3aec705b477e7b9560c5a99c9d60", - "Name": "matter_g1_mul_84", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886233e9cdb10fc117afb17803b61a2bca7de1d190a325639eb23743f51f28294b33", - "Expected": "0000000000000000000000000000000007c87e6d92bd41b7fa6a6ca890bf0b58304875a79af7959d9226a5be2f4ac2b4531fd09712eb6299c23d7c1c5ba3997f00000000000000000000000000000000164fb86eafac39e06c2403e315bff96faecc57474bfc964736b1850696ecfedbaa0795e537b8f541159d479ac5b52560", - "Name": "matter_g1_mul_85", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8c48b98edd9c229037751d02e58f3d4234d9a3b0ad9ae4947ae14beebb274746f", - "Expected": "000000000000000000000000000000000fb01ce0567f09dc44fd473009d2467c8c16da5ea7b39a1f1dba7b3656cadd6bdf2bf68f96a43252d92e428c1d2785490000000000000000000000000000000008b4fa645f3c56459a17c912c82ca36165e730807282cabeadd9c6c4a12c8a592cbac265021ef62c60eb60df3ff61061", - "Name": "matter_g1_mul_86", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f594228758d2cf8105f2ef11d83018157a3119a44874dc34d5f0bddb533f50df52c", - "Expected": "000000000000000000000000000000000b9c328c8a18113e1d1f783432c857015eaefa724fa2c441d5ef76b158ee6fe0cd1775b0c6db7600754cbf25fea528fe0000000000000000000000000000000019d30c3557af1da2ca169e70625732d9a4396b51f3b4988a9aba1be62538fd51c167c83e921f4876224d361afc90eaf8", - "Name": "matter_g1_mul_87", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82fa417c96f0cf4355a78513c77cdc676a7b09125802c8045756da867e0025a36f1", - "Expected": "00000000000000000000000000000000041054430741e889d4cd8e7efa41547eb624bd775fd9fb64cf9e3dc2c6df27c95ffb8d76933ac4fa1952a5820ff88512000000000000000000000000000000000e8a28f5c622482b296a43ddb607e0f25635664fa849f3d6840ed7118892106a787bc07806dfd83935754d2057f2eff8", - "Name": "matter_g1_mul_88", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab446561328b7689b0a89014823537cf9eeaca6ea5c56a3e58d2abfc2ee455dfccb", - "Expected": "000000000000000000000000000000000da2286b44e7e90e19d51c3c41bef375c54688b07afffbd7c528589dbf7f012e1fd248b9067a3faae9f1c6b626a5c90b000000000000000000000000000000000bfa0a482b0fc445f7b99c52a48116383bb70d5f2ebec5b7715796fbd0da744d0467584bfc1c8a42ace833d57c167a24", - "Name": "matter_g1_mul_89", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c2cf6c3fcd4b9e6b72853934b306a078b1f2fb17879db4a0a93d484abbc2b746cf", - "Expected": "00000000000000000000000000000000148a7e9b0b4fde322f1177ced0bba34abec4a3e500afb86f9ae0a71bd75004e9c631d4cb26798bf963f7aa367f74630c00000000000000000000000000000000097f4c0893f9beadd66e4cfc6976dd277e527b1e31443e07554dacca52390066a4b37a7f0824cbaf51d3a555d696881b", - "Name": "matter_g1_mul_90", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a6f6787b565e8d71be6fdb0c97c4659389c800a2047f668b366214adc716f402d5", - "Expected": "0000000000000000000000000000000003e1d921b5e0280f7370d55967e716bdacb7521547e22190e89862dbfcce02dfe7fa7927a70e7bc33448b9321de3d8ae000000000000000000000000000000001163f78de4af8494666c64d47d68a0feb0905c42ddfa024398401202d1fe0d6672bd1bd4222a8d106668ba4617683485", - "Name": "matter_g1_mul_91", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e40ed91f6ceb2ccf87e4106a16227a3cd7b2821b4f3a6e629001f78ba1aa7346e", - "Expected": "000000000000000000000000000000000a94a186b96acbee87f9c1745dc301229ec750c6967262e629924227c6680b1d404e4b23d998611ad0e415610dc8edd900000000000000000000000000000000014da21c0f6930a79c8afbe42f73e048236b6d9f9ef8f270733fa1cb1012377eab37ddf2b9c742fea44020caeb95beb9", - "Name": "matter_g1_mul_92", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefbae8ddfcdb4748981acb9b2037c017174a140f2457fb0148fe807fd194a9f7be5", - "Expected": "0000000000000000000000000000000015cc6c31dfa9482c6341f816786562481bc3a4db4a4a00807a9c7c676eb32b9dc7e002ed4971f26c1dddea00d78721b5000000000000000000000000000000001303660b6bcac611b2d41a4f7ac9ecf3f0b4292f83f2fdeba300a060131322ee3c2da3ca3539114114ec8a76dee6a5ac", - "Name": "matter_g1_mul_93", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c35851268803aeb58a2d57fc797358fb456d5cf96afecb1ee0d2b90782aa0d652b8c0", - "Expected": "0000000000000000000000000000000009f1903e9a7d275487a503b9c968cd86823fe6667c09593b60ac2c88f306e20ccde32eebb5942a03fabde9195c5c500200000000000000000000000000000000179b41dbc2ede95ba7dad512329aeca9ca3bfd4da4b9620070d76d8fe8b49ad7fa92358070dd5098a2eaff490641edbb", - "Name": "matter_g1_mul_94", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728bf9a8a4e5c65973b785c1e2637937de239bb0fde34b786dceea66f6bb12eb4169", - "Expected": "000000000000000000000000000000000f9736431073987708757d61927a45cfec471c8366776e140f62d805afd948fd132c4a5f4049de3a1474d0cb52c3c25e000000000000000000000000000000001515b057952696810a90dce1ee8464fd6370e8af5434a99333eacd1fb2884f6e8c568f887030a4957ff6d24ca02f4657", - "Name": "matter_g1_mul_95", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000b767f399e4ebea34fd6b6b7f32a77f4a36841a12fc79e68910a963175d28cb634eeb8dc6e0533c662223c36b728cce2000000000000000000000000000000000cb3827fd6ac2c84f24f64789adac53439b4eba89409e12fbca0917faa6b7109aa831d16ca03191a124738228095ed65070e7e2ae2751a1f71962726a31f77553c2da38f4fecda435b6e5459d5e833b4", - "Expected": "00000000000000000000000000000000195460b2d59df32f9f41eaef1139d45f0cb8f35a7982c38d356a8a8412f25e600580026d2d908b0493edba5dbea85f5c0000000000000000000000000000000004b339d62b3cd4cc966c6b4038adb302f997a16d8a6dfebd153295de08e57d1513cf0f16d82dc450e4d6f52621a42fb4", - "Name": "matter_g1_mul_96", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000150b75e9e9c03ada40b607f3d648bd6c40269aba3a1a992986dc005c9fde80bb1605266add0819641a0ca702d67bceed00000000000000000000000000000000083b43df032654f2dce90c8049ae4872a39f9cd860f08512930f43898e0f1e5625a5620818788797f3ca68134bc27d22d16aa883a20307f5436354bab32b4633e83178f33626af3edb14f82724b8e125", - "Expected": "0000000000000000000000000000000012cf2bcb79668067b7a265672ca614405868cf189ee9789b9e1e3186d231176dab5fea86cc5865392db8c75fc5d124c900000000000000000000000000000000121bf40feea00e151b718157b8c024f126762d84cff20aac08e7f2a027ab88b33e134a410c2af279a39618f7d21482a0", - "Name": "matter_g1_mul_97", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000cba419694214e95a3605a9b748854d16c8e6e1ee151c907487d8189acfac1361b790a5e78f43593152027295adf8df400000000000000000000000000000000110813ff6e0ddf3427e2a514d3f0bfbadcaf9dbf039e0f93fb9643d1e62bc2469fe84cd9ff0d585bdd1037255bbe5485041390a2209b80f7c64d14965cc2f515d5fbdf37953f75c4a0203bf0d9fb674b", - "Expected": "0000000000000000000000000000000013a530f94e7600820dbd8aabefde2acb8b3c74e833457102fbd297317eb532c0622636ef9e9376fac1637dc745fe895000000000000000000000000000000000139eb14d3b69be977413c832bfda234348186d46fe177154e34fe204f62ac79f4b0f59bbef39b0676d81ea42a0946fb3", - "Name": "matter_g1_mul_98", - "Gas": 12000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000106df8eba767e90cce0eabdaacc24d8e226c6865012ef8cb1460de5a319d443fdc6b4f4e58fb668943e0528b1809da10000000000000000000000000000000019789f464c95c179af18704c0b67b881991880f75ee7b03b9feafa3eafcd0f7d30a17fdd9cf439ff7fe683adca2083b57cf23dee8d95d94046678f3bdb4b0ea3d4e3a1a2f07f582e2a98ad6eb7562cbf", - "Expected": "000000000000000000000000000000000bf700422a382546a74376b0292f3a49ceff5597f0d2b726b1ff099bcda7ba92238a21db12eff5c314a29dd2387bec850000000000000000000000000000000005e22e3c772f3634b1ccf4e311241977eb20e7269540ef22d379de26ab80c58461dfa3b67848e0d584fb11de1917949a", - "Name": "matter_g1_mul_99", + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a219a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g1mul_random*p1_unnormalized_scalar", + "Expected": "0000000000000000000000000000000006ee9c9331228753bcb148d0ca8623447701bb0aa6eafb0340aa7f81543923474e00f2a225de65c62dd1d8303270220c0000000000000000000000000000000018dd7be47eb4e80985d7a0d2cc96c8b004250b36a5c3ec0217705d453d3ecc6d0d3d1588722da51b40728baba1e93804", "Gas": 12000, "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 b708f3c0a6..138fcbfcb6 100644 --- a/core/vm/testdata/precompiles/blsG1MultiExp.json +++ b/core/vm/testdata/precompiles/blsG1MultiExp.json @@ -3,987 +3,1078 @@ "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000011", "Expected": "000000000000000000000000000000001098f178f84fc753a76bb63709e9be91eec3ff5f7f3a5f4836f34fe8a1a6d6c5578d8fd820573cef3a01e2bfef3eaf3a000000000000000000000000000000000ea923110b733b531006075f796cc9368f2477fe26020f465468efbb380ce1f8eebaf5c770f31d320f9bd378dc758436", "Name": "bls_g1multiexp_single", - "Gas": 14400, + "Gas": 12000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000e12039459c60491672b6a6282355d8765ba6272387fb91a3e9604fa2a81450cf16b870bb446fc3a3e0a187fff6f89450000000000000000000000000000000018b6c1ed9f45d3cbc0b01b9d038dcecacbd702eb26469a0eb3905bd421461712f67f782b4735849644c1772c93fe3d09000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000147b327c8a15b39634a426af70c062b50632a744eddd41b5a4686414ef4cd9746bb11d0a53c6c2ff21bbcf331e07ac9200000000000000000000000000000000078c2e9782fa5d9ab4e728684382717aa2b8fad61b5f5e7cf3baa0bc9465f57342bb7c6d7b232e70eebcdbf70f903a450000000000000000000000000000000000000000000000000000000000000034", "Expected": "000000000000000000000000000000001339b4f51923efe38905f590ba2031a2e7154f0adb34a498dfde8fb0f1ccf6862ae5e3070967056385055a666f1b6fc70000000000000000000000000000000009fb423f7e7850ef9c4c11a119bb7161fe1d11ac5527051b29fe8f73ad4262c84c37b0f1b9f0e163a9682c22c7f98c80", "Name": "bls_g1multiexp_multiple", - "Gas": 27504, + "Gas": 30528, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d2800000000000000000000000000000000000000000000000000000000000020590000000000000000000000000000000009ece308f9d1f0131765212deca99697b112d61f9be9a5f1f3780a51335b3ff981747a0b2ca2179b96d2c0c9024e522400000000000000000000000000000000032b80d3a6f5b09f8a84623389c5f80ca69a0cddabc3097f9d9c27310fd43be6e745256c634af45ca3473b0590ae30d100000000000000000000000000000000000000000000000000000000000b7fa3000000000000000000000000000000000c9b60d5afcbd5663a8a44b7c5a02f19e9a77ab0a35bd65809bb5c67ec582c897feb04decc694b13e08587f3ff9b5b6000000000000000000000000000000000143be6d078c2b79a7d4f1d1b21486a030ec93f56aa54e1de880db5a66dd833a652a95bee27c824084006cb5644cbd43f0000000000000000000000000000000000000000000000000000000004165ef10000000000000000000000000000000010e7791fb972fe014159aa33a98622da3cdc98ff707965e536d8636b5fcc5ac7a91a8c46e59a00dca575af0f18fb13dc0000000000000000000000000000000016ba437edcc6551e30c10512367494bfb6b01cc6681e8a4c3cd2501832ab5c4abc40b4578b85cbaffbf0bcd70d67c6e20000000000000000000000000000000000000000000000000000000173f3bfab0000000000000000000000000000000006e82f6da4520f85c5d27d8f329eccfa05944fd1096b20734c894966d12a9e2a9a9744529d7212d33883113a0cadb9090000000000000000000000000000000017d81038f7d60bee9110d9c0d6d1102fe2d998c957f28e31ec284cc04134df8e47e8f82ff3af2e60a6d9688a4563477c0000000000000000000000000000000000000000000000000000008437a521c9000000000000000000000000000000001928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb700000000000000000000000000000000108dadbaa4b636445639d5ae3089b3c43a8a1d47818edd1839d7383959a41c10fdc66849cfa1b08c5a11ec7e28981a1c00000000000000000000000000000000000000000000000000002effc7b3027300000000000000000000000000000000085ae765588126f5e860d019c0e26235f567a9c0c0b2d8ff30f3e8d436b1082596e5e7462d20f5be3764fd473e57f9cf0000000000000000000000000000000019e7dfab8a794b6abb9f84e57739de172a63415273f460d1607fa6a74f0acd97d9671b801dd1fd4f18232dd1259359a10000000000000000000000000000000000000000000000000010b4ebfca1dee10000000000000000000000000000000019cdf3807146e68e041314ca93e1fee0991224ec2a74beb2866816fd0826ce7b6263ee31e953a86d1b72cc2215a577930000000000000000000000000000000007481b1f261aabacf45c6e4fc278055441bfaf99f604d1f835c0752ac9742b4522c9f5c77db40989e7da608505d4861600000000000000000000000000000000000000000000000005f04fe2cd8a39fb000000000000000000000000000000000f81da25ecf1c84b577fefbedd61077a81dc43b00304015b2b596ab67f00e41c86bb00ebd0f90d4b125eb0539891aeed0000000000000000000000000000000011af629591ec86916d6ce37877b743fe209a3af61147996c1df7fd1c47b03181cd806fd31c3071b739e4deb234bd9e190000000000000000000000000000000000000000000000021c6c659f10229c390000000000000000000000000000000000fd75ebcc0a21649e3177bcce15426da0e4f25d6828fbf4038d4d7ed3bd4421de3ef61d70f794687b12b2d571971a550000000000000000000000000000000004523f5a3915fc57ee889cdb057e3e76109112d125217546ccfe26810c99b130d1b27820595ad61c7527dc5bbb132a900000000000000000000000000000000000000000000000c01a881f8abc4d8843000000000000000000000000000000000345dd80ffef0eaec8920e39ebb7f5e9ae9c1d6179e9129b705923df7830c67f3690cbc48649d4079eadf5397339580c00000000000000000000000000000000083d3baf25e42f2845d8fa594dda2e0f40a4d670dda40f30da0aff0d81c87ac3d687fe84eca72f34c7c755a045668cf10000000000000000000000000000000000000000000044496e633650ef8f6fd100000000000000000000000000000000051f8a0b82a6d86202a61cbc3b0f3db7d19650b914587bde4715ccd372e1e40cab95517779d840416e1679c84a6db24e000000000000000000000000000000000b6a63ac48b7d7666ccfcf1e7de0097c5e6e1aacd03507d23fb975d8daec42857b3a471bf3fc471425b63864e045f4df00000000000000000000000000000000000000000018461a3d444ec527fcbf4b0000000000000000000000000000000019bef05aaba1ea467fcbc9c420f5e3153c9d2b5f9bf2c7e2e7f6946f854043627b45b008607b9a9108bb96f3c1c089d3000000000000000000000000000000000adb3250ba142db6a748a85e4e401fa0490dd10f27068d161bd47cb562cc189b3194ab53a998e48a48c65e071bb54117000000000000000000000000000000000000000008a0eb53c748001536d7ffa9000000000000000000000000000000000d9e19b3f4c7c233a6112e5397309f9812a4f61f754f11dd3dcb8b07d55a7b1dfea65f19a1488a14fef9a414950835820000000000000000000000000000000009d0d1f706f1a85a98f3efaf5c35a41c9182afc129285cf2db3212f6ea0da586ca539bc66181f2ccb228485dd8aff0a700000000000000000000000000000000000000031133a6c7d698078a7ec7e11300000000000000000000000000000000073eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086000000000000000000000000000000001825bacd18f695351f843521ebeada20352c3c3965626f98bc4c68e6ff7c4eed38b48f328204bbb9cd461511d24ebfb300000000000000000000000000000000000001171d5c4909480aae3b110d01c1000000000000000000000000000000001098f178f84fc753a76bb63709e9be91eec3ff5f7f3a5f4836f34fe8a1a6d6c5578d8fd820573cef3a01e2bfef3eaf3a000000000000000000000000000000000ea923110b733b531006075f796cc9368f2477fe26020f465468efbb380ce1f8eebaf5c770f31d320f9bd378dc75843600000000000000000000000000000000000063376fcdf64c9bcbeeff0f9f9f9b000000000000000000000000000000001252a4ac3529f8b2b6e8189b95a60b8865f07f9a9b73f98d5df708511d3f68632c4c7d1e2b03e6b1d1e2c01839752ada0000000000000000000000000000000002a1bc189e36902d1a49b9965eca3cb818ab5c26dffca63ca9af032870f7bbc615ac65f21bed27bd77dd65f2e90f535800000000000000000000000000000000002344b4be368d3b617df4aa8dbdbc19000000000000000000000000000000001271205227c7aa27f45f20b3ba380dfea8b51efae91fd32e552774c99e2a1237aa59c0c43f52aad99bba3783ea2f36a4000000000000000000000000000000001407ffc2c1a2fe3b00d1f91e1f4febcda31004f7c301075c9031c55dd3dfa8104b156a6a3b7017fccd27f81c2af222ef000000000000000000000000000000000c896c3f9d64341ba7c5f8a06271dce3000000000000000000000000000000000272e9d1d50a4aea7d8f0583948090d0888be5777f2846800b8281139cd4aa9eee05f89b069857a3e77ccfaae1615f9c0000000000000000000000000000000016ab25d6a997bcac8999d481633caa41606894aae9770cdb54aac65ac0a454dd0346b3428fefd837b1e3f654f8217f4a0000000000000000000000000000000474d97a9cf29e85d4a35f6102fe7984b1000000000000000000000000000000001780e853f8ce7eda772c6691d25e220ca1d2ab0db51a7824b700620f7ac94c06639e91c98bb6abd78128f0ec845df8ef00000000000000000000000000000000095bc13d5a05c686e20d7b904db4931272d84d051a516fbb23acf7981d39bffa3943d08a9be01fc48e5241cd8b775ddd00000000000000000000000000000195894e95ca3e59929612e77c1075322aeb000000000000000000000000000000000b48aa2cc6f4a0bb63b5d67be54ac3aed10326dda304c5aeb9e942b40d6e7610478377680ab90e092ef1895e62786008000000000000000000000000000000000f6fc00c0697119a34363c0294acf608eca3c680d80183a59c89b45a66dc750f818a27e3a6e136d69e7580a8afca001b00000000000000000000000000009027ceef3ee429d71b58b84919d9a8d54189000000000000000000000000000000000c8b694b04d98a749a0763c72fc020ef61b2bb3f63ebb182cb2e568f6a8b9ca3ae013ae78317599e7e7ba2a528ec754a000000000000000000000000000000000951b70c206350e1edc2aefdfaa95318368c151e01e468b9fb1cf7c3c6575e4f06c135715cc5e51e1b492d19adf9bee000000000000000000000000000333e268f0b5b1adf76b88981fc305f03ce4bb3000000000000000000000000000000001717182463fbe215168e6762abcbb55c5c65290f2b5a2af616f8a6f50d625b46164178a11622d21913efdfa4b800648d0000000000000000000000000000000008531aa42aa092a91e0894d84ff0bcec0d37cede43dec85cca80ffad335d6f69da18335869ba1174f73bb37501404d6f000000000000000000000000123717b4d909628d6f3398e134a531c65a54e8a1000000000000000000000000000000000cb58c81ae0cae2e9d4d446b730922239923c345744eee58efaadb36e9a0925545b18a987acf0bad469035b291e37269000000000000000000000000000000001678cefdd942f60480b5f69738a6a4cea5e1a9239d1bd5f701ad96c2dd1fd252f0aeea219bddcda4bc8f83983a282aff00000000000000000000000679956d49265608468757580db6b8b1821c2eb13b", "Expected": "0000000000000000000000000000000005548dad0613ef8804a347152e8267acdbbcab98a795fc0da2d9df5c8ec37e0eb32e82950fbe5f8ec330b8bffafe13e40000000000000000000000000000000014e94dbbf60d89b3f68a5a076fcbd7cc0b683eae228f5d5036ee61012996ae2d347cec19dbd4eab547fadecdb31c078a", "Name": "bls_g1multiexp_larger", - "Gas": 89400, + "Gas": 193500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed24d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be10000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e44c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d38964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1baaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e10000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442adac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd1080000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f81876720000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c760000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276bdd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a57876817010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f76894c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931db3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746", "Expected": "000000000000000000000000000000000b370fc4ca67fb0c3c270b1b4c4816ef953cd9f7cf6ad20e88099c40aace9c4bb3f4cd215e5796f65080c69c9f4d2a0f0000000000000000000000000000000007203220935ddc0190e2d7a99ec3f9231da550768373f9a5933dffd366f48146f8ea5fe5dee6539d925288083bb5a8f1", "Name": "matter_g1_multiexp_0", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d507f80a5e502f63375d672379584e11e41d58d2ed58f3e5c3f67d9ea1138493cf00000000000000000000000000000000043c4ff154778330b4d5457b7811b551dbbf9701b402230411c527282fb5d2ba12cb445709718d5999e79fdd74c0a67000000000000000000000000000000000013a80ede40df002b72f6b33b1f0e3862d505efbe0721dce495d18920d542c98cdd2daf5164dbd1a2fee917ba943debebb169138f94093d5c1c6b253cc001ce8baf78858dae053173fa812d2d1c800da0000000000000000000000000000000009f9a78a70b9973c43182ba54bb6e363c6984d5f7920c1d347c5ff82e6093e73f4fb5e3cd985c9ddf9af936b16200e880000000000000000000000000000000008d7489c2d78f17b2b9b1d535f21588d8761b8fb323b08fa9af8a60f39b26e98af76aa883522f21e083c8a14c2e7edb6e40608bdaf3e7764358a64a920cbb33ab4d571c7b3092e1ae11d9697f82ed8330000000000000000000000000000000010fcfe8af8403a52400bf79e1bd0058f66b9cab583afe554aa1d82a3e794fffad5f0e19d385263b2dd9ef69d1154f10a000000000000000000000000000000000aba6a0b58b49f7c6c2802afd2a5ed1320bf062c7b93135f3c0ed7a1d7b1ee27b2b986cde732a60fa585ca6ab7cc154bd411519f2a33b07f65e7d721950e0f0d5161c71a402810e46817627a17c56c0f0000000000000000000000000000000013c5ebfb853f0c8741f12057b6b845c4cdbf72aecbeafc8f5b5978f186eead8685f2f3f125e536c465ade1a00f212b0900000000000000000000000000000000082543b58a13354d0cce5dc3fb1d91d1de6d5927290b2ff51e4e48f40cdf2d490730843b53a92865140153888d73d4af6bb3f9e512311699f110a5e6ae57e0a7d2caaa8f94e41ca71e4af069a93d08cc00000000000000000000000000000000053a12f6a1cb64272c34e042b7922fabe879275b837ba3b116adfe1eb2a6dc1c1fa6df40c779a7cdb8ed8689b8bc5ba800000000000000000000000000000000097ec91c728ae2d290489909bbee1a30048a7fa90bcfd96fe1d9297545867cbfee0939f20f1791329460a4fe1ac719292a0c988d97e86dccaeb8bd4e27f9e30fad5d5742202cdde17d800642db633c52000000000000000000000000000000001354dd8a230fde7c983dcf06fa9ac075b3ab8f56cdd9f15bf870afce2ae6e7c65ba91a1df6255b6f640bb51d7fed302500000000000000000000000000000000130f139ca118869de846d1d938521647b7d27a95b127bbc53578c7b66d88d541adb525e7028a147bf332607bd760deac0b299c14892e0519b0accfa17e1a758c8aae54794fb61549f1396395c967e1b10000000000000000000000000000000003f76a6dc6da31a399b93f4431bfabb3e48d86745eaa4b24d6337305006e3c7fc7bfcc85c85e2f3514cd389fec4e70580000000000000000000000000000000010e4280374c532ed0df44ac0bac82572f839afcfb8b696eea617d5bd1261288dfa90a7190200687d470992fb4827ff327064d43d6802ad4c3794705065f870263fef19b81604839c9dea8648388094e90000000000000000000000000000000009439f061c7d5fada6e5431c77fd093222285c98449951f6a6c4c8f225b316144875bc764be5ca51c7895773a9f1a640000000000000000000000000000000000ebdef273e2288c784c061bef6a45cd49b0306ac1e9faab263c6ff73dea4627189c8f10a823253d86a8752769cc4f8f2686285a0e22f177fe3adbfc435e9c1786752dcf3c11b723539789b0cdeb0647b000000000000000000000000000000001478ee0ffebf22708a6ab88855081daba5ee2f279b5a2ee5f5f8aec8f97649c8d5634fec3f8b28ad60981e6f29a091b10000000000000000000000000000000011efaeec0b1a4057b1e0053263afe40158790229c5bfb08062c90a252f59eca36085ab35e4cbc70483d29880c5c2f8c23176b6724cf984632daf95c869d56838ab2baef94be3a4bd15df2dd8e49a90a600000000000000000000000000000000150d43c64cb1dbb7b981f455e90b740918e2d63453ca17d8eeecb68e662d2581f8aa1aea5b095cd8fc2a941d6e2728390000000000000000000000000000000006dc2ccb10213d3f6c3f10856888cb2bf6f1c7fcb2a17d6e63596c29281682cafd4c72696ecd6af3cce31c440144ebd1d76db3dcb659eaf6c086be6b414a494dea4bd30aef8450ae639f473148c05b36000000000000000000000000000000000f46bb86e827aa9c0c570d93f4d7d6986668c0099e4853927571199e1ce9e756d9db951f5b0325acafb2bf6e8fec2a1b0000000000000000000000000000000006d38cc6cc1a950a18e92e16287f201af4c014aba1a17929dd407d0440924ce5f08fad8fe0c50f7f733b285bf282acfc9915646de2449b3cb78d142b6018f3da7a16769722ec2c7185aedafe2699a8bc0000000000000000000000000000000010cde0dbf4e18009c94ba648477624bbfb3732481d21663dd13cea914d6c54ec060557010ebe333d5e4b266e1563c631000000000000000000000000000000000fb24d3d4063fd054cd5b7288498f107114ff323226aca58d3336444fc79c010db15094ceda6eb99770c168d459f0da05061073223f066e35242772385c67aaefb3f7ea7df244d73369db1ea0b2087920000000000000000000000000000000008c0a4c543b7506e9718658902982b4ab7926cd90d4986eceb17b149d8f5122334903300ad419b90c2cb56dc6d2fe976000000000000000000000000000000000824e1631f054b666893784b1e7edb44b9a53596f718a6e5ba606dc1020cb6e269e9edf828de1768df0dd8ab8440e053f396ee22209271ea0bda10fb5e2584e7536e8bb1d00a0dd7b852b0aa653cd86c00000000000000000000000000000000159d94fb0cf6f4e3e26bdeb536d1ee9c511a29d32944da43420e86c3b5818e0f482a7a8af72880d4825a50fee6bc8cd8000000000000000000000000000000000c2ffe6be05eccd9170b6c181966bb8c1c3ed10e763613112238cabb41370e2a5bb5fef967f4f8f2af944dbef09d265ef0d3d4cf46265fc0f69e093181f8b02114e492485696c671b648450c4fcd97aa0000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad6242000000000000000000000000000000000353d6521a17474856ad69582ce225f27d60f5a8319bea8cefded2c3f6b862d76fe633c77ed8ccdf99d2b10430253fc8915b717562844d59623bc582f1a95fc678cf0d39af32560c6c06e3a74023c89c", "Expected": "0000000000000000000000000000000017479d99909c144a5a5fdfd71721f4a2ee90b2b9654e069a38b460945b9291fc74e6922a7dbab9bb12b4bff9e2d0175b0000000000000000000000000000000015cfff11afe08d76944c9f810017ecf78b8ed54096078195d65a5418f660cf9b2024646a8532e349eac5d32d59c829db", "Name": "matter_g1_multiexp_1", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff17d5c1c9fa11c36b86430cbb1f3ec10ebbe3787d0f5641d6d7fb96c810eda202dd0000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c8129292540000000000000000000000000000000013a3d49e58274c2b4a534b95b7071b6d2f42b17b887bf128627c0f8894c19d3d69c1a419373ca4bd1bb6d4efc78e1d3fc00eb20fe7c292f3ad820a074d8b3d8d24506612752d8677c2d6ca24f556cc4500000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda0000000000000000000000000000000014a461f829e0a76ba89f42eb57dffb4f5544df2008163bd0ea1af824f7ff910b27418a0e4f86cb8046dc1f3139cab9aff661d7b30fb11bef70e15b257d7073885468a380862202b2d705a84827644b5b000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000016404bd07b6c6480af2d23301940e61817ee2e61fc625c100b31e1b324c369a583b61048dd57ab97b80b1fe6cd64c5c3346ce87c847376c8967cc18297e6007dcfacb6424e1d273930f38bb0e88fc5ca0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a0300000000000000000000000000000000053ee41f6a51c49b069f12de32e3e6b0b355cd2c3ba87a149c7de86136a5d9c5b7b59f2d1237964e548d1b62ec36c8db39a142c443a666499a880aa1cb9f523411bbc8e5554de099ab485b6c2c2e57cc00000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000009cd91a281b96a881b20946fda164a987243c052378fcd8fee3926b75576dfa1d29a0aaca4b653da4e61da82577218082c01b7795c2d16b5bbbb1e107be36cc91b25130888956b0cdd344de9b4659447000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000011bf87b12734a6360d3dda4b452deede34470fba8e62a68f79153cc288a8e7fed98c74af862883b9861d2195a58262e0c712943d8795a6104f024b9701c70b09cdee9494755bbab0576e2c7f7c9d48280000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000f26fdf1af1b8ad442ef4494627c815ca01ae84510944788b87f4aa2c8600ed310b9579318bc617a689b916bb7731dcbd4d77f6246c57d398c57848db8d3f986c475a41a23d424cd3cc2b362c1b99f2a000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a370000000000000000000000000000000003d2c7fe67cada2213e842ac5ec0dec8ec205b762f2a9c05fa12fa120c80eba30676834f0560d11ce9939fe210ad6c6341776ed9d1029918af4c5113a6110139b8bd7f938caa204373a28ddaa51430eb00000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000b02ca2b0e6e0989ea917719b89caf1aa84b959e45b6238813bf02f40db95fbb3bf43d3017c3f9c57eab1be617f18032fa64411438542922a7bac10806efaa633d31d37c0b223314a8b6221155b9c425000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c187229000000000000000000000000000000000096713619bf088bd9e12752cab83e9cdd58296ada8d338c86a749f00ba014087a3836ce10adaaf2e815f431235bff4f0e7002f41c6acab677a0ad023bad2a61b11c1b7221d944018b5ce60bb61e87e96000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a90000000000000000000000000000000002b03f02b45aa15b39e030c4b88c89a285dff5c4bbfe16f643f3f87d91db774f8ab7019285fda0b236ff7eec16496e5ec26e55f09b787c0542878e4d720027d9ea465f829a4e0164cf618c5d9cde49bc000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb00000000000000000000000000000000185e8671e2ddb8e36380e39fe4eafefbac9769935603c28caac7d3f7f0f3e8ad14e925024b55aeb67d68b219875c9d79bba67cc47e38a129ab1140fbcf0386ddba2feefc919aacdce6059a27a1e2efca000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e2700000000000000000000000000000000123f973ab6bd3c2e5b0512a0c77ea0ac3003fd891e1262137f9444cd07b927b564e618205ba09220320ea1aa4564e820705fb566367d9fc142c4194b0525c16672b843aac1160f9056ebb115e80d377a000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000002ec930fb58c898ede931384c5a5f9edd2f5c70b8c3794edb83a12f23be5400949f95e81c96c666c1a72dffb50b81158f7bfd990cc4dac62a0d730f56b4eb1c1ad77ca9cd58b089c23c2f6efa00b7fa40000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f100000000000000000000000000000000033f481fc62ab0a249561d180da39ff641a540c9c109cde41946a0e85d18c9d60b41dbcdec370c5c9f22a9ee9de00ccd807c5a41ae2baa1e10ebee15363d1d4569f731d77a418998108f5dfae0e90556", "Expected": "0000000000000000000000000000000001c143e5d7bba56a959b94955f8eaab82a92a2e2b355baac7da0b57281645c689486059fb590ef2576a7a03a7c57e85d00000000000000000000000000000000182b1e16004c7e6f55923dd0b1dfa7346d1243996070db78f45c4c0a2cef95e93c6373903b5e0dc63f171c8164c2fb5a", "Name": "matter_g1_multiexp_2", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be10000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe9a7e300bcb3c740fd1f693d4c8915c4c46dcb627f6de6e4847f123623cd23bac700000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000fa57c1436615442bbb049d08ac46e501c07736cd239298752bb94d1904bd38cc687759987cadd99bd3c4d45ba07193ab473df5e282565a0783d23e65e283a103ebbddb5c884183cceb62fc32d0e9602000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b600000000000000000000000000000000175bdd42583cbbf733242510c152380525aff7649273acef1ec20569804ffba7f029ca06878dbafde84540cece173822a048ef7cf5d1f6f625ee3aba091147c389ebebc5b8f3d285e16ef4e8afe5c0130000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000cbf7a31e6fef4f4664bca4bc87ec7c0b12ced7224300aa4e1a6a7cbdedfcef07482b5d20fa607e3f03fdd6dd03fd10ca9b63c6bf36997118d58600c1e429c105a379b9e8b0de934ab9f433a4fa63dc80000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa0000000000000000000000000000000005aa892b0a056ff61706430f1daa3f0263dc01337eadabd8a7fd58152affd9aaa329e8c11ea98692134d9718cb4119bff228da17f49667c113d2bc2a2c8a338f80be68496f5145b4be21a5786ca6d46b0000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a0300000000000000000000000000000000166ce33c0482b5957c6e746c16908ba579d6402b230bc977d3ff29ac2a4a800748d9c14608f2519e2ac4d1fe4daf29b29431e18a462fba704216b516e819fb3392e315b0c92a7411a329cdafeb51124400000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f6046300000000000000000000000000000000148b5454f9b9868aefd2accc3318ddabfe618c5026e8c04f8a6bce76cd88e350bebcd779f2021fe7ceda3e8b4d438a0b2051041bd2f12f6e6e29924139770fe209b7bbdbcd6c0bcabbf5021a7dff2d830000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a00000000000000000000000000000000016d2c22eabd4a06a5ae67b890a25fbede7d0e96c625b80329b19be6aa861f44b6e85778130d0bdf69f2abd491ee9751ab96df57a600dc3b5aabff5b1034886d24f6fcf035bcacaaec738deb2cfb8f8520000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000f1afe9b199362f51cc84edb1d3cf2faf8e5bc0a734a646851ab83e213f73a3734114f255b611ec18db75694dcb0df9178176412b07eb7f423f23ffeaa0ee642590e0b7016bc063f3fffa93e1e35484c000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000019275491a51599736722295659dd5589f4e3f558e3d45137a66b4c8066c7514ae66ec35c862cd00bce809db528040c049c4b5627d84e153f3a4ecc14ddd6baaf1d62253a0f88d3af51be18d991976da0000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000a896c5a84cbd03e52ae77000eb0285f5704993664a744a89ff6b346efd2efec1a519b67229a3b87e1f80e6aa17e29462ed270764791aff081f1dc8051d22b8e18803a7e310393f21bb4a495a445cd45000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000001450bddfa14033ed8cdb94386715013ed9b2c4f9d65944e9d32c0b3545a085113e173e5afcfccb78878414a464d3184fbfb7606b64eef0460b8f33a0be54451fb655ce0b81db89eb7862f392450354f000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f35556500000000000000000000000000000000120935947070451885bf0c328bd83def193831ab9353844a01130074f16a1ff4d20df8459b5ad6a57d5f1959d37aae928a29fcc442d0c2446697e94dc47181dca7a314f9073c06aba6dc55aa79978d7d0000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce00000000000000000000000000000000144f438d86d1d808d528ea60c5d343b427124af6e43d4d9652368ddc508daab32fd9c9425cba44fba72e3449e366b170d5b468797b4af1978983faebe59a28f34956dacf5b7f65d25548bcedb518f45a00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ecdbc6afcdd409e5d50d7b655580f1144de77f3efe5d6268032eccab7deaaad9970000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000b4e7355aea3488234552d3dddfa2d1ad3164056407770e6c54f764193c9dc044cb7f2b157a1c4153b2045867d6f99c5807347519f114e78f99617f6b147ca833bff7be962c9b1e1f32b5babe6067d7a", "Expected": "000000000000000000000000000000000b2997ce4cb01abbb0ae6d28099d20e1f08c33351a6f0dce417a279789d6c581d4bc5a4a261e37e6df31a6928040d1f60000000000000000000000000000000003068e73dbbab6fddfd3c1e4fbf58bab58f15e1630c8c236faf3048be840abe316084aad7dd4ca6ee9d353ea8db536d6", "Name": "matter_g1_multiexp_3", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679830630695c8dabe9aded1b5365bf93770aab7e9ef4140a2bbde2f0a7b109724d000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c184ef5eceadfd77b3a4092696ec34d0551c88e434567638623740b7d5f9e3616000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f7a80d9efab033e920061cee8f8d7ea6023cc05f08340642613628b39e7b7fd0af0000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d245111c860f6f5725f99b225c53b9fe1a70150e7ce922bfe214900aaa2790d1450000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531fc07041840216d60ff445cf53b273a46016c8ecefefb53550f8bafc79966f863a00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e787929b031b82dc8c9f4ea9524793b54207d4e13a548d73297f2aa6241aff57abfd0000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a63d26ae92119c7b06d83d7e2922e06559b1740eae315c6623d3e543c9bf542580000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f57a02c61a7a75342ee7f0745886c0ea2a73c21500aef8078d21d20b7216c2990e000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b2567381b0c87102055dc2901826875d5e85a794befd93fccca2b9c0a1f70ef5610d83000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc3ebf66fce49c6beb12737fe05e3adc0a51ecfa9144ccf6253088dd1a7a483de0700000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a0305523dc79dc4b905e65587fbd095ed57aa42403d2df5dd489db8f50c99e9b6000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa3ac23d04ee3acc757aae6795532ce4c9f34534e506a4d843a26b052a040c796590000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c88586d7ad8fc3e4fb42981a4415224c0d976ebe1c342e9bc1cd66d35168bae33d000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb2116e7db0fbd2a7327c85054b4c0de9727dc0b051058f8bb4ecb1dcc7f825781712000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a85cc8d88273d4aa822f44a447cc22f5a58c420bcfe757a459772825619669a720000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b5b6e462d809f8bf1a62f276dcb27e42d9aa0ce33fc4e149e87181aca70a4ccc6", "Expected": "000000000000000000000000000000000ed96265e66875001ebbe888571ded16799d0bf5a6bad0abaca75b94bebf3023487a29fbe26a68f1cc90485df379845d0000000000000000000000000000000001be40cb29d8b722f91515f7e18372f7a0f77bc3ef2852c59e7533aeb67cc4cc4aab0b8e87f9a4982806124462ae94ec", "Name": "matter_g1_multiexp_4", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d535b53ab5f1c596eb966f57867e021d0f3b099e17bf384479c959794b17d6a4b00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d506e0512ecbc5a1b02ab19bc9bee4d3d9c721278e07b7a6e389c4d6443232a403500000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad51a79fd15e80b694122dddb01f836460b3eff99e61ea6309d6b395c94fb5a43dff000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a9251bd012914a96253926fdaabec06944ffcdb4637a05e3e78a9bcf1b21b68b9dd9b0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f6a300c7e1041d94df0e0201e1135fa6eafc98bd33b2dfbe4c59b546a52538c07d00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886233e9cdb10fc117afb17803b61a2bca7de1d190a325639eb23743f51f28294b33000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8c48b98edd9c229037751d02e58f3d4234d9a3b0ad9ae4947ae14beebb274746f0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f594228758d2cf8105f2ef11d83018157a3119a44874dc34d5f0bddb533f50df52c0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82fa417c96f0cf4355a78513c77cdc676a7b09125802c8045756da867e0025a36f1000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab446561328b7689b0a89014823537cf9eeaca6ea5c56a3e58d2abfc2ee455dfccb0000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c2cf6c3fcd4b9e6b72853934b306a078b1f2fb17879db4a0a93d484abbc2b746cf000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a6f6787b565e8d71be6fdb0c97c4659389c800a2047f668b366214adc716f402d5000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e40ed91f6ceb2ccf87e4106a16227a3cd7b2821b4f3a6e629001f78ba1aa7346e0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefbae8ddfcdb4748981acb9b2037c017174a140f2457fb0148fe807fd194a9f7be50000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c35851268803aeb58a2d57fc797358fb456d5cf96afecb1ee0d2b90782aa0d652b8c0000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728bf9a8a4e5c65973b785c1e2637937de239bb0fde34b786dceea66f6bb12eb4169", "Expected": "0000000000000000000000000000000008644b6d6adf9d5b6b50d4759363901ea94218881fac2006ea391c41fed2a94645eeb3359df803d740710f0f7842b985000000000000000000000000000000001168ff1897eb699e475b8ca2930ae9ccff139d534c7cc606c7bafec0ed23a6e55c6ddb1efbb1b5f75044d0a7e122d204", "Name": "matter_g1_multiexp_5", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b767f399e4ebea34fd6b6b7f32a77f4a36841a12fc79e68910a963175d28cb634eeb8dc6e0533c662223c36b728cce2000000000000000000000000000000000cb3827fd6ac2c84f24f64789adac53439b4eba89409e12fbca0917faa6b7109aa831d16ca03191a124738228095ed65070e7e2ae2751a1f71962726a31f77553c2da38f4fecda435b6e5459d5e833b400000000000000000000000000000000150b75e9e9c03ada40b607f3d648bd6c40269aba3a1a992986dc005c9fde80bb1605266add0819641a0ca702d67bceed00000000000000000000000000000000083b43df032654f2dce90c8049ae4872a39f9cd860f08512930f43898e0f1e5625a5620818788797f3ca68134bc27d22d16aa883a20307f5436354bab32b4633e83178f33626af3edb14f82724b8e125000000000000000000000000000000000cba419694214e95a3605a9b748854d16c8e6e1ee151c907487d8189acfac1361b790a5e78f43593152027295adf8df400000000000000000000000000000000110813ff6e0ddf3427e2a514d3f0bfbadcaf9dbf039e0f93fb9643d1e62bc2469fe84cd9ff0d585bdd1037255bbe5485041390a2209b80f7c64d14965cc2f515d5fbdf37953f75c4a0203bf0d9fb674b000000000000000000000000000000000106df8eba767e90cce0eabdaacc24d8e226c6865012ef8cb1460de5a319d443fdc6b4f4e58fb668943e0528b1809da10000000000000000000000000000000019789f464c95c179af18704c0b67b881991880f75ee7b03b9feafa3eafcd0f7d30a17fdd9cf439ff7fe683adca2083b57cf23dee8d95d94046678f3bdb4b0ea3d4e3a1a2f07f582e2a98ad6eb7562cbf00000000000000000000000000000000107e1fea76b5f2be2d12e11082fe690f01bfe6cefe22ce67de968e410ef51a6192b5b28a89f222db7e5b5fd5b8bc7c4000000000000000000000000000000000014028a700cbde8bce295c564dfbd73294f9bb65db3db9d38312cdc31410ceaf7151ff5d9420de2a5bc8f0d609893c0612adc8edb64db5bf0ed6724f3b54140ed6c81ca65ef9d1b38c8bca6a62bfd3c6000000000000000000000000000000000a57058bc228914bbb3e3e8f6a73842533432e0cf226cc02990b9b99a74b0acbad498036d8fb72a163590c75b6041d060000000000000000000000000000000016d275fe8c7e37058f287e1646c28ad1b4a675c0eef9671cf95dfa25617e2f2d515b2fbc04cfdffd5d487b255dfca245d1535bfcd68e8136808edf89967fbbf76b7f58d1a8ac95ebd4944b9e440f20b20000000000000000000000000000000016b6ecca57c78d6595e6b55b9360bd946b2f0061b98d931d82b03ed747998285e093c978015f0b775867ad0d8b4a1f82000000000000000000000000000000000b584f6f00bbcb2432b6cfbd4f6c88e228658887b5278e461ede804fc8a65dc6c997de30efc65b4f43e3d96717b938644c576996d90abde581afb58903cde4b9443eeb65e21b0d68c578e04c8f28f3d3000000000000000000000000000000000d1eac060ddc0a327396051c8c4dcccb77d11da05678d0720dec020d8aa29cb8ac959184417267cd7386feb1c81146a70000000000000000000000000000000003f8b5667ee4707958ecb93a1772849d5d8a4d42a2367ca058b160dbafa8ac0b98d5ea216fd18130237a1f17ce905feb3c558cc615b1c61c9a42b8b0ab4668ffcfc9e95bbe958e72e7a5500058e6b0bd00000000000000000000000000000000180152247144900b015c3db2d8b26d45a57930a5ca988c1fbf74b63b48afa149347a343f3fc6b1f31ddd6de079391efa000000000000000000000000000000000b6f3ae16d2a580ae06634455302db85fa94d71def14c84cbacc5ef98335d6d87faacff7a9bc14dea342a6a80d9bdfd661301b4957a468e2817db5914ff102bc96460a2c5c15e78bd42884b1223fa71a000000000000000000000000000000001918c4f95a0d0931ac3f254cd61c10cadce5cb9e1ef352edc8e5944c8aa8ecd90c403ed764ef42f646c7ec5e3126a140000000000000000000000000000000000ed644cd065411c63c7d054a57344e7a909e1d0a6b414bccbd356f15d16fc1b42c681cb6b36b143e91b31866387fa94395cd2686d24a5bdda0bcb118a2c0eb5ccfe411ec452e1beb3adbda7e93ea367c00000000000000000000000000000000070dfa1dda5ba02e94b29a63f8eb571ed7e8b0d037a0203af9a8350dacec092be1bfe33f4134b2afac77b9a36f95208000000000000000000000000000000000019e11a80ce3f9b3321cc6fd1ea2b314bf0c71d0dde80cd5b4de5f0d974597f57036613829dc777a6f6ecd6f9bef2f85fb81d555d1e2df92cdb487a888fbedad976dce54b5c46a39893edeac21a12d6e000000000000000000000000000000000584b7ea99ce0398473167289d34314c60ba913338b0bb690cfbb013496d24854863237a4d716437dc6ae33326240bd800000000000000000000000000000000065964a064e4da56471c9aed383e6eb38b58b9110a2cbf991d6dee869d2f1307cf7273d203d941ead90ed67c923dfcd5bfeed84bd95fb955d1b1045c059ffd051324dc8966e504164e54f76f02eb1b860000000000000000000000000000000007d6061bdf40745ef7573917e0e19f240b6e917f7cd4c47e01969b9afdc6af4e3c93e0f1dc2d15790bc2e6f182c01f680000000000000000000000000000000014625d3f2825121a907b570e9aeececcf81137f40ca6d0c00d709ba9931e403c0c2ed262a8f4c2b24305dcd3185b81b0e3b308b95f6d496e6d5b910b6aabef8d9f868471653e8254ab4d49d593180d2500000000000000000000000000000000087b5d6595554184fee36be472a0ddb9ac7f9beb20817647fa9978b2e0c3549ece4f061b58054e9191ff3f120c12077b00000000000000000000000000000000168d8d995c1fd032ca7b0aef2ad5c37ef7c7cef8b61ab8fcb5ea2d449455bc75b1b85631fd2ff8f5ca4e5880f36905ded4ea92e0e776be341c8444d4040ec121a2847256c5c9bc918adb28618548b048000000000000000000000000000000000f44cda026dc5e30eb06f12307bd582b271ee695fa68fbff48674c0499dcc875d617471830958e31bcd2c883e97a9e590000000000000000000000000000000002977682ca8ca450df2ac3c3880b1235e0ad8436a36364d319903fe2ca2664e05a70840aaf2d62531cd8c4ba4bfae9124c07f5188e4c6270a7e9e2f551683c4f9dc943ffc7ec279d15816a7f4910b8d300000000000000000000000000000000107dd39f779801f608cceb4784134894d2d9aee37cf328bb764d8afcb6d1e0f1387b36bf5b7b335099849278eac44e8200000000000000000000000000000000045c985714b519061a9c8d8c9665b582abdc4116a48a70e0d3c4a7709568aaf011aa8ecb893ca483878404b3f8b22e41a819a0438efd7ec0c1e3eea07ba201af6a832fecec818adbb781ad0c23e81dae", "Expected": "0000000000000000000000000000000005605f40a1116742ed53aaf7092715355ba8e41d5d49909f79ec9580955c4a9e696fa30df37e4044de4d23fa1c4121530000000000000000000000000000000015acbfdf914883d16918f980aedc2dfddc428ef8e9897776443ec3cb091f6cbeea31634ef5ed061792710d5d2c87b8b1", "Name": "matter_g1_multiexp_6", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001696e814de192623543f822a22344258c8ef9b92c178c4bf2404b38f39151828bf518a868cde3db5cffb745f1bf0023900000000000000000000000000000000125bd1df30f4799271a9db03842f98ccb5a5c3acbe813b8324fefd06e3c8ec4e2c0be8c2d24328a2d1169bf6ea0ce46fb15af019ea2de662bf187930caea19d0aa07a74b49fa7d1819a539e06e4c69ff00000000000000000000000000000000138dc5c034135105c8899eeb61ab54a84cf02919e5650f34518f941aea5bbb6f9df3ee6bb2056d0b9e060158140f990a000000000000000000000000000000000eec8442c8656ebc4696ee13273b12f3e362862acc3b8ec6f2b53f58f74ea23b33c79fbbd2058ad205f4932db2e87ae9064a6af51c1d499c4c28556ad1255af7467bc750bf2db2842d626647bdb334610000000000000000000000000000000008f7f45310b5638221cfc9dece18010034c00b3cf170535008d60dc7ed6ff90bfe87e03d94e9a38201699f0742d8973500000000000000000000000000000000185b62a19864e21e1bef19fbbc21863c75f558bcbfa1b948bf939876188f4fbff5d5f4f756e0ec5348e194bb4f70706ca3daea5a083af43711fcb09282b66882ae5b5b8e1714e9186f33ac0dfe48b7ca0000000000000000000000000000000019269dcdf3772ae4969b68a0b4f87c5097aa8bcc9e6155638c3de94fc22b4965386be28e059bcea69f993cc388ea9a79000000000000000000000000000000000b95f44ad9f14cb5e3b9a338d0e4345153c4ad0d42aa00a4c12df117b89d9cf8bb556041d49f94b8f63108f03c56a449bd682acd154f6e16a583ca4968d28471653375ef79df078b17b2cd9634258dc10000000000000000000000000000000011c86d420b6d8820af8a3ef511d79aed7c82ee08df993a5ba479b29ef2f968919444a7c48a24ec33522e1206bb9ab784000000000000000000000000000000000f4a47f3f14a25108c2c9262466d14e3a8d1f21bd2d3d6f28f03f35bf23a4b5b494a7cafe6ed5f39195e07b1692bb6da562223d3fae1d303a01ee4642fb4cc70f21937ba7fe377260fe82262a8455a7700000000000000000000000000000000091d9fb6493f4441c6e57a5a58210a6b78e86f1a9d204094ba6fecf2c146522cf842219c900d7cb95366cf7e411ff4a00000000000000000000000000000000015254260fb67e88d0067ba7006a49814c74a5369837dc5279c0fd19c8826813c922793c96e0f708092158ac297a368ddaf1d0fdab6185e1c3f9f621ddc169ba92584db0b40b6ace7ed563eee0090629f00000000000000000000000000000000027910712cefec94f0fd4de6aa70ccc408e64d5de6b473086009c525fb6d058ea03bc99f7ab49cdbad3a42bc8ec0999d000000000000000000000000000000000c0b0bedbad83ebf6af4f5757035b8292fadae4bfbef9f3bfcadd21dd796d7e3ecdf9685ca6d4d649b2f0702a3280d40e910487c91f3839d5961f02a67f3b357206e406ba207dde969498e40d4a26e88000000000000000000000000000000000b0ae8987464ea0b77201d468db7256b135a5cebea92dddb3aff10e451568e714f1c418b6d53903b89bc71109180b8c20000000000000000000000000000000003050becb4625f8e3ab2cf13dd1eb8f7eefc7e14c16934b87661adbf0139631108d241bcb1fb24c5b989f6d424cac883396d32c2c9ef685120995d2244756bd45591618597306193422f3b5df4b075d2000000000000000000000000000000000dba43568347a96f26f2633d9fc0fb4610428a8d4992c2734b20928bf974bf642a5122995884cf11b76126ba66522c8c000000000000000000000000000000000b9bb25b0db32149736b671ceed44df71f36a33c15ed821f591098ecd873355cfb8a39fc7c7378a19d84a5b232227ab92087e21d775fbc2c20dda715e46c9c4970394e40e991c78ecc13a2a5d0b0f30f0000000000000000000000000000000018d46d1a9ec91cc7983b29ac83fe9101c0ca36276d40743d2a6010d574fe1c16ebd9d7f0c83cad5ec2b2f652d3e6cfa500000000000000000000000000000000185f6367fcfa70e7a005c1739c0d0a19b5ec8de766037ec92840e66e2e9db18ba2356676899763183222f9957f48f300f44043002a94560d725da2ac44f30cc5f14f52dff5671c6689efebd803b1df7a0000000000000000000000000000000016677511c781b2b97456c3059c19b3e12a865cc21ad71cf06979bee1a3128682a4a86f3e07cdbc9ff7b5aa7a9899653600000000000000000000000000000000006307c89ac36a88c6921c020d32530fb69338afbb33929e231fa704f0454d642c47a3b8d320b4266283a8571944d0558624c83d846ad2e53f3f8ff5ffd3fca8723e6cd431e89ca29a4d662e82004b600000000000000000000000000000000015a9b215eaed682e4704cd3b1265962ae0e24555a16612ac762040e1fb9b412eacec5130a6f6a31eb670806be7ed775f000000000000000000000000000000000f60035910c438c177a27e6141d0ddae706d3e852d61e37cf8bb2f03550feeefa7213545e3af5ea614c91b51bc2fb378b2b2a8a42887ca6dff5b5364d88962068496bee79cbe74de0e8a06209feb3832000000000000000000000000000000000077b7a4c4644b21ac3ef56db1163f7b2e07a817cfd9d4c6830a97d0ae0b620e0b235376d590162c378899ba12eadb5900000000000000000000000000000000022beafe4b4ab44434c9dabae45a395b5b8da15da2fc2e723c1b30b5efc95e880846844f27eb47dfae8657fa27ab64ef88ecb5976f63a38d7f3d8c8ec441b705563c5e3d899870ab5d2ff84467fffefb000000000000000000000000000000000324928100db98f5a1af039a8e1b63099214982f1729ba633b51166da97e861426bb91283b386ed4b465d791e63928ce00000000000000000000000000000000178823756c0facbd4b1cab22f346ea7d1dce0ab687263265350c9939d52abcb5a5000b3395f8268a38027410675e8baf951f4960d6614b098249eb9420077ea5ad11e38d1694f4df33719d1127338f440000000000000000000000000000000008828eea92c3245eea4d60ee385734d3237e4e346e52c5de8b24c82325819be6984da4f0c1ecfc6ded5d0539a6f1f1490000000000000000000000000000000017169bab8970f47a303d2487e3af707eddaf7c4453e9d2d6bbaf953e74947b5fd40663173edd55c0d6aad7884f69a0967056c7d93d8453be369831dc0575df6438db488780d518a53d19b8f5d22d506a000000000000000000000000000000000787474664b2803e78489de6c5d5f1938e784e552bca4c32196cfe121380aad591c9fe4d9230dbe976b3ed3b3044b8630000000000000000000000000000000000c026547c94cea37793fee439c359cbeb2b985a33559ab25d1b55773c24faaf4fe511fbf7df085bf5c1715c79469cc28aa982de1583c25307e9e2c8cf2469a0b1076c6be2fbf12caa8584f34988221a", "Expected": "000000000000000000000000000000000a7153c6173dc27b6a241c046a2a9bc25b85c4621667d0a10550cf7a090a8fb914725201876a5bd2af09d4fefdede3890000000000000000000000000000000007aeec94a64ac629673f3be3cf660f471e3e928de0884300ca8271d42c92b965c86bfe76df61d0645e955f40cbe3751e", "Name": "matter_g1_multiexp_7", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015fec2d82f5286d2067b07d83cd1c131d3fe18628101c3e45caab07f3c775c97e1533836830959cd7e434fc3fc392203000000000000000000000000000000001050e1396a5053c902441cb33003d9c54e6b631a80e3c132dfd37805bfe87cc2ddc495200268fba0376c5fa071fad230a18ca15f0d931619363f5ee56bd7657b2298f228cae8d185c9d062910193e9c4000000000000000000000000000000000fbcd07180f265688329d72ca68cde644a580cc9d698e40f69380065110ff5a61149e4aa9f67056e0e1603bfb9b5b3ce0000000000000000000000000000000006f363a9addd63a59035cad90cd52213665069f540b6c6cb41cfff5711376885e3242b596d051a59f681941bafeca53eb54274927eb29fea0cdc464271c918826d5249b2180a52a5020480d1020c9795000000000000000000000000000000001164abfa75cb4d711ad811c4df430ecbd6329968ab003fa680d235ab34a9565e5c08add76cf412f132b54812671da7a900000000000000000000000000000000141c9858dd17dbb027dde22dd65f6a7cd38a1999eb7977cde87ad762425e364e1395851b1cdb41094551e530d891b0d15849bffc842c21277be88dfae0040c54b072ff526731947cbec0cfe963f2d0dd000000000000000000000000000000000b95d221c628a77bb75ee5942c9df4b700268c90c4e6330ab5533d13d59826c81aeef7621ef6145f48bef9607d280ad2000000000000000000000000000000000b2ae1b6f916d77c31e4421f8d0241201bdab5339f95eae0e9491b4da5e226f8eb3f754d40be3b446ad6d18f28158b08aeff769da1b62fde321d46c66f8ee7f2129446d805ab7f7bd586268de8f57c4300000000000000000000000000000000128989e92641f3c3a914c13e986aea1bad2c87a8c28cf156bbc68bcbb134b25cd672832f2a988f60d2ecaaa1b83159e50000000000000000000000000000000000106dc95373dfcc85d9de6b5b609554b67e8683f90ea13156c8318aa8de0a2355a721b3bd77a6329264ae671c05af4a52c9e56cfe957b924c9c0294e1c1f12474331c662c8e86288c97e6a8b8b5b2020000000000000000000000000000000009fd9fc9ecc0d1521696bfe7624360d11111523a4ee0e30432a468dbaf1c101691fa527aac5ab531be822ae914b0afad0000000000000000000000000000000016b317ad68ec471b0ad67be2c489c9f5bb0d8bb6b5ef909ea975cb17f5964564d5f1a61d32d60c457923e4680a218b9bdecec569d223c724d162250ed1d074ed9f4080aaae3f44b77df05292be48ebd9000000000000000000000000000000000b982f33980dea4d89b577c9f849f8b8d9cb0c7efec7e17284d45c855638fe9ab2e5bdc52ba79d06a9133f66bf0ea2b5000000000000000000000000000000000c252a2e2769d3250479091050133808a1b0fd20af2b41cdeebe7cfcf7e3a92b9ab17cdf4d370f9fc391981db76de39c915ac9453b831c41becd3c1f412cdf5379e9cd5c80bc6df92ecfc5005356d2aa000000000000000000000000000000001769e8b5fda96ef205750826f34fdda3587efddc86f69d37001c62938a90efc23a3ae150d223ef4bf3766ab7d86d80df0000000000000000000000000000000009ee24ab483300764bccba33b55b8889b084288ffda23d157f650df34125fd803624d88f2bd0c3c3ca51bcb57b9f4dcb58fa60bc7cff4edde18301af2348faa69ed4f31d437decb7d4fe51142d179e6000000000000000000000000000000000146001b68cd902fbb4548c3e7cfae9cf3c8916e462f1becb9918c8de42483ef65f418d6e93200e8ec95528928916bdb10000000000000000000000000000000008bef4996b8120613292dc76dcc77b07b24d4498d6bd35f5dfb80ad241ad97bd161cb2c5c96fb250b70f8aec1aee5b56c29be0b271d4e22d39e9e06db9e50845515880f30c5bfac80bca39a2d8d61ea00000000000000000000000000000000019d02e168efb5769416132b0457ee1ca74bd5737f9364623bb270e8218c96e71dc49403584aa0a7e6c15bf6948ddb956000000000000000000000000000000000510c0917796c7ef2e100c7656591d04c3c5968d688b36b93dd690b0a8ea55694157fead964b85a5eef1815cd5932819dc8c2e971a3a4b9909dcc5cc6a0de50286294ee15f441521e0f1d2c3ad3a76e9000000000000000000000000000000000dd05e53ee40f051037c88fd28364aba276c793047007a20f893d13222c35b24e14f6c74004c3d8070405621380553af00000000000000000000000000000000191d7f1863ab7bc4ad1ebab359499f4df75b8c7a58fae8fe7cca530c7a56e5ee1617b343765960ca4bdc0245ff997a9221c9ae0132a4886820115e71e280d33378a04344f635c769fffe91e89fa7ea470000000000000000000000000000000013320367c29a4f1527e8c0f3047f776d7c892d08988c402c55e90e84b07ed7f0932c3b5fd19f8d133aa839ebd90f6428000000000000000000000000000000000f8396d819d7aabefda680c8ad51c7f907911dc4da7c5fbb7e599e7f3b758c5e7c9e9ab4de1700f72f109d7206c1be0ee1067c01d5565d0f387516d9721f7f4e5253d5af8353db4a55500e20a95f3c96000000000000000000000000000000001413f6a4ec8b21a459a4aa33ea9d92614857df629ec16990939fbb8ab11fcc919a25a10423ded219ca5b94f71377dc2c0000000000000000000000000000000014a3320275a64ede5e1221c78b421c1e4474bd499263aa21e97af103d7cb62335faf4b85b5983c5865599b709e95efc4a23bf766a1e1c068e6e8e4b60391583ac197ade53caf0f8a43c53d1bae9f13e500000000000000000000000000000000057c3c7e4cf799d716483f1e8bd4e6ec91ad9566379683c54204ce46a0e5635fd9852b0a83328386643b2017b9b551f90000000000000000000000000000000010e3d5725beabfa7e4843eeb5bcbf6e7a54b4b82fd1768a3c276bba8fb7dd25dcca7e20e74231e2f7cdf0ff50cb9cf7c2c505d4fd8287a897e01517ddbd7d7ea9d26ae4f58fbca172e5265e2b62858b60000000000000000000000000000000009d85ce8e918ddbcc47494c4b194649fdbc8de31f5f3299ea4bec7c68ff56c7f6ae916c85118553b6a6634ef9b8820f50000000000000000000000000000000000c9a680e6389d447a4884b4e134a3e025f8679edcba56bf8ea2061a00e34d38c325319a8a5efb556fc2536886e225912908006c06ceb9188651c59d434988cb5b51a5a75772ba71875444c65ddf0f4f000000000000000000000000000000000f34c8793a9ec6c34c704159d18e385dc9a127e0a9b5f95667f58e68f5ddaa272f68f5fb55e105010fb656954f25927c000000000000000000000000000000000fa1d9379fbd273b05aaa8ef5397eae24cc14f83118b2584085312986c192d2c5e3a0fd8fe5c2d82be2ee5b006413a2be8e8724c80f3527de5f0b2b98ecdf0b8d0471e63c0763a89da8a21a70dbf8399", "Expected": "000000000000000000000000000000001223d94bca6cb3225511b4e28797ddbf1b1e2d059c6f7c5e852331f381c578016671b5390dff3898f9048e5868b253de00000000000000000000000000000000093eb1c50064251cf043e7c7af7518b883a8f760deac99f6e10c3dc941fed718f2293ec2cecaba6d58060374bce11a8f", "Name": "matter_g1_multiexp_8", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001429e7011c17bff6df1b3237a06bae78d427720af641d2614f32cfef8c537d5ae9315c0b179af0a114a486e2eff7bc470000000000000000000000000000000003b9caa69b5495dd33139d14146919f9344efe2416b665dc262bd09ab91f3f07d1fb5eaa3c3a94606e74ee747114f347e14282bc687a00264b4e4678ff238d5205f6b6fcc10040d9b4393e93f76297a80000000000000000000000000000000012b481abfcf8ecfcaed39a4277492641c420acb65ec809a7d55892091c7f76f82c02e7baf2a648cdd5cdac45113b11e90000000000000000000000000000000015d32649850a5c99a787ceb894a66b58066c9257dafc4a6cfad2887e7a19f8af69f8d1fa69258289e417954d064e63eb5307650d6cfc681508fc7b8dcb5291837582eba6588132f46ab8fba674a1f5af0000000000000000000000000000000006038134150b97e785f33b0accd0d1991c7b97aee1acf9bf671188f61a846a9603f2d3f56d2edc0564d1ea7967e112460000000000000000000000000000000019434ad4fe571da11e2de03c891d19ea2729f4bb7b7863ae0bb8f18b53852ad4dbbbe682da2c8568fbe96c6c9a7236dc7d6a25511ba63f0b7ebd2189cfc4c551083ac92b144e30dd81d27e59dd86e2260000000000000000000000000000000013786032ab493b5026cf23fdcc468ecc486cc8179c9510d99a503031d1fe39f9caedb2d42dcdfa17173e693e2344bd05000000000000000000000000000000000f1deaaefeedfac7f708092bbe3005be7c4b56499bdeb8fc742b72be7ffe4d8ca90e605502f1863d89a41ed794e06586eac8e5cf13de6db37982390c8b6b0474795f479584960748b7ffed881285e2df000000000000000000000000000000000aff14b235c3569586e67cf5113ac0ab32d442a1c07cd9e249149d719dbd64f8ec1b07c4241af135d3869eae05ddc0a40000000000000000000000000000000013d960e93447cf6df8bb48db45532d567dd2b0756dd674625657e5364f81b4bb94bf436b54bfe9afe8eb5f4bd1be90732c134652c27da0a0272b0783551ae44db6bf592ff299b48c50c550367d470b5b000000000000000000000000000000000f85e9736fd9d3f9a839f701b6d8a6724af55ea74d28f101f97229f4b406016e50f54a0b3d2087117f352bcc28b53d5e000000000000000000000000000000000b2717e98f9fca574ad9202bd76ff6e53c74c342d1b6049fe66310040217563a4e5df460f264769418cfdc443dc31e008dca9ff432bb483ad726bd20cf96b07ab6f07170a1449f0f1b50ddc6e1a02538000000000000000000000000000000000ed8e6113d657b2d3283e50e9d054e612793fcdebfc31c53ef4f417e63c76234900c627b7e8c433addbeb6a79bcc5d380000000000000000000000000000000012f0a3095ae16b5535192a932f188c62c3cf01d2184f8e299794bcba86d4573e423a0eda4e17b4b512c5e06367e470f6146433a0738ab1b044e059f49a8af8d85546d0e34eaa0edf2b2a6ee466c0def80000000000000000000000000000000002fa5630b261e07326fb51aa2bd897ab49e0b960f769e3207906a530fd759a53db8ae17fa79c8e8c889a923fb38888770000000000000000000000000000000013d49d032b888aeba7e652b200c91042f409a6a824d1aaa04bc402f94233385254a2d1f8605d15d04013ab0de9e40a94de0399ce1ed861c0ebce1d4e811ea0a3d87e21a54ae34e6b5e1284cbb9497368000000000000000000000000000000001495234b14a93a24881f3b4425dfd82b49aa1828746b06822097c8338da57db37ddc836a9abc46f7a0cd17ec08d36fef0000000000000000000000000000000013b868cdd5ed7bf90018873ae2ec84e4bc71d002483831ab7a4a19bf18feabaa210a729ebae606ea18ce16458e997497c2b034594fa53a0951e2116db1b063345fa42dc8c870e1146f1b00f626dbcfdf000000000000000000000000000000000f223490fde3ae0d7b94412b3aa86030e5d9dca805f6ab5b025ce8e9648aa02067fd29ab9a1915c2df7b2186f35a2c74000000000000000000000000000000000aa747ff7e24cf6d1dd2c4fe9db8c031b78830e98cab27cf765fd874fe6b7731c13af69559748c81f3915f9f3a6c63bac1e6d9c5f8911014f0f540211af5184d96fdfd47c03bf2d7bbbb3bf1a330017b00000000000000000000000000000000134f8ec87b5572c062f6f3b43ee896c2e019356214ad397f703a839d39215bec954f02d3f81e3442586ba9762bb9690e000000000000000000000000000000000218735ec0b5bf9b59dee7cfc70ec4c6f21aa129d604fffe824b7ed6b6346dc242757abbe98c19c02d5235da448e331d6df5a133d3332e1f79f41201f8cb2c8c8d4d1ab0f640c4de6bd6e34884a77aa2000000000000000000000000000000001510f39616d7f576980055d0547c603d882dbe85dd0b634577fae134f210736007345d035d815306db660de4a07fc24300000000000000000000000000000000064d356ad7bd2edcd3622b1fc225fe319f86b5f7da875cd57fe5adc5bdb6443c5b09d676950e2d069bd4303b8f9206928e7219a9d431c597fe9700d43da8b545072f5a27a9f1af99053ac0494087dca10000000000000000000000000000000014d4184d69d34b8e509f3fc7e7033d76b10ba913d6109bdf842be4c49cc0c29576adae2f75e6fa054bd989e26bda58170000000000000000000000000000000019d0b70eb45a353166bfaabcb661b46eb1b7d8a59a903cbf9e43ceb6ece492e78d7f1765922e981903153072a08bde098efb8a7a5e48d5f4a011a4aa0dbab22ede62c903414d005d507ea3d77bd47a6c00000000000000000000000000000000087bc015b995ff8a840fbbf23db2cdaa8bb2dcbc38e12b588bdc4186a77409fa2a4cd74347f568c5b516879b70552df9000000000000000000000000000000000b15f04955dc27d19ad2a97a99e0890e6d3ad17d29f6b30f866f8cb3ee7789038abcc24c63d4525860e64593af02e39f47f53e2c06664e1daffd7d9b114e12d4190d5d0fa2244d61a13da915c39b8d530000000000000000000000000000000013eb2ed1d78059beb34c3fce731d42ba28c485dbc74916e373424917d60bc8c402e331e8aa2fdf70360049740e670da7000000000000000000000000000000000eaf5b5e47a2312410035d87aba7196f3f0b65abfaac28ac80accc9d87a1115b7f175e59ea2394198a2876568986fbebfb109d9a0a7b62c7c452bdf0a2853c4bf65e5439fdc83aedec8c0bf73a16b5580000000000000000000000000000000012d7a2e92adfff3d37ad21dd26299188e25b628a9e9d7b54d2eb8a886e80de812a32db9816964f2c0ad25d9f0aa6ae9e000000000000000000000000000000000c7084afff475bdc0a4ec265a3cb3f87d862270b6263a47d869786495abdd4316f6f154b997224d3a895010ce04151c34b0a931b894fbe61115fcf52be51d44afdcb96c94117c75adffcd8729b0a699a", "Expected": "0000000000000000000000000000000019c9d9833332c6dd40c200d53b30e92f1595c22568b31882e24b8fb17be41f4d2f9692ca1e63106c59ba574f8b0764c9000000000000000000000000000000001414165b510abdf0d4a32236cdbe51fe2b5c9a31942710a07bb5664592a3f1b5c821edea44bd7fe185cb53b11d6407df", "Name": "matter_g1_multiexp_9", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000038e60d2dae22dee4dad0d9e0658741c13d165d3718c763270292602852625ac83c5ebc1a6d86c181686cd01a1891b520000000000000000000000000000000007299913b59e2d245fa489d92873b7d2bc8921191a34a0d7f6c5774757ea4eb3d667ff8f3e9293f0d2354ef03cb6592b68ce22e379ddb8352d12eb597c179c7089c6388542909876c69ee377b14054e7000000000000000000000000000000000b07454ff91e3f9707880c1713c69f8a44d70040b44d96ac74d196853c62f264ccbe6d9c8945905092d9bef665e45bf9000000000000000000000000000000000405c965e2e8cb5e85ef9e18927c7e86e63e7aeb49f45b3428089010f34eef9ff37eb005e6b86e20236dc870661dd68c61529338195b665f1b80c4b95b7c3a26a7229884be1f4be9d49e1274a9ec3f81000000000000000000000000000000000557c7f55246759b901e4e8478aac7b80d37edd5d6be057e5aeafe3d8da008e48c96c17ab1093a6a4fb39cbe9364fdff00000000000000000000000000000000158908f112d7cdcf867f1a5b05062b92972c2947be213ede3a7fed7a477fd57e69e1de82164f7cbd53a3f4f4bad551d744d740a72e6c8b5632314408022093618321c8c0a8cf2fcd9ebacbe43505a01c0000000000000000000000000000000001701edcc472ffbbf157b1f239968924bb91825754bd4fda9f13450162e82932b8f5f39e54ec5975dbe7dc744d6d676a0000000000000000000000000000000017d13c1f6d64af2a808c3ba20792af9ee9c626235ceb9ced3c7acb4bc864ba47e55e0945a430da47da1e87f015dc024724872a78e340ccb077259aae65d6c448fe6bfb64daf4e2b6ecce2cc9525e35a700000000000000000000000000000000011231262d0fcf5a4b92cc1ed62aa66a55be739eab1316219ed2bb8d3e939e25b840b75f914cdd3f07b3f57bbc07c23e0000000000000000000000000000000001eabe4a5782244ceaa57ea0b58ed1334dcb94e449b7fb905805cefb786e83af66ded006cadc651a7b2cb07c3e3fceb401a1d84826bf78f493417a06a800d58dba688800026638316fcf9ae534436fc000000000000000000000000000000000045bb823151b691e26b0e706b8abb248ecd87107a88c728e7a627a962aca7f85d4c88df949b3c53e2d32ef18f60675350000000000000000000000000000000003342b2d1a75300ae9ffbae66326936b19c7e59fc6f597ff09f2e5d50c1942f161dcbcbba00e4a46d87ab51074320132c5a3268a8ab5a12214b266aaa4eb562aa05dd19575a7f3ba2d549a25f1900cb800000000000000000000000000000000043d72d26ee669ae8e47eaa74199feb37d51f5c99151a8f854362469e5acb2c5f6d2c208e7d674efa189fb90275b835e0000000000000000000000000000000019e6f1b3137bdb49c534902abbf42893fd576a211b93c831dee90723c7daeecdceccd3eb981537d4fe729d6e48d70d6ae62a7b00d2be967df04ef56121c95c8736efa95e1faa0196e1f4485da82b3c3c000000000000000000000000000000000837b6a981e486865dc4d6d0c123230ced707e2518277cbfd0be747a8c9c76be6aff8b06df76f7c801fa34d11141354900000000000000000000000000000000011d745300b20c5ff1e607ef3a42ac31cc55e8be979b091aac0396748e607f00f30ff579321f2e660e90e8e5f9efd4f77a883bf845d1ed04e0664d814cf0b49cf8c3e8b8594ae5d2834c753851ed7803000000000000000000000000000000000740837b02d2923815914ee9cfad663eb7246ec8c56e632cdc2dce25b6e475dbb6a75ed2ca6790f5f83fd1a274832e8d00000000000000000000000000000000188034daa9801ea182b712da519f7524cbb9f641146bc0fbf77e72ecd066bd577672c1ccf28a2c4d3cb9854cb2b9e7c80f474e8f4051c4e91124c14895fe9e2516b315d805b79013caf830524fce888000000000000000000000000000000000014ddfffbffd0317ba7e248f648cbc98fac2be9f0cc31d6476f41527c25fe8d078207965eb2382ee1e0f08a38fbff7c10000000000000000000000000000000003e492f3667da69d44b35899f425af2ba51130aa6341bcc0d4d9646cc96b090061acece81ed16c7e75fa452818748b119b3a5790750825ab75ab7422f833c671b95c6c58619189db66a6215ce907381c0000000000000000000000000000000005107fd2b5b483173992b0f2f51dc24bdba94b5174c063b52c33a8cf84ce3adefe0efe08e6bf4de3e68189e495b39c6d000000000000000000000000000000000605e8540f1c7f5790c306643a68606581a16a60d33607064dad5572947c93f3846f66afae10a66cd33621c6a2dae30c6607a48ba3fa5c033a1ef90260ada14ee50c95e5167bf801ddbd3acb77c3b3880000000000000000000000000000000012eb811b231a07e27e997900be274f73720afe3b0626104a9d5aed39a3931595f2ad57cf6e8f12d5110cf38fc8e7f244000000000000000000000000000000000abf1b8abe848b91333b4bb226b81a33aff5b8f7af70108538a3c706da182476a42e0e5c2fcdf694c8a12f62a996c86c030db724eadd2f487d31dd4354b5c0321a7983aead21759807bd893217c4d4050000000000000000000000000000000009d2b5044a8fe22a957b6d1eb20454db2cff51e7ebb6357b3c6b95387b1fd810b94eab4aef4f0a0aec4e6a693903dab60000000000000000000000000000000012ccb794eb1174735b5f7700ef95ccb67691cd3673d601dbf6b2e2469521f1b2ed283f2f98a9cd601867de4640c9517988e71d0be8fd050f6dbb8b2fb3ae2a9e593bef7a5163255aabeb07282e8793e30000000000000000000000000000000003eb6e7ab6dbf66614ff5b55ed36243e1d9baa317f01aacbd7f3a015bddfd818c6764c0802e97a42063a18edd9dd091d0000000000000000000000000000000018571d50a947e56f63b26a4377678c838de7b315e655104eeee48b7d5e6f5ee5d876b3ebdebcbde4080e022cc88c995326989184bb87a586b8752733f9ce9ea06422c6a898f0f402cbcf760a7a21c95c000000000000000000000000000000000906d5a1691dcb7dfd5d78f0688e95de2e2f06cdc70f8760e43a562365939d3fa23ddaaddfd1ddfbd3bc9777783a7ab600000000000000000000000000000000168422a6171f5ae44b645b6b6e73011494dc75e98793db2424bab311990eb7730a9a45234afb78aeff7778503cf4e5a03d1dd9cc44b30a4623a4d14861688cb678bbb8b2f8ae3ba140f60e64c05514b10000000000000000000000000000000011c20d0c6140e0e11d3ffb8c28c6bd80ec495d057775f6dc331c98b0b0aba17568e1ba773771c703068dcc6747187767000000000000000000000000000000000f88fde780460bd75f46f593cf6fd0aa25ad14cccc061d9ae2cd8c20398f24e76ef614008efc9ffe1d1884df1122111b5639d80f55e24e05e3d943340e324f6738a593a915a6bddb40f01bf12f73daef", "Expected": "00000000000000000000000000000000018ed322f140a351069f18d039ebded8630fd019e8c6c401dc760ec5cc6536bc2f52a6cd5400dca0caae95e4b9282967000000000000000000000000000000000b9666fbbe91ec8bd670b2a64571a34d689eac44c5b63a43f60da08df51b003d85c03f0eab3e2042b1175af3501de8b5", "Name": "matter_g1_multiexp_10", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b42381a83d4472a3a7a18d2ba5266bcca254fade1170c6f55d442aa2a7674008fb35c58d5a638280e0ff7531617a768000000000000000000000000000000000eb5de05b5cdf9f95c5a3ad30ce068d5491006640be4c7f02b7498963b5769d516efb9a117c60c1c5fb71617d42c977142fe1e5b3c0245e5cfaa1ee8dd8ccc4ea8878ce2272d152fd8b24032297ac01800000000000000000000000000000000163ee62f1ea9219b921ae7ed0f121426fe9fb8fc0056916c81ea9e713f1a16e3f2bec6ed0e3e552a7173f8dffcde82bb000000000000000000000000000000000f5fa0e4980d3d2b92e98e76e5d67815ce55858852f03ec7b8809b02d4b1e9e1a6c8b06bd481d9d153acc68378e779fa253bdc5565b6ebc219a75ab74dc5ffd304c94e67160389f87111899ac07a71b7000000000000000000000000000000000cfbefb41304008b0e7341451f13d65681f0726544f14fd1c0d02433d3c34a4769f1456960cfdb11b6bcf016b906228d0000000000000000000000000000000001adf387f4feeb3845b12449fd5294802ed30ae211d0837eff1b22c3fedf538ec7119c1fe69ed7d595f7c0fdcd54f684acbf64f93f6f85805517ddf0358ecfea1fd58a3666b8dd9d3773a28590fb8a13000000000000000000000000000000000d736d3b8b586e09d6ecb1ee2d7eb28bd68aec60234e90611da8f1e1aedebd9c74718d41a89186a4a5dcc3f7cc81e99e00000000000000000000000000000000000ec0e89da57affa4686494e8e0f5517f11532f6e294215bd060c370fc64c26e34ee1e2d77cf341226daf84791f5e3cd9d3f97893eb4f14f21f68110f612a444815fbf2f76b8399ba6045c8a44270df0000000000000000000000000000000008fef795f8bfb6de5feee020a9363adb1c26fb521439e405570b4e997f55af5783968b24d2e95144bcb6b38e4ef9497c0000000000000000000000000000000004d4e31720644e8828faeaeff38985ffa4fa2f7bdaa476b5c4d7eee81c89491eedd3f4262effe118a4c204eb555abfbd05fb554531f53b8cef8d93566df80878baa96f92bb54aec19445980b1a1f6c3400000000000000000000000000000000195f8fc4b1ca0c7041810b02bbc38b8bcd0711dccfd80de2b2f357f4a732e65492d57f455e99fc810d6f86eeab0ac101000000000000000000000000000000000e3010ed298656b91b5aa342f6be7250cf5504fc3aa26a2c7f46f90e852fd7799d96a85b25e6066b7d24794648a81331d79ba2c485f0aa0e35212fd7fecf970258903bd2427c4c8b97c2c425ee11909900000000000000000000000000000000192cc18dff89d9a94e6f0498419ceb9f21d70e42a1b9b64bea093d67075d499184d7b2106f74d31ccd1863beeb7be0a9000000000000000000000000000000000b80e940dce71be82106640d99c121dd21e99ba459f0dc8b1f11cdffaa0d8ab295b9711c23de1f4bc35120a89948b91a44c7017258bb979cc9bb8acbd3a3e62eac7aa152db46cd7398ef07edd031e4f6000000000000000000000000000000000b53f55edb182dd08e2c9d0ee43aa3d734143b54686295410f80086d3aebf6fc681d1150e808d684f47b0eb23fcaf629000000000000000000000000000000000d73442636f4d5dd1374cfc7ab29b995420995bee9808aec29ef7d1aac08c0ee51a0390330a863295af6129b7e8171d82583e821328ae90a7db16b20525228e8d915bc8d46a642cb0a06dfb64168cf1c0000000000000000000000000000000002bd8316507e6eded2034cf268b2b4660211e6bea2e82b3e3a0902bcda0f9ae9980b401f36178f681691ee7c10dc4ecf000000000000000000000000000000000e9af98fdbd02ef62ae90f1e87c4e7a8eb2089204b1c58dc6e59fa32d001c97f22740d8a13ccab23b5a8842b693504a8506f22d323a740553d6107e651c192c1dc6e0a0161a82351f125f08c77e53fdb000000000000000000000000000000000aef5a5d5b46d340fccdfad359b0499a5c62ff4e5d9b9d6f7a5fd6a97e96820b7fd226e7a2aabaea392869a40cd38e1d000000000000000000000000000000000865d32d825149d26b60969ca567ca85af5e280b835cf541b20b0a4db83309dd2b5700f802ed9106af73b912dcf9630b7f1bc0e1ebff8f935330c35573f9fc3b900606da9cca9a36b425977af47c7ca600000000000000000000000000000000153310de30b7a485753dd8443f8638c12b21083f6133a1c093648bcb566b33f73631c6fc558f32abeb0d6df8430e61a900000000000000000000000000000000005be397e9f77556ad952dba0540f46cbc7db910d5203cb976e168a7be3a3b8557c5f08d51cca9379552694a291d67fb4429b85fae16200da6eb8f62e95e027c24aa6ee2a145f6ef225139f29aaca29c000000000000000000000000000000000cc75210c78f2e7903b7c33379a6ab412e92f35de51a152cfd2f4a5d122f9e558b617d8a09670990b7f056e95eb058ab0000000000000000000000000000000000aee8eda7c1bedd39f97efc60af110e64662b9990257beff15ef5e7856e5ea388df058ed8aa6dd93cf5a81ba48cb88854a852baf21df9f4ec8d711a48e6ffb36be8c09c8c60eaa090876236b2eae37a000000000000000000000000000000000f396976e55dc0c46fc4543a8dbf690b8da7b6010a03e04c9010f01abe1b3beab8870be0b6a2c6d6afdf85c6fd38d8b70000000000000000000000000000000006c60eeaa2d94b571df8a6291c2b12b2ce9f17f414264e4af2a006d6aef2d70436ef0978139751d4ccafce200f16f06113814a3c6386b19f7b93c2c4e0eb1568e8bd3f0012a1ae1357b127c33808aa04000000000000000000000000000000000543f8d9faa2b3cac2518f1462c297595ca10d8415143c8ff3feecfa58b648d0dd0c25156287b2f29f3b6f9a60f02701000000000000000000000000000000000be673141c496cdeab5ba8604e081ed3006828c7c877d8990efd29798c1ceae3093e052f1f928fac0c5cf84174283844aba0fb0440b2461ef64af6ec5f15db381714fce1da6e03ca962cfc94bba26d74000000000000000000000000000000001342f79c96ba0a29de9a77cc2e10314bf2e15a7d192a90af9c025e2f23ff30fe49cf239b180cfb6f8c35f95c115777390000000000000000000000000000000011f0bfb11be253b3680817af2b929de9ccf06dc574d17cf6680643b87e5fadd06b54224f155c1393c870c2dd01d6bb07c01749cac36dbbdba5662687fd1ea5391ef9d0bbd24e05bb5904a20fa6a1e11e00000000000000000000000000000000183eab3c2a127818862c6cb42bfbc9d59c51043dcc28c68d3fea08331323c9dd50cc34a4ef66a97f98684a5d9a982a1d000000000000000000000000000000000228f8f774bb68f966f3ffab5d0928a59707d6fb4f6ca84fed831a8212f71085cdc27b1d52909bdc005b3250f26cff3b9680fbd6e6c7b1b14b000d3d18bf93242c74662ef108d711d85d8d442e415ffd", "Expected": "0000000000000000000000000000000017ddd94df17d52e842abacf3467f4461e345cbb680ae624f98c6885e40b17940bc240da17ed0a1a45f13f2ce4ab8dc100000000000000000000000000000000005ea5144aa5d5393b98db4d23477011638dba465a542dc28691ee2807ffc08413938ffb74e16c7afc507f85d76acbcd1", "Name": "matter_g1_multiexp_11", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000023977b65312306b1a746b94bebbe79ccef0342ce833684a273d8baf74e0ee71104d6c453acf02d0c4f3909144b1a3b700000000000000000000000000000000050494df74705eddbf97da56a21bd673e2b0d3a9cc157168b8b413a89359c9c48f09e756f8e6ecc67811d4bd8043bba91ddff10527bb64de6ee2e3ab4959ebef9e7a6964b7482f9fae396b2b9b0cff9e0000000000000000000000000000000015862e2e3cb73ed2ba6b0b69dd9fc4c308c0a79e5cca2d2a42fe94e9b029b22b5b6aefe0503798d78d4599dd5c201cd0000000000000000000000000000000000c49723dfa37fb1592722b14e6c75110cf2252ad5170131bb72fa35bc359470bbda292fc2a459dab89900eb251e848e12943fa2957d267019309f4fe5b6725379d893dcc270ff7f35b3811ad1d8d12b1000000000000000000000000000000000af2d03791884033b8293fb636b0c569d9b008b075c6c71ddd7b0c3f5e139a17e1fbb18144d1ecf491d2fc40b7369c0d000000000000000000000000000000000d680b707e32626219fba862cbb18e39e03a8b9ac78f7bde619049748f7f0e49cc0223f1111dfc1f5c851229e62a9cdc1551a3c2d0391fd8dedade892e8e2171e652d2a9b52f2288451c55f77fac788a000000000000000000000000000000000b442117cecac25834a442ef457061634d863875c10e1809a3b9464eef6760f074e06c046a74bfb34f4d16255cd4f62a0000000000000000000000000000000000febea79eb8102b2632b6fe3151d9d972d5dded2893a117a6cd7e2bb662f042131cf06d04ca5c88c8535155910f9e008eb2fa94a5c97c28d95008dd1fe60137b34c2e763292d1b86993c02790b8c91f000000000000000000000000000000000d355c97dcf055181b8c523bbdf7eabbf064159c15532bef1e1be56146d72c08eb5d6994a3be7d6f4a4ef204f0e6d8dd000000000000000000000000000000000cd6d4e6df1ef7cd5fcd360e8aac511a3aea1f3e29536c193f4c3a2ff0f3ca16ebec620cecddfa8f27732eacbea75500f72ae1def6c988f9242bff0e683b8d2a5c1aecfd6ebb9442131ec5b5b825d0f600000000000000000000000000000000072ff95f5cd9416eac2cd83781acf856a0bfa567a079bd3cc909eeaf5a3fb31090e3e2ccc3acd44b6b04b47b5b8609a7000000000000000000000000000000000b7a39ab3ec7de26c86eee5d8737c7ae7e5969b03457b7b7b5720e3492ce254a63e031fc477361606a24821830d27271331451748146f0564ab0d91b09db87e8a6ba8b14f8329bc041911616195f9fc0000000000000000000000000000000000886babc1acee93b5f96e4a0700805982657d15170c77468c77000f21978f0cc154a265de2f766d6f7f8600f378b219c0000000000000000000000000000000013cc47f0a1e5f7315e6ddb9003dbf901824e419854d234676e4a8593bc5ad4c15e8c59ee6985d0b729e7d095e9b7642416d298bf591bd927aee24a37c5ba508c3bc121f5150fcd1a70c1f27a79da7d73000000000000000000000000000000000567f08c96b8431a133cb284144f6ec8f7c68722f18ec257b4def0a18a754507eb477f405b8c256adb797f45ed2755050000000000000000000000000000000004945b59bc84df7b793dc759bc2a3352b3eecc5cd59bea7a9560c06ef25828ad2e9ccdc6b3beab7a71a702b829208b8556be810c3fa86e35bc935fc2b27971c9c41d03c8ab7b6c8869db90b6e0986ef4000000000000000000000000000000000584ae62e22e0c2fd733cf2093f7a1f3c763453cc34a7a7a4548d8fd43c95f13be06da4e41f257f6d38e6e6921ad0f6e000000000000000000000000000000000dc803ba6a45298075a8cf45939a61760de44d22407da6ac0d63939918daa6f78e8d0b7cd794256f992cc89b8622e737aea4445926775a6baffb4dbeb249dfe3b3e0c29f2a579927f540d8f6451553ef00000000000000000000000000000000090848e332eec39e026eac0e6416d1ecd5aee8b4d82712b6c113da1e7d38901470743af43bae951d4141592f6057caec00000000000000000000000000000000140f8aa557213d49097ef315a18ae7e62924a97c71139555baf08c70674031934b629a457f75bd801af579f9fe9395579ee0e58d08779add74b68dd75e82df172b719cb5a772b0bbb34d3401b9f212ea000000000000000000000000000000000e29d6fd73f56b4546358967d7f0080e6cad97531e3d672a91a6dd121f35cdf0f452dfee1ad98b7c832c2878b495f3c100000000000000000000000000000000050fe9818b36baa8ccef166247bc673baa8424e19a19b199ea5e9d0baf56fd68cb339fdf5d041b31545e28bb2b8fe32c773d07cb9d20744a2c3ac88082a8d6606acdc892666753793a2b8bb81116cc6d000000000000000000000000000000000c13e5062ec580886d09c87c7cc72f7f19227eca99b0092a7e9759672ed1405d21fbdc8985847fa1b57129ac40bb036b0000000000000000000000000000000007d6407d32f846088759be5369c5ab66d2f512f00c93eefaca86a86bf7b1e3ef39ab85fb6c317c28c4e331a19b927650f6bb1445e9146b117bd0c95b009fba670a5391874dd314cefc884bdb0a4eba6800000000000000000000000000000000112839aa4daa7b0d614dc6a555731cd4b595a0495f2a2f0f1a3b3fa1b603c36348e265145583e8bdfa8a2a26c1f822f1000000000000000000000000000000000383bcca42f2513ce42342f4bab5377ec276bf0f1910718c7203d450f15c5b6a3648a82e4cd1222109171030eaf05292d4158de4e23d793ba77c24a70f0ad07314927fff34361b0d74b25e8922512d7a0000000000000000000000000000000010aa255df04dde054fc069473dbbcde9c68dbd71048b195df2b23e5471e5cd39eab5658ce689ca09db80c72e099907120000000000000000000000000000000013cfb46746c9bd13aa88a24ef3097b35ee2302e76b19ed001baee8cbe5b19c2620043efeaf81697ce48af0717a1066eec629ef41d5a2ce49fd81930406f19e760a47074e159ce372dd67e7ea46ad706b000000000000000000000000000000001888735aecb7125b08f2a840957887fb5be0517788a8931fdb8d280579776c5ad70e6454303ba23908bc6fb864a4ea290000000000000000000000000000000019479631b9c711f700ff2353aac97cd0ddbf14669cc046e686ef19ff0bea0aa74b4bf771882f7226de0d4fe356301912c718651715ab786b4855092ed21be41b499b7824d0bcf68ad31b31ee4cb730d50000000000000000000000000000000003233c1edded239fd465f7f7833251b98ffed6180b56676bcbe2ed361438d26db671c03a6454a4fda34111e358eb2cb10000000000000000000000000000000003cc9768ad0576a34550b913a895e2687481c6adb3371bad5cc8f9792c61aec555a52bcb267c337649fa00293c9b4af3c685a2872c4980518fe60c61e2276ef53c007166f7eceb355b4cd533f42c00b7", "Expected": "00000000000000000000000000000000117879988edc3cc57fe19ab04eee6f9e94a30811b809afe922d63bc3d785a3a581b69512180beb89402410a4d8abf6620000000000000000000000000000000000beda376a5f1499882c560961f8b0cfc44c712d6691677ea24db18b138af8a21a5a4fcb9cf5814473b0ef7c00719700", "Name": "matter_g1_multiexp_12", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bc83829ec8e98081abac2fa8e0572e819b570b2499d4cd1e6748f48c350c392f5d52c672dd0bbcdf1469414d7ce929c00000000000000000000000000000000007d1574eb65b391475b49857766c808fa95ac2a78755d8d740d2df90bfa9aab3dd5c850d536c9794f6cfa2f004b4550c067ecd54e9ef59996493f846ecca63bbd7ec28da586f0b8d41bfdc6d97a35cb00000000000000000000000000000000022e4ed74f98d69a9bb1037a307eed57210d3ca92648ca9c54546c7b57102558ab12f5d2bb46502ba3c07529f64b72b30000000000000000000000000000000005ea660c44a9d36696a899ed1bbef1d951656f2eae553f4f124ac9cee3d7de13556a7884ffc07e20d5afb7bdb9c6f1638b5112baca5e0f2bfb885c5041189612918d203a117d886bcb3b27df7e64d17d000000000000000000000000000000000f6f9411caaf7bbed9b05368ed8bbc35a0439a5c1ae417215d10adaab203aa0a607642aa8b94f4846add8f5f8db755530000000000000000000000000000000012eba1de04ecff3405596452a4f5830bc6c8af2ab0e84115a8a04a2cf60400eb741e8eda78ef733338494fd4e7b16f812db7ad39ec8129e9e9206bd46cec6a8ad3362ade1beaa97befe148f6c67a9c2b0000000000000000000000000000000009898acf9cacee1f5750d54798a4c31796fc471a17c9d2ddbd00262f5a82e3ca968c3e02334c29aeae9b16d8916def1600000000000000000000000000000000017f5a3907bc14b6cf182af2778c88704fc6b02d2b47bbbd6e40a448a89ad1455f868dba330452112973ab69489534ece2400a11d9a67041824b97a96f0ea9da8848e7990373655d76e8bd4eb84df5dc000000000000000000000000000000000e782486684a6c3fd7f5977fa40038e8a9ac0a8611e79c18ea5328248be9ad4d95c63ba9ce41d3b4d85701283369063f000000000000000000000000000000000a98e9f649d2431991dbad1cc7f4ea0c89a58bd7e75e4a5bf7d9a728943363777c1cf84bdb1853a976e4e66a6d3fa8cbaa2d17c409ade92566ddb3913806723d41067540a36a9c283bdacb273c5b258a000000000000000000000000000000001171bd468b4d40e77b8264e082cf7a168d88ec3c21adb6c33f215e82f5ff3d0d2314e0fb12d7ec93aca92532debde74500000000000000000000000000000000099bc823a44c54fd379798eed2559d95275b324481c248d452a02755e1b5a48a7b0694b637dce4c21ad7d73a63cef2a3e5e3d21862b64e09a0893ece646de60cd66aa483662125ffabc46cc52f1cdefa00000000000000000000000000000000190f9d82f079757ad752b17b419c63ca09e3c8a23d0f56b1e738dc8ff4d588a4a2360687679e51bd75615c18c49103c400000000000000000000000000000000191b91de53dc0807b537540e81d9219daee48ad27de9e5ab2980dcc09062b80dad2a0a9024c5b0465e04e6ea2b225d0249510ab1b7850badf58cacad67fe47135f6524f0d160f3013e8ff1c881e469e4000000000000000000000000000000000c8f48d3dacefba0e1719f74867b539a65d640d2372ad38bcfc43548f7ad3d8a04337878529119b9175068b511efb04c0000000000000000000000000000000003c7b5c11985fd7ff7c75e2cdd8670f75de655aa81f6b99206ed8a344f86ae85d2fb14bce434a25a5ee25c903c238341713aa69664a8c721cefa7d6dd3fe9f92432b4d350621d5297805fcabb21ff8c600000000000000000000000000000000055e115a8a7edec3a443354b381f584ba13a5802520c54b51ade1bfc7c93c96c7cd66254738929aea2e88edf2895d82f0000000000000000000000000000000001bdf3f4b489cc22c6f57a1eba23d3348c5567d0dd1cc82924873813b92a0d0b2b90727589028b9844d351e13c6e3868c040d8bf0a787346560fa3b100b2dd9adb3f7ee716b8103abdd9609363345ae400000000000000000000000000000000041fd1625afa48a446454d6613c17cc6a65b3ec8b8f2125c0eb7b8e5d07968397d43969a6579226f496d9b24dbb71b820000000000000000000000000000000006131c506f243b5ac40354f826ac1838839eee9f61301aabd88e499d40e57df3122edc8b36f0a8b16b72f9ac783efd3e17b811aeac4fb7d91abc655f8a4392176f9060346073c957ef903e25d10935a000000000000000000000000000000000113a08cd0728cb3bab3886681d8cd4e5f14b3a4a7979f9929ed4d8dc77de6a65f7bbbf8a282818ea3f21e6ea59ab1f5100000000000000000000000000000000032e95b26193c9768cc9967c9710c7695f57fce8a4e089f290526842963504cc8c99981bed3cc7d827eedcf686c813c3bd1f096026159218836a46b9801a4f0c43189324d20220aca777b826eaf25752000000000000000000000000000000000ac19ea5cb7169ffa2741bbef922e0ba307e2bff5eb67fbd2c1545bcfebb79948489605f3c6c072444093e996594c95700000000000000000000000000000000111c277e16440fc3f0cfe16bb81b927cf76553fad040c1825210fa145240abb0bfc8a40a016db15844b8830d4d725da3f221dedfc21098ff9a9507e493d0fdb1efa6029fcdab23a016515078c76f7627000000000000000000000000000000000906df246466ac720b1db9445902aeba8ff5c747133b037f29b33880b3f511621a0241fcc46adb0532682feb4e8819bb00000000000000000000000000000000145b356e384183788358353a69c49332ca137e9faf30bbcd7a67434a980c27630c3f21781a36fe73e82459318b59331bba5b30d1397bf28100f108b84e05107ddd6cae2e82f1973ce187e8c3a7d02f3e0000000000000000000000000000000003f2f02b7ab2d2165836349ef8f53e42d223f4f6a892e7b72db93362de3929fcbda5edc4606766fe26ddfda9d09b283b000000000000000000000000000000000feb10a6ba91dddb0829cd6b95a78958fd55cdb120a7237a2842df1a2007530775848c3976804824698a4370fb022bdc19aadc83d1db9140af303c0492d2b9bb9e2b53ddb62cd2132bdf8ef62aaed683000000000000000000000000000000001433eeb265f1d57027a80189806d071edb1f5ccb97da0b5e00dc75eb88304ef2eed287f5d74264245684a1677a23b3f5000000000000000000000000000000000be2d2b5fd307192ef8a0b2b4dc9970c112a236a71ee899a0a5147012a206a0274d34901594f54bdaae26f2552da481b87eb6fc40b00246910626ab66bfbac96ea09242d1d70496466e4d681942050700000000000000000000000000000000011b50012e0d92c0f74e3b6e83d60bf77e710dc03baeedc949c1af218bcb87ca1528a745aa819a5b615ac355dec360eed0000000000000000000000000000000013cd46e3cbe008dcec36e64285173b7d545359c23fea32d3a1fa2918c5c5d671a87d90791b70a740564c0f731fbb32013bb5926f36808c0024ea7388998b4cc8c6c48d32917f6456b39d514143c6eded", "Expected": "000000000000000000000000000000000cd7a2b89d286a421808305db523aca962c3f253f6defcfee9b74bd7f00b3ca8521b520376659d584b03fc5dd736d3f800000000000000000000000000000000117b8b8a8e299cb0fe3eee45651069a21988a2421b1d349529cbaf7362425349148fa043581e5fd275cc94a4fce44732", "Name": "matter_g1_multiexp_13", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016b98dda34f703f90438f5c2624c1ccc870b18cf8eb964800ec97179f67f82c521b1cccb1b81ebd3484da1349e4c0cc3000000000000000000000000000000000c743850f15041ed9023ce296570036f96db4a510903a0e7971592348651b44afc0091c8f0d6e86bbed8bd3f6b28072af44b0204792359895b448bfe6ffaedc14d54a6d72be7a49718c0a933807a399d0000000000000000000000000000000007df1648d65d140c775f729e7739a807a7f430de0711671807a7154a8e5723a2b9137175d47bc319ca659faca10af23d00000000000000000000000000000000199ebb99b555fa438587b9badcf5d7858029e905b97229f1de4ecc1940ccac59503e0e1a99c9571d50ba39ac3619699bde25977e7426cd5652559626ff8b195ab7ec679de987a6a22a6a0e366759dea0000000000000000000000000000000000027b64caa979063b420cff77cd259e54bf86498f87e7297651f9bbad6087a8b4b704b27746db53f8869d080a22363c90000000000000000000000000000000003239455ad4ab885727a25b0cae5115d87ac9ccfd93120ffded5130ac683b3b2485fb358e3aca3b6cac4bb3da5b4210d2e7ae497b44f531fe203a599622954804c06d5348dc17eb1537e750006584b210000000000000000000000000000000002f14454852a72159581b8a931d863c65170fa9280cb811c697fd067a505910d17fcb71b27963c2a6a02264aa0e1fa04000000000000000000000000000000000303f0857d990e90e19a076d2d331f5eb7fbcf102dbf8d4cb29f159fa2277eb413c0c10c3b501cefd9ca581ca62876c5e073adfb5ab96730c53015a4ab6210a35a37b2331ff5123e00798c33e040a91300000000000000000000000000000000192b3fcf7dd2534f226ad51f40e7256064eb788e7c91b1155908fb752ed4e854fda44af13f0c681fcb818eb4202eb64100000000000000000000000000000000125b51b4cf8e9427db9baeee0417b02c2d296ec4adfd437667238ffe5137b85b40fca4fa705f81d0b4b6d788a8456f1fe6e752d40d411f1ee6e67f48109c9a059226b446601047a2189ab815a3fe13c400000000000000000000000000000000130798c851758638c03f90f9181814eba97c5f93de85a71bbcc360bc53e4491e8fea38ff8c94061cd5008b0333ff26af0000000000000000000000000000000014758dbfcbbf0e1c78fb3ad4945bd300a74f2555338a009d807e2cf0e5fe582729556bd3ecb79db131ed9a72c3362c37e657fda33cf4ed1aa89dbc19d58fbe3043acb5795dfb8c0cb97620f16f8f243500000000000000000000000000000000093318a1c189c8957c9736a56a4b3e8da13bc8a303303bbc106148a0a7f319e30f5dcd11787dcd3424255c7a02cd3e760000000000000000000000000000000015f0767a3a1e3c448ecbd4ac8c4c70db6daec95a1e4b3a69cb5dc10fb43f8ad030e360832f7726cb166e0fe5fad0c860c73458e18d6f832f362dec7c49140e6523ead045131a1b719b0c836c1ef13a79000000000000000000000000000000000c7143093aea0143c58e2c459472f44b6b759a3f036aefced481eef6fb3a1b2af72ae4cc4de06af2a8a99e27cf9cae140000000000000000000000000000000019f44d1120d82e50f7da3c1e87a47d3433152b7141e9085eb54e04f30f5931d067f9ad559cf5d092dbaece723e6a724138cb0a2b191f538b30187dc730a8c665bbfce8186883500baaa6c3242a0d14740000000000000000000000000000000012a171d46d2bbfab83d02e023f5edb18e353ea82174d1a1653952bbba234c7de4fd5ed212c81f795e8c7a0b81e37087a0000000000000000000000000000000015dd85eecde306a845917187c404cee066038a764beaca9a58b859873b06652800291506b4c995581866a3c2bd7f19618a27de64d41d13ab67c1f7b1a7390ab4dbba7d219dfeb31255f9401d5b3c62f800000000000000000000000000000000176e512a4122ef10ca1fe6626cd2c839d4c573bede92092e5ca55b0bb936de9b62297b2a598a033e9a7e49ba9aabb9190000000000000000000000000000000013bf0f4c0dee3c9298192748497803a906e4192333b1ca61deff010a63eb8e4cbd63c7bd5b5546540e71bcac6000eb5380030798960729d63db70b8bc3c0030e80d9b8ae766e3330128557e6c34442f600000000000000000000000000000000066bb65bbc3f8ed9cdd5cfcdb121274427ab7dff904551a60be48f8197c84400d54ec27ed25c2a09687f1067c10edae5000000000000000000000000000000000afe1e97e1dcee30959a6411328f0d69134bb4c3a0d5ac53b87f254593f7cecf3070eaa9e19de76ebc6e1052a41ccca00d32b6969af54dd345f42320ea96def3c6f4dfd4e22a82686b7a3c57a0df5250000000000000000000000000000000001439b3031d7272f92c7072c6b44dd3a1c328251d34e1fcafc5f864b7072086168fa6f398d6334fe7fc56d6fc0e776eb600000000000000000000000000000000090885199f56df470628357ad224e19c29dc435ac54b8c17a7df5cdd24c3fdfb136952063dcb446ffe271ab5775bbc51969848f1b8b36bd28967b762168edb451322e2f0c4b99b7f9112c9a66093fb3f0000000000000000000000000000000011a0c8f7d76a36e605f193efdb5f7899d7db5b89ab0603dd6184e69a7e51f0d7e12f466fbc917cc5b6dd6d4a0bac16c30000000000000000000000000000000015dfa17cdd22984bec570d2ca24a5ac373f6f174b66aed70a15ec892caaf92c73ad3d7ef11b2f4a0104df8ec5397f5e9957ee08a513c5e22bbec04722575a9b4f3a1343db0ae5beef4e66fbbe1ac90440000000000000000000000000000000004bfe701f6645589925b34c1117cf62752b4e242e38bf056ef36515338a5c3698f561d65b237123677d926c1616618ec0000000000000000000000000000000011892535443daffffce0867dee36b7bc711006bc0963e6a061066b889adcde877a8dd3661250b6bc48064ed9dea304168e0cf0f590f77d13819001916d2c58a654d0b9d3c47c842f2d649cb2570dc0d50000000000000000000000000000000017666cd38f1e7139fd032a79776301e4eef7fc22c144900c711f1568634d9712b2e3566bcfdd152faeef20b47cf6cf7100000000000000000000000000000000150c30df0eb5945ab96603b0f36120a4f697b6958a9929f6dd8d1b8a34a1d1d3f1a34bddf9ff7f1e105ca23ac34b6f7671a8c2a479dec43d644ec4113142e666bcefd6d729d4faccbc147effa836ddab00000000000000000000000000000000107f9378f695524614ba000d6fd1b72c5eafc4ee60c5ba36ddb72814936403fded547f8d15083186f7f5f5d94c1ce18300000000000000000000000000000000140bc17d86038d4fed0580582f55d90259b460ddaeb37a70063d09d83f5fb6c803f8b467927758cb7cc52a2a6f8a84ba2d2d59a7f138327a20263d6338d2a92fa5a2f741daefe9aa81d06f20a6fe3641", "Expected": "00000000000000000000000000000000179ba87e1596396fb5cf88f91f56e3fd6f01dda6f95363be3365bd42960ed620b7648863524c22663bad20d128d22f4c0000000000000000000000000000000001ad84c4e62b0494bab4f2ec2931d2331d88502674a1bf58b765eeb022f3d6fbe8f8546818d965a8be79a94be86292c8", "Name": "matter_g1_multiexp_14", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007eefedc0360b258ca2bc9add8e23b9d535f35332e7a35952fd832d7fe3d448aac08a01073876a21914a501dbca513850000000000000000000000000000000016188049abc44154b244c6af4e115caa14a977efcdd524ad78e5dce010f2f48259708d14454630eabf2318bb271315007740a826d524fdb7969776bede5ada468a0115229152907cb2b050760c18c8e20000000000000000000000000000000010a19a7cae27e432b77c77d26653c6f17507413a5037621bdb096fa4f33e68dd86d5aa3b52fa54655730fd88415c3eea00000000000000000000000000000000031925aae4540280dd6d08fc53478fbf05b0ec784d04abd04c3a8dadb04ad9adebe87101c6401ebb4a808104b3d7e88fd226f56bf3935ea95d976fde5790ba0584e5bbc78b37279aed8e50389899b9e9000000000000000000000000000000000447e249cb49d64494fb1f1b18c94a44791fd8d4957bac13df1f992480f72a14c3aec517184700d87200092e866d60ee0000000000000000000000000000000018a12284086bf2f64297a65f6c8b55b4ff3b791372b88aed9085152e24b1214655a74a182e131d7023f949c8cd9602dbc133e1989ac82e4d1c9852a6c7156a34b05784a58231d59e3cc875ac5834d5c8000000000000000000000000000000000780d3f5c10ab7932e3e3b45c942d1ee2a12f28070674d9c666016d084613f3ffbcccfb576fb7779feb2d0e614106c990000000000000000000000000000000000ea320730367c89cf162305c69ad594d8730d71a910f53143770f50024bdbc40b7d2486b1eec63b1ac7dbaeb51ef9640fdae1b53f6442c4378774a981c90d282d5f8793feb2334470c873491e41740f00000000000000000000000000000000049ff517593107482da6805fe4ab49cfe9cf71c9a95eba00091511719eb76db98f71f089a701c6c136b398a40dccfee700000000000000000000000000000000038d1566f1057bb2da7813c39374b79149e598e1651dc3541a445264693495dea35a6515dd2173f7de43964dd5e8257d70f1de7cc5e6a2cf7dd4b6e60ada67ca47e7b9417bb5f599048fb0c9b2abf33d00000000000000000000000000000000016baae36e71ce87a6dd7136f7572788c256ef88cb73e550641f14a557828e06ad64f001fe78d69465fed92b67e8dec3000000000000000000000000000000000613a6b87249bfdfd01016ce920aaf902de85c066c2d64c866ca0a93950a1a971cc561560a4122d9a766e38f9dca9239ca82cffdf59b742a736ae9a6d36f7840c46c20c126ec054f47ad52a22948d721000000000000000000000000000000001921d310700ff4e2868a28dd29ae6e0216bc27ee9463cc8dd2823a1b4670abe973859e86719142525ae5c76e2df0bae0000000000000000000000000000000000b4b4952e96be92ba6c78037e529c197c9404cfb67af04f39d24045c742b34a700057b2cedb3193dad70e64944642c01fad69492cab4ec7eb89ed37f1e7fe898ff49ffac4ef2aeb75d9c6b544109a08f0000000000000000000000000000000001dae69033cf21e6e1618efba143426df1501250c82f214ecc9ccbf957e685d9831533cf7f747fc22309227aca1d1a2200000000000000000000000000000000114abe65155656679b89a11c7961435ea9f77fe2f957833dfb61b8538695e2569e509f0ee2c0bfff75f83d9399a3d49b5af71c9baaf54967683f8553f72abf789da465041ee5a92c9ce1ad562c91c4d700000000000000000000000000000000128e019ff92e7171d3c791bd4cf75b0f47c2a9d8722b4a8279f1178db6dddf8a4c00083a935168518a1c26a56b23624f0000000000000000000000000000000008d0c5f3300e73682f4756e6ff1d6722dde576beb587301ded34427d6935e59e76cc8a8cb0ea5f659db9ad5435851e53c7effc9a7fe773a420ca430c58bb94e7baf26b9a97b618a15e7a18b31e5914f1000000000000000000000000000000001110168c2dc1c2f0df0dc645970c0feb03bd644fdbe1576d5e5a8090282bcb81ac9be738d18e72a31ceeb5ba826b40290000000000000000000000000000000013fccd2429da394be698812af6c3288e89a26f0244327cd38bc85d5c3bb934004bfe24449534b7d271add7a279bdc8512d5a3d0370f4a58c21016d208609f1d3e7cdf43abdb85199bfc67dd12f589b8a000000000000000000000000000000000199b9c9772a8c1bb0c015c467098bd38b5f73e5d0b3f627c8279b8dc853fa2952faad01e7be353a2762b8144cc1614c000000000000000000000000000000000f781597005df947eaccca59939253b936d1ae84805ec27dde0dc707a4583af408672addb2eea607a14faec9dabe61ae3549b86ed3fb880269be22b9cb8be6f24385bb5e24bba81bce9fd5b72ce2ab710000000000000000000000000000000014bd5d22e4bd2f7b8df4add90446650fd83d72d531395fb35dfcff72eca0886ded935e7a0e3fc99a7dd07efa1ed60c3f00000000000000000000000000000000122cfac9ae5c98dd162576c92e9acb4582b9eb67117bfbf4074654fc8bc473793a7139995666447a7663f3af1446dc35c8f6dd56906fa13144dc87c31b53186b0683cad220ab2de89d2fb515bb269cbc000000000000000000000000000000000f67ef1eff6875abb96378e5a7b1602b5dc553554987589b9953c4401fefdcc5cd7b196a1a65cb3daaa13f9fdd703835000000000000000000000000000000000f58ef60be74af52c23662e6b405f1d5c359b2ce9d15b5e139460e10da0e31161fb52f529c7b406e52c6f600d5670f3c9ec934eddc44729d05f193ac927fbcb022288ffb2bc7d4f46d1bfcc7efacef940000000000000000000000000000000000b7dc680fbfff55bf0cf276a864f448d5a9feef303d2416e7d87d6d669456b951a8769026bbba545685e1f92277b182000000000000000000000000000000000c36a14d5693b0d9d91d831c0581d1f4ee801f86e5c32f10cc400f66b58f247594c30f0059b4ea79995d6f9d90b0009ebd211ec887635ca841c4608fd00bdc0f5fd0f6365dcdfd7d6f4c36f4b25b5b1b0000000000000000000000000000000014dd947a01add8294f97a84850e6dd11ed4a513e7656daac5b725cff501446e95e3b966492e028ec23fe1238b53d99ea0000000000000000000000000000000003d9726342018f802df12fc867998b6016743739a2a4f47e1f6f50992e4fe23a6bacfea0e7ed5be570eb8242ec4101ec10bce61d4e35770e7737636c0f9a664eefa948662d3d22d1f1708fa48d3043de0000000000000000000000000000000014182228dbd223cb5b601521608bd7f87659f86a7a01233d4158484024730925e3d841e05e07f2a330b9495fb028db6d0000000000000000000000000000000002e0ad163d40a56215a774751434d19ea17341f41701d41e521983ff753ed76c435c6e2b543510e47060edaaa06d29f665c86930c1d142985bf85ce70bbad170947e850e5c6ac7803fc45980dd37a57d", "Expected": "000000000000000000000000000000001364f0b671bbcf69b3a101dd758ce54434d59fd053591cb744841ba2061bbe2be91cc9f2cbe1ec058119ec8a5e909024000000000000000000000000000000000cf5be1c16fd10ff97a154826067ab7cfd7b78ca5ad0a2e2117155f1ee126286019f8a1049b86095887e79ba67216a33", "Name": "matter_g1_multiexp_15", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010040f531866c4e6fdc255e2a7ebcea89ffc36d44e265d5129f8be44b07f00646a7810662723546ed158b2cef146c7120000000000000000000000000000000016d6a5e46b2067c29e11d00b6b6ae9f0987afb4e9357c1d223fb2962589c3527f94d4e01f2ce6a7c57f971756163e48108e559e394a9c1ff07a45bb3e022f9c212eea4ee5b77db1c5b93ce72c0512b790000000000000000000000000000000002b6e3a234119f0f06a2b049d952230da40590a84d241ff76483169428e787093ae88c4040c64f2f1e3aa5be2c37db3b000000000000000000000000000000000732aea9a2ac5612ac350b474d9d267dd1ffa822cead992d3eb411efcb6992d196d66868a0e1f89dd47da584d075d4f55e55826db8d12169a31ca27beec80554954f522b56f7994c62bdb527c2438d5d0000000000000000000000000000000014c3187e04024d719560e36b5a63228a685f085aa080c82244a3a704aa2ed68b219d1c699e49dc1fd648e904ae638e3d000000000000000000000000000000001911df5a9f709b8434856c14fe4111935156a984a5e8cc27081059840167c3daf468a290461bf6cbd2ea4fa21255d7c11362e8e39ec661cb3c5af64e0001cc94701194344a7404f1ecf7df0d5633eff9000000000000000000000000000000000216ba7fa8afa06136b054c11bbd978209017dc4d8c8a2b05fa717a97f4d88abd9efc1e9879de709b87d7de65c859b65000000000000000000000000000000001797c34bdde358ba5533d5bb531915545e3ba359ea1fd66d9dc2ce06f7cdb64684bf11e5bc02097f3b957957c986de1074d3d66cde7c4c8a4499708a0c6f7c4da458eb970b6ca87e23601c702365b6de0000000000000000000000000000000013343f0b79485528b8a5ca5e0780e8925ea7277970843ce3699046673a41c977dd0cbbc97273ed47a1a105a0017853340000000000000000000000000000000010f3232b511b8d529f91f1ab613af1e2443947fb2e29c4f98d1dbab1aeb965079f64281d0b10e58e26a4bc0577943873389e0d43f2006449fe2de506dcdba4cd0e6077e2228f7d8b6ec9d8a4129c494f0000000000000000000000000000000005aa017b9381423c9d00982fffb93a7cf9bceceaaf31895a17ce3a9bc42bc5b6f5c69679ebc91c9e5cdaf7651cf78621000000000000000000000000000000000c77e86d84377ceab757a0da9bcea401b3db29e8e577da793da0d5338eb471315315171ec4bab4e9dab36f4ec6d907a85f8dc332cb31e43bc2e551356cb8d1533c6e567d34622667e7e4e3ddef352f03000000000000000000000000000000001971e5758027516443fb373a8ba8cb98b78fd5d16b42a83becd2a9b06e8ca7d255fd687cdf10de7dfc6bee5cfd199b1f0000000000000000000000000000000013465b45ed2469c2dc6ef4b4b8ac90b9b30c793425093898203d3b13d76cf4b8e0836c6fe57e637a6eb08bffa3bb55250dc7052044251fd360538fa6d5dec9fcee53faf2f07de5d8df212d04f968a0b6000000000000000000000000000000000c14833dd82daba173eeb40c29912c0edacff741bc3ab03ae4911c334cf91d5832a8847d7e175934f61089f523b77fdc0000000000000000000000000000000013820819e27a27009ee44a5cf02e995bb317ee49b6068d2e9f4c5f072d233a6808d0feb61958e047f70b2bb1a5426319c579dd4f361fed9084d9c66a3ec4c6af5293710ba5299df3abc4cbaf5802b53600000000000000000000000000000000105a1323577a38bc9495090b4d023a9dfed8b510a9a6d755f7ad6af72eedf1c92e6a5172cf68608d8dac34242d1e0eb200000000000000000000000000000000147d889d919a58de8aad3b4735359201c47d8961a1dbd321061a81c67b1a05c6732782975445d9c1f2aed12b0b7306f469f0f3c3f516ae34fbecf45f4636c22acffbee765952b332c0f3d8cadb9c93f1000000000000000000000000000000001335049a2ed3629ca83f041e4ccedede286445e4b79f3afe225bbee6273e0cc84b32b91c54991dd072c54ecf0d6c538e00000000000000000000000000000000098220fab5661a40cf34782efcd62ede159c82dba8c6e9f032f7216b888ad85fca1031c4622547a03f14185b3eb6d0d576618f1954730111e572937cf0c9f7b3298a11d18cd890cb419f732c766bc6210000000000000000000000000000000018799254b6fe847f53e2892343dc77efa3717bccb3589b776584fcc9e934deb3b8fa4c1ac0709ce505ca4d1504ed822c0000000000000000000000000000000017b98c35564c9d67b77bfec8ce23310c93167a5f75a4680420e8d71d8851f4061d897fd86b52d4a8cdde391c5b21a63afbb9f2400ed1dec7ea63d2b26bb3e9c2acf70117e3026626f6f88a0787617788000000000000000000000000000000000499468c8da336124bb89285a81eb76fb05e4ac2bde68d2f78f1de8926109631ee3e33eeebf686c7f6b7b4d68d13d2fc0000000000000000000000000000000001ac43e7c6d46e88d88a195180df6a3a91b3aabbe54f88c8b39168ead4b9847a031561828b0076b9b94c8fc7cc0c4636a0170d7b7604b8951a95d49b6697e2d0cd2a41c3671d8f96e936cca911dd516d0000000000000000000000000000000006690b59efd7c3e7f9477cc35fc5e13a5dc7f485100ecde7771e7bbd9f79f72719cd45cc9e0e791b7b5dee6f0252c53d0000000000000000000000000000000008b6f82c8514f7804a1d75f347f08334064b81ff95765355550c53098e19a4a5fe59c6a9611f4795981047754a6304792c2afc06f19e627e9ec0edf1083823d30ac569346040965e1c92e0c15011c90b0000000000000000000000000000000000ca51cd2fbe8d015a2e80bb4a24f52abfe6b99b1fbf1b656d4398f76e8e73e7a441dcacb43a4bd0a1dd45df2ed03a4e0000000000000000000000000000000006269d0e0f77f3ac5af8f70905ddb323362ec5de91a1eb90bf3773457a2bc2d018942e58c04013b83a7764b6639ea87c141d0ff346e46a20c2498a74f910e9bb2d5d8530afc7ba47c3525861c9e8c59200000000000000000000000000000000122f6c35f7b1456952b56a5f90ef9066a191a4164d4b2f81965bf7318d485c725141576e5a1164c3c17a8bc387c9262800000000000000000000000000000000086bcc20a2f0f0afd4ce845243061e1c12eb238f2d3fd711000f259c31d826c2bb56617479139cd611d35b6548a438101d688a1aca2a837e0a353039294a9988a7111ac134a6a8a68e4f881e7486025c00000000000000000000000000000000008ee124fb457671b65c0f9f550ce1ef196c3bf13a5403a3a21a801cb1a335012b43cbdab33a1ace7f84a998a4322ae20000000000000000000000000000000005b0067f853d9dec4dee3b2834679b9145bba170f22b7e1dbbb6ca3dd98abe4f41673b283f9c43f2cc7ee2305b874a0e1b59c33ff02791031e7a9424c781ff17a209d132af06f5b825df363fbd902cd4", "Expected": "0000000000000000000000000000000016dbe06af92533e96177581a7a349811e0a3d3826241c4ca047411d5b24c76dcb6849df7f4ca050286b2d84afd71ec9f0000000000000000000000000000000012dc4fc05526d6dd6da27b117294da4e9473a34699871b7bc9f02937a8308c57b5387a6fde0dd09e8a01702a8b97c4cd", "Name": "matter_g1_multiexp_16", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001394f8d94cccdaf982b1c6a8080be6bbb65c9352a961cd5daf2f817a17bd8d5e3e086c6f54f6068691f3edc4378215350000000000000000000000000000000013560d0482e6ef2fc19cf274f85bc3d14236273dd8af86107839882dc26dbe897a7de90ab5457ca440498265bb59e59358fef5bc887b7caf72f2a533fe1455ae523841bd49b4adf16cfe87edc6f573eb000000000000000000000000000000000bfc36885481f9ea9aa275c1b4a774fd01476c6f956fe75b5f6e73199928b1928108658e35dad50b298307598582443a00000000000000000000000000000000161f833b58de4db4de0af0fd17ddf81ba20e4b6ca21dd80852cb992afce9857e6cf99cc580664a970e9c6928d13dffba73b243b83d44158a66eb6d31e7c4ae1f4b3ddbba81b2cf9a654ca7c4ea2147ad00000000000000000000000000000000042489a05aecc0fc139c0ef0c703860ed36f8bdf50e4c772487c0d27b46b395f6417ae34ee98290a40b3b765d5a41d430000000000000000000000000000000018fdc2c8ac7aa01ae6dbf84412de8a47c3c504f2abed060c63190265babf779384dd6e3330e91198f5bce5a103bdcd701ea87af09f6e62111c48993c408efd3db9ebe218ac68f61a461ad9ec1306873d0000000000000000000000000000000005a44b3af7b95c7869d74c7084d0e556a67b39090b7a62fe51fa833cee316044a26d4e383695ecd3bb1715d0693f2f1a00000000000000000000000000000000112fafd6d6f1da250d12817711bc999217d16d7a6a923b5e11cb91a333898fb27f7b89885567d33b39923d7a664960eca691b9635e38a46e2469811405ef6325ae7ef88a67c1d1c5b05806da329f27e000000000000000000000000000000000197317f509ddb9d536845443d7966314eca15f20cfcbf3ff2f8701d94974e35cc0957855e0085b3f85c7da512ea882910000000000000000000000000000000018b1ddc196607122be575ebc923dee96823fb4f8ed05fd8639b1af06ddff25398e67709809b642d4d9c21dd8ab6e65470d9a35f474325d0f065442805cab3beae4a186b252ebae54a567dec6695588f1000000000000000000000000000000000c7ed49a60aa90f074af9f7fb19f6e27ec4a83ce2ed77a44c70c8e0bec02318bbe44a212c505efed3550ab6a1ea2c6d50000000000000000000000000000000013c0a772ce2c97522607b1b05cd9a89e930b6371202b69eddd108237f1495eb1c6ca65549c5ab030cc4f7e3ff4492fe9c20e998acda67d406a238f16bc2b3066a6d69d2436577b8900a180e6a71b0a01000000000000000000000000000000000fd64797f2bdd429e6f5217858cb14d78b7054b178b74696b8bc8ec9f9ede70bd03c36c824a3f775ee2f8cd6be7e2ca2000000000000000000000000000000000f675a8a43da599a09ae2367240870636ed385eb280cc199fb7c4ee575f5e3c5fe0b302566cde70b956f3c2b20fdf09c6fb773cde356e2edac3afd2bf703b59161162dc1e915873ecf606dfc0e6efec500000000000000000000000000000000065856fe1dcbef934cef47b177ecb7df76cc8796624400d5c0518aa9438bcadf397234808d099bed89ab674560ffbb1800000000000000000000000000000000071b2ff64379ed3e20cda000602c3504616dd673aebbe7690e797d6428ecfbdb29f11138169f3462dffd319cad68b96ebffc1a58dd06752a2a77abab835d089599b4781ae51ab998ff3c5b68329068bf00000000000000000000000000000000094d6e0bae02b4e7541a27111092737e7b27fe742fd0400672953d8fd787482195a2cb59a91e8584be002976c3c3e9b8000000000000000000000000000000000c2146b68ef535ed9efbed7fd02ea5cf6ba8cc20ad8bce17c06e5d595282f6e7453e2cd267181e477f511cd4fd56e8b157f35cfd74f62fa39f919400f4d692855a4b4e9f91920e4306ebb2e772a484f40000000000000000000000000000000003925e9f1e24531f9f26547108671a6a0fcf58aa6ef2bcf9f4f64b659782b93187bdf2988029de9f51e5d41cbbc4744d000000000000000000000000000000001975210e2c8bbd2431288a42f9cf5d6bd6c6afa2eb05caebe740c0a1f680b9cced0f32f8f84e368563183b97aeb6e7ef2d1f3709700634653374fba5a94d69163ef616a72a63d462afd9f01c9ddba8400000000000000000000000000000000004a2ac3d53c193265889f6c3802d7c68b938ebb6298dbfa14d1a9f515647482c84ebbb3855686b544d4299554473f1d60000000000000000000000000000000003283688bec2b8ff2e34565f8e254d579f57f9c0fe0e8521129088099a5005dfa9d565d52a75a2b26148205dae83aa6a614ed9a08dfd406df00719d5eeacfb0a96413b608974fd0aa1d4c6176b968dc00000000000000000000000000000000001b82af64f984294882fef7e5ba880ed8b0a36a90a5e9680ddfc5d86e65aafc3899a7d63e2a420113ba29412a025a0970000000000000000000000000000000012b11a5bf0f7895e329c2c6bb3d1737aeb5fe9f32a96262d8268c74687a460c47a89e252e607032576e7b67f5ad655b87c1dd2e5e5f630fb1d07e8934dd3ab029917e7775e401c0bcf7e1fd83aef72840000000000000000000000000000000003ad0dbf936f79659ccab765a61633ebb648503a774e92b24967aa8f8e45c5e26f03acbc7984a45e089ce68c5566664c0000000000000000000000000000000011686f58262dca9399d95cf2828b50b216e1df251b61c77f952c21374bcdacd99d26891fe5f335afb7ec76ce7d95b43f64e9d16cb61f2bcdef30cf544d97e078fccb999b96a1da0eeaa0bf232f01995f000000000000000000000000000000000ddfea60c169079c0fb4b9c3ca539e43b7f184f31cfa2eeb942acd2a84b472597c83fb52544479f326bd1207b4e872f000000000000000000000000000000000102108e827cf4473ba1382a2fa8f3b904f20a40657784d54e3a91fcf2703dc6fbcfb7f4b0e04c3a53a24a6e14b5735f435bca9082d66c06761f702dd439faa4957caa70ce0343268787f41a2f4bc0cbf000000000000000000000000000000001286a578ce3829f289cb98aa41cb6bd7274aecbe15b5087d8c16d575fd991878b06c88f17fd4bd905c4576494ca9f8fe0000000000000000000000000000000018e3cffb0746cf70aa79053ac579c1adbb09ed5b6a8b5e7b84951460e551e9bb62f2c1968e37ba34f7633e60a5f1f2a97980eac6c8db86ef83748d10b210835e53baf8cc9f607915df272b6e28ac6b28000000000000000000000000000000000ad648d5e0a45c8208fb9b6adcb3c47cf0e20ca906c4fdb31e5c2f0678fa3ddb6e27848a39e8035cfd9eb91aeea824200000000000000000000000000000000005ea40be38d82e2b256bd5e26e71dc642e06145d94c1ca4fcfd6e63e2bbbd7b7aa153b498793e94ed1d89691195b4aa3a256ebae4b204b3888d7bd244bbff26431ab5890098870f13800bb3be3e842ca", "Expected": "0000000000000000000000000000000013a9e1e306a5cfd461a1df4f2097f0beb079a845a959ca3a6d3e229198c75d29daeb5e7b65603397353cf800e0a10d820000000000000000000000000000000016532afaf2b6d884a5b593cb8dbc38b4e2bbe522ac69b745fe9938834d66e2393653e31b052a803f3f901abdcb352eae", "Name": "matter_g1_multiexp_17", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a187eff5afd944ea8731afffb4aefde4046b812b47e7cd99687ce40a5af90d6a4a2c7e2c9ce515a229e6c99ce46933a000000000000000000000000000000000121183879453793d954c99cbb007ff428c721d0e0b9cef192dbb177696ab9d575d3ade2cd56964428adfbdfbafba7505805f2e8013007c4f6d8abf441728eda8d742ea2f1df545f85d092f50ca8275c00000000000000000000000000000000196b029b6a808602b09dd4597db611f19bb911b3acb5dce08bad8676cae9910865355cca0a109bb8d7b60359da6d0544000000000000000000000000000000000cf045d01c1a6d6ae397b39833243ad3cc310be9220f71a248032e9325c7186ce3ea40fbcdae5258410e1a513b69713e502d777b25f3112ba2264022e2f28dfb6e5d5239ba097e9d815928be44b6a62a0000000000000000000000000000000000c6578ed0ccdfea63fe924d0a30c4aa7d65d9f85ea832733013c0ac225f039bd6f94b4acf634a01ac67b7165a810db8000000000000000000000000000000000624981245bedf55b95217691d9dfbc16d0d83476f8c09a46f9541d77c29ff978ded7fb7fed7272701e385e016647463e7d64b471cca34ab0c91f61ff26719c7186dfcdef13895d37ead407873736a74000000000000000000000000000000000a406d8da1910d9ae8e52ac70f1fbb85954ff7590863ba9f6e00861160f83defd24e99be31ec63489a483fa77d84ffaf00000000000000000000000000000000170bac083f0f6f4ff5edbacc5cedbdfa314de364e86486cac0e656d27e6a4880ea3f76ebe0f69927299bbe4a734e0482e5723630020fdb48e44adda735943c91ad7d1e12f3c32d823833eacfcc8b02ba000000000000000000000000000000000b8a583c24eba7a27a05bcc606a10a306ec07401ddb8de8e9bf206250ab7cc720903bd81a2c17a9e075ecf0ef99ad65a0000000000000000000000000000000006d5c7e9faf830ebd0154dc1c366b84445a85f0ebfc13b5339294752f4d1dc352e0e4204d9d64abed83e8297325de2556e9e37bd811b76133c12268d325ebbd6656e7ed718cd777458867dc98b1b3bc500000000000000000000000000000000122735cbd1927c40688662c740db5cb78425942985ea69c729061a6ba749c78d4fc3d894d07c285aea9ee104f59581690000000000000000000000000000000007c18425af769864f403c39ce3df4f07d4b7319342457d0dee30ce4bab013b754e2ab7492f2dbcd5bac2ec1ca2e0220f7d46516db284a3938e672ad3c6bd40313d77c5d643ffcc59e3f55ad983cdc0ed00000000000000000000000000000000039c8c0453627d13ca0e174f5a27525f8a0054ced2b9e7d92c0ba7bcf06c78c1e1632db35abe2a81f72b986934ade66300000000000000000000000000000000134876b42096d986e6004364e176e23f81637f8ffd3dd86097f480d25aca9ce3a96c9dc73b651106b4de307c002dad95586cf63c5e52b44aaa79cdda6dd6fa92c6fce11d867b2ff5a04c9e44e0b3930000000000000000000000000000000000032e727809658a52f60a973d32bf47bff5fc45404e6652facc1801d52188dc7db79ac1bff415a6c3e49e417f205422c7000000000000000000000000000000000c83d3e5ed78c1304f42afcc0143f959ca24348510e241c3e79ed5eff8742a89b4ce131e63544b9497c2a1712999a18cefaac96bc5f686d6b952e7082236622b737fda0dd3900bec71654bdebc8ba2e4000000000000000000000000000000000c2bb8dd01510ffe473715d7714e47dc8fff0f24af49405e55a9537a617dbf425950ca3df681f1fb2a3721afdc5a4d730000000000000000000000000000000019fcf0bdc8cf0f14c4b8eff44ce2646feecb3ab0555f530f579cb2764badb6445166598824f7b0c46a857865ade1278239d6045573dafd09ab2a0d8ab6e97b0ade43bd79d820749ecf19cf7d99792ca80000000000000000000000000000000011a463b5221e4c3abd9652917379564ed2830907464235fb6f9038f1d3a4f0f8cf9f6ccbbf66c86e216975b2d372400d000000000000000000000000000000000f0e9d5050d539f9211ff7d3cf3f0e7108c5580b634b122810c78d8fe047ac709bbb06ab1501e08f0e58093ba8208e0d4c4a2ff4ce4b633ec8fe0bfea42ccc329b7d3fbce96c26989b3c7a391c9e806a0000000000000000000000000000000010b293dd411de6a5cc464e919d290d6bdb51952a7a68cc27aee3ec80808bf05a50763fd4c17f25e94e655997bc948860000000000000000000000000000000000f18c7ab95bd74d9095ea9ea66b2b14987157162b8b8a313a781ce58b05d2307db4e853733a45344923488ae9dce1a459af09ef1f27cb83189e4e13f3801c08d3a2adc8b5f88717954ee84499defc0c40000000000000000000000000000000013ca27fdf920f901634156567835601ac0b84efdc79d7d979c2156041bac04f3297c1799d3b0641df33da9647e604b87000000000000000000000000000000001527cf040f6c84496ceb57df9c9ebda89c394eef034e40f5e6b540e931775ab91a4aebbf6078922da479ff397cc5271ac72c1dc1efefb775a1bda754ff17389a6b6b6bb25e22697847d24a117eb8974b00000000000000000000000000000000197c0e4474e27fcaf203819563b86e725778409c7d6792fe41820c495e412382fefda97b7df560885082c70f9d522024000000000000000000000000000000000b14b9d40bf866d933a15e16f06ec16b502ea8e7084d68c74418414fd281a6da50bc443647fdba348b26b4a3490d0ac4b4a0c7c2e611a24c722975ae882dcb4b45e6f6b41cfc87e8c766beefd5b10bfd000000000000000000000000000000000a254b07ca0f2c9219fc0dfb49bdd7901999cc85161f741500a3ae8be566e64f8a5fb3e59985444206a2cd02ed4ee99d000000000000000000000000000000001726739e92da7bf5a6d2dfbf96fee6028fc7022cb1be2f838ec1b9bd08ef141f4b24e093fcbd99080721063f8b7c98dc986d48aa5b00fc16c36dcad061d10937b55ec4deee63cc2841b7ebab84f910d2000000000000000000000000000000001133389c12bf1d2e232cfef1a8303a733edb0dc4fa26acedbb288166fd232b79f67cbe76227ab2eb517f1c3126b929a30000000000000000000000000000000001ca6bf5c18255bb3c533ece833964320bee7c3da4af56d876058edd15f89b0ef147fba11e1d539d528e4bc452e17df8979d4df836daac0960fbbb8919d2f90c3457cc987153def711d6e8a12fb14363000000000000000000000000000000000d0caaa05d3a01c89d6efad96f5957f1f9338136119e8530853a58c0698583d834fb0f045e212e6889d8baaa49815c790000000000000000000000000000000009e7fd124160f6ba3afa752b2557f1c4b5f4010a6d4a3c8a8bfe350c6b6e198b9e3d11f2ec7dc6a02dad4c07bcd4bb1d25ae495ba75cdd0bfe200ee24d813e1aa93c100ce861c9ed7fa5537e11778990", "Expected": "00000000000000000000000000000000138cea47ce2ea638f06c26d24ce87073f98b023b800245b6fc74fc2851d79a402b49c54e5df4e1aa98e33801d3fbb965000000000000000000000000000000001558e37121ec3710ff5e6c2a4e418c803a5b83cdeec98c8216b8dac7890ce17bff08a95ca2aacb40eccc761c8a31e8c0", "Name": "matter_g1_multiexp_18", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001920ce210ffc78b2c053eb2106acf1e238ac5160b50187fe816010e8a95ec632a7fd29565aefa4bec90d87701c2610dd000000000000000000000000000000000322ce646a20e23a1a68361806cf072ae3d6310f4055f5289ace0036a90b5c7ada537e614780156f6a103ed726e15b4fbb2a329761a3d6a2e4d9d63d7bbf7fc6fd321ec0344cc4d7d1b6565c475ee967000000000000000000000000000000000a1ee4319282f43ab9cecccf2c7f5e08f35a6c7e7bdc8dd2f4d642e8968aff377791a5d1e2b2152c59a8f36d9bbe04ed0000000000000000000000000000000012e60ad9f99f55859f2529ce02b8b41f8565705455cdfeef3cb315903ffbf29fabffc2546359007a36ba579b6dd06c2043cbc3dd7ec63ac63618a9e5da1f9c3fb952c6fc6972dfec6caf1a415a0aa79e00000000000000000000000000000000000c2aa9516360c840b7f88ce0cfaa0ebec502bc9cb9304c1a4d895089a2344bdb6623638e730cf30c66d977e077423a000000000000000000000000000000001163f60b32213940c9cfdeb2c86d5ccf61c0a714436b3d0923ec338ce7bd35542726a87a1311c8072fd589499c26521d733a3a84eddaf3af8c5009646a899f6ae8cf233f535e360e29e2952088ebd7b600000000000000000000000000000000116aa02028755dd5195ce0b2d3234d31b07b557a52330fdb50064a18015ae630f427a4512dff06f93ae67c4fd0c1e10f00000000000000000000000000000000117d4a68064b3f11d88ce976ed43ceeb742ba6f473645995a2773121b2b8edb8fa2715f51c8be109f8d91c44e8943e7c5112b5912aa3cba657d8de3dc8138fec92b391d5f988b82e19f16fe52fafea7100000000000000000000000000000000166cbdb131fadd6c4e7a94af82ce4fc4805dc34aacb0d6cd89e69cef0b9071b112ea4a7d9d03e3dd961b5d833b84195c0000000000000000000000000000000010736a73e2283849595569db9a5b0b9cabf2182c3d8c40a39fa32abe52dd6038edfb8176f64ec12671e3411dd69397585683e0b33b5463bc71283f0625269b2b33ead69c1eb7b23a996c31c514d06937000000000000000000000000000000000ec2405173e541945011d09092cc3a71d9dd1ff54451127181bb2d5b50876a148e59f298ee30ec5473c520be0a53d61f000000000000000000000000000000001239198a5b1f6f57bce914583c3bac476a922e56d2bb30da4912acd31cbf307bc258f22fd9f6a0073ec48dfdaa4799bb5bcc597c5ed7f79173942a0250e618c93cd0917b37b5f354d63a2c02a576080c0000000000000000000000000000000000232940188006769a382a4958383aa6702b2cbfb9c2907a989938ac618f23e241767b021e8ae11c23617ab393d4f85a0000000000000000000000000000000016a672061fe76ed943e36b2d6fa4aadf579db96eba5e4c60cda2884ddcbb0f37668638a3167d8858cd296917eaeff8e0f2613a8e50fbc6683ecdd7c7fd38b4caa8e5dc9778909fc8680a58b16ebf40da00000000000000000000000000000000066fe1f7cb3d67c20a1ba29a52c0c86d6a2aca176630ff20d45632398a39404619e55b8ade69e0cb0b7a6f363c3b2d4d000000000000000000000000000000000aa25dbff2a8c1f1d0982a709fbe88563813e918c8f25f0da9c5d0dcf3abc257f7e32def4efbf74035aee1ee350cd4fa57a747bc919991ef9b7b10388bf3f301fd910f807ccd31e322be46580a71b7c60000000000000000000000000000000001e54b0e8f34cbfbc20c9feffc555036857c31f453a1bbcffe67bb71d0d6b2b278b2ec5d6ab6648b397c9255a1139993000000000000000000000000000000000bb6d6c1a41675b3394f5b9cf14ddfe73c188592916f24240edcf0940fdab1d1fc04a11bea4af90d0d9f6734a743b38086ba09829f4bbb383e2e131d554c42edf1065022975655c07df2b3445a3e6cbb00000000000000000000000000000000099f521ecae704ed5a37ac90dd4beb4fa21ac197d467185c8329ad7b87c02943a228285b109178bbc2606e89699403ce000000000000000000000000000000000a95a85f84e76ebace78bbedbd13c6b79a6339dba246596e0695aac18d2b14b370c033e62a01caf8484dced0ebe8a76a03fd5e91f590fbe171aa3f006617b20ad645626c970c2351e048b2ac377321360000000000000000000000000000000005b8ba4c7d3c83fbe9bcbcbf60b0b3ce42b52ca19a5a322fb18bc20f81c2fcac23e1f62b9fd6edde5ffa2e37f685e06a0000000000000000000000000000000008c03604012e4dff47923a2a43382edde86c76754a1073ba51fa3a2ec7011268ffcd1452d46786682ab2ee4848210cc635ee16785c004dd2a01920c52d3244e2160fec2d17a519974d4331527cc62791000000000000000000000000000000000869a2ec19afbe70ad0a15532f776f56da5d7a7dd5b75194d0c65d0304c69a6d0363c0ff3b549e8d15171fae18ea13f8000000000000000000000000000000000389d0e6c9d73bd98202191b5b213fbe77bcf527faf98f4d25c9dd3ea2cec8f3b1e8f261d9fc8baf7b1c21dfd102f99104a6d6e29336015d99e107cd312e300bd54f815c785f6008c47c99fa0084527000000000000000000000000000000000138a4f53b8fcaea11869a6208e7498238dd80be79cde96885e6e5226315deedc98a17f8d75df733ab6f15dc24efb5c5b000000000000000000000000000000000d25d69d6d5a9c597fbec8aa7fbbe579dd86c5fd3747378e984c20b34e018b83f889bef3069c693a91ff552fff1fb8a403f9cd3873dc6243748e16e4806f8eaa339edcfdbf4408a8e41a3df80c98162100000000000000000000000000000000192e8e186cc9159d2207b0af2dca495e9d0c82fb376041360ea80562e470168b52a3326553902fd6f5a43ead32eb968e000000000000000000000000000000000fcac12d18fdfb661a12d112fc3414839bd34aa244ce0cb40be79718ec37a014b43856e5e4b003f4816e04ce612e63ca34135a2e7853c74725bdaee1ceadead7b4c7d729650df6544bd525c05c942342000000000000000000000000000000000b860984aed11a63656e3390f5e94695d8cd9367ad7961c65d714637c68ad88a3602699ed3f627f0fbc5782ff18775af000000000000000000000000000000000ed00636e74e8163645c43b8b31f05228da7c42aa332ca250270e5f14b3660fbadb8e8957f52592d942b1cc1bd2eb0a50033fdcb731830951dc3c4b33f06310eca51762cb7279039b3d7d9ace93c5f2a000000000000000000000000000000000b162c0897755fa47053e45ee1b298404818ca282a7b5818364c292a6052703502656e536f2dfb470730e9bef0d7cbf6000000000000000000000000000000001924ea42eddcddda067126534e8b862f0e16dc0cc296ea892115a9ca9734fa03d019e90263be2c909528129a12a68d874c8112ebfe12bf44e84796e8b0cd03a93d2164d6edf1f06a5c520330a177da87", "Expected": "00000000000000000000000000000000056604e75c1069b4a061ea72cae2cfcba90130f6db6d9c268649089ce4ae1cbd80120a086e3f066f2584f5b2233b468c0000000000000000000000000000000018c5e93590b89119ad7d44f80cce5ecd97d4a4d3010a19fd02a58342752b166a1b82dbbad30d6f3404b330dba6a57454", "Name": "matter_g1_multiexp_19", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015f9de55b3b45c16d59adda55d9f5059e765ddc06d22d6e68c099358d8df0229c6fe368384a0486af1cc9e532f78817a0000000000000000000000000000000018b992d73dd4c602afd82ad0845ee2c6662c860c5b7be197c62a8a20e91764004b5293ea40602574e91c313e8103e7a1dbb32a4fd8b9dc58a382a7e436e23f49a134915372553eee8c605436221acc8000000000000000000000000000000000157a9795cf9a45d2ea5e0312783829cddce176c63eb16195e7994b0688f9f30a4f2b2113e955bc66dcf05b5441521889000000000000000000000000000000000dd9365359ce805327b8f627f02ef5458cdc806bba246dbb21065c89e7ac6093004d214145cf3dec605195f14f1a49d357df9664d3e17d9d46a886efde4e37e38859893113558843bc019699eeed8ec0000000000000000000000000000000000066d9a54dbb5fe64835523e8ae05bb70b1934e389db0ee7547da60e4af965c7eee14a148f2e3269f01e8a545480db610000000000000000000000000000000017d6a22dffc3eac4366d0d35bfdd053d73d7b3392e7f52fe04e7e481783db3232f85687d2341358d2148fb3af7e9315de2b433b7a95c26e598002cc00b7904816d59baaba79bae7c6a7c26dcc48a487e0000000000000000000000000000000008be91d2752203afba19d8f3660118f83dbf851a6d2c54af389ef979121c55426d0761812de72a79d46c66dfcd00d5cb000000000000000000000000000000000269b050e36718ef4ebbc89bd88106a4043b267d974439855b6027f7fc3441518c39af6d3fee46e87d399d3ef03c63c82897583b53567bcfdbc63ae3e864a9cda24bb732694a6b27415c5212c7f45a94000000000000000000000000000000000dc976bbec5c5791688499da28c1d120e8a68eb5511ddf54525c047378016f68e8590b95f05cfeffba56c3daeb0729dd000000000000000000000000000000000af6e02afcbb707fd4d8bdcb5e73e1db56d7a2eb02258b91ec4a5c46c4627525220c11e6e379077677e1b733e2df60e02f7ff17e54d759eb9c51e16cf6f12d645bf2d091427416b4edbe1dd21947b4d900000000000000000000000000000000119b86eced2222d203b6428907269b950bcbc1519859c013349b1c7acf486d3da5c4b35319e6b1ba8ae815e4ea14a6900000000000000000000000000000000015c342be097ba679319b83a68164f6820e2ceece3a90d1ec296514f0ccab6e454a0fc444d599a812bb4d78e656e8897fce0a097efee666c22d1dd0ae8c8e11283aae781e1deadceb3ebbcbc5e5280a610000000000000000000000000000000002da8de95ee2ee1be2f3ba8afd8f52a4fd0e352c295e92aa8fe9a08a03b6170222f5d6cabc9b9d9bf2835128c6ece3e9000000000000000000000000000000000fddd2b5faaff49cec261eaa8d093b410e024e1620863b6b9bd882088b59afdd4445a4971f31738e2afeafb36900b2d47b2baa349884b54b542e3993210ef002f70c6467c7d512801f0003da789c00580000000000000000000000000000000012060c8cab190beadf40a2e3d927d7cff21c475dad04d64c718d02ead9e351a27be81a3c5a71c6c95aa7d7e287070356000000000000000000000000000000000233ee868716db87f46d546aa1a7e4d3e70b2592efa0104d9f4fab1680c627484a33346406f61499e3971157a6dfbf972b94d087c3ea101649ed57ff308dd3ae0d25a1ad8884763cea1b0b7c56a3834e000000000000000000000000000000000cb9c4b59eb8bbbfb8aa2e9ed72eab69735a0154645d68428f0bda762d3b061b0659b31a907f531a55c0906532c539e6000000000000000000000000000000001806c7e8a8d95a34403ec78b43dbfe0bb09014fbe0e019f8c3b6ffd91a75d5e361a6794996e975309fa716b6c6a933784f8c35b920a35b71dcf8d15a8a826e5a7c2a2c4f1ac2c2e3a6d100363e7f541800000000000000000000000000000000131a492451e5c0ff787a233f72766339d7dae09f2e17c6bec9faeb08e4e48d6407b12adf2dffa3911395d5f25980c9650000000000000000000000000000000001f14d5268c422f94657a20ca02be7d007ea88e1a352753b2fdcceca5275a7ac101c0ecfc075735eec82b8fa6bd61c980ae6101fac82c10267770e74a0ee16b5be6eae2d455d742303a3c624d52aa726000000000000000000000000000000000d988d419d559b1b487297cec19386f28659fbc5f121750b6bbe941794954e82e67c15a9a00334527d85e9be706bc2960000000000000000000000000000000004c222c037fedce38f42da2b08f06614ec9b166cc6428e3c4cad8ffa440af3d8fca7b9e4aff727eb0890effbc2b88060002fb31d0372e7730499b26d617b53ea04821c6eae922326d755a0df31b559ae000000000000000000000000000000000fc9786ef5291943cfd885238090be47632c10cc46df48f6bb5250a7a85690f1c90f5f5bae03a71d7c52634cd0deff340000000000000000000000000000000019b4ec13ad67e058906a3559cc683511715b25e52f39a591b22177e2dd235e042832f740269544de112d9100c1ae49d9aa846e68337f4e9c99dde506a3af792732342e3b836376d4816557fc1fc9b916000000000000000000000000000000000570b5e7b74c04db066d0aa751c9f763f59c6121e4e2ca4eec222277049143fb2e5fa39ac0fb41cd85310e4504f662ef000000000000000000000000000000000b522af535ca2b9db0cff08bf8ba19862e8f964b6210ee19f0cfccae8972150ae41ae1b8ddce4b1d2733c7dd47bc4c87df9035283f1afc294ee68b2668870aa45e483d208483d9e967b11990cb55d860000000000000000000000000000000000892cc60eeaa0ab6584ef2731538a84c6a1e8dcc2efa9591ef1321442684ca9fd953553268ac4ed44bf50004683793550000000000000000000000000000000010234542eb7231f4356c34e11e7b4f08b4cb405a31aa87f961d4eaddbdaf5ba6227b2764e7c7c9ba76bac7da3b19f6014005df80aa522e889e7720a9f2e44e6e7e19c3160ea282ec87a4b446d7b1c45f0000000000000000000000000000000005f3ff7ed08cfc6bfc8f5b55e2b368cd7e9f4a508ab46c7a383b2123b0346b81c39ba1304d628448c65d8c86bec682760000000000000000000000000000000001cbd3457f6925d5b8db7a785587d0dc6e2ad2ff5a6683dd11c8946e953dee72bd52760cc977987cd06a2679c74f9b64893c9daec43032946a9e892dce960e07d29b304000378145148b9a24afd15157000000000000000000000000000000000aa17bed794d72f8ac77989ce1b78550da54b4920ef6ac4ee0e83bb3cac5431cc7fb5c300c021045d4d391c67963feab000000000000000000000000000000001300e87daa3c36d87138628ad9aac5ec7d62e979c83c5ee4ce9a375fdabc745fc5874578945395ae128022eb98c6d8e4f685e6bb7713f8fe202c05dfd18003eff261456026a5185ee9e68aa821fe7c5b", "Expected": "0000000000000000000000000000000010a773006edb1a84341f2971f9226841142b26bcc4af52bc8b000f165f6c59d094aa2eab1b83b3623c6c09145b5bf6120000000000000000000000000000000000130a0242c95fb2b858256de2fe27df7f5736765f880673300e3506a5e756b3b563e52b481c51a003bac76d04f56c5a", "Name": "matter_g1_multiexp_20", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000090ef8b0781c66698848215b3aa84f7be47f86a9d95bf5a1ebe9c3dd6615d4fb4c6425f9e0029fa3d7b94052ef8bb252000000000000000000000000000000000cd1927ed1bfac35325d69fc924f4045c5af9fa5b0a18fbf6c658a3a6d405ac1159d1c82934aa116a98cceb382dde2ee94b3c88e51af5822177b85978526036a426c9ca1077d594618ebb8fac4cdfc89000000000000000000000000000000000dfb10a6b4e5980400bc275ba5cd8211b8a6bb6cce026546b9459805ba48f46a429ba683ad3f96ace4a4ffd6cfdecafd0000000000000000000000000000000001f643a6d83f235edd9dea19f0f2ecb98a82ba295d8ad45f75be5c0d5b1a1522c5d9f5ed812d47da6e5fe8d7924648fc6e456b39f4efe6581657f5c701c696fde8acb59e856943f15cdd639c1fa68ed7000000000000000000000000000000001824ddc80e263475b6ae3b73ef5613c7334b2f71c95d64cbb84dd489851580e767be29e7c7b47d53668a0ee3e6bcb03e00000000000000000000000000000000073f6ee13c3b05c466d35ac49c33e5ffebe5e8325f8f06b893042734bcaa4a1bc76da272602664c2aff48e731cea0304e5d306f46a31c14de7b2940104d0a4424ebaff805a81f1c4a910566057c81604000000000000000000000000000000000abe490a12162aa01307e814684261566302501f589c655b3cb840876259112a1924b1ee723e0c81d6cc6b19535d52f20000000000000000000000000000000006a2205d02f58dff40715070cfd635aa5e68553eea8718090e5f6a96dfb0a2f5a23e11ba92d38a7cee16ce67aaf5de194ff6d13bb0967945ff3b6fbbc104296805e4fedc3c25bb55b75cc997834de6b700000000000000000000000000000000180b5eb4201b4f10f605b4a7f5f5e25783bbd7c9e354238dacbd29563cdf119c832b4ca5c908329d5087d5c8c6786d68000000000000000000000000000000000ac5f56013acf364ce736c455a88a4b2615ca40fc67251039eb99df3cf6423fb85695cc035b6a9b47ef15db7406880bcde4fb2dea292b76d8130e6aa8aff5edf0097de935b252d42a777d4d9b8615ef1000000000000000000000000000000001963e29f92f6f72be2afa4635221b0d2f6afe9ada4582bd7ca4b77eb77fc4503578f38fb49aa1838751db8cf1ca0b0cd0000000000000000000000000000000009856a48f12966554afbcde1971499ee3ae40c9c5c3aef13bc415fddb97545ed84d5f50d2a26b9c16c4403a487dca614bac5c50a3a8a37111114c22839c88ce4072940c06f0d8b6d53fed155d0399ed70000000000000000000000000000000006cb805ab137fc56763f73867a7ee5635448a8a66bbeaa9ff07554db3d07aa38542884006744f6719f4cfab1392039820000000000000000000000000000000005e6f6f14f7aedc757cc458ba363fb5d97ee0dc092cf6866083722d4535e1b852c1d99d0c7c57e96a644de4b431c7f9bc3f37387bad1af3a896a7e66a80dfce2df1709fa252b6fbe4334d02bdced4329000000000000000000000000000000001045bd19d4fba8380467df25a777b1ed2850b7f5c5ff5501c048339c2f71278b2c97e4815973303e9eef283378cd8f470000000000000000000000000000000003278c7c8aa02c15275cbbdfc49f6286d6e7fb208a71a4da390c0c853684d7b4d8a6ab24953075a6a45f79fe0c9b910b70fbf5da3959a49fab7e97b3df3f2a38d16d714dd798a1f04ec2cbf84fce76910000000000000000000000000000000007af4aafeee0372e88786c6025a710fad46252a8df870b56bc1d8a39497c2422bc01aebfb567b5b68273ac59b5cc8d6f000000000000000000000000000000000dfe4a8471e42dceabb609b983b59dfd9869f29fdde01a168c07247252a9be6555a823a61487778597e0ae305da4205fe538bcefab5d8d0be5fc143e632e86fc065af3f2f621f293b914980abfd6a0c70000000000000000000000000000000005f847129487acc07fffe21e2d0aa6275a586f051c06e2575f3bf8549ad9f6c2678c541d0dc7bdf909b7cff683ecc5bc00000000000000000000000000000000163451ea5122e16ee62d58d6ccaf8cd981a29aa820d77967e69478127a76092e9bd0dc9f24a27ddca5b40b1fe8ce18b130b921d8cd2ca46aa6f3e0dc6ff08d77972fb0a248bd39e90a1e9f32be9e892a000000000000000000000000000000000faa1804b1f65a6ca75d032186b5dda63799a5fff3ffcf1f53eeb04bb5ce08be40fac13295937f34666e0f0be3bdfd9c0000000000000000000000000000000016a9086134daa2a1374fd8eb74ea65858ebe8b2990bb92972121ac68bd6bd77916203a1033ac4b163d863d9120bea0a33a5ccd9436b15d4d04a8ee9894c116190062c4e7cfabb047b585f3aa1eeb4605000000000000000000000000000000000a2ad31568d9778b306525e275bc4f525d86c04dbb98f48e72adae813ce9d02dc6d826a813ffa5b9f9d014e92de42c520000000000000000000000000000000014e928d48c4ca7640a5f5c55c8ae756fb6f03bc1a8e4e907ba89865ce610fbd919a024e86969c52a4216d84b37673cb5c7a5bf2cfedd7048be7ac7d2ff19d4f8bf0a94295ebdc5e792393e0e4bc27d5600000000000000000000000000000000041fc07f8759995530350fdb8712304083da882a5e4df8188cdad48a3df91a5f1bcc1b2a25fb3c9b59e2c935d579a9d1000000000000000000000000000000001925153fa12217d98007963237a665e56570cc666651c29729445adab3963d599a4eab996b192be1d49c7429d9f0cfe43563651d5f5729a0ffca6b383d884823aa3b0215fa057bffd8142199a16e4ffe00000000000000000000000000000000006c45218eaa27435aff594c2601276950bb99fb3c1756dbec76e609d163b2593933b5ecd5fd8544d4bd2d145821831c000000000000000000000000000000000a43ab2ea73a8e1131e184fbe9004aaea198a3dab575d3516b422c275f20c7a6e5d41bca0aa3dfe7ec761dca0ba6687d833323c3a668541ceba18375531c3781dd98525b49dafce4c4b3188c90f3f4b5000000000000000000000000000000000d17ec8ed30bbca5766def9fa375219503bf2f7322d2cc36a38fcc8471fd9d11d2a30ef004e39cac4d1ed2d33a66f7d200000000000000000000000000000000108e6c9ef3a5a41662fa16488243af3419e2d8e78c0311446186c96f20d9c15a60b5470eb95e0e58143a3c71a7565b05d422e21fbffa7d55270eca9c96bbefa29dd915aca266071673e970daa0ca9c050000000000000000000000000000000017f498e192905962fdaf41120027d49267523bee9de8e412161cec69c62d2586752d1da3d15e89446b5941a2f321beb60000000000000000000000000000000015e9e4eb30296ca3355ba9c5eee343fe7edcbf5bd110ca5be12f55191d0f07b563881f52e65588a8f4b3e03dfce6566e3ba7ea9ffda87131452b24a9efcdc91d1262d0d7550e5a6b787eace3577159b0", "Expected": "0000000000000000000000000000000008b5f4f55def15b4590e978384fa0aa87e088916de20ff0fbd688ab3a13138f32d1e89cddc72acdf69fd86aaed6cbc4200000000000000000000000000000000022a02016f38156fcff83fceed881f96fe14e5d3410b4fc50e607d8a23ca986351ce48d6af970590f68aa2ad7181c9e8", "Name": "matter_g1_multiexp_21", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001155a7d2cf81ee4f8d65c835ef422075a9453bb85b3566ec0545c1198b93749beffffbad14ededaa5bc6443736f77bb800000000000000000000000000000000073e4df0ea06345dba9fe772710ab71153e57152c74bd05d8cd4229c5ba1301f7e654f3fbb2a45526f1bc3b09c72366f16aa2cadacb129598aa459bb2e6b7fb26d1bcb7a49617b6ef8e57018c3db1f51000000000000000000000000000000001238e5a46f24e0f00d2b45bfad87f96140ce10d774f4a17c3df224b58693afa7cd0655e5ab202998f4f8b4b5e22cb82d0000000000000000000000000000000012628d85d982086640b09f046c5bf07b1cf718b5b4b20bd99d64382bbd8bd0112230609d78ecdc742cf1ebd24f1750ef8c02014d5392d30863a12102d1c9315839b5611dccfdb489207f918662513850000000000000000000000000000000001363b85a95432193800bdf353de1a5764cc2333b0369ca7dd539f230bffe81dce11288a289e0842f2db62a89e6f6af1a0000000000000000000000000000000003dc043b958167a900cbca116b097724e64d49897f8fb6a31df99e100be837e873328f5113a28c9fb510017d28d90d30d960ff678e1b46ada4f866adf354ba8c1514df10ebe7d88d2c8de117ef5ea24900000000000000000000000000000000175aef023d9375ae90e9f562f88e0a4affdd399c3755c1b22494445d4e7d96899aa4d5f77ab9392051de4cb7e400ca830000000000000000000000000000000018e3eab56eae429c09f9eed67492181279704d947cff0f1c9a4919dff5e6fe07fedcaf5dae854dba6719194f9fccde1704753af76295f72295645243ffc87ffc2110c9d8dfd20b464760ad965d7a97940000000000000000000000000000000018d7001b1d4a67d22399c5f9b3262183a47b6fc81786f8f7b78e80fdafb3c0c175756e602c92855e8ff9d99d4116e3a40000000000000000000000000000000018451928599da4a14442910a5bf125d97f0b67af4194797b3f54ecc9ef0be840a1e0ede13e1415391f57044d71fae2efd1b8760cc40d093912fb073c5012f910ae90f0a979cfe6d81c603adbb98289030000000000000000000000000000000013ca19bea2e93c748cd2adf682a123416823a2473148e59d87da33cabba8e0ff2516e5b2bc9a8fcea9dc4240b20133ad000000000000000000000000000000000433fa5475709a7b70044f88a5949064e32014f1d64826abbf60789380db6d5ccfa750a868d9902e4646bae766e241acab79d640b042664b23667d6c60ef9a5d59de72aee57a78d75752b350ce56d8da000000000000000000000000000000001236e6ebf0b704a18f85281b09a9552e8a478c66e59c9f5d53eb6ff1f606fd667a6f0bfe239970892c9c295a378fe389000000000000000000000000000000000cc5c1039850f3333981b1cd6457a466dde93e2355c2052cc325e18604f59cb22588b6d892685fd7843938fc1b5b8d8a1d1a2965e995bd4380d4ec52fe8e65e7fd99b1ca9f4f0c656adf7051c4b9a99a00000000000000000000000000000000003f86a5cabfe7792de25b9d8c58a283c5cef56e23dbf713851b42fc0d66481ce1946d1c632e38b9de1a55ffa0bd7f5a000000000000000000000000000000000f548b05782ebe160d487c622f8378786712cb5b68545ede95b34b08698f600e02e918fa2253a8be2c1b773cc74c41042cfbf2abd851d2c1f55c56d4f8b11b196c020c2584cb03764580d410d66784d40000000000000000000000000000000015a4bfb53e57dcf53483fca1b4dad7f788e48fedf8bbd7ac40b1707c35a57011a0c7f77ce6626821221e59d8185b9ca40000000000000000000000000000000005618adc16eb9771bfe731dea180e7e2b3b0c9537806349e653a586dea4633aaff7fa7e7ff165fa16ae0013c9672a783214edaf16742762baa58a3d22d5bb2305cb03a1326adc68adcd268428f82a1e000000000000000000000000000000000039895bd3ef87c094c9cb1ec77229d615e76dbf0f3bbd399948a70714d6835b570e54f46f94197657dc94d36c4a49093000000000000000000000000000000000f1c6f8b06ea4378234e99d16fcc439a64cad45a7f8ec567755febdeeeaea4f4b133af18a4c00b3778090c5857739b66c1f38916d6bdd5d379967dcd058ebce5887ef2bccd5fb7c2bcd758e374a195e20000000000000000000000000000000003007275e93f828b96d060e775f2b92d191d6da44b1441bd0aaeccc5abcfc7d2b5e9cfaf7b8497016ec992b13455af2c0000000000000000000000000000000015c1320efcddd0709a12a75049633dd871747e51f099e40908542a3e426d7a29b6633f5e69a4c0b5c32ad0269a969bbf1cb8c8303157f23987f8a2d206f3add697b9d0a303393008429e93cd35711f7400000000000000000000000000000000068dbddbfea897bc2b20b6f967aeafb0ef759082f55a180b3eda87174d0e036761f1be1c682d1a4c33f5113a6ff4e2240000000000000000000000000000000004ad9da407bd80ef365df2eb763ee35ae06074dae0eec7e2a36e57df4b3e5ac333e373cc60c1986543c0c23f3124253561ca9ab9c3df673b7ff8be098cdadd8354c17becdf82e7e99ce264174653007a0000000000000000000000000000000007f506a54adb1f763d55278419d4c18ca581b28ee369f33b848be495dbcce72c76533b809d70e26dda71316cfc3a1c73000000000000000000000000000000000a6c574799ba920ac58d6cea6d0f8ae249ef5310609904965bf86fbf88269530badbeededfcaa03892f1ad6b76818ec4681a0861df30946911d789a5da1f5b89c38fa1a8c0407b608122a18be05955da000000000000000000000000000000001424ab1e7a30035c4ee7d5bdcd8ef87a0aac284a36259742b68a5997e7dd3f2e5065e2238f2e29a23ac5ae9bce3bedc1000000000000000000000000000000001530257b63872851431a0bf5397dff45d6c201da58d7b779318beb70a5ee2a93142e4c5c43c3d65ddc65fe2df1af18906f0798b448ea0d10c84e2a8896f153b1ac3b84c5fed6a4ba6c932260bf01d34e000000000000000000000000000000000bdc58489ffec3668363be0a3e45ca2115bd5cd1745f86f1842ab82ae31b08a1f285e88dd4e0c7b94778f42d495b1f9c0000000000000000000000000000000006f4d2a07ebc588a8f9993ec6048092b6dad82c25275c922b2842253a8fe24e191cad4fab51621198147c6d1bfabeb0ba8b7de8f34053facf1338b54cfbe38dad73121a0429663f484277af9a230abe6000000000000000000000000000000000096e94b43a1dae483b49c1a616c010c25b660ec3566fb7d9c295d3b43c60ba4967b3f0abcc0634de5cf3fba14169fea00000000000000000000000000000000026146a58d55ba4cef1cfbc1db6efd46400b78f508ecc0b2eede8834eeb741b68ade43ef2300fdfae18c02b86e3386768823cdb73dd076ad95679a9d7b11145c12a81b825477f799300d1fd761417c2b", "Expected": "00000000000000000000000000000000143fd63e2576a606ec59d017e6582711718a542dd0a4c84566fa4312b2d2bbb2d71c1e0ab8e4e214ef2376706a20e3130000000000000000000000000000000001e97699fd2e0badc3a97f6cc55bcf729142aaa13c51f9b155e5904382ed0d94fbe1d2553d602a71ac7ff39189848a52", "Name": "matter_g1_multiexp_22", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000023a2a3e6e1c1cc57b2295c664ac26abd0f5bbecc0ed8e9850f90b04484c0cf048a76477ddde84e90cc452429e28b78e00000000000000000000000000000000194aa1d8332fd8120ed518f27fd827e3c955c2cbb2cae8d5e677f55963565dfdd232c83a38826621e8e66565f8e200b39f2e54f21b7f2116c30d6e444ca82fe800435cbbd72a98a6d22bac92039c540700000000000000000000000000000000124adb0352af8f18a631cb0078ec7daf00c2186e04d3ee47882d557b0e9e7fda0e0d258393ded20288789085583a97dd00000000000000000000000000000000053f94d0889a5122b6dfb1da2d7f13a836b9be039f127a011991c360c941e5dab8cb3c7ff3d7e128e52dfeb776aeedafc8cecea241dd6a924c9b9cc3d390fbf40ab897208ce9d3e4a148b2c30c25e7eb0000000000000000000000000000000009dee1a168c00632903b93fcf330b28ec7dcb8d6fba65f369237ef873ecaddd60a2d1af6e5b087f07a103f096aeb5e600000000000000000000000000000000006f90048b72dc28cf4cb40585925e62275d44df95fcbf1206e2bc762a455dea5fc6b830420d49b2415d259f8d5ed3ab7e428fab2c596f23bc3c9e9855b74295f52caf73cb7371c93c65370583f7fef4c000000000000000000000000000000001750fc7241cee9d71d95f0023dbc4b1f41ce794e9e7822a29a84c93b9374ccf0f11f931795fb824bb5c9fdb4f9e7bd9c000000000000000000000000000000000a0e6e6c76088200a345531f589ed883203e35c8ad8413575bf961b1e8d6716829f632e72fe90947dfa46745c9ffdefdf7d3d755410f77a0e4b2fad0f184fa9312b559785fb04c6020432465799ebe2200000000000000000000000000000000141d878adfaa6a3982cd0de93b4d64ba840a07c026ca443d6d4c2b6c36cf882e109d80df63b1626c112f9a89809788080000000000000000000000000000000005a5888d22a2f654a58d9a03c68d59cde9ab5e5356b2288033ba58fe2dbacf533e59344bdf30eed07698261d6269fc70557b05efdd02ac9d8e1453c82a321d798f3106bd18764140faede610ae01fa80000000000000000000000000000000000afb5e198ea80997e7cace2d5b271e3907525b6383e9d45d8a7717317655a79bec3a48800149d6bbb11a838b1338079200000000000000000000000000000000060dee81112b7e0bde192c9d382b1eb695f3a1b0b9ef7ae33b1c5ef8ad9134c23b4f473103df15a97bd6de007b828fe63313884abc4d430c06ae843d263f2efc1bba35f6cc270de05551e1f86096bb75000000000000000000000000000000000a9327207fa94bdffaac0a8741955968ee2278dc0fd17e99c6f4717e8b0db2ce7915b1b028c81d48380cdef05ecd5a7e0000000000000000000000000000000006c24bd6aa5f9c41bd4551afaa6baf5bab1729b7012951fd0ddaf2c6dd03ddc2030d49dc92073540503718a44260fb028faea236e782a8fbe27ab15f051ed007a61e25247f1f259b9300974f521f30c800000000000000000000000000000000195d0a7f5a351dff02a805fa08b2a793d9e0c74ae95fbf2f42bfefae8aeb0deccadeb9a2dbad7285c015ce14724879ba000000000000000000000000000000000e177a86f6aebee8bad62d77703d1d34a1b708e84216437c02e0694fe722414f2ef2577c1d39a45b4cfe6c73f411b1b413994f5645c6ce83741e48ae472674921bb2d9b8abb7d04ddbbb85a3f2f7f090000000000000000000000000000000000bc7fbda14f76ed98e78eb84033b65f286527ef76ba56dae43a094a23067e10798065674daa14f912ee13dece4f36b17000000000000000000000000000000000f69104995530de05660aa048993c4e08576488deaa177520676c9cd53034ef101fa3911e40933975aa958efbb1b931f81eda24db328588e8c670ab70431ddeebb0749b431bc1bfbd992c91f35d59b180000000000000000000000000000000001c3bfedaa15025440c6cd32115555fbbec439a9a2fbf706ef21e06a534af3f43baf46897158e211ea8821a5e32f932e000000000000000000000000000000000fe08cc9ff0fc601e5609ca139ae0ebe58faf8d2e2f4f3d0a1231382a15ebdc8f67271b556cc24fc5408daf3c7f74f875bf25b5070829e3d5a66ad24ba9930f3ad64767c51e432b51bdbe2fab470688d00000000000000000000000000000000032c376b26551a064cace577ef53077cde48c284af5633152c89ee109e880b511c0b90db1b30d6d9700037489f6984af00000000000000000000000000000000059c013cde62f10f39175335b76adc5cf7330ffa75d770d908ac7e0fba6faa7b9453e8d0215f0589af872b2e648ec1d0a9535c082e11b366cda0000d8ed0f92ee30fd2c4364c163a718518321c5e85d20000000000000000000000000000000009cb943167f21d9399b184f0bc0c2aca58dcf8e702614ffaf5407644ffa9eda85efa12dd23e756c5ccb5bbb25abe57e9000000000000000000000000000000000d4f59115321181962452c6f3c1e086cbfbc155f2c3019e51e73fd193e9b11ec891b2dfbd95198b318e4513c62cd51bc2c4cb49adce0292e259e92b229bf7965864a945de86eda3ce0bc9f1a6dc8b7b2000000000000000000000000000000000637e1dae04d31282c2278e087eac9ba8506d3c1349c6b98485cf32805bcad002e37d55667f1cc8e5e11f35b4d228cba000000000000000000000000000000000778c3a40e79d6288d3a93580c8f8bef7591acfac2c734018d61aea5dac020360ad4c69b4422f7320b87ff22e30d9a6a5e927f57aa85b2df54b4bddaa041d43766c8929c8b9146d723806ee0cf04227500000000000000000000000000000000069a54448ac1c9ee754fc28c9b671e84a67e884492f8e84e09e49cbcbcaf07fffed42820b1de61cdd0bf6314a2f4a1e20000000000000000000000000000000008f5512a1a70d3a61ee7fd6750813a29c47410b7ddd62db0426b3caf9cd7c31029638499c2e27e5922810cb9bb130723606ee8a5fdd9890b8017f6c432a45517d65328f13f3a2bb42d7115c02929db7a00000000000000000000000000000000078356cf80bc64c0e03da2198da5971b01341024a620ef4a455291b7a694ac3d91fe6f19299d725cdf7506e0485485da0000000000000000000000000000000015af5f875422c1e3ec6bfc5e57ed793f368799c2e068669656294be0de25eb772aebbc61358b410fa9ef79c72f309c84c1a77ccb4b32a762d60b37827ad6c3448c33af6af861c131adb5920ba3c2b8510000000000000000000000000000000019699fb3c6af71eae16b8ee123870888d646ac71dd31d0bb3ca365f728a6687540851c8539dee5c34f16871ca244ac6b000000000000000000000000000000000e68a278bee81ea53d4a52e84c8f534a0fb8c065bbcad9f3727917402746b4d1f611ba5064f0c3cea6f4d7fe84948dfd47cde609c38eabf457cdbd1e0c5366bf523dd5801d66a0282bc187d80417f455", "Expected": "0000000000000000000000000000000009057b093eae9c7ab2455b447a681857d588819c94b1cdffc0e315987b095edba1ca727043667749c56591429f9173b900000000000000000000000000000000157bac2835d2f972fd1269039a7b6159b7a81a1bf4327cfbd3be8b7c779631e8beea634ffefd9771c910c612d6925384", "Name": "matter_g1_multiexp_23", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015b6687a34084292423eb600bacc585b4e686251892b16a52d0783b1490a82f68f4eba5eefd36d147c4ec442d2eddf8b00000000000000000000000000000000151f59108d7383351b426ba8bebcf2a04976550aa2d10d5f89d5ed7c3bbd3473ebfa29c1706560866c8596f7549085cc3c79fe6374bf8f91bf7851ff935a124b54fdb5db498d2d37939fcd43bb93d29a00000000000000000000000000000000064e3333f828b1e54d201c043bb0f327d8c9af2cb96fbf587dcfbd55547d76784de0981a0ac86b65f4b8e45b19abc66f00000000000000000000000000000000172b76a242fb2bd9070ad26497a5c190d08472d3fbffa83dafc53d2bf612bf805691bc8f850da8c230ca0b8bd4fab818a59fcd2baa47621ebd90c5cd12b89f2a533ae86d537fbb61a14b1a80982c9257000000000000000000000000000000000158e81d92b789696efcdbd6e3e7c16386d6e5259a247991118dfbb3674643fb97a82fe404832cdbcbb58156c9548e59000000000000000000000000000000000fa0d18e57d64db246ee52980218c3eda5fb7b1029e1c76c9894548df52f69725fb7ff090417ae05957a652029d0a37019ef9fdfc5f0c4ac41255eb172d485317c124211498a8b9a74c0bfda15b986c500000000000000000000000000000000027a07cd6b7cf0219b57110edf07d758ea40b1cca42270b341b2bc33c78fb9cf52acc31676811032d3f618898a0d13330000000000000000000000000000000000e1212938244e425860646cd0258b65556360e832d4f2262984f4e307023896714731a2db10004e5509a1dc25f49ab7b8ba028831f429d027319a92fc0f30def8b97a43da456ddc79443d9f8df72cc1000000000000000000000000000000000bd589682a8510471ab1be8c348ed0d242548f0a5b85ee9eaab5af164367be21684ce2329a64a6afdc6a30ecc5bbb51b0000000000000000000000000000000008c8af9dd0e06a08f2da0ab7cdfc20100b94c04c7e6773a0351bc0e0ea503a69e5f25f250f0bbc5c7685795b279ae151edf8a6d86471f58c69c1a5e7518c69c34165e72ce84fbe0b7f69d9c2717e5d4d0000000000000000000000000000000015865d51ca8131cd5d2b0cb11c2f06e39b7e167ddf504d5772d478d48463668c4f7dabed00cbaca414b6ba96224c95cc00000000000000000000000000000000042fee2fb44ab45d310ab00896170a638940edb2df9a0f06c077bd00d203966d49694c82cd59c378445ae0577471221c0dbaac3f5e25ca3d1d50ebb31258ec4450feca1e02c84672ef15c49b4de2cebd0000000000000000000000000000000017257c7d5c733cb6e9ea1bc93bda4f36b98375147a119c376996beb6f0bd030c997ac52b1556d01152991738dc640788000000000000000000000000000000001155b29f473d9abd15514a0ae1cbd0b6a4ef394aa65f4fadfd3e9551c1d8420fac28acd5337fc5d114c092bd45e9e30d109ccbb8fcd4d4651b84f4708799d84ad0a717aedaf5a76d2970a7b93bd23d370000000000000000000000000000000009802bef3feb5688df77c86c74214451e4613d0260fdc5ed6e763226d3eea8a583c7dcf29eaf4c0bf16c907ceda76db9000000000000000000000000000000001447b1f7ac05cf8dce7e81de516d7303b310316f49ed5ef3f40f03db17926ff5f6656d859367805c889e07919224a6436326fded2b8a3fbf7637bc25bd201d20e3d4d724806cfa678ee039a39c24e86a0000000000000000000000000000000000057b59f849f0237ad511a75b66a77e79ae062025e5019eb71b7b7ad94a96c2905e25afe4357506b2472f99bc71a8ca000000000000000000000000000000000f10b6ad9fdb4f346c5b4a499722e377c7649a800bb95306dd7e2ab7542e59455ea5541f2d75e7cfb1da5dd03bf037a1e005efa8ee75dec8a013029292976e107a507ec09e3c34fb4baf2979fb759f1d000000000000000000000000000000000e0725ff4149698aa757e794590ce446a1589d9a574587575ef64d6a3c935fbd78fb60c7c840d7ef42eee8d72a5ce341000000000000000000000000000000000f0478a776be354e29bf8bd2710a8529cd01da31853d04ea722225bde560f2d9da302ce4f2634c9385ffeae379324b743917f8baf17f71222166cb9b6c4beb2e57d0d054cba3f7fd3a28cd3dc4b409490000000000000000000000000000000003103b0553facf8f3cd18967a758b73111a4a9987b0ceca3a20d6657a7e365be3925f63bd09990e33e1162bbffb63278000000000000000000000000000000000998a34ba445dbefe6023e737f3e35cc6416289185a26611301721db3a24f80dd784b001a2f2a745ffc3d0da5a9e6204f0f73e1b62561f5b0fbc409e6534ad9e37d1c0724b35cdd3f94bf6489e500fbf00000000000000000000000000000000041e13fb55bc9ed069c6d625ee08122efb0212f525b319b88197450ed1a60fc7283f61083ff263e4df10499b689498670000000000000000000000000000000010d931f006adaf737afd1ed2d1a631f519e6d1e9e22166c24830e92e3571e9f138ba901f5ac2f03192c9701067e7906b3ea24fb6447f2493c78a267daa158eabb70c1b60af8175d0d4594c99122cb442000000000000000000000000000000000bc0d401197ce816b692c5ac3ea539cc9658de56e48b4c3ac78631f3c529d4fa2a656f66098a702b4307fc56e147f962000000000000000000000000000000000d89fa2bbf3ad409a9ee7b7097662113b94fab95c98bd47a70fc2707a6aff23bf39944aad5509aba34930d7343762f6e5ed307c01d9e29a0571de07c62d5fcfc80749f02b8dbaaee9f69dc9263e9918800000000000000000000000000000000103cc442deeb800c14c9b3071c13d354d8c36d187e580073d150f4936ff178817dce67ee276d1633e003e66985c038cd00000000000000000000000000000000188b34fb0a4fc2408d8c70eab6df4c6c42d92ac5e43827044db526d4208acad4561c1310115448bc00feb9ee7cfdc40a877f31ddcb55d961bf9bc09903bd927451390922d647d589302855141cf5cef500000000000000000000000000000000145220a2f8fc61b2973d219042580a0edfcbd73a6bb6feea3655dd33bde8a25e0fb841a3b038049e554315100e6724c50000000000000000000000000000000018bf41cf4ce164819a8b00e630401f0332f5caa08b03bda27c205e8fcc5ea7a3374b591a4adc581f492cb07445c8995f145c1442ab82241f56c27dec2cd4dbfa9fc3cf1ab72bc521ab32a82346f8f607000000000000000000000000000000001416a39ffccdb10f65e5f06c8d7af68fbe894a0778e7270ab167ae2a5e917fb0eef1ef1b9fd45c991a45dc92a223ceaa000000000000000000000000000000000755c58a0692f8ff860430c5f75fa35366391f7e5313936e04230a1fcf1142c81b01e68fb3c888effddc0a498f264da9de4d1470f6cbce027465b4dc2a3deaca14e34218910aa76cb45d47139b31df88", "Expected": "000000000000000000000000000000000d73a7edcbb7163795dbb5a5b4daca733e07f6498d336a5dea1a61c9edee346f74676afe0d6d39c39caa1fa7660ab311000000000000000000000000000000000f3d573970077a17967ecc0fc5e2e7dd4b6ce910f1891f444e36761e2ee3a72fce399993405761de29f9563f74d8b1c7", "Name": "matter_g1_multiexp_24", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008c2f928feb8b65e521b7218b029a4f54022a28a18845614b3b2de93035228c282c73ce172997e6af93a402e35158ce3000000000000000000000000000000000ca2dd2c06221058a4a7a06438f035ddbd96f6b39fe80c0029f41246a2c8a4410961555e43d9b3d5d87dceb8d0be1ef42576b42e0728db912a78eec2b7b4c96575e341e86a7592a07a660c11e00448390000000000000000000000000000000010d919a48f588429918f1b2f05ba6e897c45b12d905615e045c1969ee8a7d9ae262551f546b7de764266d3ab656c3137000000000000000000000000000000000a40d6f247315e0440b0b8195fe5f7a7dfdb2e1be9e593f7933691fd22789ae94bcb6bfebf3b84afaef7cae9fd539b5379f9205ef0e3a85199c60ad9267349fdc7b6fba4cb765ab21750eb3dcfc48d8b0000000000000000000000000000000005eaa990ca9d57885e6ee3eee10b6e2dde6e1652a743c62ebce4871ebd2d3c8e4915418aea4f4285ba375ad1923b70a200000000000000000000000000000000159919c720eefd062ba8d72fd3befd953e1272695471315ff500830c9b5b60ce5f94bd6e966828d69f7f268bb423dfd7300679b7be7c71224247e8034f5d30a63f8707d92d843a703f0fa93160f65715000000000000000000000000000000000b7244995b7819857f716288dc59eee9ba5ac7bfe010937ea0b67ee71388a3792e5b7feb6890a436db4f1b26df18b38c0000000000000000000000000000000009a0b73360bc0ca3b632c0116f21ffdaecf37e4d6c904c98d6225a08d7caadf5024ad6b457cf31b924118ea147ff10fb0454b01910548432a0f706818a98151e38ff9e854f1faa95ad41a7239b5cc4910000000000000000000000000000000005c2bd45375084cbc4bfebf41709a87c2a8d52256a5e4bc162501bc119394186fd624c5d3d6749708be2811da2c84c15000000000000000000000000000000001626cfa6e87e41c2f0960d6d2b8e303ff8de00c78d1e788f32cdf548a5ca00db1f3a3c082f051b4bca93788243d9b0973685617371b27ba8898ce7f30776d817ff09ef68a9d6721d4a923ed244ae8206000000000000000000000000000000000f736c8cab0794e3751a9e13027a8e4ded1308c23be3d75b373780eb69f130654121435c53b62a929cad39c605637ce10000000000000000000000000000000015b1edb73501789811fc09fe0156344a7a4eab1f04d1fabc24f36e2ddef7c2ccf9643699cfc654b7169d8e371c14e8c660cb5aa2a0cd1e8c3fdc06a3a1f6f9b6d52a8cc2e98c85b8e258f72d03efc2540000000000000000000000000000000018dbc414f9e1c66af803b0c228a3fe77c94c29239e529cee652099d80795c460a507538eea6c94e99b78779fc0f3f33400000000000000000000000000000000151bf39a8e3e85b9361a9472e95cafc3ae11f7d0b952714d2836b903910a8c701e0c3832b8c88592bb8507694d9109b5addb1fe778c84242953db87d2307b40eeb776f17767c3a4311b5d2ffd738f151000000000000000000000000000000001241319f49e1bcc2d3f3eaca51d2e4c395241e2c5d8f32749a168e4af17570793fe086610432db1f93fcbbb95ced8b49000000000000000000000000000000000d90602dfcefc3860a78a8f51432a7608a7c483fcd86c0ee6a70f8ac723537825c14736240cbcf903c94d04e24e8ecc928416b4b4e965a5f024723fbad6ef2f65a1381e70201e26ccb40188dc3d0fae800000000000000000000000000000000024f26ba0c3295002418f7839b774cd305cecc3c2cfe20974343dafbfa6677c2fa6be5c546a1fe81458678c3548d8d6a000000000000000000000000000000000fc8ac2bf4585e8ac8454e3e424e858e1d67cb6b9a7181e26af803d8895717796f20abdfce0dfb390bbc0c7b16c70ffb78077a51f88236dba6d16d7fd681c631510106b0eb7448df456eb9ce758e74cb0000000000000000000000000000000005f24bd878cf5832ebcf008835f12f9dfbc78b2f6e46ee384b419928aae0e754d86809d360b0afc01bd8f2f8d79a685d0000000000000000000000000000000004aafc9a20f52d1c78a17e7824062a1e7165362ff265dddd4c3458c7810a8e59104d36035c93284988eb708ba196d6a2871716e790e1a0120fd26d169b8ffe3fcc0d03683dcdba7d2f953f05444076ce000000000000000000000000000000000375313e7ab999d174735b5290bf9ea333a62387996bf4df3dc33d9a5212ac0645789ef4153223d488aa2fbbcfe808f00000000000000000000000000000000014b792fb5bc39dbfe409356bd75b195d7023bf6f715a4102cf36ef05b52fb2284cc0739fe5ad628a760049c3624a3f2876ed0a27553db6ac6d3959ff4c9bc5807fb7d4f0a56095ed2bbe31dbfa41827700000000000000000000000000000000006ae2c85b2b267c86320c4cdc56b1a09e25f0f68dd208e898ac5b1c0645aca3dd8000eb544eb666f4256806123480800000000000000000000000000000000006670390bd47829d3c31cf2da8fdbbb64b92b47c78d3ab638727ea834ea6203e45a9a023060056c69c1fb567c35b671795ce72b30d989889c8779c4056e441bbcd93629efc2877d36d27f670711e21c40000000000000000000000000000000011c78f1b6d0ecc5523dc089852d95dee641222c743dfd09ff2e56d008ce523762bbd9c7bec6c18e9885b7022131ad30b00000000000000000000000000000000066a1aa8af751eac5dbaf2d3ae285e0cc7a975c1787178f550a42e8ba89fa74a1b18f27716eb7ccc4f21b7957cffd8e806d220f64de05bdd6e1140c1e409fdc13f43bd31cd94e633be38ecf22ebd77db000000000000000000000000000000000cbc0fe6b4956c0f7b9fdd36ea14a4d8284468c280605a31536636114759ece1339f06e050260bbf936b560586e7d12c000000000000000000000000000000001213bfe642bf78554d91820c362b73b7059cf20a0aefa5855f9e61a0490d165f6f61416e135473e2de54bf97cc14b8f6257da8ac7d23c5ed965d8bfc76a642a36ea6ec4c45baf6882021372e8643f0980000000000000000000000000000000007cac206b2d123cbe9375f5c913939b25886a51c857271a59cc2fae2e9d669af0ada833c72366f78be265ff9db049d0e0000000000000000000000000000000002db3f65b6fe7c6688f8d3741e448ac6ff322b8769277572f0198dd6ee8a99397aaeb9addd0892286a9ec6028bf9678863d017ba8c7ed138b1bc70141abc5cdc3afbccd8b1db5a6b5f775efa62b8dbc3000000000000000000000000000000000a60331f8e8b26e97366c0e4cfea158e78ac72d63f219e1abbb670675bea008609f7154752438d9c7758b2a2e076da7b000000000000000000000000000000000d40d90f498a2855ba35f1c4bb3c5409b87062d7857bd97dd37d6e5fa53c94c78319c6b16bdcbf2610ba379d50d131e47a16e23e37ecffd514d47199cff249415a6d366fdfaa82450f0744520258955c", "Expected": "000000000000000000000000000000000ddd3c7964bf51207485b0575afb6430cf801bae388ff78a69b8173c27431e0593584f9e755b99a5b2ed3113b3fc0082000000000000000000000000000000001735fb40978d364be3521ada17c3ae74b2a738b412906fdf425bdf13ec09e5acdf29013b03fbabe889fa261302a7ca42", "Name": "matter_g1_multiexp_25", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c52993730e412fec923e33f3da42adadb5d87290ac4448d7df9b401e28b3c7fe7f49c7b7e4bad5412c815931416303e000000000000000000000000000000000db71c91975e41b3f12e303bd8ad15f7c9836b146073946129ba3815bc3217b6116a2a03137608cdab8807d5834eb12026a9bd0a71fd58edf81459152782733536e960d27e35f9f84d00da256bdc118c0000000000000000000000000000000009657686875d82eaf4f93f3e710c467ced1348b60aa47658992771195660c4b96798cfec584ace3bc64040666de71f8f000000000000000000000000000000001375f7e985d987df508321c3d0aa7e7a06cdb78117248e19c3344dc443da319f49c00ff605c057d1ecd942e8b04a5e4ef1e168ab93674bd7f2bf73318a48ef17ef4464fbefd39f77c17ebfdb24d679b6000000000000000000000000000000000da69e098b5e2c8be2ba699f20fa38cd27b9c78025e071ecb2d9fba3bc84b1e673eed79f1887fcad9bfd5b0516236a1f0000000000000000000000000000000016c4ca4d9f15716b7efe6f9e61aaad880423243b2d5ffc96804fc70f29b633dc16474f7194b5e3ca12ab5a1627da580f97fb0d947d71a1b032070a12588b85065c19affd0db53e466f194f04f58dba2e0000000000000000000000000000000005370f5c60fb3bc36ee208e8c185613390748452cf6191bfad06c9bcb52501873bff63892066e0afcb01a0204cbc951b0000000000000000000000000000000003c7a2a97cf7be433864541082bd04467bbb42b2ab708866c8520a6582cce5225af13acb887b6b6a8d627c90e43f6e7b640f850bad2f22049f2f8aaf3ee57564fb38a847e428e252f003eaac465f7d67000000000000000000000000000000001820666eb1abd6144df2f21f2d46096410274e346ba862aca0e62d293fc64a6fd213dca4ddc1a4e414796f59db4d6104000000000000000000000000000000000a2521c021f2fb7beb76a2ff4c7ce96cf1d05823ad8edd9b2021eb39c08e0c7caff505ea76bcff8f6afb6e8c2e81d2f68bf91051da5bce0a51bcba6f4e1b3c9063743646f4e75e3e5a8cbc84e8112af4000000000000000000000000000000000e756ad1ccf0404e110a778f66ade3d10464bf8902f646f7d7ff38d15ef890bbc6d61d48122ba6edb799630a62ae084a0000000000000000000000000000000005b322f44f07d3db292c43f9ddf9ac9e44e8d16c07537bf563c98e02c2705eefc1013e627567ac2a03698268707cd84e8da771e0e827a52a2f7e79e0e5d93ebae04c1ed78cab87d4353f24ffc52099b3000000000000000000000000000000000420b819a63b7ff7ce541661c5fa8cb107cf00ae678981b3fc1b568174ae3864a8241f1e9b656cadeeba232156e66feb00000000000000000000000000000000136fe878b886bc14fed061cd8ff1fa2d85f05bab922bf18a1f09b55c331e7cc9bf0f9860e9112c2f6242b6d1124851dbd6cff707bff10fd53ffeff8e9400966d8ffba6d4ad6a8e7e456df10f8f5ebed2000000000000000000000000000000000b73d3549a6b2f76741aa39ee9bc2bda8cd55759bbedaa9ecc5802310b054b01670dc803938aaea547389d7b0ceda469000000000000000000000000000000000227fc49bdf53bc4f916714ea9789b526aa53efa1eb032c4030519608c62434443847cac82a13e2dd2eb48f73473d8e1e00831cce307cb44e8dbd5edf24f1535b837277160d2cf6daa4e862e57fe73b100000000000000000000000000000000167cdb86301937bff18287eb0b00f5224e674953d70258065e5e8370016cac8194ec8c2f44330adaea44426aaefac7d70000000000000000000000000000000007e9128bb015f01aa725796d7b7851f9c2819a8a578bc7d3af02f7328c922c26335ae9f87756f52409c446852bc710ada8168d56385722f339a5b27fc25a88034d348e3d533ff4dc99d28536c1c09a770000000000000000000000000000000018bd46832b101d12f95b21332b7259719c1f94c056118d877324656d285f73a4fe2cf637cc62a45647db92ba9d6c7d18000000000000000000000000000000000fe58fe2c19ee903d82da6da8713863423f10edb954606b6c56326eb8eea6c66cab63b0c816479f8107612391072c634b929ae82ded73a4876c041d2e52fa811882fb8e22690a27cb4ad3ca05169bbf00000000000000000000000000000000012db7fda36505d19a2c6ba5072044154f444eaaf3e12cce81ea74f28e691e4b7a730095667a71308db5e8322e80fc66a000000000000000000000000000000000fd0f22b05bf82688ac72e9ede526bf806695ff430ff3c750c2946d58ef90c778e4c5693d152e39fb1837bb10cf5f3be36999c516d4acdfbcd488d39e3073db9db6cdd0c0fd1d29d58294ace6d2d199f00000000000000000000000000000000116ba7b6faedd465fd4d1e5f42ae80c133a1d158614894ba663f87137f6108ae03b8e80bf32852ccce78b776dc224c760000000000000000000000000000000004c3702ff7fd9c74169ea76c00efb7b475d45efb12e1b5b700d47a970ed9f95f46e4c0ac66cd12fe79d62898b24b54a0fd0bc405e3970dc2bbd7dfe0c54b7c64543fc241000adeef4f7aa2f1dd2506770000000000000000000000000000000016254d89b0e2a8315253434d5444000d9b56b8f43d3c20d17fd26da4c8e7432d6e463b71a5b2a1a7f559a908d73abf6a000000000000000000000000000000000170c490fe3962fbfaaea1707bd28ecdd46ba29b5d8a0a35baf7fea4eaa47694e680e47e8a9f07d25078274074e232dcc36afa3c8581df069292d53b8ce3e35ca136a0b3f95a894958105fde9c77e39d0000000000000000000000000000000007a7fd283d64efef7094fbd6162da2fd56399765b559674c18d1cf6df51036007ad6c9af62bee534388ea093d3cdc3c90000000000000000000000000000000012fcf920eeec2c1728f3e620fdab1f8a0b99c6219f44b0fd19d0f7f4a15d1636fce7b4701f9c3963cff9b030c3759fb20f0a2bd678c5858be2a49ca54de8716fdeec84e1935b8f44545c740417efa7e40000000000000000000000000000000009bcf0b2d49ce38914ea877832eaa3f1034cec429cd9fe0d06ef36691ac8ac6b69a712792e31afc700872d08c2e0fa48000000000000000000000000000000000f5fd9d2d4710d1cc6c13c88ae602f584a7b671df91cd544697070eff3342d80d750e15e09358125d15fbf8a1ae8df93c8e420db340ef2c1b5c6a71645e303eee95cd93228770b639287b14b6a5c59ba00000000000000000000000000000000053fc59a0b84028cbb3a97dc3124927d6a0eab1c58d4c6d143462bf73c0c847712bf22557a1181750146fe63e9c9668b000000000000000000000000000000000c1fa8c1539ae702bc9441085a89790a5dcac9b18925cdb1e21b95c9f7286795e8f36e7a8b4c3f4dcfa12454624911675398541eb5a03271e2ab5ec2aeb2da80e634f63a050c25de98ad13e9d63d09bc", "Expected": "00000000000000000000000000000000085e4232f0daeddb9e1ec8731855cf855d7dbc05d4b82d10b77a53306ee7a38ebf45bdeef1981325a61ecd754944c84d00000000000000000000000000000000061e32056ac411c3917684356a6ab3c7068f55d30ebcf8cfe446c68267923e4fb98596aded9740dc7944847a2e617fea", "Name": "matter_g1_multiexp_26", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000070bcf49d6d066afa9b008fa22fd52f63b68a648bfbb5cb3eefd6feae666f3fd0b9a8447f427d5a9db52ba49854db7cc000000000000000000000000000000000947d708a02cd0a18342bc04639e8d126fc4c97acb497aa507e1c4c3912b04bdca886b75b9b9e1c5ca745acd090433119f99387baca30b9cf63ad10c445daa142fcae1ab3c0a366a068bb5efc9abb3a9000000000000000000000000000000001023942a16150e6497289627dbb0205a7c34afc704232ef214a6609125e90260d68b7c60600cd6f4859ddcad46c015580000000000000000000000000000000002da96265b7460ea6a8d51122bbd2442c6784d4f5bcf6d8b0b6eee6ec82e4d03c9265887f88c106792795837c02ed76e4283a1773995bbc97a6df107082fed4ba40e2d30c5472a25a7643ca9e78b8b8b000000000000000000000000000000000d5be6f99bb9a2379d1e542ece048164fa5d14e0c6c459180717b3da46e8446e9def576635ac1124e1390196fe97f39e000000000000000000000000000000001482d8339b402e3bffe61aaa298c8bae4286f1fbfc877a66e21cfe239bbee383d701d95a6c2b8193d67df5a551bb7aba7f4202d670fc3b48eaa92e925f48821d2ae057d90c5f184edcce9ea900ab51a6000000000000000000000000000000001969dbab76e6a158506b9dd38c647d4a670a21458a9552d903ac686855fe021a7dcabc91e712aa252de369c9234fdb59000000000000000000000000000000000b60179a6fa6146aa6e57b097f20944c123916c6722fd7e606aa34b8da579f6c126dcbb251da7917076a83e2e4b02d32a76cd8d292a7053c449cb98f13cf768c6e37da9d702af28c16dceacfaf9cdef5000000000000000000000000000000000e5fa0feaca8dca2a6b4a42e4a291383ec867f12b85593360f8caec45d31109373dc16d985a4702e3b5684774699e6b5000000000000000000000000000000000ae96f4a4ac0d0a6fe6aabcf902eb0765aee9ac81ad09e7e097d649b0c0165de6ad7e5ffd4ae7d8a272034f28c85ad6f97b7bf8acdfbb148814afee1df79aea17261dad6f78772111a6dcb021d8c79d00000000000000000000000000000000006391a93eb14641ff145f690c626ca412af266d50b903f7465d9a9b678025a35a68bf1962bb5ffe76ea07989a7d807920000000000000000000000000000000001a90846cba7c708bf8b4bcdb3415e17e80ffc9b48820d3307362327b29eca0d1bb7fcac9c09d09fa309829679080b36efdbd5953bc33bfba09fe7b3ee22c46c3a86f557e4b5f272853e67fd95a0f9b0000000000000000000000000000000000c9cc9547fd49cb22986f7a1dc1da89b05f5e7c0d3cf2179f22002df9fa2c586bb3f1496c0c60f8ba36b631fe74c8fcf0000000000000000000000000000000014f8e4e8c5a12b61caf4325d1e4a8505409d722e4eb16d51be5f01f863e5dc1ca68df1b83f546d22fc116f1654a3b30e9a331bb218b99fd38451483a10e8add23c9641b975af3897670884efef90d45200000000000000000000000000000000123292cef01012c3723b4713a345ea7648bdd8b8edaf76f149f1afb993f196f57b3315d86a374fb78a34486ea10e0c26000000000000000000000000000000000ee2389f669431df6697d79ba16d3e4d9bb4264c9ac146a772de6a9a8ac94760cdde7f613a4ae6592509b04b1f8233cce9301dc826bfe2988cf93c29ca9f01421b75ba63c5ed2cee1599122012ada36e000000000000000000000000000000001284787a11e0164bb197f69702d0d746975bd96a3b9221841c7193676861e97e11077b74e69f744c521ddb40689f9685000000000000000000000000000000000eb6c4c25fa1322f7c829691d938f87ba6bcce850404bab57cc3be8c3d0abcf123be8922af9967b83789fe64e2cb35f40a1cb530e8b828542fa4114de6aa936bd2be5ef3a9b7a0e20e475022381d62d400000000000000000000000000000000069f8970964efa22facc786291d6ffe860929121595fa713f4a12f9e99d8508d7d20f7d19c51514538d1ce89d2adb78500000000000000000000000000000000122bc9405ccae4e409c1aa22b36db314a19ef6e67a572f7ea67c247085205302ad12ef7f83d3616279892ccd3c456980cf2f0c33bd044e8c4468b4b7e137ae294c178e7b6c9f19878331fb93220db2cb0000000000000000000000000000000017b92fbdb00429846fb30633a2c3f383d32d0bd433d5a46e27d3c7bd6880948f89bf70b3f1639a18d308ba80b7209df00000000000000000000000000000000012374e8e7c1fdaa4ad4a2d8607afb62ce939bed23ea42a51fbac995e2c3026c2daaa338be160dbec2602a0fdaa1e9897e5f460dacc592bb947ff6f1c15b8464824aa5c957a645a763138ac1581ac576800000000000000000000000000000000004850419631e3de2617bb6b51ef19bf14dcc9f4c7b24ae817cb239342081947f1799080cafaf51ed687b9dabb2f3581000000000000000000000000000000001108a0463d38d617d0a778bf9478ab44050ec290e442ac41e23b526089ab5aabd5819a8f08f903343e93177ce4042c82f26a9736f728e16d7b8ce0cc59e2ccc848c181459fff4321982c08e9cac57946000000000000000000000000000000000c9ef168fadf7a056e6cceef0430f65a57b0f2c3372a5d3c533871c91cf81c40d3459cfdb5f1f66f53b2d8d50124ed15000000000000000000000000000000000483ebcdc219c4c361735aa0ea96c00c4908b9db62ed8cb565d25a7fa664829bcacc37a5608a3c3ea3a42ecf74708ee9ccf0a9be4775d65bbfc894f8ca66fa6f69d4249ea7f6b076fe193f2805e64f94000000000000000000000000000000000f7232dfd8367af413dd078f9d5f47b8c76c38b3ccc4110fd59764265e6a368fd4609b52c21f8e6db2c73908d4ac0b3d0000000000000000000000000000000018433b00ede4de21cd6a1c78c5d280af98b814f0a60c625f0a8f355be43d8d99346282b6d9911c4d4074fe827b55d726fc6bfb37cbfb10a1ffdfcb91d9a52883cb9a606f4ffa8849a6e07386dc9bb3400000000000000000000000000000000015b0ef81908ae275b2d5c3cbc563b8424ee0be0e1f2fb77f67749a79b7730d33028a136d133825da14448b05bda1409d000000000000000000000000000000000461c575bf65c6c5754a214c2e72d6d24df2cc228ae1c9f99d75eebf9cf48f20945a6483185337aa7c0096543dc0a527d94959e16f6d780628694075ba5aa1a476d89d8fffcf4b4ab7e6343c011fee920000000000000000000000000000000006e7385d061bafef2c731ffedd01758f153e2635c7f2bc42ea2efe29931697a1c50e4a13ac420572afc523b7316190cf0000000000000000000000000000000018ad5dac1577c9cc1e9ed30ab277dd381a6babc17e86538570abac44573a8c2439d97cbc370cd2b5d2c6509a18dbc96f122f3a5e940ee7e5038421619daffb8a6f433605f37e78d863f814b51b2ec4e2", "Expected": "00000000000000000000000000000000020da97236c2405d3f1bf4e937d8285014a190bbc59a17b7163a292a2b825f086db5d371776988d1aa2d7529a64d2a4e0000000000000000000000000000000016cf6d7b831a81d0c487bfc3380a1dc8a1bdada61426a457993f7d6c9c8fee9ee4959324bf7a2425b070aeace3cdaff6", "Name": "matter_g1_multiexp_27", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017df783852d1f1f9c6dcf1975ed2dfacf3dc0cf942cbd7243a0cea7907ddb289f378ae59b30661d06d0702792ea9e9e2000000000000000000000000000000001717bc4192402e587400b4e7243db7e79fead2f878079c3af998b3a683a0539aad5d6c1e5da6e0a00ffbd10a2d891ff2b3908c739d505a1d6fa85a6dfb7a155202710b45861f1a8a7ac7bb3274a180cb0000000000000000000000000000000018c9cc123fd18d50a7c878b31622a3727864fa61d784285b990fd116567c69dbc7ed872866db2166c7af1812157af9040000000000000000000000000000000000f38e55466a6d1cc2512c1282f74f5c0c19777365819e48606c0a86d2c6aab8938475d15a74f24db868802fe935f6107e0e27a8a416eb38c989a66b84f037a5a24ef3358e20cd553f037a0a2461d310000000000000000000000000000000000816580c761a2f54c386cf60b1417d51a310bb7569a50b475f8d45f13ed6c1f11640079b5d6119270d616e77a489069d000000000000000000000000000000000d9af7b25803b611351f00daa88464e49b277de8d8fe22284a9001a13ed63ff931937d27ee19ba4000ebc212fe03a0390a3cbab01c34856b892aacdabe63d0a0c241ebc137a88c83ad22cf38997b211b00000000000000000000000000000000032fbde9d988ef200df573dc99b087a8ffbec95349256989774194dabea55d970ba303657837bdcdce3b59eb54669c86000000000000000000000000000000000d65e89d8df2a189761e04d35c9f4d3a5292d1dc0d083bc9a982a131b07df6250cc969a3534808959b583923bf02125cb386bebe0e49b7f07b0ac61b15306c2515a1ad6fd76a1825dd29a60e845c0e4a000000000000000000000000000000000ed3f47ea234f8fdc16e97eec7f4521941c37acccdfc422fefc6df9c1127ed293998945fb1bdce89ea18b9ec2b6e5175000000000000000000000000000000000a066fb6f1d69b88495bcb0f0eeaad2a41d5c6764e2dcac2ddb4ac340cda72d7b51b7901c758df15ea16e4e46c7053298902a82d33993a10c56b2fa3333cabf1c5d47a9c78354d58f70ce4807cf20628000000000000000000000000000000000ca7faa768ce5ddb6d668436e2e1692893d07afdf7466c00bc8c963b80cf0d44f6eb9a2070a7bd889ef692a81f9d76d8000000000000000000000000000000000f86fb53e3f061cbe777c7aeb63402616c428216a0c65d5d5a13cce1dc31567a4051420d54b4fc93c6bf263601046712426a4e2317fee033a226a91a52a5830f9ac2cf5f329feb6bdb382438b8a39f2a0000000000000000000000000000000011113946d8ed7e5e545ecd0ef30de293206f3ac50e6010fa7a1cb0371f47aab2d8775c51172c4dbacb05414e65fdae10000000000000000000000000000000000022a7b8af616e4076f625f8151d748f4f49e6dbe439ec695b854544f8a498c7e261c366a4c81be5b9cad85a4eb07c36de0390c05fb0dc9b4a3f76b51cf952a11b909ce13f9abc9fed6a349b8efa98ad000000000000000000000000000000000d863702db9f9e43ea311fdd7e0d87495ed0bbbddaedd3333108704417521b3da4b8ff0bf904710b0200453ecb2948620000000000000000000000000000000016a520d1162c7070030fea7702420de2a6e0f255c28a89bbcaf663c0d6761d201f07d86adf5ea6589e27bf844abf85a57431db9e576643f93505b5b25836218759e736c0d650a5221a652338b0073eb6000000000000000000000000000000001357cc987a4ee7c7bc063ec8cbaecbea0ace4b80e3af01f74d23801d5d37326ab5732222f60ad864cdc8c5dfd3edb37f000000000000000000000000000000000094fbbc2936e1730a1abeb42e58818ffe6dd97bed27a1e4fc090388d943763b055301852222503a2d2a9dedf69b3da26745a32591e359efa41e9ea93a016d2eedf1da112cddbf31818e8d687b36af2e000000000000000000000000000000000672e9a4eb4e8be8efab0595bcb7a6fdf269db71dcb585c12f9d7c1a8414b6e11d91373959d47a4c64a8890766f68671000000000000000000000000000000000203f3804abe330bca60b7bf9925a626eeae79d58ce7c71658b2fceb8cc93da9d455b6d59bb58bdc23b58238d4f01948ed37a5f4bfca6b77ff9e4f7e03bfed52ecf02a8f84ed3da6da2787a4ee81ad9b000000000000000000000000000000000c4e95c27fd983c31fcacb578a688c2fe055516735b5f1ea1415c5cd29592e7720eb2f548071fa3ac642b70e339757dd00000000000000000000000000000000067ab19ad1c97a773164e812771aac69fd5d199e4f60eb28c7aa5f09dd9b3adea959ab4ad47683d27394714eab4a40d281633dd6e729bc17ddc596cb1f17dc6f0e50c052a0b8c5a4c83900d918a9eb560000000000000000000000000000000003da3fcadcafc5eff08a736e4cacb1d6617c3f0850ffe33ff1648f783a4467163d1ddda082ba0b54e678b171b1f79618000000000000000000000000000000000a273fbd5fe99df4f724fb20ae0fee994823d374979ec7ff23dbe148f6977145de9a1f20eda777cbfe0fa4cf8c2a8949c6b019d29219b57404baa955f66cf1b2ee6571ad5b80d471ff6db569e32a1a5000000000000000000000000000000000015b74087be4a98f4c5cb442e4e893d4d92602b1ad36d0f038f232ce25b53e19816f44122e8f5c821b40a0cb36897fef0000000000000000000000000000000017e50b1e84c7e767171edbddc397653c35b34141bd69ca7123792d6f20532f6daa5ed18615bb364b72744f96d4a730be6a76411ce02b4dfc84ddf62ed26508a2dfa5edb5a98a6a20dd69e8b8e7ad2f5900000000000000000000000000000000131517851372c44894bf433d5162d0da394b87a9554e9d4f6174d5712dbf69f756c5da1534eed80f8596f906f36799a100000000000000000000000000000000130a4583c7529129831ad621cd1e04a8fcfeed67ea96db4932809ac140a089e6252bcd101f17d4653555b1bdd9ea3a9b5906098e4ad7e4eb2e996075c7cd660fbc399bc942f9080404b9d0758c4ae14c0000000000000000000000000000000002b8d72148ed7076656128040e7dec82ecfc2d5ed05050b27361a85d0fae6d90de6dc32dbeaebac039187e3883ab238d0000000000000000000000000000000004021fbb748bdffca854bfc5de8f69a9bec478181477d3c6e41a7da2fab3100f7e2737ce958c046d6447370d47e373ad94ef8c281a9be3766fe784ae017d93f608dc2cb97cbb7dd3e3814b5ade845d370000000000000000000000000000000015d1c5bda34c6fafa52dd3801d94a04c53a3acbe43cdd128de3a346739df5afc6dba58d63c7cc09d18589c41d9679cff0000000000000000000000000000000014367ab7f03febf90be2279a87890527935725880ae3d418ec055004f312fa0c42c8f6fbc9c319117f6ce600d86910f16feced33019b3b66d335f2118cd22b2952cdf9757fb3a0cff55b7c4f245fb438", "Expected": "00000000000000000000000000000000130db02ba2d24a3d70439503b089e6da4cde7b5c51b1d69774b38ae0f265aeb8996e50ef077ec12199ffa3d000adbf38000000000000000000000000000000000de25ad8eb2142051fb2c97175cb4cb2984ddcab65dcfacb76cfe60f6a47083a22dac4f6e06e357a194249b7363210be", "Name": "matter_g1_multiexp_28", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016785db77cadde48a4ed0d2f8aa9f91bed9387a4766c3566217afec80b180461c8e1017297888e9c5896e509a26137b000000000000000000000000000000000025b26ffb3fa42b1a9e974eb23ada4b9329d670e38970e7abc937463e522887d777934895be0cfbf13d213b3b737a5f6cb5e7df372d346fd13faa90b0d6961372ce2f32ec379e5e50e7ed8a13942cd9d000000000000000000000000000000000d90bd38049f2a8de869d8a748c9ff3120542f38fca6e8d5fbbff86baaabf0f19dbf449cf23c043dfea322d99837f7110000000000000000000000000000000000ede89c8bb8299726ec685765f10167c5b844e427d3c15da6ec2c1d97de174819d52caa96d5cc938e93dd09bbd1e0d813a5fa1674c20c97d08608d200f3f7611010e6a25a790853ed4ba0c5aacf111b0000000000000000000000000000000019e1e2706e878e60bf6fada47a4d4028750cb27749bcf8fff531ec75d1ff9b3a1b5e0bf19e2758899c3d8bc96a18a0540000000000000000000000000000000004b5f00109eb4832ffc9108740f0728ac059c613654a771beaaa028fef06b6cadb9dd182cc573d7ada1dcaf307a8bca4ace10870acf190b373c19ce615e20e5cb96d3c6be3ec155f2b29825f8476b77400000000000000000000000000000000013844937de287b98db2b9631d8e36bc36ded8bbb3ebb2005ea5ab39a4844fa354b62feb7433b8fd3e72aa89ac8e4ff50000000000000000000000000000000005603183a5fb09ffcf6faabcb5042328496f8b0f83e8fe9031f9dddfefef43ee4525d1afe859177d4b9f966599005bdb8d9e38d9383f09cf0f8a8077f1d1dba091ff0abdf7e77c3b65c2df48d6c6f5360000000000000000000000000000000008ad6b2bb88897a2e53d4fb9910b6244faaa045ef32a2fd223adbe6e0b1a5c1683dca69c0e9515dccf7e4589f1e69bff0000000000000000000000000000000013564245d53366d8468b51f88becc288b695879a70c3c753933092904b9fa5e64e39be30edf1f5e9de7eb29c4b3cdfebabeffecf9b404c6bb2e2d0c78fbb8609a38e3d3187587c3848e8f9781b7e9f440000000000000000000000000000000003b587bba9173011da620ff930befccb7b43093052636d6632fb6e9b59b8d127ffa0b7829b59873ae347eccf0e6c86c5000000000000000000000000000000000363be6dee6dd9a1271b24ff84c6557adc62738805b31714c9f7208c320aff220c02b222b96c62af96f1eb42b5299a63adfe53846c0038203d8b8df0cb636aec7d4ed7f78b0b0c1734be448bace08f340000000000000000000000000000000009b403c5fe094f6ec4e4b9b7d098c3ca6fcd838e46a885506ebe8cb3d8b29849a8f3d8f9550f6d33315e69f6c1a6654a000000000000000000000000000000000714a7aee8bd6d754b9bf0292be50836e13ae886f7952c61afb1b45a02a2c378d6d22eb3eb882206a3141e43658a068c06e9d4e41b628be51690b86aa8938db066c052f3adff774d35eee1e332312d3f00000000000000000000000000000000115f7928ee8b8e47af2739dd70bbccbbd8c4c4f9b92868b981e407887b448745514b67164df86126a7aa53af9ea7a0ab000000000000000000000000000000000772b21e2bdc688f0b883a2ec5accd48a13ff3917d1c5ca8896faffca7e4097021ae3c348bfc2e8174db93e079979967b3d349b1546a8c235d60c41408c969a0fd42425f8b5ddc1fa5102d2821bde2c60000000000000000000000000000000011bbf90f59d646617a6d074f5938f64232550e189c6d8105bcb67a3607e13b4668701f64933de602e5daf7b0f4f50c8300000000000000000000000000000000153ff6cb6a6dc6b6ec086e2ea8122d23e2c6abb8d59c7535fcbdfa721ba505d7e9113cfac69e1d81611c72e872071bdd29b83950e79750e9827ed92856e4d1e1b5f0b47c6bbf3611a1fef8f2fc47659c000000000000000000000000000000001897421ca9a740a1f03d67ed31b3922d7f6067287b4addef6689303571b49bae574c343e967dc0f270aa4f91381609520000000000000000000000000000000007ab14771a4e256ec4009aa03af8caedbec4b3ab21d6499041ec58afe17175a656a7600c4bdac42c92efc9d2d21b48bb6b5ac07fb4a184dfed685b93d2265cebd02a3296a3b0416cc6a115242079752e0000000000000000000000000000000005e4061b14fa76d4c02d77adc7e07881dbcb023dca9dbfd1301cb3252410d54db87816a6403d18c2ea8c18027674133600000000000000000000000000000000079d3ca06d0878a569a3984858cac6daf967bacb3fd540187e47dc2c0790d6cfffd1ae1f377c75910f0b9a17d2cde2bb3a7a25ad9f02bf51fd73550ccde12374d9b151f2f6fe535bfaa43efc391f7897000000000000000000000000000000000e2814ce8e1011c37f6f7c38ee9543c65d0d40282793dec81b195b2d4f4b55f2d2b68416eedc6aba6e31b2234c3f08b90000000000000000000000000000000006ddeccda49ae15e5574bce201589758d7ab8baaf1348c30111e997154b6ba413c03e939e288fd95d808017387f1882947944c8c814f143f746175ba0b2d75e2ae73730a265d869763f0e986c088bfcd000000000000000000000000000000000b78dc15a4f413ea9c8b347cd82c278cec530a28d239694d051812c4af08b5be888064f54d2fa2278ca4734549cdd41b000000000000000000000000000000000a8c5ecc1541fd79771037e247357599146fc46b852536529b841bf4b21978a85dd09c01baf8878bc2b6bd8e36bb93c030f33b187df3516866f259ff959d57fa9c53323d5c851fdabb96e5ea470518ac00000000000000000000000000000000172140620e46db480b2a9f1b7f9d0b374c0fa19145e3349906aba351686e0b75305db408fca3465fd263d06157ea471d000000000000000000000000000000000c20ddfb4502ad34e0934812913e222fd9aa201b9e10b4af688031d2202663e9c044cf3374ede037ef0c7aaa82428ccc4da8401050f30459e026a207ca631f0684a10813c64ee86dbdf06b7b29cd97860000000000000000000000000000000009d75caf6ffb593ff15d5635502abd9ef88675210aaf98a73bfea25888c90b63de14501459a038f07ca502b2b0eb98ea00000000000000000000000000000000091c4826870da1d2d7da43fabda1311384f24bc6d7693ab92f59cb76a06ea129911abdc22addd72181c3ecaa15dffc884d940555d48649f30026f70450b2caf2b8f7148b28bfd4349458ae89c323512e0000000000000000000000000000000011e977de99564d61c5e0d1654ceca0d0d63dc09a6dadf6baac980bbb97f38513459b391e40c09329d22be015fcdafa6700000000000000000000000000000000119164ddb3240c59428f11ef8c7e0469d219a591b926296f394048dd59a62a21ee2dbcca55f79df5cac6b784a2e06bc5e140e30424d2cccc91be1fd3a62d9ee49c9d64fa062d9350b3fa567ec21bb06b", "Expected": "00000000000000000000000000000000073edf80ee80c7d1675d05f8bed28da759098f44730bcde3ca1a9a8e286ff1791fbf22bc36de06d88b20f7f1422dbe38000000000000000000000000000000000d52fe400f41b902f8801063c0f3e793bf643c027676e0a1ad3860e5455bdde58d988b929582823e5d7ee0af8987c551", "Name": "matter_g1_multiexp_29", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004663e332c105837eebfb9ecaf524a8f7f4d651f3eeae6909824eaaa6250c9f7fc212f98c6b3d4c08c5198477f240a8300000000000000000000000000000000057144a8578437c9a10a7801fb179e417e9bbe1b85e9dd8e2208943978cdd77a8345d682ba83950e174c6cd39c9eb936a57b2c351a7946a20cbae1fd789ecc5f77376b09e911749831e9b5680185b1530000000000000000000000000000000017c44ab586ecd185de616da02f99ee799487b32baf2470871865baa2b2e3ca20f61e6c82d741853b71c5578199d46afb000000000000000000000000000000000c77154ab5f0ba817b30672367bf1e19f9e53a95d7fcc4565f82f604a07d5eedba2182cf1bcca2371af4d1bd09146cb98fbff9f8ac4ad10718d46a857ba28f182263bf2d13c8b6a00902af737dea56160000000000000000000000000000000002df334ee40a5aa144d3727ec6c19d8dac476c01935e7ddbfc164112e35cca9180ffdae5e56f1fb31741c327b5733d6b0000000000000000000000000000000006c1721530a765ce427eacc4e5679c42591d5d1443f0a1bca8a87dd19d6a33b731db6561c50a35511735324c5f402858b061de16f4f609c6947733b58c6444fa9549721fd9a2459652e8e4b8c69b5d6100000000000000000000000000000000016682e225b46618ff794f2da02a82e40193289c9df4ed6985b4daca3e9ce9ac6e8ce84a3fd6776119ae1a2e84f62e73000000000000000000000000000000000e383f55e44fa8528e80fdf391f2804f7b7f3367e0db07b78647e9ceeba5fb151a5b867bafb2d9c07a6a572ee71c2714355ed5b57b28451ad98fbacd5ae87551b7304e4ef5cf7b7dc443a66432406f9a00000000000000000000000000000000176de8a3ee21e803ec6fd42f7f297daeaf1541c08c5c359e286ba65b78d7c31a0a630a2c73d2e886cfcb289783f30cf20000000000000000000000000000000010645db8d7d42e004c4f76bb2fe8b99a3177624ce0c1f465e67f3767bb57ca80ebadb12fba65bd021106e17adcd8553430b6eeb01874ff4b0fb07dc9f23d8e45455c1480eba7fb3033942214e85a77200000000000000000000000000000000006c151767d1066f9567ed86f7759a6f425a9a130a4530a2dec0913e4efe2485dd4b0105f453e90bf27cbeee5d0482af40000000000000000000000000000000019a081fb1fe2893f1919628cb8a3b332ef072971fe6ea7fbaf79d327440274a589045db5d3f06d6dc32d6bc7038c528b89a697a0e8d2cf512edd2a3c3df354eb30a3eaf697779dd9270234b367c2b5ff000000000000000000000000000000000d19d55d1fa04f886078bba50e09ece3a394f3413745785c16d17c5936941345e42e4ac50cba055d79f2d813c69e0b20000000000000000000000000000000000ba513864132f44be3056d3d3d1fe8d10b8be954e785e3d07f816875a3454fb6d44c1a6da8c9644648b46dc7d8a0b67120b72463d54ac1d8f1b3f56f0f98861768b05d5174cf1883dd8eb0410420d5620000000000000000000000000000000019cb4ac7844effff88b242db9908bd8773d91cbd8e076127493c548350bb9f8230d57a3e9c4e4b212e5686bee925d80a00000000000000000000000000000000021e94fbe9881b2f5ce2e8d777a33336fa21c24818cc1b6b699f0bf5cf1f22d7b9fe85be05d09509b88391f78eadf14e3de7997113708f9d092836c2b0b59abf710d8401baea6de73ee0689436f035fe000000000000000000000000000000000c6429ad7548acf43bd9e7fd9ccbb09b5b9b4474937bcca985a2d00c62cc8b72e07e725a5d447e2a92a6bb9fff0c50c100000000000000000000000000000000135ae562ac2225bdfcbed36817c8deadf892da1f8982f4bf53271320bb4e702022128dfbf9e48fc6623648878020c1a67fc3d0560432dbb721f8a0610f0db31dfdfea8cd5ebe8da3fe3b8ac5358dd4400000000000000000000000000000000004a813c60a1988f7983f6ac644a66369153319e3bceda90fcef6fdf3e53ceb04b2c5d240cc65aaeb2530e8931f1a962b00000000000000000000000000000000141411938210cef5576dacba6d521bc46b13ce9c1f2a9aa41a0e9b56639995b69b6198f2a406ca5e471cb0a48233985ff0b271f02031a126f8632e30d8b17cc5b57de7b8b873e0971ff392d4246a40f400000000000000000000000000000000041855bc5957b8649451b7d91ef58fe8e0770b113ea3009815e60cb36c9b7ab797b4448d3747fa9b64b7fb50af906b6d00000000000000000000000000000000048f78b763a88fb7122e117ea4946a631be83b5ae456f0c77a16f3f2b546802bea7117eb27e23a5db65d616966bf2630f8b5c136aa5e2d670edcfb5bee9ff6095d85a332ad55763fe1e5e8babd145c070000000000000000000000000000000003ca70d52cbfe2c097c17bd300f4baba1d03951c6dae613bfbbd53f68598a71d80a285af1a16365b5b82991599ae8fd0000000000000000000000000000000000ff454d717d8518415f23ced167ad7ad1ec76c437e29fef81b5604e8bc628b320fa39c192f32aa6201c2b5b4035cfddc285193e7c10646a4601787edfad3d76e19d5b013a0a954873d92bd5293d3258200000000000000000000000000000000098363ac967c6800b28c28afe92c1379574ec11e0585a0319273aaa6b92322563ad56144437569f3b9cd70ba9e7f9e030000000000000000000000000000000006e4aa226ef031c07150bb231046f36b8ced6b795b3e3f25f707435abc214f14e0c420c699f9c880e8d647ba85d467ef35bb2175fff61894ccbb69d90375df627e925f1ac430a349e75580dd39546e440000000000000000000000000000000001ced5366374fd923b3196d8f6e35900b80d01eeaa6ac41bf7d05d1fb7d47810eb8cd2d1ab793126edbe863be4c1224200000000000000000000000000000000010b27a94ae8413494e0560a10ac71554ff502be7e86cd9760b0d4ea7d1df926cf7ff1661b7902fb93ebcfd1542619caa25856e5fb9547c48d41783bf2cd13493a1fd71e56b9c7e62af84a1f6cdae1c800000000000000000000000000000000120ffc413256888669dce253043ace9a8c924f2996d73ef3a64d76d88dab415c870071a22b97da222361dc02d91cb25e000000000000000000000000000000000940f2259f4fadc3bfbed20ed2b80bdd86f30a846d6167661339e15548f6e57030fcd0be99496fa406a2d025077a4a4e1155c0b9c4185025310e8020eb52abb6f2f1780da15e4ba81f3c9a88ed1b4a640000000000000000000000000000000003ea26434b5bc703c242cc5e84e17be5c7777758f0b232feccef6d200db9a03f10df46cf0eead48064f8dbbccccc3369000000000000000000000000000000000649df5d665a64565079201123e954e78f07177739d082c2bd0aabddcc13f9fec6ef082a1348a369e446b82181e52aadc5610b2707ce84ce67e82d5c0e5f5cd2c90925aefc1e39468ca86475012df045", "Expected": "00000000000000000000000000000000110fac33d46271daf3924995a4798b3f62c79562d3b44f736b91add9f2af779a614d4b12a9c0d7c60bcb1f104b35474c000000000000000000000000000000001592121fbb147085613d1b647cb0e4a7b895bfd4e5391b45bcb287975bbf0e5218078d3e88f8383a506550ae07c9d167", "Name": "matter_g1_multiexp_30", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000033f3c31337bc48622d27a9a3224a2acdb5c538a59b497a4a85840c81cff667ed0a0e4e3f4bb23a9ae53c1e79ea54cbb000000000000000000000000000000000cf0dc22af4530260cde26aa0eedc83a0ec3ae87d024e6907f3d22070e1054b3d4f24d5ace7218ed44763af6ec3f25ee32fac970e52778cc90396a5ba92ab98e26499eb1ff17d4bc4c1f78b64887d3f1000000000000000000000000000000000935dce5baf85335575af5a6801b36647727c3e28f224cf25227bfaa52fd646d6fdf0f24466631a93506a58b5f2df9b70000000000000000000000000000000007e032c51e2d9aa53a3120e5777a14963af8a9fc65dadf5da779c5ade6aa043ff496cf4f33e2672dc5e10c4a06dad86a6583bac9672a77f2fe62bea4364aacf62d5e10eb3a757fa0595a81f76543e86300000000000000000000000000000000178e7b4d05c4b7762b474649b38a5ce999c67ea677fee77115ce7e55207d87a82b6d05516ab41c2bac294fc382c0e12400000000000000000000000000000000126e5aef1a9729c73278b805cf102934239d1f706bb3fc3a81f3726feb4b3d2fd8de69fff2f20d5e5217edabb645e8df5a8e1d77c9e42a187054c938a8a5b4bafa834021b727036ed3941b1c1deb9d030000000000000000000000000000000014760b82d3b4949c67d38c6d9172e12bacd52ed49f442d781aeccb7c0444407629e3b7d5d5e1be996940966785940e46000000000000000000000000000000000aa2d6391e40e50ab9ece25786a42e8dc657e9112683279b143be5665bca43746244c27352d3600dc62c2c1c7776924339c02150e4e89b25563985c7802c0c43d00c721d521b54e767c1f509f584bf2b0000000000000000000000000000000003f7c65aeca3fe6e67c91e1f284be35149276a9d9c0c1907010d8ce26d5c88f2a68b632530a31e41388cfc97529485f40000000000000000000000000000000012b9322902ed50ae50e3bb3e07eddec3245df27f193fa88a7685795990a5fecfa4be4b5bf8b0702897cfa369d614eb942196ec0e9d2f572856217521fcc5e2869f16d5ec5fe76f7d350698f55ff0c5650000000000000000000000000000000013995f89bc17b99384e389c9a768fa4bc37526606966a74a370c9f964cd9d3a7dff9d6be2319d2c8c9d5ac1b6f5140b20000000000000000000000000000000017b32d8800e21a4553a1a15ddbee029788f58023164e65b25086e0dbe2ee0c16e519dcc4753c322b50c24edc305cc26d8df5017c9c35604f061a7095d976d08bb3570ef8fb518cb606cd39a3060157ab0000000000000000000000000000000017601971d5328ca817108dc9899c9c3b88aeca2ac5c03f70662c9bf6bf3e06d25fa4b7150e0838c21c9b089c7102a17700000000000000000000000000000000198db85ed42c61e1137fa50c8b2a3ad2eca4e9dfde3553b8ff7ee3aa6389d73c80d500c883e52be5cb9fe8f828bba84f7b82e7e565f8a521d1a9d0ecafc029f76b70042e1ec36c20e3789b49c7e50ef0000000000000000000000000000000000c830262d029435b1b857e7e3cd118e8a6825e3e413f5a5f67b37da686f442577c0beca3e86c13ef6924472305ab54b10000000000000000000000000000000003d35dcd36ea7352d453041e821dea655422ae01a50731698af020234e3ddd38140c24ba2af296a964f4f5896bc0af8c8260c1b7a249ba215f0dc127a41876f858b20f4422140bb7695c8f98e4c474d00000000000000000000000000000000009830bb211c58fdb25fb97a4ba226ab03516911e7b7d98f25b94c827774592b5d5c56edfe3c3040454def1429f81c4fb0000000000000000000000000000000003f34873ad16852f435cec18f977db00f786b7860c580ae0dcff8f03a8a1edbb417f01e0dbeaf035b6f60b733f38a564cd68d2b074d038ee0d9887168dc16805ed55df26329a4c0e062c2124a6e50667000000000000000000000000000000001718cef19fe02a179385ba031f23d28e20e7f57ee82db31e632cc3530d17291e54e8a01564963835c724056c53f9853b0000000000000000000000000000000016c44ed6c85628341789e80e1d95a10399b6ac126319bba3c66bdfe6a40f2b06b721a0867c30be1356656cd36e6370aa2a40c2e796148ed1c539b0584b90cb386844fdcde5d3766cbfb1d1b58626fcd10000000000000000000000000000000011267a6e9adc4b547ea0f42ff6cc9b35a40c3cdfd7ea3c4169fe1efdf533341969cc591f26fe9a48a44e544c515339310000000000000000000000000000000013d878f761efaacf28677577c93d825336698772044266d469b934332412bde9ad5deeee4c1f534a9fd89e799584d3394a1e176fb26983e549aefff9aeb220f50e071222073422dc2c44abd85528ee280000000000000000000000000000000004ca71357762ac2e9bc1f53919ee2c19d071fbd3918f5948f32ecc78be1e65672d12afb4d4a8df41a038bd5448bb0a04000000000000000000000000000000000b80b54ce782afbdad1cfbd57a852f629c0452346d5b898062a8abf12c73bf79296564d3fdb867ddd81156697a00f03ba62e07bb97ca3805ba2d30f39f44e70a7b2917889c26b84bac8f9739bdf764090000000000000000000000000000000009cc641fda19b0e33065a35e74a7ac28ca1bd3bb8a7fd350244ad0cd5dc89d91e7b2865e78ba24e112589e298e6c5cb40000000000000000000000000000000009c3ce4324dacb1e2ca82f4ce6a7ed1292f204f4f7b2c5e0086843546c5c00d16be4e7bd9c979ecd3af590b40b0d70a4a14278fe7a08174660c08323de272b2110047a1d1d8bd0e3c7d76dde030e00a60000000000000000000000000000000016ed972bad2d24d80332c4aeb1dc012ae4fc30a11597df1ca73114945c20e337d1c424e636d403141c737103a4dc02470000000000000000000000000000000009ab2d22c0161247a3c4eee341027a97009ea95bfd45fd186e15feaaabcfc09fd39dfeddb2d3631b943958620555fed81f516ab5b36a59e6300a54d17363ffebba35fa0c64cadb21e541af5078545b40000000000000000000000000000000001721e0fe2ebc0be63df10f4b9db3faa5c5fc3ada0bfea176c4fcd1cbb696779c03602cbcc1da3917dfc09af72fa3cee200000000000000000000000000000000192e3e3b5b9b087aba72b852319c200451a4976a4e7cd817eec04c007c8a2f800fe0bf7834d22a21c1989ad8c6ef73973bcdb23f9568e409271b5f907fd64b0cd81939a52a6db38fd8d95de76213f7b5000000000000000000000000000000000159c5a01e76ee666e8e22aafc77e27705a633bd3d1dbaca92117e4b80f917a3bfe80b36d3fc7721ed2fb8434558c780000000000000000000000000000000000c8c356e19c759e1eaacab45b4fd2e0b42dadf6aa2ee8c051b8ef4de0c4e583fadfd86ff6bbfca1eed42a29afa470c8c1b716b02b3e94600867e019be166f4532d264e0aa65d723dc0e117aded59245d", "Expected": "0000000000000000000000000000000010f2b9ae629ef12f213e6408c94601482c4c3cd0ee33e3418c86f0b8092d1a1ab7d2600140f6e1231297c3bee4a48a9400000000000000000000000000000000018446e6fc72ffb3c6c25d6aee2d9a8bfafec7b4f63dd3f98fde09c088876c7f4d30cc0ee31985526712228766ad91d9", "Name": "matter_g1_multiexp_31", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000de77471af6d857548f26f2ccea9c33f50db361c59b097fa481887b5a5deb4fcbaa25ec1008b131fedd3711d4d3ba029000000000000000000000000000000001037ee7b2005032974767d672e14be86177621db0ad5d7df5faa966b0e7db6319ead334358142feb370f60cec698f3d1bcfdf0495e49dbb8a8f9a0dc517351f39a6d823dcd42715f329dc78400bd74fc0000000000000000000000000000000000ae57db1c0d1575c49f8b049667e1c8ba0ca863fa56ee58a34ac1ae780c92418ec50294b666a0f99e0efcb2686a4d27000000000000000000000000000000000aa08900fcc4f9b551229b7a8a59aa9b337100c68703ef60597f6acaaa7c1ce910e643549dd0c328a7fa17e44b68de1cf095238bcee61ec1317c0f98ad4f8f9b39c5940cf37a8a3a676787d9dda994380000000000000000000000000000000016cf186f3a0ee77c7e990ec0784d99510320114793fd7a672d5f739e9b0f1186faaa9d5914860d66173696c603173b3000000000000000000000000000000000124f5c20e988b460c261d274251841cadf5c99a12c9ae8b4b3baa7fea8b592192dac3506860b15289df704cdba1dfdbfe45a6d64cac817cd479a501c77b6720c6777c6026dbee471b490fee9f242a67000000000000000000000000000000000166434c1551befa708de9201c02cfe18020d18ed881ac4d154f5e560995f302b57b1694740f76232307ec0ff729b2709000000000000000000000000000000000a961fa3c19068590b4c252c0429414ef393ee071b02a4ef15f6a5c722a73d145c8e058ebe1997058b38ce7961860da954868215022673de608cb43a3cb74ef2073ffff34c54fbb43f19b22a02bcc2ad000000000000000000000000000000001618c78e4962162f253729c4cbe326e7ea7dfd6d5cdac1b17353135485d434fe7c4d857df673793e9d12ee65dcad4bb50000000000000000000000000000000016921790d30423d878255c44966b316f9c29dde6695d66a97139fbc6fba9c4df9e291c308effc424e5e2134680846fc37068c3ba82e52fce0223a9f28c1d42681c7863c94797d1786c1adbc3e6d10dbb00000000000000000000000000000000128a8a8584726a4aa2cab71853f843f49efa79071a8ed0a6ed2c7913fbb85e254184d457163fe647d0ad719d04e6857100000000000000000000000000000000158d36271e87ac2879fdd3f1fe8ff306126adb340ed93406951e372a7f7f3deb1c347ccf598f2e007d92f502038bd4960042b8005283c7b91ef4b3ff7e20a91349c8c3d1301c9b54b901e8348a7d186e00000000000000000000000000000000047e63ded02c49b7126a1023f1ed4a0af20c2d5e95718f474e4171c0fa888d7fb53b6a2bfcd47893aef6657f31071167000000000000000000000000000000001404e16f51ea45098d5bfa00ece3df841a3a6630bff2b02a8063ff9af5c3f149e504f04e1fc9d9bf35324569e8b2e1730a3eb64ce8fe140d94956b0685f91a5462dba1a90093e803dc617559a66d20da000000000000000000000000000000001866eb045ddc4e29fa612a31a34355ecaaa8482cd0885bbfbc5cc0b3870a86a2b4c3f15da23638dc03619cae6b721f1800000000000000000000000000000000086aeb6a413db889a86bb3fe036486b4e26dd614aabf575f8d63614a300df8a528c9f6d47d59daad59d840f591063b22ec88ed0eac8d0f2f618530e91cdb9ea36b8d56c1001a6792a09e11ff65fc02aa0000000000000000000000000000000001765c386f85f7282251b6054f03a3941d44f9a8ea2814a49f75519f9fc985133937e2c9e06b59441a6d9a95c806d6b10000000000000000000000000000000011db74b6bd144f9a0d48185a3e9f4adbc79131764b6e82f11823f1bec92245a55d82e6d949f3378ea6605ec84f0613285f03e53ff983fe4886a3dfc03a353fb77927d7a0d1998a1c55ca7421a4bdac6f000000000000000000000000000000000bc9a01aee9eb527491f7334959b0f4275492afa38044f0e6dd222a3704f440b5ae2120e8e2798179634c65f3d674413000000000000000000000000000000000ff19f94b6802a4788c4fd84f66b9be03fb1417544d56d0e473caae0f9b9124c622e6298624fa1d53886fb5ba8b470fdcc1b04dc356bd348211ccc4c50d12cb382660a4f9526539c2a0c52b021ed2165000000000000000000000000000000000df5ceaa6ca501d1869b51f035c19c0f3f9db39c739f882a380930cbde7737790b25a2c01e65ed477755c2beb16e97f300000000000000000000000000000000148458f4ff4fcf8559b9f8a2ee4e486febff21d91fe4bc3c77988007cf700186894f1c1fa18ee3c4595a462712750d3097b584ee05c27d45390aba36772ed49d571837567e95f1fd3ba3fc1ba591672700000000000000000000000000000000029b16c9578701febf6662da833091deee23e647a15f16895fc057a37c153fa738efb1742c4bfcf27eda953a07aa01c3000000000000000000000000000000000196d74cfb1e6472b7ab67a664a7c46ad0377c2b465e12d94b035b4b79c7e358475339e09690557e4b280cc84391eb84752542cd551cafc5d50852526ba0a23d274317e1e4a6e75c0d19319e5853b8b6000000000000000000000000000000000e005ebdde060ed0233d1b1d6344b8d21f8cc1ceb6d4fcca389303e1c44c5964a4521dac8ce225e2e4909c4b2a47f622000000000000000000000000000000000fb3185aca9683a81d41a17b3a6048e75549d589354d4652756a4663cb25b9fbca1bcb9158e2ed73765d03be4e2b570f2f76a0fa585828f79553fbf3baac6a2776b782de66dedd6b734f9342e734ee300000000000000000000000000000000004df18eeff223e3a255e6652c3d14a6dad17c76e0597b43a6679a85f78d4bbaac1e2fc0ccf6a89149dc18045169345860000000000000000000000000000000019d60ee8b23308fdcfbb26ed30fda1dda5c6841b46fcd902e6c34dd268fdb1426e215d21bf650a340b284d5c7516efd3f638e6a70917c89811851109296a7225f9c7c5b3d7fe6d6ba6c7d1ee77db44580000000000000000000000000000000006b084e91066f299e44a0c37cf65c30009006ddda34d4151b0c18a5545d67f2bc76df0bf9a78fd2b771795c8d041655d000000000000000000000000000000000262ba1d9dbb009f779e2a584ed313d78e4ac69a811e071c10e21027138234a32deceab16a33767fdc4a78062cd23ec71c4ac944341dc68fee586d221db2a8167e833f18f012afa7c3844def6dfb26bc0000000000000000000000000000000009aafc73979c000236c08e089828880f54645b5ff4c1dcfea0ff41ffe8e3fce8ba0dbcebf0d4205bb6616a737b6d3542000000000000000000000000000000001399a2072604d50f92ee186924ce32c4e887803dc258b7495aa2f3d2187571045db7f360d2614b198f83bc8024b06559b0eedaee9347b10ab7b346fbc16c10cc9db486f561f88b756c269ebbba23a7f4", "Expected": "000000000000000000000000000000000365ffdbc48aabd8f0e786634b9a853cb8312bf295543bd280c1a0a9f7d0f8ba95b3aebe31987ffab1f69a504edeac2400000000000000000000000000000000150af5ab7e9b1bc60cda3ceeada36abf9bb43f1182659d8d72281c1f1cdba73fe7d6e52abaa7506b89ef43f092f25bba", "Name": "matter_g1_multiexp_32", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000012a651f467e9a1c1cc99c82e16cab2cef53b77268d968dcc73c5008e103d2e4d19aef4cdffa24b9474fcb393a48d6a70000000000000000000000000000000005d202cf9bc8c0124c0f817465eee7d4b1219071cfde50ce2cf8951efcc21fa19c762a1a8630eb7b8dd90cd03b8bbb0484adc8cfd2e42abc2f0e0d7e9c4b378f73731905760bfeeef01c94f8d5c3cacd00000000000000000000000000000000060650b71c97950ce5cd6b6bfdad46d66df454c5aae1ea313a70e7fc841e06f64a31edaaced17d8de56f1ee75f5263540000000000000000000000000000000018a211f44acc52e92ab5eb1ce304d80532fd4dacce60370dc62d9ffdebbf749689620798429b5ad1d8293c1967a43c12bbd5d4a15998d733326ce23cced86ec5d5b410c29ee98a4de19f2662c3933dd10000000000000000000000000000000000f51ac340d512becf5d7a515111f63123e9bc940242ba42be9f464b89847a8cca9d93360851e3d047de4ee667a6baf0000000000000000000000000000000000dd7e71b516b3752c5be5ee5f3908c17e3e019b46422f24659596a42e569ba9e8711b1e8f8329cfbb990942f258cce103717aadf16301a9c8741d65c86ad7f849101e30b7b1a344643b100a8582a6ad10000000000000000000000000000000015d542246cc0b46bbf5571c3173abfcf10ba447e5ec962b5f712ea7de3974c2873df1979c9d6432bc88d02588a3730f00000000000000000000000000000000005e1611597c12a4c7aaa25bd9ab1b6d30c58bd1fce3d87d66a03f25d6ed110c84c3e902ff5475795b5159126debf6cb522788b3597da7b9b106203dd0ea97527aa8f5149754bbb0c10bb6eca8a46d9400000000000000000000000000000000018f565b38ce775e6b40581f757935efca255311b872fea3bfafa0662620ad5a02a7e8ce48c17daf45668c95ab0487c4e0000000000000000000000000000000010686971b402783c1e7d60126cf484fd01b871944179adc4b28de5d72e5b8823b48d382a8b69f6b4681c74961ca2a3843c21276fc1371060c226424eb9886de6897b15b075fc5a51aab4710e9dddd3840000000000000000000000000000000008d42e31cb4c514e450f56488208444481db0beb5807c6f1c2d82ee09c9413cd6726dccd72e0b8ab6f6ce6492921b14f0000000000000000000000000000000012143ca6dcc3bc9edb5b10c3a47a5130e393986dc5e83d1eb61d9b193ca28193101eadf00916a3cdcf7b6c1369b17038ccbce4e92cf377f67244995badc72db0b80fe37c9b7d443595156fa41abea17a00000000000000000000000000000000101eb8b48df43c3e01c1508aa9d3dbfe168e7458cef2ff61c15d5b4e8dd11be6b9a76966c01682fb07368f22362f355a0000000000000000000000000000000000babbb820a5a8e0bbbae1e2455d54b97f6771ff914fe33a007734d5072a993df31c6a2726c8b03a8c2dcf48a73959a8ff79345f31c107841ae388f6cf116d10bc696aec4933de56bb9affe7e20c649f0000000000000000000000000000000002fe8c461de25f5e6c5a082fbc4ecab5a37dbba9255ebaa0b5d245735edd27550968c2558ed24f7bee99092228e37c8a0000000000000000000000000000000012513b2fb62725aaf948403c13f11a6d7461c70cce3e4f912c8d2cc9f2a8676d9bb37face3770e7c0121bad6af6302d121cf773387d5351aeab99971eaa3b207fa6a318ad60f1c3e16b7f68251f9c91000000000000000000000000000000000175c93838001f4c67a3e0e5dd7eded26a8818b2e492eab2e0e6f8b421e3d3611561c8b933010a3c5ff96128631f4e88700000000000000000000000000000000136292092a366a73a5609cb1e7fa403c59825e99c8c91a37b289ed779c4a3db71370a4bda2cf8509cc9d4b4731b4f52d2d69cfed6bb2d33fedcbd215dd4e9632a3cf86a4b2716406305f6a85e6090a05000000000000000000000000000000000d03e1d6dc4bf59262fe3bc3e163565110b751c534e57c621b4be59bac28d6e8bb379cd4afa3740797dadf32194fde310000000000000000000000000000000014ee46a0cf13e795c8a46399ae63e1b812f237eea725539265e13d3ad1a663374dd566df450fc1191512ba978736e5b779cabae288f8a9a8cd54523c20825b8fb07886bbf0ba0c5c807956f268af4fa10000000000000000000000000000000003cefffd8fa01842c36dd9fe1c57efef3278eebe5d1020582c3d13ced75d24177127da37eb59e9b46b4a0a19421a5aef0000000000000000000000000000000016c258ffb2edb299fcc04ad309ee5d8a8f186db5f3af8011d42b22b23687c2e814e2a8d366f3cc61d7c89bd9619523b31973977d8e8c592f9063c5a14a658990f9c3405643089eb58324cd3f05b5b5e400000000000000000000000000000000097b6535843436f879ce659b6ac9563d81ac0262b9a861bbb367bf8244a35a5de51f3060d05cb2174cb41c8c3dbd8dfb0000000000000000000000000000000012dc9607e0ebf73e3577ba1ab39437b03215e366cf1ecffeae4ad4c7919a63f62e45103db65de4c9e3281d7604b07f24a610bfd375a7b8d0b034c17c8fa27d4366b06c681131fa7daaeeeb08e25c2ca60000000000000000000000000000000004479ec5d5ba2f1c661df8e4f85320d0e754372e0c463098b0ad7477f7373f309c674dfd31c7f08cccbbf4bbd17c23d7000000000000000000000000000000000470cabd9f5c4bb8b1a370888d8f0f486387a89efb92912072fb0907a1e64f3327e9beaddeaff44c502414632243d6fb99ffe1dc2d7526338462860501d75380a5ed9d53e675125342afb6652a97437b00000000000000000000000000000000038101da3c35dff20a878300bcf69e393b77873a971838581daa9d096b00bd6fec3dceca882a02d397a90c816fb415a4000000000000000000000000000000001184246344c03be6103acd745b3ed37d8f67ebf0caecb00cb2528e0da9aa3f352a4677dd6b832c042d6e1235da7521fbfdd97465982b58e69993711a6a64134bc4e76b88ba1948af91ba3339e9b9d3e90000000000000000000000000000000000cf99121ecf9b02cbd006348b16f9d80f64ae3c946c4802ec6bc056bf6e95e01b80cf3fd10ab1d30260a402b7c46f880000000000000000000000000000000015f35fe1ec8c258095394ab2b021d63ce54ed4bfe14cc5666f5ea4d5a0461d535b8bce3263913c1b4e6db6996cdc037d786a2a3974c84752b32f29707805c71992d5d473f4b7bc1f0757d126607a1c07000000000000000000000000000000000e83f4b1d3eb8d45ec0fd9a4ef001e5bfdcfb9c99a6d1dd4b4e8043b4d11f5c6fd65296a33c7fd26a4e30dbbe1869090000000000000000000000000000000001197b11d6747280b37769946549ad9d4a1ff1006ac726d7cd322cdb4e3cf86906c7ed371e770fd95ab4fbaa1b7b514d985d33a7fbe6ac6eb42eb932dfbbca2f771ffad5e80fde686e5df9d34e9f83ad6", "Expected": "0000000000000000000000000000000012f496f031f5c1b594256e272520ab98f3733fc9c481e7ec8de8ba70f493065eb25b681a3959994d37aec979c22c6c3b00000000000000000000000000000000015dbaf471eeef9307d8dccceaee179d8c9072b052af66fbf049ad1d346e08bb555238a763e903541fc72d9edc30ec30", "Name": "matter_g1_multiexp_33", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b632afb8deb955e64fb4ff5aac396152e23b11a3f326df0d77b3ec078934cfd5e486244aebb44cbd1599f594991a26d000000000000000000000000000000000519f9de5a5b1623e4524be68b5ba0f997addb4da78adcc9c3d5910009a261fdf8b0efbb6e2a085e74112ac4e2106ef319582dfd9cb80d44c17c5f62360e62f6736d186194f0f8483e34d8d18d832d370000000000000000000000000000000005456d9312825dcfe5501b2c38aa610a767bd38f46cdc8acd92f0c8206a9c2f9b8f65c8baedffdec5e69f03fd3adc4c40000000000000000000000000000000009b2dab21ba4e4b4c284a623994b92ed5fff0fc198bd154fcfac9abe5f05b830066b44894ac6f92bb2f61bc88a7867a8ac0bd9b8746fd02aa70d8b8a2b5d3be46baecf9449d8cd3d620cf9efb3c615d10000000000000000000000000000000009f55a987011dcfc796df284c7bd758c3024d4f09edb3884dc087de26fc1df0f71067d44fde07fab9334971b4a0bace000000000000000000000000000000000003a4ee3e9ac2632cc81cbd4ba397d44f738ee390a4af6ecd65079f412bdd8c4a37d5413d0d9a7dbeda8a1267d6d843b069d889881d5bb87dd65a9a02a7fe239bdb55ee54a6310bc987e7c5772404d7d00000000000000000000000000000000173c7db310b54a4a720074dee01dc0e5f84b606c9c3ea0962bd4610b569f478d7a5221feaa944054cf7395e578d730d8000000000000000000000000000000001697f0e16c49b223dec9e0fa429e68dbaf96b004a561aa3e37158064ceb9232c1cd21156c053fb89ddb230deaa7f8336be658348e299bbf2438a0c013f86eeeb69a013b8004a4996189472f3372b326c000000000000000000000000000000000ab7f085b711171f999d0c4a46cc7c8cd8a429f6bd90d1b860c01066bd0d193f1c1441ae5aa97d690569807749ed69e1000000000000000000000000000000000824841eab90d56a1810c129b8f27d0068fbb7e3536d6e56cdfdd9eb553e283c5d0ab1c418869e886fafce53697520859b9d0ec92ae7df3f52a95747659f8fa3ca2cd01e8d7ef6de384111246886bafb000000000000000000000000000000000bbc8c5b5e4373e76457fa45acfd3f1151735457b0fae06e1d3e6e5dfeb35815aed44bbe6395039481ce02d2aa2c502900000000000000000000000000000000089ac22ebc582bb71a60c88638747e2243096e8d193fa1863089698fbf6805128f9e32636d6f954ff03bfb6c5bcb0060d2ffdf1237b4e03c219806f2dea745c94bf08924e1b9f11deeedf0db19da6f3f00000000000000000000000000000000001fea43c3029447965718c8e76100875acc8fb4da66f7a4f7fc5260de3844aa9e9a89ae4d9baa11c118b9f851fd63de000000000000000000000000000000000844aecf4a3ebfd8b711dfa9efaf1a57d635f46fb980903e362d4ad55d48c4289a3fb1f439e6b7d8f88cc51867d6b462cca0751c9534cee7f14d11b7c8ccbb2c537a799df59f850bb125c6362d72e9c4000000000000000000000000000000001384e33086ebe795cde3c951de9b48f3f0fa2f627524cf0c4e3691599b62d4611c6a84897298c287d162825c3f153a75000000000000000000000000000000000a04af7cc41c2d3663444c8aaabeaf70dd146dec114458b3d1dbc95cee99ba89a4c5a38f2974622292e3236fe2aede6d17f890a1120daca4a1bc1bc0fa7529f0a87b5fd6ec385f12b270bc0f1a5281b400000000000000000000000000000000158820954aaf8e6387cc0e8e528723e0875f5f719a46ae5cd9d967674815a2d9679aea9b5736f882d37e2dd26b7db17f00000000000000000000000000000000058cb933f8dbac61a22477cdb3f52c9e3de6f060dd51aada35b6f8480a53e8eec8f82800e89ccaa2d2eb1dfb4352f16561ca18257d9d989ec13d4f158b18ec17d59344f4558b6dae6c0aa0c2f37affb50000000000000000000000000000000000a7c9c1bf574503a884ecde5e921da80b299c4efe674a2d5c841e6036adaf7c1156393116c2c0b9827978d43f1e3e440000000000000000000000000000000005cf22e56bf4a46504ecedb072fe5e18096f9da550065612a1d00cf79c65384dea1bf59cb7c52de905a04f1886f36c8a0fc004ed8a135ad97cdd1bc4d0c3ccd15e65031ad7e3cc13ef2c260958bc43be0000000000000000000000000000000018e344838e2efd9363911898f27882f67454dc3b1bbc71f1d99e787bbd6a1ec9744876156ed8db2ccd826f2b4fa784050000000000000000000000000000000005528854a8568ec6491c79aae1df15d965cde683c9ea400b470105117f2bf3b41d2f958a8dea5f866a55e60fd06c1f07d8cfaa1037e2c81c6973b221dc7badf25ebe3fb4b42bbdef1124265df2c7ccc400000000000000000000000000000000047dfb6a6125ff02e12c4a9d88ebcdf8a4375367e1473f5a0d99152bf0a4055138aa9a83d98d7f74d9fb8888f643cac00000000000000000000000000000000019d0bf5162ca55d8113a97cc3255d090c6924362e6e05083fc323dafc3b12e898cd600d2730acf8cf5cdfd4420962881c25ecc5d37659ebb0c9e21ea2f8fddc518e3d8faa99627b21faf105445f69d7d000000000000000000000000000000000e132de353cb09b69ab369c616718b9cf492cdb9d3002593319a6e7b61c7d90f94808b75d8c7e3b9d7a811d01baa47a1000000000000000000000000000000000d636abffa063379e2084cfc09da5ee04d40d8e74ba0247a01be414cce820024766195520f1d2eaa90fe254e12a4d86026cbb32382902d9b1963779070d749cbc4df1e7605f840819f2c04aaf89c732f0000000000000000000000000000000013f2367ff71430cb541557f79c5ae8a0d9053d82341d83037c1f73a52585255b205706227de4e87d6ea2ca602483d2170000000000000000000000000000000011f3f4e882de30b40bc160e69fc2bf4f7c588cc83bb9dce3467accec7c47714e2b326be001a36c42ba39c7f56b72d6fc699aa549077a80ff8732b5fc9df148a90f405bccc14bf7305266836566b7a98b0000000000000000000000000000000014bcf3f26683234584d79b436cc608462f1e2c20b5ecc5019988d8e30137859a4b6d0e1135dd5bbea0781b8ed3f0653700000000000000000000000000000000090ef29bf63ca97ae8388588227e1d1a0653c43b16a35a63f2ab4f0b11fd8005d9a85d30a7406491d983f347e4dfb9f140e2de1a2901f1380a383a741d79fbb0a041da5d7bfb92edab74cd483edf9523000000000000000000000000000000001817fac61301ea6a43d7968b22616b836ecd1f20e5883e9b475c18353b066f93bd68a8274d0b6ea4480d8e314766dff7000000000000000000000000000000000c52fc676604061338bf0712fc1606dd09783a1f9a5250e3417056e3c39e59a28c7707d5225808414279ab61e49b6081062b323592118868d547e83b731d15ba2c7bdb1ee4fdf73600c2584f1db0b45d", "Expected": "0000000000000000000000000000000018410462829b3a72024468ddcbc42d59a99a70296024654f99b591ce016304537c525513defb655417ba3c0f5e614aa8000000000000000000000000000000001416a19f73407c262f5e464021eeae1d1f10c3ae5e45f132a2f402a75cfbe409651d3795e482b15d29037e2f7105255b", "Name": "matter_g1_multiexp_34", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018e6f25220e4b4011a0291424b4062930f5df45eaf1581d9591560fd77e630411e0abd57f9973d4542741de5cf3132e7000000000000000000000000000000000b31f903e7fc36327e404973b90efe5a5d2249770170ea1e58839e19d8aee99743be012b6e8a3fa73efc6bdc08be372f764ab6f4c43630d5e79e8c474d76d8973a7b7bd1c7f1a985333cf1a6be5ccff20000000000000000000000000000000005dc07fa620d476d8f64358c920a401f8b08abf739befe1c266fb307b959f37542140e398c33b082d09f9f53cedf6f810000000000000000000000000000000019d8e51a28c936b5037424a7ffa8cae75496131eeb2b2d5034e4e882c1c91f6bbabc9ce4fb2fe4be3da4eba46326a3603280f1b1e78d2339f64b5b2f2bd77aa24623b79fe2c9debab4212f4ff564983b0000000000000000000000000000000006f5f80dcfe8be87d057e2162788f7599e55b69ee8c6bb6a47c505aa324ddb5ffddacfcff35cef3dee6264ef73d6a353000000000000000000000000000000001056081108195d4d27af7332215c0b444c9f63c7574eefa81046e1d064825492e2dfc5bf2ab5847a37e6b253d9dda9fdd4d27ff9d03ab9120ac2adfeb36b070015f0e90782255ddc9111704c5fb111770000000000000000000000000000000008db431907692896f9e6e254a6eac1a0ba5f9cb84563da69c3601aff1370b7a5a98edf5a5fbab06abfb4496c777bd83f0000000000000000000000000000000018a3bc407fc42236c4429f241fa760c6513614653e8b02835480dbe1152763bc6a1a7fe076e8bb44ddc04322cc906e1ac66d5291311c7cdd1f33e5365ec0689608b3569427a8f6a9cd0b94b671472e66000000000000000000000000000000000cf32da94af97001664607c7840631a8df02a008fe262c6dc649a3eff34a42dcb98884212bf3e979629c98cbe5fc457f0000000000000000000000000000000019b3b4d82326ec1aaa3de3b2f8e329ac0243d3f6bf9356886be4033aadd0398a5c58c68510de29f92a7ca910d851da244b718a5129659250640e333f4567043ca749063e63d87efd86a9995adfd3b845000000000000000000000000000000001504d90c52af16b5f88357c87d4be7c329855ccad6f6633af0fcf4341fae54aa4b1ddc1aa22fe1ac12e9d850a05a9ffa0000000000000000000000000000000012ea642b96304316451dcece5a6bb324d197e31f56ef3f1a17c973742322d08f443b7cd156787f8291b52c0a6f78b4b1708891f45d7bee38fe382820260061e212c6cb9a8572b4d1854f3ab09409b05a000000000000000000000000000000000fc61e9589a2dd7f6dfd613225d80a70ceb977bdb518b5a16e415f887eb73fe9fa5c9130d5fc6deb4ad153c5de0907d6000000000000000000000000000000000a0fd7de87139581e9b1ab707e25c186640db92875a7822d61d8c476c40ea07bff000cbfe6975076434d0b703695740685ac0f94f300b004c7f20aafcfd9129d6c2590749504a3f08c4cc708fa30100300000000000000000000000000000000188901f19a776ebd2ddad60209f4545ca9b0a038b0b3c67b6f5e35d61f8cc2a297d51450663c4af182079d3ab6b01d2000000000000000000000000000000000151b9eaaa281acd803abd71ee4098b4ff6535e5081a33cc68ecca54eb9f1a8f94f3b1b21440f33b8648ec456dc1cf7f3fdbb634bc0f99c5795f3c4d6a0efcda7f71427f1eaa1c5411caa6cb05ee314780000000000000000000000000000000008ce8bd24052a8e1472bb64cc215974e20bb16d502b3a8113cd6e3e9a2bb7c3fccd45ff711518e8430221f40859374ba000000000000000000000000000000000aac2e8db9123be3e82905a0fe780daf4a841f6f961428b9b431c3ba2ac31e8c06118402bfc7fd15fbe3ada0ec8bbb2af5e4695c01849259fb969183de385ef30c2403e081067c2d9b6b5522c73fcf2000000000000000000000000000000000017c580f501a1c4823483ae718371432a8a69e16e42dc0b15bb8e01729b6707ec20b898e3835bba40d7e8802d9438281000000000000000000000000000000000bcc167264fb9d6c27272c2280d8e89f9655ac7e6408694a3a4ca6fd0b46d1d7e3cf608bc2ac343806c5de42ae7a99e80ea6fd588db5efc5fb2248634cca683d39d610886b59eb3077fa9612c368d7690000000000000000000000000000000017ae89082d6f531bb7905068a9c00017ba8ac8867c6e467fcd3e88e9229ba5b21ff4d0a5ce937b75b3d5dfbbe35f2e7000000000000000000000000000000000005bda8d641b782ed51c416d0ebb1cc7c8f623d49b741a7cb93b3514e71d5b9102ba2e6c768661686c2af2acedf466e4dc2060a3421c5a8336c80983c9a160345901a496c3a74fc5248fca081d099539000000000000000000000000000000000150ed2c2b2d1b0b87badd0dda44325000a6fe98d335e03f0d4d147b20d4738e1e0f0ae0ddb2783bef283684e631ff45000000000000000000000000000000000ec1fa174f3f42cdb0fb67a520da161d9a9d1e53a5b0735738580fa3e80550c95cc3a1cf67fed67dc2eee1597e469fe0e27e4afc3e6d59d0f5871b35eb83b46cf15da6c326e88dd8edf84031f58e23f900000000000000000000000000000000111f184636052719c6df1541c100d5a21d573370fa7afd18f5ddd1d86842169eeb02c494b33f2bb2f54278530729bfbe0000000000000000000000000000000016be03c9764aa34c898dcaacabd1493610f55efd36ca0b35eb48e89c7968e7a720d545b18fdb95954e01596856d42975cc7efff04f143e2d038de153861da5e04016a7eb17fbe6365de13069d088b1a100000000000000000000000000000000114fa84ccbe9552a2ce2368f1778a1fd3c67303d8036fe4ba171ba9f2f6039aec1a59fea1b8efae88c01bb50e53950440000000000000000000000000000000017a51bf70c41571f36d003c0715238b6c8fd64185f616cd9076b730ad16caf364a75fe68de246249a42cfe013606874709a2c3dbb4ee4f485dc60dfbd94a358a7c62204c021f2d7b140187ee9ffdc4ce000000000000000000000000000000001450fe1500a6fa9d966a0c905167a414d59a3f8a064089f09db047241e9abc31d9e41ef73558eed741541414731f838a0000000000000000000000000000000017e61d4092537ec48683f86b72123637df25a5fd926e5703f993678a798dbe635ea29303f8b4d9ac76231a71cf515a70d9b15c065497392e4b477a556ad620d44e671137cfd570d53590b7528f8ff680000000000000000000000000000000000e72f0c855fce66335533c05ae30031cbde78ef07571eb1b645fa3ac5f3a7d76a4d60cf078145617c5a7ccb16266bbee0000000000000000000000000000000005b3981900432b193985f28a88a72ca9958b4628e5ff9d2cf8b0b23184e2bd433d495636de3d56711f207719fdd3fd2f9e2a72eff2ec29a65b417767e7090b73c2fb530de6c8f4e4ba30543946423b12", "Expected": "00000000000000000000000000000000110feb31a1c40d570d7281ed9f0c0ac8418f4a7aeb6be3221b130945becc15bb353ea63623ec7dba2844d3f527c167e6000000000000000000000000000000000d76c7aed58945a7fe52f37eec3be7cbd4438645a649a04859a487e9e2d4c82bfc76f7ba990f825302861d82a748c8f2", "Name": "matter_g1_multiexp_35", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000030c6580a3dc73be106748d070b24d9231c382df143fb4bb8ad45e4723b40f90724b7e54510da1b2bee523a29aeb58100000000000000000000000000000000010cb3562fa1b0a3778393412994e46028367ed52dd62a1d446fa02b50acd48a784ab49141778bee5036b7d3a95c9ec217b9aa7e0bfaf135ff24720773ccd1e0a46fab6d678d91a14de137061e145fb9d000000000000000000000000000000001972db503f6d70a0b247eeac7fef277098604e54465309967b68d24ec1cece802d8c4b699eabb72e03736902d41fd5b60000000000000000000000000000000007f30233f9043927a629b11e7da48f895fce86b31911ff5c511c7b50642c296d37a3078e2e12f1adfe668731d0e6810ec6733c9bb7bd195622b96c4181e8c8837d1912fbadf77d6029f7fc44d793b4800000000000000000000000000000000011ab9fd98e42539382c85bf76b563478fae8cca90ba1beb0be56b405da8326e6f1348b94eba61fa29c78645f8eb96f8b000000000000000000000000000000000f30617240632d129ceb69de1d69a23c9bdf950819608deac0600d1d1fd730a3a6d22dcfd635b25154b5ac7e22b20c70410bb66334c677397d04f59eade9630463065cd7da3c9d50580c7d66bbaf487d0000000000000000000000000000000007556b86cbfa9f186f38fb1a8adce4c08f93f874bcb36ba61df5750c7927cec8896bf831c0150c249067ddada2e914bf0000000000000000000000000000000016ecf045f13c78de8aa18c2ddd1714bfc532ba8ff5b7851b58240cfede20f032067e943486df628995b8f3845289eb02d97a16fc5b2c70829b15f73615286eba334de1f520b5f0f6a83d2578399cc0b30000000000000000000000000000000011379452e627dbed2ef1c74eb917b95b3933b8fad8295235cdbd6a4394d9b75cd3598c930d48c2d4abbf1558c65e97490000000000000000000000000000000005e7044829ae3f9b073e4a2237de96b0a1bbec3a30dc39c839573eff77321b1e0a49d555f0e31b8aa096f83f5945026bbdbac08202bbe5df1229e99c76c1727f7789e0f8c2002f0a2c195bdfc00acb360000000000000000000000000000000015f8f0f22c1553ca663ce7e9ac00514eb53443f6c4869f985dceb118ee60a88a4826e9dc7fdbf61e77cbc93768fbfde0000000000000000000000000000000001646ecc89754ac57d7d6fe9b871692d65057f23d397a410bcb07ef3df0a3c3fad9eca515f0d0dcf0610edbdaf4cdb5d743da827b812ec6ac23b00208cbad0f2e8b3a32434aa61dde029683c34c1ab1900000000000000000000000000000000003a18dcef4939e154aa790b0ce8265f27cfff48d5fec149d91307759eaddf601c788da6ed8124764bad940f117751b0e000000000000000000000000000000001813f4650490f3839fdc9f96ef744ea93a9fd86f8a43d767259c2e0abafe308fec2bc6b9d62c1dd7b5ab1aebc19586e93c7a8f7bf434ce5e63ac9365448da8663745f66689b4b04968f9b8b1b68058930000000000000000000000000000000006490f351e78a40c0cdb827aed3869db293c7d654b43d69ad1c9b3b536b1fbac67d50a835878171974669a30ae9ad1bd00000000000000000000000000000000041816bf846528e23eb129689a87c2325f1b8edf237c530eaf578a908fa0a2604baa19d6e0b4a5801280c27285896d5a51f2e2bcfa6ebf84d3ad83c57257b9032e5d62a8663ed5d77afce00f33382bc600000000000000000000000000000000064be79c5d382c6dab72bbf28defddf14cc7cdbb23eced6bd93abed078175668d4dd66d0b3abc6384165d26bd86680f9000000000000000000000000000000000fa4c8be5d20d16bee7bd5bacc0b0086875a14a119b4888bc408850c0a099603fe3f79d334e45bdc9130132ea15a180f6d8b15ec8908bfe008414757c0c7f79b3079f9db86d91ac3ec8f38ae2c94d48b000000000000000000000000000000000182f23242108b022ecc1d156a97f1a5fea2cc2e059dcc82273212f37c312ab77886c1adc370bdcc6ee05cfec957db970000000000000000000000000000000014ceefb3ca54bfde172e0455d34f1f462208df69328782b7961ade821ab91e7b3ed5426b4065fad10cc8fc88c90d8e87f4723e85076d48389c3fb5a5df16b6bc6f7a69ca701632b1159677bd8a6f7bb10000000000000000000000000000000009339b95b043903f2a3b5926a27e57cd0c45e7955946718e7dfebb01f18e9d7a2002c670769c4674773a835311f2e58e000000000000000000000000000000000ba94f6b625c507934f633d5420654056a939c68899c41e3f337f7b927fe82191d39905b349870ba0c41c8bfc97d64a9a632938a6df169fb64daa55d2f874ef7629d5be41dfa0d50827c082333f0fca00000000000000000000000000000000007604b5eb3218140b94732a601da577da3cfebe04dc7dcd94396c1a6704a0ef5a5bbd0c31c196f2876e1a4bb7490629700000000000000000000000000000000193098ff839d38c9bbda43944d7b0a3ec9d0d6732519d4cfbec506d29801780813b2faab46658c4383b2f26c477580af283a4da7f71bde54d4b7e28b2b23e2eb05d8b025e77e15810625d71faca6d6e500000000000000000000000000000000022ca1a16df42ba543a118212a75eca13707ee01eb3ce27d3659b1fedd99b9fae859f4eaa51e9be9107704276b578a0c00000000000000000000000000000000012d60cf33701caf11be6c9e3ebbddb9c7066dec3821a2e0f9e5b94e029dfea4063bebd4b2fe18c2442311c2bddc7c08d402b71c1fc5c3f3a4ed9edc73457a27ea427f83a784796e01b7a1451b3305b00000000000000000000000000000000011d4918642919c801fff0962062a387a4dffe693ec09cd3d0286a18e3a22c84fc09e8396ca82e6054d8535cd888179230000000000000000000000000000000016a1f0c7fec5647dcce688d3e4e526749bbf23c1fcd9e9168ace47399f9198c9b3a6b8aeca68febde1b7beeea0641aa2310bc47acb3aba7eaa490ec104ed9b2985f65c7347f69fdc67b76f6f43846a990000000000000000000000000000000017203c37b21375a524bcc906843a0045229c5531ca23177dc88026e83723db21d9a8b5e52cc0be1d232818ed9abd496800000000000000000000000000000000097b4d7fdfa442dcdb64e405965439ebe70e4e71cc8e13e299fcc0b5dd88c67d6d0dfd254ab9b545e66295e2f3df14dd91b88ce9888e5dcfef70d6f960a456dbabc792571f2a98746b7d833e7fab9850000000000000000000000000000000000fc4198a87e789015a1e44935321677e84356aa9e06592f9cdbd149d13ac312980f3048dcb9bd02779a3b10fd24ec98b0000000000000000000000000000000011425345ae1139647f93fc13eea0e920c491a49998430a339cd9d4260479a427515109753e70811be4cfb3b96db5c78b3e82cc1261ac3864266379b4d518e25c05bc492a8946b38b8a64acf47aeec4b8", "Expected": "0000000000000000000000000000000011cd4c4507778871fd7b28aaf79274178df83f3e53c256dbe7a52df884d28df6a0d87d20238a15f489546a459195ace0000000000000000000000000000000000439a672492225fc09e46bb178a5d38956ae237d9f7d187d4cee14597facf2c06d7e70be5ce20e1f1389e4da6321e455", "Name": "matter_g1_multiexp_36", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003790fe37a3aa78cdeafa76bdbebfebb22ab5f1e09e4e488418568fa307a5db18f9d93126b0d3cdd6a28abe3a4648f6e00000000000000000000000000000000043244b9c78fa56c611bf72bd6a17148abe76fd0efbd25085d7b46c90318ed591c5975f79653b98440f5f7c04cae4d7ea2a1148f1ba719b2da92c418fd137efe21a44dd4cce013ab36e57d97dfed92990000000000000000000000000000000008e8fcaf6d2056c6e144295d437f7f1422f6af7a1b62e0b8073141b2992b6ba865822aa2d9fe439aa1d896b2a6d231c4000000000000000000000000000000000bc693fcd2021972914747e48c600c444bf69ca8e1386655bb5d987608d648965c754668ae0a72c2439ba0ed98e5e581fec5d6167d7777169348cf81ad3eab5153f8f2f18fb5935c5ee5e3a759f9b5af0000000000000000000000000000000004e877b9032e168650ec3502ba65118aa0a8013b995a647210c1c36a6e6c702a93caef674d03d82da1f7c5d7ddfa0d0200000000000000000000000000000000063dd22dcd667c8288ca5b172e34b4eb783403105523c0467139b814e048fa21245879a5e9188a1a87d26fba52a9f601da609e1c8fa42a993ff355a70d44dfeebc71a801daa36acd437daec5d7b645d10000000000000000000000000000000018cb2fffa3181bb665dedf1d60de6096e8c5ce43287cbd86c2df5a5d42d0129c73cd281c085fc562b7afdf52f0a680c80000000000000000000000000000000007f9884780460ea018351b4ccb5a120d44312056b96c5ba77cc38789627d20500d6b7e69dbf6ab49d6bee998a6aded67bc5f7f5d096247ababa51852724ce9ddcc6acc7ab6180beaa1cda97dba94b4ea000000000000000000000000000000000bccad9f23b4c1231eb07df139548b66714a064dbec4ac6ac43ce18671144f2bf7ed99f16442b9f6600e1122c58f52e50000000000000000000000000000000013646b3c310a4b3f279e17f45fc8104d2c9d00f698b869479a5a0e1c2131e3f3a9dce86115ccd539bbd4346261c5a75f3222b41a59f9551e91572ae00582e1e41989ff5f8e2cd1ee1a78f55c2b28ecb4000000000000000000000000000000000d02250115596126e858a63a7082a8c8f8ebe055653f5a60c855ddbbe3ed05792d08e5cc348094b8dfa4584037be597c000000000000000000000000000000000f68ec7da947cd0a57177fb91d12a820ef8574f4c524fe54b9420f9ba4944759c92d5919d6dc8030fc663c34519b64c37431e5c1fe5f8d38c759bc48e8207695a3cdf07d4c1fd02f1009088539085da1000000000000000000000000000000001960580ae965c37c2ec219dd0753749bd70ac2f0c4a3837418023c5142caf7b4dbf592554a6dd95872e018e912e3a20b000000000000000000000000000000001210b4093a07616543ac2034faa9c4a93b5f4cc3daffef2d8450b1a1770948de56c5bdbfdc9f1dc9af5e20778c1e8e6cd474e755f6ce9045baaed65c80f5a686547089e8cdf4ad2b7c2ce7c255cb5c73000000000000000000000000000000001955d93fc0f3ce0563ca4f4ffae0257297002001a3eb941cb9d3bf82b8d7f97657ad7168bd386636aaf45398745d5158000000000000000000000000000000000cc7a0babdf499322e060f2c83897fa7b6c3e7b4f56de3a18c823e0ffd87545a3dd68947df8cd8d3de5795ef7cb05391976c8775b0eaa1e4aa384d222efc476305c7ea2d625cf5c67ea4368d7a9fccd1000000000000000000000000000000000d451eb31b21eff2c18b52b882e1eac68a524e3db43f233a9d08139667cd0173e3c716f29085c599a09f19019fcf447f0000000000000000000000000000000015852c483c8545fbf0932c99b1944ac58b37228d15284c7be5f5259bb8002abd57b26c244846652a862d46016221eab19db274233c46caaa9c99690fd00fcbfa4eaaad7c41f8ae84313448c787165f6500000000000000000000000000000000044e70861dec38d2b5ac7fec042c6b931d4e0a072073333f03ec4382fe40919b29378cac920836b1641e5e2db053c5c2000000000000000000000000000000000c422a91c81a99caa32666511c0ae4decc67cd94e85260b49760ac9e97894b0eb434d39c3884aa4614360b79681403f94ac9f9ed46ae5aca33af9ba1c0fa5a2138d4ca02b962fd1d02b4636114ce1997000000000000000000000000000000000af002ec82c5ac0dc87e1ac27f4cd052eab67bda318557c70fcc2edbdc071ac4a3fcae90f73ee514cdf8a543ef59050d00000000000000000000000000000000109f720464ff2eb2978d66370041206abd9ef0c6ce79d51f7d233c49b72da520612e59c39f3a775e288ba2220fac1563ab300ee55e90ac046dbd772da788dacddf72c559d9378b39507987a9774301b0000000000000000000000000000000000f62e7d0aa954742a2018d42dd9cd76f041d9ac46ce659f4e192053a1d0c9b23fad78a06f61d2c90eb7b4d1bfe6d951a000000000000000000000000000000000ad5a5ce7b66928d8e6e3806a25425bbf2bc63f8ec87002a913c28ab702b83b6ba590b41a0691daa5b921a12375ef47b275b22db781d5e8fd07f36788bc1219c4b4a13554c28d92a381adae111b265730000000000000000000000000000000008b836a23836624b39e3b3388027093125749a5edd5df50ee0cadf1d485c9dac9c2569a82484269fe7af02334369a29b0000000000000000000000000000000015232caa0c064d8d1bb7fdcd23c0eba21685fc4671e9f04cd1dbaa0382aa4e9d87aea42a99cca22205367d7b2261defaec69b95dccdbf193d9ee4c51615c0b7be5ac6bed3f2559f0cb2755c634839ce7000000000000000000000000000000000875311ab0cde9a925383dc84e4ee8e1610b2f5af0e1f530aed4155cb8ef0b5050d907277f55d8dd542a89e4e0990bc30000000000000000000000000000000002c7a0d315bedb602f8ec558648ffa69831b9fdb6c14fdd44e636ff00777f2f8ae4aa23aca1b261460e6dfd87e7e501131e2bf1816a84c190eaa850ecfe1a9376123e0d0732d90ac3537668f8f18b9f7000000000000000000000000000000000f9531c4998aafabc26e1ab588a97a78c236a854c3fc92424320a37a236d5181d34f8e5533aaaab2a6ea3385acc85f6300000000000000000000000000000000130350be432fd7d68940fd5f54649820ff5b3d015448d48d1f4db3a05ab0405a73ccfc8eea1966abce35833b5d03bf79f4087feda4bd8205d96cd0bf6eee44c27a6669d7ae8e16c731849cfbb2324e1e0000000000000000000000000000000010fefde43b2cbdab52ba664e12c7a6ff29f647942e16ba5a0d41701754ec63bf199ac8e710ae8dc6a033abbcaed3e05c0000000000000000000000000000000002189172e607876a6e1664fddb990009dd5c7a8412d60f7dcb235ed1825c756598bc67f8d5d383c2570a880492d4ee1967b81583fcdc9afe5f35974dc9b6310ee8e1c92031a49c08b05555fc0d33517f", "Expected": "000000000000000000000000000000000765877938c1a8170e2c2fda55241e3c64f7485bbca218f4a2026d00ef4708d014fe4194048da8e994cae1088694d1b4000000000000000000000000000000000b32833dc9a39e1e73578b21f75136be6c6aa2b4128b0e6ff4fe099f7b7a8ba8f2b769f68d32ab4d1f37793aca8ecfc9", "Name": "matter_g1_multiexp_37", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ab94114b3ecf9535261a0726a9bc0e0907385d56206b61b7a42f643d46296c4022bedae90d761d3c002dceaa9167fed0000000000000000000000000000000008e67942ab2b9aaf2f6f865b7e957a25dd7ab8d8a0cba02fb1648e4c7f15ce00f4f5d09199a583f38425bc62d32ddde69f3c65c2c25c6c37aa45b1104745cb8ec511a165ffdb7e304f5478aa3add4d7e000000000000000000000000000000000e53abd9ff27231fbb09155f794e5d126c490314016e31c0b12bd1d2af97a705bc267f92e20b64c91d9af1bbf5e45b92000000000000000000000000000000000ce7d0cc6656108aa7005a56d15a497009c90871f01eb38f1bdc82edcbe4945a2f2b67c9b812aee42cc9a9bf9ee84bc08fd50c46bade91a13d6dc5a06ee62e5e89e0ae7ee885e5516ca6c2dacc36f6f30000000000000000000000000000000018c2688f573d4849b6d19e711ef4d14659c2c580eb938434a3b2afb8c20c522423db4c7fffa42eee9ee907a6492b77ad0000000000000000000000000000000016a7e69d5539263fd6b7eb893d476a00efb8cf09f21a54e9ff0d1c11e9f3651eac8a5db31b40598af6c943f864ff60ba128db1a106328916ca5d63c0b5722642febed26f00a89430d52ec3eae25a019b0000000000000000000000000000000002380f3260c7289ab2005f7b1d7f572565ec938bd894bbb0047ced0b652fa2e74aef19c9fe6bc1fd469b2a4640245777000000000000000000000000000000000f32ca31e6bbb72a02f4b0da0e1627dab9cf1195fd7f48613c89b06c702e662478b24d8b3730321f803ae3a307fd498bd45665afb6a864893e389511a0f7b2df74c9e45a86fb69f6bd79854e3a88c2060000000000000000000000000000000001892b0d219ebabc3be00f45b00be55ae486eb79b1e41aa7dc8457aa0812e7276c21024c79646128fcb2b3c517aa41c3000000000000000000000000000000000793bed9530c814fa0d0ed1684614c1e6968dec931868a64372dc1b648b1f99ccce20fffec7d485a226033601b92a7f228f5fd09c2c1819adf8e6d0e0f4e4681babff46757edeff3839e9691888c132200000000000000000000000000000000173f49cbbe6304aa41513d3742b89c6b07a91be50264350d71bc03fb9efe4faac4a19e2591795ff4a7e67fef7a85ed430000000000000000000000000000000019bb5dcc59ddf055f099a1c3949bb50972c4cfd035d4d829dde4ae94ff9669983e9b1a7edccfc2436648dc942862676fe6e61390ef88f20591570ec1fe71c3ed769ee8e234c7cc7303a4cdc065717736000000000000000000000000000000000e3daf60e4929b4a237caeab203f86e6eed0ac630a8b955a03460a7e609398d076c660401f8d2bd9601e5bb5e315e1e400000000000000000000000000000000058b20160ca2232cb8b6cc63c5a8e11613afb9776e22d93f687e7ba005b099531f9693f65f153db01f20c8e9bdd7839ea83c5af2f9d10c06552ea7d1749cbfa7574b238433c1c0e4788efd0cafeffa57000000000000000000000000000000000c89f1ebd19fb920b6748b15192829d58820ee4995cab9035ad6bfd8dedadbc6352058806a7d45fecefce40133261f360000000000000000000000000000000019151260431a35d124fe44116d86ea99e3f3aa14e2eb09be8193dbaa8f26fb0ae2451ca1c70610233d3f0af9d2e33fca4bcc88d85a5a8a29dfad37ba97ab3a5defde4ec356146db8d10f33bfb36ddd3700000000000000000000000000000000162b48d56f439ff56197fad444dc460cc6432722b9b86c7abbbfa383ae1546e160716d94e442183196816084da90bf77000000000000000000000000000000001278d0796c26110f66930ea9248078c222a0590a031df30c62fe6beeefa70deb0c8287b0d204a911c147cb6344632bf329d5d818e62c9791c320e01a3164e142d9804e9caa7f96b4c3b76baff38ee2e6000000000000000000000000000000000f4fdfa45aa3b5d1838b4dc8a2dc6250c069806ec3c551ac961da5b44eb58d962d843a1c17ebf89bd653e9e44d16300200000000000000000000000000000000052ad9ce994c837596339dcfb73ee25bf8326657633fb5861039f197249d425e35c238dcebb287b77f41bfe7f4db5c9b971c8aad41e401ab6c49dccba28ef26acf4961978e94e633b72c581ac03621e400000000000000000000000000000000185c62a080df61ddc97ab56d2286ceec655172b6c863b509a1a92eeb0719060528ad3a3365ad5e7c0858167ac2c6d22100000000000000000000000000000000126b489e107dfdf4a4638069944d1b1297db734e5da1964086114f9f62081527d7d3f6032c2f29e75b4e1ccf5b3776d4659ff910eea5280dc5c24c542516053637a5dbea576a94a22acefc902e56568e000000000000000000000000000000000f884244e098975b837a58ae0218e7e2606821c95f51d114a483ed5d31a59c9b9cb3b1db029a0286eb95686e0457afd8000000000000000000000000000000000caab7f67feea4752d3822979a770a28c879f5e8f916b72dc71a3b14820ce170fd229fdb61596d9e89b4be8f515c470e12ff32d44eb442a711250875d86a401d0dccc95e5ee39bec71738fd812d487c600000000000000000000000000000000155d3e886cce6f257513529e40c21b5657ef1ff1f4e71bc32b968db3e05652b1ac780da573fe1a1b94b7fef86e7c260f000000000000000000000000000000001184cf09544ec2826d0101d2b79095da6e5f77d453203c52ea17b6476360ccf166ef092eccf86dbe3a260f7fd25a2794666b820fae2459b98f9bff20275a3c96ddcaf98a78f3f5fa4a2c0a26cea79352000000000000000000000000000000001523e919446b532593b8e70cff1206e8910444c01399c0dbad932b596cd0b9c2e40983ddb38eeff4fbd5e8d2b15bdc780000000000000000000000000000000004be8fdc3a3296e543701ce8c1184a983a2932f33913d6d733f5baa3a783382739b697fab4a3d6f9ac5b85ffbbc78a3540a9181633a146d7f307ca7606cd45b8e721c46b955a6989d421baafd8e401390000000000000000000000000000000018d20e7846239f472ef42c78454b6c335979ec563ecbbc3a93176a7be9dde603e6f21afbb68058035958ef7392dff3f20000000000000000000000000000000011ae4de8a7e1a958a1186bda4890d282773788f7d5fc5432393ac9deaba8bccb5db952547f6aae49b8a90c813c5a93a4662ac80797c633d8b9c8907acc2960ebdcb5bdad82d9fceb4411d5173b7411fd0000000000000000000000000000000010641c99a359d16dc3e3f68547288c944d44c7c3e6177fe94428ddcf3c86937a3fe1f41a31eeab551e11cffac012e1fc000000000000000000000000000000000f407b01737dca388d0793521b667757d70e626ea0ba3b051f522639e752280b5657b1b97beae3105489161ae95a470059401af15d9b83e2ad68cc8e2ad1508391516ba0b26fcc5ec6eda8b318a374b6", "Expected": "0000000000000000000000000000000010084535f50807f287eabff2fdb83d34ca30454e4cd747cc3818a9dfd80c30fb3bf2f9f771d435b79a2d36105266f0c1000000000000000000000000000000001663a611323246a963856a92d52947e72dc123dfbeaeb9a3ede6147246814630e5304b50a6585894843790f5d4c818c3", "Name": "matter_g1_multiexp_38", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005315310b8412d62f5d63fd996e8c6b14aaad5a6c83eb3505a28fa6bbe469f7a7cfcf10b49382aad4d6764859ef4910e0000000000000000000000000000000012fbfd9ee8bc712354fa3b73e57fcbb07231aeac980e99d5843fdabc081a159bfc6507911212adafc162dfc21a5afb739c351c585d1920b8cfb89a5bcd72fe041b17f7bd091ba505b287778b0be4e87c0000000000000000000000000000000014e14689a5ef5b9ee89369c5c0de07fbb7980f37294a0e7570191b73f4406ec4bd9bf4ca2521f8d90157e9c3c7d4211900000000000000000000000000000000040d06da8127e64a71532afc8846bd7eb6fd5e845ca0f1d96effe0b12a2f8afb121d7fbe89f632262ba0e382e8204701ec42da11e95cebbeed0ebaecd31be24801fdec8b81f4046fea52f553c4e7910b000000000000000000000000000000000c5ece364affb6af365a4c7506389694b9a10f3ad6798c326852fe85a892014b6901d097aa8910256f47ca1d4667b5a20000000000000000000000000000000003f300682da34e22416f1ca2bc3430e3b153c95773c8c76660603a0ecddc20ba570545d9307a6b0910eb406aa14d196bdfdd8996780460757702e34ad98f5f64a8c1e0bc8851d6c97f02749b8f77cd03000000000000000000000000000000000ad0508c3b4fcc1cc608d002b66bc703cc16182a6e83794e4f3739238c3e02fbb6387ceb445791d54321ea52f779a35d0000000000000000000000000000000009a442ba572cdd9e658080fdf1753670c27e88fa894c307eaeded6ead17799365d1cefd1fd13f0dc321c0e881a4965d3f256ff23b38b3b986a62074c5a3e05e86ead9431fcdeb67512f6d502fcefe3c30000000000000000000000000000000018825670284d3dcaa90a678ff37f23e8ba36307f3c1146a8f6c782f7b43ce16f281dd346962904684c22c1980a772ffc000000000000000000000000000000000d65166eaa6b4ed79b5ddcd7b44f06ca1bf8b960211bcb17d5a26a8595a1ae1aecee9945a674b92384ad05f2f0f64fb6c01b3c8bb0acb17198bde9adce3b0f7ed4cd8615f837aee928524b0984c99d0e00000000000000000000000000000000098da5d9289f26b61486e3ea52b0145a47847ff2b9f1d2756e363e5ea0bab27a98fd01d633a46ab48aa1d2f1d2886f9100000000000000000000000000000000191412a43858276e4d7e69542f9e6ba4fa9bc0a8784df590aeb1e0d65ffb56cce0031916af640dc3e57662f5e5203436458f882b63c99ada33d8215111a6df21c8f7424eb2fe9f429256201d099413c10000000000000000000000000000000013a279c27bf2234542f4ac0e4c2676b41b3cdfa1b55d5c0eca1c686589c37ac63139a7f532910fefe275a08ce2d37fe50000000000000000000000000000000002f56719390112560fda45943509729fef3eed60215190ca1f90143a4d2ae6b41aeaff7edf027f27857d56bae1900ecc804d7a35e5731b111a6904e0998d90ce86cf612914152fe3d2fca0201a41166a0000000000000000000000000000000016489ce6e2b8298e2fe0836556875156502d36aaac621e45514ef03db87631cfcd308285fdcf8ca7ae8bf65bf53a37b3000000000000000000000000000000000b6c8fe0db4492a309148c54465ca06c59c7b71e4418d8fc1874cc338df40fc1355a523387187402b04f5d01b5e5b82b6f1629a801db6bb4066588ed79f75223120728c3a57f7129d88f7f877149223300000000000000000000000000000000065358f885a974a1f64ffd526e5ced18ae5ebab2ed6c9719c9f879adc940292ad124fe5b6c8278c82a33d1ab2a1916130000000000000000000000000000000010d019536f727f8ae098dd9ccb6344417042855fc6722443218d83127cd2b07a6816698dc1a48776d2cbbc937f83163dfe80ddbcaeb784e24975b9a42801c89bdfb842cbde5fbc0c3d70c0632cfcdab80000000000000000000000000000000004248c5eb514980da698bc5146fd3743f5b1a458dbb17edd38f65c294e48bbd55e0d9afb3b39df2e82085fbc03e5655c000000000000000000000000000000001830c1d21ff8cd1ad8467ae0a8d2a34367e7c44829f7530263ef3d7d5bd9eef76b756f475448c308f4c03453f54b43cc1aeff13de7bcc4bc2ac1b37e28ce466805757dda29c9c743eaea9da33f47f4fd000000000000000000000000000000000dbb72f9afde915110f2483c09291595c369f0b4ce2c91779da9266c9f74764da4976a221c4997cb940302ce0e59ac080000000000000000000000000000000012de4b2ca14004be2c64ada45e9a0ba7989ea0e22d0407088a092cad87b4e26b33d5d8f96fe6831e085c6fd27901af61c4984739882bd2f882e12660815b96d2af7812d7ae87f5be034b88e9e04fa289000000000000000000000000000000001387a1edcc34afa05541e15e2355d3cdefbfe22ab7481e1f194e461521894b97b2e18c9fbab1eb5d8e508a0bdae08b5a0000000000000000000000000000000016c4ed675f20aaf2c825de5bc4c11ce1e85a0b91b08577080108ab7b52bb674f78943a5f619f557b96a72206cc1bd447e7f33141d383a1a927b7645656ff7a5795901a997e27003c5672ae4fbab4aecf000000000000000000000000000000000498481301a55b2d1dc95f8115534b1baade13c2cc4d5bdce1fe8cb1734004600a2359e5dd1c61c7338275e2f4fdf455000000000000000000000000000000000a3d2ee413b7e6c0e32e51dcb7d124be92990b7e4307b9b459da1db20f85f4a35964b7987933634fb62a07f797b00b27fba4674313a9727aa4b733832a0e06666d3e38184836edf786317de9dd055cbf000000000000000000000000000000000a885ed8c3ab46b60a7d2e198b6e8d069ca8f7e0692f2b8ce99df2f44979b6045fc17991bfc27867be79e2055cc8aeac000000000000000000000000000000001728864f0fda8476fda4df08fb6aa9e40a01dbf19a4d22c4fa0c319d8496d405f0a5f9c79ffbdd5a4c1b617326f3d774dc0c4d0e34d8a16b3bfb51ffc9b3c353817e8e357c608b5075c173204963606e0000000000000000000000000000000016edd94f91c43f15818752660e4737071d44edcec5d5de426141966a9880bb894f3566e98a05232b9717bf85d66a57c6000000000000000000000000000000000a789ee6ecb80e2ab9c6e7a945ae4839c620f9a7bf430ce09b57a64479d5a10a1ec0a721678b5bece737f0dce97a3a56e4e31f5b6629463311b9d3c8333c33c5b2e79761ffff9863acd9d636e1a9586a0000000000000000000000000000000008affb2247059dd4bd1498c8e229dcba313b156e2f420fa55331e7eac93d44af55a6c02bf2101d90955b95ff6fcb411d0000000000000000000000000000000004759596f12f17d7bad24723ccd6f86c646a39beb2aad35ae5a219ef57e1ce6eb310b2098130489421709bc20b4a53d703f256e58f60307ac1888a1b0b14b56c7435213e271eecc79b4a6f88d102be4c", "Expected": "000000000000000000000000000000000f841cf3d8897108b4a57a7802a3cf8a43ae31e711a6258991b6d5b3851e9e0d759fb90899e462828ff9cf996bbe9ec70000000000000000000000000000000016fa655a67f441e967d3137f6ea8f6cf636fc1a7bb662b1e22f87397e0c77f34e015e6bc124291647727102a12561dd8", "Name": "matter_g1_multiexp_39", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c98e02c9f7784d0dbcb4a49c97a9365cd069817d57cea3042cb4198180b95d141c5ba4d383de188f06faf8f845f78110000000000000000000000000000000014be6f602cd67fc2d147925cd6c90457dd253db766c4b8f737cfca02ae15b47d5798c621091c4be71fec75e0b8b1c00feb850f01feb55bb99e4accee0aea8fe6ed0bd29b2ca942ffe09456733aff10ea00000000000000000000000000000000077bb03ccd915742dcf3c2640ec61f05bbd70987d2dbe9641e0e34ebed3600703e8f9c382e77f99b70c47f54496bb6840000000000000000000000000000000015ad452396c23e820d1e8a8a9cd7557062ca9c627cc7439d43c528e0170e2760e7761c9cd872141543834c89c75537d72b373fd7e5806d227ca1f49ab0a7f8be2b5950906c8974de9f2cb4e13ed20a9a0000000000000000000000000000000008eeb6c2c00a9f95c5b238290b06a67c1cbe0e96da246537c29c0efa36b53230c3c5d91e3fa9d129743e5a9d87e81d0e000000000000000000000000000000000ede1011370a956f240419cdb8a0c8ae869c3d583d938ec32e29c5ece68ec8be0e69296ff0c97aacba59991d65a25563babde7f3fdf9fba868b5eac61337be0d73517ac3f06c39b4eaceeb27ab6311db00000000000000000000000000000000179776b08cf2da01a94bfe7be4b89b3308330cf797906f85889b63487115b386c68c8518158342747377fbda82a6d2240000000000000000000000000000000003e51d69bfdb73a2abb469b379e2b4825423d2a2cf2cec62e2313a76d260be1b0f2892bf82e5435e88205ecc9424275d5ba1635cf82b25b2d7e466717f5716c33f5f3e826bdedf19dbc1d95ff0c8052e000000000000000000000000000000000af478b121104742d0cd13473d1b7f647437d980999cbe7aa8d2246148d970136f6194df1785027ce944cf9ba00aa4f500000000000000000000000000000000170e9f798184188cc21b0950e0f3a570398a97405dc87a2e077af96799960a938f363d216474422d8f4762fe5893ece61a0a832e5bbdf897553c1aed35fab43aa3f4510c1782115e14e5d56229de2dff0000000000000000000000000000000005817e3812f73d3d236e45664af8a4abd2d4a44f741c3c1866588c2bdd88b11741b1c272b68e20800abf3adad7125a400000000000000000000000000000000008dc859c2323f0d2dcab76bd8454209c86685a971d531a32b00985eb822d33691c2524fe25d14ca386047a4976b9e7159b75e0582e9ad7aa4a02ed5ffa22e55570c9f20e6a24e2186e8a2a2f838fa453000000000000000000000000000000000ee06092a2ba4c33f5c9dc6062d50e3b133c7fde5c81056f74a2d869e8f92310f07629db9cc2b755f12016cb7894aac10000000000000000000000000000000011714a54e236d1e13f9b649a0aaa80cff9e093342c71a8dc9ff1e2d4e95b0f6b4219ed847ba6620d23feded7d95944183b7252f8f3cc6341d490c5c4464bb36e012f1b05057f405aa907ebb2c983f6460000000000000000000000000000000017f6061908e62edbb8fc5498eec23a51c861815bc1b437b7383dabf303e6a45d52e73f8363addac61974043afacb02ef000000000000000000000000000000000f3fc04d17d801741f3583e072110b327a3488135659fab2e8b1d2aecf4694f6d168bdd60624713a7c2c3314f8309079f10427f6e461e7b63b781e116a4d5136ddc79ff86b71fa754f00c797c035412b000000000000000000000000000000000db7d958b44ac5ff3bdb4991dbcdcbeab36bc6d21d9e0c8fbb1eb66601df227a6367ccc783a92c534a30b17be462b95d000000000000000000000000000000000424eb0d9da831c658ff048d3e9ee43a900bd1ac98bee97be073ea55be1dfd07d425e0906779f0e3459fc69d316599e56440c89f8b10ce15806938b7ad65ece194d2fa3cc8d7d5591bc1d52d010896af000000000000000000000000000000000c9cf785be01b7f4bfb0140004873d0db4c8b1387dac0fec42c6ae1a72123ea5cdd2b8c98c69b78d617b16c48ebfff2b0000000000000000000000000000000015c4856f183d26d13196739d9b9c971af111b4905b669f3e46bbc8d8c4281cad1be05e9ac28de0a98031923fcd1f5aae43f1bb26469b778edd10127e634fed4d749e25b41d8eba86eff2c068c33e714f0000000000000000000000000000000001802675ef47f9660d5969dbfce973c8bb3e6b2a2717fac9a509fb3c7ddb272db86f283992eb3167145f2e496002fb1f0000000000000000000000000000000014a5b5d966ff72e036c51686dc6a9f39a487ab8adab6fa4a906f28acc67d64576fbb3a00cefb7720f42ffcd62fc8adefa40251ec7a7e9f7cc29948b122010d9745752df3f4a9c67427a8b58122ad4e7e00000000000000000000000000000000076ed600ed860f16ec5dbae3f09471302bf85fde7702b3376b0d670f93560e77699bed969e7001570f44dc5e37aaa830000000000000000000000000000000000c993a8b08d2eb00bcee05e1c09e8a37834fac53643643402f60fbfe2cc7d795f5c68f3d6a32c8604c37211585830426e03e5eb477506c397bc1a5204b30872085a36b65b7a8df3e0e187f3022736329000000000000000000000000000000000eaeaec30bd8d8dd9ad4d38ff97e08706ffbe51388a93967cf16155b10d218e5b1213c29c8054cb778a0d3ad22d32eb200000000000000000000000000000000079e5f2bf405cf2dc79984ddb3f813a07225729d4cae8ddf7536e9240fbd0480f6b66321749a6a9286cb07758482e7f865cb04110bbfcdf00616c2826e253f61cf955756e94dffcbb6001f59ae4a93c10000000000000000000000000000000009a0933829c2a3f2c3e93f58551e7572ecf6eaa7857aa899a7ff0eeb15ccd601559b9ff844a177568632bc0ddd6e80a5000000000000000000000000000000000b69f23cc1556385897bb7457a706cdd8539a3ed3e7fa504ffbd95abba1e824dc77911efd1ad0a9c37e1a41a76ad38d13ce1bb7cf7d7a55f0624bf5c4c35327b178923d88be748a9b079720c27b500e6000000000000000000000000000000000d3c4cfdc03ef5fa066be3c26744032e5a2045746cd303b6df542a6133c671f4d25dfbd889840fd624125b63839a1aaf000000000000000000000000000000000102fd619ac946e99c765010a4ac392ab907c37b31f628d6d58c0ade093ef394a7547de36ca0630820f4b5d857dce449e2b4c64b363efef0c5525b0337bf407879755f060af451075f4345dea7e681a3000000000000000000000000000000001589cebd579c2cd31226245f1dd3e428a76c7d0012f8dfac4dd3428a716d05a0a79763f0061d3b5846dc29a8a006a37c000000000000000000000000000000000bdf3425e6cbe628f9223930cb74ace4358e12e5d367a3604edb05cf0f0cbde84346ef45597bd61592500583827524144c85e47ebe2c26e0aa25661d3353b5d88c632182aaecb35303d8d47f01308a0d", "Expected": "000000000000000000000000000000000555fd5a7818bbaa7e786f11eaf6f8620b9686b76c6293fd91690a4d181c0b470295313294589daaac429607b0020c9d0000000000000000000000000000000009c3a53113a657a5f7e30ec28056455f700cc7c3d40cbe4219dac00980675023bfb7462e634c8a131493f12725a27d5a", "Name": "matter_g1_multiexp_40", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002d49464783e5ff91aa0dbf6827315dd308e778b3da5833cfca3b6431ae784193d915a566142ef347b6ca024b6f1695e00000000000000000000000000000000029051d39ea4369a837d4cc8cec1eb8f9e7f9c3a247dcf99dc75eeae43378b4b9c4175aaa5eb3f7abdb1afc15bc2076d5bc589e7d89994400c511789cbcaea19b077e0b02d625e549bc6f2673ce40128000000000000000000000000000000001363b8347ef6754f61520942fa8cdd07e6dc2b72cd40ae41a23622be239ee25834482533ea7edb9cfd5a4e21e4f33f020000000000000000000000000000000004495e8d41b145ca7f5268e66c03528c8d976cd650d815257906e46c1f9a0827e0e79f5a8c2906ec96718538e1da3b1d2c3d2a0cba111642a6354c117d494be805cad5b5c486bc47906a2d37a9cd9f850000000000000000000000000000000007735147af3bbef7cf0c4a7c8f1dea302a5e4edf01d42c1e484f7fb1f4b8fa23b8a7a16fbece9270d8786016836bc979000000000000000000000000000000000053406bb3d2a4cf37924643a186a56844a4e77ea4c9e9e2c707b5f947ef956369f400e448930aef7135449f8cc51ae1530ff74626657262fb49460b2c6981155871f2eb5562581a74f968233c3cbe3d00000000000000000000000000000000133b92eb9f9a3c6cba655d5f26f396dac467b6444657eb0a811dc6a58ba1898f24b336f4fe9b11c1e0795891b00b6c150000000000000000000000000000000018952f3a7f8aa78a8c5e5bd96ecd5d2b2f237916d8e2982c40cb7498423f12c6ddd3cf1afee75a3e2cd773bad7ac3bf6d182ac912b005e90ab81d4f2a906da8309a69576a8afaa160fad2540ec04991300000000000000000000000000000000051453a8b81b0b0a1566540b3026e40676ea48e3c5aff89ec4fe3b36c61aea27ebe01fe8a811fd3ff73eae0a67027cfc00000000000000000000000000000000090b399b1e5af056b428a4c270eb204df4999e53807d34ca750f30b292cd38030491c3d1b0e08600f40a16f707b4903242a002a460b51429e25f85ec4abaa580ac1a14315b1627bd52349b7b81a641d600000000000000000000000000000000142bcc3458437416506631c4dda54572b5d66093ff23f152957350a3aaa462000ab000cb8e9c9b23a17149b5d012adb0000000000000000000000000000000000734c0fe1df24449ef498fbb60558010093cbc8a14ae068aba2f70bd7718e30450411a81499a895e3d84079a9dbb19557a650dd3765032ac139d1b54ec7a5457c9e3caefa6af45d198433e5949d149ad0000000000000000000000000000000010a7a3380a6d8b2bbf212da72eefb57d2fc2305ce222e8d908bb572600bef7ff55b1df6a9af717e1345967cc18e779ac000000000000000000000000000000000c5a3aa84b489c879eddd3c20df6d510edb5e9ac5c1a2e42b770571ceec315d560235b27468299e2e60af3ac1283be12bbedc44d54349cff199befba9531dd4120a51e2b830a3e356e68cff31bbe365b000000000000000000000000000000000035471ee35c187e24cf0d113c0ca1ab6322528153d0687b15953c39290ec295c0dd4197b72448f2a692537064ede8fb0000000000000000000000000000000002717020e3369b288314a42fd8ab6c6ddf7007480ebc4fa094ff7c4c4b750f477917caf071d2f1897a826fe870c2b7dabef3956ac71bfe97029b8e3f85923c2fdf9cf1ea6582b68d5a4eabc6b044c80d000000000000000000000000000000000b501cef8ea57ae253de63d81998768e115d58b353ac1ed6e90d24f8c39a31bac1a5be1b535a1dfe05e72d80d1db8b0a000000000000000000000000000000000a3b62c001c4b725f7cc861fa042c31fde4e77b3b0610df63dcbb7e89d3fd746919c2bd8ee4d623838a05d42b6932383392f5b4291fbb18a93248e830b08fadbaad6434040c02b45cade73b77f22c2bc0000000000000000000000000000000011cda0c937d8fb2b21174ff3a5b88aa5e1c9a8ce6eaf26cac9fb3ee7f3ad20e74ebbe2d1bd9f4faa3acc43b6e6d0d70b00000000000000000000000000000000195257a442c8e39ee6b72cedaefab0034f48bb988a3355ad07b3e3e314800b2ce30267dad6ef3fd9dccd7d2318dbce0a20a96f963375d7a294b584f2da699a6a00eb5781f46830987346cf4fe922a2f6000000000000000000000000000000001630ea3c7f910ee8574f29d652e86fe3125c306218a894df0b4688ba582ea7d597d7e62cc2e7c78dc2db289f587f10ce000000000000000000000000000000000d2ecfe74480518ad4f5ded701afa68040246a08df1b8dcfe6fdffe77e33c6bbd37192c6c41c6ab5af506ba58d8b3fe4115cb4646c8996239f4fdda8c27a335361f0a19550d6eb0225c008408c4725880000000000000000000000000000000017a910c111d7a0f7e7a3d48b1cd358e2a1213edc077034b06d1e96beedef80473ec17d1c10bc2d33d4fd2a8c052d926900000000000000000000000000000000040167897293a68c980bc34b3f79802b95186200b40b4763fee9cdce8afc681ee916042d619cd51361e6e02688b4915ac8a8d98c93c392aefb64ce0c7ea455ba14c48bfbad0e3dc38d43abbc3276caab000000000000000000000000000000000dbca3203ee6c7fe8d6504ad2041aad2681b889996bbe28ff1282cd20da563dcd5c9fea5fd03072134019f579e4ef7af0000000000000000000000000000000001317a861403866494eef2bf59519f2d324586e93a0037d07312dd8df4ab844525afdf4b70f9e21a6e0230bcde35db4d8221622734dc6ccf6c7b84b387a3dfecafe187dab70ba373b4416ce3c505bef200000000000000000000000000000000069ea1da08dce1c1239d49411861d3e8ee7e6082d9bf8ff0aad1cbebdea6dbf82fb0d6332ae436327440b71ce6535ed500000000000000000000000000000000079904ab7b16de5812ea3eae39d790aad32db02c9cbf7b8a3a8d4222d3baf710ba1cc5bcdcf4fc9e2c4567992fa911edd3d1f427a25f5df025fa71244cb92dda9391d65b04756c41de0f67ea072c375d00000000000000000000000000000000173ca2615b65e574bd77c8cf55bb116462a7ab9ad4a3879f0eefe03f1a6c0d30feed076e0fb21fc60ee9f270af180cda00000000000000000000000000000000179351092d68e7e0d428811cd4503a57bab9a4072f1bd27b5e8445ec0058eb46af58c4752601b53714b816a4bd386048b55c943fd9b11f2fb8a89f6c08a6eabe9434062354d845f1ac740e6043443f8b0000000000000000000000000000000016c9d1fc1790a15985028a38e57c87cf010c87bdeb2a288a055b4b08497abd1d616fa8b28d6da8cc23047e9f8bbe6bec00000000000000000000000000000000089601933b759bb565d849c3837570feb39d442461d764a22f993a695fe1c55283b8c7db02694aa66032512d44dc88867b0c1d54e51b8572256aeb72bb032a5011a3e8ec5ad7e8b6e0397b9f6fc64c9f", "Expected": "0000000000000000000000000000000018bda18912ce64106fd3d54ec2024a1d3e4a807d7bb8aaff7b515d75c9934d4729c14a4a72ca7654ca811a69f09d170b0000000000000000000000000000000011478fbc5c03470d9cfbf3decf9416e1dbea8a696636b94244c5c637e43f81eaed0210b1cbcdd291094e8581dba3548e", "Name": "matter_g1_multiexp_41", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000446af4281a01e0a20b7428d06b63b89573912955971be4a5cddca514708419640f8a7f95b50ef8714a04e1fd81bec64000000000000000000000000000000000087b94d8493239047a5cef74dc20d7708d7e3365018df80624cc5511483c3a5d9b14ac3d4aa391da60980397e4fb1e96f082a5ffb8baa38ffd684a4a70114343a1e723bfcbfeb57d0a85ad5e592d74100000000000000000000000000000000033e5eb4bae80d55f512a48b44054d0efb8af1f9870fddd99df00f31dd437025381df3f4023ca217ba924a961864223e000000000000000000000000000000000f6d7a7371eddf7283890d59bea3c61fc3bff19eb7fa333ae713fb9a73c4971354474986ef5a9a81ca8c5b38bb67f58d5160286a6d23c30595809dab6ee6523d7d235114d1b295087e024b4f6ffc80e50000000000000000000000000000000013d4e9518d398fc0add8233fe58c198d65966844fe286fe657891245fba8f37665e2bc40e4e70886667c9e2c0a1c245300000000000000000000000000000000089562c10b287d4d66b2b694d29fbac936f700de78525e9be59a83543593b42c5c577910e7ba1b67d840d88e7a3e53fdbbca29b94b6583d46753473143d13a7aadb0b18d6d35d7423b8a004991fa1ce50000000000000000000000000000000005762727639503eb63854e5fd3de33bcdd80227e16de19cd7cfaa10b7863915e490087dbb980b6dae5114df7d56716d300000000000000000000000000000000104306b38970a94b5c8839ff282883b7c88c7ef45a7ed49a02b322a16521faf2b881e2dfe22da3f4472e2bea9fc40d7e607c80069dab2a16e39370de32df20534aca46565cf573159a93c64f1f0c4a1a00000000000000000000000000000000056e61b51113719c1829d4ae4361f79c543961de801b1a62ebbc3cff04b0722be241236d4e1b2dcf7c309ab9735334a700000000000000000000000000000000031ddb45e491ba2d719b1f72f54640c63e281dbf6ff84eba2eaa2b781d87e243e7bf84d7151f27556156970dc8a2407f41c1f256e866d218b3ec20c132446945177d518573ae3f0e739ebcc8821bfbc700000000000000000000000000000000029eff96206ff45ea9bd0be2b83cdb660d6bb2d236971517b962faa54535f01097327a00154bf35dbe47841eb36417020000000000000000000000000000000013734f1218c3c34d2780920806c5ad211128352d8a41c2a1035594f470ae347e372914827775094164a5db9d0b2a1ef7c72a47e2267010c532d676ee3c3ebfb2be2b7569f6f7a22f76733d7773ed383c000000000000000000000000000000000f3aa9f069b07cc935a974ad4eeb47e8b0083397928e8102651ee54f53005625c359d82fc8b5dbe1c76f650cdccc2ee2000000000000000000000000000000000e2bf6a8c4234d118676a29f12daf244ad9aa562faa970d2d63feb074946ca70da039e2de104f1524b1a8f3897f053f4c52f48e84a68d99124e678dabaf376c956dbe9603974283a9efc7c27e830e959000000000000000000000000000000000795a2b6b27209b48c00cc8d37864f14c6be66d6a41038122a28186d7bbcc4b02f531aaabd000fc93c685ceeb67bc3c500000000000000000000000000000000143926b42a6654e439fd01883f1ceb524cd8b5b1f2e3eed3e905f6e948736790cc1325d1b04e30247e4971b75939a766e4fe662495bffd8ace4c1ddb39e612b361bf90a0f1bdf6c7fde2bcf63df1bbd200000000000000000000000000000000074096150c9e04c082a1aea20c785b3a7396568e43707c42c512575a97db8127c8c1e0548d640dff8821d7d235f268340000000000000000000000000000000012dde2f1d15c04292bb5da4c467cd674ddb43e401799257524cf3097d0dda1f3c9f2f0637cfee914a4c66d737f9e3278651e67e96f64b80f4978fdc1cac90be538774e34c2f619f8b8e60cd2aa20f269000000000000000000000000000000000109196dc59d6ec06fc4c774f665612c11bc3e826ca4ba528a15c6290f733f3aa1fc441bd896021471e1e85943fc9ec2000000000000000000000000000000000aa0d17d44bf354e48275ee3e4f06291e242402469be6f4cd4a62ad3871d878c1d27a8d06974c5c1138281802368edb01a6ecd3db89a7f07344b5728efffd35a11f7380c740669f746fdf565905a1ca000000000000000000000000000000000067458ca402c19488e2515037abf9323ab8288e0e11f7cdee18b3da50cfa377435cfde1f63dcdc451ce65a05641cae370000000000000000000000000000000010ed9c895629bdafae66ea176388be4e4ce45cb13ecbe0869ce57f0f48852b6b8c47bcc4a14fc5327f1df372ad9f5d4a7db5ef4c1c174c2e5ffe5555f54f4e845c463bb5105381fb39eddc01103b1bf7000000000000000000000000000000000f393c5fc8e5f1cbc7b59742e5b6236c9d1d262d0b736c1bc188ebf58f954bf2835cc70617062a01459c139f328c912d0000000000000000000000000000000015501635aa7565045ef59067e0ae91a5ec4871485ba411425987d540bcd7b5782aa7164dd631e4c7896b3949cb115f9a14018f14c50d40d3324952ec22ed247c13c4cf10eacd32c3671757bd12b041e600000000000000000000000000000000174b0620cb49d8b1a5798c3746046c2888c8e96664dc7bda5b4e90336517448eef534469a40086703d9a835d2a94930500000000000000000000000000000000033db9968fd6322e7bbb9de572e8c92b5e3717a9496803e3f6ef8dd796dc6487909ff318ad6d4d91297ae6f2daf07bcbed4a28dc3acaf2220ba56d026b292a7d017bcbe358dedc57556cf638517bbb14000000000000000000000000000000000449ee22d2c23ec02fdf1751bb59feafef9291d6d56f7120612948875afdea56453e081c5c5086205ea83f0b8cd541ca0000000000000000000000000000000006114d6d8ef1e4c6d79b23a2b91e5577323107d90523001cf7d6d18a0ecf3b414d4fe1a3eb831a6d907fce9d22030bcc30fb17a38b7d0888eb02394eed26406bce9e92779251bdbcb432153a550c0850000000000000000000000000000000000c2082409ec14f6121de6ebdc06656a28dfc5e439a0278593dc6aa845e8091d8caaef45ea1ad05aa12e3c1533275a663000000000000000000000000000000000a2ad9980247640d44d3b37c7b7b2c1b57592ac12cfe9aabca4f88ba90c8b3221a2b9f5e4ce19ffcdbbaf99ffc584219980b5873a5d0f78c3b8582581349498fa997fe3c6b1abe0edaed594253359d8700000000000000000000000000000000108ea3fbf78237f0e90d4addb69f25eadb0f21c89d92774b4fdcbc97632f1622ab4ab408fee95e735281ea5da5c2c8130000000000000000000000000000000012338527c7932a737daab3f8de98b9f2aab59aa1b12e84d3674a8ddbc1f86a8a9e7eb0ba854e9564407aedd489b6016c619f5719c320320a3c45dcd6207575e0d8527c458c56d3decf1d12ead8a985a1", "Expected": "000000000000000000000000000000000aaf02063d6b5b395b75faae4039cf2eebb69053f1f161242b47854cf07786788930f3be2598520c178301ae0bd13ab80000000000000000000000000000000019574e1de9161a11e804d8077973c5ca70ff7925c847d870cd2bc985a8724d41331fec6c1cb341f7509a37371db9e4be", "Name": "matter_g1_multiexp_42", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000048708595ff4f08cfa2b1c101ec7b3538a2e6044157bf39a63255b5540211105f680464be5b03256f9153a90a4e62d44000000000000000000000000000000000f2fad0353cd8fbcf0ba75a403209094d88d8c8d068eb0c7077b8263fd9f7bff8d6234d75ac4da232667b5c566604706119d33d32affaadbf6c2b6243bb7b344a971270b488cf887334fcb15de2818cc000000000000000000000000000000000866fb774b231d82a4508ff9b017ab836936299954b2b404affea65f315b62da34c76019192f5c9a447dba8cc1b9075d0000000000000000000000000000000004e050fb7a17bc738a55f1ceba48920c62648a27cf438b770a66166522fb0929069fa6f2b2b742ed689f554e9023ec14f1d832b355d7e0ac3653431528ad0a8f6819daaa19292a00c910ff0ff39f46d5000000000000000000000000000000001710b342a52b0781d1ea18a9f07d54fb18e9c90e44815cc7509aca3a5c9ca3cca6bc32ff6ff726cfa353faca4f097e9f0000000000000000000000000000000017fd38b122a7ac39533af597b462224b86370f6e6814ca1ea71d961b9c7cf94b952fd75502031cde0851773b2c6b0108e6dcfa50f6129544835b5a4568954264ea68d9e2e5d4370ee31026997a3fbfe90000000000000000000000000000000001fd243a3c69dd5e7ef19cfbd9b7cecd475e88d7be85dd3a8f48eb46d5dca39d05aa4b43c0c700b6632ebc0b4cb3baeb0000000000000000000000000000000008ebf24e9d2de0fd82c69e0ddd1625da0367c2e9f975118dd2ba5606d77de377be10515d9eb921be5136ed25fa6b27abf7822767391d3b2331e8e1b81c659c6e0262f7355063decedabac9797a84f0f400000000000000000000000000000000021f919adb62791296db3a0b81f03b87c01d94ca312f55cd94364eaa654bc47684d7b0336a3afe813ef1aefc7dd0ced2000000000000000000000000000000000b40dd6bc2fbfa2ed277d88f77aded330c54c1c46a781ccd039b270ee9b799a70855ddb1201dae29a1b124dde1e6acaab1ba1cd6a4a6c433624dec63547119c0d492e3f38afb04e5153d82e400631aef00000000000000000000000000000000054f284874c53bc914040e6751ddd444604d34a38314d8057fa0f77978150fce0add250a6bd8693ede79c9f6b2e025de00000000000000000000000000000000045f6579793d166198d73ccd03da2e907efdb31b54b0b0fe3e2f1e02edd7d9cc0c08af089330d53aedb60aa7cafb0e0ca41e184bcaa0721caa4114d6393ae2251fed84aef57c7927a170145308bb136700000000000000000000000000000000189aa0df86ba479009d4bfb8608c31d3d49f52f1bf758e5c05ee9e5a673bfa15e1c6c37a978c4c431ea035cb7948297500000000000000000000000000000000120c90261fe77d6f41a42a170b28df1c9e6e0cc4bae247303f399d3be7c6ce8319a43e7d551fe554783ec5ccaeba3bb363cb451d8eb3565274793925a1869ca5a25fb19639449c71a761809f785568de0000000000000000000000000000000005e990869491ce375477b586b63641ec71adf226c631a14ebfae3514718ce546987c17c9ef41f9005c10eb04909a74ee00000000000000000000000000000000141b8edf812a2918dc9a2242301a7e7f6433a83298be9312cb48f0d3f0c819a4368ca961a0b6f09f9e077cca6111657e6a2f94d55f784ebfc6b6260327372217d6a5b9637ea5f9afc1a65f99c221c29f0000000000000000000000000000000010f3f93de5573e42ced8278a7a12b58086c04f8b862e11f256f26731560e606ab81d61a1090857eada5f8eb3afc363c400000000000000000000000000000000111915ab2711479677489dad7695cb02626a0525ae9ca51b5271d5fb6ff438d99730369654240b05b5d47fe00847c6327d889a3362f551b88e63463b7f0cc334fab3fdd302b630e419e362ec1eaaeec0000000000000000000000000000000000ca6c2f2191cf86c596b439de0e0df79b441de41c7661d4b80723f14337a379bed9b97958d225700f06f8be5401399e10000000000000000000000000000000015904391fc3cb879147c2b5192641c4ddde11ca8129c3a03b82f5f824b2ae60b3a33c925112d2de94ba3eee10761da528bdd400ad873cd6ec546bff698171942d536b94e69dfef4bbf316a471d4b45cd000000000000000000000000000000000fefa6dadbcd8edf2861c6ff4f5eb501a76507b1fdc1b8cc992226a7e5ee17ea343cff89426c409bc36c2aa3a8f5793600000000000000000000000000000000166706cd1ae090a41ea211d1333d360a1e34dde717979295a0d6a870932f31158e43ca041d1978815aadbf761275953163b496a64cfd15410192aee9912f869deea5a08eebd6b160667e12fdf23c44510000000000000000000000000000000008f02061fbfe82eacd770520b46ab49bc29bf358468adcf904854e39b30ec4e363e80f18eeec8064947bd8612c37493a00000000000000000000000000000000138888a1fd168e9c94959cf026605691b4100a828c3a75ce95f3dbeba2a21d8a44dfaaad834dbafe28c12154f41f652e70de38cb4627f53509eadb0918e562c6fa68a4cbdfa9f7578a8aaa8182f531500000000000000000000000000000000002a07974c00de6936c31202e2b0c76c30ad15b6c42393d5c5d2b1e0d5eaba8b5680d3837a8029283f572d43d2944e4b10000000000000000000000000000000013fa3f905a5618b7aa3ee5ed37055f0472fa361fbe07733f9c500657338c62bd4cc3b0b89e8223894f365a58100ee35416732c583e8049a5de38642cebab774d90d5f87601e3599ffc9af692ba532e620000000000000000000000000000000000775861019fd75c201b3a23141c8e962948ce38fb0f15cf9d08d56ce0dc574300e0a6ed90a7c50b8c71a1a9c466d16200000000000000000000000000000000066ea30b3a1bd410e3c70b1173b91d3eb9fd0be55b2d583c4be627c3aa9cab1b2a5fe13ccb37d781965b1b121079916c4a037e7562adfbad6b1ac48b8e4b6f277a788ea2f4416ed2900ed2791f09bc24000000000000000000000000000000000ec3ae37e6e5b0c623534f5c02d998bad139394daa28aced4b9f781a5ca671a02f1638cddd3bfb5124f9c5c830cdd9e20000000000000000000000000000000002688ab0be331d6f8246a54749c54fc111d2f7414ddcb1f3b42724e5bf14cb8ff3546a3b9be6115d91f62af8c3eed35efa878f6a2e18b88d6badc5b42775e92c17974f3a18817b7769d44ceecac46b890000000000000000000000000000000005d5e2230d538b05b690e878c03d793fc70c391e853b0ae3609f81a7f24aa6d5a67f3138308328783888645d1d84a15c000000000000000000000000000000000d625eed47e245ee74aeb91fbd72981c4f2afd53deff7ab478f32e2a8635431d9ab9848f7912dfa4bdf8ee7201ff418bc4f1a7d2b66e6202c957a649384cb277dbba769afd60708b457613f0f3372515", "Expected": "0000000000000000000000000000000007cff832bedad3caa9c91ac59292828e79811f91c51c4799e2752ac0c12e2c47a2a07ad0521097af7e4a939f3fd230b70000000000000000000000000000000015037ed0ec4981737fa94f276aa9a4325a2267b90f34844f14a92d677060a23e23e3ff0b3df77e7e67e85c23b28cd44e", "Name": "matter_g1_multiexp_43", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006984b92b5b868004f39ebf04f41084d03704732363e65c823e5ad4a0a3fb4c983ff9375249bdcc2f46650921031bc1d0000000000000000000000000000000019b9d69589cd29a9909af5a303586aed5e33650331b9866a6d959b8580ca8312ad0e96c7214ad50db7502f50ecdcdafb0241da9d8505208b4d3ba2521a42f28df7d06fc212e9e84931cbd30ae3ba2e1500000000000000000000000000000000173433f7025400852ffdfec020a44b545b365158ba8f919f434fcd995c0d84509c77d8a05405c79953b8cb667047690e0000000000000000000000000000000017d73ee336ea56efa64038b31d5abb6650c4c6f7efe67add40d09faf93fdd9fae44732bb69dbfb0dc8267c4d01d8aaae6fecab1334668102e47f1e7139059c1d715a1851a026a1580f93c2daa3f08a2700000000000000000000000000000000184ef5b6e309fee5030e2cd8c6c3ec49b1cfb09cc9cfb349ed47e17409d9c478e8e54f285a3b3a4025464162b172d33f0000000000000000000000000000000009b78ea5d2fd2113a4bbcbbe6d0108bcf27b60ff435b5b587e91155eb0ac6ea35c27f276b7e11fe5fb59508454fd8bd24e2023c64a3b51cc3d82e262f83260ed4a5e9e3238b85077852fd501b52aceed000000000000000000000000000000000d0b8aca446806ab51b4a49049cede15587aae742ce7d80c2a05d255429c945d1337b4fa7ecb8f2c3b7c0b0299a41ad8000000000000000000000000000000000bce866df7061aa4319336ba1f876254a8e0faf3faf2f9ffdafd0ebd7d7d0c854c61b476583207818f484ccf7faf90fddc0a88f0aeb2b082dea6b50d591018330c2276830ed554840c10772403561ed70000000000000000000000000000000007018908a64fe5795ad178b8bb1c8540ccc5c78ddccf4e6cbae72bfb84e794d23172998d29e568b186cacfd025962a010000000000000000000000000000000004751f7d225407a8d68b4a196e32cb4c0bc6a9ed9f2093e4242b268d6c5df978b8595d8940f59be860b66310bf8a5460f68c9e76d9d8914f14007c968a31089041e67312c6a3e5d30e65efa55894ba74000000000000000000000000000000000f61d66b0539c7ce56da9308d0ccfa9245158541b2d1b14c381ba53471ae9944ef3ec9f4eaf52c95d5d0bda92d6b9a47000000000000000000000000000000000612e57aaddc6eedd9b8a08b991bebe6f5cdf7805c2cd4de5853856f11eaee94c4c2e0799254f98348cef63236cbae3980eb90c6cc25b3a48d93b94b698eff513da37210ba79d22d76a270aa97fd5107000000000000000000000000000000000b8a8cf0fa6ea9f3154eb35994cfe2f7af4252adb8f26d718163f2bbee3cf1bfca400f4d3582fd5fd407083e0bb48ccc000000000000000000000000000000000c3251d0d9e8520b3e7b43acdef58c75348786654103fc770c7ffef8593b169bba3eaa2686791f919fc70f40a171bda8067bfd893b12c79e13659ee9b5f22de71d806a85410c9a23dc43363915a606b10000000000000000000000000000000008138d173e3e8f5e63f6aef89cf2437690dd0c848435f6032f943ef6cbca87bd2a622f9aca825b7caefb497450dee4c200000000000000000000000000000000183379ed3c9a6a6904e169c68d627bb828a05a93e38ea3b7886db2fe6d1015319d3887136180ab7dbddaa26b1fb3335f34abb11f7ed6d73fb81ce2777acd6bbe8839112c527ef4ad88b094cabdb4742a00000000000000000000000000000000083f8fe152f7edcde2c81107eacee9c58ce22b5aeb10eac15e7df1657a813c98b182433655380c9e8ac18efff2188b5900000000000000000000000000000000100b06f6129bd9063d2841f4c244adf2dfead83e23f3b1586126623ec35674ecd6422efa0e86ed0502a83549551afebd8d6693acb1eb73f6ed1bb4f74f1062f720a7f2c0ecf2b5a944ff89feb2688e1900000000000000000000000000000000072c644635936a91dcaee40e3b4794e634c315a39a9cb5cb99ef6784b332fdcfaafdc80e228cd19d0104d5796f584c350000000000000000000000000000000002318bea9077484e9c1937dfa63774b5ecf6fc63ff06e5cb653553d5111a981c09c907069ffe11b5704ea60a9987328329ca1b157e6a2b5b88d7467e851282491ed30382ba217b82ea5cc9ca0c698693000000000000000000000000000000000aa7249112c7897c9b1f95a7d8299790a25d155dc9ef7b1ad6dd7b186bcddfacd4c77ee95e634b5f283c8caebc00b9c30000000000000000000000000000000012e31211b2bc88c568e08157da9c3e3220dcd563cebe44653ff4d62f8c306ee9136832704272317342f634e66e8e66a240bb53575662fa0b726469da01c39df389efde3936d2eee18d7035704130ad6d0000000000000000000000000000000003a5576b3663114b410276a8c537a93f790276754913df727ec6c0a684ab3c705ec04b8bac882bb9c5223702860885520000000000000000000000000000000002221eb21003c6512428cccf8a9c775df9b72ed8810dada5c92463e6cfa3d619f22a22e314b9b8882c9e2f609b73353a1574a30a575138c44881c1c126be214c6b68335d7338875b8a398196f27510d700000000000000000000000000000000111829f79d4ec1a80533f76f32503cae2842981e29ddf9a376d16ecd7037d3e0dd1f8cc84d512fbb39d58564c019a559000000000000000000000000000000001808e65ee7f31a1fc15d187eebd76c63a3158469099bd6acddb0cc96354072f636651137d060efd850fb599a6965044e6dd51553c4119255b31cb0aaad7391694f7dd29420420b513699747bee819a99000000000000000000000000000000001274417dae37cd33b2a3e086f327df292b6f997e5c93e71add346d6e5f6ded135c8d6047978c10c5c38752006b7f76910000000000000000000000000000000014f867c58d3be7b09891f087f47c1bcdf82c16f899ba960d8a0db4a5eb66efde12dbee75e77816cf9afd4877d9d08f32d88f049ab3ee2b01af449abce08ca14ea3b065f06a8665ae3510b4c04f423082000000000000000000000000000000000d98fa6b2371f65f6f0b62133d1a294a7faa9949c7df16818657a9757fbd8381222cbea98a72a951e4b2b69b216f705b0000000000000000000000000000000016331e8f0661228b1e5f4df59a09de5133d16e06e1628afaf8b2a1160961ed9738400078bd79cb5bada5f99748ba220b19d6e227185c538b122858ad5ae594720fa7f743f5805552152a213ebea64aeb0000000000000000000000000000000018f129d1799d9b46dcea6d239679eb64f144adbe1a9561044355cf66b4b1158513406ef4423468b5ae446c4128dc03d8000000000000000000000000000000001669ead3f97913fe5448bda1bb0be354fff223e51bda5eba9743526e964247211e9cccf75e6f99c6abb5b8912af94f5d3f53123f01c4d0d4c18dd72ea87ebb5fcb559df255773fa0165f1432c229deb6", "Expected": "0000000000000000000000000000000013426d2d18267fa615975295d2029d2e5730fc845556d501c8c6ff8442cf0f3c7facfc329f6703043bb2d45acc1639130000000000000000000000000000000012fea8316f8eb7cd655aaf9cff8e395592360eb6d62bd42f6e1d1e27b9b54bfb7be5b56791d5ba55a798f073f9b5634d", "Name": "matter_g1_multiexp_44", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018eef275d602fb152cee956b04313bdbc8f0079da7bd8d6841fbff1f63a9626f17ea3f7a8332023fd9793ed2eff3990f000000000000000000000000000000000c41214c40c5c65e79f561b59d7ae103cf8c60f78c2b0a16d96a2e714eb30eeb0cf748044bdca077c4be5f4ed155ec50cdf2bbbad52a3f5c0b3959d46a8c42f6f5250a93c3dcc636712a4a2baed289c90000000000000000000000000000000001e5db25f5964e3a5030005152fbe9c00252e37dba6febdb7441046f734d4b86d60334d91960b09bd32d258b7ca2662b000000000000000000000000000000000949bfe49b0256a01da76f5c2270cd0b6ae70fdbeb55f932895d0e72d94eb6db236a8ea40d419ec6d9354c611b8010a918adf5d8fbdf81f8e4bf2f622e2d481fb2dea06a1aaa289ce4f6e783eb9a98dd00000000000000000000000000000000158addae39a79638dbd1a7cc280e0a24d18a4914ce4e290f8f79c147c4e817d95a01bf6b074ef8e819a124cf4e3bf088000000000000000000000000000000000bd2f13538d08742b3bc7b1cca9cb9e059b4bcff76b49a189f506b4bde56d8a58fe0bec2f8425ba5d574dcbc5efe0e93650e995b73b63d068fd54f596cd9669fc3061f0c1da77ae7d0f5bec012f9ba69000000000000000000000000000000000f8615d47e4327d862fa64ff4b9be14df2cad729b816ac7bdcddcb32500b6523af3303fe36c0e93b638992c671958d5c0000000000000000000000000000000011aa78c5d0073fb9b34235555bb2e3f27e55a1d576ad4e3f63974cfcb2646c6ebfd6e595d46613987c0c8e86846845dc3350d4f13e25052b1162dad3ace76e5cda71680fdc89460d8fa88c0d157df426000000000000000000000000000000000fe66db078653da2fcd1490a36db9371039f3630bfa4d574cb700b19697c7194e8e44453e16ae71db6c9001e18392a76000000000000000000000000000000000cc69605c26212c6a088b9a5c2cf6024e46f035e4c64da67383f294d6186bedc18922ac891f742165e3f09fb1720d476283f0256766690c88df6cf7c968b9a96121d26d19672ce9adc84b699476a32db000000000000000000000000000000000a280b29948ccda96a2a05ceb9fca703dd63c65ebe18a0002cf1c63b8f64282cf9d3d4d73ba3a13426f253d09f83ebbe00000000000000000000000000000000146f604d1e90c4a14aa6599ff5c6389e426232a2dff39334f3390006f021f83500300b7b0f1585ad591acb1e0baadcd7145cdeae7fd3f7455dfd2ea9a064c135f0a0a36990ea34929e292e4cdfa0f4720000000000000000000000000000000000be58255d1f227af95dc9a818204d687064d62166c16f1de052aca69a37ae98c2a73a9a9cc6cf187128e5b86969e2810000000000000000000000000000000003f1155d7e91220bf0b80943a16a9f41e4def1d5f8ce44d95dc2f9099019a1d5e770158338ec248eeda7c5af412890cdd9cdaa979ab08b454dcb961e3cc4bb18f706bed93a72a9c1e105cd69c0b691af00000000000000000000000000000000077c3ebd0169da81bf07ab1bfb8770732e4182a30504cbdc8fb1abc49f31d698c17f68de1a6d8bada62e98e09bcb22130000000000000000000000000000000000d677a33c1590cb55c9c78afa455fe2b349c465e90537a73906343aef577afbfacc8e157ea6f834ff959f3dea5941bcf262f9f7a26353193939bfbbdc50ee35614a3c099776f08b21e0c4c97521eb8e000000000000000000000000000000000aa0a3898520c5bc19d7f3a8e0710585dd08419b39d9bdcfe12f7baa6b4cecb50bc0d6e877ccc2518e4d0254934669ec000000000000000000000000000000001376af22bb714adbd16d8d41ab503066fbe78f799aa8c1d8958eda9e4c8c6fbe119e592f655e0c3f93455e8acd8a2bc14f0d2915e82c9a69f9e9af64a2c5cacf61ead492bf69912a35ad6a316f9914a80000000000000000000000000000000011b1300312d0ad0352ea153746f051816693008f2d0b980974bc354996ebb664e910350e28770192f59c053f3f2bf00500000000000000000000000000000000125d87c441a1dd88f489514b1d550387aaba857d5a6bef20acfdc0afdbba3e98c2e0aee0528cb78970395a9da853ffba25ed3f13198b69604c08b414562f67a67aa8dd4a7bd3c066874182d21ed9004d0000000000000000000000000000000006a05ac512adc0dccb74c7b4c2187763a6ba8db9e290cb0efd1325b7a463e0e14a3e7463b5cedd732527dbd131246c6a0000000000000000000000000000000001c1b41b6d5c823c05a5d6db55d7068409f5fec25986db6e2689dc6ec3e0d85749db6deb737445c5feacd69925c5dfc44ae188cc115e9d492be64abefa4bd4c93b61dd42a7d213e1100b8108611a616300000000000000000000000000000000143d22823412da99f7b87a794662bded7b7ebad9742e4d6fffd471b1bdc748c6f1b5bb395cd0a79c7291b9e8081825ba000000000000000000000000000000000f2b98d54e293befed0a97667791ae35494084229b2a25494fbd7295a04f03173a52efb8ff9033c4615ad1185d4e9032eede725a693277356ce71ffd7814a77fcc30eeb3a2b8863fb91ca03da1cbe37a00000000000000000000000000000000172919c33fd97de83b30740356c2bb2a9c97c3616d9f80a8d8266e07a1de21ad974ea796d3cf56660fc4e0df263a27c80000000000000000000000000000000019afdfd10bb736e8a6596db59f4f9a8244e585fa81ae315a768c8d91716de32d42fb75a57da238dc597885f083049a769d0618f898594b23ee3754fe390d6bdfa7d47fe749d6819e306935c1eab6b046000000000000000000000000000000000a944d2667a10dc5892760cd3e13289785f0a5a461068d70960e6546a0543474f92d68ecfa96efd19619d976af2ee491000000000000000000000000000000000a88a16dba3fa6cb5ef21015b18a14956ec9ec29650929fbd0308fa59ac4aa389aa2e306a3a68fc04e062367a72b3f861e1c9420cfa91026286d7f986b538c13e8c97893995485308c69f053927f96220000000000000000000000000000000014118a990f2649838954ab911e795c453ecd0d700077a5fffd1a4f303087074d595caf1b20399578ff1e23a2cada7e5200000000000000000000000000000000145bf8164b82ca5f8f93d89ca65a894c6d15e38da2cda296a94aa1a1efddc4d2663b8f09efc3b2d78510c4dceef8558fe5095ed9a9181aee392888e3194ebf9c4a6d87b503f4668bb6cc0d290880a44f0000000000000000000000000000000012db33b91d99f44cdc785470e67a781b4a72ae2dcfe4555efe5b7527b9a76de8e492c4dc7793ad948cb46070eb1cc5be000000000000000000000000000000000ecf06e454ea574dbb9ba6209577425a58267d01f29f8706d06018a9caac994d2dbc9c6ca9fe3ec01aed9aa2ab886c60dcece8ee33d3bf3188574e94a889794077035ee92473b7266d92a3c018771b4c", "Expected": "00000000000000000000000000000000003747597e0f9bc39306319018fd08bc936c4d37cc6f84ef296df5a36cebf0aa46ed35ed215ba89a247174fd72fc7c1c00000000000000000000000000000000150f973b61f26aca79a3f7d1705999308a96136b08673322b4729f16b471e38f27e66996e2921cfad0cf889878c2ce27", "Name": "matter_g1_multiexp_45", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000046e955a4631d1a490f92cd40ee0a31c096210ead2b307a7aac60e84efc04898da5d4d9767f1303ad5652a0e377f0738000000000000000000000000000000000afd054be493fb26c7826c9c1f62365ebb28ed853bd3a45d266f4c690a24e179b2eea5261adb0bc50dd184c165231d2eaddc845ad867f1e2664ef0e78bced8ff6904c5836e7c63ea3a9c858fd7b710b6000000000000000000000000000000000ec3c20a24a5f9fa7c5754007407d1aaddaeccf3f7956914ed3b06dbcff7f15c6d487a3b71fa9aeb61352698a93ed14f00000000000000000000000000000000086f3cdb1e21cf60a7a57e7ea7e00b4698a837916eb1f6ac1c6cf97ef2abd48292ecfa471ba7d9b8688b6f0dcfb6af62c78cfc6a30cea34d3d3505f4f897631f67ba77913734f6c2895d871fd6d5581c000000000000000000000000000000000769b870411b65a1a86dfdbbd7dbb65feb708f9f90ee73153e42f7141cc660c50f41835ee44f58c7ffa136b944e84dcf0000000000000000000000000000000005f0480b4a35dacd304d8feca77f8580f66396a6434af09b98d57fd4f9f781012f3900407a49f4e0aca8d3ebddd2a7bea1e40df9e1f7c84633cb3dc2223296887de7281ea66c5e1f2d5816334f7b280a000000000000000000000000000000000208f1b01599c969333ddf9accadb24f1c8239f82f5beca72d0d6d823b59a3b8c450e25a2da32b5a8cf8c0f47137e04000000000000000000000000000000000054051408658f025572a45c731e81f3fb88d741a632f1e2acadc48a1f257a69481c9c11e655c226d8e0623d34fc9fc158810b9ce0020904dc1903338089c30e616ed0be03741572ce46946883874f4ea0000000000000000000000000000000001738659b582e3667cee963fbea8cf695daa6b811dd808e724ae77db2060f248accf645db52f9838802c5322d993488e000000000000000000000000000000000a36fe571929153dd774fdcbaff2b924cd3f0ab4aced47d22a2662ac6f415b89372406c4ea5a0a466d4a4c5cfb02ad7d93e7702da2ff9f3f14586a9ae80c8713743d61b915a7c379c1faa1b151406a9a000000000000000000000000000000000c70dbc5f707fb949a2e0cd57e0ba6a5d28a2d85affcb55bdc9fd24a3fe395bd78b7431175a629475c0932b769b55d6e000000000000000000000000000000000a49fcd19bde4473bb98384bd63e96508b539fb80e1e0cd9fc9aedaacba0c36d705ad16a47f345c083401c6640675823eca54e365faa35d2c9be259b53a1157b180a373813382f47c9154af18a2d83270000000000000000000000000000000011236c10b9622f4e3d468d91ba9c6c072be74aea66f5bd77411193bf2358a03fd47d029dc7b50343ef72fe9bc08c7ea3000000000000000000000000000000000b923cf7f612e800c2c52b51203e12a72d6f106c0d047d1317711954cb33d44678f509da27f03dcfa1d4482a9cc2eceeabe2079ecb3618de3accdf291d9479bec32bca1f9fe87b00b64a12d735f5b9a5000000000000000000000000000000000883a868a58809bbe3ec9df32f8b963030d71a3ae97250ee9aa8446a8b1a4428324f22fddbe77b338ca58de26b1ad73f000000000000000000000000000000000a49fcca1f052e82fef8913b64268a33ef1d2ee213ce96e60a3a1842aa304c63cce711bba8f523302d9252e3def20e3fc541a44756ebda14aea95f1a1d05e7366dc0285305116b907fc89e777ce45f79000000000000000000000000000000000d1ed017ef4702bcd3bfbbcff36000af6a1d26ab363e68ea5629027e0b90352bf1d8e03c13a7955da6c15507cc1c9f47000000000000000000000000000000000e09830e54fe9eddd416479a1740f6f1b7693f2d153d322f27779b16bb6451d7657df85a55da75a4aee0a2e33b3a46e637d521d31de52681f1d9bbf64a12f9bc8fe0ac61aaef14d7e8d048ff09e6578b0000000000000000000000000000000001f902e2947de38842c207b9029743da51ad0dffb61615b22c73d88739d80c926c07f97507ca3bb830c66661b397dc1f000000000000000000000000000000000d8a1d29f87b3335287142baf613fceebe9d4765d29e46bbc9e459af5450256295538b49081d849f3253f07357451b6e4904a876d4ac1341e88fc4808508c89c19dd74aa8fb1dd7673cbc2d28e7d920e000000000000000000000000000000001846aeb64ead3a9b6da3b6f5de234fdc98442bbdc402af2d016c9dd25de8f9ca09269a3f01a812187ab7427b2bf31603000000000000000000000000000000001775e3fa3bd35f96faaaf9c3ce1d2391f89340f8d533e41a1d637fde7a2cd7ad997e50a6e9437468a1d5940e4004bc9068911b04d8155f90c7c5c0cb519ee6ff14c0ae27ece0374f30fa148235e8cb490000000000000000000000000000000008aff7ad8d3e83ecbf5c3fa2cc9a5328531b1dd6e30b2aa618aa087281202de8f4d356586d64082fb039db4c9ce6c3e40000000000000000000000000000000014196e8ec67e5f0093da2b1233331bf1e90a8fe1db52b2629c0d25e3c181d595c03bbab3b399c87236d2353f1ea6bfe9481e894ecd52a252cc76547513e2cf0a5cc6b20c3dc9c64c7f34f29a488258ef00000000000000000000000000000000018ad28e8d8c1d9dfd8f8cf4e60214446a988285005d92e38d46ba32f619e982cf96ab10b605b1e378d7b46b54282ff300000000000000000000000000000000029807f431a2101ac341241af021ee35c47e0ffa1975c982f75c10ebf3ab9081d294578288a5c308abb074b3e3c756c672780ab3c48c8a102469799ba2f70d2fd9d324cf558a8c8b49e2ecdb71ae1c9b0000000000000000000000000000000008cf05c3d3bbcc63ee761f7cab1494299a3e2274ebaebedcbae5b35ff33bca129d79f73ea77152f19cc67fc66ff774040000000000000000000000000000000009ab576dbf0e8cead9450eea0a506c83f12d09fd2267715a76eb46602756859146e96920174dde3a361636986a3d38e084ae1de8aaf498bd2d91bd828bc64e56482b225322b86529da703f47289c6567000000000000000000000000000000000006f62bad30339a1a912280ba5d982bdf0d3c04ad9051555eabc32eef501e80d996f183a990ebd17301ede13db85f6b000000000000000000000000000000000b0c4bb1a10f8a281b83384ee05be2d65d6dfcec36253b9101cec7f1193f8fe3d29333034de96dc62d18a97153ce1d153256548db55ee9de70ebf6fa347d81bc50494b937ab1c3079977234a34cbfcfd0000000000000000000000000000000010afb2bdbea9f6eb0c75ddb0a4404116498920557a5d416c6d855978e47aa90da70f29519ab244079762fbf965edcd070000000000000000000000000000000000b8b62a1e52eb3805056576810721cfcdb5b0d94759a11862cd7b0a88e3ddadc0efaeccfb89662860e187f8af2039f8575ae146524544307ee51e58a654d7324983a87e1b37d46cea1a4ec34114b44b", "Expected": "000000000000000000000000000000001422eeff2bf06ecd67e0b310e7201773577a899fab8ee7c5b6ef5ce1021c9371e106c49a6b607cb3d58852f0e671000e0000000000000000000000000000000017ff4ceafb7c286f2036e6bf47a15e6695beacc7b988dc35f8521459203f69975d297160dc67fb88c4ed2fd7b61ccc0f", "Name": "matter_g1_multiexp_46", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008fae47827bf8786df7e9f8cb38a8e01354ed4417a05332e45a94f93a5ec61f11d517f5554d5444001ef2991f2e7eed60000000000000000000000000000000005cd17cc813442f45e7c2fc542a6359b16db4de7749677b1575f12ed694514b3569b722ab257f7678a230ca3ccb6e0ed1129275f3ab3125db33d43b36c7de0ad60a6e9cb4457aa03275caea9635f0b070000000000000000000000000000000005aaeaf87735d9e9895e8703177faf8b11bea34aaa045852c57e9b86f6283332ab633f3e6947b84784733f6f73b289580000000000000000000000000000000004957220d5264c0ff61dbeeb0d0d51278386227a9386756a042df89fff5ff9a4d3e3e52293cc94ed729d00ed3e70b1a32dbcfd8680258eee451db60f3f42f02f388f87440d00badb0a725964042515c900000000000000000000000000000000049bec519df011ae5f19c85afb3301f41f71119ea6cd9eaffa9a00f9cb901681eec5f3f694ef9b4fe768a25a55afec560000000000000000000000000000000011414953ff3fec28aabaf3d62236d6a972da12c42102911a3ee8e88e188970a11487df719a739201b31fcda4e52d7c515a6f194abeb6b7c1c561aa820bba658f0277870e2a32f972f9d18ca361929b010000000000000000000000000000000003e5345484f59b269fa25b659e9a43573d4191c3c02f5f94534bfcd63d9abd57b2f3ab92f9fc746a852b185a6ae2c778000000000000000000000000000000000b7d7648096606b0c3fb93627e484eca017b95b27a8098e5dd332bb45171793570c69fdc16caf5b16e65f68c817de3bb579450b7aa155a3ab61e47e337ddbcd17b197de2dbb76008cfaa09d3fc806be4000000000000000000000000000000000c6afd550c55cc41cea88e670443d97c6419a295918dfde1d5490718f18ccaf8fa0cb68c42fa2cf583284cc70bfb0a11000000000000000000000000000000000f88ec67e9ba0e169ebf93fffed1fb14dd1aa3e1a2fa614a140c1a2147fcf051457cba68043efdb1b851bace84078fd64be94f96ec4a3d4e028644c63b2577a9ef849b403acc55e42432c3063a918d1600000000000000000000000000000000143a1884ecb4121e2c1c0cf2998b690d7f01aa3deec1a2ae5542647a3721f7be47c21ca071f92d74d9c3d9027b56d9c300000000000000000000000000000000113b01f060d10d95776b35c2b294216f768a323aececb308d3de24299dc12e55fac82c3134519456660a3465abeeb5950983e6618e9e4208cfbaf647592e42b2d30de9e74e4943fb2bb49109a66302aa000000000000000000000000000000000019a5620f3241d03d63ccaffdfabf7e99e784399929cfc3218d6b828d7ce137c9c6cf3ae830630fcef3cfdff705490e000000000000000000000000000000000114347768e5c8109c1bd47623eb51764d4b3f63f333677bfc28b143fcc1142f4d9094b2355408cd8c412a37a4579e0706615e300a924ab962e0b7fd0b044cae9516d96de603ee80695718c27d7fba0c00000000000000000000000000000000043c0f4b09396d4b14deb7c5027ef6cd2d426fa4f93d4ba9c3647031d557a759e3426c113fa3949cadb8b98a64bd69880000000000000000000000000000000017efb6ab8b2eaa0768bb740cc8a4e5ecbad81087cec2a307e5f53b5f431d19e3467dee84df6c6453ad4566ffa2380c9ad77d3e9e64e00b9356cceb62209ad48fc89e69e2214aad2edeba18122727363900000000000000000000000000000000140f0efabdc88a109da948494a9fca5ff790ccd6c629a088cac62e043e00e38c4281e49173ea0e423152c5b944d80ac10000000000000000000000000000000006d3d01cd44e56a4cd62d88a22c701b42c116082e92abb629e64040f57a240d71718927aedbd8ddef910198e1bb09c6841f75c89ec973f65b11786e186f4d42ee2e85c40f29745d9f428af08a39d5681000000000000000000000000000000000f20ace44f4b981adbb3035e450a656ce3d8464fbe4c45b9f7035c00aef11e389cccef660dddc025786d4f9216ef60c1000000000000000000000000000000000d5fb0a9e9ab03893a9ec61675af29e88bb30f3b61e05d7c5a3d823159bf8e641ad894ebedba4bd681df789e0c3d2547c70cfb76a04d1a9e0d937292e5553ef371e20d5d3dd33611edc0da178e2e4a16000000000000000000000000000000000dd38f99872751b4571253940ca588424190bae80434a3126a7ab5ad1383c55ad769e09179d148d151506e5cf5007b3f00000000000000000000000000000000032b2b9a8b13acb6589fea9e8b8d2535285bb32ab0e519cf8c63ea3e25d58cea7f9fb27481adcb9475abadd6f1384f4f8db878b7f5fe817599add432ecf262f19d80ac834bb0a0f983728f6e2c189c88000000000000000000000000000000000c696064b7c9653cce986e119686b2e01216faf8098d494bdf6d302c4d176b24b05bfbd70b9ea3ecc16312f899f887180000000000000000000000000000000001b5b8d333dbf1d84feaab7737d3af13d3995d3ea976d9ea1cf1d005090a809fa6c210a6363495c2b22902442fc5080b70751fe88ad289c91dfcd3c3c61ce1e33f4146f03fc0dc77cde9b32b51c75fc000000000000000000000000000000000082bc6c7ff7924b88b4a6cda58295d050bbe8087670bc6036b5bad53247b803306ea596ee0689d805e7b4de65a634eeb0000000000000000000000000000000010a79825c716dce1572e6e8886f1c698d730327f195871db7a9b6690e9ba1dc38e8d92b34ee32b33705edc021f42349184bf139cc0b6ac94697b7dc278063a74e478d47528da3f84f55fb0adfd851d09000000000000000000000000000000000cbd4ac75eb0928f366d3b99e05799bf3d9dbf187e557f211af5ae514101961ba750e81ede07cb5a14c49884a9b55b980000000000000000000000000000000004fdb80f44f89e6cb44b950735703653152466f30a410109a24b555c4e6907b2c1d4f54c9c0d2b7954002a74f1b65e23d19d9496e7ebca44354d5c6e1f6b8211eb06ca23a6444c307f92f5bc6dcc2dbe0000000000000000000000000000000019a41f73feae98fd65e365912f5bc6c86142380b2633feaba440a6c635ce2bcf7f871f1f033f93f9f8668360da3898090000000000000000000000000000000005bd1afda6a52adb550fd9bb59826bcf492cdaae8e9600e517d77832a8f3ae8777756421fe7640aae0bf07518ff695a66940e3509e1fb090fa787fdf633a74380cd5de722678826224641e46a6e920df000000000000000000000000000000000ce2a96c1ac3e2cd01ee4a20258436b62dfc2efb96a7148cf887c25d635aded48d18d38da7347abeaf72d73d613fafcd000000000000000000000000000000001773ef3bc5044059bdb5100430d4936f328cf876a48bd30784c8d3767a119bdbd5f1f97d78d52afadc42ebc85f912f0f7b27d21c1d6e06d9fba7b61fb87d364a7a6252c70b8ace2d3679ed87ce0fcf7e", "Expected": "0000000000000000000000000000000013fcc5da42975bad80f3447a1ba05d9c6a51383921164ea3e93e983e24055f6398fe773b0e7a50d98568d49de36e295c00000000000000000000000000000000188455bd9ca4a0d3174cc8f0794d8c35356f697e62265d9e3d8e72bb2d1450caf5bf79dc5ba78a363a23d2ad58891165", "Name": "matter_g1_multiexp_47", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000466047055d438bbdade1bbb00a7bca3ec0ce30b042e56afb9a25de1407d5937038e01e3c07595f46bd00cc8202d2200000000000000000000000000000000016bcc696716c21293b68d4f29d9cf675d447b726d579628417cc457043186d54f27c28b47d2e430041f9417ba323109dfacfcdf87c6ca0506b070abff83ce7812181c31729cc534497aa8dabe2433513000000000000000000000000000000000e8eb8fa4c0c2c86d0e571cd4708361e606c9fe789b60e099278d35d169424721bc789a6048774d739a5ceff56adc668000000000000000000000000000000000ddb7d2e6094f1940dc0f41509bd430163b220aeed1b8c0a2b90e37f791410a35d682b75223b32febc95500c7006f6626546fa692d9cd61895526282193c90148099e2afa54f7903a5431f932bd5fa06000000000000000000000000000000001080ce47aa1c38db9c71d1834c0b5d59676b0d938ba55a62daaf50911d23e286b3b813c7261bfc19e95f3bc8ea3b91fc000000000000000000000000000000000bebf539c3c03dd260d579aa853c28ae582b9c904ba2c56bb1239aebbfae10c05d9e33c8e1c2bf90553025d3279572fba9c1460c1cbb2a552e3452d5c5535868ee9c2952ec3fdb52dd826c16ae3d00bc000000000000000000000000000000000ba078b44f92e90fca4981c66e89c5490b34f92e4026d826c2076a995269e4d4fcab419a508b530793c465531a631ead0000000000000000000000000000000007c19bb972c27c00b5b1a8731ed7dc9af8270187cd26b1b9d65cbc96688fe2f0ae86ffe753a50b4500a46c01a75a93032c36204b6a005a64819b06804eb94c311d78977b557e7acfa82e147b4d6ec62f0000000000000000000000000000000009b70de2dbfe9af8ae771ad5bf0ff962c9f906a3637f992b08946c864b3d1dc996a2ff918ecb3c9648ef9188b15b624c00000000000000000000000000000000186a9f4c06ce9d5a969b959e4b17d4428393d02d0e7259fcbfab8898481bc97582ccd0e1d87d1735e28dde10a99b683e9160c5a553479a10996704c3eda8e57be88eaaf5d1efc8371e7e10d7d106e4810000000000000000000000000000000005b7dcbe86bb6e6b328325141c1da77f8af531bf1463bf3c8c94812784314fb13e457fa461c1c51aef0721c5d6ceb5e9000000000000000000000000000000000d9d1ac39a5ecd61670c1b0d061d93a198eca1d294d2e64c3f9e0a872e7c93212ce7835ae0a7fc2a42ab5c02192d70715e5a50e5dbabb7a56897935683f80a5b16dbef3c23461e241fbdfceea38e3ee2000000000000000000000000000000000741769993f2dcf5869b8153bbbff2e6e5d429fd2d862bdd590fc50a8f186bfb105f5d57f736b07d919bf0dff0cf4094000000000000000000000000000000001917c91f954f68c6406d6dc716dacf729a8c4a0de73e04cf0ce554eac40d750fd25b289127023af299c6f63372c01b7d4a95b293daa2761cc456b9667517f499c4d9eb9eb1d82237e7a7819b5d44f7a2000000000000000000000000000000000bb29ce10d6e571e62611364143e08a60eee5ccb13dcb77f17fde5829ae5fc025b309c98f892aec1fdedb7d1920e658c000000000000000000000000000000000ab6fe2dd5eb1b90f15a3632749c351ec871038f0550dc54cf1bf2575f80ecb8a3c0d3c1a333bdd803e22fb6bd3e64bc5e22ef32d111261dfcb5a2e8d23c8d920f013bd9602bbef45e6d4e0909abdef20000000000000000000000000000000004fe17772d4205d7b1d0cce0db3404119707893e20f6b27138918d2cb0e4de49cd5df1258103c1fac903c1a443cb62530000000000000000000000000000000014d8246911dc40ecea823f02c0e17e690a5f66848223218dd1735cadca1a0ae89d7afbdc727158257d2cb248323c55316e687c0ac8fab70de2416642afa1553bb38183d2914050602874491057f78786000000000000000000000000000000000784a1b282846404f71227064ff1a97766781900136d4b7ac73bab19cf8e03b449ddd35360fdb6dcdac80e335ac5cd1600000000000000000000000000000000074fc137d93decad1cbd4b753fe9ef3b8b3445c12e358450ff494a1fbd6e192ad7a4812358d85f6e3cefedea3aadaac6428f1a27ea15135f044643dc36a3f9c2b4446a3136bb11f696b0a430a7454b3f000000000000000000000000000000001661e6d386aa6516f08decbbac9c1c3411ae9cae62b05037dd626a2e2273eece64615c54a4d73e09814d497067f9e6e30000000000000000000000000000000007543030f8995237f65cec9b69b0356a29133d8be27b5f79aea580955042242c2bc1c6a01539b6b55ec9af96db60b394ae21ad8a6c9d75b51133e81ec34d66ca70a52529c5c3a2307b0e8d6f1c5e7d9700000000000000000000000000000000148597902b3ffe4ba8a5f9012e699a3cf189f58275557d98d132b72d3c34e5faa0953ec8cb10b0228a23803b70836e200000000000000000000000000000000008741bbe372a1e5a697e7059a9e80de8a012b0cc7b12c14bea098c16cfea154204d4e27753f1a8fae0e618223da14fdd88a23b118179ee2c34ad030993a2d2d70375311b95254c44254a32508abcb612000000000000000000000000000000000cfbbd4632e8998ba59721686310ec115b98ef470c3c4bbe427495d6d95d06ec6180e64b509c4c06e32862e17939a2cf00000000000000000000000000000000060042078794f4539a9b3e3127632c3c8b46322a669605d1774e995c5d82287d3d9be51690b4b5df6de8d55b20941dc630eac099ededf0087275d1af828bbf79ef7fb0e77179a068f2ebfe4c749a98c90000000000000000000000000000000007e67da2f320e1ef0d3afbd50634aff753a2e2104ddc03244a0c79eeb117ed1beb7316f7c5e116bbde47c53d47e725b3000000000000000000000000000000000b5399ef864331db729724870b431d8dcd8d3279cd00a59de2fdc15bbdff2035794025edafa21fce97836e93b41aae067e8dcbf708682225fe3f71b7a687da23de5ed188e40585be05533580121325770000000000000000000000000000000014bd7f0effe81cb626f92422ae7900bafa7f4c2d51d4ee6926eff68b60c7f41e667a57bb0506f7c36d3549cf154f6cf300000000000000000000000000000000050aecd688a63075feacfd29d1ab6430176dbc5ba6d406636a6650427a9e0b0d51df51d8dca27665b0b6c60e08d5b087532cd42a9b698a2c2d22b1a620a7ec60daa9d1eb8ac36894603be7bb9b5e37be0000000000000000000000000000000009252c5f7f7f3b36c5dd32991641c9f8244579960fd2d07a8641b82c5cb1768a36f4e5ad623319ef3f7d0c670fee58430000000000000000000000000000000018e432d33e506ce42bf3d873e36ed6ede0c9de44203cdd453cf91c42fc2ddaadaadd2e3870c5f5c171cfe76862ce44dc3ccd5e19892765e549a63238e664c732af781fddea558a117cb927bc4a1aceb5", "Expected": "0000000000000000000000000000000008b38b298fe2dfaed042b35ce73c76ece7537fe5181ce647de756349a8dc48d3296e243fc7613abb10e254e2b0197d7a0000000000000000000000000000000018d59a69b976b1bacdffbea68d523da3fd0d2910db0a509760bce56bcba36a55fbfe11cdc14cad50e6951ffdabf97a64", "Name": "matter_g1_multiexp_48", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005d929298c9361736ef5f7c83b6a851c344d72b7bb92a8201d629bf9bc1e66e4db6dc9df64ffb41a11eeeba10be52ec40000000000000000000000000000000007962e1b1b823b770b44eab51b3b84fd7e0e57a2a3f7eb1ad9c3ab02677376cee08b0a2977552a0f9399584b576f17f148da17551b2369b723bf932173a9167663f8389d2461b763d6a061df78d7ff1c0000000000000000000000000000000013283d9b3cb5ca4c3a39517adf466d2b7fc90f4895a24effca7ebaee4df8735c69993c7cf2483c3480cd2df4be04366f000000000000000000000000000000000fc94dee82225161feb78f2a7c951c41f43ff3c1109a824b56c01854688feb86e240c9fa48534809354e74ca8360cda4def52379c8b9e7c24d971c3456b85b51a63ab03761ec66c8dfac1018833e05940000000000000000000000000000000000fb727cd02c5f69af676f9cfa68cc4363cbfe5343e304ff5180ed1f57e6928fb808539276feeb1e492ae2455f65de0b00000000000000000000000000000000082d09bb2e1f1585933e1b9076711803e71c2236ff78e83f5dae6ad492c1d723120ef64eb25c8e91486d102c2297c9e5b2225be6985b9c8fa59a2890da56427612a4334937761e24a33d37f0f951a794000000000000000000000000000000000882f34897651c59970934848ba13e815710b4952dc0ee1abd0e04ed82ab399ccfb16ec966d010eab51e5fe514af91ae0000000000000000000000000000000017a32754dbdae7a2541eddba29cb8ca85a0c6d189f9bbbfa24d477e9f1ec2ab8f7dd2a5aa7a596d3a2af916ecfbdb2c2a64ce8ad619276bc7a00cb49faf6cc84b917ae6b37654363f5719a727a220291000000000000000000000000000000000db9ec112ddb4a9c6e371440d0c79bf043c5a3c6c6bd613dc031ce9b81b49a32b006a165ef29a8e05f019b76b3cf520c0000000000000000000000000000000002485dbc3c3e2aeafcf18dfecd842ec48b2e79d3bf7936917df759a9ca2e25fc3f137eb88a701f5fee1ccbb06d5cb08c0b891d638d7e76e0dcb230b1f9a7c3b35b35193c43a6c86f345f5a5bc9c708f500000000000000000000000000000000100d1fb78f53423c8cd60de5d39a004ee1c99b2fdf6847a62c73c33bb3d317ec06afd6424359481f8ff2d0730cfc9095000000000000000000000000000000000211cda7659f1e848c931ba1f65ca9c6021067ca01cdc8e87f5c742006f6dae39645553b69a4ae00ab6eca16afd0bda7571175eb91888222085fc2dfe0f4401ed6a1fc5df86c0c6b8e44fba6454305bf00000000000000000000000000000000004b07c2cb575e2499e333140e48446fdaa00368a74b87e607e285781b42eec39d1578d2e34701ed28488f160e9e50680000000000000000000000000000000001c2d66d28031aa91f6aacfdd80d222b4a0bc699a9b58b7f5d68bb9ed0a297ffbec3a6ba968f225732879f2f9907ca3954c9e7f7ca14c66b8431e25e6eddb4f20507d03bf124eb607957ca2f43a0c17b000000000000000000000000000000000bfa7f8b7783780a2b0f5b9f1b10da77cb5904618b8c8a1d062fc94aedb0fce090d8c4e65515c0d05a471f2261d0063c000000000000000000000000000000000f45747e4b0bffddaa13c7e03b6930ec474735b6a0e779d3722330828ca26a07bb731a5d4884ed3eecc710356a00a897000579e1ad83015c8f02a9db5c38d0220368a80b309ee45bb952cac824817b6b000000000000000000000000000000001245cf167d097de0753d29ce6018b7777b1befe43b5709e8217b9f380d958e3e9298347673dce432e57338b313e84950000000000000000000000000000000000d697bf8ec405e252588e3ef6d979bfa60ba174da03266c3a2efdac176c1ec1341d737b16d53bda6ddf8be6e1f433ff6909a45c8b78350e3ca21697e9f56d5fc8fc2a01817b78a7f5daeda487768ed1e000000000000000000000000000000000152d7f1e704619bbac7e594be6e105120b76d9bbc711ea40beb1063c2996fad70bc8f77a915411f3601e75af2f2059b000000000000000000000000000000001622a6467c13c534ff1fabaee8b29452d689e7f9e118e050cb91328b8078ef97fc82321b80d28d0c02f2b0a7b66f04a36d4e2277da617f0ad530b6209df6264e1288122b1b4d92da04fe334be17bd8320000000000000000000000000000000001c118fddc8df59e2d4ef9865d69cc044fcf870f296b009a2a471b1f74692f99e392b455b8b03d079b1f39b09e5fb720000000000000000000000000000000000032c05dc9eef5b55857956919f7a51b5f5225a45ca12d80208231304e66c77b24707a934cb9814108b44427e658d143dcba6bed6b8c42240c01df5fa0ea81dd96168c6d98ee9d5d4653edfa5172eb280000000000000000000000000000000012da4a2c89951f85757c59a2630bde25c30af955448c972d256f1a6a259793c7b2bdc3f8734f4e312897cb6a3550800d00000000000000000000000000000000199939ffbde7b14b5f23eef23d4a660bf3f561aed38205e68d091ddef9679df9230a59e8cb03212df2e99788fa2595bc23d168e01657e5c2da89a27e513bcbc6620b8c6082bd39880619bfe2b3a7317d0000000000000000000000000000000017a61df7581a341f21da2d1768fb41bb89847c88b2a0d7b61aa3275e376a46672dcb919eebf20b242ce83493c83335680000000000000000000000000000000013edc932b7755115f530d1d044c4afe71807a6b9810f555432910b54b0fef441b4618652fc4bc2ac5b789a75d2d276aa2a76fafc5e8e33852bbeb7ab8229305be84f5474427e0c6d2ed35c7bfe99faa1000000000000000000000000000000000c73683f328a0aa252c10bc3fae9e786ccf183f1b606a4596094fbe10630d4418a527509c93d23e62dba263d86f88951000000000000000000000000000000000260c9dd70a1ddb422491a20293c18e4749427cbe9841aaa3370533b6e5d6fcf882f8bd68b7161434bcd5060716fdb97e3c7e4e95167faed1391e269785918a207490c6d186bf2537c02e52e414d564e000000000000000000000000000000000bad0e395f46f714ac9d40865d588c06adb54b12439bb408a9d546b0a8ba5b3098c242cf5c17d1e40dcf7b384e81b444000000000000000000000000000000000e595304cd73c8c2a0bd1dff70e89edfab22be69bafa16877ecf669ab1e1160c9719952bb6103f31f2ff028cae0f0ea45d335e3d96a9b25be7f3916e92fffd75abeef5b91a1ec577ced52a96f6a9b10c0000000000000000000000000000000011f0037c9bc2bf953a3eb7d8a0a3c8d991e6eaa5f13dc1978a31f0eddb550432c70aad096cc0b904ee540e5d2d1ee4730000000000000000000000000000000004f8616cc7476fd0b95f7bbb7fbcda389aab60a88ffba3c819868f7ed6cf08e7c0c7da0958bcd957e0429b9a7fe120bafa563a70780837ffcf9a84456f0b4f6eda0d60cce6a8538ba10960eaf17362fc", "Expected": "000000000000000000000000000000000e87aa419d686c55b1ed8ebf6e48d8f218d7198edcbc7db0dc3bb9581bb8dbf891dc383f27717536dc5fb7265ce1ffd8000000000000000000000000000000000a00646bc197307a7416aa9e35db9ce7eb81d762a065cf8d2e07f6470e424d7d59021be049b36eba2e44750a902f3124", "Name": "matter_g1_multiexp_49", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005d5e69a8876b82b1de0b2d2a0d808c739b361d1cadf3ebc9c6096afbc19169f237774be6882caeffe47e86e3b8a33710000000000000000000000000000000017bf0fa8c247af0078d486e1961577d7977d0b4258ada3e158822d995188ee374d900c4d8b1ef4887fb03d8f6a4bf1776e2ee781da12b984e7a08730a60f50c41cdd7c7c8b3f1f30f721923ddc34fb79000000000000000000000000000000000e6ee0b0c7bb7c3f62284efda6bdbaf38bb5a72b4435b76928c5640fedbf9d4144358a20629403359fef5bcb99a795eb000000000000000000000000000000000e72324fb2decb0b0c7fa18061a41bddd6e2c55f901554de9be8ac7b2263631fee8bc77773318f6b13b2db7eb1ad0f3cd51e0b65be993ddd2892ab8f47eab78352b177be4b3fb68f47c65f5c59fa866000000000000000000000000000000000102df0d54108666e7aa611fec5c09b72d269c72e6fcee7787ece5f33153a3999ba5f22adfafa461aeda64e113b795dbc000000000000000000000000000000000b77ab3de0a2d91b8c24a47a27fbc5b2281cea40d87872010b94e895d9589880385f82ff53fad55af4f4e462df1c9ef6fed4dd284df98923bfc3c41496d6e64a10815a8c474275e0cdbc9ed26e92b0ae0000000000000000000000000000000018e8fa3c5bd83b51b1af197f0dee78e5c912c742df0cae1b59ac44fb2b903ad5ee1fe9750a034d18141f09a2b8298f850000000000000000000000000000000001526a80337eb938420cf2e825e5bcf3152e90e448ae3b40ee61929117d35f694eb5ce9133b2cc664c520fa9da8ed65a7c36ec97c1eafc8a20a772fb7887d75568047ea32458b9ce74ad9ca0581299490000000000000000000000000000000007f11b03e06ca74a35cf702f19fe29facac855d7f5adac59bbb8c058b1eff7d4748c886eb08600e0484aa976269e5d0c0000000000000000000000000000000010a5b0f723371690f6ccc5fb346874e58071167947d45e54f9d5edd035f2d68b4ef9e301f26ef671634121ae6145e44e41b2c0354d2f7d92b05043f193b718d78b457ae76e19069c8e1c2b77d7999d65000000000000000000000000000000000db2e2ef96ea61075e063629eb031235543e8f39f012fd006e143eb137524976c5a81eb26996a4ec3619a7fda051df6d0000000000000000000000000000000015d39e93da2b392dec64c58e73740376552e69caf87ce9162801466e75dd1e25b7d5762099112b21411e8d8bc18806fe5615370a76bb0a5f64d61b97bdb045b9669f6a0b7644b101d21a50483d8b04dc000000000000000000000000000000000e048ef3ee3bf3c41cc10b89b7d0f8b3f27c89fa0ab25542653155dfb7f8a7e8488a737bf2f6dab558910c9ae98aea33000000000000000000000000000000001357eb0945e2c4933b358970184a21b3369dd7a43a88841e94c3a388681f338770fdc3a32862c3a52eb251721b2979e9bcc38cfd3c6bdd32ed1d583f2bd14e175d61448c627f195559b751aab1ecf7cb000000000000000000000000000000000c6321bbc74b6b3a9f0c9470461c80b1713a5092871dc54dd022d3ade73845852315b3e85b53b74ce2b31d1780939d13000000000000000000000000000000000cdef7351c2923faedb211e79a44e0e02ebceb8103cec2ed7541a54bfafe3967791edbeb6d4b0da1ee37b9a5d77ac8f194c41471a2e4edf0f688c2f032036d41ef5f8a966871dd099dcdbced8b37e1c4000000000000000000000000000000000b925015af89d42f155eb1f5104db1128faa23101fb9bc1a9757266a2717d50e908c64c502a8d19bb1e8c01dad554e41000000000000000000000000000000000fc8c5cbacca685c24188e8f936637c7c8010f6126e9b9b49e7d38191af1246c2a3cf7ca45bce6f1e11c404919da61c3dd297b192f1c907914ef949fd27a5ea5659aab659b83239c4433f7a4e24529f20000000000000000000000000000000013fa1374d37396bc60386d07a441a7d21fb808e3b2ea0c39ca78a6dd70c473a8feb972e2981e50cab6288dd80c40c06a000000000000000000000000000000000f35c2a2897b35cd7417aac29ade18f86d56ba24848aed78a31513d5115bd964ac6711c5f71736490195bd97d2d5b507d30fdb174a3f5c06b78cbaee5b6e7a4c90551083d78c5164de6bb45ee5de23c1000000000000000000000000000000000799d71ab5145a8a4726cc5567d99b344971eb8bd6248e41aae02bacc358f967475f64169e1828a66905e4373cf5c9670000000000000000000000000000000017c680c55af98789584e073c3caf32373f58bea6ef7f839f1d5c39e512058360efe80a884ef5822bd5fee34869d028d5aafc42f7fe6854866cb954367fa65c8072bd1b60173a2d45077421d6e25f2bb3000000000000000000000000000000000b4be422e3d3e96f6a6821c55bd2a37ba57de1bb59c8f4855b1f4b6906259de6be1c1be40523d5370ccc426b89478a350000000000000000000000000000000019212f598150b576c17c32a8f374db52c19431d7a60b99379f570189b3fa15edc75b807adabbed712268087cd9b89a8a106da5f98d5e7cd9f4a1c8d6e50ea2236c2abdf1e08a0eca54555a59bcadbc6a0000000000000000000000000000000009df46395e64ce38bc79acee751484ce1bac53c5e5233d3545df2ec776440e3f5b04239d6de10bdb086aa3c462fc6e820000000000000000000000000000000009a5c816b2abdcca7a916b1eb015b3d1c01f766e01264b5139e5a34a82a874c1efa8ef097d23b9e9441916a2f5bb17b4c971deeba2f757970bcd4f5548a2767bd6c43e63f4c5fc4b157ef060a1f45aae000000000000000000000000000000000023537e0238470f4d513d56d4ef8e244e3d853b3b10a893928547675c6b2d409ef6bbfaa299a726eb472067c48f056c000000000000000000000000000000000b48f21e01e72bb6ec384a1e8ab35db6ca032e4476f37a3282214efe483b672c34989e6d5c99f69473eb19e472d984bea5262a021977dd79ab96606eb24a7c5ed650300dd68bc79f4b8378f58c6eed490000000000000000000000000000000013f1ad33a2016874de5265565049722929528a1c66b84c1876f4e4396f22fb2583d025c481d4d9aa2877e0062e842d7c0000000000000000000000000000000008a11522b3e6982a4b46ab6f1f6b07d33443780c914d4bcd50ef7ebcbec6ad944ab88b82640971e890a363dd92c71531083b3720c20044fa41712039b6e9e776197391ef393c0935a0e9990fbc1b7a460000000000000000000000000000000019dfc9ca394e105c6ad51b130aab8a043ee58f26a0d8efa5beee59eb1543c2c3d33abb5cf2b23b0882a409d32f845b1400000000000000000000000000000000143e219edb6fad7dbd64e6aa82fafd05ed92bb46e526468cc3bc0d60c89319d3fa2032b5a617691ca2f136c9f7904225d6f846581848f5dbb9e8d220b881d0327c4f3f5d4b79fb2c4dcbdb9bcf44b02d", "Expected": "00000000000000000000000000000000027cfeeac9c1606a0942a95068faed1405a5cc9b5e631c25a0010ea14cae5b7a51b406fd0b8a9d9ea7be9a8c0f76c86c00000000000000000000000000000000106c07dd0d4e6f44fb1c3451942bf10060d16980f50b63005936e35b5add71e1352c48d1048e5d77cda79a09f86ff213", "Name": "matter_g1_multiexp_50", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000065d5c6ad252823540ff4a4639cd42443a3cccd808d40d8bd71379ef939b47c3027ba5593167b4dae93b62b2bd498f910000000000000000000000000000000012623162c0f025b16dfc1c7e5fa02f8af7b7fb0f2d42d6fa0fb01af45621f00faa4ed6da6f33c609448bc027cd6a4fd367c44f7c8513472b51f96d526422bac628aad4c40c521cd7cf9e86eaf92838fd0000000000000000000000000000000008b3c274f83f49cada0a1bbf0f56f6fe0f8a0873cf13efa42ff65dd6fda913102c2034a31a1a92cd154210d27b0120450000000000000000000000000000000001521dda1b2c9b42d7dc9822c64bec62e71c629d61e796165d9a18f8ab44056914fe5c8809f21663bfc70e310ddf5d952d6f95d4b6216e4226f78e4fa5011c9becf98fe45a17dfd740fdd0ef36d8ba9400000000000000000000000000000000109f72caac5abd41a228bd82b6649fab639e4d22cb3a9a060ff7577de61f33d32217a73014f5cc2c2a76582a6b751ae200000000000000000000000000000000059d0e9e64b10cefe03daa146c00c5040381ce6ac63886b5fcf19a0555a22a395a0cbe8b49c510c9bb7a308813fb482958c25d36216b811ee42d0ba629ab7a0f9ce7edd7234620c28e37bb3df3f042e70000000000000000000000000000000001c5e132707520c525045a08626e014a84d8da23dc27b6320d5915e328c3bb0df3618cbd7ace26834920d4a8757368050000000000000000000000000000000008f5127405631bed295596639ec6091e97f16ce5a3062831102be951aec98c9ad34721489f65e731026029ae3eb13aaa50a5c6bb6b87fbe5ebfb0d182d425ee173973c6f2085c556b0fe60219b9f3c3200000000000000000000000000000000146124bfbb9a3d253670be419f80998382895ad6237138044c55764f0d6fc07da5b70cbe17af3ad0c4b0dbe33f869e490000000000000000000000000000000011cadf640e78298347115e6110d3ed63dcbd251c48d3e21cfba4bd6859b0310041e67d212b54e63be6d68d2e7fccd83b3b4bdeaf6643ed159f4a3e23c33ac486b33e1edbc5a097a47a6c2c753e5299d20000000000000000000000000000000012ab7e51b87512007e1baf2f3c3473cebb553bc2ea3d3146358688ea3167817a449ab9a7e0b090e00f47846da7f46340000000000000000000000000000000000702c1e0df68bee2666abb90bd593a17a6f9dad02a7d66102add9f3a525a1b4f1fefa3abe262852fd5ca357d2e1f02fd1d18596bc392dd0b71e1216bbb20a0e5e2559a46789c36a146cb78c5aa8e39210000000000000000000000000000000014635c8b9cacbe976733bcb1245eea410008082f240cc8d8246200abc0eeb6b7444f38da3ad93b1e029b06cbb12d42f7000000000000000000000000000000000d9aa00397e1799a82d73040122515b98be82052b784a4b385417f6e260e555c7c0c48a32ca1fb28224f75f887fa4bf86fb3669c0789ba6a5b00f14c14fe2edd15d37a742c9e36cae9ac010e632d75a40000000000000000000000000000000009a0efefb9daaaba4b2beabf6c381c27df7c32d4021a4d722118886405414837cde5c55933de23ff6769a0a42933bdd700000000000000000000000000000000101c9941d98dc8a146a75f2fa48a8650b25ae8f6d943323b1c10360cfdcbebe220494660f4d6f7921fea006942e122ac06c2988dd6b8e9aa116eea4e1f63dacf100019844d37d163c047567e8e118862000000000000000000000000000000000e5b403702a229f36c9b83bab9335cbb4e39fe8f5e9a5aa4bace70361dd05c87ae356a40720c4a8214765d028cd161ec0000000000000000000000000000000006e447c61bce31b4843530e504fa1324657eba731a272ddae680c202a7d017ffdf0ad0656dc0984a1fa297f5e32c2740fbf8322f706b1972f73fe4e22a3dad29c4ede09163561b2810cfc3eb2ffbc7ab00000000000000000000000000000000135fb22eca115779ad1295f8c7f149a6eb4fe046df664ddaee976a15e11a7a59db5e2c44b4a82c8ca1d17c0043f41ee0000000000000000000000000000000000fd9c1dceb20e85ef80bc9ee44e483cd0e2714882734a561ebbd0982d6d08e9c41484ee99790c20e83d051dad0a1b1e04a46618381ba6b991b2edfdeafa67aef1cfea066fbffdba24db25385963326bf00000000000000000000000000000000040f65cac81c01f04db3e331659d6bbaac8fa01581b1bbfa62891c1bc95a67182d254650019dfa3171e16ce37deef29a000000000000000000000000000000000afd5e22abd5d5cf78764262a91aadcb8b807b2aafecb2aa3d3ba5a187304208e212e5df46a4dc48d6150a733075bbaacd05fce871e4ff11e7a4e834061c65a0aab7bfa8a0128d460a493337c6e63ebf00000000000000000000000000000000051046cbe6862c5e37cd2f3c14dfc2825d5c32de69b40f29140fd31405615edf6c116d384bdf1552a33fb00c6c65cd97000000000000000000000000000000000a61a19fdfc994105f03aa3e1b907f5177409664b2e50243cf7e0e6e7e74c7bfce582929e5670a351b3d7b4034f101ffaba9e37ae0dbb733af820743d8e307fc02a3ce9b40032b16d0e9466903de9caa0000000000000000000000000000000013b76183fa2e01d10a3ecea5be65ffbcb04724ed30e4655e26a7ac94d5861f0f308b7d4577789d2f4892eb89202d84100000000000000000000000000000000012c3fbed77d9c37c47c838899aaea0fb6585eec54801c3ff2b486086e33040aca6baf6192c33af59f7db1d489ddf7d086ef151662cba4952416eaadebfe5e0fa0ca1d31380e1540c2d5e0181af9e317c00000000000000000000000000000000195c1bf8dc0114a472cb4daa31be44f22a162d22f2968b7909374fbc4d0883614d2911475cc3ba242844ef1c046885e70000000000000000000000000000000000d03e5bc3acdd01d174e1d2308e3f1ff3f103db8e2804210da44c47229bd983ac127295558dc5560c0fb2ea34def196f0a3851bd52ca52919dfd21efa6efc56f6dd5060ad969360b1a731e8f38f0f5d0000000000000000000000000000000001261cc24d5e69fe8a7747fce45086499ad54f7c138fe76fa665517c58e475683c5a219df303810745dc554fa3c096f300000000000000000000000000000000122fc4c068c079827635d29e944366516c1d7cdb1ff62968d847f4882da8a4919b59e57690f6e0f6aaf083af0a04b2ca32b41960417047a2258b6e9e228f3cc1130b296cafbb75f58731a81fcfe8c83a00000000000000000000000000000000050b5493fdadda15e15b2ad6104274da831753b1cd247f1dacffb6f896b9db7190bfae2ca202907d36b979b668540ea400000000000000000000000000000000141245d4556c7f1032d0ccd606e3a2d3338ad753fd7d0a3c1b8ab38e94d8618e85c22a269428537abe003f8de89f2c1171a6f7f091a6a21dbfffcec2eecaa22d05252b60bf91b56811a833dde3fcfde6", "Expected": "0000000000000000000000000000000008bfa9c347d937e2ff2d77ce7127b1af4e7adad5f1aa6d71c6226b64c62c955fb0dd0e36a5e87472d6979b656c8a740e00000000000000000000000000000000032de435000391e441ecb7e777741fc72f4676f64cfaca6fadf030e12ea6374a7fa988c443a38595def0b434b185c75a", "Name": "matter_g1_multiexp_51", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d0296528c7b2516ea73cf14c5625a4296c311fc2e09722f3b381279da52ba9482e43d3fdc1694b96c3f62b7d98d6951000000000000000000000000000000000da2aaba37d0955c5fcf31152926f2fb345deba744241bf66511da5f4ad9fab8a1cffa270c4e838c39b34bc28fbc08b02e56b63fc6ba87cf021c2f92baec248756ddae0a4f070df840db281283a4c9b200000000000000000000000000000000175c976baf0205ee7326c84c49cbd2d7c3db91d1ec92d87cca896ea09a7cfe4ef8ca45873f86e28afc4b525356a68cba000000000000000000000000000000000c442d3edb8b614407e0d138417f8a6c028b29dc1beb5825c928dff3a08820c5a8ed5de643068bf4d239bbcc2dcd0b7612a50af55f47fdaf176d4885e4910c54428c8ef433ea0cb1d009ea7778355947000000000000000000000000000000000f45bf893109177d3c336915c5e28c338ea28468cbe215ee6fc6f6e3c9aa9e0b7120586e42c5c087b55fb5789a4a9eb2000000000000000000000000000000000b6ad0cffaf555f081ec7a6fb354d6b20950fb6fee059f2f571430f86a7cb9996b5f655bc7cddd14f3f8ed37c7fd278889a012158b3c18e19471fca6d5aba5fd004a337d49ddef5db177da187c8cf1c8000000000000000000000000000000001944f2fa08357307df2271f4bb57cd07a998df56425f7b8563902aaa0330070ce260b6d86fc38a5c6a284788d9cc0ed700000000000000000000000000000000165d8134931f7a4cbeb5114a10e44172aa6a0c250989dbd88282f92fc238a8e1e21221b04b239cfc597e2b74700c626d27dd109f6df1d9851dae28bcb9e552c6b1e1b2dfb331aa955d3d0b6c4862253d000000000000000000000000000000000c7a02cbcc758fa7b1ea5fd30b3b88cdda7c8661b3712ba5bf924b441e056fb9bea804bbfa1850c21cad891ee253ff7100000000000000000000000000000000012202a151fcb86875b4dd2dbeafe5ca484b63408ba01440007164fa2a2b7ebbe9d7f738f382a010508408d26a57c566ca96785c1ab66cc5c8e434f59cc1ddf76bd78b6fe660f7cf74cfb79d7f2c7f840000000000000000000000000000000017d02a3ec6d45e9b49ddc8d1bdee168f71c32ba26d4de8c1bdb328cb4c46286328387aac8785eb5a7c71d0ed59810f4e000000000000000000000000000000000d23ee9c9fc914404ff46d0f6ee86984862e97a777ab516c2b84f5b5a7c1807d64e93fe57db53c7b95257fe46a7a15495aabd1fba36142bd768339e091b15b7f5b4ea609b57947a7187c498bd9833c2900000000000000000000000000000000040ca6ea6cae1be17996106cacbc5d9f1962203fd25917dec2c053816f3200b9853b218a07db690d8261ae3cc85679bc00000000000000000000000000000000097e8f4b5a24b010382888ebd7ab7cb71f471bca00c1499486cfbf1bc5ba6af169ac27e1ed8cf31b5d9600361ad13663fbe608fefa5472c7d1611abfa402d2eddb1e54542f45d4012db8ac6d1e5016100000000000000000000000000000000016f95e3e24941c2745c009437c1b2f5ebf690c9c76e269f877bbf73ddc6b15c6132d424c26a3c7bdd9c5302dcbab171f000000000000000000000000000000000cfca2fd001c0da52f231a60288b22a134c7e16aac8745129c351dd96fa37b72a9ef3d93d5e8e45cb5fab9e73ff188e128d57066cce439d8d0385f647ed5e9b29e8fd0528c1ed8455f37dcd81f4b6224000000000000000000000000000000000e2bdbc906c10b04c5fc1e867af43bea7ca43cdbc43cc3574a47b2b0670716a92fd863d4f423f3392ec8849e74850eb9000000000000000000000000000000000ae76847a2524be3a04bf85e096a1ca4cd3674459698fe326db2d71799c8906022e15bcadfbc9ddcd43dbee3443842a81208d8d328014a6b2c8b2b9edc70589cdd63d38f4e70abb41cff1b7693bf9a2900000000000000000000000000000000035d66b8b8b64bb0d3d1ba6bc1bd34c326ce6abac3a97188f82be38d1756f14a63bfedd531d5e19813b668012f77763300000000000000000000000000000000060851234e4cfa8c168db199bea8cbc337e685b565a6faf67e07c463632a6a163a2d22acf9fc6bc6a1f7ead5d288fcccd3a2044ed4f938c17684413625bdd281f685abea2e375bece77c03d697c82cc20000000000000000000000000000000010e398f6c9ded2fef3cd95cbef681c5335a1e9d08c05dc05b6391f65941cb3a79df9e1cc4ebd3fce82d36cc628b7f65c0000000000000000000000000000000016dede30728c57650952e9425b6da1ec8ee5702e783c69936eaf6857f199bd9ffae569db3cbd61483d48188633fef7ed7fd81e27a577b5e79929614c069d6d52146a6183822d25cf1ef84d8afcc1f6b40000000000000000000000000000000005eb3a914a78b4bb3041a32397bdba3edf6943ed474ac8efbf9c84a6cdae5d65a8f55ce4ad141b846f1bcb5df1206417000000000000000000000000000000000c20828a5d8abc2c8f72809348e770649bdf4bc0991f45979501f31d9f31e028731a8ccf07f0cc51bf8b59632897c540c5d47ce35d4ede84a83c9860322f582ec00c872b4b035d5d340981fc29884f1300000000000000000000000000000000122cf863d9ddfdc627a0993dc7ca5810e84ab254ff8147a220d436043c0a695b0cceaa374842c335c14b6ebb273472d800000000000000000000000000000000150fc0b14e30ee797e3b9202533c681ca9e6b1b43347cfa11da59ceab439c9e5cbc038a50917cd9167a0fd591d8175e484ae256d47de2d49b1e755cb0e972f3b614f3e7ba779c65ce175ca3811021a7f0000000000000000000000000000000002ec5aa74588f6a7fd8076b9a846ff3542543dc7a3c798c423326eb06ef92edb8c35583785cfff21f903f08f692d6293000000000000000000000000000000000df140c1539cd3d94b5f9d0aafc38294d1738c5b3c1880d8864e83909b152de0a469742cd31e5e8f5838ad793ea32649a09d0136d4dbb3abfabcac55db48b1ce302067f413283fc1a21744f1c16ef7b5000000000000000000000000000000000a440f227be209dd1bb816a4dd8c1abbdbd03d97c243ac6e48c4efcabef4d7a4b5bf65ea7bea6f4a1da985bbb9fac626000000000000000000000000000000001431a99e1243e57054d2b43217286b35bbf37afff72b163ad40dd4ca92439f4b513284551b0fb137f968f9f59a540cac650a6fba1a5eace6b455ee780ff266c324f49801832640856a80098f0eed0b7b000000000000000000000000000000000b99ae325f1fcf4f3c83f251183871d1b6048a43d15da80650e0b5c1b671031cc9af63a478b5939210356c4c2dcc7aa1000000000000000000000000000000001382d6f0550aad61dccb47a66d004ab3801445d55dd320a6ccf03577b1c1c915022a955e7f3fccbbdd20e4175bd0ae38282cb1f8f6d6dd81e7c49176503a76837a96d7f2b084d29d11dd9c6548cf0a57", "Expected": "000000000000000000000000000000000c62c70aac1893222d967bde4fdffc565cc65fe29387825224b8571367ae8fa857b63c32033faa564f6e12d409b5cc060000000000000000000000000000000015cb57fcbc876f5aeca01d90d55ea777aa1421547e8aff0de69fe5527c9a575f9cecd1235a37648c7509d9bebb4e6800", "Name": "matter_g1_multiexp_52", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000123fa54665de1ad1eb74d400f93b70f8502bd9386a164ef9ac7549b3693525e3fd077b2b2d8b15ab0c6cd5da30f8317800000000000000000000000000000000185921a0fb38ec1eb6804002b3bcbd4d4bc759885e9c1fafe275d51840434382df783518ce768ae40e736ad2ca8fc8803d7f8fbaa4225f3008649eebf42315785ccda2b9ce922170e606876881825cb9000000000000000000000000000000000eb30c8da4c7eb16d797f24b5d8e210dfaa68684939cad598518298c84214ad769f6a2634fc290c2c267c8f3a2872f020000000000000000000000000000000006452f211931b8d7ccd8777b2407e5cb073097ae9b309f1e95633f39d1a5a7f5843a6e87473b4b9c1bbfc17971108e3de71e6cb3d4e19f4a70a4465df6eec6326f558ee1cb99aa540ad2a73c363a133900000000000000000000000000000000162c0325ae75a81c92a8885f14e2f7b9b8bfb249fb9a352d0007cd8bdfce2d8024f1e4674614cd0afbded99472d547000000000000000000000000000000000010d8497a5f31cda80af22bfa6695b4e2c8fb5557ee74581a33fbd0cf8cb2e0b4ca3ecc42487cf957ea81a5388d9871fcbdb2b3c3b8e91540dc2724537526fd8c0d4b85d2cc20323d71fa5a4f61b3f12a0000000000000000000000000000000013270ce7a1b4abe3026d245df9b93061a435ed00d0464d8de14675247c7f2f1cbb6e21c8282e71d2fa28eca1e3f5863c000000000000000000000000000000000b87656d14cfe98c2d3f34b03de0b9f08207b00aaf6c5a4a6b9b4989744581772a2d6d1923c3d07b784853f7b2d789b9ef0c8574167a3bd3b794f057ed01865ea69c38023dbddb0afdc55dd9523ebab700000000000000000000000000000000067296630285ec7da7cfdeedd387d52d905ec39e183b87479c8f0fba967e840f8394cb518dba4f4b7d4e2cdc00ca62c3000000000000000000000000000000000ed41fe0f04e0c63f3fd7ec7560d24974fd06a1566e8f129f580251227cb9b7e10ed6e60c2e7449721d5332709f465973ccc75501428d3be8bb469ed0f2df7dec10e1d205e11a907cc30c4a76eee3cc00000000000000000000000000000000006f7bbdc3c8fe2f7da9533a3f8a3c48c630d6cf567c75dcf89e13852f7a8691e2625ca24517ad3b59ed3513f7d3b4fb20000000000000000000000000000000000a2e63715ec49b06a78e014b98effbb03f99ce61b464c66108cf18ea49def3e1f035a8b88f37b453b31357d2a2a48f4e5e403f555fbc800f1342275f18a73dbb679bd31873ee87617090912a52d6a55000000000000000000000000000000000a9e51eaf24d2d0fcb7f1dc7ad985ecd4da3ecd19fb75591467edb0f7fc7bcef67c1c272f39c31ef36bbc73d7ea6034d000000000000000000000000000000000332dedca239f4d1272db77dc388e07005d90f44311aa889b42e931d08c2669c3f4aeecd9052d3f2585b2a4e41c8abbf97ea57a38598204c15bf65e7270a175460510848540ca4004286f3ca09eb5926000000000000000000000000000000000c6b189ddc86e2d6722ebabc445190cf94bb4c54135aae2601c957e062d351d0c9fff19cbeb45cfc5dd05eb3543a660000000000000000000000000000000000133794839bae14fa041004f173506fff511526313da5a8f4e32c895751a22ecf01cfba564006037326187b899aed596ac54dd8cbe68d5151e4428d35ec2d5b5cc7f5e455207c0788a695c2d7fff67352000000000000000000000000000000000a15343698b916965009f1894c8b74a790d59bc39b7f0de01095275ec002c97c66e7a6a970b4b9091cdc54abdff1cdb800000000000000000000000000000000045f084e0a7c0014e58c9988e72e1861bdb4f962ff9869d444d5ba4094178d52f9c2aa511feb6e8717098cc1f09d49eb47ee5651c127d7c8ef65ec68fcd97d1dc228bffb5bf1278aed3eef8115a5ae72000000000000000000000000000000001656928ad3ee67675951e2d2ddd6a7d9c629a3148face6d1269f79c3d0699f95350e83a6ec20aa3be78a2794c3f250160000000000000000000000000000000001b8c9e4c818774dbd2416193e795a429a22881abc94ebd9a8b42bc4d7069a9778e4bdf7270180784d914bc6be99b41c14ab6a1d0d3f87e7c9df0c14b6fd2f9d0cd755d5fce5f40bdc8174790901549b0000000000000000000000000000000013d779138ab03fafee1e4bfa2a290c4f20d2b57854a5133cf5ad7817bd32bbf2945a02b4fd5c8489e704e60ee937f962000000000000000000000000000000000aa058528a4f9bb583295ace843feac4dbce24a22ea6bf412be019f590c621bdfc7562e8dd49afcc337cab474d9abd0129b12cff5a72f27e15032844fae50e3cabbe31a69568bc4b5cfa884f62e7e2040000000000000000000000000000000014f30fdaf2f81f9d941af33d53e2d9e3162f62f47c60164e9b5ea3a5cf3a681a80b66ebfea391331c231abc4341cb94b000000000000000000000000000000001854addff23c2f53a21a6d39c72f91ef0e8d9a6d6468f319200466f78854c41be3e914bf7f966f00e185b44108af30f092c1b10d980826351c3d193a0f54a7dd78a3995efb02fe5b4525fca8791b1c4f00000000000000000000000000000000188a1934a28c7571ee94f1aa5c161be611939e52156bff158170d5e12a6480e3b9d1528082cc2e537ae1734b1847f8f8000000000000000000000000000000001728b57eca86cc8fcd9dfc65a8f5f055d51d300d8781839d744a1b81a0233221cd353f642b3507703880eb0a33afa05c8f715f35fc967837facb515ebff3df502223c29e7089fe6d2e9120bd3ecfcd120000000000000000000000000000000006c99e6c8b554d748a3526da79e8a867efde15ec50ff62e43f691748996dc087dbc538cf65820ca065f3adb5884e2f0c000000000000000000000000000000000c577c42243b95b4a613c485026306513685cce294333b72388d6968019d04214ed4bbbd5b64bce78fc380115a4b067ca9e49fcb12c0b1e9bcdbda52e9852ee0e98fa0d43f7476b3d65ef5370c9460a3000000000000000000000000000000000d7b48e69a9807c6fc867f59c894d5bbfeeeacff500a3ad4528ed4848f5ce501baf8959f822c259b712236529dff0b0a000000000000000000000000000000000e7d7932084a0416a4bafe237c923d1390dc6662e7842829ab6747024378f284af07ccde9cf80042bec56e7429ab3acd80b0d6316c5d62d41fb0399256c5c46ebe2a12eaad835d2c7177bb7325e21d3b000000000000000000000000000000000a1f74acb627d1814ef90b2d756bf76383075134c1b34dc126094238eadebd780c1ab8a3d1f4d9566dbef1c706d931920000000000000000000000000000000009bf8c2fc78b1f7af25941bf429059e9f86b34a36ff865b33e918c8435a766d897df83005c54871ad0d3e82308e368501b96434f34fa3e00ee0cfe548a2d2ca29a848cf1c52f940685caa9a227e32a61", "Expected": "000000000000000000000000000000000a912d7d352bdd182a8b431672b496ecbf18276da61d6a8eb066c41783b7cf3df287796b34b165db186e815c8847b3ea0000000000000000000000000000000002881de241ed8109f544f3a6262eac1aae69de7a7e9953812eede9e63a970225646f5c441b7de80106d53cb6dbb43f10", "Name": "matter_g1_multiexp_53", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018896a4d84c1ec1a20e1b0e33f159de4d82b55b6d27d863ec7cbefc2d9c180beed2285aadb34d29ceea681689dab06ce0000000000000000000000000000000013398b5f6f2c0c9095af94796572d603de02d41c599e09d3e254b326fa1575e0c6a2b7263a196c5150440daffb0d60e810e0acc22c43080ab9cea11a60866feedd57664bbe6c3f0366beff177f6631850000000000000000000000000000000015b31d591dedde69dcfe9c23df11782c090c443e505d2edfa217121a1d51b6883d782917b2a082a41ce698ecd95ba95b00000000000000000000000000000000164b18eaf53165842e50112c4a8490b8246376b58bb6c188fc929160f49cb0b68ad2f13dbeac8466fca75e6f72a398b8cab0c230c354cbf1a3c13c23a36ae5f2d5d084d7aaeb427c580cb6b9bfd9df600000000000000000000000000000000012876e247618c76af5221a50780803ab64970fea8bdeefcdc1ef4c9a160718fbaed9dc6691502433295d54d4030ee157000000000000000000000000000000000cfd8dbbeecfd176cce05ca1663930be8cf3b300a287ed053e36f64618a14850a3e813582da1f54ac7e96ff61ae57c86290608899cce4b3d25f57519cc881eb748e9ee7e27f7b21d69f5d8ab3650c3e800000000000000000000000000000000085c5db53c4abe188f44f084bf17084d3ae409b753089636d3c528162c2816b9b9ef3c0c8c05e88189407d7ca95d40f9000000000000000000000000000000000015d9ab325a8ae365f173821829aa395db9211015903c08491375f82853d9084d8aa2e35c2634a296ba14b50e34c1feb71debbd9f3be5d6e65e837bd78605d5653fe63025c320cf49c035ae66d8ff570000000000000000000000000000000014bc3ba096662dc560e88ea6b7b4363c427d038fe85a49ab8d9d63524940f26106447ad6e3d7495ca562c98b64d445880000000000000000000000000000000018bf745fde497914d81d1e3ab96630f24f6ed27ebf1208f7a46ad9fb893a3f183982c0acfc001984de34f617841524f9250f62ee2c2972e751b36d95a578efd2fa5e0a2c1e29475a3cee48a28080cb0b0000000000000000000000000000000019b15da994067a017c3040830b5e5f7eb77ce0cf0674e96b209b80c54f1307cb04799624647fd1fb990c61092682ef730000000000000000000000000000000002248d31211c2a37df59a0a4ddb0cc7880dea316519ab7baf1c614b26e2673f03b00e387fd537aee442cfc94f734aad8ad08c3d2c36085212542427c1760c72f22838be5286402ef87403f816f4fec950000000000000000000000000000000003a499813ed2a3878ffc11d27dba4d55837d1114049a72444b6db0c8a7d23a53af765d66b5017695efa39bcf7d1c97ba00000000000000000000000000000000011fb1a989afe2b093fa2ae3c0405483bb1a52c21226acbdf2a52e2e5fd5f7404776551c2deee87f431ff39dfb031d716ffa16b6fc4cc9509a2b8d8434fa0f4f38b4cb4eb1bf7f545f9f43b9190cad890000000000000000000000000000000014540330ba54d2f16a9bdec93a0b7ccd58ecb44361c67f209d36d2a42b5d5a4f9b9dce0701ad0677d6d6ca83a256e8460000000000000000000000000000000001a64d5b128c07848ec579df1d26755e5d2f70cf123013ac249a4d188b0eb56cd74cb12f7de2db69b3a0f9f4ece2c4201271d29abc5f972809461a1afa5eb186dff5e28f20311a1d8416f8d54fc4b2d90000000000000000000000000000000017783e019baea183ee5d9e1f671a23108e403a22580f5c203dd6ff72dc0adaf802d031a236e72463e0fa2c5f7c6e68b300000000000000000000000000000000132d32bae3b92b7212dd7db16c87360274a409f46199f66e572bdb21c4af24af62758978e6d01af60f5fb87481d9f4f23ce55b3b32ad29dca1a0c99771fc8f7179851995d5eac804458edede9b8dbcd00000000000000000000000000000000000a625f252a8185bea7f1b73d1c7c9b1fc7f4ea5cdd017afbe9e56e7c12d58d893ddc387b7c2870f4a975b613bef0129000000000000000000000000000000000aff6dcf60f78bc908fc4c2466270065766792a05d8629fc7f5d2b61ce4882644947fcc3600d63bd5f49fea5574616bcc6fa7aeb016b3e3f599846af83f426b9ab85b6857f901c49554d03d27a390f5c0000000000000000000000000000000008ee6e9521f32feaa034b533c0b7c749f60d84adb53d6943d3974fb4b92ce3cb3f67fbf52fff27802c893cb97e587b930000000000000000000000000000000012000b50d1c9628f822c41d56b29e21f3f496f00bcf05edb234ffda56767bb33dfae736aa9fb9a84ccb6a0e21131c5887275a8d16c02389795d54ebdcb70a39fa885320d00cd4e5aa15967916e46c6150000000000000000000000000000000014d9d3051d073d24701f01631408b7dd1d37f0855baa64a13c493c15f7acf36da116595fb3d69dc386cc611c998f9ea9000000000000000000000000000000000b33438dc1f84da6ae50b1aa76fc52f5ba0e547fb15e8f655db9e0e26d6aed15c5cc4e48412d089d1ca6fb7a550f8eecdbec9767ed2dbde21fd8f315ed6292b5b0b1bb6daf2b62665c34daed00a679cb0000000000000000000000000000000008935c4cfe2a1620a0c895feecd91ea7fdcca3bb06fa514bafee38ea5819b7372e75a106904b9c9e8af268c9f5e5a45700000000000000000000000000000000114e9944fbfc05ee1ed75603bb9b79301a1f90d3b5209ea14989fdd16f5deeb01e3474da2b4692a3e0b9625d3bf9b4b2ff634fd89223733f407c242e52f034691036c7ca69f30e6cd444c561de9ebdaf00000000000000000000000000000000105268fff23696890182b5ec307b38ee1cf28336e1c3fa28b9b697998567035323ccc91e974f63c55c928f64fabc2ca0000000000000000000000000000000000ac2f8c91fa31e2d950385509b86d512c80f0d1c73d223f71b26040d58822e4269a85e82ae390441853f8169177943aa461d349e9711fa701b92b62dd3e3569d1203b6a35ac8600367a4df9a9484bdb0000000000000000000000000000000000d5a5c94375029e5511a6c6ca40108377db43e4e0b03cceaf9fb77fac7906f71019c1a85591719bfa5d9349f1089ba0d00000000000000000000000000000000163bdfc6d40c96bd24a3b83f89037ec9e4191b533e36dc699a32c854291b0823b3f071464654eed00f08a691aa68636bcc110fd7a6ae46ef78c0e26183e707eb5e0a2944e3afc09e435d56e91584b93d0000000000000000000000000000000011654611997b772db3111d2d4edf92b83689451b1e7594a7a4bd40d85820df6a1ab090f6a1959acb322323eef27fbd86000000000000000000000000000000000b905fec9e379cfba09fd502197305ae39b48facdb01f52afbcdf159c5674234ac9723643830ab8e2639e7a0d6bd979267de5b9bee26b26b28f81d96e880a3f07dd04eb56c15314f1a789436e01adcda", "Expected": "0000000000000000000000000000000004de1528d78645a4055ea348ef2618b85f8214c1dbd21ee08ad164abc02cbb2927202302dcd142c65e12934dec409e18000000000000000000000000000000000de34a6fbb73c7152f1636e5c02c75dbbc5910c763bb790d78bb56e48cbc6380bcc2ca14cc11ae139fe009135c81b243", "Name": "matter_g1_multiexp_54", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000184094ad33f83f5b229643d9808f5b3b7f3e50306788f8485472405c79e57e489549c0901c3d1694b5f61f74d87afe9600000000000000000000000000000000007ec616b56868e00563d8e8bdd36de3b5d1e314be0d81c4ee97fabab1641c89cc21e70153a4d3d4e788b04ffaf07bad624ab43047c02e30ba2ec671511d06f869bf736a9866192c5f2eea6c065acea40000000000000000000000000000000017e7c08cfedb74bf88c1a80762be0e0754a86e5482c27b41240f4ffa9d014e9e8560e172519031eecccd897b869c365f00000000000000000000000000000000115ff96d404829597f16b9b97f8ff71a8eaca1a76bbcb72d53803d35335d8a8c1cea58559136f9b254c28262aa907414edfdf850c0d3e3903404fe3e0f523cd230cabc45946c4fcb6d0e5e05e388c235000000000000000000000000000000000b5450038d49c91e4e5a40a31f1f75923c7e1599695b829d9975ba7d845ab20ed5a62a7238d6a6479b2c6f9249068aed0000000000000000000000000000000013066cb8ef171bdfa11e70ddf83eb2447c4169fe38e008be5787c38b1b8a946fc474e07795765ca17fd5bcf64150fb04feb34852ce0f3b5730962023418ad6cb860716dcb526dc53e8ab6a74a6a3910b000000000000000000000000000000000f19fc0ba8a0ec5a2cdb9844002601f580e0eb9b2265c86f6efc4b633079d43461d6bf241ccbf422eb9d7c00ecca88570000000000000000000000000000000012e744ae937ff9e8e4f611fbd1c9896bd31bb1ca36b948d9be89960fee6c0cbab3264aacb916ae3596f110cc1b26bfedcf25e64093bd92a8fb394511215a3fa674db86d7329ac5ea70ec77d24d4ac58e0000000000000000000000000000000006ca09ce8c07e89e9e51e208b5d32b5ab61f0de60484d9185a26911b56a728a7473b70313fd18c893ed3453719b074450000000000000000000000000000000003d372a5477fe7fd84a58f6f2eda8f5c61aa0c357c7fc1708f7616b8cdff249e7d2910d753c2e531a278f5853fc065970b40db4f9e5c27a3208899f4f536880b97f4c69e7d889c0726d87c3fa27e097500000000000000000000000000000000152ea2fd1934c32c3c8e27a6ffb278741b899c5e296549380d019307875629d57ae44580a944babeecef73753e30c92600000000000000000000000000000000161a77844c90a6e83ed2c40c937de21fbd714a5cde60015a71bd4c960e894d3cb54a8d1e4bb4cb0a1985d4469814a991730bc7f68d8d371d0bc51d95f8a5899249b8db5cba0d21fd88ba6f86d8691659000000000000000000000000000000000a959b12e3af03cd4629f5f6f412b7084eec6aa55369e2dd2f355c93ea984ea6f2a7a01e6a10146849503d230fb08f7300000000000000000000000000000000161340908a38e4ff5373df643e3cfdc459d872b5cfd41ab34fd3297b10c37dbf3088fc23fb71f2a1751a121bcf51ee36ef06360717cfcab15be966cba2836b97deeedd20a52f88c73e2a583b64c8e5f00000000000000000000000000000000013e31a4f0cc29a5ff7f4df39db999c95eac789656bc9c6b91d0209b8a5ec2dbab698048fefb75a3dfa48066ed5743215000000000000000000000000000000001851e72741707cf96f887d13e01981f1e3db5834185eedaafdea99eeb11dcd3e90a9985f40886b60ee2a779b141bb62082b7d8b8b9345bf13d0e113b662141f5ebfc5888a5ef8ea06f7d5d137324ebef000000000000000000000000000000001501f155cf6f053631ebac7d2c57cbb101a750f98b6e11df79dbb24ec8804535b1b24942022aa64713fc60adb2017bff0000000000000000000000000000000012a08f9b1ab90531a26221b70751efa598b4046a5482c01d72f506ffbb3430d35016848755674d01e16bb78a44f8b6882396fe15751bca2c4a651445cef236a865269849908df53551802dd378b892cc0000000000000000000000000000000008fe1ea18cd8e1d2c620356430ca43782f844a2efa6a285a7c9c086e972b12735faf6237447759bd93d98b6dc7c42344000000000000000000000000000000001731f36e811c640f44adce6bb68fd71065f440eeada278ebcabfb9bf0291e551ed302c592aa4ba7e3a502cf58e3eede69a5897c9596223ca4d6628ca1f793a000aa21a739a37faa28637692b754148f80000000000000000000000000000000018e3a4176b543f2152bd7f72ca358af6226f77b5e10f3f9006c8bbe4283776ac31e6d10e838e89e8090215a133e2cc510000000000000000000000000000000000f88c3eab9ab32fc165083ba1650736e04b4e8740591f6e3ffbf684fb359fc8d82513c25a9ecf4d46faaa14d9f13a3ff20a2973faf886556e5329363bd9b9c96424fcf2e953df90bfd011ec07bc66eb0000000000000000000000000000000016fb47b4497cdcc75c0547f4234ce94f45d160e7bbe199902b2af5a5896e7d46cdc866d0fd730f568449032fc3a2df4b0000000000000000000000000000000016c2da30ef51e6728c09c3b29a7abdbb104f1a4fcc8960248b9773d2ea7f1bd161bf17203a271edfb235e8b0be437957f4ddb773155a27badba330ae5d26096f350e9ca2811feb227c4eee09d2baf32f000000000000000000000000000000001992edcbf32707e92506e5cd12662e730bc96b5f33bb88c5569fe6b266aecf63548be20b03fefaa078231b17424ac98d000000000000000000000000000000000f6179cb8878214222c2353a60e0ee210c86e306e335e929050543f084ce7c7ef56ca8444eee59856f4107e0d8cf997b52e4030b5a4bfa767ae20cdea7f464dd2dba51c9c698556d24b8f3d4d1afc82e000000000000000000000000000000000d3ff341e9b3821ac23ff7a87cc9dec3fba38ab8f2bc0f58e4c0135a9d66c6d6731ad8bb97468ca44538ca7f26fdfeea00000000000000000000000000000000053240b8429fb290453de18000ac58df56b5bf3c279e35d9cae8b350b932b0545b6c19ec7ff186c2123731d971146df1d32e0429e7934faa526475c5c7fb977c3030ed74e145eba21af2d2cc8461580f0000000000000000000000000000000004b424dab429bb3d22d18b52c4f9412a65eb7e8ec40b5e308f65fe6c0da1a1ab55a629ef8ed57adf108d146b46e6261e00000000000000000000000000000000057b7d5285194693a7ec1ed9ee3dfbe8598d9acb670baf03bf77c7799227ea788052de690e229b0d28c0a6cd79d22b0c1f700d651c67ca5b8d95fad1a8e412befdf691b074956bb8092938bda2ad2694000000000000000000000000000000000ffc202d826607947dd8f63b227a06d8c6b04848dd102da57723fe20e9b06b7c125f0ab2d2f53e14cbe95f1031624f99000000000000000000000000000000000880400b425ffe1b63214509f9acb0255d089e9de8e4eb643fa3b0383aed760f4c00babadd32f48af724a2c80a8223b383052a3bd7a13bb1ccc22b9519c7ab12d2dec67924fd9f15f96069de22e7b692", "Expected": "0000000000000000000000000000000013c0b89e259f71ae41cc73ffa3c900ccea45a8a655353db6eb17a87582b00bfb971ba91d48526d934b95e9bb6a0fb5a200000000000000000000000000000000042a78ec26bc1ac4165c36d84588ca132b7366a3fb548801810da041213ee84c7e6aaf5ba02ac051cc1c5be5dfce0ea5", "Name": "matter_g1_multiexp_55", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000083ddce067e21b219535e477f77ba100fb86744b1b82b4ccd0c72aac69025038e719ed173e70805c025b19bf7ba5908a000000000000000000000000000000000a9eb816ed60bbe55d4833c0e91ee73669aad116ff793d941223c17c86fea3ea434172c3214a4620d4090915cfb15d11c40774f67a651ad70f17393b386e9ea9e81682ffd78db7fbc17cc5084f3c705200000000000000000000000000000000050bdd7d98b9df55ec0ab87e757de009c804880f06be3ce13c5e051c3080df45bedad4f074812a698f50d6774cd5921b000000000000000000000000000000000a8dde7b81feef753cf16f0818f29256391276847cb832bc2940bddb329b249af4970684e95fc02e702f09a84e7737dfccf1e36e063a5fdd4b735dc18bf07703b80c6b72f987c05641612d7ce73562c0000000000000000000000000000000000d989e383d1c6e48d14332a72a8efd89260fed65a47c4baabeb0c0cd8322e26ade95b8be9f532b4813153cc39e7a9402000000000000000000000000000000000f6f7ba41c95beccbf59ca1ebb1dd43348c51de617a09ab8a2d67d3f7065d3f4699b1fc31197275e5b895f92dd106d667ea75dd2f54fa6413ba77f10a11e12abea3a4b947116e1e7c9334a0a37c396310000000000000000000000000000000013f3c3eec6fd2d4c830458cf58d5e18f0367675c47d38fd5ddce1e8be3d6ab04f71d09852b987d2db64652b3255e874d0000000000000000000000000000000009c0000761e1fe517eb32bc3da4f7a933e77db6f960f5405b64d9088776b6ee8e23743cb4a1779e8d0d93787ca029d7c6855c61bb7d72b022c16290c6d3ca9c1255cede8e0b827b43e40fbf018403978000000000000000000000000000000000c7a5bc0249717c1e39a4eea37de1b423960b409f5e0b3877e90d5278cabee197948383936739ee3f25b4bbf7f32e18900000000000000000000000000000000113d6fdda1f4b2a20d98e1d458920658c762303ee69fd7273a8830728f79be00358b3f3000927bc4d26352e5b9e6652b7fa8503101f392a6c6c27300b6992af3fcc48d47f73db67615a44de883770d4f00000000000000000000000000000000108fb7a97ce429fc3ba1ca54ae841309e2ccce748dca953cb7dd9dee3ad9d919e3f8ab635b294b94b939cd80d3435b5e0000000000000000000000000000000003af838ba4ec485ec2a17e6f592fd832d05133952f273d1b472800b210c96cc503caadc17b38d3d1e978606786d9ffcddd947617bcb7ca1c8fda0d49e6d950a84d60230bc2411d42ac32e3651f48524b0000000000000000000000000000000004cef28329ccf221ad7ab2b851e869bd433116753e0d8bf38d22ca46fbdc71fd9d96aeb9c0df69c47905a99c96fef0aa0000000000000000000000000000000012ef5c40d8b6469d9f3921eaa99446fe494a55994551fd1996c453a4e5cb4a2cbabe20671ff51639710a5e45a57271aab4cbbc6d537ed2b69c2c32c84f3cea3d2db180b64861859368e98aca32bceea6000000000000000000000000000000000c81313e8b5689935fc01b5f999de2fbe9852bdccf484edd0771e8427f2a194e29d0af09db1152fcd91c8f7b665f6929000000000000000000000000000000000f37dc7f87b8de48441861ce0c88b1a24f22aef2c321ddbf385cedec7810c20c7fee3d2c5a04b5390a5fc24612e4b3e9457bcb8c44a2d9d1facb39ba7ec8ede5d5962b3256d9fc2e68a1ee5a733ccbd10000000000000000000000000000000004ebf9f75e92ec4fb7168bf71215c9ea8ec17dd9ab392c9810316a30a33b4ace8d93ab75356baaeb51a7f47b4370915d000000000000000000000000000000001307c68414b73db43bcd9062580f7c814c3c34545ad5d943685ed8df26acd457823ed628e4b215875a9008a406fadb5619f254dbf75f1c42046343b0060e71302bf6c94ca2fb8aec74fe7a47a3c9c3ff000000000000000000000000000000000cb5860f081e314d4fa3bf70a5eb18d6fb7f5257a708f1b1726b539115050754724ffd6a34d3b5c95359f40f41f2390e000000000000000000000000000000000c392d8603c2ef93d2765d98c695dbda8e4b64ed90c4771a4e69fa00a77d788981132336f870a3a93765902fd8fe8763f08cf27a47d89ae6e2ffb27870d613b9ae586857e4ea00670944a2883ba325af0000000000000000000000000000000011c802516f42e267c0f9db096fdfff77d676eb301ef1ad440b6c2129c5b5722c420f6e479443cbf43d48803f7e32d8470000000000000000000000000000000004a5ef232d3582724c3eda67cf2e69b26ce44bd927555359820efc3fc67912df560edfc4d119c5595e1ab1fd7e2a262f50aa333bb6b44086fe6211e89cb70b8467eccc228c09aaa1d589cfc24771a11b000000000000000000000000000000000eef1e6400dbda287910c117ba17eee1137377e262f7f5cf13710b521bd26eca2aa9731b0a1cf182a0d57a329369125400000000000000000000000000000000188e925365fe7cb96875e85f711d8ce233cadbcdd4c892eac52d9c77f98082662410db4cb6b24889b21f162eecd10f42d9f7f74a5ccbd01afd985d3259739023cd012cd67fba3a4ab5597e94d8fad434000000000000000000000000000000001307849ed4d685815c670477ac54826e94465aed0b70df9683d09ddc62597e7a0a7a4b2839fbec735eeba08bbd3e821c0000000000000000000000000000000005dd74ee1018ff2280c3dd8faec3c97bbd00bbb7cfbcb849bb003b590a999b6bb3a973ec96bd9d825206eb353086283485c00be7e66e318bed8e66cc41e7fd0593004bbca20f0dbc28efe4441acfc9ae000000000000000000000000000000000458181a1019a65c34835eeca4898b88b0351da7422bb5982616c90740e8773b5a03272646f26c3a5801c6c16be33ec900000000000000000000000000000000101c2091a08179eb0be41e20a545f5b53b8ee39365dc9b57f12d75b2beebdad488d63e857ba5187c8f92af447f72896ebacef63d90ad11bbdf0c5fa2db2838c238ad3049a3f47b7f67361825efbc6526000000000000000000000000000000000cb8c637a9b8f053d5104b582ca03ecba768425c639fef23c4b624f31523e0ac669183639991728135474ca19e0335160000000000000000000000000000000009e0798589417cff12eef14f00e415c51c30fc26461e92c4e3fb4a5ab1a653ae791f05f4cde0cfe2132c377175cec1c2473fa3d16e6431da14b8639d4fe316692db087a167a2c4f07307e770bb9e35ae0000000000000000000000000000000008400ba7dce60413ff085c0904066b8e9e9ae290781132e739a5a8c7bcbda322fe1c8d0fdb0e9b0abe44ff99d4ca22ee0000000000000000000000000000000008b54feb64f59541ba3b7c6f86d24b69fa30ba057db890cc6d958e3a7de8bd379257c90a413050f7789ded9ee7b28bbd2774741f87af1d6942dc4ed79b70b2d706f3db6b6d083eef0475334ef1e2410a", "Expected": "0000000000000000000000000000000017377baed9953cc7fe1868baa9e2f6c87edfab1700bd1f60e2644bb97cbe2dd1fe031a986fde6555930d4c464399f1f6000000000000000000000000000000000ff69a282658b49c270e829b326502d83a82dade820de50764a7df957e94e7c0a1f0e3d9084b45d9a875134bedc4a0bf", "Name": "matter_g1_multiexp_56", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000d1de82c29aaa76b17079b2e1000005bf37df08de2c5ba7a0f9a14870e0ac327f46f59a116c72db57cf5110aeed6c76000000000000000000000000000000000a8ff0afd1cd7f541775567134a889d82727e893e4f57d1b5981fabd4bbff59dd3d3995a181efc9b5fc078eb3d4cd0e7d10ffdd3797ad13e65a1115cab6529d0f87b91eb41d6265e694eed8f026672140000000000000000000000000000000018120f0d0dc908dce4adbe50b24b66ce12e710fd35e5a8a8c357dd80c078d6854f20b12d40279b9d6a895460d8989cda00000000000000000000000000000000064f4e282ec5cac74e1a12f678391730663c83afcc0b415fd21475875762de2224e389d607cba84788a16d622d2ef5c13e5da5568a9427e0cbd7973a34c147ac2f3577d06f68280caecf8588ebf1591a000000000000000000000000000000000dae339b418871e2f31ed380824412acbe44e6c73ede9b4c52c054924297aaee1f7da749374d7ca44b138acb85dc182f00000000000000000000000000000000155cfb670ac94e7d5a095d2797cbbb5b8ad3e037fd246246f8e8c2278f5d4e53a773e6518ebc3ea5aeec6383d6fbb62c145b5f1f156f3c823cc129568e7602694107608c1f9545edaa897df58d27b18f000000000000000000000000000000000c1f7aeb05294c1b496de11f743c0c7aa4255211e1e36389bc93dc8d0e73fdb9af7bfbcef2c196a95d1d449b9983b2020000000000000000000000000000000011251668e9edb38ad147f22cbab7d280d436d11039d9fb823a19dffedf2c6a484f112560623cde7e5525c85b4f5d06accf6760be82cefac2843265be5fc0fd6d308c1ed06fc684c4693de25372f09ed0000000000000000000000000000000000ad488f5b9934adcdc834558c8db1d62574e1ffcd03da30eed865042abae4dc03d69010e7e591d9f0a8e421d22cab23a0000000000000000000000000000000002cb0a8e0713dd3c4833af74767ce46aca6c1efdfe75d09a50fce4df2eee3fbc031357691e23ceee810d30004d03f6b9d9fca4d166149ac9e6159ce95a06f790a96243662373637f0c6a59764b77b45e000000000000000000000000000000000465d95750a3c688f560ab9ca6fd1f77457592a0d5f54c17904a222010444d048df2be3dd402f046b1375d75de446d2500000000000000000000000000000000166289d948aa518167e72591a011b3f5ce209bd32ce091543bbdee1e8776269347ed711e1e9f1193f818e3045761a75141733039312347a0c9d760c1bb9a1209a34a02b359a9c52a57eddced157586700000000000000000000000000000000012abc4f1c56f9ac3760acec3d79b77e9ac71bbfe4d2a90cf43da3607c99035e550a4d0fda734bcfcb16ad08f773535d400000000000000000000000000000000030953a6099532f7ac352eff43569914c3f8d736b8aca89f778b4a67c754ada78e121dff664feb751532a41c8081380eb21b18d883ef62084ce4bd353d7434d7e220e9cf6bd0e8d0bed1ad0a4ad94c7e000000000000000000000000000000000138cb559d92b392e94cdd8666605cb5b05e585dccfc023bb6f1abe82fad35c108fca7a41afa49a801700dd8ef89eb3b0000000000000000000000000000000018cf89ad3e05492ac8699ba0723d5ce43e81b0166fc33653c967da921faef37f3ee2e8e3f71f983774966ca183e05f9eeafb6aa11296facbc13936bd2ba09a2cf9bbd9dab6ec8cc5f73d78c90b471a3000000000000000000000000000000000129c48a05e3d6bfab6e6f5200fbb90fbb743b045509b129e3622929712939c5d15126a09f1a650489c8afde7ace8baea000000000000000000000000000000000abff3803d605dbd63bb8453e304335a943bebd224d2d8067d76f5591cc6a2b954b9156a243b0c23d08424fb9edb52383d39a61323c07f9f4656a6c5e6ba139da8175ebfb8a641de50cfa2290884662900000000000000000000000000000000194e6f217b863339824d95c77253ddef4ab97d9744d10392d399b1f165170bb8c13ef1b7cbd995c1c1dc2a9d1b87f0da0000000000000000000000000000000019fbdffa8df167a5e891d09aa1e79049d377014e58523c0eb453f5f072a468809dca8ce0aa22b45bad4f8853d985be1df6374d0849a4471eca96c5e715b10505c4c49664f341d04705fc688c8479cda40000000000000000000000000000000006f0b72c2a934e430e4b773a61317007f1ef02c5f978b3565d623b6590b6cfec22f98b49f9d7f7efcc6913c139fb27a60000000000000000000000000000000018ea7df5f807d4c4981a9159d73d83ea84359d6aa00a5ef019b0dc307d096676c0d16c6b167fc55e14329a858c044c5c0b7cb52b99abe10d1367f8d3def38221c18657a1114ceaa1c0673ab13a6e108700000000000000000000000000000000130fae66f6b4e1a9b0b39906fac847f1285a7d37bdb0d3ddc2c2bfcc6320ccbad2ef1f119f2663e3a45dbff005a469a10000000000000000000000000000000019ba2ae0c371256e4c3dd6f9ae2568386d3a8bd90a57ff982294eae9194494add18958dd516ca9dda6a0b334391cc211f49b1fa80a321d4d100069b2c4b94cbda255d8e9f1a7f14ddf4762b76e4a386f000000000000000000000000000000001152651000a16809ec599f2fe9f330b0782685f6302254450884f0ee61ee2dc2cc9211f69d5d9dbcd7fe3345542a0159000000000000000000000000000000000b5c017e7ef71eb089188ed85331815b40c37abb6ff73d76f40fd8dcc6d2120c6a52df0da042b2b63dfd0da7db2bbca9ad3625b0839cc1ab8c9798b2e9706ba6d7aa623f3c0ce0985bccb2ee5c05a3130000000000000000000000000000000003a6f178d8c63765b2c8df834ebf7e96a4f451c6e05692f96b71c8be2a6e9af17a5cfd8b263eaa254592ea9a898488bf00000000000000000000000000000000185537df1a10c4c12fbcff08de45b349a90b0cc8cd17827df87abe160e84b661d58a1fd03c669015b991225ba08e171e150e53fb45ba8ce5ca917010f26451220be51141fe21cfc1cc06a5557e8e7afc00000000000000000000000000000000085475c2fd70cb7caaaa7c5c1fb17e2346903a962fa68536240d041f2f8cd3a7b83aa79a77f713bc31f7becd347d18d7000000000000000000000000000000000c98414bc318b350113186db9e965a238f1f181b00a2265638d914d263e4a71ff643907ed8dca814e5b8d5713baa8dc9d69ec73df67feb970f1c7a3880ee84d948eab4d8672a6c1481d61efc6cd7100200000000000000000000000000000000001064b94e868fa82c892dd244c6247063a276cc651e22d09695ac6e73d20bb801a189e8fcef8a711ed471fa3b2c7d19000000000000000000000000000000001561503962d7314fe41f7b2d34eadcc985fa748cc98479a06749692a00a46fb2fe5b5a68f7001a0f89f20f7f42f4463c38f8acba4782dfbc02a14d4b1d7b2b0a582f9bd75642169707a475b1a7d2d7e0", "Expected": "0000000000000000000000000000000003e62892118f11065ebc66c58c86e2f0d3c79541aca8db33bd0e12f034f0e106a76f0aecd537539cf2d793cf823ebbbe000000000000000000000000000000000067e42ecf23e1b0590c30106b0720c806ca71fca0601b499025b58f137ff22aabdc6cc5eeef232fc9a20fb9c2bdee16", "Name": "matter_g1_multiexp_57", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000184a661b34e18b637bca53ba60c891da69fe743d5336d92e811649094c15ecf2445736d0c1577bba4eb729aa7204b44f00000000000000000000000000000000129a348f7fa726585badc23f5dabf49ae095d300056b219bce0ce15f1f6a9fc5c8ebaae56362c3501af3f3de19515143cacfb05e5d10c41b06a487e9f8afa38759eeb55f0a5bc8640164bbb081c1fd2a000000000000000000000000000000000badd515b1e0959e77e0f00c7420b46bda5fcb6db59cbd431a1b0ca68c291c6dfe89ece299434f83a980613fe73ab7d3000000000000000000000000000000001266343ad330fcb2cc8242e30a8085cf6995ebd810780115ef881516d4227c6051564d7343e4a5d6bfd210e2e40b91069a0b88d946231cc484550a87a548719f0a543c0698411f230a966cf602dc4de300000000000000000000000000000000085e7c22d51db0a45d8db7d5365de9541eb87b81c237fc47cd25c297da4435b4c9b8212c76c929b7c8f32e8d9b11374c000000000000000000000000000000000a4b0f905b48145f1831e453d0372b7861f7be6e413182153cf77d737450a58f378652255cb4516a482d166233dc88c574e3b5ff944bbbbf808f1f469a3380ee7dc37ebecdd8fcdbbd2f2561e0dcd68e00000000000000000000000000000000086b97f87625356425a79db717f940debc7a7e932370ea315d1f94b1ead853e3ab6edea6302b6b5b0eb4e4bb3c7fd14e000000000000000000000000000000000fde70203ac7a82901250e9798ef1c671f8d5f878fa3bc83556437b9b98e77f7fe7d3a0f31b8cf05ff6332df0424136fc23064970a4ae4ae648a79edb193d98208418d3489e9b5b8517ebe99cc32b4d7000000000000000000000000000000000e629b2d9a57bf96cdc6871ee7dd7675257cf62dd10028201448d8e5b1c0abe777190a868fee83ff5d067252312e82dc0000000000000000000000000000000002102d461c9522542acc185349ea93810c3e2412ebb427f8556b947efe198d616fe00818bedc22765f697507d7678dad972fb60ccab83b6ce042c09ead82fea3d2cb891e21ddc5af7b5d8e334d5a32640000000000000000000000000000000015727f52d46099c0ba041be660ca312204afb0f927fdcf0f1afa4cd3448cf3e9fb76bce7ce0da8b4c0048f76f0e7b1410000000000000000000000000000000009dc4e213faf0a8216061b59dd35a135b364431e2be37e42d065a42fc8e42eb8669d32a5f5ecdfd9234487479543471bdb68c389b94c82f006fdc637696d8085b24897177d2992f504d4bcf5ff04d173000000000000000000000000000000000afb691289f877e1de6fbeb38cee0e36fabf3daf904256d5d6db6e96ce555a9304219bad41400ab6278727e5fe2faffa00000000000000000000000000000000165a54d6db7332b12224d59d8b677517190744c039d9bb401c2e3c4437dbf230b67308fa2d5ae2bf5de282c9ae38a3fa4510c100005f2306f4b474d3843b4a79d04f0171afc5c66df70f631b0481dd3300000000000000000000000000000000032dbd300fa383541e5c40c849addae3def5a4f5392c44b9e96981dbcedd02252f9bfe4100de9954ab34fae9b2ec21ce00000000000000000000000000000000185e62adc2a44462019c86028c617ddf59a6b1c16071624de5ca755f936e73c47cba00f552d2d79baf60a1796dee009edc682a2be4d67852d119795988c52230d8273648cc176ddc012a4b4da5a8636b0000000000000000000000000000000008a574ccaa24ef76112a25b990b5d3b462ff9c43589c9efbb617b45a87bc26eca6dfc6c9e58a12650c202a06d3c86fe60000000000000000000000000000000011f41e39dc0f0bdde1b9e1879741824b20d9237dd7b462272115e8ed44a1e6b7bf82e8ae481204dd8662418fadc63bbf8af6b200fc8e6a57a954226d9a0254c8bcbbc55fd6c3db5cf8532323d4c50b4b000000000000000000000000000000000efa7f183cdfcb25cc5516bdb45c409581b6f2a5bd8ce8092dbf9050a20b2ff57c6add39e96a6f1c8d2134a5a37778c7000000000000000000000000000000000a8213977e8512648b6aeafff2cefcd17a14a052791d20236a78e0b462dcac81db74f1625e787540d7dc279846983f647e2036f73e8cd5e42ad86914e192dd969465aed0c3b752986b84a0c2444c90b8000000000000000000000000000000000287e0add9dcf33f37a10a5ee89cef5240313af0bf0dc183d0c3d6b919c88b979c932c7f141ec5faf012a7f33fe56fa4000000000000000000000000000000001313f591d1da8f6baff044857d2c04f01935b493f5b951cd3538054756d33a52f71be92ef908f016c133aafeb9b9ad2470cd5c1545e76027c389645da1089fa88f675b5b6ef9217b584d7202b797f85200000000000000000000000000000000192d02ab0a323e85e9fa6f553eaafe0d8ca2de63f0fec8139e24805f0785cc85b39908756ab4eb39354ecd8d9440d5260000000000000000000000000000000013997cf706bc8d40b019c2dacf6a7d269e0ffdf8bbc1b4b39e75b48ca5e5e6eba0007b8c55b59530b34b7ebb4c657c57244041bcfc21ede8023ad80b6d4af4b2777c0204ca5f61854e6da34ff5e1145f000000000000000000000000000000000a61b3cc7913e45c132cfb06a26fdb1882bd700b32361572fc79a3d2c432644392f341cc70905b86cad2ce52c30e2ace0000000000000000000000000000000011bb3d958600993ec04d9f98ea3f29df0dacbfe6557b36bed865c564595a64132e4036b6240c97cdb38a60533d5a08baad7572da641373708bef008057aa5af1cc76ccb882bacc50a77b37d7047b1bf30000000000000000000000000000000003d2bc11fa699b284b37d1b45c8dd6b41436a7b2fa09cef316821516801afaa4e1282d717d4eb3d46e54c0208548dd9100000000000000000000000000000000123f8cdf2bcd7d6eab31975ddd610afa79c3c95fed2a6348fa6872b74a6e2816509c71f11d1f272dddb59bafc0f48fc454b51c78093cafcb57c4c1f172d08257c379a9caeb5b5478cacb4887119a08c6000000000000000000000000000000000982c1cbcc39867c7c8c4512392af1489a5e6aa01ecf56abf4cd9050a33536feeb1866421958b929096d2c3f6923891700000000000000000000000000000000104ba4defb74b35d15db80df1f4029650f00b306d702b5934c1705d226886d4bd22b6c88e71b862109f8dceacde3c6d2ae3bbf55186a89740af4da6c073d8c0e331542a2c972a49dd3bf65261dda6e490000000000000000000000000000000006e5fc17bdc786eef8cf2140bd8002ea859619d319126fcc5053be9c28526e14e0bc8eb924fa242305069226d766f71c0000000000000000000000000000000017ee60b0dc932806dfefdff2cdf00efc4d5c81a1e84ce48a25db1d49ca26232d4e4cc1f37b34c80375597587dc183b4259b43915b15c509ab8930979312dea2ec9cfa9f679b004ee526aa5dbb25759a4", "Expected": "000000000000000000000000000000000c3dbdef90052dd5bdb70f15963091c8fccb5b8720a16140ec96dda18eb6cf003b6f5f7c244d25cf6da34f2a1703a9d800000000000000000000000000000000187456c5af42c3de3d5e08936e8a3f411fd6458d017ec508e48f2b634319155428733634e22883492d7612b2bc38158c", "Name": "matter_g1_multiexp_58", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005a912b6b2b00c2b2c90ab1aef8c9240831ea9ff2ac3a92753054f159f5ee4eadab8ef57eb5972e3169ff9649b886daa000000000000000000000000000000000981b901734dfb3b5f63bcff802536492664ac13dc695960ad89342ea865ac67d00da7130833126a33573d55a9baf128a53d5989b63ee5f157cc44c684ccc7cb4c74338b12fbfb534ea33db341fa6b46000000000000000000000000000000000b052881b3e27d232ec980dd99bd0ece4e861cecff2496472caffd741f2954718d605de98d9c27dd3ff473ff12b238400000000000000000000000000000000004de4bb9e5a4cef93662cee72259b88f7ccf8a495b733e868d76cc25e04c53a65a83c853c98a25f7a551641d54ecd9534d840680013af06920dd06bacc0ce95cf0cf79e8ccc0b10027f2d28c1d0049980000000000000000000000000000000016e4d257db25c08a68943e6e0065b375422fc817539d2874279e2b41428da449627e6e04087fd448f651a23fb01816ba000000000000000000000000000000000e80d041b65789b3289a94848ca4b1109028c9fb314e652486e650221945ef4224ca03a693e062b06036898eb664fc211b67d661ebc9008669bb4e5cffef81a32baabd71667a72f1d202ced823f09c74000000000000000000000000000000000542fcc8d668a827daf3726bd71d7ddeabc440a6fd0c08a4730803be6e76613cc0265252c41123146a5d7aeae93f485f00000000000000000000000000000000109a61920ccf34a0a71f51f4fe7c882b3d6fe449a8c67711dda64f9eb684b4a28cce6e8bfcd6f3cb599adbd0771a132dee495199ebdebda02179432d42d5d9c76eead4d4993cd09a93d46cac997716a50000000000000000000000000000000000a65c746a1206b1250598823b9b6fe5df3dfbee21cd31000e50140893875d1ad9fcd4fe12bce0758544ad8cb4cf5ba700000000000000000000000000000000038c25d3c35fb34151428d2f6bb8a459f834902334d195da214ee9fae4bc6099d225588a001f8fddacadeff0d3d215463e038e473d6f965751ebc5f69eea6f37be88cf001de0c4e4b700823d8326f17500000000000000000000000000000000158f2288a667f475c736dce9e404ed37b18d677f984b6d9dafb051b87901e6fc60289161bfcfa46a3fdbea7b4cc3f795000000000000000000000000000000000d7faf96c636ee38347b0046d333e72d601e20b018d554d50ed63e30c62db7fa20e29b3ea57b1f31e0d7544ad711c96aab2af2590309c9b9177e4f6f0fa06339fa720cf1c9fc7c001785d7145a3c9030000000000000000000000000000000001933815ab2d8b6cef8790f87dd9750bc2b7a75a9d6c425a3e84cd109f5f5ea866e171dfc212f6f8641252e9421fe3aaa000000000000000000000000000000000f8ba799ca5dd885046a4ffce1d26688d0bc6936f3a5a943dd54f89d991500908c81ec4f9b116e73f74d46b67731421bc9551f12084ad7d4ce346f841fef785d644821b5c2d3c8db3145fc26e65666bc000000000000000000000000000000000d4ba404254175cdf5c47c08ec158ad83b6ff5b8dd32b8cb9753fa157726271f343cc0cf5231e7e31583877d2591930000000000000000000000000000000000191f45fc4b8c94519d13ab28e5f84e22dae2f82550b44be737728a695865973ff5060a639e3f03904d74717963dcd764ef5823541696ecb88d0c71e00a15282c40d4826220a202be09c47fd6891b93ba0000000000000000000000000000000014d348b7dbace24bfcb258c853b19fcc1637d7ed9b0ec00d4124cdf6d608c6849e8d2f9858afa83ff356380afa1376fe0000000000000000000000000000000008c509beae3cc22f0da64bccd2e0387c05d7613460942d25182605b3eae6ce052540142d5975733cb6554e6da9f473b6e32d695dd02323d40ac1eb9452cc53376ef941237563b1ee380c9824a565008d000000000000000000000000000000000ef9aac66681015bdd9bf287caff9aee89225e30a7976e9f503a1712fa863c8d6d46a80952a1d94d96a5e0496f64ce5b0000000000000000000000000000000016c66018f43bf585195b256ca106f47077f977701d97f42564223817ade0a520aa3d7f06d868f1e91705232b1d2440d9f5e23ff8acf88d18e53bb31476f10fef288e20e818431f9f0d2ffe1265e8ea8200000000000000000000000000000000042d1d00a946085dc6329e852342573db7dda7385e6a50a2660a924ed6202968e787559fc58a162a775bcb115bf1fcf800000000000000000000000000000000162b52027b08b7d91fe0814c7be69414121cfd452f4d0407a2300bdfe9ba81a4561af74d8067e929b71a92947eac4fce71927817449ba5f053d0ed1e567b53b1179c6b62a554c8be6764d7ce203f74e4000000000000000000000000000000001598949030cc21d76a9c69305f023bad3cc761d5f857bbccec4de6b0f7557395efb2d126382731aca994a5020039acf5000000000000000000000000000000000dbea8852edc6bef41dd317e7d70eb2a5416d5087ec5207af3f5b3fec39a416dd9ccf4cfb5400cca152f173e66df05f75ce5d6f0e44a20d0a0e2f1cc523455b001dbeef772d84b2599daec66b285027f00000000000000000000000000000000081e898b02838558c1c9d7ef9f86fefe512e2e7364ad824506c886b4cbe947657c5480353e4f72e237da013d81e5eeb10000000000000000000000000000000005353bf2dafb1b9b4f2cf58e16645aa3fb759eef6eb8f516db068d2768851e7724fda5cb85241aee62b4404de2862dfbd37f7bca1a59f65982294755ddf8af7f1c953b6e482fee854e0d89e9b269e0e900000000000000000000000000000000028453aa48ad0302804f9cac568467668b1dc0dce2cbbaf280810ead2c0a94e156420f4fd2566ee7f629e57c3741b8960000000000000000000000000000000001cfc5ed80924f7088ce6a5414372d13fd8f6eb3dd83c66d8b8e4dd1d4db2bbbbbc6ffac00e3a880d8a8fb5dc07fb23f06d0535e3728b9e358d9ea82df4f1137db7a02f79c0cd0dd672e24092bf7f6b4000000000000000000000000000000000a236833fafc3da813b95f4562804361aaabcd8166780a4646734e4b65e3a1924c075d402404b52adda4902bac7a2cbe000000000000000000000000000000000def6beaad6a180998c4c70f9a8dd0d948a79524b31fa44874908058e9e58caec2e23d5a0787f1ca05a359ca276c840ff56d6810620e8da932c202628c2fa9f0a9f3fda3aa07c262924aa51685d2c9af00000000000000000000000000000000188bb3e69bdf0a5f31ad16751a12c767c86df80f53f6688ad74cb2fb32b81bbf9d60be1182ea1b6c0d6fd12ef73e253e00000000000000000000000000000000139ce5ffa569548f1bb877c3d573136a8eb12e7c69cd21a70526f8724bc67e0b37cf7149dac3f78377ae7d5bf4882a6771e7f672ad398f5c02c989b475d12ce86e6e242d36784308e56178f2a6a1517c", "Expected": "0000000000000000000000000000000006e5af407ada013abf1451bc9d5c08e5ba9cddebff0cb77175b152fc19bbdc48e1498673ae4698dc74d039a671ecdcd9000000000000000000000000000000000c8783b3ce25445209b9f1d8bd3ba539c01d230c07c4fdff38ec902467d5f7e9e8e660d8997939684e119fdfcc963836", "Name": "matter_g1_multiexp_59", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001731f73d2ef1f87fe1752c9d6428de241ba71506c76f31aa9697d1c436af51de363405f60110e8e69ab268280c20f92d0000000000000000000000000000000001ec6ede05f60685e39acc7e105f60602f0fa3c4a6da7342da755eb34aeaa5adbbac4c13197a2c93314ec79f5da8b90177f9a79850b2fd5a281b22f52de085f12bd34e56808496e1c1388804f534d2da00000000000000000000000000000000158d295d41540fb1a27d8200ddf51fbb9d31a70fcb639c42b7fafae4a95b90ab1ca777125092aefe20f856e3291e528d0000000000000000000000000000000019670ff04a77cfd367c5f0c14218b5d95ea2eae8577da10f27d96e58039b7dd7e9f7f75c32f99dae0920509733ff9c96630c1fdad9338fa5236f817bada168a737dd3685b327fb59d8a37329920af4cb00000000000000000000000000000000052f8e8098f9e83eaaec1c2638aad30b043c2359f2551a02b2b95816e1c55d37bbfa6e284f280f15dc174d5f03a7698400000000000000000000000000000000034bc698f07544952274c21f416d8f1281ccdcf6bf53ad352afb15a3412879a10b37e6b8b9fc5f46ad715f9ce7b46e3d0969599bed4899c3c47e1d4081027203c73233536cc6e45aaa78a4f1150a5162000000000000000000000000000000000c2e014d5068adce3049cc326d36ef92f294700ab64bfe170260727117f098727cef2e28dc10fe473a46c98867c618400000000000000000000000000000000005b3ea9c12179a47f7e69690f3303ccae614e06878189b40264f02e9bb26284dde846d704121340723bfd1fe5696410dddd438de35651328de7183dd38820ea2983488ba31d401094e59cacfcd1d031900000000000000000000000000000000119e9fe8723883d9ae8c61efdd3ae961795d79409750dd39aa6f0f8727ca2429856f977697c4f81894061da278a0f9a9000000000000000000000000000000001438a4dca0c786062aa9cb21e26b87e92f90dcc0bfa014f654b1734cf7cdb8a2e62fd3836a802a9917539dd068c6b4b1191f2b2cc76d848e456d07c84c0826a8861981dc84bdc671bc9b5882d387a41a00000000000000000000000000000000012872f4dca3a9f3fcb07d67c76836c23eba3f7957bb77950a4b43ad9c7ee54f53187a742b13e026f8234df9e91659c400000000000000000000000000000000078b9d597bd9b5ed2f7e0d5f8e4a518012591b855c5352fa1450704a33c3cbd5695a0f8da235411aa99aada88086f643aa76094782d0c06f2080d699b81aa04a60891046e0053d2fa757c7029df8f8480000000000000000000000000000000006c414c6611e00c6e98b370bacf2ffbd7ebeae890278a0e951d6aff7dd3e5fb90f82b4e65dd007a3289f97a9600786a9000000000000000000000000000000000cae4750f99ba13f03d3e0769cccc879a4832210d6a2f25b2696099c0cb184398b7d432e801d23200166a4c53a3e70f3049a751a406657dacceb3721461417571a0104e11c1e00805becf71ee77eadf100000000000000000000000000000000122f404ddd6b34938d8e57d9d6ee78c3fdc1b771dd7392944ae88c625f81df63915a87ac63dbb69adf8fdf856a92bffd00000000000000000000000000000000197c20bf1392d4d68efc6ac3bd5d8b53b360e305a501dcfc2e350e3738503ebd44a574e478757240236762db2f23d4310502d56084d1be7179fb735e233978a5a3c2756d780cc0ea6a8aa92b1d1f7c4f0000000000000000000000000000000019195a36dfc449c19b172ec061b4825e4de85fd5b9c633c953ba7a5617973e61abd0de3d59d441f49264a0dd2e781b20000000000000000000000000000000001430f743ee98a2b2f37d9ecf2a7d4dd4963707fd4cd6ccfdff55c3eb189aba2fb295877bc2d3db9032af26eff6485e459787a6720b8db1b4f0e1d535833ed20b519a0e4d2e9fef75022aafef52371375000000000000000000000000000000000be5d90e5fa172a2034667160f635ffc190fa495aa9af51b648125c29bcf9b4b31fea7a7e4b49d91b4a8d081c9aa2d3d000000000000000000000000000000001721ebb02265f698528ae1bdc5bd4500d7612bcab9ea939f552ffd8e9dec1d267dfd25ad4d3531676e2ecde3d2170c4810b47b662e8cc8dd005bdc81dc6d98d0eb98f86b46c0c8f24481af9120e84a820000000000000000000000000000000012b7607bd9f1701ed002b6f72b2e832dad7c9b2bb6eb6368fbe78c48bdfa17b2546574d7876425cca7986fa6839b6da2000000000000000000000000000000001975f41ed7cf252a658e80634872ac495e4b518349487930610906bd396f7fe4af3c97acd0ed3b3f265917560b13e6ef072460e3c5349c8fec9944dc99762625262e84c70f10d0a92077a351335127470000000000000000000000000000000014ddf2cedfda66e12e999d0b280883c546e00dddc0bd17817d6df90b7a614c472cb2840b133eabdc7be39b63e50cd9ae000000000000000000000000000000000b86e0559e27a6061aafc091f93b744a8273032f0e8b1c8b7071baf3ac7008a8173b71f51b27efccba27cb018b25257ff3177c4d865caebf1ef6565bc85e0b0bd51365a6f321e26b97cce887bc3f44d60000000000000000000000000000000010f691744e7094b801c180810b24f6a29c21a13514bcaa6303ae49067bdd001213f13c6f980c51b050a684b525c2dabe000000000000000000000000000000000e4e4cc3769cd3e0e458ded43b5c7c481c17efd3283972919212b877c21aa7abd31cf86ee2bdfd3cf0ef6d730c0907db393654ef7ad8687c8878c55a8240ae9df04805d3e2f194e960d5e498ae3ca177000000000000000000000000000000000b5e86c2be33255bf6f2f2aa8b17109467543168c0bb92a9ce19bb64c5f84188b2e9f93ac85d948c76989d9d4dc9eafc000000000000000000000000000000000c5244fe670dcb16d7994b7db8f933ff98744e5c6dc124e057c05d2697881115a99f983be480e30ae3e0ce75081b261edb9f942124a381b150f00a59e4579d0a2b7b728f62715633288fd03d01dd12dd000000000000000000000000000000000df7f56643536b20f65cae1ce4c67c6bb6def8c9b514d6edc92673ae743a2f4e4906aaf7e3b048f88f08a4f5c9f85c8000000000000000000000000000000000176cd183f547a3f38a86d604f8e76261755f72e7222f3734a456a3bf7029590848970e8836b3570e9a4f3500e54fa3008e6eb65778a328cf899f66581ac7a4a89e0e824c15573bc68c02cdaad89cdf240000000000000000000000000000000003737e58505d0f4c6890c7e03d5f252aa682c110f5bf5dfe8bcee9393104393f4a6a22c34c773e1dcb78881a31b33a71000000000000000000000000000000001988ab3430de7a463dcc2156db572c43b68e58ac2ee26f1ee1bf8e9889f6cd3250e5d7f9464a8eabb127306af39c13140940e3620c59504062e4e98b5d4c8cbccdb017c47a094d06253743c29465731c", "Expected": "000000000000000000000000000000000d541103aa046ef53761e929d50c88796b90b3284668a2a75ecd461ade103f086fc443a3681b6440e6b8a8b9558870f20000000000000000000000000000000014120e26b160a37f8e18faf541bb863ebb425fbd0eb072268a12657b6e5ff62d4c0e504691b3d09b710741820f747b85", "Name": "matter_g1_multiexp_60", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015c91ab58aad72af3364a3d05e2893c756a273b2c731ef421c0552dffcb32fdc4296bb79afcae2d3c8aec6e0dcd27c17000000000000000000000000000000001901b4fec7a1324a34fe403dcc51656145fcbeb4eac94f955f4fcc5ad6a016eaa436878e85dcebd8992e1a177c5bdbf80f2f697ef6783390724e04b81d0e18dde6533eea9f72c1e10bc72c7b954659660000000000000000000000000000000016df7578f74b1ccdfd537a074d71f2dbdd581f1a2f78875a7d4e1c3cb772aad0d02bf4935f7b08aa5163e82e5a747bdb00000000000000000000000000000000053931dd0624377808705d3fc6e12c4894414c8f6a5662ffd71251bc7725e6d23b7781286b8be1e35eb615bb1efeee9c34680b934e67bd7518f0d6a3a809dc7faf845eb71d0247291d61053d5cbe0ba200000000000000000000000000000000056f0c5d78c5d4e97fcc7d6c3132dc4cd802eaa1bf18921d039274104b56e8a701c25de6ad33e57997b2e8491d7cedee000000000000000000000000000000000c87632eb73c464f53c15ec127cc5c72fe6a413e74313e80395b55e122108e2984eee6f53742ce4445f455108002398fefc024dbceb522c02b88810ada9a814bfd085fb63d570663a64bc0658e5ad02200000000000000000000000000000000040f1ed7a9f7c70a546088822088c476f8954681f3741cffb7e6614dcefe2963253599acbd263b988af3764331a273030000000000000000000000000000000007f9d150a4b34b9a6f872f9bbec4d2e0795d02c5411d6b3a844ab95ea87f9330662c8b0789e12a8f6dafa2f7cf2f13a12c136f00c97a515076f6a0b63faf7e378f2cf04f8a90ac942fd70e25e683cbe70000000000000000000000000000000002890e211b1969c72a15c0f24b21dbf672b2cd33ba9ab79790c07f0734709bf13bbef4f54bf17db9629cd7abfcf1fc2f000000000000000000000000000000000010f13eb17ab7ccaa0bf32b8d4d38760b72fa0fbbabe04017d9d8283f6dcc5500a336339400bdfca06749f7c1e08f748b033f2270ad2416d03dedd4bafb78ddc598810768fafd349a42438923ddfc93000000000000000000000000000000000f7e328026c07b116dcb8950273579e0c4af027bd3aa442a41d279b1b7d87d672154d2513669428e8f401db490404e6d0000000000000000000000000000000004208901e02756c5a2430200d562c0ddec0224446b3fca62cc98e9efcfb3508f50794301b026d47eb99aee210dd2f898202d0d506bbcd56c92bfc6fbab36bc96716de1af02aa166e7db2e2a0a4c19cd7000000000000000000000000000000001309e8c1cd6ca596ab2c9605ed0e356cfb97c4079518b0241d40a3e0e4769a8e58c0ec6a7bda173fc427aaedaa275ff7000000000000000000000000000000000143b1d1bb451cd56d800d71a747173e56b75cbd6fd28ff4abacbc1dd87653abcae715882af29c29a1631850694c5aff8329762dde1c4c91043a740a8b9639e83e809f749fc8c4853966cb2ea520620a0000000000000000000000000000000013bf8880a6c95a8791b8ec37c2188e4c0c2cf188e2fba01a9e7e4b81116b10da49415a0588385156e4bbd45b168467e3000000000000000000000000000000000be052be3f3278259b6e01d9d81afb4d4215b0b738378e56719403e2ed31bb6e15e47c9986aac19f79001a76f35e4162ea46572fdb37fe282203172c147715bf0a16e02a62bc79f33cbfe36703c95a730000000000000000000000000000000013b27128d2e8bde36f11503986c226a1613ba0779de9b25686284d12bd995c83e0db9eb0b2ea759ee81bce0ed2c0c2ad00000000000000000000000000000000128d6ea67c8cc9ce6eb93111780989b4b33afff45a5075691026ebcc607e61b7a48e2549ce8286cfe4a72b182073f373b9e49472b9b74cefe5a951febe595b0020c43fd54150445fcdc4292c5ffe65f600000000000000000000000000000000137033427de6a6d23e0a2fc17d396114f8f4ca3e56e42936c96029c5b829b3b8b7ea46fa47fa39f6e5dbcd804873d3ab000000000000000000000000000000001986563cad41be453d14ea3f166c2ef2d89ada32a345554ea7c7141f6b1306af815579d7399c73039d1696fb62edcf80b6bfa1ec877010aeab030b96e80d2e27b45a93c6a99e2aeb3ccef22527c6e472000000000000000000000000000000000f0878d6eda3d119eafa0e5cd0260cd5c9bed5fd3251f0eda5a6aab6b475ad8982b55a0c8c07b6921de77c4e23478f2f00000000000000000000000000000000181d4cc9e77cc1e21145457948923cee50db145dde59520e6ddc2da13c3380188856c220cbace98f7ac4bcd7dcbfb1812810705458845232e851b33fdbcaab01966b8ed53b455873a966c1d6b8936389000000000000000000000000000000001267b7c2a91132c46ec835a5c2ea1f1c1021449d4ab3c14355777f1b7771787ca8b72b61563dc7587db6318c2661551f000000000000000000000000000000000d9f7257977b3f207e889678b72b584b84bf736bc23081d1267145a886e2dd6b669bcfd8b58414def71c27cae868f39a175fa4954e56dabfd1808f93d2686e0b4fd285bcb78b80d15e10e63ea8c7b6460000000000000000000000000000000017c223749282ef77696136edd0b30041b7743e40c2cadf8b491c2dee0730554e39ecdce41e45d647340e73bfe77407d900000000000000000000000000000000025924e40885fe566166bd4c5de6e5bdb3ab993c154ce908afeded5614cbb0c00e6ddd648263f17ebb3d81bd6a4f79afe7dda7e5373d0e0afc3da1507416f47ea8b467a5b6c2fbde484aec8777ab7559000000000000000000000000000000000730c41758d12795c7e5540e4204e43c75a01dc6263833f8db435117429ddff6cf4fbffd6cc27f553b8524710aee9ab000000000000000000000000000000000154c3ac230c725594a3c985b7ad71d98c172de8764926e74f6932f5a5d40543b5060c5d604877e3a8df093927b0b171c6aa731f9393d2bb32adf04f19884dd1a5e7aa36e46408b847222a153da95aea50000000000000000000000000000000005c6852bd3eb4db383e9aa8c74f4c158888ada1c9ba07ab8c7b4abe9c05bca51f0065a29a814892303a42a6f2736043800000000000000000000000000000000086d733e758dd4f0f911df6cae3d678dee3500a53d8a364986d88c50576ca6bdcd10fd31f3cebc7a35f43de1d90ee4bc985f367919b0f3c667b1c1cacedeb0be1f9cb175c899992ef55f14e9b7aa6ad10000000000000000000000000000000008445e5c464c4e10fb0a10c97023c5a9b169d042971597eff4380821e44430e3790683c7c66afb89921f06199c72c87f0000000000000000000000000000000017e55467ed664833131b82a2875e22fc5b29a3808639e90741b731d4efc0420b4934fc75ebc2048e8196be55a600f9bca3041cc52c6f1bf62dee4c61b1c5e35b72ebff7e8e89b05353388b551eb10010", "Expected": "0000000000000000000000000000000004f03dd7334a0dfbc7cd3b74a8e06ccf23fad0802e44c95712e920a2b227f09ac3d62429f40bef8241abe41575cc541c000000000000000000000000000000001092b20e8618beabaee18b4752a5b320307d22fea2125b3d23c6ad178f0cf2af7a1a1c0af3cfc669929087235e2f8960", "Name": "matter_g1_multiexp_61", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000121d2cecb2c9892d69e6a15561688edb5020dc39fba96eac835c0577ef017191572f8bba780a608c41d53544d24a306100000000000000000000000000000000080c59704a5ef9251654458bebe25d949bd5c7793c438a50019a9a7cf26036f014fa3f024edb767d233dc09710d53daa709a2e80dd96eb12edc481e3d58893bd0d789a499d5289072d58c2ea80b036cb000000000000000000000000000000000012be549d6b4efbe6e8c17393390f3cf190abe4621a16e951203747dc7faf6d6ac831582fefaff20c952502fe43e2020000000000000000000000000000000003112e26ed614405376dc1af80b9f1984439c0b67863f5cee6d3c44f74f320e66574aa1501376cf8f924efd83655a72b9ff35bc510c86a9e72c3e9c6b49d2abca546f7a62330156ec09c6fe6847a400e0000000000000000000000000000000013b6249bc071ab2f9f048531e6bd27a1b8a45d34c66623268402bb37f6be2d71bb5127461221089ffead4a9f6c708f0200000000000000000000000000000000016a321e986c6301240b1e9258423bb8f38012ad533b42cb487384d9af63713d4b84c383ebd4512145b3e518e0c935b1391dd27628d0808d4a0773509737597230d7849418540e1fe4498fd70d39d16c00000000000000000000000000000000069ae7a90e9402d4f9f1b4a8a799fd5bec30002683692a700ac3a25f8f0a8ef9fa9e6f34844a6c320877f4b4883f36e7000000000000000000000000000000001214fee37b448c79b5c3097dfb65f8b181f16f0daf54861d4e5e7297db7981f2ea20622d12acfac04c066fcd23169f0294f11b10e4c45f15d811e3db4b947ee6414e262965d7b5c23a731b019e63d5130000000000000000000000000000000006e8cf07f48627571ab5fd1a6f988723465ea3f741b71b9aa9156c50e13d5481d66f7fe4006a54cb283c6d43eecb4ff9000000000000000000000000000000000ade4e4a949e6dcb45cfedf2eeb91abe406cccbbc7b4c7804b77d04fd7cbd91fd44f0053196bb344fb8ac1ffa37c83d470f7a0ee05cfc3f63d46a3151c20da53604628bac70d7b521b3be65d7b2abedf0000000000000000000000000000000006b130d66b74b99a2048127c24899ea6ccb0a53c4404f36371f30fc1ea99d02853d4555385a9fa022a552b85422daa71000000000000000000000000000000001824d4d0eebb0178947adf316258d297698ef4575d8ebc2bd300558df914fea04f0269fe67205db1e3dbbae74c0db22bbd991eb5e8ac8ad7cbf8fe64a5889b715a2409305f2366b278adcd2144d7be8c0000000000000000000000000000000012ba5b9c8a86cb99337a7c4955b1a1b459c8a1a7eb6ea908bf27d5f7e41d5f3423c1ff44b4615c689df14709c703e9ae0000000000000000000000000000000008627851a30e33fecf67dff807bfc5430a77d0a85f1e4f8b790b2b072fb7b86d5e81b934ce197fdac6aea60414a616541a9caeccc2a2058c2f5a271c09036d73320f9bcb31b7296a796ef94ca4599757000000000000000000000000000000001051ddad286eaf9c9ae5b3757c53e324acfcb6a1a7d5b490eb9479e337c9824bf619167bf8f2aa5c7f175da534e91a10000000000000000000000000000000000754b16cc6cc813c5c4d44eb4488b04abb659d89cf0dae5fd5f59f257cb396e139443a99b71079c5aa10f8f48465fc398ed4eec02c2af286ae19ad5f05642587cb9ad93196756d269c783a11f23393bd00000000000000000000000000000000035732a9fc03435f3dc3e31af693b1d1ae79110cd46d07541a35b956b928cb4a2de2a16cb8295aa8e8d0c74556b8189a000000000000000000000000000000000d4e762f40fcf43635151631fd6238ab3e1dcf578dcc84d462dbfadcdb621be918f1f0a7015377b5ff9c182494ae149c26f20eee9bd019f9e0f5c794e22e770128737198b5f5dbaf5b7d18040443a0bc0000000000000000000000000000000018f1eb31d3d4e915cd1e0cec33b4838da1401c6667d8ea25209e4c5683dce96b1d7adb4feae7fdb80144c30145d7f35c00000000000000000000000000000000050693e8b9c90d12af4ded25e05df86a3e233425e2f77c7ca9e99b0868eb8d9337186113b078f8083a4273c9411ac1dfc470a66cd3428a44a7d095ef410126257175597a333cd36ce6c9822d1ee9bb38000000000000000000000000000000000e1ca58d3eb507f977257ed8bdff474a05dee19a00818754e3a85f1cec882b8e3e0296d5c3788b101da669a716772936000000000000000000000000000000000532526ecf42eb00da76db02ab6236dc51a346f0a1271f1e9d721a40a4569d46fdb63e0211f7986b98475d81998dbf8be53fa8fb708204e619c221b8ecee14fdbcb1f94731ac2c858787ab33906c92690000000000000000000000000000000017bcd6bf54d51fa12356f3428f02ad8ca31131a77951459d32c554e2dc2487be1bb9f10450e5d1f38af3cc7de1096a9a000000000000000000000000000000000b7b5ffa4d08175916fcc542660c85063e8420987b2e16ed2ef9464adf928a4c0b8e6d5dc870b4f00de8bbec6f0dbae3abf8de43c54ed59b936e1d55032eab5c9d9e04e83e4696d969c24167b4239f6200000000000000000000000000000000151e2e32203b03a054459fe391ff4a4e962ba5e10ff93a1592043ad968c9f968a6e50b5943e50815268a4abe055a1a4a0000000000000000000000000000000004bd116c6857c2f4efa087272df160b765dfdbb842a342f9cd3e5cff006030f32e5a8b60acd8a376378096743000b2fe95f59041329b6c3e6aef01d3410836852f79cc436fcf23199e0985c56f65c4f0000000000000000000000000000000000ab6c3210ca0b70b2b3bb916f31e17b8632513b15a99c7cc61cd21181152bfc6ba6ebaf8e96a05d0d2d42a9dd3b61a53000000000000000000000000000000001308a33fccdd6cc8990c21fe7ed03bca42e3ae24bf07aebfe6878c2c8316a7a52477c929fc7c67a3a13ed811a2adda7b740e4a207ab5dd4a0621fd65697f5d30b8ee1440a5f5c5e74a0dbc6b6391c1b00000000000000000000000000000000010db7de8485e5504211088ada8924386b36b7dee37170f73469bc77212d56c3dce9802c7599c83c5cc5b18883cca5845000000000000000000000000000000000ae8d817daba71325b57f81301c17f401a6870a13506de2a443602ed44b6b0824e6cb763ef556908f9b3f30010f86394f49a3f82d25c6e0d69207e6dff010d56f0d99b28fd986c5711878dcb6665b1f50000000000000000000000000000000000fc19f1ad220ef5bd76cdd7d3ca08539a97514bb21429af5b1774d4c58a7e4ae137505fc240dd0ec01d1a9eb06a157c0000000000000000000000000000000017ce712d74d68568a945fbe2e0b21c180c58e9297f1f4dbfb0775a133832d4d8aa0688f031385190324f1e8ed65bd5378390fa1b452f887ef3afc7129ad8ceb9a8397f7625c2b249d7442566814ae0a9", "Expected": "0000000000000000000000000000000016cd97de498b8809f4de87bcd5a66c41c231653fdec9bc1ebae0ab3b8c56258430bb13bf400f5f971a1ec558ee66ef02000000000000000000000000000000000cf57701a5038ec26e4027c3cc5a8cc298c2d86e9425ae027dacea92d4d475130487b2743c64459990e88768d8b7a4e0", "Name": "matter_g1_multiexp_62", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016fb67277c28b5665f1b7aaeb1bd70f679b507a6b30f956a1fdc0d522e430cb4a9c089093cfd14714f25cc9498f89b610000000000000000000000000000000018ddf06c643bd77c953a0bde77e80e77334410d76910dfb587922e6dff23e821ebbee2dd546e65591726f9743defaf9a414ca9894bc15e6bca798544138689b2471f8171a5dc48eccfa36c83af142b7d0000000000000000000000000000000011d630f01000c6e1279f330893a18b903b7246031d7d05d80d4172b08e1da182594cd42934de3d1418445a76bc9c8189000000000000000000000000000000000c3e335aba4402bd3c711569e466293c15d89f4893ba91d8690e4eaf4c7962da458471e8c7f22c417abec313c2fd223399eac8ce85a1bc70c725a2f04aea3749d75d22c0df7c0755a5e76ab4d82ef942000000000000000000000000000000000c38e3a1c95f0faa10980976f83d85954813faea27c120fc3102de51096f6c3ce89fc4155c6fc878fbd18ffb32092d7800000000000000000000000000000000178d0c64b3b7da5b6f57c69bccbf73e329b18e29e9187a7af31b9b8e480b210dd36589540d77b3041472d9612b05693a49b25140d7967b0438e49f59a6b04b75bc8745b84d7350605be548c6b4b3aeee00000000000000000000000000000000146c5b46bb4194ec04b5b63f09e8066f24e350cc62fce016b8a25ae57877614162f2733a5df8909eeed2df30374004ba000000000000000000000000000000000cbb312823ea25bdbfc4afd00cb65748401b47ab7dbd5a40905162c1ea676268745af11a2770509eb74aad45663f7f5b6e30a51d55a1ac94089d0f3217c3a2182da6b02ce70ce7dd8e2d4e938bfefa9d000000000000000000000000000000000ef489c4443175873e33111e9ebb3140ca0796f13ce8d34b30d8fcb7b9130ea0574754e800fa0ad15d71c35a3584e11e0000000000000000000000000000000018bd8ba66d5b67537a03030f5ae56c01e640021ec2524a2cb4b2005ba267e737d27916dde1e94d1f15b6d3e1d480ad82d3da3db6492ff36102747d9d663bc6e9cf8f75b1cf77044989c7af3f11d66ae700000000000000000000000000000000182acbf5e02a0b1344779f7ced01961f418fa8ce94f939025110823e5d5116d771328362498324e1067a3419062341aa00000000000000000000000000000000174d3a7754b18715722a07ecff5ee3b7f30606c3c573770c88703b6e0abd9ff4aa4bd2879c4c0512f879af95554f47316de8753f3df8be42b6d6ab578096426f852de4ff545d2e4ac12c3943b044b43800000000000000000000000000000000178c3a28f9333be85ff364329fe897660261092d9bddb36687cdbf5a7a450f27060a3aceaf45fb8acfd123116f195d8c0000000000000000000000000000000015e0a930af79ad263b115dc733560752cbc4453f111550fe3e9448b6818a75babbd0044b9b4f133bcbf16f8fb7586055a28f7ef4b12c5097a15fa6394a4dcc3ceed6cf3c6240ec2ac949bc21a9f6447f0000000000000000000000000000000007fbd9b191af6a797c68ca85df2100b898e3a4d9569c717e3d02c259eb4dff3a1ea948e56001f33a3ee1c74eb966b6260000000000000000000000000000000003b892510d5073bc3597f8f513908077814a7efda2df6051c08f7347433703496e522d70ad4093f76a3e5288044ba5dca3d0eff3368b10d00566f35391bf43c9d204a4444b7eb91017f1b2d8a762d90c0000000000000000000000000000000015d26d3ee6fc5f98584c206466d2c1a4323f597e0ad665b289e76184770e81856482c9f45ff8c891622d8de353b172e80000000000000000000000000000000017fe0582d363a30677bca1feb6d7f16be6b07d6e5d6b2a2080d07ca306d5cf733103f20403ceb486ec703277804e7971b90d76e660389e570bef756e9785e39b9748aecd7a34556bac8399aa5564d12d00000000000000000000000000000000108de390a69c6001124820072eb5d9ed9eb5b5a6199c33db1ab0239c447e009df4296f5324660e7ea1133df0c8e6a9de00000000000000000000000000000000040e7b3392a116c7289644f393bfb24d84b76d8378c042d86cb4af861af42374b709cb0ff5341e3ae9d21271c32c0a5914f18dae096e4de75de3da284a5755efe51e912e180020a20adf1f5de43cb5180000000000000000000000000000000001ed57bfdd0542efe8734b0af448c025eba4d60053b7b45baf682cd310f4c2ea07e708bccaed390c2b061c89c2855c9e000000000000000000000000000000001496190ccfc4bf428706ac344ed691fbcc7b9d6a456f2653f0da421a44653d4b1e9e967954b847a4e6014df15ef48719e32d4645ce0172000fd74f30937261de89753caa716dd03a8b3269747f2349a100000000000000000000000000000000147e5056444c7ea97a319bc71a3ee4188f68b517b92c64f556d22382389c5bab95110728cbb7d525499cc3b2d70541b1000000000000000000000000000000000f05b91c8d05b31ef6497595ecee6a6766f03a006b4c2da408f4d7b7601915cef64be69735c269007fa23e5f91fb07148c8722e3e929ba21f1ed6c51fe5ad4940fb13d63e0293893135d0da5e6e038930000000000000000000000000000000011b1b7c28754f3dc8b21dc823fe02d617374bdb9b96dbca572eaf8897f98ce9409ce8a63eafcf5308d8236bc3c18b4960000000000000000000000000000000012360ef03ee4dbf0bad68232b8454a26b666d827bebac03da314b2631a45cd365248316f72e991004d0158f89ba5811839bef6ccc893f6eed62e68f5f2a07812f2d3066b89653431e7e39e8596bc36520000000000000000000000000000000008b563f6f97fee7e2852b44d8e39ca314963b517116733924d2f57d9c4f202b47fb3fdb85fbca42ffedcee290050ef0f0000000000000000000000000000000016112f264c2b3c838b02b78822d27f6351860d10da3ccb763c1650420bf22755938cb45c7566a2df0e4aea4f0281262ac395ba8f2553e3eced8a42b221a710a5cd2a5ffe5834d3084dc260ae0f51698e000000000000000000000000000000000a8397b009cac789cfd496f4f1237e92ae570f67b4bfe7e8c80171bb9d9cb53201c2ce112473b74646a4948d7c10c338000000000000000000000000000000000092b7425031fc7c328e3be114916a06305b62ffec8e7e93a591fc5f4f9022333cc664057ff6983677cfb998defe249553ef5568a766b6c39854ba059f3130b75d7fd870bfac2b00b626e2d71c4968e1000000000000000000000000000000000df6739202d9f1f13145b697d5b78ccb84845710923a0f3bfd5a3f337e200b3ce5390aa185ddbbe8088462926a7f4b40000000000000000000000000000000000d00ec3648b2e5790ca7b05ff32c6bd3249296bd693f520f6d8385f15dbaa9f808d770f9ba28efdc4aa6bcf862c17c4abadefc3880ca8dcff10b8b763f7d15f88965c2261b72ba879e3540a90c59effa", "Expected": "0000000000000000000000000000000002665808cfac4b9befb1f285c590d639132adf9d36a4fd460de0b3347303aa056a14780deaaa02072fbb08e1dea06b940000000000000000000000000000000001ef22acce32662085c53b2080df9354903f151089faffa43c5f6a1a306d2254fad240bb1ba3dba4927ea5640347bac4", "Name": "matter_g1_multiexp_63", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000194b906ed067bab0e26b9ff4c0ecd909c6aa23b5cab3a90d1761840b784bd2af6e9f9ca570ba6643d4781885553f3e4b000000000000000000000000000000000e8a480cf75e20cceb6e1d9db5594d19849aee6d45bb3ca7c0311bfbff8263420e0278b7e814088abb69e73bab6368a92c1a5abbddc02f453519563d6b6e05959d8de5feb493f7c58ea5e548cfec2df60000000000000000000000000000000019ab570a48bf15ce6f007b528d7113cf423e1c04d9af9497dac47a69deaff52dc9fc4d202649fced07378b84fa1b0054000000000000000000000000000000000e3c2971aefe89a629600a243c7967ef001ee17f9ac452a8131ea44815ecb6596f4fca4f47a316f62234851dc485fc50b406eb0c097237556228f3a48b7e770c1707fd583b91b4b6b70f398b7dbb0d3c0000000000000000000000000000000001250315bb81e9ef7de73e709f18003018fc1c55f694c0e28152fdb244b07dd2d7812c3ecc4ba362fdda0707d02d697b00000000000000000000000000000000188a852c5850f471d4ed207d5782518f189cd08d63279c4cf19c76122df0e4663217f1cc8374c7a02d99bf6d59a80457ccc30cf1db4c6be6dbc5830ee37b5782c6dad215334163a9d9e4deb962186f80000000000000000000000000000000000df12b5c659c17c808d8e875a1b9c125396cdc3d8a2bd6f99def15d9fdd1fc7fcbb309333cce1b778612d6114bba63b500000000000000000000000000000000019f11577152bcb0229e168a8e97804e8e00a58fc236c8ae59c575c07d6a3c1864b7c8132f245aeec55d999d54745cab99461c0f12019b344a7f322900b64fe81e0d8a052c0ff5e977f58753b1b6edc60000000000000000000000000000000004b007a33b0ddefa5ca9379614f698dbdbbfc6bf8bedaa485dc360cc759ffa4ace304fc64071e8f228a8882d5bbdce22000000000000000000000000000000000927e9f018b8cbc2f21b72f0f19994705197d4b6ab3f03e231e51b9cb3d899fd8f8b71feadf3c9be61994936535c61e8338ef9fa825e47b46483ed8fd2df64bc7b56da8aecbae704b7eff2e7d426f27d0000000000000000000000000000000005decc41dadef7dc4ebd8911af09974686531907e41dfa16c857fc3a2451b96069d06ce1159d47e6f1c97cdd932486d4000000000000000000000000000000000151d369a147cae5d78eaf7ed99623675491f20aa2cec9700053f853551208fa21e085962342072c96d79233bacc7adc1dd6656a34f3b12e5568b9c348fbf4ecf50d65a89e63ec0936591f01e6cc7a4a000000000000000000000000000000000fd41ed8d5b7e5ca6a6feae98592217dbe676accaf6e73062d9de9eced8af59563f7f441a50ffbb591b8a987c47988f80000000000000000000000000000000001199e002504726f2ce429cdb3da304f9b54a933c1937e8dc39a3a416d068cf46f411b207d9c6862a50962516b2867ea5202f32528e795e0fbe6deb4ef6e45efc70019520b01fa1d71d5505e42faa69a0000000000000000000000000000000017cc9741662834dcee7af988d3e4de2c30d4f9e90f2b3f7ad07f756acc793c58acb2a04c2726129d0f0c959f1d3154650000000000000000000000000000000008052061afea4c307df56a72530effa73b34beea4d731b1562de1e985ef455d39b0d6c57008ec092241262dd611ec598a2b39f2b893be03ab4da77ed518ef35b2e24278d707a20b67ab4d1e5972f97220000000000000000000000000000000019adb959f4807d3bf7e0616a8a3c02e9babc94b8ee9f8898f2ddbc8fed7a5bd88e83c70c5a98afa823a0f46560e32198000000000000000000000000000000001189adca458e0ef67fc686b5a94986be37c414cffcea5b4fd44430c8d5902512d84200007a93104048160ca3f5bbb9a8892eb7c361f05e114a645caffce9437b7b43fa01dd66c1e75b30f3abd0209bcf0000000000000000000000000000000013d55a4b466ddafa04c5690628dc29deb0ae9115a4549767b2aa22b8aa02a13f1db82dc86fa3df85a6a15463fb0e7903000000000000000000000000000000001488a03340fadc9e8f7552273699870ad444ea513cc7bb91259ffa7cdd5e7377d8fb5510adc2502fb8124d7914af85d5fdafc3f57d6116163f1da9e70ea645243c5911cc4ad4a969a57c46c6b5c73acf000000000000000000000000000000000a847c98ccbccdec67192529c3da593f1d6de5d7dc0bf4452e4f09e93c2c406d6eaea30431ba95568c92938150a00a05000000000000000000000000000000001201397edaef2f9b89dba7f67b22088cb954f95b9db3d1c11bd77aa0dc94def6283af2866a64f0028fdd87b587669f31660a77b2be50eb72fd108644d913b9253209972fdec2d107213ba47357c96e9e00000000000000000000000000000000017f76412c8e679676eb464204348d591221ba17a1c90a22b2482991deee6b61edd7520ed10b0105426a15fa3282cbff000000000000000000000000000000000c65a821d170a9726e947868d861717e8cbcd2438e4d4b8ffcee38eaf033f8f3a57af68ab6314a52952a305db54ecb361ca575cca348dee9adfe68f8a78d39bb998205da2a5285c12141a77ee7af84090000000000000000000000000000000000b14fc1d34bd7d85fa96a4d12ee99a6d327347dc63608f94bd750e2096dcf11066e384ba3c68610c70dabae795e668c0000000000000000000000000000000004f3ac3e885cadfaa565b1ec15cb81e3fd4d561b2a8d92a9287bd0de893563676118d34a9ef3bb3112aa534605219feb2e1e4537f855eb478274992cba4e3f50fd9e944f6246cd52dd1517b55bd7f71f000000000000000000000000000000000979231339f20ffaa38ed21cfcef923fc9a4ff77f7d6fb4df212a530ff456a32f50a77d2e7f6d87c4a58270c006e68070000000000000000000000000000000011ff95871a91385ffeafd8a609a0c562bbeba71a110081e5db6c8035d8176067a528f4d1c6d7dad43b3bb8d090077e1357f9a729aa01c8bf0271052202a077913a9e0c87201a367845f9b271c130e95d000000000000000000000000000000000e2c7c67fd50bd2cc8ab18808a69d62bc2d3f110ef49a02259163f8fb152da6ca9cc771d1221d7719f9bc349e68594120000000000000000000000000000000008393769453eec7639d66525d6e875bbde7a4a28c434c82571468d496c4313e12414f929139c482569c003a6c0dccadf3017593cf311989ed8fedff72bb1f14f72cfe5bb7446ace5274d8ded54c1372f0000000000000000000000000000000012cfa8448935a292911ae6fc175f3049eae5e30d714b3439f55be9970ca959f218157097bf9837125bc8f772968b0d52000000000000000000000000000000001747193c5402daffffe4b1ba9034231321d01966befa174f526014d6c27fe3683eedefea8690b95c8f71fef1152929bd08bbe9e7a307e380c238ec1f8e2010a95fff8b03923ecd9b012f99e56c77a5cd", "Expected": "000000000000000000000000000000000bedee9e836b3e046bba7fca7632d09a5a25fe1f0fd25cc6ae1d1e07d98ec52742a60bf346285488dc84b2360e0db58900000000000000000000000000000000071ef77988eea20a38fe33564689a39a7113b1715dddc1b212c6edab6bdea8de54089eb7b49b63296792bb2f4aa68733", "Name": "matter_g1_multiexp_64", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000b7db363585b0061a4707a2ee67d6d7220e9209b4eb9a59c02aa6e177c948057826780f292dbdd824d67ca9f78864cb000000000000000000000000000000000a31f49bfddb5c48730e1cd429f128a540ff44b6a5031e7975ec0c6661f9f3f2b79ccd2d13cc1b50d50ef9c7f658d412cc5e9d01f6ea67dc3f943d57d9d8b5791d823592f7fae6719804c1ca097e651d000000000000000000000000000000000d4fb266e9fb18590037394b18971cad5840bf89047dc11e52c90284642be7e27007c62a1e331a2f90ae67313efcbc0000000000000000000000000000000000047b518cd6a7d7c4d262d1f9f5f11480e30c626d45fee2d6caa274aa1353035a3c42ba96b5875de36442aa5d4b92d6d257b8fcb85e4dbc1969805d814e75b2b80f5cd1e5562bfc1e28becf731aadfc58000000000000000000000000000000000cdc9bca5cc807710948d5189dfadca2cdfa6fca5496234f13024efd84a37070a2fd51a609c4ed6aab54f8687ac9700200000000000000000000000000000000011bc450e4222090603ccfaf7c1dee67bbd59aadafc3810d3aaa8362fe43f48952320e25bebef482c5d21a541400df5a03edc53ced9ec5d7f302216fd30a81c3554a3fd04994f62b5e3da74c8b71bb870000000000000000000000000000000000015d20abf274edf0c9d45c2675e4af7987e98005b2a0d128ba7df6b16b88784a7134d37d0da2da02557f88d26de33f00000000000000000000000000000000190adb20cb0f5902f7e92f79dd6e7d214eb892834611ef222e9a80ade4c7cf96e0b5f9382b61715e1701c7e9cc4f4ba5976568ab779e335b8dc67a64f15b947e69cd3896ff393f51fbd3c3e3a157543f0000000000000000000000000000000017dcf175327086e058e4696d689f2e8a167aca5616f2317b7673850a2272fd5742b70eb362b37874d573cfefa25ce3ce000000000000000000000000000000000e5e1af08f6174641aaf4f1584ac40d53c393314dcb1c405263e8689558445196371e2858a4f44d605550fe0f15962223aa5eeded490a17b1cfa66d409811741643b7beacf312b9d6c8e7e7e63579c830000000000000000000000000000000008456d980ecc64b04a203d61bdb78bad67b4568b2dd9a123634cefbd7f7077cd9a4c038c0aa3654915c12242dc594b37000000000000000000000000000000000adbd582b0a8ac28ab21961476e163255089c2d362bfe9daa7007a2c9d8d261593eab22a6bdaa9740da81efaa24cc3d5f9f1f9313bf966ea3b8f09bbe9dcb66a7f9e3e94e2024c49a72ccbbe03fe4662000000000000000000000000000000000b02d326ecb5c04ccea4cc3d29f82117f3d97f788b8e70cbb346d43d27e674540c7a94d242d290e55d992eebac546c9b0000000000000000000000000000000013901f8dd68285d73093c30b37419ef8e4b28371474a040a2ea293f7274ec4d6ced0f32686405205324740884306e3a693be64fc3763d06111961bb208a2b858aa1ff181781dda630ca41f0d45ef2a9000000000000000000000000000000000181bf2fe4bc67a1d10335a0ca9427f603610646de485a7cf039f0706c0a0858ea694db3b3e5ca85317c98b5cd75865420000000000000000000000000000000014b1b652e2ec7d05956705f692860b83713c5cc98c6532b3df50259f27f92d485e8df846883a4af4e46020ae54038d955d2a2b6008a3b4a4cb3a8c28864214c7fbe154fedab1f9ff8c96eab6a5f28fd3000000000000000000000000000000001084f77ef23ac990b43363db38d652f0e6dc04a4bc395c8018083fae6fa6e42f463af7748d71f65b14f94632ca0eaaae0000000000000000000000000000000004ebfd75ecc9cea5e49082e1adacf6b50e4f14600d9343f6459900605c5f36ee51e95408a3005c0c1093e41794c282a0854e742ef7c76ad438cbf30c30103741f57ebbcdca4d6c4f14e554dd1ed81b2400000000000000000000000000000000062a062d2ccf5c131e1278a63e713ebcf8a221e429b52b3a7688f7e68a12558fd0f584e03835daa3988233d6a84010310000000000000000000000000000000013e9330d29635892fbe0742d1a8c96ef527b78ae389385a366b6dcc6a04b8cd1d5b8bbb79ea649179e78fc061d23cafd6f4f00b2494a32844e01d0827ca78b06f5eb40b6769f36a04f20eea229c305f9000000000000000000000000000000000b131e0623b7f30bad70145cc4964257053f2ead992d28aa5b24c04bc316d479d077af0ff409cd395a86b808bd3e4f02000000000000000000000000000000000380fe6e79e5e0a399365d73244f2962facda8b7b381c111508819309ec5b1d3d8783067245dca26641a966969dcd0ab191e47a0b0c72bd17319063abde7df51498cf0c980c46946bf80ae4c9864e2e20000000000000000000000000000000014971f46efae601309f3d16c15ab5c46ac48d2199431fd959cbf4efb768ebcc4f410fd66de04d3280659004a6b54e64700000000000000000000000000000000113e6438dd8088e73eed84d24ec286a45ca51f0fda88c7ae3f1e6a2195f6b11877e606773bb9a8db19dc92c3b0729754b7baf8816db56c0a602cfb4caa9089136ebde05722ad4838671e45ada5c716f20000000000000000000000000000000006fceb59d8baea4a10aa9f1e825631e28bdd379189eb464a3c6d2482319a09337a78173f9207a58ce15bb1c518b39328000000000000000000000000000000001609e1ff34ad2e4bea4cfc4a993d8d52a1a8676679c91544ded432adfd7fdb5c016f8d825af1c6b8207170d05c10e04a7d9ac1699117bb9b8b90e2fb709eff4ea0f7882bdf6acc6885c9458703cbfb3500000000000000000000000000000000069e48b113b822cdfc02f2f0efa02724193a5f032dea902b189290db91c6e4550fb33e2915eaa8e56ef329d6c61a0d95000000000000000000000000000000001426fa2fe7c160e8e32c3252383a7c7967b3515c3f76eeefaa5c76f02b3308d86ab95f9a3a0dfacfa6dc12eed2f3a5e8a22b6c1a24eff71f0fc64b6aee8d3d2dd0827756f5c959f68f1216c2dea58503000000000000000000000000000000000c173c6c949a7f21df4431025ce16c18b1008c75b8b1b23d03122c7c6ef714b5741804ec7aa5ac40f6b72a1a74ca5c340000000000000000000000000000000001b32d54f8f9839dc39e08bc6a5f0efc5db9bdf487a60004ee135c30efda577d187d9b9e68bdcdad558f2028d66e935cc0431e6877166686239f014008959332d9d009a801be6a1e68c2de52ee264bfc00000000000000000000000000000000037d1cbe4534b82ee79b2c957a6eb19d18dd3f3f6faf3313b0ce12a98953190aeb55f9d494bbac4f56ca6986c65f7668000000000000000000000000000000000734f505be94516149bcd6302a2c9f2f9b952c9e614c8e90b5466073a7e734ca203fcca242cb97abe1c532d7f59a783aaf833a784d22b99537236fb07ab7b59918783e35b89fc9692d7f76a03e024c94", "Expected": "0000000000000000000000000000000012de1cacd791ab81eb49d2e259f36abfd90e8c7ed4f9f23a4c95cb48cc7bf9df233951291342d1266d016a7fcc6b9d53000000000000000000000000000000001938d574d02b8802a45ddf8488340f2397e93125678400cfbd8e64cc3805704bd5f85f8fb2f64a96ec1089b03d9d1c24", "Name": "matter_g1_multiexp_65", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017387ec261c6dea7bbcaf4537182de1620adaa5842cf52c8b5b6cd851ca3c27abafa584547db7366455281d82d3f83ea000000000000000000000000000000000246dc1cc9773db7151e05d131398146b28850e97f6b13694d696be374095fb153b206723afcafddd4b3b56bb15bf778b16c1bc60e1a9be9a82c93b7e0311e7516a57d687d8907599918df77b3b6caf3000000000000000000000000000000000a909dad5029834df0202c298a577f897a376b205812d79e0bb58b91ca11262a766dc396f69fd2b199dbfa52670515ea0000000000000000000000000000000003737873dec25f011b24543071a61590646e4319a2128eed87d40193a22c47b1a6c0f807ba3115a7e45823e5a4bb433dcf301dfca76a83c70552c9cbc9c80cb20f0d82a70a9d887b04b150fa0764ce2e0000000000000000000000000000000002b959df6a1badcd306209c1f3c4c496cbfe4f00995cb4403b04ffa6b9f2c8dd9875a2747354a653a74fbb605eea50b00000000000000000000000000000000004d6b15939c8e282a5995c8c0b67fcba3171b35ecc039fcf32d1e96671698d8a9fd2cbcaa7019cfd01e56d68cac64fe51cfb94c4e029a2126a9cf5561c677687f52059e4b7f8b7e7e73e5b1dd7f421290000000000000000000000000000000006be65e97560a40394d9295fac0029a0c889bf803f09926359a1ac40deb7777cea7dc5d2c4a9600328605fb994f87b5600000000000000000000000000000000128249d2137f7ab1c5622a8eb1c59ee8ed792fe6b09e4d868c9d9ba900a8d28bde5b783ca591f79e1d729c99e10d5cf6d8386fe6f4303959e58165b422e98c4813b1bad7808594473e4e66df09698cf00000000000000000000000000000000002244c1e55324a4aeaa07c414cd3f9872290e729c1cf1c05a5b1de3443e12b2335cd36f0e84f11f04b62af37005ce0ad00000000000000000000000000000000151684aed084d38aba7127434ea73e63219c4f5b4b92017142d19d0330417fb2806e31440e0bb7c9fca2bc8dec73072f02e1c432f3b55ae87ab815647f196be3e138b2f6e9fe7acb9459650246187eb90000000000000000000000000000000009f0c959d995af6cd0d45750cb35a28461d0f791e59b2975ba4edbd7db015858b41b3b7c5c2da0a4c6a5d7b4e855329d0000000000000000000000000000000012d495ae3096c2399149afd00f640f8840c3f8e5dda5835b62ef0dd8bb7303f522692efa72c37190bf6808ed3d4fe8e89b0cc0ac499dffd627f5d19b87817dcd67e87561d5244a4b5698265f8c5b767e000000000000000000000000000000000334cef31670360b5ac7550b55cb03b770660ee79816a2742c059b2ed6cd9d5c53c5ca54793a9912ddd7603d975c3f58000000000000000000000000000000000144f221db562b0daefb20238a527a10ff1ccc279eda86723668f8ada40b41a2825f82f5ee5d619fb193b9c2b4180d932f3875f81fd39c9b3ec74eb269903dba4173d8eb0e41a196d3131252207ffa0400000000000000000000000000000000037f14fb2d51b25cc04768d50fe26c1e156a3478b80e32da980f7e8d5692a4cf282f75e5d8be325ccb4223c7ec2c04af0000000000000000000000000000000004eaf2c069c96dcf18051a2c1d7ea876af67bf344070415894c07b3dd69330d8ca18e1313ff57d83b70e5cda3c9ea8582d8d4341822dba68c6fd58cfebd07b134c1d0c4e32ff63f7d59addff4df1ec3200000000000000000000000000000000104c1f5bdf874c91020d410d8fe74834cf15f341b86e66ac693003766484cffaef2c57fab5888f02f5ebfe1b9ef2fffd0000000000000000000000000000000014a2f6d185c2989ecbb766179c0b0d0713ea9714da2ac555bebf0522ff00766ea7e39c8237f8515224fd096d2b1ede34efa3dab1d7cdf949bd938ca6ac371f953b3bbef1aec7ae76bda37db4c940b3d80000000000000000000000000000000003ebae6a494d46ade2dc7d4630a420b519df7086b57a33da178616d4242fc20e4d02d38b5d00675d2cfdb51adc1921f6000000000000000000000000000000000edc56e6eb4aa8556225d928408702042d49cf3e1410e1c78d8ed5832ecae449d17c9d8f2a89ffbfaf01bfcc85ebc1669848d3c53632dc461619c8c522013b83550ef3dc7fda197ba37c9cfe4340f5a50000000000000000000000000000000000f96864832e7a9602196f0abba78f456300796d5afc18b0ff0c5c23b61865256fe5cfb960bcc8f73231c21b1084cf04000000000000000000000000000000000c59dcca2249b5b01c1b54be0e4114ae8228bc150e5ac7593bdf96136cd7cdd7562eb936ddc5c9e42bd93abe91bac5b0cbfd192e917f2e0c4d6253c4e4755f30812149d1ce1ee4ae5540faf1dbfbc13a000000000000000000000000000000000422c390e56fa27e3d7d5da1b2ef00a29d5340026becefc095d4cfe830208d3b94cbf5ae6f4506ae45d04764acc8044c000000000000000000000000000000000d1cc7c147cbedefa854fb9764352a9689fd157cb2540fe070ad7f6f3eaf761b4670ab9334de4002fa811aa7a01aaad479eaf11b3a30c7771ce63cec214416d798de20432670280d997b2f0631007d6300000000000000000000000000000000018000e31f0ca43417865a1cc128f33383106f5bea71015e9e77cc5320cc3e5704e437ae8d84d96f2c4530c41bfad29b0000000000000000000000000000000011a74c3779c8f351d39db6745210972f4f299009afff643e944f30dbc4367e17271c688e1858e6f79b6636787fa56e6b43077447b67f65e16a8aeb3564b2d13822e478dfb4a82a15a1c8fb7cc8170cc90000000000000000000000000000000002a6c7367526da989ae093350b7c1ee9013f977d6e75563f996e1f15cd4279932a3e4060a26262f27403966a7e0111f200000000000000000000000000000000038a85281b09e5e68d7e31bfc323c9c250b42248cbae47f9c018d72f3e69ec572779d7f8fc6ed3f027499741565274e5eb64479b496c17d0587f6f26c62752881b6a9228643e8c43f21c441eeb643107000000000000000000000000000000000b788a0d47da0daa1f0d802d340e68f9bdb5ddf91875732b4ae82f1a89ebb5787ec1c9f539b82e3c94c36a5df4ddb4ad0000000000000000000000000000000016f46ff55e9f1e19a332ba4ba43d66d2a11a2728a484a719ddfc9e223b54224db55af162e73a8f5c3355f0127a6b7cb652b42f75aebdad1bf433917c025800c4f4e985cc077db3ba36f7484f95764e89000000000000000000000000000000000379d868d91304b24e19694937402bb685f064ec5a89b49e243e2ab7eff5ca0a2023af9828c4ce9f768a1d6488c10e110000000000000000000000000000000011a9b9432ab253d47e8dff776c8b5810ecf7f7aae2ff36ce06b87436b4e20c22596c7713def3886549a36bb535a96fd1e83106e9ea63791eb192e7a035bee27bd049b3a37f080076146eeeea6a769384", "Expected": "0000000000000000000000000000000001a50ddc4d4542aae264dce69f5f5e93353a9eba30b177b33c2f74ef61149a301599beecc4d0f78078dbb9638eea526200000000000000000000000000000000160a2fd67df885232b06d3dead7ffca93cf0434a3e9a5412ed3b4c342819b44aad5385bf5ab60bc2b7191722d1372183", "Name": "matter_g1_multiexp_66", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008788a699276abcc2d8e4a35a9d0ddcbd8006a809799374ffd56ee8afa1a89461602d92fae6eba7fdd4045ba34d917e5000000000000000000000000000000000c8e03ca0da00c6829e2d7c49360e67e46ce12e0c99cb3d957119bd9c8bcac8e03cf32ec71db2a18568157f4b44cd4dca4d710d2f632e3ed0ef69fa0219e16ba30d3efee99386f1a5c921f4548ebf64b0000000000000000000000000000000001373b4a0653f48c205b36bc50541a43abfcf35974a584953bbc40f5cabdc3ac2047bb86267cdad1e8f00766682d2e6f000000000000000000000000000000000faa8c977b4db7a3c9e65d9cd5af4ffd2d7d67fb038d92c1096124312a98d94e6dc3f3b8de73eeb057cdeec4bc0e0482bd9ae4597aaf582857b40096360ced0f044ea172551c6f9fe3a15e0ce290b56b0000000000000000000000000000000012dddf5b96d0dfd2fd619b634b086ba5d5f25a53e93938559a7adef7b988749ca27d14f2ddbf5a9e7e6c1914403a45b900000000000000000000000000000000044b5c8041fa805cf2ec5a243814308369e5af534729cc9608fd17583a48132809f507cdb5b76fd6597fcababa865ddaefbcb4bad99b419820eec388f6f62ac8d87866d7beae6d431dfa48d4243b4a4b0000000000000000000000000000000017c5807458fbb875593ebfe83c49ac2493ddaa15671a59032528e0464360c64bf564f9727959108940ccbdb8d01f329e00000000000000000000000000000000121dcb798111976daed483f4efc95f968f5212cdfaaf0497eab0419a1b55c7ee4e2ea26716d0c1a8aded4804228b8ad860d89acf5b49fd1f70fc54756c4bc1972cd8818e36efc37b422ba6a9318fa134000000000000000000000000000000000717296a20594f940a05ed3ce4bf2b7779c428b33a297087e08b2283b33228a7d4d5b9c49a71ce036d6f2a078d8344540000000000000000000000000000000000fc78f64a461fb66ca081ff4d67369058e57e5ae0e284562161fc3244bae0b9c70ea6abb2d0da6cea4942530c64ea0e386af376b9b393dde994da419d1f7aab60023546647f7b069ede939386bd6ee8000000000000000000000000000000000584bbc0c537e7f37ee64604a134d5fc21d838c51a89c608ff9e3684357ed7f931fbd4fa4a5a56d20304d6f6f072316600000000000000000000000000000000191ea3bf1016b6402dca2856845017dc49c74d06bc3c5f10de379e04302c469015f205cfc97fa142727ba7e2439c15575ffca78eea65c00e1128f8dcfc96b39af1c4472b461ba5262307003bc972023d000000000000000000000000000000000f1ff007860ac58bb04d992d639a5f882c3c647e76e2d6d96888a55648f81ad8b7edb3dc2b0e56b6f2dadca73db7cbda000000000000000000000000000000000fbb952eff64505e02e0ab34875d7a79c72ab724cea7cd8f28df2578b50f78601b9a9eb4170e1b7e8d94d9db252e23c592837b4314e63ef5a153ea2ec4bd373cc3cecfa3e892c3a12aaac8ddcaf5905c00000000000000000000000000000000011dad65f38b4c24527ce87f8893c8331a32a3d058cddcdec9f8708a3bd1e31871cbdcf944ec14d5f101b8d138b2a46c0000000000000000000000000000000012a6981c5100177e643dc421c5917896455107c5995b1e969bb18b4b2752700a18281f732530af9684db180290dcb138127ef2309c699a3602b0d86a070baef0eef90f539aac3cb6ff42cb19f284bd99000000000000000000000000000000000bb4dccab7abf3f5393a338a3a07fc20d337ba2ec3b33227e8c9a832900f347d582d88cab123dab489daf471191538b20000000000000000000000000000000008589985e2952db000968a793cc0fb5bd1764ab1ecdc6f278a11dd4a1de87823016e14e9fdd682e6c489192b154cb997ba0f9a93c2fe35877ddccee5da39ce5ae60a6a19e72481319e3b3fa2eac6148900000000000000000000000000000000056fd39f2a5356870a3ebfedf35769710c16b2f2eb4a061c936f6de4f9001990769795b1c756d7c67623ce3931ea1b5a000000000000000000000000000000000b7fcba295d34fc38739c4b36689653731fa46e6029bf8e38ccb6af5ae08ffc09c86abe0de62230844a66cbde876f52663da2f227d636f10e814e360c2156e686e26ce3401dfd15f47c4ed277d05353f000000000000000000000000000000000039b08e7110b0d17c41709378f75844379c662f7f3dc480bead6bd4996de2d8889f458aabca142d50ba0e34c0c327970000000000000000000000000000000013363b0da7c7dd343ffcf6cc5e9ddb5b51480b04a472c38f90ee08cc97507f5dd665e15a160860c6df4dfec154c1504bef79e3b6ce752d140c3dfb2007a08221d989038c921efff3bc4e150a6155a33e00000000000000000000000000000000034edf693e1b201be14c496860d508d12d9180b62cf3bd2407b8ff95b93da67dc0c4c43344614dfed516d7828ffda4b20000000000000000000000000000000015246f388664b1d817fd17831f85d84cdaf31212f093820835f201c3fe6ac99d67cdcfdda3c2d74d75d5114e32c65cd7bc08091af8b8c6ea5c26f1a7d795132521350d774042d3a8c0523e86fdd23a3f000000000000000000000000000000000982b8886abbfe18cfaf4c0e16c2e7045973f5efa27e5cdb56443a22f5434e2456cad041bba3e6deafb072e5fc40f10f0000000000000000000000000000000016a45f684caf0eec143cf8f31ed5111750d8c4f1092651a471cb88cf534e81df117e3b0e8238270d3b03aeedf04d7a9f70363101b87d685aa7314f6569fca0775bc6aaffabe136e6c336e8fa43dedb8a0000000000000000000000000000000016d13da2900e2b2ef8f6ae295bf16d100d451ac4709455c55323988c71ea6aef694de0fa5a33cdd7fa2512d3548e39a70000000000000000000000000000000005795677001cab950d1a7b802bb14f9203036f15fb335daa5f0b0ece4bcfcd3b31b581b439da46452e4e688f16685e37997ff3852cd97c3a65bce9083ff66197fd5c70894641195514d556102f091e88000000000000000000000000000000000b7d422ac85798cb5ef5548805bd6d3de20ada4994fc38355e92cbf0d0c9da356a5e9e1674a50a017643f652f71226e8000000000000000000000000000000001715616f53a501acbaaec470121caac29827b6b7bfd7e689d8e48822d2c464ae50158662e69c1c232ecd09f5ec946a7a5ff95dfa306f91196849d752569b35812e1db7946708cd06df9db9ee75447bc30000000000000000000000000000000010e7530ba600fa531878ad0f798a0ede2d025f149ca980bcdbb0e4316e8d2e7d2b248619369e36d21dfd766aba5918070000000000000000000000000000000000ecfa746f1cadbed34fc1ee3483307de400ded69af4a7dbb598802b7908495519b0cd4c1fa98c9cd8e82daf8b3e836e03c4308f0467520343825a91c0421f9c9c9d06957fa2fc051970f14085339e26", "Expected": "0000000000000000000000000000000016bbc2dfb25ff6cb9cd03b0cc91f53c6ed9be933746d59e78c7251080856cf47c12bbecda442840675b03a812aaa5d98000000000000000000000000000000000555b0683640ef1795c918f5d10e8b3e07a09030fbf26eb34bebfbeac34e13c93ecf53d54dec5c8654cdedab2fd60570", "Name": "matter_g1_multiexp_67", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f08b9765910d97ac42bc31d4b4c8bad5f3db3fe5374f11ae1c08af41ee226bbb4b0869b039fa81a935025de11b1d1fe000000000000000000000000000000000ea29999ba91652e2e6dfdf77595b44da8e5cddf2e3ae6c782dbf1f972717833d03478bb8651bc0cc7946d813371aaba2849fab097a4f71bdfcfaf435994a0c6ac3671a4a9ed0402010be83ff95228fd000000000000000000000000000000000997b39892bfe0c67c296135573975801ddb99d06de02d96853f44336fdaa25dcfe253708583f415d882115ec68dbaed000000000000000000000000000000000a88e2f75817ce91c7dbe365d67aca52186b5e94c735e5893bef6aabc61f015f854f9bd110d3201be6f35147f9f9b8fce6558521e301eabf09e80a509b46cf8ec118ee8586f4e46a7313a96dc37ba6990000000000000000000000000000000012a730eaf214a874448e654a06604c4b9218f163b979bd3700b7a7fa3856b814c380532afce59b6253344da5bffd684600000000000000000000000000000000182fb293f9a63c705501aa0ec7ca72698d7d4d50af3a0f68ee849cd3f82ac24aca2e2ee813f68e708991a97e58f2d03d8f2f7c525fc0f353700fa823a5d32a93189699206c5ba5ed271a158ebb47674b0000000000000000000000000000000015bbe08935721cc6199f9255379589a4512c178bbedf69c82a0d9cba22b285730d4f27a3629d92574b2c24dbe09300de0000000000000000000000000000000007aba01238f2c4ef0192fea78fbccf2e669f802a2822baf067632daadbc1d07e70095c14bae959a0f706092b0be10335c7e8adc0f0a042a32c733b5c3356cf4a7d648be51c1d78534ca65dd43a0c13e40000000000000000000000000000000011727d6d6cff667f5bdec92a3b502f9d9fbcded2ef12ac058ac51ccb4064443b7a2671e9ffa2fefd9b121d89bb4ded1e000000000000000000000000000000000960f8ac1e52246529fcc6f8f7cbaf42677297c00022d312e0deb5fc45d3685bb33fd68c193758258439864ba4a073e5650081a6720845a20164ef7c06ce1e73286a32dd64efbe57fe46765008dc9dd50000000000000000000000000000000014b3a9296c87b54f8f51b935a8d9ec0af44d711e3109e75fe34f07d0705e9ebf0ba5e81dd8b7e3c4b4f862570637a7f80000000000000000000000000000000005b834857b8629cdbf514e5ac2e0e2a45e4374c287bab5e4c163d669e7b1a36c72cec1ab7d857e28f2633a6e5f298f55c067d18b95591f7f14261f95513e1990f5a4f6908f94a015a93fe379726d5120000000000000000000000000000000000ad8c626ba39823a33d17a4f06cf17d29e9e0ae3f28db0b369fa0bb4b7343115fb3ded39862381822c3b2d74ab7f70e800000000000000000000000000000000117230d8da035f40c181b50c12370f159748955f63ee1eb61e8242e476575e9aaf16bd43b7e79a35ab4e2da20f43fd92b448bb01a1963bf74e0fbf99329005af8e932074358d855ff43c213e02bf26bd00000000000000000000000000000000027764a17af5328811b305c21b0fecc54a3f225eaaedbf453ea4c0724fdbd481873d84b1a7ffbdc7f1cb07c2d1efaf5c000000000000000000000000000000001090ec8d750ceecf682de76d4794f9a8bbbf3a3f4ab591fe882613c1b6db0912696974a1f2ce349bd8c79acb4891719d441fc4cb1ea8f86af8839aa40c35c0706f3a159b4bc902347009f744b73cee350000000000000000000000000000000015e707430eae84b75946f21e1fb0b6ede203b843671911923efd9674421a92ff13cd900bee1b27d70b8e8cbeccb165930000000000000000000000000000000001263ed28f531d8197606a038d7d7c3e1d732690cd69f52533470f6fbef193be5e63d5af0dee3aa8a73a23253533f8223020a1ab853ef2018976e43cce2724105a2526b28d23b0226c49ff3d4a03d40c0000000000000000000000000000000007fe70102db7df6529f732b5cc2b1caef0fe03af9824a5097922dc0b07e5ff32bc195fbdfd7b5e4b2bbcd75b1badc6ef0000000000000000000000000000000011b40afd78bb5e835227e5a08f94f7c70b06dc010f5a710a025f589521543eaff27d789d4de10fd4020879b45bc0a9dc82702398b8c95c3a8cd163a8a3cb2a7a04030ef99404c325115e9a9312e8c1bf000000000000000000000000000000000e4df86963d375710c681c5b3910fe79446e73e00613bd554ee20f47fa9e2b0cfb6c14a29ed6dab0a56c49708fc624d80000000000000000000000000000000010029bbd62162cbca140c56354ea070ae3f1028e438c70dce31e7bc8691541e59e9168e9b689c19d177d4fd68f8b1081338468a325384a9367c90bd0450816a22849b845aadaf187c27b3f09800e791b00000000000000000000000000000000097f3f61b164193da313d88429a4f34b0ef2f864ad8fdf7183c3e1da02dcbf0ddeba9bc04a7594516e6255ed59527e110000000000000000000000000000000008133f297b8da5dac5e1ac3db3073587b92a5d821949968c125e5c9c79a19b5945ab47fb0ce5d6f4269231596b157826d29136cbc4764346e7ae1af92fe64560f453821f96f32a42a2006b6edee7502100000000000000000000000000000000028cacc78001b805c3e43e92fb8c4477778ce81fca9068240e0088e344cc8201ed5bba52e7ee09d5ea6f982f30d6ea2e0000000000000000000000000000000012c5db0995324657574a27c48313674d2ad3aa931cee78ade96408c5e04e6f5f8eae88018511ff156bcc787970ec40ab675a59418f1462247d3bddda5937553e96d854b5df64a68145a193b2b1a7eb25000000000000000000000000000000001768f68b0ec15fdd37c3ad9445e53a582ab5546f9eeec590b84e11f5a72585eada71129d1b93a72b334bec4df57ea4c40000000000000000000000000000000004d6e137e66243b56bbaaac98717061b36545c1c3e24801e6e054bdaaa6d28d641821a51233175f5e5823b7d2b7b42cc544a345719b40f973398a6fdaa2044037cacd7f6c361921c62053cd51f2e5ff70000000000000000000000000000000008caba9658e420fa17950c995efd00447bd5074af9b57122240d4e709229d382e371d7de867005745a35a2a7d68fee8200000000000000000000000000000000072e0c25435616f157284b48fc8da4a3fdaefc4f6d484e071cbe648fedf30b5da4457852d7715741615317e21110d4c2bb38b4cd72eb18c3ac87860aa58b4b439712562f742f112b5d769415e9c19d0a0000000000000000000000000000000016c418a3b3f054188d6891ddadb19c00ec629a3ae0f49cb1b6801a9db0afb1b5e473c75cc8e9f352adf7ce8ac738ae0100000000000000000000000000000000110b8099a39e40541dab01e10314a0cc10fd2277c8766c7c73d32d7d0c6edd3ed3984c8bce249de4776920dfa28ee86994a849f6fb5a53bd5957e53ade1baee05702185b4d0fbb7c1cc0f46cb75614fc", "Expected": "0000000000000000000000000000000011104fff0cde20e65e73185321d26defcbce9c9d3c27923a2366730c1b560da80066734c61e0c42bac1da45787f39e2500000000000000000000000000000000066efa830182669715da4dbafc6434be27a2e95140cb39738fa75cfba2b5786d27fd727df4e9b0195b49be2dcb9c2c1c", "Name": "matter_g1_multiexp_68", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000188c13fde41e3c7d84ef3b5d1fa869dff4bf02cc8448ae49c6b72cc005bd06916a5d0a74fd770bbdd3d2c58839840095000000000000000000000000000000001637ed432b4ac6b5021aac0c9d5f084e1f6c541c101a3d650861f7d860572795f04e986c4a890ea0ec049da7c6025fa3f5b9d270fe31c772e9a0bb409d9f08a07887f045f906f30e2653d293b6c2c27700000000000000000000000000000000063a1afe2f64f1d04f7a5aa727cbd0e9dd9b66234120118db1f8fc3b90ae50cf493c3c4a48949441cc1e46488972d39e00000000000000000000000000000000049261c42dea531a6e8fd82f77605ad0cc9addb23e429f03f1aaf2fb8d9dddaa89101bd5b5b169dce793de9bcafc3b5ddcbf4fe86140c50618598be9185830bc1da11429162afe0528f00eb6698ec0880000000000000000000000000000000012ecb0f3bb6fbb4802479611a25781ab09c81ff7175170805ebadbc5f25d2c40bcaca855ece57f481160d49af008d2b3000000000000000000000000000000000bc4bccd65e010b69676d3c226057528dbe08271d65f83a918b06969c1d5303cb7383645fc19548eadb83649ecc54a551d7fb7121ef0baa85046567014620e1adfb9e8b3bc95adccbf2e0b0ea8f37c67000000000000000000000000000000000e3dfb86c2eefe0b25f117484a9d693702496124fd0dda80830a4e917bc418a793519dc269fd4932236f73506ecc949300000000000000000000000000000000140faa4b38ace6e80e5d3fdd57079c215792672ce651563eb013a90e66665dccf6bfc9f9df145d34894e3972eb524f86310d3b0535e78d803b477e5dc26c71bb18acfe66bd5ba5892d924d265afd6a160000000000000000000000000000000016e70554f8580b8e9c5e421c6a6495df7df846ad67d5d4334e9aa89f7e3fae505a2d335d21624e66aa542dccf38081e0000000000000000000000000000000001090383d5f42c056c291a4c4c6127315849c647783a556aba3dc41c52545549d67560bdd697fd1f47dace750483ec9b72fc9417e65cb76aa0093a7deb3d38c111c68f461a4aac57d8f09189f94407ee8000000000000000000000000000000000e8ba15ec58e5de08935384a3674418942311beff3887d7b5b81da0d03348791e4b17a06397e33e988ac6719f4d6f5c300000000000000000000000000000000159841665c915844ed85abdec0c1e78f178df2511da4d3be989f27063a8e572fe746b20e3aff056a63f4832d82a7cc75aa0b2d714aff175a0be2ba9e675a2be8936c42f15e304a146622a95dd6b3e3ef00000000000000000000000000000000167848a43b68c8f4c205613e1440f940735d7d44eb1b046e63ce50fe8d7acc5b2c020fa936d6e07347a7858be57870e5000000000000000000000000000000000aed7f9b7108aa4e7445be41bba256667ce7587a867b9b8ca70d3c42155521ea3bebbfe01bab038969721364eb758be10227c3510ed6e4c7f84b11ddd2d6caa55e0e79ed59e1cc0cb325d55b5d145aa8000000000000000000000000000000000699a81c47bcab8342b11a207af072cededbadd374aa79f6b401e4bd5d429a0443234522a8955b3a62a21ef6697410270000000000000000000000000000000008ec25a0e0dc6a3c8906a1b3413f522440d56f67fb780545fa022026c6faae016108cb6eb23d6d6d519a4aa790327ae6ad930000a9f82e082d408999b396aca2b0e435a66faba1d95e10fa0abc0625cc0000000000000000000000000000000009c2158ea44c3b590df30e15f97ebda263670c1bba0d97ceda7ea674af0e61f0b5928fe0bdcd8f18efe5340525259b4c0000000000000000000000000000000019a5534906413fdacde78ffb03e6564d8beaa155f86e4f19be2188854a8709e82d2ade21621934c1aef8be723ea91a141a6799cab8964c7b79b80e76be237ef49c2bdef5c99a38ea873af6e9d49790ec000000000000000000000000000000000165b15830a84e786d563cc3c5117a3e7dbe9dda178bafd225503467ea4c9aa894294c4fda58734eba9864796974a016000000000000000000000000000000001285a2be50f38fa6a068b75386d468d8fc1c11405291e794d5aa5157cc81d7d66c1095f2fd9289f1306f74596e9b5c21b206dbfd70e4b24bcc09ad35ce7b3aa62d17f18347f2bc5f15730202909c93770000000000000000000000000000000019d5819c1c4f10c83ca6f1596e6cf9901611c1407d6d7abab989333b37a8c21cc3deb039722a51e2dec161c38f3ce74200000000000000000000000000000000136d05ff33253260cbbfea0390e78cf66845afb4ddd0b684b928da017fbdf6b0e840431064e6e6d5bc8e417a74c811ab3a607a7301bb7dc5b9c82d956ebb0bc54568d0654d725d4d5f13ceb6231e862e000000000000000000000000000000000593e66a323cf3efa13fe19cde7a3c254c90b23bc836e1f437f4a4b85790f325f0746147aeb1d0447022bb138178bff50000000000000000000000000000000011a4b1222d0b49a27e66cd34a12f252296ecd1aeda435035f06c059aa3e6ba69acd1ae6d7da394f32ab78538f4e50a351231e0fbbc2d98bfd1039a889acac471110d568b0a24ddf5eb3501adcbaac6fa000000000000000000000000000000000613bef17f6b6b39f9f6bde785a82d2e4c368ef231d8cb89940059ac2c16bdd707170b660c0faef9e927ff7a72f6712e000000000000000000000000000000000fc85913ebe30f0af146df556c6984ab442b286fa70ee00d39a802f4c76c3e41cee68802982ea42fb25d4bb04593c0b5393c5c10d4bc4cd1567bca6960051f818e5c53704ce44dc4582767fef1092a870000000000000000000000000000000003da5997b7b3677f6cb03fe969e328549b1c0b083a6df457a70f1276d10e01d65feaa5a36cfad19dbe41cad9eba2fe73000000000000000000000000000000000345176bf6a03a49ae0b6d89d07548ed47dd67dd620e5e29066d09a00a7e3bd4b7fcb79b114a046dcc0c705068f71b50d412195e347b680430c4528987859a1552ba8383cdc075c437ef19db6eff6e1a00000000000000000000000000000000105ed7acf8c7c116842dc159553499aac7b8beb36dfd7eb717c571ad4ee1f86b82b736b72c2936925afdc3c739e0ad56000000000000000000000000000000000618b8fbf8a2aa2d1030c6304655b1df3cf8e8260b7b2d97639bd857d58606d0eceff7ff0fc1a811396552719407daee5b6701bc11c1ef3c9389710e4dd090e3db481c5400ecb91655c20694207a71f1000000000000000000000000000000000eabffb8ece92d4b22ee47560984b3efc33913953dcdf5e22771bb8db2cd8eceea21a2b14d70b1d467d692371ff499a300000000000000000000000000000000143282a2cc502f477be295d5fb2ec847cc988e43f72be848464eb4c1dcd0b1ab66a6cc30dd4b465050f6c37e8b8e08a7ab45b07c059738ead9709bf36ab20b09fd3368f7aa12c6d9f3acf3f145c83fa5", "Expected": "000000000000000000000000000000000378217eb65cf5ff48e40ebbfbf03c307aabb63955f755a93bfbea0c176e90dc986a8202c6ea4e9ecea176068cfc62440000000000000000000000000000000012ac5e1a0c75ac5b96af3959a65eed134dac6b35559cd923facd2062ee06cb3ae2018db7d27dad2927b3e9c2e3dada33", "Name": "matter_g1_multiexp_69", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d6ab2022d950cd2ad2f0087a079e435634a1e24008d12a349836cb7297defe857cadf3adf061e8b55ece662dd36ca280000000000000000000000000000000007682f1ced1ac2aca6ee9de682c7a6743fd32264eb0a087eb1df7c520c5748cd598be45213b398b073dccbb6bd67b44c3ca13f8540eaf45ffdab5182883d32a1d35e7cd956092221cc40232efde6cd1e000000000000000000000000000000000927b5590892a4b897ff2d6ef6d5abe32bec8233bc5f35ea9ace2ec516037a8f3d162b0161c91d4e06d80d73528a6ba400000000000000000000000000000000064d3d8340eea43bb2d54dd6f5d9d49fc2275ca1ae7212329a11ed9a94c70c80584cb6ccc1eb653f001a1c1c4306e702b3c8b045ef559b76005875bce09a66b36f295070a73ec8dc66c86bca51fa5d4d000000000000000000000000000000000322791d0e53364128288e40b621e6c47324dafcf86e9a8590a79eddc8d3e6c9d74cf9721115550e7e33868ced39cc4700000000000000000000000000000000112a246f82756d88f30e74b3f5df21e18ffc9cccd713e6509572338ccb4f52cbc0c3a6d5b5c112e304f90ffb9179238521953ea264f74bf64378a339461bff41c5193e17913c67be7e2a249c9737b8250000000000000000000000000000000010bdece8fbaa604439e942e2c78aa5904cc1a0532d5bbf624794d3f10f4b64df30838799e374982feaa7346c039c08ad000000000000000000000000000000001085372e79e1046c870b1d49a2a8ea83bcddd6bb8718c7cb340dd3032739319c54eb947d518c7e17d6e603dd3539f269505655d72f1128ac0204539f0d823f076cb3a57a7e74e896b5019c9161d6486a000000000000000000000000000000001551cb2abe299a01cfba81bb306457b662ad57858a30d55e0ae0c0f5851483123c388ba06ead8ec4fad0b1e4f69ddd6b00000000000000000000000000000000159e5ffc459d38a6b1e49b30647939f37c0d4fc02b83f9dbac123d64535752977005e0cb1232ebaa7cf0bfdc203ccaeac4c861cde3f445e3a78d1498d98b2b947056cf578652e19be88da4a786af196f0000000000000000000000000000000004111e81afa9fd09e39df891cbb99d9b62205777bebee33b2914e24570db46f75db5dbe2e9831c50f9717dc317f05ceb000000000000000000000000000000000a999eb350750cd505ea9de43945cfb0c9c4ea412cb0f0e769e62e47d08f8d50392d3a5e821f1e9c947990e6398b5ec699762c5189cf154e24238e4b157caa1d8759002f69b289cfbf3f24f5dabf20bb000000000000000000000000000000001496d3b0062e9e7166d777d90553545ee7dfdbdacb355fa7ecfecd65bcb96321aec0fd835b32c8bce462c87a2b52a58f000000000000000000000000000000000ef77e6ddce1e0eae50a1c663374c31a0c5846d6c2d777bb2f4831ecc806ac28591c3ab0222a6cc7821a45ddde1ce23e298b5f6b43074b8f0807086b03f5028709209310474c35c7ee232eec8579147c00000000000000000000000000000000194bd82f02047bc08871e431ebde41327a60e838d3a1ce6eb5470ba21a9b863025c8663f7d509a73847ed41515fdd3ac0000000000000000000000000000000006c9303814ddedc68b0047b5b2f0333cf226908dcb14ccc0aae4e14456a0c83eb4f498d559a649bb64bc78900a788a4b177bfb0218ecd8cdbc6dd9484e74e41be6971ec2911bacc8b53b9b4b8c70e573000000000000000000000000000000000736fc761eca44cd197ec6fc680de349f96e5294e42648825ce9262fef91766a8d7a084e5b598b5b47d947548e0c61860000000000000000000000000000000018eedf050da521b9af0ce2007cd664e2760320056e14ddb162db5cae78ed7ec859bad03fc60caa06081f0c24bb130ea4cac52219796226385aebf9e85f5f179362d4149c33582a97b7d2aeb05a8e6a990000000000000000000000000000000018a8e4887f0c08dfb7a741858580a1e0ba7e7ee1959284ad0955beb186e84a5d503ffe4000d5a8641575540b6b7a3885000000000000000000000000000000001946ae0b124fb60fb4dd32181783564dfb8ed0616a220d5650fcc1f6968ff70dc74535c71b0cf1019eb038c19cef0caae03afb2efea85fcd035cb4ba09977b2e1c84a0d98edf88e9f8d2c4f116d0f5030000000000000000000000000000000003cc2093935fcacc3fbe4429868c7b31fe8c8b12c1184e2181dc8da4d56b9b3ace85ad8d6b850deccd047eb002acc8fe0000000000000000000000000000000008cebb95902576d96a3a257ccfe76bc727174e08d70492dbc2132b9d5f534de3b6a7baac2d90338278064565aa67b22c804dec43760dab29c161b8f4bddc52379a17f3168f684267cfbbc3505e32d5f10000000000000000000000000000000003a03e6c183afe6aae9bee030f46086032e9d81fe337e7e1c77ac6c903fb33154bebdc15e81422f057ba1853c1f7cf110000000000000000000000000000000011f5e4fff35ad1d6e2d2d4e30ddeac28432eaf13fc7c35f5a90f7f8a17de0f61bee21529b3db3633c178006f5c5fc403ed2d3daf616df3f0061f58c925e9dfbbf6e9cbfd4b0b3896a596919fb3d243db000000000000000000000000000000001986f950d86f35d45dfeba6c3e484a6da296ccda2314d03adc37bdaaab374aa9011e07e6c8fe056e66b9204c5e16fc990000000000000000000000000000000003220ebcac8189b30f6efe6051a2be1001b85a7f94d9ce289bf6e04edfdf2ff17b17702a1ce116445d763ed1c0dee645e16797ed90581fd8c3cef1f30abaed10997f13461374ea649b29101959fd50640000000000000000000000000000000001000e0934c04c36c621d9b308565cc75ff58f6c1c778b8e0926b4d22d58025edf8a853139667ab3d3616c33d8a98afd0000000000000000000000000000000008776b843fa3b1449a0879616b3a37bd5eff5c809c077fb0274fccd67d645439a79a410fe2c2db44f52887ea7f20c6062f9f29432638c033ca84422b12ca80ac4ae85fa30ff56c913c5737aeb2c84d04000000000000000000000000000000000e7b037fccbb3fed299960355ff2c6a51562814ac797ed6b4b770ec565bae5ac998eeba19819cf2b3d4e91591e7f051f000000000000000000000000000000000143dd07288b59a279de228ea59aecfba3275a87fd8307252e6b5d567bde87088a8a8f52da57cba4c0fa0e2aed423241e6f1e5df7ff90c4a4fb9a071c0caf3a3997569538ab9837ed41d9d0a8d730537000000000000000000000000000000000b41b673bab477cdb21ae5f1c04922f2b8216d7a1423a6f6b86d4c33f0b4def9c553faca2798cba20a31ee7d71422b21000000000000000000000000000000000b64686b90964104f8e79bf9527f452d25c3c8e9d53e715d884e795d26e391dbf510d72fb2850fe66e35d31444814e650cf3283195707c30880e50ff5ef605b561c3c3c354fbe8108f93b36f212f9ef5", "Expected": "000000000000000000000000000000001673148063c4f68c59d371410a8ef20cc4516c579523e2d7d2ba04b03fc5a481a30fdc6b9ebaee1138b28a9463011227000000000000000000000000000000000067e9b23610ac41d41e0bfcabc455342360d4ae4c75fa0303631e97f702b9cb660b84b5d422e8e9a74890b803c944ea", "Name": "matter_g1_multiexp_70", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014cf7c57711c1708096cd33a9efd4f907112a3d4e5bad1767ddc6fb408cb7ac3f866143000154d1270c07b4294480543000000000000000000000000000000000a20191e6786d94721067d6942731110df277047541383ef9847fed9e4b8599723fd7cd7e2ca2186d56986feb8dd24d72063b046a71c2674e35466657a85d8e02253b42517b033619e31a53665917212000000000000000000000000000000000cdb0c20ac2c22a458d2370662d665005cdd8c662e318bb8652a2123f2d65d21c8e150daf51d7874c69bc039bb6163710000000000000000000000000000000008480687d726eefe93d5484ca375557e109fc64f60666e1b8aaf440100aa15e76aab6f821fde170046d2714d8986a1fe92fa325cd07502c6576dfb93ee952fedb304022656597bf3bb03a2bbc471b32a0000000000000000000000000000000011f20086905f64c21bec021e5726c05158f892658cd69536945a3337a8075994caf4fa16fe66b85e3e0ec71ae5b4c09c0000000000000000000000000000000006d71057aeaf26fc685bfc0ca071126a81224692b3eb90e37a1941782b8f65d45b6a31567c6e3d2935d38e9e02ba08654484e688799c3f0a3bbe00cec7322fba6245570685cd7df0d744473b72f03df80000000000000000000000000000000005a186d0ceb2535037b22a6455c49b6227e54c6e6dcdd98f46d996f23301b208a87c4bcd0608972961b67c523f01c99100000000000000000000000000000000142367fb02fc6b2cf52a78e4cb1157d273e9fe13ca721e0fa725f2a6dd0b4897ffe7affa25925da47fe851362700c31bfae2ef61a024e4d8c4ae277f6b1d834193df655ffb315da67afa4ee4ddcb7fbd000000000000000000000000000000000a758981a1524501c48ffc9990b738d51ebe38a0ba07b2b049110c7aa439253bfb0491a66cc42eb241a47d5e963db75500000000000000000000000000000000082adfa66bb46b97f14dec70b970469478d73d30216201e7467a927ae4ab9d93747b07ea69c406dfef789226afc4240a3168a1007abd42bc398e317484149f2fa61174243fd1748deec6cc75e7c720a2000000000000000000000000000000000de8dddf04e0c2d9ef1887ea598030f2bf3bc7bd98b8b218d19f661ec4c9a47cb087639f72fbe97afe9617acb162bd1a00000000000000000000000000000000127e78f1f41df717e5f76692b9ecf21ec0fbaf9b1d56e51b37cea02143f3b91eb1f16a65046527339dc65d29435a2874f1525bba87baee35023d0976b4a2d87524ba74158f000e5501c6d06aed04adda0000000000000000000000000000000009c37c64ffe9bbf264c475076ccbe6638653574ea84b30f4eb2601f1990f73fb5708af6007f21e4dd52f23ef5041cb3600000000000000000000000000000000170177e891c421ac91eac0dfff8bb397d7fc531e0fbd275c17cb4d894d18278a40a6c3093b92fc537244798f24eea4e92d3d7c014416f33724acaa46412348d350f93d334588d39c77dc0b8ffcb4cb1d000000000000000000000000000000000178d45abe2415895e0a550005c76522962c0ef0193cc7475a52f4d9cec9d4789406b7afa2872485722ec034df4446d90000000000000000000000000000000005e4253dde4284944b2083e07b04940cc72cb24d9866c953564bc0e847b72da59888e7a08cde7aa7c0753cda94a6e97c53bfbb1670b7045b6df689871d5d012dc93e8be65faa4a98a51db8501a4b7677000000000000000000000000000000000e48f11dee27507acd407ce1b810cfa8d0ff4414380fe26aba6c608784ef756d605c8c3ba92592ce342baef8aa927bd90000000000000000000000000000000000e604525ab4ed10f3a9a688774c6b27e679fe456190e67689959da296b650dbfb75610dcf54b30ab891c40784a9b90ff944ee8d294d189226a6cff17456e2201d17d4dfcb78f58f8501870377a6e43100000000000000000000000000000000199b1367bc3aec710e82f98d3564debe9e01ef2beb878935df4ea98e3725391e873d2661e2a27d778bd29ce6f66a9b24000000000000000000000000000000000e77a3ca6bc4584cc1c3df35b18402b75936f68f0f70193708da21649b6def59f1baec4d6d1a2733c369cb5d9a6b39347de53613b7a31583ccb214726482b770029c0ed42f9528fa74da7d2d1dd915e10000000000000000000000000000000016ee4a1a3f99134ef55398e96b86a21708388c3ddbd86746745e24bafb062a6283c5bdd771f15eb501df6a19920162d4000000000000000000000000000000001001936f457d8241a4929aec1d3769bd1955433b340481936f9443c63a6c6ddb3be4f4e1ffbf62a5c4b154fa9f8acba3b0a9750cdfe0910c544668bc9b11ecdedf1b757ff69b61fcc838c502c2911bbc0000000000000000000000000000000019aad23ac037d496eeedaeac9248842b0dec15478f62ab61d000a402cbdcc240186248ed931fe3eaae5a1d7153d3e135000000000000000000000000000000000fc1c74c4d8488edd92b42ca7c27e22a4776761829b06efb0d1b2cfa37738efb276cc5121d926665b99497841afcbd394aadecb1111ff43894123648eea9e57685dcb7a25553233a374479c24f2f88990000000000000000000000000000000014c557c44a90fa9d958d2e701cb2aac1c0204246fae4ba7b060e74e5d4ff50630fdca918c47323f5d0eff118c7595a040000000000000000000000000000000015821312dfed1e0bc2cfb23536baceb7ceb45c6c5a5f15ce0d4d67ef261a30ab8154b873513e2c44f652b93989cb6f1badde66cf749daf69a30f41ca00d251f7f1e93b0e7f916a1ba6b994d946b12ca00000000000000000000000000000000001ce81da6511eae9d2e155efb4f999a5d75faa99eed8fe784c7a398bf4b0e135bd0e8be8d9dfa2aa8ce9c63e091cb44b000000000000000000000000000000000695ff4e598b9e469bc62dffa214418536a6f49fa5f05680e09783b2f29bbfec5d43d42c969ad3b62c25c6192e328419b2f9b44c73a1a6dfba6462e1202166b63727f45dc3b8b3b73b5d06459a1beec20000000000000000000000000000000002f155e83bcd838ee8840996a3d8b0bef77334b0e8e75c8e4278411ae1012bae06959e8394dc4d1fd4ed5f07804b41870000000000000000000000000000000004daf1423e319b18dc57753d39777bb127b651f5294fe03a15dc4974eef8cffe337704c7f867fcb4c2fbac382e444a2b0cdc89e668f7cbd53a2ef6597a48b93d7d9a78950d4f821f3935edf72649e00000000000000000000000000000000000162f530647fc6290626d74753efe315e64dca2d73571dbd4416dbb41b07e8ddba40b3dbe170922c64fabbd937c961b1400000000000000000000000000000000021ac62abe15b0f1318063428d89f22d2090050b913973de571871125a391affb1cd595f9c596c9dbeb6025fc8392e48e23b377ed80bc90a4645df09e825509eebf57f59d7a2aa1b9121ace80926ccf7", "Expected": "00000000000000000000000000000000127c2a1365d966520de7aef12e66e55d807b1a3e2305ccd5a78547fad6e6112d60a206412bf56866ca1b0af1b422c7230000000000000000000000000000000003a613a2e2abca1f42d3ed594a3b99a6cc51207b249aee2b5829aafb1327cc7bbf99604473b4048c4b2033e1befbf14a", "Name": "matter_g1_multiexp_71", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fd31933662cde0814cea424436ddeb6a668e20b69259424a652bab722aac70b3582cb641d53bff963ead87ef5dfe1090000000000000000000000000000000007d17925b0309fd8c92e52c1ad67937efffa7ae3c783177a82f1133c8e3aee2b8fe71095b6b88b01576c5203d7dc8c3f75888762fd1de395fa80b6d8a751f280eca568de2947e953feac343fd6bd592d000000000000000000000000000000001782f625bc3b25168b1f5b388b7963b9d158c09abbc0bc4c0bf5332e1817fc083d3d55124532fee2665c536b6923fe3b00000000000000000000000000000000118650bcb2d32f4e83257cfebbe8209c2c9062ab0eb805ae2977f79ef48af6fd78e7512b331933edd087054273eab52c18ce7941da132adec1eee8d81facdb5012a15ddfe0cd6751ebbf66ce6c4950430000000000000000000000000000000014a69e56a173ed13a9e2568a8af49d74c74dd67609ca58744f96f9213197b45de6468d69ed084ed8b1b29104322ac517000000000000000000000000000000000739671cdbdf98251ed4bf13d23c675500cb66344731ea6aa66ffe401dd6daa8157676fc46b413378b8325ed4cfe804a24a0497c642dce3937d883ee25b0ea577c729366c7d67e2e5ff1ccde3b19a5dc0000000000000000000000000000000005c95d722f8e50603951c21421e8532eae710929e976d76f28c050fb2b093618489c5f892198ca822d3f287fea6eb83200000000000000000000000000000000077a07fe1348e4b6b2a46f444137eb86bf7c58e320afda3d75769a9839fefd9142cfcb75da1d1aa0e7ce84b880ff1b3fe4e0ad0d478ccf5381470a3fc9b882639dde4a0147c7c82e50bb93431b07a135000000000000000000000000000000000efd66388da0825c846b6437b13ce5014b94b20cd3a713bdbb41a80892820ea7b12b6f6720fc7aa6e6756d496ef5ffdc0000000000000000000000000000000000adeb6281219c324d14ab4dc29841d52f3f21b512ef0a784454a01358747684afe22b34d4ff1ed29ea013d47d9059c838573db9346a3c8de41af54048cc51a0edcb86f36372859d0d794f7560c8525b0000000000000000000000000000000010367597f1deb2ca9338b59ddcd8d02440ce8cc34c71a6ff93205375077c00f3f1c22e00ebc9fb60de7475400976e1860000000000000000000000000000000017d148179e9671959bf03fa1c95ab608fe2fb8b9b1a650f524a070d7857dbb8b14a67a813ba1b22e4b71df52e46c42c002257ed12262d00e78bde574a9ebd2664484a446c03fe8cbb855bf92e56bc163000000000000000000000000000000000797e0eff7ff579b0c5161c8ee06a2b99ab44e515045e83438952226046bbb4adf3c8d0538a0bcfe27a533444e2bfc9f000000000000000000000000000000000c556867cb0238505da3b55321df66611e6a018be4e181a1ec121dd55c509d501558af880a2bcc71fcc641edcffdb13076b9d21a3da0359a377c11a6d0a18bce7ea81d4128dc1e7618e6c35b9149d5c8000000000000000000000000000000001357812e6d93272645cacde880754514ee42aea3690d9d5d67e3bb5ee4444b7a3473ea2af0fc563d246b4c3e8ab5525200000000000000000000000000000000176c413594ca45019a174848f765f69e138e70dde1e184515c6f3012df4c5fa39a28a7e202c6c563db7681b0c4f8b3a9c9cd895d5d1ae0ae704e240c10d8ed4a01b319598d7885f7c3fffcd9b491f5fd000000000000000000000000000000000c5f9145b11f6af0895eca18ba6338408ce40ae1b25f8c04b40c0410a6c69b0144541e2ca1d4303c4c55fc407ca11b1a0000000000000000000000000000000010f2a09fd8b6cffae5a06bf50597a9c0d496bf5529c8925c1141cdb25ffd3afc6b51cb5d21d97c99a8d27281c657bd842467604875028997efdf5139180a8d530a1e9f18c62ddac7753cc370bf25254b0000000000000000000000000000000000c16911df03f532313d162bae1eb57c947059fb5d776ce3bfa661bad92ebacb51154697593e2321bbf85d43ae7ea567000000000000000000000000000000000564ac0f20388ca3bd483033994bf76b1ba135e229487e0c8aa10dfdec1887c62651f4cc0c05622de6356edbfd9abfef2f47637b64d28fb4facc31d5bed34b22e7b270431f54a689cd0fabd205e001ae0000000000000000000000000000000001f6de29a7cf8a89e3cb5befc926eeef59270b929edb68e9b0cd96feb5286e130f1f7c0e0d46cf2a411e499be21d47a00000000000000000000000000000000002b4c8ff1040a843a0e1d691adead4fe3d5306f89f83724a891abffec3c742a3416fe54c27c97bd131730ad364373ed0474c3ac61d4fbece967fbd0599c9a92c3fe0e53899861f044308b0ea8df137880000000000000000000000000000000005d07fdc2e2afd92d5f0f1ab6541313b5a58868d1707ff0cc9e4ccdea0c105cf9cf1f6e52d0dfd22c70aee1f7835ee90000000000000000000000000000000001229bfa1d5c5e4aa5ed0f6753dcb40952fc5446b0c5d0d90b22a7b2abc388cc18e8ef74bb2370b6ccf036f09040f62dceaf9da65e0e1752a982601e9a070a7cc77d5007eb641fffbb78d2a1b02dcffec0000000000000000000000000000000019f4a0cb264a617986898fbfb53d1bde9cd82c092ad86e608750ffa990d6926644c717f6a63279f8061b066f0c4e86fd00000000000000000000000000000000082f1b79a9ccf56b743e14caf0cf18b94f1978d164d9a95fbf87ce15c3a9b414b098fb09654c23ed2981249233e8baae5158bfe535fbc342e31f32ab4723c0d9fe95a2c64cc4e59bd41d13a08ac811780000000000000000000000000000000011c516cfd059a1b8ff75df3b9b6b135c2a52371f1a0dad631e96d8673f1b26daff9e776e9dfb225e9881635a28dd34c5000000000000000000000000000000000bb0dfd476dab29ccc80781a92f5a998b8ba2464d76df001440240957eb1237d9d210be62c9187d7f17891e837d52635d66f5a8f37a7c6a32088897abfaf5a98bd4722c411bf4b52f0f5b5648e89df29000000000000000000000000000000000928c4d78abffa6517742e617ff8efcf59b48efe0b55eaca1d93a434b84c42f29683952dd08546dc1b88bb63a35b49c7000000000000000000000000000000000d63b1f625ca9d33aaf51f8251a088642211a474deac9931c3ff8ad45f80782f62f71f014505606cc4a96f91c79a25709acdd24190589ae7823a42e8b59598eca12bf13b97aa9a0eec17f5f79a01e8df00000000000000000000000000000000131c7e90e794b09da6c4936747e6509f94a467f38ac7f4bfd0c5da88d1733d1b6871a9df498b265c65695ab3ca889f9e00000000000000000000000000000000190e566597ec19df03c473b8ff4ec0cf24168f47c89525b31b1f3592bc7f87540caa8f91e2eb2f415c05502f72673dbd0291be87a213b0a24c92df5ce42381ca378dc4b9aeb4cb9b6918263bea827bf8", "Expected": "0000000000000000000000000000000015610fcdfe0bc92be1f3ea82eb0b0512ed5f448e0000951fdcb0e637ecca602f715674aab1b7555c8f8bdf886d3aa62b000000000000000000000000000000000103c3ceee1b45d9d8912887c40ca16dcaabab3dabf56b8f77cb3186b267a74a5193048ce4165c419cf727d6e9925ac3", "Name": "matter_g1_multiexp_72", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cda9f382fd65f5ab92cc560477f1e3b69d0efe355e40ad3bcaf258509b6ca5e179deed8348836b0e723d5f7ca4c43ea00000000000000000000000000000000037011fda0d188f8d17436d21b9bce522cc9f8e4f473965803b242694f403ecee29d2abccbf56ab0a1f2fe5831c14380b14c6a38cc998df3583228080ea10f215a6e6a4b02ddb6d43e8f459d494a1ec1000000000000000000000000000000000f591bf508a5076b26dd8ea3b0f7a92889131142b34cba3f35a9b861cc6deeca7378d5728c0af9503441144bfc82038b00000000000000000000000000000000156067cc00e82414150bc05ca2d0c0ce1c19e5276e00434754616c9021120bbf9d1c00df6a42b76c3ffeb6e32f8fc3eefee8614394c8109338432ec72f2d9babba06f1e7b826b0f2558c3247c923b2350000000000000000000000000000000002a8128978ebfb99e20ac99ff5b3088e8eb95a7b6b354d46e775dd1662a27d5adc9513467690f377d4a13766276bf87d0000000000000000000000000000000012ba903800e9641de498d8e286c7ee48b48f7d36255823b88a24cfb67f8d2b7b6411ba3304819f588fff0d730cf130e428728d06cd90050e44a827b44f14ea35e83c9b58ce4c3a7a45aed6f31c94fb96000000000000000000000000000000000b107e62453c7181b26a3accaa624a612b7498ccc50eaf0d47bbf350b3c8c54e940266cde786c608e42f59d793e45eb000000000000000000000000000000000194c2c3717a8284051a29586e540bd9e456c0169eab0412699865c12226521796a55d598f60280cdcf37b54a24c931040fda665c40d1da93b1f132070e0b7c8c2c0ea0e66993b5a3d7419a33d118d25f0000000000000000000000000000000013228e1a6346683320d8acad4a5cb1c23cfebdb9d9c451ab81335d27e8b82297b38e1fe2fd02651a8dce3838144cf650000000000000000000000000000000000c6d54add7bdaf9ff8158680f35be7f51dcd5c26a698750c7eab857140b6329157bb7aca8d7c68f107ed9f68b3a076aac14f014117a74f21e0b698a257ae8e3d6091ba76bff7912abb6bd94d41886d050000000000000000000000000000000006e1e7c15fd14ff3bab1e9b8f8b7d6244c707744708db629ef4146b8cefe68c505ea034c180fcff95a452f7e1e5433e1000000000000000000000000000000000735faa57e1c4349be51395bac55a331a04851b41d2ec98072c5ac38eb7bb03e00ed64bcf32c3eac8b34cc6e26769c3ad81a1239ad2c945f1c560fd1674ac7e87d49aa41a1f4a5bfffeab1147c0ef7c60000000000000000000000000000000018008132dcbd9455c3932155a0b0c58066bec4803eafb0a2cc30a93b0a335738b52e6cff60b379fb04b5aad342baf11800000000000000000000000000000000149ea542cf34141fface44046aee2f6c436218374d095bdd46638ebc804bb0c9a7e1e3b01c0470bb6efc7749b8f70eb73a02689cfd2c353fc1b4d3913f5a43745fffe6a87a7c223ec3b25b321584a75c0000000000000000000000000000000003f12b0eb97856f3ead3d46a8321481351471e558add0ac4e1f285e7ee8a1f2ca88ffedbc8ed21df31d599e80b8f0e94000000000000000000000000000000001315ca27c955f3826da43745809fb1759f0f5d5674e4d94118bf2f2ea0411c7d9cbc65f054c41ffbdf196ef24eb9afc55af95ab3fd062088ffbef6ed887fd39aa1d527fe7633b876187ae12e736fcf2f000000000000000000000000000000000cca2b061959fb70d383f7e247c131f51920e048dc136036cc301f1ae6ce13809551d0a8074cc05409d124e2df6536d0000000000000000000000000000000000a9692e0263b563cda35f8497d182fc05e78e7bf88267aaebea1f5f41bd1cadb39c61431bfcaef208adcc9118d4dfb546541c6cf8217c2a95792900e8fc39581b177a57ca00162c57131ea4fb80a4c600000000000000000000000000000000005bfb5a43e3643846f92310e9d5439deeb4fdd6b5dfd3de2ab3a40b9b8b3461136b03c5601add616dd87b9a72e81856a000000000000000000000000000000000212c6c42e24a3f11c30b7751f37c0101b8a071a3d56f2d10b6c9f4f84ae12079d8c4f2d216cdc7ee93abf8b9d6973394b7c3f3c4ed10bced85f36fd6dac2646c65d3c810e6d2d116c38aa5e10b29c2d0000000000000000000000000000000008adf951da1f0b64c17f84031985bd1f3561ab44c80c339c4c753a7c2080e0f57c41b79b6cccb75662e8642ae0a94451000000000000000000000000000000000d9082079fa53008a03f58b87fe0aceb121c6c004493f3da7ab37f3236942c8ac01fc28db26b87bd2546f93b12577ee57e33f394e96d17efa30d34f57eecc45d7b4ca150a31b8d0484578151d6e65c2b0000000000000000000000000000000000f352ce042cbbf1adcc42030ba8e0dfc76b4ca313e82a5c5105ec56266977dc83626c9a9b3b5c25ef459a6feb2722140000000000000000000000000000000009443440da963a7e64d90e4642861f3f5399835fc2fdefa7e87708c033848170eb02407a6a9edadad27cb02793055140fde92a31e571ec03e509ac8a70ed5788869854eef0bf578efe6c5e6468315553000000000000000000000000000000001699cd7355b0a0be2946f8f49648bb04a90c6bc8ee7fa258a357455864022db999793771a2e66adf3cea5a54ada82d6e000000000000000000000000000000000a3ebfef4ba72cbccab5e93155429a14fd61c106ed6d2c0db0694c4733b6f1730cc9f34a5e9598c60e189b8e4943efb56f7de01ad0f7b4dcaee1123bb80a71d3bc1e63ca577a12b14ae2a11d8c0fde46000000000000000000000000000000000be5ac701c69b81cd75fddb8da92066cfc9d0d2aa7f01495afd87e44076f9f022179b7d4b4781d0b5c6c52b498b63dd80000000000000000000000000000000006f2fd1ca9a34fb09d922a76943b43505f2aad16489a138668f08b9f388c67e46a4d5df7387a1c3aa23c76954913abfae2c69d21d40813ee40a718f0ead36b51f3a50e9e4e4b2de8acd33add62bfc1d20000000000000000000000000000000019489b41d8b1f2e8ac09cf3f0930e092afd74405e213454c458cfe44e5f393a88713b62715097a1aaf01a188e8ab07c00000000000000000000000000000000018471d616eb66f1dcfaf84b7d49f632e0a5306888e44c70710bb61d4afd440e5f692eefad842b5d37762cab649fbef34762d89025196aec4f87da2fcc5a9188b4dc7b1c014dd1d705223bf9fe1e7a7d1000000000000000000000000000000001088372334c452709f81b57f5e5c148e0f88dc29dc9a118abd6911c46ee83d0c6b58ec9b854c15f519d33d281ac9e21d000000000000000000000000000000000394a7e49f32e4f7d27f276892002ad034dccc8263591b5d941eb2a5e60097e757ea67dcdc5242b755fce30c3b3b64cdffb9f3e1d43aece3af1f59319a8228cd81e668b1e250d03350958dcac9e23843", "Expected": "0000000000000000000000000000000009e68140307d9309c32763e4de857372a61733060ac582922e3822e46c28f67bea87a75bd98248466e8938abdc4ef54b00000000000000000000000000000000187dccf66e6d0593ac8caf6723033db545c43cb90a5f5486418325860b692ffdf8dcf23da9103dc65336d3cec2577a4d", "Name": "matter_g1_multiexp_73", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000083dad213737f1789595316285a77c859c469b9bd0cf08c61884456e4fc5ef0947847186bd420af252d822419b1de3ef000000000000000000000000000000000795a6ced1d34d91bf5ddbe77fee452699a1b32daac270b4e8661259dcacbb9c8c3776043f2e149773427fe109818c87be285a119dc8cb32b1a0c5380af736114a32e9d1ca870abdf278dfa84444f70e0000000000000000000000000000000005db83053f9824116b9d14ce0173c2243a4a8506e161db7f97408dd6fa77b65d0e0a32e95062699f7aa85cc9be448dcb000000000000000000000000000000000f20953295dde557a078c981f0b988cd9da8c7469fb7fa3361f2386c7dd609bf80ccf91cefd797eb3a4f849b2cec4370bc0535bd504d7b9658e459c2e79b86bf4e718baa82b8d6e624fba0eb141c726000000000000000000000000000000000000bc3e40ec1b6e863f75e4adbcb8b504026d0634d1d3769f7795ed2956bd450e68aebb1a9d11a71fbe5b51bc79d97aa000000000000000000000000000000001703e1fde7f2c740ca3224c1994282e633292f86095be38dde3673b78729db84bca33ee820532aa92bfd32728d9756404f3fa09243c01748954d84f4deeb460f3ef78f9c34296c6a092952bc463d72840000000000000000000000000000000009622c13e8924441b0043770faaead6db793ab818532c7323d9ee9a8d118cfd2a578e1c13723c8bbdd049b1d8aaad9ed0000000000000000000000000000000009da68565c05aa28648c0d0a0e185335b4e58903982fd361fb57f544c1f253a55e8a233b341537d78c4f229ec5f935a85d84733ccc41f71a11d61852fa336df566109c5538c2c5f5cf2af961e93797fd0000000000000000000000000000000005818b813993d7c346cd70190e1e6410974e64e08fb0a70721a0ee430dcb0d92d302943836343e274b26c69030226c0d000000000000000000000000000000000ee84b6b251c9d4f7e7abf843c73f0456968e23e79c54d8742cd5967737b9cf9ae8c6030722134c376c7c9433b749563feeb95c32362014caedf2a9e066a775e2db0d1322edc86759faa99bd70c05b580000000000000000000000000000000006870d696789986991a222b988c3623ffb51ce96ee35140e817887ea37068ec77d8131a97579f2ea29a5b45ab55ec5d90000000000000000000000000000000016b203c189343e67e10928c2a45259593cedb1a016491e94435a0823522010469729bd69af9c3bd6f4e71e96c7d8ca72edee2ea28b93b2daf4ff927991769a9c69ba16490b5676074e64f5e91fa994a600000000000000000000000000000000191a7f7469739ef4da1fcfed877b875c4b0af45df7aa9055b7d5f0c1360e4c4b7b67958d03125fade281c663923670040000000000000000000000000000000014d5256c242839e0951390f00affb226ee6c906214d8d7dca7e4fba7eaa8b1944fe4f1f93bf6ebb21b4a8585e000a76b7a07e50c1fbf1b388e9264c762798c31fe76761508d070f06adc63130df07641000000000000000000000000000000001968eb742dc0e128c94c1f0dab2ff3b0d300966537293ea16856e5f3ce5e12164d9c52fa59e08481bce84f3f87dae8f100000000000000000000000000000000098ec0e7bc53314fc8729f4688b99c3d87e7e2770877a30898c37c68a5e0a4459851b8fa390cab18e7cf0d325d906ce4f0056903b4508cffb6334bb5f645cb553a8cc61ea6765283f933686f172f8360000000000000000000000000000000000064ef5e6fe9de3e86ccc7a8b809cbdd945eef98e8e6cfa82dc64ba94070cc107090427c13ddd3bf25d542696d5de44500000000000000000000000000000000116b4babfc4b1a7a36405f597d4afb478c024805495e1a412a3ad5e9ec5f01dc47411ee6e81a9477677b89291e91c2b68031f363c8b0062b34d48f4c2e5bdba884005e52f77ac04c2f29dc7ef10fac0c0000000000000000000000000000000014d07ad766b50a6150a50decabc56f04559d1b196b713be88b5543a673ee3f4499e42b58c532e38dca0101f639aaa9fe0000000000000000000000000000000001678e7e66f44cff05163ce249df65063c4ea2d2517a31f42dfe76f67041d7927ad4b0efa4b30c33156b14f5127af190cb146e27a9d36dc698e1982afc945af9500fc5aeba719d06d0c4e4eb245034c6000000000000000000000000000000000745f042a917dca8e35c8f0301612ce198f75144e145a3c3041f4ecf893360eb0b7fdfaeefe78733bb88010d6a7b9bb3000000000000000000000000000000000e8879142826593a2f1214eee206ba69b7962e9a10ba014af5daccc1e4a2d3c893fa47eb533cd0c0a9fc1c09d389db19d983f98fe5112a55c23591bf4e259d072f893944741d9941a00f907749e3c9990000000000000000000000000000000009da4fdf5b86facd674ffe6d91d03674ebfa3aeff5ca2a659777be20109946b1bbd759d4dc2d9e859d587ce50ec3bf01000000000000000000000000000000000924985f655b00fec0bdacfc6914eedab676a962e21ffedd83be646dc17f5cdcdd3f43a9ad7ff9d976e4828b4dd219b7a62f99ac46f986f2f29f0ad3da0310f061e691955c711850a2816ad7464614a700000000000000000000000000000000187414507425106691a2dac49fea1eaa14783b2a5b79a945fee44957619793be1a68aa110867ea405a076d30568ecf3800000000000000000000000000000000034e932247b81bda0a54568f2887824028d69767b9131c106a4d204c0b2bfb929b9ed7b3fce1e354e405aeca8a28d92e7ee01b0c9c6a6ca1fdac35d89c803bee3595f03d9d200affc5292d8a7c6720b800000000000000000000000000000000027361b6341bf8985d79b6dde029a9ee54ef441894f34d60a3324edb502bdc78ef60789e5ce342c240db0fa91bbbfd00000000000000000000000000000000000bea3c850bc9d0860241fc6de65c203d5a11e6425faa503c37641522fba6fcd31643209329e6ad75a3dc5e4a4790db4a297fc700698c56877be6764f48a836d210bb33e99b5735da9837882269af9b45000000000000000000000000000000000fc7095889f943697577c8867b411ac925ea7182e47a7cd19387dcdd48fad5e558de3d80e3036992ba5fb8dd7925774700000000000000000000000000000000160f1fbb346c48a6cab0105d343c55b3714899e931e7b4e0abe68c4fc7067189181afb9c040d41e4c1f7c4e2f1b8a63b1b7ac02db15cebb8af459290c35eb5a86cf98b86d8336764c6bdda6698b49b64000000000000000000000000000000000bf1740d01ece251c0f0ee4f798872eda7f5a4ad3152d86db12844ffa88ca52835799f0b2601ed1bae6d4850cc889940000000000000000000000000000000000557f274109f745af6cd965d6e706b9ea1fa3c295cbbdb203ebf049c1070595ab820efad6652b1f1ba4e2d331b5bc6da5d1a3f78a2c2ab7b85cee68ee670f50a176e988a341303afb7722917f442fab6", "Expected": "000000000000000000000000000000000c57ca082c662618951201a98d88170a9aa076fd1fc48c8ababdcbb09b63c793725261acd370d03d28ea47c0ef176f1500000000000000000000000000000000110234e4c6a99c6d1ef8b43fa897990d605af9b469045dcd0ead52b03f9f90dc441f7fe5e624349788746802e4f74015", "Name": "matter_g1_multiexp_74", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ca64fb3ced1d15f94e9b234e6f6fe59d805eb0b50ae29c9b31514ea5c6e79542688e871de6ace893868fa0eafdf46890000000000000000000000000000000019c60ebb5ca4e605e3b0eabdec53f566c9b96a143631be93250260560e47a2ff6b073e432cb1f9104ff913616e7d81c834aaf86eb77ce03f1d8eacab84d5ff98a565fd33a9a2c40f2a19d7c041a7e2a60000000000000000000000000000000010c867a070e161939458694cd4015b76bc4c76eea884d9dd309d6642436a82bc76ab57b2c0e2d3ca61f34645db65f2460000000000000000000000000000000014d9df8b34369bb23fbeac29aa8c35b346992d847fc2b9e3b96345f4a2245fa8eed505daf17edb4090726052be75662308ab2065f1d2278caece0939cbbab4bcbe3eacdc80cfae6e4500a5195883de000000000000000000000000000000000017ffdfa10cc8e1a8b3751312e5bcd09772462618b8bbdca59a60701a96dab651fee0dc755969e1c3a1d2aa4c11e48d6d0000000000000000000000000000000005c2aadea5a4b11077a2a1641eef2d3bc40c2d8001e9853e44bcead87cd968ce41ca50644ea0fe1d0ec4c2d7eda9dcd058c69b55bac97a633f3ed7816e77e2a26cccc029f7e7429c86145ca4645eb4150000000000000000000000000000000012bb9b8a1537c2856d4b2bbcc6fdec6d69eb6196d795bb0f1f49d8a886076e7fb424f63400134622941b2b88ea61b8e30000000000000000000000000000000017206fbf293f1ca1f2a0971b920e702ea39996058111ac2c041c12f58f67037a3840955e1185b413859a6f845b333b58ae7faf23e841bd53683521cb3cf215577fa51f0f751714b6aafe5c740f66208c0000000000000000000000000000000005eadaee4c48dca28f9469e882ca8ccb71f82bf1f2cb5b7f50b2e63a05e78415b3c5d0767a27f19a0b1c88400116e5310000000000000000000000000000000017e95e480a145b5e897c7a1ecc1b21c5a000248f87e74bfecc21a3cf8a06c04fd075612a62145ac089f208e567e4e12072022cdd6d942158bad47a53a9b0c3be910a41036874975724a5cdd22c0128710000000000000000000000000000000007b834503ed3e1cb74738db29c91f415beeb3ac5b75bb2cbf11f4a9cd1608ea6080dd1bd50c195dbf5ab6808fe9d6594000000000000000000000000000000000eb32afb90ecf9923ec22a483ffeca3a15d358013e64e521aa42d3db1ed0397e07a85321492e0693f8f041f4f8346c6c800ae0b956e38bc34cce55bb7e88f1370a30fc8ed0e3f1126c68c30792a2cabc0000000000000000000000000000000018f208e26fd7c03313df686e27bb6ea09d9a998764e805fe6182ee221cb9ff1552e4db5feb91b3b2fa595bc32f81898e00000000000000000000000000000000137c06c3f9eb27f1c0546b3c7ce879218a309dc37c0590fc3e151d9f7fd5963f0fda201faab489dce0043c3180abf753a57c3322133d6ffac661c888995e7cb067ca1309f3e9178a266f1a410a79c0130000000000000000000000000000000016fa49bb488a35ecbfa9e714235790cf6e7c3ea46e6a9a424f59c63d018206740e9467b0575077e86091ad6e0f9f56b6000000000000000000000000000000000197185b7c82ab9e6dc8e2a71c94dde328c923eedc6e305d8f36f4b636e7662e501917b89b33877cb2094b523c969dfeebe67f3d067b0d011abb31588d1b2fa9fdf8a56bc46b1a0196e926d4ec7304050000000000000000000000000000000006b797e2bb8c0c2a5a6ef8d9f08241d42299efc8af049245c254a2e4bfd122a01954bc596750942bf7ee467b22bcc528000000000000000000000000000000000a655491c6381e81473c23565082544d9f223042c82e241b1cb8ba48e847d98a373fc68b762a600489cbbca612defc61fa1d6d0d1876a67337d66c596fbcd7eb22ee308e4a5f66cedff584f1441be6a7000000000000000000000000000000000d7b7ba451334d1391a51142c4b7cecf0032fa6d28fa7f36d2d43ba39c6418946244da3cedeb2bdfadd453eb4d54d05b00000000000000000000000000000000127655a7acb4e3271a188cfd287cc1af890756e340eb4648bf3ea3e469644e6d21f63e64f81ccb55b9b1e0a62ddf58b5f0c4ac919efdf3d0e649126da7f8ca3daa30b6ca6f3be6854c0f447a63cf211000000000000000000000000000000000129442dedea08bee8661b558bdf8c22dd391900a501f1841c77359b20c1a1ff8838829baafd2a6ab5eff31e3f9ee884c000000000000000000000000000000000ed7c27bfcfbf9b41c833fc0d8573d7b28a6d788ea3cff4d96900559cc63969ac1d5fd366fa705357626eacf402c2ec560d8bf380bc2223efc779a747c0a36f8c2b18c3e821e96163bae14b18f3739f90000000000000000000000000000000013a11df012f8a55c263c5c55df0fb682e685a5feef160d77d26db7125ed08e6605f3d67878ec78fd064487f30228f4cf0000000000000000000000000000000019292997c874c72ce7c432f20da1a338e9dc433f9257b7353f99b5b531a9997bc3a3405b0aba89ab5a2f1cda98dd8199006c3a7b5ae971e4b0ec34a1007a02cf8c55f067115ba00c5967f70a7dcef9d600000000000000000000000000000000006a56b816898a1fc9954495b711c493ace881e3989207b2f862dc41c5fe346fc2eee18adfbb9db67e774055561af00600000000000000000000000000000000013971cff1e9a6ce35a7ae40118a007518bbdc5df5939a90fb263a9c345a70f4eef2f94ec671ac6964390d0478cfbf728f29e330b48230de23e0393bf1614cd26685cafb899db5a164497955d3e98be40000000000000000000000000000000004962ef115a4288177df2f0e4665e5d1976fd027f7f87a24ccdd0584e265e2f5cf0a7490dc7824f5eb26c9569bde9d6e000000000000000000000000000000001544f43d961320d59c65563d5f04341a8ec3e6e64fc2dba7e953652232d615c90eef2c859525fed99ae6ede2c39f510a861ffae8f62572938925593f7271a56e0f559b56bf97c454c38547a2185e2ce70000000000000000000000000000000004b250ff8bea739fd73b3c3463617eaaf3b6bb9db11c2b915f7435996bb4cff3561fc268d2cf0db1705711de522382200000000000000000000000000000000001c428a889955fbb5fcba993f2defa5906ac7b6a3fee6c07f52de8d54b0665cbea84e89a0af3523213fd19f7d37944012dd907071c2d39fe710215d174452459cc31d36007a1b5570a27ca2e42c8be5500000000000000000000000000000000106fab277085c88a7d664587f67aac8de95aae908177dc513fa24c8115fa23db44eafa7075b036242306002ee6918da80000000000000000000000000000000009e832e0d01bb5e89460e2cab772c308da07414ff8b880288c7b55d6390360924b806c71c9f9762d84d8d3cb3c2f6a6199893c06db2dab559f2c374df4298707dc1815e55034dce920ae7b1df2ec8d23", "Expected": "0000000000000000000000000000000010224cb0e43534025f8ba7a7c426355a2091473ab16a752a9819d8e5f3eb5b1b5c0891b1c0cc0017655dd8aa7102cea80000000000000000000000000000000004313278c1bbc33ae2c3010c50be0120bb3ec794d9ff77fe97154438606e5f6f04c1dbf8dc01b827643a31899342e1ed", "Name": "matter_g1_multiexp_75", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001812b7bdac748d2c0f05f10edaccd351e35347a4a582671762c0567f55e411839ec0a776c18cd71cc6de0c3a3b8bba820000000000000000000000000000000011afad9a48c42d8c3bf74dde15d7b744c6c141ea57e133c9dde7fd762636115e0296a647fc3fbca8144048721902973fd8555388bcc6791802ddb6c0f4cde44f45ac0b5d7ecd918bc34fb9fdedb65b94000000000000000000000000000000000f4900ffdc92661bb33e7561d08ce7757ae71a2b5ebdf6427922454044c6c6695e249069e83f3053e8a8a0adb5d3d3d2000000000000000000000000000000000be84ebce32bce4d58557422c7a8c4020d1bc643a99b00231a4d4a06d5dcb56bba61ead26fbf07079e9457dd4364ab6d33e5999498978d14c9de06f7beb2fd870f6f16dc42125fa496606e65c7466c0f0000000000000000000000000000000017399488c58e24c6e1f5e9a04291930595389536480ee6dc493cafa7f0e85410bccbe5c5841a1a0e495830be7e32c0da000000000000000000000000000000001055ca833e53172ac1d2d3d7c6fd625dcc72556e8d49bb487a83e56deabee4fb672b6cf7787d1231c760c2b7e9d4e55e7894a51dcfe5a8fa4da1745a696c870b353fb03a31238b8744840a78084bde48000000000000000000000000000000000c57fc0c785d6b81d4831ba71bf27f9af318a730a9502917a68397678c7ba22f21335ca2fff5bd495676faa418fe21a9000000000000000000000000000000001012cef9cbc88b838492b6a0074e0e5d24635d36d669288acebfe446157a202443fbaa5241b288fe418e1fa50eb3e65cfb6a294589c816e18859cec34262df6490a2af6acc7daa3de861198c5bcf4b13000000000000000000000000000000000a2a4bd7c7a79c2336b05bd5e0558736697c435477d4d0dc790033366ffcdecac3bb9cf48d1341835f7a42e17af833c9000000000000000000000000000000000ba384bfc6aaa8402ff869d78973c68ccc36c20a839da8d570b6890614f692f3a3316f0eb45e4afee0cca078cded752e83c4a3460caa35fc0e7342dd2da5c7b6aae818eeaf5a2cbf4794387180b95dfa00000000000000000000000000000000143e594b8762b4f821a6cd294251a114e248974494bd16a66f27192d3c2dc56c19d886b6305d420f8b81b22a2ce4faf10000000000000000000000000000000012fff0d7edf98633e1b10ba09b3c70fa0ea8674120160933689115275da6f95a8cae1ec665f89ef3c5454dd91d291ba4d2b65c1580bb46e3a4cd9d9c4eb7dc998168c66982448abf3a4e08cd12f612b100000000000000000000000000000000159734584d9cceceb9a27808a5bbc1be9acc15c6d2edad81759312898be4efaf85420cbd004102f7b051c83b27bc3fba000000000000000000000000000000000eaaf5b8e35ea5d52bbba19087520a96348b418159e043d3b39c451fb77d5b98aeaa43cacacadf3e6ebb503f49c5ad4c120892aded230949b83bfb2dbac054b83a9dbb852bd0ad85dd1d7f715852306f000000000000000000000000000000000c62de2a514ba6a74f66312553218cfcf49828b6f01ed05561b54d5f2a87806694ada45b80429e60fb985d9cc39e9c4600000000000000000000000000000000146b134c46ef783488e0f2d6d9b7039971e8ab7f3c29fbb2635bed84b44013159f483df0e7f0afd038b64f9e5cd105726af9777a58539e5aa8b1fce0994e0e1cdb5877d93ed4db715c5aaf74d6a8bb1a00000000000000000000000000000000189f02eda06f2d39974098d874325e4711a3f4dddf78c1b9ffb025425c8abe6dbcf5a01de0ebc802816fd67b0a9882fb000000000000000000000000000000000b378df4be4566190679691561aabd7182e68dba4ba05cc67ae19cef483fae99f4cc54540b5a5180c3854f5a82b6fdd0f37e2ed8e96921a0f9bff8b43d432b382d7b59938e269c381351ea49b8c1ba2b0000000000000000000000000000000011c0ed482c1a1f030fff7395db725633a60875028e2a7763a1ac801f00a8f4aff5e19e556516df899cf5e798197f6880000000000000000000000000000000000fa7faf03f2f636ab340a9d27d9b5a66fb8daa9c083a32904a4407d408cd3a14c17734d7a14abe3655979230e1a93e4d23f4a77a2c34a370a9b59ab1cfad77212e433464d0195f0d2fd20c69141389f500000000000000000000000000000000101f93857688bc4e4da2c5407d8bc68b9304d27c89a44daf7cebeef81ab96d89c83ac34ccd0dcd87297929551810e47f000000000000000000000000000000000457eef8e4d47638f83aa2165c0f2581e6a0886595f03fc41319d6ba71da0193a4cf9f52c39c79327a69037b11a382f696c59b0bc6dbf66f42cfee34413cc4cbdae7a61e232757c75474818591764d6f00000000000000000000000000000000110957948a78ad9c04b7abea4d1caff1de20b5615909c2f5b8ab7a1dbd02b9cf2ebfaaf3b21908aeeae55e47b9a21b7500000000000000000000000000000000168f08d45ec66fd4c9a94d82d9533aeaa251186478851a421f097d00506fe6dc0392114115e3e66d8874e0aa4b15cca281c180924f1d982bf4b6a2bb1cac590cdfe84198fdecd87364e163dd988f9b1c0000000000000000000000000000000015fe358a596150d9eabe6f18e06d562f9e6c42e9df7ad9ef57be8c47c5764e408efbedf136059d0e04f81d4838713a83000000000000000000000000000000000ff7a343274892ba23daff40f5f8c56db9a4788483c16a4a0495a1f696d3304c6276ab5a6d7b3cbdce14e9711b033582e44748b9eb1f44b5fb143cc8deaad23047bc5ecb8059705e7905c37625d5e2d30000000000000000000000000000000010d66f27b2da2ffe49b7540da57c25f0d36de0c43d04da9b123c153ba3eb63f3d26d28d4cc4cfef2c0652010be2f9eb10000000000000000000000000000000004d4cf53935c01bca14c75d1be55e7473d17de6c5a2d69813df90c7612aa4815ca6ea982222793ce66bd1c69f6e456feae04d7723b7c9cb0574ba744bfed8f8a347ab740bdab99136aa71a6d635d0d980000000000000000000000000000000008ece81bc19694eb40ac3ed089d8fb0cbed88371c7e314ece92547151165a017b0a5db4eac06bb2679a8d82b296f522b0000000000000000000000000000000017732041d736996351f132c92fa7249483612bcd79532156694314834c04d3b99579d44628c52eda270ec7c3ca7c3e576a794685a342ff25dd706e4df725e3466889d8f08a27ed2f32523b117f01a84e00000000000000000000000000000000026b3730efe162d58adc8d4845706f9bfe8ff54116b518d6c3b2bc6418997a44e98071e83566a905973a2d512878cf1d000000000000000000000000000000001449b0e28d1c43ced7cd687a550ff7669df47e80d3f2ee621b791848f1f7d6cf6272e39c66e8a69c81aeb67b06c630b2ed3f23c51953e46d400802dde46c374178ef379d5c1b04d25449891f0d5623e5", "Expected": "000000000000000000000000000000000154edd700b8cda3a0532b2d6e81cded6a9662547b7d638f229ac44975d3b4b2f19816eb664e6208f33bf6f8d070fa58000000000000000000000000000000000a41ce7605d7ec592ec3a030307391ac64be5df9a7f8ff9b7ba15f7f6931353fb824ae8aa76b31466b7e06cb89fbc1e6", "Name": "matter_g1_multiexp_76", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001227a5d20faf2f8d9242e1a7bea89b5d7c41c3e0d8f2629b4004269f9babd2521a97cc23075e13a53f4c66a82970ee76000000000000000000000000000000001726ad8abed312a369001f53270b5e7ad8f3f2a031804ac055ed4ddb2f40eadf9142416efbc90e84f499e07a307994db8c8e071da1ae8f615631759cf33fdb876ab289a6bcfa6fba2693a58f8601dfd1000000000000000000000000000000000a07b5276098f9b3767908192f91473c554eaed23b810d3b464a3677089c45e2263600cc8d84766c7c67d9b5e6a057cb00000000000000000000000000000000175af857d5b53d195a17ae246208b55f35f4ff193545ea5a725a70f11fdd34ad2fe22431cec7835d4fe3c401c82a93fd8371fff9230243d2e6cb6bdc4cd97260a8cf0362d18b9ba8df512d2a6f5563dc000000000000000000000000000000000039e109e0c2ccb5e6cb4c5451125047bbb854488ddd74fc4360430fd80f16db3498a8be9514099d3ad50ed4376bb5e50000000000000000000000000000000003dec8af7f6805ff9df65c39262959c3c80f271d2f0e53e7e719fbb16080d7d90a1211a6b4d0513c771ddad7d3dc009063016c9a9cfbf336ebda090d3f2a1a1b265787e1917f0148f82a9c0b66b21dc10000000000000000000000000000000015a00f549c3a050a5ffa8427bd0c8b90a788c6f9150728b037232ce1148c02bce908f60ee367b70d0c9642114d6e657d0000000000000000000000000000000016831ffba7d7d0bc239563e9e62990af4f740e57ca56d0d8826a9738338e9a1d2e8dc2b8869d62090b06f5a3f68bbcd36c9f679167d5fbb29250834c9f65d3025606e2af20aedec309718f95ba01e90c00000000000000000000000000000000165e447cc890b383b46f251531cb6d29cee835fe2a0fbe14c65f0998b2911ba86337ba79decd2701a4db1916e01ff4bb00000000000000000000000000000000007bfb52f3d4a281238eb65565af329b3e043e412588ae00342144d168d903cdc9131775ddcb5217ff692b0f922504ddaaa3300f5a2fafab132f5f4662c1d288210e7502ca2472d060aeea6f2eab2d71000000000000000000000000000000000ef8ba702c88495b63ac012fd9ce54b4a7ed67b5f7d25bcbedf951455fcfa95a8c7775c5ccc875ca5bafb9bfa1af738e000000000000000000000000000000000e53e18a3e7d294b508ec4084cf57557dd1a96ece8eac9873d35e4f1ee812a1380bf56569e5e797ef54202b1ea69291df6608f7c036c8fdc335601ac55e869215eb4e626f52bae813d45b827df2afd4900000000000000000000000000000000021ef16de941ce6394ebd484f6b9de12787aef9e7921292106e6c1b18b8de5c640e448f53abd536953b07dc41db21ec0000000000000000000000000000000000a5d482a1c20571e03501b89d2bb4c6d3251bf0b015f23ecfec87dd7cfde705f946c311483ffc84381609c394c83513a0cd68c59b1371c7063dee5732182961be90b95247511a5b564d7eee8d2c7c6470000000000000000000000000000000019c277726fc9c53de1ef3aa2ae6e15b360a98b4a2b27f9057f91eae5b2a308b2f5d618d8e458839d1d60105e4888e7920000000000000000000000000000000012ea8dedac124f05ff58ac72fc967e325e00e83aeedf956adee447720f491ba1bcee564f52e4f0e53faa106ed8088d4cea52329555d9b79eb1fd6d186df80b25245ba9225553f402cfa6037592f0b10f0000000000000000000000000000000000483da14288400f7b27d712ad849fd7c068db47709f78b297c746ab3e15f17f20130b415c9a1b024bd5b24f74428f0e0000000000000000000000000000000006746bb7d3a38fd833187a16d5500d394303e2edf7d5341d787257a9f811411a5cd586b300b7b4398f9d266bcc27d9cecaf39f2a517d432d1653c37fd9a6c4a8a811107dae428f4b2af3b12e4b6acea3000000000000000000000000000000001700795ca26c2cf7dbdb64034e45362295b7e9c60753d728bf689239b0ad7073b29fb872aff047605509ecd10cbd4fd2000000000000000000000000000000000266a09604de2ccb74c5d97dfe4e9a74cf89d3612de9b2d2d39dfa3362b500be127b83566a61df49e639d548a0ecfea7ff0bad6dae80d5f47dd8c208fef0f3046cf1040112d18c596eeb934762977cdc00000000000000000000000000000000146b2b839ff63d376db418a51890c46b0e3df6848a5a39a26a02673e93ea8dec5079e89a333c85785eb0cd1d67b1e101000000000000000000000000000000000f57e8e4cdf2670dc35a12072923d334523e7ccaca66795e3a762bdda8efe5424f88ef7e4c48b0d6760234ddaad4d7370d0c40e5d422685c5c83716380eed82392ae1dc6074a7edb5759fa34a61db2d0000000000000000000000000000000001989144efb1979a42399f93fa80bdf256316f6365bd82b89e0e2371de79ce9de2435a6cfe9704ed710bdfcbc8cc2bcb000000000000000000000000000000000084230cca1eb5defbf2f2ee29fb2c47b417919f220c25bdd2a017b514840466a45b2c00047e9628852d48a057d6335ad7e93a16a443d5f981a02f0b6866536dadd276abc0998bedd76b168ebc8e31b8200000000000000000000000000000000128df806a651c43c7e0a3b2c5833bf158ea40953fb0efb02620cc4ecfc4c32a409a8bd9e98e82812b54d027b6346afc70000000000000000000000000000000005e28760f1e574aff9664e373622147c08538ed45cdad72a546e4b5840758f5ed442f8cf24cb0ba35902e64d084406f32a1d13a64c03585715908744481c79f340b5bdcdd88d685ab8b91722ee7ab719000000000000000000000000000000000289520e710e7ce4a8a671cb00a015dcf40ee2a69309cb89b514f6fb2c6e8fc92a49905893e3e0e9567956fcc86dd89c000000000000000000000000000000000d1329a4174f802680dfe8410fb45e23f96eef4649579ca8e29b3040de33cd6bc485d1339afac9593097c70a0312f5162bc6979fa2e386abec058683c6d74de31af3cac21283cd5e4244d7edd94da96000000000000000000000000000000000175f1ed2dcd584f9c59c9c747ea1841792bfd9a64747f84dfe32e256ab5a48eb2dcaa337990089c86b3dd589d276e2ce0000000000000000000000000000000014d8bb6e278ae9bd9df2609690286be593eeb668f5e2adfe880e1d34276ec3bf4ab5514c7898a6504da63e0ecfa49d020f1937936cc3766184e47f39acfe5af4497e8edf77ab34083135a9ced61d25ed0000000000000000000000000000000018adcc61d9162790bd8c19be058afcce08104a952b15efc276af8a8807a4d2edcf8557aa03a297ca01d6a3869160148b0000000000000000000000000000000004338e5f7a12f2ffdc8158a51b14dd36934f01d7fbfe45e18276f2432b1b8210ba6bc5f246a52646bdbf99ed91f2f48f639a8b60a1849c71688a11e612b315439161717f525b5deabbce75808470166e", "Expected": "000000000000000000000000000000000c1f9b78641053cdbdd6545691d1a5238389614524365bcddb07f9b9c6c654e58a40047084532b8473c7d541ebb187ee00000000000000000000000000000000028eb1aeec5e4672c41eccb45b356529e5331bb5fb0ca8f9e10b20a2ef1ea911f03af896ecf7575613bce5eb8a0b0837", "Name": "matter_g1_multiexp_77", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001242be79cbeb2176ecadb07d205d532bdaaaa26bf9103371f2c4d86ed1df72ba8b6d5c76b7aef25c743ec4f43e5237fa000000000000000000000000000000000d2de7792d0655ebcbdc123ed6093ba68948b8ea156a31b9f23d1abd948f4b2ef2f27a3cbf72b9e5b3e966576e9ffbd5f3efcda934ec9d2ab05f25d618e5a483e830d0452a88e980589fcd7cfc39e5d8000000000000000000000000000000000fa50f78e45b1b7b61f8508bb5842bf59d0f41f2a8192cccec6e56125ff94b402dc47d3bc7762f3196a163fb148105820000000000000000000000000000000002933cca4d82c6f89ff8db5f9239ef8fee2efdfdfa22e0b4d0fbe223910b08060a77eb4328a05ddd31d205861db090ae4507a696cc57c0bc49fb4d1686752c71c9c816d7d09bd66910b23810d475aa02000000000000000000000000000000000c15db9d1dcf646bb4c169490256050ad5e408d1f45221a9b4bf02f7651fe93ffb892c98d19d730bdf3971281c9e2e3e00000000000000000000000000000000150a6d1978ec63013ef3dd3b258ea3a716c1e564469d2aba343f3d15c30cf287b706b9eef8363351cccb79ecdf5aa189518c1259f23de4cecd5e3a40abef5662b497ebaf16240f40ecd651d2ba50af07000000000000000000000000000000000f7e810001b9e3a11a535f6744a0dd357cffa585baabf065f1e72c9bab5484829a94159c72ff2221406c8b15de465f8c0000000000000000000000000000000009d48808fbf21370420cad4df7a269e1eeac98d2aa5ad5890ff362d91cca5ab1b57fb079caaba3a135c15515e98c6b175561616c195ccc1345421d8a6efec48f0a4dc8e89ee89599839efaf95c38655100000000000000000000000000000000191dcaf13a62fd6de0bdd16151b3c27f54b40ad82da1299164da87d0cb7b4c769f941c39fb4b68a8915fa95a5ddc0e900000000000000000000000000000000008b0ad7fa07edefa61ad026d42df18273b6628b65a4e655a98b705f588494d06c37153ecdadff83d94739bc254d6d8f837c77734125181c72454bb2d37c3725cf1f9b6d6f42b721bca469fec154b3e260000000000000000000000000000000005e3001f37e840a9edba48b3b436dce520203b0b36c3871933464be1c41178f7a8af9b14000b713ee8fc0faf5cc1a870000000000000000000000000000000001732dba0dbadbe7db31ea6af17520d791feced0a7bca298b932f51f3dbcb355699db533cfc8b61d35d1a346ea5de8032981483aa66e04351f4340fd2b461165b9a9983e91c148da78d3c8e0c69e77de400000000000000000000000000000000072e4d38aa0e168255f1d69ef129642b4b1b57289e630455b147574b03d17e3cf0f32326afb7c45da468e0d8c2276da9000000000000000000000000000000000b60685ad05be8453d5d272c73365d645dab6c50c820c1fb7fb50d82eebf9b03ad3c8f711140ddaafb2bb128b7be2e6c9913da6f756005ca8ab900ab686484483af07df768209a16d807f8b88b9334d3000000000000000000000000000000001401e023aac71de3398f89893102efa8760cedf47938a655983d73ca8d394a239f37959e629cd908b4e4f5e55955b153000000000000000000000000000000001458e304efcf48594d7094d30a804742b08ec94ae479cf5d4e0575828ad92cfe8e11847d6078f5eeea4308a8f0644172188fb33fb359f21bc5bdfc85d39676c2ca0a1e619bf8a8e8de62da8818bd6cfe000000000000000000000000000000000d446202ebd7a7995a4e8aa7fcbaf6c4c4591c4bc40b374720752a150b452b461f59b775e3088733ca967854413a9f0a000000000000000000000000000000000d5fcb5510c0f7ee77c7584631149cd494a5fc496b325ba93ac5f801e34c815fe562be4758212f32ab0978930d142adf5525ab4c4468a2ec0beecdb7fb072f28260ebb3d9da1a4c274b2c11a087e814a0000000000000000000000000000000000e034e4027e846a8608680995860b2673854d8fdf0e61e2663d7e0d904b6725ff28bb4593e7bf5e2c252d9c9710e39c0000000000000000000000000000000010bbf60b95669468e5dbdfe912dfeae9945f44454df62ec116b097b867b14c402349af692490269797a30639177151945ab5a55a5cfc49cf6c36b5718e108f8d006bf7fa1ec3dc7a7f9c02a2d1e3fc5700000000000000000000000000000000095e1315b3568e8a069dee00c3676d5d6ad94a2164795ca5f1418cff4a25052e741530c0df6d50c5cbcdd55a084227f3000000000000000000000000000000001993b036a3225289827691296b51ea4e42735af0506b317932b6719a381a59c89871a2a394f4a9de0aba3bb9a2b881f86ce7aa7dcd01c1b7059ad3cc0ebf5d19ceaae633160a968c33aac5dc6adb94280000000000000000000000000000000010aad99bc8570d83847a2a2688fa61d5d0ecc978ae842715a084d99392db343f581290478bc1bfeb8bb692e0d6fd58ec0000000000000000000000000000000004f82c0527d3e9329a6b460f1d781f881073b87711771699e9cc8c4229d5112d91d4357380c12c120313d2c9eb7bb427854bce63dcdc0cf408b43690abbbbdacda5f3ebd9d9e462f89f9f50a9f7bd44b0000000000000000000000000000000008ec7244587110fd3fa0e1888427fbb3942d0885e002e4f846fb749bfc4a82bd7edd15cf81af454354006a2ea85234f6000000000000000000000000000000000fc7a19df5adfb5a154f32b9022e54b1560237f4319160c9c945b7bf4b55e45fc86616d3ec3cecc177c9f6bc54dd2cdb7603824b834a83c1c408243b51cd2c2d31e2ee763d69e2ad6d369bb6aa2396fd00000000000000000000000000000000037ab89247516909dceeb59abb90d6968ddc3ef3abffac93c68757f3c9309d145cf9350e4d8f85db810cc5f156f8f126000000000000000000000000000000000289168c6dfdc25ea10e1839e10ddffbb25522be7ff80ef321241c6cc887fc7a42586dd9c1686c6c5c2e4caff0278155923c86e91c48582f19409b962be361da5936db02b6862eefc288f9a32d5f5476000000000000000000000000000000000523020b4c34e867e75cdc668e541cfa25f2afc35573b2db083987fc585a487f1eafbac1c4267d2fdfdc5d2f94c51a84000000000000000000000000000000001581bf2744d78d680c9bb38a3f0fee76b6f0231f011b3f7ab3fd59c1ec6c99fac518857dafd410bce2e8610c6e5efbb1e1b3071b561a80aaaadb5cc24b348a2b6012340d3aebcca7e2f56983a8a13bf9000000000000000000000000000000000615745e737980a923e87c3ef72330f55e38434b3974c1cc997a9d1136527de9bc21dfa73ea0d33d27324a53f12bf6f9000000000000000000000000000000001164b6ac376ef24ce3cba8e2ae74eb58437bbbedf68b4d0b6e8b7e213a789c8c3b7f173bbe52150faed93fa83bce0a9db6863b755d3dee61328a60f585531c436663bbeab9afaffac49b6f0b57614eaa", "Expected": "0000000000000000000000000000000016e6cb1f899ee8f3db4b934c1facb3928b08fabdce74f569a06ae6eeab201925f6acb1a47ffef3c608fed32c949786a7000000000000000000000000000000001796fe817d2e4a69b4e8c539f6f2179a802cb02caaeedcdb316b3ec6571c13c349e115a7a05b296d6b182c8a618ed918", "Name": "matter_g1_multiexp_78", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cd7cca90c8742e7f541981a13b177a4e639195af5f15cee2ce37b01d50fb8478a3f0d0abe4312a4d92a201b4dbb030e0000000000000000000000000000000018e2a69bd1cd9bb7ea75ceedf28ac9c9514e8d28223af69dc991e46a03d8d272d267842f30552583a1f08a07188058ce13ca0cfc742607bee58988df361d7cd5d809ba4fddb209c898cd555369fff5660000000000000000000000000000000011cbbf1ee7e9cf8deae286ba67ab0eeddabd2471d2ea15e86c77c4f2f23ce38e17ac3f3e3c2a40a1640bb3485be4e59600000000000000000000000000000000108e9f887f86f03dcbd515501f69a5983b4a6d707c26b69cb9ea7a387c5a914612ef645cbe81bf29ba91d209e839c72abcca8ab454fbc576a2b910f140b23c23b14301c19e1f47989d78eeecf279862a0000000000000000000000000000000015c1856c661396f8e3a477932e1eea7e124b2e9ae0dfb1df67c4b3928c462cfbb3220c4c2fbd755fb6435e144a2b937e0000000000000000000000000000000011b114659fa71c3ac2412d5c2cc1e184f05a45871e5ab08fbe5eff68ef9e457c4f3e2bb4f16d10e91f7ee2231bc3266359f82ceeb6160d3256228d7a41fb3caa6f305b23142ab979e728356a13309e27000000000000000000000000000000000b693c93d4f06be5bc8a84157c6f407c3db14175c56310e7d041118ec869f3992f75809b209f6dd01085991deaae2a96000000000000000000000000000000000ee21d90cc3825b401e6d452e27814672d849386eccec7be992581b1fb9f4ff4f3892d63e124bd669603e6269f099452995f7d2038ad02deddca34399e5b5653fa471d998c52bd52241840cdb9202b2c00000000000000000000000000000000013b40cfe91492dc53089325be73b5d404288e8056e30cfe4bf3feb6b854eb7d0efa3ac4afa822162ac16608555ccc92000000000000000000000000000000000576146711dfa2ee08bf08121c30fe63ef0ca4448b28076eaba9298ab925c615a56d497044be803f73e9586763aad52497b67e68bfe2d7fc256e6aa610dd91dc1b02c64186d24702ad8fa9f715b582a50000000000000000000000000000000009d66d52069b0d23faa33818a8c9bfc812ae6938dd02604e98a422f50c085a5641a46272dc9c8801a9c76cdfc2020a0c0000000000000000000000000000000004dba0f971336c813933bc6386e55044f5e3d3e5cf38ede5811b4e775fb41cd09d7f136d9de6fc36f2f435b8cdfdc26198115b9f84e3ed6947bd6f0e3c65361cf360a65bc059515da852a72ec5cd17810000000000000000000000000000000005ae8fd5c52fff0b80a2c5c4fca4bccad28f580c94edb7e28ca2ce2390cc2fe476a2b11f63c3c8759847e647d5fe5d1f000000000000000000000000000000000edbff5012f6efde3a9bcad65c805b1c4ac0899fbba5fd760513c673ce8ad18d3baf28acb3344f511fd4d9785afea33c27370e1037b709015e0bf178a41ac55774a813368e11ef7a764eb48abe75dbf50000000000000000000000000000000009d003d4213a46812ea1565bd9a6f0f3da1e69e289f026e619911354cd7444dfbfff1d842e3d9c61c305b2154851b29500000000000000000000000000000000070a1387dd16f9d8b4306ecfe0e9ba7aaa5959ec917e06da4ddf90c992fc569a56c61f6372bd26e21f5cbe7d720b68c66bf5fb297948e0ddc60ba26e49ef2892ca008e64a22ff2bb21ff70c56112f7100000000000000000000000000000000008fccb033a3e10a0015b11ffe2ed5f4c96ea2262d06ca4b0eabbc15c9b299a5220444345c65e7092501b56599980bd0d00000000000000000000000000000000127583566286e52f2f2c7809cea1170a49993f171c1c217b82c17983e02b7e69cb8c948725c7a613c41f96e80c3f1aa96b488b6b63cb8bf34efeedd9f95dff4d3d8c067c0d807bd1e20bd267748275d000000000000000000000000000000000084501b09915fa13908466d6bd50a7e0d8b39893bfcec9c6876b7ed8effd100b8f0a459d754efb6b110af2becd882cfd000000000000000000000000000000000373669b2a03d3da4e907da24c61f5e7928c5fcef4e6c9ad4303fc4cc2cb641212680f7c33605212de8914caa58732f44f661845e91de1c09f581c7612a25bfa0889f77c2add31b493b37d20bcce110700000000000000000000000000000000010608a9f87f46e528d782ef81493625f9a47134832eecca6471d2113060703750b679e64179e7a1c1c81311c38c493400000000000000000000000000000000032a0c82e42be6203415638e6cca4dc1621f87f030a9d742bc77862f4f10ceb44f1ecd377acec6587be0fdc33d8c17c98b3bf8d5e529912b1b6e445f592a6d151c6f5d01d3b021a31a2669df4ce02aa300000000000000000000000000000000126f62cc3033b7235be5778289fc568a1c474b70cba2d35a0b9fdab5cf239a2d4fb03f0bedfa84425b142c04284da058000000000000000000000000000000000dc1f91754d582f57b413fde9b837cbfe3430582b0964620b02bf854c6f666914157d44a165f16ca1d7204f35caa7b0630e1c8f222019b877e66df0b6201b5bfc5b6c10aae340c55e74410a536ffb9b20000000000000000000000000000000016d277ee7864b3af3102190cc99db1cff9fd1b1d6e7fc039040149c5944e7837895532ae41b4db50e29a5d6bad7ceb630000000000000000000000000000000016c3f6e29114782c84734cb927d1a89b7755c3a8fbc99076ce3ae17f7f1d088e5fb9757237773fd4e14c2855ec12b93723a258d66f2296fa1c71065cf23c994eb8c6c35d35120d16790fec791ad215fe000000000000000000000000000000000dc8f59e410ef7145d636d2c7d43fc4b1c903d6c8c0efc3ae162293c7c65c48182f9a25c4e5f111635881533cc558cf7000000000000000000000000000000000082dcb0872d815465131953c69e260e3a9ae44d16975f361b5effe13ab1d61c18f050108e73f50871221faf28fd79771ef4055b85f37b548dac2b64608d99ca293548bebe1e24355393520c34eda60a0000000000000000000000000000000002536653a945e03329279f382937d72bddd71ff8f19053e1fb19ef83d9751eaf101676249ac65fc61a0cbacbfca3cfac000000000000000000000000000000000806ebe4d62e62904ead05f814dfa6e8a392b887bab4aee61552c6f93ea5ffec6593e9078a33f4cefc96393a667c934c212529248c51c95b5b26961f27e6d44ef1c2b9233bb2ed32c3eee79ca6c6eb750000000000000000000000000000000018fe7f7093e0313737b8e0c6ba2fb0c93afe1e8241bc769f14cebbfdb4c73aa578fe3d37ce1221f21aca8af9ab99201c000000000000000000000000000000000ea0f2ff4c8ed0a51fc8fedaa056a369c5e97e347c6883b215d0f7e019960c0178a7962415c220766c16f4596d4b9d8ce9888dd839d9b8c236394c44d358f452a4588ae65d24ffe2bd345fc745de9d37", "Expected": "00000000000000000000000000000000184197d1ebcdaa25c041e95424bb891fc9eb38160cb0d91e702ac283280c6df697ae85674eccbd0fb130b6f2e1c193b00000000000000000000000000000000015593ed27279ca601616dfcdc493b8c7bd68260f97f8a9f10c03cf871b17cf8f492518d2f8569d60056721723a0172dc", "Name": "matter_g1_multiexp_79", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018c31653abd67897b3bf8f046712b12d35ada1799d1c18071182fb61273b7bc506779ff2d774576a725f2f1035431c82000000000000000000000000000000000011b2fab972f183c75df3bfb7968dcdfeed0755f71ec118e56c61203e97064355200c5f016b9ed66040fc886062dc58f812322dc2a7d5faa9e4877638faf8492d84e0f4c4c65ca3aadcb7eafed2106400000000000000000000000000000000030d7e368c99113318a6657deb3c89424b9acbc5e3568e03dbf629333ed3a5cb45ce6988a3e5ef79e5ee91aa6b990b1d0000000000000000000000000000000002700af33eedebc8a4847d6772cf615413149e6d98ba3b36c96e43c8d97619cb01117570f263bb2f7579c7da67f40a25c1f6d538c5b4ae15c84581f8fd4c61160ed395816557fde197e1a013ba41ba0f0000000000000000000000000000000008cbea0d07e870d679cd20b4ad088bf3c5c23e83266b20e816f69bb918824c9bb4d0b3216f8da5a5cdc6f43359e02d06000000000000000000000000000000000d1c9949921e37e73f95b0e4c444e390bb71fef0d893d1b341b9338321bff4a23d1da4ffdd5d7148fa9fe9cc52ebbfa8f2f6a4713eb692f7667fba2a3dc35363c3ba163519d95757daddefae11a958530000000000000000000000000000000003111c080876670db10abfc439b17b32f9e96758b057d3344c7823af1b0320037906b1a9d8fc42cab9e9e0e8449aa997000000000000000000000000000000000e0c7d19a0362a173b70b6fee3d3feb541c7d2ccca71f1f01f8bd105a18024fab05e0a6d448153139f2777b189ba0fe41022e50c3fe7b2a65aab79de6d9e47c457d197e145592dd0611b1dc39941513b0000000000000000000000000000000018bcaa4869a5c6ae46e6f5fd5fcf835965d21d48871010245e722bead79d844e96e10558d71e425377f4adacb3f74074000000000000000000000000000000000414d616a4207e7cf79352dbf7f319bf554f043710cbeb48aa502235db7d30f4983b5381269f34ad6ad4fd5ff56d9586b80011c7a4aa905d4db6d4f6ae46eac9eb8bb18613d4ac5e5567990d7e8fdd96000000000000000000000000000000000c86dc8b8f38d1e4281269ca252adde9f0fe933d4cc051c7aad55f96252d1e6f9eb6f4f876e153c11b61714d985d318c0000000000000000000000000000000014113f8e2c3ac4919de334eb5c04c909b88df39998e58883a5393a4d760cb6d07c65eae053a7b2100ff3028a786782bff397789685a736375ead2312874174795586e12b230669a90d072fa636128c7d0000000000000000000000000000000009b4437230d9dae44852d88dba2655070162501702998ea5a035cd88eecb64ad7c9ccaf696545dff98d778cd7400943f000000000000000000000000000000000706b196155640680b257a537c836507d95e6d5cb7f163ca340dc0f8b80859721b7b2a2ba51dd4d72ccc4c3cb91030c928e325fea39d61269c576626984f85ea43cd683b08c3ce111aac0005adda39c50000000000000000000000000000000017bf848757da8e7ce5e5e69574a9b31d35eb628102897922d4c996443fbc970374ebd601b96b3ca9412c13f50943c7590000000000000000000000000000000014741c0b49e4f02630a6cc1a723cae1a6a9862158bdcf996b46a9614dd34527a859db0b5718788eaf2caa059671f3c683cfd9bc41303803a0b4edd121b818a126bece309dfee4133aa5314cb8a91d08d000000000000000000000000000000001269325967fc68b78cee64d0386e1fa6ecaca1f85d672f8b63831a1adfcbdbb40461a77ee0e59b1fcccb7c1d543f08a100000000000000000000000000000000053a22e8c4219e4d68a961c2127201a23443d8fddb02e3756cfdf74e616dd4abe73c4ac498ff5f6a68d730c0050b79e18e08fed30e422868f37c422d1efdcc93912d55b0a731479af863dca4705e0c500000000000000000000000000000000018248505148876ab5a5ec3be7e3a6cbac30798d52f437bea7e966921723e6a4a30a0e53518e109d1683f3a4b3432136e000000000000000000000000000000000120602fd461206973e62ec8a3f1cfedddc1e9f9e1769ac06e2a1024a9af19d402f40ffe30f9cf77b8704497d3cba4a3674ecdf795b48d62f0db0f9cce057fe570d15c78f2eb7a77b66e4895a45804880000000000000000000000000000000009cf2460e5121b15d177b8ad803c045529933d1abf62205d04726b67d64fee85e2008b5098ceddc42d5c8d95d39147600000000000000000000000000000000012749abe2d8b47bd9c899b6726ccc749bab2786e9568d32299f0e659664ba1efe764944c4087c549e2bb717c87c6b876288fc80d07393f629ef2732879332a253b49d26ca7b2bef7cc49ee40530b2b340000000000000000000000000000000008d764f80994fd37a21f6923d7fef255145ea875c892888d45efb7a37310182b04d2c16d4d91a2e7c41164706afdb617000000000000000000000000000000001156c016a289989510f1c8b39bd6a8c358a1c5611bd2286e9f15983f984e89e061e60717f1b700abaed57076e148a8a956e69f4ce8fbd8f86f546fd6d129f9760edce7c5e178dffaf987bf565e9bb7e9000000000000000000000000000000000734cd0d73ef7d79fa501b98b7211d551127abf68c473c1c72c591180b605c938ef71f66c422bf2a8bcf16c6c8946c050000000000000000000000000000000008ded96a9fce61040c1acc71d6496cf72590c63c3514c4f1f77d4582635af9eccdfab2e60749ed24fd3b6e30e3576c58ab40e86212189e6f5925df810141c132eab20c123166cd8d3c6f40f5dcf1b1cd000000000000000000000000000000000df9ecaab534bbe9c8531f813a95a7733df6a4c8785575c5ee89647941a6984cdb5a33d2eced340c683339c18f5da32b0000000000000000000000000000000003632b2377ab368bc9f735609452e0ec9fadd6f261cd5352e0a5ed6a37b25ff7a49fe57452e79e7330661b81d7d80a64b96a5b6129c58113bca713e6905c026c0bfdb6d679c203cbe2b256b0a49ecece0000000000000000000000000000000006bc4871c0271394c9d6099667ff68e1dbfa9980976075bf81fc18f1875fc91b50a0e3be622882c90b1594419da7dbcd00000000000000000000000000000000168e1dfde47d19280dc213bba9fbb61fdce41f81d4b25b2a7abae0404bbd7a413cdd89611966a7f9bc32617dca51f369d9d8147c4453cdeed971242d316e350abead3dd08e93ee54738a4a5aed23affb000000000000000000000000000000000132a2a6832653eac18e2fcb2c336292dc7990fa1a004404973029a227c9871181ffdd88a74adc3edc7a8308dee803fa000000000000000000000000000000000b230c171d5739fed98d32a3b27584bb0128434401e9e05ae09a4dcd7a017d1cefe7a46dad2db5addfb389feb9c846181ba8e52986d3bb0421eb53b18ca8c21b9f7e631f16b99ec56748baeb541b32e5", "Expected": "000000000000000000000000000000000cc6517e655697449988bef516e60c8202fa48c3573967491ea2ff2db9fa0de3f542f656228a5b90d7fc1e5eaa8b06d7000000000000000000000000000000001191ca6ef2791726a31f77b0431ebe170d8fb595cf6e6b9b33b7fb0d4acbecf2d171884c392832d2a91832e982c5c0f4", "Name": "matter_g1_multiexp_80", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000111de2b65f5f94851aee2861910898b74dacf013591772902239ff7f71a9cf84919bc4a84d6936f9552e97314eb52e7d000000000000000000000000000000000db96af045180bd4d88dc8c40f8cd918d2195c2f3651c176c1ee3ccb583a7363e2c2c900f2a54f26a881938cba98565f7d39b55aadd47afa3cd35cb85a89e729ca236ada965b99f64ab302a84952babd0000000000000000000000000000000000e48144181d956ebb37d72c38c062958f73de8944995c7e7568997b04ec19949b348fd80e810632462ce43c7c6571ae000000000000000000000000000000000b4a19556d8c21206c4198059adf5ac2b8a0e08c948a8a4d7465bd31c5ce5887a069df5f80b1df89ab868ca53e16c730c41ece17a6d8b4a22994227b37a9d73e17a88859683afd5d226e113246e70cb10000000000000000000000000000000010547f218e33dd9f9425c8e7be4136e65ee3dc23e0cdfd5f1caa8986162cc13b77d30259b6b9c359ab0faac9ba29bda00000000000000000000000000000000006729e532ba87a77d1e458663690110cf63eea96f8e41a5a338493ff71b68e78e78b9c929006c0410c3739b15ff2810069700dfa3b6e5fba735d1fec3b3adc90719ec301c406ac40673f4e5677da3227000000000000000000000000000000000d3630086b7e0c068c60192be8724ab4d18409fa6ddcbed02b52fa776e84e2115457c40cac7e903047fc435114150d5c000000000000000000000000000000001066ce26d2e940899e80e9c0e515ce9d5810a4048925a7ddfe0cbb24b3d8d654c6835c6872fff5a988f525c648661cbc19e8eed297661c06c92075629e163e80a08835254f7af8c0f179400be114ba7b000000000000000000000000000000000ae73f595bc9d22c8c959eedec4d1301a13c9b8c643f4335160bab4a99886694d112ed6fbfbf082629b76d1e2509ed280000000000000000000000000000000013dc07950689ba36736838714eeb28ff3be77ef8ba181718ea7b5229e01d4e036c98eb9ff7a867c017857c029f7f13e3199ca6fb7f6df8a2e72971c5738ad75d84935e922587acf3a6b6debf3c37bb5e0000000000000000000000000000000016e11b169dc405035037a10180fb368988498b6e209ad62260c7ef45e9bffedbb0587fe282d193bbf88311f3d2880cf500000000000000000000000000000000090a277517ea7a1a7cbd68598aa1e16977cc57c8d095f66a7cd3f67814c2b8f35e17e20d7a26fa67274dc5aecbe778648159c6b98bce6ed31c30957280d8f7820e9376093d1ec9ac68ce0777d02b084b0000000000000000000000000000000002ea8cba4bcbaeed7feaac63caf21645ddc97daf9250ae29994fd04e798f94dab33bac6e08eef8e6c20f122bc5f88996000000000000000000000000000000000f7a0f6ac02bc9821a883393c8265ba748f9d7c3ea763037bde3bb0178067e93aea4dc70d25e5bcda642d06f41a7f18bef1bc580e0b52b10b049f07d5115a60ba96d14a39e48ddee3c219f11c3b2a82a000000000000000000000000000000001618ee9c413dcf713699b7910989c20bffc5ba1ca03e973005f49084aba558797e7f9ec20cb86f308d737b97c08f42a6000000000000000000000000000000000db1daa5ed21250c696ca4da3e82f6623c54d643d773286811e21c09e9ef7c9ecb9d84d90b9c76ea9f65e04a29f82750d06f6ed682c56611fd060ed2b3b1dc48974769ed6dc504ca3e0b9f68b77e63c50000000000000000000000000000000012aece7d9e7384ae79e047ca4b4fe72fe541a825530d6c38b9a8fbbf8b801883ccbc3cae7c33e4d811198a7b7876c92d0000000000000000000000000000000013fb42fb1b4e7785c1b66364de150d1e38fd9fe3d8f209b7c168beacf4b26c35fe0fbb4a41f30adabe4314b20b16319561d7b314ae9d9e78f628ec5a207d12e2dcb690688d256fe46e0affdfcc9775ae00000000000000000000000000000000033fce20f9202b89411dbeea59a5b1c632435eaf29e2739163b0837ef9278ee3903ae569931e70f79a9af5a2abd29749000000000000000000000000000000000a50360c73c3f735f97d7d71b21b2831f7d7fb59c594e85b604dbb79ccc884349cba8eab9ce613ed60416994322916db03a0c47621401fc20d2c78f7e30814de9a6f838d4328a5b5be628b833c31a6fd0000000000000000000000000000000014d9a7dbc453effa7a76c774a289957b0ccd72994e568c0de345b482ed2b6db9a3a3e56e0fda159c25acb43b4a6765d5000000000000000000000000000000000b916f28e3fdc62d296e421b1684efd4e9a4b523f79dfaecc00872a1d17724e1e07e2386b4bc6d76b157ae94559d0bcde4ac6a5e740e073c5ef8af389e70c2cb8ee8c4c04c2ab4c48c579e83e181005b0000000000000000000000000000000012a4670c5c2847bb188464dafe41360f00621ceb3b5da0a3dcc16732f4baeb0491664ed8c2f95ff9b44e2b77e698eb3800000000000000000000000000000000077b561ed2fe5c91b30a12a2df71e76cc4ac882301d1975c3cb176e22874e28868655db9d0c91003442b0277eff52669c1e20d8003fec60f68c03942185fed934ebc197c2863174442d1a1c8d1424d31000000000000000000000000000000000570e1a0fe7f82c0d3cf38d90f77634f8dc2bf9b58ac473d9bcbe7242a4bb76d11f36083c90588a680004c077e957a9e00000000000000000000000000000000038ac2b58a16af0a3a0070faabe3969025440d9781e3ebc22ff873dab532d6ca1b0bbf21f32eb9728a322c158f5390fa7713ea72a2ee99442232472ab3dea9307a02fa1279129d994af5588af4fe7af40000000000000000000000000000000004a3a287fe4401c48d7dc804363941b5836cfad6490b00dcb0ee830e876fa05a42d6e2b036a4e213bbf5b6ae5a4e31ee000000000000000000000000000000001877a91254211b2af54ea910d9efdf4b4e829fda5bf6b0c2dc849903c357bfc6f55b45c7437ba538ab6cc795b71e95796f128420cf6ab4616a05b287191105f25c7212f2c39c3230fa56bc27cd06ebfd00000000000000000000000000000000159bf4b0dc89cfc9d1687d8552489b5c3e2ed059164197028bc67c51ad18b341d04e4b8be660880a76a44ef11e785ab5000000000000000000000000000000001643a41fe4104ab0bb96200472ca67064635bb728e6d909fc0026216a90083eb612f11bd5983cf4d7fe664f1c527b96a12bacb3419c34369dbfd1c968334f76bc50885028758a975cc812a04e6feabd60000000000000000000000000000000003dc904709f1da618b6a623888015a875b11e5baa5c10eb6d750354c09359b180858bf29d24bae18e7c78c81465659aa000000000000000000000000000000000c61dabb7085a1937782433ec46b0a063a34e102ae9a6b6bae7d82c94e93c3cd05afe19f0673f729761462bcd0d9ca5e5b00f26af6f59620c7130a6d12cf2091b5f52a6b638484fc1f242dc1773be256", "Expected": "00000000000000000000000000000000109dbdd05f92274f3edb0232b827a4abbe115bd4d51f8a1e7b8ee609511125ecf35ca60991e75a0b7973c4085b7d4bca000000000000000000000000000000000e14a168decb6893e9c447b4366247d997701471a33bf8f762bde44473d516d857d1825255d8b4cee8d04736cb369758", "Name": "matter_g1_multiexp_81", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009b85ef81b184c6383ff4e2695a8c261ab252ebd81bdb518001f110b2ba72fbf5014214f816c9453319934d8a010aa0d0000000000000000000000000000000013ce486b15a77cede98a46f66ae51d17713bef6dafbb2ff34c8f441271d52f4fa27fb88c5695f4af6d43e32333e68130acc5a8ec806f2f273120457865582b08697904a2c6510bfe9ea21eaf682fa4fd0000000000000000000000000000000006a10f5973fd2aa312ce8f30ba5caad0ae6028bca5c186e4fd55ff4e3f5ce00220b94683e440b09a9fcee238af140699000000000000000000000000000000000ae8e9db6953ce2461bac3be78bebf6c4df8bc57bc7de375aa652d793bdb0899477464097514f0fe2d0badc9027baf3898c15a259b4dbb8c300a39f0af558a9827112f6b4c5eae3d43bbfe057eb113cf000000000000000000000000000000000c0c430ee1e9112d901b82e43a25ce4e5b61c81ed7ac7220d88bd10d44d28c1bd20fc8e1ad85f9b6eb43fc232594b4f1000000000000000000000000000000001233dee860032e2f9a67d7b3d61cea99f18b91620b76f8bd178295ac4fc3b8d0db4c4ff602085c7a897435a283e2a4eda0e68bdc97fd642581f7e62ecf134df2c05570713c96fa733d3db96ace88f0f000000000000000000000000000000000061e9d3a919bdbdc42500b7daec837506bf0841caf35aaac34a3670517a59bf52343b47b46e8212208cd6fdca6b7140c000000000000000000000000000000000b87f7efb446cdba6e619d5fc04ca8dce8e57f6a76faa4a773c03ddc0666ce2d83682f24d8463d9331ae58e8afcc5641e5512cac411cd103fcd7497fdf47d1221999bcecdba30467f06ec356483484fe000000000000000000000000000000001606311f79e836a03da5cacc4e1c3930695372f8f679c8f910627f86af15d1612d653c76d88b9d33f848f94bb63fa1ce000000000000000000000000000000000075b5d9626107a486079315a85991f3d77461b45e5c8aca6876287f624694c8ef1a4f5f0a5b65eefa8d6a4746fd2e5fa32f6861298bcfd4668653544b4551d7357d64f733365a5f08ebf297a09fd4ca0000000000000000000000000000000012bc152cb7df01fd9ca35142806664fdbacb881adcf443051abac7c979d09a1c887fcfb8cad281f376ea3f6693812914000000000000000000000000000000000e32d4d6aa1f5046382c1d5e6e2f97319e8c6887b850b3cee498c482e35319a4f062be80f7f48ff3d1160ea6b18cf67824301fc5c3ab842d7f6a278fcd32249f1daf86a31dd254ab9a21941fffca98a1000000000000000000000000000000001599c2c489535375270f0d1f370c6416c83c4043dbdb4999256f187e29c198b1f6c5bd1a52c997f01ebd3622c40feb63000000000000000000000000000000000b60ea3ee221eeac4a8a364eb52ee08579cf5a907aa5642971bd5523dee5dc6d6584ab993d33d9b8ad9de4a1a4f0cbb117a920aef58100de67c482ae1fabf7ec87cf3447bde1e19d9aaff82569570674000000000000000000000000000000000b85c776ed6c9c78001ec7bf3412be495f40b0978d0582ad4f86ed54464fe562f9e699f727f36b2fc753f4328f0b2c6b0000000000000000000000000000000006e11a826fb4a8f0ac32f5c52a531508ad1363bf9b09919ccdb61ef25baa7718a4829fdd10fb6b680321cb7ef12d0c01d76d5eebc3d099448ce4a8ea6dec047b0f062c6361ddb9e95ec898442423a3180000000000000000000000000000000013539f96257faa2ae642c15f9c04e8fa7b2d6d095f7ca285e0dd90f022ec4a8fd74cf48557afdb57bace088b017b8ec20000000000000000000000000000000006cbc3e4291f373ee280eaface275e0334e46e54f65efc4e18b4ebb8ed1e61941d9c859903b56ed0d4aa3f4f3152b5b4cd4cc1453dec7ae335db989886fc0964ee73e12bab69ce1f1458d1416471176a000000000000000000000000000000000675b4dab12db428a14afd8e696a64c0bb352bbcbecdcf2b064428b489194112f1cea4a383788e0bb0e97b7f88b817700000000000000000000000000000000013273075195b02abac630211c5870727a42e11bd96a2e2c6057d0c96bb60b73db72dec3135122865cd520c525588664a6d207c08e51d64a9a47f5353faac77fbb184e1123d38e39bbada85534cbcd3150000000000000000000000000000000000cb4629e659d5c2d91c5f909bbeb3381271ebde4f8486f76c1903e86efa78da06af752404ebddb3fc5d1a09ed28b3aa0000000000000000000000000000000019202a57e95d8d2623851973c324d1ed64b48b15388e052761493b1cdd6f3b54c6f47d2b312edec23e9da4c815f02e172e1910b704d39b6a64cc7a44e44ba3e8b7e64ddfa90dfa6b5ef571f9ff7d7f0b000000000000000000000000000000000a80bc4a39d62ca891044795e2b78f4eb82a3bf38c4ccb2e6d24ced4526db7c57ebf8b1951af0707af5ae5929f727c290000000000000000000000000000000001cbe991b082e840d8bd505a2eeeadf034f8f8c2bb530c742d7953089da1447e090d82399bc332127f14f1521c95f0042eda0eb154d5f9b0e25a828c6f77541701004cd0293c61ae4d36aa3038d0f18400000000000000000000000000000000112e7894d90a5cba2a8bdd0fa750d6e57c0a9938ca30526eb5289b4a59f92bddb33f59ca22a51d1bae03b850999180fa0000000000000000000000000000000016cf6b093a188ccbf1a000aa860fc794546ab0cf261784e7b7bc5750848f685d629ba55f71f2266edcf24d27667d2720caf6dcd51a851eb200c7f5fc3e106ac5ffc432f756b942b1b9a5dde31cb2a3760000000000000000000000000000000005e2b8ac9124e8ccb6665842d77a2e9398e5b3519fa4fddfc4b10acb5eefceceb1cd6cc733e300ff95ea80d09e3bbeba000000000000000000000000000000001273d1990fa922276859d3921bbd49a452c821a9746c747734692d12c6f7d45533c0a7692d1a2d95e2d2be6dbfb3f6ad106d4a893a68b7fcb8be96faedef65181c239dc2cd752c85ae7800ca84fc2dfd000000000000000000000000000000000dd2c7410b5f5ee63ad2a9ff3a96df2bad103caabe00a9892cc9b2ed2cc3bbbb53724b2ab63cabc44da7097b619f34c3000000000000000000000000000000000f695edd4b67f81f09fa89104c81717577cdd16db30901f4f04ac97e2e0749a80d34422bdfa85b5cdb65c042d90515742b9e1cfbf140f4a3b1d06be656ad6ee5169a9cfa7cbe6efbf8173843d406acd300000000000000000000000000000000113c8f77a2409e0c7ad34186119833605f924545821895a283ec83bb6cc38c549a356b205c24f65be66fa627a378eae30000000000000000000000000000000013038ad87e3b3eb6545a0b5f7eec060895deafaf509ff6687024ada75f700d466df86ae5f95463c05f19750c0ce6cf56dbc68f77d40330ad5b8cfcda42edf57899454571c6c6465c4107e662a269aeb5", "Expected": "0000000000000000000000000000000015a7b2803cd9b078d457d3b7c62a2418f19c0cfa006739cf3878844c9e1ea115fa982a02fa6fa0cef74404bcf145952f0000000000000000000000000000000018ea40f019b9226cb0428356483f842ad73140a8da065889d81e35a564e99aacc5d5d833d35fd15713ec76c65f9d3307", "Name": "matter_g1_multiexp_82", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000163b380ea90b97146aa11c64b34de710e41b2ad54036a1a98659046f0e051e5961f30ea5ad78d8052f4a5d2a8388c28d0000000000000000000000000000000012afed5aa2e8c75e437fd796067e0c610a8a4c2f3368752413e6f179bbd4db25b18d5b3f8502186259a6368dd4321148ebb3c942d3a1a15cee806fdb0fc3635483743a5b0ee9c40a48700bad5da53ae70000000000000000000000000000000001bd4abe425f0418c86716516075a3ad09812650908cf383ec1396cbb6929bbc791f5cf65dbd95b51690b58ae3cab3f20000000000000000000000000000000008264362c7fa8021dec396c8355197ce4ef70e7b8894fe23d881d34b9a1b883cba1eba0e54d928b4eaa27aabde0df9b3c193d751c4f24f4808621979f07f03b2eabba75f08bb49682b9df2da7a85a77300000000000000000000000000000000032112872b64559a03629b7ec8b32344b7d5f044670f6099d8e8b1a1d47223f9a42a072975c821d03b30d0994d782d830000000000000000000000000000000016042f6baa48d7c571e1f6c7cf3c7a0887bc4e2b2de51bae133d266dcad23c579e03d3284c09c83a54eff7f2151ce5b3dee4eef524f133183b4af95e4445f3ee5084b96c32e284ebebc5b87f3d76150b00000000000000000000000000000000028ea1499ad8761d908d863849ab4bbc155edeb03a7ef4bb93e96e25ab11c6dd0c21a6f06537a688189f08a00aa33171000000000000000000000000000000000ca3ee57dbe627ae681b12e0de4ed602bc3c09558444f38b0dee27320708549491a4482f7f101e8a722ef85e3fd742a5da514f21c8eab0edb2405e673297bb595edc21027890ad680f1663fd960ce4780000000000000000000000000000000018f397d7c84b8125844e874ea31d18b8705a75027d5324390e2eb7c9962d9de07add34a436db21a34fa7fc7898ef04aa000000000000000000000000000000001591f2cbc58c0841e5eeb8d9c75d8dfa0f2dc5e479d136905abb772a6170d131c0f2c9e8e55ffa215a4bd732c2fd85556aeac9a669c962817c01069cffbd948d9d8ce764e92859f31fdaf85f5aefab7700000000000000000000000000000000135452f0f8d4559ba041dbd2ac45f15416070b1674c9d8094556a289716814d2a4efe14857aaccb82c5ada5d6f0d15ca000000000000000000000000000000000f1c47592319db60db724c9d0649d0d713320be7dcc28e7318517ef80a3fda71fd1f4b722633ed7ab7df06218ee593e940273bda92c9b1b677edd905d76d75875e5b77841befb2bcaf1fca7674dffd5a00000000000000000000000000000000003c75767678539abf7a62dcad5f90a3b4a54354fa70206e789a1f9b5daeb5fb6d9aa222476c68cf9db8a0789d7ad43d00000000000000000000000000000000139bcede61bcead99ef0d9554ee1c19db1869fe041671c199246824a923f5fd94e1da04fa17ec921bf6e82b14f126702b77e16276f9464fa2063230d6c1a4152553536c610062f18565c030e80b5cb5400000000000000000000000000000000020aadb198678aab5a71cd6dc33bd64c47be6d080d24f2f1bab7239808c10867ddcec65e27977b9eabef64455cac25e800000000000000000000000000000000141e58a9f8c9bd92d2de58bf3bbe77a48fae9290815915d7980f4835d805486d678ceee9676ab4fdca51d0fff411ab1b0be15b654ce22ae4e32987babc4863ffe2bd8a459d0f01f68fe84a75326889900000000000000000000000000000000017abf5f132e8e466d2cae445d75978645c3b24284e1b7df7773c256ffc342d1484976ea1046aeb5307f735a69e2fd20a00000000000000000000000000000000087ce2fc44b9ed797f29c352393a8ea109281514490fbc7dc489acb55753fd5c577c4af0ca6c267c83408cd95b355e26c8f1fe94bce21966427380b6d357a3599e9db03a7694159335ffba26fe29e4650000000000000000000000000000000000b106b2b94858155849ec36741c7fef4d97ac704baa6752e8230e172da7208b7e9f187ef0a6cf054d00f2cac99235b8000000000000000000000000000000000d94c6e2349941a20884b9c2d702237c5b5ca2ed277bfc79e53452f1cd6f9f49360215d20fa06df238a7ad4ea253c93ec6d34471ed00035a484f97f4e8123d40ca23b017b94df65540a5551b905e57b30000000000000000000000000000000019b33665a81d0ceecd43f003eb34e1292945da1361adf118f36aa5acb71bd821a6732758a4aa6988e29d4cb70004df45000000000000000000000000000000000f3a244e578c66a9263f020e2f6ce49dd655c7e40a992c44cee40e1c874588e464f6254ba644e46adf348a26025d6d3ef3abd467168bf5e57f71017b5779bdd400dbf416f34f105fe747ea2f8cf4a2100000000000000000000000000000000015618db18e00670281adb20c975f4774aaf169a653d5f583ff6966113fa773075db78507847586fcae82d6a468302706000000000000000000000000000000000301b18d0fe7d0db7793c62b3da072f4cc2fc3425583537110306e31cf63b228cb8c285029044c7b9439c1227d4c7ace2809801eb18d38a61ef8a80f13086d6b1f85ba751cdb8d17fbb9ad5f8d0f835c00000000000000000000000000000000053001a82260b26e34e05a203c8233095da1da58c5f804da9cd6cffce07170e39044394f379173e1340da055066d320f000000000000000000000000000000000bfa2bc7fa0476eeffae4df98bd814db751eeac1dc67205c7629c9921928b55c70c2abe242728bc078bc2685690a38503521c9cf035b094d754db994fce3161842a9509ec8288699680c0ac7761eac680000000000000000000000000000000019a7f78102671f6d84ece4a5bdc54e59cbeab60a8c6c15a708e0169f42a52e98bbc1f8ff52f34959befc859d308fea250000000000000000000000000000000016b5d76caac944612d1dc687c6dbaf10ba60a12b491b17b6c1c876a5dff933c4bd9c6f923e2ca4cd1dab38fb06dfab6a9c8c2998d141b9cd3a82507b6dd97e8d32e9e759169c575eb484e9a1559427da0000000000000000000000000000000007741d8f72a5ddeea2fe82fbce4b3d0aae61e1ab9243ae6a3200711051ac74f30a4dadb597130fd8389353c230b6b7d3000000000000000000000000000000001809f1cc2fc23be0f05b3d12e6891a6aacea121e6db77400638031065d75c7b3fd9a02ded481eb3893b2449aadcf53d6dc83c1ea9e4f4fc12a7190e6c71c4f35d1a676d39e30fe688a05820dd98966400000000000000000000000000000000013d9fdf041ecc7f2c728fefbd6e9da3169d872406b6fa77a52e342fa8852358b02bb2ae7ac77f83e2b25f0120603d0e7000000000000000000000000000000000101ae8e945d31a98c4dc3ba0e01592285c0c92721372bee6b138d9148883970708ad5e585a1b81d82ab0656a3b03a2c00be1b9098f1873ce155a66899877c7b48ddda363ae1d2353cb3816f1ab15ef0", "Expected": "00000000000000000000000000000000193115466c33711b07826d2a021792b7c238ae67e3bcba00b24026503d818f912c5635f85e85402e3a6b2a8152027afc00000000000000000000000000000000157fcd63d3a0e48e25ca0196b7ade453fcefea33f09123434f418cd1d65bba65a789e4c7d6ddc92d4fe8aaf6bffb1ef8", "Name": "matter_g1_multiexp_83", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019f625f232faeac09266c2c4881f92c980db551ea236dc1250189c1e71dbeb151cf74e43b4d5f465c6ad92d75457d10500000000000000000000000000000000175ceb7cef0f8144fd4dd82428bade99833023125d34fb296f198673f4848bbbee343f2f2137b55b5f8c5f74032c1ccaa9cbdaa0ddbf854861eac6621255b2102e5343666c735d0384049d5680d105d4000000000000000000000000000000001353a419548d05e568f36adf72d40ba8b30be9a78732660331a5196b0f81b52330ed70e5c635acfa9ffbf083e46c8ea40000000000000000000000000000000013ca17c0dba35a747bcd314d87d1c6558e9f569955aba3d958cc5736db78d16132c9dc8f93d5eaea749a0452c13139da92073d958260a55b70b580f3ee27c42553b5b858b66f6928fe74b4de91c34bda0000000000000000000000000000000019a1bdc1f5a43fe746df46a7559bfa0bc5292f574fc424b134fb8b2d971e191b3c5d222d39515dd145819d56d5379d12000000000000000000000000000000000a08d0b7c7f5d71222e984bf574cdb7de76a7b3c61ab5a3ec202b295c62366dd958ffd5bb5a5c6c84584342bc76199c62117f11d78dfead915a94f11fa7e904a96204ddf1835d3501639b83cd5f716f50000000000000000000000000000000000f2c85f34994643712207fc431219b925f4e701732fce95bfb387ac26ff95c9b10408d24aae5005e437bbae924816b2000000000000000000000000000000000d4377368df00dcde448d8399ceb7508a8fa1c17e9d9a5e09c4fd7c09c253529c07068e4484c7e7c6d3ed6fd3ca777fd9087caa1e89e48f05bad1d720477199410941a6105f911d589e1f94a851e0715000000000000000000000000000000000d1483ef230a2ce75a59e07f83091291d2524b5d043db8d5583914a6775ce2c80368d9441aa2dd53061a8d9121a025ac0000000000000000000000000000000019100e75a72e07391db9574b3fc4aa1c669436fa802a1a5d71146c5f4b7fe118a5ee71a9df50ff67633f161fd151b947255603b470c056b3dfb3acae0dd45bcb3d014765a5181760336deeabff3f00be0000000000000000000000000000000003a88ed50b36d92aa4411afd0a340497962c7740d629edabd505d6023ecb8f9daf0e5bd8ab9dca26ed2ae3ecdfd98b680000000000000000000000000000000013d9d64ab16ce9401988db4855b26b994da09481a339c2a2597401adb72c80718a4df242776f09ed208a8f34ef7f67e6e0eab0e2486316956291feb44de6389b20f8bafe9cc890d86d27a598bab0f3c40000000000000000000000000000000013b16751ff7f6af64c06f9ae6f59e1eb6c3ac76355e6192e6eb44bd1a9f866705eadf0d2907e2458462ad731523bd340000000000000000000000000000000000ae691a4fbf3d0fc72c0e14d4b31fc19c52ca07a81db0ba93949c56a9b75433257d784f7bf0611259dba8af77403f536fb9436456262e5149d02b33a1078e198bbb681699b3f485625784df444bfff670000000000000000000000000000000008ea61aba918d691a0d04582e1f48d671df39bc7de29a6ecc17b31a32d485fb1dbf499e01a9aae5ea21be5d6ff9808de000000000000000000000000000000000f7e8863a541be553b36b8424ba6ad057986a9f78454aea770449a23de70fea8eee6bf8aa30e96e90df9a373917452f70e2724d3501e3d79b85266fd83a2a6156eeb48e749a61676a1c92ab9bdd6b8990000000000000000000000000000000010d41968ddccbb34b3faee226750e99301ac068d8e6f13e72962b53fa2d019da108af82bdadb3cfeecfb85f53607400b000000000000000000000000000000000a90e50ac4e0c39f579a19d49e6f64de6bdd5d6a3f9a91ab654f5be01b258af8709ce1c5a994501177d1c70b25e474a9a49344fe6ea9274a103f323f3d9381e91ae48233dd579944e12afdeaf854000f000000000000000000000000000000000e85db21593e8d3d86df87ceeea7d7853758d69e15edd53fd7da52f0328805db785aa9aa5db25417d76d796200a37d1d0000000000000000000000000000000015d76c5317e1c8cc5a58a0cf0700ff73d92e7f60f4094030716bb8c657d5c75262825fc0683a88278018b4899a1c1ffeb44aeaf3ba8b03e7ef7201415de7365365b828f2c1a38d09153e51432d35b9a70000000000000000000000000000000014c9d6aa24bb34080b9a99d31e1bb431e911b2ccda3c8dae9c2c2114abca597b3849c5b3dca756d0f9ff97616c0b724600000000000000000000000000000000050224129c08fbb2f2d16596f83e2d09a09526851c4d52e8d5f0afdae7001af0006edce648efe7d94b6712d012817ff753961d33104649cbfccecc7eaf33b7a2a486c77dca363ffc9fbc9ce4e8c1adff000000000000000000000000000000000da4574f20849e04bafbc41bd361e8f4411815b9e7c2fdaa9a3ee70d4f608f89166dbe9e1cf4ff0fc9ae98f27e115c24000000000000000000000000000000001463727b23e6afc17101cca45de7d08b78358605c7b1ca089fc52f6a3c46f590210083103e51a122ed0768be2adeddefa04e97c20b42dc265271740f27f1a833bc5b324bcb843a8f9f8a68231c663d57000000000000000000000000000000001363808474ae9481f54d40fd35ed90c23d4349403d43af0dd603f1db6f5fd5ad8b77d21426977b78f1f5397df17f0bfd000000000000000000000000000000000118560d0cb0eb2fcd3b2d51fb2aa379112b3075e1d4c20757ec241a4877af271700d3412a8fd6f3f5a3dbdf4dc8cdc9b688426bbe9ae054acb6c1fdd4195f8a113727f5617642a5b3c0c65566e2252700000000000000000000000000000000040c13a6f53ca485a578c6f3f49d917b774f7b2d1b15ed3e748a47b0bc0be8a7809f0ccf509f09121fdebcf8af46023b0000000000000000000000000000000014fc7869df366473b2c4adc2c0b12acfffeffaf22b4856bed6ec6d15f0f080596b81f3aceab9360e99f35ee7c43f1e2fcf365a86a8d08db5cd95f239a2f3d22279556975ecc3baae0b774b0323dbb1b600000000000000000000000000000000177b54249c613f044b40a11047778c86f09b20ab387ecb8165c83b36a1af046936623fb00764740a90aa232b7f7ae6bc00000000000000000000000000000000040a52fc58007717d6e1dd8486cfccb1f75827c2feb2b7d59b927c4bd23e5ea80d120875f611bed4b7c12b8a5c929475528715199c9f47fd6337b6b0e807e230b1397885fded024431c70e453f55f365000000000000000000000000000000001918e41c557305934aa72aaa361d15843ca77c747ac16cb4c251a2f0d7c218b60a5588b0e5fb3573e8186a48d725e50f000000000000000000000000000000000cc4fa5302c177f9ef018445ab722e568347f4f970dd893e3227756dde9dc8cce3eb2bbbb4c3cd98af0ed4a45c022cf1c32e8643f38f8177b788b8c2bdc25b668308d914fce35c6f9023a769334a51d1", "Expected": "0000000000000000000000000000000016da14ee1ec80ebf06c0622a500a8eb5a560dfa3439a8e53a19b51c6c4576c31a5486c4c49a8050cc1dc30287f33b5b40000000000000000000000000000000003b04355b2d78266675927706874bb7fa67d441886972a8190a45398942622f09ece67ea74d49bd97827fee82d4a7a37", "Name": "matter_g1_multiexp_84", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e0ae8df03e4d6e36e1c156a35425a3b8189b56e8ce90045d16cfebf7fdd973d207db6391dcd007c311af34f495cfe0c00000000000000000000000000000000198e58d5278b2a82606af16a9af3f023b7182b6b5b2d685fb667714e9fb5c7a3fd5c98dbcc84ee31fcbeaa8f832d7c854f8bfa3d47ed33a05fe3da738797f18ca5d5b8658055de5a9f85bafe6078f7fe0000000000000000000000000000000007a130c85d67f97fd0dc2159d35be8984bfbe94c28d9d96bca8bab844dffd9a6eb3052c619646a4e564c0d47864b31cb000000000000000000000000000000000e2b8362ef5fa5be398a3589413ea69e98b15cdccd203119b79d96405c2c9ae9ca8eecc7533512a25421e1748ec3a1b74b0d302be94d437b8055586aa77ec1fe616e30552b4d7d3471ea219c148be069000000000000000000000000000000000acec379756a1fe9fa72f03da4dfa18de1fad19281f262ff39fec77684f0798b6d8aa895db93dab58165b67a875572cf000000000000000000000000000000000a246df19a23260961ea578a68ab4ae8811f9f391f673eab2b6fdd56dae8ff3b059e5b69052c9216529603e7eaf4ff306765d7f1079b142e513e604d577e7caf82cacae59fb98c6f8990522372dc906f00000000000000000000000000000000001bf749b61d7081f1e6141380deb6a5517d64e8c290363306fa23d6ba3b4e72ef53933f15ae77060758287a5a5c2bd4000000000000000000000000000000001661c564a5bc4dd852f35660d1e7c8193d76a48d1f0f3dff25adf312e28ebe9ce8972366ab224a95a7c1f6146b9f22412eeee02d9309af8c74c78e21836f4e6a7a6df5406617e2b4e9d300e37d8a2bfa000000000000000000000000000000000462a37cc68530a1c45001cda667e1ec10283b826b52986adec03db59a266cafc18ff76a666c9de9fc2384c5e336404b0000000000000000000000000000000010736bad21840f49466d9db82f01a922f4d6ab71f8d8ae246765300531b2f806663da2a8c16c644cf871a877b210b9e3f8449caedd55f0a08825cc1a9e985201c8a7a54d1c4dd96f0ac54214743941810000000000000000000000000000000013ee85b0c8f999c9d0682bf3f18a553b64aed8addf87e4baba55c6ad88de9c9955b82155caa83b8b6b7961d88c16c7dd0000000000000000000000000000000011bbe00b5ddab0b579375e2014021e3bfb1e11b7ccfd774b8679896c0ee34d1d19890fe5cf10e33e3332283b3a3dceaa28ec5f9dc48931da70ba0cfa7251953e24c4c95cd019e00ac6fda095c1302a01000000000000000000000000000000000fc3750c957b3eb656ad552c3997755bf28a54fe4aefafde15619133ae04a47f7c65122c86ef36fedac0c8e0d93c3836000000000000000000000000000000000f7f21014b7a9f07c2212af1b85395ef3072b84ee5e59ae675f6fdb9cac858b6213a264a202e29b45a57c69be5259470dc6046b43e6982f11f39412cbdef14f8e330d37fbe6dfa9ddf3656b86f4f60e7000000000000000000000000000000000d1fdcb6768654b6bc1b4d885039f1649066db8037f212b2d699c02606257388000b0543d25aace7cd1426462ec25c6b000000000000000000000000000000001386eb9bb7d8be5cb9e74a37759458091c44eb814dc3afbdf017a891359831ffcaad85d00d8e100886cb5624562ea0390adf4625ec80149b7810767c985c2aa0187987b3649cab8c59a892404ff2aeb2000000000000000000000000000000000f4d6551f5587cdb4d92e13e3749f977f5bd35b5b71667edd79b5006d4b0943331a0b417f669c6125edc42099bea22be00000000000000000000000000000000041b8ec8547b710bf2c15ff41ea779f996db7996911a5b4ae9f23073e02b2c252592229af738f684e9cdf48aaba0512a345fd17367ecb06b29d764b22dc1e262ba1a339b6f0e0c77384245e3d41cda970000000000000000000000000000000000c4a3756f2affd338f688ee90501f4bf4be43a4549ad8ea6aea69e5a4be015c97ef088da1a39d1103f866f1675f401900000000000000000000000000000000023e5d0bc92794536d59425c4bdf18dc5a208841953e5d45ae91f25d3c61bf66e704a8ca62a574ffefaea854fd23b8d65ce5e62dd15958e6298cdf4a4e899e53644a48494d04fa6d1f73f2dbd645817c0000000000000000000000000000000010129a00ea1c30e98c40a6c86090327d0a9b6c25b488cb0e369bc5a0e0658ec9ac9305e5d1469dd43395f72ef8a0e7e80000000000000000000000000000000006d2f5d4f3f8169f722427dbdee62f45f9791e55988910fefe188d6535fa15e2aab8de5130e81183e6ca25a8009be66f853396021d32530351deec5c266a65519471dce2087485781f33a1423755ef3800000000000000000000000000000000005364313c0d2220ed57bf22cee05b77a53c24c97addae502c7b3275a19522b8ae8167194929770191b96b957b19e5550000000000000000000000000000000016ca50cc1aef3890dd338c8a89b906812ce26e0ef9035d1a026f686b0eecab718f6b0ba401556423ddc99d96dd812d566dfc62eb59bb84b3b6599bf3ce7af229096a8fd5925d4743a5ea386a26c9a6d00000000000000000000000000000000007dc52982caf2f5efa3e1a21e22cb8fc53cd0355f2777272806710a96a22f8e896d001bec053acac6241c7637df158a30000000000000000000000000000000017e9f4fb0adb96150095ad5f0d464549d1489d04c4556576865ed3045e0c477beea3115a6ce63910f797fef29f75bad521d35ee6d29ee4816b91d1664b5957767b4b8066775b37c3b3d08729c949d6e5000000000000000000000000000000000695feaefc8fa22f81bd48a41e6c85acf38fa542e96a7562b8d65834c2f64cf5770ab6731ca85b0c5a80a73622acb83a0000000000000000000000000000000003df65226205511218c263af6fe33a09fa3db22e636da54dd967741657e9da6367fefc5e33a370947f2003dc139765083d283067bac390f556891a531dfacfc4795358229bc9a651c0aa71d601bdd56d000000000000000000000000000000001588a4aaee74856a9d41305023b7eee367648085516c8135fca8c0a6c9cbdecdb2d7b44317286f3a06f92b9eee2470170000000000000000000000000000000005aa06c47bdbcaea82e910b8a2c43c13c23bdfe1897efb2a57d622f5251f0db6293ad21d988c3ee30e33f3a40865fadf873724ba35e4e8b731db36f5067aeafd33f2e966977bd0962fd57cd5ccbfe87b00000000000000000000000000000000140d9a251d355cc6a8ff9fdf2223df59747eed11ad140297b6189a8d49a711ec748447ddcc45733a3c36a48da8cd46880000000000000000000000000000000008ce7046871c0b7f781c667958ff22da6ef5447bd319b2df36c9fae9f5597c020c12c7fbc733cb75ca8f9d9dfd942954cc5934c02b63797010cc8474e90fa5dc88d73dbe5f9be605bf335057fba47ea3", "Expected": "000000000000000000000000000000000f1abe4dabd68ac4443ff50c0ecc5425ad60973dfbd2b29462254ad618b303dda061d80b28117803159ba503214b9ccd000000000000000000000000000000000d3da8a424576cdfc147e18fab66de0d1f93c05c0dcb08d9d5b2a9f5dcda76600b771991bf2d67061ea5b96d20a45c14", "Name": "matter_g1_multiexp_85", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004d4ad5e9acfcabc0b93eb9ea59a778a37d7beca03e285382d10d97803ad63e11aa2e3cd1eabf72383d93528e309c28b000000000000000000000000000000000855cbcccda0476699ad3de8d58b4502f9e61bce8d7db37e9fd26ac4649a4cb831cbb74ecf044ae6014c21148382cca3864a1ee754f6b0a86923e5501d54e6f47d7ab9e1483294ce98be13b7db52937100000000000000000000000000000000156e86fc66a8b684327a4de77c31abaebbaf2ee5f0c4d5f9238c7d4683f08dc78d59fcdc25928d180a6f292bee23a523000000000000000000000000000000000f64634ec7de1fc93959639991df42e7dc621380f4433fd7efeff72ce75f6ac7738396a912f78ecfe70bfc4d0ac4239093064d187f7d21b8b0a7092943de13b96c2e1ac9b578637a6e64331e2d40f539000000000000000000000000000000000ae2c40a49f6539bb257fd759c2fcc9f7b09d00059c7a7fd41422ce39aa0792413894bc716d66dc79092223b63de6ad80000000000000000000000000000000017a82c6a853fe29f98129998708f0d4d2b09fb22b07474395050d87cfe4d3bbf94967e05861c20680dabf3f4367135a75e676b40c09f80be5d9398a9ec20cb811cf6819a130445203d792a4d34fc3e950000000000000000000000000000000013b950aa9b7675322d7b39e81b13b14f2480155f74bdc5793425a02f7de41dc1ebefe4f07accd3719feecfe366e93c440000000000000000000000000000000003378e83277e4b02c3b517d3a8cfbf2d2a6585d028c723b2a263e6ba17faf14bb9aea301cbfdfb73f84709e2af99867693f63a87972dd11f5239c35ce269e4b9239e3ae906ab117f1f045d3acfd16ca00000000000000000000000000000000004d87c87f8f05a0999c712756bcaa0572b70264166b16eea7fc4785a59cfca18d5b819f0e65e193dd7ec38d0756b84f20000000000000000000000000000000012f64e2dfa3f00ad8f7f68e08b24aae83a049390fbdbaf570a7973d8516dc90e9c5c9211130d5c6c09f5b29183e24201145e3456d5ca6aa5910430e5a19567c327b757377aef98c4f46fe9a1f52cdc5e000000000000000000000000000000000851a636dfc668d1c5d5467774deaa78283a6f56cc514420fb2b6c58ec831add57b5203e31377a57adcfd9097a1cde2e0000000000000000000000000000000008828c34d4e712bdd5133e220167f3424491b9f47dfd95406bc833b3b030037c0ac0d2c84b06b4a2891c8181359af350ce27de5d3a5ef941d058a458f3ad2a386f1d66945789e51fa330fd65da4cd5080000000000000000000000000000000011021119ccb1cedf88be6f72d3999df899efc4dc28f828831be911582b61894aa37302f84ae9269b97b03a2e30d66c93000000000000000000000000000000000c373df4c0cc1d8a75cf2b9a99b5889811d3ed42850f55480d891b2f44769a371fa4894cb5bf78b7e995b4912cf47dad87bf5c4624e86aaead712987f313e5db8f2fe6787fc33481ed6e5c4d3e96d5be0000000000000000000000000000000005bbd2831bb4eb8ace45ed719056b95dcf5bda8831bc1495f763ff5e82be9708a004a00ecd102d4fd084579d892e5da40000000000000000000000000000000004de171bf5fab4c89783ad1d0cc9fe697b827f023ea1660b0fa2cab108fbcdc80837d46f292b6062761dd865bd1f905f68cfa3fd0692c9ce56538bf70e77e2a47534d9472ac702c53f2dbe68217d53df0000000000000000000000000000000018b36452aa579eab36db9b0417c999fa334292bc7174bb88e4bb14025a20c86437d5cace5369b90640c81edbf2d60f2b0000000000000000000000000000000014278d1cc3fd07e947419a6a0d7f7bd5f9e13fbd63779ffadc150e3d5efdd1a3f6f6e5ba8516066b75e1925282d0e644a36b13ef742bfe88882a4e635b5fdbd9b079e1adf3423dd4962835c68c9617c5000000000000000000000000000000001365922301de7c81b839e970775854881955f35ef7f718643a97e54746b9d9867ced3fb7525caf5b5bd0d382de02fedd00000000000000000000000000000000000d37c4e106e51c4cb65fef8460846eab04fae7e5ae1d1dbaa1e0bfb2eab7f2e27a9cd5c3cc942e38b021ef71827a0224c54daa7de8446e5a26cdbd6741cc90bfd26c544fdf221d47d509c978723c3b0000000000000000000000000000000003b9de0464ac24606ae840185d2ca6cc78773b674688a028161341b88907213e275d7dbcb8d8bca15b483922a09297170000000000000000000000000000000012ee2a578c09b7563508d0d94ce6ed75d277ebd89a7f1d6095f8992c0794b4de12e33ee24547c271e17b7a045eb3bf5b17ff7a416011549f144a3a65238d62395f4f76afc09496902c064b27739c6d0a0000000000000000000000000000000005b7aa071b76f93c765f946b96a972c1d11a2c44244355e90cd77ff069b930b2e8171f7cb1ba29f7ca6e62d88cb83c1b0000000000000000000000000000000012cabb25e52f00f89f2758790f9a81d0e336ccd7bdff06a79552a346d1966f54a5157130e5aa8db175aa64a431e19e494615de9bd7aebf1acedd9d40fddda34e4a85bc253c5e92c20d984f6c4cec533c000000000000000000000000000000000dadebc30ac3e033f433d8d012ffc70adc146f4d9574e5431360fb4a8ff0891c8a9f38a8754984a385d704086c320ca90000000000000000000000000000000000238439bc4e8c7dabe260c7b40d317014463c4728d79f521e7e321346747e9aa65bc6b32ee5920969c34421bb99bee9d38f1a0417a5a366dd2d8f5ce229afb6f34c1b663ad6eb1d9ff12f38412f00f700000000000000000000000000000000029df69b4ad5cae9fd974da7f58e4c55e83c61eaf011b5f22e1308b56e2c31530c170b304d39eb3e8a3009b67b308c6700000000000000000000000000000000140451659b4d6eaf05db63be5a7b0341612747eea7536b958b0620bdfd7b9918e8bb76c05eb2a528bf4727e38605f99a364da9c6b07aada98107447afbb189626180c5eef31f7f2cf26d5d76ab0c745900000000000000000000000000000000062493361a1a862e63eb8f20b0610a78d30ac8595e4c6c3487cf3add7cc38613870c2ecd0cb5a869110a99b76fb9055b000000000000000000000000000000000d8918e018ac5490c91cf2574e6a6962b69c17883caf2caa473de172b14961780fb237236b56a236ce8c674dc9001547031aa8d860e3b598ad0c4e9f93f26d153f8a8d8d0dd614ba868ed055c517532f00000000000000000000000000000000016470ccd107b2afb9ca03a0efb958bbc165304871e683fd606d2e78f65e34885668c6ccb655d4fa98f5776280e63cb3000000000000000000000000000000000982eaaa34f9301fe0ba1915cc5632329715c506528860701f5e52d1d77b8fabc89706af2c4ab3b729251b9472cde96f290c467c4827c9252b82ff523633ba116c52d15df9cd4e3121ff0e9f754ced5f", "Expected": "00000000000000000000000000000000112fdd661f948495ae2b9200d959ddc873c53c96ee4ec175f6748e62d76d61d6b15970d3a3a52ae9bda30a822ada25b8000000000000000000000000000000000f5b38208d69b5b842bc22ec9d91eb6b653acea5cb16569c61bfe0921f2d8ad613239e87d48c6a9b29ed6a5f43578987", "Name": "matter_g1_multiexp_86", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a9494f10e6187fa12d88e350ab84ab5bbf999554924e781d6470e700c3da78e411b8627459b3359d7363b088bbeb0da0000000000000000000000000000000017edbf1108591996f28ae17beadfd6b52340236c2741bf8474dd7471c19c1f62a0f28e8d8692cf3e700ddd86a931dcab4aaa57782608de34c6334ce5039c67767f6da7b315dcfc772f03aaf3dd1e67b900000000000000000000000000000000052f9c6ecc29239c614936bf9ecdfec677afe80de019230180d0fe529a2e82b9e15d6e081b02475e2bf812cea3ba6c640000000000000000000000000000000003dd0afc91516b50d9027c0b132453fab92b165c08428fd5c2cb994646b6b1cd5b82b7c3f7924e4a5cf8b45575e8dfdc22c1cde67b0e8ec7217c6ec72f36d8a1e73794297819de9ef6f1e52acbd3ec4a000000000000000000000000000000000da6e13230b2236b2bdf671bd5f3f8bb47bfc637d6e3f1796b555a95e51b86d04fd310f3d3198dee604baf48f69ce0950000000000000000000000000000000018d209b03f61056147d6734003daa776011b70a57e1ab17d3b92e2565b31a846d8fb7c3fc6fa1fff04552800b73affab895341f4363b688c4e9660fb0cd17f6c111a5c92e732205fab0d0da0175f683200000000000000000000000000000000116c72b5bd9d30182463c592adb8f73c16d22bb4a22832b8d47b683da5f4b8179d4c80d361ce69f92a393027ab29c18900000000000000000000000000000000026dab8d729338903d46a219004fada41eb666a9a90d8ba115f53da9e89a7bc5d824d7f4071c8859df52b3ede7b7dfaf4c5718fed7503c5e2a97fd6ab0294d6c42b1d35067e9d5ec1077176a4bd3126f0000000000000000000000000000000004e0627475a0d4da458475dbbebd6c36f4ce771bc2b2a8c6adfe9d372ffed05afbea207476af26974476c0cf51a9267900000000000000000000000000000000199ebe83e44a269752d92629810d0c5402f53a1bee03ccafe0b3299a9968ec45abdb5a74a6d90cb026cd9b28cfd2b89f6d055ad484f5054e8bd0d073cd556deba05418ef1235d08ecbf8717b550933fa000000000000000000000000000000000b4918f4bfad81349edcb45439e148af7af6664094412c9a51b887271cc3c46e34147c8a306a19f08922bda9c7146c61000000000000000000000000000000000afc3d1a7c4b6d899149801cb74a7e64a126631b3e758a73feda92a2867c53fd3efd9adf025ca6f6c762029c57706b0b4cccbb062c27a67ae2783ab65a47ce166330cfced1f11b85f87483e0250b1384000000000000000000000000000000000a093eeb354ddfc5ea3090b20312788923c5db9d78905dd31d5bf15cd83521f2f186fd284de0858270eea05d21801aae0000000000000000000000000000000011d047410dbf6df20f81971327b38996484e0862a9f71879ff63462e189471c1ba391496753456f0b5379a3b36380e1296111cb1181f048f51349aa2953bba2af50f7b7b5d2328d435bd63a7df5cfe5c0000000000000000000000000000000003d8e8e3a442f911e23b353e9efe396b746360254c14216c752fad17d96d440988d5a25f044afd37f12d74c89c8cb2d700000000000000000000000000000000179ba95a3d3b5ddd3d181e2312385f4ad7232d9af0c28f375e2036157e4603c1a01aa6c9c91496bb28508e5885bc2e599d7f0c0c7e927bed3fb930fe2d0109f58678969ac8e14fabdf4ccdd0823f706d000000000000000000000000000000000f56dfaafea0ce3152458b7252fac14ea64483e1d4a00a44f95bf3932eda2f2c51f0239e6a7a503cfdbbdd88aef2f4880000000000000000000000000000000010e02e9be7c1b795ebaa84f83bd27eba4f12dd49b146db0d788e37835338d352445e82060dd595f616b4f6d2d03cf4c911ce517fad2609f2ab8d44ae6263623a7903b2cbec683570949a96fad78fc6d300000000000000000000000000000000010ccd262b0cda9ad39177d31be0725b83e935c690fa8e07bc7f24e26f8b03122173f4ba43fe8ac933a7fed79f4496c8000000000000000000000000000000000318da543dfb04005a3cf6d93d6bc4058b4b93c4cd84ef978e6a30dd85d60e5e359b4f518842e73d182567ec4fb236b8b17d28cbcb9efde6d9cdc4c9cda385ce598ac8468d4fc94cc8e98ca3bfadf4400000000000000000000000000000000003dbf6c0676cec0202e328bf408a8fcc38758db1adba3e8184cb3904ed204b7e18db2183f5a1833737ad8eb089afcafc0000000000000000000000000000000014d9add10a0c739dec7fd09c57b3e959f3b7551eab8423ec5bcab4b14e63b7a27f128758d63f8e43a22eeec7bcaddd41a9516e93416bc7b0f3c5ef5da6112abb73fc285a14093ed19d8eddf2411691190000000000000000000000000000000014d0230f7d5c51e6fff6490c61972e2564bc31fea4a6d1f293424934f75629cb96f189c80ab32a79b2e988582d0283960000000000000000000000000000000011813cbbc0cae4cf6a8d5d58859f1c3b75ac53819129f92abe0ba9123a1a277b55231e1a24745d0d2ba6242ee758113c87fed462636eb57506f870ed1c8f66e211758327f4c19bf909a6419312c5894500000000000000000000000000000000006adb1e972755f04cc57170d19414e6930d0e6d42c09f587e490593a5c01ce6e827a6dd1e21570ba11c7e4277d532e0000000000000000000000000000000000ef599058025f40c9f77ef858aaf314faaf8d72277cd319a84a9d7038d81b76aa260df0516dd38633b22f9d3996e4761c373d64034c78482d6673c6906553151887c8aa28ab2930659671b8cb98a595700000000000000000000000000000000008190fa5e3d23c0186ba502a5892b76cf8faf2c15c91ee39d51b269b6bf4bd3e7ea395787d989c1a14ad88f3702cd6d00000000000000000000000000000000118d2d1b28f9180155277b80f1a7937dc7fe6be3b00cbf6a7ddfd08cf653ed11a4ddaa44576e70b27cacb7646a100d03f29c901f9769a42610958a8cd53eaacd9e5c4656106fab536052518b49899117000000000000000000000000000000000d28e7ef8433f8d5399ce3cb847f2633392bf44ae9fb2d402ed8e7e6a22de35c39e4f09ea0fe673ae3cb652f75ec80bb000000000000000000000000000000000ebf2ed9df06e2d5688d0ea812b7f9de78fe292584476b20bd62066977f5e221dbbd8f552547f06a3e821a53aeab83c1125c12599e84b7e648aab52cd68fcca7f1a5f56c854f3c36e0445ab7e2df2b740000000000000000000000000000000000e162f9ba960f452c269bd2f9f06e8bf1ffe737788d6364b1f75ea2788fda7e265dcaa907e45bc6ef7a31c4791b470e0000000000000000000000000000000008a778bcedb58f562c7b69ef3073c81866a395d6408829816be3172e1e825ca6b88f156ed2b2ac5a8784fac62b893896bb9a1d051e33a617c25e17b7ca8ae6b02f16c759cae0df7fbd403372eb2407f6", "Expected": "0000000000000000000000000000000003f6acb4e1f7856413fe9317bc7cffa45f2053ae62e3b5e2b82ad57b48cbeb4110f53dfcace08bbb1955c21b50fc636f00000000000000000000000000000000172cf1d257572562f9fc390f96f2c39dc5809765b0b94240a554f8bbcc44e3658f22e81d1e6c43742ef24882934cbbed", "Name": "matter_g1_multiexp_87", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000013d3d80910d9f43a707ba389b03bda49b65081f65096bdef3942f0bde2122ea575abf810f400d47ced92c45dc73837000000000000000000000000000000000755b4f5a055c718f268cf3a74533fe8e8ebf37aff3045b58927ee6ee7a862c8c1cd61f00dfdaf6cccabf981fff16c7908c35887835bf4497d673936f40ed44145c5d5009fae16eb0f3ee9168831abf7000000000000000000000000000000001530565bb621f7cd530c0eeb4cc41c2587ef8123c552aed339f80711c157e1595baa140434385d0977e9aed2629ea76b000000000000000000000000000000001806c5a90120fe65450e84ee0a56e0176e944a3fffdd2c83bf15d7dca875790d2f842eb31f640456a1221e44035ad33ca0154f7f8d52319c9e5cd59052e91b84640efe83ac814d95370e46aff4334cf400000000000000000000000000000000143723a10965da7b47bed0d0b5bdb6bfef5b748f6e185ff2efb73c5756d41d77b8c217a6d92245ae36e0add4d743e7e9000000000000000000000000000000001274e8842cc812435a576b2ac19edb84f72d08cffa129d7f4e44be5cc88b3449ecaa719b4d76aaecf08ddd30f7b184ddc252ac28ea29b5459cd2ae5bce4bf08a102280c093b9962cafb481016a212709000000000000000000000000000000000379e08cc1f47014f7eede433abbe881818c0c3a9cb02bad8cc86242aeb9f9542aedb67313f494fd19971a0a15d4ee1a0000000000000000000000000000000004e83a0e52981faf6a787d0600ccc457ddf3bb81c76117265c1bd011e5b4f3237383e97dad3b019623521b3c94d67df36d3bb5ee3410dfad575b0fbe71ac5df2048f74b52e777fe0955d6e244d434f3b0000000000000000000000000000000009ec14585b72733f621a58f35ab30580f131c93db491d4d704c8da2a7a0a1146e144575083bd963238434e2af48d3d57000000000000000000000000000000000ebd1a1c160ba7c8e3c20745bbde05f08d7f3189ecaa831d05c6a34562d6d3ccaa92472c67bdebeac8494658abf2c0405c30684c596976bf46384e6afb2bad6f821c4a62338d7a6eb204ed75070b197300000000000000000000000000000000084b7f967b141c94df69804a723169f69e05629c97a7a8c60b140787f3361ac87458372c91e04c08da2d01fa96056ef8000000000000000000000000000000000d731a1a900551ca569b8066af85176b934b94332679aa59924eb7d9a5fd776a55b4d7e5ef2413c53c244c848694b06411009058bb8e23b0a4294b5cae63aff10265e729d3601d85dd7f1e8063ce260a0000000000000000000000000000000001847861de1064a4226435ca43c1cfbc5d4660fcac177654cf5d497ba9aa5a6322f1156adafba852633e111576698bd00000000000000000000000000000000005ba738972bf139d91f0a426c96fcbb3b77a01af0f2316f2427a20882b5f355772fd6d6016ed77c31c13f88b26c628763e5489447bb9a5b661bcff2d9a4153a5aad975abdec380301b6d4ce019bf2cdf000000000000000000000000000000000148907d2335e046c50fe213b717fedac86eb3920099526a62b4466749d435f5ce11a45032b60bd5d7b26799adc63f830000000000000000000000000000000004bdc2bab60cf6df6dfd25c16f04edd96d5021b97ef38cad02cc1fc7f12494098eb793d99d15b327185718f81ec0ea620444d520ee01d87407747a4ac37abb7bd4e4c4f1735ca7458cc2e4dcb1d6297c00000000000000000000000000000000145ea0ffc3b24a623d74c27b84a390be062542795eb93a2f71f9358b44b76b93dfc0a2ae507f07a8a07edeed2410e5c10000000000000000000000000000000000d407c6c245316b5cc6b62efcd082829354d7e9e69ad739ae0ee55e6096ea08a48c59ded4595032093c32634576aa132035cab8f8120ea8e91389707a290db4ee69875d7429c6857e74e8bd40dc736000000000000000000000000000000000123f333f3554eac47c8daa1d4b362e42de1834ba9f55e4fee138eaf1a057036aa6ff9f50cddc78dabd3d5557b05b8bd1000000000000000000000000000000000116d786097bcac320327d7d56aa734d76d48a677e9c02ecc0bce550d75082c319f568d94b41e1c57c6075ee994e33304bec711286827f0941ffbb451a8eba871239341a60e3aaef23487175c9d2e826000000000000000000000000000000001012b1790e287a6328cbbcf80eaceb2c518a70e80cfe17143a41c4045e8c6c5317aafcb34f4f56494b401a8a9f21b5fa000000000000000000000000000000000613a88e513248538c1b767ba4d3667bca7aeee7974f691b7e4f012ea9b2b32603eddab0943229f53324c51838d18fe3369d91a4d575d4c142b98a53115a792ec50a290608ad316465487762e83f3a86000000000000000000000000000000000c31aa6f315a1102ea973d13e858d079221087edf178d98fb05701ed0a159309fed05942626b29ade066f8cef465535000000000000000000000000000000000177a3468b7de9612a93b9f2bb3f07acf505f56c63f798b4dfc38a25d0fc133c862e90ec8b40dc94004cfdcc9da197ee7ee472561535a7710db521976cef0c92a4ed89861ecb397cbcfafa477756e8e12000000000000000000000000000000000092095e7a431ff3a8e51e26c24dd4a5fed6d4a4a169b5ef79e8822611da8aca5d7c27139a911d5473442db9ee1529bd000000000000000000000000000000000c59f5a649682e864a792ad50fad57b7cd14cbb19d1feadc3536515f01053fab26950f56bb78d5a51f4368e73c19062f2cfdcb8240f183abec526344e8ceca6a007c35b757928803f854225d3a6ca3610000000000000000000000000000000003930511780f28217a125f524ddef656581a4ba2d461730f0837d1846d63258a02e659b25b882a3c3d077c880a64e3cd0000000000000000000000000000000019c682245c941c76605502785b1f79d37f65cf9ec61a4558092973bb2514de4e5852fc757c2fc7eac1b01d414248acdd60659743dc1977a698371cc302b7579b6d7d13632a31b47df369365fb02aff7900000000000000000000000000000000000edf518026cbf2dcca1d46340c24fa947261bcef36e3c8d026a09068a10a5afdb0964b54b70bb3b27e27c4d2e0bf9b0000000000000000000000000000000005cf718694ca47202be8c0afd56c88742e2b467d01e7b2330de778c434a57610fe7b8bd6071836a58f5d6b2876cff05a652a5d4fdf6d6703c857fc7b10a741b95fbce91fe823d827cc7203be3b3bce0a0000000000000000000000000000000013db13bf10b6d8b1ce5dccec98745dab635b8bc81d03601785185cccddfe2dfb3f3f9f6ed16d2c1a7a6bd63264b094d60000000000000000000000000000000001080522766b6cb5c90e6e0ae11ab4ded3db3ea3c7e69d00f29155283f7b25f762eb35bfeedf00caa83dcf04f22ee72976a30abda185e7d280804952fc0c074ad907fea2aa54da4c3190895270169b20", "Expected": "000000000000000000000000000000001975e01d64d38cb8f852b4177104388aba62c167da2a8530bc59f510a990ed57be0c6ddfc92622234a121ca407853dbb000000000000000000000000000000000de737b9097065462dda93321d5881430f50631f6f3deabca4c41cd491f1e441139bf8ceb598393ab2a3424b0acf290e", "Name": "matter_g1_multiexp_88", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001624f6ef9638cdc5f0b16b47ac8c5465cb479333a4ee4caaf6d2b656464d8f84387f01bc1811924312e6cc1e29a590c300000000000000000000000000000000012b3bcce18f60c4b2159df93a2d536bdcadd675439371acce011ac5b542fe1bcf89161fc3b3644679a395aed31dab569f4db766964c7855daea58d1205fe8da572aef06e0ca64912cec7c87bcb2f51f0000000000000000000000000000000005d49b4ea69c41ffa7727b98db08ab3fd3ca0c0261ef04b426ef29e724bd6158b3f3242cb915cf0992f2a631fd9b4421000000000000000000000000000000000f635c26698cf5dffbe25ff496f80c5de6b181f94a907204b79b548c1fee8c7dd426b49e9eb9eb0b17e34a26628c38e71deebc727d98bdec47b5a1fc48916dca1e42345ff5474a5fd6cab0ae99e9f1080000000000000000000000000000000003a80767130cd3c3fff0610f215337bc1b4a88886778fc0dcb6bd3cf7bee48f4c23c974c8883e2cf32fb01a84f9e148f00000000000000000000000000000000173f518f3349c1f704fd200747158940ecc395b04b4c476f406cc27836df182c3f1b707aa05767ff1bc75de42dba2a824b964d74259c216c1eccd7f2b52ffa5fcf151d47bd69bd2768e6466b32eb4fe50000000000000000000000000000000011874da4371ee8bddb34bc92fee6bf51226878e4550aa33313a434b75243c1f2296c1d62d9f31f6ffe2735f4f26a8082000000000000000000000000000000000f82551ba2b803e35c7118f4294626c151c7137eb4b97aa5265ce383f7ebc5ff5fe381776eee724aebb963d2bcb3d9f6124ceb1dbc8004a4b1f8b422d394b0480bca7c0f38aafd8f06ba090a98a1d3c60000000000000000000000000000000010501308d1a05e69700111431a0ca99aa41a991555b9a53df9c38413c67fa1b1836853bda93bbd8679e7724b3141a8d0000000000000000000000000000000000b033cfca384e480f73a4f8f79ceea706d7390e5b702305b79e30890e158ede03814d1a0dffcc3608fcb9926c5c65eb65a2bf15b2ed08b33056a0733c920741f86730dcda9c06aa0e3c135a844cef916000000000000000000000000000000000c7bf31a1f30f8e0de1a4a77b8b6c115d1a5d825b51875cba3db857a9cd2c589696ce2abe5a87acf8d6604c1f1f89ab70000000000000000000000000000000019ad7a6190a69fe1df07d55f8c792fc72cf2be11bbdd83c06325682bdfb5c31efef11fcb819d39f25bb1978570a250218c3c919f31d72ab414f91938089430bbbeaa53ad7a73224fd3f204b80fa1ab870000000000000000000000000000000012befada1cdf63d34ee2334ba2e42d7e69ffed71a39714e7ed89a86fd5cc1c65a01340c986abc37e7e3ac5a22a2bcc860000000000000000000000000000000006e5b16316867dc33a9770aa2283691f379581ff2b0b7986003174d4862d8b73bcc3f325c9a90097328f881b15f877c7f749063165c6db0eb038cb9f1a573de25bf377e1fee94f31df5987f7b2450aff0000000000000000000000000000000008e763f110c9415b63baf27236f1c0975e7bebc04bdaf47ea0d3a2709a455ea48ffefb7551a73c9d599bc5c9fbbca78f000000000000000000000000000000001492e70f2831c87222f7d7a9d00842870b77aa68e87b8cdc9d8ba61f86adce6ea514bf5b8f9d66937b1b640c43b02fac22d292cbcb836843acdd5a3fb404024174cd5c1cef632d1b9b6a73f2c5f705a3000000000000000000000000000000001685898af1ad3bfd350980872e6438048f6cb37398ceab33d7bae1d621b5b2859e6a07b4e4db891af37e29881cf573ad000000000000000000000000000000001084663fadcf81b9818c999c26a84c6f9a3a1f71a0a2982b5c6d01c56c2974656c08e4ba7833d1ef8bcf9af53d2f0732e816dd1bfe025685f2eff0856f9c162d73a58fdeae0dfbeb5ce076e9f9ec1a700000000000000000000000000000000013b077eb9130821bcecfe9b366c7a14f4487121095d325e74de44ea206078a6b1ac7d29a4e80f75c7714b6053cf2995a000000000000000000000000000000000b825b95b52382195416477f0bce73f06167db02bbcb91944e9e7534f804973bb363adca8b5ad80e77b70f4f1b9654d004f117d41a011d36f55d0cb53d4f98de3b1a6cb55dc8a76b29d393bc21826ea00000000000000000000000000000000014c48b3b2fb994920957b046643bfff19533dbe533df980dc60d9c852a3d07b8cf67454820a89ec9c7ea73a209f911ef0000000000000000000000000000000019b19e64d977d40b95050e4af365541b6c815534dc4abba7ea0af4b0a7e6bff0495fbb347250f5b5a48020ac20ea61cb6b6f5ee0549b28a1bb317cb020ae0e031dbc381075772ff582718fa49db486d20000000000000000000000000000000017fe39b732e6b815bde4078cba9f926e117349e3e49fcfb6308a0a09296fa27da4580d8fd18b0ecfd0ca68312cc0e5c10000000000000000000000000000000018a4eda1862c5c296de2eea0e720ba13f8a60defc65870f0112ab394e8160d6e1a0beff5db8c450d8770792b7efcccba05edf9812adf95c9844b2da06f75d96e742c0620d1cb0d47dfd9b68d0bb76128000000000000000000000000000000000e65750f3b9690f25b5bf80de0d76da21752a0daa8ce01b2bd8d172577f6c7d46c119ed20e73617ea163575705343c4c0000000000000000000000000000000019d0f934decb53a477b37d894d6e651a8a4f25b9375bac6b6d3483ee8d85f56b8374bacf74bb8550bd26b3d326962666f64a71e4e7652860038df67c99d97b1e5a063370e65217531253419bf2e6365b000000000000000000000000000000000907fe95f32e22ed75f94d96c191bcb19f88355bb84f91a8a535441da04dc211376435ccc60ad2089835b51e79f24b5900000000000000000000000000000000071e35d64ffa38024f4ccf7c4a713e22d8fb4b8450ba7b05ec5e759c2f8ea30e7d9e71ec2c90b8c667370131de785116059bebd962501b8381b67c22055ba01667d916932713d7ca427cd80d8f76b419000000000000000000000000000000000ccc90617f386ee2a76da43a745972066955c8e346d3de214834ea79423e7d95a008a6c119d640491d515b801034452f0000000000000000000000000000000002588711ccd23b65cf2f63b2d602b1d7dbf97cdbdb159e02e3bdf84fa65685e14d4832cde3662950a7fcfd11e68ad40a47b3448b9b404e184f7ff20466aef3dbd4e08375673ca31fdb303c88243fface0000000000000000000000000000000003b5acf5f4e39fcb32a267034c5e905eb3df32f2f6f7150d94cd17bf16e3a9fff9dfdf75a966040a6af5a623787a40170000000000000000000000000000000018e4b8d163e5176bc9a45da14fabbac696ae6870717bf5f6c00b5c73dadefbe329d86a761935b18e81d65ab6c48e241567d9d30b38b252a0661c12dc69127ac380f3f756144801633e99bc2ffa2f463c", "Expected": "000000000000000000000000000000000905fd0b04e8db7657431b5f69f1d896e79ecee300cd67ea8fbedcf51b0389506da0669c28ac8158d5357a61fbc3976a0000000000000000000000000000000003235ff6d1acbceb35cd29c5fe524a452064a6e51d1480ce1e57c538b2ab6ec4f98c3bac676817e25e2d92e701ba881b", "Name": "matter_g1_multiexp_89", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000688d6eaa2964e33cebae16623e228256937ce9a7721c4fbc85233ffb3edad5d6349d9c8a00c16faa0efd9c54827f46a0000000000000000000000000000000019fa249ce7be07208cdac9f9927163bb1b79b40b320623fc1a08a299d5500cacdc55386ce451173f683a9ce3f006c1e4aaea75e63204e177d404898aa51555767f813c3f3ed283405ed1ee829b04c85c00000000000000000000000000000000078eef7d7951f257b17c579fec05f3efe332534b2f56a953a701a8b92664b9a0b37959f7c3dbd77ac18a5e72d174b9f20000000000000000000000000000000017cb59169aee6caa1dbc3c47c29f977a44a81d33f1cd298d5df3e9469c8543d919b985e1b588a96a9268cef03876effbdb48a90ddcd791e6a9debfabcb1c71c88e7ad98f9e739ee752b381b28d7656f200000000000000000000000000000000025bae0252e5d83a3b76f2a861ebb1312bd344e3eaaed5e7169de248137a929ab94156be11e9b16ff312180d856d93900000000000000000000000000000000013c207c57a4876f6bd6e8e87eed0021d5e6b2aa3b2a323572fc2ad521e807c366fe31ec285c8412f89328cdf09dcbc99ad1795823d3834496b0a1c2c07431f9d76071db77834005fa1228393ad4ce3f4000000000000000000000000000000000ea93e5fe055ed1ce77de5d298fafdc4201418489b64d10c447de3973c1b98c184c0cae1d95831742f3d50613c5cd8c40000000000000000000000000000000004f2f3d0a5caac826632ee95dd1aafe181976552abdcc7db737f5693f3d08d3c4a85365e05e369365a37ef1b3df5cbca36d56e38fe63e573b02203be04ef9e1a044e1754eb2db50c6f9804abc4a40f460000000000000000000000000000000004c8b69c09f67ad17e8fb9fea4b7532c7c5bf3edb7669e26eea4f9c8f0bc10b0b1895acdee731da5999318d83095ef5900000000000000000000000000000000054f950a1ae65dfcd40eca15e5fbae984e7672a23ec030eea0cbc0424cc8073186b8442e0d71d6a4a77cee37c1108f941a6b36f4674ab19202037d59fd8e14369e5d3d71acc3c76985b813d81ca6e24a000000000000000000000000000000000b69b6b7b6cb1569ccbcea029dc71560d54b8bb88bd33af1c12a09d867fbeada2e58585385f1fe508a0dcdf8d2143f71000000000000000000000000000000000277561e6ac810ddf4c46288a065e5441ae0fe2d7ee79ebd6cea8712281a36f812c0bf49c21beb63a1f5cb670dd37d03ad85286877fa7e5a9a61dba9df5ce35083beca7c2f5ecad13d226fa32b9720e9000000000000000000000000000000000c0f4206d4cd564be1efcbdf57f99ce43b97d3e170017fe352ed3ec60862f87730d4d9d9d56ea0aac4f586d2f1786df900000000000000000000000000000000073202e8c73d14469d15a392589db79f3897b72bdb2b788da9012c7aaa167a157f85f3431161d35f45bdfe0f2255b6378fa5387c5712832b52c9c72e10c6f69e9c1c5b278aa379140e75e404c4f50a2c00000000000000000000000000000000191cae6012ca07ddf511ed586ef19e9f0d913d081cd752f033c9f74c334c6f5d075b4f6ec85467caea7836f51d0159af0000000000000000000000000000000016e65314e34e1c7ad577a36eff992abe6f26fc5349d12db12394bac648cbc1452cc366aff69e8cc4e2e5bc85db237a863023298162ebe7f4ae6aee45a8a6ba602c3942a8bd6b35636fc6b85596a582e0000000000000000000000000000000000bf583ae5e3a7827610d91c0d2433c8d358fbc12c016c59be8454c039197971f90191737993bfd08aa96d7838b7ce6dc00000000000000000000000000000000046fc386c5b456bafe03fc84b4f98939f9c736ac74cac507ea036d2443066090118138547766f637537425f64be9691b8ff2430d2f82c6d5e7424836ecea15af0ba2d0bd6498e65c65b6cd281a7b8f28000000000000000000000000000000000f08b3868ea056ff8e82fb7e22a6522985e92df1df9db77f787bcb3ed701bf8c90badcfd94e9d3e3b3b68ec497b9fcc700000000000000000000000000000000002e6f5e9eb44fcc7aa96a43856a707f5a82cb4c14c99b21df09e666d4802d15fb50d535184b63ae246d4ad77b6c4851415eea22058493dbf6ac248fd2ad8b4734ebe33761f2177089a3feda396001c000000000000000000000000000000000167e13cc54e9e9866bddff0c37e942ef8393a588ed3c2e90da12d0a8360edd6c3980bde808ff16588a57100d1a8898fd0000000000000000000000000000000014b21a7a106640b55cfeb19d3c23aabcf1c0be78fa554613e68404978b78e5d34b6b6378c2e87d0b8bf1cf3444d0db31ff79e3ef5d32a751b713180be37d44ae55c59c5a8121c132c5098ff972d8a9740000000000000000000000000000000002e8053215ae6894e8df09394353fe98b38fe4b17b9f20c7b48c4baad91519587f63b863e4de79be71672e1fb00d337a000000000000000000000000000000000c2ef9251a148f1ba8cd75a60ee18ba6328e1c3a6780c790cba3bc91a2145f44cb8bda5257c03890d5c5674e4d09296d039bc7274a3ab172285d853d368da0950203a48ef61b3c7564644762279c1ff3000000000000000000000000000000000aa7fdd550eabb1b734db00400304be9663c008d322d67fc771a85991bca6413ec07ab3adc3cb40d390fd41021434b97000000000000000000000000000000001994d9be11443f0a95a2ba4f7240a9dbaaffbc70256aebc0f10c322fc5b120feb2cd8492d02c60578f8becd7a8e589c92c47d0b1fd24c1c66a3cb0deb7d51ea19f0fc492f637ed5d4d03e102cbdd05550000000000000000000000000000000012b3574c35288c63930be8024afcc91194b30d2b486edae832dcb34778886af5816f7478df166f0a7e4752d8c12423e30000000000000000000000000000000012cd382d17ea10ad3fbfb40fdf4f3814a19384e302542a0f5731920443e4498a1f8f4d89086764beff079583a672b93bab4aca860ae4bc20d33808533c9a70108b153bc4b2256003ad4bbc11dc92898500000000000000000000000000000000117294ca9961249be6570ea760bb1e562cbd587f78be482263e4228171d9ee3d970b234455912299933689096f4afbd000000000000000000000000000000000029f88a99c750a388eca5dc6939082280ddefbf7d23997cca3653aaaa03a3ee4677fa8291641ad1f46fee0f8f1268140297500a2747f9a68b2d8d9ca5b0390369d919897c53d422cb76c5a283c38669e000000000000000000000000000000001006f64c279f074bf036897ded9deaf9b4ca380a9a7542490be675355c3979b2925be09ac4613fd6b7a4a8bb9e357f70000000000000000000000000000000001537e170e8dd88a92a6bfedcef69bb370f7bc1f32c36d203f5b6859be9b60fcb4d1e3948687ac7791d867e7c200967eea87ca4cf226c212c80f3db5e4e781ad7391fb73b1124d01cf893169d1c50ca99", "Expected": "000000000000000000000000000000000603f6b2d8b806c5e399c686878eba299131204084e2c31c38640d757e8a6e5b318da785d54ec8335398610e9e3956280000000000000000000000000000000002abafc5839180e8aff2bbac4db043e8839ea25d8fcb7f6faba2a1c0a567863f256f820e846e49b3296a754650ca9b4e", "Name": "matter_g1_multiexp_90", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a2eba2e26da82458a494738fcc816405760f4991616d729415ee502d13951c319be796cf35d88a8e00e17fa3c58126900000000000000000000000000000000117f6b75a6e25a786e860df05505f8e107b23c6f4338b2f87ac8740554304046f7cbb43f2193da35350e5fb39077ff3f9abfe7e05e8a210604355a77f64386a01323407d9f25397769cc6dd141bc6643000000000000000000000000000000000f6e3064df312fc97c4f30d3cab398f7921453b933d428a4162a37af5ea27c79d5b21d1d305a9609c994e61e56db226a0000000000000000000000000000000011edcb47b9d5339d08f24be87e52eabbdf701ab15f7799a5ae26cfca9d49e0e9107d9d1f09c711039d096a5745b89c9164be08e7c2fd15ac0116ca941b85615c6deb38fe85e2c0fd22997e394b8a6769000000000000000000000000000000000d6bf9e905e907ed86f5d3a4cdf61c527ef43ea0befcf6bb7eb1bb790b3dbdb83e0b958836669827251da94db1d07c420000000000000000000000000000000007f85bbbc54af3eb9e1c7e4c4700b4c784b8d2e6b2ff6a981a534317766790942898b4eabbb8d6c893180a436faf88870c391dff1c0c303c77b2a1fff24f50250dc793338f7d7f8f1d54bf7d87ab37da000000000000000000000000000000000b17bd374136dc1717cff915f7c898e049e892ced4ba57a16752a6dd875cf1cf9a2005dec3e3bc6f87b7a257d5ce7ca6000000000000000000000000000000000874999db06d15bd4b2f60e9b61d195747d12f38b75b74f3089d5b47735e9dcf79ebce22505399e16492c4a6e0f83abba2d728e013e5fc3e1ca24c105a0c268cbb4f152a97e318f3aae33186ea6bc93a00000000000000000000000000000000179108aa8a7d8443f69b7c906f9a4869ff4c724aaac4fccb5f52cddec86e32180b3ab2f66ba76d57f69416b70334a0f80000000000000000000000000000000007f83a847f4c7e7b35fd091249120bc59719ede5b6db083b33f5ea6249f9e13457511db006f416e0fb9614b8d22d51e1e8da0c8da19dc441f53c54551579fec5d820ce2e3599824b24b7c5bf1847c589000000000000000000000000000000000154b40b3bcd0ef04a5e1a550215c238adf07f92757c227e4d32e42893ee8e7e4fa9d7169005220d89b11253cffbdbd10000000000000000000000000000000018daff3cf04f648e59d00df4b86d8ea5dc74adbbc6fe4f080ea7a84dc6443d8923517a11f264f700e209af9bc52f759c76e90965adfc2fe52e4341895e6b6154fd7a097e052b59e4935c8267a6f0e63800000000000000000000000000000000163cb54e83a9935be82161939360356f7f0cd0219f446fd243d05f6333c68a1aca8f5d2dfa2b54dbc07f81f756ed6bd7000000000000000000000000000000001667e7a040817e83896d62adfc4a9f3d329e87f7d598217c7d2195c5b0c3eb58047d4b9bb640e3959f7ad1242e10783f7f3f352c7b7a9e2eb6c87edfc99e2df3148966760168f6abb13ee482f223a01d000000000000000000000000000000000222ed79e925d64fb58bf0cf105a2087c538c9538070bd742f7acf5e00ab371766d286fbccb3e708bda2d227523a40cc00000000000000000000000000000000126a9569e9ba97e5c41cf11af3a601560d037f1594f2e352ac86c744542618e9d2b6def0c7d3bb6a3707b80cdcb60f15d35c4286f19a9fe8117e37132ce4ce76e28afee25ecca2f66de3cd5e1c83235f0000000000000000000000000000000003786245c244c9508ba94e994dd510a7485f4aed711c75a2f509cf01b784eb12ce2f3907156aa15675e36b4b2587e9770000000000000000000000000000000018de0e75256cfcfa2df959f1491d87dd5414a1b51b6ff02ed5034394ea636fd0bc5d3b3a3b84fa7156ca7f97aa65feea3c2b40b7968a39fe8e4f24acc25b6c727887c3c44cc89cf62eb14a78ae47e86800000000000000000000000000000000026828a6409635184cb929a5b3fbb881ef013e8342cc9b5123ac82e7ce24fe7aa6a507ec3c017bba10126ad9bab5e63800000000000000000000000000000000132cf4a23eac460fb1a3db9aa43b542ae55d19f6bb2f408c399a570c1e479c4dd0462f9573c95c953bee07a51c543c4e10325465403dbd4898beb740884cc325923ec3e1d7483540377d8bbd02c1138200000000000000000000000000000000035220c800af6a330df6b6b6cbde47abef2e5fafedbb7a0feb84a317ca3cdb79eed934847694e85e2873ef97b31b6ba10000000000000000000000000000000011edd4c17352914beccd8c062aa7b95b913f35892c7cc5dd8f736a31a33d33a98d8f9b4be97ffe608531eb7c9643f32109545b90dbe35b0d5764bc72d45717e0c3aca6aa77c73178fa8a3ee9fec9cdb30000000000000000000000000000000012148b58f805c38bb862dd9847f12aad21d1ed760a022d2f619a0a077a0bd79fbbd6c066f0f6c58517ee9e912c60a37d0000000000000000000000000000000018dd847881616f7410f29d4e68854ded4e97b31d5112fd46437739ed62e6d78fab89b078581d052266b7c2ce403d3a79eef0f8014102664a300ea9a30fdc7afeae3cc338fd45cd421a1bfea98e304c81000000000000000000000000000000000e36ce625adc496ac94b53552effd651a73ed0c69abedda36e88d408ca7bee73777fd87b4f55e2e8b567c2fddbcff3d50000000000000000000000000000000008a209510caa720f20cecdfc9b0bd71d3fd4015627d0227a027aeb9992ec8030056a5046feadaf149d2392fc98fd60bfc8f1e08cdd72ed200253211e3b9947cb2a5fa24079b6920b4a4d3f1fd78146e8000000000000000000000000000000001373edf053517ee79eccbf02cce4b4b67d6efc53917b7cd548379c3f78b447ae5dc331285a28bc2aa5863befe2d26f4b000000000000000000000000000000000fce7f982bb8e937802fef7b3fac517054e6c9b288b03ad6497734d78d4b9074e22b1acef45938a08440948dd8b88683a7e25b1a60b6c6080ccf1bfdc37aabbc2bf92079d9356844f7f12867b3e2b2800000000000000000000000000000000001ac8ab3b3918836a5ba14e3d7c44eb8a0d909dbfaa2772cb9d7f8f517963662b5d4209e9a5d44ca0ed897412792792800000000000000000000000000000000169f8127198935f06d26ad8e4ca3ae5b95ad967aac69f7958fe9fb9c5b1f0e98e596fb73a0d8bf90174ca21a02a3e2c2dcb456eaad2b7c71ca32277206c1a1dbfa7e0e84950cbf14aadd455fb58e398a000000000000000000000000000000000c1cfb4660400ad5d7ba2f394cefa878c6a8fc214823dab539c0aa6d08f36ff1bd706be273f25ec5f1abfb06bb57e8160000000000000000000000000000000012ff9bad1a1d71fc49e96950c74d388229d4e4c68f7fcfafa42329ae06d4dd3091b5b1c95f6498743393b6e3ee794e4ea6e7b19245341fdfc5927cdae57f59de5f3fc8c37f8653e5aaca87db682034ce", "Expected": "000000000000000000000000000000000630b9d9da596e60b15251aa74de850ee74c7804414e3e4d7113cb3d5ad6b985e436aa67bed66c36f135050d66f91f75000000000000000000000000000000000ab084fa126c573ed007f983e01737453b3dcc99ead0a74cc0e8d7cdad89ce81489384b311b7ec4c34736e9520b37e1e", "Name": "matter_g1_multiexp_91", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015fec44912af2bcd34f1ad42ed24b6ce430f6d07b311d65ffd8b6d726ca23f5bc4b7437d158a36bd1790e806fd5ab448000000000000000000000000000000000c4a4de9940c7c26999773a396a8f9a6ff4b86f0525189426529d9cca037d504385dcbf1c89eefb5ae2cbbb394be42fc92898d9cbad829a5346c0925c15b585de18869adfe796e46cbd56828540571b7000000000000000000000000000000000fa1258cb0d8a37009e8c56228bbd11aa854a4695bfe96ce205efc1c9f32bff8afb64df0fb7863512ff8db6b091f146200000000000000000000000000000000188f128e662e8d28be612c8a17cfbf28b965340487df40bd3f0312187d027cd23b50e713e21f8595bc790ab8011919cfc193fe87634fb0bdaa1700466881b557c470a62464e8521be311a95dff65eca6000000000000000000000000000000000c7b39bc2477597e37910b1888ba0afe5ed03e809618bca0e543add93519909b6cdd6281e2afa65a9b45627dc1c6334a000000000000000000000000000000001335cbe866b3139dbe22266c4ed5f9fdbc15a1b338a290a590c03811b6448244027c12d118e6f829dcd352a419bdd8283dd9c99a5aea019436e3c91030d03ebefbf6ea6ac69222f1870fadae32f55ae600000000000000000000000000000000178ea2552d03f645fc3060a61b35af6e3e12095ec65b2e9972a5e346ac1019593298925a887e59a94af2adfac7a8361d0000000000000000000000000000000013996dc427ba51c4ec1f67b30c95659f35c8e71a225bf357f636fbfb428140f9b9e5602eda78bb38e87e3ab77495e505e74ab390c3f73c62eb1435226e9b4f9b921ea1918a61a614b9bdbe9eebd1cd790000000000000000000000000000000013555f26c2e10b79f8f2a4c397dfda0d8839a35a7cc15673ee5da34578f3fc4d38bd0331a5c42665bf40fb2cf693f31e000000000000000000000000000000000bb16b5b1dacac465a751a68b99def392a69a293377a22194fa4d4d6662b912d3ad804cbe51a4ec4792229de57923ea14dee3e2bfae3820f611c30df232c1d9c6bf58d40b3530858c79f840720d78d7200000000000000000000000000000000120183e73d23355da316783eb47ca687ecd34d85e800aa65d2c95aa5f8eb730a33d3273307cc05d81fdafcee5138a080000000000000000000000000000000000171f5e63fd3c71200720cba782ab863ace945cf405a2f961baf39ffab2d3283c26347ba297d16c3f2567814c6f9914e795fc8e20dd30622876a94afce1c1a76e3b689d6848903c21103cfce6a8a956800000000000000000000000000000000095ae1795306c8a8c48730987a842a05fcb263d1f9ea49d3f3c0ae70c7ff636fa4e7fa33a35637059c0b11b1b1adc6e000000000000000000000000000000000185e08447394763607d6efd8660118429469a1f6e7edd03a7a3e12ef99c2a15670d1f7ca664a8a14f52814db9810ea2b25b49f325e76733eb3c1a2cee5467157b2ee80987abae43d2c4b93e5157f08380000000000000000000000000000000012b0afa7f55ff9131a9399cdf0fbf2da69dae7cd504a0160665f0cd74a02163b8ad7ab05cebf3195495a1637134cee450000000000000000000000000000000002a130747763c25b9b6c0436390da91f02c9d5b24178318717024390a841baadae6a9f933e7f87f7965fc96bb498ade5df49b30dd6aff459f64906eb1a9c9b2067d4f1b75057874b2fee17923bcb906e0000000000000000000000000000000018911ed6adc5f48db7221656c622c6cb981b1ac1bffd64e30662035c0daf4bc5accbd53cdb1fe8eb60628262584de15a000000000000000000000000000000000b753d21d823d1050f109683c7c153514dd06663ed0ce118e388d18d36686e94588159e5afbeaa492d021a700caf2dfa959e0a33b1fa12e0ba960761b09921b81746b8df23e808a8de09e7f5cbe2bf41000000000000000000000000000000001107292ce4d57209e9c1e2c396688ccbe005699de4e77b1a221f9004585ae6cf8f901da6811ad85a88cd85cb819d040a0000000000000000000000000000000012cbe9c273a8a9c1404abe51af4a647f6c89e7e177efc04233586d70df6dad3aacc9ce2a9fbdcf2ee5c73396fe4e498d26ca68383528f6a871c237ae5214b49c18c4f3e2f3ef5dfba39e69eb181143d7000000000000000000000000000000000297e52ddc42a7da1025d43f46df11009ee035a9ac45e09a0902ba86fcfc5a4bb4c35ae8b0e0c9b86a8ed7e5ab751947000000000000000000000000000000000319c082c39ce4e59b952941dd7d14f3fec39a9eaccdf7bb41a2b935f876ebbb6778c90e1919c1e5804df91abd3bd9d5f1f95a9d1d4e8e7d0f17a954177253709d988c3a77c77d35b8bf70294bb358c2000000000000000000000000000000000ea5a9d96509cc5675e165e3a7c9f99a8c6b7be9c33fe5fba895a2d96a68e922271c90badf3c41b3ff52f359f5c6dae300000000000000000000000000000000106614bf5ae42409881f4889a82c6a3bc8000bcdec23b093ebf29b24cad128aaa7aa17566c4293f67af010e9b5950028b481f986998d863c98e55a7661136a8f19d7d4c57f6036cd642ae16c82cdcfb300000000000000000000000000000000145447f37207ac8d58c706af0b900dfc1f2638f840a0b44fa65245b5e671ffc6c008951ee17217e010ea6cd5e8477d4900000000000000000000000000000000187c607539f8d2b6afd15efa353e2fd1580cee48c469992785f02b3ea3396db5359e0d6743ff8d41648fd8680a4a8c2bad872848d72367467094675a819f9aa6107183aa0c8685d5d84c27b3aaab33c10000000000000000000000000000000012a022fc2dd9c201e9d86a0983fed4a71abd086068b8ab8c9586cf51230acafb084d559239d86a3713aef4b87a04c09b0000000000000000000000000000000017e02d69776c705bdeb9fe06d412a67601c6763a19c840f15f96de0fecf782e3a44118def54286cd52227361f0db3bf93c2c60541fe17fa8e71d58184a055fa8b1dd0bfd16ac2baa912b4472c6056122000000000000000000000000000000000e09d94291ce5e8310871aad89e0744e6b319b4fb1089048b0181cb9e885aec881fb7577fe0e80222793068deed473560000000000000000000000000000000017c8676e4b8216a98d9e9a05891ccb74e64d72a5ae76dba1b5ab2d1c4eb8291cdefe7753abc5fa59efc4a4834f815488ff07c19ad4f10ab47e73b6698f9febf3f28087614759e082e6e717588c1caff70000000000000000000000000000000008902b3f9b3ed6f0dba21e5d6bfc13fac8f003b3e11de4b883024c3eca0d2c4614604d598d31d9e328c7ee4a9d9be6100000000000000000000000000000000017a918bcd38986300bbc7a401e09b9ae20ccd382280b4e79294b6c8ae7bb1dbe2f72a582e0125381ef2b4fe24998e72f240c881fdbfc414d3e85ead1cdf166ed6929d0b2ccbc35f0811473757b6b41af", "Expected": "0000000000000000000000000000000015e9fb1d1a586288f07f399b87c37a085df405bcf88505a7d2b0ae6609d4baef7ec358f70edf838d3bb7291c6e5a413c000000000000000000000000000000000cc7d7e2d372183766a842f5c14c1f2a528d502f1bc5dbf5dfc9d812c56503a0b7cf1e6f052e998aaf45cfe24a261551", "Name": "matter_g1_multiexp_92", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002cdb1466c13290ff0c55c38ca6afe33efdcd09ddbdf7461d6bdb3e36fb5d8be851458620a0bf54932c4ddc1778c97bd0000000000000000000000000000000012755c81c142c5051ec64de7c89719cb59d9003fd8785ed5b36993123418e49cd3afab18b599deb72c969936633a956114d5455ff1717bdd545f4daa37e145121e7bd9636d7a2b65633e5ca5a63f2d9800000000000000000000000000000000067b3a33aaf3fc4b885035e60ba7f3afc7ccfff469cde1a67f48fd8cdf4b15b7beb9e2fbb13daa9283598aaeaff5014d000000000000000000000000000000000bf43cb79d63db544b2db14ec18c11bb9114db93662e8e6e7858d3e4a99cc332890ce90775b6c190d5ed418571fb907d82cd8da62bd901355a60b37ca14ce65d427bcf9551203cae7c346a49b4fa86260000000000000000000000000000000019329a66132ba7ceaf5c030fb4ae9a599895aab7df2a27fd92b55e3a52b99ac51107e798175f2af83991eb63147901d30000000000000000000000000000000005c71bf6552c314dda4bf9f2b4fd8aa368c9e88c0cbf4b1c2bef9137d608738636f40579a360bcaee1a3f12274687063ea2c7fc2050e9c1ebd05d15f197b4b1be61c6820c8d27ade57d85109d7f9824900000000000000000000000000000000048a258134ed95f91070684d04b83634c2d4c16601ad259d41e7d27292897a4d4ac76eb73425583ab1718b91f151019e0000000000000000000000000000000013a0b600765fb760919bf273a7b88bba568350ef82fc382babafd40a7e006e6808a03160f3747878368d8f6b31c619b1e3bf7e661d54796c71437354d7d3182770f10ab450827512a423d3dc82d5b43d00000000000000000000000000000000069d94fe286a9d39b64756e79669add0f66db69ead7db5b5c2fa1a9e5338aaa9051457a3a744c3b08d3afec8b87d2e9b00000000000000000000000000000000105028835bbeff46cb7d9be4b21f07670dc5589603d0d695355591ef5f7ba28c04c8e6dc40f0bdda031bb54a5710b4c0d3a364e7b217dfd649d1e08f76393372d8768bb0fc85c79ef4652417ef1637fc0000000000000000000000000000000015e6aab154e33627f92560e3def26d936a8876c52490732c807749cc28e34cb98fe8f86addb30e129f8149c504d1dcaa0000000000000000000000000000000005f6040a129df2340f3c3fd0935c02cfe162fe1afb58dba7699e7e08851b3a3c3fba36745bbc769aaf01a4f9a401d038eef7b05d5c725ed31269ae9c56dc7ae35048af39ab114319680d4af69be7e7c3000000000000000000000000000000000db5640083674fc75c0b0d1b2d6eb2b03cafa2e63d7a65c894d9a76b196d92916ce85c708c6c451aad65e0b439033d9b000000000000000000000000000000000ac8d6b508ff6797668ded6ceba4680443516d601a155cff48a51297e321417bbffa6eee042255e9ec054d837bffe628acecaee3dd4dc11e341b3dd0073842d90f641d4dd467a6596f337a6147bd30a90000000000000000000000000000000011daaf23ab5fc0ad7abbe7d5f1dc26c8ce388491cc049f01f287eb9b133e52f33d40f8693921d330ae57853539ee30c20000000000000000000000000000000017594ae7ac7f6e4f02df862b6d4ff946ac1a47085b554ebaa720ad3291f576ba720dd455829600f930e3964a44e5c7f30cba585b847bec40515a257cb839c7e5d677d17b7313c258e83d630e65cfb5d200000000000000000000000000000000174b5b9d4ef01fc9d0f05a03612210690d7d57ccb772aa53175f11b9623388de8019ff2ae1d564e7b30ee06bafc37a84000000000000000000000000000000000e4c03b8dc45b0567e9ddaa0a085d169799d2a595c03f2ac679fd858cd59341393e6a0f62dfac0e53598af4758843673b8cd305c650d2e1cfa91ef0aca9dd0d785d7570d6fb67e61fb9b6817116a054400000000000000000000000000000000197f0ad6576bdddb48c58adb1c9b2115cd9b38368dacbea9220d6a86bb621dba93325b676071e38aed2338273c98c4100000000000000000000000000000000011514f08bb28c37f078a47b6a0d53b311d5975c8a3c8e2c24a25f34bfdcbea53bcfa14b7f23adeb20bf440c87a251a66825e5f9d81273f306a065fd064ae24bc2c5ce8dbff6b22128753663a218da8a3000000000000000000000000000000000aa5f3a29c47fed2e4a87bb4c2a46a5a17102535aba9426235d42f00007e35d1c902b43c1068af279cc9a1b689a0dadb00000000000000000000000000000000056d9729f8faa8e12027b993e8dc41a340d61c64e4388c3166482ddecbef8d04085d6ae3764f0d9cfe76288929749235307ff9660ad0c24cbb139486638a2556687f88fb93a290a1d174bf87d780b3fd00000000000000000000000000000000070e376dd57cc8e2146d49ff08c6c6ada6302c36c4eefc3003f0cc3d75040d73599c7e0c2fb9f7e24484c37262f0eb330000000000000000000000000000000016a272b79edcb7e7fa92400bd55fc937d6389f1f0d3d2168656815845d92ab1e7b555fd4ea311802a62cb6c94bdc5d58bfa8ee3b44c70ba2512c00a1aaecede2180b08ac3ac8c550d70407f0c12e027d000000000000000000000000000000000bba6375b28ead3d49197ec9d3662e34c70735ed0f987f05f439da164afcbe98f25d2ce7a5e1e32515eaa4cb7f5a1f98000000000000000000000000000000000b1ec74ff999ac5a7a3ff2c91e93e5f0edf5f296b063d80bca22fa64198a798fa6b6385d25cde65b789454bc2674231058aa85b50e5f4ffe375599cbb912f41d35acbb85a324880148f9b9003c4265bd0000000000000000000000000000000012fadbd9c50f2e8518dc15d95a59ccec0c9886488ed4601b3fddb2bddd77a4bc861f2862c9c4666622e42a5dda7138ad000000000000000000000000000000000b2aa31218a13b4ab0b00d1b76a9ac7bb3d7e6473a29f2f0d137ca63bf7f152954e52182d32d3de31df0e6ef0d102c9e6810c6cd59b14ef4f6a4c2702cc53c65b3dc84988372c1195980417c583fd7ff000000000000000000000000000000000076846443079520c5b1600d5faa5a6d500998ae355c84b9393c79f83f1a2485b1809058bc53cf5f8a1a46bde6cf2e300000000000000000000000000000000012027dd1a4fbf6078b70c507fc2cdc0fefc9a0166694c796eb26e9838195e68fc76297e66e2a0e9e069274d110efb095c5ebc09190ba3df49d8ea55cfd18370b9d443f9d9084cf84f2236ef4723d2d4700000000000000000000000000000000183c019c306c08401b4f2c1d852b29dc47b56bce8cddfdb66d4e3d5385e4bc75bb9806da1eab476ee02e25ca2b4d41c900000000000000000000000000000000066d56711b80dc8725e112e4e2af6c939977aa66c931c6febb21735d78f5afca4bbaddd77387e52dd5bc9c29cf26923613a56b176fc835b7e825c817d432b9ec6d51b0a66483dfbf12166ee979b664cc", "Expected": "000000000000000000000000000000000f75ea9863e14f6151c452f7a4268b099f97d076b249d02d72caf5d52635bca3c686070d4a4bf997b753c283c82cec600000000000000000000000000000000014402b3e738bee3bda4e62c077e9d355ad8a71b0830ec0e67a4fe6dc59b1f3f7809ca7d07184f53c5afed32db327598d", "Name": "matter_g1_multiexp_93", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000107072809eaa84dfeba5a95f94aecc2c985c9e5dbc49a741811fe4b2393ba7f6597ac99d8e80c0fbf715a164099e9d5100000000000000000000000000000000124d1694bad88200cde42f1e7721f3390df8dbe4745715a2f0b6f11cfc78996c6f342693acefe88b3d83736cac6e3e05dedf65658ec3cca48fd48e844337159af090c5d1f5e9d713ac6d0fe1e1f193d200000000000000000000000000000000188a853e19d512149800bb0aabcec450561e5ad08b5159e0879422cca1f957ee15bad2b881979d7c8551eb19693bddf3000000000000000000000000000000000dc097932535d21656842615f08e7016f55752556da3be69027d0dea621ef46cc65e335873e041a3dee6c7e5b7589dd5db65ad6bcd6f485eefebda0badfc64e9e7dfe7e911f3ccf4f4fb9528dfebdae6000000000000000000000000000000000d3a53b9865082b23226042f69ca71b99978fd6dc3c8553e33ddb12542d05b026345a23c2b24dbd934be2ba3cd585162000000000000000000000000000000000b0832950405431722c23cc78bf0b9f33c6e2dfecf10e6d503c8c96ca9732c7e7a29251fa5b5b161d14b7155a50846886e0fa09884a7ff4c801ea0722cf6bfa58a46fc3d36058e8c395ea8fe56d9fca40000000000000000000000000000000014e19a8a203bd2e9e9601cf6feeac5699a3b2d2129b6e756b9b5a7af0cd9228083de8c9a2a0ebacd636ab1b662c8c0c7000000000000000000000000000000000faf049bd6532cdad26403b269d7dbdcab6c147ce0ddd6285ad9ae0e8ddab4b6706bbf038fddd7f63e6dc9a766928ec327a3377d7b9ff3aee2ce1194a22d7115b09a9fd53fcfa5e7f76bd9fdd35559610000000000000000000000000000000007e2e69d6c96b1841340c48e8ab070c67054b574bd5778a8e38a9873241baf8b85deb73695873fdd9e3387fb1fec3b6b000000000000000000000000000000000fd151202c399636a360cc014c90caabaf3b01d5a6114e078eb2473bc2fff94f1c24597e39a3d2298a2e9210726bb48e446a62ef5760c995cb3cd0984d607c232c1eb0df5516a501ce448a189a3134d8000000000000000000000000000000000ad0e842dd19673bfb8534ee20591a9076268eb203940212f702131fc6a3e7b226a84324954eb4bcfa8a007669d2317a000000000000000000000000000000000693801615c5282a327ae034c3a1480de0e1c471a412f194178a59582509ac6fe8ea22c8ec8e98034348ac465527f4b35f0c1a7c2dd281f7d2f006497f99f65d6a1e22f1d9aacb08724b3576aa19e19f000000000000000000000000000000000ac9f4f22670b52e0e85a37bcdd729b40c45fcbd6e8aa78626752d736771ede9c570991e347134f95385bd77e404e4700000000000000000000000000000000005964a351f406083b14726ced542fc6d95dcb8bccbd41aa3ca9cf0395d8d29143b897c66c78e2fe56eedf17d4d6f6c1f94c1476ae0a62c502aa096a371e30ca885dc13fc417e3dc9bc00bcdf516764100000000000000000000000000000000018e270b6208be13c23cabf52e31a156209abcd7bab03694fcb7035b453bce8464fa1e090d59a1139fe451d8c699669c800000000000000000000000000000000158dcfe7736f4fc63071a70923d81db9f7d2a03512724dc41ca47a873132da66eb0eda58134312fdaa63ecba7ab529acb677bc9f1f7572f808e969aa50efc519192ab8653c71090e5cf8cdeb1a3544dd0000000000000000000000000000000000a614d7a53b7a06e71aea4014f9b951bc19747cd8822da50f7993c0821e05100dc5fc8d043b2cbe7cc4dcae9837679d0000000000000000000000000000000004e0495281282aeeea480fa47f53f8b521a7df4c5619d4e58f730fe346a6deb3d501ec8b55b581489f28b4d991ebd90cf5ca580a25a5c87015f57f7c23cc51a0beb5926c84d44659e45512da51aa0cf4000000000000000000000000000000000edd664ad8b77d86bda4ba772f677d34c9341ce2b4d2af4b2680383bce0fd4468e936841dd57753d06c50a3357a47eea00000000000000000000000000000000063eacafb540655984104f60569720625e4499f048ec7849577caf240634ffc42612ca7ca92c17e3e50aa627059cddf2fa1cc45c35e266a82899d8ea0c9c1f96f96140eace41a8758a87975b088f0231000000000000000000000000000000000a9d9bea7d8a058cf254d2b7e10f6d2e8244cf131c6f87c4e25b5febcac352d02b1b45ba347e0b891c8b08e7b5dec82d0000000000000000000000000000000001d256cedcde615d01e15cf526c4a8bc8b565055567aa1de1847b524fa49b4b9f654f5b66cda0a78f414848aab42b05c93d2908aa9266844eb265c2b1c17f8357a5ff039836ba83c837909f6a9d0bc03000000000000000000000000000000001519b05b59250c72c9db7f425954694b29b36af21d9293a36d7bcd1ffb53d0ec55a3ceb7980580ce6f9fb6a0faa7bf3f0000000000000000000000000000000009e7d045b69e2dccad22dac427f5938974a6394c9fef84633fb5f90a0d09d437219f1b7ef7e7bb03eed106948eeb560d3b94325aad8a2c80971a781bf6f6bebad63ee37405ab7e903fb7094beef14d060000000000000000000000000000000017cac7707469b98c6b4d24fecf6d818dce6c8b9eb44bb08d6e475e385c30fafc81551e74ee98cc854d38d77d15459e750000000000000000000000000000000019d5bea3e48fa7bd273233bd6325bbe38267e4950dca4fd9ad051f487e7933a366469107258d69f0603b2f9a8dea2e4f5143a8e734824840346078aec03d6760564870c5ee2b2dc13f8a39ac452be9f5000000000000000000000000000000000b993d9303ecc19122654d5cb10d488af5411c451b39b1e19e7a104477da50324472076c55c4557576a9e5d7755a381900000000000000000000000000000000172b34e576f0539e32c5025b3a8f25b5bf407f3f3dda863b194a9fd97d3a6facc00902c95fe076b91713bec162f61cbf0dbee37fea759c2a58cf360c654f85298e8ff44b3f900e8229c3f838345d053b00000000000000000000000000000000170d799ffc4c0abf6c582b41732308665d790900ef07a74183826e48c9f0fc500b09109b2b13b2b33cc17e6e639d2969000000000000000000000000000000001943fe62329fcb67a45b5155da7f950ee12fcfe0e8e9ee15868409ae44adaa5f03c330206d7d97fa733c9e93957755a0b92f9db82d0976f4c379622c4028002ede2ab17f647bca3bbfb159045cdb342b00000000000000000000000000000000078681739039a022499219b298799027a341be64204a34a97a8115e5e10486420c18664825b764fd7bb931343c2558a60000000000000000000000000000000003313d3482f952c6f9cd4ec2f2b61f28ecf7d8cc7e60f17e9aac8e63ab25dd6bf2da2d67805debce0dad8fe37a36625298df4ba50cd5cb5a02d5f50b3ba23e5f5b0172a46cc315a0a94fed05551a68af", "Expected": "0000000000000000000000000000000010aaf24dce0b05179769031ab81db339cda85cf68963640b888d3aca310a6de690150166c0943d658e51524981a1f391000000000000000000000000000000000d1af37c2bdca5886d73567cb00d5a9859755267800d7239cf39c291ba83b1c67e6a3532a2d8e8590c1bf2d845001038", "Name": "matter_g1_multiexp_94", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019401d9118a5c2b0c6ae40507cae6180083258eb6c45cb8bf2fd5d2703c95fb07c031c82d0568a395e18015fe0a48a2b000000000000000000000000000000000511b992882f75fe98131fd35276b7a1de527b94718549bb4f5c9980917b6301a86e45fb7c7e3ea99e54158e49c7e60ee49662df81f6bd455ee554704ff0c7d5a589d91e017d7ab4c500d36378c17c89000000000000000000000000000000000d886eedf2a2b33a50dae5ca6f41237c9425b0a4daf08bf4789a3ea8c7f598d53257916d9c03df0d63f12a1a804fe0990000000000000000000000000000000012cb777812e76378f04fdaf2cea12456aa9e11b4c3ab0f12e63fe7ab11c716562b07b3864cb9dabb7970c81bc1da324c79eb26c79d78ab84c4d7e48e56889a601fda17901037a74fd79355e7536f39530000000000000000000000000000000009f09107ccfc5c4ac9b7e0058d6a0c4d7dc4309134d5fb972de3156a554211d4a2fbe639bb8a93d86091137671ab8447000000000000000000000000000000000b7f9955092221c8a2f09c6a9ffe6483ec0f8a0f6c555ec1772c260fb62c4ada6dc7beb92e29620afd15466b5f025cbed2918ddc2bfb7f7cb3d7e74b43b9a972c5b51ac20ea83f41d5b51034b5714c0b0000000000000000000000000000000009a22492a1b78342b919f7b5c8fcdddac408cdd3e8af4d6de5a4b1e510fa3b7e0e6887bcbe074fa839f2d0dc892db631000000000000000000000000000000000e5eac3a77c7a3e89e9324abcc0203046948f3d62e40156a5e1b1d9a274d408d6cb49e06b8cfcd21b596923f86c02c6be9a8159fd7915c15db69355514d9dd26c66fbd14af969ee576401b1b782fc6d30000000000000000000000000000000019914b405a24e72896b3d231582f0075fa7e59b0d0bc796d790754902238943ba634dce66131260efbb5dfc3925a1d54000000000000000000000000000000000352a5a986c500e41d2fa4f65e5a917061b3f9449c1e720caac187c6bfd4ce14f1b49ad414864a1510894530cfb4a768c818ce6e33e581595e83cf8d33a62edc26ed38c22f20c6949a94e2652bb954cc0000000000000000000000000000000019567f8de70c4cbbb25335e69154ce48d4106c8c9d0027e17c67777dedf758203b0a8fa3863d4e7812311f6cde36a6640000000000000000000000000000000009947f7401d03fa8b0801b130b43f729d6a71c04edfaf7b9d3265f82b039131fa09f20f9b4565d21939ab7dc7dd3477e9ab338e94b31d22947dbeb20fce3150127249d2db6107d95bdd032eb24c496450000000000000000000000000000000003c42ae9653d1d1f00d79f8b1a0c53d0f2d7f3ca52ca1960a621fc1bead7ab31cf6e5bf30c5cf7877c83b33b6b5b54d6000000000000000000000000000000001221117f45dea3fa1f832bb8280512841ad1798b76f1dd16dc320ea7c86473f6f8c98ce007ebc3ebc39e7a860be987fe96acb797236dbd0316fdd355f07b9b45c9bc626f73105e87c376af4d7dc075d30000000000000000000000000000000004340b7dbe7c27014add4ecbdf310de758ea5dd1100508a96501ae3caf9955c877113971a61f66e3691d09f0a259d4ac0000000000000000000000000000000001d5f83065f6d178b4dbbe0f00f0a88edf0a90021601bddc2cc27fb0ccccce7e48c6283a1e641408a20de15219b5553e60bc12a8b34e717b2c410d026660c14182250d7c66f8f88dd4cc94e550421caf0000000000000000000000000000000017679efa923688425fa9cff1f8e89ae681245371017f574f4a655aa780bd11009579d7daa47249f503592bf0ab79e67b0000000000000000000000000000000018f57a1ee533981c8df24895ad174228330ea361448ed63e522637df44cc1b888e969ee94d7b44bd532b655123f8f5d8537f0f732fee8b882d254a81704d2310c05dde186232f3cffc05401fa9830215000000000000000000000000000000000bf47631b34b2694ff7fc5d1e25de2195e606daafec34fc2c8ec86c0a325214d874002422810a81cff654eda187076eb000000000000000000000000000000000931c54d05eb43195c3ff6b396e324b5878c3fd507637c316c62b3b6e2d3d84cff9f33cd1046f1939187979330d3fc431a22bc0bec2501a505cc8e00a24792bb380ed451ab6f56fde07ace8b6c9348a200000000000000000000000000000000138adb70a3dce09176914deb0be17821cd0212c6ab554f7e200804dcade06c6cb5f7b084a1d6ac0ef8eeabc7cabe7717000000000000000000000000000000000a4422c569aced58938abb7bdbdefdb27cb06677c1066d17f98a59f847928d1bf2343acf8b5d1717aa38cf81959ac1acc7b10c801fb9d929432cbbe994b404d3baa5633628f396d20d047fe2c2ac2914000000000000000000000000000000000fd9ff095adf9e3f666d3141717ac4a96deb5b4f92dcee35be1d305031d06d51ecabf863a41cfd8dcda0fc94ecf79982000000000000000000000000000000000fb55855aab9e557046ed53421cd3627b519859e26338328d7da249fdfa6a07fa533f748eb5dd564f9922ad911121b2784f2f3f31d9869799ed8bfc2cb129dbbeeb096d771730ae2863c4ddece66158d000000000000000000000000000000001054ff028d2e2875330e3d0ffc52e2a83ee2ad2adf024ee294f695113d9d645f0be2a3d3c70f758f43f2deeb542aae810000000000000000000000000000000009a5e96cd08d3ee4e740e2f7b94a4e390ab5f6f572c4a1b2d927a7ef2365557ab9be65b8e2388fb571a3765892a96445c62206fadb762c23bf77f69f69bd492674bb92edb39248ad2a432f819304e6ea000000000000000000000000000000000bb1de70113edd86e5304248fa2f857f1620dc8a6bb28680f537e04029aee158e2ead4e0eaa373b812f6ca988dc40e7f0000000000000000000000000000000012118b670c9df77af087ad01e3b766d4a2b7c2b2a319cd733ed6c02ec36d9002036964fc442db992bf730c57a7d0a407a6f950de53d07fda75ab43f73982c2684edb06317568df15b8712dff2ef782830000000000000000000000000000000001968aed17e572c0d99e4e9262f239771976dcd9d7df19c20bfa94aefe1d4f3a3117bbfa4a6e329bc6b9552731446dd10000000000000000000000000000000004e64ce59b928e8cac2f744bef119018de8395b712013b0c69855fbf2bdc6a750a947b1a81c9df959c78367ed0e1575d95a373fab5176d124f783a36eb2346dddd5c4eba9e24e4c0cdc4f925e2e24cc9000000000000000000000000000000000148cd980512e0aa153adbdef262f098b1ece801ee4024b5561e261d39b495165851781d519d75f83dc5f298d40b4e9e0000000000000000000000000000000001dd43f37950976e50071226b6aa47c229085807ce9634e6583f5a2d47eb8547d4de0669b16a2771791c9ccdb4289cd9319d855218eee020f9cf8e4c0b6004902f0b16eedba8a1c911476af34f65dd40", "Expected": "00000000000000000000000000000000059c7ca50efe2d0a64b55a560a08976b437c350860f9599fd30370d1cbbeacae147144c216cb3e63afb2ddcf34282a5f0000000000000000000000000000000018f42ef2fb8eb6cc8c31600a3be37ece06ee567ce0c8b8c7a54c910041b8c25b2d94a94722904de079737f06e817f380", "Name": "matter_g1_multiexp_95", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000172bbfff135f33357b0dd0e8545da99c4ee74d6414724c2aa66ffc85f3a9d0e35ac80850436745a12ca6f1c4ae5c0ecb00000000000000000000000000000000152dac882023cce1a3e1fd4d8d5aedcdf6acb2ca9628a94ce92a4a551b1b7268589b52b2c90af6e4be9631eebc2ef8a62a397c2f19a8c4e66df0e062f179be2f45a0c5e104588222a1a78447512f299b000000000000000000000000000000000c40d04b3002c21b041ea8b8ce967056435fadb479fe1fe20c373b2e2c5b568b7a38d031424bc835bdbd85af8ed1d0380000000000000000000000000000000005e7357194364947c8dc32fd74757a3f3014e914dc25f42b2dd86230ca4f86981476e6f10b1559694bc17d014cd243d7f193d5a575c80a3e7599923bf5a8ba8a48e8f98322d1d8eb1da42e446d518c1b000000000000000000000000000000001474002c92db026ff5bce69eddf1d8ff8e6d2ab9427bb82377911597fafa4d60256836c094cd513a52a3a09797afbf5300000000000000000000000000000000176a7b311a333c2d4f6eec66e8c889ecd7becca75fb35a38bcccae52f10ff69630393fb7d87c3b6d97cd648be099c56507f2013742ddf2d35448feb80b6b7aaf2925d3975ce28ed2b1ac789886ae26e40000000000000000000000000000000009ecbdc4836c6c0cb4ccd014f9e582112bce0d0ab047115f38ed5dd51c54de5a43321e85c9b3e9af5fae0caaf2493fcf00000000000000000000000000000000034425e05f0adb1577f7b1bf9b9b50a76bc894f5ff0e9a8d190412eeeaf80d0bb96f21478fe8adea327f69c9137f57094e637a80a4eb1b2caba68b6828aa18f956c62baa7c5e9e591a15156c5abb6050000000000000000000000000000000000ec3d4fe1b5e1c26de1558d7dc51eba3b6c37ec037de184e8a6f481ae20b830c92221593e1bbe4ee76a85cb10b33e18b000000000000000000000000000000000e51f811e16f00626d934e69024b55dc29fa4ea363916cd8f44f928fda6e3ca4947eb15de24ce1952c39e9ac52d2739d27671631f9afd9d2e86f263f5c17c3c11c7f6e43efb6d75cb2cb8250094f2289000000000000000000000000000000001205dfd803ff3688c2023913aecb10c138be4d03756e2f05a63627973f511c2635571469d4f630758627f7977b418729000000000000000000000000000000001186b9c0d2b2073b495ef9c233c275922bdbf4691e8be085051c09e245242526b13b7051782a80726b381a72b5ef9d5ec2decb1f482f3eb48e7f52b89f6452b659812ef79bb42fb25f03aa9969faf9bc000000000000000000000000000000000413f6ee9bb25469af4298dde67f0a4a26d2f528848ac6646764703922c78d65e046204f891ac94b0b4c425110fe986e0000000000000000000000000000000011860881aa871fa3a6693b23fd7b1da0bcaaf044058ea0700b786f12f1074c615577e572e33faf8b3562bc285632696d911eb1de54fa8ccb746336b681504fd08f995c864a8dae2aa866862f81f0e7850000000000000000000000000000000000010e8fe8fd7863c2807a4bd717fc4646a0e4f99598b9c6c2cf0547d039d58290a367e4ad851c7a67e8dd546d5e328200000000000000000000000000000000063ea10e84e4f5824ad7b9b68398c9154ab25ddc4043a4990d80e09dd94a890dbabf9c3d93b13c4f40bd7b1ff32b14b2fd0a61dbcb0c657e824cbcf4670a31a95ecbd47a9b93812cd5124f3ac9450c1b0000000000000000000000000000000011cbc725705b809ad69c5ebb55ade0039989728e7103b684feb35c8142b100175235c2b395e37a20aa40845ebe2dabcf00000000000000000000000000000000057b5b5a5cf5f5bce985295f8a50252967aa54e934e87855097eb083a59863aba19ffcec4354a5a831b747175ba10e878118e9c70cc5def8e7d258e05273937c514131f39e0cc9fd2a3620dbffc7ce3c00000000000000000000000000000000041043cea626d6ab553b95c6e09de597454a3a3d1b8a75fc9ecb3afe15bdd8b5e73b8012ead8777df8957701fc9c9022000000000000000000000000000000000185da96dd1d54bb7ca5d7dc2fbe4cbd8ac95f06fe85a7a26e5e0e6353f6a6daf73b74117ee62be4f3fb268fb4c86275c445931b79e2b826aca02d1bfbb00c2dfb6d30ac2ef97a4ded18243b1afce773000000000000000000000000000000000a06b91559964aa8e8628946bfb720047915ddf08d24fa34f7b241e16bb163ef67f1e84fd205485d17725a8386a7016a000000000000000000000000000000000ec787cf5134bbd832d2a7dc1ed87b8c824552d92fdb30a790e1c73b22c753540a9747eecaf14dbf867d9667b7b852c7982ae6de98df906922e660d461009ba6c04cc6497f3645a66385c775b21b210b00000000000000000000000000000000053bfa3bd311c1780afa1862de6ae8a475b8eb9c61fcee2b63dbb6556022d703bc7eb204fb038056c654dfb940e7039400000000000000000000000000000000074ab5797d3c39804dfd5359b69a4bdd2b738670d13662eb2c112eefbc0f90da85dd1a4b6e0613785fc66b100d129202000674ac5d09c6c599173bbe9a43726c120c3a60a96d43954727a2f33ac4320d000000000000000000000000000000000cd50ddae4f053bf5b7b3237701bdee2f5167e09d824d260e89ea498fb3b593e5053b781c159302b0433ead35f072c850000000000000000000000000000000001abe8539a4215a3b7b78c79c306dcef7334c83f571f4d6836e1c1839a65c8cfa9a0811395e3c4bea26b22ac2175757e773f8e9637886d795b75e7ecaee512005c1780e7ab17b9f20ae9232595478bb20000000000000000000000000000000001e6e0709869922c36e073fdf1404a973e0467cab3a04a806361e743d67468f0d66de28f6c0c7b8cf92954330485db0500000000000000000000000000000000084e96298cca174344b7b86052426f9316a15b4031b9e42677253fd9355b1c99ed9ca3eb3949005078ba228d4167f8b0759d0bab12ac790cc3a16e88f1a108e670681f117d4fc7d01f8c5a2d6ca7fe8e0000000000000000000000000000000002c5e399eab947a52660807752ca662212cf3a201c1127dab3586cae88f8ab6dd23deb0312387178e0e9526bc8fc7b8d000000000000000000000000000000000ad86b21dbf58098fc4f758d7ec9204bb16cbbe680b58fa42821456d4fa508e42b53c8988dc0d9a4d6f6a782a5fb90b6cce865074a8a41f8a3f40228046c5be68bdb50ced10bb73ac8472f052530293800000000000000000000000000000000181f41dfee6effe70a28e4c53bb6cec52f232caee076f680fd63d73cae24b44709fc63ee3782a36278edcceeb7b32415000000000000000000000000000000000088d9011a9db9294bb4451e9981e84efa595462e26e5dbe14e9c84a8c5ddeca94f49857cf3b8a70e6a4047ad76d234585e2f9597c9b687150864e90ab042f4f012a54d92cf9d2ece09e4a081ec9773f", "Expected": "000000000000000000000000000000001170d9938910ce68e56f9e84be6f6ad284a244adbf26daf8d42f6411c9794b707454ec9300442fcb7a0f08eb91edf86800000000000000000000000000000000043679c7a917148d141a785e65b0a067e35a016c24bf7639ba374e21a817819ad67d317ee70852bd13a1fc3a373a38d2", "Name": "matter_g1_multiexp_96", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008d9cb39df5b28781d33d996039da8c94cd810bb85aa5868008b4267ad2a8670924d4b3ad7898b33689aab2211bb9bdc00000000000000000000000000000000007a8a6f888722e4717acbfc42ef1907206db31603c403e0a8c1ac0af9b37e63124d4645a506265487e5f9eda09c8baf85431a1df7678e49ee049b75ea968ca255ef456dd58cce57b64edffac1ac223c000000000000000000000000000000000db6af04eccb3ceedc11378406a26613aebbbc2201a9ea2089848c7af3b34e46a3421d5704242c4b333f72180f6baa0200000000000000000000000000000000105f40c8b702f0989a9e20f72ff6a4f7310d81787e87638c33a61985f02116e106218d64976d50bcc61cf5bcbbff7c9eb6ccbc0b600f11f1b89061d94c6fbdc9b1d389244fb29a5d140dab8842d44eaa000000000000000000000000000000000a77e39abdc9d64d72ea4b321e3310a145feaa5d342bc1a5b16c0143dd01caeda4f18909acccb3cb5b43ad999a94f91b0000000000000000000000000000000016fc4a4f6b488fd1f45a158d941d7aeb5d431821589ee845c64eb198ff10931d586f8a0678237be2a394f5976d895bc854dfe31190469897c30ac3736ab166220dd3702df5bc897835347713d03a8d04000000000000000000000000000000000d0ddfc05bc9f89eed488752d64698bf00633c83cc37931d95a599d6be6e4c5d611a4151839133e86f74bb91aed1703b000000000000000000000000000000000be3dbea501c822730ab0176f64903931aa46b0179c59556ee7e1ba54605ed8da2eafed7eb2254a7ddc34e553a9b6d59eff1ceff9e5184dd9fea44da4f07529823dc9b100f776cef6f6881120f7de11a0000000000000000000000000000000004d6f288744016f15b21da736283af2ed1f45df12067a3a70391f66fff3ce3953a51169eba6288cabd84ffe7f597c9fc000000000000000000000000000000000f6556a63def531a940269b073ea98be79558d832123dd681bb4446d4c11e2fed59a2f97904797abb07ba53e0d48e923b273e4c6266c1f5cf022902fe1310d2191af91c47995486342bc61cd361eab850000000000000000000000000000000013e692a13e79c734f3758780fbdabff86fe5936bf6c60f2f155ec4d1c49cdefb97dc02c1f1e4280c5ebb055914d93f9d00000000000000000000000000000000060898a9365ae49697e5ac23e320261eda04d818c5f1153f647844b1910bb3430d3c06df9a64af8ff9dd25c18cbfa79d1342b5cd4ad3179f406941ef6ea15d0aecdf9f6d96dc334c39b7dca89d256d4f000000000000000000000000000000000a2a4d92ad63dade4d666ea949dd64d5886eaa3c7ce466677356ce9f65520591c1aab590b48e9fe1eaa0f0f3e306cefc0000000000000000000000000000000002a2bfc836409b33bbe078a5f89c5142411bde621e9117ddf9f81f37bd546c3e2ba94975ab4652fa0858d5a2361592715b36620f65ed84fc0bb344b4b73f4eba4b1680a47b28b47f6d10f9ee8239812500000000000000000000000000000000075d3ebb18437feb21f94ad5e2ce96cbaea2f6d68885483ed54ee67f2dbcf8cfa39f405afb46e45d08cb804a7aee3b8e000000000000000000000000000000000d42851366ed4694730b7c58450c3f9ebd365f15fa4dfa3fd226d180aaa921a0d897278506ede76b85decddc9580a365249ca9bcf879a770b0a054422a6ea97ae795118ae45532c1523c842696de6d17000000000000000000000000000000001722e05d33728260ebf5e4b48104cb2c89b4bc3073767e56fda373bc0e29261c9a5c53e5768b453b116494c1109cba2000000000000000000000000000000000030e4da8620007236b89103b215e54751ba2f2dce19b0304997f450791880ad34f3e43cc4e6852aa599fd65ef72dd9a5c014a0aa616e809b674390b4553bf2d9bf325e73d3a935eba94488dddee4e895000000000000000000000000000000000c4e7e44e8e0387bd99311343d2ff3a080ddad557c8639aad64c4f6e47d64f48b91f9de2e33b4b9c182a87efce5d4e0e000000000000000000000000000000000e7cb49fd7aca3daef3c0329c950c832e1d007f21a4f950f367eb37b5d7433f5d6f1ab1c206232b2ee32137b56b53967ab722a1c20f068b6955a44073914c418a082345796912ca634e79983a24ec4bb0000000000000000000000000000000014026b8dae20a1913ecb45359e9ceb317137244e16a036ac760b47363f2d389ef6cb12cd5f5fb9e8e31ccd39bf114f8b000000000000000000000000000000000f07f9e76789dd937b85e02a9c346f81e87637bd03bd5f98a9b18ad6d109100b540aaadf1fec048530bcfa35dbb5b8ae8b314f83cc3ad501caa44b4c3ca8cf68c70ff6920f445d3a7ada212b6a19ba3e000000000000000000000000000000000a0249c354052094cae5a3d77313360a8956839af614184696b5b7fbd2af6555c6ae14a150220f01d624484b9096eaa700000000000000000000000000000000043098df38ab37f42175cc9f9fa9ecbde75bb344776ed078632b3d8bbfbf04103adde27ef0d361177bb3814cbb8bc54994ffab83099c69845cc87727d459ae300a5725ec53176424ab0ec8bd3f80eaff0000000000000000000000000000000011e90effb7ae193b47afffe6fcaa0a28c358222cbb087ce479b7fe88d25386c5a9c9527899d7633eaaed9d982d3ed4e100000000000000000000000000000000174877f80e5e9daf2cc219545ce67b904319f75c0284e41552662512727c1e05b364364c4c8835c1c9c6fe028ae45895b1d80be637e2abd98d0433150e14b629d98fc0918c7dfc179204669ab465e90300000000000000000000000000000000170e754e54f64090c4c7520bfed82665b44728904092fe3a4fb2fd2d3667ccd4ecb796e5ed9fc4dafd315c0b6dc22b86000000000000000000000000000000001081e62ee7c502159f7a8e28c5ee45fb7fc5b301f3a081899bce10096c74d1bf7834d12cb7fb1301b986e9c6f7501d53e670a57ce4dcfa680e60ef33ba99c437e4fdb160ea1012de36f4b59613a6af85000000000000000000000000000000001434584d8d1cb34eb29fd1c95871f218f4dc46f8b2ddabafdc7049e88f54fa4b80c88960a76411e365aa65cbf77f01ce000000000000000000000000000000000e4e2e1318c5907a07a7ff154b07e959d681a69c066585ba046b8889d417d01c503b32a924500944d43e68d7da8da35d54a999fdf391d3944318c54680e69b58ce3778683b6f2c607d64450ed32c6d89000000000000000000000000000000000945a9d0603a3bd0278fce30f0cf97274319a760291fea5aee143c364cc0bc60e59dcd1093aca1a3ef64696ec47845e1000000000000000000000000000000000a77cc690d55763a94aa48c210610833427ed3176b6dca184598755f539359bc7302f8dc2cc941d447d9b5b68fa716b70563ae7b444cca7ebaba36b8d59aaa5c0e6c1454a4a2907866247e752e640a7d", "Expected": "000000000000000000000000000000000ac708f97c9e9fef4482af7b95c59c2ce6b8826f6b046b5a29ee2224ad66648a8d1f9959ff434c77394199fbe75780db000000000000000000000000000000000983fb55837062305d7fbcfe8c76cce1c431067a97392923720a6c4f963839d7d2661e2a8dacad1f151f505748239798", "Name": "matter_g1_multiexp_97", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ae003001e3173dbd17f4d6598fcdaba9966f1e22a06ce747f7d2a06b2bd37579d093242a4940bd816ced07ec1917365000000000000000000000000000000000b27db470845f285c792da64e870b818a7598fb820313e075ec72e78f59f3903cb0860b749bfc67540a8bc80e844a8de5b59d128b5ac47106b4114cf225dceb621d177141ef5783943f40a54ad94e9900000000000000000000000000000000018a33b2c2f1ea187672612b51c8dfdd9e86674df58ff4f77ff3f71628e7aafbb80ad22f34ab4203c42bd39a4f73c3d6d0000000000000000000000000000000017c3a68d8782a479ba9aa829e3f261a3e1b832595fe3922d800349bdc2bf58e0c1b523eb0924bf0996e38aa83267f570a057c0405e24b7373f67197b2109b633a02589711b6a92ff49ca024f893d7ecc0000000000000000000000000000000015347adf6539116167ee71557b78d8fe13373512ca7d8d365179e25ae8ed2c6a65e1f643cb0ed677a2f44eab809d5b640000000000000000000000000000000002360dbbe0b7f8e97f6aec4b20a7e6525d83056975a4228901b4f19259c9ff2d2ee00da9bb9085232fdf843e5d305561677b05905180182427efeb848b2ba2eafbabc7519ab33db14de0746afb6071910000000000000000000000000000000005b62380515d49aa1427800077a11a8f01ff00fe7df53a13a9266910e4038167ab747bbd0705fc25ae2cb0e2451c893c0000000000000000000000000000000008de7bcad1c67d7f1fb5cfb9d20ac2134006618ce0d22f4120f5396bf8164c0effb0e3ebba7959e9dde757973080a9cc53e7f69582f4c106ee5bfccba1d5f557736c1b75b6e3777cfde47d552e6bdcac00000000000000000000000000000000185bee837e3212323dc40fd471ed9a1a58f2aebfcf7f07ab761d40bc1ed77b385a134c99385d07e75c5f8c51d6496482000000000000000000000000000000000d7d42e4e18040da671799f981d404085fed490182d397685498e80967cb9c080a766d5c8822152d78920fb388b979f534c87bfb629b817e7ab97def7400b0a83e47af8d628787ff814733fdf34ba8d50000000000000000000000000000000012961da3be1ecc774fc9df2dcd87c337ee50a99df7c4821fe08da7327276a24d754be95b6e916d5c63926b6e44b74310000000000000000000000000000000000e44d11949fe33bc3a0ddfcc74c5b0fa79cebfc0d4a00a574ad7659c7a5e72c728ae4ee031af57e9135a3eabd93686edbebb60069acf431e1671e3d00e4da0d70fa11ed4099b21d45a2b811f99dd9cca000000000000000000000000000000000f03c013d5554584c2030ea02cb451ae508fe6dcba72bf7c49cb47a25d3d65eabb2fe043b9ea90e03571aa7b64be8b11000000000000000000000000000000001479789662864eabf677d2a541e48e5ce70f35a2cd6c0a476d4179d02955a51123e75c650888e514aecc85d67781c8c18b1ee2765e762f1b8c2451270cd5a755758fd733d7922a537aa9f1fd7d0c959600000000000000000000000000000000139bf8fb623dd156a3fcc46eca51e61155cf58e2dfe8edfe717effdd4418c833db7fde2031ef27edb4a70f9d60d67440000000000000000000000000000000000c352a16159eeca4dc9a86601973c02e39f2a11c8a0955ad52236d7e46dbc405147258ea8558505bef0f09ba92527c76d5009fd559714d5692de5500ec8cae9c04ae1ab1c7c6e08c8738ef22da19ceca0000000000000000000000000000000005b8c4c2782a2a2a3abe4f99e60db6ff4179399aef4b9e305fe037e1a14a4c03ff59be1e91f55e5bf316356bbaf876af000000000000000000000000000000000eae605cef3beee4a176a0589f2676b3e212edcd7ac5834ece3066bbbb587bdb6bbe46663acfd9d8aba2251a238004106330c755ef708d8eb129475785f24be9e7836385ac918c60ad36e80e2f3281b8000000000000000000000000000000001038258f67b0097ec51adee244cc15d63c4d3bf1b3b3e64ef8ae6ac15a7c4195fe97bfe8c5a42981a2463ed1b39032de000000000000000000000000000000000a6f27fc1f2dca48f6e26456de5d9fb840e4ed3fd9ff12372e51130d7c439f4ceb4fa929da2dfa3ca271d34e9aa0985ec2431888d05cae840dde4c26911db1893659fdc345d5433556d9bf75e51fe374000000000000000000000000000000000373fbfebce5c599172ab017e8f4f9813b0e6aef3031faf61c336aa7d6b64c8986827a27605b476bfc1057a0388f864d00000000000000000000000000000000079ec2c41547d98277c60dc46a61ddda51c9df65a8ad2d0a64d483eb245986de36eea2509cf7949c5fb05a77f9cf3bacc9a72369cda74e5c86c6559cbc4f4db1b3ab24c5150c7decea862ede3c02c505000000000000000000000000000000000d50821953bbbdb494e48c59c940c5f2ac2b902f4c2ba2b2ad50960a51ed7eb1a9d592bb903a03b0b90d8817d10848ba000000000000000000000000000000000bf0898bd20e08205aa218e529db578d5118ae411159ed372eb8968cd773ebb1619f92107d2948020bb3c721ea63159dc2f50989b04fc29c4c4a0090fb11e860c15f89a66f3bb8281e4678ba63ff3f9a0000000000000000000000000000000006bab55b7648be3eaec947694311289f17258876d74a7d92f22b7807d007fe142a71210684593b1aabf74579eb1b1c17000000000000000000000000000000001016b28dadfe9b65d86a1f843f7ff4b774eab74431b68b079527c2387ee6cac69e95ca564346fc54237edd3d2d31f6ed9fc9abf1c76ff11ab538f46ce768ba597eb5f2f63073ec67e8de10aa1d666720000000000000000000000000000000000c0d5ae44a0863ef3d6d32f1d8f32f2c5b89112652e2e3d6ce620479882fafd73cd3627f9f11315020c8fc9341c7fb4800000000000000000000000000000000197067de9d61733dc0367d91f55a57ae268d5e7babe7882c1fbcf03cc38de7a2dc41acfa16bac0ae63418fc349b9471cd4167723682bc0e7476797b3be5e14b8de3e4e23b4ca33c50a2096cda8766dd7000000000000000000000000000000000c3964c79741fe8093ccf2f3d118b33897a18d920ca242ae153118bc17bf0102fd19a9e4000698b256930a2f415305180000000000000000000000000000000003ce4a6877879ee56299ed27f634571126d9f8ca8ccb1e67100064e7efb435cacb1ada74d7c7529b495957ce7a5dfe709644c3727f78dd12811092190d5d10adcd5b9fc581dd783c97d4e7b5130f309a0000000000000000000000000000000018e6260c0cd6cf806ee82a047c51a85e0d7023883cfb05993ee81220e0871b122c12e65bb99b20787322d93b82089e98000000000000000000000000000000000d5b66fc46b7fb60fe8efb6659bbe948c6776d7780633f007123c5c49f5fbe7e3defc0f3d896333d0ca01244f2b6effe0df9846c84354ab7f947caca7800e12e38d8e6651527e6831f4d8b1bd66c4f3d", "Expected": "000000000000000000000000000000000c7aa8aaa848c068104b88d0757551612285327ba5fbe35ccb4eacb1bc96a341786e4548f5f86f6ded789b712a4be74b0000000000000000000000000000000015c9aefc358834f21ec85092cd69df37e0036ea6ddf23a3ca052a669446b183e5340ec7ce894ff6575f5e6531947c84a", "Name": "matter_g1_multiexp_98", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004acd4cb6bcfed3219c3aee9368feeb58d77a7ec81d19bea11402015f4bd0ee2d7afd86fa7ae9dd320910ca28eb6d98f0000000000000000000000000000000009fe1b0094c0c2ae80a3c5accfed5d212ce39f867aa2150b781c193a0053aecb04d06e005fbfa0a24595e5968d024be18a71abe11a893fce872f6b8a020b6d84241df03eb934b50cbf3571df4800a8330000000000000000000000000000000018cf9bf39549c35e94211b4e2d0a0157d73e1ce8a17cd724eb33c38281dac07e12eec61b27b440b220c4f21915a73a52000000000000000000000000000000000fca6d956989db84dcfe58b0310fc21b5bdc82a32838c8d9cae912d683dd9c67f68e15b3fbf9d7b430ba239c8904fdd2bbf28e5bca314391550d3a0fce50b1220965860e72c8c3865a2d4c599d31d3f1000000000000000000000000000000001897956bc232fd5a9b0ed1b533bebef8ddd9e97002513eec71d67ce1086ba8473f2c013af7d8ac548290453d9f71bd5a000000000000000000000000000000000796da5c8ac165d416c8fa36d84e11bcaa80c1bbfe18efde4b4b2c71d6d00fa24f3d51eac312cad9e854f094dcb6ec7458b208a6845aeb2bf31999042c59b7b130a7ce5297e88023953b1aef63616fe4000000000000000000000000000000000302240769257e92899da03fcc4abe1ad3944b74c3046e790e4e950f2958426b5fdc691401a1c8a531f42185d382fe5b000000000000000000000000000000000053750b58b6d2fbacae94e22b397261e541eb4abf4715b3f528dbfc3388122918b1b4b506f2fef89ea936efdef0105b3b53b6cf9e0ce1661c4960283be790abf956c2d6433529b8f3a32b92b227aebe000000000000000000000000000000000168a635a14f61734372f4bdd2fd564d77afa8588e1828d88c4c90bb50f57473b2c20585dc0e93726b84e73c61f29ef1000000000000000000000000000000000e6e92355e59304ad35b1dbfbb98db803d5fadabdef4fb1b2a54080ec9a33a7147ebb4d5219acabd949337bebbffa793b049228435ade4c4c565e65f39f13a84c747c312afcdaff352560b9fb3cfebcc000000000000000000000000000000001797bf2ac9b490cd43a346fdc64bfb22301a0a0e371bb4df8ec02342b4fcc99af43b4735665c6b1386fa04a3dc5406e3000000000000000000000000000000000fcc20f4aec04b7896ddfd86f58c2e1e9dc6f863ec3b477572c073c0f4fb07ee8dc0d5a843321446445b6e7846fbc5d556197f5ad17062d2ecbdc8887bcdd32e5ed4c48cefd9e14d622a0b800d9703300000000000000000000000000000000013ddb8ff149222a5a0a997c0b89aeee36a6ff2540de3cba8bfe6a2a64fb505f13ad956a3882082ab85bfbe72f3a3a6b600000000000000000000000000000000102c1a1085f60cd5326966a2dda0872290e1658002ff3ed95c47cc0345565076bdecdeab7082bcfb439cf7f3e445faaf721d9d7fe10104cafcad71307e785321ab87b2b69593535caecbf0e166cfda5b00000000000000000000000000000000189515e637d404ce6db58d24774609cf946074aa22066d808dc022824a26b381bf09148005c61156a976154b025d71c90000000000000000000000000000000009102e313c4517cdd3d07a66e0013eeafc996c21fbf5f0f3e7d232ad5adb781cce1657bd5750193cfc0357ff55bd012a461531ecb61365908019c1e8074a4c322df2b356eea3f3eea9aa1e0e1fc5525e0000000000000000000000000000000002e166e475ff083faad64667b683e546b2358f945b8656f9c2f3f6e87a40dc3fc087dd94874bec1c4bd5929b7c96024a00000000000000000000000000000000022bb4ba4be638d8c14a16c94522c41cd3b3ad917daa454f820b8fa35e5a48c676266feece6986e8fe920b2a5e43e4b3569c1c1ae2d18bbe36ed50db1bf30957802b09a982fbed49d4968815552e010d0000000000000000000000000000000004947bd8ea8cc3b116fb7320c573fff0f107913c18cfdba2e7e9a4c8715e334a431156f384548508df8950d681163aee0000000000000000000000000000000001e9e7494c295248184503344b8ac7bfcff41a4561de03d78691ac47980f14aa47c1eaa3cca80103f0f2ba14a2842aea2061d33b2f7e786effbd2e93101a56ba1bb62c1a773a08b72ca82f5183bea35b0000000000000000000000000000000004789b01538cfc54cad0e99538e874d13eaa7f07199af29d460927c3e622c74e0bb4185afa12c53446f56033348c332f00000000000000000000000000000000154291a8bdefbc91445ef1fe123f326b8aad652c8c54502920d4dfa912c2f42d784fbc5a16d08468d2d6ee56e7e8eaa24129b150752d2d5551a622231ab067931678454aaeb23f76168219406f0d50ee00000000000000000000000000000000029048f227fe8d1b7247a82cfd3e1b4b60cdce6b52de42c4b96641bf8fc5ba9b077e33bd4c4fce9a51b63a6a2451b427000000000000000000000000000000000c83518e1b7700d68966d592cb2e3295a2db5226eb6fef972c8a84721d1e49a30e4a8ee3494ed4bbcd2a6877e1ba597d366c32d5d3c132f32a6ac3cfe1dabb649c59ae224338f747ad98b193e83467290000000000000000000000000000000003e96431aae4330d3d204093b7af21343ace4f1960de951eeaebea51e778b1fee43ecddc46667d096edbc5ff4735586400000000000000000000000000000000183a282f4b0513be661b1b38eb5f02b51aadc591745e0bd5d2d4e5545739e26470a9ec20d78ec284268d9c54c8e4f7b6d997516cac28a3968ac6946b5bffaace0856a52e38fdcca11ddfa16cf5a568f5000000000000000000000000000000000904c85edd36dfa18ddb4e1809607708142f3c0861570f2bc8fff14c462675661f2111c10a01557fb21f7f38957bdd840000000000000000000000000000000012a3a37f34ebb23d4c9268ec9e1d53aed4747aaace497695e6ea8fdbdedd58031cb479003e8bec0d14aa1d062fa30f2ce881ec65fdc2f58e46d3ee45a06d0c5ac844ee5b62872c7ba21f6b48621a337100000000000000000000000000000000148532bffbbf8bb1688f6448854214b4273b9d5adf132aa9142c1605d1882879678b6cc70638713b9438532d427f447c0000000000000000000000000000000010971ee30d83719e10e91aad3f1f201fe35ba1a057531b1905bca3a8391a3786cd077ee0f104305eafb3c94f4546da9edcd9b95e49473277a665ca0f9a8309df9ed6ee4f25d803aa967fb8f688273e65000000000000000000000000000000000f73574aa5a06ea569de88e48fcb96e822039af296684933c1b417dde95e08d2ac9c6ad4d525b0734e24807ee99ba88a000000000000000000000000000000000523deae09e75121a6d89b45161f69f0733a9e43d88d8527a03cca8cc126aeb7a680cfaf291554403723e20440b79437334582482a9038ab906880e43a4a9d39e73b6c63604eba0c8f6399eb5c288638", "Expected": "000000000000000000000000000000000db91871e4cd84b3b58216b6c2e77a9521f3080182e78d3f66fe33f313013f06aec2dc5a6d483f35fadebde873bff9490000000000000000000000000000000003b9685de062b09b9e277ad5cd664d28af59064448af2b1b2b2357df6fc88e3ee7e0ac837100e0b7593944e8db43ab0f", "Name": "matter_g1_multiexp_99", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002c7919b322a84cb1e6164043d745a53535edad9ef74533d3155900d4e1d63674b2616d87ca8b3dac6def99441cf196c00000000000000000000000000000000069f2ddefcadf0463b0c40e389837d1079781e04ccd8262623d5df6fb1989973ef6fcb8628b978a088e4f043f54d54391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000012ae6bd01e522bdc8854237da1cff327a09d34683811398bb58a45b5672fc93aea9903e14edaa4a6af3b2b58db051c3000000000000000000000000000000000abb87e947116b3d95dfcde9327f0711ea7dc52cc16c056faf0a325e36955efe4da65c9c8ee9a89b60fac7fafaf49c85", "Name": "g1msm-1-jwasinger", - "Gas": 14400, + "Gas": 12000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000044c8141f453400b5eaecd905a163ff950775a1a147e68eaccff25dff1d77c0fe9b2abf8311cf04993a615c1209a2a20000000000000000000000000000000000e6728c19f90dcbb3477112effe8bc4d65eff34814c2945170c7843d72702b90a1d97adc9a1a857e95f69a9ce56d2d4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015011119f24cc9325aa4b578d9fa3430ccba523ca0bf0359b221b172afa32a8c80135bce8e04cb774f3cd04999409cff0000000000000000000000000000000012978dda7d55bca7498a4c797bec5d170cbc90f739b1e20985262d422ea154ff35cf5c71bc23791efb5148fbdc47d63f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000179c5193a1eec7522458270c65d4fefe0cf72774498687925a47b21e7060975d02de34832fb709ae8ce98b396a9b8eb00000000000000000000000000000000004d522468140afde2f3d40841e020b0b240a817ff4ee1cfd13c62497f0d9446132dd5c0f36ba226a397721ba4a6e7be6", "Name": "g1msm-2-jwasinger", - "Gas": 21312, + "Gas": 22776, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002aa3a1c6386bc21eeac062fbe70da8f9079003a574805cf997d0f08332dc3dccc22d1ccfd81d29178b5aa01bd803bb50000000000000000000000000000000011954af068b6e7b16ff453bf139793eb909c438237339eecf79daa48d9f9a84b3732e6ada9e1fe1ef96081f3015a39541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005125a08621bff979dd62adeea6e90adf736f2e70141adbe90c01eeab94e2929cddc80d1ccc3ff186a582d79e33e22c40000000000000000000000000000000007cb53875e527241ce7d2770c949bf188dbbd7babbd14fa26f9b5ac59fe13c6e2a1d667a8315e9612297e764e1428e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066aeb84c4d25bbaf0e73d578b1d155092d4d02b75602b92ad1a8b2300a1c00389ada213ee3783d8d7c1814ba4349040000000000000000000000000000000000791699767760030bea023b1cc91edc9773ad9921fdc7a1e404504ad29260bfa3376f894fff311fc0acc3a1c2f04ca541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000010870702934c1136e6c4318a49b9b0ee08aaa292732ac268a49defe1ff4b5214104341e13de106456bd2c707f69c0b48000000000000000000000000000000001294117a4266ece3fe724937ecba3d967c90adbfd2f6605ae3b339e0c38c8b58bba5effec32cd9d69b0cecba57d17015", "Name": "g1msm-3-jwasinger", - "Gas": 27504, + "Gas": 30528, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b37533d0cda25930ea84e22c2230909934eeb4e79b9852dda61c1a0c69f3319e62a5e13c60d18ee669d041d51c22f66000000000000000000000000000000000ee646d305d99b163a19ee00840178ad7ac7e45a5eb835ce05392b91488e67134196fec73928bfdd90870ffd9e94468f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f278dfbf249949bb514f3498727173a6cbc4aa6e11df04ea2f3bada502d42a35791ca308fa1fb5d8083e0cf439ae21000000000000000000000000000000000851116ebe6e0e0fcb7ef115ebe78625e9d3a4e4a12a484edfc4da17ca15e53c4f1b3e72248b335d379d4f3d0186e6551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000040357c69d7eb9f119f5251ae29490b2f01d3c5cb8e00db82b955cd55a498c1c6e380866b7ea02c9511beaf506fdb17000000000000000000000000000000001329d35a79127fc02f35e82388b86a0faffd3edee776406107c9f67554f980fd6710147f824e863da461c1e7033d79171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fe52e1443ea05bf9476cdd5e80f36740071113800b57cb9214046e2624a7718307e2ff6252a6434e93e5af6b4129900000000000000000000000000000000016709f07278a749668d8f08f29d460a753ec56c2a66825df0760d2ff7a0a4cba14e4354cac8bf0dc967b698bcf49ea9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000ebbd670bc84bffe83659958ca5a3220517b9468cc7de5aca79be564e30f0a4ad3a01e44c79e63d8342dea2b3f1c9be20000000000000000000000000000000012f8dfc5099c08287030bc56d90e114fcfb92df8c88a4827f026560120c257333a7b33f07846d1161032bb8d6f9d6548", "Name": "g1msm-4-jwasinger", - "Gas": 30768, + "Gas": 38256, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f519184d70784b4c70107842da9a1d76d7b4f3c6cd2155f03e53dd212f2ee04330cb418b0a05378c1b51d45d52be79e00000000000000000000000000000000146f7821be5dda33e7139ec78a9454c534a125c6be4332b1490fc26d0134880fa8dc0ce14476648863ccb49ff3c223001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a35dbd7a31c32387dcc0f38545d6af66aea9f56fe527eacfd5793a0f0134b40ab4788b25ff1284c4791ffe59791dd400000000000000000000000000000000071263be3524fa82a2dc52f8d536e6617dff4677264eddde49d0e828d12d23d196fe36e0f10967e5060d5b3478d32eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036583b6b6387f9c6d0526bf1073ec996661a730e64203b4aafbfb0342e048fed94137da221fb8d6190ae717310b351a000000000000000000000000000000000ceed361a9188277704b38dc066675db2ad4e85d2a11686d215dd6c579ce3f79397c30814d0ce3fb79f4d535b16c3daf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001426901693fa83ce2c198d983f76d56f9992f640c760bb77755eb61a9212a7588c6ce53d1ed61a8f2c13a29f376189a20000000000000000000000000000000010a0bcc9b806ca9dd97d01c475d00cc8a9d506a630b5dc973cc31de2685fdd4bbb13b89543b4b7ab288a9b24a9faa1661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b486024be34d0438e7de92e8dc8bad0a24c85cfb89bd9f19bc9ac45fbb3c8dea6b8186f5527d38885bb50ee580aa1500000000000000000000000000000000044672326b50c038267ceb004718a6a3b95ccc0963fc858e2cde28e72fba67b4b5b65c9dcc0729bca2835d0859edc47f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000113448507e722b0ef404d34e2f1d8c4060c8fb4fcb83c8abfa7c74155e6f2e0e3f9def3716c0361c74d920a216292f2e000000000000000000000000000000000af9c4da1ba373f9baec6f382a69de22ca92e3244ee14a913dd439b25309852a0e8f3fd7f35252473aa5520af6f4bc7a", "Name": "g1msm-5-jwasinger", - "Gas": 35640, + "Gas": 45840, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000194200dc14a9804a1a5c1753c0841a5a0e3dc16fa991c11943d8d71bcbf04aa26b6ad3947c4f10bdfa4377f06c07335d000000000000000000000000000000000bb95b9656a97f5207aabffbacfffa9c309911822ac3a9468d9525e3896d1570de2d011df4ad894b1192cbbc8d385bb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b4986439468970c29ae3a584d0ed1581436ceb93afb782c30a0f33caccd1343d694347664edce63749435bd13fa48e000000000000000000000000000000000a6ec59c4515d6e90c62df123b5c60e635c1782bf7bf0f55eb041ab40549ae194f9f4cc3da33698c5a7ec9c5f5730bc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf32778d314765c5bffdbf6f98c21ded79d1a00cf1253d98c89bf181edaf5932dcb12a976c0fbe0d532c0bc396c202000000000000000000000000000000000f8f7041e2c8bb02ddae783648a3d0dbe878de4aa64cf3f7bd730c74e44ed976e1232dbb8475fa16fe7c4af5b15682ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044a18bcbb3e43bdabc51eec762e63fae7d7f3f5a31263efec1a51f82dd9b9da23b69ac8fbb505402b3970b94238184c000000000000000000000000000000000382bd8abf1ac4d697fee371ba0f775206ad1976054d1b28ec007f70cd0aa57ef6eb1068de195749b7a72e304ad074d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054f97b674dfc0f5660725badc1a269ddcb36f55cc03c4c8b29bd1f780883cbff14b8bfe18ab17746dde676cba1ed0a800000000000000000000000000000000174d7653690b4dc6b1d4b46cb6253472320db0288b95775bc9db08caffc4c9ace957f2c275b1c518e733e926d81b99241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4b24d59b070d2e5983e10b17a3b4f780a19c9df891cb558a1e3b479608ae87b9762351c108b6263b261287c589777400000000000000000000000000000000057af5e5f9bb829c81c9b860f61b6ad4a4980b9271662be215737664b5caa7dabe9525336b82bc7f4aeb24d8e30f755f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000ff76ea5fba3727d3b233bb6a0125eb3ed0ced6ac365775209ec6b3bacd8642987afe18b4eb25ee8d74ba8013b07152a00000000000000000000000000000000159e4abfa29b89b4ab4a6dd26751018c52fd42ff8562500e52f72ee2ec1360763604d1fdea5c81e168234ec90f063214", "Name": "g1msm-6-jwasinger", - "Gas": 39384, + "Gas": 54000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009244bb564d4cf8cedab0e183f70d316b674dd86e57073a94fe3b1ac13af3da384bce888f770be42d80b2ae70bf5c5000000000000000000000000000000000007f0fd12e870c65d30e620616828ef081b6afab6d44b111fd90a3229b6578458945e6ba73d0860095a3f69d8aff620981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151c24f97272d9bcdea3c4b817b6b95e2854ecd828f5ffc811ada89412072cf595269e525f41e0d74fda87b207750423000000000000000000000000000000000555a9169c7e3c650546b343abb8d883bc6ff6c61f23ba519f96aefd1f2e5da92d02c7026cda4a61938ca1f610a8d2291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017101412f7727228e6fcc870dc23f45d052fa9e090971b4b5861daf47147ff60506d4535488ef5a39ec80b67d4ce3ab300000000000000000000000000000000190d8b757ffb078d8ff89746715fcae23b50d520c7ccf5225a64cda87fecfb6cbeef015c647d988af11f8843cf36eedd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006b6da29cac72094979726a0804ded3ae24c3db9f8573d7e7b97312dc3346acbc22af61722623da04a59b8aa4379c9b00000000000000000000000000000000162f33dd2cc52527ef11bad3d8ccfe74d562254002134a8c00b7b1a7335b8970e8fd9d2d394de099c82ed2d89c41257b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d3ad6734f481c70b66f457dad66007bac60ad2c0e6e1439a55f413c6dfb8ba79c7b923f5863d3481b6f42659a81155000000000000000000000000000000000252ff4f00e375cc206e0b210b92a5f911336bb09fa628ee23ee336fea20e4ae783b7f37a671119fec0b8459c84e8bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099c0ce5941241bce6ab831eaf85ce2f37995a1e07c36d1415c7399bde2c7c124e9164326568171525df2a698a500f3e000000000000000000000000000000000d20866e5f4573ceb2986d0f0996237a6c743b4cb822331cea394a06f75e47f37f562bad478e559a9700ac3968a0c4161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f7f0920242ccd38b2c3f489dd45eb8e9d4f20e37b212bc8d8dbe912dbf81d35a8a25d5d4d8a1e84083edf8412105ff0000000000000000000000000000000007b5340e1decdbf119317ee913265a31d861656a167839fde1f674c81c96b0160f2afcdbda43f8546ab0b723f087a3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000066d2afb5420710cceae2f3e0be2a8bf0a8578dbbe31651949df004128d9c90160c844c8c0e872908449078b97bec633000000000000000000000000000000000aa07ad23d5f73608bbaeb5617d3efac71120608879542e5d76d86e6771bc8aeb2160627ddef8b7665d031bec6b29e09", "Name": "g1msm-7-jwasinger", - "Gas": 42000, + "Gas": 61992, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002eca26466a23e459022e6137af74828a4a043de76fd42739c291c77658117d4ccea4ed95a0e2d83cf8cbcb855fea1cd000000000000000000000000000000000a4dbb9da003acf2aa0498b88ce7a5dae8f6bcdeaa65e635c951ecb0f3de61ebd7d72317b9852741de03ae709c2be4571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090988fb4f98c8bd6f61551c4a95db33b0c25861a60bc98a7dce6e67f9258ba4086606990779b18db37af56566aee62c000000000000000000000000000000000d5bf1b2efa7711fb7a91dc7ae1941a06b424ed878e2db9726f710c676623f200c688a0160f2b848988cdafd0e26995f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018504266b12b76c706908d9d3fc124e43f0264c165bed121b3fe61a2279d86b7c2e9c2dd549b92979f06bcc41162342200000000000000000000000000000000049c310741619781ac34e1949d360a99430807175b5de87a00f0babc56427ac2f7168b3e69e006993887af60d56a7b7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162b1a58359f1f12175e02a456a604b68680b97362cf4eff8b3c62e7d6aef60729b5a9cbce9e462623088387c749cdd30000000000000000000000000000000008593e3170dce9d621ee58fe4c598144688b59ef4d5f5c886d0d395995d16c980f826dab9710fa6df84b271c0f099cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bcd8d6460badd9c853a99e6892dd12efb7592090ef876761db4ce696008743dc90b14eaa57936d8f4d29951eba4201000000000000000000000000000000000db8d628d6a4dc0d431e26de35179f8800975e1c3c8b633c8255c3a9024a3d25d4c96bcb062d1d56e4ed185d2bf77e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f89e93e5de6b266657886ac70580d52e3c16dfcf153c89a898e53ac914ff02adfcd3c31aabe90115d09230dfcb3bd3000000000000000000000000000000000a7ef19765b329ab16a780e40b09560af6e47130c9235166694bab7cc772938c7778ed329a2db45b385859308ed1357a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eae4de441b8d7ec46ac27808424284b797f0957d74b129ee36ed68b507cdc3d37065bd36cc7fa2a7522b20b6ffc464b00000000000000000000000000000000069783912b0317702031455240075555ce6fe238df76cf8753cac98c5151e408f38a3f097ae79c43f7955d508e84dc9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7d2823148c233c00121672db578930084bbbf8c33b048f0c9a26167494e698ce7c6c6f0e0aa1c3e4ce53f2df52dd7100000000000000000000000000000000062c22f57f1c4b60d9919ff827df171aaf43dd8aef6195a1ee3f33d3c25e040dbc4ad52c93ddd4b847087d62a209d59f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000004ef10c8626b08ff21c61076b379ca4a4253dff9c1531182008b9e21b90c5be30aaf2d80849643d89cf068f9e79e1a1c000000000000000000000000000000001038dab69904dc709cd72a67542aeccebbb45b1f6dddbf59e5ecca6380bf77cd9fa2731109043748e163cc64f070e7d8", "Name": "g1msm-8-jwasinger", - "Gas": 43488, + "Gas": 69888, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000093f799d21b03bb0396b88f50cc0b1ad84a1b1c6fd6031d84a80f3fdf3a8e72c0ef09499dffb90c681ad769e0d0756bf0000000000000000000000000000000006ee1909818c0b316df9d7a26f65a917ce144e3bb117e7352af708042d692056c2e462deebc5545452c2edf09b5ad9e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b536901fecc0449e4ddad02561de8fdd99b1f83dd74555c4ee03e9c809320b467fd0d3c035f5dc11014475e8fa0a63000000000000000000000000000000000c82e5b5985ade16e31f91180d8863aface2572c580a442055866990e3a7149ea3cb36053b64326928734ea67f5fb71f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6d5956a92d615a4dcd439c1c2ec61157805b30b6f6976b5b6e6b4cdbcba9d109e42eea22e0b3c39bd09e4c0f29e7d60000000000000000000000000000000002906bb6f7b0061b73cad18f81a9c4ec5fabcc283cdb55321d19ccd877873bcbd753c1178023dabc49f30578c76480cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4e6a79ea06e3f2edf0ad18aa44b43e970336ba44cb563c7d10d3a4e32fd6a2353079f57cd702e951c7c339369b375a00000000000000000000000000000000116bfb996e4eaf4776a5609f49f53013b170c90e6544e3c08cb1416774868301e8046ad72087efbfae352a8490c498d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e9357f0b3845eaa905e4f7b4eddd22da9832abde56041d2267271cf9298c9cde217d8d18892856b53d782812a5b48e000000000000000000000000000000000a7381cf76b51a880a95341720109622e289a01e3dd79527f2338b7f94c7802c64fbdcc251fde45a76ff423d0c1342631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009610461d9ab363ed7004b567a28ab93c46faaee8dd648bd833c774ed5537d7aae3fbe9ecc8677afdcf1f898512dfcf30000000000000000000000000000000006f93c06b24123a25d836fef217aab76923f1aa8d0c382c996ef1b9644b295d896525a6279845a0cb65eb1ee506228d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e04a45349aa28f6255864f8bab0885f1d80d7148a979f8501950b04121df1aefcc424a378fa07e6d0c67ad06065df40000000000000000000000000000000017d0468f16ed765b21730dc9ff4fc17b6564cbadf6c1e42d7e3d0f4b1b1d16ad1702464f69275e05ed95697c9621a1b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ac61fd4d99d9091a3333542063f5d21499a6c658dbb08f70dea7d4c3d8876be7804ac44e545ba8b27b6834518f720c000000000000000000000000000000001273a718507114158268dd9c27f951dd49dd5db3ae8ec4e5894c1b6710a53b00ddaed67767266a600ce4347473da311e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034da7f8a1e35fc4e5bb23225f8a7cfff284733bc337f38034f7580dbd46cec87462d12e7465a77e555fa6690a2669d8000000000000000000000000000000000a482a1d6322f5a9c9a7f1ced8115d72bc82f1e15a5557380cf5ed772bbc818c247d73864bc82fa3c4d6dd558ac97f381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000006a4260eb4ac7d806b4388d435bcd66b1184dea4ea6f13d70f2f272e122df4216a1b867520a5f4b2482c09b2bd7b55a10000000000000000000000000000000017727f0f9b7f1f49ebb8c2434ce1c028ead44f88ec2c9e8d7e39f4fe708d5487f2fe7a879bec6fa8a2926b4b8ffdc69d", "Name": "g1msm-9-jwasinger", - "Gas": 47304, + "Gas": 77652, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016705211c92899c825453eed6736a6e28583f896d9877bc8a876408ebb287b1683af65277bad546f7bd282029e45ef110000000000000000000000000000000010cabcae88300a6593f82511ea4105fe172aeafb34a0b4456714352a0a1fadaaf1310d38a8e29abdeb6aae8cf53a77ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019df8e0065b8726e509ca5a161e89423ee15976ff3b85e2915a1e495ab24a7c773d4da0e33f72c17d9c7b33ab6fb47bf0000000000000000000000000000000011f71bde9c996b4f96da6731e17ba1e226970c4671df38ebf322d151b8e9e1a9bfb2cf45420740f8233519d66b0c4e101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e23874b2f986fc78a10735e22c7816f1ff782cda99abe24dd89470aafbdad09dc539f21de39dfdbcdb1749701d08c6e0000000000000000000000000000000011d2be3742e3b1544a225fd9d2ee057c65079d8fa7b1573e835a17e0e1819d8e791bf790c4df21903d6b9e0092bb0c421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001846b75fc5fc7d5c1963e78544c8b1391c9d72f99c00c60bdbc113734729322da87c4f7adc16b72420be166da80013cc000000000000000000000000000000000a4cb50cd41b11ea6e1b6743114499ad436a0b42f7fa852237df2f0efc0e9fe60534e6cdc5992e29bb92a25d39722d9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000481a03f574bdd12deee516a98e29f6588c85e7e78103a5a3c0992f61fdf1c359e5bfa819feefb3660321952a28c9893000000000000000000000000000000001395bdb7c6513d9cf92034f43d85239f2faf0c0e203b68120256463392a41005b3c95053aa29450c330273b218c2efb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d22b452c7228b55056e1dde2680370bdd0fc832adbf5a84f1b3148e0d7cda9f43dca5e93e23e9f9292a244cad202ee000000000000000000000000000000000303af535724493f64ca6814db8e1b36efad4b80cd2ef9bdd892b0b31674a786402c948ac41f3e05496fe34e2b40edfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105e0994b703afc218288a7ce70f5b1914cf40e4b5d048772616a31d787041ff82146577b615e396c20944c8c861deb60000000000000000000000000000000011b34269219b44742111dfbbc4dbe1edd369d839b814c3230986056a67b16b8b0866bccd9527ad031f9dfc5583d17c081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000706305ee8421e2b0440bcda446d3ee12d5b2113407039f3bb05a86ad993bf49a1a7304fc05e696dd653aba612417000000000000000000000000000000000000c29b5f70d4d3cadb847e1656217a5d0ae4c7a3a30c2765f420ceeca98aa51dc8c637ffd3ded037cfcca0f8f2853ed8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a170c581f42bc25d5d65c23027257a60a6695e4d651dfe04bd6f2bc9af9f259975e9422be97f34e692aef84d43994880000000000000000000000000000000012ea6518a398181e54ee077a69a0aaffb0f3efb536b9acd6fc84f4e0a08e9526252d0f1a1b58830fa91188a4137891251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bda8c576c73f6cb981dfe5be4a06fbf5179a5fae4b116acc77d51eb058e1cfc5bd6d0731dde2c08d35924c6392527e000000000000000000000000000000000c39549eda06719155da7e24b8e2017d13646be8798350b533c5d7572f1f789f7f9df6feab49b82863795f0b71ab08681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000028b7cc37f804fb553158bfe8f5fc08935931f7efccea159fcd9c91e443803c7833868bf09a2c94a7a91ba2cf8ea4f3300000000000000000000000000000000123bce0576a8a414657356a85c8245c80f0df437c91430826929da7b86ee404dd52bf7c3f452052d4f5541764b117f15", "Name": "g1msm-10-jwasinger", - "Gas": 50760, + "Gas": 85440, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009521928d219edc9ad62c5af4e79632dd5f7dd2b2937fec1c3a255a9f57b5ca03a64c34583fb39006a0649f6efc23f6c00000000000000000000000000000000074f86277eddfcdef246f7e09f40314c73c0f986e112cbbb54d28e5059d699ad75523023ab9da78d076a4945f995ef851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f804a2cc57817f1e0c423f2a33db2e40a4104dce5c37ebf4386a92ef9c180796f211e0fdbb40159d0ba089f9b2259e0000000000000000000000000000000013369d33037d63bba45803f952617f2eae07fa4de6752c5ecee6da3ca4bae3ed651f1c5934622b7ad95c4f3aa87eb1b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054d18d6f239a706252d62f06e2258a781fe4d75691e145c86ed333e7471fdb2ea123ca5bd9ce9adebb06d750b612295000000000000000000000000000000000b03b3cc5adafa59ee58745acd8d49a36b3af0fabc1e0014d99871c8fd06247af2077259f05ee400c14d7ed387367d6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ce65ffb1806ad6597457aa70e78b55a8e725f59dd5d72b48c39820c35821142f5fd5dad2ef7e42747cc3595a7e016c0000000000000000000000000000000015942a64bdf367c5ba728b57e0c4086323e3d3ead5431a7ffb1e98939b5017e1d9a2632009656155063e177a5e4f998f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a55a5f3a2177a5eee23598914faf60d4a99c8e0ecd4a2d152a13c9961ed14ec5ab7a200b2b02e319f83e3f8b9753f40000000000000000000000000000000006c8b88804eed3823bc58dc0362f007f91fdcd067473a519c3e17e33ae43b327540022e6b9dceed47af398dac835bf321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d197fceca7aff1f830d14631ecc87b482bcd268840b5cbf99b3f8b94c5a65e4229b47fa3bc66e5565ea82e9df266a49000000000000000000000000000000001696d53e95438eb1fc68131067f15b0e9b771f4d2cbc6731bdeecac36c4ab15764ddc6cf0c2a22c600abd7bcc3561c2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057f04f02a1c1ed32b1d33d6b12c8c762d937803bb752793be5f34fb30267ab1fa73c54ccab2391ab1aae3e3dfdac3370000000000000000000000000000000002701e4c990328f2fdfb76f0660592a5c683401e4c9ab170754372d3c76fede1e4616228e96228964b9e5bd0d4e3c6e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5710e3385836d44b714df25b0dbdcdf198707ad0bb4ce7a85d827aa477d64990b025a4783c3ab42580d993da91f24a000000000000000000000000000000000210bd6f2003df037efd9212039b424f672ffed8dcd6986cf33d2b21b56625b32982cecef98b0802ba004ca1a0226df21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106a24548ec98c349e31d5acdcb6e1378af44ffd2fed05a4fd41611b7a23c577856675c0a7d9169b4a36fe521eb9fc33000000000000000000000000000000001495cd8531f9c25f2093d14e7df3251b06657afa0a8745f690603d295db20db226bc3e21943d576e0d87c58a5f9846a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136199fdbec21b92f6a23cab8cb33e4e5d2faf21f3cc8a279426ab64e86b34fa7d8b36903d3d48c44804b727fc01d78100000000000000000000000000000000128817bea4280c89efe1d6b3b9bc9ee1901d12c50b7b980c9a46727ec6ddcf09582d29068b46d603a8f143938248fbd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000734f72a55f3ef3f66aeb4fbc045da7d6a80efec8f4256938362180721e9258f0da6c7423a8b6506645aa7bdf0e8e60b00000000000000000000000000000000125e4757ee88db9d2a943e18dbde7933f96dfa76f787c355c58665e7bc6b260abb954b7ead5255dc020e9b699e39bd6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000043bfe6fec13ed186bc5550ecb89f3b2de12f10288a59bf8c0e219b64a4f3da72e6e38dcee195ce0e573af09605b2b280000000000000000000000000000000003383e3d2840e642f81bf1df6915dd3c37b810bceb15543de997e0199a5852fb2b971d11a1f634d9e8ac81e29a00c316", "Name": "g1msm-11-jwasinger", - "Gas": 53856, + "Gas": 93060, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ce81adf86a553fbd4454974cea6c989c19c447af5f874f469c0d5355039c05a2aa2b298860af6cf23a24d11e7bb613c0000000000000000000000000000000006539b7fa1ff62255ef80c43d26dcb71685e86c8a1d088d53e254866aeba20ca53457be749306b21d56d6086475fb8ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007067fe2a228f0842ecbb7a6388e78405dbd9a1022db031a9a0f58f11928dc34913b7ab13a596adf51c51082e722acdb000000000000000000000000000000000505db0adf1c0e5faec9596d5555f810037b9ad5a2ae1b5668fd72f52228447625a2012e7189522d2e1d7524f73d81521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131c26aae83661017a32e22ce388f12d362609d4ca93c5266486f601bb0ade1c2cc6d798ef4d1645268d538e330e6014000000000000000000000000000000000e8c93332bc07915ad1057913c698b924c3f4237c7532ed9592923235c540381455aff3d28030510f0e114a5b5c8a66e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018157dd5c5df467282b2ea8dbf696fb9637bced360d82c569014ecaf7b350062ac7ceae22d5fe5f25bc6cf2868308ccb000000000000000000000000000000000394672c48d0590cf33287fd741ff1d366cb3461ad9511d33f4fb12b3059fed7f1c2884e7fba65b932081b49b969868e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c0e480bcf4a92835b46822d796af998318ba860d8940c542009e95a4ee1bc92c97150ca8dd4eae157de0b39f4fff8e00000000000000000000000000000000010f3cec81c5979d5c9e622fe42fbfd7ad7f1e7b406e1e49c1b7632a1aaf4b1aa79c02714480806db4f4b6361443f5711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055042f2406721cde522648f08fd1eae26913fa68d0d481eb8f4dca1b0b6fff5b09e3e17cd997c122dc53f09dbf04c6d000000000000000000000000000000000ab21421a4d6895b91a5df00cbfbb6d05f83a8562959861ef4be796c40e2a6be10e6612e34e71800abc9493a2ea341a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff19df95e0f477f6b6c16c7256b9910dfd857892232b8d87e1de9bbd4799b69b2e976078001f7f9f39afda0a747134800000000000000000000000000000000021d1057956fdb34b36dee4f6ec4bd9edcdf3e11d8c50b9ef0daec7b444ba649d7da7d6718f137425f894609487652091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fee161b3767735eb98ca6159fa9b125f17fdb1cc135a9b6c751ef1d22dcea595b47ad76a0d2f8b5b7713874c9ed668a00000000000000000000000000000000196a79fc2c12a25d2702a0efd1804c4e176e046484f34f1064e6e2dcb3ab217895ee0dca2d4c6ffd737fabb9d98f40c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ad6467b9e249333f8cc744c7fe0a87fb6d6d0d9f538d5a6c344a1f07b4c2a0869e968ed041c4df33667081b318c66200000000000000000000000000000000043643b7310c753a2b48da33bccced892c57e1b8146db9ad746621bc014bbf489efe8dcebd247d590846b6791ee02d041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e001b324581503e1b1e18e13300b3c7616ebfbe9723cf71375da30de5e2374140f7aa6dda50e482a05325a278722bea000000000000000000000000000000001520e9dd009ee5086839b348b715f7ac8bb9bd20e24b1b52bf4660561cafec72fab7acc2bc4227e79be4b12cc16901e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018029c4dcddb7546219af291e66698484890a979498a95010cccb0ca818a83476a07b9aa4cfce30484eee2964fecd27700000000000000000000000000000000100a2e6f3666d850c10ba8990509e73983ff6085c2568ef092129566f82ab2771da25d6f491ef9bbc2b878ae61df82b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e80fc17b09a759f6f7447f5102b672717dc20d776caf07062129a000177ad2349e6a6639af4dbf68e5300474cc9ae2b000000000000000000000000000000001838e2d26a29b8d019e7be2703ee8b9baabc76013126223877ab067abbe1508bc0b171d130e2dd36d9d40327e63712a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000253e15fdb9bcbef253872cb21bc3d6dffc855311b6c03caa4de21966c467859a368f349d836ecd8b92f9902529456b90000000000000000000000000000000019bed0c957c26977f215587aeaf1d757b8895d1104202ef8f1d3026386bcab1ce917dd336a37194105406881b306f15f", "Name": "g1msm-12-jwasinger", - "Gas": 56736, + "Gas": 100512, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008721597853b86a7ba46a406fbdd1c3d1adc764499ba1c1ae652cf45c79ee91c0e95eb081053e866d0d48241f8cf941100000000000000000000000000000000051fb8a8cbb17baae38fa575ce2a46c6597c7fabef6f449bd8c011a4c57483ad0aeea99b61c5ab68226c167223b19ec81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a928423212136a0c5d5b7fbeb33b30d1f1b0dcfd736e93e65b614572ebeb219a9a0328b2a33b61f99d714889b3dc6920000000000000000000000000000000006a889cc23060006da36b44834981542580e9bfdd482ad8f13e4af4c2df01e70a0d39a37119ab510b4aabdd83da591861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044dd71853073f677b058e3f22316b12a375837b04d5b03d2e21a25b9d7c8afde35c35a0b83990262e8b2a66a9c6f0f1000000000000000000000000000000001657a16ebf87ac7df3ee4f8adeddcdd4db1de13c6b69a1f7cc45610ef44a9deab66409af49e616f251740570494c12771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000275ab91e7bf0fae793ea07679c98bc5c15bbfb3cf6e3ff0ced124dbb33a7ce844cfe2d842cb47a5092389c58e1e63800000000000000000000000000000000002543d8d5a5f7add0f96378fb27b3fa1adce7af9517659590b8034a4c930f1b773a01827c1678a9ee89b131ceddc5bed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001021429aa92759eb6a5e783a9eba40302929b289ab019ba22ad9c960caaf68e5edea94ee00064fe1b43d638895172ba30000000000000000000000000000000004cc0c70306fb9a0b9d13adc00ccaf6e1d25600be21422782a4bc3c7344413dea62ce71ce774aa9c34633ed042b151f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000810a1164551bfd6bce1e1cc2e349a3ec0522385e274ee8ec9a1fd3fe12e855c1848db0d01f5481353831767e75893650000000000000000000000000000000003cd90e71e5a8ac70d17eaa4d6d1c453c6afd9b91d4fb37a4c404919555790d35594a278e12e9f128dadecd5af68a0791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177205ed88acbb6c36e82a124bafd3c84bef87f13ec82edc52fde2914e0222e028dbb9b93c426a6a5abfed569c6863c70000000000000000000000000000000005e98c22e98c416920c9f8e87b2ba6312347d9aa9774a0075e926f888351712190fcca351d96f68b9636aab48489013b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002b512074899ca5cb6b9ab5a7d5967b6af8a28108728a8da935ec8be0ab8873b79516243b24c097acc0d06aa17c91740000000000000000000000000000000017b9a0b0b74d7161bed182e70f69a863bd2e048039d2d8c5e2ef6694fe0ccef2d868c914b44af30b2c08e39518695ac51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030f5def86b5299699e89c754eb046147987eb5197c314aaa546fe9142f24af8dbd582ae28716013a9c843fe36e2527100000000000000000000000000000000130c289b7077149950c7d05b8379709f59d3d6adf8649d46b0ead5f723da9a0d99aa0df2aa1157d3fb978d8fb0037d2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ecbd2e088f2b710997439a9bdafced514445b29a638e0e3a2fcc239448111579c8497415d4addf4bea3d369f0bb0a42000000000000000000000000000000001657cfee90ff4e0701a3f58ad4ed35475bf711b8042ce8c8335083998302c3d5a36854049ba55bd991fdcc5c2d7589aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a0f91b5cf9eeb4e090ad121a2a8ee8b8d0680fe5b151a7a1fbe7ab85a19988fc1007b9ca9ca5d972e71f6ed22bba9100000000000000000000000000000000128383913c7b86b788f155f4e36fc8125e4d561e4a0b80869b014c9d3cb100deb37f2978fab2f9cd5406c43cc06aff191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c00d041e667c436cfb822bc8f8a743b05ae2799bfb2d32452ed7b3dd2b45270bab82e7db730f50af6e0373d49a0ca95000000000000000000000000000000000b09b5a34537aa0a47a65d2833413169549e23a888baa11c65a2f15152946ed1d0204fbb5bbe03a8cd7fbb8ba56a90961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006551944aa88d457cdf9ae02f55309be73b67132901705ac168ca993d23aa2c81ba431b68eaae98dfbeb300e819f81a3000000000000000000000000000000000e9286c999dd43f0977aed6f68daa60d91063193836b981cdf183e39bf5b8df18e1bf5263ec9443961b08b3ec6348a001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000f9aa7c02a39a03692c818203ba7190ebeac8daf7036b9955b7e98c45efdbcbab5eeb042cb06890babbf2c8b0bd7fe8a000000000000000000000000000000000215e04a2f337c247da4c8c1f2e0652fe50e15fab12418620e03ba840614ff54457b31632889c1aecdf6eb8deaf3d2b8", "Name": "g1msm-13-jwasinger", - "Gas": 59124, + "Gas": 107952, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000164e9d07cbf6f92dac7bb20a6d60834979dadbec525fc9ae6a0ff8b23ad9d4c22edba6b93aa10bcc2b5a948fdc581d2b00000000000000000000000000000000086ed6d730ea2f98f6e3a2056672acb46c1952eec136d1ccf3d02a13107f71fd9160736267f2b093abb781f9e91d417d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007484ab08ddcc18eb8e7f9b5cb9e48ddfa36f92c69526dd01e85c273dfd0e705cfba697fc5cc93cce3b7701f830a9618000000000000000000000000000000001000cc4aa41ffdeccb61a3558f69a348645b2dbacc259273cd7da2a2f05fe90d46c4a9bddeb734829c850af7f902ad721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017d1f7e469754ed995feb9b181dfcaa60468d8fb3c169130e71d50c730d88b6aef2a77d58b660bf1478e029f82e0bf8000000000000000000000000000000001862a54a708da0ba82a5696bfc69e5dbf7fcc4fae7816e937bdafc70e0dcf1f91657975e8c55310b5ff032193f4429631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2aaae336a281d5f7599926e10aad8451a629af6f2f9a33a01d506b8f0f7b710c34c8922c499f689ec136597be60c360000000000000000000000000000000006262b6cd9b4a241f3cb5ac8494b71da1b6e7af3e2beb5719aa60572586b7df23b57663452aee9393984c84c7c2313321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4d222b477873d394f07dd8eb04d69bc2ba437b0d0bd53f6ea137f1f826ba89f1e1f2047e60a05f10eeedf0b0c7056f000000000000000000000000000000000dc97f5761d0b791cfaafc45ecb868f49a47f28ecfde4249f60956d5b2ac72a4388804860b7e2d64b4dbe7d33539cdeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001143a6c321182045d735b3eef8799d7a782191b5c4e5ea0a7d1df67e70bd32570889219d776679bfe4aa700f54a993be000000000000000000000000000000000dfa65fdd47a2afa608e080172f1506504056f01b0712551e5bb9b354ccd5f0760796a76270e4331f3074fa1467772891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019af409ca1ce865d84802ce41f280626c43f7d7747ec82ee9eba82f5c9f47d9329cbaed9cd33de32b635d08dc48d9cd3000000000000000000000000000000000646a4f6069d1cd3045aeafd75ca6b0ad637987da41dc53989ff75be2eb55b9959c711dab9a78147115a48ef23ab0b621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010719d70a7e3d0a90420eca3eea4ba27f127b892b62d1002014b65caa879a575cd3e3c714fc47e2bd2f8190327360de8000000000000000000000000000000001685b6fae8cc481a2860f659dff86baa5d557ce7209f231ea7258eb2dbd0ff202ce85a37575821227051ff8f596c273c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017931e6f7f77b3506919f09514dcb1915fef15d8e82a9d4ff1f8a97e34c3fdc0f02857cfdde23acf57c9cebd381d63a70000000000000000000000000000000012350eabea534e4c6bdd0b9630120c07db7d8d610da988363929db7621c3e02b44b9b80120925ca7a3c87f0df06eee461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac190f7cfd3d4ca30f8c86399992305f530e4b111ee1525621d65492d61f25372fafb6a23faf67cdf08f47268a6203f00000000000000000000000000000000155fbcd718e64c1466884700e5bfdef62fd842df87b8a6fea1903808b32c363ba6acd741da366004e513cfe5102444ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d5134fc78edc9c3eb0b2227b1cb1176296cd8d8d60ff6764279935c7b4dec3d54dafbf37cc2e4f2269015be1326950000000000000000000000000000000015d09a037449ee1b9750eea805ef51ae5d0091f903313867096d3115e1e8986fdd9e24635aa910c36453dccf94ba848e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000951a0bc7bd54c6f32e2238146a32238f017db10bc8da86ce6b817ee2376e6de631ae56488151f34d07b2be60d4494620000000000000000000000000000000017d8b124eccd256dca21877525d3a74da064a9ad7dacd49f7401b03919100b36b9ad1fdb0c3b5cc7f0cdf0a512e2b8951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045f269e23516a34784e41de132269510a328bba7ac6859b14bba872bb4d57761b0c51f4201c1480c5507708a100d3c9000000000000000000000000000000000bb57a30e19ac91c5095e0baad738f626059cc2e44cec6e014e8af95ecde72396ba50d9a98a1733bb0a131a9a6f767421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117e91aefc2094d370363f8c727c2802330f3b193f9d14851f0fe669c12c940e82e2eb9758d78daee09b137a4b447404000000000000000000000000000000001380d34ace5e0bece88e5a4c59c83bfff359fa0f617cf74d53cf9ab89cf6d4d72b65897c076ef7851feff9ea6ef62e3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000001203654f7be8ee24e8577d141c7a4b1a35bcfd5dabc6a23ee0ab5579321c01396cef8e5b72fb6436a204eee63bafb47c00000000000000000000000000000000022fccd7d3ab8ce938d46bc1a1e375fc53f6190037959b05ff5056259177da83924f96e2418945be939e8fbb00000471", "Name": "g1msm-14-jwasinger", - "Gas": 61152, + "Gas": 115416, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000671a645b2e6dc9dc0c106d2ed44c7a9faf9ea2d19ec71019d4d7c59d44e2c3c4be27ad2c274cb9f3ecaf0be5c98963b0000000000000000000000000000000017d8a4d07bdd30f263c9bcc64c9caf6cb59b7b7ac0d73b2c641c3e733e5d3177ae17d9f9c76c7f43d1d41171048ab6411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e58c7f079888684c89f863eee960496e00890b1ee49af1acb8a2b2eaff2fc95e0ae4df9114b10279c3db6fa97ef8a500000000000000000000000000000000023ee51d4a8ce170851f42a098da808fd5e37940866d9268e19d053d111bde34081151b6722089f191b319d7befe2ba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcb8e9c73b01a863a4b94781f2cf8176e0cec3ebe8d5ac601dd667cb0170a366da1cd390838dcd22a93e734acfe83110000000000000000000000000000000014b2f45b72ba14ae5763bc9a8d37f8dc4b8a2eee94a0704236b228f7a7b43e8e945d8aef9bcbffeee7c7c9d791d4379f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141a02c583d179d1dcd43ad57f81d6ab7f0e02aaa840db78f9bf8f9bba802df4d32071f80d7d6228acc092f8401ac5e90000000000000000000000000000000017cef78aeb96b0483d1151d7c12760befbb9e89c569c8c95684d7fbe4ef74595976082f755707d45fdda9c8cbefda8751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001057c7bcb62624b8b85887c2cb3aae0f29aba618ef014820c9a6d4d63e6cc68adcd1486d8f0b87aecd0e800da44f61a00000000000000000000000000000000197cf504149808f5c879138cfd09d7278a333d6e1486020571a5811303d775013c5a2bc040ecf407651c711cb6a66a041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fed276bd78e056c71f5750fd39f5612ed523dd4fd1837e465afe530990a193cdfdd339d886e050cc7d666b854279a40000000000000000000000000000000005697b3f45e54f248ac5a7bd7481c1fdbed3a43ae493e469aca1eb571134ca3c47a21afffba7498a0a94651fdffde4c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e4db89ede0d42db8d7043ae68c5e9a4a82c04152db6a895462facd84f49a43c519a5d826a22b78c3b7e05611fe4fa50000000000000000000000000000000012a819206705721d30412f76c943c655295840178ebbd558243f2bb645891a030db8fd492593b7c1ce223e76215fdea81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001567ba907e1a492d8b02aed55c738c21d24dc27c9de7644226cac21759a6efec47e7e0ee916a6699b25259d4443267f50000000000000000000000000000000003eaf55edb9579b76445b5d799dfa46095aeafbb30deb40bb6f9a0d4265a02c0f85cbe4a91ef023f94303b3e1030af841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029323c61dbe4a0290fc5e5415517bade938418a8710baea714e9726d2ab4b1fdc787a300aa52d79fd09f6acdc6241480000000000000000000000000000000006f9a817ee473e510bfd48f64e0e5af3fe2d1a8f4edb1b2b65c57fd601bc5df06eb6de0e90f968a8e1642d312febe0a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005cff774d5579c4d9aca6063cf700c8d909c398b9a1cab0211762f75d8be55f9d914eb86a68dfe1f4218771e39e2f430000000000000000000000000000000017325b534a0ac721f83f18495256520fbb70d2b14d8127edae5f8a9c27b63c16a2646a4b92f0d5bd18c3158b14e24a0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168a530d4a54626c8d01b8e52a24dc3bf6bdae5fc8c27e766c8ed7282835fd71a9082f8f27ab39ee79f2e1c9640512ed0000000000000000000000000000000014734e4a53f760b96c4dfa7563ecc977961343920fe0b6ffe2daa606928ff1af5ae7bf1c95ebb11c5b5f796390cae1d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c685f25f539c23945d55b025fa49f006fa406a70101712c34333bf1e931e73a2bf54203e2a481a2441106f5f2170a2000000000000000000000000000000000dbbb1697fe5817a5bf89421dd6afb241a696872c9996c92b6372f258ad3b540ad04ecfa5b86189dbaa25355b4278e441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c4f2b709b765dbb07dfb934e163171632eb1dd02663dd53bd7e203cc4b2368c3a2a53d10bc55597f2f8f1aeb9fcb4000000000000000000000000000000000f6925f067f72c5184281e0b410d38e1b95afea31d28492ff3f22d15ed7f1364793bb0e3570374d0ef411f84feee730b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019584436d1b4154f43b64fa3d870ff809217bf12a3cb9ac364e43e938f2bfb566c056b44df1bdd1c3816ca05bcde3ab6000000000000000000000000000000001741ef532f3869c8fdd586f23e647847bd108e65ba57d35334be69767d436ca75d11f15c1ae1c267ffd6edbc232d33441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0bc8cb8d6834dcb4d69235194033819e2532693324f712f7c1be7b23c16b1e5cf06ac835b88a2895cc96a528769c820000000000000000000000000000000002950db7b91bd972c58dd047ba3621d5c3b83f20e527d45f6c840b4ae9ca226fb00d16d6c4a92c005f9f4d028661062c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000001883c0ea7caeb5a560d871deb72318417e032b6a9c1fc2987e9ae1ef90c8db336ad093e71781352197b806b41229aa500000000000000000000000000000000003854e857850e05ac4083624b4c1de281f2bc308870a2ac28f679840c8c1a5e9ce6bcc8ed4caafd8b40ac3b054f84551", "Name": "g1msm-15-jwasinger", - "Gas": 62820, + "Gas": 122760, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e36a348a4daa3cf19396d542fdf3f9464daac718f26b31b16752639d4335508551ffc4c36f1e2a2f68157f1fd588af000000000000000000000000000000000171124d2fb1ea2469680158b8a1c830c573e99eb60f83da6b72a9b6bc1aa85c062ba38fa6eff3d5df31d2e64fdb846561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ffa51fe8bce43b78da4a9c27d85061f84baf877567ea9c3cd0790bb129875b435264f8555ec36b15767f88247081db000000000000000000000000000000000f75f654a446c36ecec0c6b516730352ccdd02d82717cd064efa82b58ce45fceaadbbb8fbb2417d162fe7f03239be7a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c5d3d04604deeb36311a8d36b825d7604832cff57ce3855e0ee418256d7bb5aff224a442de20aedd2a306a29ca5f2b0000000000000000000000000000000004217eb8cbac66bf3cb92c125c915caefd81b221930fe022b6c5cf8db4c94cc89decc0826d296ba0b906f22e461da8911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073fa905a9f5b38d5310b606d816c61af5e383c5872ec3e3afc57a628930b4bdef25519fe3463b4756b9d7052fbc93d900000000000000000000000000000000115752501c57c02162fb31325971d58a51c406925e576c6cc641250602bc6a3b54904dd38ba46f533b01f8004a688c7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197df8acc92b88c2395f97fc58a34f5e120fbacea5ae9ffa1bf7dcbb4bf6640d13e92bb99faa3feabb0f5b2610ccbc950000000000000000000000000000000001bc6d7aeab1df541f592cdac4a1366a6e4293ed57922866e1145e7297c5ae28508985127913fa33788913c2e0af77711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff66fb8a9c260d1bbe4ebf4bcd6d079b10d2047ea53ba5d49d119735bfc8e152503ba5106ceb8261f14662874286a640000000000000000000000000000000019a4731c96992eb07d595bb2a3d53e81230a53774c676cdd3e77e14aa2dce9ea9c27652b27c02b8fb3d60ef8c2c95ec01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f54c989e66350dc4d79b113236a95aa1bc8ac3f8b0d8a0a1d4b358fcdc8f329c8e73b9f41cd4bf1ab63ab2268282bb00000000000000000000000000000000137e0dbde2a21520fade2ef6ce8405f814db4167f290e628b5e1539ebcee9a0ee8aa83de3f69a920c5a445eb910d447b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063df22d372a24fb60366f793de7bc45dc92dee2594f3a72b1ca8efb7175aa8f68a2ad7fd1ee5853e041d36308db455100000000000000000000000000000000071cd08097bc2002431090993caab712398db07787b88a506d91388bd2abb8463cad6d362b23113dcbdbd808a99ea5ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b9e2a30b12883961a53e70b61095809201ef2aa42c91072ad8e5581cf79fc54cb11981fb67fd654290a6754c99cbb700000000000000000000000000000000147b30badb1544163f0f81f58f35548b72533affc4390a75c11c3a70be34d7915f43e345d171e2ba4000ffaa8602d8f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e5d437f6b8554a4708fc0488314af417a7e4d8af0701d16c69aed13282a52cdea7afc912279102f5251914d09c4e6600000000000000000000000000000000187fa0d3e59f19077d1bb77865061c2a73ae883677b2dcbb651b6c449b586098b40ed82fad839c5cc7bd5ba73d93ad211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bbd8101343653c5ce16b4e721d6315cd180428980f421f291c10e1c6a0f6b5d5ad5874648aa8cd26f9205e0f5b564d00000000000000000000000000000000032f89866615cd2a6781afbd16152d4d08621f4733c6ff60c669402b42886fc47b4f61213b85ebbab14f51696a6cc5781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098b50dc9c786d58709c7b7eb63df3d6dbca3a20c30d46a25fdc608dab5fed19a73bf35c7a2c1d39d1592bbee1d593ce0000000000000000000000000000000008b428ddccd19d127e5ae369cc9f674e9cc2d78f08aa99b1889c303e7743261de3077d3e69f10554bb6ab2ada1f76c5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be237a4f8aaac6425cb972a7399bd0c2b0b97e2db05509b12c4ea52de42ac8ceabc28d486eaeff2559c5d62dcd0e5f900000000000000000000000000000000072f19779873895c0cc3d00b1f5d20dd0ccf6645c98a34585fd464537f07c7017c5f54de1fb4587ea0b2e0b7a8f561c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002946ea43fd6327ccf34ebbc0220eefa96478ba18765ee3cabd595c91e63cf27758d0d2f14608ba885b0b422ffb9152d000000000000000000000000000000000db1e990595ae59cf498b8cee67e500439e4bda192754ce46b3b9c515da97fa67472dcdb3fe469231c22aef6931bec971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163ca4a71d926baed3e458f84aa5dd36ce96fbef320dc323aa1ce42f071f2b32376fe2d6c66a86d37ab78a73d788e6030000000000000000000000000000000018d200acf24142deb5675e3eeefcc15040d1359fcb7e8a1515c9dddc661c9d0bf83f0c6a931cd6cc4000c15c752c8f911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069ac270cb712656dc8745e060bbdba2cbff9ada910ee1670f2ab86ef5e9b1896670148f4f81b31b070ebcc14f2c0e800000000000000000000000000000000003d7a630148b77baab8be499d06efe3620627c73f5895aefb408c067c36fe9d21c66f7dfd6d84b654b45b84439c009911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000162b81ce43d3df6ff618be50cbf51d0a07c5ca8b5a9488dbe17d740bc07512604c459da7900447c0738d9dfc3a25083d0000000000000000000000000000000016940839cba1b7e8baf9f14cdeb68a7c57acc4e83f71b7a242e066088ec17b5a7e84cc6d1cd73341b74143f91c06427b", "Name": "g1msm-16-jwasinger", - "Gas": 64128, + "Gas": 129984, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012da2c3b4ca5ed4470f16c540fab8954dbf1a61a9f1d2cc521230451c46ecb6fef6be9335354887d311b480ce3abafc30000000000000000000000000000000011786226634a6969aa8844862316ed6f3d5036429005b7ea60d07c1ddb6558fe8ad6712a44e546412dec471d192881d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bad347bdc7ca3a9ec974353f5ff697c13235625e88fd5d9c775bd05cd7e7afe2d5cf3e64e16ec05300939751bf3f5f00000000000000000000000000000000131b7858197c400514a81047de69af7698d3023b317e08939cde83e2f745e147cb217df4ac61a2db45bdb787cac6675f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061c98a4d974525ab3dd406668795f695600e558f118793562d99debd1cf2df5a4085ff15aa03713a76670056a7fc799000000000000000000000000000000000851b9b59850e846b2fea9904cdb59111ea865e3ea8327678f99ac6ec87f54d484fd005405ca162c07862db8af84494a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000644bd28775e38b03f0c8b252de14f77b090c828d02024bbbf784785b6f2a26edd74fbec2472fade7c6dfc1bd9c80e440000000000000000000000000000000010cb8910d2ee27f535cb5901a8c85c15980c349ceae8656570b0968e28bb9d75343534c1b71a6587950963e3987144d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d39017f9e5ed6e37beb3b4e30558accf607651e60a4baecc45ab694589c24e03889a454e41c5a76d115bdfe3241e49e0000000000000000000000000000000009bfe371fbcc7e8792f6f335e923913d6acfb734930fb23497372d93ae0834c97b176ba56d348cf9f1eb082925ee81941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cb2901b71c727daa7fd854cde13c7eb3468974eb63aaccdfad0fa904b60bb9d395126067e9178694de5f8305fb51ed00000000000000000000000000000000105335168b9088a45810dfe79a25aa0d293f3c6fc5811650b2fe35612f6e0a76e29e155a8c248c1ce841a605a89d003a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cce99b2e7064aded9b77342cd334889a3804ba6679940ca83495d67ca9e77002f49f03f4a075b6cbd72a0623ab0ef20000000000000000000000000000000006a45377cbe41402894d9f885cb08f3691dcb2dd8abe9c79c777fd2e4d4b2449566c0e6501e455c06b9f1b1e4bc4f7831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ba10bb924fa67bc3c782d4883e098b4b7225d329ebb28714e9efe77ec99c5723c2c165e577ada70d0fdad537488fa40000000000000000000000000000000011e1632431321ffa835583c20a059423b8fd1b96f0eae8da99bf118e36ecf20e5ae12426ada7b76d968db54c7e3223931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009555a4c6be383a1de08af26a799e431665f0c9ba67d95518fdb8ebe6c55a8e8518a357a451231bccc604af27629e98d0000000000000000000000000000000016b26c561d534d73c21d387e871a6cb5054f3eead42d9389117bb2d9a9de78a6a31218e3275d468e2d0964e41fb5f9df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c19f914a91aa669c7877d54333c3bc4038790289f983dd6e6f37a03da63b10a68d67e268edbb9ed7ad20ec1053eb55a00000000000000000000000000000000099bfc7a129366439a71f9f715956abb1ccdfa15931cc5edfe5b75e7d94512ce36890091b7c356b54a23dbee98d1df441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d38bfe2a2d5c692658f4f39d06bed30296b245072f5880439244b378cce4e48eada84892cdf8928f5f02abcb7a1031000000000000000000000000000000000c5d773c622e158a7597c7214e3e7ba0206a66223931d173591e06a7970cd5e173ca7252de2a43a5dccb1674176ef03f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a6805dc3edc293e22e9d24bbad770d04b97a0db947897e455fa9c80ccfd67f0f973d546493b36f7295b3d8d5c01f6f000000000000000000000000000000000f3e09dcf7b487b000682ccb0b71c9f98bd133fd682fe7a1cb2f1d83ef0ffc2699987a766e23c5cb6a2080e8540266691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d6c771415df4333b7506f4bb7415f790d066cbfb1ae4907fb7a955447bc1b894274d234747718414da878a6e1e68440000000000000000000000000000000018e5fd07dfb41922f45293f02e247a065ca68b45b20527ee46f67bc6223f2fbcdef418b949838b0dd30d6425a059034e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb4dbc74102f6a4940f6a0f6f4a84f441181d58a20113eccb0549e8b41cc6394c804b81c3b0484bccd8689777664ca5000000000000000000000000000000000bd600bb45ad3aa5c6cd0ca5e133433017226c9110d8abf9d490602364100f34402fe8c07020c0beca1ab0ce548b35351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e84050303b8942b73c9e9e9b80adec1903648a82f353617536c4e2fd5cdc89693afe26916b0350021fc41bd625963260000000000000000000000000000000003ad3c1bdb591a66e9567060a8726a2abb9fb99bab009f4f734fa386c973b0bbc251bc2c9cb525b60fdedb3a172c67ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c1a7e82407964f9ec94221a2ad98df7bbf677941d72b93b15f5d706805b1315a08881b1cb00cb2ff1a25a83870df6d000000000000000000000000000000000aa426764c60fefc5a87f6812b2b479dacac2ceae65e1da7249f84f888521e4b691788191d8cafbc75d47489ce8382741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018797757b20f4eabbc0cb3dd28fc503438d988a6e7a7e44d603a4780dc859e426ec7a8b6ee130176778268e4c2512dca0000000000000000000000000000000019666ecbf1b42026cbc1d42b59b325ebf9c57d7664bdc26b93373e827a38fde1bcb9874360df3a902de92137adab275a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000008aaca2307e744151c94ba429dddb0702c0dd9c945782127c387f530e3477885ac3622961311b953e209699bdb9a11f10000000000000000000000000000000008d7175048049787424d019d60ade8f2e973ddeeb54669c32701db4def22e98b1608ca319a49ee28258d4d418eb063d6", "Name": "g1msm-17-jwasinger", - "Gas": 67320, + "Gas": 137292, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017fabdc2a00bd374668c1634f52e6845278f60d24e8ffac5ad1a0305de8d8f633fe66f103fbbf97103725afb5a61baf800000000000000000000000000000000032b04b5d778da193f62daee3964b4470857b4a0f0f5a698e31592b3bbc9ed2ae72cb481fd71ea83e464a2819a06e0a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de6060b7260fa7eac70b2c09526f8ffc5c6704be2c18c47d7c4b11ab11cb243f55bf5dceedd48287dbe00dcc7a5c39d0000000000000000000000000000000011728aaeee67be70faa4d7dc8ea48a60d0c54a9d7722a52b02c9da861f9962d390ef27e1058e8080815e142bff0b36671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f938d3847277090a771785da05e77fb3f51e628fc4ad07f3201380b9a1a7a2deb88ace689c0964ef5ea1d36e56a76960000000000000000000000000000000016aeb91f1b57b83fc4e944b5cc638e2cd2bedf1de3aae51e892bae7121c73704ab2d61fc205d35e404ea94102564a7e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fc12ab9cea6669968b95486b0b66f55f32269bf7992ab80327ea2780060aa979f00a22ba2bfdd579e71a959f6e535b0000000000000000000000000000000017957cb675ecc2a8ec93626d5d345e1ec9742f0b4f706052ae25abdf1cee0474ae893f90a7cbe78b5acfb6be510527db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f682f4c9156f161b794555ee41c58a900bf55ab576768b14eb73f0f3f85da3cca64ce718b7757d6b005e7ad733597f70000000000000000000000000000000000988605131f66453fc09e71c005277d81294186fbeec39c9e36ac832d814787c0119531480b87846782c3b3ef85b2741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d26fcda1fab4b53bc1b09053d31e02f783cd8fe6bcb1ab0053d1fbfe1fb9449ce48b47d3ec409e749fb3ebbf98b4aa00000000000000000000000000000000155d31129b3d2d6b61dbc87b8d2f55e7c6956391d9d08c72af8aaf5d42e8d7008a2c6a43bf526f8699375a140b08280e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000408a2969f1c297e6f21ab6d1a1d5f00e8a40b890e9d8c7b573afc3eeea60259e92cdf0b6dfe3601bb1180795328dfb700000000000000000000000000000000169289d8f7ec09b6d9ab2ef8bf271f19926ed715e1428034ea4806a1ad9dd5edca784f72734f6d5dc69c6c910769617e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e6a9812fb0da1d5f1fcc3ca92cc12cf17d46d40a4329169e01d0024b27383ed28a92fb52eb37ffbdef076dd610dbc5000000000000000000000000000000000de7170b36adc59e538991834696b1f3c876840c5f1bcaabc585243b65e2cf832da4ad78aebddfbd8d947936a0525a001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000108e2f1cc4a9c5aa707082f634ee8de51ec9a44897ee7e4cffafa3272dc61b6e30eba030145912ef21b9ec965ccd8b0000000000000000000000000000000012145af2e467ab2148e3a3320e01da20124e0293d3fe89bc6e89d2d37c12ea3bf09ec5073cd0c41f5aafe933e2e5713c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4186cbfdbb3aa860cafa5f6451c07c46156fd91488d32ade115b295adf39396f0c4265937621e18f641b224a7a934c0000000000000000000000000000000007c145ca75a9cd7a67f20535d9a68b56750b180c19a7bd145a0fbad930235d0ef70561eb31076b2c587190893a75b1141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122382f9424b81fb6d0397d07de001ff93666e4f39ad8b514979e65206a949e698b4fa5d1961c852eb6da19193be0a3b0000000000000000000000000000000015903eab7f515deed48be1b2810b4c43d09379e0454cbb2f71a603ffcd1cc7c53b2d4a4bdee50ae8a555050fd9c96a1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001818c548104bf6f3f231395f46561a0ebf321039ae7cf3cb54c0b2e901bcd59f38bc488055193f2ead49d8da41e5db2f000000000000000000000000000000000275b44713b2d70ad0ae7e08cbd4933dffaf51915292067e4877887325c220cee554ab9f9138d09259cf223841ed7d901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001454d1af22b3950d332726f6674f06e0be4d8fbee8d00da94ef38e6043d6ec0183a7fa685dfc2e7f278c2d66d0754af20000000000000000000000000000000009f7e4b1b73ecc1c4e1aec55b78724568999136ca5d4baf7f2c61f9fe11b80535dee231da6e2b8224958652496bea48d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004392c3c6d7d3ca22cb06b5122210c59905284e831fbcf0ad8a1b88fabb2333f4cc4c1d90596ad2adddee0634c1cc899000000000000000000000000000000001469bd6927bb1d191eecd9379dbd5c70e91ecb37ddf09eee67d897008a2fb0c366e6182d259b20d44d6aeb41ca28f9011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001347ee924b4b01057d19146402eebfb789463a9bd60f859d4391d680ad99314da2e44ff5d27ba3ec8d2b3c28119b6ef20000000000000000000000000000000019f63c3cd259ef162fc021c5bdb6fb11b7666830ff50508341b87a054988c293f6ca08cb27f62195cb2c77194e3663bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148a3338a8cf177095b53e676d0da6f5c37fc1d42a6ee18a1dd9175b1ffa0137f2fe3b71c21d1794837497763fd46d4a00000000000000000000000000000000061addc73b5f8f6dfc1210d3144bde791ca9761cef3e7cba9e917b3220699b587b535e87dd1af2522a476632419b839c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176afcb9c7400390f1f1bfb074715352d9a4ef4ee3c39795026b8833f6b1f228baee37722fd9985d7f10812a788281de00000000000000000000000000000000018227759040ae68f1f86cc8feea5526d6c318bc3686fbfae7309a423f23e4110015e58d76cb78098b60efbe012d486a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8237343b653c927da00704c1767a65a90391c8af4306e6e7b90b74d5a6f83a90ba31e4e96ab3f7c353a02ae0ef2a5f0000000000000000000000000000000014b0ab4d0f0e252719bfd25223c8586cb77eaf8b6c884357aff57935e2942c5f928276e86cb87774891792366779bf181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000011b3bc4cea81d9afcc344193bc2c22b968375e0143f885b9a9f6125bd36907ab731b062df9978947e8efc9b7d61beff1000000000000000000000000000000000614db843f5d0762fd28dd57bc58fdbf15bc64dc275590d4c120927be89eb9bd9657df2c6c680e5da78f2eceaa0b77c2", "Name": "g1msm-18-jwasinger", - "Gas": 70416, + "Gas": 144504, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000545e436641b75f0f28d4add04f670161de38b9900ad384b29d441742266316fb00ddf89e986685a554412c31fb2cb93000000000000000000000000000000000de13f457a3b61ad0ca17a74c72f3ca6cd10f392bdd2193f4e076ee8b8f48f464c59ec0a3080711bfeba93658f4613831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e26fc4e12be71c6fa4aa4e5934172f0dcfb5bcd3aace8f2203374893b14deac434fffe0451f3e5230a410c7957242b00000000000000000000000000000000088be2171d9ec6d320323efbb6bad2563a854663e987de2ec2a74a7a672f8b50f5d9afeb11e43bda1637a29fb042a3eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ee0dcc1dea9fe89bdf0b62648b82cebd7163e3996f4e48763094615a3f4d8f72cd88858f25c2895502943bf9af8d33000000000000000000000000000000000cc76cd900976bc11b5f6db7836b4895bd54b1bfaca2eeb04f386fa16c31c6b41924cf845f3c79475dc96170d00b17ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2f2207838655616df1c25bc1668dd2265b87c2016dd3b03b58938a786e203c7ab46e892eb48e404341e193fda247b80000000000000000000000000000000011851f48e230f3e9e8ea9a8cbb02564a03f17c43e8acb3514c6a4792e3d5d54839abfeeb0e83280178f680a3bc8eba9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000382bb1457e59a6775990fec46996e6eaa15936d918f6e9a1d07ae0a771b4fd47c470d29f91db996a03ac16bcf882040000000000000000000000000000000000efdc8042c7c72a9b7dc6d86710b66e8d19b86f565a73eda25921b1670945aa0e33187e916b6a5911ee4c73d9284e611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030671b2ebe6a301853653c269d81d09624d07a6e029f7360803f1fb3fb17264be900310ac7e06fe09d6b9f95db45176000000000000000000000000000000000e19fefd6cbf2bbafbd97288d994f45a2491a5c6eeb2cab98130759e335ab444cd866e4ea01568da7b67704f7e87f8471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040303c670abd8692a1a313aac605104aa25945d570efd725282a171809ccfc4f5b2af77cbf266c5bad6a281512ae390000000000000000000000000000000000fee9d9029289fa97b02ca86841b5256bb723b89292c27c02e6053d0a0eb6e18a821d3732e3cfcb6be5873312bbb020d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003877ae82810ea962c6cbea466020b96a3a1bc1198d25ad4e274ce1a87deb613adace75e1b092d040f675dcc67b77746000000000000000000000000000000000e3d732ca213b28f8393af748b9a7caac60c122ee374d0f54ff82529eb5838516886c86e92caae6c0f4d540a3af08ae11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170c47600f58e575b527b6af67024a0104cf4ef61ea3f0a26d23d6d41c4f5c9155c5434cf101b7f36a1bcbd7d6ccecd6000000000000000000000000000000000a19e440d6644896362a3e3569f919d6dcd7922da8861b65873559c9d5cd976cb6ddd624284839a8d04edd6095cc6e681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f13a4ac688eb07cd9a19607b6a40694c8b48ec8aa86b097c663d4a4c06cfd9aae625d5809a26d53782053af7bd6e3f000000000000000000000000000000001036583806384109fc75273579762e7ae189dc262f1377f4fde33f9bca8d0ad909ff462f2588204809602498231d1bbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eafd2dbda55e2c4a29a28e4ef40723a0c90852ca3e625338aef9f96f07a47d1095337deac16b5d0f6dc3a5a6f0ab493000000000000000000000000000000000dcbc21b74d522e9bece5a57ec1d1c44690dacdde6f3395dda84bbaa3ed5b3f8b5ea822a2d9b9de7955e8c5fa290bb791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce932f1a653a2b17695d7483e57f33bc005382c0c65b21395e9707c1d63bbf23f4e0c7a0d12d5439379bed771fe18760000000000000000000000000000000013e4de35f2982aef82ed31e725645beffa79ba6af402809b07dbd291674906a5d1cd0332aee259c45108a0586e6be4321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012433b7797ea7074096caaa208fdc30f22bfe6dd5c0f3bf151a4423b251aaff64d0526d6d2ac351c9b641e5529d8b01f00000000000000000000000000000000146f24f4801da81a67b87ce77b29fb24b1e3660aa068231e4b2f8e80fc6f9561339e79e8900102d3097894e63b8fcd811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c8fae65a08a0f42cff0aebd9d3cbb88476845ad11953bbd6f1e7bf19ec3d7af5cc375add971f996288c24a0a356d330000000000000000000000000000000013d5b3beba22cb04ef3cb6b50307834785165aacdfbd8b19ccb58e965c92b099ada86fe5bdd5da9cd72e6b165d2a7d811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c0d1e21755d4314c7e3f7b562cd55d75bfa76f918d015fd3d7b49805e001f8296ac2ce03f7050b321aaaa9142427c2000000000000000000000000000000000aaf63c91674896079d2bef6d264edad161b290eac2c05696397d703c9a8a051c2ea53bdbacfc97863e387e82033d0ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b0933d1f61ac4a7f1cfda77d0453958eb3436a68db47eefe8f55669db2d8f8ae6b98b1f73713bf3662868ad5e6af4b0000000000000000000000000000000006cfa53e31e18ac4b64f934cff5beb679aa72938a8ed658ad795d52a198232b0de5eb588d7d337bb08f48ca7220a40d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000394873c2fed1e467d66af28b85c39949878001c7aaba5bffd73acabd02a8f233fc4c6a89414edbbed15dea9c623e4b4000000000000000000000000000000001465738fba3b7303c46724f02aa6df6d43507f3139290dec66df37329827a038401f72d2b49e3e851897eb6338ad026b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f62ccb47e362803627f0949e5549d16c4061efaa8bf333e000256a765ac28e25ea42753e6b0531f9630b038dc74c17a000000000000000000000000000000000905a3cc7325ea0b436335025d903098fa35de0a786d76704a72632f19f71884a4c340385d251171bd60e98fa21039d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a4599b811796aea95742a0ef7638ce8fc848e526411b0df61c4c2c12d3098e5ff3a7b54b91260446e412179be5cd140000000000000000000000000000000005679a86026866c373f351d2880a5ddf043c1c67253353b730f6296abf686b3cca2e34120ecd60938d0b2e2546cc29a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000001474e3fd13fc42af3149453deaf6e64b4ac93960e6537b33a99bb72047296b5291545a1ee0b9b6316c617c61824f51710000000000000000000000000000000002f4de7405d1b9d0a2fd50443b343595c1ca8cbcb1e6459b7508daf11126b589dfe4c68cef3e631462fcdda7885cfc2e", "Name": "g1msm-19-jwasinger", - "Gas": 73416, + "Gas": 151620, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000132bc434e48d473357753c8dd920b2a2d0fe0725b3adc8956c5938214121bf18815ae969c73c438b94a95caaebb7140e0000000000000000000000000000000019e9d07c11ab7aa7257008dbfafcc746146aca49202de5e9c9e0cad4212eedafc71be8487f814adba17ec782a78291471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001122419326f0e185528fbb941e8a27156b6a25a4facca37dd2fffa223eea2a270043ca3a3ff2e4be0da52f94f7ad5b43000000000000000000000000000000000002ae60bafa9af75c09c23174dab8bd4d113170369914920185d02cf5e94eb1f5b2a17826c549f46dbf12490776455e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001326e697127e0d847550c37c641eb2c898180df0f8c50d7704d4bb79da9a43b9733dc1de3c0a67a2dbcef3cfb10dd017000000000000000000000000000000001033931d90f06c0806c6a9c1c1a856f489b82b36d8112e8f7cce07ad1596e2ffc972252c32a155784733611a235d5ed11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020b1cd41e31eaa7946dd1bd7668e386016de077c82d17bb0a7543dbf667b8df888438202139fb224413c9e4b395754f0000000000000000000000000000000019aea3f434a98d476f7ef459f556258d762d99165ad0a9a63f8121abe7937917ffc05ff16799934c568df9a7925f26b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011289a42ae2bb1e1bd5e35bd4c251db7c56b44f27d1d5fdb2d225c1100203e6f81bcd876d46c40d7e7d2f032ea1bee880000000000000000000000000000000014426b8868954c77d8c51f90414294b1f3254282fb01073624bfb5e84fa70a6256e0fbbc6a9540f605f4a91fc075a3eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059893d2ceec0ffa31ba4f6ada42199d4da6d846f921bcaaa214448d6a1856c44e0332ce78dfa1a0921e8ecebec58183000000000000000000000000000000001463e0ebdefae0ae7fc100f799effb6947695c6f3bb94d5ec3ff6f27da1ea482a4feccf1ffb0df48099278fd5eb32c6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcf0f22a86470f8b7bd74e80edaceeae3919abb65151248bd5781767a8b31993bb6eec0661cc32dff8c1deea2231f4700000000000000000000000000000000099ead44a200eafdacea929ea852cf7c633355c4d32349e8c0fff2689edf576bd22c0eb2082a3819abb1c55161719fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1c47dd5fabe2b396544222bbd5dc9b006fc7f24f99e911955725abacdce5f1cb5f571e7c030b20e24a6621e4e47d8700000000000000000000000000000000144796ed5abdb593e359307004e6d9de7534dcd31b837c364a239c4490d97211b411d8945421e980b3a85cc0d5ce6fc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e2cfc567cd2a32d5b66f093e9ca8a4bb7f59191b11da962993f66607beefd625e9bd3ec3d3eee36dbb07c1abe5d1ac000000000000000000000000000000001951f4056c957483a2e88e193e40eab2cb6bc4a6d2f6d72fbfb9888e0af35ca44a075bab0e01ec94bf426a4c7b5aa7eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001687c7dbf40f050b409a4143b9c20e5e2c058f1d5926f1c7b29821a659d4da2f2a78c3481da07f6665513e6426c1039000000000000000000000000000000000102eccccbe47b8fa6c3e68176aca5def09aed31de87a69b82d4f484c9e4c34afa3308f7835586e58e56fdc793087cc6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009003c1861ef78913c0d70aa531c8d696089b70ab7bd6c22a2f4b08242c37b71e118e8b6bb23ccd7b5b290d8f305bd000000000000000000000000000000000019cc59172f9f7e1bb75b620192a23faa3af396420a827222d5503917a6ca7eb26092336fc2c0a27b9d70cc24f780d13b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002217a8990d2ec8dd6081b5bb1bd7a5703ded9552f5160500cdfe117ecd70def95394cfeadc5dfb42f444d53200963a8000000000000000000000000000000001942c9b156cd5bc99b299206f609f1680607fbf2cec202c9325147225cc4ac9bf0e10f9cd32dac3881c772224e6827a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018581ed8147813c72000022206150d858252c79a87aea69c829364060e167857c2c454711205f9de6878b86300136f1000000000000000000000000000000000eb5241686b60467221dabc4e2d3e18a92e342058be282f68229f6fb14bd51f68bf6c54843575766b22450a7b760984a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f453559b199ca208db36b21a2c7858f1f3e9d30f2566f9466e2f9ab2ed73ceac05a1f7fb5834a10afe90af55cba569000000000000000000000000000000000abe52048855d574b4cde8c2f35d82a3fd23ea1eefdd49c4731823500bacc933475f24ea3716f836a5a5de81aaec46931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dd1f1e263e5b2b6ea604bb7bbc9c272b2adf2f4b450677d1900787000ee88062debc10355892b948660c6ea6375e610000000000000000000000000000000008e449d045bc6ecee6287e98036008dba3060e2b4f6602b199792d7a4bd31bb248c48a0f0ea0f07c3eae96d118a071991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dedd05e4d27fb71dc62af9ac40556ef1077cb8fbae8e9dcf037dbd4ebf71f5a02b2dabec1b0f1ae13b5eb9591ef5bb0000000000000000000000000000000006252be4eb450078f37d845be739239820dcf7a93cb26777e67e16f834edc57ba143c82080c493d557c3c2708f96a3821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006803e53cff8936205d02afb27ee07e924d42d9a12f5da913941b78ecbfd79e716c741393a39c5df008772fa30d0792f000000000000000000000000000000000e59a8cb64ea37db6c7ef92abfe29098b5f897746c19aea732d9a321198186f8157d3781ed7d4b46a867f35b636672741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002998a4c031aba2f5f0b78985fa6de35d7c8b4856a037f5aedfddac9e16b9ddd7a0067eb4676fad62840b4438566819600000000000000000000000000000000107c286b9b4d931bec0212a83ec4c4c4143f4916b64968f0a7f54ad88e8a69444a82f1122cc73f34baa540f775b11d421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f603dec5ab6a3e421c3cb12a4033fe3fc8e10b50428ce09dfe1c3b432f9731da008f4dcaed2edf37ec01690d52efdbd0000000000000000000000000000000011294a5238934fd78c1c28814cdb33b85e004ee59965907f13d3e3ea3a408bb4d0cd14a1937eba8fc3c2d5c53140a9bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016460c4af8ca797cc7d10af7e8c1592bfd749cae62f39a8fac6121e5fec95000e0968293c667bef80d4227a4235e8200000000000000000000000000000000001380bd18d7260e6a37ea44029120fcc0428cead4a259d11ef28b45f8b1a8d6adfa1b264564b5d6b33e45063e72c546cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000154203f424c1170fc65ee9b5eb1115ef77c64f892b5947dacfd3dd728c602ee3198a0050b074482a176db7d04ca5ba7e000000000000000000000000000000000b311a97a9da2e9f71f4f2703857412249ffabc0511d7ebd0a9e1e59a0b51b261b9193d44cd7744ae4e758f6226c6d8f", "Name": "g1msm-20-jwasinger", - "Gas": 76320, + "Gas": 158640, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015bc64f31d45ffa9185f935d1d118d253dbf222ce5e60141aa3e233b9ba5b55770d3ec5cdeb6892c0e050e4b802423690000000000000000000000000000000015838131709922a7f4d3181a1eacaaeed1e242251fb3079de6bb95627bd9eb16c7bbccfb8b47dce1ab293cdc543e42661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101474b64c5839a3a843e7f36ecdf91835bdd0328a77c0c1517fdaf0b985c5f553d5ce79245f3bbd01f97433b79138e40000000000000000000000000000000018b64f40cf0ded14585325c9ffca9cca458d90eb18cac7ab74a990df3df3a0ef9e76ea8050e9646ac23302d5bf51698d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf9ad556cfb7e2785c21be67e9b50bd034338a12d6dabf47734bb4309f350ebb7537e7cf55f262ed8f3d99510a0e9a0000000000000000000000000000000000c4c9f76de44e76066a2b10a9d48c4fb36a5518bf66e9542b033fd185b77262583b005a2cee0e61d75b56264ba16f7c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000054e11da7caf079cbb39ab0c386e98b43b99df7505e0388b9891254d24da31987231ead48e8f2d2554fdda5213adf070000000000000000000000000000000000df4bdd692decaca65957b5cc4cd34c33d6b5e85c9ca4a1e820e771fe67efaf0f32aa6872d3ff91bc038e40a9a3b83f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080c27e8389635a1f1219cf420adf5437cb2ba7d2905406d41e1197c9b5280b38ef2ad0bda1673d973dd4bb6b8111d61000000000000000000000000000000000a851fae3033cb150055f8992b1fcabacd86e5de084fe8af29bb06ff22523429f7262a73c20667bb75045732358b05e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000953e9e19d7e6a1a540bd5e254df7c72b34b5e58307a2e36931550e1b9dabe8e3207932e3e0d76f0b8f6f2abca06b4c90000000000000000000000000000000015304799d98bec0605238865ec6a9721b59cea7bd3ba721f0ca40e8404d1a55b13bfae47126db16386aa4fe386c187911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001de88b30b2d7963d901f392b1fe38d6b19511fe6360486ff63af6598cf071dbc2ba984d9450a39a0e036606fc2712af000000000000000000000000000000000af2ab4b3000ef303c2230b3b0eca9c6edaf9a7df5e8d4f83678ee0a2024dd462dbd5ec698e60aa118684305aaddd0f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148995c67088528f591eeb46892f299148056803a3ef0748a84fedc983963398a71bafebd52e9a7eb25e7e7c25873fef000000000000000000000000000000000a6f1cd26a1d1b284c5ed6274359826af934fb7231de804b6d1b98676fb6038536e96c0d0f6debd6d4ed6284c98e54941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b96d6fdafeb1e1289715f3d7471a367df97a7c34d4b6fb12b0a2e85a5ac495de986232b34718c3d11280afe82c4e77000000000000000000000000000000000b571426280599d2cbc2758ebfc33f3bd21e6a9091700b5d8b6c2e85b9c9cb337da24039e504eb1da866c7c60394d8e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007addc01bb8a8c94010407777e504523a6ced10c898594b0e659b886d82c0e5f7af39706875f6143f9b282d75687f02a0000000000000000000000000000000002ed6edd4e0e41bb0d4ee156b2dcfcbe58793701e2170bb98138f25666d1f49fed33ac366e2df79399daf6d4606d47991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000878c2dbfc20804fd2dc4528d742119cdfe06eef72bdbe39c3ebf6416a4fdb2ec7455d731dc37c64a0eee45be6a1636000000000000000000000000000000000711990604ce169bca55b086cc08be5c6ced607aed02bab7ce5e23c9acd1a3c730273ebd9c3e3a9c96049276281d72101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c7e0b38723be07408ad4b39b2bef1b60dd259fb58008012639aca83a30925fd7a6c5b2b1fd03c04a3190ce2a659436000000000000000000000000000000000643ae3f4ceb0faf7198855e4c218d2bce3a84eb24e22e7ef04a071f9fe8646349a059cd9f7b9df3d03af8dbd31154ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e26b83f125d67bb590ecdca6fb6cf3d80a7736c4a72c58b5cdf554d9a5ed49524cab86ea90adf3e791c08520a4955c000000000000000000000000000000000960773525a96f28df485c6c2e2cc1fcbb8f61c73cab05944dde96756b488b78601333fc24ebd522445f9a34a07524b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003714bf8581de78482c555daa72e47d180125ccd8e07ee863134f752455c1492b155e1276e3a2c84d6c8a24f772816e40000000000000000000000000000000016810dfe3220e8af10df32e152404a140ce28afda3b0a10e90761de7d0f177e6e0cf8ae1489b98dcab5cfdaea6acd6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a49ecd2fe73245fc2cc055afa5d0cfbf8ea242c6a66d19f05b27c9fd0a392992c8671dc554e39522b1bf70db85dc13000000000000000000000000000000000762fbcb583ad96d8e10281d11de847edbb64581ca58fe848abff3fa328a75d522fe8e721411b8aece7d1caf5d5be52a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099b8bb6661ab5395a0a5797beb21479cfa46b67faf6e7faa92e43c692ba3e9241c70c2fb5ebee0211447fdb98cdc46a0000000000000000000000000000000009f193b600485465c6af4b2752927743d0dd265cbdaef29cd441a02e263e17b89056250a3bd31dafa95c04e8fcb1b3661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e12a33e1a5d8bfca57e04504f1a38cb4aa1e5fa166fbaa4c2ca771862ceabca9f61eb64a6e67db45f0c944f6c1efdd000000000000000000000000000000000c84f3f126a8c243e2e551724f3ca237bb3380e5435cac7257bdd4dabd7e8c159aed600cb83b5d0feabce363c5fdd39b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e87050c11c633f2fd76b328069bb564a20d5ece1d1a214aba046bc34af0408184f7cb42d7ec1f160fe275d9aa197361000000000000000000000000000000000f36a03ea617c050594c8eaf6d3c3f0282c47a1a2c4b696f4dc1007769e9755c1ea2ba3ff1fef0ab060e6efff16646911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3742c60c3363fcdf70d2fbc5f267197d37e60ad718301bbf5bedc81627444c4f498fc141abb87a8f293f799896abde00000000000000000000000000000000163aaacaad32777c6b78e6644dd04f257965714c07c2f9e76843bc8d5a7183eec35a0efcdb8392a4110f2704192d25f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129e170a7c21e69257a01143e3964f38b85c8a1de7739cc72a6f374b2f51fc8d3baa7b5e1e8787d74d6c646be4f3bd9f000000000000000000000000000000000976e14fc451626c1c6b7a464a9cf2033bc2b269f57ec9910b04f15a6b98007aeaae08f82defa96b97fa695307255ba81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bfc72ccb4083136e8ea2e708d8b6bcfd9eade230ff68794bf0153d01fc5ad16cb650c76ed06f9fd40f5b35e12f7ca4000000000000000000000000000000000ea4fb8b1a6c1f64e0505ef9db75419c1aa9fdd1611e7d361f28a6f8a6e84999cf242e2d212b72bb94f79476a6fc858e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000132e540a9c76a1d0926d857f6ad0bcb8faf82f66ce6d134bbf35281398fc9109d017aff2e445bbb27511843d409d914000000000000000000000000000000000a562ebdbcee78be8efbf730ee30469727ba3a89b690d20614d96ca1885c5cded1c56f8293b9e4cbf4da1552025b395d", "Name": "g1msm-21-jwasinger", - "Gas": 79128, + "Gas": 165816, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000630d8a3899bb020f8f123b8efa6f471cf3bc0a7b24f95adfacd2c6bc3c4342de197eaba0b27861ea6bdcd6555ed5c350000000000000000000000000000000012da1972158eee1aeccc48b4edf597b779dbaabb9ca6001b0f35cc457816e54fef257fcc3d1af536d1d2c115aef5dc2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c0ffd2cd274cb7c146596723a2c26f0c1f339f5d2fe0828d7919ebf977745fbf2f9ca5e7a8e244e3d86a7fece34373000000000000000000000000000000000ed343c846bde6c4fadb4510dfa383c264d605e0717ee8453846963a13e70b1cb97c205fcf9b3d649e83b27e2951f2571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000879c9853c955fb060bdab01a7beb1a09b21596d546d91ef420c0dc53cee445fd91affded5c551653444b0b4ccd15347000000000000000000000000000000000a7a9f59cd134c59f27498b751ee66367940e82e06a2d4952055d6cd4254452e29aea2e4c65b2531c355b9858e3feff01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141c76e1e862570f1c1f00fcbbcb661dcb5efbbd5f2d3a908bc0fd9dd4b29b55a220f000c68e772b47b096f93a07dea20000000000000000000000000000000004890da769727d2b81e4946fe454309c39e246125c660cfc1c302141945dfc79cfa96934b908ec31f32bc4fc3f6e6eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bb338d98da77aff4f9252e8e6334532e8a2026b69416f6256b965962a6221ac840968d63de36c5021a3aff774cfdb9000000000000000000000000000000000d101e749765f3d28ed9aac7afaaa87f93d5dbded71236ab703343a8d9147b5078aac46f8a401ffc973a5fc6c39a18301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4bb823ede88102242f1badf202bcb61d49d6639e0984b4b9ea288dafaf62e8e7b288ebea8e2d0625c7b76ea1745b30000000000000000000000000000000000ca87cbaccbcaec6a3a68511df40c7b474b275d46fbcc3efd145538763e6a401eea7f0c1b4bb0b90f740c8ee9057ee5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df536ead3755e616cb8e6459a599488b0ca8501c19f53c373e8684334810e0132d685bf78dbbb0d16ac1ce4bd80a135000000000000000000000000000000000ccecc27365fcfc7176e665861021e4bc363c1f5411423929f1e0f31df2d48f04f9183efb913e4cd97501d0d4a2386081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171e5674010b2608faedf1ba90f343803ee186634deb046b78ccdd0dd99a0f05e735c2367129d141ae5035d1c81d98ab000000000000000000000000000000000b428956ec9d5c44e3dd46a9a5912a3af07fb95a6af109bbb0876cd3ff480f46b563a6bd1a7b180ac697cadea5480df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000681aa8ac7de6c7320c6fb45e15433f62cc6648043424a0565eb9cc65410574f4bdffa41814831c11df9ff791c9f729500000000000000000000000000000000088dcd87e67cc7d354262a7c5bafdf1bd61e301b98c70c01da3ef8a4373db943a7d5e9076ee51656b69903fa7faff4e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e42abd90762c3b0a863753370d477fce663b1d6845854cd78c54446d1a80ca5c5747b4ca4db8585987ecf70fc6a84a0000000000000000000000000000000003940bafe9f66b705be519553931f63291d557274f7ef3dac98c27d2fcc30f82d301ec7ff5bbcbb4975176dc84e772e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118fb540b05580b66fa2ef3792f102c6def24e0f77d3a9c990826122f4b8ddf5f60c232ca1588a054938426b8b1a253e0000000000000000000000000000000001a0f4bc31f1d7c02394a8d1b383a6e50f47b78cbe9e480e00fb6eee16d5192a42bd6687e433629d581010d76ebbc61c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a311f0219808ef67149af64009a0f4822268699a0ba11f4a89a2ab89b9822c5bf8c5b67b0893c38c199e88918a685d000000000000000000000000000000000963d71642f3127c3a25420f2da66df0d13c57682b6df7e6c77648b2438b4b697b8fcb5349fc4fdea9a3d51a449574c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186b60de25c5eb08254868851c057fd10c86bddd7df505bbb307f189480504bcbff2b02dd36f52328229171bf4c6f05700000000000000000000000000000000146b461d08753f4783685385eac0080ded6b7f972a1b7748f55e6e8270974ec164e03e8cb2d2e2f16e943c7a629900021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f8c951266013304335955678c9d2d1fc6e4438f3754273009047b494909f9f24c68d4d7d2d4b9f51e25c4ed066a8b00000000000000000000000000000000016dee0cc2fd25e408c69d66325bc0e522327cc3b6b7724f0daa071ea371239b26399d62abb7212d1e9a0bba6cfcbfded1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000843e22165aa7dab4ad827e80a21321bfda5b26eafcdb76186953711a214f103cbba3ba112205d9b2d6afa9b8b91111d0000000000000000000000000000000018440a66fd14fcd88072c9bb97d69ce8877e403d99ccbf87cad3fa44b4bca473293e4d83a5128bad90803c93bfddcd021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe2c8d5603c21ebcd6682aeccd9f27e5aaca6e79d4765eeff0c99e032e02df47f87c65a4ae8adfb4b398d44b2b85ad7000000000000000000000000000000000381081b8bd577fd03cca9176a22cd628b9373d1b72db0d7468032c0104a687d0385884ce9f8641f875bdb5af69f9f301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e47e2d03142903cb6e8b4772407305ecf81db62359bea545f8f4903b7b804725a34a8461b1fed82a94b7a75eeb594fd000000000000000000000000000000000b2538ac1774e397e80366418a8d13bcfbffaa46c032f82f380853b39306e8f4eca3c4a25ea98abeb1335284d6c9a94b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000959f0fc6ed7b3d0a42be318cd059eef5ed6a88f3afefbb52feb2e93a91f56b92ec904e8404a3e82f6a8dba2837c56ed000000000000000000000000000000000d3226cc36bce4d16e24d3e92982bf0222c1f6e1d3d985d3fdf9ae4ec311cbbca95ee1e420a321cda75ba131f3eb90221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f554e09658526373e2a962b8114aa5a6ae4e479a85548fd000b18a1129c5307d97a398b2db4389fe2f327efd16d7c380000000000000000000000000000000019a0ca577212de3617c7999b1a695af1d6e65764796d4abc7113bf906fbe844d993032f3d0244f2b321bb940ca437d371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e0c80927023794ccc27f075907d24bdf1431e2d10d08b6f09bfc278514cfa2224b8292e2701f8b3fb18ac4622b6d19000000000000000000000000000000000f42933ca3a07345d00fe9d479c701d088816659f467d0638db54be0eaaef228ef01e3b94e71a99894138d12de699be31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007acd1c87f6f854cb0727d33bc179ea2aad69f822a70b77ad57a2e102e2c6e6eb0e57e0f5389d59b8fd0284d903652ce000000000000000000000000000000000d200877b980c07b191b490ea6c5e733d9a2758a88129676f7c218b00fb14cdc798d7f4dbee7620888dc6318ada63a671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e09285782ba9800a45fbca1b35d11ccb56c617114087eddac54700202b118613e0fce44f6a8c41e77e14f17295e8cc60000000000000000000000000000000019c0d74b25744ffb8301159d5a888d4eddf0090e7798f5053317ae3a55d8c8604a872498b59b22eaeee9960cdcddf91e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000079ce475ca4c6832183c8e35b888f2a4a7970f5c1df2269857b32ee78d541344f40ee22aee21412905032b626575da5f0000000000000000000000000000000010a6f229b07571d0a833040de9c406afbbc9d525499e917e1a1a376d4ab0f5e129265180ff96ea297defe41537e3a99b", "Name": "g1msm-22-jwasinger", - "Gas": 81840, + "Gas": 172656, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013a1ac003ee6c6a39fc63179be0daa3924071b5f3fbc52bd8ea84146c396bd036dc7fb29aeba4b68044c8ad86525b4ba00000000000000000000000000000000080500a0234da123f16713b8e7bc7ddbc615bbb2dd2009427d1c4f6ad0d66ca403a2df8802c68cd86cdf45b70f4371c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cbe587f05dd76373862ebe0e9328d029fe472ff36635232ec4321ccf89725d258fe7935ac427c3daacc98ae70b1dc700000000000000000000000000000000194dc5b447c63fbd9422713e2bb9c16c75f275dd784872a3854577eb12409c28bfa3beb7548fa55f11415955bf8234591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170796d67b9c300069945dc152754b5e32fba08c369f8fd2cebed503aa12cf36e5365c8ed6a6b741428c6ce36137d9a4000000000000000000000000000000000ab0241542e754c92d1621c99e4e5741dbdcb41d85cc20d1641334526dc411edb1961f32423818d1104a5d499b3506f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097984ea412e6527f0691cdf1eb784adb01382e07f3ce8cae287d5ce8dd9742cfd4e945c2a9dc321cda51b91c9b2b5ab0000000000000000000000000000000009d018f20be4762f7892da5bdb3dd5e4b96faaa042a2edf0cebcafd483ffdbdf961658f461742dfe81814c4c12ca868e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001629134c3a9993123c31b7aa704f4d8041303809f1c2740949db80a25acc93d13f6917197088456e8e26a7a5dc8a215f0000000000000000000000000000000000bf30c5d6cf6dcd953cdfbba1542ab7d90f8356d54f6d1a59c74996bfdf73205dd06ab0218046052d57bbf3384383111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a6e2d4de71f07e950d78063bc0f013c8b61e0a331ab58396a13c6280cf72399a963497956fd1823ad96812603dd10d00000000000000000000000000000000165b322d91def7ec9fe4c01f19495d5dcfa1396f0f72aff2afc8290a512d78a7f25cc7db95323d39677aee224c04572b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5357adc1a74e302ea033a65428d5b5eb62e50d36e268fa19eeb0ca24d9d4057847b3ada23fa957590f68d287078498000000000000000000000000000000000353c8d6455b5b2f86585a8310bd3446249e0adbb168242929baaa86cfe61d8f59a376e8a0f887e2ce5a9bc2f51a2ad51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017de9c7f64513d775412007f4d5cc8717d72bfff75f2b4cc079ba0366339456a212e3867f9ce38d8a6f3453d920e7e70000000000000000000000000000000001468a9def6838b2ff3ce0d9604d5d2711996e9238fa30e141e701642e260bc87c88489c163eb414af4a2e60e427746a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003815ea43da1556965c08e84957565c883189d6f6479e00a03f863cea065fbcc94c1c4dd9f7ba35f7e7d14a95ebadcf3000000000000000000000000000000001624b798cb98c5d91db7e0c7ceb664aeb72c2f523382a22f10c3f9d003572fa87ede4a1e77ce52eb0cc4cd8db8b663981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac26829dbd1e983eb58c1f1ab9fb0abcf240c4832c45b3ecd45af900fc77de2262b3c64a3539dc4495a7351478c017800000000000000000000000000000000070054c1fdaa77461f95792b73d8a6394eb227ca3adbe4376de5c4ffabfa8c36a40a51664a72c3887e5f43763cae5e1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000466ffe30dff728f51b6441bac62ae70d7e454c8fa0a17e709637eca99ca365151560ab2f4869437f705e9bf3e2d3fd80000000000000000000000000000000001faa0247b6c248edfac0f5ed644d2cf04d572296f74f26ffa7171f8027bfe9e04a7ecbdf43cd7f5def400017729c5161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000549d6b517a824df976f77ec3f141a637403531c5ba87048860fff31ea9f148a2bf35d0b784348242fbafdc034abe1d2000000000000000000000000000000000a97f1c5ccf4f972a0be22a98e696d86e395431e63bf358b4913956e5c80242757dade0a881ba5147b62c00d26b266a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ad7a558af3eecd79d35ad3b4732e840c9250005e6e3381b7139a989a358ab8fb8eb1978e2208b06ac744f20e44624900000000000000000000000000000000020a52094ead196a3066dc9f2073e61c3742d68ac3524f36a056d334a99d9199b7b9c653252853b8eabb1d1b63a78be11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8e0dbcf575f4f3d2438a8cad4a3f8842dfc0f724e965105c68c79919fd00fd072c05be5beb746f9b2c415a09312fbd0000000000000000000000000000000008672784a8f9a247fc78a11bd9183cbf6f53196cd836cc785cd4944a921c4b3f8bdaaa579f004d5ae06689a9a9eb83251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010faa5bd353ac7d8d7760fb01783abc3c184c747a41d48808826ba3eba17e36956a4fae422d3de4e2bc5278d59a811a70000000000000000000000000000000008f7dd420c20dc0f1fd03b806217723f58c497cbcef94cfe8607ee2db2a154b748a7611e7013119626514c159d26bcd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f20b02a8709b06246f9aeb4b440bdc62cf277f7da20a962eff9047fe09626d87456fd69a194c0f137680944197b8ea90000000000000000000000000000000010588e4765722c502ef2dde60c2aaadec00ab9d01cadfe2c384485fb16e3c6cae071b555bf1a2e03a60bb4055f84754d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000054f7c7bb1fd20435945897ec5c41f6606d5bde7f0696679327ef4bc813c7e2235ce9a291717c59f3cafbad3ea2b61e000000000000000000000000000000001245b4ae97be92d071cc112e136fdbd6bb686cdd62d2e8fb797b87fa5c9168c6ed49b03906d1c72c7f073888976c2c181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101ddfa4ebcc06050c0b2e3d6cf220c2c170ff474b9b6d844752bbd1e3d0660c361dd61025ce65d679d78510bde481ae000000000000000000000000000000001979fbecf4eefab0730f38548764bdb81efebade794a94f2620d952771e529048bffa392b4eee2469b566596df2f504b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea3b8c541a4e71551d38f558c304c93652058526353cb78559cc0360c75944e222e11d11165d1f46421d449b305909c000000000000000000000000000000000a6d16729cbe57b94dd84f8503b00e97d27c7318bd5e8c44f0a1d061f8fd83a44ceb5b74c50f5199d469de439ca07f2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000441c138400d85320df25d3bd4aa3577fabf1ef8ca33f6f961dcfdddde3c6f81ade3c0b93d39c4773f5eefa3a1789990000000000000000000000000000000009c637b4cfb300ebfe5ec2c5d8ba3670b5ce13a4ace2b5c5c1888b51c87ba092fd34ea37be80e86d8de7f8669e1653791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e8d7ab01e13cbb9a1e122d3672609e9c26601512b1a9e866ba7b7674aa0c090cadc8207a8db483b73da6d74af31f19000000000000000000000000000000001768bb77818c8e7b9762980e3135d5eb6cec5ff265838352475f109255fc9fe053d7534f1369ce2b1206761e7421446d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084c99e05522447d77726a67fd536efa9d1392d09d59bc5fcd0d7ac6a50153dc430aea09e17dd6e7fd27907449a09ecc000000000000000000000000000000000b6e80c5cc34427959487838223293e93c2f97cdac85f12071c6badb0b42221624e0357f01786d83f6c6b4dd8a57bd341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005dddecc56f797e579cee1f00e2513742d4c6d55f00017bf7ddbe37e2e7a52f58200d664f7c821315d40d015f7c06d20000000000000000000000000000000001b83f022f408138178b09c9435fda4b9ff269b22f600b54c572f49d5db7a35d4456c11dba7bcca41514fd331b3bcc051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000017a5d98586eba4ba185cff26b92ba6958dbb31436481ed2a42cd8a3eb2445064aaa96c7698d4fe480a5ff6e2292a2b550000000000000000000000000000000001c16f0114faff885a347386121f32e78e1b17d790e568eba75f487da6bd19e0fc172ef7d751e67dee7066f0d9c8bd0a", "Name": "g1msm-23-jwasinger", - "Gas": 84456, + "Gas": 179676, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a4738cc3156bb552f729ee495754d1c84fad3c00c42ec3bfd0a54be986cb5b23dfc7b4d502c5c7d661ab0960bb66980000000000000000000000000000000000234fd63c2ba4eb25e226795b29a48fa0ca92d8c40724c4c45fea039d0c13aa978754a97f3bcbfd9543112b821fe280a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fdba950b878a595da471cdff22f8d80ab29992011a8ea25bcfd554fe6b809d28d328014c660d825db1f0863b446aa50000000000000000000000000000000001e4823bafdb73f006c7dd0b765eea8f81cac996ef004eb260e3cbedbacee9d6e8c8c64b366d0e94eec95ced4aadbe411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffa8689df9d14a11c72816983fbcecbcc480671365a7bb6f8006571f4671e777ca42631a671ab4586973e77fb0ce9dc00000000000000000000000000000000191fd2134edd82915a18e7f7804073c52f8d6ae95b6fe6299618e205306ebbf5d9e77805181d96294a7908bd72b5b5f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153a48bf28d40ba06ba0c754d355d616542153b46b383629e5c6993e40cf5b7f6068de7c4c0d0714ed35300200f614ca0000000000000000000000000000000017991aff5596a276252b61be8304a2930f5610c151fd588ad4a12f1e0d718a43d15d5f95ad20618c7092e61f440226ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014bd03750c8fc5ebc4c213b610e2b64da59843e2ad755611b0b3002792a225e7a9abba6037c0c3f878ed84f257c26520000000000000000000000000000000009c7a068c5a405fc6b13d8c70d6d3c426dce9e0518293fc003e74262839616b1054954c22f07b905901274d9de914dd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f6a270bbbc681b924b87c785f5f91db32d0a3261dd2b15db41e020ddcd1b92d3db3aa82d0c050bbd4c90b201b51239000000000000000000000000000000000141f9139c391fbb7f7286ab2a5497abb72f7eb661deb8f9807dbed4b2ada41840e5093c961722567beb2ab52809156b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d625feff25c35e5b1e7dd4b6670c8ab8e1935a781c492c177ecf91a079287a34025473ce7b1fdbcbe38cf7499af47a30000000000000000000000000000000019579322ff08f6e7fe8e4d7e041ebc1c1970ec7b4d132ecb7cc3fdbb5593fb783929b447892d7ea54e97fdc842f214cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b95cb4c25ae1584ad6599c41c5eaf876b070e5b4e63f237c564b993c57e836101fd53e6097f732c31b23bcf5073ddc0000000000000000000000000000000016fde7d3a596fdf26409506527bfae0597768426a47064d6924a05d6d2919a0c93fddf1c84b4027167d1cb07c5c7aacf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074373e9531023a5e7a7c5196affbd7ce392658f5bfb777491a48a1130cd16d2f12f6f57555ee682b2565115815ef0c0000000000000000000000000000000001342e7e3ee8d68f55d49108d150717cd8bffeede5854302f6e90af0a1e44c77320c8bcb2abb2045df1e96ec003b098ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104888376cb8ebb14f1c801fd10381612ece16dfe2cee55988c56ba4a61e0fdedd6c61e59ccad70494a519e9f9d9a533000000000000000000000000000000000ce442c17ac2e16e4fffd181b8faa022381c07a4d22fce9b15b37e41b91765c89c7cb7a696cfc8653b29429267f699581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c9979238ec82876d78c90fef5d7a84c288baa11eeae00a60dd3829e0977f001f0f8708c8da4945fe06548cbac030aa000000000000000000000000000000001129ab96fe4f45a4e5b3a2b3c6ee0232eae5ceba74ebeae5c0fd4b16815806f1e581c7fbbbc6ee56353fd0c4873874bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003943baa286d9359fb89f03bb6c533f7f0d21818785c45fb34b11f6e606970025294b81319ef8a16a24558fc71c1fb4c0000000000000000000000000000000002f1f85a505537efa74ed629ccd6f3924043f1b287a4e657a1963cce358e3129f84fa4da19ed6dc2664297694428019a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166b30b28044eb0a55f9eabe957661b280a636d986873e9bd5c762e8410144da9e7ec05d523267a49c9ad72f9da044f6000000000000000000000000000000001013f1703b603277fd0d48bc3c08c1562d13ba0aaa1ac1f415998f2c46eb69528a4552559faca7cfe6f266b9ac2c5bf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064e00e52e0dd1b449245cdb0b1b536a3259b94860528d07f379900acc1015386e6c568a14768c071e40155b22739b290000000000000000000000000000000019135f89a51151dca8766e4e951dc2c163553073f640ff6e1ac7c859a764c3cfa02c731bda9167aa1b06280d945813591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f09862ebf7e8ca39eff96221c4d44f73d5c8e82bba5a43e1265fa0af5095e964797be9da569bc20f05b0d1ddb9e53300000000000000000000000000000000151b33bacefde5f34c1ca6270a4cedf95014a41c3e277becde7a94b0fb8e50e7c5af6bd3801e743d57ce682d480b94831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000103e42bdbdf1f56d007bca4e943f060d7309b334aee1f101c9a22c5e1b15c0e60eaa55fa57c7fbd8732998c0bdc10950000000000000000000000000000000002fce06ea3c574704457431124353b62cadf392c3a842bd329096afc8be9623e1c54a34f6ad29e6fb4b00a82278213f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003abbf94c4e00652e0a8eeb45cd4e96ff3b35e7df8f3f4f1213b474636965e537c3e523c380ac56d08b617ec27d69b8f0000000000000000000000000000000017389987dd424b20ed670a7f45506c9b0a283e133c9a84c070490539fd25d4a803452aa6ba8a434ac2742b1f7bcf850d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018786ff5bba07115a01cf0161fae631a6cc355e9e636b799b0150b72d6c0526b717af9efe17657070db9389939a3f3e10000000000000000000000000000000000d1c1bf3fa884f89eb36f2ca1a035c438d87d2188f6c843218db89cecef0dbdcea2dc07c0d1ec7c203d0fc9b9ceee2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001032147e2d14f8dce766db528dc6673545c2009d594e971d42f07c3d9b1401b00d558fd7e3be7c49a9a5ab02df5f8784000000000000000000000000000000000c3baddae6eb4e38c94f3679618f4748a7039f5ef1624c1d78d35628c7bbf8b14f50226598912d5eeb68fb98f15b84071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e459b72271310e5f8e9a42aace59b9aa8cb9d702c01182044e0cb8c2236c30e559acaa68138f09a767b28f5b90de6340000000000000000000000000000000001cc037db3b2ef8298ff3e29b1d9d556c4b3560d1fdde76a2e3aa2cc5e5bb0117a4c1dcf09ddc2f2f4ea794d6bda72971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018845b7230408de355c94d234107b11b635ad3e828997996303f5affc1a246a8865bd8e051bd1f453760236af55d7689000000000000000000000000000000000c61e009626cc3bc33b6857c49a32802748a196a572e6ac6d0ea015a64bcc269b1288bb5f12e614ab981362ab229fdfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f92b8da86be8935032601e475302729625810a789cc7840a9e29164c8d66df555a16b2a40947c42403d24333503ae700000000000000000000000000000000042c8ee47c4ca101a8b6d0d9b8928d853db5e3de885cfa48e39d8a2204751691dc32922f0b3bd14f5197f6e677a45b731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174800ed8fe830ef9e171c8bcfc0af5a3c3a93cd50678a62c318517359345e64cf436374732ed7d1cbc0bc005c84bab7000000000000000000000000000000001501da61cbd8779ff03eaa50fc83db7b7166d7f2185338fe91bb33606e279adfabb6595600854176fcb7a2951da5d7eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055e2d4098057e21d22f2279d7deff63cb14d73ca4099fe1511d3f9e714b62dfc1478a12798080df78f30586088df9cb00000000000000000000000000000000117e2de8668dc49d5a4cb01147cf5970687ee334d1368df17dbf99fad6d9fa331acbeb6be770641ebe4c1229cb5697641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000001d946f05084daa8a79841696400f81d374ea47bd4d4eb9f657bd3829e8ec3bf2f7c5507cf629cd323548965842a8bf100000000000000000000000000000000164412723364cfe2ea2cd8590d9d5628a0930f9941021a6251198b092a833825a97d26a68d1aba7778d4ca964911d42f", "Name": "g1msm-24-jwasinger", - "Gas": 86976, + "Gas": 186624, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000235d2408bfa4471db485cd1455cdde3e04827251c064bd4d94d5cedbcd78a245cb84d8ca2f371b0641cfb01025784f000000000000000000000000000000000c34920e6403885dea9afec556c72449f3f1097f23024a991bd3ce06ed598bdb1083b08b114b34980bc1a173ae6ba9141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031eb3fa83089ac3084ecaacb735f0b6c4713f0d231be19def1812c1e589fd44dd436b50a1f4d13f5843676f0da7879f000000000000000000000000000000000ca643ed43a8461dbde574b5d54b1e6fa0598509c44c7595a788f15f7ae2e94bc8eba7847bb6b9b594142d57032dc85b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056ad633b5c181526d4499c63b4b2c136896f5dfa0bce582be57cb0e85542d5a217a81c93b9d2bf930119618332207c90000000000000000000000000000000013aa0a2dbc6ef32489879197aff5918c422665e8a1d8ee3859078bc53252cc3207add13e9c1963ec0d197ae2203972c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194bc26b94cb769ce7635982023a42c2a320d5dd0ffd75de1d923f99c57f2f72e15220dbb1606e4c49dec53a738ab54500000000000000000000000000000000032242a58f4b6962b49078790f52deb75d3e71fc0a9133e5bcd4c3200ad62c3de67b3584c83860dec9232e2ef29248e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9eafdb7d3ffc72a3a38d0b41e7c35e3773636902d33b210ae6d27d08cb3d3869abc8ec2972f47bb2c7d602259205f200000000000000000000000000000000059b81a9c06364a4c55ad532131263784196201cc6d8e1518ff012f0568281d92fa1588636b4bf48d8bbaff7fb77b5291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082b9cf43c85e5986f363c13da78cd2cb9709dd45ce965467d717f9512eb0cb482cabc220a2d28760a7823f28f624ce5000000000000000000000000000000001687613e9b94fa39bb943c3b4d8d1b94b7ffd19a762fcbb974f3c987e821bb1f275f61bed5817b98dd745c18d5d9bf871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e182430f07126e309b18b1611a773e529ea24da52cf2d5577feb3789cedbe9e35ac6ebe045f34b0a571bcfa92125e0e0000000000000000000000000000000016c4502a44fde0de2a4135efeae38148bad8fe1b07ee6c5b83f5530c2ca4512543a650342c935910f1a852ad0f6058dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc9ecb239c30ab970cd8c616aaa66ab01f4e70dc32e239a4bb09fab9e8a9b1229148b658e2c0ddf3dc4ab7cc93f50630000000000000000000000000000000003b87365410062d007091bfca6df1528122afb1a1dc7fdcf25dc28a023b6cfc320aca7eae1eb0d8b9a05d51eeb3edaeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b8bf43d4dd7cc4e415c8771a9ce73da1806f5c0edeac9c853a48a095d3fd0950585ed6869757ccd12bd6ce268bc65000000000000000000000000000000000dce832d95af32b79b941e8859ea5c418508613392849b8f5b327f1c645c66648a5b80637d2123c02bccb150d6d0fd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e36c36ef164dc542d249e6a38f749c0ea3ae0a1a401cd8026be41e69f43eb14a74df55aaf5ff0e8994c25890a0beb900000000000000000000000000000000023eb730f755ad6728619093eea3eade4d6e263c41fd673c3a502e012637bffbf61041b6a38baaaf8f4fdd276954dd021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009eae87eef73beb3b94052a4567761b797ee6a2d9e6faaf0ca28aa50bc39f3b20671a70d6030cab34d86504ebce75f680000000000000000000000000000000004a92c32ad072ccd5ae26ecf5ff73813c9d7cc2888d40f70f31077775a0f547d140d8ce142e5164c5763e9095e9a0c501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185b76dcf2c4a0190d40dcccb5b8b2d549afee8d0950a33a7b234342e62e1da6bcab0eb5d6383437bdf329367e74f6a400000000000000000000000000000000139f9971b5bfb7aa7a0f0e1913fef4c338599161ca04a2da4a12a1e26f068958081def6b612c58e2306c08f8efdb50b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043d5e7aa03c735e6d81cc70ce636431fb79414ba924dcdae39f71a432507a06ccaf36eb4c8fe868a8d3453c3cf2cf4b000000000000000000000000000000000e261facf6200a1043444c32c2d207eea995e88f4dfc0a8a4ca4a57701bf858f9e938d17705b1016b8976869885410ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000854e02008b6fd4a78fcb704c3c475790e2daf7e4aee6e92e6227efd84123760d7ee01d1992b638392ecc41e8efe5e0b000000000000000000000000000000000e5d6bf1b1c2bfab353273d2ceecee4f8e76bb7f038ba25a142b2cf51f653244154f01f1f684aa04536c6d932bb9f0951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f293d464c06742d0ca894275919e1e30be57d39101fae62ef357fc73d5f11b2e5519bb9ebd51d39594164386b7d951900000000000000000000000000000000188dbf2b794da389421832ab76369c0378943247ba4a6dadffcaf073cf11ab45ac877782d4ccd2a15cf6f4acce0372231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a6c1bab7dc8089f0a62581294bf729808d231d3171be45939e96415c61b3df7216e6fa4be5f59fa080f888ffcc679f000000000000000000000000000000001367797b3a81c3f9db9dfb582f15b5a8a710a8ea6fbc6549247fdc386025b95742e23ce942633974ac18fab6de138de81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c31a3bc57625598543c49fc846e5ed4b53ed157ad54f1a114519cabeb797550b7e65711ca5d4bea70050ea70e73290000000000000000000000000000000001693cbba09fd3eb5f1ae522e8f67c99acc4d01a963dcf7653002e9591a3bfe9a59d14a9cf9f56af1b2a4b3ab2444adfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120c49e3d2f222ddc28d33c2859c010a33eddd18ad400666c35005ef2fdd4732c27ef0d5fd4f0223254f09f58197401e0000000000000000000000000000000007d1c9c088c987c90a6a63ccbbf73580a8cc92bf372b38448706270a64fe43e8fb904a489f535678931ad71bc4835bcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041298fdfa4b33615bfaeb8578cba891cec83ccdf1ac30b3dc66616e9d3b22472a72d7712f0ec92b52308bbba9b5350800000000000000000000000000000000130ee8e36bcbbab76692a295e2f9f308b24c04b2cf73bdd8cdcb3d619965a02fca118a6a6cc1c25747f1b0ba336c776d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf9291061ebe11a69f275a5991efe9e508c4dc78652e0e4842ab1e4458f6af284eecbe4967c405078f8236292ff0a800000000000000000000000000000000000a5254fcb787af85ea1547f5e10d6e38c5ef81745c5ff3053eced33b4452338d2fed8619fd39c2255dea2bce7ed68a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f5c027704bc592e57f80341f158f72485cc1662d6eb923ee88f533e96eeea1ff482a73e1f9d02ac6a70ebc545c41480000000000000000000000000000000012b00941f661621f3e432b5937ad19ddf53e57673bfb97a22d33fcae2c1897a9191145e09fcf1599ce92d167a1eedbf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000862c3d342f3334f4d3861d0f9c225e3580726143db68d219d053bebdeb29014e7cb9aa97c20f50e30829ca4cc2da6c30000000000000000000000000000000007527aca2f0191f57127fe5cbfc8186a82fd3f035fbbaa6874a7086378fc273b81bfa74b448f4298f58e776412d32ffd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b26caab542048631860b7e709505250a9a6703920b278ebb0c142923cb9c6bc6916927821a1821bfac621bdc8cf35c000000000000000000000000000000001241e26cf089857f566b81e5d4b2f51f5da37cfcbe83b3e18bd59a20cacf5b5ca751556bea36cdc7907eba9148f48bcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb55f2c57de44ed007d562608368b189ae0828889203c61f233cb34cd39f498417524919907ff416d8ffa13dfaef15000000000000000000000000000000000ba15c6748340796689f986c1cc2667b084d18c271c3b8b1b6f876f52c0164d36e7eb221af8696c79e5f1501a23b6f0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4603c72e1e939f5b45b97a90ebd563c8f4c46bcb81d4e2453581eb0a2689711f1b1f6cb3971407787e1041812fe3a300000000000000000000000000000000155c6b5951ee061964593c14db0a11a1788b1bde3554bb818417f3e043e29276c542c21154872062628dd845b5e0efc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000dfd568de7d285f8f6f3ccde0d341833d17e147a8d31349b585dc5ec885d5b4dafe10a530605b07c70f5b3a835592c270000000000000000000000000000000003d34d6b194088fefdaf30ea38a64e606336cad4fdbc3da49982ce5965c3cca0b4b5e5be05f144a819c04a9c064f34f2", "Name": "g1msm-25-jwasinger", - "Gas": 89400, + "Gas": 193500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ce9753302dfba17e3a5e4e5e565051db2f842aa61142ac238c420a8592da4f0222b96a6aeb64eb277fb33f296aaaf0400000000000000000000000000000000007b543abc90ee8ba44c789a9746c6617b40c680b94655e3dde5d47092f2b094d77f446dd19ef721145f96ec851b21371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000839fd424c87a71b33c34f86abb6ba1473781919d9cd9f834e1d4dfe66bc9c31366c235e8c3284a565c29f1fe7c293240000000000000000000000000000000006621867beff4c6d93a8f1339e26c5c376fde186395f8369d3b891b03db5890b3d51f0a8f9a79456c81551e2b58027671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114691463c74f51dfc471dae3f0238a5acf3456041504834d8067a1d15931fe3a5dd2a57dc7679ffe9960fdb6257549d0000000000000000000000000000000005565cbba6925b650ed20a68601078246761e5ce98a27485a03187ee5eb520d2fc2e209c4b71cced73bc006069b42c221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000953e39807f846b1aff5da72d74e8cc979ec6636bd36eeb660759e363f160cd4ddd0f4fdb92f52cc14dd981b5fad09010000000000000000000000000000000001a9a88166a9a18cd215aeb2cd0aaf8442cd7113943bb1b6a79682cac5e2f3b1944e397300e3ddcbbca66f305a5138a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db7f955da72db06382dec5845ca0eda17d403489242cdec8865c6c00d7690b08c25f7dfe76b312e439a01ad3d36679b000000000000000000000000000000000d1341742c79e98a5e70e9c8955d5dc42147e3a88c5519d8671772589151ca669a7ee7f2a22f8a185e13875c23a3ba841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b42f6b3c01b08b48b4b1efa9de673b37c2ce3a79ff77cb8e170455481fa7ab15357b268c9650107b02cc7ddb135e6200000000000000000000000000000000019b49ba5762e50262b8ac78c171795ea2c3786dc804a83c8a316202bbb4e5704a8b1bf36fd4ad0054d15994d1caa98aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a44b1bbadee3913218bd983343cf6e206ffa2227b9b93057ea1ebbf4163bf2df148ec688ba124f59a046738712a6b090000000000000000000000000000000005fa672348e03f87fda45d637da4c4d62ed8790d8ee8f56cbd19b8ffb404c9f66d9777d9aa85ed20656720ffbce8dead1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067e195950b5267a0b6c43f51e7ad66676d489e0760f6ffa7ea92156142d63a41edabe8e64787ce4b064ffb11b7bf1bd0000000000000000000000000000000000bd92e95dcc7b62f4eea980324d49fd200003d6433562fd2434a7bd42b5d34c0a731d34cdc80b332311f26461b5005b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001393da3e85fc1e50d8f1f9424de7290b868ecb5b23fa96b543400bd13e172f76f74e107497a93a2ede02493f22254087000000000000000000000000000000001049d8b1d9c88d7a6d97721ccc3060790f1994e43006f1469fd73858e592f31cde817457d68ff9af489e319fecbbf9221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbb2431e80606a506ab625bb598d27d494b3f144638374d416b43ef6af8de9548282bd0a0ad83d5dd707fcc156133eb00000000000000000000000000000000158235a7cf71509cf435cddf76d1a7541fd1c072f9183499f0cc200d971c46c9dc4c3bf4d6071436719e70db726f1b471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028d7287529c7fff128cab1bac5fea6e269ede300c70c651eae2cfdb9285092a4479421edf59d80577224c6958a43a0f0000000000000000000000000000000017cf2ef1ba9830ee8b0baee5defef6ba289d4863979cc956c102cc91f7f1c889c6ecd0b8cb69e997b983ce1d1e3fd4b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096190d31a3bf0aa4f5b0acca903945a8597e39c2e8e5f28e1a86cb9c638c88983ca185ffbfad0a1925af1e581e438cd000000000000000000000000000000001298b5bee0a84caf01386182a7ebc1ce9db8c2edf9271d9c899ee54d6e5c3cdd91d7fa93339d40a1dae99231794968791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f40667791e7e3593edcf82de9b29e0690ad31c6144aa3816f9a30dd058a61686d83979488878559457cbee07f6e330000000000000000000000000000000000e03fa2472b2c17c877c62bf209b4598104e70c8ff8db809d40a8d65167acc51ca18958ae5ba83cdc39bd4404d56a4b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000956235f7c535a19d589c7726a8eaab9cfd1e8fc5b4f1f783dc67586c6d5ff688c1a3a57dd8133456549b26e62ca74ac0000000000000000000000000000000015f03253d3e4ca1fd914717bcc1951ca28e98a443e0dd162ba3ef7b6d592174227f143776eebdc58ad4e89caa0812b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e0bd18feb68d0dc33baa0836d9e0503029178b9a757426053523d60b14147985cd9f9d1d3001204150aed625ce63f70000000000000000000000000000000011248797b806a8788446b96dc28514b0f62e5e72e15b889731d1f4a17c2b8a794e64fe98c2a520fc2f7ac0bea03c9ae81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd0278d4e2f05b3b78c3e75cafeda397102630024c97ce0911932b9146d520607f86ce244bad27af14255e0e4146388000000000000000000000000000000000ee07762fdd5797949eb778176fb986e3250a337d46e78394cbf944aa6104e8a7761b5d1b6c461fb1a8deeb73c4a04881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f776e23a46411ec0e8a8a8a15272e283568a389c1e385652b915754d385c38dad7435ae206b641d25d2228765cb1689000000000000000000000000000000000f6c05da2396a75aae5a121870ca31ab26807317888fcc92d8b3582a596bac19efdab82d03248144e7cb1ff22451ff8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000559a5cec51b8fddf3d9ab751a18d2302acbb2c8071a293416c36e7bc65db6e4dc2da898d48d0551676e068ec2c966dd0000000000000000000000000000000019917b3b69815984664f40f4442fe327c630a5809e68362d20a555c086a06001775e4550bfb9601be4f451e4490c8dd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001744f7cc4c51c0660db599c584e63f26603d3ac18e789fb8d7e877d47a78d021db04620cfa51baf14e9ffbb1dd35258c000000000000000000000000000000000b0177b67edfc6814805cd51e4b0dbe65e493d5a2ae74f64346c2b5c2b20723497924d8676c927084678fc9fb5f512be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000598b2e5bd540fc6f7fd37140308e3c8e8a20a4ba872e1a12ca156ffec661f46f10378bb68b77f1b050dc08a35aeac55000000000000000000000000000000000e04d91672b1684c2581d249e3e9ed16335403103a9afd4e87c1acbd5919d630352e591e905b4b85deb3e999368e0cfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d0e8f69685726e0394c17e79e6070e13d4ac1c84951965f93f6adaaa24d7750efddf5f9b5eccf2afba07b658e1a2fb00000000000000000000000000000000082213946c007b425169cdc7357188157807996c2050cf9c29f2f4e036fe5ecc06102deaf170a59cb13eac96238282941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193691ed496b5b20c3c3cff87edbe09fa34ae312462b0a516cd44568d89d9e4a75d8534e24eb39d489a3188f5caa9d4e00000000000000000000000000000000077b0e6645a6f16391df529ec4a06c26c752deb2445ce7b96bd379063285ff3a0adc7b4becd1c39cd2fdbb739f2074ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008984c29d334e3dcd9d8ba70037ed1d7320747977f564c530773cc76d234d915cd7e40bb5eff489c1f00b2ae49b20ccb000000000000000000000000000000000ce49b8d792706461deed4d79dab50442c5367447cb46ef71fac590beda2898051a05deed8c5225a40001656fb94f1911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c492fa47c395e8b4a39a994c6fe56c7a31e0ba8e10682cffb9d814f17f2a0cd176e048d67d69bb29f6726a9951d1b5000000000000000000000000000000001770a1d263499d3324b522c195d2556f4e9f1c9537f55793d986d9f797bb4a53de66a8939b8c155e13d51f12caa1512d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f6f24e6b2fa011e22e39c8be19e98985a34e4949af5682ab16058b509d9365678c0af4d72ba7adbfff44c84ef79f680000000000000000000000000000000009836ad460387009597a8f843eb9f392e0488a759801db6ad230fcac6d641f9a53779bb2ff9cf20b9743638af501f5881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177d2e51294e9f9ee2061410008c607f408f59b8e48136af8947049d27b30dac84113f72fb2e5f675d5515da960d69720000000000000000000000000000000006e11feb4c3b75f69583c40a5870bab583235888797cd9fbc76bc96d95f2f23f41f25cb68fa985578720f309e19015851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000012998698282eca2a640581744f287effa3e7d8c7a4938371d2d5b85a6b8c6b20963f1d6d8afe9fb413e8bf069522e0df0000000000000000000000000000000005f61450c346340f4534e4c777cde8dbcec7875376e0d7f95da8fc8e840c42d2d4828fbc1e7dbd657d9eefd3164c3a29", "Name": "g1msm-26-jwasinger", - "Gas": 91728, + "Gas": 200304, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014e55c63149315d5a956d037024beabec83b3b4f7ffefaff95653f9b46281197972bbed6ccd8d58821ae361f86e45df80000000000000000000000000000000001cb2ec6054b8eafa49f129d09a9e465c93517232878f250552ba561dd6fffc6c04fb4db2e478eda5b3db4029a827f3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001aa1998a2a4e125b364d96b8ba33328cfa394e99dab85bf94c2acf6fe7c6b9f5731e7e38d5beff058b8b8b8bc7745170000000000000000000000000000000004a2199fc3ebddac9581f3e8a0254f79232b377930459a6dabb4026143776af603bc0078b471c80ac2f9f58402df5e6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c953410c9a9827dc3b388be812413141b8ca8a2fa3bf11570ed0d29de92f71dd36a003d5743365f8c7a82a2f37be2600000000000000000000000000000000114bdf4178449da4b68ba3febfa5f9b94d6c34b542adce263402af54d7656e18c4b20f60cecf9ba5fcc35c71c68eb7dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085185e582bd53f72627be579e19f1e94f07f7bd07989ad2ccb4cbaa9552b8bf9730924d0aa143fadb3f8050c03a882300000000000000000000000000000000015fe1c9a31c606898edca9bfb91be69e97d3058918a4332429faf1d3411d40705db123b42620af654d75430ebc89b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116295fccba781b9e5706293ba518fc7b404d3e1b7b3c33132ca92093590674f2c7e2c1dbae6247c16d18c1c29244cbf000000000000000000000000000000001812649f872b9fca969653d24a441f9f928f67b460db9150c18f9f2912e56a1fee4ec542b8f4999e9e0f5a13a5e06fbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002da11bb0a7c2c4c3ad3e515708957352c8c59b0183ac23db8309a861e3eb4ac760591400d869bd5f86ea98832efe39c0000000000000000000000000000000013ec0ed116282892727388958054a4e61b5877fbb05b38999acb824ffa368988bab987d3d2a7a96de0c4654047b984c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6ab795330e0978856ae7f80ad8260b51de25d379071b80758f12d96e514852e6dc5510133f1e716cffeb0d3ef969250000000000000000000000000000000015b9f40759535222ba456c98cc2b52e44b81f63a235220a60fad66e23a19c3df9fdff8aa009c1d4ef6b7600eca65a7351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000277fb70bcfc2579bf87d49d16cfdbc47270629b43e24f052b48637b412e023ea2edaa28f27314038f5cc36bc4b524a90000000000000000000000000000000001a82d0f81e055210e5411c9e8fa38858d8f13787eaeb6cea4d721ef873ab9a65723d2d48bcdb8d3f4e800e4b97b25ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076fd54045e1caa89b6a097ede403e4638109770b6d414008655ab42603fc7d0ae2b61db284cce39af9dbbd0e5b310080000000000000000000000000000000000d5e7740dfcfda6717eb4174073306e2c67c31c12baca5a49c492f26f04ecbcdc03f4cdc3f62f5e62161c735c9fefd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015026ee438cc215e6c1729580030e347baa5f29871e7c60eaa15da9924cca26513565bbc15ab7caff3ecf03b0e586384000000000000000000000000000000000c4f82be20ea6c14998f1e82e84559688e6c69a154b0de775210e68dd94467179f9ea6e8f79a13565170ee75edae188e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016e74435b7fd76f82aa66bab892f26464fd524ea6c93c91557a5e975b2c235510d3e62d11f0d91e60aee656a3296141000000000000000000000000000000000ea9d99e3046b1b88ac6a670eed9ce8e79106acbf4e159cfb0684bb9465c7a878a8309d3e4320848dfe0daf6677617291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078ae2283d795e04ca54fd087f128768e4b5eb602d0daf3810711db89136679e20653e21fcd96a8c275c9b65bf18f495000000000000000000000000000000000488dec1c26d2f825173c6af1b8eaed3b8c1e9e3d819caf93f5baf3f1c891dd9343575a0c039e3be63776bd9ab5829271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bc97ee113d2a93fe47d7e99212eb4ca5733b993686601ebe9145ddf8c489dfa89f97a52ac02cb9c093827e759c268800000000000000000000000000000000071ce743eed2f579223db24ed5acbe90bddca3c34482545a9c93e918f102a1834e28e959a04f502a910adbd971bc9ea81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041ffb10b221a22d846410172c82bff81c3912daaf1662e450b519667c0ed93a48b3e628b251e1a389dc2f73006d6faa00000000000000000000000000000000157778106e5fb1c2335801706f376ae85258839b944d660905722bf082e4554ebea7d06494cbcb3f8963e7172b69d3031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010e8d67c3ea9f7bb788c64ff6226b25e3793b44dbe9ebe303e40aa7d66ab842063de1b3dbbc9cedb80b47a08d936f32000000000000000000000000000000000c69123f3e892e39a2afbb86c351447483a1eedd67c5489748b6eb09893fdffb4ded1e9baec8621e62a75b4bd04b3f7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000776d01a68cb383f2bd5b3f73eb7a93da71719980d71c7c9186fc7f5faef395b2d41914d4304a6e522091ea718d3ef3d0000000000000000000000000000000013f3cdc96e12edd8ee64ddc66d846f31637bce17bb057514d9b85d141691ac70e8b2a8e3d725a860d9b67b61734a22d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001280fe93f0a9f901e65b6ad9d345ee799a57f296fdc5b27e861639261528fd5fd737a4e30123d9d46183ed0f49e1881b00000000000000000000000000000000018380f83084be1fcf4bd2a40bed840eb8bbab67dd5508e287bc748652a7fbef1705fe709851ec99742ee07bf6cb6f8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058368b427fc6258d57dc25e1cd004ca96e6d1f05e5377a124c7dd5ef07c4750fb1c47a387bc0b4d785952e150269ae800000000000000000000000000000000185304474b1784ef2d0d38e2825849beda13622b2fec16af6a9aea24ed1344810c00762a44be4dc633ad6ae909caa7751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f05de898077e64f93e001080c93d8a753a487724abf52247ac1fe02167293ba0f775f3935c1a4a6868b5f46f69bfb590000000000000000000000000000000009a9d5285526a730f1f14ab85d00cb7c7e78e48b4cc9c247df7612ee238cd7b42ddcb9dd8031c323d9f0c49df0595e5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013654d71309be0b5951d08f8be4b5acf3ce5ab3fd0dc635854f9c919cb7286a9e759d2a52835418b589ceddc6b96583a000000000000000000000000000000000b73df0edcea1f78edbc928b27b34c653aeae8cbc501b3b6001df0a23021b412d6d9f95fa6c56cc5660330e408d5ca7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ce08017ea4e317ad617c9c8c43ec5924e92370aa87db41cce342d351d7b2b67ba16e95793dc293e8ecca1c5a0495f900000000000000000000000000000000023efa50d15316145430a4a7bc87077b79d7a0d4488cf7d4c98bacd7df8565afc00f59f21f67b7cd4e3d4f3df620188d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154307f8674a8bdc2ecc157289270aa431a72f6e2ee1ac83311e4bc2a658350cded79aaca4ea3504a26967a9f296bc460000000000000000000000000000000006a67b4c943607c1dff1b2254ba19c003923314bb7a7e7914034df82daf6e625465411493c56d672e47b55dd6fa3671c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c0a67df6d93799dda1c55f1f1235f1f831b04d69532d6262941beb59e7ea7159d6718a1fd321a953f7bb61f7fd290300000000000000000000000000000000147990a10106a46d3fff1c84987942b4ad845584ecaf0b53512c03f3ef35252d09ecb86e9729c6cc96c9e06e485512141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e894a52fe2e5ada9c9f0355108ec21295bf5ef12e663a199b47d2ed2dc92f25e6a4eb88d0bddcfc7a71f8194e2585720000000000000000000000000000000000cf3a3810b2fad1ba1b9418c92ee99e4f1255674482d76283f07701396cba3a7b21878f687f6374ccf1aa98b4e9184d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba37f285113fafc68a8df3a66b7737e96cbf821559ae1c836ee756b378b77076d76ccb20b3a7c5b5d8720ba496de44b0000000000000000000000000000000004b78e8aec32fbfef577b8bffcd4fab3c3e67f9e054243dbfd5a41ec85c3164d065b482156529ef485120b39ae61a43c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9ec96cd3468c18a6aa7bdde2210c7a05b7199c2f25541349d3fb0a1310a0a61263dd5866c50dc4a77482b9473e4f17000000000000000000000000000000000989801b9af10f39fc6b93831048a936bdb7ba863623ea3058cd63a987d12c000ccc20a6ef661818979b9f31c17deac91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018738ecda79624ceb3be685314edaf3b71dfb43227a33dfd4de2c25a7a59750f05222f360d62d4026698be90bd147919000000000000000000000000000000000188c1d2b8e2e67a368bf31b099549f1fd0ece36cf6d5b384bafec94d78fd1f76937ae0edce19b6180c6994f0ccbef9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000142d164fad514c6a9c1eacb3cf1fcdfb03a0c47d06d9353c445b0017338a4e698c1f05fa4050e21e1ca2c154f237cf670000000000000000000000000000000012896d9f1d7a82231f5f220b7cddd7ce926f4aca902d0e95730c74600eca2cf48a328994801a70affdc307029d3f97e5", "Name": "g1msm-27-jwasinger", - "Gas": 93636, + "Gas": 207360, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b671b6fa1ffef32bc8e4a6d9167eed86bd7de3a83047f8cbda24a60c3f0c89d4d494fa663f3d38292d0d01eb7bbaf450000000000000000000000000000000017cdf30da17cce561475a279d0e02ef333b2964dbc55ac66e7597224c1492b0980f4ef28edf87e2bf2917f62f68fda2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1aa624e925b519767a8bb9bad32fc53a69c7ea706d38a52160ffe422333adbdc6730ce72ed1c54a3a442b59d6ded5a000000000000000000000000000000000fa19e5e45e741056ba3e9f5e902b817c11000469d007bdc5639cee966fbd2b399600fe17bbfb38fb63b0c8a5a9693781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa1d92df06ff59d895fe7c3cdb9ea8efa05ed5f4f27251d25ebf5ac6117c1bdabec5670002f7b0c5ecc526b879d254800000000000000000000000000000000119c68fc18fdf89e2c64937ec8e450db95ef15f7301063b7f32b200d43ea44d654eb71433f80b9d6ca032c126f5aa0171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd4d1adfbab369c4c24d74dfb634283b6a90c2c7fae7143dad5176ad0a5bb722c3f1ff6fedb10555cacb23614ad43e800000000000000000000000000000000099ae14e33d2f94bfa1f647ee91d28548116e1e606fa75bc3133c3cf8c2a0e5f7b8231ff4b8246d169732e226df370cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001650df56e0d3ec45fe1dddcb69b0a9552ef6a3ee4f1cbbf3a2ef6da8bf688a7612260008691f72f0583ce6d2138dea510000000000000000000000000000000018a88b162afd631195c1e50b09a76615b4970cb4635e3d0c79f1c83f8a2fe1cd59975d0641baaae7d908d5dc445f7b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001114eddedc8a3dfe331b348942a1dbf2f0b739067bb4665f21a0ba159815f742b0a9c3b81df27b2a033a914924c121e100000000000000000000000000000000118fd3e50660c5fd6660d28366e4d06372e4e59351fef1748f8ae1e1ae0215f026aed79f94f84b8130ec55fae14e9fc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139ac987f6255baa1834ef0b7fe702b2929069ffdd70b222cf25427feaa38860aac072345ddc573bb06670478209e8f5000000000000000000000000000000000347a5d0cb6026304f3b6f87d7435fee667c18bc45c93fddf6dcd364bf6b9582a19e6735f60545a57cdb9f7c7def30931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ceb5f626d2360525a960130191a446b071d9d52c27c9756e359ad427c4a3b2369b7fe72de157f2b1a5857ab9a778d3000000000000000000000000000000000216c57834aa41f7e28afff828823e79687cf975634f1e8ebe173c88ed88d94855d8ad987d4701c05069db15003d163c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c6740f73ff431829d7642ada1c6afb4615d26992ee192021723fcb34a7772cd0149ad876b1b755717285f803da8163000000000000000000000000000000000cd1bebbb1cd783d88c6aaa668e7226a3cd83142e2e02032bf91e60c66c9a1ada4356c660fa2e9f9e7e33d481895979e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d032d6a1d26863f7db9ed24e13c3560d15702a8d94fb2c72aea81ad3f7a030c10fdb1940d1fc9b1340ce7c57e61c2e000000000000000000000000000000000145a0fb5f3d605daeff25979a6e14b5585ad3fe23e9f355ff06a15e5ac376d4c936090666c968ed5779fb8f60ea84c2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c60c8e2be4bb31c10c464183b1acfdb935d63b4130a407df2e812797161092f1e2fb6f9a1b6430fb3c682ed609df14000000000000000000000000000000000ebf559e9aa921ad6b57cd1cd6a42a424fa8060f8c6a1329784f6e61f458c6dd8ebd89fc3fbb405c458877fa30fdb0a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043cfaf034d9911fe9f93dae1bb114b067d03463e535e44d1ca3f19bbb5d68fc03b31f8bb860135387e368f093cea6d90000000000000000000000000000000006074494ce722cb508b4fc234a4e2e666bed50c2232284d52a111c6443060e386e5fdf2de637b7af47f5689c4d6cb5f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae7299f95b9fac7a4591f6c72e2d4540671bee843dc603c2f22bddb40704207d3385df1e84e3b16257aa2d7f1385337000000000000000000000000000000000c9f9041058a91edbbc5954a4cd45e4a8428d2dac4f98d78dc569f7cdf34afe6040682e8836684cd54a16bf3c766466d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff5ba8b9486cc75c51856937895485117aabb33d5764a6dd7b0b5d20707f5c118294d937821094c6f0e90c829e93bd300000000000000000000000000000000165d7827869ce6c1c126a14630d2a19c086f04bae51d2308b9da21de83fd7a16e48c023eb379ca2fb95deea59a8ada921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010238de68aed30e74b5cd1d97bdbd38758aa7b5e35a3f9453a06c9f499ca403b03ab0b06548d090ad59a9af89855eca9000000000000000000000000000000000df9288cc4de7fff60bada1582bbc66023ac149cf4c540211ca568d6e495aded85340f18eed6f6767f219e5057ffd5921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cbdc98bccb1f34cebfb31560dd17622c3e61531d53fdc2b93902b7ccbfb6509b28edea43d92835e6ed233979cf5996000000000000000000000000000000000ae6dcfe1a032ca82fe93cc363aac9dff13f08d8336603fb7e908f9ecfae6748a51db4d34e3fb9ead827e8c0a9d7ffa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030651dc35e5ea6553b365e0746aaf7e6b5fdf8d2ddae4eaf0b6ad3d6a79f2ddc6e87e63ee10afcbb404eedaa41cbc720000000000000000000000000000000005a791c706130587a5340b53a5fb8031daed1d7ae980a13843d9bf7f6ac847c62539469e6e079a30cd661ddf43cc29141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8064e76148d1b44438a42afbf4d8f7c0b1edf9aaee022ab2291871641e67fe679645c86bac99b769b0d6a7884753b200000000000000000000000000000000160246a845870954ce70e3d17aba4cdb0b532f8c495d86a416f9c2e600fe5e8fca27c1fccd00343f663c87b2aab78b2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f141e47cad23053f311da6cb7734bce848f9e89fa271f319376114b3a6b74c982bf3250edf2b22d1cd2f99d53d1ec300000000000000000000000000000000193a5ee66dc0b1598c0579c49c77c1c3ac99a1441e9891cd9594834866b08949e4ff8fce08825a793a6239a06a3c8ff41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b923ddb92a060b1dfcae175fdb915e401a91fa8a5cfefd4ad850c1cb505a025d82e342e12f01679baab3b2ff540da00000000000000000000000000000000001019ef43bec2f4c10d8e13cb6144492bbc4e90ce6ced3baba48fb0d127f69c32035ffc44ecd096cb9d2cdc51d6943cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3b6b90ef6b71e7dbb152f874f2626e1732cfe4f89d1ffd66f254a19145e5dacc822950930dc62f4cd1a6c2c0afc0c60000000000000000000000000000000018a6dbf2620aaebdf0fa34869ef0d3dc77ee2ca2a28b4ac3ac8ff7a5d69f451fdb6bb0af67095777c39794df5693bc0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a97c90bfafee64bdfa42c46db15c222ee4efc2f2f4e3e4b3a156586df14cf088b442136a41df42b2c2a275626fa7b7f0000000000000000000000000000000013d11eefedd5859a95a8ab5e867253b55ca4e62bb24057fbcaa8f49ae1af9b46cd03a43f734a6b07eee531ad39c817281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019744d870276c2eb01b37c57fdc16d0ac3a887c7fb6607e8439d4d878aa20cc7767e4ef9ced4366bea6b10995231cf5b00000000000000000000000000000000175236f548eed1dbf17ddf14570f517a78502ca360c21c2e274baafe806f15de0126c5e4491ccaf1071e4f57dca1ecf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000113bc3f047153acac2eb9296c68eba801615f4bc68d1f4a031c43c827debc35fda79ed329e2c763e0c4f635fbcbe4250000000000000000000000000000000000119a6fa45488f6bd10771ae34b32a35239eaea4031d3728e97b308f1ba119634bdcf1f5a2763f44d179773f6d537be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8e207d65893e94e607181eeed4fc6a5ba830af32e42749eea44e44660fe9136bfb6e27a2d27a75b4002fd96279c374000000000000000000000000000000001253c67e4afe1966c6bb4c0e2c841094d9eac8927650bdb00c8022221f6aeb1d8ef5a4cab294b7f282b7b5955fee95061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000981f51694e12c93146fa131586d647599f9d27f25e6aa32d49396e1aac39b567675254f0ae2444acd6c8645d777e09300000000000000000000000000000000071bca4f2a1cf2684eabef0135d99cc565b5617b46267f943a3f7b8824b7daf5a4ce060730a85a4e07a2436282de9b921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd0877be99bce859fb6af140297be415f8b0f38721f334372123becb4f236a53cf87ae39d6b3efa8e6446a6df7cbf9b00000000000000000000000000000000031cd6cc001854a3dc70afb8cd459a7d18861e1884c15637047eed07d3b2f06c17edd27ebca6e046340981aed8021e241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d19bd27df46dd6806593ce829fc39e158b2508d86dd3c2f29a78ddf091dac53c525e00be9fcf81b5718e63f98d0ac4000000000000000000000000000000001674ae0d75fcadbb00bfc456ca00cd7520be271ca112e8597eddcbe9a140c7c5a2f26eeafa9ac84a06a06056335dbed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000013037f535e801db713c6f08138babd1eb66cefdd9166398cc812af8a5141fe8948a9f7fde4f5c6fc1db3a21f7f51431400000000000000000000000000000000099abeb171ed76775e3316aee3fb60f1b2ceb285a4527eac7c05ab250ca461b7a694b4cb08ae119bca13b213331fae56", "Name": "g1msm-28-jwasinger", - "Gas": 95760, + "Gas": 214032, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009deaa7bddeda215550f788814fca12048d24493f66c1d261dbbdedb7d1bd4a1e2a7583b7ad301dfc4aec26bd192a46b0000000000000000000000000000000003be9888062363d820bdfb497cb4ddf78b1e9e4224121caae5642d094a8aa578002152f369c3327f286610f62dcf9f2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159fddf9515762e6d689cd76266ea3d5c6303770b9f0ecd71a0a6319e3e17d509eef8ca7f4e948fa2040eae62fb7e83e000000000000000000000000000000000b2319cfad5d7002c083a99ee1c3fdd7094740831338296d3f6847861664636c390f293f655b6b1463c3dbe664901cea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e227e03891b9c5a0ec10b75c60b03dbf766287205a75d2d22f0b22a0a7dc7478d7530f61202cfda49186e36ec247de700000000000000000000000000000000194b9cc68bae6984c52f02e946f110b2d0316e1f298ebc96a53f8b7b2e3e06cf9e1ef518ee5bd46b64e689228e6725131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e8fb17b172b7db9854fa58ead9b58f62ad838bb903512131710cc4fc946f878186eb01bfa3021fc8e716a0d2adc8d20000000000000000000000000000000002a2ef05362b53461d16bd2176922514c7a50c076b6427414565a8b41bf1d83d5998df3c3d7cd7d8d1cd6054ab2e6eb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170092351854368a668c0e11b768755359fec6c197bc48aaaea04f55c2c5413ff3be56582461d4fd1b3e07a5b776b667000000000000000000000000000000000f71931700a45db435c1f9566699981eb1840d569a72887539375f9f32bee8c4d00221d9cf52ce8a40a83d421bafc7d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134d46c376536b5192c36eb24c742e473ebd7690c1153a3d0ef6c1af4b727c2bbd99e3b96fc9bbd9684e7b9037155722000000000000000000000000000000000e6d7f8f63f46f54f28016436b068e4db6145ff45d42c703449223d6a1f6e0ebf40e635631d0ad9f1e9e030fdc7759971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175ba1080101e04501bb4e79024ed203093691ea50a5c2553eae7a3f4a7164844af0b31a60840aa327bed5f98379bd120000000000000000000000000000000003eab303c85225e60655539b73e494b144787c03ea10bedbd919071ed4b32a308a9634393a0db1f6500d16dc25d482901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127fb8e7f0e171fbabbf13f2512cb8656481480aa5a379d5d84f756561714e3de305dbdac5417bd50c183325648a776700000000000000000000000000000000046be9ec841d1f62c3e0ee1d380caa42741197d280867e871ec37403cf962077dfd981091b5c67b97666af7bad119b681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f69eab5b387de9a58d76043ef789fbc1a876480294b56f4d377b122ec12d09b3fbb3aeb929d6d3c071aecc9057ffa6f0000000000000000000000000000000000c2c8ba062a054d50516d55e6e9a92d2e92ef797571ddfb2d5769afec873455bb275bfe3ceb20b01fe29ee9cb3156321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037ec8ccc94f09d3d64aee1bce7e9cc3b71455b8909ec20e4272e9c3b25df66214e6bc63d0e03df16dbea548783d3f2b000000000000000000000000000000000402a568af12318c840cfd4e0875d0f8989184c9f3beea7f6fe6e6e2c69a2a751b8d70b0f5e237e13c6cc4c208e772ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b38314c062a05375c5b6f945f8b99a81ed1fd4c8c9dded5f9de69e4dc6d49afa505547606c28deb0b49cdfd2eb83b400000000000000000000000000000000166402ae3cb07937c930db5a024f98017c8ec14a78a1c78636c54558a5cc9eab6b9a061f4da0fae92c067783c90629bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000673e6cd9cb0fcfd75a8e950344a55a249d4621bb2fea663f5a26e3dda34e792d401b8337d6b0ba47c6dd2d5870d0f520000000000000000000000000000000019947bf5c3efdcc30e489118680fa4a149cee2ad3d2a3342777a5324b5a31dd14beca8b7e0df8f184afaed525a33f6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007301aa9fddc2daf6470cb3dfac1648048a554d91b51ab75797497de3be48200482ce313eede021d3dd0130fb4c3572800000000000000000000000000000000124aedda89f48a4e48110e179060e928dc14ecebe52e5a69ec129e9a531f3324370a38d7f6fd30d02551c6b675dd249f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2455a7896cae11b394cdc78404003fda8cf4d8b430475d64e3b13904ba2086b2702313046955dc5a943ae64b0ec0ab0000000000000000000000000000000012ca266c8bd0471ef9d5f14bc40a52785aac46f9316989100c7521444911ef5455b143e584eb5bcc6e3f11ed46ce81861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ddf235c26358701ba51e8a25e10b8d65f300194d964939887a57d5772c1fc7f49b7261396cd7449add2bdfdb86b660000000000000000000000000000000000bd1f2fbffb103a9e852622e0c08bad882a70cd468e96db6473b57805de72bd3cfc306985d34e5080ca999b4634a90831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011680139072a57ad5035181dede494d4a71f56a543368c63121989c248ebc8b11f5eb03d07485cc55de9f73f5eaabe66000000000000000000000000000000000d4e543d023bbf26c05a2f78ccd29d98e112e69052055e621964e757d93ca42b0ca54b2ca3ca20eab956d84250c2a4c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc35acdfc77f6d37a3dd8badcbc53deffcbb14bf5833722c17fb8e5cfeb2baaf8c59bbf5808e4660fb22978ed6c6dd50000000000000000000000000000000019bfc29a2c827ea2c4e0d34ac661129d93294b80866d9f20e844ee0e1178f26b39c1f0b35359f5b8d3bfd1f7943b145f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf21e612725ba6ba17ec8078796219bd3681f0612deb1185949ddb35a863b7fa7d162e7908f676f9e73d1539d70c68a0000000000000000000000000000000019595810cde3aab9cf6c61d2763794ce83bf315ed87c59e5d8d9adbefac85c100d9f57ce0682cbd8061c90cd58d558e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011032d0bb6344b43f554082567b2ccab9b296c75d0b4662b685b8aa724132fd95aa756f3d4705c3e381d3f6b0ad0de6800000000000000000000000000000000082e15316752ef17a981397684f0f21f83a7d8d5b00dbd47e4151558dc5ecbd159a3bc79d458a11ab0a435cfe0579f911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009804eddb57b83075b6eeee8acf7763d775900ae00f32212834cc04ae72da1a019af1c7fa10dff5ab11d7b5a78d0c4930000000000000000000000000000000007245b4f65a1c10cc4a3f8c268858b47a63cb18d28b8b632e3ca8d86cef7adc9f353855cc25294bc4420c8a0d2ca531d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142e37cc5cd8e90ae2f38e6258a1696dcc9bf06310810322a38b912ed79f6ca6e33537f225a40c0284afa8fe3af8dce80000000000000000000000000000000017097a9002f88ca4f4813eab7e7c0a25eb56d9b9884810f509aeaa19945a5fe2319cd143ec05cb07524107c6f95717df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003bab6716625a5ace741ab06ade2a7250364e31e7f494c7b6115bbc6e8d997afe367085fdff6d26b290a456223f179b000000000000000000000000000000000b0dfa444f8c53c60dcdb6792a0eca02467a7a77bd399cfc9df7eeb019e04c16a483dc3a82eb372fc21cc1403a0466c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000625fe83733f861d953ee8e683abd3d89e39014239afd3b2d6f959ab67e24af137ab439dac224fe3a594d1a5af3bdff0000000000000000000000000000000001333ea86ae79fbdc5bd10830d772e5ec989d41efbfc76c02a7c14c0dc3f0fb76a018134aa2cb70a059b3a9975ee791a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d42dfb90abda27a0b9a01f4e7f14cc07c56c59c465e66408c89e55a47a4b5e9173da20882d83ecb73e018209e2d8d83000000000000000000000000000000000a6065ea4636ba4092c4b502c9d95402605054852717d061824cb371f0f318f72494891f11267c8406bd5ccf9fe104ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b161e5409f17c5d34a0e1fcfe849c08fa070b882099754f500fc8315b7e746fed39a42769019620f9b8e05def94cec90000000000000000000000000000000014e1cbe28dc8c05f56e2d914a3ecfae5407ed701197d7bb0931dbf7554110c44354e2427f26338336825259e6cf231c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159256259e24c01fe2f2eb5e5af97c3709dec85e0570d754480f02f7a798f4a21b7eb5f466e447b9f17599e94d15d01e00000000000000000000000000000000121743fd20324d93803cbcd0c984fde68c8cc44dddaccc95853bd0f1e2e4b99c9aa99e40f56bade8b1e8f5032c16dd141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000677ceefab74f7ad376a80aa3697049241c048995c0db22bd4edfb7086d7101efbc3d2a456aa888d5b77c1f1158a016f000000000000000000000000000000000cd78e0050e18b24ca36e1d96f3d074e97a63e63e8199785922cca29f5aa03ec0bc91775e3f4fae78675659c563780131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da3a712ecc9ce5e7de1501186ff3d6849656bc254941482f3764fa0d05543a9d297211e23a8d6eec49ef22d01e9dece00000000000000000000000000000000051d20af46f3e036b1d1ac2285adc55b2f179a88c86af304c11989d1d372aef3f1dc73693adece66cc8b1e4c5fd0631d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157f4fc7c1050039151ccc59d8e59bf2cb95198200783551bdb21ce91ed00e9db4d5059b4e690dd731048ae53cd54cb700000000000000000000000000000000152a0f7bf648856e76b616559bbd89979fb07e96be084bc395712411b07dfcee27f4576d976ddd4ad645f72548d67e2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000004b5883f1d8f8a4283c7ca03f9b45c7bea0796daf50a62073464c91a10ee4524b842daf754ecb490b0f44641cb57a96a000000000000000000000000000000001199c4d8092a2213f2759f43fb4b755be20494226192421fa1bfab7ecc6c4b8034c84b1a4df2cc2afa563741431b2e9d", "Name": "g1msm-29-jwasinger", - "Gas": 97788, + "Gas": 220980, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002b9e44e06816cfae20682bc898a1ab484b9b72c9d8178225e7e80a6292718de7324f7feaa05c31120274816feba50ef00000000000000000000000000000000152991e2f52f22d52309b16daa0a056bd77f4419ebb642ae071436b85a53baf89253f2e1a6e9cac132cd42f4cd26c4821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001770f05c6d7767a23e43fbecbb6bf2edc987e2a5b1a4a999185bc55b4292e6e29d4e81f31c218a154f77f033492ce77d0000000000000000000000000000000007a8181cdcb96730435243c4c1221f370f90240dcb1ec9a23f5b944a4132e31289540f989b302a54133f594677f1a90b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a18dc7d24e3de2f4e03557dbfd3112fb4e01510bf0f54a89fc2200ffc0a24d290612e2d9554bdb511f927dd118370400000000000000000000000000000000167556a4f645223c8164671c9a0e2d888d130059bf92a62f470ee5780f365dc5dedb5bb0504d7757467378cd35acbcd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af1ae53c18cff2289065889160c2727e4ba095e1d23b78c1fdd5006d63870afe8ec24e68b5ec7f636d0258a8c013f4800000000000000000000000000000000129110a7b8492de97304f5113e49dc8a26615b25c3284a2c5e6e99d96d6be2806996c0279ac195befd13a4ebe3919c901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153b7381c3cab7a5e0e9231544a0f5a2f8ba20b24bfea94ce2b7c6eb4bfeb9cb93320b3aeb7c02c630122e68f436914100000000000000000000000000000000033cc06f57841cb9c915c1b3f493fae8414abd6dd950364d45413996cb261054f28ab34ffa1a36d6eb3b9f3a3992c8191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014748ca48f11509fb638b1d6719cc8f6e5d7568dc4b92e0e0ef5995327bfcc133ee6ea41b7b20bf2b16fdc3bdd3f7fe80000000000000000000000000000000018c9a0fae8ecd9a38d574369b5a00878b42eac3be05afc05775c619d6e86a1a2ee31aa0fe4a08bc6055575681b3c19231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001996bcaa707a0b142491a98eee2dd35d26347ca9c9270fe720c941c02cda6475b072ea3d2b904e7fa1a37dc77cac9e40000000000000000000000000000000009ab9c0b544bee583f597ad2f8134a59d09b4bc45196f33722603fde0f9dc3764aa70608a2590c28163aadd376a990621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1a51eafb917118a8644cd118ed5c63f9d80ba8707fcbb43797cf708cee814f2c40992c7372d00967605e6ec98b57cb000000000000000000000000000000000b7372c79a7a9e35d44d6b90a342656589da8a6942cfca4a059c5961fe0c3440c81cc0407b8c0456651b9b33bb7fa01f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c69c240a6f0b612e3d8adb261683a1a867a1a71c3c898c1e3b7b05ac3baa6a4f8f170c3b672d109dc1dd4628de0e1f0000000000000000000000000000000016800464d803983163817a5c3a9d7e4b9f3e7077119fd2f57a2910a720ceb113557e99958c43a26cd975cc54d5c33e601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ed65f5328a5973f6fe40ff54526f3b8f99c4c8c5dcdb1b288679523c5c461eb7c3d274188c9c21547af560b9e6256a0000000000000000000000000000000001d800cf9fca6d5e479f3076c2348d307ec5b0312a23f3ff29eb81c7ffa455e1d056f0a0c2e935384cdebd2765919a6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080f917c73fddacc110ebc2a81e46d8991858cbac30a698795ccaca6e808ca7077cdf553e26003e55ae9fe3aeb5c1daf00000000000000000000000000000000046ee199d683b9fbf229cc3212559234268072ed91f0f3e250819642b045ff9d8a177cfcbd619f4e597676c80f47c6f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000240da36871d9e4cd927b3efa64ed43d94fde664c4335e14348c856426a9e0b85f43e5ab1cd609cd625640c6985b16ce000000000000000000000000000000000a4d962530e4ed39f36c20b4dac245122920fd657df7ebde8028e56583a7c8e17f93fc5a2e0ef4a16c97c11d4374780e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132d8d80c77b84d832f55e893151c3241b5b68fc9655fb18dd38234962f085e13e6e5b1a7c7c58655a2295dc4dc8796c0000000000000000000000000000000013f45fe46511c095b215d2d3caae2a8b7223f99f8b8c3f5cd9994e7f3cca6d803ac2a06c268629f9c5af18931764951d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc909ec3514cfb8bd03f18135f91362894f90706eb6ca67ab8f1c9720667f6d51aec157c5ba8456922c995a88ca86e2000000000000000000000000000000000b8425cdec7b0457f6c972a0d83ad623224358ffeff8e9bbef0b1e512cad6f5233bf980752c5af8e04d98cf502b62add1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117d0eb9d010a8af979cc3b71988ff0d70868dc9ce4f41dd75fcdf22acb9ddc98266b62f56b456211b3b51e16e2aceed0000000000000000000000000000000018e0013024776e7613395787d4477aea7c3e620155a3e72635b62bb372b94e3a2af6371787b014a1ac18e643992aaaea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000432c30f711ec5bbfbb84fb08507cded0979c8ae7b5804d7c32686460772c9bb87dd65bc2b5376bfeb1dcf678531870b0000000000000000000000000000000019e84f906e902bab0816843e4fdc6e4a10d656883b740def861338b0b11d4e623b04f1dbfab240f63e02e63e9d838e041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013336ce45daa4bd0debfacda1d9cad393aa07f8b95b75c0beb4d2ab88de66611a588a263706bf0e13c26a8c006dcd0b30000000000000000000000000000000003fc7a4636164719c67166671705649bce7ffd567401a6a739e538eca6a1b36a72fb6039a1a0e1089aa37c74615932061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067478a083a4d8e7d86c09d6317d7d93e21d09c29cd76faef172f36136ada680999349d7457728c9564a8b4f3c2e072d0000000000000000000000000000000013701e2ae6275745e1e548e663bd41bf377b2d9b7ec4c3d5c438d5d8228150b0cb92be4d438d8a74d11c8d7f1bc6ae9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c44e8a073951ac9e5bd70dc54aba2094f32273a793916f0753065171c736ef7db0616d013a3611fb57b9250510f5e4d0000000000000000000000000000000011c67c469c906aad6e3a3e5db0ddb0b4dc714ef7a1c13f2906d8c25bc3324370a42d258ea0084b6b4b596a7f22f149811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d856f7d5e2dd998de8478e2e45b3a5396ed0f706daf47625b22384126d2efcad686804cbeeb93b5661622807d4de320000000000000000000000000000000007a8a1cf20242e1eaa9584ba2a4e8ad4112bbb65b56fabad550c1188ad3b7c28ab6c75cc294691ea1057e8ff1b52f0b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e2c633c5f2ffc73ddab8662f8cdf40daf36a1094c609ae4e8606072eeba5da127560f667df714c844ca17f7f497a2400000000000000000000000000000000120a8f621a65e77945bde8825d2c505bbec453bd992784719a585c0d1273a4dcfb405005eaa90102ca3ee983401ea1551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e45fe2e0b8197ceddeb0b945c0a06eb91e19d75dd9056788b67f74e5ecde895153d46ec8556d5d627a1b8ed4b5c70500000000000000000000000000000000062a544d3ce2bcae0c3fefdc5ab4c05dd289db39f9e6cbca8c805dff41d3afd7eb09dcd292379e90bf23e50070d5534e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176631964f888b65bc3a67da9419badf7bc72ef19f9969a9d405e30c693a81c8bd44345a0cb285666e0e21587a1399de000000000000000000000000000000000707083f74979185ca45e342dee46179acc80d638e0e89c729d30a7dbb0d538466b9946f77cc5d8cb5d8cd13c03a33921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015626f56848b08c84d556e3cd507e8a3aed507f87466f0102df73c878e2ef3453f84b2dfd83a33aeaa4869cddf5a66d90000000000000000000000000000000017157627ca5f1715b8237bf846965539a2510e1b06a44223034c01d19e0183148a38d07f905faab699e39774c63f4df61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f0130fecdce0cbcafa3283c5c8b311df2f40512e03d99b2ecade8afa6db400046749d49ad53e044505bd017f40bbd4000000000000000000000000000000000d4a84466e6f880f9dcc59284c61b25540e9f99440c706ac419de9d09b7a0c33a4916746226f34a7775efefcddac14461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000881238bdf4f995971c92cb67508ac8a1864a19d347b24ed330f5c19658b4578e35c23e8d5e2877ce2f66fecd70f651100000000000000000000000000000000093d8bce3f8d507c28808e44d09ae83998e2939b488eac4bf20e3fbe36ef1d1577fdbbbe35bb05a7e79b17cef7f238a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8350e06676f343731f9338f3bba71e1230fcd1527c3bee6af55095898b39d99451c94b1343b26423fd4b761469d6e300000000000000000000000000000000042b7665834d7a442a757383898e3ae5ad10cc080aa0e81f4d142d180d9e0d0fed17d3f3b4c52be96b246845c5724dea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040905a0be06f0524c002788ecef03a459f2af0037e186fc2f43c04ad3a46cb17f43cff1a682585e508a4249bee54d5b000000000000000000000000000000000a4a14ba57219c4b04da5761da72324645208c958f463a2940da330cf66d23e95e55eb86d466937f897e920f88884c061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088f46102e5082fe9513fd6cc424e25b72fb122c9c27471dc048f3e808d2bdbb775c87784582b6864278368d132ad6690000000000000000000000000000000011a34f3a405cc2aeeb6f8fd5bd39f10922a9c01990329d061bd1d54fafa41555b12e05a3e3f440c83497f24088e75f581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185d0db9e2f0cd4450234c1ede55690a38b66932bc020ea7d7e7780453d94d44c08ff53c8337c1a2a267a325b1196daa0000000000000000000000000000000014430d4ce207e06f1430a8529d888c1a1c317ae6d1fb2d86a45f9d91b06e3899b804b52f838f28abc29a26c665bbb9a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000873e0479b6dfc5ef1712a949670b0d30ecd792018283f9874768cafd3f47e9639ae9eea1ad00955dfaec81f19736aac000000000000000000000000000000001946af1f035da684c8896f8241b3563110975108a6f6300bb1a6fbbc182a3bbe72e2db123b137b4b02bda5a71fb33fc0", "Name": "g1msm-30-jwasinger", - "Gas": 99720, + "Gas": 227520, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e3c63ba695a3808541c9cd3b8bc01d53a39dc8fadf315497b5094f0a06ff0a7879e1c5f70206d91cac86def9d1647e1000000000000000000000000000000000166e40a7d6c364df834d6a91cc5d27252711f3132f7a369a64689c6b8cf7b0007a041c09bc0f03fd027556fb1ec16371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069ad3b249590107c37ecd8255156c35eaf3306f4cc6d3fb4d12c83d094b7cf63c9c3429c9725996474da7201fe90c1f0000000000000000000000000000000002b4414d4043936fd70f147583836f33cc50021c4fa16721e31ac645fb448b63a4507a6c1c0f82094757803d900ccae01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150d059fa0f679366b8c41735776ff08f12431e8dec6de1191c75fda59f6e370f41ef5023a47ffc2710e457fc5430d27000000000000000000000000000000000c49cf896e58ce98d4c55eb75a8c7f5177dfa13e6b2a1f959f338c651743265e7304a588a0639de511c7e5fb10c50fa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca343b85aa2b9a01c60ca4d2587bd3e6109d37123a29cb5b4f7465861f6848d9dd537924969f266a2a640ef0ed2023b0000000000000000000000000000000011f27be05c30a569a87f5aa0762a295fa3e3a061703e54a00b33e7f7c6748f5f913ddb81972ff19c070c6fdf37d927b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006319aa506af95457705cf24da1359a39e6ea13d4e79259b92335bcf3e32296c607d2510c79e081f1b9154cb7a12d6320000000000000000000000000000000002ca4018088e8ad085bf4627725d6165994b65a0e101288689c435ca4fbabc2201537e52e6bb01fe59130a8fad97d8751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bae476ae5a4a4163aafe14884f6558663cfcc8fffb8f660f9385cb6bbacad2476c314ede2c589ab3b185799bcdeafc0000000000000000000000000000000002f2fb93be1463a992996b7f99b0082269a23bae4d48788d2b9b538090253978c46158a7416d56d4dea6678c56168b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c1359809b04eb90e53ff4442cab6f2337d3012008f64498caf44fde802c4a367d9193c878aa93975cc65d3d6ee9dc6000000000000000000000000000000000da070d301687721124cceb59c6e5c0a1bb3cbf114d72ba810a7e122d4fcff1619537a1392b1ecf8d8c5858e0a2806611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f3ad6f481b16825fb081a8c7e15087a8dce28f98b1535de8a39c0a58f1053ca8c31036cfa020b09d4b40c989023c3400000000000000000000000000000000157d3727b52fd6601bc47ed9a4a9d6b41b15475403f2b8ed83e8fca247cbb2f2606e2a91efea8aec72f4f191b8767ac41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a743a1c0d1532b9b572a44899ed615123d8b9bc17bc923ec52c345a08e9d255844e1cef633e6781cf2850fa93679290000000000000000000000000000000010a1a5f7aad10e9f0a7d0d63fcc3de086a1b3acf61d86c63c930b827b2c9a22936c3fbee946eeb3fc80f10a777958b801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c20bc4089adf1f6561b71eff4911f77613b45d5a11ef3bdf4973348ab9a868a141bc0af1f1cf87ebaccc8dea41d2fd0000000000000000000000000000000008e5e1c309cb32f07e380121aa7523a2677cccd4e6b47fb1e7a440763a5f92c82e65680dc301ddc295d428ddfb887f001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168a5d2bfa3bfe7657dea14591234b466d47c07f8775325fc6776cb91f93ea47ecb69026f6d7d70628de0dfa92e060870000000000000000000000000000000012562cbdb7e2a9864b3a322c718fa4c3a59e6c4c7c0fefc32ef0573ab414120e7999f237a0599eb3292fe14f64530b231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001479bd549140ea5771a797b50ea9365df7602678ff6ab0cb64144dfd53bae934429fb91c91cee71dca5594761d5c8ba40000000000000000000000000000000001d7f0852112f3f785dcd885f9342a05be6a5548f5ad4b55c705fb448a0ab5070499569372dd247a8e91daf4267136c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c27b584b10530369ec515f7d32c483e7d8bd11c5e60ee20b260edd73d3c67f44322b13c7375fdeadebff8f5a1d5d7300000000000000000000000000000000059b98e9f3dbf54fb476169d1188b260465cb1eff4397c101400924c62314b968fe20525deadb8dedf8ca450445fbc7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc7115dc54b90020f826a60dce917acc9ccb4f02920ef9471216fe829f2a464672cc73a3e978f104d04660051c9d123000000000000000000000000000000000197574aceed901f5c790a5fd14e6c0da12494c68fb4acdd0d68c1d3fa0b0cc006081167069849455b3c24790213ca1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086fa8a7ffdd7e54bb287011b00e88faa72a7537cf6197d8bd5e2abb6fce29f696875d2bc0dc4f81173e08a90e4057410000000000000000000000000000000002c803dc574c1a992f5e74e96900f4067f95ab881070ec92de54b177f3f190774fe2b7ad2f642d26d2811cb1dd3bc2471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f5cf3b11c32f1099b636e28029e6ab7daf7388460ae327537937c164b505f084931a909b80c6f86d6c933a302cdb4f0000000000000000000000000000000014e68a0d87d9af6cea2346231b1afe2f42c1d724b547d4a2c61c2a4fa12fe03ed1cd425659b37a5e718a14b4ecb6cf531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e812e9174195ed6584edb3e3d58d9fa13e0f762336ebef4669067bce8406d100ba8d750ea5419246a718889102726c0000000000000000000000000000000012d6f62aa832318b7d2bda6e43c4ea0820aaa2e8574595fae4029e88c6ac8727b464dea92bf0b7e6f84bac2ec05a6e981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b3e1a579f8970d651341ead810048220a2fb8ea9087cd8ba157002fd01395f22cfb387239de0a6f902f5f410c366ea0000000000000000000000000000000009e7f44a45018c185dbd141c07d829bc6a71dd27e6d33968836aadd1f9fc74396ef922e0833af40485a9b1761089ea7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006569f437dc9b104e587fea00aadcd221c6ce3507dc0ff8a347750306d3e07446b3165b5efdfbd003627df472ce2d3b9000000000000000000000000000000001214fe8fccc3d4ee001230d73fbb27eb333ebc950d6e85ab3175a7e740db710b6dffba3428db52064b4c1e873237b6b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d32223a25964d9ed648e87fad93aec761acb5a3c455ba817b6b4a6b11318543328dd02eb7d680bec8497b9aca7dac3c000000000000000000000000000000001972162a30c9ee4364c409cd843d0f41a82fe7b7484054cb07cdd66cac9216965dd71736b4a5c0e6367fa1ea038fbc501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad4b64141166dcc80987c6b04a32e8bf85f977d53545bf7d6e88caa07b1434799c43f1ebf8d800a6e8ea095ab5807f40000000000000000000000000000000004684fea6eaee9fd39c5c78d46c747e4bf06a9a0d5b66c59a342589a7006a737faadade56744ea332e95feb48fa28b3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195451cedec15c8ec64ab8000d72be6ca7a80192b013b3835ca585025c669b36c0138af4fcdbe280c60b8d59bad8018e000000000000000000000000000000000bdaa74fa5ca31cdee2d39c78147d172f54c421eb2ca4b8c478b3d837e760ba51bcffe324cc32bd4a91e5f9ba6dafaa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110f2c8eaebe78d583a7b5dd30a6d0ba72e64e57a1dbef4981591902062dd25ea7ecc6b47061bff7b43d14093ed8a9ee0000000000000000000000000000000012684227cdd0689746091ab27c9f93b891f6718525bcef91c7622a6186ab95063b6855c8224946bae4a01ab626f01e1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131ed2e8fc9446ef99af754522a4af9fedeaf1f8f4bfcfad5122a0e9152ace72ff79b73600aa997550522adb1cc692f000000000000000000000000000000000059c953e88ef4d699c5aa75c33bcb4535946b2abd081ef40b1179337a860027691114d710acbdc873ca45398554819b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ca086a8eeee058ae8e5b79c54be4b2711ac2a0907a5108c517c1300269686064de1ab4dab9ff7408a990f7580f480000000000000000000000000000000000123fbf931054c4b2db1131c89747f305fae6a9de89ce73a98693a6b25ae1ae81dd30a2ae7d1cf912c5d0a1cadc235ff51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001407a763736f688006efda863e7b3b18d566cbf7b4c3f67668f6c3f87f1cad250f55730ed04a5432b1f3f36429e0e6aa00000000000000000000000000000000075b3400bfbc3b7091588355f77673b73ff211a91cda2c6983e478378998312697d9041582218c21abb6d741a5906c751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005353db0f1023f6a8d7f02a6a13aafcf425176708f3a6b6e18b7428fb1f523a7cb9be23d6b125c4e133e465a7ce9d8f4000000000000000000000000000000000e766e39ac9a4bf922bb52a906a062eccb6310c1e50bae2ae30a8c68cada7a317a8202f7fce5351c62ccb0dbac917abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000124172ed2665f37c89546b903bd525ab25e24f2cdfa3e452ea4be09e5b5d628e7badf34ff4d3454895456e7a3c97c340000000000000000000000000000000018bfc1642e114aac694d20d8d903cb671f803137e14edcc3262931aefb8230176f0232c6444326e552a239d3f07bfc3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082732670056e205dee5040fd99adf4cd93fcf46bc72f0479a3efe73e426167dac3c005940270daf30fa97ad823291e60000000000000000000000000000000016134ed2822a37eb7f14c4e4597efba0b4ab33289ae7898f33627a0a7ac2078e586ce521e02fa039f2e37340dd35b6121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122795b419e10d2cfe52740d69b91c3d1ace2b31cb8a7c67c10bae6a2b02b0412847f653447c53cbf999951abb4422470000000000000000000000000000000005a253270cca0aae4a36c5f3dd8bf60c7f31d336bb9ea7e3cfd42681dc1b71134ea7e6905dac1b0169a7ebe7724253331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001086c589cc0419f2620ce157edc4b011a36c6ef414107032200001a8ca3dbd8954a918ab7fc4dcfdcc52475a0d524c650000000000000000000000000000000015dbc50113ec7cdb433ae00e66bb0631358a9d130c5572bde42a1dc9c5319e6d50914afb6617ecc4b150fd3baba929bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000014bac2a905d41965f5f5a9f82a9002a5b1929980dba64c1e0f8d742481a9448047aaf41daf73eee27ec6127c39b02e09000000000000000000000000000000000e7d2e5665c66f9eeb28b6913aa96813226069589bf3ff50e409eaeef44368908252aabdbb99445734ca0efb417baf58", "Name": "g1msm-31-jwasinger", - "Gas": 101556, + "Gas": 234360, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019d287c613f97e5264863db37c848e9fea9cbb6546399050b71fc5146419cbf301c94a7537403859cd890bafe01d704a00000000000000000000000000000000069075c0942a4739f6dc9697dca124896d76d9c68b038f20111aa5065e2162303b4b0421eac2f1fc6fe7317fe5a3c2b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016aff1c3ddb51b90cff734da0024572efbcbea41269ee918afee86571cb852ba14906c09e4afba2fcb6d1ad5d1527f24000000000000000000000000000000000f2b30cc72dd75ffb17bcf549e8013c277332a65ef1d942317fbb6605e6334ea672e1fc9bfa36ccfafa11ab893d62e791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea336d6bdb60395561ef4336e9937871b8b276d7a12b776e012bc1a3d7d6f3a45320fc0d9ccd8b4b6e3eacd7b1d1b30000000000000000000000000000000007ee33e7f55a1a6a33993f3c661927888220100a0f2651f6256e2625b7e07ee835aa37ea0cd3d06e1b75262b341e29471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000461eae22ddc0592a171370dd15161c63f6ef39d4dc99ebf1af0219a182be0a1cb8ac7f5178a88b36fa192414bed124a0000000000000000000000000000000014176294456404298220604a91aa85093f912ed80d7eac4a4ad176eaea8360b96305cdd003a31523098c848fd0fd0a0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1357572dde202679729f062cbe8ddcd5f880515e57f6935dc2574f8db894d1ad0237f1324158047fe1806e84ae79f90000000000000000000000000000000009c72e9fb8d39a2640764aad16190b45ba5c5b72a2d0b1101fb2d389a36f2a3b60f5363dd0fcd228189b507bcc68f8061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041690a78c5acc19caae338ad039529f335b4c38b2dd3c7132d7e49a15a70147e7d290f78bf1d09d9dffc88f19ea2ce6000000000000000000000000000000000632a4ad6a19eeaa934573ef62af519aadb924faa1085ed4f82bc646a320c35afca6c63cd7233f48abee0ee435a158341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003210ba8743da34c3714d8e4dedcdbbb87e7574cea45f23310ef23c4200a93a8905c6ba0c9fa6fca5daf459d50434c7f000000000000000000000000000000000eee68e70c58ccc3d95116ef4b19c3b2d62c32a2e13ab9cfd75adf921b58d0ede75ebc9e9a66a2bc49da86f06c04d2861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000beb009c1f2d8442ab9bd865d3180d1d6475ae381deb935f6c963949cf88c1de55b8913765715a4c69a597c7bdf89b49000000000000000000000000000000000333cfda212d316a00c5649f23696f4cdc2ee2558c38992b325155ad60e875cddae143e42bbd2a7dd52b81df8df7db6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a0f0d4e6cd49c5760d94a2cad72e03120320eeed79fc382da9a045a42cceeb9fdca806f702c77e4ece36df808f993b00000000000000000000000000000000003183a92d370f62f9eb69b64394d0da94f09c2d4e6e9dfd9d9144eed5973325390aba00b8c6af1c283c408d62e81c721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001534f8f7772d7e6d5abd66005799dbc77abde9de1439fcd8986321ac07caa77937028bdf22f7527f92c39ea1ef38cceb000000000000000000000000000000000b824eb53ef0cbf44daa2d375f98a8b6d867ca2c88e39ebddfb0c0ee0af6b3fc3239a9680156c25e0dbf93abce236f7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d0f24f27440c8c574239a37d3a0877424b0d665550ae6cf13d0a1204e64456d6cc1c9aaa5aa02f7cc2ad22022c7dc000000000000000000000000000000000091d6a0d57a6f13e8abe18e009b9191f4c3d5866e20990797809c565b806872f5036a1fa9b7d46e3bd53608970390d201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037b2034e4d2cd69c4258fd14ef0859d5747489ca9f153b19fd5a7a97bc7313a49ffc7f26cdfa76490323f49767528250000000000000000000000000000000019537ac731b69d4baeb5a0c8e8a7a3a37cc8b5453dcb4d60cda957f674c17afca037b58bea3a836125926b2dff2ae2921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034aa7202b2cb8d81f9ccee4e686fcf31cbaa270dafcd33e5502505a5c561776df863894427f5350c33f358d92e22a130000000000000000000000000000000007bc7421e75228cf41dc5363b4a4fec9bbb5545bb49d6d2b14765eeb411d08996d563878942b98e101049272904c91dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031ff6d2b08541011291ff01bb6f86cdf477cbff3ee55305701f90a24253bcf1ee047e841fb8531487a1c86837c541b30000000000000000000000000000000008aba53c27c7f47a5b19e6dc7f4b34de13550d6e18afd6bd83e6022f808eb8222f8fd5d89449db589f6218c4bff523c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1e64dae2f76e206f6eadef54f3f03e77bc591bc176f461d317e2cedd52f5427b7e664c46013e15fa85174665df03cd0000000000000000000000000000000015e798c6e08b4f2cc00046df6482f6a03135445445972073881593bd5c006906ebb12180ecfb19c94c8c221e3d08e1fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001483d19d713aefc4c8992f3aa1c9b2110031df7b8e3cc0f6c201da6dfa92ba5e814aeb19493decd5667ce46f49cbe3870000000000000000000000000000000016c0edfc485d18c50c176a182ccdfb36dccbf81186b68a7f3b952adb637b205c7e8cf52b65f65f0d24aa4e5846a483691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb7000ca247ae09eaf9bc1b3a0516b64beb46eec7481a9e866bbcc645e51d23dcdf41e3da2d990fbb653c18ad2cb9a80000000000000000000000000000000012f912ea4bca1770e31092451d0c8cebbe39f50f989b8f14274404ae75541505f0eb99a6432f97cd0721c38db4f28ade1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004414237707f77a26d31def216ff034450f1b9c149d4dc0ca34389e2ce3144ade9dbb9d23e36c47cbafcd230cfd83f75000000000000000000000000000000000950c4454ba2a112267029c3bddab5b107c7bc034ff5bd1db370464a87b112cc6a580e90b99f8aad74fdbf93b269a7a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073432231f2ca609592f749bfe84985d1ec529f659216fe4741ee6c4937a450ecabf4506be0c11ed16c50c3ae76dbf25000000000000000000000000000000000ac351c2c570aa559bc2f4c53878bb03d9799a5e12f86a17ca1591e66ad8009999b2f88b84bd5ed117834bb534e413401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d090a1f3b7a073c79181f0157cda0fc6f33c65835ac4a3eda8021e794268e337d2e18ed190d877054dd646c1982479000000000000000000000000000000000672bd74371fd932517ba7d754eee24080029feb5abd4b80e5973925dc951268f54d5219edf6f1177c8a3f85d8f39fbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049f166d2ac77bb131818c57d2d01f2a54d06ba21ab2ae6a0c192a5555b3d3c7c5a94732185e336692c86db664ea999d000000000000000000000000000000000dde7f8fb1a09546779cb93a9117528e2ae2219c2d5827b9cca028061fc2ee0a339f72598bc9be7570d1dfca0883c4c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fabdfde35af770c5db7987dda9bfb039fb3b185184588a73ccca1913385fb8adde20aebfb77a2cf4e7241eb8cf5bbb00000000000000000000000000000000184c013fc18dff866d9a96c37e2d09b9922ae57bdfcb689dae1b21b5c11054393d968467a83acc54d230bf8579f738aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc07731aec255a2c7eb59b3c30e31742d7c147673a682d2b7723c78f1b03d735c99122251cb581a10543656fed6910c0000000000000000000000000000000008eaf937126d3e6f96f0927a397347ba551e44e08d2db820bed4911468165ff339c3c7c6fa1be1448ba0332ff65f814a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158049c2547ca8359ede78e9be5c45022de55401e6e4e26716a59ba7f2943bfc9a552c802382c1a16ca2afbf86e3c19c0000000000000000000000000000000002eb661c7bb49e761eae7298f7aa1205257f2834c58063e2344540e0b4801b41234bf4ad8bf74dcb0c638d18f8e4057e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050e0306f649c0f7555a59efcbb6ba944700437f17990fd49405bbe3fe3d13dba545b53391d3e1b985795015cadeadb0000000000000000000000000000000001938e1943cd4a8dd3c9dddf6019e175fa3c4b7aaa511166c0c91eab5af04db8ebcf790b9b8cb367f0384a0463442f6001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180075f1a8946376a12e67449b926e3f18a92e473da9947b662be925d71ac6ceedc2b676e04d5eff5d8cb751e5d66ef8000000000000000000000000000000000b2a639a58a562df4ea1ec5eba0ae37b09f8635daf7c04142c36e369db66bcda7263d98d74366a579ff51a567d2652901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163e473287982698c7fa5ed63fa65bf3b7ee5809f766a25ff685e130213f45e524b0bddf09d9f3d6a9017aef91f4f071000000000000000000000000000000000e29738d8732958e4bc751a80993149672b0f219558d6b8306efe1609fa20e1f42042e60f0ba7315d2784b6b21e9713f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e06651dffd04bb3d56dbe3b65542b621adc97530820519da7ee240247beb8f8154578efe2090ef55757d801e58b1cf0000000000000000000000000000000001197f3c3ca8da2296f5000f7a72f1ee8e39677d9e90a0d619ce1c8e7de00d7f219bc5dc3f59ce4f3fad4451c17b1afb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000519f32c067725c6d496a939c245ef1801ce34b28ee4c3038e3655cf55eed1cd1ac36f48fc51a24538e5d92060d750f7000000000000000000000000000000000ef52b70c8c6e4c63b79499ece38cdf9f3919720cd14dbc7e1fe581a4bcc4a228f8901ee848459243b19cfda3a80ce711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014359f9f01fc00fbdfc08b4671bd4e99298696adf985c3515f2164bf1c120c38709f6011853374c455912fe615b287d1000000000000000000000000000000000a312122a9c978d5cae3cad06fa1a70c8f6aa0b56fe6090832620e0ba63f462605b08e743c29c8bba2686c0919ba60171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e205d64b977695df0b229b2b007aac9f0d5b479f32c6aef544a4a1a8ec1dde0cc7676dd757aa03654f359d40478e520000000000000000000000000000000001d6a0f86dba26735bd1cc499ea56e7d081cf66ebbda303f21177a61962e8f11bf92b826d235eb743d22992c46055f541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9052a39858d58148ae6457fefc90e5f14314f8b5be0234628307c08849231ca450f6ecfbbf15d42aff58d04a45372900000000000000000000000000000000137a7708da3b5c47a34ade4a954646f119803a75c2f104e0718037a1243a302e3cad8bf9d3e497f45f625db6c591d34b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebde9522362d2780b0111b02371620fd1c1d9272306be1e31fe140794ef5d883389835c4d96cf9e8428faedba32f53d0000000000000000000000000000000000d0fa8770bb03923bdaf724aa54e88a33bef03b6e40fdccada1dbc73561de3a256ee39a893e0d0f26cf9db1a0fceea11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed325cfb227a8bf4034423c6c4b58f3cdb1bcaf98ba1c13f5d18ea6e425235c4c6ac6171a7531dc23535350625f06c7000000000000000000000000000000000c66b73bb56be0457e25ffec1c691300d57736268b2aea97e5d3851981bbe0c871a092f9682107c14766c986f1a7615f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d50b8e1fb81c5ea2a2ec171d3993110f5387f59a42aa8cfe7c371434d1c7d7d1c4344de18aef2bc2f618d657bbc51d000000000000000000000000000000000451c7e352a055c7e0c77a5a1866938c1602aca90a73325214bb2f6ad99afcd0efcc73de56254911952a2ed6851a908f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2f62effaabd8aac2d0d0d664decb0b92138f49c584a5dc0923ada2a88972e2525b1f0ca31460a3dd45ef2930210d6e0000000000000000000000000000000003122d5938764dc5330a4dd4ae42d95855c9f3acb36dd8236cf418f46358aab0a36b0f69dff50680bfe04d4b47fdc5e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014adedd94ffcb8d3911ac2ffb37121c24a32ea64c3e2bfa2cc0846fe373f3f8f87bd5bee6aa1e9ded374dbd903e1ae6e00000000000000000000000000000000159af833584493952edabfc819127d92d1da078de48722f0ecf7a75108383ef0647ece492442e28ae32e0e3546297e9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a1e66148e81194003019a071004eb2a3378c4f52041e035d13e102fecf7f3658a829d3fda7cfe12ae711ee3b688cdf00000000000000000000000000000000182988ded44cfb383a49ddb76345ebc56bd72f33ee544f8b30dfdb3dfab9ab58545e9ea1c4bd756b3805807dab061a201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001067a2e1d961764779d809af7784c2791863a648fd179a65177b9d722fdd4fe972d19f09a0705e8195525279f4cb5353000000000000000000000000000000000ac3ce4b221da594af3a39afe25da52a6cc049ba673efd78b58ec4fd9a788da3a66042ce13320aa1e5d51cc02407f2a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e4a27d7495f5dc684dc951a096f9263cd952e51e3f53e1f52e7e50e6ee6363b935cfb1b53284c9594eacc5f927eabc00000000000000000000000000000000125065071bf30a2ed95e71693047645b418181c53843d286ba2e4186a3b46700b3795fbf6e5da1f4c763a28e8c71ba081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000519ab0595dcdd9e25eeb9d5056d2107c6333376f203b932d5af00e14825fe04e933068db9d077d2f6227f313358fb59000000000000000000000000000000000578805ab6f48cec24a0284bec90b07da435239d18f838bf6892130569c383cc8382bf4f6816475cb3ba16608285816b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006df40e53e07134dd93d85556b60feb78beeb934b72dccf87784dae43740ea66ade5820f2dbefe0ffaa366eed5a49b0b000000000000000000000000000000000fcc01fe63760bfe6dcc3e11b025b5d89033f4f8f08b18092d13ffbe872e2a9717406bdda38c75ce85f38cab28fac6c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2dbf85fc50d15f9de3033661cae043f902ccb860cac848d47f8ac1b15e96ddc900cb00439da88be21aac59a53084ce000000000000000000000000000000001734b6e92ab54406891fddbebde115100183ff020e7d9338c016443f2f84af0c03e301551cf3cc6a48bd4dbbd02e248b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ed77cf5301448ce2f2bde873c4e17a0875935681603779e11103b78dfb4397674cace35f980c4e6437f96825f8d40b00000000000000000000000000000000066cb5075658461ad959b40560becac0062bf80b7ba524f5b09d7df698dcdd90724306c2f94e68b275680f3ae0d017321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b3a0c322010adb6c2df0a1e22eac991ffcc6bcc6a36f87651379e7296177ee662f3b678367011d87663bdf443579ac0000000000000000000000000000000014d052138e19b50fb48077d0a14485da7eca8bd9ec20fa1dfae63131f39fe0b2f40e9437afad2e4b671efc087e7295771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d9ff4fcc3139399148b3dbd74103fd229386125912a05ffc979e019bc33a36919b306660f78a73c8cebbad46bdbccd00000000000000000000000000000000009dcfdf1b29ac61624b91290a3061a463f65e3c6125481c2b13fcdbc795c786349dc570ed6e171f50f45b4b529deab01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d26643d2d05df74e7a711f9065e2e3a9a9b066cbe0670bda48fcc18d53ed1b489d0cb0cc57e03b4982f58fe538163310000000000000000000000000000000017e28402baf6bf55b99ed22696111db518a885f09eb34fe0328d1db7973eb9b05feb9d2a900b57d7195f80c9c001bc391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001570d55bf0b2788bdddb7832954c55f23983a762083c09cf4c9ecfcdd3b8a545c5d57efa6bde8943075c3e35ccbcdc3b0000000000000000000000000000000015f5591d4ef4e98d0ae8c994801b3aa1a1dbd1d15ea202e6a4d854566fadd9264146342796ea96022985e4997f5a39251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055f900ff9e51070c137185a5916bae361c9b2ba410879e7436cdf929db71e8b270576803ab24169e43faf9e2a8ac5290000000000000000000000000000000011a207dd903bfad0a761010ba6eac8d7af0e5ef90f1c0ba6eb5a23b137979eb2c6eb4a7f8105a3fb689e8546e1c9980b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100e9720ee0fafd34c609382edd0162e4fb8e726dfa124be4754046487f58fc6c88b9fa9560102e3c390502261aa0a9c0000000000000000000000000000000004f0592bbfb6e196267ec88bdb856c69522743888733c635006cb1ae1cb69b717705a99159e180527304baeca7fc200f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012906d00532a8dabcf3e2f82a84e0901ca5fe54fbdaa3a449483b9314249c9c948675f4cf2fff3bb4c140593e793079d0000000000000000000000000000000019b2d0379fe758767e27e68a075771cd8c7be6f4bcf423184b736c734041484f97f693d7111fba2e15b38b21144c668c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010802953a917dc7e5f943761716cd6511f1b442266c68dda57f3c78ca4fe600d2dbecb19e81a9bc2083010a960da31be000000000000000000000000000000000569e20a5276ba0c28171c69a4e75c7666ab9b94973df6e81c21bf3ef578b7519eb80fedbf9afb295aa37264448c8c141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166d321bb24093e1c27666d8106419addceeb41db5d2fef2478d700123cd75712fee245de2bb37b3306c7ac4f97b89bf0000000000000000000000000000000014ae98d6c527f4e30404678d29129aced607342527c5d3f7009178f202edd160a90ec5b445f40a60aad113559b89f7501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000605ca7d1c1988922f36d71413b0244870a6254bd4f92d9e223b225e3f6a8290b5d25995fd7051761492077a1f75d7a6000000000000000000000000000000000b5093392868f58f3bf257ac1dc70647bc7028e927591483836c2a5d6063aee02c655082dd02e1d2a7a240e1a39338f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cd9fd2e5bba513545a73c8bbd857ac785edf0967f30951a92c69ec85127edfeca1c756aa569ea02b570f7babd827260000000000000000000000000000000016b9d9264bfdfe024debbb894bb5b3abf2d11b3b463e24c17b5e6dab0dafdcebf57dd6b340f3a1d4be13b7900fcf95a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001aaa45232af3598917783b76bdb800c0544a995ed6ad462eb163ba46a370b3a039ab2b069339bbc257ab5b1feeffe74000000000000000000000000000000000c3efaa66469ba0f32afb746bfc2dbd143b26f165bb37aa1b315878b7da55a3c1223fbbe9c89ebfe4af58d6a2233e72c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c5d8e371844b96b1c61fc9af2d6df658155575e3085332e45dac35f50c9c3e4908a925c4dac5f91c49fa31e8d0ddae00000000000000000000000000000000001a0c502108df614c7edc6005b804e3abe834cd4af6b797653eed6f25c83f5eda0514d7ae02cc621aba801dbae9b0631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cef840eef6908866876170c57cbad6f43e1849fc86b32e5be23e4f1e2d5e567e4205fd796037c854fa70db32e9809e000000000000000000000000000000000258eaa5ff7ec9958d07751f00e002ea86754151ead1b3e71127f25948b984a081ed98e27743fb7d6ccfa1a3c0ee5d671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b136ce45dc2455bfae269d34cad265faeeaf8ba454397fb786cf81618a2c9eaa2d1d6137460d1ff3bd66b7b419b85190000000000000000000000000000000003a1ad64e15375ce747114ca4c6efe485e980e4add3d91a46b019988fa727bcd999168c2c4cd42e02a36a0af4b2641b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4acb6a0cc26f531cb3d228c524cefb593be7d7af241fc74da2544731a40f82fb9d5ca1e0e5dd54d1c6ac61e7a7ea59000000000000000000000000000000000f4707023d123a7aa1069f89b196b8ee012c644760ca0620c478ce00d787e72a7aac53c8f678ffc143a5ef36a3dc36db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002043f97aad2afe0f66cf2b2d899cc4530b8d0a54761f92302bd77cdd2379fe6991825fa665b2ea787d5dfd13523225a000000000000000000000000000000000f9bd1cc0f85d56c96f9a3cb8e3926974f8ce0810208248882a7b2cf4e836b6c6e456968cd0ef9edeece925df6973b111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068468e1e951230d33ea026ccf0745876bdabb52a7fddf7204ab8cef66907326fa73a7125c2eb4a889f4a3079ae27438000000000000000000000000000000001359e66cf1805c387d83df607965484ed5fbce48fd246e5ef3d8a92429d2c685787fd307c1a78312d877b15d1000fcce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030e8521a520261d7c7ed184d13ffea6db3c87ee4f23e4baf4caadeff8daf0d895c9bb342ff44e705294affbade43bf700000000000000000000000000000000191ffae9e26f21fa6455937226d4aea09cc99b5bc64998d858d7b1d74d7d0ba59d00fc0eb54d84585863086604f6e5a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000067534ffa2d6d6051b121a910201c2a358cd193ff016b32f27284e327f673e086d683480370ed517e72795c76ad93af00000000000000000000000000000000099668b30065dbfbe8178de2f0215c0e3cfd4a1ce0f8d446d9ea419bdf9fe2a555d83984736264dda2a2f214e4f9f5541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000309210e8ec338e365cc2a6f40c50d52dee090b5b17221647f81349632249530a69c618fb5d7ceb1230be1538be30581000000000000000000000000000000000a25848101deead43085ac381da81c76d6528cd95650c74466c58fbfa4cd63a85ce25dbe6b4dddaa0187aae9861c9247", "Name": "g1msm-64-jwasinger", - "Gas": 170496, + "Gas": 442368, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c5480b6630e8ea29b9be1f9f5dfee8448bb57e0f2c3dd1525db702c3e491b3c1c41875ccbd038e224d42007f571bafa00000000000000000000000000000000047926913cd01d62be5a15bdff074ee02af49d741c9a8e8f32ca608cbaaef7e491fe2fe2bb0375466d2c9512a015e68d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a848aab1c5836b4cf5580353537313468d6d20ff4f7b553ceec8a343da6aeab297e043f6df9f1fb1c05663e5f86ee7000000000000000000000000000000000a6447bb4e711b206608044367d9c9dc079e4d52230b06add2e898cd4b1866fe880edd47cca83329b60f4114a98d933b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000949b16bde26e0863fe55aae62229cfb1c055a4165675150d7661ebfc7bf4f2761479b4cf7b5f71b2c7f633fcc48b3600000000000000000000000000000000001df90ad1bd2ed049867062a13dce7bc9efbb39115fd9428383ce44b0255b0910dd6d1e4df68bc8abf32c994cc43dab81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f559444a4d1acb707f95108cfaca51a38fcf4f503025b125c874ee9043b2e3c03276f7c11a46906f37e8c38af91994000000000000000000000000000000000f97645b0145a62b837afcd0d372c005e948182e2c03fbbd87024f608f647af5ca533b7f81c695fbd85ea75304c176661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4255565aa608df897d02666f5012556fce5bda45314f0e9ee5330bf237987c9ad25a2777d2843d9d741899977afb78000000000000000000000000000000000d226176a17080ed2393c36d00e9850df3d1460d240f639646b667e79f3b72e1c5d7d467031645eb232c056e91268c361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101204298425fd8accc314a26759abd07c310c7700bde2af3e64f88016e400f6235eb3541a246dcaddb4d25fb85f73b8000000000000000000000000000000001344f6307bec6a4d65c2a1d0d42410dff37fcc99922d6087506351430365de64abfefce3c8be2712756f822bd730a76d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171da420c3db1c4cc857028c03371c033c6fccd44a655f9821ae81d8d0ffb16d50ba4dab67100ccf7bff93b33768496500000000000000000000000000000000099a94a3cd9060cbefab383d96d5aa1ecd1bb8b8ec4276b27c0761cc883bcec1bc8e72bc1f0643cb0cfc1efb0641731f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d5a6e20be3a9b9275fab5f417b8840525788069f1790332fcde430f0a347bd012769eff83e19e0b8098b23e7befca40000000000000000000000000000000009e8b35f122e7f87da4daa98c9166d7ca7cdd3c692a16f9812585e079ed632f7446e08223ef5811c426659141722bce81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fcaf99d25414c157900d9c7f6333a630ce5903e14ac13148ba0fcb8acd0b95f74dab5c8cbcac3285517c93ae0093b4000000000000000000000000000000000b976633dc157ea3852629bb8ba64950f2fa1b7af5f1631ad128d05d27259da04a51bd287081f35d90fe6a391e41bddd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001945649b3aca765a4808884c55e6e823c1a5050e42308066af64238b3ba4bc890e9b4b9cdf78590128c16f81f2621c76000000000000000000000000000000000590e08976aaf099aed416d4b34804fe4a0ffa14abe1235209502acc2c034a2a71be3abdd9c76f3ecbac6417fdbee3211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7a5a107708e163be101bfb382550e740aa834719f3a786afae31829ab2e22ad8d47cbf8c58cbdf2005df9fe2e503370000000000000000000000000000000011eea93709751f42d0b0af0b2eaa23d13dedfa0223df076c39ea3909ffa39f8157d0787a67d8220d05bdc2c4e425602e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c6b305b492bfcbc964c076ca0723a02d58986c206be46680e557d4f34836440791d7df36f3db1e26c4ad66f28c0eea0000000000000000000000000000000009c266b6060df811d1980b2caad6cc4fa7fe9962ef27bd0fc2d543ea5ad8cc9f9948b9bbbac3ea53c3a2577c1f6daf201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000683d7b3e8ca147b372449cde76f2cd083712445f387230fe27013ff8ab56ec2d3f14c56491c7877e8ca8cb0eb9e23d000000000000000000000000000000000087bb3454189c41ddb1c2ab3940ab321b5dd65c4f6d77a18039f3296a40a3a5605d2a1bd866261e55b4dd6994eda77c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055c66f2198b6084c17854de9798919176a2976a2b20832121c4c0617e104ffe0446de55861ed6f53506dc19d5c89ca90000000000000000000000000000000014e5082c30310fce95a4df7f1acade2965e1e32291703b9b3f1ee106397062a4f93119ef60e0f6aaf01a270722d0eb881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d7da98a4419960126f7602ddb2322734198deaa678bef3dc8fa0da48d87b5485b95bc067eb9ecc01b66300c6296d8b0000000000000000000000000000000002e2ba5c2adab840ac9bf4a059666c8f2b94964406056e41deccb029a8803461dad456e96c6bd974197f0d561f164c871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159e13355d7750722aa48972dec63e6b0fab20468ebabcc6a538ee100b844f30081c1fada27cc9114a93d7ed14aa95f6000000000000000000000000000000000488b731423ea5800c2397a288c0446257e47d5e1b3f8cf3a1389926bcc95e78fe5b2dad79b14ff233558780fc54aaa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b445c0e6b0a4bf64ac4b45cbffa9196bae9f293c1c8bb0de4ce96cdacfccd20a5c65fae13461e508289cbc73a6f17390000000000000000000000000000000002175b24a1080f80f50180380488ece7c621f5a31db2b6f292294cbe60d9bebbf90051df5f6cfc9f6bf6c1d26a94e4f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001530640ae99b6f7ae02d567e060fa469fcbd87131253c8cee12d8e891d44ecded5930f631463e6ab37a2afb6b511de160000000000000000000000000000000017acae258af502adc7032283528f93cdcee1d6acfe4dde7cb975c9901967df5489b4a1aaab4dfc80f0253c71ffb4d3d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b989d2e41669309b950d1ffe78e89ac89fa83e31b5dae07ea98281552127332fef3429c25a2c72e6d60c28808e83650000000000000000000000000000000008644b074a3617e5c18af53b663829bfb45fe5a4762be00aecfd261e6204fdcc107ff879a21a06f5c8ae71b1a5b8c1ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc0a0d1d8eff56b7790169dacf460e8e04cb7f0fc6403a6a4076809ec2e9f1d685d95302b27fed5d33f5266fab232110000000000000000000000000000000006c6a8fcb415e40fecce608fa512e19ff3a76ab275dfaf10048593e5e768105d3580219b58b3e207ea0eb102944c0da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001192ac337801cf127720be76f2759775b4ce93cfe1aab197d41c1b7d5e493b9b5ff3551f0131a14c570dbc2dc1b7fc6c00000000000000000000000000000000104df98d3a176363626edb1be59d7bf41a5c65db7d10ed525ffdab53930d117a578e3c82ab3bfe4bc8db5e1c0b71d3c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015cbf252fe6e6326259358dc3be5326299153dea508e3443497198dd93d65bdff71cad3c62c8b63512286fb079295f3e0000000000000000000000000000000011d12d816fbf1dcb6c3ab25954d3325e23793aaff8d9a67840225eafb9c970b03afecae5d123dde39b46e4834eca7cfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c24263947f211cc1a43436372fb03aa38c0862b7db7b7b7d4873dab6ec808b09830d756341cd5121a49d0b16f94f37f0000000000000000000000000000000003fc7db117cb0c3bc9d9c87520ac8fd395d4ab9196b9f950368b828d8c471e980c6580f40bd4686d3f9a3990aeb440301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e676ae3eed4902ae9461a2721676f1c2b8f5dd581d297b014e6c902764211c4fe0dee198f993a48b76fcdcaedc3e26000000000000000000000000000000000689bb44e55f2c0e1a13a4715234f061e2f1c23320f928fa34a16dddf82b4daaacb53afbfa52786999e4005e70b33d6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131a0d6a8e04ce117d72617b6690f31c1e4cbff089eb11caef1bf5c83c5d7d734202e4957f980fcd3e725209fa36bd91000000000000000000000000000000001405ea86e271b1e9e3e8a15cc11889531a3de0acd7c4615f36b596948a778c60eda6b848e7e2391390571d15aabce5661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001937c1a27812904597dc98529aa58c683d42a967084125a9b825cee425ed97ff4e62eba34172d99e7445b2b4301c4100000000000000000000000000000000000c07e417024e855438ea693070b8598518e9718756da1e2dd9289b98c3f9e6e0d4fb44cd6d34106136d4b56a839a43481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153aed91e2393c7214eb89a2fa07b05c9676a468c1bea72eff7c2aa915b68c6da473d685af7eef186e1455c5ee0252ac0000000000000000000000000000000007739bb486df8e3980f99e9ebdaa2df021d912ab0c2c4c5364ac5cfcada2a53af28d61b16fb3f9d152e423dc7f3f9e771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8d0453b54b297745e37ac3072971e5d9158f5da9cd2832304b563bf0b419f567ee4285cd380e5f4b6e2fb07e3b8ee30000000000000000000000000000000011825d458232f1e4bd05354de1b249f3d1bb6a6c439efc3b89e3871a64f4e23bd96bce719d914a9c998f8d5105874f801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010c2c14d8bd7a5ba678290b6f1fe778a89ea3979fb0c854876c463e08ab707094687c1a4b490d70bdab16affa7ecfb6000000000000000000000000000000000fa5b3af935f27cf94f3ac95dc9df7168828662a02e14afe567e99030a8007216452846c2b2a88e7ade88e249fd2b08b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb480355c08747b7c7d0ae67205140d0c23d9e55b27ec71b4509d7f1369229c0f0de34c1c9f0e9f62b48d887718359c0000000000000000000000000000000007c528d3dc229827ce226d57269cd0179b6158a9d595ce03f5186e7ac7e0303e79d223256732a1c0ea8016a2bd0ada841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019853f29c1525a17855e599bc58a3a608114b88161f958befe011128c41bc11eaa4d8a2262a9cbf134f2dee805d53a78000000000000000000000000000000000eaca01e1a371a98f99183818231d64617ab4baa5c8b5f65d7c0dae181cfb22b3ed598ec30fe386bed02181ecd6193e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e9a661bcfc5dd0aecf9ffe76a39d2aa69d7133520bfd11d9035165c172e139b66e6e75371f2d7d8c14ac597a44c3e000000000000000000000000000000000175c348c556914a2b5be9541491d15b8beefc5650671a5c59a3114ea765ad7b3664cb4528be29f3c13a74ae3ea5dcdea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008263f247e53acebb9e8ee2ad62a1570a79592b0818954cace7a42b31d56f9d29a503c6d691a98a95a730c8ab70efa920000000000000000000000000000000015192c3b4811ed3cbd780a99e426fbfb5d4baf2f6356a0e2243f88db2ba040004ba5406210f3af95b55ad4e5559f06ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000830402bb71ba8c3a80a671f43e5895c5408500e86e78c9b2b44cffb1c114a8a540b7ab0289b0480a8e21f63a81ea4c700000000000000000000000000000000163178b27ca33cf677d29544e4703ab318cebcc368621bbeb4d675c54371ab9386ae647932da145e2f14ecddd4709fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000187aea5bf912fd9310f0f33e3a3561251222e5a6f8d5ab3b9343b650833410f7454e4220126dc4cb42ecc1f52ad9bb100000000000000000000000000000000042b88af46faf8ab9238af620b3fa24c843f113abe64e111c1c6dc41b2bd5b12d3b263220bae37ee93f6ace35b551c301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070b5c0689bcdc704c21a1c68c30174e6693f85ad1a8911dcae5d54c19f76de872532e7bc32c890d4ed4f1ee91049fb5000000000000000000000000000000000fcf4d51d573613b868ca4c30e97d581a213d731fa4861a88ba08eedf0ab42592fa5bf3d7a0a4bde07039791a508e1781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a47ec3f54f7e5f864079838c7c0598248ec65cedae64cedf0928ca8062c90f6dcaf568093e7f54e422d1d90fc413e05000000000000000000000000000000000c25b6fa4ac33e6500827854763bedddc496bd32fed1648f84ab35f17d28c15b679980cd2a4da94184acc7a31a2dd6ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb57366230a1d93541bc324a8df1ff5ce78e29ddf7fd431da4d4ab9723f364e7ff22fea276a2561fc95f4240af5c6f70000000000000000000000000000000009fb56d7d74acfafff1de7c5d4f6ca88c641f197b7ada7e713716d645b58e749db9d9c44062da7957b0826c0d6f5c2601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a20462240b3bf33808f0ce013fcc2926a6c6d747641fcc3108d059e29d6670ee529186a348fb7ea120d5d9ca915fc00000000000000000000000000000000007462373259bb48c1b74e5d9fb44166226482c9e035111ffeaf953c41c1260f7bae9abef840353c280e1785ff143053e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f56ba68c344ad1ffa0a93459cb18b9f0102f2ff64c7f723c4bd50b6c7a3a37fd39d12d324286a4e92c0a3c31412874d000000000000000000000000000000000a2446d990125492368c0f73a19a4bc8d48ea87bc5cd94eea8086d684ddfaa553027073586fb247dac03d53cda512fea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138b3d5074d75dac121b6493a1a1948452fd794d6533175dd09147083891ae20f0dc8885cce542907335eac8227680ce00000000000000000000000000000000097ea343b5b29dc13b45abda615051f3c20fff3e868cace370ca1581ee09e6499a15c6b2aa1db04c1a9addf0ebf7d8601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dbffc6892b2da7856614022847eecf24bf9407dfe083e475bf47a9ccc516d66181abb987370cfc12d330f841e85da400000000000000000000000000000000140be000f7262f4de8aba77c2089c5754e9056cf7d7dd7f3f9697f030dd6317a71fcf185a3bf7ed6e6706cbdf6a379f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069d5e397f3052864ab34769de5a1e6f11f70a56bddc16f38090b5276a18f64bc390e6d24f62cdc828c2480843d2353f00000000000000000000000000000000146c37055a35c25ecdff41dbd7072c2896b672abda99df9f586d568647666b3008f1e99c83fee059ccbe6064ec05fcfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa3d2fc424eff0c4c6d5fd28b76f3add6280c8c45317ffb756e92d4215869e209e1b563d62faa0f3615d9d28901f750000000000000000000000000000000005cfdfff01a093011726116319da6c3aad8c5d4670f2690cc714f4c8f517eff9f65c003db9ff38497a2a2e1cb5f28a2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a54b293ea8832f8098f8f837d02a4db2df41ac341ff3eecf6814f0c6ca8e94b7799ebdf10ff3d76c38c5e7785bdef500000000000000000000000000000000093768bab8fd54f3c2de804c7b12d504c8b4b8e09e175371aaf3d439e5acd361e93b9373d4991f2648606c278bc05caf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f696927237ec7907f0bfd6e263bccb1c3c83921dc45276afc0a1733fab76f6aa992a95109cb28775f450d650017f450000000000000000000000000000000000597866ac4f8763a2f313242919f176ba631da5653c8bf855b277bb6caf761329a2ff1a15d255863b8be9c89ee5c9d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ace497cce932aabeb3550eb3a16bfa3a3585f07e18ac78576fb2021f7f8905a2843d8daa5f8cd00eeb7a9f6e7a4ec4000000000000000000000000000000000f0381894f0ba7347bc883a3a193e605fad9cb90ed809ed53539ad2ae5d119a0c9f2367bda6f70632a91e58c371ba2a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001623e86bdca29cb30dfad0404e8f23d4af7dcec514898aefb9369ea54df9801070aa1181df0a4416461061cb01b2256b00000000000000000000000000000000025907568042fb7ed12f60dbe3059545b80b519736b35c44dcfbf2f03991a95e28c42e7cf66eb25712dfbc236fd3484a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178df93ba13f174a15e7fb353112cc6742bd6b02b0a251b129e756b7b9a2f288bd71edf043d63957baceda1132086d00000000000000000000000000000000001340e15f0f105f545335e8887713ecee646d2cbe88703fc45634fb47e5fe3d0fc54f5cc7f5743bab52b701974e96d3ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea00023ef3ae135e56292f9e57214fee8f95c36d83cae2373028bb1c79c7ac56461beb0b2a487227671f94f3223dcba0000000000000000000000000000000004ecbaccfc0d18221b0508e8decd2f768d943c72df434b7b5ad1164d389d029e5af92033462e4d8fc952f921f29924e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066e8d506698a3a6502be6e5161170fc95aa564542b80b2646a17cc8a28ada3e810d8e771f5fe882d1e3e807a8ebf28d0000000000000000000000000000000007ddbf57c8f5b84462cdd6b8f5c35eed611f7d8898a27ca6a10e5905a455b189b7ce261cac235f8c8661ccaa43ee6cc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f23bc58d2e2d3932f2523425ba88bc4f617ebf4a9c43620bc3e5fa004b8fd74d828889282de7bfcd14d7ec1dd1685280000000000000000000000000000000007b97338c3b74026c05b9219be54d263794dec1e88bf32b100560967793100daa796bdc555b23c39db47a6238713ae161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bffac74360b4abe2df341e2186ca5c6dcd1f2d2aa6d007751c3fe137af242dca90a044d78e4147a08869aa6f5c5795f00000000000000000000000000000000174b0ba5580b08c8b98f3b6baed836aef9f5a660ae320a7316de90897e009cbd6cff7401fa8f2f7d8c6e872fc12271081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014e80a5a30447d87159fe0d0423f31ce32ef0d02eada7c26e033192507527dee2de39167e417afb17fd12e7d7a87f6e000000000000000000000000000000000dd14b5e3c83f5f28035327a45e8fd568d6215c6721efc5de6c74e30ea901aeba92a126f33814755dbee8adea1a30d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cfc4e1a1299c5f9dfbf62f172d6315262127b5aeb525d18fb48c0702b5cc56341cbbfc8eba45a3f548fa6c7ecfdf8f0000000000000000000000000000000013bab2a6247dece4c1c0763f59033fee17a6089f0c59c438a76a2cad53d92f8ac2859df64d1bfd31e1ae0f2e0ff8e6ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c62abc02febfccea7074b67eada8e125c914146d429d00d88af296ac95a91d82dcbe23782d127375f2281c4e3b222a000000000000000000000000000000000cb11999c68cc3c22174e87ddc502a77f84e34033bcdf7ca9a4d339de16c72218667ae481e6c77eba593fff22c354a4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001470aa725bc9a350efde69e6da97b83a60f62eb46592fa315121d2f2cecc1628c3e0edba70068fe1515ec2a4c6dcfce70000000000000000000000000000000001ffa071cebe850e635d6e6a65d80c58ac33450d8eb7ef4e4a8f854db42bcb3074cb6043d289a76102516a2aa076dade1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012385bb137c75bdcfcafacc28a893dfc3610baaba443c3de7ada4f5b7c88f1b8cae01bc6f9ba2a1e58bf861976d727a9000000000000000000000000000000001338663ad434c70a8646786b72c75361ee19afcdd897c731ef5d15085e34f53c3e361972f3622d9bcc1b21c599430e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073d86263ca62df5e3b5cfb9f252ae188c04e163c65cbc25e686f44c44d3ed2e3f9c53a15ede2fa687afd4e7f96f5e860000000000000000000000000000000014b7dce0a57c372ac6c7304a0c370207f937f036acdb20c5da71e3fcb80fd7dbccf2926a2440f9ac982a07d48fe018ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124c5808cd59ec0c8a8b983c5ec7ea83e5deb78834074d9922f481db41d4ff56b9fa43d06fa7790939b19ff6c7a7ec920000000000000000000000000000000010f77bc4cf326c5643fe1e993126f28b50342b8533aa74e0503430efb3904a9a019d64772af771db170947f6b2f879bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c443a3a96a150ee100cd8b2ad210cb74ae3b55e9847baed30db5a77db8d5f2f5f5214a24c991e6736149c949945348000000000000000000000000000000001176754d10b03fdc72defb70965b9c93675ff462840ab847bc86ad0f22db926017d690238d60516e644da12bb28db7151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000354b4c8fabfbce771dfee456a6f3ddbac34233941d542f5560dec63850be517642bed05dff650b48a08b3f71bf44e3f00000000000000000000000000000000182d999a39f4cb1ac0a3bd4ea8b9944c42e939d3bb65fe2027a0ebb80185456730e92bbc73efeb37c3e50179bef79bfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061181c505d50b7ad186666f440254a45934a07acb7980827ab75351b3cd774955ad809dd01be7823a5cc54f7a8568790000000000000000000000000000000015113397f83bf687bc98ca924243708b1dd630321203cb5c59674898f1d45a1afdc29196c7ddacbcae1a54435421d7361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001382d7b57154c8ae004b9ff7b4d23bb4b078f4d113ba4a74ad6fb3d1a9da1941fe2c48a06df0a3f386d959fc266809c500000000000000000000000000000000060efd96f4cabc14b0551c4ab423ce035bfbbf055248fbadcf51951b6c858ffd831b31a7f7113bce1c6b6f5adad4ed781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf9d7391463d8fa2c236804467fb550e75bba19925b182992497df5fd76f667024929ca7b530ba2d9c2db1b8b2e4f0d00000000000000000000000000000000098d659bd1a414f5e5876e4b93c449b944cd192787f7da37d6f76caf235ed7a883e6f9a151bde8cba4b907694b4d96bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055be45ce5724fef196b7f9fdd05ed77b6b6ad1b7c01094ef11c8a34eb06f396dc005fc5e1a4cb0643f4fc568431a9ee0000000000000000000000000000000008c8db9eab64aa258b5feeae6a8643fa01c2d144a8daa38cdb25530eb27309f40bf4d9ab6efba79c28c71483600fbb7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047fa198d37144b81772eea5ef6026a142ad55da7141f2e022d3d377d57a003d6c5842101ba37f3594765d858e1e34cb00000000000000000000000000000000030a81129b1ad9d634ae8cfe75e6eafd9e03ac6bb9c77deeef6032bbfb4c78601c540c02d895f9b438f6b4980a4d57a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000dd142bf9ba8b29665fc93aa8267a38da28793bf3713c2abb2c2c2eed031a309cdd0050082c05d47bc5ff8334084d420000000000000000000000000000000002fd0f2f1767f981270a99ce85322cc163b02899b4150cba8613289e9253379a2741a953ec4dfa7e5a5f91abb171584c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000756ade17b13266f113794fe759603940b8575fb0b471fc76b2f5660494f7e6060bb641f41078754b4992855b75d28f20000000000000000000000000000000003d2b76534296b232e9465c87838e1eab335ab56d50fa83c4fe851285ab348c960566087c4999ce3f91a0ef41671dc191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000817b860b283f015efda3c3fc94841ca0f80bd8a51af1aa1627238cab0ccc89f35381152de8d46b1cc4635554b05fb900000000000000000000000000000000091f3c27bba08c11888b9159241eae16159ee9ebac991966e1f8b30793c881e2384002b3f7dc576813ba17c9f8d31d441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159ac51e7a570b2a76a7ec09f8d30f26536faa7e5653af02b6ab345d3a4bb0bb03e802957636cff8f5cb80260463dedb00000000000000000000000000000000075949c6fea9dd0632b6294906a2b2626fc5ff44db38af721875b854c1f0cf53ea9b52b62ba6c6ba901b341564b40b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013543adfa19cfe28e1a0ecdd22e00fec78dd23c26ade476b03310ff1366e690e9053101d37b1efb5fa7602e7cd190aca00000000000000000000000000000000102ce60bb32672f821bf84da26c840147fd26692afba5fd44f404f3130178a2a4ae6240880a3c752c3a0e9b080fb194a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c62734a97a613f99b322798f0595390c0846e00c44e428d4a27c49067657ce65ea51503d49c873aee4c0be7e1269eab0000000000000000000000000000000014ded13784f741a5bb86affbd116b2076e8850ae7035a7e6bc2a1787e79d728c71d6c5c4ea6e8e11c344ff9bc772cc491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e8297973d21679f615ff0dcb30bea4dc334c54b1281f8477d6994274cb0d88dd695168fe749ec0ba2b87ad2957e4910000000000000000000000000000000006dc6e3e85b2873df12cb062eee346b598015c6ffb8ee977d88c1e527e2d032accbe4cc1b22c9dedb1d998c0c4a9ba161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174c9bda7fa709e34c20f4e6c30a2ee061138e217ec875da0929c24f1f053827e5d9b9587375a72a16e8ac9ec7c58a0400000000000000000000000000000000060297f36587a5101dc81553501dd0b2ee83edbdaa62b0d746412e933f08ad6434efcd9200e7d40b3dcba0956bf5e6511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f948300fd46043100d912c2fcdce98d03aeb922f194c9054d2a3350fbce5aa2acbfef9f68a916bb17372a7728e9181e00000000000000000000000000000000120feeb6b93703157494252c97172ae33665d0bf8a68ce79912bc9f6d2ab38a69adf6a7e6c45f43ae592ddca996593e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094df65b2da7d84c3d7220d02f46a7cba5404393f5417ad3e1861a9e6a3cf33001fa1968787003aa9c61a1dc39a3184200000000000000000000000000000000030e177042970eaeae4dfce6ffcf696e42a9e9e7c0e89ca24b26586006ef0b0e6bd0266df7221092e059f296bece616e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc76c7805aadb1d6ba7baf59063331789e335e0f4766acf70aeaab85cd0a772549e3f74c221c3c3cacc3816d1d13846000000000000000000000000000000001690707236cbaaf153ab847c8c9db49a8012f685f1a6af929884d10ce4faac84d99d1b114a1f31ccfc7447f8f906ab191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1b1a07b76165a39b681a24e1abc6317992ef11eb633a76285aba187bafb87ee3b188464e4312f140d537da0d7c923b000000000000000000000000000000001413de60945b4a97b8c4ac1dfa77f82347f2f362ec2f5bd9901148537a7a3250998c347500fccb3a635afa0ac627d9d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f29ddae9bf285ba25616fc47c09602915d4e456c6547895e8c444276de172201b3f929cd00cb3027c91f384f76b8a9300000000000000000000000000000000073eff1f50b49401e64180da721d05efb210e524ee8c2abaad9eb1bbcb08b6b48223c7ed862d7d982f9340caa46fcccd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c92ae3dfcec8bd5a900d3c00d865381b79799f285207572c16cc42b32f3950c5e81dea53da59fc6b4e0dbfede33a5d00000000000000000000000000000000026a42dff50043a54ed3ed9f45a6505da23e57d7eeadec17a02e621a34807e793de18e2d18b5ec2a061231cb69288c081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030ec12c249fb0864b634f6362bae857bc58126399b288561cc0177aed60f8642a012b21b4ca8f0fade406c8427d6ca3000000000000000000000000000000000c93341af6191ec7f0782829f5ded8f655055018db92c457e0afdf59a0153c5ee4fe3aa44940cf17787db1e5d8b188531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e7f02e6a62131eb674c31f6cf54b60faa76f4a130eaa5d9b68654263393d50d87fdcdd9c2dbf3a6f9c7bf782ac38ce000000000000000000000000000000000475883b0291d994433c68432456713e516f8239b858bb6c69bd2391be2ffdaba67bdc9d2c5de7b8a70cbbadec082f5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d97377679fb476d638e3cf45a53ace740d5fecbe63e779a0fe776395b5ce58e5f613c218b8f2daef86f237a3ccb63680000000000000000000000000000000014b6e926e8a684e456196a1b9863b3244d9435971fad5ae4481097853a2d7acceb076e11bf5fa6aaecb0f5e9a202d5581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023cf11b7628a09dbdac7f1705ee41f5964da20ba3636131c4b457cfa73dfeee289d594f7e49078c4a6efd6e754f8e88000000000000000000000000000000000b0b5e86eebc0b9b035bf7b81e11dd0ba96c42c779206c6f10aa84deab4086131cf18b5163a165e98aa28ab888d1d4a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d432a0f9d84f09f477478b300a6fb73d628841d25b2798940f46a35869a7c5a709fc36221a25a5486391a2aa9d5e6a9000000000000000000000000000000000e0a014adea49a370b26d7bc92eced309e56805bbab54964ece4cdb88d5e426a799cb79b05df9cedd8d0174dea269b591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076be0a1e3a47d9674ecbcfcee00f25966f31a09d3efdd8b32c6f5223c1360af038e6e9b51cb85522573306ad9d866400000000000000000000000000000000018bf6e9a4cc5f653971378ccfd1d4bb7111b8044ea9a22f599913b77011d044dffb5994dc65315fb63f8e01c2c07a8b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b0e7d820e0ee2b64bdda08de7211ec1aa60780c7d879549d3c9d24fecbc808c9b0ffdeac5845afee43cb6d0ce910c500000000000000000000000000000000144c3e848b78149f4cc7f746a3acd35947867dc8f9ded8e62136ccc089e7dabf4c7990e0efde2588eb5fc27284240a3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125de1e555e7179a8c1ac056181c3e65de8ed40b05a33184e342532a29471032a757f58843f22b7239d7dd4170a577880000000000000000000000000000000006ed91ec7fa76fe2762b3fd852c24af455c7e5dfd512b69f4f0a9cc841e6b8330892cd221159dd14809a9fbb8af2061d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ec697fea121a7a857b03c0fc04badfab45be46fb0d1aedcedc3fa2a9bc63a59e2f165971cee7fa44fe6c8b8ebe5bd8000000000000000000000000000000000eb81bada054f66f2f296db5331e9cf6f01d08c322f2314642111647981fc8fa87a0104260f32a7b2626f801285ff4bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d609732c1e4d59dbf1f4de887c425807a0baf6b16d0a276c00fb6eef63a6781ffaa9245a3c92a2afe82ab5d2d63db000000000000000000000000000000000fb962cacb7d9ddca818fd32ca967aa6290b6dea5b7ef25f510ef2568f4c35bcd24ac2dc1b0aa90cb00bf16a0447184f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001268f0f881951ee6e5910590b7ab6a281182c23d76ac5a587f81930e4910108d39e00062b0dca6e222b310e5db291f3d000000000000000000000000000000000e300432392b01194e1254dc24b55435cde006b90fa9ccdbce23df38c70ed542129e4cd9266173ad59cd79b356d569031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017eb7626c50f5112686189e79cc02f794eaf95f7d3956272671de3b213b430b0adc27709e05f766ecee13ffd632701d9000000000000000000000000000000001438ca26728331fdcd9f123155110ec0ccf5377083a36f53072b4ecde5bb5629e49b1f950c721d13b9159337f1c654d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147f9a60f39dd3c57535670cbbbe35a2431a0b7057a095f2ec1912b283623bf35c88c72812cbe9bcd6afdfdb8d771b780000000000000000000000000000000006384a53be7a7461b63d44c6d8695cc3c094d740e77b49f83ce139e16a1a52fcd0b955b3222283079f8e34a7828f277c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091d7f7647f153ce3359e1a5916609b3c2b2218ed231119863ac6ffc963fd0524918f95abc42657050fcc1b52e031dac0000000000000000000000000000000012e3bd2a080878d8c7997cc7954360c69e655618126869bf9e821c96134570e239cf1086d3d3a848cecfff143be11be51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000941ba4790f818a40f9ab6d8eddb472094cf1b871c31546db996440dc44fb40dd53d5e793f8ddfb229a86aede4e2e124000000000000000000000000000000001951350a2daf2b8032c4c86a4459b5aac53bd34eae7f2a205dc196b4e5d5fcc31bc9c927d8ac130419be5196a95faac01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000435b643c0f8649b5022636f417f2c85f3b693ee745ad0fd3cbd0ce49ab92aa4908d2a43d9576e2ee66929b5680520000000000000000000000000000000000014f17faafd9eb0ef53949d3d8bdf6d3ed3e2e62872cb442e1797c5e33b2b74e3498832c81ea7abaf2e9058b536d01dda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001626ec647136e5a3c99addc3da8ddf6441e0fd9755e21eda3fb24c9c97e3e8538612d1bf1fb4d30675d557bf68f9aa39000000000000000000000000000000000fe8a3a9551566cce18353d298d07d0933038d01b20d7d6d1527611ede74ee41d9e377dacfea7f674ffdd653b0b0db431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014066ca915fd121b492a641cfd6775afe8989c295e80f2973d73ede12d308a39e2277430f69da1e7e9668a503d1e2aca0000000000000000000000000000000013e4d7bb49670752dbce18960c68745074bb83d65596bc4b1b5526a8cfacdf29b0ab733d00c68084a6c6b9c4a10e1fca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2b5b1dfa6c862a7d744ceaf5d9a0ac50171c65902d5ea4f8aaff191b16871d111b0df71af9f6cc4c736ef6e07737f80000000000000000000000000000000012faae303cc7671757b7ff54535496b7b9786daf3cf29ac889f3ea9bb02d8ce3e08e7d303792ea6a4fa2cbb70e871a691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb13351c1c0ea62191f374be76af4ee5c22dc16b319370fcf7979f4dc32d827e29372c51effe5af00a5aa90a2e1f3120000000000000000000000000000000011d5d0edc8ed1c32904066960cb45742634a2fd2d6255ef7f684f4209fa11aedf1136e62bed4833f70b5dd6cd2625fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059c9b124468d9b3140d96968ebe941740d83f7f3ec25f30cb60a0e225fda6d602d6d4c24f0616371f3eb0351223ad1a0000000000000000000000000000000005431a5239a2323f7e5d9fb5f1b2d37deecc5b3f36681bc276815c4789f8a64a2df096076b8d71c2afda0ccc1fff2bbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065ec66fa8fe5733632d7d1f8e3a33a43253216b6a8553bca343135d9b2a23a006f6888fd3dbe3ff7ffaa11f121579af000000000000000000000000000000000faf956425898eca3bba05de3f2e16b2317c5e5d0859c994ae19ccccb5928dc1bb2f28fbd01bb5e14aa56228b340fecf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123e76aa159de76973189bd61a534478fc3b95e0ee624f274efe88412c586d346c4a80413192c984906fb8ff863e30d6000000000000000000000000000000001184caf5c11bd8c0297be777d4031262359dfff9985f44886d04dd89a313f7ef260c116c09f8271704fd675e86af61021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a970130ea6687b1f78dd35e806e8351c8f94bd4ea11edf443ab123b6d925c8e969d14d3af678191e9a989e857794570000000000000000000000000000000006ba1eac93c64d2f1f4d7becfb4e54e980d06359227f1ee252f7601acb92534721caac1e7577483702daed4794e600461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015eb7dda73051d38bcd81ff2a714aec3d4237c5d249c2dfe371a616a6106f0fc7838f078ec5fcfd9b4a92ab0a74e88590000000000000000000000000000000009b90175986bd7f8d4f59934e43e1dbca0b82ade7b8183c9dfa8a92e402c9661292b14df9397b4682607847c80ced04f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c781c3220e6af8053c37cf618d873b2565412a46a22ffd287f4fbeb53128b650ae27c3bc733dc876032a84aeae5f3d0000000000000000000000000000000018bc178ae0cd72ca2ccda209beb00f0cdab57ffd21de96ebd223e0889259f26cebe46c78155feba7f08fb539503d97fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9b0aff8bcd594e93d18dda1dbbd87679b9c3229f31a1870c05db6259effefd4f2acfe7e45deec67abf7ad7d639f9be0000000000000000000000000000000000b0b80f3e69b1d0ff25cb408c60ad7fb4be1cedb7f8b9dd7191c34d4b431fedac16931e7bbac6f1aa56846ea6124a491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c75c201e3566f5339b348afd507f7cf493b06196ed6a0f3d759965ed150d5965b21d7ce9759c4469221a4a2abfad08f0000000000000000000000000000000011e4fd017d8662af3c43c2f44947ecfa4eaaf7f50acd118c31c1cb18b97a079e4c953a2b02fa8b9f578a647eac3504af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d385e2272e1ca0eb0bb277e8fa4d14d389d5afecd2fde5acc190b8064f00db86eb7448f689b715be1c0d12eedc49b1d000000000000000000000000000000000f65219f49edb0cff554a855876d35249506d0b3fa661554cf0eff6669b6ef4378a18fe3db036585fb3be7e10f0ca37b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018442d56243760a3626f5b7229a2781a75c8c065a62e08ff31998e9dfa1219c0deffecfed7b49cfae62b2c85e1bb69a7000000000000000000000000000000000602d343d66a31506854ec098687ca37cae56a8342476e03031c114cbbfb3997fa0242e398dd20b7b03ef101d75d545b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006503251371051bff87953ecab736c79460621aaba525147299564c8dd9786b275f0e1b3dd83e11d88e87d419c3b4905000000000000000000000000000000001000a46855e30b3b2ffd72f274492ed17cc928ebb3e13ec70baeff4085af77ad1da1bf9592f2fe77bb545c1577261a991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf9cbc1cdf529ba9bc2c73df19215b51c17e4981a56bdf0d70efa0139a5284ba5b83f9e8a2b2e3b9f5520b28f75461400000000000000000000000000000000056083fd07895550ed357268ea99ccb1f8cc1f4162cf1e31f292b211cf390498da96994ab09a41a4ebcc1934f3bbb9081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000552a248cf05063a0c015c9c50780c15aac8503fb97eabea39d919787d0b171aff25d4b54672cd77ad909030c28490d80000000000000000000000000000000019f07da6f9b45c81edd091024573a6d3d6a1d2213e48b3b8d14afeeeede3d8c594ef00f0a513435dd2e6b9be7df915381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010becb4288d7da4afeae7c38544bb4c24e739551b496efb156664ed85e5476e4a25ed5b82406281df62a82bf217d4690000000000000000000000000000000000d7acfa535482f9a996528f183167fe20a5aa8b8807efe26f031ecaba7df0cd4b6c580d55dc10dbb9b4667c57643bf9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170e2c50f93455b0bb8dcbb204260a972c069578c826b18f7d582c241ad636cc8f239234dea1e2dd15d9c207d533890800000000000000000000000000000000007a2b7a9519f4f7a83145cf788276cb5f0d4d85a6dc40c920562ad3c55c8349c574cbfee66fe2a8d7d8e34c68cf757e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010859221a09529e649271a611dbe66e0757cdeac80ec9aab8c67ae2288de55164b548e53943d4d89adb6699a2c54fad0000000000000000000000000000000005ecf6b8f62e4979a204e3cbddbf61e541f414f097c68d4bc5f631bcf45399b2ddd5b42d327bc8af9d2f165dfa99f8491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cdc9d8182933d451f6c9c18e1cb4e3a751d0c8cc8bc48d5170370525319bcfe8cd0407fb5b67185d4854e2892352e60000000000000000000000000000000005fa283ceca6e0c8d5efea2b3ffe472473df97974c3ad4fa71c9f7065e67f2d99ea31d6df4ed6ae035e7ffa15583c32c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024efcdd1a52460fcc73fbb1129680875db0c803c99506500b72be4d1e174cd4bb9304ed977f4e421b33690e0d379c0900000000000000000000000000000000095a3da5274e6dfd84075ba4634079e92f51506a9b9c8468109d2ece6a6bc70ee2b23d290618b9755051e0c588b825e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001411f71c1e2cc1c13e7ae6019a3d3d388e8887c330620400cab7d27311c12e00e750311dd57df98d2273bd6a6434483a0000000000000000000000000000000011524602625fab1bff2163e8c604f4cbcf5b60030258eec26769892e1c5fabe3e85db8629dd01415b1286b057820bf6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8df76ffd22184b758f46543acf391431d495195bb6c2b075ba40d4c6600dc4f5e801a3176e690fdecf8bb229e0a57a000000000000000000000000000000000f36ada6593e8794e64e1fd92f3800efcba0890e4cd2d88ee0630a1dc5ee36414fb4f6a130ec000cfb83d3abee51f9341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006303067d821451b8486726356653adf804822e64b48c9f1e638b233609ecfa7de746666b3eaec579bb073a307dfbea20000000000000000000000000000000005963d626a69aaa6f223a0a37484b93570b4b48814cce7fec80cce1d53f3d0195e2cf5243e29d2c0aaebf90aa06b41fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008938e2462116b46660a554da49d142d91911594fafb3f59b8dfd4a2227c6b1740bf73017e9a9d924905c2127279d2fd00000000000000000000000000000000197af39dfdfc069a5b16ba0132ac0eef537eda857129afae5e734d14e7fba757c73c35da7a4235ba869e47b68d1496dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029c053bd75501b53040c29f4011040f9b8a788d0d42e08693b34617d14c690f0a7120cecfd05f03277180ba9f8499b90000000000000000000000000000000017c68c5dd28027a224f5b154341dee627b7e6ba5fadbf7dc98c9856d6cbeb83dfc6a6787e65511ddcee8b67585cac9b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de018041f374f1af7c62cc274302a993f68a19a4fadc802fe3b4a92b6b99f37092fefb1ecb1707a7934c2ca496de93b000000000000000000000000000000000f15b67bce44bcf7a9ecbef85a1dced3e97b40fef7cd2b50882575a1fbacceb2100b04bc0355e97670b91fe0e4633e9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b616be1eff6bc9143ab0abe85cb2b570299d4c1043fbf81953b27bae9dec41724dccc021d5656949ff69ebb3f706090000000000000000000000000000000013f6c8e291c403409364f3c1b11341e2ea5f116382cfb5924bc990fb37eea8b216281c19baae9ba35b302fcf49904f531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bd8db07495979ed877083dd762ce13b2c11fcf844a81568a7cbe5fe9d44924aa900608fd99dd3a4b1a6060e8d90a4a00000000000000000000000000000000119f344c29facb2f2c4f4935d306b35f21e06707040240ffb32ccb5edd957250f1d37602b709666a998be8d7f7a48f661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fac986db92e9d773839f284ce6d375f6116c8c32cf9107bf0e06c15f8b9047f57662d5e7f48bd0214dd8ea026edbf400000000000000000000000000000000114e3b385de38f6a58b76921a6afcf3044853e9cc1d347bf2242568c29b4181dbdbf84173bb77a36132392af4f29fc1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000013c13e6b9cb5bbe9a8f57821b678c05f59e116fcdabb685efeaacdc1bb104070904957a92db532c1ae19c65feadb8d4e00000000000000000000000000000000016e21f441248197ab403faec9c697f2fce2f87a5fe9075d1fe7e692328b6432e76ab0f2110d60ddc2acd6f8a860d9ec", "Name": "g1msm-128-jwasinger", - "Gas": 267264, + "Gas": 797184, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009e91d6cfc75742ba2c1bed7bd1b2e1d74bd8d0f8732ee61ff502cb1932cfebee7fe27a8035f4b4d8ddf9cbd9dc66bd00000000000000000000000000000000005c4296ef1764dd57749d77934c658944b76cf80fba6ae676c600fb21fd984d31d1307eaf6bae8683c2c892667dccaa21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f2550cd304ed573cce9425b7820918763e6e3c4be889bada5f91f8683493a38a8a3b0ff0d9762847ef148f2e701b8300000000000000000000000000000000125bcaf1a655a70f34598289f2740abc71a6483876f8da1bf3a9c4b43b09082fb759be3c87b181ae6115bd9c01a622d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5fed071727d16baee9897951aa81bae719f71b3f5a57c3bf2ed1df6c0e8c9c231f5bf3493ecfdc43acd9b159794f84000000000000000000000000000000000f126d831e2690fe44dacb25bdbc0cfd77d4ea0e8381dc75ef2679ef8e11195ba5b44577ff2f67cf225b48e53a0c3e5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138723907e01c4b012ccd710b00cff2fba5d52893cbcbe834e746d05f064ddaca2ccb9999b81afb3a6212718d6698dba0000000000000000000000000000000005dfbbf4fd639819a752edd0c5967ae0e05685d6d2ae6dbe18a78fa55d50ddab4a6ef6ff63c1841058724605beda37231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a7c519124cea54593174d156394310b62ff4685fc72c1462585e8e31c9d56fa566254cd52c92282564673e8c0c4121000000000000000000000000000000000628a202f598542565c9af22387fb1457d52507f21706cfc88ea0f40b03dd70a89b438a2d19ec8be6b2b111e4e0547791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9861b68e9d217d1358e9c41cf5aef75ab0a408c2e47a1de970ed5ea457f86df8bf0c655566fc774c6bc3b21301e511000000000000000000000000000000001258a0c3796ab0188c7dcf621e54242c3e71f9d1fa6a451aba365a9cd173980ddec7f722d89a4a6fce32190544443de91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dadf1f558e5b846640b5e238a535e65e20d418498fa1d4ed128bbfb79b6b5798b8b07bef37b3af00856fb0fb839e0270000000000000000000000000000000000e864e2820c1fbe73e623d73c0dc7cfb90327988467f67089953d0ceb6ec488ee858555681423a02078523464bf95d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ac3fedc7a28efb1bdd48744f5f42d1560c61dce1b0c0e9ac0e1c9d890d17e046b6b3c49f7e888628cd29f25fe7174b00000000000000000000000000000000171dfd4e7b34aa68a59ce367a8514997dc0b96c1852f67ec42f40bdaeca3ceed7e6cc45aef4564dea85559765bae28391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001252f5eefb18b7d187ccd99c0911cd64383e2a8bae2853d15b8e823fe08205bd6e87f554408763d75e7cd4806e7e3e20000000000000000000000000000000000779dff3ca853e54e3575799631027f13f296d3f42615fe5ea479977d502dde4dc12c60a6f08dc08382d67d5bd45aca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d041d30605eb13d447aa97f40a5ce5d074f843f9ca4276ad1f95dd6c52e83fd846f397629954f8698dc59309c6c6a90000000000000000000000000000000007b898357e809d714b251409ce9e5adcb866fccfd523c44d928c634aa22d54525578c6c69ab4b3d6d235df743a9309e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc8b2445687a1bfa41ccc6df117f00ce020190b8c889c57bbea26ede67309ab3ceb7d1503b928365d236450f85c188a00000000000000000000000000000000134ff7652eec202f0753f7c0150db6d2462e8d488131bb9f434bcf82de101c84beba6cf39471a44ab57de576d730d8e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100f4bc2d1d6f4757a130b6aaf0b83cf777dc06d64f10bc043cb66013e5a0984149ce4b00f7d15a6ae237e263cc8a4180000000000000000000000000000000006508e2ffcbb35e6d29a9ecb827a5dbd19cef07eae5c6e66c70d42642cafde65a731b9b00550d909f0e85932ca9064911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190b5af86dcb6ca6bf424073ff933630a45bc79c7aeb3bf5da575c5a83a0251819867f18aa2f7c2820aaca8a0a1c03e80000000000000000000000000000000010d50abf3a74c81ca45b594f4da4266b051470b1ccb3e2cffce8eb8dd0b942d543236137c760836462972a58859d9f3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088b48cd5839c058b812551c8599b1dbde06a949a49a79e64ae3feabc917694dd8d1eb62dd86167a60510ce224cbcb3100000000000000000000000000000000163989ed7bb5764e628ce7fcd0912adfd73eddb3e1d526605d3e6610d34e0d253d3b8de1311573fe6c0bdfae3e30b00a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e9b448477e778dcdcaa132618b9368838d6a81a22c5815c4ab934ee788ad8eef36cac638462f56ee221e379a71c90d0000000000000000000000000000000016fd8ff7347a7369b75f4ec3aa3b6d358d5152c6ad53f3fdb7413a2d15637703477f63fdc89decfbb301247bdd77ec2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078db71b1a7b706f51203efd009cc9839143d177c192d6ac3fbc19b7c95b23ea40b6256872627e711ec995490de387a6000000000000000000000000000000000017ea4b81ba7181c2cd7e8535273e029101f0985f6d90c5b617e85592b623550211993aef5561b05133707a7e9adc1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000589f057f21692c5c577937f0ae659d36afada2f3655bc86cf1e15eaf229ff8e8308911e60064466bde4db00531393e8000000000000000000000000000000000a1cda4ed81fd0de9757bd96dda3fe7fc07ab09259c41eb5fccc52bf1d85d9cd221a3e1d12aae7298c3bb00fd1db4d201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013841fa47194fcb9d9961e35fc5d85b408e6e9de06903c881683fd9a7262a7f9c51b15f579f250b95eb8ae704d0564b20000000000000000000000000000000007a24683313dc89c732b5f04371e75626195614e24e31c7a52867d5d058314d994d14b3e47c584864c0ea83629384e6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001744165930396c2bf8ee77fdbecdac747a8400ae0abe03d50b266a5dc7988dbed6aca4a89a6ffbae78bb2ee0beb8673e000000000000000000000000000000001823252d83f64681415d989219bf0e82b1cd449ff8a60feeb5d15a4bbf5452f9baf867941027f8821464c14f7d76292e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bb4ce1f9a6e32914b127765d49d9d1c288c3be7d7b9e4d690c1619f17c62295bf8957704d37f142b0a2ea100b9df2300000000000000000000000000000000063c4591e511c3ac10be9f26a7a15f687ac87efeeffae04c7e15089334650481be8fa8e57ec31fdbf7ebca11f85246d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b6cfaaee9fa077ed35e8ba86bc488719eb8066e84a4fd601a02bd95dbf7436938d58b04cad0ff84749d146bd44218500000000000000000000000000000000014732f98ed3595c4b60a1c485dba08e25f39eaed65ff7b1223d0e6dab1083c6e9588c047c25236358e9f9b3ca761da51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001426461fb0f88e1fcbfed8d7cd373f5f687c168ca399b24ca867c071ec8b0080e96aa1a8c1b7729c8d1fc500457910fb0000000000000000000000000000000017d4db9f60f8aaa3e698e9823da9e4bc2c7841542c57a7f26e0f93895e32ad6dbc2faef86adb5282b75c9b75f03ad7911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b155c539c4a6d40bda83aa233244875903c1eec61626860d1bd3392694e19cde9ceba9b80dffb498dab14159571afbf00000000000000000000000000000000051c52b7c12f17933a874393a27353e7781df4e068418992ee61b443be8c270fde69422e8321852a5753f41696f22ce51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001049fc11ffdb03a018ae2b2476cb0c0b889ff9e452e85b9a130ae52ccc57b94bded9c1128795d84c94ed918ed2b927750000000000000000000000000000000001efd8d005b6e2f64cab828593bcffbd55753cc209260d2f41b107ea459f8bf372c513764779b1546a5e0613ff11f4e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134c338761e6f79bc1d912cb1652ed65c6ff29eaca2e214fb6dce1239e40a233942e5daf0bfc4b5e7d4fd1e3f20d9c7e0000000000000000000000000000000002ec9a93bac0d60d03f9d29263048e2be9d8a1b56eee06c8cb7b7adaf5b9db61d48b0a27c2c1be590153551b99cebb341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000172427716505553f3bf0430b64ee829456817c64d036ed4a4d6f3055d4f54b50ba8c5d2bb87238ed6f9a847f0a32da000000000000000000000000000000001044a6b14a66e8266532ebc762e9edbb8f5b2113181fd33f00cf6d97017f42371b5598c02b9eff08dd08a9bb3ae5a6a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b9d55641b649f11ebd12f153d8ee5af82df5f939058a866e958fae0de8befac11e5969785f0d0f2404de1f1337145d0000000000000000000000000000000017db484714aaffd8cc49d547bcc1ea4438fda09d77ceb7fb42c42703fcc7e1f16b27d135fcea829daa9c74865009bedd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000985d307e840645bac5b58e5f614891c9cb6296119c335c1918c3680832ba69d493aca926396329b63856d03d2cdea6f0000000000000000000000000000000013a5918387c44eb0101bd86ce8f1f44fd6c552556f4f94102a7227789d2c120231f39bfb283c079d3b0493fbdc13611d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072ae382ca7523572548e370d3072d6ae39f3945f9052bf46a9de76d0d5301617362a0e61ab4ba1974a0df24392d23fa000000000000000000000000000000001263bcc1efb1141245a563ed76d89b3ed3f9246e591514a7af74d7214f82b2f6ab13e3f884dceba86eca834b268a3dc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cf8961be344c7939173095767d5ed54add1572d9be6e18532812611a09703d1a99337c23dd6270974b3a97c1ab7a69000000000000000000000000000000000cb443b5ac9a02b1d9a9b7a971e79b6961cded1d8ae0f8f3a37453d4f57fcee0d560a8cd2cc4a79f62c13074659f8c6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001155c09875543a5ca4c7bb05523d6d34f85e0b8f2c72de18379a975b4558b32046442d32491216438773d90b0352595d000000000000000000000000000000000c02d4870f3666e397e85c88d5c17cec476a5d2d0bc179304098d205497483d2d6bd6b5c442e6abb4b7d3115cec54fee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f00e5cc6c6659d6bcceccc6bc0a824718f60419533aa3cc626e7e70a005835aa93aa96ed318e8ae5176344629ae9bb0000000000000000000000000000000016fd2f037f3b8ceb958eddd6e1833f154a342c8d6cdc14218ad061a3e73868297b3c9f7c5fdcc3b99da21769608c18511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b783dff1da396ba3b17dad3787f6cf91a56e8e34f5a9c793ee8b55c099c78a68136fd966c3fba8668e1de4d316f1d260000000000000000000000000000000000684bdb5866218f60934245d4bbb1945e878c29bbecc830f9093e5695c67b478ee2a3fd16dab7939cdd77573d2b73d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101d19965c84f1e7ff7fa1082adaeab41b4c879b480c0484f097a41c89201f8f02b1bd7401bae55b871985cbe48a40fd0000000000000000000000000000000016440681fd6d81c2ed2c3a333f41a0d983619e1d490b90e5ab6db5cf5bd2f2cf8d0b278b1d164866beb853b8ca8bf61d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d80a542c3ee056786b8ffe8066faf0959af6fc3339e38d76fd0063f3e7862b564d78219b155e6b6d5f310684884cdb50000000000000000000000000000000006d5e88101dc1e8be177becfa5c4b3427da20ed50c9d4ddbb1fa9113a486faa15ced7709a5054f3de3c1716dfa914b881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b8f138c21aa6b5ca9514102c54f4021c3709d74bbd59d1c88cdb6059008fec4793a29ef1f30ad1c0ad36f47a97282f00000000000000000000000000000000170f6b9e271aa35ffc57fbece080ae75098b177acd930446437207e3566273dfb457a51a7eeaceec7abd488526db0f421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189bb1f7b1cf6c26ab48ac23f362c329612e9a074a587def8629f45da18382965088bd5b55a46920cb786927278c014500000000000000000000000000000000068cea32498385a2ab424d187defada8e94719cbc4926e4a307615c4271f05e62704e3fc9f4337f7ef3d83792c0d9bcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000131b7a928e347568173f9b4cef4f10991eacb9ad791e75867675d94a94fd095ae99f858be426eebeb3a415a116697e6000000000000000000000000000000000290db9c7336c8d0c114f8de9a3bfedf3ee5d3042ec4c719a72e0122e4adda819fe45d098ec5c3ce1532870ae8f68fbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000682500c65bcf7f4451eaa59335ba78160a2aa6e9335008ecc9ab776e08b25077a9ab5ded4dfc6657fc40e0ab1cde480000000000000000000000000000000000f003e7660f0533b3744d4bc59fa491b31a094ee090283c8d863b2580b668ef40a377b91f9826cc6775248a13a804fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067790cac3713008068ab6fa8e36347148196a9c913368c19f4ae1a110ba0c7a3dedfb7b281b94b36ab9876a3cd5f86900000000000000000000000000000000128b14f59bbd97765419f8e983b6a8c43d9f8561d3f2acf31f0ec9cbe350747cd5cb13040bfdc0b576e6bd5f2f7c2adf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a38c9802cfc7764058ff6f64d45a44c05bf7d66346b8fc300141b1096d574ab3515dc28ff7a410b65f03808fa557fd0000000000000000000000000000000015d0735380fb31d9883cfa3c2d225fa8c7b36b88b980398020c4e44759d3c8ab7749ecc0161051bfb1845eb0562c3cba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e8ca088354bb2ca19d8f0ff18c5cffe5aaa61eb1c61c9afd5c73b1b88dc5f1dfb5bb2f4a2fe0bda7de383b55f569880000000000000000000000000000000009f511e563ec35a9c8f1f6a09d0b4a7404bdddb2dff4f8b3522f142225df634469c7a706097eb3855397c87644d32aa01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162bd802812dbf581d49cd75c8ffc30faff693a792834b5a1a901ce899dedd211e0a21935b26f662675c59152e7ba67d00000000000000000000000000000000173e40ed1645f7288d3ca0767f335f6228583bf09f5ad7da0d76842eac241bb677cd2d01d5aa3e3630d72d4bc0ffff3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010191a0f57724e25482ad1fdeeddfd7e0404ba39538663f115d9e3d26d350a7746dade59fe4ce2cdc883b4f0004ad349000000000000000000000000000000000a72eb26c7f19b209b986421a9e82b8a47e748161422a5eaf49b87da3b1fb221b54bc3273354a7c4946ed17713468b0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0d1ee22c23e348be331c852852e77dc0aa9f5b7c829bee1106791759db9b91087939b0b9393d712998398428faff51000000000000000000000000000000000868983a94cd482c1b84b6904097feac74ea18b420594fac6a9d3894085b6051842329350fcb5516d385312e56d61a381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001223b25cf7734f8d041905fb1f714757f3981773a03e189d764ab41dfa6facf6ae82ab98df35c1ac77ada5e32334021d0000000000000000000000000000000006dc5a1632c0e24ab4e16efac750d87672c3846c37cbe6e4ea74f1b4a0513dabd08f7d8f01047e08c4276576c1d801741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007feb788422b265fb997e56e1f64bb8162fbf8950cefee37544ef79ed398af1fad1a71fd2145706643f4f82f8700dad800000000000000000000000000000000082748b4ddca00adf83111a93bbded0284312341e9eadcf1d233c2b921b6bd6b7aa9187d986d013c39c1942bc23f13141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000166489e72e8e55373581aa648485e09ef4f5251630e64af1bbb0d8d47617bb9c9a08795b1e0a0010a8cef03590138200000000000000000000000000000000003cb8347d3a9245101b75267ad1abecc416ec9bfff9b536d44c39b81935e51f7bff88c4d974a8056acf99d1eafe4cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aab686c94471a8db9f7d2d67e11a6d858a09f8370f2198e894d1178eac284f5ee9dcbd77b3b122fed710aac970cb880000000000000000000000000000000018a37b5f7a124154eeffa6489ade64ea2f0844c276cd61706c5f248332c47894d6056fef6f54a66154ebbfe443a143181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138fab32ef71f9428cec3b459d351666b45b719a3c69cab80e9cacd3d74b2fb8d210c8e981bf490e3cd95d2a3c06fec600000000000000000000000000000000003b098b2bf3c7b6465d7ed84ff6d5ed1c6635999cdabae2f0ee816c0d651e510b65733ddffeb78c0e44ad3895f3aa931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017648a870c8d525abefc2146761ef7d9c97cc8f3c63e47072b328d0a9f03e48b1e0b6c77fed044ae2b59d39d63f937a2000000000000000000000000000000000762dd6b582b7e7bd71e7bc972c6d2b8f4a5516f5550d169b27ebef3e5413c3fe71a28cfdd7ebd8ea5d4081eb55740dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c727d1f1bb3c7724277575249899a3075a260bb9c442c875c3b0077e46af3a8aa178da36688072405e2dc2c5a1ac46000000000000000000000000000000001831f3faa4c7c8af825d3cb641b48eba66d60b18f7c56cca205687b85d6e5c87671ac7aa90d5dda24d41fbb87be76ed31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ed006f031224a211e9638fdab167e15b07ff493d9664570b0ecbac8685a99d713b6359241c0ceed42b16af168df4d300000000000000000000000000000000071404ba9bda8b8e48c54e491dec70794f4c15ba10552dc5fd691e8e67331f9b3285c9077fb97c81670343b7075fba0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b378dba3b5f1271cc51704d521240c9583530268aea0b9f862743085f92ec83b0863bf82ac0598cb2d8f58dcb6745d000000000000000000000000000000001242ce81924702eb9eeb37e50f08e2ae7caf7c34f376e7f14a598cff213415a0441be85c1201d44eca49ddbf000f27481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000656148f8b4f7848f834db3301e155707f19291e62abdc5fdf4931e79e9fff47ea2ec403529df90fca61af9887572ef800000000000000000000000000000000153b4f19741d3f26370c91303bf8f72cc193d3cdcff1a86456f85b9e7b2f5f9366330800d75eb67f5ad3ce00c14aa9241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001901b7685794ad4351707a127afefdca84b240946f9fd1a3c60f243ae91f4f843500909162cbac7feb55c458dc555bcc000000000000000000000000000000000e61f077b23f1545213b807a2f9724b8629761679a34b1d849dee689eec6696f2662f42fa2afd27d5cee29db94fd3e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113ad30041d07a664a93f37399f6516b4773036dbbfb0a2cc82913c14e24b383420bb6e5ebed40e5c86d6a130bdc888b00000000000000000000000000000000197b767c92016117ba3482f1ff8a81ad026820b0bc611056e7b544b10960854516c2c1318de7246315bdbd3d3fc6c7661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000467f63c0011b8e92f1400ada3befa7430e28f2c29ce35f4c7413cdd48181f52cba3aa7dda9de98bfc59b77a02a5d50e000000000000000000000000000000000ee287651052d39cbd1372f9560eef6642693f0217f456d031541f015d0a102ebefadb41609ba29944eea3a7ecb5ebc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027059f3dd2f80f90e5dbd27b45b4adea8eb149682b94fe3e2547dc40b85a8360af82a4d1e86ad1bd93fbfb39e20635b000000000000000000000000000000000e8582313e868c6f0b57490642b467b8c6473671bf297109b142888ad5a5b287cdcb6358112b3f7b3988ceecc51b90e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013aaf6c3889b8e92d8036da2b5b07c2fe17c1c734c85ba70641376d3dae4bcf417eaaea297ee7abf267c705a5ea0bc81000000000000000000000000000000000a3ca51551316a126347d657c2e116554fa28cd514910602bcc5a771695541a011c2dc3312b71a96a2d92ce649804fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1200e27a7198fc6801d9fbd9359150371746857539c69b53983bb90f9a5baf585ed1d6077184539ba35ea8255874d2000000000000000000000000000000000f6892ecdaa1f947a1b7f69ec7a56bb2107819f55a3ec20eb6d4315320e9c89885c6dbfe2e62cf57c57d08d1cb04a4af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f07661283e5f7bc46bbd0a62153c5a355cf6e36050f09274d63efa3fbc2d24ff35d0919dd207125ee90f478486936aa00000000000000000000000000000000193568e74edf17b8acb42db4e2359008a044db8b145ae2d133fdcb647b8789e15bc06132b45bffe9a89e914ee5a60fec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd73b4183807ad1cdde370578fa1f70e935350cbc06c98762fad895f22df060e153fcd4dd1186e059b7b14b4798c32d0000000000000000000000000000000018c38b1c4de20cc4d8dd686b2ef25ac9b62f107502827b56ef8b7131e9e57d527b64401d4c9acd52900ed534f690c9a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e0c4ae387a97f1460a893ab362d5300de0ec4190aefacc483670bc7bad31008a2fe995577ce1287bcdf6315698433b0000000000000000000000000000000006f75e65370f74aa194d3b9905c5f5428ecef8387df4f4378860544bd02b6a877a7d51df850e5c75979a6be2100981331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fb03782c6a8589ec033f0f74cc7bad4317da68921653d20451dba406130d217bad9faaac6adfc64edff73ef8a579e4000000000000000000000000000000000cda4d57e4c183a95f2a0b3299d12b88a939470fff0a03ab7033082c8afd35fbb0890a7653cf96b7b983fca088793f0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e5d564b830effaf39ae666299c542d06bb6701f69126bb1c85264f74d41075ca23598aa2205326334fde7fb8fae953000000000000000000000000000000001008e41b7f47086b0277166992df928c6498de3d548e571237f6bec053b3b15de9d0a4ed6ae9275213c08f5446dc87581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010aeb74bf5e5104d6e2785fbd1bcd4f192787a9761532dfb9e8cad3bb8b04f2b09c2d233eab3ace0ba1df92004008c110000000000000000000000000000000005bfdb99c712072015815f981a9e29b7ecb7acd5a061737e12e10d57b5e8ce0a796ae021712052cbc699223850fccb2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c32a2e242c3a4e18449be4394e59241d2e784b2e55198f43642ed6b8f8a23e26c1d3197635e8f00b6073938a047960000000000000000000000000000000000c01a1b4ec8494307a17e3567d230d36dee3e824e30cba162c6dd4803c1f941d001d85b5e75697b185b03fc4ec6c37821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017588178a37f6eac01ead62ebaff0bd219a1e3fdbf51a2b5556fadd86653aa7f9c20cfdd3fc0eaf56e7cdb59bf97b3840000000000000000000000000000000017f4024bed03b7d4d146c06e50e934cc81d17cc11dd2116d90605f41c701491e1d0fedb1a7046e4b918a21139825e6381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001585caef47bec8382370f3cf4527cb89de18e8b7c693485024327bc612618ffa4531a9763244ab59a6538e07ecc7ff1b000000000000000000000000000000000693ff60ef41293e240bcb150de728c92f00ebb70f17ecbcd37c217bfb5b0c61c2a5679642503043d9056952d7ae77c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8805156f94bbc6ecc9095b450826efcca05dc9422becc6d3bef10c0edc9b6e0244743b335dc2fdb830f299a541f26700000000000000000000000000000000028ee1854c89f84df27e7c74ff917d34b8473085d61c5f185d07b7f320aeaadd632731bf8f4d83a9ed07938d29b69e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa106ab9ff11259d25d00557e15e8987d1bd4cdf7a17cce12311d4925693338ff7aa15573b2959f88cf2ed911d78bf000000000000000000000000000000000f89215340f7fa3f6f42c0d7e290849a9c158cd43644379f79960333d5ae03f7e5a30a0106213285780754089c6e36311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d681a270017d3ae542fd2ffc0c157b0c9046af7180b795700c574fb66baff68024d7a0eab053637acf586e7a51e80e0000000000000000000000000000000016d67eed2c7d4c046c7ae8cef0e9fd875bdbf101515f944debef95982308ea619b499dca3e12e04703c2dc94e2adc38e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001edb72c70e852924006367e7454396fd4493037bdafa1b090e450ca5fabf708ea0bc867d80282e5f40f3ed577bd4214000000000000000000000000000000000ce8e5dba23232af6a5455b99e484362146e69621896970872f20fc4d02da46b257c6869bd94f7c031e7351c67c392d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000011c39127ae09aed33f7d0897ab27f707c3dfdfb5e90b53d742b29b9c710e7bd1daad7cad25622c7d07cd3b3ea1db7f00000000000000000000000000000000134574d668e065a1a82904c6090c164f9aa4d13e142e3c1d9c3668af9270b5510d0a547c07d6b4fd464bad3d1168f3c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebc39442324f7b48f459cb3b2e66445b2a226733fcf4c15a3457ced4a86f721a24c6a0b971df9ee533f5b5e553bc0b20000000000000000000000000000000006a30bdda08dc53b031124a62e383fbb4759d4668485fa6d91c47f3c2b50ef168c4b31817eacd76be45537d46fd3a8bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e9b39f1c875a07d8ca33b078f5856ce6e5071ce26894f41bb80c06d4a71a2613ef6d634e40e0fae4c215a2681f2e5e00000000000000000000000000000000133ba2c86f4b4d11d3d507b7f370d0ee2a11ba47b9267df59f0698e6ea76e73e689b71af427a0347924419c4f05b25d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037856112dc4b0a244c6a298c403fddda9b0173f0aa1861a3a9aa04abcec060992a7fd9aa0a228eb00a29fb0cb79180a000000000000000000000000000000000689b620566eb37b2319df8fdfc3350dec0c56161600846bbfce06743241d3d37ad2c6794c1ac19bad79d8d84abdeed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001844610b6fb106496ef4dd43e4ec4eeff22f2757fabaafc8966fbba3c4adaed6674bea91320c6b29110fe317d40f584d00000000000000000000000000000000151da3c678af1721a174b4878fd3a3b25967dd07d571e7cb439a1fc766642224dbc5081581e12371b9e80040597221091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134911f593df132195f912cf634092cdf7dcf8db33f403f653569fdda145cda1ed48ed545468e23f9c4b6e250b3b7bb300000000000000000000000000000000151a6789bfc6aa3deeb773d8d0a342c19b9e3f72099e1503f37e62fc2482ea63fe39d552f619d7d7287f590e5c3c6e4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d3fc0e7918853f0106fcc67e742f54b8f249d7ce45742fcad227cb01b977e014aae58cebe0ac9cd89ef1bfaef338480000000000000000000000000000000005d5d5be7c52ceeda68021c0f6b7410612ede7b731341a18871ac6972893feabda9e5bbe29fde430d4725d2578d449781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc0a2f033a91122c220085f1bb44ab0138e4c4bc39ad9d38309d54dd6f50a0d8e343d74fcf628a661d06568e75b589e000000000000000000000000000000000ea46bd9b4bbc286d7215a1ca0ea49d94dcd0fd69b85e4d1e9aac182149f763359f0fc8e889cfaedcf5c2a6ba00ab25b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ede6ad68613e8bd24c34cdc265f4206f5f75de1ae85bd3b1ff521b73b644b41cbad32175d2a6ec923cbfb15352abfa00000000000000000000000000000000006a85d15436b6889ddb7724f1efe8440c7336e5e3e13992a8ae3ada9982bfd1d80ad580f3f39f5fae55398af07444b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000798a6499923ad1447fb8bec3ea6a63216528e8c5f8726b7f20758813b9324f05fbc01589aeab9dc3ea4f256f1ac477100000000000000000000000000000000167b40122cb049b1e7c783c895264998ede8a17d6fa8e9105370e46eaddadbe0fd813a16a84b8002ac6f49b2c3b3e1bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e02fcfebe7190e8d960b7cbe5be85ab0b35577693a472596d6cf292165d93fba7152253e793b889f13ce2c0c40c54400000000000000000000000000000000084386f7af138fe752f87f7ab47b2165bbb4d2d0db2a510aa2da3fe1408fe3c114cfaa3b13b0d25801b80ba923fe2acc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156a9db98a271ca9ef8bb182ccbbc031f2b3ba131113afa156f13552e18dad4729085e2574ec16af08a4a01a954558970000000000000000000000000000000018fbbcb500f76b24f65d7a630f6a1137eb1d46491fc6af58a55f6b75383c32eb9fc36da9cd22e3f3aa10f1c417b3f8001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008f82f7c8a4bbb0ba25233155b75d9995beb83f4ffb38e44c7d70155bb7146fe76c504ed453ecf046d97b16a44fde57000000000000000000000000000000000562c7d0f57594c5a73cd0deaa26e82a3ff423d91f1417d6fa8705fdd9f19d940c1dabf497aa775991d54471bd1204ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f593e0c2882addc1e8498b09749ff401643d598515d0919541aa6b5696d19e9cec1461f9cec06f957be1848cd38b110000000000000000000000000000000011cd8c5c2291772d441bbaa70bd58f5664cb7d6a64434dfaf2309de9c56711e5063d3049c3789a590f035b079d01d7551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a09625d73df67266afa74cc90fd328f43ba2edad08371116e84c6c0c79572f2fc6f067199b11fb82ffed501e3498110000000000000000000000000000000009880126bda0918142c283ea98438053d5bdbe175286e939edf84b18906a49f7cc39af1219909a5ba4f5262a8a9e3d601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c24190dd4545c6cef2bb30d727df22ecdfdcde2af4feac2d3ee3968330feb5cbd65d4d430482858fd83df53adeb16c0000000000000000000000000000000017edb16ba089e0ff5084ad0c52836ab72c47d77a3deac4884ae547e935a8c779a0073c3654af4c22b0e63e20e7a7b57a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d96e767c8cfcb000c12090eb162f83a2f7e006415464a394e5b91475ccfe6a69edab8fff8c91b574b93b07f585e4c12000000000000000000000000000000000b3962482d347c58ec93213633fc413298d3fc47bb290f444b051b6834fa5a733a1bad042b80a7af9832f7471c1c20101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ca82c9e56f2f6f72a52b0f9d1c7d9168c5ee97a56d6c82f0eb8e68fd2ebc6464a766500b10acffd541cbbf03863bdb000000000000000000000000000000000ab27d0f3e6b802cb661208c5b9a425634ed9e66803435f9698877d15ee596037160304dfb039dfafe564a76e70fb2761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c11ee4e540b3874a10248903e0da0110eea5fb015c7b22d2053178603dfb6c1249243b474a8c4c5f26dbadbc1553d8f0000000000000000000000000000000015fe4b9ada79296a22d4493919545e5046bf8b95d5a7bdd9a7467f4b4bf723e6c1c64532a4af71d5875c571e9bf0e1f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d85ddb3a738882b83e9508f6a80ea6e97cb995de4d8268d4ece1b6654f6418f447581284f7c22a65ebc66612d47ab7000000000000000000000000000000001387fb103f138d93634c63dec396de6375588d90efc363920129f330ff9c551c435150d00c1386271bb7f72c18c7306e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181508666b83acabb89741ac11762f15af5ff8cca96d3abc5282dd39b8db86be17834b953e66b573ff06b4469321b4b70000000000000000000000000000000009555fc937513fb6395ba881acb3b78e34478d3c058bdc706275c61af6c3711fda5a6005d2965779ed3d5cab7d60f90d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092b32dfb73577b4f52b257b54206811c107697413b7e83398ad4dda90679f262287894c1253abbb1dc362d1d7686473000000000000000000000000000000000594c991cf66afa425315cd658edf27c7d7816638b4391dc01fab3eb38bb5d0e3cef6000c54787507dff64ec226572241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b26a967489f03de80bf04086b9be036100a041a5e093ad4aa80ca24f4690694f42820b54e323b25b5e93b9c2486b1aa0000000000000000000000000000000001b76905be5e662f6b795044e45af7b094589f7de99c24846d69d5cca8f6bdfe35227e0723e736c1859c4618b73441eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f15b3d211d6d0594334d1db06dbd9ed7beffb0268caa64b231a91ebb7c9ca6bc71bd4498d374ea3e9b4bfb8865ab86b000000000000000000000000000000000572946fd085340dae2f378cd4bee414c7bc1f11c30ee6c4b63a69420ff678dfb0b488443d1e8184837ae5fe7d8a1dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec8b3d38331169d99f81f65c1e2821c7522adbc32c2729a4f3e83ebd6865c28118af90ed60be466d69640023bdf8e740000000000000000000000000000000019051e0ec7f090dc5b6dfb57801bf903c607df52b07f47522e3e6ad03d94e0b162a6034288208952d267c2bd38ea70b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eaa40c604a22d37581efa475dd09a71a172659e452ffc14cc9a7bc3d7bb59016b53251c81cf4633d2f8fe1be62ae4180000000000000000000000000000000013a0332d3e348dd4d5706f32601dd82b8e26dfba93ce15a7b90ed622eec5d619cc6173f8a76ac9bfeb8e050c981220c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb8d1fd3f6f5b8f6f8ce288fc0e0d7fd5a9374fc661e2079d6a07b90c15fb52eaa36f24d4b9f5c3ae03eb8b1c1dd8a7000000000000000000000000000000000c851f5df50f57f4055f08a3a97deac8fad3344d3663b43dcab596021a760708dba708b7e258b4641df87541129a58641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7d446058be2a0e92c604bf9b27192fdd50bbb405ef6684a477c586ca9ec2a1de7ec1bbd0326fd589a0f9c697ccf93c00000000000000000000000000000000089486826506cf258ede79bc85ed0db995d76bf45ba1e01091848f2743a5e76e67a6b09abedc8a497fa462dbac8cabdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eccd6fa7e83efa3db93ac826a142bc85d86ec367950fb3e5f286fe9eac01ed557b7d3ec36ced2458aa01869f5c309c70000000000000000000000000000000014bf5d4e4f018e21311c0e8d61c6e77e4ff6d5cad68d5707ebc18ff43f411ea8b9e9d5629fea1479802da5f516c6ecfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a80d98ab896e559b1046a518656d0704369ae5b04d8ebc55e17d49a5b9b7a8f6c878229eb52dcf586f0ea7377008c200000000000000000000000000000000158654d92027a1a6ead8d74219112a346777110798967a12015cf838416e08ba90b056274eec7c9bf1de40756b3b42681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5380bd320f492115e48dee6a4a1aaf0e5eb9d9755cbdee02b8a791967996c7e2f61e0cb6eb11d109d8f4601e618192000000000000000000000000000000000b2acd51c6f3ba9ade467f04b015f17a2fe63a1df79dd5eb32c3d35b76b6291cb0acdff95ee7970ce0e3623d7b6ec6851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6f96d190da3b9d64ff4735ed1ec18d80b3db9bbf85879c7b432cdd2637e02f8032a4c435ff8e8323f2d9f7dcf855170000000000000000000000000000000001dccc8cb1ddcb6ead0fc2a7dd69c4005d7cdbac3cc3f4f9fea2172ca467d34b84890deb6f59da16d99f1495990184c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e98a0734523be174a7ead24fb00f4744b78ccf25adb781971f6223e836b626277b1b9f790e629ed9178d27b3fa5068000000000000000000000000000000000fc7be82199fc6bb2dd1acf882fc00b56542feced159f730f6632516c8c7ece4280e348cd8272a7879362d2be47fbd161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019afd9b0ea8b91a45e5388f0d1aa93472821ba188fcb0d9c1f125e7b2cafe63e7e0b112215028f5a39a6d452637e488100000000000000000000000000000000171a2569a6fc48ece55589cfed029488f2647c92ccb04dc5e7aae7827ef9dd59340a5b995211724b1bffbd619cb5af6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7aca785258feeb285f7b021c68ac1a299d7f10ffc7cb359e9c85e5af932ed48c648f1f03d8cc33a118f0cb413dc0ca0000000000000000000000000000000012910f68f47db2011616e4866c719fddd5b97a6d04b5bca4d6e8d0f545341841b84e670fa4cef62e51f34ba1566c6c9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1f1985de79d9e60079d346b872c0ae9e6f76cbb4605ca0d02caf18e5f7964e7422bb4a57c46c628a859f4f9653ce0f0000000000000000000000000000000006d6a2689eb289deb65ca2c88f0fe51cd51a41959c020c5e1c64c1c11850f0734b53618b7f155b2a1c7e9ddd9111da201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d7b8526d7ad427f5aeb8ffbc9e25de927dea01502616390bd06b2685f0378fd4f2aba941adbb4a1339dbda0d82c59f0000000000000000000000000000000014e51b572a0eda530b7e2aa53d0454e88035bb3aa7ca5ab090ff6ae5fad10d619830b187280a991b56302d856832bca01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007789c79653451e1715387a738d404353b592acf2ad0c23acee0ec3c533e540b0d60d040b1128e14c64500bb1fd4cf4900000000000000000000000000000000187bb42e981bfd0226b2801fce153ddeb1f658e907cb2422e823ddc8a00db6b7268ab3f497cd67def249c8eec8ce320a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ab44bf22f599738327f737006b3b1877f159ac4fac6cd480dc29785cf9eea6b5076c55dd91fbae5fe019f9fb8bc8c500000000000000000000000000000000153ba01b478d567b660801e6d66fd398c4eb8c74bb65463f3656b13a992a4f1aba52b182c0f4a2c58472e3f92afd14131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c2a9474ecbf5cc2b71588a0c8ff094e3b836f4ea5bab6d7f251c81af4807cec7e595e024284c02bb574f6322551c05000000000000000000000000000000001203298828d31c25f888bf668c76808598f3b1c4941be00e6f253e991230ec662758211a2d72b86680c11174b28a520d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f908c98755408879e791c2137f8f62043ef77ec6d7d71146ba02765b23bfa9728442285d12abeb7e6a29bf1ece0bd2a0000000000000000000000000000000013742633c217a5b4d9167dbcc210def68a400de6832ec3ef87196ffc028cd3c14a66d769c628cbb28b3c23be6d9d64421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fbcc5fb48b3eaf70e6f90b9bb8e532c5eff028098aa79f407b55fae65aa91f211eefba01f8bcd7cd7bf995203d9b9c0000000000000000000000000000000018139425d3aba0e05d60d1760a20653493d57b8e177790277b61f13402171bb071fbce50fe10591a342ff123c26d14ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015764e6a821042564779edd5ccf7d11313ed0c5d0c51ab2fd0f082e70bf0a2e4ad4e9d65b1762abaa12da11e8948948d00000000000000000000000000000000089b78c1fe03dd5996cde45a42d32af12065a2c4087c84c812297110ce2efc99c2836c573fb300419cc39efdae55cc6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017579f63003742ebd584f6d8b64ce072b59ed4936a291bb420c74e8cb2e1ee4fd57b040dfcf21e5523a50bb67bc71cde000000000000000000000000000000000019568d1ced5e3e2ac1dddb66efbe06f6e601992e58ece451c8017d39c7cb22909a3be5eb53d046945b938572be63921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025fed6d4aefe93b807feb052e309c16a6c2abdb6f262c5b2edc9112a3daf93c1a449a411eba9252bc620c7cce432b680000000000000000000000000000000003470cb64c67c80543a5fde913a4cfad791dcba741b979424ca99a3eae67c3613ec96daf181867b67c9f67f8f32c05a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b71f61cf73e7dedc1f9eb4539c5dcfd9e7e6e9c8febb07f1dd41c02a7c3621c9bf16a7d500b0e564e7c154cb4a1f050000000000000000000000000000000003e65d6184fcbceab8cd2de4869d11c00e3f3be844cc4fcce2e1afbb37ea9386d313c765be5fe64d212e5410ca6c607f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0aad176008af80ebe2f7150272cb41d04e177c47d4e19449b18f3eac7c7e8c73f12640d8d65c124685e9c68ebd798a0000000000000000000000000000000016e9c506189b410a7129fd3b09cbadbbaf1365fc79735c5a92fc23a34d0893d724486f7fb77fa42ccf1fbfe5d3a00de81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e2a8e7f9662bec69014bac4a244d59a48767d2ec18cfdabde96434ca603ba57b16aa687088968ee4a5413824371ca3000000000000000000000000000000000c7e6a5d43abd9b79b84ba78adb287a1e056c498504aabbf948b945c02091a5ee68c9178eaaf9214593c7a3b97ce0b371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014679cb7fee2ebd76e64fdd7de0791c60e02569863ae41face922d3d8c05b3ebb8687da928b2a7c73de5ff36b97183b2000000000000000000000000000000000111001c8c56e9c335154be11f802c0f5ea176ffc180101b79b89870099b3778fb618d0b7cb96f3ef2f55f2c08a58c891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018141e0e1c276f1b92e6fc3957d673da2e9ac4c4e92f3e6b2cb9e1b64c0a76505b9862b2680174670500fcbb2a4c7a2400000000000000000000000000000000076914dc9b5d9ec395640b1741631481888b112f4ef3ec79f684b2433c4f6b647f113c88647b7843c6c58399e9bd5c001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb18db0c3d7144b5d0239d5f060fc887d07d2402ebab13e25a46e1133396a2db2a3280f4d1c84e38767d5fdc9dc7dc0000000000000000000000000000000000df7d934afa2022b314eb5a9f31d6e817f52e86c7e6b2db809461b58688ed708e48eea6ad318cd0de67d84c1a44f5b851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168102b01882931a3448d717fb1d9d8c0a9f218925b01c07b2088fb47cecf02aa95cde3c0f4a6e0b0a83a42915ea41950000000000000000000000000000000015441cc6399728b1dfe1f484394db8711eca75e3655913c92ccd0c3c14487945c57064310928f1bc9aabf0fddd37d9151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001092b458bb934149b213aaaa6cd72eab830b35044e580e14e20c2fed88b06aff58fbb7d99a7b8cf7a4f6f2162278c052000000000000000000000000000000001903143fd8bde295029b371c542255c693e05ec80918d5e1f997094ac3dadcb4803206d9ec40d3dae8b46ed368a43a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047fa31f0fc59feeef84339be0561ab52752ce5efdd893c0a33be5cd3fdb52e0875a6601cc7964969f639d9c217cc46b000000000000000000000000000000000708d187264a0f1866e979dd55a155a10bf171942be62e694fd8f2aa50724bb823e92fdd2a75e5b83d717bdb96a0ec001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010caeb4597bf90ba9e2c13ebc32dfbe6d373996c403104a0cca3da1b1b87e4279d8c4f0bbbccee63b78148f0e2a427660000000000000000000000000000000007840b5d1a03e8ad1fc44f2782ff1194f7ebf173b58d552cd128de5a626a24328c8f03f46c258d04f84b1cf89eff4c0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014878d019d48a83d4a0f69243eaa23698ea5baeacc6d4c0b80d2400f8c3f21f5e68ede1977073bc89f4ca622ee931a2c000000000000000000000000000000001435052d32dc50fd25d648222e9b267b75159b86c5d3eb63e13694cf57510ff8b4c646863751c3f642c4fdfd206bd6c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbd35d2c78d784ccc29676a19894739f1911eb6f3438983fe2fd93dd05aff84323129fb293a907369d8a82a9acf82680000000000000000000000000000000011b313a5324e291ecd13e2ed9e34eb97ccfeac01b0fc9f18281960884112d213bb24883800e75b34e8d5a9bca85f16a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083117d9e2d123b55826dac06c97ae4270050f712195533b82bf817aa9b23f060f6799b029823470bac09f55dc42a33e0000000000000000000000000000000004451ddc9eebdfcac9f32406b25822c0e506490298822cacde77258329c76c792c1d7833bf8bcdc7c0b386cd5ba553731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ca66b676a7e7e2ecc63a4a183ddad788fb26516d7f87d8addef08ccce61a67894bc361000b9e4490597940aad3a3bd0000000000000000000000000000000006df0d1b077b7cc5622d39214a1b27666bd93e8d960bd4a6bea9357212a6b0a1bf0a810dd84076927629ced9b18dd6201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e673897b850cb9e87fb3ccee9efa6e98476e2cadd7b7ca840e5ede598f63be63e440a2a40f068a25a3663441de715700000000000000000000000000000000185ae2963a37f580a2aee3c91a99e42bf1f6ccceb3068df93158083ede286d344b704de8fb35f152ebe9dcb206a561051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094b8571f5f49f57bb926d87d34884b551da98f8597aff4d82fa37f83dc6d8cead55360791daeb91aefb29eab29aa83700000000000000000000000000000000118aa62a4de452bba339eeb2f4ace3a817bc01fe8effc6c2a23377774f92da374864ed3bc15ac56918d1dce94077eba51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ada220d8f2480b6663de8656762885e66310cb0f204c8014a70e380981a2ff72ef920d38a7f701a90f88586a237b450000000000000000000000000000000000291842f0e7e466a796b6a9ae41e0bc658aa0feaf53daf6f7cf6a64157b1e5b166c84a8eac76a0ca80f04d0a83eb8f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d3071b5a14e0052de49d2923632ca54ace073e4f0bde3740328dd483f65d001773dbc80ad92337bed65a10878086b6000000000000000000000000000000000f857ca53062788f39dd9363d2a3862791b6974057dc2edb73a503b187ccc15bd035bace26165b8df1da7dce74cbb9f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a1441a8aa4d440b1d62de8191221b83dada7a1e42610c54b2bac0a4f75bd77207e67a329f7204f15639721b2a09f1000000000000000000000000000000000154cbf2cbe73c52a81c1e4a18d34977e3bbe4ca6b52ca8f116fe8d82028e74e78603d1e8cc8e06df9fd0f1345e87c9cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acb2e1bde0c48ff04cb9223607601212b1b31b3a010ddeab08855d86dd3aadc799a04ffc253bdd7b2e492430323bdfd00000000000000000000000000000000133cfb141cdfb5564ab0497fdea57fbaf8f54d8f4f5b4d6af14246ff9b70a6d716e774d828fcb1a4ce8f634e45fb81ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128ec94b779419054f15c038b410269a420d4add8920d6d935f9dc496ca42ae1f097fb665b5234b5cba4adb4159aa38f00000000000000000000000000000000083a43c508253340ab9e7c38c3e5c68d913d5886581d95dab29e12718a8a24aaa6725e9f075d56b9afb227b5fd5ebd781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c7d4326ef2acfccffbf9d578cdf31e38247d1270806a8713226c12d9cbb4b1447c26fc2e4d6b3a43e37eac2dd61ad00000000000000000000000000000000006eaa9b0d1f578f78751493fbcc91aea04316a02a9faaba1edc00a860ef4b1abcfdd3387d822cbc52f5ee98c2b5435171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ce159a4baad76256fa7e33a48131de57b41e6cd437fdf5082791b32ae8a9605a082f1aaf439db221cc3b13dfa3049a000000000000000000000000000000000881aa002831b15937e061a64037d3337bd3c30cf9a0c3cf3281ea9e2705843a541c5675659239383c47612bd2f6647e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b94dcd5e32d9050945b7a38b03ba90d4304e55bad92e85f8d0e52b71f72dd0312149f8f1c56dd99b67d74198f4fc2b00000000000000000000000000000000099540949d887d6b7de20bf785b0e3c36cb12ba44895278a8275b9cfcb7bdb93cd39ebcfa8b7b12ff77d83d5a5bac0331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004953535b59a7e1377c4e9c556e9a7d0be26d6839110cf5c278930900a5e56b1fde975cd1492115eba8309ab1d2a69870000000000000000000000000000000014a622f4c6df000339b2d419f0c0e7c90c8452e51f7b4309fc2fa4f124a6688c3029321345f06283cd50a9e0d9602e2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141f5739d263695e88b64ffb57212d311d65226e1e4c8aee20239400457ef9ce380f0bd9c21e42bf5d0c4696add35e21000000000000000000000000000000000eaf328b6ed3879a941b00c6693e6bcd8c5a5cbdb51a25fa46f6f8902af98d14fe4a70ba0ff129723a8ed3de16a045601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057c16e1c18e5012defd762fd881c556c173e12553a3b3f6109e7ba658a3f2e7ef82ffd16b03e142c4793f1f237ebddd000000000000000000000000000000000b08540c3a4731818e186063891165162306fbf6a6a42c50d4f8fbf31bfee3af7ef9af8a4dee4426f2bf5116b50dc7b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f3744c9aaf28812f8a9dde58452d1bae3efef0f8a99c220ff68c9c1ae5400d6fbbb1566eac35b75ab44aa635f2c205000000000000000000000000000000000ceb294d6401975795ba86bd5555f4bb302454c87121b7dc3288f8dd1277cf0e1e86d4aa83831d0a7f8d08c9b5a51d7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000106f02dbb46b3abf05513dae8de2d3145a04afab9744a6ac6f0a6b83fd4840f6a4b1d0ba4278fe01b759f875939f6310000000000000000000000000000000001de555d18d1bacf1aa8a2f9ab69ed1fa98be07cf3ae8edbf7004664a5a00716fedb53b288a443a4c2a5d233975f4dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d8746e8a9f6c2cc53a899348b64c31606aa5f09ee30f23645f0baada13339ffb9df3fffb2f2eac481ee64f56d4f5b400000000000000000000000000000000126a18d223c7578e45618ffcfbaa26b8ba4e494422e0d414c3c3f7016bc36cbe1932dde0f06257039cf309a12b2135661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001782c36ec8c76c3ce1e62d72c978aaa7ed0f58af914614cf539553e9a3a2c8f50a920031d0dcacd27fef1f8b44c064fb000000000000000000000000000000000180d75d21e44e278db8bda9a4c8ffab691dce3216fb67bb2229994e72cd7469a11d6cd2d68dcc8d395b061faf535f6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197e95bcd7bd6e69dede6f0e4a510520c149a5473b500e4080b93f1d24118fd2ca3bf1ba2fa95e36b1efcede53bcbf79000000000000000000000000000000001891bb0ccc02d6f40822c06dafec8ec4daa388e20dcb3cbf9cbc3e579809973fd88151f29c99d9d9290d80289676cd261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000071838afaf2d35710fb72db4b826e745e2a7d69b62a2d134b77d1491bcb412842ebb7c7a73baaeccd7ab1c3f72bae7300000000000000000000000000000000041ab4877f90a8f990da9e50f94a98a082c663dc69c0c7b141f3432e6c7a2d33782e6b28417f8471b3ca0b20199db2cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d4eeecc984742bda5985acbf63b983ab4aa20a6b389e6160bbe820b264cca60494e5143b62e6a60dd0bc795861ada7000000000000000000000000000000000a5977cda7481ee6b56dd55f56dfc4cacb1333ae6e035f3efd2d12ac239edd58dde2abbada97b5595729bcf1bfbcc1b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d7fe3e218b455aedbde7bdf52148206d9f80e497debf0c5be05936e1b456329a96f9663f024309bd29c152752f9a9e0000000000000000000000000000000015fd0e923a208e9af3d2d72f9c86e5164a8d5a0f332d577f757cb50c8f2990ba5e05a7e76287980ab2e508dec25fd6171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156bc719449ea4f74c2758cfd0a003941c49c14b0e2474e0cd777a98a1da8ca78580997a7e7a6de2872a98cdf7080e9e000000000000000000000000000000001013a7b72a6e604ae9b576977c764aa72859d1f5b114ed68d87d3d80421a0ddd7fbaef21881ef505fa5aafbf9b9d416c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000efebe540e6e84bdf1615eaed97b1aa5523792ddb86dce3eb7425268b8c0131b392292fd27adff12dca4f50dca9b375c000000000000000000000000000000000832713047ec830c5246195ece0c9232603f3a25a35d7739faafcc6adc8205fc0e2727421298d755407b9636ac6384331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036d25a892cec5981c1cc09e6e20cc45d762dd7f76eb0362008fb21c57e01ca493335503427c10366c9833ef2d52909b0000000000000000000000000000000008ef717a33006f9438fe6f7937cf6f792a68b9f8863a94da8b86be1f82443822ebb0bfad752d83344c61c260f4a61db41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181ed308661abedd37203df1c9851938373ed77285607fe0060842d4d3b33716d2a2900eadf84a26fa2b58683f9a00d5000000000000000000000000000000001514f8b37a835f7eb7ad3e58f47d8f1cb195eff091874a0ff2c40ac43abc535933432ffa87b507f9bd43d61fc93fe3fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c19ebab51333fbae49f552291475635d5b083e107ef6c2481137683b6dfd327c80ccd39ca8177b259dd2195aadc12350000000000000000000000000000000007d67c3351fd98e7964ef3d943d070144d7e7513fc6f4054efa79dc98da25d118f0067fabd554fd926c2744cf8f9f7fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7e62340fc7f0cd528d88cacc87382dc37a65b722995e2d84dfc0304faa039e45a05c3073f4999dc6a05cae7a23cfbe00000000000000000000000000000000166ee356c45c196e762e54da3f5b0c93f461b0727a32fdbbae62b80cd245907106653c9ca5bf245c7a3c7ec3a414a30c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a2e1253318087af2808f92420ed811cb56937d7b908ebd3dc71f49ad98519ff1c924d8e0091adf1c74bbef2e4db3cd0000000000000000000000000000000007eeb738b5f83276a9019f66d5e4a8bfbc994044e36c9f6724b499f3d5db20f588f458686ca950614b0ba3a2147cb9b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010cd40c7b92d64fcea54dce4baa211a7e2658f96d4c880e6210de566b033246752083c129ed0b224a2c6596f01778049000000000000000000000000000000000da0a56e024bcecf709538114e123f1f1aff7e760ec41b0f87b5e2861266f791bf9f3a32437577b969629720020208581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001042d2a3893612a57f7e69af9d20989e7e629bcb7ff00a3d3504e6ccf91bf2eb86bcd5f69ca4393d7311298f606d69770000000000000000000000000000000013e41c6596c937c8f3bede6fac8cc68516fc7c9a212c09691075ce44253cdd83a5dc2afcc79c9aac86a783a57620c8031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119cbbbe26e50b02c634b54c9059c264602a79cb37e9a3c5be507364a5eb4a20b7285dcc8d2847d06d2e86c126d3c2fa0000000000000000000000000000000008dafcf9ec3af386fd69bb44666ca6af13854344ae066efcce17b35f7c3852466ed7c6946747673769e2d658677998421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000570a2f4bfbf8e65f13da4e047747e148a83428215283051f53920ecb4cbd9b70eda22570e76fa62598aa15539a87fd9000000000000000000000000000000000384faa7e7652c0063a8e37a3f2945d13895ebc691937daff407ab28b62a8a8f5526959867f8b755eec1910b3a4e5b791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127f59537d7dba170a2674c33c2fe1db1383aa860854dce31100974cfdbb2dde8e04204a87ec5f6e960aed2409a30249000000000000000000000000000000001945aef5ac94be227cf956fb181fe0daa0938391a88efd8ccf8285855cbccd40616dbbe4143993d088389cd001ea50bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b03e860b7b7d43cef7400dbfa0511cef1a7d01eae78166ff25379c84978e16ee898eba7820c9ab7e44e3e812d67e85000000000000000000000000000000000b47c438438a396972acb9e5af9b6633c6f270a51adfd79e7d6e7e40b011166855d53ef63c3bbee357c4a92165547b071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bb23f8a43eb7d0feb08d17566367516d5b59568d3da44c1656bb4b20473bfa68209a14fc37530e2631652f81f8649e00000000000000000000000000000000072be2314739fdd9dcb9faab9105d6d9ef8be1b88928cfdb7e2c928063e710629b98a8e42209abfb2b0f63cbf2201b001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091d0eb7dfe296371ec7773493e22a33e6ed1d6a2cdd2f2f6584113e91599e3d13e19d68257818202716b69f32fdb93b0000000000000000000000000000000009404fcc1502530ca43b47e8994f2cdee1366d1b1d18893246c8c041fa5d95381ca3b3255431bc55c93c607b7d36306c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053f98a0336cae5d2261df894432856a92c6644b125c9e4f9db4754f96fb40b718ee2f2197565c8a0e2d252fa649b1f20000000000000000000000000000000003444f03d1fab5ce3daaa2d08093c55b3e0870d598e3d838da94c5317da8eafdbcec546ec072ca8748410a4fbceca9ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9303b61b8cf50e77ebae5b573b900eaa9aae8d17ef7ee667a0539ae91a51daa4f3c2374d92333bacc6dd77ce570672000000000000000000000000000000000193f02e3384c863ffbad633255079e591a629c623c3c78085be032c96ef188e1f9a6f933a532020dd998f6a316632371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017f96ca7ce16b82a93d1d71d6aa62ec850e132ef9678d67718b95c340489afc93e78ec85aa20a63587561d5cdc039b9000000000000000000000000000000000c8a38b58f0fb4a2b3c2a2b9c896b5212384cca21c9d8e72e1b1162d5557269a02e59310e5276913644ec9b48087a5621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076b3b9141a92bf89f30abde91724f0c28eaebd8b7f1faa51f97d221eb1fa8e0b15bde7904974b7bda4fa08078d917ff000000000000000000000000000000000e840db629377ffff8aa5c8dc28c7d3d478b9f40b0f721bfbe371ff918040fefba316bac4c68159b83a6d448232572fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c16fd7ecc725da1b1918edaee61742ad15aa89a6ce717a876643990cdf60ced8fe427d66eefb497106911cd2d832400000000000000000000000000000000066ff1a339bafb14e44a5b559323a9a4e5976d8a202be7664bd9f9475e771194ebeee02452e62290f471e0bc696af9841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001708a9ef760380c5366929b51df68b256fdb47e977dedb3fcbad0b68ffdf1a021da832d2a49271109d02673e203a992b0000000000000000000000000000000009700a0a106abb238a9cbed06f1a4e2f2335f014a33965874ab6e891005d830c328ee0a4bbbb7ce78a21774e110be7691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001811994efff8a9fc77e8bd436f9736f8de2a99313c42f753e83bacc3c50952565e47f6194b34665289b9a885cb103a170000000000000000000000000000000003952c2a994987ec10814d22291204488af6f2fee058dd32857e9f0d34b5aff5d1e69522c90743c4e67eb7a64168e9d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170784c421f6982ac64dbc33e388c12686810b40357ff1d67ee45edffb0ce01921c97681120c75d81579ddad0d415b3b00000000000000000000000000000000012c62034705f9867db095ee095dcf864e091236ea21d99c776c6854afd116a0bb014fecc719b853dcdb02c4a92654f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000855e63b42a018bf34459599d224ead759d924994a288dc3f5da46c1db4907ad0b210a52526fe58a9733b06763bee73f0000000000000000000000000000000012bfe2e613ce1d6d439a8c95c99ee70f4fec4874f741315d5eddf2ecc3a182bd8415a03f16b1a565f634232f29a26ce71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131b8bf680defed3720bc23c5a169ea75c1b3fb93579b8f1c69837810fdaf6fc756fbac1610a4c13b582540b4a3efc4b00000000000000000000000000000000119136eb6d7b82c4fea39283c5a70886d5a41ff678b40d1d7a72396ed7565145dea39920434db19d0b9dcfc9ee8fb2f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e3a031d833baf041f6bbce2c071fdaf4e24d1dcfba811784740a058cf8fdf1ba832db6cfe1fcc57ba2c50255c65f25000000000000000000000000000000001316b3356b0a24b26fcc5984550e0374559418419b89f0d71885b9d3b3f3c62a8f3d518073922f58d532e1d71e6022ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112fe53b450f17e70c37d8e62006e3bd91a6bcd59cb786bd3c76dfe41a19f325b5ec2614d4bd1d3162d2b1c6bd5723490000000000000000000000000000000013c5bfe8ca8f6192bdef003a4c950888f17ab175be4b97c4b0f54deb0a26164186472013f76337cac71adab0fc097c5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014846d8b5cb98364fbc0f079c47f19b63906e69019f6c5f1d6dee1a26ea01821d108e55f0a49da9b06d78123be0a939c00000000000000000000000000000000163e4ef3f792844f81c71af14a4f77e302fbb345cb42822485fe3d9f631675de989e9b9734b86fd7da9987e5f6d56d8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cadad68d5e656e82ecbe846a0a045ca495eece2386a5a717ebc96d5be1b88a27c02de4ba337429ab1a8ba4d1c3f70190000000000000000000000000000000006e479435b793ea08c3a9fee22bcc5f833314b201468796d962b22087bd5da013e9c96887eaa8fc9149bcf790d2f2ecd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000faa486f217fac43e94968b3fc550900d6ce97603377b4663530ba76b029ff8d5a275813c0c1ec08fddbe78cb89b367c0000000000000000000000000000000008fe06558b29bc8512afad09a483e1acef857270cdffcb56f28a06ca28df488f50f9731b462957d3f39fc4290ba5163e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001995f15d1759303e07b4707b582dbf42f48aeecb58dc57d55e1a4b9137fa058e7069eabec01098ecca2ca9c4921d28b700000000000000000000000000000000119d2c2383f07ad7f840d3cc6d9ab8280bc4bcfc8523fa10e44033476788cd693e3b0d5a3b3a2928c401f0da9dae65391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002739a47b2007857f8d143ecdb3d2898853145a6ee13eca6bc9dc8998d5b773ad001f2af597a0cffae6ad5322bbcc9c70000000000000000000000000000000016c3832f1ae3e9fbf62daa00a1e1b4cf46a4335377e58e18604081f8643b315f956d35382fad6ff8f4fe07ebcd60f49f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cf83bb70f9e708f173ec8a18d1f9a31dabf7f4f7c639d08f6f22b48745e68a166bbb54ae6378bd1a829fe2765122ba000000000000000000000000000000000a63a9d81901dbd6378c0e1d47e4819db3781c1025292f7c515cba662ef5f9c7aaa6af978d6b25c066df82a78a8e76e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea6ca775dcaa0f06f305ace5fde12e06431be0c77bb935ac84f32117d2d06bfe513ec85f36a82ab8abc1fb5a3034a780000000000000000000000000000000000562dfb1f521c740f14dc19233b029956a194cfe934eea208e691dc9ad33cd3ddd99db40ce40f268e814575ab4418be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cb9bb5ecc4ca97f9af1bfee0ebd259e2254903db674b019e2c1226c4ba052a9bde09bb5f13161d88860159caf6d22c000000000000000000000000000000000cb31a0e4555f6b22dab7491010d922ed6bc861b34761ce13215fe7d3a6ce061fccbc14da03d546377d1ca0f0ee6911a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042515d2693e5919d019b8afa83b57dcff5cc5b9a4d88513cdea8489618f530231f0ca35ea84a70da0d024c601a656b000000000000000000000000000000000084f0b76cce5f303cfe0453b3da1348cf62451144cb9b4736068cd46c76e678ffe9dae2eb6db1eb59ecd815bd3b50bfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001839b49268eb9a55812af59c055e6f9b68cbcc22418a7603da07aafef2a1748496d10ed3d7b094bcb05e43102f11d3ef000000000000000000000000000000000486ba39834ab8ad14dbb1c43ebafbc7e2ddfa28a6dc0a67d48e1e151b7dca057f84d51857e8506f8310b5ea0ad2adad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e858f93d2724dfea4bd146117990d79efeec5c4f5c927ec493962e451dbad88687015afdcb30c378b334b17ecccf210000000000000000000000000000000019dc97efa35f4766f51cd4f93765795b76893e2d079be7a48862cc93d5421d3ef4184c5e335d7118998724b27dc710291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a2b5196b8be417a7a935d0f12fe31cacee7442557cbbb409551d7050d1572e6cef54a7fbbfc0d9239ecade620cb96f00000000000000000000000000000000130070a2ceb1e7fc87bc4c5ad4df5d2c9e076051630576d88d180d8f9971c710c3e202c95968df62a49dc93b407ccffb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009913aadd0664fa07104972008c26af4869c838f969654c9e13c098121c20dd624af0dc2b53c04c1109d56a5a7e0123c0000000000000000000000000000000017ab6b3890d397f7d798b99eb3235af1dd2c60f5036af3aeec60fd4fe1f41cf36758522859455f40a25a48c3d7aaac161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009de8655c5e7eb0d809ea284ce492b56ddaba2c5df5b36b7e586995f58e77c662d55be0cbb29af139b295063e63ed9720000000000000000000000000000000011a50d3edbbcbc2903f3931a52e87cbe5e4df7a5bc672779e1ea6e0c4d8c963a26cf32ea0d2e195f1db0189b3347747c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e4fc68183cab5d0fc065866d38161a5deade97e6b09a5a54e9a8caaad9e57fba32720e7a51430f6a5041a8e60de7770000000000000000000000000000000015ffd68db1299aebb543c492b392d4233c319c0745d95e59e8984d8f9ec3a4765a4b81df129b7e9045f30fcb5b81cc801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014de7dccebef2d3e9194651c4ef8955b7c6a812202eb46f713f4311327e8268173a6a9f97e5fddf8b5daad46788d34d60000000000000000000000000000000019e5f14b7260ebee35a6b287c034595677263aa6ef2616b3700706aba494e110f8a5ef9891c9d5b74afc2b0a0ed5ef6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ea41bfc4e6077de30416d3f48952a2f2b80c72566e6ae9bdd94c5598f2510e928318393814b4492f51c5b7dfc09af1000000000000000000000000000000000b142bc3d52f95b66af951a3d8447c5c4ef58f9f0a3088dd41d48289f0e8d6b49213c7bd0df73a9efcb8d0ce2d7950891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001983c136dd787b593f9de878c0be2f776aded8189a415f25d8526d5288ead1a3ce133a10199fe6864dfb6e1e583134f8000000000000000000000000000000000178b3a93ff11caed714293b7836331c86a0b2b3c438b3ea094610311cf1ec2ee0e45bf30bd4ac69bf18b059e924e53a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8af5f133df392287d690e720465702e3c9adee6885d889b152ec4e75625e9377b08f4f8f64d8165f74872cf4588a9f00000000000000000000000000000000066083df5e8c4bcd053c6b5f51284d71b05b8787955666ee5d4fad5d492fb3a5c51e33a6e5eeaa5b4e807115d620e1e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5bdba84864acec670b7b7d1ed243cc84b275da0e77aea36a066c000f5fe8009ffe8f0581c5dce4eaf89a1da646005e000000000000000000000000000000000b65fe86059b9b0a052da0dca59f0a20378a046f04e85a317b3a892adb330f498978036454b8c1e9beb9b563c6c60f771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087a1530d477c9d322ac7e30261875a1c907d67b318fb61e32c2698915beab1ddfbdff81638bf90f1b85915577e7214a000000000000000000000000000000001617618e3c6e4e6c529217acbf8322ad33df61ea43ff23162117462182a8c1943b8b24386bd22ba6f570aebba6634fce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091eba09469e5513c33402a796873998d13749f0f0f0768fc0eb75ed32eb76c811f8b76f5c9735fe9c99331a529e73dd0000000000000000000000000000000001d68d0adbe6014c4b085c3f50b57f5b72fda82643ce97c0f82dc92de43214d4a4f67465e0e85be052c2814a09a60ebc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d10b5843e9290caaea1e3d3d2ea829be24239d80a0367bdd352f35aaf8d0e91ad3bc76cf34087a87b3a807e38c19bd00000000000000000000000000000000002c710ba1de01fab7baa625506b700cd852296f3f2307246de2eaa73a71fff3158bac99a0b0194cfdd12a6bb08013061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bfa8e44c067cf500a2aff79f1c14b7cec731008ce05a39567310c241cf026762cfeccf9810604e098d58aaa262d8cf00000000000000000000000000000000162c993700e788b8274bb799f569a55a0baeea5eab95ad1658c0bcf11cd4909db72db0ce760b0d92c430318795815fed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0bbaa3022cf2909cbe0fade6e4f029ac4b4a16fc4f4e6f081cb411113e3fe1bbad3329b3b1b7efca62b558d2f4bf95000000000000000000000000000000000db0976a1997217e90dd351d50586f7fd524481453d4c86392e407c8bff3338cb86d849302158fcd296c9487b19e55e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b013275a0d3f621a6af337a59985cdcbe84af727e1bdcfe30f61ee7ff275d9c414e0069898c07520ffa098d40870a30000000000000000000000000000000001b4e2d52768423046776a009df4aec0c7fadf644f8f76ff82a29ec6f8ded49651df839e8f6e1e381e0740d65dbb611a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001062b55e2cf3ee2034579091a7c8addf917ee680fb43360dbd8c2b2e7c23e71494adffbcfffdd5179e13f7da4f7e359300000000000000000000000000000000038d3cc6f7a3944fea40fd518ee7ff00a4d8b92168e94a8db1db7fa6416ec0f6e904cb6663a6a3c4fa065afb25cd2c601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015aaaa8df2662cd690b468ab03bb9c785cbda41d6a7a844ed92d3f73954f7c2dc17b13769ab8c53db83e7e61269ba1bc000000000000000000000000000000000ca26871a313010aa9a86c1901dda8cfb3432c258bd1c96e66624bf54787eff940d2186029a20cad37e7ec428a14e2f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ae936813317c94869bd8317e689f54902d73101b06a5732c09451dd4cd5721107a86aa7bffbeb7d17733ea45c9ce430000000000000000000000000000000018e547e0944c711bdf1c4994f89ac004ef9c04a5a03b20c1ca702b9545537efee7403adecac02a77c41e94015bbd07b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016790efe4b82dcde614b8931d6a25ce417753c1bef2a1ee1692aaeedacb14b444513c15705d8ece891f667d42dc47de80000000000000000000000000000000009b19e232b5f306f8de6e98b31d85b51b7cadea3552ef51d3d92a348889b8e29c887c0a0b1575f35c4382d6d7bfa2f401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcd6364eb7d0ec0b5258719220fe69feddc47bd17887775019ede05d429f727bc94d2e06ab315f7cb170d9a7b54f97400000000000000000000000000000000019b3b86bfbdbba0924691ec0d66e3327936ce3d0212baf85aae6729bfc6d7d6dde875f8b4facee5842aea557ed93d881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017da7037499b229f7d55296fb2e55c6f110103dcf8e12779778302f8f94919658b9ccc4938de416dc1067190701789c60000000000000000000000000000000011b92400daec46980addb5d5900fd411bbf0fa952381d206dd9606f62f07fd3c1cfd3c69c8bf4bda998af0581e8b7db71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c638745d19052e7a0c112b0c9009666adb7f805b16aea3e796347d82227aabf9e9a6a60af21b4ae34d5f05f5824aab000000000000000000000000000000000e4722e433c7b7ec0cb22847de4be1eca97ea228ded2eef8c0edbaaa76db27b91d00dfc897a78a37a90e45f4456ef6501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d687d732fbdced94d5f9ecbed5fbf98a4f2bf65e16a188f7fef2e126b73eccb9e442685722b0e6d7e7c9a25dbbd8a3000000000000000000000000000000000a2044ddf20de6e19a7e567704edaf1ef0ea83ca30b67d4afc374f34fbcaaf10a2838fc5a1758376f44556efb56378821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5bc97dc830b73e6ce7c6a47a0cf1083952e1a4fbc5c24734e6cd28845180a42991c627e7328df68e918fb8972e78fc00000000000000000000000000000000108a958bf9b0284918454bd6ea20c157bafdbf5c9ea4dd0fb3fe85825c93a2cee2e06503d925f0fcf67bac5b023991651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071866b57d50c73f3f4f30dbe016ae24e6c4ef9330077f8851fb8dbac37b4ad20e6a6c48d215b102517699dec4b2b9e1000000000000000000000000000000000aaf064e542c19ab90c9f4d3deb17877fbee0122cd674ff619fc59cae3c28107e04781bf1f2e43e55114402432c9a36f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118ce088e0cd4b66df3b0366a551a4d54ae76133235ea5a2b3f074266b3d7f84e737867d907e0d014eca7132336dcc85000000000000000000000000000000001320acfa92c87735d34762cfc61bab1eb7f384d07c3f1faa5eebcd8d2dc615bfdbf7ce5c3982b1c5ec2a6cd5dea3ea3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116330d790fc56b0047ce1866dedc3cd3551c6d618fe0f2be69b70f12f024ed625bc9bf366de68644916c8835ddd7f560000000000000000000000000000000000739a3fd6a67bfb45ee45bb95986e2dba04b6aaee0423203d69221364d14830a59493a1c62fa455c6e4d862f745e59e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bebd036b96525ea96cfd47f62e55f92d397cf3a13af0f0a5704a274958ebc8bc7b6063818b6e98fd86578e8c47f8d88000000000000000000000000000000000ccb140931550ca68597346f74b63723f7f9c1f8d63526341b45dc96e34ef4d911c1c7a46ac1b422b8c599739f3914641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb8a00d8168ff3f28294c423fe93740c7f52fcba0604d3e23546c1909a0baf34a61803a3200e34de56bc9fb239a10ff0000000000000000000000000000000015f3fb50ede2c632dedd8644f119ba77ea5e2629f115b83916452edb51d3f7d2f9b16562e4ee6efa5aa6e03e28b595e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179ff44766ad25edcdd58e6a0c1ffb8acedd7f8f4d198b18337e6a08baaaac95649b7bdbb21a256459e196527e2de72a00000000000000000000000000000000078e247cfa9ff9f72a908137996ca3e76954cfe2da0c472c8ca005aa565de7235e1bba3e504dd041ef4b62cf6bd124f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c9301294660ce4eafea209fa7c078be335916c162c721bd4187def32afbfe73b25e3bd721949188594ed654fc7b8ba000000000000000000000000000000000fb41ae7dbd4cd4a837e0d07a2d02bdfd5e40b424e0bd68896166018a20bb15a5ca8e0d0a95cc72c0af53398423439261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018685afc44721f38a2bb7e73e403e1588c09cd9c6370994a72114f0bea4b8bf370f1721e9f25b95dd018bfb6b6938cb9000000000000000000000000000000000ba51632db64e795e68faac8a55d81282f13f1b84e5893c42b5003db4d2faf5c50b53b939e88a4d56e938702d14271401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000534351ed6728390bc67559d92d82709723a271daad3a3c28c716c762de4f3bd39a39d2e34bce0de99d9562e946d48ee000000000000000000000000000000000d730b2f4fd82626364998bae177f20a10c78778550c51e1ddd017e34c905dd43931a05fadb2e5eda1d24cbc94523e291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001363cb7920aab3fa7de8b49bf6bad01f0155d429da7217558362a6c93a8c9c186203cbfb058ccda492beaf8ea1a3c880000000000000000000000000000000012c997698913af7763bcb9d3c4b0249cb3510a39e7ddaa858ba7ca11f343b6b37ed1692fe167e3749303bc55a1e227861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e34b30d9033a4e6e941bd9bbc07b46cdb25990e43c7e86e7384794c28ec1f6866fb3b34a8342affa585caa0beac1b00000000000000000000000000000000014309ce6cdd10197002f7fdcde0e1fe85a7423857e4d0a824c98918ff2222aae394cb87487e9975385749c9c0e34b6bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034839d5b9536e5c7ada6bb9169e9ec3326d5a80c7b530cb0e2103bf6dab27d8c3ac5d71ada81f7ed8e067b708fc89da000000000000000000000000000000000b6d9272b74705bdf3a7d707993d427c4d3c8b91902130e3a203694f813018bb74ed2771545da294c6df16de573263071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9f766ece814917946be335caaa13861d35d2f34055197f0666c7319f942e9689def3d6db443309a4f90c88d58ca5e500000000000000000000000000000000169adb818225f5860c52af7c85bfb41360272689359ac73151c00f0d87771f4affe3fe77c3837d20ab4f595dcf49495b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb7cf6eaa5bc485664c166211796b001cb20ec9bec47119838041bb5b0f57bc665bf72b1a34ae6f66645a3af63d9e40000000000000000000000000000000008b02162f4802981cd3302e7db5d844fc7bbff083969248378bf621ef6b25297578e334afb3c8eb8bd99b99f97015b541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8e3fe3ef149a1710ed568f3aa376e9db9215624e0658b6f94ac9e55dc838c2c138d9b86670245deb401856e9593eba0000000000000000000000000000000016c1eb0d36d150b4cffb995fe9488cb831f882597810c87bad036104eebcf3c5f43d7164728990251609a4a712474f231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013747075419153101b76f3dcc1d908568e156208eb48cd4557ce55e7f0e5a1fa84c85b905cc8013d0f85cf3cc8f760b4000000000000000000000000000000001559634aed4491e19eff20314a1d9f88d3166eee4de46c16ab7c3e4a14227d3e20dd779a9ee77d83a6561258255b36461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e282b9dc942f81cb165154e0b5b307d3d3abe6c152d733da0e2a62bb6a6a335a206f4c72d82f1abc19bd82dec666ce0000000000000000000000000000000000ce9821d323eed628e9765e4e7242604eabd6706ddfd722d70ab5a460a04f18774d58c774726a5b131b91bc6466d94c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151b426aed83d4246ad6d563ad7926941f4c5400b0759881c928d666622b0661d22394a645d20fb8c839122ededd7c2100000000000000000000000000000000179a0e7a98f30313c1764ab9322563594dc818ddb48ead37734c7905fb71abaea6ce702f7be9cfb70a1b201f377bdf351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167614c4ebae80aa0f54ff8973b477994905f4beda38dd08737cbcb0127449ad9ed2ada115a09f41879ec167617421b60000000000000000000000000000000000cf7d0f80f8b4b47494f7f069fa5685d5c5b11f5eb92b7893d45a854d2016f86c2442a6d06a8f9ecdd8748c548f9e841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012980fcbf77c238486272f6aa6feeba05204625f660e13e4dce2429b2301366a82a37f7a7bb73764c1fdd6fefdb9ad0700000000000000000000000000000000086ea68c7da02ccd56754dbc697db4ec452ab17cdd8385d0d1cb71ea0a71dff29362809a67226882fb91820c2d0eb8391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001056dcc04b55fc84e63c830aef44e53394439ebf8c6d856d3e444f4cc742abf67a62f16e38e3f4cea21489ca023bef54000000000000000000000000000000000c5fdc98fd1df5ca161965f95db18b52146a94c6b7e7e586695b75c105c28c3703fbf4f1a0a7d01aaae158b1deff97741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bc08628ac314db2d0df80aa1642c1b6b15d9a8fc7a53da181aede785212d2341dabbe616fe13d947b748350585d889000000000000000000000000000000000f6caa39240d5daa0c5cdb3e8aea7698c9e9c43f8d285f610138174bcd7217621ab81e17f3214b63cbca2af012ad73dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e35d889006324c7f1a6cc9151446919ac23131a6a4dd9554908d450e9d491e4475027fff69daa1f489a921b7e70d7a3000000000000000000000000000000000a34b4ed032355a44f02a3239c053b3e50915cbc7232cface5d1805a3341d5bb67508b8bb118cf39e5c8c0656b7d2e7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013b790df48550951293d76bcb64f351550d4d65fedea23d45260df33f93c395bff8d77810223d9dcf1bd50ee4bc1199000000000000000000000000000000000b9933602717af4ead843cda9fff47b893ac36e63f83dc6df96a158a1c83da1d5f89ec32f8e50ebec374d73bff769d131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001949f9a63fdd03651968d0606a7f7a3bfd02f19fa00af1649bd9721050fc37da32f69ff406ba60fa64655e60d1b633c60000000000000000000000000000000003e075b56327c060e99c72dc198ef9b73aa42869d1f49acb6bb639867a1d71a6bc8f2346f88aba4e47d999516edb1be41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e50183d57cc446d088814345100994e2156e524d2cd88f96c1590a2b16462240de058ce245952eac8c93b703935f3840000000000000000000000000000000014cd1af73bbbde453ff3090c57a4b9a3fda8579b3a7f5668ea2a53eb514498c2581303ea49c4e2138724c37b025194ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124dffcc8eddb5310ebd4de55be4214ba405bdf21dd11b7614a6a0434b299a619fe7f37c46ce7405ec0bc2ff47fbfcf7000000000000000000000000000000000f8dec31d5dd4a2fffc249d6056f528c2c7ccefc3763b777b082bca726b35126ede3aac894078429931c513c7461f51b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000645a92961374f7c96bf41d4271954ae939bd2b3e07e655e936bfd7b34fd26df29aad00fd3bf11bb0e68c9048ffdf612000000000000000000000000000000000dcdbe596006772dffe0363d79f49597b6c1fcfa433e6ccd399a2043271dce6c1d3b26cb6bc1b7ad87ea3aad232cc9e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176d00b1108d2c0bf814bd25d2f1208fcf704c1bd9fa302c235b08fd3be0a73af960957d27101a0a9cc3e62002e595c90000000000000000000000000000000010df2c7cf154caf0d8c401f689dae28b4b2c21d73ee04133503bee9dcb88a8b645cd3e6aa0733742c4572160c688bee51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d734bd0e4b9b588d5b0a6a87c79ebc7cd43e0e7e90ccb4262aee3f92fc99e92f349c3fd0b3f30f1790d09bbdcf0f7a00000000000000000000000000000000070ff4cdddcafba9adae1966209e6346157b32677dcb70f1bad3efe2d119d6c8812cf77f3dda6ee0594629e1c532c8e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2f68cac3b89c938d7a2f19bd9fc2ba53311bcab1631c36d19c7dd0462552ef1bf74cec5bfc5838d9cefe45fcd745e20000000000000000000000000000000018e72b4800497d9e9351f88f50d8ff1a686cca8f2591a6816592d0ce8187fd0ae844638a7392312083382d4410b5a99e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f3a5bda48e0d507677b614b98f2f8b53979a47930a5e4b979321391d044a7561a27ae2cecf5b2ee95ae960ee297bc900000000000000000000000000000000062aa4c6b86c68516f9a178761b918b3bfeada8b1d8c48f5dee8058c91c1d17c06dedb6bfff463361a92f79a37448a5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051c0061acc7d4223a1510f33459041726d6997571fcae41250989ac7bcfa790b49fdb3cb78e73d56719423d18760eb70000000000000000000000000000000012244e53e33d59856e3b67600db0c63a8d3948a8d31fdc98bec32e5ae7f0b00516ce7effce4ff686b0776b5dcc6a29751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d29f0db0845d9181ddbcfd45fb8229fb812d69e131de33ee3083a6c8199ed618ea29705a4aa860cfbd602dce349eb70000000000000000000000000000000010bc8a7c3eb7267e17dd7277595449fdb7d6357b2d8b1e5c87140b5a9944cde3bced65db1708db67135398d3fbf16ced1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001293d1df5c00da7c245bfba82d0325a11d9e987151cb789f4a31421b053c1768b38c56d510ed65b446c22285833627d2000000000000000000000000000000000d5d0220f7d9ecb1f25eaf14829ae4e67c5f975da95781280fb8d2e8b169af2ec1c431fdcac98af15496cc993bdd122f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002816fad0f46a5bd3d8f3f6efee2aa199e8df44eec89928bfb5d2bd120cd26d5eb83c007c9f0b9819cdb95bb69849bb400000000000000000000000000000000079c91fa657943be028d103bb0306bf2ddb248ad7491266f23a2a5a91efbc39433d6d0be5f0d00616248e110f20fd4401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d907672dd066ff630d1190a35e3a868b85b861846bfd315ff120bcde4f0b299c1ce26ec0dba8f8290e4a4b667a85670000000000000000000000000000000008163bde37562f7f8d288812e2caae49ca9855f1bfe462cb80fb70bb6ebd6d2a80d3923bba8f4aaf1e05ea7412667a801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d43a8285c4968a1842e7bd6b3e075fac7a78198915244cd080432705305da10c0b5787bb382028bf9b0918088371d7000000000000000000000000000000001097dbc47ba22944bcb153311cc5affffcf877dc154a764388968cef8de2f39076900225a801302a63b986a4abf41c381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0244bf3dfb9ef5902da6038cda9afa6a2033fa8bdb702a9639eff89075d7591f472def2ba622b328470d28197895f100000000000000000000000000000000111e150ddb83a27f9cea3633e35ee90ca0b1ccb8a2c14c01e527ad419c05ac438a6286d94d8f3c07aef7cc640708a58d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e74c8fb2bc3cbf40f9169e21866fb7490cced691814d830b3a4350c2b53b1deeb5e87e8ea12ff6be263310eeb13274a00000000000000000000000000000000190d5831d2c33bffaf7534a2367b512b2669b671ea5afef7b1c3a7dfdfc6bb53fae01fc5f17c476813094e4d6ea1a1041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000008b9a6d752053eb6de5d4ff58970bba52434cec632207fa534ae0f0029a15982afc805b9421a4c610f163811312f0afb0000000000000000000000000000000017dd2c343fe248bf8d97a1b5ec09bde9e92ea63c24bec6a9453d041099adde402a6ddf798ecb8ea5fb9a962a1575eef0", "Name": "g1msm-256-jwasinger", - "Gas": 534528, + "Gas": 1594368, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000187ce84998b854802f88ad4173c436c43970ef8de0065a10fb93036a7b203ba751ced055bba354b63d53d676e47338a00000000000000000000000000000000010b272ac018b886988ef4fd5f835eae94e8cd1cd7fb7a1229f60a2ac25c9612ec73354a3b0aef8b56ee011339b8934a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195ad1965afb993862c149cfd70b3e21253cd38d831867750c7f3cf59dc4f0776d43ae3adfc3fbb7cf72aae22684fb84000000000000000000000000000000000e0502529af1e4b5f8ddf4ec0bcdd0c1f0ce6909634bd3075dfa9bb057756f2644354df49eb23f99905becda751c5d241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e554267b1fd3605c0e3250193d91024ed8face3f03a3d52676ac948af6cfdda5aa946fd6bc621b5173e4fc0b6ccd7640000000000000000000000000000000019f966a24b8339d3cc80588e423408e903ed83fa804777dcf464aa582ccb6cb384aff837567768353a3ebdddcf959de51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c045b02230677a23025a7c1da892cc80177735b33aea4047f6464be3d030edf27e30d2a3f51b8f77d5ad046c7fac700000000000000000000000000000000001e34ced0cf1f7393bc4749f085ea25eb786bd20f774049eccfb571ad06f3f1fbe99bce0a45842646e82afd1d8d816e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120d885048d8a308ee42d6f6393eaa63554d28a4ef9b33335b475db26d8257df0edddbb933117bba03c9cef836c6d8c900000000000000000000000000000000193a9b9aef41274b9b7098e52702f1e7697112697ac07615c0ef44a91748703f8993eb472ecddf8f79dc0addaed2e6931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001586e2cd55ca73dd3f4f7f2758b2c19bf42b05edaa03f3f9147c2b46731c157dcfa8e164869bc6762e4feb5385edbc450000000000000000000000000000000010b3086c347c86c01c8812c066b77c8ffd89e5537737d800b55f17c795512db134e5e1f2c1205285e8467df183c7cded1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001581b16583f0066af82aa49375eef64f82a72fa43a0f129a1f62adeb9ddc44535263120a5cfd57edb58bd394e45ab32e000000000000000000000000000000000bb99e4c6a1d01f700105a0e6d2bae9d81191ee7a3f784dfe32ee632af0f314719676e96cc52037e6de800b2380401011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001161a52455bd3b7fa5e43a574f8dc8b9b5bf7fb684d6dc92b81b73aef325fff67fc79911522018ade6cfc10fde5cb59400000000000000000000000000000000063f97ac26ed3060035d89d9a59e0c1091af88b9ff599a1e0323567a863ed4c3148cfc5969f3689d76bfee26895031b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000641a852118cf0a6a05a78463786292daab40116c798b1447131b6713bbb4088ba6a5e01969a689230d8a138d0a05b190000000000000000000000000000000004578810e6099aa9eb274fbff7701273836303fc5ee5e374aa4c3dfba23a349eacbe07b6245ea9853327b6cf7ba0ef1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102847f66d4c2e8690e282ab10b55a8a4dfe0f121b4e157664c83bf45276532798b861049e8901a813c4d9b0d31386f6000000000000000000000000000000000e7cad0243743a13018f0bc944d31edf6f8d7366ce72d0ce60711bcb3102d77b528959120899f8bd83e727948bdfc0351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b2c872a0c874d8e66cb5eaffd36a38d6a7768f96526132939a85da4b428cb887f62daf58c7cac0f4406d1d8a995e560000000000000000000000000000000005eb0768c8127ac70f5f7a9fd30bb0b5f8082c4b20a37d5133666b70673b9e74994f29f9a2eea1e6d9f17555563b95231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d756fb34a2764696f703388f6a7aa59d02a5f36958fd1e0b06498811234532e24b93f8c17b2dc2eb48d0b7c41deee0000000000000000000000000000000011c6d08c56a82cc263b5b9018a3929021b7a5fa3fc9dbef58a02550e32594394644829330b6cc1ecf0498b21a519d2291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175c7726054358855fdb12c972ee512657a0702a78f032868958d81545a32372c111436d887f3c445347b616011429e4000000000000000000000000000000000a4ccb54601b7ab6167406924716d5f00d8a57206bc8ecf58fa879ac6e162e6aaf8822fc6d66f6fddc74f207c0b273801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e9de7a193e44172178d6e47008f51ba2452a24d6c19ad436faefc0d39cccc1f9625d3d5c76ee2ff068e72411333a44000000000000000000000000000000000d4df9060e36c437af11f37f35e967486abf67662342909172b350198681e86c6ab296d4e5e9edbf9107f413d3be77501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001056b2709578723639db0109371f4821af1f8520163892e5f1d7e365749d4f3ccde6cf214debb0d6e87270d8adea2d8e000000000000000000000000000000000784bd7cec07e59e07441b96000b72da4f5e596a6f38450835354d55ae56c952f0ad441241de05fb643c13bfc8f5f5a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013a3964d2770792ff55c8a5d0b72ede30853e50801b45aa9b74c83feef7ee388a8a41132c34d383aade574bc48980810000000000000000000000000000000007c4328f2baf080ef97421d89a39f1f1ec08d5d7f644f3abf64d057ee75956796c5ff21ba2da7735bc2f69d756ce881f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e67e08559a66ac77cdc2b4b205a51170b79405762a33adc9da0c05e1ae9f501f627be547ad19fc2a42a5f1d6b2b413000000000000000000000000000000000a171d6f2f15cd97ee575ca2864a0ea1457299745a6ef37d84e08c61a713a33e4adef886bdbf5ac1f8407265b2d913ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001605a9f674d1e5716a47b0a27859fcd4321705d305c5f972ded1a3b6b35d675cfb500d9fe6d58f1321050dadb84e77d600000000000000000000000000000000068ae969912b75a840a0bb553a502b7a0b655f8ea1134217fbe4e5d2114df44f2e7c97887525cb73ef01ab3c59972e901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a141218ef8d853155fd994333f8495469a7b4c5e3eb7360f7b7fd0a1d90e2146c94ed32f4e528bf60f1c83482d734200000000000000000000000000000000034894c3e9e45d1e213c0ade99f2738688dfc7eea763dc9904c4d2003d07273c590c38ac51b6285300335253449e29941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e15285c31e5e54f0a46562005007027bb38066001d2f00ec0015f9da149a477929e40a4988d8f370352b8ee58f3b17000000000000000000000000000000000488a996bc590e150f8a3a78a051a6cdec91a9f96122988c53e7d20cbf2abf38765889256b362fdc663b71ca1f6c3fe21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178dd54cb644b36ee8808e28325334f0b9b8788c8f5127ef17b3bb71435882f8a35c6aa852492421fd5526b70f4399f900000000000000000000000000000000102980f257a2493a1657104f6f32e14a1e83083def406bc31e1781ca28a41d83e4efab88a3017e655c0fd1d2a28c6b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a7550ac358e93dd0758d1e08d9893a126a294a0b28e83c7349d3e5987e7c88936251109ca01cf8aa9c641dd890d450000000000000000000000000000000000e588452a3dfeb04cc361cdc2b71e3197d264b681c7cfd4aed83f4fdde83032b94862abe464d82e8ccaa99f5cd18bba01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001725ccf063832c4be0eaea56952ae38a86d1054889ebd870e1c7b5eb49556931310b63938712fd3c95b55d585956b59000000000000000000000000000000001153698ed6d6e5afca492fa1fd9f35f00b5868ed9fdbec1368c303583e4e3927feb52a6f842c00e935f37f73e1373f571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dbb8bb33a641073dbd96fb2f0986ab86d78b5a3f003c241556cd50f157a6700c94a731ce02cf3dc9661c5c9d2a289400000000000000000000000000000000158fdc083244605ac4816fb042d957071eca9ac8055c8c788436bd7c1b1d63a486fbb830f99f964d31a7199071087aa21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000328e58e92e5639e5f1e5b6f252cc8e9543c4fb483cb1457225c0e870c125ff6f5ea76f3f1b908a1a258cffb59fb36d800000000000000000000000000000000042df1dc419c0e4804f7154e64eda8d2c6e59d33df473ee8efc0a28f97bea6add7de509386f50250fe0608176f4bff351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7170e4232dcd331ca554cb3ab76b77cc9fc168c14232ed3d55a87a9051ba62e83ed467ec2326cf5c8f622ca5d769c40000000000000000000000000000000004fceefa8dcc518d02531162876b6176751e41be1d157e552ec6ad96d63a3d6f8c2bb9d090d30449df926d15db900d581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d67c5391f1e8cacfa074c0df5343ca99027272ae90bec85eff0ad5cdc254df8736f4f882d0ef9cd0a9139a7220c5ef000000000000000000000000000000000a0d50a8688a5c48bea149d2429d327d8ff974ef8fe9018d3ef76c6bef71e4186f1e5f184a956b6be76dafa868161f861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6211f83d0e73f321b9d7996318a452e56df0c3ea9d2b248e0376526f46c5e4c3a30b014e916b3d5c0e92f002e3b7e500000000000000000000000000000000088d117836cb94cb468ceb40e2a31709a25b46e7fff6d065ddb51adf9339fcbc3d8cc046a8847029a40cc08e6a1e58761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e7b33464590ce097932c739177fa679085f1324c993f5d15d4eb913615ac5079457b53a32fc5710cf0f04573c2ebac0000000000000000000000000000000009d86a4905d01b09118dafeb79ee65b3ef30525296c587e48abacc4cfce7901926fe6335f5881c41ca0341e6eef8a6761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7cf3fc44440b4976f5d264fef4f50cb3e79dc8df90a006d0e3ea91bb547ea19ea43ee24a06d27366eaea851ce2dcd4000000000000000000000000000000000049aff14e870c1d28663bfb416900d335f1d58a62faf6c35bedc4677946e1f7ac74eb4f2780d6200674ca73ed9ec64a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c2ce9433cb42dcf70d2c99edd97e0702afab3349e91255d3e7e7f1b71085ff7ac422a140d43083eadc71e8b31d2fa100000000000000000000000000000000041b87b4d6fc420a120273a5762ef25fd38d8c9014efad359af8c363cf0eff959b3adbabe1e26de0537c9a56e30cbd831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002100fa192aea9b42d0ee1fbf06ea43564f96af80ea70b14dc908a2e323cab7247385ea99e801192a2a192136f5f18d20000000000000000000000000000000019a11c656dfcb9f0bcebf9e37ed7e40d1235a89dea2cd7ec4e9db34c6ad92af7e7b0e82759dd88c9bdfe4ea8d0c1e4a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c6cbee9a045595d488d6d7ada13324e350391c5f7a0b9b7e076e34eeda306e77bbc7c7c26e82eea928293eecbc11a0000000000000000000000000000000001307ec99dc693d57633dc04929db287fa7b90ceebadd28ac4ccad539e97f462562fcda97d36496bf5849e1acd3ad242b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e1d7848271fca7d769adf3d2395a18e00f08c7cd68b38d02907804609200a2327f38afad57dd824667c51d8de83bb3000000000000000000000000000000000ab958637abff351b982c4110abd717226e4c105b046d61ae84d44eb3634ef29c226d5bf5baafce314981de6bb90526c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000171ef222bd35366a7e3338b270c660e614927b23edfca94188690ad6194afef8e27909e9c2c838375258177efb3aa0b0000000000000000000000000000000018c16ccabbaef85432ca28290773c80dd92455c33e5ea9a62ae450364f25e083c444a31a18d113877971e18b9a99a6371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f6f398867244467c7786dc4ac5d464a31d3787b41e88aa1a419d10acd58277208b4b0d3545490b9c2d713a6cac27c20000000000000000000000000000000017ad1eefc1ac1bf9e0c54a14ab2e14333bd325be2447c0e6ed48fb733019f6c4a8e5f59ffe8768e977489280cd2715e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea993fec56b53ed68f3b61a2278d0f4f3bb6104352efa3df09a6a55991000c6e66ae3fe4b69db84f938f33b59f541f6000000000000000000000000000000000737a52e04dba5fabeac7193d52dd5857c84115581a7db764ea2e78e79fa27f677d3032a05c3045613e3dc7d418174251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090048c31e9e06ce14757b304d3b55e63d19c08dcf06616558eba80419051f23ef82a8ef9e04e109b93305a19a12f2a20000000000000000000000000000000004270beea1b5daa5b6adbe3b3db34d6d673f65789cca2ed0bca5eae56d90ab7d1a1c45ef9e00ce7a866d5fdc71a23cc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e2ba4ae3f07ac233518eac4d9c583cdc3688cb5c9822725dc0e42f88c948404d7e76c37f9ea6537d5c226d3b8db99a0000000000000000000000000000000017cd40cf09067078aadeb41e11fdaab3c7e7f2229eb8f51cdae932f45865f14217988208295fac7491576f00d7f59c7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b381cae23f27665dee91932c327b4c38a439ed08f7a2d4007bff04edf72b7e9617c4427c2b1ccdb01a43294879ef04500000000000000000000000000000000073f42604df8a5757667f534cae4e7f44f853c94f52ea72847be82af09b23af5dfac373577c4d21a095b9b13862497411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018634df6012923147b446c084718d355b329f4a43f8ec2ad46b4fc14bf960679de85a2aa5347e806dcb1cbd44490310a000000000000000000000000000000000640a547b2098b0812dd3ad883eb3b9c53198b487b68594007e084ac70c716229aa53bc8c37b39e96998a0e0cd595c1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097df85fc903cd4288c6b682d581789e386fd74addc36fceb3cdb184536b6c2bf8c01c73aef75baaafe776f6b98bd6890000000000000000000000000000000011069db7f6c46d8ca62b1f67280c3c7afc5bf64dab5292843d8235dfb47b3377b43ba46f8c575086a6b95f730da7487b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168ea9eb33c2d394e8b68a93d01e9c58bc3c3079540363a9a3a7531e5c2ff57889236c1daf71930d0d19f4e89763f73800000000000000000000000000000000044881325d5bc0e981781cc92613ddcdd066e7fd5471d1111c30f6a3754185cc20b50744e276da2d834c5dbaf152908c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3f32651782acbfd8e62ee758cc9d4407428e2176bafccd951fb0cb21323d0fa6a7c8753ba3ca136efdf12e080bc6fe00000000000000000000000000000000037c66bc55dcdf376086e2d2d1499210ffceaf3c73eac4fa98d46e99291319d0903b386fc6047d5456d8df089cf15dae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a67b20c5b23e1597a5a1aed5f20523aac6646f80f34b22f5137ba16c88f7194ec6ab3a87d6dcf1aa466778ac7af6bc0000000000000000000000000000000007b5f3e65cd42fef6db9a6969f296f931f83e10912a459377513429f1bf32aa19861dd98e0ebc3ef92396392093fc44f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000153d9bd9b5658cd072674eff31a0916f3b9d1eba2db71f59035ea1b5013d87da5588e09cb4ef129b5b4ee03e84176ee0000000000000000000000000000000010ca3c087b3a78f55e3aa476d9879fbf4cddad4290716984aaf3efaa15837712f2855d825f69a93e5a33b62c8c77baf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c8f72f625afa983ae57929ae0fe74a668719c7e10aeecbbc11137437359a5a0bbb72c3f6dd6b0ea09717d2ac1f3eaf00000000000000000000000000000000017fbf8ca15319ca19bfa4a4e560d9371ba7a5b7680e9fda75e2dcd4e5e87380865a6662f231ce194c6cf3dae38215371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c2f802fcb22774399178729e803da4c26c5a403cd7bb9d40c4bf9699ce55bf62325827e506525dd0fa46e5dd70376200000000000000000000000000000000144ec492ad03b62baab04dfe1f5ba6a30a40ab91947517c1f7fb3eb672abdeee1484e318c44ecc86f0e97f6ef5049c3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bfc52aba0aae0cf6c114e69777da40606433b54f1a1db93cda6c656d8ea7586dedfced3a19d4b1f16030fb6d0024490000000000000000000000000000000011f9a04ed4386f64172db388565f8fcc3bb24c1510a629e4866951453d595e4c15de15ee22c583502c87e62e1c4a27631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f629b8d2246854ac5247f6b362e2423dfd04aade69d4d404ef11ddcc631e8e155a9d98f91b2aefd01e8e867fb1e4ab000000000000000000000000000000000c8cfbbfe2d6b43166666746d174d9c15dc8c59f3877d6667642ea7e53a366eb099ccbefaf63662ca09f82719f3e57aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121295886baee2bf7757a1ae44542700a635074461cb43b9f247b8883adb1dd4257b8c507682c7d37089b07f460d65a80000000000000000000000000000000003284d6070f7b568f85beeba1f7ace3707856796f4441050ea2daa2fbaccf3bc963f07aafbfe08e858c2ee861c442c021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b97ae0cc4e755f7c13c398242f0e835819be8cdecd8010731ecfd3dd8b6d7d0af1302889a9e25479ece8c68344ba01b0000000000000000000000000000000011afc7d51d8e91628be8d8dfd2af4e6e5e72e5f8da5b289e7a63415e8a98dfe5cb8125b8214f1bda68e12a9b7d43ffc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146f48c6e54923484e6314dd7b5116a208e0f7129a8bbae36427d2e7949246b4e2dcab61f2e9ae1a2535c64974ee0270000000000000000000000000000000000d162440369cdb5b1159eaa4012d2e00f4a0f06b9bf2e4ffb7ba97ffeb294340561dec66b1abfe36f895c38f41361f3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b84c410178ba1e4c4623b5c0f60fa0e75e041867dcea95d7e3b484c2bdff5ee2a1cc471b222868332b1fd23d3e9749000000000000000000000000000000000f942436ddd1747f3102c5ea5152ae2e5430c8ed5debff266d6a90c4dc175e051d9d562406e6ea2217a6959e20c22de51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba526fa92809b114e64fa99314b8181cce9919566b86e95d4833495bb0815b1c444d2a1dd5a77ce1bf86b9b61d936f200000000000000000000000000000000046938538113103942056a627a508c33ba201c3a7a6a57ee69005b26c19da8add6df00eada5b75bff472760b7b89552e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015313865333b896364ec7ca0ced1fe99c52cbed33f93915f3c362d71bb13b8ff1c32b84bc25da68a21bfdf63d9556dd000000000000000000000000000000001703aa367cdfd16e4cf3d117c99222f19f37f59822caf1c97df52d5b813a6a9f6ac58a67a5e35356121dace6d2a7fc761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ef0ff059ebc749971114f4bd42f3ad760fb49e45b4691aeef816dbef5f37275260d50e245754750ac16cec8cca45dc0000000000000000000000000000000007963a2e356324a1b46d8bec70642d525dc0a97e6b7830640fbf1a8954291da4a9f5d3bd40fec971c87754369dfa5f0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148c26d5e36ecbf6c961d9c3c84c28c9cdc7545f98e3733180bbc786f3c5cbec1942ba06fecdf9219ffe029d79eef69300000000000000000000000000000000114c67c2d34ba9b9d283fb9db8ca40abf3c0183de46ce17bd2217adbe13baa245e1855a5eabecf2493fb744e1392c80d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000661e1b7916472f79acc694a370b7931f6b6fd13535327d6e757d7ed9bc6255e7244bdf28844db674b989f33f8841280000000000000000000000000000000008c8af13339e01c69275aa77fd84f0735dcb0de73fc33967edae819484f3208726acc4b4a9f31b9829ee8f0c8193b1881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2fa1377b58bb5669c93d4d45c23c3538b55c2d9c270dd899aaa0d7a57da003973d654eb173f92ad07f3facf27c4ac10000000000000000000000000000000009a078170c1625429ef432a1f44173fb2f5dc72f510326ab65ff1bb66b07b3eaf717488e2b2b090387df471e7b9db4df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b6c6021a9832d5936a120895f2761614ec31fdd148974d4eb60309dce03670e9468dc56100db920d036c1d5751a5080000000000000000000000000000000001f8ef08d930ad076e92bc4fdab39dabf566d07a6aa0aa70d66a805ae581b24f7f3d7e39e1ee920c3028da110f03213d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007de9befd46cf1ad2849c07238dd7437eacd71d8df36b1f1241b75a17f4d9872b746804814fe10a6f18501a8a4f8cd44000000000000000000000000000000000a4375fa31b0f4c75c73edcf1864c5859058305e0de915e6da682532d37663085c8fbf92f22148deebc84da53fa241c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d45b05acff40a7d8d74ea5f83af1693534ea7b489a065d0cfc735f2a3ab5ad31930f743d0c48556cb3cffc4a6b891190000000000000000000000000000000000ceabc819d92aef6a63c3ee6c50f1f988dee1e5de0b17efac5a1285c5aed0342d9aa89fa641df499af64655ac5861151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120799e4b1f8ddba887942683f441317874515e9fe722bdf5b575fcadf0687eb5ab1c333720841cc6b00a2b4b56ff560000000000000000000000000000000001959e728c8719aab9c9b519033d35f173e904109b7a73996ea4f8a46c3e5834026c5f6c82e3bc39215b6154e61e4176e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c309913cc8fa478f7911cc3ce4b915fd2ac29c2cf0d53cfe00bd04ddd8012e5c73bdebb8081b702c6c2a44e2b7dd1000000000000000000000000000000000e8b7e4d5601690f91a20c1d47ff9f08855944040c54e8b5986ce8fc3c3e53b955e0615e2c2fe04472bcd552ff2e01861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d28c9f1ffab3973a89100405d697c06f98d51d8a91f99415d5690069abeb912a1b7f9429e39cc3198d9d37b0e1c073700000000000000000000000000000000054a4d33d8c0393f98011eb94231f6883054c2b8b702b56d128218a555d0cf3dfb128d0508a22b65017f818d686077a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036af704eef88757e451b0cf390ba0186a961aee2aea7808172cd516e0ea1a929a8a4d591a98bf548ec005f00299f1130000000000000000000000000000000019479829047c50ca69a4b33edc23de1d81c9a98ac2817069b1d3f0d618b47692f580237ba88c5555bc37276739a4d2821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f16db8311ca90b20189e7e437bd3c883e63ee584fb3e747b34c4189355287421dddf4d8c9ab979bd50db29ffd3349f0000000000000000000000000000000018d5c39c167a331d583e16c713761e7f8fa0fb495c7f4e3a2eeb10e949c20b123854f9e31df5af510ef1fd8c058fdf2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d43d59d34e97547ab696eed1b99371000d3958cd088cdc4f954c420527d51351efebc7e680624494c4cae548664d735000000000000000000000000000000000a083f701851df77eb70bc05dfae6378d34a8cc466aeefc208b45fabfc192a32d14af9422f93bc8f45321f3f3a11755c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b5ff1022458ded52797f632120e4f25831ece08c68a5b2e4ed600d5ae9ffa0f187eedc442a0889620733ada2835de7000000000000000000000000000000001963c7f98bd579e5c822f7bb3adc50440f1c2f35275beac62e4900bdf918d1eecb2d3de326c5f4727373341eabeb70511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7ce068d7e92761743d7d2ef0b0209be2e6af909ab5cb31b00e5051cef08bdebd3703c86d9ddd56f9e4a0550d7f90db0000000000000000000000000000000014f2721e413eec9f9ee73554b1f11c310aefe359c77d792768e1a022b07f3bfd8f0b0d72c73c9480a03535f272b2129b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001691bd31f05952aca41c7c4288d1fa9becafb7dd97195a36412199c4fff9c52581df526ea25a28d897d413383d5becfb000000000000000000000000000000000e8ab7bd4311ab78e76f5d7e5e504cdf6e3d7fa0b31e693bcf2339c406738c553adacca21676b484deaa489d1a47e57d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ef81c5ffcfffb8126b46d73e03a79c2d977f18215f3af5b0e1711c16e6e98a48363024554b5220044591983eb0c4bf0000000000000000000000000000000007566f2197ba1f80150d41b4d6154a71bb93016d5d4f14c3d16dedc5c50e425938e472c16379336a9217c676a3448c071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165c9fb380549174c569d0f8cbedd333d873d839fb062545d0fe604272f88bdd0e16a65c9fde4e029048cc041840b96800000000000000000000000000000000016f37e931d1f8ccbacb0a7ef9644a32df6c79d980a7f824502cdccc8ba189f0606ba6f691aa2bec3ab600afd89559051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b28e11fc482195d636514108105c492bd557ca984cc4a02b152a8e4e9d92b338d255f8b4142792b43daf68cad78f7b4000000000000000000000000000000000c571f3828d50183452ed29ac99006e209c99c3ca369d436542493c539e92507d1b356634c14a23e7ae61040118018f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001172349944a78777e7ec4f3114aebfe0a6be8b47e136c266539ea9ac83d4554d6465019e8201d6906900d6add7e1b9a400000000000000000000000000000000003e4042ac4353e9100029ae784b1e2af5907f4b80972d37b193d4b8f5f745684492a2f8a8ee310283bf4efb0a4c76c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061158decdb4c556c7339d525f27f9b114078833292d1d829680464e88a0d5b08e75375ed29a8d7cac3c827a24f93055000000000000000000000000000000001731ab9fc78e98371a3eb9618c755bf2e74e96c12e64626b551005d0f80a85bd2d0aa8836ece65df010151530871d8861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd41da79f6a65fa52d32d0477b308757a08d1cfc71549ea7c89af17c75fd1bac1d37b051f10d9b21e93ae1f1382dbd7000000000000000000000000000000001110428ee61a888939d6dc767170e84e91e5adf4ff76f4b925925015d2f12b1720378417d81c0576010d7dd494e736371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000848e4fae0756dc12386104c599bdf60e795867798e3ed36b6c46b3eb92bcf7aeedf66438e037dcca22dc2e42b304e3c0000000000000000000000000000000012d635e6936a60a66585d4bd9fbbbeafa024a1897431d4957a35a912e2558b0162538cf8f012c152ffac758f8b691ea21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf2e0c027acd16e14c66692a0c264682cd0e59ce492f0d76b3e8b32a381ac1aca628c9efb6a76275d0a5b909ab4fdc00000000000000000000000000000000190bf8ce0cb0c2a0b2e4fc153587087fa8a36f2416dd1a070d6aa374f185d82adcc5b66f66eebf359596da234aea7e251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca28684198a8b3228d9c95cecef7b8c9a741cff807fce559644a7fb2ea41b4a85447fb24420fc31d0127d95a97b8d87000000000000000000000000000000000e02fa43d5db249d3f764a621d40fd4fec3daa9100a51c48c3066ec1f3d8102df994169e66f15326766e521dfbbe8e211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3623467b72ed7a387633886b1d7989df973d15c68748828eb8325c8cf1e4eee75f0c57ae36d9909e8036f5dfe2e5e500000000000000000000000000000000117389d123cbb614c27b503458de53fe51daae7381f63aeb04708fc8bef0d30787d380048d97f49c2207f98fc87f83df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015809e7720f15fcbff51ed9e1e808e1d982b9a931e79d4417f03a3330dd64865c9b0bcfc5a5211eb4d6af33b2be9960f00000000000000000000000000000000159cfe3711c51b53c2c53e1dace3587a4ad341b92a5ace2d12e912e1dabc73c41ef1a6e766d67b53907476eec281db4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b8d266b3054059a835d162c69fa93b448eb471e1f1a0132f534fb5e2acdc5319209d54f400dd7b44109909003e200400000000000000000000000000000000174790f3b0b36afb6abd8b03c150ecc8aeaa9ace4d676b82c4d2e5c8279b6b0649d9dfb75990e84bc3864e0bdec660301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49e6661c53f4be8c4c8d23a4accb54bc7ba31eb8366713cb7b2e04ecf8d5b4fa570a591139425337eca656f68a57bc00000000000000000000000000000000085a90a20537be92aa338bd96bbc8a2dcb625004f6fdd1d2ff97ede587be843fc5aeca3dba036ecb9d093819b0b99f501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040505a517e14e7f14d1e2925299ed1ff0541328fba22441aa822879e947a2a8107537a90ee3fc51758e2417f66cf15500000000000000000000000000000000084c14d86e972a21448864aa109f32c85529c7a2c3cf237d94147fc922f2c3f557df05d21a5350229ad9ad9a5b3a53ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dcd08f39a6447c27df658e3ff81ee949b0291cc791853a0a6561ef02a1d654f775dd908fd3bdef520492d9c35d3b0800000000000000000000000000000000135d9b1b8a86b759169cfc2703be8e11568e3212ebabe4b1cfc3ea7eb60915de8cd2b27958899d814479a0252e5706581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bd0d71f9aa7c0d77bb7791bf3af08be3cba4758e059a471ce5b11a3a7cba71b38614692a499f7524ab8bed031e5f4a0000000000000000000000000000000007f12736be3a4220d2600f2aad470e5fcb925148e356316d5040bc61eab7fbe5e05839292ca7f973c409545ae6045b361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016728a052de13a036742bccdb2be7171dcf6e820bc566ba7d3168768e49d0749e536d49676bf548105ebfb1416db84c90000000000000000000000000000000011146cbcdc9b1772b7d4ebe3091a3c98e620ed51ee1d296ba116f7e7d5c864d37c8eda23f0a7fe5972060cff73f3bb901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d8faee7092c5d9217b6926f46b70ef18d9058f0cf3ec93f915922f8f6f6dc7a87524ac76d8540aefc33e71dec493cc000000000000000000000000000000000399784e638cb987cad3bf60b7b7c0d5c0650f94cddf9229b97f385c9270804b47f9856a581bfa100f911a02e87882621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b7fdbd91a9bf084cdd80dc80574fee83e788dad84049fbecf0ab0930e6fd3d2a9fb60e10640436a2df594f9a387458000000000000000000000000000000000e009c7a903d267feb659ccd5d0a2e71aa8c98e668c249eeebb4146f8cd877dc11621b609382d9afeb6e3388cd76db701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8e38fb80aea5e293f3c2de00a002f113d1f4d756f39167951d5160beeb7be34088eae7018b02f9b96fb16613e272bc000000000000000000000000000000001554b36101a403e1c465b2123c9fa80997243b33cb7b0b678d6f578a55a2cb45e94326087c53c6dfc6af9f98d07ffc041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d701748f6dd4710c931efc26ab797bdcc32aaed25cfba60052fb9f01a1663b98592f35a05c6ab67073c73fdd4d3d54000000000000000000000000000000000bde0cbf90b70c9f1e7b9acb4cefba137681e8cc6158dcb51064adaf5af32803f59468b0ffe24e0200c8ba1086539ad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a46d294852c301a9c4032fae4630cdf006538467d9789f237527d836c4d41fe98f5f42f1128bbbbc1dd39d5aaed15f000000000000000000000000000000001880b395967f991d7e182a9c110d2b507c92635f5ff7225de8932492e2bd9f311cd9ebb9fec26118bb77c31ee59afe671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cffa994a209df15a27014ca485ecfa96d7208187707d8a64e6bde1059005d957fdb5a6b43ed9a07d83cc730d42d60c00000000000000000000000000000000176a5f0c4b33931db5a3967886f14e2a0f98d99089c21933cca4e0c58b4c4b9b7ce56ed1cf157e34e149311e9d0f5ba91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a178b204d5a16f860fff3f1486ce3c64478fe7d3e2ed617de627f1c542df555ca2e5c2172f9ca525142bc96d8397a70000000000000000000000000000000000b1888dbb2c1aaa69425ecb6e7da76913f3596103c6081694da24bb35c5c372265783225635a55a9a8889aa69dc18651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001032a6cf6330fb308fa9a50d9d57f20eede8d9e9dfb7bd101611d25cc58d69dc43b15552126a77bb535d7941c4f598bf0000000000000000000000000000000014dcbcf503ccfa3f11c4b49f4906915a075c38e74603129b9b7e13a4cb5d61e188f3a2059fe2ca3ec93846631e598a421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d26ac26b584533005d88f8daa715dc635823bf5f4337e2f1b1b3c1b108150d4855c36bce98fd9ab26a477b0d92a464000000000000000000000000000000001717be1d7d622643c1a5f55fe113a8624f23874f8d627d75c27f9619b2bb7e6114017b9657e799eb9b8e33e6b1a575851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122fd6942675a9b5ca6b653a0d72508af61c2e1cef60a84ec4b74589c8f1845e640855eff3a860bb51de52690fc9f6f7000000000000000000000000000000001925a16fc58cb484568900df04a38002687ad764a9b0cc45f98e70ab50c6047fff2efe1e5f79bf150d7f404bea4722df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001954e4a93db320ee261d17764ee80d1b6e2364532bcb5fe6ec2c8413b08b41d15061b3d83752dd8a35391ee98add79810000000000000000000000000000000013b54a3476068070d20f9bdc4f22177fdfa3aeef0479cabb1f67911970c4203f196d5459a5ae4642bff23b3d12bb403e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000989ec55503cfb70cf1469a0e0211c06444bf21d0676cd6d0e1d471c105e75191215f447227e354c66812bd550273d78000000000000000000000000000000000fdc9e514828ac56a44e710d98a5076dd481293ff5122d1cfd7e542143b691352c1120043df13d3333db42412ae162651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095c4494dfa724832a953ace7de099875890b60e560add9c425317f5e8c08f46d13282918c3a3088432b861002c84bb20000000000000000000000000000000011bf5919188495b8b82721f81724893f66a0019207f3d5903074b8bacda46fa272cb400e14cc185bef4a5bb5a5f3d11a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000508588409e75e8eacb21f6a0929aa89a8751e92c0a0c2810d65c19d49c29408ad2ec7600c482597a0d09ab66126bded000000000000000000000000000000001192f286d4603a3ac2478fa1661753d61c240aeab14b8906d8996094d38d4eacaf936958c1a58b7bd6d1c4a5f211f54b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e1fc0d95f058bdb92cd1950932f9da78dc8a703766ff3bd7fad2f8f5930fb0718953f7c884e1e133e5823f4ea50721000000000000000000000000000000000900f97232b802f0e0ad64ba28b4037aff89c9698e2f283ba87abd0f39788f386a44de47a072ac6398eaee2b518381171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008656dfd42487b616c0d6c1833e94c71bc520535deb5c6bfaad8a12b1cb6288243f00b8b5dfeff090e920155618dcb98000000000000000000000000000000000d920aa0b38b2c316a1bae304bd58f88437c0ac0d83ef2e17f229cce76e452646ef89b79204d8d3d3d1d38c7383a5bde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cd18015b13c87b51e87b5f2feb6ac9b263104880f8c2c1dd6664d7ecb822763c1a332fa52dbeb0f4195bb717db1ae700000000000000000000000000000000063899f04ee4f900c1ac3584d13144fb8db23caeb15b88341b0a30ad7a91706bcf993ce098a4f9d2b085ea305f189d381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d28c1edd08dedf740eca2fb8b61bf3e8e6601de10cf2ea3a67ecf6a3af0e63ca7f2ee4809831c2d294ce24baaf25790000000000000000000000000000000013c4c5d5717648810f3c10be05f8ac34bef23292b23aae0bfc11aa12ed1d71fc55f169fd611dc1796e7ef88b2ef328191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeacf66b2786c63ea50cc28de694b096539c4e13dbee2488f1502740bc88cf17872ac6c7fabb78075e05f0c78e13ab900000000000000000000000000000000020d72f67c9e097a516b896d57134424b4b1366a1b43684e066447fb0ff22c61b92f6dfdc113682d690c103653fcc3e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081aed9143c5a0c0ef52269e1188ac11e610853bd616f3aa7a6f534fb77dee8197b4ba9e1fd64587afaf3b8ad5c860a4000000000000000000000000000000000c55be1a246b598dd66c7924342d660fbf84220ae54c8b96c813dad06a81d509daa590a525cde77c456a99c4a62e0fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa3ef7d5fca8ce684b25f448cb57518a3ea69f7bdceb25101d80977f4ca259a7c340b2454f91c38f5a656bd16f21ce0000000000000000000000000000000002b4d4295ae6a1c977fc89df2a8ad4394a0787c361f4f043ae74881766e01e2c4e60306ab0cd19762353517184bba9061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c6347539caba6812f660f7d5c2bf94cbc933f109a78c87d9652733f4038f9f7c12b5ed7abb6c8dcea7762f95c88fd1000000000000000000000000000000000b24dc3e8788231a33fb3a301c4b949ab0058c3fd318911c5c905813561f6ec0df7b24c646dfc3db258c5c1de854027a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009592a70f5adfa7f9d201fd900d82d3c149f7f4f1271bcc8e365c01e956d7c15197f18a5af4ce2167487741791a65ee200000000000000000000000000000000024e2e045d7103555f75efc12969ea12bbd4196b1bfde2395b945d31fbd6a058fb247874291642bf63cd6b7c8910ac6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f475d96a080180909efe6b50a8182027a14870719af86364ccd0c177de5c9a4538b4f348b21ba0661d18a3d9380591000000000000000000000000000000000700ee3f78150fb3b6caaa34397f06733c34991a224ea661ffa131adbeae8e68341900164aa0e3f4e23692b2312437471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d5bdac2e8bc91a39ee1eb4070c8b9b8a421fec28fcfb5052d586e0e3f7da9c4d18ed56bf1524a4c95ccd0df1d46fb100000000000000000000000000000000187f6b2bde9ffe06b71581b5a9219c5adb2e6f68002aa904c0ddfcf4e0bb01b76b2d256190a02bcd672c6a789cee77d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001912cd2aba1a125004291ae2fb334688001d98986bc8c13cf8a425914a96c30f3dfdeed8284d717d54014a017742188300000000000000000000000000000000183069181922f57f55401cfeb5fdbab9c66c8dd9748a90a995275638012f337d2758edb8d404fccd6b7b25d59e9468d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001182e8bbc392645d1f928bb8c27b41afeff62d50455a792ccb403390155ee8500aa97551618a44c7c7799b59be5ddbcf000000000000000000000000000000000d25607f2671c2d67d54ca544f53b24d788cf9b8baf2ade998f3c0da3220a864dbbb8909144764a3a00615c39606e2851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a29d13152b753bff6d91e071c8aee015e1d4fbd2ecc213734355511dddb5bc2b1a2cc39216e574a26ffb69fd8df1f54000000000000000000000000000000000558f91ab90ec9d4b2223daa6922953634099afa363bab7ecb4fcf0d428a0aea1e7698b57657ee221f59c5a0f1a67a5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001194e54f98f875e0f6e3a1471ee6792f82fe0ff719b20d6336eaa56a985b58bb2fd8cd4447a1ef225485a05638c86d170000000000000000000000000000000008f1ef8883a8a5d8afe796d862352136ff1f39ef61e5e51886b1a0ea415d78741fec47ef86643f34a05e907e1d1605431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8e90e5bbc31449fe33804d951e8e8594f31254f19e03b2ddae779cdd0141d6f1e6b1802a5165a260e876ba015039a6000000000000000000000000000000000fbe697a7eb4a06b66c7bcb5cc7ae5990988ab41423008b52782921848e803c86314abf2c5fb154006aac8bbdd42f58a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001231a789e88ceb1842806681e510d8cef71c3ed6e21f7c57405c5b6e3988fce6d8e505c5efda9085db9f31dcd65b388400000000000000000000000000000000013de640a40bb049373f95a74b87e2719b5e729a929e367d945a3ebffb45a5200bc4781fa1b10b9230bdc174e74b38081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000835392f9fa067f5c021af0e2b295540018c0cd35ca3a54f540fe0eb0447aa5028066f10f417e909fdac34a76bdb2fb300000000000000000000000000000000100fffc2e520489323092a81dec2efe3fd855333b89c0e6c078274a9900b3925975b1ed17537fee170fb42b8bac092ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019180eea264e00a5441a2867b7f8c9733bcc573fc484b717039048da8f5cd58a79e90fd68686eb41a662aa522c50690500000000000000000000000000000000083fddcee295291ac17c485ac67b1d5a806c3000f4d8a6bdf9c43c1975662427e7e6522888c8000d7448528d472dba261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001813fc185f88462b7df9219e36eec45e97fe25a3bdddcb2a46f63ff1c02cc02975f39328770fe5de003e4fad71f84f4f000000000000000000000000000000001997b61eb0476f4814496a413b6b79e27651bf050a9d250c1fef7d5ab6316d29e60c6683a9eab4f21626c1977be1ea4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006de1d4e040ed66be9d988affb8f214525d51e7e742a60418915c0964964284df2d80e51b9a465b687735baa6ae7f756000000000000000000000000000000000d42ec5817831aaaf04a30edbbf71dacac2d92fd42e5c1d30fe44b0a1baec632bcdb94ce656eb8ec593ef664e82cb6f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e0e30c443c6213c5910d2ae5711db8ba0afcfb82b26fa5572cbd2479488af2be6808689c696e67fc6f3d4813f6083e00000000000000000000000000000000017ec011161492b402350362af79f20590ee156b400e49356618fa8f5d966d2cb4edea0e9fc0a165c0f242bac86512541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d92d2bc19cf3fa68b8a37ee1ca4a7abc1f4875b9f7d543f345fe3e669c21afc885d18954f50bb516039fa3a62db070f000000000000000000000000000000000b043043f55f48fb977b999418d353f48c578ac855cda969ef85aa3b3788dab84c68599d5ba1ccc1f1f2ef539e71a7ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eff1d79133d08684f1b9df108969e01af7c4206d05a4a60f63196fd18f62500dadf194a45732b84f1948cc505123306000000000000000000000000000000000c3df07e231aedc3ecbcf94c7678ea7e1d20d9a32bc4278b0f98feb863396115bff3708b29e482de889183777915204c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056902aaee517efb3b9b432ca72b9afa5f1b735171f29faf052aafc5f16fc1191caa0ab487f540ce54418a549eaeb45e0000000000000000000000000000000012ade4686e4cd9a176f0a659b1a76da7a06e06fe2f1f58e1d1713063051dc3db81710077a322a0141238177e0a826fd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000962e05107935a415c7de6aa361cccd12beede3cf2c28f4f443b65fb06330d7d8665deeed5617623508565d55b4fd83d000000000000000000000000000000000bd69c524cc5dca834feb945417cfe0b37fc7a769a6597ef9f7c8fee4b8c23c04865dff2cfe99b33f54117fc18ffb5e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000586e3f1060a2970f6218faa8eca725cd2f47b35a9c65019be530a12d785d3dd7017ede774aed700471130f07bb593160000000000000000000000000000000013f63245348078b5e9c2522e8f06e54194a0588e9d0e532f75a362e5c1aecc6e0f925938917741539be9729c8d3415a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125ebfd019f418710a871c74fc0aef0ef732ea4f4f597682b1c5b0c2bb2a1d018c05d3722f5bc78df04a8ee20616e870000000000000000000000000000000000cee157262d216cfc91946526471ddba396e755eefe5c3d4917dd88cb5c304410080253bd0321382ce306b756674e9001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ed62af3ab11d5219643e84c366d47bf0108cfe09d6474cc4fbbbbaa7ba091568429127a1b0a36d9f98c191fe3feb9e000000000000000000000000000000001041eda4a42df7a2dfd7c7460d4fb4ae6ed0fe9a39fcf9a72e03e5469c070ce316197dab24339de0918e3d89bfefc17a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ede3b2d8a3d09b53e446c6bdfad3f431bb58f9b19ef7ba73d83327d36345a9a41f396692406656d90450e2218f60680000000000000000000000000000000016f06ba41d8b8632d36dffb6fb88a98ad03a0c6c12f7886b9f01aea3d2f424124e0ea6af9839a54532e737ddda0ac2f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8f55086dec464b616ab7aa8491d694562e9fb77b469c0e63e057569407e0751f25eb5aad8139c4f69e95e12319d95c0000000000000000000000000000000011fbe80430e5aecd7df7c3569480429216fa07a256ae80d2a5713f47299b19954c139220ed2f86e28dbd6b4fbe3a35351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc4f00e6bacf98f6f9237f351b99ea307fe9adc23b85021f0ae4a31f2a726f1e6a7f9478d616a34027d66f9dda3233c0000000000000000000000000000000009fd5edca2af19b8e3dd0404922d65986af2ca2c2b9976110d7f520582de9703d5ffd7a3beab648f44a166b7c68b0c7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e590ae68e16697edc724f4a2215940450d222cb65046541c7f6d83da33551f13f3db68e9e5eb1fee53068f4fbbb979b0000000000000000000000000000000010e91c9a13fd31f950ba72f98883e3bcc09538678a4fbea63034d525b117560cff911c118219eff6b7767ac001a493ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045275e2a1472b054ac828bf779f331cff064d2e7860bffcef9bd6f07442b44bfd5073a8aea4c87b1cb532c4a644fdc7000000000000000000000000000000000bea98f747139a694722ef5845eb5b1283404ae3885ebcb2d4b502abc12592dfd5ec709c2c1eca054b6996f9f1832b0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001022fd83728aee92ef9e6617083ff851494db7f6685db97fd497180e70fda9475fec7cf25692cc7f4c2efa9e6fcf8a6000000000000000000000000000000000dec85bc6e0c0cd8194aaf49eb994884bf8228d72920ae9dc9dabe61ba1dd743f6447dfeed5ecebeb7ee6a301d6f091d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001560830a49bc8664152ecdb5bc3fc62ad7b80b210e7043bfb59895cc106fbc76e3d99a24983e650e47a8ae43d43f4b290000000000000000000000000000000007fa83a37be767def70dbd7a65d01d1052222f192e14716d0c41533379568a66fbf003947e1fafe83d035d18d5ce6c991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001339d6ae0f32fe11504fd99b4297db2c51938674c9f58c3f569683f17b771df711735a9882e53d8a5b3a6a7ef0dbfee800000000000000000000000000000000071967edb11258d2852cd79c7e2f231b56e3748d42b9145f3f94cf909cf07e638946a851d0e5b9ae57b64133783562ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003805b77492c9e1a2ca329e4168b3036ce1130f58dd2afb94a6cc0aee114bcfd545f587a4241f9563e6e834a3d7d7490000000000000000000000000000000000df3d393b221d99eab98d605c184d653b993841a6f5461c55ad5619984fb21401528362abb343e9fc45a8152aad569381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ff1365558ac7b62ea3cf8959cee9855ae6e9737c495e97a91983cba11f3de74942e56587fd0db41fe9aab3eb05976a000000000000000000000000000000000b10da32d114e554d57692c81a79c7f1aca9d22b33cea6a4f7815a947b5fbe6ff21a14bc5f22bb47b5b138c89237940e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea59c0a602e25f1f9bb3d16ec0f663a232b22580d12726386af51a14e98bbc1d8b5f03584c255d5fa6a74b631ba1a5b000000000000000000000000000000000bf3b55a38e08b43d65d4eaaded4cc56a84ce12101397d35f0f8b22673044af068cb0f88f6a2f4398c02763fee8522231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011dbcac6b6c59dd59a7f9d6c96c9390f7d02b2cdf70b1c94bc376ab255d233c7afb5c4467f413b4890d26811f021576300000000000000000000000000000000104f1e502be45816c22766bae3eca432e84de5a6c0b61353c35ed3969b32f65facaf0b084704bf3030a2e2a458e0f8481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008323909660026ad9abc22dc64ba9ad4b7a33c9cacd214a61244402d0971290dc39785edf65c4288a7b71dd37cd764ce0000000000000000000000000000000002ffb8edeced6150a221cdd9e9a6023715c95f947b77559415fe8231603cb19bc1266ba201c6ce465017082efdc5d0941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dd87b77ac04777e28951c6c81a1eca78a0269e685c7e8b4712c7b2ae819a875261ce59634b567f2370bced488b68190000000000000000000000000000000016583652580d0a3d5066c0ca089ae38669028d778cbb1f53e9c2df2144a10afde8cfcd56b9fe8ee3e943d39a023a97f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a916ee4c064aed3758767e103a0631f89031360ed8d1104eeb6b90dcef90f8b98a2460bf6b219898bc0c57012370d50000000000000000000000000000000018d1e73641e2952354334a3f9d252bf836612c86382ddc190efe837b5cb6ca0082046b24d4eb51a2bc53d4e6f2f578211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c7d04cedab74880e7343b136e84c0f7fd6c12e694d3007a40788d37be17443bdcd49991b3c37ffc0b1c8d1de6ab0470000000000000000000000000000000005c413e4f50bbb1124e56a2cc6ea8bf994b908835e5981fe4c3038c64c1aa62017915a74da9d1d97ee9731409a8f268d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001996d6ef064a9491fcf9f273db107846bd24c11ae20698b39e9db3b58560a0034d22f4bf745f6102a92943bda3767f400000000000000000000000000000000005bf07bdffbc17ece59dc60d3244ade2ce398fe6b1c825b3b9704bc7b2c90f4df6b36b73cf7959e6727dd118597690ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001182ff7f7b75aa47bc8da06ab32ddc64de3142181c0fa58c1beb554c31fd02da591e0ccdc4e539251eb56530a97b3df00000000000000000000000000000000129a39690e1849d55e8e02e50e23272e706c9e33abd8f587dc8b1c66c491df5ddfcde27e0965ae7aea252f8ca27415a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b4c447f4a5d5492f2c9ccbff8282f9c08a0bfdf8cd3c5188b64575b3131cfc5fbd538caca991179cf9f3e78084482a000000000000000000000000000000000f54742b7c7a370e3ef7aa5d08b7ce8445b0bc371333b195f9535e5797a5c2a8bd840bcb4d22269bfec52927fa0c648e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016440aa723e28ff71b637786f55c222a7bf700f9a22b064b839054595c87f00086d6682c66a42f654fe977bb600df059000000000000000000000000000000001296a11fa47488cefb9f2523e260d3fd8833a09e4f33cdea0f36c81cae66b7fc1b7c1a30ada81140bcb496fd2cb6c7f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001990c56373cbbc99ae158217134722624434c5eeb12c78200b5dbccc84e49bc19aa92193295bbd944a003696a8e70bfe0000000000000000000000000000000001fe51e9e6999c101efdab04fc3c21aabe8411e827da3fce0de86392aab427be97210b412511af0f43d94954513d5d581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c0a53de7a35d8301d2c4934bb5becd473e3a52464fa08070fde9b9f7e0f2980db82f0aefdc280da9e16407e6aff82e0000000000000000000000000000000002f5c5a8f919e0aa524865d98c3f3161a846eadc897df925f737b9959dd03af27d7c9b62f481788f384b61466b9872231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2514dad591944de343dd3d092aecca56a4c73327494bee75c3b491ca8e0ff3789ab29e6c64c7e44de34e39991eca4600000000000000000000000000000000144666355234aa895e8966c8da8e9d6cc2db3c4cd7a61b4090243162f035b459b52a9007236e17bdceec502a5588fdd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180b0e5249dd8c3dabce1722229ae81edd8127083cd973aefcac450242714ad7db5a8a8259211ca7a0bf8fbff159b79c000000000000000000000000000000000da31243e1e87dbdb1126a63a181490d8a1d764ab0dc184b0c3f14d3341363ff0d0f5f712737aa08e60058fb0847ce4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f72d14a55b63fe9194cba08280bbc96885e7ad8008e4678fd2c1d90318d47a5e105a181f72fd190637daa109bcceb3000000000000000000000000000000000cdc56eb293932f737bd82c159e930883136d3557a116e7d2d33b14a32abd7a987d410be3bbd1d4de4d9efab5ead634a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120c8bda1a6b74c5a43d57d2bcdfab37a5c625d3713532e1895bfc5dc57ca977bbf419da62a5eb88b0603b2dd23348530000000000000000000000000000000008692842047ddab481c7badc87ab2846d75b3fe5fade05f37cf4b049f52b895a3c49cf6410ec9dd7bc627aa2121730c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003523bf22b4836dd845325855628e8022ce5833c57fe0e05361a8bbdf9dcb2a47d5a5bdb4201a01b7d9cdec23d2c08a100000000000000000000000000000000066c3c4fac131c9c6669c7f165b279a45c999124cb84830e5999ee3e67fb9fa54dc72a12c5c35782caa7b6f9f5a649621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4cbf35b5a2fab72a3281c6983072154dd81207f87a2fd428b85b56fc50724d52938a6b1206aec3f30d2af786709d9a0000000000000000000000000000000009c7ac106b64477e81e46dbe4bb780f5eb385e2f8916ce221bea0c7e020d7e72f078525ec19c81faace9ec323a70ba391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057744664ef45a90c2da37a6acd3c46225c2f835ea5caa2b54802cd8f7a31a15540b369fafeedd40a81c2646f6d2b7b30000000000000000000000000000000004884dd879ec6f9a1a28606047699b79d89133b4d55e5bfaa3ce98f8f3f1cec9998eed47f7be34ca490eb77bf8955d261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021ed0fd8a30092058b31f545244daffa266fbb0f5f19a58c3fee5f7b707873b8627dd539034f9f721a7b04ef3f92da0000000000000000000000000000000000c55167d77b14c5112002af9adf1be7479e50fc942ebe224d80e4fa1fb1afae468ad92a535483261e1a9d3991f359f7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff3629c4273ca1226dbfbacb92c8caddb7be13bb8ff529959e75fc97ba710dc9e87a1ca5508a01fd9b3c65488c2048c000000000000000000000000000000000668650db07ef079d46f96f2f544157dee60322216de4c53a9d786660bf59a363378027e669a31f6610795394df64e851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142d3a8466096b93eb20408b22f2f739eb1b714d42ebcb82839ab20f680316bf11d0b717d6d521000a6f009579aaa4710000000000000000000000000000000012830f60bba15ee65a504dcdf22e3d4eb2413930c89812921509eb1c199a47deb3923c5a9de6c8b2fffcdf6d393740681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f57245779d45d25a4ae8e3d36aaceadc5897523e60046c802a2f4c5d931164e60002e70ede46da7a74891a182b8840000000000000000000000000000000000003c936cf96a9f07cd2f4813ef50deb178d6241022ab7da87f72916e3248c9671a5f33b92ad89552ee8f310076721d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af00eb49059f6f811e8d8b340ae959fb2239aed5f66b40520f7a1c60953ee4ede29ba1342fe2e4d09f3cd13dbe2f245000000000000000000000000000000001868cb18ca0fda70396f99124ba228f8ec1f362702557f450e611593f926568bbffb2b92336c1addf93b57c07db91a3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d182918a468f9f11c8d8b8f7b2a5ca48bc9266c39493a717ce93af6a4acd390b53f50e927589cccca8f1821f8a53bb60000000000000000000000000000000016a9cec4e4986091ce3172179ebe61ef902b06886f47e1c2805fb462e994736db1d397db2f02376ad3885bb599b104731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e6910803a2b88c03d36d778274cdad9134899edb6d5a3809c2b93603a748d53be4dacd2f01864a82f97b79c8bca8cb00000000000000000000000000000000031ad6a51a6b1daedaa234778aa78aa1ddd5c5044366c4aeada760ef6441912cc863c178999a497a9b6298679f0551eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014820481162d49a13d95e930ce35471f813ba283649d2e486658667831d013ad5929d2b9be872278815dd79cdf63ef490000000000000000000000000000000015f7b2bb2bd086ffa3c6db139c5e54dc5f8380de1181ceaa21b2b5546ec9821887436d2c788cce696ab731a5b55add941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e15694db72b174e9db75e511aaf8974b998519bc1612c9b2f42de7c70e832e84c6e91e315b25786f4e4be62b1bc73c50000000000000000000000000000000006aaa677139fbc25f57c6f071bd47db739689f59fd7321692571da5fb3512482cf543b7c29a383569ff2f11e78b02cde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119449183391aba016def0769281f8c5183042d797ad7be09146f6b19de09c46058f72c8c366eb2e3b55f49e4510e31800000000000000000000000000000000044e2fdb29aebbd197e14d0d6bc7f50385ee6bc7f8c0c491b96acdb2b450703e25942ade2fbbcebc766212f145fca9d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010991b7c9f097f734271879ae2d792f9255be74022b883149e36e2b26a8f3a901986c4789e7ea8b2d306715e04cf4693000000000000000000000000000000000605569989f9b2107163c1298801bdf619065b4cca224ea7e054c8db2082a61b45941a6fa0685dc9686b8ed6cb8bad0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054c8061a1e024f45d4088ab6f3db03b5f7e33f80e85983f98639548ac3d3ba315ae4fa51d357304b0df613b142182d100000000000000000000000000000000154963f12c9fa4b4d441b4a5a2a78fd2e48a745c863208dbd9df961f103aa8785e8b75a7b7609a91c2b1fb763bd223a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2426eb525958e5d651f72ae7d62c10ab67beff7bdcb0d05703c8a1e6591deb16dec21673cec2a5f08d3727aac8086c00000000000000000000000000000000083380a8ea30089bfba7f40c8530a12d1d088ada72d3ffa3dc17cd82ae6d8b533bd3a396b1a21410a4c2b922d3c52eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df4e208a645db5e63bbb2f4693b4de328c12770476200aa3c64cc9989dd00690bf915fdfc9e4dcd73167f7a54a95f6b0000000000000000000000000000000004513d54e2ce1a27ffc0242e48db1fed817d9f8fcdf6be0f1b9ba8fd873f6f0709014ab244070b501a93589a6710d1d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dc9fa3eb9406ab8067a2426ae1a11b6b2508c14607cda503be45eb6b7fe5ad53b105ad6660687e8bee81e948a57dba0000000000000000000000000000000002fa2289b6784c1a285eaae9fa9a096b140b7003790e3e0fa9178fe2f7a80c7fa0e12e51bea2c7f892d346d8f2c010311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191acd79e783f796ad03f65952227baf1b8dc8eb8fadce09008953b2c48ef8bfc16504c1839ba354450d0d217d5e86480000000000000000000000000000000015fc5b9db2ae4e614e6c64ce64fdd585126fc14357fd0bf9f7303ec1a2c137914554f520a51907a502e0783fd6f2f23c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148233cbc88d035b2d85a24dfa9a2b3aacbcf0e296234be6912a7b8656b7595410e96479f1eb4dffd6e4ea5ffd81aa760000000000000000000000000000000006f227844dd6fe6633457da716e747d8fe0dddb0e37d6659691f145b6e7964c41766c502f50982ca3709987a1f5777d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b86933f94918d5db737efbccb31600c1e979d0c4074c489a6734407407bd4716f0dc79683a1396c81583b2369795aa0000000000000000000000000000000001734f6bf71dd27c41bf909352874658431b71c1e8b477210f1ab32bd4d02e5945909ba3071be6d5c8f6036c5dcf539f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001486ebeccd21eddf6401f5b8f1a4e2613a2b50aa407928cfe76b398f2a060e99d06b2915bd13cabe385493feafcfc191000000000000000000000000000000000df9b94f3e5e3e8b81b32621b4c8feeb1fc199f435237ec2e4b7b2031e3f9efcbe29ecb4ec5ce2dcd96b9326038f70e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098db46a3240d87bdaa8e7c0f04a1479ec6e2781a4bc3b77b19965ad5adcfcd05e6e308ee598cfd11dd46857235efb9200000000000000000000000000000000154d33cb52a8fedfb3dedeb04c036367350f4bde8a444b8acdfb2c1fea527487d40464da50ed6b9b1faa6fcb212aee491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010cf952b1761728f9ecf0e71362a8f224d61436c94706377c26c3a702417257d6fa480475a8e30b028baeba728349f03000000000000000000000000000000000333981a3e4121615958623eaf5625d719a07f75bda7242817536977a421750fab513e26b28d416ea16965623cb8ff1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000840ca623954154217c285ccc666033a1b27f34c3a0fead1deb037af2d1a3507d970ea43a04c4e11069717a1691657ae000000000000000000000000000000000e6248ddabf3c3cfe2a787cf898794c4d3106ee504fa91df76f59bf0ebce4b1956e8398a702498aa22868d51e96e39ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f90dffd6fb19d7c9ef0bd14f5bca6df70a0731c9f941d00ad0bd27d15a1708014c3679a8233c5b4354af1398ea478f9000000000000000000000000000000000cd98d818f57650d9c65f1f8484f2d4c8fbb79fd6ed33947b2161dd88f4a3db81f0a3e17f3bd6a0f852e881399897a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ebc1638975768a49a0845cd9a7dc4a23642f0796edb200438e9bef6b46059d9fb9581b8ec3597fbf54eb41453cacc2000000000000000000000000000000000d43bfe311c0d6d77208304ed89dd0ca230551fc4ad1f2b71ec8668ac3968e034b2fe68b78d78ee1732860f30c56808c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112e89ba33333114567e974901dd3579c39a7b6940ad1fe1911637296bea356df9582fd86578283e3fa7991e75de0f5e0000000000000000000000000000000000119bab0d071b6a133d121a425aa675c4793a2f073a9d015b50102acc9d295a85b7ed88fd0825e800106af2cd2bca661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a8ef6e7f83ffb640872168eae078e12ddada9f0180754243f880adb340a6f0bedf56fc03246dd6e6346198bfc7d778000000000000000000000000000000000700b9d7a46528bb36029d6074aaff74a09c471cf14efcb5df4b228b2e72bd5192a7d192c83c537fa065b8ddb5f7cb461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcef72389294ca7f3236c24278f3684630338882ca0ba24840ab6c15772e3d103f797508b726f9283a00149c3aa532300000000000000000000000000000000053590dc949e5feb3645b9d93547dade2b4402bbe225303e6ecbef225c6dfc2274f286249b5b44b3021e550e42113d741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020e9d9a09df7cdd15efc86655dbc4424a5051614e717431320329225b70a8fbfcfd4e421d2dcd4aafc55278c14db611000000000000000000000000000000001605644f41380d8ad746490717893e93f008bbc1e58fc31d2021675656d0b7e27e120de55788eae6003d277286bc90c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ade08845a57faed440537f34b6053f8123eacbef95c73752d9f8c1e20c40ebf390d893c71a903f03befbe3e7d770d710000000000000000000000000000000004340ee2170c0b14a0bec5a2974b5b4339a5e9761fd452f00e04f55c0dc6751ae70620115aeaae9b563b2538533f1f8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013766d1cd7d16b169e86dbc089a5763716be6055718cf76d692b5fd413a9c7d99d930465a3fa77979de55c92cd83435500000000000000000000000000000000113710afde43c6f2bcfc7833678dd673e1339cd015bb21643fbc45c3befa56b8d3b8ac4cc3298d2a82b23f1e8fc48a101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024bf65ea632d69db0a2b583ea35ff94df4fbe94b1ae8f69ca5eccb981db64844c3b492f707e1ee4d0b965b9cceb27340000000000000000000000000000000000e66119af9e9480c94a3c95b33149b71d5dc5f32bc6bae9db6b18d589e524deb5ac0726528fba6dc03d04cedabcf8c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037e0c69dfa9afb5b4b5c2d18042d8272d64d4b4d5f122b63dbfcca69b5d7e39517c6fdc2e05d479616dad76f23743e60000000000000000000000000000000004a06847f116d21a179788dbe9048aefd7c560cb10bd46cde111bc96a4ad5547827b3da85e24bae2220cd38b8ff90cbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018778f6fc719f726dc847e3d8ac2b9898fd2a9c71d964c1bbfc23f3adbf59cb57db4ab94421c7959d525661c4f9fc6780000000000000000000000000000000010ffd434170e556e708de926bd4433653b8801b90914ce33d0c85d75cdb9d9bf453b38964612a472231f4fa6866dc9191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018150e7231d9da2339716e770e38ea422340c1defd4f45ff39720193758256d366d46d97c9dbcf5923247990baef4d40000000000000000000000000000000013f384f80e62aea06946d12d4c0ce7d41e79576ad2b92904c79d379bd4d896477cc0851d7411b8b7d8054b214b48059f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a745f94954c7d992d5537e086a4a8ed7b1791851b7c2b73ce9b27753c7484a8fb157501320d2526742c44790aada5bb0000000000000000000000000000000009864abb1d2b1a6da9da3108dcf6be8e342988a56deb1aa744187c23c8442711d695b7d7c8b5e7fce25cbd5df8c223f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f705312d68ce0998ab63df7cdd98ad60cef9d081886e323ee179b6aebcd3bc4ddb0189eae8295ba3b8aa6e45c9746100000000000000000000000000000000088927a267c3dc7a26be02f6086015ebbb7df74d8c262fb9e2c6c7107b10ae3ed0f3c252267dac312159ed34647c8a7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c93720b64e970f3672d13ca5136e089fd6ba66d8131545222f835e3814e3cf11fe103d6c55b1b9aa810323ccd65c6e000000000000000000000000000000000122bca3516253f35e919145e7b24ef7541aa7ab8c581f77aff81d77e410122392937343d2817ab16754135ecb3aaa001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b914b4f2a92ddb540bebd7753103d806602ef55938c96fa4fad0a83cad6091181be2c0fee561e9a2cd4d475ab6e725000000000000000000000000000000000695fe5b0cef4bebaef02847502ec620e4b64eaeec509faeb464f57d1092e1774a5ea4fd6b1eab1f61bd014b7e47b8d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048a5090a7fdd5354a3b2b8b87c7f1bbd4c9d4a196b92db76c951de103fbd5ee36fc46d232ff804f2568db4dace1a7c3000000000000000000000000000000000234bbcfae4f7618d506ec54200b24c21ad078b73db7589304841bc43e5a556cc7739b5009d2d8b13ba26e7ddf180d481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190f8da249d05588e675e83e75a9c5b5b12860cfd61b9a09b0158033e26664c1728b0f807808121f5e9e30a50b5ca5460000000000000000000000000000000013056b3dcb76ad2c18913b82df3f64c81710856b9e865f69cde8c2bfe8dacac22a4d0847d79a33c0ec44cbe27b6f7ae01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a97e79f9e5a3279bc83d24bc246536bb4d8a76f1bc1d9080da4cb3105fc2d86efd505b8d3ff2305d7f9876edb2661e1000000000000000000000000000000000be5791d4d8f30dd9b3d6cf8fb3ecc7ea3918bf2ec08d05e4abe4ab04955b9320fc75e3c4ee5ce51abc3eaaaa7a5237b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005a13dd950b7bf1d07c4a56a8f77a0c11c8809cbe1ddb6167d429bfaaf38948e056def9842459d604bbfde48a41b243000000000000000000000000000000000a590c1990cd8652b5db89dd7b36dd4e15d2e0a310beecba92166d4162a2f0338207e801fbaf10eadbe1f21ef5eaf28a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d0fb4f341574f0e177f84a7cf08d1076811536252bd2c2cd589c581c256c7128da35b6faa71b6a168a7f2aed20ddda000000000000000000000000000000000706f968838c569c50d2806d6222992f80161631434d122e1e64430effde2b0639ae6a38b98de09b37171f82117d992e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a33189bb49f4e00bc2bf1f37025acbf63b1d9a267189014783a2e86278904e6e073738ecae36972354dfb2faafb4635000000000000000000000000000000001647d5d26dbee9e82a3ae49bc50f582ceb64fa8ea6f2ef4f8e1c5807a389249e975436e50bda9b14ea38bb896a4ee63c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037fde4659f3ad3a819c4a3d0d84ee44d8dadda75a85a55df0086aa443d9ce36b0d59faee8706980b58bc27218987dd000000000000000000000000000000000191233d0e2eb06b94db74db20d69f74e46106c5f2e0c8b8502bb9d19fd41e78c08f062d1c3943796e7e12906389df3261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f7793014f120a78cc129369c8d046346170dad8256d67c0bfe567d61d5e8be2e8e16951e2c82b30ccb105f9c5c1510000000000000000000000000000000000c76446134c04cb24534a6c25704f249bfd0943ae31794e16ecf4af3c073d0187061549c6c8ba7cce109ec2b841602ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ef47a315b8d7b1a374336bf74712653bdd80bc9b4b0d5ce72ce82a535cc4f8b71e9267247426b9ef388cd8384c97f1000000000000000000000000000000000a6a6e3731bf19700d4c53f5d2f7bad7f5686177cf8a171d63329dfb4d61c4335ba44aecca54a11a25b6aad966e93c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063666d7286006fdf948944493da4b9995ab783a513d4402e609c34fc74dc4ddb7b6bdf20ae075cc170d87d779d86998000000000000000000000000000000001572996ed032223affc2953afa3b0f03a32c1e54400497bb2f8f4c7d49bb8ec85602e4349be1c0682104420286b207841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001792280ef2c32b7be58ff701c3ca77164cd230dead833ac3540305bfa093b08f8eb22d3948edfcb4d95fc00914ff2312000000000000000000000000000000000876658c8aadb4cc7b866dcf8377899f2709834adb1c036d5611d45048c48729795431d5decf5918c2349c94d63d1c111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bf6dcc0965bd45c35a8580e3c3beb9e93aecbce2c3776b55a3ecb48ca1b56082c87538a1859ac795635cdb4477f244000000000000000000000000000000000e7f564dab4cfe7ead2fcbe8485465ad0ee0a2ebe544afea0a10fe36f616f43febbbf5fc2ac0099c5337bc039fef82f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007382994146d698985317128bd59138f89b596c51a08350bdd025bc5d8ade4adf74000dcbae2ded5660d739373e81b600000000000000000000000000000000026f1b55c2ad1fa0a26f507d9d3fc7d5f6909b53c8599cb16ae16ec63a9ae74e293687673f782aa7c8e6f5257a00849d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3d2daf889e4fe66c7079b3b2e3304a628dce132d01370de654b9119cc7755545b9f991946fe7b5ea6188683e2625a80000000000000000000000000000000017f43f939aeb777418892fe61f2945f7878fb92cc694838d6bdc183ffb8a50d6b54d53abfb1bf7ce793276d08229eb921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000255951c3f935f7b3ff36b596308f30a0236a37200026b7553c540c0d3e188f037af8f1b3a4ad6707ec7a8f9a11a82630000000000000000000000000000000014322a8519ad669bccd35f85867cb8e06556174047cc74b21708c9011192d47130434396d4a92860a3769c108bede1f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4f6e3697cfe3138f815f5c5c9a183d171fd20b80d976a2b47780d77512a7efe7b3d3112eccbaabc0ad41fdc0146880000000000000000000000000000000000207443da4a3ba22003f9d046795c0a59fae9985410255e4adb3784ba4c39be67bb6d536d239975adde49f3b476016701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000090b500ddce8d5b6f0afbca4ff335ebb7e87ee14a6293711363d449fdaab9aea4acb15672a829303d8282f3bd1b288000000000000000000000000000000001885ac696ac967b533e81bcdee49622caa9b7a918af0dfb47e9c9d31da81c4738c4a2fd3b9be7113df89198d110737f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f05f942da58d5f645e2c995bf49fbad3b05d682459e182b9a90ab95df5815119df4ae5c8c06c4c364a039e2789bef7000000000000000000000000000000000eade2a2a36d8bfe3112d7890aec737150624bbd79b32c6b932a7d4402af5b89228eada5d8717efaea215714ac3901bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012930b7794c41b2038c045a4b24fa7ed4d518d9517c250802163fb1f3d85e6640a859029e287612b7e2735850ac4d6560000000000000000000000000000000001a99bbdfd991d241c0e2f4394f641bdea725243a5d0077c5a9fe62be31c49494a0840e0b09171d8e20b703322bc9be81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001923986c1bb94ed004bb2708d43a382853cf32c41c904186635019e1b1e0aa794a06203709d6d9d489b07b3e6d2ca6d6000000000000000000000000000000000f5dbbd42a835d0053dc6132dc496f049d9a87e43c8bf906de8d6ec61c939bbd81f2a402dcc9b1bb440c1d57a574cf901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030173ddf3641830d8290288c355e188a03c79fbfa9eecb3ac3b5beaf9c482c6ed21c1089be8cabed679c8a860aa1d7b000000000000000000000000000000001252b7cdef51880f8af24afc6c03be8219fc90d3fd58741c795b58b825a81c41e8fcd341fe2ad3b1f329006c33eecb701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175fadb3b46e2d0da951f1a72c63ca52c2008f3d9b6202ae5d0d2b231019fc4529c39e05df52a29fd2663b11abab2377000000000000000000000000000000000b371979943c306de152ca54342af0166059879c3e6f88a607b80df9b0e7a052b2a9a430506321617e3e8986ea9f35fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008009e0ade21bf039cbd3ba18ef2fc3c131cbe9e67271f9ee654eda01d5b637fc654a3059161e60e526952e16766ea0800000000000000000000000000000000175416490af86eba8c5a2f33cc6ff5d593f7364a2eed074f912cde28f86c247f132d527dd67b1dc9ed5b25bb05759be31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052225c752f25a20a8fd60075f49dec9f9f990517fb04b5aeb9274f1cdb00f03f208fcfdbadad27dc331a6bb23e395560000000000000000000000000000000006c60d92cbef15bc696bebb951356de6080346e50c02a6e837dbe3de9208922d0038f47e3e74efa2c2fbd3faed61f7d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c76a5fde3bb99046440573fdeee5bfb6a673baff56c2654fac726dc445f999f28b1a47d5df2b4ef19aea5a8e9a2ec100000000000000000000000000000000156f1fab5aad9dec20f87489f353a10945a68db1279f83eaaa7758649fd6370387e31a919f91c4d80501707355e4602c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee80ea62ed531f02d04a6f6322d25f653e5d17c8f8c85a33e149502b34bc6b3d89adf65da1fb64ff7b45535503717b4000000000000000000000000000000000db1d694d6f27247d282adce93d48d866ab4d79746b66413560fc39236480c12af5bf2ce5699f00af74b5701a4ba30f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c316ee4222ed6acafab06a9f8e0cf8e46e33cfad309d65dc255c3a4ccde0098cf942589c9760ed279c5787d2ac8b1a000000000000000000000000000000000d493087bf3fedbd0013426e65c34e44ccc5b0eeda236edf4a09ce724259ee41366b57338fa0676e5e810957803b75c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c395b81c20421afa879f256031e23665a417c6478577e7e88ce0756ada7f657ac241eb02b420213b3e08712fda7dad6000000000000000000000000000000001132fc47984aacb637fbce7b26d14d73818ec4682e6d9dd3fa222729d570a8a174d0e2e85b7e548d5ca61ca1d0971b681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3a1fc6b7954459d0729e9e7f717b2edb6a239e8e8f082ddd486dc516132bf5be743ac0a97c6f546968a359c6a3c59a00000000000000000000000000000000164729bf3edf66bd171a8d777389bf29dc4c743aecd2c1fc65045051d201f412b6330cb87c97d32dbb63a4437ab116121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a446d4773e912957146625a34b4306a2cfa95f542a27de5d46fb3147161c7ca402fbcb70b4c0803aaf4765d686345a0000000000000000000000000000000016af2d460f197b9b60cc546625abe0ccb89839e3d77d57bba7ed6b0d36f69f8b13a9c1b972c52f60397a31ddafa9a0081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001033206e7b8568cdc111c648d483d83950191118810d2bf4f35a9d76cf5a9e0bec7940e36df61431d8f3e39b8a6324b100000000000000000000000000000000120e1473687ff3be83835cba7ed113d371c7485f4223eead64d8af33f79bd195e472f63419713570b9d9b422fbeb98a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037ff0da677dbdeecd3bc694ef87c73c2d139161d7c7242d7380ed6dfc065534c0b3be6c0d1001eda5f52d623b30f4cb0000000000000000000000000000000004e95ff53cdba08ea69082d52e8fca786efe20113e170b0f0eaba0db07b3f60e42ab74c418bfe26b4438fbfb2649ca1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d512ccf1867ea5b42232c2c9c5440eeaceaf8f1f3d6e12ef7942abd9bf6af99b4a0457247f094fe52667b6bfd185e630000000000000000000000000000000001efcf1508c0472cb287beb7291652c0eec439da10c5b4b00108565c03ac4d8b14b797c376649a5c0c5592bb0b7488b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000861bcbe76b814e02be7b2aa836f91cf44221f3a618758b833321f2719b1cfec7e91844aeedfadb744fdf90561cd9cee0000000000000000000000000000000001ab42f0c2885a5f6d79a02a5d4ebf694bf151ec5573ddce9c3b413e30079ffb88cfbc723fb2f769bd5ff5955d4f6e761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122e8a2e760dbe1678195a5d5d94b9337d7a26a6603054d78f568fcc43d7bb9ec8838b9fc42e7282a7da4d2fc79cb4400000000000000000000000000000000002adfc0e53185bc43e54770a4436ea47e1c06df0471552f4828b3133c8d27f0a9f6ae28f27dfea4e99c9a12e17571e111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009268dc939e3b6a4aa60449536175832c97f39d4ea7d056e2fe8c9768199d6d0a1176059197a51ae91fa5053a67cb7e50000000000000000000000000000000015d2d23f629fd79961295f29fee3c09903dfc6637e7ea60629e6c05cf7d7c47a8e717a733a51864d04807dbdf2c034b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001716dfe8ff07ece1487faf1304ca59855527c2e27ac5f226385e000f149faca8f602774e7f20d8542af73911deff71160000000000000000000000000000000016d2fad8c614bc49f89fc8d26318e92552b0c77f7ba8d755a987e78c1e2c2852cb1a2564e649620721d60da1e3ffd76c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa5a7ca5c1b22ae109f232c91413343c878a8258f9ea51daf4488875bc7225fc2351abbf0b0ffaf9cc44430b5ae4fce0000000000000000000000000000000016934ede20892c4ff736e319a48df847dae3deba172e51a84229b14b8651e71c7ef8370cb00559de4665d69d50c53c351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000527ac8f6492d188a8fbc196287cbf7f49cab49840a35a4f9bc3acec7902b402243d746c05a01cc8f02f3d0f7f4902720000000000000000000000000000000016550e5c0365f9c7e1401f6b80168a02f32b843f9c4e080f53d4e665429125678c540351d44ec0ef5e556da878d121a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cc1d1cddae637453fb11c9a9cc6ab0febb11b0506eb3b6725afd97fed22ba14e6f6796a370f7d1aa5b1d51c5dbdf01000000000000000000000000000000000918f8bfba790d573892369f2770842a307c4018ea53039cbec616c106eb2bb182bde25f2feaa3edd870d61485b39c8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114ab8c0552e1df94ef0a18f67d69c502c7fe773e2bf430e7c3deb3510916bef24910b2ae3d4be8708731861f9cef0c600000000000000000000000000000000137f8539645a6897d5efa34cc6e27f9d6f91a9406b2097f029af20dc2c8a36330c7348abe7c6dca5227ba40e0423b66a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001627f518ec0d2db3e97a1d593199e3c7e328f9960f4bc9522c6351b644ce337e91d62e924e3e1da6c8b25350dfa1ec1a0000000000000000000000000000000005ff49a77c895e0f4e4c249e39020a6033cdbdee00e2e3cfdd7fb260085bee5534e5f5dfca44de90d5520c1538b2ae581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da044c3be9e47f479788432d8113a38808ad6b18504206439573ce02703ecc53b0c5558db38d255c40f1414b393f7d1000000000000000000000000000000000e79a39f8db1a9394fa4844aa6b4ca15a9bdd0470856919b94a32a4fffdb3b3313baa12d5161b2829a9804a1719ed3c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9b542c2898aa6084ae3d08b21ae0de6d195b117d2e62162b06780d3d418aed9bae2d3743e4784d4142e03a748b791600000000000000000000000000000000175500c0dbbbee64aaa03c8defdd78f5787939467247d6f0a9021bfe8152afa8227213fdd5886f4eda4d2f2315ac3b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007383504231e05600c5905635d74a3543e146deb8f39e38c4540c13ea98588a5ed83589f6b705732519c4e7329b599a200000000000000000000000000000000067b481db48deeb9e1a1481cf671ea351fbf461b56476efc71121591471c1600815bfb1b68f6346108d1a0118d73e6f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001608610f70541e945bc94605180769e51020ac8728ed00401246bcb2d59e3ac7d8cb5cccb8138817095ba199380bc3e20000000000000000000000000000000014cda2e886238a8efcdd86f13dd62f6f53a2bb6022b7053da21aa41c7aea656297521394c37b3350b08d042aa74b25521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006723ef861f615c3bdec859e8b1d4b2d1685f7ddb9dc34dcc0c9f71c98b0597fcb086d7c320d329bde59a640e839b204000000000000000000000000000000000d806c4c4848dd50297e57c13cb0cbac3aae0dea76f8966c332203383ae0b8fd07587f9d3ba33adf2650decbd06743c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d300e4dc39fc1c6ac750de943def8f9e6a203fee72de5c562ddf5ecbf91a627af58e18780df265a61a7de240e628cc800000000000000000000000000000000182bd0cf1d22103ef2111539a37b12596fe4f022bf70ac705a14c9cae1b88f817ed881b5bef6a41d90628a04724653a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006959c55e13d0954fa8f3acbbcd779e1b3e31d020f6f4833e8e07493b7819a97ab7bf4a26fea8220fb2e85d3b32e7e1e000000000000000000000000000000000b224266b8d32f8fb68e722ea79268ea81511f7aeb0c1dca82076e1967569c04953507e800b0375216f3d62862aa877d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cea485569b753a820c4dc57860f460204f9bdfe704ab1f773162d6558b403835755657037349d29eea6a9ebe9b727f0000000000000000000000000000000003fd1751c31581d223173ce1ceb252ace9053ac24e9ba49507bae5dd6b288ca717c5f010dbbec669fb3a1f51597e13af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cb545ddd049bb50a0d3deb80b5eb687d8ae6c7eed2ea23feaa65007530a6501d27d3cbb371fed84178daefb1c88cc60000000000000000000000000000000000e5c8d84146f5fe2dc344b1bdd2b4e1738fa95c0e15143d3ba2f24a4de45b1f5ac5765db8d7e75be08b5da8fd4c469a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb1c6e52bb2122ebc123385aa25ba5e39068631a0d5dbe117f2cd8254f44bf4a80c561250348d38c5d41b2a9b4c45c80000000000000000000000000000000003dc0bd091f460be7c904310a2cc019b47c1e5dda048dca4f9a7f307a791daa3167babf71f50732b73ab0ddf7c958a661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086c2f52c7c7f096d18fbcf15d34f349bd365b2cf487b0979092c9f06dfd65a2f07dfb3ba905c39d0dc83a53e28cfd2d000000000000000000000000000000001138563300c37a436a629ac815c00de899e8d93d2470fd94cba04c1db754db56a122e0fa1d29730bdbb1f7f9af4093841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015301c870935047bde609d5d79e44e0821177b4ea9bed8a0657d85d45a129627afad4078e7878af5ecd6eab50159959d0000000000000000000000000000000003e07fd37b82a6f13dd7910db74639103d2396df273a8372b7289b52a9c8c9008bc3afeb668873eb01335da7e15b07561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c5eb81b3cbb2d4322fd67747e2b71763677c919421b8178ac71ca15a06735713a87dec3cd293947dee2301cd181587000000000000000000000000000000000de3a2279ec9220fe5a7e6311589aaff3956846238886c9ff9fc61d28724da782da74b30fa6236c80f35907b11e6507d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011373fc32c6ed0d7b0f16ec8042182c8d30d1699dc2a8c33483d1f87f1e9216b616eb97bce398f5e2f09de6235b756d6000000000000000000000000000000001480a2b70280b00966b594bd7f498d19916c64575bc56de592d931e08843b56d5c49ee1baf0075b68ea4f3038c8e70d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d0beb2996217a25d9db5e18f8ceaa777d8041585ed8df4b4d6d6dd791428fd74df5c0657d04ab11ced38fca96d124e0000000000000000000000000000000009909da3932cee823c738aec036e351b12e1c28505fb53e9538a9b513dfb53d963e604268fb0baf6ff7efddfc41e8cdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d205dd1a47a70c180978e1ac77f890302ad153e8cfec9d48b4f6c5f5b67e520dd3f8142ae83a998fe772da5db31c8af0000000000000000000000000000000005e5ab712c5d1b4af6828f09d55114f051d4b1f5b56ce4a678ee993b81b91a11fda058947e4de3dd9fa187133ccbe2b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055e0b41d3ee2ced148f578cb483ba485953489e48fc4cff20161cf20e28c80a7e24b26491768a105cc7d45a7c5d767400000000000000000000000000000000069ed977784388018f32e886b189f2cc6f36c47ab406764b340889df86ff3f67f4150a2c566cf5456631dbd92ccac8741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100201a018c938e701f3d1aa10451f99c1a1535899328edb0a5308995ab83a4cee32f2dbfa7c84db02ab9f8a046010ba0000000000000000000000000000000018ed320c95751dbe30d5cfcc49770c0641935abf79c86a99d306b9dff726d5128265898bcfe9093845a0088a787c97ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008133282c3d0ca1cef416c581bbddd7fb5fc5df0f80fbedf9dfdb899f6c0130d1f5c0f96a1e087fc990d544dfd5230fc0000000000000000000000000000000010a0c8bba8ffd7afa560f3963bca116513eb60efb243cc0af13f9abf9778409d33c70d2c85616cbeb6c2afe3972f544f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121b970a8eadbad775ff1b86278b2c5b97f9496e718f753156915f3c4baf4167ade2454853f283b2953d1b4d90263e73000000000000000000000000000000000ec027ba1760dec118a761d7ebd29e99a95bf760a7fc417687dbd9400105e143e72f5cda842c656d70c5da90365114d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f445b48336af484bd3058e6268ec8ca929730d5c516f3788f2320d890d8f4220592efc35319e57994c0760263976daa000000000000000000000000000000000d12b7f8c91cf6ce977ab40282ef1bef90d4253c833022829964fddd0cff050fb2b9e481dac1c48338f0e3331ff6e09a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d386be120fd7bf268589ee5fbdd8657c5a113628b4c562d672e186af9fcb08bd8d41dc57db75815ea5782902101eb000000000000000000000000000000000dc6758efad8901b429016380454254df80e66c6cfe3e6610c5d42f520fa5687ff093fe1722b3a6b6fd98b2b7883a5af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031fd82a2986a002615bbfadbbd4c5737970c94e7c28f5f03e2534f319c52e3bd1d5205ea75eadea8831e3bb5bf3815c0000000000000000000000000000000004711fa6b10cfcce554ac8c701196d5f0b95e62fd5ba8dc0750fe6c8f3b29a2292101bf037016360508522a7c822da171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009548d26310b6a3186c00ccf9fc8e9f8b6a1ad08f91a6eac3d2daa402a02d3d76d76eb7f3dcf0828e1f78b117ce1de4900000000000000000000000000000000150066f0844ec29cd34ec16a4d67cda0fba6dee9894efc64011307b46c87e56d474b9e2eaea01668f69bc8d7030b1af41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001013b323ff553409aa4877e0ed75882c4bc821a34701a31cb201b673cddbdcd472afcbbdfcd72d8edf955e25c1be06ed0000000000000000000000000000000004cea29593e77cf0763940df148f1238ed21440175cc02f36d388a370ddfac2511517f09d646d73451bc63e22af3f4411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fbb0c86907349179c6b00175d14952abd81ecf2e92c5d01874655b0758c1319033a6e065605318a134ab5fdee8e804a00000000000000000000000000000000129712fb3faf7372ee36a5f4567e620d6c7ee4ec424b93bcf4930151355fce2013a58174c7e5015b31d94570124601d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9179138c797fe7d30669dae613e3392bdace34c1a5e326d2a7ff4f0de48063731ff17dcddccfe1227ab408a0f8bc290000000000000000000000000000000005ec6fbe16214443eb937a74bfd9b7385c550630a5ae918d1e40b7334a8e6297e73d22923c97b750d7fa06addb16cbbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ca47b69d0b1e84aca371bfa7e1bef12fc24c371157e9d9258922211aabcbb79626e06d2154e633a97ee13ec66ea4bd000000000000000000000000000000001467a42879068bcfb952f1b0ed8403f157ae1b2d65ebb0e4f1c0093c985373f2634c95e9c1a4036c7844024bbd710f4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1ce88e6b6f7a46cf6bcecd5cb4d9569eac2f8ae1a5af0dc202917deb10ecf3239a6f22b2651e2f3e5ceade1e68531e000000000000000000000000000000000be8efab103a2fff70cdc8edd9c1e6f7719ec5c8e25e2b7db70b107353cc8126b20347ba20c6b71c90f9a4970648bf251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e2f8b6dc5da2c4cc27e304d82f8f804439e40e46620912d57de9605c32bcca31859cbe153c7c9800b21066113e41420000000000000000000000000000000018f9bf3dd190a2c81e3438ca21198398f25f50d8ae654439b41eb3fdf2d95847c4864e7f37277548ddf2f35e3b56af411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fae158d60280c77c306f1c3c9f687d62e7bffbc4e204214635661218b13bd13f4b57dd20aa5d76db7089511564c8c3000000000000000000000000000000000f8d9f8290b75656116c3a7a61c34583175a2365481b3505ae27cb207d65c7253e49c0811e71119be9fc3d0e951a75291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192c5c6ff96e11e34983fd9f732952788564034ecdcc813419bd1222f74ba01ce6240b13420aebcc3eb3db80cc27f60e00000000000000000000000000000000123a3b848d12f114593a0eaf7a64549fd10b3296210b6c8e49e5f6e39a6272c1673f2e6f0a648731413c6e73e13648ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014695fdc404fd22b3590ba16911230f9596e3204a066a866653b6619ed91f6335f80494311b3de8e0dd6dd4a5dc39ad20000000000000000000000000000000016ea50cac7240ecd1e392078f3031ad74a8727a8749e8a75176713b4d8b1e0325e9b53f831f32fd4f4d3274a6359daa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b2328ed83828937fb21874ccad8fac2a5a3a88b449afa1198a693dbecefe3a9d3028ca041627de8fd580718b102d6200000000000000000000000000000000022b3264387ffbe5e3389b094a5400c0f2395d01254e5496304b82514322c63ee705403c9a9d3c2420facd26f2bc98911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117ea6432046276820b178d163d25ada931929869e4fc677d0931e21e598d2475568b2809b662975a52993ae006c0b3700000000000000000000000000000000154a057406f5d0bfd153625e54e2c48d5c24bea56a7e4608ae16e23fe9e3ea2fcb0083e058ffa08e978c72ad6d5d49b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129350d333454e2492591a58a62fb5f9374b9ef7aeafaf1cbc91806d089538e977ac8aff9c9d1b359b70ae741cb7a1f5000000000000000000000000000000000524e2d162734eb131e54ec7b16eb361a6a06f9ff718dee6a348ec37ddc2660f39977623723035aeede16b245d5b6a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad83a20118c6efadcdf84dfcf9bd1e52193bfa09dfc1cef5a22350721ee4ec10d7950cb0999fecb6896782fbe0dcf2800000000000000000000000000000000175e0b2444b76562acd1a21666efb6b88021f5ca3f0ab5f75299a5782e5715415218dfe1473535cefacb8eb202ab3ac11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f22c63b01fed2597d923c8ad194ac27b720ab171cd3e1e17e40c7a43c84f8afada0f124a1b8f40700ce5e73e436e6b3000000000000000000000000000000001420de91e4423aa0c96c54d14e4bf234b394b784f5ae5537a58c3f6b58384284ed78c46a1b1a4ccc500cfe87c560d9f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a88f4c44cfc744877f8fb3223897f505e4960c52f5cd777c6ed1e92714408d866784c4dc0367c431f85e5eab1580d4000000000000000000000000000000001709a908199fefa6f8719e9c6a8ac031dcc17fb15d03cd65020738d31ae524d66e807acc9f0bf8b7634e9719b56043f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0474f73442fa9c45fbe3bc1b036f127293a49889833f90272b722e24d5cffce88e736f2c1bb614bde3e304150351110000000000000000000000000000000015a657201c5784629cd43806329d10aa48becc72cfaaa7e52d6f813925d2cfe8929cdfafa1a8ef3b0ee58dec3f1e074d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105d29c690cb37af781da76e2f8ccc5d6b66cdce6e7fa3613191851ed88319d976efa89ded621f784180bb9ee14b86da0000000000000000000000000000000010bcf7d7bdd63e3cf0e12cd168056dedb0f8b59fcf7c3b663c4846a89bad5bc587112c1b90bb9c2c38f9968307a33d711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000348f2b0cfa2504daf0f9077b02d77deda23004124c85685c7babf6fcd0d5fa3f3877b2fc66148e82c304c8cc5d3c3d00000000000000000000000000000000090291970f42b4147fd47b340198b2bc4aa169b170c4fb0e4351c777e64696905e5213b0b5f9094be76369ffa54b5aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cdc4bd4dfe5068cc9b34404aa4c781c035d49f4a4d90236b850e0a4c1ae7995dc62883333b9e02d5b0aa4498f92bed0000000000000000000000000000000012ffbcee74ea370333ebbe870e03cbc43b32666781d1b60885505f66c3f21130ab23e6cc8be37958e181b8e858d81a4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000079363264e024174da5289345bf50a7c5be5abd62ced3799752cef0dfa22b19c8047f6307cdc6120c21a829fabb91ca0000000000000000000000000000000018b901b7927ba85d3e90cc07c2c9839200a271913efba5a6edf9ba07d6695b5210ce4f3bec49f8da10f2af561fa55de81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001458b82b2263849914244b4ef7c970bca071f2bfb6d9a32313f6a5a41205219dc95afcc2ff46377b588c90380c0806f200000000000000000000000000000000022f6e218b7739541c28b285876adb5537fbb6be4713c0026da29e891b5aeab267fc410ef4002e3abe8cef67431972441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a0a0397719e7a89dd9efaabc80f74e24c09d5925526acfe84f919ff17e4ff39e6f0619fa1ee83a789c36468fdda515000000000000000000000000000000000860bf1281d1c06f5b5e7425f1b86b8cef0bb5e7b757afebaa8609420da2a497b985929504bca6d574f2c87a8188d1241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa37aa765c1922318d5acf6641935f4927bcbc7e4f917ac7dc7384df42dcbc2883ab84b5ae870ef268bda8f646d24b6000000000000000000000000000000001537a1c8125b576bbb29073950daa91fc580ab2ef319bb40e54cb8560ec640c75d25b6c90d57cf4bbb590e2e3ed26bbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e10866905ed0fa46718af22c7e7004fc9a28fef1e47b94c90eefcb939a2a91738da44899649d9f0b6e4c48ccfbaed5000000000000000000000000000000000760bdc7d22356c5ba16e10f350c8672e617acf4bed21354cf46cfe93dc4cd4face0b05cd12dd191462efdb370505ca21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001241700077d383a02b1cc9b5da5d02e44490e691209afae8ac8456eb080f2d8b62be77e70dc954a9620b5e86b84e2b6100000000000000000000000000000000125cea27e6046e396f5e57ebc9fd791efff98d018be9a462aa8606f6927839daa3515d0b616300255b282a11c93caf751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085eabe2a8de985811e225eae5020d4ad73f2fe5688a00ed96d7bd1c701ea65d7b33fc9c97d6a4dfbf2bb6893f7d7e2c00000000000000000000000000000000142f2f44c1eb2b253e1be99d50ce655fa0bb1c6df17c6f99922c1638b8ebb20c8cd253ae70302bdd65b9a8b8296e0fb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000142f17d3e62c10c822977c9fe35c49ee6866fee26b28e62a1506219a9463d95ce8ae59ec670429753dc5680a54bcd840000000000000000000000000000000006687b542a29318dc64c656bd6f2aafcfa9175aa44df1bacaef818618f756f48c52894e172f1359c10f7872f8dc483df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108b0a1a167bf043af0e621b6dc41fecb5c6eeef9cc7f1d9b7bd99e9cf64eeda6a0f018d2aea64bd013c38b0d2cab4150000000000000000000000000000000014a366d68cf08921fb6b9cdecd63454d1d698267ad2972a797683ef1ffd958fdefb6f7f341d829574d7f68726dc5e7661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c19b0d8477c1cd8ce1f601e9cf05a89678cd4ecde4863cc36c4d233a5167ad17c7405bb91ed713e22b50f480847172000000000000000000000000000000000f500a824de41fd4278856171322ab43c2c8d74a4adb643f02aacefcb06ad6ce43bce2655433e83e4cac4b59a475bc191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010dfddf5797928a83df6e6ddfb4cf504a51095f2e34d412041fa9695e7525725d2662706f3ea5b2d21e42656f7b9252d0000000000000000000000000000000013b8827d2231d6d5fa9d59c19ab34bfccdd511d82f90c6e1cd62863facef0278e3a96497f679515e6d7ea579548f00a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007008a6dde693f9290d0b7d806e888ef719a81741264114aaad9b615b0cc5ef88a9c7ea1767919583d2c16ee29afe36800000000000000000000000000000000041526788120a8944731ecbc368eb905f48df7c4cdc3b428cb0909bbe43ed5bcb9988d269922ed72b1349d5c939c19b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062d699366b776097089be7e9d23764ac1b9a896fe3081eee5f82dab71c47e1c2b25d200d21b50eb539e4ad9be78b05f000000000000000000000000000000000ce929c09c907f21327294fbf27a3c223bf00427b2a960ea06a1f28897f9f9455ea1d4be2643d1356d05a2d1b398946b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135a1a68b382678ee6db7a72f9ec92ab1999f0a98d4455191d01b11ea7cacb2a6d50be8dbf8606d5f99746f7dfcecd99000000000000000000000000000000000802c80689a2fdf0123520934842eee70c99242c9a57b144fc7d37975b896f25d4da814e775bd2d469e2964e105b6e981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f48a6d6240d49e81c8f7d61d14bd16dc15b867131fb74ff4d748db2a5f00dd80083b7228333f5a23cb84a79c8a46ad000000000000000000000000000000000a8f7a200ee82845018a7a509ac1d5492db67002d168453573eb1638d604e7d798d06d3db566bbaf985c39185511041e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e7d122cbba97de87d5bdf9833d0cb88f65437343fe3d20fb83f5e6df55a31905754a139726b4b3cc926022a44d6a2a000000000000000000000000000000000fe2ad6aea6648ef2735b5380faefd9146608cbc03b08997ce2e3b08110277c23d536cf3955b602b5e0a17d97bd8efba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5e6a5d11f973da9bbe1a789b954d3e4988d511b3a5a4c9e06b51fbd38dd166fed273a883cb34c6b583d6af7fe7d6d1000000000000000000000000000000000a12fb3203f34508da401e5c6e66675f1e8a02bd93028c6aed82a0b0728b67ba9d79068764d84be53a9a4037c4dd9c561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001057a93be9a1e826076b39770a04ed192b118e925d652ef5c30a680c3fde7bd1965c95eb073e2981ccf65c20bc79849600000000000000000000000000000000084cec06b43d2a0722bb7ff2987548c954b59b9ec57956fe3ea5e2a1576f05dc3a20a2e83868ec21a4756f7ac11e0e381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b09417d2d269f325e6b879c24b6033970bc9ef59c4b081425602eb1e5aae1d44dff6a7602e5f4508f5124b9899f15000000000000000000000000000000000c682154a4892ba07c4b2fbbe6d13999098dbc66a821373e0006f96977ba8c54f9bedd16de231e13b894e8f774be21811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013eb4c8b44a27705c84262966bcd37fc815de13edc10cda7e07057ca5826ec3793f76e6673617296ef9cb7eff2aaf30e00000000000000000000000000000000187dae8659feae1fa7583619a1c5d0f89bfd62efa18004fb5a50c3bcdf1cab09344dafa7c4439355ee1e308453e4146d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185da7dd7ffdd5749648b9c0b9d645ed1236430a2e77f692341b3ce5dcc4e8e53d4c05c575b8db28ba7142d16fb11a6e000000000000000000000000000000000f7b3cb64216841c54ef39f0dba026b1ed303c5b5d053292c306901418806e7ef7f1a8ff0e5fe0f2ae7b98c2032c03e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e0d3a87f704dfa61f0957e23af5a7689e5847d217351ba16747f8fc8bd91d77857998902b7fb9e3cc549f809142e7600000000000000000000000000000000004d757313c4ccb5cef57a9bc7d60aa36589e716bcd38dc7a09044b75b4b6aa3d859cab46f2398ad3a38d8d3edf8126c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073bec0ab8ee9f2bd9a47de1f827455a33cd2cbeb8ee01649b29bf360af72397e6ca8c82e87ea92b32b336327dfe87e9000000000000000000000000000000000fa7b5dc707f726aaace955ba3f7814ff5d653b64840e355fb969aedb171aa84ddb425d374c7a58d92425737c9eaf19c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bb7051a27b6a96fe6dd38f63cf589d8a40416b80686317367d7567935a6cfc82b73806d7a51dc9b6ff86153cefdc1100000000000000000000000000000000145c7dfb51de559debe0c84fe4e7937f5fcd7808033fb01d7735d91b4e32b4bbb0fec50bfe2b2f05a290932acd44f97d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc3c9b8eda29c75c88515df46acce45fc86a98736b7c682b05a6988b4005c8a7ed5b95b655cfd7d503f9f751fb583f900000000000000000000000000000000044880c8c319e4ff67363ff921ea2601c97cd3e6417ccb7c5e2f902a4514e4b92bddce19e206d1fa653533faf36992a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007167feba987c31e2c017b63e3c3229ebca10de7300a4cf1eb2945cdb2c5c1bcfecfb5951e71d10ca1b245db37486ace0000000000000000000000000000000014c029288f3b0cf3eff9f81f32b0517ee1ab4caca00c93caf6c615e488b4c73ce204404f6ab719d46f513c09466873d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b240c89f1bbef35f6e1857b718569943d2adbc7776c9f3b8923ef9a49a34ad7908b21d2534b4cdf2c57535d5cf5c3520000000000000000000000000000000010db39a4419af80f0c7cf53736b7932b3d3cdc46f9a984c5ed7cef6beb7dfee5a5f496e7a68f81c17deee60cdf47c03b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142e8b7e9ff592ec6b8ba5303171de48cf692b0f1fa74a1174382ff7b6c1114ae15b4545cb3798303e27b44035ec1b3e00000000000000000000000000000000127be3e21f39b378de086279c2e1e01dab6f6351befc79e47ed92bcb3e02239a6534e1ffc073e448bd18c96ce449ec971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a8a524a83950946221df476e8249a60b4982ce0f12018f8c965272883f1fc8d13f67b698fb418816510557bf93e5d70000000000000000000000000000000016141caad0fab72b16609eb10269a5b9bc1f973c8904193ec0c8106f6bca18f18506e60349556fb761c513b52e43ea511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000856ee5359e38460ffc10b5ee8ec8217ff550a94c8f0d70f2617eb4c3ea12135bc1b69a81ab28696377ed69fc8454d20000000000000000000000000000000000d3bb01c23a038d407bb9e150f237ce4460b78738c1e407634c12c5712c9ce527e17cf51038768b8ca2535df56a9b5dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f440e9295635e7ab3ce3a5da6ad0ed6b193d597ab93e858bd2049dfec07ca886c20081626cf484418746f0552c35d8400000000000000000000000000000000049ecdb02de4999c365e244f8e8701ff92a1c43710f1107eef50a25ad2c288fb9a2a906398ea895e267ddc18f6b2736c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a503a2035bb0b055372844bb996b65d15f24b969767241c4bfbb94b02d398ca8a23b1a198b1ff1fd924a8993a306b100000000000000000000000000000000105a846564185baf49b5739cb69aec11ee2af3c17c7abe85b5883c84ee5b1af29af4dc48c0da70da926ab7abff962b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045cf98103239bf0a710e766e4c168f23eea13ff7108753e4b6786c81556b4e5a66d74520a9b20f34faa9608e985cbc30000000000000000000000000000000000cdcebe39676bff5c52c1a539ca57a00d1b6934854c7af0efe9e82be1a7a6cb53dc3118fa47e22179e27f28a4276a891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad6728172a80e56d724d50fb6f784e0d270ea68e1f0740f8a142fe5d439c26a3c7bf935d28caa75811a826e968a1a550000000000000000000000000000000007c792ba9dbb914d3ee487872d983e9d03c9a46b6598936382e43a77a48829092ca64ec605c45041e87c2718ae1f6e231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010569dc5ba25f094c5c773cd9c9dfa6e49eb519005d3c45890ac7b375c3a729e43e2ac826a62e0fd51159a4fbe2384f60000000000000000000000000000000008c0a1aace274b33e3a6c5a15ff84b7a9d72cb05482bbb96d1abccf999b85042d5326689dd6bfd3bc6928bb4c937a2981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc0308b36b6a2fe53358127c25bbf7a83069a390af3c512d31b9550174a9de020ab6153ab081de0589d0336ba91c672000000000000000000000000000000001396d76adb7ba91a26712f65c0cc38db33389a00c776815c195a1f53937f9d5cc10a53b716e47302b987fdebf3edba361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000570d7f6344812e1275c2cb7044a33c8d9d65630c2f8813a3a6417ef81fe9b469674e468974764d447f0e04fa981a6330000000000000000000000000000000003a74f3633f320e4c7c078edcdcb5f268b2a7d33bcfb14f319481ac63df4e9e4c7fd2b0cba0b81dd39e3d6a7c21856781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbece52e8a4360bf8631c80fc09f4ecc74f3f36b17f80d40e484d62a305649f6668bf9ba51cd383d1e370c279be3b6b0000000000000000000000000000000011158a17132f17cdd24e5da3eafbe9fbbaa2270822a1da2243c99bc239e34d74aca0da5b59379e60130650551c48c70e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcec204e3fc7be70649ce455307827708915d541899037e0bd7c59e0e2dfa7e464c4251cd55e217375c89ef36349987000000000000000000000000000000000229a72db2d3a0ccfece3d1a9b08ff6a4d52a7d4eec40abf9bf3c5860134bd1af84f589d091a740e5c3a183ec9aa381f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f74b811aaf9af101496412b823b426085ff8cbe0be16ec146f716b93b67a9d49478e3a61a670e2d926063f4098d8980000000000000000000000000000000009c99bdb057d780ba322fdaf0d64b0ee2e108e9265a9c7a43f547d3e219b072defa51550f0125ba8d4e8ff682c43edec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000007528c336fff5a2e805040acf96ad5acf88dccb539ec4e7f7a0fd6af0990d11acd751d8dbe2fed7e6c00af2176402a000000000000000000000000000000000b59ed6d23573e077f8c53f4712a1db38cafa177c283941fc29b5237cef7e06c8388a725a8f0bc34fbca703b9f78790f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008eb9aa9b1c8fbe3ffc605e27753983fdccbfeea0478d2a0701da93263562c42fa7c27b1b1c92fcbc7cc780ece35a8d0000000000000000000000000000000019ddcd894aa3b50240cb1ce805bfcbe90b4838f4471b3bee37ff62544d032fa768663fe05844abb7ca6b7c604ea318551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000246ac97af8d7f651358c7f0146e790764fcc7d4bea68dc283895a397fae670f50f9a8ab2703a8c182420fa0cb9e57df0000000000000000000000000000000001f3dfa895613cfa0fd82bf07b0bf8d31368cf33e21312221c0ae8880c1679fe10179c726e624a9eb78ba41ebc5d285e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093456a46a4fea6ec912ef59379eef2def307badde4eee92b12e2890aff0b1bccb3b11378705b2f1c5849629372e760b000000000000000000000000000000000cb35f5b7eba73af36e6748863d90c2fae7ec578b70cae36d1895a7517d96b04fce7f058b7c115f211c39ef5a012e02a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae50ff2c556fcf11784836313ed209c0c248f9f5d0bfc0dcac5e0b5d2c23d54bb2e420bc5260d1a8ea17757837655a500000000000000000000000000000000031a4b0ebd75687920856558f9ba8925cea6aecc2d15bff06bcc093a7cffdf146c74ea81132755b83aa6cb0b5b07744b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029261dfef4a6147b77087c43c2fd4c51f5a8d3dc4b56e47222081db386efe87e0f4ba71e73a3300cdad0ebde51671d4000000000000000000000000000000000afc84590fc84f628ea6b3a7dcae723f453ad02bdb9e16490cba2ed2bed7698aa44222467a7aaa8841603654b038c37e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007da9e1693edfa8b13f6bd775274e6cbe0fa6ca64ab5696e8890de3304f8caf7da0897c5187d31f3af4baa5e8c4f3f0a00000000000000000000000000000000090cd618ba398407b21186a3b654ca74e8b4b81fee9182e59ed85ff36aa7b00fa4746283512cc8d64b314937b8a959321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001281492565b70cc9233c5c51059a3acbdbcdaf61bc5325d5be4464745f6bfffcbdaa9cfc0034d29ac03e44a53fb4c8b80000000000000000000000000000000012728011592f23c7ee53c47c199a6fb00eb2fea611b5f6fb0c91c3b89d0247101dfb5519023661ccd648c3cf6b94ba381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ced9449207cf29b8807e36e521e635e3e911e25e283564199dd50e0ff95a82a64ef2e4a34e2c00e853d24e4c601767000000000000000000000000000000000b9364c31b5f1ce6ff8748909d6ec8e9237a648f876c3a36a79812b108c32b6d571ab2bd809c531db0022ee2cabeecb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caedde99aa3c3248e529c9f885dfbf7c19957adb0a2ba9f38a5a64046b25a7af39666baf072d12d32f29d9c778138c4000000000000000000000000000000000587416adc0a5cfa686487837980c8b2eec281781cc50ef1b90d59b918e00fcbee8b6b55f88bb61fa1eeb1998772848d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ead29df3954bbee044ab074bd5d7869f07f0c016b1d4e9ab97bd9aa9e748a735808db53f47217d57969e7f57dfb557000000000000000000000000000000000c9bb04732fedc62369771135ac46b883bb27c7c5563bb77bf275502a5a344f2c5876d59daa89645a936ee4f593bf0841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7b242f5370170cf80da57bb3bc86a2e602f742c98f428a62dd91cd608d6fb6e119effd1f01cb6bcf0aaaf454fba1ce0000000000000000000000000000000003f64e278d8f22bcf0f648736d175f99f52bfc5429a9c3773626c41fc94dd13fe676a1a2604f71061be0dcc84847556e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014407ce6b6a8dfe423a7e8bd38aeddf8e00f2b19d6a928c07fad41445572deb5ac9b4842a04c8b1ed61a7e80c6cbd04b0000000000000000000000000000000004e6fe54a119ca3066610a55dcdb4b10b7186fac430dd18bff32bcce309042e7fc98ae21f27c09b2b247a00aa6cfc6db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008eed44596ca5f7c8797bf9356ceb21008ec86d1063937d2e66375447f33a61a5f296eb7205adea7c4a2dd04169d5666000000000000000000000000000000000a97286030fb6c35945e2acb59eff3892d748b736feadbdae16d44baba3b2dc8be83630456ced4d1e045ff7dc5a68df61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c495b8569d3411fcedae08ce202e74a0f6ef89abb0294fdec856fac5c84f3b4c0018c71d0dfe680bf0dcd4cfa7b7d550000000000000000000000000000000000c5279e0dd49b68dd48a2d040ce657178698655a9ee26f21ec798f274a19bdab7d217469566a879b65bec937ee6f8811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123ae1cd645b49b72701d0a904a256cb12c9afd86811caf50580c7e579decc067ad3594785f12b25c1e0f75df36f7391000000000000000000000000000000000add1b25c67f431822ba0718a8bc8f44f5f98c7e97a4d50f532a5000ec14d0470332d65b59173fd5dba1be77727adda61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0b0ce79d88896142137213396a5f8b54a67808b55c94e5dc1e1460004d26ea3f837a06ee511ee2cc0cb71ceee0145300000000000000000000000000000000088984d6f5b9e37345b62befbb2fea981d3d9817fdacab28ad7b0cfbe8d5f94f917db1c461925d1a758fc9275cc7ca4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7e13eb9cc0051482bbea7fb59b3cae0e38b16799996d38beb2e90de973d9bc9187f87efdfbd2624482736c67fd326600000000000000000000000000000000040b46c2dfb63eee17a60ca05b005bdd2b0c30ad63a731471355d89d7909aa3e3e9a5872aa2c900c1dbdb2757c1553a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000311a4bb683804d5d49b6a1bc574df73a2d090faa52e72f9a0bb698609f7aaf59f79c5409433d8e4568a7a775546a6ff00000000000000000000000000000000083cf005c2ded093b12875d111e779caccad2ffe3f8152ef455364d45870d92894fec763b3337da2ddd99097f96024921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce63190c2ebcb124ec63f1ebb3c73d7e570a3ad86b1f4ab20ac5f709b43ce915f95690e49da42df0ecaca2421395acd000000000000000000000000000000000cd5f5bd826f22feac664c5daa0b445831680052c0443869e6a88f14ea204f8778942853dd33779c753253040062a9ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196047e249328b2cfc9d5e1c433e36d41ee93de3533f3acbb11090cecd4652895ebb0a5327d26e6edfe0a50b203cba2900000000000000000000000000000000034f8df3e55143ebfb0710a66851c04f2b742cfe3c83816ceeba467890ab05facae0eca6be0d6521d8fa9f73031631d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b09503aa85a030ce334db16dc866b537c03bd828c2f5be724e3286cedff3d4a65f6b114775b4d591f323cb92dc638b600000000000000000000000000000000025843816d5e48807e2659aa59b25f35069f3d9541179fdb0274f5433b752b6b749e7a711b9c5860c67c6e114d9b4ee21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fbf7da5f0139f1d04a9686e21f56054f079bb2c3410001bea4d76b546e72319839a5f8c185e1aca1b10e0390275a020000000000000000000000000000000013bf26b17c026c23b361afe021a993d9da1d2bff873b9b6d0abcb84f095149825f9b942600e05743f35b17b6449e73361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179f8dbd223ca88bb320cd84c66c34e3dbc6fbfa3ae12b0e9c0681b43aa8bfdc1a6a4f068802cb0b087da5bdc4fffecd0000000000000000000000000000000019ef8d91263bbf28a8f0e335323c7419471c677b5df1e461f686c3e61d707c55e2524b83e4e784abddc484b078986f461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002172513e2ff4c594a9c16fa585e903777e05642d49fe9ef73e70d34faaf9b7e81a590fa53e42ce163415077b17e38ff0000000000000000000000000000000014350eb03764a955283559957ef67c3a37ff8f87095f0d7954af591c47d88690caf0d8624aa8e9bf02aa8f2e8cfa02231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059a71b9ffd9f4978e80a697697920af2d77bfb61242a51aa6b6aab63f5e247c8a847011383fd7548fc6d49b4138876200000000000000000000000000000000172053ff657ae2ad44388c8ab4d04aad5067e575e86b3176fb6630f38da9eff72f65ff1c39e6c753539ff6f15e4fec401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd1a0549ae9abe3f5a52d77cad7f0086918348e2609dc9f0623ff5c6ea46f3aff1c0cc50f2aadccfcb3a2a294af75330000000000000000000000000000000007b308c4ea482c5f2f1d651244fbc7ca74185a1b811ace62817341be6476892c19e848315a50cd2bb82a5f726ed8633b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114848e5bc681991e5cda4366ddf182e13305c89ad2b729b0ec92731d473e5aa06df8467e70100a7642df4495f478f000000000000000000000000000000000006bdc557ded0c5711662e8e0057c9c60a37ab1503fa393c1a1b63e1a4dc071500b0bf9405b766b925b0f9a5aa1cf3bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac0bf345e3324bbe63bdeaf3b8f3673b86bccc755195e85112c8f2a7c97957a9a11f08ab4116022ed91e1e5d7a4b7ed0000000000000000000000000000000004e8ce20527ef222fab385e59f423634ebfd2377ad273dfa108ac181af687bb26cc8490184e578fbfb5a709c19d174431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f2fbbc0b1a24022880d2b31290a6690ecdf352d6ed7e7111d67c062b52ebd655eb2d9f909c5c87980b9c7bebced5f0000000000000000000000000000000000fc05357a9fcaf113fd7c4aa9209a2d168d9647ba21ca8bf5e5c812ac602968dc8697efcd5731485eb74e1d997cee9881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2821ba7aa97c542255e9192f851c3b9af3ea45c8d97918ca31aec422fbcc00eea23a4596ad9f36f266215aee26799400000000000000000000000000000000192732fc540be66557b3a81c7956b0566901fd9b7aa37614e326d26f247692910dfb2cfeaf95a68dd8ee2639ea98f4831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b9dafaa2a584122879ed712493f1959563b9ed9d5c304544648e446658c727255412d8fc2cb8ebbc5b1963c858e5e100000000000000000000000000000000185033131994263e2f789fbd902f2abd1cea63bd329515f3d11045f3638ab4c9b11f2117b173091578e7ed0c728cf2c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000243d34b81544ab6b1b14dd5a211a974b96f7fc1f569ef3716713351c727b6c7844bafabae8cd44bc80ee2cc0a42f4f6000000000000000000000000000000001642cd6e6c1d7d9f766be080c0781e5061e84d66003430810e29c915c3021fc23993901fee34fe8f18886c2538d3ffd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005adfa462a75b7d89ddcc2bbba8e0d2086cabb05c4060a7d34d3d221c4fe0e20f816f23b79ff4e8599f824fff71ad0df00000000000000000000000000000000196f222466276b99a788952a5e37de4ad41b73dbf3cb8f8cd273235bc1b1375ddea7e452473a02acf386f70110765d6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e3b2257faec3f134aa05a1d2c082ba541dc0166016215bdfab56ca3074a505eade74e62244c8d0c51e7ac2b9ea1365000000000000000000000000000000000315ec81c4ad43cc0e180d78e820c2003900afa5960014642d0ce983a5a7387573e46a917bdcd5aa9de2329069477ba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e83cfe8c59e2726acdacb61e3b14378226c452aa785abb06bb605fe007078be179d860f68b0dd0f0622bba8b979b93000000000000000000000000000000000fc31b5b4539b9c894f2a7ce576fa8b1c40e7cc966d009edb94edc9dc4f3bbb3dcb64391fae90d4d00fc12c47d2bdc761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de1935ca804ac88ef61f419a7aed1f148290bf2b581e414b79840e4544dd161d6156d2b9392a1da537259a728b85679000000000000000000000000000000000f9b27ff389641d5f23163057a2cf6bf25174a418ced9f89b50aa2a9af13e10536cfecaa5c8e63f5f70fd3662898a7761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c2d0fb963f07f2ca1196823777ea177571f39823a2bf4edab79e6f94ee3231bc9870ec1cd0499c4c9327eba585845b0000000000000000000000000000000003bc14cf8faa822b6daac2d60ac1c421c82a64dd128dc17f0253ed3392069c5a86e615a87a6d194df5d9c635058bd4751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ad4659eb28c45d60bf53ded2e7e9847dbb62f876e38da562e19bfcc29c46c97fa3f06432c1a8f1d0ee0de1d31818c7000000000000000000000000000000000f5a686c72b8e544c11cc607d2506e272185f0da7cb5970ae28bd43e75b603b684b2236e54e2961fae66d7ff500c80101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d0ca629f53eb1eb756ac6c76f9f50a2680c604e351897e7a26fb3344791ced6057c6dbabdf445921cdf76800388abc0000000000000000000000000000000012c7e69ba63134588f30f0cd97e3e957346d42ed7c0fde500e8004e58674dd83040ab0fa115c41ac0080407aa36945761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001703c764bf94f14e4cd32cff19544c1d5207b9920c4ded117b0443b3f1e94531b23566caab388a0ab49b2ec65ab9a435000000000000000000000000000000001809a77c65f10b4e12d88ca6590bf44eb4047a21a5a497f138f2fcbaf8b7a08dab00944a10d244af602a06e219088c891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff8fb06bbe836cd3da90a336a2153e206653f6e48e81771d9528f877c9ed408c222854529df091b4945f25392354f9b000000000000000000000000000000000f0940d1b9214ee0137f47b21f998a9e6aa2560dcd58140d3ecc08d48fe9d04757ee832d9a7a5d4fa819712a45fd263d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a3f2553fb2803310a36912b61d2f93942a042cd2df39bc350d3c3667218e5d6f9e92c30ca357e7cb1d6dba48d8162200000000000000000000000000000000173c5bdbfaf7fdf53dc28e781c5c0864f40cb8f6d305ecba5414ff8720417d2e9a90d9ddaa6e83b14efd247b67cfcc301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001035fbc97d4099786b654a5913c3f10d4176391d95e1437b7e88bdc493b0fb640712ffdfa407af1dc6468d59a235a4580000000000000000000000000000000010d99def8571a278f30a5e77e35e39b1a10a282a8157f586ddf1977c7b95e12babdf9ac0d6d9ce9da79c09adf10233031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fe6b5959473c5fef481b4669c5317dfeb7ce53882f3997a729cfeefa2acaf16e6866733b192156e7025adb788a30460000000000000000000000000000000007bdaa0cbeb99d086fb5a9cb84d0dc1318e2771e8451cc5e457ee62754bd9e70e5044bf93a8e43fd1cdab51eb19be36d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000479763c84dfaf62cceb0046b61ee30ac2f8ba7424f2ec3668f77f8840bd57d5d3b28a0b7e045f6ade4a965a123359c700000000000000000000000000000000107339ee00aeea2742777a47062e72d65a35b5509282972c7d0b7ef0b4cfe89514549783a4bc824aa3f40c36a4f29af71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de40d1de534205a5d823ee0afecc7bc76d359ab8e97e01a100f62c3b0e30682016627218bf2012b2e839b2cf61a181a0000000000000000000000000000000004f5c1d74ebbc4ef21049afb926d27978e611b21d5ce3b89a70b4f12436c0b7116e33aefaa69be50a37afa41c57dd1d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000390c37942642f2d0a05c7d24f3a3c755154b3a578cb9a3cbf3a8bb78f11e479c101cedbbd91ef55919b91368379d578000000000000000000000000000000000f54122b97242d517429d553d74e426235900d95dc974868ef9957227906c16bee168078568bafb232fd35ca324eb9541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001623dd5d7ffb0a226375666a3172a6af5ad38ca13e15225df3db300aca99d7f0256cc2bb5d293280a1efdc4a123a9c75000000000000000000000000000000000695233473669493d02cea4092cf3d063cc5ac01670ba26a9cf23b202dca9fef96c75423296a71b602be96455fdc872e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c404babad3aa816fac104e86291bcaf009d0ed83bb2f27768698b2abca91e2c6d6d52bc692dfe5b53e6e7d28d9e71030000000000000000000000000000000006f4e67532789cf268d0ac32202909122fa27f662ca5c541f810bf0bdcb5e27b8824e1c8c15881ceff1853bad621ff381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000486282c7a2263f6e67887269aff16c84b32366675335f2a49f3edcdd9e2eaa566650e77ce1d36af57ed396f3cfa222a000000000000000000000000000000000a3bfbeffa8d55e34a9c51b400fdbd40ae69dd6092ec5248ae2da0557d75b52a569b5617b683ddf9ad1c26264a5384f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001156d305d09e6bd3c6c10a98035b939e21ad210ea39cb78a3a32f8b67767cb09babff9cdbaa9339eeeb7cc182c7d4b8400000000000000000000000000000000120011b3450633d1d02f71da660e278e73941af243fc64ff94082b25c5f7efa776473eef593d61c4c71f9a8d0219d4cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008d14b868c9996ced4068f0ad8d77c9c8e87b6090b4a1a07ce47529c12ee6ee2e9ee3254338bc7a74d002c0d0cee19400000000000000000000000000000000148caeeb9064285567e33f54972c2b7be2b327e4f7d64c15cdbb2d65a4a38161753e5af0a36391b03cf8c5d9ffe5dfdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cc30f665dd9a1a1feb17b6ec7ba0043e2b3db35b920283785bade41c0ee86a2a6e5fcb423b4a07e2c1e0d400ebf3f000000000000000000000000000000000152e82d69711ac6e95081f82ade6a739dcb063fda716fba0c04e820febace2abffc031bd9f83d18875e3bd385fde58621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e68a9655a0e70bb32e2adfcfd3a493bc0e376b8778e918ebce9829eb38987e1ab0f9a1ad365a7a60aaffd62c23e41720000000000000000000000000000000001aff8b0de8964cb814383a186fe3c09b4f3bf8d1009e021eba8033c9ba586b4d1bbce42720cfb9aca437bca1c8015e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bd1c66a9eb8a2ddcd00bd889dcc46cb1d02b270612d5cb56f1fc7d421599ee9f33e25400145c7075432e5127d2af470000000000000000000000000000000008e7e9216088e67dfc95fccc8e88ade66fba14280457d2513e792b4e53a94eebf34089c025062594c1aab34b63661b031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ea6910ebeddc1951546260427856df51acfab59dea6261c710db5478bd9e9e3a4dd7d281308a4976ce628afba80af900000000000000000000000000000000163c190e3306cc23398dabbac510109d449a565cd6687235dd2ef1a76c95adf722d80e69dfb95a171849f6ba8ab9ed5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2a3646d8e1dcc1fdadf04c767ae49362431ed64154d3e56e0b3c02a229a4333a79834642a81748b429eb51307f9fbc000000000000000000000000000000000ea12605b0baca56cccf5c78756185ecf353950901eec1d9033e698b20494b01ce64bc4e2326d80bc94fd831757488271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091a40ecd412f97305308706b3120156c5d6f3dcf02740269c066dc332440bff4ad20cf779fa1694b22d0e133c3cf01600000000000000000000000000000000007574790f2d963b178bddfdb0813a67a467a1d6671b900e1050773c698868784559ad131931ac21c07d289912116dcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a50a5d6fadf34fe9a09d28ccfc931a919e060241481f4dabfa25f8f8f76ce1c89482fb90de55ac9d71e7196232a6c00000000000000000000000000000000018ed384f6664d8fdc6dde21fdc15f10c9e4171524f13078f6e2baaef0b476655b7c85e63d4fde3bcca52d3dc249a52fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015b022cc99a8fa9078d5a430cc183d177df7a7acd08a4c33cf7e9afe637fef1d9f0da9fcf31ec736da2b50a4f1d9c02000000000000000000000000000000000ef4d20853926038aab325b06f8a0e22b6f13d99b2e7d643f968ad5f340edd50b2aec38f311fa0adc2fd9664cbdc9f9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b478861de307c9dd8513491c85972428ea6c5733e8ced606527bd75ece1686adafa4985a9307f1f567494e262b90d5c0000000000000000000000000000000017d2115cc3ed79d2218fd4a7823bd95c4a13536f5f55ead3fd98d056a29518fc3dcf08910b6a02c9b6a4d38f867095b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010464728668166a25c821a9e18e00b293be05cea966942667b9f44ba78c1a185a09e26b8a99dd5e36b58d5d7005570530000000000000000000000000000000002cb2cbea6bd87cbd5a01540c26a36a53612c4a4a2e4f28b6a32494be1d21c09f719e80d0cdc6c182b7c0c166768caa21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c4e1319dac24d0b1de9ece94b42d27744a05f70175f6bdbb58280ecf7f94f05d7808e4e30f915199b32ea5f1ba13df00000000000000000000000000000000030bfd7eb2b5e70082a24c9ce64f75982b3f891d205c285728c8ee2a262e6b106fa83874db731f0f3774388af5be6f431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002424f7327ab0dc953a86f88e016ccb440b5d71be20351f52cad07c8d3f0a62b21db21d08639dd8a05b38e5a387ab90a00000000000000000000000000000000013078a8e395c37fad65b5122495b1a2318109e082c71239028dcb4aea8fb0150e76afabdf585b15db646ad715354d8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d563e1a4d912e04a903df464452971ed082baf3504f03f668dfb9cd7ad8d8ac123da7f2cfd48599da7ce08a374c72000000000000000000000000000000000704cbb33b24f9eab11a15a322d18bcd31ef541a53ebfd4dfc4ea25869bbb29dee23d2d5352e4b13aad7abc58280e3bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000eafe00a2d36979878686a4dab0154305ff2a671e66d3ade8889c39fc1bdbb3ca63c2861479a369e96e52b4d219c087000000000000000000000000000000000bdadeedfe95ed197fc565ed380545c94e338e5dd39177becc510e0d69ec95c42df6a1e0bb8e84175d54656d6045040b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013428ad2774e8a5b64f264f8f7029b1c37cf95cd8cf3915dc82a5009846e534493fb9c0fcac5c7c22d62d9c170882ace0000000000000000000000000000000000f0d0f0b170b0f0c155ba6d354076a37149914ff74b717379cb09843ebbffdd1ea1032d7382cac3bbc84942054ad3df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6d1b073120489e79237027b38fd6044e39a346e1b5f08a1ad24c050537beec7d29fcdf9fa02fcc7240df6cd4762adc0000000000000000000000000000000008f0bcfaf2e66f48f9315bc2cfa2cfee31437a8eee5f16586c158eafdf429849d50c73047b04de0aed7333fcf14f8ca31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b21e83775497318753c61fc471355b73134e578dada07c1f687e74ecf1de5e92b3f164ee70fa8d034adc67ece3ccaa9000000000000000000000000000000001071c60604806801af0a7e90287738903cf077adfd5effdcb185b034e6875d05aa543a6c31271538492f25908b1458b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e838da7af4138a2b97de5374eecf651155dbffbc289b8ec25d7ffda09b954b8b17420e35146cf8079f25c719ec9de490000000000000000000000000000000011ef6892a27e024d370be5bc24ebc20d7df6712675a88d0d37102a8abef4376024d7e48168cf58c947bd0fe98109ff8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ca508b3a966e983d0ce9e9867cf880ba06cc315bd4727d8a88edf5ed4e027c2ff7aec031b760066c58c453d7734ac400000000000000000000000000000000028b63b094a8d86fbce842a53dd32f9ef5afdae5d9bc34b8cf1cdddd836696d8c675ce6a8e78c870f6ca716360c774741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f86f0b35a28fd5991563a53e7c48e4e286e14fad884913641c4bffbb9d6a6ff4b5c66493028b293aa5982599a069b76000000000000000000000000000000000264a06277f40aa4c028046adb18227df143d9084bb4a78cb04b06abd10fd87a54c4d9d86c279a7c7053b3b0182dc29d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a146ca3a00e52ee2aebe6549c813e0d84eeae207dd7ddc04d9483ca89758e772d9344e13327f3cc0035ed9f9c114f3000000000000000000000000000000000fe02b49ae9af686ba4df1974970d23a451e0677420ce121d0385358e929046b70e84ba628f1bc196c81afdd0362b6dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001793650228fe4e9967adefba5a8c4ac11a7a2c67f89fe59859f0df93af9fa7523794a281d91a895c1d5977a42e814d2e00000000000000000000000000000000048822e74234d552aff9b745529c8f944995b99d544cab9ad383ab3c12708062d2e7831daeb21e771e2169de4c7825b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000794b03d2e74bdbe359a83edd7caa80c263166a0957064f1ea9ec777ff4388272582b5327d152fcbdd9ab6026e91028b00000000000000000000000000000000076c7bb97f6a410b55e18243d0bd8a0765aac01bd30f554b70954490635c1209573936f85c47d7bc4f2d3f35542699fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155c15b2dc77537b9bcb990f071c75f443bda672543b32e22bdb38fbb2849479a4d365fa355572bef556d087c06b98f000000000000000000000000000000000175aeb978b7429d7c4ebee3f60562fdc690b66de592fb092d87c602b0920f4e074bd9746810bdcdc86a406def5f86b0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f9e536073688c3b5e10d0638bb1fded27316c7d886b1e8d36a10700ed430af1e4dd8f32d1742860cd512fed8ff389b0000000000000000000000000000000008d6d8e782b34ca7fffacf06793b8d298ee7530a1dd23c83642966fafe436a92c72cc323ea587528f41b67f2dd3f9fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fb866b97455eb41cee5003358842325b15103faa1c9852de2fc2cc67885c6851871c7a4510991f533d7cfb2233e476000000000000000000000000000000000aed5d8272afcdf0b1ec01c8a3391c424b79b97616b5a4d3305ebc475fa97d4901304d750f9f564f5edbd42f19fd27d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fadfc5038ee177f237b819694e731419d62aebda7e21277d19294a43a51ef9c8f22c366e3a124ecbb8944ba2b9bb890000000000000000000000000000000006fa5acce813fcb979789c1156a9bbdbbf1559644443e680c797fd9dc0bec17a62e10d9ba33704bb50b86fafdba709a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c39ec27d78349f7181cba585a39781d841624c6e57fd208c8a8d0c37847ae461fe6300a8a9257dc7da44ec8cce0053000000000000000000000000000000000e8e00a75f7561475128612bf6ef56e8dc569ff862473a1cd7525659baab6cf744ab159f73dde0fb6c6bd09a18fd0c791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006affa0c9c1b768aaf7b1e2260814b77a6f8aa15ed56be64a06763db8878696beacb7dc24ee152975bad425e40d75f8600000000000000000000000000000000090b2128725879a47345e54b7f39a28aea6fe76d768b34662b70c2c633bfa1be1df304686593948f587a94592ebf21f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001542c6ed5180ab050b49d31be82a87b7ddd8bbaef7735352648c8568d8d9fe102a2a2899f97f8a7df3fd75736e64b14200000000000000000000000000000000086b6ba7cb58c7423a4cd6f2cdcb449534b53076b39078cf4c935af844157d528f26e60fac3eb3adaca2921f59dadefe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000953b1103f5abdfe88860fdd6a3f90250117f64bca5e03c9f5965932ac9ce312c9d2c8d19091bf68f87801f5b543b22300000000000000000000000000000000132be64b57b2e759b146e7760ac1a53ed1a3254390562720667a40c63d32a2331fdef926c4f06cdf64209187541053e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000331758b7be8ff4a64ec908c5140b933796b2a07d637407843bf79bc613c431d66edfcfe684c4dfb4b129d8eb27a874e0000000000000000000000000000000008479ed2b5695566bc3994d682560631d9565568126d77b009702944361a256fe35b4e66b927fce84e5ca994fdf3b6b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e893eb55fb0f55056fdc82b0f6e41d664f67252a265d4b5594815b46f0789373b74fececcc9d2e81ddd04dccb426730000000000000000000000000000000004bbae027113ad216d8328062d96aea8c45874b353ce77d19b2dd14ceba84552fea9fd4c7e222cc946bc07866151d9c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102b42aef6f2adab2f76334e7bb08bdc2b953cb309dcffa31708acb0ddf0b7aa3588e08dd7e86940802b34676164722b000000000000000000000000000000000e0c018f9c43e9770c10b54dd8dde001c46f6a919c283e7fb1f3ba29de335f9dad0ccf4038ee9ad37cf980ac961183361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000933bb077687ee622afc5526562ccbedf07625aff161e6006df1a46e203cfe8731d42a61d11144ec4314ebe84ffd4933000000000000000000000000000000000e83e5102f14bd1a6473eb086c4126d7dfeb4f64d5af12b873f5966f16fa6ce5662f7eb50129545b281baa5b116b0a341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007083de341510837c7bdd0e6f51aa0f6e349675a7d3082602c3b8512ef1394128ae2998f99975cda75e857b5a08d85fa0000000000000000000000000000000002011896213fe4bbe185b8d162198d5ede677f08a6812fb6f0140c96e79d14aa73bc837a05ffac78325b85bea18019a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018080d135b5ca27ed909790a81882ba4ef3a3ede0cb00825f76cb7d7beb119ae0595f0a9acd5a95a5a79507069e73a14000000000000000000000000000000000be82cf3cd5ae1469b8db11d86a2ba976c5bc20cea89390cb79a6c0d611e0da134a7de7f6464ccad24cc1c1d9f40e7561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037302bbe9bb49dea9b0aa5a22a831baf90737ee4cd327b8726365d78f34b4064798a6783e14940a1a773b65149c4319000000000000000000000000000000000a7e7099caf057213b267a02ad5585402e522bfeccb7818637c3305066aa9d28bceeeebd9430207db20fed0b9e08cacb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000121cae27647d2e02f3c43923af556a3eda2e5c22220a32e4dd41d100c4d4c31bf35295b9219ee9fe4ab0081dd51bdde000000000000000000000000000000001999191f645cf20ec8515ac5c1c95c84ba80b51ba8834cc12d6507e0200eb554a35a1a179d74ef555cf0c7ac911d8f0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014768f7c76e7166819bffe5f58e8aabaf46b7a1ebe407a5f83e05fbbd3f4609260b690dd09e2d0f03e579bfbc466f50600000000000000000000000000000000135127353681d15b513061d817af122c1e0d8ec5e948be376d2b34a71a3f7c608cbd183166dffd70ca727c8cbedae3ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006354c42ca4449a9e9a983795f059a70752cb164e5b9a845b8fbc4edb4f44a0166597ab0293835de7911ed4063f00505000000000000000000000000000000000fb5501b5b733903ef053122257d8adca07bf0e3e333a969206c6386fccf4b4539b5ba9d40755485a633240b3bea207a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a71e8a6655847a09485b049a3d0c23837f6d96cb674e4b94f7799c825edf0389fbd25a7c8e5ec33578ee82f193b6db0000000000000000000000000000000013f9e00df2cf47117fd1468467bdabc00ec60f413e683540d2f0d3ca8289e981effa1a043df028622035627894a891d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006375f88dddd3b804da297692e8bb8b90fa73feaed748194502b9671f1ec826c5fe6a26d7add27cc380fb4028e0ca0ef000000000000000000000000000000000830ea097f451e784aa34e1524a354f57f85cfd63515d3ae1a9906d226ae67563532318bc3172bb69a7d425f312c52a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000846a424ff14eca9df30ecaf599ef62aa08d1e5698b64dea21e6eb79d995a35f70b0fd31b9e4ee12e679123208ada404000000000000000000000000000000001424367c38e2ebd6664b8e48a85a2e0cc9b297d94e473161280ccd1027e6ecf41eded5ec81a6a66ecfbfad7d33a097121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd6111af85f5bd4536452f3015c4d2d6beb589017dd4bc13c6bebe9a3af6a8748d3ea6338db6da9fa7f35bc8432e0a40000000000000000000000000000000016b80b7196538399b4bb193ade0e85b76d27f7a68c9a2dbdc2202873c428efc34660fbf69d0997127df6a69f88134b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006acc0cfd0cbd079960c7f9e836cee7caf9cf0f54de368ba7638c825d0d4546ccc9a337bec1887398531753b17bd86e60000000000000000000000000000000018d1d4284057fb9aba6957f579bc7ef6fcce5c6c5aa35a04b31a9aeb5ad19f3200547caee022dd7b295dfff5d3f2704c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101082ae48861dcb8fcf305c400a1cf7233eb0761061b9206e502f47bcad693d6a6219b5689c7a7e7ca7f2fbcbc2a8aa000000000000000000000000000000000c4130c8d3c4fa31b77f988873067cde306f9371cba12715e5fe5c4e186d510549333b53190b85343e8aa4b1f362d26e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000504138e95e37a9c2d4e095d2fec28903c66bebb772066988ce59d2a29f9c3c015508985a7a176def99a2abce4de616600000000000000000000000000000000111e201662e9d65f31510309b23b162188d64426bcb9bf578a03676b575a870122bd1f7c9af82643627234db450337d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f28e792e50d609cf386b1a93c564a9a1c300eca0680ba712542e26f29194bf0766559bee85d56b8f294d3e86d7d15e00000000000000000000000000000000120835cf4f386f2feb77571b73c1e47772bd10737172ab468e8cb6c59e6fe149a65a0685de2f138778942b4cc3e234131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120cbf33df5a672af8dded8c7053d880b3a83f9eeacbe40ca19219511f29d124d89d8a97953e941951b765477e593af4000000000000000000000000000000001107f2c380c782e59a86e94f0e76711c1223cb639f1551183e1edbef1f4333f84cd8f0ae8e723e6ecf212f44061941141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001edee51b8abeb21f54aef507f4724a96f81e3d5ca7437c4803303e5b01ffd2c7de10aa628ebee3decdbd305fb5baf39000000000000000000000000000000000445f8f00c969bae5a6d54d238100c52f7eb4f35736f1d5988897ad5e300696d41c0d7f9193bb04914ff2b0be3e035dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000687a77ef6a60972ad3432cba6b873f6a2b08b48083793fbf4a87c8290adb5172997f94e3296c8306056e07147df370f000000000000000000000000000000000d9cfe84e5801ea837e4ec1cab4544039aa2e3768609b6461bcdab951b3d9d3741dbfaca7b01aa94e7d247455ea7de131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001679c2eb18b050738580fb246c7a55122e488bd2edae779ae6fc7a40656a9f4828b5cfc1ff7021eae2f8fa6c04ad3db900000000000000000000000000000000114c85ccfe5f7a89f2030b1dcc11f938b936eacfd925e83303ac2be460a118fe5d2759595649da30befd8b6a06807d1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001303af356b6b6939dd259500d8cc4b1676bb9171302f0ae4e001b37d6ae1246aa40cdafbf0c34e29ba9ad24b3205701c000000000000000000000000000000001734c4193f4a18589eb6d5b13625840ee2a7a2be7c542146b0d438f51d2d84370a94141ab5c7032407759c06472d3d961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dbd31e8de7318b2e270be60d2dbcd4767fdfd7c960201fed2c7829cf3f584e7ce3b0c258d1072fae11832849bbfdf900000000000000000000000000000000145195dbec54185bc1e6c2e4dff01b5d26b90dc5033e50ce314c5cc64d18bdc4a5308d5d4ee0fc1b4e1105785f74b2d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ae8c4563a72f06ffaf04413f8ca804358a17db5e8e3fe0d6b41c2ee838b8c2689085625b25171bc65215e6d2b2b644000000000000000000000000000000000ba2cbaee5414addb5bedc652e178818de954a978973ea7638db701532544d64f48f67d9d3704e77b72d1d500d5b69561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132fccb6c20ac77091c3c5aae6d07cb17ac172acc2892a5263ce108bd8c2969ac7bc4f932837e3caf409207af8d8377e0000000000000000000000000000000001274ebf16c73daeaffd9cf38f01ebf44364c4647f42661a5b92f4d3c9b33cf2b5fae9c4be40a75c9d24b43b63192f601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000faf54a39aace8820e9ae36fc2e8f1845a970164ca88d4af5962386039f6f07ac0d48a9f95353c9710fae037513d8a000000000000000000000000000000000011d31bfe8c993a3f6ef42678332cfa8016b8663866302062316c3e79318c54c90ca535b739eaabb78b961a68058898011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010659413c701e67ce4a34cc928a8c087f6c8de05b92d3b0dac75f47fbb1aeecdae1ff45a421c5dc5ee3e3f74589c2700000000000000000000000000000000000f22ac991aff543ce72b98387933547411706e729223163631f485cca3b534a5aea24df5bb53c9ad80805a8f3feb8a931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069255de4844a192d0c3c90cdb3ec35ab01d27f1a06f2aa995a18a30435a8eedade9875dc6e605d4897b84b5cdebe57d0000000000000000000000000000000013883849f8a9be30bff9b68f1a0e8129d1c8a59f0afc22d66a40f0144bb3cdb8d796c8ddb290670aaef63a54ca447aec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001300271c3af761784dc724116041acb1018a9cca9199b4a42dd2fa64a3ec73a15d7f5cb12e54f618b39fba8adb1d2231000000000000000000000000000000001704169e0868e4ddaf6f095a2ad8563a3074e5e1f616a8cc2115ac374742fda9e89f673da3d0cd14f73cb735729cd45f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a2fbbdf84b534ae99b01a6aafe4710870d4d5e5ae7e081aab75a552ca1713567cd83fcda0c85c96c3a48a69cb107010000000000000000000000000000000003670f38bbb499b2049ae5bbbb23d4301d6868c34d5210f60c0554d79c68a4b3052b8ca816d1f3c8c98194c5b9ef52381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a8ff87dea01412962ff6f139cec07efbe71d1f82bbc0e1dc16b5e51e96216c78a15baa3ca6b98fb7f9cfc5017d868a000000000000000000000000000000000b117e0415dd33dd550f953f970c429327dbf2765fbb1fbc67ad1452bba0e6ae40359cd282b11b5b8b2a64c64675a5d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dc9ccdea5be610853f3cc3f038a3160dabffd0fb5699e5a6fdb9ee81b18ca380578d93bcbd5756d37865fb01c9887500000000000000000000000000000000155ec6cd23a7b999cc56f3fc478d09f9bd6944160893b10ad1f0c6f6213c22949051f17c24e53373e9a9cc634a32ed181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a838720b32f7ffc4fbf767716da941aea60419a891321633720323908bb2a844d54c7f79aaed6fd89b01dcc12d758fc0000000000000000000000000000000019570dc54a55b7fdb0ad8567a63bb3859990e92a180d72d84abb64a52a41194fbfdb665f3c71006ffc13f8f6e53cb0ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179ce38d8751ee0de1ba4b7a002b21f1735621e47934e999fbefb75e66a7782b8a058120d4bee09dd1fa0c2d23dac328000000000000000000000000000000000594d4a1bef78e6d48597037276ad72f79de664edd41be96701f6bd95ad218d718a98465a3a21288718635e6bed394671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005fe6881494843a51f0c1ebcd282c9752c21df1a4e213f05b8e2a2b20cf78c90fe3e3aa40ef2cba2395309d9754308d000000000000000000000000000000000be839bbc2997c0faa69a0625a243a18ef81912d9331885e5c1f5ab2d3781ed4055b2e5addb8a82b7772a9730fd5ad7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6154e29cc1766b50ff0c7028bdeb6b618e0774e8d2e6e4d1146e968c75d2ae66717a5b556cb95e3ffdf73bb0bcb61900000000000000000000000000000000181f370f3da74defd80351b73e0922a6b1a8be59770b7d419e48ec8ccb5989be41cc9773e9737b8b4adc0a03051bbc941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192717b42a44600e9b15c482fca35e5a1b0f9f409773e249d2ba1575b19ed200a54337a21e8937cafcc23fd8d390ff480000000000000000000000000000000001743643b43c9691bc3138e5717f76002f84da6f5c7b6d1d1963c488968cc0667b1130e6b82caee257ae1437163c1c6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e539e00b705dd4c5ebdad2bda367f388af1bc17d58f34bef0cfa1bf81053bde78883e45d98ee02836f30ea17cb2bff000000000000000000000000000000001772f1635eaeff8bb5fa403552bf09e93b1b12ac177966402193add71b658c8839d24ac67b812da75d0676cef5526ece1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a260e154947659a63c1ed7e77647dfc21810b12779b3a25c6b24b1d2f303b0617eb4642605bdbeaacefbb5c24c7d9300000000000000000000000000000000128f13cf0d57cfdde4838507e43cdb45c777051d332272d99cd969f2d9e217a72960cf790d702e89c778877dd0e759101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2d77c29ebfb8d72da1776fba255d303f7c93bb65a7cf863a82810a37cfded93ee19f963ed29eb4518ae1f7139f30fa000000000000000000000000000000000bfcb2a2ae252e4385f81cb229980c35997afed388e60394edc6eeb9e71bb02e23e3166c0f51a0b8b01626aecdc9179f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ca6288b0ea2c3150e49fba5119a54700c010a45f3bd6a1b0cebdf015378b49d00afb3ae550438c7a11345202240b270000000000000000000000000000000011c138d729d246fef585a7b705583eba764a2c3152473101ef0aeb012303008eee1ff1d3ffc00858eb214b9933fd4d911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f90e4ac0a7b1be67b0e56aa75b125c7f5a80be8e14598f2e2822c506b3c100451047f8fce8d653ce8709a8c786cf0c000000000000000000000000000000001813d56dac08123ca87c630316bd9866aaf5b3a0ce3be06f7a82a5ee63297c8a886b3be7d1523d1d0b506733c80696271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2d784b83fe2ec700ed5795a40c193652af97888ecb6ef72d08392d830129e576154a5541825631b0e61e58881eb37d0000000000000000000000000000000013a9d61b64643b678b9c699fb3d674fd490a914f0ed38a704fa5a56bc3d35e337493d8617898d2b57bf43c6bb29494761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165349a37ebd169f0260c7db05d44ae2a76a44bf5d316deeae16698d4d3d9058c422f1e2d9905801cbbf4f6043bc401b000000000000000000000000000000000c5934f5d1d2647cec611bc7630d2efb7acbf45ee16b55fe905c223bf7e05e6ff79f0c39ff5398f91f5ba9e7cf174d661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100d1ee368345f9a87054104064d0f75dfee109ec604f154dee6e1af3b1b08d424fa9e66029731937c2ad851f753d11b00000000000000000000000000000000083210b1726bceac51c24687dc4bb6d4567c6e618209d92334970169830480818dde1d64c5a5a6700c26788d1091e98a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b2c06b3f6f2a1a60089f5342cada61581e2fff1e370b7dbbb5a22077ce22dd04a9ce479c10d11d5666bccd1fe632fb000000000000000000000000000000000b3cbf13819cc2f66fa5545e11d0bb330735f742e3801f5e54631f0369e3bc4727501f6a15edba2e2c1d1fd1ae3276f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dc64798454e1aa7d68f7d9baaf9ba385e8951c4132571bfbdbf2a487803921fd9317f955e7916e535259738ce18e870000000000000000000000000000000005c28c8dc84c1d7b3eb0e29af53860fa91eee0c714a5d4e8de64d78465ca907360ed34d2b64be348c142ba112035e59e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8b0c897519bd76ede3e7c0f4ab79ea126d1d357533aba9f6c23f59824f78aaaefaf060016f6f5560bdc6dc5fb318010000000000000000000000000000000006794bda5513135cd855f6dffcc1a65bf47ececdd17dbdf6e0a1f3e06aecb2a97ba04e91662bb110b21739fb7be34ebd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099c8e51d1a4f7199b54e97ed61a7480b41ad27d5ab206e15ece4b5c7a987fe0471749999ad2c8a744816994d59f19200000000000000000000000000000000009e167a005678b7f292edc4731bb6670c43d0474072a20516d20b70ae81ad1fc3413582a968fc1db40a72d8578e2cd331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000facff84b66610d77f9b78bcfc57f4f61e46cbcaafe72922e7a1e873d633aba2efdab3bf4ee28889492198040a1aa68b0000000000000000000000000000000010ba41684014c1eea90d7abed012bbb7089b634d6723d9b8edfaef9cd6563d88fb8dc3b537a51b38e42cd7bea48a3a221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9f3cd92904b1309e7cb1317b8cf38911bfeb4aed1498708aaf23f397653d1fe05713739804152e114a916bf424d22d000000000000000000000000000000000fe7d99ea5ddb1be034b287aa2c8e4423c5dbcbbc7dbf4dca86ba62bd8d8397bc955c68273ab678cdb05ede3b286ac3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000201503d875067ee42d47dd9579885878c296836eb4ee2c38e5f73dd37d25cb78c42224352433e7c86746322d3562081000000000000000000000000000000000776a1c257f995761b0d7fc0285ede92007ef59845adc326f9bd5f768cc072dc5a2a90a458c5ee0655f1a889f93a0a561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102d6e00945c7bb47f49efe30c1293538a791f0dd8b072b2cc84aa5947bf6b45f0cdecb3f63160deea6aaa8daec136ae00000000000000000000000000000000015d35b59e1b9177b52414276a2bbf1467581cb889fbdc418ad7127597f7ede72cfe884b58797a22b798c85bac0ab0a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026dff238e4beb8a38a0069f24abf65fc9a4c186819577d67acb646c49c21941740c5c947d24ed5df325662acc30f972000000000000000000000000000000000828bfd7419679dceac17308942449122f17cc0b4f81deae5eb3525e96df376cd1259303602a1af03c26343424c71d691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000190201b688466c0cb8a17df1c911d9bdfc87c3587ab75f2841e21f394259d465e454e030727d7f3f026b32b10d4c28000000000000000000000000000000000aee0110214bd92791622bad2ccdbf3db6313d78a8b664e8b5eb375f13dfbb9972c366675f4bc983678df72a705845461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008be8f9ec9e6934d1d33f1f39245e9ca489499d6a75b87ced583424718685d75d48436da9efa52f62a2940f632a5bfd00000000000000000000000000000000017fb5c649143e926f03e481b769c16259523b6799d32a7a024e0a886b3467746db9d8fdbb653ce0d791d005ee3a2c8c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155f74735b56df1977767a359aa72cc752e5d2509a36c03cf293be90b56dc0c06adc031869d3b8dccde550c2ea7a66d00000000000000000000000000000000000e2447157d6c989dcd9c1655740d4fef8101edddec11f9ce7f7360f9683705bb6fa93a18b8f55ed11300bb5fa3780221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001600caacef5548d43d540e4de69bf7410c25f1e82bba94aa26cf7a5c8e352d3194791f3a235dbbdf86ac2ee36220aa91000000000000000000000000000000000d16fd83c4036ba7b6ac2a4c6912e1f31770fe2016465c545e3d3efc5382714dcd592430697b88fa9b2ea886bd470f6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001481a31ad1ef049758736efc9455de4e3aba3c2bd2ed0ef029a594edc0329e8ce8fa8c011c0d033535f0b85de81dd634000000000000000000000000000000000de3aea61f123096618ce9bb27146d970b15221e3af62160a7cae9c2ba895a15b012ecbbb116a25a2d114c4843e748d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d646dead28b0d943b76ac13df588d9636e9dc4ffa98b246c59700235add17ea8d3e73b92ccfd34734c6a81b2fec56f00000000000000000000000000000000076cb837003c71b953ed3bb2382737fc48ca20b6662e1a86c26b6721a7880f62c9fe95834115b14d389d80eaa52efc801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018929d6fce2d5bb63b818c2599280bd1d3c88c6e5fed963687970ed51ba2f35b03a6eefb4504c2188da37696b4a3ad470000000000000000000000000000000011fd125043db4f53c2893bae9986f8eb4df977662f8e43c39413ca4e02d2e3063806a8e647008d1b4b98dacb68a1d0db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001214e7d85275fffc166c407c36e7136318c3b1354c394cd63cba451a13634ac4665db37f70126b595d7af0db6c3e86e20000000000000000000000000000000000fd57354bbe32061edead22368eb7a482560736865b56a1e8e9b4807d5fe67be7c26855e8b8f1b098407bd12b3519fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e3383a2c836964cf4cf1af0e1dd031a9add1699a52de7405da135b4daa2b245b92cd03ffab4bcdab438889a0143cf0000000000000000000000000000000000a47b9d94e3e6391f4ae43c890b0b376fa476840e9ace40b3521dc8aa28dcdce6aa9c4dc523311b6e783f4ba0be504fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c47320c9e5c0a24acc7a390ef285e6f8fc824dcc59b37911159eb710bbb1056b7245544099a4f15c0f45d4c2fa608e9000000000000000000000000000000000e65579a534e6439ffa92cc5db147a383713c99a1c8a4978ed1b23863657e99f417c35382aa959d4dbaab399a2882e591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d816bb18ff5c9134741e176858252250cf8ce0645a5968ad97b8ed887a2bd2b8c9baaf883213fce5bcd0252155d879000000000000000000000000000000000e068ee148faec0073fa4d0d9550d34b3bcc6fb1d1200d79ba83ef96432e443c149c0ce961d260cb295adfc7f333b1551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056c60dadfbcb37fbf6cccc9488993ee231ca3879ac286e9157157e785593b7c4b4b6bac35c12876155480b1ff087e5b000000000000000000000000000000001314e5da6ae7bb509c6fd653c6d7e188935ac1d144fc1ea470663223360a7fc981ded7290ffe5ffd175d7f1a9139fa2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d50f204e4712cd679b3d22df1daef11753c7a7176881206eba212d1c10986e6fba28b6805812dfe57795165d4c16b610000000000000000000000000000000011ac3d389adc7b5ef73dd685a31591bb2c5cd9337cfb89a04b40d1c91e1c3d13da9a6f759fc0066d159e0e720c096d811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d844baaf2c5845ae19bffcbac2b700266fbcfb05af7aae68413c486fadea5dbcb84a254669f8f28a2a96c816030655500000000000000000000000000000000048f871d8257ec42c66946dc1586e56cd7d484122dcd1eb8f80d57d18cbaea74af17cdca248ec2ede4a2715c555dbfe51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006333835480b27866874bb645e4edd96627cd3d3a1feb970cf1a0e322e653db5397fe51613d6f551ee7dfdf0e3e8b064000000000000000000000000000000000f427767fb9fa4caa1a40664f2826f11a903aaeb15d21d0ef3d43d4ed2542ab0a9ca9f906154e111e93d49a98514bde41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000240e4c915d9623039391c31698b67774b58bf5e66860a0a3de754bd619ac37c1baed781f4fa03b0706b2866b49c0a6400000000000000000000000000000000194f10c086e0c516d24a04cb9572a22ba6160bcc7e41fc463e8e5014c98b306991ca45062e99c5609e7f1f57d57ea8a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a98a3f2680e9fca1a339f4d6e3aba899b5928455077ea91460459204eb455c4ef30bc96345868a3f8fcc77b6d97f3d0000000000000000000000000000000009ce080aa2996c7e05250d2ad55b5ddc34473ab9835643cfac3c469385559e5f38aadac274a2318a6d908655525181641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001af04544270c96db2c69f66970f78c2df16310dabdec9669fb76a8fb6d77898d4c9e877878e54f1e071594bfc87a30000000000000000000000000000000000d17e6817bfb3d5219ddb6d321ff350c6895634ffb59e34c304311faf3a1baf193a7b2e28ce4027e9397d2e89159be8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d35fa8ceb4006f445a874eae9feb799de300d4804c41e9dac61fd548d9a2b9b17874a952fc2ed3e3c02a6c9bd3655180000000000000000000000000000000000ac704982d1fa04c0a1743f7c1291f32bbf7eb1543a4cbf020bd383f05da9ebfc7a5bfe4e8d84666389026d20d9c30e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c4a5c18e9579f40e71c9c7d14621c0eef45415886e859682dfc157b017d8ff95d26abb53ba6eb2473313da54bd19cb0000000000000000000000000000000012e4fd99b3b5716b2809a9b3472824fd3e97a899da85a815f18ba8c82a2dbbfe88be355430fc53abce874c3caa8a5aa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089f21496b764dfd698ce3217eabbbf9a52835f4175287c773e071dca489cd5e591cc3e12f2955dba614e2434ec3be930000000000000000000000000000000004b85b8101db1c0b9cad5db76b91b66a627ffa80eef895376c92feb33d932884fbbfaa92ce709b852bdc0aa198ee5ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b16f7b24ad10e7fcd563011dd0aaf91c65c807e24aae60e101f256c529c4a6f629795d77428a8151c335925159c4030000000000000000000000000000000019756b0edfa02a09845def99718820fa83884c738894f3966c185e876b2020265b072f4b6c03898a89f94112a210afe41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa0590cf2a5d251280aadc3696e333a5c78708f67b61e2242497862094c1bf81e935cadf77ef6bae9166c757b7bddc000000000000000000000000000000000092a33b018afdae7424d85d3751f223b9daa9bac43b0a39851a77489c57c1e473668423653d3f4ea361536ac54d8ceb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094ba3e7c34d34d089f152718943e611dd6d55f1b87515842ff1159755f54521ad44389706b1ba53a2dd1562b08cf7ef00000000000000000000000000000000142ce57e9546541366ce7105bc08f9aa3fba88c713488ddd9eeee1a01e42f43d21f77c4e78dbf214a1331bf85d7109881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031a0259782fc7858a1693cef18b1f0a417d331f276c09ee24c3a7bda56cec32e9cc928a9ad94dfe73d7c4fd7f880aa00000000000000000000000000000000009aa2f062bbde2a43719802a23681c93b8a30a1f6e831fa5031ed714cced335338d368d4cacf149a8218cf7a1bec7e6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a90b55d5b1ea865bff9a24fbe0b2784223af2ac89e650fee9089f6346bf8b68398fcdd65a3692cae226edff9d5d5be0000000000000000000000000000000002318b9ff0110d98075177c441af7cdb8685924d1d0016141502b6cb67235fd2ddd7a8778576eb21570b9d7400f6d2801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000790b91e65e8f72d54620a4a9909461db27a50c3d3c6a617ce012510396c3f5fc40dfcc39dc39b41f2bd4306a16f5b6a00000000000000000000000000000000089ae1065da7c181d410cda0ef8fd73a3eb4f93b18952ca9816819498e4523bd02b320917432de5c16c12cc62fb029261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012239cddf03e892e24cc685fb69ec606436499d89451bed33fbf5fcfde2346a0586bcd1f6d707d856efdd1373067fcd600000000000000000000000000000000030b03acb56905dc505e6a1fca8518c4abee498eec5ab6190a2914994aa43a8e7cae90289d78af17ff8e75e547b1e48c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f324fae49476c33145d1e5c7945b2e8ad1480d626238ce79483e041031b7a892234713b396df4cf9c331a2a433052900000000000000000000000000000000094d8615289244960b09f609bc326f6fa65e4df9f18627b9fafafe4e24b078fa068de9dbbe6b873e32987d7689397ee41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5efaacc23398c3bc7c94494b726605b4c6b50de59200e6fa336fd04d09a021952e27ca9bed41e5ef65e3bf7d485311000000000000000000000000000000000deab38e2665ccf482815f3d873c1cfd5a2ada6cd5242cbf8b63f60e2e132da79a6f4e75d52a22cb8e71fbb578a31be01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154bbdfdb9b004ce9d4aca1206616b788bab2e4fc34b2ec238d174d6b4625080f6ae62fc0eb074815ab611f6caf7ff690000000000000000000000000000000017e1892456b287dc447af8326f764a532eb9046f76f3f82779f30966e72cde734199d9cddf7271749659f8b2ec9016a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009903507237c5d0dbc2b9f449d02646e5036270bcfebfa4ea75baeadaca336c73cc2cbb316cbb13d75522807096da592000000000000000000000000000000000e28b6566f0191af4af5e00851aa32517a3b8d11e04135d1ae7f2e846be466d62d4f872f5dae6ec9c88d9050a3ced9161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d901a94f3ba007f50f6ad201f2e3fc987d59bd975af97e8445bdd97ece929e5c4caeb25e6e47263b4de4bdf2643be0b0000000000000000000000000000000001e8baa00a480e4fa4494b4eec0701d0f8a18b29c09c1e195db40c8a32ee3f4696d325138551a881172916463de66dcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131f465d71e863f700c96bffbe7981b1a99cc36e6ef552d20702ab8d05a6159713ef524a3622a527778b751870a541ff000000000000000000000000000000000f4305e3c3bf73987d3a436f5865d254f41bc441ac9f981f4d4c99123247cba9ca25e574fae5e91c390a66b97e4dc1e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175df3d0490b6552bf3586d942d325e3409b536a178bf661d74b09b1b11528295c64b0e6108f972a498a1c7211972497000000000000000000000000000000000285d7d92c26cfcb6490463261441d80b2f7db507661f60c4f2fcfba5395a828fd4cb161caa4807a2324ec32d579695a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a337ef7c201af544735c98b476e399b3a8f8d7d24da93aa71c87ecd9159bec2a27250dbf7266a16070e04a65fc99af3000000000000000000000000000000000d4c907d884a60750a286bea5be8431b34dc2fd176247c454e512399b6619429c5954d0e2e37015f39210d9f34ad58ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3141418dc7c3d920b4632b0d2d130ce96447c23e33147873a0f09b966174ce87bb79693d6a9bcc6b244a94f6e08f2400000000000000000000000000000000009db9a9987602cefdaa31c4d989939416201c8108e3b2018fcb2a16b66f2c6467f58040b94e06d0ab887d9c43d440fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c31630dab0e0267be1e851d53879c25f9d88ac00af0d8f954f49fd9f7710811ef73d765b7dcd5a5f65c69db0e9af4680000000000000000000000000000000007f574e34136fa80d053ae54b09ac88174293ba4c11e2dfff0c2fbd71c629049fbe1ba2d5f273e7f54315e3a5f5379481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125583fdc8108e2fbcb99e7e552df1df1f4cc1391a199367d2d5bfb2f0e668c824e211dd870656069a4acb31f7db287100000000000000000000000000000000000e8c15c242d3b30898490e770cd234a06548b538641c1d6a833b8a78a246a8868ed63a345726c5029a7cc4684cab201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001060e5b2bc5f77f1eaf14eddcfd26a9308d13b301babe482fda07530015b1a3f8e4f40378e35e9d7089429c3681fed7800000000000000000000000000000000040019fabc6d8c43318f76fb0a86c5cb52c80d2353024028c0804d67bbd3d33eb1870647233f9e84e9b9239f5ca48e541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151ff39e48f25ddbe062ff19598bfdfb2822b7e95d6bd1da15692837fcc09187c70188aaeaf86321f6f2aff8f80ed15a000000000000000000000000000000001376c76e98c21c36edda629dd0e97a3fe7e4d4afe0290a4fba39b411f756dc5b29eb2923f624b5e28a69ca600548eb0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb951d73ac5738e7017c387608a414e7361b2856c8a1d7c31f1a8c8914ecd567e3d0b83114a74a84f28f0b42fb763e2000000000000000000000000000000000743e58183755d438540fec0de9bef9f59fd38d2fa8b63ae397991f76f9113f5d64571706a703124ac580e6960a2d50f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9f25ee7f403ec7c353362d82eb250b37d97c1e261d8ea93aa5d0357e7b89182c3f194f240e1eb3a55595c1808279e40000000000000000000000000000000009f6d611a8299d79c7b95256ec0c486049596696160264217f3c5bffcf510cd2bf9732c4a45daa4b989576c04c6b59211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b0e4bbb5cd184f068cbe77d39bb5ebf6ccfd9ff3005ce2dbc0c97650179beb6757952c17d54e9a56a77f4eab6f970f000000000000000000000000000000000c871aa76217ea83a9cae63fbbe08b82ea2fbbdcb3dd182dd397f25c683e58ae3decdaf0ec30d77fc21e3014608cfdb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079d34ab1059ece3caaeeb1931834221f0d09e9d92003bf7d3f2827e2c1cbaa1c14f59eab12ff64cab4e3e376c3bba2e0000000000000000000000000000000011b1087ad170c12615c61ea76052ceac6fb6e7ceaacce91519975d564e26ef31b8af1a4b423920cafa187df4e0a4d3811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d19a1ca365a0c41c0d2c7bce87479ed493502413eea3b723c5563dd457a9fe3e9b30fd32da7b6e243b828243365fa800000000000000000000000000000000091bbe83570387ee0090988814277a3141afceeb7a22ebf868297d1f6ead99f6e4ce4b4c14f722254917a0941a753ae11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f7868b12ce590b753053ca5ab698e3bb46b881668fcf5256e676985c0251d645937b124f78b1c6d60012f85e2b57210000000000000000000000000000000018e156282bf224311a9cb5c37f5b473489a985996a2c234ace771cc953de48174119ce057d3716299969baca362305241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bdeb9bf087b5f0d8b0d637d6688f30d9ecf45f2a44fa723cb2080989bb50049a9efa5d03d27bae2bb2ef55784d246b000000000000000000000000000000001629db3d95e96e79ee2daae6466c1bacfc7dacc8142f9006c44c8cb38c07b43847615cc96594e1ede4df6f3497a442be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061e486c3e706f7b661ff29e10086df6ed632c1922f35e6507f84658041230b2547335f3683a66f658b72aa683dc9acc000000000000000000000000000000000e09c23d4e9a4a80d6888ec63df61dd4eb28b0274d2da0ba6b54a958cc1429175ee82c5894247262e78e839f2a720a251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000006ea7fb918f8a472f6581b53d78a3474fa2c5ffc3871db3ef30c5f197c5d914b8243293b8d4b010e7e6c0e0ee6fa5670000000000000000000000000000000018be0b8edd63228e5ef968d6f65e63a0aa5b588231e9991fdb61ef429443c57b3a1e3a6d430ad61aab48a08e5a9ca27e", "Name": "g1msm-512-jwasinger", - "Gas": 1069056, + "Gas": 3188736, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000113432aee77ba2a2cce46320b0e6b6ea7f1e72d5089189ee383fc282ee68e121464014f2d8cc1ce9589e4681d84389e9000000000000000000000000000000000b77a1adcbd5037e3cd58e0ecaa34fdc5fce2f9cbedaf7842ce88feb585e93f0f44a0c008dd61b97c2de3fceb7e702621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019365a84f7f18cb1f77621838b3fbe27f988954d10b4761b6f7b70fcd97c4044423dd2dcebc4de2e310fe6e0f9ac53590000000000000000000000000000000000098c84ae8985cc5a3b7abc99330028832694f98a7a1be3e20a39471c20b6b956537fbea455f710067ba2adf4fc70db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc2cadb6838504a5f72728d36344461e9c750bbaa5cdec43b4e0cc8357e1b59d5c14096169fbaf73a810a9b5195f4550000000000000000000000000000000010896fbb1229fcb031bc75710f543a108065a58d44c136f7d8d948b9c2b6d3726f1823d16d6263b2df8ea8277d511c8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044561988e8841270f2507a7df77cea2c297400c2fc5d62f589312e9bbb62051a2e7370a5d1e19f114ff4b8c6b9c2f8c00000000000000000000000000000000147510462aecae094f843673231cd3100a2773103c7d295986414b7b8972ccbc4a6de2fc63b47e3749c1c514f57a474e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a3fc99f05b8c637e291a664d62e6144cae845146cbbb9771bf3cd542c2dc2e9a118cf06bf3342e3aef1edd17c4c372000000000000000000000000000000000ee1b77b299a4e94f11da54949508de1db2e6255ac1a66712b8cdba1e85b5ee03a9d471afa089c027333b5f5805ca0631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143f9bccd959d294e7c216fd8a036fab7eff35f28bf07d71c7f54d43adc3418ce79223e481a6d1f972fbcff544308d8e0000000000000000000000000000000011f92a6ee225f73eaf8ba36c11d622e87faa14a8a90f56106b92e9a62fbfd45759fda7085b565b12e0b8237d0cd5aa4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c0ef9097e37f2a86731f7c5911ed15039eabd8c27e1d6a64d87a70999c349eec724e13c32cc42578258e0655030f720000000000000000000000000000000007f0a5c7609ff876553752f61451c347a654fd8b031d2850454882c8fa0d7150843310317474ab276ae26e4ff98971501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191fcb881bf42e69891d5ebcaa31c2a3bf5be434aab60d9bc5054c636f94952c78a7a0c11f24c6f81f80818cf008c8ab00000000000000000000000000000000141ecbf1443a22a2f84ef25af0c86b94ea22421813f2611fc3b10d9dbee81f02be6035e6bfe6a584260544ffc5c87eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019481f27232878f7fe934b5ddcb8dcbee6f8188ce95d239016b757e105558f8c2e5544aa2cff848679f51b4963fdab030000000000000000000000000000000012c08ecf9f478bb1bf8ddf2c604dddbc42ad64d38fc7929e0444e9bab55784a3e7ac10bd3243a42b107f1dc6727326841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bcb0e19234cea0c962c31262ed250edf012078bb7239ee2013343a20291465d1e07edf6147660b9438bc67e3fdb808000000000000000000000000000000001694f48838c54e757ffad3cdda14bcdeab8bc262519b66519e0837c5e096985f4de3df7a96b106a9409323fa353d50da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013459fe4bec1150486ab637852e20167b2710237a68cae58d55e05576754d6f24826e6cb70c13bf1bbeb9475f0d724fc0000000000000000000000000000000010e6e256393e308886084f0dafb8aaf62c66a8a047a1988b0cea32da87ff54de090e437ff401928b70d21f6e24e0cdfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084b0283a379c20cb86b5f16a19ecd988d073399a6bd079fce82286084b19f28007b78774be69f2a1bf9e25746b5041a00000000000000000000000000000000066a1eea5139937ae5370c2c2507622bc68f7f8e4caa516a77affe736ef8be22f319d9f37cdb999836e22b01fefcae761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010e858a7463c73d1c1459306d0bfae15d798ab6f84cfa69a2631011b7e54d1381ad5cd59e5e9bb21129233258a4e3480000000000000000000000000000000012803cafa2fea7989674d1b9565846ca506112b1a30245f653110ead0f786c9d5f8cf81e7415fb76b4419a08bae40a131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a25429ffa555112ee05a9ff02fff3ca4ea6aa23c22860a3c6892bad0dabab19fc024d2eca336a634529f381ced696f00000000000000000000000000000000083504d5a4e30bf78edcb43efecbf27b4e1825975108f2358634d34b87826c977d5e237bfbd88a7e329efd616ccc386c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000444ff3d3a8059f826623fcf31708ebeba63213568c01cfc5d84c6671d0c1849ef0eddfdc10b84d8f9c92c3ef111a21c000000000000000000000000000000000870a8448d00a3522bae6258e56fcce0a860268cb1a1b4287274c5ce1c46df3cdeb247aa26e9a02ff06f1a78df62a1161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c410231302d2c3fdb6149435322991e113e5e3a35f00418c9c42856cc4334759310476340723e65e41d244b06caa4ea0000000000000000000000000000000003ac8d2af96ce1892e0309ea65ea28dc9080a28048202023e2a1068ae6f77050d10a8e2603a5cad03535dc50162d201b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d93d50d94a9ed3a0df2798d380d726bf0215db6594187626d56f793debd40bb89bb8ec3016be41f4550d3d6f9f982b0000000000000000000000000000000014c63ce8c29eaca6fdd5d2118c741137ab4c3f210460dda3ee7d47025ed041b9857b5bd054d9bab131fbc95bd334be821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bdae65e2cd1ebc8baf215c47eed76ad0e2aa6a3ade22ec8e5576a66cc07d0d95db9b0677fb3d4a4f91e8e491c90cca00000000000000000000000000000000135a9a76d97c9ae1de332044ab9b136ad9d432a37f8ec6b3308fec708afe22d6cee3c6cbdd5b82f9ab9b3ec787b697711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5929dd20f1880ddf606baa8dbde4906e382d12cadb4b04ce8adc06cf2d983cb7491acdcc33414c5f1f26b508d3429f00000000000000000000000000000000035888738296f8fce34181526f2235add4d54942b0c6373fbaef9384cfdd3385d5227862e023d29fb571c2eefe0f5db01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017aec438a6e711bf8c2b38a668f67a6de03c75fedba39576ef5a148cf9e3066717ef402f8cc0b9cce2296e866d59c570000000000000000000000000000000007ed2fc97feec8a3cb20515bf18e1082cd425f2ad0a56a24ecc06f030479b82293a3a12e7c4f8aab615c1f8ba08ca39a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fe02fb54cdfed3c73f51b4c7936a82421d3d28cec40c647b0ec2388abfd917a7fa98d686acc128e1b9a8f61c84077d00000000000000000000000000000000088be45e91eb084b6c04bca12f27b58a21f5fa79955bc8ecec16f2f63d76abf1be188640614dd56cbaf2d7d96ecc8f061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf7453ab6722bcfa9b7888785283c2f1316dccad68a3a36fd6f6dabfc984b03da4a27df36101052c54bf9f45ceb59ff000000000000000000000000000000001473e2050368bff88f1393a8f85e91e29b705045f73eada886149c1321d907c3cab9d16e6ce62eb9d0dfb06a3cf5f3df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055c06d09464ca260b636297b2a10ac9a51abe2a3eb31a534d0d98f7acd5b9ea6fcc825e9507cc3845d94728d0668c3f00000000000000000000000000000000129ed1aa5219dfc87fcb406c7a8bef68878a718f32b150ac63e9e376d5f5fd93f53ed7e9d59e1963e00695523eab47661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001183182fc93c8593605a39eb4c386d27ab3e0421d092745e2721f3b63a639cd5f339a53135179441760189105b2d9a92000000000000000000000000000000000d7ed44b0fcf1bf597d90c248888cbb8bc18379a8839c1dd8c6ac2c6546ce92a9a9a0f2b178202bb3efda39547ce21bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4f122d6c3d10379f3c218e3e2dde647906d7a6c59b6521a368de00739cba713dddf859d10bf2b50c297799f86956b400000000000000000000000000000000086f9d93d7e92e57ca74f63f9e0bc03e21d1db120c59461e945655e3aba0b40b878dcf20163da835647be19911ecaa781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b21e192894e4fed3ec6ce32d1c88e67dc0de7469b2e0858242320c3961559ce9d1374da0f949a62a68e356a63d63e0000000000000000000000000000000005e40ecf59ad7f944cb4da0c032c431978c15b06f31667cbc84003b6120b4055952347ec829fbc1346b194cdfbb28f771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fbac2f436836474a126878b311b14d890d97dc5d652e9abed79149145b9a1000e574eb55508c85d8dd92fc853721d0e000000000000000000000000000000000000be9e25489d986d674a0b670bfb0aead1c2434142025c86fad81d61e8ab31e68b97cb43e980e3ad6cf9c9f1ed2d091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fdcb157d80318b592e0648cee81f665de61c6bad4d95e6715d8d47e8f5af8f9d934b114a49182b8a89a0a2220481c7000000000000000000000000000000000bfad6466fc3412296cfd923d7855459a28f6216e18a2b04887b5402456d6a45fa6cc6d2a0f5c990499e9fa2f542b4201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006343b246eb41b2025529103a01fed93b3166fab4a8e443651d0bf5e5bbb76b918aef6b462c20a2a9bf209db2a3029a3000000000000000000000000000000000913538ed2dc347af51cb5ca9d38503dc8a61af0dfda6c6b10915c1a6b71e6b877e78a9c4504e0a8abd92eed45a4f84c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140d8df747c9a38f2ab269a09a98f574db42aad68829038e0e6d68084bbdd5bef03416e62cf6a83cef6763f3923d554c0000000000000000000000000000000010897cf20a0a2265f3c6f2b46a209d9392c99e239751840cff7401139770cf79a316a26667694d044e8f56f3aab1f1761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104f01786601a06fa2e6ab9b5521345da3affdf308f0700eb3417e68ebd0f470498c897f8bc7dd4865cf462dc8a2782600000000000000000000000000000000157085425016e8a44d2d4dd6690bd51609c7487667938aef9e2467b08b83be4b4337700bae58056563b739ab20aea43b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018e8ebc052123fb4c2be29c93d1840eb76d99e24950765860a2a55ef0e91b510cafbb09fc23e899f3abe969869ce20e0000000000000000000000000000000019bed2558f66055a42a9a4d4b8cebaf08b528b4eb07024d1c23d93785e36603cfb398a7bee9b9685b6c7a6af3e5d07961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a98a69c0ec3c50f679ed1a9e2fde094bc4b7ac1ab127d476c27e93ebe4b3f7b772c568b1c6ca112d37b11296fe42980000000000000000000000000000000002bfb6e4f34be8c0d56285583f4ebc50ffe1105ab3d30f5b7eded8b6f7c6bbd239a65544a189f023f37487303d6627711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181165c202d0ade64c98b1fde43221ceb988f360c4d3fc1a507786e9eab4bfa79dc2924fd8bf178b19ed7b6ea5432cc600000000000000000000000000000000189df594b88f707ee4f1412a816aaf71b15fc82fbfbdd282360fcc3aef1e76a71b82237552bc68a36bb67f869eafc6421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177a1edce370c8378fc34354383edd33764fa82f4f83d1f3a03aeebfa34fed482fa7bd6f2de0b208746d12fb7d02b2a6000000000000000000000000000000000d7784702b4e48629c14770b1b2dc2a22b61b65d1abd088210e5d2044cbe1fbdbfa60f241611f4cde3d669b65f166a0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154d45698f34f675ac31e0b1cee2def586c59504de43a132a859c50454ab3bbc7f030cefbc06b0528c60a3b72b7e14b200000000000000000000000000000000185c4756f344083a8bebe9e418584e4e642f6f16899c4cffa1bdbf1ee8e325fd48931c43e5c76e407912c110c1a5aa7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8f6902408cee5588c0a4d930c1a7a5c6b7f958857c354941dc2b6e74b1b173ee92345f8279cf901c6623f9279c0aec0000000000000000000000000000000007daff042757839d806e3eb43bb56bccd6ddfded58b0f7e52a9c31547e03a0f3f813c77411b235359a6ca4183d964ea51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe22b9dad98c514fea304fab0401c0b9fddc0b3bf1ce41cf14f6d50e33c723f5b343743249c3a9cc90753c823f9753000000000000000000000000000000000dbbb8f68acd384127897b4dfea0e609175d82745d0a1680d3b1805047a6f2b404fabf29fd471144c3b73cfc403c19061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022427f2eb79cd3ab6f2ae8451d3e923e8c27c9650d78b94dd04ec634b72465e779730df9ccef798d4a72b6172fbc06d00000000000000000000000000000000155ea660501bb5bb86a4a3b68392f1acc89b5f0fe2a04356432476bcde758e6318c471f08c5a7cb0837be655cdca3ef81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab6d2a9771d036da214582c737ce30bb695de0c24a512bb24abb52f25637f086a7933589b40de0121552ec066c92a1f00000000000000000000000000000000008762f9d1e83834db8aaf7e267389dcd7fb5c70c9485e306a162a58cd6571224f234e7c1d7003f9ff42773f6dfd72621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bddfc8a21a151c6eba652a098fc5abdd1f81b7e707b95d3ec8d8eb57edb7399671333f6742adb17e314ccf8311503370000000000000000000000000000000007888d52c6c8c847a4b81e2fd49593149b1ba0f4ee23accd4caeba8ecaa4095a1eb3a61fa17bc50c545bebcf77009ebf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e3847cfa6ad889c68c1c09f1ba6a1631e16d92f4457ae2d062f539745cbd8a7a3bcdd80395a4d91dc9967b8c8996060000000000000000000000000000000005040517ef8fc9e4a10343443ca1cddf895a00414b727e2fa032400cd9180b80dcc10d9622ecb76107c19c2555a685c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a08b9d581e8f1d64d2007926baf9212201d2ac9c8fd0be47f995a3506cc9b0e735d5ac40ce3dc774fe1b2718bc7d7dd000000000000000000000000000000000b49b3a823b9cb729509296121d99255e96da30f07857dfad0b99937c8743b1bb9261e0d03a89023cc0bfecc8192fd571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a40653b3a13f5787970933ee2ed85c24999dcb8b6bed5f6bf593a7709c84a71a0d5ac6690258ec1c47351648da58b9000000000000000000000000000000000c6c002db3d832c376a332a7624d7f2e69c718e16edb69e177560914ca42cdd3068123d92176d161f039f7b007ba05341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce4e524e1b89f6dd89488a847db170fbb0bb71c12f4198dea1d9e2254bd6f62393e12d358f0abdf4815b35b831eb5aa00000000000000000000000000000000052cf89e2dabaf87205c0b79f05d0ad6c206d62ebefcc773abd6a2fbd30ef01d7c8e190c54c1d2996173dc64598fa1ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b694d5a6149aa513d1aa60fb0abb78fd70ddcd83ca903a424435228f7388d96eeaccc4f7be48c770f3d9ddd2bb454d000000000000000000000000000000001956dbd36f98408bc3f2f8ce8ba4397ed636b6acb34db868d8bdb65c1bc32e5f3f2ca92f687c400741d2ee0ac1fde1ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f20e939e331a538910f8a17ea8ee13fa92a2936dac48803d076888ea12d19faee92f7a32ac26aba3229e4aa567f0c50000000000000000000000000000000015fd09c6c9084d2e8480ae8be516b77f4ed2158980851717adcd24bf5f907bcc4ce9f7fc0a6a5e087444fd1c1342b30e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d3c5159c715f8eac9e65dcb0f178900b6bad14e1e944d86268de2e043ecbcfa807a8912620a7e7c423635d93d458d200000000000000000000000000000000072243dab541568ef69bd010ddefe90791af082efc2172c9e43b378f330ea17c817397fb6f98ee6607a17da9d41c0afb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093df04313fd1290d6722e992c00cb5138337270f34c3351a486a4d666233744e2733d8614b7c95dc6938b9001fac32c000000000000000000000000000000000db734a72cd9bcba0d279cb583c521f74dfdc2744708e9910f0f63b3b17f9683cfa8451dba782e350c9557a0676573501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015445ba4fb83941f77be59e0417dd2410b0b9e224e43fd26f043ad2df77a5734e8f5488f0c4548c572b697cba74622d00000000000000000000000000000000014c5050bee65ef4748c465cf01b8b508bd41177330b8ab9ed17b07675f3f3b43a18de0e9f896d17352d7df5cd75be8481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015af83c28bc60242354dc3baa0a79bb1c371d2d494b800be7cad45e86b0461e4b60115e9f623b64da8e613980e222f31000000000000000000000000000000000021c0a80a5dc0c4fea6b1b91fec9ed43415e46d857f1d888c9807a2d535430cfba8de69f447490763877204022cf54d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184eecbda7e39c7859dbba6dc1e9e3e8f87f03c34bb9fbb621f5e92c23d2b0238fc2dfda8a4a1ea615eb78ff86db6af400000000000000000000000000000000113bd9a35f542f0b7ecce296de411d64e04a38759043b9df839bface16e1f0f42338d2591a540649b0b4f5bebf56dc4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000605ecfd75f47c629a38ecabfe4ecc2db77d0ecb9acd4a9ba1b7048af28c3db85eff2dee65aaeec6fb29b9a204cf4e94000000000000000000000000000000001482315d581689fac95b8351fa06e8f2b1cd59cb6b0b563b688c622af938a7cece02e74044298f60c605a430960756ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012240b484e38b76bd60b94a10be77ffbde50dd4fbe7150557124b47bb68286fba69de663cbf3467aa84675b0d486263a00000000000000000000000000000000172695581329d3567fee2e2288108d70ee0b5bec850a737fb00e9c557564542de9cf35255770bed75331991007f92b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f210c70c40d79c0d8184c721a1ade9844ad4494425bc3c1b02d8c968dd234e21ef29bbf36f630506934ba3e93409df00000000000000000000000000000000010c9218dc264a26807ee3493eb8370e5d7efb2866b964088db496900979d3df359099b1e36f6b8afa3e2c1d26e07383a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008eeffbc6b3a06c83e21feb005de9e5ba92bd26e0fc1c8e2f7369b77bc494a0af34e751f8ee4abea5c506d141c7c6ff0000000000000000000000000000000000c75e42c02863a339c9220915a34dc2ca2d896943726c84698272ca902707e4a6dc2020d172ce7e5eb1c892b4b0b22c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bd10978f04a6adb74695422f343275ecf332974621989a359505d62537b912af08cdcd63bcda23585102c6108f8052000000000000000000000000000000001292a95520a356c23052dacf5e1373a9be815ad997000178eb6eef7788e283ffcd9c320b8a4fd5b3148335b2be5fed641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001185aea3296220a9ceb68269091ae746eac8558789c0ad155639c18c8463ed6fc085d1f5b21974e6ead398ac16145c780000000000000000000000000000000013527ae006b2fbccc4113802d7f22efbe50d50c6d528a5b99e87186f05f86c5c17b85a747a579c80cfc5a5a94147dbe11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079f54abcb22678de04f2239c38b88f96493628648f76bfd3fea2161cc3536b426facedaa35ac353eb486e7c273f97e4000000000000000000000000000000001664209d8878c122e7c02db123d11b51af9d053a36c42a98ac755c50829c3039885da926d5207d5b18b4aa08bd3516501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d35674c08b74967e1e2854034457da8a2f1be3f7da40dfdfa3ee80588d69abb7bd793d49489a65e92a95ee945f7000e000000000000000000000000000000000141322e0aa7557235a45e230f8a28daefb12674a7eb7dbb2c7bbee8ccd95fa447d4e3fb7a6be6e25f31b0a28f71c72d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000be8e10b614cd9be2a7db8175aff0eddd4f28286e5d849298b8a48c33dd877dff61bbd2d5ad2d0c9edfa765059a8bd5000000000000000000000000000000000f002dcb7ffa031aef5dbd5e266725e5e2403fdda2f80b08d30aca2709c8c8dd43207ffb18cb046feb793a4a650cd9c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196d6359f304311747b27f7280bf90c5d531979a568bbfe3b5ab5320911472c60ee102e9cac69961a5f45815d781a48f0000000000000000000000000000000005f672d6f95db206093ff62db1bda0b6328837e908d809e687e3a3e19eb09f2cf833ea6b5702cdea4d1ba8cb89ddb6451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001562c20fd6700d55db0d4acf937e559e1d8e9bec5e614feded03fdaefa3047c4be5fcf0ac69cf3648b2106b10677d48900000000000000000000000000000000086ea0df6f5e8834455806e7ce2cb30e748fb2f69cb0094b7aff152f55d81ca8b5fd0d4efe94dc4da9ce9b73d97b4d661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fef2f1f685f6421e706b14d682650dcd23472216da2c666aaedf818d32d08cc6e4bbbf3e9005e00b4b76f9da8ba4df20000000000000000000000000000000002b6dcbed3a686ea536ce33f8e0e197cbc9178eb16bdb69d817a1e18a60524e725aa5c94b6eca4be726830627a0f75591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008915dc5dd3201dda1c54caccc8613a5bf9f6e905cdf8b0db6058567227d8062d357abf7efc219e70eed2237676deea5000000000000000000000000000000000bf05246d535971006f72cbdf9160150a7fc10d65d92c4e5214e818d3cd5e338f6d284b53f09da5e18f3fd0f3eec201b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001499a1182247b508c7cf165ab5311ef642aa661428ec0519ec5eb716b7da5e1b4c0f37e95af75734ad310c3cec7d89ef00000000000000000000000000000000114c1b503c5bcb7e85eb1d7aa6a32864762a0c5802687d954c9557d87c706f761648f483aebd324bf621f3fba09632001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c87e933975b84c5580ae94372fb4a43c908fe00c8b30ba04eec29c1099a8e273a6faa2b3df098ea5a0a2b1dd05f545000000000000000000000000000000000a6dcfbf00e0c0fe0e9801da72f5226886b0795312c30fb3a943a5f3c3299f536ab412b900fa2d60b757e7bdd601b09f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7e49b90d0da39fa012fc70345e0c7ef85af8fb5e9e1aeccb7e4af03f2d2717fc43935252fbb7a64d77ef727d33ba280000000000000000000000000000000018a20334a63f2b30461c8bfd565c38de0c960747971df349d6b5ffc91aa57685066ffa32f7e162788391f6c274b663ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008c886e44e41bd6c10226622080e9053b6a3770ce7be613686f2066c0f5f1395462ae8bd8f11f3a47a22ba5edf642e8000000000000000000000000000000001260c94683391227bfdc2bdac233bb1d839a4068608560b793b9b3d91ce5c7e96a589f8d9ca4ab57ca25a67a6a308bf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dc64a86195da7e8e8712a4f0c7f57d77a70d7c3fbba01c8566503f7d15ab739e2a789d3260e2e384e8b7d125ecd549000000000000000000000000000000000421aad94c5f2b46b862c776670b670b4086339e31b08500a8bd7d06fa9965f1cc604feee092a2652a96e7a164c856b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bdb6dd88e0ba4988caa2cb606c9b1e6e98344d805ff5fb4b0014616bb4fe2c0d84f34f9064c9ec971a86103aeae90e0000000000000000000000000000000004c6fce550949da34fb8c104cc89f24ee6bbdf3004a4cec1a3ce58b055da7113ffadd70656bd89ef703652306de51bf21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008344155b08fecbdec477d3bb7f83979057cc5c7dc8aa53a3399398fba15ff5601eb1ffc8a31bd1f8049244b033bc750000000000000000000000000000000000b9fe09e19e8719944a3dbd1aad6d11cd924167767c1c9315a1dfa55dc6600ef7c1b6b9db20553cb123774e12345a80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008ecd8a2b42735d33152aa4c5c11d4d70b56f3bc0cb1555eb4f7697d8ea9c5f8438547c9981dbd87d20e4a21036cbab000000000000000000000000000000001317f8236c13d28ac0e206f4eec23f90c357f7c5ff180ca4b798c8847363ffee3ff9f840603f274eab38fedcc276801a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116977d08deab67c359b70ecf87b407201032b592ce240e9ab103fa3730ef17bb61efc001773ed79f037e0b87e58d17d000000000000000000000000000000000878d259403fb0d999f6d20c2e78d3b1568731796349d7ec0a594c8ff1578ca645e4d93c565979337a58c4a917bca5631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117abd010a56a8aad7f6280008984b524ac6752e8028a4fcb7d5430445f73c11e6dc9a33bd81ce01ba781df85854b06300000000000000000000000000000000105e85b8620528f679109518e41db3235cad73c09f471adb3ffdde641ce6e17a59c9ef26bd656e915f82712c2c001f361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a32e87394abf7b7458bc9f70f64374be673c4008f37147c5526b4597fcb5bca5e5492c13b4599e31a5a3da459e95950000000000000000000000000000000016c8bf3f7cbe1e92aefc8f92f18e62d8617d2d3c49991b5ce2766cd9d76a4c2a5fea1d14a7e6e8b6873a52958624b72c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022694132a2da8e095339a2013fc6901f0d7dfb9ae6dbdb10ce229648c74767bf327ef10f8fe9c07b5479451a22e7d8c00000000000000000000000000000000049702b8cfbf1c6709f49e32c88fbaf2f43c293bbb0052ce0c84cf5aaca448c43083d8f36bc00595fa244ef9d21dc6ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb3e0b3288ece732354a4466e8c0e754dbc266fda9a48c21022ac2666b64fc8cf2d34fb21ae5fc025aa2f80302f93d5000000000000000000000000000000000ce933426c03433b3610bdc3bb587b5ee7b76ae3ed7bf6d657560a0063e0c59682bb0337b627680aec5e93c9f053928c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001257f5e39eb0b6c5360fbdd9310fe5729aa1ab13c294bfc328d8b7841dd56d3dd64ce0e7dd399a0fa7b91fcf660ae864000000000000000000000000000000000361262ebb12e109e6df9f0cd5c1af780e4f0312afe430c129c30bdfd66531e85556fa20000b87c112766e67a7ab27e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001165cf72c679bece8569f396986fd404994bf7ff53a0e6d1d74bcb6b41f552df77ed03cca215da239c90c79b1ce0adac0000000000000000000000000000000001269f0fec516ab43406124d602848f248e4c5331373e4917fb4e0f26da3c882092012a3df63199525962956255c539d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001544727d3e43974c18d9af31eed8c7d63a122d4bf6b1c23183b0a2654ff858f4b2660da0c2c47296644d9bf7a83a6e9b000000000000000000000000000000000ff01a6ad1f7900f0d0fbe75742b7688eebd4c85c7739cb7bd12ca5f6ec57168b7764b5dd0043591ab919e19b64601281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bd5845872dd61b9a7a316e041994e7324d1f6fe3461f2050c310a47422f156c9986a4cb2fdef3d358a776648ac9d6b000000000000000000000000000000000f7ca1d07bf33f980aaa4909b655d31f4b5ff5eb47a44c21ac68cd08f8d161cdf15cbfc5c3133232587f5f54f37034b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001478c800c5cee2c9ab44b5d19692e8190d52da3810fd1b47d468cfa7791c182fcd0a015c224b1e17ab969238be5c583100000000000000000000000000000000113abbad4a2f36132c12ae591822f1a73db6cf25f5ab6c57d6d512066bc3806d98454f402ab52ecc644b642dcac69b621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a29b9fecdaf1e48febe612de51145fe781e1b2b2eed789063fac100c39d6a6d096e8e27fe24b5d3ddab657349826496000000000000000000000000000000001673920727133074499441f8770e82b96a7a0749bcfda944252df4b603829eb5f3b2c93f3ca3ff14660a5a137646b6141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a3b618640c6d2a1d516d542dacdcb7db327ad6cbb41bca7b665a5cbb4994858ac56ee78a0c8ced274e5c6aa3b6eea5000000000000000000000000000000000639b3d87568535dff6312b1169dbb2169b16b99a4008002c145200cc384c1dbf996abb4bfc71e36920d571bcfc08ede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000678889302af0e4bed48df91d0a7770f298cd9fcd215ee2fb52da359b140438c8def6765349b006f879a633a12de5f300000000000000000000000000000000012ec8cfa008747745e883cdffdc1a1d91c828612c6216c92327967c0df663c99d9b756846dd44a55034f37d32be8e8081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfa7120f6be86d48d1f82639ce83f3b8cd1e71114102fe9221558e08756a531f969dde5a9fabbb5b78f67a0c652bccf000000000000000000000000000000000d8b59f918abb02b037dba2c59ec48a0ad46729a91c81529b8f2390a7fca8ba67e20874debfd6f86d66a7d748bbd94241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001942d7c60646b7623314a86355cc52a2d4b72a4def9f397a99b5febaee2eea99d6fa7c60d1fd76707eba09a09a48fe63000000000000000000000000000000000aa2ea821df89ee7ba8b490c047386ca995caa2ea201b18c14ab9fc5d174b0d7ebc3b41f950af1c64439424b5f0667af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c9d3923ca8e139254fdf62255ae21159b59452db864855eb0138fe758e904f17f94a19e860df8a96ce167bf1342094000000000000000000000000000000001893a2854dfc30db00204e70fd63b1646b83d0cfd720c3b3a404761af5017de0487faaeab6d8bc8023a5bcbd96440a231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a7fec282b395dfcaac44dbed3a2534ec3686c81d755477af8adc7bb479d27c8066dab16ce0ae6ac2921229f16e4366000000000000000000000000000000001937728fa858ca5e8e7567c1907bc264907700f0b13aa1b491133d5a8a265b35bfa3bdbdadc2f1ad32e6029551565c2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d253a6258190bb98a76cb607420d18911ce90c3b923b57805921a96eac0d3b3b1ac736a73182d86e181b6142426b110000000000000000000000000000000008f11dc67689b83bc842002ef9f8157ad55a60012a5e50073751450236570f729ef3a21af881a3a39f8fdd5985aa38511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d64520da7370ef20cfc5d34e9de86622b94c203f712c5eab878ec29d88d75fe913cb81eafaec739aa61ab4c705402f60000000000000000000000000000000004725881b121f87270593873d8e5db53a69f38c10f2756d8ca284b803274981670994d24613649ef2f7301291b90cb131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e31638c6795a18435328771a8864e9cc45d35ab9c34e5538d9856bac392c082fc8480af6573eb8c11d451e6e999bc1200000000000000000000000000000000162f9055f0a8594af1b6b4fed3a7ae893936ec1a5ac31679434a6fc724b62e8a7611d352f5da1bc8adadf89d3b26053f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d56ef89cde69dde26d3855b57825c71c6b15e777bef338a009a54411953410b348ae10c26348fe58d67fd903419a8e0000000000000000000000000000000000030ad2c93a64295e83dfad68e46b42bef5720b2bd37bebbb753fe23eb44b15717f23f11bbce3be62272120b03e95b831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100796a5acc9ea29b98914bde8fbc092afe381df3e2a5303f52a82d2e341d60198b82cd058e3dc9c6460d34a217f190b00000000000000000000000000000000163e9b84bf66803994aa89125b625ca132316a47a447b090c82b2e01cec33f932db497b6d05976274f10c6ab79bc6bf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124cbd4f1d8096c3a68edc266e859175c6a64d160eebbf16970b1e7d20df90b177bc72271ce61b656a2c1a923277bff90000000000000000000000000000000014d21a86532310dcc3baa2b4e29dd112c176fa8fc5bbd0bf44caeea6d5bc743aeecc158d323cca444ffb4d4d3a0d84811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150f5b302f8cc66868388b7125ef253a29d356c470b2dcae43617165a1c94e4a0fc15c933f9c84d647024a343cf21e98000000000000000000000000000000001628ad346579f572456a6d18f4deb860fe157b8cd991913777979ecaf880ed24092fbd3e74ffde5efe5ceebabc8389ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087048195b3034d172f80216bc932267132a7a2e3ff779a91c37151cfc76a068d134f3acb35166423986f9615a4089b9000000000000000000000000000000000074b8a9137fa3cf060d5d812464f37715b977358648b16e4d81f6c4b0d4a91735c144578c0aab1c7726ae2c73c1d2301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c50ba3070753f5978ba0f776699c2e77ccdf30d52adab21c4275c60d6a63749b064423a8bd4e16d73eb143f4655404e000000000000000000000000000000000091249ebb6e00e85ea707c183a703c8c00cdcc0e4ba64acc0b0ed2d3d205ee345b2b6dd5afc3d8448220953779d28c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015355f6e366d86a968481d7c45e2a8ad3f7da657d8bf6460aeda25d4f39444a77aa5749543200b511e833f76ea6876ae0000000000000000000000000000000005ff1d833326d951a961ea01bd075506c695bfe76ee1f14d027424a5d36ba401f77a8c4222a92a78559dffb6c37111f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bd0cb9f23b21cc4d15d23ef10c70aeb1d0f2718fbae3dce33cf1f66cb1058edbda151b5db5ac9a852d706d2a54db9100000000000000000000000000000000019ecc080f51a4beb30fce7d42c2d1ee9d61ba860cfad9b592e4c5ae9c6c7d3e8ac69cd08512ab3f1cf5438e741b451e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e3da9ec34bff4e29669244c11abca81d0c040cd3c706fdbec5601127b314abbd0cc62e45d2ffd14527333b055e1e1e000000000000000000000000000000001011a24543586689c26e0cf913c93165fd8ad0b1fdd16028835a527f0e6f9a1c739b5b9c45a2c6f36425f672a68aaead1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144f9e6265310af62485751d484f4d6b4636d999c0f13186df9f6f5667db88ad0cbc8c3df0822d99bd7e34728723269e000000000000000000000000000000000003d44a9f265046a8269a00e40b64aad2c18032467ada3c8e2c2071a81f0b44de5b20f100860ff9e27833e8a8c5c77e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093e3e54a8ccfb04e580dad28651547153f65e79b1f8ece8ad4bc351eff8dc227da3935a992bb8d965eedc07bfbd4edf000000000000000000000000000000000aac6d8976c746ec4a017c0f23f7b7e05b7c1d6149f5a9b127ed41103bd3588f60836f908cd66d7dcae37672ad2e7f301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094f5e996ebf539d3285a9eb723d9ac681735a5a4358f0f7b8acf47e6136ea6e784a62b7ed2dd457e8add31d4012f6160000000000000000000000000000000018578c22c12c1b98ad87518f1aeb60a2aa9e36c8493be9a87ea40197b67c39874c7863d1617a366a8fa1b7ccf2b99a041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012132c0296e2db40472f9a41cf9db6dfbe624d77300eef944adefc9fe3b3fc606e45ee819fb0bdc889b9f6ee6d2de8ee0000000000000000000000000000000002ab9ed00be684e9dd0a557793b7458992ca77922d5af6137a68d3f1c50d01807a0f4748f7c31302ddcdb0fcf2f5680a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000921993d69bc3839e44d330ac93814d2413e6aa61705dcfdc78a36ef3c35dc894d7e772bbf746d55e81a8a3e9c88f0730000000000000000000000000000000000d021895fe60087b8b3ee6f18571e16547405e6ccff3f09fa8534fa951544381cf04e151dcc7261a086ceeb1cbf0aa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187cffd8ea99a2f6423595312b4dfb671bca3e9196f558cbd603db44a9a991bd9ed489542490faeb7b1089e21b9e70e60000000000000000000000000000000013a58e3ff69ec3306f685687e7d948b0b82b21f1e268deed6ffd242efadc29380b6ebce380e498d9856bc09c1c06f9b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b159ddc536ee60deea4508f999dd6e7651a370e7a6df7ec7800c33c975652cc40fe87bd63d31c73dd012ec3aecfa639000000000000000000000000000000000b688511d4289bb6aea32d684998b5d64287c00e3dc96935cb1ba93af8ec18c3d8c81bfa623448643655346739c98ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e940a37b9ae8bca962d55c29598a0990297b73e5983d0656f304a64285211a611c0bef1e984bfe2ebdc138f3ed0ebf00000000000000000000000000000000145b715fc2fa7e7dcdde2b5f1eefe5e90f8b7cacb49b449f3b3a88a9c8040d68fb792839748734a040d47a68386f126e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a171f431570132f33ba146062e03a0c70af4507b5883f8c2dffa0d83922252a0482471dc6e03cce9ba2d76888dfcff00000000000000000000000000000000000afe3d65ecb0ad020605d054dc3bc188ade1fae36d5cedaac1f2a14d9b13eb6b6d259ac9789583ba4ff3b362ef318c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108cc3d110f5d4f071e17d60e4f1c9cab8e5cb97dc9be55f0b14b678e2a242382332b6b6ea4a42a22de65fde8b58a892000000000000000000000000000000001003531937e8e59eb78da52bbd27a2eab4a14c151f404630dcf4e1407a0bfb1b5784a546c66e6228f59a90e99e57728b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001993edb6b661eec274bc5ff4b5bae0a2a31f9b27c0282059e9ef94d86e82043113fad8181a46fc34a20ffeaf2875ea6500000000000000000000000000000000078b75b6ba57a0026ef818f1a7d73790b92086c5e6500accd13393da1328c719a9c745d6a49c42b7ca12620a50c3fdc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005373a30a5d5d9a92fa0252c9a3acd1aff63c84c369f79d0975ed757ef7414918dc68003b6c021f54822af091d4c797f000000000000000000000000000000000ea2591f2b4ea290e71b002ea5aa41c7404a13d9c5d642f79b990777b10a1d94fabed95ee7ef4ef2330cd7e65c82cbd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f942e397af95229ceb620556516a04f85a83c56a29f984d880b68902495ab32711246b9605a741f5ca0574b963e8350000000000000000000000000000000001676474b86cc5a0bafde079d612409a28b08d111d38bbcb0009fd252e18295ccd4fded376b330864f56b98c5ee92b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dde37034c8903669be6e1582b8ebface264a8d35bd09f267f52f658959e47867d840c9a33931031cad2d368f9ed97e0000000000000000000000000000000001c8aafe077f3a5fca0fd80f3b37f9ca5c50c90ac4f0b8496fe56511977750e3ba658b07e92fabe9095dc6e0b63da04d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017506008c74c130a90b50be12993ad4ee10582abec46b9e1e80ca7caf69e98f39b5579545b216f758ca68363d680f2040000000000000000000000000000000015367146f27feea78d2c9acf6dd52e11af3bbec205bcd376a13b36bed8aa83f1db4d0d426c6283550dfab6f465f2c1aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041e6a792f5eec48d2c4b064e1dabd7a0f35ee0bdabdec252fee55f3d0756d8b8161b688b03ad430d2a4b4ff006285cd000000000000000000000000000000000e18d655812aa2bf1a7e8fb6be0bd6d590d4f75885a7b0b3d8881dab341b30e414f3695a1160278b3b785588aa1b30df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e799fe6c96c0885a3b67961a246f48ed36d954f0c5da9da4db8cb1336dd5eb0bbb60b6e4d3d84630a7c5ca59e9dfb00000000000000000000000000000000002b41fb9465bcf215d6a49afea7e39153c48ca5f2a80fb6d79ff664cd60466593630279d035495d11d79ce9e868ff19c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126c9ab0d6e7fcb4a958fabc265b9f854285f4d44faefcd561b0a772b52321e5e1d1e87c7d6f5a0c5fcd4aca8cc098b00000000000000000000000000000000018300bc626c70d70daa6a6d64583a8f1b405efeb8d9a82159824ed4feccf07b8d53bc775fb37142deb1842c6cf6c70d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a22cd8815b1b4fd1d971a8de9e7e1a662a563dfdb0e679086e696c26c165ee4e1cecc11357e9b3f62cc08c7afaa890000000000000000000000000000000000bea2a81db2272817a8f37a3ff5a68b27d9eaa7dbea7ad42c6c1a692a18fec400b305b823ee9680ef899f7efba991d661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a6d76384f54dddb0bcc1edf49a07f62d66be24fefbb9fd8a03e9d57ef9ae49ea4a657e275a25193a8b82d55d999b24000000000000000000000000000000001195f9c0932a2dd5276eac3b429a1b88e8de4fd59a93a31e3fcafd62e117056993585aac01d6d9d4623e562ca35949d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007334a8600f35cdc47b3ccb8dd3bf3c1e8638cb689e74c18aa1ab20665a1a83be890fca284b72f83b2f2919d6c4ee36800000000000000000000000000000000074ecc0f3cb5319725fa51a7a25da1a99f9b1887b28b474fe8afe96b79fc8adecba43b00f961284c75016d24ec20ae0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017598c68a06888687235ba747742c63eb0d35278d68cea25dbbaad96261baee8464791f38c95a742a5ed8521d38615b6000000000000000000000000000000000bee0774fcce2ee5e4d5042746f5cd51f8e150db7a3b9176390ec79c5f6795917e6a91a4f00384b3b0e653e02b64c57b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009692752e8ec5c6804cd81a2a940b1fb0c8beea9477d3b1d71d59065e1815787a48be68b0adad8b2023eec2d5790096800000000000000000000000000000000125b8844c69adc040f28a6b0f87451d0a3e486ee595f0deb0e14a7ebbeb71b2a15c89dd5b234ae0d28b05a32cf88d7341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b8b76a5bca21fede5c356f4721dcfdacf2251edc54af825b8d258e3eccbe42fecf2d4535aa785d86fec18ad376b5b70000000000000000000000000000000004ade7fb5862ce10b71fa32dd9a147677b6d4938aea10ceb16bc2fdd1307cbdb157b4397bc135429d05db959e4e0da2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177c3e18f5e0c493c5e27a7a3f3117e8025ca9ba237a7e3e16425e957657cecc2c4e2a82663810dc0b8d958c08b2123900000000000000000000000000000000154b9d7d0da2dd9c21b99dc45fefa18b1ac6d58e71307001760b74aee99d96ff45e275456062f10f747df3f86e73f1b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079441666569ebc93ce78e14222c756d9ea0dc333953e87d9d8ea5a1dba45cd804f701d68949dfbf54c7e92ed66ee8110000000000000000000000000000000010d6a0368bb41f5545b9d8e3f04641999a2f9060be05358178efd85092ea4c9c3245e99aaf7101665c766b6d1f3f11d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e88dfb7b57a8d56c23c67b7117145696b77e08556534beecc98b74315e1d1a2fdc67a868f883a8ece2a7e3f28dfc9b0000000000000000000000000000000007b5d319c3217e38a5606774e406e8606f7e3e79943f1e13bb7027eb10da9c64412688c28d8d5730739261d5f7f0cffa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000309d4c6ffccb9286a618d535e76264243cb7fd12fde3802faa5684867f1a8c2dea556f3787ce0b64c10dae948f3a3e000000000000000000000000000000000054d3200487e240d6cd3f6ad7fd2221e9707a44354bca6486304a074b8fff6144c75628b14ea6f1478457bce92ac81b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b8cef374aad61039a08af304ae3c0c9ae15a236956361bf369ff83789e9c281428f1be72f2f42fe0a6fb24fcdd7ee70000000000000000000000000000000004d7b094a3c5681def525085d8a4c077b027b7929d1493b470d8c13cb14a355c548544778dbacd7785db03962f9623211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f404c8ed5c65699d7073df9b16292a1149c8eb0a64437ec0dfae1efa93757d4a6bbc741a474dd212742cd70b709de700000000000000000000000000000000074cd8ccc97e3e65ed65dd94699728c6633c37fb77cee4a8d6eb18d2f24947e9c7ae245b515d915bf408025b60f085e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004681afbbe644aacc0ad09b61638c855820cb3b3fa4b40a8a1257965c827bfe134f7eada84789e480d437e8c43978aec000000000000000000000000000000000b48f60c00d97ebf87b729a2eef3ffe070b1cd936476f385c153b61ccdedb26ba46efa489ac96004208a656febd4b42c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8ad45921e3e682e756194bfa98dad032ba8f9573769fa1205d6527f299cfa86c05dca7ab3a56bfd8830e11c19bd21a00000000000000000000000000000000129dedd84e87fb73c8f4050acfbfb1f4ae733635054210a069b023ac3a64189c4d877e7f2eeb1f0ef7cee4338ca1a9d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132590f0466df7f5e4448d2d41a574c7ce7ef3af602f10e3c531e5ab9756fb6ad60930c22a6a2d6ca8c991b8e087c53a000000000000000000000000000000001082e71cdd210b0970beb839b6f423e0f1812a159f2ad5f6f5d9bfa145fd72a4662f490b005d3b920b8e23c2410824c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164e6e009fbade389f6af86c8644088c672e3f7ff0f797a046327f11e96deb896dd41be4762b318cdb4757eb161408d70000000000000000000000000000000015de30b0e0f5f491ccd80c3ad68a57139cf01e973465437ea383a7133ec0cf594825c580598f1421a5e71fed0e79fb171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165d8432199a33a8d5fd6656a02cafbefbe6bb3d778f6c8608e3e6cde6951af4e24356005780a405c3f23cbeea110556000000000000000000000000000000000526446adbea96925be489cf16d177db5ac1fa93290207f2a924e16ba3b41c7994e2b7bbb1888e38febc96abc12301f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053731c3ffc7d480b4282ed6d70548ffe83e379243ed4cf6d76fbbd2a86ac79cac89789fba3b9ea6c2d964ed53be75cd00000000000000000000000000000000156095a5c2088e1d094f887dd018a16c82520dbedc92c99feb6d7bcb015623cb419a03eba0314c90748a78126dfb045c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001204635e1b70f2e8f047af63341bd3b17b3e18c9568355ad1d69eefbbe95e43f4281cbc07c910cd985afff26cc7477310000000000000000000000000000000010b5235fdd84cf9a525d6b41a47cbb30527122b4a6aae8ebb45e5aeb22c5c90625954237252bb6d703c6c2c4bc5f61431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012649981d089e627dd7d778f859b5e3a6584744477233828882501fbde0a83ebb4b4c89fdae5ead6162a04982c2c9d68000000000000000000000000000000000ce17500bf763fbb1561aa5b5ea38eebe45a6b085a7083950f0656fa0fb3bccc2db5d89293574c8f313aafd7caeb11311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060b4766dee2cb0f6f31282758c0c0be1f2c4af35a76acc4730428f32b31344613660eb074229b5585c0a027ac96ce320000000000000000000000000000000018a24147b522c72b732ba24499315290161a891e4d073338b0a81b7c036811d9f124edda8de0638f11677aeefa3b5b071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000687727795a2cfb3e8db56f11db3d326b9b8a5d8d33677e5c622098449ff7b377c80b01ce5da9612287d9702cc55e2460000000000000000000000000000000018f771e55f21098f5ef5d307283a056ecd40a52e05225a8991f7acaae5ee825515656337ccbe7aac4565c51f59dbb1061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cedc6fd7a81bf936ffa8415c5533eb7007c2f9d8965bf3c0eb84ab218d69c0d395452869ac45aedc654b911156562e000000000000000000000000000000000dcec09bcad8d5e2f1796c7440f0f148ca9fb7c826c7ee6a24ff3d3c6b39bdd61e5efb17661669277ce02b5b7c947f491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124e556ec555df74746e9041edbdcaf8642873960ba3a7ca8c9681e86efb311f772f822139fe1eff8559f94427041b19000000000000000000000000000000000a941d7a0ff924a019b49b7b2514b9002ce34c4192c4e5154669dd3bfbc108f51775fdd08c0b82feea54eb4f156140c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081f01e7681ea7f46bf8a486878f82815a4adb186a4f10401505b47f5e2edf029aab2dece056effd88ffd93406ab05b3000000000000000000000000000000000b34d5c705c02ba9ac8f87fbbfa0c8e62a2fe0a1bf0bf013da75540e5b823cfa49f83acc31fd0a8c405e96db1fc0d77c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d598b22b95c491b5088d38ce9d29a7b5c87870e4c80cf4677273d7ea22ec13bbb980c9249caf438333eb41a8fad8cf400000000000000000000000000000000099ee22ddf1831c4ab2c5bd7c5143e535777a5529a33da353ccacf3848c4b8068411572c3b317c5ea4649a4db4c770cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b977843bcbbbe78513556234f5b594a57fb496fa2736908ca83aa3619a28dcff600d5777d4bdd151cc919e43b121087000000000000000000000000000000001830c6874b7e1cd6e0db500389c4064fcc6cda29f9d4bc2381da7ea02c4a77a484beeac065296180740af4e4961f35bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023cd1c54522264fa742f30c5f9aa6adfa726dd361c4be2cb79776167fa02a4c4d8aa5b1a0a9821df539abee57ba878d0000000000000000000000000000000004bbc6b409e973d0698f0cb5c4713ebc00a900472c50c2f0b0a487fdbd823b9244c599b31e2e8cd3ec0f6c3db3574a181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092aa6698f39c150adaf8d2ed8d0025303a2c50ca48ffbd6067e1e95ef294e1a8d8d9a2b16249929d180ae48c38552c40000000000000000000000000000000015cdf3eba3a21e4c2662dab064fe4ea9f626fcb025fc769405bba09c1ea78bf329d41aaf5e9e3ff422bb76c13465ba661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018212838176bee0c66b0de51d9833a5535e006281741b51631e3f3b08e758cdee7298781cb5f3c2cb2602afb276927e400000000000000000000000000000000034a6acd164cd03a048acbc7bbaec125cb8598cdf4ea526b488d86993de99c144e3162ac0a2fd5c23760189d18c397791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e2085e16b94d873e7eb23676a277b699486672f8db2f237f1ba1e80a460067810632da6f511a84a3d4dc7e060a1f2c00000000000000000000000000000000037ff1367a118d74318d553ca51ae6117cc7e399d34ec5453c39818515a9434da6b8c3c571a1123b8d46c00b717a7d7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ff191e2dc8f1f10ae3a43abbe94d33d404eb62a1214fc8dfc67ba5cec860165cf1555d63c2f2d0789d230d60cb8197000000000000000000000000000000000c587ea9984edc3407075dee003510e09eeee3b3dbdefa11a88aec0f6edc2a208c57605c099d5f25c9d0dbf2fbad64421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b04c0f101ec16c9f63ac8c8f5cfc0b3dc7ec0aef97e31e0e84713778062e43804fcb61fb2aa8b3abe4a2debc3716dd0000000000000000000000000000000010f14083f709e95eee3cff8fe691ebe2aa183b3a6132e524690b5bd47191bc4d0aafbb156cb173c1f7c50fffc51f70441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6317f2e4444a3a84161215227ec63c039a9291a7ba6405c6d4029259e39918405ac0655b49103c315abc11c9a6451000000000000000000000000000000000119630288b45808bc42a8b6e0bc767bf98a9cfdc0152d1d6fe01e4716988c14e4fdf3e0680d337cdc3cf7574ca84861e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000700f8256b34086d526811b4eb2021acdca83762a21d82520562054afca6dca950ecf6eefada7fccbeefa317dbc62e4c000000000000000000000000000000000ef74af1ebcd12481cae4e09c6a6477baed85106cb76e64ca011cad457fe4715b050a24f8db20bec82f19f9de4ed2f0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110ebff9433b7e2d6e690191fafe6fc582befed11e9c1cd4d97d1d7426bfcbc7f837e42b52144df14fa579ad1337bf5500000000000000000000000000000000098ad3f3fc63bca3daf8171a56a481f8d6cbcef26610cb1e798cebf47cab358f099f0eb81d5d822decb5a574c2c3ccb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005735add8b3a5bd94087568996d9ba5c6be9bd93f9a19b2700caae5b4b6ea19a3e84f2aded1a21c12b6c15c7bfa4bdfd0000000000000000000000000000000011bdc4febf477b00cdc8f8247ca942d2f4a59907b49b6fe786d3e2c5b18e44677402329f76e8abe0f3f584e1f24b37a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfb88aff16bac6b4741a34a701c1759536de659cdae405794582b0f618fd9f379c023731065f6e6962ec1ab69983e00000000000000000000000000000000000794cd45401b015e8ff2b851e52e21092c3093831efc8f341b8ccc3a450894bd6cb27ec8c21b00991fdd50649e4382fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062d33d68d42e1a064aec9696d07f5a25bcc4df150ef16cb2a6e8918f59854665b5c55bb8ad60f0d9fffd45d5d7b656200000000000000000000000000000000114ede9230708466b5b399850d0f28ea02bb9bc736ac728da2883235b65890609ab1820f117cb8dc16957a929299385f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001041198f0e9c4bdd6a0f3937994aaad238dec9af4668f0a63f0e76107e3a11ec0198319aad0bd1c4d30d6f99d81ea71f000000000000000000000000000000001223bc56216eeeb5b832f107bd5a2da83b21345962a13b8c8441ae3639ade8c33773fd3d8d1055b95e6ead0c8c884b011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006091c489bd76ecdc9238b10e69eefbb5cd69f9ee31d46c42051f90f9cbaf6177619f88063df6d126d2648b3a66366b0000000000000000000000000000000000c516bc163a835e9eeba12f4cdd58af18cde5ef9374f2c100ff2d52065b7494a5d0c5071de5815218e7b00c972fea41e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e136e76168a3e912120df9da5e1d416c08d8e50fa08f3f06d4b86a1e666dc4cd7f56e2314caa8d08e4619d5194400f0000000000000000000000000000000009d4151cbc73027664ae1e52cdd949e521760d6b5a651263d31f8a434c527156b95d1ef15e05e53fee43776933fbd0681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a2f419701e52135831638544c08f839fab08270c76782fc62a949b2082a0c4bcb0001cc772acd95b5f5fe2c8ee4db10000000000000000000000000000000009a2afde0c4c8a15a387005062a686f41a8b480159adbe868a5178b15b2a910d6c358d0b31862bb9c88c8f6b96d4250f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c287e60355d614684284310069c433c9b61dbb6eb7dd8150edef0c860cdb586d61261cc71aec0a564c33beb6479642f000000000000000000000000000000000338e3f8d90da0d602775c87f206055a28f7ab945554c6f0aced8aa9ac8a86310373f096f0dee09d3f193300fcb2aabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133fd20770b4ed4f8588bdbf4f9aec275be4c8c069e85a102863c316dd560b9d567d2f9ab6bb8f5ecac0d524755bfa94000000000000000000000000000000000ea7ebdf36f867db2687c6e86491469b2123c0f84fb34a658ccc8aafc08155bcbb09a4df85ae837a9068f1bb6db0f5d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a00c47e629d63c68907bf5a69a130f36ad788f6b1d2331c3505ae8ffa462b3259436d42f2bfe3a3ea864dc190e0a6d3000000000000000000000000000000000953bde81b431da8335cb2e30534d4b2cb7f05b1dd3d350a6bb7450afd2c6b0d91e35dbee03356aa58b1fc9bc8add5e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008514da7d76238c42ad53742d4f13125d8ca3bd00ac7dcf4c3b9404db3922f09ec4b5ec61de9d022b307723467b4477d00000000000000000000000000000000149c2541a7eb42225138c36a5763f8d5034e716b50dba1577c3d37f4df6f31fd81fe39a00dcee78ac1df4fc3fa7850c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141e2990bcb25cb1f18ba9bfbc4bd0ba061bc37ee96dc6eb8751c22105224e44d2af6d16024d1ef2d5535cc809ce82290000000000000000000000000000000005f496073893d7d3c4168012a54e71ea417b91864320f63c7a574c30c97b07006810b69b8edf054dbcf6a962597b198e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bac3bcd303d917c8cfca4b9c087d1f154f93ae29ced50456cbbf303cb662a1986f2a63d7ada0202926e8ca4280c5470000000000000000000000000000000000ea18d9f4368ffa578c90710d77e0859bc94eff225c78cc42110ace451d7c4f8b4c63844a7b785184542f116ee6d1591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acdc5db706abd7fcdb6dd73e2a3d6d499de2423a72521f12b99f995141d1aae7c234677d70008fc00f9e964dc89633500000000000000000000000000000000153bb1b64759dda9144624ef2257c973eb5fdfdfe22ec89c79a3d9771cb142516f8bd4193731b6014ac567cdbf47550d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f61b643a8724525c514a319ccb5ed291b0de3262e25ff66fca98dbf54536610256ed1b5d09301e1a17ff14a7f97ca6000000000000000000000000000000000099d3626cd99a35355a75217155a672d355572166a32eacccc93b9cc2bf3db430e330b0bc55f6337431315d040adf101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d21657c37ec0f9c9309b4eb54967a845cdcca244c0a587ba2388f08aea1a5dc7ac8a02623049f640725cdb39fb77b1000000000000000000000000000000000b988219594e66b553454bcfbddafe121a2eb8f5ba9881dd071e51d6d0b2dfe50a94443260c53be2d0b65ff77f0a5bc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc0b9b835bf7a249f97ec3322770bb103b5d981e05725c0266bfed44728deab4ccfaa7264a8fc54f11c0269052eebaf0000000000000000000000000000000012ffb67e9bc18e59df74ccb3c3f53add73426b2ad26c218e9ac6cd2ddf8a27927d75da80257467531b353a9242b5e1bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d142a8d34b3818472432fbd9435a46c65e1d5e0807f8e2d531d94b5ac5ac24fe673b359c11ae2cd251623da2f2038800000000000000000000000000000000195202b0744645df948110d29c2499ee55beb7b740f61538af2537aa2c319969e9bd992de2d3f8e63e2807977ea098591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ccbd35a825734e3bf49261c506e86fce7f4c008b9489b19ef43a484f27d828108cd391038cb9ce4164cc63290e71eb0000000000000000000000000000000015217b34803a59641421e67b6e6d1c2f026be006052db8ffc6da58c54eb610bc880ae08afaa3cf320ecb2a5965d27e8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163e5573f09c71da91ab2a1d9e7b94953cbfa9acc4f14101538041b8ef2b4976b24aed53155460f1a75720bb8e014e0200000000000000000000000000000000187715ad4231d0530ba48ade2c0e42006c6e0c7fdb21f44a7b3a22617d8c4c7a9305ef833d71c82e2baabeb96eb904c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1787f030cfe1fa269dfd71a2005cdbfdfcb4476b9c26552d9af4d355d530e9fb2461bd48604aa702412b9d67fa89b70000000000000000000000000000000006a0930e941eed3893d329b2cd08f14b84002008064c92af32eff752023897625b87c89a69733741fbb9693d5e186ded1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d27fff8a3a76a48288cdfaa4dd9795798c8ded054fffa77ea7a559529d95e78f377292923bda348aea8e8fbc7eb7400000000000000000000000000000000015bd8be0f49e0410139b7e9d7bfd1e5816c01866de37fb46d803fc74401e09a7be398b76bc272230360b70c92e8a755b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de19e7be7ba775ceda719c6e193c75635f2403e8c4616f58970428a5b5e85c1782915af7716c272fb4e5e4243c55aeb0000000000000000000000000000000014dcf7d8252bb17bfab258ec39181b192742e312e8af13f32cabb32b776e907ff33f502ae0951a501d7a28c1dd29a0c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045e37bfd063f81b3e20152add47515c1e70e8cf5b6385a5b999d83351ca71856495b656b654ae1233a5376918c1c28c0000000000000000000000000000000000ecabe67d8112f407e745886fffe27c4792710b285ac5a27c1e779ce58e7a0d12865c0cbb309589792c81ab1a7547c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5d8771c1dbc8ed2565cfa344c73747006bcebb7ac0f48d78f14861d0cf1e93068512219a628a613eddfddaf34aec090000000000000000000000000000000009c56650fe82ba9e775633926f27d959a4439ad3f465829a920a069f420d1fb05920f6b7752a1d81f16db3ff5d7f72231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000392fcc799769ffbbadabbcb0c04ae258be28b47d68acf1792d36be1cc1466c8a7208761ca207f9b5a19351f8155ae9e00000000000000000000000000000000001e08357c781dd0ffc2d5083e80a16f8dde9b573ff27e9001292623a0722e555ec01233fabc006870235dbebf7076fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001294d841cbe0dfef49449253232e67dfd32eef1591b1842323e3ddef7f2c17342dbf1cee16be676fabf5a2349f10c713000000000000000000000000000000000e20c90c3f5fcecdc973fb692b012887e2293de12b8ef052cf5c5e49e07f70f64f65d7ca37f4435d30fc855a05ecee071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c6374269b76cb60cfdb6768b764ab284932a1c26daca6e3e93d7e05b88d27a2eb97f0f294efd12cb3311926e8133f1000000000000000000000000000000001028c20d1d1ec5d4446c2e680d0fa6e2c6882cf9efd5ab4839c964e188b2ab16ca6e4c7e36cc2478fa498cff196c840e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ae61d214f1803b8980db0fed8fa76555e666b5d11830c06dbb89b5328365b6aca79fc3bf388ed711697672ddca956e0000000000000000000000000000000007501b114a731c8d2043a668d7f6adf1f60dbb11bf6d9e8da8a03fd9bb1169b85973ba0890cf90cc0b627a617bc9d1ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089e28ca8426b4b7b70bb3fdb75fe1c06cbdc3a8b818b060c6687dc072e28a60f09bfe4c51cdbef8fc2d418211f455cc00000000000000000000000000000000180b4064223f92335ccb457801b78041e615615a76c0610cc9675e14636faa0851daf52c1301848e1bbfefdf675441991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bb4d6fd9b494a5160c4758e7ad54117314bf8063b53289eb7f535a712cd3f63fefa020f32b6e5ef859cb9a5b37d14d0000000000000000000000000000000008be0b1836d20818a7ade1bd623f973bf7cd5621384f812943240aea1051fa25fa1c392168b9140802126fa0b812bc381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b21fdf5818878be6342ba0f7f088ae448aab0c7f5f2bbefbd595a5f7b9f64b96010f1ba5336ab391e1e5d7705279c5b0000000000000000000000000000000010455779b738b2aa1950bc276d7b8d529739d6bb53783b694a6b0ee9bd0489187e08f3f656c29b7c5c0d11692907ad301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c714dcfe8abc24a662b77f0c9f8403a9e78a7695c7c8d06ccf9775e7a48b005bfceb9c9687378f3f5154bcdd3b2fc800000000000000000000000000000000097e078b4c8d46ce315b1cf845e1caf6ae2ad935d5f780ed9c6925dc03632026d4ffde711c9fc1f97e897fd136e2511f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a819d969c2c51ce6fe4d11cfa9cb8bcce92ff2eb18a4406971f567028a0021d73add7d418cb446d817a674f5b2465740000000000000000000000000000000005d33850ad448d3e5226193768d53dd8162f1e19bdb98d8be7668f70d1b9870a1469cecd91afbf3fffc561d48038ec3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dc6f08c1061eceffef89bcbd62a7a946da712c44ee56efe61c9710ceb954e18233e39b7f50bdb1f776592ff44bb38200000000000000000000000000000000153beeb5cd485a611b876e511da4d11e26d745330f09bb017a7ec4f70c31e1fcd5286e59443556eebc6c6f208117ad791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1d603ec12071a0634485dc809c7c8cc913b479260f4a79282c9a265cbdfed95b72fdab30fd2f586c316b9b72862490000000000000000000000000000000011bc6b99e642bf47a5e31e1a5ccbd72ac3d912a9e0b0b3ab3313ba44b8f16ce0e259138dd25dabb689c1ad8d14b899831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001183097b2cbe79a86b8483fc26b246661899a56d528bd1003a5c3c5d57aa154b94c353d4a336c587e1c13ae1c25c5b9100000000000000000000000000000000045d8fc1ef2a1e1240672e8394c9e2b8117b2797e14c9b782e04269d544286431fcf7f4d87485e76417f0f1bdf4363a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ece20a1b4d8f66a4045a2cbfec6ed45e408e9d8c3b5542e3b976bc3ffa0b2c97ac385bfe54e304c2d2f011394a7d5290000000000000000000000000000000013fbe27b8bc30962a4995488d84d69de05e2c94a8ad7244f52667f789b272b5ad79a705700b0e0828edf166b52141b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5ce6f738a81119d99ffa13413c962b1a2cf04b46877c219256c8c149d0fd28cc0bbd12b6c36775cd858746b4ebd2e300000000000000000000000000000000102f7217f8c8cbd4100590f6976d559abe32abfa2be0a2f63e6b7ac436cdee36e74043d43884497b5c450dfcf9b5fcba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dca075dc9cdf21a280e4884bc3ae4bd9959b638130784a665384ee3a3ef8df9d12904edadcbefa2e5754f350f6b519a00000000000000000000000000000000071b25357b1c130d4e4ed392cb5806215211a39cdb288093ea0a7126f415eaef28688ffe37149c06a6959ddf9a63fdca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b96bd57c8d0510aa7b4f6fabbf0bff46ed2ed1db4d37002138c3eaaf28c36cc5b96e6c6992be925e2e83fd1151b6c10000000000000000000000000000000005ede28f7e31154a5d1721d09282e6b214e94ea622f3b28247fadbbb62fb1b737bdcffd912ce5b408bb839960a3b10c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058480cf561f5e23969d79ddf13e2a45a21539f715f393e61b6bdebae469900a3bfe1aa04ad3a57a7034382ac886f78e0000000000000000000000000000000015dbe1c274c90699b2ce386473397e009231197e21b1d39b92a1fd3a0b3b1c600a0579c874617ddfd953b0fbb5b7e14f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6d613ca6b63ca1308ef85a08c0905f80f8f41247a3c5910b102f52354419b11577a0232ce930e5bb6b05850db46e4e00000000000000000000000000000000124ee9c95eaa57ba7b570f44f6bf5d91de7915a540b12758a57a81714ef9785883eb296a28da77362caebb7906dbc2b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034198c1926741c247ed4f0062fa9a4c7699b9e36132f78f67390829c6889f6664b96f32f734f081e3ae7e9377985ed7000000000000000000000000000000000be07da5b50ef7c138c37a0d3e032bd0294211a7c05d1f6ed1b429807819d71ed8adc5e00799ff51ae45f6a79f86e1471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac502794bc463e45bb6c6acacb5c0a83fce0f66bf89b8b4f6aca25a996d1acc9fd39c07b255c3eadd0958598cd6698d0000000000000000000000000000000002483ab2369ef3506d6c5e4119296ed817b8f34b4e730c8248c9be36ac229fd46159538633ae8b47c5dab76091babbe11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e1e674ba1336b28ea3218d29d41b1fdde32c9411de3756b0ea3d438babd6dc6560eb10b2c9942338d3110292038e6900000000000000000000000000000000061855a12472342b1cbac1835964dc616ffd9f93f902ba61979c8308f2050b529ba15f13f953ac6a16d6fa18241c96421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002ae5d46ffd3a50a4d4696ec50fc4d270bce248bf7da01851ef16bab6911ef178d2f9d54f96d5e5d337e1023468529f0000000000000000000000000000000003040ce18f8674fab288810e50cbc573019ac3912a4b7a3697fa2499472fa18325bb589635d3d8080a551833ed4204541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038749f3f30b38b7f8f1e66bbf316040e8cd594bba6cc77c9e199ec9f77aabc2701296f27a012d53441346ebd4a94bde0000000000000000000000000000000001880e8d0aedf27a2e83979e05e689d9c4894cf2c9c7f7f9a2e4bed8369161a83ea7a71422361435b05d4f817f0324721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028a2aa8b16188a64abe533a1ed42a127daee0537af6086a19f645e249550c88654a908a8bae9b9c0b08a3739af7a9b0000000000000000000000000000000000a5f19d542349cfbb5aabc0db46ae9b380410d8b764c876fe005584d76c0e9539fbe3f69911a244a9b72377711770a0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ddbe938ed2d6f512c30a346750bd1d16cbabdde7fa8121c770f4163ba569060efd20dadb69e0c5042069f0108dd05e0000000000000000000000000000000015efd66d5ab30d39d96854eef192f5edaa215d768a24e62c9c3962a6e2eaefb22eb49f9fb8ca6e5dae76e746a5e216c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003340433266f640af71855c912f5bf01cd4c7c7a84cdbbbe127c0a23b3aaf5c6b19f920ee87f2e9c8569d8d913e84b39000000000000000000000000000000000bf472b10d0eed9650ade76bc0fa9f0faf77228576d8b9ba4d641c537c1c4cf0c49c09594317ea8b296201f749bd0a801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c523f24ca64afced64381742329aa0fbdd99b2bfa5188bb1cbd9e832532d2a840d24ac4f04777582a50c2d44cf0db9000000000000000000000000000000000080f56c3a7eaac4ccf8b70195b1727c9e484b3507a008c021c516ea7b767697f7467ce2c63f6528db5f9cfa76976e00e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103e2adde90b18d4216df119e0d92ca0a836216073ec8ba609a662305a9a432c77aefee70b8cf32aceafa9f79296917e000000000000000000000000000000001236c5f18e601364fece8eabdda2c8b077d6579353365ed1d5fe928a1a66273b4937756a348d2438d252f38b3914c8d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001388be336fce4954e3d35a4fdc4f7ac156d180dcfdd3d8923a3a78253a6138ea2e5ed0d1b0053442d0d0377d3fb425120000000000000000000000000000000007ebe7540c64011d5d6803fc457678b2821b22586170d35995398e25e943680428209b76ae827f535f3359606e6f0d491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fab9ca1d95d442ae47d58ae7e1bf496a21cdcc5fbd9541b5b64e31def867d3ccc9157ba3b1a050e092a02517dd08fb0000000000000000000000000000000006c033bd390bf274f6f3e4e97035745e40d752a8293258ac7ea62631078d1385a38bb07e6da739f80ee192e8481b96761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7bff0a4a71bc1cbe17645baeaef08a6d0416197eb08a83af05e30772ba1a94fc1655476b6880283645e75194194f0a000000000000000000000000000000000fcb87143e658d0782203676af902cedc4f88f0db642adbf9e4d7327fa71d9131d5041e4e14e1880f2ad6c5847c326d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6f5f8281d500cbcee1e83e5474f03465d7229b4f794f03d72fcdd4ff620b955277c385860d00e59d1518f40f2460f70000000000000000000000000000000018c9a5bfcf3d1bb9001f666da2404251c4080d147ea800d84ddf2f9e3ea6cefc5dfc767b40b42220b6e88821746baece1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c76242ab146fcd892aec3354e2f1e2dd3546a57f5b1bf5213e69562c50b313a7f82b671718ba3f8cc2222bbe19a3190000000000000000000000000000000019b63bcf8b241edf079c1b311cd76f787c0d832ea98207b50daa92308c5f174205dfb6b1240b078bdf774b8e7c5a395e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ae21924707e7c445af28324527da6758529175ad4c657ba06acbfbf3058ff655901a35e6b77ba94b0ed74756739aa600000000000000000000000000000000030d903cf9ff53bf6a78080637865ee95d8d7428a783cf68aacae1fa4fba67c9d730d6c1363112a53bd1c7b4eb93a8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000407c2e490ab58c7449e03fa2c07a16c17c9029b1ca50fd1b7ffc685bdbe903dcd25edac5a91800b594f32055dd456f30000000000000000000000000000000010f6a8d7ad9bb0188de21a6fed04a58192f70df7331186c4d63b19a40c140af467f1ec8c38ce75e8fcd611583247619b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000820130bc4cefaaaba7ec743b04a8ab78e78397a150c1b2c2e68f59b289939031f9797b6ec04c6e5f308bd97b0a43a5400000000000000000000000000000000044f4f6fa7219652fd2025876b2ff3a61bc68452d43b1643c0ab108bff0d2e8057db0f986685c6e53b17356f9d9a2c261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ad2bb7d7aec7e35dfc84ec689e5398e03cd7c9f2c9d0f94a2dffc59488b51bb1f614d8bde3330371c45f2734a9f012000000000000000000000000000000000dab495b318c28aaf23070d5656453b070937a54617908224492a663a639c1a0e2c6b44b40b77eca55e3a94fb1eab80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e89e8c410c7b6cadf1fba733df1f8746b714b14a73701970b88201cc329fa9d4c5ca844b2d7e423ee86824487b432c000000000000000000000000000000000a2ba0d5bb33342b68e12f85d9fce6655fee43c8329e66d4117bf77e224be7842956de28a88e3674bd13985ac59b69de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b00a0f7f8a5e4a41c5218efcd40c269a2f12681666df1d0ea80a2796d419d36e7890cad0093d1df793de3465227a200000000000000000000000000000000018d725e462110c8b8f3df1ca2f7a330ebfc0809faacf65e5da2a5acb9964849fa3cd03a197bc4c00ae1c516630e7c2121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f8e3c4cbbab06cae109475c74682a95cf555f57406677c3111fc4a838dc95053fcc72cb57c1fab17d8f0e39f7b88680000000000000000000000000000000014fb8ff2433b0f12aa572415b6a8f808149ad6bf310b610d20cd89b2feadec271db9b86c861fe1e94544d83b9c287ab11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b55ad62dcb19931a465a2a57e7c2d47afe192aaa6068e07a4d487bf719c84f1ed08c5a833fed78c515581decca9d650000000000000000000000000000000011ef532555c5cee1075b4ec58edaf29acd27f0e99f1b7684b207a630f281ce886cbcf5c5e86ef0d4979503d414ab6e4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f51cddea6ba1aa1df801993a998344388bd4a13cce582b91907172d10b0ff0356775744234723bfb2ee2da799382d7000000000000000000000000000000000c11e775a7a354e75281c62886cdae96e2b72e4198a586ff76815898e8e7e0dc5a93270e5b567635a2f3ab8e9f2f4a771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a5874ac376ef5b24ed8c3841a0e08cd62c4847beba2189ebc9ee8c7e2b95c700560cf1d6abbd254a8f8c0364aa82c50000000000000000000000000000000012c3123189a6db9904c22426af71321c96475f0bfba28bee1f672e12750b7f61bd56a7e13eee82d1ea112ade3ca399691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ae54d5a38c9f95d63be4f8ba393f8775b277df6e761abdbf03b842d07973c01de9058285723979912201beaee263a900000000000000000000000000000000105c0379dd8926606138fbba9d8ce8b538ae31155b7ceca0a06d3fb09f281d9303308ffe1c3919084c8dcaa06019d0c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005af9a1a8c2ac496d1defa3d8c304c60273ab4d63d6a2f634c51c2ccd1221f1787c151ffffc222c0c68fcf4c249608140000000000000000000000000000000007e83b09219b17d506a2b396ecb15e52d857d67b5699144c0d84e81c1e57d2e92eedad9513a6b3e1800a75ab57ae9aea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175b33d9d1d64833f2b21cbc783a53e0e8de0c93cf39bc6cef3fe69830453f4081872ae91304f498b364a985fef5a576000000000000000000000000000000000fc72ac37889a0e9fe683d679a10958e1afb50b402adcff0020634a692f5188d934f5afc8c7381c9308f92b09dcfef291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f893db85b655221873c0ee4ade715848c4363e354e8e63d3537ef4a81b1b95e48b56b8cff1a3816e14a6c5c6e61a6c000000000000000000000000000000000f8bcf7fcad5a8150eeeb409978295d0eb083d9848dfbe21c040fe5f24a2884327b8e48f640d5416a8c35f1bcdf3dafe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed6ef877f2000f5ed7198fb04f670dac7085315d6c6c861f81805682a3b7f467547843a23d5f6d4b391c16cc6d7bace000000000000000000000000000000000bc3078f0018a97732d0c51e1550cc781f374013d9948f2fc6ba0ccdb801819a4e772eeb529f4c9bfe6d79299995f9bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019d9ba8f4d630172515ca0a73243cf642704c784d2d250c25bfa32c6d209f63737f6ef40084283fe6d25c0328c1e7bd000000000000000000000000000000000a76cc3ece037a6ee501f553e0383824c52c036f291175e1bd60f30b482aca0d63b45f75c67eb6e90690eeae801da3121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a92f71e51a6025045d6c1846bc7bf65a7a906c26676b41544fa3334637e7129742c27e4a2001df5a364bdc39436b9d0000000000000000000000000000000000a73c7452d5f927a7ff165d6168c143166457752bfb52bcea405878ac13ec56413742a0d303ce39e5a647103924140a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f595416adc7d48185f109337ec58f23af7841b9cbd851690e4eee5f8b0e127387c11eca47d1e56794669e4a9e34efc0000000000000000000000000000000010bf7591ad03772ef5b3f7c63f16e5e072ff688c86a920d3a7baebf975b1a2b0d0dc25d6644ea2273218ead256ede37d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a243d8c9f495f39e09550c8664693744f1d3606e851272f1e44af8538700a5ae6edca22120883616963ac2bf757b4800000000000000000000000000000000014e5b2e5cccb3c314c333ead2067a40d92449355d1df4537c8bc6d947b5105152f5b4428ec223d74b029e086480697b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7f5bf1e784d3fb5c536af9f3f37bbf4185b6967840885d3b9a667a5d908d1b0c8147d83fb32848fbc0f419b340bc5e0000000000000000000000000000000014b3a6159fbd99ec09b2588162687afc81fc9fb85baf3c0338511079cc7e4a9ebe609da042541a405f3972fefbe9b7461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac31c65d98d000433dea00e8bdee90211d285a08d7848c8f20a48b170219b0e7ed610ec71b98a514fbe9bb520c16ce700000000000000000000000000000000060f68ae3f5520d8a546f49891b045e0078237b3137b7e8b19b50239dff21b354e9e1ee38babc66fc168f8d808d3695d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031db8ccee1d7807944581f833fedf0b13fb6bb706b2fe8693f7118a52923f2e25e084e287d5c824ed5fee0999a69f960000000000000000000000000000000006a377d46c828120792ebcf9135c12d57edaa5eccde526d2bdee732de2b1ea98505d461b36470d12e05c3747ecb11c901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e90412f70480ae3c12c58901a838ada09965ae86e66c6b9326b580e644495781885ddba567686efc06a27908848b4fb00000000000000000000000000000000096e679e4fc99a85396e0eaed159530ac6f8290614eaa505bbc275b1aff9fb47003ea76cfca64bff9a9ec7864925176f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008275d1295e4207f0fd3a67e29bba8050c094cf336fdb42f18a0b77bae48517e7884d725684ebd36c548664be94ba5920000000000000000000000000000000007a8ae5e04573fccb404c20bd28d72a42cb36eed254d41326be3768a14bf88a0e21e2c43d4f48e62502d36bab65333181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9c6d2a1534a35d25162fb552436a952328fabad2d1ccdbbe0b7d70983eb07f8bc5b257627c9012d8ae8b6cf849bcf70000000000000000000000000000000006e6430bf17affa757a8d3b674b47d23fdfde9c1bb02153ce1e31b57b8c323902e0dea29827b42780dc5a8e764746c941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001564b3592702066a099b58db02fa3db5c1ae67ea9c7cc7418d21f5d9dc83ff14a7bafe77b5e9e97ab1d6b8588de60719000000000000000000000000000000000b6cd1a87205d8f9e26575c63846e3cb63c61d633af24e72c4849e554f27602a5be8e4ef1c81606259349d8f611d95921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a65294210b47f6396a3a4a041fa7add35a7cf4b79e0788104cb450021b100874f4d7367101a7dad30c8660f928314c8000000000000000000000000000000001067d9000fb5aaa48a1b9726ed098ec89dd15751521c51c8630e067048ef1f211d137cbdad303f7bbe0d254b8f32c8c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000afb014945ce49a2427b9bb32d2bdbfd2b178c57b102cb6ed31a0d7163a7f5e5ea283cfb3ec0885f367cafe0ff4333b0000000000000000000000000000000016885b28b43c4fb987371fbccc52e4fd8ebd61681f9e0babe4e3cc3b38a6125f20cc49350278b742002c842c63d53b271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000395a7ff03d0e1aa6b97f7064af5d7b2744d56340c4b7407cef57debcf1ce356a7ae4acfaa4d10ed0bc2b28e59a962ca000000000000000000000000000000000609c9d537420ca2bdc3930e824e31f824c2c6a7a50dd121509c6fdcd66091350d87990abb8b747a363ce8eca6505d721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039418b6ef48761b9b9734fa6cfbf184a490600fa9b014865d3519130b5d04b1ae2e113e798df7962d9fb9ceee6d8cb500000000000000000000000000000000182a765e62feef1720979c9c858e84b883c9da8c4d012885119fff2e61e239dba0df9d822c7ce34603091fe4353786d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000197b9239600648f73e54a3884568eb89010a7d86216eeee7e5f0720be75ee45c084113489408feae1f1c115857cc557000000000000000000000000000000000056c5a8ed91c52f6d7042abc117e392af424268e2ab33e818d726b31fbdb05d223ab4128e19d3da67bb2c887222a43b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a461b1c881e59717d8c433ff138f167eca88d7acf383522c5a69fcea248eac0790d83aa023ac77ab1d508096e27cb1000000000000000000000000000000000d92a449470836c6a3fe6be2fab8bba8de526aeb6bd9659b6f5e19941dd5c23c7670a86ff3ad66e6be49f54f56668be51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051e27fc21839f6d2f1e210572b3ebf3fd571f0ca2f89b2d236fe1d35ba74b2f3bb582f06eb4e7c6a0c376a9dba605eb000000000000000000000000000000001901957e991930d7e2b51fd5834f6591fb360fff892f9acef74392406a01b1f44bce62f41c035a169c3b92bf5be2a1931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001823765a3d22dfe41a8c5f874ef46c783e4d44239c611f74cf895a25f7b29073090e8257af1cb6ab2c32b2df4eaae311000000000000000000000000000000000f7b25227f7d88b3680f6f6a86af6bb631cabf26a3f5e351e93e081220aa5aed4b93f7938ae15dd90f92d115e136984c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001431f051ef89b344f50575c1f628a5f7140101076dfe09875734aa533d1d8046d6585db2c2692544798195fff3db7600000000000000000000000000000000000460a7faeb7b31d68f8157da6e42e581d67addc3bd837ab5a2cd5736a00e9fcbbbb85e6058236293af9e23d085a3ecfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7b0b10385ac6bd1a0f90ce2a2c6ec87c46db498b235ac27d84c8fe672e8c0cf521e011e7bd87becb6f7e8cf2edffc00000000000000000000000000000000009493bd9ac530f7eea5a8aefca76e2f4be67e15762e935826710f8c0323c9cdc9ebb91db3c7697b4918af117f7e283021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059efcd6a9c84dcc6f4bc76602cd5ab64dad9dfba2920225c0e0cb2c1c5f515c8f28aeb373f5ec3f6f3f4045df03bbb30000000000000000000000000000000017e5f84a2c04965b7098682f77b7753d0341f9b9c4049f4ceb682e1af6c6926b3098d0f2a3bc40152c20cf36ecff37e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008432360a0addb9b833c77a0a33631afab70bc2a7f1f590dd6a992defc8bad4b5a17babd259094ce301ce9d31d39e352000000000000000000000000000000000b06c7fe46c2fc8ef42c96a8b929d0e2c9b86b1e2c01ed96d48add8920b6f449921651176ea804665e6009d8764fcb131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bbe46bfb169a9676e997a20aa501983a411c9737be87187f950e2c2e3e6a3755aa765d4fdb5825785f4d3cc60b563200000000000000000000000000000000124c204d7f3c6ea2df9c0074f670335120c50e493556db8efd1ac1d883db5a65bdb76a8d0808c0f5aaab174b6516b8bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001282bf2f514af539142269f649704f1bc1c0ceb67a10b01761332e32966bf796308d3c1bce7c2e7da37b0be8ab2312d000000000000000000000000000000000139fe7c8ecb824225a32da04d83c0a9707298426d8044fec96029bab91961e44c3ec7bfe889806c96b376b3ff63a307e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f6813640addf21856f4629116527d06ba771debdc2151bd56568b2beabdcc45677c67e80d430da463874d0b5fedbfb000000000000000000000000000000000348aa82c874289bd9f2b05bbd52c8eaae58a973dd00fa49d988309086e28dabb4f5b816e1fa9e110beb68cca89a73a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000007872f35bdb204b6327dbbd7ad775bda615eb30925daa8ae3c86e13341781d85518884f179efb0adfd90b5a42f7909000000000000000000000000000000000bbd8cd2fe496febc550c9517c2110816f1ef7f5a0b6c1c2a47ce0657efd5551a96d21c08d1ae78de80a1f090c4ac9821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007029c7310093f196832a99df00a350d05fe480a2ea26b23ea13d27b6b0e3e426139cdf74d50205727041061c3ef01df00000000000000000000000000000000037fa92fd0efa979db73ce7a50406aee4336c75bd700dacf4fa30b358e330566e19ce016bf3dfd09dd9522d40502512f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed2181d29feeff1c235b93dfee7bf61dc425a387ea703993459d259b045552eea4239975c4a27532a94793979969520000000000000000000000000000000000c3b7d5669630bb67374d2a7c9aad6b4b408b95cb6492eeb1834ed1d90c0ea7db7c034b8bd668564551b208eec30d8b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000779357704fae49f866d301a1b28bb7536dfc6a420148f7d2954a3832d2cd69f8ff5dd059f8e098e6e138d29cdea9ada000000000000000000000000000000000a27bd6c4dd5c7e226f5099a7b8f38694ac313f94aa78798821ad657b53aa2019cc3a45c8e2f40f357d45f835c8e74011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5a41c18205e368545c7bb4b9e7811c176c7b062729be14b4f8bec23a6e3faa326ebad12315960e285478d01709e4b90000000000000000000000000000000017bafbbe027176ac44165c470f942635b2909a372835d8dff421adbc07799b64825adc9f18a1b333209a052b87041c2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014110ba7bc682a0d4b9fedaeb5ed4ab8ca3f4f321790e0985c28760964fad0e29e0a303020c443735b5457b15bf85a100000000000000000000000000000000186ec37bb3557750f78c2d4b325093956c83f368a8ca7d5157ea7b1e1d8bf14096468b86b1ba850423ff0ff0a4076c261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031f425375b58829ecfd8d9295b67051e2a2438e97a28ac225543203bad9cf23596944a236f69a55fba7487ec24aade70000000000000000000000000000000014fce889975e94c8b51320b0365e0e38d5f5f8b9a6a163a158cdf05d82debe12ca38e34dd65ac4c1d7351ed3b38b61bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001819da455d89718a9710f8758ecb6e57f932c74bc1c4dd0998a82361e5193f38b9a39203460d2995dd30759ac7224b30000000000000000000000000000000000d7d5bd3fcf8351c77df5cdf7986b9f5f1600e7f704d26794eebfa32678bb724a7e6bd80f0cfd26fc5aef1204913c6871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077480d80988d453047545d67bc6b583f5711a54b5e8d96cfc776b3078e746b17b09e82fb44c389216f53e7da1b89c340000000000000000000000000000000003f04dbaab6be287b9c4136eef637c73759edaff3e1b56d669e8d37be5a06ec01ecc4a680260830c5e02e62aefaadf4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e599ae7604045136712ba67b019de2eaa569c84a4c00909f72ab671691c51cdef6c91c628cd22021efb9cab52503d0e00000000000000000000000000000000165f27c82d3075a3c5dcd926eb3379556895fe850dbbe7fc7911ac8ea9a12d376fc5d825b3af1fc4792ed84ea613b9421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163fa68801225853a6a56a2ab553042d93126c3aec695c437ce7e9ba8d7bd0dffb3f488caea9ee2ae85e15dce6ea825d00000000000000000000000000000000155fbc1fe231127c2e5d17827635d1a2f47cc0071fb2c9ece4dddd74ee0dfb7083a0d5ba7bd9ce1f791353461654bfbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c5d567b869736ae85bfba5112a1126000fed8fbcfb90bc2d90198c6fed9975dac4c994fa8a9203d5ec1375ffdab091000000000000000000000000000000000cab607febf71cbf072bcdd8952d169efe557b94c32f2f5b6211b09d1fde8d74e63dd13204046544c25804e66f2e2f8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b73be0705865a16d3ba7f2d1828cb8a027af47ae436474a18044be6205383874383a8d83375d7da74f1d8712a0e47ef000000000000000000000000000000000ca6384874e2011bf6cd6d9246e2646c196cadd50f83099c04904df8ad2202a505dfd27fabb5f379ccaa09ca8fbdddbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000652959c0891f96cc7a7111c45987751fab9a770a9359b45631f3788e194be2c2d92b51c9de23001883e4380e765dc25000000000000000000000000000000001685f0dd8a0df83f80b5fea28aa9b13f2a268e85eefc8f0897986557696f3e09b45d39336e8d1519489c2199914a1df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e4172d52cdeda6c4ea310036f5cd681766473a8074fe892e5e7c996d2306ba31198ed02052ad760f36cfa44d13356e0000000000000000000000000000000008a78e775c73bc4ae26a816496762a418ad517c7d9363504a9adc6a372b4bbaad89acd98854ef53d9753a5e0fe52e3781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e44553c0cbd43de05c35e6f2fd31b2615e56571ad1cef0c33bc6119a1ebe054f1a0e16e5a6e32839575133819f2508000000000000000000000000000000000a1619b47cd9d769daeed3a03b5fd138e0ca61d3243b738441a9ab1d770c53a67fcdc1258b5841dd207d591607608ecd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000378bb1cc2739a7160e6697b64b70cb8da96e51e1237bdd71b0240bc2c9000f70ea79d40adc691f5c3fcc7b29cfc78e400000000000000000000000000000000009c94198f776cc50958978fbca838b5b7b4843c94368afd038271af1d6525f9be0aa3a69334975713dba3ec3d1af9ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5775e28d3d774264be1f83834e20b6fa6edd5abf683f026ae81f1991c3caa1eef33d29bbe73142e0802bdecc63ed85000000000000000000000000000000000ccd2ded7c6997ad3406a03d621a13eb1d52e3472be37346ac2988c083be24763d8f44349accfc47fe6d4b83eb3b91f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018772447d2c1a35f00376cfeda5b719086fe9b4f6736cc1cd5db754b0d52a26efee34dd17fe7fc15bee160670c06e59000000000000000000000000000000000a019fc1101980a85e073e2159368eef1ad0de634e736b2b6f7873d26ef378e518cd08fde3cd8f2cebf21f8ec68bb2d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6c66d5e6eb6ee4151597a12cc5b817e271f2eb8ca8055e012efd86cc27072cf0615f93451778f8c2ce5dde551f8e30000000000000000000000000000000001599659829368b02b8b2f86c831dd70cdb5cfcedff2e6b189580d07c7ca67c4873ffa93a3f87d4e9ce5bf68f82648bcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085ca8409e7f94c70d2128054afe4b2629b47eb981f7e7bc75dbeaf9758dd8d276aaecf1acfa6e330ec123d6ecbb65bf0000000000000000000000000000000002dd3f77be91036d2bd6e3487455fde3a604e20a415c0d44183ceaaff486b650a13874cde5fb96b71423e1335c3b58d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001357f5a242a559ac54733056ed955f805a64c7e709ddcffd83ee9cca74008ee9b9f7997081eb680e8857c38cbbf6cf300000000000000000000000000000000016d5cad269366bb769278192e58804501ca241cb38bf46813ba03f5a769d08b3abaa409cd196b2df5c984141da9ce65e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150ed8d536c17bbc1781530f2e04c142f8ce0db43882acf5b4af05daba790902603a61195d9b10650fc6d6fc08fe198f0000000000000000000000000000000012fb9a59ed4ed98fea0187f4727d872039a0789361a3790e15de057ec35044eafb34ab6ef43752fde7863bf4099413cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fad1994be876ee6fad506fa19a1fe26d3c4db6575d3676381818de77cd5cfb8323ea50bdf38ec1286291262ff34921000000000000000000000000000000001396fbc29e77693db4c3a87b4f0d748686fb5967903106313bf441d2e102b402e961569f96fed315f5ee76ba105ac6c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019706ae7985bec036ff8dc7a0f2939b3ec7c144022274f4b52abbf6efe6cf7cadaf86e0f890c4406a190c10d98bd4f10000000000000000000000000000000000872caf5dac41c43b614180929c2519932b8936c989e01f73363d08becab6decce3c8b6d9d232f4f8de9f43867e3f7ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123676021903fde800c288c07751d42dcdf66a81f069cb77134bfe2ae46a4a5e16d2ed54ce853723c4dfb16477d6e79400000000000000000000000000000000185b4be8351b73f3c8b8580942903899088f53027c8ab1576f8fa001a7df2b613dbffcc1b6d5c6eb1c35f40600b9b96e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ad1c11de98b6fffdc2e156be6bd2b8c9cdfb078a60cc341a2ca3eda413b40e702d0e7481538d15d24b4948b148f4a60000000000000000000000000000000015e373f5090e22d9a7c860512964aa11917bf752bb38c0e5846bd964ea4fee5f5ff3e54d640f0f8a69e5662520765de41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b76aa7ba46e578af7117d96cef107f2dcc53248842898a8bcac635e54f937c48d4098e31f9425381a533105a7ba6ab000000000000000000000000000000000f6d5e2211f577e0b5359f00879b3ad6efd95c5f74e8bcdbac49d35585c09d8d9b06edc248329fd4227d7996107799f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9b3d170bfb363557e6c2c0bcb960abedce7513986e7326788642fbc2440d71263b14609c7337860e1a49211f60e00d00000000000000000000000000000000146a70ea9a69371aba6a3b8f279ecf2b9635218e74a9619da30433bbbb48e71a74c06e79449d96ac4d0d1185589945901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c732970e5e602abd31f1c556685f4675ec100ee4a886b8dbe5be6065a8561a4d4749613e7da5b8b323f66da826b3690000000000000000000000000000000017e322d5c0e73bfff850c1aefe8571c57360a85fbc02babf0959686b26bb810bcdcfee06bdc06cf3e85baeadb11df1181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bf3a9821c43421e8e4e2d9434e2ac0be59acf9f2d9c9911ab999e4d959044ab3cdfddb612a6d9a7f2b4c9af5f9360200000000000000000000000000000000132a3eb5f4300f8101784f3bb53eabad8c63da291c6bef0724c0e8e4c36b7ea07b82958d59eed7d6fe4a528b3320339e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198f80f0845c2afa4ac513de4ff3279095d1f95000e011498a56a51f635817a7ab1e294daca98ca683b8bd44ad913313000000000000000000000000000000000844e125f28c30fa22563808593a3a2c073b937ecd85faf3bd544ee81088c63c1c3eed62876d4649a6852a138dd49b5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb4fb563795e532eff3e3398a9ade2567222eb423d8fc847c1ad52d580417df5eff797af7e2c0cb2c426bcb3e3f50040000000000000000000000000000000016b6f2ed9adc708a7cd01e836b7ec7cdd1fb6d39c0efd0fcab7c0c7ed276c9a613c142b20780d545a2423127ba0589d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006de44339406805bf245e4ebdc61ed32ed3eab98640e8732aef03583914b59a45a05c5215d2d2968e110e6d417d53f8a000000000000000000000000000000000ba92a232bf4220d955eb87897315d33d24e3bc7ae4a8e5d021c72fb189294ec450bcd358b41aff2ac6ecceb943fc62e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f93023d31931a212d519dfdaa5d02bbc0f2cc7a3e0109362f1f0a22e8956fcc4e2de382c3c8f1f7884ccc4eb61a4bd0000000000000000000000000000000019f23824162c49843d9d3879e8698cf7c9099eca223f4a42162d48c38526de97396cb33f7e22d2ac0ce8e3270e63f9391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000edb8be521625477270116d95266698f362e615cc5ac18bcecd8b6742777947229900969ee6495f20d4fc27ae57256570000000000000000000000000000000012529ad5e084293db07babcbfe97135a1e55d4f0225fa8dd9f009882cadbf5561abb86e116aa496e95d4ed6a4dc8aec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc71e8386e2b112d2e4aa5ecbf7fdddae64b55e423b946a1599fde2b4fb2feefa318284ef81730f8b11b9d6317bc8a700000000000000000000000000000000124f45012789cb7e361eb705b6ac9164f3a0caebb66efd3e6f1da5636922ec050fb6271431663177d8af6e5a7c3de37a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000036e095fad73bcac542ec6a8b613305a193cdaec55366e186999d9ea4d7eef5feb195e8ed2503a5a02ad13037084775000000000000000000000000000000000699c63681350d469b3388d10d6c1b58550ffa7b0726931a1919241ed40b4c89b2b6ee89f9681df59876e0eac26b92911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001311427af3331bdcb1b63b60d9cbbce40a0b51eadcf67423953d4b7877b5abbf0b92b44d4185163a06ad19bd857aafe40000000000000000000000000000000001ffc7120e422d63ff5f54fa025211b329ca2507fe9d6418d71309c0dc3465253a203f5f5da32c25deccdd81cd2f42bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a890bfdc1c8e3a7f558cc7f74aced505c71a66066cee32c6770fa4a5de53123cecc3f5a1963e4fed884d4077a21e440000000000000000000000000000000009280b66c2b596d7744918db6ff9fab9556cc5baa96fdc2a5b3c4e2a3d72a99b1b23010f27f7782888b7c57fccccc7701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118872dac0cbb49bec69d60e7674a063fe23cbd0ddc80dae210e43769885d9f2f07ba4df90d4871807497f543421c00e00000000000000000000000000000000034ee1788085c4b83f683800d761495ddcc4d29c0c0684b0fa469f38905b768d13968df86cc2e6695447c7ac05a241c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126ba4331dcc1eb0f0ab8fba37e000433623d6c85d76e7d1b479957f07b051bfc605666cfd34adf747380de73a74de4500000000000000000000000000000000140ec96822b457b9e0990997d5d04186b770d3d0285b28c271f075529d143c7dc45c01457c3f9d2f77313e6eb8ecd47a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184f21f7c06b6b6ddc4e26ddd55f386560d2d13086df383d1d6d712494a6e4ae316a1389bf4de41f47175c38beaa670b000000000000000000000000000000000359239848314c2dd716497144b99b2e3bbe5adc7556ae0ed751f9c8a3e980a0cb9636609bc5fc7a7d750e12c16b63f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141f469110d069df3fd6c014ff5d90e030e312acf08dea6c5bab5dbc6962886d119a8e9554c2c0f953c2b2c35ecb9422000000000000000000000000000000001403c5004fea08c57e325f95c7a8bfbc9552792c186af10436d2a7a1ca38abf193483c90adb5adff22a42d7a98d36bf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee3bdc697647dd57523cd1d7f61f0cddbf5c16a1495869f2819a63fe196798858e4f365561f76b50bcf12b5189a5afa000000000000000000000000000000000b675667fbb500f9d0d5037c011fef8261c4bdf19f240d6d2435d8ccd605a942003bb09eea045a23db055015fa07e0b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000756bc58939ecf60a2dd0349362f3cecd757fd6cb0710930e7c6c366d865b8cc90386ab6af6ea77bf95e36544fd102b000000000000000000000000000000000cebef3f301421e4d3a51d0478e3c6828c2d93c8b22bc2d48d43c8fe56727761aa4eb6297f58d875a1a3f6b07907f9b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c33a0be4ec8267b3e1606d1600b5d2b9343810721d68ef83b523744ad352d48f2c07be9203ffcb42567bcd0185cc553000000000000000000000000000000000f01c1a0f42ccad5d28e5ea88e55afa7f5e27764ce8d864aa55de43a62c5184218a51a86c33fe7f6a84300310e7ff4091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015edecc0c0c5ae51f0a100f51c6ffa1449303c00ca20db5bc27f5ec6114e4447b3d15897bdca99443a65177d729068ce0000000000000000000000000000000011e64459cca4411cd2558a15208d8c2f2170fb988e5857dda57fc0d93770d45a187f7b4578d5651f2ce09491e163e8e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121df4a58be6de716b996b3e06ae71f21ffae78f65eb60e0fabbb97185b985eb0f6bdecb3177248e20919d2ca8e19b11000000000000000000000000000000000fd188a625994994ef96b8ba734f1534b5b8c0c4744bd873715f3b701947aa297ed562b4c2002d3d4116f91714178c061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dc946d71475881499320dde1727d19e897a096466a318b8047cbd1dc3bc30dad8e6ee17e698db1d1bee0b1796f9c02000000000000000000000000000000000e8a568a3400bd0150e8dec55c1ca3162e09b8fe26d607f34dff4bbde4156806dc58dd990ff47b95b90823ffb69997591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000699006917e93918d8b278098692783d16541c816684def1da3a0412dd0b5ec313e4045137e3193a3522eda93dfb70820000000000000000000000000000000012591eac0bf37346da8ae69b4366509383b5327dbdcc728311b715501e2e7ee8d407182957dd3114ca2ed207fee56b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142ee4c1eceb85d789f4d2c55c92eec8e47ef878ace960f63896593f115f95267e4dde607627c1f56fc18db54df7eec20000000000000000000000000000000008048e2696ba3cdb362de917a86095084cbe79ff9a88bf1b2a2b1a75de893f77b232ad8a46872645c908564d49bbafe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021abde2ff40b8060648493bb491bc5246213a619d76053e7f252e0ce1a28acdee1fa785e6a9495e1aea6c1dc03e5022000000000000000000000000000000000d5a48daefc9983a8bb4ac17c9d4b095d1d3037db2cc85d6513123a0cb2daf7597b102722fdfd38aa173ccff444af6cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef8875e376437420c269ec540133c5024dfdb14e6ef3af602dd0e3db5d0522c4091e052f49cf99662971bd2bc18054400000000000000000000000000000000176c555ac88b30cf6c536fac890c7a8344ba3a546a1afa1cbbce7d7e0f525c37f0baa782bbbf5e7506c6a1522ff6985e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c5b3c7e201e85dbfbe80a4c5da68275059f085d0b5cad13bafd28de796ecfb7de0bcfd8d76d2b0ee49ec9071f52b270000000000000000000000000000000008b107b3bb231c9de8a5fa2c9e9a6e06edf48b0deabd290340cfbfafe5e6b78df342f347d6643142ab817eeeebfc2fe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144a740fbfccb1dcb836bdb7a75f59fb5448d8d763902ea6b0019def3ccf7a816b2ab7e3b06d573da2ae23b4ba3dde8d0000000000000000000000000000000017cc01c9e7ea6f5b805eb8080b6cebed6da203076ab2dc63b94dbeada24da0cb66ac1d702a7255fc3bafd64f2966f86f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000743033d7f17b223991e86dcc6397c41961e5f433d529e7b2d70bd802b23a300ef1216c6c2a6a08d02a42b30b1ece6ad0000000000000000000000000000000019379244295f3901b61cb302bd311f942888eb8c8144e16ad3c235f4324ce00d041fe88340f702b975c01017224750ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d471a3b42295c97ad955b5e8dd70593874a1ce5d2caa02caa8312c0041a9e91e150ccbb417e1180c6ab830c4a3615b4000000000000000000000000000000000e6bc984561df57e37468d6671d7875caff1484ab4bed6497ffb7a89d8d80e84d18da64115bcf9f616b8f103e1bc0f1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d3f37ad63642b66ed2261c48e474c513cb754a62e9a14d6c2b5e65e20d818b9de4e82bfc1c7d783c18cc31097c49a300000000000000000000000000000000002c3cfa6cccc44a5f59607352c64be7a25f85a4c827022719b84746e0154dbc44810d2af38d45fd20a178e546bed4561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bedd09310652582a972b6c668b7ebec95248e2d80e121a14ec1b004ad2a039e714f16cb3b4f2dce5f1b80e3814a7df8000000000000000000000000000000000dc9b7c86c7ae4a62b06fd73e3b3363ba00b10b9e4517a8994b21365a4ca56a7b967bf846b32a02c7ab616268f7a88031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c1e55e8ce0fd83bfca9a92dd7b07e6119e3f99808ea1e5ed8b4b8ed2d34d23d551ab5e317603026c36b1959f0b8420000000000000000000000000000000000087bab4071035bf9a68232467cdfcca2bba846059137b087a9f4bec2325ab9626451c74c0fa910095dfe8fe4d85f3401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e7143af838b07482810fe089e51a04bb457257b86f85ade1f11a9dea8a5ca8b83dd5e1052214297be23fc218b1d5700000000000000000000000000000000004413957ff81bb49e3e61773bb4c794af304bc91933be8a11f5203527ce7a57489bc97e3220186068b2b5c88d853bdcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006be0a42ffb60887309a9886eb1185ac733b91c3a3a11cf44b5de0c9ddc20e5a7851d082982f3f7df0d8e5da64273f32000000000000000000000000000000000f8c8ac95226472a9ca4450d7f845dbcc161dd5e8b589c4a2b999af3ffc8aaa2a6bd9a487c0351b950ca5f57a959070b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6155056136afb4ac4f970944df93ea3b981570ecacef2fe636454ac517da9da4d0d124bbfedd40a215dc3fa565b3560000000000000000000000000000000006e1be9e5aef1ff27b5b0a82075d14433fe3cba0831c145a8f491290e9832b474f4fc343d1c44bc23a8f3a3a8d020f2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154bea7b1b48f22e10b6f3c71d876fe840d441bbccd81ade8e8781df2d960dbc6ee2ecc8fbbb6e6df68830cce3add92f0000000000000000000000000000000004042735cb8a5130597991496fe9964167e86f60a7417d7b7825ee59b3e2e6851a620f64424d9193d9fe56af71578fa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6857ce8a394ba8d4bed54de6ee15b513640319be99cfd7b97693695e1270cc4cb1bc6939b3e78d04cba8c574f3a453000000000000000000000000000000000a96877018396e1a439d4e2718d66518e19919d19abd89a730053170f1b9402dd81c79f175a69c10153d52dda53104821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012211e8fdcd093bdfba5de39140cf8c1f502821969daa3c235143360e96c769adc12ecc839aff67bcd14e9d5aa68c2df00000000000000000000000000000000162a49e7a364838b23dad9bb32d839cb9c92a5e8e45c58bf18ebc425c27b8043835e56b2429f8f171851d7ea7e38d3e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e53c67ca7f58bba88dc6862e3522b133c37ab09786faffbf1b6c8fc6d394a02f0aaeef47982234f08b19705377188eb0000000000000000000000000000000009df642dcf69ff4224ae0e9a55b592c0205a2ef81afe9d8b39df732b8298dd6496a4f56ff8ae2d10ec1129a71e8459a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074421114956cc5a2af15df2dec9ce7f0e3ba61dc59f5319755a56595bcfc949d68626829fc333d625468c32f1aa9f5500000000000000000000000000000000065d96088d236eeb78211e3505784487cc7a254730e0843be579f317033a8699891c6fee1f7d64149196abc5bf9f38c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dbf699c6947e098aaa9f4fe273dcffab86cbfdb13131ea0bae4b3f3ce134344b75f87992cb9be75ecb1e246e0f72990000000000000000000000000000000000cf4a77292c2be26a87d3bf7307d25a1f77d961b0143de455c940f885f883f5af358440f133069a74d0edac76c0c8ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145397d8dc6523a66d3081398e9799e965c787564cee729636d9b883711576ae85cba0d9d326e1a13df8231dca7eaccf000000000000000000000000000000001490e2a58cf87d08201b662a8dd4945dad713708e976804644ecf4105b25e313ea041aa028eb4ecc58404adb169803f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001268ff3bcb8a780ef75049eb120af32678e220a51e19d8bf09ca680f69770c166d81c401edb00676482e4e14c0eebbe20000000000000000000000000000000007c3836b848f0f3177b13a6d7279a54999e8151eb02f687d676d7943b85bdb4171615a21075d1c3c1a264e09c0217b341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000145cbfecf805c405e70c17af105e0ce724218fba898a23346ab911be56f551d9fbc4e6d75445466dd0a68f7c0806fed000000000000000000000000000000000624882a3c7d8d9e09c438646d7725ea9f6f0cead1f87e5a118cd73668054793302b84a218d596b88046f57f2dc80e7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013217272b0f15aab22edcf834b5eca759d83e2383c0fc0250e1b944dc74507570d0e18da1ea212d30e477cc648faea02000000000000000000000000000000000e50a2713ac88562596d7694034db5c0685c1e13052cd2226f2c7afa41e38c368a849bf12a393c7a50df9c0dc011eb1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004031ceb53b3f4bb8e8afb24a55eba83468a7da43c474d86c28df6857a8e667825a0d0204257690952e75cfe616d2e41000000000000000000000000000000000e0de19d901da10cc9fe49c4cd9fda32ff7588dac593e43e5b672ddc4d6c856e5ac467bb167fd70cb5e7f38d1dab694b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c533a89904e447c5a6999108f0da29d0fd6f2aebe77699f9c993c7b71cd5d79233ce4e83821ad19026a8d7acd31efd9000000000000000000000000000000000364da713f087808476fdcc327137e7e235669a89796b900360ce51b939b847c25f8dba57832a070d5f364ad522cfdf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037dc84e2c648dabfa90ec7f5c12f92b50b1e77eb986896a706fb249571bdf70dca2b2ed4a53e03b163652ba5f7d8cb800000000000000000000000000000000115ac87beed0b14a51da62e21a26a1d83fc824e6e291d102ebac2ba218235e8163e679bba80c4ab08901e9c52978c3571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001815c2dde829f569f1df0d5b7b29452866e783bf8e519d85c106e29c8d89e96fdb10a63b4df4147b7748cf5aedf0bfd00000000000000000000000000000000015ab8f2ea66c2d751f7f914cb0eac2ce2923a6fc612a5f93b197b692f501db2853028b1bfb76344f926603b83bbf000b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e36c68bc2bca54a4e3beb25401933b663e7599797c00b6d870fdeca9c4e1a4554c612568c37b24b3283020d3887323000000000000000000000000000000000b236c73422c4c69a74f5a8d7327bb73b422d7f4ca0866c7d67195afa5cef5ee122bee32045ea5c06f528b654409c4f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001157f02500f6aebd0a26a8fb4ba6bc9f05e761ad5dd8fa3ba177dbd208821e6a06938eef5841dfbb707dcfbf66aeac8e0000000000000000000000000000000018b9ff3d924eb50c376c6e15a0fa0b7383553fcc5ffe8c62df52256e206f497e5fad8c7d22717fe25dc8beeccb3fe21f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015c765d8aaa1a48ef97fd64fab9ec998bb9d58f2ac4addc628e517f88d50c5f2c7248ad7c0cc208fcb0d81b67be195f000000000000000000000000000000001752a28b5f00b7995354e14af907831bf47b591d8698abca0aafc2d13c2457f7a670dcf1aa869572c59fddf7913c31df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a1edf4baf0aa8cb4687e41d76b45d63c31825ab6ca398bfa93f2e4c8ee16ec551cd1d921ad7f32eb47f8747cd8b4b00000000000000000000000000000000012eb6350c10527702bf8e1087a5a518416ceab856b42176e3cb91a1ac10c414e97c0e26c62e739398d0121d68be98f441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c807fd50212c39028c4813f857a0d79b7a1991f1c1234d39d9faea31ff56f864e252d0bdc02699ee4a103cdef9771c00000000000000000000000000000000084a04e67d374e089ad70f1744d0f7d0b406da513f81bd902eff34172f631abd40d528f28d08e60d75b95610bee3dd521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dd9a7e0634c87dade48af5d5fe8b412cd18ef5884791555e8c7578c2fc1a090158bfbc22fe79ba1f68e402b03f6aba0000000000000000000000000000000002862528ee1f242c165f4c27075df4e376366330b00706aae5670f44c89ad101f2dcfaf9c5cfb82f0582f5206f101db51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191b47e70106c153e3fbb1c5f357c87fb0354773cf68a7a2a7df9760b3566b2085991859fcf17685bc29f68b534d64440000000000000000000000000000000010fbdfa29ef21f220641470bd3e73d1688776fe8c5077a3823e573aff799fa4263a378e4acafbff41433c5fdb539763f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9a0ad12870fe604e27a84c5fb23bbde6aaf57ae4de644ac9b559b1360827fbf99c85280e7eba1bf7a497f849c4a0780000000000000000000000000000000002509ff06932995092c9c7b9b026c08e69c81ba54dad2902fa5930d681b8eec4b7370c98aa4a42968f5f1e2ab17dd2571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b986c21282f87f2f14d2bb9166883c4399f96a72300b97a391c5eb1ab1d72cbe7c9a997122f8335ad1800ddf8f62e0f0000000000000000000000000000000000da13981618ca2f7bc9dc171f60e74ff57df21da80ec36493020d69075d8db8e9a91020757f7493003261991c633e851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eca7d4d7313129ce4800576af1b697fdc4fbfa3a5913738c67d6d1b383f52901585db9691ce2821217d8eb2194d8307000000000000000000000000000000000312f82d57916cd0ae1e4da8faee30311da773b2e8e5fc880952aef367bbd56491811b6c6e01305a5c55b7edb7d6259b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001069a0f057410ff71abf433dd28d879fbc83d83777b963cace91ccb7d49497c2ab08e31d57f708d98568650c33abc0fe0000000000000000000000000000000005f01f7b0333297a3197722396e3d0b56edcc0e3caf393a602a71d8520fb86a9ee10c219f1bb193c0c04874848bfc9cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2edf6e6443c88fff071175530e1efdb48bbc951d24449b88fafc714d6faa4237d7777fb6b29cafc02cfbfd02bdb3da0000000000000000000000000000000017ee7ed5d203cf97240d0f0a1eea42036de179a54b61419a13cf6643b6556d3077ad1d532bc7535c5b66c70a87c86b4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000619be43458cc61aa6d06dd850a465c9a21f4527d4ba34660602750ef29a2c331fe083199f3caed0275a67cc89082cbb00000000000000000000000000000000127ea18a27643b8686643e889d11f712f352bb2ee224b2963fad34840f3eec0dee37d28e6169894c5c45adf99e5ce3311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8d7f15636e7ca9c016d82cbedef1bc35126d38bf8907640ff4e83133f6899ae6adc05830a0b02aaf608dca9e3f51f0000000000000000000000000000000000d43fe091ddc80f4d9f2506a9e4c1e75c7805a94e634bd18a267b1357e1fa9e0e4deb2969d7067db6280504551406d091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9e0ea3e9660ac5ea57500cc5bf29fd424114e47f6807bafd1f17e924c947fb29155c041517f159ec4596d13f6862e4000000000000000000000000000000000d3be5e76cfc84d0d9b6efb08d4a99bbf1b58077b3619a0f194c30e1d35ee38272cd47ada08819ed94819ee90088dd211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001828908d602186306ef8ce89cfb963f03381cd4c81d503a18518840025028ec7e1b8a8d386db3a38ccfd802ca1dcf98000000000000000000000000000000000d305699635b6db5a40b851617ecdc0b5817bfc44f8582582dc6ed6738e55625537935435507b310c3c4e81e5da008061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154ab34c4819decf5e23bb82cca28ce96663d0ed8b51e4ab95bb98e5ce8d9b398108f872b6e61cf8e33836f7560981c600000000000000000000000000000000105585801dfb130376bff41aead33aa29cbfc475240444ab433c46cff54feccdf7a0dabf1ac273151ad9cefe58e2d0771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128a800b0b2f19de244dfa3dc94790119c44b8fa6a3e4229615b537c89586e1d418a762fd342858ebe6de294d194ee0600000000000000000000000000000000057931bc8a3b17d8a120aeeb1b966e46d84039b998547d09485d8631ce773edce7557f9aea830864c2de8169aef7d67d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001007f7600a3d4d66199457f1365f59495fae9201cab61752a094a7cff657772bfd62482de69221ca2636490b62a100d9000000000000000000000000000000000213a019ef9d7fec41304122079c33b7d0a5405aa42561426c39131714e44dbc0ff419feb2e5d26a92da93f1b232ecde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017010a3a78bbfd11e198f3843d88e430da71f413fb35962d9b36fa1a8a829fb9f47cab3bb9b4c5ef64025b40a8593d38000000000000000000000000000000000a127c02042f8e96d29751d4f8a4441be2c5bfb2054a4fa511bc06223aaf2fddb62a0ff5728b6f578d1b8ffc251d30fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c890f992614742590462417177bbdbc2e1a1273bba99181cf2959fea95d54d9f64d5b1136d34f62e401185aa245a2d00000000000000000000000000000000019d8c91b8569eeb2707c221b5bf9211daa1274cac523febe10b7c2a187d3d9f1afc6100e94226e9b5512586073e56bda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010866fb0c77bdab22c854211f853eded9a75b00a389b5cd0895af62ca46a67b74cef149260fd1b38f6d7b6a2417194bd0000000000000000000000000000000013bd86e8eec9d56c659e1e75ff788234f045d86887832ae702ce55240e2957dcb42fb5e2831a854ffeac5e056d420ad61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cd04cd812ff178037846c102bf819a4c6abd1040b8f2da0720e790ae5e185895acd379013d9c8cda5eaa491dabb78a00000000000000000000000000000000015109df531c7b44a2f0bc1974e08a74d73544c5110278a862399866d1caf93161ad122a06931d31c572ae9fe3dcef591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001568e628441de2ee69238f1bb58695a8c55a8ae59d7f9d3f424c8c3007069134a9f65ec72c644d6c6d82790557378a400000000000000000000000000000000019fb7aa527b58f83180160977f946dc05a40ad0d46073488cfb0613921524c6eae4c6be89a103c043a0539773506ae301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083ef11db3f4279f4be33887d7b6055c62a3ae0e7434e85955cb18243686478f709dc2b4cce44eec020a427bac4c74ed000000000000000000000000000000000b6eda2339e19782b7c6558d9ee1110b1061d904fc6b239eece067bbef122122e5c24e92ad8f90655240ba7827d1c5521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001836767c24d768cdb5240ac0f9b700dc389fa2cefe2b458d3bc99ce381a40bd8d65c0f179e6d3042e2a46e9a9f964f1100000000000000000000000000000000023548a51d397503267a767d7c7b9b590bd15c05b76c529a6a2994ad3d78e3539f8d1db2c080dabcc63d0c7a58276e5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd858559d6e083305f03ccaf363945aa0be4bd1381cc3bd09412becc37bce0b54e30e7278fc63c4c3a6914414faa65f0000000000000000000000000000000004de8fd554804adf28e775b975100cdc3c1db1566d7408c4dbb0b4401f3485a6171150f12fdaf5613f7a5f8187703e301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ce85e6e6cd40dcc83ac267549bc67e0d01001fc5af6175d5f97dba809f1e433c69c123ab71083089e2cdc88a88d32c000000000000000000000000000000000b08fd777f1f88fb30f1fc81a43a825da0cf8f983a94ddbdab75c42549e81d7662d4de1c2bee7bd74ca318e7b17a41f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000114895cb9f757500b7d5cc8ea6ad2b7dff13baa0943e25e42a5ae2769ce484f1fabcb58dfc1ae95820599ab7be718df0000000000000000000000000000000005bba7d46bfcf867e3d5dc6b84ca9c645c90318e7e1c47152a54639c733e86253fe68a1b2b663fa58fb24b8043829f291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012630ef0d437be224ad9bb9b9c567e3a4040799a4f69af73a9f503947cf23f6d5f567cd67f9ec634ed7a088ec02145780000000000000000000000000000000018c4dfc51c3ce162682d1009f7bf7123537efe4676a8a3dc08d79ee626bdf9a876bbea1b5bf39cdbad5f391f60f920851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc6f41294863036193eebeb3e8e5c06620e5888a86aabaf4569fc2eefead888aa17c9643f8b63785f809b7b5d34bba600000000000000000000000000000000016ab14e90cd13a4b2a586f9d34579ccd4aae3b026853915a03349984c3bd8f38f43b4cd4618382942db07dbb07160661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154ea69a7b8cec7219daa470c8d7f38a8668dd9446bcd8c084d014875cd04a04ee3667e36a55fb7501bde672244105fc000000000000000000000000000000001544a6ff55e51ab1cb89031f9028e89a6ac6d015dd686409c3913972fc207a72c3878fb1ea465f7f1b03cdaddfc8f4911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098878c9c736a5321f596d9873f0ca50dd859cae8056c19ee69b629419e5779f6bd45cef6993511bbbb68f40bdf2848600000000000000000000000000000000193103c5cdb3f7d5541b7b3b930ccd1b84a008addb6c0f726774f51207ed1f30680fc59311f70146014eb5f0756cb8eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ef09e8249af0e60c11e76d088671e2f6ac421e9ea0e9e5d4680be885171a698881cfbcc210550fd015222a6d4830a1000000000000000000000000000000000bcef87d0d39b8f828873c909ca31b682d2ace7e5f5744bbf5086801d0f3ae35e1e39266ec683b47668b6458640869b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016b25a4f3091cd3261d7de0027e49e91b8bbd6a464e3dd586a12f1dd77ab75b05e7d1de349cf47d545dbd77cb610eaa00000000000000000000000000000000055f3392c75a8c638a5146a6b001936bf6cc6d1dd39e8009d881ca30c7065595b5c75acb53a9dd72746a880aa06e43d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c229fb295e892fb5fe971d0ff5bc74cc36dfffe0f93d90701d057a43ecc4943e9c3e8ea744a983ee6f5ce49f8c4ae2000000000000000000000000000000000120195ccf1ee4e740e2a0d363aebb4dc36a48f623f70dd8702e2ec308e56f7c80c9f83d86083c7b366ba1e5356e6ecc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbc848e6d74cf58b9e3127cbd9a4aaefc8128fef7e9a43172a3c7522829e3b7fe3fd078a0ab849e2a1ed5b86d417d44000000000000000000000000000000000dcfa794e0f7ad565eac0e7b9f4992e8023471456d34b35dfa0dd8ccef832dd2eac3c9877d0d8a5880ee47577f71fff11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143185db8b76f85ad930c40db60c7b92fbaa0e85dbf52fa6e526664b2f33d3a976ed4908d195506921a770d5319f386d0000000000000000000000000000000012b7556f604e32e720d012e274f19ad9a8f99a8204a2de33d99979f0b87fa8a11842b04c99276680815fe413a72470981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1f316e66c849299386f00d8db861d9f36a751470700d4873134468401cb71930382ba6f1bdd311b07e9303d22a6a7200000000000000000000000000000000150a097559fb85c34728a9f0e778e4cf1c21e0c51a99f74440bced814f0e4374dfb91da4d54913060c78f9fb2e04d3011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c678fc32fa63b7a7dad518f16df22cfa0798ad21cd01004e0632bda4e90039f4227b5ad4073e926b9fddbc907961af0000000000000000000000000000000005a612500d21a7b4f9852e87052996b888818abdf4fe4465559e74b43164a74a1ad13988e2fff6a49910ba09fb80559a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a4ad2a8aa1b661529fffcc23c3e68d5f3aa2ce7c2e396981bd9c4738c91d037856269e1a8c0a3c7b1d836b41ea26640000000000000000000000000000000010abbae874b42673f1f4ce0b12748947bc75b3f14d42676c24ad538845c3bce5bbaff7d5ea119c5f6be951ebb6638a761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008175cb8e6134fcfaa4aa15f238e50488b7197afbbb8dd0670f4141d49ff7142dffa3779f8f5bbc9c8e460bd82855e97000000000000000000000000000000000a95fad49bf16d1378b2856f930877644fbfdc016834ec2c1b983592da9ad7ebd67ffd9c334f059f584b26e73afe36ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f869ea7cd4d94c006778223fb70e1ec9d0a87f0ee8b7c240b2dc4234bd01e20912cdcdb33f166a4d706132b394e5927000000000000000000000000000000000185304fde25c4f9859518c888dfa6caaf160b352cefe8c54b1e83b92d3a5489c876695a4c094eef4c9c24990eadaf3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066daa3c6dde4643f10d5862e3641b9aff43a03fc42846f51cc52a0ad325e4d68d9e83be1564c3865c5e8fc872a4e31c000000000000000000000000000000001614a8479a4338d804b785e3ace73e12ce2f04cb07ab493c336efcf78e9e2fe2fa0e35d0693876af10a40ddec21dcaf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012233db40a14d7811f6ecbaa6e24d11555747fac9cf2f36c88b72f44e4075352c511dfb73ac76a47545f342d4f84404c00000000000000000000000000000000122692bdc45fa1c0e8c3be22c9f91884efd19c9c76725e755c0225bcfa6e64f07383577fe69b87596066e18cb59fcd901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d994d57e90500a0884a73d4dabffc7df8aaab82d4585c9b58000f9a44a25560296206365de6944a6790276266ead2e0000000000000000000000000000000016aad68acaff53950f389709377f4f9e6d9409258a1eae4e29b04d094dc266b90288587d7c5b2388c642612b39abfe7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4d7c713712fdf7ba3f6d20f522caf6419dd6a3ba43c4aeea8da0d0259f5a2f96a039b98b29d42947391520c2bd137f0000000000000000000000000000000004b2708fb0f84dd3d248073ec80d1e7fc6b6f3134dca5f8ed25a50a7ef73170e146c6c08fc4adc2f662a844d4c8e25861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c2e2d57cc7cec793571e27701bcacc7d3bde470ee8ddeeba0741d15fdac4011548d8afae9eed76a41286446155d40500000000000000000000000000000000195889feaeb2575fb1f663bbacfcc18acedb14df2645ac64a640df667235795817b726db68d69f5d0d63c85cc7cb82de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c47827f5723d859693447bf7185ced38cff1ed839846c910a107a42e1a047fbe202e0cbab8844dca58f8d5266df111d00000000000000000000000000000000151f495648457ffcd1e7d7be2e180da1cd38808c1bf9d4aad310bd3486095df2051b99a25fb035fa90796f34b47e98701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aae260574bb6da71056c3c8a5d84200826b6a97abe867855182e8e6e53cbe19325502ded340269453292c3f762585620000000000000000000000000000000003cf6d453f059779c878c3a01d390c995d122bd80d5351092175742cdb4a1ff166f674c457f456518a47876a73d5dfef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ddea6f071371f56a4b2dde2d2f8219cd27216a569de21360824111fcf24f3457ec8e6aa2067811819897e9def6fb7200000000000000000000000000000000121d3a14f0790b17b0c968340ab83b1d784d2c48b09c779ac250d6c269299be964f277d6c66ed59c068adcae41c6ff941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099234473ca20260b0398b2f5ee78c2239436926539c448b43422a0384caae2b334cccc008076c07e9de60e4127eec350000000000000000000000000000000012aac764870bbf5e184823bdd565a27571ef67c46cceb8acd28038abdf3a420366c6736fb225243ab7485ebf52cec86a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6766f7a792838d01dc24e54b65a6da5e052c786d04950800e04e82f6efccddfe911653c9344b61998cafa905b54dae0000000000000000000000000000000018eaee2ceb76ce13300c9f0feff94c55bd7045a53bbe885641664ddba9fe816d6cafb96434019bf5328acf3a337c13741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040eebf62e09bfc901443082876fd3cf07bb8c53c0a9aec1eec96cf001f27c856a379e659a85dc9d3f24e12c334347990000000000000000000000000000000005f658ea599eaed57a0e7938399feb863108de0a1f3cac41f432c0fe3300bab4b6bf2f846f3dba035ebca8fe0fea68b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001493580df4755e68bdba31105f2ff22b975b84d1187cbb40c2de99e02be61e78d629d29476b0a2d5cbf2cc0bf3f0829c0000000000000000000000000000000006d2f4206a52f8b1c84e2050a84b98746ff613d3dc3d5273a7d7bee924d343bc760b85b80140393fcfa8085980fa8e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4492c3209920dfb86c1406616ea4919fd725ee4a3f6f8457db5495ac3a225a9d522a46e0d13973adf51f8af3c01707000000000000000000000000000000001252873b9fd0639be7f39cdc8a79701842d3110e4339fb2447e7fcc39c78059bd116c4da60a3a54a57b4dec0a59870481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b3dead7f62ab4c21aee71e55b020c8314bc24a325d8e71da810f706324201f4c96f99d572f118c29d9664852fe664d00000000000000000000000000000000085de1c80296a4a56103c5c47afd9160023e71cdf47426fa26ce7faadc802f4b776412dc4b3af445a13a1de6a4f8fc0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013432280dabcb187702a74039f51dec08d36f4856670f7df1c55b9edc0fb091f6956a4785d641c3d39afaef155803ce000000000000000000000000000000000948a4aec824e5219a67bb281f9f907e143e279758597c14ec0e2b3ee9fe1ec9d0ace4bd4cf16ec4e0f75fdbe6e8892f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035c5ffc3596c329582a89967e8c06639b9806b5f741e8cfd2ee13b806906e01742772130f5670ac21af059ef796c177000000000000000000000000000000001028fe8e131bacde6b81cd04f23aab71af6b8885c82e609bb285a8227e11846ba84024fdf99a2f3deaf2f6384d1631021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001875041f25a3300503986e7e0ce56398aa7ced078b229b30886ac544a3f874a22202d4ea91051b50c1de44744876236d0000000000000000000000000000000018c89626221d6ef6e87a40839ab4290306da65fa3ea9838cc0043a151d8cfd09e6ddaa9fc2f0b1e26be6a15ecec31a7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f8b148fc49ffee4b2239cbf62b55cc7047d6632f2b4ca3e49d7e141fd6a752b2ef24db0850d5ee001df02d32917b2300000000000000000000000000000000077f46d2e90eb6343cd42750b8149a8c530f04bbbd6a3cadd6272ed1ac135bffb7f809388191e04f0517e9a2a2cf6b931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001886c741014fa20892453ff11cf4ab340833fd11de79f9f1cd637be12567286b1b7ec1316ab059285dff91e6119b83530000000000000000000000000000000002b5a460276425f38083a161bf429de8824d5d7e6490876595c2ed8860e40732d6c14ea5ca2b12a56c64c1054b4651ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb73ff0e856603f9fd7df55f376ba70bf4d907a29515f5ead5c6a4b07f4e5b923b8a78418d4187fd76778a03475710000000000000000000000000000000000495ee67bebe4fb0ad67dd591c05cf52f983ea6337ef981fc2bcbba94af3a07f10e72651158d01704a54218d7c7d70591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b1a3a01e8ea884762181a21e6d60b8043f30d983d32fe9bc7c4d1626a3881c29ac53f18e0f96953f6fb08b2d245674000000000000000000000000000000000d3574de3d835207863a04ee677559ff0dec0f6ef6fd1017c2e92614670f6a675794df2ae69e6a7dca46033961dd3f2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000930375014bd014ed2041793ec4c9624da85ff3c175cd4c24ff681f0d98d717a6033b2f9a568d483c8c45295278c283500000000000000000000000000000000074ea0c9de9f5bac5eb796f43f09ac55c127199da97cd3c10e115b8ff7132b2f58457e26c2686a4d312e9073d808b7451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffb3c93d9a328c17176e83e9b713c5571ef4623515caa1ef14996c61fa1958dd823c149c54063d81356c80851f976c10000000000000000000000000000000007fc21ce2a49e6212d06ee39346a182234d870dee57b561a1695c1ad6971270084d760610368b3b1f365ed0d829e3a6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca4d580bb1a6a1ad9fcf2947056f1e8bcfc468532bf22a614dac94f5791f9cd8db4ea371a3c7d896158d7e4c0b0a7ec0000000000000000000000000000000003bb0a5586ace18cee632a266f92f80eaaf41d9157ce11fb709a0f6dce067bf786649394291414d8ed01058e0263804e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012105eba9cc0d1781c546d89d8e0c36aaee958837d78b00a57afb00fef1e962afe7367be0c66ff963cbe5d2252f4a4060000000000000000000000000000000015a23392ba36cf75ad14d9cf6e16eadb52c4ea83b3c7e668bd50c1c08eabebd0b46f47d37f48ca2dd80feba83ae7abbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3568497080900aee6088fc2c1a15e81936d4379ab1a9e93f9056b0c9f1c9b494e41f0f3630556f6ab63ae542d8321a0000000000000000000000000000000011d974c8d02a8a92364d66049e9e49fd4a81faef328cfbf4b471d6fde8a397b50e55d040059f493944134e33889c76231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108939de8775999e594fa333f249b2508db217a0359b6ef1913f2b7e8eb7de4d125f41400a0e42451e63c63bc8fa2f3a00000000000000000000000000000000181097890c21da497449c563a6b79658f92057d3341bfbf0348af59a86c6250592cb913418067d80b4f9966ea03916b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e78dafc7e44571c92889f1290817e9deb13fca0befba6d10142d02d5eaf83435127c35c9c0883d8921be43d8bb1bc330000000000000000000000000000000013ec88b3a5c989cce81e016396f74a3e36938ba26502f0566361af474918f8a9ec29a0e3ee8ac04b2235dd380789e2bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a28f5d968e7d53dbfa2d05bf017bf4effff65477afb47fc7fe77a402eafa3a199d04f5a9ef5d3441a5da0e9b201c27a0000000000000000000000000000000000d76e939ad10ae63441193699f1ab63876fb06eb9b1fc9a825a3aa3dab34864513bd8a0d1d2fab7e5238498000f71761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000138d6ef41385e1d5bc36821a7793e048a435bd8937cd7c1105b58d406a1783a988547ab4a0a7468e022dfc388eba4f6000000000000000000000000000000000f2daffe9319a4ff8a0f576fe616e160622c1f388b5bf3952f707225243482c0f3583709d8f58b73cd0e8ad0eb0cbae61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0aa5ca109ed4e94f2797202b16b62a988ad36556facbfe8fd4dfb9d487e055d67d456eb4542e29b5dada1d465e602800000000000000000000000000000000004607f9ca1ad5fc1698046a1160564ac6787fe944eb7d689d440a49461b67cf9e4f6cbb2d9a7c0f0d50c5153fa792e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018db9f7ddbeb66de80b4c09f7f84892f426003e5461f3b5607b0fd9ac3bc2565403ae59e0f1505c404f44dc07f2f8dcf000000000000000000000000000000000ace3a9b7fab0f174d8358ed3c937da075c41024fc14a68de172f03b1ecbe0054da269c3258462f595795db1e2879dfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b886483d9b0c17899ab7803271308dc30749b57b536ea41377e903b9f59bb072da4d3837fbba18750403de69a0cabd6000000000000000000000000000000000f44967c5b5b5aff09b48765817aeeedb150b2fac543d63d308ed1e290703f10fc8c3ce3033aeecbe54a10bfa0faa0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7219b83db0f9fe6d54bc20ea95b22ccc6b9b0d4fab1d9a1ad77755d6f6e5eb2027139e900d6c4a43ec5e4d81516556000000000000000000000000000000000453587fe3772ee344c90e8beb40f1a6ff512d83ba8afb89b4cd7ed0e2edf2d9a5f09f9dee3902eeb89552354fd33fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e079fbbbdce1c4b6916cd4e286a7546d7d48e2addbc476214cd6d73b8fc7b9e8ef9814222c173b47bf99e5793eceef000000000000000000000000000000000c36cb0b1d61103aee3ba4302c74dc39eb9746ca547aa864176cf555431c2f84c7d89b6b5b91def85bb5c78dd0626da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c13ad4792dd1a367294b6e23ef25bf40c24541708a0aa8732e3e00d3110cacd4ccebc302053a195b6a939af3cb01a30000000000000000000000000000000016e6149eba722cdfb5d093ab07fce6ef56d6905ca701bcd3ea5573016be73d55d02ad45ea8f291a1217509097f0d03951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cef392b1866ee3859cbb6c0984a0f1daf8be64b10ba8df55917b56649634ea6429746110c2279ccf7a6620e529a9f900000000000000000000000000000000002841bb1ec89a8174a530a5be548c5b17f49d28c3abf5ef2fbdace53b26c57f86843611508d3c6f4a26fb4c9ba3d6a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000302211e4f02f5e66d923a1d0099c47d5cbd4a52cc46978e3e159f93434187a88778b8bf6f9ad5209d311184596cd805000000000000000000000000000000000a4130c234052eb553d08b9e8fd5cd3b89a3ec4ab4effe73fec180b807c27cb83a5e8185008994524fdeebce1ef1db571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189e798158758e16e400d73e83c86ee246f7a96850a966a823910f768b043e119cf29bdc1ebf84f11a1c4f4cfc05cb6300000000000000000000000000000000081f772839b0cf02a5e6bf99b72f38e97db853dff6f8db59875c72c08a4228e3083477c86bff5ff1c168375e36c73dd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a4ce739ca82b934419642a96188df95080a5f292b2328a33508aab93df98cc3be4af12bb94df30e1411b8bb73905170000000000000000000000000000000015d55141c4d00b23c8b349bea0d27b74097e15637dd984b3bc8937e2dc5f984e2cc268009c22acbd04e56caf36062b781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9342387c9f761bd6898c0af02588b8d7818e0b2a03202555ef22dbdc4714220f96faf3243ced0f8919ccbc449ddb510000000000000000000000000000000016370ca022f1ea2bcfae1d889ac7e2ce2bfbfd95d86595b4080ec4bb2be3700b15895206efc5c68dbb6fc9bd4f81b6371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000435bf7116b62f44a6d85e355b71c3660272fb74aef730f85386bfb38c11b2084d9e72d76863be7fcebf368746df5c0b000000000000000000000000000000000a9f6b1de627a140fe2a8ad7dc21ea25f0a21f528527a48ea961262d609fbd1af60f47931b95236d693141bd6790022a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000530acc675d5c9bd8d592d982af64af7e60a72788e930581cb7293258db1646a4c1ff7c2ccbcff5f606b3fcda4d246ee0000000000000000000000000000000001f7f8bcf4c62cc47de86ce3648b73a7f50bf86db8c2bafaaaae8dd50889428b2ef92dc1f5a1151b3d146b98832f1b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198e840576e44e2338d6ae9928bb4a3c4aea152cae033e221be9720444593f68857b4bbf810b3e16ebac64fcae3fbaa80000000000000000000000000000000017b188bdfc6e4ff1e46fbcaa9af3e1f5c397dd8718a1a2a71ca3c8fba2283335f894bcced59f00d7d97837673a8eca961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1e8f8d4cd7ef39895df1f5a1bd3116c25731af66ebf6784ae944a7f0adb6dd420214f93b2d3533f9d3f5c089925bb50000000000000000000000000000000014a43754ad5a364fbc16c04e252a8122f079c224a06921399d400c1bfa47905cb532161aaf834da2cf424623ed328b1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eb791c11d3c4e9259fce002dce0d8c065d777d3a00f6e36a86f734272fa230bf87553e1a805dbeea2124b9d7a4c1ba0000000000000000000000000000000006e16bf7d0e5879c276ad0362e2129281520ec9acc0931bf87f90470fd0d8ca71a75954ec6b8411acb5bf478dac63d881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a3c008c7bd09f84f9d2e27bbd0ca37a90b4c46023336e22a2f7acd102f1c5c39c61af890cc4b52fc269919b37decdf0000000000000000000000000000000001ed0a323bcada851055acfe683ceb61a05561c12acba4a04f4965a87d07a7ff0b09c35127254a015a8244a39cc3cfc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001243efe3b1f4b9045ce819cb5f05959a629613fde94f21543b68a38c19f478d16b528bd0440e9e952318a6c5bbc4c8ef00000000000000000000000000000000065e968481d8cefe1073f66c80c43a013fd48358e9ff8b2b4fcff50f494169b3b66a2a7f60f281768db5a6292882f3ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031a84a336ced048687ebadb75b8c3a199a59e0ad7870c707257b6f3936692235316149106cf706c22fea2fb2dcedbdd00000000000000000000000000000000022d3239fad8fe21adb726dd748b110be09b7fad304fe70b731b9d0c4701b2816992657d5d78e42b484b75a497ee13ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164fae5177baad7c4463b6e07a1c1fba7b945d1127b3b3f4e8b20d6977e3adce7c5046424d3e44cce3388c2ceb968e8a00000000000000000000000000000000017f62e94a394e063907298f58ff135fbb741903f2129f40e8ca193f1534b845fe9c9a6f1327a070cc19d71f7a69f5121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd59365a6b49323ba5f8aad6793cffe739ad7ae9b37f65624d2432d7aef2b243063f57094de3dc2f930c1438a3b3254000000000000000000000000000000000299afc35f82281d20db13c62284b66890df7fd76f6c73366c3f076de7c4b4d9c83248e0020e0ab216e4f5bba5a340821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112b890a18520f0b96e61569eb0969705e9833286a4490ecc7074d0195391ee90015c65af09d3f4ebe71b99ed692324500000000000000000000000000000000189c003954a811838e6a270a8853f9dc8d3a677d3c8193fd9689689177fbd33ac17fa299d23b94c9088575f419da0fc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047c9125f565cdb09ef1d87bcb296c6ca017f7002bc22e85fd9af04c610aac0f6de16cc2b3963aa25f01f3fd3c78d584000000000000000000000000000000000c637e6be49818ef5f5e437bcb4df33868c1f1873f802f52fff10ece9c4728cf0fc2330a6e0afe39a168128a8b1ed4551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c666645475545a5bc6c26156af5a63453538041151ec7e2081c37d9392ca650a8137e974c4d83b29893622f674d5190000000000000000000000000000000011b6d50f414b4e1ea7eef5106f7be76936b0e0b5248064bccf910171bb9ee8778d0f4167cd109c720852181900d8e60c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa96499d1882318fcc1d0f3416edfa957083ed9a513f14beb05ea569e2b89487663c41d1040a55bf2262ddb2054e26d000000000000000000000000000000001383c4ce3b72da8cb914494d7e22e449d395d1479d498fa4a19e4b4ecc7443096d4e74a51dbbc6ac4acce55498b241ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160276faf62d4a300626f8e02715fa8c910f8994ef90bb5e38062732dc86f551b88cc05c30cf4bee73e57d7307b504920000000000000000000000000000000013d0c622a654180e5d6e81555605926c98f5d49da6fd633ab09dba5c2bb89b21857c6b1baa7aa6b203495db441cbd2421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001393b7b9c61a6839e421bc9ea04e58caf8937d5afd265c1bbd42cebff6c532efb98862063c9a687166b14e0fe5a4f990000000000000000000000000000000004c68038b8713950c0cabbfbae7e3c339fbae54103aa837ac76de8f90fb796cec3f19a3b744aa966d62b38f493b54bbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006690665c09bb093f55c468e244e68416ddf174a876e928f62524822b345ea2e63a5e32f15919d62d86692ef1b552323000000000000000000000000000000000757039336f92fcbf0598b48e2b6a85acfaac756665dfe2fe5687cd69da931aef0a8feed3a1646eb1000fd64d547340b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ef527aa052e67b3b76703f9d34dde85df8c310760500ce21811e388e3df6ebdd531e233b8eeb5a95a797b0d30965f2000000000000000000000000000000000588cf8566df35e3862dbaf9a1d25567992bab182a99064b8fd713f9ae539dec3cdc653dae0cb75b710db0a9b6b01d731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8161373f08de661ec53ab6f8abed34a168420c8e4587e9d51e62b41cb43335ece586ebd0dea13ee508e45ceeb1153f000000000000000000000000000000001352548009c573b6541d01be109f3c1bf7fd99be74465ad82e6e36049f73b2c290ce8ccdd069ae60fc3a644a767ed0021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015aaecbd2a4ec8a5b1e0c49bc8a69c4dfcfee1d755ed527f9a7b41f845becf144d42650fbc44a50533fdb801a53ef5720000000000000000000000000000000011c4361c94154abd6e59e6356b68b78e1089d86e802d5827af9a30181c47e0101edc36b51340c4577838300042952b571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5a51545c855d0610fcf4bab6f3e57be705797bfb5f475d1acc6f55ae5e298b027a8bcef24654240835117947ce56590000000000000000000000000000000001c2acd076537cedf746d080287f561d8a6dfaab226e1a34a4843a16f59e9075c95d1613fab052bad6ea1e2a5ea744311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2cd413075677ec340d96d5a15b2eb37010b3691f07e1feb32c75d3491d5e4c3220209b452fda419dcc0fdde3fefe480000000000000000000000000000000003955d42a6268c6a02b10b763816f404aad938f82479db3df7681a7baa4e57cd7c3a5aebbb5b899b3217b93b734820c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2d5e66ef50c59f164a93764f2462001c0a23733e83bfc7dae7ec123eddad518cd0562fc2f724c55a5617d531bd8e830000000000000000000000000000000018c4741589637af91f8bfef16a0987a6941190b80383e52f7eae196632e8228e86430ac1d1ddb8985e430e04ef7b70f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea1753ae659f01a619056f112a9d0608e39d5929ec158ec75a2450adb8744e305cdb18cd7fb104f0b264b27309f6338000000000000000000000000000000000bdd2554c0540bc39a4e6fca09423c5685b4639bb038b4c4bee83997a69c21e9803c3c8b39cf859fc9c2af47dd8517d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ffc536e194e4cfaa1cd1d1fbad846f0dcd9c3ed3c01598d9eb747bac7d8015a905fd07ca6199434c75ce4f13965fc9000000000000000000000000000000001188472f0a0c4d95a118d680f8086dcb2ce712b6eae605aea66384f690f74a68d0bc295d595cded6348c226ad3a041a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000315216fc29f6cdc99efe569436813eb4d6c87f6ca03da211db92d116ece0f7a80dc18b353e036c52b204179f54b36e1000000000000000000000000000000000fc21011f2c45332a5c6368a0fa53ca5f8fbc56275fe17567416ffe2ddba2508442203d0b65838a732975a04173d968b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015503871cc7a2816ec3fd76d8023dd4107b4f9e2e29d8549181883c9ba143426a35f33879e2d0ba8c4348abe1fef737f000000000000000000000000000000001540f751e970df1decd8b52283648abf103d94923240b78b0fce876a0a1d1868e61d2a72b67f09c3478e258afb7b48c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b6f046c2849a9c77955582720f780e57ed48c1b3fdf07c35d980dbb1ab457d3a304363dd81911b52433d90eafd710000000000000000000000000000000000d295e43978262168226810b1ad87e8aa797633068b6352716cde81463f80c550b6f6663bb23769faa15072cc4b6dee31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009a2535c1f365c36f4d1bfd0de2fc722f1bdf4b0b37234764cf10391b28e346b3d94e8a54b52b1cf6be2e07a11fc987000000000000000000000000000000000fe3e4ff1fe36fd8d4db31e73159ac147224f544a434a1007e2f76822b4cf2ae3e6c0da66a2f20697518c2cfc84dc80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f0ec7e98e5beb1bc39e6f2cbbcd03924534e55d815f164ec25c0bcf709433c14d367b6aaf658f7ee3a8799583632a3000000000000000000000000000000000a882ae00b1e77e44542540452201e413792d0b3ede3b6d983a8d5c7084dea307fd1f095e4e98f1b6b598567f6f7db871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cca4d54e31926d6ff0a1c1b5f8b8e70898ed901a77e911f65c466ebd1b03e49fb27a503b34c754e31e175aeade61160000000000000000000000000000000000ed720f7031dd9659146d7c9854fefa8569d5d447a70c4941d56aefcd1e477c262dc0d47ee4120d652b35442294ea9da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134989020f041cc6192499089d6ba5a4f5b5621a85631533431dc5ff56a2b51cbf90d8545e1f2b32dbd4b13d7a6a0079000000000000000000000000000000000354bf2e9ff71b817586c69048857e0a3b2da7969cfd4545341dc87106fa33e341c23f93d5b5b44deba1d36b107fad861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035ffbfd73190e458f0bdd1e318fd976ba5fcd4417a90cd6378d252967bacb173b2246d140742ecf6a02bcfb85b2e953000000000000000000000000000000001093a9b1d945f8ae1b90ae397fad6e80994ccdd7b7618e93c651b4beca2c1d6e76bf9153cc783957ffce742dd72f47051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d335dfc7bcbce3b175ae7a1c02bff38917fc0ad4bef773ea8b99fcc3925bf15b6eead654c7849e6b75151b83de901e000000000000000000000000000000000bb724ab3bc1f433e57cbc0881d3cb96bed801f4385b66dd22b4cda1de5e544a0d328ecd64ff11cc3bad82de8b02d63e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c9b25915cb62750b212a172f77e6dfa372bf7db342033dae59e36ff777482e2695c94e640e1081f63bba6daf3c9dee000000000000000000000000000000001587affab814b03af684eca5e7d559423a3b7515085c0fa2b404c2b87884f239eefabef0da6f8aadfb6579394d4bdba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c97e6b8081c0e0921e353b8ee53bc64b5c99a1268b1379c38c47618b5d4499bf44b8ea8a87f439817041c5790b65c000000000000000000000000000000000013572c1726698694d23f0359b8db9a306592a3ef2f80485e1441b7affbfb9c8e7034992fe5bb911d68cd552c25e390d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e46a966b89db8a14e7aa4249acd0da1d7888adc3530b1b6618f477fc98e1cd053c01485b4dc6238e1c573cc026bdc70000000000000000000000000000000004cff853ec6760ee594be1be1a3c2751b8b6ae0fe10c277109dfb2db019088a18a7a927d05b7a5f164b808aa9fb9d7d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8ec641b6322e04124af0effa1a7e291d9d907777a9237184672369fb6554bc5bdc517d40dd447dc594c498f99d75040000000000000000000000000000000008c9bcb5d03a21873066e2459db0c7d209d05b761e788baae5a6aabaffad97c410b6efb9fa51d2dae32ec1ca10bc00531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a98ac2abad8cd8e720332d4e9c6d3687471262baaf2d6ea152b3c1e406a0b5b2204b7a69aecc4934349761846e73b2000000000000000000000000000000000c22c304c66271daac8761383a260140849818d99dc12ca454c01852b80ec96272fdd8b4b251fb76c56a56c5630af8b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9a45f32d9f063f4cec240b142ef27ae2a67e1c621f333848d1ab5c5a09db76bfa2008db9c9f860c3fc1907393d931d0000000000000000000000000000000006d44ae844e7b3d0fae574ad8f2f02920b8a62075b6f95fd147ce34771624f170481466efdf3fee3d17e9fb6c997362b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119dbdb18713f74b168bbab079a88051c2218ce51cfd459e169896cf414d521b146d0e364137a56113b390d1410f9dcc000000000000000000000000000000000f0f7d93357e0b25ce19e07f55c04f6fbef2ce6868cbff9ab299cd501f9561398cc4d2d6b650afbf6beba6104c6aca0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001523c20ccc082ef4bbb749377533fe5780199b9553f8d73400b1db6f8c0004377395568f68553f8b35c2cfbf24ce2b560000000000000000000000000000000011929b67b69dfd2ec08a29f8b55c464ccb3ed4d733cca8f0a4fa529fc2e1901e0eae5995eca0adaa3265d50c1c6036c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117f557fd51fafa95eb1a94222b1824582814f0e7e2d32fce81a75453afa515d13921ccf490a84a6820e3d2a9cdb8ac200000000000000000000000000000000100ec56b1379252134438909d27c2e9f7a5eeae278d55395193b6ecd07008cbef1e5fe5b3a09fcc6f0923d9c3a7ee1ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa122f31d2364372c50429abe448583299811cb4412417210cc7df29edeaeb8a112764c37d2c72a87641c357c08e22000000000000000000000000000000000144f778b78658118bbbfec1669c79ac2a1197cc1670c2940a425480963bd92b6480f24ecf1010bd9ab297d04874638981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000220cd8335080d027b450f0cfa7e18dc37c000c97d78ef3e959959b4a1fb7b542112c8c77d90b3101c91421bd3236cb10000000000000000000000000000000019ee1dcbadfdac26a4a41d9b2b5e31297783885bab7582e53d612206a5d9dfdaceb38dfebd0ec6e29b52c2b49cfa2a321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006854471e372695b228c641f9f55507351ca471fe66d1ff9f4bbe079fb95cfb2e6093a621c078ee149cf9a335469c8230000000000000000000000000000000003168b241317420146ba9489ccb8c819b8f4375511059dc042f2d177461b142c4bd666216ed86b10290fc18f7f9878661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ea95c1d37163cd6cfaf0d5f1deae73f9c912b3d2e123ed35957624d71bbfcdf166f016108d0e0451e812f24448532d0000000000000000000000000000000011dfec476c8f20c0e574b2b1fd159b7ce21287aeef5c7f6995e25c51bd9954d4b9c091a6f826c8a4be92eede2bd165001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169c46fb292c189e65a47b312b76261bf36cac0ca3be5541c7798f23334911ebc88d9fd6277c3f1f2a16d82757519f5e0000000000000000000000000000000012fe623fed785fa8e9de9a45f65e055895f7db2380224b467190aa81f74e4074fc3d7ba8ac91f8fb85d3953767c6c6df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150e9b314d3a0ac3a1be87ba743932f984a09b78e5f9db632cdfec067fe4b0ade871840f8f0297c4c7a1e599581ee21d0000000000000000000000000000000019a1c96cff130fe123d8d1498066b880daaef5ab5fea097d16b5584c66ef3c5c0ec1fb4789c728fa4ec2a596ebcf23db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff3ad2bf12863cfdb696fb44ada6cc5b8a76aaa7efb66b3c39c0aa371e5d45cf3e5ff7305dc70803a8c4bf25def54a1000000000000000000000000000000001640e7d48ea4e0b3e0cc4340f1dfbe1db3a2065ac0617bbff62b941956ef8dc5d4bcb83ba5f8b0b5c1dc258a92c724191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083835d05a95852733263802f6c7beb1beccd9b9fc94ddaef6f6b1a2c670fc96e599663e626d57ab8573eedd38611f320000000000000000000000000000000009c36872ecc565313208797e99e7e5aa5f272b53665bb01b9a82b4d6ffb2ce0be81e1d26aff58437afb54742486eee6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000527f321d4c62001efa64b356c3b2d7b0e28da7844ca9bf9cb96a1d2fbbace50718535f9d18eb66b61b483afeba5898e0000000000000000000000000000000008dee026c050b186a08edf39e79fa108946926550baedbbfc71641f87b8d452dfadc8580b200c1941283afb17792652f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db9a07e76d35265ccc8cd257a7098f8bda290541dd420cc82883f2079b89ed79712e7349889778b6cef5dfd3d13ee9d0000000000000000000000000000000002905cc4e47ac7f7843e581935fa5d5d3d8488fb53eaab120ff93ca98972c56e51b47c792f6cf4e510dffb1dbd7086b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e7f4c53658c0d3534d2c11821fd428803e0f11b0a680c58bc88eee4bace3092ae4b417a794f05eaef8ef0102b031d20000000000000000000000000000000012e78906fe742ec2dfc08f9791f2b674a7ad060bc49d763782f4d1cb0271b8e98c45e0babcde47afc166173b67620a5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000267484a1a4f12be6b6141604df89ae1162337b592565d461f53bc3b2f741e126f172d183fae70001866bc8566979b70000000000000000000000000000000000e9a61d04bee149e09204a63e751f56609235edbfb68f6652b10b7b29344dff1349c285b921386376edac6693bbdafbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097cbbb3c01cbc448425fd69fe78f8593743e3847c876b14b4807e99e3f309ee8bcc23a866cfdb7f9847a95b3a125959000000000000000000000000000000001500cc80dd5cb23a6d15198e824c48e21609b6946c291d5df64a73dccff0488576f7afa5868592176f43b2cb1b10659b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050548709c01b1fe2db24e2ea82cf86b96aa4ca0ec9667177ca02d270801ff2e43ca3d4e975646d615182e647621d33d000000000000000000000000000000000836c31d07fe2cbcd2e1b4fc3e420f30333b47ded8cfb54e0743a79c74b4111f52f97b9d2eebc7a7aba72a6c8f8e4d501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d1f7093308d01b329cc41b58c1076477ba633cdf98e8149daa04aaee9223c35224b9af8012bec80747f55807f1521e000000000000000000000000000000000787045ceaf5e1b4b88baf8a52879e864e8f45334659e759924182536742d065d0996bceb2caeaf21960e84d359923471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152486a4410c3fea665c1144e76b770c87cf71b2bbbac1b620168aeda3d77d62a1b18634a52d0723ba4567b332bca71e0000000000000000000000000000000002aca801c4b02b2e271be6d9ce8a14ea7c0d408e25b4196b48e9110dd6a33b6286248bcab75e8154ccc04c1d129084491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000137a03c96936f51837af098d5056a03edb8ff8a860cd190898df169ee03e9205a0a6fcb0ba148465a233d7c14fb22e600000000000000000000000000000000115dc35f0c7fdae3035612f4575da177729166b2fbcf96ef1180f6a016467d1d084916bc74f5a5d6c20dd0dd79c7b6721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bfce31f7548cce1b28bd18f9ebf9cd4c836a21cbacec66980e246bb5a273acb336953a89f78bd439975443a32a4b310000000000000000000000000000000013a1e301c807025d71a01d7871d1aced1be0bcda89ba469e0c0dae5ac774d18ca810dfd0d7daa670dabd74aa65671a1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a530f0de0e981338a062583916942615f97eec6ac86e5280eb1a805017d0fbfd5e36ee29f24ef32f6da394e8c9eea780000000000000000000000000000000003c1563875945f7d13cb66ca1b97db02bd86c2e4ff0415978e416969441b59bc70431b97b69e7babcf03a19e5dbee1241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b9b8e3e7005114038b0f993feca08b4792f327270db58047488d0623fabac9ace3607ee678212529ac1ad8c30999850000000000000000000000000000000010baa9583f68adea3f36cc2200220f789820266c73eb71c0969bf2bd3f7817ab02e87d6d8dd036de1dad5c40cbf91aa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008338aab668ec52fd250463034ce8be30356b0794e7a774e306303e0a0703be239ed2426010f1b99c674605b6dac42e1000000000000000000000000000000000baf0ee84da8bd17e0ff1a536b85b657374af0c2243e63392ddb4cc24aa399cb42cd089281ddd469b6b3db9869aef2461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d68a480eb0b93dc2698b6446606a05c4baf90e63de0d66932850ec8478759585626dcb4839603e64fef5ba05acb5ae70000000000000000000000000000000005ec3c3ee1ff2c2c4c5d2df8260b46c5b2aeae710a1878e8e8d0014360707158eaf7e31124e8716b1bebe5b862b8fe651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184da928dd10e414f72d6afa28d9375fd364617e1472c8cf118422e89b116e6b11e256af9ff45d750fcc3c132fe6a42a0000000000000000000000000000000002babd65b08448cd63e62b5638285d84eedb936e5d9759aad8bfbb60d5f6bd23f92126d394832172b93a8239a035a9c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001087b609ceddb89606ac4628511e2d98d47ca3f68608091b0f3c1dfa7ce8963301e3c23e20d083ce4436d28cbe3095f2000000000000000000000000000000000b2939b319d698287a40cc7e143c79653cede3fada316e375c47282b59128abe8a1b0b5c14484a8c841dfdac7ffeb56b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187a4168234cc1e9bf9485be5b0e44213a0619895abb513e2c6870ab242aa4297d48e5236ddc10a42fe02aaf304d16570000000000000000000000000000000009bece883d740b42755a84aa6b875284a24e03f9536390126fc5446adfe5e471652571c3a3f44b84283574157c64757f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103bd13a9c1e2f18da2cb53f41e21012ef3e273e90fd59ccbcd1f29e1d8b519754fcb20e327c30717253a980e65d9ed70000000000000000000000000000000004bbdd5a8d82a22e3dcee5b564cecc86a27ffe8bfccd9afeece9a4ebe6a200a4f37388d0474e4b837efa40bfb3b3b2531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f23c45ff324926d487219f736d132dda2e598c93d37ca89fbbf06a45ec39dc55bfefc06462196092e8d9c91d24fbb4000000000000000000000000000000000bd76fe0aafc50ad2f2b3eaefa83b471212393bbe42fa3686280f14aa08d1efd915eac7a91f9df5444032aff9075c6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b00497a6b27d85e36e60ecfb58a0cb3bef3da9f7c9c406fda6a340fcc53521b6a306c7685ac7226b40b3a67d1639f72000000000000000000000000000000000d6d753b57f88e43f18ccf4e170c2208dbad68d427d6524a04f8c437026c60f2e6d7e01d1347d2d5ca956bf2e4d7617e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a4beb361e648dda6728a8bb09cde1a650ba64a9113a6e98f8837111d217b47cc7cefd22ff324fde9a000d0fe7649bd000000000000000000000000000000000252ca803bdfd92b50bfb17dccc81141357f6eaff1db8c012631ba8703a40d159e6fefca388de757f185177d408ee53a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176eb51de414c3f20c44fc47dad4f455dbfd38d390aa0dbef462cf63cccfa5e9fe16658bdfe2f1ef8cefabde40d58e230000000000000000000000000000000002e934a56acea15f810ce5ee1cb43ba509d580b1c1006edfbadb374bc7945e96ae36e3f0a3014e68dc863feddd9ea1f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0e35615506a516c79ea132384f44f7248295e7488b6ebe876c1f0b2c643a6b4391d1d147e24f0402e7a9642d50486a00000000000000000000000000000000077dcc7378977134b9c8edcd541e93534c9f7b5bd365f21c4bb8b23d47aabef0828218d45fa2c9ec5567782422d745ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009849d6ff15bdcb2ecfc60eb6db65a4c4ad25b1ad21cc0654375bf3572a8c63d45328bd1e44b800d8d7e230c6b13eb4a0000000000000000000000000000000006660bc859160aba9c0c252b4298029d409741712b9e6a1ca96babc84c5a19867c584ac8bec76abf85d736b6f56060d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f0ce1722d76f0a15c12911efc53a34c6e3e3f151608d4575c83cd4a59f12f789c6c102d2612798abe03b22bd1605a8000000000000000000000000000000001201f584b81041ad93e44514911b79f7e5c39edff7cfecbedf2804428d89724f25af3fa53c2a254695cbb5002c7dd6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002da020244f7c757cde5c6022c0f93aa236ff3705e8016444c0b7f7d91b69f50a3497bcd9385b96e4aa303856b56f0c10000000000000000000000000000000007d195ce92425858dc533e3e1870cbdbb8ee5018e232bf59f92e04923ea93781de29131bfbf248ff4a9c544d76a6c4cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6ff1abf3295fe0e78e041cb7c63c69b96382fcae33ed797e99e89ad9ed5582a8525a9a2d50dccbfa90453581e2a18400000000000000000000000000000000027c68ad204e49e6d89dd1779c8b3f8b895d184124d64400b3e0c57bf2bf04ba8208f877dad5aa657fd8f957c99e08581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011629ae32ceab2c017ffe9033097946de821058fe6962ffd6a274da550e88d34ba54c2228cf09b57ac2367053f1aa9fa0000000000000000000000000000000006030322a9b78b69f5aa4821654b60a8daf3be4fb4d5464098edcfdc95eb7471a3414859d64e92d4272e33434a670d1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001661127f2685beb77ef99f3102eb26c2cade99a7ffd01bc97613d1de78cd1337a731d340f59a2b20a253caa2f28e1f0e0000000000000000000000000000000016f8ec7a55297fa53175567f6db27629e5a8db628e7de01cca47e01ed90baebdd1cdaa46f6777268cd8b57be8bb813291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d4ff4fe35d883be002d8035b0ecfe4481c540b959993c6e2e97149ffb0ec96e757746b81df7c085d705cdb8a2c076f00000000000000000000000000000000069a65101a04086163329d07762c0418949de15152fedb1151d52b16eecbc11a22723f2fd5b53141257d9dab4f899eb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019754449eeacde1d6495a0f65474abab8e25f576b3a4e25cc097abc3eac4f7f9f2814b5640179748fd97c5784486d63d00000000000000000000000000000000134315169556110ce561b8b9c0a0a4eae44c993bd44cd74899e84b40ef1e83a704242cfa38f5831735756040539bef291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023d0b134be21a459f69083559fa10e8e9a4d68d0013702fd94a3e78a76e96390e1010093319e2eb7f31bfd3a4e408be0000000000000000000000000000000003c6e935f17deb5aac2597ae6c447c3b92631f8684c6d5c92a16ba6ca88ed5dee095b6e314179482395f4f921dd43e721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caf4b086ff11abccfaaa6e74552940d3cee41af90e1d23d5a0e55c0677cad71d787efcc04c77740ff007f0d471c499a0000000000000000000000000000000015139d9764d9ee1a98c0220afba937ed077045abfb4fd404bedc5335089fd2363aa0de0a314ec94b23d3d5749898cc6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b14c325ebea88d29e351bc659edbfe6bfbbc00ea9e32b8e5a6c28d76cfe17e8d26fee00fb63864c5ec8a7eab0a79343000000000000000000000000000000001860303214c6a66823b3746eb2fa70f9849d3c27aeadd498379142c9e6aa77e9791ee96b00463ef5978fd4a4d3fca3ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf5241435628445adbb337f8185704f486792299fbbe151758a5aa3e5f3dd8f0a82afb398fc50411f0fc985b350575000000000000000000000000000000001195a49ac5ad9ad5681374926ad32c47f127fcce8d21e174f49b8e3149c0e8e9e5c47344c91a3f3837d55827ea5ba9531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b6491fe03a73a003b283cf88bd5f752704f60e35708c5036992590c88e44badcce37b9b1cc488de6bc3da91d9d16d0000000000000000000000000000000002668145670c537c8c17e4299b0fd7f36b0d4a618fb2d3d4dd45c89b2f26efb3e41d6f58ae0be33b51a388f4306861d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c688fab75193ac833957d8abb6dda22d83ba4f00fb80bfec5ec45c582c30d59bc430c624a694f4bb58e479ef12e11e000000000000000000000000000000000be0528bf873004b2fcdfb301fb39db430c58d0d3371e1d1466790f3d9611370bad99bddb5c6c883de0468bba7987fab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013afe6fb6699f20d23d877cd680fd371b301b88b8767b982fef24f600adc332b009544bdb81d3363e987aca4e06b2661000000000000000000000000000000000bca69ae19eba82610e098b5163bce9637d4fc2b72151068cb89be885b3afd95ee917ed05be1a395f615116b47f280551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014bd7df1c04680c2c8152a3a14d4046af465fa9bf44a3e207c104ef70038339430cc993ab1450606fb76d8c36acbf610000000000000000000000000000000007058c869c026bb9d9c97f5066f50132abdca048cd5f798df6f4ff6cb557c71d3d81d57e99693eba8a0eb59787a4c95c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061d11040a35d048d5407a5e27ceba815d7ae8fe1508b26c6959df8473201df97d8b2e1b3c06c1de234dc7e3dff3adc20000000000000000000000000000000000bef08a1ca38660d13793e0c99fa6c7756045993baf09ab81d30d44f1cd54ca143b19ed8ef2e7bd02b0ea9797073f9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bf580b76515f440fb8a05f4655305e883823b55cd7ae1e7212def104a1e1cd1aa31c68cf4cf26f22dd87b26780ad550000000000000000000000000000000012aa61bbd1c8350374061e89c03b6a86cf3edfa2ffbb9e610edf9ed3804cb4550cc25f9b41ab455811b4e2f056e4408e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170dbdb25882adbda085b8ea4dd2953885342e3462a7ecd066f8f338fea19bdf6e9ec93814ac5f8b711074096323322f0000000000000000000000000000000011fb5df973cfd74470dcb73183f96c5593050e723126c80fc8803d3b75eb2060a2621798d1f3c8453ae3f188cc9f1e371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112cb5fa3b9fb1fc89ee11ee37f688da176cd023e04e1f7d4737684d00126fbe55f13576170e5eb065c7ffd553fab8c30000000000000000000000000000000019ba1a470e4a46c18d28aaea87a36548a1bd95fcc24e7f4bca587e10205b1d05659dc54357b2261e1d12b964ce56be601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000356344eee82f8fcdab51d102cc8e53b7a427e2a4142e2952d9c2be17f8f681d25b87ab9fa1ae3c7a86d60819223f387000000000000000000000000000000000a95bcfb8d1851a828097fac5e5b824aaca0c5911279e7e8422603f38496b487183bcbe26e6e7e3e1f817fe5e252cfe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166df75509f895f7f3002a6aaf7cb39abd8204eb770092a055f72272e8c862ead75cbbbf4e7b1e91a0b73388d7ac41f500000000000000000000000000000000017d5100b37ed9e3ff69878ba0bfea7e97b466003b0a2878aa4d26daed1dd583942e84dddf8156e3c08b5f4b805f474a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9b160cbfb0b89780d9b80d41933530fc322ec05fcf99d301d55409a23eafed4b781eee5194a86431c3e02f9c1c53f100000000000000000000000000000000130b6a02eff7ecdfe69b311b009e8acdcaa09347c2a5d5a1a55a297caf838397725a7a1d3e54b4b91efb604408cc4d691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001675d89cbf8d80ba0273726e2ec5078f2cc5960a658faae0c0b53e37515c4e36d3fa7524f76731f67cba8ed98efb1450000000000000000000000000000000007591218ad18dc21e32a5e8d60b95ad5a4aebd8225fd37f7290d667a4011f83c13007e7b0248cd9287e54899378857641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003025554c64d04935ee950d0373a7ced5f1b93b47a75464977ace64c49c54fafcd8267a0d0b02057e56979cb048b588b00000000000000000000000000000000023a38c812e4b43a983304859facfcd81bd77bbfa5466bdc08d89802ddf5a333fc2127fd14badf4d634f5b56f9215e211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cbfb23bf71919f8592bf47a561c3bf4a684a043c4de8633c83e09cdd2bd54cc44d9d757459369dc4c4d673531600c200000000000000000000000000000000022277fc57a9f666e1bfd219ff8a35c44225ffdbf061836c2be356a70d81cffa4b15683ad4290a4939cda40ccfa28dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ec8b080de41e822826c0fc7a10d43c785f55cc679eea24ee750b6a99dba5f7679985732e4b5d2cdc74c44ae9f8a5b20000000000000000000000000000000010efcd6dc9c3e3f138bc8fcc3f214840eae0eccf11610a2849422121c3b40afa91e246597acc865ba5ccb2c7108cef661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cb80db85717dfece6f892960a2ce946e23040c1de19d731dc1152441fccad7995ffa85e7f97907d15860927dc3c92600000000000000000000000000000000083f43e28109c6bda83551e99c3c773141d0cdcd52b25be4710058697e223f3b191776551ebfc3bb70474b85395d32301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123e422d66b0a35e525993ce1d0e433537c2f63455bf4adba3dc7ca19c5698a84209c9535cfc4cf12e89b4900b6e955a0000000000000000000000000000000002407e3a00ba556d181c154f3a3bf508ae9e94887178cae0f4f109d0f062ba74b114450b1efcdbea0adf526832b516a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175d88638cdf5d3d108cf673e85984eced797c6ec29d6e91f25ee4cb226db699ef4924835bf0ef6e224c8cdaff10bd010000000000000000000000000000000016a742bfade9b1d5197edf1a92508a6cafb42fc21937c7e14a70df63d4728029b8a2fec421e9c5bb1cf42788e1b1fee61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cb6fc23f64d4a4642e059bc002cd6d5bf5013b0e97aef710bdbc6dedd5844d7ef69707ed5cb45776a245b4fae0dfda000000000000000000000000000000000ea56ab05e8a0e07ec52a8e3ae3111eb66e2a4e783ae7386c722f6a9590fd0f3587374af19dce45080d51f7512a2d44f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a17e93ee388f3446a31ffd62f7dafdb68116fe470e1077f082b564267db94ac58844e46c035ad4684ffbc5dc8b38bf00000000000000000000000000000000158ecec76da484c88a4b2019b53cc1013cf0e8064f38a971a0811e99ed4bc76fdadd2282623988533b783170f9c2c3731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001532dcd042faba6cbdf0d92314e19ea3e7b04eb69060df3e33c8a61bff2e16f1f3443dbfbac75459925e1f7922d31fac0000000000000000000000000000000016a0b073c2550a25a4e8c49939f40acb2df7b1c2810a45989e418a70b9d290fa33eb365b7366dcb26250a987d59453c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5dbc1bbe213176c3182e5b12776276569f92451772b3113461499cc91b28ec2b467b26e3af5d2cc4ed7fa57bf2c19900000000000000000000000000000000011f955e74761379a12f4a5238873a2359bcd29cde3655789af8ee8f994d0322d0b707f6838b693161e94fddb694dd731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d3cc124698a9f9c6affce4fc9926c704b89ba96c7533ef3d1bd65ed6824d39da21e7810fc468f9e975d126075547d1000000000000000000000000000000001069bde8914471c1d289954ec5f3156df7be0913103feac97356442bfe0b5ee6c9ec12bb6815a41ec3245921173961771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001378058b1a1724b510f0393bccca4dd9989b6ecede5c46c6386b7332f8087aa7942ddab6c0c4b9d4e6e5922d63ac48a5000000000000000000000000000000000a2511fb1f905fd37699c69dbff6488b798fa9b15da1d2b28c86593874c3a3cae4cff27236f9748da0268bbb968130c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146b1e6c7de5f518f98d0ffe762310b488c83853f25155d00785d9363132e408778d08228745dbff902bc6158fdddf00000000000000000000000000000000000cf80071d9f7bc01af9ea66a18b22efab74fed5f72ca23dc3ab45fbd13aebd362259e4b8cc9cb314e6208271b299aa771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ded09d54723382d622f1c46b2cbca4f192e471694d002b2888b0e8a7998453512f9d9d5584c43435957babe023eae2000000000000000000000000000000000a39c495e6193c5c81824654d9d24ddf7a138f192a372a9ded8c85a301f0218a5c5030eacfb670f727fced455b4008b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b1a8e823d6cfc4936bf33b7c31f5b55b0baa13b2f74c32c5dd7d10e56e44db11c3ff74a3b702e07930f4aa9ccaac4e0000000000000000000000000000000003cd8c9f55f9cc806bfb7f0ca1fc948755448379be58f105db0b1e00076d93d5b69f88a92423522faea500c0cc3c93f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd048161b967fe4e49a879519de96512a08e827f0a07130b7686cb13a4f897636d7edfc3105359d482406bea7fc5964000000000000000000000000000000000e1e7e1a9cb9df5ea4ed18a03fb97bd5ab2733271534e01d85541c7d2e194cf8fd2826341f022d867cdcd667c865fb151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f6654dc9029f77afffe0ec46bdcbb06fe6806c90077cf5fe49c92bee504b9d0a78fa1249b23c962e3db008a635ba41000000000000000000000000000000000a013a0b600ca6d1c36fed4233b0882c7a6c41357b8fc4502ef6aa130de8e11c4818e47b4108d2e17c52b79f762f78bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196491f1d774a42f6aae2e8d15b66837a5e98aabbfa03ced3e8e763f639aaa64172d9599777e2ff7170b00696371c5ce0000000000000000000000000000000007092f0a6c93d78534f9d6e8c5445d83799ed09836ef70985b9092252c095a58e14250fced8302bf12c4811fdce7c8b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026336d6e3d381ced708743f1db8fb5ee35ba43ecbead926a11f2517e08da9edc6888427516a5f3dd47b2647f096d2fe00000000000000000000000000000000003068696dd7f5e459dba5e5e4075c02b2fa48190ff9d5396ee5d61e48cdcca1decb1600b49c0ae522423bc85a3a63f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e168d302bdf4454eee0ade9ded73d08dec3dcc48af91e04da62d8a125c9ca3433f56da8c9f0e69b4e0a817b0f68f8b20000000000000000000000000000000005c451271aaa1ce53ad1e02a30cd98d9c01082de714d6cddf396fb094f3d244ac89b96742d0b022e473bd44a4f2234a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011293d77d4573c256006a6eb009f1514a4a71111f197345adc9538b11349feb3522b72b321797f38faa86bcfa75b14a00000000000000000000000000000000014fb17949003003721ac0a0473a264896ef3f2f29700e287943f4b2e7cf8650403c96cb792fc4e117c67ed11d22669de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b0eb17e3da101d72ff13c213a4ec6c2d332d551aa60851554ab072d5425b54a722c4d565653583bf1fd3d4be0657af000000000000000000000000000000000fa031122cf8f2f47c09ae0f13d57529c00b11602f5abdfba29763876c7da68af66f399bb0535d50ff43de70bd18ca7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c6a736ecd1e15cafc4a18aa045278b4f1e9d5f13d814ecf5d9a935be7b60cce6535285e41af019b30d02d154d68400000000000000000000000000000000000827e76a1f090a27c8eba82fd2e9989cfff806fd4cdc141d1083692d1933cdf1f0715b6f58257dc3bfe7ba1ced693a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012385eeb308b2ed0fb55a8dabb9113f9112e7f583a9df0143cf9f2c54d68603e9589385fe7e1f87e71fc56b95c82be8c0000000000000000000000000000000003ff8b8d87dbb388005f440ff1dc0f2fe9f558ecb4fbd9507adcdf7046cba89bd9957b26123965837f857a9d24ca7c081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2136386c2da6731f5676282dc12efe43e9f06ba00e990c9ce7f8868a1f74f534ed2a95767cd922fa6b7cc63006a6b7000000000000000000000000000000000230fb3c2f7c30d920e4606483041dca9d5d6d7e958b1748e175acaa4ff11698c95fbe8cdde55b11653e39f8ab80250f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012482cd18ee4291b129ecd222e3670b1f647e255e1ee047e6603f8581f08d291105a4aaee1bf9d6ee3f2a86a9c1b0d7500000000000000000000000000000000076ac013586e0b49b89501244e680472d34c957a9b6426e8e94fe06496a4fed6d6e943003f375ab518154d805b5b6cee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a37f4b6be8bd5536e314fe727608cafd7796fa6e9608a7346e7d9265b02f357ed2542def824f78f68f603b1d00d4240000000000000000000000000000000007e63cae5b6d6cf6faa6fdc54c61a84586184fba9038c29063d298ec44ed03b930b8d16018c74cf253f5955cda7aae8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048e75e3a9e7c0fa8cf19fabad9986f7f9168b782f63a1a68ae2985fb11541943126900cc0dabd92b3becca7e9aadbf200000000000000000000000000000000115e86d8b51f0471e32c442327c2d4853b4864f3e9a7e8c6b8fc4460f276935c1209b334bed29a52dd57b5c8b57d61021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000721519040d82fac82cedc1ec2a601395981bbec0c912200a3ee98f201971854c960ab595f2597ea6ceb39063141c0dd0000000000000000000000000000000010d3ddbe76fa2457ffe6fc29dc4e6947e88b567f40fe65eb2b96a7d5762e2afcbda36cb77a87b4c3ae1c77314d84ebd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086b02ce230d01e47756694b58ca50bc3b820828d236ac9958de2495792ad15ba5df97813a831c8e368e97caa7c4530d000000000000000000000000000000000f4560347c1e60e4cfb04727887642ffe7e0df57286c80a1f181f0d4c2b02eb5759efa7415f396c31d9a4a0128644dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f86f3dbb2dd837b654bdb8fe4262cdd9a008115ee3da9cc8d83b73d6bdf63c058d0c16ee0d3fc8e51d5b168da15f28000000000000000000000000000000000cc2f7b2060ef7e209bd0dfae9230ca23111e56209bd347d7fc9af8072ca023df949421a84998f646da422f0953436091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000862a70ed619e2495b101d2489b511d36c4c9378c4834789e951686e78e2a21fa7e1c2f173172c5d6271ee03eb024110000000000000000000000000000000000b26d1db8d11569c58c050c0b114b056e97f5a794826173cce7a2a72407f6d6b201c67f3602a1ba94c19702ec7646f341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a2f58466336fadb11a413d080bfeca1e596e7a5c37ff724f890c810017343da132798ae2af73ef664a8c11c49aee92000000000000000000000000000000000b3d92cde2a7acc50a207b88c18e41d2a40d6486fc51da825ff57af2af628a80ba3e7eb6919e3009aff61f710e58c8821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134eaeb0a3a8df81b98c2376a9050138b0814f9c93a9801a516bab050fe0cc2e556cab4b404fc877848ba0dbb17f8b4e0000000000000000000000000000000012cc987b68c23eac2fc83d041ff8017b1b95370653252fb3d1b65ee7a0bec3b566756fc3cd792a7886c9bfd9f8b6de251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147f37edf3a2ffa922540a15274d2c380c7b211e9cd51211088fb3933810eb87b690fd44dddeb0d3921e8fdeeba2a2c900000000000000000000000000000000028b84c811691f54b1b649e2d1dd699098f9af455e1a1fccbd82e372189789524320f1853e13cb17d0ddc1551d3e71e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca72fb85d44d7740c1c0faebb2d74d9fc8e7164f1e53785702288e5824fd737750d85c7d9337ff7dd35f8451cddaf650000000000000000000000000000000008a7099ca90a27268bac9dcc887cbc63d6f11b9d423b2ce6b62cdd17462acfbe5c42fa0d4f04c8fa64c1c5a13ad6cd091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088100c1de0d9babcf472bdd6fbc379b1e999ca6fc5186fe122dd6523a8610819f81aeb2c3df3dc58f83982f4ba0f4e70000000000000000000000000000000009da08b462a86f22c5484b83ba67a2c0ee1844814d1337fc4c0a614debffe1c5fc4ece775e558075266675bbf1e991511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e87ee0fe488e4bda38ea601a2232a195c1aa1f56c5d59c8c7b720ccf87fc4fa39f7acdf6b1069b50401b9f3a260296c000000000000000000000000000000000e7802e1f70aafcd367fc240f99927571030e05f98484d3c74f039a71b1b8e934edb1de9ae48717fb455c93099c6a0fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026fc7c314fd0c23f5c602d1e1a3ab7e0178c51138ef38be09d420ee60e063b1ab5e184a5e501815674b353a0c2e8733000000000000000000000000000000000e6aaf1a7c59ac9c6a144fd9edd2fedf782551f3b3e747b821b0cfbb2bd805d83b90ce5d7474fc8d416d81ed9060796a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001442bec21467b6c437bb5108d77ff3584d66c075a762ca69ff818f88f6f8e257caac99baef71fa958d4efd64cc0b4d810000000000000000000000000000000013bffaa69639c9ba77656a9a425d9a9d11b98fa5fffab4f4aeffc75c0bd68bfe8897ffca397409978b7f7da2fb5872041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d3af812f430b93f6e89f4780c31b4a99b0a463ac1a8328f452b722f20e13be81011755f977d20f7d4394167ef1159a00000000000000000000000000000000197e1c6f4fd6537f0d9dcd8ead3cf2b2dd7f5425b63afb0dbc4cd93d15da5cd2872ed418d515c8391d7b5b797c2f706e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026f51847bf0e79f98cbb53fdf3ffc76e1e96b63f1aefe7469144f1559ed0b859bad4caedd71e51d23434712145002bd0000000000000000000000000000000012ef18e777edb9219952ef871d150ef1b856373a94ece8c54e717d28695326adbafe159f9109051357d72f833613cc901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000406076c4046d54e0a146ddaa49e86c29f81254bdc7cdf4581326be86d5477adfbb2b92236a80a1e4501e2c1c4f13fd7000000000000000000000000000000000183e9df29a652fe095cbb8a97546266c0bea118ef3e9455fc72464c066d55f70aa53c3eb4ed0355ce417d404f5cdec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeb61235c5b0bea0440ef96cc83f29f1e3d6d86f3cada4ce25abab5d177463cfddf5e906ec5d86cc38df57299c8559400000000000000000000000000000000185de092b387f1f1123396c0dcdafcbde7649dfb644f0288d951b55c1cf6f71b0a6476dd6808a7a69cc9d9f768fe68ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118cc245bd1c84053aff9e79c1232221cfb7936458c307c82b7000f7885c268ccd5db94474488152d50e0531e7c4b301000000000000000000000000000000000d93fb909a0d7100ffb4d9035772ed6159cb3c974a77ed02ec2af89b4360ae849cfb7c6cc2d79353dec0e2a084f44a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001579cf597c2054362c5f3a4ff3e7016a1c161c65d04b0b94714e13486b7e33618c4956f355782b266e0d111f04d71cfd000000000000000000000000000000000ce7c37b7b7a216dcccad16a2697f2188e15a2c9d1b028fa5caa121834daec6b7b70dc8b57a719d8b3205b43f49354731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041b53b795c1fe7da922e5095e5c76f21f95afabc06ad7e259cf6a5d18e35e1b45d33fdea2429edf7f4f68dbba1087880000000000000000000000000000000000a21b8114c58988bb79516392bc32da970c94cdc0cfe4e2a4cd7d275f63ff0f548ab1b5b3d1e1418da69f23fab871d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099ff7fb67387860fd9e99daa4906c5424099530f78b4aa7022643b338c8b375b574f5a96db3598f32d560dc94afb181000000000000000000000000000000000d04a2ea930b54b8df5447a6f069f8dec98bf05a5ac80395453b951fd82124bf9201d7ab705a850a2c7533fcccb5a52b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afdf98f08ab187c95699eadfabfa355c627ae96a84816834ae72ad22d0b7df03c3ef11586ea8e65f37cdb7c694b8d3f00000000000000000000000000000000079ec8bc973c18b73365a675f18a5b231cf072340984d008e23f762caf91f2492f4c579d8a809f07359e5b221b9c24301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e28896db18eef129bbc7a3377b6bd0042699c2465a10af2c21c9b87834a13454c10a5b5d3d05f19d78eabe2b1f20f1600000000000000000000000000000000157577cd0718dad72affb164d77dfa6be75605415fd8eca516a6dbe9bec71e5ec29e67a822aedb27f80b4aec13c102391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd0761222611a4347d456c407a14820111f325c2a3bd7fd8b169917977c1abcdd6b05436b3592b53c2066d156dc29ee0000000000000000000000000000000005cd038a534cc6d5ebc484bf8345431dcf6208c225fac852b2e57f9f535880fff78bf946e16a5dea7ea9805ada0ef6101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4ff468d06274778eef35bcebbb209e487efcc91e39fad64e2a73376b6a5eeab73d05ba2a1cfd53e30dab93b9a0942c00000000000000000000000000000000032b70cd9d2a72b79ed23213a3b6636949ff9a715cf234adc5f43fb7c16586b472a869db68827926752c931a17e85bcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046b158395e8167943347e13dfa67c3b469d1607e37e2b761faa4b8134e13d26f574c996fc2689e795e8203ef6192633000000000000000000000000000000000f9c57070af6e0bc38726e8ecf940ca232703b68c584dd2436fcda0a33e1d8f9b1b0ab0c8abe6e3591a3fa95ff8489021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa64e13e0f68575ca656dde9ec9437b036b7c0699d6bb18ac799d2aaec8918be741d979f98aaf8f80a81242beb4dd9c00000000000000000000000000000000051d8a24c7eff9fa07b093e5a081ad4af9f6b3cd85e3d26d64bf63e6f75b6269846c683c7d48ed93e7b474bc84d29df91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000192011d5687efcded8884908b0ac6b74b9aafe343ded3e40f4528febf8a3e3a0d648dee6e9af88ebc166db9f136a11c00000000000000000000000000000000116198fd19a29a732f7e7c3839110f77728e1ea62b684ff08e9da771586d43cfe4ae2a0684720def1f17a4ab63d75ad11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ae24b92623d0d8690e889f21014fb4292dd80e8cc69c725653c97a5f77e3e4d99c996ddc4e96bf2f8bd5d7fe5528e000000000000000000000000000000000ef14d2cd881bc59c6907c7c28a7fe467e8b8af15b8e6dc25d9d204e399edfd7a74ae94c9b107db9e5498d583d0a02a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b033cfc76447cd2f03c73e328cdf3d9e938aab4cb4f0a0235286a143947192c860317f40d1cc9125d23cffa06a5e7300000000000000000000000000000000149fe74424ebd76ea9c2707b011c955abdabd2b7209f17a29d766e90a566384468dad2fb799e22588500c3e9fd62d8361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016142f4a416993a61d5487b5a4f176d6961d616e6b0c9c927e9e95112b8f005f7e792b804f09034cd08dab7bc2335dd500000000000000000000000000000000100ff54db712de35c5480cd8959db494313a5047a61c38facb63325c37c4d76010e3ed8659665094b99ca928bc2ebbea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198526ac6830bd04258f1ed50b30c3f2dd1dc4cf1de23ca36a4847e603e48ca16480eb4c54b0610ca23f392ac3027424000000000000000000000000000000000d564f52835f8c8a996389fd94a38e9400377b1af8869b0a9a79f05525f398410621f8e7624f0d8d97e5474a7833c7e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001221a62c653abf1608545c83dca12c701994b93fe7339d33a5b63b70f228b543c6a04da4518a251a77b7803c75b6761f000000000000000000000000000000000d88b9ca9cf7ca600b7aaefca23ae8138412db207343e83f6630cd1e5a58a13391a38436e8137fb0a3bd3035d16af16a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067eca475e997c320c14eaea437d331975d622b8874e5ed3f3398a361860ad071aa3cf1b6d5ce9284ba0b3ec99df16150000000000000000000000000000000001b25057218907f7d5121a70cff5e218e1b0f31d473fc4b2895fd1533b9a6ce32d27d6201227000d8ff682cc5b388e331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000302f831861ba0523836c7c38516afe94ed8e282ded74db20b62269bf875ecd7b0e7a5c1fbcaa142c632985dbfaa8ed60000000000000000000000000000000007f3b4001d2beabf82894ff03105a2246e19611a208ccde36760bc7f6952d6165f9f350e982696c08eb93141545bcd071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccf05262fbac12e459384c3cf1119b8c8cb87c9ff310f609972f17e9885c74824a010d5c32059b662faa049e7fb8e590000000000000000000000000000000002043adcfa8af733cad7e56a7db5dbdf28774426d135f67460f83bb801355e0ad5bac3bdd76d12786a37f9de896b84101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140de0f8e8bea89821003f5543c164611fec949a620f0debc533fefdd20fa8a3a288fddb01076011c500bde22a1e10d20000000000000000000000000000000002343a8d00d0ebcf1536ec7f5ab42aeedbe8ea4bc6045e5da7396674bd90acdd81bebde4044552334cdd7952854af19e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cad9de3c4c006cd9487dcad2c9fb3c2b1f72c8a662af444aafbd905208fbc8a092dc11e1cf45bc269238a2b8e4df3700000000000000000000000000000000027902f309de9626424bb328c376d6c8c00b5336deff3d9b22baa3e4b1794a5099d3587e3e1db5c2d2046b0c257ade551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077a58bc41bae6c9267c0b4b464824c19892689a657cac1dc4c6705bb2fa2f025231e82b337612a4d97c069e2975db19000000000000000000000000000000000f72b8af3528582c2ef07b158ef2192f0c2c6d1850c6cdf848537b87acdfe7cfbfeb8530119d26762fc8c30d1d5592701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077ea9cc66cf5a2336478c321251abc32a16644527a101e584cab8512442d280fe107832878c5a9691bc31dda59211390000000000000000000000000000000002ff2bc4c6a3682a1aed7ad5dd5974728837fc49ef13dae3b0153f23fb3ec5b386627c455b3d7d440c8f0559023098431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba68b6e85bb5d59d2d9e5969f86fd3b2ee974b38c644efb63feed9e4fff7c99ca7d0349fd85b0570dd2debce89cc831000000000000000000000000000000000b12cbbf373b3403668f2fe259d4dbafd8164fe7b8c840151e3e02976bc03524913f89e62b873a3b9dbff387623578801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001133bf2779e6131aa0f4584c8afac7e091d3ee30473ac174e31b2d3dceb21acaa66817b53b3ad073bac57a1ccd12d2ff000000000000000000000000000000001422994f22d9e35d732ec4292bec2f088211687d7f2b75377b1dcd9486fff6ff59993216424fb66c462f09d84cc943e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006aedc27632ae723ad76d439527a5b1c00533f303f607dabdbe92d4f51e8f78393b82f71d7f1b6b8e7fc8e9bd9ee256000000000000000000000000000000000895f619e5a9663b10698aff460fc820e3e1b2951ca5adce707f762085bb874f6ac4b2c93c6e372281fa366968daf2681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d07038a24b8a30620254d30b2fe33b78e2e630b84c60209ee626cab5d3f5fe633448380e599cc973a2863c5b0ec1d700000000000000000000000000000000140b50a2324e0fbfe35bb30cc56a59aa5c7a6ad8d7abfa95c7e190adb462bd561ffcf24ff4fabb1a29c229cd550628421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000563e01f19ac216aba65a3c08b48375d677383df3a523c8c4eefa9003e90a878014c6b21695bc654e153cd39eb0b98460000000000000000000000000000000005240b2f7ba245679e9747ac4785961b0563f25fc30170d466a17a869736f6e27751abe58b4ea25a40809199e921be581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126ff2c36696633c84576158b367a813087887793b17d2402a73dc270a52d4c157293ccc2f1ae05f3229547491573c900000000000000000000000000000000016de49862a53a78ac4ccfc58b805860d6aa5f64938267330a61b47149011020f73e7b47a8711aa03900e1fdd3857c5591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110c34c1d59c26fa98e23fa5623a5c11c599e10b28933b240368ec37122a286ba2aa6d06941bf5be48e9593f2e10de6b0000000000000000000000000000000017f8dbffa28376eaa130ec1292ddae4e1bc5a89912b85e81760080e73a915ba05908df61c83cd9ea7290a058933853ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caeeb19a559a61cf10693f536a0c7910a1b0d17a9a1af27dee0e9781c9fb3b9d9f060c34b277e2bdb245a019d97de650000000000000000000000000000000008d3258a6bd9e305fb5b0c7b122e73d42cca9f408938782c62f4f9bf985ca498d719f14720050062157317d416b4f5011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000242a215a778e8634c5de9869ba376a45a3102144a931106395eacdf6dedf176668faf8fa3f1c9bbf3da91f2026d4df0000000000000000000000000000000000be0e93b43b5cfd1131eeaa429284fff00071f216aaeecccb09eee8e16b0d1c8369f11b29a0e852a2edfa1d12f462f7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011477ee937f1038f11629ad107692793bd57987949c437c0d22c60fa9f6a702a7205f4cd7112d01c22a6c4c35a3cbf8f0000000000000000000000000000000002b615d83f669b47fb930904b95889a16ce7556a85740e9b17cbddac3782b40c861de8403e24b8835bcfc3ce66a9439d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e251580a4ad87fcb221ae10ca50acfcf0ae0b04e61bc89c599b256ce226ba58a9dee7d870f1127fad0eb06433dfa110000000000000000000000000000000016ad82672935ea4357c28e8e68a04c94dddeb2a87bae29115beaf5463db32aacc3313fff13041a3735611ef9a806fd661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001990cf8b986b039aaed5b3148b5e64e2d2a7878a829dd3f47a42ab0dfc7d5f2f73af754493fd70bc8b2f06dfa93de5ed0000000000000000000000000000000010e4ece74a0211dcd65cbcccaf7ecc5bfed268cfd9913ecd46d4c36fe70d28b8630b90ad7cd1007a8a6e2ddabf349c331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a4b0486177ae05b3c3434c2a6f418788a9985e71a0f0bc1f2364b3958874aa535b178dbc321e5b8c8accf7fe485c170000000000000000000000000000000019055decb137c1dfaf7a80dbd99a36f7558643a55f0796fb374d484e842d1c53d315c1d4048009c2e3a2ff61a5a507aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5bfd0833ea70b619d3a7802d22c48d69152b8f87ee456ec7034a80c62d57a7adf24289e0c4f2b2ca53721010ac89ec0000000000000000000000000000000008209ab9f56c17737110f8bd25dc0d6048d8dc98b053c07a8819d09df3a1979ea333e96328c05535b15ff003438aa60a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009aefe07618e05395d7ef6f84f0dff137ed97c6045b3418032f7cefe643b1d8190ddd00c515b0be39955e810bc3f9fbe000000000000000000000000000000000f1a67966b1f94853569c13e061fade6f2ec0768c89d8947c377102e8afe186a6dd9297cb05716e6fc2010d35c49e22a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de26424f245824b162cdf016bf5a7a2fb39b11b120145e61d9e36c37f425cca3806ce67ae0f502609266a1a1abb5da4000000000000000000000000000000000e4b2f7c92e791e5c1458e0d28cca80c389592ddd4e2b1652a4f8d9808441e969f4bdb0a17510d658abab9c2ef0126a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdd1c0a0ae9b58ad4461395a643b5ffd5e8f17221dfe11aeeb3ea447e7f8c15d699271f12c8255c61ba39e2adc22d9f000000000000000000000000000000000b426f2bf81287c64af3032a93ac6d66b5835aa50d9a58340adea4d05189d2d3e7fe3b4849b311a4bad36af9d0b8b7df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f250f17235c0f8ce8a3aa846d7b4a21a2a12afcc0e864df154a8a4deab299cc82fecb3c0cd0aa4a907741e5892c1840000000000000000000000000000000009fb45d5dd81e18e4d79c089b406856cdb956163916a0ce206bf02a4f7e59fa765f1a0496ee1e8816fd3d6e83708617c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094dec66fd6c404091599d8c5707e285abfb74f8cf7deb4813f04e6103b49603bbb3ea33ebfb607c1b41361e5a9b40660000000000000000000000000000000002c43d7dd2744e3503799781f00d5276c43a8dcb5e0d13c8d26aafb0ca8742b1228f07b0587648d36982df61700a75481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cced53c4c1bcf32b7b1b4d6b393f88eabf6030123dacab45589d1c5ce05a0f4748b03c7ca4f9b69bd8a209037227406000000000000000000000000000000000cd6d52e37d01a8cae2a554159e48f195a66704d2e3a074283a82389d729f8975aa152fac8254ed1bafd222e18ce810a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a249aa25d58f85df35b24e3748e0782067de47b9486dd9e9fed035e9f5cbfed8cf855ff1d92d2fea7697af9bf7e980000000000000000000000000000000001212542c7d3a5f2701087dbee68eeb70eba74aee461a8d50eeabc3acd75b00e57021780babcc7733930d7319d431a7141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001452e5ae053f59b7d7469eb6bcc02bec43495a6108c9d82e9eb8e3f753300a9de73505022ee042f54740c848e4b791fa0000000000000000000000000000000019aad1914e4a083b3175493cc71e3d2a217a2a53c9a0651577b7206a5ec337135ed606e12e74a7a77e8489e50bbbe1291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fb0dab493e4a49a35de125f487e15fc682cd65ef1d828e053959a3b9c4593db52d0eeae7623d993c7200cc4ec11bab0000000000000000000000000000000002d37a38d18740adcf20d900b967abd2a351ae0071694f42134ad0a02f4beabedc0beca28a82ed5fb2d68a1c7456f68d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0e798d1da2bb8a0ac6195cb38b64216b08de09d862261466a8237a1baa9dc43473bfe88d2a4fa29b3bf86ef9b2f0c5000000000000000000000000000000000fc213b0bc63334eb19dbfa75cfb931a1d45e264c4ec1ac8788b6d10d84203eb767d9257542517362e70af2df7870ea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5031cc04d61f37230de8b3891b235fd1d99699e605cef5b2b3cd0ddfa37e73ea6c46bac98172dabb1eb0f3a29cc4dd0000000000000000000000000000000011cb1096b4f7e8aae4719071e251d416d75beb400c3d38d65814c501b2190bdcfb278a58bd7648f0878bc628da0ae01a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f8e3d5c0647040c97680f1ff18d498914738bcd1f19c6d2bd1a145a39a46212929a37b59b50200b4a778ab30a7a1df00000000000000000000000000000000125151b058639b0e843671e2f03aa164887a7953963cc345827269519eb75fb97751092039ed4eed02fb0b009283ed441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7bfd0d277d96603a189e91e5aeb54c5e27b1011617810038fc70c3f4fa4433712785f9fdb159ae52560f4e9782fd6a000000000000000000000000000000000097671df6ba0bd058e25258049b8e7ae654cf0d6880adea55f7271cd05619febc3338508056259c3548d680611eba7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b8c137d7b1989addcdae3c61ec4e2b03eecb72449018df3654c182271c4b87d643fcefe224cbf3822313bd4478da3500000000000000000000000000000000170a8203907101521500161e30432b12e6c606f168706bf348b068564926b3cee82de01ef6c8279cd17e6335d44625bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131423b93ff65fc78c6eb057bb4b82c0c6c76bc8effab1eb8ccc685600e98eddd691301ac040dfb4685938bee3607d42000000000000000000000000000000000ae9a39de24083333b8eb4ee5c915d26d47747e19438c88a6f46e9c0578b54bf6b46c389fcd8b8489789d46c8dd862d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d38f07a8859d00a18780484bc61fb7e69d1300a8a6dd43cbe6812ab2eb358624d675768615798e44f63b925e9586ca0000000000000000000000000000000009937dbd99108644ded74e25453ce7dc61681d5951f71cce3b0f30a1396be3bc711ce74f597c42b43a31c441852318611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f3f5373af9130984eb844c41982868ffab4e78451c914debe415f85e54853dc3b9e007b4bc070393b72b6ad31f893b0000000000000000000000000000000018c9bf39ab48634ef64f524c0890998355393b8ef3e47835d1183f22d8ab1c21f082961ff64513a31d8b030c86aab8cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171a3c23e36c24c840f12e0ee556eebce10fc8bff3544de7573daf980f2150761dd859f0fc7f5b4c28580533a5dbd2f200000000000000000000000000000000036ee10e8606b22681eca0ae22e82c8658d1b74fd9e67d015ce51e3c1a5431b12043049197bd1bcdfd67fbd616f8d9251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015b60d487564e0c5d891ab55dfa66b97d89cfb6a82b042752fd2f3febed1f3f05f126a2acce31b479bd4792ce849b7a00000000000000000000000000000000079a3c8264dc09a4e0c079dedebd6ea74be6f583c4c709a6723f80006b9034b9d1ab33288f42d75ffd032bced45279c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a685de9d665ddcdee62c1e46d2c23eb14af57c0456b0f2e1f87036336e02e4b1586d9fbfa1d220694a9fce9b1f2589d0000000000000000000000000000000016efb020d23d4af065b1faa35cff126fd559673558c3521464d11444d36d53b51b4d2d57200dc3edac61850c93c934a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004945befbb3cdf1a402c35e52a4f98af64374b16955c89874de5c94de6172c80d1b5ef45f452f5695ba69f2b6c98fa4700000000000000000000000000000000198708aa1e6ea62e206936266887630689901fae676d20ab9710301474b6d9ab7300cef1b2fa7c29fd5ac7edc183d7b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3afb4e51ff5b7490de6443043a5fd09602744582b7e09b8df37bae921036832311c813e61b5f251d8c2b2a75279a97000000000000000000000000000000001967679d4deb5b5eba52707d29db1f7b7497fff4a6b8a466f5032530847b3961d92b66659e2f00af76ac4d8c0f47d9411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197c6b6ad61911fad0c2176f4831fdd904479fccf095c87fd3a4f03284a358fc7cbaa990e1c7cc4f5c7b97708ea0dd6800000000000000000000000000000000181ff59a9d5eaa24551dbb8aa41650148b898b790118cdcaaafbc9a6601eccb4d073b0103b30a1ad7e86a71aa5a8f9841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150da3842fb9828f472e7e6e8d8dae087dc6675fdaf5cab1d18b3599fdfd1b1aa3738e99cbe532178ed4f35bd3302bcc0000000000000000000000000000000009361016c5b9298429686f05f0e6ac31422c85d0a0e9df3e8f978bd211a2a448ddc272118c859da42e9005e46b7c6b7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000774244d0644a14f92fbb056cd22c2b3eabf8f68b464d71eb07c6bfb77d455240c3278f647d7b1bb5ba3bec64ee96b6e0000000000000000000000000000000000febf6fde372aede0d8770246bf1ec6c19e8497c8cbc7efc778bf068bc008426e560fc405c35b7e5c50421bd3ba86241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109a51d9e8ccc37d4b9f4d13398705e21a5758a8cd35c52030ebccbb9bc9e9f39d2b923c39e5b812493e4a7ddb62f15b0000000000000000000000000000000005083b394ea0b910be8d4b6cead97d3db3e5d7bdf0c6c85316db9199e5ec7ea11f9c8c0547863fc2e99df74f7d36fc911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001607dbab442113facb723e44541206374b6481ae149e0bc02ec8c7d8a63b78a985bac16f8a8160571a17d5b6265e197f0000000000000000000000000000000016526ce3598223f4dd5700496cbf1a40a9bb9c4e57919ee550b704bc075b5898249f2b4bc4db916fa259980d3416b7911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133dfc469ddd7b2bd54313e716990aaa96452228fc5059e4b31793a5031d664fa83b4535497b1d9c5d2ec5e8267aadd80000000000000000000000000000000014a3978a8f93c805833223798353f84f6be8fe2eecae8efd765aba76ce0b425a1a923fb9ea6be3e9d7539645f415b5e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c82768c6bfab385d9b159e5700c82afd6c3f9c278223cb05fa5f560dde74e6469b2191828f2ee28d0c494f67e58f770000000000000000000000000000000016b6c3bf3d54f70748fb2ca87403e28dc1ef8f8e1a307c93cde10147b64fd48cf38305aca587e48b4738e76593cf11d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ea26a395949cf53468899d9ce5e9f8f25ee897b153418f221c3b7d0c0cc6e7c5badf322eb5782fde997b867084511b0000000000000000000000000000000015ffd14c42b08749579c3023e01e57c66ec60e973f8393a8fe1cc0fe521786c536a229d735f7af4b628a21f40f9a54331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0e02f5a5c565c87bb4bb97f69ba851865c255a28621e3c1d8d39c91a5c78544d7dbbf9cc12e49cf99496c928c5f57b000000000000000000000000000000000a52c5d0ed4be22a71a8a1b46b7657d552d3bbb1961fb53b63df75f6a57a540a7480627acb036ec151bc8448805cee0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003274aa4c02bc485433000c2dfce9d2f1ab44f86bac34d83783173dd120e4c13875786cfb4920074b8ecdcd2c61951270000000000000000000000000000000011e9c9884851a9fe4f4657f68fd7b09f365090cf5e4d43feb98b95ef4a130fc226c373d32b8c89d60aa90de019f2be1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a2899996b6bdc626a62bbcfc5d2bc3f0d95b7fb8d4438ed75536bc3dfcb393877bd2c6b9fbc0d9f2b80d862ef475ca0000000000000000000000000000000008b73eee57266cc61259ce83f53dab0a2b7d4e32518ba022a9337f248eb3f81dc2a0df069b8856c9fe1bcc0c7f8711281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002edbddcc30581691c513db0786ec43efe1fe7bc477e94a38cfbec6e38b5b5eb127eff6f4a1321491ca1b038e95e58b300000000000000000000000000000000082a9ae9c695869ba96858055172ee5a4a96a7a0c87752da598be88ff563441a2817719900f1b55cf50e2f45a1886fe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c4333a1d3851ee7172165b101ee9527e4835b127cc372b0e1c9bc428bfe631cff04b19aca7371cf9d34a4600804dac0000000000000000000000000000000015618e3c00134ab36feb79a09b4ebf369a3ac662c4a5affe95b34ba3f037b2d2f71d9bcb0c99878c33304ae670e702f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114253ca63a94decd5d8b5d548dd17f2212f46b670f37555789fbc8ca996f541e84ccf3867c651e538800b66f4ab22b4000000000000000000000000000000000143139321cc48d95aa54d419873406e776dac6e72abf439e1bd022d04d06ce6845f350ff792e87e78a552ba0b2595b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180014cabdee922106b29d197f87102ccb508fd58e3f1dc4e0ae3ab0d7871f26a81cc33fef3a0d9c80192941a37204ed0000000000000000000000000000000010dc3f6debc11ce1d4e00cda5a2b0fe7ee99ce0d42496ffb6a39c468c5ce99ae45788490a66d0d2bf5d30d1905432d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6a1c7c280b998e03cdbdc5bcdb45845e3ac4e902e3e0d36dfc144f6a43807809848cfe2f2a4442f44f98749ba0173300000000000000000000000000000000041ca7a24242c2523816457f0fc422fd61b050b66242bdeedabb065655cd4f96ef0444da0f5569ce0930b2d8777888b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b29559be9c39450a939adac805032cef8ba1f96cbaf2471ce2d4cee4e12ea908591cb04b8a5c556cb13b49fb0a03610000000000000000000000000000000001552e0d859c5ff13a2b2ea5638ddc6852d459b7235adba1d9ece5337563db1ef770fa9f1cf934de7b25b9f6ba5bc2a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195aa4e6d9d38437f8aa7c0ab3a0b4223daa17bfdd4c10cffd3e3456ce0edf76fa0609d29ff212d13aa52512f7308e78000000000000000000000000000000000d1d5cb791811d9f55ae09e7e5fd6bd861b0cd27c96adf82d1017dc1551b4955c7e7b3265a8d381e99b231051a82fc2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a1570f4140505804d5e0296512bf1f5e0dcc905d3319a687d4271687cc811241cb3bf1ffa4922c3fc206b826bc94780000000000000000000000000000000008b6b4598a843a47ce3f2a35ca41399140159c2d5fc9b957eb8867cdb810844cdf3c0d4946a95ec027497b0325793df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167600db1a9daa481cedbe0fcf1072f6278d3a3ae3c440bf4da08982c1b254fc735c3b219c9c98605e1992f32f76079b00000000000000000000000000000000181a0400f3cf861cba151595b98a637d6530f73c7bdb0078ae010e8b8b6970edb2d5b578fccafa0130a308e5aaddf60f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddb2876bbbeb37e50c4d70c296845d2501c13636fa0ba4f6ecddb6629865824b17f5fbd32366ca1032c23cb6f5598ab0000000000000000000000000000000007cff62339543fe6a550ee20e0603c266e09a30834d31165e2b7d9e63be328e7dafbfd74838d961d6a2c73f074884f0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112381896388f90d65520fdc925c7893980f0f05f93334d312486234e0c4e7b8106cfb4f42b80b49ce11e9214bb0833f0000000000000000000000000000000002d53bb9e60e1ef98e353205f61a2e42a3503358c8d92242392a28ba6be2b18560e142734348dca32fd693033224b21a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001539505d4cc65aff5b9bb9bfbfbe3b9da5abdd007aa24515d9326e6b754fbb60480f1b362f90ca44fcbba01377d1c5f4000000000000000000000000000000000b3f19a0283a444885a2247213f341c6fef72c80fed62267b812cdacbbf90bcd82af8f4eb1875d9669cef6ea0f3a0f0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006388d0d25d15b28dd926d9f3c3a9fdf56940489aac2c0a0d54f03c2e2699ef4a9d5ead9f71e5cb8c550c5443a3da8b0000000000000000000000000000000016bc859ce8d49a91aa2a703bb2d7be212912cac8b1e48b8910686c1cb92bf7c4ae8300864c011f184b95041a64dab8e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e78916b232617ba4043d3ab46a12ff26442d529aedd991257571b5afd27a13497e801bfecfec7e8ea87abc67515ebb20000000000000000000000000000000008ff2f32d68630778bddf9be2b3d0656e2a5d2d9216f37459c69270eeb33a5cf6237e7187aded023deaaba577f7a9c3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142bda0f29d6c1c59c613914b18c455d4032c10063e11aa5b34eb29840f506fecf36f3c967e1c974ec354f2ce530c8c900000000000000000000000000000000101c60718bb92eab7825f6582fd13c8f18d6036de3e00e5ae84ffe9fad68c3934a0746923eb4fdfc797889c40ce2dd7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021ee757ed311336856ba53ac652a67bcbc692fa7648f86ba7a9ad58d61ed24615782db8759daeda40d5c6c68aa397a000000000000000000000000000000000118c983952339eb74c4c84d111d118bdc9febe779b83209a0fc18463ef52560b4405742717295c4bd22b61a5917dc6731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2a41d496de0909db486ae7ca58bfc00a21c2bc9feceac02af82dd6456ee23f13209359e4951eb48f7e7e6730a4467b0000000000000000000000000000000005ba9d86b1d877256cfa13a9e4b4bfbe97d68dbe2dbdc6b4ee94c3eea5c94c648581ba85a1b98062b4d2247546ad6f3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc177c333583e0b5e0cb32bb9bbf8a4c1429cdf36fd9289ab267f56a67f911f028966ddf48e18ec38b0b167fd5987990000000000000000000000000000000002f074558961335e8ee08cf740df85560b8effa31f3feb0a323714fbdabc41a46873100f2b089305779b20143244150c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9fd245055c428d23ca6ff3431508ab12b97f04aadec9a2abd52227d0dfe24d06094f440d94001deba94c77f5f74f00000000000000000000000000000000003ae73396d6a8e4b44dc563d09e02e22aeda4c6b94376597ab077a0fce443ad07887300adb331ed08f6977c4c6b4bb731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d473f29191cdbdf0ca0ee6ce8ae97ebb1e6fe037f7dbd72b4e25254eb356ee5a5a0fca6ad46c3baf79d860b7df3cf10000000000000000000000000000000009b175841a596dab5f7c7ccc502c2725dc1026776125bb25e781464a0f56aeb68211c2b1e08284085a500be2fe4fce6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001534d435f1e1355fe59ad34b4a49c134a73f72239211d0bcd2e99f73875470e994e4d27384dda9a9386b0b0411580ed30000000000000000000000000000000003b9d7ea495baf120907b57b62a2ddf555f1eac696a8b7117e6fd995e1b4428986028c6777d3cdf66c888c1ad22d0fa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012ccf42c61f487c5846577553a8f859abc0032329ade6b1bf46af1487feff12ff2f07b607ec4fe5911d25b364a740af000000000000000000000000000000001176865521d72193e29435b1e2c4938de6634d1aa67b129041e3793a1fe2fe1359c4ea1ca40dee75b0ae3b0f652cd3841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000547e5fffe8e658de2fb5e3dee8aac138c2ba0a134dfd547b4a5d033b23d322b9ec7fe8d677abcbb12104b7ac93b78fc0000000000000000000000000000000006a0a850573ff1bf3ae82aa8cf4642883dddad2a8d298ae0c9d6d0264cc61d7cfcc794047f93dfa1e3f3865cd9d192f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d52ad8fa14e7251acd6961a82fff5589a9ca9cc1480a1a374ff51a2ccce11a77dc479dc91267508a7c1643cb7999e2e0000000000000000000000000000000008e9af828b3bacbb6a6b8b120245f9a396aa33a374fab868e952e935c7449f3794afaea8c9914820a9942862c1951ba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000732e4e0135648f4c84b6630eaffcb8ebc0cc1d16c0bb3503f54ae42c21f2eccd5e7500750a0cf718f1066f4bd4917e6000000000000000000000000000000000fafca10b5b321edab833df1ce4f507b3d340de10f4ab9dca5a624fcbacbf83027ac8ce611c9b12bb26625df8b8a23ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b5e652b6aa0d9c690f0da08927b34edf4ea38fcc3688cf403560d6ac85420e6e82a1671a5f8e1aab71cab365f314b40000000000000000000000000000000001b4dea1697b91d70dd336e6995324a774795e30e3c489b517abd785d2b7476684d5ddecd46c9ac8040bd36ad66ac0df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abd338e96cc47d6bfe6fbad6b5570128b3062a96b3788e660a686ff500dd31198313f8aae952026bcc4813636a71443000000000000000000000000000000000571d5dedfc87c1c511359f3e92937c31bc8b2f9ce2ebf0cdec8650264b48675070592a8f75b0915c5073abe92bbeb941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001676ca539d13baace8f9b334cab59efdf25a6051074e55a3d0d0d5b295c8f32a78d3b74ebe0631ccd04c4228251d731c00000000000000000000000000000000175c364a04c2b998791aeab7194951d2e59e0b2d68e5c11fec8d7efd3008b1e12208779ad3d84c294d677e1baa191d8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aca2ffc34b424998c4dd93fca3b0353fd0d742a83f3fd1075b34ad7fe7346812e0f3ef387cc02304de6d8a9387a004a0000000000000000000000000000000008edfe6a171773b2c3cebb0dc1608b747c0ebcfa1dfeb17932e7e86b5930c4d1774b5d496573526d2cf0f91fc04f64b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019769dacd1a79fbdd91b6a9c790e1e65f48df7551df4376237338c930f594c2e357d3c10c6565448fb8b154914f43a1300000000000000000000000000000000064dea8e3b87ca7c6e0c50c9a3fe0266be84fa7e32cb05ec6d92cd47a604b85691830abd3aedac60e14ee857f17392951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037f9f3d931309ad77e19bd41985423c99330c1a429497e5686d7548cc9ca64d5ce11750bf9d3518b4a7d0e457a192a20000000000000000000000000000000004d950e3aa80f8da86a900490328dad8d3b6c91f5ae69bd331bc753bcd304c8dc6426df32b92ff014d6d1e6081ed718a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f261ff25dc59cd58f178bd2ec11bba46af97081348cd36f5b9abc25cabf919e4634e5c13decca152b4ee9a19fc38cf8000000000000000000000000000000000e41fc18b3a98db5d642badadbb3cee7a51caa75bb30336668865fac6cb1d829b5d803e0cd563e13cf7eeb729f2539131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fc80b9aa9c19f224c9656f8b286d463b2df493238efafdc2b0d19855a7c69a53df3c8fb067d5300c98d78bedfc2bdf000000000000000000000000000000001081013c98b98c58873eb5accbb1c65b6b4a2fd62717e0b472a10d990ee93d0d6243e99a14eec096ac0c5b448eaef0591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092e11281788bc7c587e7eac90cd2128c2139a472548db402263d57e3bb25cf989df4cf180ae60e4af3d5f06e9286f1800000000000000000000000000000000004b7d1048343fef29c6caa0b3b99d56830298d53a5ff21c08b0f42cf092a53dc3c1af3bfc7be1203d965a65f17c7ebd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018db196508e915adbc208a8e865d6fa3c42ad9555040fc4cdaefc449e8f4e491176e046e295d34049353cddbce1665fd0000000000000000000000000000000008e2fc2335f9837b0d6644315d4e268a0fd2e4f7d8bd2ec7cd6f331df01733128ba7f37d3078d662a3ee3419434cb3ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014783c4a9297709af354e5bde16c7b9ed06667c414eb58b1fd76bda9841fa79471fa3103738735dee7577c7462204b890000000000000000000000000000000019accae5e488a5e5bd43ab907967aeb56b53b89988915fb23f69d3613601d0048bfa9e962155de644aa5c4e6bcd28f811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000039fbbc7f3071e4a65d0cffaab8400b12a4e65a388eb1095a410d59d54397f07208edaaabb1e035ed7c1beb2f5d9177000000000000000000000000000000000c4050242a0a68e3a96741ae12e2135a4f9a760bfc704802d6f8f3fbf4c81f33e988d66939fb0e413c2f6bf36b4835bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c879e3d837e11c02c1717ced2528daeb49cc9c7339f2b15a78df1cae041de196c310839e0442cb2fb1e19530a8e7e9000000000000000000000000000000000b9934df03dd15cfbf7a08b897cffb899115e15c2da20e9a6150f1ee9561a5d1c2c126147d77320fc90bb08589a7019a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c3abbe331e153cac15fd6879e28c11eaaf795a93d0f4effbb96c0060810a3560080d3aa1b829ed7715ab121ad383be0000000000000000000000000000000003cf6e75502c72cf4af90aaf8335cd9c5b9ca58ea7344fbd39c1c2f86ca8ea05b34508021bd75a28fd890c49eb3a84b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000908154c46cd9010bd1ed652929ecc2f80c3d6d5e21ffc779935b3c2ee68b05a414e774f832625c5a237a72fa31ed19b000000000000000000000000000000000ee02036cd21a78a9e3fda568e23142493ffd40af6a44241f2dcf0398d6c5d741ac7e2e059b1b60aea7d27920661b3651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000746175511538463411609ebae42d55665532e27f7cc72fa41acdbdec00dab96300fdad67f5f97435b47075937e860a8000000000000000000000000000000001897b46a0fe8a4ee0f7a5aa675952fcd895f62fed550fd12bc093f9bf9472191c62c399c17b9ed2c86f38e9c09aead561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126a14415234f7b7f4961ce08c1e2f5c18aaf6a5643fe8cdd35483645ea8e5040b3279516e1e5392a0915d50848523aa000000000000000000000000000000000b1ca84dc81bd18c355046c637a06f6fad3e79f5e1bb464ebae2f9146e71420a9ca10e82577f33b40204f74e18315bd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ed2143f8ff2ceee5f7c0ec019624c60dff32ead310363a3a6a2a4302ba533c012e1f221165eec387811e42b94d79f700000000000000000000000000000000138077561a3a47b50df6012a1b12dee3942435cf456becc9f5f2a02f0bb07e3f722c081b4c94d6289f11eea5783f78181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174785e6ee2dc015edadc2c06fa12f7b52605e2d350a2031d85bae750ef1e668fe728ce6993b7fbe4712abf10df46dbf000000000000000000000000000000001344e109ff7dc1be4e0ff92c56c24d87c1ad7ada62dbb6403650ae810b0911b4d72bfb568621fa0547645e3ac0836bc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000950ddcadd811589052a27c9202cfb690815643addad28ce53fd3603ac27487fb921b6eb78bc8a55ebee0cab5c5aaa770000000000000000000000000000000009435f3b84da69e4b390476099a29e5d9689203ea903fe85a083e9b8f69d9c2f3e8bfdd15d8718dda149b3e102a9a8781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d8c5bffb0270ee86dfa6fae368ff227f02cfd651656d2689413ca4fdf7d4508b172606ec79f96d858003ae4039252c00000000000000000000000000000000114fc1a76cf7e00a13d5a6a48e30a40bbd9e18afcddae1e438111c154ea45cd18f0c43c55cbec6b65e192bf164b3f5dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000645d299d8e43acb8c4ed68875f1894dbb62d92c303d1a8f17397c6196f96d2023143fb9b7ffa654679444bb44606eca0000000000000000000000000000000010a962a86dba6e7aeb3924fdc8e1bcb71ddf261783cc78ea32632e22c8ea0e4d880cf476bf01c5bb0c9edad819d9b8081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129064f29ba660f2beacbcaac8edf9db069ea9040af0c1328beabd4f22aa0775460ada37c8b977adf413a5fdaf9726af000000000000000000000000000000000015945e9a1cc0c7dc44e004a0d7e37104243c455583c650ba89b16d4a3e937713165d74d7e1ba27431eb84668bc152a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165b3b0755376540131bc9dabcf5f2eecb5313ddbe3175a5833aca0e2708ad3ab4608743f142f290cf48289af685daca0000000000000000000000000000000016925fdf22bf307f4c79df436fc6f703cbbc62222c5999cab66b3647c7932362a1899d1e4648f12235e4cc94bda8606f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001125721eb65720484c8e4ce025a5747852282ffaa074b6dfd02db5fcf35242a115118cad1d9a9353a52327f698125000000000000000000000000000000000006fc88222f75bd46d256cd51b0d7e831822f3364fb95a95fadc7fc03568a756f2194a1471b67a0d1c7223396f48ecd2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c28094f7effaaa5063b3248ad3716fe28021ab275ba03042f79eb8591b56a6c8847a865ea72139ce3d3ea16ba88fe1b0000000000000000000000000000000003c5daf1698b71e496f4ce285d543916f6733a1d680975b3111b37ccf58a456187256d001b4259b4582b7713725c3f381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a70c414a4b2b1d016bf3264011b61e3ff595fb13c39ff274f71d36de4b3eef313b688d19ffcc5ca74342abb9c095b6c000000000000000000000000000000000c8818c5f90a43da2b6b83aa90643a158dfc28393e2f4931cdd38e7a3447c9404c5e16f7156ee0c64f126754ef1153201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001743d262f73919d0208a68816e52625edb7b29dd72452f14efdbdd8fdafd9d85c8bd45170a072bf3c66e4e8a18a14eb3000000000000000000000000000000000232146218c7cf14a78cf16e040732c329fea13128b401a382b0f937af555034d79ffd5e4a546a1db52f295b3d28ac281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015069740b395f97f5253898ada3660600e80f9aa0413b9e175d7168771c3e3e42f288480710210aac610feb22b1594f20000000000000000000000000000000015582ffef832ddd6a4c006598852eb3613775948e2c558ebfdf24c444403ea32383ea248076b1040ec0b3c29a166be481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a282da2e9cbf23a606d0b824d9833600b80d89607cab48b7ed0326243ff90b70a9b6e1ad13d6e25f2fd82462d43e4ab0000000000000000000000000000000000dd79dffb171851c22641e80b1cd4a44d5fc9f07e58e54d24a361aaab1a8ed330fbd8cb8884a52e4a20e348ae0903871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006fa5999ccaab6901669249cca9ae06bfd7a571e09b58bf8284ac27a884ece77bfaadd3726682fe7ba9665a1f4c52f90000000000000000000000000000000017a4801d1cd9a59e9377b8286ee006136cc97662afdfb00e57fc0ff294f7f2641cf0d56afd6b2197827c4797740e0b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aca47435916ca93d4e0b461b1c03d23a786cea4940ea36cbcb4eab2bc9a624e56369891e6fb118b40953fa53a0c983000000000000000000000000000000000f679d5aeffee26dc4c200b1f948308ea011e1c1f2aa3b55924f576a9f4a0792e44519ec92a7a7bbd31f31b0c82c89551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023e5d1f2834b61c8cd56ddd41b00b9009de594ed77480f20498bfec01aff6276b39cd8bbbc872a011d3c79dc10cf8ba00000000000000000000000000000000103dd30d89064d91c77101c101f5d6e026255c4029ec39f43023b929fe4309c1ed072c5318399902376e38567c3392601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000306989696e4b04f85681594ce571923228801e99f3e464a3b1623b4f977079ebda82c0651cc23cbe80c8d881f1eb48b000000000000000000000000000000000c0081810b38f1834da22452d289ba62195a3d429ae39565e7b85fea00102c40ab20b0ac6bedffc01446bf01d05f5c1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcb596eb18d3f69bc65152705082d10ce3f25925a314c0bd12d9e0c5ddfb874223771cf95a4a7b7176361501c4c2ad70000000000000000000000000000000014b954c6a8092830afeb67b969189f51bf94a2da7a3bcd9b7b42c0e238f3ffc435ff9b989a3b39d9ca0dec769c3b6b8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bd4b3bb2e4781d4df164f6bf4123c38325e4de0bc86edc41ec56d66bc2746255d1575005c3e242f0a12d1f017b089f0000000000000000000000000000000001f821dca34b5975aa61ffbc793cce09c2e277be72aa7bdd32158167e9703865db0f14c24c82831498178750954ffcae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c9d9a961b2dab955ef5aae435c7e96f3b0f37c686215256f6a75e656bfd9d47b0260da0ae0e2b7f4944350b52db459000000000000000000000000000000000af14a1b1553646662a418f824aecec052ac5e3eaba4747e4a1ec8b7b8f32f5e2c78233672d7924352db9f512428b24c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002af4be64b52ae057b7dfa1b96a8ad8844678b538e70051d38aa1d7a7c36a8b9715992dd670d9cd9b66f37d565f7deb500000000000000000000000000000000133e9a600d959de72ec7174f77ec998ef4890733bcf231ac781e4c45ec3a323151ec2d466fba636c3a9aee3edaf5adef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b87a1057f4e551a0ca8553b19717d751d63747225ab595dbf242df2f49eba09dbe8d1f1bb2df7879a6753bd76085e70000000000000000000000000000000015dbf6e786a4182858650dbd4d61bb39c3a4756d42527423c9748c2d9c04ccf24ad4409cf389af9b4ea55713d92b149e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d938d1f3e39b9eb6bb024a726befaa15a894132a38f835285ae61d164ecb050689fa38b8afda095b2494131cc24737000000000000000000000000000000000199166ad2d50c43c496bdb355d55ec25dae47bd5b8514a8b55204b6a407684db30a88d0cda6943db4e9122449deb71d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173ffed3a502923a0cdee0001301907ed3e91ac6598cdc602aac5d295e3b3da62c720498e535bde3726de2ad52e1a2a9000000000000000000000000000000000e9aa6578309e7d1a71ccac1da24d37310801020b55cbf0c58bdab7a7ccddde9ae1952b17707dce05216e59da6ef6ab91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe95a99f180d017d57b30c962dcebe63861eb0d93cfe5f50be8e41cd8af8f65c0e9cf83c2ff21cc5910891fbbeebefc0000000000000000000000000000000014d169be60848ec8b48ea05fd2cc84a51c18abf613e08efaf7d6fff38d2265f03b5b3fd24b51bbf1efe80ee4d7ba473e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bcc600ef376aa3f0c003cbfd8ae0c2aeb976bf3cac9d1d81194e0b2db1a3a4186b455590ffa94ccbc331bccb9d6ecf0000000000000000000000000000000017606e7b18f12ace88c4467399b78282e1f201da409233f20b66d9c9ab2ffb31202887b5bc285dafd642a9e89ac0a53b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092736594e2eba4784f87da49b487e94d9c0054a5032b57e7381f7cd08544121e4f5a74e7efe74ef997093edd745af35000000000000000000000000000000000349a2ef6c262f37691072edb1591f9586f8983abae2d7cda2d77c7cf3683c86dbd32cc0ec25cbfa2dc46840aba8b3421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c526d8ef8c924fc55c756be87da1de5840f63f6cafdb2ba9e1da9837efa602c677d1680cddd948266c958fd1bbfb6100000000000000000000000000000000157b83c5be8c49424c444362dbcdb5e301a37ca51a795696eda9b65e3ec9e062021102a43a49d4440ce5317682f94f0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002596396344d6bdbd642648aea4f33fa8c8ed14f0ad44b801ff0d361c10b4c666d876495ab0ff6482e930d0cafeed983000000000000000000000000000000000bc2c579af995417abe907e1bc51f5a9ce3aa19e35fa188642c2d0ceaf1c4460e21c498d35b78019033e80666ab1ab671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001294bbe57bfc324e73f9d46028ba61b681f2e28b047f952dd15315a11967d03a5ee0bcffbcd50b5f04bb222f88549f0d000000000000000000000000000000001803915af476cef3ab0b861b6de485bfd8ad9b165827b31ebeabe77c69ff4bfd951f241da59922fa90a8c44d18565cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c4f34adade99d3b2ba56d3fe71bc04de25eb1d6e89f0fcd052555ee9730133768b1d27ab04c2626201a46a1e8e69950000000000000000000000000000000016aeef79f5c9c2441994624a25528f337a94b772fda1239459a2285fd804cfc34c9423cb0efb2ac28f6dbfeb922e54d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178764d19668f57efe5dda5ef850a52b8998787262888c971f0b87c14231d430978240a507755df9f3df325823f4c782000000000000000000000000000000000aafc8833bbd099c172f3199937daced1ebeb036b568db5dca0245adcb5a41466301d57bc658ed2770699326360fb6851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89732284af75f0b00ba60652e0b30b160b61a7248b87a44c6007d13b51f6cbcfa23a6f5f392fae9650d3a6a72ded6b00000000000000000000000000000000055df8a7e8bb2e5267774428695a249450e44bf191e1dccac007980fedc261991785a850319e73b3b5433bd5403de5541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d5d3bba8c9f45634da77af07bfe104db7fefef40fbe082facae4ce6d00ea2390a506cf05dcd6acfdf25e663f56095f0000000000000000000000000000000016a59aa451d9f4e62c719a9e8d914fe8bca8e7744dc68e860e3e9ecb5ad2f9943050579fdbc711406213964f2231ccc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001385428013d8f81e65d2c318568c304451a611ed33e83b63557e1911eeee3c513bb33c6a6472964bab6bf1fc01f5ce84000000000000000000000000000000000c24a17eaeb3efaebac60fa72554fc409bd58e7460cd03c7a339ab5bcff4db2781d674618a41d5f0653990a532e4bdf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000427b896bbfc3cfdffe6cd45d52fa199a4cb00b82e2b7dae09cd6a40b79bc3543a3a736def66a33b812579dd27e1cf57000000000000000000000000000000000b9bc65ee5d2876e6643f64e108c5ff33f97323dfe34033cb74dee1b2d7dce22ac00523ffe2067eb14d5b304dc7759fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cde14008e6604a7ef648dcc6cc65963c63f10cea8d3532a996ad6459e5a98c5dbb32e456740dfc44b4e5e6e4d297c6000000000000000000000000000000000cc3099031b2a7238d391d4e42b9c6e491a132ab4f5fb931c395100c9dd93950149b77011c010323fad88cbf60a08aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cf05fca93fcb755b2d62986b6fdf81e470cb61d712fa389f4fdfde4b037a40be6d8890e312632de8434d0ea755f2c00000000000000000000000000000000017294c2b8d346536d4aa96f14b38f82a6a2f37103f09417fa58a0f890d3ffd53fe2fbfb6197b09b18810a87433d071c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000950f1ff2d698b9ad82428f878cc58e8bf76bf86851f79758891f1190e7b61440ab7cdd4b190cfa9a9f6bbd1762b682a0000000000000000000000000000000008637379a889dca6ab39f1a4b117dd9adf70b97508916f772b799fab9be3ae53fc392cecc259b4c58b0804eeb29409ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001406dc561b9762fa2a902f38cf4bace57a72e8bddc4b7ce096fd258debef773a3f98acf9dbc744490311fd88453a0e450000000000000000000000000000000001c3b481b056db9669640b362fdacd5b788bce16332b3f5f680a62665db7c676f8d2a6b3ae0c378ce687350f40269d901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f24ee4a62d0051d991f9f21e62537ff59831feef78e2ef917bfaea1412db8a328f11fca5e257289d46ad2e4d95adc81000000000000000000000000000000000d7b3e56d18c174d23bf08f1ebfba02a49e80d50776a1ce5544895954e0648413768cfbeab9a3be97fc361e1a7a961bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f37fcc8aff701f7577aba494fa5e12070d7908cf36eaefe6a69ebea5d0c5ddaa7bb2918467ae33e5788f4d4f24bc4cf0000000000000000000000000000000011adbcd33692fb2750e2b2d938c8ed2edce5f699449ccdf8ac5b8f330be3508cbc32bacce9d07cfcbd97a4abc48219f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c873f4b93312dfc235afeae4a123b9e4f24bff25975a3f14ff925eb73d00e78204cc3a82021e32dcedacfd9c91db080000000000000000000000000000000006dbce9a89622e0f1a3661888f3d2f69a15824209f1cfdb01807542ab82d21f8c3df64302c8d1815ca94383d8a17ecc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7138cbc0c40a165fbee5dd12d5640bf0b28147a3147862fc7d3cbff4e92b27d1042221d387b5072e8263171e6c24c600000000000000000000000000000000042b5b8785ad5c14a4494234542b41034ba2fd008e2942f78e0ddcdb44af54aed8c79ce52b1cb1f0ff931db80fe4e70d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6d0e1411fbb446e6916c50127bebdfe6dc106314f55be1ea5d13840f07a60769aae888f4718607d83943c634c350970000000000000000000000000000000018db45d519a981be6021fcc3942916ea72dd80407b679fa50061b899c789b87a010654bf0ed9a5875f2bd112cda25f641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c5b813aa47c06f21b660584d6422cb3f2132fe8b988855c418bd43ff771989a06e41afdca6a2d6a8273750e94c563a000000000000000000000000000000000b6a8644067427ab5ebd5b8fa30a9da8ffb0d60119de5634a6db20684ced1de5d5f058f525fef24d89a483f5259c39981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007aac64751f021f7cb5b3f80a3ce5437b7b03f79125e05b6900791ce938fc4c4459d90d00ed1e9f669fb0489f4929ca20000000000000000000000000000000001da0a5c2eb2317373d59fd16d4db0edd3886d4ebfbc9eaf19c2642f1f2e6f3dcb44f6a0cd7ab238a842b21a8348925a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000267bd2a8e40a9e9ee94af1fa9fa5d7559ffb98c9c8135cb382d97fc6e66e6488f690e2a16344c4e5f48aedef29d1ee90000000000000000000000000000000005d75fff326bbaae44d670d52bf74a8b02534de696bc9eaf66fbe17100ec8408be497044abbd0dfa2422ee797a949c341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029c261b11f552bda47f8af49386ca4ee973ab8f477974ef1a60c3c20838e13e88940576a5f94b7d1f58c23ec5a8c86d000000000000000000000000000000001676b9e9ad2a239b033666b5a417b4210e0c9f8037310d3f0f642cd63c62387d656c7e13f221b501f35736915b50663b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f47f01e087a2b2eb701102aa920b67dda1d2595acd813b0a9414d0cb37769e2ed9fc0aa6bd9ac5d424bf038155505d00000000000000000000000000000000068503cfc4d79f3032927c8b0e8f54030bf2b9f83979b0da4f7db5382c928d08723038a8247a157289e796cd983156c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a01a80ef24416999f9cb8b1d50753a607fd87713637bc4e57ac2b49ef668c0b9ae5ee5427e4c616d2d2f20225419c200000000000000000000000000000000055381c235ad7a7814a04a82feaef27c7645c53ffaf5df4fff5b3b60eb0931530841bdc527854b23bab51b354192badb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7b63bcf9a6025f35ad029eb483bb48bb51291dc82e5689899f75351ee2fe6ab927045c196cfab5815ab58ddcdb58fc0000000000000000000000000000000009c25a6e3753b67bc87cc25f4679774b6ce00d37e5aabe6caf3c4b58cb10ad1ac0d96e0fbfb20d485f9a853c9de791531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018616fac9052ab534418434683983c7b144f2b7622813ec2c6739d7bdad6d706d5c72d94380cf3e38604d7a3098fbc340000000000000000000000000000000017c19b62f47bbd0197cbb33d813e8bacf464adf82ab4f6fea6269f5609cbe2275db082e9883856cc8b0e1b577e13b1d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6d73266155d16e6dd44daf053b77bcabae22ceb19aa8deb47143d3593d63fcc30b2e0edd146021bf00467824f6f110000000000000000000000000000000000da0256ffed3f387e8171efaa335ebbae211244886bc586bbb8d155a0ce7374bb6bb9d8bfc286638337ccb6d3fd920791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd1a9ff8d4b11234eacb6d8e362f2c800c03156057303fcb64fa18dac3260d8c0e57d10d42ba9719117ad2a71cfe072000000000000000000000000000000001757b3d2f217d5070673b78b49e6e4f33bf373021c6c56dcfa8b22bdd66cae266e091dc8ef14ea28528afed5d8268eea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098530102ab318cfb1d126c670c03319b0cde6149bee761ddfffdfbbcf2dd608ea671cbd91b9f02420df44ca3ff7cb8000000000000000000000000000000000048dc71118929473206ff870dda9db6d15a727b6907b1dcfdc8e350df94dc1042adf295c44bf632ccc348c0d94ea62981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aed1e6e862dc2316fa04049a064f4771cf6c03c91b5e1ce72d6a20bc0df8c5c2a9891ccac5a15fd56fe1e2263cedfa70000000000000000000000000000000000b140c3a50c6082cb311ce8be3ad09440f54a732ee26e420220f18a1358fd1f8fda88729e4a0e8ac1e25abd93de43ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008570cce293e71e2efd6cbf757f275b471beb92698f0088511834a9b627c146e1cc62f6f1233586501db97aee6c0beb40000000000000000000000000000000011510affe010d23cdfdcaa4483672cdd783eb2c91ea87bc9b50ea26585bca1c892bb783d19994b2a9d244e37065b9dca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c74029a5259eed3d4e6d816639181184dd4196cbcab69ec66e61d53db7a4c4c953ed9c605ab475b4f67e9801839d9cb0000000000000000000000000000000015ceae837fef73b1339343be14e36d125657e78219d18582c32a65d2af856314e6560c5d10a2e260e3f821ed60ebf6c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009810aed331821fe9628ffdd22252723f68c8f6e5ccd12ed91e0620c9ef03cbf81a02bfb27de0885ee6bed5671e916c0000000000000000000000000000000000d981ce8a913c32114115ff0ec28cc528e7cbe77b351bc75cc842ca2d3ec6907214b37dee36550d86d63051dea0c40521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f41ebf4dc2a1a0b6ea0145d691adcdd16da47323454bcc598dc24cfc99cd13e0ec6d1abb7186c8bf5bd196b949bdc300000000000000000000000000000000193663df67da9390502458194a10449e85212207af0afc7245ff917e4388ad4b52ab5f15452ab55388d40a91ae43d1f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073bd2bc68a882d64e355236eb5a8e3d3043691e97b1882f02624de9ee9378148c2245a720127af9053c6fa373318cc20000000000000000000000000000000010f587c17bd131b4720288281b08b34777367b8d045ef908135488f2a3685caa07e22ec653db565c6c5024d0bb9ff7c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139c00a3519c033c7d19624a171b205ec172a663469b5b825ac4570efa77e0613a66e6446d0848dd73e48bdd5254f9100000000000000000000000000000000008e0da7802b823a49f3ca30fd9e8c36d2233a1d519ccf3877ddf841b060c4b068527fe8a69744db8c2d1173998a7dd8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133c435ed6173adc2ef341e3e1359432fc6963c9df17ea6df67151be27b5178adc95bba3592134adda1df90a59302963000000000000000000000000000000000629836b1c908aeca28e755a021c15e9b34bfb6aa296822d9f5d0ee74d6883036878e47d202c62c1faaa4e10bf6b311e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2e59eae1c975d87b6238671ce5d0e5ac55c5780822a183fb083ccc042b9b5021b5485660353373730572704934e42d000000000000000000000000000000000ff51161a3a473ca78820bd23174a058c7e57e855e01be5fd7e234e0879cf4cd268b04cb7abbcc58aaf4e7ebfd9d62551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011143b11e7048bbff0d0768d5d53023f72d1828b6fab2a571afa9e54c31616c63141488fadefd06fbf40b6777e8bd5170000000000000000000000000000000011f56cda8503ab79579457ded3da095de9ae40286b1761d566558f1307233928190a6e44188f7a1490ea74c645816c091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005cdfcbab392bed9af7a163296dc0e03cc322bcbae0312c4e90470bccd3a8c7ddc2410b8e67798552514f173a54dc0d000000000000000000000000000000000b4e42558c328e8e6edafc714ffc8119bfffd2a707c67cb76ae4cabd5259baa6870a6901431d6af743ddebb1fab472cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c541b69431810ddf0d36d9aceb1e489f1150eb7ed2a700d3c629813fc2b5ad70a37243f32f6e0904e838f5adfaeef7000000000000000000000000000000000a16949686065925bdb2158102e273a567eb4fa17f4bb5be9b5eadfcf9d7a7853bde3c379b5273dbf080bea9f07d667c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010763d3a4dcd76ef383ed2a286aadb321c632d0e8131321302ca4bce637f1ec0dc421a135792b1dbe8917b46331667f1000000000000000000000000000000001920adcd45120840b68d7cb59de44f14fbf5bca828ef421d40925bc9cc42a6d7f6f00ea48a972faa81725b5183270bd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0e9614cd67f9fde907898814ae4ac7d0fbf4100f2feea3d7d49d05baff2dd29c0e00fbf4a5c8d16d953b76dd497caa00000000000000000000000000000000130c74a102c92a2bb442ae05f782ecc7ca2d56725df95f6bfb7387f9579a31a9c40ee9016499e7bd1cca3a3bcbfe168a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072b8012a3d30deda44955b8edd2d5d18166f148474e1113034909989188da1795135af8d4769aa71d04ff53e166389e0000000000000000000000000000000003de9c26320a159e18bc6846e00af52b78a60917b829e431b911742c241c0c965dd9abe214949f620faa871c98b664d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001abbd030cab8dc9c113521600af533c759e50ea1870c79a891ae34f15687c907d2d6d77a46fe5d8277401f3752e137500000000000000000000000000000000046dcaaa8a7da0498b7481776da1aad35075317d106a4635de4d9116982149b0bd388f37ad3bee5e5999d2b750cbd1f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa47f2c5f1438f9e121e7b09770cf6a5b3d7a1522040da6af843581a03eb5ac6af93e9b970500f5dc07af577e8874c800000000000000000000000000000000042ed459f246188a860d20b20680f9e1a6e19b7d2d8938a4a3646900506b09eaa9d67dbf54b35019a6d01fe515d243271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011daa6be4c418480f31e415d80349cb567f030a64e6b183890ddfb1d690ebe01a40c83584ac256dee1ca58d3ab9375950000000000000000000000000000000015bd24858629156c50384d6cb1507396bff8e4dcf8b035a09fcfb4ff40f7d2183cb3dee9c8c17fb93048dedcf85957581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd700cebe3fac881a8c5924e7f29d9d135a58c8a23208161644414638db73dbc7bbec4ea9711de9619ced383c9f0017000000000000000000000000000000000ce131b4af6c881250c47eca0e1f3938884c1aedd7048e990b8ee9f09d36743ca2ecd0654493c2e2970bb55b94d070961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018361375652152eb1495002264e1927bd90aad00c3d82a32ce96f1184a1f2d744201f4f943ef6f717dd6b96d3af50e11000000000000000000000000000000000e2eb1cf8d8111f0d614d1b5186ef1238c57c3a3907bfc23a9f98d31de07864f49eaa3322ccdc4128fdaf9b2e5fd304f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e312092d487a105d3a962940c6e84c849ccc34273ab9228ca0b3c30d4b2ecdabeac9ce9578b174993536087fdfa8e200000000000000000000000000000000164815418fcc5e50bf4a7ecabeb8ccdf8fc721ca4ba24af54cea83026bf0b10d35e93e8a3ab4ee51a456db89a11727621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000369c0052f210617a01181ede90aee47bfc4321361637109b09d59035b60a34590107768bf4295947436dfd2cdf9b1ef000000000000000000000000000000000dab21a273c8e9b87af07f1b19fd7f5216763cd2e04566b85f4de1b10b1f65d458d0d3540ccb35027b549ef0e312c9ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183b501f63779942caa12316fe00479745a2717fc8502509c2fef2b995b1b140bfea106f622fdb000d917558adc2784200000000000000000000000000000000101fefd8dc66885cbe039f37777446237042aa12f417b68cd5d5942a6729f3ab941bd409815e6d5c15d21b65ac0d42941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dee3988a8410062f0aa41c28cdf7807a2e43c9cddecc5afc970416f37838d06ced979f465730298d33361a60a5b66900000000000000000000000000000000078a53dbe04a7ebca62a0dd6e21766a2dba416735dad9cc35b2b7eb7798a0202f29d924583519552b9082ce311fd313c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001742e2c7c336bb78e8d568ba6a5d5d3a99dbbe21b8aa754319b98282eae2d318e0237c7928bb6d91889dc452a6643edc0000000000000000000000000000000019b13d8dc3aa9108af620a5045b58b163594f679510efc725f35d4e028005eecb217cec8fee5b4853ed3f5e453fd29911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002857f6d7065da9beddc64cb6b7e4fc0208a4a2bec25a77c7cf80749dc12baa8cad350dbb5f5b719702efde7b353e005000000000000000000000000000000001687a1d1c8fb22dac02a67bef158b12cc166c54f92c5b09910b7d5018325364a933fa77bf419f6c50c86d7fb7c741f921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170c80454cf14fc2e38885ff416b6b15dfcb4c71b8501fed7dfec7d820898fde9ecb75cb3d99186db1f1618b98e0595d00000000000000000000000000000000103be57ae37ca5d3260e091f46632ac36ccc2e8d21d7f916425610c76431eea6984101773d5e97ba83d5ec389671bcd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a944bc3c69610cbcb0e30aa3ebc86c331bae14b3786056396b4eaa89b51b700eea0d989613bc37ae341788e3c91a4c8000000000000000000000000000000000fafc203a3e081cb92509e0701d84c602d4408038ae24a04abf377956aa40d7eba65041b99250f06880c82bf659d72811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001629c8bc95f143c205152c2aa4ee97a56f09122bf91d101ac72ee254dbf4acdbf9b91d0e350d81f15acba2c804b3c91b000000000000000000000000000000000c76ee1d073351a63a3f080e8ade4dd602014b1716cc68732a9bea0dcfe08687a01edd8722a26697b3e6ddc7ca6c58c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b0d7d1bb038e7dd0b17f3c425460a9c2254345f69559b2de5f341d07fc3a32f01b547777c82dbb2e6071a02d7e7f7b00000000000000000000000000000000161a7e2ae3405b762b06104fd904526a91f4588c413c172f9562f3fbca340fee3c13023d24ebff0381a641fc4388bbd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef12e1679b88aff313fa2426642fbeb62cb68ac6605ae33ebe0e00ca396ff3a8bec7254b33360edbf7b14214b07cc080000000000000000000000000000000000b436f6d2ceee3db3eac89133b4f5be31841a7b0e505c5b2166379abdbddb7a7e25de447ebd698b50e256ffff43afee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072084ca44403d9cb942bcc1618ea4790ffb293d48515f5e8e489134273162427edfd6ecbc7d5b2afb3d06ec69b0128e000000000000000000000000000000000a1d13a8e9789de0320dcbd43b0a2a80212b76038c154e213cfa018360ce5f2ddea6384e4d119f52e9d5493574aaebd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104ee685e35e23a581ad06f24f3cb98fbc8dc41887b02466f60f05b12534ee63b98b05e359efce8c0670303d6e5e0b4600000000000000000000000000000000146f6b774e1e3a42f8e009477d25ea3203ec3727b2bc857d148a29545549d707fe4724fa3bcca306f5645e718471e6b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b7e556cf2eb7b4bcb817c7964a11c39738820bdb41eb2d0f222c749246d07aeb1a479cc7c70c81529ea5c1f2d46d510000000000000000000000000000000003330e67685649128c5fea9dea20ebcbe698557740481d47a09484dee09e0de9e26a7dd9c4b771ef8d934b287b83aef91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031501aad4279f50b369cefc0038a7811f6f24d78c8497354258696770062c591f0a8156fd2720a9d25299f8deff57f3000000000000000000000000000000000871d0f5d69923ad1c724091cacb7d49a8c6c231bd66c94b4ed2ba729201dd5fa41b35de1332fa47bec780b6eab5656d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd1a92967447ef8d58f8646edc5ee43353a24d7fc412049126d164b348e2e45e85464884a3c9fce9051a7df15c778ea0000000000000000000000000000000014240846743301dbd3b3e8198bcf6313266e3b0d8b959201efd434e0e6b6e3b00c07402b0557cfc09d0398ad47fa69441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c321cc923815035ee51c1adf2693f169486e23c7be995867414c6347f2f402aeeb7615bedbbb2955e22f10b28789fe000000000000000000000000000000000169edddd17968dfc019b989aa529337fbc6fe93d841d39db96a64ecfcc5e4f3283ee6771f5fb46b40d1aeebbd1432961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180a8b800a722fdff99dafeee24e696f5bd3ee8cc43b1c65f74fd3d6e0ee08928dad0032b86ff4dfdaf8927409aa796c000000000000000000000000000000000a346e071b757beeb12e187faa00190cb0c0cedc9b291b2201937a8e1e48a9ddf5172a4456f6ef63876e77fa195ec6561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011389a42c8494ba585cb22345a7feb47e38049960842f108604829e1b45694b2d1c804fbf85cbda092f2df7bd2d7ca1500000000000000000000000000000000121bf878379dfd6272662975bae1c9c6a5715ebe624e8dcf97a296d22d9db0a9280bf7fff23a55aac91f700f3a95963d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e522229006e9faea36eb4da89afe28277dbc76dae0e30c07402484dc53c9ba754d499403ce70d3b78c2dcf595ff6510000000000000000000000000000000007ae03841d24a48acddce4b902126646befc66b8870edee94e307c4d78b8ce69560ad94813ebd1424df480215fcdcc671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a63ca7d71bbe1c3fd80879cee32969f90992297a1b27a3ace516a64317e50eca6589e277b4b76b733a9a169c3cc4dca0000000000000000000000000000000017d0de9c4fed354fedde304d8639a9cea59cef0a60db729e89381c8d55552f8a3e7429a4856406171dddde05982f319d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001205c786a95dd3a559f643d9a41a0bab7f92064c77ed33070074f6269d9ab3b9d76f77e5f1d1df0d3773d13c2e2a442800000000000000000000000000000000074f31b38260754059ad3a0ce3086286f1224c8bce830d670d1b15397f7904b3dab3907b2a4e76f99f0edf09f26b73401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184bce68052d06c341b2c981156dc72e4c88f0615da6448b4063fa35ea54382a1fd649b6065d5471b4d4be59149f8ba40000000000000000000000000000000017c77f25fbb60958730b556c3346250b3743824f14b18f3808fe093e86e29e2dc16fff60d32ab55d852c3b186e1277ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a470cd7453757ed6369a1223af5f50398f5b3678c70d9acbf5f06960a9f9904b1675cb5961d34dbf274f03f05ffcfaf00000000000000000000000000000000043e5a432c001ef4774067736c9f15d09c304c58408a852f10d2c4c439035200dcfddd927cfcf543974e306c9cec94ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046dcbdbfe7e4b90e6dc89d8f167f4a1100db4e75ae8dea976bfc7787fa9bdc467a4f3a385748821ffdb2255a10b72280000000000000000000000000000000002156f571f9dff275099b599192154ae5f4a9985b04e576b9716dbfff904ab7586b0b8eb24a8f571ff4bb4d47cc40eca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000765b82e13b52e76ceae9794061c755260684d7e7615b2f3a62504e2844a6cf85d1d7cf6fda39ff9d17eff15c805c93b0000000000000000000000000000000012c71693dfba217039a10281bbb95c59f0b8d4501707f534cb45a6144f1d44e6a76a443962ee4dc344ea1c36f8d2442d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007308bcb2fa13d30cdaa806c48b4bc11d6423d9d59f7ab78264df7bca8ee03b892f6e9b6813468d01be0432682d755ce000000000000000000000000000000000ea33f2c2800dd1c94841f137c9d2877e63ac4f046ebf3aa4f59b38811f55ccfa4d179d42a4c3911e102ed36a7c47e541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8bd5681589bb083445fa8aae38105ad7e448b6bc2b36a1bdfc1748f8761d24000298d6efd37e67f75049cbae72e9c2000000000000000000000000000000000274cc3ebdac9d4c053bb5ae71a03f731593a0bdb035ac1cad406bbcf72cb90c8f4a92a8d8589f1628e587346b83744d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fbbd7941f6ea166742aea1a88f61c217210eafb7e6a2b3faded8cd036cd1c27814f4699094651493f96c782d310de30000000000000000000000000000000003b9fc99928023c37015b34017451ba68115c0ade22ce8249e51ff9b7d58b24ad1e38ea0f4cac043b0aa8eed1f9029cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e9f478bb0b31f1b527562e83da937bc718ddaccac3b729e03c87c6a7dcfce8d4600fef84d587eead1a0eecbfd2d7de000000000000000000000000000000000714c6cb8c2f34ea9205b842b8278cc17843c546a82bfe012dc6160156f41c3aa7584fe2925ed6d11df3edc4d4d16c491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001370df9ec561e69c902e9c176ad0e02332e47404ca6981bbdac3ceec171f61a5e9ad9dd94589bc654f40651d81d0a8a4000000000000000000000000000000000c12ec9143bd0915d1ab80fb1d5bcbc5515473ecbd1a0d393cd6ce1e781b7cf302796e4865405093c89f1ed5b54ff35b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8fd577d3e12d6bf87471876099f81edda275bd7697cba7876bfd58bb1478b8ac59d102bec3cd658f22aa2d613ac3f70000000000000000000000000000000019380bbbd7b532e0c386058dee1cdc36aa632679a5fdd9ade46ab3906e7c021bf6fe985c8387ec3485d64cc2c515ae1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036f96bd1d34c0d46d116256d2983c32081af467cdcf7c73c6c9042dcb1b57aa867ce0d3c4531198ae05217779ea734400000000000000000000000000000000145fd274b536bf175ffcd342a78c9123350b9520db744d6c3b0852dab49afed7b1704b07e4447e9f0ba5958e7a9350101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000336e2290bad016296807e7a46b8246d32edd8b2b7628ec2a38d86962af4cb939e00bcc08eecf8a1c6418dcf3bb86d1000000000000000000000000000000000e473bb5585fbe385d325d761845d1170d8a0116a676a11fcb271bfe6a5adce5b74b0ab2a54fba2fdadc75d3dccd11241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a59b1bd3cdd56b4c98608641c6c5cbe54df9b25004fd4fb79516806b95d40737b1e0e8fd06216a0d91d81f60b9418cb0000000000000000000000000000000007455e41e85e846e22ecebc65737b945f250f346941918f80b1175b4a5ec0a927050ee7839c3d5de9d68773638bc8f1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138458a8b15ae14c7631e2e59ce3bdc8926594f7903173a305685c11848889819861a26250c16a814cd5a005941ec915000000000000000000000000000000000ce62fc63c148b02ca63df1a4d2167d921bfd99278cf4b235613d12c177c7af3cf4149aa91db68af26118a272897d6381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121b854dc021681d4b0b52c499e00d8e8e7d614950e03f4e850270a5243b6fa8ec35d5349c5cf2804b1b0235c264e3210000000000000000000000000000000010699c101af4855d9b9963240c097323ff2f4f01a50e663f00c3911668ef1d9773637210f1315c9aa37a52b1a72e662b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e32cb9667f18134f018ec040fed61571eff27dc2107c03532faad6aa3bd25ef2b63b2e3b68c96503a5bb63b29a20290000000000000000000000000000000000a039b46f7b48303191a6b1a5fd5409c02d492238274159a0a6dcb9c3e06ce3b1c76ee3582fad064ef9ad32ac07639f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033d7bb66cbf5094df15820e69ec80e63f3bfb98671015a440548382549d934673828a1b4831112c76c81c4c6a032065000000000000000000000000000000000de4d3d1acd6f7828621496e476890f98f7229c66cc2fc2da963646f90c45c553f37bd17a53afca717011b33641166061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001503020b96ddfda47a5c654d27fc3fc69db6b40fbd88ece0fd4bb36d6bf509bde1872bb25bab1840451dd5087c6950be0000000000000000000000000000000000ff371616b334737ec545edba2fa532755e7be967d115c2c129d428fb9a6b360715ce03556a1fe5fd24228cbca4924e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019562b278b8cc4adbbfcdfc460a098a896f7315751abf2ed58b3a098b99f955d6d5350bb52d9a194152eb543ae74d4f00000000000000000000000000000000168a1329b576e00ae1b69f94fd49ba623d6fc9dc98e9b26efc8eec7298e5ebd59db4e5034c7026647b44cb0f626478ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3796128efa82e44d2eb70a3b95187033d08b9a929c3f0103ca392eca46d4d91d9f0fc4dbe59a65da2c0274818d575800000000000000000000000000000000047598c3d37ab08ddec9dec5e7cd6c850dfe014c8134f89504af51920953640e87d7c72727656f36c1fb4fe7fa989fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ef60864f4a4b4d2c0645341fc18bd03df5fbf7ab00d06a0ad743faafbd86793c6bf98ba6179ca44d8cd5548bb442c300000000000000000000000000000000089da90f8b003f5df8963a246590b49a7de2c5fcd99c04605d61b0c255c929d1d2f52b355210939cdf996a1dc58135441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b13c66260333c1c802de032f3d6f242937a2f244ccd133724145c60e06e8abbb3d3d4acfc155dabdac3d8070a18e96200000000000000000000000000000000113916c9b5b685c85acda28aa0764a698912267b80e294924cb88557de710a58ae016cb5c1c72dc144ab3addc82197b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce959f5775cb29a32cc75e48c570dc76b93faca72ca6248dff520a9157c7c99475b278b4989fb344748eb3b44fa4976000000000000000000000000000000001516c2e0984bea90edaf24897cba7e3b843912c83bbc565216b592c626dc061f27a5c93018519cfbd38f902388fe07311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d7013ae671d60c2d6585faca68745cdf19630088b2cedf62eb5882eef6e70c6f53bec7ef760d3a1151daf33906af010000000000000000000000000000000005f32df06ab2eb0671d07dda2c3086d1fd78bbd26fbb2a8065717c4080d0f7224473987eaf8bce52fc52092e639402c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b79efddf383b6360307f10cb8fc59a0bbe2fe2a0df9f83193473ac050c850b749fd59223aaae8e904d34c1016e6621000000000000000000000000000000000695fb2acfdbbb2155811c0be831b18fdadf23e3327793255833a2afe005f10aa0c440ce361be5828fba939bb878af291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d14754af415218c285df7c33f42ecdb176bc246236dbf217fffa21a6c8e01df19c55b979c2c9840551cdae5af603be000000000000000000000000000000001262ac8f0ef308102969d8b6aca662d3e8d2ff45ea11539b348bf1f5bbcc69d1a99cb1823b10ba8c28888bacc980278a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016284179b880e1e08315f169460d49774254181a18c00b73844c26d51d80d8a9a22b818a6714649585d718ded941ba4f000000000000000000000000000000000f798ae360bfffea73094028c39fff1eb2548ae60381d7be6565e56270d90352325b660d5d8c736d5b75a4d531bcd3821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154fd46adebede4e361ef31aec505fa418e6f058c916b0feb74bdcdd61612386679f0236602e0bfcc1c71be5855b7c0b0000000000000000000000000000000006994b386832e7cbf95a47ddaa6b86c7d73ea25b137a435a9fce36d5b8ce9603ca21652e21cf21f77e20cca5549efc581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dd9bd4d9ac6f25ebc95aec597a6e51c4d76a18bbee3a70fe710f228f7193b797752c0f2329095e2e212c4db3f08d970000000000000000000000000000000014ea3262729837dd8cf09983549fb7836d0cbdbd737e8ff15bdd79353a6f2951dce30f5dc9cea87878e94c19407630871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109934baff95dacf4cf92bcaea56426a732391b0c0a36ba481367e832729c58558afb9a15391efade82d4121397fb2240000000000000000000000000000000013cdf5d0828341d1e25cf287866d773d087c26208205fcd4edd32aa66682613e4c0c7f83ee5fb11261852c05463e0f8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176a689450ecb6a5c48bed8ec4bc6bc63020edb2162c6df2f32d4e2e33188259b03d77aeb543c6e463e0fcf5f43942020000000000000000000000000000000014032970f4e8a2d9af7353cc93a3f0522e90f8fd9d4fdd50b1581295d00899ffe953d009b153647e42674b094cbcd0251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176b9300935c4cabefcf6b46ac2617ce29a321b4e1a62794af7d9709d9d5d8e8a409874bdf71adcfee4a637090dad504000000000000000000000000000000000924478019fd8cfd8c6630a51e25ab6cda3668839a112e1f839766a097ee8207829ff0a410d49d8c3bef235cd3ed787b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c2df58e5aa40ad9d5e96c4505df7904213106a88c386fbd34f994fad8227622a244896011acc1de0a536b14d5684fb00000000000000000000000000000000184c323f04c0beb118d036b1f4b3c79f9e9a5287fc79e2453838f5b71330bc68748fcc7f07deaa04c6682626546367ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a4f1622be1fb32ef380e1b1b4199e5cdceb9ffdb3d9c1778df6f9c214ee079d528621eb7f444fc1b30ecaad1e4ec35000000000000000000000000000000001395a99545c848827d76ac1ae0cc3a0f97ef81720ae11c17e5a1469567df87012bac79b4af1b3ca38914060e4cb1ad4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124699eeedbdf20ace526f6254beed8dda7fc95ef4898b10c66db6a1ca351597442bf27bdccf9d9eb48dad59b48d118f00000000000000000000000000000000125a0c19547e42b62a0a710c3a0f91354e0dab66a19c988e6c2784b12b8eec76a11235320511820672133b4f3b43607d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d0ff0ff3d2c61da49a23246d9a43c2fe3d676177597a9a998cd3f1c8e700d9400fee9f79be8e5d40c7de1ccaef5c52000000000000000000000000000000000d13d47a19880b7cb26cf89437350e302b7285999901c53df3071583d7bf0b2ea328a3b67a2af5f869a068fbb375dfde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032945dd4df0b78a591b6497423ad871e203440527ded4c37d981d72df90e8c345561213c662e9f2ab19fd3c1de307aa00000000000000000000000000000000179a700329a81e49e16025407ab09616e71d8194ae99168bcaada304d1d58d1f4013f2bc5204e8f110c0cdcfccd63d6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d82a637559aee20f8728c894000b4369a1c90487fa29a40099e92b3032135d10abdd768bb132941de6e776472002e300000000000000000000000000000000163bb573c0b1a3415dbb0bce0424df75d72332e93c9017b47faa3932f3679775f8e08b7001c3805cd9675228f5d7032f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167183a84509bc6bb1aae22c507b0de870bf199e58aedfe2a9ca9f3f6c07f84b18f9b8ed252327a0915e2cb3355db5b70000000000000000000000000000000009401cd9ddc828051d78dcdae3864650d4dee7352124150a3011d4b18334563f859f3d275e43f1d1385c258b3a9e05e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d4d23d581e117e0452099752c114e3a3c38abbbcd22251933d6c10aab8cbc9f00e257e75518e972c98b4a2e497b21300000000000000000000000000000000134660daeaaf0e47ddf44f9c239f94a341697411e7bfce9970d924d7f47ce870440aaff6915fff1206d65bab3feee4101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bac3231d663c7e511ae24bf298c2024d90f377b43d64a183c12f8c42a055a5f6c806e8f219f705cefa62aca0d332ab40000000000000000000000000000000019fb4f8cca6b29178fecd4abb4be9c459fb5378d3b2a4131c0df364ec997fefabb974e0102e8f9e074bfba7e740b72141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2f001b75628aa50824737442b2c9e40e7f349861dea93070397f933c758efab9f23c1c0aaaa9b3b09c02fa727d05080000000000000000000000000000000006b0ae70c498cb11698014ddce164807f2881ec3a91456c6c1878d5579717bdec1d7900adf6f730af4c5b718824325141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f9193a4fc1cbb0a2f91adcc4f3aec2b0ad2c9c374d1dfb37c25232a8be56f4d27c846674148142b3c25dc0bb7456f200000000000000000000000000000000091d3665e27165a961a0cbbcd05a4d0a76f1f8e0484004b48d48352e616d60426625527e0682f119cf0765264d2c8f2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6040c77a6099d2c656e113ef9eae784a6ff8aecdb0dd3422cc96f08c79714d86e090676072fb7880f8db3a19e105700000000000000000000000000000000018f42b2f6579ab8641c44ac2d80f35261e4f33452e2c26e789a9f7335e892e469530e856e4b56736287fb7dd3a86f6481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001025a2a0e6e7c6dbea85d133e7f7957a1161cfe0c3ca6093d4f4dd469a0afb4cc24270c878a48a3a7bbf53229a7509060000000000000000000000000000000005a0b6079465da587de94f9b77d908bb30d8ad6db876f787e171a26fc4c9d32b765dd546c57e106420ea9f0cbb82e3ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a961fc66feffb93ca228fcf7cffb9f5d67395089cbf41b66abd82f0272ac593500c91550b918a46106149b9b23de5480000000000000000000000000000000014d65e58b6044c85846cf500b3c848f2d8a4dcaa289efe721ddcafb9b43d18780add9da5e3119d2794144d87d5d65c491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007260786620db1781c952652e41cedb08248bb3435029b21f0ff18a059d4bb33f3e95b02360eb465d0b8ad65364f6a86000000000000000000000000000000000021056eae46876032568df9bad77563d0af8a93c246fdd81939e4caadda28c907d117ecadf5a5c28a16ea10689c92171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eaf228203e88a7cb20cfd33e6df7a7d27360b28e5252545766e1f6057a427afeb04cc3d6e54c68d4a8d16c2c5d39c5a00000000000000000000000000000000192b11fc12edaa22227046382a5b175da2807fc9800b4d3a48985fcdfeb3bdd925b6dd802dfc78e03c58326a9dcc1e3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197f5e12269c2ca204958f523cab81fe2201a913b228db65a8119db403c3c8de6251c53bac2aa28f59849ce5e22ea2d20000000000000000000000000000000008fc2ea559ae7f8d477c09968dc0a8518dbe220fa4b5b4d23a6edf77b0c58c8caf36339854337ff1138fb0ff272a684e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083d98e47f0e06772a8a30043c675f81aeabfbcfc0e796e7a3692a3cfd4a509212da826ad7b8a611753e18d21ae4a838000000000000000000000000000000001680ab3c7a1050099e5c356809c5c789594dad01ccbdc0f5aba886118fb951ff3586beceed4a547dce97abe17b0f50bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b843f3795eb1607e9ae75523734f419d305317b1b9bbcd086721a983762e86d0c03f143714847d1b8b8a9903abe55c00000000000000000000000000000000067a17939ea352f88cde5c55006d513eeceb140ab93c26239f52a5e38ca5fea5ea79eb361a8a88b4583558a05bde0a661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e5c3ae9ff09d628e73a8456841bd78a455bf0c9fd4bc3d6b156380b2f60f1bac3cbe295217851591ef77f3c2286dc30000000000000000000000000000000016dc5713cdeef34f1be00c55788ceccd28d6d4e96f208ab2be2725eb26db55ee86984d0b13be20da2dec3eb3d66d22c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079628e0c0a804e98f4b614000dfe2c8d928c3d2a81d1080fe0708d43427721f006d41c30d235fd5c7b9cd840d4f586e000000000000000000000000000000000262c752601fac3faf8a5b912136795d86a0bf2d925eda9d8b5191721fe5f025eb82673643114c6af8fa5ff2e1e39c1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019fc05759a65e865c6830aefd749c41a4da41217cd1f1f12c8ed0631d87bd3361ac66bbee5f245572aca05f103cf08b00000000000000000000000000000000135a7e24a0459d43c011f2f28723f3bd6fb3a941653bb8e2fed63198fea31b3788b71a6a54bd704254452654913e56671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100bc109e397ce813adfd5e84096642aa8676264527f70d911d4268f28c07a340e16947f1d547f6d94a03bfc560104bb0000000000000000000000000000000014f872ab7890121018289adff4bcf9d2506227edc4f306f301eef95ae3281d851d4339cf8d04447fcec9c33b0fa49d481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b4f6a57eed3dc147fb54ddd5da3ce00ae476f2798e7f1804abc714b6e049bb32aed30bba5a6cae452dc07a1bd657740000000000000000000000000000000003dea4a75ed07f12b51b1d0122650f903b174be68bc04dd9d75a1faa62522fb2ae61ef2d74b5a4a5b9271665ad1c4d051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001102a48bdcd0d19659fcdf51c192f1aa8ae9dc3560b0e705a934c6cbefd8f298b36142eed377aa4d4c76111004c059100000000000000000000000000000000007bbf83d19c0bd4617b89d4bdf697c26c8fa6a159510cfaef9acd399fc18ef93e8397af9c07bd6502389082b2603b4a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001505408d585f287714d93f7b3106ec74fdeaca1748aa28ba0db788e377489b859068fe858d02a13cf1a97c902b6551100000000000000000000000000000000151fd7b1e8320fcaa9aeb963765121173179b67b711da8f26d76e5f663eb9a997cc3c5bbd6a73fc9ac6c02179061f6421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fcf8f4828c2a94f384d277e60ef8f678b4fa37a5617d9ba94962851a0701f22c887560a2ef53c362f48a8483c4c7e40000000000000000000000000000000019613f6a81ca13b1caef16050f368aabeecfe837a8991855f9f0f1a1e280ceccfc0c9106a225a4a2a30f0445ca1556531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8c566d1a302dfb6e2be730c2b4bb665a7f6c9f034c62b7fbe0a5b01caaa8c14eedb6aa0695ca3ee2e4407ff648e3f00000000000000000000000000000000003bf037b5322dd80e1d0776aa371f006adf30cc84d04bedac51a6b6519a104605d97a0e0c2eb0d2115a6b352466ee2881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f0bc4548a92e7cacde86faed9d6b217e33c116d9c051ae67a65343573fa3b87a0b27fe31d0c98eab7eb68abdd9393d00000000000000000000000000000000004b2749df919104ac6c553641ee1f86092bdcd3f7c07df6c13655b78d1dbec685b3fb62014b7c12a8b8b05b5143c7491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d709a7ab1a9e35c381cafaa2f1452bc6896a26d2e9969b39ffbf81024c42eaba769a028ff2ad2de0aab544e61eedb100000000000000000000000000000000007c703ae78bf8fc80e860ea804e58e7b828d8cdc3eea2a2eef85b0708bd5ffb6b6026d1806227f58e7badad2969c76501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134667d45b0ee37cb354ef27c73ffa5b66b1113db69590f24ee1c1533e79be9b33aaa7f4179cc21ec8e2e2800bd78e45000000000000000000000000000000000986f4ca56b08606dd7118600a618904a6b89041404eac0a198adf9d31c4aa5591b9f9c5ec8f0569523b64787440a8ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019155b09b3e8169272b5291062d13f353dced086e78b524e8068dd048b36d05e408a90016ec0ed803288152920aa050000000000000000000000000000000000103765755b359fefbf130b61c8a129dbc39082627a6db013f4b6e7b4ae6a3ae8af6059b45dbd5d6e6a4d8bd1f8aa32981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011dff77e842c8700d082f7df69e3257315c13260be1d42e3d81741a3b3e5595e73cb4c66a52362e69f70b91b475b27680000000000000000000000000000000003c936edee5bfca30a0738e344993be1072ed30135b18de6f7b622a8ca5cb05635c54ef16a05ebf3ce3cd1d4c40258641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aa88e710f0365a87180019f3fb321fee4de04f33a902cf05db964ed398d2f89e7b0aeea3284bbacfb6f9e7ce3f33cd000000000000000000000000000000001490f3605639a747d9a6969e325e96ae19fb7f4f15279e9a6df0d13fcd548b7b283611e915cd1627e4006c02f4bb1f551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2257e517b472d41c89b334319428bd68cbab0118ee1bb263324b8c3ad29bce2385565aeccca87ac97378ef6fb9c59c0000000000000000000000000000000006aec4d628bd073304cf87a7f1e6d26b02ea28caa8020af95bc67706eb0e541c05e02416f285061aee86f59c1f96f05f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eca502344dfbe58cbae2f146dd5840d934549f3ddbb9df5907a06a0bf590958bcf9dc28c1cb77cd6c8f9de9bb0007e100000000000000000000000000000000197e889f4705b35f527a9b89cab29cfeb99ccf960aa33e97b3f0a4f9107ff52500cec10cb13dae7f2b37bba2106594ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e9fd37414c0d9e7dc654d8138bd3fef399eb51a5fdec7ee5803faf8187fa23d65d3500bf988dad4e1676a06053a4630000000000000000000000000000000004a8a2e8a6b07bacb46b7d9204a3f9ce10f252bf70ac1721f2a839ec32b1432788e11882215875b36831bb64a067b8f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056468eeda5c3cdb901732ee682ddc325c986dfcd8ca86b1ed949d6eb6cbd40bf6c9958ff9ea0058e9a247e6b3ea8918000000000000000000000000000000000b51b37005bd0f0776aab2151f09de1a27e50d0c4419fc78f0ccc14990abb6438ce274cd7528bc7ec6c2c7619cf5ec4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b6e9c6db3aa48554210bc926b0c8c69b184caeefd1a802e50e0b1d0233876dfbf3ded220c0e80a5b43e9278d50487e00000000000000000000000000000000055f1099c5e825f9300c94a4f23a9532f8b18f138cf1cf7568dd7190bf271b9e195b1643ba9895a0c6215ab5f55df2891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011866e5371449139ec5ce6136d5611a9dbb975a8906d6d98b9893794af41f2edf6a2a24e2da7b67fa708f99689201c68000000000000000000000000000000001179c17f2d8a1c9b943e924f6f82b5028eb20bc02ca43e0760405211464ef5bab3ca183adea1fb391f896b91bd61b9c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ec2d9d849ecb33e6b84f03d9b7b00c4b17175d84506439ea1c03de626a8c41f83ae8b35a05f278f80c4416cfc2036b000000000000000000000000000000000ccd841790bb65d9b0277e935a38340317786d18511bea4997eb0c11de2f75d31240fa429f4ed73a20ead3986c04ed941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013675a7eed551d195c07af4301d5a41782d844acb1cd4596a1303af719cee79d0d6a7fbc5f93846b3c7a68a604101f600000000000000000000000000000000017743c4f79cf7836ee42808b978d97b0a88b758e9b32a7b0bc5a1e575a25cad6dcba2acf2b5927f11bc303a471084ba01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa73bc4535bab1a05d478b6a65d9d90fbf446beb4d1401d10cfd8e468f737a18222e0a0e524537fccbf73536f938732000000000000000000000000000000000852e15ebddd659575ef192a8b3a6c80b6afe627b47cd8494c66a6fc8b79c4258e332f6c514c421810ddf628f67be5121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000304298e645f19640ad6b07b863b0278802b190fd2120935bb4edc9198405a235f9cf42287975142cd89dbb56eb8d6450000000000000000000000000000000006d3ff4ff8f9dbe1e2bcf42ca445992b229097859496feebceb7520b6d8c6e6478c99f0ead2e40c55b1c59ac38f813151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f90cc9b70538dc1e1ac84e8a575414b8f307f3a006f9d6891b54147fdaf7036c0764d5c55ffc2263e8afa791d14efc000000000000000000000000000000000cf3d03dd6ab07ede83e2362db3f4662d7fc51ca515b9e22d38d7d53f6fb76e207f18fd4e97387ef55213b2763ab31141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b01c7b82d487ad4413dfee72822f1033e222ad8af3bea969dca56be7c2d83a0956f76a633cfbb9e8acea00bd3674d00000000000000000000000000000000013b14899f5a86cef5f34931b710350bc3488aacfcc53b874fe5090246a2eeac9d1a4b3a24df26232ed6f4dddb037848e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f0ac2cc0855d7e71583ffda042bb5913394f48a0c12d98f475d22e94882ad7ca6c699b212091733ec6ed9edc22331c0000000000000000000000000000000019dd3c8096e6b7e7956f877f7a173567dfec34cd1372d62d73ef50f47dcff0453beea54d0d408289f4c63e109d95ba141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153c613da8ab42bc18f58b95c2872e38a83f612d86c2f34c4212f68628d57bcc44e65431a754179dcdd2577751974f980000000000000000000000000000000003e3d7b8a78f2959ff0a95ab333c0606366fdc15b76a0f9a558850ba170ded891873802445c4519388b9961382d356cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ab1c6c8e5ee87364d8f88ccc2dd8ed3e5b367d81b4a86f10d7c7204fbf675cb6bc8d1ac50c336e09f9ce00305a1653000000000000000000000000000000000e4ed2c26ff4bfce1995eff736c2d0372995135e01d11fe0ab16b8983bb3929ba9cd31d161da4093536be757deb080381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043c2964ab368bccf3125586702619c2980579bb4e645aeb91bc438736b9e1863a67b43557daef3a1e28f391b76ddc370000000000000000000000000000000003f1a1892aa164a1d35be30baa7308672ae8d7591f00245991926e2b9fa108b2a35b1290a3bc815990c9ba8d7f2d6f461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018201db5729d940f1001f65e509ff84218a8f18c23c1e956a18b5d94198e7f91d15a03de584a7be5355943b5366d558d00000000000000000000000000000000118aed76f6871c38f3ce7784d7c0c0d5bcfe9cb56ebf49b7f3250c173b3cefd354d8c8c3b7f587cd37f0dbfbc6db384f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017749c5a65ebf7d6f2ffe5922dd3d65d8ccdd01fc0fd0982ad82f1539c95d2a43c308d748277a84febb89dd6168de240000000000000000000000000000000000ac76fec61e2b5cf1b8686c89962f46338b343b86a4e8c73ddae425990f3f6d1f461ed220b4b62a8528311b50b4f3c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f62331d2267b2212462c11bf2c7185b46eaebfbf159d799097bd545215592d3e20b1d99ace56f9239c37cf60887da00000000000000000000000000000000011786f28d2ddf291490ee11432aa33daea7fe558e33b0ae7783c9ac606e0e79fcc9b147bda9468800b78d6a775c2f4d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a481a2a3a5a0ce05a1fd64576d844d05f7d621a43ba9da46e4516ec63f95de4876beeeeeb3cbfdfda57a3b7eb9d713d00000000000000000000000000000000085cf5f5c59f675deede80f60f2dcfd1390996481f0a9321fb02f1732bcb60d72a821969ef53fe0b60d43cdf3eae41121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040e4fe640c8fc4db159272baec4f2815630fa77c8123e6dac95bffc6187c7106c25c3d36cc97d0ce3234c548ea0eb0d0000000000000000000000000000000018cf0d4086ed624618ae2abcd2dd66e5b664097d0eff57251dd3e1277bb4359679784f8c4c6b25d6e01cc2a330df4d7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d43f713a9f67dc170c504bb13f2c5967fe12482ed296ef09ceed819d5a652429e096905a29d73ca9fe9bbc8d9ecbabd0000000000000000000000000000000011e63fcb13e7a18a941465b1a0e4ce7e3f92a41fa83a4334a729c1cc2ab8b04c1d8e3186f6bcac8ebdab9fc54a8a63ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e518f402026bd1923f210e14bfacc55f8af8ff6360f174c12ab18af7bbd343e6ed2f59849c371ec1a3df3efb80ee1900000000000000000000000000000000168a0ba2fdbdb6309d7300c43be81f6924cba902635532ff0709d4c103ae04566d45945c0c775d93e178cf2cbbc2e0c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000491e9d9ebc43b16b0f3624c2023ed584ac67b1135704b77de4b337f3fbb53f5ff83c16d664b8e28f2a5952ea375765200000000000000000000000000000000121d9f926504a8d806eaa9ac921acb53bff7830c56c882a9efd94d5324d2f372be98b9ce61e4ba3674da09bcc2e7aa411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000120a3d1e261e9dfb91c54b1d1d342b190b1501b914e089c770377564f520cca50ed34958993947c1b3f1daeb6435d8d0000000000000000000000000000000004f05424238adde2374a73ae618ea738ffffe36acc9ebe17821fbec914ec5f129d2a6aa1a0e4a643fd6ab67883638ee41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000608182e6d48b7f8ff5221cdf5df561703c2fad686da44efbd9d4489399c10d32d8678b879737500ca3c2a6962313d800000000000000000000000000000000099ab9ce92786af80132465fd1b09c5f9aa00e5137c5182dfedb7c284f08d9d755c833b377a4e353f4665df21a02fad21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117e6f9c26779f4b789dddcc5710640f269302baa0530a90a0226ab647961d4cc201188a9b1fa0c0f1f13081ba7f4ce90000000000000000000000000000000008e0715ff3c9cb350c1c8bf7846ac495f5f65194f2299ee2791b28e1783fb14e499a43c5a84176549307b221d628f8301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001795d91318d488f7f0b5f17070485e7001197f95a1685920cd5dc2c12fb6c8faba48aca95bc4cfebd59640232dd75d580000000000000000000000000000000016d9d911535082a282d41a087984c034ed2d061b8ed33dae3d379ecb4316e04be57273dacf5937e988cad84827bf22cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e85b0197dd3b33e247ce9f3381fda91b035f2fb73249de8fd1a15b316d1eb92d12a1fdb0dca9854b077c2f63fa5f9200000000000000000000000000000000041b687fd04bce8225dad41c9f5e431afa562c07730939d4a05ad02464fff26d538c702dda6ce235ef0cdda303d044c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f67f536339f48878ff73c0d74fbe020815312a88fba65e98409edb0fcf87c6c49df95c01aab4f64f451f2e7f73259f0000000000000000000000000000000009e3a7aaeb55572d0592dd86d52b71d60d1caf98207511f2c8d7ef70032976a9998e220daebebb59fbc58b5bbb9e48bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136d49b5c53ba13ba8d4979a548f0e3ad72d2401b8a287c8ef40f5a6c80842e2b1c5e11379efbecfabd6e76c552aa97d00000000000000000000000000000000039ccb40325c08ac5a56677b497e9e5a289971fd15a76da80bccaa8d10a8b39d8432437788b009119b6a0ed3081d6cee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b1577a85cb87cfa9b3fd757a728a151005527c227adedfa792fece5df93b7f0f26ab8317cbaf8710626e0e7835518c0000000000000000000000000000000016aaf8d979bd0d1d8239cda831aa9eba553f22490d3f167fe8d61ea24fe58e6a451fb4a0762747803f55f5a77aa66f3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b52e671feba534926fb9d9daa7d72d4c8fb9ec5f9f0a4cabd7dce41b11a23459a65feac65825be57049b026f0be8290000000000000000000000000000000000885c5dd6ba7b328fe13c17384b54e41aa8af832d380fd5b5c1aa3dd8dfb354eb9c53b4c3d46969bbfb1a1f7bb78fa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ccb0ad92eee61bb59a9fb0bd6068bea9a3255eeb18f3ddf93b597a655e189b59b8d8ef6d21e42b7756dd96fc2e2a6d000000000000000000000000000000000a72c6cb9cd6d549224440b0479ee49a391a2e31a55f567e5a739d814b0dfeec5a79db6068695455a942bbb8c84331b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018684860dd8a83c505e69adc5724c25397aec2dd73714d211df1c891a2af074cea229fac76e91baf3fe7fac6d4ff55770000000000000000000000000000000015e7c017af76c941684411091908c63b566aee9dd47c71da1170ef2826c9441d24b675fefcb529abd712e717e1684a5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037d4341041bd91c93180523d83f8b785c9e2616faf41e97fdf48b22524b4525eeb6e1def30343d5fbca577bbcbaa13c0000000000000000000000000000000007111b3bb6c5dbb99d93a1df9789bf2b8122598aca78b9f7b010f94f5676780299280b9eb59e7145b7af85c19ee2331c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168cfbb62e1f747d67b45e6671f5a2dd60ce1c12a1f5e17f9eddb16105ed3196faa252a36ce5452fea3afe9a5a524f9a000000000000000000000000000000001094cc1cbd3381a6828b4ae641c1d8922fc96ace1ed08f3d9b5f777ae2df106089d5d211aa61afe2792fccd8d2fec55c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000011b59b33b90ebb180d1c9a4a1f575751c93b3a34497c0b4db65cccbdaa39cd0f49839779e837d65030de0e37351f6400000000000000000000000000000000013d14ced4cf59ff65f38a2d7d4b055b5329e1b8f79eb0b8795ec14cc65c351c930f85ff0b247496dca500cca147d78f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e4bdca95a46518fcd3a631951abb6dfd937e41718f93ccec35f8aabb765dea23ee082633a7fbf5690d954160b37db70000000000000000000000000000000000ec48cb7ff0ac797bbedde6635adeeefe0be0ec3067472c4d78f9482bd60055328b3214924052b924afe48b305221901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f8b7b922d0085ae8ee2ec577fd9e45c02f6208a6fd3bc4b4a3aac1ae3aea0012044f02dc7e592bf5eed9fcc7882c88000000000000000000000000000000001139eec2d41f669beac5bc249f5daf07a8e9543d5c663079d68a9efaa6707076d6a1661852dd0f55bd289bf642573ac81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126355ab6d40f2c192ead1cda9d5758089bf3697e1b167c344f5f3b18afe4c97bb87fbc15eac768eaab38bae53453cc7000000000000000000000000000000000d723b8a9703902d6762e538406be1e238e86602661b2a9e20d9105944a5e3253c720ace41dc150e36f6ba02aaf9751f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba5a37d98f9ae0e4fa81d4c1c3da1e9df589358d8330799d6a33f1f896823dbe9e34174726d74cda8d0bbfb57476baf00000000000000000000000000000000115cca57c86d8bffb547179536ed9e4e0b3df08e4efd0c3b80375088f7fc27b68b4a1eae1a2d28f71c3ff94b6e5e9f7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e8c942e597c9d9510259e8118ab35623dd994dde4a778f32714cbabfed9479fad9ea9881b9925e3330627ce61781e20000000000000000000000000000000000e2772a4176772898be703111ea7be07cf035c852299cdbad8f088123e1cabb58627e56915495c8a2966de239837f7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010de9e937b7aab8cff6bbdf969a4585304422d62c482487005af771b066da1d66564b9302a0f34224d51f9808a29ee92000000000000000000000000000000000da02a576f6896b6f244d8123a80e025a0705b8b837ee60177a60dacdc8108973e7885ea953a63cd426a1e20b1a27b4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001384031b0c47367e6ce851b2105a68d242b9f709b0a1b5f62df8e33619aa811a574f4f63f5bfb8ec98befcafd22ebd33000000000000000000000000000000000dd894072a2d3fe7e1d01f7048f394b2b8cd102b32108f5918fce9c36de3779cabb18da48c2284ce1f121c38aa3c3c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdc376148574e2afb2c77db4ad630c7b01266767852a6f6b6c2a7871e43678d7dd4a1fbaf7aead7aed7941d1241f36a0000000000000000000000000000000002fc06e129b3ef2a823bf042e5a73a5c0c886839f0eeca5583b867de96926fc2defbf2d8b344ed8273269047050685091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d4798604fb9b9f971c5d520ae4e5836b7789becc9e00e3094c4cda0598e9d2c6d64a78894cde5992c6775b1069f7c800000000000000000000000000000000038dda1cb2c6d566999a490ca855bd8e4e800149195bd8290aa947f7adb9c7642b8c2a1107e66176e393f62c5ef519951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002eafde67e5067a9fa0ff24e7d0427aff98f45ae3fbf9ac0e66cd7a29fef14fc787d4c7e54cdf290fde7c82edfdd06260000000000000000000000000000000008b795b1feb5b4a268cd28682dac5582639e037e6239cd17665aa559583aa14a1ce5a2801f0b86dd5b1965234f5095be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa9c5c827256e12840e06fa284b8385ab470a93d4bf74219cc1ad396411f4215135342aba52e590f1c6b52d347589f00000000000000000000000000000000010152439125202e0f7711400a55d947ae636245d3b8afb60876a1e0a72c69c39f06747ebd8e27604b621b5f8bc81f66e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f469cfd73a1d93a431a83181876d67074d1af0b0456d63a31ce70895c478a7f44426237ff1250f652565fd7d32b0db000000000000000000000000000000000ae7a7e99f2d3b48b51b5249e46c2ccf4e01a77516488f55cc4d7856772c1214aa7673d3d850505089d4248af3b518f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9c04b77c46891098535bef14dc0d3034912e19cf77c0f6c28165c529a0a594232fe4c0e21a36b0bbe7fd17fc298c990000000000000000000000000000000003f4ae3f9f7556f5f5f56ed4e3e78f3775f3a5e36c1f4db47704550d40b3b84299584cdfdcbb56fc8b3eaa9ff5097b601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c2a7289432ec5e79a4558645bc213072ef4949a17811a2eb1e90dce1dea8079ce389d0b50cef59be2dd5318b1858e60000000000000000000000000000000000701f6cfddfd1d68496c8063bb73e16266a250f1e2722faf95c261ecdfff33438646738e8c28bc136996489e22013801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020652f68c6494558533c1abed1087a5bc70120f2a57f4f8d0c7a2dfe4da4852b9d4b5d65cc49f520da2efdb0334a8740000000000000000000000000000000010fc81e44985a22084881d4f4e3547c2e261616331a7e0165c3e3d11b879ff2ce2fbdaa44268020e0ee0cb2fbcc272f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001333f633a5f60f4407f24d3bc351f5292f5d33fea7ecf01ff82872980fbc7650d2851cff83cf1af31b221d1888b43943000000000000000000000000000000001626408d253bc06e447fb4fd2a133c28a2618077c2c165de45d7b6b6d03c81e430d490ef1724e3a0492a7a00fc2cbcc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5b77c19ab18df72424fbbd4d2fbcee43424c27a2d927cb282e9d1a5b2ed7b69c0cf60c1abb1819e40a387d1206aad900000000000000000000000000000000067471803a7e73009ffd885515c8ef3db2e8d23280eeec84d5520b443acf9b44a31e92032c96cf5aa0c2e369c4fbcc391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004049f4b969ea678351b05f0aa4dfc20e20a215232b69fe6a05f733b08fa0431aa6f3d5ece61d07047582e89caee19810000000000000000000000000000000011a3e97f01244fb2a54c07389c3f8ddd5024d42a519b671f2d0fdb95ad003313edcc12982fcb08715a886a6845c86f1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e5b45f4770fcf4a4d5dc04fc00f587e720c0f0184c49c7cd0236009b4446f8378b83e6fdfdd571009751fe123d918b0000000000000000000000000000000004a6f103d678af9379e6b03d47b88f4d58e1bce0bdbdca67ac539b4acebce5a1d56cdef2ab6e74c2ddf652244f86077c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001688d72c07f3f67c64bc0f28e593bca09e792bbc453a34acb1bfe66d9cfe924176c6418b86684fefbf55af1a6801be3f0000000000000000000000000000000007d5ad12c260d7830c0652427f72b2a3756513fff4cdf491b1bf396045fbae36e2e3a9dc089757354880c67eba8db2cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1ea6565ac96c5dc137d3e9dea66b73b6b0962026900dc75312fc42121f0dd0b3ed8105a31daaaac2a099d02901a8750000000000000000000000000000000005ace1992ddda822827d29d99d8600ef0aad6e306eff2b52d8b8b66df3b6299e19b43abf331a81f55822b4e5c4621c5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce9cac0e5988a04d1d1b2ce2ce06136e86e46d6136180cfa8a44e7009453ebd6610e03a4ab28189bfc708e24ac9815700000000000000000000000000000000111a5c1cca8378fd16aa75fe6a117b335299cca6b79b47cdc19d91dc00b7dcf62b40eb609ccde47833113aaf651e4aba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155557470538b31f51b293a5552d635d26ed02e80c4f06113b2f46d20d91843c50e445315a657048e32a9f1f0b07938d0000000000000000000000000000000016f91d844ee427003f5d3ee766c8d23b91865cf0f67a541933ced2ef88e1250638a2c18d125912d9fda4060c481b35711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2c41f15333f54864792b5344caaf727c4183c3fcce547c322c9e5afccc19b8b4d1a3f55023066483769611f9a980d70000000000000000000000000000000000ee18470bf2676827e9fd037e4d76f5e51182f29bf74dbc3ccf05840db9ad8bd4a0679e8988dafc8a25e8ec0f366f961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081ba236786a55802562d5eb7e034988253a8a3e5dc8f2dda76e65172190189903387309dee12fa0ecb460eee5d7b879000000000000000000000000000000000ef242785e006a1f3361766b60d82ece2cb5fdce40ce0cb61e4fb4a3d74fdf12d5707292b2c9fd43eda88854f0b2c0861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003384ec8132ee04de514f6999b2385cbf93cafde4c2b39a56748ce67ca205641ff88974bdfc897e5179b9daab902653600000000000000000000000000000000022ea2e8d99d19273d0496fd46942d49bf4b2964c2aa0cb20d61ab78d9a6ef2fe4cbb31ac95c0d40e22f42305b8ea45d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd9c35a3209ae2240c85aa71b09e5c706bbe0b2fabd829abcffbec6bd49bf1f9228b7893e7c577d62f060627d470c2a000000000000000000000000000000000aed38d577b00bfdbc8f4c78b76fe76f161d3e56baa3cec08c9e19592b208ac93c113a08710d1df01095272b1c7874a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8d3f0f4ee6e6d5c7089eeed0387b51239ad74b3cdcbd2e18ad02434286647061f50ec168c063fa055edeeb8eb3f630000000000000000000000000000000005e204d847309137e256faf23388d2f225108fe9fc2741bd4ddbf452fa6b8fc61e0c1f8810fafdeb150b1e691e42d40b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b99158821f422add2795359efb2824a6d3fe459bb456857810210d9059bff4de6a1f1baab8598e1c05c2d50dee217600000000000000000000000000000000104ecb3e7b729e2dda53bc8de3b2cf33e5a7230da2e19fab4e3a4b8c442283c52038fc563e7f66bb9a3a231e3b2a062b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f40d22e3cee29341e91c936af304d08c5c16ad44d51d03cbc4e96492bf9567528ceb942a382600fcde3a950be68d790000000000000000000000000000000007ed795c876b31646eb45dc8c63ad974783fe0dcf4e0e8e9ee3cbf5a0287cac3787f0f1ecd94e8b4bb5e27361b3db4e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001156c741f39488e43e0d79d8284f72934995ee03fdbcbd033748235ca83b036599f0fea86548bf3343acdd07f360fdc2000000000000000000000000000000001720e2e70e708ce3e296684d584f277024edaddc1a8edbfdc6fb569d18c2648040798ebbf759c810c84a0eee8edf97061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4ab3ebf2811590a2caead3967b5d9970cb3459a4e8cc9b34db0c6654e7986d05176f97a34fe60b5096bed53c2a09a500000000000000000000000000000000171e05f29c47c3a95acc27422f1c997dd1570a3a3dd6b742d1de21ec33aebc718543db98ef46624d4231496bf67926001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000818b4603fe095ffbf063b214e19d065bc1441b535342714167de6f5a772ed98832e1f6e74e7ead657fd453aea96e893000000000000000000000000000000000b6fd6af91dec023287b8e3c15405ef54996c7d8f234770ccbb1ecee27c62bce3eeb72aa718ecaaad3f306aa3d2962f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001658d558e2b947cc6ca28cfa4acc21495f55108ef04cdc9ceafa7e82514332620d41bd6500ae8d284ef59f2e1792e22d0000000000000000000000000000000008b5949db1097a1f9676a151a08f902b3e27024b3d52ec8b0f7d25f75ba7036f56c11173149281ac775af7dc4a2916e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cb91664d01c41f36316814fcb35c8e50ade0160520a281eaa1c6853c7d5ca8cd0f525b350a91beff2470a0e5355e96000000000000000000000000000000000e1091bdd43ed58a2555ef53f8404792a6936d28c679ea9a3f2e30a6d5bf539551cab3a01f0982c33e8dab23703ed7a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000618ae8a3e503231c27a7dce860dfd06daa17f956bce449b8fb0b4cadeea37a64f8c145ae1c6058713dec0bf08b75b110000000000000000000000000000000013412c6e6e4362a1f6d5b154c4317d6b736d4599383f3c24bbc0df3a0048625f6c2aa3e009ca2ef3686b966fdd3921c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000265b744f5d43d68d863385ef43a875cb0f911959b47248f951d8bc22462a02528f586d81bebf84488dbff262ceb7b0b000000000000000000000000000000000bd0dadce86079bd92cf5afbac30b1b95456c906cb0852aa487a47a2fb67770755045da6fb7e2332b5c7d979e1b5a3af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e518a0114af9f6d2e82035af499dd6fe41a3d738cf6ff17d5b04cb585df5cda65aafe501218d362cdfc3043f871ad900000000000000000000000000000000120919f609d37d02f00eebb0afb3ce620dede7940358fc2fefb935c8fb4ee8c71b011b2c9ec582243830d508ac7406ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673b02fb6dd24f44ef89ccf533c778a38d8cecacb885750af6956b801aeb67cb55706b122e71483466a0607149dc92f000000000000000000000000000000000550f5b02c4efb8864eafe94b8790d83d85bbc6e4d22053c724e6ddafa3ad6da184c908fac5406570e88f8d67e9d4ed31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016abeef972685c1ecae4db5f0056771f2a66f8c14ee4a39cdbaed703d2d66c53589494b48fd858801de153777368cacd000000000000000000000000000000001535493b8edae5d2804ce0855d79c223b6499b831ee14b541a4099a387cf67ad21a26b5b004a2399836836e3d45843941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153ef01bacab389b8aca28bf5e46a8d4f33071feaaf397678c16cb09c1a1d97bebf7b384acd0360a5a570c3c378e5fa1000000000000000000000000000000001999106bb1a51013b256c0d27b5792c44c3d71e95c3ec5ee13f9630e6741ed502f3ba51879fc1a387a196de038d6eb821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0f193a09019d4e127d2d41d7202616ccc164cc831845c471e8b2becd9ddbd8193bbaa38845e276346988bf6c3238b9000000000000000000000000000000000b67a89aae818b1281b1586a57f02942dcbaa0c063e266def098bede46115cd513da7c65046155e32fa83d4ff8d2f4a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffd9488d7ec87c071c305091dd06da5166933535811d7e680fa1c1220c7e1acfc96c3a8887204ee69196e49fb65c5f2000000000000000000000000000000001771a88c07e0214f33986dfc627bacdd2b6c20cc9d54209a59fe98e568178b6e522990fa19c8cad30dc3960af40714831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c3941c3872ca141bc25fe8e414b6619dac5e5b1943deb8917cea3ba34e038fa05ac5e665f8f01dadf1f61c25baca1700000000000000000000000000000000156ce779a2c263ce7da9acf14632c21099571da31c77f9ecf62de839d17567f44d7be1a72e18ec8a9dd59b17390f6bb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca1b249e61571695c9c9f1de9fa513c99d094377a045045124ca58e4264a7bb087b6982cc610cad92ab66808eaa534c000000000000000000000000000000000bda0e5bafbcca8104eb7c9812b66a4a79ca0d58b2a5f54362a3e9ef76bddc79d0517292ea2dabf460782254cd920d1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fc737ebee4afe1373345a8d6952bad18d9da7b56c2f869e2d76b3008e411d3abbb1b7cbe0bc6bf7e140c0e63f686b9000000000000000000000000000000001016fc1189c7479e3fb028a71403722c179729b4a688f35d7c8f1f1496b334b244563e8c11725c6e4b670a4044ece2d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009786d244d5c8a447a82818e2b12d4d7f57891929fffca7aa1bc626685b196f2e37d4a86680e79d7ba76830ce22dc21f000000000000000000000000000000000b1334e1bd8eae00becb0a06e6a663be43863eea698e639753b67bebf9e5f8d8e3454c7eaede4e0e5051f8a90632537c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a4a0a370f5ca3dd0d2819bb73c64cda995c890cf09453b237cc7d6a55b9c67f71c7c196cf5b799c3979b4a0eb3b2aa000000000000000000000000000000000f522244a641c16f3de32fb56154bd335e6f2299cbeaf14b8cd15a89478e0f64e264a54a6fc6006003dc118edd1919ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd8b7469d3d36cc7ce0a8843d66de8e4c8f848b2e6c871231b8250870c3db66dcdc893ffbff709e2e9cca43bf893d9000000000000000000000000000000000063352165e6deb56acf2aebe8025e7c42d3eb47c53bfc6f38d89cea3d18cb84539ccb59799fa8cb3ea6189d8d085559f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5b6837b4047c3c3b9ad743c1f71f3787cbbd8cc274ea8dac3b1dda5abfeaf529eca830dc533a1db81e88621a2345eb000000000000000000000000000000000d0e03ca3767f3b54b7701163916f4f564d4eff4534f4722015f90fa2ef2c541863800446390154ddc83e64d8de0e9cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb2b9efca7044b1c2ed99393c5718ff1f9a7d4bd07d7d5e4694565359dd6db5fd6c8e5648f1cfec60587a20ea7012d4000000000000000000000000000000000456941d3a1b366e2d4e37a6bda52435eef8c165031d2152de2a0a7998218339b296da84717b0c6b83e8c8156d32a49a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012491b7bf68adfb7523bdf15e72d3b3a21f3638614d391e4d71a5478243312dbaf4d7975657426a1ad2534fe27b6eade00000000000000000000000000000000192f08f3cc9500e1c056bebd18909e76934aa9ea5ed8927f5725f5168c0ca3d11e46b33300e03c647f46ac59d5904fa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003deeb83083c9e24e4e455f14ed2378f67a9752f5140d4b374fbd56bccbc2e0a48a2d4a0c38c900756380ab958bb8532000000000000000000000000000000000d6e027d5b6445f1eb1cf658985191eb61828d05ca40cf939719f5f40076eb76a1ebf0b332f549d37c7abca6b5e12d441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f337852713fd09ec735da927a3fa478a32d5d8cca76b7ef363c2c708f217e536f74d51b0f0adac511d1cad84329194800000000000000000000000000000000011b6202c3bf97e4650e15771632a465d86f35780b255490be87300eef6eecc8c2937418eab1fc668d22fca8300f7dce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009d56932c3e4168c9e9d2b3af80f8e1b7b2463be720418d5f80a2702d1c65e409fe8d93fa0a10a0eb4ee7a707c5fd6100000000000000000000000000000000073581208ed579ce4d58ce90fd03e84228395e8dfaa8083fc83704d1e8da907d77582910aa9312517397e893b27b77321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124ecc7c91b111a7bb7fd42a9988da68448ded20837b6ee7813d220c8951752bb16b239cf9d13e580849bc949293bd530000000000000000000000000000000015c98b0504d6d8a88a953954bf4f4ee10d4e497ae07054f19af67defc06c0966bbc7b8f535407145533acd0a4a22ac7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014af136bc4e066ffd839853276adba657c9b67519ced82bf51695ecde8fcbb56610632edea3d0f3ecad30ba3ffa9ff2a0000000000000000000000000000000001ac938136f98de79d19587cc5f728fef35089cce55ba919ceda08166fcc6619d0d50c1440035ce608516601f893f9d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126bb9671e517267792dd4ed2243cd357703cc1629cb7bf08ef0d9ef8cd0175fe1495ad9cb8a090f89e0f98f95eb7b8b00000000000000000000000000000000089ff09b2748aa3c722fa744397ec470f5eac218e1e8b20538641c27924921a8de8b29ee560ad88f854e03595c99102e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000764a2a77904401f737762c762b06d26b08a235fb3796680a17ac003b2930d698bd9174ab119970decb7952d5ff4acce0000000000000000000000000000000005912d311d38341dde42f7403e7f7a6e2d7dc6e773dcad32b27dcb2e1d74256f6972eedecde900846951e4f2c249c3561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100381469eabe1327bd3298fd73abe89f7a77c1844f1ec3fe36b8b71b6fd58ab4c3eaf4eb7bbe356ccb6299086d31bd20000000000000000000000000000000018a1377c49e0f05f1ca89f6d483b474b6b77ece9d714ef8934d19535092da0da9b885f89fd6dad8d7b4a1af8a814455f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168fd4c7928724a6807a2c53a155c77c6008b9cc3691ba67ab6ee3e7478ccb8e61df4fbadcc5ff0dd4de09d84f60dac400000000000000000000000000000000078f1a5aa1522956ec82ff461e2b1c286b1587217ced3c88a70f269a19165d664f937390bf7be25037debe10390716e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e6a67526b8b74a4bc5aea67e179f7d16ac42c4c693a7bdcb1109e71cd960d10f18e4513015ab1f9e9cd55fb32e24e8000000000000000000000000000000000d3b19f7129006481b26c5b7d161cf9369a2bb93fa017a93d394c300b3d8ec20c1e5e53364b65984a12616ab1fc4917a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001922a38508a578d012db1c6863b03739e13c1da571213d92148f7605579a9e150c30a83cc514c1445c887610bf5252e80000000000000000000000000000000002cf9a4bb6bf9852bd58175b391e4a1c9dd6da027f404f8878da6a83f5fa0d7cbdcda03aa5444329333a268730955d271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4bbd4d0ac43bf6ddce5569ef9335ee428f366a8483c6ab339ec6c269bdee7acf3eb186c720be346e8584e2632b83570000000000000000000000000000000015eb237acd09dce01d17ea0c21cc66994eb42be77d38a5c07b84187b53d63c76a8b7d6dd4b821e90d35ba89e3bf6bda11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da3710be16aca675c2bf2aacd9ca0470948a960e059d74ad8b84e280fdd95c228541551aaea76335bc19333b92a116400000000000000000000000000000000119671acbfc39b553cb821c881bdd7f72f501bc4fb45e6bdb8dfec9e7517f6d9b3ada8793c06bad0dc6961dcf35ac84d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065f74559e1e24fbaec2c2b9b0dd123183c2462a448265b2731e2e0928a80602cb828832a1ba0025261dd1e3beacd5de000000000000000000000000000000000746ec52a802fc70614fa33623a07750ac300ecdc8043251968c6e6b4f0b49915d2596befe84058fe1708a96c6ce76be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001091932c74bc39089576ffd44f2f6a1c8bab022629986f67b8c022ad93d2a05c08641560d105d725556da7ad8e58c76a000000000000000000000000000000000a2cad59e673f2abf1c0ed2536c9b787131379ca5d55aa6625c8f5c8e73508524e07b4c5ab09dd28145980417f2e99bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187efd24effdfe761cf8b97742bafd1f41bd9dad678d2c3117c54b46f48388f9256eea89319a7f632f586c6f4927b29c000000000000000000000000000000000bd476a7804b3e43b68ec928f0e1faab4c5ef81496fc1c97d7edc7844fc1bf350e9499e09bc700aff0864d95aed371571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c1b27da1af76ece7e7e3e4e741b04803a098c0af9ae3310039a9276d6b35cea1594aee3db23863d9152debed6e45a3000000000000000000000000000000000ab7d2019417c48ce97e56817336a0608c459cc55d807197cf6a1e99ad8c63bce753b76d33623abf3d5b40475ca70f1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d465cab0cff80f17030671b0f543000d607e361a7edd48d92e5668173b2de628f3d8269425cfc3042893ab4f521d010000000000000000000000000000000003b3d4dc2f2158c4cb7850c5fc1a08c257e8e4257bbb2e601a6efa476248758a6b5358199c0218b50cf6e30bdc10cf5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ccc8e8af726afaf2944470f04c62015c362cff9b041bec0b9050dc27c53708dc72cd34b0b7856afa0489d074d8061d000000000000000000000000000000000c2c84ff780d135662f32dac3f21d428279660e56c64e9fbaac7e06c951ecc892eb431c0fed0047a8cf3a964ddddb3581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fe644f472ddec2f8de2d1a42775c50ff6535f2075072c6ca058a3d4a29e8b59fc1a0d823a23edf90c2af0a854253320000000000000000000000000000000019a9bfd071c81ab09e22dedca90567999c4322d99968b4cda602e4b914b1d45397832f6ccacd48e16dea96fb4d3b6f391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191e4c6dac139289a62ac28d1d044e40af53efc4e657d1777a36ebde3261da250516eb7708f1f52236794ab8b03c9ed600000000000000000000000000000000018d22c0bef069edabee7dc518cf596c02ea3289a896ebc96233e539b05feb9ddb6023fcfcf5ac0f04d24b198fd9e9571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea420a67fa3384c28e78455abc0ba28a1e2489ceef4ac82e68416411f55ddcc48c6fede3314d95f2e4fc73ff2a6b360000000000000000000000000000000001ac8de611fea805f10e544eb9eb6e63fa0d7e559d8a225ef1934114c5397b5e52e05defd4443f503ac2b804ce0b87c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161b3beb6f28b5b229927e0a37713dd499b7ca2851c9c0d95c7d3b4d83376fb0d747b80d8067c64f0c5b55f2452b84be0000000000000000000000000000000012af658c46a15139f36d4d5f25adc63dfaf5e77046ee868b4acb37da046c19a85497834d67c996c3cd427bb0b7fd3b5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001315b21c683bc730a0306ccab9310d8829737366db41011bac4d6bdff6228a5f61dff33f730348c2b9da6a16285e0a0d000000000000000000000000000000001170f50200394cbb53c8edbde2918555b6b5c8dfa8046e411b4b61cec988cc1f18ea9b8d9332cd5701ce42f631cf76b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014653176e3cce4dec0fad0c977757e070f013739a39a0bcb08823bfcdcfef05744585ea050107c5fac3c5e35005c09f0000000000000000000000000000000011457735dd2ddffac03f1e7f1a86067a7d979349fb67567d87c6f462b81c7593ca7d8c9c8d75a0e486777d7af05db3f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001da04b157962b502f738773bdc1f0390fffcb5cb05c2c18ad14e742954ce02500ff57877e25cfdec7f2f1b6844c42d000000000000000000000000000000000f7c97a711c5fb7670d61e2068b75753a5284b4e61770bea3a722bcc2e4f3393ae805517a7cbf8a60745b16a3cf50fc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ac7173e2271a6cc7dca6f1c80e77acf5953ed6ba59692ccc7766eda835e553df95ef71897b11cf29cfed191cd31b1b00000000000000000000000000000000158f732a9f2ba7fe3f054a0cf0bd50b06ac1115260cfdb1796a76fd630468fcb5acdd2cee4a064ebb672d9623bf517261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a75eba744d4b8b57c6effdd11cc722ad7a1a94f5aab609832390cefff2f6105e790837ac485ed339e2724a2ef8418b000000000000000000000000000000000fba023eb6ef6f757765dce72d18e204065ab137e48c9f2383088e626c9cd023a56dbd5afdc2ff492a1a9505f8c869e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007afce48c13014171e0dd9ce4fc6040cc420785a2e390fc58b79ada006c06421b1465e582a1d0f9029b441b1c10f2e7d000000000000000000000000000000000d4f3c17e6c6923624d887a5134495edd3f4d7e8bb6a82ff23dbf842f03d460fb4d71f584b8cf5be7fe06e8ea7b5851f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012235511341c1a6f326e85516f499f11dcb199efd33ba9af83b29858720f15e079ddaea88c2d0234a7a01b497ede511800000000000000000000000000000000199c7491ea10013f9277a840eaad1b00122740466db127715909c944ab70f364a6439f846458196c37d36a0478b3fe111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4e32e07b410c0d2d087363e55afe637734fc4ac624bc3531d56054d5161793e82bc7ed33c88327991e1a053f67b3ff00000000000000000000000000000000156c6c134393e1fbd9571fd2971bade2577fa2e9f38ba18f7706bf622d66f8e86cff0089ee49ed5c7fd9b01c22a5db591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cf179a94ca8f132fb7b103a3bb4caee3e29d608b16a303e32a9def5060fe030fa899220dc59e9316b8d099d2fe42bb000000000000000000000000000000000a5bee93c84159dc0ee62572e2a0868ad8a91e98e1992d1a393a4bf7c616683ae352c951a7c166633e1acea41b81d7171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006304a02c93f2419835cdb324b78719f3e62fca5cd0e366e5510d09ef1de1ed9ee9a0d4bee920671c4d1c91749b901910000000000000000000000000000000014f2ca64d0df7ee607bb8c39cabc811b84ba52afa8fde5070d78cd358784bd89ca307c2c1015fb57513f4918730c34b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ca8aad4f45fa6c6e4305b3008d966277117bb0b706154b640c5af1e5222b0391cdc8633b46731fe9b32ccae8088cef000000000000000000000000000000000e856f9efa65d3df3fa53365ec34d93046ab71e0f1246f8d7336d60ad6814cd7f5f3a8310cd5d1b894a4d81cdaf0bbfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b89b6e17b64f41f303055446d8e36cde67b33cfde98ab9ceb467366069423007ed17d6fe74f92d179bdf027c7c3039000000000000000000000000000000000c448267092f77dd005d1efb118e01dc4eb0aced975378f8b27add0914e3768092eeac8bcb13e667d977f190012edf7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f64a59f47f83e83408832d7cd277a78abfeda384c24f5b73604fd50a3ecbbc1b06c0217468d8d517171695dbc8537b000000000000000000000000000000000fc5ed81fc233f79c45da8f30af16faccb52ce2284d1a9e7de72d55663e147a0d0a7a641c7a6056a027150fed7b4e9791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e326a229b627999880ed1fa6dd20aad6d3652bf6ad9a0dac6a1c61b4b9b95092698bd491bd72a289bdff826499aa840000000000000000000000000000000011c9c349313ae92ef97167260e499c541176652bb5751e2a2e5a7739cd72507c09f94f02491d107ac781bee1169347531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013de445364ee9cb93adc419eef88c2b5dea831f655c0d3adc416925ad8f68f53a9d8877548b6807bdfd9a6388dcddcfa00000000000000000000000000000000096fd770f94c6475cdb51487da8e51c5023f040590bc6e9d19a54b747dbe8906a76e2b59b64fc2bfb2bd547356c464b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf1d4a18762878f1437c625785bd3342e9bd7bbc1f5eff961f13dfd0567dd29d3c43027c76d650cbd97ae2c11fa93ca0000000000000000000000000000000014f8be3c695584125937d54d58a67185d11a2d3092ed67f45167b09c4a2abd188b83ab0201971004aef4bcd1edaae48e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce05bfc73115713d5c33d9cfdaff819de53974305d860e79b7edb232a429621347e4bed057050c46978b80b3bbfc07e0000000000000000000000000000000002283c0a5e93e583a4d20fdb7d9820461eeb9804fd91f2107c78bf9af575125d930642fa76cab995b90670f524120f2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0ccbf45e16175a552e74010a5ab54af6bcb52478c4a1d7aa65e8bf7e240df856e7bf7cb1b88795417075a1cbc9ca4e0000000000000000000000000000000002a9e3f553de57a3ec13defbc8be91c153b74d22491cf2dcd92698f19cf4e9442cad1ac8d8be2793bfa71adf04a9c7811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001252fbc302c483efd300cd0fc4cba889eca8fc8ae329cf65b5f23d3623ba98b35ef7e167b31e0cb66b6ffd95c61a5b0d00000000000000000000000000000000118137f13f381e930a54b7f986c8b809b4e2b3add44a9b38314d66debb9c73cf55dcfcb6476c7d51d0b09e2dc911c2ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ba31716b261bcebab58dab2abf16aa35b0661a33298843b81ff38f600a632c82866b157bdc05e787c0caa1063fe5bb000000000000000000000000000000000d664bff23d5539d1fc378021f3bab203407ad30094a961b9aa21b9605f94ca8de9320a27946fa7c24f8e42e61fcd6201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011155b2240cb3a982fddee6e049bce6dfa00233f130dc55a57c1845b1d631ed5c0d40b06471461cec7266ba4bb78c1980000000000000000000000000000000011f35714f49747b0d5a5027c2e9d1dc632e2731b34742f5f216a9c967c10217b5e343a1682daf1b1aff45e445c56722a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f89a986e548a35e0c014755ed0a38325f9bcfdf4a74739cef09883345438c1d7d5b2ab5f6f792827d2e13fd7a7b0ddb000000000000000000000000000000000c44541a5b6fadb90bf5cc88ff053c10119867f99b44a2672997a570cf2c818a2e9967538bb509042b33830c1b5a64f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000551cf72244897c911f6cb7c1ba15dda34b10c974b8dfbf843fdf2a07c14404bac58f7ea552b4e0699ffbbfebe32dbf8000000000000000000000000000000000bc4bb1038e2171266d0ce5def581bbdae500819102725021397f4c03df816fc9b2d38988448d030c519fa45b0cbe70b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001824c5ea12c4b75d413b609469776423b26a75f559e44463535cecfe6fec469fa75fe8e9a437377bf1413a8aff70055f0000000000000000000000000000000010a0dead767f3ee1c22f8da401c7120c51a4947bdc350af8380b6fd679537ebaf718966b18664094c06d93b0f812ec261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001072719fc8cea906a0c4a79c9800f1b56493d57bec18bd9b963e5abec8200a4a8e0c8c02a194749f2326a495f128a9b00000000000000000000000000000000013418b76ed9da79c42349fa533e4560c67ab80706d9c84bf2c604e3cfce15e823eb03756e6577080575b94dc06864fd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c8bfa132fce79559be4132ebd735ab296c03702001ba85c234b4205e0c067da3ca3e7e20dfcdc3382ede048495d959000000000000000000000000000000000172f47d0f251daa4cf320b959b6276ca0add15ab1ce7fdb71b0d553eb167081cb5a00a64495e5c7579a1d764e56a47a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4732c1a10cc9f2d9911d029e4ef26db04c57c3d6151b73e633d2c95fdb3596fd665474128ef11b6237400816c2e12000000000000000000000000000000000055384e5e247ad359a7d46b2178460ab36edb9a959962927a3925ecb812cbf10e314f67464309a9dd361a99c46168c2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f796d028887fa5b3d4634d9e0bdb573b93ca936066e6f04b773bba53518ad30203eec1a6042936d071514e6bfa5f2920000000000000000000000000000000002fc62c26a7353b52db6b4b9a42d7c05d73b57ffaf3f30e3477f09570f53c493f547f5b6885e099259d1539792ce5d7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b8f2c5223f86c694ff7943775192b750a7649935f901c10fdb0dd5f7414bada981904d0c9bb4d46531e36d71bf753e000000000000000000000000000000000b536cff8477ccf93e45283cb63418d95312e2c0ec261c759a6b9f6c5d7d13fc398b432c859eccce89ac5b8c072f3b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011da94a5be90d556e5162cb3a1137fee28e589ce8e5a63a9e4eb107a83dd2e491b6da3f28057dd405d3405299089eceb0000000000000000000000000000000017df38816141a18bfa41aa6aae3eeacd8ac6531bea08179220b0823867149193334bce6cdd2984eb08a41efceb51b6f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b09ae260c192350741a8f8e6049746338ab6a808d580ead6c5f1cb92457289ba35c32a330abf9038fe015ee42c6d8800000000000000000000000000000000081a581b92f7e0b3ca6ad1cfa8d0a7daf32fdf7574dc59b4bac0d14174982860c960395a2aa070d466e7e6c7d1833e061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058a98eaaf21b149184b499044daf38760234ca5aa8b20036e39ad2936a80e71c352b1fd0b64a090b0e0764cc7d67da00000000000000000000000000000000010db0406de126e8e05dc07fc896c4b1d12a8ab336158e3b0636ff00b981656b9a39f0fd9b629b8109eb6911012b89eac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010201bb8d227c6985435a7c205768170c42422ce90016bc4b77390a3088e7de30ec7873a5642eeb87f908d86129113ce000000000000000000000000000000000b16ba2f42208ec8aeb80a7967f667f002a55272fa83b9be910fbc4b4974a273b4edf45887f1935209c026e44b3470e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001811c178195bdc73e7c33cd10f4a0fe8e41dfe230e334153950028fccf9ec804ccbd726990e7d6c5639552684c18bf320000000000000000000000000000000004ef8e3c72d14c79a226a8336f808c2b72c48d927907b732fd99f15072e3c81dd39a1dad5b0da1b2fce3adbd74bbcc9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003149736b1352b7e23226af2aedd449881fa5403a13e7649385032b030f9f715619862a9c2dd2f1eca777898b339d4900000000000000000000000000000000013a55a271fe5c02939758bcc631cb03e8c98a3e47c4a05df3e2822536538391dac611b77d5aa82b098774fa38e1666991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001314ce1ad8e1a3a35e50544a7ff3b9ef1eb6ea0193eeaa1d2968046b4f09f8086f3ff63c048753d20e30e9dd4272e827000000000000000000000000000000000cece16e82979dca32bf380982025270caf9ba81bcbe2c0b978063e7d6bcd1cc2d1b87d10711c25cdfe3399bf847f11f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b063dfb76ed32b09e807f17e347807c5e9b1408bbfe82c865e4013cd93b980e2e5afad45973cd865722e98e2b7483b00000000000000000000000000000000080833813b73cdb0984d33bd1d51266965cb951a5b2981c8b17155f867edb896d57dce1619646896e301a5f4846825ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043ed3a325a82269a3bb5ef98cb94f08e0e9b490bb408ab21fe305ae32dd75ebded16a0a5efb0a89eca8c6a0568e32110000000000000000000000000000000009f0592ff5d0929e65a1341fb5525e078a5319dc1d0e4e8b8e11751ce484a8b19acc9090c42ec46e6761db637857f8771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea3a4b87cc251ad311af3dd8db1d238052ea94651352c0093492e4ef57aecf21de575a37626e762d17378a3ce27d7be000000000000000000000000000000000141d0d51a2d50231f762b78ebac3c59857576927aea9a4bd3a302e4328362cc4b8f829792c5a818ca7e33434aa0a0c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c521d9fc7ca94945c5d9d8756f7ddff08f9d1ea012bfb77c3fd9f78fc30746738c196fe6f793d10ee06c552fa9c3912000000000000000000000000000000000d2abe395135a540564abc2ea1151923e13ea05d87840ecc9aa0cafaeb1209d8498d6eb024fbeca3276b478d41e45b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140e53c54c48b5e00134d8ae57af2cd5374a191df05f6248c2d51cb1a8630b86d070c2743a20cef26043ccba2943eb91000000000000000000000000000000000273be71d80d705c24217d2af91b69ced45a8abc17e67c76e2c370af5a05eaba9bd706421141bbfe7f44d47fd181ce591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111d6765dcaa2b9c539f5c9df1f727e41945f1a0c0394d2fd6daf799bc331a972e1a4d844b293da427adc1bb3fc9f36f000000000000000000000000000000000142b3d87e2b607919d6abdfa81efeeb3abd092eca502c18399a9b4205787c7003e9327f6fce1b85fe76fd5cab23cb7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000933c400fe9431ba93a3663e386b00dfd35a54b4faf339db14d4410fb0f3cd63aa9ac6580082e26a7f118512a8206f4800000000000000000000000000000000185cfedfbd48fdc163f854995737153eef4708601a1542773912680c9f1e264027c93cd137d0f767124e593acd4af2d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000762f284c082cea4262660a404614faf737d4d70dd7c270360888248c081a4090a4aad047143f84657ee321c65d065d60000000000000000000000000000000004be67e36ff93aedbc832f5d7809c7f6bb45293c5b953d25fa11ddf10f7bea99c1992c241c68a4dc51c3d4c0c1b7c9df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124611fbba211a186ecc58466173d5a219ce335cb4d239bb60873d10e982379b75cd9ed60b22dcb17e0aa4f2f0f53e2b000000000000000000000000000000000cd4951d1eff4ace94331303b93408e1689bd0c3c2a8439ffa8d1adbcead124b75576591cae7ea503d4b58f3a08bf8121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a506c0785857aa0acfc1c3b9a5cdf83a5d17e507f33b7a082adc5395baab436fe01a13f25e2f6c1be3553cfbc33031700000000000000000000000000000000150f07ea176aab73e149736edcc5d34d49400f6c57a37c599328ff822d74a9079b42ef33ae01219bf017f79c4308a1cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aa7bdf0a75e10c7211c155727326ac964af2484642138fbbddcafc6dbb5e617f8c659a2dc400526cc2481608565cc10000000000000000000000000000000011f74e59202b79c3c231b29695a841c9120f4dd68ce5864c5f4789c404aab8bf2e0c6e18c4abe2dfde5cdea50acff99c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174fb722dad03efcad8a91f4ad4ec8a7d577daeffbf724c281514ad1a331d3d650335357274a029492ad11efa294ac4d0000000000000000000000000000000009b13b6ffb6063a678c49cd4e1bddda88cff5dea88df40758aa0eccf95e46da50a22087c36dcd4a04e6547d7144e8b911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001348461ecf787f12563efe0cf0c1f5988f56b55fd13ac520f4acca53a2f9e19af4548e535500ad381dae30be60614c4d0000000000000000000000000000000011ea3931a1dc682177fe902c7858fa62ee9df7251a5c1b99796f33602520222cc87217b0f727bfbd93b6a3cd19e0ac391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152f2807a0007b494f8d734d8b3eef29385f274d040f725352be537339441f3040c12116b7a84e49ebbfff5e778507020000000000000000000000000000000005fbcc42a8f28c11281d481e9f804a58abf1920e1a65f159dc8fcd4934a2e041d3032e3a95d0c84dc51e0e11aae3fad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012be6c9ee0ca13b8a5447f45fbb006771862ec48f027dcc55fc15f62a7fcc240a303eea805aa52278fe4fd0e280f0a7f000000000000000000000000000000001644ef46d1e3eea8ea2bdd728ed91a0c660d0256d85859f32e6490c2f5449c03748905e1518b8384e3224f20d039bf7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a1b250d9c69ede6574fba8bf0472dde873048cf2bc38f695f29fd81dad746f095dd42e486037b8fa70d04b98e9488a00000000000000000000000000000000156a7087177469d649e33f8ae7541c27e90410b91f3680f858fa7c543e59c9e72c0d1146a1636ae839af1fe77b1cecb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000671f9c314b848b8469f4813bf60c76e13412436bd6f51ad653ecdd00cd248cfca02ad08d5273b2c31fca2fbd89e950e0000000000000000000000000000000017a4f7e5277cd5feb2bf4928e7b9505c1ad076042ee709dec892760e7b419f4362e62cd4d6188e99f7c3eaee3cabb09a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8ec3c28172c233c0b8738fc4b011b055709c9ce1be04fd77b996babf1755eb75233cddd67dda45f771bcba6b58c7ef000000000000000000000000000000000fd70a87c019125e0628c7b1165cdfdd3bd19405628cc7e8646d55c83a9b109aea563f5d8da21d47b0df8b0417cfa05e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025492fe97c73962b601cc101960b2c8320fed415266eda664ec550243943b45db460ec116e889b0f94196c31530a1840000000000000000000000000000000014dc3c680abeba696827c272ed9f04104348593297a58788e7198c004c3e8e43ba8a3df13c0c79273ac1387a1c60d0ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a755d2e452ef95db10d824feb95286f9123877bf61ef973e7abe85b682163829f78cfd738ebd9a8ad6688539e13235b0000000000000000000000000000000006427dc1402836734d528a8806a9d4188eaa051407a3ff35759ee17428a718f5c6f49c23388b892ef31cada19f272a0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b77275b7a6f7e11364b533db09d06a32e9c9da9026177d51f64735c2c56f72983853fde4c467b73ef105f3a5ae443a000000000000000000000000000000001307bac72e80b471fa4aa987291c58bce55c9a87dc891e201bcc51552df118012903187804e436dbf262ff3c998429d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003975a28d20f150b5401070cc89326906071d5e5eeeac33a6a5502637752f8269cf42ea144ec2341c22c70de24fd4b160000000000000000000000000000000002d3f2aabffd93f15fbe6094a5a49d8f92bc0971412dae7bb9e759460252cd70a206fd68391362e5f6630e139dc0541a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e207c190551cd071c020ad92b96a4f0b9be4fec42edb1b61ac03cfa097f675dde001bf600563a7af92803aa1fe83978000000000000000000000000000000000df65349b486a1942efef08e0abc980ec7def10cf0ec4ccffb495ccfd5d86d11abf5aff7a30ccf0632c740281c8ea64d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ca44f4ee0025619ffe68769ed7392449ec0be0481ec2c735060241b8cebf54db7c98af29a4eb61e370bf6707efb13c0000000000000000000000000000000007c9fd725796fec1df27b23feb78fb9499c97f452c65faae40900eef68348fb21c62f5c0d1f54c6fb444e7e37d5de21d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001731e86b057431215aec6e17f1b5175d8f0cd645392568f57fce45ee357ab6f98d3ac46b0b529e44d0450a82a3a24b0900000000000000000000000000000000133adec624a8e434c8a38e05888b7765c715f91c9312e976bc18aa6e633786d79ad2c37975feef494c6ae654c328eb2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e12bc922f44c44fa39c6df1e8b0f2a4029ed54eab8ad1787e27afe7a66a7964ab5a25346600d6debcd25fb18f9b2641000000000000000000000000000000000b3777d782f9671a93fe5ca28d5b36e4c2e6f241570334614058a31382d941a136fbfe9843e190b731ed19ec8bc648301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fb13aa6124d72667e54267d08ae2fbce363445aaacc5e5998e48a505c3e834c7dd1c183edb1e00997fed082bb169d4000000000000000000000000000000000b73b94cccbe87e5d25f4e94a2023c4149738ffddfcddd38524edffb6af321933d759f2087992ac7280fa0b73422056d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b480c3f10d980383d208d72b20eb9f49870b0c5a37c718768485c82dbe9e8a81e2b14ed542fd46239a28e38c65b480c0000000000000000000000000000000005696db865fb41ce037f4b414fe3634c61f50c5b9aebe36fb634d836dc61a7814169f6b642589d6522c0921014b980e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016397e2c6f2d0ab33736e8cea2ed87f5d565ca342602cf9ed3366245f4d8cee2a910bc0c3275f86fccb72a6b0eabcb110000000000000000000000000000000014feedc5e5cff755ed7eea591978df0d170eae3d0b86d646b2a8e72d46f59bdc07e788568f5f0cc461b898a8920c8ec41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132589a6a7938dea56b5a6b6e7b46dce23c0a33a8d1b9ef046e07416e1b4264f17868d86837bd1425d6598de4d49bb100000000000000000000000000000000012c1b6485b69b9fb385a7016023a40e166baaf89f4d466d698899228fea35c77039d47937dc086222177f4d54e32ac281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175d8758b3c28fefe3b34f46f5c25fa7567dadb691f1db89537fe456579e42c072c39efb1febb63a196543a9450b933000000000000000000000000000000000081d663d7eda00def9d8b1c2898f56c11581ccda4d39f6bd696f8ea99caa966943f38ecdaad7a40435d40d02162237f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149ebf3e20f69f49a195cd0cf6f28b0e25a26923d94713b434c2c0265ff10e54a729ef6caf3713477f8da497e6e210720000000000000000000000000000000004f05396f703d55de60bc31fa7ab97ebb199315275833fb9415c4ea122f914eb906b46d65e294a5a8a247a7401eaec321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027126bd7d94e91ac30f9f9b9a5096d1761f1edbc6d4d5721138238ad3ed1877f6fd6feae4a67efdd16b000dd04248d700000000000000000000000000000000094d4508eae7dbe0ada5c6774a9f5ca2b9795734fd5137845232248e9cf51c6e3171bb0db255bf3c1c25898060aa6e551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013341daa2a745adc0d0ee34f2392298476fc3b1eb295f1c7fb62bfe0b88cbbe89ea58530c0aad90513eee62a7420a1000000000000000000000000000000000007259a178dd247847f6b933a333b98564365a2d29447d156d6f1514a674452f2ac797627dc7e471e6e21f8a453ada5d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d0005a7bf3bd27bc6ea8ab49f5ce83c374c535f76a9e7f039292b830e1f193a50a84f41ffe5dd55b83ba210cf3e37900000000000000000000000000000000119f069d93c6c1e0b448adf3de843e4cc370ca2f16d428278bb632c6c4e34e3ffe24d27b162ba5da92d0c487a43f14851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001544a235a132924f7ae985965acd4ad409043f61dc7b880a69786621c417aeb34b026299e0508e78d581bfea2fa9afc2000000000000000000000000000000000e3b93b553b53374e856d70cdc29f2c26c38c89c0f5d80b7f46acfc2a54b42683403e805f4eac6c29a65799d702b35a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159322c900ec37623ef56fbf72ceab58f89c70f4ac42aa2b4b526569f92b405374bd19a3cf58d836adcb0732bc4fcac6000000000000000000000000000000000fede779dd11eedf222e80713bf6f01a92fe4e15431544e6d10a7f1147d3d02232ca394f735a43ba12c7c810292a87491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0d922dde2cc3cb5170bb9e26c3887410d1abcd1392b76793ae3fe226c267734bea16d3749b5c335c5217d8ad85e1270000000000000000000000000000000015d20038526a12199959f74bed93515ace97dc09530868ff4f172f7deb030ac2ac2ee92b4782d4804fe3918cb5aaea271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2d2e8b389241ecea9213b810eb4a66ce9e467011d8361f379a9c40c2f073df1bce54a4ee38b4a022b87ad2e2ec398b000000000000000000000000000000000dbe06455356f3df6a917dbfa25f4305cf0f0b2b3db401b4a246de6201016d18a4e97f32f3ae5d6c3f7c36027e0698aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152e694a8f18e3c27ace9566cb294b5d7534b3dd29f27d1876e2f0374cfdc7b3223487e2553edd4bd009583e02dfad09000000000000000000000000000000000cfab86e673594f4759b2770d1faa6db3fe6e02a5a18c0379ea26f2f81bead5dbd7a551727b0ee3d490d071ccb88c9831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000421cd4a80bf1dd13fe4629c7223f90036f680457129ac1832de4c46f93680e75280ab6fb37550da062db1e53b3d5625000000000000000000000000000000000737e00b47d2be7240dd558e01c25d4b61a9931d57a3d435a25a7909ca48d0ea672d74e7ad9c101372be2d7b67581dfe", "Name": "g1msm-1024-jwasinger", - "Gas": 2138112, + "Gas": 6377472, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000032007cd3b483e58ad66b9d31e32576d448922874a6a811bab27c6b99991b1760667240c17c8f725d14b9ae03d3975ed000000000000000000000000000000000e074e23a2f0fed94017184199ba2779a4728d33c3116c6634206eaf46dbc149d9531e0428d3ae98f33e3f8078e4c96b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6b3ceb0412b1887a8e93debd54b8f853521040f44ff311ace6be13037a031f4e6347abba34eff95b7b330d34bcaa5e0000000000000000000000000000000015ecf07218e3155a8a93c6a0c87a91bdcc0783f6b9de0d49753ba7cf833e643501e0bf0c308762d6b5e11375ac86740b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef5a85caafdb82adce7441ecc0322cb457d1e689512310787e98e378cea1ba91c18e9a520cd1cff8f6639365ac99ec70000000000000000000000000000000007501aa83ee78e56907c2ad81932f35d35c37f4e200d6a6aab2c9a54699a4d83cfd8ed43c60a11a2101b0c020a2f89981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088f4fbfa210d9263a014e688ce17b51784830ca6522eeaa3434cc3199cf73f7c636b4a052237bd52e273ace2ffaf7bb0000000000000000000000000000000000c05fbab30db84cdd7c63ccac3abffb8310c65c257af40a0de928dd28e5550046bb1bcfea5fc3085c118dbe0c9f46c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143b927a4a23924aeaf3b97aa0a6dcb5c2e609204414a39b0693affe36d65d33e059d9e3d3786f3a1ff9c9c7346bfb6e000000000000000000000000000000000754f407226e2b080868d3da913dcdc263cc1253098dd49d763ba671b8bc41cbf12e87b878df1a936cba0cbc01e9b7631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001286fcdfb4348c9f35dfe3e006d8ee64d3d09a09163ce6e4c17c6b09ec6f487e9ee44fea6c83666eb86ad4e59b8e44b90000000000000000000000000000000010923d71f470fbe0d26d4c3e4bae44cea3cc5d1a358f1fe1c0bb3c07e745b221058a0ac75d24b09f528924a770efb8591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2959a6c02274ca15b459e88ba5466eea318686059ede0935e8d4f5e8b60d551e2ba3184b3b058dad7ec5dd4b2d913f0000000000000000000000000000000018bf3dacd0542aa7a388684328f67d0971b4045f2967223af6f280d5e42b33e238b69cb43dbe8ec07c36bd9eb08d9b321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c45fe4ccb91fa877878719f8e3146672a72d6fecdbed0dc4c76f74cb8a32959dad028c9af5ceb94201b1a1b1f936370000000000000000000000000000000012a67ae13f41d886cb552177981681f035002034c31dc0252fe704b4e445e94062a8cac411f7d260364ca09c745889771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e351934bd8d5acb96b9a6b5cc496f419faa26d53130e04f8378e4c0c8b1f6efb530a97fd7a5f46ed8b22a683ee6c980000000000000000000000000000000010f37d114779513790d73a4f7e2945dc443bfcb3034a263bb02c44c204750266d9b14c9ed8d7a4a9ee2ddfb1daf837fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb7ad23b86d661c2d81f74e5555fa117eda06e18f1924f31a1eb12fc3b8a7a33f12dae599e21cb1aa447405cb69c348000000000000000000000000000000000442833695039ef95667eaa264b5ae242545edc1d1cb98e650985dd34f4f4d6c6f1399970bd440e6c5d7618e0b75449d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d36103e4bfd235b508df977273bd25b3cb595ed2b28eb23e7f601350d688087aa5465a4c16d81e5716d2dcad03d31000000000000000000000000000000000bb49310af633ca47312a14055ae15296c64b287de7f62641d092104448945faf27af92e0eb5f2fe2d92a83d77baa0421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4883ebc79f7b950e1ddeb699291c79671c41642b7dda699c796bc668f194ed0c4220f00cd466cb370a56f327445027000000000000000000000000000000000bd4051f0e7e2bcd9bb0bff7ce07257429ec684b705397ee7ab0e76146eeb1ccbf3e253d9ef0d539d9c6bca197a22ab11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d381f5d5a0a8cbaf34d0ec9211a1f35f0ecc8055e2c93bba4ae05cfe3e9874323f4c30afa5f43cb71ffdda7320e7dd1000000000000000000000000000000000b90dfe427466755871d6c0dda71382fb9768a0f39e694a319aa182c84f1e7049218cafe791a03cfc3afdc604d0ffb841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5a81270434ec9bee1ec77cb1cb9302e184f88cdd0248c8ad16ddf5cdaf88ec5e616fcd75f209801c26e316dc9b3030000000000000000000000000000000000ea6967b748a55b34e5326a517c586f124ac90743e122db0e28f1675492acc48d3ead68e475e054f7e77e17ac1c1dec21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cfe1a0c029ee59e67b00ddf61451f85adcc50de559b40be805c4575af2699e4a311ec0ee1234429aa0ebdc6d1921cf000000000000000000000000000000000132bbe7e63886bd9922ab742f1a1b61d0209786e3bf640fb1314f195a1113069b0c2c7eba636b240d8f8674969ed1861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038b843c973efad1b8edc51e346a3564ed54deae2b57845884b78dee089bb8982fa82deccd47013ef7524d7df13490b80000000000000000000000000000000012b8778b25cd1cc301f22cf9c4918199035bb68d2d7a1ec5dc6873ac0983227ef59e51838520df74ce20fc8b70a0b7991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e85bab1f99f515fd31060877ecab50dc8d494ec28685ee048b5a4a252eb0829a27c08208501b25cb19dbf188171cf94000000000000000000000000000000000c3125746a939e59f4902ff79abcc5d4f92dd087d89cd3d2515dcb8c6716a255f9e2ef52fd3ea18b453158b2ddc101e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001067c1c7b32ba31ad257a8c2b249362e3802de0d08316826ccdf5d0620292feedfd0947bb6a8279e8f3116d3c9d6a0390000000000000000000000000000000018cd58680a615c13bac94648e1c651b98fd4490b18267e86f7a733d6a1fdd8ee0c6ff3c3d2ee33466e03e467c86312811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021679ddaeeb1679f165b53efb32dbb76f3c3b7a338a04efdf4564d6c0f642409be752a9cdb148284a60f439dddeabd4000000000000000000000000000000000bf6ddc74dc5c7f5a7e95d3ef36e7afdb5fb620066709ef1f225e2865a2e808fa2cfa8d9bb461c6d8c980d22ccd5f2541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033f40464a093aa771150801d3fc2124fac5d70a35a0202284baa9e0d1e926036c1d1636aca98b5999599251852108210000000000000000000000000000000016ab78ff003361a19e3c2fd0cf0dd1bf81d947e7b9d85835a7c3e930eace725fdf8655426e89dc19b837c90dcab546041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e6f927754ba9539ee3fbc962394488ddbeca108ca74d26e396652f49b58e2a621bb5a24eaf4d5ed68bd04e4f888dbc00000000000000000000000000000000172d6f63a7f70d89a6cae192d069661775adf6c5297eddf29ac7c2f1fed25c4d07994527c31977060154266239c611d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689095426885beae3f8f147742ff9f2c904885d7273f751dc06d8337dd89ac888a47ce7a60bddd1a6825c032105a5130000000000000000000000000000000010e2d430236f97377b55b3ea938da46e7894caad02c290509fcdb11905ec51e8d4c58f67f6be23640f025fae1e598cc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003a6c6717dbf1b3a707aa7c2d77aa2b05a58c87b011d3fa4ca549af916e3cdab14c318d7f380fb258fec7ea23399ca0000000000000000000000000000000000df4b139cdaca8d8093d8c4e73ba8debec68d79a98f8b5a71d0d5b6b22b8968cad2ac068dd10bf905411069eab30f7d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b8c59fe028f1e9de599a30bd461ff6a8f52c029bee709e136e5d389ab0f17a5bb684982cd8eec25a77017a4412f979000000000000000000000000000000000b88f9cdd214887939d4b5b3b0b91ba7012f50fbf7211d40f4b1bad3cf06de29a1606b75cc02636527149e0bd6c208071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057ecdfbc63653eb22469763509db3a462a06c8b55777b93c973bd55b4ad4d556a3f7d542334875711e636fff27839620000000000000000000000000000000014d65f36ec3188b646ed06b3909b2b68a33320b710bb73009484ff54c4e59b13003d9181fc3c5ce78f0d24e250ce59c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001085a46ab150ab3c9efa1d27cfc70c097f3d870150bc0e9b77d3281a3ac236f60000991693d91a46229c31a5bdd6097f00000000000000000000000000000000120fa6328d34d7fcbd7d9ab28640bf3dc5607d2ad019d2772e44a7f4126b36e0c6754d8810ab835c98f03c3edefc22941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001052894142a43feace25e0940ea0eb9109446235f9d80955296c0e6eb9fb437752730f375b7574b0ce51e6e73ffb986a00000000000000000000000000000000143a9abb96abbf5cf89ff70bfe5c6fe1b698070e47f12e3836d83ef273474911d4a62343eff96b0b9e6e07efeba197061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b159c90d7142b25b142ad6273b80408d31c4a5f25f8bfdf8c6802bd735d063c2a4677aa85daed153323bb3b9c5d4c9200000000000000000000000000000000084d099e93955509c53d0e226be0fb1925439332121ecb5f014f5084b509a4618ff37505ef7ea963eaebb0503dd3dd511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125341c3362719ea01c16bc7cad91d12d61d831d0e6776ec9d5b6977435a997ac959f8ee87d1afed5d635bc51a5f9b60000000000000000000000000000000000bab67b2091caf5d5e2ed5b9582f060a6e34872c672bd063bf42a9d962a55ae5cc921a6e5444c0070cb52ee6bd83d1071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019d5e6c469006a4927bcfcc6d8e44714639f8480e7d781a778e4ddb32c8290fc6840b208650cb2c3f41708b17b21eba000000000000000000000000000000001030727bdc730e39eb9cb0cbf7ff49279869ccdd6e7b72ccc00802de953804f0fd3aabdcbad2ea3148b0e7dde373f4961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182d1a8bc85002c762603b0857cab576c68ef1353f3c45f7772a24cf0a684a422f5747e2ebfe7999d54d4d8519f9faed00000000000000000000000000000000073350f9440de88130e07f826445cab28906741ad8956a54cf375030d8425482e3c8e3ef9c74c0f2ef0d9e12a3bcd81e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001997d74cc5cb14562556df3c05282a3c71516d2635477bdd6f3dc103c9251efb26dd269c7847cdbd538f339a9dd5b2c300000000000000000000000000000000098262680f3971fb3fbbfe40be99f80932150620d3bfa299322be22291d03c78a62c14816f125dd283b8adb72a827a1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026a87621ea32b6d66ae8f1255d3dfe188224c42f10165fdf664c4b63ac3c387dece6dc786f86f083b6c672562c2ea0f0000000000000000000000000000000017388f32a0c1dacb6eb492fcedccb90a72c84258e374bd264c69f5b01ae376b2abd697f0236bb27c72d94e3d81ca9b951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a2d89c80df97d1427dd94e59ba07ea9aaeaff6a2e36cf4d34c40e7c75374470d73bc2990f9e6dd79d25c038fe49e50000000000000000000000000000000000baa6f4e1239f2ff8ff0195eee0aafea0628d4aecf36ba572edce0607dabb8e82446849b08d52f8dada4a5ee496ad5d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019250da40e17a94e7aa02ccdf4ff466c9c6eed3af7f37eebb91c4c331f1c8451d82a6704c4214bfe6a0dda87b0b5f6d9000000000000000000000000000000000f045301c4fe1bfef3681d4d5f631e5fad1627a77c8a43c19684b1e4847e195031fa47dae857fc2077019e2c7e7b24471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1b6bf707e25e1fb6402c32c7b994f64ac36e63c774afdf17091f6ee4bac0106352e541a4899991f0022c4d343d7db5000000000000000000000000000000000307c4244f1159c1324993a252012856242d578360c8bc6e3bfa706fd5766174bb832a69b2c2c472d56e2353a238a62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004469855880a8a089eb7006362650d617ec5e09e67889bbfed11c6342dbfc20b966cf73e473adbca1798746a0845ddd700000000000000000000000000000000030318e8e18958ac777c7716d98a07bc81c23b3c34c7df73768f40278ab36b94f187c39280eb9b239ae3e875818fcb451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f8d347c12f90497d88a3a6ce49c993af8e35921c9c2bd790d160520fa275877a7d0e56d0403ac169650a6e449c7838000000000000000000000000000000000187405f96434de0e073619bcab0ff0f6e595bea588007a0a7e90bbefde4e5241aaca77d4841e7690c67b2029cee43311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b964cb25a3b580053fa30f91865a24c0986257cbe9e46403ef98416f12d04ffff5fabec3e01de824a1eb072d729e0700000000000000000000000000000000151de234008bd69b51cdbc2ffcc7e2d7d7c90b86ca05fff2b35b19ac339582feb01885315c799b584a7e9eb94d3a27261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028a6dc8bf282283ccfac9410426f70431e2a12bd3b30c8cda309c45ed0ba7fd34944d45055144604fcd4519158ecad6000000000000000000000000000000001412af8ad71474649d27334d19133dbdf89556dd35924e081393498e4118d29b34ea211f270baf63ab64320b42ef78611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037c9801aefb7293e96589fef72c0b20911bbf585caa2b62b2743418366696687e8d6ad421efe860c241c76bf4045db50000000000000000000000000000000010c20eb3608dad85c1ed8d3f5531d5bead8d5b939b70558b572f90a383707014202b1c2c940c3f96aac3743a81718ed51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001779e1775b0a6c342c85ffa896f2df91891bb719ce3b1f5f09913c17cec6291333fb1ac28d4f5e708eabb2c02dac3cb10000000000000000000000000000000015c09641e704667026bdf4b3bc78dd62205e01bfdff6ec52de776ed8a3bebb81452170a9926ce90d6affc70667f138911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001866280c6def3853ead557c96924505b12421a3813f6bcf776b0f01b8d0ad4e33699407f60a01fdf3b623b2f6c36a97c0000000000000000000000000000000016ca2304bff90ba992d857e43e51484464db111849946ed606b5f5fc769afd1d454d8eeff25fa59d8fb86cee3e45d4d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171ca1fe6c3a569d66f1427872d2bfbb945a3515c71ada66914eb5b39b9e12d66de4cdafc4d1fb8f64667070d631d40a00000000000000000000000000000000165a23d82e31b797356e4cba86c4cdaa92f2cfc9750b056a84ddee5b4d21543fabbf03e4760df90de2b0a80c0c7a25c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012207fc1854a740cc6cc443d7974c19a0568d373e404d4ce6293ac4ddf4b81b01c67b88b1c6d4aa075765ea55983b028000000000000000000000000000000000cb790d9609c18371be48b834ffa53ea0375b268e593d084172f522d6bf58609d473f1ed28825df1940e6ea08b0e63c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001219f7ebb4609d93161b954b54696884225d985519a3013c64bd21d82b209cee5f9f2a23b7c95d859ed0a5b9e0cddf27000000000000000000000000000000000786453141e45096929b03dc2c7710b6a163e4fcfc51e73c08fd20878ae8ec431105d000eb9374e183cb15adf96e6df51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002efbdc82c92a2a663530c4cf5eb6e179b5704dd79c472d24afe2f7514766e72275a1ffebf2d29336481f28bf10fc9d70000000000000000000000000000000012de417a5aa2cf3ba38faffffade38eacb8a829771b8302ded729f0d1e02707d62365e24f6fc5ebaac8ebd382917d95d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019951e64343465dda2130b8f5917e6448dde1b2cc4e76e8af410f2040e82c7865b030b4b3db862328c99850156ef5a3d0000000000000000000000000000000001009b1c9afdef8f6a8df4a87de5e6ef0d61d4b6aed2b721e9bef84a6e2dbaeec4307d47a4eeb155f61b7f353bb77b9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f1ce3c8db6d7f744fc15df28bcfd48b3cde56a52e9f78894e08d4a770579c01e6dbfda682b1d7ee593660a249ca489000000000000000000000000000000000434f7cc6d08ba7ed39b57a33edf80d45e9c5493854dd74e5c42c34af9dccc9c58c265c53d449db86653fbb00413083b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006598c499533b0b32bf8c7fef46b2b32d2de899182c79e1082dbc82d3fa749b7a96acb1c1cc2c0e3cfd8a0bb0d27e68100000000000000000000000000000000101b8e6fdcd5ba1203b83521b44e65003128b36f0f27a19c52744173331a15bdb398e98d1698bc5fcff8c82704fe0c311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006dd5a4b9e21754f0d81db9bdb0c6e2acb3a57ed1680800ce652d19abfdda4f4fe82108e80c135bd66992dcc0f92f8f0000000000000000000000000000000001512f2aa5a7ff68e38b830e23043d99730a5e6be3288bc18925a785c27e405b8f98ad48d776bfbbb56039a795237ab91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f3f4078268aafbd374ef27a85128f4d0a2d6e28a68c09ccd320c8b61942b87947d0cebd62d88e659ed5d50bb3e84270000000000000000000000000000000018f64672dc8d1989c962b751c9ed932c0990e3b28579d24f55c72c5a5f715007bc69b0442a260dc9645e86ab65f176c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192629af670e5197154a571d9bedad378b497d5e9d644d73d2a3452fd047698717653de2955a16c4bfc0cdb1940c760000000000000000000000000000000000187a27d93fdb7710a54bdfda60b09b62f69f6f7d4a18c8b15c80dd8d57eda20eb9bbe62af1b72ebb520246c81eb4c12d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000476e95d2e71ef3a156fab73b700244bd9512eb337fb4b2511e1648f1d0de6c34f4b2f38bb9143d01f3db39f8f1255180000000000000000000000000000000014443354ab9822c7dd6b72ad979a39539a7ac75876fb16a4d6af4cdaf88ad3826c3b168b2c8f2827bf2b0092d6c678561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef83fdd7c3dd23ed4edc8bbd32a553c125a3f9a8750170c70e248f8fe39e6a385d0a021769d361774db81e5be00022d000000000000000000000000000000000decfd66779f3ba05fa4e5fb0e189d4d20afacc58553d18128a8ea98a67729526dbe682f61db961112082fa1aa6e8f221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc0b339e5bfb39f21d9be6db705c131d8684bad473f9e885ea545dee22918bd0f1a86841140969918a951bcd457c42600000000000000000000000000000000036a51df51ba575651a7458ef08168c0694cb848625d13e2f5b744e00fd8ea8b878cb60f1a41e4fd25c62073ccba66081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b684ff9f60ce57b457224ac43fc5d88d3f94e0ecd538a95b5c8c4d6a29361a8d43dacfb5210380634f08f343a8b564000000000000000000000000000000000a6708684cf5272742d3ea7ce0dee63a0106cf28cae80e7ddbd2833013213e7f763af1e8e2912faea1544ea0058696741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1ed05d66d11e2b28f37c5098e8e707f0751bdff48756343c3a54b45a126ec5af938c03d1c05a714a2223ce96bba0330000000000000000000000000000000016eec9338cad83721c90443a91cba1606895ca7ad61e20b4bba64ba541cdf7cae5c6c753869fba35f266927299daa3311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001841dca2a38bf9e33876a7bd4cc092535455b026c3a80e4bd0403cbba5766d491345a3560c6d265d93e40e1c5ffec38d000000000000000000000000000000000a506f72deab22a3724b94dd7518a6680efceb7a8b0d33f066f338f97166469ec11d27a2dfc7e430e9121a0c555ed22f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fbb69704970c1cd56e0751721a4fcd8dad1b2d3d14361b4229267dc76bba021458b1f69a14957a10a5f58ee32f13e300000000000000000000000000000000014ad8937e701ac0c969a97e64790e693813de432e5f68f78441946f603698ae0e39d6483453fc54dc7dcec21ff828091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040a43241a0a03501dc6c6af6512243ce956d9077bd0892d72c97f5dd558f31d8dbc2cfd0361d909454d83a5215b83b20000000000000000000000000000000015f82b5e63c39594bd5309fcc327df698a9f05f4840dc651058e9aea7d1599e51c8cd3af2adc6b83ea8663003747d6dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f9c56625f60561739e36891786e6e59fa0702b3aa0b497f66246f9570ce49833e195bf556d1ff9d835b7141d85cf04000000000000000000000000000000000d4a7f99d3f67cb2be1c471f01d2c5ce89ef2fbf985fccfa37fa8c550b9eb87d21844e5bc714b55beb5fc8a183c3d0891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180ac2655133504ddfb97b292cc9be3bf276c345cad53f8ede52e81d8c51f82ec48598f77f06595eb2a071b882d0d9d4000000000000000000000000000000001461783ef9c6b72556d79ef5f8a3edd3d91b9c114412f42c523b9f0fd4a156c4e9789ffec37707c38b793b4730d85efa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cae6aa287a1dd866917a01d9679d1ea29aedab0ffef3b5b6ed8509e1c674208261e56ff1ca375fe3d41fb6ecb9ec1f000000000000000000000000000000000e6c937433f95e25f4ee8aabd24b701cc211bc22db208f422ee45826ec6b56fb6b50fc6c5449d021e03f42b4397b93301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000b7e8f674bad965d023b019912a7d2cfb5b5db5998dfc182763c2db4ae13d3120b9b59673781290e38777028fac6eb0000000000000000000000000000000004b23e96ef43a19439b9ee78bf52490804ddcfecb43137cb8b99ed0be83670c16541da61bc24fc1ce763ffe2b33473531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d73a3103aea50eede0ad6c01810bf2af21ba18533cdbc47c03d69eb26b63fdb54a0661935b9783df2d57d49450417800000000000000000000000000000000041af0ff9b643cb6f068cf1b75fe857e7c98aafb7fe1e2138bb8ce739d674929910dd1830824dddb8dc1e6ed8e795e921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170e16fd0252a09d025b1995478d0b2097547a79b415b4044b8308118bd0c55da08c9fa28c235e7ed8af1cf7b71620b90000000000000000000000000000000015009f6f01560195f4ebfa2904f1cbab5a9dc65582a63b08e45a99c59d7aba13d62b1ca5eb0c9b0d85d0ec18e376d5161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193ab882c2e79b5714f30d57dcaecf87519f70a3fc3fe7d6f02a59da51578892f0c7ed5ac5b6372cc5856a0aff7da0fd0000000000000000000000000000000008ff891fa28d25e1215159ac4359316d4da5c0ed9d44b2a941190050e4936a7ecacc3b92c62c75b5c1e5aa4a8d0da46d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115489cf5dd9f289b372e219f9f3c15f768c69c94264fdf6aa6a5f81a5ca2cdcf5b7ff86c9b6bf732f40a99310873615000000000000000000000000000000001700c38ad4be29e9d022ce18377fe05bc767c5997527a85084042a88a72d62a1cdc9049b1db3c6a7a9939deb9c0838b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102de80550ae9aa9e25ed441967e875c3d17519611bcdaa93874665a6b21a6218621dd5c75d2e09bfa4afd5563730be8000000000000000000000000000000000bd608717a0791ae9aee400a082d6bba1985717be3b63d5c8ccb7432ba9f0d397f04e91522604a60ffbc5032ab6ecb0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d9a153393b95ed146f6da48f3f72295fc530073df4f22a613f9695cd92fda563184d37c150fd1446b1c2d94f1250940000000000000000000000000000000005c35a609a67e2b8461ffae2a5283fce152f968030d1fc1d330b06bed9a37140fd39e4663524e1ba55b690d6188715e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f82dd7f3672472148efd9935eed494fde50662092b1d08022464bbe8672eee6cdc369b8de570ff5637f9ae04b93af27000000000000000000000000000000000c4005fe2db14371ccbe55257657629a769fd8d3e6cc37e3cd11d79cf1d020306b48ddc68627c98623924cc1749df7901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b41bd861c49cc19cb6988a2e2d426b37eaa5cd32c457c1404d5efb65f07b0039b1bc1f5dd5e55916ba666b1e105d3600000000000000000000000000000000102c868732e30cd7c727653d58394a29475087f6aa02f19b855ab41be201bc606e073d8cd2efbe94efbd03bb06d461b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005150e5832642973353e161bb49f4780ab6bf1e91f23ce7320f585d9c784860f88905fddad1ee558045fe83444c68a870000000000000000000000000000000011027a2af0036bdf21fee8f2a250eb37b9e44cdf42ef927fcbea1d50c74f56a650630fc7984e88c84f58b823be3def601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001156b0ef584bb46734bafc0b9579358476c57f318b097708e8f9dd9add8aae53aa8a95d10461366d7a215b481004b021000000000000000000000000000000000468f36128fbe1c65453396f7f1218f2a28a7b2060c4286653db8ab786e7fdfc51f4a9f6271b7c58651b59409e3c288b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000147302fd7b65c86a0e87e959114784cb65f72ebbd43a9f03d84780eeb0c1efe10f815ce731d91e83f191422d89b882b0000000000000000000000000000000010d0019ded6feb2497a982f5d92e11a11114c535a2434d9ffd3fc7833625312aa3210718ba33ec123319733861f6c3d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a284d05e32251965be5d13f54db18b2548acde54e2ceb395e94aabeca3dcc338741963a245dd4cc0bbbcec2287bdd890000000000000000000000000000000002a7673189eb5f0fc5bb223a7142d32d4c2f76f378b47c3c01d37fef858a2bd913f8c263e0336e149cd0925774574f711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079e02cb0ba6a3e5f0e04d96463f56b70b93b1db504997f865df3216bd310964a2d3f253e180907748c7e707334df8140000000000000000000000000000000001d62217fa6e91423ba839ea8b50a6525c4306b896ff2eec52475a9b675058f9b83075fa91a62ac431b796726b60b1c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001462756dc8b793923770e87bfd8a327f70a83c161048bc868eb47e2561fdddda9f3cbc991544b3d10b60a5de8988e1aa0000000000000000000000000000000000c415624d92b17a8744a468244db414e8e4b980ba04ee7937838447a706d01c68f4bdf10433e92463306c35b76348591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001859da83245613ec3a91c04b5fe32cd4f242f6b58e4823e5d9133b6efbc196889ad70d3665008c80ef7716f31432a8f50000000000000000000000000000000003c1f6fce218c6a206f3e863a33d4151e53e91adc0bcebe7c5ca9c5ce38f49a7483f21a909cc01a2c5c69532aad743761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb2e148232bfc23ee9f904976cc2cd9439a57d5bc221e8ec68fc4854cf5598b06459eb0b3354492cbe2dd211060fb2d0000000000000000000000000000000018ed57ba2f2b86ac7d834d64f7cff8e556e325e9e088dd630f649c3f4617ba4f9c0373508a0c7367298ddfcadfe1037b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159ebce2f2e32976fa23c7985a517f95a7471587895b11e9d741b024111ce5c5dda5246f97b3a33c259b271f4d70c29200000000000000000000000000000000063f87dcd69ad605ab0f643ecc81a1e9688d6d0a7b42107d7f2c4f48658db4a475391299feddbd08442f1b65ea92315a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c018cf79452e50882e10fb629829a038f48c93fa916e5793c0bdbc1be19c7bc75ed5738db96bceb99cc861b4953ff7000000000000000000000000000000000df949931aaa56834a119d1a4766bc397153027b9e98f67cf1c9413ab016eea3319b8fe6dffb2ab0aab7d98617e0b1be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7dacd162f1fd7b1def536c4083529561eb0e500ceea94992c78f6e3023b5580d3012b89f7694c7aa9da18c26c12bf3000000000000000000000000000000000043f80774cd47a8a2f3054076120917e5046a16917e0a16acc32773eb5caf25299c6a7c6652b18aa4820d75f6dd97401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001302487ee0766fcff5c21d3a6da03bcf6847ff1e9d3504f69aa9594ea00a65a6c6028050cb1eaaa7c45250fef886776a00000000000000000000000000000000147781f4ee28bc31c1abb5eace55a9e3b58f7b3644f790174ecb0c1eee913e52f6eebb5dcac42d67a482adedc33bb0821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039adec2ede880b0c96e13b60589e4f9e65e86a14703915b6311918f81fe3af2bf434be941facb5ae03b585e7dfc5009000000000000000000000000000000001268f097825a6ba6947549bd4a3c051d59fa6846379778c53872c66391ed59b14ef80d41969743a989149bf7f6b44fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152b4faa107163d6f5e7738461a7539b71d6585465ec3b77cf84ec5f11138dcd1043bfebdcfa26ba58cbc26fb1cf77f500000000000000000000000000000000088782327f8e8c98c3afa9fa2e4f881b374f7c4cfe567b481081f6bb256dca6eb10a3c51ba5aad953fb531c6014e0a271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059069a63e4c1a51df90605f0c604ef23b1bec2f6c2ae87344514292baca2d4adee3b5fda85c00c437446a853984a40f0000000000000000000000000000000014d5b41aeeff5e3c1c9ec8545d400d41da4157b2607159756b4868282b665ddc39b9573979c89ab1a0482c0ce94a67c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010316a016f8976ab60502b324f94ff1a5186fd179238cd8d894d78fb89d6def54ae1694ab223ffac7f188fdb9a1bb6750000000000000000000000000000000008a66b5bc4836338d05f9f6b04fe1a366f37d4cc19eefe5517616154e0711a8385c8a1359e2c6716e5417e2d0d251d241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d61f67622c76fe10953b942555acf258a6a73b2101339cac812bf68735e361ec74efe01a570760f1257701718d3986200000000000000000000000000000000029a6562ca4261117a34277a45340ac6385dd77e494e2b639732eed24896fb55c040839d7ab982f2bf642b212303464e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071fc210cecbd2443115d13b1b890aab0c33182e8fb35ec912afd5ad0c1441019cdfa353dd886ff2deda0fe72f6e005e0000000000000000000000000000000013745d02eda254cf2acfbe8c7e5a4fbbfd31d6bb993da3cb180a834380be0934ed51bab195af18090db2b814520d953b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000867815f868c5efd7ffe8bae3f0fe3beb85379cd4264f770e165c000cb49728f7b40386b5020e07f39569dc83fe3dd2900000000000000000000000000000000085bd4ade2f1f134da5af39abda5e5dbe91de3e9d37b1bac92c505971a436d7110b64f44e3a14fec40dfa61dd43312941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ca9ca0ff9e6f96ec2c7996b31e79c9103e7ed80b74508ee45adb744be0a18f8f22b704992e6fdabdc05819ddf66272000000000000000000000000000000001731073fc0048a7c92079754baa5a5e8e5afd6bb599eb7a31952bee9cf20e246ffc4e0381dcdf2e1dafecb067caca7881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d934b73bda02d06e90709b50d5d13e2375d7dd674a4ce67c47238ad2b8fe5548aca2af33973b042336cb5bc0b05a6c40000000000000000000000000000000017f45be1b13312e020fe9d74b83cde81db164cf3b17951ed336edd59cc31572295b16e24dd9441a98dfafdd4548b129a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004504d4a96824b343989f62f18a82ecc4a96a92795cc63c2c5c8f7777edb3c5bf16fa9560a699ad58cd152253abcba3b000000000000000000000000000000000b75ce9b422209d35cb380f0d6a1c18563cb23f708bcf9e88b21290ee00449561e7e88857192907d86546959702484111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccadb065435c2a54ec8dbb414f7e14d83ae2fbe09b7da697c9db14c72a7f571913d54d08ae1746650bae6e9dcaa43c10000000000000000000000000000000003b924369ccb05c65e9a4271daf88c3ebf07594f2f05ab7070307ce3093f82c9e2aa8f02c776f766291554fc780b61f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2766bfdf616f95dffda112d2681bb1a093e6c5c65ee8b254d95bb64dbf76efffeedc7a85153496348c04e8c413d8020000000000000000000000000000000011a90ee51123e41ae9b7357544a3bee1e604a1dd818b773ffd181783e5f592b202770647fdc196d4ae33b923b4590c991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c5352571653eef2c93d9e84ed8b1a8ebf94a5e8fea352497edde7288acef453b4bd00cf0bddbb2271e4947cf5a6f650000000000000000000000000000000008063c1211f66e9ddefe67cd93aaa5dec7890ca25b43d18b38a999ac6010723861bbd6e1250f70e62da1a0f8f119090c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012769606353454065c2ab1cb25d284744adb5fb9a9524526203f30f0c266ebb9af11d58518b087d06b06511e4329318e00000000000000000000000000000000138969e051a71302ff060f5ad9679101f06b40556d3bc7082b41c1d4a92f38c75df919bc5033fd7a8a32a5f050e994f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c478c5df9ca90ba1cc4367941a2bf68e69159fc4e40a4a701aded777209fc1f8b185e8b13311f5623ff6172e4d543c600000000000000000000000000000000048cbac81daeeb22a81ed04790da93ca2612b708f4f9d871996a6b1e7ef1ddb4470a3dede075ddb84c198097a09b0c731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e433bd30ceed5c4bbc555c5f09772ad5a2268ee2adfe8e499253534f066316aba70f05e1193a7e3958d3c7f4a1ddd200000000000000000000000000000000161e8e9c455e75c30977de9678b38bd3d1f0bf6d20a8e3b5e4e918cb6a51f9be833b84bc2d6942b4f366dfe0537217b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000beee16abece6c2abdb2cd560554562c01cc42ae3ce8ccef79531de962e3f921b2905d30f16baea0290cfe687903a309000000000000000000000000000000000091d5e5ed66dab10904efffb132dbf633a2edd0c47a511398cfa6c555e16020052fd38e3f3f6519d961aba547cd61351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001002d1aaed3845d4d76b8ae07be19895d1e4a0bb0c90c3c5c8837af979cd1411ee1b2f056280e4a02822d8020aa544a700000000000000000000000000000000179a25f8c5558dbfa3a00fe127c91d819c3394d5c5851a9a9ba5084569f60d5869e4d411c53a5602d4b48747d60513511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194b5f869052c2c753ad31e82caa3e8ab987edf64b701e94a6b4c9432a286a9efee8bb1adf6d0ec592b84aafbc76af78000000000000000000000000000000000be06f43b813da7362f5437f5580ed3d9017115e758acb0267a75a844c1919287ece8b5cb17d9647521a832a2f6e5e141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f3a14cc154a635110cbe481072d8b783bb2fc1c5c079e946fdd0f53c23b1c27f79908f1f49a5f1799bfafb47332fa1000000000000000000000000000000001446f925b64dfe4b678a9a1c6a1c972f9bb35448aa5d10c2b5d5ee28a6c5e0ba75248a0d4ea7583d524323cf8abf56561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c0b3ce58e00c4d91554f5c4abdde253da3fe567da96c8f73b121b7aa09e5a1daa3743f3d0ab691a3e80f3ce5e88ca2000000000000000000000000000000001965a264a01bd107f9521d7044e7f4c7beea1000d9c318ba3b84f6db395011874dfa7f7dd3e4dcd235d38f893542c7b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013473897769214a91c5ab026f385ff3873b73826971e27955c27891c3b7f10cb526f4c5137f98a1dd132ee4e2cafd5100000000000000000000000000000000011c1b45da6aa3a24bac0575b0a3a109d1c185612df1eed53944c099ac0c7abe1ce61c5079d1b3fdc3746d9d740eebb771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132694e7d6a021f7d05f7479aa171e2e1746cf1903a8b325522bef4b773997f66ca708d786b5995df1c615d8f04e96f50000000000000000000000000000000009c48456478b05ff74ea83221bba6dae5abc14a64214fabe4b092385289400c148754a9f5e1bbc08b6fbdc50654506e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012662e0633cea5435cc896b6de3af926adab899098a6bc0816aaeff8e0d706d7bc9c6032172e65631da76d8224c5bd80000000000000000000000000000000013a93cd08319abab8115b995ee8945ad748bd20d215cfc19adbf3bc4fc060b7e77de956a962afe922d8377bdffe06f5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097dcda137766c1965306264a9ee37ffc0404021b2721a0d05750f62a78c920b51ed8686744ab650ef824d5604d5372f0000000000000000000000000000000000e2fb06b77e1ea0dbbcc0d120fa00fbf86d5bf31eceb54d9e58cfb8d87b4b857bcb792c66f5b912ae7b88a2a00d689d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005de4e8167035d2a6c2ee9682ffc0da2f9ae1cb898c216356a30c82fc44f142f04a8ee68faabf1dd0f9df89428c2317d0000000000000000000000000000000016174869e2cd1dd9d938479a8c43f75f7bb9ade206ccdecae5ee675abeb29870b622e838e5fcbbd94e3e09573bd7f4521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b662d61dd10617b053ac3796e0d8c1cc6a4210c95791b615628fdb8f1d41c79d5281dcc5d62b361efe3e18648ce2a6d0000000000000000000000000000000010063b63e5a0d8b2b0ca168eac8b49219b098204682986a3efb251a8bac1b88b3e6d74f42109c3ea527e9cdba9d41b371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c29864c493d10320ecca3f201fccb1e821e83f8a68e6e1eaa3bc8a734f93d592991013b880333edab581908afff7e000000000000000000000000000000001083c06feed32a6ea6f54b59c63856c458c217089cee55626f401cfc07cad80fdfb56483178919095dd02815b552f10d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001849467444028ff330fa842950ad471d7f4751ea9ba52050ae6580fb2897e91bbfd185d7d8a607bf03b0758db478ce550000000000000000000000000000000009f73653f3e2a7a5db07f3a41a31c1fbf1d2f09cbbd4a608df8e72a68dd07ea2272d69067d80a074542e33c25661d2011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ef0446b723cb2945354ae45f2b32b70155ff8a4f7d883027fc01fff5bd8981ac1b763ec79a7eec0b3fa713796d25d500000000000000000000000000000000125ded99bcb64d92d9de082cfa69e2f2b21af891c049c5f98e24f5788ba3aa04d71e799fd87f02fb020462365fb9dc5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001698f3e1c65548aaa68001399237b87ee60e701116c3d7c77b33343986c98095e1e68f1e8086c05746cdf43049a1ec6c000000000000000000000000000000000f7a64ce4ed9ce2c3458fb9d4377d751369dca025b48029a285f901dd3d514f6f09d71c0cbed576f5ec201d3865727911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9dbaf6a26d6fc045b65098ba16795a80e757d567d8fbfc8187d95f2c84635ed411054e030589f5a1ddb91b8cbdb1c9000000000000000000000000000000000d29ecfe4cb00fa10714b0f685c28900fb6d6bb16859baf03e95db361614691f01c851eb02f3740abce045d22a7892841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cdbb96c7a0f090fdda28d90568d9065ee20574f3f841ef589f96428f7b658f06db8f2beb5c3dc9e8d23cebe24d0d4a000000000000000000000000000000001428857ccf3c898d73821e06accf7d5ca8e2b941b7e8492c8f2595fdad49a2b0a42d1d9320381a5ce6c40ba5939fd41c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d389ec102f24ee8ec8bb9764e895f71e46e5fd2dfda4b572c5327ac2a76fd3ab4f0e23e98a2c3eefa4c249480906dd000000000000000000000000000000000306156750e8b0e8d2499fd9425f425b553482e68d1cdaeb96c9c2f158bbda5d9ced4e581b749799a85dee15889df8f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018556fbe25e00f028acd3d4c6119764118e88044a11b4d256358c71e9b246ce5f0543e38e94743e9db8cc00680dd5bdf0000000000000000000000000000000002bc95e45cef2295a3e7cc6e9d81e22dd755f65ef9515748f183db267e9c627a5b771e11373ce05f1f5072362128d81f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065b19014d6aba377f2adf8c37e9497e36c2f5bdc47d99b0a204d90361d12f1f3ad4cfbff0823ba5a9b4a60758ac3352000000000000000000000000000000000731a6da0852e4583c94224ae71d87115347390da3e6b1666806dfcce169857bd7285109614b4e4bd92b5bc74ec941e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bcb9ccd4bfbf762501b873c50d185e296c8976c96f3d485008446c56b719711f580678c0f4b700e9064265fe9829230000000000000000000000000000000005dea90a4ea17a6ca553ca1097e34a9a92be34a4270a62e6d4a5a74c86c3881daef06b242e1e85ee579c95ff6a45e3e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000541720a25e3829a49e1398b256cde6278304b0ff29ff8ae766d2f1584d9180e74b852490f620efdc6ed4ae9b694817b00000000000000000000000000000000184220283757a77dbd04f4f2e47296d9b4829fb788faf03463af6cd116b3beedf3bd47f42274b56867f72b74a7ccd0ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001777a85496fc37cca483cdafbe2ae22a196aecda9a43c90312c2ce10c1aa34d2a7f3e4584ad3acacdbbea02ecf17ffaf000000000000000000000000000000000aece05dfdef5e0c921f0dfc04ae9a5f03bb39ca8a862a3628998718ff2c47413c081c586fe2d53e218b4eb6918a6ef41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb84be5262fac27bf796cf2cd8c3f5dd46e9f86c146be5a84090372007df74292ac66e8b9cb8b39db34ecef62fd64a0000000000000000000000000000000001635934b146d516875562990df328cfe2791935bfd61481d2745a849ce52d2d49c238d1ad3338b47d67de49bb1c6235c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159614781925f6d57b8dd89acae268e113dc21e870b2ac099f8b581eafcbb3a7f2a9e58f4fdad1795e9c425d81604bef0000000000000000000000000000000012265fcb86336b06f83539198b57e7893dd051309c3977941c36afe2493f806133f484df54a9c632635a3e8eb5ea83d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001319f83bab38ea61515b0230e525373d5d756442c88724cceb652090e47dbd6de1fd5f98b07eb50651e58b391737750a00000000000000000000000000000000077d25851d2f1c64b14ed30ea48e2824b3cd93a2922d78073a5c3bdd1e2cbd633aca8e3e11435d77aa3640b5edf0fe471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189cbdc7e969aa333fda9d00daafa3ca7ae1f0ded43d19c6ed9b5c29097ff4d7e47c433c71cece756a18f2791dce0ed800000000000000000000000000000000086b88a1a3a3532e54ea451b6fe7bca425c5753fc1fe9b2223bccbaf22b11d27ecefe4c8b0809c4a79740ffb7893bf921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bfbd5ac57dda92068a47cd9aef8dff0e5417c94c031524eca6ee6fad749b24b3a5028f8882d9ac919debe3986d0268000000000000000000000000000000000808ca692cd9690990909dc38fbeefe7bfb2fb1c5538e2b8489c89918657e3844e4a95f67535288cd77db0ff4021f0ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe3b15aac6a8b04cf4f8c4e1caa99f7a035112dcf160a79f34ef0ed725b4e23738d150138ef236132b5b6809e0cb2f00000000000000000000000000000000020d2bdf1a62babe7f685a41b23216038ddd03fc8f9dd8e84b62b055bacfd3c2a8ec2f5663e35199d539109be305f6ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da4dc6bd1b290f7593f27e64401ca3dcfe8dfa266490b3cdd1216dc471d0e4507fa88b7bc72dfeeefd9357d28a230820000000000000000000000000000000004b84b35ff110279a8cbec8f5f00d04934bf1b64671c2a8325720a243ac63a3b601ddebda7443ff406c0910bd7497a401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000babe817d6d5f0a39f0c5b720b31c4f7c8430da3976bd68502bbf42a6e79ba188636193ca68acf73d9f93b4661aa304b000000000000000000000000000000000b4b26ecaa5ab138d3def229c28d4b9207960bdce29e2fa63ffd3f182f86e835826a66b4fcba323d7cff4c8af82d17801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042cef5814745b9953197c0853ddd210a9179e25ae8a71857ca06ece63926692f1f60ca1261503f5fe45fc5f155c0c0b000000000000000000000000000000000b4620e4c151881f6c629fcbc4bcdea4be19a180683b14f5b31a153154e4b0760c6fb5241da531bf4daf79c14863060a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ea4bb25d0f3116155d1f77ca8bf51c8bf48c3a6183299ec1132bd2fca92165a3e39bba2c6cf074c3822ad942e9a3870000000000000000000000000000000015338f1d0fe0871ca513168f25ab1a801bfa915aa03f569e86bc71e2bca55754fd0d834cbcf9d5fa38453226011627ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084249d816cc6ed2cdcea62b58d7852c19bd586ceb3870f36be476160c336abb874e5449c7458a9715a520602340315b0000000000000000000000000000000001607d0545f1d2977d3673adb80063442458d519571bfbac599542dc331566740dc9c366a860dda8e78d15d7c15e30521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185ce194db60f6250688b869f0c7b26bb758d535c35e2fc1308826781c52fa9f168ba6392929a0a762ba8713d3800f61000000000000000000000000000000000db29e64fb43067d1eda7e69090c8cf5145c7239966553262b7543eb5d536c05fd7d0df3f631cdb8926074a0baacb8d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015265f76c9923b8462a2f052637a3172ef371164f75f5dd59efd49b84d4d33df53040de25782a0c1299f0fcde0074f32000000000000000000000000000000000b9ae1f6ceb27bdbf08642f66eede79b63917000c64c88a08ecc4fceb4e0dd83a5448a4cb66e7c0c4bad6ecaf7dae19e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113dc2fd6cc3d2d3d41b8573233ab54b055448288088842f5c74c3354b3566227de84b3dbde9555505bef60d349da28c0000000000000000000000000000000009c77c78ff364592588221485a64867933267f6ac15c454add80d4fd22e4af85d872f2ec36651a3167d901a34bfec11b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac42c8955d4487bb2b2e3a9a76c94c2b9b53ef636a949e8318158c76bf481013512df51f6cf9620132c80497d14269c0000000000000000000000000000000001d96c4dea5e0166dea465e490034b31242a8c3225a3f7c048ede9b05a732106c4aff5f099136a8222bb9785445d53b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009665f6e8a77b02be1cf251eb13488fcbbafe0697b7a6ffab02cd222216b830eb70bdb6d7b422258332057244fd45189000000000000000000000000000000000277f279f30aa9dbf6e8e4ac71eab6b2f166b48e5ccf3acfec4df756a8eb85d5fd1e7d1877acd853741c3de70d36f2081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011373b0c5de75897f5ac9a032f067736bf1e9a18bf3681911f4bdace09aab2bc9c3e7425f401befab054a16eea09d97500000000000000000000000000000000179226fe77262079a1f167982df566f7c2af78b49cf2539d7b273f02c81827200eb8af97683ae12aabbbde5436bd9f9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000368ec17b90e382b9abc8a833e647d010053af3152696d76bc89d4c84c4860562ed42c04ada7f8272a6969dfdccb5bab000000000000000000000000000000000c167a58793136d67436d9df1735bc0c53370f216b4aea46cfeba02b2072142b2c488048ad97f58b38441d7175c1f30a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c7ab8731a68c8886043f2e5caed45b30f79a0142f374f99b30f65d54dd5350f39e8cbc59e7fc066a0e5b47599b0de90000000000000000000000000000000010c8cdb86060ba474f03570d100488b1d70ce313ae98790687b5c201c27f638b91d6fb28e7ae858e0bb69e79192a6f201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b54e262c824b32353517637986da2e6aa2e23053a5c20426c5016f716b1bee0f5a753dc7e0ca15b7f4f53312376c21000000000000000000000000000000000ad1a8200a402136f9d71abfbe8cb745169eb35732992bc8cd240c4219b9ade073daf8d7cc96ade28a16aab4335158de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3584599dadc7a7f55902fa94d69404c33d78def92dd1cbaeba6ab60ed61885004716bf4749662e3d285ab32dce464a0000000000000000000000000000000013adefdbaab3f1aac72b4fe8778ed01c4f2fd65874d73703347e6d6c714718378dd3f03592b77e5d889ecf3cab10bdc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000452cc48da32937293931d463dcad00fb4a7fbbfe449376b38d3942bc84196552a5b66cde42adca0925dd2007dd7d0c00000000000000000000000000000000078e47899067070d935303c40c61b4488e8993c0f4c0f2f55019c74b1bd0404a7f6894d7bc5fd55f7e384e9a00b271f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b029ab55cbbf12314af058055968d3a9de7c195cbf6bba84cff23331bdb49ebb205e668e2f403cf568e640decd20e00000000000000000000000000000000148c6deba1af3a27bfb1a69b9034701178d290a058211b359b7b5c28dacf14e2e48cd3e737318e1bab2f52bb597b45631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120a25de8a703f4ea826264a995cf83ee441582e20cfc64168fc9fa7970d668bfa0167fc81d121a19abb07dccf960326000000000000000000000000000000000440942721fd7054a9e42108fd92260afa5945ff7defc210bd46fbcce105e1ea6ad707132030489848b26e89ffbc34b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067584e32b0a6d395511201591cd505778b26622f4f44692ff33a48844a87e544778896ac93fcc963f459f11500851f60000000000000000000000000000000011038b1a7ff10e7aa31dc8730a7ac9c009da3fd0757f233672856923cbc785c9ce419eb9f26be7cdde3e5cea696aecbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002458897a574f44145fc9e3a01c82bea3e4d7cf3f5f746eb87c8f2680bd9ac384b3e88b4e71df0f2c438a61c216f6c2a00000000000000000000000000000000177ed2ee1bdcfed82236c9001af939391028f183aebd7d78e3a59ede34cc61282b967faf6a7af739a8c9875b9f7750151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009792bc09a1e30c4f67c0e5932c26950de8080ccf292c7cce5ff02bb47644adfff5c9da4a62a55a50b6187041f6ac32f0000000000000000000000000000000009bbdd621ce67fc75d01d7a7a1c33eea3fb87f051f9d161a7598e0e6a65751ae9458b7f9287c42e26d65a93436904cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001498776665e429690285c133b4292f3508628a90e43d705590e14778b8124d09e883fff8a4c9747d437f58eee524e7180000000000000000000000000000000001e73af4f2f1d506d0ba5bdfbb2493eaecfc26107ae75ac76fa6295bd6f7605cffc11c04dab4b7a069ff4d5bb596c2d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ed45cb2432a31100205bce096050f8be2579a68967f8ff6178c7c76e87c2597029668784afc7e32d9ddb39df3b2e89000000000000000000000000000000001905f497d5d2f30f54f1eade15f3f3ffdccf14dcefef513df3eccc95932731d46da3e777ea02255283e3bff107dc6e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151e56a55a8a3a75a6ec7da7f3ad97e09641875f9f7c076420a4c61fd93f76175889fb8538469deae0e334aeb4cde8fd0000000000000000000000000000000006b701457e0be02c0081f1dd4b29164667044291a329678d558fe6d6472609ad94355e2eba16c212cd388b4c0dcac9d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176b699913ce4a2577dcd3db9bc21c1ea73e6ce44ed4eb1016177afe6a38ea6b75f8ed73a37e9396f702698e691f39cd000000000000000000000000000000000bc4e399065a23dda4cf31f1956651a110247867560105dbefc307a431e61030c8a7942cda050db8486581facbbec74e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ad2e4bdd58a0596e6c1280bcf4b97baaf67443277bcc174befa306262085d05fcbbeac1371d988914bbaa012b860b00000000000000000000000000000000087fdbb7c0d258d24df98043e10e40f986f69dcd6ca9f1d5d2411a86be1889897af289a51b40909e635e0c3ca941eaa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fc3ed2d4f44251a1c869fbc2c0f4509d347b4e3e6d3faf0ea0b42b2fd474323476df128c007be0ceb54926d2fedcbd0000000000000000000000000000000006eb94e026a12fd27435aeb36ac623c65305fa941b5c0e047557dd71d019827b45d4e9b2a26baa9273df0d1a03a9fa8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078fd3c1bd4f816e48c01d175cbdc60f6a9f5d053ded7ae21d105e0aa3a1a749c0544b901f39c862e2f7e651e80c2d0a0000000000000000000000000000000011d634735d8c4d91dab2106e99071c46a9ee2fed7aa30d9de75f249dbefbdf0172867da9f8b734b69168e7b5561588461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086387505a17cd30daf6f5e462e224d4161dc4a308fad82658551c38848815c8199ae42d2e6af16bdc272b1b6513cbe90000000000000000000000000000000013a2987c8eec7ff55cb3cd36058beabe1021bcdad80561ca702f8147ce9b3a2d756df41595044ccc8df7c21651b566e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001485fed6024ee50f26b05f86f061d50872430f5a88457aa187b57a5d3b7cb0dd8efee006db375d5c1c70bdb213b8d05b0000000000000000000000000000000002f4e7652dde9da8c6bd37b9603bbdcdde0f2de628fcc133d51df5b396a5512720ea1884b4f98bde5a343296a80cb60c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103cfcfe3d9e929f40ebf81f329dc63c1a8117c93f18e060c80c68e88cca715b8621e6f864f79231eded1921ae04c602000000000000000000000000000000001398c29a1a8585f6d308f99d3a56acb2eabe6736cf348edbcd03676f6ac3976325afc2a3639ffe7079b42ebeb88a222e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001141d80481f45582d4d1be602d0a065e2bb1e93619fad6ed9fc643560c8fde3af9c01ffb6a461a1931ffd0ef816d74320000000000000000000000000000000000a838f1b5718d5b8de8b6accd1b49c920261992c9c82dce8d99c02a3289bf9cad37fd458c5574334190c432ec557dd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007281a214ba7e92b4c9d76b5c048eac4c970cae5190a81938983256b9506c9d3dbaf81fcd90604120e9d743df86d60600000000000000000000000000000000120558c4998f5c07d64a6686f18122bfdf873e1f97b13133ee8bd7264594c17babb4f0f270d21a2eb6916d5f65c85d1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001902af0399fc9bb169c1a64925f6d1bb2e5b54ec8a32efd47e31b1e639ad440ac6d3a43265f47b66bdb75f960b2e099b000000000000000000000000000000000c77c24dd3969b03d68e04e6978a7fd5d1b03f2cb0001ec1947d8edc373c2655b69e342d46300f888f09b561368dca1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079235d06a7efc54cf53d9042841adff4bea22823b55531ef51b14acb6e58ee25c80107979b2fcb0bc22c8fc9d10a58b0000000000000000000000000000000005fb88b4a80d56c78c2e46218511a37108fb31e9fa9dc8eb3e7cd5c559a18bc7a7c35b83a9cc9358297870b43af0103f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bf4293d4148ddc8c80aec8b512ab6d285588837b381195b21d8d09f3cace7cb3b2532d5bf1cd97c2a18a0475d6be99000000000000000000000000000000000ef0ce84181c1834f52bbdfd409f838ef70710f7c31db946b8f825648505bf08a57dce5dcf541cfb67b987c22861bab11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a1a1fa2095db1891e3ade6deb3cb8c1458f09dada8d02dda37790d3408d1a3f3b646be4c571babffb52e4fca4ad3ef00000000000000000000000000000000027fe5d22981bf45dd6d072c46961633f66f3eec09df47e7875893cef22a3384efc76b7410c1dd127d0a4356cf4517031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e2e9a83d178dcbd9af498f243f89e00e073f49cb041a9305a168f54da1efabc486c020ebbbc2ac00ae0274c19761810000000000000000000000000000000015ef2ad8ce539d04189915f8e8418dcda616e4d65056842f72caff3dce98b0d975737b4dd7f9474405f61173dbf781101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e42f269dac1e170500cecc68c902529704f8337148174509f18565645f8aa59b87ef772d7bd702a6b0cc38c28169311000000000000000000000000000000000d682c2c1f0ce5712163cf9c087ad4a72a2fe4530afa372ee9c58b8471aecef445b30da39109d7351c5d69dc1d2504811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1f5f8de755a26646002182a1135511cd2f231a675d83248efbd216e722a5b353e543b55e3aa25f6f424c11cd749c75000000000000000000000000000000000a72db2586ae36f2bf9fc5c0028fd8a2c8542b87ac6523b200ca9191b565d43c013f48faf2212e4a1b515c0f0d140a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a2138c81bfb8d55a7a743fe280eadb25587c046dd693b0253dc9fa12d4e840f4655f6a1228ec5e6d21c975d6e322e200000000000000000000000000000000103ac8246743940ac842659972e5feddb992c09a1a39d12b89e8f05d8b0907427aca7dc03cc826a70352b572d3974c861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012188eac38d09f7d8f1111ed2032667266178cd9d1d97874f01574b724dc5e212cafeab63938a7e1b976d8c437229dc100000000000000000000000000000000184a53da6e59898f7a942e1077bf4999780391c774d457d0c65b8071330f4ab42438cba935979646b2c7e58c5250ccfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063a405105eb730478280bb4c12d3daf56b5ade5133e11eaaaaf995004fa83b49bd06fd1218f8b69a9c9e55fb9038af8000000000000000000000000000000001591ef398b9dbf06715b53a26c5532728ba4dfa41cd89ac257392b30932e8059f5281e40076a83ed640210524447306e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e7f44081243d8574d7ce0529330ac1e5602de5be468162c85d224daa7f2a0c12cf179cdd0521bd80299045adb4076e000000000000000000000000000000000844f3ff8ddcee8a3b83dff1660bff7c964379980bd90dc057c737ca4f0f5915948acbb308ef5448a9a43e3307fd0a901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123333eb0987e94ec732a461c9a55a244d0c4ced073d95ea9e5644fcc6e55130f4d13a900d7c7e82c03df624a12890d50000000000000000000000000000000004c3c4854c8b97d82fb223815d0f858369cd06cfd0c85ae38ce4caaaa1689835f0cff7b41de3b09535051c2e6a15eab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c1e8de4c1ba3950a57975e03655d0aafc284611daa777e4d7d39c97556f3d3a2c1e6549d48a9d00214417272da524000000000000000000000000000000000f8f75d64939dcc3b98f9e366bc55a4602e0a862283765b60a83079fdfbdb2e13f7eb5632d64db8b08d529cd554ad5591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acd6ab8d657773ca289c10046a4f9733582ea140e165562753dc7f0bc088eb5e01282f3afbcbda64f498f85baffbb0f0000000000000000000000000000000019faee6f734069450af8b8c1dda24e967d35c662503bbe982494710c5afa830828646db550f61a4002f579ece55e3cc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d00ac49563805b0c642452d957763348a6a8d4705eca327e1a2e76f87d5c841a0ce282502d4574e5fe584098dcd44a000000000000000000000000000000000bc2bb11026c365e21d4cbad7975021c93a4bc696233795267ce7ab84edef7dc8c2f79663b9b1b88a36fde37187758af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001568b8cd4a1ac261b765576fbe33058f734ce17d9850bef78592540c10311509b486715b0d55971bda1ba0993a410ebb0000000000000000000000000000000004eb6c3e030d791dee4c786f1a607f5b3cd9ff1c448f1b1fe1b880031a833f7138e7caf8cbe4f5ea083b8bd00f6188c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000223df77eef43b0956cb14076e38526531449896a5da8320c290bfb448b0c40dc18d242bf184f658018487e26a70c0cf0000000000000000000000000000000012d38c364fa8b787ab2ca2de82962e3f81b67895ecd273b6d63ea88abe7d6f56d45b09da74b959a8467e87767a95f7041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000349f0884e725291bc3518bfa6d5802cafd1c905cac0d00cd587fe6be7cc2d58fac49e28bdc8a5dc5f3d4e59c04dd790000000000000000000000000000000012413d2475d98108523212b8ae74bffff236d7d980d7d07b1711dc9edf8bc7234a61243fe0c48626444888383ce4a10a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167677937ba9898b0848c9329b0f442b00896bdcf38f1a65023edbe2278d1d47f06bb9ece56aee655eed2731a8f1f8f3000000000000000000000000000000000618c1438f46432b58cfa042bdb535b69bfae91716d05558297f99a9b22e84cf8249909a10d98450867123b743faac7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060b287e2a5b1aca8df91d805cbcf73a790b41084728c1284e439787db2993c3a9981ac2dd1a7f93c3e1de5b3c2a6ba30000000000000000000000000000000005bab38e0ee20d088db20287def31185572bfaa5db4d7b5f015017e32b8df549df5661c418618d3cd6ebd44888841cb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057328067132bd75a551f6108da018bc2bebc7789d77ff754e6bf9f5609bebbbb56b7482751b6cb5abeaa9d507e5930a0000000000000000000000000000000001778e80c8ff9647bdc187b257c00e34d7a183f2174fcbc38501b3b6a3651681ba98af88c81c1716941a0d7e80bb4e541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d920dee21d3e44d6d27bd14c41f49ebf7fa3dfd136e7b7feee5ee9bf43ae9797a6b3ff290b7a3e074c6ed850819f21000000000000000000000000000000000b6cdb238b8a3d9fbfc814830d7ce10ea71f49094367acfc2693ffa3637c847d745c42d176fff8f03c679f73d6ae4d2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001003e84593ff63e4c4b7a0de75439bb38afcabe5c6b9a087e737ef4cb1e8f05956cfa48137d1f26d3a3b555c75ffbb780000000000000000000000000000000000d7f19210a5ffa6926f46d492be60abd160741339e549572c3ea787ded63b53d62b8904e162d19fc0ff962badd6b8a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077470cd0e716a383ead5186625c3ad47309ac77e08654810feff787884d0e4c414b094c2c77f6e08b04c7c5280301f90000000000000000000000000000000013b114a6459a4f33ea4813d5dd5b753ccf418014cc718652bf1d574a80146fa3b26995c8c67673799c01bb45712703121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006508ad991570185f389409fbbfaf619103744729cf158da3b8995b5f8bf302bc0b8c137a94f95ec7c3ee29f3a5024710000000000000000000000000000000006737a7af173d3fdc226327b5df0d5c86bbc498527c524f454956ae25fa8d134de0dbaadc9a40880fc3a7bcee0a27d931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6c907cd3abacf79edc6d152965b445897929eb5384f803d38d1dc260dc2298ab764d48f29d8f5cd85a639543d17b82000000000000000000000000000000000cd123e96c9aac3fc82fdd4dfcc05151ec04b755e8e52111c664c9f4b2998d6eef2142e41f3d04f4e3441d28660e75e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc6905c971c0df26c7a82517acc21b117dd2204bc5612ec157bc819d421e394fd62f13a00c19d4880ef0572bd25e06d00000000000000000000000000000000001b2e3f750043fe10d8e1781e1cd677f405db3cb47648cf855cfa21bf9f1d80bde6e31e8a333d2da89af25c5a00e1341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6d3b2bfefa8b83519bb7caaa5841b7522dad456a6da16d046a33575cb30ceae709d55fd758861fa4eb6f2d517ec81b000000000000000000000000000000000fe252ec76ccbb598e5848685d048472e8f68d5a55e67b57ae52e9917fc5b3c68cde435106dd1f5064c2caacbe0ecdcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d9604c6ca1948e4d15d2f4d1e6de191a6ccf88264c6a69fc1473b3502cc64cbbd3c0de6e805e4e1d2f3ec884bcab9e0000000000000000000000000000000015f249778f004b62f7f432a2dd931752195885a6726acfa9af5211c5f5710a4a73b6d373abf7d2136b7481d827a211f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002410d56330caadfd9186a95d184216d19e9bf94a61534431677052d1bdf5b8b9b2d55a2a5a18459c87ef1b8049dbb8c0000000000000000000000000000000004315b3363b9e6ccb12152bc00d3f9dfc138ca538a9149c72ee6ea367e46a95d78822b20d39b50305032049e78533d9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016434f8c752791545b985212bfa0b213548902a6c1c996f935103216507a8e432eb46a803d29642666fe0a99674757970000000000000000000000000000000019c38ecb62e6917600f7c8381dfea444a46391353b3628aa3a33145bfa0f1fc6c50ae7efca19f160a36f3dcffbc6dc631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e66925725fbb5285d52a2c09687620419e3baa74cc2519cb1c881d6a1b1ff191bc22542f3cc3fc55af14fc5714b2c300000000000000000000000000000000184196315e745ba4756b8cd3d53e3ea936ed4e8ee47ca336dabdf0074356114eedd1730a5ca8a7f3eb0444ed812d9b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef485978e910ebe2ee8500da07aa5696656b1984a2e8702c63493201053a3871511a38b9d3b0a4f009cd2c6a46358f000000000000000000000000000000000117d0ffac855b6beea17a726a7fd66d90f1d35e59475b139007f4e83ae0735e91d130b61f81923d0059e8a9286ff7dcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006185d1ad02785a38ec700c7aa1787670794850a54ae1e144231599fbb430a8999e4f00e892bfde88d8e91cd0103f3040000000000000000000000000000000014c1f6f5018e6b886756141a08a8cc9aaca478a8292ce59be95115e20298fa3a8a5ad4436a6b9a8feb801008243139421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055395a15c61502e8cf676187a8ee4c07a9002d2d3d1a6c5bd0cf8e64a7e7a9a10f69a4f13275afe5a901d637a6bc9cd000000000000000000000000000000000d310857bf3b7e0cc904641386804535fe1cad339b8576d0ec3035d92c7d2cfb995c9696a83367b48e2345b5c273797a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071f4537b0eaae5887c00bfb0995a3169a0fcc9ad571d28a7a5c4fd5cb0e231a20c07c598ef92ceee6a84561dc86816900000000000000000000000000000000055597bdd0f41005a99b4ddd9f8d5fb8d7e353df90d4c6b7f906d675515b1dd5ab17f3afaa6422bb522cedd9f2fb33401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186a7c38f05c5acf62b2372769669117bec525d8d89359f52b5a2db0806242283cf854b1c314b8dc1d8dcc58bdc91fb4000000000000000000000000000000000c930cc6a1aa4e91f5ab2e0447613a9b69b0384d8fe577b7c34dd1055d0e89d5181adb587c6bfaf64f265d8740396ccd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a3b0c0475a29b42ac358bfd7b3ea674e1a9f204ed1e92f908e5a18715c7d4a71bac04b7b3e0a2317cadbad77afff1c00000000000000000000000000000000085b6d81a1d1a4db97bfe2bbefa3d4e05dc3b7deb4cf975742129a8c33aacd41c5903191ea930af0922f4990d2fe90431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000708108158ac9e8e99b248b69d2f9c7bffa52672d3be6e2a1c5ed8ab55c79c04c74f2a9509b094192a17cb718d0ad7d700000000000000000000000000000000135a82ab3802f57c05d908e1293e5361ea425be2ecadd8ae851b3bfcfe09443c8d0209590a6b32d11bbcffdbdd89ce7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009aee69955170db9d4285cfcedbc3d35b61459a9b3868cbcb6b8eb469e9265a3c1adcb9f68a65ded00f13c4a49675e57000000000000000000000000000000000f080eccd4c199c88316c228446614b941d73b50bc2faf1fe9f794dc72726c54e9406553cae05234ab085bf2bd1bfb9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000db63520c96251283688f97852bae7538e9c762f4992c28029b0d1f5941a92e70906d49e27c64ca69c61abb9d37659700000000000000000000000000000000094f43d16d02ab68e85d49986d4f0a3804bed0f22b45ca9405f9eefeaaba038c6964f693f0552c2f26b87c1908307b4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016034a8d5ae1cb7252c0587b8819e0dd722bedbf1561613f3fc1407a61ac3cf50aa81f4031d9e837ac3e5f535dbbf04700000000000000000000000000000000037b8bedcef2e40b81f4082d9e83489f6caaadae825f9ecbba3d7a61fcca22ba96907ef3e87a60820832e9a18c0da3ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109fe6c5d1c991f5f1ecd97466c9b6dfc361a0983dd0b303c356d43cb4db39f0b909077547bfab0641c93f8f3904f77300000000000000000000000000000000154c4f05332de6b79d2040ac20fe9faa5b7bbca05705f73caeebaf832e26c85d30a9b5da435e4159e7b303e1cf2322771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019c50e2ce57936daea1a0e8186849418ee2364ae2bef81007240431c1697aae7e349d226ab9f95ab2d3d3adb32a67a500000000000000000000000000000000006e7c4c17e9495bd021edef9f1206878b7fb37b2b7dc7cea3ddae80b116d816221fc25ab5ee9ebc65cea02c7ff5d7fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001732df8b8a8196dc1bc35c41fe2e7b6ad40b17abc41a2717515a27415484942e2263508fe70642b6d396ef915b0bcd10000000000000000000000000000000008627c7a84e3e7366a966cdb7859097e4d5ab032b37692215cce3d6646c294b47182d0c31a8bee1acf9b2b305d19da121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192e9a49506cda4d13736550a386f87ec34b9caec5927f6e09eece0b3db7c72abbb417645f8e02de71264c480627b32300000000000000000000000000000000143785a4f6811869bec77494c27658d094c0f1a9c1e74ef5513c86599e2a077794cf01536c2e1b0b96117870c99bd0861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136219ec387717e54517cd80a25cf440ca2223204e023759ce5a3c2c7245dd43103f764004a8b589fa2ce0cdc55526ec00000000000000000000000000000000193e80c9af397fd2ae8b48318fa1a15a251396fac90a993a4c78afeef1c7c91c19f3ab8874a92ef4caa0df87204a43eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c46d10e2990e076de07ddcd7776eddb53147265f8ed574ba63cf6f2950416df58973aa298d501188bd880bc50a7f2f0000000000000000000000000000000012f0fb44ba0ffd24109ce2013d4ca1431df5a8b58eaa264ba30fe06e9cb2141c663335a3074fd92fea3d0445e235699e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d7ba01ee498456bbac6e75709cdb8a1d0921041dac84e446f7acb821e2cecbe2f3d5cff9dca64484e097bfc1020f69000000000000000000000000000000001426579234531acba2f0a14fbfd730ba2f470d6d2009427600df5e271be5bb9a95483b2418e09ecb6fac9ec994db8b941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001587d7de5776f6c3154035af574c25a1238078940de8380f5abcb4dd0716b3edcac9ff5db3cde96adfe629b24c3c4b340000000000000000000000000000000004cf46db82cc7080741e33eb4e14e905ff2b750535a8d43657fbf0f936ec038f0b239a5c620718bcfed7dcd18ee47a3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061325b172ba4ad7eb20ce1a2eb2ca242da9522f9f8ca0617061166e27d19884f10304fe098534e941846d8d0e510f6d000000000000000000000000000000001160fdb0f63dd20763d50f46cab5c4ff1121870b6b105677cbc1f6b0d31fafab20289a9f789ec950bf92951240516daa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001620f4678c14242e3cb398147789c73739fcdcf90716e9925b21507ffb3fc8708e043d216c80d851d126e76eb3b4f6db00000000000000000000000000000000149880a1d8b2caa34ec2150bd71f6e145087be0bb436f7d57e65f674e75f91f5bc0ba1ed3a1d0eef4ded9345f6dc58391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f770e891788042e8da8e0d6a28adeb78fe42cc8d80b541a05feff27a5b162d053c40e9fc1c558064a81f449ad7218c700000000000000000000000000000000139efce42001c1105b2bb301c75a26e1d093dc557dc556102dbc0c12e7b584363f3a708fc93ee5eeea47efce748072631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d42870b296eede640e36befd6a56762c5528ecbacab1d26f828ff3d9a4199e1aadf4989ee9fd928d378448006c3ec100000000000000000000000000000000139f0adff5e9377baf84913788839acef8517119edacba63c62d47fd1a4cee06c3b31c76f35c3d4999771005147971271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e62e7f7d3bc805958decb4be93f7b8e1c323eb4bda22d988e6b623788440940b806c605b033d380c085a7a54130daa00000000000000000000000000000000151688efdff162f00825090f0e6962aff6956e0fce11b3c5f50619d4a10ff6375e8e59f8292047ad5385634b975d7e431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5d6a32934cc9fe2b75ece02a52f13f4d2bddec07ebf0bd87e6f9bc3768572fed736733d339890b4cfca046d7e3b9700000000000000000000000000000000017d2617cbcf3029b3a024e5f87192253a85b05cf658334d76b9b7afb555169523f0ab2015b75c6d50b0ba627f98b6d541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000614a92748905741006e49e144e9d07a55fbd50f0e6105d513a1acfcaad203f5fbfd2ae1ad0c7967d8f0a0f092263e040000000000000000000000000000000014684a9ad9ba0dcc46d95b6a853f0552cc195e78a294b5047f90d4532fc3ef09846fe4618d7cab5168dff1bc1f83e3831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec2b1d68581186abc5e3a0a1a4a3500c3e2387b7d206cfeca37cb742f52678a9fb7028d613451464d544860ec45b4e0000000000000000000000000000000001053a980b671f45b5066e7dd65627e247daff1e4e9a111b549e050a4bf55c690540d6f5c686a0d10217b57f02e752e381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d6f0d6c0a2b1330dc14788b0da2f9fec098b85e26256ec42269d28c297ce563b9c6089c18d39cf60631d62cc213d6d0000000000000000000000000000000009a939af76fece30c8d47f45831ed5358800fdf1bd5c765e79921bea3fcadcdd035fae86011db453cc5927e1a0a292611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086d48d0dfd38218caac55b596c5a5502647e0dc64a22fbf1b56cf420970c5b457501a3beb0e4f5398bea461626eb2140000000000000000000000000000000002719797d6689956c940420e6c66c2e77470f2f396f2fbffe32a6f7a3178c7f9edf29d7918d3512d6ece682c0c5472fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c22ac560d253e6f212a74f88484a03536dd363040956e72ee9341228fabc4263971b08b137faf1cebf665f72d9190a0000000000000000000000000000000003d93daba595e4885ed55d0e809e062afe4cffc654e1c0296d622a752b225bd2fd951624a90a0b055e840dbaeea1328c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071228a1bb21f492b8e80397cb9a03bfa897cf24314f5e39195a3f90fb2d4c09fb9f55e6262fd8939eabbc3333f1e8380000000000000000000000000000000017e3dec06c00211c754fb628de5d7df7ceae6243ca8b535ac619acd93dc40f1c1be2ba8c92ce991899a2ccf1695a9a911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001872601b4212fa01d443b335e6244982675e842826e875a72f7d0405549da22e46f728cb35ba073f9eecee5b9caabcc2000000000000000000000000000000000c2afe425e3ddb4f2d41921f792c9edb86296990bb1d5b0d84e70bd26aae306f46443f7a7ee6d8fbdb807b6ceae288371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000028902d7eff252eeb7ebbf4de3a481a5cdff5d36541581439d6701750c3eebca45ed3e0bb4d255050e1f9c1d5f1b26f000000000000000000000000000000000feab30d6f386103e1e01dabe91cfc8ab8aa82f395a7f86d72b91eda38436855f5add9cdd564fb60eea78a1fa1c033be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188fae8df2b9fbd86ed21e2e2f90be5886ec5db6c238d52870f406066216b0b4b5658eafe7c9e265a9a936c0894a351500000000000000000000000000000000119dad0641daab1c23ba99228bc38c16f8c09a656340c720f502918b8e59ea1da7027f0546b3e6fb48fcf4815270e37c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147d6d7524ae2184ac718145b0149b9d72347596eb940ce7cca9476c674641062f1d55128c676ae52a70d3b07172fdd1000000000000000000000000000000000f3aad8a3659d0167de805aa7ead7680648465e0093fa2f96a772001a2d7551c4c4c2c4ee0c6b1e6c5a52a710ba03b631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f374e7e268f5beb5ecb001073c7bcd5212c692a910894e26901d268b4531fa49f802c15eaa987bcd5aec88b27defe5f000000000000000000000000000000001171102b3eef34a3938b40443051417dd8e2cca86b0101d24a5f1e6b51876831aa7b2752dd4e5eedb2d0c98e2734a7321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3d92577fb2d1f18f8d7c0f8941665b5128b05ae773cdebab3bc889452af61c6cc89204ff65f8ec2e5aaeaba336d9690000000000000000000000000000000016b4e5f95ae838789c411d2bcfba7d17732cf2bdd96e7ff567b8ef94b5d7b80f59b0cb35e874c869a48d8428a99ce37f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001499285a8d67cae5e1b71f6f4a642893475c4123f1357c5228297f7f1e0533449f81e2aa596f01271dfb8de7f02aeb0e0000000000000000000000000000000015b504d899a1b02d790c2f646f15e97e20b6252ba6a56fb49735dde41a7b33c6933dd4ccdf4d02ec5dd68389bc79f8341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6a79aaf9a049991b7b776ece59f7917eb9c50e20bb533737baae8d5881964915b5ebf5582bae471ed33fa3db51254400000000000000000000000000000000085a8e1c6290cf6069ae662474fa006aa3f87a3838eb2162edc8fa7e2f8595716cb730a3eacc80f4ce323ee2968713381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd2f004ed843b76cd7a291aebb04e3b266d91d3d1ab8e287b9961a54f97b00b87e419f97a22c0e56c32259ca243272900000000000000000000000000000000161e8e82f06d704b6821522b64a5fc759325471ae98208b313b42eb9a6485979fd0da35ad221d6acfde9a15f9824d3701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100951df5fda90b78c6bf2a8a27d4e2fbe1ca0294644afd99952f10234f159b74f83c7f51aae7d7386ea4eae076a5ad5000000000000000000000000000000000efa6bab032a516ea6a08b2931dca5db86b927cd87e25ca71173adb3e0c322ec5ace76129812ec4d2c0c892696e288091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000541fa79af313a4575535bd00b61ee5b1c6d7cae431856017f8eecb925f1bb6e8f56c25a29f3b483d43f30c37cf1f73200000000000000000000000000000000004ad6fcd8965a58c77b3ebc5f654fc8c7719eb562d543cf75b9f5abc1d1b3f9f37a931b5994eceea3d869584d57f69a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018193081f522f57261ee8e93961c791b2f93cbc0d511536b76312413f7f070cf07f6280a030862d16945b80c52176ee4000000000000000000000000000000000cf169151eceac29983fdc0b1c42bef19dd657b9a3c6b4450fe71b29b9616ec6cbf9841b3dbd1b540f8aff3759e0d1e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006eb192b75d41ae7a0447975d343b3797e8876c6386fd6e13ec6d7131bb7ec400b5321723b369c41062c1cc2a04e3d55000000000000000000000000000000001037ba5338cb2185724e4d26d3230616f4cab4aa7da473084b1b37f3c171fc3cdb18e4e2fdff012b86b0c2369adf0e841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1682c9bf0907c46cc0a2120f2e494dd9fcdc8e0814284927fe404d5334eb2f584331663e3bad863328c353a66a35d00000000000000000000000000000000189209dc3262e36f42060b6687b9dc3b092362a80ea3783996a12044c564744bc5fff921df27e95ab61750c8a238567e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbb667a785537d6e6d906802f24e85bf4afd634c31ea5e3de45d5d31dfdaad327463a434c3c8c56b2fc3e916cd00f0f00000000000000000000000000000000181f4ffa345991cd52bba3850eeb88af2940a8ba834cf49186bc278eaa4ef63fd98df70e7e9c347d79cc3a62dbd6c6621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4f333ab73bc9a758dac7d1b2e69471616a7c76b37dbf3bec9e4845069dc5c2f7d54fb126e3b9d61e0e2f29918cbc5c000000000000000000000000000000001298abe5d5f47c4dff791a318c47701ef373c76aa2b1ec4e6eecca589fcfeda05b167fb4f1618e51daf104765faa10f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db516539454b7b9040d44bd0420464a0174c9dd6a992767a8106823329f4b63c580b13cdc3cc77bd680fcb83228a96600000000000000000000000000000000112fd05917627d464a4cb60dd3991d7b472adb6ee14528a36e3f0af680be72b526452ff6bda647d310fa5c620b0744cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000532e78ec3dafb9f957e42f9c49dba5c821a076af4e337d947f17a1756b12cf144850b2d9a27f4c4126bc2b7d64a844d00000000000000000000000000000000145ce8a6318ac9d2f074f4e1b5e8c54d869b9b35398561a09df89805520d94b7a04b38ca98b6fb88dddafc153837d3351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000706a516cd06e73076e228b4c2fb036449611fa4307f6bebd0975c1b722968f703ae431187d1a5f755eff43f8b41cf740000000000000000000000000000000017938e6fd63059c5d6409184a54776aa789c524a0b1afbcc26b6065d3ea4662412d125348c3676a6ac43e7e4d03718c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7e3c36698faa1c31b68ad1ec22f51f08b658901cf49976ba7a6158e958a11b30033c82a30181e36812acd6a5d3e9340000000000000000000000000000000009953f382ec63c6e7e27c5255a859f91135411bb4c7bbe172adc619415f32bec0ce7b6c5f499d80220ed5060079a92ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c98fe321e413395e57fc6e3fdc5e8a9c1cb632e347b272b4866f7eb42da714370a97e7897c8622a0226b279f6a426d00000000000000000000000000000000004c975bd7d5723fa35d63d003c90cf3eaf1aad036a307b6d2959c99deb850516d2f920a176c3962355a72a88e9d4fc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eff3e33676d0ebeed03add1476ce79ade9ef81fbfa5af0b1a5f3d2ce53a40440a2cfbb8f6810856e46deb01a119c4b20000000000000000000000000000000011e5b0618ec54c2692c9141c856db4949ba347041ff318dbd15707afc682144afa088594975d2049e994ec93ca8ce5811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170dcbe4c867bbec261e69e4d1135e4a6ab521d6aec9f993ecd5e3d17315302a16f99eb036851957184c56bb49ac97d3000000000000000000000000000000000ead6bbddb0cb90c3312cd1b92ea1bffabac5030e7be5c6f4b7102d05847f841c0fcfaf6b53907e65c832946586eb75f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164c4b4acc15075d253e298bf0fa64f664a0c6639db88f0eafab3ca585510e6b54949e4be4ead8d4e552e9156a4fa878000000000000000000000000000000000f9c290172c6c2ea7cabcc7778698c908646444e975d28f03638999df8193e378b9e7b0c346ac2bab44e47c63d5fb8011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b6fc27accf54ceb8326e0e99aa7ee5ff9209f8f6ef34885f49063aff5fc612d82007c51d89b1100c752f8239c09af10000000000000000000000000000000017261bec4802fd4b4ac34e6a06cdf591a063dc4dc247f84ac51fecd79cd7a2fd669b740373fa0c216e6661a023da7aa01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a8c4f6eda083387d892b14c32150f4a4714bdbb12f847a410e70dfbe74908cfc8d615b5a0717855c48a32af7ad140f000000000000000000000000000000000cd2580f0196192617029f8681ae951aa2c095d913d301da1c82b048b05d139dfcbc7d466d726ffa448eb23631f4a9f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd156f3e0828f92f52581a07a065d8d85889ded1b0b738cbad08f28882e518b93e3ac0f924276c6818c88826d3ba658000000000000000000000000000000000b1e4d0dafe9596cae9536cfcce7e523db522234cecccdcea9bd579e111bbb907d7d831f0de7e0005b48e7fe001a08c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e1792bbd7dbb479ee2aec11e9ed0b3121942bb82526a02200a31c13737b6dc1ae05a295d7db398f4ed6c3115aead3b00000000000000000000000000000000005663f797aa9268b36557b39de35c259ee0c7af49d7c2b60f1e4f58aca95e2f3e73d9eab0e9983cae7e9b6359e2fd081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e5d6c0936574a108ca584098e01f72dd5160a68fdab44ca24f23427b74039956e1da01a9601decb9fac8b70d2a42e9000000000000000000000000000000000b43c96316a2902197d35c9da42a5844dcdf32e117ea4cdbb43b80df488acd111efc7b1cc7bbf68427685d92d40351ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c35ce21d2e878c5d1ae4213746329d05550770fac80ed5a8dbb46f54b77908230ab9e9067c88586fdbdfcb5fff55b000000000000000000000000000000000c6dd2a68e6a80ee049f2c3d3e60ce9f72db75e05f4c4b2c514874850f55ddbf4d62442cffb35042c1f8c554574d32291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004169e872b20813112ffad59cb043819c1c780d3e160de7cf12ca339a4be912c4c39b6a514ce876c58a69d4bd8b7c8b600000000000000000000000000000000096b300c0007bbacab9195df89d273582f8295374fe81fc73342733bdcd42a1047f2adcaa7a7c8c2c634b3cfb9e4cea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1b6282c3b03c52e646cd8c2269acf48e06658ad8b10ffb925f21ce47650795303d0827578bda26b89fb88d0fb7cba6000000000000000000000000000000000b5ba78d0c00070bb5bd2f278c51b496a14bc571da8e232f0a386b4d7abb52761c3d50798d9280c77e7e8ab8fb9bb9d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112673a3caa7f0e6845a24f85c41977759d5a4d5f06d50f1f501b89d349fa92b353b94943d8d4ce4f7418f789269628d0000000000000000000000000000000015ab56834fac5bb3d374e0b57783c5cae1020ff08440a73c64ef15fe0fb6ab08137b3b224aa9bb3b3ec450faea41c1771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156c3e7b78c5aace14d7ee4071f5f91d1f6bc0ab2627158b4df4744a5cf1f9afdfbbbb4b446b572da73530d6a4f9517300000000000000000000000000000000042adfb740b021d90d6e80ee6be60c4301aa65ac8d66e91226e23e849d757c1967d3451d4f08a394f0e0dd82680adb961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fc3e013b44b75671f10fdece84ef84dd45721bc2d558a733158b70d44a49a9133521096d8ee99710f4cc403662f8220000000000000000000000000000000009159c4fe16ade0b58c8c8cfe91ee564d98c5a126ac64f1f92f7e1225c43233f20367b9d2d885c02ac11d1ed8b60e5d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004c4c42d227ccd9c0c745d9103f3592796f0a1df5da7d07b5daa1b4097a3f8e1db6284f38558afa06a8129850e8285400000000000000000000000000000000041518ed4f5607fd9a335cebac12922634c79ffa21fbfadbe4fd86066ed29fb5c4fba4c26c4aa5602e7943b4e2dd37ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144f7939bd3a503e123bab0aecb3fe86acf9309431e48f63726ae11cdb121dfb7cd4df23dbdc388e48b13694404c5a7700000000000000000000000000000000188ecb65dae4940be167fb649d14787d0ba0ba0b86199815e850f7a6ebae9a1b25c14e8ce47754944d1f752c43d987bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f9a123ffe84d1caae6a752aa6f6faa458ae5285a2cdf3950996ed3044db942732402de77f4300319eab84a924a4fd20000000000000000000000000000000009b693431e49923472e1e2e40f82674b293591bc3c76f20cc0413baf454ca9007ceceac172336c0a2794bc3c6cd8db851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097ec2280bb1506234a181e08e1a9f0344bdd20e0d008b622b4e08a208f673661d090dcc314d1948968771271f4a96c1000000000000000000000000000000001385f6160b4f3106b370758c3d5472fd561813b18c3bc9abfc78ec69f67d73f2954d2499ca1329ffc46b5e98986a50911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000804e5c84bf37f9269e630da289e5ff50e77764ad19b43d5ec57c4e3b1d12c17e1fcbb64d923c172fbb4f1097a955eab0000000000000000000000000000000004cc3569eca32f83c7cbc71312774662a9a0ee3a99b12f0633869198c14b950a200571a2973c4409e3423cd67c2b91b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001afcb56c1690fc1cf71191e275717d688476d90b22143677237cab9d6b6ffeef3823a7e525c981662b768d59a9c468700000000000000000000000000000000083af25a46953881dea78dc73005c233979bcd1c25d3f07dbbb128b78043ce6274a79c927f241ae682f81ce63cdca5711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007defe49418f28f904abed1c8866efbd7595065b8f28469bed7c493d6d2f6e6e8f593be20cbe4b29a8bedf2cf08646b10000000000000000000000000000000014649fba9d2f95c74c9b22b97351578afde9aee8bd3716c9357b81a0e3a36aca6deb9f35edd66eb904d4d044c1c2cf691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4dae9a9fe8220f95551e919ea6d714d7cb6dd73e33cfac9f15c7e73f94016e5b1aed07b50d29eb475dd7221d431a7c000000000000000000000000000000000cccaf42bbc200f7c6c3bc4efdf138325919756b36103e120e9a8b2ac5c3ec42d981bea4649cb09766ec8f719c056a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1e1cdb155093aacf3a1afd711cad4c694d63674b0cd7842df6884095f7933f8492592cc042649ea70cd91445368ecf0000000000000000000000000000000001eef0fb70f777deecec044a998fb79a620b30fed52891f96605685650c7745f5d6c522d99afba98cc6cbbd50f5297eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fd0196ac7b4de4919e66687bc86963e1770e9db4e578eeb2b283a6030817c45cc90dadaf70e19daa459da36bb9e24d000000000000000000000000000000000afe1fb7a2dce7ca9fa2d6f349241e8fb2ac2a712a8aff1e15940cc01cbff3e3d7bac5cb1b93fe0255ef702758a085711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c95c17593e2160473962f6775504a1992bfca655ce6e207c9c40295889f6bd3988bbb15451af79b27306f57a828cf07000000000000000000000000000000001064e5e187c356ee674158e46fcd03da8ab9891d471a443034f32c003a53ac81de9aa0adc71806ac308b3ba6fd2383501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183db9a3fd140a49ab53704d2661117bc60305410e7c088f753e35a659de8e0aedad09b3f3b1732956adec4859c4dd1d0000000000000000000000000000000013ca5511351cbb712df2c5d8895a60e02b2c28af39b1647a3e56c1b6378603b1811d07cac68e1cdde03afe85e0ea99541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1b7992ea089729bf7a5224e64ad737dabfb789eee95ff82bd1356b6c765548d5879585d3b0330ed5071f218c705acb00000000000000000000000000000000114b963127ed55cd158c99daa1f921d2f7ea0a2f3a7d98da3a66d1738fa34dee72ce6bdc39c4213ed63acd9c803394e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029010c65975636648464c0828b47b4c3c4aa75b69d09e133eb1df2c4fa999c8302dd277bb1628f713ceaa0c8c9b3c6d00000000000000000000000000000000086b1ca94a9c80127bb6f243ec354a84f54fc3330c5b667ea9f12ebcdf2bc4fafbff8c78bf362ec2600f4b2e81d959851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3622314fcf0cc6723e1682538c5a65ad4d535e2fefb884aaa09ddad3bcae874ba4e5d290de75fec79a4be052d98cde0000000000000000000000000000000000a6e0aa2c47473a5a607f1d555af6ddc0fe2ac1ce824fdea32ac3a6008e9e103a5d140e651923dbf7c80ca9a8a07aa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8d05724ab947b691e28ed8fa57601e666ca9283c1d05809a7622db9240dafc110b8fd35bd358a31983cf7398cbc7ee0000000000000000000000000000000008e0be0255149f195897bcd77f61fce2161458da965a81eb7861334fb6769977db0abbca42de61337dc88aa537db23771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e9035623a9b1823046a9e9bcf1981366926bab6d33b10bf3651023571846b7d09467c224c4f90b0cde13d092288022000000000000000000000000000000000f06f13456eebc2208172ac1f33c3d3e16a2499978ddf9cd9ad7633787a79a66c5a364df6b418b6526c95b620bff73301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001907e9bfcf7ad7867817f59b94202cba059d83c604ff0b0cd4f8cf32ab55143819850f95803be57ff55b699aee00c977000000000000000000000000000000001152f0fa26cd14b1c79fa79da9532e62ec2a3330d06e1661e4cff82c1b2e144673be00c0b3d867bc8979f2de839f7e001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cc878433c0dfa238222347ec16a05c7c068b6f5cf75f2945ab910d81c2f7afe6724e5ac8ac164f715741f70135e7720000000000000000000000000000000010ea0e52f574b667dcfb80863de1a1aa06925a5ca2f8257ee5ac064f49dcbacc79f9d964625ed6a201fc920f6e648d411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000648d4e19f5a8eb871a1b5314527316d97cb3b8184c6f22acdf6b9e57da17bfbcc5efb3c53a0dada168624ad9b1266b5000000000000000000000000000000000ecca5627aac4da54fac0c839ec430ef6b75635ba4a5832707eb156e45f5149524eea43561dbe8fd5229d710cbd5fdc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000995e3042d9ae1a0b72c1f7c444b5db9fdad0db7fae649025f13a0e0d73d576e957fbbfed5cd8e03be363e9123cf7cee0000000000000000000000000000000019d3342291f41c7983ce2f253e84bff27ec965e393bd770963d5eb0333aa0878cf8b9c046177179ca963876ceedceec01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000874854849586769455fc679507906c1b0247ed4283936e319a287705463fe0a33c84d6c09a7ddba523b70c24c293fc20000000000000000000000000000000013389810197f7582850a08f30264f5da25d087154f2c2c0f5bd4643493801b94ee154bdb389c71f84d670e4a18034bfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7096dc6b04c380113f32a61cd77b6c0dc99be18e25e57e0aa6fc2e340948c4f2f46842143b90348226efdc7dd55ae70000000000000000000000000000000014d73304f950c062bfafb025174b841b0c16322fc7b1bf65b6a69b6a87ffb1c3d57312f8b17df51a9a006b851b0839741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011849a6f1fdf85ba3e01087f851f4bb445bbdb74f524b80bb2e4c76fcd211b88d8aebbd19f8551630daf3d4b1c265ea8000000000000000000000000000000000086d087527eed86c2725fa2887def15087a17eb87b619ac3fb334279b11acff2507324e775921101dd82d63d52976d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130374f11ea770df36dd18cb3831040edfd87b1aadd03366119adac1367d7ee5d758938866369db7918ee4a848da5cfc000000000000000000000000000000001577d8d05d586089f107aa9efa19e0adf19ec25f1ccac0747ce7a44727be111f7e1f56a547be8a2aad98892deed34a081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102389ec9650fe78e523e8d9b1fe4f3c3f065152c26ae40bcc63c960e2928138b48d977634ffd97527ba131a58b7f9ef00000000000000000000000000000000145317623c7bec3e7d80bf5c4a2f34d524e968baf6afce4106c07ade26f16501416fd83279a283d45666a59c4de7225a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddfb47f525cdfe2dbf677b340cd1041c88c304adcf7a9c02e0a348ba18f5bd30adbb023671f5ec409da090fa5fba46d000000000000000000000000000000000a1242108cb0c57aefbec61fc8a620f1806503fe7d4b1a6a1c7168569a62f393567ec999a2be2c49f4d1cfdc732ad67c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018067831186a08baecea61bcccc34d3a61941c8eed8ec353942c4c8587d26d1726776f26367b56a6554adcda1d541e9400000000000000000000000000000000185b44c48e4f7a186cd98e498b1dbe879a04bcd3662d8617e1f7aaaf2296f35314bd7534e25de6f564b20e85f1f4d9b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002223eb133c8be9c294ce8585d5337f0211d3871cc0eafc1448343813da89dd8fd942509a650e7008d309bcba384fb0400000000000000000000000000000000004cdc07299325b20cf278441e48bf005f39178ee1fdf69e7d0ca792996b660211114ef633608d42718686eca33afeea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9264235969b3c5684d817a5c043a9f76546ed2d5ef358c2a0dec0edba67224a723b71d172f64fdca6c085a4dae0107000000000000000000000000000000001548654b9910a573304e1ccf34ccdf73f240c96a7e9ef46be1277926bea83d8fe8f81e8af3fcaca1adb47a6d1bc4062e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ca1e46ebc798e92445a0aadb05c4335e8dcc711a90977a180e919ec3a7dc73cb18b00756edcd5d095de23275f3d3b500000000000000000000000000000000046be4ffddd250a949ef5d9a8e3fb8b547a70efcf683578f242d11b848ae15bbff71038d066adc4053fde607bdb3b0881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011444ec9d095cac7f8f0b4cf320635d10577753f34fe56e76d5b28e84060996fbbb9cc55035b4b5c1bced7cb11313c44000000000000000000000000000000000991b1a37e95436018cbd0be6b068d4e6f802d782cad8751b463999e22e408f91d48777d4c31e2a63d09f943fb9473141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135b47ce8d62d23dbcf43513499e997b50bce59906d94633374015ddeb74763f1c7f445ca4bbf48fdae56fb95fabdb6a00000000000000000000000000000000024a7c43135b5fbf2b987180a90a2ae9accbfa22d1cffcb582768d8b31bbc31cf7fe9a82fad5e4853effd2191eef94621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aebc6a46b961b7f06bce58c83cf5c2c8a82247b024d0458938abc6e22f0c58cefd109d1ed19f63b3fb9d038d0853061000000000000000000000000000000000ca8a05aa3466befaa77473f321621ccedbfb85e2fc1de8d91e1c68ff40155f9db2a53f566df2edd24085e65e47661551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3677f0d9917b8e7f0f940f0b2ee928ce15679f9db66277d64b8cbe64a4b65fcd61b8eef79b95212b165fc573d1eb370000000000000000000000000000000007485c772f91e69d5b8bbd4e081ee358189cddf53e37530063772abbce1994d61519e9bb5529b7b2d2b6c7e95d8f09881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9a2e2bafb08e4e3de3e0decf459531a63b66385450c242c1d18f469fd6bc54c98c2603eecb86434aaadef5974119de00000000000000000000000000000000024df245829b7cea913cc77edd7ed76316394276763d97075b70125c3f8ba19c5adb23f974d7ba548aa880210cbd68a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000581e32661155b9eefd8591c2e1fff3ac409d7ab9a7866d48c7fddaddd550ff23531a47161e5f0e03b123c395668f171000000000000000000000000000000001437d9f01a837dd478fe17c67a8cbddc62c94d65b99de9d462474115eb258eba7cf80dd99de4f763cebb97399d6e1fb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d4acd7bfa255fd826788c7deadba60c082d9120e7ab2d6e79a88a94b8f0c0d82b1d1fe51cb85fde889aa19adb3d28b0000000000000000000000000000000012b2d20a8e1ba660a537f9bf0dbc7ab53a72996d8ace255c8fba1a613b09abbe916ec444d2701b80ca39d09fff46adf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f57b023f8be03965ec900852b73bab809d9674480030871744b1089ceb555cd40b0ab3a74b7c566b9eeab018455a40000000000000000000000000000000000efd21f0cfd87f6cb99da29ab03e518142c8ce8f7a46264d0437fae8a2358492ff0875c8c598556de5a877ad167e33401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f9676d650c0eedb68104b990fa0d6b89971a61c380714f20d36153237ae5e2757daf5badb50b214960f295161973a900000000000000000000000000000000120c6fd84cb97265da18a474267a9a7af1f4327f92b18b5d22b3cd6692ae5e1e92b0b82a2b7e817bbc3e162b64e991a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008f7015de3a56dcc09bb5e87e0b3a47dcbab73e0b3ec4e280375f5c1b820f175b360175edbf16d23f61cfcd33e8db30000000000000000000000000000000001914eabf620052971a87d9eda25e98c2b92a94eaa9bdaccce4c48c2b8fcf9cc35e5e6354bb6365c61436a5ca63bb59d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fd4331fff0d7b74b2cd455aac382298211abd2b774a53529ec3b93041390edd6150468da836699ca993de3a6be3bd2000000000000000000000000000000000994ef7368b1b2bae34d2748f0e12514399b69b43492794fbb7c45fb2ef7c36cdda988ee05b867bb8d2f6211beaf96421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001028bd49d5b03f6c546fd66fa20aef9bf8304aa9678fe6a0c910ad74b494eb99ef709da527763cf4fd82dc6e275814b9000000000000000000000000000000000617af35c4860cca38e17b1aa9a603a22a4f08655ce618152221e6d52f72faa735d99efa88030101e87e5b1d460935c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fdc8dae7d59b823eb70c24dc9037874c2039231d2c88e768200b9a15d0f194d0fccf362064ade9fb88c53e3dd334c500000000000000000000000000000000125cd42aa2d0c6bc79abb8ef38578361af12c586d342d016bbe8116c5c99531fe1baa16c95020b0ea6c39e5f079b3f1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb5b1a777889342b697f5bef0919bc0a3617c7eee93a650be5370e861d2031bcd7880c788b1cf40345aabd96a4eea50000000000000000000000000000000000b7c5be7d85c5774f7f4581297a674a8213329cd55a6bd64d27519c7611ab099afdf970b7648c19cb68fc457a62429271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034a99ae8489bf29c8d37e54ddcf3844a1f284cdaef9e8775bcc595ceba444116c352ce972ea7fa1aca2434f4f238c620000000000000000000000000000000019c2b8717177d7de8011efea25523e88187bb2fb5a1d85b57db7d0a29a68abf2b2723ca3ea0b3827e7ca190953b0681b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000608f2a6aadfcba03f91f65f1c6f911333e3bc3ca50e2060dfe5af5305c00f485e3ddfe32e88e67804d5d4cf9b999757000000000000000000000000000000000dc0475a0e78bfc77eda3c3ad1c92a352b65f0d99db47da6d4d7ff967fb7715b53ef408722bff08f3a2cd2b2523c2e041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008475b8cea77a15bb5fc457bf264846dc05c47b927b0949401ee94bea619554c714fabb604fb406b972116e3a00c37c00000000000000000000000000000000014776a8e78e7d3aa155e890717048e27c07fdb5068e06247fe370911213c980ab540fc93c0aa41bb4b44d14e075cacd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014d89ad78c92dd2a29446b78cd6a6f3031b1625d20d50710da8afbc800172eaf68568c1303ed4bc341bf4866d6a1d6a0000000000000000000000000000000004abf2cfc1d8b701e3795e6f48db7e931958f11e11969eab2cf3259183c26b07e37a8e4f78360ecc453662aa2c25c89c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bce712b99a779b3be31a8c28fae56f29eeb83c181b30982300e42f6ea382b35363b0a7a38bb0b2cd1e9e18da292e0e0000000000000000000000000000000015926512d9a0069dea49310c36ae19b4fd2021031314f7e4ef1e59bb213fa2506edd8faeed624ec08b904de2faacc1bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dbcb9a6a81bc04fd4b5e2cbef6fd758d3514f2ec475d939b09fc6567c94f5966c561e2ef6c2b530e96918802794539000000000000000000000000000000000b0c63e4f8f83cbfb13a7c4a2554e767edeb6bd65d648d0c729a8637abb9af34b974e558e2884249ef0f415bf83df56b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116c9bd0a4bfa67a78e6044e44f255c8a75d61cbb5fa1f4314addbca7cfbdf24579662b0cafcd9fe156833bdba8325be000000000000000000000000000000000e2025dd6a05625dee5fdd93b3bce77f00fe36c2cfafbf60edfe807b90465535a315f56c8d75935b843b7c33d21da1931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016165beb6c6273343e979eaea809a65d4be9e7bfed856dd7a07fe3e9e62706c5bf7b30e2ea575e241100a439efc4044e000000000000000000000000000000000aca4996279b719adc1dd95e5d1587aee80483504e53a75bb0be1f48193fc01a5b0e896055085783dc57c93d783e6e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001640b2796843db11c3fc4f366df9a6987c8f152c5d0ec1f94d4a2e7081129e02a14c58f126b6be174c44f4c072c938d90000000000000000000000000000000013f8264935ebf4ed75ed9279c5594c986a9f344e4473acda058830d81848eba854a96fe1ed6202652099e635ecd3a59a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f2342fffc9b84a32aecb30f4ae439b56e914d5368afecd887a9fa5e4fa68d4ddb20660b596fd93b223ec65aef086f90000000000000000000000000000000017045599ec201cef97d5404e512afc2a4116724e71547db8b9013d4a5d958f4dd4e4475254bb2bae879f2d31179849601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f78ba4dc45d5dd58371a60877f15b9e47acc58c5229342254d5a147bd93312da21b66f2e596e49b468b1f4715d7f1800000000000000000000000000000000152b7d1bb81e9adf35c7d380909da7596326d36cd8d45fd411922887d1d8c8e58d2388500cec9425a64212aa5daea1311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca4147f154e1b915b23168f573956f599a2253c5176e9a2fee0f0710efa5e89d2f90b12a304689f1a086867eb70a9e80000000000000000000000000000000005174d0c90dfeb3c6b2db73d09b83289b52a154b522be6f068d07bfedfa4f1091aa1f713ac5b6e100fbc2f17e17c2d8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bb1c917e8785ae4f4bdfe18108c9ab2a6d8772b6ba764a5a662b8524a1e957b2724d3cedd03e65017d37551afefd3900000000000000000000000000000000014ad857d22f19e55a64c9ceb2ce54f6c96d62c503bc3c224e69d4683d1a39125978a8bf65931bf903d8da94ff51ed341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151e8870c9d9681a70b64cc4bc25dc9b803eb013eeb8ed0eefab48c841a3eb6b5f9563f7a76664845018cb435bbc8ebd0000000000000000000000000000000015241fcc18bd49b069c49ae541a57a5abdf1e920efe40385acf1c7c64ff5e0b5f81b7a369d4b02ed9490ac7cc0def7531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003323d2a87678203cc54877c7df836e53ebac12d9d6c280f6b54ef6b0d17f2e0a65ab4345c3965d47f7df0e3f5ed740d0000000000000000000000000000000003fd3af23a6caccd2f80db3905e9f001bc5633fa5c4170b8c54770e3fd8b95f40bcc50e7e61c68df19e57389de670ede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1c7e8c5e6e629b9d8de1818ed6b63bb7838a7b8eb33ca8cd19aea33d2a6f4166c70b86ad58ffb15139edd401f7ab2500000000000000000000000000000000038292d6fc281883afd307b75dd3cf5188e812a6e01a5d21caa7af5f5fc60c409ee7fb56205696961d0f013c292da2921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f429f22d2eaaed99ae57ad1ace58f8700ad4d9e26541fd801d74eabe14c11626cabff59c36e39f6a12903a1b78c210000000000000000000000000000000000ccb99df5b7b80f62f129111127ee0dc7259a8edabacefefafe42c882a8e5b9623c22a4a6b9fde272d983e534e1a991d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cdb148cd630b78602c5da04aaa971b1b91c6c7210ffec6de2fb132a2b20d907def6a1742d584ec6b6c72ffee0116890000000000000000000000000000000010f791a223fe8fa561e53fdca268c65975b95c18176767a4120040514b0a5eaca487d639e4040e3ee62c61831c59aa121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120916fc4c1bf20923f8bf02373c3f62eab0257ddac78793365953900d9cc9379233453c9d516d281111355c5118cb5100000000000000000000000000000000034e3288469df59cfb33ca253f90337d1501a3489401ab18de3ed31019ca77729f83a589dd20e7207276917b6a740ba51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000177efe5ea7115ae661dec468d7af5f6350fc58a6df8f5fd118c066bdbda2e0d6839448c7e3e9659f5d96b4c6bb7fe730000000000000000000000000000000009dfe0a8eb0bd74fa27eee1e0588f3d9ba61cdd1ed4dacf3df2c0bdbc668c98579f4079b10b6ebbeb9c5954e18d806151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e911a1429736bffecfd8f88cec05922cdbd235956992ccb337388803e93fe6d472bffa69b6445fd3bfd7ecfea8ee04b000000000000000000000000000000000d31eeff680ea08598e7d6e2a8363dc64ecf68f8aa7ed4b320248c03925f47de804a3d1032304a440db826adbca6bdf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b2a9415184f0d79ce8f774bcc74a5ec611ec43928768ac2b531f310bf0c4947d4eb0625a97bf7a168f5089122e4a170000000000000000000000000000000000840cbf61df78fdbedbe5975581a5e7bd41b19ebc61e8a0541ef2abc34f5a1bbdf9afef2d6c9713c1615cda000fd8b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a83040679087e5e88a005c69aaf4ed4e9c01c511b930f2f234aaead4b4df52aa89deb22c6391fe314ae93e8438038a000000000000000000000000000000000790f5f03c81805b9f238bcec04e99f6d89565988f85c70a1214a28f29ee6b487941a0e0fb121979a02dedba4d94c6b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112c67214a585457d14003d451bb4e1d2cd82de1b4ae8132f8407d1c5f8bfa8b22c81b220186d1f2de4abdf49a9448c00000000000000000000000000000000001c30e3a774a60110fc6fd3da7a341be0f9b783320e6834c6c8bb929be84f1eb2ef6761daf3a700f8ae6087f277dc6df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036caa1f4e66f153257ad4b44865ec4f073e395856118b04a3445372d3c6e941b3962a27ccf0d99ec242f095fa908517000000000000000000000000000000000943e03496bddff6c96d69d633e49328edb49b5eb97f1632bd8d29167448e0b92e051b892747d9a3521830bf7d69f9cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dbbe2a71a450988b380624c928fd79ee3fe7324514f6bba24abe9272766a0a6f0b894521f63a5342eba95b4cb5d8b70000000000000000000000000000000004f612e2eb3c2400e45ad0fad3e5edb65948f4bb4fcffe5e235af21338121a334cf1b920fa78a331f1d64d62f78902fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da04ea8aea344e5f5df1b4bb3b24331cc234bc3050537997a502643c264f94118da289cf0b9be0c5102ede3ba77b9a0000000000000000000000000000000000e555b5778b64b9767df062dc49f691120e20fb2b96207ab01cef7c21fd7c418a36559fe2a70d0ddd71342f831e2c5581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005aff6350b4444ee4c4907da991a42452a39cf85db2280f962780230e0056db723b113b5cd6e54a18a51ac811d46c7dc00000000000000000000000000000000058e1e75dde66beeb3309691f8e7958620b51f20e46b6bf9dad70964679bb8d1866ee17cd91a8de3d608d817df34244e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154a5031ae67d378d507e19fe6b1572b1cbb267a819f083a3c06642d37296e4406545f4c31991a6fbb4b9a88640398c400000000000000000000000000000000130c6ba58d3a660cc9324a26a33183459c726162ac2176004c0267f0936483ecdf76f2a0270cd820b56035e29d99b7bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ec5c6fd52b295b6b4084e67aee813873be442eab6793f18520862843ed36a3725c47c76bd34520d45c93504ce2e1e800000000000000000000000000000000065bd3eeb2fdcd19ef458f24f9b7ac6c8736325e55fa728140743ed8899e75cfc133d7eab743e9a2a6ab853bbabe73f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018786b3153d61fb9a3057b54734e84e0419da3ed2bac0b1b2653d2253ea604810b4dc5df2cf66e92e44c607d5845baca0000000000000000000000000000000005add1276b17074d1622f3bcc93f1be0c544c1398fa301e1ea95373eeac208d1d06905ab995a50bc2f4aa726f44136981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031f9465481405c1e9656a1a1b93fd4d271e0c1c3e86a38bef3e54f0acd865c0576531a3c0988b8d335ff1562f36188b0000000000000000000000000000000015b2d3b56b1b7c1e30f3d4d7d0fd03a2f0a7324253da551f04805233330208bf07bb6ae1ba5cff41bf793553c1637c681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0bc38ca3ca1636d4142a41e65e9a201a33dfcd0189fa01a9d67e31cb4f28a72e87e08b1cdce85869eb2562885069410000000000000000000000000000000014618c3d92be0492ec2be0ab1a058486228763e1b0e67dedee1fdab4d0eebb9a4afafad5be4bb4db8a4ce43216a78aef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8e4d431d80e96598d258901e0cfd796bc27d8f023a3fbbb583df311fbfbf292d9404ef6540d1a6ce34ca0f2bac3b31000000000000000000000000000000000bd28e5570188c7c316797b0579a5139906fa42d4751be15437a8f165487c81ce8fd75cf646a7fbe4ef2c5d3143d1ac11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000320c17a19aff64752e12764363af9d46493104d537794c46bb2c5b9155cf863f5d9212dac52f5b305872b6fdb600c800000000000000000000000000000000007758532f15fec81d22e669a711b3a3e37c88947c1fca58cbba0779ab5fc8af6b52a2f2bbd689e4b46a920d3958f45af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bb78aaf07d53a0cfdff0d7ed685d4b8944e2a2560f730c524444cf97bd40632654e778c15395207ec2fa9ef94e70460000000000000000000000000000000007f006a31be4be21c7e7417a1d535581e833cef211f3182a864eb2e93dbe86ee64d28fbf9f7be47e5dcf93d42b25d81c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e809d0ce711cd762010b2da69a934de4a09e9764a135bfb45fe4e8e8cfae7d1cda014201148d68a7a25d75788139ea000000000000000000000000000000001147856996f11ce95475fc9e8d2599c26bd1103a976ff448b7b3f96f78bd6d77798b9f166d426334e26f156cf2f27b751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001392a1e8e24f607a0a6f00ff9747fd1f8d7de472c542a56c00102e22d9f2cc0d8b0ff35a3a54cac20ecef25aa5d3ed96000000000000000000000000000000001672d438d03110ae1d7333fde735ef164ec03bbf0e1a074045c619ce988d96a9385ed9f2731a373f0a9a76f8e31a2ca81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d845c4b71e765b7d489271790f08ca9b009eaaaa4702956ff7854d2b703f95568cc6656f72c3a31b6328631e6045a2a0000000000000000000000000000000014e7c6b2b055d2db266da3f7635dad731ac9551489be998a995aaf28d2bbce0e7bff05f3e5f364bec42c4172108bbbc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a80fa372cb49f5e66a9e7b5c56db05c3f141f52ec1c987a7e98cb0841a1cc8ab59622f45beabd7622f805b162c1d08a0000000000000000000000000000000005374402d5f5b09f52d8f072c1880c78910a28e5c510f55c82335152cb1fa9a4af8d735c7d2e069e5a779df8433eda471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001069583f1f3b45057b91e4460d728cbbfc18609823f959b8c78abbd04cce8f21f5e594961d6c6458698286408a8b52f20000000000000000000000000000000002ad9013fadd9f8b2c559c63fb0014c0352fd9894f596dc1ff4127c356cc9b4c5930880034154eb8910e7582f37842db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052212c391d999df71e3c212946c286809205d1159b55bc9475f59ad0a8f587a0ebd5fbdaa5c219cdf591bb7338fbd2c000000000000000000000000000000000bdb32b4b6fe1bfc7d96e447620b7be4fd9a40e2edaca99efb86f7ed4dc180a80f8ac11755582daf440fadeedf9b3bb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054f57574d71171c82fb5d3abb1c92d5350709d6b2275aec41b1f8eabdb48290833896d4925e1461f70674e4e555cfbd0000000000000000000000000000000018eac4aaf3cb2cdb5d5243b1738a34e68d7aad42a1f45beed29209e2cbe9aecfcf0bf67939f1b93d30a98ef5750e74051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b35c52e2bf7ec91f41a060906a6f38727da8254376a1c238c198d2343d844820ff0117739240dcec2b812fa490fd97000000000000000000000000000000000ac7e38533ca88b8d7502f607ae9cf91d9d929b85ddd4eee327a766a98592d6549960a972a298e0900fa2f661d1e4c851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1764f43c537f0143c6f01160cc284964d5054e34dcb5519f1de3706d31063d408fb4cb20bd94479445c8725560b6300000000000000000000000000000000001c0ae98ed2cf78cb0ac25153a7d6230796473b8c2413ae60cbbe314d61e3470723eb9b35610f3f06ec70c3ef0b569471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000396e5bf77beb600b6cece5aaf125a304083f1a4f90cfae44aa72e858dd8d8e8e0b141d6a76159022a7517c69eed920300000000000000000000000000000000039381d29dc299ca1086843a1bdedf76604ef78321fbf15fb07f3e92de84cc2e74e3287dd535260ea2e9f19012ed9f6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f3af78edf2ed4e6fc01ff29ac963f0cbf6573e8310224c30758322b80df2218409069d11c106956e94ae9f3c156e2f0000000000000000000000000000000000d1417774d4f11acf5a572bbde0758f28d9fb659dd082b740382bbaf8b64c2b8a5965adf8660f77ecdccdb0867e5eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001325814275069acb96cad37a3dec0545c1ae407a5f50113c6a60c5bad44894f56bf3dc28037a7b6a93c3b5d66dee1684000000000000000000000000000000000139b11f71f934027a6eb3b12de798819aa3caa151a38ffaba883a6e27e70929eb3b563d7bb3ba307697bd7e2a96ad3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dbc7515d691003743727d56c36056d1b42c1ca66747b372c0b8a43a86e768db4530b5158b360f174f93193bf77474b000000000000000000000000000000000034c2c9c482b32f9d0c721eb27ff1da0cd9941d875eae797e846e489aeff2ec6408b3baa7b4ccb6a8fecb074f8757301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fee60d0b028b3be37861a29bed8411eb90fc333320e2eb12887d21f06246b7a38caacbd846b81ac505a96fda580a6f30000000000000000000000000000000016250dfd534a20076765d63439ca4584d8bcb49d028131479556a67eb27b7f7ba01610e53a062da06563231e37bca1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da114231f704d7c7fc1fdc6fc213857afdaa902eae3f96336b68dfa9eb0ff91c91a248892382706cfe856e64e3a37e30000000000000000000000000000000001c44f9834ecd5d7f4b4a88cb878ec190c3cf2b4a2f16509e1ca33d84e7c8efc4846a9a156d7ab70e31d894c70712d551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e4194664198dfe3792a184bc375834376592c7cbe977781424c19e664c0bd17d28a679073ba3e1297ff4752d2b52a90000000000000000000000000000000000aa36adece6647d454afb83cc1d23dc0aa7ce4346ea004cf324667da96cce6c6ed2819aaccfbc879814cf726d0b93ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b2f877df52aa6287731c89dacaba184662e29daadc6aca2ae2abfbc0685d9f2bfac933934ee079a89e4603134c012c00000000000000000000000000000000192d3014c14eecb3c63d8e1e98c8bdc32de3414c65a06f24441a689c86f9761e624ad9acf50034fddaf5c479eaff93761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018214a7f6453f0034b9b53bbaf69316940f1f313af5bf49f6787efdeee8fc3c27cc9dc07c5ec8458ceaa9fb15d94813f000000000000000000000000000000001766b803edb19b2ace02fee6c207ee7377760b30fca1b27e050cc8f89ab39e102ca952a33e6647ecb9c4632f169950ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f31c65b92199c144de3d44e52340a40a086bae99e6b807a0341dae5afa547d6982f8cd20de46a4625756cb69588145000000000000000000000000000000000a36b54929a717711ce0c3aab11f43dcf991d2978f753f45c11ef3bd914ff671844b21c8e9bbaa43dfa550b9ab29e9d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ce157ac22514c3828ab6c4e3e53e05740a2cfd847ce3a63869f9b535d74361e555db67cd5be55f19cc82e01895dcc60000000000000000000000000000000007ce7c88725fc7d53d188e8adfdf2b305298649427672090c670b626ab4df66f2e14d1645a76b12cfb5fb16349cb2b3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8d82eb98a3a5e194ccab916554ea42f097836ff43c2fe910639988bdc063ad64b463376c3c2c289a6be9dc04c10888000000000000000000000000000000000a3aab07c13aed10715f38f20501aca4c6b69a4f6196c0c049defafefa873a907fe807e55001cc066edbcd32194ab1de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b51edd39b5b6461e001297c80b60e89f624ce960000bdad4f680da1ae44c4f891a16f61c0db0ffe251f346d1e8445fb000000000000000000000000000000001492317fa3877744bab150f303d0edee2dde992876aaedbbb0d7b6666650b491dd9319905bd6a85b4b9a18c349dd963a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001459257e78ccf3bf82f00529fa6dbf7b40a535054475bbf92140623e6097331393bb620e8a2cef47f200e231a3a439a80000000000000000000000000000000019d2f2ff813d63e128b2894d67a46dd5fb45d729e6c6e438326c7c471fe371cfd29377a95ac2833e51b194169fe4e40a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e71bb76562528d03294d9411796f44c4fd4c7ca52605653d168be70c8b28ba3790664b3820fe4a96f669bbaf4f44b40000000000000000000000000000000014c6025a996c78ad95bd66d532090e34b5ac9e95479fb7fd6f490a2aa9dff005a9f74aa79dfbe16f401cd2c08f4905171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107bfd6ccd3b1e7a9be262edb1ce55a08f5e87650286c679bfba4d6088bc265c4ee490c9cd5b05b471d8e008b267c4ce000000000000000000000000000000000228f702abe1b18a086cefe61f0692cc151929ae8e07cdf4d33f4d85ed0f54301740015cf7c2fc2fd957b9a45d5245c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cb348fe4d5897b38281690dee14c61920d0064ec1f1707a190f3501e24bc61b839b9ee0f4236b4df2c5f420d0efb5c00000000000000000000000000000000013974a5a8ea2d46b9a709c981d2875c5799ba45bc6c5523380e63adc867fa6b0c33b1794bd422c6b01ad279e3dd85101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153138b4af4123eebb0bf5242b39bc49bb1d7e8d9944c11f6daac2879144cab0fc3a40655bdc30ed804a1d9287726c5e00000000000000000000000000000000025917942ac76cdf20c96a5ce693a8320a0206da64cc2a6cb978605ea4350765f99372f3dd713c2ff11f7b15c0efcfb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e98d5b5bfad6e5cf49b36c20ea4ff3724e0bbec5ac241476410311ecc21c68b69b307ec33ea776900b05116df6dc9a000000000000000000000000000000000be9ea6e8d6893cf5975207b52e226204fd41fee655ebdb9b901887e3735c4de7be340ce6ab68826d999acc41a66d1501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4d431e72d4068fc6516d158900d276225eab74b69a35ef4c37e44b9ba4ff48ed2091af627435d0af2243c02adcc5540000000000000000000000000000000016757338f57046fe8b2edec642b2a4ea5d500cad331aab54a0241f74260b342713264bdc678ba98e8ff98fa0beb709fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ca9f8d241535cf61c100d2697fd1b0d9596a5288cd1277a2d1b1192914eb270a8c61e15ba9e31b8d885512ac8a70db00000000000000000000000000000000036d28ab97a65690ec2db8a35ad74c56c3af9124d01fdba76bdf0462b7e2b551b28b34dfe0ef641e684f8feb1ba9f1b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc7e468f401ed1da5f4b6a970e8ff35d75f214220e0ed39baeac2bd43c6f052567abf29f99266c7cd81d011f6cb1b7a0000000000000000000000000000000014170f10fd24a2aeaf7ff88f21dd4bdb0fb79e6428a2ddcf75691f601eae84f26b3208f8901c93cfd63355f405fc318f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e395da6751313835c97ce998117da08e7bbe5993662350ea48df03a30fc65097020d55ee266419739964194dd06f88000000000000000000000000000000000fd9bee77374381d29d8f37633fb3167d65c94a2141a5e20cbc5939a049e50d4fe0a7b868b0f598b898ab43ab607d3781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d98b8c9a2e5802d7778cf10660d1d4dade4063bec355b243b46a9dbd36f7127465e2ee5803cbbad76ef1e198a5f8f100000000000000000000000000000000187f2f5c276b4bc52129fa1ef2f05de3ea2ebfdf6593587f7dd87744ee2810e43bca6bdb04005543339df351b83368631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff8535755b078ed2182ff3a8a49f5890215254785fbbfffa7a2790171084d56aacbd01fb5553a07852f7d1dac759beb00000000000000000000000000000000113a6adf9ad1da55b395782de6ef7f56b44c0cb572bbbcf30f662d7b6ae6710a26ac020d456228a8a879ee834b4200841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e95296679513066215466fd77d5db89a61e962e20ae3eba6f24f402d6823355480af9ace526b42764cd3529ab555d100000000000000000000000000000000008dcc1823dc83c493a275d1c837eaa446c872837e78b7d34328e518df42f04d50ac517ba27982d118ea3f8488e3b3a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001523aec3444f4e16ae8cdb153e8f1d9ca20de23449011c50e1dca749d55c2098240ab85513c0abd97097c60c8f471ad00000000000000000000000000000000017238027c2abf0ff696fe7f98f14177018e378d715b3f98c3d3dc06d2813e9146010cd3bee3483bb7712e8031b59a4dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011360e4586cb6fb2a864d19f54bed7e1e122fb2ea43cf16de2a6c41d936150bb011037cca5b1e9021d721d54c3156b820000000000000000000000000000000000bd5a730913bd277858a9685cb2eab31c55bdb0783fe11994dde5fb1b49b73dd6b6169a5c602a09cce471c2a603c97e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b6e95644d9266ddd8abef08978cb9e84577b71e8fefff1d25f038a645a4a426b90da08c278b6cbb1bb4d2cc7ebcfdf00000000000000000000000000000000032c82dd432f8365296d2abaac4081423110145d1fb17e45edf3093a9627a00b257303959aab46134fb03c7f7643e3ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc217708886694d1e1546078bf41107adadd76b1244249c0d9529fad652edf7ba1bd91ad1644b450d73cb081c4cb503000000000000000000000000000000000fe236ec172417311bbb4906b35083608632650f917eaa1580a462b0370247b8c095ca209ac4765a922077a9e5344f011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018c85cd9aab84571430dc7c9c484b350d0f600ee80090606c493636681e8755eb5a86d334f4d2b961302165055e60bd0000000000000000000000000000000011013b1f59634f653d213112a6ffd0ee7666aeee3c62747704bf3d8a7d77a037cce20181421e906b6282fc9c872eadca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187ecdcc37fae66136f2abda2d83bfb3b16343da7ae39baf18bd89cd563fbff896cdf1274e470eed05c3cdb817ba7f9300000000000000000000000000000000036d96d253b980dd81714850f15861f13291655df7dfb1db24708ff4828901c7d0bfc053c926c33b5c1c85a3fe52ad691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001547a7b1727361f8fd2302dc47dc7e61dd6fea23edf8cc8e77607ebc01bbd7776e134c3b7b5f6ad4d38e76b2a1feae0200000000000000000000000000000000194776623554e3451a2bfd9fde00dbf548b1367bc1fa1b831143334cab86a6300665e84850519de030ed642ce877bdd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108ce08c47afc76bb2b426932c431560925f2c5f5ad38e6db22e6d3662180e5617bd0fbd3f50a38425ecf2396868c4100000000000000000000000000000000002c3728742fe095696c91f81f96b91482d1359f071ef72a222badf186858c67cf3f2196ee75ac1d66ac8635271190cc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172a0509acf8853b256dd02d621111f1062279be8503dff8b60e200eb0e6b9025a026f021bab63386af83989fb48ac1f0000000000000000000000000000000011dd6ba6fa97cc9976b47d18b3db61dc1d16f276b46c4099dfbd8cd52bc82ba43d7935da6706ee37025fbf3a394146e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d697207d18ae9a20a274601a1242940cf46983478fdb0c842670838c29ee0b8038405c52ff9822eb7bd912bf3f1b20900000000000000000000000000000000178ce27d6bace369eef2d202dab0bc294b275ade6ac574762afe72e0af5282010d3f154db39941bcc962f477c73efb0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001068a5b132aeb84002f3a80cdebc44ccf1c9e7551b3114640721e039af73921c2dc4f06e78af033876b7e9cce189a22a00000000000000000000000000000000126454a74d8ce9cb9bb0e00b5921b9e9ddc816ce38e2accfaaed506ba2ad527040e42cef8aefd5dc36608b86cb20e5dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001789bef9dade1971f998f274bb176c0bc17f87fb82482d95e4dc1103a04a705a29a541d2c40203c948ec0f9f14ccd2900000000000000000000000000000000102448edf58f27db4482825e830ca787bf8c4d53fd21dc264c5f35a921dfaf8c9fb36ff6a10ed4dfb67eb1f2d8e6d7e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d842c9a1937c6f6eb8ad2c92dee8eae3f2d6835852bfd60346dfcb67df62578b4dd1ec536201dc6bfc62259a24152ff000000000000000000000000000000000ef6d4b8f5c4b9619608c6651514ca55658e2d32cc7caefad49d5c7d627cc8a4070e53733a80f41656d848aafedb5aed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcd732ad217abb89a936fe170381b9fd759dc53ccd977905cd1048a2e6182f5f12e128504c9afeea633550fe48b94f1000000000000000000000000000000000b2d178d358ef76e7359a06da3844fd3953893fc39ee3daf835e73693d7ac70e42f7f8ba3b2a938e74dd04bc3f2bb5a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b19c11581cae45c9b3d76125314df9883013c3172f523c54278c05d01f60126e0a3661904363aeb242a3cd9a9c5034000000000000000000000000000000001441be72393ef709317448d76957c624938f8d6a50641169e847a8cd3a2916d9cbebf91ca6e32943716c1881916f03851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001127f60282ac550a5ceb43cf485a41cf59f0955d0d8d5505d977cb74789643f1d59bf3029ef5d083325492a8bf72daf0000000000000000000000000000000019a81fd35a6238f1e25dac4e09812df9520cad98fab8baecc04a00d3d687de6d43c291cb046ebb1aa2a2ab56ecf411fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f80e6d946790890b64c076c80fd973222161156a90e66bc41c61cde08330cf0b2f548cc142c568ba51312f5026cd735000000000000000000000000000000000a8b41735ff3367bfbeadb87290494d223acafbdd6fc96a9ccac4a1a637d7e7534dd88064327f41413052a1b4b831e461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe57f65172775f893c4ae5d45c60eaab4396fa7544f0c45ba29369a05b5c3610e1437346d5ba4262f371e190ee28bb300000000000000000000000000000000069a7596e8c82c65c5ddd8ea8c9f608b74d39dfd8e5797b695ea258550a0da7c2bd982a8f1bcfb24cc3a2bd1bf10daa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130f8c5847d31dd5888c11e53ff5543d9d49e01ca1eac3ba7caae847fbd2bd1256daf190885defc13041bc5b832266c9000000000000000000000000000000001628b9e76690238e00d806264c00776e151b89043d0a5c83c25a350ad9692c0c3a76c2c96327a4acb02cdcf24cafccaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148b3fa9fe5708a6bd022e0eee7768e291c0c33689ddaf7393bb8961d86543154bca566feae2691e0b43602566913311000000000000000000000000000000000cf5fe4fe971753d340717a9a2610e6f01f9e54e3477211b2f45b1b0906489cbb16fc4a90c394dcaeef6268bfe2007131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019baf5109be1dcea35e2e7166612d578ad8eafe1cdc8b68b1edc5fd61d9951565c73c9aa4f06c0d08f51677c87910b160000000000000000000000000000000012cff62815ed156824b1d0f9b278f60b4d4d3f312ac9d9b70894c500e0811823e3744a541576b588fccd7d4f688249541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fece9be0c8574a9cf243c773a868aec118407adb29d54b75938558f0941c23d32f5a061899c9ccf16b02d495fc20043000000000000000000000000000000000ba39346401aa9067816750fe1234a9f24f9724dadd761126472f8c59bcccc8783ea96d4e1a91f1f11943a59cf0a1e331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5ede8dbaf49711363b3db099d2d1717b14b4194205da385755288988ef5fbe614c5183c557f1c37df323d7833a74690000000000000000000000000000000004863b2d47c4d3f198eed1067bdb872c98dd19d442f9700f5a742862b663ce91213380942773c586959330e0abb80bd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9056f07c1190f59706e3edd8c58f8380cba6104cfc99c372cc720638fc5b7c3d62ba082fce6726b4bdf5101be5912c0000000000000000000000000000000002e6e903c825e96fae44f0305ec1ff2b7f9562163d1d19ed43a8faf9b45b621a71018f5cedafeafa245788c35b2f49791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d6f3a54b0838f5e0d04f7762f030f208228631d316c2292e9b5625ddf9e23992deb041aa6f7dbfdd6930a6002af870000000000000000000000000000000001743213de89b61877f528f73c9f39755ae62bca6b855985ef20ef9fea29e49addd807adf1805c6b2bc56ea78297e43da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001881632285460b4546fe60fcdf7537c674b75f92c0d35d0e85a97b46b29e164b49817940078b8c4c87ff3cc3906ef5f9000000000000000000000000000000001230f1ba7a7cf3c7ef0fdf2fa3b9a74087ee16aeb3ae32eff8029e8eaba18793f61c1a96e77c192e609308ae21faae6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020d323b0c98ee70b77391d0744243494d40ad59343b6f53848edac72b8f9f47baecafc207385926dd2c1ba6a2115539000000000000000000000000000000000b223e2aaf51f8ff5774d6b126c5b47bad07d7d2c849e5a44f926d0e53192d754bcac761a51042e32f303697a383678c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186f8059f2d094d7e6edf241ab917700fbd966cdbd178ca625ed836d4be6f456c1af37b44841a0a763cf9695498b450b0000000000000000000000000000000019d51fce03f4713ef40bfd506886a07aab0da3044a475938425e8497f576f0b28b73bc506291262382075ec028b6b7081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74667b92ee623fdd066808ce7965cd4e938bf6eb636919103da1f47da6fe5d7af4fead3a5f007198f9095b08014df800000000000000000000000000000000025aa9902420e3356e1646f5f5dd2b845101c4c15ccf687d56e8677e33ee6d0fdb3cfb3b313b3a0ceae8401005cdbf461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cb85016867d6d26fd6555d2fec6f60f0cb55e425ec99af5e90f08b2f16af0995fddfad8632df5269d1c55899513ee60000000000000000000000000000000000230d2973e94ebf8274108dbf01835b0e62a0f8ed70c2a4468103521677d2437dc344d2749c2f5a273c6a5f5c91c2901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b31821d1e4027786cbcbad728209972df08a0c7d2aee94a6f9b02f810b2e09744d446feb8387297fde0e3bbca613152000000000000000000000000000000000e5a14cc17b37a43b8d23d9efab2250a281c8d362ec1e974f33f375b2e7f9801f013b9f69b9f1913c04e4259c11af6221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b839aa36b7b06537ff0e014cb72308c407a775e9f75a3e14a69c578710ff59ee5f79f34427d281251f59f2f035816af0000000000000000000000000000000015727fee06b027758b4a4d6bc0155baf846bce98bf66a16ed3d2834a20a3338c2317a063f6c12ac172cca73ef5cb0f7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000120485ea8768b97f87e3cc11f59cf798787629975ae6c7d3148e6e0f06f50b840090038d3f21c3c8ecf540b2cc3f58c00000000000000000000000000000000115f5bd276500c909a7fd26e37372608c3bb55be4de854914ab1e611b87fb3dcf26d47d72dd9daf31260b924f22d72691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb444c08ea1ddd8a7fdb9034cced4f2c345419c07e748425b8bee30ee799d035934150117ab7ed30b20c21f8877c0a8000000000000000000000000000000000b4d627a8bef0fb3ece9b554cdf830e3e4e2b51534c776294522c461eb81124119cc91dce3a2da9ae1fe67b7c350b94d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ccdb74e8f32d377956c91a1a8f0e6f611cb768266c849c68b581bbae90e9c7f7ecca0e6c3d21821dfdd50a8aa1f029000000000000000000000000000000000d9e734b9a2adcba55469857086f2a2cce6646da6c518a699e76ead4f2b39fd231b0ccccfe639316c70cc8b60ef22f911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001835997583f5629da4eb34c240a206f9a1404ff638b215a47472f44ec53d8161e2d2b82e0be14af24e9f977bc7595e9c0000000000000000000000000000000004c895840fc89f0d380bbad45a998951eca010c7224c3ad09b8c67b57fffc7e4a9ac715dc2992846f2640c59a524ee2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a730802cd62d4011a92217b5a47e345b615006d3338a6bdf86f539493f3c65a02095a900cb2a87e2558e37c12e6e63000000000000000000000000000000000292898b8c6f6a5ae41bf31b814dab69e01d9df350e32e831d10d0bedb2c5bda9c41f5b8c991e21451a7663bf9e719d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001865011b70c3832d4f6252f539588dc16d98392af17842d5e37b03a4b7ddd0b1c4c87a41c96025a50630751feb073090000000000000000000000000000000003d3ea5c21e8ea79e76d3dc80e29d11f2488bca6a28f14a704da5e41bfa99d9bf25f88f3df1baf61631c927a175dc0b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d7a8181075a81886835b59dee0eed9d0772056b19a8c694624675ad3335f74943dc7feab7f639af567c70b85764ded00000000000000000000000000000000061bcee0aa7fc41e661fd039b0e8e0276f531f5ef8a89be48f441d1dfb1c731d7bdc341d3599517da4be25cf316060d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ed06a01daa9671a7a7f81cdb3539d87dff264294be8eebc816d1790e01224e81252d133439da9bad5e26d2d53ac42e0000000000000000000000000000000002e569bde8c6985d91504cee76d9d375cb57ebdc739bb5d3ed5a2df7b83848abde94a995debdc19cac0b77aad9bca1601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a009b393c61a86af9b4014d08f9f33654e680b48445307c4ac1522fb05ce7798bc7a6f5c224ac7f187af43b5ab43ad7000000000000000000000000000000000ddc149fcdf51db41606df83d3e49771e7dd9a3610d23fab84a896f04da404b1084e361a7c9a939e7d12ab6894d2c5771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c09089b878bb691a58b26ef07bca1c578c44a4f69f207c12eb2c64ffafc87e780e769a975a56ccff1c49bdb2a90d990000000000000000000000000000000000c338644f3e0f19e0e675fbc47ccc70f3fc25ce2d0ef664b8eaa97aa30237b36bfb0d46a04c12bf9e2fbc6c6b5f67b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ec59a363f721465d9fe4fc0af80aa8e3393a2188d8f95822ca8fff07fe8906fd522e7e76e6a1d58d1f0118de3432cb000000000000000000000000000000000994b3e9cddd65b2559bcfbd8b538bfd5b6aa7937650a699226b97e14ccb4cc0d478904f5679723d3caf5c0f477a53b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2087e21df1da91336f5c3ddfcb1666ee66335363e01e5c23574cd8f39a3d0dfd044d39baeebe71dd31dd972ebe7eb1000000000000000000000000000000001681c56571fe767ac7e08bf8cb03d1680c5d33cdab2221a5ceed6eb25742c8bc140b8df934cd5157d86455eaf59c4d331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079cec6ce1d188a094734833c5529006f1c0447830d42cf8a7b3990e57783d897a9383f5e2251a13bf42e1449b9c9c170000000000000000000000000000000013ec1f908af9c5a05543745a1f4a7883365f757a73dd8a24dfa28c79fe08a3409806e7f451ae8c7d4abe9174763e20c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175a40d1eabd39cd09d191ec5fd11148515f63eee66a9b45a4d0e9eda27e50bd1d198debf087bf3c6782d1fe364b2d0f000000000000000000000000000000000d58c9f43e4138a6e6fc53322e640befd78dbbf983304a032a23c037515f9388dbd781c08345599dab56728249c791ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114441a09145e8929b881f69c89bda8e7fc3c9568b65b5a909020c29649e2a3e93a0070cd8a425600f0e01b792391bc20000000000000000000000000000000001ada046c6e083351a506a59f3db226606bb5b761e40c8e5b95623a06ec75cc144b6ea4604ac9c192c6ac62a261268811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a498fb2c9a02dd4c9b9410804b4b1914bb42d566c6c101002e6a28e5667e80e0d326d49d4c9c519cceda6b28e806068000000000000000000000000000000000b5468d41123fb55dc4388994fab27cb837f5890c685f1666f6415b94555285df448a7fc8c0ef0a636857f6ae30c66c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a94a17292b26687b9174fd77d47c2d0bc741b0dce8d929409f904b774f917563c9d8b91773aaea7f76fa144cad72057000000000000000000000000000000000b85d8f2819975ec663837b133359f88454db44287b6230ffb23e015d14bceecbdb8e65b32f949ad22e3a329ac82a85d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100ff69abacccd6820324d4652f1b7d208fcbb39d6f6d440cfdd392450f7d06d09210946fd22221c53422dcd239aeaf80000000000000000000000000000000008ae8a4bc94aaea601c3ca4c8c537053d75ac3e97a1787577084459d0b445d2f1e939aea3911c28cd79c571ca402001e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d170590491b00a645282f79b012e1735f2342a57c5dca848f3032fd82a72efd7a5a57375c699b7d103c2110685be6b4000000000000000000000000000000000cfb74d7f007f8820048e9b213d32a5499cc0494a2dff396874fd38656fb6cb3a76892f02db0f2fb81b73f417c4e2a731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160c1f3f87f509ac5993162494c85ebc82b4ad7c7683e120c7f766c7b29599454a06141b0b316deba7d5e15e1c2bc47d0000000000000000000000000000000012a9b539eef5a057b699b0b764ca87d820b13b46154584efa36ddec5398820e5a2de91f184a32605cd357cb0cd52bfbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2d142b1bddd87f4e3ee229876fb4318eb2f1cbaf64773c5d2c25cb8b6f18cb8fbdcd2d37d859fdbaf568b8dd38cf960000000000000000000000000000000010acc3d377132629dcc25a39d2404ce318a31b69f718e4600ff75e7244fb653311baea030db1668dbf59cd5477d0295c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6574ce7415a772aa066bb792895a3d7e9923fd392a8ecaddb4e63f8482a566cf91df3ec615915607d466c7ee80ff84000000000000000000000000000000000fc4ac2659d31b0c300ba58380057c9c96330afb661418a2dd825936df29c39790e79697998c15b6e3c4c21ec0d787311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a019a34ea88974159ecdca82659e21f2cfacd1c5a9405d81a380ec5541ed272869a3949482c346c72605a8369410ede000000000000000000000000000000000e53f6462b19e5ecda90644269173ac4238cdc50e56bd385ac8d3c0b1d70062ee4d342a1193e259421b0fd13867a76a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001471137f09985cbd2de91fc00e547a1c50326a10ed9b34555ef6c20562a26448cd82076fe14352a4472d19806f5b6b6b000000000000000000000000000000000b48a8061e60fd3eb54bdc1a405cb73e2ed465706847199c1ae4ea3b355b6a60430d8fab64fdf26727308be94d7ade781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000361d9b30ec0b22a1b56543dc5dd6ffdb6b480d041fcdb28524bdfa184e7793ed368ba3fe8a2d4a6e8ec3cd40817439200000000000000000000000000000000139fdcc15b248e0146e11d909909010dc78a3ad22c812a9ca5b0d8799f8680d53ea81773166d056d43f1ed027c60fecc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129caf3dc0af718e9e38b4cca490ea774ea33df1a0e40db4cdd8fcf4aa15a7ef08e68d6bf54ab82aa25f03396d324ca80000000000000000000000000000000010592a427cd1aaab021674637d836dd55fc70990e0a6d9896867f4f0dc49232620a96bc30504a82b27babe9752e8160f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd5f332126f75d71699d84a12b8da2fc8ab474b41925c92497ea231ef0a96bced111d8e5cc621f6b2fc38e061ac74e20000000000000000000000000000000016921e63b5fe43b027f4273a125b0eaa291fc40a6479f366f9b039f730e423a52274db8e38595cdabac8974e309ee4f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002569f84c676ff3f1488a4449a4dd825e621e2513461ebcefdfb35a7dfe7d8309f0bdbe1358ba88a264d2b9fd53667c90000000000000000000000000000000019fc3307bcf83d12c6586aa58f742e028475ab5b1990a87081d71a8b84b20bebeb076fc09bcb5a024a9ccc66526f7aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000060f7eaf2f5f098bfda593148dcd3c9c37f1c34b574cc48a9e67bfc2fe50261de116e1e92f2954cca1af041cb5b0de000000000000000000000000000000000ecb93b042a48e6df82e3428dc80fe85214ce664b38404fb88fd670e831c8f4da7260ad6a12b3b1d2d917ba3b242825c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000324cc5cdb2cd1bc0189fbd7d464f55153df20767e275cf6a3cee85c66fe92a2efd58e54246ec9bf412cec58e020f929000000000000000000000000000000001573f833669e2fc97eca4d725b0127d97a88556bf7fca9bd7fca1e4faec98b5b7beb0892f3152ef8ae879cde3edbecac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018b71f98faee5c8c4164a676ec4e0aa241f7e723b31f6f6cb1b9197eacfa12f3af872fe6fc0de2e9790a67f26068e66000000000000000000000000000000000bc7d304b282001ec4080165c7119001ebbe60087742e5f227eda96954e45861e539a5811add5987194b6280049971bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000daafc7b029ab715ab7a2dacb21240463827bd5cfc9e225693a74dc34cb4d859416a8e12c7f963b531d7b07a781b25b100000000000000000000000000000000040675ae6b27b73bc0f71be9d9dafb0ee9e2954b2768c2255d7ac177bc34ea57d4acf43506254041d5ae3868a2cb0c1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000007b5a3863bcb9b6c49cad893ecfef3d34c6b88a1dadc81746f027b3ef37e81cacefbc2d0a68d99e2b952358434db250000000000000000000000000000000007391cd37ccb995db44a5f61721d28ed67ed76bc2c8619574c29e8496941527907a17cdaf6d8b13b4385e6eb9c05b8ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001073e86555ef9db8652dceb021c0cf562d1c5c9833e2c50bc2192cf4f446788c6ac7b3df1e1cf076ec6d953e50d95c74000000000000000000000000000000000a31d76d8d7c6161d358415ea6ba423f0af78494af50a118ac36ce4831fdd2aaf01084b5c98ed1840db9027b5eb9fa9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022cd497ba6274b09e4463bc6396ae257cb21cdd4298f9ae534769f6b7a1cdda3f4abe4f05a07aa6ccbb2ad519ce1345000000000000000000000000000000000ffb58bfb64c7fc6f8167a19c4de93d498179fed803d41e220acaf2ebeb4c532c4c921b0feb5040b5ed555d3e0b12bbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000999f6229b581d5420ded5d71580856a484642acc49970b25b21bcdb8814c1c3aaddd6d59f5403101acf4d3855de298e000000000000000000000000000000000470c532a10ca9e609b04f09152184bf884a4497ef4e4f2257fc9e39e98b324db933567859b446db861db724627a71231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086e7e4467015a44f4ffcfd5c185f926215fb7a16f57f93872496d6537c85ea330764a6bf9560910ff539c3e7d6cd8aa000000000000000000000000000000000fd94df18a12496827681df9467e167f178b0de3c588ec883025fe02d8c17c4a2608b26806089fa6d3f27a32698af1ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bf6299b4628ec7eb19422402fbae1794effe10f1cbec86936007dd62f97cb11d98c74c4f91a04aa29c1b9dd8c1e6b700000000000000000000000000000000040d6d86eb507fb70a4066b8a20c07077aa276c24d9faf427d99764573ce708cbe0b0945854c5207de5a37a290cefca81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ed45bb21220841e0b9ef7b19832770977e81447bf52ccdd1c7b73f5a8d122515ef3d0cb2e0652b457c1c3bbfdcd463000000000000000000000000000000001051359c9fc98d39d4de5e46cd33189e5423aee58e3f4a3a66b57a7eec2af9e97d3b3d420ce4a142b2f079d8e365b4c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0b371c20558206718a0456aa7637166f0dcf16cab7d960f330503d363513e58022ab43cd5b4e38608ac16bc78b94dc0000000000000000000000000000000007b11965051f0c6b573dc4e399ceacfc50c86f766f12a37fab3459954886a6649812915ac9e0021e528cc656ecfd294d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000692bf377b1c5f6e84836cad689cbf41800abfca0770a3f9c6a8c4d917e6d93de039ddee22e013ef05c6ae51c1557df200000000000000000000000000000000074f90fa9d645ec84a4681500abba428055eeba3c1d2f8ea8f88f577e7e7b0a261b2d2ac6fa799f5c45bfd31f7c248d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d0c633b8241329a5e5cdd13a2450db3485031b225a50fe8ce60dba9b496b5931ba7b3214f6be9d63c019186023c65300000000000000000000000000000000067b9d7e6931fdf518b10ba0c3557d4c16291e80ef148c4a2fd578a69ad7a094f2286a3b3a2b42eb8137df748d3b7e6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034ab73f7f8731cc42ece61199a67aabea2434724689a7ebe19533c27e0cc5b4d8dfce52be27f8892301fefede8f9a930000000000000000000000000000000017c1ee4fab35d9fa7a81ccc2eb9ea73f19ef394b31cda79afc9fc77a69326f2b16c805ec16e8d68cdcb3bdcaa16192f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0980f4c5dbceb47769af9f640cece2a80c6cbcc3058dd62fbc0d0c89e166354233635067c87609c011b5f293a21fda0000000000000000000000000000000006e77dd8384f3ffc75b97799d4df6a8bdafbd71803b7dae9332c21643194670e154d7d49e2f6adde178fea7b2e3f6b131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000355c0dc652a1a9afe66faa4e202f0ca12bb368c345598e98ad854c8e28813e91d4e6d7a29f47a7614a215e3748e5a5d000000000000000000000000000000001444aedbaa412b06ed6e374982b8e7ed3a9e3dd89807f5c94f19d7d1a6348fc64a017af639ede1a7bcbc9eb0ae87295b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b1d5ae4c22bc3ae8f024a56c0f35db6b7f38faf226cf768dfae0689ac5097278f6c63ca796f5f2b9c0d7dba4adf38d0000000000000000000000000000000019e4f92b9cc4ffd58a0e7e7868d5368d283ef337ae3a83922dd62e0f8961d025da10ac6313199f13a586cbe2610fe29c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd6930ed1818f5e86c4248ff2b36be4bbdc5cbdadcc83e5d3cd9527a7be7695a359e12ac1e4c628063c00604e68931000000000000000000000000000000000112c28b80e46d9e5492ed5adbeb66079f072a510cd27e580ea6a8f732a2993ea490dddfe573079088964181016d220e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130074006800303cd1080d212e330d0f17690c09c44af87c0323996b79644f30202dba6ff09a9316d9dbc9a588ea963e0000000000000000000000000000000008fab72f336753eebe20f72640a3b79c76dbd5447dd422b20697a9cfb2482621f038e1a1643e6f4c8b2cda73502c098e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001633fce7eb0738c5f70afbdaaa682f27bcf10236b74b3f2b08bdf0ced225e31230265a7eb94ddbf6b64ff750a59aa8f500000000000000000000000000000000082e32e526a6a950a0de05698e5637752082d52597e7125d2ed3b85ecfadac65879b9794a546078605a3537fc7e00e371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030d3b77e2185ea2cfd3c2f0f1baa93a4438f0551e240858e04bf47a48452f26b409f93bed7a8059e18d4ecb4fecba1a000000000000000000000000000000000e51fe174b701f7151d8a8b06dea7c80c99f6c5d091a7998c39d250057c05c45a8c40e5df09b39d5933b44feb727b4bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f51839e6ddbcc89082f926651444b4be14d4dd9e46d668406fa4d05332ffa442c8e2f79080d6ed3099fd29ef95bce03000000000000000000000000000000000e9c55c194106933dcde74c90715eb74c7b66ddf617329bcf06bd48ca0120d38155aed66668965c1e2547fd57320f1771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124dc87907902a30b4ba2dd84e7574f3358b213849d1e3830e208aed82ffca81cc4be62d3e68c64b1f4bb1770775249e00000000000000000000000000000000199b8daaf7017b6940fb96558e6de26cdeaf016bacc7cc181be448c31553df11bac7e674e25d2993cb7132b2b7e063b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fff871d376f0841f98c53933819e0a628d6b6f3c95ab1c317b79f28dab1852a03806eadd1b3aa74d797beaa3f0832b000000000000000000000000000000000d073605fab40a9c60eb8c3363a519139a6b813c289d288a2b23dec47f755244e437561b045866076473bfb8f65131a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092b6b42d133179d029682d5cd22542d2c22bbf14c814a08d9d6fe957b3308b8a7dc3c31df1ba47820fa8252cfaa2a350000000000000000000000000000000008ac643c485fcd0cc7696481da467b54b94d05ff923865fb09fac132aa6e8845b59128adc9d617579aa799ef0b0efbfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c34ad44b7326f8746c4f03abf6633a426095464b96cb410091f26d30bbac675895ccc0b70d42ec141cf8472f4bbc17000000000000000000000000000000000eed56242bbb8cc5c4ceb0f170de5c4b8180ab39582b20d21e18baf316f3ae1e449e1134d19dfb9558e73606afd955951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011563978a057d2790bb8fe9b2d12af5cd65d3e83d1778279593c02b4332d698bd6f8d43d4d8e9e0e2238a40134bde558000000000000000000000000000000001721be325f7ea7478658e65a2fcf9ee018c4b743a52836d4ce5745e6781c17346f120ed73ac8f01193c78f2958cd89eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d9a504755dc73585b6a1b2a7d6121e7df704c5d2479e550b012c5bb0c0143e570c561216609f24862a300b2499bc8b00000000000000000000000000000000017c07a85ceea839d4add65466fa57b1f70dccc5acc6e6e068d59ef4290a66c8dec61de72c793415ae1a0efdd36f69a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000712d668a1dbcbe170aedc8e6261b740ec74cc2b02d558fa628860a2d8e66f923be2e939e81bfc574f3d437320cbb06c00000000000000000000000000000000041c855cda274c651d62418ffc6b19843cf4349475a78d1d14cd1bb15ebc2096651df7ce4123e8d242a113b12219d5141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fd4a5d8d261ad3edabd56ddfdb7ba34ff77f6619bf50bd611f3bcc62c6c01f917a519b21dda61e2a80a49adb39c3f800000000000000000000000000000000127b0d164cd62ec4f6c0732c8916eafa6fe6b422da0033bc80ee8e5d0a6c3a65b123b82430e0d487008963602794450b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000571c0031fdb10799569d024444e40f433d106708c4e9b51bb32fa2e68a8c3eeb81eea87ef37c953ec2376d36442acaf0000000000000000000000000000000008e6ad7b9da2afcb7153a8a384beeffbbc073e4edd623570bc4edf1705b455766d7ee87d99dc4ebbfd28e33e5f5cdd3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a985aeceea0cbea0db060af3e5d44d258f28f3cc2abb47212387634fc999401fc5feb9d6c6a10b277063d13e85cf114000000000000000000000000000000000e000590867dce6cb0ac7f22341f81feb4c6654086366f4456d502aea159bac410501b57fd9b43a89ed750978a6d6cf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef1cbf90ce710ab6b41fd33ba8f723a9a877dd2f992a336cf3c4d2f72d8ee10444917841df33c4ea51a560a1c2bb2260000000000000000000000000000000007d42afa00313b97af6f29c7c436b971a1b4fe63023333dbeb21073621a9d1aa03897e562f5852926430035652fbb04f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045ad6dbde9da5b685f6d7dc10b51a78a2edfe476fc12e992fd3dd386dba78c7bd6326fb469a4754c007c3d83d6ea99a000000000000000000000000000000000e4a62bbb3cac8449c39ad99a247be5284de9f26a3ee99c0f98f27aa0c840906ef3521d79eab7db7690e2c7893cdc2831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001049bcf8e75fa9b56fee6cb36251da6248ff342954bccc3fd23ac3324c464ca5705571813f104ec9ac2cfa3cbeff51790000000000000000000000000000000008732848dc5991b0e1e7838140450eb6f97c0c78aa7535ab15b714e1d63556d4fd4eeb009cad4f7bb485dc5e1c7aabf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090fe58e288b8428caf41594e646d84228ba2dfb9b6a1437a21d07b1b5e182919da570420bac6d68db41e740780e95be00000000000000000000000000000000040929cc25f42673d2ad3fccc101419a106e28b3dc982f01a7f350448b5b745561e59d18a000c10969c493d4d9ae94c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc41bee11269a9a5ed0ead2642f887f0daf524af7148b802f9b14a3e69bb828a135437613ee6e2652a4396f57da791100000000000000000000000000000000053ff390177eb1cc3a23ce37eed4c4548ee8000190e6ff387d3c6b9d0a28ab36b0c376be8bb5727061caf8de0c004dd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001216eccdb6a4d4c61e6bf241e9ddbfe8e0e4ed08d20184f5c24cc9f4810d9fedfeef229c161b1441bf0c99f47b36fdc4000000000000000000000000000000000eed8866cc67afa6506695bcb14aef302db96424a51603e1f00f011ebf0c6923f0520cb114131769926372ec0d7a806e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed0c1042977811663bf1d525b8bdd47e9b03b314674a840309df70f518353fa044b8086fc61eb49d64a1e3727bbf74c0000000000000000000000000000000001e4c45d3c1107f58a41ce9c553e8897ce6192ea559d66178f54b9826ac48eb1b4dea328b81864dff854501bc40a3eba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5d9c689bf0008a826963c11142cfe1d738cc510ee476ef723d06999bd72e052ba6c61aba9c0c4bc56a399041568a450000000000000000000000000000000001f955adcbb01aa50f81e1e5a3e089d26a360147876ab4a28640f33d8be39f33f2e3d430fdd1ebccf6fbe86b355475581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5f4fda5c986f362d8de4305b61c1fc0daf2c04601499464042285cc0d35fb4f46a777e7a4d6e935fbc49611ea620d40000000000000000000000000000000004096293abaf5943f6535476b92682bd1531488a3e8a4a9fa7738f877788c172fa185306a34b82f83474181d0b87c98c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009096ba37dee41a8695ff721e7c6a0f714596f254dae0612819ae14a037850c13f9e9c5aafe4edbfc4ecb9d89d8fa37e00000000000000000000000000000000068cc4712ac28a8db9d3eeb79e0d72c2646a31349d8bde9562eba5137d33c1da2a45d065d2584b3bec25331d14d7c6001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e370aa978a717492e2d08f1006b9c04287d199c92b1fd7014e75aa075d72aeea10b89a2f326ae2e174d77ec6af2524000000000000000000000000000000000a820bcf80628d179135abd412993313ffdee30283e1907f67f37200913dd1cdb04b50460918134b280fe7cd5115267b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085a6233e328b2517d75b5cb8c2c53b5782f095e79015478624eda0ed338aa07c7ef287c37c7a15662c26e7b49f1d615000000000000000000000000000000000388ea5bffbe057bc5aec3a15a035ef29935df001e8a6abf01b1719767ae39620d3193c87b9ebdb8b176870c9e75e9301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a2d6dbee2f182ae123bf064f0231a314bbdfc3ad46adcca7c25218f784eabae814c6de9180bff76ed4188c084ed58a0000000000000000000000000000000019cd3e1c87f1ece124d5e6bb3681c48779f9ebb215409805e6a926842cba22750f4536be7f6144ea57ec51e798facb5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055267d6e93d635e5b7a382bda7c14853cf964c05c81effd0a7a9e0a0bf947f382bc023fca481d5ecbad49d2411660e30000000000000000000000000000000013bb88834b0037ebf65dd15296ea0889a393d6edf53300f2c53634509021d8127b33dc9d665d15635c5ccf15e5bc3d7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005684292efadcf43de6665fd2410d3b4b073fa5754dbf4063277c9ff3d36d46758344f8d7e59aa1861527e958d440d2600000000000000000000000000000000117938f23a121ea17d27b8a57f0aa4a73f76be2b9fa5af46a38dabad187087545e9f1463263146149abb3622d3faf49d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7e2f73d20113702d1c95bfaee5830aab022d7f80047bddff912a884da2a538bc9d108d607ac8cffd870a7c9fa5ca4c0000000000000000000000000000000007622edcb2c84d7ae3b0895d8eeab5d4b4a7a879b1dcbb624bb6148be6580057887db95605d0b21a9c858a84b6d6e7a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e440b2b4480a19957095e7e884eb29efd6f8949114a91240dae77464c437c79b5a7fbd3f59a83377679d948dcf451b000000000000000000000000000000000cf68dfaf6ced5a6496984acda652289da71c86f385d1585cb21297df843faf0434978097407c9d03e30137e8f30beb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a195cda7a60e83da8636e1bf8795cfda7e49d2877346a04bcd9a99771a77cef77dfaac0ed3deac5522b1d1988259f30000000000000000000000000000000019703a0ce8a51a72b5bb31f494a2b934345ad7629775b8ba6f4256b1987ab7f64c9041b370255d9edb3a07f408005aca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173795fc5219025fcad0be04873b66e271a6f2d10d62640cb10e93c8bb42a74b203115bc85615aa85f9b5a13484ce1c800000000000000000000000000000000126fe23a8acb30bd36264918acf16d9676b466d8e4db1ed1c61496ad05401316462c2ce4ac19bb35e3812ad21974965a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001796126de82544616a8e0daaa1ac755312c301d6410798016b32d8c57b65b1343afe1d8aaba1f0512ad028d1545fc0c50000000000000000000000000000000006ce0af8db44d95d4686e8dfd2f2772070fad8e8c12bda55336443ceaa9f6ac12dcc8acdb0bed889638fd6a9a63a0ac41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c003e819754fa93590f73b567c35d6531ef649a224d7dfb4b40141217e398548f9fc88d2e724398355725b99cfad8c000000000000000000000000000000000e0d7441a592da8bf1b56f89d5549042093f203a54da638aa071d588fcbfa9875e38141c1ba6d26910f0d958c5dc5d091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001968aeba818b7ce877725b3fb8cb3442944e7d12d71809d4f7b34753e5092b467500acdd59733bd250e8107cea36c3390000000000000000000000000000000017c775964c6475866322633bfb100f50208b667b951245f41a8a361e5cf41db563099bd6027c3b56a91071638f9e221f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163e5e026c9adc51cefabc991079d116796c0e625b891bbfb51cc57f4bef975df47898b01a5b91e081f496078106a9e300000000000000000000000000000000143977f45e579b464ee22985eca3f0aa257e506eeafe185453662f215820d75f6e20587775329082fc94874ed16c90ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001070680f83e6554530be517747be1cb367a40427002d2fe4c74f982e2e74247235940e28c6f6c2e1b4ab29def63895ab000000000000000000000000000000000dfe3f610b119993193b10b62a86945b6b234220f4467af941d414b2934dc8294b56a7f02e6ab02c2d4ae7ed11e5b5a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5085b2d455ca2da033a8cd03f1ce8badab0ba2fd968e57d5d86f927ace96ba760c917515dd18d14d8fbe4e7a7be15b000000000000000000000000000000000346d6add2cb16a50cfce28b3aae66beeeccb463d1b92d258d5cf06b6f3981d7d87cb20a6d80335ddf6d18c65d2a93501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc469d47861d2e61f15522680a5051a4c0cea7569a570d8e822bdd4ab43e741206cdb4f1873fe485f55cfb016e0b866000000000000000000000000000000000c000300a234fc5f160e7e41d050d592867772f5c051dbf8c8efdbe6206808563b94b2fe76c327b16fd9e66936132d021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bc9d6e66dd33d8bec3ba38e94a4c876ac2204e4a0a0f07249c2f4669b2e76f969c69732f0660ad4a8396172677b35e000000000000000000000000000000000c580810b033b308a0ed3854be7fef74770056cbc508b868ead00fef512acd7a3df7b01426a146d0c7f42922322d132e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b40ce2140196395850b8fe8b295e0037f6d84655c5d6ec2749b556c4a673e4e0c8889346216eeaf36a599bc7c149d400000000000000000000000000000000183c3e32492cb1af03495a7be23be07d2e868187477dfa523213bfe54f63a3372fa42666fedd316925cab9e3511cc70b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000865fa2918adab8e8ef9ceaad21181e055fa56468906cc70f4561b391bb81e2fc6c2ba2cb8868183e80c7a6f5b2b9121000000000000000000000000000000001523aacf75a1d07747eb9c5b37aa302777dccca95346e5e836ab506ccbe72502c75055f74e5a082c9ba54f9e36801dce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b2bfd0ee491183ee659501e3661bc29b0f862fc21be9ec8f167fdb37f7b91d9765a38a5ef6419529c8016b46b94698000000000000000000000000000000000b93d410bd4353b04b97068cc45db00064180392d919b64fca0f54e5484567204408bf8bed364fc31e3aea738234b2bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001017eaf9312a6f272a8b0f7af3c9f41df13f4d029b9df87d8d325592562d37fd7719087596e28685d91bb9fb71b1926b000000000000000000000000000000000b5f8b51b6d8636d33b6049d6398de5f1f615abee6d7827683d4eac0a8af00a4cee5d7c45269a88ed3880df6e2df19661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009482bec00076421be6a00247b40510e2b7cb78967b16659d95ff77b837a9d474fe5a67441acfc180e8bb672c5cd4da2000000000000000000000000000000000cc00cbfdf5303055df6faa42f619fa44b35a1ab6f8bc510fa8a8309c5e4cbbc7b6f09aaacdc01c7b9b060166cbe05501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d7dff24e51c0d068392461c688d9dc2b3aedc118fee8f0e0d00467fcbd2fc8594d3bf658fdd83ffdd028bcef005c0d0000000000000000000000000000000018c4a95917fc4964ad68ff3cedfb42f28f3d4887d31fa4934ccae38af85d5c5b685df87af29a84e98e63b75f0f75ab4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052e41463a212b2b7ef8dec1c118160eef1e72dc0c5e1efffd35a9e164c8890d68d15b57c41db7883e84b25c8e2f0f2200000000000000000000000000000000025cd2480fda96c3763e63c7fc7654be0fd96e27b272ebd0f0138a88737b3d089af719771aa85c480d73861b9199f3261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d93fd2a09bba916090c92d8906fb5b8323b47794334f7dbe354d982bcdc03c786f2f8c748010c8459f44b8da559a8b0000000000000000000000000000000001658ef67e917692396da86f8d8b357ba24ae7bb8ba1524a7f1ca2a560c258f6900e8fb48c4c093ac1033d849a60ea811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017645c46479a4519c7af6a1bd9258ec5382095f218e32d1d0836ba24fdb343763272ea7a4c355bc3b53956e22e53509d000000000000000000000000000000000de9ee904483bddad4db59c9f5936c91ac9e4f12c89d18766ae217de3d10a8155999b75d5c32bd01aa39ffde7110e00d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b501e9be7fb0d482d08e03673d28393e72fba2c9f3a0c4ae8269bf6b77493115de55b154f9bdc0bf54903fd3400f57000000000000000000000000000000000b3637069e9cb8e157407d8280e8e187674185626d6b2b7fc5d06205ab6fcf030c95a84ebb70bd1b575c4e38a1837ce91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec1011168da8c3867f814ebc5ef2039d524927a64dbe929eb0cc98aaf8d0c23890a1219d202feb90fc22e000d4eb40500000000000000000000000000000000088018ffbf4f90d97367e3981e66a6e445254479d29791d50d06042b4412c55d79a06010948e62359c8fa000c5e67b711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196be932cf504ab83ef240b768c77b6c0648e60845ea52547b217cd62bca574fd5e91baa81b348b926a0c1080fe983440000000000000000000000000000000011cd458aa807cd3e950475520af9ce84e922d5dc8c1a17e02340cdd29c19aa8619a9d6a7be4db5554d980c2793215eb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d44eae9233452e0b9fcfb36bea78d228b6c33a94d15ff6442de0369ad3940ec4635a36f56a1b9f4aaceada0f76535920000000000000000000000000000000009737cfeb396c5b577338cd892342f45206077af456e552b9a44b9149c379daa0b22dda5b009d762153f26f9862391ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058567c7196fabb31d8a61dc2f925f594acf9b9a365e94034f39fa5766dae1660b30225a81b4bf1c921e311333de6b2c0000000000000000000000000000000002cea39ffebb2663e95a67e46e8b78a00519f3f2dee9dbd3cd01446e3fe653735ea48ea30ad6c6aae06baf7a78e46c661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195d2461a86511caffee542888bc1da2eb85254108bfeed7deb1bde1c66a3e5fb723b6ef7567c47d0fbf3202a788d9e70000000000000000000000000000000009d9749340139e9b3e658ef0636e402b783318e551e376296825e3115b961c3db1e623114f685b8c32422f092811b9301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013536f9f4d7916e6fb9ea555c3f47bebc36df4e46a34ebb27c62f3eccc33a8a426853e22158d2a1d6057a2fdf207b6a30000000000000000000000000000000003171982f0dada0f6bce712d079a428c2956a4608892635057cf87f995c1641e9e04b9f48c06864e74020cc8456dca8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001968f7371301e0d5bd27da19b7b558bf8d599ccbbfa25d7c41a59ed3202717f135cab52fb37c52611ade4c7145662ad900000000000000000000000000000000053d4b2f1b36fb22f01fb812b0d37addaa1504089cd9985266d216adf9f269be1234598cb6adec72cb0a2babd2143a8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f16a28e6abf79f88657f75392f98dec34620c5016713abe3199d9fa4eb3256eb74bb8a6bf79567985122d9b8eba698000000000000000000000000000000000e274ad2fe795b3e301a561432b5ddff85037fd8d8d32e96e8e5eed92a74898a95c115607f6043cbaa19a5b6949800411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a17771cb54e5775bbb61c02b6e5b4bb19bd0c55ca3ae0182ada7619b37b426bb3f1a30e8cb062b7fcba0424ab1ac6a0000000000000000000000000000000010056a77c0ccd3069f5320fcd1618297ebd45ccd132dbbe3813379c1ed2d51e8149af082bbee560e3df59497bfe1bb641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165508b6c7b1560929ce24e28764eb2de7d5c82bcb83706bb13b52fe637cd31ad9fc443b76362dc1bb071d5de6fb7f4a00000000000000000000000000000000109d6be605f2e257f42360f2f993a0d7625d292ef06b09c2b3a5cf1d8e94ae7aefe0566bf7f8116bc9b843bb8cafda6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000195b2c0be0a515c3c8e7907ebb994c2e4cf4b835d083cff0b7f18316763ec05055602263b5811ff02d5f6f885fe425b000000000000000000000000000000000730c0c8ce4ddc9cca60626a4682f483f67b920369ceca5c27a8e9305c21e5abb5e75a2c001163702083a76d1e54aa671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b076051bf16186f01f51a7ade47aba844e5d8c32b0a2572d8004a23914fb60aa277ee0cb0afb253bfb2ecac89f77330000000000000000000000000000000006e5e82f6871b37f5d06d4f5ae1932603a79f118e77c2666682f79e4a0e79a1fd92047984a247f9634cc4d8d7af7e4b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018717324748f996c7da373bcb2b82dc85cd4fc0bfb2954645b1947cd0bda629a3a7d37882d543ceece0ee1a513d8c88d000000000000000000000000000000000eaaf23e343e0c4a02c5303ad2c89089fb465cf8eb782e44bf5b1bef338f91410db399510a30ca3efe628a048494cde21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058f96b9701cc411eba7ac4e5a3361f3fd7aa42c11d08c158b73be4e04aa83a3978e59c68dde2fe00f2a3381c4daf3b90000000000000000000000000000000007ae03634c7969c6ec0e6644efc62cee5915991d6b3a1160678baf00441c756cefd255c41f890b9546ad993eeaa530f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ecb05561c0b37110186848008fbbc3accbed4c6016a749556118ea0df45e9c1cafb91f931b292cfef050ac3190b847000000000000000000000000000000000b62fc7d2e65268d1842b4fe28116b96040d2abbfae6c23a991321b30981326787f60e5f6cfc8a828fc498b7160791a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db432961a006ee2205233ce23a800e91e9fd118bee6ee79a7d1c96b3df8e6931690ed58342dc5f6ca971c6ccbefed46000000000000000000000000000000000e4a4e90d39200595e83ebfc75b62e941203684ca06d594262894baa24b83d1ae0b4a6f92854520d4cf0023005170f171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f14ef95cd019af7fe1ef7ce3a4efecffdd9fcc88ec5e50b1498a431f9287a078174bc60fc37ef1261adaee5c21c4bed0000000000000000000000000000000016fabf8a4bb076b7619588f328deda563402c0620727a8047f75aa57055433450f0c2e93956f837f6466a4fcb8e7b7441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014453d804fbfb2ac7c1c55e86dbd3423f814987bffdb6cdc84fd30703f12a1d19c53f0ff2019cd880caa7d6ecbcd0cb4000000000000000000000000000000001183f2ab16fe9eef4a4b70d8ed8974d1eb555ad61d524a3d5279a311e80bcf2c2c9aab8019365b2efd9a3cc3901b03d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ab0aa8e5ccae66fdf35dcfba4c4028d6e5b8af1799cb0150f53e128c368ef8da2212a56ea5286d6b06ef322ea26719000000000000000000000000000000001789e48cd3ad5c6f50257b649485f016f85c4c73ef8c4873656bd2a49306e1661ce349627b7ac615300b760bcbca04241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cae2bf1659d7dd9a384d75b3b650675f0ce2b213f375cf61f4455906fe2c4d7ddc6d6a84757ae5135f3c42dcbd1dd730000000000000000000000000000000006c5f4ba5a38077762b2a16cc997f47155979fcc07c29f4a6b56234b1f37a4b0d90ae6b83838af3ccd2679763c7c5f191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f8236407988ec1428b6395718aedd125cfe98ef37ebba89521eab8a598d682caac88a641209f4fdac9e883eaf6c27a0000000000000000000000000000000013d3c352c72c31d6de2cc469b4c5dfcb3e36e4969777944a4e1beb42a328b3560a8b3663ca7e99d9afcf83e1102910101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f63b952f9e60a765bdef50067bed6c1020c980c2afeb722a1385b424c5fc79f797ec0ca480da34ed2f04857e0d1b0000000000000000000000000000000000057938dee614b947d2d8af9846255644ed3bf70969b05f4e29b7f17c2d1050eb69dbdb9ee24ff1a79682cf567c5d2a431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f4b7331a961e3078c6974b28a49cb4956c44a9f366042fa9ea071acc3a8a14b28353837e4d89c986e5aadf2eb5ebfb00000000000000000000000000000000059752b5bddde7c3956b3f1f3d21319f08c38524963e738fc7f72fb0c84dfe3cb84b6d53d3ded9048d064adb6936f2831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136a0cf9a571869fca267186eb347ab24cbd8a7fce5d14eb07a53b064d0c04dbb899f83049eeb03720d21a93b6cdf6d00000000000000000000000000000000001726d2ee5793b23db417963e64c80bd72c7cf8c1becf1c9fb155d2a4116b91466f572f61fc54bc6dda7a97d3d30c99f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cf9ee32d0e9cba8266753fbf374a317d5009731bd390e5a31f9f3e32fce8dc3f36cf9c08fecdf32ac55a87d72a50e40000000000000000000000000000000005c550515bff3bacacf6268558a9dd0045ff581087df755456c7b6b3d3e0593717573fb2c9859268f0aafe5cf825e1401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000490401f13da73dc5e73b500349ad5251832ab2c132ac46dfbda72e649d17eb90ec8e506b66c8759e3d4a59b0c8f6d3d00000000000000000000000000000000127c82eadb70618bd9725156e7ef9472f230f981922b40fb9841822368b4cf10c8f750268c8a13a8f3eb489bc895d8101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f6b83157c648209d8c57cda768271b21994300461a609607e2bf71585539bdea34bd89cfdcc391b1cbd1ed027a6628000000000000000000000000000000000edc14ec7bc059170164779d6371ce7fcfd833e3fa0e5b1ff7bbb55b7dda893bcf946c33bab3a3b0af1f48df3aea68511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000090b0cf059f9087e247cc990c75d85d6e90bb554c9123907c5461c85ede897b0d2819ebb11672f205175eda4d2d96bd0000000000000000000000000000000008403c18c972de72396a9c297fee41c195d74ad51f7e3e409de564ae245c80393d49a9ceaed14b08a57259be06e7c4331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a6b6a9c392d19b59998facac5cc6c69f9b99111559af43078e113da6d6ff80e086de98bc61e0d1a71833802f065e1d000000000000000000000000000000001995e63570cdfd9091588b742ed7aaf6ac574907d58037f8db0c9db59eadbd9bfbb2069e1b957eaff7fe79d8845725931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046bbe94965d4b5e111368529757ba0dacef4570de9777e17cd3846322f556156e170db64568fe8602cd14f660079b1e0000000000000000000000000000000010d92d67917506b90f3d27e9c242855cc5b3341bd2e6b57014f939df8f63fe02731f540fdccc954c3350bb774a2f8a991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fd18d851767afacb5430f921f39d72c7638992bb50ae95d2670e17cfb9e931ec527b49396b36502bbaf2a00034dfed0000000000000000000000000000000014e384562dbc2ef409c09094caf23d88803f9c13074f747c2256277b545a3891eda292f2866fd5e7f8056468dd7857a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b5e84a6a9ef0de15551123436bfda5000460117b9148bcca5ed719096cb10b81bf6b310be90cc3cd7c0a22bdea59a60000000000000000000000000000000013771b0b4ec65d56a912fd855ae2cad38dd344b8ecd6003ca0a21daca4485c93be32258cb482bf97519a8dca5cd997591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001256b7bbfc139f1e0df1153eba6e15d22bc9dd1a95959b409c36bf1112956499f628c13aadbad454c3333356b90adeb800000000000000000000000000000000055ab42ed7b05843114f22af1b6419bbe85d19213050fe1030c28944c19c8aa9d0b0dcee323fa0fc529c5b066f9be42a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170ebe6e34b6b8609fa8119c327b002445999865006a1f8108d11ba4faf49e1c28f214bc5b44311553f01ddb92120d9f0000000000000000000000000000000014e3cc6fe5f50c328706d3981ea483978d102a25bb4654816d972175a640fa20fb45f86e784a598ff746f64032d6985a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a189c1f374024ef70c64e3ea708a6080a82917e518be522c92cf7798de8569cd775c0b5de2810864cab8443f5ccfcf6000000000000000000000000000000000424bc1c9acdb55fb48ccbd9ee42f0ed6e9509ae8d07f028e444e52f3fc4fa6d9eda23dfd5dde256fe63d66da51310c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001444fedd7a4851bcb86594cf66449f5c10851422c409baef41542fa10196fa36519424bb3484d6ee4798bee8ef47d4c2000000000000000000000000000000000ab559465b0a9a263e3946222fac471c257b6394082b978b5ee9a0357602aa51a63d4c107cfbb2ccdef872115e6739941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b9a331f3e22c702d0f626472e1b6eb92382d26e2b115f2e5dcef89994a721ad05eea962e880442d9033907160d168e000000000000000000000000000000000af1e3206c787c35035689f0dc6051482831bef48429d4aa5ecb56c30da75f05d2b22edc59d4bacb20117a8852a552341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029efbd7a80138e7ffd86248a6b07214ba4c8bf289d0006d8ef9f8c4ed5838263d189dfe09d71efc9a77eff4ce84ce2b0000000000000000000000000000000004c75b773eab13527323b31c485396d7206ee7ef76524b81ad348279258329cb275842ff41d25da8d07f82eb72ae55eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002388d889ef1f0ce358062dae8295db3f5932234521e89ed99b01a4431b3b87959f711a6d7e879f8b121e23a9385b2440000000000000000000000000000000001fb2912ad78d9523895b6099631e3312b54f272f9defc116225fc8e3f4a23dc2e330230202775dd0710d6d54cfcd3d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b6bced2e14a33801f48c41f9c60cd7ec76816efea0aad0496fbfd40966ca8d2df45d4b30271b03b290448c9ebd62140000000000000000000000000000000017cbd8abbf1f17d869917252b88dfaff433c36740a97b53d85a74d043c7dd333f8e34445a76d83bf30fe5664f00bc8791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000412d88f8114e4d499c408513965cf851f1bb278e4d1517a93cd7b16aacc7eb3255de9561a9e443d9bdb23753290ed670000000000000000000000000000000000defc87f2648ed0463a5333c57d412001aa7ace114779347afa4095078c1743934626bde7393716b1968f4936f9e5a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079b7e119a2716def435e100871130cb999252ae47e0ec5ea3b39399a22eab06959da516cf054cbe8e12ecb6217b6089000000000000000000000000000000001956c25151c851a61836764366e68a8a94b19b2756de31e088b1e1aee7baec41bba223d61ea08b9fde3ac5968f9435971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001667e291c7085f4f5305960f20ba1aab9f4293d6df23f069b0958c5166e4adbc29df7f775d1c7c3d785b739622fefdc5000000000000000000000000000000000617bd1af62f2cd28aeefe60d4f0b0635a6c604aa67b4adcbb962e61d808c788f47f4777b971b3289f72083935756a3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082206aed81e0a71ec263146c81ee7919fa0749a6279723e891a2c15ef1d2db8e99f51126ae7236f177dd40f4ad81cbd0000000000000000000000000000000006893001c309bc017c468d6b40632bd039c58d99016fbf6cc8c93f2d04ff7c7c771f722a9b937d655999fbda05a23abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ed7f0c4d58dbdafffb3d710491a20e71d2ff5a73a88278f038026818986c6754d6cbe862e0a0cca21f574661bc24af00000000000000000000000000000000096756952fcd30a77058f37dad6e80ab6427baad2e82bfcf647cd07cb5a1216e3544451ebd49c63c5da64bebdfe797b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfb5528e305af44841ad78e9e3005f65daf7c8b4301650a2315bc81abe9d603b518ed77d8c0f3047295213aefda72130000000000000000000000000000000012d3738f4a4bb366ac7b81b4127e76eea4b60ea7e94d708aa8be2a02bcaec678197689f500e43f9301eed2c7099497481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f71c567f0e75eda67b76627b57de16da316423dd76825960019ea8dcef44ea4a6ffa8c349bc56ef4bd229f7f09415400000000000000000000000000000000072dfb67eab9147f33f69981e70f0f755696279972a2f220dab2d03b9d20f7badf428156abb2d624cb56fa6531aaca6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000036a5f85050a4c19ec8e571ae4ce1f4c7a85687db6263d867d012760194c85903cbf4c921378f91e52f7895c97fa2d5000000000000000000000000000000000a9fc6002d73ba10eee503066a57f21fb1129bbb2786c55e2cbf22a282a0716c61155b794ab85e2cfb9ec43cb3798ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091f4a425c5dd7d7c417602850d8696a1b6b93650a1045c6599bdb42fdfb5a36bd6fa8bee427bb698ce0392b56ab01260000000000000000000000000000000007b8e459a68895739cda3d1064b2be478f620f8cec83be70d72ae7a09387aad280d063b63bb0975f93e9534ae285981d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a4811d1529c290f23d306c204d9a1551b1c82996ea6bba9e4abe12b77649eabea6a671abcda6e45b8143f6ff9966d20000000000000000000000000000000012b98219286ef575ffd53b8a30c2e126ba7cf98d59df2801ad8d9522aaf8621b02a4a97e2a296cb9bf4aad2588a75eeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2ad4aa6e75762b2a63ff4828ee99af1fe7556e7451a831ffaf08c58f07de7781015cd4d61776863de01f89e3c7521a00000000000000000000000000000000047ac48835ef62151e9398bea0fbe7c895f798cc03f6988c2242d1f4fc1ebb5c670afc76ae43c8b201a6f473f03bac981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002414cb45041d2dc3bc3ee62d6895baf05c4df98193be13a7a7f60450049cc39f9c5f5a816f78b7419726498ad43d1fb0000000000000000000000000000000010f2a5c1e0f523af84227634aef8afa6c3757c9de52046cbb511ef5c4b218b06d25e662f821513fec64396bafe2a06971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014427895a5b87a359d278298c58b00e57ae2665bd1d34adf52f8fd323779371081c105e67e66df497bb535ec77abaad9000000000000000000000000000000000386f074e0f6b0d7c3e3f5eb751316bcea4a17142f89c17ebc7e5fafeaa8be3724dd7c792330c041a0b700bf21e472d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001187afff5c060b5bdf044fbce8659be0db6f10adf35f6fab4576e4d17d1c49cee17f338e34bbbf88ffae73a1263a70a00000000000000000000000000000000032f2fc39fb5c3995d27b991934396145a2410889964aa700491ba6e5181c7f621fbe3a8a0b11304d281cf5527ccac6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038ccef5a2e4b7630bbae3625eb9cd99db637aaf48d5232f6c5e8b7ee9b49f994167454398d0c63daf8f7978631e0dec0000000000000000000000000000000010d3b8b17a6f64237ca23d1ba360e40aee80f0f7284ca1322b19dff466eaf47e73b0c2d099cd90b420a480d1d8a0fb921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016819bb869d96d0c0d919155bea40ba6bff378c6ff49f108ee89426b4087a9ffd8c4210cd5624c52d5ba112a2c52a0df000000000000000000000000000000000cd01bb76c7a572437ac4f2c43bdc6a2abd512bfdc0949f3221a673a731e232bd6fd50e94dc2a8c1f65ba94ff091eff31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071d16f494cca29df2deb5fb1de585b701741b102d70478990f2c9dbbe44d899986200bad1a97528894bfb63738567e70000000000000000000000000000000002e9495f8729db545bda1a2b44e18c78aba1c5c29d10785f27dc853a234bcd2335d92577731bf73658a0490f7ea2c5fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153d6c0168f1d9581275a470b4be0ef3a69cd85a6acdb3b72479697f47e9351a90e0f7e91dabbb2a361bb01e2b3541810000000000000000000000000000000004926ed58cc1693485517e23c6fbd45548df27736f57c6a6a40026b7bdd557f8d2dfc4ec1c17a1f472d7b4f3f2da54171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e6ccfff9087dad4892b1881f0cd76ecbd9510a32ecf12ed6d51f1520af7a6ec37f78004ab5c334550f6a262c5e401800000000000000000000000000000000167cc603de8b7892fbd80d49450b740c29722084ea455f0a7ef041913438afdac48eb275c5cdf0830bf9005d00ac32351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f7b23ecf9de352ef23d66171f813104897a7c5ec5f736565311741d25f77dd318d20ead294791f812f2c48b2a9febb00000000000000000000000000000000171e04537c1833e5f31812adcb23e62b0ccf2eb61f2ce391fd7d5192e80f93dac78cde29d483ba5300516d4084dca83e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb84a074cb9f11b40013ade413680802d08cc4d5e58a3eb14937c8105fbf110bd229dfb3b335e981ceb57cc2572133500000000000000000000000000000000115239b2372b2a34997d7d216241dd4d639f1ae57a61ba8eb32d808efbd615b8c43008e54fe9ffb513baa831a27a4f9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001962ef21af82f8cd4f6bc6de3bf61e79c3d05c38a126dc61fea5cb1ab5745743871819529ae59990ea051259973e7c45000000000000000000000000000000000c772de569e55429f955730ca6beb2009a0fc65ae6e4eb8a6ce4d15775cbcced19d81cb1f8076eb7fe946e649fdbf84b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba2e2c4b28d6fe3061eeb5cd89df8624353f8c62cad5f8cd015cd95ddd86a2d6a9ce13077657ffc9597cde565f150f600000000000000000000000000000000022697ee91b6e54a2e80147b8e85649ef17c17e4b9df1302a76ad0cd767f36353f40a176a59d237ceb7972736435ac5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d591963945e5d73ee5fe37cd2da52695858283ef1df7a05867ddbab6519c47d8da17c92b6db3ab8059d6f94a3ff789000000000000000000000000000000000ba23783ba1db7f7571c7c0b039cfc218bafb9a6ea2de2676cbd9f06dc4c2dbe828ad3eed8c6532b8846684e77a340091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a793c34459307d018d4e6d0fc3d6a84fc306a170b039dce4f31df709e51cbd23a01a45c37229ddfbd848bd32288da1c000000000000000000000000000000001432e19b43b130c2bcae3a7ecbe0a1ee8deac081ef43785f24491b36b7b0b43eccbe35e0fbb64c2e624d028260d2cc771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000226d95b0080b5393ce69055e344fdf1bce9326d3d0abbf132d6c2bc8176f752a9d3ed44669b2c5d3eeb539854864875000000000000000000000000000000001311213bb526e9efe3e8c04811e4b2712e4a6525a176737401b0f9b23ad75cd523ce57f2cf544413567fc207998b53e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a99fb521926922d98ca0521b606f50367a7175735e1c842d8064bca6fd351de5421bbe8f73b15bd56ab8459f9f4d56000000000000000000000000000000000cdc1cea7f728aa712b6817a82a230590bc53c6a38a685790512ac4b452d080d8d93a8ee9b1db3c94e9156ee2e172cf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011873f043f42c2e96657766688001de8bab46421033ddefb6e1539ba72024ec28295b37611f04ae848a89f3a3a093d08000000000000000000000000000000000c47d461aad37a7213e4106f136f1280995b56343eab58f62fd45510ac35a2333a97829474ecdfc0852a03fd1b9884bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcd5ea04c9307c9e10bb61d7f3540757930238c7605661ad0b0894a6686b465b4dc02006d9cbe990b5867a752574c0b0000000000000000000000000000000012fdbb1383d29e9b7668cde6ae6e5674066245497019f07869790633f7707771fac2f615e51b07ac68c95aadd4a8218e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027147b01d53738af34aa3dd3314841c35d35a11d90bd8fa84121172d3f7728017bfec909c31f68b4c4f24f2c29324aa000000000000000000000000000000000a2d2f8f868c0dd6f70a7b0dfaf3e1de13eb4a7a41eef9067b0eccbd4e27c3b65f36435da3d9a4d72be91cab03a645e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001726222813603f2a2fe7e4ecbfe1fa015a27025334c759b483d482d5572e137f75f819e29e86edd186fdad37f04e66d00000000000000000000000000000000015d75a5c537761d4f11fd5d231c555f6acbc1da24213c14c4d400748a0c8c3a6a002bdc94fb9f2238f6b70b8451304eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013140f8d0a64463828e8dd9dbd967ef38e5212ec9884fb3c196222ec962e0d53a961e35de2a05c327e0df33d9d7ad280000000000000000000000000000000001884820a4496d9ab0ba7fd6156daa99b864cb06e8f5ae3fceb2327bd6214c0019021bb68db557405e854a0e953ad97571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf0098f1a0f8ce55e4957851636c526e3282559ad9b14c62da94a637b33f9a84267bbe2f0222d988d83457e4426fc120000000000000000000000000000000017f9cea8edfdfc46ec9d6e701aa9278b0ccf5c4224eadb58cf7828f8d717e4efd7f67f1ba7d93ff410d8bb948b20837e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7bcc69e4291a8535ef99645260425dc3d22c793063a5d227dfa4c627cb71ee4792a072f6757babb9fd9eb99c42cabb0000000000000000000000000000000011e7bdb631bc280f6424fca344a5b91081996b88ac9b3c6d6a06749da370244be698aa137debe419ed6bec125b1a6a481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033bd57061984faeb50bcfba33e49855addfa9dee04497e7ff6b2c733b081590aa4f5a05d684aee591265fec24c8d7100000000000000000000000000000000009af6ac5c732402831c8b319fb20bbf59ed83ca7f8770e5bf2dfbeee9431aba0ffc079a6b30e9e4c89894de8e13b62031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001230473aad671d7a062fd993c311ff3d16725ffea4238de73c40da753e62ceade23b6d12ef8898c3ebfce050d2d964b40000000000000000000000000000000013a537a1591bd440e178a753330c0e330b6a79d2202b7dad02c5a78ecbf0a8a891c0553aa6c80236e67ad4e0a47c5dfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001314b1fa89fc3b01b4f23b9d72493667489e508b218b3fe75b4a00c8f2564d8a6d6c05bbe3ead439f1e312d014765141000000000000000000000000000000000601132bf5058cfe88131628fd28321c5c8ce72b5e5ae2696c55a391c1bacf4f885a15261e83fe7b4a834ae9d2731d7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dc8650e6b1e2bb7b44b2d7607d101fe9b2ed0f3e8f26a972b6fbac77ffecb8e96ce9082618bf75fd5d977a47f79b010000000000000000000000000000000011fe7474810e706df57f40d6d976e9ae14532c8e9780474c2874725e741a9422674c0d54ceff8e96aa2dbbdcb0f029551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e940a6c8cc619f868234fd74874cd5b181221a8bd282e2ab0f690d3b00a66ab536f8067499fcd53b0e0327782f18ad00000000000000000000000000000000021d872da387c2e57a416c2afce59a5d81677a8951fa60be8d1236fd88f697ae2783e6fc02f4ea2f4f16035dfff249071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be35e271696e4037ef82226e26f561512caa6b8b7bcbb1a0536c8af81bd9526d8d74d1319ac3bf340886b1f6b0e163a00000000000000000000000000000000102bb876f49c76a3737ac243b877dca91f0840e72b9ff510f3245bbdfdfcff66c3d9adc47519ea9db725b56e609b39631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036b4eab67c87e49356842a48989dd37afcc1299e92ad181efb67f754cf4fe389fcb017ccc53e0a2fbe7c94666a21ad900000000000000000000000000000000163f4ff13243987c9ce4670c30a1e8f50ab0325539375d232f1f603b46d4520822e7b6893d85a50a9e54e6cd6ae807641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000438ceca6356c37c66d7ed674e474e65fa4f2efba2c4d392b5f1182dd9f4970cfe3f2bfd9c78dccf6d739151419dbdf8000000000000000000000000000000000f7d97a52e5cd9c4955db7e2561d562ea1dbb117f434f6ea3f6e2cc713d5354327966e32fe43d505733ce75905f6f2a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120b69653d0057394c5f1542ded11ecad31eccdf97fe5a7dee4d31b007028161a5f00352d681c0670a09909cf8776f8f000000000000000000000000000000000bbc61a17568f94e7f4c2e6dee51514d44a1092777ea9a71c17cdd176ef542da9f13f3ab210df2d67e09c192036bd64d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa09b166a384d3bff7c93c7f47278a78301378d6d0574984b7e2b0b02ce3820022954f404c8781632adeed814acd32000000000000000000000000000000000213b863d962c23997b1387e8d3761c04dd4d19c5b08da0c554d563079003f004f5eedba0e2572ef3604c7afaf3fed5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001180158b411b3ddb466c0ad94c9ebdeb490f91bc393b69d2db9652381817212083d045fb7ea280c8b940bf392429865d000000000000000000000000000000001610c5c6535fdfc58ad51f3bc63d4a2dc5f1f51cc836696230aa4f2d31acd1f5f6c592e18b5058db82a77325fc16092c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001378ed1a1318435462086e814f68717e724d6bf1d235cfe00fa0b6a1f694da983b9ee7b4bf235cd417975786969d8b0c000000000000000000000000000000000f76389aa8baf6be42f247da78eeb87fce48b98499b8d0d44735b1652a9f3552c2fb2e2d611a7758fe6fb87f4964de791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025e60c67e01f501c9a45c07372f228940a62fce3e30d0e39d2e6791b2b6c86c35fccc98067d4f51211eddf29be8a8270000000000000000000000000000000001bd0f4476cbbc14316f3fcdea81b88178044ef5f9a339a91d7c20def236d14422dd576a221980b49793389542fd23651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd29d1b8dc0e1c66acd1fdbe6c3c37262fd596c237ba06b9235f92fe3df42fd8334affec03ab059c8bbdf84e387e6240000000000000000000000000000000013e84002e508289b820af2dd6611131bf8a59ff593cb87ed6c042f77b07acd13e3b09fcb2416a24c182f04d49e0776631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bffca8168829485b52e76d8155396d728a958a92d071ffd1ee3c801a0f69520df8ea596da544f617cf76ed2afa64bf6000000000000000000000000000000000f46926586ab6264664800babcb53f5920afbdc9249810d04c122755797654faf332c65b797ae62fb0589320422f07dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158540e90ac612b363125b6bfeb782a6f7721870db25617c6dc797cbe75aeb8239d54c06b0072e3a6366465235668fbe000000000000000000000000000000000aa9878eb1a6374cb5cf4eff2f6fd89460aef2b6a6eb906e807242cb39926c4d47a6071793d7f06916c59d3856aa337e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187038b45b079a2c342175eb833b3f56e35e3155291313acdbddfa5c9d8fc9c7451bb5e1094001954958617e99db726f000000000000000000000000000000001334c6debc42aa7b4ad075584076e57515f3624a761b2438e76c52063a3d7ceb6b28c38ffdd1d577a6943048a4a58f181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000079ff426ff17d6e4dd32f831334f9dcf129abe77f38eeb81e9c3bdc06624bd31aba4f11335097a5857d5d2a7d8c93040000000000000000000000000000000015087ac80bebe5b873a6b49f3e271cf733f8f8d9ed9a5303020c65b5fdf8d28401beb5a34270a6ead70ab5e58b0b6b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8b19f820114aff1e91b49e587c851057c41a2df584e1330ce404852ff738784563206c6d8dcdfcaad9485f82d06e3d000000000000000000000000000000000d53f0dcde9d193f0c84f3fc0c7d093a58796bde168f223a38cd1b5e8ba3c30b07e77a741f1182eb403e35b14819465b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164ac813cc3b45b64390cdb09b68e7d79f0ed6b6ac2056b604449d1874ef6780944cfedcec6d9c274006cbdab414af5e0000000000000000000000000000000014f96f88e580df705ece706d43a8b98bb89eab33443f5e98cfb1bc3bc3955c837ab9afe26f530673ba033c8ccfea9e4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b74171ff9d8a494ff1680b77587aa7f5edd8fd4346762c1bb14f163767b1cea9cda885f20dce0aa07f59b82259f855000000000000000000000000000000000bf0aa17635224a1e47e4aa5a21f49b46c268f5c0582b94a66b189ff399af7503a45831de71f120e0f3f0979f1b351a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b3359f0c58ea8dccce0f0793a04456a2089552ee83380ba160b354ea96682596f787f5991d5cb8c63a1aad724fbe36000000000000000000000000000000000147b7d7e84cfaf9ac3d79f64a8926e8eb6228e760c979dd79517430a44aed8c622a8cb367f056fae572338b9f4947d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000406ccfaba58f5b19b3ab6696ebc36de407dc7fa84e0000a78ae53e8884394aea252776f5e78826f7ae446ad37fc2717000000000000000000000000000000000a8c058acbe8deeafb4a1e7f046cf02147c73fa1155745b7d41f41631fcf166c6d1bd819bb29fe1ccf38a154712b1a741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000382639b79f0f04f653ba5e98803bcc79feab89724cd8473a3c99dbdab70929177ae836a8379cbc29b0805d744b3a5bf000000000000000000000000000000000a575522682cde8fafd74d6be77d79474269b10c2eca89f9808ca312b57850fa55fc2637030a44e87b1d2e56f048e80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b53f24c20bdd9b084f71d8077a603795d6bb4d85b3ede29b06012b5519605fb96fe995c7d8767c7ca4c9022abf4c00000000000000000000000000000000014f99b1dc9f9cb40304570bf16153dbaa944dfc95e13d597d7b7ed5e3565fdbdbfc9fab694e8dd3a8f49468c8f34b6d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dda86643d21d2cc1ffb3ae47bb68ac48d5799f6d23f9a99ca094cecef98dab0fe64cc118aea3b4588aa7093a79e1c2100000000000000000000000000000000020a08c9fcd09eff76c368682afefba154978faf68ba73414e50a83a9e6a76d2c425d044df241aba30ee8af49a812ae51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164992abc7b798aa8bc219225c8f2ea32cacd2f759d352674538852a79fce87262ae58fa4805ac19bd0cc24fc40e7fef000000000000000000000000000000000dc6680540fe41815cfb5c186e4252bdc18d9347a0c0bb4443014d1f0dd728f733679a1be68337c91abf7a11af0fb99a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191747f7588e2fc4179f35f8c273934bbcd29c370300c18e1f352e3249e7d79dd2694d5f874dcb9235274c2987240ab5000000000000000000000000000000000d92b72e8d02eccb193f9308fe31d7984c8eefdd91d53f89166c668fd1517a70d91db1d25dd20af1630e04fda4ab159c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000727b94700431b1f54c34dd666e1142f40ab4693e7f57d240603c45137bba0b5efabef4d1fc436b06b0ca0bfd533e7c7000000000000000000000000000000000581cf87bfc4890a301a7d06e92c93c60405dfc1c5b1cdd9070f08e4d0f0e4cd1130edb9a8201bea22e54f6d029675461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001477ddaad1ecbcd9a067eeac5687d609af1968c2faaeabb73fe0326c4b0a1fb9770850027f0a32578c78ce7cf3be434e000000000000000000000000000000000b552a04af6233ced891223cdba7d980cce5162c0b9e2f62a227a3e2ce6ed3fccc2825e1b3b8ca0ef6eb6a7063cbfec41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013370c81c296ab212588634066b146ead2e0f870a125761164de1fd6ebfe70a9807746a9837b98ca0e5a026335fe011d00000000000000000000000000000000132d48237ab432e50929e256346c3264c2c45c4f3e0fc4ba67edab3e427825ccad596d139224284dc0429e35540352061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004969220e2d09bf662840766239258a3fc4e6312fb4692b8a14ed915df4d9e781018309ae963cafe73aac26e269207410000000000000000000000000000000006532a4ef6fcd40ae6fb195ba32053ff9404a500c4a236eaa90c99ef0e0c4a8e44b6fd6c7a098964428f4df19296d6001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070c14e36980c29d9012bd6c4051238245303d23351bbe58c531bcc179a29d9e5a8c26f5453b06f905000d5634052fa6000000000000000000000000000000000e70bd62e47181addf1313d7e8073e7cc93070088ed87389e2764810ad8c5ce9801ec01586cbed7739fa2f94b8bafe3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f83368f3887e86accbec036c8bc269928ec0ce71be6937d5c675b95680eaf8a6e58215fa710a4d1253002e29fa3a340000000000000000000000000000000003004306feb3618fda39e38fd75f67d7f1054cd9afbf38a3f0dcd5c39ba1763aad7ca62511610034983ca1979729fe291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167f47dcef982f27d1f48140568d149add2a06b1ef4592979a5877e52fc0b2ebf58042d910fb16312a1d213bf731e8ef0000000000000000000000000000000001b821152424d5e69383fdcdd4370e11a2135258cb6497053460c12de4086715a013123cd23e90ea7e719fbad1da50091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001598b6c1d9693c4e538075a645b3d84dfbedcb5093a2a2627ee7d652a204487140adad7c04f6a85254e95bc27a07070f000000000000000000000000000000000b7348ee14a6884e0e3c7a0091024eb92814b711688ee0845659e208cd183c3dafa43c3b05d82ef811c3addcc505a1761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024b594515da045e65a39089cd9bd75867a6aabd2cce4f6ee92f85b76fd9531c4b7fa4e0f9a3ccdf9fe0131d2164519f0000000000000000000000000000000014f88496072c189ca01fd83ba718a4c905e659abb3396505b79162ebb14d04ab2d8b8f5b9fbeb25f78e99a34b80e2e861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f845192fcec8256df2a289fbcc35f77d920b67085edd37311e7444a362af051ac7578e2b2d2146aed3c209ede46aec0000000000000000000000000000000000b1304c3fdbcba42f9ebcbb624a2ecae13a98882a45ea86a3f18bb42f4d5d8fdd78dd445013574ac12a8245bab31e811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001022cb8522b20732f3206bd5e3c8ccfb60c5f6d4ae2eef93d7968f361818ed7a519c0e691c8fc75e3b69a3375bb2eca00000000000000000000000000000000014b9c960eb3ee6748c1be21c3519477b42d2da1a092214de50a9cc5d86a1013158373408dbec01d04c9954710a86bb351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042e16808a7febd2db26336ebaf19e05562ac9413855b2e751d04ec954de02c1f0daa3d5dd2e1425b1754dddcd115f1d0000000000000000000000000000000011cab26d5082eaf641d69985d488e930dbc73e0e55e03eac71b458f2a9f0e74782cae4a6fabc62ac7dff120f4e67cc131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067e27847598b00251feb02188087dc402a23fc6e69de155ede4ec15257377ab26685e498ad5d7990bfc1f6e83facdec000000000000000000000000000000000b9e8b48785ee96723a07fb91e70e545e3d9797d3b8f30821bb3217e8a155db6b5d47024ce1f3d1593cc54fef8811b171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025301f0180aee7159b3f2b8c4e87ece03337f00a8fa06c092112c46f3e8d5fd2902fb13ee1f3fd23cbe4bde4dcc6470000000000000000000000000000000000a94c030055c550b224ceec91c883483adaf67eda82ee3fe82914632d1873b969db60452288edff0ad9d586074ab137d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001133dbdd74995fe59c85976db507df2d78fe70e9c2c0465c9689e013ebf02fb71d29afca0e17cd6b28baa895c92e8e3200000000000000000000000000000000112d1cf1cf5a5a11787f12bea68f8d9e04986f67eb045992b5f302146801422d060f1d06e4436bd236b0df68b1d4312d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002539a66795a02e13a711bc58de141600e36477d7c86fef67dc7b120f0808ea6983b457f955114a951ef4f4727a42b5c0000000000000000000000000000000019e3db6e8903b94eb9d016d2604cd590f1ce2ff618ee28bf273a48212c35ed78edf1d9e8b98f25ab385070740317cd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017126c96e747f3b8736d96491a1434a73b11e563163fb76c42c77205bdc3485060da531b2cd9bc412e51255c4ff7d94f0000000000000000000000000000000010e33f3f68f9a95d257029798968136eee52502413827fc6beebae0551562ba1d0b0569732b07636d3c5f98863fc7b2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a6de613af4c9ef26ee55ddf9c217fdbbdcd25956d0fea91c485cc7942f93b7bb8b2551f52c04ff139404c125a6940b00000000000000000000000000000000112c9880614c3ccd84ff7ed60eaaf15c9d1743d869d0186c687ef3d3bfa91cb92c08347aaa79f50580b94e593fb062a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000860da09771df210b36c60f0a0f5bfe01ac7cf0834458fbb672e737ddc8979085d7616c1db347f1cdbd5b6b1128968750000000000000000000000000000000010b78112913366a3aa225ae1ace9f6e323d2eb63be1df8f3394fee9aa883772b28765c6e8420524d457b00835c63b8421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f86a8054120b0e8fbe9ae39eb6ae8db7ded10e1f440d726ccdc26cf2f275e6d145fb83133d726f3699c74bd616c02d000000000000000000000000000000000ff8ad9d3bee0484b128145953a79c6b8c6bf5d493f93acae34914ec373970ca3dcaaefb32183e746ed7ece4b21b345f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074fbc7a0cfbfdaabce6c54ff7d757d2399867aff98b74c0a8b8d0e903f7ee580d512c78274fe3f020e9a83cf83795580000000000000000000000000000000013de902931d058dbba2bfe75b67565f7feb8a8aa854bbfee4e128363f4f7438d06e17402a71ee7a318c47f1cabe9a8881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001756ae5b63a7171f19603008feabbbc5e13a4e7226ddbab0bdf532b08f8a1a444080333d0b2721921aa3b2a6c26f3623000000000000000000000000000000000c1926d2cebac3d2e1f07b35425025d83a8380712c0f4bc6f66cb2f5e0c05be2bf6c59fd81576548a832c7bab4b694711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bcc53bd6c2cdc3c3749194850b115098e521439b2542d8ed5008dff0bb65e19484fc132488cd2c2a6a3aaa3403952c0000000000000000000000000000000015a238963b95e85ac0598f07bb5820e2f85caec8afedf6c871388e1e88eef802a79c893617ba595a3a383605b7978cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e49bb242cef9aa4c5a771c7630aa236a0ae567039ddb42822f707382b0cc25d5b5ce849c2b71b4d0d681d3a1a2a3360000000000000000000000000000000004168201da90fec8fb7cd0291f58c77f099a0074922f3a22ad5a0935d005bd14cbc6ec8bb4f7cc5d648ded2ac9b197f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003720b263599359968ffb1011bcdc7d19ffcfee11ed33a021c886c6b120f6b86d2a669a2cdb873cf901b2c4f8ae2ef8b000000000000000000000000000000000ef3a9d585909bbe18dce9ccc4c97993a39b7d6a9310459b87845667d533273d17b5fad9e790fbdad2f24f02d7237fb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e82e5a39fa806e156d224b2f10bf8943668c07407f6783965ee8e4410ee55846193a8b3206a8816cbb1f2abc3d5dee70000000000000000000000000000000016825c1a93be6d4b80e0a89da82a1cdf8c53a363a83d174c21d9094e37d3c51f286a3f7fe8b7a61c374ec8723a9a92a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e419fea158143e209fad39a025c1f092580901e0f8b3a697e40fd4bc413dc68133420fa5cf33855df3eb0f0b035e7f00000000000000000000000000000000187f77f8f10cb9a1a7f18af6d731193729656fab98d4255e3c9ca3756e211c20d5dacdf355ca0e2f6bbc7ec003a862f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001093fde9f71d50aa53f57121b3353cb862520f25e52481834efae55141ed97a19167b49daef0a8b94c5534283c7799f70000000000000000000000000000000015a316314b0227d2144f9eff60e7ee8c55a45d35d809ee7538793e6b1ffedc7036e657f0118a5f3ad27541c0d92f480e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5ed4f39bcb3bda471051fd252b422b7fe199ea7b3abdffe2c47d6a6c413d34a7c642e5ac43df66cd99b1176f809aac0000000000000000000000000000000017d288927597b27adee29e7529136171dc09dfcb3121ec828f41a344a949611cfc59b5b87ef1d15076506a89cb766e7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000023b9a77f7a8586bfd9073f16b49c7f03929bfe4484ee4fa535bbcb11b74894ffd7f39d69c9af6e52d880e97a079772000000000000000000000000000000000e2ccafb39fc1f663f3416972277acd1b9497bdd4c4ab280dc4585a0af628751a3c57a80a84a8738abeda8796b7916e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000844ebbe018df01f7b8651d3288db8feeccb24cf686c132685daa1576aba1f32dd6be19499fbdbc34fbc964b6478c0ac00000000000000000000000000000000139264eb6d110d97e1e18a928c9eb6bdc2de4578c52b77c232a92ba741bb454b8c62b2589ee6200b28b105bc0b9f0a5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd4ab38a37f18dc22139059a1587380724e80650023eccaab109039ff2b33dc641aad816d1b2292a6bc63f01876dac1000000000000000000000000000000000b62ca4f8e4fac00afaabcd66a0b6655d4a5a9b9a400297e91487365013c807796cf0af5927ba761b3aca3b7b64594591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e991eda400b18f91ed05cfb26101cb5b4c2f890386a84c8376ff83e29f8c9896ff8cb07f2e29484044841887d4daac000000000000000000000000000000000525a917051b32db4ae3b037a928f9a83e4a9981f76d7213bd232829e10b1069455b42e6eb5b2f1537f19207c294455b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000662a4e8106064ba11d9681895029deaad968842b756391b2a7d0ba744b7f2aeaf8209b7340bcd34eeff0277f1bce3920000000000000000000000000000000014590db213d9f23e444882e21def8e991fd8233e1f354b05019e4e63cd44d1587f04a5e0ed623570d0793c43c820e4461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077c160cea39b6ae8620e342bdd9bf60c30cdc17116c5cf75d6debc579aa0948e8bb4593a44a654c8cc010dac41ecf8e000000000000000000000000000000000a75c55524a6a9eb45a65d95ba69480a79c81904b99513cc0581886187dc206d633588fd1aec55fdf37315dacdb87d5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee28a7b0b539deafb583aaf0047c8dc57cff3e41ca4e6a1a0287d029959232a72cfd5454f68e8595d7eba8d21abe23c000000000000000000000000000000000889777cf303f057d532de75bda3c9a481aa93de704e7639453e22b6c39d1f6c38f7f0c991eab15e5ba223aa9074c7bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8909e3fb5333853f2a5157c22cc8b9efd95917d61bdfb8096b4f38b2ad23b61d92834f98416832a8845f12d330a13100000000000000000000000000000000140b29744a9a7fbad8ccea93fc320d1bde715ef48632803402ec34d5a60494b5b9972144c6a59e1a2dad563e61080afe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ec61b70c9f0dfadabbbacd90a3cb7f5dc8c06bf0482f6c2919bef5c26bc789a74b5e2e69f5e07a05eb9c55a17a881100000000000000000000000000000000089bf178569f4d95b872a10d33489afae2de71f7c0b0c70039d0ef311fb87d644468ee271cf4e50c27890847b411794c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c8703ceb2deb5d8a63003fc52eebc534d2e670a360123f5e2c9195ddfc7c13ffcf35646215711f51b43acd53879e51000000000000000000000000000000001894126efc9b0a888a43681c6bbb070b605d9bb9fd0910d5f92df227d8cefe0b7c613dc88704c0b8ed52a4b05370945d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003ef9b19a2425aaaf00202d9c1b1e49364b6e73a99e8b32992ebbf4586ba5962b3fb68154a8ac52b4c87159bcacf2890000000000000000000000000000000002c9300a843ee187897395a9265adf1432786c6f3ed6f0fc272eaa3a919fd503735b8a93009a080c916decfb00ec09441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b52c94b01b464c85750c7790b5be5dead57154b20fed1b36dd21e5e231fff38d848651e44be7d49c32b06c6cd6bb01b00000000000000000000000000000000138a05f0aff2595665ace929f6304ddff03dc801cb2d1074fc5f78932b0cebed39666d9fd9ecdd31a71e3c6d248352b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf9fb77fcb472b173507bd8f2f60d9815472a11f82b7c9e1c5dd62361477108c431bdd5f1e7a81e83e49824513f8c5f0000000000000000000000000000000007dfb87c54b8a22ea70ec543d5bb51bfc542bbe71a54adebdce1a1b3df869ad341dddcdecd2e8bfa51e301562ba289271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d6819d438924be9784dfdb0394bfa5ae022f07c3f81944719f07ec460c80d424c0cbb00da2fe94d6afb2453394816500000000000000000000000000000000143b79db18018a8d8b8beb23080929a6769610f24cd6280011178533b6fca277647c96e86f7e78db3f4f15173be072bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7cf4c43bfcec98224d6b5f9d4325eeb759d96aaf103be1be300968f4405bc39832a2c063cd36fde576b5d8f1b168730000000000000000000000000000000013e99712ec0b46e8f464ce0f08b15746e35efc0f642f21b07625c28a951bfb38ad802826709d27ef5f0d0907c465123c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076107e3b96ce90dac2e193046c08f0c5441995f7daa1652abc01cc2dd85cee1553c5b52f73e85ee74a56e93000051960000000000000000000000000000000003cd19e2df7ca79cd65dc0cff6a707578355fcbc0bcad44480dd58a290117132e14a4bfb662ffae9035d01ef7359c79f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010995422a8d80f906e4b7efc22c1aa012f6cd4bd6a4703ac038769c4691d69a4ae0ad1cfd15c0066a352b1b8ba04e5b60000000000000000000000000000000001725947dbffbeb57d0bb2c56d1311e64a38c8dcef8ea3a762d2543e18ccea6c7ac3b5d8baf3226bea7956c3f721c6881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a36e1c0b9210e2295bc1dc2c0918b058474f93ad772ef1635fd32c8f276a680a6dd61037859490d620110d7808e4b7300000000000000000000000000000000158cf44db63565bf98c8537dcb682dd5a96b8bd63a929398a7738632f08a33fe65501e172c7fbd9c567702002d04f9e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000723c083b9c58107e0be9ad76479236d9c2f139e3780467b93defe79225399752ca30bc94e93b869ed6118709db1d17a000000000000000000000000000000000da89809c5d1e21972b0bd8bad2a7634b4c4e48ec2b927605df73443dee54f5f9b3f245f13915cbacd526cf310b9c3a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000290a52a6dd7aa892dde93b69103c4245455a0d8bd225aba9c64297d13b220b1bb305ebe321516344b8f9b20aeef348c0000000000000000000000000000000015ddb3290dadb16912b25cc60714d5605ced00852d8abd257e6c07c3a1f4d22e6d077471ed3abf8ff739e944e1865de91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6c220ea1ca282f6043e3a8f2f5c7b638044283e6afbd6ab2159aae284a4d37714bdeb76a4419a306b88d0d575a6cfa000000000000000000000000000000000393d24918be09ba33dc8b72c84d935e2d3b7d6533e55024a0c1ffe4feb51a866e1a8a8088d71d16db6f2d542cd07bba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016faf65fa08e50da2396cb718c079ff8d39ddcfb6f012ba594c96c9d2f5ee095502aae9be97d74b89eb6f8a23877e330000000000000000000000000000000000466802a9b01b3d54fae3f68b8580ed4f62ae040b378834ebc152a55be6ae8a018a389f11c8bb5c842362b313b6abe411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b968d05aadb9944b96f08cbb3a8075f45dfb9ec191a5087460c0b09ff0ada28da63e7b4a731ee6f77ae7b4025a503100000000000000000000000000000000017cebf15f390c72758e65809b80f55f06faddc12e3f0d1b371e4e08d6073cf3854a73a45c58a47778ec7613086ecf381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe5046727863f81bc5e35520c437f08ebe3d6979571eac03e5dead6a4e27fcbf5b0fbeb266c1c7a000b2105066e95180000000000000000000000000000000003b6d837f23e1fa6d84ac4f67705a6a1f9e139cc1a6ff3fe1a5e36212cd59ff617ff491683c633ded78e01fde4c0d84e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050831b3a735045877b83e407ad7eeb7c62ba2a5eeb40608531f1ddac41fed114c7346f5be478b1385bd9e96a374642200000000000000000000000000000000107cea6938c2f3f56ebd6c006aa5839a8ab1fcbce4b1db8ea77b228826c81e371aaaf4f9935bc0ff41896f31c1812c961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000282f4c11ae5e6ff5bd33d7857e1500c6226dd5b95041722bdd2fd51273262aa881a2c76652ddb06dfe94c58ee6ac873000000000000000000000000000000000d673a030b738687aea2c09e8b22a96008d86a3276c825299dab0d1e0ac8d89fed56adf6c014ea66ca5fb139c0b25c971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079920e9006385096c34c99fe4fc7cffc054abec7970208c97dfd4ab11ed383b14e0476af8ac62efe08688b10effdb84000000000000000000000000000000000e3bc1137795ae1550d9315e9882998d883f8394caf54663e380a6f63c58294a96ff4a635248c74eaf041cfc7248117e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e12396122f6d59f22dadc2c5a8f8b885db440757c5c98696453251ed60dde9284b66968faa36ad0edabeec7065756a0000000000000000000000000000000002fe37cecdc1d508fe2bfde3d62597887e21b12deb864908377b5e0d9d3e11aa969ad0d9e9bdeed34a05f7add4c294051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f84c6bcc60d0fd0fc34b9506e6350f0a7099188ce8be4be8c7830a16df628bf83c63553f3dda6d349c21b82be47aa50000000000000000000000000000000010b8656c56db06db1c0afb2cbaf9eab00d21d917135934ecbcdb0cfb572ac841060c189576e684c58fbc4b49dc8653241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a046a028afb690a6e1b5d9b308b0fbcbe58b1ad3c1092111eaa5152c78c77e6054ce3ed8402b5c482871c22e427003f0000000000000000000000000000000001be6dfdf60abf1efae7bf95fe57b17ebcecb2b95c495b120e4ccc8088bc115def10f752679e5fc30cf4252d53a6cb181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010950ee8b9cf6657a82916223d001bcb9a1ba17a9176eb40bc6b465ce32d5219025387eef51f8d0a28587d4d0775efd000000000000000000000000000000000a129a7e652d173e3e0de083ed7e0d589c7f1ceb7dc70d5e90df18baf69b2b4320567d195a99c288090128ef7804d5d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009a1f90b7ce5c08e6e3782263687898291fa759a3db24bff38787b49a06344a322abe57cd5e0e631aaa9c321b27b76000000000000000000000000000000000131fa5b486679a4d205b937bc37ba7015a306708ba676d935defe536249d65350e360e19774551167c7145e01f8daa041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e63fb8caf70fe6364eaf3786c846c050ac2a64baf0c343244ae81ddda292e56e7b1aeaad002a555044885e9a742dd34000000000000000000000000000000000fa59d09eb7f4a7344dd75f46a706655a7ffe30be38f80331dd5b9395ea8d6ef22bae858a670f58f8c803e68fd9814511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e952d3890695cdc8b0d5a97bcb99abbe1090467e1c7ff8f75bdf92eb8e4a80e7d74b4f5253a9174ca087c862312a240000000000000000000000000000000019ee5dff6261602cb7063eceaf8201bd39358d16d9eea0a9f4900082907ed82bd82895ff6627ff475f7e8a31977efa801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d0b6a6813af916cd3fee44f4f77eb0ac8ef2100cf4d3e65d6822039c882e928b4972d2b89ac5d9cb5fee8e3193359d000000000000000000000000000000000c43ca171944a1f31bd9ad52dfe1a6a200a5dd1f420342fc46ac9bf27338804cf283ad0c6064e9bc893b4424a0fd0eb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b051b381b341f053129e955cbfb5ec05bfb4b3ac46547b8dd8aa5b04e4806afbbf2ae8fe3f42a847ce797aea44611850000000000000000000000000000000009d2b5935ac0ef09355642f7bfc9984256cc8a1d3f6937b0f52e3ac506d723ed0808dc2a453ce912b65cc5a6a5ec8c721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000dad12c00f84ac04f85986f2e325b8bc297f79c48f77f40f202818fb81cacf1c0292c2ac5a0d4eb372bef21920e70f4000000000000000000000000000000000146bf3a19ba21d45b4ccd5ead95a0683f8d2ee6eb881a3b149c71f0dd0f4eead6dc6c01343cf4697bdbe28becd2a0661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f49c2300a84c38c9e213bceae9a00005932a25ead2d416f60cffa026dce3a6719716f61056a770fce0912f76d436c750000000000000000000000000000000007f909194b965910b441931405ba0db0b44fc71f56882fc2ec08dd01e292703a66d4fc282621ec15d1b5776ceddb55dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac302ac3b5d103308d9674987d6a3534a6ec2fa20f93387729ffe8a49f36b11e6042fe82e2b33b45b82a7be93506975000000000000000000000000000000001527a2c0921df212520f5268a60476ab1a1a57db0af3a10976948f2910b227dda427249a48ef92f83eacb84e61cdeaf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016166106f823e6f9622ac1decf57ff1d535d366db729835566f2167fb4bcc16ef3d6e59c7a34ac38ed8536dd8100259400000000000000000000000000000000078147154032e9ed0d52e933d83a7532b9ff33674960929008a85227e6ff20ce477053909320e5072a0eb728c425b2be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b41afe1df5be62069bba2a71ef325424b0c5608d18ae425bdbd4186f15096ac1ac106deeacec866ef776852a62aece0000000000000000000000000000000017aac1b42b21c5e57dc8392d7e948a4c9a10be03595fb9e49d060b4253318bd9fda2761f3cdb314b61960810129563f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187c1abb8cb78b126c760f5f4445d7b4344899c6ba153ba94081dbe8286dbaf32218ccec0a8166937a51765df7ed98310000000000000000000000000000000015fe3724e2eb7ca7895f765def9c38f65c62faafd9d323ba9b1a6bed8121379ad9afa207c33211488863d5ca29ca9a101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050db936b15509f4b127e31c3f627a869940f51371a1974de56e68392fdea618e062f322b8e19126acdde8e1f59511960000000000000000000000000000000008da0a02adb849720dd6d4d13c2b4d665acfb0878df5df55cdb7ec8787d90c078bb8c0d893b1fabe96d7aa3812b2213d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f152adb4346ba3320fb73d263a1f9aced1dbe4b5ae357611c7a6cf3c73e1e06f91d5eb51d37d89c55f904937bac732f00000000000000000000000000000000029e8dc42ae1da7184e5ade15413dda58529fe98a7a1904dc087085c091aa68d77b9b509d594b6887414f8193c60cf2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b7f0918093c177fd90255566eedc349e857071ed24bbf6ce7d65b5f7fa292930f28d327581ea2afa2a91eec23240cc0000000000000000000000000000000018b5632b6f7cadbdabb56f6db9af5ae346e2c5e9495b0bbec0a0d43e7e28e04e1ac2e921198ec167c180858d86615dff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000517a79892072fd20927c10b69bd3a2444059fa7aaf3f14f0513468c2da088a49a28d417e6e38bf98ae78cd9b94f72500000000000000000000000000000000008761e6b67bebb6b572ed921b3c44aea507ccae47f4e099ba84852b540d265ab556c143d71e083e90e891107018e03661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8d9e339b7bff9753ee58d49a779a1050a490acf7432b3a5cc3901ce603b33cb12f9ac73d91bd9664429fdc580c047d000000000000000000000000000000000508090147f48efced9188e980bdd386d43ceed9afa4607e6436df6ad885703ae02243c3887d9c2cdbcf9da09c5480301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f143047d610b02f7f1fb9b7e9ac9e62f0260a19991fe62f3c80825dd704fd35add86a88a07341c7a9145ef558a43770000000000000000000000000000000001362c7976f83b7b1886de38cb5c9c90bdbeda6b65d317b245ed71f7baa03a1e649eab4c2a72501c572215f3e26866e8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123eeb802db0c2f446f29cffa2184e92623ba6bbacfddd8983d0da52c3e4a3f60e98c5c4cf93658930406b03a64a1f2d00000000000000000000000000000000075d46ae3ee0a0f2d94bd2c45800a24eed849e5d40ade62b09f2beace7ff7ec1431653cafe42882e9d475d2af4c855af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006ac508f53dfdf24481c15d7c1d89cbd9c9636b6508668f63defd69ae7d8e6a0305afa0f2a0caa6aad0a654541aac17000000000000000000000000000000000e18eedf3f776d73c5d667e8b37d770b385b6e432b793dfba920c43504d2ed09c04fc0736c8e927b85287650e6e015e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002126b9c214dd9542b15a7bdfce7f6a462c0ab8ddfaf0abfb8e730e7e57f955e0b06060096658b9c3119eb0bc68c738d0000000000000000000000000000000002419ca1b9cdb7a08d7de9032bb23312da7284992d54ec58bb8e8b1fbe7c70e6d33aeaa07e26b0a328e0e454bd75deb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f7a0fb3fe333a92b8ee37117e30ddb4a145c2ff58a3173494b5ea1e577ee3bcc8a54dfde20ba7ff3bd9514939b5428000000000000000000000000000000000fa720bccc05c2ab5f377cb70a20196ae3ccb1f611301b2f44b95d47db0ce0cf28bf669148300592c9798a44d1e72aeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b38f0f576d43f07d79ad99a62457b169cbc8c235b47aeb7d0f8388fe995431ff2ef736782bc22b8bac00a09c38229950000000000000000000000000000000011a8382187a97492f5da1cff5fb145c859d6085db0e18aa1325bff944e918cfca8c1febe8b492cffc3195b6cd98e66fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000be172b62803645f02953906ac29b1993adffb9a030cb4f6310f92b16e72dda02fcf13659581ee0880b77fe1b0abff500000000000000000000000000000000115c81153c25f5a08b546ff91706e3b040db1b153af2781a96a8005c5706153ba3f030b85e26792e8be6a80aa04a970a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c898228ba06a919f4ee8743e25493b65492527e936999fe0d4a834bcba9b768807564927d4d037e82de07b96f9c226d00000000000000000000000000000000037ba972eba7f0315d262398bea0ea0fa7091063f77c7c14a2ca1da97c882d3afe00822f8f4d4c69cd4e56e3f4f28c0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016377e9b486f434e99480291e3ab2e87feccc329f4bbe6101c2f5c96c2ea2f39c355cb7ba28e1b3758fbe86da0d567b80000000000000000000000000000000015fcaa7a6c4a884315e3a550e44f2f36d3d8666f272ff26d1d94ff0cef1b8f739b9861d57ca1bb14a0b05b9e38ee992c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000107c47fd0e4918ff15b3cbe48d66f61c9e92ee119e959f5382d42ab20109f30080a08829228755dbbec083e734dfcb30000000000000000000000000000000001a7428fb01468b201b5f9c9893a19e3ab1cc1cac471bbaf6cad29cd919f4fa17f78a17706035bcc24b2a76ba07818df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001850e6d6385850925372e956c04014e357ac4f12c7daf15219b4b8547aec8c0d7cc5009a34bce170d2f9d2f468da96520000000000000000000000000000000006a58ada59e20dfa5f4535f2d1a72977e1efd144a232183833394951b5454ab64b943b3ac5f64cfbffc84ef8d2567c691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012aa887b5821d57ac79f21baa23c9bd109a1ae485cc33c81fb170172b09b6f0e75120ea69341e172ac857feeae0be6710000000000000000000000000000000018a20704aa17cb24e92cbc1e0bf88107913095a3a908f3b5f0c953003e8392d6e7c71f8f9363101a58d171dbd92d974a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178e4206324d82695da9ed70d6486b9ea5718c1999b0f9b97e603b21d2d5c84b657c487eb8364967e67f798112045ecf0000000000000000000000000000000008922c279f2fc6c702d0a7cb79e6ddbe7c459d4114e3f5660ad146af988338da7dcdc12261cdd919ef2d2aa1bc0a458f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc06fc5d19f0308c0ff3166ee5f3860b5913035063f1a31b6414ff908c1fee5f5266eddd73ae89502ac866b9a8b1c750000000000000000000000000000000002fa1072955c6f686c09a7074c56369c7946e93cb4b3a5cb0e2d3c02cbad742cf80c01159ce4730249540bdf856109291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac5c22af41567a8f4daf7b9ca20d5702d47054336e3eaaaf130a4e1299de1ab81f966cecf11b8759aa36f64f372cdbf0000000000000000000000000000000018129bbab7814eaf3d8da66c574452af4f63828b1dc143607f6cb82ce356bc7fab2c89db4b332d68142bd03d3ad12d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cfa4ab31cff6c1495ba3200c6a2d58f8b4ec520b769b3ab619f225cf2fa57a36c0dd2ab068d8cbd2a1f2a39d14cb93000000000000000000000000000000000aca2768ef8273043a6242c885c405a5911664b63b69cd37328e9636775704bb8851f2b6c54c41bb0a598d0a0601fbf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000343ee3cfe739080d3f7dbf61af8f0b5328ca6d620850b8463bf9320794923c4a49b08c34468afc5a97c1b2196ecbb1a0000000000000000000000000000000005cb3f25ceab2c4cfa550813a5f0669f914dafa311917366c13f28305386d9e894e47d13a7644f59264b74a4d1f21cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a4e8be12baa785e7e0a55f3b63214e0cd467b5e1d2ba771853bb7f699b4d6cacf6d11fe2b72fea2d847a69f987d191000000000000000000000000000000000803549dedc10598508f43b76adfb581ea4f6cf7f63868cd4c397238f431f35a8cc31060c9933366ad89e4c4dfb9dfea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5237c0e69648bf70412cfc0169a8a682995cd4dba303eb0375ae434256fdf2ea8c1299a186cf38633fe9c939cc4f2a000000000000000000000000000000000ec481bcff747a436cc403a90464f24ac0eb1b23568384d914bcd2aff753ef0184ae8e2ae4fdb29d1854b2e84df900421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b3a6409347046541f0dd2f23d215fe4e66fa1ffb1182d78e9dfeed4bdd530557d3f06f1e293c58f8d65552393d2f880000000000000000000000000000000001de0d23e8f12031832cc4e33376ce400629de8039faf2f91d204e7c64a5319ddd903071cdab95f7577c609a74eab5fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001811f19283aba662f1531c306a5b99d7c3f59400f30acd2e2002b51434e87cac5acc933b8f7c53556c32fab3f5cbb72e000000000000000000000000000000000ab3d4a00dc651357f6a4c4a2e21f239fca0a437e4bfabb2ca575b3816a518022fbd9bdfd68aac839bec1769615453fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c81a72807e1d9f8134e9925365ab4da7f958e35d1b3614aa4c044b681b27e5fa706aff573a0b204f6d06690308fa43400000000000000000000000000000000057b0e465c3e0c2cd01c21596854efc63029982924d4af17a461a5046d6e84921e80e4f11a4fc86c028aaadd727710161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a6a880f00389495ac590390381beb67f51d192143f1e412fe4fa5ebb0567850dd869fdaf33680e6c6952a4f3d2d1a40000000000000000000000000000000002689a0d5f2738518fe29a9a50fe61ec50c06f0aeef29bad334947617e8d9c4b9a40efd5bf56f3c0b7cf6b8238c708fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127cf776c2400db8d771db5ffe75a0387aeca50668f97247505bb50ed3efe50a161b26f3c8375f60580716cd8e403cfb0000000000000000000000000000000013d26f82ca62eda2a1d779900ae66da6ea529046de818520e472a90d967114016a64d45df622bff0e66d273f480e84e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dff191b6b4f64e56ef2ee0b2ead49d4db2dd7299ff43e40c817b7c2d34cf7b961639dfeb7d11028b4a90e6e9d7ab643000000000000000000000000000000000d4315d38109c08e0b6c61a5dfdc99130b781c8fe781c768098bad8866315df2e767968d997526eb0a955f1cd7f4dca31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f61d385cda73446f87341bd089f53c3c42def6a34b1a26dbdad575ed353b7a25ce0febdb89e88b3ef7d4e3309fdd5700000000000000000000000000000000137d8d8de4977c5d3bb3bb4beb1b15389168fe57273fa59acf2286c1c4d9558ba8577ccca971e5502c4383ae0807a99c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b192e213a2c740356e608629e623e1444c50559b66d91b83ab934d14c524855a1695b49bf35954c268f9e17ac99a0e700000000000000000000000000000000154a58c76ea2c5920d9b7a8623290bddbb21da15219edf75e32d4c32e9b725daa4bb6fa509b3b881d9493569fd0ca8431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c6490a675fc775162312749fc02e18a196208e2293d2376265665779e000a4da6e6e1343666e6f87417dd058f48b6f0000000000000000000000000000000006048710a80cb90cc6fc95202b014506f002ba14080cd6ec08424891e807f97eda59dc88767c88858b793e7b5a7bfafe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009954dd2d1d332e76c85d5b736705030bdcc06cc8b731c56feee7403c00255eb918a370b35faa21f98abb8c96a1a8c56000000000000000000000000000000000b65ea3b664969b461c693ff5adad600f224788ded552e2b2a97503c058595e5944bb74979977f6aceed01d108d1efc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004aeea4a5e8fc6032b562a4b5455f2af36c983b9d4567c961da0b4a9bcd26e6fa1d0258f344136f2122580131fc6dfdc0000000000000000000000000000000013c7c74ecd0131427ce1c1acc189ed68888273f8a78c932bd0e9be0e3d35301a471fa41e0a6416196a1846d58c6961631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001684d7d87ea69ac759c7694f56441c45cfe0113b7a58d608f93a2f23402966a9c031ab39a58b775917c1e1644034540d00000000000000000000000000000000168b7a9cc121cc01c5e7cdbbe32f53612ad0cc67e9d719b52250d1953412713f959b992b542a7b25cf717ed0b7d191d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7544c69ba679ed4f9ef2d812a65bf6c94b6aed766da1acbf464c25c400cef4bd2364e147c71529a5dec376c332d1c100000000000000000000000000000000135b58b276d7d79506e0a80df5aded63db11a68927752d7182c0f0176d2383d2a906bc23a89f144567c96e5ea07b9c121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c9da50ae458d2e512731a11286ffed8d865d59f2dd708c28449ecc5d4ed4a3e5ddc62242ece9caba40089ce12513ad0000000000000000000000000000000006a36f2a31029733f3da4dbb3fcb72c52b4edd21e182895d476e6ee6e0e0f018aefb6f213fc180d0fddf6f1d0384b7f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001492862a8b2d3d21ed5cf525f1d413f9268cd1b591ec36c6d9a13c6f77e92978bf4221911308ef084c9adb12c10449420000000000000000000000000000000009b84c40c5e6dd81fdb1deb769f32b1254c2fdf1364ad9fae7da1d7827b95f1edbcc73d72a72d4746464e999f8ed48f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001744fd3088095025ff76c2e29560d0cc330f2bc72d2a42e3627d2df7a1a916e4ee63a36074637b8f2876ac4395321ef1000000000000000000000000000000000f65f54bed4549b3cf11e779a558f52d27d2970045d42e2e312e8ddf6e7aa846a5ce3b682d05fddd3459de00036a18b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b25d37de90656446e1cd89524c46762cb5687bf7751517feace1711ba244c0b3565fe52da1e8e66db0004e6e3f5f0000000000000000000000000000000000047bae4d2347d6488cc2d1d06e27227d7ee95f4cf00cf0d16bc936d6a3715fac9cc7aca54f02a26aa5be3bb2c668832e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dc926a98e68c78d9e9c7ca0448d511990f457342bd821e1e30fcfca60f3fc3714880d20449a8a1b0142009724d8298000000000000000000000000000000000bfd3aa3b486a0d818eccc680932bfa5b525d7c4d77d42d1d176a7f4f11cb81a2c65a6e3e5378978ae36dd29920c6fbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008aa5700b5e8c39310f3b48586a312e1e623d355c18e242de8cd68ffab9d1bd786cb656b9ae984b9bea081b62db05c2d0000000000000000000000000000000009c9f58e35dfc06f1a516b17294afa5167ef90314e70064f2b5efdbd12775205bc47d7adc216dc62046a300e84ce52291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003605bafdae0a7bc09bada9c42f4cce2adfb28862b60f50d8034de6ad50e2bc0e1f81185406d6bda716fbe74062329ab00000000000000000000000000000000110a7b7944d97595ff8fee1d2ed7efc9a64c2cab9b71c3d0e246fe1c8f9d17b2a3a2333ed5394f89215787fb68dfbc251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf4f370ec9c2a04bfcb97d06bdfe33ef71bfcda3ad5173aa6a48ef00827c96adfa73cf6498c7b11d07e7ac5af1c7a11000000000000000000000000000000000e8eaa2b214122d041e275a927de61b6a3a2582e4acf29e782fcc6d9e10873874655589ec8b458f1fae91860ca6b8e581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142cbd67a893cd24658b567c4e7132f3c3aecc397ff4615fcab6f3295986309d5b5d8bdd006c081232d23250a5358721000000000000000000000000000000000c6304c6383884da2bc74019502a2b085b7645872de8321fe8469ae1f29bb969490ed78f0665924f5013037d4f4ab6481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3b7e4c01f7256b0f535b75b4256094dfa0a87b6f1af50c529f3adc82a9838ba1a0252f33424748051f1d9b355d413e0000000000000000000000000000000013c9aadbad2e26e5f196b97b7ca1a16b36514ac3297d239f1c24e102884704dd02fd26b0a2a5b21226c8df594f6250a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116b595463dd9efffa713622b9213ef4b93b23b57ae8a029cf207f3d10093daa9a660782f0ee57a127b1a0b50d2d96b8000000000000000000000000000000001518838efa4f46763896720536a1bea0353355280c8e650cd747f38855afa6de06a186ca3e09a38c4bf33320f88048761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ccf8d304ace09c576bb83f4510669e7cb160864444b4037ca68817628a2a6fdf8e671e8f269947ccfb7d7a958b812e0000000000000000000000000000000018eda754602632ddda4af2d702102f59abab31dcf4ab943f1f360a0e7f0003922c66a97c10f98c2d153a7bc2cc8dc1071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016c747ab2a6568a6b21fc221d6df4907d8be9bbef9bd9a5c8ffad7ad59ccbaa3784ed8af0cc01b082660aff6fcb583f000000000000000000000000000000000ef37eb24a2715440ff0aedd0daee3751cb66422b720cbbebdfb90e35d96aabd5cc6f08661948c5b3791b84373528b701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014acfd5c8f05013db4af8ba42879882cd86a7611765d2787acafdeafa01c7ac0b64a06b85e6602626e5912c02d61e5e4000000000000000000000000000000000338bd539cbc31c53b70543aed4e1a85b8a50d8853a523bab27954acd30a50e9eacdf6e47bf3d4c8f0698420d01d12d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018167b5ed7830bff61e900caaa19cca326c5c60898c26f87a7f716ce0901d740387a5ceb317a8f26582253cf96bb11ea00000000000000000000000000000000172367c4b5f78cbc3a3f0e85d0ffd802f11f806e590082a71128ae1de3d293149093daff6b59c17b1ff3a6d0c1483b011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cafadea79d2b36adff03530f0f36c67e7a78f0db1ec23a736dd938a487d2a759b171ee13bf875a86cb636da5abc9a9c000000000000000000000000000000000fd74fd075f946d96269395563f6947b3a428cd19edc00a89c5d44e7cd4b011dd28d679a4d5fe2dbdf3ce7d8828391141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a73e98b38fadfd4940f0cb1b020b5eec20a9f7514672807ac762ab23f5db3954e6848438198274c27f3f991980daa7600000000000000000000000000000000134ab48ee70f34b1558f2b99fb18558e6d8a50d95121ffc193358c9958ab8e98ff5ac607ad30448e9751d480986568261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e0e0cca7f2529bc7c264b4975b8c2b8cc1cabb3cb51b216281876331a45274422fa35e4be6f5959c557605a07e006a00000000000000000000000000000000182aee61a6e18a6d386020bdeae4ac52dceec81a41e6e5d42d36ca66020be2d6137d76b745e780c17e33056e4efcc2a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fce199e6c20db79719ef4628867141d606a44cf920605bf07ce36a6f03b568d2763f2e69f13984a3fff80a9c48102b000000000000000000000000000000000718d2d4d1cf742a65700b4e1f381a1b84af3958c4e3a8670b17a0c0cd344617ca73fde662b56960bec067449858ba891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133a9816fca200f57b0ea30e3c9cd54f971cb9377231b1915279ad75a6c4f4bada568d60311b4835caf5a27134debe9d0000000000000000000000000000000011849824542e0c079029fcef54fd2e6d07afe05ec5b4c1cd6e3565f7b643d2edfe6acb4cbef200190507a59b2399ea8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002194fe7fcb9e1ce063f2c01f4c50993a4c029aa941a859ff91e15e3a3bbec28a7651bb34747944e7bfb0f8b96f4f7e90000000000000000000000000000000005aafb5a9a84ddead31623e3f567b3380be34ad23e783374665d25c71f52ec1692b949cd8c9d6ce34134e36024cb23201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c79c77a30863d778a45203e41c01b3a062b4507c1f7dc60e1bf7d040ab74db6b180a841f8ac038bd798821d76094fe000000000000000000000000000000000373c28df5de7fb7f2ffb4c3d114b73b1eae364a774a7cfd19d3dad6587e934385bd8a4bb7b3a88f55bb321646f0dccc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bf02193e4697eb78afe3405721638acf980135c52eda0d1e97cb96cd4f2253782125586c58a1841b60548da475623600000000000000000000000000000000108bc3a95b7c53f7b6258aabfdecd67361f5241cb913d0e11461a89e982ead96ce96933f3753d15fe6b1e315fab7e3281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125a6c7767adcf7f67a0a5aa32f701808b9b3cbb85ed94a219412e6d80d7705716221fe644ae9f7bd35b99602c1bcf2e000000000000000000000000000000000ec9eccb6f4bcb15bc2498910e546044231e28c7705363793fa98aab4a112fecce87d01e7da7751f8593291d5735667c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001966718b31c504ea12f09a981137d3a5554582bfd3cf4c377333209cbb0c1bfc6b874c14034ba26640dcf465e205d9ba00000000000000000000000000000000063c0c6ee9f30f325f3c57a61491217a9635a47f3ab350b7db610247faf5171cfe91c2dfc649480582ae4a434a8a4cf21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673ac402eb2bd092c43ce780c2e57b6860119f0b646d7949febbe4b3dd535fb73e89ab845afcb3491fafd1d8267b8d30000000000000000000000000000000001975c4eff091d49ec01fa7b12c9473854ce7cd966e04d6f19829ef0a40f3f0d7e07cea12fb9d0a866c698458fa5232e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bd503388ce235a49347b06a59d7045994482479b55490ecb038e14f9b0acf5d3266321ff4a39e536bc0b3614240331000000000000000000000000000000000d9accbd244d3b824a2ca4c81891285c99693a2a9ca70030f772c2dac1ee75eec539ec115ddf1142bbda67756502317b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f57341fbe964a56df5d4b3d93662aaaefcb66b66c1c20895eaa36edf01906949e842cf4b676d0c4ecbf53ffb1d8e980000000000000000000000000000000014ba76f40858bd67e0def739f6895846b24919fbe73cafdbd8e2565fc198e86ed6e700b5b5fc67822c3c1e7b021a60a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001023e7844bd2a34fd0335f21702b0b4bb4a905635cf23eb5f3342a117a418dc9cacdc83c376703ac6414d4fb954e498a0000000000000000000000000000000006476f6b4fea601ddde15f83b94f250d773d2239926b5f82555d06ca0e257483cca4e70285eb17a681a2ffe174e03d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cb06ebbe9d9d4c31bcb6109828e435e41eca49bdf810da1f8c9f8e5ca1094e625f89bd878a8c55d1ec1d17b7c543dd0000000000000000000000000000000011a9602be668b7fd6f8554193ac74a02cf5b399d62649571caa5fca6126b5b33d5b085e70751bcdbf8a66845f3ae6b421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013efa58da1fc78ebe4c9cea402f50f1ed5ac302935157fc78ad9edf53899912acda05fed6c94b5e40ee9e3acb6a0134000000000000000000000000000000000d9f1d498117e59718d01c82e6c1f5a70f97d994a3644c890e4ec0d5b692a89214cfb80661c1d4ca87c4e524170fb07a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000056b92e22b221598a4ff581b51add6c3a90de63146bfbe00a278b63a42ac7edd53246d4d670c82bf0123442092160350000000000000000000000000000000004ebaf4323b019bcaa5b6287644c30db64ab48762c54455dc8e8756d14917498b62e15b9259c0db3da456282694c8b021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d39f63042e20753ea3438150a060f24820af32601fb4d82a0604fe046d089f82e844ad220ec072f19b26e38fb1b2d8000000000000000000000000000000000adb7b0e4d52d81c93316aa3ab747ad7915cbef11e51ccabb61029889047cc55571eadef554b19921bc0604cf069fe4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190072ed20096256a4303c80ee4283a485ce3912f05736f27d8c94c2e6031ccc4f9af73960b7775adc694357aba0e1ac00000000000000000000000000000000039b9452906ad72d218532fd03eee7abee89b419f2d358ac89fe3abc4211eed30f6148397be24c5386faecd11a364dfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7972fc63a035a1fe9606b52621f1ea4bf5a5f7ebbcd66535f5b48d43a3b4c4a133d08a32116337cca785cb10a0275e0000000000000000000000000000000017729ee6d78b5d4e55755f3ade681e10e8a97e1d58d7dff66b4e40b800b54f482ba1a9c6ceb8d9bdf7560c9097c9f94a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f679df52ea8fbc73ef29483da630e616e1fe7ad4ae3a2e315905f0bb882db6de2da13d247a027b1e684a4c4885d3110000000000000000000000000000000012dd2468dff38e9464643fc6dbb6c948d601caf462a267469b06a4d72b058a7d3158a3ec223f856093a984a1e73ec51f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001997a246693e0a01344e5e7d14cc8bba54fea5a7b1755c2def0fdd3335855036c1aaa0a201384edad8f3828c7d8bbd5900000000000000000000000000000000073aa8a814e610eb7abec355cb578acafdb92a9e84ff2df800e5852eb9165da3693ae857d7880aa2e378e80d0f1c78501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165334b5ea793575ded7e347819866807f3912b23afcd16ae5556d1e22574efc0fcae014ea62f9038fb4ceae22ec10c20000000000000000000000000000000002c2fe8622b6da8963bbea32cf314e813d396b9de50a256c6160bd7b83179e023990ecdc3d74415bf29f2aeabcaa630c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ae2ccde78a44a3eabca4213a509c0f2752c7488c5e70d26f65ea3875db4cdfc093dd3323cbaab30beaccaa87c8d2500000000000000000000000000000000013ac0fed61c96bd7032f0711add9e7901e539c1c579018532b3270d33ecf6d3a6f16bd749711d36bc2cb4e1be9416ef61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000661fa014f07947626a0744e29bc64c93f79328f1883a09934b2e35c8be93b5c9f9ccff2f138a9a28934f1689a42a35400000000000000000000000000000000137f170ff52e79c4fd0f11445296e01cc823a3c64b5de3a2f746a699eed6610446fd7260f730a3c92a8d46f4f5fbd1731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150e62275213410da1fd99f4b284d0a983af739a59ba84b9df118c9c013871b563f6bdb6ee30e87488c7cd84fd3f77720000000000000000000000000000000014bbaaff6f5f9728cc414598583407ecb8e49212ecd574fbee6afc07cd7a69d332c12dc202dae75e101a195d7c6df9fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a0a4f4b7375db4ab709c41473fa88432742de68efd7cd3c652a84efbd3c1c1416f426a0093691bc1d5d689617857780000000000000000000000000000000004c7be76577721d32cea70f30dc1e27c2935db3f51a60046d6a97b78cbbeda424e94b745af3ddbb95da2b7dcc1ebd5781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183961151e1308ccf1dd0c3edfdb0d8fa3fa55f678241d812327969c6838d87682f7b6231a777d0ea4a944738491c2850000000000000000000000000000000018b635aed5b3e6f3f14c9d147239e805fe1cdafc055a4235ab3b711fc3dfa5074617bc6d3e5bc62b10e93722fbb922691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e934826618ebea7b70dd3fb1b8858b3b33a518b8d2dc89b56d8dc31c3bf3576834b0af717db5fdeb362fbfc8f49bc200000000000000000000000000000000018a8e43431bb3aaa57db39526cd5be28cc11cc7f22113b4d8bb34abd7442cc4308481b62bc937886b7d2509d5f8435b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b133090accfc8198c0101be804fa771bbab85070c962b3d55b8ca9e683c2074bef91397e6e472f4fe49226291fc5b3a0000000000000000000000000000000000531d3e6b8b16a091ebe111b41289c705ed00bec7357ff6cd37a20fd4a4e0a74ab02bf72ee122656ecce4a65b40f4481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acf1de55b18dfa6aab398cb5b936f824a9ebc1a16ece09cbc8c3f5f0194bb97eadcb69830efe519764687f2a0ec51ec000000000000000000000000000000000dddb0a0a50355b4a8b1fda33ad4c8cd226474e49ab62bbbabc979121ab8040d0b3660c450c8e7cc78df0c7ec5b309eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6c50c8b5e57b1c396484ebbca423c5a08a4190dbdc020920705b15692a126be97b70e57689f19f1754492731ca1c0100000000000000000000000000000000037b7d1c6372666748b08fff1cb3995acda3206f1aaa13668f6370caa871f964c7901ac8a5dfe09da44b012816782b2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000811d757ed709dc893e0873e32482c9f7a27db1f4178704d472848dfe09c0c67dbc36410b562d82ce924630b502786b200000000000000000000000000000000014c6b966ac1c2b46e6183fc5ff348e2ef1445e4dfcca49917d6803deee4e63d55870806d056ed44bb093681975f29f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a2dd0a8d15287d86826490e8760c21963b2a3779acb5e3dafb5ec457c217c908cbbd63a7ce5deeac44bda51c2b2b75000000000000000000000000000000000f3459596d662692dd96e541f4086af27bca94358fa3b7e484f7b1b6e1f3e335a3164626a629bc1a009ac881f16e56341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8b505f447d6de33df40229109ae3602f9bce1fd7885fd6a20453fa268d891b9381389a29a0543b60f01f3971c1277f0000000000000000000000000000000013081799654bfef12fa57936fd928f050ac89406f0b8917a8d357eb7af52954a8be4db98e95c641045876e2570c272f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7d0ae16c79dfc225055d92146234f9600abb4bfbf975580b9b830094813d14bf0691f1d8090e078ef3806078613b8100000000000000000000000000000000146e65e824ff866cb76eda4d75fb0680605726c470744504197c93296ecd2e091d540d7ee761404d3b6b48e847994a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042231c089344fc9c09d80731ee734c8491b72e5ed1441dd9346661849b59f19e4d02812e9a4b812c86810b499e7803b00000000000000000000000000000000182d8875100f60ef28c6f7ca70edc0dd9b9f2c279650a452a44b16569b72d3ad113b324b10a24a0a050fa2f44704e84e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026df9b95bf9b21c3d6af8d79c43505ebe1dc2ea7d7e67e8ac609d14e45858d59de43901e90e6d760f98808dc40647d7000000000000000000000000000000000b8c1e03b7fc79e1c05e1ed7197b9f5d0f3c9fd324f31fac7c282bb0ad51735e683e9dde0f1f7773266f62119d9526011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137ce1c6c73a9f6d585b0aa9ffa3c076d0ff1c64f14ba4699c2b82f05266e3aaa6c7bd499e4bee39c1273e1a0b1d12f20000000000000000000000000000000013d94acac79a253181e2f9e251b3f7011e5202737f0fa46dc77e675a3b7608078f7ca12ce329da543520391acafc02b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb0c98e8cc9425bfff98d32affbdae33f723409b32b282053972892563263d09be0b7516b725719e5c14c9d5b80a19000000000000000000000000000000001077b72534743ecde12b6a994944bba7d2d4f1a913a089fbcfb36199b1730c524315896e65f1756348e603dcd28729b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b57d7f46a8b2efc7636b95bbe2e3db4add05c7351bb6080882694cdb563e615b9f6b474ad07b1ff8f76a68c618f7c10000000000000000000000000000000014e36e7e70bfde5f22063ece7e4ef7beb6d33ad79c68f6c0f31966a9089120e4442884591580955c93e871ebe7d707ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d46605d1320e724a1e707c09cb2a9a46dae1cb159910eba01b5964bced950ff444e9f62165dd9666f30f6cbfbb7a8120000000000000000000000000000000010c6ffc262073c4f3a041103e1d0a0b6523fd6bb5bf86f0a62ff0d92a91d3eb85da4158460fa12ccbe93d6d18c33352e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f31a7a6b91d6268a9acaee973f62d883435697169173416aee8b8fe708bee04a0aa1ea3d6ff9681b9747a4aed6b7830000000000000000000000000000000004ef41111cbd28f1ffeabdaa67998d90cc36a5a37f021a7eed23980d8c74c33580ba5e8ebbd039f29e13c61ee93154e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113dde670bb398e65d49fc13d61168bba93013c0b4d63a4066705679cd6ed6e19fafd25f8f3736695847d47bb29b122c0000000000000000000000000000000012383adbc5860c38569e6879b14a08128c4b42ba878dac7c44fbc2ea548ea4969a7ee86e7cc7228a735fe1cb2f0d34d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001008b69f6ff2e8121ca788be709f5c121a1425c57bcdba7e6338e8d4bf8fcbfaa6c5666e88539459ab558704ef07792700000000000000000000000000000000094583cbd3f9e5de234ecbbf1c07918502764050722af7da1014b122524ba8f19c271160b782f848c4d2410bfbda6cdd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b25f20cd6bfc8e61dffadf7690895e78e9c0e2fc57699386ce5fcd4b3a9a8b56f2274daf9bd2aa571d7d14d0dc53070000000000000000000000000000000002b4a98f9c592586657a788aea618cc2fe74d11dd3055dde1439946ffca1834f71bb7ce097e6e89e76d056956023e6f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c8135856ad44f19aa60946926a87ec59bb8cfbcdf9158200a6f6217b16587f15f0ea324f0d5cbd865474ae19db8c220000000000000000000000000000000010730b4000035d23bd5f0095f699c0bc28b614210ad7704e63b289975298196739573a217e6b0d4a040821b7e0a70b521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea66027b903d033f6d3aa0a5dd9b9ccbaad009fb0472193c8b615475a542d937570df36650c253f4d5be079f9be13c00000000000000000000000000000000016e7546fd38011c7412ed787a6149d069538b4f071bc89bfb34f8c9e75205e7ef59d441471d230a6c22b1e4ef9426411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b790a6ef1e6d21140ee601de150a768f6f8e22b3b1085ce227f9ed70625d0ff6fab617b6684043d9f23a321c4ca013000000000000000000000000000000000cc9d0f2caa382a8581ada103d683fb6cb01a4bbb029b82b2207a5d864f5f5924b8735aa48c092baa41d42011321e4121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fe10b37048d75be5315cc4a3be9ed16f6c65c1a5ea36ac1c8f1d36eeb755789898e4e2091abfeb53c81825aea7c2cc00000000000000000000000000000000142d6c97a41d8facdbfb57ea6073d4e6ea67cc80564a93a9115ef99338f4fdc6d96ef6b4abc9e7c3a5d6fd6e5c6792c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060cb93dfd4dce7551732f75cfd707e5fab0d0174efdbeb95f134e3689a90f8a873101aa72350c50b31c414c0d3c1f2e0000000000000000000000000000000017517483e78db30c9d574755b8d95536e89a50a68c61fc4f62eaad9299a131a47a6009c11764616c188e51eb12f04eb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175491847481df452311edce53b35e8bf5bd7d162c8f94a663ea036e70eaafe8cf4b3f6a9d8fb308c8dacd9939efd3ba0000000000000000000000000000000001b1eeabba269639904d0b2fde01b0f00309a391f91a601a8a6046044bc4ec16c8b221eeac6439581dcb86c2e7dab9761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bad947c211e9ed9632e098b21dba1a2d78234e018befa8d39ae1777d963a1d13ae05665a769f18995fff260f0dbec0000000000000000000000000000000000cc34f2e4b54811e64137f617ca712d04b2c4e75e5b45b835772adac37e3d1093f5989932b0268013944a758ae5dc4971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c59b5d850866d1c7d88850a3d1b87fb135bd24a3aaaec08779fdbed33fedfbb293a08c16ddf3b56cc6e0177aa84a490000000000000000000000000000000014001a5da2642ca1cd1b079571ae8dafc23d0c94a61999b292c3b3212da604144cb5136a4fa267988d8abe79c15edfcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c92854a0d114f27ae33442307902c96bf05a8a4b8696ace0396809b442ca5a016ee0da0c1751bf2965a5ab0fda2c660000000000000000000000000000000011353e746b711ffce1315844f75c447bcfa8b178f474863be4348f30cd0239be7ae468eb4a475bcd2a0ec610c07550721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e3e41b684dbe8d04414cb6529f7c7eeac7e463946d3e65c16286063917ea5b19bd955f2ae4f66d2c8cec740132886c0000000000000000000000000000000006fa5c6273020d1b21b621f75a31a39d95f97513010e0629e95c297a64959bad9bcfddebc23be4e83d6ec8b21744acda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5994739094ed036eba753b64f297e6c7b355c7a0330929f0dd3b4ebf451746da51f4183a007def6d1e9b6e184730ef000000000000000000000000000000000c9f85c12bb508c1be890dfec05f46c6e94f2b3968843fc9a8de24cd565fcd26c0dc1be7198fdc3b24a81276609812121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d17d24fad0f216837b9e2b59bebea91bb78eb9453d7cdc85030d666089710202a8c754cc7352ee4a15c05ba2d27d0a0000000000000000000000000000000011985b9e44ec67365b49f96b6a69d8364f12bd0d20998679d7d6df9c39d79228840dd9fdd8f42127e2e5a860956666a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002711ff76847476f4f7456e47e938d8bebc2ac55c12619b66aaa619d4866d77221c54b9d8c843365ae248d685968e166000000000000000000000000000000000a2b84651691b96445cd6ec6b1a6f1caae37a8d7dc216993bd934ddf44a06c0ac1f2c5ec283ba2c5cc79e39aafee87f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001853e765b9ddb214e9b6a1b03541cbd66bc06ad66ae5be871938e8e3bb0ce68fd64d75f4e200c602d84b4f820c7a01cb0000000000000000000000000000000014eec4aaa7ad2b54e68ea209c34d39e9425fddfb21680747451ee0e0412ee2b1c0256526dafc09dee7548a485ef185fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f89634e5d6fe355e01c6c7233164d63e6367dc3a5520e6fea3dbd147aa9cbce7fd9fc38ba98aac2629f7fa6168145af00000000000000000000000000000000015306b8f46c5a1cea4517b98318eed290006247011a2a0be3ab51e303be24b0fe1749a2c1eb30b9375b53c65850a90b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033031e42e5e139061631509e852cf0b84542de1ebd43547e37c4a8af378d3493b9f35f87611f4bb147b926de3d1d107000000000000000000000000000000000ef7dd8241a6b051f205686f4e2ce67e6ceac4df93ce299edff5a491e460d791776f455a99c42bafed95cae8603ad8ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015cf7553686c59c5cc9ea059c701c6be23c886b5794921ddb63464fb2ef218bcddde42af99a98737a6959d06636a01030000000000000000000000000000000015b79e7d6dde6ec10d5f6d8dbb73a43f4922eb683213b321c51db9e8bb533013a15d7ed0f4925ebadd60b8388315da451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a24c0009badc2c8b01866272e7537b7786e8c3fb66bd77cdd8ddda8599a9209ba774244d6d18b4ca0d9512046ce71500000000000000000000000000000000100cdddee8a25eb17f88043321a1cf1774771321edf41d27cac7d9a9dcebaec18cdc68cc640de7ac64a354cfac0ab3051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142fdf224370c235f838fdfefb09fa1ef026d741d24bfe18f6b49926575c530b18ba328a81d873e6f8980f6c9c7570820000000000000000000000000000000018192bd931c1e2003f2e8294567ab9b6d8a4c6611871b320678d21fadc45cf7c7f275a8ae30ec2a0da9c0e482943ceb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000595ade45a1bd71a2f6930a0b37d63431fb0527824865b97f6841d839f71b5b956fd6ed807c9271d2290e208a0a363240000000000000000000000000000000013d3ab83e0223ce9a4727c069a59d6233acb527fd58548c38a65bcb1af36b2f5f8069bff5bff5b63b5ebdaaf083c318d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000037c14c346765731a5749b603481cc6f93963c041259fe7c5e22f8cdb2ffa66870b8a4782ef8559b9a534143ede6ce6000000000000000000000000000000000829c7314e2d2862bc6baeec3b7aa45bd2fbf5be9bfe201f6753c270afb1ce635c229edea98b89da821636127b54deae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001425d58abe34549bab67d814590099f431fbbdd1e7da98c889da4e7efa49ac58cb003ec6bb22a8185ae58cca2de8a5d9000000000000000000000000000000001741c76516e8c2bdeceb2ab1d9822d3d34ea267342a4da3a394e34799b41d3c88626b89c29b019a7b94ee231538594ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007422603dd8bd78acf6f36dc2384e0ff02f599e62aeb6cae26d59af16531c0890696b05d440749e6bd6db5b301ffd27e0000000000000000000000000000000012739703562e31a33678a72a1a8d822bfc4b0210b2cf936d3d4e0b8706c9e7652725aa8ffc88b1993928b8a544a013471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caae310c6709a77141a190976a8223a70437a9854caa397631f28ac4257894581c41022c568fcc2755cb6e2918b32f4000000000000000000000000000000001487940d50bea9f7dac4717f89cb5b13f9042d19836047d9d54b67cb616b94914770d7c82231486ad143be3c057089fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b42c2a87faea8def82a4b5d6da9a58ad92a5142aabd527601f584de887a4ccd3d7777aab11f55889a73a0ba498cac30000000000000000000000000000000003b318ddf9d7299819408daf7543b2f8869e280b320a69b654f1a164e384cb062c53d1c2c1506479bac8d9b7196d132b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019791737e690d5c174cd26cf5c9ad23271525fd7b60a08a09d77ccbab3d00ffae2acf2edf8e05842bf0e25c8473ffc3700000000000000000000000000000000161298f470f57284851315af49aa4c416d90dd4733ac63e9e0e802cfa287ca7f10e03d0b7d8cb49d30bf28ffe2bec96f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff82fc1216f6bf48793e1c99fcfe3ddf8dfbf1df20fe0981cf282e428104e220628109d5ae9c7ade1e0351017975a310000000000000000000000000000000006dd1b893f940efaf6f0fef340d9328e3a8d461fe5b3cf1cc6d4ca05ffa59e1da06d42cbc23e2c021bacdcad8ad347691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000759168487e5f38d8cec9d244d59364632788346bef56d04d0094e340bf7d6b0cf62aad7bd73ba9c1652e42de5266ad4000000000000000000000000000000000fc3f4a03094c3d528fb03a12d657227ce1e61b77bf733ed5ca60e35a0dd8ffa230d8c691ddde72c983a5c8ee6a4b2e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156293d5c5cc00091666c8dc47aa2d5c1310703af4dd86098618cd986c1256709114ae9298315bfb5c19d890cd0a928500000000000000000000000000000000137ab1c1277b8a7d87bb9b6940c5a5379fd70e730df4279e8956e84a32638cdbf61bca9b9a2ca126efbc5f1014e2d3951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065a55834e5e40d12f95d789adf364020bb11872ee7dcbca20cb9ba165cb885ad0151fa5079888476f0883e4893f96a7000000000000000000000000000000000b3b20eebae3e658afeb77b4e66b859035ae6a182edbb4c762690cf297a9b416071281df1c02af5dfef96c955e70eb021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdf478f1f0dbfc1e603344b61a34250ff8c08fdb84e8988815629eb2d6f0c011e797591e003ca7e620d2eb2e1484e2f0000000000000000000000000000000019ab5d62ff27572c7183af7e12898eb0554a678dd1a3b70b5bf9ffa42927af412a7b27591c31eb469092bd6f9cfe8a191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b5747d848c968d1d7f03387a70899274db7cdbe20e98a80d15286ced50e528ad7a622b5ca19f879467b2c3351fc3f000000000000000000000000000000000123de59541602ea9635375e572f01a39d7f9eba98b65e632ee36e912cd57db7cbf4d2dda750f07f0c776b531827fb1791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6f5356f9be7c05f5373b79d710d15b2a76df384adad6c0bd6701a1e9e086bf10f6f2a1fde3f06ba45c89ee87637fa200000000000000000000000000000000175f06c41428abc6cdd1a5f527d816b2d3689396a252a622fe9e4b822868a20199fb045e3aa8a811338e7c047a69c69c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130f1f47a101b93a98eb91265f032cad950d11a16ef9cde66a740f5a550659d0eab7795ff6c56dadc01824f7070f202100000000000000000000000000000000087231f19f246e6398743b15212f9faa3c983f016e052366b3454dddf9c79c20524cc3533472b9c0197bf405ec4160cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fc97f58472a01cfbe5429eb559c31a9a00c3e797e6409f5fbc2854b05204e5c147d77a7bd6442ade8ebf15a9327fea000000000000000000000000000000000c413723ae66ead9c223a074d47bd817984dc91cf4dfc49876e4feec4d6fcccd9e7b7e6320978da950deadc2961af5a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a77235dbbc1b2c2cf2ddd353c56707b61e75a0e28b3f94f7d9809b1a220c70af31204a6e1332ae860e17706b32d419800000000000000000000000000000000037b84256c6f768eb5a057c1a865ffca79c95daf1afef21aeae1a63c0cbcc729851ad16ffb2eb9f2481534020c624f1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e67eeeffcef0c04e53265e5534c4ece37385c767bf95779498c87cf72d053ca28aad30485d0d56806e606a8fc220e1000000000000000000000000000000000cfa38da02853debecd2c9957a22d4f8cd4a0c1b364d8d440beb3ce2d8fd51192d96113b1c3d89e9790dadc267e899e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000434db4ca161e47a5f99383e89572bd613591d2b90364ea863f21f471b50c64b3d1883bad7a8c910abe25e9be54518060000000000000000000000000000000001eecbbd35e2b0f0d3dd42252d52951b494de78bd425b7d7994962115a3d290fcc1c970dc7ffd0776d367968b0e3fea11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149c99b029149fe5e9d1f8d984e7ba22a7c591a3800a9c53efa65ffb1070a44716a4016cb513a8a81fca0fe8dcdf06920000000000000000000000000000000000cc3e08e02cbc862f4ef9da5d9ce67cd4ee543c887ec46326ab0ba60ae987d6eaf459d7667dc2b9f3f9a4094abc98e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013935d17a97687a562e0e048041dac85cedc728c4c0e96872276d4c21e6c4971b4df846467dbfd0abe22a51afd8a7c3700000000000000000000000000000000105d663335d884601da565e6e74ead6b7c4530dc4a22de901a5e1133b22b0823f30bba4d6e550b39d04f659ce98824141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a52cc8bc6207af0546a5acf66f319b24ef21fdbeaa0ce890b94d7c8c465a13826bcb447ce2d67de0acdbe2a92fd33100000000000000000000000000000000084ac9190de8c46d2a1dd590e9e40addbcd425a527345d721a0871486eaedf189bb140363a3ed30b7ad72d4d76166f8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b86efe1f7b8fb6a7163b1b142215fb82c8bfa83bde03ae5fc6c5851436ec42aaaa8c54de4a86eba1d4af8c038f68a22000000000000000000000000000000000228c9289d4806acb45d12062b3dd0ba94f64be372d09a48831f4797a2b9bca235ba8a8fe20dcc54275af7c28d880c2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005660aa7d7235a7b95ea3f3b210638cd5fc77c63064bc20741ed11e4693af1786f0d11ee2043a1f324e02190a126e6cb0000000000000000000000000000000008497aa15a31aef7020975ae0275a30d63a229e5421153feeb95b8c8e146741111a3c3ada3faf25480c3e9134728427c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010211288a84a0f734c6f00e56ec926ce191048627c29f0f627ce87990a484597b0383afb889c92499eb4712d1aaf177d000000000000000000000000000000001914157c0b2581c656e70b6593d7eda41eb915507099c5021073875a50f435490c531999515b81279c0ad2c7806651151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c25f3280b3f3f642ee083ca59d45cebe5c4b24a2a0e55e2592c239f3f10377001443b61403eab42ae64557b51ca06200000000000000000000000000000000001f14aa3e724ee21f9f7a0db09d926144ba53bb6f4226dd880c80b7b92a301af6368f3ebec9b1d8268dabbf1bb8dcccb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9605b895cfd007a7ff246d288485be5049cf0bf2808c2c3695a585f29527492f1e0981b38f8f597946f978e2902e2f000000000000000000000000000000000042768e6b159f9d297d59f1a3b4525e55ba168044aa4f374b631b3d76fde1d526defd64d56b4bd740464b56ef3363221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001a2d59f9b3aaa4d91f0d51803d559f4b422c16b9869cd3ab8954bb01eb7f64e6762211ca37b6c7cf035a43b3bf0dbb0000000000000000000000000000000019458cdcb53683713de1a020acb5666b91aa813c4440daca0a6d2b8c68d4c61ed1b4c8812af490c50b1289ce62d2c2221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013daeedd76807aaebe0dceb29a0454c41a5e1711680ac4c0956191f6e2271523e68b301ba3ba3637a067e0737aeea52b000000000000000000000000000000000c842f38681df32dc8e2b3dc48e9a98a87eeebb135ce8887a25320afd4a22767b17217168fdbe7673d0dc4f4b8828f531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078c52f3352ef8666b4a7ab6e02b751cf42ab0f67772e947903220fbc493ba8c729f89c9864e97d0adccdea0730b34a6000000000000000000000000000000000e88e0e51dc0c4583de937753513bfeeb6a0b83b6b8b916c29585aefb11817c4eb15198face86415c83cb541253171e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001523d527ba948b18a922f135873e94c86b72bfe637d8139b05a09672bd311f8dce4e77f9b70ffaf22fdeac6aaa8305080000000000000000000000000000000000ab481d920eeac58d2110432b0ef4a53a3b9dab024a01edffa8d5a0267d2bd593fc7dfbd26eb290f2a26bf9b81501451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031c17d1dc34a8926baa64c39827e2634df57649e866f6d5b5a466181e74932473a93f7821412af71776baade843365600000000000000000000000000000000179ae236d19e02702f03f79fc4a2df73f1e78d7e396f1b4d93b72d5c9e3edeab5361eaee8236fa10c6c9fa5208f5ca771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000242a54aa60ce662759a3dbc073e620cb1274b66b56607eb7226dc56e0d630d5f222357af0c925dbb344720b701e1900000000000000000000000000000000000af7a28c75b54681d31cea97ea0c1d0760f43cf36b38e7892f2566ff595c464c4c2658c7995e82edc8c5cac6e14e511c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000797ce7c88f8b92bee00c66acb9f44dc6b0c97715acb2551b278742046011383fe01f51433e846eba05fdde06468164300000000000000000000000000000000092a85310ef2293c4b6687ad3076b81f1d2fe2ca8ac5079173ec9b92ca368accd1bff31ec5f398966c8476cae1a58a0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001870ff2e74b8c9b9fbc0d841b0670aff0641cfef16c6fe8e1074de3cc167a0d7be96f1e313839acb43a3d1808c3db9180000000000000000000000000000000013e9b07debcf3c0cf834dbe9b976eb709e87c9888693a7cb279301b89a7f8085dfaa8a73e73b8956c1396ca83b29f3f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e61ffe58718c79d4739bb63ae922fd6a7ce12d0db0f7ce451f58b10dc8add9a5ea8c69e769ddeccd52c643992649430000000000000000000000000000000004d21e6b4f86c345a8297f0065c1c029c636d8e94717210f692c26cbaeb5153a94f3a48508b0497a1ce0db86a8dfa3e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e0bd9109a5fa9f2766cdd043fae09f8757056eed27dedfa6c3d400fa28501205ae172ce77a36846b36183b9c007f16000000000000000000000000000000000cb48f5677272c2e617776a44e8f3a3a47e24a59ec63f94eeaf9d3b0e1a70ae825af11e646f967a48a1a542dc0ab0c901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c2f27da60e1d9bf894295bbf715a029e6be14ff32f1ccd12115ebdcb0cc825ca8a6bc46524d77640c9884c05ec5e8f0000000000000000000000000000000015b9652fee7c9febcd32a5ff466bc4ebdb73662e411a3871a203330c5eabedf4eb849f3e86a819e60dd78af14cbb82681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001915de1c647292bed3cf0f626a0a7579dcd42514bf216c2a2c33fabce4dc630256911f7d82703882f622679262def9cd000000000000000000000000000000000982dbd51471ec2fe780f116c1e67efba7a2b7068d4efa76fb4f9b62b61d0cc717e3b4cafd4d33a7bc5eb86186326ef01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8b083ac5073d49f91dcf2f4dd2d64ac36b68e7be9aabfa1b1e006beaeef23c668787b499f55445eae76a808cbd48cb0000000000000000000000000000000014cc2521de20bdaa49a60c55aaeefb919800aafe54df3e682463cb44c847044aff2586bd53a677ed986cfd95353c31d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f25f87a363ccc6c50fa1ad639afe59201fd1497b0d8d534b0f78c1fb8c5f2f3ef924f607d3c038ca2af843564f0ff00000000000000000000000000000000010fa0c55838bdcc278abd417c3bc8fda1c77910576439338f4e614222894e1e7965d35804407bc86b5df14906e1698b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000504af0122b4b6423ed68a9063e8ccac9ec3042bd671b391d73e43a7bcf32fe01e900b79e38cb4bcb8cd19407c3c833a0000000000000000000000000000000001184ac4c76678c71067863c156d0f9a184dc7e141916e811475ba1f8ed7c734123ea6c9331248767e791916ab9df5e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003381961f2eb0a485dcf7f7b7cd3e9472c353b022c263f1ea50ba8b706cc31e08bcfc5d58165ae36309669c40d550ba10000000000000000000000000000000006389847fd6dcbf8fb896d7f235c93bd4237a0dc8d8b107c5285f8088b7e77de7a17efa381448a4cb9a65038ac02cce31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017837a963684a8f0d66ede7d54166d443ec72463365cf41a357ad4db67765a61b2780cb010b5e63dba2f0008e4cc0ebc0000000000000000000000000000000006fa81b011db765fea0328baf86cfb1c52a3202a9377c8ddec0ff7f096676edf5ef7bb723f77c9c4fb9fe2059a2ca8e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd4608596e29ffdc156e4ee9a34490e4391ce5635cdd23a3d14177c2a226a7986b32d612d5e75945f5222413285963e00000000000000000000000000000000193c7273463a7b626221da82b246d03d335abba13ea3dedf08d031054ec6bb2eb3753a212b364ff003afc1a5b02bf5c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c65946cae08c4bb1d5d9d9e88d8e1b6352c668b843887de7103cfdd11bc7cc8695786bbb59af1f9f5a62e74df2262f00000000000000000000000000000000018ecf72efbd7b51c1b439c3bf90e8569681ef6674b6fe99d602f1ecbd663c0a3267e1b473774c06065df946193b23941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a59b440519cc27aff499971118e8fd208d896f782d42d13fef77620437707b5253d00126e63745dff73b8bc675e879b000000000000000000000000000000001600c96ae36e316cb7000c50f5252b87a3aee98a8eb401b74e86acb28f9202a7f874dc9bec14b78f1a8956389e0df1201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037943a748862e0ef68849a0f01d6c46012fe33fb45414e0927767927c4edd4f03b23088b6bdd5cec856fdd8216f5b5c00000000000000000000000000000000009f3960b95c71c2c955b8b2a607503600b38f60a25a9b3a4d8004567803cda3a97534eaa1c6bb3753b2befbd08d0d521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eb21b34f330481b3cfa17d3e34daaf89d733c55c3117f84f87b42f00b52cdc00d9a25d9e33b38ae29a069bdb1ddbc400000000000000000000000000000000199fcc646fc80a71aa6c0c399e23da824f8a9ae85bb0b676ef1cf3f182c8b6cdc9267b722b5b1aeadee8b9396af6d41d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a58a23f8b32dd16eb33935e4f350930ea43ce627fda908e8369fe819a222eb5939b7f7ca1e3966af6a01ec8a4800b800000000000000000000000000000000100514e87f96d999e2099f3f43406cf7ebad2b0200af38bf925db6aa4e393d466f4781a95a5c65c56d642ec2c75669431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d6dcb70b9abf4de386a036e6fdd322f961006c0e41920e387b7a5614ce67a516804d1d95d4920b244b8d301b8425540000000000000000000000000000000004fdc7e22bd53dd8c0682178c299964a26b225744d1397112b6630454191326bb74e18ae896f431a115f14920fcd34541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e9777cc480c91a39b7bfec16ecb5aacd86e5ed349dfa7d87c20f966617a69809c915e8cf3db3296ec9354ab783161a0000000000000000000000000000000019959d41887cc7f245df9950614dbe5e058ad0688c46263aa930b8d7be6f685a15974e308388b07102aafa6c481d80191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d8c6cd8d42556f07d76f17e347175c2808cd9cad375c905d2cd49995a9c6bf98ddd511b67183d1659817a1384257df0000000000000000000000000000000018ce8cdf9cc7ea57766a851136b265f147758fe859d1015020c9c7b0c7152178da431f456cb996423e191bb5f9581af21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072cc6276cd004b85751f361ac83d78b81229dca5467fb4c478b6e27144618a8ed7e281cdc8c59c185fd4751b502f74c000000000000000000000000000000000b37960fa9e16662f389628c65bcee50107f850f3307be578896718003a0e292f4ba5c91162913ed28311be2b030d6be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e026e225dff7d20d43b1e68b5954f8bb501c667abc4160fef966a3a35de4b9407a8e540d16d6acd768688c53445392000000000000000000000000000000000e42d3cdd76f104bfdf7549e324836878a11832c56c3f41023cfb173c4c149803be2f179fea2d26eeeb68443991025981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099283e7e76707f7b9b33fcb838740538a4638e686562645cbfb4dd504d93074e2bbfd0185ac29546918f8622379c3f10000000000000000000000000000000002539b10a4c125269d0ee300256422899e48c4def2ae165df7d9f40607a3a7e65af2d2e3a12086010db80555f259aed31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110fbecacf2989d31877ffe36fbeb537d8f49ae677b1e2bb5f1a02df45bf4be41957f9aa811c3ecdaf8f6d48a6b08cfc000000000000000000000000000000001507566a144a09cf5faf8725163cbec5fc6e9ce61b606a30700fca163c9453c7f4baa71e5e1d12d78b5a6cb92e011f391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cecbe40d14feac2cc5a530b01543e2261a7c6432fc88b10e24d76bc1bf6e816c0fbe4c7f0fc19cf81eec889c324ae20000000000000000000000000000000007ea3671a42cde13027401f6761e022df18bdf59557ea30ac9ff3b33b4c37c236a10734ff0aa96a4ef3e24b2c5a599c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b654ef9a4cf80be2df1a1954b647fd43889c98c868371b195cefab2b44bb8ba65ceaa3ef40d7b25aaa3084592989a2c000000000000000000000000000000000a5c25a80823e96d7866a10abeca8cd60988f39e5c15494ea670767a8818a1f6134bf197c856b2558604ead7f14ec7571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022e77d0748c92298d0351f3ecd78a53051f85b370e803b3bef56f896a8c919e64b9f9bbe46163c5803e645104b613390000000000000000000000000000000011f422ef67a973c8548b933eb83b41a12993c0bca651ac4bde625932064b1c18ce2551a178902f7aca5f2d9e0771d4271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b25cca8ca1800f2effe7b73b26fac8bdb4dd52bab133f352556f0c4ef803b27e1db7efa46e0bbd0b223b61add16126200000000000000000000000000000000138c31a3c1dbbe739979cad8046e419d93ecc61f7af4a77cebac16f91c6d9725a2de02527a47522d8f8999f489f566b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b4541dda14d014b5c660c64605abbb8938bcad2a5a8ef88010be8f8c44ada7522eb9a926f6d4e15dff1bf46a63281e000000000000000000000000000000000379bd9b32cf5769365ec07a749880a08a52d90e6672e4f99e1d68994e76b124388a6fbd2fbec4acb6791b5f932fe5561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f327ff6c4208423a09aa244d0bb652d58457d1da9207d16de30d5e50b119aa5834a981c740b6c81197295637701f2fa0000000000000000000000000000000019b89be5e0c619603e6dbc48d8aa80e22a96e0ffa8d4636033ebcd34ebcf051c99e0227ff397181ec26def107407ef0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c27c00a28372d17b821465bf78b475b5dbe2d5e352cee5898c4cb2df0e96c6870f9769084e27a5be3d94a1e8f3bcb70000000000000000000000000000000015dcd307586ba7aec7c000f7bc26ad67266f8b7560c7e61cb43104484f4ac2438f3ec20ffc9c4d165972baeb1e3d97601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000959dafd305d580b6c5204b16ece2884125dadff0bb47cd4d385739da36d673a98ef3ca92770384e5154c837ed7d088a0000000000000000000000000000000009c62087e6d6a6f4ee5f9f85d246c61ed5050c8f4ce92e7482b5196c3d91b87acb22729afeb4640afd9a22931af79a851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001374226a3faaddd287c13d508116bc156e5dc9aabe3a8e43b7a4ba8a20073b9b857b29d34a626abdcc74a7f76dd150a300000000000000000000000000000000149faf8190e19640064246c2a669e061a87c235db16b29b0902fbbf6507ccaad40604d2ef4f42d7569c1f6dd5ec6c01f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012149361cb00324924ab1c537a295833cfcce0ddd985682545f5be462d9483eb1e7388bea3a687c4bfa5e3721c515903000000000000000000000000000000000b92a05caec1f1f8e8a19632d4e9e188d39364deada60764042d3bc49440d4e1c55f5e27a5c19c9bf4fbf1da5e106be51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbe62a12a4e3c6ee1c2d9baa17d039cd706944ea8777a8506ae925bf981a04dfd0d2af8776fd9cba93b4fe98a8c2728000000000000000000000000000000000140fce64d1bb8ecd23164d7162a3e621b95f4cd77352b207b0ff8f024f244c43111118d9932ed8f494393518e76cc351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ba939aed0955f2a27b9d4f1953fa9b02c51140da6cb6bff23a1c6817eb98392d0fcc6749ea10b493d783d9c38015fc000000000000000000000000000000000a737980b50e4aad5492d2f8314bde67112576e07fa771f82af3c987a094172cabc6fc93ae44113b49b7c42a4be1bbc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe73bb5219780f30966f76810f2bcf92fd118ac83947946827e444d139e720d87bae7ea299ef4fee23968ae543018b5000000000000000000000000000000000419177640d967c11a436457f42fbd1111edf2b34831b0f3784b45eada7546f7eb49d51bafa47d63372614d4142bec2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b3a2585f96f27e335db7b80479d716f758abbbe6d5ae2de8856e6dea0b09332a95040caa094af1e3a06dd59e047b460000000000000000000000000000000012c7467ab17344443e91ae8220576293be411e2298b528e14bd341a857674e0a7947edc5d909a8eff1bd232ec4c0ba6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e869a41a4c8c3a7cc03b60146a72c3b07eb9208a6d1ed57663f2be9230987323802969d4a30dc7c61a6dff04bd0a48000000000000000000000000000000000701fd43d4f9c3a8fa880ccf88a7168e13528ab1f9989d7593c10779fc1d9263d86e61cd99d62188c3a496e054293db81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f944f746e34e5c4340518f2c43a59d9d2966fb56970cd91901e27aeee3d43b35924995042d7edd139d3193ff6a82c8000000000000000000000000000000000946c7a80ff7690530bdef41c69e7b116498d75e2fe42baa7b942a5be82e150461cb82db3db8ad6ec043870130d9249d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013082e93c4df7903a6ebb9d3cae1553e7ef457579b8cafd705379b6299534aa1a289a5a1f946af3b03098b0977a6e9dc000000000000000000000000000000000e10cc8ac4b9ce09c91690a13b6b2ecd8269c622f27b7e03558139d7dc3d3a4df5d271d722a5338f47b0285068f03dbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003721f1df3ae17b3bfb440ea29bd4518848935974e198d881ce3ce6a2ca38ec1066cb9bc7b76f02d6f3b5e27c192fa07000000000000000000000000000000000c5713077165428ffb53fb892df24543c3ae20dfc5f98ead0c0f4e7d9299ccd22f581bc67e84f26af16b86d4b1b679411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001764325a97862342a95fad17a3a56be14d320f120b310e3e043790cf581afc952aa5013d3109adc8a34b53bf2baf9b320000000000000000000000000000000012c0c53fd6b20e3c087306a781fa05e5926477fdc5667d68620d7506c8bb41cc50028c79a96d72577a73a5cf5db4dd861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d52efeb200d553e72772fe4003baffd1bfa8ab21e791447d68ba1a9ede29dd61ce7602455832ef04e100d1f33cc27b1000000000000000000000000000000000d8db28b044832d2ae490d7cfb1958f37c1e6d3810ed2be3280934757bc073248daf65da68e8ca282a121fe11543e7971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002baa028bfee4ea2d8383a594e0a8dbab82e195979c3da981278174650baa06296dfc845e3de7f8498828ce57312d3d30000000000000000000000000000000007a5063759d4bf602df5d1539eef2114e40b5248065efa678a35f4beefdd277e8dfb1b1f555bd20354f24f5c6c453ca11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001841b858e4fca2ef8c6dde997b14e0f74c1ca1117ec3d4ea787f403c44cc2437b208a01214daa11be9a42a5efa7b5a700000000000000000000000000000000000e36da1ef990e8c6ca161a5d935e6d40d3cd33029da27558ee5ebad8646eb269da33e77262b16fd02ae759ff05a3cc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4101b03b3899603b7fe2e48e2d19ecf0d1bf3292ccc6e58d9fb7e5f9b7f4f8e58f33c5c0e28d0f0f5e6a88f1a2eda4000000000000000000000000000000000845e086f6a0bd9ed7b8ce67426c2c7d6a7535c127c88e2c223756e32c7385b52cd25d47dffe4f31d15dc659f251a0f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017362e42f80fbe3d408a55ce25f7b39d7927e82d0b71a202b8c2fb05e7092a27bacc9a04ec0cec2448da08005e4f1fdf00000000000000000000000000000000079a8ea525e98d5ab3f4bd0b1e428ad8c2bde15e4c3b74d61258b692f4c497211808a46658c419ce3cd5173f1acde14c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000307f5701f7e90982fc03739cee3ea484529e0c88cbb34d692ac3ff7f4a502a05578b3323bf3aaf62433dd4f519803c00000000000000000000000000000000131a48875cb930e87f495a78e80e111030c3b13ac6089caa4853f08f54689655fe30160ca3951fa5de1b8f787b7917ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095a56aa6424772e757dbee4976cfd6042a66a37f42c1b845d0411b7fc7d359704ddde13deb094b42342834480da13cc0000000000000000000000000000000016ddd1dbb74bc38b9beb25313d78fe91a6d088e71b244d0586f93852eb5c9a79d3f810bb9e40e2496af71a8f8615c4021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007206abacec86893ce4b7be5673cbeb8ccb80a1e46087472f542733c163f90a1ca524b448aadd243b6f9c7e214c0ba7f000000000000000000000000000000001570e0208b9adff5051da5aef7a8b3d404749ba7db925e5831a1bdcdb8cb98ab30436383edc3f35d9a257dba55c1965d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004deb1a6b8ac7248cda184a3dcacb67771450303d06be28185c26ff81ebde1dd49f01ef1963f9d8269997dfaf12382e8000000000000000000000000000000001200daddc288898e8ebbbadac3225ba68000779d55a049401228b4de1eea69394e7244a2f96ffd88fff3b26e171cccb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b9a5f9d1d00a5c9a13245f66aba3484ee8fabd4fed08ea3ee2846a8abb5d2e3e170f500b0a6912241ee26f82f8403100000000000000000000000000000000189bdcd1170a7eccd9474183b96a7905f4fa970b5af3ce281f63cb068f86bf255fcb9b7d282e3a12e31e8053c9c590571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e97979b8db52f4a8b32e74404b61521266049a54b5c0e5e16367641776b0359031302dfb37ea189438fc45e2f7a93c0000000000000000000000000000000016927c16874e70b9ea3ec9ff81862d62704ea86e3cf2fe08af235435e49a2fa868aaff66e975274dc7723147421844411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001336140109a3b222ef3a8ff1b5c43472d5afe6ad9d3730f53e4f442d54fcf72993554ac81161cbfd965b39fc28df12ae00000000000000000000000000000000180e2489700d2af03654fc0daf434e91f9c13e2404be49c308ef1c96140865b38b153383869ab05fae2445b6d16998e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016d756d504d51b1c16737783d8704b5c9b28a6c2acbf3361fe675a2a85b74ac38ff4fc6f1c50a74c5aa6f13df0842aa0000000000000000000000000000000012abbc0c41bea3154be90981f370cba3948c4615e94b1c5684327d107bcb98980282794c42570e2e72985e1db7dbbb9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007feba989f5ca654abbb9c3f94e6bb2947044fbe8e24a5ade346bb8e21850b8d1f96f196d49b5b7a814e1ff18835877000000000000000000000000000000000088baf2fbebfffd64faa42240afb4052cfeb2ee7fe655f81ce5d90d5e5fe6eb795f7c8fc298ab18e7c7f1dd59c5dd1e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b396bf889140595686d9cab55f8d0b5f445381e2598e7e09e33f011457e9479f96cd8b82b1171c4130f158fddbda8c00000000000000000000000000000000089481b1f774bc57db2c55b869e57021b263cc44d32d978fe6d164db60a69fd19c2196b51dc3c164ead9982fe59ada371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076408fba9c5def26d5c4e2d51d27b9175976dd76ca136194107ad2f9bd2884df7d5a388865fcf1a69d7d65b88390ade0000000000000000000000000000000019ca52a9f338f7fe53c84fecd2b7b0ba685ee00c0468ef3f95f20d59a8fc9fff48e95af7ccd0ad2b5d54fa2f8d26778c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ef5ed1107b0cacfbcd0ec4826a541dfaa58012bd36d8e7d1d263296d00263526d59d74c30f5cead2b21c295fbef09100000000000000000000000000000000134234abe4f6dacc63d81d72b4ac8496871ee241b273bc6de57ca7db986adf2b16efc9824ae5f1e3b86568ec1e52e0a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130466efb332149a161a753dd9081cd125054e71a6f4c3d4bb518bd18a1dacdd15588961e3e7152a1b4a7d8f10425624000000000000000000000000000000000bb37247fd334f757255cf369dcd160c3c57c66ee59618f001df3dd82fa8e5f22f04bfb745c20e48a6b9540296f3c5401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fec50fe91297632a74949de95c6d9709753138832747c05c727cf3c762462630ae4f6b40db59f6989521a2047a0974e00000000000000000000000000000000076e8039cd188a076f7699f9146a755b204660b9ab7a2cca2f52eb4caf23c39c15190b90a9e4d6a8e9dafcc2e539d14e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d46ae8b44e23ab46e6ba794472664605b4708d0f8058eeb57251f7cf5cedc7892da092e7cee4b41d4086164c67b7ea0000000000000000000000000000000019d6acc78ce3e0e1b5a3112dc9d11e4b0d8f6d01b14df117ed2dda3f95f729ae97daa2b2716c31d6a886c1732e4e5b3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000601b821982b1d3cc47d27954fdf58a9d0079f3938ac8739e6881366ca95e925b185fe5807a1a084f73adce26cb2f606000000000000000000000000000000001566cf78b7f467cf593f6bc497b722374fe25c5add8ab1e37b0e7ca0a49eed7a05d8fd5ab5ce192f5feb3dd4e751f3c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f197ab1535890a0c9dad930903a18fe9182d62fb0a5febdbad360e3393628350f73b28fc02e875d6db20e28431706ab0000000000000000000000000000000005a94ec83909abe938e8e3b8a60c9a05cfe52983feaaedd6db606f794fa5981dd6dc45d3bdacfb8c475cd82702fd92bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a55c09bf72cdb9204fe57b1bc49757f4dfe647f8273b02adcc22a8cd5505275aa02abd5041da83c065dbfc0e46e47b0000000000000000000000000000000002dbadc1edaf5ab65dfed69d700d1303559a955850089c011e76bfd91a5e4be68c2633ead93bc55164d1b8778ddaa4991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092d628b9b8443c0087bdfd3b3c1cf9060ea2ccbef3388acd130b6e85d382276910932e217b65d8280e0ea59ce2c32ba000000000000000000000000000000001906d266723fa2e1a7ad20c97c596be4c3ed6844696d3554e9332f2d7d41c2e3c7d47d88b9812722ce9ecb03c8803d191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f031599ba21cf15e24afc2b5caf796c7cb5c748260dd19a0230a934acd1e4f057e1fe5469d7088366f06863898348340000000000000000000000000000000018b3aa8d5a1fd73c39b23330ba6ce150d85e744bdc4eb1e89e79176e9c55b5ea5724c9bf64207c654fd61f363f44ad021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001994a4790df134ae14ae149786b027943fb4a222487d0700fe64dfdc47b9309d7d14c2221b75445bf0cc3d87325a14b8000000000000000000000000000000000d753cb5a28081096e8b10887df5f787e718be9e37a4f9f25f514015f99d56536953b0122a5e44d7b2ecf996845dbeff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c788b4b3d572bdf266e1448d6f616f5a32190eb36cf86f7dcccadfddc6b8cef2d6e8176f5337986c1d031f52437b3f00000000000000000000000000000000103e58853bc4e821aecf81aa2eadff7621983d28ec2b821b123cf70fbb83735228cc917282e58ce1f69af939efef099f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000759e04cd6bfe63141c828c35b726af3cb300fc3440a7f53131ef96793f0337280d58ec44d4e9220d40b1ee4e28a472d00000000000000000000000000000000185ee56d6b2fb9b54fb0bc8de6c707cae9abcf4013c404f4e60021b58bc9478ed964924324edf02a3fdb4719f78eccb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082a4034ac630bb1e6c175edb855574ba3a32e791578e0e2a37eb77e5ec0e33e19c5e381f589fc495262e266109755f7000000000000000000000000000000000fe4ff65445bbdbdde90a0e24fe3ae9b60bd114166ffdd96e540e85841d6d7b2381804880d61af92494742b538ceb41b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4f52c043bc5b7061b70c32b75e6a23f5d60625dd5be63c4c0feb62b93476043c55981e5dd25dacbb4940fc49630fed0000000000000000000000000000000016c4dab374fdb507264de51e1c02649b4948c5350ca0dee8ecbd006c8bcdb8f6140ec707d5c77e86bd571b2f89db44941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017604117a199ffafdf9e3c0c601ddc97700d971d684680ca555e84ed5800a10a852c4438c9d4ef7dc278aa7e21e24c32000000000000000000000000000000000fe7425221fe3dc62b28c3fb17bf1dd1f75d70ce46a66cfa06fb49d72827ebe7521f036b6deee349c17ab53e382c87681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000895c511ad824039acd2a68662ad8861267233ae760121618b76ddd0331f85eff99feeecde95fb5240d76e6bc9d8652e000000000000000000000000000000000aaa407055a1894dd30a00d817ecd16e1380802b1e50aa76a08f1b1fc8b2e2b5e8b05f07dcb0563b75d7746eb563f2751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082913ce03bd087958281d6d4e925c3c4973047c7dc2aa06e08607d36db0c7aafc52ec8271f6052fcc7a8d1d48946e2600000000000000000000000000000000150ed6050298f26cb78c2d89fd247d2b03f6eb9f78bbece69b2558220288a3e98edd11e34dbefaa944eb3ecc50bcbc1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001220e91025956120ad3c0a1d195ddfb03a24f8295f7da3f848f3ada7aa6fc7c428a9e89b1f03e4c64b6ef3593f11b64f000000000000000000000000000000000f679e8346db24fd2a5e9c97c196e1366e96b9b2e3bbdee7bfffa2e81317e62edbf40aaea46f8edb33e0fd78ff30180e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aea4d6e8b5bc1fc871500e4403af57a39db7174e8eb43ef5400067d295c4ce4fb98ad8a583227ddc22bc717d2055a610000000000000000000000000000000002a91e7f14f3e1032f0ba54e65118f182c877de098ff265469b1c9c0e3d0ca2afa6cca4988b8f4cdc11e4b681e6d5b561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f1b13f8a0afdea83dbe58f2d7358004df183103edf053d5a5b66684ef801d7e552b030458807f773418758b411a5f8000000000000000000000000000000000b53e8b1c0993fec54d82110a0d9f0791cdb45f507dd853267935125e09d8fc191c7da072f15231ea5570bcc6cf1375e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f15a7f2fc4d0e6d99431e54d3c1ec067e90964bf6da6333ae11b97067e20cf85750e38797f2dbe72b38a0dca0c7e6c000000000000000000000000000000000141a00e60a3cc05d4b01846fbb24740a28e8bfaa1229e80c28389b0817519c0ab1fbdb7ec96c94d4509450fceca3df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001480b1cf8cae6f1df6df5b77a5a018f32f5990fe2d9143ac9c6721a63db804ffffdd63e360bccacdc6b5f91f941f9aad000000000000000000000000000000000d6187fd6d329a2d2fb7205f6c69091b5e72eb4d693d7b44be1894174de0dee2400a8c93c0f8e30a535b408ace483c641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001232a3ae2a9726895a150c79e151e0524e32e4ab21d2e3400752577b92c0034a51f563f1b817562838fd5bfb6134e606000000000000000000000000000000000212e413ae3de9b098bd15420948c85bf048547ef678c1a28116d5672a4df10965d6a68eb388d6c1ba6786777d8dbd061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197846af412005e71496df79f0c8c35cbb0f0be4c84ddf0928125ee0aa21257464c5b24bed0b8a306f85d9383b1f6d4a0000000000000000000000000000000000084999a9761157a601820ed61819636e5d4174c2e02aa3d442887757daca735091a755747e9e104818ab43f3e70f751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000470f3a35a1b8d9a0fdd988567da1ddbce8ec0eb777527f29fa94c65fa07250eac6facf16667f7ed3891458226ec4c0c000000000000000000000000000000000c750070aa47567357b042e664595687a7a9114176d88c141d035156d3f9a41bb43ff43e16574a16b03081c1286f8cd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040a06b4b14da7522eee96fca05fd48f0dffc4c7529f67c58b188eb8b1d9e2abdc1d9118fed5f8bcf5c533be105ed69f0000000000000000000000000000000007c17b89bdee1a4418099901a65da0325a3203f0e180609344bb1f647b6c9745be8bfe3d7dd90450074bb3f8b8f431171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000140977dc235cfa7da42badb6dee5b180337d5be4a6aa06949a6f3183224f4eec24af01bbf1b128b95fd3b3991592973000000000000000000000000000000000fdf8cea050130ce6baea53d27156533264774f00753785f9b66aea05949879f137000a2289ad657ac97832b9779e2481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b32f3ffa905b1cacacde77ba1dacec89528def3c42f8b501aaea66b316ced3c7b632a1c5a45f9431728c060e06c092900000000000000000000000000000000129c84e748433bf402ab0ea6ae5868064dae4c09767ce4fe8b3064f0a1bce94ac547e9119f3228846a903a3c84551c4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a535796c5cd1683eb3c373ec66bc837c2e37fd06015c4201f8fdeb2a4c3dac307c7e8554c6f3ed2d82d051800513d1000000000000000000000000000000000e25dd60588332be0b546dc7e16af828ad17ff9132c1980de7132d80a76c382d7bc69774818297044e0271f2b6028bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001417ef898ca333654e342827a80d621ff18810661a609ea6cbfa7ef25001bf694e390511d1c0489ecac8fcb368a9db380000000000000000000000000000000011a193bde26ec56f6583d76f7ec43e2cc1ad86384e3d5c9574ee0b7a5f0d2ee2d6da1ff5bc073b696ecc24107543caec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8ab5b6a5e45ef44620801c0726f3f03e072888055b0bd7d767a9fbf4760eb70a959eb474c8da8bcf4294f22cfb44f7000000000000000000000000000000000dff76fc074985b900720051408fb3bd0340fdd487d5cf9a7a8d146fa6b3a673d1fd453cb4f7ba06a167738b9323acd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008c3508ff0d3925b153cf4f37ccfe0a042f042d5e8e98f1ad80d1607b1ec74b6a98c09d48ea48f19b96f2be06479a18000000000000000000000000000000000fb5743cecaa42cb9ba6d2f4d5329c672219b9e478c691879561c00d4ed801cd23b1329f1e115030cc9d3a2f2a6134801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c37917aa38aef28855ac55a34c73610cdb8c6e0e4c8e69e2fed1af5628931e22e58c7b8e356ecda1742ccc4d61868c30000000000000000000000000000000017643bae0b0cccc2c94bf0ae59802fe91b6a04374bfe3f0c7874ce435098d7a091fd6607e651711d5b88ea227c43a6551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000685570349adaa9fe48b0e12f192e28e76573c86bb8343244f644f8124d2b66be6f51105b2641d8d6634169802bbd630000000000000000000000000000000007373603070b47a89660674e1ec35b57472343c4a47a876fcb83e7042320648f8badc47a6ce6df84a56616218209d3941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000417b236fe09854fa8b6fbd304b450674f22c6cdcb21cf3fc6c1525e10a87ec296683dfb5be661eed1d7742217e24055000000000000000000000000000000000569fd7aa0ac0588d44c06045469cfc11eb4c8fd352c0d9f2bc613d4b2cefa642cff9e9ebdc7bcdb250ab8f00a7db2fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d59699041be95d8e3e5d3b57163f87eecf9dad15f3df46f2eb0e942452bc7bc19ae8a8e02db27f630617a662b01e7f3000000000000000000000000000000000108be5b5f52aec359bec1955b5f2c16181c0da201db6dcff2b86cb002965a2fb5b0b7cd687fc81073752adce855749b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029e0569ce7efd45f96cc3c0a5e53da1cd444c3a27396d31eed14a60232e2a74442f3b6ddba3abbc1947aed187ce9a210000000000000000000000000000000016ceccbf33d7051dd100b782e26642de6a995d30e2fcf659f488aafd665baff51ab2e3242963a6c622d270d205e6df141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004667a4fcf3ddc6b3fd2cf20984dad32840c5c5d412d78bfd9e56f860549d8782ef07fc45b40d28e4c034ea1b17a8e26000000000000000000000000000000000a125aa927092dffb9c4fca9d6f874654dab8d7838b7b7b10825f763eb6767fec8f74d4614ae5eeb43c8239560de9dc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004411261d3faee96dbaa59988eb64e7f66095bd1bcbd8264fdb291658fc8772daee67968dc98fe8492ad3fba6f72f4610000000000000000000000000000000014ec1fcb60acbcc80c9aef300e426d3a8698c30ba75e854451799434c38cb19bce1fb1adbbcf33d4e19b1cd930ccc2381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016dae937fcdb65e634bd24860def5982b112b750b91ab0a057dc13aa2d5cd3ae6cc45014db447bdeecd9708f9f91579f000000000000000000000000000000000f3833cb40cfc03e00ae502930af502944e51ea4ec3127dfbd9804565a897536d0d13a9a26b3abf3539d37d5e49bab741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a895d2f609a062c21554e0874fa41d8a21ee2c115441bfa50985df795a4ef40bb502600d9113fc00e653cf664678bb20000000000000000000000000000000002e8c9886cf24793aabb82a57893a985f2c0e590df6f30d7f0c0a0e124aa57c52a0833b153ad614335236f2c89e794971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb0d59bbaa9737bb4c90b1b5e331a09ef9d96e521c1f1ecc2f79ead7c5059f1f391a83a671f496199a3ba2589addc8c0000000000000000000000000000000006e541162a11f0aa7fd4f48549a83a3bd63c5eefefdc25d3bf04ce81f86d35b162558222ca0a80bdb165de21e06320011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000655ea6ab02467d1c65c4716780c9f22f40782b41ddbeb6da9239afdcce220e40512cdd914d31d7ad7332248ee783e2b000000000000000000000000000000000d9e931a296526a99d3ef08dfb1d4775a2e55c836bb0e86cd3359efcf67cf865aa531a8d49e143e9086fb0dae3087d2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a281a4b80cc821fd1a13fe5a2e6ce0b5370777451fcffe8431835f459b31d4074cebc933bc24e19d1350f959a557ba30000000000000000000000000000000019b9fb71bd4b7a2807a52576401dae1aaa1dfaaed062db9499deea249b2fbab0d26675a8e8391156125b50f6dfd861c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000031d083dabb84d61f57cf41f75d0b378160dd20ea659828ca5681cc82f66d36321b16d4db29c7603a5a81723c253f970000000000000000000000000000000003dcb50264ba8286b8cd0494bb0db3abd2703a9da4149249431271102709b377b958988fbb3928a1d666a6f963dc46851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115e6601da2dcda7aee8acb6fef2150899275da9a44a84d3a5db548a42b897fc8e65690f7c38536345df9dd618068ae60000000000000000000000000000000002d4681118aae618a15a005cece766f00054105cde059d419fdc7b62cfcaf5c158962885913e12eae66917e4c06d3d641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017011b0d2246f43beaf8dd707d6881e4950aef1e08c38e08cbafcb2af7e8ecf4940744e5353c37ebf0068a4b8930d5dc000000000000000000000000000000000b34ecd6bdd1f4d2a5d1d8bf088abdc4be0892f51e22fcdbf1f3b8a969577ec6b14b6f7e4269d6ea014f2ffd8729728a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f8a4443e250c7fa5745cb3e719c48e304d0ca344c22d0226d2ea65e934de8898f4ac7ac5a643cccbde9246c8ed8e8b0000000000000000000000000000000001aea5be3c7878155a5e43aec8b86e62757d2a1b5211941eb2efe5346ecf7e9d61f3aeda9526276cbcfbd0251d5cb9941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130df446b9bf740740f503e9c3d8c6f3e97333e0527904cf70f230c020c7a6ea6e2c52ef334391177312f0099c801bbd0000000000000000000000000000000009d8f1e9f87e13cab8b5208de4833d870158018e88b86aa380850b0b6aa9c69bee37afbd7f25631137f6a068c9d75e6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012a98fde1b4ba46073935f7ada2666859038e7668e3023d8d5471cc6835c9d7fe56d10360d348e279a0a9089e08d9160000000000000000000000000000000005063c18a9bf161b6d7e4c11fb7f774b48c1737d8e2e7258f655a7f691995bd5c7ef9ac3bca0bc27586fc636a6753e581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fbb522ce0dcad916b7fe27db8210bc75132a811ccc966fb1cb10f839291a4e064df6db0af560bebabb7f0dbfd6de6c000000000000000000000000000000000138004922c7c2240ce8a221eadc88a2dbc5b41af887da8eb34ac9caad07a5a4dc5528becf6ea955fa23a0a6fd4b85c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168f7c11dd99679efd54b362907320046e65d1e9b0f2653f6b4e98a2db621c601379baffae0c418ef6bf41df18c48cee0000000000000000000000000000000003d1e78881301a415182e6d1d29999ba1de23dde7954e6ce1b7ac7e68ca4ff324adea9886c41bcc6d0e5af0f1edfbd181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e84003be9055e3775ae2eeb9ec97602156327711008bc6dff034a075294016d2a6ce2a40b26e1668678c25df6b7022000000000000000000000000000000000225d84753141fd56e9be6e4efa1f9621cb95e6ea635fb3697e5503954db3699b24c8129b7ce8323badefad6c025983f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005580465f8f9ba4bc4060d856fe456a88ba432a7c4d5e05e999fa877292f4adb09715af85bc1fb2a7d1d543453ff8500000000000000000000000000000000015bdbcacc9143c4fbafa1255144cf0e07fb826117d4cb0b24b38f3b60f482fa5fef3b0d9ac94c39d6d22db765d89c40a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000779171e02bce548bec3d1094e41795803ac275791b5833bcc85548e1054260e74bceb273aa583f2b425fd07c9e67540000000000000000000000000000000006e7cfe6ced8b9cb867ab34219e8d6c12ed27a68adc69777b34fcfd00ab9699cd45fc7987aa8587f462f680d6d6ad6571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001904cd4d37d69f8345a72397bd0e4db961c60ec9c5cf44a49fc76c0ba468078ce61352cd3bff784620d3beb24353476600000000000000000000000000000000140521926bddbf07547b0162cc6c57de98fc9a15686a9de12f86c0a81715183e5ee9cc7ec2149665aa1f77fd9baa31381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000366bbc35b451f297b8bae0fae2ddb6f8130c89a297ddd4adb5a84cf83c48736db6ff814611a51cd9ea02ffd95b85eb000000000000000000000000000000000cb73fdc813ea478e07a1f88aca3e17687fcf83cbc926fe4928a3fda683223df1619e2688a495707b819a43cb6de1bb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000501b3428c2674ddf7e7342964af73326ff93528d137a29c976cbb95e150110a477bcc6a517399eaffe8b185517eab8f0000000000000000000000000000000001f2eea4573fc994596154a1c7083cb26b8c7b64bbdd2c121eb90f36b25caa30d766a2aaf987961aa378092f84d42e741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001363f22a2855c14249a1f3ef321fd39780905982d5c6b338b22074f2497b970a82241e2b8538170a3927d5d428440ecb0000000000000000000000000000000007f672f968b23ffd23b79929b0e16dd41d42fc97878e9467506517b31248b2094faee9f8605e6debe0bcc3ef9908b6101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170b24df30d9c6ed018b04f31e02fcb07bf7f89ce9ba5f1e2b0f6899dbe975bd60266f5e8240fc130d18519384b957ea00000000000000000000000000000000157913061578ad1cc083ac3d2decda6b2effbcff260a802be3276da9e9825f8ba23a190391d26e9b04c5bd1130cdbc201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115e1e1f545c26058b93dd5c0ce82759aee69f928d06ebd5519e3830d08f3fadaff436127c69bd9d03ce949866eedce900000000000000000000000000000000098d4f3fbf6a6db281f6262ed2bd7e2f7af47ef2e77f2876de489bd9ce3b8b241330437a2684310c4ccb1cc2b28119971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000496fc523e07eda6a3d01caee4a9fd6ab93174222f9ac3cc62207d3fead137608435792d0c215d7ad0434c08b4577643000000000000000000000000000000000c3c349e1bdaaa6e36300610899762cea2905a37e5e72bef8bc5b80c411a549642c8fc5ebf0ba47042b69ba4e5fd60e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e9d56e526441f93993fcb36470c12c0b579b616bcd5c63e1385729277a6a27c4fd14c09f1e257e032562aba8bed4070000000000000000000000000000000003187bc57f92772ac2438c51bead0219b5ec2886fa0a780b0a699f345657f98b77fd6cf784c131cb87c04c26b2b236741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cac711712f8d16422c70dfc3c2b88984bd47be413e8002466bba5460c8fbdb7694e4980d500c05ba5f110768b632370000000000000000000000000000000001416292bfe461e0f910e821792cd92820c31628010335b94b91528cf3eb18fbe87534ff489cb4528fcb2285c0fde77d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010020bf3d218d9515448fb3eea708191624aa0ff10ade36e6eed770b71fcafc56f9d386ca3c6656bd7edce08087122a500000000000000000000000000000000140867bf7105643cd23a030d547ce83850e1e0304c2274aa467b172fe432bee2ac082222983793769c0d3804b63d79441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a6aec9d7cd3f027dededc638c4c6b3b2a7958fea48bed0fd2bc675313e4d2ba12d9187d113bca0850b17e20e2e6b1200000000000000000000000000000000021656c781b21b7383c8f90b1065745cc750f056a4a20610e3efe452a28235d074e247fff074fdf4ad9718497c10e3701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000993cee3735705aaabb0eb7b0c05ced270af2559911929e4601729c283952b5399226d6caf8018414db54a61cd814dcc0000000000000000000000000000000004f8ba2c096c1fcf792f826a7900dd48fd1b72f4cf6f260941b1f4d4c1a2727b7ae30cd274309da12f092ace6b0f565d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095ef9449afdf574b92290a955bd0e7077104a5d94b8c17427a161a47e3b970af7fed5ab3e6fedd961c6d11ff8ff671d000000000000000000000000000000000e2358fee0e7a559848d30d1bb3f8eaab926d78d11ebf05854f653f6ccf8b9ed8a34114b881207ebbace86577b5711541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abf43984cbcbd25ebbf9b5c5686be803d2baeadbd4ac4e769eac118352d21c331a86fda6fd4128442009989206706620000000000000000000000000000000015f80a0d1dda56177a48834833e214824b99c0a6f408b4e8e99355b499fc4199387b50dbd61447ce08633a9814c5421f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee61140d93e426376c13cd8a8fca79f3ee99bd601881e3b8d8a825601f1b8f1818e011365f8175c26b66071628539bd00000000000000000000000000000000193dd261d1482c0579157b4baae94c9c7b87eda36fe5e8c906feb7f3cd54bd0851822995725081557a35557cfbc10a361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042435457b5d2d7d5e3dcc6367842a6a88ac7c470a9461c47780c7a5ce4417e0038853ebcc9fe7fcd2722df539a3537e0000000000000000000000000000000017f685f25839da010ca2e599586636dcf1fe2d5666b494c228994dcae8e1f3b6c74bf0c8110f4644cab17e6590c0cee91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a1316bf89d5c10794b2f1770621bad1a6e94933fda91f9fffb7fd58cd79414e5f2c3ff9c4ab5601aff27bb9f008d1d0000000000000000000000000000000014771ff9753521e4dab0d6f0498ada6621b64eb690c469bf5d86260fe105f68b063661f12edb0fd0f66fd4f91c4ae1f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f6cdd467c5524e1c4ed88e8ca75bc3e00a0c32edb01170f3606e6cb38800a7b751e0824a5cd6c92c8a6286f1d0edee00000000000000000000000000000000024c22cd170c400e847ac665575230d66c47f2361a45ee9acc08c7ff80d99266ff2408bc1e341f20eea482b92e149dc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b126a68a45af7dcca9fadd40031ab4a8b92707518bd389781366d589dc4d9491d4293ae3b2cfcf5d24e59c1f2b9d51000000000000000000000000000000000eeef1f0c26c47d8ca8d52a3474579bc6e0bb3a845c81e9161281ef3dbd80384cc171250e134144894c30ee49b10c5e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a576c1da3e5fe21d419a0530f3d4444db1e2c067fad0a692fcce400e383f3cb0fffdf1993c06f0ec337d93e63cbf13c0000000000000000000000000000000002824120ca2865d634e89f2b5c32a131ff9f9efc5e226dccab602dd37d7e568b3ace6b8c8b9f55e98918567483ac674b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043d7e54205465d0cce77a05441f216df5484fcffa68a691106136554332c8a9699ef4dbc90917a625f9549e5ea08807000000000000000000000000000000001769ca9a6efc8f69e947c853416639055e24a871f1c1c67377db631c4bd23772785ed4cd667278dd153973b81f0efe251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186f4ef83f425e13fa82d5e4756b176fc2f2ca2ce05ba273924d4bf282a4b2e9fd7f3918135a14e9e4ad99f2b66f45f60000000000000000000000000000000000ee32349fa4ed2759ed7260d0f75798263527cd741bc3e16a7ec8b83bef0fffef25f80d31ad47603cd5ad44ca1ec1721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe087ba8066bd7f0f4e364875502e149c8512b684cad0b60190816e1f5aab2a7af75e0bb11663070620f4dab0b892bb000000000000000000000000000000000c8cce3300bcc43ed7377f9cb97d51d2188b76a0c4eab20c884da991014d030b21391434c27824553c801753631376be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006441569fd4eb04c729df0c562c935b3d1e7ea29b11c39dcd92e32cd4a793dc7856ed9dcf293490b6c66f4d5ff7cccb4000000000000000000000000000000001887927525329ac248430e2f6ba5abeb1f5c285f1564d98378b6666b5501598eebceaae66a126f57562bafdc91bf59391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa13c71ee07cf927940acc09be245cf9360bc3fd1cf22d049c0596faff3d879c0089b9036226ef1351ed5be266170ba00000000000000000000000000000000064a699e9ca11af818e9fe6f4eee0985fceeadde53ceac455c7fedcdefec908971641d91cf0c845b9f14d0720cb0f4a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109f80df81131f7542ec6e7930ae323bde0bf23c28e8e1b9cd1e0550d01964616bec75f90fc620ff4e47fb5a01095105000000000000000000000000000000000ff16c51cefb8b8930d135831bac5081fa5852993ad525b81a62db21b5535f6b6989c7aa6e7ca7a17f8b9aaababe5ee01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9ddc36475c23781995342169d2c0b190d38cb1bf4e9db7d89d00f0ada52b194c98ee9a9c520acc5b5cd3f2f5c1155200000000000000000000000000000000027e3f123c61e162aba9e639b0e6af44a4a265885d9fa5527f9d0966f6b62bd941e75057164687aec3b8d51ef52fcb6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000704dc6cd2ae310b3a8489cc0e00b3a91f928e6198e3639289134dec0874c342e8a68a1d490068cb955442d690de431c00000000000000000000000000000000075a2cf0f900d2d6dd86ef7976d6599c1ce095432454a3de1773f02dc64bbb58b6a744b5a212e5b188fbc688557367351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121aca798f99bb029fabd886070db0b61e81ff94764ddcf8159ba87ef8a4f36f6ceacf3a6185c53aa1f9d93a4bb2b91700000000000000000000000000000000126cfeacd1e0834c0aa4ff136dd617de714cd7afd7b22bcee6549a97ba539de4148271d26882f422f308b698e97b7d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d592947aa79b870f2e2cc63ca07a90ee00ee3d515fa312f0c9a4131995c3e2f6d18525e0fac5b485381912d1fff87000000000000000000000000000000000166460bb93817ac666615bd068b49c30aeace0dbb0048bb909ad5dd16fe601d9508b12cc06c39f415357b676c31c7b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026b4afa3430a07727537e376da8eb5fd6fb3c607841a602da1453c7dcfca7cb0b32876cb649eb7f4e97f948fae2e20100000000000000000000000000000000186eedb37b465aa682537b65fa0d25433eee73c7acda818cf46f2b8d68c969f56bd3c6a95be9fda9f93bbd53261a41bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004c754f93fff201605620decc02ccc509ea6b6b06a8b473a1c0bb1fbc5b2c5bb9d40a057ffe7bb7c36e667a51c9237c0000000000000000000000000000000011f6d16e29d6214a3577b0d4ebff3c737945fba79eda7ad5dd6d3b3a92cd7c1bc3002eca642c09d60d99c5884dd7e7ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063dd8ecc3e2b6e07296a2a6a7d844693d6a8fecdce3070a43a43c0fdf132e11d0d1b3d74bf48e62f58c1bbbda52bbca0000000000000000000000000000000019862384b8ee86707d454c2fe3f985b99f88d5ccf19dda994a8a4c3fcaed407bba8e2979344f046d02f1fea36ce26d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d13b8545eafa1c274968cccbfc3a7ab274d1e798b8bcfa245863e17891694515396d2938309edb101ee4aa42168bab0000000000000000000000000000000008ea8ecd6b750e1427451afaf4259a10e7c0bd9581c359d8b515585c73e04dc302c0c9e977e395f47c26cb086844b66a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010821a1369efb387af7a5532ad1203bea209ba365cf554ed61120437920b1a3e5f77f1182d54ae82fb38c5aa95b5599f0000000000000000000000000000000009fe11718f6f05410e67d44c0549841cc078a0e5623f18f193470d64ddf0143eb27feec8548b1949f46874fe90720be91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dbd92164c7ce18fa5c16108b514949bb522bd8fc12bee4794736e3c576794fbb3b75be219a63c02657ed9f280574700000000000000000000000000000000011c7539b583d223932b48b45a5816bc450a736dc700cfd510e4db303d6175cb048a87058870958d0e6ce8f09e20368631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c3db43e31da03a6d0da7529d766bf2839964e7971347a40536f5abaaf91525996628f66777bb7465872645ea0957af000000000000000000000000000000000875114158b4eaebdb7581a90d201b34463df9a87464889244f005fac6eb816a55f6bb36a50664bba790eccba050352d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000373a124a53ba5e7ba5296414be02ae89d7425ff0ef934a2a6d4741c21ee4437c43a23f9cfed0be7bb314b056d95c7c000000000000000000000000000000000357eadea1eb51402c1824f61d239a089788cf8e1e1a5bfe0095d49f7f266c23ec98a9d7584cabf375d1423bf34bfc421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000579da742878757df9c6c983596e491b0823c339e61fad7b5c6cbd735ddd2188e46b16b3ce0c58e079ae8e08eb205c72000000000000000000000000000000000d5b053a1637aa80003dfc2ec1c99b17f2f1e10b1589fcfdc28cdb382cd300215314095d6649bb250272be6341f8fa3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010519ef34482a1fcdf0bacee9107dbbf778614c266c1414b713cf1e955c14d4c317434eecaf683d33caa399587993d0a0000000000000000000000000000000009d72280e8698267b1483f5f52dff05c6e91d02cf91310c43ec52b9ad202c1e985ac9380bf387d9a587225630ef226691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110c0043405e6d957a98fbdc65e8c10e6d82f30b5642042a5b2b70b84114864eaac3fa7371727a4dc278d49db5390f5a000000000000000000000000000000000406b258f81ac32933d3f55cc6e313871794ff14e7e1d8bd183fc1589926e922de4496ff2fdc1e57d4945cbe53c190bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002bb2697d79b24540a51f6d1a6a04715cc67a7a052752e600cffd782cd3bef38e0a958080e5850c48dc1a3499ff623b00000000000000000000000000000000099f89d6618fc7dbdce69f884965fdd5e0bc01f50d3ad6bde2a0ac61729850481e8281fbd6799e02b2730c75eb35f2761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c96eee9a5c445a57f6a39a308ed32aec39d444a50f2340750b741f01d68adf6ce933993cb4bccaa4b4ca54262f28a800000000000000000000000000000000117abd1de879221b5b60eded5df77e50c27204a5e5b78f4378621e39c77d76ff45d2128bc1357a1c7e44b16efee0415e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccd05154b487ac2b73753b6dff8f6d46f2457e168ed23a8520effc8aff9ed198348f8de359a596d9e1ecdf3b5f8aa95000000000000000000000000000000000e00ffd26fd4fc73b78ed95a60dbbebe9f04b6313a62955f612e3947769e3a12f70c38c0af64bbc9ebf77f10d85033351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011de5d407eb9f38341c61e0eac0ffa54d063f08fd76590ed69f06af816ec29e761a706676a66124a7758b44650a1142e0000000000000000000000000000000004b7f49b4cbd30f1cea3b62b25b0fbe1f1333a9251a7f8f024e50a2e55499351bb94e14a358099d209262dc264bec6121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019ddfe05940e7629f77f1cbd5fea4514ad4aa25ffab529954ee7c9d7cddf6bcfcaa7ad57dd61a271dc5771599d48e58000000000000000000000000000000000ce428ed85e6b660b65d9803d4d91514b1d1e9b56c18b171ec41a540ef512c306e39a1383b0ef8ff62f266dd33d9b1991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000528dad1cbeadfb1b1012130ee3549e189b0df22b96b9d3abc7c3b95d84e13449528b05ce9a310132958fa907d5eeb56000000000000000000000000000000000801686e9022c9e5b8843f69451e3dc1e1117262226b6501af10f38a66fb0307a70e12be4eb1563898f99039595be8aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039f42706f314602a432c40a7ca51feb150bc6b38d514594d6846bef8fc61f84fc23362f23cdd2a9ef61d0a671d917050000000000000000000000000000000015d914776e0b7c827fc9ce86365f92c6d4993d8d6843c3cea555bc4eb82c34ea33d65f3cd3e2b15ba156093d4b5a705f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ee9f7ad9673c22c5a5d908064cfe418e4b28b68a7a50cf3f0534d4e9f8d60d1a8f6c6cbf8a74e99ca97bfd602acb7a00000000000000000000000000000000027a9e2d1e5adbe923fbb8c35c039afcf6d91d31a249a36c7425d1e7d626adacdd683c66bdf80f97b8f231a3c2b901a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673a72543cfab54492560aae86ee55e7149985bc466a557be38386ecb04a52f319d1d96a8379f08bf9020d96ec8a988000000000000000000000000000000000aa32345281cac1fdfeaa709daafa764838404902285053fc4606b62569c8d1c59baad7578ebe8596da94c8c52e78cfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7b2c7c4817d5e605e6bbb93b16db551c865e31795536daad279a7ece0415589636813c2927d927cae37b535660799e0000000000000000000000000000000011f892351555b1237b0ee16391723ba3e31dcf5c0badbbc2714af27397bc8ced3f24cfecd922bd287ede8f6fe5aa311e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f965f3ed7a123a4a2dcb8cda707d913384bef6cd1006c0c3e1649e9a7f2c0f7191ca9c61e105ec2864c9ca1db92ad50000000000000000000000000000000014af0007ee0136c93ac2fe10fb9f5887d21a08ecad1313d0105b574aaf41a99917d27113b09db792dee5c19281bae0471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013da69ab41103c2e1594d183481c619494de16c50d92d86a2f1f5b52a52bc85383d5d2892cabe1fc14ad1be5e44e08cd00000000000000000000000000000000101707b1dea772c90f1331b9281dedbfac38e229a7e3c8a49d636236d05cc085d2b25abeefc29c045fd739ac6580d21c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001208c293a83e64bfe136afa87f67728a364cbf18a2120f08ba4f14eb90b561ca3ef59cfd91a6711bebc43aef2fd982fe0000000000000000000000000000000008d079099e412f4c36abc0f04bb69b288d8202c2150ed4501edb12fe06291c12df14dd6a740887855db7e49770da58ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013db5abac41c67e843b97e7e37cb0739b61ae9b3eef335d3e9276a09c6c371ff7966cfd8a118d357c5b281c289879c8100000000000000000000000000000000092725da8b4c7c04097cf1f1cb9c79f50e946ba8b621dda62b33135c29d6dbd98677b27d0dc493311739e40a60be2ee71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187944038146b034f10dd304c1766de8b0ace0751c92d5dcfdfe0433e209b2752b36df0d30c126abe1ccc03c83a12df0000000000000000000000000000000000de01a494677f435ae434ca91ae5c79a187b160cfd6896ebdc584b294b01dc08e2ea530c36d4aa22e41ee1dd1e9a67aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2ee1169f81a81b890f9c4b6d695ad02f8ecc7f2b6c40f6fd0e36b7999dd92bf7f5eb82dd4aa0468f5c563d81477b5500000000000000000000000000000000110878fb4258f9e20189dd4f28356bf37ab9aeb15c534b99d312770a91d0c60f608009eb74f46c50904c6da9a5c3e3041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000483df709fa7a1c34e92d006005cc77c6ecc41cc1b66c47ed012a4a277eb383f5d8187071bfa2e3780980810f0b7648300000000000000000000000000000000176571ea0a2c3f06b6606358974db9b1c08a901fece4505c42020ac86d0d2f7b1817cf5a554520e198ad13b2a28741db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137f0a0e188337f1ef76969a5ca87805ba7e9c3857f74a4ab08c90ab9c23455bd968908e19735e63382303bfb2d6997e0000000000000000000000000000000001c9acdc427b5691fb1c57ef6e15a0e4ee91a54e6192714d5648e80c405bb736d59b41aea377334ef26d5c4a5508600d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001852ca5cc7d3314a81ef7b46bd47375304c1386512d2d8490e826fe4079fd875d51da2405ca75a8a68aa7c4e90d1d9a90000000000000000000000000000000001e7e572f7fa35ff495b1dc612bccaaaf77f4d86698b5d3b6e977aa811e2138b7a343e858bf2d437e0f102c645f6c07d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dab5d38f5b4e87d755e66f64752409a783481ce42dbbba85eb7f0df88bedd8e746eabbeeb13096d5f742d4c9df081a000000000000000000000000000000000f88200542ef65e322adcdf33ddb2df1952de97aa0123ea076bd67e8bbba87d16808db6900c6f6af68be20ce601f88ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a443fc39ddf1e9ee0f5d148b2f46a4243611c0c44acba37f71a2f20b55be8629774154a046242c97acd8c759dcb12370000000000000000000000000000000010505cad2a0766080b001be5be4145f14dc2a86e425ecc2617e64ea7312d8538edd914c56af128bf52899cc099495b931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f8e3ecce7e68d8eafcfae82be606ff2dec4c27ab0c8b1e7afa6f89c3c8fbb429017d5ad8bba808cbe27eaaf04d1d37000000000000000000000000000000001992263c3dcf27a9adec71fec8ea8c5737076eed05427d527d06702ac822ae86d117ef8e3ebd7947a2770ea7bb57c6da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0056fb5e9e4b611e6a8c126ecf8c60fb424d3722645d6bd1b526e7073f41b2d7e05be35ea88a97044e1abb4d3d8e790000000000000000000000000000000004318758af7a9f49b634ee651ecc69ca79781103d38afd8eb75e882c7b4969c8bb1b9f3111a030d1e14e174681f990fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e70a6475a06d542494b703691d1b91fc6b593e9669b5d5ae4868ef1181df0ba92f81ba548c72b48370467975fcbb82000000000000000000000000000000000ccf0c053198f0af003a342770391a6cb298d57c418ba6b18bec38e9d00a91f1e985def08729085f2d2ae10fd6b682341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000723fada9e052ee9e8d9095bb98771a06b2e579c5fc20aea7df41236a53717f4c5b9d68a4278d70cf8ffced409ef737e000000000000000000000000000000000beefa1c536ee32714c391b6f7d4573e7cd239dc6e749c5474ba53faf1341cddece6e3ffbebd4f74198d92dda216124a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001852ddb23f3b7e8f562f80ccaa6bb9b3d5603b029d4e90dea9936421d5247b254360e72768f510c66b5fe836e4494bee0000000000000000000000000000000010c9002c21cdc363f8fd78907b1df78bfb42c8b0b98fa95f9561ba1ec512bf1fc94f4d096a2b6b48a3ae9fe981ee5b291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f4d7ac401da77522695b882b49358c64636a844026158995d9c8df9cf1b10dfdb21473d11dd866e0639af0ecde4a67000000000000000000000000000000001875999c398f749ce8109dd532161069623bc22faf3873dd44a87639e92ab6c932332b17dbe3dc7f470c8f9173b2ad0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bb9a5f7ef6a77d451855850debba0b4fbfeb2997b39caf72906a7a488e11fb8ccc726438954a58f04d3049719ca4fc0000000000000000000000000000000005d1dda4ba546015d10db80d7c1e10466ab8ccfef4f9c4fd978391fb1250c3f0342a61249561011a4d74c5a5e10f0fc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122cdfad891523382368dd1f9e28e1e6e857f70334c3cc05bff85cc21bb43dd3b471378eb00464567e143eb55d12ec5f000000000000000000000000000000000343db67e4f54c4173ecdf95d4ab129e9695e2b32e6856e9ac3d2c544a4f64e5dd99f73da4a235ba5e7e944db63151621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009df2771e9ea0b07867e494c0cd34eb168693fb086047310827bc0a80107369ad5d508ea90dbaa50f788b3bf87dff963000000000000000000000000000000000ef9e3771dad1efcc30c58c179a554a947a0f91d8713eb31fd94b81208feabcb0642ece0d467534e69892e568d12d6cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6a1502dd2b15a100e690505ded8391e1679eb62f4bfc34d8653ee5d8b6db8013a2d27b845e29b09bc3e2320a4ad7f5000000000000000000000000000000000ca0c32ff5310120daae39651222d04c9b726cdc934b6caf8da6880454190657c09a25b4262b5045d69a8abf8e7f758c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000945e13f2e734596865db4f6ecaf56accfe5281eeedd7bcc70328fd46b1fad6b3c10eec768509ff3cdd1d29cf7805d650000000000000000000000000000000001dbb0cd0b1d41a7064d06b9e1ccbc834d707e3ea5536907e5be756f9f44b0c2d5508f7b989400e872dcd1c5b48b5cdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f53e6e87a46a3fe07a8ea41f12f6d7a693dc07909a3fc9d62e8d9441bbd73ee1fb6881be0de840e890859ee0742d300000000000000000000000000000000005c8717e28112e49e0846e47826179ad15c40294f2e72444a6c6c3e278880c2793eddca8a9f817449679fa5321408ad71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110a44d3adab3bc260782f563068c3651527004a968dd69d63a8fe030a37399eafc3660f43ddf4bddc300e73b672dd6f000000000000000000000000000000001684f7eced92bdd4b616959d5262b30b7edd93dd6d2b25924816fb0f4647e327a25a7a90d7287348dcba86bfe420fe631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a98e81a6b71e43eb430b7d85f98ff88eca55cb405fb125c5fa04d4f635674793a203b709de52b7d19612a252bfaae6200000000000000000000000000000000135ae46954abad4675e2329d46d5f54c13c4c878579be016fc8ec1de5e4b354de32f413b10d7c755b4887d950ba84aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1263feb2ca2f50dffab8de58b1dba92f053b61ba6294da3ce6b69aa97ab326bd63ad9d29c4a1849bc64178b95a7951000000000000000000000000000000000235b6b3ff7f5255513aa2088c4391620de20d80e6ab866c9d8cd5d5af4d9e2bf40b9b4371bced47c6cb741f3c48ffad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a558a8d99a7a9d73e134d1d8b15a27a1f27b42261dec55992fc6f82cf6ca1b3f4cf814a52a7c150f7ab56c40e186e20000000000000000000000000000000004aa1ca0a0f27e9f42c42b99a01a4d60973996d7a543ae15fb7f176f66899b2a82903855a2cab2b6fedd0af929d909341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009563e68d919a8b32b5c019ff8709fa59e8311590412224810d67d1cf56135c3cedfac6c50f5acc23c4d2753150921de000000000000000000000000000000001982a3505db9288f3af594593fea076fb2b853bf794e3b843a9274f1e812cee80bbf0653b3d7fd934f9414506ddef8181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec7f4ec4758593ba4690e4e830048aca8cb6d251d89dd08910f299a1fcc38c044476ddb7b388dcddba28080a544841b000000000000000000000000000000000ed13d7871e6b524e04d3316723cb069d980de2f43f0bbcc301bc65cb4d9d8c7e5119df98506ba848c75a1f08b19db301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b7a728468f7ca884cb4c69cec3a6af45aa0f986ff79155135dc0b21592d6206eff4afc6eae736b62d617d5fdea63d300000000000000000000000000000000002c3c20dc23476ba3e2626cedbf7c303981c43ff67c5664bc8452964af61c230f0e4278530a738fc421793c0e3203601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001338d579db7a784f10e0534beb16d380f8090719338f92e6d210bae913fa1aa140539ec0e76590233d8e1f5ba2effaab000000000000000000000000000000000b4f57efff088214162de1f12cf564f5f4b256a4aceecabc5f0b654c82ed13f2bafa4e01ed35773a038e58fc87ebf6691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b90b2c59c29ee1683d84e2f55683495cb8fa2da353db75948e1d7c3f2784562cc1792902d6f30b2a8065b15153b57c5000000000000000000000000000000000844901e21ddfd94b2c074592c82b5c76ce318e1145c776dad79c71d78170088cf29d45393d16eeb54f016b11c070d431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001390764d5de94efd678c6b531fc63e5255e68394f029966978c3d2692952d4edcd076c28596977c725e4312f5412ccf500000000000000000000000000000000135a5c0c969e9eac78e57399aa4f40a0d1afad3b05ce25746acec614a7c62fff6e4852a3cb18b4a671bb467837dd2c941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c450880deed35621558f9d949e1dd98923e1f7dc9dc6247bfd523e617cced6d5131c19c1c99668992308ec3118e2040000000000000000000000000000000008a1fc4d4625876df290978b017fffb9abb5379aeb91cd284fe880d65116199f9c6356c85c4d821b483871e84fcc307d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c094fc12f6aa9f4611d4e2ef273b42b3082c123570645da9579d32df57d61ae475e5bd0b9f1e1040d1fea0c41d8d0d000000000000000000000000000000000fd153094e0ddb80ca2a58d11743c6ac77b9eb9e29d7741fcba303b039be6529b100c29b9f5213ca08fb316bacad6ad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015621e00a94afbe8117a04d021a5b8c5d2d1e3381a4979ed62085980151ef63bd3a8934072c053f0168dd9b921ec85d100000000000000000000000000000000149f09ed2f79be47f87cc435460049e908cc28095da3971156265be6ac0b458e90603f5fb412b688bb84a719859348f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8a886b0ea9e5f7255f6a57eb05fdcc1b089318de86089a571527d5ea47154c18b22a4b144efecddaa747fed999456200000000000000000000000000000000109214676a57b867090bc3b978357d264e16cfd58317c4e7597db3e88edbe7c90102585714eb03c004a4978645c12ba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4a3f0188778d2ef54365ec782389ed97016c1c7b2c7629151bea40f31f3ca0d4f1eeabda2c7c54fa1ef969cb267b2f000000000000000000000000000000000033caabb2a512770a5bd36a67e1f07126e16c09740fd5cb5281c70ac8520eaa30244b0a468d4f68f2d8ad80d5e571b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3dd698a801ebcf32ced199038b72c912e0d35263a4ee6237a2bbc82159ef02f17e802fb94126e475e09a5bce89c6bf000000000000000000000000000000001872764c8ac505c36651da15bc86a62445038478ad6c4eae2d552db6702c03a7ac185ff17f9bfe6fcc64dd6190d667581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006daef9a9b2037671914ba4362f3a573e544ae4603a05667d97d6302fa32d9b3d6709548f7cdf315575d4f7d58bcc05000000000000000000000000000000000073bc768871551650036e92d39298920f0c72b6de24ba02cb49bb5bb8b6cb2cd9e78f1da92efaeb6393a14bdc2ff3a211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001194f0c810b1071040b6dceb7cbd4e76de4f7f57537476f6eb49f2e83bb248d6768452af90929aa9e1e0bfc7f7a3f1d000000000000000000000000000000000decd2838d4f53f9997da4cb29f3745065f21aa75cad6a8bc56e64d6dc0cedb20ad3594fdb0eab9e3acbf0ef1293fc671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189ca78f8018a505f3ae1baa4c89d6a64a9f874bd503eee23864061070e75cac4310b42e280a3cb693e1d113e39ecabd0000000000000000000000000000000011bac44598642c14f41f3f0bd7c9eb43ffe5e1dfa35fe39ac4e7e444eddd7a6e930b8952970b05753a3e7ff9d9a5c7121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d17c56bad4abb4e69e92c7624c540988ade19e97e3ad7368ef9b5fd659047064ef7a12cf1748d77fd1fe4d085f0a130000000000000000000000000000000014952313acd884c9a77b08fd1515a9b8c9996667e43bd1fa52e12c256a7daa84814fd27e4aefa0f2272ef9b4062c0eeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105f70193d48e445101f41eea20bf89bc722c7df0309b2032bc0b6344dfc62039feeba9018a50985a325507b4ca8ed2d000000000000000000000000000000000018b34cd0d7c1669ea54df5d809749d46bc66a29a961ccc5aab50ee3d2569268c135522944f8b7a8423f3426f0d32821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b32564e6da33c47f5f4ee4eee394ccb7595cd89da56bb18d489a105bb8ef1b8095a6f89b390b0b62eeb9348b879730a000000000000000000000000000000000c0913987a59a213407335004e0ee374c2741f505f1c117b3efcdf57ab6fa79e47039a9f06895fe5e7c9b0c4eeb2c6ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131925162982b2ab0359badb008ce0bf1f653e800bffdd2a78c76581857302d0b91987870afa779b3165aaa6db1ff2b20000000000000000000000000000000010271b35bb046f6a38c78438eb3817c51b00b6a228772849cb50b5abe63d14e005ecd8bf59293aa9dab88d84e14cca391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000565aef1ee55db5e742e6d37eb9d469e1e49c416ca0880ef957119883b4a668e0b7d7e4baa26dcfa736ff6c65003017300000000000000000000000000000000042f981dd588c8d0cef2db46a790ef26582a39dc64aca18d2e7cf8b6f14111f216d4de0528208b0b70698fe424a75cce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103e4810bd4a9b08d38e81e05c4de55c6aadf5c7318b4c8a7274d757e7f4371e7d52864c582fdf0ffb069bbcb5fe387300000000000000000000000000000000189f59b6ce93677f2a622a6e5d5a8440016c0ec117efdb2f89d46fdeccd37a12d452afe4808ce585e6065af1f4413eb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca39fc8d3eca63e7c7fb0f6431de476905961551e9ac2c44bb2f60b5db0669ab4ed9f44c71b350fb86e4a0b464fdfd50000000000000000000000000000000002bd726cf22db43e2d99e3ebfa2cadde6f2e1c00e2882a96c86fa65fcab94cfb5292f883a42591e1b46a7b07c1b373ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d75cf1b7b161a8fc20853335337c6ee2766a844b8bd9ec6b5bb969c2c632d52e6c41170cbac9710258c40576ec7d2000000000000000000000000000000000272855808e61348c24e55ab8bbb94c77d8751598c026c5406b9c5497031b6d3e4f79a79896e8257475734a063221faa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc5d1f677da41f78da055b7794c9b4ed43a83068d5629a32404fc2f4f6d1115e32528a4b71410ad22295569975875890000000000000000000000000000000000db0eed2992a6d0b7fd9e82b34869eec0161be61f4634b26c3bc82ce16a89e5cf4cb63c47d1c1385f837eb9ae2d7bae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002be0f7f78e79b5f5fbbab1e813d2f69265862ac6d32f569604f33a41b39ccdb95cff56eab3e0376b0f862e0b0578ec0000000000000000000000000000000000fab97373008c422e2acfb3be0c9ab6431efacbc26d84bef2c80489df2d48403f3d358d2d6915bf4c8f9dae634d5954e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009824973abd3c728d02b2045a0bd1695eac2dd1013f329e0a6a88b49fd74bd13cfe849edb8b55536bf329eebff89622400000000000000000000000000000000169b57eab9a49dce2f678645a1510ce80d5da8173684358381590f9e03c7be35389ec6143a575005eea9b723bfeb11b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bbd270f511a6f953c78426ad6139f97e9fae967af786b3de31d511b557faff0f005a73f1a29dd1d42dac95418b83de00000000000000000000000000000000173414012561ae8c04539915098a7c4adb06f6326f4b1e3d3c7c710148c1088dbad8ae756f960f117c6e547cac562c821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d6734c76ecc9dbade31e8452a38ce2b45b0aae3dfce208a7707442b906d85a5ef1832f63448687aadea5b6cacc9f440000000000000000000000000000000012edbe4f2bdb326d5e9bb0e41693ac8113cdeef1c605ad0206e2b3f9bb8439d54ac9d54d3e38ca88f4a69c4c11ccf2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e72bfb5f5816f10c6f10d340e61a369485709e044aae6e80fc8256e2bd5edc065ba1c749a1fc85f7d94602b510944f000000000000000000000000000000001287db37dc67a39dd177d317469505f7aa9fcfddcb7e6d9542f5e5746127a18fbaf16a56f3570e6b24bc82264fdcbc981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3de0c9e848eaa2bccca1ee5c393cef1fa4aa15a2d6b8b936e851c13589e1804b124308d8d45caf773e1cdd584b3ae800000000000000000000000000000000180ad47eed54b964f366d34d01452a39cbcc3c985d8bf417bfd97d7324057620b89aee2481d8cc95a7cf540d44beb6851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148cc071144c74f858c3863813603ec102f28d4df5c872c6523296e275784902e7dad3267d9700f5aa80d85ff62f7b1f0000000000000000000000000000000017d1ab953f6523b48728868a6432884b2b2722bd430145da548946d9a60edab788d53539298632b5f125f74f58595ca51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002849cfafff6fb2a7768d9a256fbb8cd809e24ee3fa7d204b7f09c326b5cb03863c91352002458ebc19ef49bbb969cc60000000000000000000000000000000018d1a88bac26a824bdd90068a58e0508c25769e0e0c6cd8cb4c30718d724c35c7d44f229cb3afa46fb07eb708fa48d071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6240d14f6ce6d65e19b72aaffb0244f21f5651d21a872c6131e41bd0dc021709be25525d2cea6a0ed7f01c9dff88b00000000000000000000000000000000010e749fdff1f63296bdb033f59d7106164c5e19c7b33a63419402e9d98011ee0fbd4ce404e370e3a55760adfa8b225c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001567404a725454d997f77357ea181fc8cc8eb45abeae1e4e1be34d3ea25ad92eeba66fa038284d03019514edad2b48970000000000000000000000000000000006463c1c076ff62aa5a2ac496e9db979730cc8e4392285361503c2c764dc4fa1273e9bd33e44d6bef8684a6e7baf6cdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af0135dafe61dbd8a1780bcec8e4221db83e43d1d81a90e25785cbddfb991ce267400a088b132be51600e53aa88a1f20000000000000000000000000000000008b7ade5b3f8380bb086e55ffb6ec32d82870ec3cf136a8264956a0427e3b515018f853dcc720f819c6d6478f84aa1ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172f49165a571b730a79f21b9b3afff0962033d297451bfe11ffe3085c1ba9c4e978bef45a38c82188407a025f5b79f7000000000000000000000000000000001634d3a795eae4cb05296553d5abbc35d09bcc44743c6129ee8d43f6ed7eda27bc7d0255832a9c4fc7da764a11379d311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6ac7e35ab8d48de22a45bc3f31dc012d564c935e59887807ab8ce149ad152026b6d001054c01cf2ee969b6d2956747000000000000000000000000000000000edf13915914ee21bf0b270c4e1f645a43ec5baf7d70efcdf33de1ccda1d52c5f9adbb69ef5ed07127b606f6e89ab02f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001655bf5f49c26fab24201681400682a10b0ca784f1da596377e95d784f784d3d6346d9ece18520547e6ef0852ef0c9140000000000000000000000000000000016f95cd32bd672b7d4bfcaaca4b28091cf1a1393ea40797d7ef5d7d99721943eca021fd67a26b848a691c7c0c863148d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a743ff0117fa8d2b879818f8d2486943c9617b080eafd658d37c63bcf7ad42e00c6e5e827114a00f6a89407b2d70a1a0000000000000000000000000000000016952b04a90edf126e6b5188f5b0d2e21b884e0233da035cb9783e7591989e61f50c628d0cc81cdd288f446e9cefa2c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e4e33c1075524a560c736b0b3d900d472b1b86af802cfd27c43384ebad81d867dc72c2dcb9c24e4b32446f0ab388130000000000000000000000000000000015c406c06a0911c2960ca837a9acfd551c0776db5e2375cf13899a20096222e1fd46fc70834aa2155e248a0b2ae4efbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbf3163b9753b16cb381221e350b145f212274c68250ea61fe978ddd36230d7e5225ac6e334091483a3bf2e25c02e15000000000000000000000000000000000ab812b73f4d2ab50540ed81ca212ebef636fdc14cf593a2e2f917a53c6c8a92be97e6bababe20cbf7d6b2e4cb5da7341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001a2afde2bbf3d60c8d182d63a214508820ac51698ba797de4152be872f0161d7b789247ea73788b47218fcfa3f2b5f00000000000000000000000000000000138e78986d9f9834dbd6948bb42c5862339b260a6ecf24bf660d2da0328c3312eb364a4bf3681834c5b25a74c83ac2fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f87a869a18005791d76bcdf1ce64077b68da217554811b97bc776ab40c89cbc6cf8941e9a8d3675d9f9afbfd3208980000000000000000000000000000000006801f794aa066fcc118d8415ed53308d4516f6376ec5e6a4ea35d39dc127b34b1b56f798cdd8ca2f532f566b27f2b281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeaa8149a596a97e9f15018e946b5b31e250aab729443d54332e65bc268ee72d9b7f2d4b93c151d8eadceef5d4110e5000000000000000000000000000000000c47666641ec861aeab8c6fa0672ff1b5e43a1ebc7caa1777c1d4202991613094a3abd3cb71ae8cdea9d61a994ee5f131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c41e11183ff135aa1e12f8371e0c31c07eeec11442a3fc5b4a7eda2ac531cbadf137236d4b3fd491e0be7b4b153638000000000000000000000000000000000a1b347e894b324e76fd6dfad28889eb368a870c414a5ee3116419dec06d2e2d8789866cdb5d83d8916a7374a63939201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001840cc889e8ae4a91505e5d14e52bbc87957dba34ac8e379d43928fb97262760f731f6b1497d250a8200c113414e3757000000000000000000000000000000000becad162c908bb1a20439370715edcd32efd4bd6487f6dca1031130b1f8d6d0d9b39998f2e7bf07c2fac052de37d2831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cf6c67900ae433f570dd5687b2c4e4a3e056251c1fe5f7f42a629acb3f08fbdad55b793e52a8a71395a6d52deea13e0000000000000000000000000000000011c5126a203e93d59f777b9e6cb719567a5b440c074cab1c25e977ccc5b0dbf75ef19920340ca57e1371a61e19b9d7cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b582932e14e059c35c4f9793a544223d4af0e089349d523e892471ab2c7de82a43414063b7fba47da36ab04b65be4c000000000000000000000000000000000d5b0c1258cbf6af0ef5fcb6b6215824f0bec8269979804d5e8ba11b69a2e3750a653cfec0ce4dc30fb2cfe1b2462e4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b618a951954ecf61f8cfeca12da72895449457c294c515fdc67002bdfb5855211b02f2d382a4a918e9abd6c8afe9e700000000000000000000000000000000015abc43343a55fc0907955ee26c1cbb415c40d8d543a1ca5d8d8b8c0c7289819901c7c0c2fe7d767573642749b777821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112ca64a7c34fa3807a10dcb94463f21e38d243d0730a7e3dd3b8fe6ba519673f85f0c6d5bf613a495d22fe77bbbdcf30000000000000000000000000000000018b712a6c0c545d0aa6e712c01b9a27a1f5402950aab23edd1dcdb11fb63616869c076a045cf0a13d6886c3044dc5c271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fd745dca9b87537450a222e7a6a0ab1a58aa81f1459b8a7ca0c256a6eb2b800268a779c4a61f2f9d30572c663624a400000000000000000000000000000000001f9b012d6e243805debe7f4978a4d2e9a086116e031d8f525469e768d52887075d395ce2b0b8841bbabce78cb7dfaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f5674d1473a05f3882c5719a045ebde7c50fcbda6de6f094650bee8267b26c79abb8b9a6241b95e299fb15b656102b000000000000000000000000000000001773f0d20002fc229114608c3bf6b81fc35118172e1a7486e75f5cd7d9f025b3bfd579aad3ea440a5fb557f96d688d0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057ae8a6c76dc1572f4e7ff164b36d66e7fa7d5e436fa295472be39e1fb46fe66d8a7d36b2bd949d52c1a5dbb826994d000000000000000000000000000000000885f897f0a0e62632130c5258e053bcab60aeb89700551aa8efe492784e6c8a589fe522c065e31d29d1161aef28a8621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110a04591e110495e721b21ec18cfa6cf1cabd8722669ebf43fcc771916ad3199e774467db46c347bd0959de53014d30000000000000000000000000000000000afb50bef961725afe70b7ac2ae5ff298d336477b4427b737f27cb3271fe41377ce9246477e33f2cea3390305d29e6cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001608abd8c9b8bdbd8f08bedeeb2bb44debdb842f781ca484f18bc12535a252427fb078ca735981dc48450f267cd5708b000000000000000000000000000000000023063fc39679e9c615473d08c20183b59d28698ddb22cd462a22112749bbe5757b20e9db706a8e12ba059da0cf61ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f25995dc9fefb2749a8d36788023dd286a138c188c57e246877ba36db96a43b715fda169ffd3bf3e1439cfe84149a64000000000000000000000000000000001778f51c7b23bfcd7f0fc04adbd4f46bc6cc2daf56ef3f6c4b3507729f5f9a1c164b80f942cf2df727916f252565d2791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f5efd23dc4a6c30a0490e8cc20a5094efc7ef2ead0fab9d73affd46c015f17b96faea7602edbb9683ebc6007801a1c00000000000000000000000000000000041eef5118ffe97a6a6637784f15c27eb0297a895193650d965ab24479f891bde3321eac035d979d0d723a16c689b6201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049b85edfd564cc9afafc28b024be48af8d81462a3cc0a12fca56fef475438d3621da58bc7c66c24b1ccab49e2393082000000000000000000000000000000000b76d1b97c383d2210402e95be7a40a55d4669d7911c29f1206934d5f270a89b3cb165eaff4865ef7a124e7e4863c7d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b9c6df96cd2b2bc86b2ebde0e69521e72ece5677f1bc012e3e4aff50eba95795243a1c7759bdde6ddb1395016354c30000000000000000000000000000000009fe687f65924382645ed92edf5027f7b2b626d4748a0b97799a684ff4eff63a7e7bd4aaefe569a2b7562bbf78e039a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fe9b027020a2e071ff88c2779224e7e4571c2697eb32c0fdefe4316e498ecf76c62e8baa4c3d396ac70840b1746c4d000000000000000000000000000000000d8073ec215c3adad9177da1a4915a7eaa927a5f34de052c422ba212b821f9d344db72db6dac06d61640682572dbd5b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd0695f5d152fcd3ecd8a0cc47d90a1596876b63d03087143f6e1e6de688d576064b838f292345490a035dcb709090e0000000000000000000000000000000019e0318dd94dfe8ae3ed3fc4a2e69f357536da9bfb8b6b505952b54fbbbc7f87ed16d94ee1f1ff370764cefe8743c2321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000622a1d6bd1acd2c1795e6a90433d9536738446c20253f5dd4264bf0e0a68884bf87f0fde7a4fac8d713e3f9cc033a300000000000000000000000000000000005faadaa99cbfe16a6005f4ddc6d6c88d6251b1e97b42c65e3003a22c52229932839a1ef0869a1842d00804a93b0aa1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b2bb722f8b8bb7fd517ead291ddf9d768838a75b84092de562e0dbe2469cf12c61d376d6320316b667a78068fd468200000000000000000000000000000000008b547d2d036578115a8f10c3bd3dc212860ad22c20d244831e23048e031957951361f0d8bcf94822dde919dc0e30041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000535ffc1e8f265b0fd3180c3dd36eaf0dde560cc7266750d3936fe8d0d66de23af7af29da1c0e80786d3a778f332af4a00000000000000000000000000000000094fb43c07069943d3bb8cdb06409e301691651cbaa47ef30a985316fcbc7bd6675d0a26bef0dddead6e3e7128e897871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6d5f571d4259af01966c232a2d0478af3f8a5e437ea2654e3aa22dd8126a4559ed822d80f23a99fd47e32e585f540e0000000000000000000000000000000012126ddff53a254e2549a4e3625f97c8049406f338e7cbc9be45d54693aefdc85a88fde7c2876aa84ab3deca13a3f9bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035b3a83abdb6a3f26cc632f096786d4f86dd4b2e23a511313bf394f2dbd857766012a5dc2a652126bd2d4c40a55e8660000000000000000000000000000000000b0eff72869ee494a35890af83127d63aef983a1e4fb14f5c2f01a40aa520c470eab279849318cd09d0b892217794d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001380f371d43ef3a081c52e19aec34e6565f1deac51ae23d6b27dcfea4f0262ac0abd3ae82793d9b3f4e7e85dcd922d6300000000000000000000000000000000038aa7a5659b21cb046eaadb3c83a2de06551c4697ff8a38cc5b01d53d6282ecf7912af5981f39b404d8b3c1367c8e121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054c96632a740641e3832560c862fcc126627865c3cfcf3898086cb8932a4c711379bd4dbf881113b02a543cadd91ec700000000000000000000000000000000042b55177a03567cbf2bac828d6c91f65ca8b64f2ee3383ce66b0bd29a9c01f34b87a967f289748b492621679d26c21d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000eb8bd52bb4712df06935892d0c8cff126db7500dd698a40aa9a7115396a5e22ac65d01623a510edad31af1b043dc530000000000000000000000000000000015e227c6eeca6ad5162209b1c64f52b7b7ad6f5f236f91a7d651743dca752d320383fe3d57f353b9e8f37f93b498fb0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032801b26033c561b6262d1d2f9cc3391e57aa0fb03a900e66a3e1af7cd00d3554ab8134b2a364d3874d1ceac70d83d5000000000000000000000000000000001164285afb3010d08bb0dfef245c742c7c947a4b8a31f097d368b66568a3712b0882ab0bf0aa24c0e28064cf139308821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014db504075b12150b2bf4bb3bd726b30a6a61278c976f16afbd7884f4a7086768a0aad8317abefe632083bbb13f62e5c000000000000000000000000000000000f4af249c94f689673715c208417a79e56af1d9f73337f1d53bed2561395d7b9d8c8f243dfd2ea2914494ce165f6c6561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001466d0b266c6b66d1e81594ad7e8275d30c72768839a1777e6cd211315a394dc1586085a608db11696160a2598bef78900000000000000000000000000000000109a3ec7b59fa58699c8e6dceac4a5b94afa517d7a4cf7bf40df59e535056870b23130a021d4eac6cba20d9583003a061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001609c271c8805878a0870af860992ce714efa0615806e6745f534cb7fe5017b231e851a62a01db66d90141551a7b6e7700000000000000000000000000000000009ec54393017419021e56519751a3dde3169e8a4debca3eb0bf606d7d8cf0d0694b4d096b934d4cc58dcc0f4992fd5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fafaf6645b84bba45a7cac36636ccc23e325828b232215ebbbb34b807c0226e515c84ab6d63cab8ca13034db978b608000000000000000000000000000000001020f63d1990a1844cab6f2dc86a756a1f565464de9f4b09f3187039ace9c6b9e83f12b1ca7aa06c5713f73aafec92f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014496cacb938b522c6568d95fe06eecaaa01ea584c9aed2c7d4015d6a53f5118cb780c3526776c2fb83835b920d5a405000000000000000000000000000000000ade76cadf54a66fe79212595e3fe355d960e02768f198edc5a8beee727551946398abc1f82b4404fdd88df3971d5b451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c9ba3ad47c1f23d9d76f6547b97107f8351b41c7514118de1ed2ac11a7a3e80fcb5dd8fd85079aa0636bbff4c8a07c0000000000000000000000000000000001d5aa8fe93b8a9e71062965da2880fcb29fcd776be9c51c1d9b5f45ce2b00b917436a0cee6ece95c192aa53216c0adb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f65dfc2ec2d408eeab0ad43eb425d381c6d04c33f6d50905b480e0c82eaeb706b9cede0be5446437911eb7db828fcd00000000000000000000000000000000037589bce74200534a1c25a87b0252efe6ac2670f0628b518b887fd95d0b61033c304399797748c2e363986cd8d03d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086d272501c102d3869b8718636c3c74d19751e011e4919e87d03c6ccbea09127d4a516e4dab08815e0ce178bace28cd00000000000000000000000000000000072a263dd2b21f6a917ca5656f03b20e3a0aa8f9c86682f23d140855ddb25699c3ea0384fb5a8b90274baf02585bb11c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001742c85fd129b459267280a35fd2197efca3a574f02e5aaf9a07e4dd07c477487227892c5f07a075e9f6eb71855e40560000000000000000000000000000000008d5d90997c41ec5654098a6594bd9425f2ae6990e1f6f96b00b8d8da2532405cfc3cbd72f282347ca980275ddf8a4aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db330aca445448b28f877fee42c52c20fe7678a964e7fcabff829e913886e42bcd841c10fd1552e4ee74d9abac5bb3e000000000000000000000000000000000468b10dd604607b1d597ec7db6a4f38c71d7c2d16b92844a2826aed9bc98e07dcba8ad4167055c693403f86546362d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161c9ff70bd15e2cf8b3705b6d4000cbb6c57ccf466fccea7dddd3fc7bdc5fe9771a1787ebc2ad62a2c79fa24d335742000000000000000000000000000000000f422dc138a5a44750966c4b4bf800c9f2cceaa3b1fcfed393310526002f019fa8152160eef0a6de91c09b957eb388e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011f55536a12029224804dbdb505085019a9a3f7f2385ed180f6073feec79f4a7842239f1c22cbff300d269d32a21b8a0000000000000000000000000000000013891ee8c6a06354b13aff05acd0f0ea39bd1931fb6b220ffe0bf5e47e7404aff92c0227ef527767d41e8860943f4cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151d7ce322c265889ec51efc9dfaec0f9484b7196312656b2a0ccec2050e3ce2dc67ea6e5845fa982b9600023badde020000000000000000000000000000000007d07a21f7a291e33a70d1c97eb48467fb28477279433a7afdc2fc7da6963ce11256016b73c6c6d00e0ab46ae1f4cf651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136bf0b0af899b5d612ab92b3b4f1262ca0c6c14acbc2362af81353514a00a2ad20d45ef194b6f33780d505f356d229900000000000000000000000000000000151c0801de052ab1ef24db90d43a7ad6fe2a622aae6fdede328be0ec3cd23bf92ceb8bf9fd7787930b048d9cf97a64001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c7b01bd44e06f2dfea99d416a5b54ed3c3408d037a4bf2e4176de4c2be8ccd3cb9e30582d62372d31909c832c3ce850000000000000000000000000000000007a1ec03a0f012a3c1b881ba6a6f65e824a77a8ffa79f6968d1feecbf5ab4433b359438de7556f5383148cd9ffae1f141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d719b658ba6a3f2b4f84afe77a7cc3e1ebeabd49364403788db9972b8b7566e1f916306dbdee17de5fe51c618d3f3c0000000000000000000000000000000002bb87cfcc1cd29e954e211216cf89f9e7e2a583f4aebaa956da0443e5d0ecec0906cba146cf06beeced4993369eb70d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b828ac1825ea0fc41892cee243f440f96b858df3b11ea4002cf0d35d1328366f877cfd5d9622367f119975ffcf933b000000000000000000000000000000000f057e8fd1c0e30d32db258380642ea19fa8b44da2194595018b63360809cf344051214772a8cb305c64823075b8924c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001242b3d3a9ebedd4e91f60827d28d84f05bb0db40d27ee69be6925e7b620e5c8a854e5795ef1c6b478b400d95b675a3e00000000000000000000000000000000043a9c897f3dbaf024cb8200e5e551c2365c44d7018af31a008cadadde2b38dee77777cc44f725681f7eb518e0e1ec541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011283ebe63911db8c67f64f377b13b85fd6c8b8dcaa2e1dc6524bf1be9698244b22dafdc6dcfb03b720de332b995b79600000000000000000000000000000000155e5d4e7c658c0a28abe4fa28f16d1493260e6859b8274de58e6f23314480bfeaccb12036355e77706b37fd90cbdf5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ace541937df3a0eafaf3948e829b357591a3a0cf31cad41ff6682abdf55239ee450a2da1ec9e29e67f1671c6809d9200000000000000000000000000000000088c84e9dabfa5dcd8a63e2d9ff3e540b9b8f99def1e0f23515f4ae337d501182dc08d0eb2b4b53045c12fe8e3b299ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a8d258062dbba5760c84a336470cb769304c65fd3149268bdc1b44daff125860e00ead98cd6ffe757e6ba149e69207000000000000000000000000000000000f2c843043dbc78dc56a45c56147a6717cd4f45b294619f490153590dd120e7f60478a12c06a3e5e678335036a74f2ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052862b589abfcb2dab1cb1ef80658341c95ec55dc22c59b0e035a216e73b4ad10ec752890ed7fe8e0475074620c544f000000000000000000000000000000000c5b5c9c4c330fb3125f28cb5346fccee22deb0a504a736aef34a04b1e57f6866a1b4d9613cc99302d0f9df86950cd391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cb6fbe236dd6761a2522d48b68b97055aef2be538f0105b242d138bfb83401617219c313eeac6c548419799f04fc5100000000000000000000000000000000012c301c993f17b3b15005fc4db6dfdca4a9d6cec498c0070d69284c2f145ea2ffa1e1c246fd677127a24ef5de01d8d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8c482f97fff549bdccc9e255b8bf7f341598ba19e04451e9379f794a9869eea138a6c83ac9e103d37e45690d5026e6000000000000000000000000000000000ed94db46df11f21e761c59d078b4ce4da283061f20580ad451e07285a1a46c1a05c5bfd2f3c7998f37832591e42dd6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101abd00e62c73ce99d8c2624e711160a2a90945a1e03f01ecfb1913b706e8a6b6ef9a055c54676808bdbc804955819b0000000000000000000000000000000014d971cb41c6b2a610ad92ab43c1449f87702240cb899907b66adf41a8ba5c7147a418409cdd03546d1ff990fa69f8e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185559440cd44edd0dcd144a99577592bccd1e313cd451beccfe5e48b88a1aaec02ff7a940e4d71a0fb937aed276f7d7000000000000000000000000000000000ce9d70ea4ce88c64f07598c5fa7e1c57dd15e4438ca5e160da5ee7e923d9e54a1fa891b473a13441f6623d2588680691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c1c5b647a51ec74fc181e270a70b9f837f6c9a0275a8a7f55d86f1b14d12ac77c2da595e1d0486c809f1a6984afef90000000000000000000000000000000019311ebabf285877b0633daa5a08267fe76f071d8f1f3bedfef7090af8ca18624f527e248f9229bff22bac10d5709fe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6fb1fa39089f61fa7b699c8e408ba3620ca24b60b89a94467811c73c44509657515584839dc169d95e3f5c23f0e9b10000000000000000000000000000000013381cce2b57429f6e4aa94c2c76330a21bb75b306d17bc348a48da4072f1f85e792cf0537447feed6a2e93f03e7a52d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a28c4fc7f90f4fe21bb9b67c63a1573e0445b36884ccf276ed7e6342bc41af999fc4ca7c0c70738f185e37f419ecbfc000000000000000000000000000000000f37e8fe4a44eebc486cb213b256a6d3299f8f344a7f0360caaad46a6fe91bda2d181c72e154fd4122f1f837fb3e27481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010cd812ce9160202975214f2994ae54c279428895c10e224350d96c5f7f1594e6e84e75a40005ac8c809870ed34d15ee0000000000000000000000000000000018c1dd6b459049e81269ea9909901652f9af3b05e2b5891b075e6b540e61031aadf0950075e0617097771f382e72a29d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006271fe057667da2d37b0e0e98a4c5dd20a875a8a76dc9c2fb1b66fcb22ac6269daaaf0a2d229241fa153a313324a5f90000000000000000000000000000000019e2162d8bbe052bde936d0aac598aebaa2e70f2871f72bb58d4da413266da79e637d57ff9a794a171aef910f9219b151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ae08a28ab4add98d3245b7d1a4745558aafb3e002954b89a39bdb5254556a63be6cd96db0ee127776958469a7db027000000000000000000000000000000001457f07c310550e4997fa925a6026009c7c227da8abab7efdd5de5d7e41dc402cf092850ef0662f1acadf043226a41701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154959caeaf34e938ba5fc09fa0dc030c98cd48bc1c348f6258f60e75d9b80f21c51fceedc1b1274409c56a0814ff5ff0000000000000000000000000000000009082ac1f9ad90d9b839eeafddee87c49fbb9ea89e4f820c8523be5c5aea4a03af5db7712d3bd5d2e288dae64c1cbb4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155ae8032f93487ccc8296fcd1eea54517effb8a34bd4dbc09a4f9ed9e4f541b82a9cabb8d2cd57cad74274c993a3b2c0000000000000000000000000000000011048184a765e0285e4d799b1ae45c7151b0c1aa54f59d165f276501ac8c5d5ccbd44288bbdbfde58e18a55a03db4b3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000477d4b85b0f75548854ed23a321933fda4e527853b64edb02565e6d6f60e2c5fe3a1d8da5b8b689af79eec471af315e000000000000000000000000000000000cf3fd958e8406358364674720ae91494e43d089349b3ae4912d3134a5d1af38f506055bc8468d90820fa3eccbe80c6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6fcc585c9dd530249af11e20cdb83ecc0cddf42658b13b1f4adebaaab5d03a4b3221b155779fa313331da8ed3b0e1b000000000000000000000000000000000bf11cc3eec2168423cd8348b113f4139ecbeabdd8ba778a543c5271db58816f892ba0d7f969cb0c7f18d435101630d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061e021095e6de6caabe2f27924928702f2b84fb38be9f954a018b6c312bd05607654dc1431762e7edad1941db7f751300000000000000000000000000000000079905af69fa10ccc714ce1b105e751813e9316d15c38807013b2ec4111d9d3733b77150355ef8cd56031d35e29b2d501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfea88db432daa1a657d04c2b0fbb42b9cbd23a2d4ab47bd57fe2ebde3f8dffa6b01ba745530435ea38101ff8095c640000000000000000000000000000000005df5bcf93ea02050e9a472c2c3e4bff9fe47461818d78be72af77793e76ac4fe90c39d7080f737a40fff17087b02ac91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cc2ba0e52b4962edf02e0992080d4e9a51838e62dea00248598a8e0e72df3de91f0c7b3e4ec3d59c96b1f164d62cc600000000000000000000000000000000117135bcb61ea19e4617a440a4802029c038551cb407e0dce79a321975066ec5bc60fa41ef21ccc27fcb7e4e5c388d0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012550ade0fd3980bccb6a803bd1468a10d01a8260405f1ab66247801e3795f4af22adb2f2e3cb2bf6a3a355cedf1a05d00000000000000000000000000000000093348fbf2587d071ddd358da9e7a96b324c50c0421b66e2ff6f4c32efa281477d1b3e163eafcf977a4ddac3f63176f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e22814239e4f5ace9664400f3787efb9ef4eef8f4c83921c0b3c3309d80b5d5e427a2a097ec78b8f3c68d5d59326c4500000000000000000000000000000000182ef856ab48686af204889bbde2518318d20bd4a10960c657ba5b5c601e84182abdd836af7ec8df2e72529af2865e151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6caca1a63b589d43666371d533b3c0f1baba0fa544c62eb8c8efa2d99108361070f743e0daad354a68c823f636ec1d000000000000000000000000000000000f039815f99ccf7fbf856c9f7afdd6c5297e7787608c99d109edeca04b2f2213a5759aa5d3d35d758f35a70c2938ba831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189bafe56321cee3d9bad92c5ed0b27c1598a231d6222d65223c8da5758bbb9d30c2dbfc179382e7df1adb65e05a46e5000000000000000000000000000000001790ca2d4d4292732e64926e6662035e026e8c94f2db6248dc64ec56bd9363437e0cd3df34b52291cc802f89c64859f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a00a01dd3f08c433498c4df0ff181ecdd77ef32c3321374097c192a5ca0c01d85a3e1729e565c70ed2c2e32638fe47500000000000000000000000000000000147ff41cbb097145987389700348a8834fe082f9a2df1f975e988e4033b965a26f523ea87f34821edddc8b4afd46299f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8e71d75397d16bb61212f476e71aa7c77dc6f0426b316e90ff2da6583526288540bef759953adcdae547588539be24000000000000000000000000000000000331fcb9ba770dbc8c6fbcce76fb8147d2c1a3e9ea7f77296400a79ea25ec599dbd77d6ee493b5aef58ed836737da1761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001da354ebdcca09e3d2acf60f7325bd80f9dff4b693868dbbb3c99e0e72a98b9be7a9c2f0d0f2e6e3245c711d52f37400000000000000000000000000000000067f0f97ae597c3ba0cb5a9f9c9fe85e6c485b8fa188c85c0284f7c157a097603469a8a8a6e216e887e7d3fea9a3acc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c8c82ba5af2f60dd8547711f81e6f5e8220847925398d0f05f6c699b0fd3311540c7a84f09f2c6f38ecdc4682ce9f20000000000000000000000000000000000360fa81f07bd049a481d5241f36984d90ec04f362b589f4036c6d9d5d9aaee7f7a7060fd45c1208062dd54073d6fe21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f472da772e1c9f2b44f2a5d3049d75f7058a40dcd6339790f8fd663e50093b942220c733dfe494113da89c8b1f1e4a000000000000000000000000000000000b4762ad8088bff4de67369aeb0dd9390fd9c26dd94817acf5172d6e528751197946f993288daa372197c159d54975841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a2738d64cbf20db3c6c31cf7a3ecc97ae17120d6f680044cf0f39dae0c993ab513184b6a182ba95e90dccb196ea7bd000000000000000000000000000000000226e6ab7752de192d0f84b9b981e0e8ba2c1da15cb7e2d75f214457655ac0f30c9e7a1c4960ac552a5510368d1b0bcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128ebc68003d9c3aa3330e8b4fef0b6df21071b264cfa35c9aa1a69ee87ce799560f5fb80232a82c44a913a18282f2ff0000000000000000000000000000000019e830519686d17a82714d958d6b943ddae7caebf95a7fdbea07edb376f92ab17084858c747607860a8694e5181650d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141a57ec7735b458576d58531596c996b5483fb401c5e25fc75abc81a18ceed9905d93d5c622ba24cfcd658d764b60af00000000000000000000000000000000030e119731dc868873f1e60c191442ba608a3493cf20f0f02fc19f9997b528b7c7f99dbc85bbd05aa9c8dc2ca656c1bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145c638120329be5cd9da5c60833bf63c6b8a99b340ba5a1c22e0d905b457d6370bf6d36a5a63ebea595aff3024437e90000000000000000000000000000000011acea0b6a20f158527e1f62a9c07d42097071ff1667dc7063a371ccfb7b8369935981381f6932625837432fb61a1c5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b32e42599259123bcc24215b7cb1e98d3b95571ee127be2d5df4b7f2b0714120213c0c586ac6cdf3fac4402729876c0000000000000000000000000000000014bbda24e9ed3c6b1a029c5b9a81f164fb0dab00c3a81572cef52791d10b8c6a84c48da296daf49d2645ff454e9f72ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d1daa744f61fb6b80a725c59b49aada75804237063e31e62dfbc2c498f8f398cf55fcd09da4f4431b90d39e8bf650a000000000000000000000000000000001325723acb0a485d57acb8400e6191cabb4d3a3f725dafaeafe35a93203eb3490b4a49f02f49b259c6c70bdbc352bdb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188d3210be6d46134965b71ad5081f22bf32b3113a0b825198f495a47a4b3414d48dc6b9268b39178cbe28a999407aab0000000000000000000000000000000019ee7e7b3408d7f882e6a696231f68b61005a078a745d7cc4caec6d365de03212e562c2da208860b6500d657679d91dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e78fa2838e1e43de7baeffa280ae5ecddb6f7642a8b1a76423a88202b96cab8653273d5a96305b375608dee4d69d8c30000000000000000000000000000000013de4ff293bc87c6f887bbf304cf63ee506844ab8b3f897d537e212c60f641c47379af4d6b5a330fcf6cfa95c6054d731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cee92913c4c31570a7fd5a4478ef128f0c77b6713c5f037382a44c49bc560bff7657b2b02a8120ce086ec1d955a64e000000000000000000000000000000001962d475c82c8d20fa610ef33ea4b1873a09a42d8c9e5c54162197be22dc3fbee574da7804808dda9e9da0fe31f266491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c41c697c1cf5932d4e2166d988f844974bbe419c845e0f4530ae2be46250594dca8d57313348dd0860f970d17245f4000000000000000000000000000000001161b52bbf5d74c8e5c4b150453d11feb6cf48b5cbc723f3a5be0cf08432fe1928eb446f42a37bd603d7878e7d3777391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c28dc5e564c1e9c8df0634fa3d24977c7eb3a95b0e836309c6dd62b98a3448e597092450d2354d5dbe33a32b4e26a93000000000000000000000000000000000c9315b58b4c8bcde61357f0e8998718baa5f8d52506c8c7094fdd3dd9d908cdcc035edcbadb57ab747bb5ab8ad93e791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165719d7739f073b5ba138b2ec9304308d88fdc69443b8b5c41babfa416778abc2e26f6b292a96720ce43c2c38cbda7b000000000000000000000000000000000488153cecefb2021b059eb37be80cceb2f0170a201ebe82583b23797b5bb798b7fd911a28223285c373f00c119114f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001962a364e7470e4a4430a96a411d39ed9ee29979e1d1b4c39eb0ab2527d93ca80a2e167af61099c125e485f1d3428537000000000000000000000000000000000c236555b115b662ad29ed24e060ef4cf9d09177999fcd6ea5a6396f3b6b4b3e9988f34694964248d27f0ab045e2ab941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc0b44005249a529ede11475a755f1227f35ffa5e6a255690717486bc7059a29b1174f4fac70d620554501f51794eb6000000000000000000000000000000000ffe3ac61120557dcd4f7c6b05f6bf1b28fcc432e98947b428bf5d45f4fd6adfb34d7ffcc70aaeb079ff5c5b578644971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e20a17b90e22eb49658a0f97869d4639761ec9e4feb0800f0eb984afe454953b998071258409ca6e9ca68d5a6a24db0000000000000000000000000000000002aa4923edd62fd2defb77ec619727f88311b52c9774bf917d3af57af1db35db4175333580991f93bf2f55abdfe65e171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001961fbcb94238358a71022c9a29d72078fb55df178165095604a96bedb1045aac718cbfa95b6f44b281d82e02453c22c0000000000000000000000000000000008f96658df276b8b5cd2163494543e25e210da599d3b6aec5fd861e89261ea0e7985e986aef33fb154a906fd07790a841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001331750f9dfad97546116278bf352563426dfa14fa64f863d22afc6679c4aa7f9f0375682f0ee542f2b72f1b9dca435000000000000000000000000000000000b52ed382eb5e474af86a728eaeba55995b075034cc4eab4b58631bf7bb80f1995e04e4e53dac427005048859425b42c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e7b86d6e1c5d63aeca19db808b754569421a8adf1f80a82ececcef01aecde0b167d5fd5985adfcb7fe03076d9494470000000000000000000000000000000000a6444694094133d0fa5fb27ebf40dd9f89b4b2daebb5f92ba17adb03246210e9a17a29ac4983dca59452dd15c9fdd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e775024e7dd8d7e7e6329681c3142c71961676b196b0268ef38f3131a27dbcb77a48ea10a9657801796f6ee02a4b71400000000000000000000000000000000039345a9cdc53788142c79d3a993c81d0ccde639a65a43289721f998eb33229cfb59ad6b6497e297f04dd30d91ca170a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070e23fe5efd8e48ebaed43b678de98522bc11cb1d68ce0ab8562c8f7c9b1d7b21417ff0a5482b9509e45661b173ca3a000000000000000000000000000000000607c8dd18a3df5308d217cf95edd3cc20ae81cbd706f031fd94da667dcde7181362c1c8cf469253c8405c4a485777861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195723a2e119821cbb391964db4c5522f3456e9ed1d8710653460cde00ba229b303303455741309961ed7bf8e649c4bd0000000000000000000000000000000018cd9c87b364c48c96d4c88bb911f2bd7513ebbd62e4200a32ee3b81327f394cbfe8a86f4ec38c046ed6677be7cabc971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098f011985c1852aa7b6aee6c391d52bf3bdd841d77477b06a723fe6de19d7ff5cb37856fce035d65cbcd05c6b246d9800000000000000000000000000000000085ea71b5e716685f46bef93afe39cf7f78414decd2e00b34cb0a17ff6419934c6786ed347cd0fa92f5752e55b5e6a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f1b3b47e529ec8d101cd5414d806291e09dd6747c6d4baee723244144114c0c494bb386e2a6dda63aa1fd4f44fec580000000000000000000000000000000015db8b8fc7f0e402932773902472c66f5ce78e7f922aa287a8619ffc344b55dea15e3f973810c05426d381754dd83fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063c8125830a4bde7a90337e15a706230309454213427129968025bcfd6f162948972f4355349ee9fd7241e729ce26ed0000000000000000000000000000000000cc6503ba1a09ec8f77089503661255f755aaa1cd266ca5804ef50db8848159aa9b840eb7f4f5b4ccd1cd553fcacb131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189b299dd0e06c5a3e24fdf8a2bd97fd01ea8e1ab622fba0948c0e81bbc9d82ec17ebe6b07788f189a49298d6b4fa121000000000000000000000000000000001705a6a64909557f18c43945dfad11ba44934751616481dd7ce366789d25ab1c3a260c423d097aefa7cd458374f0b8101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c74958a23d3f6867a2aa16035ec56d965cb35a6e471d843b9cddf420f4f8a671f31e2dc4fdb3cf0fdf330e17f15e56000000000000000000000000000000000e980adde2310179db5f307ff0ec23c442c2e72b96316c8e390668950ded2e1cec2b5dc6ea23e0990f50e1e87543896e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e87c4ee0557de92d9db4e3d3b720f9a752d8da4f9ad6123b3dceb1afe0c812278554d05c74e18af76193fdbe31f7990000000000000000000000000000000006a5c3e3f06498d90efd9cbdc830d06e556cf52f2f6c30f56d2ee797560f99cdf01f181bbc2f1c8ed6d83b670418aa541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056d6538213cb78a601306f8bd1be8e90c372af4bddb35bcedc720f9eb778cff236385358bb54b370220f297c47a000d0000000000000000000000000000000014c181538dec7e9ddaa0b067febf02fb6ebadc09da53e5cbbdb357ae638ceb42c2d0c56814df4524af31ee515219f2d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079181eed3d24462bc74897c084c86fafe24f1c4271611352dfbd3afd975c57ccd5f90e42aa615c429611c745a75d4270000000000000000000000000000000006904cae0ec31d7c3e6aa8449ee530ea31885142d120227ae26f367024f56a5f13d3126d212cd3594b36e07c36891f331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d5ccd720d47ba683e7889e1b9a3ba818c600c5302dd8b4de41ce39de24ba78b0e375e1de8fdf885be75fffe6a0a2db000000000000000000000000000000001796e45c3005a795140922962a9d7aa3166db944aaa01f73b39fc3455b77884f7d75baefd13f5c123e7c5f456eed5dc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fa86fe649c2b129afb7f37f539cf074aab4978784f092515fdd3fa159f6052c34d9bdf066898552b0899409fe81fdd00000000000000000000000000000000158032329f1522d747bf442523c54b1c93fce867d96554ef47e006b2a1f106a7c2bfe8da9cdbac84a2d416c2ec42f7711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eeabbca3e85887f7549cc286fc5249b0ca2143c1bd67b1e80c35ef908efd06c2ea9a9bc5f79ec1b060ecf70fad6c2da000000000000000000000000000000001448c1bb70993e7918c626774e143079c659a0203606a774f293a994c40b69983871f309b91c2b99743414e4f378f1bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001540d2dbbd7bb5c3a43410f0a9c6f9105a417c0ea52bfef688bb89cec542e6e756a609b5d4dca3f06e256c0e5d885d64000000000000000000000000000000000ccbaea47d304b5fd1e62528ca555396f4416615a5c6dd7e0c5d066098f0ac65fd4c8ff5fd85557f21acc4e7dde8b1ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffa570f0d83387a4ff26273574bb94dacdf92ab195d923a9aed40134a03b075eabf7c9db5c69c950ab37e97511de319000000000000000000000000000000000ae85daca5ba906ffc0860f58ee0360b0b723ecc75b37c0b38695a17009ee58e63c5bb5804baeff275266a3aa118768e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000002b7503c40bb2893c815822dca084300a1871394f539dd7ec07018afd359610278461853d375a5b57fe0f3767bc6f0000000000000000000000000000000007aff4b8659be35c9a4da9a8669e6f19398ad3d940e3df6e06534e727787863178809e2cc79672e66946719442ae3d0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000465f658a14fd8bbd054199af94e886e0b3fcb46eaccccddadb9a40f1d1a1e8312df5c41914b4467da114dc4158d7607000000000000000000000000000000000a94261a49c1aaf17d54e3ab1efe8458d9eb3a79b3f775e96ea7d2133b8975912e873b8a8981c46d9516b7aee424575d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000705e20185225eaba9743d9b776b66e799c4883f22ff8fb93cec7a9934671b8c460b844da090b011a5a04876420cfd1500000000000000000000000000000000029f60f51d109b30e7aa7969a313faf62fbc0402e212927c470ad5600cc382c69982cdf8b1166556cc762726578d453b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b12f72b49616cee6c297527a08d24d6dde88f4cd52249f0d76168be8d1c982c93b784af3243d82059c839f2016b57730000000000000000000000000000000018206f54d28e5bfec1ae3bd7fb3ce239103450e6d7b6d10dc9b8acd2c16234c9891c8fc66082def422f1b386673dcb9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001693d4d5a35beab10bf91133c1731f03d5bd7f942afeb07427e644962f7127e7afc1b52285049d6436ad1e95a4759f99000000000000000000000000000000000c18c224830ea65670de0581d266c9213a2ded20a848d1067b4ebee00bdf60ceaefa757e3140239d16d374d213fbe4101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004ccd8f64594ed787886244f40adc18d06fdab060be46d7b5aba96f9484e27dabec436db52b33b8638bb446d4a067c900000000000000000000000000000000130947444d41e9427b71d4b83bd94e7e98747c990c0e219c5d08189569f36dc7c933f5fd783658762d016cb91d7fffeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000637cfd0b2f6d2a77a23260b775b47df7d2966a8ebc0a5493e1ce4a5b849c1d9bbed1075700c5910b3c10e5a9c1efb050000000000000000000000000000000014b573d573834f1d9f045d708836607b75d80763f802b75f626acfa75fa39db46246d9121ec70652e92074128d3f1a9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b9ea7944b98a647f0570314eb273283e218a404a98c0d07fcc023eb3c0461ee5cd488f47792567aaf21bd6f623129b000000000000000000000000000000000b7412cbafdc74a9b0bb7b3c4b053280a136d6154ce5ff49399952e122307beb58caac5f825114c4a7797cdac9f950dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063edfff9f7d6281d702a85cea7c41ad3bc076af07484a7749d04c679cbd03fa59b23636bb5c8457edcffacd1700212d00000000000000000000000000000000045c7275cbf5ad941c919aad462c3a242ef65024c5a671561a9a3ae9a8a1c9ca41bfd18412e8da7ed2a48a8c80e078fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e25af8ee5f8ac1e6547d81735d477e3d745177b0906db211536e2ce5c9faa77aaa99397fb68e8f6e13c2d2196ee029000000000000000000000000000000000f38805d1f0efe78454708aa19a08d03c760280747a22e2a07e41a2882ea3626f2f6dd4cb3213be037208e9ce0c0d0c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c8bde4608791b96ca947397be46e43676e0872c3f85c76f9df85a6a50a0e5a186e4a18427bdcac7cc39a2f63df6f51000000000000000000000000000000000ffd73415a588865fecd709a2a9570ab218d7915904b5c34c7fe3a8590ab2f20a82735edd9cd2c3464a26808ba1dacd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c632f5b1391049be0dd9d63a1d307c2f6a9c69971e4059341d510936438eb78d60d93561c2ea9a2745bf3e0fa6b62dd00000000000000000000000000000000191d511e1024ba5c00ffea3f018cbf83de05f510e03f198c03a8741e4e8013f1268bab5a43f3879c8bca4182d116c6d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b3a3b722f3929634b4264532229c25e1cbbeb2d7bcbe27ed9a7ce77925ae7323dc621f6e9e9fd563b38df715bed9280000000000000000000000000000000006d5b02f9389df85965f25616fa56ed77c3f5cb815fa796aca9cece3e1cbfbe74663afef1623c6fa8d7b897b5238bcf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123f9914cb063cced7b6bfa21e4f4c4599e0c19c09b422c75497f7c89a6a1cf72ebd560e79fe2df058b161f47cae903f00000000000000000000000000000000074789ede4d477511409676cf71383533bfb488e8be572d6d3e53ae571acd95ef3f18bcd22065a284adb31051dcb04381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d704e21957529816830777c9bfa8f197a355946aa63c14b6a50f1880dbb75de05875a6fa27c09db983de15242896a000000000000000000000000000000000138e2b0c0b632f9d01b3e7e721a471db48537447f71db2d280e3ecb36093a33ad6b1419066df052a7f79f5a4e4c89cac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f34cb14bd29d06bf511f952d92139477572532aeff6ff352c62039c678ffc7283fdbcbfc9588b60e22fcdea9e32456000000000000000000000000000000000e2b45add5640480b9dd65b480bd1135c3bd261c8c5bacc1183f7060488704ff197f5f4cd61742472b0aad7d7b46f7411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe02f20edea3c7c81e0fb98df7e7389e59058a049aca367d129d5c88ec8cbb9cb441804a17ba411de7d197d599d7ec0000000000000000000000000000000002ab15d1704e69756804fd940f00fa1b37c1993de135e8e1a3c75149278a011df35a5b3bf1221833411d5b7004ee35bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137ed39fcba2df9734453e3884d21d17ac422bd9e72e5ae7b63c19fada2bd7e8ed9f97d100bbbf80f2b9d709b769c00a0000000000000000000000000000000018f1ee43e9f214f84b455a83eabe208fc2c772cdfd8e7bda8daa58ba422e2a9d71e8e3fa7de513ed3951729d7bd96c711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c86fe1fc28590fb919c6d814d83949c61270756014bd35542af957b023d8a7aebf4070e21ea74254d19ecc6edf481d000000000000000000000000000000000d4170246614c4a4ee4a4c523e3970b937bc33220746db20554ffad9aecb1b47e2a6dcf89929a0aaf173efce65a5296d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca1602c13be84e3e69c7f81c3df81e7624c623aa884ffad757c97791589d97936c934ad0c6f9707618d163e119b15c40000000000000000000000000000000005f8c9b9a6f1537b8583d3f36694925fa6ecb2c00d862c08c824c06d5c4e1da22df81ffb8bcdc02fe477a3dd86fe62861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c01c3f0e5e76c378774b215e665b082da9ed72ae3091b322881c041e070dc85d7f7f6e24cec4fb2ed7a689acccfe5d000000000000000000000000000000000ad1dd6c2658cd8b43a83bf2af17ee58d9c60c8f2de6b45132d7ebbe76c850bd3f535e9300eca124f953daca4d3c489d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169d65d36c32cce1a664ad8110bbe36b0eb5c854d538774a2b70640b3f6122203bbc7af9e4f3989d693e2306d969ef5c0000000000000000000000000000000019be8bfc44f53ff818279cbe4bd24b7d5a647c7af3930141dc73296ac9fca84fed2b00622fa7717e48b34c5dbe9dfb7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b941dcc14117647b4d5ec0c663dcb70ef41e19e0aebe9ceeb97d72947d6c48c7b38fe623fdc6eed42d47d5e19117a74000000000000000000000000000000000d7bf395d86f6d3155c3b59a9d76fbd72b7cc321e60e758ed5f4399b23a51f8310186d62ccca1d59199734a628fc9b341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9154e91da2093749c99413d6fd7fce40afb38124ff87a841b7f0eb33abe7630b63dde7dfb91506cf295b1bc68a71c00000000000000000000000000000000001ebf1aec3365464c67cd2ba77b4a690b5d1be72541efacc09a86c141bb197d52e93f9cd6097a89881d8cd22321fb7bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bc565564f6f465b6f7595d4f947a4e534927be7646319dd863733566d9ab8b101129a71b719b2bdea7fcd09423fcc1000000000000000000000000000000000285a69b286ce370b5d28067ebf270cf66c4df33d0d35461e709c4fe823a49830d91fd8812d00d045b6d3eacc3f912bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113b9404e290ab59d0057ffaee2899c49581712abab1340ee74c4c5b6facaf46dd683a0bbee068a6619409dfece5730e0000000000000000000000000000000008361232b18707a7727c024f0e83a66de8700b58e9d651211db104b1c045780de34bf9309164c8d5034c550b66d76b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009940de312bcf7ff7ed282035e1dea1dd7123cd3e0e8f04c0dd9614b7226e3b8dabe4455a97caf5fff085419efe093400000000000000000000000000000000195d4837b010f1801766e0d673ac925f73610b71ddf0be6a7ecf7575bd7f8b111fe9833b3e110dd266cc1552f6a06fc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b828543577be9242347551bc6621349fc271043d3191a187930cdd941553ac6bbb263cae15c8630a14cbccc811dc4a0000000000000000000000000000000010b8e5ab94318fbf9973a6f8adc3065ddc7f6d3f0918d3eb6d71fc14470a6eb041f0b1cf370920414374dd7d4d8702971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001143833d136e1b3cb40bfa34331e9ac52533c8a64c7c3e7a3077f547c45108bf03df6bcc2a0322f431184e7460189e5000000000000000000000000000000000d11d8e052d49b4a52925a0038f593202dbfa879be63051aa8bc03e1c2f37367a34cfbbc4f5b7351e38adb7ebba36b981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013750414582e6fecd5b0a53389a44dc073970f445dd394056c3614f919be46a85bfa70d9156fa9b7ae7a3fe370af6f33000000000000000000000000000000000223df72c4c8d98619719912d01bcbab0f3bcd5f8955b1490aeafd4d8adbd882b18a8494dcd6bf16d418789f6c2a76e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120fa1e72db0c3f4fc7ed7c53c9fd77bf2b2ac89f1dd0c8af54adfa408f4a44fd16cb28346293dc599de045b8d4aae850000000000000000000000000000000017734cc479ee2515197fab9b3cdd4558ba7a304c4ef2495dfe935c7e54ae4e48101ad93b09b83ff404969150011e54b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001de602f8b09e9d47df893461e4db65c86f15d09b309a2399101704c42fbe65dbf3d640e52b571643f75d552f405e17b0000000000000000000000000000000009cf90af95a3cf5ca6e5cefb414fc923dd139eb1a815babd25057f0911bb0257267f73f31fa3e71ef5ace6583d9529b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000041cb05deeea4e41879a2340498c97d9c0aa459f9622943c6387a5e32e5b96ccbc3c335c369bdb7d7bf00da7d4b3d9e0000000000000000000000000000000012c92598b88864501ef55b8d9894a3bbf36c5a4ce12b6a9a7024f1f84ac0537a3662a375a2a28d4b723be60861e65a7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000784b8b2dcb771cd42e543557d98bae393d652e71a1619625dde33e86079cf216d32bed64ad6090a24c5aa1abac874a400000000000000000000000000000000026869ece7ea865928bd81064913eb2570d0569f06cf14f491d2856282928c2449f39e772a95e6205a9e2242ba5167581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009ec383fe0f68d41668093caf86f46d40454937ad29ceef6ceee0f3522a9f52f35fa08b2a7a741a1d8acfe5dcc1c6da0000000000000000000000000000000004be1cb08c81226fb4c7f32f086cf933ce5a4af615e657de68fba967c70dc50a3dc013d32095a187702ef9c9ec8fdd651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001601e253d663c01427194d309c2a311a885d4ad03b6f336433a4f5aa2cc0c0fe2c55933c497e19cbaa172132b25e8dda0000000000000000000000000000000004295f9fb86aea6e7c1bc26b9e5468c7fdd370924e903177f863373c19da19d7156f71acf61ca2027ca137b425c595801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d293a8e0633af32e2dc5c5ea444e6461cdfd6ce6faf50b991e31fc60af96d1f2b1e21289a8eccf2a02a9063c735e1c0000000000000000000000000000000015e7ccfb25b90abb4b2bf11bff4e08f430b519dd1e895e34ecbd879bed4914a3ebef8f19ac9048c5139cdbdf3055397b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cc614eb8c27fb9af064fdca8d5b4c90e6d719067cd86869cf0652a4cc037d69e2c7a8a684580843f73f0d81d1edff1000000000000000000000000000000000daaf6f172f31d801c87a623786487db9e2929d8701c7e212fdf997dae785b9bb4b9d5321d99a341773f9c07dc08db031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a6001714bfb5147b1b1152e0f701147101686970779037fbeaaeb0ecef8a0033b09619d76cb8e6ed42f72c0d179cf30000000000000000000000000000000007138e0874f0af15535481860a784ea17606056e030532f8d39190a18ab4e9f4da3248912f656a8ffdbd30b7b142329d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188b57e18bac0ca210a48199567b99af637afda70b9ca8d523bff6fdfd401e0ba139f47d1df2464f850080b07e08f26d0000000000000000000000000000000003d4f64caf21182766a81efc1e0d90dbb49836f9e3fe6798d3c3e6d36b4b147f3ebc5c8180be356024526427abd2c0c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c421117f5ceba5d854f4f614172e16aaeb5e3553f1cc0daf6c0eeaeb7946da146bc8641710d701ecde71c0374733b800000000000000000000000000000000166c20ce406a615fab1f7866ae2bf771563c4468441d9cc0db941a1131a37f4eb25e7b158d66f790069120f0e49d5e1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f369fcfb0b9c79d581b05364869b9a43f23aabbd969c37f148b14a924c560f3a7e79edef244d5350cd3378f9f2ed52700000000000000000000000000000000179c661350bc05d4ebe4406ec2ea5c9bf3f51e8140931b9b6a6b5d78d0ad08fb51a478b57ebce35550a7c2c9948965d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb091ca17c67e4320c285dc856703ef4b1db833f4e6e367110265decb53efeba8b3b1ff4ae96fe8c17f62bb977c67d500000000000000000000000000000000065e5f1f40da76caa9ed568e4c2445acf4f18eb72c653eb3850df8602b1c805c19887c9cc8d482bfb1dcca97a7a7e1d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c7858ae8e362f80d06370212027cae6f2843022041ae296640677672f9bb4760d70dc53ee7dac9937d65173b7aeeab0000000000000000000000000000000019f5f0f75e4fbcab50a030038837dad3f72574ec117ab4fdd0b63599a6982b7d4b41aeeb14a3c23e8d0052498b16cd011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145e2c82b834d2cfa4307c57434646a418068ccc68ae2f2eae21f3c6c0501d798b6a90fd891b1b9403501df7c0deb2ef000000000000000000000000000000000fa49a30f76b510136f654154fa06bc35f9b4a7048cc5d407d175cb0902002d8a0a92cd2e77e1a938910625d4326c0c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013988a56a09788ef8d402926f14e11f21dcfefb0247303a9058ead03e68c9683dd24abe0c273907b841e6dbece0a6464000000000000000000000000000000000d26709a6e022caf725febc3c8139278bbfc9f995ce2b93612eda7426c815900fc3a0113505a89d522859bd817a40d501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000600e2e8afb23565d2fd50ce70012d21714aad68ea82f221519502ad4b1b0fe8e536c039a0fa121a9e27c695dbb4a3b90000000000000000000000000000000014819c937b51d0af7a8875536faa6a8e790c60b0ca9bdbc7dead2e882238142a7794c3382bb73d02d547bb74c52298d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199683539ad2d7c34963b7c74242045acbf28172b87d05011e86fb748521fe84b36bae7277b52b1561aa3e6be4be637c00000000000000000000000000000000098ef38b1fd6f047a86f544177473860ca147b48bcec653421828a16a9d98e27ec4c0f104d9413d2820211b96b6c74251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000424a335ddba0dcf0a736f8154177ad87dd133a65544d047a1e7c14c91fe75bb7255fb65d00e78d4799391284f3bcab90000000000000000000000000000000011a32aca62cda6bf5fd47520d52b6c7928418f0fce747825d3d9a0a7456e3df4e14c61474d9632a98547a0254ed25e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001238e79aeb6636d43aee04aa67fb7d04ee65da479f92395225720dce1e5197fc2eec954faea5eb8de7302e207df9209a000000000000000000000000000000001858a4ab878fe4f081d7d32847bcd0f8590fdc7be6f756158c71ae6aff662072fbb8af6d5a78b3ccceab8d83bfcc591c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ad5cb907a8f6670b25fc0138ecc9093630e9ac3820042f9e3662c43db53a0acb2762482045ac030a7422424fe9b4170000000000000000000000000000000005c3dee62de9bb92936a00e066ab76456e9d3c35226eae4f14c25d7faf8b6dd3428a5776a3da21fd943887dfad2291561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f6280f0a614598480b4074594d6ffdb57985277b2d79baa01712930f64c5028e5c5a288a60a3d03c75e0a8bfa4b32b0000000000000000000000000000000013daf3e4ec5fe1595152ad31cf5a5de9c5ca4a7c7b7c18c9f46fc56fce68fbba14cea302f97b9dc118710399efc133921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ad1e54aa9ea5fc576a74bd71622bd200354455f73a84041530590453cc2c3b1836d600420812d441879c5b44fee65800000000000000000000000000000000097ba0d583ffbab156783943e86d23972b49bc839dc9d2bdab4e29741f0cec51b584ddb8978e3fc8c5881cc5c04a84031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba786b0e864e382afcf2a2d902ec818b7cb4632069afabbaa2434cbf1d52feac99784350fd32628462705778b04e7f20000000000000000000000000000000017368ad3c1cc0e8ad79956403c1c756bfef99ae7d10e3ec17b774fc9c5db90b3ce1a2dbd48c5817c45c12e1773659a9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173393717405fa8a11896c9325cb8e7afd270fd4ace6507ad2f03d449b5afa226cc8db5fa24679eae2124c67699360630000000000000000000000000000000005ec55dd33152794f2bb99c0c3100e41c90f18e6c1de9e750a6c0729f51a9f2a6435bbe14615a5cae8a72b2391e18eef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b5be17463267787223e0855d15946d262d5f14c36e636289f2f45aa581f89a3964f9f4e27ed673f6ac45c4e922f8d70000000000000000000000000000000006a1e21de777f6fe1e4d6947a48c15c23ff66b69315bc7055d442bcd7a9e002eea21fb09d53c6a5c32ac8f6f454c985c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044faafcf404c7e3890925eef240919b668891fba385765d66a72aa25b9788fc66af2160ebfc4d7b9a18fa99bbb22280000000000000000000000000000000000c44efac6f1e32dff6809d563a389ad041997daec740af25a70c1936ebbf3fccc185c6b117aa778b24bde67f318ff6911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001902810d7fbfca99008d86142511d3cbea0d68d8a5595ce9d7d4b57b9a224c70c12e4f8b06c75a84f7694619ca36238200000000000000000000000000000000075a69a11fcbdcb083e88044fc7b0f0f997454b92517feeb6dedeaed1c6a00bc88d2931a5a59daf1ea42d03a9923d1c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b35b6023befb075c9bfd4c0a7bedd6abc49dde537afe62a1daa6d90113149bf6ddc9bde129e6d7be8f95652d15f4ba1000000000000000000000000000000001196593a29fa3a10134307ea4334b9a04457466617bbf83a4aef71afea937d668177395068a36a9a06623376841412f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc3fe05ade32c478946ade2fb9f8130feddf6a0036c820795242e37ec588a7dd59e82c96114875414be86e672dcba110000000000000000000000000000000003e78f6bb2a353fb48c95c0e5dfb44e3862f2fc7af25b51e202327cd20c8fea1a6ee00c8713b6f2e761dd35e94e6b82b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2e1589176e4d9d18777e3df6d3c8e08210c6ca96fbb8dc6060ec3c5f2e360f922343ad2e0f8e3cd1919990f343258f00000000000000000000000000000000161ea4389e89f80b8193f411a6e223091c2b1ff90b2d9093b0a4e02bf3d829663db94aab7e02f972c55c5c639b1f7d021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0036a5674bd0d796990eb8f10e7d4bf4190864228d93f981b4f0aad29d9f3d1ef3343d7479f31fba4cc8f045959ec70000000000000000000000000000000007a4d3fe27bf5dc98f8c9a66b30562c6ad5cf0619c14f869e0c7a2cc26843eec5d87dd2d6e211d893f2919c6c1e74d7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178751924e460a4c4d7c07c6b2dab58c0d997dca3eba51041a7bf196269509af14018d3e15a0ed3b96b977a435eb8d4a0000000000000000000000000000000011ac437acd31f2a5d38a665d15550d4087ea62ab987c8f332b40c4e8bcb5ad44b0de6aaed228880a6d692176a88adb0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087d58abbfdffc77a46569262c746ec91c4b03399b7d9e8ab043375cdff0f6373fcafdf84e1bd6098917c3fe9e12d2610000000000000000000000000000000017e332732034531da2f39ca9744c4616ebccdc3b7c6be2b6ab0ca7a108fa6d0f0b3f51c4dc0dc69c868b8959c9e12c641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c01d508f330fb3e4c9aad4bb0aa45fea1c8d833886010005ac65f028e09705f39c5d712e97d42e922afe68ec9227cbc0000000000000000000000000000000007609e0e7f664b083e96febc8b52af7ce330f3d0591778aa574b38d330c1fb113338d310435ae8a215488589e03d67a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015133a6c5b8becfd8b13ffc85b96b132a7b3182cccd710573b91abf8c92031665897345cb60baa10de673e42349218e90000000000000000000000000000000000e5ffb24009889a6c66c40e49e85fd210aa44c56b94542f9286279a383f12a75b31ee9542c0afb02d37e33046451fe11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000865f597728f754b931b4d262c98460181bc9201f488b72efe6a7fad2b7eda99341e771fbb45b606b2856db8f61d0a1f0000000000000000000000000000000005f25ad127044c72cf6bc9e2926c96f68dabd9dcf0a8ed96097de04bbe8401e0430f02ff2a81b2b1cf69891d29cde7e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000557dd5508da0d6024fed5892e439987388ea82015c7606c3b330be485ba0b7d838b077d482b51e32135160781964a8e00000000000000000000000000000000195b89cc39d65d4294ac46fa2e8b7eba0a0c2d1a74b70e83e15e0381407d7fccfd512182247f5d87daa9ca38f008cd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011274b2bb04b713a0d4705bba63e2fafdb219166e985dd77896095268f5f7f5a27df1376af47f664011b3994ffa6ea6f000000000000000000000000000000001688a6f821056a3011313b44c0c1c30beb01bcbc58677ef926ba658581aabdd4584673cc2c59560b711031c84bc8bb531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b98870af3e92b92101c21f56fba66bcc75f3665983938736f417c9827db1802b4858d1362d1f8dcd796cfc5baf18be0000000000000000000000000000000009609130c9e299ccbf0c0aa37e2d2a6d6457fcad697eb35f34d1383ab79cc51e9040e5050671ee6b7234ba48bb4086691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e29224ff1227a2319cb893060365c78326396256b979ed77035ff112290c119e29a19b21b52d0df34d5a2bd4811a0600000000000000000000000000000000008c8caad76963e7ba7d15b1e60bb1a6cc9f2ccebf9299daa947d3808a52d93f4523a238b5ecc50cdf7b954544e32dcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022c8ebe8ba1e43eac1a0cc24d1341241e514f976d05683942f213809e6494a124599f2837b0e9f67cea1a2de8223c460000000000000000000000000000000001b6cac2d4bdf9dada0ae6567eef08b19c7319bd7d76fd6321a59f5a42f20893a75791159eb9bd42f1ca490ae9300b1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e86fa869b27771e6dd5f6ab81b12f290696e760d52dac9cd4050ee26040d0179ac0b18e8eddac37cdb411f1023f77d90000000000000000000000000000000005b8ec54ce2816889fda281ffed0f81a99808f23c578b777a4b5e0a915aec1f8a1b643ef5a5634ea025b83e3a957c9f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112095af9c55ec5423fe2186f80a29bfd3c5cb72d405d7adba1ab8bc6327ee8f28b73298095b7c118c5327db6a48b0f6000000000000000000000000000000000fd45756f1de446bc751fadd2db191177f390ffc9139a3ac71f5dc5e4698dbc21f8406b0161bd8636c4be2cc85ccef121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ce186ebdd55f6ee63427eea55a7e77bf0d2c02d9037c5b20d0b9b87ad24612359366c9f01ceeca1721c84fe34ee2e300000000000000000000000000000000037e2525373e198b28d389ca5236f361a8c88d9ba41ac7f0347cadb6a3b202d8574e2d23562046c4faca8dee5ad964061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012af791919fe5ecdc2e9c29edb3c895114508324eecd3fe0eba717730e3b6b2582e5055dc0a49afde3826abaf1ff9ab20000000000000000000000000000000012fb10b6ad4cf5e50e04763a71cd8642b761ff18eecb74c031607535777cdfa77dacc6d2b565d4b42adea935ae1b226a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001944c2bdb35063a045b5141e652fe102e6dfd8b86afac8fcf3c7f9d8305909bbccb644ddff0e6647f6c543dac45a32660000000000000000000000000000000000e75b7c25d3a3785bfedb1a0a978e57b92087d213101c352315d6d8b6420a3eafd2d05d1dd7fd70c2a9405214585cc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c4fea0c2570d05f7bfc1fa955cb16699a7a08797870c43f3569a41050858e2968d0dd259cae010744771446d55c150000000000000000000000000000000000ac8c11729008232195350eea6e604a594abcfb9d4efc0ffccbb39862e8aae57fe1e2aec9a4faf035629d818f0897e1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001432b595e90a783398b918a4edf2a7874e825ae621f5fe6923d38c6e1711a17138f3dac96d6787b5dfd2ef3d9af831a3000000000000000000000000000000000b8adeb7b9e46f292461db8ea4da0a6e548d7f57a2cd7601d97a959be138d21108e5f71da7baae98f3fae6167373d7411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b04495b9765cf4479ec1c48f9c2f59f8d568860838a5e06d9a234e41c565e8e254cc7795f049ab8b88703bbbae5198000000000000000000000000000000001026ecc5eea22e8a0468d258847835dffc12842e3b1802b65745ad043c4368e26e2a5e51178ad60db3604c57ec9393691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007eedaeae6295531b6b9c3de66a54a7e98f5fe4a6d0044adb4869d1b896e64d69390344420af491eb8447f4b7fcf1c8000000000000000000000000000000000ea40892c6e23a4f2b3bcdee4ee64531456d15c37b60e17ec32319b742eeb113511246112ae6f6b25f59d965223b66f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192b314507f254ea7bba02a98143f5ca7701dbfdf091095b016a6a7377dbf3fe0ba2f1d5b941a47e86782cbfe20e79d5000000000000000000000000000000000b0568164f38bd8350c65f1fa6a39b20fc4ae73d1eabf25060a31640e30445c82ad98443082fc2ac909c9364a04324681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001644242da17651c7cbd5eaac89222bc82c75a3df2b40902460573b7f2aad2f1ca2700d86a7b7dfff411a7f0563c643530000000000000000000000000000000019f9bc9f901762d658d9bfe53f0c617e4d37b4e22906254bd262a567f5a3b8eee5d5150eba74fd0b70dcd32ad9c3bfdd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e1535ac548b33ded6cc26be524ae7892b065dc4e5369f0c9f2cd982c6a08a486d14ec540ecf7599127734daff2566700000000000000000000000000000000030e455f011ae5f47c6e49b51ad629a67e521e07bbd97cb8a870db4a02e14d818375a30e8bdeedc06c556bee97381f311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000587378f429f92641d46381881247c5205f165baf9ac9b7dd7a7b80b698532b4b5cc9edc4f2e7cf4fbc21b5a5e049e5500000000000000000000000000000000004381d30959d87cb2af3dc8a10b660adf58271c307aad22d3c9f69026e457f5f7f4dd52dfee3b99d82de7da483bcdf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000934ef5ce9bc7f8bac10a7e80ba1b2e5450d0a6e168515c426e56c9c29fa3697f425800e0f34adcad9af7222bf5668d00000000000000000000000000000000011df5cbc583e28ca10d7317a7ffffb1d466245735fe0d54fbe6c816e47536a0d27310d1fdabe89db0ad73ecf36b2f6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178977a4188dcf62995efeef158e45c2a5f2ee6898a25a3509d0a10e11a74da51897065da34464fa3426707d0b9b5736000000000000000000000000000000001887d9d7b139fe689687fd330884f88fa97c3d8f5b4f249bcccc9ebda6af417ab0587ef7e704ab829110cb4f59f718481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a29b9eb38e1302cd0a264021edf027d1426c1d9b1159014c1a11f0c45ad9592072132fcdc73efc3923a73f58d8519c00000000000000000000000000000000165c6b26965a3e5d0a01c47c459b133174ecd9a9e7e8e6bc154a3b2250975e3fb7bfc537704636b939d00d9d473dca631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d5f1145d783d10e60cdf1287341a8a2838d5c8a798fdc90cd9b4910c6da4e237aa5142dc2840fd158a57899a14a6b40000000000000000000000000000000001b2e1daaf9853f7b880377a29567b778d3d4200c6227d171c54c4196359baafcaf5e8d20a79993fa8ebf5473726768a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f56aabbc86322c2683de66ce3778e6e15c3e95ec34a75cbc72aa0dd9f42a7771fafb4d81b9c7e82306feb5a7496c9d3000000000000000000000000000000000200f7c472a699844177439fd274eb80dd5d7642c4c59d5a04cf77f585f8d7689d84fcecdd1ead1291ed535080e268e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133493bfbadf2b95f1dd8bf263e25651c0f10a7f442ecffc5ec905739c2999d7e4714fc71f63170f8cd4fc3ed4160ce10000000000000000000000000000000019397e5fc4d40418fd991ec5d82d469b5133d3f5c63084e6c36d621478e5c05b0afa4e0890892ef8baffb743d8c7abb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164532b0adb51b97cd8c46e4602a153a72057ca5fde11e82428f1c7a32f00c27f14605e6b5f1d58248ce7e5f771528d70000000000000000000000000000000018270ce81d72cb32557b77fd7566f68cd152612b80325bcb82e94aa301e867da3666245b6affdf6d8aa3694933edba691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac6654fad1a9cb850a999c5ba5c303efd3416db092cb8ca260d7e15b1cc76250c884f3fd4d496b7559bb98c0b5b0fac0000000000000000000000000000000003f7bbe509a39a8e73a10286a7d5c520c80588875f562523af1aee9de9f4b0902df29d28d1bd20adcdc2f2479da49c731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000709656752447787f2513541f3c1e147fd9df83893c448719d44af9fc0cd7397ea84c851b899e81e32894485445268c1000000000000000000000000000000000d4a25806f432f56e85791c3e082de11be5c75754a781b9c2c126643cb5a7f5ee77c6749fce1c0e7dfd628251b5f179f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9c12164084e2633a083b0ff4d2f69718fa141852b2bea1ff56bb90baed017e73fd4806ee684a69a872dd102685a5cf0000000000000000000000000000000004c6c6f5b204e02946b0c1deefb4301015a3002cf9c0394d4b09da2f034d3caf781aa99c854bea61b10f7874fc4bcacc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156adbb584bee59620251323f9c2697b9f9b6d527a85339c0781078154ac893f060739f03702334ce6bd4be18f135ee60000000000000000000000000000000011960659ca49c3371264da7a4ccbd67969ca5278ee0a5c24af47e11e761b4444f84546b800f566f0924d25bc6621b9791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b720f853dc92da487ca06d48eb48d0cf0826da51464d75d4f9faf38c18dd39e3d5b01d2717920e3df13e4044c1bc21e0000000000000000000000000000000000e6c8ce7b0df94afad12a600166998c61b40e42e049dd600189aa4945345879eaae059850b71a63e239972fb8b3ed9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf8a0f9979d96edfdc6f7e7caf64b8611427d4c7c7eb4b350a86d2d92ab2de914d924f81bd5ceb0855b77baa3c8d2a60000000000000000000000000000000011cd82d3b5e7e30f39aee829cb4f29e7d2edc199c123278e1df46236e0ba7dbad9391156e752bae633514f865f3426231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061ef6fc23899be1f5843f8f60f203e5a0ebe2f1d323cc73dc16ce7243e98d105d8963aac0eaa3a0daac587f4ed8ec8e000000000000000000000000000000000422418de2168fea3837fc30a4d9c5ecee3a57892de6b360a1ecae6e23e41a25e6246968e8fbfe4317181ce6d13c22701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ec41bc0d0cd1bef5047b042192f75be67e3bc3fb779ee7539e9d9fdb48933e001b58632d0a16fc3f8591333d5085c3000000000000000000000000000000000106c4c3cdeac0dba701dd10676f51b9a0803f8146591d1facd118fd25a02ca35ee7dd2b7db9eab0163316fcd59335911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a71f669f37b3497cde82ecbf0811d5f53c4f3add8e4e4355c40237ecd40689ed21e50b6789b99f00f25843ab47f0706000000000000000000000000000000000c52d4d797a5b212323b262d429144ed1b04e26622ed74d75a4700d1a34ef2f8da51016b1a6ba28a978b65ea6e8214bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009161754ae54a4be331b1b35f38e30f3841c9c60ec10a67e43b8510143a70b225328453c511b48afc9dfdef1438cedd90000000000000000000000000000000017c1dc337da61b16978356f24c1215adbfb9fa249500202aaabfa7840c6d265b37fc5045feb3b125c3a0afea8248c0381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002653c587522fbbee9c7f969bba1f6a0a7f3329108e8e431f68751570d63ee6f3e111274ad1e4a5f79ff7f8e72d86c0f0000000000000000000000000000000003636bb66d97b490ba6c02c505803ee6f5bd2e216ae048cba7098192008e68209a67c077e2d0a962ca911f2c897ba67b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b61a8a9134805b78cab9c17bfcd07479fa108cdfe3edeaa8b46b9a287fa747b323943a736c53bc80d405f003caac980000000000000000000000000000000004db63c3ee6e1f942ed62d234f0f5e917ed6ac3c903b96ee9d071ee07a8d767754dae1d40b473935f6c6175b2c552cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001558387f4c9bb9f5224eb8ddd68ec26ac133d2df08e6d81a0c1878f2ad7a9cecc57a7d99ffb0f8dd65ffe3509df5d8d0000000000000000000000000000000000870603a38bbc2454577edcdd742cc884421164468c6bc6024e471ea698df47d2677b8bda3b95df24f64ac86769c15ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8071c35389d02ebab67b4ddb81e4befd28970c9227a06b7cbfdad4257008bc3fb4f11fc56b7c06ef67e59bbb293609000000000000000000000000000000000c08914cc823559d749654260381ce2a34476cebdaf707aa17209861da7702dc00f10d440efe4e53d31b2bcb56f679041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194b16efde683c06a8fccdd5abe2059b07e216572d6397e6e8b7292616a86dcbf3a28260b1d7b49459dcaa4a437d12d700000000000000000000000000000000036e686593eebeeed81c0138ea51733ef22f6c282ab058ae4e7b534b8af124ae428ddb6b0a71b32835cff320974409b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121e343a8421ca45549ccaf3a674648b45bcd24ee297f91f3945f62a6b30d8fbe85b3bc9b290fb06d3ba9d7db566789600000000000000000000000000000000050949833c055605b8783e26cef0072d112490624bc3ba7fbbc3dab486aaa413d1e2bf00cd2c788412ff41b9496218691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014ce9fbced65a4a0ce7b86d75afce01ced0700d126cc3b740d7055419689acfb700142a492b3ad1e236797ae77b5558000000000000000000000000000000000cec0f90a956cf122d8dd64d1e09ac0927c35a6a3fb4f2f92c4bc835996d60a7f294d410ad90ddac90ea30ac491242411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001473fe10a4b7e2e1b7a8c083553eb3aabe4219e9819c6e08240e342f1c95d0a29c5090948024ec6a77435ea474b0f6b000000000000000000000000000000000e77bf2e6fc185970603c29a0464c8c938f165efd244fd4f450686589337b9e9f0a1c92ca73ac8ecb33679e89dc585881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49c6900df36a63910ab835c7de14a841267c468c9482141cf2a3e79b339f2b7c3298f759504e11be23bf10b326435c0000000000000000000000000000000009fb36cc0f5d4803737aa198cd7f657ff9635f56076fc25ed18b3dcbe35519d92cfbc6c8bbe54f2b452fecc9c756e2f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b44e4d5da0d8ae286a3aa6a6155ec436c3ac63147687a60dffe88a1a762ba9fd753c73b111fba14c16746484ab79ea000000000000000000000000000000000a92a5d031e0b8075319fa5c3200c5d2f766aa960f4f61d85baeba65a5d17d7b4b02991b8759b958d63fefcaa005f03f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a724478556e65eb32bab3a520422a843ff9309d26fbd601cd23b078521fe4b561cc13a8a4e9752a1e9789488dbee150000000000000000000000000000000014081b1b0dce399df8bde059f7fe67879c1126e9ae063e7e226766260b30ba59549622c4a8e6e20df85b053f8a84acae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f51dc11a317ceaece075a62da25f0f4f029d7449540207213a8d5841b7a57f41f92f0bd9d798a005ad3aa0fb4ed050000000000000000000000000000000000379332973464fc62b26cb05297a4a0733b79755cd775c51677fe69eaa5bc1fe957fa4579a20dec17cb2307f082286bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000575e748867692f6286163b257e64e28b46bd5af2cfd268143711b445e80b23fb5931694396cc5615958b3b44bf489a30000000000000000000000000000000019971075321b105447e71996faea681e441cc2e529a52c852945a62c99f0d92cba674a1f70587b8c755467fab72fd5b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017668cde6fe168fe1b38d1af57284893cdbd9c06372715676b5826478188c83cec280d6937c3f470b680cf31b96d370900000000000000000000000000000000034392441a6b0acbf6b11e035ee0f7ed950d84aaa361424f52956bb9781e362f48ae6b596db46d0b3e539e24a722ba121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee31409f46f48a480bea1eacbd0f5a6d3cd748415bbd42406a0cc77090c32f30c5e2cf1fb6b2fe2b6d7b09dfa35ecf000000000000000000000000000000000024cac75bfe6c5b6edd76e2cbb885780410a43ec8be9295a1bbe30fb90f41dc0823316a8b91c8b239ad0de8ceeadc1961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147dc460a6b1ec8f82d9156accb418e0410948f6b22c6332a2ed9a562f6feb0967ef261c5d8cd4351141acbfbf26b6d50000000000000000000000000000000013003c7e5ce47db3dc4d6be2b688e51931f0c4b3ab314743ae56ba7ec2e4288b96a846353f3542701d82b90dd32c9fb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163070f474f08599608aa6367c5d9c736f2842d995b408387f9fe25fd0c142e6182dbc50dbba556f25843ec5bb83ffa50000000000000000000000000000000000840c7bd5918b3fe7360d191ee178feeee71f7e8d13bce81025f00641cbd4639ff55558587f40f97ce11417157775801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e84e3a74dbb55b995aaeafabd9043c33c54c769b1f520763d2a8c889715a183f575de90d9ad00ac389dc5996c7466cf0000000000000000000000000000000014c6666c7241e3b95ca489cc435f8cfb658be370d5893a514d797d690f303b9ed96255419eac3402a889bfbc2e75589b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005dadd2862ddec6c23a89b6c0429d292a8ebd5eb9b0add5b1513e6cf0b599f9063cd0bbac2b30c4fcb349b65fa097880000000000000000000000000000000006d9e0416107ac597b36caad37999de8b878f0a310417921832cd61f0fb0bc530fec3b1e858be756021f307ade91a5931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a30491776ff6465e75d9f89a1122ffb0f9ad8b1c9505a239016d3f06e108afb8586899fbf25cbf18ec6e1318c8446e30000000000000000000000000000000010fcf81eb321ed6b930f7631bccddf16d3fbacef02a3803db5d3abb91685c0258f6ede867bb2ae29199ffed7777422311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1af6ade8c405c8f509b7828a754880791d9ddf4322b963c5809620ca1a8ade8863f4c432e379d8b9a80fcce4925a1e000000000000000000000000000000000c6638c39623036eedfd3a9ee1c6f4a2c1a6b62d70f71c59fba40edeeacd595969353baa8066c20de04c44a70c29a3841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009357270bf46560cef42dbd251686a7211dd1927b87f57519fbd06f902d282b9cf3fb0ded9e3cd4cb602c236b065f77f000000000000000000000000000000000b83bff22f3b795f025fe78ac7ff1a2db600c7e64fcc01a0684ffbf314c8685e937f49f00a38bac4ae16069dac5e0bbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091356e68e8f754a1f72b1749b38b4545ca9ef8d6e06e8df6be16800d87481caeeea3c68dc75271ae866e5b4ab4a5642000000000000000000000000000000000d292422226d39d78ebc8d326a0406ac1cdb415619feb8754afd7bb31397f945d418f18077459a32807dd5f492f7d13c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000680ba8f899e5c96cf0964383153a96e523e2d97a2510072184e2b99a4ad70fe95ec0bb84798c68fd7f6238eb32187ff0000000000000000000000000000000004c52a429750a71c784bbf0513dd98cd45729aa24a55cf21b168e5a3197cb47c0a5c313c66bc3ff6c4da1af75bd1b1c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008df700a7348debaaeb2d1adafeccf07687f0a46c6aa54365f20e959933c9b535fdb190c7384cdf0059a589f704e1eb70000000000000000000000000000000003974849274f1f56f4a8b2e9ecb7f0087725708f470f840d287813b45463a71366d04d2f157c0bdc5963d1beb0a983251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013055a2cd6e48a80e859801518ed959c7f22a16f1cfda4840c08b6291406e5659d9afd5fc4e66b6750e034a4d1132fa000000000000000000000000000000000fe1f227e8141099a8370a88cc3649857f10d06f5a5ea77b39b401ab96911bfa360967592e6660dde6bf9db838a649411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b097ab40a90baefb6d09fe9a9ca66f170499570c9c76bd8dad56bd923112304b45dbe755a9a334ccb3f2dae7de617c0000000000000000000000000000000007a8cce5344f8b211088e50148cd2f0d359102bf3689e398b2bc1115a96626859262bfdebdde6875db4066adb38ffd961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152312f40868cfaa1803d17ae446f31cc2e2f3e8fd6c6bc529ec2c2b24671f38d94e2df98ceb0fd9787e7010895412c100000000000000000000000000000000124b8fe0e4bb4a2379451ece4c29d72811f1e3f70d1d51af4baff5de42423be1bde91cb409c2de019bedb77978a3d57a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5c6892fabf1ea76b416613789579e5a6caedd20ec486d7afc4fc84eafc080c981314d0f30f6855dce1b1bdb4d0ee0a000000000000000000000000000000000dae57a87386b0870089398d8f1faea4038b51cfb9cfba68254521a54893bc86b353eb3043893a4df90a5788f909175a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115e0044af94fc3a9e9e2404c36f86ea140515eee337a847af8eebd884c243b069fedbcf1440c0dd5c2a9cf0cee9d01a000000000000000000000000000000000df60cd5ac4df3f20a03b29168b28ecdc3d18a85e69800ef3e26e48a9d579a5602b8cb1b45ae668465e8ec022dd684931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3dfd50ccfb89d620be5c275e0e2e110f1d23f85e0300f5286a1c0a0224feae11419834941ad40e8ee6891083d2495d0000000000000000000000000000000003814aa2439b63646f2262752d0b5c928532af07f1ac76418fb0f93a80b95087342df42f359cbe168b3d04b0e258ef761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bf8c18eeca8a1a25747cd39eee9c2e83c37ab1e95ff357424e070688c9e3cc4529e9ae66bfdcfedfdb291eebdf3bdc0000000000000000000000000000000012f1992f566011b31eb932ae4a9264727de154dbacf579ba78bf148f4007b13bcf80ff188e867499e3e699981d90cc971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001492efc24fdccbee87adc55e26276efca68fe995408b50dd48513c0486896248635024da4cfc215fecbb7b019b80654c00000000000000000000000000000000065d232c192fbf5b3d548232322983f079aa3c78b41d74fa4b00b9fb0adbaa2b91bd4732a1b74d813173aa4a6ecc87d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019971562f441c69984518778bc064ffd51b12804b1fb434d138ed1fbc99e935e248de40995a4b0378d702b1739201a25000000000000000000000000000000000bb8d24a48d522da40b7ea26b6a790c66e42d98eeb1edee4485d273ef7fde731012799964f7e618bfffcf7f977a0a9921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094d794e7d42b85954a6c0377b53fc53d84b0b62d32ccac4b74bb25b18859cc39395b0464fba4b35a7470c9c2f446cef0000000000000000000000000000000006db2504333d4de2f3a4f0457a3260c57e8f47e8c5dbf29e957cb5eb1daf025495d11acf1265a10c6f5b1a82114dccef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008912d140625889210d4d72edd0a4bb46c1645b60e590a80bc78ebf199b64c5147ed3363a855593ed6b1b5959639e5bf000000000000000000000000000000000545dc5a2c4eeee79c00869e5f53f4ba87af9badbf7234f2cf8449f9a125da72515df437efa261d629009d27822969211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085a57e68732ad2c8466e7267bd9b793278865e98df1dd65ee19a774d60224e709033977fa2ad4756007cce7016230f1000000000000000000000000000000000c544802c42028979f2cbecd9325cfcebc3f4d54792c09f9539d2b4a9f5df8b4f9631ce7ba2a6faab75a451f67cdcb861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e3f4d577cb731d7d620916971bcc310417b8a2d1b9bf3fdb387d161d722f495b5fa558a99bf4888c30d0ed7cbadbd9000000000000000000000000000000000b03dac7fc647ff3aa8081d520ca5100511637c6440d3011ffc5a40bdfb85b44bd257f5f0a0af2184c668e76ffefc3af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c2dcc955d3d5dcbae3c50621561afdb27a146b5f761e2d31a2415f320f168da260f1c971a84ca06c34768888f87b850000000000000000000000000000000006ce6f027052a8f3e65e5a72d671a404269d4ddd413a4e02f3f7efeaa6be324528fd6d159d4a4ca62b1aed89ad39e3c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185a9c80cabf0e987010638b5a6733c7418cef664d5671b0b5f5dbbcc84c988ab8356dcabe7c83e52d941d79130b6c1a000000000000000000000000000000000b0dc84a67177e72879e3a8685cb089971624b0343479418cb06f11c66dd2b46eddb5fc52d286d3d8da869bf9b0553461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b9a44a6231e23397a7f926240a6ff6fbe25411eae71b5ff9394b7c41db03decdf75f900ba8078834cb48bb7f38f0c60000000000000000000000000000000014e4a60dc0f81d9134a1e5a80c4abe82d6a73076a341566caa844be47816243475b0dcc5d7e43e6e427321ca884f0fb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098313a197b57ea3afc8e0c991440c050bc4742624ac528f2dc80c36afc646be75fc5b943211ad48387b8c4bae6ebf7500000000000000000000000000000000119987d5698b783dd6c81e564c36f312bc552f76977356e3c27d6d8fdde8a79cc12e88696ca7831727ddeef65b7f9bfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d994253ddafa13ecacab8a4a60bdbd6a445920f96da4518b89019a1b7a242eca83a673ef97088c944e2f94ff85c16500000000000000000000000000000000192b0d826819977548f97aa59d3d3f97e75dd73712cc9a77b0f8d38469b2e9697301e7d381a5c40a7bf3273b51a988eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197c3a1006bb9c747bd3ebd657d97eda34856af5ead590fed4f655424bd0b39d7bcb6ac4bec898b581711356ab91ee7900000000000000000000000000000000081a0caf40a8f723f9d1e69a541e58807c66af59a42ea5625790cc7fda9c6a9568608b0f0e404e05d6af88ee8812df8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019159a8197dbf4d68f4ecca1a51339c30c76798de00c1ea1e78e9fee9415bea2741dcc0b44a0e377ff9edc41cb47f9b1000000000000000000000000000000000124d14efb3048190fe2c7e0117830952fda684db1f9f027a801ca400346e5cd75d1f43bd6a586bb2afeca32b9fba2f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e804f3584e185bcb1b6c49ac1800f26c6459dd14430d773cee116332f74a6717e6eb58e8ff5e9db70430eda3cf0ca59000000000000000000000000000000000c955146a036d7791b80c01fdcf524abc91ccf722ffc76217c3e63c19d7aab931ec4149c14bad7836343809bc908be4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d00097ca449952baf50f345c013e854a956e7896ff7c31083611a921d01514373afdcfa17f450e409dcef2db52327dc0000000000000000000000000000000009b9e867d632d915f3bd2f2d6b315160976224061dabb99e5f0c911c9a001c4d7f53c66150cf1c5607f61931f82e57c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a3ea15b2d73fbb72c7052cac17d81046f2a46b3e433e1afad0f1be1698a2b49811a62652bf24dac4f32f7b04d009ed000000000000000000000000000000000d6ca10860f5eadd005866c3e0ad07a3c277f72c961cbbe64bb613f47adb7567dec6d7f4f66e13d6efec45971b101fce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003deb30db62b796cd64c4aae532c86c12fcaa3e89713df3683d80535f2fcf18fceb4e982de48043aecdc364b4b487a320000000000000000000000000000000011dff25380dfc3d50ae24b93cbcfe1266fb62560e7e10bed612973b8170bf1d07c9140130aba82c7e6a9d641c605d9db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aebb4cfd5d3db15403a280ec6e0e55e430857e2b29af764a6ecc82be172432f27ebe6d0f5a2f8c8209ff484953589000000000000000000000000000000000180e29868aebd114f703c6ff8dda3a4fa9e58a0c0b7b54bd599f9e691384b20ae73e2e953529e27031b615c959e3e86f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fbce672b1ca155f5b0c6bbc7edf76f60463cc96887428c22589db05d3bbf337d48026ab323670201f8e9f8bf2a8d1ce000000000000000000000000000000000aedade057e01bdb05ac53650a8ebbd3ca536a5271ebe416b06597ea441a6e2d4a28cedd3522d37a6a967671e1ee7b851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc4b601facd28516d2f438c55707ee19b88ab7fa0c1b1d67361524deab137fce42fbe77c74377477e534a1b8d8a93db000000000000000000000000000000001849a56fa345261cc373bc81d49f3daa0c1469c19781c0a4839e111a57656f4775993b58f5fd394b8c6adb30608f31e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc7f9e4f72c2f8ea0131c7992977a0cb811c38598d9c8fef9efcd662f993b569f2fc5b80fd58e9f3e203bb79009de04000000000000000000000000000000000865e5b6b16fa6fce05b29e0e85075cab87dae3155fde12c4e66e15f204714ef32b6959188605c38858d72d0011f6bad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e7f861ab8d8bb6ebef0660c196775c02b209dad9a177c0a892fe71e9faa736214b6a212fb020895d7fdd3a10aebc1d0000000000000000000000000000000017f430a4344d00e35609c915789add8ee31c9b52093e8f7d2b64c53263634f861d13212445f6a874ab0d3cc216542b4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005789ee1ae1bd390912797a7bbcb83b3a26df947ab980b2b0d198827ad06b329b161597be490cc8a78dd6759836b66a900000000000000000000000000000000191982c2febd53d354bc9b2ba5bd0d26472de805cec91967b9cbae0cfb73dec346ab019b09bb8071b103b718e60e53c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000964617d67f169cad6aff8f1a877fd8db45113d483cb789d30c931c6e0dfb4f7e13662ba9b9432ba05dfcc2e5b04b2890000000000000000000000000000000007454bc0057cc2289991ef666ff1818d0b4da4db5c498b330611395ede9267b37fa4486492aa07a134c4abdd9dfa19431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013255baacee3115c7a37704ddcd935067a2e01539404fdfd5d3831d7caeef29f664d3a8174dc016cf0370ec9a057f1510000000000000000000000000000000003c6a1f4e4f04b7eba45342396e8b39db65922c009ae00fcd92f2db75b3d64aaaae92e0648fa871576fd2b1823f964231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014680e4121a5ec209bde069b52744fec71b766275580f0ee939c5c5ed9e004b2904ecfa55da81e27134945ea00416b4a0000000000000000000000000000000016737a799141295bf04c4222ae5fd0a296f9229536345a1b441d1bbd09ac25c28c0888744b1af789917a3cdbeec3a2d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064cef1213732fda38663cfc5d03cb13856ada6b32a32686a05e57a2991b3632a023ea772d8aa18c47e1301ea239050e000000000000000000000000000000000832816acf8001fa758203c61236a313c306eac4f5c7cc1d3576cc8f05ed2390490ba3e2fd80fe43cc744fdabb88dd831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175c03f25980ad2fb5200c3b01518340d57743589435ed355bb8049ffe67c75842d1952581b66ae73447efc39e188d330000000000000000000000000000000005463c58843f3500f818af51bd53bce8ea4969d72f3802cdf30168895f3b927115a8b6c22d72576a932827b7ceec41891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8ee14eef3910d08b7581e83cd4289fa03bedafcbe991fa909ad78454f35151daa13775e48f3abb94785952690a11af0000000000000000000000000000000010566ec88d825bffdc831fee82f78c37c30d6bdec966b0cc2019af4c0e76fd5f3984b74bb6ecd9c753bcb363492efcdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005034dc4b0c9c559c4e8754998f9fe3c8731b8d1b0d68cff44173ac0418f6ccc070d14609a73f5d04e7e54c82dbc963f000000000000000000000000000000000450ee98ee4c95981c605a63a119eaf2a63e4f46dd1a33414bacf7c1229521d22031e138a27ea28897f5f432cd92eba51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e321a57b61b8336922d7b429bb5ef4e3ec3fe17e7b28aeff96ab06eb95d4809a3ff6a4c11e4401bd118630cedb17000000000000000000000000000000000018bb0dfb2a8a3bae60c6d709995eca65ca8c519247b75dd27627f3a759fb43380fc230a3c4b856dbb6f6a7ec4250556d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000965b896d34898676be2364d65d38e25e44a7eb63636ca944f5ff1b9e9ea521ff737046d63b5c6a84e6f61a26af4e350000000000000000000000000000000001957f3b667c111f16e040d323d277415604ed1e7108052ce4bd2a074006e19afaf57b4681430b423f12bbabefe8e05761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019998cd0f91c9263e232cb8c9f2c6d2df614fec7fb6689e341681c071ca67a7be1871f1dca5ae8b9ca57e6cc43f8f8ca00000000000000000000000000000000108de74b482a3c0e4c3fe22226cfb4ae92ad3beb883569d75f238820be12d1946162390269e543e16d13f5de477fdccc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015aea3a19354729679e5da9f0f73362ed96dab415c4d028dd9d31cf133822c1e6eaed70ef31adbf7159b7cd52d043e38000000000000000000000000000000000d0e62fa7355c5aa723b6984c614361024ac9d17fcfbf7f47f4ad5f41f5d7421fc1e9c71af2bf65c71f7f90a7ea88bf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c144b3651ee93e0039ab3bddbbb485be6d7381e16de46f9f193edfc6b5854a958ce7506dcbf13af678e76e0ce6462a0000000000000000000000000000000014d132dde8f087112294a128cc2ca668f6f40cfdc19b281ae1ff9083b195e604e0a4081c06439e6edd9046de668f93191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d7846bd118561de4d98284e414d0a03fcdfac842f699552bcc1433e55a6b5a24be461a3f152893fba95f98ae99b4700000000000000000000000000000000041ac833e2f56a86ab8000c8ada2772c57d06a8b58725c91dd614fa1360695f5c2ec961102deaa282b8973ffb4e932981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb61dc0fdec8aa2bf7d35c63e650b599f2438df9e69d0cbda3d0812d72533cd9408aaa1e9d73105660b4861d637e78c000000000000000000000000000000000265561781afbb577974dda50def44918aa559601b49519c3aa2f192607b419ae2d580b92f06a7cf5c3263b165c8e88a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7027d3a26f5b1472a7e7d9659ce670d5d2895a62903ec07263fef96762bdc8b005fe0ffefd55eb8f24d0b553acd410000000000000000000000000000000000a1111a16a30d9d7a12a7903af68eb30acdd3666732fa210f1b00402888314f00d9bade83df22cf7a5412e7680e546b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c04f646b08abc84cfd2c7c1d1fe7af5cda7294771623fd005c1bce9aeca57a53222c5bcde5d267fed40e30a6d26f1b0000000000000000000000000000000012e42e1a7ae5798c3e96e873a1d2cc2160a9c5165e5dbdea61daae4fb20fa53b3c17808c02431037f986b814e34a4a1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061b9eb388461bff173a20e7407a33335f0a1329647fd2736d4eec8d802197b13cc35b6fac718c60650cbb95515ebe67000000000000000000000000000000001075e59f6376b8a8380dc3a4458bf2ab1c43839067da8a8b2e3bed0ffa115b7cd7895734e48a981c10517cae7eea20981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019ecef925f1e7a4f9c4ba638de0871879071ecb5c5d6ac412c777331bdaf51677e00a2b3b243be79af2fe334ccca365000000000000000000000000000000000ab8bfa536eb618e89343a5f4b750e17fe15527bf5efc6337f06439dbe8e7dec0f2c1f37ad337ab91815848aaaa5e77a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c12555c07c85351a7e933dcbfbd60e54a3de649caa9cabb8086bcc46fff069c57a82d13826c3fcaa613b91c650c81a0000000000000000000000000000000016cb329c57144c08d484141375bf30a71d857ef8f39a8682dcd6c43b9ac52640386ab007a03512916bd0c434291330aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067ef11d4b04cdad17205197efacb296d7348be65e1715b9b451a934f9d9398b8b199e47c2f8f0cfacdcb6820f61b352000000000000000000000000000000000b1bd820253d5e8ec9174ee1e322b24f82c07c092c32e8b3583ef71816bd0ba138ab35e5a0bff7b65586b699e6f098651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c43e0133170334b15e13ad289734b337c243e734f65ef20b6ff08886532de569507b7f599a8a64be8fe2981687d5200000000000000000000000000000000000eefa44c57aa35119639ca7d14668a386e6d77d9a13030bbaa45f1b3d465a36f6423b65e7e4216b22ace73e34cbf18a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fd5b2c2f8a5b410b74936b2b33e81dfdfed67687df761750ce9c19d15bb4eff18581c72ffba955fd4d21e38d7d67de000000000000000000000000000000001252b760c3ccc423ec35b4c5431212e11aa258a56e6e35cd534f8a2e1cc819a5343e8ec2e0696254e1447d8a7ddb41341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152f684e3ac6fe6ac7df7e6621198fe52aae36c4d2b3ba93044f52046aee50e66c35411477892ae8bdec3d6c54fb35790000000000000000000000000000000017d166d85a58549558dcc4de934f1b60116d684f84744c1863c8f675629caea689706ec7fa427a1923c5142a3642b4d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005870db230fbda010ae540e6dd923f79011925a2790234a839ebaec87d6aecbd65a84d5d55d80cda41c2f69e3aa4b7b3000000000000000000000000000000000f469fa80ac924c332dbde488f196d3ca161130662ab076270005e0cc6f7fe434d5a351358aceccd8708d6efb4ddde2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ba2dd1d8ac3d02106c7fbb64ec15919238cfe5b73ea719ad27d2c1cc51ff7e611f7dd977523ca907bd04f5c5dbf35e000000000000000000000000000000001909f5e81de424fdbb543a2fbd419a6dc4c95b18569b1196f4855a046e7e1963f88838572409d60c0e64bba59d6d78ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dc50fdc09db9053ae709e7235ff09a30a875a052028e52eaca7952f27b90f6c5c560374813417d4034e78d93a4f83e000000000000000000000000000000000c058510b2bfb35e434f430d64eee5d313f241abcf2c7775f5ecf3b3360a14cfaf947cef77c911541a327694b91c75ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002ec1db6bb488025b0d861f59fe37ff4483a9612b6a3854a61ae5b80d922b098ae51978663926d526c893290980856e0000000000000000000000000000000001d521aaeca2df95d17fade0db6077009c7445b5b5b925891746acf3fef9df97751f1be42caa154e77fb49e67dbfca791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019131379dd190ec9111959cf7fdb12261858cc4f05deea28da351128ea863b531de5077f6d3aaec697118a4509a73f790000000000000000000000000000000004d1965f37af6eee68a7b9826f7608a46c09fd168e5d55c2733c45af339619cc551fda5cb599503527cc3f478e547cb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015afeb8ce5bdca8a0d77a7a3edcef6dda10431f41b2e840590e7b26dc46c058eb94c30df06c99ddd669f43a23e362a890000000000000000000000000000000002c01c16dd26749e5f4e3137979a6fa73b2993f4451bf9f99fef12122fc49b2794fc46b7dd17d8bca8bc16491e312c751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c408d2e8580095222b4203c06b8a6a6c2d5396873779a3678b80f7bd99f408879277f72da13ff2f6b87e752501aaef400000000000000000000000000000000047d97338975f51108acd393b014d0a6869eeea5933cfdade82f8e713e2f431571bb8d87271ea9d539ad02c5c47337341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf31f959d6ccc537b03835f9ce6ba98565f702a496c5f4b52818c79403e870dc83aaa7f1419e77a760ac7a117fa4f1c00000000000000000000000000000000031cd33e07f332da3a56cc75dbfb2376467b71f82554ff6bbf2c959f63bd2f784453f942a47b43ef0d9318bfbcdc246c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008e6a36b67f756ee2bf8a78d2d88b2948fe5b9ae8364d448166502448c41e3bb2fbb68e92d60a00420e933bf384852a000000000000000000000000000000000ed364ec6f9ccbda1d6507e5a3a00517d1d7bc2fcc6d390a591a037c72eba36217aa07e7554fd76ce3288aee8469d08a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015486bc47b915ceb10c0b246b529d5133cf3007b53cb95610d5b70568c45b258c42b7e9f3ac40774ec14188cd967c7f20000000000000000000000000000000010954c5d6212c50e74de0e6a7752649feb18c45f0fbfa67f85dea09f37ca8c6f9b61ab13f1c901e90935a0cc9c28b5b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd34acee072657b1190c5fd2a5b60ed23f5bd150f63c55db78d917d42b0362dceb46e44a43bff6f9f09284a0b7e0aad0000000000000000000000000000000004cf48ba2801045ea7791b9376e3e233da7cff43c87a3075cc25b991980b67ca1caab4aa75eb5fe7132a1d3e3623758d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000976bf5a79c90facbc3ea806e20286c96edf9a48d277405a2d825968c3546591c74895599970ea7dd2302de883431b8d000000000000000000000000000000001031acca7d331ba32fbd0410d0680c0a4d8b33c9c91437f1f9263ca0f437a75edb3eaf45b492889287a3c7b3001065641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5dead2607a2da62aa3e76200ce65a181b0a17f7b8e5814b45f08436c7e50a34d99a90b1615aba96626e9c31e4f8daf0000000000000000000000000000000015005b1ce370efa385b39c0c29e238b98f131d7ae78b489796633aafa24f9a594100de32993fd9799c69fb0d21146f8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041fe5a6f93756d22eb1c72eead88ed791b58d66758b63e3cda7cabfcf3dda5f2c7e09ab2bcef89fe093041431ae258c0000000000000000000000000000000012e9a6518faa3abb02b6402c357a39db8105ec82c204a1735e792c0587b6b781b427dfe14cc1956ae7e2a0a1ba666a9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a06fedbaee0b21c5d1016bc9339107b47fd75292fc822763aa84ee401f0fa257a491e44ffe3683ed81ef8a945c9f9c0000000000000000000000000000000001f82a217d92c62ace556157742943d42b22b4ab46af8e9f0bc7ca9051bcf98cc78394fa8d97ce93307775eac7a233181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063e2a482dd07da954264985eadab87e392747327834fcfe9e23172fdf0ab0f17dea73a317bb33ac56dfe0f250b2121f0000000000000000000000000000000014036b9434509906a89b817ddb2335a1aa7e8c753a14dfaf2e7a97e4cb31e1895078bdbd625e7002ad4197c8df6d0c941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005605558de69cdacd67da47ae1e27476e51b6b9d2aec3a3d381401fd06d3f6200cee7785b38dded80af4897c9459dd8b000000000000000000000000000000000734cf01256d4c36499f7895acb3aca1dfbfe316c9757a9cdffcb4a326913c990017a48d40ff544742848414ced32db61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1a52bd36fe1d30f81137e31ae4c759e2c6dc86bcbd8e491abf7b506e0ad9c0a0bdfb0050bddee8a14d490532534c1a000000000000000000000000000000001774d3b97b57478a5c2c8ff46e59820ec09fc73954cf30f7e1bfb7decfeee5497c65366daf5fb55cc71890e788db7b771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000becb0ea048daa55c08292354b2f7f3f87a772c122c28b3c192e7f352bdca3097710ff8ffeac5c903def0893be1f1565000000000000000000000000000000000499f4f781a97d6f6499dd90828ff56108ca70c9074cf3ffd699b17bca3415acacf7b81775df4ca9aef69094eeb2ee0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed216e6af7f5ad67518a6edebe57608bde0c7afd49aae47127403144470a6c3b7e14b31b000f4eba1411f004cdf4ae400000000000000000000000000000000139ac0586483490c670a75c775db97c5a41dc010086b5a7d62ed372e96913d47d83d9ead99611b4baa6ba619600fbf0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153c83e385cf2446646645280489c3270ab146e791d78fce37b12cdf7b02eadd4d64326d49b6fd2fcedab08007ddde650000000000000000000000000000000018ddba58b1b5101c1ac1ef43bb72f7bf96e58a1da2c985b71db1a33b9273cc72bf4bfc251a25df6e03ae3f70d1d9c9431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c740261b9e340150250b096f8372ec484bf4d5e7faf8a7b826002526dffafac37ff23adaaf8239b8bf5f67d316a00b000000000000000000000000000000000f92c82ff6ea1333e6a50b40b9cd5eadfdc34ffddeb5a86eed52be8b85ea98789d94ef24763d4d00515585ddc84411711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0856a6bdc1a62cb07231879f8a46b288d73c0cdb3c270011c657ccd98e7754e146b68f659ce4ed517226a3af23c21a000000000000000000000000000000001085d5768619e4295683507015db2062ccdbef08c81d1a2e31c1353ec759ceccc52b5cf1eadf428c195ae8da70124ebc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad4e6f6252ee8d639265cc534fe8aabca517c54c149baeaba29a4015578d372c7a41092eb43d19207d2aa7f72c91efe0000000000000000000000000000000017c745a4895037631ce3210bcbbef7590f05c7b33eaddd1f52fbec80bdfcf1fb0299422b623546e3d0ad1584e76aa1ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080ec62c35cb632f9068608ea6511d945225ab4d60b14c81464b105df31f852e4024584eae04b238fc2aeb146b13eca400000000000000000000000000000000147f8e3fdcbc1329b5b30c32c879366c5d999bb8b7f34646929ab9f6e7156bd18daa16840353816e28ccc46d93f8f0871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b56496e4888fd0fdf388160f7bc0d0e539712c934f505dfdda79924ef428db0a4b7f5702e00c4636d5ef7c43d031046000000000000000000000000000000000812b266cd98634b4b08a2ff6433ee000497fe1c764c9461a5b401eba4b6e6b1f745920da59b6bd88a51d48add3329c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055a8cfb4495e0f1ea81ba44899170d983402fa2cdcbc42dfe0be9c76eabf73ef029857bfac2647b84e7808521bb9f8f0000000000000000000000000000000003273fb2ff26bff62c4aea0f721976854f7522ad1dbf4bcaf594e62d4c77cc6a43d3192aef39c7996851a0e0d300d0df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd8f6a526c797f549479137c181357c8b73777702f4c2e293832b7c5d382345f55099589b5b761d691593b3d7911abf0000000000000000000000000000000012eae7966b31a0975b21ab3d79c809dc1317ed14963351444606d33f6673ffeb650bfc9f3177ae2bf44a360c0ef958dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001542b6a5358f73c6392e0ccbc628f402168b121dad2c119a3583dc5ffb63c7abada8702a58402fb865163442084f2bb900000000000000000000000000000000044b381ea59f07427a2e296887d4f8cb78fb93e739876b424b25475cb2daf68d6a0518d5509ec9742c158685089c3c391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012aa0a6fd26b1ef831d0c452c425aae6260e5f483b714c20ce807463ac28aef2d3e749d1110b9f4576cb7729ae73dfd70000000000000000000000000000000017e68fbb10d9bbeec1055dcf109824eaae8980a60704b18185dd9792a5d1932fc1146fbd7138c6460d9ddcfdb80988e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001729e530cd85c9b8bf107d9144ee13adf6422148c6f1dfa07f7f00764ec092a3dc608a8d26e4fac1550707697e6bd4560000000000000000000000000000000009a270f69d7332df2d2ea143a691d3273d37834d2935b48e6dd04d1d34bbcf758f097ba158bb3efedb707f53b6a628e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178044b47c8c7ca293ec349cd5bd9158b928cf34f2bf0ce44f094518d755c12ad90b9fa0ccd3e63583d1072c9d205257000000000000000000000000000000000cc52efd543665babdefdae276db517cde138c8efaa1f1b803e43bdcfe5f0d661bb6aa55a1e8336fdb7611cf8255a44c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007df99d257ea1dbd0e20bfb100a24840ab79f38788547c027943b79046e612df0536aa96554f9437978cd5703458d49c000000000000000000000000000000001434e7da6fac87b5190b23a9b698238c1d4382be9d398caf187b3610f14cd458061501d97ec4391b3a60988f0e37bb7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001789fe1597ad51eabcfa4865ca7328962dac0b681049060b94dcaf54612dfbb872d77cfbd11ea6e38d66ee774a88efdc000000000000000000000000000000000d2717fd2b3a78285fa3451f02b75cafe0fa94341a45551dc09bfd3c93dcc427f6848ffb6e33f55b765927b558d144261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c875303b5342a96daf5feed7274fc26f7db8aecf2eb193eb4c38c6772f9dd2e49c0b5ec37f613f43e6f1f84d0eefa8a000000000000000000000000000000000777c5f3c4f6f37db51413c58cce1157148f0f9eb4304377eeb0d162d80c44a9ec2381a775c0454e9b8c65e25801b7341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1234744b9874a6409a150660cf1d3a4e3eeeecf4b25ac11c3e134f6b110e8764fbc9401a200918b5881ad6bb0a3e11000000000000000000000000000000000d9d8e7b5b5b010db6d7e5bfa7463c82b17939a9f000bb60aff9339fdcae8619f11fa35955c63fc58e82725e93867df21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166bf929de63f4734f3ad38af9d0fb6284c5a4ceca175f4d37ec5b8d164678e0c88f49a30b278551eef7e09f58c5c8ff000000000000000000000000000000001060372a3e7cc12b25896a449b1df2666eaacc2713ce1f9e6af650ef574b26658d5c08093678f2478db36b002f5a849b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f24f42e64fe73921de8eaf76a89cd659ac1a9be4d4a64e726c3c008b0609d2d6f77e9e141c0434e7fe4e1e318144a900000000000000000000000000000000049a61744929e7ea7eb9c3f22006536c290e5721e5476c18382a09f00cf6377601928606cfb90c0e4832a9e2baa7445d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088030f13c12b299bb2734a562192be3694436803af1a6cf64550a9df7dd11d582c403d458b53ab19c157963b71976a100000000000000000000000000000000077bb47db6172549ea6b00f1f278f58bb4c88f78663d82c7d8072fff04578703f5a8d7db19c006584f728dd4312bc9f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001470434a67ec265eed708efe232907314cc94ee6fca9bfd15745c60f20a7e049cad88cc6013e954e364ded3cdfcb463900000000000000000000000000000000115d0709a6a7249e5644afeefc93db2e935b69258ad9de6822b175f87c2b5a34dc5a22bbf14d05295c18931334d73d0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d463b20914562e55fc19d3101f19d858207bfbd45ccb876690c1f202fa2600d719c2b9d229564e03a61951b316400d000000000000000000000000000000000387d6e9826d40849257fe305d682ea3ea8d8d74515fa854b0e281a2acb291b8173673253171a6ec4b5a48a2cb567bf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087d32aa3196cf37902e3e22676ca838fdd54cb1e92833bcb4f437095f51f2967771618fd59fd593215e86f9d5c31f39000000000000000000000000000000000ff45ccbe8bbf76cb3accad67554dde5cfa1fdd225c85c075f51a6988fb9957f36992bacc52f1281564d64f46d3a24261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc9291fc98abab63ce72791dab5cc28bea069adabdc7e25a720113bb19a5613b814491d44f0221b0d4ba98291f5076100000000000000000000000000000000073082e8f724bc8938da46a47fabcb9d1c8e708790a435043dfa0b1aab5281e579ea8e091e0ae3447221924eb360414f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6ca7d603249b62ef448f1abb71244ccebc2ca178ece155dbe3a47b052b8c903f4d1fbc5115f1b4b65a9ba42b506dd30000000000000000000000000000000005923a3ac9a83670c9694df8c3dd4b90b908d15ae03f43543b52aee150429cc5f1460077545ecb8b0c1813dabdc7f05b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001115665e5938e1d6fbbc9db56cf19c6863a5be5b35c4237df8d5460e1d11eb4f82ccc0c2354b949843be16d92cb6dd000000000000000000000000000000000b5f64887e13d3cba7abbd86ed48325705f5ec14db7c8c70add677faf2fdd3baaaf0f34de497425b9d36c41db35ae1311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f6c2dcfb709e8e9d47c15fc545161ee50d0f1147f195f055cfdbcdd1ccdec191fa9519aef70e63f5fe2105d77abddd000000000000000000000000000000000e963e6433fefc34036cc77b01049c14bd28f17d54274a68defa9380e3d6bfeb6a0f0106b3b1128a3cdbc85080cc80051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cd27d3730da9b25d5071c5146d103adb6ce6c4b1145621a2728dbd91bc30784611666c36ba2aff32e519a63a7f76a30000000000000000000000000000000017f805efc967f09f4c4c46b37273d1fb232a105917c81f69682122bfb90eeda89f766cdbbdb123396e6ddda0db3bff551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffe73e4123863278b1771d8385b870e1483165bb038d504e476f66106d0778f9d21c68fc7e2342e0a1ac486ff571b4b00000000000000000000000000000000052b0a09fbc0da14110a9459cbe61056b5562c1ace79caf55e58baa86c16240638492584ce9dfbff5100c6c4faba3ed41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d84e8a53d78d669d5876253bf188412ea16e7b8ab7390789ce13e519b13f09af3957a40b4beb6ba8a027966d6a12660000000000000000000000000000000001133d79ba731923bdc78ce6286a50f2470bf28d195c1e2b42c0ee738f38be38b4f6bf20785a03dc8074ea01e5bf5caa11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017323c5490150dfbf38faea5fa478d058fa4b5ef7fa3614c04cdd5432489553f61384f385a23cabd5309bed7ce7aa6e20000000000000000000000000000000008df614ed10b00144c6ab4387883b0be5f907ee69382705033d0adcfe235e69813f45a9c0ee00700e6509bb23400dd9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea4439f9da9e484a7af5d582dd57099c335ffe410c2c2d32af7886410f0badcd9b220230208a8b4db1a765efa8133f900000000000000000000000000000000198e8e1cd28ceb274321ca5ea0b4ba44c8e1121100a7cb7f360eb0f48e493c8bb407106473efb4259311939168c74d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8623f9b47f22866dab20281dac6a417353ee873aa6179c081ffbd64c2311ed3c646ec09bc205080323cf568b1272b70000000000000000000000000000000010b03698bbb760c05f6d729729dc751c652bb669712f45b82ceb7e84c0fc668f701e2d4e01b2b456b5571703e90c5cf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100a0ee49d4f5597eb541ece7d97e1ff350b5fca33e70f8b08dee9d73321b7b540ede7db67f0c44957a999a439d21ded0000000000000000000000000000000003caa9c201d59820288d6f1f827f33a83196d5bb3dc7a42613dda61712840d57d4d8181a211a8e615baa5806ef2d477c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035a0893a9ca5bf544650260714e977be1de2916d31e5a1387f303b05725581ddd2aa42dc9129a08ef875c00833289dd0000000000000000000000000000000003ad409e30a7f4031113dadf1b97672709e7f9bede4fe3aefededf759af17fda0567621dd81f3f2407d40e17eb73963a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dbad5b0288777419e219d7d77daac73b6981c9629ebb0953b864fdb6e97d60c7d033c44d103ecb1a74b3403375db440000000000000000000000000000000008d7b7a3613fefd4058dc7f2572c129272c8be4b578cd7b59d64ddbf7b587f1587a3a03d75632ba291cce765ad7729b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012194949874408f90ff0d641c7579941b87db3f01f3dd20f84bfc52dcd5487caf28bcb22e9d0d332bb93dc2e42007d7a0000000000000000000000000000000002df041fb394585357b968993f13bd808d21a6b7b66aa26fd6a22067949ff2d999693216402366b5e9e4a9c5bad3f2681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001877ab5f2294598de83e411037857b10a6aca53ccdca72971a6aca66b77fec97e879c0a9b0b0ed0dd288075cc70e6cf50000000000000000000000000000000005439a16c1c70a94973686813549c279a82b3954b39345f6de329c093891651cbba7f9cc08e707174703d3bb0bde2cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000684a214e3d5ed90d20c1a7b18a4fcf701c1042eac31c15824aa54e2a67d367bb2648edfe7c0356ed7643da1a96438e800000000000000000000000000000000142293cc80550d166e6188cb02e66fd63219564958c1d5a686e0645dc44f0f7da77a43eb8a0c26a5a09013f79210964e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082dc740877929016940089cbb67ea8da4e733cb65453904bf52e36aa0e0e06ad8050afc500f0694a1c02ac39aefebea00000000000000000000000000000000187fddb1760ce9db417cc426428bc03652986f6f6efec75ac8fa54eef1c2bc216ac3d5d17c9f23dcd037c4fb36cd94ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001825289ad9aafddfec7dfd8720023c1a8a04c22926ee1a2231ef2ea8fc9c5e88c5adcaf11c4c6b82b05d989c2da3dda5000000000000000000000000000000000617b38d561b3cf090c070d9e5b8f3d97eda7ac39322c312bb2389fa49c78fbcaaad2c973ad96fa20a2dd168f92289321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8b140c4e65f7434f86473ed147c2d8c03ef1ed6bc6efaa1b405cc5b80d3b6604dbe9bab74bacd50955b22741cc1324000000000000000000000000000000000b216f7e02c4a9bbd3ecc6b7f2f107459326a27d5df974e91255dd14165e17688ed6538d179d7f44a3e4c9ff4343dad41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016017948e754a3440a7c78b2c7ad696a9a701c905eaf0621ee48e80a54404887d7172701df403e8d9913fd868785e5b9000000000000000000000000000000000c02b21928c59819bb27ae9d05b1e0647e22857b994020b646a9c98ea33c00eb3458f219174a02242b7f45dc00505e041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000460339b13ca7eca4d7e6550fc7b1047972c36ed0dd285ed3d05394b153961234311454775bb601892c0896ab1b047b700000000000000000000000000000000193deeb32d52e14ac7beb131961b401441856c3fd307b919db511ecc6fbdf656c11f3d6af2aa2508a990ca01b3f2c9da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f2478a8de6f40a4282713295ef3e5fe537ee29b480a31860150e97783b9f7adb0f76abd107bca4c7bb6818c75849060000000000000000000000000000000008795d4b975393bd43ac07728171a6411f50f7825a579edd212e17293b9563e5b72a27132edcd2a9c37513225709dffe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001451bf0d41ef46d0626f580c93dc112752379be4480c63d188c54d1e04c43c22fc3022ea736c22b9faf69a9caf037e1b0000000000000000000000000000000003d6083061523ea5e28b0c037b68cafec5eafef297f40207d4ddc914e526e5f5f2a0522bb09d08051121be0f3a0b1c2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5d5a37e9009df0ed24f589aa36dde0f5eb51f65f0ee8e43a20fa0688cc24f8e1dfb273392ce2ce3d79a9269575a3300000000000000000000000000000000010ab230a5cc2d9dcf5b67f1be7757eaead84877bff6a561233919eb8e1b713b77ce320e2812cbbf003dd91f924f952491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000bb99b3e2c49ba31d648a0ee0315888576302d375899171e60ec6b34c344d6c21058e58656dc59e36fa68033c4c70f00000000000000000000000000000000027734c169529a04414aaab0fc27c383d4ad8ba9fac391a122127f2d151a7558388bf590be7df1e78501b02288e657111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010977b35ee9322e5c9df70062045449c6c46824dea989d7abb6aa536e37340c46a003b3725d8b127199d9e813c316b2d000000000000000000000000000000001197957f64b98fe84390fa9c4bdb3d882fc1929524a9e2de4f7dc5694d83701c5e502e5d8c98673518f8490e2a7102731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d219275a2399cc78e99fb00725088c83c48607fdb6653c4a9896147988596c21cdcd0e81fd0f09db1ba32374eeaa550000000000000000000000000000000000a225824ec32ec8d7cc53ad8766805d8f88922987541a0e2777b6beff68abf5f03838a4d013a58cb02571eb90f31a2af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b7aa3e8b687a233af5b4d4ae3ce830f4df51aabeca09465e4e1cf3e2446a5c83e51538bf74b182c342aaed3f014167000000000000000000000000000000001808d1b4884c4dc24363b0aab9e6f0f1e653f6dc0f00a40b6177f65b54b8668a0e2a234a1f2c91f6cc449e5fa7edef401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012698165841a63b5df6d62cfc671cb03648927203323462a47b3f3550417228e79f148fe717e61296e8b33157042eabc000000000000000000000000000000000a87c946c710d9efd8824e2ff59e0eeef09a0fadf1ad0493799da44395cddf5e1b47ff48d319baa50fe9ba53433a167d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4e13efff93add9bb8dcb2624218a01759618c165adc90357cfb9a13e75aa9544cb82cf40c3b06756e8559e28202771000000000000000000000000000000000d237e6f8082280ddaa1a164b258f19b9bdbd51041b0573a43967a593df5c2bd9358208451583be0b4093561b36483951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122dec2ee37c3d34c96d81f7826312e15dbbd9d5aac9c24efb5ad63639241e093cc4d20da3dc8e69badf1f2ddf8eeecc000000000000000000000000000000000a53a91bf1407b9497e26d96016574c9b7575a93865df003589002c27523d6ee33e7047360e6313a6de9f288dbc560e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c2abada9888c25c28a90ab756bfd260691a152cc1653bfecf022ad53f14d5beea5791a54bdbf7c1178c34dbc6d30b70000000000000000000000000000000017b4e030b32dee8dd8e94a6986016e5f22048d78ab0dae8973021aa33fdcb6da3521b566a8d9d6e084d375797d7b26f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f519fe291dfa0479fe78121d25598314c92e3d352d23f2447b00a153ce0e2317f2410bf3e94e87cdacd9fb21f868ee000000000000000000000000000000000ea3ec51efd63353195b34dec9c819eea616d8dbd2a73fba70e4b158e8cbf46088dddf6c6420017432e9b25a67745b291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cdd51e99db42e2a42d23c61c2bc65fd2136ac519a1325f1850fa4f37c4e3071384077106a276cd4cd52ad6e67edb7f000000000000000000000000000000001133a35ebbc24e24bdda8c563a09c602951ef9cd0fdbd8509246ab50208b0c9d5590adfd9eadc352ad8aafe5c872d6671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ad3f7be36677a2519a3df2ab8c0e6a4dfaa8bdb0f060f999c8ca3dec31df10268148146bda3c655bf52eed2d2e8bb30000000000000000000000000000000010c2871d77af0040bbc8efb542facce80f3a5df0c3642d94c18011243d2adf3156a4ae0f1188da2967f7c8b648d65c1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b2f964230494254be4ca9c7fd473ce3117dd4b346cf85d81bc6c27c8f2544bcee0e2d1d0a097f6800160ae170f40650000000000000000000000000000000018174de7be43fed86a2b4301b4cc2773cc4f57192a9462b713368e14a0b0a065d865572bfb2f6a151cb23f92d8a90d9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001195b8cf90456f5e34b04973a9219fbfb8d04105e280d75f1e58e9e450a6725ec8488aa499373ee926a15209b831fd2f000000000000000000000000000000000289029aaf50f08102e44a0d8cbd35766fd15008a9ad3c3be6890ee9da9d76c1dcc1d29445440af01740e9fc823a7c331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000357cd6f20b474c2c375af8ecfb76346b18d8fba0791f1b1379d1417b33354cfdf4bd4802487740b40c2ed112df8e5f7000000000000000000000000000000000af259c37282510fb70c8f8afa28886c8762722afdd8092b3f173da80b44c79ac3017d09276b71514f173258d95a36371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c5886109cae47e540c566b804739383bc491c449692137619aa7150cbf1a7e144cb7afe0b22cc142eb4d6e6c4c2bfc000000000000000000000000000000000f7395f7fa3c5786b356265487628fe4479060f62be48acf466199b742ddcd9b2c3636e9a34933486cab4ca106a0ea881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee6392dbc2d04d9d1a0da43ea4a4e4fa86d48ef95a96494a5e8779055dad085eeb0db7874f0fe02e2d5094ed2bcc92400000000000000000000000000000000058872b881f2daaf7d2c1248932be6818cb4edca146b8cb9f34ecf74f7393babfd019168a258b8f87e60abebbcdea11c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009012cd169b4bc6ce52087ecfcb3e1e4a5565b3557720fe0336e4830dc01ae99169d7bcb7593372fdd1ecc773d2b35af00000000000000000000000000000000132ac9808c126b1e3d34f5626be8b693e1503d28927d021ea0a9dd1aa64ce0f4a05bc82bc6ca40f6b3882f2e33c3e3321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7e692292564d2c08a20396922055e2a3d8fbfed31f8a05d0090b554d5f318fae7ab45acd5cd54242522cc1b2ed8fb50000000000000000000000000000000003bb6ca15fc9e3f8ffeb1714ce27274b990ce117231922a273decfae4dae940cb5f155a1eb5e67851c2a380635346eba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043c33618242415f2bfb939f6f9ae2d3d1623a6372800b68c7bb06c75a9d02547bb2c49908864a96b97c3a554f99b9d400000000000000000000000000000000074965028b92542e140596a1030ac234a08bb5ccdd450e41eff53ee8f88d2d3f0c473a499d1cfe8de76f1029c9bef78d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cab60d959cd0972b7265a92ec6a8f50679539f8b337f4607b0496531166fdb22399e4f62854cb37dd3c31e945005900000000000000000000000000000000006ad9d94db5c6bca460338151357492a2a219e029be62049f03ae675d92fb5fea3b4a8924d65c72c4740ee5c09e501561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a387893ea1fb87c3437d405a4715a2abe71d505fdca4cd6b10426b77dc411ac5844402a5649f0a37a296dcaf908a17900000000000000000000000000000000103424b912f3575b4a46245349be127850977d7e97768b36bc96940be63a14add24bafea0aba6aaceb1496cf257078191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cdcb32cddc97f800535e87e9fb4897470a0d9b1c5fb8be60f6030eabc8a02ad437b372174b7008cacacb8ad51013a9000000000000000000000000000000000e643ac29852f16f7a990bd455406e8d54ee4c4b53ded6a251e8c268a1261f1b2f3f0fde5c45395e81d4fb1584b6a5fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143a6be72808901e0f73f7e41b3b636840501c7bab43d2fc5a767d5214de4388529acd8b6618006183fef112b8c7da460000000000000000000000000000000005f9baea082ef1f6155740a8fcbfc604211ccb5d785902718372becc39c8c52e03504e76f6c8c7be00c477d68fb589291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a21c330c5360ffb3ff27e84baf1be5a9cbee1cbb7a7e9466757d010ef1cddf2c27a7236b1da6de24b3043e0e735bc400000000000000000000000000000000002d009211ca2e3594069e7c5edbbef17cc16cae340e1c8f26b95c215abfc39ee1e7745a77aab78000f1292fd0a0c21de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196a9b00b7aaec5f1cd3271e721ca31f1d8763c2387f6b3a41cfd1643bf38ff113f3872bb05748888e45f847966ebc62000000000000000000000000000000000ca7fb0df9a424d0b963a3e0177abb9a739f66948b00ba41b4c498325fd08d8f98dc7bd68ef067d018a3f655f0ea5c8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9ee00a50bcb3e75c9e16ca09173974939c3f9b024d7194aca4ca11de26fbc357cad20450de030ad45d911952741951000000000000000000000000000000000e1a0d6c1ddb87a1ead84582f940a714d90234fa9ce67d63d70b2f4ecd9f9dc80eb085d6b770eb9ff76dcfcc0062c3531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7718f728ee75df0700d32a36efecaf58a834627e7e9b6c275fbbca136af575d3c08ce4e958b9fc9723fba7c123cd94000000000000000000000000000000000cb3d8d625c701d70f6f17760824041c8e85e4eba6e1ff52f4f8b28ba210dd51eb7f02e8b887365a094282239f8ad2011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062aa94a7249e47a1b89c447922c6258b80a3236756974c105e7138b415e06189ddf7e9b6be120229320205102ad790d000000000000000000000000000000000264390d34a7cb6c63fe4efccb6dc9bfa7a00a1007e8c9ed83b8fd9be02a785f9187eec4af454b5e7642bb1a1fa2059e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012911b166ff6630e39d465efeb1e5a39350c58dc8d90f9dab2d584a6fdd7b6a060a1a012870b1fb3041d9d6c8e8efb85000000000000000000000000000000000da888491f18a7c08c3ae3dd9dbae3cdafd0ead10d2149e077807f9e165611f9854630f5ba12f1e69b2dcd7fa922e86d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b4ca9840219728ad548735afa2bcbac50e57c3fd616e64e1de856026499aa20dbf15735041882fced148d58b2e066d0000000000000000000000000000000018c5897c9ca74e7010a4a5840370c52e7ba8eab65265c617b0f9c77dcc3cab68a2af1a1e4b5400f0ec88fabac9b20cf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030bb0c5ee343ffe5138c75a2a1fa4e39526e96093bbb628f9125c7688a98dbd5e7ea6c3d48f3b5125cd995026af7ef3000000000000000000000000000000000f480a1d6f81ddfe607c820b3497b3471f7a359c4bb086f4bf3077348f1ca0d40a38b8a36501f861aedefda584c77ba11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ab48bb3a60a8b8a751db878a0e3148fdebcae9a8989416d584993e3f8d436f4c96bcf6ec2ae539921e7a923f24bae50000000000000000000000000000000007e7da3c1bd5dc539505d60ac4923efd56fbeceab841e0360e60dce53cf2190eff8005036967f7b8c80ad402024d75c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183297092462d554b459c3367dbcc9c5160108b8279c62171873869155cd725fb8f6772794aeb262b43092372f570ef60000000000000000000000000000000010d549ebfebcb9058ca4895485f21b0f3b9e2dba707b16fee90ac859dd8537d75d32c6c51384135aaa6aef4de6eaccc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000216cf040ee2a7420c6cd35a9550c607a74760f1dde8a7ba5e06c7cba7599c820ab945600fdd691d77993d8b9eb8b23d00000000000000000000000000000000185b86e05890bde07814b99e7ecf87c980cf914d7f349bea886e5064d3ee12368e6647eae415c06894d8e3a18cfcc05d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b14dbaa80399f6f0951a13eb3bdd383b3709d0c7e023fb96f5c4182dd926266c5a1ae25bb7fbcb00bf8257b98c863de00000000000000000000000000000000044ef036bd4b28916045f763f33c6f85359fa80af15302678046d5f4a9463ec4ec4a1873b847642e766fdc0d128e7ae11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057a45e6bf6efe47e05f380c0d3dc4f106cb6c07e839f10c125517417fee39eae903668d073eddc5d5096077daa38aff00000000000000000000000000000000102cb800ce0fc31c9164b0a53880566394bb61b72d28975e7bc3c0091ad79af0b927f1500b6505363cbbf1b78aa850f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099279b9024e24e4c335d10e2ef668de59a45af0dcd2e687c1defe350ab8d63eaee952eb2e208ef1e715f900c114013900000000000000000000000000000000038c4bfea318d152d3a69cf188b1f062bef23f12f0b1d226869c268bfa872a88be2423afb601ca7ed0a13b4901c8d4ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e2aa6106dc3bfc74b7b5d18a40d09e7b58635279aef9730929c1967e0712a7569d4add49770f4132cfb5b2b6cd5343000000000000000000000000000000000b2afbbd6cbf92efa9694c437dfeab42584109eb324b40109f93786288cdd1301d9da58dd68d2b565938fa820e86e3581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132b87a78584e03504954744cfe0715d01ffa53ce607e01a96a3262663d427b85638be739ef7f5433f12352a70b061350000000000000000000000000000000000840332389d474b72dfcd968fc5839892a8f43fdadc7020d67cb0136f4617846d278e2c2435986e335968370236cc941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000faed983cf87be5196cca1efbfdd07cd2463bd97ca6f624daddc0f020ae0e6f233d6a644cf361f666471b7836266caa40000000000000000000000000000000007ba2587eb49d2a6be0b531093deda8df81313cdd6642f68a53320cbb786d8928db40317776de8374ee88c2998b25d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000139078db19d01a59605c2a874b0cb56c5fd3b425d8cc79632a27ff658a8b173d1ebf29f93e92afba301461df8daf865000000000000000000000000000000000f9d212d26abbadf585c0b3b30eca7e0b91bc71a991da72c13658322eb9dbfb9df3a9034cbfb9482ff0a3ec9aecc72c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080a9d8a4ce382f0d10c283e68ddcc63aa326c60673b38eeff3cc9f05896e81d974d56c4b1950b55ad73f173d63e11b50000000000000000000000000000000005543c67fdcd5ffdacd6a41a50c8cc262db42ef6d4aa22aebdfe21446429d24f1c9a6188ffd6466b8d421e750a26d99f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e849e401dff6f79cd747ba63d9d095f1184b97c3074122c24c29b2390396cb6c609fbe9f7ad824f4a51ceca25326e20000000000000000000000000000000015bb5334f987eb5171c92f0c4041a291c3666f81bb1d9fc7881de4eaa56c80db0ebf8d1981875ca1a022c2e00d90eaa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130872752943c5dcb86ef3a0fcb098a14bf69d3871ea20f27b7d4fcc4429db45668af0b4f35ca7dee663e766fd1cde400000000000000000000000000000000012ce566dac7c1147c6a47b4e19fde9ebe2dbcee1ff689d90c372e5a66c77ea10a664e1366c323211fa18ea69ea46db4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001400ed428a6e6a388a9870ac92b548bfddec0dce75ba3a22af4667825a0d5649ad6ea9146d4151a148285c28624d6258000000000000000000000000000000000dd3c6a15f4f6bf616712fc611a99ba42eff8ba404b8e0faef0f583cdbd567145403566b1c8375f4595e248750ee71ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049b8cdddce2226c068e52d273f7711a0913cc471673295ffb200bc980f7c465476cfb5bd9df4307e46c6238a2b98d2d000000000000000000000000000000001080d006ea4096567cc56d1cbb5dc568dafae8930699ea5c18738b3d81ce9e8ea27a05443063b5219aeee98ec65d569d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027c06c03bef72d7e547268b6a9d5c649225b7d861d84e3b04b1fca6bb994dd03df198062a9a2a46725ea75bab51527100000000000000000000000000000000137cf32048ca8ba8b52f3983a8afc6835cbc0305f6f71c6fe05f14c527b082170f0d089189a5f09603279af1915897d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2d4adc368a0e84072fd2f8e45016eddcec7251d11b5bb641389e34a4d7a752fc0258ffd4b7a7db7acc3ad8fac587770000000000000000000000000000000016a9399021fb80a2fa57ab9416609be8d0b5bdc2af1e1db77beaf0eb6525528e35b0ac6720ff781147fb66272aae0e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e2420c7b6cdd61640266439eee1bcd5f081da72c94bb1e45f90cf2c22c4e4f53e4bb816a3334472fc89622a4a8490d000000000000000000000000000000000975421734c1a0b90f8992448a09cfff974d802bcad7bfadeceac3feaf7d1e645be1e19edc3c94b060e1401d7b2dab191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001914b335c07a336c6ba6d59c502177028bee782ee9780a1f02e239d119ff6c135161654aacb860473a2d6cb4161860e4000000000000000000000000000000000f7dfe4d2401ddbec12028b8f6f4296ea2b1fcc2ad16af91d56c0b8cd1c5b9753481919f2518925770317045e706eb511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001738437b6638aa216876860fa37a53bc7f1fcee4393d179e9fe92ced9baba5403aafc443f1c68a18dd4b861ab63b545a000000000000000000000000000000000703b4d1f9ef4b0dd434a2062cc48a289bcf08fb22f14f293f0342e8a6bf139116b8694554b3b4b8363614cb9e2b90701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001395844a02056a97810a67609dc818986c2e2d9aaa8505d30fc751be7305d9dc752edb93318f66d59d987af2c0fe6f3500000000000000000000000000000000082dc2148b20cd39280bfa2183d11012bf5c594ad26661b65beccbd3ea3b27dc6775831e55941ad5593276d5fdb2d19e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdac8924ebb2a2875cfb4142cb62c73d9daaa7ae72c9969f6eb817e17e256e987ec0629fc244e69ca2678a37fe44ace0000000000000000000000000000000001245ba0f72335612749eba13b842c41c937af88e19b1ea6b91361195d88231b1253c35022666b191d28fe727173ac711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e0e73172afe306c148574e89d0149b65056491bd180b0b35713ab76b4cf01d53f3be5e3aa0f28e0eba907a3becf81f00000000000000000000000000000000153006f92ab9b70c3885d6b099f41db8f903b69e417adc94f93c53dca493d3557c8ccbf55d55f06825226c0adc983d2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f85321ff8c282cf4d6d72ccc02cde927fdd020ed5b95cdddf4810f8b07ae71aa335988ba4b5fee2d55c4a7e438634370000000000000000000000000000000004a0b041e264dd653eb8de9d9ae95bbc6ed81ed769853011b7942e63d2c9b530d2c1da7733a02b23741866e2d04355f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b358dbcada3a456ddb67cdb0b8f9979eb396f07d2c33d6f08d2f6d4b09ab04cf155cc4950ece534459f7b53335f9aa000000000000000000000000000000000691b39edb1b00041761a12e2c7425dadda0aea6a50e9c45606d9755c0e015685ecc1cce91e0ac8936c3ff69104667aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7bfe72c99854c4585ad751131829509a796a5d722ba2103421d197f9874e41f6ac7161a6a883f1d413367e093766fa0000000000000000000000000000000019c08dba2e8a5ca3d59afe3a37b161f400bae355339292fba4105f58dd4bc764e845c32092ffdd3ac846979a86c017541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba553541a118d9abfa89775c2f8b362bb5d88411dce6e12ed611573c1b02be0f56ed44100fd39aba193bd079005a14900000000000000000000000000000000157e5bf2eb12a530ea29bd268d90ab03c64a6f46d19f90d4044229106d19a371a6dc3c73a23669e02ac83b345e6988f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014952918815aea3c98b79cee39c9c3483666f2091c9c5dddd9acc2a19fc39529497c07f484dbd9364ea845c3b78b5453000000000000000000000000000000000653a2257afac9f711c9197937e43a3d4b389317cb29b4b289b97843cb65daaf64ced8345240f4fbe4ab42f24c8415451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001818b11e2174ea89d71baa50641fdde66bca58bcd583a8f2147feb92009d2cba2ab326cdee87fde5c9d03aab97a43346000000000000000000000000000000001706a596255d9d0fd573a45c2ec171d240de37eb3900e5f4f6c046d488554049bf5cc6828156518548f8573f0c41de391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dbe6bd0b4105dd9d48cb0dae7a6565047f46c3cf388608621cd60939e632b0f8ecd0e741bc8442a4e270aff1a0a08b00000000000000000000000000000000105f7cc77e5cec9ffa975ccf8792d6ce97ce554bbbb7b075c7c660df5feb659ddfd86e17fdbb60cdb0390dfe8a3635ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182a5ae750b45b4b7fe5221da0b4d9dea782688e0dfa6b6ac96d3c0f960b2d1a32c8b6242629c221dddeaebf2b32931400000000000000000000000000000000154556ff16caa2586831dce8fe83ebbac880d16c7b84b317b30a7b76b89c9a84209f9dd6c1060cc8621e1f34045ac5b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098a42c83827de71d1eadf012606d7c596f7b97eb600a6e91b1ac858b0aea038ea7840982b332000d113e325d6c6c74f0000000000000000000000000000000005bdc8f299251735a7a362840b48c7ffd08503496de13379f0cc4a9e32dd2eb43e8833fb163ec979987e9df9318e07f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000965efee82bcd6d9ea87b285b7186d11480decd714fbdb083b93111ac81e8ff4c9da659b6d27aa706ed77adb6882e9d300000000000000000000000000000000130567c569704b7086e8ca1e42ab92806b2ddbfcd7c94701b380284074cb5b883aaab1bf645763885de24ba4c0ffdbad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001942b149319968cda4f9d7a3b20d983e53bc51fc9e63a26a149a1c9c51081dadfa6861948279a3d63bb9d3ad195ba89300000000000000000000000000000000092e0a0d32f6fbcad7a911fb9f2b3c8abd66f49e3d2a98d701854351a5655736f799ca438d5b7630148b0f0a71a4d7641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005de8812a827ba6c2eda2d15fb5a512c6567b8ba35107dee99f07f70e77d1f809565e1709aaad755066c25e90eff99db000000000000000000000000000000000cf0b29848ca2150a6e8fc30d0a2fff095e3cdba2cf05eb6b4f9e7baa012fdf30013182982d898984f5a35a02c2d88d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee118ac4f40f6a8557c4e15cba996d5c80a03214d561b6fcd56696775ccd88b01a1285411995e1672071541bbe2a5f9000000000000000000000000000000000067beb2003398d36feae9f418a2d0d8f200b922534d3bf018fe6234105ebe8287617337b6a0b034ed22f389614afc081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfc352ecb32c491bc978fb115dc6e9779ded0e9aaf7d2e5586d2a21b12cdbcecc22c4be5648203643c56e8a2517cfa4000000000000000000000000000000000fd9804ea2cf917c485ab65faf9f52715a03dac2f4f0803b4a3949398060b7af106fda3eab55179a8ddc11d3179712b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df2935b11f74fb47d6f7d1e50b2dbd65c4a31c267ace95e7389739724e5e26c0e21e2bd1bd7c02eaf05cf945b9593600000000000000000000000000000000012b667af8d120a0b26fecc610214565f94f1ded4c67ced5828c74b5e14ced751eaaf9cba8bfe3743f056d2f20c8a867b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a13d122dfc6d6aa8315e775574b960eeceaf2e53b2e5ad1dcbcdfc785152fe4f56f667fbff4dffdb99c528f5150141a0000000000000000000000000000000002b791f1585342f9c98975912a64dd56e41dbd43466394598f0f5e0024f9cbc6f7dc02b1bc6ca9e37e4c9fb86b4a33241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031e61fac9a5ad59f21f0a4df6fd17ad02c52c27e797b516114bfedb3be79dcf9596f0feb56234c2889451032c517dc6000000000000000000000000000000000df261ad5f4028967b63e6b82a2a32d5a05e326f2b7a153f17f97b944289c670dc37a9252e40f03a38c289cfe233a9661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4450b069f179258b904c4280dfdd660f216521f6d44aab245e3887d5eb244889b0816f8602bd4b6337728e0640306b00000000000000000000000000000000061c39ace8d371c4a10a596b4879ec61615c1c070c0fb46b23074851f94576c60b9331c3f285fb59c656504f50338e9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001675245ab016871af948c95d5a164e981256a0aa5e5b5c1845f8d5322bf8196929ca204def38358c5ec786de70ecfbd90000000000000000000000000000000003b5f2672ac084e1cec821b60f82bc8630ae904998fdf62542eedf9a6d08706d25945dedaa1d05ddecea7ad9cf4fb90e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180474fd96ed91dc70f2ffc9c3bcf6160fce6e42e481c5ab1ebbff1717911525fa7da22180b9461044392e025c206cec00000000000000000000000000000000061c5930f08cb4fe3d584edaedb5873a21a4f1496496f46938db1bd2ab1e8ab186cf7f2d81fcf09d97182e133b9d77641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ceff9ccf7a40575dc01974c1d9a2707896e96cf96d8317c94d288e9fe1c651a6afd06b73db5257ddce5e3492e6075050000000000000000000000000000000002a8d731e5198a077676ff03adcb0d998b857f0b0f734b2f72c89ac51f49c671db28eb229e34a1c7dae6d95025683dd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cf49f46ae22d66f8eeb3442c62c89a6fcd7811608e18c3addfa8b261ee17ec829aab147685812f8bb54276b785123d00000000000000000000000000000000033909e12dca5ba7de515ca46e2ea59668768e6fe7d5dae35fa49a42427d224a6c1b71102056528fb9e2b0d8e792b1ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062f46f68ed283ca0bd90171167fce9a1dd00e467671ac3895e41a64c082ca934fac3c41f9e4f09f2f64e6d372a680a90000000000000000000000000000000008c7a314bbbac36f9baea503312ad72c593cd2d1d4073fbcb21ce87c5c3ac416165d6b49b9e0db0c6c73db6e007a74021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b05ccee05d515d411a62c1d7f90106c0f8453c8ed2ad97b633b52c0b8b7be8275214c886c8c750c3ada41f45165a0c000000000000000000000000000000000c7fce37d21540739cd6e98a67549f9db725f34b3279c02a5e663b03503009c3f3019571fb0f68c1dfb86b2fcfdcbe661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000625f70fb3ac0c9ec964ca9f5b68eb9802512864e4e149d9f567eaa6b28566597da6c26f978fafd2199d93c9858cf1ec0000000000000000000000000000000010e447377c13f49e36e85498f66ee5bcb40f492854135330979a3d9b37dfb3fb68f8d41efe5d425e9e67d7125e7c11cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b98c753fc64f29c26f48f7e8ba20a77119d5070b2348eece41eacf75f3e5343d095be24830a1d7a7330e23d71d9694f0000000000000000000000000000000015990f125ee6ed6c438176eae44eea0a1b1fa8c6a5b211ec2709d72e5ddb02e6890d1ce60e90804db39d7666ab2cd49b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011570c19ca60f248bf4258407507268363a31926627dde77e52c086be6e3dd56b6f5ee717360eef87e78c560a9c4976d000000000000000000000000000000000a978192f987cc0f03bf4872c764c354000f93fc9f364a340ff76d4250883cff4642acd3a8b47fd47d10636ba0656b431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae8040231c919f0f3e6ccd46f4bafe2b464e135b478b7b8c76c01b9cdd01cb5ef520e7561190bc5b982ec5e38920a87000000000000000000000000000000000c7f4d72e869dd3c859cd1416569b2ff3278fcfb230a737fb9931f29194d0f1b765554ad5b4462267409609738fd08361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b18279295538e4199e716091d75b7206bd8d82861fc0ccfc8425e123cde5b233640196c37ec54f339934f7e0afc52d9000000000000000000000000000000000675565cbb9c2f281faac5d416bcb7c346a278c2b00370999d1c6865ac5f2ec4703c52cc7b52b7817027b9331a383cc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a0b18c5d0f0a14945983b34d5fe119067d69939164b7239d3bff43b0a9b3dd911976b91d744636fdcabec1a618f04000000000000000000000000000000001571fb469a12f70681dce097be89822dea93aa68a91c309a513fc36ccb2c9964abec0b723d864bf0b0af94d40c511cae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000771a6ad18fb99edffb66c11b6e54664c72f6ac11380888adfbb95da2645ccb76a62335ca152fe3d10bb17c1bf1970d800000000000000000000000000000000148627c05233c6507f5def752bb27639f8e356e42fd723514bfcbf304df0270d169f4ac0c2e8f7703ac97ea4735ac95c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c2c615405a1962a798f56b75d5d6d2164e5f21ec9f08647c725190b7ccae38f19407e9c36a2ef4015a449bb881d3a80000000000000000000000000000000013712a73ce0cd3e15ccc55e41506bfa9e1f87ddec178e0e4716807b22db7ebafd2a766ff55a1caad274afb9be98b156a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000254bb2e7bf42ea22908b313d3ca8dfa4ffeb194073a126df0023b6eee47c1b4de97b777747648e9146e60f989f08c8600000000000000000000000000000000192911cc9070a8a95cb6b0f5bea78cbc75645b7f1e4beb9c3d117a04b25188b8ebd0e1fcb5611bd85f2f7692f5e290181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160754037da240a910fda111a060dfc16700e5ce7ffb5e0fb8c8a7e3fa4780589e194bc416a7b3f1c5a691c483e504fc00000000000000000000000000000000049366b802fc4b025356872ad66d4cafd34c234fa7c4115e6d08a60acdf61f55b57e28af84e6a99e2a6739529b3eae1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012151d0ab0b97a56e01003b8eee2a0a54f59a018fe85b9a3a88466382e2f0eddc246276d8979e7a30d2bdcdd6dfbc9aa0000000000000000000000000000000007d7dcf664dbe78ea1eb5af4b9118359e54aaabb32f365e643269578e125c42a483acbcd3f107b5aa814c2672170ad341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c50194295e8853a3cbeceafcd549a63a0ee12a8dce5ab4c1f7c8751ea8a8980eb3706eb9711a1eadb8f6874e3ae71d00000000000000000000000000000000086382b73f8379fdbab190a31f36900b1894a028a732fbde3e37d70d3a8c53d5cbf1d60797b09a7756cf1cc8bd3738561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053f1f1a61bcaa76b6b13d4cb9656edd5d1b0b6c9f3c2f935afd990f9e196ddf3fe94d6961e87bbf7457aaaabc15fa840000000000000000000000000000000000902a9782f8af65ca135c6aa62e1ffafc1c3663a57aa79f30d203c832c873dccb94d3fc70ccbc024475112139393dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1cdafa828687c55e58c1a2faa1746ff737cf0eada80cf664ea3528a4de8b43647438e377f74fe7fb8d207a8e2e44f00000000000000000000000000000000124431f43eaea1cac8d0ae373d8f514ae84142ebb5e10be9466da0d56aa45fab333332a8f51414b15e991300ca0361351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162f0b3b51a486ba9f9dd5371b7d44286d6d8bc066646005149571a387e5af2b24a41f7f82db561c9206dcbc82442a8d00000000000000000000000000000000173c69fd43f04ec3f2d4ded29367b790ca8958413585ac0423bbdc6a71bd888cc9f3ff905e0006848a8ac79aee080f9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001311ca6267fd37f2dbd066c33a639830f1cdc77ddf173c8ec0f422d09c8e7595bafc46ba8faf4a89841bfbbbfd6aca26000000000000000000000000000000000e1998fabd618e84d5cbe4abc5c4743b6a34e9aff7c43c3084e549de5dc323ac4a5e62be9afa530f11c80a298aacd86d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082889f7d334c8bce97a84b790b5b0b07241fba8efe91d61f0b7689a9c3c43c92c777bd66927cae9911c8f19afbf2ef000000000000000000000000000000000051114d50edfce8ad48550aa62e55c29348ee5d1a96d7ed497a8b98ba6707c6b06029a93c11743e94783ec689eeb5e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dca5dc0e4d005ce43f920b8055e903b156ab5ebc8231f34e2a68bd022b6b3308f97d3aacdb8b7edfe5d327b1acd0ee000000000000000000000000000000000bbca756fa632ef50ea75f1ba9518ff1bad2e95332f7c089baba58c0fc6d8bb517af01b458eabc069e6d305ab639cbbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e246c26a722ac2488eecb546fd27d3ce231e7525ed27d8b0a007c85e18b27f4142ff7b0a11227b0fdffc4dd9ad542900000000000000000000000000000000058d01b26984665222bd59512798faeb160a540cb77dab9b7cb4fb1d3a25ab1ecc477702f0561d333c3e0e9afa7f91011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c62b3e1c1042a51f113860a7570d8b6f7b5adf21e9902d2854022007d80cf58fe9f65417649a8b19b9f2d1de9405c7000000000000000000000000000000000bf588bb802df12f15769ffb802dfca4e08550383ba0f9dcaa940281f780bd4b3fd02eafa28feba1ef94be340db96e581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184a256e50eae99cb5252eb429ce3954066ff6893416854a0b2f5f60a3908aff263e3fc0fd63023402aa256c6f2878ce000000000000000000000000000000000775130031dc563ef9866d63969e6940917a12318b4c7b58a7aed3986ecc37e268bbc6b491c9b1415ea310065f8297b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074ebbf5dc9e032bd6a8e2e6de5c7d961ea4714b1404e8ddc70621a5df7ea36a502b0d277eefefb71c2a19c04c1517db0000000000000000000000000000000004913dc1cfdf43c8a950879734a8bcf6a6af35166e1cd48c8a3a950e0a035afabcb8cc961a19e67e3e9711739e8eb7c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135c3ac527c06b3254938a85b08962b5a1eedb0f29d989b8a621b90893d52110fafd8c8da2ec9307110a0cc5fac58b8e0000000000000000000000000000000001a67bcf1b003afe537a756fae59c0b5410e2c29757a3093f64d36d7be557f57339935e1b7729640659817682c6ea7011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fe309f09a54119ae8f088f935ef6c77c3969e04f556bb0604752a9d5e6df4d8138bba9405776aaaa9173f16ef5f0a700000000000000000000000000000000139d424475f4b5137b93528d5f219b473b03aaae685e17d262d83dfd5ea28117a32cb1f818ca28cdc9447edda387e8961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192798d81fa09194a7f31ee602f4e475240d6c647e29de9775b3385ea1e51684507ee1473c0226ac0277339e88eec22f00000000000000000000000000000000047da48c8b3e02eb93818e2fd58167f01e780172979fa296959359544faaf18b27f37cb4861fc86da476cee90707fbab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cc4d11017b08e0fbf7a37ac4bd97471f34418c8fb60b8a974c5f60a0a11adfbf204a9edf20163de2e1ab8d812a895e000000000000000000000000000000001471b65b5a0d7b3a3656780dae231016f7f9c6afe5cc7bb21f30a0ac09b2983c6c1019165f3ce1ec80cbebbaa4ce755c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ada32571d1f4f9dd947d0d3fcce17c705cd4ad2f3ad139df092ac74e0102e36f6337f0f64e5acf6e331c08c91b14b88000000000000000000000000000000001316a61c0be759344bf7028209291e31a6cbba20ed77baee5e7de1a8d2362edc1b2424cc11fb036b9c04e86a3e445fd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d76a13f9c68429d6b585515a2cf96bd32a9be4029717c6020f1a36bcd27efb146ac8e69497bab61aa290dadd77a58e00000000000000000000000000000000033d2abfb69b069c313205bbbd4662bc3e3e7b46e43912366f03512f896043b640dff00fd2cea141e9abcc971329e27c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088a223842be7cc6c514f589984dad64463be4fb9ea4840cba0690a58e5ea207f86fa01ac2bae3b82686c1358de7db95000000000000000000000000000000000c2896e7717e66a8b4fdf99149287662ae3af2f8a047bc631330a55410af88bb2ec7957f54594a6f338a101f0bcedd1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003253734fc1f61a537f4c0b3899bfc37cf8cf6929566f3749051b3602138adc52ae169dd35365afa3df71a6cd28e15af00000000000000000000000000000000044e355cd514c361f9b7c190e4d6bbef6790e05bcbb77b386d249d0e1af46969c13cdff5b062e3bfbbbfef225e18ed9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022340d75eb7e0cce293316f8b5b2f8a3166db1aa356d4ec1d7a3d74a0b5afb6c9a197cee094a3d0179c8e0c8059d0f60000000000000000000000000000000007d27f07ad5820f6188560f86198c42f87548a42c6e7ba7805c181afe43f837bba51e15e4620f79e1d60cb18348612041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004279cc1f57a5dca8615b1981ba8bafbae157f4253f7da72f8ccd5be1b29795c931df3d9f95d711483017a9f20d1e04500000000000000000000000000000000016c21ed357700f02a37b3f025809dbb2bb5ed6c60e195ba35ebb2cbe3850e11bca71550f2d59290a5bc3a44e19c94431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f0dbb75b967ac6b5e31c460ea7513a66ce15aee0d3b4a4b0219923ada64d62b27e93d1ca5cdcee59a4216d706b5a9b0000000000000000000000000000000016164f86f0efe58170600abe7e500daeccbbf1e9e41b6e625e8cbbf299c2899dd57e1196ed2f4b000549f13d99d7a8f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a208615ad2f10179584e03ffa40d736d7a4fd06508b41d08e2fbb7dcd03ec871d602dc8495d94c85b645d017b5a1c2c0000000000000000000000000000000002dd1cec0de565a72e47c655af94ed366747859c8ee60ff62c491b36912298dc6e753b387691fb4c71bc9b280fad10461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000266a685c9612d7f382b04d38b50ad4202944657d35b87fc0a0234fab5446adfaa431cbc9a1cae794997a1a32aee5f530000000000000000000000000000000001c1428e505fd1182e73aa962a9ee272996a708cfe02ac311b5c37faa9e0608919ed411cc3233074ab6f78b7dbd8df4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef23a87125937fe9908725d79373c80903cdc4ed2bcacccbc25cf5837c1179c9dc534480063ee0d5ffacb384205f9bd00000000000000000000000000000000111f0fae06bad6e524d00af3ef1f3347f46121a32f8d52315ff21789063eda4601ac3b6cd3acf33c7e52c71ee2cf4c791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c0beca26609f6ae5f6cbd0859eef71b4cd7d75511d3c6935a7eecedc0abe5da9789ed1a0be4dbc3746f9a82fa1dae10000000000000000000000000000000012adff1919439558e71d276e1e21f061000ab267bfb8423ff69a921c85ca5ad7ba0aa4f33e387216f0e88a410375ff311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb930cdc25aea3a082a4e291f04493d9bcbfd59610ce51ae1cb6aedf61387977d42ad3700fe0cc1cce37a570866111b000000000000000000000000000000000c9760228f5ba9c7befc6ef763d1017bc8a2a8988327df60f047a4a20728892eef0a21c4aa4fb73e093359078bcd10e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c80912bf79cbc32b4bb44a498cd463d77cacdd1ef3592687c96a03e28ca0700145e118462970fe0432849110b7cb780000000000000000000000000000000016008807e5de33b666cc573952649ada4643b67940b65be0f9dd54a4afa33b67f53c0c6c2bf5020ebcbafac048dbb7aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bef0a054f5c8d82a37b793c507fc0841c755a25f7dce1540441696c936aacdd292096aff26194c1311e61b5f7d42f700000000000000000000000000000000169043a4c3bd801272dc7e2425cd91e02b8fabae5345e331dd72fb3dd5c4f8e4a80e47d2c9f92e5ebe78a73c34e43d261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000452a5e4f04bf67257eabbacbe2b38bf6a950dfb08080fa7d7ad8928d5123a567e0636ee6da9b767098ac6682b79d5000000000000000000000000000000001352e89c105a085c68bdb04b05cc6abfaf29e28c61d960f884aa3f50b5417741d1cf1fbd3946625b6b7fb80218342f051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014124127c5db150232e88a103808736c202dcc63801516ebda06a1fdc8d7c7ecaa66d083c5fd830eaa907bced902d5db0000000000000000000000000000000007f388d2e7387cef0f53f9527236e12756db8cd94e785bb43dfd9f3c0916d51caaadacca6279aa175fc306b23506a4c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b65fb3942a3bc3a0da7fdafdff5fc37db4094e3f1cc7a70d80e094f728e587e355438a24e731edf4647d051550ba1e0000000000000000000000000000000010f97a12f00cfb30bf7c80c685a4fbd0adfb05264fc7c67f5c4e92c5f82c6f427335ea06a535aff38d98e8737ac990281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007539670c793d1b91f9234458e884210e42eaca0aa1668a85760d2bf311c8f05e1ce5a9c44c178d9f1c644320c6fef3c00000000000000000000000000000000100764d18aed2bdf55c3ec424a2af427be4391c5b523ba99c57acae456da579090f7a312f6fdf304c0bc777ef705d7401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f52e825bc139e23a7ff129f27fe6ee15cb3c7aa5d0dcfda2f405f689823d8328836380aec73c974ad9c9034364b55400000000000000000000000000000000053bce7bc8a15d8dbda96162c642cd6e1b69b7d2718d861616105a28abac2c0a784a329c4fe50b74413e0ca24ebdb2b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001110c9f83d5817a82e1182f6bc6031dc6112ec048dbfc0741d3df716b5ad2c206032a606e296dfed31ee1d93edc1e82f000000000000000000000000000000000089749512c1eb0572c867943218d24cd1c5aadfc610dfbc7a2c4e30e016d093767605a53a6824463971525fef1fdd7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181857afd7cc75aae25bcb6b5acaeae41fcd98771b9b1a1efc9bfc8cd3df0a7e7baf4311ca4411710651cfe7e451f7d90000000000000000000000000000000009bb95d0ce01fcc66db69b59555b44959d86dc01a63038018826d59240759f79981f3001512ae95e76eed6fbb508026f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019604b9d149ff4448a986e478f6c0e733d1195894439d768e3d65f7e5be36037114bf6801786641e82575a034fc45d7c0000000000000000000000000000000000effd3a2377bf0e90fe25c733e64c08471995ff6a114552998a84fb3791a103d8a07e71a5ab470e619a8be1e8a005131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcddbec700e6706075a7d2d28c51b683ff8ab557cda780b2437697e868c92882684e7a285c4648465643616e049ff330000000000000000000000000000000003ccc01c5c8a9e09bf8029c8eee9000c1e7963a2afd06a090345f899e8b1baf34f9b2cfe9e8ec8c471a61cf075530d491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df0f041608a5da0366362aeca3e43a3b59de0d4b21fa0a37f83c2b006029f41d3c57408aabc3207d26d4c5bd2269028000000000000000000000000000000001487675e8946ab4942754b61a2edd145e5482956947e5a28b4e780463bc695481be1e555f837892e3f8f979daf44dc4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f02505ff355766385e7c545e0d5fc37339ceba0e6261d8cadfdf2c71d7d0f9e0385a12de1224ab282b115bfceca1a630000000000000000000000000000000013a1d1c03bc36edcce182f01582677e40ea178fb8505e4fcbbd73583514af6d100b6ebd608e4db06a375f80e59918a391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011800815b749063fe1f3da8744a9812dbec6b12f4352d06463ba254141473e6bbfe5ed94678d289b01463fa0602d4b410000000000000000000000000000000015d6b529a33da12a0c17a038f21504e44414d9ac2ac618d0a57796db1ad28e10e53b42b418fbac2f3476f12b3abd27a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec4e5d42ae2b64111da2f2ea314f311d03508c36fc4222e06c5822f737fdab113b32e9dda18dcacd84a576d905af9110000000000000000000000000000000002bd0f3f9a26f356a060d043f0e6fa361170e83cbbf30ba9ab57aae053bb827a38b17ceba8f766fc63d55fd5e9bdbc931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040b0ed65fb627d069d81b9b9c6bae97067c0823a868db83a0b31b722f346f21e2dbfa18aa570a3221ed16c4331370f90000000000000000000000000000000006f315db56b39689bc706bee757c67fd68ea0d782e74b64e48fab793e001acc524aa0371578a86d70be271cb59325f741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110afe91e7a6ed75249e80b1157ff9be5dd99491e0e4a0739391b9aae1144bde8119b972e887a7ce1e2093535eddbc3100000000000000000000000000000000063536343d922473984ff1518d678a0dff486d315483ad89b7106967489f2ef6ecc315cbf552168f36a4536d4eb7219c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175ac1ddb840c29a57e31daac52803bdc63dc860e25e2beb7a999de9ba92f3ea21035be7fa42fcb15afe5ae068a898e10000000000000000000000000000000004173e78c6b790631576ee36668e3fb9d9ab5b95b0c3c9e12356c4f5da0c776ed0efd6ec5dce57b5a9f0eabecc79f3251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e1256efea124ebeee7536fa67d52211cb2d6e21dd153b7b56d3c75a88ea13fabd44472774b560c827c773767bb5d7500000000000000000000000000000000090d01c8f4fcf382a9f3a7b9a384a878f10607371609c9ee6cc2fde6cbe52d5caccdaeb13b5426c2e4ee9628a1f109d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013e68c0d21448eb799c7b9a66152d2132ffcca5e86abd6b4af57893ada49a16306b380095ee2ba5b01f0359ed9b31620000000000000000000000000000000018a353b8cb237774ab89332c08c93c94dd45e9f1ec270102b0d055753a2a95dfe34157d9dcb873b5375296528e2b7a5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcdd62d94bdfc9c8827f2ff7cd80d4542a6d993d5b18a2234761ec8ee11b4f4b65e18456feb9bbd826606b306445330000000000000000000000000000000001592c717f9ca17d96caadfbad9761c9518e4aa53f486812f80438b03466c84d2d797c1cd963183ab41db36c47f1c48d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000740fa9821228f6b48df5cdf277a613278f9bbfc5596da8cec7608f15c030f0617a04bdda9ca17347a614c4c460ae50c00000000000000000000000000000000064b8da267527980e4207c730f7c38e1b13fe3d13798befac5e60ee730eee77debcfa42490b6bf14cfa3a853e83271c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047360af520ad7d81a1c30b77c585bfaf8760776d0f5f4c1044e8022994c9688dea200e91c08dc40234dae1a016136f2000000000000000000000000000000000faefc86164dfdbc128d0072bb4d15524723d3a191814d9cd6eb25d34393f240cf6ac63e03494e40f79d9076848bd6f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f1a402a33fb33af259e6f3eb373ca148cc60f61bb46bb59dadda95282a73292778091541d1a63c8471d3a9e8682ebf0000000000000000000000000000000014a8c48feb5936aa1fec493172130d1363e8431174e9bca811546a6c53b881e84e2b4781a342d1b6954184a1b78e25761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187b5460ecce36ed8e5db02f204a4871b7b1133bd4c2182dd2d9e70f62e8e62a0165914dd3aa197f28860db9de6ae4900000000000000000000000000000000007b0277d455bcb423a917c9f57fa0b5bee51af6d96fd68bf220b0b27100d58856535a272b87163db2fcf499fbd85856a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9246004f91d44fc52129958618b36670d00e587537c5f3b53e760d56165a4b5f4d3371fe11ee3b8de0af2f610838680000000000000000000000000000000008dacc4bc6768ee62cb9138a33a9483ed13c3a3957aca9dd697e1be3eeba5c1d385376b12262ebdebc6af35d7b3345ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3ba1774e67f66fe4337746c0947c915cba9d16206672aa419df8790b428112fa2ff9be0dc2b945f223eed6068eb93e000000000000000000000000000000001246cbe76e597cfbd0fcbd28b7b576c73e123951ac44f74f58094d8ed4f05ba6a69a66a0c71be13d25c38da5afe80c231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0613bb9860ca07fc7f1949876a03f29fcac55ce46b1c9d486e9c2ff8e7eb8303269b70b38b0d62395b0c70b66d3fb8000000000000000000000000000000000ad153db2504c85637797ed9dbc342617afb150bdb593783d9c8cd1b1eafce41f8e4ecb16da4797569e36dd56b3665691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d5ff3ba7159046de97b10793137f49097db4459c099da627cdb6b91432cccae95d91995747c5423aeea8f09fdcb23b00000000000000000000000000000000091b15b4d1e3cbb1679f9956e66fcfd276d8e00e270cea26df5d3cd744bed003180d302beef8a39a32a96535569a9ed01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cc8be6ed3bc6fb85d996168c3cd77d9343016b131312d987d2a063afa2aedd532493535090a71bd3a4557f64fcd5990000000000000000000000000000000013dfd6c33a326400fa8e5575a5f09887f0c90eef7126172789f52771a03dbd42e117c2d386633c6499e47c0cf44591e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d531d643e289bd33a114e91cc6805cf45fe09cfb46756d252c78e1c72721b3482ee58a55b92b3df8466a3e5b2c5e67000000000000000000000000000000000b382b5cbd7379675347f58bb9c9ba9df34b420eabef1b437bfede6923d23b68097743eccd981abaf82dd623aa13bc0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001318f56a548d8bb658c3b8486d1ffb90621ef462d832a7bffc695342491a44125e6c3d571f1afe12592b427e673551960000000000000000000000000000000005bff673c9a4fc9533bff8abf979228a30141a33647686213e08652d94af293de577e944b7def9db6482435e11c994bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190dde2e55db6b51380ac359ebbf71e32aeb12cb87cee2a042970e203be778ceda3b90a68cc2231460d39c6f38f972a20000000000000000000000000000000009985913290ebc4ffdb154b54c34e20b5b951cdbab8f4bc6d678f5a0e34dbe9756a95d951d8fac0ef526ff006a77c1151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001054f66a716aad2b1a08cadf2e0c8f430820761d765c6646afa93602a8b287f9add1730f307842b63a2ec5382587d95d000000000000000000000000000000000425d03c26fefab667ee9c2b71e84cd055e56499aa889f050a0a6eb256212868b1fe1dccb8dfb2be9782064ea1bcd71c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000b4ad86ea0164ac538586a337e425a9ecc4bc5bb762197597cae01e0c8468d33f58c24fcf4010ce686bb0482982bee0000000000000000000000000000000003f932096cfde9bd5137c024c8659b35d63be77d4f8ea6bfdefcf6ca04ebf143d550d1d830ed15d317c1edbd5eafc42c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f0cfc0cd5b06508bfdcb5718a4c63d80a261b8306d84461c4b0866794200bd28be233adf5927da1f35ad76e3d3faee000000000000000000000000000000001216142ef0ef4f3079860828467493f2e07ddceb663b97d103352e87b225eb24f0698e4050b062393cc0e93daacd8ad01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000129f3504419d86bef4b46bb46cf7c36c97cc6b5d08936c8d304577b691b43daf6d2ba3550e0d153e6718aad028b2c9100000000000000000000000000000000018abf4a9f4dd92e1a67f05c6905c1e79be30d6e201c918916eb13fb75346739449bab0ac86ab9ed51d30bc2f408771a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000970b3998896c60a3afc2e3caa70bbd75fccda97e2c20a815cc0044a73143635a693321ca2dd62b2f01311e9b45ec7e20000000000000000000000000000000012847e67ff8427e1fa065525ef18340cfb7d41c82c0c381be87a623120aeb075a6c193d760ac2ea2a1b2b935d245bc1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073481000bbedeae7a8ad2624b6753716a34f006af524eddd10a93f561217102adef7247d9c82acacee2cbb8c110ef500000000000000000000000000000000004758b444c59dede5ac76371d7fd30fcf0d34126cb768ac8ede356db3bd8e8bbe91bee032a3c6c07edfc95b3b22fde461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000def6ef9101a742dfb22d46f92fb318aff64accc19b93e009970d0aee0743f0eaa1f90c4918f9a37dd3d18f9d3b57f5900000000000000000000000000000000157f8895be634a8d235a50c7ba4c98666c2132d91451d071c89595e2a41c13072921764fa84812242a0f6aa164c39f311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d5aa79518cd9d5325d0127631e124a1a148b45bcdb27f3fa680d5e868e2de7747752b64af72786e70d008e101db0e9000000000000000000000000000000001894c2a988a99d578567c182eeb36170c3895ba71fb05104ac16f630e5d89bf30272fed3fbd008f3a0c0a48bb777b4451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c144f5c012d36ec58d75c09040429048e6a317c550714e4ba091b681eff493dcd98f9bb6a267491433e1ce995d96780000000000000000000000000000000009b3010abb7431240373199a50d865f1808b4bb6c55a7f65f7e06fc8042f3753b8b4a9f4075d3e60a6e9af15dbc357701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e7552f97296d60ff327a5b1e6857325b09f0dd5b6aec3df9c8e0ba061e9eabca61e072568ac0b885e20b6fb212efa900000000000000000000000000000000136807cc16f4e18c0e540915883bd7afed95ff6c9d10079fc2713fac90e7d4d43f22033bfcc4079b179fc77906d4b84c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbc60f948c2c733716702b8d0fe9d2fdc94c49104b314a94c5dc5dc4a278d89b814b4493dcc5ad47528f70a49865f74000000000000000000000000000000001901bc9c97ea3bb05dcf2ae05e6c2a38b3693f173c7ebc5d71d535f88e491d5ceed00dc049b6a47155c20549ea1edf631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018265bb96eda1b3fcde6c527836fe432b8b952895cd3978db66ba0aee789367e657ddaa68d9f0701412f6f05d1b6fc3f0000000000000000000000000000000003a8e4910ac4391ad9297f2fd7903448fadb9fc981b4819725cdea045d8a2b2ec55d71e604c40623267e4104d4221fa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000404c9badef6e616d93c59835aa0f1d4eeaabf2127e5165fb78ec6eb38e83e4f6c4c6aa792116e795c854d643dd714eb0000000000000000000000000000000015b0d1e2c50f5b91c28e7da910350efc381dbbe250c4268e306914516fc6a30da073b67fc80b7dc87c55dfd83d9898da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160e2fa8bd979f815f7c045e61d82b7ed0a691d5254d69d8e7e5e48a899497f34fe0ddd3f193cfc5ee68a3b4eb544af40000000000000000000000000000000006c9f80802676cf98ec2abbd8ea0716014ded2b9ef9262ea19a90236a036c19750c3ba0860bf1ecb7c0e0ce0bff44a031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001538ec0f501b1d931a3d84306c3157e4e2292530df497de260559944b238ee14a06b45b630772b462a7571b78bc1e7d20000000000000000000000000000000006384117b5f0b02209bbf0dfa92b54f4e8e4d0a62d58e00dca479756094fc1c9317c42d7dae1572561edaf9408e52af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f2a0a1fb45ec2f0b14460be6c09481e86da415a1c138f2f015ddf19dadb224abd6df0d107a25b2ca181b41fd524003000000000000000000000000000000000e1fa78bdf9f2a8f7cf4c04946b5cbd7ac50eb43dacdb3177d1f250ab8ec53a0d13af67d2dbb190a026db605626d4ced1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f80dbc50371743ea40d30377ed7eabf6830b786e229c5bbee9a7614b90481a0ee0e38e27d0bd803e12aeceef57289b200000000000000000000000000000000092dead05b3db300f709bebed4fc30585b65067d842da14157c2387212648ca945e1cc993db1afd310cccb478f2659911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049deb16851751c49459066fd1a0f7270beb6970e223a0fae31ffa3ea69633a6b8fb7ee9da6e60d4c5ef6f2db48f0569000000000000000000000000000000000278c1182df37adef5d388ce43cc07d3646b27ac5a5bc5f7a9b50f6f74c094f5cfd814a0aa8a6fd217b4f48c1ce853351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bb7b73babd35842cc1ca65d0af68e0c70051a38f9ced716600efa6b517624930daa7546e4da61069d121b943798d74000000000000000000000000000000000b14bb1160a76e907de9df7452dc8400671c125e3e82bb21945212bd21a2e3f57397427eee5db701f13a551b2052d2bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112fa4eb5db97f269a8487069fbb2e03f0c51a70f45d33611e17609d1b0609d5e2baebe866d99fff869e39019ca1a80a00000000000000000000000000000000170ef4a68d0f5b60c4d9f6eb6b629d7ab71bf7fff1eafc06e1ee317c2547b448505d67cc96e1166bbe7e905ce9bec3331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c4ebcbbd6216cdde825be522e61a8625560e4f24be225885f9323ebc3cf331e80f18f1eba286f761314ce2ef2fc99a0000000000000000000000000000000005a5b803adc0e76f524d1d93a5d99a988e3913489d2009394da5441d69db213466c6ffc53c9070ceb7321de77b4761f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128578ba01dd688c1e6cb12492a288afbd277072d42a15e81cb54f3853ee5131396e5415ca185833f19daec396b656a8000000000000000000000000000000000b42e06c9404da6e7b34b37e48c9b8c1168cf4537fd59ebb06e3d990cccd348c1c49d7e8ff2536843c6604854e3356321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001590520725d5dacfd807f0e9d7b90046a5c506e6541058f0611d1f7d0ed54518f7339069f816142de77bc78e1ce1956c0000000000000000000000000000000011deef3425107a3c0765485c9bd3f399dec88eddd9040d8562565cfb55715178699a452972795950fefa385db5044a831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063150b62411d859a7d76fd378c67403478198744032ed2ed32cf3982fb3c483d1286f33af452e9191b166ea7d13ea3c000000000000000000000000000000000be24bd912f43cfa1566a427876bda2cc462fb1e7f1f5d5421aeae495438dae106365efb5d68b42a3ea67e083b70ac641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183abe01770dd743db6c40e46f9b263a00c8cba950224c8a51c897a92c78a7798b0b85ba59c404f448be395901978fed000000000000000000000000000000001927776cc278f4841734e4d3ce661fe843e11d2ab134d98c565fbdf05fa179694d2ce841e80418d70126105d3c10442f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001448f7a88e1790f7fa989f2f2582ea6dcb39dc674bf404032b512c9f9588000fe9a9795d39db6cd3add1e31b21d8c44e00000000000000000000000000000000193a24d86e1b707273e640fa98a2a068ef5b1b662634df813d1ea87284396a1a18ea634b8934a0b3104a0f1f2bced2111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9fb507acf4b1bb575ae952ed84d5ec4e6a29b5ea24a897753b90d49db1886397dfae349856e0d2e69ef09c4f28fd6e0000000000000000000000000000000007d5421637f5de504eaa49c22ceacfb8583963d6f10666e3a0d64cdc57ef242d93cacdc5bd86da8b9c2f33c0263e06d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c453a342e940da4e0c4fafe0ab6706505248ac3a8781ababa62d3e47d747ceda2ed34ea15b76315fa50d9fdd4c36918000000000000000000000000000000000e326d5e2a7e70e8070cd9c54f78f1872b40786f3edf6633779bae6e90efb175356b9fd706d65be84f5460a4b52c58841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001652ddeafcf821253c148db89a648d830ad613ec0ff6bd602935547ee1cc8900088dda0fcfdbd271debeb7ba8b31ef2c000000000000000000000000000000000753e9a5acf86af7d977a473daa5fa6d27ec934513063f16fda5a86b512bff702ce1c4c34c542e69603158c129c89d121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001948be4f4d88ef5c51013756c53451e3fce7326c8623d58ca4afbec5bf8d1a825a461d7b39ed6a8224d534d06c6e32000000000000000000000000000000001579ff5700907668a9a1ee047f1947413ef9546696adce370e32af316b1089e00bc61b27ebf6433592b4fcd97640a51b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdfda36069d8ed76eb4cea657f13c1489f5ac1f8e0f62bd214ce24aef1245dc1453d3c45b827ba38132abac0cce8263000000000000000000000000000000001625f5dc86acb1e58465f3f44cac49631d63755b4949ebb235560032f34a0c22b68a3411aac826d9fa9d8f78d4c746911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091aa69660689333fb60a38d105c443462e0aeb49e6cb59c47080e92093a2d824f1f9f0aa6a2c86fe50a4e8d9942549f000000000000000000000000000000000ff0f77b9a6a6138951ff811008008d62c1020c30b2ac29e635eb3ad753f2a443852ef3c8ae63b816d0be327515a35be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128562158ac53555989e3879e577e7a97a99e1758b68bbaeba5880d6d70592ba60829554bc1e29668c5009d27a728c230000000000000000000000000000000004abc9d2942359c1656519e885154cd0488e7a5461f7c924e771648fa0635d8978cf18cbef8a87e708218215d10f060c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ca203f58cf12faea4ae0e79ed91f07b3d4075d5e524919a92b7a411ebe4b9efdac5c7f19c2d3244b4d9d9134361ca20000000000000000000000000000000014f6c0d4751a6781324fa4f0d152adb9329f22453a7fc27b50632baf8d9c5713c9996594ea883964834b2bd379f46d8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e38f31e1ba0a15720d569041cb751f885808a195ba4016f5e1e9d8e39783c813cd0826917ec9334516328a56327dfc0000000000000000000000000000000003146f4d4325f78021c28ead7bdeb307a9b51fac79f342c29cbe79826f9427651bed51c8c25ba006e2ceb1dcb44b0eb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004067519e8ee71cc8bbcc2289a1a22472ad758eebd26902e80b7885852b9e202421f25fe7f3ac21c34ae0edd1ca2dd72000000000000000000000000000000001847709676a8d44cd1d60a3590e558505372d929bc95d93642d0955e68b0b376eabedda257280a552a7ec3373046122f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046035d172dd7cf267880286a3e8ced2dcf16625f912da4e8657244a1434844205f1d72ed6e82ef2d714129b2973bd9a000000000000000000000000000000001050ca3bebcb84ecd73d448f7d9a9d3ab8253618450e6654ab68d861b58954d8c5f5f5752171f357a02e4d6aa1493eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a71b78237c4e15d8e7a57bc4113e9d87a16d0905440c420f8db7fd5154d4f2b77387317060ab556db85929679f2ab60000000000000000000000000000000003ed16459ae558388bf410b41ece27d6bdbb02501078b9b46fa4065b664f8e08e051974b2ab2bacaced66a3ff2399a3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001705fbdacba90c504a414796326cf867e0b21bf959ac1bd63df2adb5df983998667324049bc302f13db07b6d27b5a0a50000000000000000000000000000000015a8b20341a2bb1bb4a7aef8614c8aaf7b770702a31f1db92596b650bfdea873cb62248b41951462e9afe9fdd4e1d6ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010aae2d94fc6595293fb63fe20a6480f3a8403ca2f47f04543f461a414695a86f1eff0fe7a603631cc7a8a0cc503d04200000000000000000000000000000000069c867a7468268c6ebed32222622484fab001b01b51dec6d009f73a8daa879ea572faabbdb21b6d45c0be0753d5a1b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e885ef239df6064c88a3b219ad40a8d01a2e02a771b544f2648582e433c78fc8714dc3b22be4d2ac01d02498debda100000000000000000000000000000000115eb97d959b55cc272f3974b2fb0c7954f8512ef0a95064ebcdb38db772d9946bd4bd0a8941ec59241faad65b19ca591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041aedc786ab8dca9a201805814bec8ca6fab1ce90b2c6571f398e312963a4d9448127cc9c485faf4e904af46445bc3000000000000000000000000000000000106c249bf9245b9bb91bd7befc7c69d397c1d4bf0a727057ae9801e5b2df23c698b1369ff6464f4f9fc551a7e333d34c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f64069c6b19172a6c92a4c492faec713a11b4dfdf606fa4eab902980952eddb33170b77056506e5a676b81345a7b7d90000000000000000000000000000000012f828b349d974dee88585a23bfa3ead4aa457af004793f86323653fff8b7640675db17b34080ad68df8fc784f7817151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190daa8593e3ff56d0cd389162cc472a091386fdb3a2a1a503f86d89a1c31f3ca4ee7319cd12bcdd22ab7836957841dc000000000000000000000000000000000f69c92a106b6c8ffe1cf0643f507af0174721bb4c44db4f3eacbe4280fbe24e2435930d768c822b3a4766dedc57453b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074954f0da7f196fc65af579cb7a649d639f1a820b48534169ea7d2e9f6c9bdf685be2e8e2c230e77a9a818e840ff6cd00000000000000000000000000000000111184bb532feb6bcb2da352c0a273a383b232e8cd8ee8f4e92af0b640d311afa348d4a0fb711c228f1193ff940409501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea7bbe602058c1e4e43e5844ae21ecb809e6024c477fcc03eb0e7a5fca10fcaf896bfcb4223ecaa4de2c9b5ee8e14b0000000000000000000000000000000009992bcbef9505503d29c07e71db857707f3405a7a9d16765975e51a5effcd10aeb529fc3b990e220b6a2380c7ac4d341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ec149ae811524bacae845b2b36418ebbcd9f572995a9ff11317426968d4d19519aea52e866f10eddeb5a73b569460e0000000000000000000000000000000012a88d14b708b6f5e42bb6cf1d70c3f400df8937c6c27aa0bf40a582153bd2798187a027bb09a38a9c9eaafcb5b948121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183c8ebeb011134172f5e1e6d74c769f5bd50620702c72a3d73ecd014523c505feedfd24ab7b14a650873f8c9f8566590000000000000000000000000000000016c5f4c83143f67aa6f4a4110cf767f8e61dc40abf654dea54a54ffc3a6fa40227a5b796eb7a16f9f2d965c0cb1981cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de3f7837bbba918ce0326a773e2904f08a9403679562f46b18bec25786baa32f274f61a7cb2a632183db698e3f416c0000000000000000000000000000000000d84f5a218a5aba7dfe2b44d9364fc4d8c68bfb28d619e159a6dd1f0811fb3e1aa258281cfd3a83dc474ef0a45e06b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001700f9453e0b7fcee68bb4d5dbe5a14b990bfb4cbb16ecd2fbabfd61eb6c301adc08a1543b08cd0d650b55202f2f552d00000000000000000000000000000000119c952aadd2be608400e60d49519ad0644ee4b5ed82a27075bc79c9e8a72081e7886160ff58c427906ac87341d22a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003c0eb1396eb5d57e0fbbedaecadfc791b002f2ccfed2fcde2081d132e1ebdef082f41b243dd0aeb03daa8012c743300000000000000000000000000000000018ddd528ac7a9c32a9bda8bdc93ab3f7700946859d5e94533694c09b63b2821d2fbc560ef187b210b1ee5a55ba72a27d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d440494b0af2bed95ee0833dfea0a624b97ddb2bf3dea395dea1fc688b76d8f2ec54bc0421c6baff4ab47eeb3decc000000000000000000000000000000001346400505d27a7e01cafbcc4a9ba5351589da2c107197a945a16d39d8e9a4cd09b5d287702fcf6c6a7860c330c175401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4dd90ff36976646bed1cfbaab176bff5ea25dcebc1a59be65db11d7763000520891a0bae74ab7a38b2463ef04d87bf000000000000000000000000000000001618cb0eceb117e2e46b5f49563bdb5cc9edcff0fc2b32dfbec1e68cbcde4d09d9493f6e6558447ec8cc5d3eea7b8c091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018afd1a009c293139778f073406b15977c77ef96ef377ecc5f7e757784a32cda917f14a305062bef0ca0356002970a6c0000000000000000000000000000000017d0905bc7e07943f0c7ab2ef00410ee6f08115ef06a7bd5d258890aec39ba1e98152b45d202c35b23a995aa626120351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ce87242957009efd36e79ab13e6261bcd1a68c678fa723a4dc3ec30ef37a56f44c0756d9f190802507a8f3e0fd5122000000000000000000000000000000000bbb06e79570bd3389479f3dd193f96778572b8c77c68f8843ff4bfac4baf66d26a3c50c4fea3b6bc2314af35eaabe4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eabff10f2a2c2e84201658083a53cf673f33747e7079353473c53e8844462aed9d0ed3172ac75af36b03c15626b29280000000000000000000000000000000015ccc21fba91bd99ab5a2c4963b1f39ae85c1dc5a5e912239d252af6b1275f2db78b4d81c11032443f4704942e57d2751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a38e5c29411815846d9289773a80275e47c735ddd28f7ac91d5b0eeb6e295f333e973ebb7c1c487083a41765e47fc6b000000000000000000000000000000000094f0c6cbde38e264256fa4976968436ad2eafb3ed70c9e0ad9e4852b2b02624efd33db61628c7ce78165971b4ef9c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e747178b058dfdcf5360c465fc05fa210e844809c28304a875fd14c067cf49197c93c3847425e0974b3b2c1c420c5000000000000000000000000000000000051eaa2b2773af3a4bb5bccffab1d00bf7108fd875d5c94d439967daad7aa235797c2ca6008000b70ce26633e21c72d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001062040cf5e1274682adfb86b8616d73546160a03346a9c9ccd27836177a4216dd6a5e4b057108335a65b7e80c559e61000000000000000000000000000000000f85729f0305855c575e9ff7b6efaecdfd58f1db35ae5e64cfa2b83873129cc17c9654bd6596d1aa174bd9efd4d490c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194c6118f8e69220d27c2317a2ba2db3d50eecd107f85acbc3bcf7ed334507920f6bd3761d70d316399db451cf7ec6d40000000000000000000000000000000012026ad1bfa0bbd73c8d766b70063b89f44846b4f12084c49f128f14e85098ad87605cb4185032f5a1704fdc566fd2d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091e62ada7e651d558a58da4fde22e49ee23fa0e8e90afc9577e86447a54d6ee0beb372fcac90e68da3bca36aff67a2200000000000000000000000000000000029109f236fff7808e09803558d443ecf03d5a637a22baffeaaa6a15d6b6b28bd50f192515829996cf9accce73e91b491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b41373279827efc80412515f56c1b69606153e61f7442af0ce9f32fa0a20a923f6b90348d1b8008cdce8f3f8c80bcb000000000000000000000000000000000b08f23c875f8b1360648ebc2669f0235f5d4a35d376a5c7c67a45b9eeed8b2c8db750c8f0064c01993d4bebc64242ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130d345705c5e950c89375710091da73bb04ba8401335d150b8c843ed88153edcb099c2a2f135aee844b057935a02d5b0000000000000000000000000000000005e9b1dcd6e1942627a76a68edcda212818d283756efd9e45541235ac4f3a5a4356db7006f8601f7c713400362d1c5531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008432db6c86aecbf88c13221b7d8d46a6d51b1ac3d629aaa57804f5333ed5a438ee1dd4c47238169c74c2ed008755a8b00000000000000000000000000000000168047ff280a9ea7e02e2832700121cd61db6983af941d46b47de6d90e0e1b2f69d3ee038b330ba4643afe00ffad40371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2684a6f30e95c1609fb48213baea58d2dc34756a6768bc5222350bbb7c8f2308da3c6589b32ff12677c7e665f537c30000000000000000000000000000000002f0b18c4eb976c147dc356ebeb1d81b88a5a56c0f352df993f024deb1a91f47a747491bb83fa98824ac26aee19eaca01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063ff43dac0dc78fa4b4ca5047c4a70d9a716d7f68903b9ff3377f70494c8db35b83d22c0e718352d411839e8d4885a800000000000000000000000000000000085d88eba08500813a5240a64fa0e638fb37242c4503701384d49d62aa87e9ad79a709deb2ac5853d241cfa1073caa5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012522ea0e13df61f1d9a4c628b5e17cb15fc850bcc9471b7056a4cf020882ecf4dd290bfe643ef20aef17c068aba6ea6000000000000000000000000000000001393e8c0742206a45e0f221cabb38a2d383e1e864cdb660e4676da56fbbfd38ade70490b0b41162f902dd1667b439a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8bdfcbaf7675e0fe270fafc17bf6440366c2f62e162267825c850b64d7af7272ec86b7e9e8d9df9a1aac642cea4769000000000000000000000000000000000a40c6e462aea08702386860b7193ff8377c2c674309b915bbb8ceea7632a0781f8120970234671525177730cf7cb2421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c02516a2fc738c460b4b5105950f30041d55e81c905404c89a4cbdc48f62207a46301cec257237bfbb9706834d2756000000000000000000000000000000000a13273590963e1048f2fc46dec82d2064ddee0a339a46ccf0db3a0c0fb246db8a0047212c2adf10cde5b3ca07da8e261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c3aaee4080003971ebe98953c20158ed1cbf123a41449ac67da43358903add6bf51b54312928ed0e47389413d5a1a600000000000000000000000000000000026a85acb562697c7041e3cf96a269cf54848719b07f919d2e1e602f443ad76255eeeb7e7314640d36c85280dec22d401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018503e0071d3c8dfd7e25f74a8b248b9d4611c9bba17730d94c0637e40486ad8acc75858edbd26ecfe034059bf43a020000000000000000000000000000000003aa2b335cdeaa14fa83733434afa028460f7ccf1c7e84c8827ae1b763073478395450e39d9847a8f6b2c5b13f85366f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078604a999bcbfe5f60fccd2afc5e2b60b4275fe90e385a230b54e28a4ca5453f4ef8af1240d627be0be74235cd833d90000000000000000000000000000000003a9ac7682d3befeeadf99fb4cb75a5b4e6e709ac22d94cc09452bfab631087728c13db99aafaf61feef38b9d06bcdf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b947081e4ab6278b5094f71530d0a04d094a9edd24fd35586e457b39b11acfa944eab65526cdb282eb9500400e2c1460000000000000000000000000000000014be062ea2dc13b173ab950b0c943df48df7ccd21390c6b0098d80092d4bc165e5b11352c0807d556b6d0970d315333d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104e4e155f24e25ee1fa6014a7d967597dea825d1d37b6a048eba64b498110f0f93a0e9e45a961b990643568e02cea30000000000000000000000000000000000a0d2a8e7ca79c0c1d8ec7d35dfd19f66fefac148dfc303d0d053fbff786ab33629e735bee042884d45cadcabcab2e141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178d98bac763b8409d9743d14f5f8350a00079177f83b484aaf6dfbe8121c8322878ed323e02e4dfebd2c75d682f80ae00000000000000000000000000000000058236bef349391bc836504eee4069b1fc5e5c5ecab99c6f797a1c1cbd41cd44768d392324b8c0d1697862de7379e9741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7177aed94cd16dd91c490b20dd6b52d6ac5b846dd586f3d528a40e890c185f808c3c9ffc3d574a96be5ca2e28a15b4000000000000000000000000000000000cc48a9a1bba2d7109c8542b93f66aa7d4640c6d129c0a2fe7a5de4a08a637e231c6ecb7c624e6c4f430600c203d3df71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091bdd84fbcc36a5a2ebb1ec02469480367230791edd6655440266e16ac69e0094582e6f26541726b95fae04d77c1bce0000000000000000000000000000000014952e5582d9e639ad106133d8c3914980ef2cf109977fb5eaf9e0d0e539db877320298cce5002419161767fabc678ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000312dc4905d50fe3e0bdc92b61a32b38b8a7c88bddba57532c2a3d34efad3502c174724983d8486f1a2b4cc488eb13e3000000000000000000000000000000000e336a02518a109524cfadd8bebf3a1bf35e468e6f94ecb575c4c105d5079a903566ec2188e70611867d68c6192da4141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131bbaa14d4d7fd46e6c69b4bc5e70ab98cc4eeb4aad80e522ec2a5bf568c8f78b20563155e180d833624c354da3235b000000000000000000000000000000000b65c30282a38ed95d3580f74f92c845496753aa8f093f79eb56a7fe2cdcd364f276bea369b9ff8a899e35ef3ad4e79f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030444fc22c9e353f9764bf331b168e55c03f564b2bf1f176500b78b47e65f16a2a095ed640c3a280bcd5cfad3e9bf4000000000000000000000000000000000031c3013f51cb5663b3b47c66f81c132fc95bff8d23f9442ac79f87bb638516455469bb9cc3dd7c9a97732279041a88a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165bf1fdc3fb5b1c9e1acd80a33eee7d9f15a0224337408b13571f6627374c6b523680c76b95403d10a9390b9aabd55e000000000000000000000000000000000d3ab62bf060348463cfdc94b6234a23b7b5934c1390d8aa5e075ab7f7a15b8671b47bd2b532f4b05b6e64caf9685b231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2550408fa1f7e5d6250151038aef9519177fd329fdb7436c25c04a833d859c868febc13da5824ec090a8e2e789950300000000000000000000000000000000141837a401c63a4778654f815ed54d85dfc61a73a61175b3ea4acb7ac0ba3ed8b506d08f302b91b5ce9a303ab795bb141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165779fefe916c61361d690ce281a37b8dfe7a0568014c56088881c135dac25c9f1323753410fe72a81f276596faa12a000000000000000000000000000000000d29af555f18f8717fcec1a1ae023bb0a8da6722fa94e0e54c6ce3ba424b2de0cf2bf08bc5bf594cb042fa43cc706c5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005be40542e14053360b3ac551e38fd1482f5bd5224ebe17cdf71a46836c5b684a82fdd606166b019633461ffda0f76260000000000000000000000000000000018b77b97a0aa768a53bc2853a897aaa2411bbf98a9169ac6734891dc87fd0458613cbe9d5156c7ec77c42f18689b9bcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067545b06140d2d3fbfe3aa706444af10e07a1efbc1d4f0569b37db00196ef73a26a0f126bee93b70bf15c40022f53530000000000000000000000000000000016cc9942d16a7ef6295c13200cd8a9afd97c945b09bdb54c2eab05c6311d92772d598d9d246e1356a18a5da4aec25fab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011264c8415e3ec6b5bc743745f4ce84c6af6474d5b6616347b720e9b9fb89dcc782995c626c76ea8e061139ba8ab9a1a0000000000000000000000000000000005d7c7be4c2090cea6cf05063e31230158d96b2ff7b96d9831babd557285ac090abcfb213c3d52903b97874751bfdd6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005475aeb243b9b04de4a22d71e5711308f552408e6b6f1c76730e6b81fef3f0ff3bf79778dec8116b304c864a32f6b26000000000000000000000000000000000e3c31a159e8449a9a100760ecead5ca79af78ae151d95e12be5979e9d10c38bb785430765e7bcf38b702a61e5bc8a181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b924090f2389f6b3f089dbdc3d98c361fe2d425274257addb8d448015fc6b3e6088ec96c1c40b6d4a610b2495f3e810000000000000000000000000000000007ad7d0a06c2be69f7032291f0895b93b22623d996d1ea1f976415f35d9a70a0c458562c59ec5fd13ae9fef18ee9d5321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa32bceb655b5c832a33a0405762a13491aa71f57b1d7b2a920b8abb51870b34b2e6161f51f90ff9b4029216e19397d0000000000000000000000000000000018c3ede1d4ab1e7e65bf7b15b3e4c18ac4187920249fcf5057232df37ba2e40b5a8cf0169f1ab6b508b1a0834a468b081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015af2cb45b9a9cbee29c09b3aa2207557e2a7569f77e6ea7bd38431f5d8a591e3920a654292cb406aaa888d7ace525f0000000000000000000000000000000001985f3d8df5b0d98e34b711abe7195e54dc5e98578a1a178a9c79512577f343eedcf85daa98fc24d93f1c9d5a908dd091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ada11d3798505a5a613a17884baa67b71ce1235fc0649e1b5a13b5b55fc4df7b95303b6aea51a7b346157a44076adb000000000000000000000000000000000d31a38cbc46efc66f80cb46c872ff7e1f1a6b7858fc24bbfc676a1020a22f7ca65a093278ff89040c82c71e35f598e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119b9e58a4444e4e9e81ac8a69d9ad96fc6837135ea845daedd3629945b01ca82939ba1fb0c300fac47ffdbbc65a770f0000000000000000000000000000000008394b6a8eb77d7d1936312d7d09a77d736b40269b8ca7611c31a7547d0f17d7b11a8b891e6cca952ea41f4ccd77bb0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016686829189e32380c1887b4d93e04f1f57d257db3b79e36d9293a1401a3005b9d5cbd07d0fd4aaa6e7a0c2090ffb4ca000000000000000000000000000000000dd781e58a33a7ae65cf9b9462b222f289c9a48845fdbb9624c122d7fbc7f096c7f1f9a1511adf1379e126cc29650ddb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d42759f4b3eef0a64c6bf891a6f33bd9eea5263e69a86721b5fb2e6f0dc9ea05fe9b5f984005836a2cd6c3be18656f40000000000000000000000000000000014870d36acae6ca33f8a519fa37d81895c7eebf0d203c41bc221c967ada57cc1bf8180ed9cd177012667ca4a0eacea551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142f74f20258e07e91f890f4db876d5be7057772a9262c5e67a3f378d26cedb21493a442aed3d05f05427812842ed880000000000000000000000000000000000adb2c79b6951f1155cdbd12dbcd548154ac5fe369205334bf6dc366b753440f0555adec4815605b1b516ee79466b3191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177a0f3b57e86909aa4ddc39d9780acf35f8e085bb0ea8d2b5599ca44904a737d03d316f4e1456d277aa79ff2e95a102000000000000000000000000000000000fdb19590aceb7406b9960b69dcfdf8f6bf1dc942aeecef601e375e5e00bd95ca283fec78ad7f31327de97301613cb431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035c14036ff867bc40d1e06697e64c6d1e2f712ca7c9a012ffc4ec8116ad66fb40d94ba463d6f8664160cd88208710460000000000000000000000000000000016ef0067524d0277349302fec0c12fedcd878d13d0fff211bc65bfa72ff979a6652f7aad552b308fcd4122c278cacdee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117cced5032c03ccad304054cf1dab7fbaf3139a4c8c918aeb4bedb8876be1c0a293775367f993308343cf3a4777fb4f000000000000000000000000000000000331daa33caedc1cdcdb38f47cae790a85914cf854a0fbfbb92ad03cbfe428b311dbf86d0a24fd97af29202d6b73d8dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010297af9e5a061f89190a3bd7af999af98f846c8e1ea04903a31a2c9b51c4f3feb190e169b2afc4a4acf4286e8d43bb20000000000000000000000000000000006a03be46b0534b4bf4cb2c0aa6dec3a12e5405750c8489f684cca0e03878af2e0eba7257ac0bd6c4af53aad6b1761df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120d7034a270eda2921eff3405281e42f76efc013f4d855fb232d5d6f3f9a1e291d38a39e07fe766f6c0e942a6ee6aed0000000000000000000000000000000000f652700229831a0ff6511f83726de98782be1c6c2223eccbc9f2bb25161e0c80010c163610a81cea686cf56c9976721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000785864b1a74a782d2854dc50d7f0b6d3cecc344dca0be1238c0526ad4e6c7f56b00cefcb3bf5f46da5ca0620bd069d40000000000000000000000000000000014ecb7fed008ede18d2aaafe3a5ef90453d1fa18e26c32a23ae53e357f461c63d8fcf20e281f7477fa0d475e51bb5cac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3d906645bb06b3e7875ec0110c630a355d0423cbf613b8c9ae435fa10642383e502f05206208a26145d7d9ce3ff1fb0000000000000000000000000000000012f88c7b2a1351a2cec61bf5fa824a2568845f969e22d8b0ea4651e7a10c306160636d7b89fb2d4865e761108b96f5d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e61e2a7539aa200c26252d3cae80b49d6d694c7f2ad7da45cd3a17653b73df295d85ee924680e0f3f237e1247445f4000000000000000000000000000000001704f6ee513f7cc07dc2dedc50cd5cc8df5b7490a132c6a5be2f50a972cf985f06cfe6dae1ecae46baa3997b92d7369d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9809bc703e6637438eb5ff2910ae3aaccc637c73cb2986bb076b9451c1e59e8f585c207cbf3fe89917e9bf104c3dc800000000000000000000000000000000056c847cbcc3d2826e3190d5ff03b7e2fd74c862aa38c23063756ab37b12c855d49816f1d2eb8774e60a5ab806a41a481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8e3a89454f4407455144da1d3269e8f0c2d40a0301956741b5ae1eb66811dd0cb9e8a80c47fc8e6c51b77f6509a2af0000000000000000000000000000000012127381d513a5e1fef86a6811c91785fae288337af3fdb247af5f4e7abfe19c8a1352390d490587c9f484b2be0995441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031084bbd4eddf5fad8cba15675c53c54e82be30438fec449df904efaf4fd8215e07be98c80bfbb483be8511b3858c9b00000000000000000000000000000000009a9a023a4158adf85f2c7853026d693cfbcf96996da530f90ab890b0225770ced035057cee431ce9f7bd2846b259601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0b08b21b24fdd8b9daa4b0f7dce27c78fb5e6dec6e2aabcf434b7e3943fd51d5574c6e9243c83bbeacc49b61fa54ae00000000000000000000000000000000153b7d3ce0e8b42521d00a5459db91eda13bab60f878eca9a28c5f668b15565f52e897c506a5f238591dec9fa99839d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128d189c8e3d41cabbc68fcf83bf58f6665ad836719d52d21e7499e7b121c3202c5236ea2a87091ee7e85b1f14a680b900000000000000000000000000000000125543ca2fc4a954f6be6dca42ef87aa96f1a07793bdc1404369945c6dba1a5b163e01d8638e14b913542060cb5369a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001790e335b2283dc7f9390347fa45f97da6c790d1f7024a39def5d709925c2ffe67bec7568ea5b850bc72cc091ad2956a00000000000000000000000000000000136e7bd1b776cb436994079c0cd4e70ab5b01b78282b423762116f19b16b0e3cce2551f1e78703b5412c48d156f1dfab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156b21a9811e880b73aab79b491ca78fdf34a6b8cf11729caf9925e164fa880e582f563aebdf7511924f545e8e2be4f700000000000000000000000000000000157a8af9960d525e718bf4cbf815f760db51bcf9256060718d5b6664cc436e1d5c2f640903696d8b5556a6bb8da4f7d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4e274d226fe6511adb8ff4019ec904adc75fe70c4d54863f30188a7fa1ee7990b22bd39a8d6e608859d7e68f173d8f0000000000000000000000000000000007126497247e941d46d9634abfa9e211b390867a8577b28a1e475f4977d5fc5aef73be339186f65654c06baac1e895df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c3a0f8b2dc7ee0a045b4fd6b5bf58f89166417211221a064555bf94b5cc95c41614e3671e3c0415d3eef6eb5a4fd3000000000000000000000000000000000081586cabde74252e5a0d6b057e28d4a2915c8106fe31a38c96643573de8429865123b627246916d0b3bce5b44eb6b241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d09404447121503c1270ba6a8e9563ab0f4b4edde0b6792269985e357523a5932b584ce2b38b388fa8dfe9de6dc6e8b000000000000000000000000000000000d469afa64d6b74214eb6af0a35fc73954e8127129dee1bd8a1c5072db1165a26f8a50f91e0216e0e0292edba49ac59f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d59a79ff88bae650cd40ad984f8048ae1b1488dfbb8ddbfe1966c9690ace1369f3ccef09b14de5f3825f12758cab98b0000000000000000000000000000000012d336b5f0fcbc3eb7bfae5ebd5d69fce58e335ae26ec81c99764dba4262fdfa7b53e1d5d55996deaa1618d240497d6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000140021d531ce1194b801b2e92e9ec096f74769062643120eb65d031cb38b13b28b5f55c73ab794e75f4cac61e84dc54000000000000000000000000000000000ad74fa287d5af2c2467dd101ca5b0b69e09988682f424e6e089e1ff65c68ba651da7a7291f180192e6bfe453e12c9d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e9d72847c0ce6c6a9d70eca36048004dbe0ab579d37431cba92f3a53b4e2c830aabc3ae431839721881f140f40a81500000000000000000000000000000000078413deae4ffaa019fc1be05a9a104d5a7c1384f6d64b59bac69abc22e5f7641644a40e834a4b9644000dcd50f696cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e80723b788640da8190c5540e3ab68e107e37791be78d4b0fd79cf41b523de8c0094337c09f02a0b9e46a628d45b300000000000000000000000000000000013104f5470f6de2b0a6fcd1155a89448337a06f00497c3e2f9a2747e976ef7f5deebddfd03191ace9e5c728aa498a9501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013231f3e1a15cb8897eefd942ce289c23f8a1aecf5361e7317b0758d673c9adab6dc7b1751ba455a8be1347698681ef000000000000000000000000000000000c9d9e3a2f8b93e677e12e13750672ece721e2f359c20d161b3703655180113e73d9092882d06d31c1a1b5d1d6a81f951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006783c20da9158a57065c6e050b8fcd9b6995e73cf4800ce1ec811b8812ec5b7296b5e2f728dc239454e0aea8e9993e50000000000000000000000000000000010e8312d7fdd9119e955e68c59961c3b932a94db432b78922898473cc5a26b914260e000856072f777e49a5247839c1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005efccfa80f98d4504f8c72a18eaf33aca8df5117c5513cf62a23f29fd6071842f2a07cc1b17c86504410e34b8d9109d000000000000000000000000000000000080be0dc25c315824bf4bf22243735f2ac0579699a43bbd7aaf6e558ca889ea99278abf26d360f633ea1ea2c03f090b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000553a939826e4af9d5aae5158c66b3566d24adc76ff27333c1d9937d599211320df9035b83df6c5073d47669611ca4140000000000000000000000000000000019d57b703c532d26a6e8631017cfd183063dc77ec67cee1f26a13025ab23926ad0c913acf5932af05a42f667eeae53ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000965c90b66d7ee3c9fac25501d7e208c2c9a98c95daeda52c65e4b3b0ee832a4a807a88118e0f773b7fffa663679d3960000000000000000000000000000000007c9a4ae934d1dd89dbf4e05bd9ec4172984ac3355c926024a240bd5e08d9e423b7a1eb7339a1db263cfaaa4d1cf09dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c5f40066629ec55cd7244c651ddd161efd549da7171b7cca06e6002e613bf723b0eec2727165d4abc33a3d9ef2f34000000000000000000000000000000000135b50049d03d04215ccdd904fb9b41f7849f451f7a049bf02920311f1887b5e0aa0f5517d295d9ff2386a263bd010091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005691cea3e9f22b69389d7da82a897b5521269f30cbf0721b38809739b513c0b3738aa5f137d588ec10f870e6dcdc55c0000000000000000000000000000000009f1ebad8c281ac9d403c81160a8830329d7859e159bd5389c925abd78e2a155d263f530d836855304674e47bc0907241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002eefacd7ef50eab87d65d99b6a977fc0e1a269a9a41e5d849bc129f4f6f200fa6153aca4ee3bd0c075e619a9dc302b10000000000000000000000000000000011e618ff8ee5efc5cddcc51615960fe38b898ef0fad0e62f51cf41deefb4ed0212f4f194cd5f4fd1640871b1e327071a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e98f75b39919e90e740178101df956ce1967ff86f7f6e4a1d4c22ce289bc096327e5840a02328ecb1f886f09bb8bb0e000000000000000000000000000000000aa01cfa40683b45a5676e986803b98805aeb8e35a10da72fd6a6687a54b37ac1987cd24865db979ee8175fb59d7bee71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037496e21899a743491622e4b70ec76d12248dd1956ce339e130d3ae1e60e773fb87b45ec139e8fc31a9da4c91de94d2000000000000000000000000000000000a11b261a77edd34096736f9ec19f77df3953a1e8224f47468affcbbbfa9e32463b12dfaf5d02171f2fd09306d694ed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000871d54bfabc3a68a7dacdd1078443ea1250051f97f2b6ecccae51e6b9c21ff9e432f891c82ef18b7e4185ed77c4a6ab000000000000000000000000000000001389f53beff07ff56230755f8d69a95499ee496f14bc098c092e57b279f9654e418d3b9064c5ba0b23043a8bc01691441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c5e72d55ea16eeadf77a9c8ef3bf326c49824068a17971fc721de8e461a1b2d5515eadc3d82873607988cfd6292136000000000000000000000000000000000c59e84aacf343a067c606a318f7ce1d89cc6039e7d3ebc4dcff57d6e385e45cb1311261287af430c7bb39fe1475d3fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d38637200ba9061ed86eca6642de7807baeebd01fc47c7a0bca687e54550832dfdcbb4fb036a3d8a338654730335c3200000000000000000000000000000000116a156ef8c67349b1654e8a4ca8f07165c220069d2be24a99c936e2f2e1b8580eed61965f76220b6a4ba2de9c2d1f4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a8a5ff2a4138da85f557a260c20d1783b9dc9df5d047e8c03e01f9541a7e8922f20e94fb9e057c930c80d8c5a4ae700000000000000000000000000000000017f5f3492f2d8f76df0e7894689f1d04e29d1326f937040691587cd3c4a879c17c89ff1de6d6598d4a064b1a5e7fab551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008241e53fb868b922bbe91c29327e55735c80aed846f5bb497f79e5eaa40ea3c0d96b2832c27a6a67e3e31b9953b7bb60000000000000000000000000000000005a5aff72ae801a006b4deafc7b7c3563aa761a82c4510e63e00c3a7f3826fbae62349b040594b34f1871487b9dc02ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018acacf8a679dd25e18112e2276d45a76563f8f639a175652d755970f330f131260b0664b4e93b858b1ae415d8e7db98000000000000000000000000000000000275b055bf52e4fd1d48496f631765c3ca8be9b3c304bf579c610e2ae2da0c36bb512053eece513337d7031faa54e5cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001710359d31a61efb50f0b8776e3b961cc814e9a5388efdc4d9059a5daa11114effb2691d07aefd4e63ae65f4695173bc000000000000000000000000000000001892a5512f20016b3c755c01649165ec51a9d81d531a77402168954dac97db63bb125d64df28090cb2efd7a27473a5e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a2366558b7801a81b266c98b6b87b80dea8a0a3d342a235dfcc834a19fef5bc68ec5756f16fbebaafbc20fe4c688ad000000000000000000000000000000001886106d5f07003e8dadb94c192d04aab73ec195d417a3ab43d4e40de1598713626c810af15291aed05c149793ca16621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ade2d487c0c9e4b07a11758949c757b0e5204591deb64d68380de87ca23aa47536cc9353bc40ed44a9bfe2f1f8c8d6c0000000000000000000000000000000002e437138d8d0a24dcbf03e83d11fc8182fbdc6a156811c4d5e8bbaae4360f0a6c66d97cb446c3147bd764cbf3b2fd341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a20d28b9e2591590643e4af33ff5a8fb2398b06b6d2e399d8e9a1b33d01e774e58cb376645d488d3e0b5f2e4b14e284000000000000000000000000000000000b2a576c1b862d7c72f7843fd5baa0f91ceabf0f37f956916577da5af4b791dc63bf0f540121b24ca03e1284a727e8ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000063ba4963b8b4ff3e5433c1cdb7f808e2355d583083673ff57cfe69a01464f69a71f15f20ca91e0806fc20ad598b4290000000000000000000000000000000012b54ce9cd92bd323242cde713b1af174454ca050e53c3c0de7601d9b2bed9561997090ae8c7248df715afa8bf5d4c781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec68b7520fb8a8f40f1d0a7f6c07c61c26384f9be89f076375e8b3b04e7260a6cffdfccff13b3580b9073af55976d580000000000000000000000000000000012ee742d37da2e1245b48da1a9a88863c1567deb7cc5b70c4792babb6d0d008366710285b1f8e52b6ab051e4b08368b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097bc511f5e59b189cfb0d67db04c10a083d329ad5c2a5a30c967a633ed4234ad25060ab5dbd658d81500a5164f1ae5f00000000000000000000000000000000129316409f017c8f0dae8105131630022495b240466181d623aa97e2cbdc8494da109c8da8def3deb4c5540728dcf7421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003799118586c551a0c6e00b2d92d9b860b69a02366d843b6c636afe3bdf589b2dadca20646de3711075e80e46b881ccf000000000000000000000000000000000bbc5c8268adea4af4ff5dbc73d5653a0748568e8faf4b48ddaf2bce55ed421fd433b6beb2f2841e0fd33ce97bfe4cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f030d731cf794b3924a287cb9718f3ea9fb7702aa0b2cea6e1fbf143efb68c8b1ce144a595e542c6cf9434fcf5a806b0000000000000000000000000000000003b744bbc210a41a25ea33fb704646d4f1260634667ecba3a0994f9ba9622973e304849a4ee08b6f3fc3988b68b335831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b48d835c83c64efe538847ee6a8ece0df7ea033cc12ac22eae517225db2fc16211a9a1b91e5eb89a11d149ae1a00580000000000000000000000000000000018e2131acbb6ddef2a05e51c2f3c65e56bcce1579c7d745b1d6a9ed5d68498982de9a911f76e42ec12f0e1749e1411ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ec072b45f593e294a4798ec52e6b5e0d225cef122b4d80ca5a9b953f123c9e6037eee9ee69cce336e89d6933a4b24f00000000000000000000000000000000166cf2de8807d46a063e7fa21141039a5d2ce8a8593b98797251f997c5e984a78d6c87194c040d8dec23729c01865df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fec7579e550d261d3b4be761a3696edf45daf70debcb0d19cfea6f85f54e6da8afb5027af634d5ab809876ac4bd1e80000000000000000000000000000000009b7fdee5e162620699ed6892f0e2c472385418fbfeeed4ed24a5d590f62d334f44939a7a61368e88d810c990c6bcc981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001890fc4f1ded9c6082f83d68bd79e12610ac05212942a4cf14827e6f366bfd52067ccd7e00425341eca0296e96305ff30000000000000000000000000000000006b519d626323b9e2828d438acc0c0a51e451694719539bed5b2d1297e4592535073480ee0bae7cf594e430208484c231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001562186d9227bee2748a4387e8fe395cf429e399c45a89412791ee4d3aa840fa166731c4191b86dab5b79cfa669e9cff000000000000000000000000000000000f643cd18384070f442e134b2aefc5f8d29c4c3f8b677ada25dccaabcf8eea58ee012aef5341f0d4023461dc33e3cc131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ad86a50a3c13d0c87ce5ec8747f9b3e286c8097df229e4ab6f56e1ea34a11da78d3f54c3e308e439490fa083682ed00000000000000000000000000000000001edfcabd8785201013cbcb9ed9abf9fe2f3fcd0ac3c890a9f2174a8dfee16a7db6b17a94803a31a806d5b8e8291427f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114e0e0e85f47700059bccdeffea30dd3f9ac0dcf73e63850dff71ca101a8ceee8893b405fe381782c83322350b070e1000000000000000000000000000000000873fbaf0478915a5bed38cc1ef0977b78a3c269ea7959752cc436a291eec7332716f15ba24d415c3b230b7c489cb5401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d25987d38eead40474303d121b659013a1eec84c5b653ba1725e6aa73394b39625ec687a730a0e0328388cf3b79eaa0000000000000000000000000000000002c46e8944c6262db393a81c27c3d970188d132c8d6ba38a6a5e1679b8cbad3d6282afe27eddca8d007914d651230b341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005496f1aeb84f693abe7282d3da1566cd066c33b77d662aeda7065dc75c2d3dab6a9be18efb700b37e8d315e53383b5d0000000000000000000000000000000002d664a80eec5a20f81aad8bb791f44f1ca6cb608a1fb24201dd029c4cf45f3e6ed3df7bdcc123b7037dfec3d93d4a0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0e6ff47b4b2bc6fc531a3ce06852fb0b1a2d43f6e816ae157b9de3a3e758fa9bfd219f063fd42f989fa17ab674beea000000000000000000000000000000000fc3e4b0e6748058b658b299737994aa0591c056c506b79f57e03b4749efa339565079ecc1ba2304b009a3d1a7330d171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89d70dce1e67bc0550db3715b4bd96dcb23b1971a5d7c28b1e67b0a176b60ed3b66b51bc3e495f36dfe8077d0b81950000000000000000000000000000000005144a6407b4566cdba7d5c0a8388a075fee80aeb2aeaead3f18f6229f4f15c0d40fadc139bf9c10e57583312126dbf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca0637f614823c1489d6a6800c8ba382032e7ce7619aeceb255c38d83e51e1b07c51c307449924f32c5f4b7137c1dfb000000000000000000000000000000000cf4667098146807e27b953182868656afb0b928eb8042ec1225a9c090604a0aa73e4ea6c918999c18c25112bd746b641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001326f14057519c003a057f2af6b62b5611ff40467e5b7f78f815773b07293425ac2f55135bb836b5872349fdf3e7f8af000000000000000000000000000000000e03225b11009eea69dfc5f53f4e91d1a6a9bed701193c92f30febe00094bcab3dff1cc277d06088bc2409a9c27545b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b48d9e9538a06728503f412cc9517b1c76680bacf85c4f4a3499b2501ef585a13d027763770c8ec3ae8716e5cb998f00000000000000000000000000000000187393ebc3f88a503d262f78e910fcf8406572c942016b223b35459cd6f1d6427ebecc717d05fead70d311727fd583ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f8dbbea33095f2447eb9371dcaf8716d2be70ea7ddc9f9bc92719e561f8d3d938a8463134cc751607ce68fa4401a2c00000000000000000000000000000000093e67f737dfe24634a7c423edb5aa167095c99a55c061d2cff6b8e8d7896725aba38f8ef71e878bca06cd249913d9e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000822c8d44a86113ba2fb36b8064596e4d5816bc340aa26fe414ecc92265f5ee468b4a62aa565cd4c94d4007eef7a920000000000000000000000000000000000154483f0a4a2cdce89b62893d26ab5fc2ce1c26a24382a78693a56f9a2024d24d1d4d41ad79e9fb69793bd8f9892ed1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed31c0fcf97549a278dfe6e8cf7b00a004f1a75eda46a5cf474faf031c27ddb57fb6299f3c2cff486069c580d45008c000000000000000000000000000000000ee36011b11236e4f7df627c737271cec1d624df0727e94517066298507a28bb7a5a8f8e56138cac8ae2b57a21aed3631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4d9a1ec9a5ae3c60efe24e4210444e44d0720e9d39bf47c2ead437a9b533f7432c65308bfa48a74f0faa205e33a05f0000000000000000000000000000000009beda6d3be4b5755b3db0f931a735b60590b888cbdd69755995cd70ac5967dcf976e79192de88fda15394948279dced1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000737bccbd79e54f428cc33e9302e8ee2911dfd23793329017e00e4b9cc303673b67c82f22150b009ddb660fac8372bd900000000000000000000000000000000133e556c646fed5c7c63e07fb0badedfdf988aed7e32cc59a9a5e5de85ac0a82f1dc6bb94f4b8ebfa476fe06084a54ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189a4ef3635ca9b40203257450d4e3050de4f9bfdf9f9b859c936e140f27ca512afc052eabed06b179536689aba8b1700000000000000000000000000000000006fe52018815fcc71c6d236e912f6205daf613002312a086fdfe602c97f450cde5b105cb7190f305c2f316c6bdb254481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113106d1b744936b2c1c5419ecf403a1937d77f3e92b6a72d70c04a62e1e7b0283cfd736799e6e93bfbd485009cc7e19000000000000000000000000000000000c30ad2eb9bb1ce949e56982eede0c5013d668d0e32d36a261a476cf03ed6c2aa5b5168f5574bbd7c52b5749aa31c4941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7411ed9769e37b6f7e6c2c767f9d1fb80d9bef6eb50f9ade585b3bffd926df755cb32e33f26b1eb9812654ac1e82ad000000000000000000000000000000000c58b3d5434b6dba29a329b6cf2b6355063d6d853b13a0156ce75e376841dcc160cfd44da4535b254ae8eeecaba329c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086945700398cee1a149c68f29783b9a45781b2f972723639ddcb3fd85537931e3996a168a0bc4aec074b0665736eac1000000000000000000000000000000000639db2981af84e101e11919568cf017cacf5004a8e49f864265a045cc05e4023725c83cb1227da791506051565d56221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f8ef889b32607b7a0a5fb2e950129cf44f757afba8924996f5a5421f850a2315f4948f6b5bf1fbc9b0675af2b076a30000000000000000000000000000000012a6a2271f57735b78839b58545a90b1388a2e84d37c29538044ed9e1f93e012aa8b6f940ee2231a0534441f9e7488601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091d1305dfd5e573cec3e35850ce79b29dfb8c296584cfd794436fef1d9d02c67bf444590895903350ef737a4b28e035000000000000000000000000000000001408da122aa028cc5708d326633a31d2c5b1e0150fda07c90ddf441eaaf75c39b5fdf8d52493f7c3d495d18f9fdf73df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c00881f2f0c37d7d5b9d97bc29035d2c9ae7252f81c8f1e8f571c4f768234a1558a375682591a5e2cda484db2831e7c000000000000000000000000000000001165c8536171d0ed7658bb6f21fa17a5c75d6d1bd934f6a112a47091ca1df7712bab41e83f8dd6397fd31080692e99f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000881f7c17358d61058fe7b4a7337f27562ed490d0f3f89aab44c55cc61435e7c2880432717c6fe7fe913da02cbfd6a7800000000000000000000000000000000093eb98e9299a3195908e0a0fd0e2794e0bc11bfc94d7ad95624b9c9a7fa31b1846bf955f60dd7d1ea2ee41d63b534ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ad014d7709684ffc29e93f3024963a046c227ae36b348698be8ae6333dea5dd212e564fc7be75225f28f7e3020949f0000000000000000000000000000000007831910f16875f741fb3ecce0cb73834fb1ba8468483a0cd862605161210ee7d1f2e4fbd3d55e07c27f63a6c357f6bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b42b6f353e108aa38c26cb6387f7010c6c1eca17b03d2595fc900c4fc083905b7aaa8481027bd97edc016a850d703b00000000000000000000000000000000128d963119740811beeb3984a8f37d2c8a1dcdaff4e3367366e4318974b9e04e4a47cf13ad709e4eb31f19b2affecdd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ba16c76a01932a245ac21bfbcf7947183ec9edf25101bf2f7a6034ee26ddc95a0e5e398ddd3c9be2977571027b74a200000000000000000000000000000000092917851d092c5dbf050015ed451b93cc4f45fc7d5dad2fb27062b54d87422db24ee55e8a91c7e2653a1db823fc64531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165ae81d0c813d9f980aa37ba48a546513fabe1c9e0a38ba7160792e0c8a2588e0ceec56cb2722bc7a8d38d934e41d410000000000000000000000000000000013cbc86094719af6353cb42d51cbb12e5db4b74015acd5dbdc2fdf9f136bef91de539fc45412f1f50b7d16228ca47de91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000514243edb723a05d62658224021db9747d0f41c5cff6234a5ccd6b8bdb7747edecc6375a38e71038afa210bebd43d110000000000000000000000000000000018d0679c806b10e1427662ae2c1a05208ead185b9c351a243130b71a97805134b7cadb2d38e68c4c6aca30558d02a3c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023b8f03b05600cbc38d574e59f89be8cb2b442be4780d7695fbf9f5544fb67d941931a25ab5cf825775b2ca412538380000000000000000000000000000000000f508374d9e6f510f3cc842e351486ba04937d0a8223bd772aa9cb686b18890917b6051c9bffd46344645126a77e1db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007612670c7b184732b5e555b1955919f266840b2ce7940354cf4bf25677936905f4e3d341dde46cead1b0e9e48ffb7b90000000000000000000000000000000006f7bcb2a5147425619593db4ab9eb37ac2683980f5a61abd8fcc8d5135dc41d4efad0b8db09b049422b151747425dbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dbd1ba66474cf97951603d7c29ff65aec7cc91513d6b0deb2c1d21e3aa5eac68a3a4f7d1c04bc7343fb39227646439000000000000000000000000000000000a9306b6ba9c819448f6a216b4a0d7f7aadbddc9536dfbdf126e31fc15803b2071f9441773e4bca9068e43a51fd4e92d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b0bbfb0f66cca3fe522b7bd8cb13b6eaafdeb2d303d71d44376837005150bc38f8bb7acd24a71af894ca6b862168bc0000000000000000000000000000000019c3294f6b392356e209320916746169bfcb1a992696977ddd54485a5c5d69d099aa878b0ac3fb2c036a24149677b8081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b74bbb45abe85742ac9b59b490d90472ba2aef53da18489758fbd3bf9b692f2e9216189f4790856b60d3c439e4176a0000000000000000000000000000000005e7e0c7d7422cac5c7a2a4a2a7d2497c438bd41cf07e051ed947464528c3900e6c038f57d2ecc4f4b193a8a52bcb31a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069b0aceca4515b4179a5c500528ff0608843d03a8aeac9c694cafcd2af89c18249a55ee1ea3b9d17fa0c7ddbc4500580000000000000000000000000000000001985e44abef01215d87404499f69034cd0d4241534c2b4ba0ab9d85bd45813b204528bcfc0b1df3307c1a6f77ca43701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c38720522cd0eff260157a0ecaaacd6adbf8963b651a6bed9bd10a4f2bd67dc665cfcdecbb7ed7a28ac3b4a191f29d40000000000000000000000000000000014063ebcc0b1107c84ffe395b6204f4e14203061d018564d14978bde203b3daf709e72b144325035ca53a4747375daaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000912de492afc46f39bbea9b8521e76eaa0acd44713927722b9f1922461a3e2635fe77c6e4a945c3cd4889319b7210427000000000000000000000000000000000e356e23eca6d1a9e40e4a813f5cb0c5d8ee35c6c8b01d90a909aa9b07c486db3b4929bbbf0c37a20fcc899cbb4d8e0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d173b148a20902950cb15306838be3abffb036397ae9d638d7e2f6f9d15dd03d814cd328ae14bbebd51e8322348ad20000000000000000000000000000000002749a17d89aeb4eeef05b850a2b9079cfbbd02a9ab631ddc4ed6b448eb620f79b77e7376ab450c63883afbd90c57f6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ce42e1a1636f2d723e79a5fcb3fba5eb9d27dea103f301f27375feaf3e858110a80cdca4291631a48b68222bf9812d0000000000000000000000000000000014495a155aed9851ccc87ead597a6f530c5f45f888ac9e87da5a613cfd0f300b2668e3f69ad796b1c419588c71161bc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001620fa048f8fa229fc9cf71d2ae900d9073a4ab057e14e2225fe617712827a63da030990e4dd251cde5696156bd66c8c000000000000000000000000000000000e7ffb778f2f31d25f8b882bbfeb5b7b471b47295aaa2b5a6bd0bd1370479a5b4bba517da37f3e2c7e5d6e60e56cd74f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed32d715acbd6c502af3fd49f965bedc936bf238abb36644c9ae320434071049cea4b8993947c4dad5a5ab37c39f5fe000000000000000000000000000000000376041cc9c915f529e22c07a619abfeb540345057338130f358c5eff4d00183873e5ee820801410c18ab1bc7cb86fa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a6ac2f81a2fdb8382915ab0b72d01a51c14b5a3f6d4baf56ae1885ab574d4533d4f6028052d224a9625a9916ebd8f1000000000000000000000000000000000a0da16cef13799b7b7470a804a1f877b611545936f2a84a9f2115dd255e10dac549721ae425d257e703f083c02647b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f3e4d957f871f3b03a3164cbf36cd62e4e550a56190794714fadd0507106271b43bb74a80927c4604de7a372c44801000000000000000000000000000000000290e1dfb5ac3a6f9fa7c3b5e83ea9fba12108a1c559dab1caeedb9ab15bf56c966b4f0bf7d27d6a6aaddc69ccbd9fc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbd55867ad63cfc4fcd38d2d98f59e5155724292154430146c407da6ffefcc48b922edc30b5759b12b426d45d8b766d0000000000000000000000000000000002d7bf93ca5ac9e708671baccdce4110e8754d94de1e69e32c8f45655e06b4c34be76fb5008ea408d7c41a808e6403ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001178cfdbffc0f910f39b81b8d7a4e371aa8745ae1ae74053d13aa90f94e82f56efee051fb7054c0bed1a78fd93df08910000000000000000000000000000000016a6f5cd4c859c5176c755991f88aaf8d603559419c621c2e25c75c24a478d074be283778d735129d1d60ff4e7146c1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001551be4464ef1aefe6fecce96de12199d777b8c1829f7f50241d1f88eca44ecb9c719b7aa93a2b4790721bd29d71291f0000000000000000000000000000000000d2c8c7088d19c834214ee8dd27e013f690a32c1b476eef98806ed56a2cb5d79c532b18ee3957ed753330768451b3cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef5376c93d82a2957723d1c0fddc8694a56ab0df0d9ca639616c03a80626a49ddba023226327222cb6e310f37718d8d00000000000000000000000000000000148d96e2d367eed19b0a93e3ffaf92885076ab5908555b18b785ccc2ad725a2743ab546a4f4d4bef365500e2cf5f249b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c13ef8aa7fb353de6f965c5c637f055803453a062d8def3f77a48d09bcb4c72c2e28a7d3c439a9775a7cc7a57e8de000000000000000000000000000000000123bd915e5499074f5a05f283985333597558f8c0c5549a51015a9b31f4988802b91279c8794490c56699e3ebe4a67b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000056389ba2dcc052fb3981f6932c80c7a2482ae51a590fb0bd8550a4fd50815bc6495c2ad7d52957090d08d3c79c78de0000000000000000000000000000000002a95367f919b91939e236c5d11904e344bd4213aa5533c79c92ab51955a5e6bf7a76556f489c09b57d39dec3f8b5c4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d339263b3b1afc5edbab744ef1a0f981905621d0bf3db71284fce5e5672a7565f1af6c5f62599156e3cfde3b506957000000000000000000000000000000000dfc8243a7ad96b04f7ba3a2220803eceb989703769360495157d61fe744f2339ff9e3328e669aa1b0eb7f76ff8e26fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190544712535736edb6cc0b4949b5d0a040ebbb851dc26bcdf02e442497c066996d90e34bfebf3fd55826c5bb02df2840000000000000000000000000000000017c0b4ab5f48f2d0b26f5d49532154a2338d235e34811098ee59c1d663d03fd4f97b4b7c353f0f6d386ebadbbe14fbb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007eadcd08a64752fe88f38b50286d1a4b00d7474a3f00a9e646b48b03d850dd49709d4aeb0d0b314bfbd955def7864230000000000000000000000000000000001b78342d9747aa1349443842a9e7a05742b8a5aa3caa35ab38d4710e21f2db47573ed8c7a66a97e84ade9c6210825431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000901c6f7304ddb31a289e9825a572df60711b59b6095ca13cf912f8d2bd3c76956949723066e8f797f24d9959c1e961400000000000000000000000000000000023daa1adb601db783560b8711ba364e4af6348a41e0829629b9e7ff38d36c727740c7bb70bf3a8d3acb65be4a658ea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a4dc18958fd0252a6d7ef4562cc4a2fc724b86f971ce22f134c6d70fb175bd7a397be822bf72b2e47d1e63d880ca2c000000000000000000000000000000001820f614dea92dd500e8bf7a4dacfd6254231c53967dbb9be5ba306a0e06d5643219ebf20497ec4a073566d5b1237ed31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001184ebd10132286a157be5d6edaaacc780a355a2a5d23ffb3de2960d064f0150787131e1e54bc4a25c40ff10cb33af88000000000000000000000000000000000c8afaa3648f31568479e5366d5c9d08333ca7f58c7b6da08d5c66c4e24c6e3d569f0dd7115231b34225cac0212cbaf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167a43a6757e0ef11c981f52096a22834e70c2bc0fbf3cabcb60f2e73a0f623edff59992d9b6d4521c27787d77baeb820000000000000000000000000000000006de6b5c5b39b4d1e6d0b02ae5561d248cfcefc97b1e70422729c8b9f09a9b383a234dbb984e511efadebe8f6a0caa341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba5450e01fe52fdbe84abde2037fdd37da6ae24ea0b117de72845fa06c23caa7dde9c6996e0e935d2115ea19cfdac88000000000000000000000000000000000ac77830b0150483e9093918ab2f054496aa1e59cbd0c122674d14ea8861c385d85271cd30aa3143b756b44b2d2d0bca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040384bd2e85f83acdae5673a5aede3bcae41230d81f3377c0b6a5a357d4a053e890146459fcc55c055e1edbf3e80b88000000000000000000000000000000000595ffba244438208ded3b0667478a41bed268accbfda6cf04b6deda97f96204219131a8b75e46a9fdfa3c4855a280001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f89ae4b50700faca55387043804ced7c60e582f90de771cf8eeb252ed4e2eb56473c57555e59101d4d5b8e6190a468a00000000000000000000000000000000073c62e0851c6f836c08f5e5663bcc7acad0aac4f822fb65af12e15ca40b1ade50e5a782b392bdb7b0ba14aef04a1ace1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063397d2890e58ba3f027f418a3d9de26fcba11d61042a0135b394920bc45e60d28bc1d71984d6977e3f497e0a7415d100000000000000000000000000000000166cfa88133d62d4e93760c2b0355b223027592b71d58d286bfbc9b09452781ab8034d4e27faef27134911145550f26d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cece3f42d5d9b5192a6c2247c3c401e8d69eec654d7700bcc0dec3409fae81f3400d7be1c511c19ce739c14df5cec7c000000000000000000000000000000001070988ffa4e696fca398ecd816249af16ea7d9c4c8228ae3899166bf36b4cf7e6437fe5277adbb332d1711484c31fff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8963aeeb9b2dc735f707bafafbfd8448d143f8bba378b4c088f76e90781a1321cce4edc2d73b220383da93a6e258130000000000000000000000000000000007a00f81b0430873dfeb6a0350369d9bd74d0bfe32f8dbd5a23759a69d1f58d9ccbdc41275ec5b4ce7eef69b6f0c9b841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a22a6f85805d009a40059bf5b921dfc67cab1c455b0a68846e4836f4f61f48ee34bb7bdc4b6d8ae2bda494d9078efba00000000000000000000000000000000032e577c7f801d8e8316debfeb6b195af1e9e08871c10d2dadf9b3707af45e1fee9dafdaab4691f9bc99733c477792891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cfeb714c46489fb9c79258e550878385335ea7324e48f9ed749bac3a515d50ba10b09727cc9683d964bea71f431ca10000000000000000000000000000000012d824f815a59ed78a0446fb8cfb7e615b448f04360c2b5261d4b24474d5e48918e8ddd37bdb2ee5badc996354cdc12a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001590051121a084934fd381067b262aada5d688ef11b3f97ec10cb62b46276689ce5937f80d1967f49012ce460ec73e0000000000000000000000000000000001787d06c7c9891c33ac0555d5f94dc90841bfa2df0e51872508967403754ee9d8ef97f2329f44ddd805cfed6597a31fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076f60f8215319c32126977772c73b459b6fafb5990ea1c49a4e2eefff2286841f20d2c93c63375b4b6aeca7baca55860000000000000000000000000000000011225564e25ef8b98e777a53969888ba139d466a8c3dd4765c6051a0a6e8b3f33b91e08e58bcc5a10ec694768e5103641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e4b06e631dcfe3aedf1299c55927d9b0486611b690fdad15dd76afdb9a4f147a7673853703ffd66cf879750935917c00000000000000000000000000000000120cbb99ad9852c5db18c86b3701435c3cc8189510ad6c443d3562a85d1f794521f3685e1139dd58e82ad75dd95598491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138bc109ff2d31ccea8d556a56078062d0f7542e46cad7836867a73a46e973c3a45b57479cbbdf3d4fe61eace6076edc000000000000000000000000000000000e781d7918c80d927455bc30ada70389852423942acf73557b3128b8b6c384819192a5bba7cc3f6af95c5ec575c695f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015751eed718b395dcec1381a25ffe31c3db047b6fd85f92243ea4fd7e7795cde56998c0185d59e70f12081c9f3150e5b000000000000000000000000000000000784740fb59bc5074211c77d1cd104ff5267d2c955096fb8d46efdb62cdf5b0b10bee599656368cdac54162b9899e20b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047183098acbe57eed0f77996e222554393a6b4d05b40035985285f128147edc60b28f5fe43c42a4b602324a2bcf537e000000000000000000000000000000000dd79051e293357664fa484d061ba18b57fa1466754fd019ba624a2211746bf3e9e5f1d4250a313c524d3669dcd1635f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e1d6e24c1a368b8fe64243d9dd2a3c8bcfbafd84d0fa0afcee3cb7db4632f10ee324c9b3cc298d3b584666bccf5b63000000000000000000000000000000001162b287823cc1cf18561935b20def124e91310b43931a9a5f7354c2cc0c584dcbbcdbe616245fd28f6680a0a32a859f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018619b644da88b7fe3adf1902229fe374b0a78a82649500bf89f4a1f8e77d7049d076e9db19e5fddf25455fd861c0a240000000000000000000000000000000014260648fca46f0b21c523526e590f1e05925b69a6d0583e27e230893f80c0aba8d08aa4936ee616a7f5f607f752fcf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a68e5a4b5944cf8b57e441c0c0b42966084f2d7c580c58dcb1790b55ab76c8260ddcc21a9929de904b4a1883979db7000000000000000000000000000000000e9d95f1bc27128670ac591b3454197e0e65800ae1700464fc53a750d013402da050c5d85c148dc9b9b0e9ce7c76f93f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d15b66a81a58665b132b448a3dbfc40c450b0d30b318c920e40d757aa24933b8a1c2d2dbdc66e91feb08d292d717ee200000000000000000000000000000000025602cbc28f4d682fe33df506c6f1a7b07c02b26c543837a9c76d1b8ad4535d5292202d5fcc391dc88fc58cb0776ba31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142d49fd5387d746d9f97b8ac32638c5179956494c6043c6b269e82ff89764b4db9c0102db192429836f41a16c45e91e000000000000000000000000000000000ab4c731c155293b9380774ff5d83b95b294f3c9e078d0010eac0c96185dd3d25c4c4897117523976cd673df20be216e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a3b8933c08ff3d92593c9fec9430d6844910f1e04ef2c583c528fcb4afd9c6939411f20a621605eb6dfdf20d9426160000000000000000000000000000000014ffce1452814a7fc518ce9fe9ac16cfa43d7d4cac20e96da514cdf9bf4427b21cdc736efa2e1ed296e4fd28c4a4a7fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c85c900edf01ed86648b997785e02375118d9ddb5ad69f1dde7c3f4290707d36b17d94446fd423c1d5e7518ec61b130000000000000000000000000000000013ef4eefe9d16dd222e87e96047c2ebdd8e74d3a1e84c04252deb00c8abf1b6d73d7db6c8060ac976064a6d325ce17311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb495cf841bff7682a9df9f0df58a20f1737fce178968c39e8406fa7e758cc594be4f65adf1e6a466c17cfd53d118a400000000000000000000000000000000076dcbf885f54cd8464f5c6dc5c0cd454293c5d988c2b249b5d50c028ed86f4210df769bc9a4654fd258a04c3a0db97b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015c32741acb5a8c46f943e1b87e4bc76abad655b96ec4f4f39a6ea9741b7fc4b73bff8bddf6c45ef1e0f2ae8c3b2ec2000000000000000000000000000000000c3da142c2475c315bdd08452ca3a72f3642f60f76a6fb51ae28e0e6b2fd10b14cf365641be5a019c5e5b5bd80d39e6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4d8898762da5595849e6e245ec7eb391680eb3ad1f42ed4901aea988b3051f5be7d091491362fdb84d3980bca857e700000000000000000000000000000000034ebc46e7ab5a726ee467348fc2692232af80541b689656be2584a74c5698dc2b06e5e7c436fcbaf1a72d2ad0a9f8711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a4b21b49bbdf6a4ef12acd8da1dec1a02328ae127ff9faa98fef345f3fb97f4532b2ed887e6e0c2e946f051730d215000000000000000000000000000000000bf8a19b9d187b5bd720b6b5b23d0c675f99ec78065eb5fb1f825a45e1f66508ce1046f14af425a61796581cff3c1f591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001654f08932b433d62defe726eb40561dde98e4b127e50993ece5a26d9de2c9e5a1dbe6bbf2cab4ee47eff59242f690590000000000000000000000000000000015ed8ae18c9985f79e774cb6a9dd711c0386eee84d4ce22df4e6d8939ae32cceb3eb91549b0eab306b500a6829cbb1fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001545c5f3845940a58e39e9b94eefad0a1214d7e756c88c84af30e2661caecc36a2f755ff30ed1858d93d072c272d3eb6000000000000000000000000000000000a0779ee83cc3d847ec206b18a66b90bb9f6413896bf429ed0d8c28968a9b0a514283f09685e415420cf43bdbd4deb351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c9643244e71e4a47d5b2e16486cd664494db959f005c8ba913a12c37b1d3a7499bb9ad15c64ed9d54ad5c9dbae9eaf0000000000000000000000000000000015603459849726db1c69554882a42ddd80ebc3cfc673dcf2e165e319ff3eb4bc97443eac25d69a41eff492432b059a071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db49fb3f6f19b70178996fcdabecab437d6592983179fe586ba0cf806c7ca6407f49d4600344ff365516c4907bd3f640000000000000000000000000000000004a7044d7f59f42c7290bee2d2530b4caac4cb1b245329368f77488e3ccdbe1937f1effa3282bbfcc26d01bbb8fff7271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007886adb3c8e5a57e23d513b1f74221f2588e593b6002f5fd149c23931f48daca2093673ff8b2565559e2d8949db2d9d0000000000000000000000000000000003d1241cc955650721bc45517d4397a8f0ed97df4176151dcaee631c18a6db2cb96e126b563fd476f21d433f338bc0c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dba7bd1542eda4a6dbc9a949c57add893529bce1930ed07e278259aee91e9d3afbdd963d932b2090d9648ceba1ad3f00000000000000000000000000000000000ed3347ffb0db43885c946d46c496556e423e9c06bdd861e97ddd131e7a4a7af69498774805a52e5ca351fc26587ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4d36e627e86cdcf91a3872382a16860fb09ea1d13a7283ddc45cf71252cdad99e5e61644deb1200d45d29ef7868664000000000000000000000000000000000681e0eaf607a9e9b8e9360ac9b83a0f1aa496286e1f9023b0a9860027288775e5af2fd1bb2fc082cccf25b1ae174b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cced40381e9df0923d970b023c5b5f4c88dfff7ab2f8cfad283f6a2a171431ef6087cdc177a1e18c23b7d81074abd1000000000000000000000000000000000caa36b1b833457ed29dfbe30db55d97b0b9dc00ad7d0ef94fad9e8d3804d9218ffb29e613215d96a53ea881962805351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185ee6baf1a64785f231ed200a8a811e3a77e7e6f44a4ad2e51ec15800765b36da741ad3d3d8ff342137eb2db066181f000000000000000000000000000000000fd083a364face0b024aa2a865e687b2b38434b4d84294ebd8ed7be97465414346aa2dacc8820e8cfdd67e662c7cc6c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e188eee4c8507ed93925af2873660a6c3e0cb8e46227a73f51ff17f5cdbc57c30ba4cae734bba8aecc87f6d858019600000000000000000000000000000000198c77cf793ae6f5ffec95eeecf8541be8b2fc28df71db6e5e7152c5917dad8785159762e746a9fa6a928a4544c3ae401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058869b3aa4c251bf7a1c997f49dfd7a12541d619204eefb7cad59eec103eeadc28e5f7c5f67376e92b3172ea408a17b000000000000000000000000000000000595d941f23147d8d81f1bc163d70b8c9e1609c46efabe5f5b5fb6526befc6201ca66c4897ef523f268776abee349ed81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014adb7155bee4bfb38b34c3af7860ee2023cd3697c2fd739d4ecb145fe49552132be468e734abd45745f349a42eed12300000000000000000000000000000000078e1e05c38e6141da8a4ceace4bcf3cfad21813823b86b479ba547fa8120832bd2b909f459f78095a6ed6d31018a1041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193fcd1290109825b9d361e9d79ed99ad3d39015dc6997a4ea4df3ed6bd16f1b8c5d7dc022ac446366940c8a9d96dfad0000000000000000000000000000000004a10c4853a29b4029bca4199fcb3bafc300c209f2b32079905c888a31bbbe5a4795f0b69a492538b6a9ddbd54d41f051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001826b9626237a037ee0d2ce2894983d206b47c15051c8e8b2fa74bdd8915ee487413266ea74821b136d9cd238fa2328400000000000000000000000000000000044b173f839c3df14fc7ef922a93b593a1babc5bfbbf809244bf34af910381c91cc5013a578a953d093f69ebf5d527331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1f9cd54610b885e198509845189d219b0fb838e2fda9eaf541006a4de35941544e089b2e9b021ccbc8dc36e5674550000000000000000000000000000000004960bda6e6f7095451a859b11b5fe080394f8917d48bb5cbf6372bb3a1236f05647fca260e50faff0436b70e44a47131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001140662cb8b88b8a9b91850d93e4276a03ea19b9619748f4dce6a2a9a1468635f0edbfc9e8436362c53fc4fd0d370fd2000000000000000000000000000000001418f5e3b3117fd8b6c4f8e1e613063f31a88363600f421480a153f011df274b5b66f681e269bfee5709d2b65abd8f5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004da2910a8031b7926309284d4cce1a8b6aa0d077139e1a0309b05bd10bd4eab7e40f622fd33087fd3058ef437cab2f8000000000000000000000000000000000bd8c522f82ec7d451f7555e7262dafd434a56c1f38c3517405b30bc862d35c4f7fcd8af23d71c1b16748e6594e0d9e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e735230407c7dcbaa1685101045e346626833ba8edff0db6a25076d5db3ecfb766782fe2adc54c9c83c5b00adcd3890000000000000000000000000000000003ffce54b0d9b57af15f7cd148ecd3811b8b560c7f5076a386f8b0b221f38d5ca6d0c2272110bbaca079f44ec5ddec2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000baf0041f7b53a126fe390fdf3d264ceb9dfbcb2ffa51380c72824c3959fe2a0ee36728e146a65299fd7c561c6df622000000000000000000000000000000000131b8d7c31fd96a4c9c02cc8a5281bfee25279be5a4113c7a3c8311032cd7ff890aae4211f929f4559f578043132cd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd64ea2420ce31c253711b653f27336e4cafac3b46b391a406cdbf5425f3c128e294de46f382ff3bfe48dac3dbab6680000000000000000000000000000000005b1b1a2833ae879914061c8c6421983f15591398a174a42234c16c82843b9e01d350aed973ebc3a61dba6f0abedcb501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e18d6c6371b65cdb95ce6a3b963869925f170e17d9ed5e5e6e7d7c3e35cdc299006eff202241ce487d4dd24a7a4b690000000000000000000000000000000008199ef4c6618a71b5e1fa2210a5211780d9daa9da4129bd82a9ec69f544557bc0d26cf22fc0a0f221d475ae150c04271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f1aa1f08b08c9f1fb0b6bb502a18b8336e4f44f509676499e74c46ee38b05f8e1c9b13a24bd6c4cc333e1602acfd4d0000000000000000000000000000000002fdb55872944a45f7d39426bfd664946c6d84a2c9ebd504a1b2d644da194eb59764217c9e2d3fd7784cb638ab5f54211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f059b7f8a4fb2b8341f55b468c01b2df418cddb0f15aed42ff1b9147585ea53c3a4846dcd542d55faf485400b929a86000000000000000000000000000000000f4074cf3d5737798a2bb4e5011224e96f6434c3cacc5e212cd0d54114bf835f335e870df5dd088105dde5b6c99003b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001260766694ae2197793fcc56d61957b344a111d49fb81c0474f4f191f83a79065d64ccb00e35e03c7bb2117e49138501000000000000000000000000000000000ad60e623a7dbf8c94b7f2f4649272a6e39f2cf21dc09f2f21e5901a32c67a404460e1a011a5ec4183269aab4952c0e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141220c320d9bc0ebcc7db83b2d86316ffa7c37c48efad1e80815ddc73fc3a735511f829ef1c9e0df9fc21651a0817d600000000000000000000000000000000014ebfa44246aab61717a36e785f93bf6681eea4172aa1ef9af9138c2a97faf65f590f381da6f6cc1658f8c8200699951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c17b681d90055663899c2c0a6399acecb31f618488fdc4ae11e18c6eb8b4820a37019db29927a278f769fb104fa81c000000000000000000000000000000000c2244bf4d389f043acab3c7db58c4fbbe6061d5a305d4a8c4bfdaacd5ebec96cdd366dbf7fb45ff10476c4cbc5bdd711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ccb4c3d73da4e0331af41351735e04dfa7a0ca2df9d97e299576f4fc1a87446472903b82130212724356a0dcf872b6000000000000000000000000000000000eff7342bab5a18266f42ce93d3e11efd67d05363910da902a99de80252c35def80ce57f0613b976e0d3cfe29303f22c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a651edaef46e3d2515eb8d465479a2e574296cc9f9f4ad586262d4b31a48139ab4fb86c592cba97fab08a954f1d9aa000000000000000000000000000000001015f3b8b0e1a9c4101f8b34fc68bfa6e43d26c0633f13045940f3284785af36556e7718d11247343d68d7dd1604b5a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067213d9685da752eb8898189777910948e5c396171dce9e40e7de8b9aace1c0597798b32633fee24a5a5d55f78e070400000000000000000000000000000000115583417cba5efdceb7a828114e589c7adcdc2bdf471832fb3b7a96bbca9210fd20b4ae39241f829df26bfb09290d281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f2ab7d003ce8bad794dc4b458be56b57c6ca2e4a92b5e54bcb2f73ada174388966ad58eaa9cf15de86a557b986b1af000000000000000000000000000000001735c69d93a905b786fdb00b91da2c4ca306224ecaf31da122229e4d244a2b0cf024b70bd1b409b94aefc4fd003f367b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6f68cd338f14f17aed11dce52eb4f83564068ecfdad5c779564ca6e245cdd8aeccb9d8790c93dcefba5509bf6fef55000000000000000000000000000000000127573a73abb85be8916b0fdc4542d056ad6e8fb9bfac043e995ed91c7b751e6965b90a759c024675053b3537a534c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a60ea2eeb86a22e1e271ac63f89236fb023b445b88e0bc5f2020af1f774ca1e819d8e6b928b3389ca06c7b580ca9b50000000000000000000000000000000019757a653c175c7196ce7cfca76257887b9044cac70f6bf4c93a265ed81b88a89708b13841349516e87b561f8e12c5fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f558bf134da0dce52e9c820a8ab4b1be24e8eb37c95fa245477644f8ca78e2bfa8153d9bcbf302019de3b7bb6b2e170000000000000000000000000000000010ac083438ee76271364a409f226559d16bcc79dcf83cbc4b1e0bfd389655be8b3eac4d7d6f94f7cd8b631325cbbde511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a63bbaa683f0d422c6901952d6fb399c230d84e20a3d99d0eddf0ade0ddc61958b02201042307f60b195c9ed4c425b000000000000000000000000000000000bdadec09d890141eaef0a5cc8e12c00552e3fa8270ef63eb111784ecacb5dbbb535377d25ec7941d0293cc960ef20e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028f0cb15cc179543c39cd424366259a29996b6739b709572da6d0b2ff57d537043deeaa67430530641c261186765308000000000000000000000000000000000c9498deca86636865290352c8a0193ba9053e61e98ffd228a1fe3aebdc347e109735f16b70d1475be47041aa06f4d4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c936fc77099e57a1f697f69bb44114624dd202e24b45c6195b08e744a655cf1f3bd3c0849cf24c429d408d6077d97b00000000000000000000000000000000013df11aba6c7bbf89a28c0f9da7dc52e69edaf68d200f392348ad8f17245bedab60502d60b8ccb151dff1282ddd3dd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b336dc23590dc12669b3bae2e6dd61cba465f55c8547c494a10580611d687f7126e50375119bee85535a7242319d36b000000000000000000000000000000000eee78d1ba5a4f15a05bb6621a9615e22bc50761c709e171095227a92aaeb31473220832c80844fbe4ad357146a76df51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086259a0cea7cdbf04c61d86a5f4928b43f6b9456a0a87f323214607255ad6f99655954348e8f561eaeb8954b2c466a5000000000000000000000000000000000935872090297741d605a1d1439648baee5ff45e2f2e2d2eaec6859b6315bca1d85bc5ea58d58d662eef0c93ae64d3ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121b6561ed1de7c694284b4cc9c67d6ea776f3f072c2d3179d97dfb21d6bdb0baf3a704449cf794cbae3ab063a4905290000000000000000000000000000000015a558fa6b497f0b0519a887e92c25471899e887d4ad1988998e0228e4507af0884c34474686bb9ba0e92bb6563de6b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e116459ff88ed81513ab793965816526a88fdca0cc6681ca1b5a536037d48c133b3ff2dbf13fb44fd4355f36ef166620000000000000000000000000000000002bf0436be880c338b0003bbeffd4a7bc7f264a7d4931a31a755cfc259e5d63a532ec72081bc935e15501ce4a22ed2891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e22c15f8e4445579207e406d492a4d27f0f6898108a3aa571ddb62d1a2b46e0cc6ce9e02a0b565657fdcbb144949260000000000000000000000000000000017ce50ec798f9b2362538a737dbca84fb97759b8046e8ff2daa53ca38487047bbc3112f68a63a4dc13403331e261a3e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d2434274430323de37bdf71da462232a719144fad2fb2127583f0418ae677945a339fefb5899b826f474b3082fc35a000000000000000000000000000000000996db0b08a2911da7c2ad2263e0d9c110fbaad57530aaa80ef0a90ad5f42c74390c55236043d9fa6c8e6da533f9b4831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001854e0fc75b75d2516145e22c10946040245801b7ca0ef68e47c9d06af0b2c6d6804c03d643b17dc858a07e33259edf800000000000000000000000000000000108a15e82329816849fc83ed4a0932eadbd41c6031cfe4c34b63fee885bbbedfa2bce50d03ebafe2f01cb680d66dd6e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f61135e9dc2b07c7323ff99689b2643e4dd8de61900f036f0c64b08ca49e334f72a58fe65596160233e4b55bd21eb0000000000000000000000000000000000a0535c32805ee6791033cbd2b9444ff048a7d3a8802d48822af84e05b5926d873c2d48010a29e0cda8a6a33cf7dd5241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000068e137db7bd348852113e6007cc99b77bc4046aaeab666a1b27aad73e0fe0a9cef555320ac89b79af2d553fc2627920000000000000000000000000000000007a54044f2d8abdfdbbbb8367a961949e01ac9a2204c272125e75295acf8c249482418352409324ad6957ef324e9c5031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023931a4d090ce4d798f219cdbd1b23e99dd1a745dbb5f5b01fe7449c8a1077899dc9c404fe2fabbe3fe208f55627efc00000000000000000000000000000000127a4ee85874fc84a4a38756b6cc1ab8c99a402659a6892ba4c2a6598dea9cf11aeda811dd6d62c3db3eae2228d7acab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a60c7c8e723c208fc90af1cacf37fc035534945b3da6e405d5fb05b1a1b77e7234cc938e7962d0bddd13437388651de000000000000000000000000000000000307eaad9fef5deaf958341ef892d136d07dbbbd13da01fb2abf993d73d68e9d3383893d31bd1a2889a3dc3d4381e6dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000167b3a8e1659f042972ac35450259488a711ab2ea5fc24bbe0af6168ff297b957e5881bdf36fd64aa63d66246af5d58000000000000000000000000000000000172a73b0c84ff7a587fb4cdf18d5020dc3041651943371367c493a9c10a535224b5b80b958e0e1f4470c8db562b60191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180acfb74d948a4e0736f782296ac66ebb49be6d329ffb57d352803d69c65546a1615691ae369cbeca2138da1df5d7d800000000000000000000000000000000029f6ee011db7de94c5289537c0353f140b15ed66a4ef44493b923974f99b04d7636d3d9860e8904fd3bf7b227c1a9e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c439980fa21ea1d3a4adcacbbc911759012bc9f54c78e873526806afdf4cc4db454f53a38776024bc2a2ec33404218000000000000000000000000000000000eb61d3a60bcfd9b94568a4d286a1cac1d410a08932d14723a60b07424be3d6ae7801fa676901a87d8338cf98e9c32171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bfaae6d4575a6b01d71f557c5f25f21a9cff88b7939280e3189a8c52470cb4d33bee0a5aa05320d5b7b9bbbcc406d100000000000000000000000000000000047d844bfd9a53c81b33148e985e9d7faf74e9208f46afe78750fab0c7e02881c5d71739598644c797ef8fcd26d068791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029706a909ebf642eb10b57b592899a710c0d9a1ea2ca13844761885732edd327f5404189ba895e23b55326b51caf9300000000000000000000000000000000003a82793aab771c1bdc7ec8159dd64eb07e93be2e42e9c392a7e817828c3a716c48b48240584724719a6e7d0401408561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000884ad21c0393e133da9a79af06311add389f7de6f2d79b2f7014f811e24db0894ea4fcd874b1bb2d46c0ca1ec9080e1000000000000000000000000000000001697b7ad2826481480a264e31b6db86fa8e8e10ce539277d2887ccd63b92d8817b5ca89399fac52af7dff44ea98db1241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030445ea7780ba0b73fa802ab0ddde2f5d6619ddfc4d32ea3d142d0b8280d351df8ef055435e4e7ae6ff18dffdb0dd00000000000000000000000000000000001915df3ed014397359652293d2d6c76e2e87edfcd3b2f239d1c538af07768acca146565d434317b24f14a63438c537b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017467df73a1a06807a59df888586ea2a386eb627c6d14ea37c60e21b2339cb386b910b29c9aa88e024849f5240ba222a0000000000000000000000000000000005e7703e7dc2a99b3f1b016467b14b7d5b7e988850e94dec8cc22f1e5a864306a900ec68476a7f2d134e795a5df72bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cd4cddb96619484e61be11acf1c0a1570ea061ed36a6a80bee377d30c3418e627904bbb32d86ee98b35d9e80a0589e00000000000000000000000000000000051f7615c7f6aaae22754691b4d73ed9e8272a5ea51af1f60e9a815b911d71aa78ad41f3ecdd07b84d81cb2b26f9f46f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018144aa2b796921a35f0f5e65d546738677df679c09c3bac57463027a54bf182910c595bf6fb7b13a60c300ec728f390000000000000000000000000000000000c3b9fec4c01a3d333357746a61349e71864a9b5965c3c480eec1071ca7e5a18c71aad0b5fd169c0c3a4895aa370bc341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d9799693bbbae9b5781609bd2d349d41fb17b07cea94d73a822b1bda33ba47f4ec4d55690a6d8ac4ff16cb32960dd50000000000000000000000000000000011512bb39ae06b7c36719624a7151c1f92a1ea227dc243a801d7e369986f670dc1708815b96078011bab22a161899b221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b40739e8aa4a2950889c9830dd358adc16a31dcaf779f5f936ff669a07e004a8d1f2a985db05d84ac24b115fccbdc090000000000000000000000000000000007edf499bd56229e65c007117ba055efc2789b08e8ee725be02cc653bfe6549dbcfde4e62c893d31928274a27665a50e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000358f3539d76fe3b4f0210dabc4b8d75677ee854376b5803940bab1701601f7b13a593baad51fcf7436ff05c53e2372000000000000000000000000000000000ec36014c9968f898b0d85b96ee935501473ec6185f4a2aca562ddf017a8bc5dbea8a77d38e72ba75a74127484a2127c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d80d0db1bc2b6016dad5190f9b9498a312a33a3094bee94c1c6749012f4667f76c534670b06fcbd5c4837e308700a82000000000000000000000000000000000950c5882f8a8385bbeb32304c6d4b2e1590d0b652f1647985fcdb6a2447db2a487e336c74c316c29d40b6ed62d4f1991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b5e9810bf844d425ac9f44349872eb19b047fef683ab5adea53019ba7ab1c49c9555f37fe0418924f40b7481850ff7000000000000000000000000000000000fba7994f389b3863f5f70aa5e30dce156baa4c9fb33c9e64383609756322a8e2767321f623c68578e7694202ad528201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183c9c5c754c9aef1c85d9234ad380bd98ba60e829b84788be951c8488cc7d5fb5f3cc4c07f6c018a9cc6de5bd0748670000000000000000000000000000000010abfa44b037eca1457ccc12b3d013e1617753c59d476d5336db9c87a08d6cc8963315cffc808535df2fc15078bb40551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001893f20ffa0b680ede98a4ac5c763d980d841833eca5e2c4586b819dbedab8dd804eaf99fd2fea21ef22ba56fcc1901f0000000000000000000000000000000007f921fddd21e75d1845c2925bf4b0d8dae1b5b52f3756f4147a4597ad4168bbef40069dd048f262e5154f3839568bbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013abdaa044a73f7481d20b7b309e85d84b953ea24823d57a3d8b87ee668c6c7e8ea9e1a711b78a92ec8b1874d5d789f9000000000000000000000000000000000e1a0aa671215617d3b9725723cd524015190e87e4397162f407e56380769157f66a4b6955b09e07c1b388af299cc69a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b602a4e1d757b630abd7bc4cb3c5386d8f64813f6c10260ee49fdf09593786c55374a92f5b42fdd6367d9e485265050000000000000000000000000000000001c6f3af834b07f685959682d6d91832dbb9eb37c3e4698f71864b7d6d4614f220c3b16176a0324eecfe2c57f08ecacd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000478767439c82381a0a5eb9dc301620f261ad5a6afc0a2700aac292ef926c4b8c43f113f7a5888e6df1169ed88cdf3b600000000000000000000000000000000135a229a90d923f7bd9264eb3af03371ebde0073e644a2e3289485a5d3480a6f02a518eeb606f8d66ea7f4a4a6c0bb871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121910719b09ac8ef9c78561169a20229fc8ead0d4f42f5327e9130f07c7a9c68af3f18795a9de753d704b32dc9eed00000000000000000000000000000000000713e1152eb454a330bd2e5e726432fe5d1e59acf4e64cabf4a3cc6133e5dd1a87449ae4b704aa8c5b0a5dcda1e260fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001524a2490ad9fce68d6c26e2dc7c424592a29d5c4d04472916d44a61f30291f4c8fe6f5c89db2169e2a2eab73382b6cb0000000000000000000000000000000014d606953a86684bc184c16bfda76b9a797dd5c2a6900c5bc789e49079adbcd8a8a4da0f3930e86be904efbd13bbc61b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f9c42ec5221d061c7192325b5f051731a5a652ba6cb72f6d4d454a7a7c9e43b947fb29f4e37fc4fb9ed78ffe74b9fe0000000000000000000000000000000013ed2be22c1df754bbc66b659c13c92a2e7bb0984872b70251ff04a525db41cb7501ee49acc0ca62e0f1abe8488d7c7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcaa1293cd29b966a3a0813661b18c738e762235fcd8738cb0b7f3776b615ddc35a38b7904ff9cffc3b35a437efe2b40000000000000000000000000000000004904578221a1cc6c62518cb6e7dcbca7f17efc86d5329b54cc04ce51917e6ab1cffc06371828d817a4542584c2f11131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187d820063a1d46b115d8b65bbbf0ae6d56f475ccc324b2ce942bb94f55e1a9efb7ed5fe0769d86ba47bb22bce2fbb60000000000000000000000000000000000c2daedaa9f1d044f2bf95a733615f20259f09f6aea16c8760d94fb494c37f4d7d14dbd0506104544a9ae3a09fa50bcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051e157a71e1678706cb82922200d15fc3bcc07d334fd0b06bee40eb7a5198d9f6a0c4b6de603041edecc325683ff840000000000000000000000000000000000b9e0e6f1267c4e6b9a7663baa138180d33f297a5ad07dd369a2fe037344380d47c77ad732746d23451b714bd4e7ffd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001804a53760572300e00bccf2d3461ac77af784bc65ac01be9e374a07d055d604e32db40b4356e95a293d059a494b2f5000000000000000000000000000000000af1cd35bca5740a9a92fab62531760f3c9608a45b548bacd8118a7f4ec9470a7e5d60762e9c9823b93f9a9a0e63051b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006da7aafc25391c7b591b6079fea4f35fa28b69883d45168596c1b899f7d0e1ad7c19e10951f5d5d755ffa3cfc8d14d20000000000000000000000000000000003e2de39ce894986c95bdb831c39aa26d1042cded410ea1228337fafad81155d03c1b70f2f4091bd44123ebd953bb67d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a0b56b3e06e9a4cb748946d0193981f24999828ccf50a9a172d71d78a57e6094ecd6d218495e409471a3e9628da13b000000000000000000000000000000000fde7265e8c4d6d8c15f9127883783bfde4e6438578d2d9858f332455255c1c4f0344ebb82b85b940acb35e33d71e61c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073da75bd47306002b7130cb78883d4d0c055f62466f59473d6dae47758ac46da64ab8e543c77d1201492224621362610000000000000000000000000000000016d1aa37d8387595fa75167941100e641851c4b57fd659777e3a79bcc249c0b6ad8a6306e6d4411e84425c0fd395e0ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bf38ee26c7076ed56683506a06fb54f4babe0b5c8ffd3dfb477f2986591e023338ca9cd58335545a18af4795b8d2a4000000000000000000000000000000000c6e3bdd97a87a07eb3979f0f486fe832dbdc4815d70a3c9e14f44b51283ce55044d686b709af58d3338b68f73cbe9521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6901aa3061540c90dd13f3deeccdc07dc300717dc5e8d8c78fd3176a2014a9b17a73410d816e39b08675923b5f7652000000000000000000000000000000000f123beb981e97389b695e7942292e4c416fb7be81077dce0b668419bd63fc2273526e5972fc9c143825dd4f0f9f28c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e8531f5bf90ea098374db41c990fb4d7b5e8f9d55daf206a7d585bec537d176d582481dae164c13374f7d0898b6305000000000000000000000000000000000b125674edd6ff3229ae8d86337dc4afcf699a0e665a06c85a13163235705830c60d1df7ba721f293decba8f2294b1b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fa96c23c82d82a80c6496eb0d28e14aac1cc0b85d48120da4c57f28f79f8263a78264caac9b911bf84337cc5b632f20000000000000000000000000000000013f432042d6582eb2191bd4cdf01f299f3a225362032450c2e4d56890df836bb7b2ba1ed20577b5331f033d8d28f05551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000354e6767527570a4a0972e9fd7d7ec4038ca8a0ccece2b8226549062ea3271447e3a9295129eeb472be1557eca3740d000000000000000000000000000000000582ea1aa9be0451188f6d5bc457c2fbba689b1c360c114ea8c23bbc4d91b6b7a13279e91644099b9d0ff83a842fe3e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001150a34a299d7a0e7cd42bb955707d0ef980a17570ec3d29be2b3a00949cb68ba0d261083cacd35ed5d16c574612fcbc0000000000000000000000000000000018fc879b2204178841c0098a6546eaf5295230bad47005a735e1437bd4e265e8e29f95bdd40294e82f5e5ceed271ab0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cab28759256ae12c36be4f41fbdd948a385669405977dd34870c92d9dae7dd34d6286b6e79102b7f9aeab86e2ce085000000000000000000000000000000000cc18b5bccea8717dde660ff953fa4de2421f7a4503fd10aa158963a939d945407a49bb47a9b29525979f5e421182e1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c6d7939beb06aa0788df4045cb0833a86b115c871e7713b7137f18950304bf1900fe8f4fc447f71de0d54e1bfd2fbc000000000000000000000000000000000e9798f25879e29e81e315e6b438e4041d9337c9afe8f6e222aafe44730deb3ba4e055b3ba2372b4c2955f7735a004f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b91192ffc961baef2895bab8eb91bea26e3f82cf3ddecc766a7173917c3474be0dfe074aa181399e3121fea433e6c5400000000000000000000000000000000039e3494dc9de760c9cc602c2600cca28c3b2c59e93897e4f820a2ab804416985c1a7a0ce41ec718421d84042c1947c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113da26716776065e599ad8c03e5a83aeb6342c0226ff6aa16d99f8c1f14fc223cd0a5e4d9587258b65a73d667a66e300000000000000000000000000000000011d377f905252560995787bdf67607a78193ff64dc66dbebf6a0c22e4d8bd4d36b924d2c8ca591b08b4b37f3a5ebe1f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ae620b94c34f75e07fb2b4b0cd9ed53bf2fe5fde9dc7ace232f6b5afadc47ecf90e8d414d8dc87f68ae9c5ccfd92540000000000000000000000000000000006e0c1703d64d75adbdc96404a885e9b731ea833101e28394bd48510a1bbe8a2cd22180dab16f27e427311a18a9246391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a23b760e11e4cb2e7cfc5f612fa33fd9e4f960dd74eb9eec75c1256c4740bb0b0ba0e0958a5e67f9580ede91e39a2020000000000000000000000000000000005a977679380f4dc8246c0ed3ec7afe3a9b886f96660ebe86a14d704ac108974f753b1b6c4993ff52ef1809885897d621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbbebe9d82cb18059064a6068a12e671f4f14fef3979eebc514275c3c85c2819893a0b38b7be1183d75baf8bfee0a1e000000000000000000000000000000000f2b1c423da2111f9e4e98936ccc7b59fa8bec782fb34004d8c5d6f7f1d71803e175d664c425dc6e2430dabd90d8dc241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c96a15227e962a080ee5ad16e09d7c607dcd418b3093148fa6e4546294efab1228cb6842fd3ef131261a087dce81560000000000000000000000000000000000ddd392fd9bfef6af3b5361141f5a20b681384b6d5fed252c4ec95c8c4ae94a1350bf355b7651c792d0344ee940773fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015eb92cf3dfd70d4b4d669310cc5424969cf96e4091748e7586e040b96b47f0faa179e989a9cc549a1611583f402e81c0000000000000000000000000000000011e5dc27433b268fea5ddfe7c342598e5521eb6d5b89a1b1fd9a5b99ed9395777cd68a399efa8702f2394ee9463755c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010625e728ed2acc936cb99738721d573d58255febd7ccba09bab4dbdd5f5a21c0f97660e003ef15da9ea1489e8c3374500000000000000000000000000000000089298cf52a135ea35032a392e6439ea10d8d313bc9d8ef953f2da7f12cc29f97a0babf64e813ad226a161091d6d2e5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b0d33c656a6e4f33d97d690158ad3f387528ba63db1587a71c5672703f9d50ee1d6668cd38a8fe10ee78df8b0b5b62000000000000000000000000000000000b4896f958313a544e462419d8ff1bc0e72b5a91e782c4ce204dfe4bfdda9983a5b0f5de029f28a8764f680b762c1e4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050a36e428f0651258c0224b024ededbd34b31803bb11c1000f45371cb74a33b85c0da1118dcb08f4e935c0e7f01934a0000000000000000000000000000000018b5a92eb415377ade0db12de1f398e6c854653b4e319b23c02e903dd19f13ffb5d5dacb89d9b5274a35b3bb3e318ae41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b080a9991bf945f25e9e3f4cf7e3a99c2549d4200df0d0e0c531a68111825cba95f472a66f0443d1d55b17290e5ec8900000000000000000000000000000000174e795142368cff844277257cc95b0d180669f73239db80cf5eea4756aab431f64bf5ce7782db729335346bff2b9eba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147626943a0bb74d061969b16f1928381cad7810ad162caebe1482725fb6b3178eb9e85a7cc233df98dc7cc937bebc230000000000000000000000000000000005c8cbb684de372c8772be3df59e807e6423e39bdcaf75da00711ccdeeecae003ab9aaf3c28e98a81a1dad4d318117a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f79e48c24d2cbb4e30d4b06fb0a49d41a23f586e2472d1cba1ec0c762bfb9c27491434b1e7a48fe39929db79448fbdf000000000000000000000000000000001060e66daa0b5ecea92824f2f8eacc1076b3ec0c9903db829d2c41f3e8a56edfbb6e1abe4312786507bf9477c05295da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074c9beb0625b8972b380cb0271908e4176c800346a73cb85a91d3ae18ede308593919fc99bde12378eb35cec465622d00000000000000000000000000000000190badfb4e529e864995b9c17ee6cd74b792af2b548db005c7b3fd3b412069bc8a1c4972dc1b3852dd4acb0c0525bb5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e7a3c54d473abafa9d9ddb724a325638f0de14bbb49f0c7a3c35aa43f72f5761705bd79da03182945c917e0df81deb00000000000000000000000000000000124cedcd30a7926b9d689c5bd368135c15308ae8fa2f5e8e6cf2d5f5b37f5098188723d33ac4f3db44030b47841dcc151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e12b3941ac008fbd6201b7781272e9353352ab4e90f15a7006cc2ec4102a53e207c4db288d7562914e5bdf295d5f8800000000000000000000000000000000063b84d43322ce7ba28bc0380368afe24897e5c23c718a90231e8f52418db499ff0f342fd71d7dd2700c462826c9f5601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000835f7f18c6028ee64e689b1be4f6566776abec08fa235323eeb4b24e9668599c8670e460bb1d41aaedf3d2fc12bf32f000000000000000000000000000000000aa2655eedb6fda6b78fa7e522d0715e1907d657b331bac2a16f6b3994d1e3b05ffd93e1c76800d700247ce3681b1f9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689b90708594f5d3a67f75f05c91a28773654e4714c5c283545c5aade7f933730b38b75d80b7888a101f17d77f1e788000000000000000000000000000000001029b7f5587f50ce70ef02f9bd58f9cec823c1fc7aac07a5b8ce30a040ee4801075fee129ea3a5a5e036ba50300c13d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e56c36c4a5547a9cd7446b9cd3cfc8a4c6e4773dea364df4811a1231c07a456945c7c83fdedc4cdce2132b0db3d4840000000000000000000000000000000018aa0e11b0464164393c950202046f38019a5f1147bcfd79564ac82ce6a16eacb6ee9269a25f05ba96411baadfe0e9501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116f39b4ae156184d0c74dd275b752bf2ee8a094b2642acd1817f7b04eb0099f0d69329f69775ef6fec6d97c6e09915e000000000000000000000000000000000992537ebba244b3ebba4028b5422326f55884b53dfc03b75a76ed1aeee3d3bbaceb0dd2b11e391d83048b5504abdc0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea1c1e139a2b9e01d1c114efc0252f36bec019fd07bc732ecad8e4a36d041ccc8efbc606503f4cd8bdf0cab718f9e6a000000000000000000000000000000000042a6880fb6ecd68df831d6d4255b1859b0e486c95756cfbd484d8c005665e1473811b1f2ff7bc5fcc44131197f09491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000803fa3115cd921acbad7d441efbb92cb13410ffd974742dab7ce88f08e48f5792cb57c1d11c833ca28e3d428e8206db0000000000000000000000000000000008f74a222397e0ed0fdaadae67a98942e1f1221fc2a3d9e83d34f991afa104d5a704b0f61a77915c683602e628a84b991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050c70036a2c272b0d4dd5ed54017448eafe542ef58f99cc4f108cc6cae0b10b6b18d5d7bd7388c9bc536dd6e59c91ec0000000000000000000000000000000018a5f2f4933b1b829f1f591b2c7310eb9bc56d40c10441a46d286c72d18e7ef3df057c855f35eaabef6984b03f2a3de31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137d95994193a0ad423ef6f90a7ec2e003c733e0da890a9c8d756461f7603c9baaa0afb626341664634c6646239ac6dd000000000000000000000000000000001813a8f6960e621b67cb8ce31157d0de23483739b9d03aa818dbcfa067709046fa7b913829dbd81bd9a1a4fe748875881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f7d0eaeef234399b1b585018fb9f49f28ff3c5e4b96484764cc5588841a11b2fd722f828d32ab9b0ed06af9aa5941b0000000000000000000000000000000007d8e9a06835508fc8cd0ddb97df1a0726c5c4c97e82ca90fdd687fd8a367b7fe5b25be52857010b8e047c4bfb160b001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001043c9141144c84ace125a0df6f81cc44221820e45bc842ac117b016b26396bde506407ac2350505785a681b783ae5cc0000000000000000000000000000000006dfbb8d69f19864fce2469beec2a11709ad4ced6393551b302c33fb82250055e98e4ee61f4cc4500b42536538e4363c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cf5d55991981a4e431d896e5ebedcb437599b9f678bd54e2b0331056d5a549f5a8e773086cd5bead08710e9df601b9000000000000000000000000000000000b930719148bf4fa8ed858fb1d9891dfab144df0ec49054548a51d1a14824103d6d88ad90e9d77da938e88140c53cb9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc4cc129f83d350c2d0a9f223bd5b83a53cc60da3f486b17d1f980311be02a61a82a9f28833fce943124c2761b82f650000000000000000000000000000000012acfaa552c17917a4e594b8b254b0106edccc1a3212e2c8ddb44227d10d0edee55e00b725d82d9eea34def70b084ca61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146bae5fe4227ec94d1fd28e383c5bcceed5159ad91a65a6baf2e88be3d28a2a69dbcb0c913c07d74b04f31adb781743000000000000000000000000000000001081cfe902840aaf5b8c78a8d274c043559bf48f731fa0c942d75521a8142fdfd0b7f1750762ac330c66d26bda8f9f5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae074a9d3426babad7565d9bfe50359812a0e7f6eb214cc9297212a3f2de547d4d51cef62186f20d7ff5fb717b6f122000000000000000000000000000000000fd712a181ac8f9570f1977c76e6f99e54ab6af3ac9b7f216034de44c7dfc3f91f1f1a6ef7654c5a31e3f0ea3025c3961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e77326dfe61b083117b3333f0d6d3e4c747dccd3faa2a31998f8196608c3e0a41038f760edfe1b3bfb094f476d0113800000000000000000000000000000000160d2271afdd7a2ccd4bea2443e263ed86aa0ca8af6a69d4d6e35b2a09ca9e2d3f90892639ddbc33a92eddb52fee61a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8e0ae650b19977fd6298fbd0ee2cfe1e5661f2b821753b549c2ab3a47622dfdd6e08ca89dc91d545ae555a59b3958000000000000000000000000000000000af15232593767435e86500f2f1b8922cb23e4fa72f45e10cd14b7f66200c859d4b8dd2c657a4a7aa083e5bf9d2360211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e987b3e194143c6a8960ed87333f9eac4ada59e5f17207317be05376dab64377151e77160fd1d11e5cfdc7ec868fb61000000000000000000000000000000001843f101a396b2b2e9d8ae95d1a1cb9b72c1e35344402b80726d47149bb55b6867e96aaf66a4d70bcc5c6d1e22ae5d601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072d47a27852bf70556b0713fc3879846138a039b49c204b59007e6a7afcaa6926e521c9cb38a9d9ee68a83e7b3a81ed000000000000000000000000000000000623a771dc7a0aade68f3e97ca7c35907ef6b95f03b81f65741bcb5f0fc04f8a238052d80a93e8657b1a39fbd179d2f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a473c948874d2b4d27c0a6a2d71dffd04eb966c75c13709b2dc9e47f2d9c325afd6b6e15d5009e958027764f817ed8000000000000000000000000000000000733933d7ea933bd7353e9e60fd42c406429bb68ac07094c161283ab7b4bf4efaf9f31f48dab1dd6ed7f1051e034e3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd165ef4b04daf0d904f9f0b0b7743b8e1af8192b0ccca1b60d64fb3b65f2d3a88f3afdc67a01cceed93c10f7b687ac000000000000000000000000000000000bb1b760e397ac78acc2c6834557c782a56f83a8beae5365a385109edc722fd095e0f01ec7183cca8daab6489758431c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006259cc10b419a8d5ac55823899140e53a84aa2fce1ab8f8499680d405b48251549b65477bb90e9ce2095ccce31a610f0000000000000000000000000000000017d81ae5a3748e6ec118e0c7dc2e128658f06da33cd0ec79000065a9928fd3a3332f3547ec7522f45518615e3b45da8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149fe2ccbeffbe069090a4ca4ea1b47cd82494c9b501eb13e798f244e8593fc71c1b14d374a6113c10115107a8cba36c00000000000000000000000000000000072244a287ada3450ba7fbdc871bebf038420caef541ed295ff31db8ea054eb7ed4a45e63c3b2c36538a712ead620faf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bca769f090440197f815273c348a468afd1e5b43ad7bec1f24933c1b8b7445f2c9382583a61ff6a0e7c2e468f242cae0000000000000000000000000000000019f2e8b57ec17a2fbf461d5f5a10476c604264f5992da6a6ede80a23cab61103c4a73eaae4a43106c31c4ddb13a160491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175f5cebe49a9d9e0b8019aa55804a298cbc4e944c0a16b0f89b3d217c17e3486c0c61e70099d7ad578fe9600354c0ce000000000000000000000000000000001532ce826cef5464b652d5494e407a3e25851ae97919eff054baefc4a1dbbfd32d833d91a2291917c4eb1e9bdd57616a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001899e6529ac23ab5a412596828b1e192638a2f87c13c83acd61ee7ee377fa16d029408196d22a9b3fdc74985d9ccb45700000000000000000000000000000000021a95bd3f437bacf173a8f9d38dedb2b81cff014ec9372f7cf26acb7291bfde7f24140d280f6d7a2b44153cc2f3ea011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db3207016b163008e9001ebb72daa3313a555bfb571a0181b8cad9026d6cf1714c4fc5d559e6f927243d2b5cf50cf21000000000000000000000000000000000fb6c683858d00208e36393a396edd2fc959771720c4df27d03815758f55ef2f149ea92204cc984591811395350da4911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e21db878a3f0a7dd8a481a60374d28d76fb1305399fcdde5c20e8922d0293274dfc722c2c1400af6eee75f2fcd0995000000000000000000000000000000000719994ed98e76cdfb51c030b2ad1064d3f3bd45203a89aab20a3d0df6b0c764e306a90d0436fd24e49850e30775e7f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be766000482f589339e5fa516073c7f0f57f3b61fd1e8096e43bdcdc8265ad5bfce2851fd79c493888cbf4a2ff2e7b3000000000000000000000000000000000dca0e74f86d565b61cbde53aebd0f71254daa4bb575e1f4630ab33b6e165d2744c842c2b62acc0812f0bb3c1ad6ad9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f6b9281c5a11b945cd44a82a8590ef4e3af7ea8513a74bae21d0fc41a6f7cff4d9236081fb38812ff34c32f08430fc0000000000000000000000000000000002e2091e6dace0032b2c5525ff7a8e1fd365bbffe1474e85d15e46dc5f883db0b9b0a187befadf18f60fc81f6fa3dc6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c7b244bd94b6ccdab961ce17d157dd379d01ecdaf53b36da3e35f70cea2cd332ebb5a17a45a88fc4fbf0f57a10e71f000000000000000000000000000000000da6ed38ac031f365309508a1f9c592fbe76c837b45085511010a203ed6ace88cbc5a7900efd4548c121e068ca55ca101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c35f5aa682db98901f476e41d5f4578c90b9236722569af34c32739f9201387bc6bfc22acee0607684140f445a905f20000000000000000000000000000000017b9a78469a201d1147e1d208b74ab3ad785a87684917168761371fd3677c6a4cc1a1d972d12f5beffb1608e61ba41791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d95026ac7cd4501cefde256c50f90d9ef30f76d1ce01695bf3ab8f9c81a3473723ca21c5242efb87c9a45f7b3029a6000000000000000000000000000000000dfbc635443aebb9eeb2f292f4f678766ca4ab0208697ca3f459944b8e1a765eeea453c61de023b68bd680c149d70d0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f4d68788e35a38fa1100d42c2d32b357389f3755712a32de187fa24f058f33bf65b8f91731dc253ca1ca615bc2bda90000000000000000000000000000000017d4260b359ec53ce661f5d6885bfa190b585e2e5b6b390a7cd78f1a8039bd52f4dfe80e6d08998592b22f9c4ec4d4b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013d23197273cb72b9eb49d1b79523950928b1359cbbc219c8663bb3f004591e7a64108ab8072b04b52e9695db39a2870000000000000000000000000000000000676b33bc024a565ee1d6620883cd67bd3d0f89155e37686be817cd557cde6101f5c3d629d1af7fbdf361dab23379a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000864d88630ba013c1316f8e364cc4c0b39a13153900b1393885cefb0ee0ed72768a90d52d0aba61925982032efac6bba00000000000000000000000000000000081c2754adbfe9682f58c834b4f6664147b1108c1fa98303b7e2d9a8f05071eacb5d98cfab76768729ba246cf52524d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001372fc2791498bd11c89dcc8fd6617a4bd8ac4069d1a15f535b132f6636dc5e16c95b7bb7d358f3a6e9c55d778141c00000000000000000000000000000000000761e26e9ca8c064f00c7eea8e6672d96be2e18a3edd324befe7d4b70ea39ac325872424aedf8d3395196796ec06efc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015711323df9bdf9dbe5423bf73ddd1573696a88b0f6d29edb300e2fd60441094f9ed6dcc0d61d7e1b6a54aaf2609f8590000000000000000000000000000000010e9acbdcd956a783359d84fba8e4a71cd231919b92a1e772f624347b90b310bbfdd9453502918acdadee21834542f401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c70c5d4af6a876bffcebd08bab2097f0f16160865373652111ff17f2ea96f483e170de13a489f392c19b7ad3f754ef7000000000000000000000000000000000c0f3d4ca084337f8de962c289ec01c8b8cb8798f7e717c5082282ecf9a967d821729efafd4f603b65c8832e56e7b7131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f00dd8777a3281ab2595a362e1299da287d5b34fb18617d82479a82ea90510d7048997da7059b76cd7e3388dfa4dcbe000000000000000000000000000000001320d82168d5d6911068d1e7bfa1a89b321098caeaa4fae7f38c57e4191cddfca284808c5225c82edf747bc37615c60e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004de15fd12b669b89c81ef4226b35e546b056bb8a0e48c9eeb90abe007670d9f5a2126be4e211aa027b424435d05c87c0000000000000000000000000000000008f2568e0ffdbe56451d45aa8a3306aa8e0b219db72970591ceb7bf07ba9f1a296d395eeae7267fa4cda51ac499d352f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014edf21be3b77894e79b0a55d9e0ab4fe8f399ad6eaa2bcbbdbdbfbe8b8c7d49ab31bea8335883c570d4ee32d35cf7ef00000000000000000000000000000000160c929baf538af899a618f916efba0fdc597dc46572ef66fc2fd25e8acb28634af18270180c1771534b1faea20894061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bf5f4bb8d24aca0b58868c485ec80aa1535689161d43361bf794f179771797ac76dbe65345b2035ec0f969fcf1d2a800000000000000000000000000000000113d3450ecc7ad7b0723dc53ab41abd81de81c22e1a853b56156e725a6a5c1c45875cbeeeabac8c35104570425bcdfec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d567aec9f19d8d9d2b17ed34f87384914badb67caf546413ddea616f666b4d453afe681073def102ffd93577724b9100000000000000000000000000000000197d67e0f2567fbd6960f2db0e4439939ec6ad1b68258d3a3c657611300f80b1424e61b0504778e43fcf3a7cef14dbe41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000040975e73640c05baa6ef2f5dddcd6c828b41b945403b5d83afe898412942ad435d49f650c49292c095af216fb25cf000000000000000000000000000000000020ad1ae763e2c2abbec0e88194e91dfc58c650687075823843af8e7792525f905acc8346c7cba8cfa4107ff37ecd2f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebd1714c727f1ab81dcf39a92860d1fdefe590ba680642c65a55d14a7d4726e4eba6b651d5651783394a4405e2c755400000000000000000000000000000000186eed887c2b22b5471f6ebc70daf747684b8317a900acd1ca884fae27393969276e66873a78feff0839fc88d15492191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ba9f7973c3f8c6e1002cde146bf9be0a2ec0360ac7b3acfb2fbfa52cb6da5be7f1bee392c2c3d9f0530aa59c4d95d1000000000000000000000000000000000a9f0fbfc226136a255445faafb1041010d240f3f8d5f8122069bc3e7df4491b83f9dc09ed9eedbaff68df1b3aceee511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1fc17e5fcb57ba387547763c73402c293aa6df757d2215ea7c47a1e00d48a69ae925dd8e6d5c1bffed2c0490fe21540000000000000000000000000000000007d9445bc180a97d1939b602276287ac932ad0fa6f5ee64238721212b46565f7182b79ced8c1c7a833fbab32298f8e9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001750be6b878b3615a53d7d9228870031eb93926e03d12f2359e787c98e4780b6c75f58034dcab4143f8575fa8a1ce5e9000000000000000000000000000000000bdcc4617999eef67022dcf838546b79c54b6724d6f1f0592b72bc73a5d62cdf45f8e69fa2c6f2fc7236272e554856601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035eb2e1f4bc7cc53c9933608d859437518253a8d0aa09d23463e0e42aa7e5d311be4fa365bf0327ccabab3e8d3ce8400000000000000000000000000000000001ffb7940359984031aabb105fd22d87a21559eb45b32fe998f9736de710ed1e63aa65b3484dd66972a7cc88e21085201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74687c072d2a4c86ff5b4b59f917fc48ade84986bf3be94d73b33bbce2fab01ee8860d06bc4e7d16d6754c55bd47e50000000000000000000000000000000008f8854acac323c4a0208f72ce385adbcf02d0f2d8063c854fc20013917dd1446ed54e68c25179cee135fe57771594c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000513537c74da804e205803dd36d8c517f4d44c622d585b5604a386e16edf5609e0e40d6acef6b1a02ac9f9bd08da4e38000000000000000000000000000000000edeff635e75c5e0954e57a982d65e43e7deeda3aa57a743e98b6326929995c6684e9725af3559752791b9498caa92901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000396ca682de8c10640472834339221b789b6f3bb316781d4d7aae85531a8489c3f5f4c42e49d96380d955540f046c3b40000000000000000000000000000000007e19154f4e2382453d1a6d49672eb35ee1fd1869dd952dda4b8aa2b863e77c98b662aed1d9aad3caa6ab7abb1ffcaa21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061cd0d402fdf6fd82edc75564cc84bf8407be05e6bddf733e79e293fb0ef5aba5fa450215aec4a8f1b3f9f84c3c8d510000000000000000000000000000000007fe8f816bd15d636b42f6e063a359524944d4974767734a41ee7d0cbc0ada068f08fb3e5ae19ae90b337e1d2819d64b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b10032555ced8cabe9cc9bc3c2a11e716696d7d21a120e5ac5f5e74242cc9be741940a604b6763f84e935350e661620000000000000000000000000000000017ae001defe7b6e9f07fd9ee7bb1b40f5e7c386f53ae2a38901634534a78f98e49f249addd5c571f6a8392d0b68c5e551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001287137a0b495c9251e49d4fd1b39c9dfc4e18a2e4bb9ddb25f0fc3a4a909d84c0263ff92c5f971f67280b3b8781d7800000000000000000000000000000000002b1d687f4b9f8365393d0776486ab31e02fed21c0f681f90ab97fcf22cb2c627be59063587563891b13861124de3cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e10cf4c4644ed6d5cdd44ae7711405ca67176b21bc650749b5a6205f56397fbac705ce1cbc6e6550d5ea65f1ff6565000000000000000000000000000000000d4e9d54b1ddd1a651e772bbd78788cec86dcebe839f6ddf9a28502f69203f952520e658d331c269c0be7e576b8657661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fa26775cca3f3182644ebe07fba23525934acb881ed622cb37270279877ae8bd18090d8b7e269d74e7924a0b22afcd000000000000000000000000000000000410e136378da2cdd00a5357705747a8242c2b881a890b355565491491b4ce6771955f921e8369d9b82d802ab355b51d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092822fc67fc229b88115ee36091c2bfaa68f415fbf447d07bdb38cbde07f763bb2ecf879c32b486a07949518d92b2cb000000000000000000000000000000000cec33b21a2b63939bafac2fddefefc57d0f8f6074d2acbe33fcecde1565a47376cbf74980a3f3bb3e3f7c11cc6f4c301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001460e93c82df1bd3a31aaa3a04d88647f133b0e6d16d4bea27ae5269b73fb8d70be69cd267fa6a8bf03b3b2d8231d4530000000000000000000000000000000008d008828d1219875dbe482e497eeefc49ffe22f65d80099b1226468af77320ebe42330b5ec51e56d207ca2133839efb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000956a4d45bc8f90604780aae88a458b623d271e5f2de92603f0a4bc830c0e0c74228e9ee374153d955b212dcd3312ff1000000000000000000000000000000001050f36c8529334c07057ccb09ca80a58a0b43b16087ea11c7429bbdbca3a1fb7dc10ff82443077f417349d31a308e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9b1addcda6725c46dc3a7d1020de298ced55f1693f6b56b1c5ec8be3bc9c87d9176b2d48bb9ddd36ad8db533621a2e000000000000000000000000000000000d859a9cfb5f79de00e7285604c756c1770f1dcfee03011af0b64493fa3f1755b9d7769aece05b7efc585ea336467b211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040836499a84961f8d6b3b32dba2c8d7bd3068838f9acef584dbdd2194db56051662ea41073c83b016c49924cb2b5c1f0000000000000000000000000000000005853537d50a00f43e5de61d8e8141a7ef6182db08668717c19ae9ba0d4012bf2db2e093b9a986adecfbd5fe71f9f1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199b1dfaf88ca431ae49192f069b74f8fd62acbe80c2818e404dfd0450725d8939a4a4a73fb0bb0d1fe64529a175d520000000000000000000000000000000000aa8778336022ef875b6b4ce44edeb2ea274ff3c11f06246b417c17bc8525c0089ea16cf08d4be990a82176b74d2fd8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008127cfa03cf0ce8e672438ea94b4f94114ab71d48332e9f05c83df045215cb1e0800ffd053bc7728a4fc17bfca186f0000000000000000000000000000000009a21359c62cb582a9ae82178a3ddbe156abd820dbd35668137483ceea84c1a2890b598b0eeb7224f3b146dbdc8194421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065729d9d1f5b452fbaa48a25e221d5621f5176911d346c33ae098c98081c5e97991b9dcd316f2e216246f62c787120700000000000000000000000000000000073c49b125b1346b8fc129ac99c8146800af7f307806e346f405e91987bc0a8afbd748c305f3e3ad70e9db0d62ad0c091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000763858cc7e97310e5030fce31f07943f1eac57487bfc45d820166ff8d1327d8c844d3f477eedf0943c6f1dd23e62e5200000000000000000000000000000000070f317d6a28e79cb3e6eda44ce3fded3b9dc822141683defa80e28b8c94003fb9e25978649b81832b2bbb206a7361181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000473c0f0c926b3ccc844456a117a479cf037223341191fdd1a1e6ad1ebad1229ddf290f4c87aa95660b46628330ddc3200000000000000000000000000000000082ef1dc0beda0b30d2180cb3df8ee6e39c83fcb0e12736e009ba60d69422323695303a618291d064bc0e2fdda415d521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d322f7c0460e724c7981294df9d3404b14b18613ec64fddc8ebf46fe916c85b23607905136e583e571b2176df224167000000000000000000000000000000000f4a78eed408a92e258ba4894f276817bbbdc2b42722aa92d5e34aebbb3227aad6353a62bdc158601d4692e0c0b14eeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030814ace0fc2fc9d766d2d67ad6c018b3f8eaa51fc7be5402965c6b216eb24399addc8bd70dac11af998b2412d05d1f000000000000000000000000000000001466c0680735bd81fd315401a10dfbc7ecc3ebb8d7904e4906ccd4969a8f05dd7e4dc9a194d34be5ab08ac56d42821cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108f66f4e220ea80a594721cade80fe5fd0207813aa16cf13092cc034b05f9b2125e0088199ccafd56e7fcc36763ca540000000000000000000000000000000002a4c80c6e405069b838dd034b4914aaa7c0ace6c1e184945ea370244268d80ef8d849be967886189101d80f5378233a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000061b5a278c3e4f9a5a441b70a610dfa807708b039633f93918de0fc59437ae17bea40a4bcd8b5aa6bc9281032e9138a0000000000000000000000000000000000ac40e7bc9347ebb8b9a88f00d56527bfbfbf64344a5ae796d2185fd3794d41644cf1894fb04e73a88954ba335cb18f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008885616a26b1f1e9c75b349d4edf291e25b7b1f93da877485c582e8887766cdbcb4d082774ca092e31404da4963e82d00000000000000000000000000000000032b165e72957877bda52351268734b53f436ab25fe933e5a1ea2579833284ef958533c3b40fee209d8c85fd1ddcfbae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000811939654715967f79a1a7ffd4d6fff0b45de35886bf7d399eebbb4dbd673823180a17c8ebaebb7d0a2203616983f330000000000000000000000000000000008f060d0cd98450ffb8df8c3dfedbc528d28a8b96d5cbc96bd9916f93613bd9314b33c82bcd6a90330463f98b72f31481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006370168172032573b726e9c9ea9725fb7896b848e03dc530016ce0bafe34c317f686d7c54e8c9ba350c576416d03309000000000000000000000000000000000cdb96cb4648af55be9b5d9f8b36ae1453e6867531534f64ff7ec3a074e8c1e68e24dc702b0245bd4f5942c76878e7e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013952bf6e5f7f8bc0caf9f0f9b193717b90bb23c3f5cdcb91d789ce286e1415a675cdf3d9fe5369ddb1654b1a02495cf0000000000000000000000000000000006010725c8d83e11f0c7e95539d1cec4d4ad2dcce2f64e63f74812921229bcd86eea04cf68406a54588b0b62da80a9581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f24976039b76a6a71047f32498b491ca1ac9a70f67d2ec96afba3f36f4de3faef4be933f8bd34496f90e23229e2ea820000000000000000000000000000000016b8337a96495b5ee2603e6dfc27853388f8e9e92144d38fe50bfe8df49b087e2d974c486bde3e8afd34796c44d8d9111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ca381c789bfb65c6908ccf68d573af90424272489dda7420d8daa6d99d2f9fc42da6b74f24c66d53d11ddbac89128b0000000000000000000000000000000006c6157289990500741b6384d529d87d66b8b4c49f17898a4919fbd7a2b515d2e19907b5b49ffa8ed7b1b08f377bee081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137cc28952170bdf54613d57b8d64d4d134f8227b6be7fd9c90ed73006c79e802776a17a9dba6b3d80df5b6e187a18fb00000000000000000000000000000000046023a6de6c99d01353b2f2d0776f5fcaf410390d9638df993d7c3663d6ce5be67a3e10cbbfe55f953523d4fa2852501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e9e328352c4ddfdcff0954eb8fe686cbe66caff29e75d9ce760fa1ee96bf53aa8e3e1e5d6a6199ae758c8ad2f5094700000000000000000000000000000000008db49767c72d62ef1e5567c362629340b0d270cf465f636162e751f4854bb6d5bce10e1fb01e8552240008531296ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe601d0eee89e94f16e5b7bbddcb03dd36225f4800999088a56c29282084a8f81f033cf46d1b420dd426a837cf6a3200000000000000000000000000000000077df5b662b6f3a18261cc7407ff929d08cc7993e875053cd72b59a81342b5342ba186651e4102437b0b1f7b673ac39b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cfee3036a352eddc8272290598e66e0a01f63c610901f25f3475a8df2564a28fa78a20635683c06274cf500aa0933500000000000000000000000000000000041c0c9cdf9cc2971ff9275d1944ebbd91acca5b3623783262fd768cb828f97f6d92c26789674eb75cb67a93268328fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148f9d1fb9a75e6fe8e3a1a8841960c28f87c817f34c2ba0b947d56e51180e7aaafb73a9257aeb1f6bcd78256076458500000000000000000000000000000000108920ede87f0732393274e2990510eb01081587e50b53c59c44334626ee450565ac5f380375bcc162fd1c93208a863d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e44a683d95b957c790e2eab4766ce8c5529657f953cd14c17be536962b15ed5cd8643a5c452d9c0d814f674e55104610000000000000000000000000000000008aaec51383ab7bd709f9a8b3b67c2dbbf038965a2169a7eb8812260ca750ec81cdfdf8078ca73b65597f67bf6b077651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab413ff5e4c05e1c3e3392a59328a8765f9bcb8fe7e23e0be8228eefbdcb1641377404fdbe2029b34f14f6ceb9763e80000000000000000000000000000000018d24a78c4fce1c41fb160f2899033e1eaa9c5fba794a93993a2455624fb02b002e28b8f2483524dfefbc079068d65591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee9c2e736e12b19b90c5303d521080ee69640703c1754ac6c4152d2de62b6cdec118ae4497b0f25b1cee6727ce6d1710000000000000000000000000000000000fd2a4abda83147ab7a4d602d33666bbf9ecbf8c3b46c795f4f1bb5824be61c0cc34376b2e5c42b6a6fb5d1dca480341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ffa325131b62f24a33e4ab6671aba21e88ed99246b60927fbd0e6e1a0c34b0a6a63218bff025bc63501316fbc7dead00000000000000000000000000000000044b65a54deee4ca65ef58c363680b01dcb88e81389b14c4712559083689c2d8a0bbeaf43097e89a45a80f531bd42d321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c5ace6433cc539600fa8e001a6a20b09aa5e03912a828094319fd79ab72d2e3d9108850151e773834f4671c35a16c60000000000000000000000000000000011db2ae0a95f4854d835b767dfeca4a0747da3f855e82d85ad026170f1c7be93eb4baa13ccaa55cd7ac1f57424c5c4e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb5ae120d5a9d211f5d9daca16a5bef4425135ba75eb7e9a97621e5f35b9191fc405d34e844b22b45d302a19d0f9a8f000000000000000000000000000000000fe116324424f38d69fbaba9a0e228860be5c81ff9844403facce0f49c089e615ca83f16467f829893b1e959e4413a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f4a39fbc15ebd6c23561b5cc5120d97515712a3b9b7fb5d75884760ba5f7afc68f761d4b2a1393affdbf19971c15b0000000000000000000000000000000000574e251b22446ada61464835a8f1620e292e624a3193079df2df1bcb3aee2da30bbadfd5e3b6f7fed3c599eb2fa9abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159bb5561f3ad4a74167be4ec4b79af84e5f83ed2df14922cd048a0fba227b685d51123e4d326bc8042d9b13abc695db000000000000000000000000000000000c43be7d98d5525637d790b07917b840f54e500276dd364219feba419bda275899c99ea5abe1d0a5d6a1972b0ef4ea291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000763a7bde57e58cb69f8a34c28405c48bde7b0e5807fe9f81effaf45bd96e475808c11c4c72cf5fb285bec2688c2b6bc000000000000000000000000000000000d4aa1c10a030d7de39b74de6dbfa158331e70ce664335c3d750565fa0820860492271ac55f5ec451f2e46703878cea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a1ef2394ebdb558ff688c47fc79aa9d7a0707383a9f67fa9188cb643ab25811ccd253fedc0c7dae4ff77b54fa5aa5f000000000000000000000000000000000247d25d9d688a054d46d53b43aaa4e63f239c91c3086b568cb092dfa694c285bcf69c34ff329b976e3e3b29dadd9ff31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042182a619178d483eaf287bfc23909e36efef791a9318ce9d66a2fabdce4fa1a318e4ece9379188aae2ec63bb78b5a700000000000000000000000000000000174f6696194133d8b500b90457d9de7afef0345d14cfb6def1baccd16f7c34c10671dcd8a8f235f8e79e5a352df1138f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001697cf85252ee50c9e52f7b0822ee7bf2fa690f109086125bcf4bc24bb5d8e6ecc45e95f2fb4343360301c401893c8a0000000000000000000000000000000000cc903b21d3347a0ec1f88c90cfe5cb29725dd4d332eb2a3dd2f2668867173964785327ab4b907ef97f70ad73207679f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b29f57ee653a017aa6bd0b89d48ab2df7ff083276d3376895d6481f0cf99a425d54524c002afb6f985da4031443a74a000000000000000000000000000000000231a8b90b77a58e42638a3575a81f87a7af311adae80ab12e6b314733c819d74dbf315f16b40eddd0d6435f17a0760b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035124899f58a0ab28dd9d41bdde4190c6101606b6ec42b6670bfb2d7fada41b6fae728b72b1373e463b22737646736b0000000000000000000000000000000014c8348fbdddecfb418aa553573ddb9cd3892f2ed660bb1873458afe086c2adc2dbd999ae77e7ecacea23e416bd3b4ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065fb382c0ac61bf04deaec0938fdccf3cb86ca6e6b6fb83a0679587a62bbc2fab92fdc80815a439558a057df006edb9000000000000000000000000000000000cb888ba75c42a3abbe79e3fc8fc6d720b1b54b3470157228a4c3d797cedc4ef48ce3f0b536a0d75db4ea209fa27c8c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ff0551f558ba2cb02bd156b71a955dba9a7673746960f7040a067370d8ec3bb19ca12e24c82389900c00cc70c545d00000000000000000000000000000000007019f11712f452d18c994d52a0c31db4fb8c718c7efe6271847c687b6be23b4ce5fce434bb29f57cccfac1e197aa7871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009322ead30a644a96c7a431e167483e3474c00abe9b47e64f123dc296e3b8a495341595cbfe38fef12cb17110473fe6800000000000000000000000000000000170c3cdd855347b2f7ac01ceaa18d0f980b37a79a96b0bcaa4e9062c24bb39dfc331e8b257dfed1b0c18bf6d198c174c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4b6bb60b71a4c5bad58f0c2f8d282b9b2b8952ab9073a0583a7a6f0a56679a18e3e42f59534b984e9ec7b160305b1300000000000000000000000000000000027f62c83bf03b65cb3e9ab90e3104d65b291850233e1ccbd6379f29a042323915ad2d312d3fad88f745f89f5c6ca2461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009342e39e49c0ff7291714e830b4ec3ef76e6b071fd71c35d4369678b0593dc522f62ee6938a129e5c17be140535711b00000000000000000000000000000000093559c79516f7c71db4473460fec93b79f601b7c35568590f21a9793fd46f50e703bb19f04df53afd80ce95f914754c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117f6da9bb120e783d03a08ee56118d3843a791dfa398125f097652cdbf9e5eabf10d403d09064223ed4a971830a7e1500000000000000000000000000000000064469a7424bde9e45b3bba41e5e196a1c518076d121df271741abb2e47f1bc9c6e69a845964c6b4265d0746843612a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bbd87e6dd10fa07f4637c8346f196b77392e58ec729b214f1b2d6268c361584b89eabd52bb99942ffb13909f849545000000000000000000000000000000000fadfd8e2ed7bc7afbfbd697b88358093ef5d965ee71afd9e899bcf45e5dec88f3e4546ac0bac2089b90cbd6ed577eff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e77bff20ff9efcd866747da07027d917a52167974f0993c179c8e4fcfcb9021498709b5327e597a1486e281ba2276610000000000000000000000000000000012a7098f193c54dcf4bb9af7dd45d3616e1405dc8fd7cd28c955cb8f67ee04eafb708fdf3fd4d1a6ce23e68106e711aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000702d7334921562dc0e81e0d9565d58845b059a6978c1e7ec541d37754e1407e7ba945eba53934223bf8a80dbd80a4c900000000000000000000000000000000017ecdb9a4aa688b9901efe8ceabe33dc846c6ad31c367b791d0ce69293096ae6a6fdfd9b0542f906e58d1ca9ee8bb291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bf36571a46fb136451300ebe32b2b2afb55ef7e3c62663d35f28f52bb82bfa7e4481fa81723727df2d828af3be65e3000000000000000000000000000000000652c2fcc391da6271b28593af460893b7a23e5f0c6cfa840abb7111f353c38ba5b4cf775d13f84e460402f76f2956001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017571f4ac610bdde007e838b1e3cfdd852b67cd46fd7508de64aad01204143aeb13054c9a320ff3be146a36efc95b2450000000000000000000000000000000017ccd16290d32ab0d72966fbf0104cbf05d510a4a232b055fa5ee0087166ac35d9c737e21b8e845ca673dc76cc3ed0531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8b823e4e24962389ea96212d886338f4bc9a4e7ff2be7fa4edf0c8dac7b7317049e3e0ab5074e2455399743485017f000000000000000000000000000000000b1aeb78d1dbc71e2045ca6e128d1b8a924babb9ccaa48bae01aad0a24be8b1193646be2c0c0fb4624c4ac7f33e6d82a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a83a6a1f2e2a4a390a17a13e7bf3ab1cc227c7976818c7e22b111072cd7fe46541032c2277588c8f1bf58592c75ec900000000000000000000000000000000085c79123fc6575c8ae8afc068397bfbf49cedc1018315183d5849e3bef65505c4978b4cb8c8258eea326e024b8785161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000502e2682bc2d212cc7675ebafac2ccf6ee6e8fe5d56cd46cfdc1d9f65e1bcdba56650c3a1a8d4d545fc62600cb3b7ed0000000000000000000000000000000016e68923a51dad89f65780c9868aa7560970e51fc35ee09e0fec9f685673e52a25d4ec148a2b8b969082408637bb49d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180b1dec1a5faf0fa04b417ab9aa96417669d5ec650596a21563f07e3f6db060939f0357a52e6c874828812f67087f9f000000000000000000000000000000000292cc178a39052e4d8cdc5c3b35b5d907e082558eaa197fa3092c12a888dd76c4e5ab1a57c8208008f64e911217d35f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000485421dfce3bb5b31466f52a9eebf8de23d77b9dcb0adc6d67c9151afab181038d289422cc58e34f99f7b1034ff66300000000000000000000000000000000034e031556b96e0fd847bdad124be5505028bb0fe8c1a61f8ab5e1077fc052efb0ae1955368d762fbca554c3853d513a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b048fa6198ed21ef406c9a62caea97f04eea5b6ead3ae5f3651e60da6f670310cfa4970bad2629991f61350ea0259b0000000000000000000000000000000001635f552dd8dae543006214523abe6bd4a12e25563fb52505fdb89fc60553b9ecffd7e0d8f69e4ca2185008f064c78d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005c5eee11257acafe86bfbff9947f0956d1a744cc4eb9386d13ba49537f5c1f7ebbeb52ac1ae57f13dbc458eab7c4c10000000000000000000000000000000011ebb90f116c32f8031d23494089f78aff9c48864475e772e8fd5495ba0e76e6fcf02797fd4c349517a981da3de481191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e99858241af981d2bc129a7393b3bdc93478a278a5a72f290633bc66b4983a6d3b2b0374bf5d6595946902ef405e67a000000000000000000000000000000001360cd4d2be3a963a309e68d0d001a0508a3c85feecaf3be8f5f023e277a82824b570c1b644565d1c483cade402058141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000386b89402091048fae55be428c7ee6d00b921614242b6baefcdeaa87b2fdb9358e0c4a5a632450739281990c9142497000000000000000000000000000000000be5d7ce8e9377a98d52398f0ce9fcfd40550b35564c40a10ced0be046c5cb7704594ea175e93c159c189f5864bdcc941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5061fa5e74c6c01d1c20fd2c88f9ce5c11952d4656959ec39dd18c9bc1a0f8a0823df9184ce9c9fdd73e8615d338a9000000000000000000000000000000000e5422089f752f5f62df213d5c47d59445728f8fc1e29ff79c0c21e3d05fb7d831e2fe6921698a1cee5cdb59a197849b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151a67dc79601c44e752545520edbc37e176e3cef4d9d7fe67bbd1abd73bfc7e704e784f5bbc317dbe847271276d688d0000000000000000000000000000000011687a342fc0b3f5ef14a86da718f6d6d2db9b4a63193c3e045a3e67aae20126c018f3954b528a2502b8e7635af8d1691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095f7579d4ea4de95fad8e23effe5745d69cfcfeb2c28195a9d0141b88f999a42ef50548c293a39010463ba3b1eee79e0000000000000000000000000000000013914fe434be4ef6333641661672ef317a373f615c701a95323ecfc52b5ac5306f1564b4908acac1d92bea9467286e551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c90a6ab03ba1e40b759c3eff77f70c9362bf27a0b415fa1eac6f210cca9d8813c8fe6ad1a1f11eb5b4cce005f705c90000000000000000000000000000000003e78bda2bd69a1349a86405d436f5ee0595236119e1c6925ffb7a821b3faa4a120804fa70915b0f5289c88ad95626601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c1810f66c313cb5cd8329244ceb3e538a34fb5dce737e96cce8aee1042d4d900ab82831fd6e449e57db4bf603c82310000000000000000000000000000000003eb976bd84fbb7655773782129858ae8289c7d6dd08eb6cdcea047c185fe442fbe3136219216c349ef16a5260f5875d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b885537229dcd9e8f42e00e9d62cabd3957210855cc92a60c0ce35ed4d21d077cf353d7534eb1c46171942143d1ce00000000000000000000000000000000009a57128d7bc9f3809d05b8466f5310852e3b50ebee2029f35f76ab81e825e67299205c7ce9c558b53ae1a6850c20da31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001576d11e4c4094a82d6307010332bfc299be1b6c5f2b2d2b1476436befb061c163ab17deddb47f361aaa2be0a12c37f2000000000000000000000000000000000d8767c224837c2d1f2093fe7a352d7dc530f012a1f0a1ef8f011880ff3ca705b9d15284d1b8468a65cae94c9accf5b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000527eee0ff91b68dda2fd5d43511d20578d225496defc97e1e6f8d7897ce80a1b5d66e6dcce7aa6c374b209594d3587b00000000000000000000000000000000007aa971ea8f2942de31b5765663a479e2cb92d633fd2bbbff722da14db500e8b184e51b2e9f3df49fb88568e47ad42d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056d56b368bbb6f06439f124f3246e5868d12b7d11539ecc3b8547126ec40641859416f871f4dbd2ebdf3b5b48c2fadc000000000000000000000000000000000a6c7164c17dafc85d844da68d8dd11bba8dd45307d118a6d83dd79e85f0e3577b2c0af2bdb6bce47f632e6228af97ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160dffe6d01b918b0c468b487b005cb6cf139b946d66c718dfc63b273599aa3e5c3041b163d94defec5d4e4b92560f9300000000000000000000000000000000188d52e52ecef9fd3edf87b0e7145f8d4038301b58e45ea891c2c71212e23f5aaa115c901b169aa059e658f89ba21e0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000411894e35d547722b761f3275b400292b0b8aad42c69c9818fd3a8fd9fc8deb28769efca48059d20ac8d3f4178a38700000000000000000000000000000000029ba85e1121ec3b914df7a35db64d7b8480b04d16f57fd43cfb4e5d47b4c38f5b2a904dd471991823eb72c89cb091b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001813363c6e145148c114cd83ba38d4ae8274272e35b1432e39204431f2bdba50180b74e5b3d3c4cb198263243f412ab200000000000000000000000000000000027f9fae80b29acb1a16ee510d86c75a47bd390e40f2a639862130e3a34f6369dabf44205f06d5dbbe43d18c5fd27f731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075b3e2f7ed60c87a0c3e5f0cd2e4b06fb5b6eb78bd94e033f03ac79a8c8220d3656425c76cde8c8d61708a85113e497000000000000000000000000000000000e0d1924a92ba1133ada7d4a76aa4a7a5df51f46abd7d8228880c78ec112b09da61d8544dfd57f0cb62a9716395bb1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098ee937ca7dc00a8f71b3d020426968ad0d4ec0e06c6f628537c9c486eb047a2bc56316871f4aa3a2885851c4878dc900000000000000000000000000000000165d17cd127d262ceb7c18b79deec502173ca3fc1b06e89b967127511fafe044198898914ea2bd6784071b8b8f02b9231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035033ddba0c6a00a5246ac8dc7c662e5a90486fb184952498d7f269e7ba9402cdf1db237808c0bb1e25c20447fac014000000000000000000000000000000000e38f5efe637f8fc54e165faabfb58294d51569db89912ffa55162dfd952412b32747a48a5759d9c8b04c252e9e8624a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5fe5f0c35dcaa100d3470644f541484a8e928c226ef53c0786fef4639c70defadf416170de1039f4f542bc8ab1aa0700000000000000000000000000000000158cc9cc88a8a281495bb321a808bd202cf79d37d3f693b92440c60ed72a3bc6a999a9136d0b80a0455d736ae11a2d1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002683087640ca2f9cc72bc8a9fab391d98a6f77d2cf6952caa8b73113f812794779dd8c479c2e373ac8a27097fd3b2750000000000000000000000000000000018b8af4532021ca43649dcf83564212f53c3b6c13fc63ee2f6ac45a5aa4ddb2cd1484024c1835a46d655c0547999ad451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012042a79dd5d9082a34f418ae88b8fddad2249f9c6923a3c70cc28e88815f3215147d7eef52e93e50a4508ad4013a921000000000000000000000000000000000a68b33446e2a40e31ff43858c0d4f7b2909eac72b88bb196a8475875ed095c9bb30668dbcb6f815c700bc97d32aa69d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad7a60b0f9b798f9ec744f88fc04c05e8d3e4b20b01f0cb6d3a7bcfc00ccc171507a569a6e912cd8ea910ed4d1102ee000000000000000000000000000000000fe0f84cdbc80d3182a3211952efd9c80d906145b321cd609b5837978d6e4a8d5fa25fc5615a451ef1c7c263586f4d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a90296d49aa133074f79f104910428f9bba6928c9b7aafdb50e1f749eb54f46894acacbbd36ef9e1317226ac583c540000000000000000000000000000000014865ae3e38b87f26d9fedcbd88633dd34215409e271861a2d291a19efb1680a32ce6bb935a89c5d0544c6b5b848de8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062b20a559b3d08aeac6fc78507570224547478d45ad5502618865b0265c74f1e11379802ccba0bd1f63de5e58927968000000000000000000000000000000000d37355458d73c776252f2370a38457330aa0321e7e0c577fc8ffb0e1256bd02d9823a76b21bcb23986127c732e08f3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001352a9ea1c603e4831347a65e8d3e5bae73ced0afd4d716d5f8d61e0c0dabb59e7ef67a967e27d073e66412e380f3080000000000000000000000000000000011f3d0d9d53f5d1a9a10a343faa8287bc6bf63d21e556e8ab06e9ce7c0d87e524345fca6f9d0b7afd56f12877ec09e9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4085e3b29fdfaea8ffb95f341d71012b186ab31057d0ba84deca90e4ccdb8666d130a0f879fb4b4f4ffe71319aa5bc000000000000000000000000000000000b455673b7afa2a412cc2a4ce7f672c2ff56e0bacef9e2efbd549061c3afbaf28c7d665857d47c987f04641f842a76711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067bc7dc93f1fc5ae13d6cf623d9320fee1a6e3c9189e96fe571a57d2fa9323bc515ea201eaa3ff56af35bea4de74cb700000000000000000000000000000000152875c58cd8f0554651b874f00ccdfb51d06ac22175baaf8726a69985edc2e37e4537673d95b4f860806338cec715c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000101679a1704c083f4bc6ef8977eca52d6010a4aa716101a94e1f4e9e51f0e7a2e7318f62266b38c92dadbf03b8947ba000000000000000000000000000000001767857cbf680c1a02c527f2155b88a5d3eb1260f66aab848253cc3b22086b239070f91f64d77c177d82ba666d2eac6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000563400196e3b2bc30aaa9c0ab8ab0ad8497995f3ea7fce04558c827434cbdbe3d211cdcf1601b9da4ef31d089e6c4c6000000000000000000000000000000001580c0e650488c186817c53b7f04ad1e1038b7c1c957f6628b92a07aae88e524346d8cfe40e269c4a53b693a9a2fb1721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002422e90d3c9da67aeb6f487e0ac60b7948d766b37d318c72fe454694ab901c666e939b453e7eabe0afde69c5fa66f0e000000000000000000000000000000000908c99d5e8c0fa8382115ca083d3cd91d1a709878a5ea9023639f9dfae2f6f5f6fc86eec0543caa8dfb4b5b02d2161b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6f9e8aa323df1226f097a2fae52ceb646038b37bf7f30c7123185c82a29e083e8c4511c149b3cf15a6c1f48270e89a000000000000000000000000000000000c53eb2772b99e3ec63487b67a4d0c6e9db31199f1a60aa878c9181c28a9f3cbfa06d46afa47845c484c7ecd47fd1eb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c2c29eac81f5bbee9700b7ab0051843aa4f5bd2d785e7532e7d83818ad05b8e9c96cbb4f0000e4c4c57295b9dfabd0000000000000000000000000000000000475385cd89a62172a09633b2ad1ca5d489edd5dc65987369e9c86d2cd5a1cf7a5a17584b590be8dd04096eaab7716561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c40efe3aac2b7807948724ae3437de67581c4d0126028b74ec374572b75d74c181aa599936f5e3d2265eccb3b75c800000000000000000000000000000000104ffec118d710e01ffbd0ab625d18d823d730356ad3e7c1c1439feeb0193cb2eca3a3e3059a8452175edef161400bb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb6764f835ab810c4c98b34fb01bc5b87632aa36d97dfff6ba05011500e61457e8e77e7e3f9f82562e5180456ed676800000000000000000000000000000000087d8e882d64776fb8f4bf9aea0c0c15004a0a9f303eee2677746806f7197e21c30d996d7a728001b5a101a529742a681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056d2d37f86675ee5c7297f352439f2303833e8090f3a099212756cb6d6d963ce5cbec226b0877b7945767a7031428a2000000000000000000000000000000001591272b308bbbd30d682296a7feb34eda7d44da2953854d76c05954d53b18ace8ca0f5c32d5cebd6221271648c15b771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dc34329b06516d11bb7a98bf698c0b140caccb213d1d5ba130622087965fe2eca5154f4ba52fd3db944cf2064fa5240000000000000000000000000000000000f7572eef30eb62711d4e6365c52995d36e26833b249a3731fabe7f25c0481a78f460ef7a45e5131e2f7a914767877d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d48cded4e28855ae5af35fd787f8bdc49cd8dc58024c15e413ef0ab34b3a5e8330ab6aef621bba28806cbc8e50ce418000000000000000000000000000000000057416b2b9b29483a8bd853a8d9ee9038862d11b0822d9d8aa3f1fff71e5a1b5d58d7bfe5afee922818d4195fed74741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dff1685cbc9e9423f8dcc513e3c958ea106a3f2f800406569bc7b86365f10023e3d13740f1315dbcd0e1025cceb980c00000000000000000000000000000000128ed8907e2539034c7cde95f8d6916cdf4c3e352031419871887e9cde6ef87c57deb76a4712e9abc386641198d5825d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096bb778735b3867a5dc185de75b7732f6490508d0927f76748c300424a6638101bd253fde0d989c70d775ae99c95fba00000000000000000000000000000000161b527e7b0edb91c3eba69808042fa84d168b1adfb39549b3946ad04ab757c9ffb8e9a93da910c4a92b7bc7de5387e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136f63ec0c4ee18f1a90b36541914e5307c4c33f3f01e3ea6f4c12f4a21c6c3c3f82b7cddfed5cac821b7bf60ecbb9cc00000000000000000000000000000000196116911a5980d41397304b5e87cf54ccef10d76e21ecea42fc9d9247d7b63913b92c6a1d55fd8d69ba3174d14ba1d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000015b874b6d84bd5b7157e2a3b267e361653ede58b098174a22d6dec096572d05d5e4a2ad7e60a67ea6a3f5e5781a9fe7e000000000000000000000000000000000bf50e866245db6446e8a2b294f6987a9305f5cc8f855bf4e04b9707552307dc497f4706cde8f5c849f3554ab642ca35", "Name": "g1msm-2048-jwasinger", - "Gas": 4276224, + "Gas": 12754944, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a1730de8e6abe2efc1e10dd1ceed419d14ec6ec5e8701e17217ca974fa33741a444d65b0f8f59961ebb354c37dec39700000000000000000000000000000000023c960b709fb4a0789e2fa2496bdda7330ba40410eb959dd32cf620787b5cb52ade72ebc3d7c57ac62f4ade497e93111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001398a54c25090c1cf9eb94504693ba8718a8c40150fc47c24959360e0569e45a0fa40691b3abee78e24d55785b4f7c4a0000000000000000000000000000000002fa98a402d6470e1a14e7ce61bc952e6a3bd17816b25231aa0ef9be1da07dabebd7d4399d12c7a80dbb8f33cb7844871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000774f2bfd349b970016d57bb932bb43be2cfab127e2da90cd4d2d2221a1246e7efbf684097c7121c7c677cd1092ac751000000000000000000000000000000000093049f314f8a8b613975c9d3e16571abbebaab1e4d09efa6e12dc27f519b918b45990ecfb4ea41772d53ce78f2e53a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001122c9857481ad1b06a42e2d6e419563853538592d37cc6d27481f7505f5efdacd3808c3b44e47923aa5ec34e81ee23f0000000000000000000000000000000017cbebe357bfe70738d4a656f5203bec6f371aff0f777dc58516eda53792906ff31b824dc22d5594fb5caeb20ce0447e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d49e3f5a9959904c285b12bf0d3585d4dc32ce9b72f6918759c4cd0adf71ae1e10bf5e0976081906494265e881f9e5000000000000000000000000000000000dfd2340586ef9b3627e1b442c986d507fac383384da9da504678b121db9c0400d2e5445a86f3981885d0bd0a02ea8201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001065f05c75bea3129a55715fe93d4afc347a792697720e96d06b08697091264d01a2372904e47816e458ae38f56203340000000000000000000000000000000005130ed7a8d1c1719a9c4982b0a0e61e08c59910e719e5298760066edce86adab6892d18d01df7503dcfeead616c25261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153b75e97ffa9a7a41de85b2c413d1f2138cccf6e27ef3e3f3ece12340333204843b4c2c2e8b86d136b5c6c7fb30df110000000000000000000000000000000009914563dc40520452f0c4456133ac9eaa2b44014aedef3dc48569b63502f8f298c71aa502c72808a1cae66e81ba49621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130ab51776303e6cfd0cc3ae7566aa24cd2dec7dbfdd06adc50a7f6fea630958defd538104aaee0b00f7b35d0773f19b000000000000000000000000000000000b0bef4683439b5df92dce913ba9c55672fe2641d59f5f6e51ea85f33b3c69eb69274de5bb0d97c6973ffa51c2a157271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac37695878cece25ce28edb58dce9376f6ba1cd100fa1f958bbc0f3e9d16486948c83c8ad4a13c03dd533b2671ada84000000000000000000000000000000000b9ae369196cf33149389013ded774f22b779b834771a77d02ba5586d6510f0c160d2885637cf91900164fd9b215b0f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a2c23c761c3e0097dfb2edd635031d99bfa9d8e44755892cadbad078e2081056695c00934a38910de92f32af53e3d0000000000000000000000000000000000f32fd7a71143553af09d0a45634b449a5f100e492d710a385b3c4c4ec589784bf6b0e80d8c36ae26bc4bd19c12be4d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c2aca4e569bfe9c54dee9413a42f96a69d3297011e0634ada6da227844263a74eef8cbcc9100ff7c0dce57f3d906140000000000000000000000000000000006556e5837abfdabaaef168ec47da7fd644ab9701074f6e4d429986fca50eb9188feb6b9aca5837ef78fa396fdea79651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f10d835345a0724804324f9df74d6c0a1744965866a464a9f21c334a7ca76150423a5993c77c890357ee038db7e9360000000000000000000000000000000008aea7e714c796dacc479d89a5e3f62d0797ae39132bffb4fb8a1188dda2be4b4d59dd992453f709367046c5f95544621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa8473f7f71ff2157bfe94e6792ecbdc940b63820704c0e0c627fa159693f9668af4d247f4d3af9521407c1bbf3dbd700000000000000000000000000000000098f74730f1624d709fe7eaa0fe019c0deb4858bf1674095c4437ff67549db429d6d82e6adcdcbc9f2f2c7f29ccd45e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e302678aa16a3c88bc89d5a812abd0b5f22e33f8a65ce56ed9a08c8c9f3b963a6d87f343bb435af7b8ee44b0c2439000000000000000000000000000000000078bab275c87423fc7f9d0327d543f66d15c1c9847ea4cc60a0f5cc4f1fc4555e86638f8563addcca236ddd2f998a9f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8d4a91ba9603d51104a6a47ac02a2eb4ef6535a1b3395d6f4a11e2c62afda1be2342850f74b316be6c957fb2c6d9400000000000000000000000000000000010c5b48fcf1f6a832046b11befbb89fe9729391caf395ce7f38be6188f55259e0c414e2e4783290c2d2c8a534f9a68161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182af9fa2929fb2298438a3d9512493c7089f11677a68260947bc9a624fa2b8ea1e4a9e08c288ff4b2f383f8a122dff90000000000000000000000000000000016d28fba47fddc65af954c02dfc5d9cdddfb3f9b0d6652639fe86e919c3207dd06426042c92c6ff480e195e405d743391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c975adf0433578398db50f567a97e27b17e89837dfe3f30cb6e220b810be1ff1aff1d192724d5ccc378c41026b26f70000000000000000000000000000000009e6540cd564d6a0d46627ef833d46c4df2cb4691069257fb068bd793f361a7992ee39314a37c148c26f4454fc4e6d8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000360c05b68d18819d5556c49149558e7b02814506e386d943789677c243c7a635f8a36d3d6ec465e0dc6769356813b5f0000000000000000000000000000000017139f82f4c15f64e8f1be020ceeecb0dacf0579094483ce84333bfecd267a7219cfc9e03bd148ddecd9419ff90feaab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7d135883074547c37e5e92c929e510ffa66020c50ee332a77ecd27ad19cf379dd769a134ffa7e2f0886efd03a3630500000000000000000000000000000000198895a37464291134dd59ccadac7a8a550da6b4af64d991c465f007b2e287c9a7d84dc7b366a3b57414f5b74a9593e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086b9e3b72ed9ffdbda1c87c9d84349c6648a028ba4be9fbabf02e3ca28d6ecf64ed3a5d435cd0d640857d63f82f3ecc000000000000000000000000000000000fe64c18a9b7813a3b71690607deb267436114fdb23524c2c3e078efa5dd774af32d1dd4f86eaa1f8cea26f06b6b98f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081bceb5b09db69aa9a6c89394828e3ea221afbb39ddac67b01fed5ec408901039226320b24acc501eb9668dc6ad0886000000000000000000000000000000000f86b25a356066e8f461047104efa13325493945a287fb7c1cd916b968d4f60257a534398bfda135090ba0687b74be1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b60efd3515eb74330c47b364aba0de8df518563a6042779f4bab35b3e3cd6071c70ea95e14ff4343d52777b493f113000000000000000000000000000000000fe88fbbd16a0d650bcd2e449cb45302d4f4a65fc4e6beda5b7dfe9d5c82cc562cc00fd0c6613655da131217ceda27f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cac4f34fe4cbaa792793dc0ad73f5f320ac9572e80d25cea8fb37fed59ad191e53d151ab94697952154e44e82ec60f0000000000000000000000000000000001c2def9f22510b9de82ec0bbfefe31a3d539539116eb62f0ddfa14dc85d8391387159a53215f7df86292215c0ddc5cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e952333968cbde29ab5432bde7428d24827a51ed37649811a9a702f238b676d7565d4a73ae761768411023d8b43cfc00000000000000000000000000000000074c7fab6efffaa74d4a5ffb6b389ec3d41acf99cfb03f0f9f262884353c4c8184440c720551dcde08db4d024a6fd3e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181ebee92127b88fc3e45f1d4c113bd07a0c742dcb2ee7a5942c6e965bab8ec9e6fe0348bb8d96ae551c5cd2b6f00379000000000000000000000000000000000f6cc9b1665a1e7be035eb692f1d220d73b62655f3a2689a757890bc794db261d53c58e656c4213b369e10e03f56df171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016254205a057a86f4be8fbe0f13dcc0bf1826c5b587f143bd2ea7e7e1895dc99702a9029b5941ca7722e301f28b17b6c000000000000000000000000000000000ff97a0e49189b70f26b6a70ce316d450cca8d0f25da4c44d239d6d8605369ceacba152248855a76c1b6e104d44d27f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153205e65188decb59c780508f6d9659a4d341214138f414f367af6491baa85e5f8b0b863d211740a15a021149fa808700000000000000000000000000000000177bdd9a2b8fba59839a5e7f6d4c88ade9cb88f8aafd3c65bfff84f664a6fa2f69cb1acbe05abd2e4ae85e08160a79211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dae18aeeb8bd44ecf858046a9a737cb560db4a49dc72009192b348fa2c8e583138257cb294b28b47d3ee0c4e62d4f35000000000000000000000000000000000d4d7e883779ce0e3b2a33fb837cd908369fcf09de40f547792ab5555a413af9ac14ea2c23e22f3ebba4003bf356eec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ebf7d3fee2894d17762ee6564e2105c0721c9543e3dc6103ebbf14b57b238e3211c7225b94a90cc4d72bbe8e1e0f580000000000000000000000000000000008ee85f223a1d131a4915e9bf09b400e5935c28bd08575612385e19c56064e1d8eeda5c62b4bf363240820d2cc1f49711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d35c4dec0125f2eab6caff93079a923fd2fc72e08088c258e02c429ede7653ea97cf8b8935ee254dc45cffcbd580b7000000000000000000000000000000000ec6c19d3d4801112c8b510bfd80c63c533e316f715b603692e7630a0bf6fa4ed246b6d81a259aed3f8bc79044d491391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147dfa0157cb13b4754101921c44ba948237b5113a4bf30587825598a00c10ab81c5106aea824211b55f494f95047d050000000000000000000000000000000018945753ba687426af1e26702e9c0cda4e96da4e269f745284d0ca188c60432fb7fb6740e1912053c04176b1006383b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d36c5fde7b87c4e21bbd395b6a77604cf7b5dbdb73fa99d2cfaf9099f9464839c11ba868f061b66b26e6e467aee7d00000000000000000000000000000000029059e464905e61c93a59d6e0112500306b5533bc5a99509806bfda9b99bb5b2f800094778c74ea110d700e0d22da631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a7379d9cc9211a9e81c57b5e0122a4f2b18277711db3e9e0c59fa8afecffd81afc23d56b4719de86c77588b41226d5000000000000000000000000000000000e99c9c166a36a813fc488c00d57a3f576b39954d0074f240dc7a5cd1103ee6c6ec515e80a69d41b2c98f3f0e5276aa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e44a2b8cfb96138345fc79ff62df105ad53e9d2ebe94dd091bfeb320902128d3453e80c8b26f48fea29c06630704967000000000000000000000000000000000ee4155f63cba0d57cbb9c64e2470ebcab1e38857490063c737c05ee30c5bbef299ffe120d3dbc9f9c95ce4d0d95e2851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e8ee6b6db540c3d7bd0a84f50b4588237e7fa27ec1989af674d6d7de150dbeb16d96a9ce2134d512bd47e0b8303c07000000000000000000000000000000000ae06b55cc2f14404c03cbbe344499ceb69d9e1bb7a9f0747c09223aeb2804a4ace3b3ecdfd48608aa90c11cdd31fb201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db546943c02edfbc05886f781a85220ea3faffe1f740892dab37ba51d711675a5b7d5a686c3b13decfc0f02898abdd1000000000000000000000000000000000b4823ff38f91a33a7f906ed6f433c1893544de606b95cf7b969c08ad7596fd9b8c4931ce1117258456a7eb715202a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff950089c390ecaa4be7a475a1d8498bd52db0d9288025ced228be4a5c7d9b672c6200e24d7bc000061c1fca2fe8bf300000000000000000000000000000000039ec6c37294b5a6ef6e124adb86f9a1e44224b0a986ade2d6c66a1257d43a144cbf591fb9584b2e398cbaa5e485571a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001681c1a8efe90817e0352b115381258d5f860c7fe7cc2636b37c0254cbc18b1e06b3eebe0ec079aa1a9875a3a14fbb9f000000000000000000000000000000000744a25ee61d8917d232d0f5b680f94053ee94249e5aab6b895c7a63f14c0fe0bee7991832b790c42d4ca24ccb3063701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014673a362a7e58691db22038440b359c80e7a9c3089457f65e663a10ca248dda03df99a73da427f85c217f2b9e82b9d000000000000000000000000000000000090decce0b5d39cd91d6092f1d2684ed3a25d652898a58f462998dad13dc3509aeb4e6a93ad990d33a032e4a4b687e7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f37d09bdb7575434bb7d8b81d8f4c7224fc69d861000ad95b00c9c4d96a0c03d1622c958cadb6278acf7c62b1b578c000000000000000000000000000000000658ed63a89a80b4d12592de824b695cafe884ac81cb096d5651c770ff854be188e7c4b4b6279f132f67260765ab57c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bd8020830748f5cbf7aa11d082f73b829e6a6a1e253d777957fcb7c69765581b5ee6feba52529c40a6d5fba578a5e8000000000000000000000000000000000d450a421b99895adb23e113b0dff1c79f4a9f477bb800d288a84f8a3d234e406f17669147aa83ddadfb80cff1be754b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001654baed6e488143ec4867960d4346d90c28062be20b4deab24abcad9d707819ded944921129e090604cb1b6a34a85870000000000000000000000000000000019a22e7273bf6b64f58678b429b8b1f104102e0e9ead9ce2660e6a7610626c6f16015242a2d29919d36f518a1b353adc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdb2004cea1819d33d7c28c14a91e64cffc6a9c2836210483813c42b0621e3b7d56af8d72728e971153bfcdcfed2ff0000000000000000000000000000000001369d94d084f00b1d68a136428e11c659034e71216ad058ffb65759a9862ec21e0a763fedca6991c8d73e3266ca563931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6263bfc52a439bc68bdf6f38a105c455a0b5d0eb604b3116daf466a7bf9a61151f0499316dd792f56046629c5ae70900000000000000000000000000000000058406f8e3ddc48776e67a3666467a2b324c856d9b2ff04a3a179d07b0d2e935c5f4a4b976dc5559e7aa1450538f548f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007de81224cd5f7789f5622b06c9cce12e7c242443468168f11ce98632ecc68644be3654413c54a6b07b405f6dcfabbb400000000000000000000000000000000184438db25d7bd4ba14f7577837f532c70a50c5b45e60adf175b40df28bd77ddc06062e9469f84e092ba1c1e4b42bf9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f84ef89ce7c6edb4b44f78fced7e2aee2d1121305aac0a2df912686dd263c3d6a59eda567d304967cd9bff970a18f6a0000000000000000000000000000000018b44e5c2e7eca64d221d8b8853a20f60cb029203d547fa56541d9e212361f82a6dada13163155eb524670265ff6dcd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006998500ac726d1fc5c31832a10266e232873543a7cf23e9b6a85ee41ef436b3c25feeb93e2e57dccaffcbd2c52c98fa0000000000000000000000000000000014edc9e79d6e17f0a196feb215e6b317d9ff074fa1f8a3be2d33364f4a44a752e5e2c344e6d8d239581dad316474a9ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b19e7db6ec5c82ae285f779629fa71aeca960b9d77d3ddcc0a7253e3661b20827a778acb2c8d2807ef87a9106c145100000000000000000000000000000000137ea0da2e655a86ebb40f78ed84cb51436158fcfb901edea8d3b88226bda84aa3cd7510ebbcc7fb871e9422a66a912a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003421b8c520449e2375f8163e0abadad80a6f6824d9a343f47503379a79a907b1c0a0051deae0b6d7546beebf4e118b8000000000000000000000000000000001722743e81ff6fd370d3d16240bb3492b4f6d9bd05500be9c0111309e7cfcebf550953dd3e8b69f68f9b4ea007e810cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c01aed49707be07b752b7eecc651d765f6c3dde5bf7d2d15d038aa5c4c86fd0e576f603e13050170bcfc7e9f9cd0074000000000000000000000000000000000c7eba29b7f8b7a2275f6a753060e345f7dc2bd8ee808a6f949b36ea3af38018bc5ef5ec17082a4f905612d87a8fc7191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000eb5caf92ec1e8ce05eaa246eb1b19f2c2973e85a2b65a1d866d9afe2fd532bb6aaa5c7225e3307a6d199048fbfd346000000000000000000000000000000000c089b9d16b9e1fdcc8cb8be316a85c7f81bbb31db542532ef0a60c7de9338f5800463de665d643b4265ff9cf9c37d041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018550a0ac6c00bc0908de8b8b46cd090a3dd75634660dec25642f7fe87abdf726310ad892c54468ef68a214eb1ddcf30000000000000000000000000000000000e70c9fd778849a57b1d77406bb6c02a20991e6d497f64869ca8822ce16a6db992ead7a7dc6249020657a2fb7b54cf791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001323fcaefe5e291403cc07a0407cfcd9b59e2d62e321e7359c778257de88f895143212248418269eab5a45a4235f2029000000000000000000000000000000001880f0ef888bfed9f284aedecdde018fc64f0fdad9bd75c9780c0ce3475faddacb623827e7f3f0ad2903a4fdeec0f2d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d56a5807b826f8b5da96c78fe403ca1582988fba6b6d68643a77ff796d1771c2398a7ecdd38db8e77eae1730dfd248000000000000000000000000000000000111d78e1f8d2a2f2ba0f1a4272097d98f9a65be03b0f4c74f48d7fb581ab5bbc233db95ebd5475c11fb47094da3b811c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f845c4863bc39c257f89e133e200a5a6f9bec0f1277aafedd9da8e42749a922abe7ede0b95f6fea78e867e1c3d65a560000000000000000000000000000000004f9c3dd53b5cbd97a1fa5cf4e0fb39d815bde164530b7ad394fb7a474f11e57df7f598c4aa2a2ffcc2ba9f582a1832f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195bcfa7f6e92a6db605bc807c16d37e108fb53c93841f01d90ed188ec74babd08e511a277aac4a9e4ca5c9329d225380000000000000000000000000000000004dfed8033fc3968dc99e476232f3cf015052a87e7fbcda6f77c66e627543da9e7af7ab32d8f10a442442da09255ecfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9aaa41dd733fb0d2947c084eb636a8b12cc072a7b962f1f013072f713b936bfd9356b1fb02bb4e94e2efcf44491c950000000000000000000000000000000003c8b2cf351047a4511c1defda2fe5c66b3252ac440a188d5ca99616e589d21de9c56ffb6e2e691e5f3fae026c3d15ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018196f98b6f873906713e25f936aed219a7b040fe2b5765652cd1453ea1444ee116e8114a17045bda94b82ae1d14e8c50000000000000000000000000000000014c11a6dd7d70a53b7b8ef57b68afaa06c821ec1abaada6f3a8d7b9348fb38c97fd23de77c725704901aebae124633891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3be8b461344101cec2ad95490c85409af78a9d56cdc0a76560278973040a2954d90bf47ba69a8e38ba4fd0e6691e7f0000000000000000000000000000000012cf0251e68d3308c471ccd3d8b6fc919dcc70ff525729754c40cb73fb8d84693e9b6a1847a690853183ce42301a12081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a757b0063fdf78ec95ffbf93b97c28111053657b3276ec886fc75342ae5a54cc30e947aacc3206fcc06bf31e61f93a000000000000000000000000000000000950309f83b564d54ae193df4ffc000a74cda3189a8329663925bb73cd1757096ab5e2557795ccc6ede40995d8b4a20b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa73119e29e042a756c2eaef97c65b2087eaae3af35e6f21316056b7b896576f62a96cb42ce7de22daf863e6397e74f00000000000000000000000000000000100fcf4558f9f21f0e27dc7fa266e276db08864aee4556b9fd71938010cb5dde58e8e17e30a58dc5b177ff57236dd05d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058cda6a99fe3a61fb7b3966f93c246ddb214c662d092ad624c69838c7b1e8957c82c2a94bb1035109eaa8b77aabf8aa000000000000000000000000000000000b626cd6fe7bc670df7c9941217cfd54cde93549b765cef6887d36407d12c2e75d3a23778e98b89ab0cde710589368a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ffd0b660874facb3349894390d02931f06654ce0132d951e888a3ccfcf48d9b50e670e2bf8aaa55eb471e4ad1ce80a0000000000000000000000000000000006fb52bab4a8df567f865785aa76a40c95d7a3bbceeb733c994d2d5c906d15e6563bb6eef412d2434019dc77f10d0e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090d37f7f7cb9454e6c6c4e5b32b04f5bb7abe2c548c954e0a5d3d2474ec900c0c6634568c981e102a3910b4bcd7ae09000000000000000000000000000000000f4c244fe24406770e84efa931f19020cf41cb2dea4e289e705c15096b1c150b76b3adc7c35d5fb6261c739f66c412bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001efe87332f2e970a2e7dc406096899daf01ffcdd8ba5b5876254bdea4dde852f42f24d315e27c1a1f02c13349cbfd17000000000000000000000000000000000b233923c24921a4e182ef9d9bccc4781d863c9dfa45dc6ca6eca4474cb467b67e5ae593ab93a2829c3116d202a81a2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008aa3f76745a5a17681fc69dfed95f87a47795a37ac68e89a380317a2157d66c07d98f48363a135f7f2343ca13a8a0190000000000000000000000000000000002f7d4bbb0b25762fa1e670f206ed6b2d2fd0971760ac4913ded8a6b2e744811f9ea986fa54706764103ae69e0df2d171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e287477f127a13031865cc2cb5810df6bcf48fd6cd2e3c9f51c9e274ade5be4fbd02290d2fd64d80d64d6508e920180000000000000000000000000000000002c030c1bb7600a63cb879a999c86ee793052cabf2c34d0305d006eed0d88b8e807c4665ccfd162c502871f2e285ff2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117a4b8f5f51199cecd6cb7f26bbd94da77344164676c7720e56b7e8487adeb93e96bba98d919e68ad959dfc77a00626000000000000000000000000000000000f0a5903482513d6c42b55b9c70d7faafcecc95217bc62b1cc0117fc42916bbf314eefe22b3e69e4e305988e7b55731c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ada78096c2c59bc8dc24bdb7fec70c87ed8c274139f5e6dd141ee7d293204de560546ce5a4d817d175cbbe559e964ac0000000000000000000000000000000019d588facaa929d0ebb94bc08440e25670ca985eb148eadd143151407cf0703cb1abda2aa4c832598b8383b28cde1d251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106bb1c9a751fe58361a83bf04898505bafb486c6f601e57bd3ff91d49061f91c5c7d6e5cc0b1d2c7603b91bbba8b306000000000000000000000000000000000d62258885339094c6ba81cc823df6f14b94cdbfd5c5334c7b5a01944dfd19ba97ee13dc41be72dacd9a4c4507f52b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfff4c4927eb8bc279b63b98e63aa4ea94d11cdd485078beaf75246a5eac706c7823a794b1bb1a125ac197b96a1bfd8000000000000000000000000000000000d11904384f429f44ac54c3cc980fd0ea1a5eaf94d41a32b0838b8e748a9eec524b9d498748d51f4dc7f4d5f1b088bd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e3d31e0090f4f375f6057ea9260ac04b2cf6b5da10e0327793b621baa16b67cd67f5afbf7b3f38ba202294cbe1854a00000000000000000000000000000000000630c5e90f69cbcfaf17c151b71d44f7a430cd22586f6b7f436e878c2b5010d4029ffe4acb6820b6cf0107eda5b4651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138a20d57200124b381a9b7ea17d8e4fd82cfa596e3efde313313d28d68d37cb0736f4e9f1fbe1ab977d6caa6de7394100000000000000000000000000000000027b8244d19dca38b351c6d796c8d6189439ec8aac3aac523865bfc1bc7c0c201ff5b0a05d53c63f144802995c7f74ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006694a0c70f6d3e245d157cdd52c7d0e7cb6274db04b7f8ade197f68a13387b8ccb8290cea14047f523722e28fdbb08000000000000000000000000000000001726d95af877344456b2f2c053fd92251a96356012bc51a365bcef878301f56810abe425c82feef61060ed0dbf1c35311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066f6abc564621898361c5df6a4d2ecec002544372896237e967671981747e23d6b84d7da24f1cd71434843af6f19d7d000000000000000000000000000000000bd41dc2850bc17dedb123c14d4a505565a5202af653b5b30d7a8c0bb20917ba799e387abe1cc8bf55b3872994b57fdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000feb28be418692ed131339c3392e29c2d1e30eb34c11202b57f598abace6bfe22554548616c93f0e3a576125b9bc4e4d0000000000000000000000000000000013ea5f992dac7b82a9df4173203e2201f1b8a05f851462befe321eb83a3aea62d53ca8089c0c3588c484c519429e58e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093475f526633791d50a3ad6bb6dfb31864a924ed126830eb394963500494dd63eec3c73e99cc61b4a8fa44d261df2b70000000000000000000000000000000008a3098aad0646aba714b7fcb8fd862a115fdfa8935220c0944ed999774b2c0628ad4f9a10e4f8e54f0f6ad677c571b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147e63b348cffc21ff8ccf80fa91b680dbef325ecf0c37f68a7d0292305c8ca7beecf20244847f7ed0b31cd01ddd7e4c0000000000000000000000000000000016ca25d30933b25e3a1b5bae19b3c99423d9d39f7620456bdca480a2cc03638fe276d43efb36cd739b2ed4404d3b70c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019686d10d81dd91d945d77118a738c7026cff7f7ec8f183867acadd235bfa822c11df722a91f6982a663412fef2a1078000000000000000000000000000000000205386d7c022df1ef1a8ecbaf778382cf9b89e2472d4833f2a82b4bd330421a5f183aec4eddf3a6cac10f7046b097d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000822bd0d953f849069f198c6f2c57d81f657cf2070eee6b03625730587d2f790df245161ee35c91e75b6dff3fa8db488000000000000000000000000000000000e174c58799ee4d62e60e0f59bd199927942548f06f5ca3505165561194ac48752c43154e3778bce7f5df50858908a761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6fa0780933322fedd45076a6b8ac764ce833686162d473fcd210d21693a762c7e07ae0a59b2a26deb56e98f7b938d3000000000000000000000000000000001585ad7dc6293bacee6ab52b71a7bcd9d4879096c03c446f7090b24755e67befc571fa275bc86ca130030774fa8eec461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a69f8534ac2c82c184894f659d223bce01c813cd9c6446da92f6a1681add3ef2eb41964d8c72baa0c6e57aeca19184b0000000000000000000000000000000018be90b9fb67dd1f3ef8da67535c8bdc226e58d5a1234ec46d229c5e291d8b0481dd6f8281021f2a4cd525505fba98f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a38216151b9037db9ce417bfb110a501f96579e3cf65b3ee00ac8274e032efb3380aca284b51822f3d0ee5323665910000000000000000000000000000000002429a98a8c541c213f7a0b9bcfcc0ae76ec243fce7243a0e3ab5a319458865de187752f06e2b32577cc9992357dc2d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f50898587dc3f9f6b633b65511e20abdff5152995554f9557694a29fa637752b996c6bbffeed64b63d1919df00644be0000000000000000000000000000000005368cd744cf84e869347c2796c1d0a08314c0fc0955d7514448c2ff967ca24a104de7296b351ec90f90b62d7fe1b41e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109c2c15358574cf99cd2a0b6e3df786feae5d2bea15459060dc052653fdc0f7db1e7f644b17cfe2cdc88a5319dca2c300000000000000000000000000000000199b1fa4a1a6db6232f860bd32089c6608e114f89f8752bde137363dcc90072d6e844e1579de413238a621cf46dc8e2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126359d7ad7373b5a2099c0b11e027267578a8c54aee6831999a2404afdf46f6d327e1cd2470f53a0cd12249e22e31ff00000000000000000000000000000000091f71b271f3e7f4f2e5398064273bd28b4c8c36d8d19749ffb0afc9a4a35abc9466713d7b8e9fb7869661745668b2921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d6baf01617a330b5c0e723cfe7d355f259d3558028cdeeeadcc07beab4a8f4b9adfdd9c31015c2daccb177428d84900000000000000000000000000000000007fe48f8d3330f228b742e146cd5e94fb2a4bbd881e33438b15d79f2cdf15705e92d210ae8122b18115038290fe179901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001005c8fc3c58369968d65a12f90203f91e304e0f09c51db2c82a06acd3fcce96b9813ca4d55ea3d14464c7b1f03b0c550000000000000000000000000000000010a6359aa1c2202582afe05b52df0a78f98586d6c7f5ab1bfecd0a0705f6dfb8011399a568ee0ca123ce9ecd5c2c0c281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2dba33bc1c4ab9fb8300a9a66c308e4f4e939171f998f5bbc9958b1d3a892e608003aa26ac84270778fe9bd1998c65000000000000000000000000000000000da5cc256f2ebf9973e932db0fd6d72ab119232cc63a7e80d8f44e6d3212f0c955a01b4d89d23ef4fdcbce4e4bc323661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ad45352fdf06bd7dc1ce87309142200ae276a34ef084cbaec2bc8a168b4c3e3c01994b2d17c64e16834af2bce86dc40000000000000000000000000000000014fe3fdcf40ded42f2dbbac1172a4f2ef8db5338df69f4ae4fc9e3f6776c27d77264f275e97d46a89c6ec92b863504d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b238b26eca9b1b156356473581de6ccbe600f6ed9809669963efd9e5b683ed3669e6bcbceca3c74ba1c7f840d015e2d000000000000000000000000000000001128ae0585912592cf9b5144fdb08a0284274725e06ecb2c6d6db4919466715c823bc1fa1e77ac368d62d984ade366561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121e83dd10c9115eee656f89a7564f6d529eae87a64a898cf1e68e1e7e4629fa202bbe881b9493f1b306ae842b7c7eab0000000000000000000000000000000016a2feeb4276274f0f6f8d5352644004935c9030e6a0092483f28d23e9ca051290c5d11df3fcd25788b8cccd1905eb791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab46c7de183ee87d63d5de408e28dfa58466ffd9cdbef534db106b993224afaf7f27b4c948297ae65c6292ecd19c9cb000000000000000000000000000000000d5042690d0524de33d68d39c2602a0d35ec63fc4e4808708672111ce7035d8cec375b47c42bb477fd3dd52039248e411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d88024893aaa6bbcbd3cf1a4e0c55deeeeaeab60e31e151eb62eb8da022b96fac2a4bbfbcfd0b648b6067faa46b35a5000000000000000000000000000000000b427e8f7bc5dea9baa0a8f7b1cbb8fa9f642a2644b266a064c789b7acd486b3a0814294699c38644db097169819b74f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f42889caf073db3cf184c227ddae1cd0cace401edae3c1efb75b60ca8b3f1c46f0c235470b951bfebc18fd48b47c8ea00000000000000000000000000000000155e01e3e3258df3a20a431f36402731ad7291808a6507a6f37c1b7e0ec8095a5b5582911eea4ce270abd0aea5e3dad51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f07c07905a272fa66dc12497f3592bfc2fb7578cd27545ef2fcc73eb43807b8b019285f9be9b92cda37bb3805c37d07000000000000000000000000000000000407edfd4ae2bcc499bd43a04c4435222c9638979ac8eb9aefc87235a93219f753710011f95a01d4de0332042a5cc3b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb3795f68bc388665d4e9532e2e79860bbedabc7db77acf2dc8c73eed24fa630c0d21bd1a0a44bbd0146cfad6bf167e0000000000000000000000000000000010bdd266acf71c79f27320da220d5a97b238f0be7052afd32d9785785e8382bac411597732bb647658fcb344bf73c5a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086568078a77b456c68175fa5ce8e45d71af32f145696fcfaa48a48c64b46c667ec8080ab39cfa7a8c01de8ebf53210300000000000000000000000000000000122cda8d2dde160690622638b3d1b939cbec1e7dfe9fde774f8b3086e95e5444cf8e2356009363a3d20be756eccd6f791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f2e6fc0f5ea0f0a752e3791ad26dacecd293e6a2623402dd75b736e88dde4fb1b3d306e9224314750e8c402ddeccdb0000000000000000000000000000000007ffc8775122e562570d879a6f0184ec9b22e85a0eb7bd6ff17b853fdaf1d7d095e14aae86a1065ab3f228cf691b489a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007654aeb4e7ec52af3f171996a3d903857be38682e6a2284967ab0c4d4c4475392576f0be00bbf8fec1ad731f276fc71000000000000000000000000000000000ff8bbc7f8c348e3399dc83b8f721e78b2610798191ac602d83cb1bf67e3f251be9321941d8d03a9b99dc1197c81edac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003487d000616ee9475c8d368dcd1f39e449f87267772dc76dc1f2f2e966392ed0f663f9a6bbbf0763c6240fe9edc186a0000000000000000000000000000000006bad4fe4f85b85559d7e1906d081fca82f9e2aa1be0abdb9d926711f15c219d5f101e68d43a938d520f0ad9ff58f1101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e4075841bf11b459904b5c37b27e6f1d7b23931dad18a9c381c875a56ccc3422037ad44af8936fefaaf908771676c200000000000000000000000000000000031115fe1467eeb33a89d6b4db05f4893d98cc5fa72b48e0cfa0493b13fc0f3af393b5bf79adf88c827152c2257f0eaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d82a376057ce587a4bbee669589ad6b0bb685abbfc79c7f0bcd3abf64a9321b37db7aa4fac9c397008ccb20b934b3b400000000000000000000000000000000027a1d90ba72c6aa1f77bb666e73a953c6c461e0ce1777bbbff3463931404cf4f32cfe2344f17421213a66a4223870fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013237a815a5e3ec7f7bca6d4700a76b69b314356b6923dc4ef0c6046460239890bc87fe01509108c64ff52a17e67d52500000000000000000000000000000000081a70f4d256ac589d85a5884e346e45178e0782b0ccabba7626d775ea8e9def6b818502345f0453aa38f05173b1a7031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8d10eedf21dda2f003c9cf671b10c607e6c2ea4e5103d92ef0401d4a6783e89fb9b3e4f01c2f6cdb42dcf9140df6ac0000000000000000000000000000000003861554e6c33f66e7fe7cf5cf47a2da67b27f52ed3d9eed70c5c044022d1a826299eec62bc04a538ad10079de0c2ff41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000deb722b15709fc2b153b28f396bfbfb03fc64a6e0bd68472f6efaa27b0db7140b812085d385c0e5b60d64ed8143ac920000000000000000000000000000000019763e324e37dd02030460204157339b4c539e9884f23ec1a0d351d4a56b8cb85e05ba2dfe80caa7bc2cd075204bfffe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc233f2fd0bf4a89415dbf94f4c67b3e59997a4b59caa56ab6b769a6994eef21be40a54705a9c0c05ae4c805d2437b60000000000000000000000000000000001935ff5db947e299e140dc7be1ca334dbc69e2ad5f8387a5e151d6cda96d52b388c44a6e515d1b581ed5d2ee8d74cd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e2f66835cabdb01ceee27528914d0f52820a1cd0a562d9fa953196cfb0c19f1864d7ab9b5cb128b6378caf6d0da5f9000000000000000000000000000000000597ed5c9ba5738781848b3ad3cd771a4c80a51f7f1ba9610f3c3814699f56db7e42b4c2c44181aed1af7db04f203d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a15e6e1eda7dfe5b8cfe7409c5d5c1ec9d9d5af490ecc3fc5782ce61856a974c6b4771eb6a0af53a8cc3344050bd682000000000000000000000000000000000b7226444d71a04a35d3fa17db43207b8fe84230829802f45755f65a08a3f3102914c0bf92180b68c3835828f46cb4621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b22a41232cd2cc3ec669b39028c918aa6ae5c5eefa26db673f57b79dd1ad2ad49bc20f31c955f98e54b920bd00c9240000000000000000000000000000000001e700ff144fd4939b405fab8884ecdc70c936deeb112830af7f84ca02e1470d3608e1d173b1330b4360071a00107f5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a5bf3dd1ecdc1012f3c481dce96878c626c28df1fb55d400504e78d0c6e8b00281c9533527645d2cda17bdccc5ff7c0000000000000000000000000000000004c71650d0fcef16ae357880aaa4294ffb2cadba82e3ebf85d8805b78381e1c22e5721285c758e1af8073fe3fb6696691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7ce57889917275107b3280e368a4bffb3fbe0edf43896d4f06467668ee0bed164bf1c1ddb2460fe8c1856646a0444a00000000000000000000000000000000141ea944c806798ca3e0053f0dc803ae1f0be4b33de805df15f3f77701a427d6a0d6d715b883f4dd9058de46631844751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1189e9fc194b8706fa5fef300127173797c25e66adabc890c6a3b9cf69e17d116059fbd3651b65b42a781c60376dbe000000000000000000000000000000000b32e512e679859bdb77347e5c4cbac0a012b3588d1a5f23f3e93e382980fb0dcb3e87dcd8903dd4520c4248cde6deef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec2a6c8e7154d99083cd030d33ab62a49a2102728da81e9d3f7658580ca4a081f09e5458470a9b2e486baf3cbddc0670000000000000000000000000000000008ba2f0e681788a626582411810613007e5ffa8aabc59d2cf6490d5c0b20d83b30ef199b90413d7700aeb22506de30331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c34322f59e563a9930cf326432a05ec367e798b60ce0a2c30742c1ec7c6577ff34ef947be16cbce439dda9450bfb889000000000000000000000000000000000c24b3663dc3207de95a1eb68255db233ebae57fadd264f89849e402a7759091fcad7c412a8b7baae323ffa30a126ecf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe19ab1e5d4a56a50efd379e6584d0e8930cad4e3474e09c024a419f038eac2e7e0b5122c1fb656b2af4aa47506af890000000000000000000000000000000019de0fc118a1034c1594a93b4a94a16d83e85c5e86942acf5c510d691ba6f07943f8894caa5222c35a73d4fb2296049a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000256c2970f1d3281c924021e28c23b92d16c3edffb5e91c776ddbfbe2b70780ef599db181d779e16d449b536cf0ecacc0000000000000000000000000000000001277bf7af6c983d78f706f80df9d2bb3c98a669cdf4a98080bb82bf1557d636b7a8bf73d3770f9c77c656c75e4f4f241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001172da28a357d85aff8c4697a491a6ff89ad38ef354c8efedbcd540f2564422e63f552a4aeb9db7f181780912383851d000000000000000000000000000000000567fb0b6180b034f1a0e4f198f7d5b8bfdb97874fc1e2b90cf5af58fd8413ba629e0e0f18e5a4f1edce7dfa36bda4ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001099063041d603e5897c5f476e859ab16c2e6ffda6eeb94151b38a2318b3555bdf2e2a7394e7dccf9c4144bd07f3729e0000000000000000000000000000000010dfa4b89c516004d7d62790113ee600bfc928a35b01d8a1a574b4e9d6435ce4c9129dc8dc8cce90ad9715a0125ff23e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c1404fa874f10a413bca4ae3a7d733eaeeeb889269a288291b311477d340c6b4213acfaba5d564aed893f50d4f5553000000000000000000000000000000001182dc1752dd419cf886dafc064487827479c613f293e2d13b7713485a26040aacdbd4f6c10d52afb87c5b66fcb5603e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a78b7070d2d7fa909605acea77ef2b290333005affdc1e481c535f722fcfa46375184bf7666ae542829e2e8fcedeea0000000000000000000000000000000014e281ba8d5bc5c78a5b66beb6d434196e7d17a271725096634f509d9512ddc9d4cbf7f3fdc4036e22fe5cd252cd95d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001093e2461d8a5ad955114c2f697fadcdd8aff026992772fd3e99d58508ae8e47d19a634223119531f05649133953406d00000000000000000000000000000000053a42632c7cfb4c03fb8932e791ce20bccf1f7c3ced2315295df758c3cd2bc022a3ee747204aff9af4d8e4011aabfba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019974bf48595b51f32ffaf0dc2dd84787006dedbe1e2ad41d048fe2e8cb16a9d56236b330ecb9762f26d839e4a90d5ae000000000000000000000000000000000ce8570f60e75ca375ef870fe6f3578770b2d4e569370427ef92be0e91f0d0a5a392f1d3dc1d6ed6cffd72e82e7f90ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db0d517e5c950bedffe2d40a6308ebc100725cb42264831bef4b9dcd784bb5458a241efd19e7997bdaf4a0e414bad34000000000000000000000000000000000cc1b0f5a2985d3aae15715c4ccdc976f4616a75775b648ca66b736eb32c49b89c51510ec7e956223cb41ccf2c182da61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cefd2fdd7c5e83eb0d88a306c99d25b158904af490f208fdcaffab3a791992c3d0b2351f138628b26ed8d7d56af3100000000000000000000000000000000003c132aa33a08bc45414439ada47c3583c15638f52dc7652fd9b8376556ddd24aebfe9135b84b6c14a63737d8f12b51a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff291d4949878be7f95de509546378dc070d30868e62a063aa949ceb075d662544c76c0feb895d6190e3c04f7a9ac7d0000000000000000000000000000000019e70d82ca0fc26a7e67371b04f00b9c2a86152a24b5ec2a7de2c20d08f264154ead7fd184fc3b9131a5412bb6f75ec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019960bbb5468f21ac685f85b358a57bd2a69edbe3ca1737525e821f66ad199f202d4329d929c1e83fd0216d6c33f12b600000000000000000000000000000000098f5dca3489f126f3e0bcc2ddbdefa40217fb68672f35b1ebfe60687f43d1de5e23f61d31fa3fdeaa6384753111cc4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7766d0889887313d07230171e6e5022145f44f36fe33d0b8a3434846859ea7b20ebd97a5d6cd5b7238192bcc13c973000000000000000000000000000000001265c1dfd5579a1535418b54388a9069cd02dc17c76243a1feac210ea2088498e93d897472510120bdbcaace5cc1cc6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ed4a3b00f0a3c1dc4435ba743fb6a22f9feec147dab90132b007acc5eeadae614059e25815cdd3d85a79fbadfc136a00000000000000000000000000000000065a62f36f3c831c1eb7d49ccc73f75ebb07325f5429a1bc6e2d9f0cfa4c84b3c445d5a5beaa9e5cf99a0b47e7a4e9541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000634ead49eb6ebb2e8f5e7b0ec0e31b35636311008d7ef681e904e7254ae9bd77160e52f7403c51cf0d0dc3e6a05ddaf00000000000000000000000000000000164382c9ee86014182f05ecc51f8550ba9a54767449bd46e454d6fe958b30cd791d85033af3fc1bea8f679fcb268a9bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019e389bb7aaa7b247eab69d15c7fb45143680e7b8d50b99e653412e191c394ebe95e00ca44ba561e2b8fc8085fcf250000000000000000000000000000000000000c86704ed1787ecb09bde8fcf39bdf32b079159ad8d115b7bf2021bb221e9efef9ebd8e0f3e48343a1e483ca55d9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8efb5c4232c9cbf2e6097486af882265ec77f6ab99fdcc089eb47f1aae78df24194a134cb653a82f7cd539ea2c49f7000000000000000000000000000000000de73cf8fefa9693da1413bdcec80a67ab152a7d04551a874f7f09ab8fe811505a1d288d03383dc78830c6f8175e9b761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000997c6eacea3040961f397e9d7b926622ec6fd8aa2273a1b06601f200cfee161c67c8f1ec5548f5b6444abd92510a42d00000000000000000000000000000000184f187ed44ede857103850892a9fbfd159df4f244b028b8677d508c5b3a8715788d52e823b223b6e080f488dc2aa47d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f0e5ea83a26d3eca34593b23b98b7446ac3db8dbacf6f3105da5ead1346b77ae018337529f27bcee8bf1be0a39d4e20000000000000000000000000000000007adebf2875a9bb5e31c2ef7a5a5e8fd81537e9d973a3021e0c21a1222a21dee370f854e2b54178d63c5dd9af50185d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001518f5bed56ba6b4f14d82a03b862a96c2225f667c9bc6e1854fb641ba7b9d848254fede9550cca69c1a6ab248e5fcec000000000000000000000000000000000ba06f813d3351c927063b98be4880750363c0be3c6a0966992c92429754661a390f029681514f374f0ea92f63046ffc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ab613611e2aa6b0058d7defe6048c5b2256a1740375535a7f0c676fe22cbf423acfd41800761488c2ece257fe4b9ed000000000000000000000000000000000f13537e306672a1fc3bc747337dfd8f05c79fcdeae09055b01ffa24e01b41c5e5989f92eaf165ce6c23b44bf65cba541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041aba18b9097a7d418a7f94b395a9a639f4ac1520206acf40643be3c2ede5471080d7b0adbe66e72b76ab820e8133930000000000000000000000000000000015f88f9b0ffd52c5f16b73f41d2329197164188a953ce00325e9782ac61e6aaf3c518064cf72618fed264360a922c02c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015416730835d00f6a73c8b991837ffa64d7180ba9228761fc476792499815b02c314132e096425fb925557339187898000000000000000000000000000000000535a4b5ffbbf0ca186ebe63992a0b2133671b3da481d254c1ba7ad1652fb983fc9dec7a7d0089d224c10c765d58e3841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009634a8eb38c02db736aab937c76ee5c11121c62bf72b6c2866dfddeccdd4691e553602fb370e22d476434b52d0aa2b800000000000000000000000000000000136abc1167988604aafae182612eed96276b0a01fd89b193b39c1be4ba96db4dcec77be8cd08bd9247a4522ff025bf791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000066330f2a929479e8348bcf6d84ff66170a9d422d2fd383a19a5ed1dd68dc6666575692907e2f2f124453af168de60f0000000000000000000000000000000017c18768c5396de8d31d59fc110827f9da2b34218bf22e20274ebce2ab6e68226c860f05b70c57cbc32ecea1af4397fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa94e57139d0de69e4cf53abae4a95e063bf6b255fb5932a008b91fec9b22372b838ec19fd9001465e4af0943896dc300000000000000000000000000000000155f42b375b107b0fb63b4174a3c8793361c547728b8ffb72b6d5b88b0dee2598fbfcf4419b628dbfd620420794578cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dabb8fd32b3883b92cdb90e9571b7884cbce9a58dcf5787908462f91a31fe3a6a15724312eda31aa681a7ee399e29a00000000000000000000000000000000151afd2fd79423db99c5593cc08848e6cb763bf242172d3db0efdb5166b0ffebfba675b54f9f68e8d22f27b9fadc79e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d63372e22a5cd64f4f062d06572ae39096a1a07174ac19f232bf697573cb584615e24dc1dc86218da2cbd8786de5f65000000000000000000000000000000000feee06c2a979dfb4ca65744d0560bbe44ebf8e3e69c2b4eafe6fc139d8e3bee0b8b2e63d07a8ac6386433fe84080ae61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030dff2f81392463171b028ca0d65be238270dc698f7506dfc03a5fb85083aa8ab4d36512c48a5206782bf61588958390000000000000000000000000000000014e9e8b11d2864d8cb52548664096f6c66860d703cce4fa33cd3dee9769438eafc076effd3dd4ebb15179dd15bc490b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bb59ec2c9d94d4c4ecc13a0e696dcd3f3adf5f5532a9301845bd312d69f8f39d571e919b287ae2bc36dff77da7ff1000000000000000000000000000000000060440f8df400cf3167622473828693a195a738f1a44c7109b0452b4d9a67948e4ae20d29c5302b40fdebb36815810081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3fd2164530eab3e5f472b7735a2c7e01c0a420ff2840a8d804dacd72fdba1669032fe81f99c0332fbaf75bdf9c1ee7000000000000000000000000000000000c82eb91810bd698f12ac69967dd7b87b4d5ff608a31de60be216dfc6f1aacec953e31e181410328f8782b4999ac8d571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177379f0dc18965beda800ca6e301c63da209d916b1c889b883a1b29cef25fb4d6c6438b5ff4b4ced401736c273d2ce80000000000000000000000000000000000cec7a90c631febef2ce24e31230ce992a681eb23496fd93a50b8861064a4b24608e457096d6269cca80efc03c887f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed4aceea3b2ee55ff68e4fe9746f149ba2c5981326dad5c13185f957f06678c8a261df1f8c63fd6b20681df948d950c000000000000000000000000000000000fac99d827225790ff8e07663eda1338d7a803cd66b59fe277c7141bbb08c05260661d65a5264ae663292a8b099ae2db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75a45c913711db9ba536c9cf8658fa595f1bda7f6a5554b7dcde3a0d4d25510c9e9de43ae7e8946cafcda848f06a5a000000000000000000000000000000000c8528f8521d85b5e436bd468737728ffb1e899bf6c23c55621c4e9dff3ee61d96647ea78037648e9a22acfcc1020c351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f318e7dbbb9cd760e5fc35b2478672b8d2fad15cc9adf693df34badb2946ffb6d3e86caf6417d3f7ba25fc42c5722d00000000000000000000000000000000100d3fa8bae4dfb2d034e2a3b0969341a1faf489242d6f2c76e8168e0b29a6947d54c380d6daa9977a9292f11ced44851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d08a3968fcbe9ead2525d33f241d3dc18b96938635c865a7eb131c7a02d8f1b91afc1bac4cd56fc7e684556863729100000000000000000000000000000000186f2b3ef13d6155604f0b3688d45433a015b74f2fb433b67890c3db18d4f0e45779a8c90eaa7a80a47e91e30b24d0f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0c3f818495ea31b0a3d1a96a40b719918135635af754a60bbed0b46c530daa3b93aaba4943c7819b8053068c35ba0a000000000000000000000000000000000106223b96c9dd22adca5e4afa82b7a6cb2ce9a6e330457d906ecd9bb0ee797bf7e48b08ad3e6e932a69b99b114499d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a561fe4d2dcfc355bfd5ad27139e0ce9dc674acd93d45f95b327fd6bb69ce6c639532be11f194937bbf7f7e6994e20000000000000000000000000000000001912584c9547827f30872cfed22f71fbad7cf7143f688760e5f1cd31d592911049c5e5837993eb8796519402f02b14631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049c1bf2f8e56b9183f6197192fe1eb7ef959d1c5e36b8fd15fe2781ffd55a2d349e61d4b88ffcdfd4798d3bf484b244000000000000000000000000000000000b541f34ad6903c3ca39841bbbc6c8281bc7ebb4fc9a8705e5611f99d9cd26aef92a5ce7c813fd808871ece11307dbe71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007027179eb19707db1c1aaf7e0c9133e001ca4e56fa99037f2921b8e9c693ce8c296d475ca72f41469e9eb19ad6ca8fd000000000000000000000000000000000556fe5659cb436b31d36f932561f1714e5adbf4bc024eda16797083b396060cd1f09019f2a7b7af275835d47f7706b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006efa9179042688509e9d23287860e72f30c1ce3ca48588704514dac04b10636c3134e94ee61f4beb743837bfd3a29bb0000000000000000000000000000000004f316185decfaf0b9124fc4c259f99da4db36ae4078b0ac9864c9a7dd35b5e89652cdc801337cf85eb469b6c12babc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e25b734ec2e99adde2d526f066f24fca155f8f7cdcd4a9a5db08ad829c88d80ab4e65419c0f293a7d58606798ff21700000000000000000000000000000000060f0173bff2ff4e6f2ccb5a310b6bbeb3f0c18c6b94c257c535ce630a8e710b701705f4164959c82c43adc4e1ecf09c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069a4117fc6b8168b2c12aca408e73d7fe0f7afcd14f7d523f22ef5856a32331231c149dd81ddd2ff3e1092c6da45e640000000000000000000000000000000017d6704a1b1fea5acc3737cbeeda45d90f4d6fb413b94c5377901ecaa357a56ce6bd97e1aed5afe26e48dca75fbded3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a940c99dc5e54ca122f58f34986625b9210f52979cab92bc82b635490353c0407a0ef5b7d7059859cf64ff8cfe55aaf000000000000000000000000000000001177c395dc36fd2560f9c436838df13e974fd4297abd5f9a4d5dd2af248a8a5ef25871e1025ee3b808c54e7e12e25fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018149936252740d0d055405d64ca9bd4d9c870d9e3dfe685f9a130a6e146781771135b593c5f3464c115a108502e66620000000000000000000000000000000007218be7287e285039960f216befd156f97d3a1ec24641b3f34fc02cc95d79c9313ae518d40dcd6735a66d4c12ad79c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020ab889381564aa46716797f5969cdc1d30a26cb3d9eeb97b79f0e908ef993a239f64e24f46a1390286b598b4eb0b9b000000000000000000000000000000000b8d7e3b488fd9be95f29f6fb613c26f5ef03fd2d851c6cb5c6398f525bad462a965d6b1ba4802534b8f5eb8b449d85b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001525d3e059a650a0e9bc15ec3145812d7c016925d533a52dce34c002d22b7a0027e51087110f2070a9aab4798c5fc3650000000000000000000000000000000004e7d8dd2e2bd3bb69ba0143583a431cd735fdeb125cefa5920c596d9dcd4bf93945e3583b8cc7d6ab4f08518ea787cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000971952c8e833dc062bf77f984aacc2983bc4ebba185016bc1e3e8f3edfe513f697def1e4aefd9f222cb07a53a88a8d0000000000000000000000000000000016ee349783d8d2d7b54ba219e7ac022cad0bcdf6319e2f8350918a5737bb4e65f54e2bbc59925e744405d5dbcbc1f15f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e29a226240ab824efdb457530aa96ec26b695e039d1eafc1f095cac437037e6a4059312559fe7c92e73199fe37744c5000000000000000000000000000000000313b97bfdb19419cca53eda4cba2d69c584c26052964bce3c1dbe8147af2d85f291bb612c01bd53b782c2d2f962337c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189dc3add19429bc8ac496e689e3907b22e37eba37c269364c7b8108b5f808fad08c5342bf1e6f03fe9d5e56372303a00000000000000000000000000000000016842f33d676a90cd97158b164d20bff847bf30e32fc81173fbcfb26b2225bae27d4cdeada9cb6b4bd4226a151078b4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f5d4689535e796487eb644424174656e83447094596212c65e043885f04cf3922122b74abe191dfb1a4ce973250760000000000000000000000000000000000e88f8655a2e80b6edbc334de91a445295e86bcf54e0538969b63ec16b6a679b16b95b36618e7efc00bc96447801c17a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e8243821d60f65c9f2450cc6b2092f0b55b772feb6a8e2b85e91c831e5d0f86fd211276208cdd0da61709e3cf323ba0000000000000000000000000000000003b58b493a8a23a55057218d0f061a3a2315e4343dc2bb6d6e8c4ae524a2e98e5fdfcb7d073f9d3cbb6fc85a28a5c6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc4c1bf00fc3a7cc9f4bb5b3666b83e52af8435898294b95e41d9a4ac2a1772dbe9e84fffc1b3d728366227aeb30a6400000000000000000000000000000000107c70581ba81fac1fedbb6cc9d5cea8589b0a0cfff3935a03a9b184cbe5710038f2a57b9f008ee2326613674b2730841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5af4f9275cf99153e66def661b20a6d672cc84b9d2a96b067dff0958d55c3aebd0f2644a60473bc546a0991bd06b080000000000000000000000000000000004c5cc7cacdc2ac28be8941adbf10cd3b74b56c6e888a662e71349560010568b867909742cfb85a3c13b1d9ce01fe0071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dc6925e522b2ef65c416e4b1d4449673c7993dc973bae4952741105f308633fa5b18debdb815bef33cfe1113e5c6ca00000000000000000000000000000000038fd4ab5281a35e3d79c3107818c49dea6fbef4dca22ae438766e1443bb203046cfbdeacdc3474fee6e7d03394a72ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c0c715f844ae036d4cfe846c34d73a4898f0b3d2fe69717b4b758a6dad9f79339ba81a75f4710357ff415577ff0d4e00000000000000000000000000000000116047d57b155338326509f9be0997ccc48c99d998d001a48e262da616555c4afa08cbeeb10f746526910ddb57d13b971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001429935c5293fa437649ebffd00887bab438fe3973c95be362bf8a1f0cda12b780f896363c9d4fbcbdf7d4eb312ca779000000000000000000000000000000000f612adb430c2ae67de06a0f4e821d5249e526ff41ce6f7c858f8dd27b13eeab906da8d98d0285dbf919882c905d258e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f191d3f9d0d62bf213aa857b0965f9967d88c4b2f48c29de55046fb9cbdceb61c6dd6a2d57bc864bb309587b9cfa4680000000000000000000000000000000010879d82acb829655193394521fc47c1137d7e70af414318f056593e820e009fcdcb9c38d75f3ddaa8cb8ada5108ebd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ecc78a4fc8b222edea873e10b13d7c26aff6d4d86b77f179b8b435db73e17c04afe0ab7dd74e11d77f02a8ffde0c49c000000000000000000000000000000000becab1ad811a19f8f88a1afb8a7ee7823b668d5ff7684d9a07208079b2adabaf29a229cbecbe9d0b2ffa3e34535fb811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003237663189a911367bcf8e4a362f06489a1f9ba513b27a88813263d07be4188bbe07bb12a04c6b6b86e5d8a80debf380000000000000000000000000000000017512fc5588b0b16703a13b5f238554245e08974ac65e0b46eae57c97b10a33b8bc01f104a35991ee46c5f3654efad361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3a8b25f4d88936f7acf6043abab1759e959f55311557c7a836c55720c98960389b61ba150d13cfdc30ba35a4f99c0f0000000000000000000000000000000017378fe4ba3bf430802dc9c2e623c959ffbfe172d72d16f27f68d35b7208862d1a3d8ba191c99e9a82bdb2f30535e64d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001570f57cc254e36e731bbc311b2cdef5e97da51de84b1c7ef4164ed3f17135150a1071913a76708c0a791436853fb12200000000000000000000000000000000170967ca2fd04661709942fc2c5da6bc45e15d2f989d45ed952b80c2a38e5cbf339f376c955f996ac77e9ae38150627a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d64140311922b1c7d05e3f9ac1a68370741ac824daab2aecac3114ba3d7768f6e904606575d6cb406895c5bf910675a0000000000000000000000000000000003d8231c081a57e41cc491db7eeafe9e11e7e1e2adb022f9d9b76de45cd8820e25c91c6d302144506c2c65632aae2f791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8145957c7bd5a110bf0667091e3d16895204dc123f70d801472a47c3d9ac2d9b11f93fd44a0a74555b3f5704be7b060000000000000000000000000000000016ae910428b0aabc6a499d945569c91e1029a4309a85635bf22144c415161d976706bd3e673f44e74a5fdb0ecc428d701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f103336b40a5e4bfe7a86a03832b414f8957935aa4316b0161572166fce5602ebe8a0d5284dc6c818fe3dc0f3833b310000000000000000000000000000000012f8f7920ea770844cb6cf798c6f9d1a3abb921b3478d4f1802df36a3c101df1e28d2af09a1091d9d49f6c6a0ba85da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c8c8be082d2f02513e7c2fc6ac032d058ac42bb2b614daff4583a4a16b4fe7661bba02a8464dbb9d9191b42cd6ebf4000000000000000000000000000000000070dcd6d034d13cb546cbfeb6f323b60ed11dd115ad9d3061c47e33da9c9d4ddc042026175bdb34720a5a92f59554f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a6139d00a7990ca91d42d933e0d39312ad7fdeb0c0496e9ea3edeae7d4854e531b28e0c912003c1177d0792c5cd8de0000000000000000000000000000000006a6a795f27bd4a36e9aea91ce07a1173edcbce6dab347a574d4fc96661aedf57cbfcc161847be6b6d94074dd53fc5ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010180f42d688c0c489efda991939402af807458b88b354bd416dae7356ae3ad06cd537139ec423c6bcbadb475ddc69c1000000000000000000000000000000001519f82f9cf0d1e4ec8e94347b6e577007893a18603474a269cf1e84769fa624f1d989411d2c51849b0c27e583f967051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001780930da219a98e2ec2c5725d25d6fb7b48241cddd375f4edf99bc930fea4b31bee4f0c8902f7ee30c69238cca0eec30000000000000000000000000000000018ee1e93d7e926ce942a074958a2fbf037cfd77ace27c28bf32b7775854c99d6f4a8de698e9384653f2dede6b0ed1c9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4dce78121515816f56beee2fb3595f855335183641a1a83188360edb3cdd6cab6f70c2f7b4f2887d489e733c9afa1a0000000000000000000000000000000015bfe06b7874ac5ed0c1a624ed5b90fd1be6dbdc56f7ce09e6613cd8636e8e11449283831e1e76a40027baaba2c5a45b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005775ee6ffe0e01e022c29c495dd242c24f4f4913d0127515e00b867241e179be8f2d0819761a8400e511425c45aa6b0000000000000000000000000000000006473c74d045c7117f06561bd1140679b32d72fcdb1de45b89a4fb363e3d1c4e5e857572e45cc603b5a9576847896bd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d830d7cae29ca19634ad3985bcf7db786056c5aa538faa430d7102fe02982833a72ca079c237f7884fffe99ff903e70000000000000000000000000000000014b93dca69343921b7d9029d728eaf61862f1e9920eb7e29c48a7344a10548ddb0f98e5bd70628e062e5d54045d647021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba27fc8c0187a6493ed63f3e8c2ede5162f081c3dc048b03f918f1649ac03c33c25c9df6fb2135bbd863bcf8747d698000000000000000000000000000000000aaa7017d58aa7195b882a55bfdc605acf9bda927c02274566e9ef13b462223f9aa3e9d46a8e3a431c96b9ee7546d78a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd824860d22e2b3b504a3fb82bbe47d8e097465c0c729b1334153f046cf2c6229656dbc18439e3112b34047343d9cc1000000000000000000000000000000000faa6e919fa2e1da3b07827ba50b0539f2033b3063446a45e6d9cdeaea79bb9e1b8fd76f8801ed2b7579822efca7f1151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ffb9a1e0d2a5498aef2e2a5e5fbdc96f9ae5fddad805cbefc680b9c54e716990d2e22ed279073ea8d4dcbc9d100e5a0000000000000000000000000000000000429a53efa704d50cef9369168119d5e45b5bfd332c695b1a6b266b3cbc8ef32b09201b5591349ab738a0a2fea0049c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001203c563003c6c2b9991a0151543af6a2959246d3b4e7f5a022893da096635c9dc5c06c42354941784b4756f511caa080000000000000000000000000000000002627a8a781c5b9b94805fe697583ac5e2c8144159636444fbab072e838092fca0fb629007a835abba5a9ac3fc69e7081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197c0077825f2f746fa96dcab0fc15edbc5cc54a9cc35c13d2c7537cf8ac036c8d271dbc02886e440fab5db2442d0b3300000000000000000000000000000000004bdfb575d8fa2df5732248968f6b931dec26d44a253bb49bbaa4dc597aefb4b80589c2f533ea7926d9d107ebf0d53d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046f44a0d34b12b1d34bad1e529b353bfa77b2efbe07408676b478046f1ea5e17543dbd85aacf6ffba5b0086c3425afe000000000000000000000000000000000e69a770acef6f33f7eb8eecadf6dc36e138f9748f9e605e4114c7d38ff99c382bd88bb46daaceeb5783affa6d7b9d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176279f374709d54c734e3f9a959c44f05d1e5f4edba9f71978f9c83e2f4e16df1f25f0e2e57479656dc680148e2edde000000000000000000000000000000000283c900f4e975952f17e991a1ca5c52808477e3d977a3bf13e36069f9aba8201f5162869089e4a2ce7c08c4f410d3491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e691d39f7243df71f8c1026c5ebdf10de560dc97cf6c18d98be14aacebde4b5300c0413d341a35c4b70f80f1b2a80a00000000000000000000000000000000013559ed6d49e132c6a187b2d1529ee933943150ca06e831986ef42ed9adc1a6dc2f144142ec2bc2808587198a0e31521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bce95aef2a54ecda3198ff02574087c9bf92c10c8906de477213f3a78540ccb71e1ab7b4bf1299f9da12228a635d5890000000000000000000000000000000014f204cb272acb217192f6ad6dda7c9a67298ce3bda3fb6b1ab6b67ce85409e8ce85fc16db4412640f5f04b8fbd304ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2c68cde8682dfb11edd9fdd808e0e0ec244a38d8405f321787a394183fdc8167a38b98efa09714ff4180d0d68322f60000000000000000000000000000000011611269d6415e6e6f12fc2836039270298a85dd71c8cfac124f5063afb6244e5f8a8c787de6e31b02a9aec12855e2b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001209d1c4ed9d48a3ba2802bac42385e0c2e0995a6e6b79e884a3dee5928e1bec92fe7609b85661935e90b6e040a6fdb900000000000000000000000000000000082d7e49eec113e8ee9ad0481124ed851f6716fc76a328772e1d574d1fd8259b4d55c7f16f117608507611b95310d0331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bce6a14f3f9aa1617e070c59a2ea042566e7de7b7b54a6c7483760f2d1e65ed32185cb3a773731658a6ea213a8a2af000000000000000000000000000000000a9b55ec566f54c48bba45c542d26fe96a27cef40160e8ae30ed78e1b9ef981353b641a2236d90108b5f040fcf3c1dab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088271a97d9862bd8cefc2f46460db3eb9efe5390c85be6fa134a0b776186c314566118a50060cb0e97c5954c0ada84c000000000000000000000000000000000baa89a5b1adf8c9252c6402886475930cc512e90255484dbbc0b6b496b94ffa4d9a56e2410a52420a0fe5d4dbdeca171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fec849aa99f886b10160940bb32d9742ff883d779650eebed55eabc65502d2d131fa67924797a7a69eae77a0b70ffb000000000000000000000000000000001286bcb2a8d390d11b9adf4e0246312959ac0b2d4f6bcaea8813520d98520bf64754d9b951e396c396d26180b26eadf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081d1e61f7b729454c857fab50c88e4c3138744122c7a1c859e4ba53e08c0e169727743774ee5c304de27bdda7298611000000000000000000000000000000000640e0953ff8f5b4d18e48378b38eb7676c1ef76e4e59368e3236786ce8b41412b012045de3d62e432164bf46430a5581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000328ded122b64e9e361013c0195371cc6828c02c0004a64ac59be363120d066d8043df7e01ba2cab2e5d39c48cd84194000000000000000000000000000000000bf7ac9d8653a29abc833925385799b2730a0d60ef3105e24362441eba84bb989e8c34c6ae07abca17707993faf235e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c72178cadea50c8187cfb2dfc5101b9de0681893e600894b2606f89df36b2f07058bebc3eae92720ea357d26fcc088800000000000000000000000000000000164392bfc933b930860b9387d30f9e0c7a766d5bc344f78022820d7fe787fee302ae86abad7788be77344d522b26afbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e2b16dddcbb96405e2902948a9c1a43043f9691e85b9bed9aad21d34a4dba0cf9c55d39b7296e724f16cd2c5cb3c000000000000000000000000000000000142bf02e017597bd511e06b487d06cf0520bd876f4fbfb7039d7fb48158e207ded3c2165b6bed6e026ee391f65eb0ef81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000548de52ecca447c99f5141191b1b197be036ba301521b8b290a4f59b3b69a210bee8cbb507ef2a6f6870206f8f1c22900000000000000000000000000000000163dc7a8aa6da9f591e3dc6b948959465daf5bebdd43e5d4077941f4e6131dd99c6d42b8b3f87d09baf0d1cc9b1a4ec01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000291b8ca871827f12a5d72b48b1fd1b968bc47778a5fe6cb03b9a7b6815dd0dba61ac23818d5ae7a5d49af5f6d759b8f000000000000000000000000000000000d2480252da7ca4bc7c012de367191a98fb11e5cab773bcfa8557f4860bf9f1b64bb8c9e929d99662f6784873a48adce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fdb2a9ee343a9cb7a182d8d3b7052f8ef5e6de5ecc7466088acb414b9f802dfa3f05b81c2483ab05d67a1dfa8c0a990000000000000000000000000000000019e20d34df29e82a9d975b22261c760f4e0672c8743e87d28d5520690e157d3cf59fd0e8a240c57757f8e1c9566502ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005751cf80da8e8cca7df46a8428f9097bfab5e5f0e0f595639ed8bcbf30f2b4abfbb80c0176906de72d8951c4e5d9cd90000000000000000000000000000000008420eb88b545e81c6e5a185dcb85b31d2033e88448e43f73b3bc684cf5b6d6373d5b43d4c12aa6851a4ff2126c9fe851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad421edbe9880d5e68cec5149f6fb5003d7d8459977f5693e0c67c48e581a1adc132f51fb8a154120389e3a9f7fed4e000000000000000000000000000000000c1053d04108227803efcda6628f9e0caa12f5c47399f4e234694221d42194f7a2371167983bfedabd5291a915f53cb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123d6d50ac169978b431a9340ef4f2ff444c523eeff810b591a112f00742caf342c4d0e768b9bee37bf4f478360699700000000000000000000000000000000003ac5c383a20d4230268dc6798377d650c1d104b0d2031807aac7b3796ceb188f824a2b09477b64f3df9d6ac2359711b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005599de85996a8a483097821ad74664104f9f7644b9e6a04a7ea38e2f77bb084d21ca42f5ac8a924e12490bdf5ac166a000000000000000000000000000000000982550b4beb9c7bd1eb29c5937164d48657f9aab8586d12fedeb93f8aaa3dbda3ebc5385059d945d7ad13653687c0c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009587eec77f1181f7254c285a1054173f96bf31fccda6b346c5b62d28b1cbf3dc94a2fb0b5744134902265765758ee9f000000000000000000000000000000000f4f0b05595948af5d149e626142b870f629acee64cccb49d48178b005dd0b34cf78a1ba17fbe8df7d90682cc9b141c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c4d598bd2adddbb39e56c67d3d2240ef186e85b1da7788da5108ccdbe88c986578be858f37a8c2673de3e07c6f555300000000000000000000000000000000131fa148a96d927f804cf17b1650d8903d86a2f7cb358932e4e6c54c495aea83af42326df88d9a9f12437708bc3faf7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa3ffceb84e17696533b4f840d391520e58437becbced77ed6b4e77c7d889853e002b1aa1990df303f99e19aa7c2f1a000000000000000000000000000000000499d6cd4d219d9bf3c4ea0221367a6e35461a98d1654c6fbcde89a87255b023aedc8d4c33b5c19628d10ed5e7e534801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018589ca729ab6e409a481ba2caeca0f03ad813c60d10f4c4c54b171878572d4ee27058e3573f1858c098e6dfe49a56680000000000000000000000000000000019a01342142c17bfd9e93c79aa2ed19ae2c93138aa7cf2dde2477a69b0414561787d6eab81af52dfa503a17a91b5e3c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000faf3972d161782b825240a4a3f3da53791cf6a91d271573898200440e3cb2afe17aa97f63dbb94d63501dd618638e8b0000000000000000000000000000000014f574f394d5a3796d7e8b5e9604d6ef7312570a4fd06f6a732509ab45f733f61b127a6a6388442a5f4971e7407325951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d939610a281fd0860ce69854ffd33ebb0996ce1965a17e092931afd10392ab29eebb8dba7a035542f8a8560b47186100000000000000000000000000000000005af71d93dfeafa875e8017983300aff491dcf0d6aaf5f73ea0ae32749661e0afa5aa2860daa1681d2beed8e8ecdec221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c2a8b293b6337edaefbc7be9cd4f259ff6cfe50fd5fda89d20a8c4557447b8d77a5fb21d2cd52d96b2ce3691d96a5f0000000000000000000000000000000013ade3fa55465eb5541e50b0bc4e1c892c3ac581e6ebe9ae56b021ced02b22183dc8716bb75a8d1855cc07bf2dff25bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cba6107005b6099711bc9bed98497f5c182a91002a687df39717b3e3c23e69cc355d9e60f518970cde7b3a1a4e71ba0000000000000000000000000000000011cce2ef545f432e4f6f5d17140dfe06dce150bbe201d72a99057c9e40ee927005394060f2820229ce7b33462e7c10331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139205c3454955864c3a3a363ee0a9091eec9db14f0380da3ab1f25f3fb631a2c7ce870300a021ff2612730382fdcf800000000000000000000000000000000014933b7753b6164103f6b9569b48a5730c885ca1336683e26e891aa351fd4f970f874573fcfdf1bd4ff329dce58f25801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e2d3f93faf40b1358297b2122f8361e935b16184fd8e7aaa9bfb4e8a6818bc5ba4c849f95a43cf5665d6f850a19a1f000000000000000000000000000000000033407979c761acbf3a62288984a201d7d72d8c18509e5bc0d2881fcd49a9866ec473f48ff62e66fcff3df1376fb7711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af88d3a1d0eeec8ddd8c7462efbc3b5945c9d7c0b1123e93157075d08b3a4670893b0770fa3a2fcae6848dac75306dd0000000000000000000000000000000007948fa4475392917f5ea70e5452d04ac9893ede9e6b3001a6e05e0e621b674b4f7b146f10f6b63981f9549773bb45911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137e0efa3254eb3a3000199f398812303a06eea470a04e356801c5d65e32f5bbd377f1a21c63236b06bd12f4cce5a77f0000000000000000000000000000000013c9a58a37007499dee3cd29704ed70105be2485f7808163c24b2b0441da9057b70232275e239c4b93ccfc4b735673c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073afed6fba90e89b8fe7b76e88b7bf32aba394e8afc2ac2c26a60f8b6b3c983e139a09411db918c6dcc67ab41535aab00000000000000000000000000000000032ee4015c21aefdb4bd54bb9329d2b439d508b5ed81327ff50e078457d1b3acfd432c7afc1ac9bc1d06a803cae561c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109ca86402d3d96bf010b8c20702e0dbc2cea2e390ebab92e1577b8f9f2bcfc7dc488bdf949e9d19f18a6b9608a8fc27000000000000000000000000000000000a6e260aa93469aee078b525d7c2cd7675f1df85d73bd3237a3f8621618b0960ec67c48e4c6b747fa83bf820a4b066a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b9b59de96a11aa3aafdfb514afd1581f084deef380f583adca8d72147de1fbd528cd7b7d8a92a5ea3e84e4fc19a07d00000000000000000000000000000000083bda6ff113393623c7920459c44c3969c093bc95cfac9d0771ce20d24b7593549b8434bc7d52b554d60c2c1780d6f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004b99bfb772f179b630b7d58a7d41cbb50affe56c8d01006b69c9d9d82e44e9017185cc013244cb4c6f666d220e5b0a000000000000000000000000000000000eb0b3272f4d1ef13118c58ad148dd0db76d763bdb297654dc490fb19ed863db791511afa15222924a7b25845ba8b6f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df44f54f3a59a00498116f05b8213aa8b25bbb52104c8f2b47c9ae43a7f41e56207763356138f04683bd576db76805100000000000000000000000000000000079eecf398ba66a9f4dd742e143fd582c5b645c6e1e1234adb83fc7367dc60ca0b17451366dc23751d1ba1450f77d1ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfc699574aedbd91f87e819962e1f7c0a7317989ad46d70fef8012ebe7ef9df464437eb36dc4e09d195f3487b5da08a000000000000000000000000000000000844961b01e1c64e2cf6485792444cc3b0308ab3fe474310f51de4f2272831203106fbcefd104bc19168e6b2f3bb55bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001815cf6212abe48ab721af502e10e717b7f83a616268d47e200f16ff61f8f67d4f781cdf4399c33be0081e7680b8f1f20000000000000000000000000000000005980ba4a63904adade55258cd974dc0748a3ab8462e1f847ef976be395a90c0368dccedd3bb8af84c6eb36b5e0eb19d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001656dccd663a762c675a68ff982f5b3668a9d92e550cd2c363b4283f2e6f73736fd183e3f0193d89feea581fa1b52eff0000000000000000000000000000000003f7706bf2ae3dc41fbba3bec3fe4e55591f95275b09b368529bf67e029aee6cbf9273870ea19f9e01ebd768fe3b6cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000539851a23d0b050838f4de937debc50e6c4b0e6bd995e7c66fdc5991dd7751513b0e617400ddef77cde37f9779e35560000000000000000000000000000000002559c00ee457064fe79a3af80ef8ae4f9ecd367630b2ad20e0538641c2a4c2d8775105fa325f6d2f4df33944fe5d0551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168d60b7d339edab24f476abfe56d89798b4a676a6e213cbee6e184f35ae7cad9a38eacb9e2bf31b7e5d35a09e49a891000000000000000000000000000000000dfd17233d1825e25f915d2028501729f930f56d794dda6a625ded2b868db9fa28170329510b2f09cdd4d9546db3afdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fac4bbf7fab9c06ddd2e3a1db9557eb6fc57a7a4fceb3ecfd2c187567c3971e88e9f59b5db4271e30ea98c1a20003300000000000000000000000000000000019e602f1be4f6d2debc494738d7fa03d17397007b121a866329061e5b1a16a6bc92580a7cce31fa2234a16d6a25ae671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b78fcff232c30fe19bd991d7976df11693e636f7078402923ac0d2832a8901f5f167c49a6fb27e5712da659026ec17c00000000000000000000000000000000047e7a0b05e778d4dd3da7bc6b93ace745bad9cb8e7ad0c81c180a54458942ed8a15a85c4bd69a96ef55377300c391081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccc205ddb7d7bc7dc559e04badf1867b6318b59d2d5a658e00737117a68f5100e7053143083980d7a64be5437711c9a0000000000000000000000000000000015ce9e3e939adf5b21672647ab24bcf3a4fbbf0b891929fb2d69df95de858c97f0007c5c343d70ea4a44c8f45eef77fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf8a66f5a33843a2c3828b168c7bff11115c2f2bd9c4c99671f1d69f1b3de0d3f2e51342785235fd93d720c54867d38000000000000000000000000000000000f899f8fdd2012d3ac16ea2f88121f5413de84b9f3a6b6d01ce515745a8b6b9aaaddd3a7c43856c6ee7233786fd4cec31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001514f463f246a6e60e6c474bd81ecea4b0ff546376697b185ba344c0ee35e9d4c91281389783ddfd7ceaf5169adc31f70000000000000000000000000000000009e1da9e83daf8b6843c7f068207a3fb4d690c9d11a87640e76ae1e0a99f623da0ffc0c25a5e8561b253eb11babc86d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061289606cf4508cf60bf8a54b31a73b754a5dfb954c2cc784f8b21650b33b81dde4f7f0086e781e739cb40643743551000000000000000000000000000000000eb3b1be290b7cd5528ceab57b7e869ec5177236aa6ea7acf36bff08580126dd20c7b4a60aa658931c3c18c9c5e6e4d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162f37ae71771963148d957b24dfdd48cec9c7b4c2a37ea6603d8abdc3024b4b2603ec88ab1ab00e254986a507bc0658000000000000000000000000000000000755e615de6bae0ed175302aeade00c188357c48541b34d924ffd4f91dcffc14173e9065b16d8668e1f473a09dfab9d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051826f8c438c628b5490049d2f6f89af48e612a6600e326d021ea0c3a6ae326d74fe7d58337f439f325f8971d20ee7800000000000000000000000000000000124583402dbd30381e3965f53eef4afa7b2c4331e0c4f63cec2d6fa0169121482c6d0596796b65befe506142ea797fd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eee34b82ddd8e94aefc50317cbb3a4e36c472f3912ccd0e3b36b407dce8dce7a0b859a11c64bc4c721529bb7aed2474000000000000000000000000000000000991497bd267f64eee46309f123e787c42bab9c9ad9f5a9caa870c038810f9f69fd385479a61ecabc8a6c1909c535b141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014da3405b1945c2241810e1ea8ab77f87bd0915e1658a7d9511a0433c4175c6599ab40d3bc378c4965965a95544c89b7000000000000000000000000000000001915b0babe5fbd3ca5b26aabb7f32fbd3ee907b33eb3ec9f2c8e1e69b481693f9bfc6c54a4fc097ffdcc58a55b8400b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017598c3be22425b1088094223a52aecb58dbf20f4efc308d136fea338d491be3403392dd23faba2fe18d677998f348e0000000000000000000000000000000000f74484ca3b6d26157d506c18eb5632869829dcce3deed4f7a56eb20b50ce045df1d62d98ddf49e27424860917d7b00e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008061f9895d7252366b94f471d609ddcf7be76cc738891415f637685495d8567d4cfebb64e83f0db9408833023ed0ff50000000000000000000000000000000004305111db5ec3aa8f3f93468c05a49105258d470d97a74175064503f45537156fc561049b19fb9bb04daf067843274c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096811e723c0c8a84cbf55d6059b226acd6d72266101dab905bfce75ce8061d1abdb2e005a43ecf9132664de226ad80e00000000000000000000000000000000087f639c68ed49140c385d039df1030df31e88d764f60559cabbd79ce8f4b025f7dc48fa24b74720b01b09228ffd9a171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b891ee25885a493ac307b65048e56ca63d1b5598ed2b5939ae3cfc8c66cba3f817709ce25345e779f961cdf0a2ee5fd000000000000000000000000000000000b30c7106a9af3367b2d930fa591c530dcc55ae27972af7f3ad3ff8c6e4bc3fd97ad0b97374d74b14649eb39f6929ce81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000403066292d808988f3dcf9c9aa8f8ad1e44be7cbddd7035409a052798e81a14003da88d3a0e245b653163de98f5024000000000000000000000000000000000148fddb2dc717c114441b5d4c4d726a4c20516167ed358a477b52c859c9dbcd30a0e75aeb9f98023333041a919320d041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9b22a0e6da44e9cb98a7e5b130ad79aad8810c3da48cc5a847bbc433272ca4b2e144c222fbcee65c1d0a3866b169fc00000000000000000000000000000000122b7d314fa335cdc989efebe2cf053aa7433a038418dc2c19cd516f51b34535b86f1db4a4ad11c4d554702dfe550c031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0150998231a77baa936b34e49ff55f8029d730d5767edfcbd246fe21b69c42538bb4ba5d9561235ee9912aa418f8ca0000000000000000000000000000000003f46a3a9e26096496b777d182acd4c8d44acb377d5446f7d1ecfe9474bf7c39921bfdab64cf5c97abed9448a65645361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cf6bd0d88a1f258601b4fe8cdf52ea6036552e7ddc2e6fd77e9cea0911309c9e25fc008d06d64cbb5fac386ecfc1d90000000000000000000000000000000014880d3cb9a7411cfd2024957d25d3ac470e456f2e5d8d364bffcf6083d79d279ae1ee86ece82a1823d07e9595437f9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d9b7ba393fa8df0a2b411d579cf678898a94fde779979f04b3267996f44fca9d5ca38da51ef08c04a392714f486c0600000000000000000000000000000000113700383f13ceb2660ef8743eb7abbaad2716a1be071ec772f6ba487bed1456e75c471fb15c089cdd532d300ed18f5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d837df5d9f0e613d32306e28ce89115f759e7d240900aff4897279518e3c1e380c121b3befba68afa3f5ba2c010f2cd0000000000000000000000000000000019fb5931d75918b9cdb8d160062e6518ffa5a1ce7ea9d44236827a398461c3eecd24e8b5cf0af3203b4ff925e43767a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001754ea272b55f1f84bd26ed7c4c9f2d762b994702e2125c8922130436c32d487d49865ab1b3fd7f12b7183bba80443ee0000000000000000000000000000000004f5b02aef4f388ee06e2a75039702b8e27f3e4b553ee9a4352ea416c4542f9d514e15828a68f3196cde2aae58cf522c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152e866afc2bd4fa398dcacf70526fbad1688c13a2774e5f14878a9f017e90b3d3842f23f401f7311702f668354095350000000000000000000000000000000009b4b00708d45d23a302959e822e223c1265fd44116461dc5067c189f18e28255bc8116dac4fa1c05471b4e9a1f7ce4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000487ded1892222f3436118b1afac98396e9b10a7f155a0d7cc34ac10bd5767265415ba9a6b2fe7c696aec2fa6f7609c00000000000000000000000000000000010b6ddd853a62be08605673ddbba0d252b5a71f3f7bfe2080de1bab1a5dfe0546b1cfa1e25957868186038b255de02c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000496792b5bbd7bafcd4550275ba8a2264c1e72f7ed75f5fd575ba1e8553e7ee0ed81eab32ca109d345bf644689a9bd72000000000000000000000000000000001230e2fce42d1db5cab8ee196281ad2f27b9c7e0bb5f229289fb3a92dc97f62ea7dc5fd626c2dc3fc3fe51b12081c1231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd6c26b91b488ea47d5673cba4296e3440fce5ac4af4bd2e40714ca6963dd75f6eea2812a18e54640d86684450fd3da00000000000000000000000000000000125c3fd4e97ff08fc77f5cc97604658de8d65e6190de0f198fd9e77d0a30e47e94546ca1f7beefa175448eba56b1bfd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001650c506b76c6daad95237c6bc1bd2cb2885236b2adfa9893bdde46e2094e9e843c74effd553e1dac5570687a4f71cb00000000000000000000000000000000011b6df2fa0c78ab4c85581a1448b2fe6ac64b1e508440393de858332332e33658fd827fb49357c2909a3b7b89df5345b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008475e6b3318d6753898545ebb2c14984921bc2619e4da3893b5aa2756e8b5a2ace3c3741f6af7ab4fc88b59cb5955950000000000000000000000000000000015dca7693ec6237e668533f762241c5e5c7eb9f708fe5fbbd0975611d61317d943ad037bb204a344efd6b802b8e65b451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144535a8545179b4d4d5df14a5c2f0b76bea627a9769132fcbde55992c60db28920fd753a2c5314abab8d7312f8d71990000000000000000000000000000000019d62c386ff41b693682f33405116724673b0a54d46d3ee69a65d396cc78c7dd796d494c9d2e07095ddb15d1e3fd75581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038d11c89f3cf902da1789b5c0e4af17be06ae4a92ab2ad4242cdf8646f40059335036cd341f6fc9a189dce4b220d11100000000000000000000000000000000029571a79b876e320c343eb1119d83e7be9338ae1892ebe20c73487ef108c102effca463e35898f0cb0ac52d121655e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001057fbfdd25c687fa77c73fbc1f008416f9a62731ace70f5729b5af47ce05b0c64747e449d01da358dab6c4f02a23f4b000000000000000000000000000000000f5cdab136e727256b5bd420ef3e7c30204a99c8c62845355addf490e9d9c2ea0fc7ca7b01d8458c0cc86bbb741a9a971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ed5869874efb400f03c498fef99116c3b28e12557b3bb51d29d551367713d5f325fda3ea89c1973e513b3f86223e99000000000000000000000000000000000d160cb2c59efe900fb63c7462950f7a327ee5ff240a5efc50f73107f1c67ac89d43770f5de1ce04bc5ad057de20a07a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001efce793a14da04cf1a3222909c3288e6f4ebd4ec9f0a2f7f3443b852c5aa07f5576112a5f9c25f6ba317eb0bd3ea6900000000000000000000000000000000176b2ad174ff7892581742cf796c215473a4fedcd158b0989f1a1f1c0c084f135dab34af261bd4f91af06aaa96f18b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f81c1c170f51ee6faf51b42a1de67e70e0b94f4d7253849075fc00a73d379b9e6e8b1283d869819bb324d09894ff86a00000000000000000000000000000000197fdb4ed1bc23c2a88466851f1c6ac2ecdb73961301f5e9c12aab65e99e89f93b6e751f063896b713d38c763269c5e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e15ac0d229f2b72259eb0cfb8d69525145a2402efbc62db47f868693b1792e7b79be101dd1c1573fb9d8e1af02463c0000000000000000000000000000000018be7a48bc39215fba39f4663923b20bc356b81d0cf95575eb9c6b7ecd9c4d0c1f6c1cd2f2e59931a2fef1aeb12db1611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9ba03ec1d161db3a85c97e698ab778097416b8a07ca72cd3765d7b7a5640516f95652183e82601f5a754aa566e6ecf000000000000000000000000000000000b7ecf4a64f298427828662e74e72d12b8147a58ad58f8f451ca0b23f08a10a00a78d184525ea7bf1d7b24f111ad63561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89ed91190a40514b6fab8c51fb6435639b3368b0ea1ba8456805b79cb3dc7b2cb92422d6b5028df66e3aa1cd5b5e400000000000000000000000000000000013213692bf65ba4d4300cf4b851e41ef0cda01c024f0cc7c427fa4d498fa7ac2b5721fcc1cb09e09799f5f42863fda091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000787797e2b4bd823198db3aaa4094980824745480cf994a0fd92e6d378cd17c430e7a112c8b98d58e718ce31b04ce755000000000000000000000000000000000e960940bdf423e33a0d938d0801b97c9944479ba95b1c0774a5ca3a961b69455595e3ac4e44a057babae6ab351669ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017db727b514457379b014e4b23f03f1abcd26b18e5f73111960ff006d2014a73d1c629d98e102abee5fa3ca3a2325b13000000000000000000000000000000000c3ddfd751eff5351a598e4079523f546f46a924fd8f460b861efd0f28ecdaf974562a22c7d7572f36377fde37dc323d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a08b93e6076ff874cc85bc44eafd9771c05daa4d2b09ec6403a87a8e0744fa6430f44de839906c2654b39ac6d9ee4e000000000000000000000000000000000d58ae6c088af5f55c6b1f42c0b1ff53f47f8742957802137ca8011bea7ef7c6fbf9cfd2f241eda72aa49c3f6756f70d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018cefa58ab523810741df2a4df5422dd408a358208ee707a1ab117e0cef38095398672a580cc37679ec5cb5faed8cea0000000000000000000000000000000007f83f91d0d2509f08867e6bd962312234ae85dc6e6d351b82ae6fb1c0e887b170c5841c4a22b8355b97c15292d6263f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139f241da3f51c87632a68ce74035b89676c1c40754ce75f8f529fc9911fc54415a66645a0667fcf482accd6808dd35c000000000000000000000000000000000041723167febd59f57498506d1dc8d4ffe4edc2acbf4bd494a736b3209d7922b7f950f95f7e0b7f35dd4f135ab2783f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001860f8165e50339f9172aa696876cf38e2acc8528e3941f881778622901449fef5d7ba73d475d87dad0c1a1f4ac912ae00000000000000000000000000000000129b43ba963a3c07533b9796b35a0209cda3b6ca7d27278225e8a89e430a5762e16c93093b91bc67eb3fa8cf7f1e6fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d424f1c83119a794e7e67618afac4d63ed157349bbdbd09ef00192a5e08154bae6fcf3e47c4ee27049db48cf48a6c70000000000000000000000000000000013212caff92bd1dafab11780ff771cbdc2e69037c44406f9cfc4ee87f08b7facdff8c273d74c24b3dbae274362aea8151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ccaba1e8ef4a3b0abf960f54132f3e8c3a1fab95aa3030d89ff4601fe430dbad57d79e767cb1f51c8f979b49dab2320000000000000000000000000000000014cc0b2d1919fa5a2faaa42f8e1e9430421e589ec7f65a5400c1b4138b205d9cb330902b7f742d5f5f9cbfdfa528fe601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ffed6f20e3b7e2d6ba8d9e5043e505233567385a5d2dec90f84dfafd6014819c7b7ffdd7a649ce9a9c763577e4eee10000000000000000000000000000000004fd48f6e9797ca0411a1232a29c7fc4fa276caf6d24a4efc2959510f681817ec39d8950b856bc30ffa28d03b421f20d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c194a1c97da407a0e4ff5d07341ec988ee2fd5b4687b412fd1bd4b6836866a4b116729741094463dbea603b13efc770000000000000000000000000000000019ab98311307a8dafd88e74411f74b2536cf554c9a8944e0cdc83fa5e128e312431e46a961ca31ebf18bcdea26b4a84f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113770393d9d51790b613d5c67baf7864dc6892c05ca5cc15895f4c9124768bf0714163684bdf5f17bd1a53c42ad95d30000000000000000000000000000000001cf48a7f7d2cef5d3fad15101c3acb59a80fe07ccfab8dddb6ef51c3c68ec93c389b4ebd005fd329c1aaeaf0371a30a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136db71a46c7eee425d3f32947ec9847828d42a0d70b7628b8895b42f6bb7a74f3235eed4b857ad2f5990ab7d3ccce0c0000000000000000000000000000000008f0b00c9f15f50d774814ec0521014e978dadf0827cccf4a455976177432adbed2ade223fb766621164f6ea6f26c6361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008562699819e683da8b504311d2a0f50f8c98ec7edbf5cd94a651cb91583ee74c25a2b7618faccde5b03659b8c4e1b30000000000000000000000000000000016022250c18f9eed5585e05ef26fd6b27056f23047bad590c2170f0f324484bb2afc113021edcf1e99c3d45a92644bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a52510c70eab373ac09c63c9a90936ea8a80906d37b19b0ed97f96e287db58a9dec8808af203814a1bece686f1d99500000000000000000000000000000000094452f6417ade2591770a9dfe1ff7cf0540aec514f24012d40b531950f394ed702c1da63299b1297fdd2614d5f1f33f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001135061c93bd08adefaad33aad54b02988dbaa688f00954b016f1d820a1c840ce78b39f9b2f517cbb0a4c45018d8982d000000000000000000000000000000000d91951db959af63ebcce05cc03999af80fded43335883b852dc142d15b12301b76b99884c5401accad73e67fbe0e9841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176e05a68981e91d4f4d38118c7edcb486d8dc84897071b8cbcf3c64467ede53591d36251c56e8ea471b39e91d0321160000000000000000000000000000000002aded3bcdb23a13020647fe841645766166e0153d5e957d592b04356bcc81b8e3a0d00ca6db4c5079a3f559037a9b341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154a8cbfb8374e095bc27a8aa76cd8586b64983ebebafc317cff1db29d52a43725d8997699ccc3ffc04771cbdf1f56f00000000000000000000000000000000011310b05d105d4107a1c4be3187aa29598d9fe004b6fe2ea0c0cf9390dae53325ce9b07e6e33f1d63f01c21d02a637f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e114703b23697a172c6d7d9c9da4b067f0417d35f1075b0b953590e7df333cdc64dc802a2bba5025df1a610e40812e000000000000000000000000000000000d9facdb1b23eda1e538c8211ee7fdd4498e95de2f0b0a339875c72717f5c303701fb88259fccd5642fab59433c6636a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cc8170f29e6b1adee45f1838930ce70760964ef7e891a9e638e2e23a1f97134d475b30ed5ea0a8cc1d5a9b96906c39000000000000000000000000000000001953828883297cc95372690a942e999c877aeaa658051a89890024e4b455617d3230c1beb16f015244480625f889f9501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fa950d20442e100e7eab3b94a148cdeed7ab15b589a0dd3ad4be764ac6dbbbbdc4520dc3f80d1359526d16fabf885f0000000000000000000000000000000004971da5b246d65eee87e3b232cd50e14cdbd77d5538d470ab35e9f8b12026fc7ac994f29f126e1042253843b48e71d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec033f86bc013cbdf0971a9152712c2959fba12ddb51814b582db597a60eb025c4f7ce40a8bb0e4685d7c80a6790e2f0000000000000000000000000000000009247a927ec0af042420213300c1ce471e1005150306086cf7eeefcab14404a10c90fd1997da5149900bad7de4ad8ee11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b94f292345559998bd1c44787d75f34595fb75c829653a3a2fb03e4a4903c88cd66b3b20f9ad816f815d4f7294a5dc5000000000000000000000000000000000047e0ef23009f130f0403541547624f78a8adea913801f4ff083bda13577d7e2e273f8945c7bd8658e8f49103d3bc771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bc4ec84146fe5042b3201d629fcd5295490b918fe02fa5f84ed7b809b48d11688ff30ea132e4ebfad0bc76ad1fb17f0000000000000000000000000000000013ae842a93d228eb585abf989c6004505b2cf19426ea27c13b07ad2f12f408982d6e7376c8401469f18a1866238f4dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cac6a277d321f35378a9f046b308c98213209df49a426ca34fb1e43f50f7531a1a0a170029b4637b9be3437729549000000000000000000000000000000000169bb341cebc52396bd83c2ea7e6f4a8d72a84053167d5b2f229f77d7896190cb7d61ddea77ecfdaf9b7ed44a9e4d1d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004533816a243823e7b3475c2e63394ffea01089254b31e2f64661b10bc3717736bf099a0c0b1e6dbaddc0eafe325105000000000000000000000000000000000169eacc012f078c717f62a5bc67d6a014b7949439add5855459f4b66c5cb9a5b2e95812967f919d83dde78faa742b3671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000557dcb5ad08de34382d56e0b611751e53e766003637c4d4f9b0d5d5f5e13fd2e6516eafaa1c0790671e5df2763bd283000000000000000000000000000000001805077c7e39d88e127a732eb738738006e271f21cfa4091127ff46343cae30d7cc24e7d61efa93c19fa802b34a40d231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003565c99b76ffb7cedda2e9ed43ed2b37c7417a464d060574739da488bcf35aa39d4d13027fd17029de1945523473c480000000000000000000000000000000006b9866b561a78eedb647c53cfb06100bf5ad627453cd0531e2a46c2ffaa9e0c17f4d46264dd79090fa982ece43e14b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000582202db870de45ebade9d081be109bed7e4de081ab169d416db6bb0e10d15880bf2d98b4d16afef1ccd2a8de4e1bc40000000000000000000000000000000004c8bce91b3a1f7768a81c3da81ec586f785562a361a5d189a3ee27203effff99496b695911d740dae0e008ff02c27761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef8686bfb3b7b3a8cef9986d3a18f36cfa4e21f7e10c5b86206066a72f8ebbf4c5c26c3a9dc93d54e2827810ccd29a8000000000000000000000000000000000df2bb3c1fd2ab48009750e13e882563a35405a495dbf721e17d9effbfa3cfb44e034d3c2969fdf83f0d7451b8be93511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d2f8cc0c810619e137fa6721e57f80b5e8ebd1ea8524b942bef4f76927dd702d5b6edbd4f766b6c3acb190fba21c1000000000000000000000000000000000896f4afa5e8d9cc9b8f83cbd0593c9f1f927d023885c14df171f9675803be5636e46f82b43c0ab6645dc0ee5fc1cc6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000085bc358cd6703ca2cd0a4ae1e29a763e49131aa7fc4c34528d3018f1a5a28407b82b81f355c560ccb0bbe651270b13000000000000000000000000000000000340fc1e89d4bfff8fc7ef363b4762fa710ca34e78212013ca2e18b910ed8959f8a7571db682f618e454910213a0586e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e85a3329ad8c8e8ea6b56f13b0ad1c1f807434178cc2e91195092cf3a0e41cbfad1d3dc9c5619df0c11b4928bd2b31000000000000000000000000000000001853fd0c2e3cb5c22f43b0a0ec8f427b11481ff306adabc8f1852e1e853aeb46cef65633e687ade694ccd19e1577ef371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016612bdc5823aa43f3a2231a6f9c091ced5ea2c00a6a9c532bee192e89a13ed0105cec809ccbbfb3c8c1604bbe0cd91c000000000000000000000000000000000756ffecefa1cda372a5297af63a448cb3303710b3c1545c52619f37f3822104eddac852bc1ab3310644b0dc5b8b498b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122f47200608d56ed78c98820b2100e67e490b1075c1e3eb0a2c6df40f4f0e33c3eaffc6750ccc82909f91ce43fb06940000000000000000000000000000000007031b4a578dc3f4a9b8c10d72d21830fad427e206fea4b99207720f78f045f8199667c7e14cb2c13e3beb079e821a7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152885db532cdb66d04941591f3d23ec04d902a73222e81d16c66083b0474037bd3ac68939ab91dbca03900ae637454300000000000000000000000000000000176007cd60937b1c554dc3777f9469103082bd22b0b86a77cb893f39e5a204a8707f05a92bbbcb905f14466a9e67bc971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2e87e587e2b33af1de6216eecbc6c96dad6b17fa38b7c58553d54790d09d95e1a3c8a39314c90a44a2ac48e2673dd300000000000000000000000000000000070164feff1a3112949129ecb1db8cb43d57f6c3f5680d04195442d35524c4ad17fd4c9a4a506f8d0f8eaf6a23e542551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cc3fb8b4629547602119596ef9af770c7f445ff2bbc05582119773d295400bec6e1012be1b41c1410c127acde07f0b0000000000000000000000000000000019a9aa5f45a437865b5d0031dd9915f8bb4c0660e841c0803ec595c50498c855e3a1c70cbefdab9a2c859f0cf8618cda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000693644e99b13c150817d409b37e250e582651897ce03f284276d4cf287c38e09ee7788738887ae98ae260caaca899bd0000000000000000000000000000000002ed5d43c840b50a081c0105d8238a458a51ffefe2ab0b3ebbf595e13142d06b6e9e4b673507931f502ea7cccaf4cc861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ea1b1b72a50bed7cbab7fe55fc11ee5f80e82fd106350c52dbde9f3b49e68b381cd0abbf7d83de2e03c303ecf3a66d0000000000000000000000000000000002e92ab97b9316acc5a4cc46178467cbb154a35a99cb5a26568e8039261568f6f7a0b2291dc64cf440dbdbdd16f8d2351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f6d8bd01c8314989358d8df68097c15c16231d66745c2f6504f4714d84c4de68107dde79c8b2893ab2976f741ae365000000000000000000000000000000000b38f3a228a5baa59b850dfd24309b3a4207c7adeb29137b876b21975193a7cfc10036c504118451fb65cd004b398b8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aca3c9193b3138cd9085123e13e9b5c4a8cf675a4b82b5b451c91628a3310be4d25d44239c7aa926f6e951a132b9bdd000000000000000000000000000000001188604da73ce0a5a1436650e3832a3a9e9199ddd624eeb5df2ce55a85cb6efc835ef1d2de093bb5592da051d8fde07c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001971f1940887ee36e930f03d3b677f3939a04f752a86e5ecaf2c1a3583c972b3e685bbd6fb742fae1033f6bf9c3e6ab7000000000000000000000000000000000dd5ebe8b2afad2ccddfb036692cc3a2d72c9200b5d3330875619001279eb399259a68f6712f198db7af6249299a13f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000799b33022b3ee24eba812de4cf544cde7a6894c344b57ec009ee483de517b7fb2f75a2d064b884c94324895248e8fa50000000000000000000000000000000006d2f24a11717ac889a2bc5994044b4790b7283f4e3ade25f7b77fdf0348e0748a523e461aacbf425179bae7638cf42e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3e3a6eb82986691143dea394a278e6f8b2917dfbc627480f19de4b3670c96ac836b7c41fef928a7fd6f3fff4be6e010000000000000000000000000000000001bc33169713146d01730343d81ea32389ca34985329f6adc5a7028afedd3d910c2c15e62d94ea3a3c83ab9c40c1891b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002068c622d6cb619dd16b4b91be03e4f0aed364b4a1c59b72e200fecaa0021905c2ed79a5c3d5493d4d0bc7e529ee94600000000000000000000000000000000021bfe3633895b1ea954125429f21ac9e7ade2dd4ad9a9ae9f244b3b1c96da79122a27ef7b15d1e232bca3d25339b33e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133689379bd57980dcad88081295a0d12dc85ca7419d15d3e24bcfc8976ad35d2de3cbfddef279cfee23a8a727915a760000000000000000000000000000000001a4bff3854b5eb2656ebae8480d3a858e0e16716b26ced496579582c0faf99959b8a389192015f737cf04643d22b99d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9dda7c7b77b9fe1b474e47454cb4215d802e5ed72131e4411987c3e8f95be67dd3a89e040e83c99f01459e2c010cf60000000000000000000000000000000011e104658935c879b09ded57f73ee2761ebdfd5de0a1e4d0b927bd56b4d2841af62cf355bbee33910cadefe3dfeef4081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100f08a8d88078eefc8932a42edb66557690f5d2d54249f0776e487db611b02bd138cc927fb7e6cafc0081d603be20b2000000000000000000000000000000000d815119f67e920273c578fbc29318d4a9b93342096c14dc1de2256fe3efdc2525ec1f73f4c1addd8620040b14de13641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016870eb02ac057797f8a76b4780c48b886d22d49c0eb8f2ea605875e69a5d19e7ec8f7d91b3bfe404421750eb4baa38200000000000000000000000000000000172db71aa5c89e0f84889b51faf4814d54ea17216742e8f50916800e5cc2ffd78d060ee36d9cdc37c76feb6b6cf73b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a03bca64ab3966a3468ed1bad6fb6517434e373cdd1f0d2551716ecc067445dd314ef638b24ebbae26609fcb3b4bb400000000000000000000000000000000189b8cb09089ec04a71f38c9e01beafb695b206aca85274aeeb598e92d61a91f23169e8284cd10902f6493ffcef890971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af35d80dbadfc569223208e2d5f515b6e7eab59843398245920a5af8c563cfc78e1d603c66fafe1535f0d480218e8bd00000000000000000000000000000000175e46f89b3d63452c879317893e7dd19d0a9ae426ce4e99d1a94cd6ee79a88b97d94d51aabba8738b62376acb037cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061f932120eb74dd2f702b3559ee4b25f7094e617bfb9b60e40534ae2f8a0eb28664576ac7cab1d91b88490c50f1fbb60000000000000000000000000000000016f39113ff2decd67f9441000194e50074d9c32359a6381fd083c75787dd1efbfa645397bb9efb512d2428d09ca091fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000644fdbd9637e8075902460961a9e59a146e0fb44d2f13dd4745b5d02317ad448541f98bde13be1d0d668cc76cb6097c000000000000000000000000000000000e5cd58149b2697ff46f5f898f43ffe4b25e87c83c739474ff4f68adf2967613a187935aa6afee35345af04baccb98381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c2d1b55c83103240e3f9f59d1f659d17cec41fc96614c695394addbbc94bb9400755811a979516e1d5e7ad5bde8df90000000000000000000000000000000005f0ae66143f7ccd61f05e6326a49d4048e27b9200240c9ccc3208e50aacb39a011a38a7c7a9bebfb03aec64153f152c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de01b52d0476e8ce8c557f3f71b5ac1a4640b67b4ba8ea69071bed3c3efaa7bd34e381736d7cb0f83568dfa238746a9000000000000000000000000000000001219cf8a50765dafdf9332bc948fcba8c47c945035eda2e0a184b43638ab72a9253c8d4347fc1765b488d9675e5b8daf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9c438588eb7cc58a165fea2418e1f430ecaf9786db2cb2d4a5d853a91bec87e72f4b11d224c63e2422212c646d30f2000000000000000000000000000000000ee39bb67fbf9dc7af04a068d80837c8ec1355584d76c6351064b4c576e65a389b2e9b87f7d3679f396b7a7fffa607bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132fd1168cdfb8946f5019f599fbfd7452dd7c89dbd6b246ae0da8edd2b29f2a9fe9020947bd3e09c7878f9a607b31740000000000000000000000000000000012ecb87a8db9bd6dc1ac3422f1f812f370b45ddd4d28cd203fb6edaa112bdab900da25e2d59754bf2a4d2404f087eeea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026146ec5ef6929be1ec2df395a878c9e1ee0f6f27be202709e09cff3098ad15ca989e2f2edd673bc8214c02c0dfa9540000000000000000000000000000000013cb27be2cb14ea2349115a8c9f8c2d7f61a9fddf2ae5508581d0f8a42d05fa9fedd3ddef6b8f4badf138f2f6b209bbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e9f1bebba2668539e154e65177fa187812df6114170ae46461021a3e7b358b3b20acfa69f1698630a3330ecbb20edf000000000000000000000000000000000f971fd7b3e060494362d40a5d4d674d2d0e3f273e48fb85a25dc556cbc8785ab813681671eead8a419dd9de717b87131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185e18ebf0c82c8e309ccc1cbc9e1aec1373da8db6d965bedbaeed91ca7c4fe0553d90858c6dea054ceecc20227528fb0000000000000000000000000000000004681dd9f85c181e785f8c06e606820379e92bba0d4ff587520132a94e3d0c621af7a5841e3ba1c40a91c5e6b3c7048f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001270c243bcfbc387a538f53b74767b78b8381668468032b5818f47fe5cd9f8b8d838adec3419060c56f50919c281d3dd0000000000000000000000000000000017bf377d16e5294bfd43b61d024e577ca63c178cb8ff8b0760860105a0f5f0eb1c5e47cfbb56133b871dcb89a87331cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001246aa044f3a02b68cb16c405cba4460834fce0fc9fcd59fc198a8c7ebb4e0b42d581bd47f727fdca571f2f816da615f000000000000000000000000000000001992c56047d03bba546c4e1e1e2e39eea1709103ab7e63201497ea3f8fd05fd3088432e9777a8cc8ff628e1d05f8793f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131b375f421c6bdd6006f18aaaf715d865c3d3a95f715edd696b56b05ee2510faabe8a9c0b7a61390c4d0786a609aeba0000000000000000000000000000000008afafb325319986179a679e4639948cb48fb738a61f4b4363e067c1ece76e512aa7371766e0d935eb037d142217a2a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd7fbca565ab850631e645d0d6466010e2d55fc3a93cb414d1e5cb4c1e5f8060ecebaa74db64614f8c0ca9b3c7adf42000000000000000000000000000000000b78a1bf6bfc8f44aa3014b18324f37297ea7032f27c1b5e67a5073b73e8fbee9d373611c968f003b015ef19cc0851891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101f7c11b79187914d9c4c84fdf4472a9aca6178051b5c8a066d13a1f99c2592489c96852486e94caab0012847c31d460000000000000000000000000000000013e73ed84c657711df767b1ad96b281fdd63d90a01497d74567df47e96a9f14c983e8fd7c2cb6a80dadf3d4eaacdcb081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f7417b1fa997a9584eaa61f336bd750fd5347c0e7dfc496bd3cceffb6fd20d6e2844642f7f0b16a0aef17dddb2a20200000000000000000000000000000000134a6d1639ae80e37ad3f35da183d7a83b6a0afe9718f01cf7ea3fa208bf7f68a296cb22badc2443fbbab51d9e368af31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147822bd7a84ec594f661e7afde6a3fc5b8aa47248981f5c5601c2300e3d55f672e9ed91d994ebd54afb5f3269b71014000000000000000000000000000000000ec8ed4e5a5ef62da3647aafb16b0d42928c9e262c45aee1e372402a221822980eff1dafb10e5c97ed5e1e519575ad251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001099aaa95699b7c65a72f0b472b256a76ac0b302f798a29bd8b78a394e83ca9e43e3ad2a2c8836ecab261bbcbc19708c0000000000000000000000000000000006df75d8fb0bf897fce956d6acf8a54d0a6476ead2cf929bdf602227d799266ccc76b6acf935a23780c5bacf0039b88d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e18a05406ee1709d7d095f05efdfb4da54558f70448989d02cf4864f92b7e150108d61fcf30d976f68c1f11ee50cb400000000000000000000000000000000069550bf7c18ba02f97f755b9735ca6208cf92fd86208e20a94c6096a12ea5b6427df767436564c024575531bf60b7f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcde442fa8a1d734b76bf959909d18278b34ee956832f5ac49f68981228484a66b59cc139333a39825c221a92530b800000000000000000000000000000000013e40d5978260b6871eefc9857cd2736f39b158fe849937152cf6f320b68408af6754de3d7d564f650766d20edd7d69a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e18ba7f45d20f1e5ec5c7dc4cdafb57530a88a0165571050146a735a3b8960c8d20ae3f3324126284fe2531545c285600000000000000000000000000000000073cb8f9b1a6bafd74b3d256358c914b42d1eea1a80269aed97d56ba7f0183b1db01a05a4ed13d14a0f7c861de648a971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130c6d6ac338b20ca3fd7bf0619b7fd562145f6c2a83981a3b23d07e77e20ee6fbea7e1b0f378dbdfbe6c206c350da49000000000000000000000000000000000cb2dc59d96e3ca227c06b0536a8913aa5561355921f18dbc397a62240d13879963c073c5b5248cd5bf939f36df7373b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fc533e5d6a74860d93c3b3b7737bfa6cdda0785854bb98f646f678eb654be70525ae1524e935aa616f51787ce9c06800000000000000000000000000000000187ef8a77effc734c97b59484b0cc6b660d74c611fd51939671ddee33fd17cb225145ebf8d3ed938249f772b85b96d911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa1dda26d80306692e16d48e98f32facce2414350c72ca81bd052a386172e8e0300363d5db8892f1b94e3d4d99343310000000000000000000000000000000013615214d4cde9f63e5803b9e321c403399a0a3edf235b4f793c6006b54cd17facd5369585564207d405799a1b55cb881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040fa595724e8beb7fee1edca40655065e9561df12888357b8d645863cc14b9155adc4ca7fc91e3025a062ef517c41e5000000000000000000000000000000001662aacd8ae85acf179be2c922835b0938a1193191fcba906162216423dbaee265a3370a6099a9293e7ddfed1aedf3521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeb732bc03bf60940e25d7a6a7bb96c0d4e4d72282f13d48d10c2ecbe87e7338739a9b1b9e125f160f59bd22463d4540000000000000000000000000000000000198fd13e1fc580733623a24203c856348c965f1d1e0df6a68327d0b9c1bf4243cdeb6e32cfd00b539afb43d52126f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119eaea67c8aa9a319390119e73e36601106006afb8a9ef6098abab40309fdc2038a3317991d92fb18ce247ca7d1f5e10000000000000000000000000000000010d378e0568c0a2c0a3476cb34a86a7515e4ce6d123cd2057498f681d86d4cd7323ff923bbe72a82260d5470850154161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040bc777a01ec8700b90fdb72f435a03a1b8d0d5c3f478de38d6c9b8ea1a31a025f8bba396d3461be1db7423e9d5ef4f0000000000000000000000000000000003540ddd975bb819c91a5e1f68185ed186d5cace078d93b4d8421cb4a645744d71371c153f386f72c4d439c77a6ad4121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0045c8c0c88094ff2b7cb0feaea36dec6a374f20916cf108f63c8a0c82ea59a32a95d32132a423db3f187516fd983300000000000000000000000000000000062fc6b5391334e7f2e66bb276e5c0a7c77f2222e1a5f09ef954d743f59e95fbf247fc0a995481ef673fa33f221161591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ab2f2387e58341e71c3de1ab9363de988f6fa23a638490784b72836ecdf6135ce185f6a0205fd2b466d5e01c11f64e000000000000000000000000000000001105363b6a7b8d996d55370409472f64be1fc8e91e3794d53af775b7639954d695c5ccdf2fa335967e1da1bedbecbe6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012169f892b89533e667f0284c59d8290b05ffc0786eaad2f91f80133b928352030c04a82227476eb5e2667c6963cca540000000000000000000000000000000008052c2a322e7cd404151a5f036497d5f6535e6c76d5b19bb517ae7609723ed3d0496fe5882a388c61276d07b25c27501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e475a6e31dd1908fa305a70802f3715f0c48f56812b1321c24ee29f9bff2e21baf3cdc9dcde0754b0259642aff80509000000000000000000000000000000001083306da90472ce0ee7d8acd29aca516c65d940b3a9dfc42a471b7abf816cc28a97283d348ff5575b0461174ede53061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111fa36dfc6fbc929fc2ac7665c8de726d656efb718b4d984a756681fed6158a8d372403e18d8e4b6a610224c6d7ad7f0000000000000000000000000000000018ef01065bf66bd295f0cdb13c6de452aab434fed68d4a7e8d8f46a9735c201b31a7cd547af2f439aeede3ea7e9c8b6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042b29dcfe6a621d023a464f1eb6b6cb2c1581ddae6af44c80f00c4eb16e1677358507b0cab6691692cd7a0f9274a2c20000000000000000000000000000000015083da0d6d89cdab1a1877c13e6561034448ea057b608181085335b96a178ae3c2b923ca16e49181538f28cf68fffc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e632929b71e05df1d4f497553efb842d3a286b0df663df9016182394b0ca1b7510c5ec7f9d19d243b178535a1bff82000000000000000000000000000000000bdedb1093a3240c5e2a4659f604e5147cf7b300497e0f1fdfed1653b6c4a24a8c9a51395fe97c27f71a5b4f6b52c9731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097cfd3608ae495961cbc69c39e4fdb2f9340593532859bfca4b0631b67d4bd237f9fe3610eac80f16cc376a9b7cd82f00000000000000000000000000000000000610a85b4010068bf5fbe661e0dcc391e8f10e641035cdf9f62e8b4e90aef3c02efad48060484bff237f9f5cf2de3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003400da5e5a306627532e78e5c31855b81a953e53ef482ea80267751b369824bf1ebce86c6f5e860f77f5df9122611fb000000000000000000000000000000000badfe57ea33b051d54b3265826c19745f7ea6da29b0717f83d2d8ac82f6073ae469fe6c6a08205f691d9713d5f285461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001687aeb40b60fd146ca41456fdb6fbe1d23be51c3d1f45a51fa9888db7aedc6cd043a8cdbd180b2301f7ab0e93740f940000000000000000000000000000000014562f0b9dfedc26dbcc60c101f5f85c1a728112417079c3a51ac909959a91bd6f3fef7569490ed01af2d91e94a6b5191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b57af56577385884e4a61f7356c27660959166550f5d2e8085bda29355a4ed806476a7bae78b30cc52d96b16570304c00000000000000000000000000000000155329db361682434ceda4cf6ce49ae296c167352bdae922304474d0e329f8c77dd433e7c1e1da9d916fb8e18e799f341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005450adaf5acc678ebb31224fef2a0d2e3444aec8e2dd843151832c5a94654c493b31f93734a3781de1a35fd5d6923fc00000000000000000000000000000000094a8d0906e575411537a36bf4448b6d3696312ee762ad9a517b4edd9fb05f82a82eb58908dcb8baca1831d009dbf64b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ee63c84b48e561471e1f4120905d6f8d91fa4a41e9edfc14cec0180a19849731d39d8aef273151e4b8b287210cda58000000000000000000000000000000000383839ede8849cacca9ce263cd58642bb4ca375090f5be0dbedd342718a85fdcf18c9013bcad6eb2f95563f9c9ff9b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104cbb266f94eca53d30b20c239c2dac542b15790bb4af3684c598541b1ad1c095a1e2efee3f472508d0f9b0f0737bca0000000000000000000000000000000011e8acb1284ecc6c88ec36f37cb7b134e49b476857f6c13682a2c5eb97a19f158832e75a801d19b6a60267061af67d081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182a9e2deb868fa23f4448b8a991ddd6e2d58ff0a6c8b24b2bfe0ccf0715bc57e1c29c1395fc6394dca1ee6396c295cf000000000000000000000000000000000c5939d45a5db911c3b719bb80eb71e412325f7c3634ca6db36beffab0f8d508c9235013730a8f481cb87260c3c12cea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011217e7aed6bbd230a65182d6edec32535d83fbedf578b16eb9e1e2d6e9b08186dd617b816ac4ab865830ac2b265ef2d000000000000000000000000000000000694cca1bdc0ebb5c1d0d09192bcae63ac87e5b6855f7aeda1c0d97093f5efed1a72c73af2085bf082344275fc09feee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003783170c2c95dc5658274d61f8b54bb3413dead820f7b29384bcecb98bdf9d53ede8288c64a6aeccee69d294eefabe200000000000000000000000000000000130bf2c37eb720c4731a850f2a6b7d9a214e26efaecfe16469b0b39a9f54e705645e8754e7e2865f74d0a7a5edc5dbb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba5f0089cd9096fd34b809210bdeaa1099a1a9130627bc3eb017688927bfd630006b9dc792544ffdd9f137cd5f9ffcc000000000000000000000000000000000ffe66322db6aeea62ac317fe949703c6125da92af85cc3e0ac8d8a5af7ab14842f1eef72c25a95737c6153f3442041d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085c49c037280f0e9994895cad16e323f38e59e4578407882821e6324ed56587010e932e181635e1ffc18396a4238c4700000000000000000000000000000000089d213af54613a338f10ecdaa3cbe9eef4b2e917ff44bffad6fae46bacf6b9a6ea9e7fb83539877f285317616a33a381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005536359f00ba85e2ac9f0db860a0fff3ebb1dd3eb418697b719c6caa392409761db22e08281d0560fd2e7b8a7ac79470000000000000000000000000000000002c9d76314878bf50143b3b69d582ba90d796d5352ab55aa8e125e032ca74d078539644e8da0fb22f01a8f4c313d9f8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fae677f9e71b5a07290e7b97cab17e2a4d83e2fe56b9b2f90a08d928eaaf7728ec9d48073e8cc928f4d886430d7f32000000000000000000000000000000000690ce4cf9f36580efd5e60418b114857eb3e8ebac4b9329fb12521e0d5cda899dbbf5e49c81d23eea456d8bc8708a161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166b1f8abdf620947b77b9e064ec983a64aa3683aa7480d14f0747ad614582d03fa6b358c0a022b033ce19c0c3474cef000000000000000000000000000000001016dc01b4b57d9db775c61e13fdf0e5c50fdbf0cf8d5d5a7a3ca0683e9f61de5d08be5ec77cbc80c7fb5f5dfd486e161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190d1adfcdd41681f541b0111c169f3e7a85e7a6383ef6260e4b884ad1b907b78f9fc2720ecc0839512ccc25182da36c00000000000000000000000000000000026319005685e1ebd1cf00da6be131c445f32d50e0c2b3fa7af319f9c339b9ed22438531d3fea33c98c9f5977982c2ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbb471edd5f0189d82b0eb5590c84f8d9c7781edb179a5cdd29cdd11d7b4eb45f0c34f1c43c27d1ed75e538e0a3cf3b00000000000000000000000000000000055356a2f88ea8d08714a2b8b9a2de24f8b3b8613b483831a8812381c01d1dbabd81a74cc9ee55af7d39fd72e49cdd831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035a7a881349b6756c3e27f2732a18ecac97eb87fb94c284bfbe727f53b4f87dcd1cac7219c70c91a1bb6b3cd4adf646000000000000000000000000000000000055a1a44381acc2113d4e3b4d359598f1960425952d8dd4fe31dd8a593b09ee2cb73893fb45dc0500e08942a1dbdc7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7d3970eb82949eccc717fd15b43d70609153a170ddc3043181c65adcd10da983389554eb5fc52bc16486de3d4107f80000000000000000000000000000000006de65b692aaee5ba7e27ae71323f8521be08d3e51ceed86cfed685c34d525497b90e865a009fff295272ff8f643701f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000110b74ad6735e703fbcace6c89e0a5a874f25498da9a2a9422be4e7b6589c2f3aa61ef7ef96557f40504306269e56020000000000000000000000000000000018dc0678a0cce8b8008618ff78e2d52d37845cebb2963039f87a890229cc441d63dc48779c20f830b63de17cd82f25761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011821defea047f8ae7e410b0e40053c551ae78b550755e53b4135af3e3f65ae74a2c8d11f2c5e94bfb485c1d7bd943c20000000000000000000000000000000018ed5c4b2ad754040b54eb495787a4703b5955d28ff354b4ce53c5dc79f003463bd92200a1d746a6eda3dc6b1cf5fbab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012c35fe854d6c9d41b0e229cf0445d30993a3be03ca8784775ebbedadf47c15a519944a08ebb45d0fbd9eb067b363590000000000000000000000000000000010c0ee7793b27b4b84465e81bdf764b36a2e3ee3fc0a149c0805a5f7e08303cd38154feb9dbfc55001471c0c73fc02ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c71d678034680a2c22a8cfdcceaba1d284829515afc9a2d075c411a233f4d383c15efdf9b38c36fbcc522805ae1a79b00000000000000000000000000000000010d39f975e0558ba1a8775949a2924b9d53af6c8d14c2eceab247beb2c5fdcc4e146a0916629713440eacca4760e2561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015593cc0c0b4edf82c121aa62a65d59e77f509864ebf834d6c4c4bceb1475e7d6dac076ce02a6c9d048667e984087a2000000000000000000000000000000000926918fd5709660cbf1315f57b16b10269afc9b0f9ab771a3d263237831f04e91d63dee1276c0dc81e8f04293e9b23d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002067e1b319c4af12c01da2fdeeb5023a6cb6796ae13f7c10136f77e5f17d59772a6a3b0bedbd536f7385a599f9a2fe200000000000000000000000000000000117e47ead23ed2ea4f0bcc9d90762498f37694f12a5bb24ecc82ec77029a0e9e1b0c7123a9538246e970e700f6d1e2d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010587fb7dcad99516c9a68832ce579e8cd07c829dc997e5c24c318a5d16cf33af493da036bb227b941cc0905020b725c0000000000000000000000000000000009d91f1a3341b9295d85026260f8dbcf909832b504d514bae9dc15011b1cc0d64ea53a9e9f39460da0d0b1527faae40e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097fe4a745fe9803efc5c4f106c56434ec2642143eebdf729991fb21ec409db2ce080c2e40998923ba173d036cded8750000000000000000000000000000000001da0439e3d62895a3e270f7b5b73d0db152016457775b90a057132178e67fc385999d68558fd482dfb10f3012a7e5db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ef73a51d63c29e98a659da8aba2b496cde60c40eeaca0442e53daa6b56a9020268af3d69e7ac338875e444ad8f925a0000000000000000000000000000000011d8f414c8c9a7db0688c6da3e719fe55fd2564e2de03e954962ebf0a59dfb59516b24e58286ee26c2089910192bfaeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030812fba39af8d0ec3c275850f81479e9c9fbe7d3d72961e0c1acd2d126435cbbbe8f9fe17438bab9f262c8c571b1a70000000000000000000000000000000013950af9af843cf55ff3cb22aa67a39892b13d2ce9ec92cfe4e2bb062bd7463804e8f48ce8942b8b3c115949f502f6ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087f5de365480c350c6c9eff3db5df2fff245a95c42ad70604d3215487cd389bfcb037ab2daab12c8ecf25c18296abb3000000000000000000000000000000000ea3448277abc3abbaf772050d964692b2f77adc028d3fab7cd9c41429f2a0ce145766b41c049bf1d11d3b82c820d7741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f0ef6647470f398f4c46d370a61c3693bb82c7ad1169b80cad8d6860105fd60723169259c2ec7c80cdecb32e30bfbc00000000000000000000000000000000107996dbf17ec32db185c7671fa4d909fe48fe901b7c9bb70ae0be66b32395df7fb6d3e8b9f46c970e0483c3cb68bd831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188dadc56fdeb7c12e3bc17598369df0b32d1472a9144b20d48226d950452686f99fc81916197d9b98b9c3277aa5aa3800000000000000000000000000000000039b400b3e1a5d1a2536f07a779599e63ca221f17c523019fc33355fdc0f7777ff5c826b8e0b247018191cda461048d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002830b178b6b44651007646505dd41a0c9edc713235163521f486cca96849618c3e96688320a65bd365192f4d9b3b5d20000000000000000000000000000000001657b61d393d2c354139f36269f238d836b1eef467fc56ea1b99db819074f9de76ced36952e4e28a84dd2b836455b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a11953a4ed918347dda5ed4cb92fe0d696d0504611a1d8257dcc80ae2121084538816b8615dfc96ad293474fb7a4b50000000000000000000000000000000010747d6a69ad299d5e15b6876138e5d30b347e156417342d7ed5c193537e6e1c0c946f0ec7612d36a5aef907de7219591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e7c5a20598669f6f14e3332d70b896b4bec6e1c5412eeebcd7908f9418252648864ab7be647d28a10f6f769b1ba88800000000000000000000000000000000149065eff48c87736813e8fb6a7dccff196f96f8cf4e9ef00c8d3c5a7f0dbdeb01b143b88b83f30aac0423310f9a4fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bde6cdf6ff6a795e333497ef003ef13bbf47b0830a3ecdfc3eea32e9b1b5b8489e47be4e64bdec5b3bd26a056277a24000000000000000000000000000000000ce5abad01f8b59d2ba06b637da67a981f88b584604be71711d91363ee23a21a733e9b2e252e915be13b352b16a7f8461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b49b39bace0974e8197c990b965acac828239231141107b2305400d9e352749baafd577262a3eeccfc283b48549ce620000000000000000000000000000000019b8ce1c1ec36df8324f227ee01a97494b8430d720c155d49f4121f46375085ced8295590c3c96efc812f1cb5756bc1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ee0c5b50d16ae6def56c2eb47dabc74c72f84b50d1001e38e1f66d1602bd48762c65cf7f18ed17dda7fcbd9631d3b200000000000000000000000000000000143e3dea2fe77a259f194eb318b252061365830a5424fbf60abc3a4ddee072c3016b7d0db76fcf24439f31c1359cd3691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157f226d40743bda60d90addcab85fe41be1879192fcda3cc28cf41c452026af8781ebc84d39866f96bffa4fabf238920000000000000000000000000000000018add4dc60856e3c65b6701f85e3de3f906e585151876d02fbe5edcb9e03ca5e5a9a8ec6570da68bceca21574ad1cc6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e37282fa13ff000c5db0eac966468988c823e82465cdefa700cccf3f6c058f5e8a4cb3f5a2a2bfc3ed0a480d562226e0000000000000000000000000000000001f71a4cae9a416c6dfa0eb43d42bf2017db82f94f0dcb7cf43f044a7815b66f5f21fa2eda37f7d0900b5155a1f25dfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a27ac4ed6b63cc4edec30f3df4874ac1eaa5fac2d28dcbd8dc8a85ef79d11101e369ac8b2d821fc14877cac1e50826c0000000000000000000000000000000001124b42b00ef786d5ed515165319f83644e7643cb0c4d765e82c216460f516da83bbfe4dce5ac047145fb931327f8011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bff757740446e9dd061cf31403623fcc0fc5d36233cae36f5f9fb237c6b33350bb32199b4240e4a5a7d2992774f3e7500000000000000000000000000000000056be9bdb9bb8ef5c12411a3ea930c693a691fc171d2f363f8ea38f645aff98a892575a28d8b820b20ff6148ae79a8431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135ea73760db39bc0c28dec2c3ee42008b75617bf3517f48ecae338a2c28e666f7cb421d5b2b40c9933ba5998bf04ede000000000000000000000000000000001140bfb083fa54e9f8783b4f94afb95daa87b43d4e228d3d1dcc02af8e54bb89225c0cf779c6f2043e45cfe4746020c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001738c3d4a273523a0646b3017a030eb25e5d8ac5181fe006b67309981f2ad4c42c50b3a9a268fbdc99136d82f2827c5d0000000000000000000000000000000019c1ccfe1cacdba083eb2c6508a4323e461339e8e9c5ed69e7d419fe3aea6f5ef0615a9d579873b9b96653dc5a7ac79e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157fa6a78fe1d801418857cc0c4cac470b3d817ab09b57ee5e9b15cd80c31e672f697e9ff051984db2696a6bb38515cf00000000000000000000000000000000130b697a63ee88848063fd5f85eacba15726ac0e5bbe0585677390c39cefd05a1a3560b7e2939bd3c5d99b2e5bf1cbe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfd68e1a744f568c5db97036b512cba89397e771124fdcb550ade4d88ff261e4ebafa62fb7bb93ffd29a5a78740ae8d0000000000000000000000000000000006674b7550ad80e3d208bc588457c152aa676181be8824e0f502788950d04dc6f97d4520f5f08329192259fa7acb7f9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001229f08d29ec0eff8364f06203bbdb1ace0518f67b548edfc9b9a6903aed94bd8e4e5ec29c9dbb2542250559ce35ebcf0000000000000000000000000000000008bbe8703842463d2ae5064e4747de36050273e63a750b8b3aa7ab3b205bebff541204747d1de0db4678e68d13a4f94c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bd214cd9be24b856fc8d0abed768bdac48eb19bdc609ec5d8a00165f425878c937afaecc42daf387c52a5a1d04d5f7000000000000000000000000000000000cd6530f58a361c7114cd34f02b39fe0e9e1b19c6704fddc99d42bb64b48b5a6525e759035297021b3438d7628f84a7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a95a40195f2bde6cae58a570987c7f50f712f90498b503cb61c65b67d04ad2e75a0a7460107d032a47f1df302164ce40000000000000000000000000000000006fb856e55f6adfebf759d1f40fe92cb55ff9458057dcc05149aa36277c3477aa288a29d71dd33cce5b916c5d60433ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b6bbf521cda75970d8937f96803018971a62a63eff8e536958fd805d68148f284317ddba2747a6c741190e37cdb4610000000000000000000000000000000010807b802e69a45689960cefe34627ed89291a1822581dccafe90f14dad2697db3fe4d7361697ea8e76bace1e959af0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f3c7c796dc6156da8a582494d70bd6d1e7f8927fdb52fd4c64a2aa0d63e91bd48d25b8ddfc63f48c6ad84d43ea9fa60000000000000000000000000000000015d886c557b490a7d609b38f9306af6c3f63bf97e90f310db4f25b4d90ccb4cc75792884bd9e6ebcc59144c5ecf9a5661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153915b5af6df4fc70297f410829fb9de7fb44312313662d45df144e270282f1a3f04f44ab6989ed87233d14729478a100000000000000000000000000000000176a24a6ad50ada0db8c5e22678911ee304490e2c1ef49aae3246dd2f6798916d056d970dc57ed0af6ab74235002fccf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004234d99c52e030df56d1e0996b1b9609377b10b82e42de5f7e98b176384f5d2a6211688fdd0505b4fae0a9085a198a5000000000000000000000000000000000f1deb0d205f3c553de4cb19ad7385a8ec5666cb50d41b3ff5f35c4c4b682a0ec14913d34fbe7b31312f62cd3c8ee5351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042f960a0e70adc0edc14e5ff4acfe32d98465f8bf4c79a95dd3fcb3d83f758c69b50b4f6e8434bb2525740a4af6eaac0000000000000000000000000000000003a195f39529bf68ff1a84b81b89ac4c624ea4f8a84a001704419e4efd699ba0e8bcd4428bcae5770c13eb25fe74757d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000965927620ffeb7745396798aeb67c85fc5858c135f3bcac80b9c99b739564f0b823eaa1e680d32a63da702e26b2b1e90000000000000000000000000000000010a9086cf5666c8054774baba649981c4239eba8966fac97b13f870b486050145339c7f42830baabe3b9cdbf57bed9b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000839d6fa2c972575b980f10c14f6effc5370bb4e4b9f2ef01447530fc89684e4f81b83c33469a0451011cfb8eb9d9c360000000000000000000000000000000013e83db9237dac1110bb449217a3ac45998eda8742884ec4c3d40a1dee610c15ec2b492086cf04edf540e6ae1928476a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f40f2f0fe706b9cba8beff3fbfbbeb74057377f881df252000ffc017b5ed898a81874a41e68917c841add1421b42620000000000000000000000000000000007668b0ec8861c3785ba955dbe46bbeab9c4b276676dc22dd83a126c78b49cc37e4abe79ebd5bde88bf97aaac3c605531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097608d73c5553ec354fe559a1fc0a91c5eda7fbc2847f288604004de7c195a2d49e45196ca2d41459fc8c086aee3ab5000000000000000000000000000000001956454bec3ab6e32cb6735897118eae4f2805444bf4fc65421ef3239ae42211930a371d88e130fa4076e33bd13f29061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001792666461e081e0fd1e7d598aaf0eee51974ad3cf07298a4886f4338c72f799f3ffae497a4703e5de140c70a1b06db2000000000000000000000000000000000c61d67968f80c1c53d7c0ee639c8726b5a2b410a862892152c211350ea6c4655247ac97130f02dcdb2228bea2969eb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105f4538a759a7936de7d933d1454995ad27c195877cd66aae6517ae5890b05ac08401178183bf8a051b83975cd817a00000000000000000000000000000000008c84dec52ea2f91f132277f915405eb6273e7a81ef231c360ea50e261c20feae382d15b1e79db67a8118dfb00fbdbd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004870fd12576639ee504d6c4673ed85de343b868984b396e7dbba0d69df0367b009c369c61f538873dfec56c8303246d000000000000000000000000000000000b65148dfa906ce7647ab5192b2465ba65d74be067b3aac590eefa592e1d4048ddd4b1c7bb8f5331a66fb714d92237bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c566b92ef5d9ef0f33aa14caac5452ffe5abb6592694fee382cac4788eb1ba7acd8ef8ab8ea371aa404cdd8f6ab8a700000000000000000000000000000000095f8978de0ef3286744726e8df26c1dfdab944d49f0908e72d94ce1eff05e452517cf5bd8ca7258fa4782769ca12ee31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebc3f4b274b637c1e2474a02e8b195020f3e9a7677f90f97c3c0254df02852be5ed7c295073c714ec8d85fb11b6dbc700000000000000000000000000000000135fa897779c0a1e417f6d1af81128b61d13360de57cd91b3e69bd7f7ae34d7277bed74f48107fa30b5b01d86178df7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b3de655a2500695eaa7812050a62dd71ba205e5d08beff1c2288106952b4baa5dbae65dfd9bc6f645a23598fed7849000000000000000000000000000000000d125743535fe4e55f1893a2e689f9db0adde3b3d26c1554768e08ef204ad60712d0de731ca9d65e81ebc96ddd1dda7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000931c0d5e2dcb9c2508031e6b8a4d1dab91cddf52f31a0a019401b67e4076fa77d5c0e030d7bbf67ac4b1abd93c4fd8800000000000000000000000000000000023fbfbf22e7fe29fa87e616207ee147cd1247da42b7d749d9ba5f855065b2ca1a5c84c07a50ad4e962fd8ab2c7c1b001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001908d4ddef4b4dc7bc59dff3828fe404d3f568b7c90e4c88a90bcb0559084140a6b5f8b97a5fe9dfe5458f9e8aae489e000000000000000000000000000000000f14a1f8d6908686123fc359fe3a7c4a6a9eb15c9b3b720aaf88fb1156d4c6979c458dcbe60b398c85c18b9cded894601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e5531cfc3affa1543bb07b55d86bdaf3af5f9a23c3e535c108c049dc70469edb231685757fdd6209d66919bea0e30e00000000000000000000000000000000066167310bedfaaf277bf07b9602301af885c089ff5fcba210a7123cbaad0f13f73121f1b4b7f049b8fe1f57535609541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018336035871f1c8afb338ffe9efe254cf76e66fddea963aa6cfc248a3b81de6247f97aa21c67d541bf4d1c0ad5d4357900000000000000000000000000000000046720f87817331fe3472d94dd931aa6321876556f060feb8d1271448d851957b10d4d2f1167defbc943bdf2a75a24781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f6892eb08c8e1380b57c191dd02f363b7a967c82cc18de1130d95d727d0b7ab2c4cff0e87eecb7cee45481bb794c2e000000000000000000000000000000001100c1ea6f96b4399030d434201fd4d2d6ddb9bdb48072c3747ab12bbcd5db4c88c3b3b34a13d5124def604439a3a19b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf308fb63727f155b74353721915d8008db2e2173b06b849dc83d913565a4c70a166f04cb08e0d7537c164817654bf1000000000000000000000000000000001261acd51ba3bb478cf6fbb9cebb37c5c66b88b4b8f2f63fa84c19ab034d44e1620d7dfed65fc550f7cd5442ad5ab4ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199a087a02d6fbbac39c30857942b2f619e52a68a000902a0b98c7a63be05e250ca68b2f7832bab7ec473b3778d790b2000000000000000000000000000000000c58593b99a936f3380c7773147f1de50646e61ac1156e39a1a9119447dc1b07d9ad8c3f48502b5ecc36f3037f2bf1801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009db68fbdca3bf8ad2a98bf9b9e45cd91b7e33ca7026b92eec2afa3eaf796cae96e47b028867934ad6debbbdb6bfe43800000000000000000000000000000000078c204bec8e809e36bda95277f9c6ab9c88d85f2c7045a741f45e972daded1ace83597e83f180b3899157208ce532a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f6301286bc3e529f92db82914d20c5d23fe12c6d59bb430855c3f306e42c5c92b14e68c180970caed697facd639eeb00000000000000000000000000000000107414cdf846216fc126900da3425ef179439cfd27188533bc8b57eb12d05033e488b55a1acc684f689149f164ea07d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134b259fa35323ddb6c4d8bfee81a82862386951056db9da4f5d501235679615f3d696916c12999078195d3b3f7ce3eb0000000000000000000000000000000008b5583c138079ee82b1bad6336bd93be979bbb6f9f9d3fdf529ef3335eaadbbcbc95c6b4b43708d2890ea4841e453701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000846819214c21d4ec375035d91ac6312d11ca71a740d904505bbeb2c93e56085312a0e7c8c1873d86f54decede55b5f20000000000000000000000000000000000e7971c24d4ac0579c67178b117af8865eae68a9098e54dc2230ade0be16d95203a2b8a648213b6460063bbc3bae3e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002b62fb779ae877823caeb1cedd026aca46a202d00745d5b4466382c9aef9deace93a269c8b9eed2e33e253cd99f69c000000000000000000000000000000000baf8e93b562ea911db32eebc7881d8a38e92638d058135b0ae49cfa54115c1d141c9c61604e16e18bd88b18b2423cef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067619719b934e00fc5544d387412dce58c1d0fe8c17a8daf091db354e9982ea2c03c94b287abe3ffa80668ef38ed05f000000000000000000000000000000000aa033fe3a2096e3632102d98195821635caee580a0138d113db1cc2b50c64a35f3e9c57c851d51a1722184f41fb8d671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077fcd409736ab10abce17d3666fcef33902c5004cc0292fad126b338c35e3f57bdeb7f32ad3822bf2fd167fcd7aa5ea000000000000000000000000000000001561962667a7f38c322c5b409702e481e528351bfe4d4a2e10e9e1a693cd0855d5d305c4527fa067b4f010cb4a47f1081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d4e739c363ff1ca9d73ec8736fe24dbbd1462d8b41d632502b2704e6cfb28405d3f440a05abc9fee7245eb4a3b51a9000000000000000000000000000000000d77c01323193071bb8bb0d65f180978fe3bf475c0b938b97848d20dd42627cb653626568bd732c673e66be14d085c4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096382f11181625eb1ae8bd79357fdef53290037824d86d288ebbc93f6a526291d72c8bb6104958d075992d7210d0cb4000000000000000000000000000000000f83530da3fa6554b00144012f6027b80adf20b15e48a8fe2805b82574b2c2194daec8c477c396f65f4300d2cb72b3311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7e1520804099b399bde36d9b79377059d3e7f02be46570d225d73ab69bd76ecaa7618fa6d72bf284fcbf924af4cf5f0000000000000000000000000000000018142fcc466d3bf2ee8a1efa16e7727b71f3336b1fe3b1a93d525fdf8a0a6ee34e18ac3dc0efb7af7ac88d4af4fc75da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b31ca726810fbf53187693003b3951bb9c448d06dcf8a7dbb120d8d436b44476a02c2ce887efa1f9065410c9eada0b30000000000000000000000000000000005e5ed64149e246646e38d83f2e2fa6b692971b19d806aeffae6168e12f900877be6784b31ac67434188c8d30967fcac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d7ee0d3e07177ff1a3f939b472df1a0aa253c1463207f52a29bef30435c7789f5fe22c68156e74b8883f4587dd30c500000000000000000000000000000000088512034da8012890760b2f677a60787859b4ac72682879886c8de0942edd5eb63f1a6e4718181fec1e8ea25533aec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb2d4f38563d5fb23b5b33f95fcea1f11f9b353424f5893d078432057fdcb73b561f6752efe5e92699e529f3cbb3665000000000000000000000000000000000aee0ec4363d8143bce9a8537e82c123e61027510bca53169600ae56d678fd6e513394d5b34a77c8959f301b94885ca31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001388fd6fe3b7907b01e49635fce4dfe3bfb05df8debbc8c5af9df86bb5dc16cd9c8c35b3184f0d193595f68a9a11de8b000000000000000000000000000000000ac7f2620a45dc80aa5af926587b0655ec882966585aeae87889aedc98a1a33f9dbb483a6add415e0784f452edbcaccf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004da92224cfa217420deacf8d427aa1d3e6268348a6ac0d23d4534e4c7f4d490743a965a94d8c7cfc7ba205488a27fd600000000000000000000000000000000145904a450258729a7c419c0d2e01bebc4421d59ab0baa9f20d62bae0160c9c1afd11bdaad2f3af5b910335191a2ef591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000015f95203b0f1e4b071484d974611b0a03338801df32cf9ea00abe2500bd6dbd042fb03dda5ec5bfe3c92a0505f98eb0000000000000000000000000000000001830b29e99ec697cd279005e8646931223f0fc005d8d7e152d3281ac7f3327d3013f9b322208cedc2e0b93f404f27ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c24dcaa36d609607050f0709fa8fca40d5777cac1ee44718f485fa0c9fdc92c0a7ab163373c60c69df3712df421c680000000000000000000000000000000018be04d1326b970ab176a62d682e877aef7ac534f6d6118497989890b8ae6df80bb061e8c71ddc247d6f1f6495d8a2191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006354cd30b9bc2f762d7d2970f8bcb73b33a9731c55fae7fd115010dd69c0bed9701ab3e1430373006c0745536a898f40000000000000000000000000000000002f5b7672e352e2b519eeb81ed45a9f2fcfdeb79ade86bd3b12ef27de298c1d2b9678dd3d276f7042b7e506d4a0629211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4a0b803cfb5d042cd93f126caab2991ca65cf1743beef49f16337b951b6e7a41cd1bf72acd0578411c9327a42d698a00000000000000000000000000000000029b1a91015b17ec7fc460a55783a35a8d35af3290b71fcbf7ab753149ea68f00746bfc48791621a403aafe5756d743f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b5ef30aa8ab3caf3b1af8e01c650fa5a0e96c44924d5d06e03477aecdfd4bf343ee14687e46c9a8de744a802248b35000000000000000000000000000000000aa869d7f623a0b3e586dc3b2af48bf52bae06036d29371ff8dc6cefa610fd3df08003187840b927891b5540b8b518281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b4d1e69b69e67f09aa8b8b9b554f467ce7501527113cebc13b293dfeb9394eb198fdb9b75912421bc82bcd11a0a972000000000000000000000000000000000446d4746e255d8f81ac4df1d5a451287a791943e2187943525b2fcad4778bef92aff9e770897e9daa08be733d0b08211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001453ebcefb001ded4aee20224eeb7d84fc4a79a900faf19a0b904dce7d5de2f91d57a35265b7fa95f4c2ba7c34ba7f1300000000000000000000000000000000039f9c28346b182ba23579eab72c0150c14d61ecbc5ba5894dc2d72030175ad290268470eb235af033f1af2abb3619461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cdd154d48fab1a248d4b46d6bb7c2263f868f5be6a0633ff7623a30757f84fe49db0b8b45a2d51cb275c229e43fe2200000000000000000000000000000000116657893a630d49fb4cfcac1fa16958ce7e12a5ddf95f3ea28b6d7a09821c3e162752924234a42587ddf7f9e85e3f0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab684885de7cd3029c7aa039fb0f27d6a4b719cc73fbb6b22c420b40c71bbc2b36b6c2456edd34a27d0e1e7934c3c7f0000000000000000000000000000000017329d5b941edd858127ff5c7349d9860087b64ed0b6f202eabacfaa0c7276aa7aeacf22df087c94cb6199a2b2e7e8351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ba130ce7ffb00c56dd5337bff14ac7433ca78d89a9dd5efda1d8e2462e8f69a0471aaf0acdb063d78b74ae4b35c634000000000000000000000000000000001190a2aba2064ac2350362ef83607db954f7d4ef3724965a5fb089eb0c6469b348bbb77ab2fb1abef660c2459abc0d611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab1ee4eec9c6e73b52dd0ce541f5b1a655ce522aa7f5ffa31a6ba65087f7975fc40769e2b3274cc1292b7a34014831e000000000000000000000000000000000a38e3a0d357d8771e0071ba95c53702bbb8a784c5bd570a30e4245977b79f1739304ae65d2938d65dcf323f15c068f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175bad86e0918127faca4391bc73077a1ab48aec2679cf3975e388e3066ee601190c9eed60868f8c419dc1256e8088a80000000000000000000000000000000000f312f01308352c5f6262dffc351ebc529bd9ef5a30d6bde7ebd58d988d4b4bcd4308a6760d3add2f93acd36be5101e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c201912ad9e4e86ccf98478cac2f211b9b9a71f27b6775e198982c8d7c4b176f284ce8d061b4799ebc6d5ec9d80ef4500000000000000000000000000000000057d3ce28b5f75bd164deb738ab3e0d5ba15b73b1fe5f3a1a33840f1bc7ecf33c0cf082f93409c9b61ee8a0f0eb757191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673ac336c306ad0b2a705f07417fe5a3f92cd08419931b9d11595a2d173b72e823a986a85c7165415a881955e8ef76c00000000000000000000000000000000197845419c70a99d9e6859642d4cf93e15d87938cf63a56d508656bec0e6fe9b277cf1b2a9a91bed2f270aa7ade13fd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d384d645e982e4aaf5b2b9911f27c90a1782a7c1373d4869031ed39c61e0a73c4f872786cd1a60d7aedec1cb84829e000000000000000000000000000000000ab1c707a024247b54563f879b8eac6e021ebb67cf10fe451ac9343fbf61b3dfcbeb20fe7b3e2b45356efc3e601296b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fdd1e7434bcc85444733590a911810f68b447985e29078196b0f285b32fc62cd0f3f8e0df33e367b06a8162a293dad0000000000000000000000000000000018738f903badcaaa65d4a384853e079f5fed839f7155dd81fb5d34fcd6139528f690bdafe2a3e632a7d829c08e95c8e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001004b7c2f038bf83b21ab430bb759c0a265f556214dd73895649321bb559fbb68e0a30bac78a04f16952269c23f940e700000000000000000000000000000000024d128d1047a69bf41c0ca3cf0c10cb095968c8d72a97fb3685e1f3bb848788b4f174dbe5fef7b26c48884fd40365f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001ee46624f93d2345a2181825e4e2c9f4f19439017e798b669e64fc50f71c5d7e48a1acae9b51e827638cacbc0795160000000000000000000000000000000009a4ebd9b5bb88aac9d1231eb36b0a32352482d560257f074af610c4d6de1368297cb38a0cb4ef8925d0dde389b6da3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9b4cb1eb011b931f125b3efb7602869f04e6c041a974a07411e6aca2b75ece4ad0669b500dd8e4650ddee0f104a0a50000000000000000000000000000000015ee6c929cacbd4e4f48f44fa2bbfeeae85a843cd1dd9d920a05d04e4c31f6dd4ada47523e03f8b18a5dec80872daee41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001520b1c1822fb566cbb68a1b1b42c409ff97b9237bd9383d96e9578002c72f47565396c7bd1786916d3936021137a54e0000000000000000000000000000000005f0270804748650ce51324ce0adb335a9527d7e6afb3022237656b41b83e3415c66ed128daeffa51cc9d5258825f1751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001790133643eb78f99b2325e69630a96b3b6e68bddde859e5357ef9cb7077b12139a2aab5b7805946ae08c15735456328000000000000000000000000000000000c506eba2934d1839a6d43a26bb49f3e423edc69fc1d53ff1c5169cbc2450acf96ae1a129dd434c791a61d4dbacaaacf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045715e6ebcd9a3ffcb26e702e310a9b86a38693b41f24086504a5e46ede2f06cecc53b62bb5fd637571e758bdc2b15f000000000000000000000000000000001517cbbb177218ddc22da290cda48a45e2fe9697b3cdcb7c99135bbcdee1c1df0908d02fa160a5d526af7299798c64411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000683df08172b009f344a0c09a6756b7050c8d769c663a205487396fbbe962cf97d0b2f85c117d13b3d5b8293b3d3ae8700000000000000000000000000000000093006628bd09b9a8cd681866ce7401628f1c103043958b9c4ceb4ad4f123fb4b59b60689a22720837a13ea1e49a2d6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000091f8f00c356201d81aec1d6a6c58c4033b5a7fd30e6fa5eb4d1a462eea7dc39bf679b4d80830efbb4a8a68e5f3c2260000000000000000000000000000000001bc02434a63730ef71dfc835815fca8355cbf400138a253260e72ba3c5b891b7a257070720e8137d73e6afea9a4c9501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000044358e5ce43b47a67c3e32c559bc5bc0159ea7eae087c0569f0f4eabbe21a1cf15086e9942063609ae581adf2bf5b6000000000000000000000000000000001774f16889492e6b33fa65e293ac654bf3c9d86ac6c380a7d339ed8561355cc84562f292d63ee72c292c2f45d6a6d34d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d5474c7f6fde44b420745f0db077d49d91fd8da065eab81d203073487dec28d508c3977d80f6452eb8829378d1c5f4000000000000000000000000000000000c97cb79ce73e7d784a14327f12e3078e1957d2013b3b9ece239769e5950e4cf1a7d25deb7d6dc77d2a40316fbda63221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104d5c73a631bff7a935f75fab6a72cd57d2f924ce6f71e4511516683c026ad3ad89d6ac0ede9635820d59dfbfb291e40000000000000000000000000000000006fd052e0abd6384806f26909edd0b310f82cacf4d1e0b53ce2b45501f2f42d425f1c2282b1b658f0419399b9f6d1cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000134d33c54d8590bba2e3981fb141c9ff6e52df9cecf52062ccd1e12d90c4f0f57ba62cf37e6a185af9c06aa60daf6310000000000000000000000000000000019c9a35b2d94a9a2243705a91526b05e68e3ed170c39261ac9619cae636621c0243497e41cc5bdc7ec4c3c4a136738b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015550b9dd6068a759434b6a097739048d33500f3a4857c537e86635dcb80819b640464f726b8b0dc2bcfcf8d7dbd6bc2000000000000000000000000000000000c2ee1ce1ded97c69da4840b52283e533aab896d86a62f8d12fe086c620fd76033cef213bbc681fa810e30c382d049f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c19bcecd287d6ceb9e74feba5cf9286f25d7920215ddf8e81d56abb35ac93a0d0f8a8cc40661bd92df2391d1749ea00000000000000000000000000000000012408ef5bcc98d3ad62132a7dfaf037f4456f0b37ad8b983ae9d390e1844fbfcef0611ecfe3c805b94e443b90e658d6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011553fe18ce7e629a30d5961763fb174ef5c86b00640ba0d586014b3cbe2fa70a4ac69483e9b7fd1da21920f1086424a0000000000000000000000000000000001d0c17b1900cf9f14051cff77d8e7a0b701eb2c27b92bef8a4358a1157de170e5ca581e0b601bbf9b4b2b9090b6a5091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174dbb27a1cc96819265c3d885f59bca5604ffb9071463c1ac1b3515b749860aac285b8eb9db11d6d06303b689506f3600000000000000000000000000000000175c6133ad5484dccde28512dfbbea740b7a19f5b95fb47f013869fcfe6e376cae83481f71db906d336dcdb6dff9caa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f319c933b1a32be988a9cb672a0d8fabb357f1ff6d24d23935e2e63785def45ac84b5d68e4da507938d0aa9c9b5d120000000000000000000000000000000018f64b379735cdfb045ae4111fdc9575c086c8dcb289d9481521b0f1a7264bc9aa0065c8087cdeb89924b6d0f9e8dfc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182e62382160884974e94dfb13bf34bf19cd7a4864166b8d8f90df41d8b94158397d47a776317436d3fcfbd47b24e8b1000000000000000000000000000000001652fa3db52102e772c590727a46fa7af51009d7640f3d512f84960ffa2d41ec2b3488947e35dbfe08c6291fd3e7ede41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066c1a2e39bf78c4428bd007aa37a37bb10431d32f5635e23646ce81a2b230030ea70db94e1ff7f43b0f11b3a0888523000000000000000000000000000000000a7a04b7d5944dde588bdc478cf6d22759bbb61ea56397e729b0c436a039054af9fbe99d2ab34843a6eb933527362edc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011e06290461b06a4d1bde45c3f91f85460e2501ff7ec4222b4b0f328fd76e9e37285411ab2dcf32fd7532e5e9ef6602000000000000000000000000000000000f1ef0eab341cf4114c130242cf57e6ce95988eee3982a86f3c09c635ccd155bb6b94dd4b30df7e5ed7bf4c9fc1c062a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010350dd168fde3225cf7406d643d7a26bdfc3da68ac490e1932dfbfb8b2738e9f96712611f34319126512ebcbe5af8ce000000000000000000000000000000000d5c2df7cb88fccf3e60e9c87fe41582225e85704f817deca73088bc7d92c56c69d71d8e00619079579a585dd45d820e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016307cc7e923dd4401f42c99a8ebadedaa7b7a290566c677c3b5904f2896d2736fa65d5d1126fe9e7996fee91d7578a40000000000000000000000000000000002a57ede35b9d45974646a1f66683de1b471ef33d891422491877a0501fe14110ec187400626cccc062ba226d4e59c221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cbaecab51f99d705410f9f0594eb3707768ffa072a03c81d6c165243b0711f75f409e86370a00d6ca56b196c321a6a000000000000000000000000000000000b60154fa3aec3b0449b0574442f66684f49caec95b637313d0e9dd528f549f9f23abbaec4be0ffa3589844c4d05b7091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001030eecaf6615777c9aff309299dfaaea3b286a95cb10374c5ef234131bdc8bfa4d7d0378558e226c0f7df1b7530f0f0000000000000000000000000000000001202ea63e2db63031647c7b66aec33f40aef6603d01a85297ec9a3e0c0bb984b9d8903079afcace48642d6412c0a156b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a0ae8edc0ed8d5642267013d843aaf5789a279f462c69889af47cf0b20b31195e14d538ee3f831b2d4ebc24e0ac9c200000000000000000000000000000000072d019bc43c69c331b5d3c35e984309f9550f66032114211fb40e6bdf51a7e8ef0ecdb52c898dc8ed7842120cb5512b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000754061724865567b0654afcd38bb4c35e2c7e8868288ae794f3a0c2928c847df0451c18ceadedf1bd46cc31163df70e0000000000000000000000000000000005504f200d230e1140c53fc53b60d96302371eedbc07356d613fd9386cb3747873aec2725fdeb855b481f5c2d9fe3a031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f62f5c773b8261d192194efd3ed7d2731d629bf10986a4e57a842e0d0774e6236c0e238d6df9c02d7fe31f291d5d280000000000000000000000000000000007937a960e332e92ed5ca985f4de66d75bc32a7edbbc560c9a1efd60d5e3f52848aa938590d5a29dc3304da1066ed6ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000519a249d9ae62103ee47f3275d0ead14142c8be0578d013c04471d898d52ac84a18e43c955592c2e74820f8facf42d90000000000000000000000000000000019afc23d1174f4ede9d34cb987ce79ca0c91fecf3db835c5b2e43f90bc8b84406746293c352d8a728fc7e849d7e4069b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044bea11376ea3322d194133237bae05dcc3f2ec7cbbef78949f1c34bf99a7f85266114d873ca2b929ea765a99c3eabe000000000000000000000000000000000abb75c79f7271c368d8fdf2f295786c81fcaab5c112def778636a1bf58e1d36e27007522c86dce0b0608aade192a7361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001259eb1e3d111422891cad5b506f6bcbb580505694ab8b2cde79144eb72d51b2736381ca2dc4624b4f3a5d7ef641602a000000000000000000000000000000001536e2a0bfa5a5fdbbdd6f454cc4156aad62a948f5b7874ebab9aa19be41b7c5581921698e90978f8b04221b2bb786591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a2a344bb24d32b96ceae594d566a732b142db7c3b3e35013d94dc142e355cce06c6ce33cbf554928b885a1cb623dcd00000000000000000000000000000000031233c6ebc36668fadbf7ee71083bb25b3cdc8fa93259bf486885450e80a0008e84527a9f6c3d93eed16a64d1e495a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b5979a9181ab84a4ccfc97b4ba9b77a423588e489a5b547ebc6e82b5af63bf4fe8c25ff977027f68688ae3b27001350000000000000000000000000000000018ba91529c4e3c5e60433548b9463abd07ab47c99060d68ef42b6c0ed3f96cf508293f588f563fe194c9ee96426e68f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134e5cba303d3363dc1105a344b733955745c9ea2ecde95c2b769fd69ad6f03970df2ffb222bf6b130761330761464cf0000000000000000000000000000000008a408a8da834baa9d903a4c96430828f6cfd7700c26f7b65d22fdb17edfe6c132819abed47d75302f88bb871504f55e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ab7f137dbd16ac75f652136366d7706d4bb89bad22ab4b9d64b8a78fee4f308a3862e6e95ba386057ed359e07113a70000000000000000000000000000000016aace40c10a2e3c42a6ca49fc19c81b8a6a44c5e9a51ac1b5590581ea3fe86e8b5398cc1a8b2bb03f2d791eef8358d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2b3cf4ecd2868551755018a478976208f4984fca01bd18d2a4d4a6f9a7ecfbfb0b89ac777835eed768681b8457e06e0000000000000000000000000000000001c2c5cf4e13221b4f172113c6622ba06147d01b0dfe566268ba77951e0a781ab1cd2b34bd00dd89e0d9fa8d390559ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018feb4ba0b489565cf530a1812461c11dd6a619bc3b0b82da4c1d0424aef83ffc2a9ba059f19d5f7605f6a45d5c26c0d0000000000000000000000000000000009e541f7587347d6f617a7ce72f541402de1510b9cd5840c615db05ea100f4153de8d1f836076dd2829e439b65453ff01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba97c329643a9b1c6d38452439ca35f1cd73f268ab9b5a763d89ae3889090340a65e3d47a408092baed69232f188115000000000000000000000000000000000d5951abed7ce6bd57ca5548a8f293c459500cae7a69c7bdc141a244e5aa57dc35d4e36ee5087959bd9a8ea03eedee9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f720f052b0311e03dd5f3aaa8cf9400b16f73df081de05232053934dfb94de6562744f5b8ffc83891f0e74b5c4769b000000000000000000000000000000000494e8bf92f523dc1c1186c22a7d9efa85b808746fafd979814e0f050f014f29c323a0e1cb7781ead6fc23a780b14e701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009eab960c0257a3a9ebd97f692dcd2edb5a696604e2e409dde5678aca3432a273e25e790d69b5060e62c5c5a0c6d23c90000000000000000000000000000000016d2e8719b80d218d257e2dc50ba40a5e6a2bae3c864c88cc22ca731fe306a833c0941e8c515a9af9af8b60a96b5b0001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fff55cb452bf4b29a181e05fc4a549760bc6db7d1f95bbd92013ec506949f69a0512787ef535e0de4ea39af048011630000000000000000000000000000000015d87751a0f392f35f15d536ed960eafff49a5b377287d250e8dbfb54953f81ea80d3c4ef9dc18fece8070887ac93a521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013409257cb8c5706fd72c0a3f54f01f18f52d5d7ce32329c4ec69f91f77b266b9e991acfe6c09c1be13292c9c4619104000000000000000000000000000000001256fb5641dfa056c1543f4210ac1bc71045769e28139c8ea0c2e34b5c9af2f2ceb762b6d743b7ece9bae959796becb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d9cec304c65798b07a0565e37031985a20e35fdad3de06e63b8349f90e560aee6807c70626729a8ce07de14030141400000000000000000000000000000000086f816cffc993d27d99cb9e38049224acb3f3265454e3acd4a59cc1be08fc748654b109c74c26277a6d1adaa45d4dba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001949f8c3006a9fd1b38562af028b3988d9196fbf138a08761a5996c9f78cd04d98881fe04e31a1211e9af008d3d966f0000000000000000000000000000000009a9b17ff34f25b08fdd7649149101616d806be021a0ef2caaf0f444baba6ed1911d1f228092e44195a16330d7cb1a801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001862718460302f9bfb1f0ee4bfd7aed66d8b42dce4a1947328c9285987da79cb75a66a0fea0e52886fc3c2109fd8e3140000000000000000000000000000000018556cbe768fc7bef3764cdef9d1448b96d14c295b61fba924891792059a4bc2d2ebf9af5f16ce001344d788d2d1fa511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9f8c53fa684ff07ed321549d7313c343da213ab816045432c34037b9a60c842d04e432675f40c06845b335b491e760000000000000000000000000000000008bc95295d3e64f4652652f6cdcdd2ed7fab894dc3ffc44bdda7239a42f0793f445bedef930b556db2fe4fde00f703611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f6909454c928812eeebe5d769ebe70e4cc34a3e9101476a8015ada1551467cc3ddb0dce463fd288546839cc136124b000000000000000000000000000000001431ea74c09a8e0b688766e1a4ab78ef88d34ac37187dc98bb5479761f0de4076d3872d29c3474b602791b5404ed95ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8bac8d09538b05b92c7ac2e72890884d57fa9bab00294eb06104b1abea03cf924c478b2ec62471c99a6059f29c6a4b0000000000000000000000000000000016c6ae2c8be6a2621365d08971076ef450ccc5cf2eb76c67fc951d8d885373ce27fb9a27d70b7d67899558866a99fcf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc80f8038c6af3bb8d0f31e89c2efc2b7b15f5437cc72053418ac49ba0c2a73669d9f2e05e60ea5ed91e6cd0374e74b0000000000000000000000000000000000bc5e28a49af3fa995cf68bf0b557ef7a38274e4ae2ca52bd684950dd9b2a263502d2e3257f7a9a86e243e22914fac51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097b950382ebbaf99b261e0703a4406ad156db535b991b099f546aaadf8fc20161edb8ccffb3cb02574cd2343334625c00000000000000000000000000000000187b1a57453d8a977af44987b99dfbec678d72777219be86c9564ee3b53c8d54310bfd807aa10612d23417862128d8c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b2f5d961a328aae62cfc82b4003c5332d9ef0e3227c07b6f373ba066529785b3e2d4165f5cd97554ddef8294e873530000000000000000000000000000000014a1848d2a311ea29d462f55bbe85f1f56417164d9e05f01219a3df02fcbd654240a0f1b43e7053ea89c477c4128409b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199037c6899c293b728cdd6e9e10f4ccbc8bb17c1c1377ab0877bc85b6f8891b4e6a746a167c9831d46881ba786abdbd000000000000000000000000000000000f320f07e1854612de8a3ceac12529de519f49a05ddcecd8662b9e1686d52bdced8309ab2d78d47268c99df37a3cc4c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e130955d9360bf0aafceea50cf3b4528db8017641e66c312b588d4ac58043570c01b778bc5ad65f907bc8b642881630000000000000000000000000000000011a6c4edb3e9c53922d7ca35fd3a6ddd8c80effc7bd0ed3f6f0ede8c33b246fb771ec61e8cad29b52bd9ccaab892a30e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052d83bad3ccd6ca92ec559bb270ccc727333e9f3dffa0be2f9042ec8bd9045ff024b20f855e027c4be1e2cf71032a0b000000000000000000000000000000001074fde56849ce5fb412997d89d49776af8f489824107a616a796a124043e9b6794d268788dcc3af9bcb7ec5e54d138c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cc9b6a53f2f28aff549e3b0b8c2ca7fa2ddc62c0c59c01ebced96c13363479c279eea9a0347c40271dc3ac50781985000000000000000000000000000000000b6dc2dbaec24ba15d0996b006d651fe0d92e57a23f6b14f74a4b57eff95f9c10e382a84f4c69ed8a9e6ff6fff85e6011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c2673f85e74b094adb61bf4ddd2b930d9c4d85dfe4344329252e7d7524790a056f432349ec6e6c6ad05bde1f7ff980000000000000000000000000000000010cf06e825dec655a2ad4ca87dfc550ed9d046049e7e662287558cfd04ced49833cb95e9aa08b0842dfe79e97436c5511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000699b97289001080373f0d6386d7da6bfda67ac3c63ae2572d0747ca1db42e946ac4bace449570a1e15987d6c5759ac0000000000000000000000000000000000d02702a5f7d67391a35a690413a074e1da491ff09b831d170e4801e1d5ebda34b6997342f7f13814b53817254cbd4d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139d55fc7b72e4e916369a1a897916289c3d375b25f98029eca0d6423bcdbcae31d45dc0fe0de8ec3b1cb594430d720700000000000000000000000000000000115629efc9227ba89a95948c962392d7044ca8f04836c433cc1761bd0517afbddf3b1b4e79369ef66c3ff9ff358640651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bbc4098ce17d750cc954bc3e388d91ba41dacf61908cfe851135c1758fec5552acef94cee7d046a4eb418d3c75c0cc000000000000000000000000000000001586056abaa810b260424df3f385386ab6f8672822bb4dfbd01a7999a231250767f8dfd8f4908aa1420565b196bee4c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000223fd420bf152788af499ca9163a2c10c0a88b2985c9604da0550438065d99a98a080b618d58e9759aabd9f75e5cd65000000000000000000000000000000000b3a9fc09ad2428ae0e6147921d508ba10c5573415c39b578b13de4d0535ddd4c06704f4a7c95342eebecc10739aa7701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e085d117460eecfaaafbe4ef27c29aefb8aff9840daa207379d7c7c3d4a2b9f4756153035ffc4555261f9cec56cfa60000000000000000000000000000000008dcead8bf5d8888ca814215ce50fcd81421ef661711fb318dcbd2252b009767079bdcb074a4684533d512886f5d94731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001424effafd8c24a9d2d3dd282457b6c79653dadd7285f3ef7952e7965020c68434f54deea81f7cb6eb69528a435128720000000000000000000000000000000013ea60f289f6c5a6e593d2634b8edb22a97193cddf026e459beb96a366df07f64594e0e3a2469c114635d34b9b920a461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033c05956d9d47f6773eeb4bd0d8401c11c6dc2d4ab0a257347f8f8f47313c8f498f1145c284ba785282987e12075e610000000000000000000000000000000007d77b93a2a018a9c1644fb60d9d56e6dfc73d9048b93afde7900773b0e7c490704079c493270c6306969b5a7cb0676f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c92df4fbc3dfddcd3fe91a5b964765fdbd57b5359de078e2901cf8203eb01cf68a25e18180ff17ceaf00de7587fcd8000000000000000000000000000000000204361a3f72101dd1a82a78d74fd8120b3c9c85e25676b1e0179cbeeffd3341bd9c23a7dffb95ab574bb1952c0f72981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b0a4c42bc8463e5c99d464900e05c1aba594152197b732e3669b2b98819b682ddbdc79d6bdee56e678e0c2ac1e658a000000000000000000000000000000001450e99c30418fdd3ab051d355f295ab55da37ac3b1e0b817608503a0aab370425806690d3bcb97db179c6fe89b17bc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6a3f4f871182dbbbc5e40f3619f4933d17e4178aa74b72c241a880958c886f830ef35799041424949e86aa5f3a805400000000000000000000000000000000139de4f3f5b4deb8653a476c5904587d0f9bd72139a50b7027ac0824e20ce001585ac799e1d126f62a150a00a2fa731a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136da9bad883290e409cd6ecafb62f7206f68fa3cfa8586824cbd9e4cd6706298ed126e5860b7eb36155474596c352f5000000000000000000000000000000000ecde7140870a35df40a936351d74bb9a7c17933fd842638d44c378cddf7cd0ba8e447048d8f533eea439fc27ec1b0e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75742112f08be82286f14eb0ac44135e80e2ee2d343d7b2fdbd414eb265ee4732dd218ee0c5271c6443edb48a95d600000000000000000000000000000000018663bf79f5be19540ca3f6134392462973aa92483b10b78f5bcb1377180c768a4016a7ee6ca5081daeff402e2a19df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4a3d5c23da8b18675326f625c8555b8a63216b7a58b015cf12f0f9520385b01ea7af90c360845491f0f31be33e96530000000000000000000000000000000004d13ba2fdddf20f2f457d917c0bf8b7f144e7c6e1234259757f175008bf7e2807c62bf8364127cb017524a038d9199d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bff3f429ab382c5f77a0f18b6540855e046d7ffe99ac42c5f777a1ad1748a9c0b92941ddae8b651e4f0bbb6df441496000000000000000000000000000000001922e039d95ac0175b2fe4aead5593a1adbc096ec37a9aa9de1468f9eed032d74a7908444731a0f68b84fa96d71e24d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807fc6f852669f1e20c697c6ba7a6be972b2d2edaf37640b5f7e0eaaa15e5548cba6580f757155b43544370ed523cb400000000000000000000000000000000055a7201055761682f962eb49387346b60365381adbdcaabe0832af039d16120eec5f9691a795b5b80cbd99d0dff67fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103152a3774d38f9ff9c5ea039914df2ba77be06e01cc646a8c9e4859d240f70d70ed8bb0394df0deec45a665cd73eec0000000000000000000000000000000000e2a932c2974e9cc4db2183bdb2e9508866d749e3bd214583ca7873845399d6038b95bb39cdadf99d39d2cba76ca7d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000707143fa6336fc4f92f0b722319ca7c6292ed962391a9d79a6ccbacad3316df9d9677ab16a21cb7702701427a2899a40000000000000000000000000000000009be48caae2b58d288324b70c4c17da302f8e3b2896bfd864a97f83122f8863ac10252bdd81e8e5eba3ad831903e99c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e6ab2e31494d0804a7703d844de6ea4f83ca4d3c0f17804172bc79a226f1220ae118f0b6aaf2e2ceb985a39d210696000000000000000000000000000000001409897b3ae4f2dac17a321c45c7eee1e787348e01f5408c320ac674977107d04fd298d649c9c24b5909b94f3bc7ed211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e922ef3b61546587cf2b8d72d5ace79d09c39882e9fddfbb028fa2e50c746fc310be6c1fa709441c3267f7880e865aa0000000000000000000000000000000018f92b1cd76a5c146e651a60676b776a30b702f4fc0071d1f07d3be8ad07a3c9b44cf60aea5cbc1bf4d1660273ec3e251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c88cc0376be4de2d5813eec54bdaa3f4b674e29e76beee06c152cdde87b73f94d4f029654c80e6620f44665036bc8800000000000000000000000000000000189df77417243b30a8ee53fe6596840237ce7f1a452076ba30717af727a5efdc36fede12ee51482a484cc63d7688b4c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005738835c100d4bf2bd5dee5ef730d4c2539e041b696a9d612e54dafdba9d8b03e1ba22bc52879d15adc03fdd2a9a86000000000000000000000000000000000118879b5be0ef3d7c5783b22dc21f7ebea149bc46ee3401c1e030afa6565d1b15293ac420073796abc3921cc432a5d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014916e0b677b6dd38794d50c516b0eefd630759b6ba60ed52cd46d0f6f6a5040a4b012f53da723b83fd3f6f315bc46a4000000000000000000000000000000000bd104283d7df4227bd76901d02d7c24d8594ea40bdda0522a5a027ff1a97e6ee5e2cf4a1c2f7ba92740f29ce915aaf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017577ceec48b7c761e9bc2ef23475459086743e419c60dcd245f6f96e4210b3e419cd83525c283b0a4740464f4bec43000000000000000000000000000000000d128c33f50a4dc74e847b2e143a9a920e72eabc96d5124a6802585bd4f67f5cecdaea1a393c2eef2ad8bdb4a52bcb8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001254055caa9e7df6e74e370816e3d5f171410bee1b2e063281ccfd5cdea8594cf351d4533419cc86c814c4b22fdbc9b6000000000000000000000000000000000f98027c58d94c4e574dbbc66e1559f57537315318586ad330024c8926dcbb6854c87c473171ac2bdd574ac1d7111a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af34145fef2554fb92ecb798a0eacd6c2cf4bb8ecc43802b55113a0782eab3365b4cd206e922f4dd4d1e2a712adc21d000000000000000000000000000000000b798df6bc751245299341f6d410c39bd59ff8bb6a8a6172295b1d31344cbdce45516094fe3299a58d0453968e746b8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148a3017dd1252b6072b5a705f2873ecfdb44527248c09c37db6e699cdb8b1bea38236c694f4e9768550dfd8a4ee438e00000000000000000000000000000000138ed9231d869236b6d9f5a4e20b6854301aed9ae1c33b4858b9ad9d6d9322da30914311c84addecc59ca838f1723b511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ec1a0298a1f2c4484cab04569a4a6528d6d5bb20cc6d3c6961589b9867bf09cdcd9d92e0f4a4130e4066e2fd9cd489000000000000000000000000000000000de6c4cc2890584cd615e3ea8c0847c0d6065e480d79b11517fb69447681425b959549dbc8796291f4b69d29e0eabb121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c132c07a3c24a51e743584c064e4da1b0333f557f467fe38a3794981e756337292455234725cdbb44e17ea5d1095af300000000000000000000000000000000067db5a0a68cce2156090669c49d125be123d6d02fe6df0d0ea979ed432e5f0612f33d4e2028b31b671d03e04ca92b131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160c624288787e6deaeccc96be907bcfd3b6c6447a68626e48489b245c1e5b7b02ac9e816368bd26014112723734735a00000000000000000000000000000000127697d5528dae7d3d25edf85cf053b40c8d9058b91e855ecd647ed29cd4b3b3534376d5058368cd7561ae0588611f781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c427fea83887658879196117f0ba3b1c80a8ef195d3c322628d51a488c8d9d8cc24a25362aa6c2ad3385e87fe96ae9000000000000000000000000000000000fda2ac5d2b030236025507b9062992f28e52cb9bf8682ef933c3fc8ddda069266d985adf3a841d7356b4f19f13ecf9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c2b0f1c6927e060fd2e1e3429e686fbffe312ed7aa93adc8f0aa039635756c3feebd794ce61672a7bbbcf2cb789db400000000000000000000000000000000145a0c709cb36cc9a3d9876ad14ae90473122a89395e2efb1880acacca2106a4c0de6521cddacc5f39a74f9956e6d4151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b17bbc8bcec71ff5630840f2f44ee8afa6fd1285c95de1ee1862684ae629ebf1aadb28dec7816235a506527b004754f000000000000000000000000000000001677ef99ed8d05d98bd36b30dfac9490489308c6b69aef8b45471d7278136874910179bc4250c287b3194a1884ea1c431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099b9e7162f8147ca64515763c0a1d3977b2108c5f92d2bff3efe51193a1bac2d5719c603a097fd0b33c198bfe911e3b000000000000000000000000000000001036a71dc229149ea90f2097091edf4e6e35997724c9b5309c1c98faebed852df4587dc279c27be7ef0f6d856b77c6501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088b1082c9d3e700a6eac260c8bfc1090bf8b313efb96af470953213fcbdee995fb14267b1008093cdc314d1a2f2a0c400000000000000000000000000000000136beccbb9c4bc8a9628b416bc455df705cee623e4cf785ec0780b2f25debaac9635702b6f90db6de820d62e05af118b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ab0c2573b4767e81fbd4679622385bed85e393626b163ee63194646202c3ff4e6f5394a38a2ffb46cbc8d6e546ef470000000000000000000000000000000001fb163006b922f0561a4594a9c8f53762cc5dcd10f6ce185760745faa516c9f87edfc3123b099bab6878a9f96972bcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9cd0c9ea338b6e4fd92ecbd0092f6b9fcaf11c41f1a6db16098b4a9efb974946238c2a250d3c2bd48b43f48072ba500000000000000000000000000000000007a3fdd09ccfa06e5a2280d6f2c88c2e5f71cd43bbd57b6f07dfde72e8c3ae2aa89ba554dcdfc2f74ed66066af8fcfcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aaf3d50538276347a5ca2aadb21f1270af44af2d0a343b97906570fa5ee820bb5686b1b5213183277b12f12c6cb7cb000000000000000000000000000000000f71def9c8a9b6bc555ae3250a7a3b256d15a10180058426fc385c7d1f2ec484f7968dbf0591394060218c0abbae88231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f57b512be82457b8f4575e596936844e9aa6a9fdeb16e204ec1928a1ad519fe71bed7234dffbaa566bebc401cbe369a00000000000000000000000000000000190c2ae4bee3ed2ed40ec75381eb1042034f2e14ad755b025783b65ce3f955a0311e110dc40ce3bb7ee762e41e9832df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014ddb4e74acb26fe4b3393dfe1f69ab6410660e764e546e78283e38e178ec521937f518f8b8517bfaab2b39040823dc00000000000000000000000000000000019c136f0785e341984193a5bbeb3bc6548fb31eeced9574070c26f0ffc91ee73b051916f64dde3b9f4896fd3129ba251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004561b232c35fb60bd0b816fe6f8d1bde2a33d13e810aa6e451b2f4a3f4101c7ee12a69491e06813ba321bc927e9ef8500000000000000000000000000000000098fa407e32ce4bde5caa4aa4b1f875e1ed4175b3458b69a406d738003fab915de94617486d30adb6562f3a5ad3b5e961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eab1fcc9884490cd5acfec38da8c601c4dfca4c08a3ddf9fa492cd10d042b4825102c6d7aa3b8c517d931697fc59da000000000000000000000000000000000960e84db7cb48d66e796c0b79540026f504d47ca2b1798cfd83c35f025b92a1b2094882fb85a8ab81918dbf1b2a2d6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a81e649c7e25b6802185948df23c829612fc74803572620d7c6706e7ffd4077a1f39dd4ec91facc1ee24da76d37a1ed000000000000000000000000000000000c37bbf210f00ec014f01a144626a359617ee108db28c13f8e14a5a05c17be274a622905ec8df58a6c2071fd556f3a821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ed17ab284eb2b459d711a3fa4862e32c19f9e37d0d109d28dc04011b9e23df08c4872a6196175d05aa76ae6ae17ae30000000000000000000000000000000017dd9ccb7ff37c891e037a64a4ef6e164aff7a188b20113d3be84c88703b44ff7fa178879aac4a7f48af11716b1ca1df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bbbd531022c696b0fc7ef477804567d1c7fc16c3a529a4b815ff68828ff02ddf0776ceecd6013470034468265c4c0d0000000000000000000000000000000003b36b2cb7a59852377acd258c78879684cf6970b870a8fb45f05efb85f06a14e55d1a604fd44a15a1c152a38ba22c6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001028a4dd5e0ed5cbf50feb81b975df8820ec9a605816f100ef69a0fef036e8736b535458a855a0f8f6f7e14c67d9a1ef000000000000000000000000000000000ae6f68d5c89250355c7f137634a53c286672f14e2bb30d1279f16490cc21cda283f5c4a29c86028da593637170e917b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110476c28c744fb76a33ddf92abaf7a147b0f1bc7ce46df5f76a2a41f84dccb6d75a7e6cadd5d4bd8945e71fb605fe9a000000000000000000000000000000001502dcd865a85daba8b4293578ee2c2b030ab38cd27aa041e7cb749e8495a8bad350914a15da9cb0b662602bc67688291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce47436ff67e35037126c1215450cf09b413223bb7da213c489039f437e2b2e6eec2437ca8eecded7075e138baf528400000000000000000000000000000000028db966959059d30027ba64e41dfed409a738e08e13bb5b35ff123cbcc4ab5ea6214e9985a685c90cef36f2285940391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044197fbb6caeef6702f2e49aa73b8c2ea198a331527ea66239d6c63c9560e827ee5bf10f6907d3bd8adf5c5bc800f530000000000000000000000000000000010d8a4ffbc646245af6209100cea902ab38c6ef8b82488390a13e60aadc3a01f205499cb86ddc2ebd8ca3cdb8af08d791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fadf219e7b52190f13840a590e438f0641baa274e66e144a9f9c37fa7c1a7bf6fa6be6a8bd678ea643be45e3356a1b0000000000000000000000000000000019d507a4596ba55b8ab49b624eddf1ef803e4346221b4eaa42a4e83e3f345003ca6596a2d50850cbb33433a48ae7d4ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001820af4318193cb4f303e645d8b3f05910f122ab9ddade14e18c535bd5c74b5e2ab1582a0a5265e4d44e40f0191a7cac0000000000000000000000000000000003fc00a27d948727575a2d7a5ba0c4c3ea596ff3b1eb2e57b9a51c628375138c22ca93ebeaab39e1a953890877cbb0631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8ab6cff137f979b38a05fc284f58c32478d05393e3f209315e087d5d89779f290b8e6bd405e779daba59392f381e400000000000000000000000000000000010460e84c8dc37032fc060494f0f2a8533b4f6276e27875abfc4a57f207e6c949c5361385254518ea03e2ae6e5df0a921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8bb7b7109c98e70cef8672ccd1ea68aafaa195146fd2071e7c3857e3d5da9d57432ba86c3cb600445f4396a4e19c400000000000000000000000000000000015560f9e322af3d3c8bec7a899368a0d45ffcb7c027ab2f26339d94e1516a35a6450664f8fcd0f5569b81cb07a3616cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fe5bc639557dee959ccf9172b72bb6284d8a25806d6bd98aabbced7c321f96f557960b3ce9c1a0074102d9fd1c5e4f0000000000000000000000000000000017ef6ed144cb840ec4cb664d069d246f2912e0e815ab9584f1885f38d17531572d9b537b51feec26f1078931532842d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101f2b7f4ae8d205e885d84a4b09e7de834caaecbb31e61994991ef0361017ad25bf8dec1009de3ef3087d357c4caa40000000000000000000000000000000000c102cf6af462ee1fb901a67efb90bcc45740b67f772f5e40657be8858164831f99d0b94e352b24edebe65c35675933e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006044ce11df891dca33e14e826c54df404ef4ebc1c58f31303effeaf4b41acd0b8ff842018f12f6539b1d2e2adeb89850000000000000000000000000000000005ea06237a571c9a561d54efdba1b03ad64a16a58d541cab3d15a9d4e0ef2da96a8bd0a1f5a0ee897c0e7edb0085bb181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f7730758a63c5c84ddacf0fcbece6f89879d42f1379584be332e6fa8d8422cc1eacb2174c2219fcd1e834618da00a600000000000000000000000000000000084b313b9e3f7f476eee9d84939dc270751281c5f2c8876a687e4fcddad501da2c3ca3e14297bda3551da4eeceb3a3461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049e147ad70e2fefe95f50b56aa0a896baa01c9e7d9eb2c92c64471e41cbd8e94ac867d3d6aaf71996471b7d9b9d33fa0000000000000000000000000000000011b0428bec8f4344ef72e2d3a3bfd6656792c26322aeccc126a016480744ff74ef234413c3ce5630d5bfaab2ca4c42811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cfe7c84f8259cdbb10df2e1041774e914175734f141cebf661c5f8954f76aaf73bea09297826c1c3b470d2b84a31f5000000000000000000000000000000000fd81b5652e55c74884a416f866ec1a011d361df10135e26d2bae9bb4ea21c5afb7f8d88eed18d68b0f76146b0ceeaca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110f424eadb52aa547c6aeb02cfd82b00937493c490ab10bea322146472deab2425a8201befacaaa66fe89986030ad2d0000000000000000000000000000000017188451976d4c3f15ceaa2b9ad9974510e7473d968172ff2496f71fd36f812adb05dbbdc401d0cfa0b4419d5284bd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ee5f61d62ffdc777e60d3eda462fd982942d8d7d3a75fa328f1fecb2c31278d1bfba67d728986cc0a717d536b7e7aa000000000000000000000000000000000cfcbcc42fa7e744f40afd3b8565753e8f420b5d7f0749f4ea4a36db0f3013fdd18fc772bcf2bdb93635171f9fa1b0a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f03d1c004918427452443c351912fb464c6ba5c290986055154c88538f9334a33f896cd8d9e7e7a7dc844521742afb700000000000000000000000000000000178c2cdf8b9bca61517accf152b86b2cd9004eec49401e792f2bcdbc54a9390ef011d51816d292c83b19c832b64d4d6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0ef2124eab4941aa70b6b6614c3944813378136d49596a170fbfd1d523c49b25d1294835f95ba91e416e6693ebc28e000000000000000000000000000000000ed793e5e1b84a6f79898a551562ef7eab240962f1a21b54a46d92e2d5643144e9a206cf69123ebe17203c0433583fe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db39aff46275b0f1ad346d89818b3c42501e985b134834e3a00ab2af0a93861105bf7f86c2616b81b57d61516f81623000000000000000000000000000000000c758624c0108bddc03c8415ab1191f3a47a417a8c3c4099952c4eae1f3c3b7b9fe78381d5c0337bca9e72665c5e10fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001118ecdc45d794a8e5da752f07c813ce5d2d5ec99a9d51d68512fe7d20074575b17fb781c925e04c6564a54c3a7a216200000000000000000000000000000000168a3d23bcd6e7c083ab2540b5a719a545a0f02409265a5cf34a232c268e3a635c975e288b8c023e1444fac068b6d3731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072bd0399cc64f8e8f80f109618ec63a63a441c0bce0641b20eeeeec04fbd31c3aedd8d8218179d7c9f323e7e317f88b000000000000000000000000000000000250566d87cf739953cb0bbe4e29022d4f9b1217b40432aac6e904dcd6177df6f120d19d13f59577a349c18db9e0c1e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ca1005596d46ba521a576a7876dea2d54822f606d11e9a865d1d2d2d40db2970d1f1eb91571ed7d7adb99c0946b4af000000000000000000000000000000000ff5c3ffe56b281045b302976fac3a586c7673918e89b40f148eb5de54cc7456e5aa354325146cbf33a6ad79ddfb02d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eae449cb76344bb8d0d875ddcb722bc7b6406f7747bcc872b3ebc4732dc3c0ba5ae941a90d6244224c14d37ce318e9000000000000000000000000000000000c3d3b1c242aa396588857f2ca9bfe5a27e719fa4ae08b48b2d67d39ec1c10f56663577d984b9697c78edeb9e7ef20671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f6885956471becb7db511a0068da34f58a51c6dc34116b780d3eafe165f6b2adcbc8558f2d80a2cfc5179c0254dee4000000000000000000000000000000001622531e50446bcacd7c9ccbbf458e900f174e0ec914e9b0763d5ffc969876f0ee4708771fd13afe872b89abbe02f8331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001495f71d011d23767192a7c5e4b029cb0d09f5b52cbe3175d1873c5234994114fee61223e965bdc4054e3eba2e8163230000000000000000000000000000000018e018bfc4c6e63653c2719696b7d6889984b4adc044781e79549d58582cf096b3b02203381ca73db65ddb6bfa3efa7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a590b31a9849ddd77ec83c54ecaf37ce3f85b3bd0acbe38234d6adbf74671abb5598ce6bb34d65e1d399d3f38417aa30000000000000000000000000000000000352d0e73c6b5e4f321643e9311f8d220549429b90865370061a4b54112db26831a4243fb653143e009be13d11af0b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f75a7c76e7ae0172263b05a61a1205c0c0d1ae2df07c7c9873dd5eaf8b82aebcb3ce9fbe8afc50d31c5e4cb63f3026700000000000000000000000000000000081b594abd588ed7710e6dae6b3d84a3e690ea32d0242f2846b23db056b92d5784559fb390256ab110d9e835ffe8769f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000536ae82c661a58b4599f29c29e4ba5bc2c45b67511638057219bcafc10527bfe5d927ad0800ec01a170acf3cab4afd000000000000000000000000000000000c981e963ff54df01d85a172f375c855e4e0ac6a44d3580b2c008b8ce2379ddbb897587989f7fef5c39507314e6f1fc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060d70d7b323f7e4d1f1f7ba8a530998575746342eb840a3a308ab2b101b55ce870f07ceaa7087f57222a383c947f6fb0000000000000000000000000000000004a3a3b312896aa719aebffe9ae7cf536d5c1cdc1ec04caa77a5f555d152b8b3b6203bc1e6655a94cd0b970ec2c0c38b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048061e01e777e517794a89e8e08bbfa028dfc6d3dac3993f0af4608bb4273efb65bde5ef98a41a4e95a7e77a78356b70000000000000000000000000000000002ff48c3945c43751fdfb829ff4b775db5a2a425e73cc57a7d88509ca4e7081879695020f5b442ddd3c55a2cd647970c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb3cdc685d2e912e00518de50123d0563829638cd46518a6183b88e2b1b0fb37bf63957718d8df8f2d0688f29e624f0000000000000000000000000000000019cb7f2677aef17e0d414577887997845e1aec634eb7bdb327b8f0791f82fbb5eb55d78f852ce77cd66789f96e6e9d801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123a9fad69c28ee2f8710f271fb6827ebd4a393768dd3b47367f44ac29942d2e089c5509ab41e3b3bdd18d530c79f59e00000000000000000000000000000000026d84bcc60ef42dcea0bb3cbd3e8b695a65ae04fdcf2f7f40e459034af82821be7b034d7408eec9b813255a98ea28e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f2a97a5669d252dcab8ebbbbe10244f2e0e29bf49bb0fc6ad772965ef3f3ce352752afdc5bed1b9f851d62772514ad000000000000000000000000000000000cf4fe7217f8d84ababe2cef667af63c306c0a44c113aeddfb79dbc5114b315169852b9806d5933570be71114d259fed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076fe6e63676bdc71cf72f1f306d0496ede550cca31b72386b34099fb75c86a387717069a2d59d7a29357b4e814708d90000000000000000000000000000000017ebeeac5e824240d0dd60d11fe293c7092210fd633947889e574e24fd4f30f02b49b65b045999e545b497f9fc8a82081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088bde6f7caa65dcb745403c6645700280aa270190bf9bd265003a21407fff6e5541f051e64d6747fb9418d6813a037300000000000000000000000000000000063db74d5e321fb54bea443e997a865b3249639fefc2a23838ae4a5a9fb0e866d533b2b3c07ef22ea14d7a78737634561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000610752ec6075b6694afc2ddde05e2b65f8f28ffae628b11ec7faa2d423f172d5fb3062cbfd2ba7657a7d7b4f17052210000000000000000000000000000000014564a4848e2c442d6aac740f943ec9b11d6b076b7f7b711859144259e6ab2125b05834acecae57acf624784594209051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073a59d827f6052d7095cea51cc76d426247bd416b113398d738298cfc721e0050f3f9e4f4efd9067fdff2e19877b86a0000000000000000000000000000000016539295bd719ff861a4e38dd57bfdfdca65b8785daede242b4b4568a71563bbaa06b943b855b08239bd7bab5cce40641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd5a8d8cb68897ef727fc6265f1afc9df200e89fb01312654055567edd4c9d7d2f4053dd5ba7ef3169c2ae38295429100000000000000000000000000000000011ac51b2162fe981fb44d6b840f103264025ee1dc57759ea630395561ab841cec65f3dfc69e3cdda044166e9bbae8471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001616d71583724dd03aab3b4285fe4e2bfdfda2dd83a1270a9073616823f091b081f8f44bcc0a28ecb9605df012bdb87700000000000000000000000000000000146b7d6d87e40a6410aeab5790d966b45832aed85b2fc7885a7f3bc922096709dfc1fd028bf26934afef8456a0d58b461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6786b2140887425a8ae65ed3028125f4ed3e4053ccf5c487e47eca96511d0d97a30b1ac0096dd16357377c85d3c4dd00000000000000000000000000000000090bff2093048f94ce1545d7a737adb2cc76cf20ad3926c10717630b684a99017f22a6c39f3ed1b9a7e955140c4354cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c73616481fb2fc0b533ea07501e8ab2c8c797db0a3ca2517e339ec21d5ea32de4c28c80adfd1705bca87449b2cb5860000000000000000000000000000000013393b08d1b37c6140256337a3b03fafa5ee3fb6e50dc5e2a0d679ea08c73e868e76d4a1a49cffa553a37d2a9285318d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011db23779842201faff024b712ebaca45566181787cbee9418ca0fe2b966ffa24cbdf26549bf5705d552a92ce1f5935b0000000000000000000000000000000014f7c460337e3c4413a49acf676bde6e2b69a500e42e4bd5be590a4f9c9d37a0f46622c0fa7940f25a654bbe0dac07bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbd9e173d1d5317e1388f922a888087b12bf63797a87e1624d47c6ed89f2a46abe4438648471c7ee69c5f6b6ad2a86a000000000000000000000000000000000a498b77785e85a0ab8a3061557b562074e91112f186c2f1552de927f146749f3358710040df403d0cfe58096d5266361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001219e276dcb04064cc2736608bf4d9f45c2368f59ddcfc961e0776fddb5a61813aa91ad39236524b0ab7ebf66407edfe000000000000000000000000000000000198bdaa519f206b71b4b2ba3ca5d239c8de4f121b4058638d5060d2bec8fd706f27dea081c555c2dc18aa28c5ac53fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001733b475453d6987c9e417399c4241a978a59242036d088fdbe822d51a9a73a5fafc01c0c9fb2924894fb177b8b1136900000000000000000000000000000000126f8d591a97322b0948f3230d025a20a9e6f0bce400fb15dd7145aeda051979b97830da579a39e3ef7456bdfa3f4e3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c8c82c648f4f552c3aaaace443860008e91062c285ca527153251ce051050014365864f683b60bc4eaa6ea3f3c26ab000000000000000000000000000000000d6a6a8ef621dff9d259ceed3f7ed4a44400741bdadbfe257341de6ce7cd3ccd5c7c86b2c2245eaec65decd8d96802a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c95177d7a5c2203ad8678a19994f4396eed5ec8194c1958c91f66122cf1c31c1e09554b236da69c8536ff41963f82c0000000000000000000000000000000012b3fd4c9bfbac1f22006b2c1ebf06d3c652dfa0ea0ecc435c8873582556ded084df1c6f4808b9f9091adaab887343d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b7609b2c6a27d602806f24fc45357f98d62304e8b43a959c1f11f0cd892eb0e6f6f87bbdab1bd77ac2649db68381960000000000000000000000000000000006a70b015c4c343ccef09abc894daf520fc8d20b6e0d1461da450e935b5e94b2c07f9cbaaf948da639f69188858334e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109ad0c31cccf8979062916c64cfad9e1151ea6506b2d46efbc819a11d3549a9948b199895f9fe0c05dd445e1306699a0000000000000000000000000000000004a7be9220cb74c62e745207967ed0d5820c5ec6fe16f96f1a3f7112e7e76b9cefe8ac86fb25fa296552c86e0a544d8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158b856f880a537997bc22f740ece5b67cc234bf8100177fd48ee3e95ff8280a9927a6e48957be19656d4506fc6652d5000000000000000000000000000000001480ae0d6b8111c8adefe373cfe6ecb2d9ea0ade44129dde2c0cd1b8ef6f79d32cc2933c775afc381d9d62fe600a60ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000032710ee67b2852909ae2537b6964a711cf929c7e5909e1cbd1ece2c0b302f4629dc0112b0ceaa1c45313c6b4e1fb56000000000000000000000000000000001805b1297892a09273cc97b6d8dd6258bb845f8f32ab087d840f08577949f7d1558a2da4d1e3d88a90c1f1b82a7035f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d007c829703c814de461253e18f12f9cc721acff8d82dc7dd4f580738180f3f11f6b01b6b04500e691abce0f2e84c10000000000000000000000000000000009a6e7e3998fbb0d803022ee8f8ffb6dcd7e227a730d49a9e11ed709b91f18c74269b05289cee0fca67894aab8aa19511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b841fbe72807a55f1cd6540d0ef63674f8a08ad30db6878c66d1147b47b67b3a69d19a3eb98890b92ba29ce93f29bf100000000000000000000000000000000095b85039fdcf946b23f52a71b6efc722d3bd1e601341031584d735737a70cd7588dfa62053e03baa7a55cccb61d83991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001999600ccd5fdb94a17f7626d147456b5ead657a588b87ddcbd1c5fd30f01815632f79ddf7e00e0d5b34bf779cddd2ad0000000000000000000000000000000009596fd894043e582baf04f6dab4aa24d8630ae8cf6440743a5d636b74aa18cfbd9ad84e0f778dc9b0e5eb0dd3e8168d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ce76f3232af4e26d44aecf0f34616572342f3fb64228e709ff279249193e537fc2413e584322761594c768ac83b5e500000000000000000000000000000000103b41786f5477b8189934b43d79cbc29fb7afbc6bf1c1cd88357a37b5f996885bd071286386e1cf5db6f46d16fe508a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000641839018bb72cdb6391f94e99c74e402843b60df3f03e3e362d8a534a81a115720453c9574df2b93dd27561eda74c40000000000000000000000000000000014c91b573c11d0b5a26beac01619cf51010a0909000a52094ae13bdffda2cb4d9cd7e48e1d1c171d291dfe9812fbe7f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbae97970aab184aac94bbff425ad01bc641585d9985e6378b4841e74bf4f7cf82fb8559aa6c4724103276cb7aec4d30000000000000000000000000000000009beb522a5297e76969b799c572ce74d6ca92f19df848f027051372f9416cc882d11b0dfdc803c6ab871e26f2560f2e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097e293d62ba305e6f6656e510a0d6e082cf2f782a7b41d485171fad9e338f21bdd84248fe4652aa3e2bc95e53dcde6d00000000000000000000000000000000143e52c9396bea4c79a2e68886c762468c1328e75df73dc3460f95e82bb4ce85ece96f3aa074fde705cbb26734aea3a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ad1e9dda4a0c540a2b91b2fbcad6b4dc5122b0b63d5b2ba1fdaf025b4932686d06ab4835c68ddfb6dff69c4d0e170900000000000000000000000000000000140f193c508a348e877f31aa36cfe2385898ed32331247bf6a204cfeb7136652b5619724f234303bd828abb2c5b25eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001792580d2d7bed5f4d7187590c4f4c8897929d30ad53ff5744af4fbc4b5d5c57b74a1c99e24860acef4dd87bc71be0670000000000000000000000000000000014356351f568196c162be30eaa96d209aae93533e449fbc66467e10ee97c599dc4d64284452f802f6a712ba580d3f03d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c275272dd72342fdb1f1f4db4d8ba82a751ee379a87f26d7778c929a56120a96f286b2bc8473edaf2d3d0653d777f90000000000000000000000000000000011c414d18595a1895c9af42365241095b6510b4fa5704256f714e8a81d3e4b1acecea7cf4d8f2bc01485d6903ab54c481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cc84f2190fb3643989137f8884bb4eb77416ac395407af554e8501503ee2e145057d4f22bacb629be1b0dad7ca85d8000000000000000000000000000000000f5fb1d1b64022599bfbd214725302a894f032992475349f23c2868bb18fa1836da38981f333d3004b8921a50ce3e2ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001307776aa3c28f99f6be998d64906219ccd1b880ab54a588d8993ed97a1ecf14c12e7694981f8140faf359d21776f9280000000000000000000000000000000004859e8acac76f4b2af72c51dd3497c2dfe40adc65d4762d3596f2415844eaa4f709c4b81307aa49f272a074d30c20db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095cedfcc32ea620bed3fad20f9d17057bc7b291a49f4324214b1772bcfcbf27dea516c8cfbbbe944339bd37a4289a230000000000000000000000000000000018d29e8cbd01d664678245aa8c07de3f2887b5dff09bd253a29d36b86699bca406d4eb473ab0678b52daf93f812b5cdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001355bea25feb09895aae1ca997f4a88b31fbcdbcc20cda7ee8f19a01b897343104d6afad6c63b7de8b18c5227fe752bc000000000000000000000000000000001276aa69bdd1dd0dbe110ca622ecf1f9f86d2a7dfbc486302ea0f76c232f3ff60e69904aa998f33eb0c3dbf2236bc0871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019151c38d933bc2a74c581db3cae81bc655e0eeb3031112792b6631dded36cd8d69e5e846ca8beace0ff495b5f934ff100000000000000000000000000000000182e82a6008f4f93795bf540223eef3edab53596f223d42010a04dbd601373681bfc3c5454419995ed75d0ef203ce62c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75d48ef374747f99ce2c6a4120c053d2a8cabb1cebe37e1f925e9fc34cb57a0679c18784721717456427b60269f2b00000000000000000000000000000000019c99b15a1c50b4c7d6754db62ccc0fe505d637e116c32a2136b80062d33fdd64980e5f88b277aa533cbc9b3324753221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000093c0f6cac8cad88679f212f3f69621d92560d51eb8a38f07fdb5b0e47f1ce890123050901fe5d5eed45bb769f9e3d6000000000000000000000000000000000942b35046b666ee55b79f151b21b5ab7364fab5a73160ae81ccbf61900a8b0234ba4d50613128796f0d1c1aed89ec761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000171054e20771fd095632ab51e13836c9d4c38799be1a75a74532b15c4eed6bce7f53305130fe9617e8eb447da911550000000000000000000000000000000019ecbde7d21f4aeefc6619d434fec381cd1e6ff5d755c69204e3ffac4954ec184c2907e8690b6ddc822376ca2c2dc10c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001112b63a03d018af74ca0f27bc645f6f17fa945be8b1aaed62a77f743e31368ebe61fc1d58f438fe84dd9ab78108fd2b0000000000000000000000000000000012d7625b134d15b5949247d55e95d146c6e30c3f0c8edb79ee1addc9f1130ce87d66c9bd071d89c493e76afef30f223a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bd2bb6707220d1c16d12d89f95b6dacc209bc2bf9a27273c5037dffee7c157d4ce0ae7eca0ef5662021baf5e87ddc5000000000000000000000000000000000238257b34e5cc4b6d6f3812141f5149bc20f6a589594c0b9e905f6a11930c82cdb8199f9900fc6c7ecc1db602affbe61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bedce42ca45ab6dde10dd6dcb79cb9457a71ac0693a770510ab21ed4232fd23af6027b9e431df35c2034af3c12c932000000000000000000000000000000000df657ccc2c2b2c20c6c38ac442ecc82d399efd1397a4d31ec8c3c0d4404f967ff585cee82729f86f851c6356ca0bd251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000673b26b897752394d5ff4d55f2c2d2fbe3ec3d91c6fefe43088e1e4b1e539d0b0369479aea4af3fc23eaf35e02e0ee100000000000000000000000000000000079c3da3911f44fddf352c3ad99dff853753ae696ca3f169869ffc48a7bdccdd023d673c38850eb5593f4bb37a0d896b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006a51a66a0d9ad4cf6d6a571269cf61d1260d8c73200716b15257e824ce40f9b65423f66c5cf5ece60d9a4ef17e44c1000000000000000000000000000000001145016e95c35b61aea66b4f2f98261c2ecca66b236c8b94bc2ae6b1a53c31774b8b58404902f55619784d3d819cdf981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001166faf413bb0f32a625af9d223269e43ca5a71e0f92c79ae7981ba876321bf008bdb184dd961c2c3a347e5e080c2a50000000000000000000000000000000000c2703d0ba96eff7d258cb09ed4ada8803d373e2ea4a364925d14cfdbfaa77dfaea9eb3506b058e615c42bd7c200e5e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010acf0496dce4a3d9f0b72ca5cb1f59675a294ac8f92a7539dfa661b600161294b37a99301a1d27b13a0b12e3c89bf3400000000000000000000000000000000168af6cdba3b31b3f865740d59764102d350b714a601121bfa771fd207fdd6222c50c464467ca2194a8b6d3b5f09e1461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025db1a6c019d7873fee3e7f2f8d40866f808a8a75c437aa2046239580ccb1e3ecbc7f00149ba5b82567bc0108c0a0cf000000000000000000000000000000000de040edd5f73de4732c100134e9d35afcb217225bbf0212ab5d3bc88ff5ea7d855c86ac701e18b910232cf80956e5ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011c8d1025df627a8f60eb96e6051aa37e1f6216df1010bc42b3d96eb5e2a8ed53d03eb50fc6d39772c5899c6012560b0000000000000000000000000000000003aec2de34b07290a3331270f01c3e317d8f3d6c0855007d70c7dd9e0852df2143d3c9de905b0a1dba1eebee88b3ec5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b71274f2877a8ed00d3bf172d23b9020142de223f2336b786fbc355705ec8c09353b5af777006de91f184b10215631000000000000000000000000000000000f6484f6a20fb20978e9eb71b94b14ecea6b2e0bd55f724a076b0bd5c51663b92695e8e3c700732da45eb3aeae0e00941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001606eb6a75e26b280f8058abe0c452fefb02a22571f561eb143315879750db12098b0b19099709388d2630c5a339ea8c000000000000000000000000000000000fb1235241722f2e09167482a1067cbe66583fa639081ad4c8e3b06116a53fcdac730bbd33ec899937cba5ba5a7ac3291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066fed1a40f5caa0cc57d78562b11630b3eb40b43ac28bceaf114f78304142d38526f872e6d5c3c83750d5530874b5ea0000000000000000000000000000000016535316347e4b7a7fab67be00de108a8f9b7359a0c49a2d58b1279c3e7e0aa8e63ca8c01a7cbcd08413019f74fa2d801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130b1af5b6dc6e504001471b953dedbfa505a15d46a78c9364557d5a9fc723d294111c51af73189e53aa2a0a031ce87c0000000000000000000000000000000017c7f152c5dfada406db46aac0b7d8f7c7b56d5e08af8914807ae6c9e9b11dee56c9545e722f2f8e64e2990b8cfc70511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001952fd20672ae2486b2a1bee1972088d7ba1e990231cbbb8bdd8de855fcb23f9dbadca3bca7105e6eff71fceca33ef0d000000000000000000000000000000000a4e31d994906894a157a5796692f1e6f5e033be2e3a01299194662d975983fc54854e839f879c3a3bebd17625e1913e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150681d80a8f923e2a2fe1f8f1a19ce7765c913c5ac1d71a03cb853bdb79b51316ab7f02a9e04b97392cd409cba1b8ff000000000000000000000000000000000a01a5cd056f484a3f97082b8fdf43c1ff00f5937dc89aac330295dacc1ad832f6a6e5a1e3a507e67a5419e9aca39a791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035558b530ecb98ff1ecc5c3386118cea40ea2d25d2e4e8e25bbeef7fa9cd69ae39a4de78d5665c0900a236f1760c8d4000000000000000000000000000000000a7dcd3fbc8bab4c853b9c298b1db401484825880f6f66652350af4b1ae2e74297cfedcc6412bc255a4b374f32c06ae81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd759a0c8524dbc755bada8d373b4719d0bcaf9a722e976a70f40b62d33fb1215a4a7cd1402fe0ba20a9f28d7ad57c900000000000000000000000000000000185f4cea3e456c25efcb4c2a5770aa5e0de4b2556e4c827ee234531c5785c29148b36808ead601c108e0220d554b70a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bac42521dcc70be69d6ea1e844b99e870cf29fed3e176ff889dac057201c3d7f8a7d9bc7b61d6792b273e97885a84d90000000000000000000000000000000005482985e06dbf2510b90b8be3213640b202c5ec6c572ffef1672abd02c55f15a97612902e270aee0e7f47f40026e11c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083e97e8fc6bd9d5fa57a30ae72d54283d6fd3b1ae19f76ebd64d5264467222214d840e48874ba51c76315317c5e752e00000000000000000000000000000000119e5ea8a334eb2f367fdb5c0c40c13809c8d8224e206c6a29f5c5bfa18c7533e2ed9971972d36a6d6ae483ec0e95fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b2cfef0ace9daad7baa7629eec891e7ea578209ac9bc94a4917cb82359d99f11314a5f81f2cbc185ce25d90ce81a6a00000000000000000000000000000000174a6b9fb60fbd017f214d002ddba7596c02beeee3bf9e679007214fea6d60c645109c3616079c2a58e0784d04cca4781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a272689068abbc959afe2845ce16117545fc13ec1d8a6453a87763439f3970ae01eed6d20e02331f1485570a14d826a00000000000000000000000000000000005a1ba371762575fcdab489b072ac197e8dc65279b09ac3a94b19bce01fd80408c82f094fa8a7ce11aa2925d18cc0201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c534a60de438b1829ef559743dff610495a93d5d9949eb974f2c0c78cdc2a9b64414a0d1690ce7f005310496662d1c000000000000000000000000000000000345aaa1a7ba189eedb457fb99b9aa3b0f5379c224bbacffb3ea388fa133cc82f07b9b349d09846162777781da7f91261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cb3041e6973b2440ffa499129350be0d607437acf5a92ab4cd317df6293300e2612d69e417bb58225ead19da68b1d3000000000000000000000000000000000a67372c5bcc8476ba59600fd347d7bd0bc971d86f52b6004bdd0bb8413b9aaba76dff76465b0198917e5f66b0881a3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185770d658f382bf37e5e28d502f1a8d1e1fb16b7846cdba8d0d061cbd4051d4e77225e4683432e41f3a923a51d9f99400000000000000000000000000000000073860d68f0edc329825632061b7ad2cc7c0de07367ff8165ccb3c3cddcdf4b4ff539bd2e2e58b81a617abb0f88773fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066c51bcd2c6a821a00a4c1c5d81e3c5fa817e7a5adb25f9e22e4563e81d75f31c7214bbcfa1c1dae6b0e662270c862b000000000000000000000000000000000ad0ba0f5515dd08422fb5303ff389f383ef399499c63e3873dc00ac744dd856c5e614510539dcb7df0ed2e7348691511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4251016c0372bde4a05be67765ff833d7116cb5718cc6147ae269d935eef194f7ece096a210aeb36ce3ad931d905e30000000000000000000000000000000009131dd3c9c908f02307c8a447003e18fe07d106239e5c45f129fb1af5ac1480aa74585b1e9d4c2a1c9289bf8bee6c401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bd49e84bad0e9b07ed81d57218384a0b13fc23ee981e95c634434ee2d2fc2bd50305ddad9dadc7a845da89b0e82c7c000000000000000000000000000000000b7d5806a901c14f7d149a1febd957589e095e7a0f751424f5464c9a11fe87d0ca6d7bbf2daad42006b32a02d46809b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ff38766c7310003aa1e05d172b9bbe9ef867bf60b8f01647069dd7865d0ca1b4d085913790cf866f502760a4afb000000000000000000000000000000000017dbccae6e9ecfd5854a57f1fd1f27309e815f03fcd87236af60af1a0f910cb89c77043ca5508e38704ce6bc5b04e2341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bd8417c3edf98676d31179914a5e9e248420d0c3e164c38a774b2a85187ecfd27fce8a7c8aafd8814f47150b1a8d540000000000000000000000000000000007afd52f80daa5f04729105a1602aa66fab9d6249dad4f4e1b55aee8c98bc9a2dcbaf36dd96647e67a90598fb1f90cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f5dcf4cc9a605968c842771e80b430af1ac6c325e73917d6c9ca6065ee88975007074033b68f54dcc0f1659e7f95d500000000000000000000000000000000198bfcc0fafdeb4f45cdd4fb65b125803270c182d9bad293d6525bdad1ba6ba7e930dee9e65dc3b61574642e5e6706ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dda18ad34f43bc17e3f8708519dc0a31d1f1c300191a7a57d6d80dacecac18d53f89e39141a9909277c4f332284de500000000000000000000000000000000139c2f42c8d215fe43c8728d6f89683a32ec4402a288ac1a079bec56a17fba86d70eaa09027eace5e9341e158418f7221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008357084539860615f2a6491f0b8828993490397b766404d0a97d04a7016015830fe33c29b5f2159e874860919f0150b0000000000000000000000000000000002b69fda7aea712383132d2778dcf9113d49cf3731662df06832341dfa3851e921d2be47a493dd45a90c342ca8c39c7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f835bc3f8a6c845087f6460f42c58ac08a434f04e61d7bb167d64eabf8ae37bcdd9f4520984a4f15095b14e1c39a2c0000000000000000000000000000000003b00977e36b9aeac2fbe67d2d4361cb646ab7ba3cbc82495865ef5ff7045fccf74d0fcd1c1af845dc5b63afdba709991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0034c649a979f9a7fb38cdbd5139c1c9fcf7b5fed2e01a583f6d78e8a083f89e73dc0c360ede09826ca2761be4bdb2000000000000000000000000000000000b132f073f9fe0c70da323c711925d1cc1f7ef024e7c5729d9a5f31df6c4075399d890352dcf3370e58c3d6270c467c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000721ee2c1cfedf346f8a5b4b90ebd2f41ee47573ecc7793a1a63f4c6c91266299ea588633c54c919ff4aedf418b3381c000000000000000000000000000000000f3d58f573ffded7c03206719e71e3c776d689cb41d3e693b6ae5d06db71991aae1bb1cabe822c2c145e221181c869001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000580cbf7539329132027d92701d69aa550fc2445b24f704f550556b2018ce49a584eaf95b1dd55d39471f17f06bb4961000000000000000000000000000000000cd0d571c7b96a54d9d11abfd69051b8d5ed89018844515f5078bfb657ee09e51557ee79fc49de3166be2c4c8467517f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c22b26f017796f8276727446efb3053822ec24e4fe55ae629410b26a791d4a3bab71eb845131800cdbefc5d0b5949800000000000000000000000000000000118d1ce29682fde0346b5b42d86d11ee4a2fae6131f8c74a6491da1d4ac5898a2ff9208fc9a2ee331de0923df7c834631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c82e0ba1e9a49fbaea47c1e1e1b0c8771f1ba263601b4b37289178df68cf4dec35c04cdf55549ebda44bbd8fb1e8d50000000000000000000000000000000012f56e912490a2ffe77c3759f54f4909bad27b9e1fea231d510ae9a4879e5e78603764bab9bfc8f6f4d629e79ff8bfaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b003e57e1c74fedaab38e0e2629e6efa9afbd2de8239a979d420e8034d24d15b45d989a5843cdce523079965263ad700000000000000000000000000000000036f893125aad6575996da90dabfd73c93f793c296b6e08123b1c0d9fe7bb57a7c52ee9ba0f72dbe41a93b2dd428da921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f282ba2df9beea080a1463341323945ebfd30c5b68492febb868722ec3e32412d8f692299670816d3994d30cb8d4e5000000000000000000000000000000000e2e03c9519430e5c9dec3741cf0f3dad719fdd34b9857ef9a860cc0b786085629cc32a895ad9181a21d4d43356cfb491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab2bb6c1769ab85dcd0227b375dd6b14c4b58495d0054acbdd77569b4c59cb759fbe0e2a8db074b0cf43594ec161add0000000000000000000000000000000003a51d198e15a3f26abbc98f7791f5a94d4eaf3d455834567fd0967bbfcbacbbc81e835add3bb8c7cc16c6e0d58604071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b18eefe08f146eeb93ca3011510cf6bd45057f62a7b20158d6e6a1e40295a4988cc3cabdc6e0012ecd5d0c8df0083c0000000000000000000000000000000001fc37fe7d05cb55e9f019925194070c346cfaeeabc87fa3bfd133ddfd82340cdf33b0628d5eb4e6ab464a42f6966f201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001195e53fd2ff7175fcea36da131136eaef8669bbc20d2b31596119ad1ce1790a16442e1dbbfe237bb0820100a8f3b830000000000000000000000000000000003118c1236f48d28099d8bf5dbb16639b4913d231d1813e2b4687f9c53e889308988b1848793111bd9f73b1f410d27161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdec6607776099cd4dd93007c5ddba4272119d37abb836a82dff7c734704f81a9e31da21b491bf00d56851d6f1d9ff50000000000000000000000000000000007734d972cc7a64d979b9cc66aabcfbb0b2ad77caaf0ff40cb9eb78183fb3178c2999cc3bcfcc6864c1f22803d80e33f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bae441613a18af6e0049c78c23f0e784d0f0137dd93511a51b398738e5eccdbee89400f57f9be7f88714a7d33f0175000000000000000000000000000000000d363643697e6c58c00168dd0b3df281dffa2d27bb4b172a08068bb2b05cb9c1d2da26f8d512c329eb64191a84f5050f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001679eeb2722bbc5f31822673c07dcc7a263c1c8cae7bd058998659a954a55624455fc800731f06c29653133be8ec755d0000000000000000000000000000000004e62ca6e2fb6f576135c06aa5b53bf0bda70347d60f8f4926f2d7a515d91fd92ec67486eb9e4267a47a62afb84de05c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000199df9102d15e0319584ff77851c04952b5a68f477ae84d570ffada39a0cec817151905770ffa78381be32a397f3cd80000000000000000000000000000000015e4e114824b65c9923313ceb2a7d360f36d07bf5e2011d6beb00f97c92abdfa6724112c44e7957476312a3d17e659b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122b47e56e34daf7653d5bdcb3e75d887553ce99f21bef5974f9b2fec5184455a1fa0999af7f28b851a420470c6cd6b70000000000000000000000000000000001542687df8e6d52972bfda3e5dfa7dc6bc537ae13818f31fb319adf5b042c7d8d9094f428a3d766208c501c6d43a0f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de152a37cc3ab1e9553e0f54f800e52b155d629994a73eae549067fea6d14a0c2b156b1ee3f9b781cfc3b3b0b88bc3200000000000000000000000000000000083e2a21921a77bccd34e8e626c64cc445a0206a73636fc8ebc5a7c4b018c36029f4480e2636e4b10bafb6a651c1282d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a7ecc412be53d20cdfbef4ea0ae7007f25a8218c39be732c91b34e7ad9ad05a74cc69817203b8929bd9c16568573b0000000000000000000000000000000000fd10504cc3d8ae4ab0ab1ea7492d7b09362ed5ee2c5af9d3868a28e029d5860afda4097cabd18c57e53ffa6c47334661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001719bd521a9e71a9a0f7192b37aab412395fe04b55d000309ffd1e9458d239db9799b900715dfb4930b60af5d2c3763200000000000000000000000000000000191555e483ef578b9183d74ec432814e484be7da872c5861a8a9e070472115dec554bda7c83bbb7ca2f73f0ec67b05101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000c41e248635fa186c4497851c814e124988ba8f4db329c2ae72ce5665d511b0cf72b3ac3122d1b825f5d14ba6e3e67000000000000000000000000000000000242e51075aaf087155ad59f34daf37af824839a3126f2ffbc29c2ddf4c832f36000ce312a03da4568bb01773cdbb34a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189d003b0551a8cfab4ae83ac67e2d97fa7d3ecd470e841395da9969aa48b9300f8aa7ef4e5c00ce76b3974c7524f552000000000000000000000000000000000427211b247b475aee0274df2156121639e3dd759ac85a9a5f2fbc80251d656b9a8301b3da04cb1abaf94ce133b871db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000886617997d171e3ba6c99a27b2b79cd48d4ffccfae6cd213d716f766c75b77a4a8907a8d0bd1ad7daa650569555681a000000000000000000000000000000000c38d5187a918db63662bc5ee2ecacfdcb50934721019cc8e2d951bb150c910986b127da2b099a78af227f1a24e8bc2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039c3f38885a296dfc969dbe139fe0ba8850c9849344e43959da74ba3c88336b1f9b232923137e00f63bec94964e453a000000000000000000000000000000001001b0029ffad34d03f4b566317c6b9ce0ecfc9e94103bfa91e5a5224a41f11930846ced29939f2b33d29685890ba8ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f4f05ae2bc9b05ccfa85c0d751cb2c0522133d90cb1d422ad71c69b6e5deb9aaa729c4041ab1410043eeaabfb8d74c00000000000000000000000000000000188b44e4059c88e9e3a5c084ba310a1069924fb65d592ef4aa769709bd39e68103503ddb88a6164ddc8cf931a883583a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab7eef955b9ca1efee65980764104bf950223715f740584aa8d4e1178db867544cda3d97d43c835b3ba4ad9feb813af00000000000000000000000000000000182bdb028dd8e51364c986a788ba4058b470719d774c0e05975c564be87eda5d7532f926c3015e73a0dbedc9609d16ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f2894a4691c802c027d769cc090c3044060798c64aeb5a2dd310b30b998cfb67c47be9cd8f80c76443231e06699bb1000000000000000000000000000000001775b6cf3eb18fb3186a1cb7fe202a2de13940b523260f6d08f0f68ce368c9e24982027b973b201e8752ba3e9a7f77ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d7dd438519773b2494c3f48f94b6ff388c69d0d479cfdec6200f20f14fbc89c169b67abf25802cfe570d162e53ced20000000000000000000000000000000011a236c092df352578458db1765e09fa33349d18987db181696db16a7fdf65215ce31fa1e2b40afb5ed2382da101e4201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150bf08f70f4de3cc46a9b2b4a02eeb2e574e536476aeb2ffdffc842625d4ff6eacbce0b015a45450836e52cb775a8080000000000000000000000000000000017a6fe20fe5e4e34e810fc6208d5572f1b3bad1130ea35002aa3b8b8b1cdb9c255471051de989d73f7455575a77269001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034ca0147d6ffea3579c17b5a781ed74243b56692391b094ef1e3b7e795bd7fff4a6f4f00031d249bd42bf36d0b72ce80000000000000000000000000000000015a98ed5d981938cfe7f3ff90d838e0dca637557bc54e4c1487a59ab66d16343d42d316edf8d2cfbb324492e98865d6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab2166ebc6162beca7edd8f0770cb0af3dccb41e613940f841c7e601bc93db8afdb29960827c2245ae9bbad099458cf00000000000000000000000000000000117c22e8d504895ea1cbdce447698bca28affad52d01ec7817c2ef4d451dba46cff01364ca87cac4c0e3031ded1eefe01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ce43b125d8ac3323e9f08d13fd556207450e996433da1dc56fb634bac2422dd12d3e72ea8187a4fed7e6aece4ad25d0000000000000000000000000000000002893624b134e5e4ed4a6ea787b39b2140d7c6f0e7da65718a973874607dac91f3cc8299ff88ff656b5ce270889d38be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dbac43d51c70bfc0fa2265895ccd110a74e78e7900c1eb32e878a7a319a65de850e7111a1b4127720cc96ec53d7b75000000000000000000000000000000001219ecd60c5c62fde6f58d4174224e073e08c6b859032437f528867823cd73aef065938684cfc423d0a7c6c707b379d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016098b07be0a5e22e2d010f3b69745578f272ca4fc1a631843194f0a6d80228961f1197aff6eef549e430b77e36b93a100000000000000000000000000000000134bd264a3ea6c8a6f46771eca7d68a7cb8587dc988c0d9acfa15c766a1aad683fdcc07c32dd8160109eefc3dac1095c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad200a52be3dd4c621070312d35255b95ffa56153476998e0c603c12cbbb7df2fa2e3328dad1dfa8882b36f85bb9b0e000000000000000000000000000000001428eff2221b92061eb59bed1ddc8a3c292155ab515d0a12ff9e3095e009df65a9057cb2915f01bdb10c5fcbdbe3832a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75476d362d3479410a431efc172aa09e6860fa1b7d74230aa8e104cd49de3ead3d4c6184619babe09cf5abf6d7d12f000000000000000000000000000000000bc07aa8979744705e2526b8962b0453d867dc03c9c0b788f1ee0643c0f12f551aad1ce3bcba1ecf8db7dac3df30d8a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001923f2229257a834002ce2f5cd1003be34c05775bc93be2fc953017fd361e1eb5534d4b373ddff2f105b3bef760856d900000000000000000000000000000000157c20830e7acc2484d2005fb9a055f603d6a2d930bfbf534094ecd336e39f7b763630a109f574d2dc13b338d4c0d62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ad6f12838e1c8d9cfada32515c3d2b9a202988a2288385f9a218e64bb6bf53d7ac4ef5a0864dc54797aad0ad7272310000000000000000000000000000000016017f2cc8b4a4bb6b9fb24cf643e67411fa008cab0138681da6b89546492841e15724a761bf074fd99fa9cb725b5cb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcef5c0049a794b5a7918363636d393f87c3b34e225bb37aa1333348b4ddfe678254b1caaffbcdd25df1648363a261700000000000000000000000000000000175b56d2f43bda56dee6393ede61a075ec600c9d529f35dcbd228387bcc7cbd882c9012eccf2f6df46ee3cfc3eeeaf0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d49783696c7c6cd324a3f27ca5d38de3d014cf5e205ccd7a53a8257523f3a50dfdd973738b3a570a5adf6f5b3b41470000000000000000000000000000000000985eb4158fdcf22d7198d8016fd5d142f47a0681adc5e953df8478359a151328bb9618c12cec6f54696c1de892e7211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001050fb60a3c82453f68fc186ce3e1ed02f6ac8212861806b8fe29652c1875662d32e5fb073004c9f402154917552b6ef000000000000000000000000000000000e9dfc089d1505e13d0c41a915d720ac1b1175e78e0cfd3b420fe2bdae5aa580eeb164c7fe8837245433638c9c650c5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000706c3ce43fe463bf0250de2577108ecd8d068964e57dffa75714d54a6dd27b0f82ff46dd272d72f55207168972ff9010000000000000000000000000000000000fade45a4a41bcd1ca186017304e0db2e45c664b98175636e631167cd8632354ed715d07961d7c713ef80e50bd43d941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bb6b3286c17986cc5c5f9efe88e58d3443d00c40a2b0ba9641ba54a6b0c7dcd64d955e494c5d92cb85976b896519830000000000000000000000000000000006afe9d4877065e46efe7b8c2780e0dd579eb59f51b330f8aa1fdc777660648f99d93c3eb500372c6267cace3ba3e5181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000057dcc480aaf282864be9274bf3ca7699d62995a592d8c644ff1f89b5a1b9097099e9de74c8f60d40753f7d41ce6a00000000000000000000000000000000002574a2583f1ee4049089f04986e9e1aad89a4f1e65db3dea058cf710bdf6d9c3abbb0bb40c85844b5faf4d865765ac21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df10fed4bb30c8f1612f7c9fdec4c93259d0fe2ac4a60a5eb839f1b8790238278840aac3cd2eb0673ec7590008ceb6200000000000000000000000000000000001cc197745bc860881dad6f36ef7c9f6328e942f3cc94efc323c9fc2bcee545b02b11092ff585345f0a8c966b57f7f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dff6ff2ffe2af6bd7a750d9b05cd79fe8c389f7e5e9fe9cf54f2ac374f40dc25011465e65081d27f577942d5e01275c000000000000000000000000000000000b5b417d7dfce5e19156b4b57f72fd95588e7a743850d92f0293de68a519af6adca00ee7b24192da81744f85b8eea83b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002107b07d573481e0e326ffa415a63b32ff50878775b83dc6263ef3830fe0f62e82f01965a5638c25b4dccb9b6c48cda000000000000000000000000000000001341554c70003b58a6cd0f8c1a5dd8ccd6c990487eccc7bb3bf5b4d4ee685e31ccb8d86010946f822c03ea1ecd2775f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a2d029f6427723df063531e523c0b3d53fcbb876962d4821a684c65b911905955fbc53ca193b829b785f689997c02a0000000000000000000000000000000011abcb59a45c6c79a53934adc0a1b2e2f03cbeb3952f24d3bd92f6b5abbe042964b17ddea720db3a610dad890f2d3c401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070f17c0793c803b709111a90700bfaa3a2d618229ce8225be0c7a85808d92eed6f1ec1d9b44757c9cdd401cdf1c8ba50000000000000000000000000000000005a934358f8a7362c05a881a3bcc1da5fde19d6e43994f2e607b9308fa790153e41e454ecfda74caa8a689a2633c489b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fcb0c935df793c1f25b489bebb38a1216c83a082cd234a8bc7ea728281230d886b770c8dc8cb6e66696675ea1548280000000000000000000000000000000007cea65bd10ac159d24bd2fd0532f7802bda997f4c31befdd2e799efc09cd23bd7cbd81359be49e4e2b29f269e53e7c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008251020287af5ebf948310b2d0c718f92a6bddaec3a456760a35bb8bf23651140a2bfb8960d10de187093588759011800000000000000000000000000000000166120e0a17c851841b6c6d7512c815f5e0b0f3e740c0c3c0f7cf0e7581bf02f28bf697c330ba0240d4e061ed7593ae41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c4d82516ff1762e0a44795b4687c8b8fbca63200b53340af38d0d41c0169e46925cb7c8a255255d175f82e42393b830000000000000000000000000000000019e7d8b7560c51d0311d795dca5b97471dec0b36f1efe52e90bb54f3dbd7b44b7edcb206596bd80ba68023fc94b5196c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014195c5169d2bc6d9d31a143317c55856535c1ccb4f3f401f656eee5e2e07224c04a82212b0b295f31960593950f967e000000000000000000000000000000000cc32f83d76d9faa17cc06550b7b2b5989d063b72c6d6a8658df7b03ff4177537a7412c82f8be81ed56a16d6529c48bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117dbe8d8513333f699863ebb7a604717eb4d3191fe34b3fb6bb42d3f5fdad6c0208df2014fa5237c6afe4b30ecc15710000000000000000000000000000000017bcdda756df685282981153f822e14472fa187bf105317c46f5c49c87cbfc94a2cbcd006b93e71c26d94d6368b8a3071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017138bffd5834ae1bc660c089dbcd8eeb913aa3aade8da8b7489b2eb87c5527ff392a4c429b6ffa0566bf825b2421e9a0000000000000000000000000000000016f7ddd23e3459eaee15b294f06ccbedb428c9c6934fd185b0d33325b91067c58eda147e3395ef3303898b9947c334f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ac27cc2d8552dc2a4cbc0cae91a3e5d178b6ac2ad498e74d1a284c9651130cf477fc58e000c6f88d5c191838d7b183000000000000000000000000000000000bb54d5035ecbb95a3ac7557c49c5f45bfb738ad39abb84f733fa9289efa9a7433d5e61a41a995a8ece7b3755ee179d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032f710645727bb1c49117baa7c7903962013737c40e3fea6300711ff3b77bff5af6810edd261547c44c12239e153a8c0000000000000000000000000000000008c8cdb9771e98e244cd75dfca38f23a0dfd504087f744137279ad252c1d52c34a0dcb7022c09d63711a05d00d4e41d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b7303e54b1ca9ec39fb3bbdf881c1427e66ebd6ed58bb6f591bbad6c0a0ae0a6d837c402e398273aa2d398a2329e3d00000000000000000000000000000000007dcaa47a5586a9b8fa0f373a96212c547b32b9ef376f36260fe8f85f6fd7a5ccc1b90a6fd5caada61f5bc361eb38dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fdafb7768d900d2d900c4328a270dc2fcb6fcdf951aa1918e8e73f5c881673bce8e9691277bb35ddc72c04c9454a4c00000000000000000000000000000000089aae702b51201215ceac74a1ba557eb15c761ba5997d554539e98fd79d212a0231aa466f04b5595646ebe18d35acd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1ee6e4470ac294093804b610ff0c233b4587d80682ad00d041c2db61a76c3ca6563340121c1ddbb1f5f4d659045166000000000000000000000000000000000cb22831ab3a26a990991c18738b79e19acc423485fbf3caa0c0e08c2544c0da44afdb3ac4017252326cfcca725ce9c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d32a976a3308f49a0f8330be655033f3462ec55b7155c04085bfa77faa38fce70a76d557d892e5976123b8d4166d95000000000000000000000000000000000e32a70de4ca8e4ab9eae6b5e1daebbf8c5281ae16f732c34c1d8e4306fa790de9ed847165576c2d7e1771f417da33131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000251a8c1bdbfd43dbd739cc49df3d3f2dcd9eee2e481a6e4d9f988709ea1d507eaf0fd40c69b01c8d9fbb65f5789a5f4000000000000000000000000000000000dc0ca937eb55529ad999adf5c208590d1bd6551a3509f7faab2efe3be3feda9b2348044193bbc0a33e41eb14869dfd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dec810a2ca7f2d46775d7c9dc7a9b9338619e6d1618bb6df5166f968770f2e4577b4632e01d9914e3470674367b70a00000000000000000000000000000000190cda6167278048b731b919d8973e12287fb104e8e1b7da26b83a9048bc7b78f0e26e5faf6e4d2ac97ba1f75ebe87161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c66a40ab2edccc6c79b358322a79792476409d798fefe32511a2265ace229c718afeb3fdc8a800995601a0a1499ba1d000000000000000000000000000000000577f65da4a815da54b5901c917485a7287a75e53e5d802f6addc4ef05643a979698bee00363f68265e03fe285f96d7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172fec9f191804e66d23cbabf1363df207f1a2c83fb34486fa0cf4a7020b28c7fe3f14e272b02822a83647f6812681b600000000000000000000000000000000092bb316167a3dfab5ac6806a76a3493427a87909eb19ccc06d15ddc407a5bf1cefa13276b7a096cefc240ea23c43d671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddfcf274889f9098cf717c130edd950d8be9f1a1658d1c69fa841dd7879a70cebeb4cfaea1c31bebd8fe250b1ba7e6e000000000000000000000000000000000f4e4ab4f559c5e142ad550a6d033b6a24cbe8c2f72aeab56b82f52531f1b8b901bd496f49c83f31eb44542ebfc8f2c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f284ef8c378290c7a07e4ba4c49079c5ec31096fcd8835aa8086d87bfc2bf460964b12cc87f9e1cf5a45a4ffda450c0000000000000000000000000000000011eeee3fa1edab6eed94181fce1473141a699c5c14800fe58713f44fcb42306ef94704df5c7ec1c42a294d7037a6f2161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018df084c8000add26252a8f2a5d128587888b50f31e01e017f748b420767e0121f6c1facdb03ebcf49e0631c85828da000000000000000000000000000000000fbee5702afd32030ddd485cca9918945bb9d7f6b8eddb8b49c87a698ad777a385b5a357e3d08fd9632f859167bae7cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ff3a9ddba8ea46bf9c4bf84b1a89f84bc892e4d327de415373862660052ac8961c37296a9e511e04e63d1522b51e7a000000000000000000000000000000000f706aa2e0c47d94c86985036c1e554f565b9052133c32734a154c29df6c675a1231aa1a129c6aff8b884e62b40118301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035578fcd95c71d64158abe7c208adbb5a1c3a9b5a76dab8113609fae680d2817cb60a547eab8647d163094efe4e3f63000000000000000000000000000000000d34d9fbb399e057d8f435068204b3058f1981121a5ecc63dfba9b969300496e45c19d167c2a480816f2ac59c79416211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c0811e41e5ce8cf7589f2abe9a65629a5935a9c778f5f3e8be6fa272a908f7324b1947a6e61d857e487d143be6fe8000000000000000000000000000000000074b16803126d7fd8bdc867c72d069a75139bd17be8a2e26292202220b1d3f2039e069cd4563656f35534648d6b1dff11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abac46d9caf0e70f1c5ea33ba8acfe37a18a6df210219053a128f0a4ad89c246d4cabcc2ab452b3db97c0e24245f7bc0000000000000000000000000000000004da7a6230cbc0d75ad7d6d745846cedcaae5bbb7df5ef0138010e7890ac960876c5416c5dcc2d8b892a4d397ae3a4491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106332e62070830a02876ef10d23016239edadc9dfe2ec041a7a85fe691c97991a8af8e3738b71c985a43ae40e51a4ae00000000000000000000000000000000116abb64db2f03b687249c66f444c4cc3b068bda06456a773a461a1131b3ec970e53d640f00953decad9500a2aaff21d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cb777e1c9f77c6232f7a3ce1fa2f99cabb467241511f1ac40327ecf7bb8dfa0b201183f78932711dcf4a4f47a0968b0000000000000000000000000000000004199bb1b9681e4ca55746f9bec3dcd83cc07edb4736b025abd2d9aaf625a8e9f692768aa2f26e0b0c6dd5981b5816cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b00e370996680bc8f2113a09dcf94acd89dd74905dff81ccec15d3f8c68e0cd6489689fb070810fbe3e79da633721fe000000000000000000000000000000000d7381d520d5584f1d224497ae615484c2c887d1cb4d0554a02bdc72a0ef5c9a32ad0e27b25bb8c5f8f2afb6eb3a72b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107c1004ba60ca9603fc6a582f290247107c86812b9322247a055d4569a8648748e258e8d28cd41fd43c23e0024f2a90000000000000000000000000000000000b144d001a5da1bf1153513039a8cabe4697367edba05d74d17ddaeb29703b8e95f31352d711ed4bc2e75bb191211a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f12da7234025c5fee95f6f6a50a63b2588993085f6ff097e59f8125afc2445335a04035b3a3a2b0f7233f3a2817e060000000000000000000000000000000002e19867c2bb015b56a86fd085729e55c69f2434684707073bb163f6c2f0675afb676653ca9a1a73ea2f79a645158f9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2cf49a05083c4d4ff93addf75f34ae7b09e98ad3d1624566fc40792ae6a75390eea45ca2061a2bfcc82b4dd9e93e9a000000000000000000000000000000000782cd194eb089160a6ec3819554efec099a6b47e3dd865d5dd3743f4bea19962f17aec1ef1a5e025abf770161ff8a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b884ee2fa05a0625cbc2b241f9822977c0bac869a86e1c4ea553df124a755e920f633fc8bb9a14882cf81c16f9903c00000000000000000000000000000000033597121b1e5176dc3d91665fe2115385821575530852acf29b2f45e3a466fcd0cb28ab49863c8ffe8e4218d51c0d991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cbc36c1b71baeaebf662514ada557a7c07127e46a9b6bce2770c6b762c190248731902e65b7330dd04012b84375d440000000000000000000000000000000007d047eb9290ac0a2987287bdd3a5ebb180aff6e6da25f022dd94b8c9317c2bc081bb199f64123e8e698732819ce2ee71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001046a2b39c7341f9f36ca3b5da7186e184aba0936de635613e7eec9086806bb27cf8ea99e00f324dcecf03d1ceee7fef00000000000000000000000000000000131ac04f57d925a4d1174c166a387db81d1674862552f2783e6f0e38aab2a43b2d5ec158c6374a36195ab5abf3800b791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae01f62e61dbcd7e10c05327a54432be8aa14837608334f047516aedd8a3cf39c5a7ebab43e2f1354d09124558c55ba000000000000000000000000000000001059ceaa6ac2feaa425ba1df4c23845334419840cd31fd57d6e3fdac7a20390e9f575296ee1ddf563a647f685c75231b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a06a9f012e5be6900eaf1253eaf5331927dd4e032b563df7e135545768b422b1d16de295edf256b1e613b29389b4160000000000000000000000000000000017bc1cc1d2b2759e78b850e3dd83b257a98fb7c39e79c95b4fe5ffd496e80253c0a0f137be1fb71d33c7b73930e58b251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b102f8311187c0b84e622a0ed9c497fafdd6dfb39f8e40077cb68a268230c1b82be2c4b558ee04369d53ddcd9b5f0cd000000000000000000000000000000001725cc4af7985779bcd7af3936874530f4e2e99d753cd7c40dbc6df10f61c8b267b7d9161f235905e844e03cdbc5fb391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d27bad5d6734724bec530f5ebdb15c334599ebcfde49ca635bb373b991cdecb45fc2e3757162529b6266a77e906ee900000000000000000000000000000000003adde06f1f82a98f890b41f0bc9a3f56f45dc6a28ba67882021ef69f92a59968dc01e329df5bf3aa33fd4580afd7311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001480fe9796b03f65c2dfc8d7667c88f888d4559b84b9dea6f830af8715baf80951a1201bd9f6ccd3d8578344fd93c95c00000000000000000000000000000000004596ac83e4d53f8f9322afad8976d0378f41a54a9efd08ff81c10dceff0f0a8306d28692abce430d0783868dc4236c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000592a66e57b12f6dc54583d40654ed5e13610f729c4da9c9e56f81e76459fc83e6edfc97b6ed396d2b56973d1180283e000000000000000000000000000000000545eefd6097db75c33c16ca92df93f6701033f6a43f79970fceb1021c1b2c42d5b1ea4fbc1d21840b7112d0ddb6e9051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3d8b5783309e8bfa5e183128ef55906980e7797dac9f49772e3da92b7fdfdbbe377106adfff48bd8bf4f6c3ad39fa2000000000000000000000000000000000888bd6f1fb9cf82dd6b4c0b993aac19e3802b84f4990d3aab81d3adfb10327671ecd00aac394ea353c14a9c2685efbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f5d460d6e4cb387e2aef66046d0551e0d7b79e37fcfbc5847409e48aa49c578665e2f9951114a061f3f8043c9cd632000000000000000000000000000000000d7fe2a8d29c82d7c0eb5f2ec5f0cf22ed0a0e16b2e08b76d9635af481e3fe2eaf1196e64d577b981267ada0b2b78a9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122e53cb3b6f15b4609facd738166dfe707e925d1cc78a757da2ff1f7eb460646c109d9a6c19c07ecc76506ad8d5c0e3000000000000000000000000000000000f8822f15ea9890e0366e9497e5435a4b12d76db5bc1c2fbb057154d95ad238f2366ac179e7374730c6bee69e282b1091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199486c252e88ae64edd7996285ec0ae96b0f8c47adb17b911907dd47f889c54222b1e2cbc0bf813ad04e1cab2b72d71000000000000000000000000000000000c448c1102513d70f485011b83571bbdedf797cc8ddc7435f6078505851332761736dbf1aaeb85dd37cc1ac88375e5691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d099bbf190e608841e934025a6ad2813663029078d1a4cd55a138b4770d2eec66649bf1a8b2fc52de1d7e600b98fdaf00000000000000000000000000000000060d8359a72f8027c41fd95517f599e211718dd2b6cb7ee799c9d519b9af87aa39d0abdd7de87328870b633ac44075c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028de2d74c1e4115ca8e311ea8a3183da2b1da74e3d9d39024053d4747eece68a867b2fac606e6b9fb6a1a1b7bdfada80000000000000000000000000000000014a52d0a2bbc0da103bfbb41e33b42f2a2e25c3d2b6d8a461c879670d05328fc46bf76faea4d61fd2c39161675285a8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019feadb8aae9605128ef8a7e5e7464904692935b4aa0f071c83e5d764598bf22cab0d447bec2b75ebcd352f25dd29435000000000000000000000000000000000e29f99d5cd00b229437da308625e789ab51bbd7aa1ce07b3bf0fed81eadfc27644b4288cf3ecc4b7616706c9d19ce861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d47568f2e41d4f12e494ff1834b373d8e6e5751dea9a0f92326c90159a2a4a1a366bb7c246dc5e7c8268ff76f20f02a0000000000000000000000000000000002311c179d953bac57c7e78b1d47eb826bde900dba9e926a889111899a0a474db9e79b5308671ff55219249139a07c911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f558daa5331f7f71f8a5c202739d2667c94c7d4f8c4526cfabeca521ba817b59313b74252f025171e4215370571c9bc0000000000000000000000000000000005eb55a322d602619742e2c7a0789e59b932d2c06b463749bbd74b9585a2620fdf9dd9ab4a45fa13104531777fa07e6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c82b961e57d515ea0892781a80e90c379edf06a0e4c9f48caeffb1c27ed4da3f6a4aab4d606d4a4b030a2bd3b7ed60000000000000000000000000000000000d0d8d96ace834b3b78f655391cf0dc64b400da5a6dd3881f971dbf7839712d9cb2eea058ff7adb334adcdc7e370764f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000111da88adc2dc96023c63648302a2c6892cee147a19cda06f409fb59569e2df1b436b9c897eff4b97356035cba0ec0300000000000000000000000000000000015d4e9126a3b202fd1f6707ee5e106c08f595c1b80451d2707b9505ced85621fd0c714f08b2cc13747d913c3e668a2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129de780407a19165bf441c33ffb126eafe5cf19f374c0431bfecd5ce038220b24e396d86230a927e3dade4914e509fb00000000000000000000000000000000179545433a62b0a912d61595cfbd9f300e8eb51d01139afbd5b1c28bb01d326ab7dd21ea766628b606466a6550b235c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000664a3a100f40b55def8adc08dbb4e8a3531b6069b6d0713a6618e39b42ad66df85a343cfc5123474979e66158ef667e000000000000000000000000000000000db8e7e5a3d862009901b66445ee9ef8f6041a6767b313ca577eb5fab44612a2275eb0c3e7df29d58c28b051ff7ef2691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49fd513593e6c0ee647d266b70b6f6b8948d3df30a4ead1682de173717e2bb66b0e6f1f3b04512ee3a312a94d9d801000000000000000000000000000000000dc35533dd3beba6af9c55b7bbdbf87f13fc848ae1db5f295c1fce35abbce45a0201c8f6b20f0b8f2372daf7e13985191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cae7d9c1dacd5873a94bd1a7ce4f7b317a4f0e4a00510e5b315a5284388df54ccaf66ab6343783c0537589388f12ef200000000000000000000000000000000129abad4ea7852061262bfaab3053fbb8eae6e2576cd0f20af335234acae3e3a2f6cfde127fd97286d338c88c0c48e531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000336adecfec05020cfef6717347a5f3877ddd4ded33549832a0ba2e561e155ee327c72919bbe42409cb4ce8df2860103000000000000000000000000000000000de555f8cd7244fc3276f91d9d8d093584c1f6ac75539f274666103311a6f244e51af045a85e708c12770a77946c31471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9807a293a298622afb0f97bccb054e6a14ca6e32153012a575edec52206f175ab35c3c267923b37a1ad286e947e85c0000000000000000000000000000000015a0284f984fddb790679a726fdfddcb703ae389b81956c2b7a9fd0bb8c4d1e7998aa80d23a616babe488616228c77bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082e8f8012e85a3f82afb9c796118fd554f818baf24426dd03d6f5169f068d8ad4a4e430401f333e7285e4ff29126e5e000000000000000000000000000000001927c2b87575c2896445c728e4c5201ec3e47fa8a5998d42b2676768407fa77dc101ba70e14633f9d819f670ae88370d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fed6c8682f5d8d469f2abb43fa89c061653921426777e0404a32f7730a14c6b1eb88d8edf45379fa90494405a1466ea00000000000000000000000000000000162642d55184cee24f6eee0bd25b0299e1c927bbabf5424d99194240ef7a626b28f4e54db88feef14a39821923fea7a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048fa1bc38671cc4b125c57d9db3d33c8c25925ffab2c5a9e9b86c526dcf4bf291554a0fe1996efd2ed087f8210747b10000000000000000000000000000000003847d6061e10036265421953407b10964213f5d5a641d43caf428a2958d29bdb3f338b4ea10a084dfbb4322a465305b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c16ff9d85b074ccc3b1a89fdd08cdf14871bcbb79e0fe2be07911e9d840798612a0e20553214a486b85ca4e5fd9b5c000000000000000000000000000000000ff6768f72be779f8efb59f0143377c370fe0aef64ecbc27b3349b653afa88766dd19371457a02d1157d5fdb2bd5abca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b2dbb0d7692378d09d69a4c550c66b2469c6f0bd31d718392a5dbb3ea59b27329cbb10519d19e9446e233ea3e0e9a000000000000000000000000000000000d9f7c72854439fc4f6f7cad7792988200bd38cef7af378053b0da3404278223cb65c2524f4b607772dcc53775c0e06d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dbb56d62c30dd9f922d7d187bdf37b5e1617caa4d57398248ebfca7bca05dd9535ec96ebbf85c270832d90a940143f0000000000000000000000000000000014360021fee7ca6deb29a469c740285323661a205df206a50adf93e7ae9e15eda6d0d009c3b304a10e5b18215e2b76371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fdd1e5b1476661c2571e14b8a2e3554bdddc69a5658f288e10d06f7f03a4dfde60a81da963b3d0097993d519f21731000000000000000000000000000000001106b929bd96bae00eff5cfc8560010ad02abcb0132e1abadb46dbc4143a492ab73e387ba63dec5af50a0ed8dcb3c7011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132425bd7886d3e028ee3cf137c28416888cebd8f738a30cf665d3b2d2e0d41bd979017f061bb7fa74a0b6081267bb0e0000000000000000000000000000000000cbb80711a010c484c164e4ec7054c79cf968004012e4a02dc2b38edf66ff8fa94f73323f3e347508082018d00a6e9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b293d1abed211a04772d5264d2b1c0e66fdb45fa4de64245736714a3671fb25e5dfd6215127ba5b2b452bb4144d74f0000000000000000000000000000000013e33258dfb5493b3590da48471b38ff7bb5f9a5973def9d7a7584c7b9610c1c23df1591ab4fe94984f21ba9089c46ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043fcb2ed212142227e7c8a7758f52ec40dc9f81203b10e40e55498703725f88bd314d7ca005606fb9a9a32de43edbc50000000000000000000000000000000004514fd3473a382e9b17b7fbc42c5b16804303e73f82c65f89879ebd8852aab9f453e9816fc797309fca8fe05988f2401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f39f47e7c9c2daed27c9288be45ff7497dce932f0aae9dd1366078692a75d3ef375d7ec571ae0fe1d87d035723e7a70000000000000000000000000000000000256e69eab6fb139d1b11dd0b08c6d75030f79194ece0a4e29c2708dec3bb377a482633c264d91ab21b07141774b30e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a844b1a5edd3f0e29e6f65e247803075f114f0e119a5aab240b006aabb30f6c18f8bd1b5ea2b308e63d392f37912f200000000000000000000000000000000155c5f7d8339238bafbd02a37d718bb75af164701e2b480ed74aaf93157eae8e63aa58cd47d63bf3edf7c0823d9c6af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f36636831274066ff32dc0e98ac9b4367351da7ae88fd7789212ea9cc675625f075f767cc5e70300bc757dde79d1581000000000000000000000000000000001915afa483bc0e7437305611efd47baa29f9ad6ce8a177af2c516044448ace10f5db1926f3f9272c32049a03acd5b3511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001262108681725ba3312474398ca7af16e9c381371755d5c64760d987ce7b844ef7c1a808074b9891dbd92ad5fe9234130000000000000000000000000000000012be468db76f5e3fb609a222a6298b8d825d8f2f642cfae4ffe20fc5be8d712a3735d5b9e0518a4964dae2c545d92f7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015e4619e5b94b3c0790784d502ac4e3d094ff44b260f66dc71d7a40e58f54fb08c2ad817a3a0c07a6391b18515f740b0000000000000000000000000000000014ebcc4a6daccf4b8303d8563bc5c4eab1812d3449a27d513d36804c24e6de02abe4d291391d84fca271980c506570571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a2a0248f14093763ced150093fa47f3fd8b30d72ef156a6253017c03a089e99282a5ee332d0a75ac5dd58838eab6ab000000000000000000000000000000000b7527990d34345433ec6742263a8a173ff12f453e010b7e8b18880c4c1a50074d9981ac3ae525d0e1d6f0a6993cd57c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021d79fe29b950a5ed3115cf1d0ac09bbd98ff54da53ad230d4d18bbeb6a3b1141cf8e809ae7758a14be791e93aaee530000000000000000000000000000000009720864c6c10aa1ff281f969c485168a32b34289787410e486c883fc1d9636a2cad087b30d8c06cb87af117d86a76a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006201b99a234aa8ae87cbeb24255996099a0f7130e8fb6821d6741a9eab1009f39e3c22f45cd4dee9f59f5e06b6afb230000000000000000000000000000000014be94cd8549172b1bafbed136569a9584d0783f0919f8b666dba37f5485999210a9879ea5aafb6e825d81616e2e005e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d8c346962286318d25f34136f8760db46c0cddb94b0b556a835ad5a847dff30692ba53cab49a9344959056cbbc89670000000000000000000000000000000012e656921d9a268b02b5a08ec1dc2b96a51ede435eebf63fd176f88339254512a06da55497448ceb321eb7565789f2961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a2e91a24275d7ad56c54b3a4570f1882c91431c374df88852581540a2f2de8d5d866935848e84b3b0fdc318228b40e000000000000000000000000000000000efda833e49d32c9568a4c07f69ac18e72070c82a2fd404f09f28427ebf9ce88ed0648f519e893a6760d7fb2d6fea46e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096f6abc385b15828fdcfa2f914fba28845792d76027f1a857fff57ccf4f7f6f1344681731bcf89d44ed3d554b7bf86d0000000000000000000000000000000006ce6abaea1eb2322abf1151783726f2db845051455cee92222ce3c297f49e1611cc5b8b69b6702963f1364a0e0db2531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134d0455a5d0b830a4cd8c1f5cd6a4565fa975b68aa3e8586d4c13709af49b0702d24547d226e12e0a2164bb3ca23e920000000000000000000000000000000002eea83a11b629b04c2b859f14e8d64e90c81d1a65c10a632de2431a7ce4badc74756afb7feb28366cf34a0cebe9d1311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3fdde0e2ec331e63c9de21b9daf29f6664c71197f3a19313ba0b24baaca69759bdaf41945986bc125b92f4b1de9f56000000000000000000000000000000000702926c2ad3cd2b5e6963d391b2ba7aaf73d8807d6acd5d13e7b699ad0b4d17e191ab2538dacd890247164d8551c2671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000784fc8227e05aa5af690a0907cbc61e821b973b5f38ec87722645a68c4a9bfee2a023231dbeb5ed654a6b9895a962a30000000000000000000000000000000012089505a283413757dc86d57aca300ae55404893c40e8dfd7650805c8d36000ea1d2aaa52ca3be104919a64667524c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc6d9dc8a9d12dfdeff75f84d6cdf46cc3eefbebe5693a343bf8f065dd7a1b0f07a055dd204ccbc50e7de57a255043e0000000000000000000000000000000002b30ee9154520136af5e00b41cea3d197fb16638c8b0e27db04ef26b2beb1f0524c030aa12207f04dade06140eb646a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071068aeb2da0abd740945ac95eb1315fc3ee36546daa98ff19df32cb2268de75811795c4c857b51d15b5af77fa21936000000000000000000000000000000001383def2963220133f9e53ffb011110b277d929991475447427811a96277bc7a0f8d73692d038de255c29ef0a26b54411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa8d41f8d2e406223512da2eb25a3a84ee60a5f6e7fa7c08db9825042c87e1660b7609acb2420ab2cf6b47400a6e97300000000000000000000000000000000084f590c23d03506246f586be8b92ef1a8e6bea8c5cdb68e6496cef9954c3aadb304629bd3c94842968e99ae62b029731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000140ab4595f7f621bb57375a14261836f1ae53026b5adc1229cbe2fd0f18707139867d38ea3510d895917e6e46b41ba9000000000000000000000000000000000b3ee0ef74b0b2058ac914be5747c57c56b576dae3f7a6ee375e2f9b637d282a258c43b6b2a808ae63b8ccbc2f0c0af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003edd1471e326b302f326907410ed05d15eda89649a2cbed0c8a8e39dd43d310d6a6d942b7a2ee3a3cd785b52f7a911e00000000000000000000000000000000038797a0b7fee56c950d0068860c111e6a1e1986d78b4425948d94820765620d2a925f8d4af88f863ddc1886ff716c3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d11e26b94fd0226dc45bef20ca2b121b53f1e01373d3d11c330db54edbfcbc51131c86396c232f388a8fd16e7d175880000000000000000000000000000000007a4db4cee29cf75d92597592d2a02baf5328979a273545638b4d06f96c0d1705f61ea3bdb6c3a3ca547ec7db2ad86071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e2185ef1543229ef5ee3d21b204e716f6010370dcb0585e7b1a8dc4629bc06b145406d1513de19270659b373e6ab34000000000000000000000000000000000bca21e7992b37521e9123f2c52e8769b99a47111f72bec767e87f10661957f71ea30ebb985bccdb17d353889ec8c6891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010040a77f16295aa94e7b376dfee5f3a4d535b9c8672d145f884eb91a40240f23711f0f7cba72f71ee0f2770b9eeecdf00000000000000000000000000000000083bb9bb523c71c9f6721d4fe52fc4b6275934248ebfae16bf4b0c7be0de755d2bffd6a37598ca6ff6266f22f4774abf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea29ab29c9191c2c7ca467c955b4a115936d2da83c659e7e53f9fce891e7df1b9e61c75172809285c75d40e22f479010000000000000000000000000000000016afc4c395ec6b108837af8a532f39193030ce1e13dffa12f4cdf0fea039d1b659b75e929689bd65f9f7b5f7b5b4fc161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004aa6ece79e12ac8f3285112bf86ff83273294626b73f1613a8759a83cc72dda5d86384a363e6e2f93b7db6130cc8c450000000000000000000000000000000006640019ee46b667aeadd7983370bd3548363af90e2d147969e7cec178f591f7e3eb8a9f9c2acda150090368c26add711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1417080ba8a76d823e53e3f61e071fb674675bab023dfb671607a080a4f9aeb0304000bd40bca43548029dbfbb7128000000000000000000000000000000000ee7d58874226097c28f45a33f6404ebc4671ce782a10d833b8f94a352476677a998ac49d4d4d2a815a807848962f1b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128686dc4b42ea97f0d5302d6323002f7b7e0265610fb4a3a79864bf8ea8ef5c4aa357122fa1079043f8ad827b7a084f000000000000000000000000000000000f461b1ee6f52ebd5a451cf7b1595b79bddf592d25d34e46fd8f2ad7eca4bf30120c3692d325326cc3ad039af645f3961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f96d0eaf9e0317e14bb70e31c94f0d1f2d3bbfecfb30ea93f34a7e5071506848e07ec4c3af118f61267738acc6fce150000000000000000000000000000000019f5cca6d3b55e45e44d496cc403f771813658f368897588fda43f37a809b2aaf95c7d79f2e974586ff47ea7e2a9003d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a504b68bf21c0ac56bdce3783c79d1ea7dd2c6ce7164446dc1dd3564b2a1a9a99ad47bec04cc83f545564d2f0e3538d000000000000000000000000000000001437eacfb3ee21dc4514212d9b9b7fb6cf24b641718e9ebd58ffde0ca9e7fa7f899ac802f10ada25b6210a8452cb09691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050c3d3ac8b00656caae1bf4280b3bbfa252afca51131d646e4aba719201da4661bdf888b7697a020309b7840f88a31d00000000000000000000000000000000026e116bd461efe94dc5452f79c3f22e55cf70a1cf0be9cff72d07737fe3c4b3267394bca3b3cb70d978bec302bf39721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807c713d4a50ee84cd091a02b84cd70b305e73184dc563f3db1d9b05de2f28b4ba0df1a97916dc986984fdceb173ba0000000000000000000000000000000000f65b71408435e838418f3af58b8d083d9992307ef94cbac612d16ee1d27796424c7f68e97ea7c98e3f93779ff4e87571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a9c5a37ecdf4846c449792ae970b62b7328096b4bbb960a16df355089c8b84cd16abd9d8acb3fe9d8c19ccf01a2253000000000000000000000000000000000ce16d316333193824dc70268e75db57adf9aec968f45397a51fcfae4cf6fd70c4cf785b78adaee730611718267b36361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e64bd95f001be6408638e93a21f4ad4dcb5d33a763c4bade8d56ac031de63fc373ad14ea3467c49889d285a40595900000000000000000000000000000000005f3aec71bc0cb4621c60ccae169431c7af732e8a5a59afe83d0f4cfd734da361ca2f66cb13ef1310f70c2b56221e9a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092a1b5d85957280d8fb1ab5a60aa3d84e73ba935d81451e979ebfef460d7c9f7f914abf05f3cfc500e21f3c270d9f9c000000000000000000000000000000000d60a01b7bb45463287e38b71840da4026fe211d86ebb4b8c46064e60bb2ea14559249b4ba32080dacb18c6316cfa22d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000947a1cb2a25f313d93f4e0d6ada5e74b5103b5e166bebc0ba01ef685889ff4d4f76801f1663f27acd18e64bac3d56950000000000000000000000000000000011dc2f55c63d7ed56344cfccc286c4ebbe19061307935b05dafc2ef147f268a184fcf4fbb4e9785a7e381fef42d0282b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005d33f385a650ec8ea8bbcb4a3825aeec9fea1f1fff223f3b6eaa9f14fb03d0ad071b42b148095d05c77fdcd8b451260000000000000000000000000000000018bb939b20c3530a46be3c8f44376a5ad6b95c1f8ac2ab132c8263dd3d404e31afd48a1d88b646e3229f6e1f397de15e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015726d0020f9e63c3b41474a4d6c6d63f5d029b06ea161c75ae07a9895c26fd384f4a532f8b4a4849425a207326c2eb2000000000000000000000000000000000fa11e3367947c4159fd5fc5a223ae5de5472404050232e9f536a64718a95d0ae028cb9731f81c9059c1873a130dd3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a4f288141024e4007ceb89522a8cb9d4cba74f1b947fef8976d13a0ead1edb02c76a6e891293c5f05c0070f48c39f50000000000000000000000000000000014ae87e5597ca97cbc3a02e1e776ddd2c04263fd62ad374681687f2fb7f24f760eab408d56b990d2b7e45f7311a2602f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001828d39e38ca7da6fcd893eedc0806508083932c5f15eae3ba072b3aceb097dba204ce5b9d11c0b09bcaf497336885300000000000000000000000000000000003832d343959621e339959b164bdff6764f2c02875e9c716ede4c21a47623df6474ac951167fbdb6cf8687b8cc0026a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120c1f59ce78b7319833a3c1f12697682a81e76f112e2678823241c953978abbfb38241979c1cab0ce50841e2679d3e90000000000000000000000000000000015fdad8707d644fa921198d4ede58e1a845ba04142069fc7f9d824d801ac09887a43573a70fd92184c154786788a3d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001510e382500eeba249fed5687c13a344f301fad613c715e2664bb9d8dda8f56dcc09b82502daed6c5b3efe6fbc0321ec0000000000000000000000000000000005c1774a417215d654ae9a73396b8a5f2eb0f85e317c0e08f63d9a1c584373b1cf7807f6a536c2c085277d0171bb52701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8a208f76058b3430d81ca13e742fe5714b46e10ee0672bc966f889e43dc199f4dcd958e9a46a7199cf1d7b423e60fa00000000000000000000000000000000071723a892470433832b0b41743a5df692e13b08de622db6564a690995a5618155db638fa079b7534f8cbd5032e61a071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b444a33a3e0b81682cf09f78eb502faf52cfe4704d73e03413667e8a2c4b0e859348f01e99b8aa6a519f62ccdc23c15000000000000000000000000000000001262cfbebc08972b003a3fa79a1db786a777adc309c1a7dcb12a497d11cea5241e8a9fdf66049333fa0b1cc0407148491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d91f825aca6aa44baed28a6f4a6c081f4859ef9a51f6d9bf21afc78d3958650923b9245f78cd7ca7cfa5f5c7b145a9000000000000000000000000000000000f0cef2229837da6e933672ba382660e28d8f199b235f9d880386b646258ac6864ea3bafd3d8eb36e1ba376246927a241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ae3005befd604b001cc0889364493a011afd35943bff70c6b239547dd142bee8971227eec32b2deb2e8230f3e52f02000000000000000000000000000000000169929da3186f1092f9b170fa734edfb6275f6c42ab9e9d7c083e219d6a3543522ec8ce16d333e4a33e6304bd3f1b931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ade6a3630e120927a568c3c5e7af3a7f2167ffe9ac47ea5541c2449615837e4012af1f8ab32455a0cc2f7578b405350000000000000000000000000000000009a0ce5c7cb8051b095b6e66d6ccee9234d5a6b175b43d2479d18ade111abf054398db47f7014d64997f6e43eee5d4d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006774f98386d0f7bf14df73f958e6eebf4338c19f82d2d31e7930c9841570e992620f764de7fc905385fd14b9149b2cc0000000000000000000000000000000019ee9c785c1e93aec20c6bde989f3f38e998aa044b034d81b0de2d6a7facbd3cdbd0781a2415e463e856c634c4661ac81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050991fdf32388a015b4599986def2d2481be8bf4331700c9bf201e34bb74f2f862ff6760d048f21635517957d27101700000000000000000000000000000000185e035b9f9b736b0fd2cf539144d36ee7e6d42a96990f4f1f2a4f9e3f2fc84d0dcce47e8154e2048523c40fbff28c071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001990ca1a9bb9d36539ebd8b63ce7151095c61b64a74e5c38cce158855907d1d15adc46bb478c6e169dc0ad595460b3ef000000000000000000000000000000001646ecf66583a86502c4905a5c2b57cf373272c26273d9d9118d469ea602b56a636ff96f7e3905a3918d5ec22ac9dbd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014789a9c564be2817dd5806b3fb47697d3936e773f2773b20cd4a65f096da1dc754c3242cad108d01f2ed4ae8df84afa0000000000000000000000000000000010f2ec772ca0ef7afffb31030d4529f711aa103576f369b129effe41f800f7148ae15d45783f9aa899db1e60285265751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111aec3f4f6bd8b8d28c9a331ef9d8f796f8a87d6603b333f8d6d7772a07513d5cd86dc3e2f9d5a48e9338068f5e5fbc0000000000000000000000000000000016f81f4c7ad03aa15e26ebeae68697ffacd5ddb967c48161f33381832128bbfb1151d9879d44cb37b63a5309bc93d8a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092120f271df91567f708efa79a955eab379adefa7ec29fb72e8f9fee34932bcb7fa3ffd9e0db0c733122f2f0c5c942a000000000000000000000000000000001619ed78f7fb4da227cf8d82d18d9a0726c350bd5d3d0fae6e74720e5c6764b51033bbc4c01049bdf4ee3fde659e37e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d29cb0f63cd86d5671fe582776db03b13ba37cfd659a36f320ee3f914ea592eaade5b939a77ef8e13fca309dd3b8ea0000000000000000000000000000000005f6df9875b49cae712a0e1b2b2f03fa5d4ec2d939cafe59110132fcb63ffb2cc784c5762e9f654b4172721a5a649ff51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d164b70bf9f7ef5dfcf18e7b072c7cd630472403c8a4226c884adecccdfc2e317c7273b95b763d09296374f9a1385a40000000000000000000000000000000009224caab937b4662b328469f75508e78801682964cbfd2e51f25ff457d5d34347106aba9cc9fde0ada323fb25a616a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d9912072511fa6f7822e81115daa21cf39ffac1caa5b4874171362a59d38df43453b758ab57a09e8878043315ebf36000000000000000000000000000000001487d30f8d55168b3eb47e245bf87b1f8bb3b9fac16a3717fa2932d6ca8f4f2d228ab76cfd36e8d39f659947b62f8d5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d985a9d46492436396cbbc9e5c7f14f99e4a95807b871c80e2585339abcb5103573e4876e6823854e125740583629400000000000000000000000000000000030c09af0a495f43c07f54a8dfe030232d872abae7166206c91fc807f3e5c0d2b3ea6159c75527040d0f5cf35838e2221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019070cb800c50384bc62ba5a4b170472c259f105cdecf95a295163cf8c0d62f9c052cd0f1969088d1c08f33413e82bf40000000000000000000000000000000005269a5f60561d08f018ac09afbb8cebd39a9b22bde4cf2135a10e774e95df33a1f4214cb54a067af8478917166171541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7a23044d93c7b03a7766069cac6653fab8d1a117606c5ebb77456a3d08e774d1f21800fd4f23cd064964dd219dc94b00000000000000000000000000000000055583fa48d767606efd6c82f1c0ae1e6d56dbcb26c8caeb551a2c5f40ab8dcba9007e3bb2357a4cb9a523518b9c0c051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017faa20074845a1bb02392b00034d2196303a5be345fcac09757d33ab6c66b352ea18067c793d616f0dbd0c82a9b58ae000000000000000000000000000000001153141d5ce7b746e047c3a84e1e9029176e94a0db2fabe1015dbacd4c1c8f2c97f57bf4d928000a6c7cf48b582c54f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d8a8624c32dfbb770292ccfe5b18a672cdee8cb606b6ddc3e7cc9620926d512ea316cc5b613a82b4c60eab93bcaadb0000000000000000000000000000000006bbaf464d8bf9bcdee81d1aab424b0b3c08daffb4ead83de5119b628a8ce358824b5c72bd4de0d2ac5a897e418805d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6b6d3151f71be86febeb269eaa1feba37c3258000a667106de4b1ac84d91355ef37229251654f8ad83ba0f10321e55000000000000000000000000000000000b480e1ddd10a0758767afda0ae6bb0767c1d1a4833a5f4af323354906c62e66bc2330598e07bbd0dbf90af320c77ce21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd420a8a44016b806fb0db97b87e92b793ab48df243469e187230c19b262febfd8ea4801b39f2f1f1796cc6de21389f0000000000000000000000000000000005708499c87788c2b49ae9c08b5a4bbd782fea43ea68a6aa0926f5fb4c8a6120a7d00a4e861e0a4a0108736d04c46b6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000397d9b1ea0c17ba8bfba39ba8b9a7c7d23518507a95d53ed70a1490164ca7e42378ca5e3bd2f846b164c06bfba8d51d00000000000000000000000000000000062651d43715ff392f89d65370585cb36d760ff35a17e07f637ee9a1ac654981a19b667bd3d8d7d8d504fdf00413f3271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c5b2100522c7500740520357ade93be758008696ab6bfc82120aa1e56e352891e1c2a944a9fb91f182a2eb391b03d2000000000000000000000000000000000f3e921ca36af5d2b5f984a0c8edd38f4decba458641f3a907c323cfe243e12f6f853cc62aded980d1cc84f6bc4ee50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d192b60876957a35dae510fcbac59832e5476310195438f636aaee2d6314544fa99aa5a7e798d51d7f8764f915b4521000000000000000000000000000000000df53768b4aae77c7f23f74d595d10fa10be44939449cda1f1f74f4f0eb4371982d960207ed5aeceefe2f7e4dac4e5ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006db91cec22ebe5c50c7ee16a126c6897efb97ef04e3f45c0f1e13b69faa3245293baeb6b43ccfef5b52b45e8e8e40d1000000000000000000000000000000000fb6caaaeba72291edc9c89cc3e96a28cc24d78d4646d12d97afd7957c5775d13a846ed32a4f255e03fafc6846b024511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eec3f5c26327b54b03e7990b8d0f7745806a08ffd1a3192d43b458d7f4b00fbb81546f44fcd5fa02922f5ee158aada0000000000000000000000000000000011a13917c75cac2515193aadc239ec2cb4da1e6e11baed1410ad62e02ac63784616d96f48f17b54651076755454e77a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000279b8d4fb13bfcba38a5b6c92eaee084fc851dae3b0623ea1df13e01c18a3051072e977b61239817a8bebc17afbe266000000000000000000000000000000000e93ca08e7f8c8306a9e39d4ae0793e85fce82c40ce51266e7565988ec68129f0dc6bccb15cbe1932e8c81269d4457481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd944d3b3e96eecc15362150ba661cbff971e6cf1f828c95e6fba00416807605f0f3a367d35e174c6dbc80b1b8e43ad000000000000000000000000000000001069a552e0a77834d73da735b008b789fea422f3b2b19cea5c73127c6d14d172b928d9324074d8458d3f4028a5c8757f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0a9c4fa316d0a65b6d8ae371d8809a5eff2f4c47a58bbb1732e4fad64bd5e077bbea2badd59f1729a0b702f2d7c2970000000000000000000000000000000017e55870c8642711b162a7583d18983bf6f83b2b4479902650257e16b1ce951980aadf1b0c16165c092943481298d1281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014323197fd8f200b247ee900bbb4328f728286a11b9dd5edd9f8d2a3cdeb4a0b955cbdd836287d2d68ab69a25a565250000000000000000000000000000000002f88372fcee5f480a6ad826b5af5dd4a68a7b5660561e239893a8a361bae2195957094139788e3edb5738b73028a8da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003854dd74698295891ee1b5acb5b8978c82a7142f911d5d8abad84410a7207daa1d2c41bcdbdc66c56e5be5c90ea4c2b000000000000000000000000000000001440e15cbf14d10122307f8e29a94336060b4a441ffbbfd6cd482f7ca1dd4ef5fe57eafd2b49df8ea1fc19e9e7899d211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154d23e35c67a231551231b43d695d66bc01a78a044de8762e215aa7871daee6e50033430ec610e021983dd540d3a9dd00000000000000000000000000000000104eb4dbd6402e898d25111bc30b773c4382133a3c2afe5e56e2e873f1adff57450fbd719adbe10f12ec8446300703471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3cbbcb0ddb83a08379eae978fe444cb913020fd841b2b3ba432850aa6d3e29e46de6d07436ba552e8c7ab42d03e06e000000000000000000000000000000001745929db2ecdae61686a28f8d6589570c29bda7b5775c0a31a12a0e55805586d3cf06e76931d5622b00a551c2b265401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016003bc892e78edff115d0d88da2349791d9d761dec16e22fecbde28067f1300b83e1e9787e7f5afb4ea05d08f8ca4e7000000000000000000000000000000000a6dbdb86b7ce1c6528144dd7db8ca744b8ed7227c5de419cad9c2bbfdbf54f38db655b667c1a2b46a17b1cac5069e551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035125ed32b045f767649f54be7f68006dd965a56fdea04f4a3a3e0f11cc11617e4f94a315ad6250c7839e74d91421b80000000000000000000000000000000012a61f52b5f69f426451d09353aa0674f09a99e8bbe9ded79fc96ae755ddef0e06c5d013d9cf7cc30e0458a04f1b6fe71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf91ff84184820e9dbe1363ada1d7974ce67196f6d0c4a652277422500a11e5b3c92f920ad68340abb297170a0b68d40000000000000000000000000000000005afc91a88a02e8024266cb70aa48a7b7a0e21fd9fa908c5220ec2f3a1dcda6b8c1316318b1370db1896e9f2e48bd76f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001348af7ae01f1680502f95d7766f58b58090cba891aa6bad7d3c8add8e1cd210a44017f4c4c50eb2a64e07875b08d803000000000000000000000000000000000877719ea4899f88e200cab5e3dd2f450f58a4926742ccbb21236ea25bd49b5afc18f6f1057e411c11638b0646fbcfff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053671bb429e57201fb396a8a9bbf88c3416703e46260a29dae767c652dbc3db6d9f4bd9b70ec9229802d1ef9e433156000000000000000000000000000000000c9da36de9f6d287bf762277bebd3804569526d9e993fe34677d5945baee89c5fe1e9439d9382736e7ee963862abdb3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176670ede37e89fb10ea865f02864484c88b8ef598a0ab0cf0c115b6548c796188cb64f2aebade923ab990c0164c1b810000000000000000000000000000000002c7d0f101ffead3baf97b392ee7e4275d60c7632a472e0ef07a4700de8c056d8f6db5b20f463c065bab21b907a074a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c20981c0facebdafe00119f2fab2114c6af3864f1a088e24e896d6f2f9b756e06f282f12db8d1d5f5b41e7ee23792c0000000000000000000000000000000006f504bf3b85c64d744f33d248ca3b7a31fd0b534b430b156c36f379880ba2538ee1a691c9671d550ffa9fb40cc8e28c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038f7882b4bc43082913fda01e8e4a309dfe886185eff9fea61864276d25657ce5986b60dc1ade7a77cb5835ec07fd0400000000000000000000000000000000164eec14bdbf9a0cb9075cba4b97a0599c01a6ec2a8b9d3299c00c12f030a5e2fea2d3c44acd95740e4d2028a9d51fd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031f4ebb8c150a2bc7f6dab0dfe4b26af2d4777ee19ed2e580deba92acae59bb65cfb939992a607b61c4293ae3c319540000000000000000000000000000000009f6b9d81cc4231c9e33150b6fc5e924b11de4d04d4eaa81dbaf50193918dc681cb627ad2ca580eb87f9af1bfe9ecb541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa581fe30b5e16816b22b70e2c45ffd672b594ff2c6de7d1029c11775dd94a0469478e09669ecd78d8651627f332a3d000000000000000000000000000000000841ebe1612e4122f05d05999a42585191514583c3aa737c0e0bc7fc757b30973372cd5b8251efe77bfcb4fd8d8a04d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f1a51be048b40d4377ad41c2444646db8c351ac0e0a8599780b68b02a7528301a74431221f82f86f365a1dc984b25000000000000000000000000000000000042755042476f2aa1d3d85dc9b23f566b5dcf4d2101169f72bcca1114a5966b4b93bbb734042a8ef253b4ad0476c8bfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d9e10771dc796a70aa29e8c9effdb3ad12a394f4b84938d518e2ee7f21804ca50a725e900fa9f33894a94762614250000000000000000000000000000000000e12fc5826661c0147d1d09945d125dad846d055d2047a554f2f67201b4e9407f3ccf8597d7b531e02527d6b9aa37a4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b3246c84b29c836e681cf9b0844e536bcb536a034df74eadbe0d3a65342e52aa77bf1aba2cbfe031cba1cdc3ae8ac6000000000000000000000000000000000b0264f63019ea555736fccffb02c73a7e7c1d174a37f2b1e584a5eca336702a6ef912b8ee5a2334fa1fc67af9d082f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001911ea7d4c3b832311daf9ea2187a9c2dc2786bdadcbd095ca389951c6c00b83bdd2a766c6861ccbdb2b76d69d4b1754000000000000000000000000000000000f3f165c12df6a03cab03a058fbfdb2695fb48ed00b1a9afc58145c2dc226cff0da1e23622689505595401adb03e05fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ebe29ad202153071b8a0075c08e78a205fde58111347b38ad63227cb9c015b79858d01c0cf053160a93046e57caec60000000000000000000000000000000007ae8292a178e10192c871ab6f4345eed8b50ea01e717506943384b5ebdb4f66ea1f940d7b699b1e1470e25ee729c1871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000136516bc261991696ec38aa4e0b484edac0ff8dcb1f4954c2e13b977cfd7b5413f5c149ee45c14a3df6427e9c4d5b90000000000000000000000000000000011e07424e789a146d99810f5aae0ee9fcfb94ed499154dde6582024c56931d34fca37f502359e0e3db624109067d39f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001482a7cbb8a08ac6c58bdaca01ebdc96c3583c292b9a6b0e634bfc340564edfe5e1b1c382a4608a1a703aa65377852170000000000000000000000000000000000557b5b5d9325631b320d553c1445855ac1ff861bf743cc6792a879a5d89133eabe8b9058cc8726330693465eff19d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ca7649db2e9ff4a27694027c61a18136c0ce7253cb49a744bc9bfcb2eeb0f9508553fffded834ad0f9a4ef7b86be830000000000000000000000000000000013a34de5bfb7bdc6dff720204466200e4a13d884756990f9da79a1e4e5df5ed88de148c916dd7a510376a160b733ffcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c6ebf0b8c8ca12d17cf430780f22b5fce6a1abd593169cdae862bb500594d97e3ac432df1fdf389bb40665a69103230000000000000000000000000000000014ac7474ad52abd4b31fa37e222a390700dc01c94cb5b7465febd669dd7d759a3e867d2caef07d5db22cbe8ad42f5f561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccb8588eea17564ac421af3ec356d161b951644e718e4da16c80556e912dddcf5264a429ed705f7852ce98efdd1babb000000000000000000000000000000001353e0bde13391585bb156989fb531c3711adc5e86893545054075c792fddb4dc566374707d61b57dfd8b1f24d01fea21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006dd3a31a46223be524b6d00a855764673460829d6fcf8ac686f128fa7fdde71d487cacf493eeb2de3387f74e085c23d000000000000000000000000000000000d2b299805bb732a097f041be32094479c001fab61fb8c8f210e4f22e87fc2b3cbbb40b45051d8259088e8306b39f4e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017852a34cea9d72a0f06b44f78ce7f0a64622f91e00af204074b0469e5b14b4a98a71741f1ae4d21f6d273c8022296a7000000000000000000000000000000001800e70ec3327f20c9043513551d2d792960bc09eeff27fc6b821d324f66b3473e97a1f074c1ccfa3fff9379bb2263041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001023e0ca5a8b960aaae50e4525a56c03bbe1da7e90f4e83b6c36d1307635b5558ebd705c22504b73792bf28049d8ab560000000000000000000000000000000008cdfc8b95133d9567f970f56c7c6f0995d9b464e25ae9db5fbcfc09c3749f83f65823bde2c16a9dbdb2b2c574f09c771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011952e955fedbbed36cb4d2911a6e9e4cd167f456832a463b1f1988ae32f40751bd195d5b1e9686ab428ac637bcf7fcf00000000000000000000000000000000034decb4999ccd3b3b69a302fddb3bdf12b5939776d1e32334c4ccb4c95d2aba45673407de47347ce57fa8a92dcba8fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc12455dad0fd38c8dc3008d3ccab64e03366b6fbd07e199595e42d0d45c3581d92b8cc4cd828d60acc0d68e58d3e85000000000000000000000000000000000c626dd11e3c340dfdbe574d61ba307d84cb747755a503aa2874b57e033b87d065a31104a3f7b68de1db5bd92f90e1b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001764f49ee3571fcdaf72c30995a0bacdccf0a1152f4ba95116d244b5293932b5baddf9712aab7f662a7be28964c73bc900000000000000000000000000000000116e95aafc9a7d5c343ca5c8ed14cae22caa6f64f18f1c18283a8f20b37f45fec702e2482e1f45d31cb4e849d0d64f931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001569c0a587e297c652a14926d39b1281db6a60bbb5e01b2baeeaae31b6fedc863ae3dbdff782f5216a7ba800d259947d0000000000000000000000000000000001f8ee4b532ef576600d963905f8a642df01354777f762dc9d551a8863be870f6c2bb6e3363c22c0f496904f6f30e7d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083246bfcdeb3abd820d62268479a04f408c59f5adbaea40b261c00cdbddaa9a87c5794a46396a997cd64749425ad3d9000000000000000000000000000000001195ef3b2992cb323bb5289f9fe5e8fb0e66b29b78700a9553e82a02ea750d0f8ac7b1d31025553c6fb5adb42fbd00ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035d58cee313e58341655f05ff8534006c48733d17098989d9152a965adcd8fcfd1016c9024932606999c825756ff9c7000000000000000000000000000000000c7e7bc99d8450239f2428827052c2c5e3109481cac01c54c8cc5e93d1e74e3007908a44dee5e6bc5c1bde4e12486f711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191e596634a54c462636f5412f567d7e1a29970dc44679d1e234e8c6ecab1cfac16b10d236d62a4dd86cdbc61359108c0000000000000000000000000000000014483895bfd165c1b5f7cab805cfd009b86d37391aa5c9a470abf8f2916b179126a78cf0afb9b14869795f0bc20f34641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f9c1c806a3fe403a0924975c6ca8ed3d13ffca31d0e08170b917ddbd8a4265735bbc1b36d8eb39aa526b208e68014d000000000000000000000000000000001649314df69f016975fb2da668f8efc4197e4a5c6db8a32d907d25a44978edaee79f5a1cc6321bfe7750f9b4b0c3ea781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019165977c6a3e555b3d796fe558b135980321b2efddb5ba1c5db5d2fd4b28882586f0739809e325bec1b1943f2ffe69000000000000000000000000000000000164f123ec09afc326316e92e2338352f12e8d8097820427636c572555b54905b00cf227e8c068321b0f0460c4f7b42b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001107f39c0da286e7404e2f7841a54e4ef9eb55861c9c7f643abe8269a8b43e373df8b7a2a3dd1cb62897beff0b998a200000000000000000000000000000000159e0b10d6077fc77d03a98186b459e13cb275a2a095acc097e59e08dd65e8fbbff2dca9bd240e9a46ccd020bf911a361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003a69414b1d3ecc4425f3ce88bf92cedec017a5a56f4737249a88850e271b2922081427185669cdf460086efdcb8ef7000000000000000000000000000000000a3977155b262ce8e8203c78e13f0ee11e2073a02d9ce4565ec4f71ff22a351b31cf018020f2de96330da7e289e9b6131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150c0566dca578e8047543b4d6248b41afe3d28de80435177a61dc4a7cb4d930ebb6c69f7a4169c7afc675915e9a7159000000000000000000000000000000000b043de6ed3553b055dafda0a1be645de10085595ba02a33120151b9ac76260e992615aa353c7a8525a31477dd39a7611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166b74f51667b43803059af1941b340050dfa14c915852e03aa4228047692d0b1ec8fa2d0e7a8c2de4394d8b82d47078000000000000000000000000000000001607ab94c338f691415a05eb0a1d14817887229ed5dba0ba007412f1840f8b6fd70999e7fb96ad1fee32ecdc196975b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012d8f23233d1d442ece97d5a90033b3d3d247dae694b2ea07d1d0c3e7fa259a7216f0d0c873c8531ac46254ebcaaade0000000000000000000000000000000006918f9f9e62e8e8f18dd7028bb5b02c9a0eb90044361ce7c18482af760a96f32a1b4aa1c696ed9af203d659a4f6c6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026b3e043fe8c1732c86116c1881692d5d7ad2545102ed4d7ac48fb9875679c59733c9d47cadb970e28cc11e77c2019d000000000000000000000000000000000f4e97dfaa754e49ec2149e85143818e732a16cddea5a28ae8f11a11e1f78c3e71d73ceae977e1e37b0d40d82dc2b0f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000829cecc6c9eff30cf2171e0ae6821c9be72fcf325df65f59735ff3bf7a955c2902224d09bd901e05fd13b893cf460a00000000000000000000000000000000009441a86a80cdcd6d5c2bc7ae9a3a8385f29e2f3de060ca0c0b8c645afd8681dd01a80c6089195fd44765d01b74af3161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013399883cfa147566729742f9a8c56575d1ce6c7d1d2259de89e7f1b36a93f33d9cc843b4e4cabbd501d5598fc6f2a930000000000000000000000000000000015819d5ef8d05cc547677e01a461e3b30fbb51054c121f83711123216642a9df5ef18e6d07658824d8fe3c0aefbfee921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010054b20f655f30f8645cdcc2c13845f8024383a1e6d2a2c4a15bd08a1ad2ec3d415da676ec648cb4d64c9342c488ce10000000000000000000000000000000014c77475a095a7087f2b6dc7a27da27ee7d9ce7f9bee82a9560ec002aab370eddae5d256c368a705042f78a7632879351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189ffcaf645cecefa3a717f93dcf70c615f75824f815f47cf02628dbbff782495d594c988d2278b5be857d99db0fe70400000000000000000000000000000000045f7fdfbff9c8da2b23ac88212786079db7cfb5777d92ba59dd9c5e40addb60a354c90752d559ba8ac04985b5b3cbbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a3d42df44adc46cdf50e173acb4cff2d3197a03b585437bede5460391f4e12ee2458ce5576abd14c656d22c1588ce80000000000000000000000000000000011730a4083ba5d22ad161857496c991ad9c37abf30ab30207ee46b77b28b8c2e915e6b081e14e7217618bc40ef5488511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027abeb5f5ccf3f11d689dd746f8dadd9b3b9c6160d1975f8bb3e41e4ad6da6952235ae385b5b8a3a5899cc8f1b13fee0000000000000000000000000000000011a90363703958e362de002017e4e86ed2dbf5c04fde4e560aef013c9a49f49e51acc19f5f3e2e46c33c81cb90d98cf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d3ea45cb0c04a16a6cce99ecbffc9774cd0cbd79eaa8955398d60b561c09f3fe4f83ccee537f8d5ab5f93461e85c2d000000000000000000000000000000001736ac366727445880a43c8dc1bb15878cf07c6f1eb9eae0d3a435595c791f68f5fa10ac4da0411640a5e9c4fa1724371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee7c3dbb6847432bae8cf6e6b7339777867c07d8745c335fc4061bb2b49da4af3be3a22877a9428f9bcc6957d0d64ce00000000000000000000000000000000100bc614d637275674bf1dd025127c5670831586d4aca79c9149f793c71b92b7f71b144d50b900f0140f7e42b1a8ab4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9a55089e6fcd424863c35d52c90d2a5fe7c45ca946e7f973812a6cec14262ebbaddd01c872ddab62213b56aa181da6000000000000000000000000000000001283e293ff5e04e379b00e7a8251e1b5e5dbd7038b99c3e0221e1f7c242458eb31f5e2a7722b638c4b08c3ef1131ae681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed7ad207ce19a772919a1db35bf0547f74dfcdbfb0be33bf388b147a17fea10617c8c07607245d8997f6775f47d8dd900000000000000000000000000000000142308f35bd128e384a630d1c7ae1547d833839822570deada353edcb09f5325f318fb1feb6000646fb5ff26a2b22b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006524535389bde29cdb4021475adb9aac3b3a6039bf1366167c15ec72ca56d8d9cc66b8393e2fe7b1213de4859130d5f0000000000000000000000000000000007f12ea23c2643ca11d037806367948c7d0a032cfe61b281dcdb63b038c6977a3ee642e5c1844b2e97a8bb4a7827a0c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0f2288ad42102f284bf7695559b0d7ee44ff79419902b5b06a32a4d03fd7ea03c68273e959041d7ee25a8f113b5e390000000000000000000000000000000003823ddd6b94fcb20ea16e56239417b6039c5237577e34deeea479d60ae9ee020e701f3ef30b680e58facecb3bef953c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6ad5d3f33da0e48e182653421a497b83d2b6a16e64ae75f5309158722f72b2c35dedb6b3580e81a28391775f77fcf6000000000000000000000000000000000e7e6cf3ed216ad95e87c3e9d2f387436288448af3a8fcba9e64487da322540cd2698dcdfaf11352bc27fe4849e0a0a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffbb74b75dd5ad1613d7f51f7e03f9ea2c94235a4abb918c50b2146d5a17892f0a4c81a274f678fa6bb3184063fcb49000000000000000000000000000000000a371de0789ed85d8801a9c9fe8c5a4320a42130755b09fdddc9edf27d721beb90db93238c3bb1968561c190c95f23651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006546be4106512f52cdd1849aa84cd155be1f4ccd8f1ae8185b17d0bcfa2f0fc9e95a8a14e503f80562ac4fbd5a58ad50000000000000000000000000000000012d0d9e53f902120bdb4b74009425187844adfaa1a72bc453ba9b8bde708b7b6281d1ab12bd2c247a84c9f175996992e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd26a9c0ddf2fb1a04da0a1edce583cc1e7109abee3ba2ce57356dfa6d718083ecda9bdb4eb56c82930a302fd9fbc8b0000000000000000000000000000000017250a9d4acd12df90702265920d19dbff62820ac28a53886dbddd215c8569576fe57fb5d6773ead34e5c350b21edbad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001593c85979da0cbbba2be2f21c8634a704b5a2d9a9058e75318ce478cccd2fc682b1344e0669a3fe63a377ada1d19959000000000000000000000000000000001055b5a5b351a39284a5cae6f667db6859f2cd7afd3558a70c0cb8832d354a7130397104d65e4bdaf4c6fe5042cf7a651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003152e79c26bcd3d6be2d008da5aa3db178be19c745bbd5e180f91bb2555db75899c2b9c5aba40a5b7938cd1bd0e02ba00000000000000000000000000000000023434abbb1409fa6200c7aa1dfaa5aa138a8b5dcc34bb511b6d8944a05e2e856fc8e470cd59672367ba0ed3b9725bd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064a421769e7a07be019579c2535f4833635c07646dc7ede80f5f7595024f8cf5c3d2012e28eb561616d4161adb73ab90000000000000000000000000000000008dea6f18bc1c91c0462bbea52cb4fad9fd2f3e08a658908079a783f7dd3d7a431ce365260ac88d7696e20b011cc59cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e8820a5df7ab0425997577a26f2e07cbbe0837aa4c02d100e30d44d8edf91ba54f4a026619b24e270142537ba33c8a00000000000000000000000000000000195e4e8a57e36baa77321b3c0a907a8ec2b091ab5a660e180c05ffeb16f509f6a67d08cc85d097a7fce9e80cd125a4981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002404b3866534ceef07b6f4b032427ad51f5490cdb923be78bc9132533357a173d38b9cb3b7694209377f1a90b460f3f000000000000000000000000000000001742e92898b4f3b31a7b7b7ab0cfbd95dc804d46db4a066ac7b9ee9c6cd12340cbe222eceb175df34855e85867fb6e4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f437c104ef22a3d140eda90f524089ed3d4ccbee836a052fccbf158ec2b39b9e6914cddccbba0aa8a90aa63a3266ed000000000000000000000000000000000c3ece774ba6fd2fadf621596d3eb9eeaabd79fd8185b74185a23218b7d04b985ad996952ad894fcf1cd30d84c1f626b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057c7ccf0cda632f6b28f7a45d13b4b1615cca160c54db6a8ecf24fb628dd0ca964d9dda3117b6f38fbc5d7f07e012f600000000000000000000000000000000072215ea146eebd043aba3ebccdf6e85e19d0ac7cf6470650e27734e20531b6891d5f597e5e75d5e7ca646ce6819e63e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c93354bcee400e5ade6bdedb95b9c9d616823268c51b4c579d87e56c576cec97de20085c309f5157123a890c6e6829f000000000000000000000000000000000b4b518be79eb3d762c68c94ffd981e47ea847fd625353bfddadc29a289c9d1f9d325e9cb97d3892480ecff66b3ae0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018feafcfe6047e7be0294cf81c4487576479477106bb17bd9a037042d30a7058ad69ec575b9a79459a15a2311f25b8f100000000000000000000000000000000172ac9966625cb75758e70906846564cca8a6bc6842a0c05e8463085e9ce52e85fb0e30d735b509476d561a6e6289c5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac6f7ca16244ca9b03dcb770bab60f079810e7edbe0d9a3d12407a35d70a14eeb00e955f786cab3efafb64f146bbae700000000000000000000000000000000010ea5facf9b8ea088c92ff1580262b77791cb8328026588be483e3633fcff3bd597687628a0ce443c04cfe44db7d1ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122ced525a41d10bbff55052930676c45a2f52e1d5cf3abf12f8c775eec3b80507633460130b17b9c4c0c5869ae3336100000000000000000000000000000000028b92cdf071a327019dbd127db1c3c6c2683a43228486e751fbace9c5c95d1133b7bd03bd6381df4a1b99d2069effe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198c8081949a7fc40c645c3e662f6eb765050b0aebfc710fd81a605f7ab33a983027d638b6d6ab27b34eee23af4a06930000000000000000000000000000000019b7eea2abb90eb8c2a453ea7b99f564e9de89398c6ee145dc8ea7050ed92eeced4e9d6bc0592285b7d81eb1e55ec8821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b7ec88ddf82828d69f0af9f0dd4e943e87d482d33137dd7ab55906253a5dea4a418865da2b357be66723367c26ccf7000000000000000000000000000000000ffdc792276fecfc17452ee4ca4616875b8a376cb27bbf40bfd4dabf891fd9b0af3f5c7578bf8112750f742980bf45271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dc718d20cdeaf12355e9b4abeaba99bb491026833def62a56028239a5dbd2ad2405b1f47c026c5037bca74a257073300000000000000000000000000000000117e0700a7f257d5377916e679e147564812710d468ad88957df25092fe41574dfc6d4a5568d61f46fa9f8499aa715021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d083b057e01a19a519012e8443312659dc9488874c3132d2f0225d5287a500b05333b10ac97d6a35bc076b7b71541210000000000000000000000000000000018c7c9d21e9d464e85933beade2fac8c5c64510015474fd83008ecb165b9e6790c834d405406223c64a32251e4fbc0811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f906ecff9796c5b197b303375a18e4c6324c0f6329be23c367bab583fdb3999f63e07ad9302321fc17946a272f4708a000000000000000000000000000000000fc4f3a3fdff6f6ff67c64393c51c2f9104797b81910428d0d516e442ee9dd96ed92ed4a867a8e7ebeeb42a8816f85bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000561cade10c6fc55f3dbdc7f984e0847ad00eea34b544ad1f04b4cad8bc2c067f7a3945c7a1caac5c20a2f4d37fc39af00000000000000000000000000000000150e3dc81d27bd0778b46bd913c9230e9ec3f8b8c2beb0da37d5cea59343989c040e3d107657d372f39e9d38ce8d966d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bb8fe74aa0af494c6ad85ea2f53936c6297cc101a48e5c02810696dc24c932637436165e7bf85a7b7f3c99ec56b2a50000000000000000000000000000000018aba3b77bb2e1da2df67d27fb007e46980fbea37efc6c5ddbb90ba12599d0384ae37ab125bc24ecf5afe66ff3828d0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cfc579e2d646103094129711d774073d7c0c2bab4d92fadb95fd8fcd87f5ed4a0945f79ccaecd316390493dd6ecc0f0000000000000000000000000000000002a8b2b6bd49fbfcd96cdf6089bd849da6e82620d38620d7b76077874e8d66ccd2807dfa438c7157386d3f694f1f68a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002febfc1e185028f383de39c285aca640989799f935460bc650e68d2077f0a77d0896ea21715264ed8f9c43194363ef3000000000000000000000000000000001376f2e6443461ea7224298d45707358a74d8e46998aa9e535e440f4d7209d906b5678baef796547d37102e1540646b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e97311f62da93aefbd6439fbafd57570712f5d4f714018fe68e715928a0e978ba062d1fd440ef85d82a3e07a24e95ed000000000000000000000000000000000a78b45a784470c78bcca7d9702630278604816e4c01c74f14859cee3bce05b77d255bbade2261e9334ff5a5913336091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d9bc0de62eee4097280555b81f5e1b3070c63897edada5894bf948fe3748c17003199b5747c8a9f5c032d05817775900000000000000000000000000000000036083796cff0d6c15233ef6ef00282d9967aef21d8e75851f7dd1921cd4fb49057a6f1824312276927e243b315f147a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc194c5be3bbaa06014872764bedb9cecb3b4080b009d3eb3cb73e3a1f408f6d40733cc215c35200d26ae4906b6840e000000000000000000000000000000000b79e3bb2e163fec63b588dc0f8d33e62c6b3ff44d3921df782e89229db71934c946975c7d18d03913dd7f4749c8b3211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018abd6087a069c941f1989121984cbaac8d7b08713bd71ee95df05350b0e47c45bc9a50a4f3a11ee28f23afa9cfaee2b0000000000000000000000000000000004eeb9984d209549b2acdbfb23b344189958953d3c78fdbeaac0c61fd5d837beb10a455caa2aa0944223299575be815f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6572d80a157f02e3d16c93e82bc11c5a5994794dd9ecf628d75c93d72baaaf65e97d271ec114e8a12a96729947824500000000000000000000000000000000061b8afaa66d4b861e2d442883bcb65809ec930e5f88916f9b410434c7a1e064f060f94f56bded021cd8b0051fd8f48c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a45c180d71585aa1066059aa92c0c87edc8b0af3c60a780f3a511dcc65099fe501040e149a4e3c7f9626fb93cc60e78000000000000000000000000000000000ba38feaa90cab68eb88970eacf57a6f73894532bb37ddacf8f6411c6ae2117538b50158e118bfe09c841253f7a139d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b37bc2ce2d4c989bdb41a98312b424824afb2e25cb4574963abbbe0d4af58eea1aa905ab882d4d73059ff95b529b2e000000000000000000000000000000000e9e9a611f32c6dbd627fcff3b80e6dafbc830d55a41ff5fc8e65b1260f4d6827c3de9cc88d9d0bb6856db493a53385d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005abcfca187c11e355ba262f3acc8073d4a6c92a22d888b85172684c14fa171dc5726a2c5fb6cb817a9f6116646b9ddc0000000000000000000000000000000007dd558165c7431466773828a44f3bf4722ff76e5b41d09d95726b4c8cf682287e1435c45f939f70b78fb1fab45ac6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014400c30aa7e17a4cbc2e8e6154683ba827e0cf640f311c5a21b4ccd925d2f6e6243a7e9f04b12e396d9cad573e5004b000000000000000000000000000000000cb9006c4b45113e72119707c6e6c5409d4dfd324538f5cf32f31ea96be48d06400b610abc29e550ed5663a6f021826b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007505688416b67f45d30f93c620926538015bdbb9bde663c13e8c52962f5f99fe708b47977ba5c67a54355431a58c8670000000000000000000000000000000000bf7572b65536a4f064d4af46ffbe1f3f179adb81778799433424133feb54d2149d24890ab1d7101acc804b0c8ec2341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d36c7036fab7244f80f608ec310ed56e71f16c606a5e0c32fdb246589f6d1f9e86d82aeb92ef80fbca9deb45e45b3300000000000000000000000000000000157f947f6744567a8fbabfe35aecae22db2a90fcc9a7e0f59ae70d4861f8ab26d4c6803cfa84ad272628d7309db551241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ed9f10ec3dac0d655070c5adb506d34ae26003ccc0a3f0e3eb1d236068a149110199ce46b105b77d1c84be8f880a76000000000000000000000000000000000bec424cb16fa12d9383daeddf2f0e4497ffe101a6bb1dc1f25587d36ebc15079d80b9fed76f6413e0319ea2101da80c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000edeac545330a230358385cb0bd815961466b42c22a2f2c1abf09ad6bdb1ec4acc610515bf68caad34958d2678cc8b9e0000000000000000000000000000000018d53d4d1cbcb3f4a164eb7284fa4ead1a89bbcdfb5c5f6500fed44c48b62f63eceaec1777ca5cd8181c7c15c33af6db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001590e721877c4b430a79b2deba121777120d0ae3f4fd9dbb0d6374b458994cdbcfe91ffad5b461b4b289de35c75bae19000000000000000000000000000000000c5b0956bc43422f9cde4766f6a8008d8f05ec10d642dfa02c4e47a8327a8ec0965ad4649dd0542a8ce565e66bd001e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048c961d481923ddecc36a5d37a813be88d6d5ef1d3573831b0c494533b25cda4071cce1df8accc71f06f2f358c9667f00000000000000000000000000000000184e14c8bfe8a949854959c46f6b4423865312f497307e446c7d717cb2993b3731b6c7a94ee54a4af9ed7b9aaffce7d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccc7ed0782c09eb07ebd5221b9c0d29adeafdb67a8754b69a856b1ee81fab2371af62316213d72e14786fc904f204a00000000000000000000000000000000019d158fcbbe512bd76c53fae0afc90fcc0ea282ba666de8e5f06e70ee6111ec986d2b53e3e2d8b17e9f9acec0b724df41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e088b828c4e6ac589dcf893c71f056483ab903433a2c011efe671a8e94d73292b52e9e6dad150d204a20417ce7201ca000000000000000000000000000000000003d573fcbe59139e2dc8cb9f5b8a89d4a7126ea89957b35fdd1e0c3541199584fcd98ad3d0ac7d42f9ea159fdb8d1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197e16fd9f3fb148316291c906ed4832d173f6184e7bf1748123d9d3b222df929414f812915fdada1858ec43d1b18a3700000000000000000000000000000000173bc0ac999bcbd09e24a86f9e0d594665a15c338368e726bdea7ec25bdb411ce74c2c9798b5cea3fb583ab9e69795631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dfeac09aa5125ca8d626183657b855aec70448181ad8da21ca4c4949280340dad52e087134090cbe1d5712c3091df00000000000000000000000000000000008325043269f7f39d71afdaae493389bf88e5472b0a476350da2dcdf3cd9d848eacbfbbc27aad3f923a5f2bdc7e20aca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018803688ea03f8d633bdee4e4367ef6ca23dfc925016672a96bc4b252aa917f5fd160777d2b03bc071894004f99ef677000000000000000000000000000000001704af270b60b6d87f627628d49f2466f5fa30d4c150eb59328378d8ba1f124bd4c4ee0d2cb3cca726447df2ada19fa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113f4eb256c0e03e41a8b902b946cdaff709c9db498290ddabad5e192366a17e89e53eec06b2b1d9134790d83111415f000000000000000000000000000000001260b5036664c0eef34432a9d8393fe0f3a090a03d9958a1e1542b9d2dbfd862f9450dff5e8e70628fe9845607c3b5b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e0511179ebf03b33fc3c33d058e9a6ace6be29688fed00f3807c3926d3efa3902510edb0d6539ab0516644a55ab05e000000000000000000000000000000000c792ad5d217c5e48fa684f86ab9d75e2eca5785a44192f883fe9819ba01f652fb32a29b28d49905216124ba9ce6815c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001604724fb8af98ca2d2183795e610e8c169e93906563755b3be0e465db9e622905630a7dd9f15d61aaf49ea724c7545e00000000000000000000000000000000080f37e6dc929accc6fcbc9a3c13f278fa4b3bff1ee1a7249c956ab7ecf885e5580c08ddad0efcf7a30e71f9d357b5011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000418dcf53d6635b4c0931f49a68a400422df08dcc88ac270fe7f934179103d7541af3cf4003f9e7e32ced1050d22c9b200000000000000000000000000000000075338a16894da3ea6f512c7035e22884e250ade8ac2bb9d6a238036cb47e02747de4a76145d38d690a508089c0d80801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9cf279309791c8cc577c664fd332c14cc5c821905f194ff711b08b3df6b3e9f82a72bc46af00a1368ff77d775933b10000000000000000000000000000000015bb2eb014c3fa9ca7dcac01670e688969e34decbad364036ba40a961c77aa4d7a962386b5578c3b4ac351676736787b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001674f239a7f3532cc4100ec4c2ee2b0ad56cf272fa68ce5eff993611fab4e9e59c680c392200fb8206de486322ad5413000000000000000000000000000000000c22ace6ad16e6abf06ca0588b19841ff7cef5c72ad80d9041715036a0a160f5354f83959a69a1b2b922214bad71a9e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009ca4d7f1e512eade03b67b4fef5959b018e6af3866a9a7bcd154effa0868f7bc49d5c1be6410615df3c5a6570e7aed0000000000000000000000000000000008c6dc890425d3007c12dd4ba407bd5f15a19ce26580f348f3d9a4ed4c5ec289f4f2429546938e09c8644c02ca00aba31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6d2d7bc3144a4f6f6445e2d12c1863d92aa9c1f1a79b8bdac144d74a2aca175d702555baee5ddf8253b320a08f85b5000000000000000000000000000000000eff16de03c352263c5b5286eb94beb11d9b5c936ace083a6bb93818e1ccf6aed8c51af70a749db79491df82aa801c561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030c09bf41bb34e61d1593622c6ea1073fed838ca6461e974bc4883993d2acb237c07cc8d6fa1fcd4a9c03f6808749350000000000000000000000000000000012d2c4403cd5fe15734f571ec59647cc4f4ab4ed5e0c2263800f9f1a1e3d20b8ae55072b441efb21f09c4e72c878894f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4e344b6ade10c56530bf2e39c3d38babfa35d328f824450054e253b3a8b7b30cf21a23881f8e5f0677d1572691e389000000000000000000000000000000000b8b3f651cec94f48104f4ddf84b639aa44e9c7ca7c33672e1dcc4cd08d0439be62096dff9673a3b1cb7f287f5a14ca51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051849958125f4f04e79fc18e4bc08ecb481cfaf19a3700e23a9ebf4b653142f78cdce7bec9dadea96d0a959acbc55f50000000000000000000000000000000015580cfb537c7f3a719990669277679037c5553b2ce03c89d09e0f6e8324212171daf449dc4d7d6df0cb838bd06d1e7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001601e06adf8969c35218acd2016c954c3847bfd9e0fd7d5a9c6fab5dbcf6f67de9e47c8a9e57c15eb849bf69c465b7610000000000000000000000000000000015757410919aa01ed5d43bfbf4cd4a8afdccbafaba3dc8b8fde5fad23c8091871b302e859e7d72e7202af8d39add35341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e6d01228713483dbc05cea49f32a841658d269288eadff56f31da2c831de1e48f899499868b650974b32a0e09eb690000000000000000000000000000000001afbd6aeea7c2fef8319bfef02f191182a3ed74727d6c62ace61ec165dc4f938f214340cb48f05846fc58840628a8041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074debafceeffef489e664f3bd81f15d0ae49e2a510795233a39f55819c27ad366ae38dc32c36687a095f7a59832513900000000000000000000000000000000120a2384968008c5daec5ce5ab2ead37c3e8b34d381ed78c8549f01e8e134583b29bc71faa947fee6c3171bcdf9b02f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8fffe737c1a46bef9e76e5b60f69f844c6a40eb8d7165051db1569b6eae9485384b3444452d1fc6abf8a0ea392038300000000000000000000000000000000093600f3841af24defb2d774963297d1615c305968b33e9d109482b93ff063d1c9267f8b611eaeb96bd912c13cbecf261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190be8b35c8cd03a1b804ca9587c6b6a5c79ea78063330bf49637afb2234d59fd82d5304fdf4d4396b10d5da4bf9d29f00000000000000000000000000000000177d45f747b2373672efc9d49f75962f28c992776a6624ac78b305a35cf970dfa00c4d334d56316ef504e6e63762317a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082b050941f7ce4ac3d95405c79d9a394016870d9cf6cc33813a87fc59dcc556fd323346286ca052063fa7d571dfe97200000000000000000000000000000000148e0312f314cb689d3e4134b7df68b8ee351aa95b45dfd0fbb1e9bb852648f69b18b95e06a6c2883afaf99ede8c26311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a015feb9f7feeda1a5fc50aaf3ba9a04c8768b1ec0987b85e3e3e36e9eb73341950e19df00d046c6d0f2208163aee4000000000000000000000000000000000fe0d57519122a66c130cd8713cddb9e5bb795a49ade0131584801692c2e733255b3dab830a038b015bef78549ffe5961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bc2fb01760bfcd7c72175ae4e0aac45632b0d2107de734a9456694f20e8f9cbd06351aa37b236086721f9d26b9a19100000000000000000000000000000000151fc93cc357e7601bdba142d11f8d1f7fd282e7ee64b41c80c8155008c3fa66a20c7fe044b792b7b85c6484a85375a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6e2eda451d727bda5caf50301f7a5dfda551604d2ca995953ff9160f24fcae8c50793567496733ebb4194bedb6cefd00000000000000000000000000000000003bf18007c6265fa3279c6bcfe6ea01e530ad9dc46b6208e892b8a1ff559e51fa29f48f56cf0894d0d83c3e820583881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e4c2b54347ffb088cfc48e83f364886732023ad9b15765f7b1f4bd2246f0ae5affc9e7b00e6dba257d153ed058d8e1000000000000000000000000000000000cfde79090aafed59f6650d30425baec943981c66b8cd84eb3e359517e039230abf5401af5c8fe7047f73eb79d63d3bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000306a31cf7f485731181513b94ba67315d9bdbedb9e1a76cf6589a5ae3e9729a82409ae54ea427e9109b0ed7b6d4fb8e000000000000000000000000000000000a3babac244b49a34d440b05b3bf523f2119e659781b1a787d8f792557ab53c9ba4762d5266656d5da7d3425b17f76871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bd24f79d8b557b20c3e822936c34f57c066755ad884e6dce616171ea29529ec5d6cd450d0658f2f9d5eae83ec7903c00000000000000000000000000000000179fd25154f799ffdfe70ba531d916051f52390e23e5109db61d122aed9d45aa8ceb1774392e94a060264220f22d8d301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ecd24d7ddc3f81472772ea2afed3c79baffd0fdd287ba8c6c0bdeb36d2eeff5b92947afff2dbcf2eb2ed36c3bef927500000000000000000000000000000000105f7882a7d1236810366b7ef3cc6bdf8ef8a433a7c27b6792f9a19d783d9e253b2536517afe0bb86e65ead5632034491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049aaf34e09ae3693115d92583d1bb56aef51464f0895a2c6694795f5646b6c0547df5901cd880a312873b5f3d70f5930000000000000000000000000000000007e78bb83e04ccfa8f9d7e158c66fb8140c29282090b6c0f9fbdc834f5187af5cc48ccc327fb1dc1d896c34380e78d3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013379573068a85df62f71de3157b2a3d042e54e74f779ef6ce08e3f373a113618e205bf2cb64da98881b2522935a24ad000000000000000000000000000000000dc8a012201ddfbe8a0cf5218cdbebfef1b239ee892a9664f5290575756abcfb8bc223abc809b3098ae6d1593a6bdcdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000148e39adf09ecf10fb21bb2181648436b2cff699ed62ee1e9a50516b80eb576a9fb9c56a054313faac5dd34eb5703bd000000000000000000000000000000000a093ba1b1d5d8e797a54ebfcf320e5557a006f8b4eb01a0817e59f6f1fd5d9c993ff882d0996956eb65529f47c5eefc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0e464349247043207a5c7d780f5d635b09a5d6be27f360cbc9397418d0a69e1e09db9c1a3078a7170f344ce27578fc0000000000000000000000000000000017a7ec70006cb88edaf099727b469cb1832a3a5d245393a7abc66cb338d5b14f5d73f7899615ce2ce71afe86240668d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000617eca06880ca45377b280d7edfc23fdfbb9cf5a1d71ec3de5d452366f6f8c0cae846145ea00fa55e66e2828474b6b200000000000000000000000000000000035faa871dbae0b924d81764c2d3d08d4c8bc1d9709b13c69449ed614acc58c4453ada36479e6ca3fa93182506c9fd941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002009bca2c96684b1cb2e7fa39cc70b8d2ee5a332b453dee6724d3bb4843157f884d733a15d0c922cf7782f77adfc52b00000000000000000000000000000000059ecf5d0b25742f52deab98554b02dcfbe87fa55586ff47bd2b693d0ea26ae82da72636e68007c3905f172e0961ec781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170762624fcbd6e1313a7d3605df3917799f87e2a6c5e976b56e687b5d666183e4a1a7fbd6b7c08f54184f883a890162000000000000000000000000000000000c65cab64aa762a3fdcc182ca2f133201d44c6c28dcb881fcdb6242583f42abdae8d379927f92768704f9465c7b6bcae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158135fea5ee211d9b330a4112e4ae736921d6974838a2ee1240e77f558dc470e41551ac323884b113459aa7a964a91800000000000000000000000000000000155ef1ec7a8fbca7bd70414a73566cff1548d2d03f89b4a336e50d1971fd502e829c7ab4c5c9bee3905d25adc32d42581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071ab4895200b6c8c224cdb0376c2e325d723dfaa361bab31045332feceb9af7f7308f05b049750953110c8defd61a9a00000000000000000000000000000000047f5f7c158f8102105331b8bf9041c30ace29787259403047bd0a09c034a57323b1810e9e163e93b12de9ee4ef7f9b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019027b33f3f61111d4fb412e4d120c895dc6cbd7eaa448dd9f28e1e754a4decdeacffc0de9803068b6970310a3954f0a00000000000000000000000000000000082f94c1f1777501e7a3559570ecb30eae51cec434d2b7e81bb4ed496b2de42837321516e368b6dd9d15241ccb9434161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d065290372931ee3bff8e59dbabfa4c0c7a4be2fc4bdb4c07911ba57d0d4c4162e72ff3f3cd884958255d61bf7ff90000000000000000000000000000000000645fe437bbaf312d73a39d6c02910b5a71104f8573d1bb62c817ba4714648786a47a39d56d22c5575afb9e3c9b4a6f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcf2597e1d007c58388f696f32e87bf0c1c9dd0a8d82498e6b712817c65a27312a6ae4d66801e89f51d8ac2db87495c000000000000000000000000000000000a2d0bf956414b2f86f2f868385f2c62daa0b4d1b67960eae829059a8e91a9328fdbad019d651dcbe37a48182c8baf5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b161ef685574c54796339d79da83c0d7662b11836cbd80aec7667706b198a49ac22d35ca8ec589591120a41fd61114000000000000000000000000000000000d55b8f7dcca3bb5721548cabfd5635060b4405d7968cbc4a6f6c2b7618cf99e9533a45f42ab1ccf343da563f482a82f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000012d8b3d241d6ea891fab2dd53e79743b809c71ff769da64a5c65b0bd91dfd747f8b858fc7f7abdadf2f857e13ab0f0000000000000000000000000000000013b03fb02ea7acb79426b730cdaeb67fd851ed51fedf34b954b4ebe5c0a7427dcd26da4de5a61f206f523fc423bc48f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084444f0c9049e4c912921bca7bd350a130d3bb90c440b590699f973d9bf15aa678878b44d4c855f6031d96c3a542ad20000000000000000000000000000000008b3f6036c1bc72e74fca81e3b3737b23277d3f144d82869e1ff5b5ca0995929e3f6326c7a3edcda18baf4de725fa36f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e61bfa84a8c090a64da3e495580aec8762579e2eac4c62511cebe09e6956b9c35dac4a0e0f2f5d857bb4f3314ade9f7000000000000000000000000000000001959863c91ada69808f779ff8367b3cb4bdf35bda52f89bf2b29c3b1bc25c3fb75f9ef7283b00c670a817ec4ffe164341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043952b8cca166fa8093696c66c8b6ce39bb5fce907480c9b930956aff574e193c7cb3efc849b68c9f3fb67f244bdb9f0000000000000000000000000000000000eea7bfe0d6185d4aeef016e55cdb35717c1be8ef64a36452c070eb46204a4b482b04fc7e0d65f88963f1a814de54fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103cc9f493f26295d855fe8fe8529c80176cb8c0cb1993b84fb59b86e0c7168ce3a80d10bfad0e94fcc4d969a1c9bab400000000000000000000000000000000102c014a17855e58b87aeeb6971bc8045ad5e75f2e22b59489830ef635659354390046429bbaa35f80b6b076402a7c261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001189cfc25c6c51ea038fd83061b5d5e48ce15911336fc9e50b8a8e81a8b2c2e7de605eb81f70e6a511b1fea6bb1b5b280000000000000000000000000000000011ea9cc3d7db9fae5c30368f670b17dc1bab0375fd1f8a971fe5a1ad0cb9972e2b4e04db9605903c29afb59096df7c3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152a1d2eae01c41ccadb7c13e6405c0a93a44696f58ff16ff62e15fb78a6a7dc9fbbaabf5bfdb589ef54d970b3647ff3000000000000000000000000000000000d9a5c2cf5713c2e484ce4f759ab0e5fb3d22e8b0131ebc9eb76e2a557a5721577e1166c57c2514feeb0b69bbc9b8f591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039c7097e720b8acb7f2b620f18165dcffd6ff89c16463600d183fbd3ce8dfa24ecb863dc54c9ca8072353977f391b680000000000000000000000000000000016eba4e180292f73f58f1b44e6b0ee19eb3f3ed8f25806ac690255099e7f69d11ba7e5f4c156b28a5628ca34133054421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6d9d1a830bbee41fab3825d0728e77e8ad22f8df12c3d829292acb379869c9630b642423ec1350b8d5f3f7ee49751900000000000000000000000000000000192fe4ac65b78ec4fdd534f320efc16d1ddd1a03ae5974a0100bb15c038f7e27db085fb6ae29c6600bd9aba4b78419431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d5513029f1f2a07b1c1d1e35e520032c187898e9246e33beda61dfbd6d754a0b86e17b5589ec4a1239c0996bd4ee590000000000000000000000000000000018d5a84057078f951c95dc9497728f92d4cddd773733c9d2488f886a85993309cf0c39346ba91ed818e3627511ded73e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fa53f6e339c97f07552796ce719080c187fede2ea0a9d7c6add01243c88f3a257ade9199a1826477d4871086966ede00000000000000000000000000000000196d32a3d320a0527d874d1552c5da42342b3a5b0e5fa48b2cb86a838523e4cc9d278291ae4d612c234ee79c6e9a96051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080631d6f440e0caaf4c0977109bc8e727cda14badffc50898cbe2a97bb4ef264aeba669653410ebf0f1900f07a2648600000000000000000000000000000000184f0397f7cd94e7ca2135037a50c802a85e3540f0a7ee3f42d7e6a0346bf1f7b3b0dce301469136b0ae21b1081d73661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000957c8c6231d6f21fb331878c20587b4be19601040b03d6ac3a9e7750bbbf76ea044492bdd1ec86d2a0bc39b6cf119cb00000000000000000000000000000000012bf274249fc4eee13ed718b260d95e37a495375b96d99c99e9789103a420ed911342387c14b70ac751c9c0240a8a021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006094a74ac191d887254e4d4799d937995498077d04f414fcaebafb7e67b4cee4e86e57c2eca8d1e43f05410c23180ad000000000000000000000000000000000f252c575a8b5f2c67cd69c05276f88550c04d343f957f3221c7785417100d190cb9a98c6a181a9da02bb9afa9e129381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d124b9038f96868c2e51b8925d622d9bc0b8138bfe741d618ebee3ea532e842dfbc7e1825f459a0c83caee274119230000000000000000000000000000000014fc28b5b15b884f78867ce588c1a5a6f08c735b87ec72373a3fe490c242956605d572e6ff58e0935b3a1ab1526025201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3d23a294f9c7221fd73d8d6f8e2b39bb1c67203a0a77a98810ae8751f00a4c74c8c296f8308143d572dafb3323d6330000000000000000000000000000000001d8a837266020600df18f16eef2b27fbe21de5a7227106cdb424ba2bcb02893190cffce652066bee6949b2a3fb2666b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bb01af082a0418f7862b5003f9974b047ab88362bdefaa30ab9c938942b100aac1371dd6eefb680666a9518237ad7700000000000000000000000000000000157cc059bc3c120a336e260395ba274d647b12c0e3198160c87fe95aa37e308c3476dda3066acdf854fa889fd8b1aa931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000338d3b7fb5a42ab99fa3d0c7899dc0b7018db189b52fc3db6c9f8805c63c48888050ea3d707241f17deafe0ebadd4cc000000000000000000000000000000000d9dd4888cf763efecf5289db692ea1143adabfbec4948c6de76c435ffc5eed215e516a080676b942303404108c3bc6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3fddad4c0b3df0acb6571568637c7e2ae928eb350c139964b15fb8c97763f187146f84c3f7777bde0b10a131e109d7000000000000000000000000000000000f9a03e55aa4c13bfede92948234a3eca2c34afb324ae206e861a4ed9183eb4656d3bac0738fa88e92b38805b2db45971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048399171ead1ac19314d19c79b08163cfa6fd4d2646f1f6b6309c0a797eee978cfca684e4f03ade78adcc35caec275400000000000000000000000000000000153c43bfa36675811e3e79a7d2e2e50cf5374442fefcabe0d2a51143dfcf25e80f134feb2bf91f43f8efba3f7a27b2be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c34aed6c66ff21a6f2b545c3de17cbfc70e735165a0d825f7b602a3211098cfea1506be60fbcb19f3a0dcaa4c9cc70000000000000000000000000000000016d0369c42524833adc06b70290ac29a7f56a286b31a4840e63fa5092c36986adfdce20e917196a335ddef03bb73e6551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d036afe4328082d9bec8fd8b054c0470ba3417c44fcec1feeb4801caaee02d81f046f7aeeed5d7be5585fe19eabcb340000000000000000000000000000000000d7dfaf9c0c6bc01d10e5f3e30e49b45e2b280114e3a9d39ce0d171ec3ce00adbe791612b7cf4d67986ad68f56512dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7cca7b0b6383ca093a5151c0e048571e0149a4008da9e6fa3b71ca749b5e44ebe97a69faf6bbb3a84a6cefa67f518c000000000000000000000000000000000a0c65e3a156733d3cc9a2586f54dce579a0ac73c5c16a67d4eea5445aa83834fae20b42fe5c891c6ecbe55f4ee873821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f1f8f5811d41b03f8a06cd5d6bce93242614d601f3c2ece3f22bb20cea0ee5a0898366397378f0d0b54b557591514f000000000000000000000000000000000d424094c655ea7970fab942016da2f9e047e2679cc6936e73c8a86b4ffc30230f3fb32aae79a1bc114ad42000c321d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001900a5f2de43b4cc8b8201b50d9fa206b783404d39a2f1c36d6af2fb7ae5414cd346670c19272a0224916694b4b888f00000000000000000000000000000000003ac2b79b2042e711fe81594337977fc6074cc6f5685a72c6ce496949ad0c082817e648612b6364c11fb303152ff58a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003651e0f56ea75e11994813b17a23048e773ade830712c88577ac74a121e5ec664e2f56ebeda1f755e5c5a71963983f90000000000000000000000000000000017d8e13e9142dd41152ffab4529da7b5dfed85f38986bf873c3e8179d502dfe2c9620f9e73cb431d55a765fdf8cb2b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bec94137f8719b3c416399afd0c9653deafe810320ab57028b10ed719da3d67c7df0328d74fb98aad7dbcd13f2ec570000000000000000000000000000000003dc3fca0ad4266d3822920ba8c346fe009bc4a70064915b262556522c87f26d6a37fc090199df998ffbe9e00567627e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056f399c990c96d08dd9d00e22d1ec868d16c936ebdadbb67b8e7ee358de148493907a94e1a5a31bcfc4103870482028000000000000000000000000000000000e63e9e609582da5ffd06d37586668968da7b0dd0bf7848caa0a67cdeccb691c3d65edc89afd0bf37e5c574d6836d4d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1807bf3b94da647fde9a0b4759fae6665bc1746884e9f68233c0e0f31d0c39ac076192331073f972aea72fdba901a400000000000000000000000000000000056d4bfde8146bdbde9279634ca8fa92482df66b3ea777c0808829630d7b1de60a6feea742a3089e56f396dcae15a4e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185c6dda9ed0a2e9f838e31b049780dd63df502fbdf41411dc3f951d4d15351b431e25ba7b0bcc76e8d02d0e8f69689e000000000000000000000000000000000e5518ede62b48726205060429240c0826eddd1bf315da5304c9dfcee40b8165defcee41ef9dd90b35249c6a5b0495b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001819f8595014ac2fa5f432cc7ee167277d986745102826013f313cb105645c865dfed3bdad3fe2785c7a00d0b03302df0000000000000000000000000000000019d710c67b5c34b304799378e580b298d8ae1f02a9fbd10e3b94515ae79c1db838cb62881ab16f461b0da39dd18e74de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cda12a68ed37aea861402c59fc90b7bbb8a964427c1dc2835c640242c063eca7cf635502e055ec54dec19ba9920abd80000000000000000000000000000000002f294b0667da603e0b3b736bae541132abfaf1b1705350afeb029dc51ede721b2f7823e8d3db36b0a56e404c63b2c011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063b7af2ebbb584d8b4b60ba6a8048249d9871ba408f72e8518498ef73edd55f969455b05f92fbfffd6577cf439ad3280000000000000000000000000000000002c966b853839979b88f15feb7cedaac2390c3bae0a39847787a0f42cbdce964d91c1557c2800baababaf954192aa07a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c561c2be003cbc11b8520a06666b92d1b0b6dfcf345e7b39b070f6cff9044228d26cad64208687598e12863ca2b643000000000000000000000000000000000b874dfd4ac8b4891937af08b40366294c7d355195b5691161f3c3d62fe566baca7cdcdd57968b16f431c8492467ff321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee05d96f62d2aee89334a1b34328137996dfa45de4e943f76e9171df1235df49762db30564d905769cd0e22b54a86600000000000000000000000000000000010e562be0c84e350d26e66f345dd966c8c2d6f6f7fd734db1300fe4ff6e667f4617791c02d1d1bb2daed35070d33be451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5a29f182fa2bd36611fb68bd0f2b70d7737ec2a9824d20d9b9490f014dc417a3395397bbfbb5bfb208bd12e958170e000000000000000000000000000000000cf54f216f008eadc244f014ef04d7746302b5fad839b86261d150bf5641ac14b199c74a6d24959d5f62abd1089abd5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b9cd0a0b151ea21dc9e1270ac0c681e56af2d30d15d90b972f9f6380639067a1ff2e1e4c5d0dc6a42f7eeb0b7e597e0000000000000000000000000000000008d342af211a3bef380c83331ea97ff5aa9ce1234b0be5b16aeacbd4aabcd10ce9fdd9f80a282fdb489c80da408c3bb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f190f2bda94a6b5c15c4a3ece93205344c3dbf33e92bfb4964f756eaa54d6ea1354621a316c7937784b163df0a7a6f00000000000000000000000000000000101df29c0233f7d9211dba6282f2eb254ac00dc1af0471a7687ac624d4adb7fbef86f11692ca0bf67cf59a1be4788c9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191db252588ead5df4cd5b2646e5daae4dcd9955de380cdedafd658b2fa260d7ec0c2cdd3c8d1f5ed33319a949f4d2a6000000000000000000000000000000001545e825b781dfbcafec2e606fca50bca1f65258fff0231957d3c1c70765897c52e43aa6df35da9027e1cb18c145e0ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b401659ae5fc4b8443333bd9bc6a15ca919719bfdf3ff772abaa1a75c88162ba36bc3a776fc20720b523e31dcd0fa2f00000000000000000000000000000000076b0c3d530b28840c031dd0f9b0c9d758e353d98fee65af13109dc8abd6b98c16748e27355414d8e2221b08c2cfc2c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000980e27cc723492a0cb9f871a6f16a00a8e93143eee8891a09c17b2b070d68e352ea4cf3716f8b4b72025df090ba2ed40000000000000000000000000000000019d11c5f76aba7fc44df427db11863175ae82527a5e3704de7c20d1d8b287b37153de26dedf1e5c3a8074f0adcdf5ea81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005918d0334bb27edb3cfafef03059447fc4fce694eddc5be492fd68c50a0c0766b4b1f51b2ba57980282017dcf70a0cb0000000000000000000000000000000000f158ad866fa02dbaa1bae3ec3b4cf857819782b872d946a4b682aba43571e5eeec92ce4dfc00e68bf14ef0bf8a35081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000363f25c0a2f7d5581e3524b0ec986356366edbe1707db75d7440d632f9d60fa729a403c8d5e37824089dd97a22b59670000000000000000000000000000000013545084d519c85660b424da44da32a93e9e53f510baaf8b4222be5fdd93f43945a8b0fc0e2b9d14420c4027a0c66a471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f8f2bf4fd29f67b9fdf848103370268df354a3d5f5291c203adb66a87ba8611dbf8dcc68a0ff4dc98f9f41e08e737f000000000000000000000000000000000a278629272492068abb084589298f2a8d2f48d71e524988e44c221990185c8e74e4ef01ee54237989e1add2f12fde5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6364a312abffef938b000a7bd403d74851d9c6b6646e69b3455e40e84d18b77d0fa14aa862b0977ffacf16d37c700100000000000000000000000000000000073d72568c833a1f8cfb0d5e22d98c3bc812b522761a055026148edffefe58558461e9b670f09f471d0d2846f496ba8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c69a457e975f75b1bd3b29d1b5fe9c21eda14940da5be5b144df7798ac94a8173d830e80cdc52b8c5e9712160c047950000000000000000000000000000000018d377cfaea2aa32faf6a19794727f27c735f0026797c9a53797c4d42d3990a21a2427d5593eeeb1cb1720f28ce5c4311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000171576d9f87925451d578861acb515ef68e6b278f736687de653eb40c8150046a3572284b36aee38aa7f4c6bc81c1da0000000000000000000000000000000003f410b94592c4bf3839b2cfa9b0cffe8b6a0b37e2828945035c9a1e7b32f86a41d1eaa209d88182823727e05e49d4a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014fd5c48b41ab311b841b99fa2e29fabb6332db5112cc68be6bfb12d642d54a96c97243d57b2487d2ff79263006d1bd000000000000000000000000000000000c81eac9d2026118f35178703bc8886511953f7b86a7cc20d80a101b7124a471a36afc758cc6a04b75396e6a8b77f14f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b8469ba59e96ad7271c7f818318cc19d29dd255c7d38e94600c12cde76f6042ee1c2840ac9e6f14a8c32ccabd6777900000000000000000000000000000000116b1dc6de4923901f39be37ef5e92ecd635f3dfc97dbecfd22d0cb163b38b10c958520c2348bbcab676cc702416cfca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179b8e4171ceb15c935af42a3d9ef902bc3fae9aa1bda29a06b078ec14ebd9d3c779038a364a55c408188c90d1dcd38e000000000000000000000000000000000857e2935fdba45e5a64f0a5a592a49d3d5ccdcfe2116d2d13da31ea575f1c5ad1fc5b8aead349c0f3f737ff3842511d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e7dd6b05eabd1163be3bc19aa7e67dcde09032140e0ed42cf02010593d1463b68f312e7b1c78dc056b2bbf3601495b00000000000000000000000000000000056c7c750e03c352db94704757f57d265cb40cd95309509f4219e47820d092683875ef06d8288bc2b7274b355ef3ab101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a79c8a1e3e0112d8997ac0b8960ba062e3e6a66be2803e61f2fc88ac5d047ab9d68047dd1f99e8602b016cdcacd417000000000000000000000000000000000630c33856c1decb5f6c889c6477b11cf1feb65658cd1eb5b27c5cd41ccb3d340f8669e1f9cd17bb199127656aa6c9031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019694326d17f2a6eb476f1b149e8538669e6637879279d8f7aca01b6779803aa352beae9840394bc67cfc88e3cbc89200000000000000000000000000000000000e93267e08e2e88c4ada1338abc3f842f9534cbb4a663ce1902d96efe29ab00d6898ce4d7f519dfff23a8c10e54de581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008657511487a4cf3041737cbca8a9a57b9edecc93507d46a22cfb331676f9ef251987127541e40a9cce74c64700b262a000000000000000000000000000000000ec6c0853700af75c3b7a0ae0a9ebc2ce9f5272bb7f5a3d1fb2041a3ceeca5bfe38c0ac7852b8ad69722c437e01ee7981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f3afd8fa9d42dbe9d558d4373c1e04c2967484284b6ef07687902a46dadd4198b2f717888ce99077b2fb2bcb4b783d0000000000000000000000000000000019f949613852652d818bdd3808a4a16d4e8822ab5c34e7283ada7bfac3fddbe999621300fd9b265d4c5e7ffccf6c55db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bcac738fc5b334a4b1a02847cb62359e4b7bd5a59d937e7bd5994a6bababfcadb1d0ee1bcdd1275aa8d26ae2d52bad0000000000000000000000000000000004a842961be097c91a43449b5b231773b5d8b20a4a0512f1d7ec95136b5be65a6ae42e82cc20e8f13960d1cb6c260afa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8f3a17da3574b5e88d5a0e01297bd652ed5062651bf099e064ed85b0bfa57737bb07c849a28353352f7a94fba8ee9a0000000000000000000000000000000000ea014804648e24649be2469cfa23d67eb7df8c40893ed6d37d72ec55a6ca095fb50554f7c8fbc7b951fd9c968ff43b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a098c4b5ece79b419d731e75f1ff731d20e0a63fede245fadeca480fdba01835d274a2df2992377ea1d9494237855a0000000000000000000000000000000016b0bc022d582b54a7dfed8e48aa9c8aed703c923838225eabf369ea21103a2cb7497c1c8d149e04077955693347caf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195b409e64a2d6d7685eb3c2b82a577b4d0276198ade23e0f9e605d332b5ddcaff7010648ce7b3b0595c1c717ebbb7f3000000000000000000000000000000000bc7bddd61540c1638b1cc2ed60a0f7b51f35223d7a43f63444a223ff46b1214d89dd05f6debab6ed163ee1a66a4d8561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131604e4c1045f77bf80efc9f3ef72c0577152d3e4f4662c35ad77e4e3fe5387a69ded7b91d6fe3390c6cf9a3e97a85b000000000000000000000000000000000543980a1d8f4149ae53e48f13cf045e066541cf5ff42b2fdcfab6177578601bd15c86a5ce16b094fcddbfb1037234bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fb5d57256bf951f342f9b337f2952a296c8f4a83530b20ffb8cefece7f45363c1369dcf60f7e34be340423e3a61b5a00000000000000000000000000000000055ecd76563d776357459b8b7cc42c2983884167ab5a2a9281c6ea11461256b69e185769ebbdf1e2ad766e548573046c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f0329a4f25683820b186232205fdea4d9ac16d77ae368d072eeea82e4f6828439f8a92a370b09a4270510fccafd15e000000000000000000000000000000000202f99e5a16ae529ca5ff8fa65a1ddb0931821f1d50883d74310883b1b9a27af355d706224424572980e9f4883d789c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a4c65abf1b8ab82beb2a1b8a298343abec58b55235bfd4b39e11a0f728ccc30bf846abae02c6ccb95d6420a4015ace0000000000000000000000000000000019311125a2d8c93a227e1cf56ec5288b91415c29aa4efd12b7763a2e5e9ff8a2ca0c541571dc9daed160275abf2b8dc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064463ef8ef4f64b92eb8ee5d7c9c560754ea4ef556c5b951e47536a584ec8ecd2cc46606d87074ea1f9e5afe061a78000000000000000000000000000000000194a0e950bf91cff8b41d852cf317d30a1ab70160f00344d7e700c0c6d6f2639f57a7572ef4e5b5ea7e65519eea3db4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017eda2e5b923c29289c29b2e681d05494a4ecfd2cb7093af1e2debb7cbe3aa861b4c436699d7b5fab37fc5c34280abdc0000000000000000000000000000000009587f4a79e11f884613aabb07268769c69bc4dd6dd18021ca8b5e25ca329a401de201ef9b78ff1ae7087b15a662b6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178d9024675adb6cc1379ef82dd41e29df4367e736c33f1ce2cb7d3586d2a07908ac5737915b583366029e512dc4b58d0000000000000000000000000000000004fefa28e42827e878a6bf9d455c30f9d53f7dbdf817130dd0b979c01600750e9a9708b4791441ad7127c164a55d39d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e9836a751cb070efdd4a7bd2b79ef9b0b2d5ab0a5ce382e12ba9942d640d10453da32916e7458572cdbfb36931a3d700000000000000000000000000000000023a05f1827a52fb8e3c97dea77034d347a02a1aa6db8e5cdb155f7ba479c5844abd957084d804b50440883a7f395bbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004162dbb0cd49fe5019df6f10a8bfbcb322c8ee62a8eaddc88700f3aba103a1668438c50969dcd37fbeecc20033d48d6000000000000000000000000000000000b06ca15f0b1e829551bb2b9b652ce329a36943d5c5b1e0106b6eb3eac3878a53bc079bfab10ffecfa5a4df2b15096501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb7abe42ce13ab545549c2da5ef63db56b5cf549bf6064966c0db4d4e29519ede65c0b069c0f2549e73302e7cd4ff30000000000000000000000000000000011034e41720620f5161c3b97a3e274b0abf6bf7ca5885afa888ccf4627682274d701497b331f9464673cbde9fc0be50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a330cea940e8ba220a3575594f30caf80fca7ad9131a1b3a26318303fcdfde8d1eff41f9d515855a2a7d1eae18dccd4000000000000000000000000000000000e460c3e6aec2e17d7c326bec9ab97b59268f026f661982383cea9264a379131ea2b7c2979c3672d4990a052b72922191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0f2b0634afa168b9c1987009b6259ca6db6d7b198d52642bb5719fe27607b9e8be25b9ec0669e408e974425c79548c000000000000000000000000000000000c7deba9620f7d7688d42e11a5baac5819ba6988b77b5aff8f1c205013361a6157205d31156ee7a3c888a04ddfbd32151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d80cbc692428005beb46c71f512f258eec2ef851d74949bac0c59085544e96c7f2237785b03555ed9711cad339b4590000000000000000000000000000000006f0aa0e4ab492d5adf5f7df57c33651411a9184d340c9f99f70238e86d2086f3cc64bb05e7f0bba5d17d0bed2feb5a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bebb7142be81af4b3ab2147ddba342cffd8fd9d5ed3417fcebd635ec706f89bb2b720fd94e9cbdc57975f1325b2a4b00000000000000000000000000000000030bc47a8cba434fb7df01f928a89b1b6bc37f329f43134dcbcaecf2c801b0c4dcff997e2bb5091f8642036e67f9175b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052a0df3a550bc012152186454f7d2e1baece4d3e52518c3549987178658b391d2c849beba1b38c59f7a5a1ca2f8b2a200000000000000000000000000000000130bbd95c39843d155fc1b9b5b9550c9d4ad367294267ede51fd1e7392d55484fec319922247a7d0cd043908a3574dc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b77256bab416dfe1ec204ad1aaf25740da6bf3a373c68216867d66b013aa25eb18dd5d6fca3304b1f66410b602ad2fe00000000000000000000000000000000021c5e26af09f33d971b0d6d845c348976b4bb47a1911ed8221e4a4fc1324d399222130a340fb79b472277159cf1ccab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eabd4d76d709b44b76d62f627b895f5d68b2ad9d13dba3737f317005cf805714662bb25041a9cdea7e912fa647c925000000000000000000000000000000000862b0ad9a9625836199133846b76b397220fc938e17cbdf0fdd3bccdc7889efd402d8e75c0e093102c349d65804ebb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fec5e4b27246412b028b09f9644c6bdfafcdfad163465dd8e3dd9f7de1fc9b668583dd2e147ec61a1eeb707188ffbe20000000000000000000000000000000005f3b1e0ad454df724016f3c94c3cb360aebd774c203ca4720ea541e5383867e875a5810d9dba61650eb1ebe8659d9c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f061a77f054b019cd2acfc1e0bdc86fc8ae2717ba1d134cd241fcc5c338726435ec576265e6559887bf7c6d1eda248100000000000000000000000000000000165b133416309552da35464108119e75c005a9f1ccc23b03f5d42e5bf5c0fa98f98bfb9ff85101854f4d96dad7c9f5b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000145bbcc8efb04c44ac83a087353d1d231e831bbe22c097e0cf0b9dba35b374570825f6f21915a85b5428f19cd55ae1b000000000000000000000000000000001495df4ee901ce0fa2a23ea7bda5889cd069f88c1ac888beae4f502b664e95563d2cd4ff9682a25189ef60fe3ca626531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b7c2f786f69e62485a70dd9d2ecbcec0be6ec0cac5e6e8c50995c0995793077118aecdb547dce1c190dab0e9f8e63c0000000000000000000000000000000017fecf7e1b34a13c204e419de810acae98de49680f572645307790bfb7d63619ccf8ae2004d6fd517aa2dc17edf03ef61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042e6e6e05463dcbf912b50de03142d55a08194938995d372d201aa34aef1f62ce875f619bde166a60431e518a7a571d000000000000000000000000000000000cd0c8d95c9370dc2f96ed46d3c8ef6416765eff945011a1c41cc4fcdf7fd14282781cc6179ec53dac71be931002b7cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148d585a223eef942d3c04217c8d7c428a7f770140f6e07613a1f2037790d8214379529ecc66ac89174f6b0bc2603070000000000000000000000000000000000e4349031f08084877d0ffffcf899290a522d4f19cca8cd9268806a6bac02b22fdcdc1882757b7bde1cefb3272ef86fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131944931ce981493eb9182cedbcb6b236a48a4c5d57e43acf5ce23b2ec43efb6b2990a7f792c1a47fdf5361c0228e500000000000000000000000000000000018cdc34647824decdef26a24c5558e83e0690bb29cc30cb3a3fe055a2df57576700f1a8ffbb5048822067262a42e92841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173379f32053b6f82df42f14552c91ee2d07950d32771a493a39b1cb31fa613c6456fb3747f0cd3b883f5679faadd05e00000000000000000000000000000000012e04f47a65a2091623b88df8feeaf6f4e7331432f85e0dbb451a86cb4a9dcb2eec0891c96cd19bdd0216275f6226dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe3c14cfec078808200cb147daf49d2eb913bfc0f827c8532f48a61e80f78ec762a03ad951107e28cda132252c976e70000000000000000000000000000000018ac56a7af42554bf080dc608754cc3da106be3bf3e0468a01315892c5337a2103a0dac37d38ca71a4bdb50f6cd9f75f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bed8ca2baa5965cc05abd385a2ff2fa5760c327554c3f0826f8d3643427e74484f08dafe4b643d03f602a173e5f9bcb000000000000000000000000000000000ebb6e541bf97c37a5f7783731fd4fde514a501738aa5b5ae8829fbae5bf63f862558e541d0e64f2f8935512f056e67e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036872cd30e6bf3730b4122351c9afe60ab0938e0406a1c35a89d62c20df3496cea52908a5e2896f127ecc3ed9b4804000000000000000000000000000000000180bbc580508fd8e1b682d39194e9cca4d76988942691376963a8a207424b6e0efb585967192ef84f127fbeead7b32071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149b2dcd4d75b6b568462bc672269b4d5f7d2bdf61416fec260eeaa76ef318201c6a0e4d474926c7317261a8c92b30e4000000000000000000000000000000000b0cd3ac3704347979706d288db0de75a7b0ad4bbc7ff0314a2774094331b9bd92bb3ed8b1c27497d53e8741296676781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062a7722ef1d30507e1d80d6e84367ff79caccfe47267fcbabf5191ab94ddc49577fc3807c27057ab547b13a8c5b78480000000000000000000000000000000016236da7a03d3986a8fb9526e9c45b386413d58fc2f9392b1b318c87ad104b345cbfce84ee1e06b7498c747658cd78901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0e4833cd2e31ed370d4b3aa2e7f6e71bc5349be6eda14e979d24affa79d0ff62aa7c3ffa442cf3417a400b9c6ee3ff0000000000000000000000000000000017c438d862e1bc0f3d9f309eb975bb09620802b33584b1a45b23558d6e68d0a695d7ba7191acf8d20c3bdf05d905b57c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d12f5dedd3f67b887651ee178d59e4ab01b8f403d69ad25e6a5b581ab1f1b67212aa92aa143a10e5fce008d22a2c10a000000000000000000000000000000000e44700f0c164836e796fa4c15a5929ee4b2937a4583ecfa662bff008f446c473d45be3bd978e4b50f411e64786df6ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c9e7e3cf906cc0ff2c52d5bff4d7f7be1dccc0c6924db53fe9c2a8bdc46bfbdf11b8a440aefaa3bf095eb6303e313c000000000000000000000000000000000e8c7e38fafb79dfe6d8780294a59b71e77989fc899517ace11bd45b50b12dbe470328189efd2ef5a92eb2779b636b551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bacca1d023bac30aaeda08c53f5379946ae67416838083cea9aa7e005ee4b4b829b86d9786aa392e6a32bbaef151a50000000000000000000000000000000011923f683222e4fddc50eb4219cfc7c25b93c8a23c4f480671b79f2f926c173909d7eaa579ce312d3fccdeb1008577851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1f4eef07aa208821b5e922cef7768d79d37c0e75250ac311b64b457b6c7ec03683b676f16af045fa35d45a31ce7c7f0000000000000000000000000000000006f7dad7515720433a7233e5499b2de028b1d84aacf5e9b026177a95e1c52658aae04a1957deca4eb1c9171d9ff7d0ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191d16fa600f91b3ca6317704e25d0d2cc1f2b207beb8e1e98ca281375fe2d23849e0c05a7a55ab1ce1461c74f1db08a0000000000000000000000000000000011bf998911c5c3f5ce74ca85fc7ff7d012961cef894b0fc24232994ef91decb4e0135707fd4c94aa39787f0d98e7f1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124e15e1fbdd7ad699793f6b63d533d22599546348e34bf81149613479783206c9ff793a050042870e33233cc00b3bc5000000000000000000000000000000000b8e75ace9bfa5cc531e094fca551af997ae28446b3eaf7c84ac45010c85b79a2c3b887813c2eac646ad194932cf43201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dc8449120f0230d9b2460834318ccc967d9707660df7931d69ac7c8251b12ac8bceba6a88fa5098032a2838f892e100000000000000000000000000000000014d803bfd175a0b64c7109d31c50eaa71e5463fbd5925c98b1b3ca45fba9bfac8760ffcf6f0620591c3293cd76a6e2c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ccd8c5f558cebb35cb12a8cf3149cd242a1202db8bfb0e3123545f1910ad9ad6ed1496c191a65cb14bc79fe49b7e8200000000000000000000000000000000005d355167c3e64ee161d95cb9c9f86c1b2d13c26576cb8592593ddd6b3d883d4b54affad00a8aa4502a5fbbdd9d44641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ca6ec18b536c1a0fa7bb2d6f7e13df668fb7b8ac3a7f44ec5895e2edc243f525faded7ce6eca8b24283617def845090000000000000000000000000000000006123df662a4abaa8d519b3b00dabdc0136ad6e096205f751fd5314e15e45f5221266070eb7e23a08d4f7416f20cce601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173e440d00f0db24e17de1ed832f99bef7f3e87dc4d62bf54bf2d7a6fb358a98d21ce9a6889caffd8c8c1efe6716bc8900000000000000000000000000000000030b0d475a7371bf619bf330d7ffc46fc8d81213ce04cea7b8110672bbd602baf641c570e52d85f35e1cb3ca68d487ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c36b6258f0b6044628aef4cbe97866c560218667a87f0278e02088b253b9174fa22ea325815bfe577b8a444f4ec9e3d0000000000000000000000000000000006409da464b9fa3a38827b3747f8d3d148c896a87b2ce397748a6096445633f09cacb978b86e074fc0eb016493d5834e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014125f783d1db6c640b0acb1144ffcde173ab1bdf3f23fe57967825487880c7dbfabdd7ef85541ec697dfaf20a91153000000000000000000000000000000000bada14d3640b8d3d16ab8d1a5ed6f52bd25d8a8ad243d962e4503b724ab192f0e0c8a7bce9b8b00d6f7d3c3167d65431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017149af6dca0caee7b1247bceddf5ba0de7f00995f91f89e95f7157b7eb6e9e7ff5e87922deb4693b4631dce6386da38000000000000000000000000000000000639c4cae1d1b7d539b662726ddbe68857349557a0b19aa63557ede2981f8bb0c69aeec7dd865b341cde2aff2bd212b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bc5a31331c53367cb4a8c0e993870987025866f5ccc59fe2bf8e90345c58d34e20b878530495029e9a0956bfcb007600000000000000000000000000000000043e5e7e46b11490ccc19a684a80b0b63841fe6b021beaff27c9a1cd21e3a3c0f7d16941e424e6c55f57ba258ed019fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077118b0b0a0e2c69af151c07e0f213da00a2d74fd8c5266eb2db0e8f959e04ca5f0998eaeff7b54f7cb467b462de91a00000000000000000000000000000000066ef94ec705e24c05f666d4aebc17200f78f835f4af1acfe3a5e91cfb03b921fa637def74b000878846798be51363271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101457ace090cdb1b31c9d496fc2abd726f46d1160673468e0b2abbbd6b8468c4eef46997b8453ad93ce4be61ecdcb320000000000000000000000000000000019456add3b9277da8250ccb29f48fe897c8f72df826fdb5568633b7ac0035a50c6e70e7e1b212cadbf39e156b57467611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054183fd4866f8958762e142f539f60f5706072d60574cf669542cbbb9455858b9d62e2d426ff5c8643f835dfd765fe50000000000000000000000000000000004898ca36cf395d9097a082722e81d09987abfe1af50042f516c7d32c7af849e984043d80e9b3ed0be15d91af242ec5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010e1e77284313aace464b4113a76ff4d831da44e921d07a13f8d721fd05cbf489e75e0fe7b0c8fbc41ce499559dc48c000000000000000000000000000000000870c5f40db041e511ba8dc46b8ade76950622fbf6399c254792bdf9edbc60db37cf10e7700ca0578d216a68b9f03e541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000801ba58a8b7a5962fbdb3d38f27aaacdd3f7896f34ff01a64a31c38c8a502f3a145457f3f631a0b7bc938c56f544e38000000000000000000000000000000000ce2c50bb97d64228298bec9d89bd5c82dc449f47e6523250ddb733cfcbe1c9c98e3e5fa359fd58ae030dfbd2262d9231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155e278b2fd203fa2d4cb7a5e6670b2b8ea005b535d77f40c6385d2e191fc01bebb43ac440efb31e3d90422c5abf954a00000000000000000000000000000000124f53f7647e1332bf909467c9108aea7216cb16f41cbe15523450763c78c86d910ccbdd86bbf8d044c7625fa765a9d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e9dff6a35c2bc0ca687b1ffac9d5c93231ec206237217a5805acb9df09b1a6b8182f4ed9621df701af72792da6bae10000000000000000000000000000000001158134b150f0fba045e548c77ae725782ba763baa2001d98276d9ed1b68edb4361a743d549c7b35520bd7711c6952d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb1e3abb946d1e5ec9aa145361ac84fa9aa548f0740a5b812ce97d38f47e067e5dc8493bab6f37f6f562bb0ed01ac640000000000000000000000000000000001d93268d611f9658f101c1087b77bfc95b758632a6b01d9b8882e2d65c056ed5e53350f7afa3bdeab9a7eadf0ef22c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068ac72074450e256d551fc7f224bc2f1a82f35ce9834f41f44b561dd187f7eeb63a4849c2096d9aa08d99190b3bb73600000000000000000000000000000000188f0a026c88c0a427737d452bee229b4f6d1fc83efe9dee0592504eb4fac80d325da097e4aedf60648c7e9e294b78761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001799070dcd77e2133bca4e3905d4a9eb5373d189447b5622bcd912324c084ae08994d87c5b88680a9c148edab6858a8e00000000000000000000000000000000177ad7211b87d01918c73cf3ce22e67b1452f2871bacbc9df8c91bcf6166fd6d4ef7bef6d4b414ab22524a325321a0951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009518bc29b9c1555dd6a453ee98fc077a433de1fb02cbaefe656d5217aba8bcf413078f9ceacd526bb2d6c22ce6ef906000000000000000000000000000000000aec729a9765cf09d5316676fa593c9ce6c636e64dd9bddceb22f1f30526804ab901808a936d904dce969eb490b0d16e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000724ab07102a6d42cc167f26e34044529b3bab769e175606f082d9320938dbfd4e7af54ffb43d99421bf8e829dce0b94000000000000000000000000000000000599b1179ed5b40a164e5253096781f93d3c001e42b2e2f24a59e543bb6030bbc1e4c0cdc8978b1ebcca119aab6f98ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013755fb6dfbf3d53eac9014904ad0a86114a1a6a52c565ad341f57fd9b697e5ee9f259b771cea32a0aecc915f102f98e0000000000000000000000000000000004a38a3070da57b8afe93397a2895a104cc0257141ff2253067f20e550a6cc150923e0b3565bd73c0927632b5a00804e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119074e161f944b8de7584fb5e94e4608ec2d5afb161f87bdd588667047333494d37996a0e039b4ad61c89495b253c2400000000000000000000000000000000036d7895561a20e465e3e3b818f486450478c219d8e6aeaa2541837dd95cd168aedbb12dbf39b964d29ec0ff456344891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003486e9abffafbf258154960a841329a943bb2e4f67b2e24a787eb837b051c18ac14da2b57f41a321d63904f69ac11fe0000000000000000000000000000000009c8d96ae369c24d8abc1e8e52659008165a106a0b1716a11ac60f2b232db48d79c4aeb9954bf93455e1cf6bb79181541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001772cc685312a4fb2b563e7d688d95398526a4ee0e6a226c3feedd9f511e5c0887efe1298c47d1cafc4f3733bffe79a2000000000000000000000000000000001948f103021964150c1efc1993482c7ee68bd5880997e0d1822e535dbe6efd9fb611e2fd7e85847bf2b6a61d8eb2fc131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000345c14c0f34092275cec8962bcfcfd54778ef6d982c6250f1bc29776cf25fcd4b7f34ee53567e597408a6ad06a08df90000000000000000000000000000000019302fd67d63b19f836e704feaf5582e7adcc2b07f87fd2b5e2f7fb26efec4023cf01e794b41302d98a7ae34157c38c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b75d93b7b637577c1d613e045ed26f923c552a1d63223009c6c11b2bd9aff6772d44c8eeb7acf52bdc0d6b9874b81e0000000000000000000000000000000019f32fc0a501038bc4a0a1aed222aec1e5d3dc965a50179495a6364c29637649c3f56148d65148928f1e0a44cc8ee54c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034cadf27e69da3988ffb8d18761f7de9bcd466334b92b1c2ce8e8331ac25d7ebc368795e9af09dd713c4e7167ab8c810000000000000000000000000000000004001ac4535c9a49c0c685d0206e80927c56aec9ac4d5e6a05188765b94c9b7410b0cba02cd78b56c102c4b4de7a965e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cc99c8391deaf90fdd471bcb765a0a96c014902931f184a2a6e51f160f5ef7ca45215b50eedd9ccf141f9043cbe7b500000000000000000000000000000000103aa3681fe016866872bdbb6d68dafc88629aa57c7882809f34af0490accea82aff0e42e4d545bb908b72c19314ee751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019755fb221e74da759ea37d11bc18c620e84c00bc3640b735c82a936648484bb12f669c24fe97a057f6b65018d7934cd000000000000000000000000000000000ae45ebebfb387bf02a618581baf7167e93b20749c52956e02a01e2c985d1d633f79aa4fdd164cd4bf9ee0f75f3583371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2082ae75b670e20751b2ae3d8c07a5d5ec457fc66b382cae4f0a0872d28684dab8da7e9aa7460446f74de5df28618a0000000000000000000000000000000017c5e4f3dd572c6d29af9b903a2902af5d783512f18703b5489266a858e2f43d7b92251683029d2e08f99f2eed7d172f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a26baae206d7a96c508378792fce2b5092e93cf091d056cdff7615efa8dfe78479603460815173876166182beddc610000000000000000000000000000000018420f5c583ee7df775c33a5633c5ee166649dd0ea3a47bec20155df7526a1a8896d135c7f25c09350c25e0a8d3539b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b6864da0f142384f1dbc0fdec037258911bc60ef38e3236bc9ded27c26d81ac6cd6318d1740815262f9abd84ae13740000000000000000000000000000000013bb2161e04338d7f62ca1135a7a449152f595ac20eeb5eeb2ab5c8bfa1e978ea762272b10252db3b9b9537088ae9b041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000313d3e5752444afdc4f85d55b0045848d5e5dd06f20f2ed722b9f31b26a0b671e15c0954307c88a9150ff56839b5ae0000000000000000000000000000000006b9bf6d6c3b961ec2f089db75404272dc47f4d58aba2e3ea99a0500819a22fe062749ac8eacdd1f551cc27ea5c32df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d63e7b99854c7518c607ca8979f7f3bdd65a2d29ba7559425a0e89b9541b5b120aac109314c4730fe2c4dd0a7cc76b0000000000000000000000000000000002d990913bea08b6c18a91aac227cdaf3b226eab83f32fcd344a7d78dc28618b02062c982a3f5cc9d91516465a4029541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001507f2acc08671cbf3ff04a73e5058b8fb4ac88115835adc57c2940a5d5f74e18c8081ca2973da6cbccd0fbaad0a39720000000000000000000000000000000013168837b1c77236150f8d210ab94ce331b199dd53de7e42cb55fb7615b4255dd626efb8b6b028dedbc987beda252c361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147067371c214b98b6c0baea2234205be8dc11d148689e7807a07def24e2ad0d81a761354834ae526f4ec3e354ff46040000000000000000000000000000000010628ef5d71baf6b7c220ac605a567cad025c0a5fe13d1fe25530ac1b1b0a65d2ad57b5746c8f799473183c2294e027f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed037e4cceb9efcea31537ddbd9d2be7ffb9059217d52a40a87b8eb26dac6f05e45fe9deccaf8d05b4b36a2a3874cd8000000000000000000000000000000000cc732bcdc9dc08fd6aeace39e623e0a9a503ad82d5b0d7ab5a78a34383f7edc5a585138bd278fe5465724b2445a87dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023d7c65c7cce5efc4453b6fefbe9d735782117b125f579a65b25dc429ebd9baed44be6d99cf8e2abe94557ac2e3993c00000000000000000000000000000000164354e3b077b0f9c14d6c7c7a84db94615e434b807011e2f215ad65aa85777b9b9892e7f2a3b8ce7e203ea665ce46251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1217e68baf9c77132fde06d3092fe9da378a40885deb0bafc5600cd11092f1978588119d668e14edbe8f0fbe83b599000000000000000000000000000000000948af0118880d8dae794692cb2b386dc3828564b31f1a2407af48fe4c197159dac5b7dea5568915599b716a06764d5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007772545d564c170890f853eb935f873b7de123edcbb07d2bb3b21dd2a59dc1e7a63574ad560ea5cf4bb529f939ba7fd00000000000000000000000000000000132ae7de1b7abfd605e9df2c8522e18ee342257c44a0f0437f8def12f41fab19eb45359f4deb669f2813a53c75997e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b108b091329878fa269e112edb919ca0e49e35f2a4ccf17cfa3b236d44edb34f38d2fce1cf0d5b164c926de74d48930000000000000000000000000000000001350c7d259f785468b05fc689bd515f98cd7c4c80df214276fc01152a617ce0a5e5e1947ed2b9c6f7cc0fe4b70db7c0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067797f0faec22dda3ded692a3122008d83d806f3e62e181322f35694a70915d7b9974b836f4961b257300f862a804a800000000000000000000000000000000134aa4f2dd4c0ee1f20d4c51e4d8a95cd241e9214b55d3dd22db840b603c8e03ea92771f0a6dd31973386e781bf9bf111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047a579690bf2cff3a32cd5df28a1222fd38e32217f96b29ea2cdc172581b6ca613db553aa685c68d253fc3c987164630000000000000000000000000000000007c3e58e4de4d4786f29709fed5b33f03d9a92d067bd62ea56aa0a18f184665b7c22140c225200864bd105f82c5e23ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186e195da6d8da3b4ba93bb115de35f83c59078ce2e0121d0316052b923b16b41b3517ddd1a039b03a5db1ad5e1f590e00000000000000000000000000000000047eb890f2919ac0f894718a1f55e11fb8dc1ca0f6065e71574b00a1c5520e91143354820b393543f97d4d0524bbc1ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7d07d2db3374ab1203ad9565248f9cdac1552b86c8ea325dd1532c31b21d19dba4d2437847ebe020fd72125e89016f000000000000000000000000000000000ab09e925d1b1895fd10a14a9ef322deab88f4ce9029e129fc278ef77c87be6646bb02cbf8609be21ac96a4e07309ae71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000996850ef0c1843cf24dad6363856cb70b81b5e974d62c64ecd3c6f3b3bb16fc8fa93a9193243a99f1e99a3c66fc4397000000000000000000000000000000000c9938109950f4e4011bcd5d3a57da43ba5aa1ca967ac2b3bb97eaa71e611a7ebc22db32e5a51b3c5c89bd73f8b990f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ecdb77dce577ab9b2a7e609b7e5c1dafff253ade5721cee1c6bdb04abb2fc184c67dad90fa088c7c8989cd7780fced0000000000000000000000000000000019ad26889948220d2d8d34c852c81dfbd3c71c8b9b77e8103d048f8fb8a104b5659c77befc0ec07ac2a26c200b09244c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000869a8f614c3ade83b0af764d7d2430f5d9bd01a3b84d0050d9b4e7d458b4517c5cef7e96b339ee749375bafecdbdce7000000000000000000000000000000001940807fe28050ff5c7e8b4eb0fd1a87afc1d40b7f881700c0f0e7e79547939ff643ea5d0045a68d4bc0b53063f7e1f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7cf2bbfd6c2073089616a75c59df78d38fdab556e46f6f083e6422f783c5de02b4ec1f4edb8bd6b4621b37b61c46a3000000000000000000000000000000000eca616275b579b77074a4437758ac72e273026518a5ed8f40504bee9acab4913e4db7dccae17931851501d1cb4529001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001135d2888790fa5f65ee520a76c03f019a35044c4d11f25a1af647230f47d0591d3fe21875aa18d993ef271d59f58ea400000000000000000000000000000000024e534d655868c137a700ae673d4d5e70e4de6813ffebaaf071547aaa97e215ac6d91b252dfa30895af12159ae7cc541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000731e1d5e13101864ef558ce08197a2967f837da91e1dc92bb55b0ef3054f2ac8f618006350a58bcd6bcd53ed5effd09000000000000000000000000000000000133a95b9eb4429e3ccf7f46acdee581e170df6dbb9de9dc0c4eb2bfcd297a11bb06b2fa158332e9ac82bcdec75057941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a16dbb611322215c8eb08bbf7dec61b584209ddb1739050bd18dfc1df35592df956ca3badfe09fac6110f56dd9535ff00000000000000000000000000000000116ee78b4223868a8959fb711d543d4a3a4a71de196cd1ed276ee58ee86f9f0582178c51075b8f56e243c707aee84a001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c100ec958757aaa9441ea5a3f715e5249c93d63e2bebfa5f7dd2622a0884ee6fe6d164fca7a2b80e8627477432e2a10000000000000000000000000000000001f07661572e57d3e17b528ab7afdb0c8318010bcb6e1fd19848de362e71ca448beb6d32ac8a1bdd2870df6d4f3353491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018205e3bbe3e92caa3972de12e92b86f11f1ebd46f51e318fb63bccf25767288b074b3e4c3f71fdccec386b7f2da0436000000000000000000000000000000000f8ebf3f886b2eb11707bf154a787a7423c368f7d2aa62f5950a8f80dd83ca96c8be8db82de8fc3ed1a65ba1e939efb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000285137a9709f40bab114f5efd2af714d10c5f7d7299c9966f18e5dbcea65b696a7c2b43810a4a8aa5d70a4784aa81e8000000000000000000000000000000000ac3ed78ed88fe0c1cb6905957d1ac95434cea03adc2f532dac16574b7d070c58535362edd50a0092842c59576c169601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001970ad0086a67e4fa67800be0837f64e4c45a2e292ae02208886b5955a30ddeba56fb5d4bf0f21dad884749fe3269c58000000000000000000000000000000000bf4c81f8692c50308705cff255c889198798d504bf4b5889b5fd98f63fefb5233c604dc8d8960435810598f0da667351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc2811da1fe524a25a154005dfa97a47c299ce9e1e2da4c93d4291d98928446e0ce5996a8244048964ccdcd9bdddc5900000000000000000000000000000000128cc484de090f0f921bea4889ac6e02565088e6ed12f4c36eafc6c57d2ab1166290bb3dcce726d95175d7fc2e5df48d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0f2d123755bb73c00639c70385dbc989df17586c35eb2bde85341ea6afdcfa17727e16979e5478604e99bf7657a35400000000000000000000000000000000018fc90c0579347ef3238182c74dce4c4c87f370bf97df4a91085141e6b8b3d71965c1cca523dde99a282e7c5dbcf6271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000054397ed4ea06f7d9cf5581f9488d3f96a477465e65b726f712f024757c1a7d3d297da93e56d6d21c8b600a623cfcd70000000000000000000000000000000018577aa55c945548496558e25b988465d7d9c92e97541234eca8787da4ad4d061978c27e9938585f373ac6ca39eeb5d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000620f809bff2858a302347e93055e9d41b53547d82495de4b9206bc7acfaba1397104a8a44711c5adc548738fd6075d10000000000000000000000000000000012aa46732b82804d324ba18c37772cc40b60640e07ea063ee2679c2456836d344efbb57bab86f434bee0b7432d9fe2f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190beb7d10b1460237cf097c823e14c0af827c385847cdf52ba44951e03ef82125b6e0841c1b07e10a3191b0e3841fd700000000000000000000000000000000111c682286a2146ae42b4b12a9ec2a7cfda346fc76d873310bdbca70a9645157eabd8fee7860b773e888b8d991fb94f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001201c17d111f7970ca13117b84e1b8128271847db6b361fa8e1c686d0aa29383a58828fb96ba8a553027edcdca3a899300000000000000000000000000000000157243b0ae6561fd2ee45cb8075e92ddc83430e2d9d643965c8db52341e3c3e8bb9db4fbef599a4f694a1690a1b8a6761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001209e385b8a9c8c7472cb9ab0c65a8248bfa0b69d574a22dfb1debe6ed61d6ba911d4602e8a2d80b78860aca5214ec7a000000000000000000000000000000000fc610f79469f54517b5f03327ba6c04f6dc44fabc3b65f5459b62899474004547a2bf22856cb14b606187460cf542d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c0c5278b1f95283722bfa78b14d30b7b81b3e3c3b5ae6fb512fe5eb4072c0f28558b84e2dda700328a2630b23657460000000000000000000000000000000016c6cb3012ae7f8537d02690ccc92730854c5bce7c1e7189bb285430537908e1489473c1e6f5baa99bcdc8f9a16fe5c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017948edd4f8bf62cfd7a7d8d129a85f26d1dca54ff5780f6df9abf0968d82dedc23e570aeef749624a4fb28b2e5b8ffa0000000000000000000000000000000014117623e92c4a0311ef365a38f19896525a939fff48703a3baa13e241f3a595faa267dfaff29af0456f16540859bcd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000625a3ac1862a0196ab6fc140e1a61eebeaa073c8580e78ae14079924579171c711a5375d9f8f1765116d5c25807ef62000000000000000000000000000000000a86a33a35c81e2f799c1b47438a1e03a72d099c5dea53389c6c4f33eecf02bf5f6a944f0b1d6e28fd315dee9eca08f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185188627407c10e12ccbd1d6ae90e64260a424e26969c07dc22e6272d96a437cf27ec989909e69309eaf5d7649ef0f5000000000000000000000000000000000dfdc31a362aca57db0e07596b19a3745312a2bd1290af819500669658334b7dee36d0697ffd515add2d81b091e8b0401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001182cffc34b0605dc65f43966b0c0cdcd79e657b458c0efc4b1857b5e3699301e52241a43f53cf794d5a3b6d87b131ca0000000000000000000000000000000019088f3bbcfa5c28db3cec94b87b7c915339d8ef65517c5ce12e4e9a7950f60088b67705fe2e6911fc335bcc6c971bcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000106d215df1c66952866154079ea0b71d4ed47b0598b3991c322933d146ec051ee75ac4546ad95f52ba28cd23bac32c5000000000000000000000000000000000da4c23d36f248b6f10a58d20ac790a5bf26de745e57bf8a23210ddc70dc6521a450a2926b7da43f2f52fdc8e96d89ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142fce7069d5ef6851f4d6ff5d9c1e010e40965b5ff8951610c128118787e475aad0337255da25649a028f36ccba1d5700000000000000000000000000000000035b1116c0b9f0b68a1374ddbafd2f883ea9a01ea54a8a71873bd638e4669994b0adb3f498e1832995124fb88e932de01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3443d78d116a75b83cd6340f143b31fa316da5b5269c679d2cd11f6333a87aa3023ccb38ae3270d2ff0052f5032de0000000000000000000000000000000001786786d48f514cd6a2f49342f4eb1360903c8a20792c19b2861a49c9704814900acb668842a4a4d087034a8e151c7c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050b55c82609c0f1a90847fe66b2896606956ae641a4ed85fd15489f25f7a3dab66de41b9f58b9612e7d43e09c045fbf00000000000000000000000000000000019c79fa38536fcef4784d83b06dd9cf42dbad0ae1988558b9038c8d522101a51bb1f8b0cec97b025a6cefc29f8b65371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001612cf45ce354e907c06282d34b5b24845f255ca139c0ae77eedc317552665a1136a265e4043249b59a940b5c008728b0000000000000000000000000000000001dfc7b5586c7aa4f96db1bb5dfedf2b6eeee61f108ecfc5f0d490b00ae9d630c9b25c6d90711b17e30799da560320381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a828434635295ac6175aa01b1fae2b240a395712dd13c53260e6654d789dc1afae4ffeaa3ad26fd6f5213eec087789000000000000000000000000000000000e9dac8081d53e08f31e313a88ad7e4865854ec31f18f5b7bddb6aa6a5418f37815c1c3afceb95fd008d0567eadfbc681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017da4b4b2a1e010ae158c8df7d5c18d210b1949aff15c562b88a0cc46190ebeaa6f85a5c58432c15fdb8da44d40f41520000000000000000000000000000000019c7ecbf1d4795a55455a11f733712136e919d43540d44a982f6138dbb0d70b0a0b3e995d9701a54999ffd83200833451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000326587976be62f9b310eecaacebadd37c14fef7f95b2377839c5afb9a8f021cc73cd5c37bd8f2d629533ec927627d20000000000000000000000000000000000fc5df4321e26b1be94383a3c54cf0a41869742f25f04944ee92b0748605340156eb762c8da40dcdbd4e55e09975cc0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012442cb20a69c228bdd002b9159abd341728f38fbb8261e9fd17c2b23a46a986fa223d868447d00a8cfb4deb51b2ff00000000000000000000000000000000019c62ee4dba3cfdbbfd73e85cdf9f2f024715f971a46944b38c94a489f4e373eaae86b9b0167d0d0dd9368dd7f4de7ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073421749ab16e2e8e6225bb1827d67e10ed3d075c36d0e017de6c557c1c6357f9981b17ea73d75284f32932536914c000000000000000000000000000000000177a176dde7e983381157d2a263f55334c483bd8c82be074094113bdfa693750e873b2abcf51d70ad4f33ef3ac10f7321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afd15e3552ab70088110fa92904851d0c36db558a3d65d16512f7bbc9b8c3c9bf0e71e3ca4485d22a85d2c109b470370000000000000000000000000000000015d1c16181beabbdbeb0e472474a898e2933004a5dc40fdba76e663322806cd4a0f46d3a5abcd06c8b940b815d348c3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131e1b144ffe856ffa047c130128c91bf27a3c59c7061f52d2a08842ad017bde74d62671d65d8be7a3c8bf0a451c39a00000000000000000000000000000000002b7f14f2aa6e30b88bad39feae7154f9281cba2353aaf37e5e2c3de3d328aa45d2c232c5759a04224e1a07994553a151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea693aebae4f5e02229a089f0957f1cc0bb9db7fb5e8487e38ea229e60cf55855d09cb979f91aebb0b813144f69a01000000000000000000000000000000001258a1de6cf07585dd6cfa88d87589a8fd0c055947d93d968af516107b724966fb3bc5c47675d41ddcffb300331be4f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010604d4fd199b8308a8c9e5b0a62c25bf6cd7275d9182fa6d781c7ba68bff1140d97ae4c61aa29c8556fcc739f7504f000000000000000000000000000000000682de3a5a795af0a130d106345ae8e9d8a5ba2523fff38ad5c941117429786ed1f0e562b1628c70036ed56b91a8c72a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bb368a1ef9eb8946f19372659a571250784879aee50de4efe2e43c148e8c4ac84b23d2cd5626b54acf1cb0b6deff1d000000000000000000000000000000000efb4f97ac9011faf83afda4be67bcfd926c7575ea43654645a90ceb79c6c8d21d189bd46fd979869512de7517ef60221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001310cb34fd5e8055aab5bde3aa5d8b69f71d52f31c1f8b66a167506a14eaa2faadb74604bada4e6724e7c197c27f45ff0000000000000000000000000000000002dd62a444bb0a0c76f80c735a4723317fcfe881a900ef74519f397d9d0789beb6fba90666bc5f3805edbcbb8af9cbaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd526bbc54f5bd7e7fff15d902b69c10a8e046e111837d907369ad3e95e811a99552701d0731e2ebdc832ae810707c5000000000000000000000000000000000cb023201b78c82104bbcd0d498d2d297378c36779c8976263d3350f5a1c3250bf5adf8be2ea04ba3a5a6baa7efb67ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000515512de97ef30b9ab9621813ea3cb8ed3157731ef6d9929112bf46cedf8941a83235216e101e74ee227bbb0d90593000000000000000000000000000000000165bb45cce8bd2eae73e764c7b19f19de04ad9ce763a332db6be8a2b56194d673f9048602e6236795748666f46bbe3651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010dc069d80b23610db1615396c173d0750307d0288581d997f8ccb2cf63f235d638e564018a901179a301696d9b54e4b00000000000000000000000000000000098f8098dd74039cf3ecd35cb7744a88618b0a0aede9a5e4ab78e5ab14639562cd85dff4618b4337e2937c0a4680a6bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7ae9d8a83656c38bc0eb6541f19b00a9f29f9ce5302555cfacfe96dc3b3e402453e99f23148c0d98c95b54f070d074000000000000000000000000000000000dc7be7595475c0db9ae12970b3908159a8872ca5fe1cacee0383198b9f9d40f18223c60867bb15aed46dfb916669bcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059520c4c23093bff92633d8fd3ac3835f3704b661d848a4978220ea3b3128598edccca35cd20f3da6a3522be82ab62b000000000000000000000000000000000904d8cc09be578feac5d9002ad0bd6612b1a83eb3cc71789b90cf42272bf9b1a6b4f365d7b06166affd0b101c5bb6571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000518b7882d2e8f9b3772abb215f2ff11f4beab7752e41a44d5e63b18acc77d095607d7f4607055c030935f2a862ac10000000000000000000000000000000019a1ab8ba196d1de6f7ffa5dad09d7a276b492694754e050337f5857618639a5463f810a74425473ae40bf6d3a97a4801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ec66bc157c486d766b44558ed391444a323e86ae996d7ef1c7f07582e30f2b0b14549b8f27e27ffb1e82b09b1308d1000000000000000000000000000000000c1d81179e0a15b19e03ea2d8756bd088b98846657b7cb6d6dc364bdcd28e0c79bf8368ade430ba5e83365b37b030c841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dd6a21feb39438a54b5f1ba21126a761da7756b061326201d92f9ec9673f2bd698ab9f51cafb3ff83293fe340ed57b0000000000000000000000000000000009b400345b879beb2bbc9ce5b78b92699d5f7fad9382988511aedab5343b2492ebf374025490d660be0f0055c57eab7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cc4bf9a40dc806a8a1f324a812432f555d255ded0055a2796e3963e3e8e6ddfaa6250e6a56e829a1dd0ed35dfa8c33000000000000000000000000000000000a5b60f1733ac2fb02ce534bac7234ffcf54849af139ee16f808b838470cbb966237a56ab6d1a3355903f65df3f1f9801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138e280d4e7eaa30dd2b366c3ac26839cb71bdc64374d3cc8bf1ca693e8ed0755762db881da4ca36a28cc21696190d3c000000000000000000000000000000000088658acc052224756de51f5d41e12b764d767797f3647f0f8b00e54ef9479c1fd898534fe933fe571d2427dbb1e85e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e28de35850759362fffe018625872ed58a1eaf4ae434926065344289c35509e3fbdab6830d9d545dcdd9682fa934a130000000000000000000000000000000005454144a0557445a8f924795abb123b765d6ee824c6a7e4f3922b385d02efbb3e8b524e86c8b7310772366bdbcb238b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6f6881e6e2533c4997702e5a73aa29bc12eaee130b53d90cb492e075baebd119861a794765e4f18ac68b670ccc37160000000000000000000000000000000005cea9b2d319b01ed4f73ab2da998447b46762a36d3d8c182695714ba5ae4d4136d259dc3c3e55217d3d5363421e189a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f432fae63fb74ca33b30ab4ff62184d586f931c8fa5a2aa223787af7cb2eb956fb305a947a18625c9056682fb1504600000000000000000000000000000000166038ce66fa6eb68296ec474055004fd8fb87023726095a0cbb20d38855f8bfc29f878526dcb3dc88e334f2eec85c5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048c0ddc42bfc8d17303254682b7465037c11f37e34ad5143a62598a8aa8008a2314f59ec7e30656db6d1e013069ca820000000000000000000000000000000012da64ab3bc4e3d7adf0e0b6000333259ec23c33416057695e3a82e34d5c4bee399f3101aad9034881b050258263d2781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c02398513f62ad752163dbc34edfa64b3b5cb4bbf5961693c7b7d3fdb0bfe914030c0673397a52f5a1ecf6f9b3f4f00000000000000000000000000000000177ae0e79802ec895c52c408bae671e01c2570a968eaed26f625b75fa9c98c4aa16fb33922fa621a5ce1f89ea9a9d8ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018522ee067b8c624b5dab45b3e76f577dcbc8e3b58491c87aa267c957355747e10ec1240c1b1895d9129767ac7df73c90000000000000000000000000000000007e481f44a18a8aa0573aeb64ce06a5da8112059c4448e312c19bb9867da5e1b9d581f4dcb0272f0701b4b8274d1ed971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3845b662736c0ebdd261900cab0446da8067fcbf7a3e126e074da03c07d6a277fb82b65c54844e4fecce98f448d03c0000000000000000000000000000000015c978d1d4e164073986716f98f2b363841ae6f02abb51221d6ac9d632bc1e6ada434ea272f66de1949485dabb8e9bab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001999a398ac3d05939b46130a21c4370905c357cac3720f9ca83177c45319a79dd7af17ecb45f2e0ec82ccb3c3c8efd8b00000000000000000000000000000000161696716453d7a6818bd38e1a2a56ceacdadd5004763423bb254067331acd2c84438091fa9d41213f3942f5499265181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101d2761b573dc0950dc9cdbefe88719c084614a98226660411ec9ff2dd9c2b812a829f7552f2f533e46ca0ae94e348300000000000000000000000000000000009bdb1bce7e09d70dc47ee43adebeb7bec97300355a012058377c2b96708a05b7f86f055919b45f2a7df6d29dd6a9c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003d62cd2eaa9e2975a85489d9a89f61d35430290bd971b6e42f23ac590fa0a76e9704306191a8b3929dc05bd386c1380000000000000000000000000000000004bd4aff6e01df2a6f1cf6eeec2d5e64e7549816cd00715c19718109b2be5f0d313bd89916756c0ccf8b172c1110a18a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4901d2e46c6ac3c9e2f39464453a6c7daaba5360707a7b2e6179cb7d6d225fae18582fd37f2c47fd75fa6e14edaa7a000000000000000000000000000000000704fd1d8c0f2311f9c947497a217eb165956aa49ef8fa4d3073f1d29864723789c97baa5b7c3ac92a2c2771e0279ea41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e36258b9fffc7fa146f28fb68a01508da0ee1bbb378e5b9f41f0d7116fd7dcb5088f045eb7f47f74cec93b97e903be00000000000000000000000000000000174727af9d6ef2e5699c931652955dafee15e876948600178d63cdac64936161f525bb077e0be91d1f03e004a913467d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015779a8bb3d0fa11638c480a056e6981a001baa346be93e1d627fc083640e1a0d12c089a1d0107a1e412af20f3855b0f00000000000000000000000000000000155e67a7596b01dab2713c60f182387d407a50d03649165323b27a8b59b7301baf8323f9389fe0ae7a334dbda543a54e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017325ee580951c62a534b139f192f92e74f60d78f4789becc8875eb92de409a653fd0bb5d3ad5e2b9544e27f6e1eed6700000000000000000000000000000000069d03b4e569e6016f31c6a66597399760b48afcea915823769a6adceb83fc1b38b2b23fa63d5915d5930ec8c555398b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000badfce8bc55bc07f5179ffaf9a4d9a7d3665b894579cef8a00b6bc75c3afa7779c949f71f74dcff551f0d6b1932cbb3000000000000000000000000000000000b0975bd4e9da6a51c4a258a26102850ebb28cbee526583fdc31924da31effc7a882e39074acc612ba0e5ed16fa975df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018380995a9e08108fa4ccc420b5706d39fd482da48903006cf0ee45dc9cf281324631566c19c10d24ef65b07dff674a2000000000000000000000000000000000e3a4be63bc1e0576c8fc947370da4496e73ed39f87fd4b924e4746dc619d85753db0267a20497e6ee9cc08cc9cfa8c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008153b366c75e0e0ec84576263c008d034cd6e7ea70662fc5f5054a37761f65988953f8377acc5de8be88afdb18c237000000000000000000000000000000000adea330372e62f60541baf13cd66b3b1126774fc9788f9624e7b725839eaf0ebfcdc2923dd24a3d3b73a59e8123bf0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f054a6035cf267f8ab2394afebda11d1fa3c38a998306cbb6110466a77ec83a6df1690b93bad4e8f424a21404da5dc0000000000000000000000000000000009fc6eb95f5d23a2ffdd888357a46f3303f6b7b478ea56506dd4dbf08ffbdbcb87440420457ceadc79d6aba39cd6b2681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000345b2d8dd8f4e9a6675863a0091348a7e3d6ea4e741640b2f4fda41db1ce3b239257d5e0f3e7b20162269f10dd32ff2000000000000000000000000000000000e1bcc0ed478c19ffaec404ac08a5cc2ed281dbd3d786911a31b865d841bdfb2016e2a91c1f8ce12542ba0fdb2bbcfe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c2d8d69638792165f10eb43b3bca6f4b5803938e145ad2c883d5841dfafb399cb5660b9fb3304cd0c7835f232414f00000000000000000000000000000000014b83f9b9e6084fe73f92a1fd244fbb3d8bf1a90ff4848bda85eb765a4c64a2e10772129847fb41dca548899ad991d221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f641652228c5eb7eb2356bfaf53dbaa107ef15c27fdb92ab86f200a752bbcb30ee81424398dc59c0a7a3d5ae9d52a9e0000000000000000000000000000000019d5c91329ad9abe5fd7bf87cdbdc06aced85c6907dba0303a41ac6df49539b7ef2f30803e8f81e4a981049f121887c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004021b8c38841f20d012ea29bd5944d8765b8e9c83e52f4d0b970972dfa66482e5ab7b06f70fc983ab214ffd8d50cb2400000000000000000000000000000000041a0885fa7e234060995d727806b274b0b8f88294693c2da78fe7176ec558fca7ff6c15e42ff05b145f57342602e1371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf70a2f34d052efe881db309f225d9965cbf8618a7b143ccd68546739c50aad4d122bc2e05033089a4ac511fb27f08000000000000000000000000000000001820337d5f774f4041cb59c00b97e3c2a615c1eaa3358089ec0bbc69162679cb15daeca255f1de2f01e9964fac0cbb731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000611797ad7ef7d620806c4a48fb14a12fd910cd804d9ed063954548e21648185eeac5b32efe6b80a36a2385f6b7c09800000000000000000000000000000000002e81822460be0a390aba478e34d66526a9737cc201e85ea90c3ae3186fcfb3e42fbdb1be323b5819d337a97ffd20b261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002efbac97066058dd071f356c60bd176c2366493c27a708d4ffa9d021be7da9fb4063cf05e98f11f3faf36f39387f4dd00000000000000000000000000000000190417959030a3137de4af1fa28d401191d4b26343acd45b5359d82aff8e95acfb46b1c57bf3573bf1c5b21e49e659d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4c8ead75087f1ec889d543323e499673280b27d16c4528c707ca471376fa314a8b61d4ba71b260e8c27f86a8b76fac0000000000000000000000000000000007be34f41f4e434792c7b49775f5e2fc1da83602d99786a537ec6d1ba8799aa10fddbf707a9ebb65f579d129c15478f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8e6d9a0d1060e3ebb477765ca2e700927ee2c0ee21bb8b610e8d19adb1238b148c40557b639f4da35e4f886e3b8abe00000000000000000000000000000000195cf51b62e6a68685aa6660a3724302ebab9ed71408581d2022257b96b988bcc6458a515839ad300d91e3939c81b4001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003180ed4414802774c2564e8521b0d4280ca86515859cd628ce9ace55bc94aab11ad46298ff58b28896f2099ab4a360f00000000000000000000000000000000139374a224c957ab072918ae587f8b0a0935ea829ef0ef75901bb939618849e70b562890427e9cbaec119d1cc952cd081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c2fa308485b8567c1c76d2bf4e0ce87d714c51438b089afb553316f11916c5d5802dce99e456c8e79aa70412b90faf0000000000000000000000000000000009bdce6d811bbe8cbc8d89ee2a3472988b727908f7a6651284f3cd805d0bdf2a959d40b86fe18c49120fefafeff22d6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f8e7942c65d59040f07f4073fdd5b4fc9c8e7340179ed19d2927696f01aafa4e45884ada8efeab6fa59889df87329a000000000000000000000000000000001951ddd6f7a1f6d950e956015a7619a2d7662964053a09f98d2ca3539583f9fb5b4f0578c03ebcfc136274a77a9deda71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ba963531914ffe8b5af97ec4b5656b99d6124ede4328462a2d809459f3f9d2da5ed874152685137917598082ddd0e3000000000000000000000000000000000e98ab1eeeb2a528b88ce39e6e4a425549e3e29cc080874c383e1f8778015c23084ab04777d165d213045d54a4b434561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001535f3ff1366bdbd59e237ddc37e23a0c92f2974306e57a83fe97e42c368ea7f6fcb62b221eee2f154ca33ceb301e630000000000000000000000000000000009a4af87d2a599d2316d0c15793c0b75c013a94bb761f5608337d422eb588102d54298730496dce7b9c3276360bfd42e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f10b7c6e19d3c39324d07acddfdec4eb18a38e13b16a8cd8e3bce4fc4b204261c7d470a9941cc50a11c99d9d00623a0000000000000000000000000000000018db27fa37cfc87e069c35a5bad3f7991f64fc6dde2f49acc75787c8d639745fe802db24cf5f2aa0b196ee09ac1c9e601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b04fcde9d433bbec0873c436c914b968bb8dbc8403bab6753e6aa907ae7049973d5b88fb0ed306611ad968e69d310580000000000000000000000000000000007736d7f597f41c02025f2adfde4991d1fa7b65aafb7c8fa4e3a626b18b3270daa603e9a5079433bbb921bae8b1f15441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f7ca8cacce156fc6651d5f60f01427683ffbba9ae23a20171cc0e8429db2416725557a70ed3f91879c70fc1d5d64ce000000000000000000000000000000000f0fda13ce09ddf6fa1f808234cb07b0b1abe22bad611d372004c116ae66a70f1c67fde718cb9ef8fd9d13e00b140be21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f1700a75e9f2e0bb760a1ea941afe719b973bee31d62e8d74e8ebc2cffce6eb6dc2944bb8147694cb90b65fc5b6caa0000000000000000000000000000000017cdf01e6d54647f1b996b85223e0fa40c2771820e8c672adb514e0c8ca8889eb2e1315c2df13b730b6e7ab1ee209a561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087dd5d4c827323e1ca76fb04fbaed5e67dfa2d3e775cdc23c4092fc3f1f0bf6a4a25e419912cb1169445d723b4e15390000000000000000000000000000000013be5368018527fdc50236909eed1bf4de7ea4a73df85aed243bfe1e0964b2545e0d06c48e541c33bb882f7e06a016961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f281392806950bba3d5b03a94f0f0c4b575fd0cefebbd4618f69f8de5a972fae47cbf54cb6362f736bd28261dd4bc7000000000000000000000000000000000ea479191b4072b72a510f33a3bd6ceced2b834d74cf5513a9ddd90c6c28e0edb9c3e2aeb5a452743d562e9cb342e0ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010670940ad9e2571a6d0d3c9560b7bfef47da754a08038994126aa960daee03467596ed8950e25c2e67525be99d37840000000000000000000000000000000011ab6adbca985f0aa6cfcc6b5b248c1653d210bea583a53c125630c17c5692730810227c4a1746f43436da6dc9714b9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a3bd791a3b27bdac3d89c26ec02078650f6f2c1144d5ae03ef0a39071e4756ae9b4dfaa500bad7b659fa0f22e3382a000000000000000000000000000000001524fcab621e8e35c995bebac8b567b3d55a8d9fb766f8fb9ffe8de5b9a3082496748843d941435bbd97ff4e1b4fe4211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fa132c5142dc3db0bfdbc39cd64c03199859332e7ac16a1614c528e38342e83a1c0ee043011340e369fb5ddfff2a6c000000000000000000000000000000000af1ba67396f7ebadf48f7e754fad1afdaf2168dfae475b44b81914857d227f09dc398a57bbaa89e44ffbc3ae43642b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad8c9182af98ed81465959623ab3d76958c019f5ed8edb1dabb340069e2b8e8cefad89bcebbbec41d898647a8a93b3e0000000000000000000000000000000011ebcce1e38cc7e38e6aa8d59813aeddf0bea4fdc462f83c36ccdbb4f298f1e5482ac7d2e5b8b01e6ab94d377f03b41b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a217579190c9171d32e31d1a47e3acd77199dcef8d0c8cbefe28931776f4b5274b1fa9fe14c55623f6ecf19049131ec00000000000000000000000000000000026bc9aae5e03f066cbee582eca8177ad5c1b5dc08ed586484ee95c779d422e76d36fff68840e771673f850b296ad0481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fec057e7f9cf9ad7f00146eaf2004120b3b75c0e751174c583794281b9ac1fc72e80ac76d54a70eeb026ae878a19bd000000000000000000000000000000001137b13c750996aade79c835b706b9b8586203b9398bb87289d12c0356b0c4c2135b1ba78dfb615b105659f111529d411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c595a8e95355e5dfa3a466c2b80ab9190ab3528d6ba3df88b79a8d8b17cae134fcb91e206b3421d35947b9cb2077a90000000000000000000000000000000005fee1ed612d91c9c090c2fff6ed195fb7407e64261f88875744579f813b5a38b1a330cd13c6c8ba5528e88c2650ef541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139881e3a0d9ca040c723d14ea3f4d0fd70dd2a4b20f59f0e9f9bfce83c9698a07d2b39324b1a7863f8c83141f45e5590000000000000000000000000000000006783fa2a93cc1ab51aa4f04fcf6fe193056e38a79d6cce83f90438802d675e36ea5cc747a70d106f97238d9f16692c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9d380b62fca0260552e15424dbdf69fff7ecb5dd6b60d0c43b98ea259e139ae42616aa27b9ca646d86c3e743a494a7000000000000000000000000000000000b9310718c17c0988b30748db9282f5ffb5872ce6706aef0a04589a502708c265d273e8426681dd681eb2d56629cab441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144f23ff0705b93f52c464a3662dc523c424020f5111711f9ef967af0685d07dbb2dd1f73a0de9b0df8b97aa23424673000000000000000000000000000000000cedd13c97c1f09778ed37053958d1d3e74d658e2c457ffb8b29f35612a45de0adcf1d45f71a077da7b960e2826d3a411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d189242537ff37cc87821e25070c3f8e04a49919f87fedf0b07e7fab88ef25621648e7dc966b696e0d26e17f657efc00000000000000000000000000000000135ae27eb2df99af461f25814313871e771a5dc24206d291c2072553ef26a2f5c30ff24c2da915d6274d9de79d3f8c9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157c582e409c0aaecdd47dde6ce2ad3e5db199920ad5aa7ae7f39ee79fe100eb9e5a9f4d8db890ee4735fc53504d3de0000000000000000000000000000000000c2e26994bc2df5bf239fac763390aec6b25b6e578baba391f5eee8def1214b74e67829e6bf2e91ac41011af6ce85cb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000624eb17e5931eebea9040d23cc6724ff937deae5a4338657e7dee254396fe97a87ce7868889fcd9608f74c5dc11592b0000000000000000000000000000000019cf4769239b97d9cf207dc04ec188ed8dc4646f07b951618b4923a3ccc5b5bc7144b5006521ad4f894aa91f26b2aef51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f8bf08733700be4fc9abc12f556a50c5a8d00ffe64c8a5c74e033d8d51a1950fbd3f0923b2220a18fc154d065641bf0000000000000000000000000000000010099a564a7d8c7a72cb795d3bc3f4f369712959837ba6bce07be4b628a2e7ffa18ed1f67ce0f8a77f8a1c65b6134dbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a4330352eae8c7455dc20c027a93175e4c6dba136e8c5240d8aeab64c3c1cce1f1c6ed0a3ec693e7bf560140a4c0eb0000000000000000000000000000000016af7ff6613395ac5a731280c5b573eda997723dfd3896d81e8544db7d1c5612d9205e16873e41c0549a43180d33d5f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014f0eaa92c19d69d3c4a1fb0df8c2bf7c167c123cc6095d0cf1cffd5f320b6e50acabfadac734a3268ad2ea13c837c3000000000000000000000000000000001291d0750352c9cdbeb480cf2ddea723d3652521ed6cad5f7f07f200c2a2c07547aadceda6df57bfa295398c35f61dbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001726cdbc932ad48907a734162655f65d4008ea188a1f4fa13425c4d0d4170c7f6a14eb58230785fae19dfe8b990cbd35000000000000000000000000000000000b830160c2f525f5b06d41cdb4eb35279c05eeecbcc32759ac81d7e99fed9a24779f4565ed9b74f2b1b654bab78003df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e39f6bd87a6d7e2153ed393c46fab9ee3edfb2ef2af9634486b997e2a889371e2c321efc2bccc140d5094f2098637400000000000000000000000000000000186cd2327501b9bdc2ad858d7fb704b9ff1d1669f36b4bb9ec15fe93f82e62e3ff16ef9ac9eb6d3b85dbecd0af3899ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a32a2a46cac4adc4428d687fb8f34393e6d60a2fb91546eaf8b94b385111e5cfdb41bc18b7a599ded969e5c89fdd23000000000000000000000000000000000d633a889d21809639e633012daccb52f21a9af9f2f03f714608c58178b8ae719d00ace589421b4ee3621ac8203dbe911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001433317800d20159d380680be435b3aa264ba36cb2fff6088a007d82aa1414f642de62cd8f3b3d46bd9f26c1010faecb0000000000000000000000000000000005645dc25930c5f374f6bdc006cbd659936b98a157cc9078d8722dfe0348124a1712ad6c4577d162b74a83601b00f70f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e9c4532401ae40a0db678eb9b77d75aa12c8f495d4aeaab9d83c14041a40782e9d5383cdb4018c78650f0b372f117b000000000000000000000000000000001577e38c54ff2a74e1098b90d67c01f350061e30667c9fde423bbf1829cbdad836f64d0fe52906f2c16b6fc3137eac091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000195109a2e44aec39b9ebb7ae4121616fe58615999891d1db96831c43a466a565ee661f6d23392bd863efefd3c17d1fa00000000000000000000000000000000022462a51620e7be6c7b98c8805e7b128dc04789798ca4db66ab46eb7f064d23e00c4708748356d1d961aa2e217025981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194050fbaed1c80ee8f0ebacea0c1e2a33a16d6e3dc749c3dcc2aa0e1d383378aaab61591955455947fa5ef0d860de470000000000000000000000000000000012a1fb715621ecc89cd7008055c38c0390f07ade578bac59e33c22972a989f2d6477008ab8d562bd00c142d654915fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010564449dec5e396078dd15a04640789a243d7344a9e58b55f5039cfa4f61a5b82e95633cdd013797aa3ff61b61be4fb0000000000000000000000000000000001f6d8721e2eca71dfbf71f914d4f1a9ec288d18c346b0506edb13323dfadaecc2a233c994dd119509f1e9fc639d62451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cb81c2109cc05bf804b2a179193a821d5a161a8a2833057f1bb9d00e4f214bf12c4bd1910130b0051ed2aa983e2aca000000000000000000000000000000000c83707449afd6f66ee78a0e78c563b28b43cb35f88f582a8a07d43b93d4b5ed9872f5ae8b652bf99db3c5dd2d8a414e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145cab6789abe9fc85535d395f45f753fa25cc5adca12e8e4b4414873c01ff2ad5f676e752a4d8acb9bcd50ade0443600000000000000000000000000000000010689cf7250f4d83b639a6109bde9a59337bf0b0b5e5aa9f7a35db4cf3ab5d2d9b60648055bb2c68d773df495d7504d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112b819d8b0be43fe0a25f88fdb60cae2d4cb93d8da34a5f4f1d3ecb26683cb20acbb7e59256e2e16682f9377bd2ed00000000000000000000000000000000000d728fd71d9c0ab5a09fe6e34c87df560bb14cd969cf2e444af7ac36b56701eee6b6c29967ab7ac4bc04c7fd8cb921691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096f444dd3258960d127b8a02c7ac97609558b4ef890cdaf376a12a969dcdb47fb5d5bc6a620b4a90f496ccbc5e5b633000000000000000000000000000000001668c53a3937f6a7ef9ee15c3a7969370562f476a455213e98daedb1ade41f08f4a6a10a2877c3ca35d60023eddf19551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc586609f2739a211458021a98a9c24fc5cf8d61d07fa7b69a27a107c3f0fafecf2129ea3ed4f221c51c8be4812c221000000000000000000000000000000000b71c35db4b0ee1d3625e39d43e18fc89d2bab581b7cfdc858a213f82e5244cbe3d3a5cab8892a60cb5f9e512f0b95821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051eab14e80be0558677a908142170fd80f120e2deeaceba737211c93ce0a966a62b65a86286ccb95eecf52766d82b6b00000000000000000000000000000000024f41b32bc97700fddcbb8a84ea8b33e9940a47d3c92f663a346531081146decd893ae3adaabf2203aa914967cb02161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126c31b413f1f22d9d257eff96229180891ca895b6799c26bf5a2fac8e8f6273bafeebc6f5e2fc39ec65d3c19b94a2d7000000000000000000000000000000000df2ceff55acfb3a19cf74b7f054d86a12a66406db301aa5a01c2409a7ac5040f9b192ff4d123518f0d099bf10d123f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ebd4ae590a1909f648b5175cbde3cd630182aeb8d2115fa199e47ef73ef37f0d99f178c02d9af794456d2503b27cad00000000000000000000000000000000185fe66379021fbcdb6232893eb38193c60dc4973f3d2731074c560675ce296de56c982cc65f398c00303b2b61e344651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2135e833564c0db590061a5328ad1b8e8c249d59f7f43651ebda660e71215c7e62c045d4044abe373716e711256b900000000000000000000000000000000003065d86280800141ec7c314b331af8ed68d58dca2f3019900b8ee96ab95c1b0049946847d61c3c56ac2e3265cc945721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001827d2a3375cd7a6f2de543c74781ebb066f90c5c64ef46212fe73bf9cc00401905fd8562d01bf322508d4b2d168346d00000000000000000000000000000000147345bda34af73b6533cc30f09e81075ddd83a4835111e5e3335ead04f98ae646c8d55369e41d0951a9c535c9297e591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f0ca1b0437291776d3ceb19cc7c229565e1030a1d8d41a4dc8261fce6b335692196aead347de03a68c8cb092c4b2a3000000000000000000000000000000000d47180e173da6e6c7ad2c558db3fc098d8b4644a5152403e4a68bcbdb29f8cc7680459e072c7efa9677eda196bf9f971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175c3fae1cf782340c97e18d8c9762944d4d95a59ae06bdd17a3fae723e31c15ab448cec214776c27a935b5a905d821e0000000000000000000000000000000017455e4f4ca3ff1761b88b10810aae602ef9c2e6d570f31b200b1dfd870f18716a975c2691b05e6c54b075f5f03172491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018af2aa6cdacb5e80782aed917e6f81d8457f66ef1099ffa31792bdb2190a788fcc4163aaab16b42c9cddf9e2ee06aec0000000000000000000000000000000019c4f4d629336b75b333003fb2978f8dbb8c8c3acadaea80dc477908aad8b932d86ba2d3d8fdd52280da4856c5c480031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ec140b4300e5b181110e18a5824c653cfaa73755c45d92bad4b7efc9ca1361f8abd4cb3d980608043402887ab8868500000000000000000000000000000000009b99f980c4626c0d069a0b83901ef76f0015d3a3a1f530c94679b5a81b1f564d1fe19cf9375ea8962e2ab4c7e90f151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e6aa7df0b094cea000dcfd5e5ee264174732f091ac6513037d9a3778671cf90c12456b6596038b8954ab13724cb835000000000000000000000000000000000408a44b5660162806106e225b0cd8c48141f7e6aa3e266a2e2b9af554c510a94d15762faed6064b524d5c941a1ca5f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094cb5504889a15c0b5101c1377af4ee8d5e82da618d5b9bf39b8d1abe899d3bd7152e8aeaa6b615f0a0d846b6cd24e200000000000000000000000000000000002d714a7530e1634733945cc252a1fc56bcb6d7f06c713fbf75f0735e40e5ebb37d68b0453fa2495e273dbc095457141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009688819eb6525d20f23d2f839e2eb103f327dfcf9273e444a6ca90534cef1b7099f05c091bf7f4e32a846403bd645a0000000000000000000000000000000000462b0190238322bb647a2f88be7581ca008a4a699f1eccfb34c8cd0d160783a7ef133e09804fe52f1c6e93e9ee668141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137477a11e1bef1bb7890d5bb7507d697e751b13759ad5b957e4c57c72519f20c03cda148c35c4594e73bd8e7e64151300000000000000000000000000000000099ab0913531df0d5086c61c593e088c72c865c6e8fcb6af92aeec180f600f7036a56dcecfdd7a2f21f966684b5cfcad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090d1117476d93998f80a5c39690bb9c2fe9ad10f2853b842ce6f859c1b1927a002ec7fbeb229d0939457781331ac8890000000000000000000000000000000002edd39365a79b19f44f9310d857644a512508e63524b81f00c89dc64e212f818587c14cd05572271d6aff0fd7b0df141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c0f5356abc8aec544b220fb07a358da727d38ad3a641afde91f2e2d99b9ce67b3cd71c9542b597833033f3ab86224b0000000000000000000000000000000013be4bace02ddde85208f186d238eb2bc503988a95b572cc1e52c2f8b2910e7d53b25a2467c2c20d6f7ba926ef19d6c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032a291afda5c48bea9f0a2aa12be52ba21c05fd2e9560e4e0f8cf0e45bae7e50753a2418ebbedef094aaac19cf7bcdf0000000000000000000000000000000007cabef6ece211562b21b9f65460045e63d4bae5e6decfce9246cf5b87c3a6d41994539733892f900f6c9f743040e7181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c7569cc0b122409a0cec112e531e2f0ebb32f0ce625dd88919a22e97213a999325cfb24f0d65c9561267a5a8c36b3100000000000000000000000000000000040579873821d826ddbde8ee16111358ac8104c55eb9c15dce9a1505d72b64689a5864aab40d4d56deec3646130947161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109ae0514d4a9ffad25fd3d28c2121757befdf5b1b1529192b0efa496469f928747941a81a9f72adbb4573325c87d1cf000000000000000000000000000000000b663cca373e565dbb866fa6df50cf04f3b30070eff683fe9026c40d23b98ab1b50ce3766ff504c69db6d09e0902341a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003aaf42c999d4294ddb6c336121cefc16063dac4a20d8b054a7d0bd80e70a381b2dc3dfe4d7a51a99bcf0fdedc0a9a4d0000000000000000000000000000000017b2522acb1f3ddbfc2d4b843ee9840e4f0965c09e948c98d9e0f1e100703918a51b276392a6ac24bb3a1992337a48fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a5d563ec5d4bba5c4fe29cfa9543b63378b6d6f638ac78be92d48d3e9199c465c61ec971d9ccb25a36a90ebc90c4a70000000000000000000000000000000018595c3e1ac655a9898bdb08d70cff69b97474e87e8fd045117cc9534bbdc33b2e119e5f13078063b2a9f9b30589e76c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cf60c466de47dcfd9d6c4ad1b9a6c9c213d870afde146ce543492dc8e908740bce11486ffee295c308f85229d99d650000000000000000000000000000000010016176bc3897490bd66ca73472f3c4b1e49dcad510a5955a3146ae83be6b0e3df7617ac2e12468dfe92f4be0dda1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003059cb4966bafd78b8c5efd34df5b2a05da7cadcede24e4f3d80bec458e8947380c68ccc472079898ede894a8cd26650000000000000000000000000000000011f3d37aa82a4e6ec8e2b855a23ebb7e875d3aa1a71feb248406ee5bc149e23428096612a38783810e4c07512e3b64601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008400ca9f2e8d0d0138a830d95f5a0c62525ab4712fdeff210bed20385315997ea559801f36af6808c3ac20da2bbc2c700000000000000000000000000000000020858260c042ad5d4b23c7b6f85584bc2329247a24ab67dff8da3dc26acedbddcfd5576d4f72f4fbbb88ef391d979291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097d43409768185fa6267d5c65dcf3bc2a89282ef7de1f511029b5b974420afe3e5fd17333e186547074945f9e0ead6b00000000000000000000000000000000166162acf4a62cbf371628f50bdb5e185296899c6d16b3ec569c2850b9b9926e7a1a2a609ef7655baba24c313cadbc8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee749bf0eb482436b13e8a8bc539b30076bbf88019b2269035a1dcb87be0a6ded5c3017980ad14474886dbfa7d2172c000000000000000000000000000000000a7e4a0a6e8860c426b466667464444deb12e749b27383c3a411666b739dfb48fd357566a2276a19ba3a60c98e3ab62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab78c6af656fccd07bb0d68d95401e54d074bac7840ff670e17164fac756e105ee23456f562ba12922b8cf8bf4b771d0000000000000000000000000000000015ab2cfe8d5466f9b940df38ed0b72b0c887bd8929877573e2454cbe49bd5c97b68f438e6cf5d73e742db7f96e8b66c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d34840c59c38479509369988029795bae5832eaedf74a857c7817412178e62d274fc771eef772660570c7dae1bb0225000000000000000000000000000000001185fabc0b10261b2a7c20f545de14b2a97d4f8cf5b9c6eaafb34aa90f581d15efe741a469c26db176de167db13da4b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000876e3830f5219519e12cb4013e8a0dfb3d7dfd1001669a1833f77d86f4bd56cf95eefbc7cc7a89d65a36632ecf93daf0000000000000000000000000000000006c7409a101650c11a462dc7218a6ef768608ce6ab880246ae7b713de4513df8b099d1160d137a3a629db8cf19c9d6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d01195c1e1f42b7befb1c5fcc101c79c663f93b37bce1d62158b556b9df82d921cb4f9f1255008b19ab9669584c1a0000000000000000000000000000000014bf4620ced3201483938401fe3ae8553cc0377aab7cf71a43ac67f7f33b2b710ab3ba406a69779a9f81c77ba21de7961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e802ea37750c6412977649624b674676b04f2cd726c1a4340623a233901b84d9d0f1a699baac456cfd833b33ad0b1c0000000000000000000000000000000010559de22895014a68bf59d71279463a0445b8bed92d48008ee344c7689dcdb16d40e7e792e1d49044a4b2ec8ab3b4141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ff348de534a39f46929814c0ab81f1095df34bf5a49b04e4556c78f6fbf77ec206059a9663307ea829fac845e187f30000000000000000000000000000000010a243a68614f5947425ce153bce76bfc5e0b2662519747e7df742777de47f32a3fbfc1eead222990653bdfd170bb37a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019317e522bb35bfcb293db19dc83855c206c6a63c95c5654c6a7e98c1dc121c5a9e3a6b78494ebe9625f659cff2fab420000000000000000000000000000000002363f50389e3936101f7851cb471816ccae29e8ab1e4e10ef57327b636da83157e6138615051484e07d20bb0a9fc1bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e1a2ae82ee08c0e3bc40276288840b6b9ef7a654c98631bfc8e34a7d182c1a847dfcf5de00ffb3a6892349d097bbd1000000000000000000000000000000000f15ee34f15660cb6b2cb651897e5fcdb7209d809b6e1a221458465c184494ea6d78c47810b64029c9499fc23f192a3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018240558dba4aa381444cc92bbf2d2c06c6a2d3082f25033e8c0a756a9aa66eb3cb499355869c9bd767c764d7df06c3c000000000000000000000000000000000275dec20dbb317964011d230a75e900a260a8644b800f6cb7e0066f9514abd2d706e1de56546691cf00294ade614e7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dfcae20f28e376e1c4eaa71952fb94d2b0ecd6f567b526379aeadd5f163223070a9030980a295e51b1b865c6402c31000000000000000000000000000000000239592a1cd2a7378a7091b5bb63bae1625016ec0fa29e2caf53a1778fdc47928c270236e723b91480860d4eeb6fe3131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084838ec621dfe731a0f061b1d2bddfbe6f81ca3ae66fb70d22a1fb31d2f402be3bf62ff208dd089ad502ace1843e3eb000000000000000000000000000000000b88805c7b66eca1c078f34f72cf2d032e42294737754c13279145e41e99fdeafc57819fa07bd73dcadcc15cc93d68bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136511ebeee6b98fe1339db907cfd9662c33114d86915fdf94db4d960edf5cc18e1205ca794061042dfa053b343039820000000000000000000000000000000014c90b10ee3fca4fb6c07cf988012aa59ec98c4378b5fec1f5bb50343de8b273e386fbf078e4225a1d61e781ce4dd2381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173f426ed1c9385e13ba861b8b854a01a2dbe36c75c0d8253d2135a1b1125f589684e73dac9a02b9cf45ac9dd3738c08000000000000000000000000000000000ea6e876ea13c6ca1774a4053e6922b1c8548d424a5e18f2fc42c17fa86150aceeaa1f946a5f8179f060a69d397050991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001143e7823229436ddb657072cff30c71e6590dd1e3a8575bf904e97a7955eb88f875a51297ef5dec11357341284ee43900000000000000000000000000000000015ba2e543bb43dfe7ff84919f95b3ff6c3e611e290f656c6fb4c5ad365acd90f973db09228df8a814c946cd783a005e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e069c881af7adc50056fc8ad9ec7dba8e6a40fbda5d0cb14b81aee508214039e411ce001200980e6cbcc70618a6eac90000000000000000000000000000000011fcc15d75b22edd074e4601c1497561532454f2a277fac7eb032022466036e80d96529cf77bd0c93e589a78c5fa99611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f64652b93720016577981eeedcf7aa344c30f1c666829c78b88d520931947dae2528acc1146f27f8508df3b608437c90000000000000000000000000000000010361dc1ed38f01e57dd2bf481ff39013dcf5681971727e21901d9a9deb708d91380b7842bd397511ebfdc6f08450eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f785649e9cba7d11a8797afcccb917dd9af73bbd4de14c1c56334d20ebb2484a8673a63fafaa8771bab95d3c733e020000000000000000000000000000000004b74a1fbfe0ac3000d89fe32ad795f7ddcb0f64bac77612e4890304a37b158df94289a9f2487a9eb6c432bc14debc471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078dc54a8c2bc5f43e7688299338306881460d87a74219d0d14c566f1fd4b0530c7538fcc71e6ed378f0a7dfa5701e940000000000000000000000000000000004b27133d71475045df3cb72c05dd0207ed18d556cebcdb76f0d6bc25caba399c6eaaec787db7f699387137a46949f921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d3a6c791339ae44a86583e7b1fe19522df8cbe3a5e1c8efa0487c800f98b234e21c35909ce3696a8003c9e1caa4b1a00000000000000000000000000000000153c3333e0c28efcbfe700bac5f0a61bfed4fc6da73861ab8d1d85b925b9a606f112642a34e8278b38926d370d6d69151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a947a93e12c6230122e4d0e29bfc6f95f734dc93cd29426b0a5ca816a06b939d24e0b2939c552234684d50e7ae9a63f00000000000000000000000000000000129c6b59c2c1f61604335bf624db2bff14ad47476a55b50fe0aab9b34608971a11659d15a0516b78472bdd6ce5933c0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001556c7064f4f1ef3929db9ed8de036592d8a0841a70e1d834addd47c8e738cad97e6f1c70084c59066c71baf07a4ce2b000000000000000000000000000000000d0dce7977dc5c70f28a1905a18c6b1449b3d469f0679086cfbd59af33f647f0913cdd6cc190920c2d4ba91b8e6d85a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001807dd844caceb14669b190d2b67f355f38b86b5732030f2073d474f5a31fdfcd01f2ee382bb57aa7368e2293fbaa8e1000000000000000000000000000000000cac5f4045cb9de4b16117fa7b58d289e7220188ccf7ff7c0e931a78a220beadc472d866a42bca69af7c19c9dc0c0f3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2fdc2026239517e34a9b5bbc5d22314ab0f8e27e9c4ca06d3d80ea502074d78e1250b2df1334761e7d73aa528710a9000000000000000000000000000000000e3981abddce0782884ce3198ce96401e40dc5866e105fc0bcf4cecd287a6a538af681690d2ffbb5da4564130e747c301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fd67332f22eadd7f9a7fc4f0e208e744d7aa85947b79dda024a46e036d0ea28d91403218e3a433b80562362827d1d50000000000000000000000000000000003e30229abcdd4da055771f85263be533d679ace6fee311ebf566ecd8968643b6b89a5c0e1c9a809732e4480d63c0a931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dc799eb53ab9553c20c0cd7d73a446e67a002ccfe2c2f50aaf6a67949843b1ad308fcb75fa16fb508d446994259a3f00000000000000000000000000000000118397891d6cc849654ed21e0c3650fc86551147e52430f2f2802f140caf5f48e8785811c9841bb82fbfb22513a8591b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cd1283696323b7e8e3b6fe2e4ae95cc342cbe929bee0076be88a09184520b85e7df42f74ae010ed3622920df0952200000000000000000000000000000000008c23cdb0edfe93c235edd2e0a6352d40069d39f4754057435a00d8cbe67d5708d290e61bbdc61562a353e43b37e72de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba9eca902ba0c9d3350a51af447f68d996d1b1024299494090744ad2f07d8e08a1ed53a56437d65991b90c27c194199000000000000000000000000000000001841622d67b5a0dc6e21533c9e6eb179e6ed385b767e1b15fd809bc21bd26642fbd9ce1c21a311e0dcd5eef9c3dd163a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dd19d02752abfbfc2c46ce1d029f60d2d3d50360695ec82a82de64182331764eac178ae5ad443ae12a45d4b51dad8a00000000000000000000000000000000033a3c5a0aa7bd1326688236f42cc9a47355c133a204b2633d09ca2b8b48a8ae5cb4c6e71426bdc074218f0b7bd0d9d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001281b2d0bd52eb9b0aa9b425f1db10ff49496a0f3db23a34f8072370f9e82c21c4c6e51c1370a45f6c7aab38e509ff53000000000000000000000000000000000d0804e911b421a75dc1b9c768c8a0265580ee2990ac6648ea2e1f0cf49d7b2c304ba738920f9f71fd90463da3a019871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184978aa1ce37f0ee415fc763cd2c068bf7d20dc1e43f32556a929a231f93972bebae7ac58b8c91adbac0d6d7e0516690000000000000000000000000000000003c3309ccf812d2426eec92fadb52a7306d21a8eeed3034d9ab3e0342bc00e868621057dc954316ad13e2f9aa804eac91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d0772c1c9d18dfa53e5a5cbe84b4ba822a2110f6e827ea8ffbc1578fd200708a31cf515a9ddfbf4e9c4a361039430d000000000000000000000000000000000dcad6d3548e242e4cfbcd244dc888dacc6dc7b28ded4460c4a02838dfd75a7fe43606d700a2776b6671803f028738fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144c00bc8ecfa45eba043aee6059430269880c74709ee2f02cda5aaab8023d96d17394a9aeccdf58b036549418b76ba0000000000000000000000000000000000899ad82116a8a8ec8fd6b06eca4e9729a637e13daf94824857bc2207bf419e6f4d54b2836f2bad9e196127e2b01b7c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189e742127d6fafc8531a6dbd9d5dd052be4afd3cfe5517bd4b7abf13668e3ebea055f63afddbd0d512d3e7cf3b377020000000000000000000000000000000007c1c38fdd18bc6281aeed25a5b1fa5c37cc1abdbc1043d44bcfa5a01d1ce2abc3992b001ce547d4cbde74931b4574431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199bfd61ce873342bc5a692e0c5aa671f8277c8dea681dd26cfd52a614e91e31d1a3bcf407aff346323cf63fc739666f0000000000000000000000000000000014306818dada1206ff5b1ef24e3155c5ef386b2f8d3d2932947641b803b616d22b7a292955990716fc26813df188eea21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ae67150a359b7f1497360ba26902fa1cf68058dd891fb1d0ad875ca5e2231fad50bec298389e69b8e1098afdfb1cc200000000000000000000000000000000120c519c65e96a0e377229c54f0e0d0c86ce059692f19f55738b392bbba65f3cc843ec64ca493cfec990f4f59de52f501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c87f722fd4c2d0b54e30036ada7f4b8c67e7164899ffb83724c347a1faef10b3bb8fc32b7284983a3c36cf277eff48e000000000000000000000000000000001158e938c58c74cff146ae9fdf23c29a9a1fbbc07dfdf22d370a0cd77dc5cee586de90e386e5eb16badbe739286eb7b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186a2890d0a9201d91aac640f4f06d8f3eaa51852270f64f08c678bedf6f747243a6079de046361f4e7a4b3166866ea600000000000000000000000000000000041ba7533f67c3c58cbd1e5c59fb9d08a805985d8cd81fd6764dcfd3cb782570ab9133a6950d32e2b4c593304f04de811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e69bf2c806d40bfb07c4ed68a80adc844a1bdcb208150409537ce786109c89e16fd2cf4d06bc3a10960d050ffafdf6000000000000000000000000000000000e9722e0962ffe223ccca06764d0f40892e7de7079113f795039a2b6a0e12b873f08aca4aa43a8301b9189e10e2dd5f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004586444308c3271227817bd7e34188db5d5f42f13f87ad2c734aeb064f84f9be2edd32bd107b1692e33fb4c325a765b00000000000000000000000000000000151eba68cf5134bd9e745c44af0c03685cfb42825ef1ad7b2147613c9db391b06ccb3efbf314fb6a792d4f47c80f4c771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b6d0cd240d296f39729881320f940dc02d84bd002f934f903ef24f5250fe7994a489be6fc46a2c4204a39a0b91fcc50000000000000000000000000000000011aaa09b480f80fdc825dfdde935efac6ddabd85cff016ce61c23f2f9bb9e8b63ffcfd81a4fadcd68ce7e315af45d4681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002eea660e91dea9a7f659edbb409b63eae7f421ead0aa5375c91fdb83c0a0fb5f80bc35bde5b985bced69f8b9f76832400000000000000000000000000000000120cc31816b340702ca26371b54296cbad56587a767dc8be15496acc20872301c94dc808840fa3bf4295745d5a830fbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aea40b8da6b8a412ecbff0c9eac6cfed70da1f2f17dd3eef163f8c380aeb8519fe2f862e689ec3dbd42147fb61fd4ce00000000000000000000000000000000010cd22695c4d0f9ed49f35d80b875dac008b4c45bcd793f408e92106c060031328e9db25178a8d4dfb8adf7246380b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016694153e799c192cc8837430ce7292b85532264bcf66024d6d7532731de3e73d1fbce5277dd11095f64aa2b9d97791300000000000000000000000000000000050c8019c9ee4c8034457354d109626ed7f629bbbe6425d588b3916c8e851d03dc88040f05057e7c7512299e66c3fa9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194baf079adcd08d95456aa5a6585be7001cfe1fc9b1734568db9bbefd2a938883546f5f2e7920c93455755842f878bb000000000000000000000000000000000b2674771556984065cbbc238823a53a2768fe59dd733d5a82c32bf9303fdbc333f7624b425c12c36f3fc32ef2b8305d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af9d77b68e0c570a1fd928d79ec8f0cdb99d0fb34e4dacff1e26ebc59f9e701d189619c02984ffd8449c18facef4544000000000000000000000000000000000387f1c4431e6feb8ef397106b6ed189a141bd151b42e235de7a328c1a52713ece701ab3fc3ec85414241e09d61764081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6af89655756d3ecb46231f49e5f806f30ad97e96ede4c7dcb781c82a55f8978612d215d0afdd7ac50202e3f493b9f10000000000000000000000000000000007750d2d54f51f23c2c88b37c803dbea64a9185661e5eb7fd4e59a27eab92ea4fc1d29bb6728ca7ec5bad0a2d18c3ea91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b23c66227f52dd54adfecc39c56650ca08c55117a17e22dc9329287c28488f2a9b9331c5ccfa9e33cc63f8ec93a1fbb0000000000000000000000000000000007f58cd6d476e97d3cc012a814b34155bbe0f8989ce1329891b420865115614984178e11c5e767f6febaee0123fed1ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8db4f6ddf7cbbf4864eb42f849e4ccd3500c85bf5315387a140ba8739429d96d4a23fb87e22421d04766462efeba4a000000000000000000000000000000000dc66f926177fbbe81a0ca85239df9e760dd3d9cfc736c3af724bdae76e7f74f6f22e042bc275bcb5771e2702ce25baf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001765beefd04e0e855d9b91532d0d5fc439b90fdb8d1a5fd649297ce52352ae5c93941c669f14a29558e6559ceaef04c00000000000000000000000000000000110fbd6e021799309bed6fb47ebf0ae84a4a73c564dcfa5ffac03b69d4d3c17799f6784d8a9a0044b401f233f6546cd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041844a3cae4d12a8f5b7654f5b7f2a6e44c8f02ea150b864b2ca5deaf20f09e2745d2ae22a664b53b3234c3ed46753b0000000000000000000000000000000019d3b9ff4854b4b821ce97d32d0956ef4728394eff713248b3dc97189a8195357657eccea55b4b2d83365eadcdcf4b6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a256303b307e97bf2b38bfd80b9b8fd309b8e7079c416aa4c811b0923aea5a6a658768ed006e6a5c1f811da2c697eec000000000000000000000000000000000af45f33fbd3a4958773bec545ac3f1c9f2c4ad527c5e21850055a881493128b0598dc2eaf9be7e4984c1d946117fa031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000196cf8732372f1c02b351ea5b4bb7eb8f0e6409ec2b1847b2892d111da1d35cc8402831313ec4315f68c293b2c7e1280000000000000000000000000000000019bc46d5e30ba4151fa71a564f58aaaa23be46a334aaeb0340b8d11f3226d45ce133053377a64a3a71cd0d37ace67e4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001290f521b45a92a46171e917101f79cac23330a89fafcb04ea83a0382be810b01f28ddd578a901dc04e7ca009fade2bc0000000000000000000000000000000006303b87c41c771dba9620e0d535b05187d495018fbd84245bd199ee2cd990297d58339d94a01f0047a4a2db26f498151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000118030299eef298ea8a721a41dd0bb31be0f86742144c05d7fe632b6c35e9f0c2ccb7b7fd87cac1e5882d43d465c609000000000000000000000000000000000269052c4d2afb14bbbc3394d2f1b49e2a68ba0dd6dc08bc0328468ac77cb601af1719d412b706ee2c0c2aa425592ef71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e98a6d533a0472e5c15b3e00358ff53388dd1db0dda0b40b2fe210d88cebb2b620093b577f526f3da72314b695f267500000000000000000000000000000000074fedd522430e7db49d6645bba93e374fa45f2fdfea593263c30b009cbcafdff30e8f2c758f85c324f97c9ff0b198b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eccce5aa7eb494ed80550a8c7f2adda1117a33e48d2df367e0190efc3c75372b15d035ad4e21803bfffaa8af22be1200000000000000000000000000000000177d153c6a1920ef73dd3ca6c9794a384e9e52b2c1591afb7d19cf08ede33f82cee31d94c51ff3390c3c0db36284b0261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001400dd903191c1508f2c4bef8243744b53ba9735ab327e585dff03f789faf15355a8b3f453ad65b78942755ca7a16b4c000000000000000000000000000000000b5995cf77455ffe5825290c0c26be1c7ffcdbfac32e528541323d3c7daaac8f0e40c6144e34d4bde7ff8fa22ee01ea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da474302a6d882c818edd65816364e9f4e6cebbaf7b3d8ea287fa32e89ca363c0193260ace23f89f51cf8831365593f0000000000000000000000000000000014d2b16f2a16e6dc4f613b6bf68a0d1b1b4482157e80eb4b7b9bab7590374e8d392690cce70b582c4fdefe117dbc86361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b06a05803d4eef9d67215351a841a3f1bb0876f4e4e7aac23693cb77e01254e6b09e220cc955ef5824ac7a89165306400000000000000000000000000000000098cc84e0c4445d5f37ca5f6073fea188824e98e986c13cee6afb997536274e2dc392d1c00ef93705c4a6ba70df664471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d8af6334edf7d9de9e2a3990ad75a77b3bb84973188b26f39526e97e4b8073690a0f3ecb5dfeafcefcee1643b0e5a60000000000000000000000000000000007992793af8836a975ddbc7f548802aa312b64f458d65a2f7f52e8794e7023183a57164f17179afd7df20d8231e245c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000449443b8d5576abcae6c6fc5450622f4d6a29f573e887b220e6bf240afa56fcd0a52fdb6e9d4f908629f254b99cc7ab000000000000000000000000000000000cb871bd95a10a4e6ca1a7b1ce2c7e750fbb6329237013a17ed82e16212d5152ccbaf3ca3412de407422a96215387af21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a8775dacd21fe96cd3c93385d74b304851e30fe7fe96e1f323b223996985136c96430fa1d0abd10a3ccb60597cb4cc000000000000000000000000000000000dabc1460ce2b684808a27d468d9561f4f997ca6678b3083fbfda14fc83d2984a5d08764ccbe6732b9dbf6860c28b3a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ead00552017bc66e508e8fc3ed83ce277c18f1d3f2dc6e410f5b0473dd4ac4627b5a9ed5b5dc2586babc3aebd67137000000000000000000000000000000001681df95caf06090ef1d2a7ad0663176103a988cb7b42d35da7e7603dfcdb2ccba733063b8b88367c58b2e0fd1c569e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dfcbde75729e236db9c1c86d583236606c6cd64019ba89bbb1e6f9ff464f5e861e23224a0da930cb15a28de0b5a61c0000000000000000000000000000000019207825799c31e93faa9e7d2a149ff933dac099a746e60b6b425949d97ffed36dd41387fb7d1d281fe00ccee0c14caf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039edacf9be55a33c96ad2646a8dc48c769fb536db44b25864a288f207ab0c6fa28125d3ff23ee8215949368dc57b12c0000000000000000000000000000000011041a5adbe46ff76381b9811c0e0721d2858ba916bd79a0498c2448dae440c6d0a4e0de7fc98d9601ea8d68fd4ddcd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e42da0ec8cdc17b759b568508b7135e56b6b4c08c3ce7cbe6db721f6412445c62d0e6afc207fa67051c37e1d06e76140000000000000000000000000000000018cc22c0dd2767cd0ea2c4c7eff51745b0fb7d1de3a13e249190c8d88f85325bdd2a3a0f39af6a3ee354b150287ec6bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b842ba47c7f95cbab9308f121170bccedec09cb2432e2813b4c1ec2a74475e1b3563e60675f2e69088f9fd56855cd7900000000000000000000000000000000195b456ac66c17321eacd7effb38cfb2b3dc3bf02dc46fa0804e2c82e3a4c2d8c42ffe1fd7c929010947a12d0876deb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad61409fc3430c81164ffa466330a75448a3efe4dfeb1e0986a91e8e79333eeab43a14bbb04d8c0d198a55bb054cad40000000000000000000000000000000001cd36e9b60e078478a9fc424ba94c12bb18a611b34db2fffd66d0e670fca127e67939ea71f274aeb33bbcac8d44087e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef61b14a7ba4e88dad298de167a3677a0d971883c0c5f3b615e3de7b0c2be686907cffa25878915e08ce7bda7fb175f0000000000000000000000000000000004460e7809f5de78761dff0665c5b143ad4e45be66cd129ce61d95fcaae27b5517de75c3e54a5b9d5c2b0d11059ec9481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067fffbdd8fa56c4eea545811bc7ff61f443b384966abcaa955318f94b4290421e4f48b6309c6e36f7bc0ed2ece304b90000000000000000000000000000000002d67b8ae3bdf68412073c5e76020204600c346d658407b6ade017273cd0083e3b13a80bf1b0224a2fab2d52478a98521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bed948721c0ea417d32d7dd7948f4b551ba8b3274c0253d5b0f359155028caaa1aa4261c778519eb6c3e0976c0d7d2a0000000000000000000000000000000010996eac90fb2c6658bd7924b56dbb1894d09f287d9993294d2d93d60eae85f7bd3c7bb20adb87db0b0b6b280d10d0c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2ffaf84b09ca8659844f52ceb1f8dfe2fe45c002103c2b61716d0cb57adf2bca0c292602d5846f5ca2327e2444bbc20000000000000000000000000000000010c95596a9d89d84984a9d0a71bb0178bb5766d88430e85c8e963bdf455de4d518dec9101ccfa81d49f3fb55280db36e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000613b1afdc72547e9cc86292e211d30c3307be713a7f9ee701d99bbefc0a1afa55e1c2cf5929438727cbd7aada8dc1f800000000000000000000000000000000141e58e47d82c1950d2638c766c98fb0c982ff562cd15ee4e0ed8c409b7d985d86c984a3735d31a6af6e4f21b948919b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013677a29bf9941995454e887132d2df51b813dd22aa5f4913c3c900aa9ec62ae88c8aabf9313f6494361e9c412aa7cd9000000000000000000000000000000001995ff2214023d62f435ff5defb48a8fd2da6203429e311c688a5fe72d8ff71ad06fac85fca63c18d93ba717756cad3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e82175df164d9ce2ba4b0f8f52a290cbb9dd9620f263bd07f0dc4ce278e0d64c9bae04e27d000919864088ece92ec1200000000000000000000000000000000104ac870a1feade71e8fc2e4cae12a8b2b6abe635b7440f19a3038c25d9fac853cf20fe7a8e3436a58e913c1e16166a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192759b6787dccd74c3eb737076a6ef29b414bc546c0ab160300a4c9e9688d4ddfe78cad120eea9a38505f90c2765307000000000000000000000000000000000303a69e562faf5707da410ed1e788bf3e44ecd70d8754bf22e27187abe99acc600ce695910f7c7d4cb3385330b3fc2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001857175ecd64184455fef2dc8dcdc95f54db3c26b549b10126fecc32190c0f2b1c29683a05f40415b82608a4539a43ca00000000000000000000000000000000196f330f35fa7e5dc109b55b35104a13c35971433ce3b224b6129fd59918ff252563cec08d17784e2e6377ac08d125c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000754eeaaf1d98eb71d56bd2ce724bb4b24cca802c77d57da63e38c358fd4d9b63cde929db2007a77a0b1d6569d78a87f00000000000000000000000000000000006063ff64eb8fd24f46ee0e24892b8d369f6a5f42bb0dbe3387bba8fcf71cb1dfe36db56a4a33ad4ff38c92e6f2bd6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009df67b1eb91ddc9956aa76369086c34a7306da10d5446b793952fc2aa24569751f202e5dc9ad2575bdaeb0cb26cee0f000000000000000000000000000000000a8c8dfb0470d5584c1dbe564f27a71fa9faec1e8e26ad6261d2c10e06201e072aeb70772d414994e7b2802107e4753f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbe495d32115a3328de135ecd0566e29801e9ddb1faec6a2412b71aa24e531a2bc9cfe768d53b3c0f5f438e16bc5823000000000000000000000000000000000782382130bdd522933119e3f8537cb7b424c113f7b3035a3de0f33dbc91c900dd622739020cdc1005fe6cf93388bbf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3672b72f0d9d3075d76eed164c1c021d34024229221c181a139d41f2ba778b4d516d0b7c15cf1c8d64cb85df703273000000000000000000000000000000000b833d35193a4739f7f181a50709e76e35b1f0edc71e01cef6252b095c6ec5772b573e222d446edbfd53a7b25e70cce41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eed604970767b09484a1e0e0d80b6c8c8c5f6a1546e88fd4ab3741f12d33c307d65e5f7412b18473ef8a128cc035f50000000000000000000000000000000016983ef707f7bc2aab8719ffd283b37f619b57dc47be27acf81bf6301075c5dd935114130eed016baa6b82df5e08132d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8e1b5cac1e8cbd6b62d6336be394dfff8af8b1c087df956341b4289076a96e0c090dff1b7d91e743ce7056b3595a6e0000000000000000000000000000000013c804a038ada92c5abc0e4062d1ac57c8afa8995612c40a0adc37366f63e17b24772e615962be0f63076d4a304ccf4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014993c56c5507ec226d02faccdb700a6f601a833b2cf5e1b2fcfbecf1eae40703707d5d78db54e5d43a8d3a053559d0e000000000000000000000000000000001882521e14fc5043a7a4028e92b46e679af33e7ed95e02a68e2c78f6834b2f4ab8061d789a5f6fafc1ffd586df4fa5561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc1dcf2d2e73b92c25f7adb5709906f46edc7357720592b57e177e8cd0e3ac370314ad1b7124f92ed9d2f21e1a3bbdf0000000000000000000000000000000003c7596270e4f61aeafe91f7f7f51bf197a254cbc8e78fbcead8bf98f3108d3ecf2344a887563708960e9a3374e304c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193ace971ac3cbe335fe577d1c57b3f59d89a249d1b90a3e74737d993e11e5fe5fe1d9b3e1be397b9cb5530d1be6b38d0000000000000000000000000000000018feca1c1fa9924751f39b4f9ff840c056b4f7ae54b60badf8edf3017aa218d4c4bb6c8c3263da84739f498af538916b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155878fee9a5fe514cc8704e0644452ab40b9df815e5294c729e44432dee42e1b8311629f7790b7909b26da4727fe4fe000000000000000000000000000000001637223f6c518518d9cdacd908896b4253b275b0813bf259240859a5e844a076a0fdb5f4c1aca107b4ca8b8819d5f3841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001722e1205a15c5961c642e1d0f33d32733140c8c72bb90f46a12fbf3c373d03cfa9b0cc4d97b37a105ee9ce374fddb100000000000000000000000000000000198869c0906c40cb9ed9f5ffd78f0ff8042142292fcb8da1477869a8e92ed72a89ae50dc7ca52ba33034d56bb4cf77031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057155f7027801412b5b72e64081acecb9e32e03c509854b83e73d2e6289ad570bf219c39b0ddb3250946975a677c1da0000000000000000000000000000000015ffe7341ada9fce0707dbfa39cf1f161985fec9c18cfdc980fb554893e004f8ba7449f9551e5f0e1e9a7822d0221b2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008faca2078b5b5ac7c9bb99fd94e093d02689c0e0dd5d30d2b2d62c4e163486c5f052975cda32117f81f9b0f2b0802a100000000000000000000000000000000110716730769de8446141ee082b886726ce60f5ab80fbbe2d7e4bfd3631008ca4232387f0c17acde2bd3af10468cc6fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d08f186d0a658731c6cbec73f5aa5143a7bd1a73cac5d96b9245132ceb27fadae2ec78e77895811da336a7d7eedd770000000000000000000000000000000008345b077b819b25e13fbb4100c1f361b223d876ec6b579c5f78b6de4218a0c889ce33e5c65e1d3cce7e81f98a7572ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4e5a96fc060a88284313bdca833681a90580aa4587d1115acf37773746f179bfad612bef1d81f83ec767f2e96410c9000000000000000000000000000000000e735e9b9aaf3659dbae640adb20489a17dc9e618c5e0f086193cb0beaf636d10fbc2e30d7269562506540e61fe25cbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134e994b407a8fc5347b05b91e40c2887925b3429f41eb4964f518e046bff873d43707c212b9f1849d4a9568e46a1c000000000000000000000000000000000003f26a1ef1d35335bf077717d08e740f2e1fd1b6905c7524128e8e23f8b662508b6e0caa9948ece47acb56d19df63af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022f58be560afb08baf071db85ad388dd95409520d164f5574092f45de76b7545aeb4dbc9e8587e143b3703de46f6437000000000000000000000000000000000a65915b318edc344338043225b9fdcd5f55ffacb7530aa1aefd8a27258e16db0df9fe6b90eab3d31c3ade9ce132a3241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001042273de380c70db6496029650584890d477991fd2e588cd931dddff10e78b243d753f55808ded6197cf651b1419854000000000000000000000000000000001557146e067b72cd33cc8b03b6d61bb371e332c70fe6d93b8edc0b56d8e09edfc3199f1346c80699e09fc810fdf2a3111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3b1f3ad0f9c488a57d3cafbf8bbef233257fda9b8c4c0fa29778e78251cbfae648e669425a76f58a82d2a5dbf0be560000000000000000000000000000000008a1395e4cbe4bf6b81cefd3fdfcf6542a00d9e28d8e1d3b73619d4dce1ea0967c92404abd5096d9c43a96ac29cb2acc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddf48cb8c152608e333b89fe72f168825552d63dba4ccc4667e2e8bb32adce9dab27831560742bf3d90980e0d64366a0000000000000000000000000000000012fd2a170c8d0ee456a4c0aae6837539e79c799c676a3a19179becbe2d57f0eebe0e0c30e46cfa6bc5265f78c2c256441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046491d85721cddd56bc9ba9a7d1c54296c9ae2f3e3dc811de0a26b50560c7a423192cf190198df873184840296806550000000000000000000000000000000011d7695520a8777e97731dadf79d4608520233a9c0bb519b20de0abb375c33f376b78da587a5259bff83da1b669088ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2dd654ea142ed86fbb4ca0913ca5367fa8f205b197ae3286b36c0b20f96252359e67baff8c524fc7d2712502f3f65d0000000000000000000000000000000009c67b7b25c5ad1935db10e39720fc06ad2313e6fdf14f34df0daf15b44666d8820fe90ed9198e36e0c19d7180bdd3161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da395c33b26e2002419a93a965881056b59cfacf390f95a100fe77fa1db3493b885da6b45e3ae35077a61d1b0c3ee4c0000000000000000000000000000000008016dc5022eacc7cc458d29bd687654435c7d170157bc30c6d5fab732811ca70c1ca8f45eae1d804033e6e70982a63f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b3b6876fd0a0f1e05eda1ab8060d7e4fa4e9854165d31e44edbbc4aac8020ca117436e099821bf9de3dd462d856ee30000000000000000000000000000000015a08df9e87137d030373100bc2c238a57a109faab569ec1170af939c6f68e9a94a5170ce14938b368758e61517463b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099fe5ae800fdbbe9090e11bb57242b4fe7f2f898e84f7a96c2cd30ea9fd57f49e3a099c916c2e20153501d44158832d0000000000000000000000000000000005af19271406f1450a81d42bc1138a07fa2a30d8295ca10896cdea942abe130624b107f433b1bccddf831c88dfa44f181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075a7f387f0eeaf13befaf8c37655d3127f7afa3512aaa1fb0554dde5a0ddfb62b1116dbb111f70e32247140b43c7ef10000000000000000000000000000000000c9d6f510f7b3e7efe9bf87b160d891bdaa359e77b6c9e4c129d946f03b37d4679d5793b97e28462976a44c754e5a0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2539db3c3644236744be7851161929b2c3590e392669379d272a889df6e0835fd42cd7a48608a1318dd51dc51d9a1c0000000000000000000000000000000018771d61f0ff4e7026abb8b12771d9778afa5937f20391cae167012dfba6a16b643e2c0757c8abeeac23c93223f135b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050ff8747848f47321a602d93884fc6171d96fe4665245590636adb55ba0b87562ecad1865b66753837ff02b3d2e3dd600000000000000000000000000000000042aaab1c8c24046d6ac0804d4bbdbc09a1193c59c71c79cd20703ff7b5b5c08e37f88f41fb94d72dcd55f19a4a24f1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a25b5bdd29a1856b06d16b45ee6ff8e0c89782c24d7bac83563c5d27a59a86abfcd6e45aefc8252e93bb0d85bafaa1e0000000000000000000000000000000006817dd5d13b8a87bccc5df1a4289ca2e3b06433990fea0b8f21881deb90594801e24b1fc6c6ef2a8a89a210d8905b4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c7bc9688b8263173fe9b1805d942cc444c43e5bcb34a52a9964703b1f8b0e89282fe5451f1bf367e90634b047197b000000000000000000000000000000000518dd1424a9489b56e90cef7076086be6d9bbc1ac98e3cb0aabf984b8f99b6bc5ead1dbc581fba00bbdb6aff0454be41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c0e9dd1a3ee82b771a3dfca8192b15447677d5d772522d1ad2600c497b1df505cced652526b87667425d2f5c527e0a000000000000000000000000000000000f915a04fbe51552ee125fdf44b918130a510d34151f05c29fa4dbf9b3cb0b13f0bebff87bd3822431202ecddf59a84a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dc6d3a3ef25835b6ca577a320faced7222ffb960d0015145f282305d59a722525c10f247a3b30a6289bc45265de70b00000000000000000000000000000000022e088110173dbe2f535ef887c540c5d94f6c8d342fbebb368281c5c9861fead1a1c2747999fb7edc4d495092fabba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f05bbc6490d499655213e3b40fc3d2322c6b586da991164ca2800212d88345d9663f8a99e043c46b177655e9b1dba40000000000000000000000000000000002beef6b052579c4dbf0a69f55a5251cfced3a4a2259abcc256d09e8808bd7c404fc832558b017f82562f103eb3fbd511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118ef7a65b15a8a385801344d7c731c7bf33b8d94bf500291ba8708886cc1a0f5df827541328e52385c1fe0b75bda5c0000000000000000000000000000000000700de6e48b9b4ced185c0883d6fba32b4c5abed54df18732ccd5c27448ef0a52c6c202582c84cfcb6e1ce9c81fc8c711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a521958831cb4f4b829ec8d46a19147cd99a38bf2c3fa3c48d7f7c7d7aba877a6025086e522121eb2d6ed19fc74123000000000000000000000000000000000bc97e37f397f1b7356493a41aadf04bdb40fae1b3c257c0ae96f1be9da655ca8d0b8127b2da7f67796359c6d6f0425a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000633deca8911646ae188660c78d29bb133583179457e762d5634ec7d4d09c9b4c2124450436c93cb8c62c2da5d913b9b0000000000000000000000000000000002b237bc619da52c43b982e2c98faf898d14141532292b70f96375acf56fae4f09ea08a5ef96fd5c24e8e211abd9a6681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000381b8925bbe1b08a4e5b7b72525665c271a9dbc603dda82f0281f6fc703c97b730cbfcc4a884d7c291c41ecf46cd05b000000000000000000000000000000001954c80e47b2fb3c7c3293217ff22384f978f8bd2d29a2f680090fd3ef4737c5bb848bd5b244cd0bb7d4dc8804e1b8791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179b16b8e7f01f01b59957e6503de75594a3aa0a81526f3371b19f3fb1d1abea621499047e8a4c978961a22a9cc9c697000000000000000000000000000000000b4e1bb84a9919dcfa1b420e22a3de952f93bbd430501c8c7051cb49dc606e7758254b5232b154f389d13bb0584093841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019112066c6adeabb8f6d1ff46b58c46e7f869ce4d3ef1def9153329d6448f0d1e7154034a0deac6ce213fa54747a13060000000000000000000000000000000018e6f5e3a57859f9d670c5ebc7c69e0a41103b2d915979841ca5c172a69e3965f41dd2eaa36d6f3ea8ecca3d0e34354f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afac7ac38da62b43ce70efb3e158afba0d6322e0e7fec41f4513ba95f049cc1ac8498207f118dcfa82718e0449aee690000000000000000000000000000000001f4aaa8dc3df31fe8887c43048997a10bbdddd76f112b6dd01ab14a287b3841a7f9c58367e0eb9748122a9a1f0ee9191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c5e74635eb8b85afde9a293033de072d6a507ee907c3063d9388387c2b6fee14dc91d0aec291f85864d0d89fc257760000000000000000000000000000000009126a7ba2614130d5b3696b09e36a68dbf71165ec60575545b3bf24f2c6f63a346cb0a77624ef142c44f96b525370431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164fe8232738a914f834626c0d33aaab43bbc174349733afa0bdb72eee7f8a661495ec613c4e92601f4a79af51c54ca400000000000000000000000000000000035474535602193b9b66722d6ab765cb02b67958518ffdc85b67421662989ca6f067b8db360aadb18305a273d203a4061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141c53423b58bb9ff7d27ae251be5f0afdc50801a7df402b88fb6f951b834000b55ede5e90b88b06675f3e6e8b0a2e6a00000000000000000000000000000000132cab43b5d96668129142bcab9911b089bc65bb6920de80ba6d69656f62a125882ac8eeb524dc0e75417f77602cc1731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dfca23a6de3aa8473ddf75a31b5fd7cace7034b756f85ac86fafdb197b1c9193fd7b731f6c21a5b3e7957e6fc57cc000000000000000000000000000000000069cbfa0f07d34318580b2d26eec830a5ca9d91de32f115c2937c602f8646fabb1861f559c04f68517c944828af7fce41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dd217a250398567c35150bb5f54b12329fb65f2148bf0fdabea5c6fa976ad94a48aea2034ffbd150a86d645cd22026000000000000000000000000000000000dd36f8fb3724b73cbe5390929bae16610987d9465ab444b0396aad86b0abe2635b8ca3c4f49dd47c6609caa9af53b6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001443851045e9ebcbf325686f279c61e47887fccf4cac42bf16a25be8f23858974eebd2b5b4c68473780fadb5328aaf70000000000000000000000000000000000c54f60391ce8e8bf5e82e2a07e001b6e1133b85d95b2dd46b3e4d865dd91e0a7d82ce8e176b585759ebe52de978b9131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a21ae14c0577411929b94baf44b011035f43681b0687dabe966fa4a0c536e38ba53d7184d4386a5f2d3546a0d2fb9a0000000000000000000000000000000000a1515070e8dee546d6642628d11d97965c008a8a77383897652e0530fe98cf072983c28509bc033d3a655fae26ccf291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011018373e0216d38775b9c01a58eb68356631a4643efb2bb5686c607105e32fa4ac30fcc9247f3f6d23be44fc35b70cc000000000000000000000000000000001730a408d06a4cca57f2d16321667da3af8f22c0773a00df27d9fbae3840936c4f9e874a757cac4d8a9396a24b9b19e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001937df44e0a722a2f0bedecfdb54e44951624118e6fbb59910c685606c044a6326ca1bcfbd4e8150eb5be3284d74624d0000000000000000000000000000000010e11b8811238a4378340f57c944bcb22cc5f90207ec8638c0f8d76eb9caa538c4affcf0c0cfe11fd2dde722ea3f85661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001569bf45aa71c78ca97b62dd1bbf0134341b9e68a7e7cc32bfdc4d6ab3bb673ba55573630562882bc178a72276acc8f40000000000000000000000000000000005c9785f234150e087d570fd46649afbc89fd4868e323d9eff3e076aebce2e9fb09c1a427a7ed188b820586f3a7201fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168bf81438dd0011239dcb839d897845400483951c4a7ad18d431c081be517877817ee779ecf137c094b3d5189f375b00000000000000000000000000000000014df014dbef9ba7efa763bc7811437de082e6a53f3a5cae8d5d2198d1b3ff503c34f646638f2858abfc7e00a223ebfdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c192e98669be2dbed41f8e61c45b13658ed0169c5e5f80e60a1c92be21dff495c8f63c6218f3953226b21108ad159f000000000000000000000000000000000d13ae4d1eb8f0aa2dc32946d4140225a214edfe841bfbf1fe8119c5e6062133e490aad97ab158557c93603d253c29231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015066911f305f3581e488d39acd4c21c8fb732a306133f8c26c8b3386a7aa5c1db92c6a5f90663ec1c2d10637988a6b300000000000000000000000000000000070b9e1983f2e5cfcd27f6baa424b19c5088d09e54a600752bf9dc149f38bbeb7c2f3ffd4cdb7f8ebadb66e97e6bac7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053b262b75ac965f67e3a4426d03f2d3401b6aac0c848564098c1b0780fc7d5ad60dd68a3f4600a16a94de7a00c60b6400000000000000000000000000000000170e8be9139f9e0cc9f08a49fadc38e04b76314dd66b8b7f87a855fbfc73ca305ff0650cf9631548d914465bae21c6131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ecac5f8a09bec5b728dabb6a42256b80e294552c9882b9fef9fa4bf0b2f1ecdc4b8ef5b7b5b58f93988c98d3286eea00000000000000000000000000000000128cd3180884d6c6669c807edf86da6249324e75207db8cfe3c0dae753a9ff91801e44680cb871f8f030babf675247b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3c055d34e132d2437401572217144d5f802b4066ba98bcc6215d85b968a2bdd4eb2fe7a869a35289af0fecc44c52490000000000000000000000000000000017e2cf12c7917a33588262b988c39fa208abf79a19e6a3c8e72ad42f0aaaa3310d6a7340249eb75e181513fb069e0a961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123915e8ccdafa20d60e1462465d17c1fd127825704f8e73976a4e611a3d3b8a85fbea6a6cf839af569e0ebaaa07d82f0000000000000000000000000000000006e3ff74c0fe03504224bbb25137284c624a1efdfc4bf1c790716db26dbfc89df4488e1be7157c535a91aacdb886abfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010368947b850fe7f68d38577f798d9751e5ee3833cc1f01f7fadb7be6fe1ca4da2ef79f0e9e2c731b4dcff4c2db88f750000000000000000000000000000000016e387e9190f9ad95d0de690a177c008cfbd061da000d3e9047b21c669be3f140cc93aec8c03d88ecf4d84f7f8d821631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003af12a2ccdc7fd35105e639d1524042f2e41dbbea20c993222ed19fc50e083770751eb23d43acf8bc882dbd2edc5e260000000000000000000000000000000019727b23d3fe623433764e4e31650f300dfbdeb2c0ab8ea3faca9331a755ebc520171ab226d4e68badfe15dc7dc646861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097d0b066098541976d496948e619d2d915016af5e7da9e1d98ec860f6d1d6a011cd5754a2269fe9c5299a4f1cbc447e000000000000000000000000000000000b7708f4bc17411ff67c025f55e495cff8fc0a98ad0ab65f672f6c5eb24f649e5c05156498109303f370845cd3e269c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d8e8033b4baee25656ec226ff9e5a833f5d48ac075dd9089b8d0cd67242f39f095a1e7098418b0960f045f99e8535300000000000000000000000000000000128e656237d5d5489dba7acfcf261137666cf501be256fdc7add8fae50796b312eedf403e560aec343fe7b6958f40c2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116973b23fab78e6e2bb86c38abecfa20e1caf5df09f410329b7840fca245c444e5631420cce346b7b4f596bed17974c000000000000000000000000000000001412ec548a6c79a9615d6bc1dc7bcfcef0bc71ac811e6724fb88d8aa87cb187fa38c28f864b84d10ac21887bc4cd79521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004494662d055e684941c308795ff2116464e0cab72ee9fa20a3eae4ceb4178b17437f3216102a8fed95ee1e541862bf7000000000000000000000000000000001895a144b0621f1ae8a6d624fce43102ce5fbc3ab844d39cc0f822b0df2e5d58f2381659b9d8b5abcb6a4f5b0dfee66f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f959ab7ae43642b043cbc6877d24697a4fb324df8eefd065a0ac2da6ac53489f1ba5a056540f344879a63b2abf16ea000000000000000000000000000000000080c1956342b3777067b607dc5fbae53c96e697120ac7e158cdcf8266b4649215a095dc5c3c21144784f4b1024982a081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a09ad646c9f1ddab48c1e8ee2819e19cc9e89c2b22f85de88793c2c21e552fde407422227b5515021bddc0950f52920000000000000000000000000000000005eebb8bdea44fd2cd4f5095d5893330fa371b87ab269a19e4714ca0b25227da83ee5035a426e0fd07f8ecb050194ca61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001265251439d3b1989cc5c1d7b98276c4f75decec0c78daa260161c7deddd4df418c97c746b6ec9ff6188302dc5c84e00000000000000000000000000000000105fde2f4a81d245db44cdf900601b0780cfed92764194ad11505696978db156f0c239dcbb2ef23b961743270724ad641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092f2122130876b6e380765b50372c9f2cb18d8b4ea272e598ee8b55320c863372d418fb9b591dd2c57c71f1e80b030e000000000000000000000000000000000efacf890803ca2b1920b5261510d9583abb12aa0e1efc820c972988e2a8912bd321896fdb911937b5e1b9000e82a5571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a08b9cdec028d98bcfa263723ec32bb283b191f6b0ad5b8b6795ec7af4600209e7ca17007252ad79eeb92e70d699ef000000000000000000000000000000000cf8bd21dabb69046c657d6e66ee81597304316930306d8189c7ccd1ea2a2b9c0d1bfe8bd354df765c509bf41e4f34261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a19c784f15829810c700b41b38e06b441025802524593a186c1ecf58e761a99dfdf1a1aa4a4ca80d10a0ab17fc3e0ef0000000000000000000000000000000007b74102cff63c066485b68b6374418b0051b896756577cd415ced272858408550c1f4669d10282bef2a732ca58e8cf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfa15cc7baeee6e4240d5197540483e79b4a2b7d100d1f1f3777643dfda5313c7495bf21ce8696dd78586fed65d6815000000000000000000000000000000000a656801969cf36a3243c74892a0bfc923cf813ad824f3d2513937f6ace4a83c8efae3af9175444dbcbc05348ed35e121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020b756331a997e91011bbfdbb490aa700bf26cbcfc70fbe029ba42bd97990017f24f2a12851539865ec312994a22e5a00000000000000000000000000000000100fe7803ca3d31bba156db9147c685d5858bbdf8b34accb3dae0402b139c29eb8068b51e5a36dd1177ab8321457027d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bc4375e473a0cb6217bc4ebae061fbaacea053c57d25b3f5cc847d245abb35c3ac165e679e71a996b936a7db11c4260000000000000000000000000000000005f2a36f716b481d51deb094a3dbb81452918eb243da53dcb4ed200aa78ea03ca4559e0f1819e717cc66ca76b9a817f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d9a85a0461845785e39f8f56bd99b1c3dfa89fe6335530523b38649a62448961f340086aa5da123d86a11f098e7ca3000000000000000000000000000000000576b7bfb6a2e2b11fb515333b890cfe75e907ab4518d3d60bf36683eb2981d5eaabfddcb809888485b652aae7d4a7f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001229a3425c1cbbc4538212633fe88944df87e5c71b99bb2c8d55a88191861fd2acf21cb5b4cc058ae84c91b8cddc9d6b000000000000000000000000000000000fa86b9206edcaf427b9432ed8a62106f27cd466611dc2c149af246eda8f7252d1537074353cfedca6e29a426a7f546c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100cf68390412b3d6f7515d7d8f88b1f6a3eb6456ad911669e95ab01d304aa81aa89879ec15c5bc3f2cf24a5409caafc000000000000000000000000000000000497f45ae5a965cd8175959b2d73e647dcee55a104c5f89c4ecd81f9470e3bf003008fdff453c57a69bad46b5d6b0a2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006816948e64a32eed42b0056102c9f3f1a5bf8214f8718a19f8323fd59e67a1ccfe2127455b21cbf5bfd08124c6dbdb30000000000000000000000000000000009225e10b8a5974826fa720d578ecd6bf7193f8c91675a0043497e2bee9801c7698068faf316ddb6e5b77fa491b22d751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119854734ba80a316abd66ed2d220ce40abc655791c58f70a9c20a9195fc164f72e680e1c4da4155c00a4b078d2a0ce00000000000000000000000000000000002fefa172cd9d62512e1ddc9566b6f69855889281af11701d7d24564ba178e6bd5fd7863eab398c0c21ee4989ebb4e521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001172acd67a574da584c69629e3d0749dea49a4bb93b07d0b7eb24f0a85e16614fee96d2ddec8fa44ed767083c53035390000000000000000000000000000000008ee21576bdf5b2e1606962dd8fcae0957e7c722d31832091a69cbc2eacf1590f8ca5d3f46b4fcc321d5a25f066a17551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c221a750819fa7d92b538f2cf863a43cad81c6621dddedf81f2fa748b2563b565fbe1cca539600ce0cd452250bfdb00000000000000000000000000000000191be772861050cd4b68504f7e839db4c830e89d141c8efe5b063c9bf0b1e2ca97b0c0dc77095841493c4b29463102141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fab92dc56271f5431772d7f4872930cccdfb1ad94e13fa075840f6584203b9d3abe769fb028b5c8e05ad9ba8b9c73d000000000000000000000000000000000e91a61e13012b3f1f3ed18b7c91eb4deac1d659c7da3580469178d9c861104a44cd73a930cf9901e770b43a42c0d6fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc82e3d7b9a135c3eb80e84bcd655885ce42f92f50fd1c958c503fe9ceb7e7daebe947f915b45968d1d0a44931ef91000000000000000000000000000000000158a02157c32faf4048ed4ae5312d5a48466aeb435efa50b515ac32e88f4578a02788298215683a3dba8a2c30648c4321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001520d4658d717a8b9fd64bb5f23dc86d7d75600be05e8e6a2c31fce815f42db4e30aff05fe16e3f3a0b2772da8d99b7a0000000000000000000000000000000011048429fa0623f549828457db04684a413436c17c551c897cb9b325ee5000b05d67e25a163b54be7c7ec558a6a746f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b0b07ff4f07c8ac5b9c162a1bdcea4efcfba8e4f961adcb02a7fbdce2bed72f316be3b3ea4ff72c0b06261af247e5c0000000000000000000000000000000010468f3d1425b239418f7bd8e70ff5747d85069ca86d14d716d8f54905936203c4f11b26c51cc50d11062e8726f683db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019be99ac80ed551520a109e83d854d417d18298fa8ec7024a0b1eace829334d0992a36a069a424723cb2fe3d8512d6b000000000000000000000000000000000180d7ab893fb3f7b1f4cc7454a53e9ea1e67ccc0fe659c29b460882168b7aaa3069fad7f818ade4295a9260190db9efe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018287773c452dfe9d64abbe69dcd21027764248a684a40f630ad106c573de6037fc8896d2452bea8572199574a6029400000000000000000000000000000000139d571255edcf9a8c26054d6dd29da2e4753b8e2048fdf058290fb440c4978ab2dd19daff3303abd4e147933a99df7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000036c9798a049b34196b5eedd9df22399ff1f02b0cda65b58b87ddd9a8e36b1600f2242c6694030940737ba0eaaa7a630000000000000000000000000000000013aa2d506119b80d0f0637907173705e80d93c51a5e033044b322c87df88029df2246de09394a4fbccdfd02daec264da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807eb8f582ab3f6f4af8d1119ca65f39ed44873bc8f05fb3e24071815a33efe6edae9bfd17baad7be38636e32752d7e0000000000000000000000000000000007d169b2363d7000d81aa036fc16557dd7559698c26958b2a30a4c312cab5253662dcf4a06e4dcf4996aa39e9fa470381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000795e084ac510f891bbba776dc9c89c3028bc5be7ea4e8d7f15c7b2b70f73a6d7ac6e78e33955310866edbff5a137df1000000000000000000000000000000000f0e02a792452ec96c0b869c92d095065fb218dcabcd2e8286948dc51e573235d4255305ce8587d0f5038f5c72aee4681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d49432dc402de6f21893d9283996a259d6df2a7da5d218a51a4c6f0cbae4938f9352429f7b5a8fd5052ec86c8eeedb00000000000000000000000000000000072c2502b05bf02e13cdb15fe9c457fe611f37dae396f333bc161939514934743affea10ffacb0673d0085a2f5f9496b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160c52e982cbba73b7f70aff84820e5d8d1fed4595141bcaf8f8ef0e5739bf73a0283bea40c9b8471768b08f043546e800000000000000000000000000000000056617d5dfa539f59ceb25f607dafcc9c586f67635e47f406b67c49024b56a105693d39b2609a497f7c46d75864a05471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cb3c2dd83c9efd78945607c18f02c872ada20e592dea21315e8d99af3f9b88b68ab17d4fc25b8a43404eafefc979670000000000000000000000000000000011de8e838d8b5807a5a20edea048ad6a7082965e8d6732a902a2e97c40c80896d1f9dc8b15d8ea3712aa04e8020ec3891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070bc90292f5ccbc7e68588089a117743a7dea99aaf4d249f8e0d93a00f7b59451966c00b31c9824dbea3e30f2e6596e0000000000000000000000000000000011e8d0194ff0404f9ccbca22456ede1e3e3b482ab9e4636c8af477cfd3102ff89c9af9f1ac25243575520d29c6ec00d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ebdd540355987212b2fb9cebd71a9eb72c57fd1eaf95ccb8e5b9beb65da2ead0fb6e808bbcc3ad59c2ead2f36353bf0000000000000000000000000000000000cab74266752d4f33f41abed43c67c2cad5a83a201c91acd282f1e2d837f72d52175b9c1df7a57567d01da4dda8024c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b073df5fe8949a394671de49c17c5277aa1304c9ddb673b6389d1e3c88741d7a118aec6f32c2238d27adb1bfd115650000000000000000000000000000000005dd4477f898237f76aa803efde2533088280d503ed7a02c69135a1f761c84520ce675c3d2cd973d12255793a58abed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120d32237fa7d4023f039eaeea63175d43534145bcdbedf88832f37ddc8b0b48bfa4738cf54a6557149307722d1ac6c60000000000000000000000000000000004cd2b45abdb1d444205d2dd606ec840112b8d1c7bd1baecbba996071e9ebad4ebc9ab0d8fe11325c57859ee535efe751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109a6d6021ceca689b98a50e48502681da366be95d584565c911582d0ebec2ec842eec9a8c0ad4c9526deb19b1c8861a0000000000000000000000000000000014741c0fdebdb08b450183b36b1ab2f26e8749d5ed34c4cb1155a9f4405741059c249de17c7fc0867d6f42e145e056411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e6c05e9e850a5ac95723e46054b5b0658adcc1be8c0900f480946350b5369b15540378ab55f8f3e9c4390b953360da0000000000000000000000000000000012505dc029a53a509b845a6eebc12eefb09d729aafcc9797c27acdf29a6760c6547ee42c2fa8bfb4176b8fab2c88ddac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eee87a030ca52f7af02a50e97f0b0ace756a825cedb2a02ac06fbad9016ba46e7208577a023b648271260121f1147710000000000000000000000000000000002cfcd74931d0fa72ef3a39fe76d4e3f3b63b441a7783575069960ccf00c050fba55ea8c8e945a9b4437fdef0f6003721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c589a1fb3e786d9eaaa56cba34d51aacc43dfc9d92859654a90c7bd4f6eac4a2605f49ee25a889b1043c9dea45430790000000000000000000000000000000008b099b6dc9de481649e442eaa33b4a4d4d32223c38265c26cfc02c71f7c43e41e374c1a919d2c2909793e7239ed80ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045b341c66de142896199f574ed462d10f7225932d83b06376669eddb042a4f82e6edc86c7fc359096718af2bf37714f000000000000000000000000000000000a36da6a457278f263498459ebae99ce6257c920dc7eaabb20ecf36b24514e2003e6dd42a45c4cb685ac38b7548b3ab21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001950ed0e0acb4c3765f8128cf778ee58067f9d4cd9be955cbade4547104ccd19e16ec01b91f30575fa39e50c7b2bd9000000000000000000000000000000000000d663fee557efaa61296e20b547f0f82c7449ca19d4f1e02c9367352cd763e85479755b57231bf5355402af7daaa8e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b3efe0b861c14bf3a1b50c61ba56f29bfcc8a67c04c24228ad64f5964a383fc658c4f11be606aa22856c7cddd516ae000000000000000000000000000000000cb3531054645600fed1ca0a0c6b3779a51d292a6771cf16de5dbc698d448a844746e4622e6d472440c540d1bafd97c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce7a0bb51cb2eeefad7ab2f1f6f20b330c0f3d3a1a6b94244d9db4629a49e7a2d370d9204d349d4fb1729d371f1819a00000000000000000000000000000000018fa3727cb19113dcce338637c2b2290e9ff1137161d14dcdf1a1bed054f7a4711b50ac176352daa83add7cae2870fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a6d37dcfbee39ae8b0943980996993f47e9c4dc7db34db03b6d24e1d457fe6aef4517dfa32ff63528ba35dc6f9950a0000000000000000000000000000000015a229f9f528a3dee397a3bb776bc04fca4eee97505f9f9e7f218383575b22f5475d6cb4ad0376e035be4b324675afc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001323a85be79169297cea9daf0368cef178ce2b133e093c91e9c9802e5082dd76b804fc7be55548986761ad71fc058210000000000000000000000000000000000697222d456a45bf05eb61516a82737afc133634a069c5ce957b3371b3933cf75b83b29a6f31f60d67a170a7179662fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001690e91b9fb7ddfe0ecd191b6fec8047409a153f2e08ed3d309b0f6853dbe5cdf2579e69c27f354ba205bf875143916a00000000000000000000000000000000149050f172460ad12c7ba3aca01934acdcb8e51150d917b4b696494376d20bdf8f3b2a60261978585c45cbd47313efa31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195b76af3b69e7ebcc573228abc82c08f252274cf05ab89cc5a6d8c646dc22f340d1f3817f503e7381d8ea8d72b313550000000000000000000000000000000013314c65e92ea61dba1e415e5d0c46ba0695b0c03c4c9905ed3c629d71e2f16a479c85424d5940871d53ef17acc221331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b86eea0f6fa9681e264acf5c0290a950ad9287be412d4715d846b0bb1d1543605da633b7299ce52246c75499b75bc64000000000000000000000000000000000a81b45683a01431678baeb7070c0c903b92f1f96b0a2a5d896ab7ee6d6d6062fc07b387bf9f7dc4f093f49b0ac06e411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa61cb0c9d6494853bb501e1a7fb6689f970772b8038c0ab3ed17eecfa28955311e386ebbebf8d160feb572ab85410d00000000000000000000000000000000151b9ff63869c97a5c385790f39b440ee1c72de16a576f82f9c3fd80f9de39bf481456763729667cd34c08bcb0e024a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001586935a07b819a547018adbe63b0a3bad8c1636f7023ffd4b26d07fa540ed02ac821e5dbcf3e10e63f7d348471c5bbb000000000000000000000000000000000614232f3dc6820cdc96eb56843c0aca376586cb801d0325e5b05451359c85f810d8c63c9177f2d9ec744f1626386e5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011de7d147588446d75904da811ef4e85ab0c8680f688bf04499ed7e517643e07d4fe7754dcec9124a2151d4f771464e00000000000000000000000000000000141b756e740d973304f890dbccf8e197b0a1bd254a9d0e1b49468b37326d169afeea2d86baf6cbc9ce0f09967b00d48c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c97054494d055e828247968f8902380a8687e0747f2c8be0ab56ddf58b75df16651f248a757925f9ec6dc218bc87d41000000000000000000000000000000001600e069faf4fe6ed355a948d7b9f90d223e93eb26e34c2248f17d25242b88cedf2beae3242053b381b0361752f20ce31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cadbe674fd18cc4d241c6643bfd5120200ac8e0a6173e59dc52add259b91ae3337f6db0662ebccc9fd107d7c749079200000000000000000000000000000000139079c7b506f61c943e5e9a861211a5cacfe42363d8cef75ab2ff05e6ef1b316b7fc89f1cf7d7aaeebaf600ff591f491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a909049ee11dbadd7bddef177800c5023ff19596988266d9a27bb740cdf9ea74d12a4909b147834a583b5db20dee6300000000000000000000000000000000150dfcefce15869fed2331a924c77c723fb464441e664ee25bb8ffdc0cbb505490b0105eaabff24cc3657845e8f632201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000091bb0a0f2e6ed30dc8bd6b185d4597151c5a0c0650170c0da53cd737bbc748f015c8ea2ada70e6006efe60643d3ac00000000000000000000000000000000005dbee65ea4f90fa60ab702d1f136d2ffe9e88cc46d06a1ae0f2a08b7423dbee61f4102346d4fdd29d732fe553d854151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff968b9460d9e9b0123bcaf5e7cfc57f4fed0eb5f50cedf4bdcbc6b58247eade79aba316e3809f1e2c9598876558c3400000000000000000000000000000000198f6d5fd4f12978c8ed50ed8273d67ea2c28a432f25a094f76e5fe9434c350beba3f1d93c5b1ed5ad88a5955410d0991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014048b78b7a1132cf3ccfa1269712bf5e9cd59488797c2ac6c4c26f3bae4e3b4f3050085e9bbe41954d10ae5a9a87075000000000000000000000000000000001357fea3d344292ae65d10d92a1123a3ef133d37374bf20f0f07e31964b559035ecf1f812aaf64309f43bb51f3a4e5801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001199e39255f6208f0bdd309af7ab559dec39e6836f608100c7c3477866bec058dd76546f79e0fb5e22fa598575e0d2f4000000000000000000000000000000000df872339c6cd3ca630ffb33834075a5367602962768ab890cdb2db6784f95e554d99c9adb713aa206c96180ce1512fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000195ab991a36c912514ca04444c0d44fc3cdfd0e40c0afb9dd310fd712ea133181cfac99cc49e898a07c18098f05721f0000000000000000000000000000000000f489b243e09e54a48a589c15ca823af4bbee5e8afef6a45b89fc0adaaa2a9a79bf422b2c610f77550071d3285078a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011391c9a359c9c1ba68687efa2bc381531cdeb571f586c8893e6449befa4de0886351dd6497fc9cf9a29c96be77594ab0000000000000000000000000000000012b76ecf7301cf85f8b6e4eed83ee03a37707dd8fafbd9c0f2e5bb01d49a5401abbd2ea6d4def405c04fdbf58dc71de31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000044e7ef1cc2092abeca7516ce3815c1697d4cbcd3f19d41c85902c88a4e686b77eca7fb5a46e03aea0e4ec6ffd70504000000000000000000000000000000000e54ee755b698f7c026d94d065ba1094e68992afbfbd89e2dd43e17784cb5a713e723a15bd96b7bcb017f459ade54b541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e9718bea2e11fa01359c4a545382a931fc177084f756971e2641096d9254565ec4e02099c8b1be2c4516b5c9e789700000000000000000000000000000000127e6082d5f838ebd676e60fc6260e007d66fa3998b8c191ffbd2acdae0aae025fefe0692828cc869fbd308a23e5596a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000257559732d99da8f646a75460f143a91475d6e06d4a52b2840afd18325bce52727c5b3cd4c4faae5fb7c9e23daf6ce3000000000000000000000000000000000075909aa15aa574db3142605772c43621f75d72bea53edc701ed118a5f5a793d46c0cb07b4b7dbab5d8912c1863c5f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060dd4eefed2ef57a59992e5d130ad7dc379239fdac34513049fd25e21b778d66d4b7867cb5047bf76c4d766b0f97e6600000000000000000000000000000000056a52d55f4f5944cf2538986388a406a8d4d1037e701488129cd6cb88ae57521346c79c2d1bd70fca9a20093e7752e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162105c0737d011caf032884a379dbff34dacfb40010a49d22c47b349fe45354cce0b32abf70a2fe9d0d39eb6ce8dca4000000000000000000000000000000000a77e56ec90af91ce92400fa544bb6ef83de8261cab0f263e26e87c9f9c866ba16b5c6870dac9f4f6bbdb74c42c870ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e99282b1da5c274df366840f317af96b438a488eaafb61c3c43cda62edc175b4a7daa034efdc94afe4b167e573802b1000000000000000000000000000000000ecf8da5c49aff47c28b4685a815806ccf0a9a194d5e7995aa52790a6b33c2ceb52b7b59c7b31b905fe5818fc51cd1941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cc32910bba04d090fe0ca9912dbcf26f8b1f95d3ec65121a5429413984a82b54840d0f252e4b6a57bbf26a9e6476660000000000000000000000000000000013f1ead087dc89abd71cb221ccd6b33c3c02f044d5a542117cf354211d4996ec9350370f1158c1b5d0fc7763d007ba3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110b4aa749e6d111899f08ed0c1993c77bfd9d638957bc0aad18926e457103001b5b819a1d62a6807ac78949b278f3260000000000000000000000000000000005c33a3ee78d2c0c3c447c2af5b35f8f44854549baeaef72a09dd16cd33fc7317fc32e3ae7a90d94afa202fdd53c16921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000885bf363dd2914730ee942da5da479a488259e72c75bf543a2b97a6975601d54a871cf1eddac034e13dda8001b258270000000000000000000000000000000006e0052b4bf4cef0689526b6332732a7f61d09871ff59185e0da997cfe5bff201fee5ceccb09f9d6eb1b343e152038651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b0b93c63e99f45e47ea1f34726950a059cf373cb109b8cdb279fb9db2af5a74f0702747cf92e6d910a85f7e8d223550000000000000000000000000000000006e95fd92e41e30a55f00db40e3b77cea6ad62277a63b5de995f63091d4092720084b8c91df3b7609ff27d6ffe1c02fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d624b2e9c019631f3fa0f5579f8cda39a840162ce6d64934f4df851e4cf844081d77924bb0312380f7469c4c21d1efc0000000000000000000000000000000000d978ac41f054eaae0ab1e2022e1e675d4e157b04b9caaf8148b0edfabe591a86cd6000d8ecf58b7719e3946c8d92d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058464c26f0bfe8982c02a954e3cf15d433489a29f73cd3d0a99ba7306ae467e2e31de7dafba19e2cfcd7cee1794aee00000000000000000000000000000000000a836ae57108ecd890ae8e53b98a13d03772ac8e7365c4ee3940f6bed7c57906f9a3096548b8a135d95edfaa7c945531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fcc4c28705f30bcba3dc8f21f50f146c94dcc1ea06db07f1db4bf8e23a2201947dabf410523989dcb4953f0f3d84480000000000000000000000000000000013844a44c75ad1f3bef5826bd8cc6a155c9a1b1ad55c2806b355b235e79bf07ee9f89e517bb020f483b668c2536850771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026988b706ce9fcd1aad5fedbe116b133c751501136e3beccdaa6f348cfc7a3dbe1f5e6ceee4c367130ce863b5592617000000000000000000000000000000000823b0b866fb9b5d56a5659a92c649192184bc8abfabdbb65962dce24728ee6a88441ad9bf6ff290f3557f2d34f258c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7ca17dfe1e8e6c256eb985edb81d9a4c47b8370aa6a694200d969c54e82d10cde63b6f12f315119e2b3f7afe5b92190000000000000000000000000000000017e7c45696a9182677cbd4214250b08b8a0941215315038844aaed01f02f23676a4360db38ae88e7be684d505999ab1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155ba51edfd06028e1e51c04724e23e9df577e748f264e8eef61ebe232104f5d9795aa56ab1d7e1dcaeaa1e5979e081e00000000000000000000000000000000126c5b6cf0e102c92bb298ee6ab18822870192e55f990f2cad7aca1e710f90b8e24f2d61dae6e91d5d360d8e28db724e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000121eec3ca445ba81559fe7877e5f205cfc2b5c257b01b3e0382d767cef4c52a2132741332f3c270eab22c7f3ebcd2bc00000000000000000000000000000000145aa5d02f86061238c465b3aa0ea7d96f55e821d1c0e88a8718884069cb16647cc6a68fbb0b8c79921ae6bf85352ec71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a5de1f0efc90969309a4ab3b759e37bf3af9100693de0154969fd1a6f00b71cfa4f1a5939ce830a197816eaa63c54000000000000000000000000000000000a79d5911081e6de8f1e8a251e9809dfd5b474785e33efb536b8cc5d5c160f2262fffe6a5a0fd9db64d3044ec08a8fcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b653a35f69f0071a0c3c5e1d12429634278bf5e30079580c3e30dbbf207bcaa00946893c3ef0d9490c74791dbae222e000000000000000000000000000000000fdfcc4843ac83643bc9813ed57414804b33a431d7901e9eb8f8a11c74975277ea48923b69461a4408e0a01fedca21ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136875932d8b14d0525ab3a1b7e8fa61594804edd00ff2fe45b5fa706919ea9fef5eae900b429bf5674dc3e84b40d2c80000000000000000000000000000000010b99d5e7251b73910cb5dd443755e4853180cab2813f9bb4245538c193f8bad88ca2c3a34a4685af0bd704db4fca42f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c67931a983ce71e271a443a9514423f6aa578a2a9e9b0197219832e79e4ff6eab503d438492ef3b8983f4788d3c2a8c0000000000000000000000000000000014ee7fa2c9a626a7a5ab6221cca2a78a7a258668ad24003fbf262babc563f87ef8393569076cdd1d59ecb2c8f57e0deb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e568741db3e4d8361784d7aafbcfc9e6a99dd3c9ec5bf92fe4063f69f624f75c3f04407ff00201a54c8e45df346f900000000000000000000000000000000000b211ceda1aa72598cc3f9e1ae8ea3e5d77ccf82ddf8c86474bc0b58a1c7a3b89b05ba96f3bd2d66c48237be125a0f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cadc312c3f92ef48134d415c1a34e97de19abe06ed2b96ccc4b3d974ccd563e566bebe76e67877003bbdb8bd401c4c2000000000000000000000000000000000d7d610baf66d3a2e82774ddbaa00541d30862cbfc2f29b4a6dc24fca976d5dde8167f957d1ae7bc7e2c409859face3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154cf2dc88d1b9efeb401208434ba14163375f62aa02f0ac7de4828d0306c85554bc7146b17c68043b2c4b33067a26c600000000000000000000000000000000159030a1c6529acff9a9c496e662360b647cca03f3d00aa0eec639dd5572f0960ff2250a6eab18cfe9d16fdf377449011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000475cd1fbec7c172ac560cea6fd9448d745e61301014f9887569da845548c9b3ce8f01bc6db6fbd8ff6c84073c7f02a500000000000000000000000000000000131c69d5c3bc61d25c662133fffb9dbc98c01b706db4621e54437d3ed62902d56f6d5020aa2b48862e73ec7bc1a1778f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fee063b6c6734d96de1509759de9ce6679cdd953155a6d9ff70e3259441b35c8ae391f2ee1714efc9255ebc93bc0d2000000000000000000000000000000001790ef7ae78dd3fa52c332ca783226a707bba58ea78806d752e64e41267dd6321c7d42634e151d1fa1c4fd902776408a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017cf4a64601b9bcc3a12cfceabf43d5d4ff93d03bab06cae3f2cc19d4a88affa9e46465c1dce988b66d423702bc4bdf000000000000000000000000000000000eeb54579e8f121183a9787b22bf3b42f317da44b77965a19f1699326b73602def0d935f60d4a262a85911df81f8ff5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac22c1558585a06a2fe3942a28d79983d3be184de3da4e49413fa3ff94f4a0f66445b9d1c5aff5b7f6e64db59e3422e000000000000000000000000000000000558fdf3d68d6bafb253c424372bc5cd6d1f0daecc97bfe163e65962ca2a8886b2077b078343e67aaa7953af6ea85f441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000daec869af0613fa94aeaf448a2695c56ce85affcec568592dfe513a81798e399cd00732bf90dd071585bb9bd1645de100000000000000000000000000000000023a92a28d32daccf0c35db4bb11236666723c3f75b1b6b043071833618d4308483357193eea8ac52c11c41a894f44a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007d88ef9aa5eb670d032324a7aa389b936eb7bf1fc80a82dc47f49293ca92de5a700a6d8d37f4e10092c4de9e98503500000000000000000000000000000000128aa5e7268422ea5842fdc8cf1b634f04c001f9825b841b70e79f14c3181556ccffa998de98ad318f91f90dda9f36731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dae8702d9f1bc1c7c72b1fa61c7d26513904ce9ce0934385e9b3d613d517da539a1ba85bf7782b9ea7b170ccca2bee0000000000000000000000000000000011aeb40943f4fd1e37d64230bf258cc482b5222b0c16d33ff730e2dd5b68555a950d9b4516cc8ed8783319115b6285d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008904071d0b512f08371d522ce44409ecd053028bde4760422ffe63581a604ce53a303750fcb8c0fbc90b46dd982d7cd00000000000000000000000000000000179f1a5d2bf6a51e1b52daf88dcf17ebf0fe923d8d6ee356457b8c186bfc845e378dca77963ac31c9c1f844a5715d2a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149b71f3b1f2b0543aee0d862520cbd677f306cfeaccd1c7faa48481370c3ff0d39e3e170fd88eb25a72c86c366d24ae000000000000000000000000000000000c597594f26a0dba4f8d96336a43c7327874f9dfdca7468740e16ba77b935168b008a89f55049ccc54834cf9d2e6b9f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000fc8b28cef0fdd0b2bfdb48c022bed85689f6b6d76ddafc92ad800b1158c455abca778b9fd49e8c00977b5d2ca706f00000000000000000000000000000000048849fa78aacd30157693e47fd2157e9ea6c8de7b79eeebf8dc76be195a31dd5f3cbbc0aa3a85bf6bf0ecf586c348761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dcb7ecfce41f680a1c4340c9501c111c146ac5a9457c68eb4b77c62a162ba8c8b6050309083f31e3f6d8f2495dc9ee0000000000000000000000000000000011ed7cde426a5822af4f1b9764c7892849b33d83fe10b24e64711b89e2a4702085fbb56dcce3cc946ae033dad76250841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001537a9e86f194adc744154e6b7639ac03f754a3e1f9a4bae9ae17bef5a6b3a7c59ae73d363679bb9ecc88ab86c24272400000000000000000000000000000000168e11aae3a8b4b1c5149cbc08a4436cffbcd093f476d44c7d49c5551ec3a20279dcff50dbab0245048c8c06e45a16551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018154344c90fd0e427d938c9b1452febe277928eaccc4507397a28501f6ba102195c0c20c95124dcadd9b032024040f7000000000000000000000000000000000d587f2e943d436f82779f74e1978855dcada6b84d79238d39f7e55ca3c00f3b856e921be2e82c7a35104000d3a205e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d192f001de6e72b4b85e4b276505177d8298efc0b56d20e3889f5188d781dd15c08e7a616049f86338c424cc48c0220000000000000000000000000000000000d63383b0e872d454abacabfae483f6499c890c2a5b30afd92e38e08e05eaa6054bcdfca9932bafffabd4fcb299957551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009da375a4351830986e6f7b93c8cf2c79372573c0d09cc313bd6ef0ab1820f27dec320089e8746fce4379f1895e9575a0000000000000000000000000000000012f934629242edaaf4d243234b487a6f74ad1f6569226b40e4517bd31767be1a3aa4155feb9a296ac79447cc2beccfdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001914fe4b019bb63d75d10ccd25b78c3c534017c0e1f72911b21acacf0860579806ccd70d95269bb6a3001ca949e2bc8000000000000000000000000000000000133388ecf830695dac82257e0c376b5e25be77b5f5088519962758cf14aa49a27adaee2e465b92aad592b4070868d3b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000256c0fef8ee7284fea5dd2185edd290655dc6b4d08085c853eafddd3c4d329b389e1d4b7be5a2db2b5ef82102f38071000000000000000000000000000000000d4ef464c0b650ea412deac762f5e59d3e6b6097e2ed72c4f961f44fbae29f300e95d24db49550d65b8dc3177eb0c3391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fd185205b47a025fbb4a67f1c427e05dce5d163f6f00fdac0d4c2e47812fe0519b386bd2fafc46f68a445465069afa00000000000000000000000000000000105e05262097644a21def89751ce1957c8d1d150317a9b4bfb01fa2730bdf0e946e3115e316f07e233b1518f72e919d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143a176c2b333f6d2e19a43bf26ab8a9a3dc5a19bc2b71ddc2f08b8719fd32cba54d320e88f3b57548b7470b5446675500000000000000000000000000000000185498b3c2bb8f72766b46e1fedee2af3a91650e926947f65c61e40ba4a06d83f5f68016f21e1d40e1390f383c323c6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec1027cde8aac7bd034b60b6f17bdb1d0839ccb32262af595f15c0a3ced4c834063316fa0930f7f6c34fba15439ab18000000000000000000000000000000000d9b8cedb0243e8ce56f92be31a243a42bbb73a6fae3448c6b80417b18d0e8ee7048157d37f884fa66c0506ffd0083a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006daa65c099ac2362257b9bf1ea5a16f152df28e9526c31080f17ca785c1fc2c8543e42e8c5024fc9420e199f837c9490000000000000000000000000000000012589e7bff4cd73a9509e008413bec5f257626f2365075d11630cb8f167c3bde03f1d062ead08fa2eb36931f8e3902701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ed324872838934d5359344980d459e5edaff39eb89c33a3b911b1208f33763bebac31909e74d9b86f8fa276b4549d0000000000000000000000000000000000b387f9dc31902ccc58cbdd83c1d129e628c6fbdc8a180e58b14a2ecc3e35b63c6cfa85c08c4a56a0f65d6384d768fc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136b1e48073c265dd979482e55ae2de6114193e3b1fbe5cf3a1d5ed11d62d51f4bda13c32266703339f4cfbf357ce82f000000000000000000000000000000000b17e24e77240924321c2db1eb2941b570f31e3a31234d11c2caa86cd2436b67ee4c17dbdb0ce9cc99bf90470c5287d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dfebd57d40a7e0aa93f975d485d054eac9f999ea1409d338eb53d5269c61a7592e5cd50dd3561ef0a176e784d428af00000000000000000000000000000000106d959ff80754040502035e32f8773b0c00045068142469fbed48851d289902d70c97042a592087aef75a75d010c9521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1e23ac180af7f325eeadc38f4c3b9d37fb7aa9148817ba508ab16629b9979cfae24c65d2a83b64a457131c920dc9530000000000000000000000000000000012bbfcac733666df96a5c3fb321411c6bd5504451037bd32d0b6aebe7164a81fd0d70dcb40adf6685d4c49eeb75bc5501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018563149cebd11e8459fe8db1d3cb1acc7037fe5d5c308ad0159be183144966c44e3e7a8c0bf375972065813ba7a366a000000000000000000000000000000000d33ae69ddb61995d10fd4ff1592c5ad11d30561db476364e8386806ba2f047dd07ed6746eac3a754aa0d295972f315c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007e400744dd3062c24f397ab8c678c400a0366b14b7e1bc89b0ceb7390cc6d31aea0d3afc9cb32ff471d241471a2e88000000000000000000000000000000000c39a4ba9cde4479ae5b5db32c13dbe4bead8669a35499c2f009bdfbb879604b4e2387363bac076392502a6e757c8d361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcd332572d766e3a5eed58985c755b7c0986b5cae01c24282b20d1bda5dbe39f5cea1eb5a29212874a337d62a96fd510000000000000000000000000000000011849c12737b88236624c411e210f0a55b6459f1eeeea5ad68e287c8308a9e5e87e7b96dd5f97671fba3677f0c0b50aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000671300a283a9695b4aa3135d98edf4efa124f22503e646acecd877e6a207991813855032a8fca0b908ec7f05dde75a8000000000000000000000000000000001049a2e11fe6dfc9f194a76534fce4a1b99a4bc58b989a89506294cc64510f37a102c670ebf23e7c412c353c74bc088f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d1332404e5d497b78e44ab70eb8d5b981bb6230c3c1fc47f634fdf4d78fd0c0744709b92f9370c84551d0cc76bbcf7000000000000000000000000000000000fdf2902401ec6ad1bd16aa0df8f78c0b4042ed1112f69a1740da04e43315e6e14c06d0f73dd207b36f117bd3c6f871a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000294d018aa3e8129250af5b689737d108517e30da4f93f12487f7f57f3f5344222e004ac75f5a65c1a02e0d0137dea75000000000000000000000000000000001217ae634c6a04a46c17fb8666500175662c44fe7639f43a0a80965f00cdb844067c4797b4ef5fde14879ea270e3f6721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000519e13e91d8d2a0e6c657197fc96ffd26bd13d23c6e7a69ded5a95a07fe5c988879d84bbdb96ed3d4047cedadbec1d30000000000000000000000000000000019ba75602a0d92e30d450287930f5f1b25666ce235cf4bddd9e33ce439d8a1a2e1bbec54e20396231098e168b70b3d3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b9198d08399658b084bbdb04ba7e9118792f83a77bf443ed3d73ceaddf199568fa1407ba976970149fc9253804acea000000000000000000000000000000000617fe94151cbcd6f8e35420c9ef326dfedf10896059898a8c323591aaacc1696597d1b8d60275297de9e87ce74fd63a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dd3b5fa4439ae2744a8fc770c4a4aff203c6a49c0de485a9228d38fccab96603271e7514fda27afd4626ca92790c4800000000000000000000000000000000163e5107efdd6c749e18ef16fd5adbb5cf080f28c390f872dd6d2a491b4f4ac01f350ac9470d65c7decd66e3f181e94c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000404538485a8a30bea899b4a23ecd8ba1c38e2dddeaecb99e7a05444c31b9fcfb40489dbc792875203c6941b14e244c5000000000000000000000000000000001761c409e265138b8f48e399f7500d031e372f0138f3c6f5aa1823f444378ffe958e0da4efa481e03614c77a240a10881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006444fa17c868d3a94517b0e6a73153210de21811a22c46b2d9037a9a6c359a9a18208fdfb133093a6bb5045212b38fb000000000000000000000000000000000b537e55415bd31135ac89ad4a0a8191384944aee56ae517d49a632e8930b2f9cba38ac1db423f279add2f153d48834a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010918060bf6bf3046632b8f48a25b044fb3e51d346dff24b6dabeb4177843f65059d28657e956fb5465e9b06adfddc4c0000000000000000000000000000000015eea01168f52269a09c90518277ee4a97b0029b0e224d9744ee4faa7b38431b821cc597997dfd0362d24fff1871c2321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194859f3ea3cdc0ac42e403ef25f298d1060478e8f998feed8c2cfa83e7a904f72a7611642192c4aa6e43afe067bd22800000000000000000000000000000000098d51524e941205d4995cdad84157a6dfdc687c4aba3461adb40287481fb27c92810ffb53c62f364707ccc313ecede11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9bb5dc30840774ac873dbbb617bf37508846f47f4a1afb1becf49115025dcd0e276bd59f1263f2303e0003b8d3a39d00000000000000000000000000000000062de355f55abb1f7f63e6eb007ca4bd8d98abe569d64f132816c75265b9a552398dd204c3b38a9882580ae677e7c57b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cfb65adee3205e2592903cbe55c41a9ddcc51caef96a38b252d8dea589f12b6514bdbe8db75432967a0a3a046b5d240000000000000000000000000000000008b40b23f2f2ecaafb93db1fc378351544a74d08e335ab80f150b0ba7e7a382c91f87a6b05a2a6b3e15cd310204651631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009687be8156dfd68ef223302157083bdbb579cbfafc8a62dd4187f113db0a8fb0e8ca6c1edb2339aeacc6fb2f05446c500000000000000000000000000000000146edfdaae75cf331e0f21261c1bc1eacba1fefe4c95dd9f010d178a52a6ce7936b69e0cbe9dd749c12fb3b546a1c9bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d60fc6d90aa77e460d5ef1aba5c5f75319e8e88c8f3ede8411f9d15f7fa3ad59ef33c75df513f18b31e76fb1350336000000000000000000000000000000000f130392e2c9ed3e54df3d939884086359892f41d395b5ca0b6d4e639be0d00b3c329381f286313f7c9ce1775fb5ca661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001524120f1fb00d612dec222a775e85f9ba3a18055fd15258a41cdee77e1ba5d2ca56e7c8de5a367f62cc805a58d183fe0000000000000000000000000000000014c55722d24b4e3c99a21060c9261648095b591fce65f82059fd18e099663e86b951cfd3e229f44f4cc23615945ecbd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051f3aa5492708b02d5800dd5435dc920393ed23541886da0f22c8c235dbb4b3f263c2bd356e469fde68f306f26e61490000000000000000000000000000000017130e2c574d966452da9987c7832fa5f3b6da5d48ae4dfc34f05c084a23efb57c9c6a9bad3945331685fe12efe58a1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c1eac72476c0ab505873440822370908504f7f17cd3b88679eeed0b2599acf8f9ade3c1e509d95e8dbe80d758fe52900000000000000000000000000000000172af8a8f2e04c9c5864d7209d49f2b293d9166d57957823768d35c2114bf1f9ba057820fcb061862cafc2c26bfb1d581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d2a3957a29e0f726d603f944207f62d772a04cf897a41b795691c31c4667ab78ed733c22b7d918fc60b895572183d80000000000000000000000000000000002ae8c95b2e805137727b99418aba57335a3fce46e99079e7c1cd2f46c774e18dc18f7470aa30f8b2ed1b185c950fd901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a751f9a48c6c6c2fb4d6dc03c0d940f13d973a81460677b84b33439d3e484943e9eff6507a3fbc60a90648e7b84dadd00000000000000000000000000000000068dec6ed826fcede3907949346c1e864bab5211fae8349e0a083792036960b1963de89bca1dbf009400d59fce069a151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142d29d0b40d847e91262695dd8d532342e7721ff9c9913843c3e43e5cf7faa13d0f65421ceb327f0024f32aa04fe50f00000000000000000000000000000000180d1d8a3cabca93eda47ae7216984447e215f9106624b17f68e20fba48fe88f36dc5f4d5d8aec1408544fa89474e0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca0dc24dcf78c0a9903cb58790d7650127f972df175a796ce47cf754517f0dd3e52c247510fdbbd31ca512b1cefa77d0000000000000000000000000000000018c01dabd9fbf047f53d226d97aa54f4878f60733ac5237904e6142243e5e9391385f5a622f06530f9086c15ec3b89d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059e0a3b295890087b19f094430ac4edc6710dc7ded1e4431cd27c77272b6f2678acb72e1f882d7b183b3646eac5181000000000000000000000000000000000173ea65807fc8e52db9293b7499c7edec86240ece1dd152fea87e21360a01f54fe2e2d610eeafaadd8091b9434fa5f3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018ab2ada92f243926c2beca33deca75f69b82fb7f71a34c0f3e3404ecdf3fb3eee7b5fead5985f2c7a56a5f250f88da0000000000000000000000000000000014a2eb6e97fe92433af845604e23b1eafa18ba317599bb0b280ad38aedb1ccb5e0cd5453b3edfbcf2b849ee4528eb3311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007aadebb34cc4d77cc49645107fe8517034fb62c5e1d0f6d34b6737f90e932f357986781b42d6a4563ac8b24dea7d11700000000000000000000000000000000099ad77cb36a7ef863dc64c987eeaf207aa07bf36f23a9ebefece128cf2de308c1e39d41784e170009722bb816b268c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019423a4fd03dcd91bd01bfab813ce8cc583347207d762600a3038b9d2e932e9c5ef0a08d9154be79f4cd93323b41d0fb0000000000000000000000000000000013ef87e3e3d3719ca7220df884828862f154eb20edb9a743306afb84ca2e84596c473e013f5d5a0cb6fd63a1bdba6da71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f26bc4e9a5af09fe36525cee913f2a0ebdaa48312d264800029e1d96649a7728e4e68d7ebf131b59af13f20cd0fbcb60000000000000000000000000000000002098e5f2c82c005b9594a76c239fead57b8300774dda04f972f076176c64535206a5c46a83dc47907e48647e91dd3fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb528dcb0fa0afe9ba57f744f1cf1c3355a581d7193cb9ab571c7a29287015c665ffbd0f644e5e00f063e7e424f6fb40000000000000000000000000000000010b795bbf8782860a6775d7f34ca2a59758e9d68e7127a8ee15dacbb4a701ef92c7096859151c0af8b5b5941fe15ba821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a09736baae46dd67e055cb1e59ed49f5a2d3eeaff0741f6b9572cda18c08af9e816cdc9d283985c0964c41b70ce8f400000000000000000000000000000000195434d7a60e52cef1c6d42f8cd47a49363e2432ef7581ee6e003794374644b0625dbf36814f910b4a2595251756681a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005798ac4278c47d9376480e8fe1f3d22300a1b12b8b8777ee434909dd9040f7a9b7fcd00cb171e441a52614e0c1a45d50000000000000000000000000000000000bcab365ae0c01a7393efb27d013c5d78fe3276be7ca34126a1d109f0e8b006a3e1dc859881aa909fbdac7a16262a181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073953dbe2ddc59c682fafea7bdcce0041051288eceb83f3ed6dde99f478dec897cda2a0dffa27341d11a54ccae6b83600000000000000000000000000000000122735fbd366bd91fec19d737ed25bb7f1c93b96fae37e371eada8c3474dfc05c0711f41054e9fe985788d392acaec421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f5b9c55f62e97ebb4c0a9a2c13db0ee839f3595e8c8a8404357ab2a3a9b4aeef2ae808ee43f1d28fbaf19b9921c6fb000000000000000000000000000000000da39753e36961b767ff7c13a73b5a07f1d8ffb178fb96a0be3f0a5a5b421a338152163c7f84b9cbc03fda9f05fdb3751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5947c9934c8c8a782a17a383eaf0fdcab5acee9669db2d24526701fb8bec0dd2d235d711e1a5cea0b420c4f702b12e000000000000000000000000000000000da6c6eb9f20b0d3bdb3934ed281cb1ec47de1a0852599297a97d25d69ef9fc1434f63cd10677b07aeeeecee08772f1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f570e4e568128ff643b05bffb1682bcffe80b97de3b695f25fb8ef80a0f571a8e642c745fcd9db02ca301b522c3f2f000000000000000000000000000000000092bdccf597e4203542a7c9f062ce9e06deaecfabd7fb8e185b0ed127e862124915d66a1202e638a6d8ae34c4ceca991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000837c07e39157fa53f0f72fa6c0a5a301970a0b68f8977ee6929d6fe2c60adfa4a4f9bd9ba7eb744de8f0c1e878658600000000000000000000000000000000013377b22e1affd67d3e31112eb27ff14b2cc8b30ac0af07633e216e5648dd6465196be99a754259820cbf41198b290461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ca8ffba09abcb7b98080208115aa77ebbf4718fa593efd04d1ad9d1b6fd2dd8183d5be01005eac0745e835fc3c3adb0000000000000000000000000000000019f3ac589b1b5b4464bf7a8db892c65d3aa8c2d9dd554cf6499b85be03890189da67612537c31f16c37b17708cb0b4311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c845eb37d9b6a6470e19c7c2c8c8a080b06d53d33640fe2dc6aa5ad5480f817e92d822f62783946ad1f3735cb73d2d400000000000000000000000000000000052ac51c7ec7d920d6e8654e69e353c28af835d5c0cd74d48847397b1a7c626e27b074a223451d9d5d646207ef9fbcb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c394248512a006df665827276682746c5de1d173af3e6350ccecee7518d8b306dbf86cfc5b6a241d465656d38320550000000000000000000000000000000009b58a441e0b8fa142ea1b350e0997f4307c05fa9b4aed1b2076a65059e1aea7dde4b80846329c6f62975354e74791f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130b18169f6e1b9b35a730e44a1336cdb753ce2bfbf268bbdb11786fc343696c09c60a9abb4b474790979c79267fa304000000000000000000000000000000000158c48234f32f31777de7977ea71e49b8a93c032091f1577d8dbc1167adb453835b664412d442174b1d9de4b9d9582f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001d9db814161221103a7daa7f1e7957e9234e78955adce0169cba91063fab855d0e2996873b3e7c533337aa370e5dd2000000000000000000000000000000000797a60157f43dc6d2e739b1b63c337bf019337e097a5a2cd496c4b38305fd0278fa639cbe40f1458f77770719597a921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100788abc3ac86f54e64a0b8c91a4c16cdbd029332456575cbb48ad07a94b6cccb7e8e97c95bccbe111aad8949b364a20000000000000000000000000000000011b8af6e976ec1a08dad7d44cc3cf62de4b85a1e9c7fdef6994f433b661f52ff8dc5425e0a1ba2706634343812a93e141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001535ca6f5ca62067f97bbd091f2f1b273072a53080bd4d34a0c57357d0e0ffbd31dbe178ea3527bbc60b1db28a43bc7f00000000000000000000000000000000045c44c06f49908a38087ada607194813eb1f6e914f5c0ed2f7f046fdf87794ed94e046a79baa99fb9e50ee645245f0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132601bc08081104d1e3ac1e18315494a37ca85fa671d6d5352389dbdee649ad4bea8e05ddb1ccc5ac9231282092635c0000000000000000000000000000000011022a0683449868c381aca7f5899b932b6ba01f6a45f65b53e04eeccf013142a86f120fd5adb25ee691843b2686a9011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c65042b5e92e816fdc8f50bfc2d33501c319f73e2b9183b796d5bdeb519080d3b103a320868678c0145018aaca8de6b00000000000000000000000000000000020e22abf8e3e18bee6fdfbdc130beedc5a45fe69bf1c70e2028df0580857fffeb0bbb3ea7328dcc7a428c08542f24041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b304d752ecb9a6a5b79eacb25cb684fc05192276e5f36900f0559475523f0eeda27a3251b498f0118a9842eb46b27d00000000000000000000000000000000114b65d422f2fd77ae9913f194dab90e024fbddcccf4f19c911c1d67135ac542710770d08ce2366f7983502940e071f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fe122b11d0f5ac0b4c609998bafae12d701849eb7d8899cb9cd6059c0955e1c5eec12cff77889d88c2c219932275db00000000000000000000000000000000072480f02a37821b59abd3d07297dd98598593b9704a02f0d65db4404dcf45fc0716b323d454e1ccc0bcc97362f29d861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053a3a2e0467130acc0d78effd5ef299cac38d9263594cb539a9b567e4535a5e0bf54a9a3f67ed731b47d5eba3312d6a00000000000000000000000000000000142e232037d5f0c658a25627967f4d77c957b2388fe289e5324728657adcf267dd2b6c1b4c8dbba6815662cb17e4e9ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003987ae4c072ec0ccbd50884d7fefe0b0e67302c2bbabd0882deb5cc89a15d31be37d1428b2094d52121542cf21264cc0000000000000000000000000000000000e89a160a6ff6271eb530e4a408d3bd910f79d34c520546d43c20ca2a1761069d55ba876901becf355f42976c97658a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169af034cf6f516f76380d296069d6b05a07175e86e9c91fa6a4a48925cc41f2d5983fb088ba7274431c06251babf31d0000000000000000000000000000000014a4ff21fba7d28d32b1c3ddc6859695e4d09e8402e8feb8245a1ea5a59cb837b93d550113f80543dec9d3c1e5831d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050c44599bd0c9a0518fecc1ea22738fe2819f1303c483984ebe0a855936c1965ad64aeb5c687d91cd51b1fd4592ecc30000000000000000000000000000000000020d23d8742ba39c96eb91ac0b5043a19abbda297b9decd29881d12864554a2586419dd3935c4559de0ab7f73ecd441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014947b554cd6547338abf2207e63f763190606e07a14e6acc841ab7ca1cb2ed8a0533fcd20dd9961eec00daf1a54597700000000000000000000000000000000192df8e21513a584b5620e3192e27d798111a786c73e236582ab29cee644d033feffbcfce2b46687eb6bdee271e92bf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171a8fbfc4fd210b912d0948fe93cc5fc2cfa46f5eb014c0363f797b510419c070427691d1e943e0e4fd90edae759dda000000000000000000000000000000001775c5cfbeb60d20dfa0f59ce29ee5b2c97e9804d27d2ec917cd7662f7d9c3df6235d80bf51915700e07b7a7d45982f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4859318283d6ba2763bd2cd168f4a0dac50c6efbf3c127a56dd82a49a54802382758cf1c30026ec1e54d4b520d84ab000000000000000000000000000000000cd253e743b1dcbbc9520da24d0cba2fed238b789984fab90a9712ed3233ddc5010417d4988c54ef2f2a02bfae9ac4021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000258f2d15a4dcb712639479ec6252a78966674dd21a0d08360e6fd1a3122d090b84f3622e8a50ea68da5aa39865c7aec0000000000000000000000000000000001c8bc79a630d2795fd02c145094540df1026e82a59388181026d890abb46e5a9469c5fc3c7a9f948078bca5f22c62711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017712b6b2ff52c1f37b2eac10a1f10c3eb1de522e172e909480b7502f0b57258d4600fe3d149a4a14243ba72f04a9a4d0000000000000000000000000000000007b9e60073c0cbf28c5bddc9d1baecfbb0074d88163cf09daba89f7960af91427e40d1b22de74c9934a7228bba9b38911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001545b79e420335c44d37852c6660208bda856c6060ae7f17057d16c7570057c73c3e74a433d8f6d73badb4e2519d9938000000000000000000000000000000000ce6dd53e06f253e36b962e0bae79960a0b8db05fca83a262d58eaa21306d5a373915bfa2f1c3b26185c1760020265a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123983e746e8f131c62416fe3baa75d811d84c42dae0c2fbb981112892620d88529c75cba693450e27f9fc1058bae5920000000000000000000000000000000019c02a83862ae62b790214c220b2f23114c44968c98296214a20241b89ba01acdb04f5627f51fe649727723a25ed9f351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000040a2bfb0f3bfd7e44a41d6c19c1063d47e3c0c088ddbbcb580ef75834d8e09f84082f8af25683d08ada377122ba3020000000000000000000000000000000015873b3e3090eb1f5ef68e25c53e20c09797963025fbecfc9058946b46ad9bf479b7a77e8d833022ccab797631726e2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a572608e685bc3baa0068273293a7402f215d6fb1c38d8ea81bc99ff3a2041e32f38ea997cf9c16033e035a96543978000000000000000000000000000000000104d12c941f26a175d4ac36fdc39ed058a89025294e98d86ebdc39564f9da0dea8735789e723d4878a813d2f2c686651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ce04f999be665bd91b5ca7615949f9c9541af8bfecd17f44dfe1d2341fde5574f23d0f391455ff2968a4d443ec995f0000000000000000000000000000000014ac55dc41d33d7d739ef78225f5b770ccd2a704771f22291942208dfa306ab6145b460021bfd50653c772601902a0561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a3d12ffaa5e0080c74d8832acee016d7fe1a3f36f9e6c5402d69cede785f795d5b9594f10630876bfc680086ba1bb6000000000000000000000000000000000544460af30e2d06b4ff3189c4f25f88fbda57e63f5101b5658726e592516ea22a7db66a42ec0aa734e1dedd8f3d2aef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5c8461d4aa30d897c2f916e5691c52a07f35d65f465d00361da72dbcabe9a17190a4b782c4529619193a272c434ef4000000000000000000000000000000000ee2a2315e4b1b110f6ed63f83bf9dc94052e3411db87231dafaf438d8ca66f391a783d79ec7307f249ea8c006dc0ee31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169f41b3d39285beccbf89aa2fcaa7bd7644fb121396345622904d2202b68d9af6aa12a164d3abb40b77561a9d306b81000000000000000000000000000000001039b9ebc1099b923451a0a5602b0490121ddf9c9710fe40a526f65faf81badf306784fa8a9f8db4c47a6384e34cc5561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001309f591eb1ddda7779fcc9ed31bb27fa97bf606a51091b349586625bf18f4fb767b2cffb5177012110be6d38b3556c80000000000000000000000000000000015db62001cf4d8689d991d1b1e78bd4e4d948eb0b9f3b7d7b5b829467cb9faa9b3770180aaaf9183ea2365dbdcbf27471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5a4e188e69c9bceb3d4a9a4f4f83bf83ac7b9ec089ba53026db2e8ded246a006f10694a21e70c39f9aff1b4c08cb54000000000000000000000000000000000f1ef3ca42a2d0f1bca9abcc5366040650149745870e5e23b78c598c0d3e2ff3c69d808169e72bb3010bb41664702e891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099a5ec5b44b4a039b9749c6d2867c9d6a071a7f5e9267294d3bdc7a2992444a29312a54b8c1b2852057935b4707b78d000000000000000000000000000000001733cc053b1a977200bf8f8a122a814f62e7a737be5f90db07c7decaba7dc6ea4eeeaeafb682755a503a452285fbc1b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b65c7a7258d0a9d42f914e2354ef6d2118a697ddeb32a0abe88247850b55b71690e6f7df8081b1ccd464ce341d54c200000000000000000000000000000000181f47cd05617e40ed26995deb4ee4d7afb464b9e509a7e3e7969d17a4c4f0f1f2be81471b0067f764b63134019174321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dedba233dd5314bb6a5842929c0fa0c50bcb2619ccdb24d81f943e9fee0a31f21fad3f143234dc075aaf9aa0c46490000000000000000000000000000000001186ced9649aedacb91dfc479a78ae37651117aee96acc7794395c285653b14b897584d41672ec494922b8f0272173031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bd746de84a779815d28df3454a3f8ae86304b57f527c73709311edcae8a1bc49930953d1e33393b048b21f9c58d178000000000000000000000000000000000b3c42c7cce7d0f64bd6b1468548634ecbe30e108c810857143346cfd2c7f3087ac49a709468a600edf6f9fbdd600d4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001123c0a321ee41fb612d725243b62d9f895c5243b7b8f5af5fa9664d79a374f5018b1397507368a2e91f92fe1151c87d000000000000000000000000000000000644cef7939efcfa782abba8a6a7744e59095cbd657fea0b94a6a50b3f0b93d17a341b7609675e3e45e2affb08888ce31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cbe501c93bc5b65adcf4f27d5d9bd4148c27666f17e785295eb8c346dd4e48a7c677659751c6fef04d76f6d24c89970000000000000000000000000000000001f274a8e6e95e52759fcb89376c2aa9c720984b2cf0c501b0636025f814cc52ae6ca0c1fb2faa2364cab732c49c3eb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146f93701cc9419dcdacb86a5a66880f724e53af69c28e45218e0969d1add8faa46025e2009ceb6482c1dac37b249fe10000000000000000000000000000000006e39c2576aa013b7b108e086be1e860bc7675de6be454bc22c2106c439dd52992a7c06a041ccbcbe0abbcca35b8d0051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b44d67e52b901733866038e4a4df2e17d691f67bebaedca0259bdb2b3c44d5a5c75c5dd309b8af49b597b246c5cd62000000000000000000000000000000001117f136956f3aa97997c1f773d098af2234e838328db138d8150dbd3609294580cd9fd097913cd28dc3b3cee664f4691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aff41cac3405d006e43cd0a0ab4cb861ebcc5836083bbe657e411add94824c726c9769307025676635fba220722a0a0000000000000000000000000000000012ed758472ea003c5e07e2c064b5a009215fb0280d2467db05e33d7bb28c98ab9e565191ab0ad3dceb54be08c7199fea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a3ba2ce76af954f2f9d5218f9ac2b9d4933bee3e303225b84e408e89c7c5920efa2a7fe2be82b6adc29b14f425ee4d000000000000000000000000000000000cce0c60fa0c57cc9c6b8586b018402ed7e0beae1654470092d7aa8c023c657298f68b784c1a294d0cf1e6d84351c1441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb0de7dd2cd1cf1f27351cc04f707b1fcaa5159b01f507e19ea425cb18c09dc343de44aa0fac400049d3077b1338a320000000000000000000000000000000002bd14688804912462655b2ba970f481d043cc357594eb44f05f0390306d4c9f0c82347383208a71a977e696cb2730201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0a07cc3229d2ba16a73bceab432fbfda17ce3c526782b2057ce650c82e71c15c5932ce87a7b92688f39daded4c77d700000000000000000000000000000000050a1756ce9478e7d80139a09ac041591a5663a3874a9ff8d992d6b49edbb0ce475df923eab24d19b56e4a75878dd92b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d74df3789c32f32decc8c68b94cc9c83346b31b951466c1b7d42ff4be45c7a76d5da33ccf157769406c4cc32dee6ab0000000000000000000000000000000009f25cf34570239097cfa720f8101168e58637ce0334b9a465bab906dffb96e7544a05ede469c4d3368d07d3e811ccdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002be1d513755de9e26f70e52f5f5dbb82261f6ad430307932b586f3951597427b8a2972ee28ed4d00216d95b1b59d2b000000000000000000000000000000000291deffc942625f839f2b4306f682aea47c997e491370a2406eb2f13cbebe65efec19af3ff606ebc6c3d7f465cec9511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a38daddeff2e822a39d66be80063d86442be0360b203dc5dba189cdfe731b7476db335a1e2351932b2dda77256a08000000000000000000000000000000001380f6bc349145f90229aff6f5c7ca0afa72662d37058ddaf36ad5066b961fe43923ac6e8c8e29b0a0fede5a833a78fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186b7559098a8832f57d2471f64d07ea0fc5f43e5957809ab76dbacec9d81ba37ae59b54eaac9ddc7c20fa866dd4b0e6000000000000000000000000000000000caf4a4e9a77528af9781990efd1c554bb7587073f1446e09800bda26f49932d93b042200f93b5ed3c59dbe9153120f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001495f4ed84240f37f3c6924950846f40f8a94ab2858f27b7f14bb79b5b55d37f27e3db9069a5fd69d146086cd1738502000000000000000000000000000000000c2a450dae6acf62d965c2281adb7360787c12304c83df50079a449ec42d945ee37ded1d55e0c325c3059a8861ae6f8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058f004d93ecfa600e871b0e02e3b6b9f144fc955ab8b8f539d647817de3b8b1520effd22b734c8d05514578eebfdab800000000000000000000000000000000133678f22607bf79ef764e059fa4d22538ba0a9b2e17c40014102bb2c636645e2963164575fa928234cd2ef07c522c9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b317c96dcca84230d676b8608bbde7f9ebbfd505f82b150138278b9326bcc9566b17b89f2b8d95decb39c2c7c65dffa000000000000000000000000000000001124165dfc607df45515d41af9d80f28c081b1c5530b3806afa03f12d43ab1c4b958d9e76c2e31e4b074f82782add1fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014ba91cb74e862a75d94f1096ca68309f475189ab4eec941843e465a1e7c8afccfe91a4e710c7d0eac906ffd51cd13900000000000000000000000000000000090a6f22f56e1cb8d23f70506bb42538009a03e6c51cd087059524e440f480d6adc48200c95e1970a2ec6b28f434d82d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069dc7c55387c795a802da58174eca9212e28b9f635dbd9dd40e6872f4e14f009c8a3c6c8fa3095403f50f45eda33ef9000000000000000000000000000000001637470558b3f448d742363454e3ea9aa816ef9070e47ec34e29c065da87309db31e1ada1afd2826efcb72d241f99b111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000334640b27ceacb7f39ad6f2a9563b36578e428ec66722da9b68ede088259563c83209a979cd6ca27b6064368b4c3b7300000000000000000000000000000000160911767d155b4be6adcd4ccac95d179a11a57a5c502d15b0ce47db78b36ba2b2496e36a1f5b9090a1aab8803365e981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145dd43cb3fd86cc6a972c7622260db52fae18560090b19a4488de57e3e1e48516df4bf5b6d9ff2acafd21a7574869700000000000000000000000000000000011fa08dc6e569b4cff923996f9d5791535de7969a71c6e96c33c1d1cd16ee8d5a93e27be604fd05a903467f82cefe2241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f9ea2e119a7b76b0a0f7a5a12182118ced171213423fdec86c0481eeb96eab14a38170541804347b5e9d5c601e27b900000000000000000000000000000000038e2a21e5e969ee39eb604267c551208821e562861af45f518e38537ae36126d4ab1eebbbd9b8aebc7fdf3e13a5a3d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bc72f736b9fb8264505ba322b9580385955e2d3b29c7f4e1e66438ed4d78832dbdf6c08e9b99456ff6483f51fe349f0000000000000000000000000000000016be56b1b622d502c4601c70866ce96dbb011c56d59545270d31002950f296bc42e9657c2bdcca36d5e32f6606ac0c1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b430c3990f64fc049b99505f9711976af7665329e46a89a5db107b805e1f9156c2fefc471925fa1f8a2d4ef2d53994f0000000000000000000000000000000009c3c589fd456d56f55511f3fbec6af1b070afd7cafa7a27415a723607852954103c0c4b8f25f6dd5ec09ed1b580729a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bd706c6cec82fc45319f454f158fdc42d8df01ddc79d245daa7545a9c6aa687a6410ab53e26b69b0e9d98b23021ad60000000000000000000000000000000005bdb89cf1cc55f51088eb9a573863f6b6c0d8fbdeb4902e55fd001b157dc6dc793b95211912b04fe2dfda04a03699361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b766c298b5b1c1c31acff294e1b73240e101045f82da8a353a0d2d19aee9f2019ae2b3127177db9ceeab6dfb0235ab0000000000000000000000000000000013fe14aed2f43634ea56e47e6766e1f70176b7ef048463280b5d6472c1ea61ac24e12fd40edbc46d1baa0aa9e520d2431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fdc3bacfe962f6abab42cfa5c5b46025b04ab144143788bb545ea6f41b0025bb7238d7ab1380cc73a42bf46979a816000000000000000000000000000000000d2f4c5593e4ffc6bf38942500ebf182a757b243fe8a68575ad4c83866cd0b27eaf5bf13c22299d2cc50005c0d3a41031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c09431e6bb6e3ff17ab8562bdc375f1fcad232006c4648dd2676183cffa5bad5eaa3bf44f0df036d8e1990f0610c6c0000000000000000000000000000000009e1ffc59b64de9f1313b842d9778fc89917c2cd2e03f8c3532a558f9f4ffad7de532ef91c9ffed39fb16a31238880a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009460bdce66b93c899f21cac851ae3ba055f4b5c2611a2c837df9da8b382adadfaca8e13982e4eccea663e74f7a7c5f6000000000000000000000000000000001117aa9a960b7a7ebe773f1d52b895c9428d23d55bef4afef53a9cae10c851999436ce812bbed28a94ebd0ef78672a561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012aadfb9875a81a8e98a3bb9fed98cf1d353c3a53f159bba8caf5bde402a4874f94bb9a3e53a4d39b83860e46a470dd30000000000000000000000000000000006d1d36ef517dc15596b5eeb39390a8389d931c35d0a611235897855a56e3c74d3afceac69f799bd702bdb85e62701c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001242686bbcd118b4a980faddd057d6310c341243bc050dd9d028d7b18607f74e0390e209c58e1f1d087011a4283fed97000000000000000000000000000000000e1a057f838aed63ca2d0f859c784ed93737d67224ee1dfac52bf6181f2d89f77e030773a62341620b192716b4d1a1591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bca58037997e802aaeac3c83ba8a45dfee792a4c13339bee768ef9625dfd8b90aaf3f76fa70637714d6ec253f53f6d0000000000000000000000000000000008a3b27c350e478eace79276604e38ffc2d2e39238870ef47e09375c4d8506c78017ccae65c63ee3005d3464e58a79091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000816d97f86ca02fdc08ca87f1627f2c552801cf9bd5d6284e5b0a5a4662d1992026fe430ee7173f4455f80705dec2e11000000000000000000000000000000000fba960e0fe33402697011d6c5db6ed7391db32e59a16eaa3d7a7bfc15f1c5a6eafa5808de10e845b93c2d83f117a5ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ac03a9555897361f01a2b1183d13ba62d01581c9d90dcd8f5d1144947c231ee270cc8c9ff05d049bc60f00a569da6100000000000000000000000000000000032a280182b7f678850f1f249198dd2bc52f9f4e708155d1024005ebe4d16f0f92017d24f44ef87d5cd6c8857cd52e441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6e1db8322876a1061f8b627975ccfc06b869772b01cae1ed152d9140946d9fb6b7dc9366daa054bfd621b0d792f6d200000000000000000000000000000000193dcd1f35df631e6d5328b4835747e4f10b26d8f95aa896fbb762980a40ccb3407be9be85e04976c50aab0eef8b8eaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015223b77f13593ed99a560a4ecf4ce2e96e451a379dee462211d982498fa22e2878fc6d624583a694ac00db4340c12ab0000000000000000000000000000000014c582e2158fe485a533bd3f95c3f060ad70b8dd956383c84971e7c0f4a5d5a57678bdc735d1ef8d8df8194a69533d191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfe96b343e367a6bd0180f7459eaecc5402da1268f8ccdc7f89ac6d3c492f4e386068a73e4d67be06956e8a3a988ddb000000000000000000000000000000000f70f51cf54d25d792e200357ab8ca6b38493820252f540249afb4974c4d952aaffdd3e3d3cbcd0c44b82b1320078a0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cd91139278f06edb6a0ed8306fe77f5aad91af559491f585d9862588351120d75082e498a954b6343fb9bb857df3f70000000000000000000000000000000019f6d2ba3ba097c117698a349c33edcfb131ae7067aa1c0f299642e3f7eab42265f2e8a4f8dc09e4840c82834226cd731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006451bf0cbe68a40a02447d126d4bfcfd12121fad1f70da60c74b89f051268d40169697ef6244fb6d1e6c68bac7ce5cd00000000000000000000000000000000056d0be19c73b8d85c57120bb616f518abc2ff388fe748201146157bd420028ea6d83c2400ffffa7f3091e55dc577cfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da1ee24cb3aee7977d34f5c9d7c8ff0cd9f6858ad6cbba73cef1da7bd6e44205e39811ac1869895f48b25e5fd691dc000000000000000000000000000000000193e25e186229fd82e1c9f90cd6e3fbf66b5ce365b9cc86e9b9a6df10c8365b0b80660b6c2dc285f2d9aeee86f4cde031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d9c6591a6b05cbe2cb01c4b137cc56017b7506c8449b909ba4a7d6a5da39502e059f36f48bfaf3882102078b72cabb000000000000000000000000000000000512be90a1ddfb6896ed02baea6a21b14c96b6bafd029d4d4b353548c4b62b16db9c4331bd4fd4b943b04a1457b63fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000641ea2ac241b7c3899db22560c267a409f7ab591cc41f9aed910f9dc3118e90ddad82e6cec8970235227070e35f0afc0000000000000000000000000000000010e623b9d900e8f696f6d2a2f7883ab02ab227edeac7be8f741a8bfe07eb0b0d5731e974ed86fcea0c2bdbf82472415c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044eac7f50ab7c4124977d18ad487f1dee7779bc5c6858a66aa451bdd83dc1ee23758ade3eab2c236caffdc5e5cb8ea8000000000000000000000000000000000c2b4a4964cee0973deaaa9bd38c70096e3756b4afab5a64bb00109fd86f3d4382831456cf9c169b1a8c9da769dddf4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010dccd3bdfccd782f99df445c3395bd3f420249d6074c83a098c49e978bed4f05ae9758f9aacf966701d7b0fbc065939000000000000000000000000000000001759db1e40e54b654b270b6cd5ef2d92749e12fda43667d78db17b4b9bd8968bc78771656c9101cf7ea87f34bff73b621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001917c430a8d61fb3c0cc1a0915c9652d733171bddf4f13cd87a109b192d7b671a9d6562b4a9a779a2a36bb3b0a24e4bd0000000000000000000000000000000011ba74f7ab7861e2bb4a25c2c5b86c26670648dc9d665eb6c697c3f0f5acd13cb951aadb52bc37f49708a46407385c731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3fc9586354c14cb338465ea2334e7eddf404fbe810fe1a8ce10fc0b7ba0a746527b4d4f3d796af995e46d0236391330000000000000000000000000000000018d168a3b9ca279b9929a3e431776acb119144418319d7d2367f6b44e5b94cb7ff640a45da61d64e0c9eacf4f544e9401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001571cd3eb9563be1ed5f4da12d182a1ec284a1f5afc08c615c5716c939e831dfddcaa47dab7c43262b671a8cc7d7728e000000000000000000000000000000001381dd080f0f39e6ffa37ce5568aa269efbd2f8c9ac02c8c3e98f5df21e728a67521a3a4d730ae96c5ff9dca0f8dd3b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000761236f004ca82fc189ca57406894a83f663c4ee1172318e9716bf3897d5299e2678b39a62d5f8718c4d8d92bdaef0d000000000000000000000000000000000190f03b4a1210a7f3a4486138c85f8b04f7d7e394173acf4115d7859675505611b055de029c0462fb0faaa590ae33231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5cc0d3493bd4746057bbb071ffd65613865fa918271fb95e33792e2d107b45abaa455624c85bbe97d20f810f737d46000000000000000000000000000000000a8ff632fad7388e42eb77768ce1c3730182204121505eb55941ff9ef99abd6e5749412488c536ea5fa5beaf29c7bbeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047c31805bf51c1c1cedd32ed127e6d4db09d7e36ffe8275a16028e047e2a45583047d7c0bdd93f6db937d7b88ebd69f000000000000000000000000000000000a117b6a4d19103d761e3698589695cf4d887cc99df52f4a4e168c72483d1810642a4f7f97602c286c9e9b9ca5402d7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c1b84cd981f7fc4039d1f79a6de0bdb1a12b7ef4228adbecce80437d64a558e1d67328d5ee230bd15ec59b1fc8c71c000000000000000000000000000000000a27d65a50887a76c51459dc6b8505ebbf31b107dea0df9769eaa379ac6fa36a9f145bc53000c6ab93bf9367421e3aad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dcd6f86494811936f04672bc836665d647cf5c950aed50ffa7ac96fda78777954cbca957c5a0f5352355d4c234dc7f0000000000000000000000000000000007a128a0f8283d250d12031aa2bdfd9291bb6956bb86a96e2483f866e065446d3cf3aca59fe2f3baee3202f5c538ad721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013093dc6037e82f03f8b9e40f18005ca9351896c97bc536d1ef04c24fa80a5a826e3faa7298a5aaab5bf451f93522a510000000000000000000000000000000015f44e7b2a5e484a3328fb0efc9b1c884505e8dacd22e025be898041196bec28f8d06d727981ac9bcdb062f92063bbef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f595d13ae920b25e61cdbada5d59b70ec116616e9767e7d9f900b1bf0f9d770c68fb32e314ff40d4c200ec8b13e2cf000000000000000000000000000000000d0617ba8f02ba2d34b5bc7485a9722a241eb3ffb0d94be22609355c6f91d646952e8dc3b63fc44f87cdf3b40cf47fe71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001690c65ee4cc146eb25840ebb0f31aa074cf6deb582618d20f235de27d60cdbcf4ac1942e6c7ce6d69ad4ed28c8da63b00000000000000000000000000000000060109dfc9f340a3b8081e42b2acdaec27c981b4f3b555df9e12e9fa5de2aa9c53f5f72a64c9244de0c2958d99b4698f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f940d38f06d8019db6f403aa9b6305f262209e65de106e7ae15a9ba7256ec70593dd7746be248d3ad4bc4d77ab4df7b000000000000000000000000000000000b028f3807032dc37788a19e4bf6de8d90df899467af06a6bdc363a5918c78e3846422dafc4d56e692d4e3c1dbec8aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4ec361ce4727321435db1db60b15f22815a867701d6ee270575ccb0c299abd5dae0dcb6cae3e18fccb1e0930acf417000000000000000000000000000000000d27b8174707ecc37f40b07eac828668878655971e20f1e4a3c427e1d379e22caab6449af4e26f01c6997e9f42f000c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014991150fb8306d94717102de8d30f76a1c074898a3d9da8df8ca8489902635b97ace62bacaf4bd1092be2d7781b1eac00000000000000000000000000000000070acd2dcec064f5b5c72dc1b0f6c1bf7a964106de0d292c2efd44a7d32152fb064e01e3c91f8d60920b9d9889a4800d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116a924dd6bbaee3b26f1c3b16335ff40f948fc9c1fad12a35ff437f2cf5e68ca7ccdc975c6f953cb4d0a9274410db58000000000000000000000000000000000fce9dc655e2463eb9b1868872e210d91b08bfdd5372cf5462a26f5a83e2677787ac9e2aef54885163c64407e3ea727e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000509c0b1ae7ba8f4cc336b40fb75bdbf6c4a454f3439f2d40e81589c614e7d3324314d25c1d7d1351eb2892c4a3d11a300000000000000000000000000000000149ec72c38900ce863e339a5ed71364b00c96217f4369e0de623f1f291e1d2b8144e160642dd37184daee8afeba58cd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5bceb1e90927091326dc60aa97f33b8abb59aebc0539a001ccd4d99b738bb483b7373514d07cba9cb05dcecdc04131000000000000000000000000000000000e47917b5ccfbcc31122c022b176d72e30793ad4b6da694b61f2d91339c76e37f0893e90a83b80afe6fcac61eebe11381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000789d54c3b41a7af487d63e53c69ecfde20243332af7af1cd87ad02c758c0848af8644dae5cea1cc269ef31ee576caec0000000000000000000000000000000016bae18a053de086f1ea73a5bbbb4e6e4a8e59d8aa7aba8f9f4fa1f5f5ab9c666387fd9ba61e6a25ead44d9d5b68ffbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190a8eedd9b92ff81438e2a72198944b98a167335044b84bd7dfd1fd38fb958fd7d045baba2d09daf9701ef11ae48a6c000000000000000000000000000000001954d59bb07d501850c59c0e0d946e72930958b13a4b7f7fb322e22bd53e0a3fb0644bf5bfcd66bb2d809db465c370c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a008824091f1229c1ecc087e73f68e4c6576675e86e2afe283097b38d93b8521a06c5c829c63c358a2a0c1d769e98f200000000000000000000000000000000173c000524cde4e43734757d405e2f22c79e909e14fa4c719c6e859c0b40d463cf074e0da3e1880f023ac034713f0e9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fdf243d85a195df663e7322d9d135f37f59ae5f3f7af112a11d05629d8d65ed6b772d77d8ce546eade6c4bd125147600000000000000000000000000000000116a4162238cbabdd34690689ea9b399429e9aecc9dd59488e53f86b9c0fea97d397d6ad2e631e90644fba9fac4099531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f5a2aa5d92b42ded42023c47060279fdf8ef79df84c57699386bceb38af360ab34969efc7b9bc4af14ad22431a8be3000000000000000000000000000000000a0b05301a23621505acc5ef06bcb7203dab95d0e0d6c7cbc3e1d399f536971b446feb25505d3e75ab8737b7a8bf98541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011354cc92d4f7fd7de00a85d6eb4653f33c81e081a6ef54e01f34c3880c11c7c1985782ad0532479d98f8dcfb037e5c90000000000000000000000000000000019619487ac29c5920f83db694b171257f6cc41390c3459bc977efe5e3fe74fa08de74a524824dad334ad58f2fd7c18cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004daf2b6f83593a45fd4838d26017292e36023a1ac8c7036e8fdea3e99357a07aa2da19543acb0496ade188a25adec72000000000000000000000000000000000968158572c40e51d91094f14629b3a4e02431c85538a9fedd0e08d948dbaeeb1941bc68d97699b98eb6ea6635f581431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dd4457b87612ecb6a205a49f0be84d4fbf75fdb4968816d8c1c92b19fd49ff7bbcbfe73ac499f7b602b0a8925a96a80000000000000000000000000000000007042123ae8708a8499fd18d6fa92ca672b41bd372e550b820428820db74b21985322ad8f1d3d36536cdb0975cc3447b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bb0289b35eddfe50a2678af93fb33a0248ac2ca00406e9f295310e5d036c582127e3549d504e1cf151853895a60e700000000000000000000000000000000002ffdb08dea599a112784e333799d618a514d18bfb95657f4d97c23f5d17b4d8a30a97a25a59c1a37f7f77d3995e99751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133e4a31151bee736fdb3d0172f34a3084b4cc055ae96aa25dd910bde976d8d53ee36e34fce2034faaa7659d974e80c1000000000000000000000000000000001794089cef87d43c56262f4f5b4929b1ecd5f3a6116f1a46d7630ec2146bf2721d9c39361418b7fbaf51321de53b241b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002143ac4d66382c831dd0bde5c8d620e728cbb92cc2b02611f69f0ea895f44fecea96c599da45d2a9a264d756719030c00000000000000000000000000000000089a7476bfa2dcd26e29d3ceebe3b7411ae8205e6df1171b8cae1553d83ff09f1fbf82db5b08ca64e9c0e2b5acca2cb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dd8b8f3be4451b3d371d7d5d663e950741deaeb6488e0e1912b983dcf2938f61cafd05e0d135df0af23cd074264f5d0000000000000000000000000000000016d8f1df9cd54fc20486557a2bfc59b0eb0b89a4e24ff2aa4016dd1eb07e9430ce93b3b17cee24c4db3456c22875e0071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d81b20a63cc524bd3c93cb7dfa6d8f666871103f5999693c966da8f53784f2b05e51344dc2b5aec2f226660382e4376000000000000000000000000000000000267a7d07c557c24e218a006f271dace8259acf4adf7c965ba510fa2714c68206d0bb6d082525a32d8aa820dfabb8bc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3d5d505b8ddb8f6b6e9ddb39c5e7feda63ce1691ad47c22b9acc4895272f0b5a46d39d18bd8020303eb1882e671a3f0000000000000000000000000000000001950e22788144247a8a2e2fdd2dc4d22e529f5dd165afdd9a80e84ffaf602a88489a9cf141227b91b7df5b92b59b9961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010055455028fd3b5674a784e874583198ae38cd1a75d93175644d429ef7b940f5e20e9b0acb36df8d2714bb9627b363300000000000000000000000000000000097b3c25bea41b9325c6b4b9bf5340c804571108da83bd1e0ad04621accd40b87d2ef2c5591dcd7daa3da6bcdf5c45701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af8758d4b9518c9a8e8a1746e0f2a7d2b21fd9e3fb4495b4d112c251e76e882d94761c7e6fb055bbf1ef957b68348c00000000000000000000000000000000002f4d5b89da6542acd368057e6e1c9885215a73604fe7245f02e62cc151976ccc35038ef08ef97ef9ea5647ee38f8f1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e15ec549b59ff5961fd1ee23b8ffe533e8f6e8382e2dd84b57228405e19ae3bc94db0abaaaef62aaa2475be46c06be0000000000000000000000000000000004b3a39397bc04bcd5f114fa17581fd714409118c5b74a1f5ea45b576afad2bd50a9524777945605a72ec41a549380341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a87b0cc4f9059a5b548457b216907982de8ea939d79a83b2445ea45f0c6a2853e1443b78d0e7a2ed8e111ec33e4db1900000000000000000000000000000000033d7c045a5332712dfb33cbaa1a57862521f94af5a84349ddf15f2cabb8eb040226df2ee86587a6b5a17fe4a204ddcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001213bc3358e2cadbeed872e1783c5786fe80ded92f12753e376131bd3961874f83c18aa8ebf1daf89dc6854ac09698ff000000000000000000000000000000000775ece57afd032b36cf5d3e9ebee0121b3a667927a8230cd109b4d8c83e84a67ae09de9d17467656220ecaa44c66b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000394d17090718ba504f748071688ea9c99a4c6b4f37b79bcd7dc329592f1d8b492c0e35e3e660d5c30231d6f9c0f62b4000000000000000000000000000000000ca6b54ab44d758fc8a0bfdd57d13717788f9b0672b5e517fcfb2d220da572ff706524b7d247f15345936a223a5d61c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c75f767841c115f5f91f989afbf3851a7983c9228c0d0c22e3321825cb9ada3de1e3effcfb8f2479bf07530ab53b257000000000000000000000000000000000a96644036b2b81bdf8e8cf447df975440ee6421fd13da85e49546c08d9eeabad391621b9995d059f6ff0b7508b61e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d500cbd528194af718a06c86281bc02ad8456182db78be7073153112df532ea64321a6182a907c6e0720ade5769dd900000000000000000000000000000000057b169b3bca558b891662aa7c28741eee4490447f38dc4c4577ed785a952410258b420e895d3ca116e4efa16b8d080e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065ace26804907d15d38a507b272f15fffe9fa8dc5d7cc1cf3142f93f2d0c8d1bc3a5bd144e0860ceefbc96a33c00f210000000000000000000000000000000011adb2e8c6a4ea8043bc1c4778a3572b63f77de43dc9218a4a9de370cc82af04086aeda0347685cbfa328f9d07d8806c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001507ace73342a2da65f092540bef86f5402633c874b35fc91dde21eb7338bc88aaad1ed82498e5ece65fe9f56323ed43000000000000000000000000000000000c6419b62dd59bdb5a2755704b22dff1249838c02cde5e546a14cfd3b7804efa9031d6c452e3d376032bcfb268c547861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000477b1e258c964d7b9994bfd3f220777641d54d18b1c0643f924aa895a7fa46ca54ff1f1b54d2d6f1ac85448a1f1e65b00000000000000000000000000000000125edbc8bffb1b884b0397138354bd87e621c4825caef64992c4637d8869156f71598ef4682b897d59445891663d2ba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ca65c93e679d954e4ad8e71ae1963db5793dab99f4391a0c4c4f3e91f96a7ba7d258b682f38a322e1ec4eecbce5e8400000000000000000000000000000000161bb3e53d2f40ae1722446802c684b1d76de2823f146503633f99028b1cacb136ac08da25f5abaf02b65294db41a2061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c8cfb68f37f2130774e8eedfdfe0eab62915d37781ac69ad61af77130772df3337b0364081d8834285db6f7dffbef10000000000000000000000000000000013d53cb14cbd4f6961fe6e72889bd547dc004bcf8f35d7e0855daf58599ebee9c7f858045c83f705fc7d03a8494239f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001609400fbdff7e752e83b75e309f0d0a30c106d7ff4f39cdc88998be3b4c39687a05923d386927687b7ef7f3758a7b4e00000000000000000000000000000000054737b20d664a524f47917188427a53d53adc1a71d98baa71f2d94b735ebc0ad1d9a85f036a2c50c3c5b912cc253e4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4b8e8372cfddf6b0ea29befb93538da01430e3f0b669388b8c51e7298692b2b0823cdaae3568978d507290b0f5e5c8000000000000000000000000000000000c75f72e65cdf40d8aa1a9d3814a04fde3934e941d8e0ef21a055a5442f9954122dce00b0dc6c5848ecd3097b2ed6a6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055fbdd3050b150a8cb5960af091c4dd2be8ee913ad98592795ea9136f055a9fd5da7b2ad7cd46b85d20adb5dce4aca80000000000000000000000000000000011551e409b3eeb1de4e90f864e0a74679c8a6fa13b6525d55a290fc72673b013eed23867be9ba2a9b4b4020c8c3c68561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002690104eae5966a229f57acf3553763004a5091a7ac2d0bfc2be4de3651442a3a110a1372b5fbe036370d45bc2f6cdf000000000000000000000000000000001637a90adf9fe4f43397aab004ec584b2b9dedf41412e4a0b1970e4e1d125653384f1cc4a4c6681076b57acfa1d58d311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c545e621d2f23032a1b64dc393a59cbd05cb4ff1b67f47d6eec5f81e589baa4067042d7cdae9f7b905281a43ac9e580000000000000000000000000000000000dfe8e70066690d20381aa4530c5d6368d7eb23bfb2753514956537c2648a83eaa4894efe4abae2f858ddc0575a060f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a40440a688848705b3e3f9d3b88abe3da0b3250ae5316e32b809e81cf3b9c94a3a068a1da33d90be961bf612363e510000000000000000000000000000000016f953a1f8e1df494e30df6d20f57511289dcdddd2bb5495529ff574c37718853261dffa269e8f7bae5d3a06e736f2341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124be474d61ad446810a831fc1d3fd47b4821cc915c373eb4a5a401037a89898ded96061a46c801206658ab99b2a9c53000000000000000000000000000000000df266ebf2f428926255fb74535c60ac14afb2d2a952cac47ecd90f9339350bbce30e2e9e52ddb1910916395afde99571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019774d7ff59a2d275eef8ad3d311d723e314184d6151133753c812ab9ca7794d33e8c36c03da51f127deaf2f26dfb1180000000000000000000000000000000006215eebe30d4b30756f9100f5085b50a2952687c287d75fca6758f657ebbd047ecdee68e8f85ef35f588283ef62220d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6b91efe1a4ff904f5e62ed5d46b3d4b5061a9be68929504734a0ca2d0247ee515c80523e0c8e159f98c4b931071c780000000000000000000000000000000002a219b88865140e41242a2a5fcdd443b0d0a631f856f6bc6135f90fcc8de7d3532234df936be7b2bf3fce5c704c877e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d737c22e18090adba58845d573de5c19033384586e3c12f2e357d111007380a5f1b935dc3273fbb5afbd0dc8ea114570000000000000000000000000000000012977b4ff957defa0240f23e456c7cd03da86f3b2d764f92b3cb7a5bde126eca400258b4c77ae1277c861f6fa6b421831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ac96b5418e7d87c4368da9a25a7fddb71f4d7cef07b7c73fb98936fd32020c03b0f904bfc5cd84012a85ac9eb9d8f3000000000000000000000000000000001856c8c60b6346cc8b2ad1b5482a5a30b42c43e37a487f4ac2ffb92eef8dc05332efd2a816ac591d55ed7663ee66360c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f98b89ade1afb85828bfde0efccccc0d4208ee107f0d32987ff92fd2ee7526939b496b36be5561c9350e6c40d5398500000000000000000000000000000000046753a3c7190ef7b0dad0b73d4f953d64664427d8e232b0a87c77c69b775eb4a35f463287661667a5f0be9d122b4b231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d1dabdf454a196de199eb35ebedb3dc138a9ee2846e6fdf8ebc604d128f08b4a0d782c287c4d297ddf30ca340bfdbd000000000000000000000000000000000b6e627eaaf3d2be3ebe22d0a1d1d67c22c4f7584cec6c610133a2d3ac405f76e55b8025120196bf69f60bb89e0586201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c77ade0f0a5e25f927fa674c5d9a4e9e7823449c6b1cd7bd814a57babad2e7e927ac3e5de69c5aa1b21b0f554a64e00000000000000000000000000000000003333ee0e2ea188a9159a7452b1650ee42a08f381ffeb737525a73205627dd272fc16e8b8eda97bc63e87b70863bffed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6bcceb0edc5270e004287a996897616e59dded3334b4b7facf72729ae87e4d53b692aa87ff32c5165c5891b0ab6bf600000000000000000000000000000000089bb912b73b529aeda7aa80d6beb5fc9c7e9329de0ee9429aaca1d37a64002af5a64647fb413fd07dff1ca6eadb1d751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021dbb7fe1194241588dae053184c59957b7090c839e4537c32e6259d1d2025b3d5e12ec33accbf84b58dea35e567a52000000000000000000000000000000001341b6c4fc818fce20d21cfe58d3896b4b354980f392183120de37520c76dd564d452c1e375b03df397f1916a68cef261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026561e93e0e2e300996bd0b7d334d305df17a9440a70b0731475d4ce9fa3d87e99c23914a8bbd0bb1a23622b2dde5d7000000000000000000000000000000000388cb1632c98dc43c24b71f5f18ff4abec9f686c9dca7a4320fa4df2f16833a27a4ecf493d5bc15be4decdc1d45a79b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b24e8cfacab48b5cc1152bc431bbec7af6ba51d5b1ac4355d6bc11f2a9fc2b7bec82d0969a88cd69aee8d2d70429f0000000000000000000000000000000000cb54a0754fc36324922161a24697092251e2e80fa6bfc79f227ba695366add1dcd258fc249e8a6934c25dd7a34d2f481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6730888308282d820e5f49187f5f8619a2b1bb527753e12bd19b0696d6acc6e2eabcdc87a24e3160ab466dcd6763e2000000000000000000000000000000001272b03e3b0ad7ba0e6434c725c16d06950423f542dab0fc99da1c274a4b98b50557b56b4481890ad49de6bdba91da1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cb4d5f490c6a43376140bc18a98fe3aa94095e7bb777468f84e0c01e3fc9dd2f2cddb2b1de7a40f1343076f5ad6ae5000000000000000000000000000000000474b848b0fe8c8549bed222ad805fb4b87969d8f524db2b4dcdffd1872239bfdd187f8b9e38cbc3dc132d216e630cdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191458e3a3982195230be8fc9da15b0f6a4f758403415b8d835a5bdc086b334f932651487dd95977a62fe93ea715ec6b000000000000000000000000000000000b4e5321f8d5225642d1a79442a0a0440dc399ffc129493ee38fd53efe0a0ef248f9a3154537d3e14c652bce9171abf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000655a595cabafa34059bc9e73344c6dd1ae36a49863d452919b153deef8fbec015c9a65457b8a280b145c3a67148c88d000000000000000000000000000000000a4445a39a72822b785adcb17f0e3b2319f8e3d7c56193bc14465b6b66ba79e8f56e448a7aa02c06eb996d0d71c1e3ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019327497181b3da5192b74a9fad4e33343da179c119fee4585cadb78720b18862e8583521db6dc3bdbc1380b748a753e0000000000000000000000000000000018d4620274ae5152b23bf21726d545c60239b8dbc8bcd62d6c88a9c554fba6717e48eef99eb78f7778d36580f746801c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098f007b195180c989704ef5c99b67d9070c7e2ed1467b378ba259efd8e6abc8a3fc591f91096c8a3cb4cab2f18abe1b0000000000000000000000000000000001551bc55d0cc827492826df9c73624a56df9cc54088bd2b9307d0534a837f1fe2a171be154a99347c16e0f8305ce9681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010b7e0642220f559b82ba41d2be17d46418742ab1f91a8825cc2ba0b6a9ce6556398967720c0bd6607bd0695bae66b5000000000000000000000000000000000275b70d632a486dabef2d92c1b55b25d74d68aa2ef3133d30f704c44e3b60685dfa888c1e4a8b42650dced216c82e771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af520515fefc40926183fd2ae26c5c24f74e85a25765a74b6791f59a3c713e7fb57c6ce54aefc2c8154e710492f9450000000000000000000000000000000000b429e9153f77a3d08c5f0c47cdcf73513039dec6d7058137b3d23122b06289adf17b4dfe9aaac055a8079039a49471a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011447843b7cba13155c62b5cbb8a298eb7aa57db3ec78f7971fed1ff3f1722165638bbe9260c0c8b37edb55cbd9e8e35000000000000000000000000000000000caa709b541a29fd2c26d6f74b2c580bf898443377582d1d808aeb0f162d5baf55c2691be5d4804b1e402a2253847e611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136a9edc2c7456129c1b6abe908d7ce24985e0e9a6c8b2fbd060b29044f30907c1e94bdc92ce8150bb066e4bb48c24f90000000000000000000000000000000008eeaea50e040c3ace35269f330f40426553f1b92134f700341f5f211bfcc9a49273f9383bf01be4f7106fe99cd450aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195d4c8e78813c8a7a82449ec8e7207aa65008278d48eaaf87fbf342d2f058262c82e0f47f214ce343a7d8647db861790000000000000000000000000000000019b8af15fede12e1bd523e51af08069cfd0ae9219c95a7be41e3fdf60d5fcb18cee2bd9adadfc34372ebb7d5539986461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000402cb58b3447ecf2b0f70210c4349d5d096ad95990cf995dddab89569474c86286bc9ad47371b9e8f32048abbd02c8d000000000000000000000000000000000d9b22738c7c4bc949d329d80d898072a3537b3679bda26c42861b8cdf54887ff3fd39d5e374d8790c3f2a5530b0565f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cefe29d70e1f6f5545174744f891a8eae67901fe9cd9b5fed7193d722fd0bd09ba163f282da3b850d9b294e75d8d8000000000000000000000000000000000198d518d5545f3c9f9ae1165ef82dd26b50839910bd101589d1a554e9bc740495aa7babde13e376dc540b5050d4e1cf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148e4aee273b1f356f3ef9b89a236d3b1d4db651e50c3d4a9a4d5ea5b6fc5f0eda52152f891d1442dce8f4197b1978b800000000000000000000000000000000125e60d0b514de28de6a921bedcc3893564442e1c39db568562608bc8c1f143c2701b5431070f65d577b799cb7ffc5771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ce47007e9085f2099163ea1ba293e61f097d1345784e06cf32ea0ebe14ba0510e3acaaa85d4d2ee103a6cc94606340000000000000000000000000000000000bfb05145276802bec90a48a0713585d38f455f37b0ef7a1b0e69eb5e9ce34a0c57d480312fcdf22d8f90becf44366931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103b362dbfeffe70db16e28037a7724dd6ddd5ce38250ed3bde22ff641627f21c1592c61c209b53e67307bdd2ebeebbd000000000000000000000000000000001392bbd8d4134a696acc372c29f36f37aa7dbbf8827945c9bdd1ed30e5fb1cf9f0bdb84012dd188aec90725572f64d0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037de20e90bc2003ccba1cee28ab1ac29c73ec4863340d37928dfa6dc5b13b72a366ba0f8d34fe8b6dc007dc855a852c00000000000000000000000000000000067f0946b593778041f6053985e8c6221513f804a7d3824c8003fbcbb6dbe5dedfe79ed7c3b68ad2bde5c68fcb4726031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018889018d102c17a1becace07ce19153808bed3379f7dd562937dbd2ddf24f268288e3952e53924bf321d87aaf10d2a3000000000000000000000000000000000fafe1fc9a9cc439d4e9531e1ffbea780c242ea4e52ee6ed4f92586372116e97ac828a49d177842e796a7c9ea243011f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7ca86f72fa0a34908346a0ca02b23abd8978cf1c37374d9f7277b1f3be7b8cccb62bca991e3240b81468918463f8c3000000000000000000000000000000000038ae872d7669a416dd85e522002f07d0769d90761a32444d888ef45dde6ee7350d26aa71b021a7d27420a658626e1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001654c192918a85053dde43f99c5b90836e880372d82d4532dbbb9ae9fd3701883ec35c63983bf90d5a76cda07dcf83aa000000000000000000000000000000000ea6f384bb572be445c7ee3c72bb92b59d1e262ebab4dc142ae075a04d7bbef2a34b81efb2c9bbd8399f8c5977047afb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf8f22116c9c7b992e6b6f0dcd9afd811be529c5abef4080f0143f46eab6141591744c7ee62e0b0c41053afaae9a70e0000000000000000000000000000000015e0e6747c9d87826a8523e32f125af9f3aba3d85af8a40fbd43990271e31f12e0a2c6c73289390e4eec183b889e79a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f02d48ea861b1f3f07b0ff80e3c09a2e446602c523fd16e080bc480c7b8676357d6a9a07537cca50309dd21c5ccb4e10000000000000000000000000000000005ad8706a3fa386ce8858904bc8b0ea99dc4b5a366e6002a7ac4786e22c9cc9fb23a5e2e923b140779f756afa0f0cac61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0f2e66c8821fd5a443fca9535b992b0bc70a7caf62e9ecb511394d55020d5e66582d2876b776d27129d0b4d13fffff0000000000000000000000000000000004d7cfd164898b3d68b0b20f65d2f649837626d9f32084311a79f17c761064e25933c025fd533e5ce44bc4cbb0759ab01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092dfd0b701731670e2cc923fdf8ed09bfc2caeff6296029870ee17f959fbb2154a5d59289104e28e56407c4900154f800000000000000000000000000000000159be25ae3fd44020d962d02d7a39a38736b88e2ce91261dc24224a0c6302b909932f60ed57f8f9d50bc77575fbcea901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f7b3bf08b78102637708ba44b959abb5092bb339de8a61fcaae4ef4e35970fac9259dcada9a896e3383cacefd3123500000000000000000000000000000000000f201fe244ace590e44de77e7de540d188c8e6e10377989a3e015f7069f13b819b1c6268ff6c32790904cd0b855c2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037ca9779363e4a448b0d360502660f71a63c3e43f7a3a2c3883e6b62f0c4ef401530db411a6a7846d7c2306541a0058000000000000000000000000000000000fac7156c23e112cea8eb3f064c16d3dd0502f127650927dd38170071c02a0f3a28d841b868ef5af250eeccf70a9799c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd04c1a11eea9377809a62d3847f5934e96ea7eb682ba7305f53a65bfa899b361278e0a5cd1fddc032fc84b79bf910c000000000000000000000000000000000b1259b32930e5a66a1cb2dffe3a2a8e8eb277d38f9d4ce73ab1ebc591bf7b016b1f4b9beea946a6c6bf43d9104b91f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000728dd39e3251d651edd206f0d2126caf71c353df36d1aa4a5bc601312773af245ff296125c8fd1e63662ff5e6dde6c5000000000000000000000000000000000632dd081603c7036a5f1f9dcf2cd028a8f38d83237335dbbb52741bb6ea87497918024b2808d9c0aa1e4609ed6c93d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ce56f5615ef97fdc3ee13e44d597da433f1d91d0f86e8375e58a1a0a3cd8603d587cb57b847a22f458ea36a09562170000000000000000000000000000000003ab8eee8fef0e230b286d2f240292441991d7221695474bd74657de3cbc7e06765de6fece7ea589f8c9c113e0c89ef21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018857d052a349f52000f0a355987bf6bf1fc29aa304117c382e4f337de9a65dd1ed7613c7955c1efb47931c42a001f7c0000000000000000000000000000000007325e50231dd46009a063279a2a63a84b997842077cf5272950e246bae0c1f36f9568fe9b0da7de13547ecff957c2e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a632b7414d13c76d17c0f272ff0718ded2bf6ba2ec9e3452cc9ac6ccc1f54ef69362bab463d9daef5e63c9f5cc531000000000000000000000000000000000e55c09dd2050c956c6d3b3b17fca72d453c7fd8a34e27501af521e003b0c03847f35526b88b60fa97ce0906dd7d3d2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8f323eec5c18e2d062790de52d120c643d99b40a7fcc8a98ca17d3c27763e6bda0cd37f5f3e56c379329a58fc47dbc000000000000000000000000000000000b8780b2028b28e1caed89d085637dabb9cafc704372a0873827038d44cd78c5de6856a2376c4d38161305a837979f5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fa4b01881101f973b8bc201b23144b82b1ae85aad670f9ea28988d63770580e97704dc98f2e2f17c7e75735b5fa32400000000000000000000000000000000045b3e531d921c65d38570137b0441f1748bc12fddd2fc1d8458be051c0ea225d58fa25967fe2cc970927ce986f87b111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189f64ae24498f25d84ce0b198998e191d6a8a7d728a2008c6de0658d689309c958c0e25f0b47bb15043541fa25ee5f50000000000000000000000000000000012e94a844965a8a1aa38a6ee73ecf065efd4c6202c6179fe63f0c55981ccec905bd846c1586ebfd06367b37580f4716f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153954366e6b25ee954a0356cf74b9361803ecb087207e64e276b34e1fb21d61a458c3f8f2b6923f67361f9673ec7703000000000000000000000000000000001126eb26895317c081d22db5b26f50abdb6b91e22eed139562f9bb0fa81c7663f90868d33cbb5ed645232d45a03266fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017122498cdd636fb5e3cc453585551fc6e0be644793649f8b7893b464df938b8ed246fcfba7e9e2031c4d604fa0197e000000000000000000000000000000000972a58f61dd6f6369fafac0994a567fb64ef823d4ff5a4adce07d56ffaf94b57f1b6a5b289cabf1cb6236e9aef6dc721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000895b1b5e589b91d240f83f6d93c5dbf86349cd2127a16bfae054b2f6e59c19bea6e4f1bc7f4a0183e03f906fa7f98670000000000000000000000000000000016357ec0e8d217e7ecfd87c69638312e28ed98c1b25fb48141b6c3c79c4b1a47a014de7801c6d90475ab754e480bd0ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ec4c98ad649af7fa1eb1d6b09758df2f31e1869b5e2d8d94d02347f3a015d1dda6e0fd317877314e55bcb4bf41810800000000000000000000000000000000054b715c3e79f361813ebd633ee2d0a6f5118f54c2ad6fbb0bc9ac80a62a7242e23ed7a8039718f79dfff2aba3cc402b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8b7e910d01fca5ab5e53ebfbd77a199a0ca616523fcadb46ce2fe5d4d8279cd4ec9b52ece33eb26ee53507c8f09d73000000000000000000000000000000000e2616f17fca6fe5ac9463f86f60587e1bdd432e43ca209634a9ac13c3381927c4dbf9d9d32bb9f47de02c88c2e6deec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff1cace6e7c369d483ff9cdd7659b8e43bbc6bcc848ed824a9ddf70719e11143cd4572001101d84a6d2fa677dff5222000000000000000000000000000000000735cf4d2a1a6558a6d336ed5fb31fa19f03522ec6a053d2b4ab7481c78067bdea946b190b138c75adfa7a4da25077961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052d2270965ca2c49226db6c1b531f90ddaf40e1d80ff61286eafa2f372e700c2a0ab45235cb8d79eaad3e69f7f8bcad0000000000000000000000000000000013c7962b4b50b60d5916bdf15ba8bb1989604d599908b961dde8a548315e76eb70645ce4ea8db7c7137a06b5697c4cc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0c5db34a79b61b7ec44d8edc8745cb774b18172b83391b2a6650c6527eae588d3de23222e17188e83a2dc78800fd30000000000000000000000000000000000fc16dd28a0c0bab7d22275948c553189b835661e6534d2b90a4bf717875dc5904feb6541aa4e2da11a58a489ec755fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f1997537fb52f94d196026f56fb09d5e93e433939c64e3ec686554c0e05f4e821873ba0657eee4ce170925198bcf5d0000000000000000000000000000000005af4e5ffae463ec39d73cd350ae1e2d7f73cfe7f2f20e7f57c103046680d60065f3c1d0edf895d4eb1353c824adfb7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c2bccf4d3fc88cd10f863228d76c9d3199bf2f1b73016b6dc33611dfcaa2971364a1bffca0d363c9469e756afc447c0000000000000000000000000000000017c073af9ab80b163dd4d87bc7475cc6d2005c0166d96bba4efcbf218c755abc3b7021021255ea19feb0e9e1e5dd81d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c819673e6ae10757f839040118b8b609721881dfd29f06be749a91f58f7a308a3b4a9c3fc30632b2d19de23fade57b000000000000000000000000000000001265cf971440aae83691f337b08eefed434f6dde1369333e8e677863bf404a4f515b338b441d7782c86e146d666851e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a8b6beba9e8bd3f58f7949c9476b7d6fe7de81aa04b8d74c6dec02ecad333e5a37502bfe511b73fa54cc54ecfcd88d000000000000000000000000000000000fc1bf78b29a82ab4e6466b84e83aac98e75ec6402c0179b0e9f2b3d27c8a5d3deaa093f93cad5f97df5e082fae382fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ace0142f74d8ebda313896beb772d001f67a61963c0778788076e50753bd93e8f83e3529975c91699e4e904d9b41090000000000000000000000000000000003827f1cf87459b1dbb80b1c585f3d29dce2690ead97737f02e6d86af1f1d31c2fc537be8e7b50d8fa65f31b7b8b3ed81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f18a5513c8e08bb3e4e648e5cfc15ff9d0b5e4bb031b80b9d2b9f3717fe617d7fd6e911537fe15be8b130644e32325900000000000000000000000000000000185c9209ddf5da2ad0a1affc46eba28ad317b425034b933d17811a6ea5c1497e5ae6adb39dbe8627d9c2fb6f27a4985a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000394593f5ed51e8ca8b5c44b1be690c9b4fc908cec57e013a9dfcf81a540914a854879ae39aa318eb3341f2ee47417c000000000000000000000000000000000103376f1d7015e3bbaf4d5f107b377bab22a9f026fcf4ec3e90258b87f5ad117f6e63ac8e0c6165e2ce7824df4558ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163a022be3d2838cd964e0052a67aa9ca9710dfe9303588d60335624ed77cf97bf5960da8ef7e4f0cab8c15bd86a25170000000000000000000000000000000002a166469e59d361ea18f766de68ade1005ba61cf785bb670c3759b73d6d23f06dc0dc6c8fadf9a146070390a0ce0dd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056a3b1d7c471a37a93f9835d91c167bb73171daf4f548cfe7f3363c835426a4087dddcb1bd4d8424557ff56ae84a6020000000000000000000000000000000001a38757d9235479b0c78f207b25163e77fd919d8775de5d4d950182932e78da4f541502d5bd2f9090ffb899cafe9fc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b83a476b664c9d22236fb0b78dd9af817f99b043755e6ec4ce09c0de032d840d609b6e3aef61f04bbb58cf6bde077fd0000000000000000000000000000000000d67f089e57cb578d4ca1225ef76fea52280114b7c4bd2495e5f845b961992052b12f270ed57a01ae548b60c6a32cae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001624d4ac492511f52d5ddf70b03a6dd5e26a738cd6ff634e8dbfd19aee1b6fe62054277c5cb4730b6a372fef7f14cba3000000000000000000000000000000000c41e675736703e995e1e6d9659f3f473ef344f893d8218a8fa50828fdd55ab74a62c6e60141d72f3c278ca9c3c5b8e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001780b01679550e813260e6af24e5cecd00a74442284a4b1d01628b32de02122fd3f959d9046d1816729d7754bcf5bccd000000000000000000000000000000000cdc847b35e8c1db9d3304bf8ca0f9bb2b6fa335e4a233ef3039eb44b91cea40fdc24121ff99d595a0b867a43472fe681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcb87b3d456df47fb80f2f6c55c45dbfdc7b00024f1b48947e4c92c5e85af28cc5962b4f9bdf9f042a8c48716da69b400000000000000000000000000000000043ce44fea4a0c9529546ecc17987f6395167be1856e9fd9da84781ce45e2363f9e6e55573298c7ace3b76398d701c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001944f6184943889fa740e193e6b664cc83d7cb73b868b6a1b9680d86f9e534330bebcc2912e08a30d67e5d8840e5a762000000000000000000000000000000000cf87dd015b4ca5fac58feb35233ebc9920fb44da60a1bc045be81379ed83c5c83c0471cfaaf6f20a77afc35618c1d731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c9407b77e402877b2d1926d9242d228aa7813e4fd825a7997442f304a777e96072767f02cd9760c56be73a4342b6f9000000000000000000000000000000000dedd33dd3a61d9724670ffd95b3b2ec6e69235ed651dbd4c403a9500723a71d8284191b2d757506fcef2cf0c7d21b4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e45874dcdc3a10a3e6bd859c39d2a419ab2d0529d42583cbb777d253817afeeaf9c7faedbb06583be004d0b8c30267000000000000000000000000000000000c2c7ae0fcb6c775f55d6ffcfa63476e61697e6aa6182810c91e4c48d44b5491a4bc858070bddcc588b7b41e2ae6b54a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154e9075f6117a788418a690d9ab818a9f553e3f288b231293701f70b4fd675bfca730c39dd61a50f3e7856a651a6d9b000000000000000000000000000000000c5530571fd75630139352a15cfa9c14e5f7c0630c8ad93af3957a0912a572977320aa5622eee148f83dc7a89ee1b43e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001203354573ac13ea13d25bab55cbf7108cf457480fc8a2d6b89917b2bd83f71ef4378140a08e90771cde78b381107bb500000000000000000000000000000000182f3db4a1d75468c6296e57641e75cf3b4f538bfaf92c7c83eeaf07b40ffd4b1d0e0f687d1aeff65d47463033cfbb4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b25f93a4b0dd05dd9843adc1b4172c81839168566a2b927ab71241aae9192293fa8a3ab5812244c531e501cf8b395f000000000000000000000000000000000fe8d6a81b7799921c5a9a8512f05c58b1734ce9909ba0855629235b94492b70ab849681bdf05a1ebfab91346c2a978d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005aa1c6068eac3cb2d0748cfcbee9b164bff473896a3bf05c7a20661a41d43afe5a1f7c90bd667d51cee7019d19f39f80000000000000000000000000000000008c9d4256efef29255ef4433075264937a7864ce5f000006cbaf2269dd389c548d6f88dee0605831d88c6d9f988093331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185e4743ea94c3d6d73a2fc7d648995656f87134a19717c661041230b4986e6ea919856af73e5c55dda15a65508e0b5b0000000000000000000000000000000005909e1c21b8486d46acb4131419f209230c7d1b88ba86f8f4eaea14fa06e5f01a39072a3d331eb52af1ba9547f9e4681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000713b4e2ce31c8363175b3045505c8193ebd1dc68ec1d5d638b7c4eb81431f401d4eccc30fcf0ee9002ed566765cfe5900000000000000000000000000000000118018abb0ab2877211333427c40a7286662ca75e6254aee20ec3954a6e90311f8dcb989d86b67ea38ad0ae4fec855c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b33259c2bd24bbcb8c77b21e7e63e2495f3f1f4ec75a83d6c0e0bd46a878c84d9fe0df14537e2a2febbc52b744655f0000000000000000000000000000000016e000812f8ca8b989c583f03cf36dfeb21791fe579201c8d2e09cc7242d4039bb510a4c9cb583b64cce8b99e2267a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112aa9a3eb360728780cc0fc7e82fdd600fe3bde53d06a1612ab7cec9582df90f35672183c5bbc7dc3f4532ff7dbf9a0000000000000000000000000000000001129438b56d8e3e30af00ed805b4a8c0df361d25c8cd302edbeaf3a488d85945f8e741addbe8782d3e84ecb3b01560161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094b34bcbbb8c9412c676ececb8ed1c41a4928d395f345e1868a4c7c0514109698e31cf535f393bdd2072a300746b3bb000000000000000000000000000000000caa9f93140afb6b1410fcb6a8fb622d87c5519174c19f3ed31d5818ef9d28f5b9e88fffa486546895dc4308d84b7e631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6b47b2e1298bf23f124252b9c0fa6c278fef6acc40571d22580f3e9b2e344f1316e4ef4dd4c4aac9b865f6511192e90000000000000000000000000000000013cfdca57f264c1c82e8072beb618a601988a6a6746a381b1f8d170b9359aa15cdb7658f2610b7eeb6dfbc1c4d4aa6031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ac696014595f119e4cfafb03c32842e69d3d3552d40b78456fa3859032cbfe0a18ccbabba3ce1b512aaae0da9f433900000000000000000000000000000000033564cacf212f71672cdab25a2cc7f7fe29ddbd473522c0fdcae704227cd906d4d239e228dda66db9a09d68b7faca041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cb4138910df1da9b724fc850834a29f9915aaed5ec0a1b4bd7839df1cda322875625823e6ff3e577bed88d7735f7a900000000000000000000000000000000029a1314acb5c437c72e580100afd831d6083bdec9b562b1dd749eb29a29d7dee8cefb0bea1b53bff248cb334a536eac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cd78dba670e10dd682ad4b1ecaf563cc793160333854fec5773504523c09332ad437d5187c56b536cf116d53c4b02200000000000000000000000000000000112c4b7d926624d466adc512bbc810258aa098e6d4af5b73483947fe2fd427e599b3ae191454104536561fed5c16ef2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d2adc5496282548bd2d65002c343b0c9493ad16d3fddf324fde870214164a4d96d1c0bf34618473cf67cbc2e844e06000000000000000000000000000000000ea4f2d957b21eb87e286e75acc8e1d89f47d3ded2ad1bddedfb7f9d5b43d1260aeb4073d95c9514ee436a16c4ef2b7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad1e6934a1e3c3a731a80d149d53bedbde29a34077333c406adbd48c201c8007f74ed028b3af6c107526a8f51da3ec30000000000000000000000000000000014f1b95b6414120fedefacf2fd5c8180b418c69aba43dafdee311646b5c82eae024c336bb96d94b2044dcfc7a96202781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000adde0c3de13b5021490f37c9d917493495b94b47ad0c44fb56ab27a64788291daad3fb0896152e0c8b5e05931651ea10000000000000000000000000000000004634c6ca41775d92bcfd61e2665b3f5a58ea6cfba597e5d401cf92981f04c309f5549af37c1d3c3c3cab81aa4ce03a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ada46325e812135e304db19ad9b040503988336f4cb129da0dd55dff4071799fc86ace822ba1f1872a7a1d26da2aa3000000000000000000000000000000000d153d03b839c0eb9b9d1f2b486853e9d42bbb6487474e436190b893f364b20d0c5803770236b9e35310d819a1eb0d1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ef784f949da0bc0216c448f5b0821cedd3382f0fb7ea24a16bc425138ab4d792581b7c9a943e085702b59eb18eb102000000000000000000000000000000000620665e06ca2a9984a2017a33c089e3a8ca040aa3317e3432bbe0f00b7bb0f7571659f8f93356abcc0486f2b54157801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cccf3495d097d93244b950b75d5f2a71ca82b993384d07083f186b497ec9a8e0fb5006bea898142a189e085a85f4230000000000000000000000000000000013c57f27681a2f974f7409538f213753a09b8694c92f71dda53ab3ccc2ed4f235b49705f205c8da43ff74de8864f8a061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000deb3725b064be6a19c2e9d343aa8f39540e701d6843a3c6d8e0c0f6ea3924938d35b204810fbb3158636606bebc572c0000000000000000000000000000000011be3fd18165c7eb43ab98697f040942c0bcf1572f93522484216731aa434160362789e344e60ce10e796726219425801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067054b1aa99d31ce601a1725c614afa54610b74d97fe245a35ffcec99500fc7f095d4f8d37b1e483464eaad0193ade40000000000000000000000000000000003c26a178b334b605a24d93d1ecbd0058c7f8eaefd28fe992d75dacaad7877fb828dd20f3d8d8987122d9de820bd7a1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfecfa9732c9a9cd3e237bd0b1d00751c4df0a091cb372b6dc51baaac96138d58e1546f7c38550e230081d56562ac110000000000000000000000000000000015f233887b2793b0214d814731b8f7cc2baeeccf340f9f9de6049e2146731e830e77a58722016e2f657c77ad670a0f351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020e6e173054e1e2b89543830f767837091e17e7ab78053e9f15598c931e8e2bccc61364d2134905199b3614efc2ac43000000000000000000000000000000001614c7e7c54f163d58c892a6fad75711d706c138da9e478abf61b05db0c7951d889a3edcbd802c1c25e9b19885097ee91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018438c03c9e56431cd731645ed45cc8af9687f10b2a04bd49dd1867a46c6497a6dab56467e178bf22ed2a874194e19c4000000000000000000000000000000000bd5bfe1a6141ec755e1525b8737b3a329ffdd949b7b33508e97d428eafd72dee74af212c81348a4622a635eec2d40661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197de8d809db7bc5b7dc4432932c1e19db2dc45bf94db6c5d50420da22f40d785926ca6c36a4fc55ed273570a0c1e0c70000000000000000000000000000000016d0222928044b65f29c861f16bbb974c4056291271e05a5ac2461ff8800c2f575568bcc94701086db657f7dac64cfb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e1a6e0c394616445f594928751be00f7f565af53558cd4831bb9d312113642bfb2f4ffc45bbd87d2f5f4e12bfea150000000000000000000000000000000000cbf3311e1b3e2cf796ec707570b3f7265154cd0a001fdd3378fbc89083dbe5e47df6fd591ede10be2b341a3a41a6e681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c43c5d23d8af4bcdf323b5c3f7d8976fbdba38a7c96d1537a60e506064df7e3b17905bd23fc5545505e5b2a0aa5f7e0000000000000000000000000000000014f2c90c76e52e2f83724aaad91c9c0346f880cbf704e8fcd954c5ea7752a664874865ca01866d329e7473b639b24cf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001548960781817c6aaaf833d79d42649e57f8d284297a37eaf2c20a275eaf1c8f7ea9b858a82049536baf04909687fd58000000000000000000000000000000000df030d318c1eb2720169d4f6a8592efed7083be119d6128e127c6d1f8327c942b63346ee32447fade5ae7a2c8d3efa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c4af0fd3a0581158c3c6b323db4a36a44bd0bb9f021ede5ff8b99241d8cf7f20d19855283796773ac143d1b3e1721f0000000000000000000000000000000016a73b1d31d8d234af8a9e820b4d1ec0c584c9591f7421cd95623f450822a8bb2e9876938918d83c7f8da1814b361d2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d43ee4b9ae7d04ba723e360a3823036121630180bb967d730f99c7ea78e65e5af64ab40ad6ef596759d581ac1cfd3b00000000000000000000000000000000137868ea6b2182e10d669bd461a6b8ce6c2c3dad8f7e7ad5f657310573633031a09addd06eaad2fd92fc6e143505b31a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001387a927c70a0edef3f4325b808581a4fdb07f33be097e1a082cd9f40ddc46346ad79829e1d2c87d3b130590975075aa000000000000000000000000000000001534a5ab9370de057181378ec7e580bb67d6379775668ba0566bd8429d832ddb4821c59ffb807e64377d4e2cf3a575ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187a84ad4cd132bc8dac86a6baccb53cfbea8a1bc424e43f6eb3ca03d7a2858db8f143d76a5692d40551e8d4396efb00000000000000000000000000000000000fc0795744641d0c90418b764fa216ae28ce7edf8c5e77266e43ea8514d39f4481358f92f94af022ea8bdca728fdbbde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098f99707d90bda18e305a03b0fd02a7557fdc355d71e02be92b633442b0ba55c850b3c020d36b249c61eac9a9b68dbf000000000000000000000000000000000796872dc3cc45efdb52ebca0301025bbe06aafa0494054e1879fe7be86b76cb145a6eca8bddbfd55f45078d2d97099d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f66910191955f4025d7638c8b8c82755e7749618f679a0cc9fa478688e7cdc52757e219a95c6afc5541ca929aaaf360000000000000000000000000000000001979109aecb27702c0a9591f7c002a0bf480164f4c48c26867ca58f3c1fe12e627f731c93ef3c599de48661ad906af71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064a50eab9206d132a9103d64eb5574005ba4fcdbe50e889f648129e3c5289fb318156d856c8d5e0c8e41dcb94fb53cd000000000000000000000000000000000f639d12fdf796294c1bc245f22b1fcd80bfd90e0847309c51706e7ae7a15e2b3c2941c94d74248a0ce723e00aa91c551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ccaf612116d89f15c3f3c827162b1c259dd275fb47900e3a82477482d62435bb4f6644bcdf81da5c79bdab812ab1e0000000000000000000000000000000000afeb0f167b40ba2e3f99634a33b4f988a826bd7251e523adaa0e7c0954ee0eafc808a7472f73ef02da707ec38a7cb361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000769e49b8a64a68ca5e895dc7695b4db31b3da69eef2a11a94f473b477e0584f768c96594e6e397b9311a271657e42010000000000000000000000000000000004caf21a77aa0ea516159202b022f64f4fc7aa9e7b01bfc711d719cd1a0dd7bced0c7342b2f0aba16fc411c4f6103e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001709fe2bb3fde768ac4b01a857472a98e4141b23ffa830ad42ca23058492754a67a2e749eefc09f48d94b740fe306adc0000000000000000000000000000000002402f51bdb7242903cc54d7ebd3d744409fe8aac8eb4659f6ee5ab4429f7403a973f85d6e127d9acd51d1641f2fc0d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098b3aee0c4f14e96ed96c220bdb30836a9e8f91dc7411d2220a088090475aedbd3e0513c0bfdf07f93a66f012a872eb0000000000000000000000000000000017f73fb0213a6dc18f2055c480f724ba9cab19cfcd764d725bbb3c752cdd539e75caf952b498bcb1e3feb5574ce6e52c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020d0d4731d899c384adb60348fd22569251ec1d7d19ac224618cc9bd37d104abe19400485f9e22dac5b0f7c7a71eba2000000000000000000000000000000001057dbf8f57634e103b28babc342e30995b2a7d53123b5ebeff687776ed82a8e2d5dd81a53a2ea6f1de75ee8323dbe711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183c93ba9dfa0e1c6d9ba95536ded6e78d606d1e76f971ba568d6fefe0f8fde86bf6f04b1a66e6ecc1bc9ce71e2ba5cf00000000000000000000000000000000014b9732b90daa700ff9e284e58375463608dcd7ce8b1307ad986a39c806caaa0f57251956ad7ac21a8632945997cd391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b9317943d346b692d32f67a8275ffe1a692ab3cca0acd56fe99cb2ffdf674ae05d53db5b34445df3cb3e681b91ae0c00000000000000000000000000000000153ebfbce5176ef8efe90d88c2b6ce43b8188d380d7e639e9c06450eca86e17ae5ca50726976a5164e78eceff2af69191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190913f75326b19e0d55a776964ae813b02ff83977ae18e59510ceed8fd7f2ef4427ef8bd45c6ce6483f3cfd7afeff41000000000000000000000000000000000a9b9b73ba6f057199ec981c656fe6ed1fc65c89abb665a0eae3ec714f2e8b25452097ba0f54f7d88cddbb214bacb7691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008198af373a3fcbfdb9737486ad42a86c37c679742403e61c0a381630737f060f28c05cd9333b0d661321e9af404c205000000000000000000000000000000000c3a2ac921d3c0e7aeb5a43039eada3b633c4659fd059454cbac5b9264778ec5bb9557e4313f9893213cc3b56c70e0e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001717491308e7f441de17e64509d3e5391222246fb318e221bd6937da55c1c767026db8a4564ee51e6e301a4ca4425622000000000000000000000000000000000327cc54aa5fd382bc4df6eb4f0e0ed2e3718b588c62ba5a6da7f0a0308d6c1fd9eab0f065410847bf004e2c1e3c04b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072ff0c994d65e0364ada3c3ce4eaea9441528e0545f03894b8c46305aee4e952917e1744a6427a9956cf4a5367af2130000000000000000000000000000000015e143971b656526ea728dbfc7f2c018ee42987a5d1f0480696ce06168aa6d6db7e8170d36304c17aacdb53579ad29fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbe0bb48e574ca28860e29ca02400883004d003f521d07b2a737c8919859acd968616edc2f6a5ffd62ea5135bfe62ba0000000000000000000000000000000014025e83d1d873a2831c90671988f9fdfaa5cf91dc546b6ed9a0d6a78b56c85a30ac919dd165ceb0935f3bfeb04221721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000feafe20727ad9815b9d0e9e38ef750b8e5e58257c37a1aaf870c2b455df71529bf6d3ca11cdc081c0e08feafeffadff0000000000000000000000000000000002f4ccb52e0b77344077ad31c186deb5c4a21e4902a5005464a35d5cbf8bb2abcb0985fd260069ae5294ff018e6bed0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c47d12e834d2d4d46c915126e06d12b6878f58b44afb764e7d0261407966d81177ad0dcc4eb7619d9d3abd710f4b080000000000000000000000000000000017b616805b1625c60e0e09c1da70e7f83d1894c97ab44575297550847bf7fa08ea5d731527b662d480e7dc1e300226261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f0d4282a824f35a48d1efa413ea9b60ee826b849a91bdcd960e3f1137a17ebfa9008bb188b7908d5535fdb7be77abd000000000000000000000000000000000b65f410a042d519862b87c1d66a7bd72a8eeedbe1b5dfa397dff53d2c3b61f77821b5f1f8eaef9b2d18f6ec336da1821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001718cc7f8cc5371f44e7777f66f0218cf3d39abf93fd2261f3c3d7d160da8193e9d5b12008c5959a58eff8aa839245520000000000000000000000000000000003ff3c7366737775dd651571fc420d138883a2846428ec04104c6cf461f0da6500036c08f057d4aa9dc69c4bf21cc9dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d8e48a0f4b5482868b4fa9d12b1adba697b249c6a578237042bd731fb791830bb8c09d80e14cbb602bffee50fc9d270000000000000000000000000000000008010048241948772d30511b1fb7f77bfa97eca5e14efeb2502ca1d85879f9a27a1b663b452a657c451d006490b3940f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127df660352ad016e565ed7cdc0bf1f6c1e729e08108323b0e171d75f26ae8b0bff101bdb24365466317027cc8a2d98c00000000000000000000000000000000178f7f91b7b131f5b522be02188cace1d7e42d9a224eb4555a7ab8eb6a8fe3cd86f3be4e162a97364e24f40375177f4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035b7673b391fb367a47e88e5f8d243ba7e78f454d2e3a4cfe98abf33b1f81ad17134b9a850bd252ce5f788f742432d000000000000000000000000000000000156021692b862f3a3d10908e60cb016a5b64af86e41aaddb525c5037208da77839250c3c08175c3662bde33c310b6dbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001356ee463b4d39178ba441ec481ccd9a9e24699545311dcf9ce7504c6e71533350d917a66bb8e611c74c8f24760c6248000000000000000000000000000000000964558bfd791b501b102aeaad5c42e08b161648d5aef8af7f274631eec68ee5bb913c89b7f2b2545aeacdfac15ca25e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae096a580e752a44e80692c2a95a60634e5fa5b2843e8769ec13ef11b1038295719c4ee4e3ef7c6a67673792b83033a000000000000000000000000000000001225f8d417578719295cca6e0ca0f207486b11ba38ccc023c2aa28bb831926d2018962ad0d987ed8a4956dabad77c4fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acd4517399389661eb415bec10e4e66291e792afbefcf335beb38d56e00a9a3b3ba8790a02ac530d550cce1bbd3124d00000000000000000000000000000000137a6f6f53905d1a540b84057ef56be664f67e6cc723362b2a15a151b57830f1e9b9fb5aeb127cf685ae2a7944bf04a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6fb2fe7593b3beb8767c2fa7e2db04ee7f76aebcde2dee14f86ffdb35b31469d2978d74efb870344dc17da7b1dc2ca00000000000000000000000000000000073e9ab353a058159f4135b8d5f01dd1cf7e2899b0c5c521804c49f7e85b5b2b75002c4f2307146ae7335a11beff413d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001529b7421e683b48ee713f4f92cb926a05b198d111a268b0e8b5c3825237f385172faf23fb6431ffcac050395bd8b1260000000000000000000000000000000017d19067e6e363c796cab866318531cb170082fb19b686e50360b65ec0f4f58ae08c72a050ab0991cd7b421abebca9a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072ea13933e3dcf0130eda9f1a4504e0e61c3eb5874bffa792579125c6a840695f5de4b31bd02834494856243c51be460000000000000000000000000000000004777c406bc24928b81e715bf581dec4332366ce8cc1034bf436393147a1e64bfb7ea72cac416b42f96c0708541598821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d07da4ca2bfe04458cedc26e2c5aaa65b93ecbbca814e7d7a42b9ea3e446c24dc565d0c7b5e9e52c5a1c379e3d169c10000000000000000000000000000000003a6fd82c68891d0b56071bcbc88f3d728477343dfb21173f210cb9ca1ca1a0164bb40685f67ae27ab6d0005ab3d6a131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ae6fc9d0dbf9addc45002fcd2c897b76cac062187b5f930c999b5a0f0da8152e896e3dc731684346b7b8cbf50dde6b0000000000000000000000000000000008d3b5f0f55cc1da7578f81c20530f1fa8717dfdc2aef1d348d90b160c02ba86f5caa4f6f9394031add5923ae6f742881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001068d91c7a20d92492ff4ff15eff47307759a400f4c72c3fe26c2e1bc0427bdeb44bdeadc5fb56197ae79e91895d328600000000000000000000000000000000157f4d4f972617bd6a70ee63058d8c1b03d8b9a3930d825daf53a6351036758012fd5b312600ca9841f41ae041e560081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d48dfb7214495d23a3f5d4a5c2eaef2e4af49a14fdf2143d4aaffa611a2f7ca7e081b07184cf0d7b326757a0a72e8f000000000000000000000000000000000e816bb0c865957a2dcd1da14bc8043edfcf06fe03a0bfa3587dde25011862e32881ac9894e99e3d0deb0b20bc5beab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000981209c7a79193a170d1a6cad516fe828adad25ecb07703fd2b765c0ce81d2e5784ce027657741840d359b7c8409c4a0000000000000000000000000000000002a6ab9a5bf08c438d073792eb1680f46941c77c2de9393d6eea36214c7834d9f6627b8c1958ec58725316b5b2f89c5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010902a41f82d0ec79b619a27d59c1fb40502f04d05e7e5d296a0770b0b2c856107607696cc58d04377ace84c5ecb5fc10000000000000000000000000000000013ec7fce55163625f845d54c359b78bc6e070d22c7132841966ddfe4b3501dfedc11bc58a440c24e818ce8b95e3a55c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a80ef0b44c4bb40dd27b6dba81226f6ef4756a15519f7261b4109305666a39ddf7d2d39488db2146ff203d68589d480000000000000000000000000000000006e990462537f9937a29fb42534400c0ba20d1165576b1371409d654e15375c7f3602b8f3ac54d8e8ee43fb9034eaf001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a61f53a9b5ddab05f17b840da7bb915eafb4b45616ad82f4ac9c3a3da9444cd9c966c4afc1c98e12133fb9483904c1c000000000000000000000000000000000b8ed02ef606539f7af3c5a28c512f15399d7cc0208dd50ae217241ef0baeb248e93004ca1475297c750405bc0c607fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa71a6a7aa4a28aa547d9cdd439764f31c920b32e6055ddebeec07d7c3f1146a36a1e1d6f707411e2daea2060743363000000000000000000000000000000001468a10ec26fa61fb13aabe2dd749bc45117ee0b23c2abfe9593a40beb35d6d1faf87258eddc06b472b7bcc39d8f0d1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d08308b02c9ed31c8276a8a9309a2641e613855164336f4411dd1cbf8ff072429aa3cdc8c047254fbe2f3cec68663000000000000000000000000000000000d30dbfe0afe28320ba5d90ae312dc38218cfba4f6e79675a79af03e3c2dd3ae6b2044471528a8e808b41ff6a987eb2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c64f85908ebcdba5b886c03d2cd6c05a9a2c62854e5eb40453888dd5e64a19b3453767cd1ddccbbe5a00f7f00df0b070000000000000000000000000000000012dbdc0b7d809bfc1b982ae863165ad39c420b0672e5ed83f9b291fbb6632d5dbc3663feba64a44c80702397adafe80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a18d50808170ba5008f077d429d08422fe6ccb1e8cf540e9cae73f3ff1fb5ef8ab4d5613b96ec6e58a5587ad987f631000000000000000000000000000000000bbe6b9af1097fabdb10db28c66caa07a2ddf7820717a9260127e59d037cab4b1c81fb2139d6f9d82ab01aab225021881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019903debb88d1ae0c40f21b682c6fba8534341eb6b8114d156d78d9dc5fed28fbf9729fc58f4457eb8ceccba821bede600000000000000000000000000000000061931ee10d3b88d9b119559c077d0c0e79de81c03b5a2b245ad88a01ac646d501b52621029217dacc707797a0fce6271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c18937d2c42ed233e07e05ade84d018455a674487f1c23a3e07768c6212499644de3550e9f459d62218b63eb4f8d41000000000000000000000000000000000166075ad74f83cdd39bbd7a0d5107fc5461cb66d860ab508704f048afa5be811d4e7ca22db03ec9bb9ac5c55a3be5501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fbceaf260ca9331e0b7412690ab6c1604f71079c961d7129f1e45e54a39bfe89823af0b895ddfb688e3d9da98abe6a0000000000000000000000000000000009cd218fd239e867da696dfda26e1533671c3ad50abcaf08f4c34ab46ca0294cad596be097feb3eb1c6702ca28fecc361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e665c06de12799f5fb97d1bc365538ccaae66ece63012b32a061e6ed95a17210206c6526b3e3f512b90e843e62bb7f000000000000000000000000000000000e884e144a10e6f268b7f3c9cd8ea4641ff131333450cbe46e49ced7dada19222d47ac0c2f7bcd80ae2edd6ce819a20e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e471aee58161dcb711d96f7fb5403829cf8be682fee40da45dd47ba19a8c74e619947ab54af06a09efd518066af671000000000000000000000000000000000b5be4a912f590b4374f863a7bd33e329b89b7d66e8c3ade79de518e4ef1e3be9117d0be2180bb7806c8b9447a451f571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001271cb48885c01b03ba5e85b68e29adaa593f74724a6a70321280f6e7f5623480772277013e0cf9ca444043e2ecf8557000000000000000000000000000000000e84a63e0587eb66cc75e7a77e46ac859c92f9be7c12e3091706939d794d44a067a509d15d0f79db02888b2f38f5cf6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086cf874901f34aaa28d28cbee9916fc0476705424653f6d9825b8d7a4bfa03918924a04575a49e1a46bb77166f22bc6000000000000000000000000000000001073b7bcfd40bca0deb526c0268907cad2ec1ebc016da7f2917e9075c884b69ef5992eb5b2c8ca2e4edb8fed10210dd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc27fb1d25cc01965454246f6f8d88a0be740af5afed68120f97b9e9a97fde1c14a7f0cea14ef051028997664ffaf2400000000000000000000000000000000102fa1cbb91e761d65ebe883bcf6d32ccbbc8b664bf4114e1854eb78d63ef8a37e6c701d706a103499f162fff536b6881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e8b5292559034b1994c913e5326d351d67b0e4432d79f27d9a0bf069a1fd9e0163d0521f213662086f9395a33bea9600000000000000000000000000000000010d9397ce0e3ab166ad9f653e60c664b748a6f52081cd3cc9194e68383d2523d835ce3f05d76f3096fc5366f73d5a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1958ea2188985b2eb0903324eb47d6dac15a8040c50afa3a7b4bec40251ac24660dbbed2f977c22608ab8d904562ff000000000000000000000000000000001843ff23c0ae5b7c22574ceba00a591f68576320dc75623fa215ae556ecd12ffe3d534833d32e2bbc8c856bab169b9111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000115129df0ff8d1bf8c162f0fffb7288f2e02cdad80b4b0ad5ead44bda5e20d826976fe05646ac8c20caa39fcd042ff4000000000000000000000000000000000816eea927f38d8b4cc162d8773ff5f2a820ec8f18fdf19a2fecf3266943b7a3615010886f164e4cd540b042c8aded681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011782db8a64776ddda8b6e7416c33e1dded2e897dd6c1525ea9a1428b0c9389d94620bbd6ddc24c6c52276e7d36eaba00000000000000000000000000000000012bb2686279148d8f3790d120a28bfa40ae651a6ed5072d3b37fcbdd12c0a68f4a67a86ebaa9e5ffdd82f686e161b7201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001100b2b234d7acfcb1cd46ca6fce1e87aab6ff1762712f57ea7ef2eaf84a19c34271ddd8a8254992ad2f7e0b0ff378e0000000000000000000000000000000000eae719caa53bc8403b0bd11a84493c577cb568730092ffa26141a361b959bdf32ee4a883be76134c8991c0809f93dea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000506fb3f61d9bf27a676aece8786c860739ec5ab672a229b3c562956d7d9ada429c97b6de8a9a9973df0f54555b75a660000000000000000000000000000000004f4eb767fe5e862b6059674562fcc0b070fef344947326bb42c0869e9bc17578714b1ab3b1aa20475fe05a229fe4b861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016152be87ad121f372f5d555c3dd767eba4f654c2bab5af3d9340c1b91c84cf40fbf29a0187a1a59b2bab0f26ee814d000000000000000000000000000000000055d3b29e6dadca2c04464e7b588943d82de86a4c46fe00f6094bcb98ca915a6b1e79e43535acf8931caa1f143fa05621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7e9cd95ce4f2283f8f52b7d870aaf9339e1a492059cba08b5a5b1ac94c7574ecaacb66cf80eec75363d25ef97cc82d0000000000000000000000000000000003af4b2ae5c6e4c9f9396e5442145d1522b6b4630474846af0ef6f2e363c294f078e7047507945c846484b61a116dbda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de0e32aebd4d83afc1dc70ca4d829e5af78836f2bffb0bfda52339968c12ae013f0386bae83ec73510efb889be27f8a0000000000000000000000000000000000bcbdaa1d5f642290d1909eb931dba726ef948a5cb242b9f02c12a524ca0533736ec4c70a4c6c9b4f629fc9ce166b461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009686a75cb811dbc7eb083931bc537d2e33a80f3a36ea7285ce57440bd6f29c09d6056bfea03ff211eb3ebc435d70bcf000000000000000000000000000000000e3bec298626395c71d7a99188f322dfa97937f305d98130a0bd90ba11e4b2cef372b2ce2e1fa435b5ad0077143dbc641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142a6227eb30cb51b2c7af06aa1e86489ea34a90d4e2a0e80164ad43e0d6b5202f9cde5db145f6098a6f24efca5c95940000000000000000000000000000000004751a45e2944494178ab16aff057e21ec0d1f1b7a5b3371fb257a8286274815e20c799230f98d10363274ed121887d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001784fcaa44fa1b42b72a08a49a30cdf8d1a97b7c626d455533b8d36bc1fdad4b429f914950b670f5d14f6f88e3e930d10000000000000000000000000000000011a78bd8602daf61e98dae8c775cdf0f42ca163cd72c8e0735e2642319c9f675b1f52f021358cae7b67d55e259648ad21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017c0f232c8112e8994b7b6ae201125bdb09f5aecfd3ff6c907f44cfca671e668b5f4396300e40cd409019ba083330950000000000000000000000000000000011e8141a04a46fd8cb67f4bcb700d7fc10c8f3bae45310c9644cb7e2e26ef64f25cdcb7cd365e4a2b4ffb37754b0c7ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f629a2ec4713aa4bbe7e29df85bcb3a3dfb49f8de0de1cf90c1a5d32adc5f90ebc104aaa4498ebe20643a49e022765d000000000000000000000000000000001657edfdf0348982f2665d7066a2570341cd66712dc0fc3956b696494f83a02e36c0e3e927470978147897e586d829ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021248a820ef82a119012ba21884c70446e9d353310c7d66d884a31200cc7a0403487ce8f3af741adb29f3a76692b92700000000000000000000000000000000026d55b7c8cf35519b2663b83374318738bb0ed700619c54f2ebd99dfd24086f7e312fd14d572c6e43ceb83209052ed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015275b54352ae1c0c3ca4fe7b97d083856b3afb389dd3a2e033f1745058689fa29ee7b8e319e00d0c4b185273efc64fb00000000000000000000000000000000030fcb60f49cf77f8d96d6338cf719b36f1a984167d220d19ff925356593fb49165800d5f828e94b7f6e2087610bfa2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165db6631845a685208571e4020758686c7fffcf9aa43999e057e6bbe3c8f05810abc51a4d6014de32b900a8f3a60903000000000000000000000000000000000f92243dda8d5d782da0687e096c2646e335dbfe51427b6ac21b82312741da6a306566dcc4232ab86985395769412a061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098cfd4f949f620b85353db03bce6b58237fdb5212015796f6bedcdf5a40afaeb7780dd5893c8734676f1c897be12282000000000000000000000000000000001864469fd7ce5b6ed60ec7dbb974d7eb015a685c46a6384b9281798ab64ee789555f45a7c47e3508f71b80748692c3f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006000e76cbcc19aff95ea3e600e762fc4ae066fef6b37975e3ceea7cc6e03f281477587fdbd391a2f637ce4cfcf26b87000000000000000000000000000000000e6840e69580e51f3818021a00f22babd53aab98354253a6d9bce3808a64bb6ae24a715629d3729d4df294ac932514831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3a2453ce024159df7d66a181345a4fefaa8bdcd3e576fb413bb9b8c8632ef423db9d59debd23b79f42353f56ec9d200000000000000000000000000000000007ffe213072ddc642616ec85b9a0736bf019af82a6dd720406a617b67fa238db97e840f1685a5b6a36140fcd65c4c8f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b19d231f5bd56b8e5be9458b493d480e1334d2b9245f3c1116d574171df47cb65fa50d431cd71094fc9862f5213f8e10000000000000000000000000000000019432e129ba3e1b074b3714b2fc309b216b6a93ce4b2dfa778aeaf7950cead749ca88bb837b4821a85322877344be47b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142cb388857366c94d3d345f830347000f01ff2f8d74f43061fcc1c41e43955ba99649cb6cee875b817a07ffa228c04900000000000000000000000000000000161706cb9096f32fb33626ac4e96f7ab0694ee12455c357026cc7d0e9f046db2be0b09b0c6034ce0a4e52d84f50803881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ee6331da12a117303519723bc2c8ec1b4ac4e2772b6db88048261dc8cbd5ae5df00f37b22d6acfe5823ac97a1b9484000000000000000000000000000000000500059e96827a21fe537627a364ad71d1982544a177bd1147c7d330bdbcea4a3a9257e1213ada323682a947638395a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cb49963924fe2807269a883ac92ccb211ef44bce952e25bdb47db464d21f3f57180fa51d9f59a20313a0e79b880f76000000000000000000000000000000000062dd86c04a5db6549fae3358f0050dbbd190f5674f6c716b20aecc638cf9bee65a62a7326503ee9caf8687298f6d371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b43b5aaa9a24acfbb031a957ea5f87ca5ba2569b2ae7ce0fa61b65edbb76c73e54e83742bf49650e7bc82ccf1dc022000000000000000000000000000000000743ef4cfe4a1a55dd8e2a68d31ffacc947247668dfa8b81b159d2a10e46a5698fce7049e3e47c61040ac0acb3b3bb801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013391769860a1f9f861e0540ca8140858108d136ed0e62830cc45cd9b366b9835afdd3b819a85e14442f3064933ffa9d00000000000000000000000000000000097e14246a5e19bf0fe65f2983565d6d2b2fd920d8df49c54b8b5d9cd49b3b220b08e3707cbc16e6a4dae06f104b1bd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174830cde36fc59364fa578eb81f5f53dd86b0c7904f1caefeb35ec10ad0472737d4596e0e8df6b13d3259caa12c349800000000000000000000000000000000031012ac20f5523948ff3167c160da3d4419059b82526ed15a1a7422a83a9a1732e2543ba27291ef110b3409a9ed43dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013225b6520f2584af1fa996602cf6d836ed83bb62cbb24035e07135d9dcc7355b5373080bbe180d74204af4d9190aef20000000000000000000000000000000003ed7a0f97ce73f7889e91087028836e8858af974928f4e7fe769efb2753102f459235480ed7968711e2ea56faddfba41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b2f2fca1306fcbddf02000bca8d1071f3e6b8e2253579208193c4cf64f593754481519ef62b23aa931c853c8df83830000000000000000000000000000000013d202c8409b43b76920af871165908acdb072c0ca049d0e337318beb1fd44e893b99a2722d1a19f65c975e2b88354241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081f10b179f4bb062d9fed04219b89334a283b6e0af4f6266c3d562756e12638990b7069300dd84919df70fc082837ca0000000000000000000000000000000016e6c8e190e62a343e7988a0eeef2fa650f1ad5eb339cbbb5b0ed7e1737ec76a6eb6eea08d2638f0f594764aadd543b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a130655ae07d71841720206bb6cade8accf09a3f1814a5cc437fc863179573ceaea4c59bd2295eb824ac2a28cf178d0000000000000000000000000000000000965ae68d69b1df7862d74d435787e4db5be8e9df24ddef682ab39ba476e57f8650d7a4d0f6f64954ac6813a66e15671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bd0de07a69a8bb7f91e18d060adfe96c9502cc346952371aaf17f2d6e827414eb5ce325847a5ac610f08c9dcc879640000000000000000000000000000000004f4d323a4036e52eb248b6c252f8e29d924cba934804682f32fd62b23ece955730c73c58b6cb1595cdb06edbdc8d7f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047f966f35ad7193a1543807336215a8af7bb86ca50ff2bc84ed48554e59e29d0fca76285b5dbbc0ce0d5fa91de03964000000000000000000000000000000000be02bb7cf8b45282803c36a3a2543e03948bdaf4bf571111ee914a4c9b50e95b5ab65e20c580747a56e626cb205ac5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098ff6150e8bef0fa9b86c3499f7b7a336a9f429fcd570f6482f74c5a696169a2d243c46d13a36cc544d0aba8687d91800000000000000000000000000000000114ca91b45c040b41a2eda56bdd39054fd8b134b377e0bf9ff069a5e690259110c25e990b24324c7ec65b74eb50337831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000490fde965a94bde43e44ac869e35cf6ec567eea401faa1148ee58c1b03124f1ff0ab3e00e2fe311cec9e9875d0e44f0000000000000000000000000000000000cab21121115383fe3311259f287908ddbe8500c6830d448a7fb1b67aea6472db9c0c72c1eba5e392e387636e066642e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007526063da1733294b4b5cc98db4390f1eaa1c2f20976ef88a68dc9359663b6242aac0ebf4e724c085c0e4e064675c7b000000000000000000000000000000000a92034f21cd22bf7f563fafb53075e8f31ef5f7f7901e258efab4ceec2a62b4c647a7574c916912503039f59914326e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119a6840a7a15b7165264554867b457baee77a1117ccbbf08fac034559ee9ef4b82945bbcfa9958e3c5e08548d6d27c900000000000000000000000000000000095a7fc4cf4ceda1d05719826d14f305fe987a41ebf0c2853488a356341246e5e90c8369c1fbb1deee8b9b10c16f394a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed2ae400a6f891e1de390200dc25f058268f1acef276b5ff78a2f728d97ae6d0e913c8afb6ac6d7b808dff9fab802440000000000000000000000000000000007b0f5cc391dc199c6a2b28deb28d9cc8e4f4642d32838d2721d31d78f98002251611a2b80b4dd695f73327b1f6910981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103d41b6ce4148e421dc67e0542853709a30f978f7ffa0002aaf53f8a6e629ffc2d617ffaa0b5faa84d5dc38d4c59a89000000000000000000000000000000000b325e470c0a7a4c05bd4a183123a982463c077b819694f1677f2f7383aea3e9a32650bd66031d95ff98d2b3baf4a89d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dee204f4115551ae044b63aaa363eb10069f9529ea64879dd81dfdedb035415d1259d5c3ff8faad04ec7145375fff90000000000000000000000000000000018b75efdc32e3fbf5b9148016dae52dc7a44172f7b4e4720760ab0899e063c2d7b03c47848174d00019f5eb105dbdd6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065033c17d112c44858b364f0afdec53d6382510a1ac1387f4b215f47a3cf0c6865eeadd6e582b28ba60ac774a06682e000000000000000000000000000000000732d855828c5a0f7bdea65449de163ab65dddefd750f426e9d5c38065257780d189cf538c04d84c54fd692f4b9bdf231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1c9230088ddc65f76f039b92d90f68e347aac05546e076110698052dbc1296c457f70b1776a4b28e9e1a2d5d1e42500000000000000000000000000000000127e6f4ca08d3819bd21f9eeffe80399817fe063c3cc999aa02a23f7768faa4a21c6857bbd03062801a97c866d6ab65f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001440546b91e4af2395cd74bad04a3417e0037213a1e62c29a0834f791a424cad624775f3699dad3fe33c0b4ff09aa600000000000000000000000000000000001792c409a941e234cefefb1a702fdd93010c1276fd3a1f798bf09350a57c035ac2db822ef9e06f7e6fc2398761a6644a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173da028dbec940da1aa48dc1f29aede078c968462b596a4f291b53d7524c352886c029d731306fe9b3227d32a2e917d000000000000000000000000000000001113b9d754a449560dedd8666367757cb210a66bbfbb5c58838524166d4c38d2953bcb73b2926be8c3715dea2b3d6eaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185adfbfe50cb40278096c6aec43c99ceb0c1e9c620d5f6b0afc63b7ae898282361b206b4fa815415f402f2f75bb41d10000000000000000000000000000000005e342cda6f9d73f713458aedba664fb0ae2af31072198d7d741b8b2bc0635e503af64b029becb1416c7d65df3a02be01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3db41bfa0b6c681017ba834ec4b34bf22b66ea3aa44053f8f97f1badea1495d4bda737571eee45c9a413d426a2cfe80000000000000000000000000000000003258ff7a8a93b44c1e8d9af233378008e3cc4549a4d9ae38ac342dc23e5144b9afa534a5df4aaae332c02fd1e0b9dbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017185436e9d3ff9dcb88afa9d7a3ba2777e65ab86fd3a92cec4b14e2c332cd80ab579324e41581bd16bc5fc5eec53a4f000000000000000000000000000000000923d216a2049abcf0b07bf901128085cecce233b4b4e879c835a228bff9f3386b33d907b9721c8706562967526295ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143d6c8bf2f9848bff41cdea96dddc8bd005c3b04e814641db49d59c4ac7cece0a33ba5ba515aea2cac2cd8b4f2a08d30000000000000000000000000000000016b65a32810e6cf19061d81eb4a08dd2d10b6e894654379080d53fecaba630a44a4d358554c5db488aa4db9d8866cdd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114ae424bb03f923d4668a249c7246ef5c040330e1812b1507f432dd25fd5e222b8050f5ad24701cfeac17ec66ab85da0000000000000000000000000000000010b1e9887372d31a4e952ad82e97badf5d3010bac27ab9dbaa32fe7af18a4484c4df99831ac21e19e21a0d918a8904361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f096edf252a29855f8c22850558c443617c621f020842fb4597b6c54920ccf1f9072c7ed003680d53d81c28f98aa2bd0000000000000000000000000000000016b0ced51f0f2145722b79d9f41927acf85f02f42e2c7aa63afd0f9078fd017240f8651974b3b396db7651c8cc0f88a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000881386d58225df214e5a90be1ae02366d1eaf6c7d5fe0f1b71f0e58aafbbe03312d04d6e4131a439aa2a973cd9be18a000000000000000000000000000000000fbdd88a8fbe822af7f74ec122e3cfd2d77a041995471d5c5e26298c0b4d788d13306ec6708a0d57d4667bcdf7fe86f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a67b0d4a9ef1d940ea4ac8655167c8b8a6434115c08f23a9f88194439c041761fea39c1ce7150199a5e1ecfd3a40d21000000000000000000000000000000001278e1b63d3013d4c394c7298dd57be96e24f85f6adb22b608fe5fa96e4a1ca1edf5568faa68f41b9d5208cfbaafbb061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f83a23025027e8612fd22178e3a1b4838016b01bb572134fd95283242bc7eb80ce1407631470499ef96092887968e6c000000000000000000000000000000001542ab9ecd7693f86374777166612fead509f07dbed57f544552802bdb6970e823b3190d3332d0df274b172ac0e4b2101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016106e598a6a0b0d1a321dccc8470352067520e1cb1cbced536b1aa609b4e76485d3b70c718710d2d97ffff48be151ff000000000000000000000000000000001858edafdba6a57dc3fc7fe49f5ae600f072e397c03cda9816aed5402ced67232e3cd6a4e413947c0f500500cc02b20c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103a5677b93c2127f73cbeb5029af545437070ec1feba08617b96b669146431a2678c46f834b838658a09212b82c78270000000000000000000000000000000014e66e960ba77b61d693a814ef0d5c6a49125c0367b029fe8ef511f1ad180c876d0a6c2e3ad8e4b74f73cb61d4ea667b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fbe1fc29df63db20c40459e3810bc4bcb8729e58b57fc508bda7ac9d42a6b37ab3df1a1af773bc7852692640f492c3000000000000000000000000000000000b436bb9103d770fc6b59898ded02e68df5bec60c38b5bd84f3f9ff17e48ecf4664194fa160086badb0694b565f4921f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c38ef67cffe9c4d7e8e00e70d4251f0b03310bef6c07a9d987c761aa5a21d667c339526513b098c0c9c8c37e123445c0000000000000000000000000000000006b9a6e3c5d7657cd8a2d8f8afbeef518e4cd2b5d7cfff23ae6d8800bde79eafe0565cf4f5d83b90d737b795044dc9721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b55fbb936cc1119404f2a85478dd14bc7c29dd42c888eb129e0b1b09163bb1e3b4008c88f672fb7fce7649fc8a90000000000000000000000000000000000004676c40fb8a58bcd17d14d8bdb456dd12f1b30d3684687880bc47e78895bd0588df26ffa09893d2ba7804886d8c12061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ade47485c8efd60d0c59aba153933c19eaf200837e5985df675018f36b07e6b7c5e30dd49ffee2e9dcd24e3583c0f90000000000000000000000000000000003a8a4ba04d86dccf4b2d5796b6715230c4583351f47ac9c3f786cf9c7d39cd64b2748a6eec0c5f61be325a4f88380971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dfae2b3a536057c98397d9c3f4ce9cf4838038bffc2833db8411a3f27e4cc27254c0a495dc32767d46b73af11b2fbc000000000000000000000000000000000c11b660ba1e1299a93de9cee700ccfe99267ab4071d7a8f601d52d647aeac576460be489177ef6bd0d2ec326f4717881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d9ec1c3735f50a81826e31ab326cfb4d696040be2a38285cba5973961e3f2363b5d213f9aae510f26a13fe9276ae230000000000000000000000000000000006c7383e97027ccaa22b562466c6e2fedb73c41dcc37fc48c113875ae5f4c7042069e60deccae98df29eae60ba9a587f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c4defd5c4019b48a75037914b27c6423fa4f9c68e8b0238872fba21c416d990db50e65f9686c0e4006589a23a89f7f00000000000000000000000000000000042d7a48904098ee36d9f3d64f357e729ba0d2bd34a2e6398c439a1a3969ad8a7a145139e1561e300345bc697a1134811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175b115178d952b7511d70c6ea4ff5d73a9519755f6e705dc52f41dcf10936adfc6ec0aa73e0b2ed28e770608ba6afb80000000000000000000000000000000003666e5c1b7d5943714f3356d81dd18b8e957b8480a3187afceec9c86bac053e498f04878b7710f461d1379500e95d0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d90836b484048de60c572a0022868c8c0a8a4977bcd875e510acaf254814841295c7948dcc4119c628d33f96b10124f000000000000000000000000000000001305c1501c95fddc6f1266327f0969a30a93b650e1274fcbc93fbbfc3dd765914a44709f1e852f9f4fd46ac0da9fda611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000e7adc1971494937db5c7ed847f57a9a6467dcc42ce0cd305d9217bd65d10a97f5e487bca4354ec59785ab5663a1c500000000000000000000000000000000042d9cacaaceb5d12bb0bcc3df40ec26fd67f2b51145d3acb9222971e5523963d2bb3b82d0a4ba336da2e23531dee8e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b1b89a5c9d4f73e4774a46de42358aafa7e27d065cb87f2eda27be6faaf90ae83d62d253e07117231a81fe32d0756a000000000000000000000000000000001075bb70c748fd66fbbe992ad6e8e3a92978cde329b17b6023df610dcb55a605d47bd1421d382c2131550250d710cfbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000abe54cc98f4c0a2ea99844f9344bfe6df769d40c8e94f5b9c47ed193b9f21f49fce1f3c74aae3ef145fb42a825dff90000000000000000000000000000000014149254dceeda26c438805a60843962e6df1ade0260a2d6e7cec572c96675f4545eab4a765642bf8c899dadd472aaf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003113607082a2b70cf4269fa32e53974c10a4551cb77e42e2e6db89d77c13786cc78394542f3e228b48d557c4dd9c866000000000000000000000000000000000da19cdeb13be6f28cf6b225f07deb091d9e4f3a9b2a804a97b67d82fd67f16bdbe08c3621fa7f2d7ece7b41b483ee621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019256b3ea2de00770225e96dc15d4467bc61517724ba8e5ec48192cd2980e60e0a825d33f4db271dde64dd19d8acd08800000000000000000000000000000000167416f3ef7ee2c5361ce321d97d16d5baeddd4050dea90af1407189c981822596632faa4761fe3690cfc6068f2598da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e360c7a3250430441c47059e538bab410d6a2ec04a54c8c66ef37489d5eb5d1109e994bc3d6577b91a5ec90061a09a50000000000000000000000000000000004102c4d61bdd023b9effedd6f5281522764d1f49ea65755d8f1ed07ab4e0d115b32d9e5e81c1fa2f78ddc7a5f23505a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017dc7ca2d57ddc9f8bb7cbe16e73ffd47dfae9a1bc949213c4bfdbb9474b8f22092d09241dbc91a5630e82a6754108b000000000000000000000000000000000ac7c8b045168d7cd0cd1eea9f8164287b45d2a4cb4ca458034b7595249d22ec83680aa3de53f0d1a466ead95b2da5a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100b46105eea02e91cb6bb5dccd39c05746365ddbfbb736c27987c74f8fd82a076d89ae36d68b7978ee8e8686357e7f80000000000000000000000000000000015017546ad389c8f070d5dde58868610459ee62de83157d7e5a190ddfe129e6cf306c399bbdbb4a6133920c5926773ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d5e9424d25ffe389196d946370c73f74c8d9fec218a33c93562f9d5aa77068056dcba4e0a39337576668c2cdd1ef99000000000000000000000000000000000e32964e0608c964b8a8df2b7ee33aadaccf5a48b37e06161ba69f819f9cb366f4eeb672c718206cdb02c2f547f47b8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3851ca8be318c8a6a865e3b8a28eae24e2d7e5e274de254db81475e63e24e5a759ebeaaa623737dc39766381abb092000000000000000000000000000000000a1bd236e16e9995fa4d599bd76ca9b9958755a5e8f80e20fd1c52053fc4396705d737be433e617c45a3286e8c49c8281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005eac64826c95be4002733e2c74d3d8626afbddc66e01849ffbe9db4a5e6afd167e2dc6c23af926d6845504677ea4aa70000000000000000000000000000000012ceff652cfd03616d29adf426ad190f85be220dac1c68833c522b6e9f9dc323c32ebb7e4616991a5a432d8490c6c51f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f8ef24b2f4064978b73f96e3d2ca09e94091452d832591e2cee38564a8015822047550202c4d09912999c1c2189b25000000000000000000000000000000000ce90f8fc100d6b73f76c1ffed24ecfdfb7a778599032d2ec50e46d8d942dcad8b64ebe3adea226e6ce663558fda53b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188a3aeb6ccee304bc729930f41340b3273faf1f1cee9d4038f2b7e9b9a8aaf06708ba1e7b50b2f87108568d38dcfcff00000000000000000000000000000000165c69d3cc946fbc5c75ed752eee1d19998d2bf37fdab76aa8466f64594622fe7e3175403378c7411eb2d82b2528dfd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173082e0049c271a71ed0be0aab6eb73f0beef04232b3bb4a1e3097ec33ef74f63df992cb63509253698c20b469ca7db0000000000000000000000000000000014953ae5dff61ded4edfff0281b7093b991c62c9601f0aa64e1c1831c9a798e772d8aadddd8652802406261bb5bfba3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000299da1882f322cb02a59ba81abd852c3e6c1392355db52f9beee8d339a845cc82f1e5f2d48f7909412e523aa5bfc4520000000000000000000000000000000016b5c4377c83434a9c953cdd042404d0786a41bc582e7ecd88d8566e667f8afd6f03eeb437a65f1bd5bb550c230610721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f8b8d5f0e54a2d3b59307471bc79375a627aeb2a53233c1722c56dd32f08b73c50fcca05e2402a5a5ff11013f17168000000000000000000000000000000001194559288dbc2efa842599820b79ec60beb659d15f50d2f8f1958cf369d5c2627e47f631a7474564472e1becabc9d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b1f86ba54a90315811ebca01995657e54fa5b9832e5a69555199f4ffa356150664b7fc6694d9abc783ac78878e90f0000000000000000000000000000000000ed415e154044f9f186b0c2890ade67e486c401992189dce22cc011defc26bb1274ee9d3e910d5805410e0a0b394b96d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e13daa56faa40714799bf601004972470218cf1f3e22b5700276523953eaf818f98c51ca132db0f6ba2939ffab801400000000000000000000000000000000008f9da63bfe4940890af99963478ad067d85d5846a56a5f731ebb478a069d11617238b6441b5d072fb46755ec66e660a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110aa6fac509f5c020a2cd8dff7afb0fc584f0fe4fb38b32f62c530094653eccaf69b1b66b8cf65e16d5814a745ec5cc000000000000000000000000000000000237a358074639d00681cf993fb1c4d5facb7244c8f2cc7dd4f9cf1bf23582f91a8cdddf893b824b9ab11e51b8fbe4371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a44202404120d12ad00dcb8e3978637b48439700598074446098ee8f5e316ba00fc1bb417b7f68a03e35205d1d34f3b000000000000000000000000000000000dd4abdd77ef7629ac18d4d7a9b7345c8047795228d307d0bc270158d5ff8edaf680fd1c515d24f7741bda33a7c82aa11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006941c95cec9cf89a83b4b6147536df52db8ca2e5510ec2ea369c35caf04a4b61c5eec0abeb13356744d43ad3f9fda330000000000000000000000000000000018955eccf195b1f64ea88de73e6130c495c36c0aea23b57f720936383c0b004337d01cb51f897977766f637be51d07691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000225de0cb0825f7f99b0224da95e7d04144c24c7011300ddbc9831280170dc54a7af1c3f9a0dc2236d3d5d7ff53718b000000000000000000000000000000000030f95ec4fb1ed2c22e75c079f518d005e187e4e056b2b8ad5ecbf4202a71d6ab0c74017323d7ddb3a17f0f6e940469f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3f63df120c777024085443aeaaa51c5f8a462fa987a333d37fcefbe28a891753c6d13417dda3d4578b669b923c4fac000000000000000000000000000000000f11faf44779259ed20eb0be99584a9dbd6233d05d783cd9af6b6af1ab7121b3b51baa3de38af5228ae7765dc3b112411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74f8331190dc0b7cfeaf13973a69c5ca70a6f7aaf4632fdc4c5ff77705b52334918aede4eaf727cdd57f5081c50e5a0000000000000000000000000000000012082eaef78c5a5c8b8e56e02461898c0ec231b3bad5e34f8472a040ba8e4bfe7ee20aea16a274bfe66b0e7dcaadfbf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b79ada27bd10c66d5dfaf1827a4d87b3c054915be0252b452a03fcc4b9c9182f0e6e8f2cc2510033debde61d5eef47600000000000000000000000000000000073524e0f807bd65ba037268bf87e2e8df7efc1bd416bd62529d74e1cb997a03a03c30f6593c41a8452be8c716c4b9eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008361fa84654132f8ca7782c8d36ec8b42a578b7f23f6dba4d3732f0fa3ebcc062568ed2d23c07ee29d639106833e56f000000000000000000000000000000000dd7689109e813857e37d0759b164a81e78c181193954361f1b028dab011e3f13de92226ef520ba835eb38d7de36bdb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062e6d31218fe6c749ca47efb6688ecbcbe51bc54e49f88908cac1aaf95aac9dc3e917ecd560f6d283551cb4ec0adbea0000000000000000000000000000000005280bd041c289354d8b3751fbe7647bf63c35a2c4508aaed60cbfd5d6d5cd9b2b27bfb39f91d41f7efa539d1d1c56001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000163195c0d7aa2aec805ef88c7c0ed950c4ad12f68324dc4a75451454abed24887a5000f663ab1f06987ff267e0146ef000000000000000000000000000000001784335a91a1ca7f70d938d7c8c11f6221bcb7bb83f4545778ec9aaaf107653603bb842a079c81a953b562c67e203ad61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c84d7150b7966612aa7d21af6d8cacb4232cbcbc0cc12deb08ebff3f0a91627273e7c0f6b7eb3b24bb5156d5f2ff4d7000000000000000000000000000000001099ee918e94b1e965ef755b861e330a568015c96301c65ba4fe41d37c6f9a66a42cb47de4672bed3fa44a5d20a473cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080aff5d354abc56c3c8b3613293bd98a52fff3b326bdc3f1854f9a5270a9ae43be4478b99a965f640bb7af196d9f6ec0000000000000000000000000000000014cb47b9bc39de4a11e7be6c2200df708eccc55efc29e74bbe56f665caa5a562076c35714f55437526a702f0cfc62d741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097ace2dcd6ff27dfcbaff177965dc7d0dbfe354f20bab46096b03db1ade5a8ed1398005e6f8306292e6e649a24c5ec80000000000000000000000000000000010aff1d427d258e471ac08de64fc936805d147b5e2547b84187a6547f19cbc1f43a9ec4d3bb0e21e69597bd4081947181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f0999e7c5a9a1bafeeabf5f9e7de5e91f0f8e7e8b3619b2238c605528168ca452b9a7d231072833cc89e537ac865fc00000000000000000000000000000000046755f04f94f5b7461e588f9342b74be381ba50681c32a9deb36a286ba6ae107aa0db21326790697d9f3aad3fd75fcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d2a05456a67a946b87027b0b4157fb1a779c6e680f8417f84cd7e4bcf724c55a995dfc10220a7efb230054c5b94057000000000000000000000000000000000c895bad9887d9d2a5722f94623936337610329143bd33232b6b44140df1a813a1a60c83ab0d9f71f8f1fa20a7f61dae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102bc7dba8f07471d065c19645db587225d25b0d5d0a1ec32a169379e60fc6485b0fe04f9b80ebd9b1184eea4812acef000000000000000000000000000000000874e146a80456fd85aa35c1dfef99100c5f74a42143df11b33a9dc3bd45b5ae49230de02b93a136cfb22b3fb557ebd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058bb9a1600a071b03943f58986d04fefbf06d62c84e034293ce7f3d8e715c55fab5ba70fe9106f6b9bd17ae1f1dba4d0000000000000000000000000000000003e6cf22495e05480b58bb6fe3b656059b06485e944fcf6cc8a651e05484b5adbbc987981e5230b14998e728bf95db731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017354b6f0838e4d55b00ca2ad40ef5bf718cb0f8b3468e5999e1bfc995b9e4fa2dbb10f453921e8e71590e078fedcbd50000000000000000000000000000000012df80f6932ee3ecd9a76df6bf27ac0d7cd238e8b81928bbb2d7ce2147372ae5f5f802b6c58180de92f778056881e2d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9e43234724058802ea856a70766f643b903575511c8487423d92958ecce1da686b7024660411307f0fb90e0712716100000000000000000000000000000000145d45e6146d1600b0c0882feb4eba051fe3c01bf7e4f1963a38c30158b473335aa7059220bc7c7c577ab8d482ca57131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160f1625b8f4bd477f3460f2534cb7eb9028f178fbc95d403040ee5065e72a7c587f768db2119cec13a65335112ce438000000000000000000000000000000000a1bc0cb8681b18439bf90439fb85a9be9638827749bf1b508544fc645ecfd18e83e7e37f39c7df0dc8a4707d43739071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d24c035aac02ae370dbb54de50c65df8d7bb90e6061ee5c3ab83389d6f81e6b5955df6b4d93f4a09d77c936f6474130000000000000000000000000000000019dc107b0b9dca38e813b3a2712d7c0d85ba4d7c289ff25b3d58e0aaeb68c572679d9f41ccda70b503724f1d6e081c631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014322181b436142575babc3693014e785d1c319d058081acd161a1ef6161cc20a31848845518ac5c9160f22dd75ee581000000000000000000000000000000000510c626d87768ee402169783adea593d3711f5ce32e10b611344be273de691eeebfa49f29e0c98d4267ff4a77cc45ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b9e17182810d5c070b77c5a3526f15de26065d950cc4591e01959bb3ae5d363bb8e9c53d7f6a521d0f1c2f2d395d6a00000000000000000000000000000000094673fe6239478f93c35704ff2861a92f257442a9f083283e5e6490d8c4a9375a50b7a444d39e55bf088ae638917efe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019df6cb6d3116126e991aaae3179a83cf53ba338dde3574de97aea48bcc7318dab17987a2b1d7cf1f1dd3580c78765700000000000000000000000000000000156e0344d9fec0f8180a795511ec113ef7476e027270324a439b84371ecda744b9c9bfc51261a5f1ff7248fb81d1b26b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000386cbc75b64113c132fcd8d807c8a12487dd192a31a71f31b903580aeff41e58272904ab3b69ddfe8e86571fcd601070000000000000000000000000000000002d064d223d9fe62ee6d137386e93526051a794a3ff91a003659360a24442d79cb29c066ceb8f20b7b9f7e8a5f93f26f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008075793ecac6c17624cb68562c0679ded37a9a143ff6abb1855865ee6c8e95c31ba427e21457b072104075ae2e74fa000000000000000000000000000000000050a0254bf96db3dddee69d9654ac7819be2b7f650b0f31f9afebf39dacbc66ba619706fad5904aea6fc983d61103cb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018c8fd0b2793c7a79da208ef4b11504734a39f62d62261f2c43d13f5ceacfdfef26753602ec4436cc7e95989b7dbc1f0000000000000000000000000000000019f3ba5f4d2ac2afa2f2a0888e27e80fccaacb8200be4a3a8298f75fd0e9e21916a252467263b41339ec8277a50705e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117e0f07bba9c9e0b92a2e256e91ba3198671d540b45a730dbf9495a6ef0e0aeb320bb847f1de3e24b7750068225fbcb00000000000000000000000000000000111f0e63b21233cc205b47afc460cb38be78999da4c93ba25cada6e7ec6725ab0d0347b487d527f39c23accc9f3cdb921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ef6da9fc5c9d2d64b8a79d6204a379628b08ae2508ff528a217e803a91b6a7e76a702d48a40f89b96ea4b99433a470000000000000000000000000000000008943286a27cd49b4423ddb4f33ac37573669a1f3019ac2786da0796c14b7f4fd3584c4a95bd0d34a4eb74369899836c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bc096c879840d4cd15d7e5802dba2be47ce9baeaaa8c0c62ee33f9128d906792c831ac2b5963a4cd4903ecedee897400000000000000000000000000000000010c52d58e74d117c0335275fcaefc52ab0b525315ef29d7d50847a0187b6b677b44689dcd486c7dcfbf32865e9179f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e6162dcfaf71b35d02c5c8aea44774c2751902deda9e90f4d9be83965d78a11a32979cd8fc27097b03ce21e3b49f7600000000000000000000000000000000154d9a3392aee248682bf1aa6bb7e3d5e0a4c9bbe59620dc7869dcfb13beba012f5b6ca886d6c02010e031f14b68c3901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019da6bb122e6606f6227f1f9413136aa80a4f5a2e79f2ae02d570b9671d2be92af74a4b4d89eefdced9ea9d6ab4b06bf0000000000000000000000000000000013b681b1692c1b6f5e5d45c0652bdf986240e66be08b249f713ce1f59a73ace4032cb5d0318daedc3f19ba7f5f93a6961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120386e7fdd15633c18a108238cec88b3dbe9d1fd949d749407f4a5a9409a6b7be46c27cd8a09087e6e1fb02f0e8570f000000000000000000000000000000000435920c79d737f800f53801a72e6b95f96d71d743b2b77a8e24ac4ff3d378b6390bf6754449ac160ba18a428e2bec1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f212d0fd42ee5fe684fd7bcbdfb1ac8cfe7b1495f957cfbb8b006b825621a151a082da17a348bb2c7e1a8075cc3bc7000000000000000000000000000000000e19856b79cbd783bb4cb99372466547ef56e7cf597a231d27390906ae935d3ca71a0483cd1916b8107dc4fff5ccce741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d253612091eb02f7d5bbc6292ada98de8ab89f77d3d10dec71ef5d8e5575a613a493dbca65df777b2f7dc142edb089000000000000000000000000000000000e77e496cd62f43b54fc0ec7116c9dc7a898a081f5f0ac7abd7bc220099150bf4fd84fc7af3589f24b256e0eda71df9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdb14f6de4d16795aaf603d0c90f535644dc2c9391d48adc4d583005a03771e1bc9910f15047706b66cd52a0b9675a20000000000000000000000000000000004a54d32f92ace095430341bef42bdf4d870a784e72eb8093331c8c0653d11bc7fbf28369b5550e14d23acacc2d51ffa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000add75651af869dbad425521b6bd0ce921c2c67be58b75d075e507d46db810c0e8c870e6b15182495197c9c912e9dd280000000000000000000000000000000009da83bd5409c27c58b630a563af5a7babc3db0ecb3ceb6a697fb331d3a77b2bfedd275b7c34fbfd49974533ec6b7f3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000204307d5b8d62e593392795909de84139b0342af7bf62171e445820c4631e904a24a054d5144170b0d1f663efe14aa600000000000000000000000000000000048d5045d0962dd811a1f0c73a78f3b2b7f902c8fc6594b10d2bcb011a8cca0133dc25600f8b565cfb8f60f3849c239b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160b5534f3276c7d3f96e994166882162a79de9d59b11d3452e527b241638965172536432606628312921681f10af68400000000000000000000000000000000113733d67b4f4cb7e2e1e8f94a0eab139760606edca093fdd2c4d637e92bd927cf605b673d1e3130ccabec6f39bb1c4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002c1ade277d3187c4523a4da41fe7c63d7748f621baa8bcc80f7e08db39146c66f20e552d3f0998479bd244e470828b000000000000000000000000000000000c2d190380bd9592f6972e899040ad28b7dfb561a1503d4e0be04244906dbfeb2086831624d0bd073530b6eca5b60fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cbea001895711f57724c544e90ad87c1edc69832ed427e112cfa5b3ebe4bbd697b5f01ae12e7a95103c1c7097845a80000000000000000000000000000000011d18278cffd7bcf9e284313d5211d1690ae0441eff747b5cd635ad728078b46b85ede6850ff9965456e8be71c2853c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010dc20b32f6efffddce6de5c41e0cdcd133f72234a4d457ce7f1513df33354f6fc58f2f1911ee260495fa0b616b7e19300000000000000000000000000000000052ab431058cb7d63a07e73a4e9212b0d2b063a8b52eda6de956ec2c30996f37e7dd20723990c29ad3e0a42194f98bb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012999ec0db1401b70dbbdbdfad5d685639982b90e40f27486d52c706fc70847b34af58c1e3f150939c2ff8614c3441da000000000000000000000000000000000adb361227db201ddf96b44f804933772b94899efe07db774ec3312552d04824138a63a221e7a613756996a81c06158e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000269507552dac81ce5075863fe8d41c4b5df57b3f275ace4b42941eebeb713c56311ba35665b1e54202345ee4fb841f9000000000000000000000000000000001353a6f314ce8117841aa5951c38f2452e8548e5453a14d273526029ce9fe166a00ddd4cf72d5aea1e47b2dde52e0c171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf5ffe9e65ce545b1765ba7f35f4ea958ec5fd2e3adef61007055d8f1827a9d6624e9420334764e7414467e28a941f80000000000000000000000000000000002af69ee1f4b84b421331d6dc6020958131715ed9d1bca7a17ab78b050a48d7bc5e63f042557f0cf8da4e8ddcfafaa6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e36d883b6a378e1c61a6afed62702baaaaeacb0c4fe0fd66698f42ed1f3417f7dc047f8ae8258d41a7327eba08046c0000000000000000000000000000000018bfcd932606b55d48167be88f2d12ed86db995fabd30801adc68defb5a5d991afb574c0ad45e7792b68042d3318e3771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000939fc33a76be5a9d454cd698c16225981ee5190d8820430904a8c43654a9a2267464045ef738daca1c46f4d57386aa700000000000000000000000000000000050df6b421416380927eba5a7cb0bb753c43438d987219bd097c6e5ec9c48e76605d01fcf43e2f22c69fe5fca9f9e3f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dda9faa76f41069537f849f579de11c2b61908a97c556ee397b5c5395060a51dffe745ffebefce80bdd99ded62b6173000000000000000000000000000000000b9b5ee1ea775ed43f3cc31721273047f23cdf0a3ef71628b04468c61a8047498db0f49d29ee01f81141c0a731a0b5a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d1f23b937346916736bb4b2868bd2f4ec600d95488d296461d3c07c80c14c2c5a254e0832dc9cca63ccc43531659d700000000000000000000000000000000112956e0c677e02ed2b9ad1b8a4c28aadc5fdb898c2d76ca54f58c01b694dea4f2cc158097210dda2f85105af940b73e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6efd94aa1debc9afff662fe38ebff4a5cf0ed0aa4a225483381ff75304bddd39399eaafc0f21867ba3066f4e08ca57000000000000000000000000000000000d9e31904c9f4f65e8739583d1edafbece6fbdb7703d8cec9065934d2ef63949abf229df0ade203ac5f3b0e2d750dad51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a8c51e8438c89deb9492db14d7ddcf88a9d1f92928e5c5e3c7e2399eadac428e8d99f8dbdeb85681d4038e2d49d43c00000000000000000000000000000000160e5321e9c3016f3b1a8502f395c17b183a6903bc852d2de59e0bd1cc82a822062140b57d9156eb10fa831777877d631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000686968df25f3a1d6d13cb50559bff6dd42f6c78317a7d189a7e4283c4d48dd0efde47960133985dde75b32cbdab03f8000000000000000000000000000000001877ed3e0bc8f16d7dea421c1e7a9b484fe78c65d214b4d73a93f4e70344381c2689fc73fa465ae02f9636e11457e0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019535efa06d28a93b7b59826d0f4a7fa9dc92bec5c364567075b00698baf8dd4e8881a23f67d3b05ea2482d071d28fb400000000000000000000000000000000031ef5304bdce0b5df3356d57cd3ae796a270b856fd93e7570709f2205b95854ceeeda10ec060fff9de1e44122edcbb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab7830a7f90ceda6f238f8cd7bf882a7cce91c3a0e9750199ef55c85b2484f29da37fd332ac39a0fa435de030bb8000000000000000000000000000000000000829ae2db131e5cecd01125ea7d6cb547ba9809c74fc68df8587921bc01f637abd7cf4d650395cea8a139576460cc66b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000744f517cb9596dc4d9573c3c61c10f7dc3e052d3be58833e9860fd291bd831ef50af29a2dff72d35d7adbfe029099dc000000000000000000000000000000000085670b8e81d6de6070cabfd9785a4e07accd5e171d49932d5a8c6fec59163e361d1801c5a4a27c77daa46801f666de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007f2751987193573936cc8eb78937d51ee031ed30098392d63e392af93f73895cc000bc883c9a57019a3555f8d81d03000000000000000000000000000000000636777afef84b2c03cd4130f70b7ccde36ee824a4a9aeb02787ed27f5ed657e9642a5959bffc418fb66448c44d298da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ea7312a8f2f5d8d652f861c25a4a31d396bf92e08d94ece7045a6598fda44667ce783f0531bd1f7147a290692cbb7c0000000000000000000000000000000017a6d8b4867a4d15ac437d775ab89cf768e921e50e703c9accea84c15aee8626eb051e8e0c41ee2d860639b5ae2f9fec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129d8dfbf6a338e80af2306de6625e062e0475afbbd9b4e4d74c583f0de1b375af92d6cb05da449749a60461c689f5ab000000000000000000000000000000001093e809e4dec4c0d63b18d5b8cecfe1d8bd1f5e5b35f8a3720e3fed97de44dcc8d71cd84440ca048c80c8baf8f1d61d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a28c31cdc6f18d24c5127f3496582c884d6c2765ecd82b1e9bce844bfb7780d89d9d87a92d2d33d8e94d952109f21100000000000000000000000000000000109eaaa89b2dea5af12155c44e0e25aa01cf2b0625f71a0851b57c98dd78214e3d60e452a750a6fdeb8458c899b4a0c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cbaa1aa05f6365e5bd07c7c94b641c9213ecb1d5e00ed2ff0f1a93950af31721402896f8f9f77609abdfe058df385b000000000000000000000000000000000aa6dddb7c46a83c0d4655977afc40cb0ac91feb926c762259016aaeea405628a5187ac6d9d84e1574a6e3f0c89cab3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cc0d9e7faa9f2e362592b6790bd1194f29143cd62bc0d62ab316292b71a2774803a0b7ab0666923d862b7ff69d01f80000000000000000000000000000000012ba54036a1e35bcd32ddbaac27b3e5dee76293a1ce599c5e9e5bf87e4c0f802426ee2643745dbfeb6354d2affe429f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d0207509e7d0f2dd13213f731fc977be1340098413fbd2ab7c54f2ebb401185a07c4febbcb2ed5ccc4a480551aa0a300000000000000000000000000000000153eca6ae8f272c052a4612ae30d06d93d44ff2bc46d1d224574280b3237d2290816989cd4feef9e9b94f1a816fd13ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e0f8197ae9b1b4a31e721fe6ad0c2895a41b11bb285e1cb0539a403026c2efe80e4143493db00afd4a72133a86c1f0000000000000000000000000000000003267eb1f9a472763ac1efeaee92b689e47e58e76894f2afdabc33953b2873958ce1a259bca68a0f1880007b11b185f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002259000f06b3fbf09097b088f53e18068e3037b028517c60c22306d95bece12bab7b664b7fb68e71b7b93b6df4c1e0c0000000000000000000000000000000008aa7d7c47d3da648caa39df70f5c41f36e18e8954e32e859b3f6be2c9b49f0d5353be476aa275bcb481aa40ef1c1a8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001525d9745ba4095f7cfe08fb815ac1e89bda89207cedf8ec5853b56d0c795088a56ae454ba0422451cb0725611e482d200000000000000000000000000000000012d4d9738806dd4d26b73cbb6c77832bdd3ce690e93d035d439b01eb7dc459dc18da7804d809af45d6bb69bd7d653b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023d58997b5c8d35ff94e40a26976ac4fdf4c4bcd6cc48dfe519fcd65b50564d41f9df4b5b1cc8cb4a07e163b097ae5e0000000000000000000000000000000004f59956e4999c865c580b01c379e4d3c68c13b85880b8b9baacbd21eb5d13fb3019dcb24dbd6549ff4e96166452d83f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff36f9be04d939cd7ac2dc0d538db15733886ed3b8c0f4776e95f46e155f390ce1699eb7e25afd371fc636029f25cf70000000000000000000000000000000019bd5c1b48002efaac48cf24f184e71390196a6858d59184359e85937eb944e15ca9768dbaa7f77479c593ebe8e3536e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b27d9b13cabc9f9b515cce517559da96042ca0d0d92406737f1d95e5da465bc0a3818a865e715d11dd9da0bbf0a4fb00000000000000000000000000000000120c1d610eea3049d67e43f133c265d92471609b780b890005246f90a6640fb3827a72f16a04b89d3e005d825974a1871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133d2915ebdfe7443d89c8ac69832742435299129a345075d2ebe77557f770bdd2cfe46f4cf83931225548c6bd60457e000000000000000000000000000000000bc53aa2883b13aa7eb9bd0cae4e3d70ccc7bdd221d069eeb1435cac2127278638a4a472627aed5ee48cc4ace75346fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000938665903d30fc0d93e270802b81423d39ab264610d3740c28f7c808ef138f26828f07fb48a502a9995598265ebb57900000000000000000000000000000000035744722a3deda8ec074a62801208e0ca265b8012cd231d8cf1b5710f7c5e481378ce5208b2519b91a091a08a8b5d041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d765593ff173c52b49db1fb3b1bebacaec51852f07d5af1b767d733a85b3a84fdc550df0b6a749da2e6e633b835ce900000000000000000000000000000000052ad9c73567fad6fe1f17041931bd0a0fa72c755b19cfc6b615df3f4ab7dfa2b6232b4c0840ed991a9c1dd76f4e6b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008fd1155efaba339a4b153683fe1390528e93e144d4cc611aa4df473ff0100a5873eb76b1a99bd3e55d591573ae4176000000000000000000000000000000000e44de38a58170061ac988bf3b5d15d6db629c537e15a5cefcacf4d65f3ef3378a911f142b5f679e91edf7ba4177aed11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec37af4c86def87346fa8d0ac6741074c6c184a19142d72d5589d3eb1d3ec535af4014a3551402332957b1e065460720000000000000000000000000000000010684088134cb1eaecb6dcf154f1475cac9c2ca8394bd037341240eef263f58e64abcb6a17f303384480502bd788c2f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcc013431c096dc6fec985bfdc51b5907512c07ef592fa97e4b55d1c0c34e3ff62f60517f209e760bf0f1654fac3dcc0000000000000000000000000000000007a6705dfb802b8bbb83d7e5aee2fe32fc8809e664b7a89d08db694fcc2eddf75f6a6f0fbfa5b77686b8e66351b7e2bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174e672d9cbf5135727e4a1c8115ef41c379ee8fa5d8815fb57110a6e946fa43878fa0dcf1846291b438db8019f2cd8500000000000000000000000000000000122908e42064d08853fcc60517880b889f7e7a791810d39c8e4179ed3605977304c5d2baed33b60f18cc432d61f0aa8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029312d08b91687ad0da9bffbfcbacafe745976b6cccdb9b2cfb251a873664dd6e83e3c2540f208e5b885ec66d0a764900000000000000000000000000000000189e547017655de27d90b722a1bc728ebcdc889f775b064c8ed9497c4b7ccd780e335f8d0e9e1d30cab4acfd666e0d1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb64a1d534d425c41b35975facc39a1d6a775bc566a9748cb5a77c94e14d36caad9ac029f0db9a89ab1caeb469207450000000000000000000000000000000012b362f1e7e6ad18dcca8c49681c26afa32216cc46a8192e80e17cdf27288d1642f4b28fc3a34e5d03c3475dc20cebae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047c5075bacfd47298b572ca3a9698d7e2b1948e2754adf83d4d28eb2a5f01435b3d851afe9f89b2aab4fa48b726cd2f000000000000000000000000000000001584a01c0bece725a66adec84bd563e57063881e7154ff82bae17e8ac0de7e471213ad938ddd87a63b2b44199e857a111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccdbb9c4177b9952e168ca548a7e535337075218e0ae5ef1374a9dfce640e84b16d0db7a6b8928ebf0f1fbbe3b521610000000000000000000000000000000001ac558a19dc64be05afde347ba96b710ce93d6a44b2ca6d3e121c5827f6228638fd812e0e4ec601e23549273f121d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebea2ba8ee96161a7a47c21037c6168f70328e22a8a4a521693e70030469aab9505e1c5d2259805377ec7238285e8490000000000000000000000000000000003a2a91c89109cfe1312b79226c2aefb7b1b8663247b5817587ff22386981090f32c9389ebd160dab0e5e322c3bccd691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a22c4eb3a8fd6a78477f860906208ec9dd9d6ba9cc2b2a68a8245d61a52e81b41eecff0929731806724af16c807fb00000000000000000000000000000000010dc39274387d87221d3b36a1505147537ee4a4d6b0a37d8e725c26fa33549e2923d9825bb47c79d0aff631f6bdc0fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f1613809eb2d678822986e9d9a47e6716c218c0efbcdcf6e3249440622f8bfb0234111d2ce3fddd41bec43199bd77b000000000000000000000000000000000d948380dbffadad9bd76d19a04f385051343be2365cce283411a97a90bc5c3eacc9a301a7698b93854b84ead7cadc5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171713cbd3ebe33a3ca2930cc7c88db56987c176b7d019c4df75d29e57d50d3e90562a5691e214d0a52928dca66edd4200000000000000000000000000000000028d093ac89bbcc49b212ce990a288d9502b3738ac46e7c1badb3f832783c91da63ee482db107dbb8ac4dff5bafefb9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000093b6e9ea3d375a43108254f6de3f8bdfbf379823bc48afa64f3c91efaaab317328561ecd5765555f41a2980c298ab3000000000000000000000000000000000c3b126edb0cd037c6776ed67a459a2f65cb10e8164ae2cb58a272e81449d05f64111e49f1e45631aa2d1f5f390c94631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ee2c356a74a56210590d5a5fdfb8ada392128a15837646e3c1b5c2f554d213babde53573632fb42e61fc2efcff10a20000000000000000000000000000000019fbe6f59dcf0ad6982c6ddb523d0e2979c68292a50d71025e60e92b32cff4bb9634a03cf69dafe9a355abba41dc3b811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156a978aaf4ad0b7212eb042557ee7e837add87ef683014a736d17cb7989ae1d468fab7e7603907e3c2e43b485745b8900000000000000000000000000000000144b33dd4f07533789c0aecf3b31fd7a13a623e593387973fc2d13a7bc4dfd16607926cecf1b7060283dc40932e92f961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044cd95f78646ece01df935114583df43ccad16ff65b23de01191f2e6d31562f429c1cf224a3b527152f46392649159c000000000000000000000000000000000b45325017cba543e05ce63d068a3ed9e3f14f1cbc69670526a5b3dbf5bdccd9f1b6a19dc76fbef46238fbf3ca8135d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ab7580df53c160768ae3e40444031939e165a63c3e8b4006333ff0754ec737b0774e567cd614513f6b3d56ae93de77000000000000000000000000000000000464f1ef3df22ab0e0598a4cf38fea26456bb36ac9fc97ba6afc7a078735f4028f6f048f0df9d93cc6739dead32abe621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a950a9ff0fb2a6ec2b5428bbe0a70da80b2fd30acc192439f66ca1562770dc5ead051ab9878fdee2d30c9322df7d320000000000000000000000000000000013c6d457a46cb3747c7cdd272a64d44e698458d6b01af33f1659840c22d9b9d805f728b53cfbf882ce338248406188db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e29f11ecb1717706da7f0f8ed924105d1dd943f24016edc5ce7e5867ec1ebb237e7294692bb6cb2709b88b9c60d863b0000000000000000000000000000000016fc034eb0252e263566ddc1a692bdd4d8a97bc5f7f9281681f675a068e0fb6d77e8a92f9199d85094885175a4275f9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000682f53b1e78a700d38917d27039a3969304f043b4e163dcc74d0298e5f8293d217ce863bb69e6c183d9a293a0f58ba7000000000000000000000000000000000a88060199b86d0c1d5a638ca971c188139e4920d21c33adece5825c4acb336466472308788545dec1c5201133c2be5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018da96d262e9ba7b447e03f5a68c54ed757e513d312e436ea33d01d58cff2f1e0ea2f2f9c59209ab330a00a41170a5ad0000000000000000000000000000000006cf4d75383dae7bb7b83d2dbc91fd7a72eec82eba95fa1b0e425c33f82711b4e51db44ba5bc734c4e01960cdc4653431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000119f8821e4fe51fb759ea968d35d214dd63b89a50866ee1cdf5330040b7963332e1085f82f4dfa18302bda702a746c000000000000000000000000000000000152003d4a9a32171df2fd57785058fcc5487ea9965d151c287908db4e8163a71fb333eef4d91a2dc99953b9b1914ac731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aab889c581c59a5185ea72659a4ed8f03a83e7be5595e0e894185e2dd19889cb09b5a0c48246078e2c9a8f8729d05e50000000000000000000000000000000015ea01e37ac7803a89a879166e97dca9c6b96fd0288c1663a6bade53459462ad89121217613d9c54bf16a821e5eb0db11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f29fb94134c120c4fb61d7a90aa43e5e5194d3a41a92ef28e88d17397ffc99302c4dafee3f47a0f81f758016c44dc9800000000000000000000000000000000120715465f8d0f1b55c5d73779396af0ac85cf5fc7a0157549278367209f67b99418ed98ac58b168ef2a6c9f84cac1e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000051192eba0e3ba46a89f434d5efc7b506d5d7b18fa74202c8ceb9a83166230477e8245db53d67bf861b69d7c099fbdd0000000000000000000000000000000018fa8bfd85f3878d0fd826194bc7b63bd8103641ff7fe2d7c2af158c69260367010fa651b364260c325c85085b12e1bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b327ee838cebc2607ed856e2762983b4503b1cc114dfd1840f85d8fc573596cd92b0f8031f33ba0f18bb4a6882afb40000000000000000000000000000000019975b3746b4970a4fe6ba2b65ffa7167ef8b462ef9e09276fcad52d6758296a2f2896f9d1bed1425416c79e7f27b2591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d040836b8f0fd1beef01dcb78c28f3679a6f1c7d49d20d939d78b5d2afc9f8810b22246d991dc7ab0fb5bb944e02f600000000000000000000000000000000004032024052aeca48fc75f68d4057dcab01868c2a9663a61e8c6863fef645bcca35530742b7c2b5e8c1d8b73801aa161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110f3036fd7f990044a5a994d7090d92b965bfded7c173aac71f1c6d9d784cb39b88d1cb7ac7757b9926d0e86cb58872000000000000000000000000000000000c2e10abc4e4e1a4cd78934c57c593830ae5accefc19bae86d380323a128ce3e0d8676831add497c5bb77bb26a57b80a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cd4f33dd10fefc7cf8e9c97216d8a46fed0a851006dbb38f049be4ffb15e2096d271c5e33ee770ad8d6c9bbd720dd50000000000000000000000000000000015bbac0aa5aaa83e03ebb656f55acb75a941ada612d2c2bf1b1785026c50c09056ec58a84dabfd23196ae45461ad88581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001643d59d2878df98ac3257f3056508553b80699e248841458751048ed3b4f7b50d520108a501d09029988f89d652f25e0000000000000000000000000000000009de02104c72eeb1274c7b1d3024398ce1aaea629044ef4587b4b744f1d536ab2c5618b5a4a6737e6524b3dcc04a3d721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c3ebed669daca862c519ecd9d7d52a1ba0928bc221ea45dbf86ef4609963ca484aa3f41bb7d6bda0c90874349b30320000000000000000000000000000000010b2b46356386ef179939b74a59eddbde29f88f3feb4784f0be394f0d5ec2c197f28023e59e54730f7e4501ba1ef18391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f4fc540c9e9bb5bd2524a731ea8ee835653093724438ae30af940fee5d0fa4ae0ebd215e79a386c63d26924076ca8c00000000000000000000000000000000019df2c0842edc384f40561fc33fa85d413f0836030b7770ee4a4a84fb25c95ce15299767cf2f0b847229d316ce1c1c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a829cb37dd28c5e941171a6e43ed3919a3f7cefe2a1e31b9bf6a84ac2fc089f95c80854b3235b3ba0cbc28fa358a58a0000000000000000000000000000000015dfa67dd80760affe476bc0a2995e36ac29feb084ce6b3410185af654d289518ef6fc55cf6ef42691fa7d20f71d419d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef2bb65a36641ff3965194a8f578ca9ed3036009f89147d63db2c4234cbd41d5dff1fcd9e65055f71dac16be566e0f50000000000000000000000000000000004dd9ca19d72c8de4cb87121a37145e001fda355ff5bbf9dabaede4cbe9002a4ba50dcd0f65ac8e4a59d5e0e34a0c2601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c16eb8af28434e6a1548e4d256075405a48c3b8448b80b562fe1bc1c8dad1056f6171768a98a72f4268f7e25e2fb100000000000000000000000000000000035154e2631a09cf0dedeebaca68f15f51ae998434ee73d30f16250988ead13dfd4a51fd126e0d4f8675a4015e4d76391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7bf09da9e26d4258bfcbeb38463b15341960451dfc923ff5fbccfdc90cdc76e6781832bc65ec4203d840ffe9f4f204000000000000000000000000000000000cb1c0fe98c51fe9db06c4d9020823008531c9e3b7d95aea44811f89f10045909b5789bd637b60d2e79e2de79e38fb051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008619f14453a135a44e372edb80cf7d9b8d3796f2e3661a3a8dc58bc8d6915c7099a36e6d52f25c215095fd2b8e90c8b00000000000000000000000000000000008c6c5e395249331a020fd14626b409b44005c6c9b6cde5543814444a58060b359decbd3365f7064a6da7dbb585fcdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad7801d28b48167a85d962cbc879781b51594e1cb2b741cc2bb188ec47ac876b692433e5c52d961b8b94026ec5deef5000000000000000000000000000000000dfbfdfaefef632841a8e679bcf1a6f98c6800a52a8406d73dd947be51cd8d100926bf1b49fd843c53699686939fa7ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbee8a9ac6f7d80dd314618abddd5d6f3dcc6a6db7295d4cbd07c54320d9ce4fd71326049c14bde60cb4525fbf0e248000000000000000000000000000000000d72127908d2368563461595c87a3b65c71b9d078578b4f7ac3f6fe26146389c2a7d244e35e97cae339dc288cca556621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047be5633b0d5e3a7ae598997420a2d3df0c8a7b52f88563159f90edd044d99d587990e5238224ff0e3e0fa1d8e10d26000000000000000000000000000000000f0477e0c8ee6e0fd9f11952b495561ab6b6e2e4da357e2cad5b9bde7b1c01ecd18623fcebfcbd0b4f8ad910f2e2c2f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b8ef64c209d24595d98d3668ba6374a565bb367ba077ab77cae3462a02e0bdbe57d572fb796817a6bfed4397ec9d92000000000000000000000000000000000773d08245f1f970bc0157cecbeedda7bd01b35e2b4a7a7eecba84e81ca630793a7e2905e5c2385ac04408732ac24e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeef118721adf15dfc8b4aa3d7f24d25e8e93d09448650019804dd4b3cf542403498f14c0b6d26351d6923f25849b3000000000000000000000000000000000156b3bc736e37b9f403b6e58c5915fd7519a471c7b7b5aa5ce7892a5094aaa827b4822b7b7a282e7771094dda8c139691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000566f225acc9678de46c1bdaa2fe77a18b7eb27e5b4203af35564d1b7974f8112ebad23aca88463950294b6651a40eb30000000000000000000000000000000011cdd1f402bce43ce1cb158bc152a68aad4b5aa4b7c7d3c9f2d0ebde56ff3534d20c9e3244bedc10dd074b1efdd975b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005105380b26cb9bdd08ce17995308d16621c12376ded3569d67c01b48f794aeda3d7d0351407507c184c9a0a68f158b90000000000000000000000000000000012caf0e94634aae6ae9c03baea1ac46753987934a03a157d7ebc454b4b9fe40c134d79bf2b71c3b5c2e2c0446827b7531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d7ea85ef270140d5f9cf89927d756345d2149815e4811318b14b542ff5e0b568ab9f1276f4ab26b4ee1fc7f1a9ccb0000000000000000000000000000000000c84992d8ac6e583201739647b254cb839db3751e3d733abc709ec21ac05eabf15f0583bc81eb3ee7a5f9dd31f3bbaa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016001a27e7dc197ee240a9093d541170e865f430e0b69b4284299d97ed9f178dc55761209a46b3c012c429b26e9de330000000000000000000000000000000000650c7d4afdd19a5d8a9272ce638c0f6141f3badad71dfd262d6e6f487f3ed5ffba6d083f63dc00fd13972467d85d8ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a103c5dc82a17cac194fce92956c9d005ccf87cbd7ede79d56b1113835ef755666ca0d6f5746ab4fe99b44251da0d900000000000000000000000000000000192604f95d96f38bd5d6827285bd0d164e71b72ed8333f7150b189779920048e04ac9cffe60908fe69de0b6fbb22529c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124dcf9df82674ea54ff745ba6e8024480c103beeaf2cc8f4c5e40bfc31e409d2d92794f3916381cd1e8706c985698a500000000000000000000000000000000052b9b88007f58ff9ae8a2618436c206a478616cf869386b72b0fcec7a09332ca84836907d3706c9740fb473455745151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117b2a3c22e9ec184e9c8998d0cceeb9174b0e2244711e64c794607843941d05068f0b2aad7f2e8d8c0d6e1447a193d50000000000000000000000000000000012554fcea4b00c2ac818a63303288c87e913bf6f8eec8797a1002a53be28838f999931a04bff641efc33426141b77b231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6e99c06a8562d0c80e9289dd12a1bde931c8d3ddb0e4635efa55a81b214d619504a79fac358fc18c8344ffbda16f36000000000000000000000000000000001255c33a9c33fbf95328ecf9193a33c5d4d63df4962288e939387bafbd51040cdf37b9881894a9523fe1112962955e3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa29063860e7d4943050773c233049f309d2ae30ba180e29d348ed6522e5db5b08d6abbfd119f961f837aca7121f3cb000000000000000000000000000000001897cecd6bd872cda410471eeee7365a384340e5aefef39fb581e2d45fb37b0b85b66d31e628b2627a4d7453083254241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000996184b3737624d216f3650b84aa482f943b932722cf719bc8aca5166bef6622926afdaf17119b430e309d5e8b0133000000000000000000000000000000000e638d624c7c0f61af5446c9c7343ce399535c1289ce2c4f91dc5551420997b2d2cf2715a61e2cbf8c2e83dc19f6c51a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a11a0faa8eed18b2146328df63c0ec633470130211218ca88983819c361eb70cb80fd4dbefe2c6c1c9d040fd595dc20000000000000000000000000000000018cdd5506ae40955b4b444303bfb09b68022c1a215b8e065fe808e576cbbf7b096f296d7d153d0a4d5cc4812cfe4f2f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e96ebd31885b466bdbb5d828a47a636578509fc52732d4475aa85d85f74cad516eb16f9d581ea8daa0b96ea5494af300000000000000000000000000000000173d251234dd9e55602a505eeb279359b8da8a78976feb8f6dd25130c149f9963535a14fd72f3bbf3d246aa702d9f04b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e5cd30072b0fbfa00d5598c7450491b030dbb2ff13eec22c13f97c8b9a53aa692918d3f29fb914b6b474bd0b4562520000000000000000000000000000000005858b922bcd4db8c2b4e68588226742cc1af43a7b4a0d428c8479091ba525eff740b8c62f5fa0981f974b834db7f2a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fa247ddc79645de2835867cfc818809f6a84ddfe0630357371b42e32b9d6a192792b8eae9a580939099631ff09db530000000000000000000000000000000002cc765e0f1bee545c3c55476fd04b5683c81da9fee5d4a8d48bd124e2e67b8081437e22768fb785615521c984483bd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e0569715d5c9d07289d0bee3d0eeb463994d2cb3885ff2c810856f3d8910c88a7415b13ae59c52abf0cdf7f5614c01000000000000000000000000000000000e58335d30de74a1ec71138eeed8f2e65df3d8e2fd228562670e253e5db6297ce5143ff697702e3382551846654c88c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137db28c2d40d3ba5f4ccd8612509736b77b5f229612d3114b7917081d7ef5a0ca03ee160d25e4823ea87240ead566ad0000000000000000000000000000000006a42925bd25877e15fa7dd843ad4babb0705b0b5d37d19c481d87215ea8f866dd424d3a07b11f6d7b7831db4855174b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f8f1d8d64d431be80826670d4f87d04bcde52d9077e36284a2e56dacb2bedaeedd98d32ca26cb9c16e364dbe3b5dc2000000000000000000000000000000001953e86f5df185fd780f46488cc06611c2738c8785acb86c8b4a53efb8fb6f8717dee8dae5f00601b3379eea7e98ef061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001074d846a6806752fde4347ea400039f77b5a242bcc9276366d8628405204c70aeb59bd03c0721338e4b87ee9edff1590000000000000000000000000000000011570d4ff979cd5baf1a8b0becf89aeebc77d39a3026beed2f8b3ee07c94fd24d391d8dda9f65c006359ab67bc5d8c2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cc49cc2cb37d7188058b84a4135fefb3e09b2f461a661dc2cd9f7f1a30ab7eba3620f7b77fcb8380da9dcb9727050e0000000000000000000000000000000000b8f7ea7e2f8c6cff5fa9a4c912cd2a913fe474d9ce2125b6cdb05b00a8305b67fafab4cc4eb3f27574bb38e6032bb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2fa197e604ae7fd31fdd8069cd8369bd03b01e4114dd1bb8d491fd556d6a2f54559a495c54239b75f9f4403437ec9f0000000000000000000000000000000008dbb6f24ff848d19b857f0649357b9cd44986708de87a2a7eccc901a5a181ede8ed4de8e3c69ee876ebafe13bb2eb851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006944e73970d0f02a06d39beac6a14961ed5e0969f3c690b855fc98ff709c09def58675ed0f3ff5756477d7bb8e5123c000000000000000000000000000000000dd082e85a1962e7d5960d26199fac8abc74e85f0eb164f5054cd58cbabb35ccfb821b22cee21575614ca14523c6d77c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161ade03834ec2464e75137b0467385814f90cedd335e69e30b7cb39be84d3fa2663a323355bf7acd88646fbeb883c4c0000000000000000000000000000000011599339a8bf243d320a848ac00386f5d8d4bdb60cc3f7b6598116728e2f2d94ab73c15c45e9cd5f5d8a6b9e31fd3e421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a3b317ccac0354071a3974ce28feccea6f6f71feb14fa764ae80bde043c86bbafa5d4d47ad9f73ff13e93c5948ad0600000000000000000000000000000000173b0b63fee7eedfcf1193a3ec870bae1417239487a4fbc83c7ba36773ca61d6cb92aa86958d25fe1c34fb361c05056a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e362f0bde50f89e79c5d74641d3afd24ac658292280b97d3e50e2d35534364998fd9ce9185b8cf92edcd9c74aeba884000000000000000000000000000000000d27df92d858ad19b40e1785feeb5d1dca13248773c7bddf40360ec874977265236e594194bb480841e0fb2b9b440c371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eac9b0f3d86a5f30ad7ff365e33f45313ebc1b5b5ff985e575dd6f3d0cf80924af5d1640d25469f8fb1d9ed7b10fc0000000000000000000000000000000000aa3385e750554244a10768a4bca814a93d51d62b2fc92ed0499da9ff864a7644d67987f73585e926da4083a6866b6dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d7e97aa9f5c08e6b3a0ec7c2aa4fca12edc36f192b6cb409bcefc2ef0577a1ba06f9723470015f70e49e922d02cf3700000000000000000000000000000000096563dbf1b11f34b69793a60b46cf20d256e9b0bd3d16160c983010f9eb8d6c8b600ecca4530bfbeabb0e4bf5666b661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000624ec7a4ce6d89e70d23557a1e91da51eaa465e11d872938013ae1f15284610a3c74b4d3ff2d4a258fd67b523070930000000000000000000000000000000006a1e8e1cd6fd18e6f580a56faac6115659e0d3385cd3343369a69b945bd76e7b438535c89ac4d6ffac14a1f9165e0901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000947085c97fc9ef9de91a970f88f0689fb251f205d258a8621b64b2b44baa5f53772b526aacea7a9a74b186cb0f6bbfd00000000000000000000000000000000029ce2f8622a935b9cfae1b19a54a998bf12128a0af2f0c2d304ad497a2d657fe8eac77815882cbc7f3e223895b6ba921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d3990cc9d0851ac93e3d8f9b51a2bb6efb84eb5f5a9800bb9a49cfb71b01d17683795d92b3abe2123473b89d44e5530000000000000000000000000000000013841db289accd77400a61a6d771b54be3ba5f7c23f8618c3bb6adfac4ee0b5d4af8a9b197b2a02abf5aed031c6e47a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fa80e938f64a5bd0d559ebacf2c0ca1479da9cdd05d3de135471fc03928dfa6cb50cabf89b0699d654d6520af9f619000000000000000000000000000000000c7403b38a37c84682383d86a74477b9951998cfb33cd2e8a9cc69977402ddcda3dddc39742c121f4dc9b5d75a6f817f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2e89d7cb46f202091726904980bb8bf266e70b753b479df561edbea6d3f4ed4cb1477a660f029b6059f82b4a0bb96c00000000000000000000000000000000118772fe9b5ca7796e2855d07c2558eed456dfe1e63821d853d1d2bb830bd7aab7bdffe8b760d434c54b257e38946fcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058deee35fb35298aa2400bca59c257aa8d87ad30559608b5da87eb2ced83ab157849390198a67dc73d61ca072538c9c0000000000000000000000000000000000235a134bccae84fca2465645293c2d0beb755aae310dbe62d417f360ef3d343ef6cbfae588b24787b98f4a202610bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4c23578797773ba21ab789f5f297e08c8471577f61d5364569f04864d09ec73ab8d2221fdba3888e7295dc3a7548700000000000000000000000000000000007fc18d17fd41d04bbb76081c64047a47c52781eabe1775b6336e3916967d38db194bdb52e70378bb80cf4d4efe327391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c933acc1890b4b0097df4ad57bffe8cf753ab98ce76f4497975e56d27032b2cf692600da65f1d3d128cf689aa6ba85000000000000000000000000000000000244c3de4789cf0ea6996911e9e0db614258372fe5fa06b732542fad81182bd6a03dfb956c44ad68b0eb2ffaa1ee203a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001399489803750d0170611d6c26f8e27039b5ea9a982738f7c7830ec47bdb9ac33ea516cca37f1837c7c577acea055d6e0000000000000000000000000000000007a30645d8912d66825a7b7f20480fb9124e6c215bf486d43802757e7e317066e5a8eab7cd8f4f9184115b152274e21b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e85451fc6b30ecf1375ce4fc2a1eea6033327057ef2880e2d44465cc3e2942fb8888ee93cc244fe33bd9d2ce392c98000000000000000000000000000000001005c4059a2a81768622c90f8842ce77802f3d71519cb3c89090f26f8b4c57c3fb4a6f3c114b0fce587760e337bca16a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164042ef1d66f14484fd833d1e794a54eb119e3931d21a4299b707021dae0822787d4767c46824f12da2a210c170e1dd0000000000000000000000000000000012ac6a08f0e36ffe00cc3d5075bde17eca2438f152ee52259ef45ff867179e839a3f7d7d8aced02e71ad59661c29e56f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d4b8499102bb2eeebc1117ef48484a0a17737b0f2b87d171f1ee03b5e7b0c10b92c54f96d99e5e4eef07984c475fe20000000000000000000000000000000019dd0aceb42bf192bcc849cd65ebc13d61d2b4c2746925adf31ebc18f158657f42bc36ee847193b864fb3b4b035552881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112603f370343059004a926005c0cf8a6f641d06dcb0a6a7618b66bbe163cd51eec2e58ce3d878233cfd252d6e3434a100000000000000000000000000000000060b12dac962a0fee142f2117aa050048c676229d524903455b838359610e2870f337dd387a42621d47129528c95c9941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e182c7452b78085584c253265c65557dc2e10739322e1297a3166437d46532db03e6dca9394530a728ec9ec6a6ff6d00000000000000000000000000000000113dc255b64b1907b16f730f81f236f3534d0bf3b678555c94e445600347d13e2e47caaa5d67c854b554c0bca72441381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd34dfc885f5b23b9b28c7f23e6b47f541a2820e627ea86066042878a28623ad745efa76851bdea23b93b34fff075c100000000000000000000000000000000013bcdd250fe6360be808777991d0cc7fa146cec8ee9083d9e0484ffa77c9bf51a00503a5e3816b7d006d1d37bff99591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d2daf32581b961b1f0e4b9b688ecdc7c5a267cf368ca21f1ad1c09a09243da369b792d2baeea0b4f83a973b491cd30000000000000000000000000000000000555ad8682fd20545d74365968fee0f908aeefa614c94c7a5ab534d9ff155fb429dc01dba16b480e38922986f92a6c331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063a8479ef8e3784fa6944409a64cd944c795ef311fbded7a88e62e832ed9732a20cc2fb53d96d3c312ab4a19e99e964000000000000000000000000000000000089f2fdf008f122c5206773d45d1c8532cd73dff3683e639d2481a0702f8d182debd48002707c42496a7f8b370be71d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000053c5c5d2517736a4b1cb1e57ea1de8d5f7cefd900335e6d67b25688962eaf834dfc3f8704c861a851cfb7ccf06620f00000000000000000000000000000000090d69c777da22d03b6e37aae0e44a7c22343f14c30bfbe68af60ef4de1ea3fac8b364c22702eb374ca2d46cfe2931851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5fc05480708ffd20419ea85953e9e52c50450f93d35fd966fd3c04593dcf1ea87b0b3ad80cbc57104a3547c202077900000000000000000000000000000000168ae5840afbb7d2438186f6a8228a24893993d14fc5bf21aa0aad39861fe63341bcc130ff65b5c6ae6e4b5f3580da361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172ae3ec48df7b20e1f4a17259a36cf81337934ff722f12ce97f08f342f8dea2606ecab6999a29e2514f8d71ac498fd70000000000000000000000000000000014a95019bab52c0c13f66037f12d1331d3bfc479e18b3a4a239a2c28ebfea145851609ad97d299ddf46f8b992e6f61131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce66b2a982b3d8a93df162e5ad29e40bc39cbe3743ce98ff1fd3603c2bcc732bbe7aae6f0a7e9e5c26fd7aac991e7c90000000000000000000000000000000010b1d69af3f7b892478f144ce62b3536d1994bcf0e09a0c9663bac6bfa0e8542f48c511c6828c12ba989ebb184f192d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f3db8918d212f4d3e5468aea53252b468684450a30766ab7ff735a770fb490c3f333273fb0f4e6c0aba8bcc131c8f10000000000000000000000000000000006977b3561c80fcd787f26a6ea575737bf9614ceda908d60092a1811b9803034c17235482330e1d5415c6550c851c8221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ae1f20b0656c0a18a7e6fb67a68e1cc44b8334c127194aa7f4092ceb846f7bc50141ea670673bf0a4a7ddbca8314640000000000000000000000000000000004a18676c13abea760d6830ece56102038927238604839831214c03ba222b59bf19cb9144cc97cf297a5b461208151331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000186c69b362aa531166d1101fb6a5fd36ecff0c3cd22559589ccd0e8bbb8800ef2f302c430e5a219a2c8ad10a7ed02e6000000000000000000000000000000000a29eab1ec0c7a5eba5166c4a7b5962e44d0fd5a284e5026db55ef01f79a60a01a047e87aebedc654299961580160e671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001430cb8efd9117b996ae87069563ccf9d61cc161ac3256b8b4701f8fa4628dc1b950cb69dd54ed10938aa652d4eefee0000000000000000000000000000000017ea67dfd12a132b44a7b18764e13e84682995ac1b4cf6f43e60d65082d54e5382de6fdf0dee69c25c0d099c649cbea01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075eaa8bb63037b20beafc56a5ed2081bc88e618ee72f5923783a8142c148d00427e4bc8dd3f7b747ddff95820404d7000000000000000000000000000000000180117deda01538e264729036514d667994625e3ef1802ca8da33f77b13065e8b97f3ed0b30c7e6a73007c034254ed8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fdcbd8a2fa2ba32751b5c68b0724d800a6d24e8e3142633b8036ecb2eaffc24972553aa45c0d6ec1db00b9297bb033000000000000000000000000000000000751e83f17773bfd780c8021189731674507b6028b6624bb316a4eb792d833a72738aba1503aa9254fe11fb5efcaacba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010da5a4c6a3fd9b60597d7a657cc0413507f5a42ab0244863c34b2a7caeed0396953e260ec232b7d872988408a76331a0000000000000000000000000000000001de5dc51c1bafbfa59c689a41a1f0ce70cd163e7143a80e14819148934865b2f11ef31af6d02acf487564bad524e66f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000321642be8e91c22b0432488eec4a77a953ad0b41e05cfd465ac6fe4e0a0d8e0d64495a1a42a4aa2af66dffcef063e6f00000000000000000000000000000000112c7e7c8c0021f534ad0138157b61f3f8ac75bcfca4998df0d5b4f9bd0e2a2710c1116ee5dc97a31ab7b3818bdc5e261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136cc14793e42bd8987a9d667e8527c69c910101f70b6aacb0a22790ee5fcac29cb8e3029bdafaf5c5a40183f195d7320000000000000000000000000000000014ab149d778ad6cea6f0ade2f8c2ac85f676fc3b746cce6994b0eb08eada6221fefc558485b1df77a23b36f4abb63b141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a51db5eb3c7d3681413b98d4419b0c8862df5c0f253266d992b6f4050ca156b68456c4fe73b7045b7e810596ecc40bf0000000000000000000000000000000002702a490e5c3f6c6924cc12eaf87a24ba21c188cc5004131fea499ab97664b4c7bf8ac781627a400a0324394cd593841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072f907ae37553832c8aec680d7a00388f9b1941d62c6fa1ba15fd302a50a2d9ef2147fa8246c071567d815112a19e5d000000000000000000000000000000001520fa86c4fd80a11ac852ee67c328f3e0c48e2ce6de28dca4081df615ab24b04aba4d4fceb47d9b1f606d916bc311331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175e26562abf9e622eda51e7eb8e9e821a0af605c68a6c7b576430f5b46d501b37e3af9cd0f633b99b16b1137d6af1bf000000000000000000000000000000000316a049757a032932eb9b55b3a5a3290d30e648f20289c6946623b6ebdf91265e36009da78cb402d87d205fb228c11b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc68ff1e69cda887a9a2d90fdbfb015374b8929bbbc20cd05912b3c764e9084ad94134cce695c206c1181c4766cff3900000000000000000000000000000000022baf28fd8f791b162cf4ee60804d080e7d0ff2633075b29ecca2ecb099ae96e2fe92b667dcef841c747706d287b3f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bd8bdc2cb56b7ade7177a1d23cffceffcbca4c3618436c7c9122db3c3d94175ccbcb358fcac3c640b130a53d4301fa000000000000000000000000000000000e340b7fd3d8abb3e903323056c31e4528fcb82f8bd391ee36efeb09f200922cc95da28703da061b2c61ef3f224d6a5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000484cde22c7cb5c61ae2a4988028f8a941a5fbd98ddd40be8e6645857d04b8199b61ba5afd5e92331bfa43269ae9ee4400000000000000000000000000000000159d88a3abe08620da1565144c9fee9d9fe3683e84d52f3bbd7131139cfb23ed5f9d15a9be939c6992026a067da972d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000256fd2c238779203ec9245d5d5394399ac45e7ee66d24e28a883eaec80db22cb3d40e60c4acbb7d4d9c0723c820c7c90000000000000000000000000000000016219f918e5a8029bf3b324ce34147c9fbdcc999aa67c6425d8232361dae0551c4e52f121731f0c4ac9a3e5de379c3571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e175fb7ce1c45e861ffbb4d6d035ecaefacefd4d1738e4d3abebd22d0cefad4ef2a9d8d1f80e85795ef2b9e5e2bb1d00000000000000000000000000000000137fcd96dc0653c3e286456af1972ee3f59ad1d8455b292fafbe90876189a5020bdfdd1505c8b8a1cc5bd6af908498f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114797bfc48f63ca372403704915b1ab04a01525e39668ad7f96d156947b7c1ddf2e0f912e1086b3644638e5d404ad2800000000000000000000000000000000181fe2b2419d0a2ef70f4c5171b2264c511a708802853a8a8c8cb63e06974db14f195caed54abda2be8e7cc95ba554d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001173c6dff5658f8d2b75e7cc25968b02f8980831035565372cdd07aefe800263db99265b2fea0199a7e0ee86da20287f0000000000000000000000000000000000d9b8b52f1f0f3109045a44d9afaecd71ec0c07bce58bd19818aa85d237af2a25de57d20ee3da29372fac19823165f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a0f18b15a351dea4a7620730be50d37eaafeb0fc420b28b7254b743667af4240506298a5527946f7a167c7af309d5a00000000000000000000000000000000013c4e796f70fc5cd79cb05fad66e863a686d69d1374eff100751d5e0d990fa065ba4eb1598fc91f234a32133c7f0ae21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001752034cdb0feb96aa4a621bda691ddd5c0448140de3a47ec6c05fc4fa95c57dc4e7350b0dec5e708d378d9af8d0fb260000000000000000000000000000000002a5a433a9fc8f438d3dbea44ed81db8ad1602f93b7076b24f234905362f77d9966519188c64de8023ccdbb5ea4522661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d490275de3298c1129f604f8b53425fc15579ad16bb337058c9eddb70f39e68dd512a5cb694e3bb238ae52202c6bfc2000000000000000000000000000000000c96953e74362709ff4e5b7d60169e6132c93db83e1941c017570af346ad7515ec39d24c22ceb5d0e9b2e0e632d50d471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013153f8824353d0e0ac8c2af57b5baa95889ff4d6f4e2e259a350f5d1556017f7fcc853b4f5a756db47316b3067727e60000000000000000000000000000000007851490d90a003a0809bf11687ff1893ae9e7511e3963fb221f09a3cc52b0bb2a3d9dce627fac85aad7705e430f58e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001384bb7a767c1dadcc33c1b91aaa67b09e0febd992d44693abbd423552029814bef690adc6333f79533cd77a5ac688ca00000000000000000000000000000000175a59c13f91865db10bc6ee32dc74cd444e585b5bd0a85334cd4ba834eb0c26370874878bfc811a91df1d9972be43521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab1f8f5ecaecfb036bf799f9067c7723df8b0cc770fc742888efea1f757c337c00396325ab3c65ed53a7078f34fdacb0000000000000000000000000000000016d21d783afb44ea3d7ebf353e222f3def22964bc09b448305696aa635db1fa60c56861470849068ad3c0bef6fff2f3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b04e3d8bc44510a0bef3bfb00d7c9325e0993ec72655c79d29e5a999fc7551c20e61f5711889e92ab0901b552cad640000000000000000000000000000000007d68ccd732c848b9da8d9b5e19da6d017c1d377d1f857421497c897181a86fdef790e22f6c5ab97b9279b808c97a34c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cf67258dc24f1a11d246600138a39156f03d36d500d61d902d21435fc825ae7f20cacc9be4e61a41c8f057c74f313d000000000000000000000000000000000a419ef3bff762b45d3ffd9b785640a2587bd4e445c895464d1cff3f6d8a24c5d3fb638cffe050c5fb6dd0b900ab5eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025c1a875b3d7ceecb2c858102cdb18f71ea8c84224097cdd701a734ee786bd97a29bcfcc33cda023a50bf9527afd7d10000000000000000000000000000000007c40823f9ab5f90bdae41f46d9aa3e302d12980d759ab0a5da78ef4db6b25a1ff7576d7feae512d2c5b7a00bed137c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071becda544a633a00255a219822ee6305ef4d8a5e425b723e36d5a1ecbb16f6429e72fb6b9f808d1903d9e17a0abddc0000000000000000000000000000000004f573fdd43903c47fdfac2c9f99f9ac01b78aaff42daa2eeebda863331c863e7db8e3ac3f72d0a785240da5bf86909f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f86306ab206922dee831b3aab5b7a66181d8d7165404b0ae204677a82216a64b0a203d9e136aebb1c76295662f207f4000000000000000000000000000000000c4dc92a6df8ec9a3ad498e36fe8ab87aa89a51cc06d2e69d27ffb6904ac95126e7b5fb0383bf3c2bd24d1b889e5158e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a700a22442fa2e5ae2c30bcf2bbaf06f4f83ee67c96272f795fff9a69ba9e8bf15b3d54152be2fa23432df7e4999d570000000000000000000000000000000009c953359926deb190c2a79ea64670f1cd4c2d17748158b5913640b6612dd626040d79f75500d6e461d50786ae9f46c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003ce2e8b9d4d7f361394fb84ae495806bd33f44c83ccbf78e74db16d4c0121f29e9611e3660fea361cd1d319a2553b4000000000000000000000000000000000048a841444ab64f1cd7256485b0cb0ddd5017115b0e736d85cc1a275615e507c5ffae850f3bebc6de799e2a469cff991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5d6bc13bc9dec3a9661cd0b3e0ec62ec52908ce556186157c6aa05d3ee365bde4598d08828db6036dd48b6d12469c9000000000000000000000000000000000aa8a78f5ce806b1613f8cd0e75af1720ec82e2b9d2d4cb193bc5d11e6b77f0e50fc7e44c6dcf0549290fa799bf184131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167af28735c55e8d6a628534351aa8fa8d51a8d8121add5fc34e529179d2fda73fdda61e826861526aac15aabd59440900000000000000000000000000000000046928ce13d14514550997784e7711033071861c02ca72d0c8d3a3abe0e28d4ddf0f2e917946645bf41889c3a93712831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120b633b072523dc8d9f020ddb3960c576aa139590d88f9e987a80a9a93e6bc72e46cc0bc10283bae675eb8ee4e0355b000000000000000000000000000000000365a56b8df56503ff1a0561c10cf1c5fa10967f8eb9a955acade9b6a70b3e33cf1c09f013c026fee1f6a85ac40747b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd52c72980b228a167ccdac72ceb8921b863b3af6dc0f5897d6b4f63a5daa07f878af1c2af83a3f8ba0ce0db5ac43620000000000000000000000000000000013068e2d6bab3f2c695338737a6afb783a9efb267a8b06182d326204457048066345c15c516709e44b6674e33a0d95691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fc881e72dde64ccf8825f13a90a45fb9152a5819f00a89ce9ee59aa1b3881ab7dda1060a0fdec719d3873ac269ad3f0000000000000000000000000000000003ae7f502eca903de83b40c44e2085ecd1acf1dbb04e4f26b02770c94042dc7e631afa27a7cdc5ab603162e3787ae36f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000408c7c011857ad5f456512720fe0e90a8c2e60767005bb24fcdaa5f1474dcfcb190cf2d093fccb69a380c8b9d9200020000000000000000000000000000000003c731f7444223abb6475e0b00326cce7ad0506cfaf82b6903c4bced86e634c038730c008b25b9e18f010a45a97626471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee5b47c04bc210c0b63ecac79156fff8a7aadebd9a16f5e19bf083015dad1ed250dbc234ab4e706729d8b6f3971323600000000000000000000000000000000094643015bb491f15b60785ae54f03cd72b176c7999909f921261077a62f2b287e1b2db5371e41631fae13d7689e2d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e78765c3e5cc3ddfa8c1f1640f4eddec8c1f347ee77fc4a21ac7648bd9faab4e7e159ec7ef084e22aef4a7be7263cc000000000000000000000000000000001211dbbb597bffc5d943f900da60a3e1535792bce11d78aa72be854c1445eaf95aaef08c0a2bcb3f9d1f2358487d1f401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e88f5c73c86d21ebdcbb9ade26d8a4f5b76ffd69db8e24f9dffc66f0bb66fb41f45578e529d77df33d971b2d19c64020000000000000000000000000000000013e6410c5bd08bcc5cad62cceb66d7d078951a37df24b1ab85f3d06e71a3dc67a6989de0f9513f7efd19454f0cbfc7c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74ceb48485e58fdfa9ef1645d5b565af136dfc646945f1dd1a8e2adc3a07cf5578c9de70e4cd0a40e444107c519d7300000000000000000000000000000000079fc31c9c22e5224e104eb4a9c57178207336b8381960546a2c3f2d3270438ce568c237ac9bddc00c345997182625251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000987949c3d813f0392a8531bb8a465ef3bcd57186fc29948de2eb87da2c197e3ebe540fe86ba9d8d08792a3e59720d0a0000000000000000000000000000000006d945fac065e7a53df12f24895cea038d4a5999fdf481c8c0260bd809a05c3212eac608135e574fec2794ad0c11d8631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d2422130a1d9eae7d048873ec62df88a998f0b858a3c183f074cb57e33a8492a589f0790b2864942a0462ad1ac22ea00000000000000000000000000000000093fd6bd4b78064c27562257529627d098e698afc74c0cc588df5aae0dd318ae6be3f5d1a137feb939e8724eeb12f31e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171b1cd2092d9f62c47ae87df2d2d4468a9505945723d86ad3858cd7fb5fa0799920e75db9acb32ee3de30798b04d5b70000000000000000000000000000000013ea45b878f2cc39e7624474a39e56381f153ed466fd22423378907f61f30f27c5afbbbb261ff05b7ab1735299cc82ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001930e0a06d75f80fdcb7711048460168530772c5ee6d68fa86884cb1fe0d3ff7a2f5fbed10949f5a609b4447da53787000000000000000000000000000000000074012521d510418cb641d6a5eb0fbaabd5a83d999d211d2074cc6129aa575a625c2cde7bc6222c645322f69ff01307e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001507874ba47bfea1818950c9560049255eebaafd30be02d93a49b051ddb952561cf14f6aab3955bbbb2eb74151b8a32b000000000000000000000000000000001814b0f26247042fae1e5c99fe18b6f7d76b12487a823c4559105f974abb5d19ed9749685a63193eb583ecb26761d7421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b971b0951f942037df962d45f0ef2a3f9cd822ac89f0f3bd76007cc2f75c8f024b57182c0042769a13d70b175df87f10000000000000000000000000000000015cddbaa23aaf0be5a9072cb5a963bbcdcf56fc63ec30050dce88ef4d3a58530a8cb30daa28cd6895cf15345529afc8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e6ea808f234c7bae093efade4b59f38c26c873efd3d13dc9a49abc5b55f71a9bc8588934324015651cb3a022a658660000000000000000000000000000000014d6301720d12f02accbd35cee42947e3226cb0b5ecf95654694b203bbe5689ddeb5070d520fbd1cf4e613b4e96d04361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000127e548e7fc50f351eac4c7285dd55e3c11c3054be027aa4e76fa219f732fd72b95aa82c63cb56da9df3f0dad5d076a00000000000000000000000000000000134148977fc3b07ced0a7b6ae69b3901e5db42f51f31ceeeb20ad82f5b7346c0e7190c9d751f356a413c3f4d41318a431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010de422cf373960b0e8caf46859678de69eba51d49b56ae7d7166481897d91a699872a7b68b71b5753ebbe4cade33133000000000000000000000000000000000318096e6af31351fcd11f7059fbb678f8e64e60eb1ee00930b6660774e6c3d5564e246197303b75a7f5ae1490266de41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167cd3f1efc2e212b8cab37728087228c5bdc007efd46a583e1c2bd390d745d7a70efe1d85c0c755946aeee739fa969d0000000000000000000000000000000009922ce7fb12c802e361785377461079a2f350e3691330e06e78f52dbc5423cdec7ce68cba38d472b55f93a67d655e4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010595bbce676a43adb31213ef82327a0e56a3bdc47eca85ce1ab4d0cc7ebb74dfdc8dd494d0000037d74a2445ab696ae00000000000000000000000000000000145747a9d2d4eb7af6bde1e84ced0f87e2758df399122842d65f3bd85098866d4c05f3507a4fede4fd784019c1e0f34d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005953e8f0e419bd853a20b57d3fe46859a6a118adb2afb8ef6a5c10fb1a54d828781eb7099cd8f5cd0aff1e8711e3c06000000000000000000000000000000000418abdbb08122ffb78f03c0b1be480a446df16200bd5aaf246d6517ad1629140547c4985ac70891ea2ffaf2f9b7e8d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001804347a14875450c9a7ba8df26eb6fd938922ebb3df8699f9cb412b696180ec2cc1f96809d57be97eb6e20cd5c1d1fa0000000000000000000000000000000016dab34a31c0c9e29fc4b9ea4584c2c9466f9c25b0b734547b219972dc9011f2bff5b3243f7aadf245420bccd28c2b581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d09b73f38a361d9bfb516837dcc769b0673909d57b5b15cc19c90cfac6d6b9d46c2d4fafbbf5261d00ec8a79632755700000000000000000000000000000000096100e7d0047ed4438937e5ff8b54001d106c53716560a957cf41e8fa8e8ae12babdbfc4922a2ae7be42897241835b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007830e85168902d28512bb54b40bc26317a10d4abfe39e66561f683aeb384b987f18f5c6efe68031e422b256a61788d3000000000000000000000000000000000a50bd090b7ed1fc86def17e97d9e85d109b3fc5791c1f7c24e06c3dab994d415ff5d079fcc5f0c357970e393d7fce421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010436385de1925f47d38d60b487766e48efb5320d07b16063a8240d7e923bb640011ed2c64478525ce9b4b470f4fce9700000000000000000000000000000000054d1dd08ba5b5e6e8c662ec491471bf08f44c16437545c715b7427926ec1d95d42c440f8114ca0f79ec8599b46f64711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b44f5b80c879fba56141768b1ee5ce132b50bc33f618d1063a43b7ca894106f1b81b64998fa1e6f79248aa687a34e170000000000000000000000000000000015b7e15f03aa7d0ab3ffafe56d5c05a0f118a3721c2f19f11494bd08a28f25d812c1e23f20f99f1e9c13df6b4c795e3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017faf3f6c3a1176c0210ca5dbc1e49c0276bd8cd55289208e93765647c3423eefdaa6328cda5b76ff3feb1d047c1e696000000000000000000000000000000000abbdfb510c15eadc4711646f55f2218bfa5dd3ebd35cf661b065a92becb3957cfeb6788ce04a09a5972bcf709a150e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0a34d29425bce751a063b92a8b0bc912b7b49c914ea04191397fae33a862dac65edc9f39ceda32eb9ee9caee3e99550000000000000000000000000000000003b1705aae6fd19eac9b8d0b183ba872df13b8390d8cc12e58ee46f10f8b885e172d7a91978d30600fd14d94eb93b14d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d83a98d663dd95e6e525adde6b331834cb1d55525f6bbafc843d4e8405ebddb0fd6a55a5effaeea154b10c290b672c100000000000000000000000000000000198a42b2d04812b4c837330fc832d68095d8dfb78f59a57acbb8965c7f3ec0a30078cc27da9aab88d8c0026d815c40431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d8b2a0a952460679ea60f33dfc4d78f68efbb90ab1de69b0c46ef14891d5bc309a5c205fa90f2cf5cebfa91b1982610000000000000000000000000000000018c1afe5958ccf07fde47603850bc4b869bbf6a4aa47a12a9a3fbcf5494682dd8550076e0deea9aa8b1c4994830582831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdd1a55a5027e2c44b597630b7da0fa2b99ceb3c395e670f9d93ee273d555ee0fb67f6785f2818f22849946b9509bd60000000000000000000000000000000013ed7dd0122cc6cdeedd432ec18ba792ab1927fc34e5218c0dc86c2d6748476f15734c5aba5bcb1735281d59ba7e4b781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013a12002fa37391813c71e1bdb509d72b4d0a8bcd75e43edaff5b556464a46ac299df07e980fba7e604218a6afac22d00000000000000000000000000000000043d86e55be2f4b928f4688a947e3ef3dcb3d29bf35c2492d910410dcd22488af9a3efd17250fc490df5bdca105534351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cde6b0b705c370e2fe6a1939b1578dd70c43e162e440c2afdf980af34ff327906b0d0422381f1e5186140bf6c5a5a9000000000000000000000000000000000540d6c1c63f5fb9673a3441ccc6990aa05993afc9464dc12c427a8dc4dbf48a3d3e730c798badbb893bfbaed687d8241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffc355eb1b8ad6adc2a4341b186cf207fa027ada410956ddf4bdb7c623c3de2e054be306d5cfe1348a4d0b4fc3e86220000000000000000000000000000000016901665333329601179dad02ef67768a8a8f60a0e99781f61d62b7be4587442bc93a3beeb7e528c7687a00d9e27eeff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011adc291df6d973e58ff3f9b58c495101853a5d12df9e4b4f116155103ea4d87a5e6c0784c01715ee19f05232331e99a000000000000000000000000000000000156b590de71a001beb99d891932577f62947dfa7f20b4e652efc0b634765fa9370d06dcdbe96ad7c1b5340a8f436bd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c40d9a484619d2c689fca42c4ef4a12fd03bdf2f9682822929bfdaad7df70b921e4e651ab5432eafbd82794349872a0000000000000000000000000000000012611ce2124b8b3e231dcbb9b70d32d589fb8ddd4bd209361af18baa4a65b4f9229b7fac6de5da0ed4d1629f153330781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4e19a621f429cec578d3d804b5d19cf4dca940f2c207f0ce260b467405eb727b2941ebf7cf6593e1fd571ae8dd1ebd000000000000000000000000000000001855e5f2e6fe010275492f6ea2cefcf76a9a20952a1605ed32290159d31af43622e9521fe42a24045d1db1ab4e90f4471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a0642f13d7884a2e94b1d2b94f0a201fb6e65baa224fc1567ea43e9df9d0325a28f26ceaa3451054ea44b019f4eb530000000000000000000000000000000016bf52329dc0d73466a1a5eee91f7fb8f793012b4efc35d8a9dc5991268e1cac7df7be00ed19f643a1b9053be2522fcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d22426a53cdbc1a07213295f15fda4fb5bd23562e86aac96d8f88d34442deab8d4ed1daac65873a894a18a337eb04500000000000000000000000000000000139d13673bc021de2b05ca27e9952accd06ce7ae39f9eadc8da8bc2891b87ac65b41b2791cacdb3a1869538a76f1c2e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007494cf434a5cfc491460b7279994779c55d4d89645d7aa40547469984430262c960697c3e34fcd5195a4453c69fe46700000000000000000000000000000000031252a4fc43e92244eb9713690d81f0039862a8c05257fe342c385eac12c1b6a88c52c5a32c03abda2ce5657f4eb8861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f2d6906fb28d14f9382eedd06e70f5ac4147585ea5bc90d9716b4113c9c33a3453211b590eb433b73ac055774a80030000000000000000000000000000000008d99615498d1e43db5a674c7496f7797e42d0af9da79560b89651ef15d02c6c7c8412efca0843132595743683033aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001be4e3d77a3064014b7c10c8c613b62f0a4dce0fdf0a568c761e87337efb0cb61a18b033eb402728631a4e7eab6a7f2000000000000000000000000000000000592ccbdad457fab8c9ce5962e0d1281c3f0b0c26683a5b7263047534e435ead5eac3d51d0525ad5cbd4997a1407c2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebdf13af0959060822c881b2e75bc905b3f2824685d2bf1fe8653a945d06f820419c1ac6b1a462ae030c2413ed82c530000000000000000000000000000000015363a3167b6f1199620fd18226631c51ea1ce6b11d49c84b7f314a66d43cd800f8e77690ff79c54dee5e9860a13d24a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191764a011327a7d999cdd60920872e34e57e76696fc268ccdd9166f2256389f38c377c0e9e5102e8dc328b205ff78ac0000000000000000000000000000000008fada840d35d60c17e5b528293f98331eb99387aaf39b5779dbd7adb581cb4e85c4c7d2732d4560fc91997a506fb3d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117d6a0d1f17f56de0c8a64203aebe87bce6a1a3cbb40c47de113de66c131fd0f9fd47b602b87cfcb9da399fcf076a9a00000000000000000000000000000000047b77585f3d8d56088d785633bebed6dfc36eac9fd8f70a78ac126aea72fda946523b3f48f877acbde2f329d59ab9461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178205feabac517d9cc5e34408ab5191d3dcd1770006b25af69b3a852787c531bee914dc06bc5e6fa9c8933007aa766e0000000000000000000000000000000009072b58117c1918bc477ee11bb75dace84c8411e58d8ff930b3a1129c9a62f69ce140ac62e24c85ca6bb804b769c4771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b18fb5088ffd426fcb3ef8971b1ebdefe485586b41b4f3118c41ef8299cec3aff41bb1235d88b2d23d4cb4547de542000000000000000000000000000000000c07676d12e59fa963fb7c151a999a0d0af29fa78272c83fcb2084134ab72fb1bd347c90c1c445d9141b18e3964a0c621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ad168e4ee533289f583873ab1a6e06a72cedef1f17d5f410b383a721fc9e1c100cc0b4f4f7bdd31f522d0c4c79b2e000000000000000000000000000000000488eefe5c3cef1320748594cdb7285b7b45134fe3c3db1cc5df8fc0e2c2752168dfad9fa7fbada1a01711e0f18db0a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015864e1ce52c4cf1c413995d75f412b98a5f3f794edacd17b920e1cafb8507a6c29b779dc117d678cf244e8313945c8b00000000000000000000000000000000018bc76a08ab5202dd7b51051e775b14dd0958da880d37818e5c9957f5f73e582a5b8f2316958bbfa96405b31d4fbb971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9e4138a457b2848f666715abc1a7a4461ad1dc6cbb6d012921e397cd51410911377be48c72fe27f51528c4116e3b33000000000000000000000000000000000c8d57f124c6db68190cd119bb309e6bb3e1a4003b9aec7fecc1806c58240accdd242d3dad863d9633be334c08bf19e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c526dd7aecdaf43eb556d00bb1ff8ca15fcaa34f72c69ba86b705fcd57529651290ed3a9492dcc883df16153fcf0680000000000000000000000000000000010426e4e9a76bee4ad2fdb1c35bd58bb52ea361b4de0b5314d2f73af21b947d40f41d8dc65fc368c9a3af8f3d4ad1b571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157b5316ba8ad822a3b54d94c13327e96a3cb1b734546ae28b394de25d21e60a8ee9e9185c74e918860701a1ddda63e9000000000000000000000000000000000271d9e690dbc0f6848630241932e011e7421bb53a7787497cf13083b9495cb323d5c457349d2204de590ecbd982e3a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae31f8fb3c18983c4c77001a5417ebce02fb8e5dd5789f2bcdc5766f1f481081a0cae57da0e34e434a4403333612dbd0000000000000000000000000000000013dd0cab65315b101ef5f4c0fc9435bc6c6ea76ad83b5e639f2a96fc59d1e827205a531b24ed8011cf7d96e1816393f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000983c402cfeb97ce8b71a5cb3baf32a4c449eed362c635525d20b2458ae636b8b7a4ccec97cf6722f1e3b266ee2118810000000000000000000000000000000016c8cf76bed2c1d37ae293b24a97cc421620f2949f32eac66ba1b839d5e2318086f752514f0510fdd1d2ffdd6f8ad1381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001489790ed244c375b40bcac401ba32326621e90a8617862490d394d8943d41a0078aa58ca02218089aaf6edf4bcb610d0000000000000000000000000000000003962c3714b1023bf79fc891836a0c56499a5cff186461ce71d741c437efe59fb114cdea4fdc4fd0aeca19cb89f1f1831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001975862116b6f2dfde4308bb09bd640fb7bf44194431c7c6c1208c018743fb8df74057e426aa882ba561d525dcb2b31b00000000000000000000000000000000152568803be056cec78f90d806426d8f34fefa8dd1e0190035735abe74551f9f48fc7046902c01247e71f56c5fb362121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2f9e8223fc021daad5dd0acdd2b49c9b70a2a7adabfe40aa82e565c2e0d2d393fd847f8170b7da4cb0dcd1b9f81f4600000000000000000000000000000000178845a237f1e6e518f66f69a6b087a72f6f480df9f0be0f33fe1ca3febeae7afceb877fa285ff9b571b4f8f51ce123a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b7f9ff03d6b9bc68c495131707ea7bca29442a1eeb56436d15a3fff92036edb9cb3acc60af335817359890dbe8d1a5000000000000000000000000000000000c70edcb6583a8932705803453e56fb6c043d0889752986a4f538fa7d9dd20216ed7d77276a11d75ff499b41551dd7b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e177a6cd0fae4d0b877e30df63fbaf218a70cfb5f85acf1a5b593454d8c6c25d4984650ea24c43ceea1ca23cfd1f59000000000000000000000000000000001246bfb6d8fbbdd5207658ef05d755720c5df02ab7b886362597d3e000acfa76e1eea44f71b5da1d552676be288ca4411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007161a672c464889f0f1b144791eee1633eb462618e0e7fce25b5acba115e5b27598ab54f29e008d74652b943b6226d70000000000000000000000000000000015709a44de5676ab445f17f704051b5e06c171cb20eb4ba2dc3b15efd88aa757f372440e6278109e006a0b67e8eac6621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000286facc76e251ead7a9e988138d24e3b16296be9de3c93acf2fad5ed190a6d8d666d5523df5d3771bfc2d1fd12dc6af000000000000000000000000000000000f1e7504dc1da9b1e73483271f24dd7a6a8f0c0b16239e5b0db26f53caf6aacff55da0bfbcb557842f0082e6cb2d71f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1849ba4318617e825d9d7af25bdf0d309afa80c7e299a78dc216f622853af7b7e201082f23531116f8ffc7a7ff5c29000000000000000000000000000000000ad2811a9b9abd5a8b174a6e92c3a8aaef72a14c3e146a15e79e62a07309f396e6f4694e79f63a67f2c9fb0bee0a8c791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c547a057c14a7218cae0280fb42d39488c85e7ff55a021534798f59cb45aae870b25df493c513c92f20123256e918a000000000000000000000000000000000ce08eb92c35578b1b0c16e1046e17e93200873d94d3a8f1c19b7080a3b9b2d707ba10b5063ec527b3eb11a105c2754c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102dee27508e1188b018cc34bd3a8eba9d49644eae56d7f38f59dc4a87bbda847026815610782d6508e80e4676de3d40000000000000000000000000000000000f20782ec888317fe7660495663cc65abec658dc7561fb794de45cec69e2973a6459683d69053e30f7ee398e6735afb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001630513a5a4d2f90da3e2a728150e505a285847672d570a783ea98a8d36ea34aca83d7fa85fdcb7cf92415a4d9f64db50000000000000000000000000000000001db66fc8de7ea227119539b621be487814415d6437406a567ed95840d6fb7003fff0a9e820402de7a326e29a6c5516b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040f2f660f633b84c99486ff664da260da39a72c7e337980bb8e3a02ab1cc51ae27776449f9885927b1043e8b73e1cd500000000000000000000000000000000057273e4f164c6ce308bcc67e9721fc099782a5dedfcd7ae7e08719ad683da4a3319e15c83115b1fe4cc188f9b4056121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095354cfb522435830cd9db532099ce333486d0fd585075fa210a2925745d38db13f8fbb2313f6b587bbcf5a6bad654c000000000000000000000000000000001580b4008e7cd4bfeb8f1990650d4e531c4517b4f55ae4831aae50fc58df62a6067e34407b9ad36b42ee0d86479f2b911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d54b8f0b00ff7369536b1079abeb09ed386412a009f0c93e94d301572ec636bd9c536a9aadc1c5414cb0f92ae269930000000000000000000000000000000008dde6a54941488a969fd9f453690daadbd97aab9fc69efb04b0099baca28195e4f775b524afbbd848a234e3c221ea7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d5f1ef5e7882ca99d5070c96fb12df242654e60f6ab0411192562712ddd67613406964745c3f49392cdaf26cc03938000000000000000000000000000000000c023f521482359a34c1c80ccbbeb2a531d37a7a48aad87be2057546f935cd87b17159a21b195f5659cad8333216770e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b214047316b2052c5492f7afd7f704951420072a7f2e3c5a8f609f4ff2574d859a1fa360923b6b07cbc62565f682227000000000000000000000000000000000b5dc45f2b280e7c8ca9e1cc402ef911181abab0c60b28179fc6996494e1b6f362da6121aa61cfb2467bdedfcc49a7591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d025dc7feda626e4a2879ed537465edc91bc40dff2d3e2e5c9c58e1576b35c162f9bc7bda127ea20b550259109964c000000000000000000000000000000001654a7647d36e4d149b5197756a266c8809c7e8f79c743ca812643c4188c2722d648abb96bbb5dec6fe9d738a14db5381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a14033fb955e0040795d9277e728f624ef10dcb9bd31641bae6b364c696a8f192be6bb2095cc47e02b9de420f807ae900000000000000000000000000000000111ea8ba7ed71b56afd6b20e9d6eb4ff7a5f28a6b6b61aedbd13afc9d94fcdfa99068347f9e529ab7a7c09093efbf91b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c1f364625f6105f62f14b4f69a7bee5ff68b59bd7d15db3b94b3bb889a972d9fd669162b3edd921ec1c63409db34040000000000000000000000000000000007f9373b37fd0e08cc06d7310f3c96e0f4ba3b28f938dfbfd8b1427939e46b37d15a0efc513e9caf3a11e40ac88e82de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087cd62556a01e8f35df74d8169c4e14542fe1366fcee0935c42732d983fd91ca1a8001328d602a16477b02fa246d03f0000000000000000000000000000000002941b569ea52964993c6e2854a58a239ab776dd013980801e224af4ae0607d50169b048955336a1a9e451bf930e233e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e5d5a874ee067be22db4efcd602ed5e2b168342261ef7ad344cd348985e5c24a373993cb94f83f6c8128ab2d1c67a1000000000000000000000000000000000ebb4ba395f7ff170e7c39bedd5446cc055bd043bae165c4088e47d77ced60d73c1cdc18d2f63342fd6be3bdad0f0b021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2e479ce8bbbfb36ec15e5571fd8f69d7700e4ba1bf85d3cd4db2ace30125ac920736329dafa39aa60adec3318c91d6000000000000000000000000000000000db33edd9b30ad68884e490ac9cde61c8986adc40ef8a1ec9a5b2868feaf1a6d40a5c91466e0802a677097f205bb18531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007131adc37a75f6dab98389051ef15450428cac64df34157ab3ebe4090174c5fdec0abef241eb85c63540511b8e6be9a0000000000000000000000000000000007308d95d4af168c2b35574316f151c562a3eb946923a5e1c8a3bbd62d9051df4ed76b646da7092fbb48fe96cdab841a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc8731839d6e8e852beaba6a163afbff808ceee455474349d8aa0cfb2cee4e728d7825c611c6a1a19213cdb6e9fc6a200000000000000000000000000000000165788ed11583a7e6674c12e6882bda8a33e433ed6d35ffdde07a9a2887b8f9a47ffe6d0ba70407a1173457e4f17b79c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0dbdffc104cd4b37aaaedf99549357fd4d4f4a6d9b32cd0b736f508bcc32b1d9c2bc1ebc041a7a5431b9931c7bac270000000000000000000000000000000018942e7a1135067f754c7c8b39c247230a41dd7a0e83e96ba327b1a113730b1630a6877805c1669819804ed721a6e1391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bfed9b5657fa59093111f086e6f6522018f1b952eb8995b121dc1e4dc771c864c69db254558d9f9f64d7031eb0fd93000000000000000000000000000000000394775e955df9ca593af08be59acf96d297926d583355cd38affadc6aa87fad24e9473ff4101818b365e17cf82aa94e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbf0cd7b9f83ecb5d55adaec0ef9e7c5ffe712ece8e592121a1b3ceb7ed0cdb6d9024a0199ab6bb9b02b40d0e5ce2440000000000000000000000000000000001f7b6cf489a1cabd71d3ed385b35a544949605c39b9afd22c51c6cc163482f2359fa105ba13233e9e6cf75d45476d501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186ff5bd55cb5a79f5ab753f9c6fee615b3b4a868082bbcce150fdb88828e6be0ffdffdc92b815841cb4ad60d800d335000000000000000000000000000000000ae583adf5f87b9fc446a8ec76be8a02d46f21d05eaf751cc10e4f9c02cef15cc2791ed5da1ad33e1b527979d65523391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb4a00c637eca527ce245af559aa43e66064da39fadb7b32f43490cc2bd73e57f92cd15e8a097d5d2cdfabc97de54b0000000000000000000000000000000003a9c9c6b7c1ffd72e20181727855b7c6a54454210e2b59a0c12df69518e36a029c3fe8381538365296b626ae6dd1f881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170588da73ae88b3679010a2ed3920eea030232a1f03672ebd78222763ba22844ab20fffdb461ddef34cbca31584f54700000000000000000000000000000000060340f06324fc2aa4cbf557234fd0b0f85f557a1c3ad8b49eef7726c6a3711135828803be975fd39811021a4f4636b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071a8792b03325090a75f23d4f16a025e16b396e0ddbda1d0e14c2090348635642f68f8837d44782d4c3dbd6376147a90000000000000000000000000000000008e72fddaa45b08b8b577c08fe9f9fd02bb92ae2dad3d4a38512429da1fed97303a849733ddc083bbcb79ccd5d680ebc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043c525002c5f4f5e8f49aa62e3fdabc277a4564a4f40153e139d232818ab2fb67186c916c6f97d34877c2df3be7d98500000000000000000000000000000000050892bf8b541407cc988ba58bdd2a07be559d7e28860de5baed0dd5da3b3c34d8f268febf351adf909fd2e7d809e8171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001389e2dba73f4101f38fedfb0c8844a11899aa1363cbc157abcff6c7a8d9722af103f2d14e1f79f5ec1496f86df37a280000000000000000000000000000000012ffd45436c9360893849c3abe3fc610356522832395f0dc87a3e426e82c680a07e71b7af703cfcfa49570d26fc764d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018a724c8d870450e88a559579860ee1bcae1420649af70163a85b8489b06affdbbf9db2e9d3e3fab63d998c6c2d4fec0000000000000000000000000000000009e6d967282b0b1c526f7857292b062039f1aac4d32524ff940ec9a74722d732c2bcf6a03228d035ee9c64462266c0af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a143cd8141850f8799780e23ca5e88034336b8dfae8b6703b67c3861a86b093838bdc579ec17dfc9c8d511802a8c8b000000000000000000000000000000000876eb539fc293679ff1377a27b4c89969c7ea2dff20a7ef09a4be5ffbe97be047a17eec9d6700f5fa5021dc186cc3011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156aafdd9f63ae738994bb08cf55736e69436e03ca0f0d8cb6b142ce8037dd2ffa595ff5b0a6067dc38ee414349fc4b7000000000000000000000000000000000e23c86d857a63b115755206d1dc40e7e8c8cfa821f04908a152f0c392a6507c2ef851fb3f1fae83e6231296b3c4c8361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c8f74e376a5f2fa83449080e486a90064343fa81b09fb840084884e18c2e3d2dffcef2f7ff538501a925075a36d340000000000000000000000000000000004e3834c0959e746d540453c98d495c4ae6ed96caf0e43b52f70cd79a35486247f1643c46d901269d662640353e1e3e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bdf8c57c76a6f4a15fd33720d56dd05c7a436dc22fd9081878f686b7d2d21acf2b1d05dfdbc497690b0e0499535204000000000000000000000000000000000f7818a2cad848cede65dcf06535f99a96cb22310fb26d4f4f49955fc82aff09d36e29ec45524eb0cd068025fd26d7021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c0411793247a2b9080047dc845974ed0684420ea0715e228a65d0ba2f3932b9907134771034cb763bf991fad60cd52000000000000000000000000000000000b2b328219f502b4bebe7073275d3ea6e1428ce9b2145b32c99acdc172d4308a326c4f2ff872509b0a0ec2ba2ac0490b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c52c04cf70056fc6a0d6b8a7c04d12daf5b6c6984940e457659c601bef41f5ea81b3bd373d1ee6d890b30a9a2db737000000000000000000000000000000001879a242b5e492ed5ab41da7a450dfd56442755e0171177e0ec540047033bcb970aa2bd9e515a44f1332d394cca0c78e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000409a783d47da735ab470cb7ba54fbdd4352ab0158c47303120a2f9e07d21c8230709730a9721d89127abcd5293cec4a0000000000000000000000000000000018f5c058d21b0b9f641b6b13f8323572cfc700340a289b13262ec524cb2ef3cd6db4a6b5bd302348148220595a20fb0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097c9a0ac4e005f0c98d906574131f33a92fc04c408e04f4cd5b919d27c7492fb2cc60113e3086dc9583935b82354f2d000000000000000000000000000000000c7f25c7e2e994117a435b2e9534025dfde72d06be9bb1e04d84e7d811166f5b7b7c156789b972a4ac308617ca1c318d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2e8d75cbb13fbcbe597e5a8ee6179dca478bfc70444c3a413c733b9cf41d4a82b1f5cd6e5d526427163bce2ba70ede00000000000000000000000000000000083cfd45903b882b49e1d5f80438f2b436d9ff0b93e666d39835490795b15eac41f938b0616f43fe27f77abe3fb07a631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016dc1c57a8e3d242678e670e902eaa3b6cec8788ce8fd6ebf8f9098966684f3dc0f3c7b7123f61aa81737aa7ccd8d23700000000000000000000000000000000100c4bba1e04d566a04d29aa4d449097b09bb8837f0357291f06511d09bca36b3e483ef5af7ff7fe2e15dba2cb2a453e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086bc22bcdece3b990f534597e5c4a7aa8d60c7d16fc05a4ca6f68c5ce86111b62078d09ac3ae18d898b6eef082562de0000000000000000000000000000000000706eec3b03f9dd3801101dc46995919c18b58bd13775bdea6cbd8b1099d8fe4b0fdffd365a3bfd0fd74a60313f2cba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014405eedf0ad786cb14d13287d027a70023bb0515f7555358942cdff99a3c927024044fd414adb6be6e995991c4c580e000000000000000000000000000000000e3a248ae88b95741090b3ca6757ab934d1ed0281283fa6fef861d3127019dedf14719557bb9850441cb767e4e8dea7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152799b33ae932b6069bd809974f1655f20e8f01bdef67290e53179ebfbe648efbdb9b721c93425e052d8bedaf2e0f8a000000000000000000000000000000000e6f8d037fc48cb48c0b9a6196491df7cbb34eead34765e8e2da361d430d1c47abb828c9880957a19cabbdecca0e68141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4e32f49d801fdb498c30e86d1da8eac849f945d5daf5942334b68afa9a137b56f338fc6f9d6f75d2b6576c0fc2c036000000000000000000000000000000000526b18267fa99042e1df66937d1f0803d344ac0456a0dbf85b529ec35b343ee90d62a2bf6a59aafabc2ce53a082b6561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c485eddbd020bc6810b3eed3681c0795fb6cf487fc7f07bfe8920c47952bf6593c67c30da9b51ea078b0f0ecac0d0d00000000000000000000000000000000167ed7930ea1fe98b81ab1d1e258051dc2aee31cc214a2bb850440ad151756fc2a056c9e202d2a6b9bf8d21518bbf68a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121b4283e782aea757d0f5d69da17d151c3e1880ee884660191f839bafc90daed40ff596e8bc10c144b6b2f4d524badc00000000000000000000000000000000101878adc98b627148cfae69034c17a6346367eea17b0fa6410f44081aed8d5ac63e180c6aa4bda98bfdacdfa8c006101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189086621808d82931e7a7bf38909159092cc4d727706a6e094007cb7211cdf80c079ed1ba07ed118340afcc1dbba65a0000000000000000000000000000000008bff218e8779dd6c3b810579fc1b04672ae0292dc9550b717f71a2328651907bf1dddaf9fe7ec9c8c143111070159171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001615939d43bd7cfd77fa80b1ace0755115ead20eaaaf694a208c219cc67dd26c139068114ab76df03eadac7c0eb9f99e000000000000000000000000000000000c7c50d57f8dd062fa0c109f941d79d9a92f35afc1ed6b9a6ddc23663ecb75e4592554d81fe2eb544e3abcd16b475ff81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000575ce7dbc05f1940f5046ca4ed1e0850e35090ae8cda85d5a2f8421048e8cf850a2deb4752d7e2435ac34d3e62c394d0000000000000000000000000000000004e9c70ba2dff23a31a1a0fc804a24d0c07f201bbd49c985687bbb998bc35c0a8794f4ad1c89105a5dba1fd6b400c8ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c0c8fd87a146b48c6e82066e7afe1e08f608e9d8cc73101e7dc3f64cb933ef849250e6bcf2034ed464d065f230f20d000000000000000000000000000000000e8208495b7c452f3d364e0a201b279796291bafe98b5eb13491a2d4fbd01cf2828f694cf3e3d50c1ec430f6a0c184321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4dcaaa994d8a1b9e0808684d53cb815965dd8b10f5ba6976885ef37979c81df093ef76f447f7326954189585db55ea0000000000000000000000000000000008ade5db3e12d311ea738ea5cd4076f298d41f43117af071b33ee46e18024720cf5ca5fb4e484e4d99931c41cc696a801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010daf97565856be5468aac670357c35ccc56888c82779c2cf0fa4f53ad0782da1b9f2fe004667f770adb6834c330187400000000000000000000000000000000167ceff3e014a8d5920222209600a54d9b10e7741b444a317a7752d8a7ac0e02e8548d4a3fc1babc4903e432a9109b9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f094dcb69ab3035622724606c08df428a55d474d4b437201d7b9c4ff656b1202c82cc0e08f9c88fcf126714cf555b240000000000000000000000000000000001aca84564fe471eddbf081fd7081b39abbf2b06e1e829e5704fce66e1baf51b2075d11fd203ab2a17907cd0ae63cb021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134e94132dc1713678c7554217b49f6977e49bdb1355cef8b266a00d2659870fadacddb11a1381b7744668c6fe6adc140000000000000000000000000000000003fccd8cf77af20396f6b9ce88dc508c147ce7fa280513505b49de549c7c44b7c497d461ef09adfef33087b08386ab0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001034d478d2b26698b0965b1374a95018a1e6218547d2b1a14b71dc9949b1b6d78c35fb8a0a74ad1d4474f09b91e40b8c00000000000000000000000000000000182e84f5c0758e882968b501f9ff75efd28bb8f365bf34bbef5b9a44fa4a6ae0b7bfeca1d2a639e5db21a8c052a033bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003127702001d1eec30574b0395006807eb71ecafbc0ab2ae185d19bbe081245eb8074b370774c471792e06732b5c54f100000000000000000000000000000000176b2ed94a5ce83b326906e68492095981b4b8396e63599305fc262b94560960087fafc99911ceb1beac7fd9277ed3e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dafa652d7aa77a93ed62621b6eab96b8f1f3c00e66dda7f89ae37cf2a076a7941560a850291119efe20e3e90ef45eb0000000000000000000000000000000011a32427b4292ca03a63877d0f6f5e57c71238ecdb1ce91b6bcea0c5603166bb7188f717cdcc37da30f958b348adb9eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001348b9d516f0c89e89db981624072d9589e21fd60ab54c85f6bd54103c37eda77930e4e56c04ded1d9c727b1baf55d4f0000000000000000000000000000000012b7a3fc319473633eceb0b97997c8cebd03dfa229ee9d3b01b3ab095d20b957cb723549c7788ac11441eabf41e9bb671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1042e03363101a5a3136ed423f3c11af2d3b8c7144d357c03e5177ab9c245cb1a995c96cf0822de10be7deb057942f0000000000000000000000000000000018165fdd3603a86796ff650a21c3a40c8646a5a7fd8ef8562d96da4f852f917c9d18dce15addd67268f1a94b58cbadca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d248eaf53fd97624691d1e21cc382de032b64e3936272d9a80bbc8ba322932575bb5f883d0eaac5dd55a64c65476e1000000000000000000000000000000000999a20d60c2e47d9ac518ceda5bd58cf6968c31e992ac36dba000c462657704b147c0d07834a5cf0971fe42a7bdab891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2943eb19aad35fe2cbe8e5d45a79daacf4d61ff07f1bda0fee4247c227d08403600f396227bab2d33ca210902eaf680000000000000000000000000000000000769acad29cb08e653009ada40797ad1202261d2c0a38804cde8887031cffa7e59033b3a30db21cab8148f24d5cbd101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a0c8b70cd672a7e94e9c62d642458bdc5e93503c46ca70017006406b06c8f223bc6b7da7d4b7e03272401612f804bf000000000000000000000000000000000ea392849993f0aedd837600d9aea2c76265090af0fbb3c1eb700ffed994bdcc846a0da2dd76f2c733db5b3f83f7381d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8240630ddabb0009159c2961abb79f493c7c459ab2674d435cdd7cc0c5f6340aba52e94bfc48d7048e6685b2d10c4d00000000000000000000000000000000050e4dbd58647e215a0c9fa22f73922625ddc599b8d08847d8ce790bd48262313b178deb1a4199d7ac61841fca2318de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f988d4d1f6b2c2315aade775d5aa5592f9137e7b9f8376aa1e47b6ad7522d4309bde9c57ae91bdc7f860d71fe92c8b00000000000000000000000000000000065094d38e8d695a28f8b9b7033c66d75c4c08e69f076af0288e98ef4576e032f34a751fdf18486a5703b4ac10127c121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cd4a5f1f33b4ffbf4227ed75e7629ee41395b4416be31351330690847e19a36e6a9bc790ff9f68728dd193cf507e1100000000000000000000000000000000195dea5c5cd2d28bf6fe03ae38b3e18c2d7d98cf49c54e9a556591bf7121d88d686d3f76ccbc5fb502e9ae5bb5001bc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e15ca63fa6587120a086b42c18182c5a64679781f391f75b4621e4780010e2c47c2447f4e242ea3c569f23697e7f4af000000000000000000000000000000000d27a970d50be8f5d8bc228b50ac6e27013384feebc5d824af5fa2ab763545cb337b62e9e8936857ebd23a3ad0bf8b431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc0cf6cfbf1fc1eaa11556906086553cb4ca1ff89b876f84314664fbd2a5ecdeff6c9151ec55b61d6743f47f8cf4ab70000000000000000000000000000000002de62e7b12a811a814f025adf74916a84bf767a7811cee8658d389e78a4d2386a5ba2011e5f7ea3883d9b014a87bc7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a58dc82488a26b87691cbbd333b73d40efc76efdd3028a71a901f10e2d602693a111479fe9e3b27c268413791ae728e0000000000000000000000000000000011e77d2fd6e3b64d870ad354629d59318cd690b14ffda43fc0ede0b6b9f51ec19c8dbf65c3b1a5d40e571a02066629751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c7fcffa27e9b41d358d34cad14a55360928cf005fa839ef94b117d79d7cf18b16ee9dcb33e36e62b30140b203c5ea300000000000000000000000000000000028c764b32a0302820c5e95762469df9c628938f66bd3c11a788714f95e960a89e2c7b0ce0fff6a00581757c522ebd521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018fffa1ea474fe59598579e370a77679c250b8b874d324b3b8aa094106a9e386915e9aeec85ddf9ba41d94dbc52fffa0000000000000000000000000000000008df80ca9da2f7ee21e62eff3d30d64d680ddbbc3a6699d4b3ae676350bc3d3789b9cffe7f9982449af72122461d46cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f5d5296a1fae3dfc78bc9d823ed5f279da8bcfc311e64b0faf60b91fb93e2ab83bd51d1350d8e08e064dc88e0b3d2c00000000000000000000000000000000062fa1ddad0680c58ffd11ba086ded53d44df2ed4a96d836a87fa6bcca97f489867ab1ab9f43c3f27258aed9e42cb25d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd929fd5b55bec3ba8b775c6ad116089989c862adba26fb5506ab155a953889b28da6945ceb58dc6100e383535877ba00000000000000000000000000000000182ce29d6d39cdc444cb21aacfc97366d6ac43f64618ad2d5ad8575e4def2ff194ce2392779bf9bb235a844f71fd54871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088219b7234b2cfd4d540fa9429d275dd31827d7b297128be304b59be36e0f3352ed67f02276bd200072de97024ba54e00000000000000000000000000000000015cd0e9d3810cae32072af0ab51405f33597ab1a8641cdc83bf40605f61f4ce8042dc02eada07f65141bcc74335efd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a5db56c7bd430d40d937584fd72d1bbfa2bcb21ed86af134e759fc892d9cfa7027d13851a5386c6945081c138d7400000000000000000000000000000000000cede2329f788c7b5536e6ff9ddc4bd8084df25714048680d13221bf4d0a55bf1f6d14ed1e5bb8fceae9c59e501748cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c090a3d0eb2a153e46331b6469b1233be67887019484e32caa319d8d2ac24c88583e87d7e88e3e565eb4a1a8f9a36d0000000000000000000000000000000004da5dd28de98b1c38d3766aebfacb9185f81ca2c5c938a4062afe3c216b5e8ed782cf639de953bd3a31ee4ae6bbea4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f73b74db6e476a55d48f6e3deb0f9f8b3511610dfb5f40e37a98f8f7944a360833b9a05d61f38cf7dbd59d8d0135d12000000000000000000000000000000001765a0ef1041cd0724c751ab7ce7355b663b83b2074db4fbb2ee6388378240721e2c23d1c5f2493268b3d7ffa9f355fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a8e5230d5b4aff6b55bfde18591abaa35c697f96eb7e1aa40857062b050fe74a9edf077e6716808ee41682eac489bd000000000000000000000000000000000bf9e412c2fa57238c035c18ab6cf875634868adb7f6f82cc56fbc16a42ded00a719e3bb8793fdf6a80b0e6b7598c1171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b657f04ca044c1e17dc4cf1f148f8b9a64baf528140d5f3b20b5526cc95548daedeea4ed971fe256f966ae03d5632500000000000000000000000000000000152be8d503a74e84243df796098f22a299a3c0e70b179e259b33ae8a4ace67669f1d71c29d63d65c544f2f0b369e9e421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147cc67d792628ecd3f7a83097b001f52961b164980f41dc610d04c1fe54acffe1d633043a04464036d4c52e02bb73260000000000000000000000000000000017952a7d3fdcd476b0290d74fbbd67462075e0caf2f4c7174a226cf4666b858757a7796e46892fb3f0035ab68ab7c00b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ead79b3196fd00b6fc90770b5452a55e1b20822d0753e8391db1517a867110a7d965583aa623b1c04a722e13e295df0000000000000000000000000000000013248f74ccb81f45a9c4e0e6cfa11ac9e063a3092626261b3ed70a6d53ccd8b566eccc2c08c992aaf006e5c29f186ef91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f85ee6c0eb0eb8059c0a1fc4fcc2589dfb5400093f5edb110536dda4da7ccf01053c35867bd7cba722bef412422f82000000000000000000000000000000000d6a3435b96a1a29d4ec4bbc1a5d721a74e168aa0f8b415a9d9f86e8ba1307aa7a56c77a7e8c3a41d3ead7a528996d891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117d9368bce34659880559ef27824c39a18b1644dc75b88d7c49e59a837c888cf69d2a82536c5297141c8f711c303dbf000000000000000000000000000000000232fa91de22693eb521b73c510c9a2a4c0d3e461ecb04165920247e5e883c326f3fe9362a20b47844695b87b68ac7e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140dd2ee9a4f573da898e33a479d3c0d3c3f55bc8d047564ca527b57f0d31f75760e01ba70dafe75d03e21e960a10a430000000000000000000000000000000013219c141ad8582e61b5675485ee55f8996e9f57954d808def6284762c09214e9d5421495b957372a615e5d6146f89d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5d0afb17dd82e267770db5803481a4006774d596f2a46120f49e162f5855060765ea16be86a298299e8d5e673607080000000000000000000000000000000000a37c2e3886b29ef6eb1be6b258b4e1f7bc060026887f6beecfbf4b01273476010dfa4d367cff00d16c4bde2ae53c071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000abd57068b71935c7b8512e7fb4d6a726ef62ee21f9dde2d772e882a408be7d2fb5a63dea08df2c6b8ab54ac3b90e3600000000000000000000000000000000098097f683a9d83545c410633f6921885c701e94eefb3a7526eabd520e3c31c4744b706873b4a362116d6e56d3b9ed4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b54f67187d9d156b2c2cb19669c7945ea70c9daa365e25e54be7af1051fc84a2b1cab84705354cdbf23cf733a3575a50000000000000000000000000000000011169c31981fad975f4b9fe25e6b3cc47daa7e1edca88af9f3ab3b43f703c169e99b4cff2297d37b3472893c864006f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133afbabb0fad52a9d16bf742480a46b65b623ddc36f0836e3f4d8d7065a5b99a21ff977ab445d0ce93220b9cb07f3850000000000000000000000000000000010f9740e63ef557888f698395215768f2cfe2ee1af56d176c30f722fa50af58b454cee2da5dfbb64378637aa1fbbec181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5e22fc41d88c99119021cac1f29d58f08dd0c3fa2281e52850e1219bbe024c9cf01c5a9ed6075cc37b9cf289df84aa00000000000000000000000000000000042b92aa3d9d7daf59e1c1a454b567aafb836d3e0e9f2dd5e719dc2cfd6294e36e84010257002524d26cf5118bef4d5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c3fe4a1caf76049fa8f6788e89371e41e90fc555e82caba44417a315951f9647f324240745119cc1d0953b740f5ec900000000000000000000000000000000032dd389c5d66b46e25b3bf79621ef45bdde10a14536cff7770d9e5b599e9c5009215b38ca94758c525ca15f3457a2da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001227bcfb995cf1ce71b673bc38f8a4bfed67872617fda83a8b86e9070dad46309985ca5862a011e53f79020d6c3c95bd0000000000000000000000000000000012527f824e925150161ea2fce6100592c2f4a89edab115fb875d8ef6fdeaff37ea7537d52f7947177c676487d93fdffd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dfcee5353fca783ac968c93482b28e4b2988b83d42beacfe6142d113de23bfbba6abb68540e430c5602987d910ba2b0000000000000000000000000000000002129907efe303fd81ff362a5d9c55acff5ee6bdc4166297dbfb445a393c4d6a7de06b154beeebb73c22b0d99076574d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177c64106aae0934bcbf314c83788cf9efcf3bd7d5a6f933e65c648dcc10cf2b0b1a1610640c480233ff1c34964688b60000000000000000000000000000000012a1a6176176e88228f604bbbd3f721c66f3edb5f659c7ec852d12a83281162ec3e09cb32dbbd28246f81c11174c5eae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119a39c6fd474a378fc499c70bf661f4da7f9c07648c729bfa6acff51c4e578a7a491c2456a3c70b348ecbb9fd066021000000000000000000000000000000000224d34e3affb9cf5b15c22b45aff639234c6073013690cdc3ea08ab64184b0a9546b61e92d47b9d252aca151c2883cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179226288c91209a37735b7d2271f780b52a77c07544f04dff6c17f8017ae7267c70c4be86004f2ba3a59eb8b147faa70000000000000000000000000000000012c36e46149764754f3f8da4f42a4c74f7e4373f2dec5f2f989a564d7356d35efdb25e212c67d21ab06dab8b3fe6e5db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121fcb535a7f9b6b88108351b69f38c708ab9ce7666491e4ef2ab4da348de53ee58e2f970c0e034d702799ee26a52aa4000000000000000000000000000000001986cb4858829a3705693641e2b37da3489a292159c264dcb2aae30e4c57e570aa8ef96005598d0f94fd4b7448ba0d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e059a037c66b9cc2e7f5c466833ec22d6d645d504fa88ab3f57b9e5376d6d1f48541a9bfe3281f2d05c2991d2e0fc60000000000000000000000000000000018877846020e28b1318dbb7117195ac6ac7b910fd86b2ac5232cf1c6c52630270183c9c0748467ee77ab786d2f91041a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001134052f59346c7607cc01bb78c2a33ba4158337a208878f5fe5efb00700c68c81febf0409a76e269e726315496c74890000000000000000000000000000000001ca1e890af2c3a408cc3ffe639f565a554c1486c5b0124f0b5972d8dff0272a1a531442139c85dbbc16770d07aa7bfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008459c590a02378894555a9398da781d996c7d1f0a4e357b5fb9a01c89e4fb2b52b4b12a3975d73a5639f4ce546f92580000000000000000000000000000000019f1ac7286712bd1fb4b54a23503cd04c9a61819cf94e015cb0a0986bb50895789a4848c8e6a52bc0746f73d6455a6ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000864371bf822c344fcdfcc848b9caf91b9292fcf337826b735b4d251ec5a5bf5dbe915ca7322c90d33e3ebe7ab677ac9000000000000000000000000000000000d628d50ba4747e6f24f28630807f08b110640b7884b482a4537af61d1bdd965d0a8184b83e8590b68897ecaadf802361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9d10092d4b21afabb7eb9e711a69d196da505b196fbc34aedcbf3745b87d23b66c0149aa5464b214d26dcebffab3630000000000000000000000000000000010767acae44d8cdfedb01397597cad56b1a4b070e22a3a408bff88f256009a737f1bffb516e749d91e5bdbd8e59023ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d8ec05cf6e9ba46a64a8927e5055b92051749ed219a878f0da9781cd56cdaaeb88686a259275ee5ed5e58f666bf1c9000000000000000000000000000000000d33a56a2a32bc4d05fa7bf0a6978133efc0ca1c594ebc5af4e887ad82212c426504b203aae1c437b613a4d3067f586d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c917e2e15c0d57a0a6305ed029876cb471fafd0d31b6b116e0973eaa5db4a33e3c596d54023dce9f4f154649ce3ec820000000000000000000000000000000008bf7597f79dd7082eec1dfc0d1980529a59605003b3e33c4bb5f7e3d3050fd950a80f8f387f9b84e1000891d7e962621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cef1368c4cbd5d932749cc0b0e63f17fde656f11d7cee2bc1dadd4f4b5a6e100681651ab79253c0140f68980b9932a80000000000000000000000000000000001461511658a0df5b5da128fa8b90528d8de67ab3399bedd07befc127b79ac25996377153cd7c46557fe2ad53000b48d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc205c10948fbd4d8b38250bbc6f7a463c00b3599b151750aeb87e4dc9de780bba6fce4ac3179200b7dd18be9e040110000000000000000000000000000000012d1959a51498cafc05bc6af7c0b9416b1867d9bbee371a550196753892465647d56ebde36b31b08a51f9872ac989f1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122bc9318be6f05825a149ee22cd55e8b7f899250d76b702f0fdbb856b06bdd629beae4c2f5f4fa60188b6d0295d184c00000000000000000000000000000000070febf1db092f857c365af2cfe718279b6d20c6b01931666eeee3f6ff8709226609854435976fc84ac674d2cb0914e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af5b0209eb702902d9f0817235d718b083647ac608fc2f53238974ace7b183897a3f4d096e91e97f806f8a6f713d3580000000000000000000000000000000004b0c3f4d1f694e536d28bb42a8fbc371372699c6c31041f83ba4ad6f5d2c8a5c1345f8ae112d5168ab00a7dcc7c373f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070f10d1773484f338125d6d285999e2f9c7ca92e76f1ec5a69d032ca0e97ecf33685ac1ccb31d914f60d2d87a5f1b26000000000000000000000000000000001253ad7e29286962512cea59c7ca879d2b0d1df01c78f7aabb35267a6f1942a9fc823e25421592d0822ea5a6d4e103471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134dee2ac93903288ff36ac75df4fd529e8dcc22dbd2f586db8a2483d0bdda1bc62b470c95bec5df8d08a8610aeaaa15000000000000000000000000000000000887d6d5998a05275c9a62b439654f632288ac527c4c17f091b2d10875955bd214945cf95b3b68538a607a197b292e851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f683010d03aa4fc27d23c4bc85cadc5bacb5abeae2346e4b1c2542b44d32f0ec0e89f428a4d0b8d23500d52b961e380000000000000000000000000000000002981d0be772bdcacf8cec6b3e90f12d4f30f7413e33f772330e8d140269854c177fdf9cfc61a4f41ff9d89dac06607d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e13abb36796776a5bf5d0035caf79ed8b6a4cf8140ebcc2c4b2a071aabe86ae991b0f7304e425f2ea441429b3e71ffd00000000000000000000000000000000122211660e4c0a2d3cdf3b544df85ffbe96fa247c45ac148741a48c43a39bdb184c9633a4670b275d2df745dd2d1a5271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6d694268504ef5e09be3aaa4d73d2523da9113cf20cec97656e45df880e0b3f47a17c7e07da9fdec1f0e7d57ff85f30000000000000000000000000000000002061541aa9e0d9ee7317085f60e06c9481f867c5bebbbce48f1b74e565e1286c9868076329efe69e754df6afc8da1141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011dbf879d2eda244b9c343eb5894abe8c42767a0c306b8edc8ab199bbad78c217233f60fa7ea59fdf47650763d69c3e000000000000000000000000000000000154caae078bfaf2a5a4bfc96e2acd4488a2cee0efb9e30cfe2fc3273035b7322aa6aceabd44fe717157d33efedbfb7811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107f24b70c1c4bb1b79483166ebf052f2f2ecce17a4f594d8a10c914830db9e6f7f855d59b05cd27c46bb8c333f5cbc00000000000000000000000000000000012644665c27c6a90db276572c3c28306315bcdb7c9afc8d3f879ae643b0719bc61d9fae1ce70a6d4775a883626fae11f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab1863d3539e56bd6fca1eeff2e717d2745f135cbcf28f213c9d247bf2f57fc8ad74500d44c20dd40ba700b93de63280000000000000000000000000000000000779fc271569b24427fb1d362ca90895a8fa02c1be293fecc46e9f8238db757b02eff349ca83cca20ebe617dc8d095c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137f00e0a1e7ea7ce47ef1932a2ba6299e34dbfc485439d43a26c769999aa1438bd6ad44deaf0b0d4545df47d89126b5000000000000000000000000000000000268c083eb6634b447699644b76f6f42c07291fe72db258a579294787654a5f3ecc394cc92cb28694642526c838345701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3fe80c3eb8c1a9bc8f32ea4db42ca5ec5c05304257bbc45d23035498a020aebd1077bbf304e63dbffef54765409b0c00000000000000000000000000000000199890fff7a495c52d1912b2d2f7608b60038d9ebe89c11c55b3bbfe1bf8b1bb640d8d502685be987d084439ec0b8f591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d01553abd2fa20c7705503bfeff8ea4adfd6808399adbeb31ecde55f9c0584ca0253db923222ef414b8bb23ba274386000000000000000000000000000000000fcb59c25a7a64b2f6da1f847717f6d94a89175300f03d76e181531a831382ca90b8987750d9405c8c51abc882c332ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125a12c59639d0ce40b883261c4bd5f0e232d7751fa754932ca5d9eb7063422ce562cee8246b602a1fca6e608653cf2d000000000000000000000000000000000249dd8d2326be060496f5f0d7fef68ec891b10fc29149d0b8d21ddb4f1d41b1e61877de162402c7711fc9db3320041c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f28bcf415784395119d3b5c5ca500a807bbb724f62e6146bb75bb07715e663f4a9bc546ff9d325ed2fea8c44f7b554000000000000000000000000000000000bded07bcdb0b70cbff8e069834bd282c0a2bb6562f7e1d261f477a276feb00438ab84d53f3f35e9675f44d3701650731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017782c22a0ec6901414a29aed07b8eea3a50ebd9fbfe0d8a0a2feadc927eade0d3f48e3b39a43a9f89a3fa10f960659000000000000000000000000000000001579254ced0ecd3cdce9478da86d636bde054a1ab6d2ab75c90a639762dcd80d0e09d7b2df0d28898798cacca17a7d5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163c69ad6c491a87555a060f9e1d666e024ccf114affd667c06e694120c6089e015337205e96b389890d3d16022b6f3a000000000000000000000000000000000bf19b8511a6920ab194db23c7fa67a70f40eb1eced346963c8f65789505593e0c3c4da4090fc63411d819c15a7741881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1eb111ada505608c6826a89f406125b1b12215cd037aca9873a827eebd2825acb2d2c1909d022b4b70404d66a0e4b8000000000000000000000000000000000284d829f58e3063d716ccb45794337aa0639c3a7d4e6b9b23d381e8dcacfca88597ab05055aabb32a633fff06ec0a681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c30154e8ead8a42f28c2cd880ded0de9d6a56bd16b14bf872b585e1aaac30dd23c14eaace8012cb1c777ce458dd6f070000000000000000000000000000000010070241584bc05c8842f678b0f1a290aec6a67212d131493a8bbf4cb3d6396ea0accd8bd83a3633407354ce742ce7831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127f465cd2138bffefebd96aad1a1890b773bc3e92ef9f3bfce9b87e039a9f6637f9a04c762030a3c95fb481d23931a50000000000000000000000000000000000d183a827c4f74266b993fbbff76e2582e8c24fc18ff31df7c99d09fa2dbd3f783f7d01ae8b63024a924026863945fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007583ba430066f307434868063bb6750b75ce5703df2d88ff356c678374b8b8a9506d2bca473aac6a9a2b58f9410d2c0000000000000000000000000000000017ec6605f7bbb29e3ea35dc3432a4f29276a8d9988477e849a14c5fa9412a9f32705d4ab9cf30709bf27865c5795384b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6d6cde89a1228d9b78b46871f1a0cdebc525fdad5019678b413b00b79763de15f1a6cb9b729d4426b5d19fb1e43752000000000000000000000000000000000b5a4f056ce2832cb21ad990d6406010a9c6af80a91d636da44a5a8ba197e3a4bf47e21689668499c4241422f0fe0df51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf9edde2c5e0ef173cca5e72237fa34009322216515f2c73523de2f4200ff7c55bd8bf1475ff49cac7a859bc7bf5fd7000000000000000000000000000000000ed48dcfd622af979974665276e9daef0299685d64da8b05339aa981757afbdc9ffe681acc74e44cc78049bd78cd10c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114c626d5a5f97d01d8972a466db9d015a1c75c684349765a25266f48c7460a0ffc3c8c0a1702224449508adda2ac6d00000000000000000000000000000000009d33646807728325dd7f424eb52800ac6f155f12c5fc6ed1189f5937d1fd40aa591a4d14f895f81a3e71c5acf9b83ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000716e761bd8756802ff9c2a6b8a25d195acf82ac99a18dd583c311fa408254423af6673fdd0af20bb54df65e2f8ca3ed000000000000000000000000000000000b6657fdfd9d3e58a83cb777871cb795d68d24fece0986d14c70369bfe804f12e44d1dbcb66a999f821c79f54e1da8021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c3093154401ae35866793516c006d7bb89b1b40d0b69dac5bb39503ef6c2eadf18b977e64f9051919435f4fa35ee5b000000000000000000000000000000000fe4843ccb9a13953775b689c4f24cc0c846c674d8c09d747847e1994f4247620d7d4e385f2eb690ecac8f8ce1f433111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b0f635346328719bb8e3368c606fec67423ab701b4c846df8587e0afac91a99e5a17655905e4639069b044b821ff22000000000000000000000000000000001018f5e0c0d11018a90a1106d31f9cf41c9f011ebfac0a9dd4f98698ac39276a0253a23ccf5131e0f28aa717d175daf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162a830f6bd3d39a1569c2dd63331d5deb433c896c0410e8601a3b26aef037de369e8583e8b2fcbb2a6ed8be94480074000000000000000000000000000000001054b7f65503aae3366f70be50e667c17934449eb48babf075034e4ee63f71a938019a3cbe29fa547462d7c367a679bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190bfb7a0b49c8f583e4dc8b38ffcabf4c4488ddac0c03ba579bde6113b650bb469c67b35b7b3330ea12a4d8d8a19494000000000000000000000000000000001881f114393550e3dafdee177de737a6f25deb10691f5415f80353c48d185681208710322852169b05944a5b10731efa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006524c6a811b6aa84405c40d2471d17d368857cb81d1823c36c75dff91d741cd4447b6216dd7d2c39d2b56635345f16f0000000000000000000000000000000014aabd4eed2c8eee836efa318a80fded1f94004fccdeb4e178eccf0278caa50615395719858db7fb2c7c7325ac514ed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066112fe0537c20b69ac978d0657f4bd0bca4b1069a328c327bbda09a10fd1b1f20bffc26657817597b65bf17508b5cc0000000000000000000000000000000004415f38b13880a54d1db36cbf0f88153b58f5e25f93e5449db627e2b5db39bd885430119ea83a21e84deb559218bd321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153ee311d0c39399e915b035c81cc49ed9975249b3fa79f13500a653a107015e14e6b0eb1eea2e306cc0619a0d1b59fa00000000000000000000000000000000187ca82a83c941b370685a00c5d368307a270cfe3ebdbfdf05a9c77011f2862a2b00f36f3fee987acb44d358bb9de0aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7cb7d27a63cdf11ac421fb3baee8be45059292661978bf70607db3e00b38038e88a31fdcfac8a39169e96eb2a59077000000000000000000000000000000000110aba6454b1515c7a8e715a1d329148f03eae054f4bb0b4e689f2f844e30cb42454c3d650b1ccf2fd55b13de391c981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c32e9510be94fb44f2c8d228d3ceea26f3c19bd3a115d0a2dd4f269c7bb7fc85571a4877012e469b3c184142d62bca0000000000000000000000000000000019306027faabdf805408188f4051ec8ec17b48406ed454441207683e08eda6b7fcc305542528faf83d6db4d199aa48201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124d308aeea141c321320abd18750ccb0e027f60bf46f75804595c1689dd6676f2d2b4de52a60f23ce2b0a9785d845ce0000000000000000000000000000000016f72448e45f6e1479bfa3b0a58f04823ad10a8fbeb9315a678a96674a77ec1d7e80bcd7ed366c087bea6f8158518e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad1828e277dbc837727490d2b3b23467356a6afb35a679e8c4ce8b02da0fda62c37f55513cd3eddd25349a9f625bcaa000000000000000000000000000000001600a39c4ae049c22c2487dbcaa9d7cd83bc3d36217079f57af182ecab86ce2e377d8d6cd8d03d7d0238c531c65f530b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d0c95928e7443382a6801b52a89d5d765adde938d93f3458667320430372725ad5641ba43bf736e26aeada5840466a000000000000000000000000000000000f38f2fac47b59b51a6eaa6f10edbf0c808ed5e1ec37dcf4929026d86677792249537ab4c4c31cacd4509508df362e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000617b915c1a71472611c0aca5f332947f0e9314cbde5ac9fa197dbbd4e5210c99dd4857347c517077c780b183911f5100000000000000000000000000000000111e878f21046605ed1ec1acff14a65ab76fe8bfd9b5366c60c8f5ea3411ebd9dd40d5cc566301a226feb5706a10e93f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d4dc494bfca265673402aacd8e03d03060f58817f1cb8ec02c4061c5927971882350a8fde6e03884d58b0ae09c05830000000000000000000000000000000009eddd78d93e462baa241c54834b50eb13588231592efd371567b0b1f6c221e42bbeab506771faf7f0f72ba707b2a1c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057177817fec28e26be81c7157bcb808948381ca1d7f15f38547d31965d47e578a80c6cd0df56326a88b2936fefe4d01000000000000000000000000000000000a48c9dd6bfe505565f29ad3f37bbdc105869644886db17e858584620390fd7c96ab9c0b4a071acbceddf1837b4bb42a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce7289e56f28c33a618a3d74aedd6eb540a6ccb11d4d76637113fc491b40c58f2350b0bef99d1a1f1145468f003bd41000000000000000000000000000000000719d4033aff1d6c7abd3a0d052033b7f11250e327d042db555f02e0adf8a5364926d0fa9af936a5a9d9ff074b3aa0191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e50c05a0aba567aa9263da3742f18a9a46c461e4da36ee25489023e9c83f29b9031ef255be676e38fea1976185fad970000000000000000000000000000000012ea0296b98e2c853a8b61658d95f098c327649bf2f0bcfac9b6a58264f9708d419d2569125a846cc8cd6a2301dba4141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175bad04a658386447d7def44f640c929fe001da40fc296128773cd948c0c45c6b4c668f7810482421693f27dc7b320f0000000000000000000000000000000015c056b2acd16f6df67e566d122da81055cc570e5f4be1071b9b58c3960966b583524d28c07ea281401783d215510cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016e0f682af163d945b26e20df5f51847e1bc72a51ef59591e512d912bc8afaf52505e8a74e48071408d909051984964000000000000000000000000000000000c9f8b5dfede897748ed1290df886c7cfcf34813709fe127518889c27e85a8eb8e40fafd307ecd4c2811ce0ab663d6e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ccf9d859968ecb3b3376208406bfad762a7727cf0594ea06f3547af48ee355c9d7c52ee7b2ac7a11cacab5b7b474ae000000000000000000000000000000001748e626aa18fb16b0e20e353ead9add544e3b0fe24e651c34f0543d38d86a70dd7d183cd256511fb4573a32dcbd0c751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000013aab2526c8db7e75642e3b56a00c2759206757954f4fe3a684d9e719a5df1d5036cad7d515ea4668ba6ea95d1e74d00000000000000000000000000000000136a4065add8d668a870fe794211edff0d0e476f84da03a3796a1b1ddc9b46145d17a9c9284d5e162e842ee8d33791ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb9c4effa3bcbbaaf4f8bd9300e20e64c501b44eb7a415d1e7a5673a9e0c8cbd10aab248778602081420a229633c3d200000000000000000000000000000000165025776b37dbc9efd3f7d258c6fce82ec3f7f3fcc29fca665c37d2fb9d94af3ed66baa3c150d8f02d2ab0ee6d196b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d5e4702503f19606fd86456f6451c18d61a51d9e176df6c80bb4ff2832c8f81895ee58b5055d28fa070db5b465bd44000000000000000000000000000000001851023a1777e751d955b7ed41ccb59c79642c3481d3b83b1d42d225590ac5168c8ea1c73300a470dfc6896f9596e0821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b0d317a634bfe36fe4d6bba0db9cff017c79604c32cad52bf04198b904033160836a1684d7626c4d95dcc8b9c4238000000000000000000000000000000000acfe12b3bcacba11ab226546a3ecc841d126b78c669ac88c58a19f16ae53c5c04f1289924e52e3bf25028a6e72f1a151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1bba3cbde5d43f9c78e65adf6e97a13d8e665ddd29d0069bb8e85c7c5d9a6a6c401eebcbe43117d9d37e076dcad4250000000000000000000000000000000002cff6630dbade788754421d07d9b9a5cf30916dd19c8db8f1d1976fd62991f29f2790525f30cf8d9ff379e532a3088b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eda161fed19f5074fd407bad6adff4571ef70bd435d4c70e4479d395e81f0833831fbbfc13fccc894e9c2df6479772b000000000000000000000000000000000369260e8b965240604d7919eeffbc84111f369dbb30b7a31c1e6b8278ee0324d8fd75601eac68c47be503803ccdbf9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134c07ad7506821a767e40acc9a4a3b690414a48380f01ec074a5192a0aa9dc53e685b99f9b9db1da3fe17cd7266e045000000000000000000000000000000000a77531440c8ccfa968fe835d6aa8d085a86060ad83e96dfb8b996ceae80dc707387e4293feff8dca1da7fe975852ae21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7a6941070a08e4af416367002e201abb19ad89099af7d54cf391893b399a5e8c1d0adac977329d79d4fd2bbaaac3dc0000000000000000000000000000000002748750118f728605090a5ee87055576908822b6d8647306381c709efe321bbeb7d8baa84d448f32319f415bdfbf8841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6e9cd4b4755f6061ed11a1998e237d1526da1c68916f27c3097b5a1fa0a2f8fc4cf72364a7401b1d083cdc9723da050000000000000000000000000000000014e576aa7ab9443ce6165b206f98ad8b65c63b36da61236a2215a06398998ef0b846aebfe7d5219cd469186b6a38a3071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cc6dda41f877440b84b733956377b280ceaa51bd0878154ed5a7524e2069a4a83199e9ca8599fb963333c093ba63a00000000000000000000000000000000007558b84a223cfacc73a2765515c5a1536dac83d355e77f30ae40cd94a8d266cb3080c7c2305033439a9fdf32c0000101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114f035c7db1ebaacf5a19b1eafce096086e3d1c15bd6cd840837207ad91605c1f6b39c645f2c73f9e1ee86c3c38a3e600000000000000000000000000000000043e9bd0631bc9655ff3567b23aa28809cc6c2dca10c19dd5d61d2f8da75ca66b3d3fa636dcd5291f0197cbc7445e5dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114e7f4761603e6e5f1cbc3045f724ef2a109e0303dd2de9f0cabc7a740f8683476e478d6c6c2f06a0e2fc1d3528bf19000000000000000000000000000000000d9423807bd5fdcdf9a29bf0dbb18dfa24e9f6d251238c21f7178bbf72e0ad7ca8c88f26768e19ca1155d0a50493d9241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000710badc66e453d341bc8024715491d8087f24d49abf1b7ab3dfd5d6400d1319086d5b28dbea5dc0e6efb6c41a04d1740000000000000000000000000000000015ff3098afaa2f032a19322ce84ac8e96c4aa8be45dbf9fd38d7535b4d032e466ce9f2777ffe2a67ff98b8ec646993011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d186768a7f5a163c0e81289e9deaf23beae4cef029e5b2732f5f5f30cdb3376a6fb91bcdcc60be0fb704274c8a7446c0000000000000000000000000000000011d9a5234787e99e6ab91d688e1b8d558d1307d8314300b9c98ddc28414c34eb5422e6d5ee83674d55feb7550986ada11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c5523270e36aa4b8109b1de6f2aaa64cb82af4735bcba86cf5290e70516dc9f999799aa8d46f8272b5f1b37d8aefce000000000000000000000000000000000ff88d738e8bde309250b084061bd5b02965abc89f414c570bfb7af2e46442a6c3fb646dae95df9f9a9146cd5c0555951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035e7ba1d16be64e34a8ef1643817be28070938a1338f0677484dba34afcbbe7bfb70aba8af6dc6f58377c9c0284986c0000000000000000000000000000000005d162b6aefc068956b642af50d8d946d9c54ec87f6a357d0deab1fd7e63667da9ba3951a173c43bd31c7b48a4a169711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097a2176bce8bdca929db516336d07a0116e62336b0f20ceb211b45d96934a4179bef91e97599120afce741a0dd2809e00000000000000000000000000000000167a0d8b7fa26a863330d0d07741a0759cd48070f4ae20f31a26c78d909a6e7db5740c47d63c2e6387c56373074ba7a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001523c906d6871d1712021eb6d02cbe3de3022ae065757ecbc649e774cb023910cfe432030736a5ea071fdb1c1a06ba7d000000000000000000000000000000000275529a5c5ac15d80dc99570e776aa6282187592f7d486dfe1d5d525cc4a157367a8ca95288a73845f9d603980157781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec8afb041a771bc6cc59743659de9d7edd99b8a4467324a08db0f4b825ddb8f7bdc49ee6f1c2dfb27bf70250e5d0a66000000000000000000000000000000000c2e7e9a81c2331908d844e6f3c460a9bdcfef83cf0748bc934c329ba4b7c9ab82bbdcd19c270e393ba1146ef2be88911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f51c3d6d6304dc229073956289625f7138dfa366b313525bf99a42cc0774fa559973c6f5dd7acc8ba8301560471e2200000000000000000000000000000000013b95841b2fef0dc5af31e47e526e54598fc34750793e48f36f6e95280d4ca507af75a8907ec779c6fa96e76dd4581011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6b5b1ad9b72ab88e1b7b22d4436541a94f053208d3b43306af8837320023767e256073466cf7f77f101aada424d27c0000000000000000000000000000000012aabe4aefb6a294ee68b3e65377ef41798330b9682b0d87a225cf1c371c39269acb9295126f2f20910ccf848e080dee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066568bb72034a6e91b7fca1be8f21547d944a28c0313119bf7659679abadb40677b1637c54ef9b0dcd69e621b0175be000000000000000000000000000000000365372f94ed3d8cb57986b1e57b5b3ada3574ebe3e7a03afaa0b5e0aaf3ab7e812040411358728d2d1211d3b809d23a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cf3ec9d3877bca04e9f96f1c8c4a9dcc82ecd353ef497d76fdbdb48f75c469adb3ae71d3c4ef2a701996a740d67868000000000000000000000000000000000980375d673e44b235fd68811b485388be6befc8701048e68f7d07f201bfdf95a22c9729eb714a47643b86851575872d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f36c310d3a40630ec183b4968c6527369755c3c715a986472ea3b1709f7f68c83d4c09f75bc811de1edba1ea29a97520000000000000000000000000000000001760ea38928f86424537d3ed2804d2329fc670157fc2891bbe4747a594bdd572e08ac4f220f14d09a6dcf03690632e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189f946984fdfa5973a0ded1d655b9918672b7091a6673a6144948c28ec7e2a5d8c847362a10fe2f0be73a541f98f166000000000000000000000000000000000faa511ffee7c79c477123db97ca38bb07bd726e168eaf7f8613e0d85e7ed803126d0b22be174983e9058358285e80991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182e13651ef67332c456646b6ee145c6a55f3187a51ffa65a043ba707ba3bdae81de346b5bed73367f2c9d61fb7a06ad000000000000000000000000000000000dc33d15486efdef313c95f9f70f8297e518053c02a2df8f40aac209dc98d93925146224028580556718d72b9153386b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021570546f896c62dd22f44cd5ad4978330df53cfd79cd1aa945f1b593c563ac1d27ab36c6a89f57e8f984ca81d500e10000000000000000000000000000000016c83533cc6ecce644ff64cb1a3a8c57e66c704d1c2e28e86d7092eb27dd7fab6cc2f506b55cb1b334382fe4ee7f25a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017814542ddf5c1e24505ebc0f8a2e8ff2f7356f23bdc1178e6b582e5799ea6beb1205e332934ab2f58d1e03ffc2c87de0000000000000000000000000000000002a84fce73de430ad6f3bfec7d6a052b70c2f6a7f7701a755a38e7fd1677acbf43c7619c8ede78d6aaa215b1213884511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181b11e9cddb6e76477755a60a116bfb26058fabbfd24227ef77c0b0144376f73b85f6dd33fac5295b34c85c91da394f000000000000000000000000000000000be9ac9baef26b8e604235a9fd93b709201ab7a71bb40f7e0dd0088392615c9a1e6c5e512e0a1ff0af0df4f40f58d3871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168a36e2d05306a26a1c5f1ad7f3cfbb4901599ed3059e991ba25721b159499a0898db606cb4516e42335b1c51c15c26000000000000000000000000000000000920a2bce1aadb4660f013c39b6f76f5e02f1f991b9b12e01bdbbdc25660835915bb2e6f688b76a066985d4c736979bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004649674b64c3f92b013b7a0ddb3790eae67eef0a5e509a344b98f0da147213c8a5f6675fc0d3402f67c88edd1168d23000000000000000000000000000000000dc534a517ed648ac4aed345afe478e1e30fa68dac284f314643f174d3022726a274b7182922af6120230135cb4c2fb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084c67e965c52302bdaef759bcfbf886879fbeb7dddaf0866727aa656018efb2b5038aa9ed8bb00a7dc35236c5a258310000000000000000000000000000000000a231f94cb81b70ab7cb3c592501832e306420b8b01f2df45cf1b374b04e8e55a666863bf2b2608a4ade5804b9ff6811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001203f446a7322b15f0b5e6c077e7c5ca1f3912480073d39ad00e62b932e6dd23521b79bab8b871958b9fc681fc8f62fb0000000000000000000000000000000013a416d6f7c218f8ca044a13ab7149be277e30dbf1361183ac4192ec2293d090a896024b785d9598c31dcea5d9065b681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b29cde24f39c8de5610538bdb9ab71492cf65140876cf5a0de24e6664cd07ef95dba1de70feea6d54126d84f02d1e000000000000000000000000000000000003528892a780e1b4e7ed44dcca1affe376c30cd43a6fdce1632299a30cac86fcd31014361dbd2d2b41e619063f2384c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3a547bd965507d04e58ec7567db6291709edd8eb05ce5110adb31e4fd45fbb2eb82cf0015e0a16ab6e3c62574edc650000000000000000000000000000000010cae65f07bf99b3b8a82f659afe2e778f751b52487d5eb37a089ae2f5f944f4d3d44de66e9e5d9b73d072ec6cccf50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117be0f47a10746ecbdb5f9e27171a168db44a881a5e8ac5a5284e975b0b8b799407b3fd56ecfb4255c7abeda46d9362000000000000000000000000000000000a07e72de4c1ee1d9e3eca42747797930c4fd152ded2aed2e4877cdd0fae4cd3462d0b5c9f998c24a1e30068cf3640091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000443dc582a43dd855a899e50c71183aa287da2ff7535ee914b986854a9755220aa19493e1fbb8a76c94df329fb7cadea000000000000000000000000000000000b88014d62c2f7aa5b66b0a911b4e680d4b62988abb805232cc40f071454d02a2c904da19c53ae71b5edc20989cfc7401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182f46aa6f74fbe1d6b7fb4289b64396981c2732a107426ce7ad479806ae5f58a1ab8a7c8e7bd49af3497c6719ec5664000000000000000000000000000000000087af5ded95a3d7c085d64b658099ea085ad95ed1712f6cb83fbefadaae2cbe073eeafc2ed27fc5f8a3fdf74e0536931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010999ff27f530a977a4dae5036f71be0f19aa1f4cb62cb5bfdb3049cd184b0d1750a395e75c575d2f1ec64dc239aa3da00000000000000000000000000000000156844ea096dec9c62e5b7a829feddc0df74e6e2a06db905477802a0e2ab5de6a9b7cc7001c2e2611e2b661122ad24a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001835fa9fef758d13e0d6d7e372e6455b6d26b6a0a10a677175f28288bcccf9b2079b94adca0bd345a8152cd45bee318000000000000000000000000000000000ee991f6788c2894c808b28f1d2dbea0fa39a5b7f12d40ebe4699e35e6562b696869309f603f94d3eaaab3661e812da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008134308eed1c5f36fe7ce6a09a0d5c1b3c7ae5a54406ac462c9eabb4e4de5e1b9955e5679f317c1b3887414beaa95fb000000000000000000000000000000000cdab023018e27f3af8a3946461cf4fa87038684ba684400e6967dafb6a0375e806c9e4828d4ef0c99c5a518f5e62c4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117c50eb91c53ba1049a6842c4778f68520a2c777396e66077ba21332e6e748a5bc2d0b2c782a288f315132c155c99830000000000000000000000000000000004d476e19b48938e72501199993b114aabb3c194084d4d8391c52f4d965f861d73f0c6b0cf717581d639a968ac00fd261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000261eb78c2d7761f9f0cbb6713db252643f556a39bedead9b29ed85fc1622937dbd886c42df17539becbbeee05bf018d00000000000000000000000000000000050d568d427fc8168c0955df7bd3d75d101c7d6c3b61a436a3e8d3f251c6111f66e1268bb2d7af3329be1b30f1922c211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011dd3b5b12c8ca944b3678159bac55f06a191ef0afc22f96ac9623fe8219bf333a2913b80b09f739bd20879e267c1a40000000000000000000000000000000000a6676a6b75ce49853405f105301cadaac5a153a6c68e50e2b987b1b69c54ecce9d6f302bb334539c47e46b632aaf6711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000474eef0c18ce6215c547ac32ff341f3013901df42865adfcaffa0cac9c85fef1b34596a0374646b97a50ef7c021b4cc000000000000000000000000000000001635adaf4d7c320f9e3a886790163df345f5baa543baa7ebca3a712d3f66c55b837430f3fab9d0bcc8b6d7df148f0dd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b702c4c81966935d31f21935757d1e464c0a487cb881843fe8050a30b2ce931a6c279f782e6d0814fc75ae754d091600000000000000000000000000000000012190154b7fb607d47059a5c75a228ada1f9f1c6cd9637edb7404a4ea71bd0d5eba8f4757bacecff94f2521238a7ca591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b950c2d748f0fb01a2ee6ee3ae0be0a6f30698707744b8b2eb5756552215ed189cd1c1bb2b8a76cb132b97ea294d4c0000000000000000000000000000000014f4b308232231424209ce8ad7e3f7b9b2c02ba99f7794e37ba45766d364555e1e305d0a3b731f94db50e137feccaa331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000431e977a01295e59c0cad353c13cad6113fa10c0f74cac235ae1aafc8a9a0de705c6adad0e04596cff4f5312328fd39000000000000000000000000000000001292ba6bcc6dd06d06bdd43ee0e714099b76fbd0585cf5c8fc800afdf172292af73458ff2034bf35f30c663dcf07a0201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d13c4aa6210723e7b40e4c6303a5ff9037854a2aff73249a7c817565d46c5b5bf0f27904f397b3425809b5ad940b927000000000000000000000000000000000b6516a23e4404babe42fd1c9a10a6c90f80a69cb90fa4e564258a6bfa780167b148c3c667957a897b3effb52cb7ff8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128fb9b94833499c653e5c9f7b03d28d7a6937458c25b1d09f7457fc9469ccc8ac0a2a7790fd530a453b17c58246869d000000000000000000000000000000000fb5c99cc1b64db7bdeebefc69a4e75c87ce5286c5e4021eb7ae1b8e67b98ebc09c7aebaf733e96428c1d2ffb277e21b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7fc580bc588c297383e577785f3b82354f66b7390124ad32d5270abe95fbc8e5408eb7a49da3ac77ebca6a57933173000000000000000000000000000000000a3c7ff9c277b51d876e72262093fcf87520c6ec9911aa8037a624ed9cf5bb3a99f8089bd0b774f314ddeb711a82301c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034cccb5ff10ccaae44482dd32a1b91010ffd2a9815a08d39d027fdeb63840b8c0c00f99e60ce1ed0576166086d52337000000000000000000000000000000000bd6f75b651d27857a52fd5605273d6bb13387634ce17b789ddb51d61052a79189074360f1b415d5388fba9156d2b8fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a7acdc1c14d7c47f11819f09a2b1d33adc58fabe69a21377a524e624f6184dea0026ecc824b70e59b956b3f17fe992000000000000000000000000000000000de3fce8efe567049e0f899fb36280dab792ab5efa389e1b7cc99635fbabe3e052c600f7125fb38e095dd7ea980d47a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182027d4dbaa9737f2389936474cf920d86d3b3cc9a2164e0bd6a1087f7547170d7efef3409baec3ce68fb90b1d439f1000000000000000000000000000000000d01014a7ed1e888e282ca2037f878d4d46cbf134078e89dace4a77a41b2943277737d02cb2af43b5f8569f670a8d9901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118f0992f31e4a0f67545167fcdbc1a93c2b3a46ac77508c485a14c6e044baa8b04422a6aaf91d74fa3c73f952b84c4400000000000000000000000000000000126b32b62ee47a3676702ab4eb6735bd97854ada8ebef04c74c715bba28958694820e14f5c1fe4bcc956d8684abcf8461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f02309e85c8d18d0f1f42b36e86d4d08b30e0c1e36537e39748f1c889134b4a4dc82d8f871bbc20acf4271677560dd70000000000000000000000000000000015bc83629c4064c294832aff45af17faa7f313e7d96250eff7478808dbaf0e4790cdcd232ced5fc88ac3fa47dffc39381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae18244c91d25427e1de84fa2a9218ae99d8792f01132c5b9b63c885e3500ef49bed29270b0f694faaef428ffd5c25c0000000000000000000000000000000016a0b3f00199a6038e22c8420702dd3d70727b8838026b18521adc95653b9265c5fbb99a6052812227a266d62e8a41711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081fcaebab68677ace7cf5c31828ec9bd45e5fcab70151809da87ff57772e19f9cdd2dc8da2e31ed61d8deb51113b3d0000000000000000000000000000000001562d8f4748969d8cc2d0a3cd1dac2065f9491b47607f6965187e01b134a5ecc4c5383dbaafca17aba71eda850dba4391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093cb53222f27a258e0ed9ffd464e2fdcb7ab36ffce91d646ec1d158eb758cff0c1675440e82acec1ba55549e63d91a20000000000000000000000000000000004b70d06cc09bee74554f8aba2521e1d096df0deabc44a83efb01a8c26c700c733c725579384dadad7ec76fd323663391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010047f05006b8ebe1a8b52acb18e74dfff4324114c6291a2ea35747327313c8ba60139ea3394c7811b6938af414cc94000000000000000000000000000000000019a024075758e9fee3eaba5ee5fb6dc53d0f7a9c00aa3c1fbdc769851ff78c379544dbfdc27c51661feacdf9c3db3121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d79527bdb23739f5df6e853632c9232b4bcbef6acdd04b4530bcacaa780ab5c9e7e1f9fc46af8703eecda6078cd6630000000000000000000000000000000016a15faf5144270c79501910693a69dae9a5dc141499e87686e833dd75deec3bf11e0d9975fd97bc2823e07c9eb50edd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d88f030d1a4955d2a50907b7b6230dd479e228089765d6916765c2a9b157cd6fa08313dd7cc0a0bee51381d8db94fa000000000000000000000000000000000080000e9a5cf21acb270f85ec4dbffd5f878755d45242f98f64ca49460a27cb3f040e50ee1b1b1d91d44220f1292b9121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097d6dfdbe7a6d8b1e93ee7555a5e257031c62f67ed42718458384978265dfa1e541f3424d354266e9efc40fd377082e0000000000000000000000000000000009be64f8e4fd2725dc3ca220eac4bbe54ae5fac5708f548352c9795d80f9fd044750e2de47f6447b394489bdc9ca485c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197893290290fde71a9118b654ea3d08e40e5d6567b0f06607325e35e2b2126feeeac5cbba311e6c06bade1d776c814f000000000000000000000000000000000efb96c5fd2b4492912e6bafa90500bce0baf44cde9f4a2188c2ce9087fb6b87ecaa91222c5c0f37f932ce888f27febd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3fec6bd9dfdf12be8316365f412902f10f2c2930ef8ede5c610d3a6bab8d3f31f4d04de5a4d9012174ab480ad23aa7000000000000000000000000000000000885071f2e531d875eada9cbb06e0b9ff1dfc3456479020ce576ff73aeb9de7b3affc6c79b14b419cb79c28574dd953b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e3ad5218ea3d425efe262120b2fb2a58913ea63240a654b54604fe4faa4549b3dbeba0728379fb4bd12b6d526b5ebe0000000000000000000000000000000006277f4fcc2ae2c7d173647c435aa18e2b93122cb77a47ae4237402052359b80353a1322d7dd16cda5ad6d2e9c0fa2281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5ee7e1b095afb224ac02974892f3fc9fd5b0d1c2773f125c7602b1d997d13d2bd28130c81fff7d9af335570041b75e000000000000000000000000000000001384ce3936604451ffc039f79a7b2a548f0d58bb21c655f7a020dd6314aab21b046350273423263b1e4154de6018b41d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000888d26042dca804d9bce363a69c9dccab5375f3ba53ca6c92752f0eb0d6a0e2e9c8fa8de324dc3b32f3765ce97540da0000000000000000000000000000000013e546b71db223830a04d1b6ae39cfa85814cfea9decd5c7641136ce4a1df020e553f02495cc6c9d8f20570c246905131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5370bb0d75669c4e9ee8070245ee3c372e3cf940d7210fdf4ab443b9226099df908599c85d123c3d58829d0cdd827c00000000000000000000000000000000023deaecd26b72d2e6e40b7b33783c66823beed7fb47b393a2073ca9890ef4911742d6c44c7e1b138685f4bedfdd64961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1222435f5056d78ac596335828a8ef84f23dfd22504fa4875b42c7ff7160e1294ede214f667f74a633469dcb2d028c000000000000000000000000000000000fbed157ed6a9807bb35ddd1fd2c433fdf115c9e1da7f3702a245bd50fce3575ab25cfb10c1fec44f357c3fa241302e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001198a4a93f81091ecaf3c3c84a10c370505a37eb06895eaf9b026ac6caca4900ef2128dab1a086dc5379ccc508ab6849000000000000000000000000000000000a5e57bf4559328468d79a47849d4320a9ac00aefd04241b2013a3a8ec2cc3a4f01a0d1c94d49bec54c827df2e0ca05d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e4f6b1465621806f64ca23db2254f568deb6d93b766cc6bc2fa746692fca64463c384622f93189a510a0aba6bf4dda000000000000000000000000000000001437e93338dff4e9ec9549e215cffc01f70a4095e03b294bbf7a002d79b95368c2d7e73812b56134dc7b5d31f9998b5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190ef1bfb7eb8e589a7a1e1065e463420d8365e6c454e96485a11cfb75a9884852ae271839cd43546b8e8cbfeff012830000000000000000000000000000000016343ff76b64f33b45c953f6107147559f77221877234cf7c5959dab061d73c3afcf9f58d7962fa3e50852aedb18c0831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000515ea034f48ddcae65d1090faafa598fa85ecb349eaaf04808964522a1ba88986722124b1e7844662987a7e7a85c46b0000000000000000000000000000000017a53c13dca393c5aa672b5cd0f0d6417a5d68a193eddfb6154dd93f49de4420211d4a4a0956f9528f6dc4d394e0c10c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d1a7f429a1608395ec8a385d068297126a4cb5664c67eac643b9aed9066104333c4ae9bde178b22adf95812a394de000000000000000000000000000000000041641ad0950398b419249023b291d2f095c3d9503530bb810bd57430e51bc12e2065a6ba00ac7f6ce1cdae8f8c4b7861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017b8420c725f2ed05ac1e6e56b97b649ffdc69886bf23e8ea61f08edc407960b034517bfef15c57234ff396cc2ce9b6000000000000000000000000000000001170f591f2b15181971d2a12c2e3264ff9654aa74d96e4068a6d20ab4d4f8cce7ab74a87b4691271204f9c7f26f9019b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8df01e17fc25fce290dae5212176fc3177a3eda26a6484e25120d594fab4f7fb8ea8a261a312808ff5341682e8e9a0000000000000000000000000000000001ecf5cb47f717ba154f3f6347cb65689477e676cd5ced69d1f50d71b788bb4142f888e2802cded07e8df0752cfcd8fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003277fe7e8942fc540aeb128b0f87a6937db3c42cf1b10986978a59293ec5f586d12f8efc56b24989bc7532f7d330cd5000000000000000000000000000000000365e6a7109d1c459be428fa4d920c3d7591dc0360a062e9d4f62c66877b86174c3f9c818fc7f0b8b0c083db4ae84f661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d42a100025f5f8bd56979a0b15a9f4e3d1d7c41c8903ece56cede7137157dcffac8c2fa75fa7db8a648c38b616d4150000000000000000000000000000000005a41a34f189f261cb2169ca1a2552d448000ff334d380510e868fe3b13122ceb254097207a6a2325aed2fe7954bc08b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d77fda012cd3804877272cb85e4fea4decd4220bd961af177b13e05e4580af2bd24de83e392a49a1dbc781d6fe62afd000000000000000000000000000000001533905928350e78609eae1252877972fdd8190c24913fb8741a5da6d5ee171b0effb40c0062b003ed440fe0b12d4cb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fd7872721407893387e1af9a487834689b804a4948219c9296e17fb936c7ca9f39d15549fbe79cf9c117627db3622e00000000000000000000000000000000035bfb2670871a6814285155e618ee55f538db075d6f5b37289ff60337f14a01aa228721a99c836d74a34a6be3d2d8261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092a254a1a8b90ac06f41a925e8929e31196f1ed044e40025e3dd92e388da467d0afb93f9865a4f16ffd5aac0427557a000000000000000000000000000000000d5fc5732adb4525c812c005038a319cf8eaa83fc3b65c048735d8ae7e82b7c3951cfcd5eb36e87cd0a70a2e41ba79231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043b7f73c36b44fa867d5f63d45f7e3ae3b9ee433797c148345557928634cab556df1843206db6fb8582b5d937d24a040000000000000000000000000000000018b11f00679b3ff73dafbbf9bab7e909e11a3e257f14f367145d31208bbd5a301af2b1664920021b5168d27fa3ba5eae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b25b442d2788e3e2158b6c4e1e7c654d19910d55201f4226127588b459a110326f7e3f8243f7735f01a44ef5d7350000000000000000000000000000000000a54bc5143469e523183749756a760e02ded2ad292dcf2cdc5d5584084fd9992a80f5eee34bf051832f90c511c5476681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bf4fdaad2fdc2888a8ee7a6ef278887e98a2268e56141b7bea32523e5bf38cb73fedd52af2c1804683c51bc31fdb2c000000000000000000000000000000001508739aabf53d1625881fafca4487a50ae34b3d8f675a19508cd320303a059eb82ed89851cc3f4176102ac1743e70a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011299c97ee11978dd6e4f4e10997436c523230591f2230112d0705400443fc520d94eeaeb4db5fa9820f1b01e16ff6a7000000000000000000000000000000000b7ebde19fdb8e2f04f0f1da417a7bf327fb97a06ed1ceb66a1ef5ae8ed27e4ec5f350c0267f84009009a1c5a5808f861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003029f907b768f745b8399bbcb65703f1f55114a913450f0d2fc79ab51c4c606254712f1bd73ff40e3d5f4fcafbd647e000000000000000000000000000000001637977689677e9a3253283c6925df235cd676210379f284eb44bd54d007185afff3e4f17a1ff021e242675551d5acc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001028a4c6a19e8f4e2ea89119947d59379490aa0b99760eb1d0d72ea3d0e727c5113b18d0631464dd60ffd6dfcbc9b912000000000000000000000000000000000b386fe01c4666262fcda30a2f2008e602e509ba7b6c3ecaf55d5071f4cf2d6617fad5a469f4bf298fd018d9b56e9bd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016995386a79aa391fa6042d1bcffe3ddb343bf5d0e0b8fa5f969b96c2c7713aa4a5c1a488dc7d58db8fae1893776c8af000000000000000000000000000000001848397e095f75b09a7a2a0ef33f46333d716a2044d61a0910ccf700c337b8c9a1591ea51f47dd383f2e27268fb3dd7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000581998237e4367ea45c66ae720701c9564202d9e167de582d71d2e65948f32d451456015e0b678484838526f3238d1e000000000000000000000000000000000817a81d1f7b80db93faad87a5de905468fa98b907ee4bd00a6cec7bff92bef9ec9f014e2e8d831032031660e40792df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4ad9fbb902f1b9f7f5906d89200ffaedf48786f03539b317d10d1a7317d0fc43bc8124288879b28d771ba12707e4b900000000000000000000000000000000032f484aa3a751b0b830001adfeb8366d982c763945b62d6fbbd1f3f95a1f41465084a2afcf19087f02f1bdfc9e359e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000943a9bacb0faf2c80edfdd0cbe16ad9efdfdfbbea95a6bece0a5ea39ef0b2306ed177c4bb6e6cbfc3f1aa4aca45970f0000000000000000000000000000000005835bd610465fef99c27477a029d7f182c3a16c134e718973495ef49819c6bf5daec6014b39865d1c66651631ad6f241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001538fb84582b2d6cff465c2afbd2194365ae25e5c1c129875db0e87b49d842d82ebade8cc00b8fe2859dc16e695a32220000000000000000000000000000000014b2dcb25c17e2b164214da4d5090ce49366476a56e7efaae8fad1ceafcd46e32bd2ed1cedeb584d9132af5a8df4d54f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015261072d9fa05b56626f0c9de76681947d46538449b2f49137a3499dc78c2d9f128c5cc76bb1de8f2d4c11891ca80e700000000000000000000000000000000198bf287cf695b39f8213d96063c469c08b3fb0ee62641fb1b4f05e445a2cb70e5195f1cd5ef455cd7bf47fade2b588b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000882c23698a842f71b00dbce067aeb68c0590051765ca3b7732bb87ed2a31e2e806d89b803fb4c662ca17367f00c183700000000000000000000000000000000059abbaac8f8b2f8dcf70ed664b96ce3736e9975a40a48a25ca94f03c8401733745153cddb25da31dcfa9c73681128ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005972cd71237c7fa8a15f35f9675318ff1ac33ff525c27cc185dd79802df3d37617340d2a46fd5aca5a8882483bfaee200000000000000000000000000000000052b06fbfe7bd8fe2a7bf76ec22b1ffb2d68252511187140134b200438dbdc422028ea171989d7e3a6607dece4033e281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001251474bfb312c307243705e3ce250ea93488cf923536e5697e3026d608aae3921ca9b62d587cc1405c053a96dd71d540000000000000000000000000000000008242bd30f5cc2d9794b2c258006abe73a3547a19704ed34e37a8f06a5753bfe969a38098e9bc6c329818f8929aea1091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190f338c4548bc0a791e61280b91ba0433e51fb0488110203af50f4f1fb55b369165fe953cf9c22a5ce84efecbdfdb6e000000000000000000000000000000000e3dc00b2540ef94618a5c8d9998054140d832b76de7f79e3cf25eb607d191dc2298dba7c2dc501e3d5ab1f4b9514a2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eddf7ffef969cf5418e154518e929f4c8f063e1ac82f730bc1bf55064a42884bcf0583f3928f741905cefc77edcdb0000000000000000000000000000000000cd491d60f3389b5ffd5c39224fc883990e57b550d48e8dd70cbe263e99ebab28a4df65adeb1329d744720195736fc211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9415cc54bd5ecdc2bea7b32a2c1a22cca7f1c86f9a3cca56bd0e59ffa5df9096faedde3f10de9c0845979353747fe4000000000000000000000000000000000fc38fd750c57fbce6191eb2b6cadf2af99854bb047a65be3ac428730f9e364257c747f455bbcd957477ac5a9e3266421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cbc6f58f419b033ef48e86e295a7667a90863336dbe4a57af1c24b259da0cff2302ce2aeb21dda327e6c9fb1902262000000000000000000000000000000000e86204b2b08ce40bd0aca4af5d2d64b41441fab22945bce18baef1767cc4246b9b8421ec20e4c9b68f8eefc234b7ae81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ce327e7d2cf21417023d00bf4adabc5bc930e4d62b015798ebd46811df9937f6c11586bba314e57167334d88aa535b0000000000000000000000000000000013db73eafffd788d8d5450a03df60d59a5fcdca899a356cce73f5e212c9f79a6e28fb6bf716862e9d4c4643b40b6fdb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006790346c9b7e1231169eef17b152d40d06ede85c54abb87f0e1c314abd97cdd5d80a8d165d7c424e84027ca345b1fcc00000000000000000000000000000000015bf6e108688ea8ea223b6cad7fa3bd49568553b8e791d726e208d3ae91e5a7fec41855897049709ade21e6922419541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f93098d767316846b46bcb0d8b7fe1b8acb2889588a4f4cc100f5dbd5c9c987d4a8c6478ab091d224ac7499033f013b00000000000000000000000000000000046768ea3c2d0ce3a57607f3068a819a451d828833111c90ec8a68ecbcb62e9348b33ff776cfcd10c8a8c1c0c1602f891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012c74a0fb7054e002b8fe4414cbf4d3090cdbc2c1b17bfa52017cac299e2c41749356d6253f1864f290de38427624d5000000000000000000000000000000001570f3184fd3a110385d2b48424626de6af78d9e16c1e471103f7a85bbf4afe7bb92ae51becea5361c75e48e2b687c231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004787f32b74828883fde4c4eb8deca38bb0a9a1dd265188c09fdf75497d992f12d307efaf4da3615c6bf4b06d159e6c20000000000000000000000000000000011611ea2680db7ac587076e3a3b1ce5801619d96d124880619a0b099c844558ead47ba8eeb88bd91bedb40bb98ad5ac91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d889ecbecf320c8ea7437b7d306b66153d764be87dc07fe63c3c201ce80bd8af339d502f38826ef7d181edabf811c150000000000000000000000000000000015f02a803fa9cbd37ef79faaa00de75f395f99ecf5afdaba8ebd6a6e847854ea41b8fb299cec7aebf107baf3ecf2bd341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4b72a9d0ea08048b03aad6bdaa0010e42c29113d64020f913fd46f1ff428ef2d77786a114ea9a6a79cb09ac73428f6000000000000000000000000000000000233609f107eb923e40ad6828324677cb636063c6a443b66c84f47a86515c2d08f1e8d368bb06283a30a6fa40956ae821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197ab30ca98868e39a813c3033050a8e1b9aa45bc3c9f3f404e9e8c53922e3077e4e277a51ef12a516185d6ff7350efe0000000000000000000000000000000006ab36def0305303afa4a21855d26d3e8198a2646efe78f565e4696d4c99ecaaffebe72d6386878f482d02d4c10bf6e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001452ce20b2c6d9a67c7e279edbdecdf84ea7b20f57530405e2407335a0f02cf35c1b53e08a94fbd476dc31323d385ec00000000000000000000000000000000007649c64872da423d5b5332df46974504cbf9564d0087142fc2dcb9ce906a049325c1de9d69dcb0089331b52185f7fe61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022fcb0e5e71d1ea500decc6d7b4612db4243b2c7efd15c71a32360245e5f4aca2c5171afd8dca508443f64cf5d9f833000000000000000000000000000000000a3e2331b29958570b9d10c5e2b2fe6405300a3a312502e0f48f59e37fd5ffda9f6571c7970159a6bdf180db38202b371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000755dfd6e4d959b09c7cdebb385d57512a8fca54e5389be5401454c6c07ba0cb56d4ca8291502382d782707b4720897f0000000000000000000000000000000000e46c51aff857a6ed25202d10f0ca55671b26fe77af792d98091e04b9ea5795927a4c5697876596a7f0388ebc67dba81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de3ae7e3f7829937ad027342500c22b67e56261d0408677ad0679c532cede9b2eec3230ab488a14e1ea50d8aa7bf5c3000000000000000000000000000000000e50ca090f7905f30b04bd234c66e4cbdbc97b117fdbb3c50ae017b3fbbbe03f1aedfa6f5595824cfa9cf657690b86f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039f5eb9da27d3dd2ab039703f5ac8c1e83239169c51e9b8d0902d2549c128a04dd0649c4ef5108fd01505e9667ac4cf000000000000000000000000000000001564609f19306ff8e54523d2a183626793d5bef4e163b62f0c099ad5b92b5a7fd73735035760680049172ffc8726345a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168d9b50e8dacf5ab8f28e181f1c52d5415db0ff312b9f849c749b0b5b9bcf47fde8b81fe55646efbe39f58a73657f9b0000000000000000000000000000000019657fe35c6730948a74e0eee2e820bd3db1d3045e0cebff257ca6f07609980624047c8822e74261df59bbf73ed13aab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b68c6408d5d683baefe2a59815b974fbd7665ab60d14ef051917bd886671ea4235c98837ca1513021913e17033bf14f0000000000000000000000000000000003dd76b2bc86ae90fc18907c16909add5ec0bebfc7399ce26311b4118629d6d76a762b9d8654dc7108238e0426bca7191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082a3aba3ee823ca0eee25cdf5e35ced63b366f298e40db132e8e222ef695d2d1e2c3bfb4e0a119be9533e79a4f4971000000000000000000000000000000000132f474047b8da402e73166fb3369d321c97c1541c276753b4ae0f02b9777d01f273d1b8a9aa3ed868be6d11880b955b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbf62e0c2ece933803404b3aa5764c26a2114eca5922c6f401bec8d5d447da3a3837a1b866f6f27eb04f51f9b2129540000000000000000000000000000000007aa036bdfd298a2bc8881643c7ef1e9243841f5ed023f4e006bffefe0066995783b1a89c6a5a41c781069e94d672d7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ad7027d0714919108bf1de241b4fda12f1fd1108c10810cfd38a79fa8c45c83a5041078e9e20f9579848da66937b5c0000000000000000000000000000000010d261e69d30994b40b185338671b6ae1f797cc136d75ea807bbf82dffb7573726080cf6ad3248b5b5fe202c382ff2941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175411ea735bb9b1387c839793758e0b84ba2e3978616902cc54fcf1dda6b16e3477087f3995da2c8a0bf0a1f69fceb50000000000000000000000000000000003169bf48b6b3d89560cec091a928c3d1fda2281a6dbcd27cca5183939765c09065fca3465e318060b533f73ee844df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001947bdd2a8446fa04f5971c6937be70a02a07bdbab4269afb44e153e79283359e23e96e18080bf433b220a66be65b858000000000000000000000000000000000a2a895cbd02ee0c4581b1886d8fea4279c9a366675d9210d1ef22b1e315cf88fb874a3b20a7dd0a1898e205bcbcda381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f832e090abc2bcd1f54b4130d334531c3e8300fd87db86c9088a61118a25416a4478ffda2a9871b9ac43093e8e6a52500000000000000000000000000000000155552cba13477324160ae1bba296858fd2b4e033b25231dca30961bcd3b2e1f8cf989b8bcda5cc72e4fecb952cfc1bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fc55b5365a3a34267628803bd7fa5287c22673fc1bc7cc50cd43dd9cab4a9d5457fa7e87c1d92c022548e863a50559000000000000000000000000000000000c98348baf672865d20aebb9ff61b5a40c6aa9969ba199206c4b065c71acf550539a8f4374474ad031d75f0d1910f0371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001476d100c2aadc55b6bfd73d7b6e52900d79649c56de2e5e7274d35e93fe44f669496cebf82cceb321e7496e07093cf6000000000000000000000000000000000f80c36442ab26bc3c67d4d8006fdb69b4188bf58ea6142a93de279b0012dd603f46858084af0db531741cacc492568a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b111e8c6426e83ebdc80ff8dfe0f06de5801ec49011af1b0114a8f78e86a5fa7373735a8e6abd46ac9af12b2115aaaa00000000000000000000000000000000045edcc73d85db585bf6522db1007823a63786a23f0365212dbeb81eac584ef770cb7b51582322c35dd2fc51af8e484b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f8c97a2d26f3d96460581147ed13051fbb6fec4f39b57f6a7ff0caa2d170ca125135f999e50ec4e0f79c7cf2e42249000000000000000000000000000000000bfd93b606842a2efbdc0c186726e0810f35889ea42392859e900d8f8e546c207af645249ba07467e0eb94e1067b0aa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005268642e8bdddf219e404a46d9d332cadac1087fa6598cc8d2ef4ad0a519b758a700f66a8dba35554eeda77784237e7000000000000000000000000000000000a56ca04a67af4269c95c0070895e83a63d12c1ae29e116847cc782051c65e46082d7a0a46a8bca4119408bdbb9beba81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061ef51d859710a04194a2efad785d6516b58daeac566ca601b39265ea4d00fc91c502614c26a351eb9b9f2706e70bf70000000000000000000000000000000019551764736d594117593547221338bbc2482d5175fd9dba46e081933fcf83c4d3ffde6e9aec56b6841f95ef9f25d9091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166e4a94e593a5841c5b4ccdb38914e7ed7dfb43331d3b48e2517bf6d64d7197a3d88c9c03f8440c28b1618a795cbc3900000000000000000000000000000000195dd4b627a72ef6a7b7ba800020a4de7d6764885b3e8ea861bd439c2d5654fe1fe7392199d19f6787fe0563ec1b74401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001542c11cbe0088a8799f08e7a9e5ba73ff4cbcac171cc75d530512395f61740964de6a88ec0f822cf7bd3e69c33e7be6000000000000000000000000000000000c0fc1826e12bf454be6abe4d07f52fd8e60f0d09e82e00c3cdca8789ed1d4ba58a3f43844cb2a7a1e4a88f4074569f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015822c53d5345aaf69f8583c60b4a51f64f8f17fd44c23bcddeb64187164f026651ebcfc9200d5755289347c154199b40000000000000000000000000000000010368a2faa902d3b699e27c610dabe8990f1a56e50c42c5f3a2db7412b4ffd5bb06c41ff73aa6d48594294c7cc43d4131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cda3b971d37280c3c7f38b4693321cd1461ac6efff1980d3bbcc26e65c71602fb6c0037bfc06a3a73d68c66cd56d9dc0000000000000000000000000000000002cfd987f64c351689d17bafac4b6a9889a15a12f499cbb067bbc5872c92dcd67e9ad12fd80438dcb667158e0b3911bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169912eeef3d2567812c53f599e08230052a351c926425e156e25a81539ae5f269be12d33a9f9bc02614b87743b877950000000000000000000000000000000011f74a70d2a333e04c4f085f8e452d146a0dfe9143a3fa292a9c9e94253bdedf982878d094c61a24d337980d22e970541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071ee200816a9ab88d57c072f5594c577d373834befde0e8fea72f90b5611cbc0c5e8e2aa6f95c21c0e5a15aa3ad03d5000000000000000000000000000000000e3d2fd9888c7715d5ff4d0c89a1c2aa47d3c7739da8a8d64046bf62653dcd0ee3f6ba3e0a69c15f3823ac061e7627a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a71c5cf839d96f3b4a0e17cd6c7ff95590422d35d14cd7c8df470a053017650e3aabdcafe078f75782873efa332267000000000000000000000000000000000b3d786b512e252ed2741b637539e1dcd9ecb64d94176377c6c8ebf03bb0d29e52b472924cc08898eadc90f3e32efd171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0e3388569c8f9fcb8bfe3b7211483813607a2000169dd22f66950ef3e7f75a22b305be401f8f2e006943e69ba350320000000000000000000000000000000007098d2e3521387e3f38c34f31eb5e05c251b117c0d2f77c9ca24fb47168b0ae108ebda1627d6e32fec484efa7acc1811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fc3a5f5fb16ad292901ae02011fc59d380f5228492c0045098343b80463ed1e524b13d08e65358de9590bcbc150a1c00000000000000000000000000000000019a5a503e3ecdfd1e800d2799287b39001884424ce207bd9340a2beec8337669a55ad6e624a097a06b00c1d5af818601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cde754d4a7c87c55168831a05e9203565a3143f0d4c3d64833bf3c2385be46c60bbd48cb87890f3082fec9d0ee456700000000000000000000000000000000038b5bbb589f96a6b776c3779d3f064ac7628883e5d16995f125e36d58981c2b092c86a7ba79b2af64098c011195a97b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b01416502f217c3c4d3644ef7acd861f5366947a4010aece6d546fe108343b215d1a1474ab1602caf735016b71a7fc000000000000000000000000000000000f8401cbdaf818b64ff9725e975aa47500141f838dc2e4cdb091f481d47570bb31fbdc8058d3ceb4a9b3b6a6d58879ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e5b9b6f2401e9b9b4802891f5fd43f6851e255648f3dbde87a301b30cb792786b0c2e20323455876b52132397f6c570000000000000000000000000000000002710a0180b632b5d69416c24f9bcf83384c260ac269d27cc56b2a7108f6c99dd9ee0c0483a912e128c6fe3526e2f2fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e254a635a5d1e3fa55b22c3e6558cf796d5b4f9e1f1dec966bfc66d6ef769585cef36d4c31c7342d4181c7a579f265000000000000000000000000000000000d3bbd974d2bcdd4f27780d9a54d5ed8850bb1f4d591e89194347b7cbae24a2d1334285371dba9a33d143f48262f29db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cb6ee768b184c3606d7d4abc1dbad76354704ca6e83f7789d8ea4821b64524e1826b12da5320d7274774e0701cfb4e00000000000000000000000000000000099eb18fd5143d4bbbc1d0e94d097e422f06baf2e1e73564eea0ccb94d398bebcda09747c96bd50a34c29e5be9c1f70c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052181c68099d94b0d33015a88961ef166d220b5ef7aacf0d98bcae271538d2de17c415e3dbbfc317ce139ab5aace6180000000000000000000000000000000012f6123a05dfc803c8f6cc982151031436542daeea7d3335f2e0cadc385ded52b056068f1fc98b88a01c2e4a2eb39fed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c4a5828212e6847bca4fd3881f7996515b94dcacb29eb847d6e6661a632a5bfe5090bf42b3671d3224c58669b5f33500000000000000000000000000000000058257c1f6bf61583fbc0fc01731727f7381dde691270048bc5de52fa1fb7f5080d9ab9e36999924ca2e5243478713521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001883f73e2e52cf7e431039f5f85291cd7b5e5e41615aa07b50cef561b4bc225ff266d5127a498d3c2347157d2294607d0000000000000000000000000000000012a2c543a715d02d092c9f7f17c2250b6d3fb486919b870f09e402de795936894f9feb8f5482519fb9e19b8b190036c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b291889174b416c3c36db917dd9bf9c4fc873da699dc0cef731f1b4867c078a462a80688af97e346cd4f0bcc4d704140000000000000000000000000000000019648448888003c975f68e071626c254619dbd469d9b9132223ad3ba9f554741473a6fb9b06fed2137c5d767eb73aaf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011531fb5df9f99b8d2dee28f7943a50ea2b23a565e4b4de411f3c79fc3e39c7451d396e04b58ae817b0eceff31a624a000000000000000000000000000000000013cd3edfca5e8022f2bc356c1ecb96c7350399dcfa49773afb7902c80981591cd2dc34017335270b271dcb90382a7551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a907299a10ad69c95c882eaa4b5c358fdfc8d5b8b7f3f0b269fa45b5f844c18291e12c45591fd352a6ad99a0e44c30000000000000000000000000000000000c75e0e7600387c6d09e4c3e946f9464507ede225a62d2d574d870846ae322d91c3625460e5b598d0780977da5f7bcd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b20aef047d33f49a4fff43a4e05e4769ebeac15d9bdeed6d8a72ff68e1ce46b700d4f40ec436c14bbbbe7c9a166c7d5000000000000000000000000000000000c8a9896731cacea41f503ff2df566ad46e5574c50a14d954b1395d410133d5b985e2e5d1b4c168e1227756bc56910ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9c74d03e48d907b9c2fd3ea1920b4fe8faf2ce8fceef0347353345de346afb54437b524e6857c58df9a41415c8180c0000000000000000000000000000000011c7829b4eea03d5987c109a64e98d96f9d484d774f9dd50329a8a78b5ca4e594aaa1a3b8e78fc830d26e77e1d20042f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ff7238fb961161b04f90a0c411826f7d1e3a1d97f6c1ba6695364a40acf6e38f8c00b7d693e460503bf2b757c3a7d6000000000000000000000000000000001847b1d3706a5f11443a266efc4072b4e96b6bfc337e4bc2b07b6d58d3a619783c8cdf209b39c2be7623f9cc63b5a52b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001272966710902cbbc9f3481a6f2e1cde1f367074dc0365b14c6effceb11c9787a97d08fe4f6626bbe1263b8bc8c70ab600000000000000000000000000000000054be28a84bdf36adbc290fff833794cd5f8d6d15f5de5d1b712e0e0284ad1a31852258bce38df0551493ba8532d08ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010405774a089dff82f88fdaea591782d8d4ee7b85ddedc3cabd5449453fd7ea06a6cb76d73504bf460faa5bb03f2fdd20000000000000000000000000000000011a70f84d3d31b80b4fc0598b38801dc55bdfab5ccbba708bbe35b88e38a23cca6889c283d7bb34ab98e3aade48566141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000060b3957bb1d5e9eda50329fc869452551dbc8cdd4469a78e807f71fb40653f757ce067f07baf88d6063f40573b469b000000000000000000000000000000001118db56f4d94b12e58beb2618c48511885ccf6ea13c0fbee0d9378fb67add5cf042e60cd1a9cc595576d6b48e9d53281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108e5dc80af46215b1471cc48f3b5807c1752217263fa3ce122508b7030824abe440cd3bd556c9d1af8bc996904cbae8000000000000000000000000000000000a16b9686b572c45976251ebcbab0d7683ba4844a36f4ac8636a968992dad7b95ba70c360b297c24701c33118317363c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013824b1127bde34c82c0b32f271e5a57ba7c7309fc04101ffd075e6b5dd6804af9d247277d9e8674872d8fa831b6a9eb0000000000000000000000000000000002dc54fcbeb08ee200236dc577d5b22fa9811f82aff26ee4b3cbc5e97942066a11d8f693f984881673527410828231ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186156bc81d57479ef6e84d23675af126938e935d32dc1b70a226c17030b883ae6d4303399548314424d3e8583c4ee2e0000000000000000000000000000000011361862f0b9c14121146a9e72a9a2db9bc5f01f42928cab6ac8a3940afcd182eda241437560b76ab881a92e1070bbe51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f03a9ca1fc13669063f758d3afa3648329d2d2921baaba447a6ec43ff2ba6708f9b2cc1ccdc2523bb5b328fe63397a00000000000000000000000000000000039689bf993aa66a58a4a58ba58e6be3ceff19e2d4028e0cc475c3f640f78684f3db278877f1023ea0a6ed1a5ae3904c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bce6883364bc0b5ba7e03437bce3b5928e039a0a3b0831be3588b087b4b2b62be5713e940974ec499d165d6a56fdef000000000000000000000000000000000e1916501843a040a43676ec864f52f2a35837d8d6072f8c14460e84f51f36321ad9909d9ff561a9f849d551b094acf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013aa536d13324c4a610749fc9d02f97fe8d792fa29811eab8d8811645c50759664d00ba9cb7ad8c902a0b5a3ae4470e5000000000000000000000000000000000cd9976558d904f7057c3973dccf652a7668bfc12f40564028fedb424c16a02b07c77389bc09ca7c99b2699ef6c618781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009484742695e6bcb724be665f54057bf3949b1a08903f3a3c6360872710c27ff7d6ee2736f9c154e2087b5d5307dc81400000000000000000000000000000000097a41ce90c310ed70558d79e379a41e805db80e49e36b458073fd9ab9fabd620e7a80e08bac98f1cd48a3c8a9cb1eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001493e9cd2d1937f0f724e1f0d4cd180d661d701df181d5252e35dd468d72a47c2808e045cca1d84e0f9b20d6d2a41385000000000000000000000000000000000ac4071f471f8142906a95a065fb908e0531b21d47bec4009e2f308b7e3638663b3decaec27f4d58dc17d5a5d13db1981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd99775bb18975346d696106d8ae2e6be2d3f664af885ba7675dd0cf62294787b98f58013584075f139ccd344d76d950000000000000000000000000000000017aa5bfe3053b23691929db4e3a0350609777da28759c72ea7d76a8d47d09bc7941b58227e4010781ff3e708bd2951df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086a76cb30502c0a86b47ca8f546cd4a9630800725aff1c63a58adeabf03830e98cb0854b939398c5977d734eed1235d0000000000000000000000000000000000102fbf5c964a54b56a05fa6177d8a701774b0eb0dbdef1cd1dd21e8232e862788a674b9fc3101a32cf4724e5c57fb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb3c4383dd0b1a2c66102250ae38cd50921eb23c185b05fdef7dd8d70b03344bac1f2974c3e591dd30d8981c6478ea000000000000000000000000000000000d7012cd35633f815bf367422525dc8ff0ebec6d4d2d3daf53a5c7c4e3bc0c8bdd8157091a04454d978501c47330adad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000223d4e0c500c6087448e4124cd655f9ff8f216aee42f04de64a5f5f94acccc5998a1164b3e50940e8511d95917e958d000000000000000000000000000000000e01d2a2e271db6b445f2f2d3e7998da54fe873f8497fc5c6b42373482978975d133203362b36cb102c0c9cebe5baec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a190ed9c3d8cd5df3a5cb38ccc33061d9ff5d6f711d8047346a3e15f9157d0be394dd01af4a927c7a63fd40430befe00000000000000000000000000000000162de5c3ec84c0b6b4ba15572926d1128f7c459951a84f6611fd27d60af4e5a6341173247e7a67452b67b3f2cbbcd2de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeb43ca9202276f4cf9ddf9937c5c35912c74fcc80144d7331c0f329d857e6fbf7d8cee2ba39a0e43bb19f296eefa330000000000000000000000000000000016b8fbadd675d0484493e5ab3d56acd658bd46b2494a89818ec288368d09559e403aefb06e87877691ae864c556255b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011312304535eef7d614060b81f0d0db188b8036c01bac69d740f9bd50f4610f76b7854f18dddb520ba966fb9afcc94ff000000000000000000000000000000000bc00fa8fbb4b03457869b7b220924a6a1a796093925e11715b0475a5fc95f6cd8271ce92661ea96e0ba2a9ba3cc92611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a276f6f1c32675c8a22fdda5378f7ed99878f9e7a6e4a21a3b077922c5e7428a322535b3864a93c3512a7f958961ef0000000000000000000000000000000015970cdcede3da7d64d784f77195eec0ab25adae3afc6f44eddb21e781938e596a65081103e2ea27de747807b9392d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c4e55f80b849143f11d10ea6a19182a1fbbd3f3dcef3f905c6b38897621729dc42ed9c43818c1499f4616f51490afa000000000000000000000000000000000766d3c11696678d21c48b4a136800e089e2b85339512c468f37288c2b992c3629a9236f032f745745a0354f117abdf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000998d6584973cbf2b4028cb92616f6fb38cf8ef3996d6e43f95ef557958aa207d092c87f9b7d28db4143e0af72d6c6000000000000000000000000000000000077c6d80a5299969f6d523dbea1e98d38a47ae1a11896bae5f03d5257b0bba68b46dc36557f778495f5b3c3933f790de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc2867e5850aa55d572a33356944b998f0316610f3f04aa764dc716f412c533c849bad50576f723bff7b3f758581e31000000000000000000000000000000001600f0c50deaa317171fac835a1562d011f494caa0daa8a77fd222fd0665e0e4c70e6256ac663f2cdb0590de1547438a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c6e53a6dde124ac85fd512c4f116287e1ee3f4ff34ef5f7aa906b2b471a2ada490d32f6180ae0734465e854ff6c72f000000000000000000000000000000000888a64140f58a64d17c5456d3356a708507733d9029dec489cbf0ba4f9b3f5b1767cc177b4d8ffa327bd7f5f14f95191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb6e54e6ab6243e3f7dbaea2f498b25d8d244003d27967891ca276dca6e74459dc11d192db19059daa4259f1386eff900000000000000000000000000000000180274a77406918e1c5a45fa2ba911bdb54d7dc2ee1d7708618004a9f1160afe2e53c0317393d60bbe61fbe8ae0927f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000817ff207ee37999d86144551e6dd4f1fed5df35bf74d167ddc235c3b2b95564e9d7ecd28cf21efe03b34551d26602630000000000000000000000000000000005483c5ae723d85cad4ca753d7fe43e168f2eae4330feea04f63829dd94fd938bd04978757010114584d54c48c3d1d0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7591146cf8cf47f60d456665c39a05a6a3ec2f524711d5a13afcfdd42f5b2793404c3862af760bec0ebb3120d8d41b000000000000000000000000000000000aa5f0f4ed79d9f4334670e1ea471ed2f451791ace43ad2d7cd93e2481198c029b117df9a38dff43af78077da130e7ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000685de9120b79495547fb080d0be29ebdc22b17357162d3e0ca48efb0c6431710e3a2c38d828621b59afebae551e812d000000000000000000000000000000000a7f9cad5fbf615df06c521e0796f40dfbc3b44c1533e1d1120a0c5b15404ced4b9fbeea73085f47a1b8d6c7df760b791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bf02c93f402a62d9d0eabc6c6312a5d1fbe623cd9a1d4b46626d43038f60a35ca60189a5da783ba331bc0ff54ba7ff000000000000000000000000000000000f86cdbd10dc3e6df368cb356b12a359bd08107477cee517a853fd6048685f9afedded341e12fd5b6cce414763550d241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025a1f5418d61dee3762e5077ffdabfa9b7cbdd7c5827c919eb21f11168f4114ab53b1d4384940ab2eda9c1ab82b690700000000000000000000000000000000041d010b3e4d02ce759a010151be38ff3b859920ec44307acd3cf3009d21c216d4c37cca1c0646c99c25b8f394ed2f881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006edb9e75c581b1bc96d45dff4970a63c4c0bd41d1b4c64e3f6a4425eb07375b007fc9612720145b8897bc75e84809410000000000000000000000000000000001c4008e7bad938ae5f68d31d92e9e375ed57af6f1436500cd8ad5423bc92704962660e469d7a4f3982cc3703556c46f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca0dd2b5ea16f5f5a7866d9b401539bed950f94e7aa1174ef6cffa908aaab8759e911af03ba6204b5344352b0c193710000000000000000000000000000000012616f913948aa5ed02fcf8695f52d521960f1e0cb8591eb433d92107da694f0a04e0aae6e454c0d7020032b5ab2a5271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001174a60a3edfcb5e8b5e3186933bb6ddef4824867a04213852c5356218b4c1f7d726b3f3327cef1cba96d77e9f8476150000000000000000000000000000000012f67a54c1da7682d8d2c1f4d60d9ac2bc7a000410b7b690b037079acc6b4479b4fc8e2812f84b93242808d2bc08cea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a927935f97915e29442593382e8dcf998edee6dc609919de5284490e3d7df162144029b8cfe047c72a87b221fdf050600000000000000000000000000000000124e08edfcbafbbc93d8971d2c472770a116b4ebacac4e945d86b71e16bbbdb0132f79fb7f6c382561931785390cfbb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c69e897a15d4f9a9784cb8499838196e288f778fdaa457b3579ba0e2d8baacbd2a0b2667aca7afa6d1ed682533ff040000000000000000000000000000000006822aac2411ec055ced53dd23cbe1378fc92667afd2807e0a082fb4aff985b669e554cf6b655b078c0825c894660e241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078a372be72701f54e582949ebe73afa1a82a04f6effc85a57778cfcc782d3ff18ddaef402bb80aadc1c0d99a721bcbf00000000000000000000000000000000049b1a25fa6e8e601afccd0b8c35f9d79db58c735a04159197cec6a8a02107a7e0229c0dafc492548a1fd75236eca75b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9be4a858ec5d7e9f4b92572462764c0f10b8397cabba130ae8e56561e43b02359dc3ea8edd3c6a3afbba76053c06d400000000000000000000000000000000134189ef2d71caaf586582578b4d8dae20cd6200da08f0f5b9481f7f0e791ee8425757c09eed2408d5d3c8105c8310451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae0e9620f54cf764b92b2cd22e8c5d10b81713c2725dfb894e5950557d20de601c4ff6756bb5cc3d699e3d9b85792bf000000000000000000000000000000000c1b6a7816620cedeb8139904edffeba7b64d095e070c3e7edf4d186fdc1cc76c47ba52fad82f1e71e9f12db26fe49fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ed9b17499b541e03ed812fb1e4b7a2fc15bc5b4039a0d63c7305b246ef5b6cf1b1e209bdc9224584b6eb744a83809f0000000000000000000000000000000012a0d5232352a17eb8ce8058d363248d31285c0509b517f62f3bc108467552a01b16bc9d5494c0c5377567f7a665b6cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176ac42ed79fcc6815cec1924432922c22fe9f139f03e1723cf7cca901bd8e969db53abc9eb8a8c1ab066e67793d19e10000000000000000000000000000000016deeaab18548d983eb86b8cf5cc505da6e10ff5df8b50a9e271d008ac501365c6b2d676884a80980c4166920adb08971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044631185d7e9f98365c23fd3d3f47d2451bac728d15d8b3682c2824aa2175ef2429050e9e28ebbd15f9765a3cb5f87c0000000000000000000000000000000019cb56e21071d2b790872427cadfddb4bb277c6101c8b078632fc287b942343ddf38d2b37517d8815d9e74464490485d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b63726c19bf7d491af70391e09d46332a4aae678705b2adfb59e385c5cb0da27c2ee72d9df2dc52fa2a99485f0e09c100000000000000000000000000000000030da4dd6963929f022345d4e71fe820d34c6c0afdfac4382d7d6f94439747371a6286dc444c048a09a847af91c1e7bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c3da40a3ea8aca870a0b23b1f36205b7b617e5deab0549b781ecaa1433bd9ffb9260a80f210d6274eed78fd68804e00000000000000000000000000000000012581febaabd7e366db2cf94384031bf9648de37dee83693f8e9af60cff77cfc47ab5afcac8b1841dbcf95d148b90e2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e629602f9593a5097e7a6e87bd8849d48d7535490749f83d2b31723174ac2d177c8b192942ac9981d4b1d4fcaa30840000000000000000000000000000000003a7cbd60929d98293bdb3f80e0dd1be44249bd96ace544c8657c7d19a006b63180aeb8eff392dfa3f1cc648edb0f4111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc1d7474720cd58e21bd298e22ca44b913738bf8466ef968f8d1bbf69a6b2075d40d880efc343d16fe1580b4a0185a80000000000000000000000000000000002f329395affc28a66be2f03a8e5bfb9ba7b1a3b6b2153eb91aeb09ad039b3a3805d0ec8b85d75a521da20007cdd5d311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c947a6c6efd37b7ad92bd27b2362cc78d9ed19308945e32670ed02282ee586af30d6219a73847911bc0c5535daf1db8000000000000000000000000000000000340e074b08e57bc8ce48ac1a55cf525c4f5bd47a0ab4f521751b6d0c1bab207df57e54d33a333b2b0ad2a736fa12a281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000c126926259c3e13d7d2d146daaa0bfce87b5100710a0d694411ce87a0690f1b2c1eee5ac92895f01198189e71bbd1000000000000000000000000000000000ce520d7deaf014dc9cec02499a872e6a1bfb02b342e0b50989d51d09715fbaeb5d805305c5732bd317104d81dfeb77d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093e1631ae401bb528f1985febb8dfd56360475aa6d842a6a8f8315b2da0f6b0446c9da7bcdf9f952a964e70f0d9c36e0000000000000000000000000000000014d4d5217bc3f841e1ef1fa36b64700bdf89b1ce011315e14ef70aa7cd5f9f72cd4b6e089bcbb1db5bfb99c3c54d90d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b16129bcc4be85f9c15320c70dbadf395b98de5712b9215e7b16e9d78936c112a462384ef53030a4935249cd4d4d7d000000000000000000000000000000001427211eb2c65bef186f7fad027ff7bee0bfb47b06b54c1b8a6cb6e38d5d7068c60cffc7cc1f5465d80eabf0fc6a796b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017867abd83eddc1e282c55ed3f32b58d1f85eeba59d12acce51ad5d3a07794b129a0ed52038353fe8a22804997e682ed0000000000000000000000000000000007031030f83f95e52a64a364095a1bde19c0fe1a7a55912941413e0628748f3dad2889f6b518b91b85eb5df1797d6b891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012287fbeb7e65b170cc1eb62d7f0b617965623ac2e2e7a25e10609a6bec0ca6118679d451e6d42ad3078ac576e39674d0000000000000000000000000000000008a11d1ba3d3e030d529e7053ebfaba155a4723123697c1a6eede20264008d7f79892a147b69cef34847228d81c3bd1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c91c7c6a81650d1c3eaadf1034fdd3d364cbc5780a99194623d05903d906bacceec091bd142d0a986f2e4dd25710ddc0000000000000000000000000000000001a5e45ef9b2ab62e39035ae9c262d79edf840cbdb149616f15c2f57647eab6cebf6946ed4159f95b12e5dfa6b04312c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c71c4663fdc5c06dcf0938869f6e33bd489613ec89bf26e8280496b23a703890bcfb510ccd2ff3f7e9cd00d7ea8e41000000000000000000000000000000000dbba6ee6d63b1c2b8ef08499ef24424612a49a5ec72148c7bf8ef0bf020cec6650cc21420b9a0a8e88a52e57b0bc5a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dcef986e2fe959522337b62a90424b84fa806dda9253632bf87e20a03d507ec82e731ff36d3280ea3fd0fb258031b9000000000000000000000000000000000cc6b5d543f20d9f558006e97748b4bdea619263dba3e502ab17d71a836b42d6de24e3ac4d3e45c8a6977e5ed7d2ba501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9b2046e275597cb45d9d780d77a1107bbe64995ebdb125ef6fbc05b2dfdf776f93ce2691cb41a35c943164b23b5690000000000000000000000000000000011d0f56496878b6280996e2436440782c71665d33bafb3d826040aefcca2c2d065b9fe46c44f93474275fac02071496d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018eabb273bf7f868bcc52623cfc480fe794a8a39fa8f3b4d86e8185ad0cf13af669d2a852686159beaa4c9a8fffb6ba000000000000000000000000000000000d3896701ce5354f859e07b5a8273b34bc5f3d8c17390ad2509db8241dd7898528ec5c2c915497daf046ae8644fa13471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000735fe9c2c56a75e904904763faf30def907228bfda9f68eca8084369e4e4151c3563085c52ad454921e8e686e91edf7000000000000000000000000000000000c595df91cae71b38345fd0e0554c0dbfc0470737edeeea613c11486155d7f422054d024f8d34adc33866666d9545ae21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ccb57a30b0463e0395c38c756d6790a00c9b02087a76c4a21c5f819262d2eef026cff7d6e7a43b2c8e0c7e73015ce800000000000000000000000000000000114602f60b9d0bff0134a9d5c6c8e18365364207f838e0caaf41b070f5a9c3f50bd2b930314cbe9dc75069986e6307f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea2e01cfe19b683728793d86113391ba236b3f5f8a26d1a87be7c262fcb4591d8fe0c79c0bd03c0f0c3f596c70880a80000000000000000000000000000000003992bd04e9b5967a289f6c7673ff209018aa1ed2188b5da54c5a1ff2ae5e856112dda2d456404cc866fdb92dd8c49c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9099f8ca2dabfcde480a87d922a9e5e374241177e90f82d55be0cfa1fa18b69050c9c38f8d8bed3e491946937c46f90000000000000000000000000000000018a2b379c6bdc34b8c9864e686a8e16a0222db7f8e1f68638a627dc00c09ce0d01ee8e4eda121b1a043d8f3a5372aeac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de89f14e969e81c34b349e82c25b34753438d3de9f49dc551fe542eb50dba907fcc9f8941be452206f23ebbbd640f08000000000000000000000000000000000af63a1ec01796ae3775dd6cd8937293bad0588faa690e707d26706bff4540867ad80fdf04a89f7dbb9c2184134e9e5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c64b803d391a4c6457b55894be653be668b4dd3094231d36c08d393c9e3b575e59000170f4b7147d6a337392606ac2000000000000000000000000000000000639fa72b9a1cff78fdd3145945e8a6eeeac9e369119d366d1014f8e5839536278f8521f82029136dc4dcefe827596c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3e303652331c8e196ca0ab7df3aef8637cb77209d145140b575d81f945cbedefabafe6e89c897caa5b4d5ea4b8256b0000000000000000000000000000000015c592e43e21f6866a3e1b1f76b9279dbf33b4bc48c1e38d051e18c15aedc4e892f926cc62f3d763567db9010ee6a2341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ffb1efb5f6283a1d0e1ec4c396076fe0f6e36706a2ebce5a14b2994c46bb5f398f15a793d11c4228b0f32fb1fbd021000000000000000000000000000000001733609f21f78debe7c3d26185fa6eb4db7424b6dc79b3805e3ae5f377c087a9420bf1f93382fc165d3cad7fe158c0961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069bdac1b77d25211546e9b2693c851d66ead7307cd12724a22721c9860d7005e42f4ee44cd52edb107836489a2965bc000000000000000000000000000000000ab790d61fd02299d0f06926b95a4a5c26326a28012fcb141d24a4c114e9276eab60084418e95184314d324d15b284401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000210b6dfccab23641922ac03f1cd1773391a9d12cddc8f14cd1f5a172b6206f7885784e2af99df9323714d6ff3f4483d0000000000000000000000000000000009b76b46a35ae4090e0ee2b5c631bbfd815efb5caf95707eabfaa35299819509c4803e371dbc1c3df633903efac630fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2cc0c0022c9f49ed62d6e20ea3f4f0d62b58cc089d08a7835d3fa3aa945860d6cbb1267558f8e43cc08caa5970f36300000000000000000000000000000000086ced2dc798345e61546d7af83d735d3f9b3475211e458acbdf673198c555967726e87ae425fabff13eef7bf3fc8fc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173a6e14c6901cda808d0d439251518b7bbdae9d88e67d695d793e396574b76f48606a61b14930aa3ffe89a2d96bf6bf000000000000000000000000000000001253eedc01cacea5735ee0acf74039f72a3f7003e30fb1b57ee1374f22f4bacdc53f24668fe39c6fd3dd3b2094bf0df81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018eea4f3a33f6ddb1a3db17728d069af3c8b57fc8fe8f8a6af75a2d0492a4bdcd629a02a7341376c94a49549abed25bb000000000000000000000000000000000c8e685b16b55efc3a5d7612cb61600d660bf6c61922678621822642a6472797607289f0b49ba2362f34e31e298f71281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b73ad0d82fa06a1589ef7d1e2c8113a3c046acb403d34638ade0ed070d5a70488df9cc7cd3f01172a88b1975216d3430000000000000000000000000000000008a0a0743e7cb4a32897c9bab96f09b201d38cdfbdd2cb8ef738cbe34ba54dc1fe7be8b5d9a95187705780455bbaf1fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141a3b4a5fee89cbad259aab46a1c0569a1a0a553692e877e73418eed9294a968d15ffcdbee6bc54dcdbc71f9a9b794f00000000000000000000000000000000080f3e1db0af9ae7e7d426fc5dcdcfafa708cf83f454feed320c1f9ead4f2c380a98ef09198153d88397b6fb5e937d851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e321b654e27c5434e499573fa0b0319409b6d24b9273d0d01e82f946c7736bf4c919bfbcf84f4d74c8d3a04eb800ce7000000000000000000000000000000000d6ef2dfaeaa917770bdbbcfe57446bccb1023721797ecad6cb74a87f1c2697e3697510ddae7a8911bbccb33efbe65811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000766aa5fb6457a99413aee1d2ff3d3953d3cdfedbd6d567097e6dee2a53609c7a3d1e1f5f4cf4244e3e7fd9c906736bf0000000000000000000000000000000015a7ee941771fd3fe9d41bb1ebfa8a3fc0024e04260356f69da48859760c7a386624f43987727c14b58874a97e4737011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000574218c71dae1b8d06256eaf8179dc57aca34ba1a9d19bdcc6d3ed6eda6492908c68233b358cc821e46c8bae5e77d360000000000000000000000000000000019566eb176cbcc5182772f8af4e7ed060f4fe426f1708c8f1dd85fe220f29c853f99de0ce316ee0bceedf80d3a15d4ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d539129ae955a56f57335eeba423c810da23cef10e0a0529fcec04af7722085b83e3801b139e7222d593110c24daf36000000000000000000000000000000001051d25895a515621f047cd12d09f34fb4c617c01f169af27e90645ffd02a6f355964f02498ff336f0aadb3d7fc1b41c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cddb68e6dc68216dd18a139b9784b9eee498aa1c7e346d6600a2f31267a498142268354c02e5b29eed8db583dc4154000000000000000000000000000000001239d4b2cefe83747c11a0e8cdaf091d0a09e0065b97decaba824fd77c6f84d4c24d0cb919d2343d3486929d6b4e5df61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d2b9d9eae13ff4c0f27ee18819e7537b59d6bd78aceae13729bcd9270f9204163a45f389210be3643ca8ff0fa7ebcb0000000000000000000000000000000010f0d79e1d49b9c7fed7f7ff5b2cbfaf9b4b7e98cea3571083f6afdcb23393212d0b195a7e9eaf2a873d33dbff3d1a201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ce6acdc8248bcb148039ca8cc08780795cc493b29ec43820b02cb73c6775ccda6b9ffd4c6cb90c962f33d9956a679300000000000000000000000000000000088f86cfaca7d37e36553bcb6cc7d9bf75867f24056c48cba84715f7134d3144c2bd6c5007a8d0e5399ebdf2d25399e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166ca0a341e5acb98b70a0e0663737cdf67621802cc8386d7d03164c60a7e4c984f84be1c0db4279dd80df84bd56f599000000000000000000000000000000000130927b883391f40d4f605ffad512d5a172b9ed7b638ccddaa73f33ee3a9e83780003336b88e3d43cd098acbb7cd3711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000800be9cb28730a625f8d1483603de5fa31cb3cc3a6bfc3a4a2f9b08bf204e2af8fb31218911b73584016844c2420d39000000000000000000000000000000000c41d1d3d8a814e0aec48684a5d8d51d394960992cdddf43971c4e1781ed690af8e40b253c6bd8f9d8dadbfb8dd38ee41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d3e726846a89d38d2a9d4fd934843da13075e70bb0e9d2c19a0574b224de3701abeba58fb6f28e95968c1f86d4e5c6000000000000000000000000000000000dd8adef15b50a576901f312179dfee26fbc2203b9f4f6f71996fddb13f9ef82c87775f16c41826b72dba701a84827b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000959ec02b5e5335a0d9d981aa87c9693cc0e545d3229cf43e070963a2744468eef7e28d34e732b8c7f5ad4af943e3206000000000000000000000000000000001772729f3ef9e07c4ddf99e17f122fd3f0aa398356cb3561ad962b2ab6d31bde2617a7b7e78ee11ad59f2c4388f23cdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072e87cc0deee35949607c0a9bd0ee755a201eac9875e78c13f34c6e5f0a2e33890743e8e1451a03bed440436ec573690000000000000000000000000000000013c8590094d369fc3512273dc36556998fba9b203d1d2110be7564589cc1bd19a5940c93aa187e980cb8050a9867736e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da0ff079992e8a32739a60928cbeab7afad84047b173cd5bedc9a0285f0d1d2b404b135f11d68de35ca80c57fb360460000000000000000000000000000000015e61e00421b13f4f91973c308d9158f3c0d2442f00d3576acf9e42b26568d47f5aab442ca94dffcd136778cf3af13061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059d8ff3785a22535e251269fa41602e6b8f6a4dec9187fe15743f841a60481b25ad448084ee4a15eca2dbdfdf6acce600000000000000000000000000000000157b7e92bafe3203a317ee63fa8cf3607414c797e63c41a155a8698399a5e4f1024af4f53f7a74286804f88d478961241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019736c39d7edcdab5df31725155aed52bf90f51e4d7ff5f931a68246a74f1fb24d287243fe3a9148a291e23a68bbc464000000000000000000000000000000000207f3ae9e20a5a9790443fcd503bff1ed947df4624bffebb4eaa1268e1565a96c7d29d1f22c2f654dffb68463a63e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad47bab9eb5b8d9093c249ff7e825ca054778524c1356d9ed13f6fde88de012aa120719b14685dc870c6c3adbc2189f000000000000000000000000000000000f0116a3cd42c55a1c208dd5056e32b91183dc19cb09b6b91aff749604dcc5470ba741edbe677df8c39fc2cabc1cd5a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b25b85607df57827358670fa948ded04020d889ff094533a2e490098ecffd6a6aeda10145557c20e6950d338f7df2600000000000000000000000000000000049eee265b0c90a7db6688df2a1312c1fae3de19437d0314877d81693fb72c0394cc0e1419a77f3f9e5a96aeff1cd3421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b7daf6ddff1fcf4c8f81111a1ab5be32f7d5618e9c347b29794fb899b5fc2fa6e693fd545f08f4b04483598876a0d2000000000000000000000000000000000ba1cf2f8c76e90d5420d2bc5468a65a6f518b906208c54af9a2a27eba945f650368d1446befdbab2958ab918fb95a9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b78cc0560c92bd97cf8d8a40b84caa626864317b970118a13f5516c8ea5dd2b75b15104de6d93e693e8e2b889dfa4ae000000000000000000000000000000000d44c529592561cc6e3056d4fd2d8d0e678559c2eea1bb66caaeed70833dc59faa4fed40ccbbae40dc518e477168e0af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013496b9d2ed109e211c04a70d9f3b50d71767087bdc8362641b555685a5671db1427e31d5c7d68690fd89d9e07ac51a800000000000000000000000000000000166a9acd043cf2dc69d9d416994105d81d357ffe06059d514cbf25d30b2a0729e65ef0061846f131144f8ececae4e8d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181802859d2b59d94dd8b4b1005c474ad8ec25931fef394fcdf35c8355d5c619ef63ae77cbddb52188a0f8b7dda81a4d000000000000000000000000000000000c52da301d030c2ace3f9e6fbc4731992f6cd20a21f006f4e7795b5fb01e2041084d84a108606b4c202a06135ffeb22b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165efdeca3e7321bf5624f84096b952237594564ebc7d07b146cad0249a03563ac269854b584208806c16ab4e7a0d478000000000000000000000000000000000ad08578ee635820578fc23e628d9f556602410ac69f9f444e47ad8eab3c1930b25fbaefdae214ec1e73ccc15f467f511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea3f94377b7db8cdc9c07a6242e46d37df61b3f93a83c4d7153a214c1b1ccbd37e7b15676da27ab2821e45405ca37b8000000000000000000000000000000001639cfb8fd5a199bc39be5992890e249ff0efb686f91843690dd66c27ee3f9edcbee26957b1a69bcca501a91ff7706461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062960c583ead123b4923f780332deb7ba23754ed858fe67686ecba37dc4a449bc234ae37cf90790bc58af88893ef2780000000000000000000000000000000007ecf5d84483887d6389bbf1a326a9581721d8c77badd692055eb5e3840e331ddbcead90efdcee4991437e3ee541d8a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e12d3d046565f3b6d5036082ba586f6e1d648e0fff76e3c5e8b2e348234f9e3d60e15a86c27e04997812e6d50bfa040000000000000000000000000000000009c44527d13880c1f15f2c961c3508d0d5bd598f345c96a10de41e7c4f44dffcacb702750cdca15d5aeef2ae449611531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001606f0f3d050fa67a69812591c236cb6a3ee0fe0e5947e92176554b8b495921c638740fd397522a88a8a768e64a4af19000000000000000000000000000000001227c2abe891712f4a542638b9214e0b662c151c359e95fcec56e7d284adb7ef622bd33c4afaf74eaf575c2e90d139f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c4b9fabfb4fd9728d7030bad50b637fa0c1ba25592c3398bddbc28ab5c05c17cba0759c693ae3ea0ff35b5f1e9a217000000000000000000000000000000000bb1393d0bd54135053797faf8389dcfdd2a03002cb8e8db1fcaaf0eb58a831292cbf12cdcc53b903657cca771c67f291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b85adef5e911bd7e261ab581341c7f5c44aca9a9b13b7fe15530b5dbd068f2b23fe3f1c03deb7f0ecbee5c4908abb56000000000000000000000000000000000cb84c4ee07b745ca74bb4cef45517864074a8a0f674fa56b76b1f90d0b26a5ad2c966c55ad4df043b7d2094eb6e2aeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001694ca1c011322e914a531d250390cc6b7a64a54741503ff4dcd65ef2b35b13969836d48b489ec296c888e09c2d1c523000000000000000000000000000000001977c69eee7e6a8ac94166acc5e0a6cb3d09b8e83eea1c62fde07ca5eb21365f7a1386a2c4b2dde5144b4ca820b47f121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170c67bd68b52f63e92dca20cf11bd5c36efde65c73d1910526c686f620aa7f9803ae8aafcd0a2fcba8b1b843c461d6e000000000000000000000000000000000dc54dd4c1f667b2aa723f5cc89e2b2a4f3bbe20d1523784b2aa69307223974e267250d901a1a737795bcf01b49916761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3702f67163b324914a469ec5ae6ef073022613fd8e19618489df4f4c3b2c338a834950ea8054a2397448f62ec7c9f20000000000000000000000000000000012f2eff7425ab8baebe628b97e5391ae19bb163440886c0c192864218953e1ee22e586029cef53bfd44dd43b00a184791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acec7e6492ef1d2dd309d011a8c011f0d4a137e9c859d066e490cd2d5d07e4d6074cb36187ecc7ba43b6c8e11a6d6ec000000000000000000000000000000000521d6c2a4c8ea71dda1e67d2bd73b82df04d3651bb790dd412db04b9c716044f7aa3fffc137bb36e489a201c285c22f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010421799b261063e1a1bd13a1ecc5d7f76b0b46a5a15d0a6a85cf89764434c5526f9d2e34921e68a5df9419fc3d00c6d00000000000000000000000000000000049bf5795bc0437c4bc44e9c20e95a4fc22877932a7753386703f5cf7df049eb6d2b75797914d75bcea598362251aecb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d232879afb5e6c03f64d055440447973d0e548ec4dcb0ed51121a45907e806607dd4c9ccfcf9f175cfea96dd149e91d0000000000000000000000000000000013db5533852c4656db4962319025fc4cefce662a34d0ccbfde635b3c53962a702c013e0d3bc3678eb6a261fefb5c81711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0691a1dd40b83b171dadb6dc2246601bdac2a2d9e0ec40e14e47ae673c4bfe461acc3c19db079030906241a1066d600000000000000000000000000000000009d82218ba2e0fa8a79acf70ead7ef4583fcfb2e7313e2285180927fdf48510ed44787f9276fb490ca1c16b0ee15b0021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e98868651f4ac5e573241eab717fc7d2aa54d2dbe297a8a41d676453092851f9f4bfab1e60f0e119479f14cf226199000000000000000000000000000000000b8e13e01a24dc52f259fc14cc5ca20f9d74aa93630d7728a2f458dd401ab2f33b52a60e6efd131b0d749eb3076154211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000463f32d6aeb56a8f8fc301fe574330810d97986915f81fcb44d14c511a916c0a86faec3c310ce15cc2faa55447e344900000000000000000000000000000000135e7b493d90c12d0c5d17824457a2ef58eb4710f3e0f02b422344f6549514404a06795332335b681b5c56cca6ac42ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140ee924a8f6a385bb311f0ec93809fcb2b1aba509c6beabcb05d7c1053fca0da389dbce79d20d807f34292b147ea96400000000000000000000000000000000077034530ca75083c490cd22c86d35c562e19773dd2eb3107a4fe7cbdac83161eaabb46c222298800b3b6a3cb9e984c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c12b54bbef6b2f664891fc51d4aacb4247e286b42273dca5860d72216b5208942d80bf3b3b28afced371394a547965d0000000000000000000000000000000006abe2a5f3b47223c52be7b27137f3ad4cc9064c871571b604ceada0c1d436079980b1500c6e4720bd18a4ef225bfab31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000916f8939af1b71cdf7b8befebeebe6dcefad363608c2cabeab097c75d1b5e273fae89e8af02f93fd9444cae0ac050c4000000000000000000000000000000000eddf90a131665ddcb25191154672f6beb0f7e8c786d741a10193a2f145b9646d91ed6b0133b330242d99b62bd006feb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000671dbd9ca01b25370cf67f6d5a767fafe2cfd419338d3b8fdace000541cce4d33644f7bc48508855fff27955962cf7d0000000000000000000000000000000009f3586f44655fb07b47556a435ba9d60f610a11a0f8415a1d7cf55583189a967af4d9d0cc133cfd821a806ac5efd5e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a7aa75fdf91e406c329fe61452ea9b5e2cb0eb505348275bbee2c1cc5398da2c0f5fc7b59f810050d0dafce6c30c3400000000000000000000000000000000043837c433a512e09f2e7d46ee03118c9f843994862c9bc8b10cf9a9bb1da6de38f726316e4c586910d77376ec449e301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139b6b621f6b5a506ab1b8354dc2200308eeeb4f84f2d94ec18a2e6ea30a3b2dda92e82184f1965b553f21a960360be40000000000000000000000000000000017698a432577048872d902d33a4cec34804b78b24e5db4012a0240c3e1e21d5ecd2231c38674e8969a2e433bf07df9491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000225f58d444f2bfdf5a288a69733bd0ee96c554a70e337261a659b795794c545d67031ffaf5f506dbda9675781dbf6a4000000000000000000000000000000000a6a9582e3efca1974ecab412d4865566b1bdd24e191089fa45f40e21960074336bcd1d7225906a1cfc414ae4ab131fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010c8da7727a0f32584747a94475738cb0038fc102975b2b4aad40714f4024ed90c3b57557576ce0df744b15cf1ecf160000000000000000000000000000000004c41fc346d8454f0572105d6798882a84d5c8df45eda32e6d5a1373a2857e57afd5c80fcb16e07643f04940abe317c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014707fc1f89793524b30ce62c6709928ee2b60288fc6aad5ae37499a5b970deaf3bd00315991d15d6a7b8a0a0225e29c00000000000000000000000000000000186cb3282e7bd62f0a5807a4c4ffe407d287fa8b759f16bfca4451961fa2cb522f5f12e3bc531645ee681c2f57c5a9f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015906b92e0e2927273ab3eee783f6a4a924fedcfde0b16f7ec41faf0ecb13d06235ccea81ea8a6a5b6a5514e21093a670000000000000000000000000000000010be2dc06b55c1a1c7fca4e22cdd9729f59943c95dd2502886687986da40de3445c7f96d34ef6c9355e6ac456df1b1f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5a858bea3409c9bb0683ddfc0600d2db8b667f80a63e26d3730e12e677eeebe5f6b42fd3a3bcee45f8fd150ff646000000000000000000000000000000000014f73254badd7abae6784dce2ffe0462c8072605cd98e0c7a3f9aa78e5c99f846eede8e7dc4db8165463344e96537b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000edc3ded52d30cd7d9519ba5f990efbfafdde06e51f552d6e0653b2a9c95845868cc5cb4eeb0356fdc74a9c4657656270000000000000000000000000000000018f0aef7f0e6c1083f58822fddea79fa72b7cdc9b736b948e97180d40f0aba7028801bb69003ec7b3e5b8547c3444e8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c36332c65b1508ab2580dd203e7cba30293d6faa722693447e40a312b2d59c6f94b15aa83ab59d929b45c3bb58e8d3000000000000000000000000000000001549cc875a163c1c03f5285b1383582958f937cbe1881615c5e501970c06092436794eaabd1e4352d77302c6fba5c8821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ea466365f39ad591abf5a151a43cf848173a6fa2a00ae7d6a537dd5b97c9fef62f1df820c897d9c77f3e7f9a727276000000000000000000000000000000000eacf3ad07d54eec65c300cfb66bf700c43d0cec11922fcad82e4f7e249de29e08d1dde9709269cc5e1301c188b291e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000247937f2c8bd3c1d6f7ba1b168d1e0a39ffec2ccffe400de3f113076116e885006af62aedad8747ddcb79e8d8a5cf1b000000000000000000000000000000001914103df2d6b2526d4bc604267281cb7a2260b447d51082431d880398c1bbcf2ed5c9463a5112064f63eef5df85d7311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005381796a10e86bc6cd20ad90de53be27dbe025262ec7b4531001aaab2c65f03368eb89e5012d8f1de063cc65f7990c100000000000000000000000000000000012a546e0e18af28229ffd401dcbd6aac4c59b6979acf270b498f1e5793bc23c1a6bc1e2d0ad40a3e78ef4f4abe1da2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ee39430e44d3a9b27d35a71ae4df9c3693d59e019a970517f7f29f1a7a2204ac485f859cf544b3371be80cd7fee4ce0000000000000000000000000000000015ccff4228a2c8039a6b0ad3f2e867140ea810695ae5569b39d35205b5cbe66afadb72eb3e955ca4123aeb778388a49d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082898bbcf99b9a7cb5e5c36c83c821140494ed81477ab0c841f0aca2462170f13f191eed866460b2e0b0d6d6f4190070000000000000000000000000000000000e9e9261220d3a750221dfb52f49a97ac10371847a6057edd4ceb35b395b7f4bd321ab3f4ba174f19ab9a6b6f404ae61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001533fb5370050c488e5fa37ee750d3d72f6bc25119f93111f23ba4237a0bbb470fdf6fad2cde62deaf3242f8a7eb559e00000000000000000000000000000000113d5d632beb247c117666027d7fc5383e7d6793848c6b7009d62051f140ed84f6ae8f8323edfb9f789ee61be3d1fea91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c65f8f669558acc176e1cda87ecc9e30c0ff4bdc0f974231ae9bf2942c8f1ec068db6d0656a2e071fd9e3df91f869f000000000000000000000000000000000c8b94cc801be6ddf9f984291c23e01152b8354133fb7b6a876c564b37f9dcc2c9964d09ff58a3966dec741dc6c4d1d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195521f1c8cc6489b1459bcb7bad5c5e7e63bc7085d7a9366def84dba07111a33b409c7ff29fe591c17b8b58d2f060cd000000000000000000000000000000000e7acffc461b874fae3cc5ec42545c18831be14229e7ba891b6457a484a8ea843fe4f66121c17d1cc2d8fca5af04c5491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081ece4bcab5ffb439d5441a91bda095a45c1fc7aea97b7a5ba41fe03481dea9c366f39ad9192967123e04a1dde6ee59000000000000000000000000000000000ede071bb318f4d36e562bd3c38b7849a3bb59e3e06af55f77257ebc34a14547efb8a4788971553b0d62cbd7953d2db61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006dbc1750daac84f5359d5aa452293902238da269cb207c353ba8eae7cfdadb1a73e127e3bc5c7e038e74d70a1027982000000000000000000000000000000000ff13ef919373a6ab51dee4d523e8ca2cebf62f55de7196540867390c796b92ac45cbda716d0e6e49f70403fbfc1671f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ded8ef5bfc2bf0e4877ea2f485e6451c22504f473a64c2c1ef223a91b4b64cd4d744856a3ec0dea209791a7f72e4a5000000000000000000000000000000000bd4aa9bd580d7b9243ac324f5ca1317e209512779c64b2357635a581e7aa7e46ac09452df4dfe50475ffdb5f8e185731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028349cc8226cfddc4c4893e1fd2e21e65e7fd90dafefd73de447c138c3f3047788aa7ce70a9d8c667134559e3454787000000000000000000000000000000000a1938a7e55e54d4e4d1569ee92482dfca18070116edcfb0cb1d347ff827d6316a50e2ce81ff6d078cdd282ba2d1221f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000005b8829e7072e0b9d7bc195f665bcdfa4e0206b21c8a6084ba98293398267a62829a7366c9fdffc96b4f647b36b40d00000000000000000000000000000000086229ce7ea618ab851aed9b39fc51bc286102255d32e9c1275ffba916945d2bf3b3dfccd7b08e180ca567e22143fb341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fdec5f605990fff4f24b9dc91920de637d2d1a6c1510923c1996dc6a07d255cb70e961c6c29453604aca7240f5b3230000000000000000000000000000000013757a0d6d54db50d7e525d3b9ad4efc09209c8ca3f7e713270ac05a6588d11a916638aab61fa89464c2097b800310bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061f2d89204e10b09c7de7bca0f1be0f0cc3036e9d719499e5936d1aca56b7282a0e7777139824b22c6305fa4bfde5e10000000000000000000000000000000018919fe861a16aa91eedfe659f89a6dbcdc18d72278906c357e2d2865c45ecd54fdd7978d6b5b65c901cc22e6aa286021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080b843e9b740e246f616d2022a6eaf615e1f2f728450a61f27e5977a5570e18f5bc1a758221356c681f352fc6105c61000000000000000000000000000000000493fb5fea3613d37dca1a060d4399f19be49807a32bc22843ac6ff3cd88db9c2e532ed51d2c98c4bd344248405c262e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8a0e714748df41fd3bfe287ba2151fe0054fee9a21adb9817b31c096b85132f5601c0d891dc46ea1037c65ac64dca90000000000000000000000000000000005045be4fb6798807d73bddc998e576ee364ac0a2ab5df7aea019fdf15d413fe7853ccbc576f875df66bd06fe1e7bb6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d3e4fb948a2cfd0c563ed78d1062688bb13f168b895f8b6e5c6aeeee7e0fb7dad0a5ddd36fb06614ac295fe0ae7fa2000000000000000000000000000000000617903758b9173c8072593a1606844d20af9791f8deb4233d16f8ae629f8d0662bd4ff416a89a4e284fcb265b855a7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000070f0ff6a9a64b2ae86e04945aca036d3b806752660e9eb15982902181231b6f9d224f405eb06a5720c195d361e88840000000000000000000000000000000001070edbe9fd7b565abf56c2907909391bcc462fcc37ff6ba6c77ec54c942564542d85fd636459a02806beed71675e491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007de78240d34f266caec2813479e960946c79a6110a4d12d2cac25f0ba2ca9184412b687b77e4f2dcd0a296223eac3dc000000000000000000000000000000000c33a72db7cd6dd2b7361164a2082d507ade7e902db73005bc7e2372a7b7449644703f55ea44ed25095ea81f3908fa4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebd0502f8e159c02ed8c58b1e7ed8d5665384ec530f5e1fd9c9771e2d1415294204b6c3c043e195040435692a7000210000000000000000000000000000000003a09086062eeb6f702b938f0b70c657fac579673544f9e63c3e04286dd7b71bac4ff5fd457e984c1617c5742d46a8871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006025ad59b7df3aa441710c18f93bbd772fd68597fb8682ccb5ca7dd04db58d0babe0960d61122da138ab3a2f579fd43000000000000000000000000000000000ca4a8e10c89fb58835c4338cf93730e0c430a3a2272113a5db93fe0c974bb752ddfc02ec73f70013999cceeda675e7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b6db9577aae205f97e25d829dd20a2cc39cb4d18156532b1f227c3d17e5b15a0eee570f558bc4a8ebfdec4ba6fbe890000000000000000000000000000000011fe3da32f887a845050e57cbdc05d23e4072173347fc5e9db6f2b937e7a96e525183afdde465df2d6d1e56f82bf2cd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062199ed495ffffb1c0f39a93c5ad6cbb1e8c6d49f168ff6b1e270d59db6dda48776214f36bc1b438e104caacc06cd70000000000000000000000000000000000a55e4e83234c75950015bc8dd867c79e0a12eabf4311cff26ced23ecf717ee3c1c3317c1f1004348c4fe19df0defc2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000227ffd06cbd6820614adcb7abfb9d553a4ebe02c5ba616878e36e478bd8e04e125604bc731e6154ce6be59efe31caac00000000000000000000000000000000071d7b9710bd55c0e615e4056f8478546e1f6a906c2a8fa20a8049e884bdcb31dee4369292815aa3f7b3339e39dbd53e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db5add9c50d3ca73627d8ee12f677c14c6cc610d612b2283edbf0bae8bd5513ce98da888831cdef2eac40b38cd54ff5000000000000000000000000000000000d7ee423fd35f9eaeb6f457759ffe4b59e54f76e8e0845df45d63ae607f7257cc6fb99117b3a752532bc04613e1e367f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f1253ec214376ae4904edcc365ad68143e3e0ccca4a03dfb34ea75f05763d8bd586539155e0fbeac9c41c0efc646b50000000000000000000000000000000002d27760d9a95155be78f890f2a6b4cd6b4273045cda3554a0927d01641fdf70962e0b54080a4989d8e6e5f28c58aaef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e57fe695c3cdefea4f98a16dda72691866839f4d9dc9fbb7d729eece71e6611edd23148d99092b2deba874224a362a00000000000000000000000000000000030f69f0f03dc7249d8e64206489756ff6c695fc21fe37b34590f3d9a9d2e85157d60c98bf2442ba22da7a6e075cdf911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f927f8e5e4cbc7a1081069fb3eb9b2841ba715b90218830a6a92c13085ed5977bf1b54fb0224ec94a62759dbfc694a0000000000000000000000000000000012677b732b3c95f68f1f29dd67c57e4f6f2d3a9a08f1c3d3194a4880d19d2863f7cc174301b298157581fc6ad9ae65c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145c026dc37abf582d157bcd145d13ab4b27250f51af8aff1bb9860501eee54115f398bc6c157473e700556c8148ac0e0000000000000000000000000000000012219bd48ff9bee87d83cef54feb8dc0bc0208035218b1241f8e807dfa7a0694557575ec62baa40d8e32eac004e360df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee2d4e702869a7339ecf264e3b4e0d6f8060d1a0370f2bce559fce684bf66b705b10d3ca0e650d52dcd0dad704aa93a000000000000000000000000000000000d6c07088b7e7f1a0b85706870c343f2c5607f6b4a68086fbf9fadf7c5d2c494a0a18b97affdd7a7308c32f506ed84161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad3ab2b4362dc45d557cd857acf4a9331afac38f70336328f745a4934c26b909b7d5c726354c6b8a65e7d8368ed9f7c00000000000000000000000000000000044c6b8d2b35c3ec853d1a9ae34430059bb82a950bf4c6661e8e86223f3375ab683efd2c49115a2dbc7d985847f021921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001140135b586bd76e16457083bdc076db558e9b8ef5062d4edddfc0f90de9628bad3738bbc513b2816eedbdd91ad5b42500000000000000000000000000000000054a4e9528e853cb38dd0a2a932b4a3e48ae4d05b5c7cd6a0467fc5f7fb57d1387f04ce2900fdeb62acc7703786edd6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d380ddced173c842d0e8a16464688d47ad39453ae463a38490186b2db09c1ca6242bc22f1bc1f8b11d4974bd07fb41000000000000000000000000000000000c7f9a83fbdc43f4d513ba8f033fbd836d7ac7d9ae22d91b293ca0fc5375398812b1fafc353c5ec98540b4b1c5ea89821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd113f951cc41637a8ae8fe9eb6b229aa65168d94e06883b08f8def4eae28c99323018f09fa28d3ed48300e8b793733000000000000000000000000000000000e432967713b25a6c3e8742c970d7cbc7407975860ad57b06e96453fe8e29d1ce93375a719792def537545f9542c7a741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019463df93f9766d245c154be2fca15afdd264e515f8bbaf6a9aaef68e7dc187022ec5da5bdefadbfad57e35ce6c08e24000000000000000000000000000000000a91d47326c6e9c353bdeb0b4acd7db3c9a6b26f125ef4355dfbbf5300bbde537323cba5734f8de5ece51d967fe28fd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5d8c0aa6f45eac59793a44b2ec74c39d854350117f64ada3670d1ec6250089450d09cf629e10c9865919b2dd3bde1a000000000000000000000000000000000c824993b76f7e964a8008a0f2996263a2aeeae7ff1cb6429f5ef082abfd3f19a450aa31af186d8f0a296a8719c8040c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001845c391fd08576749f9c8fc70542d5297fb0a514f51043311afc4ea016513e1a57b1ac4f297d7fa305b1768e9ee7fbc0000000000000000000000000000000014137b54d0893b47c1b5143f1da6771e3da0a09f1d1a8ab574fe48b4288885b454ebce4e5d7dfe6d1df0fe71e2b7d44e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f23089b8c117d1f7f135e4c5b6cfd77be1dbec0097f7ebb25bab498780eb70e2c7d5d5e5150cc948f0a19425368fab00000000000000000000000000000000114da06fd9ef52ee44cf3a4e5f5f63b72cdbd4fe9966fb978b231d681c1255c8a99df3b26fb273850c84c4e750ec7fd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a49dc3573bb9f327c243099fb2cdcbf42f850479d0e3f4ccb2c913ed9435088a639bf100ef3fc6bbe73092a782d035000000000000000000000000000000000490a254a354d2dc461172bcea93cb51bdcbf633eddc0afbacdabc72ae4f68246ca062a43418a6557f0689bc7b9186d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185cd5665aedca80432224a30bfcb78422b0a50c444ba039b762a5999b2a112112229fc8adaf91cb52ee0091930f455b00000000000000000000000000000000077d7bf47b53617292fd2c909a3d35643bfefffd6593e5fa9b76aee416c6ec12bc1642a2584dc58a363c6d9fc03731111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019193a7130e849b48eb0d72e4f901181d640d79fa2bc1fac75de6bf535a13e094258fc61be9440689266c383d1fbded8000000000000000000000000000000000e178f92c190e3bd1e0821e5f63ea0e9bbcbcfb9c387c2753d69fb4d9516d19036d9302e93d06364fb138da3024b2cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5fd1e985dacbf4b0308b64abad7a4bad38677adbbb443ac32377665f47137f776b4982dbd183ad33fffdf7471b09a60000000000000000000000000000000012db89b6aea7069827799ed4de2021e23488bdc6d933c656eeaa9bd7b7514271303638ca6a0c5ee9ff549884fa51653f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b889e8d01993f0358c3e1a00af6228839b77d011400d36955b8756ea522324d03d4ebc881b95fa5b2f03b442bbfa8a000000000000000000000000000000001778990e3f7e6f36dc75ee88c1279d7cd281540bc4ba26f80de98ab0c1c8a2ec19b490b23d16a423e2d7edc2c58647b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a4ef6361f2fd6f42895c13bb4c2c90ab997952215c8b322ac485a4ae8ea9d899eb79b145efc6f63ca1a55e3d459d810000000000000000000000000000000016c6843d3465bf05e37046ae0eb4866438a03ef1477210f151cfb0cc575c386cdce75bcd8a17289bd367704f3c5673911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5e3b7e9941e731eeba60fe75665ae6a6df1b23bb22667568d3d420f55e51fe50535f15b8fa2b1d609fdcd9291a5f00000000000000000000000000000000000c75ee60ac0f75fbbc8e9b79ab9e65dc2703bfe83060264f1d63ff62b195de69e2726ffb23f0202f279c73f484aec0721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c004198acab8bab037aa60d43ea250218bef6215e88b42599ccd231914b2cc17a29808fc77d6b252bf5bc5d60471bb0000000000000000000000000000000011b96b416ba8c7d755cac3b86304e7c0561fa731caab700c0e343c173e6d0b2f6254c42a5d8a0e4792278112a8a87aa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000083a1109468bd5e64a468f222bb4ead4601d0b945b78c1af687df288b86b210f200f686807a0e434737cdfe32f05b35000000000000000000000000000000001728d02edb94e55d591ae9f4164c9986743059874e551894ae2119b0e518ac8cecdc7cb9ca1a35e67eb1cab1f40f1a891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001149136a42a39611bbd9645df50de68daced9269dfc24ec8ce5ca3b5b7419ff8b8262cd4e3b0f92308585097c3aa7741000000000000000000000000000000000d45bcabec8890c376499ace9d55bceaf3fcbae6b65e87eaebe6cff106cfc803392b01069e5923e5e888e1d4e7bd1aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a802e2e3bfeb79bfaa298d4197f78b02536c5d9cb9a6f3caee9ed1583368cef9c27238d11aa18f22b62d5860419f0070000000000000000000000000000000017ee28c37adb417311e4044d42ce6d02bfdc9d647141c1361c5a9726ebabee5bbf546f8db56d805b5239b4491750d1781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dd4d586a3382571dc7cf473b7ea6eedee5a8eb1762ebd0cc606ccc123b17265689b679e9b4feafe69ad7af462fced4000000000000000000000000000000000aac13ab1c36e1b27c09e6e763510873707f17b244e8696c9781d9141bb75801a078e2c84e54f5aa93ba99437df660911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000600775281216279d33b07bed40344db56026041abb49f8e97899f33f02ff91c0645ff436adb6525a0a76b79eb1cfd0200000000000000000000000000000000141399b7250bb51fd54f6a1627f265f7dea3dd90d944722f86f51124fd9de019fe2ba770d2d64438986313bd17631b401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1d0088e2060d2bb36af9d528b8333d500b8d972e803f179551e9d80aa4ad34f964e7053c28df3031f9b07d56f7c8f60000000000000000000000000000000017213d0645431f4c3f5bb3a081541c5f5ac6a986aaa5df096b8c5911d541fe6994a617654536e5bbac7ea41f27bae8271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cf24e7f89a9351000931121519767dd525f9c94ecaf11e35b626d858f5f9c16d6022b246a1363f94bc13fd6b45c5e60000000000000000000000000000000003e04214287bd4532668ff82e2cd2041d57f8d672d08f5aeaef447b50e2149722516c586dfaa6ff49488ae6b40b875051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9259aa5488052421e3d08f2c26ae1db4397459f30e769302c1f6c1699b7f20df53bd7e42563f02614db8b469cb28270000000000000000000000000000000015d7fee47feb93ca119e2131efceda451e3c1971b0c6bd62d7d6e2e25df39505ff746a7734f39c7a3f4fdee4e466b7481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018697783c243da0b0a1576a07bce66740371fccaf37027406e0d51fb7bff7156a0771fcfc267861ecd8b489dba8bdac2000000000000000000000000000000000ea43a8f73d65a30ba1d9591075ee86e2397d167a9b377d4c7d85cb1d7505913f1c5c92be53401c182d133252045a4f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000328fc303165f9ae76ca63fe8acf9f9d29d98853ae2f6611a82c83b0a8ffb8184f462cab1fcdcd2e4aace69a62a55fc00000000000000000000000000000000011b84fc9f5db0e4bd64ec4c50e54bde6377536ae497b294de044e06ca9f7e8c1b3c01a68d32fd38650a53cf6de9476481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000157f45f4acea6ddf56574e911b007b97a8764b9abac0e7f72c149b5522e162bfde1e2a51825cc70faf5fbc8fe18d2a3000000000000000000000000000000000ab77e7852136a9df30e59b0160f9ecca2b86e906f7717db2c772200a8cf4b31e7f4bc866a5db4455de961f289269bfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011045b55a82fd56fdacb0e0e8311a8a7eb41cf6db5cafdc2f84ca2ee78fa23bbae5c3e83cd542aff17de1a7ccc929e47000000000000000000000000000000000b3f6dc2e047005d0248eabc12bb5d8f055346acec2186973370db58a4eeaaa6681bb34d881c02cd166a2ef422c45b371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017199fde141217bb533d621b397b3e9ef1cd0366af049b58f72dc7cfaf7d1edfbaa199ccb173d50e747b27a1c72d035b0000000000000000000000000000000009d0853a74814f3991961d59585e90f4ae4a1be143dd8b8e1ef4f972c606d25e8f8786a800a31f83ee97d21ac0c587791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039311487024a056937fe1516d2f9d4c10feb431085202f049d3b5108e59abf626caca43be32be1fcc83c0e7229604dd000000000000000000000000000000000681075d589c0ecab84bc0727b1d604ffd170e991ef39100c17c5276ff0fa082350f430b0362688d7b90e9a9171ee3e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000802f41832842ad75f0965d15bb0cfa08ceb6cabf0f2749c6166e294a8742da426250cf06a35e47b9f59447dc1537d1c00000000000000000000000000000000076a075da305c8f1acf0b9cb611d253928cb7da90d255146d8243a88fb0a072e901b312cd0ad886da7600c482dfb3e2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfc28db3c4f92586d3738350c98948bea45d80f1d4f0e300f5ca7ee675dc534de1e06ef0fc1121ad3c20b3d5ccc36890000000000000000000000000000000001649bbff40f63e637d34956f68f61d9f38a427836d549efe0ea08657b1a417cb45e312fe844378abaa052ffd69a8d3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b944d1c6f3504d8f4315274d450308c533a2bfd513a3a0ba617277c3498784386f703e84b264a41dc2e0af4211b9530000000000000000000000000000000015829372d1acb8ff8909b6f757ce61ab660dc0a16f63788a7486fa204cf19ee51e4fa95c72dc1cc2ddc867ee45a76bc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000273005b31ddbbeeb9d3d2adb2dcc56bf404b26d6509692351674370b664461be47ddd0c69886158e677b99f574b1600000000000000000000000000000000001816657c659db7fd665202b44d99d4797a6bd4f319f8a49f1d146ae2385b1742715711e89150b62803f3c0b2455e52e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148965001e27318d85d826c1598507b6aabfe7f2e805c71a9ae4ec90ff8e1f3265b9c4b2536c5e147d1ebf9d0706cb6100000000000000000000000000000000157d1cc99e8aba2d5573407654cc20df9864855b38e28d0294e07c4fe0cc310168dc7372200e02dc6982a70e174e599b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a66ac4e0e3fb93e28fe7444124b87f6c0b90eba4e3776c0c5b7930af603b387228d103197bc156880bbadbd2cf55570000000000000000000000000000000001e855e172a4cd25553d1cadc2f07fd77e5f2246a53fbe8ef0fb2d0da0ea0e3348c0669c2d3158d25d8185fa5cff20641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019703d6050df5137a8710133c5c71a53291b249f6a0451a192bcc754b95d381f99e5002dd01a6d4938d862f4fbef4925000000000000000000000000000000001507757065f4ea16eab1b523b4ccc16d3a153c9086124659ab4731df6d49bd31bbaa6acbbbd49e742038a35c070754231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107065e821f77b06d7c0c70f036daeb81be64f90e128ab4bffb1d49b21fb5bca523b12b2122a48bedd3844dfd41d31eb00000000000000000000000000000000191b6c33eedbd8bc950c5160fa4560a0b174926d486335caad5f89426c6a7278a94a30527191a5954ce7bc914df575331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019db69c003d015489baced0eefc0003d8e121cc9ba7f9476b6fd8e3e5acccf31569c4f396a41918b3d3236f2d08e8b86000000000000000000000000000000001499783826b5782e09def40554dbca40697c017931d1ecdd8bff5c842fb354c8a4740952a19fa6594b9c8cbe26ab75b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fe7379f752ec5f32801d8efb06a2c83b9f37adeb1d9bb6584236c9c13eb52e820ace40ddf2fd908f0c7a9a778de26600000000000000000000000000000000105afa7ae1c9c215091615fdd2cc577875bb543bbccb24b28b056f2c58be381c608033013e39ebe0375d50505e947ebb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a61669016f3fa47fe1f8fe1cf01e76783401f2b53098fce585e303fe922360a3ada0c5e3631c08ba8b321ecda1f5440000000000000000000000000000000006b8d35e9355e4a9c9c204e317df1f4ea66672f13ecfeb7c98468a1a3508c60b71275631081be367ab590d4fa384b43e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001088ec4bb2c1d03d523fd95997b9ac0c89b2dc01db6fe89c27c055b01bc4c8c5dd1e217264bbc4f7cbd99e9dec700dcc0000000000000000000000000000000010b64e3d64d030cffbea26e2a90455635924066f83d0ad071019adabae7c7db1a34f9fda1a3960599af9adf20bbac16f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000def07cd0454a6fcfb4d6eb9b84925656ab0859ae1a18c7829c003feba025e29f36912835f73b1e7d448613c53f1936e000000000000000000000000000000000e08f24295c28c656beebc76320cc9e17329ec8e5ed7f1dea11ef52b0189e783fa028fc5350f8f8e98dd03080cdde2371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107f442f86a16eb837fd6ec54060e56b2bb8fc3bf0730c55d53cf3dd21a8a1a2c29150b9df2a7945014b7e9e9d5de6ef00000000000000000000000000000000008072523f6ac3fff24f7b3a26a1a1f9f56ed6b1d2227e36f8f0e47997cfd3b1f2264a7a34e6b1fd166984619f2c5b791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5b4bc4958f117f9a82efa6d0de128cf00b28bd01e18b539cc4ebd4ae846678207b716395eca5f7a1b5e6ce5bf00a9800000000000000000000000000000000092c009226b57054d07ac20611e0e795428deef6a9eb5cd190af1c5806bc0e5fb2e7c0b0910adf78a96bc495f995164f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f895bad8698089b7a6e732e745de1ec6cf6fd34b24b67febfeb1e156986ac6e76e20a06cb1bc57ff0aaa55643c80650000000000000000000000000000000005bb615d1f7af74f2e9ecefc9f3c3602376cc1a1c13f1d6525bba6caebd8fe205c229ea432da6aa41697c753a8ab1c0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac6a801dfe8e3f3f35d9e52f107a0ff07d1d06abef9ced1b5f8c2d3180430ea7e07c0e84ec203de75e7b6c8f1fb2d950000000000000000000000000000000001efa936a8166b3cdc82caccd2ad89aa6363be9c3937a06cdc4fcfef92db97ae63af365045f7af7c7fa28fadd924baa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b2f952f3526839cc25c13a619b14e1dbfbb8bb56d31bfea291703998212dc233f61f52b2e77af723ecdb8cd922ad3100000000000000000000000000000000089cd07a5f8e28b4512f633beeff51cf3b900ffb5d66f57a65e674bb21c867202924d3e59687aa4498b2588fc0e7f3c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f8b04ee4b13b02859ed0111a9d28a6441a0d03a4b3367edf24ece5799e9496460313dae1057df3d2dc5860a0905ac00000000000000000000000000000000017ca4f4d3f59e2ed9c93ce5c970194c1d0168a5eb65a3ee95fd89ae098561ed33c3d2bc196c49d150490768f951f1a941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de3b06110793ddad32685ad95bda7c8dc380903b713e17e913c306bf9304714997e013a4282078798ee8e7a5184ea16000000000000000000000000000000000a8f0f8ece294b52270975068aabe8819a99fb2881660caa7c9bedf1871f381fab2721ed2192af1956739bd1340631e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd71c5c6177727c36eb1851f63a6b1a571484e7b34e1e94e1437754b1afee91c5cbfd0c9794d078191ab8ef7fa4685b000000000000000000000000000000001681b2b3602cdbe883cb09784a88a3c7b38301f5226e4132f537c800577712897745472d8d423675a478b56c7f2d361d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d78d5a5304918eb0a90fe0056b8a43be41f45d4241eec751824dc5f498e909524b3437c385eb6c05a8d03b49c664a400000000000000000000000000000000058b0484ea1556fd39d3f8af968b47d98962d889d88e975c590ebe4ceeff927ab2d538cbd24f53571980a5750cb698d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142b168baf55b1a98ed743f52c29d8ea9abd4c20474da3b8339c37acb7ff1fc3d747f9a236c55c3c2d603fc9a9194c8600000000000000000000000000000000181822c82bb0ba31b573ee2cdbea5824648da065c8500260844b914c7e5afed60496f87e30e08bc74195f4046172d08d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189061e7aa566adc7b9ce4c66ab3d038fc9036d7e0582dcc31b9e06f4d89c814bd3b98a854c4f2ac8a36b29c38ae658300000000000000000000000000000000143e826f208a9addd96ddcf81499b37a0c08bdf72859eb34271fdfab952b8ae6f1e1fd5185704b3c509d17347e6c56bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba10d850e242aea79c52e11aee963fac7df643148c90f831ba8183d96187188b40c8a0a337c8eb70c62e0428d42d42d000000000000000000000000000000000ca5687eeb89d15536c74f2252d7c6a33a1ce9f06b34dddf3907d8af242d39a380f8e2cbc075a1ee6da54039f39a4e801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001153a2f97e3a48eb55dfdefe4678f3a556965a01e8b504905a2734c2ec95ee577c3d663af4d0de31aec77f568ae371390000000000000000000000000000000005a745a13d4cca838abdc83e921b55ea436e9346215ddc66d5bd98f960de3013101f5b7813ad04890ae2d1935b1d009d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140622b70d63ca6567285b714635f1b7b315d658717fa23041033de5b7f497524b46a0c8a71efe3e01be7f5c5094b6f2000000000000000000000000000000000ad63cba7e1b7ba072b0fe39e461c13aa292018f0403a605ab55ed4475d89d8abacd9a311997d02de19fa8bc95404e5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f362c15722df42bc54558e61f1bad262c6340393af4d826ac675d67f153c9b0c7b034e74b4b3d35d91754d4d46641320000000000000000000000000000000013c997f30539b144b241ab9edf61bd652ff86c5143c3e8c23795e0bb8fce2e6eb7af1cf1f46aa1d1de02016e6206410b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a56e88b7eb5b1bab38f72365177c051370d5e4a79dfd10e3c81b4b2cca5c12b17825bd804a13beed086dd060add2e95000000000000000000000000000000000a9d344e63d91ef6f5abb87e195cf6a1c8b071365986b148b905d975f843cdd0ed0f181a4137f21da69d7fb8367c52681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c0e77243dd7fde8646c435f35d039faade5c922fc1f22e3c6d52abe2ef34e3201cbfa7268c0d5d1cb757272967f4550000000000000000000000000000000011aa246bd618465903f369c8083516b63f2cb91e6bd0628c287cf14c032d7721a518b1abae6cc8799841c4e6b680b48e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8c27d8cc181a6fa4227e3cfe913fa3390e90b385f145d72d7c0d8e5030fa4d3b2c32fb5bb079afbafac48ef0f51f9d0000000000000000000000000000000016abb9b7138a58f4ddcb25209c21aaa9c04aa5e4878d3df59173d9e5c4b06362e76278a1d474e64003d21d8c48e4b4991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a02d28f145755f9a964920221b80a1f93fca15111a5d15eeab939328b36be417fda08d0b31890000fb5e2ee4bbac5690000000000000000000000000000000019a9f697c7d9b9df50d456a165ffdb5c9fd5cb403f368e2178f85c0b7ad18474846885709c90065bce3e2a731cd4fe241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7c299a19eeeaaf9bdaeffebecd52fc715374e3e06fd76c6ba7a86c32834d6fb2a294b65757678809af371bebe2469c000000000000000000000000000000000945f1116e0d382514035fbded3aad76ebde6bfbd1c689ec16a908f9c7383e066c77b503f1df7f77ff57ec5291952ed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000387cae57c2ff8970be249947f0f321ee9382b4c5421edcf0040d0b84122fbab90e4edb12131fa884781052e38a4bace0000000000000000000000000000000005cf5dfbec4fbf64ca7458203dfe3f7938620f52161bd333d3e371f767766891a784ee5a198b0f623bada0d6359e368a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a2896bbbcfe4a44eebb7d27e0444be2bc19d5d0deeb3f58bf93989672e30497792b4b2c734df7a642ab82b5020f2e30000000000000000000000000000000017e0013e66e14eec9beeb1ed1114d802ef352563d1aadb27aa5a4fda8cf57dedf0a896b91b6802d7df44931f80f334d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076a8c7e7042b56f1952637870f28d6cfe8ccae2a9a3fdc05d862b4015dd89ebf8e18e130abaf4c9d90b249c6fcba4d2000000000000000000000000000000000c3ee99cfc5df084c6c9c185709b35d282a016028a96d990ff9c6394045a9bb54cc5e8291977c0955fb839faa46ec2301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016825cae084a9708acf2ca8ba31fe7c81cca8ecffa5fd335d58d1ebb791ed08978cdac4b21f11fde05819f40da6538d40000000000000000000000000000000000acff77119356e1e31add7e742a9662b8fe864f77543e75eb389bee2a53cb22699b9ac8f1ebd0775a9585d161194d081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ff4b295d3b274bf0b43dcc4a1e1a6fb5e2a32638c5d8aeebf00a2d807c9fef92342b0060c6954d57c0cd0172ef89e500000000000000000000000000000000069c52e3fb24a0548755d09d7712cdd16569993d06f8c02bb6cc7a69606ce524c3845d8bf2c68d00afaeef0fe3b2ac131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbeeec6b11e1db3880f59b69af90796b96c803f9a3d339f859f7bfa389fad8d6774b818b6ad3dfdfb7d60cbb4d46ede0000000000000000000000000000000013badc3b037ada51c279ba6462aa14933ab865a975848acfbc664a491f55221d254aaf4115d18cb91649ee6789ba51b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fddecd797ecfd389742c3a70ab5b7b8c272a53d4fd076bfbbf4f01bcddcb7b7bae4524d47934695eca8bba7f611d6020000000000000000000000000000000007911ee36e8467090160c9289e293e137ac45b1fbcc7b13bec24aa266878d25d84bb9919293dfa33b737ec2ce2fd67811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4580008d4457a50dc2799794ed8d3f652a03babe1ee03cfc61651abb0abb2469dbe67204bfd62b4690033a22758f0a000000000000000000000000000000000d3ec120eb3e7ce30b9c3be9f2b7cd0408ca9c7f672896cc7767f16370614ac26d6127f397f700e0408e52d6447aac931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd2eae0ad1b14f9ee2451ecfa168f049297998db9cad05bd05f6279c06c48ee56b9107033e97e766467907194f6b6180000000000000000000000000000000014a7561c8c41e5fd934e9c051ec362573f1244b984a59577d5932db98b9f1b9d5f4a7531a5a281f53e48eb1dd8332f801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135febf45e5b1f977f83383aabf0bad6b3243816e91b7785fe79ac43413c48d62aea4514c9b217a5bc52764097d8052200000000000000000000000000000000085a8f381efe12dc72ba08d6f298cbfc74766d09f377272ea6c0aa81fb54f4178faa5ef3aab4f73995053503b633f5001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ba3b23460658870f55e20df729abbfa7410e9a718df11a272ec77afdecb36449096fb301abf4b4c56239dd84c0b6030000000000000000000000000000000016f52d1482520146d408e231d7554db2703ef004125d051b7f9f8c335feeb17cb23a9d8c8276a696599419762b8714411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003414d561a2ade9c0e0eea9dc9dd7b584dec5a5f1c4ff956911343d1c47531dd392be7851aa9aa0dab3558fd47389dd0000000000000000000000000000000000c331f446002cd45a9a1bf96777bbce604b30addba2638f7a2d69e55f2095f2a8af8a8b3d543bf4cefded8b93027a9491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a46e3def610d6b372d7de510f2d1f6296ca365d68b1540debc2a7037e4f235b800fa1293c70207a52d4d23a0fd708d6000000000000000000000000000000000ac48c5f3b863337866027be775e5e00bcaddf9b5b9ef42e5c1a1a9dab896dddc162214924f183de3705767c1e34e06a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081b36aece4cd564342568ff31c468dbe9c48cb7714e643a74693b991c193544a5d8a4f05786cd7d5a585b5d5f24298300000000000000000000000000000000037f26dbfea1097b9b275c8516bed034cfb4c237aeeda641e53505bdd9b04656299e82979f0a77273e69b540b860eed71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000806059c68dcabc5797de1530f0d72c1ad18f7869f5cd8f47e38877db62efbe968a87e0a8d7de77221fc79adae44e828000000000000000000000000000000000dad2a7f9e010bb6c9aad197ac3b79a2202dc07958d98a7507eff6928abb0b5d98481ddd44d71c7272214d79243a50f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8af193b20f9252af2ae9e46431984c142f4d4b59334ff5375e12f051353c360f083b448aab74df008764b8a5f2ca990000000000000000000000000000000013f2f7d29e3e7e5fff6ddf87725428a52931f2d5b0f706ccc16e412f9dd1d18b08865d27c82b3fb77d59e66a5fff9b041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fbfc512811452bfa5134feb157e1daccdc856fbf7f6fc087a4439070a7ae2e461251892ac42e9be088e22024c0ce4d0000000000000000000000000000000010c3bc0deb8ef8b3772fe67ce99ac8f817acf9a7a5a8ceb8cf4d5ec0f897fdd314217151dcb5cba775637ea267d604441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ad443118ff0358ea2e888ea09591120e8092a636740dccf3298603435a01ae8f29f21a3a22bf37dac9be25e7cfeaea0000000000000000000000000000000013b128b4489c2f200a9b027ffb156624d58a8ce933de34452a3443a00e4c59e170f5a52f617c9f5aeb6b27ffaeac00d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016589a97d60871e3af0cc6b78e9af3b9e11fb7eb1304602e2abaaa21255dc46b3848ce5567a73d313442364b422c55d90000000000000000000000000000000008c9bbb1289d6a9f02f9565acf566a33ae8ad2f4f70294fc2bdda55271baf90c5f21044cf129e84c9ea7fbeb21f0977a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000502b99435a32aaede99ad07a686fe1ad87bb4612b19a12857e7fb39523b1311b40ca06b4e5a4fcf6b870dd594301ab500000000000000000000000000000000035ebd546a4b8af6c3f49f85324d1953423a5a5b1bad5ca7cecb20166e9e9914868c2f47dbc10a44f92478bcd02faca01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005318679728f55f687be5b014f7bc1d1ac5fc50cc32db48d2779fe399ffa567e7551b01a9ae04545b9e7f0a55badd3dd0000000000000000000000000000000016b1a2848218aff2365ac45860fb6f6254fcd0b614f716e0bb8b3a9346e295f7fbfcd9b8f714c60c95c75e65323c3f7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000700abfc713714dc05c5a5d8e637e0ce7f8fce3da4e82c0bce0b6f6da4c9fe0e5985121c97e9db882e1fe9b51029a1440000000000000000000000000000000011a62c7d8ae4022fe6470c5a9b6481bc0b11e982bb98ca94c8aed70865200e614a97eaba3fedc55def5ce606b5c556531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b8d2b8d6147cbf8065f5f03412ea35bb57f42da3a83d415799bc2202b2bfd1ba2651288a4179f767251f6ca870bb7c0000000000000000000000000000000008b430f8a0f68b44b8cc4f471cb810769ed8d5212771d21b1deda18b6d0dde2c53d1f6767fed2cd4f9830dd121514fc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043537de26759fe5db48e9409322dac5776a8c15d10c9e6c8a55ebcfd303f44e86c98169555529f41648ead20ce9ae8e0000000000000000000000000000000007907bc4ea9d494289343f874469534cbee027fd4160d04f4a6eae64d0a915a7cfc5135b925575a46b5d13f3e15b26f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3fe8ec6e7a8004624e13b04a8c16ca1e0916f9ac873e6e51850a70dbc5a023daeac1372acecaea83253580d68361a60000000000000000000000000000000010aaf3745e8911ea30b6882857c6c0b35c61b5bb038f672e1a87b3cbbcd855976b1ef6fd464955eb34346ddd1b2bba581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017600f733356bc9706efb991a25cb2bef20066b3788711ce4c6c24e73df777c570b04570afaf8e56d8ab7dc8ed8ff5fd000000000000000000000000000000001609168a8362e4cf811c359dee4516ca53d900c57859eb917f6ac6f649583c87dfaa73613417df47de08ab901ba29d471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e709c467ff813e4c0a9877f6fa3e316d03d802095fd101422bcbaa1d94fb3fead5aa94e41a2fb4ad45345d16e4126d00000000000000000000000000000000022815363aee1a1f7018332745c21f17217c3a0439089386b755d280361e940fb4d12c1707527316d966dd654ccfeec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112d296b561ece75d4c573988ae2fc84ab93f9ef15a5c2509844d69800bfba5d4008627bc284477db0b498e565c62cf000000000000000000000000000000000129dc7e339599c8881d77e1e08e6f4e0e414568eb1884a0a96da5074d9bf3096035ca5317ba6d307680e7508136ae19c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001566799ca2f853e31b9e6a7cbab7ab588898ecdb8ed6ef1a783e34b3081b97df311c8e650e6f7fcc877890e7e3975b98000000000000000000000000000000000977a96e2f2813bf13e11e34013302211cd744a7fa95c902a444d50c6de222899121e923ac44d916b657fc33643f50551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ab76ce14aeacd3e3c8e4714931e7aa541b66459281224c7d1f0be3b5507e43195b67ca5efecf7999ae23ad57ee8c230000000000000000000000000000000017fb79964ed12152a7d5c19699c376667e326964faeccc9d0f9dfe5c7d2c93922cccf456c4dd9acd715cf78453563f8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c252ae4be7c12b96caee7846036ea5e553414c7dd40a8a15ffb7d891039cf311de0252589958e6817def64ca399d9600000000000000000000000000000000141a68089a4a0cfbaed1c0dc66b8f59eb60f8e9a28576b7974945fc2ceac175a6efc7227a5461094a65417e8aac08d8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eccd14464654c11199a1be24bcc5bf894f171d7ccfa6a9c4e07f0083d259ea6f3afe0809492e8a4487618ec2be516f60000000000000000000000000000000010a1e5fb02f2e59df4228bd6dd45f6f8e5435ec0363bcddae18147d09a62acc6fc93e84b7b004480ce929a8fbda1cd3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bf53d730774f6655e4af4fc81ea8b4202ef83c2e96042bb4498c978aeba16d8571ebfe705aed4a05593fc38979958f0000000000000000000000000000000013d9148e85a836fa158292055322a131f9919fdd02820b2b3af5472bd8167425d8e2ca5f64fd3ea5eb6d635996a453e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e544c26fe452362a6b409e83255314487166caaf12ecbdeee12d3e711bf744df543e1280b1c80ef4952ee38a9b7f59b0000000000000000000000000000000011e71b3de8768a6dafe30b614f97246217ce612d8fffaa32048b92155b13cf03ac26ae264d241fa16692a7aeb6ac79061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069b6a386fb5d31fb654cc97895955212a470e7680124fa96a085fc69165c59bbf083f1020d339a353e573edbfbdcb1f0000000000000000000000000000000015e2932de1d0af3358001db59e4777a5913f4407b966030918e1d9f6ba5f38944ef90b3fc97d89af40afbaedb65155c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d9f530bba156f08b6885f8c96a3322b4b4e31e53711c17dbba29714e2401fcd2ff0ed994a0244f10ac1d75e704b08d00000000000000000000000000000000069ee19cd9d4825f7e441ceac3e791a8d3500c1678fa60fc025fd436adbbcd607ccb26b6e60c338d2ccb675da93a930d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c376c6d36629a22a4e022762da90499966aee49465d6fff77058af122b6602a362b2ee85827b05b5be00d7d03b75b980000000000000000000000000000000013d339bb2ea01c60e0a782050c7a4f998ef64fc452c1a45b1f1845b922b5e5380510b170af6907d47360d86ad469ab151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025e51c15ca087a6daeac26c08b4bbc4effb0813f8a23dce1959d783406642f176f2aa05b8774d401aff0d4cb87de1190000000000000000000000000000000017d07b1a006e3406d8c748c4f262a27ce440490525506caf8c1c9d09308057f0aecfcbc286ee60b725401b083cd0442b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8f51265fbf77902058d52898dd332800c64e3243bae8a51ef933ece0357a21b565bbd2534fdb497d854bfd4e492c42000000000000000000000000000000000dd4516540e4a95e5eb05a10faddc47884eb7cbb881862c19dcd9936a4936901df881ad6fa029ab31d547b6e9f3dba431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f613e07c299424a59c969ec6f0ac4a914376a82fcb0f8873509347d5267cd2200c68d4838aa7866fa9ce440a412bdc000000000000000000000000000000001045215c25fa66c1d7a7947d81dbb998debbc7a5f2463377ef11c0eadb0e0249c8d1f52ce627b9d1b16675d05f47bb611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012932f29c9a672a080941ae2eeccf8f50f3155f01cd7977ba786f7125840ab9605b771793590735ab41fc1dd10babc65000000000000000000000000000000000e4a67aceb6e0331e6381e2ce6f69a91326302eba69b92c7432e53ba9d6230f99794be8eaa1220b272a3dedbeac0c1911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000867f3f29eb9aa8c1480137b86d1670a112d5d0c6f0d7baa3674a5e93a6fa47ce5eb604ef1eca90aefaf884f52b4c768000000000000000000000000000000000b23b1d055214e42749a51c3a94a75f5689a285d2a9fe981de27c565d4dfd59d8abb7e6c5868dad15c3cce822e1d21591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a556e55102935f073d0a907dfaafe15b59e6137deb822efe0ea5f7456413cdb4237da60808797cbea35acb696bf0a900000000000000000000000000000000129a5a2f446a56a22e162dbfdfa6e4da706ffee8ea937e1f6c8860bc6321bc4058c17d242c6578dd86c99c1456fc08201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e010f12ed38258be199faa4fd4083e88692a4bc14fcdf8b5ca5d330d6d4dd9490835cf8f6345c985eb2fd66f90f6f6a000000000000000000000000000000000d1e63a8bab7fb5feeb7cdc196aacbedab5a860dba9512dea39fe4cb62fc7440bb4e72ea9c2899132be49504f15845421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001452fe7d1b1e70a8ceb89698a18b1546998a28c2790c93bc9aebbbfafa4891f7f4b04ea3eb17f336fe25461022d28b8500000000000000000000000000000000190e2e9d90461337db4729445eebfc4b7888089cc9c09aadee260ddc0003ef34bc43eb2a364c7b0db3a163c750eef0bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de991b461c0908cbebf767e2361ca517477dfb9b0b83d81ab8758b0fe0293d6bdd3fcb2036fab71f4eb17654690101b000000000000000000000000000000000dd5aed5f49abb2892412696cd554ecd022d88aeb2f9c5fd27d39a8da0bf0e92637e7311314b9ed71bb9e7ff4a43cf1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b613ee71629dc2be82d0dee6e732124511cbb47c82f6e9b35fdbc5a00eb7bc5f39cea21dc734b637f13a9d670ffe7720000000000000000000000000000000018fd299c4d7b6d2c836c2b63bf4056642366c5dc5a08f030b890be42e719dad78e335aa750c3f9d78ebe20b35683339b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044cce1474ef9b00c4f74da04023ce9cc40912ffbd045e82d5929fcff527649a59e575e5499f4ce25a0320d1d7d8df6300000000000000000000000000000000131a42eda492ada34f1ba06d23ccc10de7f1977da173390aed188e2bbaac27276ec4e9cffea9c0dcb4f21a0edeb9209a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011646ade271835ed5bd917996e8b6e1a7bec01366dbfd5806e85d143aa7e14cff10ccf6900a5c6ebdd95efc2f85f5d1b000000000000000000000000000000000274d989be7a88746970815e7258c971fe3d084833d85a0b79ea25b111fa595e2e90b87cedb3627576b4f3991bd0235e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112155b07a321d069c05c44e92f62418af8cda4bd2e2c52d8b5edca85119ec3b5e6f691c95a2ab004e9faab5c5f328fb0000000000000000000000000000000011dec9e358e92ab524b0ec19a973fc169390eb8a74e334b17d3e919131978fd3aab3dd32a9acb30b203c15c5684537f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001479513fc9af463b57cc1681f9a7e4f5dc8d6567dcb5d7f4de7d20ace90bba25c2fe3b1a9dff7c4fe0e5887b0f3ed74d00000000000000000000000000000000138c1da0d70dd97948667a555441ff769e3413c3065c9e1e9da64cfbd8b4ea64680554e8aa0523eb253549e1aee400061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001888584708b0090fe51bd6c8eac47c3d9fc348ddc83173d2e41daf1b7b638eb3d953855ea660ef9d73940348e83f98650000000000000000000000000000000006f20a4bebc30066e24a63bab73e3e6e2a2cdb0020e4ee2f0c25aa011c2758d192ee99f36bf4cb8feb3f861fd3c93d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fbf64763545eda91fc78330a727c4b9b04899b66361073f828dd246b7bc2bf8a5c91099c99909a0190c46f2a369a9500000000000000000000000000000000070c152ffdfe035a10cec9b5a06081120d3e221fad1755f9e53329480166a8f2a5715643bd234497b77db804a2206ff81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb49275096c8b5944621fb55a5d8acc8aebce7ebd900eb5a9a27b8ca377b3760173fee9bbeb5fa390a5a27edbe7c4970000000000000000000000000000000017b3a5dc4bf166c3a7697d8578a72ca8fbdea4ea1c0d45835232c034326e6ad8e2cb1259a178d3dc6707ecd125bc3c9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fbc71d1f4c44289d1b9e5afa52f86e1433ca38dc131dfaab90e91681f94f17a4587d5e5d313d2a35a2163d2c7de5a9000000000000000000000000000000000662de989f6966a09c3d52e5af827aae4b15172e605f7047597ff2526f85adb7b45d5db1ab2b4c64d356ecfd33f470001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f52a9444b72217455c7040a3d4dd1e88309a5c29619d1d22b42d451bde46b9acc2223e686cd3a19771b659ca0779f63000000000000000000000000000000001242d773791293ad16261e5c7afd958310d7940cea97626e0c4c6a6ee1e6b7af59e8f6bfc22c19c872c62b7bf43cf7931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157867cc023c51f3e1b611f473d9508e46431d7e1550ad3cd4626ab236d4fd93e55662dd3362d5f308679aa9d532ed07000000000000000000000000000000000782ecce6533867ed47cd1e8575b0d119094bde65c6115e1c7adf152b2d0201675f7550e9fccdc2c42f8f3cbf91602151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bb8cf0162d1fe46da74a615bfb2942e3b7d290dc0db9fe38e1d2c9ff7c6def3372b7ed0fe02a476d0e1c04634d4b7b00000000000000000000000000000000078b9383b227117c6989679cc481c2f48108bfce795015f3a7e850a062cbb129f709f9f6f5665775886d6963f3b0321f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000742b95f1b93fbc3459744c831574a36afda214360af3d568e177f464d1ea26e05237645c400170dcd3d75e04210bd360000000000000000000000000000000018760e1f758cb4f35d456c03dac0054674bafd3492383668141735b0af82ab0350640d2e1aa5c815fa6cc4b08fd73fb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7be586b2570c8a78be52c121900716ef0e894fbf05935881555b2719b8cbe73def5a0077ccc468f85c44dd6bb28ce4000000000000000000000000000000000851796cd697a3bc972bbe2b91cb0626ab3690783f56149779fb36c86771dded06eeee5740a85046e84e55be9b6fea0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c472b8dc6196676a1cf27f748b58fa4ddaa79bfc0cf5e2a06c28b568e8d2f78b37f41eed14f8a464a49424e1d3684cb00000000000000000000000000000000094a43da82268a2aa369308247535069a490b6dcb7a5245dacbe7bfb19bc186a4e83999f0cfa8047d7f70ddb7bd396dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fc5c0719fcfd056b25517398cbfe53e0cf96d910e4f6d502c9da027a06463443760aa3e76d266c1cc5be5585a042c200000000000000000000000000000000026bd35f43d1748ad7ae43839b4add2f2c1807d76e17fceedbdda6977f27eb3503bc17f32f4a0a8481d53652ed120ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb3eec09543ef3291242c6f9ea672d2bd41073d2bd98904df573d5bdc7d5708c76ddfaaad80cda3fc05195cc84973a20000000000000000000000000000000011a50d7568b8d2286961d2a4646e69301d979dec65305e7a417b7e0af6bbb266fa8c17085adcb6133e0bbbb41e61fb9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a83671e08b524b58e9e17e7aa1d4832fccc174573c78c0bbb7560287ac3bfffb7d7e10c41a1da6445497255d1ab3df20000000000000000000000000000000007368d3db9b1f69ed42e1cb8523e901a9b00390d85de4c5c8a6a5e0d64bd20345a92438c3e682d0ddcd8efd2aaab208c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0c61f9366e067f48fcc0c37367d1f8feedaa9db0a4e1373b9685f9a670fed865e7b2e625361a4d3100abdc850ec28c00000000000000000000000000000000138d4e39cae97af144e36d191886858a8bf134d3bb2d10aca771007bd6c82794d0046cefe9c1b2cf8b31e8a59beabf501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cb9aec0f949359cfbdd93f1d4189ea2d75a953d428e9d0a673e240467c3027ae55e183680e82c01578c9a8f092bd5600000000000000000000000000000000168e0559c6678a2559011abb2dd5961c53d46e11082aee1f546488e3dfd1e6f2b0d799dbf15d2cbb3d8209cbd69325bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fc1f231cb8aa687140a40f4e7fb4cdf329f871500820896fc7963710850e71c46fc1686c66f519f0d4ae25af128d7700000000000000000000000000000000175e6aae004b92d7053808527776dc39cfcf7e1364cc2e4fc044dd6b85caf20e152aad78bc3704e14c9dca66413683b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141aaa3ee60c14524da64446e3b0cd8e505b39ff7dae1cb5bbaa9a57a89cb05a5617d3a9f8662b71dd5fedd44eaa5b1200000000000000000000000000000000053e6f25f7b4dae561c83b8fa6725db8d9c0afdcc7a4479b538b7400745c1f3bf8e0491bc3d277c42a6d08634917fd491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ba162cec0d042c2db771c91b063e004c425dc5dfc8503edea20e4795d11ad77da1161fe47f5bf159871dfcf1924227000000000000000000000000000000000431b6617ed2961578fad9a957b2e26b95c1f360064bf528486fa56900382c1c50ab2a93f1c8dc1b69218bfc97450ce01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000245c73193acec3b204fedd32afbc3ca36711cc4dcd6647705ef0f57703d57a6d910c7463f96b9622916e8b14482e494000000000000000000000000000000000557826222f8f3a683e5a5961bd27453c25969a4e8a786b4b65eab227ef94978ae5ea049c89c6d7c4739cba2c76310511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083617ac293f5a590d097ae1ac0b0cd0355f0b4edef527a2fe9ec7a66d4901d7659bfa6d0eb5b0959945f12be732317200000000000000000000000000000000013a276555d3f8f69ac1364070c4f841e6a956acf9f7a2d4945ad66d5ee7f2b47d910d09814728b1b62f9a96bb01b3561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a69858f4f67a3b5e9c3d3d251f2085afc32864341a24d47e9febd9cc82915b557f200bfd455a7bf43a3061a1d7fd7b00000000000000000000000000000000062c33a018c4cc935b4b6e949e3a1a68c6f440d34d4935f3e87b6f12cc7c5dda80222ce9b797439e13ef622f380ca8b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbe7ce45555f5c5c739a940282d01e2353ed9d3d7d02af8781f3c35810969878f73c2c8aeecf9712738d3d16a4605330000000000000000000000000000000015e33242acb8458b785f8aa04966adae73d2a16ee1d53d0684c519b3deafdaebe22d8e0968f4b7785f73d6dbebf2f0401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001350e65f13cec9d32835d90eece9fd03719659dc389aa95db54cddea182ae8b00dc3479ec73a8531293e36abda9f98280000000000000000000000000000000019a1bafdab6291172ef4f4362f24ec4738c729ebcedd1230924328a4d2018d9d8f3c2dc097457e4f770ab01ebf4482a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008ae16bdd1a3104aa11e7aa52b439c5d6ed93c5713076aab60e0eec254ab29f45a2232e6b62a7b7babd5d78efda96390000000000000000000000000000000009b0b57ab0c22b1fcaf3c49c731d695d9c7527d05866008c4e882186bf2db26d6320b5ee4934807d55aa95b88eb62cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1b2c58285f5e42d39c8dd9c23b71551cab9399b664db05c7aa0af350cf3163f4a4a316283b0bf2893f06292f5b6fc100000000000000000000000000000000038cabc5981db9af8051b77ab548dfe1bcf53a330dff9dc2cd4a013a93c40538bf2992ca345442b00e446edc8cf690861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb606a6d2b191ce027889322d8e1b45a20830d3de2b20cd5e87e0eb6724319fe73bc82dd7ee0f49b53d83becdde1e990000000000000000000000000000000014d8c79cb808be6f0f18e44eca9029a129a6428026a03f836f9ad1766ead2883169ab3e3f7df2c3a1752b6debb9d22571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085614354b0bbd692928c69cf061163f5719743b2b701111a430abad8cb1d0a863b02941587a1cc64cd91897809cb5330000000000000000000000000000000006acded6565bb939e9861672e0c6a301628ab6f923afd84453c0de644bb9881abfd0893207bbd605c46b22833d65d6c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a5890fda1bbec36a6b1764ec44edcdd1aaf30b6e01f4a3dd32a22f79e4897568eb3d2a268ebcd8eb64cb01bc4c8778000000000000000000000000000000000e51d93624fa174fa47da1ade3adabd421f575bab5e0a6bd4579636ef4cf13a94090ecba86936392a6ad363c3b3323241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab7f3185c26803b4546a07176ba6c21d10160b0f6272baf9f5582c0bc1f77cb7d9f087f8d740dc56e13002b61da208500000000000000000000000000000000156afc2f4c4b0393a65efd03f27d212b00e92727b7b26b2277285a5655996d2e6654a4dfe647425e33d36065521d674a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063c9e0fa195753f6e639010ca7427fce0012a44b0c45f9c4a10637060f1a7c325a9027648df41dc7684b9c42af6363b000000000000000000000000000000000eed05a90ac8c4bfbc84cb90b406d9e9d9fc7ed718eaef2461184e6eef8470742f2d4dc10ab62631c18486541669fd631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001083ddc482222879ad5389d0407b4306b22d6e09b82700c236d7192eb9fba99c949d1b35612f687ef66e45315579f6e8000000000000000000000000000000000785c3e19aa054895f46ae8c744c8e412d44654283e78103867542618b63844f619711233167fd8820511647be55f9651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008043db79ddf6de0fa4e191d107ac7582f9758d6338d60119e2e8dbb8adf660f8ab33977668b345823b32753707260d50000000000000000000000000000000018c21abfa629e48f968f59b88c7b13fc335211985c8c35b934d99d2f698c9f6970980afe3d459babc76dcce9bc3364c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b1bcc317f716218b021b46aab74797edb5679b209674147344424a77c79dad95cee5e8764a797d1501c6b13b66269100000000000000000000000000000000028a227f7e264760590f46dd37d047b1bc12208d1460820ff7d7ce5431791b971594f7a24e4fff78cd8ae174c33e62c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2fb40ee2791ee92d899ceff8e709558e08136a4405977125500cd88c8b45c4b61dc7755deaf554e431bc20357b6857000000000000000000000000000000000d886bece81d486278d0002c26d02d15ae6f1a73ad0187d0e21f911b346847331efb93e191d7651584f04547ce1e88ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f210b30119c8066e9004167925f3a449c544f2e7d8aa450415dd305e48bf618c69f5b497193268ba380c314a5c53fa40000000000000000000000000000000002a48b3f05b359e9fd44ef5c684cf322b6b95a12ee4932b75d9c883e025b9abbd08a97ba4fd19ea303e6f7e02c7bdfcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b568eedffd1659a0ac38733b9cf02a012456ffaf082a69bfa45fcdcffc0dcdcfbfacb402a7c6b03400f143697af088f00000000000000000000000000000000114deab441b58379ad7c1d79ff7c97d30aefd7dc42cf26fe570cfb3fb5418c16c548c3c16cb80cf5ff67addf3edaea7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009246fdc74f70f3c8a7c75b4b225e0f8da8354a7a47550ea00b4dce290cf42e6540149113c987257088e1978c572e3370000000000000000000000000000000016b1d0a7e73d6207cb9912df0644901cc5f0fe309055293ff4e1c70813809da43ec2fba1707e6da6962d54fd322b5f791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a8055dd60d1b5aafbf771fdbed3f900e712b100384c77ebef21ca958ab417d9be1b6234967165659f3ed94bc624b1a0000000000000000000000000000000004c27e403332871075387d6af3bbe05fe19ad8d5f8bf34228b81d1a63d462f999e62525b0ba0c85a668d74cfb90f68a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016059012a0ea85605e9737a5cdbc223ecb54c2a857310532af9dc816673794363a5fbf0abee91917ea82d88bd87156db0000000000000000000000000000000010c11c12793f29e7550cd99e1079ad9b5199c00954c6a68553574251a6b575bc6b00d60dc9db766cf75a195e23a341b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d48a3b67394571effa194788addff8143eeb16d6f1d4db941a4ce2c868761a900e2147d716bed04f93cb9504310f3700000000000000000000000000000000000c1f954c4c367615b6a360b0f512159609d757552ddeedf1b7126f8e519aa7c57ca5ef77997c8c94f05d9f7022709f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084f2111a7abe0ca239c3243614c3cceba66ea4c21125c682202c720359cd45c0528f1763ea7f26d6b0b86966b5baaac0000000000000000000000000000000015e4514112ee251303ce22ac128ed1841445611d23c16374e4045ed81fc697e116c1a01212f66122d82ddb93edadefe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181011f7bd3f39968b0391c2ec9ea05040c9c0645761f5d6b36bc6a43ae28cc674e5f31fd07d78b2ded4e96dc9cd3084000000000000000000000000000000000bd32807e078c8ab3265a761b425c07bc1d80a52b53f5b1829d2106c047c98ddf08b4e0918cbef96451cf5748666060e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e31e54ec7da342987d51e7ba6ade67c1c6e48d61965d02484715eb8699b80beb4c962b4952dc76b2f48e71a71c8e45e00000000000000000000000000000000089963c41402cc60ac886b6310fd99e6f78b65cedeae54eedbb93ab0460880404d51a78accbb65aa19f5015af65e244f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016495aee4dcb189a41f7aba5a37b81ccbb5f4b639918caf8eebe5cb8c299ff18e0a75bf0d6085e077dfb99d27cc99bef00000000000000000000000000000000136af14e20e6962488603388ca797e4f0bc466bea3be06d852155bff85b7d6371214b54d75e9f5a0a8f915b107a04a361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005978209a9d5dc334830668f1347593c71aa7992148bfcfb83cd0fbfb7a6f5b0e95fe5dd3ed13f3b7e21e3a2dbce228e0000000000000000000000000000000012b5f08007623ff9373b73c0bd83be8eb430d040f7930ccad1519b4a533474b91474129af3961de5bfb6b671619786741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0595e1d2b0b4acfeae86e6d1ce4bed2dffa93a926af60d13b79c73fe23d800c85d5ace834b7e7b536cd0437b300714000000000000000000000000000000001465b7a1886b584b59be303268bb5ce42c33243a70542ec2d5c4baf7e9b0301a90b4175ba639b3a3618e33c219ffeb191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112388c93106797cad200bd85848dca83930a06b34d3c8cbe14566aad8af176d47dd997b337bf1916bb2cce3eb712b870000000000000000000000000000000006d1cf43c1a256a9a4d84947d1d2e93c0006c30e914ee31095e6667f51cba80c1bb9fe8937b2b240c8c65e24e4f1d3f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012deda7cf221d0fdde2d12ed17e569f8d8d3d1655559edb955eab3f22da0dbe349b3e415fce5b168330cbd00515729bc000000000000000000000000000000000669a46b8e6911bf6173ff4591e64d03432a568760418dac6beea5acbfb9abe10f2fbf3bc2da1ba2bc7e9b700785d39b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dad86a923ef0ef41f177744f72af35a0bde7fa4611c959b18c14dfaad477d7f555a162fac21e011a9a00d43a6dd95af000000000000000000000000000000001086721859b47fc3831b525df6484677d28d9e7d4c59c402db1a48a2c95cba2f6b3b0ab695e354fc01409e64875c28591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115b429fb38da1d3379c84e8589fbd8136a2d6811537b7911bb72443b803214d3d55dbc4c6af95c386e06a484d9eeb37000000000000000000000000000000000832e5aaa4fb58058ff6590ced9ae289be5a804ae6bf49611cc71a3c698d9a521d343e1d5e8965d8ec6203a0f12795d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb4d9b18925fb558b991e6115c995a6cfb0b948a658c910384344cfd566ba6fb82dcfb10e45ade8ec04211119cd9ecc000000000000000000000000000000000a7f84f1c839f46ca6b1cd9b70a2e9e91311f1e9f3a9587ef5e6c487c59b7777928dd8a6fcf4dc5a9a18adc653e61d541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106668c6915e31c2eacfe0e558649567b3ba07eae84801ce56ce37d5c19478b372350836d4e402506c67eff7b0e69f3d00000000000000000000000000000000109ddbd91c434c9066f0fb7332f00d5f0a967eea73015913947d2046551cb53b1fa42bcb02e37aa643eaf93f72567a931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e6dc40e081fba05ba39eef81eeb1537ebb98ac5dd23373a81fd0723691bf0c9d9a6343d2899ffa8c1cbc92dae28f90000000000000000000000000000000001956d62844570b7368e2f07023d052728bf063bd9d0215e0f5e51cc927619822211b4c46fd6830dab5ec499c9614e0761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000425ec500c17703d5eeaa85c912a427565b434dc9e8b7252b3d8447ad23e17e8348089d5dfcd5b830e9bffde000c864a0000000000000000000000000000000012a383e361b178ed0cf9f81a26526869769f623728c72d882496f581a7ce61468d894565c3d095340ec88f527ddce7081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5c30a0bbf8bd711d026e4e961f0db2a9cc897d50757d569c2e612513c2ffbdba902f6dfcbb5e243b2aa7f70eb7576e00000000000000000000000000000000024b20d21cd49e76452bc5fcff7fcb987e1b6b9f37bcd11887b9c463888d0bfb3e0d3533165c255a2ef7cbf8ac96f6d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0a64d1909ada32c43a0cad9387c2dd01ce2d0ce6db5f5588eef1e3443b92d1b0df356d7858ed3183791feb4290dca2000000000000000000000000000000000d63ecd254ef781d6dc59d2b368923b652eed204c50f3dae94cd3106ff4f2e1a21b379e83f16ab02409d89da56d9e4991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f2bce4d90f7ddf9b23e38121243af0cbdf18394453cb0ac472e61c9678a9cc6fa5fd19c37837b029468ab8438f41bd0000000000000000000000000000000007541f9a17b370f212d248dbe3a1fb83b356cad5bfdb890e94cc4c7ae74fdab732c1277e52c09249d29028cb55176b521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a50bd4b0f42352d62fd1014cb215d5a4d64558c883af6e040553ed5da1b5da9de7ec6544756f32733c6af9730ad488d000000000000000000000000000000000cbab31e29efa431ab797f8a85781a3c7672a0072adf499598fa0471a92956bd4f15d1b45f2ae243b11331a9943a2cf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000174475e4f0b6e5070db8e6ed290f28ecfdcfc304e96e50f455979ad120867b6247244591f90ca6ee68fb22502a82d2b0000000000000000000000000000000008bdde38cdafeecf8020a7274acbff14c4a12ef1a57b7ef19d81dbe8329c4eb099d1b5b954188149498bb58672cfc5ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005a5920aa6776e5fc442c0a85b4ddff1fe449484f19dd6829784946c3838b83b2d6bb0e67e7c438d24d0ff8908f99e90000000000000000000000000000000018125722af1eb632a258b126e4d9b324217c5a05a75633fb9b1c3556c4e37bd5ef6475b24cd855d89fd0fbcfca3f9a7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119324a5384b102195523cd5c68cf07d9c4eddc96bd69d7c1b1e4e31ee8dd633a1a6aa484bc59022c04c381ba54121a000000000000000000000000000000000091a1158c1de661f8fc0b154274dc52b92694ec7abade552e15fe97fe9592c86e4df0f642ceeb6238669b71af91fef841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001592d2e3f6216054ef981df453c6cba26ec695e6246cb6b5d9389a12e4258942f4c0cda3a717d1cc716b1d6259178cee00000000000000000000000000000000009443e8d0b7c79f70f38f7cef14aec8faf512ad77d0cb38f32c9d57afb9732a4bba39b5b2d227291ebf4cde6c14f3301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049111a1d44b7939723e47335d854861ffbf06829763d9961a1811b403c68736463e825b27e0f4f7d65653fbfcddc47f00000000000000000000000000000000039080fa964bc3e7e0aa04b5545c17a1c632a77a5f2c4689eaa6bdb530648234c46dff95fd7cbe3001a066c10a2ae7b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021496f49c7199bc9efc61948701868328e171eaa86f6005f08bf9742b67ecc877cb0d11ee6fc9db1353bbe67cd9874b0000000000000000000000000000000009d68f389c2a8abb3562d0f650ea44953e5482c8b861bd88e88d4751594f4f3ab901008880b58ebbc4b378d26d59b49c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084691c9e595e7cabe1637a271eeadd29087276902cbfe8ac37c5cd4108b963cc21b3d77411869dd53fee7fc6d7d7b8000000000000000000000000000000000043712669686cf41b0fc8b236f0b244a715db835da6e6365893b88efd9318a14b592dae5a8c4af48431269a72b40f81b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183e0279f3cf502cb280a14368420ee1fc8cd975a33c75fb50192f9c2dc063810bb301afcb813acf9f01bd41af4a5e2900000000000000000000000000000000124deb6fd765f33646a0a25132be9ede1a7536f5ebe34f638bdaf9c91aba22889b84f536b0f15b0d2047e991a3d3b5411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069a758ec8e948da7d62ae6e923b3f6c9e3bd8888a0300940bc150ebc7052912e51cdc3ed5f654f2658f128a0d0b0fd000000000000000000000000000000000160851c1b4655b6cde9d75a199c093c092802e7bf9a23b229aa5427f3c9f5301d67913582c69e937902d1f5438c7c52e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034cc953e434ab38c32d23f0b620db17bd0f799cb9088f99e47136093e15275cab448d2763f4d2bccdee31b4a9f64df100000000000000000000000000000000041e855cd9f9ef39588ec4a5a445357a307eaf6aec689e0bead56fd1f931d70de3c10a2fc0daa883a73375185edf35851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b66a076478283f61e0cdc69b289efc7b32e5e4aee431a66a47648fc67e2e00584dbd6cf244a8db065c0297cdfa4e62000000000000000000000000000000000667475e40667d5c72c2608732741dc0288d7dbd63a3239ccbc58ef863e8a98af450ed9dcd244962b3f5a76051fcfc131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b6e3302a1c2dd6a7290c1f77d1401f2538e58b40587a984ca82c889b2f7c3b8df6d07b00831f17458254728f97b3a80000000000000000000000000000000000bef5d8ba5a820e8ecd1be3329c92acd80384fc41e87c0586b71c9c56541528ccb6d5c123b07e1ff10eaf310c3ea7aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f21be1782978184848f41f0c9289684b3de983546fb84e73ed4cdc860c1c1c1319decdfba3b3da0bcc54474949b95c00000000000000000000000000000000162a2167262e080710ca0369040d1439285cc4cdf1f326f9c4f6193b532d25a110b0fe7a76b14f3f5a9bfc427829e0631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd1a7033b93e0ad07c0fabb079d387b6e85b6120e5b9e704918b6c34f449b53f9b1de9dab11b280e09f98e268bf14a00000000000000000000000000000000003c3b4791555665160e25319b22d4b5b05ba863b27c948b0a86a1eedd359c96263182cf3a50a2be3e7880779d7318a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b79b794fb2155f6c6c2a9e33f11bcc40c7d6c6534a1bb9d4bd40e332f01a31409a3fa6736de981aa77f719751874bb0000000000000000000000000000000017036201e6ead8bd4529f586c274908b44e4bb78eaba10d9457fc3eec811514558ae39767f274383fb25d9e21e53379e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180554e41066acb4835ddfb8a45a98917b1b7a4e6e8bab41dde955d69cc777cb991cbb989a541b219fed2694702adec900000000000000000000000000000000001f9690d83e1c2ff099baecf55030308eb89f2f88dd9b8a5b4054564ffcf7342397ce7e1bfed983709470c703888daf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004325298ee0128815df082d268421ca419608e9d65a68a7f5d91ab9e5999e5dc78c88387da124612a9d462f7d75c48bb0000000000000000000000000000000002e205ea73fa7a04b845ffe49e0fe2a992b8b37271097e7093bde957df9ca628e8241790fc2f1803fd62a33c317255961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086ee42724934c38b69a8f476a489a6779b386144cd3fa854c088c0a216195029b7c8fd31a597e1fd7c7793ecf8b37ec000000000000000000000000000000001296fe6681158df4a334f84825c006ff5e9552a45630c1a3e9730da3b56d7e7161ea5e4b57283cde8167689f31b5666e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002528ee7945a07a0c149819edd5bc01efa131f8d7dc17859904d69974616ddf16ffed7104711482582861a9a87e42d8500000000000000000000000000000000031edb7c42d73d15e9184275b933f05e303781f0a15f0d0c9f95f56161fd87c638262c28ef692b759b7a45c77ad8fddc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fae5969ee0a1b28a68900ef8427b5de0feb306265812b6a1b9259cda7326b5e0cb2c25061ac7b8094c878fd435664a100000000000000000000000000000000075f63ff43c737f35ebd0c069334325941e97ac9cfe4aeaa58f5d2213dd7d9cc91b4b45da037040365065ba10d642a3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf5407251c0dc89134b48450ac51d0e63191b40191d0c6de6a1698ec0f830f002494b5728142d0f08aefd54c0a11b3f0000000000000000000000000000000019795abbe1a1c93cad03b058ae38bd5ecb62e893a3fca5f63da48d11e3b4bf0e6b39a58555a4fc247eb80cc077f19cd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049bdec2bb1d254dccc60abc5f2de6b2936de9569b45542736446d5021708bb1568166c2bbf08b1d1639d1d9cb2e51bc000000000000000000000000000000000ee5b5196c35e1ee01f81d8e0d4afc91c71527fb966e466a2c67356698671751941d0e8f1fcce4adcbd1c95e41ff6d551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010afc8d67b3a804ddf374f9f458fa14f114817a0ad8fe78ce2feedf7edd6a224b46cd59fbdcbe4e8c2a5309ca287b155000000000000000000000000000000000d535d1e367cb2aca480ea943b189e400d706055f898ff2f69450690ea26808a086b0f7c036f5835c7ac78538f5f80591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015391a8f5f46bad9d3ce0c19c44ea33076a3b3c96d9ec9dc6d4300e21b45cdbf6b81830b3983f31cf54af7b8923b0fba0000000000000000000000000000000002ddc02ff93e2c5a3d2b8db546746ebd9520d1d227878463e8fefe93432c7e90f187568035f0754e3332cbe2d1d324641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7635677ff39b74e3241528a5679d562b81f8a4e45dbabf5f9b5092c0c49e6065d0265a9ef8b112694d3643296cda57000000000000000000000000000000000186987ca787a8a3f71ecab13da2bf4c7159afdfbef16eb5608f55826cb21ad88b7f5b2f1a582322f1068c0cac99f4b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001217cf74aeac2c72189d2ee2173ee8529c0abb2e7c2449cf089fbfb02e39453b5e53f6be6a0bd63e330522e38a95c92700000000000000000000000000000000159296e25ca8690dc30a18c3e82be208d8e88e8c0bb8935d351e28aff92fcf6edbed9011330cf1a41bde71f6ad72ae2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f78465c45eeb0e514c0389349dfd0f6111ae995deb3fb9984a4dae5898e6f3326cbf5716ce06b1b08072b07d8ea1210000000000000000000000000000000009b588de3c78cb46d9b1b0a2c97d5def861dbcfe9e709b136a54775c2764a6945dd90e5c96cf1547a7638415c0ecc7c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000359b265ada07ef3dad974168226b39e163c3482f69f9935276d17779b665a3ce7aafe7858f4731e2dd5a3369c5d20a5000000000000000000000000000000000cdf30ae1e86f4d5632ab1936ac45689d6bbf4515fa0737e76d265d6366ac14339e232486357254c2b015c46b5fb00001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f25fec0b0e8a6cb2d9d4747bdb2a58ace6645911644c3527d177a88c84ef973e8ee3803a528c264d13531fb7f97ebf1000000000000000000000000000000001095dedfe38bda187c2aada8dd68622e255dade82f6a21a671733df91167c7912512f71bf88037586192706b590ddbeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054044e06122f5febe575b9265e9c7b9ddbdede97e3a2d827365f9c27503bd55c23d4281ae86139ccb916d9f8a4e3bef00000000000000000000000000000000131aab04ef91d6899617bf1a6413f887900c3400b2c87611df691c89d4f664ef5ded56b7533924b0680f1ddc3a9308b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8c541453ab6b04a055874957a5882ef85a81251f9ecbc72a24e6e574f3ae6fd078e29a3b56f9486fba7d5de024159000000000000000000000000000000000004de411aeed7a9d2748d57b2f8b131a9a28341d4fbf425eecdecb60788ca81ab7ecbd4dfb033bee0c74fa0d8a6c31441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135f8342f7e43505ab170a55e4acb6affd403071dbd495d6baff2c93af46f792cf03a03f7a78341bdb984581b340f8eb0000000000000000000000000000000005dccff2ebbe47c68cdd4012a54f57bb0387da4063f6391a9d51a4aeafca350174c0fe0b4b86d0298e4d174334fd7dc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e04541112e446801783efb6f16c7b72ce80a6a58a5df859236a49f8c76f8e8afa8ec1655d52ee7907380efe139917d000000000000000000000000000000000cbc1f3534a09ea42b2702b370cce29abbce7e0805f62408c33c32e5eb20dea2a81b43bef69d6f39b143fc7313cf9d281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049f846554ae4763cb83e63562f52a8ac5f19e596f09461948b9782f6aa823b07337615eaff0659e19119344476eb66b000000000000000000000000000000001734f653d089cb5f424ce0b2a66664badc32b902947f0c18732fc19ea9a8852d0cce4f5c8716159d8040580508cbbf111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c53ec787c86753590b422355652c94442ea9e6815d0b9fbc322b0a339f47af9420ce66555e7a580602a13783f0e229000000000000000000000000000000000729057b6581168afc5ef9d971e8cb80612de4aa54424c1f3c7a5234a688c836204a368c55fdb2502ca5fc5e43f097971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070d9c928e437ffd40ba8d0f432d58e51ecb0f9ea52f2331aea8cf3fb9cf2275ffcf1dc3b1340f50bed9b5c200480a6a000000000000000000000000000000000165f3540a1e4f55ccbc0d334acd2560bdeecf645cf52dc4412a381aa67a7edadfea9ebcc534a43ccff98e992c64fd731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9da4712eefb1d86a62c9de1fe982b984bf8c0d72d4e4dac8e0e566fa1d62c44bcccdb6bd6c97948635ba0cb6aac92300000000000000000000000000000000158036151024aa3a11863e7f5b650e9854f7bd0fb05872380e13a7944451d842e10abbf8412b2caa4b20ed8bbebb4f931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006a6dc2f40bd7d050f0acf206620f9b935a82a2257b8586c226ebdef0a81196ef321413810da2d115a9bb5e032f214c0000000000000000000000000000000003e9a178816c3a6c5c4a45d3390e88a42bdc94f864b91648421cc8f5e6fc60748574bd87e35ed9bc517f2dbe3f438d9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002531e21e97ae19660aeae3c0d56cc11876d6d4fe58cacae886b749f6a02b401be21ff1070347cdde8ba76211a275021000000000000000000000000000000000d80af3103c4f3dda17126b2bd5559f0e9f92cfc9cb8264857d3015fbbb15bbc5ab161e8e7151ebd573f7b0013c360511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102e8651e2421735424b9ef320decd63f820f9efe0bb5a14493154da699d66cbee852d9d8a929045173651748d108fa70000000000000000000000000000000019b7d775027bca8fca55ec5b14197d24538f50c1d62117ab0f0ecb48fad5fbcd2cd3d98bb419d12be236fa9d2da6a88c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb04916f15c866b2073e028a3eebc223ae984948304635111ac89c4380fa31326c62746a399cacbb1bb39f1b4eb5b00000000000000000000000000000000006eaa328e1cb84bf62de0b6da78852eafe9f8e0fc5374e42d81743bf2a4016b492630d3971e1009e45f4bdcf475992f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf2be054b9170ee2395fee23fec11ec89648faebaabfb7613d33bc541b8de1c3e4c556ba0cf66716d8aeef54c6022c5000000000000000000000000000000000acbc109c68bba2bb82b5af1e7c2939152edc250b8345e74bdad28ebaff9528ddf1f2ad88c7e62cc46301c7ddf6c39261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084c02d81f351c41d595323d466047c1c9238e2ad8fb78f8e8b54bb18fb3413e7993baebaa5a3471837676eceb19b19d000000000000000000000000000000000245b93a58d1e270de67bf339a8cb715887743e5e06d27bd2d83e2944f8d04ad400705bdec0a22517005a77d90aea42f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ffe5fd75a4c015af73d5f649ddadb16c0ac903b4fcb2dcfc89868bad85fa7ed30760e4a693ef8f4c52baccef40946f000000000000000000000000000000000941270a752797ac9aa59d512d4e743283fc7edb46dc7d28a9f2af3e6dd40c048cadb40e0bbb2a912c807de6bd249d601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b946ab2b7b1b3c1f825a11fbda43abd3cb8b84defbbf7dd9d68b7d8524cb090840a8cee5ae60d034482710d7294498000000000000000000000000000000001287d71cf3b16977ebc42dda57fd79595101720ad3f7775c0025896c34c29a1dfe4d9544e632a1581deaa268523d0c811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a041cd121b31ae08d8d185612418b8a624e8cb0d0935bd02d8de025892200958b67f1725bac629729b0c796bc5914c1000000000000000000000000000000000a52e73ee5f3be4ca2f9db6529033960d2859976e829ea5dd1a8750486b4584aeec720b27af8d44f84e543ae6d1836ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032a460af0831927d192f8ff6933af6a8baecf566c0f322544a8643049163aabbd5e1e657902d0ccb4dadacfecce33d400000000000000000000000000000000140457699590387ef9b6af0813f78d7038a7b120f039b90ad99b2892a0a07268bf7ec174a2227aa55d556c9afe4ddf7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001058f88c192393978eae87a87aea76b9ea4a9a52288503ea58cc9e7badaccb83cf3a4cf3030eee78a520cc7317e6286400000000000000000000000000000000091c91ce18eb1dba13770555ab0f151cb2495873315e53d5839976ed3b654d555000a83d7ee21bf2d9186a73958c64cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d17c6c9f78911bc0ac04bab3de11998a55119b475ed721bfe0050c81725c1fab79c8243dd90ab3c0eb1c98d9613f8a00000000000000000000000000000000171992fbb3e78a22045911feb9f959c6efcf790e5d48318514bddf7625556137a9773d79202b4dfc55e705f93cdd5d241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bddf0f9e4c28242328e58b60ec912501b63a6b66f2dc5e1e1faa199d74de0d8dafe8ebe3b9bfd977efa16eb1ff0156000000000000000000000000000000000567092e9fc807ea56395e0afc4b6b3431dc6471d4bcd00c459bca676425c82294f235cdacaeef74a8f4991bd60b4e8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ea0abfead866753b81a73844ab7529d979c81a4fbd5f76736096692d6a6443e6ee9f26235e9f905246964de9aeed9e0000000000000000000000000000000019cf6ecf027dd75dd4b2aaeb89dcbc39d7bfe40a0504eace832ece56d1f3e79ca8e94d3e5f525b1154940174f1ab85b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086ef725dc03280911dd63f30d8adb0dfa397bff6d679a9fc6f2c3c4e59cd4a3c48133e7fb135c30b9d1d7af4d9033e1000000000000000000000000000000000e732bad8dcfe1a219ce87e3fddccb59568aad421afd4f6904aca4ec3b62711995788955cf789a2278115e73b2f03e271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f49c016d706658e33b5282b4361a38be67c5e066760b50aa07e0bd537817571918a3532c26f1fad7937393199dc122000000000000000000000000000000000eb5afb13b5bf29eb03fc4f32d0004c75bb0c20cf5f545b740c5c99f76877203204fc2797457c84b3a804710f54af5571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071b2f270c3982a3b526d5f5091b84e92fd2858f4f8177b9cf1ef3ad58bab50e611033ef539a909e05bba45d66a8059c00000000000000000000000000000000074a7f983452f9910911265021a04a940dc26b1286e5317ed70065d5ebb5f2a0d0bd210253a0363644a07d6b67646b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014995c353ce70ca641febf073d06e1f300a1a669effde727c7a1ef99f5e8bc798044b1bef51ee1e611f60de8415a2f4f000000000000000000000000000000000e2b9219382180c2901e0d7f2f61e91989b8a70946e76d4e78ee5d96a6e1f0245744621383f204523118b3f7c3635e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001370eb00e5eaadc4e69e2ffbbd48616061069de2a3fa762fa306446cf7f3f929485111753740d9fc66025c368d74a5120000000000000000000000000000000007b9700b11979a536c283664599fbb89df9f8bdf73c456e8011b8d3a53a31bc418e4d6e9ce48f098e3266136eced02d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eec48d4a4f33e04fc1c80c666bc3f9b4ea165ae961e8b284e9fdb512f50f906c51957112ba67bb4e7dd4f4a0c253b70000000000000000000000000000000002742bdaa8196ad6fba002eb0b1ba74e44a0be0fa2a90646c3fd7e3598bbed3282b15339d7577e4a64a374e43c91be451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e315481e74bd37b9c7782f72ec1151f631320c5d20f86648e8f172d4b03a5b230c92c85e00136520dd1f8d2ecf21d7000000000000000000000000000000000896430bf16dc35d94fc66ce99b2b43962d70571f5217834f135d9ed506579f2c4c716d74e9b1a797cde4190beb72a271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d143dafd5258cee86e483dbc6d6cacce2f54493798592c9db6f29aa6b23e631c64398b9800ad1028968fd21702a9ec000000000000000000000000000000001903841ee27fa9eecb3e4b87c27daecc51aa08a2ee8ac5c107324f02c5a7dff66dbc680cff544ee0d6014e80f82a5b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003118c2e408e1a0a675a7d81a4083922269ea3a526f60719e05e941408e2a63f46798c12156fb44ce727028fad8838810000000000000000000000000000000006382dd4ffdf4fda1a71d7c5dd0825cd7c66fa59fb59044c55dd01714737b2d4eb06635d69d62419c645093386de0eaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004685ba3662d6789a40fce48931c38b97316364ff0327ca2fd6e64d2a8e1b2d417f7885ddfc3af46f6b2710cb7258c3e000000000000000000000000000000000996942db2f57cdf8a1dad785215508c73691e2b244afdee3c15f4fa8c31aa5a588c131416cac4413ff2fa019d4040841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001177777679c9eeae64cfcff5abb9a4b01f6579e247a04a63ca7e42937cb8c8db102b410fc5cd90ca4467d563c14ae153000000000000000000000000000000000a01858f9d767c3274094131e14fe7c7fdb6a9017ba70087c5fb9ae3af9c4ca9333df617851ab1548076955ff88d34a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc0b03ad66e0c8335291d7fcded349404c6c3b02c986a0516634297847e0b16b9fecd16e640d4d36d6753d505fbc76e000000000000000000000000000000001799ebd179f06038bc8e0d0252180729eeaa3b45ecff68bcd6e4c69f270d23adcb00427d4fa1a8f117aa5d28a09b183b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001873e3c2ff5146704d0b76419f29e242309b0ce31cd4ce9d8182bf26f5ab12729a0678a291e5d6d89626733280f7b39e0000000000000000000000000000000009fec362982a9dcfe8221a71e8378b3d5d810002be7a66107ce0d92238897acfd576e0c1131be29003ef3db01ba326311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088cfa996572b286ddf4105d5aabb4cc0d4b93344efb5092d73a841d40f54f8bd973a1e7bfb9dd73c094942bfc8ef311000000000000000000000000000000000fb3b59d239a22aea27b483bbbf81f1a6cbbc6e5462d02ce8d3a76f7cb4ff94810a0327bcf5e74efa027dd28b12f09f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5bd22977c15f92d4f4ae9a295cd76d32ec379fa4279f409e0eb9c4ee81e7204beacf51493e226bd01831cf496944f500000000000000000000000000000000161357b9a8c8032342d068418a63526b7ee6e465780bf1a4408f21c606d84a0ebbe87e95207ec6c0ed2b3659e38eef3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038c949cb93a367c7a61e24fc45a0dbf249bc05c210f9ef4a222e09c22d22fa6e305f536f80215556fd786e19642a11700000000000000000000000000000000170af6f62e8d037bed6dbf037cee71d2d3b3e7ba228eabd1910835ff4d391f414733b631dfac9a59dd0c01e6704f740f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bc41c1c663b4487aa4989e8f9eb8038bba4d113f8857e15829b075f7d8b4e63c51a332684ed709865e56329fd02042000000000000000000000000000000000de477cc7e66fd6a285e199c8f384a7c48af70c3c0c971c8585d3dcdea2ad0b91be2d3c824c52c3ea1ab1b9f31aec4851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cc8891c58282e5c4ed86652910efe4dea4e66520cbc764ed0c861c54773219ab5bd449d00fb89445edd6ef3bb0667f000000000000000000000000000000000208a18c217938d0f23325f90f4526b7f722172608776c6fb48983925b24f46e9a42cc41b9f06d828cfd5b6e35fdcb711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a1e79a8d63ab9a6b5116dedeba893e38e0f39cf6b5757302e6cba49b28cd18ff4371f5245226bbc0dfdfa430a32d4400000000000000000000000000000000179ada57f867261b55ca30898f5a72f24673e0939f201a61063417fc7cfbc7cc22a968fc94f9d1c7c566194d156167251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015e5736b55b840eb92fc3a39ebf0b9918716559d530ade497dd41271b2af51ef5d35798cfdd75607e3375d4fcfd050f0000000000000000000000000000000002164a8f6108acdcc7eed4a7abb2edee188f07a84c24fcc4847e7c2c840c8a9e22476f3b5e5a0f6ab2c020d13637342b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000880a5e849097d7f158ba1efdce01b4593be8ce8d9e26987ae07cff455183e41782349364e56333f3bf863d79bafb133000000000000000000000000000000000581ff810ce40be640f78cdabdf7fd1c03705cac3ca9c67a308f8b8e14618e264b7264007d230b37e331d8717e88fb441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006723e727341a055328117635105d920bc562628254cf3cd15dbeb612af63d9436a1118b115baa75160a56eb97f9672d0000000000000000000000000000000006d063bab2c8a95f34fb715fba6dec4f474bed6d5627e99727bb75015fec671879c4ad71a33b85f7b3deab769b421b041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f87517701aaa211263c35fa0719d0442bb5d610ec0764e79f7070dec93eb8ef418f6ec0ec9001a20e121fa6ad0e6242000000000000000000000000000000001334270ccedfac10af4af0ea27c237575c65f6b6dd9be35e8534a719dc9d7b584164428fb72e98173558b89517727b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120df0d7df5b62bdab0c60e598e1d440596b97691a7135699ce582209f7a75424d0cc190276b1b8ca224b0b45553bf1900000000000000000000000000000000120d2a4abe9965d7ed3e20dec60f66f951e3da8574ad3587a840c314532cc943f9f62824251022de29fdc334c80f99401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082aba2d7cfb40caeed35310aae8edad4d46493fc490de9f3c87e178c21adb8c714623e7146fc2e5ce6d47423f74f7e7000000000000000000000000000000000578a554e8d9d46e3a925e53a65d07927786aa294bb1b64b41bdd2920b4df7dd14f5b2f3f710f4784ed97deeb72943c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082d21ef9dd2a6e1fb81fd344fa462cb2981abf70c30b31e20eb696c8033dcfc71a555589bcc56c6981bb74735d125cd000000000000000000000000000000001718c95050b1d07063a02ba2cd5851f78c57129485b697b5fdb14e06a1bf640be7d211d98d3046b7754508572e5cd4f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d4564f74a6e48c117b198f1cf6a67265f31cc359b175f1d48a597f06f9ac159e7591e42fcfa0a266d6c0963f46aa80000000000000000000000000000000001728c0b2da069859705e604aa6bf6fe4a0f322c14a01f968a9f1e6d4672200dfa5b3b4024980e2fb0f6134e342e3cefc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000561122d0fc951ce6c6b7737cd6376270e81acdb6370f07fc24555ed4e874b25e00ca6069b591e258981fff31d44e0af0000000000000000000000000000000016ad27b20aa2bff204f5aacf0e990b2c2486c90ffc656cf5c1d2b1ce16c1c341f4eba2c60acdc13275dd90cb7fe41eb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148b2d0d0384bcb9a26a373b35b0cc9882df1e6dff6256ce28a74c9a6069303d9badde5230ba77ba8aa3442f51c6acb300000000000000000000000000000000126c90c154470bbca9959fd52caf04d1834a172ed11843d60f624d9f36ae1bb1100b352ea314dc9a6d643b1a1924831f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000589b21b1d79a615a8ed74f2a8e27fa416b9eea6898476cfc08241adbaf2b1c92b9625d6762d6b1b752e09f1220ac9700000000000000000000000000000000090542d2a9feeb380153966f7e3ba0af9646b83317e6236b4e5cebd594b913b4ff957a31803714b948d75b49f977a4c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002882d437268b6eba31d1ed1d5763f608c9c4b5f1cbaab50efb2369a30e7457435d34e086d02f1f6d4cc2e6ce8aef9ba0000000000000000000000000000000002ad711d14d30e883805f2ccac970ea5438b2d44f3e66a041077a48b7c92d487fdd84a4c400938b19958983e9b8dabd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147e2d7594ec31dd4b1afb58bcd88412c4f9d88639b043eb4556a23ab0948f9536169aa0006dbe73c5dac859288ad70f00000000000000000000000000000000023f5a4d7deaeb143c3486b5053b2147395711e17b9f0da379d508c18cca854e7cea70cacc191c52e04b89c3dd19ea3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a49216c008d61f896bc647eaca4e497f2fbc6203510f427f2a5052fb9fc84c0241ccd70ab9cc744fe84c022d2729ff000000000000000000000000000000000a0732103c03bb4aac33e6a0cfc64a5d15f88d71ed241b309a31c3ea31f46c09ad32dd6f647ac2f3fcbab218ff505a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d78b39479f0a484c46596d2389269dfe92fca945555b6325709b0c9fb84055b5a7ff20eb700a302db4bea383cbcfd510000000000000000000000000000000007f1cb60cccfd1d99717345b9f77df541a5cbebed2a8cb2f2ceb77c830f759a81440e442f15df32b0423a7cec0d10e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac5dcfecf9fb8ebb2f7dc020dabebbff6a23a7169abeaa6c56b2d6864bee3c670e5969792dd9a21cc2ff0cfe25c5e76000000000000000000000000000000000e3fa81d3234eea9a4de9963347b914df9a92ed370e9324640c65f1a793fe2117160fd4c227feebf29bde9be8c6bb1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001811cda8eba404c5e924002eaa5f2c00bbf209ea2dffc771ca27bb1b7e197b40886ca03b973494a04e544c7b93d81282000000000000000000000000000000000202f96e7c1ed89fe436f7e625701f36b4cabc3fa4f558294c6ef88388675609f15bf01af16477ea178840db8e0693c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004d5f91496afdae36cb2f871542cad498f2a3b77cf6e6e1e120477939c3b2d4e0297a57479560b540f1ca3ab665bb49000000000000000000000000000000000263913192be2d0f0e1e5b2390fddbe6847c450a532ddf422771c5a55823f05381d12faf0d33ad52805b78cd462ad65d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131876acd7243937be8a38b724b2c6687fd8c5ae13e1d11f61428e179fab211bc18332598499237ed72a0ad885e6791500000000000000000000000000000000128a011c0caa0673370303b4f7019454bdbaf54bbe3c97c00b32da15570dd32c71551c6e5c9ec6a503b5d652470c9bd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3789124cb7f90bb08edb2fd29ae626358030b8a9c85872bc7bde39166166208cec7ba6ce1f70c5273b13e25fc0896300000000000000000000000000000000159deabe97d1f101d9cf236b2d33b93e13862e11b0097004151be838bc160d08c42fbf71a0508567fcca96ce530d14a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002fd078c644724688ccfa8f2af24bf30d0c87faa0d80e2fba66a7024b2f3a2d958b526f850c31c1651f44dd4c6373a5000000000000000000000000000000001760b1b0c08eb4c9a04d3881dc1c2d3d3e1ca23018f093a6e64a686d6eee8174960ff71b9d60b8935e2956c4066610691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cd7bbc9c22a7227a9df1e5fd5d8e61a6e90e73f122dd9d7f20628fc6cd675e901b5efaf0621f08096e6b607eca136000000000000000000000000000000000166a2b8fb79d78c5e60235595ebfbd0cebfa9d0438bd0afe81f768ffb0707981c75afed8665e53753daf20e5e6edab6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef4cee4f157c391e2dcf43462b474db45fc584160daa74d0bcf26676d6546e75eeff90583cc506bfe8c7aa4dc673b83000000000000000000000000000000000b00428dddebe423784f17c9d1d7d29ae5defa8bb122b72520826ab612002d30abb81d2b48e6278a64a26094f241b84c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009af6b78417a421f291db660dc53397aafa63f1cee05d4d4c5d29e1c5c534671a07c48f551667e3977ab8aceae57798b0000000000000000000000000000000011c7805c7d26c34339d95408eea866924f72bc8874a5fd7e3b63c235dc5bbbf16712b6c62551b3d682cad6b980f6c4941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca7d96635870b64315914df2caf5a6257bc120fb5aa662c9992e669ccd6b2ec1ec9532fe2b9286049b2c55dcb68369e000000000000000000000000000000000e7b6144bb6d8c2be680e7a055d13d2fed10488c79a970366079e233d4671606b5f3b7f913c4a7298816ad4e987df8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112e0ffa0db03ab916b5fd93c2689b64adc611d8c271683646af54f21486d9ec0974f669660ba3cde94b297b534a006f000000000000000000000000000000000eea32952ec0d435e56320aa3f6e90ab19db7ecaf5f77c57a780ffcbdd4ed208b3ae1f948dcf3172dbc94f7781f1d4691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001800907f96f8171fe646661e77bee6673c002d06a67a0d3360266330e638c4b3a174b26427216bb420250505d2f9d645000000000000000000000000000000000f45d5cd984bd2c1eab642b148253978ccd99d7231717d98fd43171b31cf34af87cfdc1f2dbe7ce3395a460dcc376a121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003957c25906e16e27d8b76b009057987dacf368189ca07ccc81ab06fce6e0254ca5e2d022d50ee6a4a7595cb0fa925ef0000000000000000000000000000000006410a835cd298689924f4dbe73f1dab40b736cf5e6f9ceafd3a5c0b517ca9fe2f5cff603f87c41956708c2279ce8ea01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000033279a421998acc68ec591f0cf320bfffe62bf76b352c47d1c20b3e267ee515a5f59a379c816cf721c8dcd79933598000000000000000000000000000000000b01308d18ee0c2f1baac4e52b5863ad48cf9c6142767f320c3e9fac2fb15b57db701f37266ed75634cfba435f6f58051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001214e9e7d8fcf312660575e6aa43232cb24a6af853161faab29a3f5e72203b7f182799ea674bc5df7ae712ca5bdf8c2f00000000000000000000000000000000144e08551eb29c162405e4c07f86fad025ff813241d1422c73cdffae893e6099b63e178fc830b22a0c18b2f98e89daff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014cab54feb6fbc79d0c0ecd8225e25fe27f9c9dd6721b69b8d383593edef543d53a72e291e13f462886090028b424400000000000000000000000000000000018ed520e6091745758e9cc7045c3a1f991a9266880cdfb46ace386ed53762fc5a7f9797372f3aa89f09d56c9ceffc3b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bce6286ba886cdd66264ad4e0e327a2f4376f298147e0688744c0272054cd6b886285aa01c3224ad28120a7aa11d5630000000000000000000000000000000015a2e71bb67f4c40b5cc884f3fdeff809932ca5a4629b9f0e9edca5cd48d94e549de301787fbb0aafc6bc8bcd77503981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dcc166d171ed0d63149979b9545ef116049a303ca58e3971a5f0e9e87faff7cf55577ed03d62c57463293c46e40e600000000000000000000000000000000003926bf56f61188c4c0f509208982c2aee21fd2d77d320588467c3e78cbcc4aaaf7447e81b9e082f00920d26ade8c5021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013382c7bb1da9826fc1736c94a0a1e9c83c72f44f52a19dbbf82afed5552790cc51da26852647220091e3e523bc23659000000000000000000000000000000001754ea271fe9575e10a6f8793bb9ed7bf1d07bda2212806027953f12521fa3efbcd4ebacd10883a4dd4f5857d0741ee21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004854461441ccf044849c5a44ac53e239a13b2f790c7fec01044389013d869caf3a07f82909acb820c537c17917e977000000000000000000000000000000000196dec16024c33263854d8d96f413eba9bf073e1fbb674c6a11fe606d3dc444d734c1b85f3f93822a56ef8f38e8912a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079efa6ed020a10040d30cc8117d2ad4337db64ab16c9a219c0a31d718d11f2fc2ab9c09ce4d06b86a6bf96b0672268c000000000000000000000000000000001723eb2309e3d0e2c3129e181823558052802c2a64744824a2d2bff8304a20d81768b4d4d1515ee9e96bdfa7a93fed7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d1a451ffd71d205158e95fa4b25ecd48bb4923407c2482263bc38c5416143dbe7907d3deb9f5754e328eda0f2094cd00000000000000000000000000000000131f194744b656be23e16a9062bec09f7fd29a3884b8218729f410e9dfc72c55f087c200a373da6506b94f6cc9b056291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d13b67f68b0c0d5fb58c3efa9a71aeb822d76572ef05d1c36bdb79ea75b72c9fa7f1200bde843e77289c73cca74a9a800000000000000000000000000000000146b553ffdabdbffea4030dd58f3183a513707dcfcc6e1e164f72b7b125bc0e7837634f17847a988c7a6a4da25f0e6951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113a7948a2614e31d28e67b24a501bf873920b1a1edf286abec72e46c10193063d38823518c9c7df596e52dddbd77a1b0000000000000000000000000000000013ea4a5e1dee5164d02ec7df351ce5eb7ca2746b930731046a2a564ac3e7aea6f99030913c57b98a5150c63950bef2a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f5732ffaed418965c0c0d0e9fac1151e2d02dd1d13c4d185d98f635fe015adb526c838dc64fa957b61a1ab79c690860000000000000000000000000000000018325a5f90eb15a41ba01ade4d0faa4c65051faff9981fdd33f34d86dca3b6b7572b0d73149a2324d4c9145ad99e36d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce8841319701f8d17e78e938b3f2d7f4278f0db83899e148c2ef8a6e3a24dc1eff506e01bf1c0d887f4d78d56b90dfd000000000000000000000000000000000ae2c6953e07fc2798fb87c95069475cb29c890d9c9165b1dab2ea33dbecfde998e102508fe0196c634ef6621a522e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012370fc0e4d806565992fefaccd09a3768ddfb3582b5a80a2e7920ba454d5e12f2db370616dac1251ed9a32457db49c300000000000000000000000000000000156c43d5ffde382f4e393f454511b2ebd69bf52fa84330cbc1bd071896b70a176a2a5e2ccaeaea5dc923b19412bf5bf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018703189b335cf82068e80eaa87b5d4f8f85e41970c8bfa6507c37e76ee83d5b5cf83c4557c952db64d5d4de303dfc8b00000000000000000000000000000000144039970ca20ecd8a8c2c9dca526964298876aa7f8b8a5517a34676b1475219342845c0f37c8e46b71b0d473ea49b4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185e7b7d3141133dc54886f718bc1d43026ec173e097c604f533c4f3bacda82512e0b8063fd8541ddb47712686afe5e7000000000000000000000000000000000707c76673ae26ff815bb5ed134e3d54ec622c2e68927bb4e918bb7ed58f4d1160c056165e0405c127eb3b99cb12e90f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7fda0868af825a41ac3635adb3f214402facd152ed275eada88ff725675e8156bab0f04fedac2cfbabe3cb4e635c0e000000000000000000000000000000001574d99e64867be5491e8e2401129892f109a00538b4f3a1a4c2f2b3548650f2ed3c62ef3ebd668c4a7e246f1f32d5ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c090361f99c42e7897deff86e54e64f0b0a279921c85ffe1f981655bffdcaed02f85a9499233e7aaae9f1d73e577cf0000000000000000000000000000000011d27d728df62489cc7c777211464fa3e350fa53ebd210d207f960e8ec484e78176f1593121e9d916ca69fff1ac3de0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e9b6f58842b955e2fc19430d73c63bf6abd1064aec9f32ae3adc6965849ba978f1841b66d06dc510a67f2bab60979c00000000000000000000000000000000150f7b5bf27d5eee259bdcc6466527a17a6621aef0afd11641a603a5452832aff96df0a93178f63209e945f0da0bff5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbd1844f2c54d18f0c71e4fe778498bbbd3e3a2621725bba4f2b0573baa193ebae0e58220737800f75efb37fb9d5cb90000000000000000000000000000000005b749debea5ff14f25a7d0be3ceecbd396b5fda0daacb51ed76e608e3d84aa2318766d1d83333165ea07349674a4b761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001349f5583de75f293ca8d6d4e8406c385aed8e52422085e81c56fa6b8c896fd336054c3a45810de1eccf48042d5df38a00000000000000000000000000000000035707fb49278a7f11636b95ab94bc97d8c7819e3eef9f55c83a917e7919713d19ebaf627ea063f2177185e9eb3c29191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc8f1d61a7c9565ce72ab07d947c5744859497a7627adc67e85068c8e15068a47fa98f2a357e3f65ee48aab5cc751af0000000000000000000000000000000000b317ba185ec85f9c6388377b8ad5ab85fa73e66a6356347819986ce79e123f601950396ea955075a21a1c6dedcd2231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8f4f9e9a8c4ae473fc1e521e39a189a77f416ecd445fcd78e5e5931e342d5e647a9af56e4ebb79585c9ebcfa88a9a00000000000000000000000000000000102b8256ffb7ed4a303692d718544ff6c1f528777d9e08f8039daccfe242fd89017ba15d39ecde64f08b7385eb1893a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f88f2f88501df778fc128d5ce8e11bb254ea472d8328425d4db7a316042d16bde7c393372bd3da0894558ad53a97e20000000000000000000000000000000017fa2f1508acf84cb1b6ed166be8c8dcd003d14a4f7dc65c788790d894f618221e1552a9f67652abf706d9619e75c8dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014150b65046182d52123fa00d2afc8cb303b687f90679287edc51b6dc3ec59aab8421c4784be781fcb19c0cd6a3cd06f00000000000000000000000000000000149a4f80e93042bac22db69da5cdc576dee22d4d21a32ffc1dddbbf2dfaa9548ee07e4776e8c12df01118ca0505e40dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f5020ef5b4e7bc1c21aae13537450ca867debaa04f6a3a66f2ce605ac00637d30a1c6ec8ca802a1c5f9e2f3bbeb9ec0000000000000000000000000000000013c02190d579a8f34f5489914ca2687a89a15f5bfb17dd231a836c4fee68fe0158e27c6af8c367a004d9d1de04eb64401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7384a45dd3a55e34e6c01ba4cb951b32bcd5684693fd4217760e56cc94806e7caad422e1f4e5928d2c2a7100557bd8000000000000000000000000000000000a57a6931c5e57ec60e3bb5272c00648cb893ef022f26e33f6a6c455cc6f0eff77d1adaea7e87625f89801b72e4f8e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051f940a9939aa16aa9b3f24b25324c60fb70e19d5fd2932c1f93b435ebd5bd10ebdc6bd429deba38fae6de67def4cd60000000000000000000000000000000012420d8942509abe6b7447668611dbb6f743689d670af1e27b01b97084e5b58620815994a2c4febdc5fd285951f8876c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032d8e6e03ec9fa4faa7a9d39d6963f765043f48e19b0195271d68bc2ebde5011752819063e22fd81706213e0a40e79b000000000000000000000000000000000d782584a12f0e1e1a1e2f1e640c019534eb5bfda891e1a8405f560c09bc52fa694959ae835f5d22c2c74f82120c96a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a8741637546cd3617ec18dbb5b4ccf74ba2865c7c1003c0f937c733a328f1854240d104a8110de9dae6429b1334999000000000000000000000000000000000c32107eeaf9f01dde2e9a7203cfce709fb5b4847de0945a8b186cb1ac2df2560dc4ee2089235c42985238594cdce0f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108ff1cbf8d8a1ecf8250e424c4d916fe777cfd4b6f4458fe1b33cd43b4e5b8877d9e09f478fb3357583f41cf94ecc960000000000000000000000000000000016618239ccbcfaa25b5337264584988ed29694887924190f89f970d9c788486b80a1ea6fa2b51a47bcda04cb61bc307a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162179f41e2e2f5d85b2adf4e90a3e989ac7b37f74d531425e9759d713c33d08d3d677bcec603ca2fd51eb4d6e13e983000000000000000000000000000000000610eef42bdb08bf3c7adb8948d95b79a233905a9b71b70ee1fb22f7bcd482a57ac7634c03019bb5ae91b7fc2fe478fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaccf87def18741c63fe5fe3425bd82595a29250954250fd6f52f0d75fcdb71bdfccbb2c40f83565c3572797b34c94d0000000000000000000000000000000005c01cc46574ce46cf9185270c3075744e96dcb488e003c54d647a35892887290e0a49fd8edb22da1421292175d400911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c68210933af738d9df821d1389881fa98126dda29cc197dbdad01fa0e22082121c28be59af8b1bdf52bc19b9b0379a20000000000000000000000000000000001e8d6cad636caaa1785845fbc39308c694ab18734b10bcc6b32552295c22a19af9cf05d9839bedced3245ffbb5584cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001121677b3768176245c16043840848cf42214e108a96b205cffb8ed059268081fa404258be5377d24f629475957f444a0000000000000000000000000000000008f430d611e2dc59a6e78a3268d66aff3eb6ab9dc29dfdba504d054fa673766f13eef94ccf28ff9e0d0d78273d73725d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f0165c08a2545b846c1d05cdefab7080b2a59ac77af97cb304e9f08794642e3ab2a537c23232c9fb6f8c560e6d14010000000000000000000000000000000011f548377765cbe98cd988376d903abe3b8d3e9953166a300cb693347aeec58e7477e124ac5b91438d9fcafca782ec691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e3ec989da2f5f4b63c1113dab5c119b4fcc6c95e81d8ebe61be5b713c0ca462b8ff7abe337c8fb4efdfbbde5dea636000000000000000000000000000000000ec7cc566bd4f29eb81167017ea2d14ee4ede46e9c539dc2609da74af8bb09345ff08bf1a6211fab13da1d8f145db9911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032a5387530e2da598d720f1924d621aa0da94343e05ed346acbde08958cc48d49ad486aa958dd6a337c6678f74063ce000000000000000000000000000000001880aea194f91fe32320503b92761c60e26c0242d2e0521d4feb4b96d7804f0fcfc3be4afab9a47636f047eaf86bc99e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ffcacda9b183a5077263f3a2efe37e11d7df0ea33e21518a5c1ed2c7f5c4a92d534be4555ec754671370dbee6a49f90000000000000000000000000000000000f6ff3c60ff9072742a960a6adfe5b390e2030ec3af9826f08d30895ae1f4fcda1181dc8d5c5c153ce43d5c965049d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001214d9ce5f324800c46d9de61c772dc6e2fb189c7afa63d873ed5a2a1e44f608a755a8de016b79c247bcccb37eec159d0000000000000000000000000000000013dd1b0928817e86f30b70fe605f5aea470e56be803b9ebb04069ea33283d8c194931e0e2e8d47018c4331ea44a7daf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001392e022dd8caa6eba04204615cad587275789062caed525bfe11abfb5e456d005dc57ff98591fb2589f4a525e8cdb7400000000000000000000000000000000004d2f40b1ac186e513bac855871e6102aa9564eb8fa575114965adeb25e8584186b7ea54ddb0e73469b0a25091a6f3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011530988dee38c46a3d2b388580199005311b9241927292ec7a3d9132b5acf3a9f6424cb4660376ef9dc19579050093800000000000000000000000000000000131a40c103e66eed902bb20ef82e51a1ca8c2c946e55d73db4f9f87724105215be5d4b00b12be5d3989f5a73614d91e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fdbc914b5ebd7d11540f76e11855f009743c34c6725f33776070d26c6b7fd251dfc5f94cac3688afdae452958eeb2c000000000000000000000000000000000e6d8f32dd8d9bb6aa4165a76fc96ab598b2b65a6e12db9e435ce12427c03f030310d80f8f337199f679da1646d59cea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018018549f6fa8942e0a22db820fc4bd4b3822b8f1b4c5a039e7508392c9ef5c802fd70c31c91e95ea6b5fe4c7271fee7000000000000000000000000000000000c4c6d4b3fed72c5d54b511da7a15740647e28a6d0908b2e3c01d55fcbe65bfc8a67019ac2fcfd4a170cb78f173ef6e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001832d06481573ab4d103113d49789125fe70d0f14adef4ed9b006ccc86ae717926bb9beeb44652b3e271fd99a75ce0e0000000000000000000000000000000012c7ca9bac925f4cbe91552261862340c1cd659e83045d83ce9489389bc920c0e3b03636789d10504722f736121691ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073de5b9cd4d2358c418a103d4fd4653b4ac32a43d434f723483621a159cb49255d7a0883d379a8a08fc8c9b0cc59cc80000000000000000000000000000000006ffaf33a960c1a466f8917da82cbe8f310961dec008d0d7fbaf3d76dc740339ee91bfd2e41d4177328fb11c19875d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d82a0e8dc2d82dc8856f18a79841394f70d8882c09bff7248a1696d8801056376c9a8c6980e26f644e539c24fcf5880000000000000000000000000000000012a69ef008501aa90075d3a1d3cbb0af712784653667361325aaaf32006231d8dfa5b6125d4c840dd21192ade0c23d1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ff3fd877c2f7f8a14d78e5af42e1754f16c3bd53ac0254523761f433eafba64d3f158d2b7ed136c7f87e921e3962f0000000000000000000000000000000000d08d67da1798dd43d151cef813edb655d93803f1d6f28c60c79cc44226e839cc58f602e744c8e5e8881a4d725486bb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027be6f56273c38351ef2a857b864469b2743b5069832ce84efbda7b913624c9bc6e0962095256d262adbc4987f78ea200000000000000000000000000000000137bb171f08ad3e82a524e51290c6b9d5c71905a0d3b485802b69cdafedb57c753cc6275500e910bfb41fb557f4ad7ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001989f098c2bb8c8208e01dce2b5f7c237b191d11bb620eed3e8bbc77bd104a3444193c4b84b65fa0fd78bba437fc0bc8000000000000000000000000000000000a8792f2ab78460772f49c62bb036f92734f9fd61567074c671a2133a63bb18486075d4b10b08c8eb0c11f6f286278621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cb972663f97cf6682e7f258d5e2d540e313cb21371e9e656b318c45bcbc09ae402c8307d919c84f2bb61701185b57f000000000000000000000000000000000a56c242e6da1df7bf518abc777ed36a409fda31228ab519e6c63a2cd3b5fb2c1211461c11d4c6c14bf6fd70f255b3e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3c26d38180f3cf375d3ab62cb2c1f00a9b20708f1f689c91f577459242c1541e47f775654b5e6a69c75c256661c852000000000000000000000000000000000e4372d7d92c21fab13a91b05ffb0ec33033c27a4e8e0d64794894926580ea12b530a665e6b0a4b12fabfe4be621bbdd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053fc35a33fd7dcea7cb2f5aa94a7338bb69526c75a6712b8cd91ff1012bb67c76e37b7fc391407ef8ce4da0137e1a4200000000000000000000000000000000051c06f3e010f06a2a7768eac1513005e4267623a5a3bdc9a8b6f8e0b9f39f1704ccc0045c358d7fd34656528dacc3e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f6e1f16a704b6aed9fd586a1a8863944e2b0e62ab18fd7637fcc5912e8f900fe140ad93464581663c5fa1510279f1e000000000000000000000000000000001793cccd33cec78a53af5a13b1628653e7c20b4aff2e3cbcdbb365fdc1eadb8e9215bdce9df7d766932ad32063fef0ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014432fa74b331cce53a246f844e6b13d96b84c5672a4ba91b0b89ac111ee5102c0d01fc8ac9083d2403f0d5ea41c72b30000000000000000000000000000000014e884dfc2d84cb632025a207f81663c5421b44333a32b079dba2c8647866e0487d06c0322d36e8f5a45e3ebaca990b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061595fc1c47a286e16c344660a62cde66f1b9cab357f26b77de3496553f8eada7126f5d68884e8ae477375656a9b05100000000000000000000000000000000092a23335ffb2f1c5e8cb5eb7f6b63ea31a9505eaf63bfa58a4fc77e0bfdffc58788e851b619bc1c144673e898240da71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ddb7188b3328592794c83f07c959aeb01aa660070d5b9b8248a0ffbf0cf7ee807d8ff9d98572a907422e1bbae4ff2c000000000000000000000000000000000524685a67b7b7ea6f8893e22f16852992af1624bb72a67b040fc4f25feaed92e837810230dc9b82dec732859cebffaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c6904ed6cd3ee7c4a26fc34b6cc4ad787c7ab3663de2f47bd002eb856d9857e2e940d3e79245b00b1728e358679c1c000000000000000000000000000000000b38589479505256b3718f96093b17e2351ce50930636cfe072513bf8cc6ff7f59fac2468d8cedc5351b5fb38ea4d36c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a5baba050ef38a53246de5465b832e2eda40e94cb1165621b3abf6f7986e9582533c54032010494f7bcdef0ff526fa0000000000000000000000000000000005e9458bddda75bef48f92dc146b2b7fff98b8cf89de62720a88527d01fe0ae1e7ca946defe6fee234bbfab522a777c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000872b7d182070e115309e8935ffd8eca8f4307170515780089d1a0254ce905c3eb062f9c1e5d81ed7c10aa31b639aef5000000000000000000000000000000000baf042059879a2f17e6b976240b0fe342dbca69b5868c59fc89b902957a83b368373e2eb2be201ec281c8f2788cb9911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016e18e49e5fd482fcfb44b91bfe7a8244b51b99143f592980d56783d29a40eedceed2b459c2a741c6c68e227f11d6af0000000000000000000000000000000006c1741d152d500826b28b52e7007c091470f48ff626188af95968bbc32e8f28db6940612cad79cf7b8c5f625d3dd25d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c52198ff413685236699b3cbdcb2a844743ae0ec388d0f19784d75b76bd32ecf9d2072afd24eb85ab7373902f23994000000000000000000000000000000000b52487e28501f279667b7b8177b65a17760c421bdcdca499b9c637364dcb680bce1356501aaf602297abbe0eff6132f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c4e01b6264c5649a9f0c99fa52869354e43a4fa21179eaba87782e73304d6bf104bfe75459e15a6d510af2ac6a1197000000000000000000000000000000001972b5464de7f91e11cd3ed6a995a7a0372fc0ac2294131eb35e6443a619fd74c528c2348c347847908a0cac3943133d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d838ba9f20c8d4d0e962137f5de82584538b5fd73092bd3e02a31de6df79b41692128c5323b50644603685af4b5bc800000000000000000000000000000000146388be7e8ae6986b7d667f77b08cbfcc9f0f880a02008a30dfb48eaa46dc9d42efe3b738ea3d1799724a2952cec88d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bcb08bfe1da7657c42f1dfaffedff442dee9f2502a960300dabaad5efcb19d2f26704a36ac79c5ae8ad2542bbf1893000000000000000000000000000000000142268eab968c83e69e9e434ae15c54bd8f2cb784c39b3c84450446c6377ec364fb9c3f647b13b626c0f3a4ffe89e8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035bb13d24ebc2b627bf8d3b96e80ae2303f96bfcf441d57e4ef3ebc3e461694331566c463680700cd4e47d55372babe000000000000000000000000000000000858eccfdd2b40998f4050a131d875f9ba851a801c6dcf5d85f31bb76f2d16160987076d42d8e72ae419baf35090c4cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0d640d467efbdb1865a54e3fd0ca9185e08b52419b3bd1815bf625831f86c90f9f394c6de225c0043c4ee60320a16c000000000000000000000000000000000c9662de7ec1ebe557d148973fa21ac795050d7c5d4d048356b4c9b0d51c85e0a632955575b0cfbafd8d72caa3cc41f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012514c99af2c22f95f4fb02e307c090fa3ace72e68de35f12e91069e2a77745d6ea84595db78318a929aedce62caa942000000000000000000000000000000000309db4e4692418fefd4880bc0082055f25475a173babe8f12aeafc13846a8b14bba8e63ad44846be62f9f4277ba5d141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b2d8a702d9ae43f6d508f92f37f5ba3bb86abecd5ed9fbe2c590adcd853b911b03d9a05448318151d94ac9bbc433b80000000000000000000000000000000015a142f9ff44bf5f1933878e2c009621543f00d45ea5da8d70fe8dfdb8354df537615f41d5c31a86e1fed5c9eaec37bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df888eb6b6f9ec62b7803a3f6d39a0230473df6d891726cfac7c10a380cab7e6da502f1edf0b600b374caffb194c78f000000000000000000000000000000000f926c3bf6870e12a76e35c3d661d81927c00afc5028617aca866f477bd870e97494b0b88829904552d5b01925d89d321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dd2cb07b568d314425122f23177a13e59194a0d2feb2f818c3abf0793a0a27daf841ab0081af245f75eb6c20d4066200000000000000000000000000000000008c16784ca8cee3c304ba16b09acdcf7341162043b78df9ce8f069daee52407b6aa7a4a44d5e31f18bd4f17412e19e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cf443db1fc5dd8698d250cc9fb95505918d0316eae884bc323e2b06737f68a38f8da26d43e40e1d2b2e7df1a56b237000000000000000000000000000000001069b8ee7475043ade78b80e0675a4b808b98b8d7b0c3c2b7a63eaa6d5b80111fdc5450180994d179246847bb081d44d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b5636f7866dded581fe4a460b887cd18e0e3c9ce716e92907f95c491098f651a928a1208ebd139632aebc13bd4a2e20000000000000000000000000000000019f55b97ff92d86e56094f2d90cb177263220d74bf7066fd686882c918814e4d053d6e74757f324b6bc241dc74f4c3121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190fb436954884ce2fba4a38e52039b0449a3a556535425a93e3664fee7c1b2a943d3619ce2dee750f2949526185ba82000000000000000000000000000000001883c6626df40914ce2c15a7d75608e2fb359362e560277acdd29033be4533c293d01122ec0255122a18e90df478bcde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebae319e5f0460cabab5618c858d030b4346a560f95f1190d1215caf2da1b096920461a858240d4d6697d81adf0cb040000000000000000000000000000000013f1f0d1603a3dd6d4def1349072ca924fd7e4e79c3c72f1fc229bd9aa267b41abd7b9cb4a991d5e79f63993a1f5a47e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082053003c6f76cd6f01c0d0d50ee5053a6ecc285510b504ebbbcc4da2c262e6ea0b91de2c26a38e4cff4f4b2452859600000000000000000000000000000000183466a12df33b9ed7cf94985c29cf2d9434510496d8e73935d3ccfa345fc4be4c19c17f32144343b3a0cc3f15b62cb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112e8f75f6505f03bbc71bfc6e2e15a1620a2344a604d49b7a8f4b83c7329b96c3961cab4a692844b29ad76590c2492700000000000000000000000000000000028323f8840f5da31af29705dedf59b7f3f0d2025fc62c7db6200de7c076264c2d9498f839836106c28e53ddcce220111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b71fada96f2275c12542bf9fc2b932cfc7878b98292c8f32fbafec75a985b703440b10e6e8ea7825f9d16b41ae2d8f00000000000000000000000000000000043f36d8b2a3b9f5bdae91f7de8da2fcc52c9bf237f1515148ba8e9b4d874fc3ce9b10cda44b32d30954952c6ef53aaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0e3f7c7b2694359934544101be4e4bdd4fa2849104da41fd80ada55ab3571fe2014af6cf640287176c0baf9cf09ada00000000000000000000000000000000057ec4d92931945d9c5c061ac62c23499424bbc142956aaf9c1a395b1b0817fd7a7e763df7c990e958e145bb260f39fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000161512d1016710aa14768013f2445b6dd727502f5dc1ba0e6ba2beb371137e7a78ea3151737d63c500fd1b757ccfdfa000000000000000000000000000000000674f712faa60aac4d7d623b54b15a34e832601d20a1a7fdf81fd27fa58a280520a5e552e59b10163be3287a457ca8f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e076ca12c4165da77862f49e479e9a700fb03aac93149491733a29c1e8d88ff4348512091f1e0eaf076390a6a25ef700000000000000000000000000000000137a9b12e0dac1fac59654747ce6e2c0bf69a92fb7ab12e53b0f83e333b43a747df3b8a9228b470a0aa1c67c7585414a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ca1e24e55d8ab7f1905957c9a2b487115e97d6baebefc2ea9066249ad553dadf77c816a08daa6571893a4255c3b71000000000000000000000000000000000106b740e1bfcc0e62eec98307c4f54d991a4ec6a861d6d1f0e62eb38a1652617856e4f2eeb99a69903a2cb8ecf8ed77f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac43272ff019f1ac63a156e1672d3734b3a988164e6bcd92c636560718b0cad035e00acefb6e9a7d5a498b237ec02c40000000000000000000000000000000019a483093ecf6a2869f9bbd5fe7c5d32a1b02dd7c7b6d1474cff196f7fa87f40de3fcacb39d8f1ab6e20db974bebec631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c6e4cf7e2420fb383e664990b6fae6e6903771ad8b37ed5d14a3b831eaded8613e3c2a5ad50fc5a19ac61b4e3afad8000000000000000000000000000000000c6ac8968b39223b0171f2d2314df24067ce48f5f6a045a2a758ececaaf9f51d00a83df3d2f796204f0c4fe190d869c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c04802e611a8cb1e8e56f9186cb827d55142e133e7b4097e83f41e736458efd722f69d224f761dc843961cdb6f46950000000000000000000000000000000015d1551f2a274666dd9e45a0e56bf0d2a27cf5c6dc7597a45614078f851bba62e3ab23aefc7828e6dc9d96a770a9d4e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aea943f15bb896e56c41eb9b21dbafb4dbf3d1f46ad62a5a0d9dd4b0bf5ca30e8cf51d74cd6b2193bfc0ddb3885c8d0000000000000000000000000000000016febac9461db6901a8a13374cac49f2885af1aa4c65aebbf80474f7ee30dcb91a34aac766ebedb23b879f57f34bb04d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002d463dc4da27ad2115f2a1d13ab9a8d36325a66909c1cf4e40a105e1c536be11d4a0a83508ac82efbbaaf3c780ecb90000000000000000000000000000000011ca8cad60e73e7922d46b6d1f4e0bd13c343f477516df12a29903c3c5ed0773c5b4d4892aca81550ec4b354786f0b8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013401c78570d6152026a581df202a27b13c8cd807e0da791565f4271a285cd61dedc3986af4f4b6db64a74b479efaff70000000000000000000000000000000013090059bd58303cdc68152a2e38823f3999da7b227e15a8832f2b28268149b5e9bbf002d0a9ee1fedcb4447a4c696081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a272bd9af5fb317c933c975f2f11a4c3c7bd783fbbcfbea122786f7d104b47773b754033e8056fe00a36b4100d81d9f000000000000000000000000000000000e5bdf44464edb775cb592cda24acf1988b15d0557a04b0a8b7ff93d2f83e1932a5bc9218f8fe94e4cccc5e896401e311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae2f845eddec32d172e7679edeab4d0fd815700c0dd617369ddf4c7c7267373b30ed1f2b6e9f5d43eca0a6cc991364800000000000000000000000000000000197aadca3fd15e77c436cddc99bd623d25c507618a850fc5b438d1525e8e8228934fd330d1dac7cb7dad97a4a11b4cef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c58e0fb254a63c750946f8bd3ffa8766514314c1f11ed73cd6136f1c9dcd085edb233fdee84d01742448675bd42cd1000000000000000000000000000000001240bd1a1b5f7183ccbe0c3dae9d02b1e2bf55230b4d2b625338c7ac3ad6f8d542eb2f20ba076228d97590d23278d9c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f06222fcd79fd5949837331b61eb386a9d98f4bd4107cbeb232484880c045d6b55091468e1ff5fd24a8ba020253a2c0000000000000000000000000000000004f82852ad8d78166d6865234d8c50550a20ea28c251cc2a4d40c0d7b659b84b9819724c5c5decda883443fcb27a88901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f7811e2add7cf8b4dab10577ac3c8ae7f0683a1063b20fc23e0191401a7cf07237c6a618c2d654199357456042c1260000000000000000000000000000000007751df6796aad740712982976951bf22365d8ae6c70b70485f2f3ac4fc01ec4e37cd1f5ceaa09541edcba95b1f54c211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001320574bcb16fec24c391932fb92aceea2e6b862772f1dab4063963b877cf9923433cefc18b4e4338c18866294e57d140000000000000000000000000000000011dbded803938f2d02b5832d2bc158ee4f350a6ef1c945d0b456326916fff11083a5d0f0814c1766af3bb99182267d9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a8300f44d5dffc241e7598fcbe767279228df42145535087947b2f7ead6d51c8d8c95f963acd8d773386637d959238000000000000000000000000000000000e878732e843de4d6d0e557f3416dd9eb1bf432af6c8ea2c3c439dcad4d35f864b3566491b4e50614e4ad4965531db841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d650a4d4ef2743778596a60526677cb7772ba1df41cb7c962a5e9ab28979ea08f7b51c5c8c8b75d737a169a8e53be5000000000000000000000000000000000e7a95dae68634ee6be82936564c3b90b55f59dc1cabc0e7c0e21a39b376f6b6a11874c5e739400a8e7b90fb1349090f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007771b7c0046f0031323970e5072558e981f844dd8e776f75107973f7f25fe2aca81409aae9244245b2195641eec737a0000000000000000000000000000000013035c533a96a82117bcf5f3df119508a714844bc93cd5ff40d151b4af58a60fbf20053cb4e719798f5c54d838bc8db71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eb280d0657b1fc4305ef1f91fb1030c4a82a543c26dc0bbd076e0065efbe284a2fe74143ce5f8a786d92baa2b81fb000000000000000000000000000000000166e75c11705dd841b687d5ea99238b90bf193209e19315c7146d52e42d23953b20c1dfff65d0bb7f5e5744a5b3d3adf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003be0ee0cc0e3edcec734b0da1dd95cc897a1ed8e078b3cf260c67619f07a08db4837cd480c9fe6362e2ae98480d88de000000000000000000000000000000001352a88816cedf38a5d6a0fcdadbf5b9aa6a1fc83b6cc9744c3ffc6e07ca90d51df1d16623479eddff376f99273cb2311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b8bd67bb43fb8a2266b98293658f4c707353ad3df04043d3a754adc7628e9d06bbea0cdbb7b406301a486794588b3e0000000000000000000000000000000004feabc20b20fac6b7cb620caebf5ad4fbbfe4a265f81784711d7d342f400c2033213c8147b5f7c0701a7d5e32d5dfec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093b5074e96c01ed6e9fd21693b8016547b17baff6c0c4be1ec9115d7ca16c31604fc90417d0f8e23f9162ad94672312000000000000000000000000000000001476950369a927d9f97f17cc3ce745fad4a43512f7af2c70c7405a5b1fa072a9d6acffb5aa9a9511ce43a7534fdd6ae71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000159877955d3e49f6e5347447f17ba0cac543c24de82e1e971ddf9e745335ca5ca4e32f3ca59484bd6bb690c17058704000000000000000000000000000000000857fa57cf1ada4013efcab045f646dc39a7499904ac45ad93e3d11791f36c46107e4c9ca2d274d902982d8994a0d4401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1c6f3f629dd9322d2c71220fbe607ab5881ff589ce6861375efc81748955ed3def5da1e21c9020bc9ab534893973a3000000000000000000000000000000000da198a54e61e9d098edacfb3dee63b0f296d57069d6fcc2888149ec0fc1ffc93a507b69d53d9955d874ed5a14585ba91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d495cad1b3a883ce7ec2ccf3f31ff9eed422dcc11302cc938ccb8f5b72382b0d1c6876125eee4bf207b659495e5a4600000000000000000000000000000000097bbe69b5e468e70cd9e89b2d314af647672e89d95f4592cc77066589916902ab1b297289ac5087627a829aaa642b661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001279862eb539f6f00072fb14f4933431e6032fa4a9cdf24bc19e34a55a6f8e5ffaa3afd151dff9a9fd53a1737747f6de0000000000000000000000000000000012e1547b8cae6d23aa036eaccddac346b8069536eb7b3a027cbc7909881c60cf8a5b70fbc89902ccfd2d6e4a24edf02a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab68e7d11758bdcbb2e2f7345720a370ddf1b3f3839dd9433fd97c37408035b23325318a8ba25df89e03de3cbbd802e0000000000000000000000000000000003f119844d019f29e05fa02b7cf065fa6dce02830c315853e3ff3afee580779e158ea602a08de2efb1462f9440d239501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000706a2d733f2e7ea6a7cc09baa3b9f3f86e0b938bba3db6d619438b2d8bca1184190af9434e69860acf00495671d72f90000000000000000000000000000000018261daf159d2534414d0daa0f4ad3b737ee2cd04ff1bafce5aca8cdbb9fb4774b3803cbe85f838458753b9c1856800a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056b6658d7817400086214aac098438ce97a7230e3496e335b45c5078dee1a843ae3aaa3f7fbbe0b2b07d0a8ec323c1a0000000000000000000000000000000001cc3ed8d20be9fc2ca26aa27733bd3797e53e4595f427f95ec937656b0d9def113fef67d5fc67cd9fd5ce0ecc79e0771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b811af804f574836cf077c4142881e30824aba7e8ce0ad581591c8464365d6424262a0aa47aa90d92e6aed60ac4230000000000000000000000000000000000329a101b1a82b10bdaeaa2151901e0b3b92e514007b13404d38e7bbfae03cdcdb3f7cf0b94613a69bd46dd39e52ef431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001571b940025035b8eba3c82f51559159a375eff08cdd0d18be551c58b32b712de4612149f2ac0a6ba621f252c8b8825f000000000000000000000000000000001438be78e9880ac556278d01b657a218298953d15194561df261ef0bbfa99ae3af4f6803185bc157ac892597df55246c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f897489b5667466c894e05e2ab074abd073185a1380a365c0f3b981cedcf5a6dd13a9f1cab8687bf4a74c510a9d4e41000000000000000000000000000000000d85a13387711329ee7232480095f5acd82a92bb56171dceeb5c2c1e2162b36ea9995ba6b557c874e6bbccd9158fbbb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127ae22c38e5b623cd71855feae611d34848461779ac058141a1ecd3f1a83e7f51352e864a3c565657bc4a99ba9f0a740000000000000000000000000000000000ac436b7038e529c7c15d6cee6e25b145ce19b178ad1d54af8e228a4a6299360d1d4e8c26f664c646e6110c33acaa9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107bbd7af85992763bf6e9a46b74cf467e47d0d73b87dff55b481d782c776b7d5a3ef57e027e2337fb517c3ae388f952000000000000000000000000000000001291ef001a59aa4dc01e142f4c8c339c750e5576703b9dcc3094d640dec2efbd7e2e7593b00426c801241e0318d1446e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c788a17792f6612a287ab7f2582d72c90d5bc84bc89c0a5dc9038d679a0cb91d613df56a702662f7220710827f0f6b10000000000000000000000000000000019f80c7b4e69e68ae3f5b420e65b64196336ba301ded3227abf1eee2d4a0448533cdbebcdff2da75a154262c8451c8e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026eafe18c1e5cdb0f659296b22557bd0eb222e89c4eb74c5b21da78682fadc1eaac8dbb54a0aa714e68b288c4cbc2400000000000000000000000000000000018fec8de5cc8107ff37ec319c6a8df977de8bf61e172b71f47262967ea056a3e9d6dc8eb01fab2f5cb85195147b6970a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e2bcc87b4c21b0fcc0fe251eee14e69a42cecee1f180bcbd29969b1ca6dff77d8a0d4601cc25e866c8ea9454a4fefa00000000000000000000000000000000144a59ae421862dcd786ad2d8056ad7ef623efda3aec47eebda9218203220a6a4a31387823e5b9638d3cc941e049584e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ded2e47765593d38861e725b172bbf9121aa8d661c4572989d2aed03e024ae9d3f5945faa347e43b7276330aecbde000000000000000000000000000000000042ed94eb448c2f6b5f2139393ca7dd240ddcd709ba3bbcbf713c216e4895cd29dc30441564e12fb8d0f6c1b50631a451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3042a230f2c44ba569eeacb2d1440712e3f9d326123aab7d8f69463e389f7251efc69680d5017c7e5779eb4e11dbd0000000000000000000000000000000000c6c4bdcd3c33647711448c75c12ea905ed0f52703c4709ff62eda29d554eac990a101cf05f647efe6f98296c2fc73dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186ff13d914286ebdd5ad2032fad3b8941c6543ac1a37e30eada26c41a69258aad12c02a79f5ae82ba0c1be93821f54d000000000000000000000000000000000736e2d1a7078d0ad0537493ae07f09faa1268b97832d802010404b01a7c005f259b14c7fc886323af0f220f884aebb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001955870617b6b85ab13b3669874ddd91b75826c1a736ec2399505496ba5bb1fd9ce20c303c2da60937a8d4f20a4e6d81000000000000000000000000000000000be61d56e9ccc1011afcc0d75621f12b20ebfe68ed8065c244a78c33c4f7b2f4f40d6b172143ed0108ce9d51c874d4bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080f1b3d001c049ff81b253b635c6992eb2961a72d60cd65caf2e27e6bb48fa4bb50ed4d7f9852613afcdf03326852eb000000000000000000000000000000000552b84e59fc41ff4aaed1f3918bf69172e72daae50abfc9f9aec23894022ea3450d5d65dd017cc31e1645cc2d53054d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a6df535871d8034b0a0a036ec42a8113f80fe1b74e5a487c488db45114f5ac9524c3499acf15b49c14821bc2087cb0000000000000000000000000000000000457336046d1a1a2889d4a7940fe9cb4a693ed6c9fb83116461e03bd54f705af5433181f0d47ad196b174b7a094ce7fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017f510a6df7e25ef138c3fbcaa5049c8ac38c5edf3e3fcb0993c8743153255c485b3e37033e215aded48071fac73c410000000000000000000000000000000015994c0b76d039f6c5893131d9a9bcf827c1276ea58ed05417154d51d3a700b5815fe7ea466a992fc22561bbaf5cb0831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089711d2ffe689db8a76b4caebd69458dddd94d6502ca8d3f502b43fbe97155bc755a6c38e3fef02ecf3cb3e49fceede00000000000000000000000000000000078fc19736caefe8fe2da2d3ae22f73371a55b3fa8baf4b5b06f91b8baef4e067e09bcc0edce4fed14a109a14be007ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b88373362c8ed4fe804a41ee808fe9023e5aaf0b5e341118126f0c0dd0d8c7e75fc831243c5bffe2ec17ff8305eb1d4000000000000000000000000000000000d5948e6c75c4c0c39ae852b412e1474943fb615f5960c3c353224abc94131ae9d5ab8fae576cab9bf2dba61f7d993dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7ae10b09464ea00f1f7b1dbc69486f346d4c72a10a6569add7352ec2a699fa6c45e1fc83fd5505296e2d1982cd9dc8000000000000000000000000000000000ac6402c5c9bbe08ed99e57b2eaff2d69d7ff30d777a6bbabd454a377b2b78b666222e5739c8cebf339f459f5b6f857b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000949d6b7cb74a4ebfd9eb444479902640c2f26a2e402ec0afcd3c47db22d302a55aa39b7ea9fc7e30247f1e7ca821ad6000000000000000000000000000000000890c822bc5db707e62d98eebb758f5b14ca11708a3d924ac7fb3370c3679d0e7374b1ac19715c0ce3638c27e2a877fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001957da8b8c62081952044465c4a7a5cc248b204a3232a3db2a6543b0a680e4abc0d19651a1785f053f5318c425dbf77d00000000000000000000000000000000131c0401b07c5995c3821e714b2bb9c57349d81c93afc1bf95095ea7c3d3959574995f4c0bae8e3ab767b81fc07aa6d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfac923a3f0ba2afa4fb0a7b40b9008c2e62596119ddc63561c83991520b5eb6dd01ea0a6d64eb3152b9f0d8d5d8251000000000000000000000000000000000f80ec93ee30961d2ddc7ce0ffa7f125e5caf70a93c0d1dea764844423100b1dce97b3e74f0217bcdb9a20b0e98a4f381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105c920a8c628c5ee6df811918655734414a11d9d3c8c2b267211382bcaeeb101cf54b1218ee3b2d70bd103d93ef2a620000000000000000000000000000000018183909b6f4ae01b8adf79e8f943d35f606a8652c1003dda0e865da28ac0e5cfee03aa7ab6d119c1fe64cf3ae82eb691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7b6a789949ab6a18528052849366c64be6957112138a4d3cb2e4d2e23e4d36c9c9c73cffd4db1c6e5e4c130a81effa000000000000000000000000000000000f5b34a2a448a3b4dc1bae9e317726363d744318cd95a75be2718b6f2f7ed698ea4584de11f6312b9f06cb97a6a855d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183f731229099e4499ce7612c7ccf8592986f27cb77a37daf0b26bff95f7f5d3be11e5869c609ef24e2353415c644aac000000000000000000000000000000000114ec4f9b935b8b22a9446fedc91a1a827b486aac30147fd6e1ed17ae3f014d40d7ac93beb63c6c9e191e5cf85f53bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001244f72c444130d42abce0086ec4ff444e674915723bc3a76c38f1a5433312211506ee4184b6a39627138960695783920000000000000000000000000000000019d8c7191637362462b84eff3a35404dfbfc773644162557fee58e4eb19740044e12b6c595850eb69649964cffe0e3ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb83b92216803f44abb850c622dfbeda0c595a35925131ecf3833e39f9cd726c91555367792b0563206a8274aa65d6900000000000000000000000000000000019f59973beaa77e793d2fbda4db276b792c859878d375a21778dae5db344cb836f84985c02e2bf942bf148e0cf8c8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dc7b92216d265c7df538698d3e67f42346e0d7d48b0637574a2dc398865a56f790360d6d35b8996ffe51fcd34cfc6d0000000000000000000000000000000004169afb5d531b61b2029c951db600aaa3425ad4acc61d100168e54751bc2b3f808d5ddc2052c87bc7a165e6470816a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008aab59620251cded56b0a75f70599e7993aa1a2429bf7bbf1aa5ab072dc76ca038077a4f2ec35a733f20e14da803bea0000000000000000000000000000000001bfb1a02bc7971e9cd2a6132dd5c6eda6d35b1cd9441441258959f4709dec0253ba6c7944fbeafacdb53d1aec7194b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053f21eef97cacdc21a070c2d6f982a82c2c4f98241402dd430b660b52ebf4e566adbc07b36644a3f338216f0cbccce60000000000000000000000000000000008ecf818f2fa8706424797f829074ca8a8dcd77ec2dcf3104579332b765bb3290613957e7c143c5852da45cc021c4ce71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d209a728ed2ff7a6d4e59743fc1f5f4fe3a1f74dab37d5f96a7997e11059aa1b6de4520a35716b14fc10f3c1fb6a13200000000000000000000000000000000140ee309280024c3a58c411a0c49fc166460ffef8891cfc505bd2b4ab75fa4be812f859e9042d27ad47344394f421a881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e56ab8267ab56080109e7e062bec24698acc1b23e1cabc79387eafad2f4bf798fcca2bbde5a085b68d1f06bcca53a40000000000000000000000000000000002f63a8904fee05c1c3c772e4a06512ee169788779b6b2d1fab5e15c9fb15efadd9269d6e8c61087ab93c3bb863f3c981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ffa0015ee1a894f153fc76a42f582c3a6934b818c2f6cf97f348e3745c8787f815ae0e24b9fb2fed2fffdb4bce86b800000000000000000000000000000000075dc304ec95efb1d003d5e5a8f2112035066d085117e2817c944f8df23c53db5800daa1687b0187c69195114344607b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dca360ef287b9834d5f6f85daca79b765d626901e82aea8d0cb772632a6fc5d908972a9afb4a47c0f04704b747fa15f000000000000000000000000000000000709902505613d4da8441e63052bdb2b53fc518286ec92d4668ff2884752fa66d0ccb1dc234f105bd5056a11ebfc343a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148a9292a36ef70952c15224a0c04b605026e58c0c05adeadd3551957cae51f5c2be81d5ba165677efe890791f839b780000000000000000000000000000000014494bffc51402185c8509f29c74d5aec835d855159f8ff2cb6189d6ca9609be63065877804802ee9023557c22d384621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015cafb23f4f461ceca20b75aa8bbc86704b4524efe61ff1e2adc704e38ac3648b205857464f7c1c995d3eb38abdc70940000000000000000000000000000000015ae0b7263624365a7678fb13d7f520307522dced26b4eb37be39e849378258ba1e54653272b3beafbba397aa7527da61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f75fbe3b2715efe591b764e09b9b29d3edf8096c80208893eacbcb091edf1a24e51b6de5e7aaf225a308902e9a7683000000000000000000000000000000000eeb52fce388696cb0bad149dc6b41496053e53c7163e7dedaa47b9724fa6fc22477728f0c4022ebdd22e592e202108a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f9984d2aedab56a7843e4b801c3087732993d7c75cc6aeaf7801ef285aff5fc7430c5efe984fdc3e75d58497fb7bcb000000000000000000000000000000001014d5953e8af52868da2a967635ecfb946b3b3dfbdb629e3271b5beb9dbb78ec4d3ee4c27c2cd04abae42bd53859f961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cd2e31ec4d48d76f42fbe42873979cfab23c779582c0aea33a1069339b92edbb577ea4bf5f217a7e4638d6d68fbff40000000000000000000000000000000017d409fbfae282ee8a4bd78e0e013bdc0b1c5cd41e2ba40637be8666bbf92a9423f16d0410ff5529a08e57832966479d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016f8df8dbf74581b41ebab248602420c2edce6a242abfbecfe7ac0f3193bd696b940d5c44875adf78ea855f26798768000000000000000000000000000000000c30e8c3786c9d43947337fbcf14eb3b40156d72a4f0cd455f213bb33b53157487deb8f3523edf86001c376c8a0c746a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000670a10cf742da54bd016333f57c98faef907093197f565ffeeb99befaeb855f8c14a0b97775c3d2661373aea8553610000000000000000000000000000000000d087c99d1304a797e89d59aba20fa4f9e14a9eab0f804b5ff58a1c799fcd931ef0aef3be12662a249780eca2a4e02031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090bac216e4b504ca392a25dab9508a1a21c7e10af9f896649550ae25a9684e165b3a8ecec46512b0127e23336ce71bc0000000000000000000000000000000011a92c450da8642367bcf7ff2fa050ae89307122ab84c54971e0fb560d96ea94e9bebf03661ab1dbf0ee5bd27104d0791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e923f26ae98ca4f622e18ca43fcfdb4c67969b3bd1b79dc43855722842fc4085d544c8aa004e95c25189dff5f626920000000000000000000000000000000007ea320d51f2386cdb518355c81a85c7a4a4a8bf4da22f845c232577fe1b20bbd21fc69aa2abf4a913c21fe061707ddf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d37d78621017933650d22dca11e8cd6535c4e00ff8c3aca6e93582530519223e7fd06bac0677bf37354553d8b0cfe0000000000000000000000000000000014746572098d48ef00a1c323063fbdfc227cb948486e7f11ef670c38649e3f8e2bf8de5a5a408206697e78427fa92a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f9070126160d86737dee5a76532288b4083e4190fe7346dc10bc00128895a78123f2174c4d48ff54be59c1a6948555000000000000000000000000000000000b0e56a982f2d1430ad5e6b7165ff32f865af82dfa2b7618bc8ec1b93ee925c8f7ae5e6298317b1e470dd06667101d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ad7d590eb6aeeca06ec66543051aeb4aa8563309ede60d323eacfb2b0596f4fe3d194f521d05253a392f287f83d17a000000000000000000000000000000000acf7096efcbeb870f588d7935fb0c7ebe3349f0e30231adc90d5e54d0feb47f7940219954c4e10c69d078c5980f3a0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112208cfe134e79deba0ae766a41c560cbf5b0a2401e330e477a843d04bde3bf36b8d63b35b78a2673c4bac76d1c49be0000000000000000000000000000000005e852db35397784eb28295fc29aac1592b13c71f8b69e06f4da3f1bfb94c02f42e8b7e56cc65dcc76d7c8073dbdad851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001385efc42ac56a1cbe446dc4ba7cc679faeb0039bb1ac0c27c1b05f42687cd457779ebbafd03593c25db132e217851ed00000000000000000000000000000000058807816249bf04ac2a73f3fa5dc9572caa9d5262e917b26bdff1cbd24e92c4d291ce47b02513919cee64f1b13ffcb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e78378c06aa2cd45a3a4f9130e37a57e38d47d076ab34f03dcd1549ff34ea32fb4082b49f3f322a662de186f98c9df0000000000000000000000000000000017fab497e041b494a846d2599c70414a571f563b1ca80cbddb020dee66ffdf89827340852e2ced4abd8979c6508c517a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002689f2da3b72de33c68154bfc506a834270858ac1f8ebecc712d2c547efc3efb832c4dfc19dc0f83082812e870402e4000000000000000000000000000000000b9b4d92d4a2257a6865b6ee4695b48472eae649e5d0203f935d921d89d88f927dc9ed1713b40596b7dff965db9b415d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d81ef768ed945f85b2028e5ead9ba29fc735b6285290933befa4a687d15aa454d9dc11fe45c6ca47163115f573306220000000000000000000000000000000010b4f9de18ff1be318e97dc7d165ca46d17f82e028da544fb7790e7770fcf06394bcbe95108120e2095a01e03dd465651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff0d24868a22904416aefd8a90b36395ecbc4cdda7aa2aa01224c57c0b67629c0ed20653b87aa145d859ac87681b473000000000000000000000000000000000dfa71092402ddec640c90394281bd19fcddf8a803f302b560b9f3782ac1f316a1336ba2bff3ccfb08aaed13a6238a191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3f61a4c5490bcd060dff8b9c28a69e28a6e8a9a326fe3c66d299a90c5acad54ab41c5b7c05776f0fdb1c39da92ae6e00000000000000000000000000000000074e925cee5ba0ae23092abf9077c7a1927f506e8900d8509f1c5b323d74a38c00d2501ab7c4e9304efe60576cec795b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000838180d3608bf17d8d949de03d91b1871e4a58bcf818861c2eab572cf5625a30a076ed0560c7cb41505e3180cb656c400000000000000000000000000000000056775595c8618bcfb11cbe62b944e67f3397045c5f4b07b65d595bf64726fb87ae300b8b81997219dbc4de1989129671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010b5446c938a0fb70242c352eda8c92acb4863c8496f18515a5840dff3bf2b395bf6df05cc6aa7a76e21a69e8436541000000000000000000000000000000000f026a9d2746d99c85dbbf5ec9f7ac1347e218bc3d2cd5a4710bcbc49bba269594eae8ba9c12327aae788e8d654549981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066bc772b99db3993c1654ad0d65ea88bff1aad0c0a714e5e82490f38d2154e28775237767c63a01288ff5eb0ea96b1a000000000000000000000000000000000134429fd827d0ce3ac96cb657113f278c15f9b18e39de9eee11fae8830c74bf2bcf8b1b0417acb97abddb6f64d9d32f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd09fed3eeff11b1b322a47ce3299e225ba9105f39916ae3f93fdce19ed756ca95f7f2408c88d58b80d474ae586e300000000000000000000000000000000001521a6cd2d76e935dd07eb511e085a42e96ab17fdae1d1f24413a743e99b9d2c85098fb88b8b72b4f1be8099a5467ceb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004eb4dc68a9e222fa5e97041037a7a3312f62d68a56a9ab036cc2688e202e12b9b48bbb092eda4f4bd2888c0365e3200000000000000000000000000000000015b50a8accdb228740ac42ea6cbad9e9df9d9a69b78697e963efdf918c787a1c89860e3384c0d13fe1d319bd1edb6d681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe49e93887385140fed86f065af5f26ace2fcd0d2b70f77035814849f37c7a918d443d7f5fb5b4171f2bda29b88ae220000000000000000000000000000000003cda1c7b1435c91c389057aaaa30c003d79a5d5cf377729d9ffb0bc7d14857413818ee3b5246a966d44a4d26d1b597c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031c9faaadbc4c938a2b549415590f679d6af42bf09ab11f0af1574dd2f7eef0b48e9810c40e6d2341a07a1388d366770000000000000000000000000000000000251443a2fd5c59d8ddb5e41447f1f0946e69a9ab6be208687d792a120b30d43938a1f38b8d27ecd982cd73b5fe5bc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092e2bcab95827afe4fc5313ace4349fe3e09e36d031a2548d6a5185f84857e2da4bbc215f5086ea461632af3d2b5332000000000000000000000000000000000a532862b949400a91302a94add18af9dba62c24e7b497d6ad134196d4385a618a474fd0601639354ec25ad3dde7b4671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075c27f00071971bdc1adeb1048c1f98b1955d603c4e4d69f74f66d2544a9a7c40637259136ed758cf7eda2cbeb804b6000000000000000000000000000000001279311dfb07bdcab96ff341d28eb77746bd268f2fa3492caa0f02272b17043e09cfaef088030c3fa8324d756ced66571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a1189c4aeff2e004e7d1236888bf741e1439499fd268581bb1b39fd0ab553dd6bb6ade98363931fa6a7fd74f4d6fb5000000000000000000000000000000000cc6f85c19c8f1fb460e29ddf7c83824fcd545cf72b56dffeaf0f9a428ab2cd71b70172e60f65b52a92e8fa37d946cb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012146524ccb8cb2faa14a0a583268c21ea99d55fffbd3278c80a93ebea010494906dca2a3d5afdce13083667fff5a06200000000000000000000000000000000000fc213a3f4e5363af7a4d8d7f62a54d93264cf43b55680b6c706a1c4f7efb822b9a6c3c0efcf9d2d3c8b414846c9921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107dcd28e7747c54f35dd5db9e5263caee70e9e7dbc2b7346ef32c821c0120a2c880a8fa81b0b6509c66bb51626e595e0000000000000000000000000000000017e2012179252de5172a940771acf02de4d94f29eec013dda0090fa48eeb52e545141b3ebe55d65abb1f885ce0b393881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a94e7cd33f053c0cb724521006dde9a0de77af19b233028efe7b6a5682a22d46a02cda55526d81ffe4dd0ff53e9d6700000000000000000000000000000000163ee20bf0a99b09c776b4bde73de92e728e258a51d5b97f4ba85a73931278dcb87425c69d4105cd53b6b63de670a3cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033c33cc3fecb91a6ae3607211a1863e35c217d66c2acc619423131d3d99f1c9d84c16c3f3820f1bca68b31d5ccd424c00000000000000000000000000000000190a9bf5522fcbb1e47d2eaf36efa78029f303fc075cc1ae07c4e2ddc6c35154f672c774c4a44544b2b0c7322d42b3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000289e570546f4808cbd4756f826eeb12f92c86a449e1f4506b033d8083ab6a5134774e05c67890cd4b4d16800d287af900000000000000000000000000000000137ca623b609fd1a1d77323fd4d7733ec91bedbdf2429834515432acc80e71c99772ace4d1c9db37e69732bd3f86448b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008eda3c665e9bcbb702c9ef2d75a64a52efbef49873d223635ba3935e02708c609a9f3e667d84216ea242ce2be5898ee000000000000000000000000000000000ad8b603b64146101f8c91d2d228068fd7ad13ef53b7f670a52e70357500ee06c5bb3efc2ebaf2da27ce104b384e187b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001620cd8c8df11fd329ea5883bbb7a650a7b28d617e8887513ef0f9b046d992444e679639d90e6bf9b487b098e7bbe30000000000000000000000000000000004d3fef213cf87d6c0565726c77692f8cfaf2732285b32900bb8f37161c03fbc1d45a03b2106b84f79fa31ce9a2b8ad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e8468fcb361b3c778c8bab018dc4472e999fecd0ecd9e71f488eff133e34025bfdb61bfed654ec68f8a2eeb08b2479000000000000000000000000000000001475667d8951d22ba9ce0a6eb2bef69f6c48f4b835ae66475dea344b1fc6260673c67b134155cbb200c7906c63d421e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011308b4a03b10624febb2e22b3f6cb66aad832cf35c25684294f93cc43c667c4e91d1db273d504f75f0bb620444e686800000000000000000000000000000000000c3886ab30f6e662dd52ff2122234a833a2a3592f6955719f548b12d45effdb31980b94c25b158972cc16c108b79fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ee50ccd4e9226c1c850f945f6afcde9caa3101a368d0b9df4138c4e86e01edefc19d359d03df76b5229731c26103fb0000000000000000000000000000000008dd3f5b1096559938aebd26eecdcd158333bd1ebecf2d1776298383fb7c15c66bd8c645e87b46c1b7f74a1a50ae5fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012eb73b7a0b284e20b2f0ad40cf151925a7e481fc7352f0f1de5662176afe777080c63502845ad031bd1fd99bb4ea0860000000000000000000000000000000002c004ee718a84bd638fecb7755a3267b0908f687b46fde7f8fd79ffa6ab5deca6eebfce3a8ef6ffe15dd293c54aeafa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9a3a94dfad2d1a4b04c593a6f38baa0f254bdaf1e915c16c81ea930cc84fa8ef2defa91e34541f7461ff17cf9b1baf000000000000000000000000000000000474806abdba6028f13ba826d1834ba3e5a7211ce582b99a1b1cd81a0f3522e21e28aabcef79094da3af67e30e5a19551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009b1d23d51829ec71a6b43ee084bb3d4fa23b1ff58e50eec959e6701ac25082438547522aaebf4c7fb40a81b916b71f0000000000000000000000000000000008fc4226073f7200c08865747c249e8707a24e86c34e9face84087781020484572e4391fbfb8b2ac8f8ed4251808358c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158ead58549a811a68b149c23e2e9508ff9388a5143872772a91245a5a7e09540e41fd37e47c7b767982d2437938909a0000000000000000000000000000000019e35957349a5be78ea22f50ea6ad9f95becc0bd440394344126b718681da15c4840a3a4dbd84153f31bc271de41eeb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002803cc9b2390e25712dc32263c6274b6e9e5ed071cdceeb68e61236f686fb7a0dc9bd4f83dfad457f618a6fe019853d000000000000000000000000000000000bc276a62de0b0f3721570b5fac9bdbfaf7e755b75c54f48e58330b7866ff5360e1a7919509cbe9f152ecbbec12989e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017233f007e11b554d20b4c66d506c826b53e73c5aa312d3edff95906e50382be6c2c30012ad8baa2a61828404f2a726d000000000000000000000000000000000c0dad0a3d241480c9a357bb64dd0d7da96de47a660a6f15ab5caed1aa0c09de91ce3e5c4e43a0333585acb93b9f43701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012df7bd0c4a5d257048f3a260674ddb979dffc43be8c527f1788f56aec89a2b1c5e199d08c9e4fb93a3884db453f763d000000000000000000000000000000000ffe3e828d07ebd5bb9ab1225b9b04e82137498d5864c206489d160f65d7c26eb2dd53e315f2597190510aca4cb728171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ce8e21d56a0225f99060d2de3450dcc7f0ade73ac83a8f33da339810b6642a8e6e3be4e0ec45f176ed0ce0bc2af143000000000000000000000000000000000e7b0517db283a0b65772876f9dc78d7d37f2072faeddd0dcaeaeb7e010166642348ee9087eebc1d16a79e5a17b63fd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9f3bf0a55295c28b9b511b0611f6787dc8279327b0a0378e929e2d97601481b1b31ce175f1fdac7bb62ab10928c42f000000000000000000000000000000000164d709d890005f1c9b6292a5adad2dc5d740251a807c1195d12f9a18e0554f8af0cce4da0d5cd6d16a51134010b0e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fa4fbcb74cf63357ec20cf5e389528b0857057f827b22d7c98e5bee335932b7864c13ede0ec3104d97762c964c9ba8000000000000000000000000000000000c76d4601cdc4562bfdce0934679a3cd93e99df558948d488a6c05d5de28ac9aa34232948d39a4c92f2d57c7f0d36cd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100404a0c0e1af655a0c170af2a139486dd8a5a950535cec29980a34e282bfedc42016b260c002ccbe092e72145ee93c0000000000000000000000000000000013d48060d5b7e8247caf74a33f25c9243bf7e6c5ec56e1bdaddb11768f41043ab8e6aebd96885319676ff116feada7ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fac7395754a061a40ada34bad9b0a1d514835b12e37a3561108c41e1386047cea53c0fa6e8796381b1ead5eb23d7d200000000000000000000000000000000190a1fb5403a9cb118ffb6acab4077db18f42209acaf8b00e8acd9dc6267c3e10e4ff10787ca5831031d2fb5b11bf7b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012c6e6c14cb1ff68552f7aeef04aa9a70236f0430cc6fb0920c3d4788330db7abfa86a032a6583db0757fbbdda6d2520000000000000000000000000000000011bd63ca71b181a7ab4abd755162932724a3efc37e74569d55d59b2be3f72c79a185c31117e50bb8d8748501691f91021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a0271199d1bcc10dc730c7ace19b9bb014b3c61b1c331a4ad79c22886349d59caae000cf4db5cb5e30242412523cee00000000000000000000000000000000089837f08733024f44cad0df5c41b4bf4e6a326322e23111d4c433fbb7ca3ec47b4789f8b267556d078e31aeb1ea13411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000381c75f43acd9a4677a7ca01a4cfad06f4b9fa6d8ce7b762d51deb0b2e8aa5ffadaaa3ad9aab3eaa327c03114a0859e000000000000000000000000000000000452658ad02a7a05125264b23c79c52f51162ee5bae7e0cb45f360759cb1ac4ff61c6350d734df51ad82a685f6b5dba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174bfaaf7eeae079a4dbfb55cf5173b7aabc5dca2d92fedb865a808bc0e23f74b696495f6732e7da79439a81ac149ef100000000000000000000000000000000056f5f1b11e65312543193826c5fd20d82b968cb122e1c6d41e294cbd2be551be488395f556c1c506d39eb16b04659a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012bbfe66de85a349daa8d17c53199cfdc23795f6272ca82b744517da9d1faaa90ab776d7de5aa1b1a83f1ff8954cf9000000000000000000000000000000000144279a62fffef383e2da43956eb39e4f40b3c36f6fab6ea36bec7b84b1fb6b61cff770858a29cd21c27a36e15bb1ab01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000853295f0764067431b1316bf6805d0bb095fc2dbee3ab01e21660863bc7b23117d1f49864b5a73d4498c277db5dd0bf0000000000000000000000000000000006d9351c0406ad31ec8e6fbbc06b00d1e8fc46dac3f1a3fd13f8c1757605e36830da693ebc2cafefd808edea627940c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc2cdd95c24622fd4afcdac5d4142e07563cc03955dcaa8707361535203f491584be38e15cde14c503565228eaa827a000000000000000000000000000000000c4ea0c587827edec68c5929c01f9b5f1de331a678a8c8f397f5736b84ec9b5a66741f24ccd1ade344da2782bbd192891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001903fc58d305ce920c122bda8957722a44b079ff202166d0ad4a766cbee356071f7f8f1f40ce31039d13cbb50da29d290000000000000000000000000000000000412d1c9fac9d71856412642b1c6d04fdc219641e59f35ed9487c7c913c337d80cc14d4b0c1249cbf0be5e4165da1a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000541dc34735d759c76a37bb006f3764d89c8022922e4799d503675d852cec5347c390e820a77c5c018200190649e4b4a000000000000000000000000000000000f380d28edf3190fb5c5af561779f472c3f5643df5b712ca50a85b01c7d7c5894d608fc407a635a2354dbd3ef7ee8ff01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dc81bab958902c0524ad80fec2a6217ced5b7d02448320dda3e2851b0a4395a1c87c797336f60dbb556d227b066e0b0000000000000000000000000000000002627a45cb80fdfd88879b68cbc0585f6707f80ff17f9ecf3857dc24a823f9e9bb9875d522f4046f48c060e2173f60101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dea9e366eec167c68bb9efb2418056cb640a4dbccb3a2bd6cc04a09028c4480a7d67a13a4449a92da20157061f4481000000000000000000000000000000000974660be9f31d459b6da4d4c9513b182412a4667085759fa132e09bf1c5f6916f38a6e89ad88c811311082c36fed24f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ff52c533b191b21255c9fb6f827f84a5e608cf4688afca81a3b27884f89cbfde0d9d827bc6116aa4a67f7ba239a85200000000000000000000000000000000190b47bfadd25468bfc62e068487b0a84cb3ace1a5909712b91fb30f60b081b1e93cd7f5fd5afad611717cf1c23069a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003854049f08e771b79e54bee7c1f6b3dde47120611bc66f002d037e8823cd32a81a7ec836a72518b5379baee7e8ffb45000000000000000000000000000000000125414c959e3a1d0a78bfba9224b147fd13a04e248a59c3237b65c52df290d7b9a2afff736b05403b355fee95d5a9d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c47ec0db805e4e3774b5e9a402909bd36e724d0820bbbecd0ff07d6ea039cef6194177abebd2cac1c676683840f14430000000000000000000000000000000018662c6fa3992c1bbb8ed23f9ffc816675667d99ed173eb8dae02015ebec2691ed615d94a82f5358f63c06ec080792f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001273f785da39204f8596647aada492bdbb96d2b22fb032a344c4a2d114456f431f648463ba2daf931db481864e9cc47f000000000000000000000000000000000173104686e5ec28b7a69ce937d1b26092e964911d42f5b66449314b27e69c12cebff23c8f3405d190c1c234651f94161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000819cbafe4bfaca62e087d8aa2d4e338fba0c0b9f3aec65bc90a604f62c1d31334d101eef4669e71a6d8850e9043755a000000000000000000000000000000000d46ec0b7911c29e7a874fce5894a41c99fb2303174d58ac1f58b8978ed5844ebb1c38c01230021c0a3b81f3858c912e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001016c7ce2847822d00d697907dadc87d93ffaf78c1f3da31a33b8fa33b56436f1b2b15e1a4810a2da092961e8d977150000000000000000000000000000000000f52c763bf7d67a07e66685bfd6886af1bd344cbcada7ff7e0371a009368f023c567b1cf7e0c5b9d622c1ee8bcd487f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023cecb99effe9cd992f840d86d7226b304272e3204d9fd0cbbaf0ab3be07d50ece62c2bccb3d37065074692a7da706e000000000000000000000000000000000b8690d8ac8bcfdb5de09f2cae1d96b59246b0c7d437421af86b77ea3711bae6dfcbe4a44b1149cbffc732df7fc578bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e992a2a297eb7e63f18200affb11f5b8d941a3adfb9554f404f65c8f28dcd6f9bce66eabfddfdc6d202f6f1d33314d0000000000000000000000000000000004ebb686b17428342097be1748fcb770b75bfea70a79316f3840bde2ccb133c475d5d75aa0f36cbd80d38397f53376781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007875bc16666e6709dd75b187719ec3bf2dea732b3938c7adb37771d6ae836c7e4640389ea67219f971929710d1e7279000000000000000000000000000000000147476ba3301991e9f9a99cbc4345e70e92ded560418285b7a8a067d965964b9f7972c86f3e0cfe41d502d1526f34d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009da21077f1534b46eb5a09a3e3efbdbe951b9098d803ebccc8040ca6d6107b4de658c7fb121d31dcee1b7f5d3fc3258000000000000000000000000000000000b8a0e07c99803f312da487e062e79ba223cf14dd5fe9c86cb3102bb6a97445c57e21f7f34415b21ff4b891d396cff1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1afd16790c25ca44f7c9616b7c4d58d7d98b3cc90404290211ed3bdaa7570be4b48b4684601d0178e031ca6fcbee1000000000000000000000000000000000130f7575f2178db4e3939cbe9bb6321cc59a143ee65ca06241c19bd8181b3fa281a27334307ed319336ebebcd771ce3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008febb3ce1404a784213246520299c1956196c98aae7a2c64389ceef9d9e8e8d73cf23c44f9aa00e4eca62d619940052000000000000000000000000000000000b4ffe3d6ad8382c64d011440c48d3f3ee5c81f0e3ad363cad047919498199758dbe01bfdbb1380ef1ec104a02a2e9db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001392960b7e8732af5ac56923e9ab4d1e01cda0429eb84044226d359e2ed726079e854e91e5137b481accc8cfb3d2179100000000000000000000000000000000061dd271bdfef68c28c8c387c7e0ab17ac6f595f601b4ac416e3044c29486091dabb00b926268f222b763879dda604b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a87046f2d334c3bebb0e124721acae080cfbd94b49e5bcb5b348dfb3a2621f5a1942f879a2cfd0350fef700328ae08c000000000000000000000000000000000980b518b0e5d3299427d9ab709c3c6e86d7567c483b4ddbd2bdfc0f34990902a20128dcd4781d056a3b59ef993151251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178ec0d791b7a74d4ced12970c7a57a3b310557dd90a05e7d5044c4cbbae3461194738c990a10c2faf2d84e82ad939fe000000000000000000000000000000000dba49d8429a64cb503746f41c24bdde9776c930c1e52049e9c1179f23d2b3532c4b754d74f05619b94a642f007f84431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059dbd83f88c2321dad43bc3d58020965110cf77d62a3ad59da908cf4923717e0990b9975ed14fc08a954457208d6f26000000000000000000000000000000001512dae817be1fdee54ea080292d3db5088af28ca66fac122eb6ee858d20dc38685363a8d08a9a1161cc120d552199a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019df95d91d2c55546bfbb5706f0cfaeb25f39a50500fedf4cbf2f5635bc5055aef8120f05172af7a2065bbe978baf2400000000000000000000000000000000146917c9e5a47135b6c6ab1b764880fdf88fb64d5ea4021c9b692213668f902afc89932041a2c917f2829f10a5b690351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e8fdef9cacdbee0a23bc17c40943a68aba8f8d77a3a5f9f326b70c7efa93ee0c7b100d04529dafbd256e6922ac3f3d0000000000000000000000000000000016d765cc7fbec579bb89402e553ff961d4f19cab4fdb2a24d9c8862146658e65d5ca536457b0bda73ac8c3056fe7ece01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001684699568b7748c179602148c8ac337fc90124540c6732a58ae320813e4587b1926bc729ad0f4c1902a0824ea664a8700000000000000000000000000000000012db1c6ac720a531b674c190354f706057fc18b6de1e7c7b1439cfab52c696efe4194dc5980489b2ecd7a45ea0cce181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015df458d1cbaf2d9f9f2cc92e6f266243ffe71505c2d0267164a5da78cbf2c2d0d9e8b70d10e3a254f7103f75e4ec84a000000000000000000000000000000000cc409c21ac675b66a3a53e90b125a499dde3457d07d7514e5757e3c166d40a77a133597eb2cf9bd3e506e8ccac84c6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e399b33cca2a2ca53b01b51cd1a657c729c711e9654cde8997dea0408b1158e5a269b1ee419767176854c30bf2aafa000000000000000000000000000000000305efa1b778575da8c5d116844a290b288ab119635d6efb2badf848f17f218ab1490aead65940b648d42473c2e29f9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146ad132049e31f5674161eb7583e753a0981c89939c7a2f2467558a326a816007bf17bdc14a3f6d2fd21f77cf4b8516000000000000000000000000000000000d70a9fc5663eb6210b2ef7e60d6ce450f9776cf4d5e845d46c99d158cf9474ef240fc7cd6d3450b9bd60fee6a6cb75a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148da33cb66c0bc4d40d8da6ea26282b54886d266a0a2ebe5b4a9d6d43bf050e5e6f4a6a786d2c025b46ecd67850a33a000000000000000000000000000000000ee3cda47faffdd87ca9f985947345cf858f4dc3ff75707ed18b80486ae0bdb12e4ebea73c36cdc98e40c1c1c697bbc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba0b7f8cc0333f39d2ad13b760b12b6842641bf744fcc581fdd8ecb0f7f4991b9f2d272a2c19b688bc22f0504898f190000000000000000000000000000000019e5e5728ab067ae4912e188eddd983faf652bf98d02436455fda76640ad94be32edf17aa7c65165d9aa07a0dde0ce511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5a5fbce11e265d90110cd27a8a5dd44e84afa9b47b202d59b2e2494cb3421acd8a5c9ae626f9aa99119a0a6c057c3a0000000000000000000000000000000009ac6c7cf39ad858e884c60a48909f8eb8c93772293b672536b12c911e63c5088a025c5d0b651558c2ac4fdc85040e7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b8a3230503bf9eac8fa142e8d9590237d13f27243dff1e55329268ca81b9c8c621acc1d749072f7476b9b6993e0e3e000000000000000000000000000000001803f22a509c5b6f1e42e9336a9699acfecd62e51047ff0fa34edb29628814733710fa1ceb6709eca69f796ef747fa8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001441897d50b210b3ba99ed0b52c1f2cfbb842682eac8deafe16e254a9fbc0863c4e734ae3915b64ad1a66ce0d9a693670000000000000000000000000000000016ed42a66f357aa42f872ee51ee6c252ebe6dc1cc0c4b1d46eeb63dd3121bfdf46beaad106cffe7764ef5749a8ddfccd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d2048229aa7ea8424b2cb14a8e5f06fe534c5a39e3f9c094876edf9cfb17c1dff605d34e6f4a6302a6913464a04a070000000000000000000000000000000012685db80e805efeb0daa21b847f1b9dd540596d9ef3f3f2c610c8f517384c96ad4fffc1e1c1b19a2dff755526f0db851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dc120f58317c5f1ac1d145a0f40d3523679d78e7d7779b5e5f7fac66394b4f5ceb61685b2556ac1c62630ad99f9371000000000000000000000000000000000078fdd01f457ba3d3bda62be7beb2b780fd4dbf2620128cb18d5e38fe20eb352d222e7c710e4c43fa8682e60a08a0901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001210389741e66f6eb55b79f8ad96cce4231b76ce7ccb0d06b5c05dc88c9c26b64250c11b50d1acf60fe4a4b2a35e2fea000000000000000000000000000000000da04e446d92f9478bbed220a2ffbe44fb2e74f5b04d0b21a52ddb5e6c3abd8a42947f39c0b0dc07c9a960c7634597e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a19ebe1ac3216d222c92e6d674d38301c2f36ba04ead61766b6ded9b399b9ea4d47c643ec1818286348f42ae46edf0000000000000000000000000000000000c42b3f4ba530cc92b4503112b35618ca22fdd60460620cfd45143b73409396cc5dfe58bda6c13b91e17b5acb76e21091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b5696c27abc84458c8a2cd7362d348c4886e6246751c188b5a46a5873c79fb13c0cca07993317d40baf87c35f380c0000000000000000000000000000000019413c058f6dc565a414b4bc73bde15bc12fb43348533d889ef4fc276c62329462558a7cbfc55bff6555b82152343a951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fa2dd6e3ab26bc7a44c634b052644baa4ef5cbaf452601e686a3d3e014a2c416e5997baa70e59c48367c68b293a2a30000000000000000000000000000000000e7a3ae7fb86566575087567ba2405cca2ce713057bea5d324e126a4331f3f1c10cf13075d13ae4571e372d708614ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000733592cf60a16fdf4d83a93297e9248c70dd3aba8c950cc7f6c70c782a6fedb8c1166542d2b1019bdc8c6c0ffe21624000000000000000000000000000000001593170c3280012f0170dc7d84be2676d0041eb8298269005c80c64982b16694f39dd3b9d07fb96f10ddde76e019354d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053e2edd4fb2b57802d3caac5137abc025a463479c2cae77a5358e6e010d5e26c991f0dce0cdc87b318a04b258cd1f87000000000000000000000000000000001645a1957f5b267ba8bc83843eea174463c0d703dd12ef6383cae06ec782bf60d3bc8fb110c50a52c25bf029bfb383fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170dce55d05fbd5a22c31f1e446d7658eddbddbdcbdfa8836e0e1d93ccaf380fdd0a043fd9ca9e6b814755d7f60d99f9000000000000000000000000000000001716ab66ee96de04f573410d130da8feab60ae683ad2429fcfb9792eeec1076734f4d66ce6db7d63cbeb96f3c7ce2e091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c99a2fd35fe5e0e860762d74098bd3608101639a881ac9d025f4e8b0b61352bc91ff03ab51e27293851832c1c66ab9000000000000000000000000000000000cd1088edc93c45ea7f80d4cf9693adf87871b39d5bcc514e475b5c78052821111c4260bf7fcc4cab35ceeac080cf4421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b78d29a1860396d08f7898de3b46eba45879d53a205498959441bf1072ec6e23b3cf6493469eadb9fe2cd421c76b4e400000000000000000000000000000000116b1621ca40c598fa1e9886af25e7a882a3341ff75f4146a3f79805435c6c9d516ddb681c9e044a7cce2f52eea9d7c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0186021eefa7c930d48fb2008b8c8f2458f91c08bc16216d677f77b7ec913441c057efc2490f2c83bb5ca28bcea4920000000000000000000000000000000009a6ec839758efce3ad8b29af52a450f3ef84ee37a1eec54ba52eda0e6acb2cb6e8884896b9eae94fc6cd3989f784b641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082b8f9133eccc3baee10198188d3a3ad67c311ec8419afd63e6f9767af82f24f032d840fdc14137f9ef9e0883a7b4c1000000000000000000000000000000000131a10cfec6efb1566a600c5177ae6b78ea1239d1f6e76d19b9f36aae7214242fa1796892750d92793f6b6e191d34441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159431b25e9d2fd86e441921de5baf52f79442ef0eae41b68c9d06793d38e334dc04ba674a2eacdc373c54063c4e465900000000000000000000000000000000075b2266665a3f6aa3586073a167a8403fe0266cdc6a54ec7f284a043ae62b61f402121a790cef51f5857065074c47a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007722394c50476ebc7dfce5c7937851a4a77cbe38732c9b6ef6cfa5b2314dd4c3eb7475ed1c6cb617455cee653bf38b3000000000000000000000000000000000e78a1caa5303db1f7277d50154af087989c3a4239f2c0293663692a497bd655ea2a1ef39aafc3fabc85c65870b46ad11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001901e5eccc5fbf7e48ba8666e2d18d101312ac0ff1aec2e8ddf80d6c7e679d6f95a5d4ea289b80036811d6f10acbf1e8000000000000000000000000000000000120a62ff4e9799b886dac92f119376b19be0918ad67c234eaa86b877958f1e77982054111ffb93064da85a7e5f5510c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e86e1342b517d7774620114d5b19bea3752d052494d84bc944dab2807c1999ddb023816a468e22b856478aafb496eb000000000000000000000000000000000ac9568feab0361cce9bf4278baade58b8192d4333e360735f24e14e9e0399f387b7d6aa8f3349774a23fc342e2dcecd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000689716a41dbf3b23612afdef840922b558edb4ea3d786b81f4fb5ab94ba3e01404aeb5170a5be30179977f0e019d514000000000000000000000000000000000b8bf283b054b3245bedd9f534834523af2b5e2cbea68d2de813c5bff81764492b47b955d41817d8af2f02c76868e7331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047770eb09b93054e1e5d59ea23c5f5026378f84f3a35be9f288e4d5796b1c115ace6c6c36ef74b84e3a97aeefdffa8a0000000000000000000000000000000002b52e1575c7d1a4d33cb720fc1429ddefd4b5428f96ea2237c1df3110a2a29ed1ce6cb0732f5f834164e6d97e9171521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dc9c74edf387a46bccabc3172b46f46e9163c25bfe30ddc02c7a88874c333d5804f3e97cce2bde43627ddcc4cfd85c0000000000000000000000000000000012c7c98ae66f4d6977abfed3460a11853f631524481d9f57b75b7424061a76a0d4cb8e7a6c9bb03c17f104a6e7a271f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139a42b6e16eab536c4d27ef4f95abdee9414324f9dcc9690ba6fd53565d1b1da9f211cdc4a60bb96060c030243d93370000000000000000000000000000000019cc3a3e001fac565940b331430843203469c17af9d2c796f424d6c849dfe0bc03fc6b70cf67eea2aaea4626bd2bae4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011223fd60a880bb259554cd98c8e11e7310017c16d731bdd15b1cb7e1b1385f44fa5979a60b97ef1356613a81672a1290000000000000000000000000000000012976c0483c6839f92c5fb702c73181d415fd681a5f3a16814f45d080aa9e0b8a1031c92152a4f8a980e0317186cb0481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078753794fdb85cdbea4cbc74891a7895624885e51d09c24358f6171d5fdc8717ae5ce331ceab096b88dc7cd4732717b000000000000000000000000000000000fc328c7422f0542defa870dc968796d8d063f448bd11fe6019d891bdfc7f265923a0fb1fdf475165e9235365f72c1191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198ca1c512c1312c33ed3d95cc65bf9c3ba58bcad5d950bfd9fc4a24fc271a715d665813cd34b15abbe1d45add1b9986000000000000000000000000000000000a3acc0d8297f302a1a336fca51de16e8eae373499b7960c7f1e81ecaaa8b5ce9a9b540a61829c1d6840620660b5c00a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2169a37feba05c4f3cb6e8bce5e1fcd587bdbe87abd58f66d6455621cb1c8027bc3293fd93185483f8aa57758e2c39000000000000000000000000000000001540efd6ff350d53841516a5763ad2257ec1bb880cbed1c6235df6c9cce5d49a429b7a12c5735d279e27a0615caa2eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091009c5a5d3940bc98a5fa1ddf195673c71fe86c5103870feb30618f4b29b83fd118104aa21ac7770b6dded4904a9c80000000000000000000000000000000017f8b697e9b057993be628040eb39df0d77aadbf4df36a6ada26e0dff9c716f00ec701caa37379a504102ac57000a3861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002b43018bcf395dbcfd6b465d0ccf78a691e389ad0f9082c00fbb5d7d2299af268f57074b5d7f72bd8edce35ebe592000000000000000000000000000000000093b938a6d95277d711055b5f2ac39db305afaaf39aab26cfb6d00f04ef33e4df62d555e47a0021a3ef80da778bf58cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9f958aba08e01dd28f62d54b8b1c37653befb36606bd8a18053d53b6da8d751ed984daf5a4b9d19a9de65f936fc54e0000000000000000000000000000000014258f6b0c40cbc332bd980b0e781a4ce62bdca790508a19620dc11c72dd0e81539e5a9a083b7e5e2398e735572269321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d734564462983eeca9a7ca5c3475e8746ba2d197bc06812f79259518b1ddf2feee452f80a5ec37f007e4ee03668cc36000000000000000000000000000000001970a2c52e7195d585d49ea982a7f22fb0a2214bcfcd6676452df9f4e0732ce4128ef19d2f1d9ead2adf913e8fdf36ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ff274406abc579fd61f80bcc9678c9175cf4721ffc42dfb049fa993496a36db96e6f311ef64244b717c6140ca1f45f0000000000000000000000000000000008fe505adbd27a4a1996a8d506d2eeb2dc1beb578d4d3dc881d1a7bf4233604919822602189cdae7888d4f139e47b60e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fab864f836bd63ca545d854e49d60d2fc46ef81b3ca7f48d3c9ece4ffc602d57aa91c9faae7bf51a494fff329d6eb6000000000000000000000000000000000e6b64d1930e4d26176951f49e847c16de5031ebff3c8a0e76c9b315d186004b9d6b67359d69e2e863a9b93da0ef8f2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da15eedc5a9f943d548f98506588fc4ad8ac7c4bf54f6c137ea29e9facfc35d3012322b086594412175a1edb0a2a3f0000000000000000000000000000000000d559c4dfab7acedd8dc97230129a688af4e874e43281b4ef7738f2075d7f2a64a10db1dcadb3f3e541a4c3355d198fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000508d39d74e7718e4ee50bc29a651c337f1e1ad838d68b5664c5da58e28a4754394b1b3dc6a298e7febb2e8bf4c82258000000000000000000000000000000000e605cba8745acd1629333d24d20e188f0edd646fcb525fdb74ea8d860fca66cba5f85d7d924a21993e8ef729b0a640a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a86eef6452a73f29089e5471fd1c70b9abef3968a6c52e747877b958dd33de9b4b51cd617204dcd4b4765ee35150c2f00000000000000000000000000000000092d7edf7866c59a58e9a46f8a644f2d6939ace882dbb6012f1ea6b7c45e2535b8f30bf2c92b3974c1c6f46e545ee7ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031220713282162fbc06d1f0c907fadb00f4d8e76cc1d535b7b6ddec53583e2fa5480db1c5dd3744cd10a2eaf7373029000000000000000000000000000000000328f9f0b607caf0cf344f010cc01a6619b53c6754b1d69a056dec33bbcb935b5fb30a9a607d5a77f32ea352cd7281dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095f0c23c723c191343232fb94f78429c0b1a4358a2909ddbc0fa1c551d49fd9188d10d656a554a9502fac1c4ce3075700000000000000000000000000000000034fe6f5e96a53036bd08b703906dc036cacabf7b88e808fa20e4eb48b192d1a68b327e12a3fc01ed0ad228b3f6ade9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001530537e6219752ad593cdc36fdc341487980c2fa4b2a222f10d0881620238d06dbdd40c4d1455c20266f659b53db0670000000000000000000000000000000015a3ee553c5670805471330dac8606adf848a1aad3b3285b07bd701894520c33702da3f6bc245c60f1ada98d95eb03471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000944686623548e4027a3c6349e6491b1f367fd879bde5ced04877437cdb079a042ebba2624aa10f459b858e5b08230410000000000000000000000000000000011e5a2042e3a687393495f96800c5e2d611c31771bed906a1ea14e85f2572be15614c4bba3af34630b63bb901a75ebca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001290272147436fa476d6ea60c005a7d7dc33f1eb69163cc2a71602bd38d7f4ad38184f4e72bc23935ecb798d368c641100000000000000000000000000000000122583b8d15ed0ce8dde481b491ade54f75f37c987d0ac6afb2098e02c84e37429e36ff3172503c97bfb4b5cef710f461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fabe8fa751bffba9a1d2971ad62adadbaa6ad86d0f5a26a146dc2f5778aae36f3826048e4a195f1c8adc2b1734992a00000000000000000000000000000000149f38eccc7482a50a62348c1582b361fad08f3f51dff7e62c691a27c55980c07cbe7bfd7c0f9f4fb100d0bac78ca5171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001656ec662ae7a60c95f37892deb1fb7931c174a92cedba1d3704f0d8e43b96a485514e45fa396d91be8644b4c23f464300000000000000000000000000000000113b12e1dfa7b996851847c92d3274232ce74a4f800968cf5595ad10393a78b7a4d731318da5a3341ccd58259748fb1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000956cacb668658a74830284df5b29ac22496bd202cba4132f5da470cf970f1121f1cbb3e3140c51cfb92661f797170530000000000000000000000000000000017a5a7a5fa41d93956d4c6bb3531a56c1d86ace01b8a0c28f4b65c56b02729aa3cbf60478935042b56da80a1bf655a3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f30d40b6f20887eab9cd907cee1a1e68d493e9673e44cc978ed0ab164139590f6b322a65e3cf00ac454f3ad1b62d1790000000000000000000000000000000003e2e7c24804091d180653b4159a858be58efef7f60bbc7dc82ab1647c5e9878239abb29b0302f4c9adeaae8898908131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000632e38402dc913861dfe9884a7cc7f7d2fedc72f96ba01b2509c25ae19d59102997d5d0b72c37bad2a9b58b4b3b6fd800000000000000000000000000000000104714d6f472e37d079a4b150f072e9d41789bfd0b3756aabd5df7952310e5921eab1f68565fb19014ba3caf44ffcde41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccd99971d40b308d1d68c1adf95c49a47fee69d0df2da72922021e7956bd2b652192ee0fde520d3526accfb61c042c00000000000000000000000000000000000c284c2a540eed2424f9fbd87861db5663aeed81d37d5c3a1cb54136549f3cfdba482ac5ba02fcf3a3124cae112751c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007835b602011904ae2b68128a96f4b6f709c960c010ff38df305c1f2aacd7a06e6428fcb1a5e91b348c84be3ca06a01400000000000000000000000000000000073aa1945abd28e200c880d57bfb926259623bfd24f20477973bac419399f09086d9c991ced3b66ac46126276d68fa7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008c2d71063a235692dedf9de76c042cf205da9d677b70e0caaed6a1d940f4231a7cd0e1cdbc3850e02c15ff0842d80600000000000000000000000000000000164bcbeed2534344dcf4de0582656e9967ca74baceb2d4a48f3671a284d6c09a4ff9fb4f00dfb236423476d269e943f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006c178e3d7b6895258014039ba7334a88ce19281878f735280523a4c94e665af641a4f17f15783d1c04026f4df78d12000000000000000000000000000000000484daca265f39a00eee8cf1e343382a55d851e3126ae125f344f8205999bb67f0ad099282eb1dffa8a6763e38a832eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c6a6f0231378bc28813339ad49ce2908b2ddbf700407352ccaa8c7ff8028f81d73c783a96f64708fbf9c8f6560871a0000000000000000000000000000000003cbb53b2a9294edf930e644563d4f0e4138c8463a3e0743f44b3b29f290be253f7bc1fcd10563f1b93972ee85d902971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b04396d49b3659c549fc5eb29cb134483a2baa8ef2b9833e0c58daa172b45e2f25214294411fdc09204a10193e24b6d000000000000000000000000000000000723892b5111e4332a2d6421a7d37f019bb1ab9da612a78044eb391cae0a9eb1762db45874285965846173abdb4933c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016087fdc8f38d75ec25f419250be821a4dbf4e0abb393e0629f2062864e3aae3ffdc54caedbfb60062840170312af0780000000000000000000000000000000015d91ee08c56cb73b7f9e19aeaa890c886f7c851340f342ed3e7822bda49442e767ecebf341bf17bfeabda7966513f721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc2ace7304eca1ed0cc7b04fc2188641618413940fa42ab0c2b8b9d934fb1088a34461a8299c75da37aed000cafa2d500000000000000000000000000000000154dd78d7b4f72af194151d628399f9e68e8cbe8a5b184644f6cda2299a31c5d49128dda0463af8fc17ef6dd8e6ee5ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068920a256141bdef5e1b2722c4a513572ee5b9dda923f568a2b6c079cca1345196b0e2d4777eebb415c3ec63a73f1740000000000000000000000000000000002e605cd7a7c939e330c0a6154017d445c699af448bc6132bdec999a01c7c64f383db6f47ac2e031495460d6a78f29f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d88e636ff291c890d471d7f4f0c05ae0b980240c330ed06488658b6de8004e4813e7edd5318d8c48d6ddf31c0ca2020000000000000000000000000000000010d6a7722680a3fda70db776c14623f86925ad25175bef333be2ae10ab2bb00a7d4dc571936ded57bd33d999a6fa36d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1d27377b3a4b06ecfc4fc01515ab813323709141bc9bc0e9ea62a5b722e0bf07b79ecf5f7e0a8da7e96e66c68f891b000000000000000000000000000000000666737d4356c66d7308b0dfa1fad87676da2e7ff51748092e46ce373cfd823500a44a9998bd295ae78b997ff8b69c9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015111657d70d3892ccc6c1d63f970c3c5d9b3c58c34b3f685c1d522c05c49ca2a2982efcd6936a031c327e891fee61420000000000000000000000000000000010a4b9a34b0c56715c4547285ebc9e0e7a3f1bc4cebbb91e21b63018fbf19e04df94086dfb4f3fe7dcc48253d4bb71161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058673d76fc9e53d646add5a3f870d8c6ff0f86b56bd44106a33cb8ae2e8e7d2acd367587a3f286fc88f250733adc227000000000000000000000000000000001160b9af3915e07d7ee7bde6e5dbe9fa4fec6f0a98a1a12a27b7c0169bee2cc768deabb37df5e94a087bc5ec09e6af371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c507b3b3911a1b8ae48d55e676bb202446171993ea93250b782c0384414c7f87d1fcc1fd8d9a075fe6e0ab5d19467b000000000000000000000000000000001388b0bbf1a4a7fd35b187851fdfaf3d4c24df87379da0fb846b59fc81259c4294f05756655c9378b758cb1d643d54341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b682c786552d55edffacd83fbeb3368ebda160cbd1db8d21c78dc55ff410ad24007a2c5183bf4eea8f4a5d2b4b98569000000000000000000000000000000001105f1de1b1a48956f54fdc89b952774e4decc9e79871bdac5acd4cb3c6e48d758c6ecfccadb66fa89ea796c475f96b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a31d1b778deffef6618aa9d215b7be6ffed3979dd1cd65ce89fdff3e35265a0eb491cdf6e19a9646c5251bad5d14c0700000000000000000000000000000000069fccfc584c8331aad1f327b5f292bd8a8c281828ca3fb8879bfd94a571cc587affd7f4678b82bcbcebcff01851ad021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f5dc0a3a3e5021968158c9b67f09ffbe2bcfd19baefdbe39910545c1d55fed5758af1dc1abf6a87a298a70ed1cab54000000000000000000000000000000001419cf68824b8a3a03e5316f55540d13186d00d817557edbdc5e2b1ef85033faa684ac5e31ae0e3f85f7f6b50d0a577e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012464d3ed71655e9e810e34f41e54c2e9409231237e320643f15aed9f33e837e67767b6bc7c733a34ddb311199cdc57c000000000000000000000000000000000590a5c6607aebc86ae875cbdac3f99bb452aab41f4d134e9ee1ff1f0d02abe194518d91d81de33a0bc9374a114f7f751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b6508dfa90f3459ac9a7f0700c34885c3baca593df3644b4f54198db204729bd6cec39a12684d2cc954d199fcec244000000000000000000000000000000001927d9092c5c8273ed994380e6bf08918af07acf1a14d3cdf8b7970e1103988e8aba0b99f72e14413071441f7f5d201f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1aedee3270b9c4c20f78fc957e4c487aa5bf6ba165780c96e895400c8ded33e7233b75a2ac16608ddb6a673ebd508f00000000000000000000000000000000116f6a6e5870cb17f44af54c1ca69dd97f0efbc513f521263f52e4ce4e3692d01ac6420a797c6296dcd9da33fcd793e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c87dd44b0549209b8dbb9242d5469c77dbdc8fbb0d3c6cc6dfa9d89018ddf459101e85fb9f568adbb4d863587aa0b6b00000000000000000000000000000000089e6b7ac9d6f696e129337762e068cc61e5481045b583149564de250576c025bedd01fc8a59ff3deb66a781c10dcba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000717a213568431157521a420adf4e66ace80d9bb7ed7e87ff8c8412d7d7ce9c399aba9c86e784637683f40629603fc3000000000000000000000000000000000d9fe441873ed2e642b6fea7f025eb4f016b5d43a263d0fb5bf46325b27a01bc362297c217825ff462e86c888b4ae93f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fb84ee2857a6925857a195e4f7fbde27a94d8d58170b9fbd412e17080d04bf60cee58f27b283ff38cea8a87cb36045000000000000000000000000000000000264431ac58259a6637e31b60bfbb67deb8a704c0ecdafd9f669ca24ff246b67c8900e6e4155b40c200f5541ca28ea791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143c4bf59c0feb30af7351a5cd57035345dc95eb3480c28d84c1fdf3f6483b4ea59a8792d4b508fc0eadca32a575893d000000000000000000000000000000000924de51161a062c65d903bb38591e50a9e9009c56f3c01fa53052a249129aa37917c285c48f10a2985fc66a7ad7dd141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e35032d2b1478f7d3320aa332db52f51c6ba8a73022751c4810ed080e5557cf8f7f415ba76e197cd6eed53b8e2993340000000000000000000000000000000018108de6e1cb75a85f3c0722ebf2f069aca9018bb3a56d1581b93b3dbbca8f799f9adf2c81ec475e6f4c30653e0336af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001372cf1d2b6c5eff6664fccc9de01729ac77995b63bb24d1c07bba8e909f7eaed215e1bf75c8d2122ccc4f66a0372c380000000000000000000000000000000001c5b70b9025863b2b31f3e14c38dc5f4f1591b21853321106053fdf6b57008cea654ebe0265420cd8a646b4061317a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048c72b1342d98b243a074068f028eda2565c543cb76200ed141cdfe1c162e075b3f404c2efc35e8d9993989a29c9c090000000000000000000000000000000010668156632fb5e263a3032c917c1836c93137ea4adf11420295d09d39000e293205f3a4a766bf6f128410514b6a47e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040bf0af53dd37d037dbf6edd791f299c4cd5b7b6df4571b6e99cec7cff3e4a649738b3a81e1d82586cf9a7ded70f31c0000000000000000000000000000000015fe8ec6865e8bdd40a47c58fa54072272636e0978bcb8fad1a88b4a5a6c88329ecb29a74afd74f2e3c9b7ef89d2b4441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001271f98776dd76cd3955d37fadc193ac0627e9c899505fc9882272b19d1d47dadbc44f6e1cb31cef63beaeb7e5ff5ac7000000000000000000000000000000000600dfd03e8c1bfe3cfd6e28696b901b30d5d4e9f2633d3d11be0aa83e08c4887833e81827d73c5dfc59e516c0d85eec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160314479b4863406cc1617c4e4c733983fbf47f3920df21c226b18c24b242c3b4b5676d55e127cbd5a35ecacf4cee45000000000000000000000000000000000cafe30a3ba39e04f28692fb36714fec7e6ab53439d637a6baada2114c5e374c440ffcc5a1d9f5fc9f0d3ccff8f20d001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b831e5f0dc0fb74757f8253858358e2d23acbea566dfa384ceb03f35001d618a0c72c8502633185bfd0b4d7d1fc6d0000000000000000000000000000000000f18ed9f7b1379a9fe02ab3c87bd5ce2881a5ee891b7a7f0ed80ff6e8e5438ebae7ebd146af70d958cf4ed734d4aa1111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105b14455cfc7ed1b92cb689694bb734945a0236dcfd54011f1f7c5b79c7d8a169135ba20d866274ea54a254df39c03c000000000000000000000000000000000ef3659e9fc55d71dde6d369f1bcf5cfe0d180d0be6c51076362cdb762d8d0be4b4f3acf49893666b78f2d7b604bc3861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0388b169e5509e42219f1bcc4e0f429c7cfe0688d23eb74305004b51ec5fa32d4d933a29e14d9bda492ccbcce604180000000000000000000000000000000008b59a341aec9542a224772c491c666a723c80a55241c68cad31c8d535bfb002d5cf6d85fbb5cda55dad92d5926d28601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a6f654fa95133f5b71758244ac30e66352c6a73915651f95792a85ef8d343e45f5537c5fc2f697ade2584eb6ae5a700000000000000000000000000000000013aa828d78b8b15d283ad0db332e58967c24b5ded030dff7ba7cd24ed4deeab08a8747b2947652b855ca10724030b9841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caa963604cc8938cfe63e69c4caafd2ba420b778232db1071e1c831812d57a8b239b00d09259c4e0cb14faacfad72fc0000000000000000000000000000000002d8bf1d415e7933c5c5f7dd46227f2c9a7c0d88f58aabde71e83052e7e09d47a74b4d53245a2756487549440bc859191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b712199f21c725364d82ecfca7a6d9ac8405681d904dda9eca93ec221a15f4e3bb471781e62c1cda29272f7e602af2f000000000000000000000000000000000f0a26cf0a94f2ce9bac54c521b6d8fb6cb620b3f3e177b8ce6eae08b85e07268295c1a4f810c6e18fc2b7b20c6712901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037ac050e2be964112dd0ba5fcfe7eabd7bdcbc2a8bb2dd84175b844b6a5578ee03ab41d8acb073d33dcd43189d4a5c20000000000000000000000000000000011e93dc6bd54b85e1c1e4a21edf71f3ea148ac31dae7f0252016e9d56451624d0fc5c8b5fc0060f43659c6c14bc0aafc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b4c481518b7d5891335cfe8d081f9faefc90c9be6619ba1dc3f8ff086c6bc76efdd5c9a950208ad3d7fa3bd3a6f6040000000000000000000000000000000017e10197671ec37b013c339e81b5569b64f24ee138b8084688ed25fdb7f92f50a5d39adde9aff81ac8ad2965657e8e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bd328fe8afee0c4c9a2348c39e09cb6ea2564da01ee5bd971f04a5ef615868ac6fd571d3610716dbfba2761993f1710000000000000000000000000000000008bec344e45d27151e904b65ddcce9e51acc3a215afe8ea191d9254eabf4254b38b7612c62f8c96b7f152d8b30e2ce8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125de9899d0a983d9797a44df5677d641f7d72cc7633f909188d46beaa8134460c5aca8fa7dd2c370dc50c06f161fe79000000000000000000000000000000000ce9f83fec4118b16766310a518af679d8e5b265918472a68f9aa9b24b3e8b2d279b68c7f0031205ebd840e0d1fb27041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152e94fb80bfa6bea5ca01d201bd02b9878a717f083ce75d908f3f10b255a07c3ab3d25b5d51ff342d7eda1760b56f4b00000000000000000000000000000000046b2ddb20d395e8babff7f6a69c18e7fbfa10cedad4688e9ef90b0da41674a348fe2f7e641bdc5e27b8b29dc84fd4251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ab6fc3793e1c72ef6846d828b13becb6cfabee2d6ee6bc0ad9e9c4daab2d419dfabdde65763623f540b75075c9d879000000000000000000000000000000000b90502647c4e9204ac24d207c68570050f9a4bc9253e4fcc840342c5372d138c5cc50d1895970aed9046097019c32ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153390aa01866b9354f24d25c1206cc36c25e1c04ca1c3bb0e57b7487adc700ea082a448232b8ac2612864eee6df4ca90000000000000000000000000000000000b695303838b83839019f4f2167293f22d202dcb6482e379c6cccc6fb073dbadc7cf7105050edd85cd8092613df7a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b159373bc1a70a2e189a1347a352d5076e3f1c9ea89c52bec1cf9881e6c31e6d6f7fef2a3deccff421cd4645e4b7830000000000000000000000000000000000df52d38438182fa2e1fd4666bfebedda43566791701218ea17baa68415cb5608f602938e20984e897d207c73b92f5e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dc1d6fe9d847204202721c0eb12197d24fd0542923708304afb8163af9479c3972dd1b8dc5b35e3daff34c4405f7ab000000000000000000000000000000001739e6acd835faf97eb98a500ca07e2d0f0b5ab334e7db818025b30fa714398c9bbc2ffa2c74e0876171f3f4cd1fcd241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2aec119878a178821f768710f18d9494247567dc41fa1fb3e8694aeba8ea825da4f05ec7092fbcb2a55403ff48c7a30000000000000000000000000000000019b25b73eb310f57f8382e0fdbe1ba0c140e9c1f00da88be7f3316b08c2c0bb08b209e3b11228b88b8a82d77c864ef231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000604444ecf0e9ed667ef886235bf7c9962440168c34f6e0664cb2ad2a5995f252b39c4fce4c31af33e37eee212a93e26000000000000000000000000000000000c3b733c51c9fa047398c27441ea967f3e5930ff97055918b744d75e23565255d6aef73b2e1db6f1fb9fa6f21ab460391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be377d4e409363c98e5e36083baa1ab3bebc319eea62c64789f35cd775834a85dd11ce04d70b96e79f43dbb4a5d6bc60000000000000000000000000000000011e67d3f0a725cff5de9f5fdeae9ca53eb6f5c3277cc6d9e31fc11416c6154361549f6317ff2906f35ef045b785f13341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f826a48f4ada87b6ba8b6c524b7b4cf23edc925b89d75e6b6ab8c90ad21a78d08f93da8f2c20d66a37d5bb043cfcbd00000000000000000000000000000000040df76bf9104060824b034b908f3d5374fdb2adac578a4624cf568400e2f8418905b01092982489d5434e963adc9d461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a7a33f22df1736262f2ac2eef284c2d5825c3ffd51348b61fe6fb650e80dd3df835af1a27b11888313895f638599110000000000000000000000000000000007ddeb304e5a6a3f4c4c82901bf3a83542f05628a98856930b1be62bc37e6ceda67ed16e04ec954dfe4f578ef18fc8911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd2e2fe9ef5583ad56528382c038b49a3981541933df255fbd7a2861dc10b559e3b323f0f2cc4e38169fb20196ae1ae0000000000000000000000000000000003daec0bd12a57a806627f1cfe264def8e9a2c72366afe7420e97f634157234262061339bce8d2ab725209f17f4d03441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010660129ccea69597825197095855d741dbab60b1028727876c88a56ad2fd24bd0c33b0900ab83c2dba959fbbb6dac9d00000000000000000000000000000000063ab3783b881ce28db2ec9ab55a618955f1b3e26938df9b72550ec5265003592778a7e095e338bbb5678dad9a8594db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005aeddf16374baeabbc83ff05cc4a0c01923f25dea8d65424065952d66a32bc0c0e679f4d5c86238afdb320c1708c410000000000000000000000000000000001751433832021d52e14d64a9943bb8d3d40c24d147cbd38a660da267383677fbd3dbe96d80f6645b25b46e47c222fae01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001616336604c8c3960c6dac6be82ad787f1d33a5e40d07be8f1b1c19afd36395373e3db77317a2a39ce761951d1fe82d1000000000000000000000000000000000d1305a2e34448b39a2cee407070965aa39aafce53de8fa6ccc66c0821dc178bc6f00e094bbaa0d24172bf8cd847c0701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2b835fe80fb3dee161ddf7874c6e9691e5c13e4fa7a1e4fda44e20dcffa495b33bc6b615d6dd3715b345fc13d934f1000000000000000000000000000000000479971b28446d30e658660625a11d17095a35d685d4426877ec51eff33917359b2c7614597fd6ef2a9cda4caabccca61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001888b705b40e1a7cacd6ca8baf8977220f603ad64f2b57abbbb25c3bb79a87e9fbfec39c3dc0135f567549615e8c1340000000000000000000000000000000000800cce43b4675b891f6715b0f72299724e27e7f226f77a219fcc696f6aa62032ef1fc1049d832be5a3b3d7b45658b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e2703793622ae928e8494aa5d837ed5a5b4ea94ec01e427a4c6a2af1903a662577149bc777804a175c00dd6317741e000000000000000000000000000000000381bf9394f69d07c2decccae195155e15fc778852e542fab205d936d4cf5f6e1ffad428968794bdc8308613f99e37351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e4364677a6b6732d137bb1aea847694dafde8d67689618e414c6979be677aa349203df0f60d2e33de1ab6d875c173e0000000000000000000000000000000013a8dc23c5bbe53ef6903eab5bc0b3a8f782aefb57fa6b8b8b7d134e6e745103ed34419f18fe7b8825beefd13de955c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e4fd807292c55d3876a4db9bd74c03598e7db9729b1c4da18aef3d303ffa99e90d73182d7c748faa44d069c1f5f1c70000000000000000000000000000000017845e4844becaf392a40c41b48a3fa8faebe05e78175065b417c669444f4ceb8ee551c57cb1d258da83b573d4ae60261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d9a9a752abc370c63a2f04807521e0dfa7823e73702e953527e0032243d72de62108649d4b59ef02826afd732d8d5700000000000000000000000000000000039ef9915972d2186363530d92a9da77efcfb2c032f2e73390c3fcd0b7301fe84c1dc69b7cdb54a3ea62a5be5200479c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcd3147ab013428a8887c86ec72ae5a57c2bfd6bd75f46a993a085833e7e3e7dd7c1a5334821fe1dcd40027dcedae2200000000000000000000000000000000009c04ddfd3330f93ef03151527349150a6a5238ace8cc7dd51aedbfb291d6ab63db384defc7622577900a745ab60fc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192cadeeeacd29e3d3a3fb9ac024d79e0db4895872f78ceb39711dbbec0d901cdf99ec3a507c98fe22694b0b11e0a58d000000000000000000000000000000000ca9d937a9067d2ecb61d7160286b39bb0d505e771e2a9c0914d93aaa59e2d9194060527af87faf9104d693a148e888c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5c9580f28dbc989e6a0deade168d480c2eaa7dbc6806e12895627c99539fe329669bb1e42049362b46a2b25246c9f30000000000000000000000000000000008c6abcd70c9c37aeb94ae7670ec954a0760d90209f717ab6f96a5dfe52b49f2eba1781488014ad1011ef9f565bf50261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000848636be6cfff0f5c651472528805610dcf70d8346d3e5c86c58abce7f416c1d4800991d2f7d49d182265360c78b81a000000000000000000000000000000001692d25da91432b309088b5e31d217cd51cd967783d682370a26fba2e3289b1a8873f64245e6cd898fecfd473c1e5eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a41507d677567a73e263f468a26a26d23eb1b5c3f8686217e1e09ab34ed7a678e3de57c1ed1a03514af0a8024601fb3000000000000000000000000000000001616c8a4993216452e6f90939816374c0c0677b457e44e6601287ac261f4f14f0bb8a7b5c8ae46af1cfd6ffbd0a266d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dd00e1be7a8b1e22b4e330e1838d9605a27a539961556333b2524884903af8b00b08e6335f4a307f036dd1bdddc6400000000000000000000000000000000010cfc6926f60c4f55750f9923f9998059a9d03c4c7572ef2ce79853016ff9d2be705c9e0458ed8335fd4a456891e49a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2b2a15e532956dc9fe7d1ada229f87c87406ea672edb0ce8f728bcd1cf6c7eb6eab2706ecd6f2a1d64400b9aa58454000000000000000000000000000000000db5ed69ff7f34b7ba997d33cb943788dfb0e67a07bd97d16a1184eb07cb60063af5b95605e3d1e874b9bed0f69d2bee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0d38103bf5206ad11375bc7a6df76d910f2d4f77d1c14126cf86410007201543c01447cbc4d37975f6239b35b9a1a3000000000000000000000000000000000e4d7f5cd57cc47f24dfd6b4b723b5c50644368022775fe5fef05d4bf351b842ab079bb95875eee71caa61a2445a65aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b62253c55045ed15e4d7b2dfcc71157753a225844f63160c9807927f48b9f35cded2da826995a31c5667295715b3c090000000000000000000000000000000013a8d3e1fc09bfe2e810406de651a69de748957dcb1f4950e44a2e075d45688e2fdcee372a20c3bac14c639743cb80811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001934c3db03aa24253f461aa3cbd2e759c5f7fc945c312f4658e25aaabe9ba63a69e4d8a53108f858f164710ccb78021a00000000000000000000000000000000074da0a9837f8d5245123f5e1702e289b7adc02abeb63a86582c90b18538dc01eec55cbab5a48ae64eb04bf367e91ad41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009199b28d6dbd3bf7221893ca18250cda72873352d91791e9176d2cd758bb2cb1d595d7cdf8fc0e5b99715b997c088b0000000000000000000000000000000000f25b3aa2d8d119948da4048436bffc457f586f7b93b72c9451e4895683679ddbe4746b96277a4391257cd822db2496e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097c57849901a0c8ceb9b9ab077cef030f6573c76bf3716b8cb798b644a07a025abb52484f2a42fce34c21ab6aba59bf00000000000000000000000000000000107d831faa5763986bf01da1befdfeb4b5f666c097801a651034ed12826268c70bb7a8951d6d8878cc7af537e73940081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068dc00d547466b69ee4f046471df4483fd845c22c717d88ce1595f5ff499b1d5dcc3e21e6a568dcdaa1a32500f7cd0100000000000000000000000000000000187f2ff0fd30748154bd2cc5bb1b16d7f12772db5a238f7c7cc98646e54b0fbf38b39ff408febe977cad6ccfa02e8d9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef8e1610333a9b729ffa3c1e269e0903fba19f327840f94c5752927f9f1347642ff69416caabf7171a204e42c429d90000000000000000000000000000000001068d553146250b78582596a8c99a355fc7f891646e5d95a195e034a2df9fb57ab612d5bbb6e8ae3b7f68b18f10e08581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000601c5f1d30347ca81553d1189938116b0157c73b0972e54c9a0d9fe5ab48f543295a0f900c3f34c514e786701c8c3990000000000000000000000000000000003ea8dc74450579adc957b24271959c737bbea600cc269540bdf4c9b79f8295aeb2f8f5db86e03ebb33f3399e6952ad71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d001d499b54e833cf670a4554a4a877b643b9fea5e0bd7c846c373e79b7bb0892c1ae75f129837733e647d933ebb0300000000000000000000000000000000141e9fd4b6868da372a66b71a75304ac3a10b87098fb8b2540980dace4b6f579da5eb44bec509facddea09a4086973c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013da1c68ea9ae18057a9e9340a6cf150071e976db263e884b2c55e5a09b61115007956ffa3827eb85562ad7e9a20ce9200000000000000000000000000000000181f7e8764f46a0ebdc991c2f90144c0e9fcda912bc94304e9a84051c67ed432aca9f348a8f26074b0661c73f60b64d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fb53ed6ff26b2a00493666633bc7a50efb6a8d25f53361ad31495b2a57cb353e9b39c4d471931553c306b8575c826a0000000000000000000000000000000009efeae0f89156f2c4f32a4753de34f2fe49544a5f4e3c1f609735d7e8434b5c75389c0c8cae12cf782d7c0a858463961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dcbc65b55500c6de4c3100df56f6a75352c38a18c4a25961298adcb65ca7610c0b320029d9b8d61f6f590f942f953e0000000000000000000000000000000014aafbee5cf292a3421d3f26aea44967362ed455dddcf4ed55fdeac84a2d1d1fd179e1129f994927ead0c30f6a26d6101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058cfa739c2d537470b49076a830472ad807226b52a9bf07e84a0c39de38c01f073e2696290891470eb2005a8737268f00000000000000000000000000000000191ed3ce208b6bcaab738572987928f30e1f20372f0518f2c7d8c43766ad31393b876cee074dcb9a1a77610ebf40b0411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169d563023e0a496ad95f818457baaf0316e825d12e69afb2b5c0a6d63e89f188aeee97f06159a479f14cc7406c3830400000000000000000000000000000000057522c0d59255b1367797021793a812d77ca53f137d46587528901a922505b3f59baf821f9a239c1fa51889c92f29971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bea5fd2658aa42ce339c8753155af12ba8c56f10719d0d3024c425f17a262d2189a1d12ae0cd91b6a138609a0aa6220000000000000000000000000000000003b653851754e56e0fafab7ea79da8f0d32793597cf109d49d78172df33da44e8c7a7bdc2b7c4f87ba30a262c38783a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e1dd9b39c8dc38d1c42f8724239ef8a1e0a429a368d0dfd2a954e054c2520a2c47b816b82fa0113827bc1b010a608b000000000000000000000000000000000dec3ae706926a4b5412aa1b1792f39700e39731ab05d2f3769499a0e6b2b37b1ab441155d6402018cfa564fab6595831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175c22ae8c763ad3e98ac4e8b1b595b6bffdae6f030c8e4e9a1269289a129313991e842a8638ee56844633387b4016d600000000000000000000000000000000126512e580bb64c9d0e2b2f81140856767b30600f2ef4e9f08b1a88d2208857c6c140bd20d32f82715c2edffcc4bb4c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db15ad1a06f77c6072ad66153332aae1914cd72c1d0207f1c711582d339944ef2bcf18a4bc1e247aaacad2fd4cf2abc000000000000000000000000000000000f426f7e706b7c12a8d5251a1cf15aeaf439014046fb6cb3a93c557e2d9a17e1b7d77dea0c8806e69337d5c4c97e8cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ef5a2e56769ef864db536b0a6b7845a14e9554b7bded3118e61fa8736bea63b5568bccc00c75b027baa415d93285db000000000000000000000000000000000936f60473f9e3d849dc50a5f8382f627358e51672ff91f23b36f94d53e809c847e235a6833b24911ac32fe573b22c9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067c8ef39353039c6e85717f5cea69038138d28e5f871a8d824880e5e94bcad1d702a4288ef3dd0fe683ab49ee27881e00000000000000000000000000000000088dfa28ff418b50e704f0a92919a9d725b4832cfb6f881fd0af34bacdd7073552562e21635eec76931cdcb7e3fcadd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005526c9e42e8bd124690281c424641989c840c6b203a6f4be24d1302c8f40123ea80b82542a9254473cf62487a089ac60000000000000000000000000000000003acaa670dff46c78711cad38dd98128f849caacd734a2a043238fb840f5f58e08ade6159a378c8a95d9033b2c52990c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149959ea68c732401811c9179d7b6e8cf59cf2d81cf963ed9258518c5ffa49f9353530614daa689bd88c0fe539d010db0000000000000000000000000000000008be0e966f60eb0d020e59396ad64e2624ef6fa55069a8f7d4b576944b4ff450b00d94913691d24a87625a770127a9e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187194e63ce4888f10f0b99684faf7a65133c1a164024eebcb06f54b9064c47a63d348fb27351c3820f3e76b591952e0000000000000000000000000000000000ec000c23cbf6b7c7e691d5792b26e28e26d021ed8d8ad31c81888c62fc53d4f92a5765fb816564e744bbcb7abfde9791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b60d378cc45ac4e45a8dd0af9bbb6b4c0b67ef5a4075540eb5c19df12062a9f6f23b5386dc206420c75482f0a628d000000000000000000000000000000000cc92a3ea8aed8041e4b2fa4a488fa916e1b5736426839dc986980fd4ea0b88e5e23c0bd18d7c0ee7624985f87eae1291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bf43320647692469f8e05eab4f6ac97f21ecf30eca350cf90c4381a13dac51d2a851c76138e41cf8ee2fc0b00067b800000000000000000000000000000000121a9536da0957d7283ff97c2bef442d140ad8d6f430820d446c07da41aa1ec854a16a6ef19b2e0f77bb51f5ba3b2e271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d722c721603cdcb90cf09e9078aa2599f8e2cb20c08c2780a365d154140cd8a3f7ff76108cf021dcb8bd6ebc1035ac000000000000000000000000000000000e92c1fa8f90fc999b49521bcf26206f008f46ea78135887f7b6478e59b5b6d4afb7d34a227538ccfa06d220b0e047f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1a6a01fb85271eb067cf250a0aba46a7ef86dc77a5e790a5aed1befd205df5aad68937c1f07d9eb29afbf1e689eac10000000000000000000000000000000002e774fb318d04a1c6dff00ea421d76d0e7381cc972a8bc5a9f7c2a8d5bce26c979fbdbf0ba31cd9f7f90951e541c0331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000356f039f3604203ded1ebde41beb87347982ba0941fed2515de1447a08ba0ab4123724137ba14124cb127cc92be34e7000000000000000000000000000000000bbae900394d878d51e24b1aaf2c739f1599ab1b19ae2bef75fecbebd7031360f96795fd5337206a5818cafaacc47ece1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009961d8b69341b2bdf19d4268e489b7e11a03b023e39c1ca707ca568b988e28e962a8674df617f65d5bd912d0d280c400000000000000000000000000000000013d0d03dc3f5b4b462b32d6b187adaf2becb55e43ccb0572b331f9dff9f90522627a02aeb12ae0c40da260d2a7edb4cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019363e4d10d205e014e8d4dbd60ed1785455223fb9751f2900a76c72523be19dca6779ce5a549b61dd128eca790b33c00000000000000000000000000000000000f55f0a4cdecfccadaa18512f0fbf520bee75f42fde6f7fca140e314fbdef6ed36c4e005fb1492cf3331cf510ab83c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059ad18958fe60fb5e1bed46389f54e9904022c56524208c06774660406b6fb6c56f7b46439f4d3268eaeac39042a73c0000000000000000000000000000000009b6e55486829e9d1e8e5539921b188d65feb184e5db48738b666ff2b8272971b9e4c1e65985353801dd1adefb9a4b481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099794b90dd85ee7a8490dd428e5641b49f0aec14b02e32e57c884860a8982355ed206e489e5af85aece7f0e55e2b5240000000000000000000000000000000011ee8915cd6e0246739abce8954126be56f1373f4a1ed7ce07784a38f013967125a94fee3f70b33cddd937cd36bab5fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001202c23cfc2151e27f1871d4f31a71c5844714a84a403a2939e84b878598d7ea7822bf0e7ec3d4505495c6ddbba13a5c00000000000000000000000000000000156c7d57d719d3a26fc5a5237492c0561a63cb8bc31e31bf2c127153b885108dadd6c5193d2088db6fd185e6dc8612231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bfd8240773277ff84214daf2b275886e87820009a5766feb68c4e3a8ddc743589efe5ffe03c6d996b6e3b96e775e840000000000000000000000000000000018a0bdf3803c29a4bbe1a51dec9448172772c3373c8e9ad328fcfd10980ea2e218cff4422bb7e9bc6ce2788a9b6f143d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019de7fadf2ffe652e9c2ad8d05c87643b81f1e1a9fa999f930645e926f8ae58ec8f88d06243db0758c805d43b4dfea81000000000000000000000000000000001486ed9861114ed2d53aa68865ed479e7c1a4f66c29bd98f5c83697a7fa84dba6837f3240bce8eb5b23ad8b67e357d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139fdac7528942d2c2d8d0148b6395776d4589c9f6db05b7cafb13ed76997d82dce83e7e5beabb21f2219a8d36c99d4d000000000000000000000000000000000673331cf6bff67cc9838e0f2fee93c96ed152ac95397519e863320d0a3750f8cbc02392d90d7a24b3f9e40fea6ef1701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebb7830093eed2cf5e53617209c9358bc521084a5f34a521b82d4ccaa95ce4e602d1c7f182836dbd685bc4cda334d30000000000000000000000000000000000fad4c66b50ffcad01d448e79efdf6c9446427732e7d2593e77a06a4d804f666429db195b4db3b5f216bd4fbba16d4101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d3323d02486ed850b0e45c281354ac2e12ce533684e610c0258116b5fd00f47d02eac97bddd1f195ce88599e3ae3a80000000000000000000000000000000018e3869e7cfbac2a62b2b2feb7df2a72c9dae59239a8d1162020c7947ad9751efc47a237c5c7da70ee25a238132484351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ed3a533aedeca6381443c3582b69b54525aff8fcab94320daf35aaf29a945311e75e75c1ec8d18aaffb0280cc137b70000000000000000000000000000000010f9b9734e3316ef54b9adaaf649761c9621bedfd3f1f7f2c183906d576962c13f2b92cfd2d69cb3e4337022fc8a41ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d160d3a0232e4a81b1a1b39ff97c1ddd6a07831318ee1dc9d2e303f97cd94d1a745c970beaa01625356c46c1d94f91000000000000000000000000000000000f9b9086130fed82a16120620e0cfbee3553750907697af3ebf9d6c3131300ca9895d6f7a2f33f968a1c4f8c7d235e8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100800e484086215688bae53087c646929b12f25d189a9fb5006f7c1ed0b661107ee46395ad7842632423449f4ebe7420000000000000000000000000000000018ff21cbb1651f42a82a4a065d463489915e003b677b12bafad9a4f4f460034278f55d5b3a3516244d5f3e2507324beb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000736c2f0af8eaea0b8fd4fff820d3e6ce3b5ebd439c303d30f838a852bb0fddd9c43996fa6347cbf922af7c293406bb6000000000000000000000000000000000563551f216257c9e38dc07686b2afaffba8ac4f22f267b154c5331b5f199af8db0f12b6b4c449c77c49b474f943b79e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb72916ae3e2ca262b6d5cb0065d01dcf5194e9df04ec7f38e0a58d19d40e4ee00305715e53b7ae568311fa8818f88d0000000000000000000000000000000009634d8703e0fd3552f5487b328dd81e01fb7c9d64ebda64a2b2debd06e18d6bc92f851cd0699642dc00b3b1f184906e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a221cb22551460cd5484318235e750b8c414560025937ebf55fc1cd1af2e911841e9a1c4294af021c903002352f2250000000000000000000000000000000002c1b0d00297e1f705944e4c1b9083d886f5b0c6cb4aed65826fa6237b554b348b18eecb1e523d79066141c5e34ca83e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010addfe3611224ec5ba409711c7e376bd3a382ee1ded2d297b1571be0b3631ab34fe24aa9fba5c9ed25599fb55d582be00000000000000000000000000000000166605242e271225a535294af4a136ff8d2978afc5833c6225c334cf34adba7874a0531bbbb918ef47a09c954c43b69e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041b6b093cf1d772eb41e8b989ab3eba4a970c3577f6b654ead56061a22bd59b6e50be7fc8a76275697a30ed06a9e14a00000000000000000000000000000000032bee49c5493763bcacf244807b135e6ce7e7f5ad24e0aa84c15cf93ecde7580b68df83e572a889c9e29d8a375870331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007af41a5c79382a1a43696b55e24ece6209bb2f16983735d56071d58b06c15d53c2c412c637f32e9ca00469e090911fb000000000000000000000000000000001237384457b67fb3026a96714993cf0597ec7497462683888ae695b2a630b76a25637d6930b48f1c9bc583bf5a71af071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000058f64f55522e1356e27f7f5a7faeb319666041ac42e4ed12cb79c228ff1fa43eb3cb8f8a412861245ca4529ed0d9c4000000000000000000000000000000000dccd41d4f84b7a8683f7737731335566d0dc8f14326de8b38334fa9446257900ac6368019b962766991e3bcfb767e1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015e98fbb4756324e2985b56827bb48e4861298c4648a87b55b807183d678cddfcf0846fb974eb39bdb1a5b6795963f4000000000000000000000000000000000a72cbc795546698b0ec3a26c9d90dd0ba1be1348a1fbbdef2ad3ebeb3130201dd67bd812328a34648f3342dfb305b761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001185b5e0a8d8fe424dab278693c39830ab5d66b11693d282f8b57a05ba4c45af08930393585f8a406616baa73fe72a1f00000000000000000000000000000000083f45e55b7c7e79e4860d63a1bf865fc65954dd63fd82aaf9565d1e0fd727e8a8f261f5711b684427932cfe4c94058c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fac2dce2c80d2cd9d9f08277fa5623d718c65362fa002e92b7f4bf66316cfe3403d4e039b758280cc49bac4886f4710000000000000000000000000000000000cc4a501e9b3f847d75114ebb50347d5e38b87312218a91925c1248a3c460f1a1323eed76a7495074b3c1cf597626691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a0c75eb0c277286c5437ce1b69d0427b6fbde89b02773d17da484f3a3e1464eab185aa479f2d5e4f595d0048200ae000000000000000000000000000000000cb4ab4afc59bddc19738343dc98d23f38180fe1bff8e0ceaaadf653906136fc1430cf78897fbc2949faf2bb9cb3b6a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049941a8a94e90bcbfc20a4fc6d4c115a5c0be1bff80ae599bd27a049bc45175fbaa6259ed94cc42e874d98771dd7920000000000000000000000000000000000ad60a7f9eba3120f99c1723c023d1fe584ab1a6a68fa440fe813e8677d5ddb7ecfcf942ddaed96538b5e5180c4d2c2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e277619e7527b61e542caaef4556418ea7c72f96d3decebc6338c9c346f2a26c5ee6494fd3ca70939176b1b4d201fc1000000000000000000000000000000000245f8a32bbc5ce8f61d80c6ecfbc2814deb9079a5f9250ab873ab11ab3658c8632793676c6039fec41a8de8d1c3e4181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a405f46a9221470dd68d594bcbad7109661a07617a5e395bb47628d24854ba09d559d44a2cf703b6c4b80d5bca246be000000000000000000000000000000000336ed34acddf9329a9669a3571819cd83555485fb2e06f9b44b6b162171b6e1544ba502fb5dd5de1eae3d8b870f44921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dca74a1f94c017b371b6f4c3f651da30890d23ff2b8053a77fe23f690209f1a440346a0e35b98fbbeda50242fd7aa800000000000000000000000000000000141b8e7f0bb420afa2836b9874d7a582f6a801721a9ddfc35e79b1fdc80f37a609fb68f2ce9e73fea07da05d1312c8be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000202bfbf8f87625fcb0146f86e5a615a828453bc77e4dcf2a790a941fe5ec0acca7c14d0d9141833694b1bd146245578000000000000000000000000000000000b08496d894eb75c2d5a04c0ad985a6b51faf4da08d1828a1001a15c8259547fe925d7ec71132a35ada479a6871622e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ab53b52d31517c09d460c5dd2533f2b4a8f01b0888e56f7d10821aa5021332b4b46954d4e94d497ab391d1dcd4184d0000000000000000000000000000000019150bb1262c44819aec0c80ab2a0fdac8a3ed7d4b1dc939631925377b9d1d46a78b48a63d504b5fcb3420c2fac72f8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6d341b362132f641a88dc01f886b6647cd30fd654886c02d64f0931ad4c2deca306f9e45e8089cc73813be4bc5ef7400000000000000000000000000000000010cff3e94bca625a6bdd323f5b7d89692ad1fd06e8f5f82f22e5ff762cfaf8b5fdbea66be9aa09566d7c04071567c991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2bffaf3cf09fa31ae5819c922aae799d6e715a32985a851f211d7af26d2cbd544f8f17d475d8ef3f871c5cc4de750d0000000000000000000000000000000010b159f3157361830f9241264c998dee3e4541b3cd6f7b8f38e9661b35adfa5c4122bb355df60e6cfb3def84960b7f781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001916815f3b7933be9e9a17dfd67bfd68c1f96800788fc60178d58efc4c457e6cd4d48f66eaf2c519f144e5a93e75fa0c000000000000000000000000000000000657e9217664397a47d41b000ba9215dceceeacd10071cafb0c14c2b4aa1b0b3abb6261aa09004062ae845871cc6f5081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d718e1cd30a051852e280927fad885d540be748bbc42d628210574dcc45098c2154e5520ccf2d7bdaa7e7d04b47dc80000000000000000000000000000000010881fbf33a29767c6ce25fa23a5c7c2e475156ceefb819a9e0adb28db7f1d9be3fe3b3e3df101e16efa73bbdff8a2a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cb3b930ce7ea2076f32093451f2f8a2d77890302a378fc30c3eb9952daa11da0dee215911ece81d86f79070c8db3fc00000000000000000000000000000000081a1e01184c617e11ff2df6a193c4ba925c61d49dae0762ea036ccd8b2fd0366f340205f3844273395d8537eefa847b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001457ed635dbea77a65bbae67b470e74b8ce77a1852053b674527f8ec3988b83b9f1775ee57ed7e694270b8ce99cb4c7f00000000000000000000000000000000014dd3de136b8e7881771a41f67de9dbe8b70057f54265450d4f50a9fc2fe794b53e97f9737433f4b2a1c3ccf7b244c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d047bcb8f97d04720af4ef9d4e5a5b6d50c23f86fef56772d994f760c7f0af6d1619e6b7fd319f5533e6aadc3aaf6100000000000000000000000000000000028f199aa9cbb1276fb1b6af31f549e0338a5d2456f83bc51b192f1f73951f4c5ab5ad37d3a9545d05b85b5124771a0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ed0548b8cbe2332be21d46de3dc3d24d37e4f36930e874b4722dc61c4064b26f33cb969601f1eb8c59b5cab6ed78180000000000000000000000000000000006fc4909410368afdd726702f364399a6483785f759353660bdd77200dbf64d5649feb3b4a68faffc5dea1b6cacae12e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c73c09c8b836098e64bc65102a6373314969ea4f953a1a6138018bb960845a987d8b5e629c3359ae44e509a03aa1710000000000000000000000000000000008efa599936f1976964f040a948bd500525ec147f3672adb2d55bce12c9d16c79d522d94464796c212c056f1a87f872d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e122df226e3b16b790face1dc1b3ad60422d235b4c99103eb50bd76717c54ecfcd68f99bd71d94482929161deb39430000000000000000000000000000000012e57caecbc9b97c63b11fe3cb9379d4d1d04cf382419a982751ce0ab03885cf293850c1f0b5d3bfc35e70d71e6354601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000166b3e11c9a3085fa5b0fb18717cca2f4b288a62dd1d5af870ba12aa74e08444aab8164bb6ad9d8561262a1461806180000000000000000000000000000000009e3e78e42bcab0f63b8d28cbcb068cb743585a7beb55576d481a2b57789a995fde09c254a77f4628b9401e39d5df22d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003048dc0a721cb06625c360c22ff03f00cb1671ac6f16521c734d940d55a62573ce44b1fcf4449c779836823c81b42f00000000000000000000000000000000019890ef43f93ae538ef8eefea0a3ee9fb39bdc53733da3e8d263182cf188974c7f510efdea815f7e96dcdb4c2c9629a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000daa5a8a44117ea2801f9ba6bf260d1653d454780f14933ffeca34e6d7c4831de6f84bcc9592b3327dec3669e29ccbdb00000000000000000000000000000000156eaee970da17b742275cbfd277bd9231116504a69b12c0c324348681fbc6b19647860247de6fcb9114194b5bb704f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000752af6d89a9834b2a7af7e84520b934e64dcf7546a53b68ce680c513efffb7a7c1165d6e3f2a5aa51d43deeed2944770000000000000000000000000000000007efc9650ae553e3cc5fa62fc90a86675db6d3204971a2619ee77616ffffb1aa1e09dae4445350c287a0f72f6d19e5631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cb2c078b3d13b942f6b95323bd6f72aa0516266b505022e8a039607fdaa24c789ef3a705d92743258f1c171594777500000000000000000000000000000000129010dbe4a2b6988b17fe8113c0d08215278e703ba7f64232a1a4c002ba7f92751281245be0c92017def294ab3afe481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ae47927ba222b1d69a344b25aa6b4bd28312b0715868405f6c2cb3b6dbede3cfe606f7e8fadcd50e7ffa59796262ad000000000000000000000000000000000ee2f6ac4560323a534095c6555b67b07dfb3ef3656bc3faf9e053491bc593cbdcbc5781f97622f2246c84fa42c963dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141f076835181c40b77c256cd8b146ffe51d6f13142bebc9207e367b4bb7bd613b30231b15a1c4238b8f226da3242184000000000000000000000000000000000b99f0c05732f9a52cc0a9a3e08d650a952852527bf9c6dec7f2a477f92075e788732aa4350ae62db02d76ca9f02b17a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016aca25e60b86ea6b8df91aef0e82c2268b65d8b1cdf4269a889babcf9571effaca00da7d358c4f6bf6ea9af85e843f5000000000000000000000000000000000c75bad6ddefba40721ad492cf52f176d633e87ad67d2a7debf96fc347140ad66ba084d2cba40b05937a100f249eda0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104dda1c1b45701322a361cbcd6042b9813e861da179a4191c3fafce2c493ebfbb9df8dc5dede373350b5ac26490b5620000000000000000000000000000000009ab0116b2ded6d93c7c8458d19911bdcd111c4d956af4c4b920ce8f07c8dc9120baee6486b87a33721c11759925b0511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000913c86373d9b73eb9a6e100e30d08dd36ceaedf7bfbb8d6540a26ae97dc7ffaa7aeb097cd3104bfeb340f6854a0bfa80000000000000000000000000000000017cc22bdd0a97c6b9e13751051b19b0b71499c704e8f967f232a6e37c797b0db5c49fd9ae9f3e39bb173c0302777a6131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001419f1b27bbf6bdb17a319c52e3eeae653b07ed99f84a96455bce7a87b6a8d80ca501c86df95bc42078d7675e168969700000000000000000000000000000000058728a522f3dc4bd6f7a7e58c4bb47f6ee8d65a4df4ef190fdc169750e77f89e78427611294799c1bfa50d6bc9ea0751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006294bf970f3186ceb2a2aa60075ba258952787c4d8c5afabdacc6c9fba595ff35eeebb1b3d0f404f63f1c619e6687e4000000000000000000000000000000000bdebaf5b7e81afde94f2b6f503aa6124175620ed0cb749c799e33754fbb24d87da7d11565af8855025b315321a385d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fd6fe84788c407f1a1f694326bca2c39b24c173863c55ec2a921d8940d1d294583e5866bddda594999b8e6801cae580000000000000000000000000000000009c819869247e3ccf09f4b1600ef7568d807fb73b300f8bc7f197ed870e94d752b426cda413145e7a60038890ac4c6301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001670c1a57c2eb3ed9fb62cb5d6874381fc8d523d046db238b62d6936eab2d7019523bcd177758756c319d69f71ec01460000000000000000000000000000000009cfb8fd75c76e73ed9edb66add7cb3ce068c7e38af65d705b70f433ac391677ba8693d2b7a9da66874744a97f4c5eb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130d865d0bcdd521661e509a76d436afd0567591eac143dcfd87c0edf90c723908b3dbce8f522f7bae53116de56c7f30000000000000000000000000000000000d4a3453cee6210f473c9dff1a6edb803daf26f5351c8840fec93f4287913ec4fcdc1181c950a15d4f32c6574020e2ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154451a717b375799e61e9819fc814e8b3d720ab0c725eca55e46214a1c1ab3ecbbabdc62aedd7278d41dd603587c18d00000000000000000000000000000000152e95fcc64cd3304baf3425315650307d16bb89a339d563b5901a99a37c772176f59cdbed30bf0d75472920001113791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086e5ab34fae4b6e3cca1327a3b4f0937a31d2889472dd2694bcee4874c24306b4928906214a670ed815ca5ba4dbf50100000000000000000000000000000000088ab0f2a378ac465d719a365603acc61fa4c000fddf21d6b680fb54591ad6eaf2de2618bfd9141ae5e49a238f80e0331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025faf310a8ea586ab0357a5df6e8690c1514ce3f8c5918a2e0f0c838deca41d269a78246d9f09f616579e18ec21758500000000000000000000000000000000176e297c595186fb78b253cd468766dec77d64d6c6c6b8200b92770f93076f34292e63681c5081b69b225b0f074b2ea71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004af00e20fea7e198f8ed998bbb0b85792f232d7ce047e03af4ac8dbc81011cf9e9819116256f48aef1d782fb08b6c7e00000000000000000000000000000000177b309ca7bf4d3657accc697d3e96b260fea7d1e5c60d1215e7f53e989ef9bb9761b424750fa30803c11dda9df1cc981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017561f21f593a3ada8dc1831596490e8ed6099991c5c5d00bdc4e6b651a564ef3c60c51954de4cae44b983336203cd36000000000000000000000000000000000d186ec44246cdb540e385a909cfddb3927aabc8bafa94aab1c3458be19fd3862c52c899ae100ddab01f0cb9ef5715551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ae579f18e3100bbc6b7617d943a770d8ea56f1c04ef36dafa288805e6f6a63077a4a3282799d68e870c16036d222260000000000000000000000000000000016b9ee73a3eaa003ae931d5945188bc718bcaf0c5492a5070d304ce9cfe9e6f6e5736397535b481d9f128cb03397ed851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000989c613c62038d452013200503672f82d7c55b3beb504db03f6767340ada2a3cbbde3a8a0728f92af4cfb68d1fec375000000000000000000000000000000000f7bd845488fba68975da61c91a8f64667f713c228d89de5edbe9526bc63195bc08b09df910f02e519043250a340ec921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e1362b2d78d142bab24f62c42a68ce20c5c2608c1536827346b7e86666b7ed07ea67488f6965e1278d6f23f26114ef00000000000000000000000000000000103662bbf4739d68bb1bca50b8418dd6defb6c697e2d70a1a3b42e795f0dfcb4742e8ab22877af5d7d007a2e3838f69d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056ddb1a25cacff56d94299dfe3046743fe3432bd50f237257cf3dc33122963264ce1f11011696c43549f94fc9dfc1d100000000000000000000000000000000059ca6e500db63a0ae8c0dae73b101ac01274d477d8e33b0d25b4adb8b2ac8c9abcf7c5f6081e6c4dfd74b657e42c5dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ca25ce8835d989625f25295be93fd5c9b87b8956f88257b05c0296adbe62117696a20d34c1db3d9a6b01ff5578c9260000000000000000000000000000000005f1d27eb0ed45207932c21db85711c5f4aec17da426969f62c80431d1472958cddc81f783b85f9ece06a36ea61c88301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076c7c4c2542fd10ac59b1d92357ff4c561eb159964a2bc4867d44c714db9aabd9331eccbc572b9041428ab3c4ab118c000000000000000000000000000000001910d94aa6527b7249ae61389b7cca586292f6c763e338c7a2daaedf2d78742d7f51a6f657d47ce116a4c09fb96836d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a3877c93f8c89d225b6f6fd5633ceac3b7e7495cefd0af8a25e9af7f3e804fc400807c260880e689cbdd927775c7940000000000000000000000000000000017c119ca025cfec4e98413434e58f27c70d079a0b1b5fc23f45dd850215b15c81ad4fda47a2152e3fe3121bc763c0b861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000671d6d815def0718ab866827af3ba0a59193f9a74b19218a024e0fc1cd8165ac8019c8d04a70dbe737507d56a373b1f000000000000000000000000000000001640f288c3c70e136e6af37f379f0735b25250929196ac881b9cc0d012920541a756cf390d014cad4a540568dce883691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dba5d538c9b449512b49e54bc2ce9cc4ef99a985f48897c7c9025bb749de25209f4f9ead694cdac886032af1613c6600000000000000000000000000000000000dd0a9b60bdced64a0dbf4a4da92b8574da7f7256edcff05ed612d123945885232ac9e789c65755cc3bbd1af369a6811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000197189db96fb4f76264521677f2ab038d3fb8ecd3d64b9ecb4103004e4208faabab36dcc4b96bfe4ab448c6787f2d1a0000000000000000000000000000000008c6ae95c556d58c4fa2b9f09f551f937df26750753fa3aea3c98012906b254def4dfa75bc280547629fcf5309cf50411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175f7acc8e916bc7d5c6377deb56bc74ad3dd3859f4a02976373107c6cdfa2fa75f7cad8f22964395f7d2d0e6a65a2590000000000000000000000000000000003bba58ec2c5423d8e83ee81b1117b35c57077692e37343c8d91b2666efca10f661cae1217186695109dcfa3c86295821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d766536b28b41eb3a4c5c8ee9e49a7a535aef63deb0c3a30666624649295565259ad5e56d90af4ffa71ba341bf42030000000000000000000000000000000001d217a7ed35576c4791877d3c1e20490f447b5c282b4dcdd9b20ceb5999a1160fb24636eaea831c8e2642afe38a7f7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2e8565b9d3ba81bcc551a5515e5d71435afe1d64537ce2039d72b3c43e627b7ecc1675711138bc87b2cd4f24834fa3000000000000000000000000000000001293ad0759fe43b146ce53b1627e55d69d15dfb8740db827819bbc6afa78bec7006a009f6469537afd9af1b4b6b970c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c68b4caca45b59541c1b3f3a0280d0ad2fae571d9925f952c6dd47479364cb5566abcec2c4c54347cea55ac37a2e3d60000000000000000000000000000000002230479e97a8b0e6695d2893701705075a0f23acc4966deaaf16aaedb6a27cba1580fdde880188fbf4fcdda6e69e3de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109ce3f251c9cf8d4a7d3bfc39b3f956e10f92fab73616b9d8c28e8781b487337b785bf9021ac7ba0f7cc96b05c3dfd300000000000000000000000000000000043a25257d2fc16a749551d0c6a9bfb3537a4a91ac24333201fcbff752d7fa42e11c568948eafb1da2ab16736a268ee21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005a08dd6f72fa8bd1297c694d0b3349b60da33964eea2752f788d1b9e6eeb16d93241a1784ba600d9e4f40fd36c668100000000000000000000000000000000075b1eae7208070d7cb6e864b6861ec91ce3bc330a515d04f52b9bef11a1368f6b16c0aacf72846e0bb09c5eaa623fb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a6a85d0710a2aab1a7afd060b669bc30e2e0f7036024778c7e59b7b870b6da129c77d10143e5627b89d99228d84eac0000000000000000000000000000000013b5b6ac8128c92dd980c984e298ab19190fe97462626660e4352c66bbb435fc5c6e3fe81424848c68670640d04d31d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5b49a35c7aa86bafd2673ea48a6bc7d94ec3041017fa4c358483533c4dc3f46a2162847f20c80bf2457bcbc01b6efb000000000000000000000000000000000e16c3ca5a3952a38d97b9b7f36dab8c5586f2e9d4c0928cb74c463bb2e26eee140451527fe5f9fb846c4b47b5600f521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032ba70a3ad35e8a86cd3872c142bd4c10ef6e817fe353a14de6da1baea7d7e6abc5edf8446fc887929d563eff19647b00000000000000000000000000000000185199f8fe88987dad9d5954258b3fa8432b9a9ac77a211cc79f583d407cfa9c7462c470d485227648e15247cd44e3641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136f97e62d82e3b12db1a7dcd671224cd6b0043df2efd260043b363d653e16b3c21b087f78531137ad149af8a3e212dd000000000000000000000000000000000a8b9bb2379b39966f32331141b68f059b436b718cc6906d3e366712e112a445e472ec3b5437eb91f28ed670270323f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000747ec9b5e0ea16d54112f042aca56a220af0818b3169ffa0f576c0f2ed026a2dac40f6b4e53eaaa7201312e0ff867b10000000000000000000000000000000018c2307cad5c686c9b0f510e2304d9af2fbedbd3a79f4d6fa2bb843143cde9b29cd4d6570e758b46a567f55908854f861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bfe1343fc3ef85f8cd8558bf0874b1f63ab666d0b93cf7980c01f389aa36093135909fd96d04d405f5239f2318fb3b0000000000000000000000000000000003915ca17408af1ff1d0d3bbd1cd808d2cf0651caae41dcb2cf807c33e1f38f53bf2bd32ac28cfc6888a40e68c40e62c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015291cf122c57e841f0dd8eadbbb011beba59b1d517433b4ecf30ee6bc71e3f91c1d3853b6ab4673ea0933f5df505d030000000000000000000000000000000005227fc5907754b1f4baed066679f52f50458b6669b09dcbb684d7533503385ba23d135b59cefe45100d88af1344bf641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c345c525fce9ed80720bc6957f5599dfa6d16478cb45906b0075e58ff68680d773be95846ee579947473441a4b269e0000000000000000000000000000000011be34369216e5b47a06ac9e4cbf6eaf7f3bd153bc160ba8601be175e3e50c9309d60b43b9a67543c7576a2740de799b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001633e75703e50f09beaaf93e668a9d8d99b53e75146eb8b38adfb9668068603b59afc83c8c3f7c491a8d9ab555a78ba2000000000000000000000000000000000510e399dec9bb96170b3c30bcc5c356bebef14434c7396825b445c98a8bfb92e512432bd8487e056d060c58153a1f391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062daf4ed95025a94afdcb7d3df41be235239f402478bb208c65ed6649f2dfbc7f90a9c8452e766a942b4268ce9afaae000000000000000000000000000000000338ccb2175da5919f1286ba923e94ad7b20b46e8262b039a3efdaed6b98f7581257b94c5a464570ea445d5bf6397ea71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7c32b27f4597466469e90648d7211c35c7c54365cedfdca3ff5bbc063cea7e1ee2293c312b5fdadce4884d33cb2008000000000000000000000000000000000e80b774031e97fa5b86a120dca795cc4ae1577401494d27ce601faef3756438aa024a9b9eba9fdaac68749228ef9d771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009198de864af6e2b9d509efc9e50d366dcf20b78b58a837552a8a5861e77fee88981bf17c9c382529bbdd1d7655d54db00000000000000000000000000000000087bf7d5fba2d944104b641c146f85666dd4d4d8e3c36d41a8a63687fe25a936ec77c2182a90a0c956527b9901198aa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000daa49621dc933207babad854829477c85eba58f348d553edb2c557e128f8e3a7927c3994170b44f6ee803251b2184a80000000000000000000000000000000009d7a77efecbd0090993047825608cbd77cb9e1903aebc214f0d0cd1251e8c79b8f419d1df380f00c25cac447888fd721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001882144f00f49bcf882d2e83b3730a4f8085e4070e45317ad676eea90419f616f1253d5dde01bb52a5f6c71717f5393b000000000000000000000000000000001409ac44e73bc0a065428b5ae3099554d97f545b5da8595b36e874483f1f4c1e3a61f8a7db59fdb6ec93a0f8f10befcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178a786866c02cc8289ed1f9a4456debd85c4727ae773b95b604ae3c99f1618bdcbdcf740c5840b9aeca0e5462eb616a00000000000000000000000000000000062a98b2b811dc8f6bba38c7a5067313251d1769f0592ae2a56de5c2777cd309b195fc12ff38d9326b06eb64faa8edb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000850ff3c7750c2ec22b6ce17bedf4288bca498bcc42ae2ac3f4d4e4542cb71440eca8cbe033486556a4c900242e5612b00000000000000000000000000000000030f428694dc02423417374f514ad6462577de3b4a8452bff5c490a4a1a5910a7e490a86b1bceae660a076b8e401629f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121a34fc6a5115b57c0134811a10d2e8e74fb34dc6c23409d48460c57e20f6dfdcb2f31f8979973940de528dae17928a0000000000000000000000000000000005848464235e71376758db902185bc4da676b9c9bc9dd1d18d93c5430f454a8d2d75ad168a117b9023c56943192fae201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ad329e17c0e8041e1ccca72810ce9d615695c47d12ecd7c36450601b801c9bee2e309625dcc9b17447b3b423d72d910000000000000000000000000000000013c0ff5a0a98dd6cd68485f616a1f7d6b2967a0eee8356bc7c1a75fe4fb8762e38b459cdf58bb6ffcab1a6be8a148e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a2510660d7b4572fd5d665f60967f488db049b99a5436a8f3dcc56db168656aa2e0d9f410fedbe722e7a7b2195e45e000000000000000000000000000000001086630e48bd583bca8b3316264337b6a9ed8b6a95be56954ac953449810d230be3b21fc4ad8f501e3a16638675182cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7cf44851078718c57eb94d83fa431159ea793524e15716e76b857ee1317c619f58a05df19f5ba9a5bcb7d187bca457000000000000000000000000000000000ca4abc82f13b02c64f84e92497eed8463df5bb33a024f6836c805be3a5cbc094ad3716cff1f594d766b018bc80d670b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc42a196e5de18e38e50d6e78c16e26e2eb357e07015c3d2a821bba5f49c075b48d1caa7cda88bebf88250398e08e880000000000000000000000000000000007950cf6e46c5c03a741f3aeb1913d63f0673666017c35614f8673197c9dbc3468635034bfdb81d6905b543b501a2b2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056a73740a8f8293952af8f56ab236f12e1f3a61e480915243956d1925662cefa2d069cf7c3ee95041bdbc9620a584e9000000000000000000000000000000000f2b4844d222eb5264d7a906c4f7138db93e1a428afb6ad71e86fb98bfecf9613e4ed4a3cda5cbdabe6d0d532385a1fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000672693bd02a6d28f509e0a681f8c90743921e2d53a23fb3a53a7414245f4063cfa90798e9eafbfbce478dd0b8168c7e0000000000000000000000000000000004c1c8e666446bc8ef7c61eb75199f6c44d65f6fb7b5bd50f56414fb1692072e59264ebade0189d003a4d49f124b002d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040cd3f491f52f0ba00187cf1d43599b6e145be971d98589df0a571c487527737dc455c6b4221dfc4123b446f0f0e6130000000000000000000000000000000015a477eeb4669b650162b5b1fb111c5c6069d849e0b22e1526f4efff3d979d26e9ea10f5cdc8c2d079114ce84ba331531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d66395114180964febbe8bd6d44290e5ce746a3089fc9cdabae8ae0dd12a90fbbf7c88066d32ed7f0be40633b0c9c2000000000000000000000000000000000d9729c88361edac95c009817a83f1323d6747cb9649a6504a7eb38f0577b802617c704aaef1cf39e580f9fa4530e4821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b04f72a50cbd2bb52a99251de9000835357aea307d48c9eb8cd45a16b8def4a1fd2617597a112f82ed0117e6347c1d0000000000000000000000000000000015513dcf565eebd724c6f68066fd36abd0536c445e399d3492d1ccefd1b2ff265617f18004ba758e87d2c571c47c6d271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001662c47a593426e52945c2dd1e718b1a529240c428c6b8bfb214f189715d908986dcbba1773ff1bb293fcbce70482bfc000000000000000000000000000000000708cb1fa59c9ab3e7d849acace0e1e7da0465f3cb285fc5001a55125df277083f7b8c15d830c65426dca12ac6d498dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e1169543aab09515b6b0a87d3a4de948c3d90de680248e4091ad84223bcfc09f81ecc7264344ca1daf0af688ed47ac000000000000000000000000000000000065cc54fefe9454be27c6f01aed65e2aee2c4c90a5a838dafc56855cf734f5f1aaa16fbbc03d8fd414b33f405b975201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f92de10d62a287a5d35544be6890eb6a6474452276190124ddcb5c3b3e757737ec9f627202a541bf86dac05e9190560000000000000000000000000000000008ba87543d6c71038cccf3414f7be41d693caaa3ea447d97d10814f8eabd4eccaddecf4e4ebcaeb1469c73e5aa45dabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f6a1c4220bb82372fe30495661500a10a7b5a46dfaf4365282dd09b170ba5fb999ef50cc77b7e885cee3e9730fd9770000000000000000000000000000000016d8ec09644cc741a705550eafcbadfdee1a9bb8611f71299ec4eabba917127610c5e782a9e29214c01dca81dbbd21251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6919702f7ae6cab9a16c552b8b4224336100b00f1d3aa4410372e14bd24e8b3551b571430007ac30221605e00002b60000000000000000000000000000000002c2d57117259b6ca9f789d7faa1d9e2832eda5e47dfc1f84d8c86e1598f97c7e161d21b5717be307972f1d8103b16741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a824fc9c92a28b32d6b4f2e06a706c78998e3f21635b1ed651a055797638d8bc8d82ba552dac71220fc4f5afb24094900000000000000000000000000000000013ce26961e7ed33a58c83d0f1b665937f99af31f217ae99f1e12f66e109fe70e76a7b01740f2287b11fbe47b0fcb7dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b8d724e06257ee8313316ae9759ab8637b25f9dc94aed0986a695cee4545b47efe6b685e4b3a654af7754dc1a2567c000000000000000000000000000000001959405099786ef965d172493898368cbecbfbff2b1669854b14922dc9b8fb607109a95af8b7723fd70daade8675eff11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f33e622738d50d92da1ed0c149f048d5e43c07d468cbe7cbb05060f4a119702a6c6bc876b84e868f563d96660329db50000000000000000000000000000000004c54da801b474d6a2dc81b982ac350521742816f25e1d92a1d527171f0ae5fa9536255cac93eeac417956ae56a7ace41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000715923ce6e7ac79dff184b5a397945f3e334afaa4525c4e5dac3a74a111c4f2295343dcfcb55f6ab4cf8680cef3e9fc0000000000000000000000000000000010517da1f4e8e1b551fea509eb11bc28ef800a31bbc11e2911eb0f983b06c6d023c31d6845bed72e3b61ebddee7a9db71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050ed086a0a8908828c15df35654a18b9f36ba70fad534924426aaabc71ead4301d39dff0fc29e71f6af122fcf6c177b000000000000000000000000000000000d04bc14319c2f4f6d8da3c865da1d1c4024539de73c5d2e78989fe7e64ea92683316dd5fbf32b15c73b4e4a1ec315f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076307a676494c98bbe93dcb7bf21a7f3cb94047fd0a85bdba941a072411c0be58cb4154197db9507d4071c8e70931350000000000000000000000000000000002514400b08c3af8b30d40cae95ac4b8602192a0c067bff97107337435cd1d2c4a673b1000ef00a70f61875c17523eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7931f68cdc71a7527b22053e16477d8787012efbfbddbccfe1a9e4acf98b365e10001b968f469ee7e4ca294617c09d00000000000000000000000000000000100dce988aae7974724c229217a4daadcc8ad01f123f7cc4c0610e205a88502fb7df464b6b0e035e856dd070f37484811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3d73fd450306a19340b9218d1817222043cc64909b4b4e5c14ba17f3d697a767fbe2468802d159355f0659377a1323000000000000000000000000000000000ca66e1855a634a470f2972e01eb4ab84db9402e936e5759adeac01c85fdb033f114502f7fab6d99edb5b6993edcc75e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193a8c7b4eb2cb61364a10ccf547ff2960102286a88eea28e3ab52cc7c24641e46682dc716da226d66bcb31f4440f910000000000000000000000000000000000a31ee48a283f35754f6cb1973dd407d2fb550cc7d0661e42fe01bf6681f1da8eb100263b12956072aa1ab08fce3f2491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129b98bb61b15c856b17d64605742e402fbbf6c1880c0fbc0d731aeaf7210c90cd8563438382f00134bb79fbb1575e2c0000000000000000000000000000000007a04bcd1da99dfb52830ac9b08c0da7036928bd3127ba4cccd004359c353d986bc08fb98a71ad32e1b9dae7d694a30f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd143085086af59b500f3d1bf1a4af7e4f067578c0d675fb6fab135217296313227596d69b405078dadf74a19d7c47400000000000000000000000000000000170e4f9ea367e31c8f0a4784dc2d18ffdc99bb76f64e0f86d5c7e445c3d2ac2a82c95f5c6eb337ce0f0baa7a5c39698c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002aad4df3cfdb6e2e8c3045f44c6fbc5c6ef6b0cfe3089c020007530869fa6123d74516ac00e358ca94d776fb9824d61000000000000000000000000000000001432bc44a959b4230ee3606cc5a4e5d4fcde3f135a668c8c3e147b18c80a3afad5868b47bee2e7c0944651c79a3448c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c2f4087c429f13b3c69661cee99a4c7473ae5b809f9724028f46ec1ff05d69bf62825258948356c233ce7911476fb0000000000000000000000000000000000883c9959484f3e829963955a0ba07b38c32823f2bfa33fdc651cfeccf79f46428efd930761136d6686c422b60bdd6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b53c1b6105762f787332a44dce9d0aa6248110d701234f5f3e0568a3b123732e5e9abe8bb2fb72931e55ecbadf8fbdf0000000000000000000000000000000001c84d0fe0f165847f00d399bc293582a06096521144f4edcc5df8eee45449f138284a78b09b67ce8cd0e2d56d5993441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f53d0ec0ffccffd5993a1e8ddc99aa6ea16082a8b55aee86be02eb69ad8220b37fbac98ef8bdbe153aa9ae996b4a42000000000000000000000000000000000327a7f5b57018205ebf1b3d9f365e295281eb94863bef7bc1e142d0e39736858682e9282a0fc28177b8fccc8a8022461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001774fa60d000130201997d891105ab4853718ed65899c6956b277d93fe45fc5caa2d5eaed0dc87e74c453a991ce9add400000000000000000000000000000000062402079f62b7a7fa3d865db00a7879dab814a31d0d90ff89f8a552fb802eb2efd29ee151914c60b0acdb9abaee69621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083b0c4a1b70cf9e94d07618e340cc5d7c5337cb2ed576ba5b872017b29ea77639a7a8452173756c39b8e364b0368822000000000000000000000000000000000b15c5d33eb74e7d391f0399e9c7d3065882ae2d136f3710958478e2069e2c336a405c56ad83c21bce29700d6ddfe1621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c9bdc26cbe3fa65c5ba4433558d84fb9a3edc9f6e2d8aa0b581ba781d7a8838ce59153a42ab81954b92b81bfb7016b00000000000000000000000000000000156b9640cc41ff582f0d544e3aff9a6887330b00378e6044e3f93a5ada5e810c6b8daaf00a180ff57084bc6207595e361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b26f5fddda6aa833967a69e6918bf2271b874e31e94c0e5b4a8e2f0e46c423781f76d28f140f980b8879316c3f0da60000000000000000000000000000000018b10c8f47127c1bfee7239a1364e9b1dbbf14abc4bf18c743e69c36e7cb16822e0897e6dc82954e55de37a8db0f07b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086d5454a7a2bde65d6543285af367317ef0c8043bacacb82f1ba18400d39f7bc5af1bf9651e96003cd8e7041e1bb9350000000000000000000000000000000001e4e3b59f526463aa2cb31596dd84649397c82470f45f6271d50ed0b1ee9a451f95e3d958d1b19d6e36128b76e52dfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f9c42650ca7287c7c28857f9ca4d1ad77b77a3da47179e9bd28269e146856bc935b349e2692784d3765353fdfad7f3000000000000000000000000000000000408ac5979e5e1c22ffc4e6ba03155d5b358dc959f23df79a2a1a8f49bb5c38de8e5983e7d4637172b78a663ba15630e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f562b2ea047c1ce4cb0378bb7526b38d89b361c4a92420cc17e89a9edf25c67ee5bb1a0eb801cef6e5e8c1d8eb317c0000000000000000000000000000000003708d2720bb00c2f56c2d0b9ca7da7f721b7b12e2de2bd5982e88936379e054dc595b714a56717b54014749870276e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014103917b6e8fed3744426ddedf51e984c11521854f224d5636764e4fa12861dc3063a0d75e69e2c891de3a4963b5cb8000000000000000000000000000000001527172ffe2a09ac050079a43efedab358356055ec83db5815f4d5f1094629fc246e0fe58aa1cb440fc3a75f59902ee31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001370922657c96c5044f083f6a5e3b4c8cdce02590f389311563a526f7d71929ed75dc684c1203b35b630cc601ec264990000000000000000000000000000000015969a1981d6236b38ff248e0a1a41a17ea6355937ccd017fef21c2642be3ae74fa623028251f800e90f779cc85d369a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a993e22f919c4bda34d75315aec03ca1e5da527d20b358a65ad29ab8a5bc9ad117bb81402cc44b79914574474fd8e340000000000000000000000000000000013dc77a72edd884e685f865f08cd96f72c184778caa38c6ae6491f625a3a517fe2aaf7fed0ee8fe23c5d39a60dd54a331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f6a7820ad1b602075ed673fa2e66f10956786cea667b7faec790c17df1e5a35a9c96f38a5de73d89f6948f8bbccc380000000000000000000000000000000013479772a2a2a58ec53700530f4658b151b66fc8065c32afca1d61b5c3add9ed0bf0873d4de78107c10c5406c7a67b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072ae9d9ef901316e3ce208c37c1f5e9e237887ad61fd6d28ce0405efe50d8466219f7e57216ec8e1fe9a9cf477ffef2000000000000000000000000000000000d2a652b46f219faefe8f2e55f7c430de027f3226597602756c0307c1694009bb947cca616fc32c3d449c6750d5d2b891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026e1ada965a3607ac249608a1e0da90e4ae1cdc71157bbc7dc303b8a7405af8ae81a1ce87d3a9e2147382b6c497a9ea000000000000000000000000000000000d50601a103b5e89c869ad9f3a8456b5c57e1b5216177dd52c9a5b3aa2460af8d81e247e9b7160b11ee0fd103453247a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c221f4f8573b8afeaf8195295a7e9b00a451c9a03f5b6814b3a5419b844d1d13978155c3916e4b2fb89ea3977c3f7a00000000000000000000000000000000034352802bfcd66fa3675d880531d54aa74fa4f2e8dc31ddcedadff8bffecd8988e058a97f102c5d0408d7947aee8ef71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000690ff5934c5190c3fb58edba3097285de24f8022b35b7744b2c7d8d476282c486f116d5262644643f31d91041e49e1000000000000000000000000000000000185fa522c936371ef023aef0440b850a18ddc14baebfac726dd111cd62a8a6b9e7acc67a428f19742204be7d12dda2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d687c35fb1aa4494c9545adc75fd82b18b90c398b2a8d1b488c37c611f8ffa7b2493c2d657548959e9a7fb04654cbc0000000000000000000000000000000016d1fe97b32985940459e15fb8efab3196f9993ed85d9fe1970b81515f22305a9c9b66ba55a1f10fc4fd7927847ef52f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a78dc317c72c8fcc386aaa28bc6c6aba6678f804e3b1ed3c3f1f5ff56c20e89c32a5dd0139a9673cf7629dda37d7e230000000000000000000000000000000002d20661db754d9cb9c12bda65f89f9b863beefd82eb4f4214f2fe688a5e983a062fd9d896a89067625b5697451154211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b858a55751fe0546b2768605ee7be43d49acfe34b6ccbf9d2aa5dedba209885cd81cb0937ba72bc138f835cf76bb83000000000000000000000000000000000cf51732be8f584f527621d50537b0eecd8dc5ca2f3402d7808f8e379f1940c0c1c756771da393288f16e6c24242f1f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf30763d77fd474cf5eeb2f0578da92a08b26b072bb8758363e341001e52172ba0382ae9e3d3f351ed9912189a19fb700000000000000000000000000000000088df5a6249d00be6629772046a54ab790063dc97025af6e3b1a67e71cf76726f14403968547a2654c57ce819e3434cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019be6e3bd07f4c6fbde9e010e177c58d8e67b60f23ee9dba7933191be50936646c80381ae5d50e66714dc3ab58578cc1000000000000000000000000000000000f28bcd77cb730417c14ba9a4ff5dc9ffebf6617ac94f462e862035dda2b6130a6f235f923bf3e4f3b404b56854c4dae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090c713a9027b9e49aa3f468accc7552564899b00eaf8601d683ae79f3ed1d262583d67375acb949a63bc66642ad57750000000000000000000000000000000015fddd957ded860774396d9171280d066fb15e52ee03641590bcca1b95c07a24abb654b9ff83cbf050b263e8c3d86b711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ba11d10a62d1a736ba94e4431d62fcb96755ebaceaced3b8f3e3a8e7b61fd37c880fca7dc236a41ebfce3b2901c688000000000000000000000000000000000734f7e35380ff40b608eec521e81bd3a988ac1e4a8a71cce0722e6dd9e7002537cace78e23118d689c639f8689ff5841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bf27e5ccb271f878ac2e434ff5e26f0a166fbe9f0716eae87583fda93a60a296eb831b6492c54a601089e45604554e0000000000000000000000000000000016479994cd51b03d2e92be2cfdf05553e366222d7c0bac75ac729845b53ba5466e203ba69fd49e69834d01317c92f52d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e8bec5b1dd098efc10929a76714f7279f3561946ddbc760220a038cd5f7f9a586a23c6f1cf9dc66f8e7bbc1545e384000000000000000000000000000000000ed599906fe5bf2467d866578746cb99b1258f816621868ebdd45b03dedafaa48e4fae78622ebce553e57350dfef7bb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fc1c5cd3d562db1f343dac8e3aa3e5aed9ba692362e61c21517fc7a01a150dd28249fe405358159614a53b073da61900000000000000000000000000000000121f936933d1d1869dfba5df26ce06432acf2b3a882cdda152f0a6ae849a0c9372af34c6c48221943fd50118f0e5bcee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb4868ddbae078cc1cc7a606b0a420e01f3e806bd8e15ac0a86fa881d2be874aab44b57bd3eb52608c3d71052befdc80000000000000000000000000000000009d33184e19ae2d3db145747deeb5ede8d5e3e538c08d0f8d385405f5046e8809b19b788e58b5c48c3e395fd17a775cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf4705a623e2076c4e6b809ca1d9b5f2b2c2f25ccfcd4f0fea73fade7c5c416ed7d46ebac6ed9928ed1cff004b2d6b00000000000000000000000000000000125558adc8a55b0aeba9bd5ece3660f5119efe5fa0b73a236941c509dbe07609cb95e100ba08636cc0ef0f2318bc2fdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001726d524081c1c7d38d6cfa8327aabff05a424e6670a7eaeb90b2b2f4a78f6f6eec453bd2d0b5007cfa948c8fdc12764000000000000000000000000000000001081fd7ef04d86286a39f0da66b548ed09ea0616d87509964d8c7bbef1bcf8245807ccbc8c6ffafb21f077fac9a40ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061dc1cd7463467db9e032099a286eed9f2d78dcad3e00fb6614d53f780c7787b98544723995815ad9f939f68378ceac000000000000000000000000000000000ee73385aaebb305770b70a449ef612ee04563b3defbad5b88d73eeff6f5133c02324c2d9a24869b514b1490f258a4161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177ea8117f55e1f43805fdfe5fff4e76083bb0f9458b746d93616bb6c89c593f138bdffa1d11e83e0ff2cc518d5251730000000000000000000000000000000008b2ea2670245628d07c6f137e77e46c388c4cc21fc42d7aea10bba773cc945662f0fe674e05e04700601ad1914464f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189f8a6cc8b32143b6f80dc723cb27607b41afe68f1aedda205bc081d070533ea9a538b56e9220ce037306780527c2460000000000000000000000000000000008feb8e8ba467904c686df242263e896aebc54f62514fd7232aff61eb04f9f4fcbc7818674135c2517bcf834268b0daa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e512e45d5ed4b359ec0b42a31a5c5f15a3fbe8e984e71c68bc39169555892491485c0ab2c5fe6e6a00b436372f6aa00000000000000000000000000000000014dad4da37b721b9f987ba6c16492ec9a4883d062cf02aa45de70d3c72ddf7ed975abd15f3b2c4191314275a11f7ff261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdc3ca079caff9b2d20319c102ca20f2a9933d1794f8ebcd805b5b8ef643d4b4a11071a5aae4c1887ed1443cf2db599000000000000000000000000000000000f65d02c51e897fd4c909d7b44ac173f29449eb3f1b37766acc92f1fa55f49c75ced4894e50f88dcb1a54a582f06eeaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000617398f5b306f1a5b4afcb8805d97da687a91fdfe4d14cbe00ac80b8d509f24e18c87dd47046cbc14693c77b74358de000000000000000000000000000000000dd19d684a5413f6f58d24f901e99c1350b122bd158d72ceab6cdcf959a6d692e5ac8711ecad4b8a753c6b7aac37a5c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021b99fda2ab5c242a761de7b9cbe92d9c1ac8e6faf7f956f39fcdd1644eeba4fd15a06d4c3029c0677bc63861a16e0d000000000000000000000000000000000fefc199aee7d56105c99c011af13952d0a9f98c9de3a15fd095a1909c5fc27d52a938550ff63370c26844bc1902c6931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080bbd7656576917c95efd49c38add44b842a3bb0780eaa1e29c4102ff12ce5a811bce28d3faa3cc7286a23d1db7d0a6000000000000000000000000000000000ff4a0a4b654305dca52c309a73401e62b6b8a0e2496fb06d81b29d6ff1dadf8e9f2a6fdb429e7a07e0104cd7d8401ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012df87e8f1321e3418c4d8d3d5a400d13de389965c816aa48716164360b7bbe23a16fa3b96527a68fe178f831739b2030000000000000000000000000000000012e7f07cd470f4106512a0237c8cffe2e790eab8873482782df1d848a8b7da01eaf49043636d9743002295d864979f631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e023fd775c5e221536ffe0caff52d0fc46da1b865289ebca1f2e7916d8dedbbfb13f0919c9630a85a2f4abf56e1d835000000000000000000000000000000000feaca1ebef354d3efee51cb092f22ef6d18d60c81eca69220e875623498b59adb678f4a51f6d73ad9f44a3f4703431a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004851c061cf5a76a27ec2a6916eb65d933397377b16abdd2ffc0684a6858f1198950781d62ace5e23310cd60c7e4ec3300000000000000000000000000000000069f45b557b350b06d7de7f3fa18b1f867adf765654ea2e3254bffc958bd907ad81dbe1c3dca58dc451c592685ec03341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d50b5a6070393f86310dbc27d80974038be82996467b09c5e541383d1f695c8dab1f2f6b2d60267459d3425672531600000000000000000000000000000000068e9c0c815e43791245b639e6c13f3e627865ca09b1aed65248c2803f0e340e1f962f57cf356879ece089d02f72033c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aed7ff562a87ee20e9a8fd5ded84eadb2e62e8622dc146077bc4c9e59b97e9dce45a04481d73c1e2279c949e7fc30d90000000000000000000000000000000001f53dedd0aa856bd0e6db24b0976c7e09a6b0d3031fc71d44ffc7f4e3041780f37adf0ea2c2df98f19dbbdd840c22df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199898b9589ce2d703826aeb491f5412f8f0a785c3cd5aaf89a546f2df680e7162f2cdd0704b2ebd94371511da5da6350000000000000000000000000000000008ff4ba7203e15210eba70141f5a8b814875ef0646a5135261058b6c1b4f741f48fbc1c71d3ec094f3fe90d651e18c7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000133c30b22d35853cfbc6541c02bfe65b9c598c9a570a2ac517ee3cd987b47c15c8d82b3ce6b4ddf53d540e45caf592a00000000000000000000000000000000139e43a8dfab8c200542bf131040122ab724d7a969ab4bd5c28881489fbf7b185494c0693e0db9d5e7d4bcd95cd63d331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000568f762dd79782e1dd13be346659ef2b64e1bf4b22734e38d21a5586a5ea983060858c96d56256af2ee246ef96a987c0000000000000000000000000000000006ae808d1c8fa32d423c9805067dd9e15826d8384e228c22e135588ef37b7b382bfb58a98565a4f5f4d902591b97e4791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000662e5c9303040678501acc58cb56c3a961538bab72897b79b7994f4f83c8b330e14e57303aed79523fb86590227f0780000000000000000000000000000000008e240f6cea5672a9dc234167b9713d51418333e9e06d4536b9321a87443a62130e0a8a8bb0a3d31dd0c78c23cdff1071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007568a18c2633b09c7472d7612418b6e08204c7613ec90e536fb74535199e5707d5f004144b0a4c9b910d66cb334a2a1000000000000000000000000000000000f017bef971a3cf3f58b2760125e26026458ea50dadf976c6b5384043e2d507101c0995c636afbf5989fc8ec0c83f0931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144e72a0f9d6a789a18f2b48974db6a4ec224f84d0e42e4f6d15c53d75ff2900fe0638a33834778453fc0a5cebae09250000000000000000000000000000000008f3f5732c8419318395692356e613ea5b7b7aa5c792714d06282020a87b75dfde2ea522165a73ee9781a763b86c700f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009daeefdfb67a9de5790ee06eafac7dd40d31cfece6ffcb8c49f8db9e28a0ca64431cbc2d967e731fdbdecfb07359c3b0000000000000000000000000000000002660b5b7d8571e5c02d72a63c275df4493b4111263f51e0d19e1467676b9beb76bd5261ee7b17a0bbd35ea0895e4fe51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d9baac61892e9e7b47740d421e50b11adc76a1f7e1a9fbc958a342d969322cd6558f292d803c37c6eecebd1f41e748000000000000000000000000000000000cb0d2ffb62e6633d5a526b5f2f2f7b787b311ef61041c5fb2ebc95d6a742ab89606d0e8d82694d70177d6a2305494711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147b2beba39c95bf817b94a5b80f056edf03ea90cf7739e2944c916b74700f9bb759dc71b2980c3a44ccb9d3c3bd34630000000000000000000000000000000008bb29dfa3a71ffad8669fb24a0c854f02f70dcbb372ca0bd90383cf1b6824b22a857ebccc5d70ac9d48be571952df9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d10a58b7d344f597b8d0a817e81bf45e936642d0ed280c2956351660d2359444a319dd1cc1dd0e99331919fc5283ce000000000000000000000000000000000291b350eb996e5aacaea1c7b85cafa5103cdf27e0900515f734c2257d12e2fb694f9b49d5938e0fc4f51c2e7b57cd4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b74049ebaa441f0b633adedf45369759917cfe2719aa106d7ce098679d3b2ebab2fd420586bdaf222749348ce51c4a00000000000000000000000000000000004c5b5ce63041398a9b9b3749694a05670788bbd112bba82167e3af9e60b9f00fd3a74c0e691d4c3b6a3812279f931fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3a473897a0c9627c3316d59ffcb865e967378ecae9655fb68ed600afaebbb7396ff6fa98dab3b90ebade9321c08da1000000000000000000000000000000001179a9c27728246d2b18270fbcc3a75d90e89a86c75a9e6d55afb4582e359ae67c58ff5e3a4256cb4b8022f199dc41ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176dc15e0315a9b8fba926acf022dc8a474e2c78047a5d8b262471cbd4b5cca31a7cb40d65658b0540d44aaad894ae710000000000000000000000000000000004e2535d6baf26c47aa7a9868715d7033e2b573a1f5577cab98e82cced81225ad7c704c48700ab85f12db8ffcecf47fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e928ed9031a7092eec1cd98f8952e4f1b5e9456b3a230df46bff11e21fc2017b9f6798a58fd4ef4d1c3b42a8e5101f90000000000000000000000000000000000ffecccf12d0ef136a8c4b287b5c7940f0495e71f06fc1d228eea137941b00e897ae08206514e30f5c1bf8646db69611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d923698a0a84a87b2651d551070f452a77d23b37ebe811289283c10b0b3f2d1e6379ba9445cb3a371b0a09ccd8bae100000000000000000000000000000000094048f938184f5b4fe9397ce5833a30389753cb9f56f04df23b9fdea090525187928a96623dd613363c440a826ff7851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e55b85981e5c04c8f6e234779aa1fc3fe649b4aa37b5970663a1e77795b7c04b7fd2c55956787c4dcd07585a113768b0000000000000000000000000000000014649ac93c708f0c3e68374c996ee8282829b18872b3663583e156dc1fc8122b82567efb3143ca05ce134e8768a7d2841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001554ef148c60bc44c976226e21b7f90bc336e745aff96b46aa678763170ce768f7fea2145892a72071a9775119162f1d0000000000000000000000000000000007fee5ca613f94898766070ac7a356a96b135de2f11605ea91661a99c8657d44047d3b315808f46f85645e33c8975f671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016895340406b1a747cf5fcb2b12be622957cc42b4697d0169c075afc98768af700f42008f3d845a592022c1a552ffce60000000000000000000000000000000006a46d4d6720db4ff2022bda0a5a62ca61303fc5a7500fa278c863812e55c5ea332f8659c895dca8a1933c8323a0cac31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130bd0b475d201d4d5b39d707ae7b4462ec8cda721259334f9d6f32499b0fd5e54c89ed4317b211c839aac82872056f70000000000000000000000000000000006a8eee8ef30327ff03d1e8a2a02d53e7d13066bf74c4a6a464968abbdd9a6c5e31db7da4c66c5f701dbeeda50f427ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030effadee585e20d5386d03ef748f96c2236a932cf5369332b14c54a1f2c4714368a35b4039c52e8c73f77f0a9f869100000000000000000000000000000000014ac11944192e35cfcac103222c2ce7229cb5e0e4193db10b33bc0d60e65efe0072ff87c753f25b845713cd1a9b7c1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126db1e73c97dc152592d8d4d50da875b157fd0fa3c9c58e61ea82b5bca5dda39d4f836a5a5967922caec9bcf6a4c6db000000000000000000000000000000000107edf16eb63c43f29240f6ab53ef2cdbcbcdff59e248465f642d93f724fb7f0e3c2158f175ae49d892ae621b6c05fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001385e6ff86d5c54942c61f8f6f0c10089cdc376f47c0eeb9aac526824e2425887d2daf3782b8af6ba5f257c713733fad00000000000000000000000000000000109650f8f39a6ccb7e3055722322ba86f5fc4579a689c7f36beb2114256ad3e9feb94b72ef1116f40461f12cbe7725841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081f8634a94eef094070e6d3a1479df97bdf813b068928588560507ed2cb27241749d02df943d03d1dfc1b78534e7b970000000000000000000000000000000011b336e5a5da35ec1035b3d38ea8d8ae4fd9d32105f9587f582e56a8cf456638695c803d41a2abf466724de25ac9ba391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001102fbde1a3c5ca838afac5e87638183ba9adb82949d28f257937de9b34e93827235be696c38c32a3256002e51c0d2830000000000000000000000000000000015d5eb14a5a12c7fc388f49993f9a56494f625033a4626d1ff66addf6ba85bf91019ade3c9771398e16b412ebc5654941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd4564e079b268e02e8b974ba0616f5f9bd8262a5465532a60b115897e1830efde0536478d56ca37de5d54010d90645000000000000000000000000000000000f21442ccbd0f604b6cc9688c8c714ba38249b787e7cb94f1f80cd3a9d0c6350d001eb90db1c32e15e4991227dd0f2ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b83429b471f82ff9f62cb2e5402bcb39e8720ebad12b0c7988a81791011bb1c212e0c7a20b5ebf2dfb03937fd7effb000000000000000000000000000000000f8cb80d6b2af497863828dfd869157ca4b7476b5421ffbd4c56054c6de29133e1040cdcbd83bcd042c7d47dfd122fc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcc03d5a782be1834611cc121c208cae4266ae284b79d86630a984899576b6cc61781c865783c528b45b0de7c63ff3e000000000000000000000000000000000137d5c4315f6ca01c1c88221814a6d5c4b5895ce34997f0a34bc6d3eec9347c7192b199d01ed440aec2369a7fceda7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001299694f05b673207c48ea5b66d245163e95f6f51c08c941f53bc217c6426aed372617b15dd499c68c1839facb16d0900000000000000000000000000000000018c298fda0e18eb2c5fab6ab2c33a9211e8ad6d41dbdc609002a4ad61cb3e6af7d4a61a1b2e65f7b782a798cc20384251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015da7ca038fde08c0d01ff030484fe24e446573aa5d30f21d0539256c1ac80ac2cad1e240728e779aa4bce204834a6d300000000000000000000000000000000143ab5e494603aa04f7186b87257394b1a02069f0ac487121524bb734538123e5e88fb18fe45861d18eda761086e9e981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141fea8e72117d32a28c67c8032905e2a9c0914007f466a444abfca079075fc1929f091feef72238023b1b1e561df2d100000000000000000000000000000000036279deb5601c9a975f8779747992493c583a55643d3d9ab45d6fa55c2b22890e2833d3121f0db8660760654f8296be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108e9a7821d4f61f9c6ce5241d294cd0596df6b435a1fd28b8905bad742da45ea2eb0e0a5483f5dfe4d8c891b5a311550000000000000000000000000000000003db81d0f056db8a975c26a96111e6ba918fb064fc95f5414a7f56f64e022e25defb19fd48e64461fae0d7e921c7534f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001056bf81c9a3d6c848973a0b4697a6a42ccebcee8a618bdbcde792b4c3f3f92b00e006b932017d4863c1df03b68893960000000000000000000000000000000005467d0594e44290b6273d8c9d3f47bad4c6bee27a45142b892a0d6f90a29c4db5ede4ce58bd59d7b7edeae932ccd4a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a5b1b28c3a1bce112b21afa50dbd46234b89ee1f91d735d59b72f183bcf107eadf169ee547ce1a0b9fce5e86e2872f00000000000000000000000000000000013eabfc8944b22af3e1098724aa788260c16aaea5c7b624a02d867e8201b3428105a0878da9b320118b0e019bbfe1341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bd87ff830638652e9c5b1fce066aca06ff92aa99fe46393674ba217051fa972a42a2ef59df948ffaf497117d3395d100000000000000000000000000000000009db3eef2ca39294c2f953b94bcf48cbfa7395509184f8bed4cf68bf913780bd7fbb35f332ba89c8cc8ce20ce2c915e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184dbea0759c96dec441ca01ba93959084e874583608e8c9d8a8fbeb19af674a5692d22af75bd46655d70182ab88808b000000000000000000000000000000000c1786f7a46e188452457b69f8b7df4a575062083def1602c6453bf7f3059ef7843a503626652da9fbcb66b806a649d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9a8b92e3672622b4c71e488db3459885e3e41b5c554b3725196a73bcb9937344374ea259eb5998d4ef2bff4afebf7b0000000000000000000000000000000014fd6ba80aee046456da2d1a442019be90bb927dba8f74c7963dffc29950f576dbfe7670d408a1bb4f765faaa70b3be31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaeb58a508f7eb92a4ab83a7005f6951c31f9d56dffc5e8f2f857ce7f2343a30f999f3407e4fbb8e3fca8a6370ae3b60000000000000000000000000000000009e598a46a06a887f22a63d98ce2c768bce86fa57b5824a7c270f4a3bb345301efb51667ea3c2654930232ca591cf01e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e381b8141a779006ec965781bddc64ebdf8d1d9ec3658d7b65d48fdefbabe129f5bc42c5cfc77960ae01abf59536843000000000000000000000000000000000b6ad8b406ebca6eee7e5c572f2166a583033250c6aeb70cfeea934f6fea4af7f8594e0864aa17b542c1d80e54b54d981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001209a8a1c3bb1c85da1cac03629f3a1bffa28ec3b42f51430b46f7cb0de037a659588da61fd32f20ceec1827d45a4eef00000000000000000000000000000000116266a999af3afa74e14515e735d5abd3ec85a36992a9f82f01d0eae40a33e7c79712ab8e91f8248f7899861bd0fe451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039e2fd3bb734927b58a595cc0ed40ad477e1f480aa690f4f9af7f9248420a9bf65a63f25bcc9eb0ab4a2f51a2531afd0000000000000000000000000000000001e9db2f59eec371ed108a643c8bb0e25ed9969c7b94efe60dbac0f03164dbf25375f07307425ed7a2998b48b40326601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040212c16c66902ebf81bc44353d3ba391c5b6aefc05f5c637dfde12e55c5e63fa8f705283d21180a2ebb365708266f300000000000000000000000000000000029cb5fef429ac10ed8b12412f11c1315da8f381ec728523f157ff967f076aefd0001a0feb39429e63c0405e6ac943d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbabbacbf35839ccc00d22e3be550e15a621b98ac545b9e9cf8551c65a5cd3c0290331d49e29278c9e3ca716e5a7f86000000000000000000000000000000000957646f5f592fee4d1aba264e1f7ac633417984e45b18e624f37f8b42653133657502fb25608276bf722f83ab54c05d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a7bd4db58475053be8079df2969efdc5bb47ac9f1d424efe6fcee3c23fef5311ff1f989ed8721e585eb5f95dd3855d000000000000000000000000000000000b996c80b2e3492c3dd2b9e0244373b5ba1b9b2c36292b8115ce1c372b9f6cdbb1cb9f5219ff9d6f65a470a5af1f271e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c2f0b9bc7c6db5f567396f4a24cef58151038aa022e35afe65820168e3af7f13a30f2a4ce1347f42e5b981c76578af0000000000000000000000000000000014068f6e954e92493698076978a9db21c5eabb1f94c9344a895a4201ed90a3468c13a1aa47e2ed8c6f2297c1d6ff3b531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f3b8e3dd11255f8748d0e535dd95024ea75892d9dba82c662308fc63dbb179c009e03e7eab6ebe9b25dea14ad85a620000000000000000000000000000000013c975868cef4873f827ce6fe397e3f4f6ed4c5d8ed44d76dbe3e6402063179161e3ddd1ac29f90c3515e5ddadfad3c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f54f97965863c77a7d657feaf05bf666178331df0859eb4439520907e2a6b15bb4d8f5b3dd269c26fd59165fcfa1d50000000000000000000000000000000003d6a3df5d87af1d9366e88f868bf41a1367e39ffe744a0eef615c956bbbbd1f92c10b838151f4eed4765b8997a5970c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132372a6104f8f3555dfaafd263054af25ef0d8b005ebce11c9e181b00cc7f0876c62fb7cfeebd827c675af54fd0c64600000000000000000000000000000000123a7f5254772da34a2ca376e8141b35ae417c88788c3f72cd0f5d509ad3a7ad52cdcba2ff803acd3019635cabeeab481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178bf36636136b8b0fecc4b0d2da4e49b9309f1fce351d4adc4a4ef7546b384c17f3a820669227eac319f3e26b2803480000000000000000000000000000000010912e83d60b91e6f0645e1ba2578fdd03ac0a5540f9e5a54aa8754ae15f9d100f72ae18ea0ff20f4e7018bf218565ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0fb85c7fd63e97ad53eb91643f1d7a0b02c4b6b4635b55239c80cdf2e9a09481274442aa82c10c180fbe58d4a4cbc00000000000000000000000000000000013ef672c3d4d5a3f950c385980ad2152d39a695266a3ee93b3e98156b3bec003b29693c910cd96bf78179ade194d64c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001410659e4eb02effce055f8d9816e6b6cbfe69b005ba3570a741dca5b8931ed501a82a8f19d9abe27aecb9148136fd88000000000000000000000000000000000f34814334cb289a7be240d4d3293e19ed7e942d8fb88d0abb412e063e47de4e8ac6a93402ad97f93a4d2742363ac1b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000166f64a1c3e3428fb2a9935c9bcb1606f97fd53ec36f89f559616604742400f7ef88244f6f0133a8a34c92b97a843c70000000000000000000000000000000017ac94dab4a5293f8399186b9ce92d2e5341ce4fd95c86b3ccdfdc83659df2bde4945f369744aebc219c41da8aa8fc6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e64f64ce21e71baed7b1419fce470a86e952aa7d77ace9ef83f4c61b724737aca14b5f6a9b8afc96f56424aab175fb0000000000000000000000000000000015bb2898673cbd1efa61d66e4d8b6fd3913319e7eb3fd2b19f77828fb64725a4d403becebe0667a18c3a87468c3a46ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f75a579c35cc744cc9cd5d71a46f9363c91c35b3f24a2a8e62e242bbd0f17b5a5a74615a5e1cc691bc976466fa4ae0f00000000000000000000000000000000064e4d67bd5b83269836e4839c86c8c3c7438b9d29408019bc20e0ab577e857b28ce2f1157941a360a858cb6c30427361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016beff845aa068cdeb86cf8f38e5fced0d127a298bbe5f7e3f9b6d89763b8a3997e9658814be1f34268ec3df2079503e0000000000000000000000000000000017226e07ed8cf7c48de4a121d3026df80b2b19bc71c7685b6baff5e8c038b2c504217a82afdafd043e731793619d72721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108b7915e793c4cea377c215d8f306d8dfdc79689789b22438559b803b7b319cb5d35bc18de9a0be317699808935514a0000000000000000000000000000000004af0cc42a5d9c121597d1ff737571584e3259344cf1fc3826eedf931412e739ddad5f3865a2da102612b6ff2f885a8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099cf3f1cd3043c741ba54219a92deaf40cd262b36736d8919855c625db8d2cd6a8005b5de87d8c9fefbd42776bc26cb000000000000000000000000000000001788c7190b8799d6bcbb720f54228fe997c9454fb9ecad3ecfe05da44900fa03f2ced6cc95e12df575f6db8bdad58a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063d2fb1497d9cf93a46d0eb9c27ba309acc904be26b48eac9a755a2b0ae278a474d6be3e15bf1e71cc1c383682d98b40000000000000000000000000000000014d924ff714d996690fd1ad0b34c893fe204cb4da5ee3d2199a0b9fcecc42c904e405f1f1a3dcf4328457896bae802fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f1dc7f1fae6f070eabe369e02d83b9e0ae934f3789146a587ea789882789b47fdc3121368bf88c0c35ee2d687e6e39000000000000000000000000000000000fba1d253793ec135716ec03288f6487248da2190c4eed2b1cadc2286bef2d695fee0126216e3d9de8195e97ac734d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001977f2088b9f343a163c3ee2d99890dd843459d5977d4b30b3eed034c5565eaf74355eaee08e599bfdea15b22478c7090000000000000000000000000000000008ea11d18299366846a5ff17172336d6ec85a8e442dc932a79530f735bab1a0487c65d924d27b56cf2d92a44c847a9a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000873c5370e5e674b9a01c7987d45fdd4ff6ddb85d68c30c429ff56296acc04706971c23cd03f6b6d7eaf2c8a40f3b5f80000000000000000000000000000000019a307ba13046d385b2b0eb72cb7e7a40e3776a9ad9486e68478cf7747f0b05d92c96d5b8e81751f2a29e5f205565a0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b5dc1decf9c6cde8651d3e8768ee709326759000895328f16e2f5c4134529655f7feedb440ac7c3649bce5c3fd9c8700000000000000000000000000000000074bb82ec97c571ea7e35655825c2c0662eb4b3e0cfec3782759752d0eb1552c9c2419c8a9c7a603be31eee5b6e7adf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c69e8c316370fd788a3178c38ef14539a7309fdf70861c257ab29918c24927efcb071d7b3f05a91631d2b78549a0cfe0000000000000000000000000000000016f752016e2c3c5d41e9b47f842a0db704837e0a70b39641b65656caea64871140c385a3034c021a1d31f329ee9910a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d08f56cf71e6f4f41926276ba1c5e9e88d3f956756e38abc09fcf3313d0737e8d76a2af836b0497dffe4d11b6f183f20000000000000000000000000000000013f6e19c1b00db73c7b4a509b720ebf1686f12b2e27781815af2a5db351a07cf15a310b40896bfb04150960dda46d4031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030eb6627e38171603b17f60fc2402d9a16a0aa9e42cfb642f54fba044f0a60a197ad872172b61bb7bfff11cdf76572a0000000000000000000000000000000011615c1f53b54665c6e45d56bf9440f5f7e57757a6b2bcc2f8d3e564fb6cbad9d04679e574a2f68fe71d94008b0bd83d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e9fb55eefdc4f89c44fb78db33a556d7fb07e378dedb26bce94ffc500de8165f6ff29893e26cebf31630accd6a0bcc0000000000000000000000000000000007a95f4806e9d715509730d2ea65f2bc5bde9bc8f6f43705d8b5a8fcdffdc3b3e5ea367a5c75ff2407561a49f43767581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027e0e801fe05151071075ee24ff3e789201aa357302e701290d0970e96fccaece2377846eae528771464e214e9d8ea60000000000000000000000000000000017e25c94d5129e018db375a018cc67dc774c0fa8b451cecf247d916ff6043609e24561b2b9c1d450b630a11f23f112cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfbbb937297757eae35024a93a0d55121a0dfbedb9658540f70e1a4414dabef4eb56f1c3e02a95d12be59dc65c1be8c0000000000000000000000000000000007a4f900a46ebfd3cd082cea61b605b4cb9f4f4b5a6772e7851c670f724fb2415de49170ad03c34a6a4f2408ef71160c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca7ccc599c082441dfd17c68ecd01813c23955d0f4d506fd1ec76cd490f25c001daba20f1a1cf981a7d28f8fa2728c30000000000000000000000000000000001e23a2a75fa119834f50b00575158c530b630ad94e24ab7626e1c25c9eea6811b72441fbd32cc6b2df5a6450f45768e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000be397b1f6efd8cb4fd72f5b7c6411c6f9c4fe5f0b7bc3e1956e86d2546c19752328300b6b611bad65bf08d498622590000000000000000000000000000000019bc19d9f338e2970fef712536ef52d9296acbe15c8508c8c4a99144ef6f76f5f18d98a22557b7009303daa8c5ffc43a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b7721a500f0a33da809571be189a00b7502d4d871bac803f5728105a3d58b44fbe186de087ee67ee4ff89afedb5dfd000000000000000000000000000000001790b57376e47a707823043a95aa0d3f46ece80490e1e83109cdc0f52357f100d5f5ad523f0d734780c4287133bd96dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c60eeb008e009666e344f8c0486d54c2d70a662e4a1b16c577fc961c9624079f2d06a4137b194eb80b81e5c2befaa5d00000000000000000000000000000000177af139e7e5e038e9ddf909bb6511624ca046e2ea39fe37456025b59f661cfe66d9d69eaf067f743088eb8df4833af81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053311a219ff26bafade5603edc0fb7de19ffc83f9abeaa542c587c375037e20ec6285d8b0cb55ad724847f02439d5bf00000000000000000000000000000000173afca71f6bab7a9c8fa771d4ecf4104d88fa94e7fc98c54da0ef047dd1d08ebfbbc6001da2c9390789d8fa993e1be11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d185a1e889f6474a15ac74a43a3f01df572ac34b509513d63c3320c4f5aa967e0b57b4a1c21a6e851758594d2844db200000000000000000000000000000000085a01a961a3c7b36ff8cf8d1e4f1d3e8a13b97dbecbe49d13eaea3f7814db6d5689274738920af4b5b53c3cb570122a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689f4617db2629c52427859183264a05d085c60ce7653edf55228a260319a7730a959963780acf0fbffa2bc79aff7de000000000000000000000000000000000480760c6f41808477ffbbcf4088dacd3e4d1ea3433be7489150f51d6e132de6caa0ff9f40169410de1eb9572d8bf52d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000386626ea6f078e55f0d02126bdc9095254ead02254e36fda4dada928010af313d80309b4c7fa277d1fe720c9f29a22b000000000000000000000000000000000f5cc754ce54f0dce68676796236da2b4605014ba5b34589cf03090ccd423a2b5254d43bbea6efe95e427dbd5b2ec7271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0f53a8a3ac24fbe02b36e04da5403aab375ba337071bff97f6fe1b0f213025f5510ca39cea980fb764fcaf174f7d72000000000000000000000000000000001499c498d87de3058c9d469d51ab1454b69d738a6754f8613309b7941b6778829efde33fc1ff2e8dd10cb08248fb7fe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147490164e580a71e22e5d7e4542c9c7e34884bce0d9516df9d4227ae76bbe544f510b2627226c30857b45f7894ec2af000000000000000000000000000000001162c3f1c0a243d46429edd9f8e3151eaa87c21dae7d7b82af24a8ef8ffd94f7f3ab43772efd0c556646a909c1d73ab81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128f1f181a2067577e6f5e3fe29970bb4c51e4c2a78988ab1d43451719359288e56538e198e70bcbd2357ee6938e1e560000000000000000000000000000000012f2cc03e70f101eac90f5b11503f75500242e6460b4821a3f5f2b375bb9d28176d096f378be46e7f45608d84d5d70281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e47074eb7d730850d9eba36f22a2b79019886ffb1af3dbc3766fd34156a248d0269a6e8e01bf3bae25cf7ee7769b780000000000000000000000000000000004506c23963e7a4f043f737a3d2f78bf88d29dff9bbf4663f2090127eacc32e2a849e5e1be2a07e943142660c6fedb801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001661bd1bd92afe12190c94b965476111e0db7b3c7f28d8fbbbbbdebf40b878fd3c7591b11cba9a9c5bc983d989712e7d0000000000000000000000000000000000ef7c43a43f6eac3f1facafb73f7abbd57260aa7793f168bb789e136e8e6bea273e238f9c142c08e2e3b377baaa2d8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b209646e4b69b1323f4599a1049194d5a607311e639d91c500686e7198e051e5806cbd3be6f9d62b2383682a021b885000000000000000000000000000000000895dfd92fa42deeb99eae815d61b0f9fcc7b97f16702494d0311e95afc58504d5f493b8c64143f2a35d044dd58b9c4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120906549bd4786bbd0f5f9d1c6d993051b7626b2a3d81be62158cc38b8309e3652e806cb12647733e030fadb37dccf300000000000000000000000000000000004a3e963182dc33dff5ca035b9f8fa38fb24b6fa5bbcdcf999189158e8d8ad987b20e0bb2c0cec380b1a2e6b68d21df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007802fbc22f43355d31ad504f1199b9b22f19cf0ab62917c39a8bfa574f497ee4eaf3d6d3e6513eb43b9981fe984512a00000000000000000000000000000000046c4aedeeed3319babd08e47d9b76f0d4d9ea07efccb2ee44cbc0ca037692cd6c87b50e426af123cd4b029a9f7d86911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab39c649a8b969cf8b1845d8c7131db5ddd320ffb20e01673765da7ed6e403bcc8ca92ac267fe41fee5aee33dc1a835000000000000000000000000000000000a942b4522e4f78692d040f945c4c8ee7f8e67cdc9b1f81fe9db3f5b55ae0bf20892b2dad8f74f4aca6b4c05e337f1471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af065e3d5dfb4a922a986bc18967cdbd339f1e58ec93b720d771d627adaa3e84e503be837b15af06e1bce2e1479d2a9000000000000000000000000000000000086d68058a20fe23ee7f67fa6aa5ca4af696ab727185d1f1cb4b4c7ff0bb1e61be65cc45ed58bdbf00f95fc96adc95f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142cd027b1c4e870ddac162b6b8170d6a067ba6cafff9fd6d78c5c7f6f576f6201e449d0d0975061afcb44f8580df0570000000000000000000000000000000006817f31a985e1b534d3664602239412d22146a0111467cc8b13fdd3ccfab56e67b01f86dcc1b9097e7d4decd7728e771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001621e788cb0cc44e1b8c2318580a40db301ca29a81705381a11d7f096202562efe26be5c3c71639c648c0c0f5eabdb9b000000000000000000000000000000000a19dac3d16b27ea40a9a397c7331228e9e857290da2359e4a4f2638a2a179c3c672c62b9d96c7f6225a27a7311791521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000699b655918a7d1b2b61775cb3714472b493e7b0cdccd8ad4120ff0a42b7d1253331d98f6ffab67294309675c3b4ada2000000000000000000000000000000001032d11150d629a84aa2877a65aa278066f3c55c7d17126b4c048d4c88a57ba8c00d0d114ce49fe4df64370786ff6d5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000944f87251dc8740d49b7ea92a6ea71c1360ce3782f8229130e6926b3a861ee800325d7c50add151947a510497419247000000000000000000000000000000000128e43bcc2327d9fda3eeea7b63e297fd9b35b7d731d66a2c8305a6835dd8f45f665c0ce667440ef1f5f0611989e8e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148fad9b69bb0bdddf0047c5877c5af687360b82abb70c7c84411372eb043c7adc2c124f442ad0f2c1d30c6c746b131b0000000000000000000000000000000010249e8401d308ea8bb05dfaf0a32c30a3e1c44285137da5b08c3eca12212bf31c1fac80037c6132584353b2342cafc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a56103d62e728cff75041977cf94712eea192cbb325551c22ef17008d15296a3535b9925c5fb56416176a5cedbd10b00000000000000000000000000000000012a3d765f5338c4b32188cbf24f39ef5e404420deebb5c078427771ea7b06db25e7463a84cd16f37ecd3cc0d975d18a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144ec3b136cd25c2199a7a98e78b5a29d2d4ef40893a5ca6c2ae99db7d50c62a98a2688bbd638cf9a1711f25afdb7370000000000000000000000000000000000cdeeeb2f61823a8848c542dae28f0000960ed4628ced4187fcd569795f972c10be1357aee8cdb8038bed8a8234d65781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001515362b4b885dcce8100b2fc5ab85348077db5b83dc181543213849af3609e6d68ec1751876e9f4c4a4939bfbd36100000000000000000000000000000000155a2e7049fbd76f416b03c70adda54e8465f8c49862c39c0c5622ffab8e9fb2fec0885811b8a8e52ec5fc08cec508431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011afc43b67340dd4d08bcd9a32594b380351fa6d2f17569d4552bdc0895b6bcb3bea1ff7be58a7e93ab14c247275315c000000000000000000000000000000000e4033fa2d04230d22c50a42a9aa52877286b553374319329ae30cc1958a51d870ab2613ff43b210bd945fd6a64406651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ff9b229f19f0d535e08316cb24059ab1a424ecb125ce444aba56e5b7fa0af424a07f23cdc1abd10dd0256305f17bab00000000000000000000000000000000034fd1f4f2ae0dc342608fed1a3850d937a37ba9e1cfd3ef5d3283dce933acf5a9413fd5e2522169761c6bdc60a44da31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c492a93a588333a6d1ab40c9a11440e2f97fd21b0e497d8cb8f64415f415c2aae4f5c32d766f586d08532ba6fafdbe0000000000000000000000000000000012beb1ef4c4fbea1c5b0410586ba71a3dd8d390693285d8948c9d13b28dfac10516d08844f976142a6046e1f8dfc5cc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125a63edc2b5c383c726849dc734cb0d7961da58377cde3f994727eff1cc506dff698253e6e6171c76d68726ec747cf50000000000000000000000000000000015c6fa071f405cfbc45a69505cd91cc07bfcb748b2874d9ac77dca6a8426dc131c3c09f8c8f86052ad33c6091fd629d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bb437bffc5342926ab62d68805e9dc5099201e874ccd5940cd44f792140c57e92989e660e72648e72c680c78fff83700000000000000000000000000000000176459071bcc5d386607c5187e69360ccf7ca72acfd1614348500172bb27fef781d3b2a1ac2c0974519d13c3ef79d3c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179fb9c2cd3e282bd6464abc39c23e31176952b4a5ae2670f659b1b4967a2aa0f7655cfbfd6391928fc464179725c706000000000000000000000000000000000b11da59cbbe12d61f7df13004cea870bd9a10beebbd40c56ea9f8f045dbfbbb5135d6df5059d96fe45bd5fef07584f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070f3adb21331dba3c26865b57794bee01142255fd2427ebbeb3bfcb355d37cb262ce2eabc1ef14f97f25e11e34603360000000000000000000000000000000007c2c25e6630fa4db72b04848ce5df1da3d28148558f2ed62581a8b348c343c32bf9d429daaef37f34e4e28e7b579f971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cfa6857713747c5673a74f5b414fd98f7091310e31cbb2d1530459ac658c0d673e27299f53debbf41e4dfcce936f26000000000000000000000000000000000394549714bc3d8dd61c1cd1c6b450ccbe10a31c69886c0a767095d92bd847de226b42cc2f40a494e5b26601485686101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131ddd112c353192b8ffbc1578218573316d5eefd0b997af2fefcd5403a6b3d95ac161d4b7ecad142b8ed2113d566f770000000000000000000000000000000013f1d8132fb3fadb5a42f06051f80fa692a3c7f148d88c3d02ed8a92496952df3816c98b96511cddaa890de3b5f0e52c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187e272ee6656dbbc960c9ee2ad15416c2c51ab4e17b600b33e36bb0d054e4f231f8068a9c2181a68475da170c1b6159000000000000000000000000000000001693f4ff3b4616277b6abef396c7ed3bc78aa85d4d11d3b3d13b659e36721609fb491a6182fb9dd386631d0900d045431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007df3c4a648f06f28655da0e0d71412ff1f786da4ba6415235f227ae1b5c8b329464a5ebebfe8660d11ab06511aad3a2000000000000000000000000000000000f034e2d5180b789cbababfb9d1db3775074b1b4041b714b2b4c7bc55bb34f860bac254b73584004430afd90f38b0f091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139ba10bb54c62ccd4d6c40ca83128d0e39f677e542f2fe73d536ac286fd102b5cd66743199ad458697bdea931b0c96e0000000000000000000000000000000014986ee0acc79959311a821c42ed49ba7e3f018688f0505317060deaf6eed68fe86c54fa24faeec2f06a161c740339051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006afa28c5d710eb3e4fd2bddb05ab6c27982898e46cecae0cd4a669aa27f05f0db6ada48b213cf68cda433be631b360000000000000000000000000000000000457a160abffe20be008081f3d71fa56b87caf765ff611f5fbbd83d8bbfce307eaefa29d43f94d557bf2195661bb82fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd31c70b600c66013616a937e2a031e9b99a6968b6ad56314ddc51772042ab978b596cf1a1f4f556124048ab098afcd0000000000000000000000000000000000561ac6a65bd9950c9f75faa6043e280ceff22916356da8d4416d8e5a87742dad1d141d82eb90f2fd8e58ee39d106921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2c02cceae1ed3df350b68e324143fbb9f8ce2fa018960439baf0f243eaa81e04a77655a95da16f880ca86d990f45e70000000000000000000000000000000006478667066a43afdb7fb88a9b64d4d4a389b0120312b9abe2c793a358950fe3dec23c6803d782b335f4a0d82b08cf021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d6d5caa0c8feded6333e4776e5237daa42c181a058d4b8cac1c30bb1284f61bb6e1d40b591ffdb18643b943e67166a000000000000000000000000000000001154b7d57db13d477edfaabcfa406b7fe009e146576561e50c59d1399465a95761eae4675e0f3f196a9da62f1e3769a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005be98e323b44f1553d3ed33b68958e1b51b1425a9f68af603093f705748b6a9d187f9e22837ff49dee37416ab07cf820000000000000000000000000000000009ca6ba84e1f86cf3d50ba3f7ab5abd4b6351ceee1c35847d65655b14fa7789ec7ffc4971bba4973543106ac2218adf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d4ac90a81b45990d87ebb037961f5f2aa11a870b2278dd8debf2604ddd398561903aa38f1d7e959c501da11d9a69ca000000000000000000000000000000000972c143863e33c238f41665281474d92a035b4c5bb23eb74d6814f4bff764871f854b70c277d9246935863eeb8e5d891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a7b5b4a6e27560fda7b47b47d70cc7562534b9ad407495863c1b2e7b4d6bc0cc03e90480d31db74c8714ac3a2708a50000000000000000000000000000000008e3a1754d5cfeec4efc222af528a6947c630e540981566237a0622c8deb8b1ea0f663f5b06ae3e70c4fa002ec151bfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167a4191218ab1d97262d1b9eae10c8a789f3a8bbb5058945206255901d31cf0adc8c7d3f62e81c486034533cb2c1822000000000000000000000000000000000567f306d9ab0ac90e2db473afc4471017e0735dcff7a416f10882946b2467810768886cfae2367c312d3dc3373809491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fef9e59d5cdbf7c21e2eab254833433c0dd7bf6f310294be5054aa01b6f96e1c42a844894b484f21df7e682e180389000000000000000000000000000000000e1f5a78e32b3af1ee825c121e9637df84af5973b755ac1aef7c7901afb493154771f6a2fa1ff1fb2dced28752d7f72d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194ddb28b07efa7f5640f8cf62e9646f5acab9b92cb8c7e9f911d1ffc4f66263939d29e58fe0fd817b8a32657c45a41300000000000000000000000000000000197139af4bd080eae31f7f97872a447ae21bd1a5de18db7a4413e216979e67eb95277e1e5f3d2f5befe3bfb914e9231a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001242d476d43c34e0a5eafc1a864f8354c2d44293821bc38ca6801f5f89d5bb7f88c9ce0ac78015bef858600e7a164a71000000000000000000000000000000000537557d4b1287361f263fdb88600bcc223bf763afc56f24a7bd7ff47d25976a4178a5b1d648b41105b4e2653c2334401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed58dae7a96105a03f03acf408da0a43c37e7388d15614fe24e278558f2fa1232f656afd531c6d639dbf200218c7fa50000000000000000000000000000000003a4de29591a8a184e7e47ab6bb1be1c2436c9e1cd80e508066d828a09977fd62d9b173e2510dbd1464b1b056f0a80791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000398bae306aa14d3ada53f8e944ba25926a9b57fef711adf39221910326ddc64ed10dcbc0ca09bd2c63e8112494a4eb30000000000000000000000000000000004e2c0c99475b69de34ffd0cf157b2583bc8a41cfadc3c2f665b2590702eb225e2464a1e585331892d831e51a89aaa2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d1094d50494a2fc829b20aff39bf7a663d42d63c4d7f1ca6a9d6070ca401b05283c469f256db88b76e044ee6fa6c9d00000000000000000000000000000000100c547eebf2071ea67a14405e2101add7ac9eb4f8f923f21adc0c503e3b539c09ac60f6bcd2a6c577fd138c406d8e221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e05393130d6315ae832371622a68dc08ead0a8fd5e748b114f682bb860a9a9870c1c03f699b4123f0eba5cd978dc7df000000000000000000000000000000000ac00f4fd02d97d61d7b877c79d89a9f133fd6dcb98d735578b9f9f6585b263b34d3764eece1c22fc809e8187695aacc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082a5f6192516331d9e8b1833ec327b144a5a020d1ed0b0bb4f79831cec38cc6d223def3a17eb455b14abe48c2c39c270000000000000000000000000000000014046e573933bd62848f1accbd30994e87fd8e489084a4e22d0feb4a3d58252315f44e51568a4302ff7d1af0efdd89ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000527e8bd1cae5835c17796536b5cbddc14cd11788895261dd3c46408ea35d4ea397fa962aaf570b865b088ae6a448b950000000000000000000000000000000019439716e490690a1015cadba1eae76f523bdcb01b1b18ee1f241d44818cb4fd0563920179b354ca0d34343ec8a4d6c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038344bdb314e9de4800ee3b8a70a2474b531b89b80a5219902894fb74ad4936e00023792f11c43f8fb9a73fec881e000000000000000000000000000000000008b36196a86801d0aa423ddfaf0646c1e05615b5af44e70e89f1345e4f629a1b09cdf87a287437ad78ad10a17fc70a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8f6deef7eaca9ded38de029b72ff2d5fcc65d3dda922a4d5235d77131b5b45a3affdffaf26fb7da772bf26bfd587870000000000000000000000000000000002411f238bcba73197c1282723463b2c50898eb546076011b24ff24b5b82b2ff74f097a8f617e7e44b666d67cec3f3b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008593b39dc5c4e81b9e1a376e39baf84992960db0d9c13a8db32da7ee31bebbe20b17403135ed6eb28420576d7467b78000000000000000000000000000000000b6bb04b5b53a0db1ddaf2911f6052ac7774e067d23388d1ffdaf69cde7ed5873cabcbb50ff4a91c16a39095c1a2f2021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fbef8516765ce9c9347e0d0b28946582fb75bb574f227eb5fac99ab8f8c03b7352ceb55bfc1e30e53ef8de37b9e36b0000000000000000000000000000000000c4e127992f0c2bdddb9288d216ff3d448082e97b19f11fafd93657907073e81d5169ba880ce6abdbc0dcb885cc01581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000148d4df38533516e588f813df1ee0693669c3ba8fddf50002efbe82ecfb651e907e3e72aa737a3ecf4c9ed896d067cb00000000000000000000000000000000122b93d1f34a58aeb960b77bf49576cd2d5bf371500baebb35c64ee4465856d6ac5a764739409ae2b1610dc70b70506b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000802f3cc53b9e19b7c86b67a0f26bf2edf26c9ff3ef03d89f66beadc7ce75879b73613883cee675613e78adac552222500000000000000000000000000000000136de5ba963ead16fe78dc68b326f95496bdd5744086a972a0564cc33094f7976f548a2abb84a6ef24865036f6c26ab31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000882ac25a031e8a8ee41008737a52b7f7bb5084cbaa44c2e8897feef93459ada9ef475f62bbb850c45c00164d6c9b61b0000000000000000000000000000000008d41661a294b291300279a823dc0bda32b7f11beac75d623ccbfe822a071c85b6c7ebb4e6fd4e4884df609665fcc01c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f320d2220190dd2a58fd0a15f3e06c1bd97430c8f61cb5cd7cf5762d3aa8795631710bd73107fc7386474a70a659ef1000000000000000000000000000000000c199b95188d59e362658562d085bce0498557a1613fb554f75116d61f87a4d2079e58da150ea28b8fd4a6e72760f64a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138c60fc15d0b801e129ce0f54e8bab46ee82796872e4b01f145d1227e69ed5398801b0a88962cd00df88cddb1f9768b000000000000000000000000000000000e2b8d5609be81bb3d1c7f8daf702d76463a3e6599a0721a3a2cc5ff3b6d3387743ac9e611ab5a629d0b59f7fe1cf9e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069c23677d7aeeb0a8e548a00f3006a40b493f0aebf20099dad8db312564816544a8db8f5bb10e1f0c57dc8ac63a6df60000000000000000000000000000000017223bf5c9324b990188f8c28604cd6feaa8886b2c6058d594c21b87c95383e01b962d04a288ed50ea13a2cb2ca8f0dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185e3a3a52709fa0dbd9780ea13dbe8ff0dbd94e514bfd9bb8d0784be0444ba84a987063f959a8830787560d6d6a95da000000000000000000000000000000000a0776471c48ad7ea6ec8f26e51f04ecb09a993ecaceb517e9dae29dd36713f12b7a38a0535d7242f698fd9a93e285e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff39fa938872b525f07b0e56f820a2c4b2dbc98b75c4c2635c053c624352577e7c6ba4a66af0d5e94d1058f5e67209200000000000000000000000000000000036a99847003812d138cc7f568cc481731ffa4b07ca87b0a63c65d8a4620b6f4585f615f5079053346eb90047e53d9461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007cf827a9e1f834143d334add1be4d168cb42eb7b99b13cbdcaf6f461fefc54f110199e8f909da8d0df4f4674bf0bcd00000000000000000000000000000000011526caeea64195a89f36aa1500816a0d0037b233dbf6a836827c84234607ab83e356f3257703f2fba96d07ae815b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000979e0dca31ac72cdac9f21ef1d7982592a7aad51b55c006451e6da545197ff937add4f1fc0eec8a5004b8d6751d3f490000000000000000000000000000000011c4056be6ef0fb8d538e0bb1c9b3eff46d3bd75914634e5b2735e564b091c81c434e05c340837194fa5fe9cbb83948b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125e963b23e57c013df669158a2a27e028e4f791d030bf3edbf7f8eb40c30162a076472a5dedf82286546d9b6303f28f00000000000000000000000000000000114ccd83c76bfec63a1117739a648af091ef65437b6a987c008d89459f05647640219172ea1c5c3a780ea380b54188e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f22d12eaa8d8d9f0f534faabead875d7e57ddbd8880310efd23fefd881d5000ae716f52b57603cd3ba9a0d97910c45800000000000000000000000000000000015c86c379239e916f726455d25ab619077326adf6a6a7d1bb2cc6df27ea48a12809c03ba188842a9f91bafd9accf0ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145e1fccab0effa89cd913499c1b4bf8492460452a9ab15688400228fc76e67a830e6a39e79656f4a1661a5721d61b7d000000000000000000000000000000000bceaf5a5fd9753b0aa412c2808300151309bafc5170a83a67ec91e65b50818e15736b3861fd78798adabb5665183a9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004330e60bfb618262a5d302556a584513f213f898050b5812f783828944fee41dc4b14d1f0428d3f7e67edcc995fd6fc00000000000000000000000000000000046519ca05da7bbb3777c216eb1038e87237aef7c3e3915c127b5797ef5110fd60f4761e70ccd276666d8d7cb52690e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bfc88cc3e717aa3a4cd66977eb4aa8bb2a052eae85c46e9d975ac61ee2f587734ae7760b94caf3136910011d49b462000000000000000000000000000000000e076798011510e334449fe6a33f74ce500deb47815ee4617ea4f4a576a707b5b1d434c6b48955d36a7d7aba3a9cdecb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008aef76a49b0eadb4b598028fc69120f855613d65f814afb6ab7f3458417b3f11a34861599d93baeaec1454b5a9ea3ce00000000000000000000000000000000127c732ee9c36db7c719581fe4586117f65de00a373a6fdfcf510a81e60288bebbeb21e077c1901ef11b8a7c0b61310a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f748fda777487583cf1ceb2bf42324ca0b91e371fcf6d80638d764e41ffd5398c5c7bb76aa44d0c6c90bd13ab8b580000000000000000000000000000000000b1eae70910241324931926d8981afe6f9ddc92ddbba1d51f838f5f858322a5d93fa9092a098c9f0dd29ff45d95ebf041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f9f7492e85537876b735ac518a95a382b60ab7998a152fc1922723c4288b99c3b227101246a2341ee5160c879ad9b90000000000000000000000000000000000045a7be00785ce04a5cf56a7c6d0b835dc9a005b826df57ea2ec2f6be7b2834db5b35865612805ffa74108c4e567de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000601000b7f064daa2a1f3fca93843e55d4a5453322c0405e6e2cb9860ed659d706f3006e72ea6be8e389d8df8f1fb42b0000000000000000000000000000000003ddba5602f396f868bb1fa8092d79f7dc8e0a59e0505666c99de910cce43ef49a9e53fbedbf61958b41a858db248f7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047a63a750348eae4ba673e5ff353b20719cf6bdbc68c94fb5fe054fbe9b407d28f4a7c46bcb5ca616cf8c80825c49a90000000000000000000000000000000014763ed0e33d8979ae27a947b3eae170d583ecaa864f0ef44f13f4b28d1b7724917656a291e00b2b1fbd80e741e940131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001587125684dcdb7994ae52b7580e94ca9149de7e06dc5107fd179eac5cf85274adb116d06c3d1b1e75efeb4c5eb937300000000000000000000000000000000006c7bc6b09f86a31fd2b69e9551a0458565f4bff88c775d8397831cbeec7f1de91ae8508f4ea75501fe072560fa8f33b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d70ba3f25d50f06ed351c55e396458e337337bbf923df7d5337464b2bc4d3e18c1daa81ba5197233f677933842801b000000000000000000000000000000001141ba7adf3445b4de07a0df3b545589dde0e41a28c9c7a193334251ab717a502f714e2cd46c4ff1c32da4560207bfe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027f2bf1e4789a88bad0558800caa3574cc84a49d86ed1b40afd724d3506fa6d3cad309cae5d2b08ec4b14accec3395900000000000000000000000000000000109299c3506e096a803c2699c00e8639c1fc1504f2cd70561cd518ec858359ccce2fd06559160956e39120561c74c2c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fe6b3d259bf8d8c2b1ba7e2d74da566661cc7478c06513f7c64298293b23579553ee6a6c603840715f5baa40628c7d00000000000000000000000000000000153bf7c7fe9c9c902d2f7307609a7b5c78563040607cb3967aeb6af52eeede9cf4be28d809c10bc03479440e14153f621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001345a0bbce7902d149c9501063d524881722d0a760075c5912b5dbc6ea18f8fbfebdb9017e1002c3a7575330edaef66c000000000000000000000000000000000b6346691f4c480528f74c8a8eeb88cb578f47e122d1377b1c26e11210cda11765f3c2a018314aca9da2d39397b33f9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ffabc584cf5734d315e8439e0d8839df833a654a47853a3f9580c03974e3a70d38a7a1f743c5782eba5450f7fccb46000000000000000000000000000000000dce15bd969daf9cb9477635743d10491fd96b3c21856136c66c047aca99f4212c2ee32cebdae113595a77432eb63ed41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164087770883dda13545a308bf4b7b68c6caf81be4a2d030c249a5b837997bc0954475d73baf2ae603400f38c0e9ec51000000000000000000000000000000000ff741f945145f099d758a2997cad7a99db8774587b03856189188f9f96afc06e1a181ace17cf8f960b72d9853464de31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd135b1f2b49d8555ac9aa9aa493d6d8d60738484ba90613bb15b328b93b08614fd05d96fd732b27e29ed576f297d2d000000000000000000000000000000000e03b517539d29a3ae9b552c129f7c611ec708b0f232db3f774a6e853936dcc09ace5d6728e175b9d20d9ce606f9e99e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a4b4a5ac8650067642d162cb52e63faec401607225b5f05335670ab59bc8c815915dc79b8e066c48f38f0e81634a52000000000000000000000000000000001702e03ba3bdf9971a9105a9112d802b955390cf5f57bd69624874a37c27ca507aab8a9fd6727a7227b3f545e0b90d4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f0ffab560d11eeb7038ecef42c043c6cdae32941bb329a6fdb9217f6445e431e63794ed8d9aa50f0d4cc1df2ed6123000000000000000000000000000000000379d9041c41d7443b1360c3620457ebe3186f9a1eb5cc7d7f26f8ff41fbd6b79f43987912d33a5bbecfa1c80ed9bcb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afbce8d724d371187fa42e392c1679b3848f85a24018435cf89e73b70ea4a281667ff843fff2979ffc2d0ef9aec97ee000000000000000000000000000000000c367f9c6a31e1bf90a31dcd95f9e22b995a664553a444787b0cda7c91b69110b0b2e1ae105ad13c7ace88f8ef8125eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd8d0b306121ec305085c003aaf44cf1e62a9b12f4c3e65975d689d925d9ca9bdca04e0a5fab9e2d6e3217387a3b1a7000000000000000000000000000000000f59deb0ee31e2ab1e7e5c6884a9038fc1e78b735d2e7f5c165845c4625b1926fd3550adc2e0363bbfd61084d6c937a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3c46ac25f4442812bc443b4a064130730d1fa5269d23546e6d5d520a8a61e0d90025f135553e493d9eba9a5fb03944000000000000000000000000000000000a5f49f58d74de2cdb85c481eb244945d60c3f4465017aec127a0db0b4d0b123a6110b900238f3767a4c1c8019e6c7371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ce8c0ace3044c129b869013dc777bb09072820bc3a1c8c3a99b0a555f111146d6c95b21d7753a7857189f0ba0f383e00000000000000000000000000000000059275493bdc96b52a4fb0c1629af169ff790ffe40bacbe7aa6955ea2ddcd5b2d6a044f284928b593b8aacdfe3f1b31a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b2467f3f48fc7134251cf907b5e7a57b609056cb19978c0604c8486d0438d8e168b9ff19362e38a3b68310f539ab500000000000000000000000000000000014416c058869f2d4a5442cd8685f19f13633c49aef172323298ad38d76cf09eededa763c36788080820f7442a15413f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e55bb920ca483fd5c5f711b474e556a775418bc831fdb3e943bcb4b76c8b3f42027694ce9b1c0ee238f916c9737e00000000000000000000000000000000001318ca785512c43d3784a022fca4b7099f7b8299bae58853614e33a12d999c05b33455236b43a6224005b3c1e5d348971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009790cb28041cabe0be0701727c26794e734278f55a1ed2ea3ba7c307fac67e8dbf3b8a2d809a779a4d46275cf8258650000000000000000000000000000000018056cbe6a8d9e3d9d04c9cf36d06a742c1e7d562562f4388bdf526f82728d18e7f660a3cd80589d456acc3e5cbca78d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001aea7b7b25605401b97be443fefd83b301a9e4be23619f6c605ef5732c203f5d148d15a6363592d867af51e80be179900000000000000000000000000000000030a1d6ca1591722ed1219c91a9aee13c65fd4560a309ed7402ea5bbed3608b34d6d09633b574c67aa7fee726cc2807e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c69e722338339dc3b0258a2cf2bce14157a797eb87b7a530db7b45b6a3685e7cc0248f5bc01831fb9b13d83253d2bbf0000000000000000000000000000000017433952a0f68767bc166232b2a87a17c36746f887c3b48f1b23309d74d9022329541fe95a3928df87786be45c29797f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cb2542b6544b75382e3c90be2f2431b54bde8a0aa795a778676290d9da6fd7482be1653a6f950a757be495fe9293b20000000000000000000000000000000019e13d09cc61578590f69d8d07906433d8abe3ba2b7e2d8751c9e4772f07835909b37ec599062cedb2ce0e5a5d5b72ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004511d6d12957eeefb2b5fe5846942961d7594c9817eacd126cd38ea6f156139e89b776fbeeda43358b6208e868f2c54000000000000000000000000000000000897fac3f14e30056bdfd8c55bb33a828cca3a2829e1081d149aa070c5dc660242dcc8f6e2986040fff0a8cfb9d9af2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001820425766eb7299084718610003e004db530f0622ba87fa7c99134193f796d4908c47ee67802ee55f5d019f11f3d5b6000000000000000000000000000000000a5fb62dbb1e1a76ae29c52a31cecb238ce198da83c8a25baff5ed989fc015d7f60b4aafc46b417a08778a5e9626b06c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092e2aa894c251b01f271051976c9b1add7d0852c1932f3e1004563a5f93c731bf2af74639926d9fb58351e6ec4b4a15000000000000000000000000000000000077a5ba7f61e50aed4b2350e598fdbc3be601d783d70bc5473f6f22610c76d48039ba03a03d1815a5e2c590645198941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3c241df6f8f7e09352ae002a36abdb9e870fc5b9e267dbd153bee62cb14c68cc68d78c64fe4b50e501aa8a096471b80000000000000000000000000000000002f92e1cce872bccd2374c4aa65a2d89cd9d695ee23a67951d3267aacfaf7920ed6eae1a4b4a6bcd2f28993491cf9ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f71d6ce835ce03d37853b83b14f5281c9766e2ca3b5eac565280fbd7e70ed1b12e290111fcd1e022c42427b58c75af00000000000000000000000000000000158e6aae0d7c22d2e052645361f19a60dfccd1434b1c5b40d7e56f7b17af05bafcd7909e11800c0c52813933a837b3d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce5573df58e74e4a84389d51a4e237af66ac7881f552a1a8a2338e3655f3adcba0be5e62158d8d6bb94d60d3a28a0d3000000000000000000000000000000000d4f196ecf6de0943b19551ad6c6dd4c9f34708b32cc2a85fc976b92cbc77fb306d0326241b57993869cb3c1b0efc3641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c41fb0b59196ff64eb4ee8a0234c41b4ac5b8930a9bb3a592cdc90726ed53eca6323d1411489bf8a1cf4cfa4f5bdcc00000000000000000000000000000000074f90a824480e2eeaa12e5166f2b78e5d21af3582fa002735fcd2c8279902a2aa94f288c91e614ed48148d66eafdbfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bf2d9fc2e1d3de9e445e15e1711f20f8b018b69aa2a403a6aacbc8c4a602d61630c7bbdb9eed38d01080282804d4d6000000000000000000000000000000000922730482a894099e6af64d6c80f0a2ca3de8737aa263a827339b1332ebacac919eeb532e774b41db20503a47cfaaf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052bc9763bb2ea95aed30ed23a83f4720a0b63589221eada77ec42e12081506a545e6b79838320816a98a6cb08ffb6de0000000000000000000000000000000012d71b3409768e8e49ade25b3d1345404e856bce789c53e908bd2b7b55e5ce4983a3f5745ab4f3eef8072d4ad17565cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001732efc20f2b3db60f1a5253bfd181b1bc266e028fddf8665c1edad8282f16f9d7e0491e58c4e9cbb9e6c09c1b11246800000000000000000000000000000000005e4e5c614a7b042e023419646b42b6f04796e886b4f06750c968ab05304835c8fe6dcd1a0046acc80b1c7c645007b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ac487643a5da96b8607ff1575d92915b7e858a5b8fef6421c7bcbbc38515e22aa997524b9d2e180c61c2b4decf836700000000000000000000000000000000155149cc3e5446bc94be31b9c244f43eb21bb47d241f9c7985a2817c232577c89405f941ab48bea49d5538cde6c18a8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006744c53a65ed278e0d4ca62f51c669cfb4dfbdd8c9d3638c5117507e29c0b86e25c0fa34465dabf88fae9be8233f3d000000000000000000000000000000000889bfb4c1b7711169f48f13363b56c7c05d59833426c55a4b113eed935c24d09cf36c422aafc74aec0e42ce424f85551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ad5ffe584e1b6c80c7b2831af2010632326c01c8a3fe557d811d62ec8e60e8bb3c0a3987318203fb04b875af191690000000000000000000000000000000007c597142950f74993a7d6c98cfca3eaebd114809e4147793a411512a2baad1467bc6a9cc243d14f0b24835f310e08f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dba08466e1fa7044051b39ab27fb8b539715e3b0f6b358ed56ecbbb37bb53868c5ece6955c54cb843919ec21ff85d79000000000000000000000000000000000c334083404bd54fc3f279f8459da64a0e48b9ff07f0e2d17500062be83e93bdba295994a14fd474808de382b7ed49081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190eb09f200ccd147325a99a21aa51f09c15009b77284e801a77cc9611b4cc5940ec02d4268a00335c83a42cea21bfab00000000000000000000000000000000095c541544bfe68220b7b90165e5aa37d4793d3f9f641294228e8d5f1538e00fa10b455d70dfc344178b2392fb29b6e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000039dcfdd7a79b079364d47f2e010619983a1ecb3e9d6a043639a9b6b4aebcd1a086fa1869cda235c1474b407664af1a000000000000000000000000000000001015ca6303a8c3d6b057a170c1b4705ad2847959d5e9116ac3f67869dbd3eb7218b8fa483d3ab8296cd3ac10377333701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000508e67598c62dc72a4b0d14c2535286921a68021612cef91479b5f75b83612703e48d7c6aeb02575c3a06f179d771930000000000000000000000000000000016b354b9b6fbb5ab0d7939656303d374723d38afd571e82515f9d90e56d98fa13bb1b43eab48b4b9cdb6423f6c2af7331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a9455de4c4992cdbd93a7f83c065780f74432f6895c115a56eb0fb7641e7030284b1272da5ceea76b1b431d735572d00000000000000000000000000000000167112f9989876e7e330d787567fc60166bcf07f7dc61b766faa77e482e30d77dfad55464471ed8066876ff6096196a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148d72c843c0020a3d133a2cabd72cb0c5cff034932771a1f6670ef899aee71082bf936d1a096b1aa6f2bae13fd8ddcd0000000000000000000000000000000014b6bad54788ac7266223c2b9ac937206893583773fef15ec577a7d7bafed2602517e28f022ab9f1c2db43a3f51d073a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a50fe66ecf34da20fe032554072aef37baa39fa2f520015d5fbe7143bd763b424fa3fe922e5550f089430f74037774d000000000000000000000000000000001555aac1245461e814141b40c557f534d2de501ee4f06d400963316b19861736ee13b5363ade5fdf27e6bafb579e370c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c7b095d3a1e6b3fea0d860562163a7ae6391d2cf521a63c348f8287867b199d4126ab6f4dbb91cc2764ee97faa8365000000000000000000000000000000001397ebf9215bbcfd0e9ca49524c2df3fa89c3e946d506466ab2f8431ec4811ca1b518b78ae863f4b8667e8497a6a78591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066724daf7ef48974888c75ac6019116d1b812e70e77d3417a51c3d9eb24ac7a49c91cfb965c4338acad5653854babc10000000000000000000000000000000009fbb2ed47f57764dff9ce82fa5293ee1801eb342989d90a9a83914ccbe93428935a99c8458f1ff11d04bfc46875e2271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084473855aefd9b7cb72da9f07c0f4bc3188fb5b40fa3abf9f634933671fed7177f534e695d2b401a3bcb7023cf99652000000000000000000000000000000001155dbcd3a00368094ad6b1bc5ea0647584de379696c951344b7bd217e526c650fc3be6e91a4056fb6cad0937d45ea9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009732c3cc883c6b3dfa8b1508ac4b84e9dc8c3c43bb553df50bbc41eee68a5ddc7139d67c732e5f15c860cf351965984000000000000000000000000000000001586488d5d64aa01c2ab118ff2c67879f0cec5375795bb4d2761f1985c041cf5b8a8563a6e84e80d2145feb26e91e26b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167d96e204acaaf22c3100d2f50fcbe513194494b05bf277e3664f27a21aa3e70b4bc0c33c84ae6b213feb9d16794128000000000000000000000000000000000dff734764ec3982682d93a30c85bcff701b11babb2c9d9c7b714a4fba143809afe9b8cd6f2df4931979c6cde932d7b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f14d43fc67e0dca75b6f006bbf771ad42cd2968f2954755cba4e5809e82c3a6d1ff4fc416275805e93ea279287a0b800000000000000000000000000000000183a66df5d298123037f364466f0bb7bdec5507a9156925fd5f0f9b0e2040963af6daab3099b8c424a9f3466e336f3de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001621fd0e3600b2ab7824f4654c61a520cbe6a434df8c83f7e9f6537e1d7933d4de3ca943135ef96186bf4e2e720291000000000000000000000000000000000004299081fb08e700c8c268b6f0ab53268672612607847cb63129331cd9b43034dfd7e2f61ca80a200688e222b1774c721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c3a902cee2d059f0bfbd7c7d02d1cc58b2f08abf7436b1e26f369b3961d1889abee6f7415b52c9f892a95a317003500000000000000000000000000000000000496d5de982c7e0bea906268cc06092f950581f279737e8525d9addde0dc4cbb877e84dd632309a79893b9038a28b571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000640aa86a5b5d9a7cf5ed4ff40b31e051166b6a90483aab0f70ef51ff0e4dfdf7263e2c504677fb267535b15d095061700000000000000000000000000000000151404159be04aca0dfc823c4d241bb3563f63c949f19f89a24ee0d2d7927006ea68a05faafb32fe575d6ed3790212501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bca8cce3d7a8d2c3f7083910f81573b9fbb3327d953da3acb22c5ae06064d1824d5b23086116ef2767d32e391802ad00000000000000000000000000000000090a9220cbcc223a009ffefdc0a98598ce8afc6767e2a9a676e5ade17fb80128999f027adadd4aa158cff0a4b7e6a23e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bec82d9e44d54e252466ea0d8c15b535d5585d9cf820dff34df8fc76d347d70c0b908abdc9b2a22ced8c27277b5285e000000000000000000000000000000001287cdb054ad242d37a6377563ca31adad01512cd6d77f3776a07f2461ad6592f65285642c631f2050d0ddf8205c7bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012908d6b002971dfe3786868971471376dbdd906acd70f8f8c180da843db18af1f44aa29725c38b9e473f1f8e4efe5ef0000000000000000000000000000000003196c4d418bfe27b313899bdb2a2223f78b30d29b4eb280d64c8783cd7092ace845538e2431d0016805d04c0dcc77ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155209159a323faa6a0069dd056dd592ee0f78db4cca0f4b8732808f783956ab58b6816c8b6a2132ff67263501cedc56000000000000000000000000000000000f730e8099ed98e33815ef71333eb19b0bc636e8c094c12e2cdc8371b9856658bee4e33b0994396ca620e86e725e190e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012883f777d8939f935950a3ae398776df7980738a2989ad5640b68ead4261b5897a4c8bafcc1433cac34852e1a2cad7700000000000000000000000000000000001602fdfceb8d8ed6ca0407cb0f3704a82fbf40be03cc94a7a1edc501beea9a55e4ac2559af7a8a53bfcdad27e308cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b1db50e936cb7c58958f0d03887498d7b22d8859b9c124af2099fdbe532a1bc9f2e0ae15b1c818245827db92b89b180000000000000000000000000000000002c4fe8f2e4b61982dcbf9947256b60cf70263b1dd9c938fa05d8b8c008514f1a9d25ec81cfb1e789abeb361e18aab7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029812bd255aa73c4bc0a42569fcc1ef020863c5fd759712b6b511b18af77a1654ea726892e8acfe31ac9ab1e3a29780000000000000000000000000000000000b9d893e3d0419df8de432f78ff85d312d5c57a0ac4202d21befc45e04697d5bd0e3fa392c20d0916625708f70e7971c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c1bc99d288a7e3412eb70044304281e4753bbd2027be6e7f940a18ef6d71498a4ab7e071ddbc29a7c970369ab27af3000000000000000000000000000000000e11eca8070accd00eb0b304feb0e468d9027da20309f816ead0aac8180f53cda69fa87d9d86f6196b00514e721d437d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074495b3df8ad3b9063264bdf7752ae685cec7ee44943a14bab214da89bb98d1ad436144a38fbfbbec43cfa51439299d000000000000000000000000000000000533228056ade0424e4c291515fedd17f209f15df17dc29e312a6cfcfdc16d0f53efc91c17c01b8d8acc0d87ad020a5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8fee45d7312a66824ac2c6e2861860edbe7bb6be46c4934274c2eb87ccf579badbd1adbf3f45832983f91618fadfb8000000000000000000000000000000000e12e5a68ff42f08b467aca7c46b09b5e851fc2a2f6550fcdf556e0d960624f3e6f47735d364462845fef0ffda620f061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000379647160c7c4216b165551212eb8485687617af4769bc45151e1debe1651c05919d3b187fc5bac6eafe31b94475bc400000000000000000000000000000000082f0bfa32423848436deff7aa74d8ff936d26519769292a952d5e174e0774f873db2bf14ebdf1669c2363ba2ae12b7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b33320ca860c9c944d41530063132500ffa31d7a034e51d492445293315516e3e1fdcfe85590c347c71a74d6d205e61000000000000000000000000000000000e623b19e08a1c1ec1307d6599c964dd38d844e89f0931e8600fcfc5a2d25ea2edf88b9699214f527d15ab39c5b0ecc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dde052dcb1a0b8f385964c0c0686a8dd0a449b2ebc8ccb838008bc6a3e900c21dcc8af7009ff75028e461c06be4e760000000000000000000000000000000004d5a2d7866d81faf9070ed1430fce11447aba3ad12a5c6ee55a7959a324e1a173dff25c6408c758b9e6f9cf3cd1c22e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001482eaebf0c2906ed95f3ebd738e3013b3db0e5dc886a86ee720f17fb134d436ffd9cd92e39704d8f5bfb71e5f658162000000000000000000000000000000000666ec20a6ea1039ced4d5cc226ccca0b60df10c4b1c01ca641fb3d88e4a23554e4fb4a5ee0b74e97fdacc812f1dd2f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f52bca441c27802ab3b32cf68be9aade0011ec89a60d486d90c8bfb73e59d632a83cd93fe20ebaa2ab6a42d4359c90400000000000000000000000000000000016f96f62ceac74b2e3c8f3e274cdd57a5ead5bdf3915dd4f9e09e3518d14e4c14f227c1d1fdccf43916e03d207930a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ee3e0b56bc6f872c624d01bc4ed0fc28a2be32bfe7b2c9ac604805371df72eab49601cd5c6475063e177e9a4a92f6a0000000000000000000000000000000005ffa850d0b6baa605ca6579f2f9acc6134fab0bfa34f0f89d8ebef5287b505e298f139f06789fde5ec6b0837fb138491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a7828faac68084ef41e989b968f235f2b5555ac2cf92758afecf2ae0c74fd546c5eddce5f0f4cd0c3daf700ac1b25f00000000000000000000000000000000056bf8aa92d99ec5bda529e018d860b64efef75516a48bd19e911934f2db96f4106b57e7296b37c05ab84ce418ef6af71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007784d7e0aff950dace1712233d6510b4dc434cc1ecda1084a2083048bc2b391fc13353ec4c7f0e8c4c286966704eb6b0000000000000000000000000000000007e1c59969cce5fd3bd8a63877c5b099b046a9e775171687d93947242c5850f4be964242f4f9ea5c155e7ddffcd134651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffec8532175ee307f53b12051ba4c2afb18a79b37237e64b46692a9fcf69565254389f3bff9cb278b51feaa7062a85400000000000000000000000000000000130b15555bbbe751af34c7d9e330c9fb226b6b8b68072e097cb973ed5c2b25b129eedcdb4950e8382dde4b54eb550e841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084ab9008e4824899281e6846c523853c023a5c9b51d68b6a0a55a63d368fcbbaea9a35068d3315670770135bf5a372f000000000000000000000000000000000d2881943108c81a20491164340b74c6ffd01e49451671d48d7b16f465af83658c203ed1f05d9d0271fc4a831b0ec2b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a808e62c6c7deb6442b8663e52019d468a7979458dc433b88e9d5d0c50668a9fc6c212c70606202a2e46d9ca763ff4000000000000000000000000000000000c711d9a3f57df0a7966153b5fbfa6b3c1d58cb6d7e21337af41c3ca8b6612fc312b632f5f46c1254dc450d524d0c1cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000138ad3ebe1812c46acf97e12977d95bea6e6cd44b0b839c3d2a194b0d2bc0270abc1155f34b3dd9567ea493c8205fe5000000000000000000000000000000000ecc2dea430e6cb904e65a96d0ad5630a6bbf95d017c7c8ae2ff16d23501a6e9a7aece5191f6b20cd33276b481cb542a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181c4dedbc3766b06f7a6d555d86eea8864c4ad3c69317f719796b7b82ed806824633d42a1685249b8ecbd200b3b75fb000000000000000000000000000000000eeb784a270e7e827bb482f71fc641c00ea14bf7c3e8605222dc76911ebf6d6f4bf123cf89e6bdea2b268b159843c6e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd2cfe21201c40463e9805a1dab64f052faddff1014b10ab63946474ab98441cbb9398e1937583247d3415582e8d97b000000000000000000000000000000001378d334d571ce0eec0174b44e919e3a996cb706933c7314099b37b4375f22e03816ed8ca113e443d1fd969ee113015e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d760e4686f4b190a56cac0458c8f91a7ec74645a3d39f241c830a7842cfa5a3709cec89720f4fb50ac11fb810d0776000000000000000000000000000000000f80a3645bd1fa58a2965e5eab2cebe441c4305fc9b220cc10015d10bf3373ffc880cfefa374847fce253ff85fecfd0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d27c90c6a2dd4314e7587bf2d5181a6aa3025899d2fb32b1d5a34ab9faf9cdd632801db12a3ef1c4beb685a2ac81ad00000000000000000000000000000000028efb802c771144dab499069d221183d2404406956192ef160fc910df531f48c12c55535110efa5c3790e9aa92a0b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce248aa7c959bb492c36fd8c4cbfbdc8cdde00aa92d5f5db4e83a7436c9180940c5ed5ad52adb098976a8aaa667d2130000000000000000000000000000000010ca59e855f27bfbdd0fbb79deaa388fc8a9f01dd23908c6178b6144d3ea3903af220c2d84418f544964105ee29ca4d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a36758e69c8dedee5f2e79d42ba974c471421b7680d7595d9c8d13be9560a90075a40b766a76b745020bff8677b71cd00000000000000000000000000000000008193a2b48ad95b4b90943feb9f964a31a1273c5779d645d057376127c17d00bc446683e4f6ece9ea94ee6990d84a441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a772bcbf2b2177aa472b6ac24680c6dc02a91a19ece19d44c4786cc823977747714be750c813672cab3ecf9f2ab995a0000000000000000000000000000000016355213a3a0b2f42f423e2df016fdb8f7944f3ff86113388f304003cad28a5a4f3b5898f0d9c1786c09fbd0deeffd731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9b098a732f22c01f3ce078b5343e3768b99c82be3824c71d45ecaeac03ee01c0228312e34de13b81b942e60d78bdc9000000000000000000000000000000000867b037fabf1a97b7470781a56c6f4a9650bca3fb8588553f11ed5aeeed240bfcc5088588f5aa255389ff8fdacc83111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f3bc7614c67b2211b6b016156e9093d88c7141fd8837d42972d6db2fdd6257c8f9511e8b03960b514909607a3a40f10000000000000000000000000000000003e40d7311d9bfcef8fa02fd53758a25119d782ae4168603e852c8f65f12150269a54b925971dac84bb9ce626d090aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000165b971dfc4053ae2a36920313ef41a96ddc16ff57882666b1e6d26962f100fb46e540ebc6b9bb62da981c790bd76c70000000000000000000000000000000003ee86e515a8d8369ab529c8fe48c4ae97132a7db12710fc0e64a10991eb9f25b82b51173784f74c0b4f4b3b9d0cbfa31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e8e3f7d640a83910617b77ac7ceff3c7e71aa23d4bc4e8c71a3a46a4be08011bf3aa60188de4fdea03e6166a3015e30000000000000000000000000000000005763820a6d80fca5a91f8d41a71d4ba9dc6d46320c81a30203a485f084f11387b7d0fc6d0614b5123f28188cff12b061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097529cca8428b4027146f8df3a24c6f34b35101df16de022a2b509280c6a98139fc064d55bf4fb0ff56aab58e1e73af0000000000000000000000000000000006c4d337cea53f3dfa8044afcde803bd7f31f8531144e6683d354002374f935c2a8dce5a62492d911287cc87b70c35501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ee9cca3597ccfa5708ef6f4fc19f1fe962e54dabb6a4920abd2da8715a9c3da1a4a90b43a76e05798c1a8f0443a28000000000000000000000000000000000072dc1f70a35151f25ca6ecee9a7389582d57d7848babe64a3f0a87e35c16731c44fe6825376cff3b05dbc9645c071cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b2582e245171a73f5d8fbfeb773b4657073d1ed0c71bfeb50596cbb7b8b8b4902ec05546a99a7ad79a9cc1d1d3d2b7000000000000000000000000000000001804f2ce3fc8d22fe7a9b312cde7b5241c8387dbdd55aa0d099afd4eab6d2e854690354bfc6715bf3167c816de48fa871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004395b8560c2e00ebbfc6b926212f0278627ededab6f01c76469396920493f09a2eab43daeebe3e16f44f4510274dcc40000000000000000000000000000000011ec96a5dbb04a016f4907b1ea61db8691266ef0ba236d550d439f3a4f86d4968a0e82f81bc626d59ecdb3ca343cf48f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001209b761662df407da587c4edd21cba2490d08302e6a5d3e479cbd0858c5e8e8d887313f72f888598ff6292da6bfe089000000000000000000000000000000001480e2ceab346280b34cd55fb47a88735ec04da209a467dc2f0dedae6fe51d5504081671db0f70941b8cbada39a245951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000986483635879c384c59451b376efeb3c83dbb6ebfeeb62466d428dd6bbd859ea6c92f07ab29a4a888428b5ad2d702370000000000000000000000000000000010c0902330a6f82c505e2c38965f1b5d63b0935cf024fd66d4e80761fbb48361dec6c9047f28ece9cd7c819817a8dad51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfb976ad352224958f5f042c78d095ddf4d672023efbe37a6e716b1cefd2ab0c8f1ab01895ff446f5b44cb716615d2800000000000000000000000000000000153a5bfa1ee5d2ea594fe2544ba3de9256c54dddb2f370bf7eade51e3b32334be1bcd09017dbfe751c3fd5ab13c839f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161a74ec8f0ff654dda4a25e2027252bd1a24228d05a0293f47560d68144dbbbc28011f6d078e458dc9be23b04b07351000000000000000000000000000000000e792f731289b71bd0d6f2983864a0534e994d264d614b3a3c0ccefba8e6c44c46c8be2eb43f92442a4c2ea1c106717b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe530b6c4ae5d3df6de260cddda9ffe26f0d5416c5baad987e80dbdb855de7abb1c42ae175f0a253ec99d5b6c311070000000000000000000000000000000016abc877a6e3d2baa98304ac7c3e7266dc2649ce1b7b406f79d482825da75a16df10f77cf3d3384b32573013d4a0a60e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdfb6fd591b298cadc76b7bf4877c6770edb6e119054e215293612119684d7eadc0960c9d8691e915e20def924aecef000000000000000000000000000000000f3c4b1418c4c666ffd69c3e27ea472934f1e1bae19da058a42bfaf3a9d23eb683b698e49a61406014fbf368dd5284661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002bc8f2bbd4bf1035b5d17849b2a499ef993c89725480b29235ab9baec44db18f099d52c98f75b431ef4b8c6a24e1360000000000000000000000000000000005c974be50f8f7619a382c599742ccec24a7fd758ce0c9ea3893e0ad0e22e0170ce1ac953aafc182c9c6b7d223e39b651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065de5ddc6dc276cbfbda7b25c5f324fe0b517c3df9d98755dad204a30c237c81c39aa72ea6e0f97b62547feefda07b40000000000000000000000000000000004e25761c473435262717e08a8edd35cb8222371537300ccb67193f063ed2386772112bb9ae20ebcdc892dbac650de4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d480fd74b34d4716aae1cc1ae806672231e58ee0e826f3fbc32e347bc446feac7406b61e739f22aa64e1f996ebafa1000000000000000000000000000000001469e9b5e1e890f3d9c7675d1c6fd3139a28d128d600e083e1e64112b35fe28dbc5a088bfc218c322488fad9d5d2f5b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001e31efd85acc5e94dbc3afee2034d81c28ea900d683100fb0bbedcbd4443530c1d5f4a5f366db4cfdb4dd9487e220c0000000000000000000000000000000002cd4bd9f642ffeb43546fb021133bd3f28e1f05241b84e27afb188562a4e2fed7f8b1512f33ff7843880b0450895a221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001561b9db57311fe2dc1de21cca11bb2ebe093fbde1e3bcd73ee6477fe467ec15e3afa67bc9100576671eb2126c2b41a5000000000000000000000000000000000f77f858ca649fae56cae1eace26ddfea4cc8eedd488f5342b0fdf2ef2749a4e71b1c618fb8c45d6367c1e9f65fcd3561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000003d50e15fc0c401adc387297a9086557c347f1aee6a96d7585f59eb80c1ba9048e63c5a5f3dbe769ddcf751bbde7240000000000000000000000000000000000a5b9f0ef77c8b4c5f2a15fa0d1ac7217fc19330180fab5cb6aca99f09712133493611633de9b4c606bfe0a0ee843001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dab424af569549f6d528820c0e6352fd2e43cc9427ac7e4db443eecf6907ee7fefc90d1eff203915da95b9d2af05c1d000000000000000000000000000000001106138a9306b5726c15d4742c5db785c7356aeb066e7ac9ed1d541ce862a560deac14f678f68d63f97194b810180c351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e57bab83500bd04ab1af8aad47d15c10454388e6b986bd68f368ca297541b0928ada2b64b1aedeaa92e8a9d8af9ce40000000000000000000000000000000011552292080a882f6dfb2353c6f83e559eac74e63c0f6ee75c1d16305992d6cd4e3dc47b4a83a95ed45f0f386be69c361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067ca607547edd63c6e045feb31686bb8c411272675ad576ac27c75c689fbbaa9ae50d117e15f70b71cd3adb8418edd3000000000000000000000000000000000ba660b6cdf7f49490ae0631478d02e310a987021486f0a8fe47139de8eb0f332468bdb321d8f6495b703313dc4260111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171e918d61e3f339fbf71b17570e25dbb925e3be0810ec566c4f680d044bb142b5a111dacdf73ff7f9b561df80fdf0ce000000000000000000000000000000000f66960f7a6fbaedd2450653db1ba3a3a0cb8af09958a7d3da6a5b8cf5f57d086ae7bd2c539aaf107360610a5977f4271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010cb86079a6b4b1cdb118b5ba2e24e8a61efe1014899fe09285c63fa167d9f7d6647848d9cdaf6d4d93bbae4889877c5000000000000000000000000000000000744bca0f63f4fde72a732aae6845f874012ef9a5538792a00561897ba06520a9b5fedc111279e78d989f729b3cf29eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001767504df0275ccec33f188bfc5f0388091b10c599f07e847e41891af2f2c256becf1253ab9a82f3f32770eb20c82dc900000000000000000000000000000000167ef787378466d427036a3eff27068a83d59bcf0c89fd946266ceddc12c11ac02cdd8e1f36b04f2f65a238a9d5a91df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccc57ff7868adf545760571148e2054934cf1185426110d2ae9aa2cf1e6268156191ea9c3cf890bd71a47f109128e7100000000000000000000000000000000018663175deaea4280d108f37e8cdbccab129448e88fc839051dcabc42451c88d29afefb6065083661ba6103e5ba71591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160174e603c366a1594410bf0c74fd8db53bf6e56f3a83b4d97cf5f361223cc6dfeb8143492534ed7bb0eea34422693f0000000000000000000000000000000009b557b469eeeaa719260a561e6cf7d5f4284cc1ebe83e368248d35af6f3288ee61ef476aeab342ffacbd5f572bf254e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d63e719127804e893cca5b5994a73fada4fbf82499502964ef1f22dc3980531c763155642e4ba290a484e48190b007e000000000000000000000000000000000c9275ce5d8a3965afb2efff41ea0678966524a7d1a92dcdaf6f6b1f564f1f346b74b5bac5bc64b8dc8f679cc073789c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea7eba93cd7dbb7be019f5af45689d34bfa2033e784bd00e10a7d189f79feb68f3097dbdcdcfb7d6f5341b0e1b155ee00000000000000000000000000000000082480ef6e25e8dea79aa76c80b9cbc7f1f34cf386c8696c0c0977d0a03ae4c63ff50bbf6f93cfe2f439ac00a1fad73c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177fa7edf5c1c655217b63b50dedc5378d0596530f176432538023c3a0b3b1daa3127aee15b36bdc9288f26c45dcdc6600000000000000000000000000000000110332e5f99e3b23a4d7b2119dad3af369cc5c40268752539190fd6f8962072116e443d9d8bdd1b11e8ec24fb9d971ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5ac4358df16489ce839025e95d330a32afe30666f99394449205c71a9cd684928d3ba19856e39505847402047b86b5000000000000000000000000000000000b8b750c134b442eb82bd71846d65c34cfa765dfee1eecf8779d3f1fbbb93d676300dd0445b5ef0d708066fdcaa1bbae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107febb6ee7c01ca7b8b5ef771c7c1dab6fa5b32e9089d0ace6079434a3c7b3287bc86fba47223700cf4843646f75d01000000000000000000000000000000001192e23794dc2690d725ac29a5f80fcc528a5dd1502d9c5a9cfcee89d65a970c2b71651743f2b8bd2680598a1ddd6aaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e819477da151c76d988c4a75da912b33bfcb480ea191911d711fe4d71b165f113b55cbe3dfdbdc650b3239dae61ea50000000000000000000000000000000008d5f335edbe9ba3a6ff1b8a6b7cdfdfcd54d55e6744b0ff8fad564326b38021aa4e6d4d4db1c05d11fd76c51e5b90b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008295bb3ab4d47a93ac284f70ac8033975f47c354f206bcd171bd9cd3fea84e1714b73d59ad4a34fbc5224a38dc4822c0000000000000000000000000000000016755f7440bdaa84d68109fb55ebd9f6ebb71c81c8dad90f585d393e1f9c114163a4de3c198f5660d0d2d8e2c8f66e9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001270375d304a5caca51357a7f81912d907d3333724ed4c3ddd038d8dfca308a7e534858a603ed08fce84f43cddd64e27000000000000000000000000000000000590a639f93e377b1b8123ae68c6da7229f479e38451d34e25ebca127d6253600bc59e41555ebe08f997ee45f2b5c87c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019625b00530ad0a7bee5a2a0b546ff59100ea45e9c4ade5d657f455beb867396c71044c646b4ef3de197a578ad43e4c200000000000000000000000000000000127509ae3dcc6554b767f179a92fc71854e2f4611696eb62000798c8d8e9088fb5eb2fb81c96ef8b5e96e065e3d02e091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afd7c2e944ea76134b6ccf20f1dee9b2964bfbe5fe3d9400b97c02aafc866d966586ec2f69a03afdddb37781b5e87ce00000000000000000000000000000000075514a486e8b6285a5956e5aab149596303b26058b4f1ff21516be5d01b648ad0b0d776977c5fa84e5fb16cae6526b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4979a0349d585fd87063f8ff7f5200e62e2e3f031cba9a11ebdf86520e10a51d17cfe9bfc7bc0e5bd0cccccb46a8ec000000000000000000000000000000000c47c030505dbe71d18052a43c900c7c80f427676f8a58ab7b080bca5b2ba9a4ec08c03488e057be49b03332bfae899d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a77b6fd25f61e605234b5acbb23706475a8818f6c3eabbd2e29250feaaf754b7a4f29fd1e9b1f371d7433d4a159fee400000000000000000000000000000000043d833c0426f052c5648eacf88116c20aaaa37a131cb2d282ee7eff437d4a14dc35c7c7623843e94e3daee27ea90aab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d1f77c8a597f9d3581e1ed06bfea5bc03de1de11dcf0eff928024e279d0212f810bf19acaf82791031119e33058193000000000000000000000000000000000bae6e9d1d2cf08f99d9b889e2d2dff9cca9218593d050b59b9797835bca446e57daeaeb79f02bb3b51f738ecefe87781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015de7fa8bceb9ae2b563b999b3cbbaacac43b4e77d8274fb7a46bcefce3c724573fc58dfe80b29a6d1659e4995bceb040000000000000000000000000000000002181736e09e18bbf383418e796613815ace04774d72f1c04d6761064bf1bd6c7cb41d90440e24e17a9a15b05fa7a32c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141498f37a372b19066352d4194844098660d0463b9e7cd673f6185b9329ad3356f0de916925db6b41087607484f5597000000000000000000000000000000000da1bd1932483eda4ce05a12f75d09266d5f9a1ec23d375d908f3531cf66839624f4bd6ff0cab075b47c3c09d586ba5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014941a2215eb0f711175eab098b6e7d419cbc7094cfcdbe22d65df3efc08a4125f00ea7da81727e7c3d19b7e6424fa660000000000000000000000000000000018b9898cf15de648b099eb29795e4a6b8fee7815823ffb2b02a5c3569e714ff933ce189d564f299b69bb526d6da8264f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001368f6530617e9fe7ab985a4bd6328b6d41b9c2f8dbd1cda3ac9116fcb6ae347082569b873c7733e8b4be5a4dbd484ee000000000000000000000000000000000d815277889bae7035ff6b94a619e3519ac63877e77af61b5bea747e553e63a75b362f13db077e9f8fcc5b0c7cecb10d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ee53df3e00e451f3e79ce22c12016e82c45bbca0571fd42cc91f42ea73e92e661d2b6c40f17ec587c5b25ccbd0b8f50000000000000000000000000000000001b12ba0c9b5147145d9108d00a3336a5e99535a97a0f33fb5ddbe20ea2e37180d83257b9aedf5ebcd69489c618d7c9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016483f851928becadd24df5e1c29cb7cb8f9b4608ee0106794466275f5a0c4250f949188543d22660343a44018c607ec00000000000000000000000000000000026028df9757edf3592272f31ee8ff496efbeedf5fe812df3d81b6b7a7cbfceb08ba2585a646d442c7bf47c4094abdd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004225bccd362b65cf423675ca72342e21f8fd0b39fd37009913cb31d650418e2dbf61c7c4d3634478813ef92382508a1000000000000000000000000000000000026fafc0cade13e6d0b974ce95f026d798b252af9b654acac2b186346907269e3e2b17d0a909a8d3ce7d93a8542b6111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014aa2fdb01e537178fffff81f9cb4d0b7fbff783c5300ef6c6cdc9229f800b214f75d85dca95f814822bbc60c8043caf0000000000000000000000000000000007862643d0f2b5a8c76118ddbd07c5f372f4e435be1953dcef7290959e4ffe8f9bdbf2b2c73e38269e6189877b86f2151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd24533521c65fd9472d5b761a1a8bb435d65976f19599d4b20352fb208a6aeed37e46333dda502a43b19d3796bd5e000000000000000000000000000000000157d2fe2c98a5a1abcffb55097dc7747f8b7c5c0c2396c426c99155fc48a5b95389a57dd6fe86138f6d47cda1fd07f4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa7762fc4910ce3865c79b9af7ec03a77fe0a37c63f8bc90f02cd8f7c57ceb6938c363c68c1628a3864861c6053e0fb000000000000000000000000000000000e11b34d529bac3a68f313f4e1ebe0ef3e4eba0832cd69caf398a1a821219266e81fe58b6fcba38ab11863c6c440d6f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b224603d40eb0dfaedcfecc6c27fa1e1111455276a1f2f8f9111aa5e5168474769e62219d7d99752fecb2f2268fa7060000000000000000000000000000000002c25b5facebecd99a9f6378352702ad959a033ba70727cf0ab7571eb2f1bd0bac186bd2db03b729d5c942a8e9f3f3d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005444c167598fc866718e4088671ed1b29a10c4172d4d7d2ec7e09ec896c0937dcc3fa0e2fa5413a813ab247572f9cb40000000000000000000000000000000007b4bfb0f3c3cb248709eb0d6da7a5856536920c22f294249399c1f551b84b8e2a323a9a16c08a79972e9444cf9d29411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7fe1b93783366021354f370dbcb20ca8287872989cc308c30023ff2088738d9cda2e9a9e368440d495d27ec7999860000000000000000000000000000000001606ac002dae9bbe6ac521d9ba07e6e54ff7441ddb5be6e71d8764f02f22f7b1e258758b0c44ba19c205add7b138a74c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154d45be3c664dadd1226ec88454fdaaa2ac10b9f9c046c9dbd5f6d77d2c684365a66f4602e3f7caf4ee6e536be8f5cf000000000000000000000000000000000f52d6324bd111063da6fdcfd4c9bde99a21fb0c1dbf50573416f625b1888d319eb9cf3671ef33b28d56523a67c0525c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109236a2f430dd436451539b9aabde6034f351c231ec06683dc280693e173729b74d8ea92d1a2ecd4c11fd8e68be94ab00000000000000000000000000000000119cf76a755d72a0773e87032414e8112de139df4612def0f55cc5d4d7439d76642b7907d4795e1b28b477f06df9378e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015044a4d4ab02f81022c9db3d0b1e1eddea7beee38e30b73ad802b42d191bde0ca656cee195c377ba07951b1b15de8bd00000000000000000000000000000000072fbc8fca0876ebc194c54243ec163757763fc66b1c70362b8b1c162dc9bda5894999373b65dc38989a425a0c284d1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c88cca6543024d61baf541dfbca6f48ef05b0bf8fbade4a81c6fc2969547a833bd05069228ee3cc1e6768319bff3580000000000000000000000000000000019d1cc3c83143b77ce1a20f48c5fe5bf687b104ec7b0b97f32acf83d46663903baf94e9b9124d09ca415148b76db43b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e0bf7f10be04b5dddf42f245d03144afe12e88948c3a974e3922016fee2657e8deaec7dde68c60cf8a5bb25df083450000000000000000000000000000000000edd46faf3945b0c1de820a8734da075b7d42e5aff88b568039001dd2009d6bb51400dbd90856bca8aaf16d0e8b0f4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a74ab8c578871bb746da95fce4383ddcbd959156127efc1bc4c68affd22641eb6ef769b940b5e75d7343ff8e59bb040000000000000000000000000000000014b7a57c54a64f8ec69f0d63f26216082448d94b6e7c818be7002250bf44f65e722039754f242dce1d4be908682369e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001538566e5b219404f1bc26b3861837b573c99398102d749aa88e1183b19463deb8070d433a12aeffd7e7bad0a25b75ca00000000000000000000000000000000118abc01e63983e0dccd5b7bd3574038ba300ce3be84bd1a9f62613eeb9f505d22b7f258798255c7db447ff21b54e5031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016280f6f4b4a457219687586b6add63aee7c7acb3857c563f37ee4070923ce6efdede605aa77e0b19e4178a0c55825640000000000000000000000000000000002e6bc54a025f75533e2106f95b549c5392d599385d0bea55b802b0af2ff2e80bcdfdb5921f289508debf770956ec7381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002529abd28cb1568fe810da3ff97eb78f2f7a62287daefa0b3ffe8a1bb8a7252d920ffdf9cb07022ff09fbcabfdee58200000000000000000000000000000000074002f6b87993cb8fe40289d125512a1ffd4ef5c7e20f9da64b0984fbb46e76210189ebc698e9dcaeefe0014b954e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176682241877385411d0121d2a18cc4b6bbd306ee1f23250c1bf1449e88473e3d4316f16bf816bf66aa5f32e0267a950000000000000000000000000000000000bb13bfc13195be19fd77e5443db47a3005a823a866237a6bee9407330a0acc8962efcaeb9a6fb1073506b35043c51381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f614bfb0d77ffb2981a1de0f640e8b2f206b45c3bc2e28b4a0c85dc94f318d982d6c0f0eba6ac15f9bb7ae005ac9f00000000000000000000000000000000004b6804cac754790b0ba4d2ed4157d5e33f34115694362e7d8b8ab4f05bc032fd230f2a70247b623389b6c5fadad56b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b9cd682b8d91dd87ad0436244e65ed502533c941bc4b15c22e9fc8208d2b1680b2c1d565ab8ac691ef8cb655bea1ec0000000000000000000000000000000013ea73ade23cd244c46f696aac40cceca8bdeab597f1eefd2a245bcc6814fe4d3b53df11f3ac9a42b5b857b4cbde76ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ba355da5f29072f1ce6556eb28117c291a5d8359c5d660d6dac032795247e6ab28227f604fa695b9af360ee1686c24000000000000000000000000000000000514827b0c2684cc83dfe4bb118c039e37eb3afe3bcf925f68d64ec6c87416caa9e76dcefb8e7714ace1c77c5bd577261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001916e0188c580c6da82b576c247bf026d5e1392d387b8cb6df4cea23dbb0b239cf44ea79dc5b69f3589929d93b8205010000000000000000000000000000000017fa7a6980d7bf80c02469fef3fdf99fdf112980919b171066e3aaed1d9811b351998701a198212521961fec1e7774551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000557a024b0b23b267aab806af84a6b27c8ff6732aaf1238271d502dae04fef430316cddec2ce0300f579554cbf507c6a000000000000000000000000000000000dea331dc85f67e917dab59e56d019a788277eb35fb26a30240c8fab661db14c3eb60fe4a1484d6223df1aa1fc8f6e8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ae2edfdc30e040c860bd8bdcfcafe7df509cf2077bd05c9d4ede461d3c9e6cdf9feae6092db944d98c3c14d8d7d3c00000000000000000000000000000000018d932487fc8f30e5c61e9fed02468a78878f1c64f3d98893b0f8c52e71ed175aad2302a4e41b43718b9ccaff0b410b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003eab3a07f5cd5d920e849d09337b6bf207817e97b62d23b2cf29826a7648c6ebc21db032a4e036dfb515665f809089f0000000000000000000000000000000008d24682976cf230ea65e08d0f3914b37f0c4c4fcf0178eecc4ff7414a2dc0b4c2192f85e33cc08eae5a313d46e8a57b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ad461daf75d97fb4a8df3eee66ad4f4d52ce7db447831e627f4bcbbc1af816a4fec85c29b917a01878a821697c332700000000000000000000000000000000158024acdd1c792066f52f56b0568584cb14a0f90f34c2d45f2865a42649c30d83210651e0127b1df198175ce27047ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6cad41b0f57af2f22761f8e724a7254250d88fc8a7712780919b6f89145541c8baa2ab8248d509bd391acbd4f34b7d000000000000000000000000000000000cfdf55a4707bf285fb728fef03a93d5aa15ee98c7367518c8462593a8911896f4e0d507b39e5467163e8f9c24a479ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097b42c25098c874f981add61f7d5535ef4bff8fcd7d976029f168d25c64416d8b6a25412ffb87bf0b20e7d82b43c7fc0000000000000000000000000000000019a13745bb270a798aa678b0b74c4b298c0586368fabb350f8cc791dd850706a42f2b26f62006ff5f08a3e864e635aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151bd296259eceb417c3fc4854639e42db5d2761fa2cb8e38bc5bff810ddf5cdc9b718525b643ea96cd53c75a0bf4bfe0000000000000000000000000000000016a156c0e5a87e06137724c3f8d42d07a69a667d29d3cb271aedca14527c28b8a92d3d057808ab4187fb8baff1608d461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003524700e29419913574479cc57b3b98f6ab23ad7763deddb53d8088c8c958011610debb575761a12d07ff0b6cc0fc3d0000000000000000000000000000000018d4f884b50e4118d718d6e90fd3e30150c89349fe78623f312a94b83560f6d5398bc17d898239bc3c1c3fd7d09becde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caad01fbbf719a9bd921defd9e68f6d61e676006c8b255c8f8186c79d5bd31587a6c7c53e8318615f7818ef4e1e293100000000000000000000000000000000143af413792337ac93809609910e305352473d818e82ec35e58dea271d0aeac44b75cc40cf7274abf48b31aeac1765ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df6da3d6a58eba74e9bbda1424de97fdb3b712809d4c6c1ce7fbaf92b88a46031543efa7afd29e588c3f3e64dd19e650000000000000000000000000000000013829e5628dc2892a064cbee1fab272d6601679243d74a7882f49f7d99e2418b9330bd638da2f4d42c05af50adfa5df81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139ee51f224bdeb7925540f79ec64c18f7a0adc888a7a8ca3b52e9a2e753d8b20fdfede311ac490b995bc67549209dd9000000000000000000000000000000000dd50b1136453ea9390f988eb38004636189433d9f21bab248a8afa291bd40993cd2a347c10f6a36697f0f03bc791a461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c1aa318cb330e66ab65935c8dff53ee393c4b313a39ee498d8b31970656f6ff9a88327ef03f37586ba7437e2f86ce1000000000000000000000000000000000f8b56f81a587bf020d05368022a54459087b9ce2a9f08d6f33dec1ad5b6a83a0db87c4353e7d553609a4fbb14a626011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066e25d11bcb49ea88e24030e35ac832445922146bb4052a282f7b038ec0751c230a4c51f8a48ac7627f636d2ea79d6100000000000000000000000000000000161eabf9cb16be07fd6039357899d1a708f34ff2e67d00d5944d0805b14bc8b68c87ea1bba1485936e23457c960388c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dfcd2068333404ae886686ad38a0815bfbbc15a15b7d336d946f234e72080fb8439901561b2d483cbbaf07d6f2ca0600000000000000000000000000000000107908de7e77f92219c83255f36385f157fb633fc0d6a0e33d3fe05cd3f7ed9371f0beac7664075e25eabf3a0fab03de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0bbe3d79643b4f7362a33f603e124259c8242c36e46d605b5f9b9c6453a0a1340dfb6f594d975f8ac3245d4f75f8960000000000000000000000000000000010c1323859a92acdc936d0665074bbaff149b6fe597fc6e9bdfe546ab7f7a16abfc8216b7e4033c3b23dabab84574b2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fe6bcf24d612628b7244f08731b4b111d21c2ed5a55e09fe226eb6ef17c32cca07d98173e6846b446cf652c6d5745100000000000000000000000000000000082468d3b741325ff23aca7e67f8635cfb305424b9707bf93e236a4e9f38f914e97e10263fe7885304bc52a2ea5748ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192b245ae5e8ca0a49b1671f6899122430aae5ea97781db40592874cb8f3cb9dae2f6de6644d4b9a3dd67faf6e80f9ad000000000000000000000000000000001291b8d2a0f27399dbd297593fb09c7510b2c86f2f130c565abefd1bda8c531edc7bbdfde907f1422a9ed71d05a8e2201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030ff7915fce335c6dce7a1addb67c3cef95205733d4dc00c449cbe674a339ab06ae017b3ee346428cd0d417dc4637cc000000000000000000000000000000000f818e978eaf89b99fa030f563fa82730d19815b1b229bd87739dc2a09f5bc975bbe2eac2a7be420485eafdb59740a5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ebfb93012319e55105060482abfbd936f72d7a21458cdf32da7422875a277e8372088cb2a0681c516dd1d182b6ef8c000000000000000000000000000000000794199bbd52aadffdfc593cf27462be8fdde9b36317f976a5a16b3b42129de7612b6e06df954945f2fc7a36e030bd431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7584da5ecb6e67240d5af65ebbbfb257c080b6bbda0e803a11d9d6ea7456611d6d19c9efc029d5faac9375e2c582b900000000000000000000000000000000118247e0f3d3b24a8b7e25a2cc35fbd76732a7ed63f85203083381dab82f8d2b08a80e576dfb89e0b0240131d5a3b5141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd15a4cc7cbf56844ee8dd963521eca7b30cb3a68b924bf7f9990c6336c8a81e30a4d799451fe180898a9a5a112561d0000000000000000000000000000000017c328b30266075142b7ecbcad3b9a1c57723e7b0d319e49d4679bbb0ad9ad408925ca5ba0ec3b6167a8c106b62cc5781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fed565b085aa69f74d53882868862c6c487b6f5d8b5aabc7758768b9e427d2630c9c943db28c9404227f9eda1e9698400000000000000000000000000000000152b36f7f0a26fff1b2536adef9271db799e9460f35d91cf6afb407d249a88092058bd791e85f4f4d92e95d8b53fdd091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d2da898b471acd292dc77fd2f986cefbde3879ccbba2907c25d87c4e30c80ad91878f7489f5bb95fb4d46e574a1b9600000000000000000000000000000000022c0ce5d5cdea7fcaaeda85382c695d57fb08953448118a6d0359d04af80fd85687f3e4fd928db0ce145e28923cb3ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbe99647fd155fb471450021182cc0b2a43abb4b3665c316f2b9cd922c2f1434f74aa700533e0d7a213b6f38f505549000000000000000000000000000000000a5daf098da498e17dbab98945b574e9ff779151b42715c4abbe9e6dec12815d6ec593cf22be59cfa855d081a09d0aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b312de236ac83b0cdbdf7b8629676348b5fcd56f9486c6a8529986fd3f490c87bf1bac96bf5cea4b144a62b20c411a00000000000000000000000000000000006c9a6bf77de583d8bfcba2c339e1f731a4f7b73efed715bd5a03ae20cf9221593e075fd4ea4af5346108250b7bcf531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141f281aa6fae698432632b2479bd54cc4b0ba599426775efaadaebdd56d906ad2463c6ea9bfa532a0b8cfc632c1f22a000000000000000000000000000000000e51d23d398e232c4bb9d10556df130e782cec4d1bbb0bd3296405117e9ab0bb8d4aafa9b7c1e706832ee1a922ab50a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df2ccc52c64e81bc27246d789747a6e208d07e879f93b4d93fb5c35f225fcac7ab80a725c2139d12ab799617350e793000000000000000000000000000000001114e4f01d74c81f08875015535e52493eefdfede8ed03392d06882ee73922bb930bda835bd40f7b1956328ea364405c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001095d433762c64e8eef7feca67c4f2fac4ff73d177123087bc1b695c9df9e4aba4697fade5785a9ba2c2459906a9d7870000000000000000000000000000000005225842d300934c97c5f82e5964b3cf1e1f05831e23bf96e0d4867843680c33915b41990ebc6d71fb976dd7b30b47c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f29b93d410dd7ba6c935e4686271c2abbdac185ecf7cc6c1826f9416d2cb77ea0497cdd1adf387eb72a7083304c69e000000000000000000000000000000000bc638439215f61ab6106b726125d22b6ba2d895af5879443bfe539aba0da005fa050df05985a042ce83f5a22d04a7241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4d662741daa14ff358c9eb48684e00d5160cb642fef1e5091a94e8553f504e56912cf86d483b6774461409713d69f8000000000000000000000000000000000b514d840864602efd0e0c7c17102e3dcc17c2f9c6939c187d5629a1796b00f1fd02622d58daffb493c94b5cf79068131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c68615cb39650f2ee35c9153c0a260a8f1daeb46cd102b5470a92b918ff4f484fd3f50ac4324588cee4975fe4c5686f0000000000000000000000000000000016a18030f49c2034a771d28ad4d525867cadf8a37662f4b28c1b3881556c342490d72e4d57f6d1271191c8e338bac9c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d8366c94afcff0792e31b7786d08177899b177b2cf49bc77bb846fae62b11032fef60f058a10466d668abdf436c130000000000000000000000000000000001ba0b06c6d3812f0c40c3bc2c5532eb14a957739eb7ed05987dcdb22f7b52a03955c2356240c58bb04cdcc2e0e975b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d0bb909c0f98721bbd0a9949d87e84e6cbebb93a832d320321fde1f1e2774e69a379c318d0f60547c357c228ddf8a00000000000000000000000000000000035131e801995f046cb90e9232c37de121541d2d3435a910e7937dd558326ec771bdbec2f65dea72ef6aa111eb2503231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000905c053e24816281a46d68e203d597a4fa3c234e0257ce069a16bdf6ef3078bbf2def1b47bf38e190860070b42f0745000000000000000000000000000000000d4a328fc86e1cecc72b3b773649eb5d08c03a27db631de89817ab4df8caa58b94cd6ec2a23d7c07a13a59783ca128331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085b4e19d8873ebabc7f89e4e8c3ac8e798cab339a1b7d9ab261e719713605d4ae3842e6d89e01e892ce82c44a3da69b0000000000000000000000000000000004a40dfb58ffa92d2639951c5d08bac4ff3f716e04f31acd29ba9af58daa60d2d0b8fe72c6361c7fc1d510aff39909021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0c8710c77b22b733e3b29d08e41b14a16bd61bfd9b015d6552080b2dca8482908cdb40c509ff94a23e3acadbb15db200000000000000000000000000000000190c6bd189e34d78456afc8e88942f0e5025bf33ed7ac0b709c7a6e4bb0eac96e9aae5dae4abfd18e1178805771862061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090a5c0e3323e1c6052061b48b5c818b7e35e93aaa1cb636b111ea616b2478d87f2592dea70cc0e73ea023a9e7d30e7400000000000000000000000000000000184164ecb8b9cad2a96bfaf9491cecc7be26f8dd6d93edba11368a1225f8c918b0110ed47b5dde3000094b54c0eba9c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f5553db67bc8df3a16fff2e8ebf2799c182ff790b953cf2c564754720f2218d9bfc5f0c3824f90e53272d362359f30000000000000000000000000000000000ef7615fb1aa63dae3f7386a37b4959f0aeb94eb4352bb463e72bc593f0554abded1148b119b6789c683cca53e159f571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149eea5cd1f67ae195fff9beaaaab6b60dad42a50ee46195527e2979d6ef0072cb02c6fcbba112c87110204c19da85ad0000000000000000000000000000000006eb91e83057a0ddff5f23e9b1c05dff534d0903e2aaf63aabbd779559112cce9ca71515d2955aedf53e0f84ee8270f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3df0ebe61fd0f3ff1c82a5d1f46a600c3e22a5b3be0cfcf09dfc38a0b8e6f199efdf0eb200badb8e78c44aab3e348e0000000000000000000000000000000000cfc4e93284ffa90482a2267a5b80be5b6d96d8114378d8034593b5fa054f0b1fb8aa1a1e9a0c55ec2d7b390d7505a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a7e86f0f19a6792d4a3755550b15ccb179b8551bf654ccf0be13a5f2a581c9d6bcc90494224e00caf7531966ac63c7000000000000000000000000000000000b92ba8ed18e31a9dc0c193f1eb33a570e4c09f204e453dd806b385c197139c8ab237781b2cd2e340f30d12f946a5abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012be2d05f7e439112b9caf67d305eaa9bf18c56442ec3e31d256d258f39ba10f7dfde4c1ef06daa2666dbc473d1c83b100000000000000000000000000000000180017de22f7bf27d25cd5048edc33de6a6112bca4557b43dac4a62f1347ce02285ca46158dc0ee2ca4e58e33968b17f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d01530e2b3758e5d7c1a7d6147c60f028cfc0e9769363fd41967ed47cfe58f45fd683b43f1342abf62ee4111d2a608a000000000000000000000000000000000072e55bdcda75f484352b0a5e6b6600b5e0db8d6c312e5d2cdca6aea10b36075b6362e65cddcee44fda5c9c3904e75f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5e0f7bc5aa1e4667b543b5aa5f67ad30fb4d312dbab4c47dab883c400717199a449a37f94e1aa84f548f165d7e017f000000000000000000000000000000000cc112b2ee9bd8adfa23db5e18c70b294fa48869f3524269c355894c3d4a5c6ae4ff38b6469194c9a2b34d224c5dc7a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106de6cd3c22859015ea2ebb966a6522eb79ffacee4022dd6b5282477b7227135fdf23112175090d818fd230cfce6c15000000000000000000000000000000000d344b613b8c4e854d67992afc41d213afe3a19e55a64f2dfe2039f1e4a5c416d17dec1c56e89261bafbfdd130f6887f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009782df7ff3f34944414ee90615641a7821c97542094607abc7f3dfab22b64a6d516707b8492373c45dde3bf2f5db93800000000000000000000000000000000169406ec0c21294604d99c1725902a13c872d1c3044fc2cc6092deebd18e0bffac7699ad8e289f344207f5877b385c271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011198cbeab130c5bdf760f6f094151b24e9ec64145ac0357ee48c5ccef380cc6a0fb58e207949a6f9be49ea1986774cc000000000000000000000000000000000b9136a902506fa01d15a44e8d471c51b004da3011785e41cea0670385fc352390e8325ca9e72da537a7bbbbaad00ba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae41dd6640679a332da47c1af423eabd0fe632b341d7bdecb755c82a4dd4b62b02a5df0224ed672c7c619bc626a6d3b000000000000000000000000000000000788240e7d611f7c485dc5b7d71b8a5f2c8917aee7c4a85bcb3e582a4c9a201f7bac99a9bbd2e34a7d5ef4a2b504879a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001696def9c320137916fd0b9b1b9d19ab244e58b605b031519c4310083d2552fb22a90ed6397f2d91324824aef2df04460000000000000000000000000000000003ec63070553e114ff2900c678aa29e0f9549f20e5da6455036771fcd74e66023d10a8d25373372733e603b54ede9fdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e640b74f26ddb8b588d13fb12183c5553327c75bfb782ce3f4a7dd3d742724d02131346f8492f19d2042ba39c958ede0000000000000000000000000000000003b4e0174717953dcc8442bca939c52a873431ea6b09fb65bf0d0a3b73913d0c390ae5aebff42067fd4ab31a7ba26ff41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001876fc58ba72b8e11095dabf9f4dbf968bdcd63716a07ec9b42fb229259e7126162ad0a3cdb7516ba5177411ac688f560000000000000000000000000000000017e9d8b35eb73a0a0a4156bbe417a71477fa63e69b51cebf2584b8faf94723ade364feab382c536ac1a0d24b3bbec3f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129ed9691b2e6ceec944878ae158920d1deb9136211546754dda802ce434c58174091eb91634588074db4ae991034860000000000000000000000000000000000ea71ba722ce7a2cdbac5df838065a2671ed0e2957c5bd26da8bd9480821508a4d40b307c3f6531ef815cfdd3277470e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfa4b48cbde7c8ec52282d70133d6ca0a91d2808d877e6aecff0cf5b9dde710ac066c08cd73d54b010b498147091565000000000000000000000000000000000eb67f4daaf92108d67461762da24f0d38f19cd30c4c00468d58c5cc258438b11d26044ebb17ea09d5548491239d02dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b728395ef8aa8e76d64ab8c3fe3c4c84c7453acf4fb6350ebd6dc261ecd4623d47e22e853d12ae0d763815639c61a5000000000000000000000000000000000d4d417bb7e668d9d365a86b85c0f0d4cc32e71f9821ab1beda614ac4e2f1c0ea03fb3ee93ab90a6347f03e540ea9b7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140466f0b33681a8b910a82b896d640583fed191678be5d732907199fb1c50225ad104d0a8a169bca7f2e0f4c2671ca5000000000000000000000000000000000e7d645aff38ca00f056ea179d7a429fc2725d8292b6d9c98dc9ae4bc45e01c8abbbe9c440901a8ee15cbd67542bd9361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f94eeafe1e3e73298943cfd105a2d63e05673b1ff3d7d26a01a4fcb42e878732ff04d70d3b02d04d44aaf1af4027b680000000000000000000000000000000014c52335866b9486b3fcf15f4058c4f52438593a0abf0cb8732343091e50c354076d813cccfd64c78eacf22cce358ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcb6e6510efa55b0524bd8acfbc22bd0850e4c59e57ff7fc8c07765c107125ca7866887150648914d0babb2135d5b97000000000000000000000000000000000ae4b76e47b0c9860e4d0e38c2491e37b2a3dc15beac38564b18dd39475f278690d0e9d2ce5ebfb306e7c7d4c61567a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001967cee7daddd5fc4d6ab943371ffc6cd17810a86c4acba42df60b23009dd03a9a6e8c7fd228dfed75926149bf777ba900000000000000000000000000000000185104ebed6c3f7021769f346a1ed3a371f2dfe0cb5aa30462a64a098fc96cb621f9b1ae89756592b3a71381295cd62b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c73305a7ffe40d128443ce2bf2c09b50334f6c6c9c157e4ee0651906e39925f7a5002504d9bae4a1b9403de1a87ad00000000000000000000000000000000005bb37ceb07b3f9d9e934e054dd23f9800c6b32ebfe9d7d367dd3e2c0ebfbe04be4e52c6ee170543972ab89c1747725f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051d13d5852b41df0072b099dffe4387cf70675fadfbf4dd0ba2037d6c2103e6c1982bb6f7f92b834c15522bb23259f10000000000000000000000000000000016dc4dcc3a2a7c470be10ad62b1cc867623e9e6cf463b0fa42bafca48c6052106b9e8934abbf7c0c83a2e6181f5dad9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f21d51822cf876b8f22b239c7ed3e1bdd08e8048b028a100cecd98ec91eb3f157b63b4e7c2a0d5b27f3fdc6917a9f8000000000000000000000000000000001978d4697130aac5700a57ac009cf5a0f6597df9fab7786a9d07e5b2294d7bac364677ace265e859e509142789f17b031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004977b41b70966e89cdddd3bdfd94c1c553b0f3fd0b079be877cfc02dee3e4ebee7c64fc90b735928967d02cd513bbce0000000000000000000000000000000012cdd6bcb7b917f9d9ee7506a167f5e5bc79585c8296d374c084e5b8cba293845d66e2a4425c30e60dd23c137667d95e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ebffb5d89a8e8176449a52f79676b8295711823f3cee7c2cb89df889618a0ff66c9cecbe7c36929519cad8892ac2210000000000000000000000000000000019d425a2b105257ab263f17529b0fbb89da61e4a52a183a46b550172e1d83b473ca74c49d067092a8dc1ffb0e11b77ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5f7eab7f3f9177c697e2b4cae8825480d5e45e57969c68332d73b1bfa04048521d43325a2dfa94d4cd26a55f4f86f40000000000000000000000000000000002336c19d198f8a6f9332463543a9cdb15c0c77b5184c16a8d2d22491a51e996398990ceaefdc6471292153c6bdeda611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c551c5feebfaf414b4648304d99e1b8d37d48e9f145c3d3201f32c7e9d2d89b00e3fe957e90a51b83a5e8d4fc31ceeb0000000000000000000000000000000019898130e4f9c445db004fba23124a1ee6ef52d3e80cd0600871484019a9382d2fe5ba1c702d98fdf453fb82b5687af01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f7599c089bdb7839433967ad2beae71d79e620c82cdb3443089f4e95e25ca5b69a0b32e762709db2eaace4daa9645a000000000000000000000000000000000d9ba27c416f49f9180ecc07c19f398f76b63a9734e3edcddf6815dc0a1dc87e0c5e24606dff575e650e6b6749fb04e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b319d7e9c2c41151470dcdeb437a4c55d0ade6263534e0ee3c389b663e6d2a01b707f8fcae2f7ef4435141ba2021a300000000000000000000000000000000065df37dd0fa2ea3ac47eea6878ef015fbe4d607c46abc5b4f90ba355b5d159c2d116218b0867eef96436c89d9500c331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d7ea2b47c08bc6f0308a40b9b04c3f1ad01b72d43b9e42d8113b9645109565315d9cfd9819d9043e598400614952d00000000000000000000000000000000007314cf838a5841da4a14200bd458b895b4a33bb474f0c84abc10330e538e220e6896e0180bb042de95c370ef52f8ee81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b3b06cc9d8e000397897ed3ea3e861cd1aed60a1df0da1c83cab35754f758022d25c7f33d036639a3b89c84109651a000000000000000000000000000000000d5cce8fd7835696e33376c3cf1d4aaa129fd5b352f90377a78748c0a917c6d05000253fa30a2f6ec95a109fe2d4bb291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c62345a6c810dd06ada4cdf46def7f872626ffe5bd9fc7f1975bc95b3ef6fce801374c4abe99ba63a1095be697a9c8000000000000000000000000000000000303e5d509395dbe0cbea3158cc291ae11ed24e4db81bd05c71d62f52857a80c10eb3d403b8a1bac175947b0010b3eac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e93b306f6915e80f8d44c4e72342aa97c1654a370e8f5f71b001257f69e5542030187e55bd3e72dfe344bd0d861b8b20000000000000000000000000000000012b8c04fcd4d759963aa80bda996a5addab2fc0c01c6da3619d00194854b46d6a5edbc4c6c3acfcf34f09721f769b3d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001087913294a69e7e8d383cae35f7dc81e15eab568c87fd5d0a0b645def5c7e9d936240a564966b2500f88fc1ddab3f25000000000000000000000000000000000258220e350aa832b764a28379b864763644c0d2baa5562cb1b22737f8df361c86c8d757fe9f298293de891edfe1aadb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001527cac4daf84915843f4aca14b8fe640fb4674b8efa7cd47b229347effdbfff4413fba4fb62837eb5e8e2ae9bef77d8000000000000000000000000000000000cbfd8ae00594dc9579a3415a3afa2c15adeb28fb9b76942875907843d32cf763908b1601070c3b053aeb2065ebc9ad71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c623c9aacbe26468e62c3e618dee67e276db94e0339e32faa1079d1adfaba6653897de0afec2b4758b63189b211fcf2000000000000000000000000000000000f85dca1ab2017ca545e4033d974e932a21b5f0152dc2154e1ce2365da4a33d2f8516a40499a52ee07e390336060cedf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000290d3c670a67da0fdb3af26f70a5c9119a330f715dca52557fe4dfc20c2a28a92e649bdf8850ee03dadae330296d4560000000000000000000000000000000019cc08c8ffc527b6cdff5f9f9722dab5061dc96d8ad2866ea72b315a4602c90da919339e1065f87e2649b5dc284984791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb95dba7488bf18858d1381676f9576c568eb715ab225ff8d25a84b20c6f1cd6dc8e2955b6a5e6aceb176293c53dbde000000000000000000000000000000001908f016526a78f89443bbf738e4fa1ffeee5f3c54985ff9f21023d4fea68db6ee8bbd1cb33871bb0b0033580b59a9371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bd2e7dd67bd0b72b2ce52ba841a45d7427f4dbdd3702fab3d67655f1fa0befe5385c7d93a67cff9eb6c6301a8ea766000000000000000000000000000000000273a0cd7c02e397eff19b1c49174e9de5e523f51ee2943d3ee745ad986f5aba92f13fe45469b20e7d805904c335251e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d14fffa74365ce47f872d8671399d4385e2d46344cc9a14affb3e6fcced423d731f854bdf3098c05cdd42487c750bd30000000000000000000000000000000014550a918c4716be361acf40f30e8c2a865ab1ee5f0cf863828f1c2da824379d248f2b12b578e60509e36029096a89bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fca0d6b4fbc64bf3c7b7ad70dd459bc9f7ff64716307da0185e3bdb59a13c9becf67e6265de23d6abd309c5dbaef40e000000000000000000000000000000001507022bd6b482e8a0fd144e3923246b901d38b151da1bea81937f721a2baed35d39493a10494415847aa0fdd793f61d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018523585204bc4c34767b0939b40e6f2f3f9f1e0e1996af69eee55ac3d7a162e395e70fd611beee50cd49e6a203860b500000000000000000000000000000000019f6b68f2e3c0bad33b7833994716170b576a9d2e6d4f83f9525b6d697b78da7b51ccd44540ff147aaa2fade0f2792d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b286587c6293bac49570a3e812f2bd61d9798250e64cb03c7dbae219314a95091f80ae143381a8f14c689a2781f89a000000000000000000000000000000000cd122ee1c29d904e55b9a6722e606ab08eca8e4c1c897a71aed8c63821fac8307ffc716612024580c03be1f11a606d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001672e3fe888c0d7b3ded53a4e418075b089c350699db800a0e48aada4e7528323ce36827f4b651dd19bd95ea14bcf92c000000000000000000000000000000001567281433198b984f240f7d6f7f402e4dddd482d28e25ed52b499e20439fe8e231b9e090fc0514c4bc00878a26777121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020cb7e8427e70ab2e948cd8e6369bb14e8d7b6b162315a0bff2fdc5a556960020ad498f31a3955e5290c1dd229346290000000000000000000000000000000011de6d70f29b24abf4dd666a6238bcce1edb34e30db2db8b36c1ae283840dc863786c79a1b5a66e611d1cd711c1f6b6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a11b0c833936400d13a8ab4d80730dcefe479b61f4c97ac09a8ad58b4ba08261a93a1c0af925836bfe119fa07ff5b4000000000000000000000000000000000deed4977fd03f3469d3617fc6cdc198234e518ab156c5dec9fb105627567b205d1d0bc7a272a3453b29528a6acd08e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143aaaa8ab651bb89d17d18ea6ee102f583aa34ad7cd7a7878cd2df5e1e6d83c418da05c3b064d0e80a9f9f739b2b37d00000000000000000000000000000000147868f9fb6174b85e50aba1b4c6128cd07e189d57d56651609bebf451e24c0c4856158e3f1e51600559e32b3cbad95d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007842fee58cbc24ac42ff3746c8d43a5ecfd93dd72158c5942b4517c175925d28af09ee117108bb53c5636846a6adf850000000000000000000000000000000005d9bae9894ce88cc11aeb9deaf05a90837ab689615ec3675b2c764d09ae05fa5a88b30bc243b871585477d8b006cfe01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000224f1cc5e10b2d8c220f0668475fd291c41442f5ee3a49299a37a4e8d7d5ee4fe0b89082d16b09e0e7d8891a6235f860000000000000000000000000000000012b9f8a3a88b5c81e547211a2d80013ccc3825ef5958d7dfb28b930e9b944a4da8b21135ca6b170c98dad70297328eb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002062a534918e723df3a2a1301caaa1e1116786c297eeff9fb1a0aa7b99ef2c7b51c6d39e4aea555ca448783c95b7565000000000000000000000000000000000c85da99188215305c77bef56fce934a7d4af4f974c91f5e9a91e1ca256d367b228589dc7a950bddfdc2318800057f301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8d7321d6cf2b2c76dc6ff4b4a98acf2dee69476ed7b78283dc7cd1a0d0fcd04c2a3b90de5d1ef95185f544f32e8b3c000000000000000000000000000000000f1913951d4171392b87edef264734b9d153d9c48c5823835c741e0b1429a4c4422c4b47a69e063ff1d8ff6922ff70811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092df8ad1a607f1a04a89b881ebd706a459527e196835cbdbbf480600b9f9e49103ee959b8e4bcd6001c1faf17619858000000000000000000000000000000000880b331eb233ad98caf105c1cf0897b75e006aa78cfe5b5fbb1637594439ada00f8d1bf690b0844dd5de837548e24131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000531f33c95777ceb8cc9fd5e855a6315ea2858eb8bf670e65690bb42705e97d2a837749b1b140298400cfbf5a4384ebd0000000000000000000000000000000006fc6be9ef19afe0e92166c54d9b91f1f46fd44c25b7b03d91504b1d24b5d67f4fd13cdcf210f1001102db9b444585ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000425bc0928f9876f443319b37b10f6a57691ac8ed52d39b8507c3079f14617aa73c70b449aa5efe6ad5d770b3bd557a500000000000000000000000000000000125cdf5bbbf9dcaef25863e793460222b25429a7071925949133d7075bc04fe5116bf4a65c32b31ab0c4d3984a5d668e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005294afa3910cdc869cb86e52834f68f2aae860af51fba8a42bec7ef32769c779c22333f8e3d49df1fe9d5c355c5f821000000000000000000000000000000000f84a31b00b7d78ebc073397a11bbf1e36cb3dec9518c19a722f3ec8f9a157a572811576bbf8fa7fe68fabaa8cf309d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc03151ac5e58b24b4059aaa89e11829b0ff26b274d6449da57bfb39f77b4853953989c099e0b6bc122333af383d4260000000000000000000000000000000008672b42fc3ffdec9766100543abdc6b9506f31fce07df72428ee395593c23cafdb9ef56d868c6018ceb2c7467eac56d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144ee6b7e8f68fdf1a33ad95616b0290d04e0611ca6a833ab55f6efc173e0432e60f4fcc5b52b5d255273067c6d0384500000000000000000000000000000000009409e46420494fa3f32906e474e2b0f676ba42df9920084e7ad6b503d8e0e2f9f67a2b1cfecfc097225ff8639ecb1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003deeca036c9b337add88a5b9846c9bc6b91f587517d25d55bb08408375a76e97df82adb13aa6f6cf8218003828f1041000000000000000000000000000000000318958073d06b7a346987cb543a3bd536f5f386ab4b2d9812c8b62a71b658b55a13411d35a09176e529cefd668fbafd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187b259ed5d758e510b2969ac280b7d2747a3804ef461b6f07024f92c3322637dd5c81e0606af927c7eb453262dd9832000000000000000000000000000000000627401245469fbe10f4625a1393a92835d9e2060ba66e8e1e5dc544461110e5a1f769a2d1af7d1eeed61ed090e483781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001694b28c850869b1c7f2cb1b248504f689461d8a7921ffd62eb1f644962735e3fd4f24d423be1f1d7d8981703ca6bfff0000000000000000000000000000000013ef3c6c5083e76c1db4524dd46b7273161e0d2e24e8198e63b1a0b55900484abcef24baa25eea43ae3e80bf755f52601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc89770172cc9971cd1cbfcc0648d55aa9af0b7758180288c38f933a0d7a08855a952cf32e38c769b579195c311ae2f000000000000000000000000000000000ab30469d47c249a718e1b63beb375eaba0035c8cf2e5443156c702090ab5ec1acab7ede3565bcf5d1ba987241517da51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b33e042a76e20edf7957410ebee0524bc0cee1ef544e0a005510cfd8316e5fa8e5c2858f8bfb78d9d1f2a7ff83fc8c00000000000000000000000000000000118bcfc10fa5beee740783c68dc484a16233d9baded29538fc968672510560d10869cade0429896f10059ce6611826011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b845cf04ba465565c31d4ae828625790c4eae943c46cd950d88a34c05bcc38fcd5fbf4aab38ce439d1b2bae21ba0f6f00000000000000000000000000000000171090be1a8c2f4509fbe1d91a6fd52d5673ff809ba9cfc5d01c3b0a51804f631899ec48bad485ab4d5042be19994b251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189c4a7f1d492e39cfef93a099279619f02e356dcc8d23d3e407b278c0e476d02bdc5171eaf782f8f1d7dc4ab4b73c6a000000000000000000000000000000001930a1d01ec9c737b99910b6e1c025ee3a981990998661c31d064223620f6bf13a0400d5ee04b7bf900d1dca34775a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010040d2aaf104b9d3505b564366d01bf94051627a842d506e691a893b79d26a1b9ba2d3c696484508530f062166574c9000000000000000000000000000000000441a52812993acf6b648912910d2392564f54a022f3c0aaf3bb1b9581712486b9a001672fb3ee93497b1db4b355e17f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9c1e5b9c7c619b1782bb7e75d6b8b1e431016a485b17553e06ca1058d659f39ead9e9b9d69fbd7aaa43a468f3e1ba200000000000000000000000000000000045674e0327f4227be907735af33084f84214b8ab8c18bb22bf0625aea3be731830a6ba4fa86cf619ac4c1f1bcbce4ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197b52c35a26ab7ff14aef8473582d79b80d9abe0ddc4362928c6025c52c5ab8ac44553c832004105cdeb01a828df29f0000000000000000000000000000000014f7d1b955c56a834558ebf58604501f7a69a14005dc1271dd0dc80475d95e3225ec0ee8811035eaa0a71c2b9189b79d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8e59276c63fdb451c223905578f8bad8d424f8aa19f99597ea444d24a77fd37f092886f937b0e25dc22693b358fe850000000000000000000000000000000010556f4d80a8cd9fbd385a86e53c03e3a6cd76b8d12beff4e9f8c6f030efbc739f70460f252540a8427e8503acebf61a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001324e5dedace06232165b0176dc23a0194085c722b8dd8f5350033250aa0b266d418e45eaaf980f2e24fd58b2970741e0000000000000000000000000000000003ba47e83a0f1a2779a37939777949440c8e4a02dc31950326a1130226a32f195f612d2590d8553d79b623e94e41672b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090cddcc6bbcc16e29874cd209debef6b6ae105f0f0f1bab8613588e3ada67e686cfe77668d1ec593382506752077ef90000000000000000000000000000000010e5636ed7e901456fa81e4e21068e63407c7f07e510543a694d8a17d1945da3ba9a620f9bb98b0d35a8fbcc5f9ba9f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce0436edc3fd7295cdd7ce652039ed650a742003201bb26ab1c4c97aead5f02194e42251f42eff28962f53cd0956fea0000000000000000000000000000000018bea5b9ae44dfdb73e987bcddd6c40e8a7d24fb779c72eddb214bf9c86225af5681f4357c1a4fca89c5bd7aa0afd19e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001258b95df4e8f29c0c27b5194cf47fe5255259ec0e3a3b97b895e06c9ad4c8bd32b4543547ecee722d6f2c496e3ae206000000000000000000000000000000001897bee3143bfb78d5a7514b582c1ee923ca9ee534b408ea1076a7fafd957e3d3f1dda66406a7a3af484df707f4035351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aab742d2416c4b241c5337e20ed2f7d096c707059c41d183d249d52c40c69e1c42d08fe2022902cf8f96d02463bd86d00000000000000000000000000000000190137f2028bc83e97becdd7057ce2e05d7df460c5a7b4671db5e4f4914fcd9c25aaab50d891c88eb7e4ca72a582c45b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a228d19ef65011d60a01123de1d5f1d812a94ff5f555209b21998f2ff9f74ad9bc46ca2a238c4953304adb7e88bda20000000000000000000000000000000006697bd5eec42e31f621eda979a37524bb47c69dbd434ced3fb1924014523bc40f7423d193ae3436ea064ca28a6881931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017288d0d65190656e9bf3d1adb5092d0c41e217f480ca2cf22348a8d92a602daa2fea9e33bc62bb75e874e9ece0c42370000000000000000000000000000000019783e0291416c6dd719e7c5e2d76caf8a7db47412c99f007fa399f5aa50e6685979ea29617bbe400c7ece6ee362c1d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e393e0b715eca642fe6c191083c9d44ef567888b7b89d078638715a13e33e6c287c015904995b21884de4cc1250515000000000000000000000000000000000f667afcf51858ff0983d10d04521b3e3063916fed18169b5880087e21fb8bdffa627dd0277dad5afc86f8c8dd3149be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a164c4e56854b445c68c678444aac2f40d2ca1429b6434dafb9fcfda201debfa07edd0f98f31e0bfdf3ccc7b1b66aa00000000000000000000000000000000112f0756b1d3309209b35d419e95574ca27ba45c6627a335bb212d65a33513522ffea2ee1411ddb44a25318a4881446b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da9fc4e942b288d2f5210def20ff835382ad5ba401d976c95ef455944700ae4a292e97b69c93e91537638a16cdc5f1d000000000000000000000000000000000247a1d6d3fda87c736744292b9c3f7400aa54542ab24f067036fa64831464b79caa31f3c45e97dcb14b8fc90a63b4771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c5ebb0ffb77edd6f75b3930c2a191e5c55c9a5e2e64faf95b4d2341e38c37337e445a5deaf13b878b6b2748849159a00000000000000000000000000000000154fb71d97a4c029c47fe1050d5be513c306c017f15d2c7e401a3bcde7a6776a822f5b70a8752c344202c9f695df4c981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008698920049fe32475f0f1839abb13530be46fed39244d54f18669c30a9f7e1aeb2b48df2d5d12aaed16fee19e9f64720000000000000000000000000000000017754c1e7df72152d4950f1a413fae9f4a5263b5b57c61149ec1d2a8c2bd1987f4a3f9d9235cd3ae17a868bfd91266041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182a296984baa54be20ed116741945827dfca7885cc41c16cd386684b6a97508aaa1b7a482d943eb686653973beb2b7a0000000000000000000000000000000000e5b33a5c3d0333e7ace47642b71a4770697c3d5b7d7f395091b02470ee9265b16a6c10bf17a0fdad6ad0ae879ed4891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c20fea839e22e38339cb9bacc6fb4a458045fdd5da9aad6e3e888933d913c9ee548d9e3dbaa6488ec0cbd252288e856000000000000000000000000000000000f47bba6522eba23618212b2f943511a9aed565578dc216cca2bddc1a2f7372b1e4984a7122a40ed2bd19cdd7c6318081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74acc772cf806a2716f5bf52207d8991979aa2c0cab037c190c6dc03e5bc70c9e6d6e91c33fbe7739bee721f2370d6000000000000000000000000000000000f10e3002c8dd14fbe1e87590b4d6cdcde05a76659405380998bc218137a97555c79ee446a04bd3d73110fb1253e63c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011446c5331b9f762e508f5c4cc13eabc6078b206543e9c0d74525fc042f8c52856c58ee3006b439a4947d4ad1e72b3790000000000000000000000000000000000700ae4004b9c7dae224e4278a22724c68c7b225f6e865334066dfbe5e80a38e8838ff83fe29d5b1d2db6acaf4010fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007abd52f51ce39885e25cf397d48fd79dad99d66fa40fe4ef3ace7261199b02a183af4dd5e10e17b955c2349c4d742b20000000000000000000000000000000015a412a47d4f0d5d0ca3085ab63785b135dd545e8f122beb6b0e823b6cf8f1b83b216cb8e8957379c755b1010af61c1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001041146b3d05982a533547ea7cf05f0bdb8f6f70e73820f65aa87bc2b3009a154a232b94a61f8fbd5ceba72a05f5a03b000000000000000000000000000000000c9d8346be09eab6cc8b58ed6788ad8f00307dec4a48cd59d512747714511385b930e4cdb3b8fb5040c1910c04ed11c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d2ac62debae4881207cf5c73a2582df4d7930eaa0f09e7cf295f4c7a0e2461f84eca06e9dc7eec2f70e5cbce959bf5000000000000000000000000000000001628ccde7e966d29380fda2f7d235af0e3dab97fc66eb3b50afc2fe15291608082b64700e523de33ad3dfd16f35321631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ad779e2c7ed28614dc3c4ac1574dbda71b936b6e5cc8efa5a1cc191400250c91b0d3d1248ac2ef5a24ad2afb83dfcb000000000000000000000000000000000f9dbeece954dde2dddd4cb9d0fdbf06b5e83e80d67f98a1fe00c24bb76f5138d734ef2382d44bea9155f1beb7229e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c9c42f4f2869364fecbcf655f4042a93367058526bc9790a43f302c00f75b0a59d4a35f96706fa045e90d5b52fd2730000000000000000000000000000000015f8d2c8406a816040b7676cc7736fc7e72fe2677ee755aa0002c9dcccda0648082d6625b3e072d16f79188022b3118c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1abd8aee02fbb67b01263efbf8d5bf6069545bda04868698863e00f211368c17bb5668cf4fb61903eab0e8593a780a000000000000000000000000000000000e943966559d670ec4feafc6e069190864301643b8e1b6131ee1dbdd8745855e6a11470ef62b1ba7977a0a26e02c20931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ab552994f9141375b32b4df1a4f016558fd679c3adf7c7e22b38e0e099a197cf908a39f97f7fe470446286831b54c3000000000000000000000000000000000c8ab44a0f76f550a8e52cd9acca3adf5b1073c13a3a3edadb87f08f702d96f63254334e097c9ff6f7f8ec71760d57941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000406fd6ea8da815b0077d6900729694574f47118fb3a81193fdb37db5184c5aaf20a5d5cfa268d72846d8f003a99bd1000000000000000000000000000000000ec97b2a9d4cc02cc67242e36bc5b154d397749d093d4e0f22ba15a55207af63ca2a6d0cb6579dcbfb8a5f4ad10e6bc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f99298ecaabc6a46b64aa0388d94c3e243cbf575ec1ed9c13a7d99a6f7856d95233cfcb56fcb17546c3558b1934726c00000000000000000000000000000000036b9080651bead33696eb09448a619dac90acf479b0c21a5fce917b9c26552742aeef1ffd198c74dcc89a5a45ac7a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113237968a4c576cecdf9d3c636b24b48db3215286774920330f223b20dbf0a873212419b749e387d0033f2ebd0030ff00000000000000000000000000000000193e4900863772841f9b5d3e6083a784edd2c1129de7bb4ece6598039d2ade494910a4b94804d7b5a1368bc5c86ee5aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001319888749b5c4109a4edd94223623da0093bef0ac47e3a96e2c2b14947388f115acec1860173792283cdfc3a3b65e4400000000000000000000000000000000073f218d630a3aa202c92768f8bd8afe89df47c15e71aaf87fbd223961301414e35beab334f5dc31cac6b76d7caaeabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071e748a86bff323f864742355627e82adfef377d0b566437694659d2838629e5ebdf233fef455bcda8b4738e9229ebf0000000000000000000000000000000016c150499ad747441a60d85365dd95d1e942ef94479f183f798ff9beca4a396a21565b11f62bbc049d4880d435f4370a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e89b8c9e9f150d6aaf476d186ced069d28324321b86a183590182a0b8ce56a328d6a285a7223cf97a016b3fef229a1b000000000000000000000000000000000067036c193f249eadba4e9d92de2c5957ff5cf0b2e65d191cf826212fb0b81fe54bd66e552ad9c866d86fdf7e96c2ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010eb76e7052a6c926add14ba61459b51657660f6e1b7e4dc1ba27b82408238cd44eb4644f6ee949c41225f288a942ac100000000000000000000000000000000162172b68ef75a1a97ab47474a801b21d670e06648914f26a90f3a9ef863bd9d1270a3f7c7fa6ffd4a97558779becf951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182f4c58c2f332bb0a207d08c75f84ce79d76b8680ecb0f09f6f234da4a6d748520b4527ca92f7926d76b7f108a254c70000000000000000000000000000000001bf543714e255ec0f2eca033915ee1eda3890764b20c75533ceea91b46884c4a3b2aad7032845d6ce9c8f37c64ded9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160294731c3da52bc00a61084e568e488bcf1a9dbba39733679e7c1c51da560cf01e5c0311a68e47841a5cfece41a135000000000000000000000000000000001212277503175f22731860090c92f56251cd3bbe06ed8235b253459c77bdde9ed42570e01e41a065f59c6497170b8e1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019505ab021c5b3cd703f076d52aa2bac927118f9e3013ff74d2452cf003a10e963c850724ff8d1ad083bfb10d6504479000000000000000000000000000000000cf1a5fbd75abdba47feb39e7675b26541364d65f73609a5d3f36cf8fe6dfd2d8970fbea034ff5743dbf7a0bb8c4cb9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8b14f8391c7b89b425914f5c46c42b52bbde0a23f00e59ff4cdb434061d7d970e2f70692676beecd6bf96c7c4fe3140000000000000000000000000000000010bfd77b6e8e5de7fc7d6aadc8119490896c7534194c2034128073e2ce7605c4af16bc300391cd2c29b3866ec1c4f1ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c15e60a978840f07ccee65d82a0801e48f7163b48036d992ee412dffebec86f8bbf33f6fcba1f8b379cfb8120412d10000000000000000000000000000000002f821132d589f2303c90a39128608f01766e302125c5f813e8865fdb755cf572afacc3025bc691f465b34abba53993e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ad1e29b358c2a627db496d0b2acb0726ac1f31aac410517d23039c6ca73718615736a773bd6480df74293df1c962e40000000000000000000000000000000006eaf5248e177d0568b294b228112fe7ba706478dd726a43277ff7364b62247810bdbe325ae8c20b894fd59c55f74c961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000729b6c8cd2b0de947bbec4ab130ba99e39abb2b145f03a98f896d4d60628b54c5875be3c612000b3073e3205daac20000000000000000000000000000000000e1464a79febe8e2a43afb2be57efb52e75f4736035b85bf6548eb910e89ee605d830f73f46e27635df0d233e944feb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b383fc01e9376677a8caefd9bf2e5ea7defc37eb07ba49a71a524fe861030e7ef2948e72613fc63f95254dd537b0a1000000000000000000000000000000000e8ffeb60fdb72800c7ca1ec810c426f402211b4fb024cbae322dc97d4719fcced67f107d9ebc2344decefdfca7c20661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123ef984064c03b19cbb95d762af67c9d74c4c3d59f0677a5518ef864a98636ff5ca6ed02374624e11f692676829beba00000000000000000000000000000000179ac3a2e118304936748658c3a5159b6e77152da5882978ac157313592526de48057db17cb44b87c11713f6bc770f671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000006b48042717697178a568f1796de736ddab8414fe53335382fc6e6690ccf67bdd5b21d3ba6940c582f17582a29918b00000000000000000000000000000000048ce9f11816f7d857fd0f6ae2f53f5004627318c928a484756f64a2b474434feffa60e7bbf5e80bc264dfef98eccbe51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bebe0fafef376ebbf5d9ad4bc776d80be98a6a699fe533f62f6d701dcc381fd6490068456c37c217dd087bd02e5615000000000000000000000000000000000093ef6f8126bb31d1a9383d1e41fb6696a339b6386bee423ad916e6f64f1c056ac4484e340f257479c1f2311edd324a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070e4a3e060b9dce04b771a23ba32fc0a0ddd346b16d476a16a22e3ea9069c625fb95f7b18eaa6963778c0f86ef97dbb00000000000000000000000000000000064d794f438aa7fb55760c95d3080da44baf278f4fe84c649ba2910a9df1aa3c226316d895586f8008ec70e00795f73c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a72d7c154db16f02cb2c8fdd81b0263775a68f370faae2692e7fdb8f67d3e205f7b952591845a096bbf830761dfc3560000000000000000000000000000000011e7146dd8407bc3dfcfcc752bdee0d3e0f2a91911ba365ac258a4fa2b9c147142294d8fe4700c2ac7add3e0a98386991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019af09fb0d44ec9a4444b715ae09bafb07be6fd30c9296a40d88c5590c62ca0fc6181fcc4921f7998f30aeda9f79f06c000000000000000000000000000000000ce6d2a3c377a02f4d6c509267c851fd1ba8447e448f384acaafc5582d635809f9b69fdacf60a0ac7c10e67f5a6c52a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d95a599112eea3de63db72303c5eae91631c3b5adc43ee200eb92434f378a4faec684c19f1e50da34ba11df93e1c67200000000000000000000000000000000042caef535d0942b4e4a865a22ec037829dcb22c0ba4f6b1add51ad757015373f138fad20374cbdd4caa7e67390a8fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef26e84550832884fa6a572c6b296df12f68bf491c51f6dc7bcc9e19f64ebd02bc300a5d51556d6276fdcb6e68f623400000000000000000000000000000000155722b4772ef115fa4797a43423db26fb4e481172e480a5c437efaf74fb1f8a21da3b171fefc0c8e12cb5e340d79d861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001258daeba2b2b1a55d60fa172b0178103bec58362825d7e0b86e8bf414a93bd922a28099aa8701e359b7e03e3ad1ed640000000000000000000000000000000006431bb35150ac8bb1865b07f5abb021cd5df0eb7bbbb8ee826b26c5f5bda1a90079d6d527a9b3fbfbc161520d4e93ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f225ea60fbd86040d99d2b97431c368f1a05ca81d86e9fd9b5022cfbddcc9cd1647e895ecf527dc7b5d910ea09e49a00000000000000000000000000000000015e25141219f28ddfd695773a6f8a16a0b8c3d1f33fc45aceddfb88a854d26fa68b92944e8c24ab7dec89d12240454a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca39ee0f5a37efe276e25f3c5406cc07685e9a050f83448ed0dc8288521970f723ad587cdbb4d516a16bcbccec7e3e40000000000000000000000000000000001ffc8d99ef8eae221ebe1b750886892c13e63f3eb01c4e8bc416d5e994867a6663be09b3bc91684ed6d312e18f129611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ea14cb26bd057de40513f19fc5c3f711940fa2198041e31a1607bf489981a9e23e5357b143d1855e9586f167e3262500000000000000000000000000000000191c8091add5b1fc56f8804afdfccbf9b00cff1106bc3d8efb3a9abc1137681f9d38558d9cba646ddb5f7cca72bc67d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058c19a357cd3c4abceb502099bb9b3949040ade89536a1cc6b2eacff66f32773f3da943ab2274e800a0da82cb63bcb000000000000000000000000000000000008ffa9f887459e0ca67141b6e693e9d0ec0865e8c7d0a1cc8c5c67eafe72c49438fed2727dca568a4e94a33ddd852571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d304e9c35ef0143a96a2a5baacae7779632a537187201aef6f8e3e16dcfbd99d6470022b14b6052de6f9de47a53309300000000000000000000000000000000076abe43b041633c97b34e9e0c464d876743572580cafc20599dfb20d69513ae568cf07fce25ad964c883826d27ce5db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006006cc74b97b2e34a7154e076f3ab914276f639daf5dbdf812379ff220cbec7a826011f4cf91e7b9159065ca6ea72b30000000000000000000000000000000008f58e2bab0d8762a6ba35c9db59252b8069c564d60efc7c7802253fae95a3ee45698df8669b3447d5090ed9762315031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141455a3fb08e272cca4d32a5fd86875b1a24efb0bfaddacb9e3dc4d25ddcdf99eec96da98eac10903c3867b2e5c15960000000000000000000000000000000005b987cf14e2a497ddf1cd8f8e85649e550bfd5b4f470ff3e4a345b55d06211a6b89d1f30d6fb63396a537dbe10258e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e1fa520aecd67d2e454b4d84e03095c27d7153e045a651b174a0477da0971acb62db5f22bb820d15ebc644120969840000000000000000000000000000000000ddacc8352f64f37a74edf1c7000d2c72bc98a03806ad92520b65e75553223c0d9b55103c96f5bde15d2d53ba348e201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152be34330705962bd191b148e0c80432f9405f3bd0f7d167a80b863bfdf6d6237d6529290ac8dc871169514053dff11000000000000000000000000000000001697c291b31fb317d31f903442cc0012b444df787f24604d53d1128706f1178a2d05fe727c0f03e533fe652062f40ce31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1e9efdf7feedd94b6a854bde985fc0d60396cd7c342addd40331d2d7a1da202cafae5d447a4cf0dac8c22dc84b8239000000000000000000000000000000000412619988b5cfec5df02e409146650de1ec4d88f74e8a7a4421dad1ab195ab6ed0c4979dd237a65081c1bc844d57f551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa7017f3a991678cc987549d75561c3499787d13243996332dcd9cb1a8c68f99d32b4911b5ab803b9f65f7a5cf9a360000000000000000000000000000000007ce2ab399faf1e44b538149ced698698a764ac29aea52ec480b48a8b00d382a911ffaa5b40d6ce7738fde526cc683a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183d7a6314271d2909629a8fbae11c8a9497332fd0f1c5e3520c249ab6907fe369ceeed22bfe9bf489e119af67733db30000000000000000000000000000000003b92151d6d9544e76c6f6a8886614cc9be9989b80b34de25f9e3bf4ba6a0cea8aaa9f90d108be50cc3d559a48c72eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041ce57780da4d47881c7b5a8a0bfc1a2eadaf4fd25605d14a7da5dc95cc2763c2cec81b02ad2fb45fd72d4d14271b290000000000000000000000000000000015fef4a1a1862a7ce4373d64b424f876f800476ece6f95f94602364f7d555adec687f8fc73fbe5be856e4d882eae1aaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001931f8a633c979f1ee003bd6e08acd890842b8bf4151afcf5250453772ed3de9fab58c10249ed7f00c00dcb17f421d00000000000000000000000000000000006f443c7f712f99b934a00648cad0d736ba642cecc147b245df90bb2232b535da55dea0b9ef75b64fd35b267fac1324e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019773aa35bf37396435a4f4ce0d81184314bed7d262ff85255999199bb797a1e2475301aaec7dcd8569b7fe12ff109e80000000000000000000000000000000003b95396fcf4c374e2eb8e00c7ac5cb91dd20c0ad8627bd5414bc2021cea4d7d47ea592c7f0c54cef0cb5bc1584b25191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fe329c53d8ad8dd8afa8bccc63838b2c719909fa9926c3f57c4b5474b77e16b6b61cb4b30a39b875d76a6f2d00eabe0000000000000000000000000000000005a756cfec97615b844a491646c542d9bc9453de1290e8169865fd87dbba3e46e9ede7e56de643ec263c95cd2883b2941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ea7182034f6dd06a2d767efb0b978fcbe51117eda9eb0ea2576eaa3dd98b56161352b7984e3b4eec1d94dafc9ccd0b0000000000000000000000000000000012f3d4b1b196758bde5103cb54d084e2ef6e335f2104307aa4c523bf6f9244e9744245847ad5280e138fd44d36f24b801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170127a26e684d9c343110786c22f6de7477cd42a8851ad6dbc00be4fb9259ed97877ff5717e2f1605d8553cb1da2aa30000000000000000000000000000000003b1c7add0964bdaaad8981871ddf74682d32d77ee0e6512d99acb522e4e9dfbc0ddd3c8bc0dcc63ca5feafcf35cfb211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091f757178a65905c64f45ce6cdb8fac2fa4fce1af485d0b2982d6681d33bc9203149ea0e2138636af2e09da8aec69eb0000000000000000000000000000000016372c1964a4ae6e8e22800838c50328fe76c223d3a7013bf55b154a89c8565c0487670ad8d1cc6e06e0b20b0edb53901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161df9d10203f549071b175c0be1a98892478e48eba1c7d65cc471bb28d9ba08b1d93949cb66cb68000ffd16202e74a30000000000000000000000000000000016d58c2cd8544b773bc27e0aa96dd0ca06d2aca9e8f5518007df5cc6d8f91e6433253ab6a84e154d2ee333a6aabb931b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e8078d8b90bab73aca86ad76ad90a11a2707cce2a46148183db7042b8bc307848754acbbe9df379c63defa912b588f0000000000000000000000000000000009d693e5202e28c1e619d30078a7b9066450c88c207d34c2aaec282509a240a7a73b75165e5ee12b60cfb2a557def3621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae00881c2876950e34614a7e8bdd9bdfce88c16f877e98feadfe2929b49046d1bb9ed05a43a11906d749ee0cbf8a70a000000000000000000000000000000000d499b4dd5c0bf2f6718a7a1fca08958f25873c48b20238b2fee93f907d6e698cbfa24df0d59cb0a88435002f2bc30c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102a9cd6572d0740326b2fd0891a47e2bdfd095e7ea0f26f26d626e9574c6e8c67ca0b62414e440e12becd8f0cf924370000000000000000000000000000000010388d4dbacc00265b4821279d2fae1be530ff75e3614b7d42a46efe2264ab034c4ded09888d1b8c750820ac581392281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ee34f4a2cac2171bab347bc78e837f5852660ea30b372b0a670e85d815e30af7ccdd1ac6110443e84ca8fd82a3ee380000000000000000000000000000000013a61ccaa13a8cd1f1e43e570326656707f4ea854d68e9e77062d7fa2c24cb257f3173837f6260429dc1d8970307df161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011320e22478aa33daf67f60f7ee94a1b9fecb8fa6cef70c40828d140692a30b0d07a03ad9bbfc2ba1e5f6c33022fc8520000000000000000000000000000000010ba3c4bbafa276d1434f1ebfe0b2541a93cf533dc2400be649a63a844df637bb8f6a52185c6becb3dac2276d7d659801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009afcec9996b8df61f0a6bd28573f1ed2f1e7881214484ca80b91b43b2a369b6d6a397ee1904554c32cf918a458eee7b00000000000000000000000000000000016ad065224ef9585138917e75cd13e32c2ed74279285c6fe95dd49c02cc7b6cb8347a648907e01d429c1a5b31a45b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000043b49d7424947ce54335f9b0dc78bc5e492dab7104057e7a9f80097bdf5234a6e6c0921d7a6c500e7b84872c2da7b5000000000000000000000000000000000b45c1395e0e62f88875fe6b63384778dccb0f978d81988da473f388d7db89d79622a70d07426c1ec523206ef1cec60d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a63333de9b4f3516a06b9808fd43ded774dd8d261bc0814ba4970cc994082b97602cc7e9eb1ee651a4f6d509b7e77d0000000000000000000000000000000000c86f7645b8905791505220dc1e4a3d6116c39c1a29bf2d9e41d7acde74c795caa5605a70abc28016c0c0d7bfffd91d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5df07978f05f73f53109aab6434e994acf680debe43d530aeda7e3648054e7556ff018075eea36a2e7ca33a586e21700000000000000000000000000000000049d70eac478f1a649a2b30cbfbf59ac685c6732c8ff694e97a451582186867e2062482a504c693b1044330bb0a12fde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7c523ae2e879032e992f47f7b955f3b0c5aa83458dc16967921d77cd6b1725e0f433cafdc10d8d84fdd2872e8d5e73000000000000000000000000000000000384746ca5b42157faa5aadf86c403b181720b6119b1abcec51ae58fb868b9c17e87cd9e6388980c030f0db9c49079451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136d56e5dc87be3f279521f248cc2bd04f2525b64ae4a1dfc77c49fec5260537d542bc821f70f636d05808bf5260651e000000000000000000000000000000000f1cfd5cb2f0e05559fa4c3ec2ae2bf55a36a88df5aa0ee5191ffe4c8deddcf6cf21f76183c64f474b1c7808460006731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000561b137ccd91fbbe137ec2d46798438b77bc8371833e4f4053812eca9bdd67dc0cd9c7bb8bf1f42a9325e83f24b233f000000000000000000000000000000000b70d988aaf182b51de00bd801e11c68f4713f48fa3002a94b5539b100b0777c2e8e2e354bab037b8577f308a7e02e7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df13768e7007ed48ee40ac965d6b223a0c15a148c2e881624b4b726cb9cb8e149ef50a2aa976d628f30121799be24cb0000000000000000000000000000000015148a4bb01170654003ceaa66cd02f8ad0350697950e3042b3ea972ab455d1491a11bc7779f703a7452f62d5bad5c0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033ad90e36da5b9f49e3d106ffd6c5a3e701a842dc418e84c907a42ba2343ec17998feacb2182efb9ed3c0e5dcbe98e9000000000000000000000000000000000163dd1c83f135500d39a65084c33de072302ed5ecc3f3b8bfe1b74176c420e12d65e13d1628fcadf5153c43348a3fc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001757b8dcfe3fe33fb5ad643a897fad178571261f59406aed1ebd20f8b0a45b7f2f3b7c8665b545b57baccc243b32897400000000000000000000000000000000105e9f23cb556d10a3ce13f1720b30c9dc33721e6d8f5e8839a766a9d6c8dedd45d56f46768135ef563d950efbcca2091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006c093d5b6872625e4fc22d9b4589953d4638c6b3870b837ee0c2ed4cad7be0045b2e18506cd30ae6b34fd584654429000000000000000000000000000000000f3497b9ba244a3fe372136ab6fad41d337e9dc4c0a4bf26c9f92d5142ef4e4ba3f824633cf1b16e50d38ce35fc606721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c919abca00a292a3c1746752b499ad5ebfb237f35b57a93f207bdaab67681adf2fd677b5207d726a010cd35e5900434000000000000000000000000000000000fc10e64eddb2e2337553e7f3d6775387d9ece87be5fabb9549e9a4e5a5020e4fa3403cb8796cd099164dbe3b09fdc8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7ca8e9547e391925640ba8a2578c3734d1c3765e5170e5cc88fd57f0f7807acfbb866d744de6dd2bce248f9efb9787000000000000000000000000000000001658ab1c819b8da1ce6fac6724048dcf95b39b75a8fe8a85fe9fe34d270b044a5d8f336faff4cc1df5511a837d654df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026f29e0e9842bf7acc07cc9874d391f4066ec6e04ae9904b4afa988cdc22dc386b23b174e5bf34c6f7d11258bc36a020000000000000000000000000000000009c2ab1ccea3a4daaad1ea137cd0292e35ba01316cdfd5e5ae9629199583be468d541f159491baa927ba78eb2be8f2871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d2dc038fb9f583463721b774461de2c6a0cd05971830acc3e1da538d4919b5e7a09a526c21f7f0b37aad31ece17ee900000000000000000000000000000000132728b7fbdd7a712c3ecfade91f6df1cf75240a63fe230241a73ebde95d3e7d9b68be1d46f9f2d1e7c92c53fe28d71b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028f4454baa657c7eefa24ebb91e641ebd6864bd1508482508ef56b969af18db6e862a1bdb188afbb4234de723bbc79e00000000000000000000000000000000199adf6786f8a5c51bc76bfc07fc0ec3ce436204a8133e2be0e4fb12fe00a76c71f1549e07e52e5e945b3ecbff2e25a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed0491b310c5b167d6887df742c1e4b7287f7213a2ab334003d7613d2bed5bcacaee5d9bca9bb2db7bcd62caf016f390000000000000000000000000000000013ee7eae92a74231014facabef7969d13753daab7e489ef382a670c39525b57270b0eae1752fd9a5ecf17a2e8f1702b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044b3b5a2330bc5ce041d9bde4bc448bcec0fd107d91fe12ceba81b3e8ca5c6ebd0b9841e5c206c9739cf77d87827e1b000000000000000000000000000000000bf8eb8b6b41282ae73eb630c70026632e36da0aa2da359503ede5a8d3a39dbcb57f16ea33366bdb3b2b6713ddf126231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019714ff8ea48419e676ec5e37655298850723a9c42292ccd0c10092d49afe3754c0d5a631fbdc6b86385de7f8caa5c6f000000000000000000000000000000000b1ba5bda8116d21c650b85c0fe2fa8784bb9a95d39966635b5ba3f65027bd95b58f47498db8ecd7ed2728af54086b911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017198e31ba05ba0955179f0ed84e927dc1a0388678ed247d74477ed058e4dcb7afe5941b5e3714865d004a825026f79d0000000000000000000000000000000006f084446a3f465371490ebadc33354003072876eaa2976482690ecb368d93e2523e5bbc6caca9559188095e7c54f77d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000118216bfe9d69caa6bdb276e1cf8d13649477ab2877cea5f18dcb76a0a0e82376d790850cf2f02910d60758ee8b9eb0000000000000000000000000000000002e24c4173d94fbb041f56c58a28f049f7da9568bc41807ab9e7522e91765dd5d30162743d1cc53ebc6635f5511c8c631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000889bc3495d60010b9a8fc354fc0970f7adcf532bb0c7ad1e8cbbe95db11776527f71ce7b1ee3076afe230d8a5f1db7a000000000000000000000000000000000141a834b8d213f432b2d2e749a5230dff9f3945116773c6c4364230a33546490cf2ef003dbc0e3cef5b76957a99aeff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c44ed292267982a027ceb35343f56d171829cd6876d47c36292c3c21528cfdfe02b4d5502780a3aefa3b6c71656252200000000000000000000000000000000186e3190007a65acd2f60b500f0d68d039499648428cbab8cf68d65fa7dfd160917e45fe977e40acb38f0cccdda47a6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c46425e2dc1408339e8be6c5bb925582a1d8eae0e0b844e19ee726f34ff89babdc03f9caa03e53945c6cad5b7d8b5b70000000000000000000000000000000011fcbeaa262c97e42a02ae70f34192e7f53890cab4d859c02bda8e6b0fc85410e6b51e66c32564a453f409c3215ba1161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3f9cf96b897b69645a6ff34c42ec84e534143c43fce8aab5f2e74d70c611527d5fde7563306f8ec32d6c8ac789695a0000000000000000000000000000000004ac3f3a60547e3bcd505cb1856a8fc4c4725956f3bbd48d72e57df4b81fae61d7c11b7dd7f257adb2da8859b3e255611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f266a8391aa2f49a9680e3bb0224e769234d7a87d6d162004ceca7daf535d7e7393de2d86abbdd246846aca655c804000000000000000000000000000000000b99d33d33625dc13658aac232707ccd4d77c3fc2d142ad086c457eeafc61a75e28d24cac0ae702d4300e642dd5e3de71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdabf76eb0304999f97d2f9743504805f52d85381671cff259d768541ab9fce4a7460edb676bdcee84a1e5211dc6b0600000000000000000000000000000000145e4e2ea28a96cae223e000689841c04ff61e2899be2a3083fd4f1a247518e339e2a29cde0c865230754685a89c99801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000335598e6de809239a3e3fbe246d85d43f0c77f4d096d3399ef357c6116267d4e288f6885198f99ade0fdc4d25b0123f00000000000000000000000000000000057ca0ffcd52fda082aede02eb349cbd29bcd3ca4bf64521ff304d2f8507eb9da2165837b3ecb1124a55c31bfbf1df8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000152fe92cde534180194e10625c50a6fd41818d552ea722482d8775d003ddadfc37a7d549ec13f27bd28e2c1c061e9e20000000000000000000000000000000011d8007a4596991f21da83360fe441c4ae0ba4a13be87ae3cce6a00f83ea5fc83d8b60a6da1c64368da152aa767a81b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a5ef269bae013d5eb2646331bbda3c7d64f87ca7a8e4a3c71c802b1205b4f90ae582a3190cd72ae2661b9b38b6dd36000000000000000000000000000000001357f64debc1db223c416d91244c6adc8a0d0a0417027e751766f49a5368a943442d175d166a49805f1532fa1bc706151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001410d1753c8b8663b5cd8b7d1f9026d7e295f4c4b84a217588020566fe3bebe6f131d59ce873c50636cec97aa08fb6f1000000000000000000000000000000000c916f1ce545240b29e7671d938afaa0623a5d391cc4cac1d3a6a9e89320fee2c06dca26722556de8245e371474a386a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017daab196928228e11be0e97a14ea16833b59577084e83083c67d35febbb991291dd2d79259765d5b3a333473fe46860000000000000000000000000000000000a212710c38488eb738c60dc348d91f0bd915fff12244d642623c8b82705559a0bfb4857cc531b4f0d34f4f7ffe2205c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152ebd9e53c4a33e227e24258f43c56012a4d417f8f38a94284eaa77111022d9166d5b3bab01e84764c7a5db4f06bc190000000000000000000000000000000011d1ffcb92b1113d0e2491c90bdf1d6aaff7d766e3715761cdf74e5473ee9a75c9cbc68eca9b4dd683a83e3b1905b0f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d9cb67f1cc7e715ea0b28d2265fac08bf11fc8392ee31e4da3c00345ad606e8a152449a7d78fd8de8ed3ce2b6d9501000000000000000000000000000000000e37a9964f12d39f97adef0aef96a29556c23b46677ec1f5e768d4295416f7d1c9aecc5960aa050aee43e222abb026d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b1352ef2eb97d9603bd16a085729fd19a7342c166385f58f4cc8b45befa4dd6b346ca6f115176d5201b6ec67704cf0000000000000000000000000000000004e8457d96c8ada2ed170287cf0369ebb4e3b427bc8b4fb5d248c6b16590a62f421a1151c5c24e640acb02760995eaca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138c0d9b7acb2d2941b03fca37a6db8137779538de42da7ff1b0bb29ab373d799e8a4d0f6f85622c0835e07b44e648570000000000000000000000000000000018943169a3337eb3e17690fbb58f7f03031da7d437c629310798c38ef1ac09b2c7c86723fd6315641b52c56c2772611b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002185205b4e0a5d0ff016ac32f1aaa141c224efc5ccbda4544f876dffd681dcdf5026a98ec0acbfc539a5542f558693d000000000000000000000000000000000df52b572a572bdb7888f163482454bbca4c711b328b09672375c48d1cfd34475241413c7d2aa0bcef01a35f7024909e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014921516356f557de72927adb19e226268ddddd9a3b234e1953c3e971e75a90db1a4f8f494f225c6fca7265f9c39181200000000000000000000000000000000188fa4c53a8180236b03d0c766358c27105c3fe1c35024a148ee38707724525c14500ac3b9c3cec8afd3ef3225e693031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbe31f82cdc0eac6de1da92a701047b2dbca2961894ec2cb1c4fc8503f318503a522da774c0a759b8f351fdbba517f70000000000000000000000000000000004bc09c4722e27bafc4b6c52b1d69da15d743b18cb8b5f534e253d14972098cf2142608a72b24bb54abf1426888f326c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128d181753dc5fd329e134f92d73720cae1b77305e4f606a8745f9725f16419d9ecbbfb41c816dc54642ca22f524e0440000000000000000000000000000000005fd12cf2df76f5d642bfe072a6cc338d487f3cab7a71f48599101f07d88acf75bbd3c7f3b996cee0f846961093180171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001566b2ea74b915470db0838faf0b3a8bffa28f2516d879a9776409ecb08542886a730e0a0c1c5938a47ad801500a5a48000000000000000000000000000000000fc64c55040bd9ddcd29d667dee740ff37687fd19d094c6c3c161b5d09553196be860243252d0e3692ed15d49d7286701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110e8745b034480a52d7b8ee8fa9441a26db2c9e26c3c1484a0c93a210d0831013b17974675495f5f23479d67bfbe7fc0000000000000000000000000000000013ea82cd790ace5a9bed8db0a38a6293e135897af476dcb45c6a36e84b1c5ed798e19d5aa3a86f1b145c3dbc82c5b5a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009566f133cd348594c0a9abed3329aeb63b1f8fe7f3e345b560dda9ff87401b7db0e2c899b9cb6a261e353336deee38c00000000000000000000000000000000174445b067086b350606d09667eb3fc01a797c75b7af82ab1a1141f0109c787d617389b3beb0bb0cf942579c916eb9281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c8a975fb1fdeb2144954d0b711d9561e61de9777977289f34de9624da41ec7d49a69bcd1b5f24f0aec772a8dfc074e00000000000000000000000000000000075e868f8174da59d14b4e01b75428b341b1ad395ebd62f49b1c20fb4eb0ec4a126a21a11ca6a0c0f817b266cf039b291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155583d24296ce8e16599cb6696cb8e8480e217fcdc750234a9e37ed54548c5bff99740a32c760c9887a5c0161ba0c66000000000000000000000000000000000a71c2219452948095b2edcf10308f3e4616b9eb89194af9424c88eb433944b18649d8310a7e365d7bacc2ed253534111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7a219a1f36ec671bf6d969550e1ebb7b5c32494cef503b4fb84e5fe117aea4b5819587b49cef9417e7a4ff55d5e06200000000000000000000000000000000155a169b7812b7d3ae26566ea73e7690d2530e7ad7b086c8d7573a6df73b7eb56457397d697062a44606ba3e0357f6c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012789cdeba88c60e81d3d448c3d86fb9a64508e3ea147dedc3df258af03e78cc9b22f57acb3d4bc4662a2cb8ede5792500000000000000000000000000000000041459e0c31b598c9206609437b0604461f48819a0b5219f28a634526c68f2c7f47494fe6a42fc12508ec4a12b83288c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b88b970a0be332acfd3413849b44682a72daa7a2d993b21b1c8f8dd5859373a9588eb3702a0e650d14f3628c9f96a92000000000000000000000000000000000716490c0b58297262c7240bf01f7dcd70d94d722a722cefcd0fcea35bd4e40f9779754d5e486360ccd2529dc62b321d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000056dd8a7d7433eb39c25bf04c068ff584b09435db11f13659015121df64e4e128f54a3c5f154c15e11bc35af63d7d99000000000000000000000000000000001608017375368b6a2804a04312193121cfc19475abbffd86d8b5de414990d75212432d87b4cd17114c5fb89db1c48a951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cbbec2c7621e6a358db5098505779c151d38526fc1ea37bbbd5d69fd007c3e00b669c3b5e98b671964c2f7d090b50800000000000000000000000000000000102ac134e1d4b5ffae4b567faddc05b76f37f09540062c308dab9e800e866195da765939b692c7e1538a47eb6390bc531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8f059b1d13872af5e6776982303e9112f97d35504cd07fea30bd2f3a624edb141224bc30df4aeac1537e680b86a254000000000000000000000000000000000c86505accc2f238ab91e7feeee74ccfeb2fee97cbb72957435d3c144da91943e687ba43988def1d47aa8b7c295f184d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8d8d3ece2d81e11be7329e46ea435a3882013fb4fe3749f768ed1c07d7f221168ae1ed648c04fa7e26c324405f4a4000000000000000000000000000000000066daf851d334552367936ff9440d3032e8168b88dc7c115d6eab5640dea2ae8fb006369649b2ac644b18d9a338c8c971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ae9b5ba6a29b120ddf30d54cde457643d8784845d1100419508b148f293af5ad3f5ef1f8e55741db0fa02c5a7b6d1b00000000000000000000000000000000169768ea58e3a9707e4a1d3d4e0ded5d546fd8f2bde67f784989ad28544f43673ccbf6f525780c42f14c902a0c0840341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2de02758c77c2d166ae87fd16e63f236a962c44bdd3a7e22a21b0b04edd9be28425d9f6277db7c968e50a3472922de00000000000000000000000000000000052d053b346b9da3789fdfbf34399924efe51b56e38ef1ad586d95be2821f6e379e3cf7852a8ffff7cf3f8de58f481541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7ff71a8e3425109398a24da639a7dcbdc1e71577e70d365450b70de83dcf85c7e9a0d85709d162f0e128c645927992000000000000000000000000000000000614acc3718e72bc66a05d82ac95ea075ec41d221f96c048c14a9014bfe42a45a69c6700008642cb7483d4f244d509ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001078b6b35e49e611bf9d67b968e3a6c28cd3e7e1b59a8b0ec46ddbe5cfb9d5a8809a6dc01bc73650c4aca69f76b910790000000000000000000000000000000017664b3a857e7a29e33425ab6ec98a266afc55ab651a16b28dab1a06efae658324a3e5b102ce88d626a9852aa9885a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014a2f92f7894885341325ac05e41077bdbf2e28630321a12114a51e0c14b60a0fcabd1c75b9e046371b3ef78063f4890000000000000000000000000000000011b6869aaac4888746fb0dacecab0a1aec4d8bfa27703eedb42eb0e84713dd1b45f12c7e7234ef0c2f6366ccc25ab4ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f97a6aa9011f26167b9c62a1e626c7b334b7ebb28d1269dc669aa7a01c5868dd0eef9ac7a3e3cd36f7cb1e68a11dc4000000000000000000000000000000000098163530c5a14a9bbb7e1b321b1a472a6952d460641b0e4e8eb3c0cb67ef11254cf1683f317fd96e6ffefd3d05a122b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062a8771b779aeb35057cfea02bb02078c24ecf57e095674264bc57ddf5c69c731a13bd42f9aab01b9a3f4444f42c15900000000000000000000000000000000003191d8978a08c7cc46d0bb30078aad0438c62f595b5fa7faa1616854043ad860bf60f3e936c2b33088242db480c7451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000080473c94c5f01c89e45e5f335dde2513667bdc475a96699e5e3800e4995260f19b0a6b6a2c8b704091245124c2c32a0000000000000000000000000000000016967f726ca770c1afd2f5fa142957ccef96e142684dfd661cb6be0b44db2a52ebdae7d56fb43f8a2c5d7d856a01af951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000082ff99ceff379ff8218af0c2a50175bf45f6dfff618c0de6d06ad81d3ddc0b87f0074592fc263e78ee570f5e76f66700000000000000000000000000000000040cc1ac3d5ee27983cc0ba8e6e7bc2a4af78bac4ec59e0103d677e2dc5a9d0ec35d996ee52f6cb7c8100fec1ea8aefd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000337b69c3ed88acffe0d4fc6287cdf25b31eee50a284c25801354556b1c478704faffe5301c86e3b59395036ca0365990000000000000000000000000000000004bad0dc614d3edf3b34f9fd5215ca88df311d4d5d2b76626f18c215700e93a3f8621ebda433388ec508199383f85a591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cee1a85aff0965a37452f3ed6cc3ee694206d90eb4ad4ca6f859e3a81a8d3eb90114945b18ebe953c25f775d399430c0000000000000000000000000000000008486a2d7cbb646191340bc1a0e470730c6b8368b189ae15e4488e0c7f5ac6bd647a3376c1084f577140f58e51d5d4291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171082ef74fa2a6effcb9bb5ebcaa443a67d669b54ac92490da7cf3b64b8ef97a11cfb3c4f3e0dc76674e2fb4d40f823000000000000000000000000000000000d80e304fc75a29dbb2e4034c77349a8bebefbc5e74b9f73e841ff0d295974c0b6b8648e25c92429f90813a8ab5c71971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005240b23a7da074d3b0f61267c765cfd30cbd8bf9cb8628236c01ddb3ca80032d9bee8a39ba8e960de46fd4202bb908d0000000000000000000000000000000007876ef35263fb808d6a5528ada90e67feb9ae28bc55a15f9bb3c705fa88b1bc5767a843f6edaf42d8ca790b12ae0cb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113e305afc8685dfd679162cfaa94dd49a5bc79dd366724557a49562d9dc02a0cdf838c9f9ccf86330ac014f006f2d7f0000000000000000000000000000000018cb65427d9da03fbf16b87a9585f1c24c83e267e9bb8baabeb092b227ad65b8dbdafd45ccda7751839cbc124980cb431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c2353b8f363e0778a24e4bc60f132b3dc29775ea22bd774e59bc53615413092294ed7e91fa96b92dafddf08cbdc109000000000000000000000000000000000a7a0594bdaf9bc585f61ebc0288f56e539aa5bb3c9f249cc92c2e887541de8f5b5f381c1ce0c7105fc000fb52ae058f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f69279de331740395617d79d9a783bc607f57eb001cb9b28c95d6272c125310c8b638e719f9ff1aa4a06966cf72d030000000000000000000000000000000005d01439809bd20fe32f4c9c643895ef0362371ddeb99bf9ddcffe1beccca3ced30cd56d41c455f88626048870a61bf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001560cf987021816fb2ec10176288624df8e7c3e8656ef06d7b839519029b56cbe0e79210b3491185fbf2e869730efbd10000000000000000000000000000000018631a919fb1254c57f34a74e7b5a8cb2288c7947e91b27c5c6536042048726c45f3a6679e4bfd4f412def2bddb5be341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000849db4da34e073c43cfaf978c5bf2a56199f0caebb2a304e0b6c7f0b5d3123db6f4685be03ffd0f8db6789a18239d3a00000000000000000000000000000000127458acddfb814c7fa57cbc0f7ada750e1093f25bca8b3d830cbb907a2cf00779b243b1d30570f963e8b24a46d7078b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009607dfd042c18ec26e5c6bf7c506997b1859165ebdeb8eba08538085741f036737ddbc2d50e1ff23fb15e3cf91934a60000000000000000000000000000000001ec90855f70d3a1d6a6f4e8a1028077b2994bb3ec2fefe3de2e3ca7e33f2a350a19938c7fdb530d5cda1095fd604fa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0c698ed33d7289338eafed25384cc9c768b4ef066b4fbe92b12bbad8f06a1a6606b8f1ae60f9462ecacac4c84f25480000000000000000000000000000000015fb02bc533b400ff46fea525dbfd3fd4e6d5ff608c72a7b4348b9f99f0cbce400915ff44c5d510837dc4a97a00e8b721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d69285b9e37ac5aa391d85c94d50e72abdc10b68844b9a4573454fdf40989b46d6383c50dea4a9a57984bed006b176000000000000000000000000000000000036470ca82ab901ca4f54c59ce302faadf6dcb49bff77a2ffc9ff9d7205834740572b4ab3672f48e5df5172603640b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067b7a1ef278c826a51a8824235a84078696b00f01273794c19615352302499aed92170d6a94c24dc6967bd9b707cffd0000000000000000000000000000000004e83ac897c5b86ea230614856289639deeebd7f010129d5e898c717a5321bd11d37c39131f43b3913a551453c50de971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf14f770a90fd8ed99556e70c75444b263855964634cd851366ef047596ed6af6765a4811914e6f69a04086384a6b86000000000000000000000000000000000444f3c9d3727c521925ecd94ba88c06371e19e59a868a9611581bc37be2c551cc11882d4737a6723951023aae4bf8c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2958ac971525e879ce4a2ebd5791cc58a0fef2335b70384623eb19554bc7ae4aee87e2e2d82b9dd073fb8a0f6de15e00000000000000000000000000000000174dfa1e2747e7834e394c40a664c9fd15e6f786e0b44374685130e0d26ddba584a798cccf9aac94689bae80ee85d71c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000942f157cf7a5f17eb6b47ea6e534aa4d9d67d546712175f041d2700374192c75136a8ffa43dcf92fd54949a43f30f91000000000000000000000000000000000e03f7a655a397d3958f6655b3b2583296c1ccde6985f609a2a39390a01a19361df6806dc62638ed8547b754c8f544b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a80aed87190677e0e254f43bb045a2dc0bd61fc2ae0bab297fe5022380b275bfcf4d184fda535b87c10d38d27919b3c0000000000000000000000000000000005ddc57a3f38272126b7352866205949c945d45a6d2bcbf1238a30adad685f4c237cc6a944a77a3aa7f1114dee7c96f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000061cc90208a4daa72b55b1c75b4c1dc8f5cf8405f2cb3c6806c96be4564c781fc14c7d848053349787aa2e359a088920000000000000000000000000000000011e89e8d6b4a71b1655bc19fb5f672f04d3a8404b832c2fb8eb33d6788131832bb5be36a968f40c876deb9250db4b1451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001343cdbf82fb20ebe1be27a2cad67d9afba969cd9d4b192c40317de31906bf88861e16465555ae3822b9efffb449a13a0000000000000000000000000000000013d3d4c6ed6eacd34359cfd5ba7528bed76c2e39908063d4e14019c480701e1e81fc3a16441a2376ab639dd65be968f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005281e7d161fe5aac808165d5babc54a1fab2fcde7155e55ec48f341e4cf540a8b3a4045e11ef7554b867725c738dcc8000000000000000000000000000000000b1007db13af00588f5425dc5f6e8ed28579fa0d7e34b9bd9f3cf1fcec5254d0441a48e0de963f79c14f03e6e1a9b3f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b38f227434fcfa66532c445c577f0ef1bd713e16850713b89dc5e884e2c3b22b45ec4d867420ca84539af7b0c66df5000000000000000000000000000000000abf2a4f10097f11573a665e6e9a6b8a4619abd489f887f857f57abd4dc0e9913b3c10694dd34994955e45984c60670c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfd85beb6c67837ef0dd6b9c1440b71b237574954323fc6a853d4332411f97abe6734276367f751a5afbbad694d7fe7000000000000000000000000000000000deaf17dff82f4b57331498a9fde46b8a5721ac130907aaf4ff5531576a559581c22e0b2317018972ab2422a7a4fb3b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001336226c03b6a8c33d245ef3396a9310ea244888ba9516f7780e29c44a4239cd592a49b9a9851441b11414692185932e000000000000000000000000000000000214093f5c3686d49510ede32f30c1b183ff9e8135fcf295ae1ab44d23fbbc941317db24231ed37965de57fcb72a19391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001177b6893af5e2f697ed6c970269bdd78d8670c76a16c32b25bbfbc56c8228c1ddac2b57fbbf59067703a09d20637077000000000000000000000000000000000e375268e3956dbb16960585ca737c586b8edaba3c194e05e876a7ac0e85250b03389bf7b9fa932e38dfa0d96d2044d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136983a79b451e57aba1533f95b5392e48942cc696b76a338444c0991944eb20b5e04d97e24babe6c714070612306fe90000000000000000000000000000000015f3fa8aedddd131109ca9cd75e82b85cae51d27ad1361921b31e306874cb42a82ca96081e6aa22c47c88667ec60f4f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008681967968f9ecb524eae7b08d0cbf0cbc8bb1b15a3b6603f19ffa6cc406ec0797965fc71d444861e5c5823971f6dc60000000000000000000000000000000013be555d447640982fe2ba6d70426ca6970f052f4ff7214b17f1cebb6233678c2cf0e1bd5f97aafa314006eb3d1869241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7eed07e01a1d8f694c4047e533fa416e6e1fd3595ef0d9d8a971a4d41feb0c0a5f4496906d0c9731f3fa6bf4e552f200000000000000000000000000000000099e0aec238a9eddd69171a1b900bbbefff18505b6c99cab64880a811ece9a2e40e218e73add7a896dfae42dda5c79271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157b503b62e94514e63a42e116d4d18c56641d5b4868950355e0ceb23986bc819d3cf8131a7e78b758b108044021ceea000000000000000000000000000000000d72bbdf710c951aa5ccb5964921402ea2af032785526d4d3811421569fd68bbd847b1e543eb46ef8079939373690eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a194a6a568954535675831a5abb985b26d43a95d0b402e08d606da7c1839a10f7df47c17068091959a40472530661d00000000000000000000000000000000003aee80180f519878e5497ba710aae527c95f5cb5fcd397a0583945fe7003c32020386b8d375433951ef7e0f02d7a331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002faf84e2bf58f36955eb8021490b3afe993a1651f47b3865577030a6cfcfe77e6e22468747c0f9aa274a97bafe1026f00000000000000000000000000000000036c77fd13205abc7907de3c3bb096f19e4933edf2dfdf03c87e49b31aafe37f915becfbc53df5fd7ee43016a8e59f081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f973acd8925102d61d27aa26e2191ad34fa9365b36bc756a6cfab46accb37f8528263af2d235b2254a62c2c852024b90000000000000000000000000000000000fdef8b926f0b4376b305edfc3e1c6176b7b942b6f9b7859b4b8b071b8dc12a116504b5508c713041aaf95565fa9f011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1dd72e764616adbadd27a35331cb3d50ee56f09563eca95f7f1e5bfe571a2c27734382bf59eae798ce99cd20dda37500000000000000000000000000000000035c82ce3404e583e429e7d4cc67b60dcb2f5174874bb03de494c2d85034e31cef6ee7c4f4f93578ef26066d55b59d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9a56b814a5134019ac170b1f663fa3b6cf873e6171a716812d8d4ac26394b3b7cf2044d3416fe26d90046641a7724b00000000000000000000000000000000015cadc0765eaae272a27ea04d87f50463f18028bda6d83ae771756629341e3e10777c2e94b7bd73bdf9a34d25be49741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae75cf8041401512a35b2e991a98eb47eed7ab28c134b9871b5615a0e70824f0bb2c67ab75a082daaea5e9d1467a8f50000000000000000000000000000000004ae012fea8d12a543d725ff6bafd691eda13e1bfd9427ce3378e0c8c788520ec3cc09bb09477042b588064421c1f3501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073a5793217ec05210192719727737b7d8bee515c7ae7c9756e7988621536edb842570e3eb50c1b80d29e34e0db185cc0000000000000000000000000000000015b36a284108630704823cb7454cde11b93fb15bd5783722b24a0849d8e9f29079cad878c9b8aacd1e0de58e4f8f1eae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b02da9402e60d499e9c9f99398513c9021bc8d57b218586712983a97f1552fce0087bca68a713d6e8f6caf2086793000000000000000000000000000000000164f63ce74c0873c30628a9199063e9b0013a934769d54e32c108db1a0211a29ab393df313fa276cafd6ae460e7da3321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140dfbe8dfd661a89cf924281ffd1933ebb0e91298a95237a2826351c64c5c4fd379333c1dac0ff505212d7cd7c0f5bf00000000000000000000000000000000057dc28ee5eb6e873f63d99379ea6f93453053006ba5b27cc8fab163fff0beea8f4df0b1a9507a277438842e2cf782f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b6768a88e06e9908ba018fb0a2c3969c4c0b3c6c4d8fa53f5bdc8a8d65fed81c085c70b7b224f742d29a61f023cdb2000000000000000000000000000000000652154adca56de5084d0214e30452a0b8b778cf9043ea3852fbf2f16c5c4f2e72fc80adb7fe4eb431771d6e4fbd67ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca861086ff289d51ece5acf15385ad86c97ad01c90a5c7b560c0b1bc462101bcaf2ce5f70b23528d2643c3d4e81262b0000000000000000000000000000000016df41edefc6aa54948c26bf6318e4cc724066a0ce97d749cacedc69916fd42e6bfa081bee18852d4f1d82cee91569781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000381988da7f81fcd5e1d892d89dca6486feb9ebd53ff94fbe964f480d1e89ad0dca1989b0dece9856aa4165e1647ea86000000000000000000000000000000001239b90bd383f4567aa95023475a6dd6f3e3e3835bfb2aa15ff527ac009808f66d6c9024d754401ef7d80d67005ca56b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f14cf5bc72767d734f46e6cceac005a738b33c392c30e1d4485ea2b59f00ae31453c0d79f6e1ed001c86f30e6de484000000000000000000000000000000000a8ee9a019b7c98e3ad496212432ce60b472a1317a33b3da820ed44be6f5e64b978d22e07ce2c044647e50fc547374651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d02db655eca226737c23662cc306a1080809e8e9aacc6f9ff9eb0dd3ef590e982c37cb7d2f297406e094974bb1a72a00000000000000000000000000000000143bb93bdc8c3a7f42cd7ad1786b584a2e767f4e9639d016a359dbe398115f10d890668f462d07d428759d7c314a59871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016ce91ea741313fcbb7fabae6341c6205aa06e4e2f082b5f999077d65a7880fbf082560627dd812ffbccc158afc506c0000000000000000000000000000000014c2e717e327d44b37d23c0742fcb5fa840089d27367672a14d56f91c81408a79d601e122f1cebc8d36224aa142e84f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015565b040c1990352735a43a66200f4eefeb75476cbcf5888237aaeabf09ae2a8029624b0a7757147922fea651132183000000000000000000000000000000000c4a6b3d0275f0df20c49c08e06ef53cc4ae0a4eeb972143d5d8dab7ad66672f2cb7aa87395faac77ec5d7fbf71adf421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b1ded8cef5bf44b7d68ff268b6a4db53d547558fa057c875db742db6b17f4b82c75062e3d832c8277bfa49e8cec97700000000000000000000000000000000163ae51410a68196f3a0de2cf8e18aa5de410f5585c48013aca541fcf1913ffadce664c189e26fd629bdc841ba8404ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111555402017e17769c1f23871d26608c5000d39d2c0bfb8600b996c152542a735076c9f0545ed2bb34023a66d62216e000000000000000000000000000000000e5a4d2e4c16b0fd22508e171e5ef80b5094580a6bd89567e1e1fbf462dc05f43bde98f09cb894734b9dd3da8656c1df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118eba29a94b70d98f7219f93207c4096fd00417fd6e51e3ddca230741e89418f50a6f40ef7e9f1afa80749bf588d197000000000000000000000000000000000259083427a4cfe4c862666f60b01982c463804124f2bd77edc90c6e7821cdfe7106a2db3fe3d633b15557199657fbfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd09354fa5000af1172c7863e8f09524fecdccaf04bd8bb31844090a6fdf3e4ad822e394d8038b5c4dcce74e3f005b2000000000000000000000000000000000117ffd89bc99938120e5b4cd9d4e4a89c87682e6474ee92313f30e573ec4fa85341d4ae1841fa42b9f08d55930a168c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e2c35f5c4571df3df94b52fe383452a7dd5089a884f9b109ea571ac809c077fb30c72d2366c372664feba3fcacc4740000000000000000000000000000000002cc72bb35ad8150d64f6d8cc1bb767bfb2dc758f38ec9418b2369db958c3f26dc842d7b4dc34b159d01cb3498554edc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f268ef7311fb3bc5a5d384b555a07f46e149d56bcc98c2c10b258abab37b7226abc09f3cdfe93ead8443afaca6dcbf000000000000000000000000000000001535429b0269bf65ba4a71dea759ed10e4965c9852d78d361a93d8e35e10be37a4e6bda0ba0b9608f2f7c1da5c8fee1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134b8e8022e77206bf0c0ca2bc1b385e8983754e7c468a5ca82add347f3a3300de5fd5ced9bfa30c79ad636f5b4db216000000000000000000000000000000000a1a919e2c8636c7b7c22485c1d1f2ea513dad7a7ed6922d589687c2d2c2dc81c1c1bb6628aa419bffcd098ddcd27ebc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bce0322b8c3e8efd8eca5837462882a7338c1619d37f0b6fa8b8beec0a36c8375ca23c333af007611285336eda5982300000000000000000000000000000000111a3d0c5bfe00b00442ffa1534b76966045de0d81092516866754509b6a484c24bf9d08e56c7871cb4071e5b9fbbe7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ff7184c0614d51bea355447183e8af1f6635ad7ceb5fbf13fa85d0c536a66bc1df734024de57942baa6558e442810d000000000000000000000000000000001271eb8d01f2a76ed84c5d3dd8873924c45784ebee12be098576f119798a05b1d378659498e39e2d8208b6e64c90e17c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c4dd33351acfd22771ab8981518cb5c68e016fd02a065edffed90564f2eaf37a5f5f46fe53c4466791a4044d1725e10000000000000000000000000000000007a2b508dc433737d96e9a0b0b07208f967ba13ffcf73345ad7b29aa7fe802e3f5988f27d10c6f7d5968d4c076ae198d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b19032e48b8242946fc4dc0ec74ece961ae1dc1528b7bcd6266d9514f103d6f8dedd53618c944d09f6287cedba823200000000000000000000000000000000067fffb43e15d98665adbef2b7a2ed42da2aafddb7acd6e772bfb88a0d1854f5d9c250eb681b3884793533d276b4ce131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019de9475d338fbec3140e2b2772562d23ef1941d8512a64981804e5a975b27370ee1951448645c2ae38c0d43a2b80b4a000000000000000000000000000000000926a23f7a5a7569fe21f528a4c6ffd2d2337852157a07aaa15ff0a9cd74c30801dc424b3859a275db6d6d32fe9775341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198435da5a41a613c8703dc56768508bc0458e649c321774ac459a60943916c8ff8ccf3f50e35dc7d0af45b126a9aed3000000000000000000000000000000000d67d9c15118f6861a6c3863dcd5a9248b65750a8ca30b667f87b392b4c8afda5260f99425abaa997470c8c5cfecf6a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e7af19ffa6231aeedb2fcb9ea939ecce9f4f3b746a6eb455dacc5cf243ed8222e589461a57290d75e886f56c9321cc0000000000000000000000000000000017b96db0698e15efce619dddc805028397dc9f43e9ff9a586dc0cfbae68e53b1e1c8f0be91fb464a62a40a632aaad1371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163b358cfd8ef6dbd38e21f2d00d929ce39f0a4e4642b74b378401a4180a5ac4a8f459faa8061d81256f11aed4d44a9b0000000000000000000000000000000017e6e962ce679a44e31b01e208de3fb0bffbf1becacae265c9ba05d3a9f54700602c013b2280bd179508b84952e745621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003982778c5bd26e39a8c48d03ab310dec6e0f8ef7602c51367afb6cb2b4a452d8987f9541674fed8187f61c5c803818f0000000000000000000000000000000013c483f18985898dc4a691941c2b7d3269e201644e3e2d8eab46f0b5719b1c86b092a1aafe22a440b5ca897048b7314d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a672c8895fc97c85e108f89c458a5f348c0d043825be87e695de4c052b0cab198b28bb9268052814d27e70da297f800000000000000000000000000000000007fea31dbed2776b9a2fe6c95076cadd53d9d7b8cc0b965eb518699ecc4b6b9b6d0e5ba9699211346537e7e1f47af5fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004961904582a05e77fdc99308e72eeed2405751b91e5416691b223b8223d56d9d330e17479186964df3eabe02d5aa60500000000000000000000000000000000109396ac2d77c271179fd140a100826c954ede0a64fe8cdd181231de0fa4d61241fabdd5645b40851247a4d8726b8a241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cfb7f00bdf223744ca3552e82c0090e99badd92cb80aa1729b9062644ae4f91dcadacbb069c0dee4649cc90db00ad8000000000000000000000000000000000f770471d8653a5519028a626c9950cdb7c1b44319db4a1b7960cdda097c7f1e4a0bdd17c848b0f37de4b1dfceb6bb231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001181f10f6ec9a923ce8b541b9c9995e44370ce08d9a306ae5a5610beb5479e0695451fbd32f62e68f5f1f12eb9cdfad3000000000000000000000000000000000ae57bf8835e96ed4694813308fd956b58466afbce9cbb5f74044a7e692efcab08d5532ad4a4ff9b80a8fdbfe609a06b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050ae43d3dff192732ba86a4bf81694ec7da667d28c7f77402aab3d5c1482184d9699b4bbfed8e9b25e7ad516a460c0300000000000000000000000000000000123e62c1f38d91323869f4d3fe34a04bb25877d99be4255b6ed30a403dd0041f80f081c17acb35461475059ac3ff27301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eb93dbb12c3c980c815e04330822bb70c7a24b561796f23f78ddb46d2c7cb47bf5cf15364a5dc85453df65dae8b4af0000000000000000000000000000000014f84c88935234f762853bcd7ef9a0cfff48f53313c5a3f8589a7074a68e0f188a1e77665759041ef6aaeb0848be32911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061971f6838b1f34c16ea34ffabf8305f9f916504bbcdc805ccb6118f09f9d31b41fd95b808057eae33c5efd03aff6bd00000000000000000000000000000000140326175e450b5421e436c618954d500e381d9fb8203040cf4eb12d93f8d2ec611142ecd6d2d129dd9135f6d97966c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001288c6c7bf2d17e6895605bb024a1745f0da23f96cd58d387210f6dcdd55b5c3ea23c0256c2400644427f8b9ae2d0c610000000000000000000000000000000016489d0309343d1d51783ba5f081c5c8d1fd777c6d8ed94f8949c888885a67282e7be0c23c564b0da4a9c10d6939decf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067143e697dcf6f53a4625cc7ef96e9d2e28d4f96df8d0f05f610680e2f59d7bd84f860ba1d587d685703ddfd1cedbf6000000000000000000000000000000001634ee51d57d09fb0a7db507106ed32b33c4889bd5e2cb7bf957b59376f36257ae9aacbba285ef9b69d293790bf2420d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001173d8d477d8128577bc340d8dad93f39d1335689332ce74d422ddf3e389f441172b5aa7cb065f7fc2a136d4f10fe5dc000000000000000000000000000000000dac65b4635f8b9a23d8ee085c4249959caa5ef589d08af377fd52519c380187416f9817721a998d815bd56bd4ce8ac81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da5a804e186ab01afa2d1afafbf0545c0c099640a35184cc1b74ee5484b97f84f7f607a11d5d9ba5bf021434ca7f0c500000000000000000000000000000000021f7f2bc9f45b334d5dcc8017f69506cc0665a108d0678f6a6e4bb10527a7fcae84d69a790fc370654e8ff269ce255c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f3c07e0ddbb10ef130ca1c08adf08ac8f12157f6803720763b7d078e04d15294d81aeb5469c270dd365fdaf245be35000000000000000000000000000000000977154c1c613f042ecbaac9e468aa306c94401631916fc6f14c192cf485d5d747bf74f8863f6504b40c4ef32fa6fa841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034950a6299de7869518671a48f1aca471a132b3f6a1bf1ab5b6df7cb8c942c12ad78c06a9048db77084c5f89b17d842000000000000000000000000000000000c8d0f3daadb7e3b6976e959db8395df1f93b4378531c0b05a88b59abb0cf473c157ca67e92b09324497d176116ebc281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee9a9a44de05ec357ca6adaa942c34f56a90dc7c234d1fa9c34a9623293b8a477c8fb3bc05b35b2b5cebf3e7bcc91a9000000000000000000000000000000000c59071d9d32d6708fe16cc46ef1fecde8a30e62112e2d167e44caba5be0a39c3fa16407b3d9c48a9f7f22a7b1d8f8db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6d21ef7fb71068f8413031e2857705266a7ca10ef31000e6ceea839394daade5cd002f723d5217b29797c1112ce2810000000000000000000000000000000006a183b8b3edeac06626ad8e71b3dfd0c0661bac5c3b504b5a9d7c3e155705b4f81b63048332dd84ba1c48c61411b50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9dd221ae813b377940501d2ce2f11c5ddf71291cb09db93649731a1546d4ccacbe4d37d2b42ff138591c93b2c0fac600000000000000000000000000000000146a68a64cb40561b009460c5e4718750ddc4c69894904c3727edb63304625ac5cd82b1fd17da9a615323b83754f11cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c62538f152f1667a876febf1ada00c5637c42d8708d4392aeae1348aa0ab61cc7ece24d267eea11ec5031706dc08f000000000000000000000000000000000af84db236f098e86f48513c59402ba602a5793bdd72506e4eef7bfa4c728a77e2f4bf3ea54ace5665470eee42c3320a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134ba12e9d1c3de55cbfc5d796cf5221ef0247b381041340b119467903451da8c2d6e804dada0e4404c4b971f4abbf040000000000000000000000000000000006ff6f235cc3481d0d12c15a287f2f18823a118d0759255d31b8ca5bb63ffd639d4643ce4afa81d425c16f6031bca94f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dd3c9bc3ffa9cf71747c3db458df73e2df00112e636f9d02cb52153b36d3a165a1ee365a46e097e75e37e5da16ffcc0000000000000000000000000000000014a44f2c101277228c82648172cb51dc312c0af0539ae10f1ab81205bb1802160baad27b019846b74a90342ff11b587e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cef9305320a13c43e7c30c1ebd912f955fd910ac908cd1e12dcbe74c453317bf75c07dc96fbb1d575fb0a44ad8a24d0000000000000000000000000000000004199af2e5e4256d4564321a8485edd408cb9d815fb464e3c39cce49687c57db15fdb93efe65232c7b438b4eaf9a01a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e79c90ef374b5638415725d017038770d2e0fae40071d5e8c0e98722e978a91b7a93f0c034a6996b71cb008127e7d200000000000000000000000000000000037cef266b8bc111df1aebd1d10720964cf22d3195ed159d196011b31c1db45ca1af7c95dd7322a2682d6efb318c0d881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000348449cd3128ea7dd0d213f7ae440aa86527005bdec12c7e6812978b6f2f032960bcd8d2d5c4918adf96482b7393b4000000000000000000000000000000001682d3a0960e3576a797422ef9f0003c11e8431e091ef61d351940bb3c29eb3cb1dd1b8d13573f560d81db62d53d81d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076564c3a5b234db1fac5502684a243b92951f3ea7fe2a79469e42659f9deada85b0caf8a430d5549679f8063193ccb2000000000000000000000000000000000c075116f67bbfacc9fedc448846373e60aa845fcdedbabf4dd1e59ab21c7b1dfc2e3c79c2f83466ed173d90e987945e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aef5921dda01a4932549f1be9e672c7cf4fe12391f3d7d65588fc784239c04046ee45b5b487c2e7ebd925586212862700000000000000000000000000000000132a795da61bce017c6d42d1e7d0cff770533ea34bfddfa595d4815fff9fb24868b31bf7b285d3900ae431dc1ea66f9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095def14fe363928f99143a3fce9b30a2d9ef918cfb6438d45d062f2a2208831f140d0a01a8df0eff16bdaebee2c381e000000000000000000000000000000000555753aade7c4d315b41698a332ebe5a2d641e137442e207662b040560c1690095507cdd06fb2d21a5f5167286249d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159baa6fbb096b00e37d96132e8f9d9bd13411064068f00dbe80f4013067aab9daf8e7c9679def5474a7a834edce945300000000000000000000000000000000164cd5aced892f0fb15107bba0ec74ec0e0ee5ce840d475f9b040954a8b251353b1ee65341ae7638d239fdde0e427fb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015122e427bf409464f8800c53e7e8c3364686fb16b74ae9fb9849b99e17e441e117542c8b6afede418b6e86d29b721bb000000000000000000000000000000000280fbc214383bdcc914e01e3b74f65f7bd727e9733fc9b93535a49bcd0e7c85211899410117a4295244a252d6ac9aa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bc7eb8494fcadad967ca6cc08c892010844f332d0cd5d94e1c524bf669d749945a4dd178b79da9232cefe11c4581fe000000000000000000000000000000000eb01e49dd39506fb76e161dbb7cdd06370251ea9440693b2b846eb14ea8257095ef1dc2622c83ceccbba6e70475b2cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000149139a4838fac0be1067caf86a25a6e81c3ed6da9f97088ea29d15c207f9a9ae1a15ec45c88777843f8f1eafc36ebe000000000000000000000000000000000fb6a2bb465976d195127144c65a8f2ce3ba97f1463279a462064b5bf4b15d1a4bbd0524a44e91a85b5d44b540abed1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186f73854b56376c2b04841ca7dfa3521b343e20431c062c59b86ca95ccee0408b738837657eff66edadf897e62767b9000000000000000000000000000000001102c16a2d173fd846aafd58061a0ecccc6623e7053668ddee19d16882a5447b2f8a4c1f1bb50f39eb32844e515ab6fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041710297f5852af042ceebc2ba20787e23ba01c9d3b2d68b39c8815b15546eb568c864f7915108af2fa8101ce23b07e000000000000000000000000000000000cd20c2799673d5ac0bf0dd65baa3a4d7e9b5602706c37c4d314a021a23063a23804c500b74a12ad78f24ab2608c266a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001872406aa1b865bc76f78ca5791f5d8d7a78ff7d70538bfcf2bb39287605eff6212e1c7f17dddb4a85b7cb9bd8822ebf00000000000000000000000000000000147adf16cddbe6ddd6209a346b7e49ab2556888afc33c9d91d6d3ca85d294eabec0c84c6941e6ac0c1f70c96068d11751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001909524e6f6b1f42dbeed9f59ae0e0864b406e8119ee44c090478804d71ec330cce73cda0b40c5146fd7322c3905f7f100000000000000000000000000000000059034314201a64ea473b09c6442457fee247d41c7754044e75a9194a4790e81db29d98fa6c82d16302b9ced99571c7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad15d0b44530feab60b71a19fe0bb727e659215c1ded76199cf9e5fb1d453ae601680a3bace44f6aacde4959e4da77e00000000000000000000000000000000111923c739a04757e764c76dca1ecb3dfae924970fe6319499a6d8c91ce3188fa13dfe678d9362135b173378f1df724f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b3f097a244186b753a9d34aaef666fa743e2041490646cdb29061a89d33f86495ca9b4d8f26338862336073946f5270000000000000000000000000000000001233915ee82e368a4cc8c4cf67934bbc395cee6f9a07a82a5c3aecddaa572718c9d0e8493633c16fa8f972145e7c6ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a31c45435ff67c4099fd83361a39b0305d0ca1ac7bd983d09771dccfb32b94663cbe3fc047ebb8a79e86134ffcb89620000000000000000000000000000000011c821696d0354b0baf60435b3ad4f6438ac190ae51b50f82690bcdc2b985b3474a714cb02cc74bf7718ed4980b722d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d091faeda381da24c2def22facf97017584c7dfd81ef91480f5c91e8d0467680bcb8f023bb24d53ff5a2a68f394d00000000000000000000000000000000016792e0773a52b96040694f1d3a9f9011ba4c8b3d48721514fee4cf880c7d2a4352039419230946d1ebc60a9736603651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea850dd323aae6b4dd6d61941e794a6b34989a0919ad97cd8a6ab1a3a999e5b26286350e5a5e25fb0fd1a1fb8a527950000000000000000000000000000000018634e07ca25c44acecd037208f50739a44c80a76a414ff0d47e4a71c4538e8d43709355c06d12870fc4cef00077959c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006154e62de42b06c9afc6c46ac15a77561d993585a6dea18a14eb86225a16d7a1fbdfae1eb2306af002203e6a8a3432f000000000000000000000000000000000007bc550c4dda3945ae6fbf8b58c6b29d4ad5f70a9730fd32a01b69e1d39e79db4784160ed6092fa4ecf48979bd22d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000431fafb50b9523931e298cfd766b6de0e648bdb09f76d5dd44e98920209ee10ea1a3fc573a1c54c033c35e1c73c1f2800000000000000000000000000000000083761021f9ac8a0870f733fe5b4466a31fc585bb32f896f6b738760bfe8a0c697948b149ddf741a012a0fcf21823c3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b601a79cf2ae52e9e1424a4ee500d822272fbe8ae2c822f1229e3ecb80420a2b0176f38c40a671bb56583928e34dc70000000000000000000000000000000016fdbae8996fe9c304e818871f8936d71f899f95b2f7a062e4144f77493342a8345e302e0f9d44ed099294c3b68d78a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016269e9dd8b57d7a110929ac830f140b3ab2f30d2b346aec59cfa113f5465c1e03be7f247d67deeb391b41da27645af5000000000000000000000000000000000ec2b0d198d3b587ff08cdb1f8094728261c41bb9898445ad60274c1c470c1313322148699b2000941b77b915f27c7561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c30d2b3c76ec35bc2f6d3b2424973c8dd889c738aabb03e4e093cf3ba2644c2fc5e4b11c36c6465880d237eb43893e000000000000000000000000000000000b42a51fdcc4a21fb78aac34d4713ae019fe877a3a5b519b749d8d04c939e92993ba1e292b116afa7cfbcaa653c5a92e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017430b1e9f9b4c3b0ef8cdefb3c4e8ace13b1d67f34fd71fdf9c2a0b278746ae02c204bd44a1b0eb3d9442c0051dbf6a0000000000000000000000000000000002486b308042995c6e184a1b7109a2e5b3a5f92b0dea150851f3b356eaeb869304c3f2afa79db2af23d462c1e831f3b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5cb8f1716ab70ad41a1dcea28fa66550b85b1479cc9051c1382ea63fac7e60b442a03d852ed7e770c678e41247b33900000000000000000000000000000000045e9bec29fcba13ae3db440d1e78dc7a21185fa0cead088d178a1d7aaf4e2190bcc31c670168b2fc537c953a20e6f081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5ed9dd21461ba501c0d18b5d4d43aa96603879c0a79600e0fd198a6fabe8c999f5789ca4589a14370e541b6e8f51760000000000000000000000000000000010ba806a2fa9490137a2b55e841b8345332ac26a690586263b535fb6c7176ccfc942c723d4e436f23dd4ba50dec4d37f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039f1b01a5a22c1269df77611728ea829e6811ab50ecd3f6983a267d1262833d659d0226f8a806ae14c5a0bf093e1c7b0000000000000000000000000000000013363b08b1695a5275acda5d651beb16b32e4128728c4fbb58836b98fe4f324b5aecf6f6e7699131df3cb8fd400c1d331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130d4b1fadce27ab8f6f79034a0da0f1facbcc623e4fdfa6a321c664f07e2f7f8e5ea979a484a960f0f9e2db27c459f900000000000000000000000000000000024ce1ab7702c712d8056f6ef16dd90e798ffcaadf5c34f26a89e12a4a9e4675aedaa1968f64188ad89d814680b6dc321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138ebe60328cd8677717608548dc30b1454023ee3b11d3939f9d8b053d92dd1b0efc5967704fdcdc9ee7df8aa45b997a0000000000000000000000000000000014709e5abcd566343ace59443ab7bb17b87f5e2a8aa5c638869c51b26ada593b5fccaa62c63b9459783e2fde2f63182b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d0d928b383aa45cc4f3626789541a2bdea9f5ae0561e70bddd3f12fd32c1f2c1d364cb76158c0a725840dc91b884af00000000000000000000000000000000127c7434425891242e174239f35768a8ea53e2366670ffbd4b8cdaabbd506fa65e7cc8f0ef5eadceff9e4c4ff4f9bf791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3361bf07dcb795ebe86546a0721324c82c190530af4cc0c9fc97e604918a1bb41537c1deb1ef1ae6ef64ba22125ee9000000000000000000000000000000000b0da95098ce9501da6d36692cd7387c76089de03ee7daa191adb2f349cca3dcf2453d2d3a8bf42858c3f448f19ee8541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad29c630ad12fef0c344425295f5a16aabc9b498d14c3a1aaa5bfe243bccde6fe791fcec0989f64e457377e3544d72000000000000000000000000000000000127d93ded907dcd4e422146785bfc7dbc60c56353480e2e8be78d927f53514b8f1915481f86998a177ba94b6d96374911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c60bb2f7fb2a5baaec9f60e68088b46ba854d9f58fe3b413247f76d9ca49d4131a5912dae92428570ade4bf53dbf6f00000000000000000000000000000000003e21c9e5a9132f5b470838f60de7c9d08be400a2d8d3fa0956832f5f91c64aed040347826116547407e002773ca51231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e20f1527781f06bfa0556ed5b3351a569161bff52d5c53bed067ad8e92ed5e0b74ed673744403edb10151ce09aef8f000000000000000000000000000000000913061357c40e0d396e7bbaff74999e64ad7bf31087a1bd0227acd86dbf6a5f981635a16f447271d58762b039d689331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188e91ad481ef0781e04bd123ccd00232eb5e6ac9e58c760373409639bd436e7396470fe343d0208fc590091b5ce6d29000000000000000000000000000000000547f95193a5f2b8bf4585b983884a3bd7b04731461c69f18de8ada62457fe4f22b20c051d2edd8ebe7266e0fdff435d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f117aa0cf2966f0ee0b9f7d54ece6ed73929f5b169717f196189b464a57a89f1a120825f66978d972eb71c3622a14c00000000000000000000000000000000016fe75724404866207758d508e13d570e32b94761b04e31afcdfb6364345b7bf715db3c85e3b1ea0671e9e567e8b1fde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002922a91387620faee87bd78f1b07696833cc1ec8787f57bf0884f5303ec5450e8244c9b569e35849448518662ffc045000000000000000000000000000000000f729ae44b8d3e76e3dc1ec52d8535b207fd6985f744f838630bbf9ce981b8568e90320c2b62fb0fcd284c647a5f82b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065234b9b0ea88385aa4981614c43fc02474e366ea79b6d215a922fdacef636bcc0c6fad70290c13ea4d013b1d4bec84000000000000000000000000000000001690f45936ea704867c511a706beef775c0df83fb39d884270bd0a8cc3b42ee350c6f08a4cb686d2ad35fcab4363c2ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f51e3c9f6c5eed3649a163c4cf96cc90e3eecd3777009460dd45ab93eb01f07f622701cedf638372c60cd4c6a3a92e0000000000000000000000000000000006f00e044efd13dc533c8e89d21fe78b927fda4752afb2b6d992965934892431deae064e6f174f27b09b66c5f8a0870b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124797f909dfce31270ca24a725771d56eb1e0e728c5ae10043cbeb9990f0d8b3641629fdc6e660a96d15fb5e41425fa0000000000000000000000000000000016fc687d0d274e36cbf8fc4785a8b9733c9e478254b97ff569532ff68bf25eed08b12a88043447082254ea01ecf2a03b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001980d05e67034a5d7a79fcb8d5afdbcd1e4a4bf8d98020bf9fc36513a30ca76a3bbd702f51369887ccb255a395a5bfc3000000000000000000000000000000000bf80f58f5ba700f4e8589c98ac00259a2ce4dc205bb739ee5e338103970358b01ce10de4c0d0c940f131ad8b1e7bd0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000651d2421317cc74da93d1052c75eb3e2e458173c06bec03c37dbfb7d47a737f11a77ed240cda5ce3634e53f6cd5a6a0000000000000000000000000000000017a66eff7687bfe8d797054948e813f1c2a7a53fdeb2854e8aa994f825c0a603f973e7a6d1a890ef4e8605e4b4c501661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159781810a404c8d3b9dcb3509ae01159bf2f0c5ec61e7f0ffb76c970624d8ae678d157f4e2c37e2f256b4875f65c9f6000000000000000000000000000000000c00726ec52b5a20b5e02f3b8dda399e3bd0b391c45e84c0fb3c1cd2dcd6840317295746904d2dc3a90ebd469e2487901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004080df94e2a441b9efd78676cabdef959b0124654f1ee9fe82673bfecb7f80ac7e4f035f29483bf03adf3d3e024d02d00000000000000000000000000000000020dbc0d81ca0766fdd4f1d75664cae542f51d1b6ba9dc8677e6904f1bd8c299ce705b954243a3f65a29a7ee2d37cbd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001089230dba7c884854c8b34ea86cad56120943a6f8093c179b1c88dc4c8c08f11941c326850accc2cf7cea518e7f9dad000000000000000000000000000000000e1f8007880c2fa48cf3d41689038762ccafef3da51145e93996796ca03f834c6cf42828a86f0c10130af6dac681c74d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a81d326fcdbb4874c155a504cae5359252ea2258db77689e35077a107be2fbb5e60ad1df002bc4da1084b82b90562f000000000000000000000000000000000e071fda83ff48ec0c69d236e09805b7a3de4b070728a8d7afb2aca801a84fa1c302bfedebf6c495ccc19eefee80acd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bc01888dd74bf1d579943d73f76cf9168574d2ea781a56e8cbc08b65bb0f7e232c348514c7608180058c79f47ff10f00000000000000000000000000000000085482021f53a52c5d74eebc1ea9f6c2fe1bae4d53e50a28953606eb0ce938b5e1836322241eafdb359361dec6798fc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b01008d2e02a255ef7959b45a2579bbad67d35577602165a72299cd8485119bd82380ebba9b15b96d7ca4e3b7a592db00000000000000000000000000000000051fc56ad0fdee44e7547328f7bf8e0a287a4fe12e327435f8b9b0b3ae11e9de638fb1cb31b3f2b19816720100ba5e0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000961322e4b85d3b4fde11276fe55f2e01f9976d6a58c256381835c7c9fea455e0ee1ea92fe96a81c4da1da26d086396000000000000000000000000000000000023a842e8ee3faa1fca123e9b8876976c6b69e755937e9f48d7e80b1db75e49a059e0d501a96b1804f7ddf15d29ffd631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3aa4b508ba6f3b6a0845fb4b99bef35e4461f889196ce8801e20841c71e0809feeebb8cc8fd38a9cef8b6a02a3f64f0000000000000000000000000000000016b8c6b52fabe93f4ff7975f23cc7da6f636fe53bb8975ae8a5537be5d4942097fe736afddb95b277260f497d6974f371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001619a8b47a41a884ed2506b59a36fe159a8dc7eb7818552d66f1d1694bae768ab777f81a5f64707988327040c673613f00000000000000000000000000000000181f6bc2693b6685eb2464fc6922d08566807f6d4bc406499ddce894c69e50120b3c6b9d94c45aaed904965dbac5f5a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f6f479610757747c178a2172269f03950e2cbde1aa4d0af3828ca5e4ea3cecd7d0b528b9f94f8d9fe97cc47393b4fd000000000000000000000000000000000553a349e029b92f9c95f1653d340d70474fad4b5bb528a071c9d5bb1a1e95cf7cb41ab5098559d8076bba343971bc121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001167989ca880c6a3221193c533b8844cfae51f81c16c9cdcedab20f1ce0e0b11b2410818ac0e8be12e744ffc8e51525800000000000000000000000000000000091d88c66ad50b30236859b29a1c0ada236f78525513285b4f51b35cd3cff3230591a8b77315ae4553f704786c99f2ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c917aa064a321401bff66177439c346f8019b99865c29a0d1184aa5ed2de41af31b1d760c151b3af3dc1b6d35134e88000000000000000000000000000000000c3c4b5d56594870fd8628ee8e1dc6a591174c424583f724d2ceaabc41674d182fc5a0a9488b30a4d3ea024a76495f591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a536381edd5a87ab8d48d5b5e2d126a42de60d686eb956aef32d3b887e7806f8e9b6c632237255408f0e961db05c8c000000000000000000000000000000000582665bc7cca1e26fb5f6c1115600cf6c8312d53697a521bc4a63f51a8556abed1773c54ce4fe9342121245f3fca2311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005aa7ddd5c99986f09e515c5586de6a414135f25356f79d8f20b327e30de60e988cd68e4780bc35db73a2b22012da10800000000000000000000000000000000111ba3a532de06535a07f4419bf56cee505a7489cb86fc84f10e54b224f0874cb1e66eaebb0283823a2c5cfdadc5a4ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dd714e2f323b8fd1029b365c00641c8b0beb60a2a669e75b3cb28e712d0c7131c2c21848261930adff3d02d6e7e70b0000000000000000000000000000000000cdd8b77a2a1b1c61690aa7cba2a578f839beaddf25e5ab3fa6298035c34abda3919a38e6740da471ec8ae6811222af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dbcc8e2289a220317e815b104172cb2e109a7d227cf6b03fa0eef838059c98d9c5c127c14a9af4c2c5cdd015a36dfe00000000000000000000000000000000194ec626ce2ba133e837d1786e2e619b5d1d68b0a5a3bf9faee959880cf60ea2cda3ebb00d30273f209b1f34a0a507d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e422d5adcff6af64faa995b59de2af18d10b4f795c93cafdfb2d9cc5d875f5d779362db9b178577e4669915864cf3e000000000000000000000000000000000b462b874cd4c1678ad4101608fe07fb0cddb73fb886fa1d3c7916c9eb7dfa72690eb6cc9c7b55b9ca8c111f6ce8f4041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6abe98caa71760196de9ad7d16bc5a7919f7e4e38f37743310f57cf5d8b6dad649dd1c04e21ac7278d31b839ab2b7f0000000000000000000000000000000002b8ebbe772212359a010a078666d2a9f5ec00dc9e6b479c4005b91c2efc54328075c5658011656ca7fc7398479656551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179c842b7a2557204d2943d14ee7aa0ccfae8ca3ca42f22eb8f07f78ecd462c94f9035879707a7b8d8f8c5c79aca8b970000000000000000000000000000000007dd30bd37d3e62bd741dec6f5ffd1f664ca5a3ee3b122f30dfec4bbc519883e201e301ba92aea0c3fbded7c7e8627121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059608d8dc34d6caa30d99c18a262263be3ea6caa99036e67b416bed3e48706d2468a437f74d8bcfde987838c41a1ff40000000000000000000000000000000015d119e2c6099694f7dde1372102cb52d4c04d715c0fddffb34d4432bb211843e8dd11a1ac15dedd03d15c6d5ce31e311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178048144ef4543fbc2dde1e76fa2c723237be6de82f0f4ae366e132e68428f2d4055bb83424594dc23a86292f79057f000000000000000000000000000000000991fa76a1fbb1bba55c66597ddda281d65846c4b8b861666b8e4c8a4b906e5f189a902e2cdf6a4449660e2866dbcd3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014945b7b2a4ac17191517869b021be60d1c6b580aa47ae59b96560213b664aeb980ff40b0ec3f1c74900bdf97e48ac60000000000000000000000000000000000a314b237a586ee94cb23ff60f6f5cabb5051e2e74de45f4463353f085e9e1d99b666822574e1552914a88d95054de61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ab716f50f4163f425ced103caefc1a1d25f97f960246bf9b0e7cb975dea7b28be893ee1d672c2b8c95c1af74ca9cb100000000000000000000000000000000041b7f8284b4f666d3d74f3b00b5482cd5ca8382782f54379f50c8bfec00996d71ea85f77467c83d858e4030bb1e3b041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d27524822be59e0d9308d04ea18cc5dea7570ddd1c787c759230188462a38d2ed7131e7fa41957362e207669692707000000000000000000000000000000000b4e8be6323b8953938f4cf72ce8f90902b057d7e652919d84b1eab345a5a4cb00f3bb8de71c1ed42bd6d13b77b7a5cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007077aad17f5a5bf5147fa71bd7df259acf9a6d514b6b59075cff6db10677e65d166e6b55f0c51fc8bc323034bd718ce0000000000000000000000000000000007dbb66d3e8744468f08d11e719cb1007088a04ddd34197f5eebea5d8594a6c86c087acd6b8e89253838ce17a87fa33e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be958765cf288926a31f7ee36ebb8a0824c7698e1b3828ae0173a000e6deb3447f988aaf4d7b69a594bd26017e85a2d000000000000000000000000000000000f1b8a2559eee674dee0f6b27fd729104b30c9586270944bb71069da1198491f116e55eb76275e809484d65d921a73871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9c7139db94420da23c31a5c8e5ac5175ce9a39d3a60b10ed03e90bcfeb641e43345af01124723431746302085e0f610000000000000000000000000000000006bd43c3d259dfdaab8b111a6ae716e25e32b76d3a9b8f2cef5332d5b558f023ae0f10bc2b982ea509a5c8f989f930a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ce5e19dac7549d8c8be52032fef1e26e0c9898fb6f0fb67ad11577a350af609cad635a5d0c2c6498443221f79592620000000000000000000000000000000010e6a361c4c7c61e2911cf6babc634904dc180050c9416fc761332ef59a2a61b52cae921568840e6561a6e002d068f561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b66ca9887402d79dd08bff64f56d96cafd2ed598efe9324b3a05f0bd4d85d8504ce022a61c85773afca59aa474a4d2e0000000000000000000000000000000000fd33d7006a63b62c6a0c388d85c90562cb995f86e0211e9545bdbeb6e611d81ad6af34d388776757c20e02c3ea74941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7cb1b5896efcd4694c11551fba3f155d8adb936e1d76474f41497d3daa34a73f86d352a281ce8a2281fc7c8b37518200000000000000000000000000000000089c9503bf95ac414d26d55e8a1c5c23a95bcf655ee94ffd3dac058968ea07f30289766ed1ae02596dfd338460418d081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1f97b1fbe4aa7e4de7b859de8a34634e9c0154a6ed19149cecbd1f659791b928cc83a2ef029c2361e51d2e2460754f000000000000000000000000000000001658c1ef72f1f9301a3a2f0918c2eac6051603384f59173465a8819ad6232cfa2f15f52b4ad9d611b66169ce1072de091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da3cc02370edb8ff35edd976eb79148fc9f7a189635bc34af81dc81e1b8349a28c8900ef379ce2e604fb03a04577264000000000000000000000000000000001334b442395a15a5556396af1c5c8228206dcfa35014dc63c3e8e8c14a818f5159b494ce2cd9238bc855abcaf82401001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075052afc243482153bc1ce5a7e2873e785bf5200f5856ac7398e673a53770ccfb1b23f292c9babf3aebfc37a0684f6f000000000000000000000000000000000c92f8a9226c7605cf170b74d35533082780fccd5972cf09ee7a98cd88d621ba3c285c6342f66c44a39183f1e3cda35c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008556ff623981896d755b33fb8419ad80540f3bcca4389f82e9a175a4b5ce293ab5de5aa667140d97d0b6889480a16ae0000000000000000000000000000000015acaea8115744c245165458ba1e6dd9ca51eb47fe79b2320c64f45d31873d66ce5a0c6feb6e7ec67ae0dc5d926a6d841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000994488ce9d79f670a98d96f2a34d38f845b69a859e9c0e62564266fa6c6a98d39817a5fa51881b74faf7817968f89b70000000000000000000000000000000014037d46d79caa3de9236ecedcaf510241699597d0810d0a6453a8523c0adeafd4bdc3e8d196a7996feea92986686e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010049b11484be92516ea8e296da69275d8374d293670a59a3c7569f9ddf376b60e43b31367439613d05abf025b1f295200000000000000000000000000000000097662cd496dc28fb41bbd79072df4539e8945769299a9103841292f35d83e5dc90129a61fd2305f0d294e77867244d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c2beba5335b3bc4ac63357749e865490fa474fdb5061121f83684ca466f1a30287cc9ec3be53f387f0e618a48d954000000000000000000000000000000001258e3642cf85ec56795763a2eae6ecb8497eb5e381f718928cacab2039cdb2371870981a68461d969d03f3cbe0590981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001719044405e8a408ea41921c463b781303f6766b26c4078e092b7b6ae4281bdfd3323e1d1f27b43d8415f1d2bcb8317b0000000000000000000000000000000018b3b932b5e1b5fe1d4669536a069ca130623132e770feaf0670a4f31663ccc0fa1109e6adbf2ce911179a8518e366a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b0949391d2fb9fe822afb0f2802eb7438a1604b43f65e04144ff5d77270e43dc79b91d0c87e2450386510f5008d1d6000000000000000000000000000000000304700ef60f62ab6c64349c92b83102079f98ac56676e560b33bbc23c160f5e17b569be8962f68af873cd967a9a2abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fa75dcc1bf8f93abbe21843891bb6feee051c0fa17d85a1cf26f3d8814b91474b4c561170c125998c00f836a712b2f0000000000000000000000000000000018f42e3dc7b5ca94962d4ee16a791b867ff98135ea2c3c026fdc657788740bfc173b18b08efebc9349243b932d7c34ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001394698e826d7bef8c2ec23e6a919277152020faa1726383dbd9340b7acb377a1b9956e74bda055b9f04f3933c8036010000000000000000000000000000000016bfed5a31e376d1e0b5120ed5f518bc32ffe19b209ada87531a2849eb0d43c01e23a0a3f030af5c462756120a417efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6e86020cc26d0f917b7facba524a8721b944b00599b7b96262578fe5c50b1626b90188876b0030a7144dede2d4aba6000000000000000000000000000000000337cb713f5dca702bad8cd057539fd4bad36c54d856c6d880e0ef561548f54cb28536a285d7ae274b789e1e19d5df271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d91201ce0a03c3d98fbc6e967727176f416f78b314f2ad7d44c3a73d4a017ac05e20a0f694bb6b915b45016545857f0000000000000000000000000000000006ec3a170539000ac9a60c14f3e2c425200e58cce4a15a0a9e934e52a9143c9f68f582dbc493dd52b1647fa82f95f0af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000577a6a28c46ebc96f09ed8f92e0e5cf1aecd0dc1f8acfdab70adbcc9ddf97d1392d211cd46d337605fabe0d8bee1753000000000000000000000000000000000ef66e1dec70cb91fd1f2bdf6e7460c225005ab1d4ff605af8f6beace860d1acb2770eae3e3b74322e512d6416b21a731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047deb34e613e504d08da46bbe0d0863f18bd5787fac9c905bb80ea0aa4ae36341b34b01478688a5c666e907f92c01a50000000000000000000000000000000012fe222d07d73594c3dbd82ac4d5c9043d79772d67553120080e4d398e5de2c608059e089f3dfe2cf8a7e7a423df79cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019575ae5e86452a763ebf49b4241bcff0f0e76eb9cf4069e901f126504bab9cae3dd025310e62b33d70ea05eaa6c006e00000000000000000000000000000000156a6125ce8b1f681ac014f5c7a75e98e811fb25e35f44da553f13b7865d7f671d02e99f0e0c8eecdb811c4bf1c239ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000059353f4b3b39938979692f780bb2aa0bcc26d7ac68d609ef34f17d3dcd8efc84a6ad051aea502b42948ebc6daa3f680000000000000000000000000000000019c174736ee25c2c824ba4d81390650454ea6d1c87653a1478917eccda42bfd6229fc82a7cdf732dde7c1ec92f6206321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e82768dca49536986dffb242eb8dd1ab0475a2d75e7a795d3db8dfffb5aff2161e7c9164af56d277b142fe677379f100000000000000000000000000000000033863add33d93e95e21170348aca83195c37189ea3147e962d109ba7594e0a0696d1666916fb9d1623e843dc703e7801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f7d75f289b19e1969a69edaad7686c49635756f788b9231ebfe0440a1aa5ec0f8e4333d9e0e824702079df354b8c8e0000000000000000000000000000000011479b683723594d64fe0de95b436ae2d71d8e19e4a0680cfde1c034eab1aa007c177fcd0164fdf65e3efd01204f4f461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e721b73a0a7b9c1d2bcac1c155fc1c78fc5156a5251051b3ee7622c2832290a66c046af25cf47d5169081ffea9a5390000000000000000000000000000000005f7b83adfafc68ba7e29fdc673cc25015b57392a67d11eace617b0fe7229e4076064fac9a5012acdbc037b6e7bb2ba01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055291b0d854bd145cddc63048db23570ad19a74748d87165f662ec36620b2992b56df69f729129ded368d64ab3bb2df0000000000000000000000000000000019e2040220d9048e2eca70f44e17c9eeefa3a057ed28065b401e3f9278f10832358ad44b059ae1eb294256621efd60bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d87be06b756119bfe4b7fb882275922fbded986a8e1304d0510a10fee80edd2d6e02359db236e8b414a856992d09ad000000000000000000000000000000000fe56e8e7368291be2e60ff12a3c463485f97bfd39826b1d9876e0a984830089a32334ec5f32888c1af0b02c1362f8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000371d3013f51412b35c361a80d96111d004706a63174ec6c254da3bc73c9bfa40bdf793ddd5658e469c3540e4f24b776000000000000000000000000000000000cc91c03b7246408f709e78aa1de8891b2292ae8c90384b2938135333f877adf0b7e9a712f1c081c556679c9958e2fb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002691ca178725444ae61bd733a806327e5deb021c088c7d7e3a32ffca00251e14354572a63287044f936f1a485cb91490000000000000000000000000000000019bc2760fdefb400842b65ca4f5be87e33d4b035b24eca51ea2ee43df6cd12e93cad90ca73c7b1747372cf02e54051fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd5b5722a43bf8097d7b4f39d81c84465032e5dbd16cbe58a0626b398d199eff5af56af77346b478ba3d2ce149178dd000000000000000000000000000000000e20932d9a58cb489eddad1f666e968970987824846d8a88874f54d35962dc5fb7fefd7c8be1c9ee3f88ea1609814ac41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f2fc7acbb085a7e3740f7a8418dcc7f41b72d79e7f82b84ac1c752afffd088ffb3cc18bab6db1e5a5402b81f4bde3a00000000000000000000000000000000000e3153cd124f94092e208edeb077d9f43a45e8d38cb6952bc5bd1a7636da46b60bef450690c850a0bd4137003c99dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e21f8f69d58edbdc36e496b85ce348613e59c4d2e3e1bfa85fe2210522c4a1013ad500b1f823cdceecbb51968f802540000000000000000000000000000000013b719ecf1e66aad74139e19b87a9401dec4eff7c699116a7fb52b61c0c49e2307b052e9d9e227a929c340dba4dec9911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a66b6e0633171f799c7d96a87c6337d9cbda4b585de118f3283f035f48d5769cf765030ed1ac7bd5feda2435da76f800000000000000000000000000000000025d5ed119cd948f1f07e4d8760e6e4835c4b034e3531a1276984b1741ce14f8c2ad590ebe70aa73dbb5e8084aa612fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100236883827016d7437babd245723a840b89522c9ca73076887571cb55d52ee7b6061fcfab68b2d3d34d70113026b9700000000000000000000000000000000139c3267dbe37bb7d3da9f2018cc99427e3d4d3acc4781b1a7e09a4b799b4044f947a9ae01481c54c57c686371ee878d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020a95883d7c8860415e4309613445372c3ad6386cc228ca5e54de213bfcb570ea0b63a806a444d7aa550824210811fd000000000000000000000000000000000fd9630c7094a8a2d430c45f3221ca9cff1a9bcf9d9725eff9f57cbf8040e9d3ef0b21f8f2454acfdfb09d8566417d251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbf96c729a7433bde8c2d3e048228c02ead5d85002c486f732175599b7c027378cd9276dca7f5c8c8bbfce18222c51a0000000000000000000000000000000003a822ac6cdf8363ee3211060fabe2fe7d45593c1c537a7c20ff675d6f3f9de4d411704d0ba1e208faeefdb3854cd5331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089cd71f592c3580d9fc6ed21e5d5982e99b8729397a724a0b4efa89afe92455a963ac2642e5fcefaae52e0a1c28483f000000000000000000000000000000000f11dfb4943ea9c159d279b36e9f0c20b15802db40b6c7cb7ad537d59e468698d421dad9078b66240caf03d587a6a3a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b7afdacad4183d1d41a3c357f6e1b286d55e5ceec500b1d0a3fa261b8deb6390e861e5495f430d5c7f658e4aae9ae700000000000000000000000000000000123a9c7745cbcb2da8283f8230bd54f844a1e500c03566c5fdd77eda6322b7e96d18218063c4d644ba7994154cb6fd061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ad7ec6006f03def1015a390fb9cb6a41467dc7a1e53621d2b2bf57be21ab21c1b6a1c5aefa7c98d0e5ac813144877b000000000000000000000000000000000392a799c068e3a754b30d08f3fb74b521928ba9de0b1b1e11fdb535e8413b66225bcbb67e5cbfa19db122ea342153dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005446d3bfa284b2abf019cff0bea520134b305a58b6027bae727160fe6fc26493f3549c963ac1596e95cf28147c3d28f000000000000000000000000000000000ad0d46a03bced7335cd0b10e58f19326afc772ad516bbeff11b0014b6576fd938f86fdc9e8d6577500b2b04b13570601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e694e5da33617f95e1a3c5d30cdc212f908cd64e82563844b4648d3fb9bfb560bdeb372776fb4ad2b28dab4c0da8d0000000000000000000000000000000001641d9f620cc262f55dcb5b4f35ccefb98d21b906681fabfbf84aecb92b97091f8d3724086294137e87e5e4a98a22fb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001893e09510804b67b0c618f7aee666a93c2f7851ed26b7b8952286de4d0e011cded679cdb277c0e86a732ec68658ac7d000000000000000000000000000000000b8ee6a99893820a69ca99839ab437f5eec445ca73c69f1dc3bea3e5c9c2ef708a74fff925cc609b3d86a2017f35f72a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004232efc15a3a48bf5248570bdcfa33ab9aa37a1d5b1e011e2d8b3348305fd0fc63c0d9ade59a92714e66f7d75d08c63000000000000000000000000000000001473b1592d73f47ac8d0e4f9284f950b95b2329de61c59d992dc85402f17b7eda99a7b413a8072a55230f38947b340791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fda1c699f7853b1c2d183ab064581b6768b1d58a8dfb1d93d8503f812ebf27739c7eef8460d82c88763f9bf699c4cf000000000000000000000000000000000cd092694c5383d3a3a946c0fcfd9fdce84cd629645cb188c89cbd6dbe6a6d92b476d5b3aa1b7e39c8eff684811f2d111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fc259bf4982df8e330d1a46b4c5e6dd7c8f6ec834015928174ef0ba76f8b9da74629425044293985dca6669b7195ca00000000000000000000000000000000000f24008c365c1e3427c7a32098a7409a75fbca89f13f14201744cfec3a8da8c163762bc20434fe0cc1cb4fb0d9100f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d95b930cf40061611e664ec0bb874a1b5db1e2021de48112f674dbbf7dbb7536d09fae9bf4d04c14a154c440093466d00000000000000000000000000000000054ea1649303ba5291762da24c6b24cba7bb76e219c62fd8556d7d982d88332c93b4078d664b6b2a42f471e877a248831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b9d5f3976b63af77479a42580f820d421266bf584b4b703f75fbb8f189c95749c978a3610ee2cf513c1808d326333e000000000000000000000000000000000805133385f2c55a1ee95d0092cb703956f6594eb3c11f46b401edf9cd5aa0c1b2857dc6fd3faa39185e054b28b675e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008415d387ada727b7d8bd78a24e599eefda04952ef9f122fcaf046e2c3a94b8c8d77f7fa126ac13f375061eacd29c45a0000000000000000000000000000000001cae1db9825f1e38132bdc40728c875d6ce8d7f2c70cf7dd9e17886c233333cb0f5bb319bd6b677044c3eaa10a8a8ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f8ec61364e420302c7b69658bfdbb183acb44ac9185324f715fc3b30908932a7825467b520525b205eedb55b7e481f00000000000000000000000000000000164eead0ebbd34c190e152013e52680b1d9597a01383613a7530600afad000898245421a4c0991f6829cf0a1404df8421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075d5fffa1511130cc467ca61423c22b64221c47c187e2de64d1939d4443e5c25175c862c65120e3e490fcf427c2040200000000000000000000000000000000184eaacf3ef66b2e57657da7a950daf33fd071217009e74c3544ce20dcc96c7b0ed155c34ab3d0d0b137092493fd44511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000763761cd2ebc040b662475714afe908ad9dd5ff8c3b6b5f9fb8e18daaeb157f03c448f1c3de705857c5df8081e07cc9000000000000000000000000000000001760103ebdef4575c582f7ee7650332c5954d099c0c3098322ae08554b8996a51e5124d8f7a0d66b821bd202480dc5101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4240f8dfdc9ecc192e58aea7bb3b5573a206fd26d52bf885d698b0507e7b1572b219d53e6128b6dc7e42b67d7009bb0000000000000000000000000000000016e633b88455b1f07c72f3a88330ba6e8d29906b88b79a94d13af2c347cc587c557ef61bc081c8be5961a7eec4f2d5cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191ab694a3c060a03c63d48bb16b50f7a913bded06f0a98c0a9decb62ae7ef78c8b5908da6691b8414a90a8b431f6e870000000000000000000000000000000011b83ea6dfafc7d0f3e5e3bf256b3be362904dff9ea1bdb84b5e867b7a365bc4ddc9066efe50b01e8d9bf030b38e8e801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171981e948dc5dba3fdf614a8799a19be786a4572cdd9af1e15ce642b3dcc9bd9cbe8657597ffa580bb987932c054c320000000000000000000000000000000014def38bfdffa433746034a44e5711d83329677c1b5ab9ea499fc3caa8fc7ffe1961efd038b4dbdd84071621bde772031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000269898b8cdf98033a58fb9d834f89fdcaee04a1b194c806310846ebf3858718a4647e26ded7826f167e99030239290b000000000000000000000000000000000fc3b57be5af8738ba84e91e06b5a19fc507829de39021a1d15a0d65801a3e222969b53dfa49d7bacd77ef4d8978bb771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e55aef891af94dcc17bc8bb0aecd5310ee5c4da39aa5a0ddb826215aacfecba2d297de893bb06a4877f3b678fc252d000000000000000000000000000000000135d1b35cae63f807483c1a0e20af28171869121fe9449b112128ba2d6080706e245be90d549e9af074289465c0cbb161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000733f487ea1c6525300ee545a04fcd4584c9a8036d4f879c68e980a2672740107e147bad96471c0edca4648ef08f200b000000000000000000000000000000000bc2fd976f9a0303ccca59bbf788bc6078fef17f232aab528d39942aa533ba7405f268d875147657ddec24603275981a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ee05afe992efe78a9a27d1b038ca23b91290b5d4a6eaa871edf410d7b8e929aafc71180e3de18a337c07d5d67b580e000000000000000000000000000000000493ac823d362e1947ece5ef0d9df9bc3a2e57df6654695b47848458e74714be7aa43220460165c406eea167ee6c35941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146cae7828c871adbe7c9aa5072f70fcb89daac458d8a42bd8c6760153b106efa2e28acf477ff927f83b646afbae8ac3000000000000000000000000000000000ebe6851cd81741443640d24c1b3ec264092850c1ba5e5aa51bf53f338dc7b7e03c9053dc2fc2c48a391981bbcc4c08f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013eec155f3f320144984231a7f62b3d9bcd7449eb4e5aecf7834ff39849ebcc04f2e5c2728adaa636ae119c2d0c920650000000000000000000000000000000018c891edca4b070e6cfc9f738223450a8e2ad8d3e79d9fb0d55132da4065f18df688005d33562626b486fb96779d8b8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a87625563e21ff386b5abca07f3cd37da21e7894282bfdbe976cd368815ae75bb316798036e63a0f274ffe9a78f9f1c000000000000000000000000000000000ce9d1a6fde6c871fdd5853b0857775e9f3cc4b2da096ed3c30d03c06cf440d37ddb15277b9a8aad30b2e140d24c5e001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053f29777c0febd658180eeaa3479ef1c4bab87eee206697ffe5f4aa7df2634b659530bd2bc1040ec0531609a1ed7aea0000000000000000000000000000000002b5588b0b10bf9c5949ffccd537b802a850b5bfd01799479a74c553703e96f53296b12a3705419d8785a507e6077da41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff1481cbd1c4fb9352d735cd559f76e0065d7f35553bec072443b06ff322d05c1c22d8396764f63c5b22c87f69288570000000000000000000000000000000003c4bf0361df71bd80a3af7fa8d643003a11cd4548a52ab8556723da25178981f394d541f291a44ed2b1548d9fa229df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005e8c573f9243b489b8e8e6b6e3812c25583b649ee8b360a5f9e1255886af1d2e2d9f8a4fef6e3820cba98c067205ba000000000000000000000000000000000ddfb182115c90b1c42bf5dd55e0a967285393a78d5f536f1a8e8883130295d94036622d6a3fc3a207ae0288336529f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007258cf66474c365868e760e605fba0bb27602cba6714e5beb06ddaad753706762469f52d74b49f928842b61c1364a9e0000000000000000000000000000000009f6b234506e26b6a3b926236b1f19b1657d294d921a9060e4f9027c7110110d356b61fb7afc1564af64951307cdacb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af45c841e5e7b250a99f93c38a0040f504e4208828462b9e1fe2325ff4a92d7a1a029f0445f87bd5bf4553ee799063f000000000000000000000000000000000cca6c197f69648f137b812797dbe2347b27332f88957717cb1bf38a9038d24f6a1c20dbc6f52f8bf8fe46dec59005e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001385b6d645a8ab2e6cba02bb99304362afb60c34f4c8beb423a0720bac5df622776dcef9b9e6518db15d251575974487000000000000000000000000000000000ec28f0df5a3f0c79cf953226916fa2ab18a7f24619fb52a04cc012a3b9ef0849d6fa56c7c58d3b0bd13283b899bdaa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ee7bf8363bfb242a3bf89ec3937e8d1e6467185bbe04b9b2dabab3c95d0434e03afb715d4174e4d40c7b12555459010000000000000000000000000000000009f0f0f086f6742f3ec7745cfc32842dd5e6a778242f2645c315cbafd7628405633acc6de095130370b604023484cad61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eb022fe1f4235672e241737200bf507bf4ebcc842e2685121e4d34fd57a2b3a0c36dbbc1f0bf9c7fed0761a687241200000000000000000000000000000000035f0dac383b53c2d3c70238563a5b12d5b7d9d2588a660146f3ea2cccd330804913791a0a0b19f3844aba9bfe7b57e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000121e1d471691b4a738d8634a0bc890a6bc0d0e7fcf0d85d1ec0247b2975dc168bfdbeb67e20f7134966e749ed255c95000000000000000000000000000000000b04b88658407ba9d620a1212dd38259f927a2cc5925a5e7dd4abc4d3b1b1480d7ec897cb4108b58c12bb95218c16c6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c084b17e9d679d1465d77581f5ef539a896f0592fd3e78b35561d968f44f3929b59463ed40a0419da69e4cd68eee4f80000000000000000000000000000000015bf4506cb7c5a2a45077eeadef73c181e274c524ec2b83f58a54bb1d6e2e98c1c6f118ddd678b0768918fb4c87934201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001538f3284a8bd61b0a2e535f0de9d794654d474ca727377f4a9e7409a53ab2b260071d5e279e7bacbe1eec8525551e460000000000000000000000000000000018ce4751e42dd6b2f447827ed2222499d0e674debb5313006a7dffe52789030c711a56baed2f2e4a4d987cb8955fcf0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154347987d25ab3ac8dd7e681ad5a3a54ebbd4a32f7c8c3e7a8f8037a89ae5acf40def6318a8bffa7bd03d677dec82160000000000000000000000000000000019e06ffd432e00392437c06efed9a39722011984076f9f2b7329ec004e4510b89c4f1847dc39b4e2b61e8782852c0d111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9c045576392a4794b9cb8f3ede03e29b3bc9c6b90fb8abaeb4d7c3266997c880e099d3898adfab85ccce0bd6819e6e00000000000000000000000000000000007f04a9caff80c31d4f71a54755b47e762ba7e42a5cc31e928097f18ff36707df3b4e37e276efb6fbefb2732d5a41bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cb6cc6da249eece1cc3280a670f4b28324ff99312d9f97075e70e403f200e5b6c477f90c3bf9a1e5e3461bfeb7e1e40000000000000000000000000000000009c1246d50e097d93575a483fcb62fd93ec95c48e3590f64d9b710158092fc2783aeca954c740c50f2c4c2f2cb57b48c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c6cfbf3949f43b79c73ebbf5899322697fea7a9be00e7a7351f649fb8bf249769e3bceb37e96f7b7ccdf0725efcec90000000000000000000000000000000005dc908d0a24f37efe63928b60d3fd51eafe641f8baf3d106f94ca7efe0ecd2955b4c2f7d9019710368489cf16cc88711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f51d6c04dedb3ff49704c0edf7fc6f0e4b0f566289841e76f8e71732d8566e0e287d5cb50bfcd7a501b598a4bd852ad0000000000000000000000000000000010ea9f03f57ec7df6a7c8d7af2fe08e24a83f4190adc0831e104d78f664d630d7a30b848fb2b2d69138b46d749704a181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb81fef2df434848cb83ce22b0bac08ffbe8ae5fb21d08cd21c9287cc35efcc26cea01449f920548b14151a0fccefbd0000000000000000000000000000000007d5cf99762f131512eba447944d4d2d86ffbcd9a112367bdd223f277778c9766c891fa820f84dafc1e7c4af7d89fc921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006917b6c8cb8a9a0f47e43946ca91d6c01a321750c40f4d887fe25e5f507f341b9839fd1c80d505212756fd67f1eec3f0000000000000000000000000000000005ba65859db803b2a42f3c38e489c2d90aacca52d1acca6bcf679c87998b31ae09d52126f7207040ca5db9eb3093fe6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003301dcd4267b2defedff1a830eab983220cea001e39c994995d8a8567a4b1cab91b3bdf8987ab627da2ea1bff09246d0000000000000000000000000000000001630301d11df6c9aceae152b49ecabc2ef3d24e092e5ebdc3aeea336c4fe8afff884fb7a2a7882980ef6194e4f166af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f2aae64c08e705bfbf9ce6e909e26c62ae72ceee896605805ca9885332c84888e6f021e29ca3b10cd3206e30199e03000000000000000000000000000000001354494650b81915f2222195196562f6300edb365a98c11a4070536486ab7fd76e63fb0572ef06cd89cc92ea36e0ea071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7cef06da387d0bf821b0f7e423b31ff13532f43843589ac5158ab803984cdc0ada3c3d7c48e575891f458fb385e06800000000000000000000000000000000123cf581408868375c7baa85093d110cb74fcb5decf8a31a79a89112ed3f80288db25346b11f6a8f95eca2b12d0fa5841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b62444c72bb045e20a83ecd08cd1a613833b904561c190f94e36bcca1dcf61a7728418dec86aba6526fad0045f64a4000000000000000000000000000000000a74ce3a2a74c77a2a89b9fa93f462e9045a58643a8dcbc154c7b46a27ad2c0380782304b43e8256ea69b19b671f59db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bff7fb056f35cf0be36ae2c7942766d5d5216bc4aaf34be2e0909a491cc0ca5621a52bab2b30e9282ffc093a41dfbbe0000000000000000000000000000000004d3db82fc2ac58964e66798dfa35ec9c6e3da96555bc81fea825ba3f6ed79f227475e5ea126d34a6e93dfed8cecea591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e6f4e96ae1980526153e9bd611dbb808c8bb5a1181cc42d2c6e74d452b31853d00cb773f7815604d93327ac621086900000000000000000000000000000000096af5bafd872ae25b3bffa7317c2aba437caa9b740659a2c9948f77133f33dd2a999b3c7468e3f57d6d90ea968648621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193bc968b4e79f3c472c68a899301e91a6221f97f79c3ea3b40b7399983a9fd715c2c61ea3639d1f605370f4a1e51fbf00000000000000000000000000000000040419329d26a67f9e22301e81d411a3f848c628aa4c4becc2df3a17785060a8e987b1e799c48f6740bf10f6d195f9f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689f3466d2fe5a0d10398ad7a824b990e595052ce03442e7961733dc596913e6dc84893b64f3eeee5e5bf2b4eaa75d3000000000000000000000000000000000f268947fff9888a352b2f6f3be56f189cd7376f06abab3c1f27d175c02f84c8177a7d246698fc7eae7f539e0a0b0f641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010db4db9c30521597303bd0d09461f8748e315aac2d557e5594cb9eef9f3cef978fcfbb2beb90cffffb8ac3b7182f54b00000000000000000000000000000000175f5aae55bf5b9002eaf184f2d284ca1264ecaec21ee15b8eeda322a362ce1ce1fd787bf1bcb2f952b4afc0ad3ad90f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d45945227b5794ce037ee632fbf3f6409702cc4287f03adbab87951d1e7531170fa60b3ecf55a0a5622b8b86e92d250000000000000000000000000000000005b357676a10815481b546fd62eb6fab5e04c262245d427bbc44763189366f6df0dfed8fbbf7f655319db2429330a8321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019d4c1ed40b88bddad28a5aea556685ab3e9edea9217d97896aa4a66f2e65301268944c574952fe1a13b557a7dca160000000000000000000000000000000001296404d30c977e3849aa239d63ccc2c076822cb9740e9ea56d271ed6ae9c750043950cadade9efa86da1a272c7880991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074c9176206f6dd1f06bc99c4467a381281a2f08d886f18dd43c0b1f0a2a16a3ea2d725b62a952e599f0a12f5eb14d5c000000000000000000000000000000000890188889990214284ffbdc80afaf2460745aaad98167bf95c0a7c446b57cfee596cdd1d921396a301550467788eeb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bde1c5b939147169b4f66d13caa17703521b6a97593f1ea4016638c6a1f8be6fbb600404afb4040e6bda3b682047f8000000000000000000000000000000000442519dffed255edc41d3c3b98cd8e8f596b83fe2e351269a3e87b23098cd6d466df1d74d2a1258b6c9c1ff0d2d5b2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000641ae4bf58740b5f568303660d3a8e225797a0b907e1daa920c72325aa54c8942f4f4473d00caa3f4c060d0c96040930000000000000000000000000000000003d487164d426f3d174fbc7c52cb0cbd6f788fd09959f345af713bd9502b30a4e18392c27fb246120df81efbeba98a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d19381a524d7cdfc05bf621952b5c0915b6d31780e8d534c46affe608e054fd7c8fca0c7952e9657c0131ffc1062b90000000000000000000000000000000015dc43c5015861ec08277c938bd70c48bbd774009b757bdd9759befff8b11fb0666beebd469cec1d61cdcce5cab699cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014edffa83ee0124e791f040b6293875d17db893d35a07a8dc947370dbe568e9ef694b79799e8cb267e7799042faa9faa00000000000000000000000000000000068f6b2d7fd9f128b974222ee2770c0ec8ac6c632d1b86f711cfd7a5c0a07f32a459a891bc537809902bfabd79f692271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fa8717d35099e4f09f9c17684cb8de738638e85a27f00b71e5c78949dc388b5d393394b43bf2c5646be7a7f934d63d0000000000000000000000000000000003481c8de1b4eec441b3ec08434f69ebfb6cbb4e43bb8205fb9b06204909c484e9c3867e0481de0dd60252a90e432a8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5b2d6417bc6fcfdf57ec3902d3cbe3ac7bf1b5df1bdc4cd6131f4f357441c447801bdc8954cfbd5352e16975d0ea38000000000000000000000000000000000502484d6e79dbc9ed88e8fd02183d20e6986ba9d5f227a85c059f7f24281a9fca6c88b9ab2ecd88569473f5e19248551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a68ebd1e0661dd9d9b10aa87354092049e39f1c931f788bba59367242b34405d486fd399bd3b417375b6be3336fc1a00000000000000000000000000000000139a9d5d4139e6dc8e8dbb30169fbab33c7221467a7685177e06ef9e5aee027b4de97b536e893402395896966cc3f0c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1c05be27831199b63cb6826df96f8ef6a4531462a392b72d78f3b5bd9c4b728d5b7dda7c27b6e0e17e48e1199ac732000000000000000000000000000000000d1ceef58aa563f418b3dfc7cd136be359c241e682431734aae479663bdcf1a18850783e4efa6c29774d39eeba7c9e421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104b8cfe6145341aec3bf9a3b45b6e10e96188a55e48003dd6bea09381a662b8ae3c447c4d598a6a9d919d182183a21e000000000000000000000000000000000636514129c6b1b57b39b3bcfebf1642bc813c3355eac48d4c8304a8e8f79434ae996a60f04484184b197b449ee44bc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaa998496bf562a6d58129b9c542b68ab9bfe8c426d1d44ced520d8f31ac45d5b831a6bbd81fe4d6ab2e388bee7cc5f0000000000000000000000000000000007f4d95f1c05c1162b6b2abf7ac64de43c316e8ed60e97ef0bbfca9ca763ed98b5945753e120fab6c958c76d95d6f2411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152a3e0282d47c9ae9ac663d6c293b626a6fa535acd717ed43429c20891f32a1708b7199e3f53ef4b6d2f9ac19ae37730000000000000000000000000000000018d1379178a62cf7d8a145770ffc4a849e40164c3bc7891f6f070b3e706640a749415cec8e16b8427ef032087dcfa38d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001280dfcaa01e08c4d19d1ca5fa0411dbdee1aace0987a2d46d4aece5f326127e3d1f9ce1994832fa2d9f66b0775256d50000000000000000000000000000000005fc30bfa50609e5a7c9533fd782c896057ef387e451c02016e48639f854d4bc486e47653b125f7580b81c2095feed341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1eed0e550e052372d4789cb44aaa5019ab80061b6fe92dd1b31226df08e05c41eb47f087a9cea81d8e3b2abad01f5c000000000000000000000000000000000c7db890f28176e6b4fa3159f513c9cf80a7d29739b01ed05301dd41445b1d9fef270e7e486ecbd2cb499c13d63908e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055e01b48ac35cd63f36cff92ac9a0f9b5ca9116a7eb56e1c60b565f000fa923ec9dd340ed584f3a633515e7d49e05b80000000000000000000000000000000019c79922076b58807a26acf5a36b459fa381ce71a92cb74307cc7873159264c6f687378faf160ddf7db1aa92c3edab6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171022a2a19e1c9d1427fee6177b14fbb36d02749da0f4b889009c66995ac7304f1f68185368a312e3f7270bf7e89eee000000000000000000000000000000000a37bdb345e7d386f2f71331e78298061f82dd7a01257e294998efa12bff96e50fcfbf09fdce5bccb41a8d15de8219091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bfee584bd06bd0745a76974b6fdc2d2fed39b45439390dbf15df98501230a6310863392c6818cfcab1ffd0bfa1cb850000000000000000000000000000000016ed25ece3ab54abae5c3213edc7965543eb47856e2432c2a1150da9bbaa907470a128170c758b7e3d75c0eeaba8edd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d947ab8e88df817e30e9d74559ea94ee0283cd0e818e97365d406f1b5348b83ab25cddc886800e098ab8536d3890740000000000000000000000000000000005a5002f7b4005ab1afbb178f879dceac3f5c32ff092ba8fbb732eaad0e4a60daae78b546a85e6e5dc20475330d0d3611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152e08fc98d15738b3c94fb8d6ee9a9d27ce4757cca0dad46b5af0ce6eea9bb72c8a5f087b5ea16a1fe91ac51b4efcf90000000000000000000000000000000008f67e30596530097a7bd32396468f01b13ca9d2e38379ff4002c03060e4c5e41687489e43cbbf31130d38a48a6496f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001685d4255b9263e56cefde5b9856a406409654425b29435f688564e8058218ab771bc2c3a8021fd5d8009b9d23128761000000000000000000000000000000000ada6ed76129810aa8b5782c8f2106df6dc378f702ea49b1e498c3e430f89defcaadd43093abc3afe4a6e2572e387be41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bad2c7543e8ebc1b6c77c0dc32ad8158698c4ef2098446e8da819e4ce80249d2bfdb97f446039c26b81e763e01a8e400000000000000000000000000000000041ec882d3a7b99b7f183e67db1cebd25d5290548635e456ad08f2af64740cccfa75e562b7ea0279ca65e579bf8e4d441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122fc11abb12abb6198a28dc8302df1b66a4b3c35e8081dbf00ac1d0a53c5ff13bbad129392f8dac47e12378ee9557470000000000000000000000000000000019aa0606f91ee5d4cac1af57aec63de1c3b7f3537af791bc8779229552ddf9076fd83bea1833081f6d80eb07c5139b861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021b363d3731804651ed8267125763151d61ee080da5b824ee27a519511c7cd5ab4bbb19a5399b6d8b4b53f0c1e887f20000000000000000000000000000000004b4542c696d5f1a6fc4aaed3356cf06f9ddc94a5635dcbb6aa14bedea810ec1c3499a9283a25910dd1d190a722df8551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069b147d0515c46a81c98af0e612da19bccb6789df292e4ddffa64e58f21c78b7dc11b78043b052ef9a3986b9d50786d000000000000000000000000000000001248985ccb175c80d5327a80b2767f20859c79f269d9665cebb1971ec62dd3f264a3668a006b030c68b6b415df8201041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d294cf5233db65440689802646a485988568784a386acc8ad44678d4cf65f9c7fc924f0b49e71a531a8fe412aa829800000000000000000000000000000000115247320ce7db88ec141304daa513abf38ea07879f1956cd12fa2e061a02b6c23c3b205b920f7df57a21288c0ac8c4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002859426ae10f57f52cabfc45fa569a79a5c1d41db8be14f408f0b75fe20f79ec4ab9f7504b61cdaeebbbf24baf42bed0000000000000000000000000000000018a46ec9691bfa73c008e62043a33f5a20977c8c9981bf2c0c351979a53298b51e46346243227423865c2b2d5d76f88c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d0f4f4d415be96efe1a4d18ce23d9255c55eee28397db99b89cd6f54eaee0c0cd46f8e81605360347f6bd7bbf747970000000000000000000000000000000011bb8726fde9b35919b981cc97242ed83ddd1ec307d417408ab7aa8be47fee9ad44352d39bb5a48964e4edda8b187f181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005223cbd3622cf0cfe4bdcec522399ea39e1d39ff644ebb9bdee515522f612bee5d3206a12eb95bff1f1a370c50b7b2d00000000000000000000000000000000167e5624fc12abc28af6e4416c339a54b73339e96dbfd2ed1d8377cb273b5dc8c034f4801431759e485af4b1d9e1fcd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001511cf5cd570ed46a255269e8e8983142a0eb4cad944163135adc6c1a883c2f1092ee4fbb8f1213efcd0fc179abd6396000000000000000000000000000000001864300a37950e21686f7dcdc9b313a9dda5ae1886b800e2f9119b5a08616cbccca5c3e374ab08bf46161458b2ff765f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd30cd411122418dd8f058886e759dd595be44b0c6dec724b90fadd0940c47c81c7f11ddd97a4aa6f08a44f9b27bfb4000000000000000000000000000000000e0274d68b9e8f8aded68991271a6a2ca5ca725fbbe4ad42b79c08fd78cb518af381450be413064871354be3f3a29be01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021937d34975bb30958beb45eebd73a1c76a8c2bbc2f2277cd19505b6fe9b33056a815fec2216884aea29370b9b9952100000000000000000000000000000000071d697c09409344406c3f54ef5464e28a31ecde22f59b7a46e19e2599f0e57b04866bc7e482a681954799678955a1e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a202dcb1a878e73fce11557cae947ef4cabd761f0aae5c3a02939a2c64d2e2ccb1aa175c5cfae68ebdd27ce51236370000000000000000000000000000000009f7b6c9cc25f8382e6b6e2e7af60a67edc94169f5382a71eee63d47f8c215509bf9d6ccbd65aea71993a450f8598f271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d3e4c452f97fbb88456308255484d863c3a3dc73895201f2d045c9ce9ab45c28ca90ceff7426653d45cfd7187e3adc0000000000000000000000000000000009e55f85bac752899addb9614bc7264d1b86ae04b72ae2d29f4386849704e10dbad57505f04c9ab599713bf0aac83d901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001809d4703fae998db9f1f7d6c924d59f0220743c7cc7e9fb619641acbf7244391989332c930b2ec37da597c0f56dc2c0000000000000000000000000000000002b147c0afce911f6cdce7bfde143d2504542acfebd8171b6cfae5b7e2e03a8d0e5b954b7d51907d2127e0aa00f44d891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017208a5255be77869e6cabf4e3ba403dafa18ddd9674616158225d7b66600b29c3ffe62119998977532a3f20d2f269e90000000000000000000000000000000008757c8be33ccd5549ba3d173394772fb8922f5f9926613b00eee9e6f9479808a085e94817a3333e5004221dabf4934c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af011abffd18c87cb9812944675637d6e383938d8037c7cb74081c31f2b7f4483f26956ea499761765f38527b8aad880000000000000000000000000000000002cb3c8f78e993a7855d38955e227248c53b3505fd1c64e3dbfaa06900b0c6fa67e4e9d31ed929d457c4b1f5b3fe459e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cbc5a7427f728466117b27932c675f2189f7707b9dce67c2211b3a01be0a732f08e72e3afe69337ce49e27cfa25fa70000000000000000000000000000000010459399f8a687bbe8eb0431e2b56cd7a8f09e514a74f83897d26724f39e653c510dd81fa68d63fed2d21dfa474dc1391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013529d7b13a056aafd0b87c9c0b6ce3060ab6282b63983dc60399ba1d1e1ab1021dcfb7e17f50e4fe69cc2634321de4e000000000000000000000000000000000f485dc475b6e3e308596ddf1b0020878adc2caa7f294fe07b39d4ec369817675f2cab8e2800b52264526e1f23ad70411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009107d0b03f7b51997a723e356ed424c97e32f00e3c06416df0b3051de3efc1e84f3e985063576bfa46265463c520d1a00000000000000000000000000000000017ebd4201600792a47dc8d998daef95e6ba1685214f2b4bf366f21c7022ee588385a41b774d842eb6e1176faf2222361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da2d6d1a7017f43215f310756978b9e7e28375ae0b2000775b1960fe9d6b5ab731dd8ce3fa43c776ccc1734014bdbca0000000000000000000000000000000002e5eb7ea8219fa78c522fd09035caac6b5a42325fd9e84d085068c5ba7ec7a29b2ef197ec428ea3c32fc052e4f3a1e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108370886fc81b9ddf2fe348d3bbc42181ec573a69ddbf93610d8ec20f9e82bd0f8b76e61421601e7db771e58a67a9f10000000000000000000000000000000007bdd99a952a7d93ee1aca9a22e77c0cb01bb70aa3dbae20b434fb3afa18f9560c40ce6a491725826bc4792f22a8b1711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076cb0ca763335e4c2dfb51bf837b96220d5f202138ff070ad6f9608a537c30466681645173596a480a131d4d130251e000000000000000000000000000000000ed26330292aa33499af23596f7a42ca50556f019e553d03439808fd62d4ca56c0cdde8db3cdbc2d56b27ab5b65986041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040eb317415d85aa30cb7b951e366e89e4d45fbf746aa85237f791269f88ea9487aa55da7c4296f15a74411bebd48cfa0000000000000000000000000000000011c15a139b03a8a0150f6233cc8eeaaba450d67b7d8ece71d7533278d8451ce4731405b48f43646b568c6a0448f17bb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8651cd97f69695eebea35f179da3bdf9a2424681f0170542280dee325511d7362be9f82e9dc1ecb4d41d7fe2a5e85f000000000000000000000000000000000ba5af9394a30fa61a9131a9e14bd717ef4e7e29d42b15bd198fe358a5bcf044dad874a14a3b9ef36c3e3a3023bebad91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd4a318b55f7eec8b0a92b9f0aacf078490b495aca0a20fb5269de26e0875473be1792288c205dda05b5423a2ce252100000000000000000000000000000000085b6e3136d2d67fadac25250c543d82c77c0e14411aa20623d979e3b01fe479fdb69aee82eb2f1e5eed06e051a202651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041afbdc3ed5e40a4cb5c680c90649eb0700aaf56dbe18182d135c8f6303b4b3268f0dd83b79cb49e4d2474d0c463980000000000000000000000000000000000c632f6e2020555f1ac1533348cdb5a2edaecdac7442184d77bdfe059fba174ab49f7d971859f228a95c7365fa60aa721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e0437bb084996a31c5c7ec5bf66f6e9e420e531c13541492f4782ee17c0e1d19955fafdaf6f048a78339211094fe07000000000000000000000000000000000fe96ec6e9b20766bc2b3ddc9cb4fc0e7ca0fc6a35aea941fd8dae6be696c6fd649d6c4d25bfb62defffda9c0bfdc8361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f9a9c8094da590d1afe9240f1e6c1d6db9db91da13b2cd2390a9ae85fb0a4b35a67dde3ef228e4fe832dea467132c700000000000000000000000000000000090b062266b500b995195b8595b0782ee2e495cc98b70ece63bd93e232e542e2c878db1b4503aa959605783385c5776d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c00000cb342d7a2f8820d8eaae6679ce973fbd4335e5c84b6bcc1183781cc4cbd9b6915211e3d8f91f2d535c15d855000000000000000000000000000000000425d832f7745c71f63bafe808bc1eabf47d437f062e9c45d24f56c443d53da8f0aa5ebaf6cbf8cc3a30a2d5256926c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7c463a994e5e38684a0cd2e18804e1139389bb1c97f40ebca64921d5b4563f01607ff8b8db72fc0bea52da9d97037e000000000000000000000000000000000ebe549961d8a97189af51a2f35ddb524c9a796338b1815f1df847a71766ef61ad50090416ad6754f53e5f129c65ad991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f6ab3ec387545505b63cf259fdaa5d0349af9f71aafd28f8028c30e3f3cee48fae58a429e4b55e37cda1994235547e000000000000000000000000000000000b7147de1e1b369170739edae46db196d119d44b095b94ea6558b0928fd1e5cf7d002d95b8dafde4219916389c0e860c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001610bf411998c812dae4ce41755f6fa7ed56adba9a88705eda3b6160203e1c59a291cd94814b327018a3b15637f38a21000000000000000000000000000000000299da986caa5f40e8057602322c7fe18ecb9cf4cbf5fa647e9f71939998e7124e35b8474ca809ed5abf8d7bdbd03caf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017989533f0795c5feec7a4d83b335e9c9b83631c7f7945d9fb4f0e7236c6d1d2a369ef2d1bd07e28a69d7ed50dd98234000000000000000000000000000000000cbfab2fd6da7897eaf46653634ea240296832d58cf9a44cc57731aed90cea4837acac8c647dba55a22946ca290dd6c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc8260c9a345bca2b604aad43053f1056f2092a1f6a3e36b64df9a0b2b6ba955419368a8b17ce1ec4e97034b87ad99d0000000000000000000000000000000011c7a849757c6dea736d2274d217fafb010b81f06b424f0012dd788913a73abdc052a74069a7a42865f9db84913774501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1ccb3f1db307856dd21e25a040053187a503118be78530ac0e9fbc4eefda70fd34b824b40c50161f920246ddcd6c7c000000000000000000000000000000000ec433884857a788428b13d087fb41edb292135aee62b9b2d5cb37d15dc9b404aa0cedd4027ce11b7f1e395aa89c7b331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cec8c6587e0c711d3001e7addf6fe7bfe855d421971d3bb5b3896c625fc4ab605801338e0c18bf9a1d3fc7495bbad6000000000000000000000000000000000cbff0998681c7f56512c848065c308e578d33ee48484c8e4ff3eadd2a80847f22047162e243d63af9dd2068a699b2c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d42629c2050ef74bcdb8c02c750217e869a9187e9ad8d1936a3c3ceb6c6546694be13ec615fc38d275fc5ebf0ebbcd0000000000000000000000000000000007a96de8dc0d84835e49ff97288fcb43c312ade8bd068e3eeb9f400658cf683a3a08afe6bf50ad7aadb75da248b2e8e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ae72f133107f1c136eda2e15c99f25234b135a3e875c80d414afce2b184feb2a7d83d3cc612c87d174cb8c45e22831000000000000000000000000000000000b50c2131e1f1141bb2ee355ef49487e2d8343ea51df91b3a2efaf9f4449e7a8c4b420cc10330a14cadc570cffce1ae01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bb5aa3a38b214b4e66a581c7dcd78f223f0a76c075c5bf143b01986e855a57d81e00cd3a7db7585c271f61bc6791b1000000000000000000000000000000000cc4b7f98ef84d87cf5af2272da65fd477dc90b65dcad365c7c159f2f03f345addaab6239e470f9b0c289929118643ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000680364936095da7ced38847860a06daf53d13e3e69bb4a3eda004a166db4d39a150fdeaf7aac055e0850ba20ece1ba30000000000000000000000000000000012cc988c3bdbb8795822268b5d08cef78917b98cbf268585c53f1d4521bced36c37457d7e6d7c848a226227104f269e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ff8a4f6b20d623fa9e2917ff681de301b2d37dd48e32702481b1a3ed0224040ddf72f62e8dd679fea045f480dc0ffd00000000000000000000000000000000196c78bdf3d77587a85ba4e749e3d7eb245abefe6fc099d328c67614da0ff53c1c29d60bd54294fbc803ebe1c25561d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016692b717e655b0f66e5558121c910fbcaa25b1a0199f98ce83bbb96da6ed5d3b94638714fba313130abdc8a4545f0820000000000000000000000000000000019a56dae4705a8da9b672bd35bc8beee1852529c373de4e550fb238ad1999b1dedb5f3932401e6b67d0a94d8a00653331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000192d1938da60d5046eab4a3b26ae1cb8ed807aaaf8bf43d6ac127e67aade117cb6fd0b5c82241581ad8cded5401363100000000000000000000000000000000040346a5b1f695f5b4de133882b9de892ff6a7da483267db7671402188dca3102eaeee7d828f5fb4289608b36d49b8df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c3e30718a3873afc4f058170d371b03b79d3a847159127f07a27a1fe09549404fcc8a8b2c60f7ebe7409e7f2a6d1830000000000000000000000000000000016c1bd7ebe4bc3545bcd6657a72d674a1c7ec041a2172011304ff7655e3545b5d031eac06254c5f8d952629302b690851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010da547a84940cdd7c85a4ce58ec0274831fcf4ec307e99759956949e8384538a83d393e552d989953f22dcc9adb27740000000000000000000000000000000001136d2dd68f13e28d586a3d47ad0446b1df3e9eb1bc962122f34f050da6a0918062e59e61d12e4008d0f0d63d1a5ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dba2206f76a34ffa8e9e3a9de46a226e8c9eee935cac3d9fcf0f72c86dd7fe173049adc7d38724710e0a25907d23d8000000000000000000000000000000000d21be8851a843f54e1b2aa9f8387d191c29a54d6e86baf76c5703c61a2687e2f200e33c48d71a2912f3f4ca61fd08e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002589c8f3fc1ee8f7f63ecec8f46f43804a5f03d900e805040fccfd9f3807a616afa2da6912beb16d5c19f2a7c27cbb800000000000000000000000000000000039c283ba16a47bdff4fe47fcc97ee27f7d60a6e5bbdc9290a7a8c1f3a38c6639e93e9d1e24c038cd49022740a5d9a561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075cda913ae121a30fb8182f0864933663bc49c5ed960468437864b020ae0bec0a796f4361d94f24326191514e4150d2000000000000000000000000000000001339d7cb860aecb489030049e116bcfb2a0fe519e74259001010c4e6a87aa9468701d7f321295c024275766814bfe95f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001102dee9f6dadacfcfd95be363c31cbc15770d5231d6d56fa3fe44d7b66d2f55bdb0e76c3c391dff12559fc8c15d6be0000000000000000000000000000000010118f80ed1e826f81ea4f127777a330c37b3f3cf00895a3d1fddd93f6c384c5f94f7caea6f2dcf0c350b960c796060d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001874bcd13f3c4d0309579d65c63900df2a7b1670da2a994435c5ae533538350bcda11f120aad6a22c2dccca1b1061c8f000000000000000000000000000000000c1a893b0fdc4ace6215a252d099ba97a25b94a9bd3f55a0701bcd3d452b4902a0debca580d3b3035260b656c1536cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc3b8e174ca1787380088ab061f4f31b78c135b402c2ee40a22a2eeb3b9259dc5df933db7fd810182e8c9ef564deecf0000000000000000000000000000000003e232c28195296c6e35d20671488a55a2f3d80da643e80dd9c6bc7581a8955b14752d2bfb14b1db2400f79c3980fe6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a65fa6490c6e06087581a1098d592e871aa199d0949cd6475ea47e22440de37edfaf0a8b3001aba4e40e1ec5e73ebb100000000000000000000000000000000176239dee037f5eb902c8ceb3e249d38baecbfcfa847a96135da14ed70dd57eafa813ae6d1e44db47e89456a2c9e366a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ccd35e9fae2c17ef5700a48a5f69a25e255604dce2f0a522b9b70592835fef4bb8eeb07b987bd5f5a757052a31eb5f0000000000000000000000000000000010f8f19613606ae513c2bfc94e8a4a995f5a5d68361d98a96283ca022a8ebde510948abb133a0645005cb188b41e657c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000776caebd22ae57add9970dc04488159ef860cb0d056ac2492b482ef49d6624c48b9addf90275815fc146f60e5e5e833000000000000000000000000000000000157cc6f6238d83bcb04b030ee0a6e47f64f8501cf84bd0f8b1d8550629c4e5fdfe32b6edc2f6ea4cd78117881ccb63a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a4d7d6283dd4d616d764c5c422830bf1ce59a6ddbb9830014fafe94c1243525623ffdac46cdd57377a5c38c586fabd0000000000000000000000000000000007da883c63d4edaab0e0678ff8d692978b41bfe0a1376a011135270d3e9a0778d88c4265a3c3b7a6a5da45b4527cc7871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eebd68534f5ae97d9361bc9a0b47f7a1cf586f838cd500e6cfffef2a6cd184188651054c0b95404f4161ef779150bdb0000000000000000000000000000000001e2b20e96d3c723e5e099b676081b0308d1f8291e7964fb453c4fe238b33bfcef01e07a1cf4868a37d67ab5b713f1b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001121891c2fd0eac95afd89a470e4a1f019d7ccd0f6908b41e024a9ac80d6c4a34a2d3fb4675399cf8f5a8cc6cae090c40000000000000000000000000000000011c956d02b47bbe2691506cdf82b3d1cf459d1111739ee37ee8aeb5e2bf8406ac0e8f231a518e33a414d4e65ed23130a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ec78804581697c8751930147f37ecec0b08551b956653e8858447c48e10da3eb4fd53615aa5e0bcff5d6073d46a0d500000000000000000000000000000000038b4a3ae508a3d5a076bde92899201b529acae5a3ca6ae275277b0141c3edb6a29f9858d9dc7f8375759ed0d2a2854f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001144b8cfc620339c8494d98448eb21e8bebe865ab935100c9f5d3ea5e90a196a8e877c9b63ed9bbe125f2d252e58fd5d0000000000000000000000000000000017b3f3e93615c26c3bc73db6d3af5b4ef5e3fc14dc833c47bebb82dc6afcae6fcdec1104fb02c320ae699afe8787339c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001872be798aa2001c23d23e8c7a64feb8107b2043573dae31e123d0a7f938a388c318ccdcc2af945a19f49499f1d59fcb0000000000000000000000000000000000d3d42d2d0bfffae378ce72e9f0082157510f9146c033213c30453f69f628ab05e558f5b38346bb82ad5aa52134f5ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb256230e85213592f666da9811e5fa8f4303aee5d2e6257eea078953b19afc857fed4f58296161bdb4321a8412a9460000000000000000000000000000000017d14f7a193f85c47dd9c54b8f8465580abca29e3d3194b6375cd20d065dad91a44617021896ed23d3f4e46658eade2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068edf905ed7d56930bb7fec40f2a5a0c11b18aaf6f7a6b4c76afb76ab3ac0505ef2e54309e2d6ecb53af9917338b0d000000000000000000000000000000000093f6e1c94d305f2a6166722aa08161dc54ba9d08dad068287e679c67716466daf90160b287d6eb900d4e3a69b856cfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ae30f44c51c9f72d93eaa5cb57838e56d6140f39677aff2e42c3d1f7cd81de3f6f8f0633622d562937c0965b206ef3000000000000000000000000000000001772a3ea74093709de27c109469316fe722a93907f52982507c196c4abd62ac96eebcd9ae368aa6f4e27c82459e228a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a1167415372ae14ee91998fabe33cb0f5a45dcc50213b62efa471bb2c9f575fb44e452bcf2c7fe47f8c64955f5da1a000000000000000000000000000000000983537af461d56b68565dbb1aebb9aa4e8202f999f3c2759e806f3e8704756fcafe83626544bdd4ea0f8d87eadd4b211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029eb274de08f231ab4bcf19e35fda133d963dec581c2a35ae77645641b69a72ff79f5d9b5d731a91b6c67e091c0686a0000000000000000000000000000000015837b803439fe450929ed595c8ea0511f49910837da32f2a777fbde95c36c04a35a574faeace8ac44115c63c946de171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014aebc2b7cbb72f6bc5f1472206f635954547c2626c2e3d5eb9da78a281b4124a694b649607f6a1cf4f431c1f5d686a50000000000000000000000000000000009f2e99512d7f755fcfbdf46820fc99c036bd31022ae60766a96204dc98d21f09d81d27ad6ca37a436fca90d1f8ab2e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c93101d9b29e7baa6ea300a6c7985fc71544949374e48378ef2f2f62415e8661f914f953e44658cdde80c225349012e0000000000000000000000000000000009cdaa91587019d24b9353b9bbf5de859117f57ab2265b24d516597adbfd8c0ffcd8a4b4110fedbc602aa160a25f89fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e6d2531bc535d944cd1bd9bde036e75d668cdaa846ec2068ea532bf530a61fe76c97776b6e41d48e4afae7a73ccbaa0000000000000000000000000000000013396ab6e8dff1f84a0973e8ca73f9ebc98180377472fe374dfd1753d790431f4f441d777fb9a808dd9f897cbda4002a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000661bc08d0b55c05197d30d974a6127ac610675787cdd8f705e2bcd32a0515743f4b301a45bfaaaf2d6e0ab99bffa7fa000000000000000000000000000000000c3f6d5d368fea0d6e750d02babcee99a8f9073e42754498647fc57b863bd1391a58f19bea7994fd62201aa3f9e483501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcfc928bb356780ead8118d9b19d1d1bc35e88efb267c58fbffac856c163d19a2dea66b9c9ca5c6fa2d65a590f83db4000000000000000000000000000000000bdf79d8c23c0a6618506345cdc1f6de3e442747552529aad8cab90b8f4859e15678456dc7a2dc4759819bf09c155e351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168249730a9f2bec5166f2ca4314b8395dedece77949c77e13d8bedf039a54fcd3ca37610aa1c01656b7799dd0077d26000000000000000000000000000000000a1c74dd643fdfff2116356875fe75fb115102cbc20453f6bbd0f3f65d6793fd1e0dcaa37d8985ff3dff12cc8d4b88f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193d905514b5f698feef6de53f66a7d67949cc9ab9451f0c5bf781fbcbbf426f520e50b550c5c01c8301a24b9780c8bb000000000000000000000000000000000e18de08e995622e9d12a5eed19436e761efbb53657ed960d345c391744d75d672e9bd014fab26f344c04cbbe021d83b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a063d2f15ed07d541208752fb7dfdf89c27fa34f54c61e3c6f7f0702885f7687c255125e30077920aab70ecb70c8f580000000000000000000000000000000012a464dbc759a696e966a658e841c98e29d8c5472d78d0ee174b29ae56459d16ffd4e797516550a3fe36c629b3c84d331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000718bba2dbf470d31098a060654c267614b2eab220d38290725208c3b9a348f083c20b4af4d8b5adab01a904a72e25e60000000000000000000000000000000002156cab69d4a180697c45d25434191f8c3146496c66333c4fc06296fe9da6a7cf91b2ee06e7253b9295b5de160fc4151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c73c3d1943f0331128afb239ee83e10ce1a5b4a57d1b0370447e309e5cd5f23d6f37a429890af13b030e654d59c8c3b0000000000000000000000000000000012402518f71a204c00697b1209a9dbf16510e71a3acf791f49c2062589ee382aeea0d57b9d03888dc9a23f3e923e36651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159d5e36003ad166546e8870425b163c007a2137d753819d14372557e1973a3aeff979d36028b978ec0ee6769f79997f00000000000000000000000000000000174b5a0a47ec139baf76b9c344f84d8fb14961fd6b966c1bc4d5874801b202792a1732b467e9e61e936a4965154484731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040c0f68d91e7209ff7759da3b126bc71a8186b471447df1bba36b4968fa11c7562a46d8ad8af69d22e7ea691161b7a5000000000000000000000000000000000518107ebe282e9103fb5c6efc6df800402d4fa23c5abd61343dfb8bbb108b5d670f735dfeb4a85c44db92f98a3e7fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3b99bad71aba858228fc9b9882dd8ca3d6721b0c735e354eeb9f4ed7b4a67312bdbffb19bc502784d54275ffe027980000000000000000000000000000000014be2752a9b0c54d1d2a6eaa4f58af8e8c4efe09455b42ff8e3d289205574b3995f9b67def3b3edd95678c05f93238c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109839bd46879a76879206cd65c7c514efca31778546146a23e92e42d157d78e19a35f31a5dad15401fca5f7aacc3e5b0000000000000000000000000000000007ce572222899d6ff5fb6d69f96d7a403066df9de6117a990050f039a51ffea4bbd52685ee82a55eaf55ad27b6bc68781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001828cc3b4d9a14863e6d27504296d820fd7f87fd77080c642b48c0d31ac0619df9f906a3f3b4011aa8123e3c0bf236c900000000000000000000000000000000059a7c60b5ab2a99ccec81083d5ffaefd5ee39649e4397041310ce97e59349ed20a7269ffea752603cd5d406d9e166cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e8224012766bb1cc64340a0c06a4ddbf084a5b592344a5c4c24dea4733167f67774b750efba6349fa5926b488182870000000000000000000000000000000015efc8c22a7709203fa52b82271bb6f6724a80bc2c1d174fccd0051ff217e1931dda18e04b88345962b19310236366491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a909b9d9e94890a5d92b5a74ce184004b83ea744d10f7c1833b40868467b200adecfd61296fd0e6e5617cc242cd6eb30000000000000000000000000000000019049064f046fe6c11c60fdb006f68da2d0984488caddd6b8af985e8af603b238a64d4c32c90bf288854c5f4d74fc45d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000973215015991b49a56f980ea5f5ca7cf2eb9a3417b2a7dd86035677bcb75095bcd623209cd69e816b296cefb97adc5e0000000000000000000000000000000009f6d9263bbb4f3139a354d640518b7524db7dda17948460972d289e310639de4e3886cb678ee97744f603e38e6e13771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c97b6ca92fbd4b79f71e3c11754c5d4307e56f90ecb4a778827b3a25ecd781fd2b34b7308b42472fb7d171845cda19000000000000000000000000000000001662016571cbc04eef9cd2987e07fbada59a06e174620b725af4cfa81407bfde7903a020c9bdcff71aca530e68a665471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fee51754395bfd525ca9d25a3ed54bca8c4000fc505d0663d4a25d3d15778f7fade55d6fd4394e03676016cda7aabd0000000000000000000000000000000010273cb0670ab6b91b7360c072d327d2b07810b779c4cb08fa92426d67770729f15cdf2f5ce138a0f48bfd05d92751c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114b260c1c3dad5541a69d3be25a253ebf6a5cb093fc9ba5f7d70960ac8b98a2f630394e9c6e00d6867fb0d76f357a2b000000000000000000000000000000000bab53779bd7cb6eee6b722db6455a551183ad607fdeadc500f50dbac2022eef90c3aff3719ab27086e16cba5a8eaef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000def3f2b1e5a983c99aad7e94c1fb9616ce2ddb1f4e2d7353cbd29c44f1ca19f064f899c53e06e01bcf9031ddbe1d586000000000000000000000000000000000c50dfccd743154e4a3c572bad3d24bbf589c0c9afe03786d60cb025f3a55ace2963e239c4a486306f4306f86cc6c3a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f0eff1524799f10be7e6d0ed6c7e192221314dec37c032891c8b49b0138404ee0f61b90cf7e38bdf7e00997d6c660a000000000000000000000000000000000b215a899022b8485ccf4cd519c493ea2c4e97561dc05f4bb2a228f315cd195e5c2489f7c3e719106f034f290b036f1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001802305d8910d466ed46645a86dc214083b17965c802ec2e73db7ef6c970b97c56c244c6db5aa566761157ef97e0cfec0000000000000000000000000000000017c643a5086265e2ff13bb8ae22a5cb29427694e4a05cbccb51b3687c4a8a6943875aee3a952f94d3d8577590a8c4a971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074ca2bd7660bda1ae9cd02f872aedf0067b172ffcf16b951e92d3c3445b56f8e5c6dc8c671de2bc02bd5b57155d82c000000000000000000000000000000000066c67ab1b08b2093fc47eb05424b1c4abd5329d980f26dc58153abb42b535dcc8138b9c57640ec0b19716463c1c04d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf9974483740905d5ac46cfa7f86ea2871d0c2c4f2d6db4f7d52de8a595a8e8f2483294cdb2ed48fbbe2ee995434bd10000000000000000000000000000000015452c17a3df3952c3debd55b948561973a9cc40089c32a2a05bf279b69cc498fac7b9acce331367072b24fd3c9c2b941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011eb7d2290c1e206ce8892ec7a2bb4046c74cd1b43d6a819e35ddb1e071800e16f258a202159b6d6ae2ea979f970bfc100000000000000000000000000000000053a83b265f58432e949d8fba46b8925de46b8a4729383ab915dedde6a151bf93291075589c046984f25f757124947dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e7fe57dd13da716bf208b075a03e0d1bbb77208a603cb5c75755f7bfeb1ad2b1a27cd7ef633d5c98969bac9aae0dcf00000000000000000000000000000000132202229aea34974d59683c677bfacc883e4756ca95bdc948e8d89e3d4798af82d3e9b1cba4c70bad8942abe0fc92ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c60c17e9595293c9da4d3aab05d157067993211a767f404142497e8dc1fd650bb8fc91f9ea8025714549dee63e932bb0000000000000000000000000000000007a25ec2e5064ae7c7e6211a75ca70b2e65b91db502bdce81e97bf9deac2e851e2c8876055f10453e640c0367d9cc3aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023b74339080c7c0d9b06cd6a30da6695f93bcbbe4512c447a4ab0205a0ec2694b2018597422a38a0f0be907a451a1320000000000000000000000000000000001d88d42ce585009fba6f8682b8b9395c94240450e00965a6b8bb0566059330df8546c64d25f3f3ddd1e82c57331cece1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001808d6bf8917b4e8c03adccc5550c16adc99a5895ee1f63069b20365d2819a15d26a7b1acd173c432a18a09ccb924a2d000000000000000000000000000000000654897a2dbbf07db16089349490456cb4f7712e43cdf92db0881465754470f0ff3e41ebc263d285dc743d369ebecfc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168e8474b562b341280f09e4ef3f611f83b33d983d8d210a8bfe31b5194b3d80e3fd2ddc8f3643650b6c9b31d696fe0b000000000000000000000000000000000560ff4d614742f59cedb4c876a88a333b7c4cab8235cbdbdd2a55c2841405369da761b9306e1a09c4a13aa85aa8f5141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000369eec48927a691fa6cf8424cb1a2a553835b3bfe4b0af0635a1686c3b9bb0ef6697e423f3a4bfdfa5d998cf3b91a220000000000000000000000000000000001dfb0cde1496d34083cb91d49de1d26bb7c4531eb5d373e50761333b0c18bc2e654fa4af7132e707c4ff278b097efc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005060931ad227800a54e2c64201b32790aa09c7257a9ec8a5fc356f5b3d0cc8dbe7bb6b9d37460c57dbe15e6c1ba4c7b00000000000000000000000000000000181fe5713589a7576f26c8c63a346c1d64ac37227151a52f056489574e45db04b1fc2bc208882892e7df83126a7ebb241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c84ca06546be459597444bc7d5fdf545738bff29d3d4da98412fb1c663526b341736e69d6a80b4f93930fededa446ad00000000000000000000000000000000187eb7106ece8375ffb080975e85088d00a23fd3a8e6c8003f240d6f63bd636af177b5a235a1ec7b7c57332d5bbcc86d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000255347c160ff93b2466fb5f8259e9b232f83f1761e16dcd2f9558587bf702e8f787a469e6c7b78c57e9b49abbb2ebd0000000000000000000000000000000010e29a4b5601ffc6eb3ea0599d8760a49d4b1bbd689f4971ad6b669126d6e36c836513808cb988669134ef041b5b89e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000317fb47b5fb06686e0b5537e5e2616c39fe1ca926f07bec3e9cc8ac8336bfd0a3b45cee20183e65f67c6f0cee5c69b600000000000000000000000000000000120f16e6f93bbf3e32901602f760ca86493758299adce458ad7969b9f8de63f512f16e7eb6b19e4ddbd140611978d87e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001be3e496dd1f3c33c3e3aa3a3696c57b8e4b3835510d8e5b25ad1cd7dc578d2f85c3d85a4cb002b23b97d9f3e491f80000000000000000000000000000000000c43fce05be4bc1e67a2bc71269272d714d51428b3c515eb592f51f53a05ed89842d2c605e8bfccbf7677d084a823bd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012363927bf7bae16993a67ff65ac896a5a9b40ff12913611dd6520eb95cf7aa97636c68ba913d47866a461464cf56fa300000000000000000000000000000000021cac39b2f94cfaa083fec833dd1a158bae451ff3d5195050c663c93f8275557c09890ebf937a616495903bf66979ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0f9ba1cb6002eb3c74b0c54674936463df314f7d14252b54d41331487b155947b6d1454d1fcaee28408af008d7d1cb00000000000000000000000000000000186dc743979b259ef13e906348c808b36d5c6f7ce5a59ba4358b0c2b55ef41e15a9bd61a0f60a410534ed0ed9cd839e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c4772355d938c6db5d5bdfa7da2ea77e3f7a2d16b00d443c6715914b55429ee93ccb0cfe348b1a828ac26fa16e491800000000000000000000000000000000130a3c7b7b9bbbbd7accf619b79d70a7527ea86384d722873960c09624a8a0a835976be87e5435316fac01a53d48726a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000164903d578c71b740294ac699e7fd532d3f68f394df7f3247f3efb0fbdb4730f768abfbe98f76b4e6cfd38c010cbb34000000000000000000000000000000000f39fb51098e879d5d80143743fddaf795f087c1e894f51a81eaac9485ce83776a64c8e006950ce1d1d6122efcac55191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a7510183a533ab5261f4315140b5ce33211d0767629e541f6c54235b308f841196dce0c3aa763ec800070e1d01240d000000000000000000000000000000001381e7d726e6a537509bf5d0bf42ea4a0b02214be7c601d35263df182a56354abea3fe2cf66537ee287cad276e6e2ccf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ae0089b787a89f5af279cd09226822ca647e8b2f3eaa5cae8afa661359f329b64803c80f085847513f4a2ee9d757500000000000000000000000000000000004bd062d20f3c8923386752e4eaf25e04cd663e159a936bd13f557348b7aec2bcfdea8e461228894f781760aa5b32eb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f60f4c9ec91bf8840504de305cfb50e51d8f04e08427e09ea20c90e76c44c72b7ad5fc493313fe5d0768ff8206f1c39000000000000000000000000000000000446375b29af37f6f85789e7aaddc65abfa20e6a3718344a1cc14bc3b403050b6615146ce404deecf1462b095f5e53661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d031768868ca6b46fc6e3ea13c8227e5ff8e8e17d5e75b2f1ea01733ba5c87a58f09f3f634041f03043b5ef9c9e849e000000000000000000000000000000001459dd257684155f65fc7eccb8494a4490dc4f2fcc6a9927a893601514762d41ef7e253045ce5644a849ed7671b588621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d231605846bc1d8905b2f6b9fcd4344de4d8f95f548d0bdc7b4e77e15470b0a39e5c54f58ef41b436c81e37046df9490000000000000000000000000000000015474dbdc6e3f625c0afef5809eeedcdcfd62eb526d323cc7e479667dfc24d96452734216cdc2e215bec614e3baba7511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f2bd452a132690991d6abe4b8f89e46929543e2f0a68916958a4a3203af8c4e4860052e657f7b81c10d19a94d00264000000000000000000000000000000001326d72dab35b604c513451cfe4087748e8861ef7c47aad96000657506a76f14fb5013b3aae1b713fbf4d92fe28b1d821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b17bedcfb1d6eb09f516245c42ae9b77d1b3ae8949f0f2a1195373dc719e1974bfc63b8592a8416e2ad5e6cfcbd9ae000000000000000000000000000000000d57b6cf2becd766075080e5b589f15110d1cd022748e0c20cb6cd9619dbc6d34d61bacaa3e2c52c1aab204673cfa0481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130908707aababa96f8a93dca6da8372e3609bd9ce960d66a40ae5ec76c7f32fd11d50638207ebaf7f135dfbc3e372dd0000000000000000000000000000000012719dd5a441bfb75f04c3f93fe8ffe60a5818304c15b714376386c9fe8a832fc939ef7f1abca620b0b0659f9acceeae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001651ecc0dbd2f856cb207d03c031c1ed99ba253346d66c9a39719443de409b1d4558ce945b79820b0e0e519603b6f3950000000000000000000000000000000003e930d3f2da36f3975da2a56a9ca9966a66a540a5cd80c4120d04abfd688c4bfe1b582f3530401fd22bda7a2c6fb55f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f14664519a91756a3ed32f14f434775ff5cceb59c622ab6173da3935a06965fef3e38671e6c67f2a7a520a8f2126ba000000000000000000000000000000000611e0970e39ca6464e5ab4cb25b2ec3839af444e5c8adc225bed2f81104455501588280e4ce92bfaa90930829e265db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022b0d04ab735baaa42e5671ef8722fe290669af6183621632a7fc17f7d94fac578352b6b6c4ba5d3567b53dfc1529f5000000000000000000000000000000001083a90c363cd99fc4821b34d97438cd90cd5b77241cbf86e2f32c6454597387b7d92b27fe8a6608e6d098cd458e145e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ec10bc5c67adf872973d5bb076a7ed574f7aa082a5699607f27021c892010c2bec0cb47955f03cfcc7d8b68657d2aa000000000000000000000000000000001113b04f45a12741088b500b59b25a0d302fadab1fd83f3b8bbf09f20099d2e8ce013c760c1427300a73def35fa5dd4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fa23bea1e8b5bb918188e249fadc6c51ccd7a839b799a8d0dce769dc91b8261eef17a50dc28734d04acfe7e4fff201000000000000000000000000000000000297055b49e217f6dc28c16b7e399808c71fae0807f7ce8f33e2edd72745815b5905f14acdd80d341b8f880f1d27e0a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189164cfc926d9118dd8c887927ba751ad1a60a1d8369f9830a1c43bd0258976a7456f89e77f3b9994942077508f165e0000000000000000000000000000000015f1873213c86c2b93e75afed9816996a4120dde402df086c4beecf699692c3c3a65fb977b5762dac545a832237aabad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034da32e29a99479a085e0100d71b0a3f0bf6347d5cca232a467582fc3cccd3bee64be61f6a35aa9501c585ad2b5cbf6000000000000000000000000000000001701bca8988c1bb17fb44c67ae7064e16840add6e92d0ab6cf249b8b9f5d2d1adea5ab1dd83c0befb2974f39c0b42e911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8f9b587ed9f7d1eefe6ffef0b697aba2afac186e3541d76f0cfd0da7984c5babcfaf3a73c477de59fb2c1f5a76aae4000000000000000000000000000000000fc16b37a08684e103508912aafce2a4dd11ec575e032f97dd26c96813affa2966c788006e976458189fabce39816ca21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032f07f0696b3016995cafb0763b43754d51d647cd4bddf53d4becc54a90c29dcb0a9bc7124cc9b404b58f2e7501eccb0000000000000000000000000000000001f8c06e6bb72af57ae018ddd657e862865a6a0fc03082f969069a31f65f6bae406a503dd5164cd1e925a06a8e000cfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b9acfa7b11ec10c5716889ebec08d10a7dceb10c857fdc13b37f4f8f78b407947438d09baba3e0939497186205910c0000000000000000000000000000000009ef4dc8c0fca6d06f3ac0f93d991708998ae653a85589b193d3e15c8b65a5e3f1f9576179f561445e4ba5e9fdac89ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162e572c3e7be9c6bea636a2de29758545e2af06ffd99ad959537f2f32c7017c341b9c6aa70df6cff54acfd2f8d5dee30000000000000000000000000000000016650814e7aaff21659e1725546da208bfa14ee095de78e345cb25ed781000c5da1d4151d1091d4d00efa1e17d6b00f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcdd7e0779d0f46f7e4da9a6cd0c409813884d5d7e36e4a1b3df69f3708b4e21310d3d4ca445df1ac9e5c58cac101f70000000000000000000000000000000011adf274598fb43c1b1c73e3e262707d5dffe30fe8495b82ee606f22945e809722ea158b1568e3ea3734ca0d8333a2471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000192f37e80b58cb2bb33f05f18754dd299c7db8ac5af87d471a0ef9f6d10221bf1d0bfd21ba60db8cc8072c4ae0f84c70000000000000000000000000000000001898fbc5940ec600184601d65d665655040093ce45b437166d2e49b96905885becc7b70d9ee237c5791c9d1f8d270ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005673cfbadd283f76ae73d4bc3b72b037b37023a9f257e33190844cea8b3082ffd9c1bb74d61aa9a7b36338158753c84000000000000000000000000000000001826845da04a262ae2d8f08bdb97b80d2d0f8c1cd1e791c20771324cb44cb587c304dc48a366c5fc24ef53cecf961c951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e846a549269ec3287daf7efb6ea3548463d91c28e7468998935f27787052d0ddb69359c1c52f685a1553befd0ec6f99000000000000000000000000000000001736877df21b01a9e8d32756f180520a8c4804eb608a5b0ac999d23526b5a9f89bb112fac090ff1b76137971ada21f0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052ab0bcd8cb9c3b83585c0b0c428ab2b6b5ae2e64fbfa120edeff4430fbee752225f44364ff5706505fc66f3514de1d000000000000000000000000000000000ff9d7205da09db792e794a8958f6ce7ca43bfae14fbce1141a0a2b38a0ee4616bcb89ce795c5afb4bef81f2b843f3071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135c1455a407297e8d3600e1dd0021b64c3dcb6c1a3895aa88fc1bac47e5e6ca26bb023727dec710395e38f3b5f832a8000000000000000000000000000000000e1562e13d17eae9178cd3c4954df8dda5919b05d03d74cf9586391c6a8d553a21981ce69110d70aff695915d465832c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127d87ea0d6e4c8484ef810fec45c0179deab9d4793546b78ceeffca20ca533395978cc175a9c9a7c69804f8dec3a3c3000000000000000000000000000000000b01393df5aa07269af9a43029a672e2e6029efdda750112e93a832c6f31c7aa0aee3fc198d7af98887c2f80cd388afe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aede57e01caf31caaa407d7d0262abff236fe6f2d1731fc5db6fdab86c40561c2e77c225d79f98bb1acef7df8876f68000000000000000000000000000000000948ccb2ab131bfdc95eb1cc57bfe25929d48ab45a9bb8f895a83ea96078d0fbf7ec35b2a2909bb404bb2568eb3eac1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000325a3bf42bee14a691a31dae0d5fa0f656e3175d255b4c1124e8e3d8e78eb0464e142337a8cf5134f2a45266b559a460000000000000000000000000000000016cbf32077d37cd39818ba035ed67f4957ab5205f892b1a5f8000fc38f25df6165254b9437f40a7e254b2debb50bd77d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123f7c98cf9bc8aa622c66a6f5b52c8a0d62b7d2618a6cc0b7b0560d7d18e2ae3b776b45389a12319561dc10952456df0000000000000000000000000000000019c318afd7dd391ef8e99ca2c27bffba6edb540ad636868f17ed6bedb90bcac71c717f86b79e3d2e4023dffc5f824f661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000878486a7e72aa69cc375a2f4dd7214472f95ba0b4492d22672fb98b87ceb532412acc51fd0ad78707a91f4669bad42400000000000000000000000000000000019fd50cb5efe933673f368bb6bdc57dee3162724cbb304fd75a6d93853fef0d19383def7ce2f3e24a1e2c33efd702d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000909e0bc2dd6236931960bc3701e82404c72d005b1ea0eb329e9a92006bf3c8ed60b750cea2cfb0a50d1d6dbc038fecc0000000000000000000000000000000014908067978b4b5122a021119d699f43ada6250ce270bc9ee4dec0ae900fc1a69de95205fb1792492d981dadd58b39b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4044d5f4f427abf0c3f08faa4d080151fefaaa3bda670dcca75683723f9e379a3937b92f465b986d50a2639da1e6ce00000000000000000000000000000000051a6001c813f658b1e39250c16e253e1824ece5b62830e0a3f19e17bf0d6558531e568e269e6927460435335e6c07db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001118428e0be902b21f4b5504a1e927a6aad58114d0f96e894ed1048c40e6558793cc2f7af0bc4ea59d75e54ca089490f000000000000000000000000000000000000d7439ba0a4676ab10fad19381ef132169d02c992d94101ef3d990c8a8bb5546ae3e992f86a1d9e301315a970462b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e32612d21102f90217e832fb7a00f1d9e1d4080192893a14414158c7ba00df047fc3c2df8c0b7bc4a5d757fa0c530200000000000000000000000000000000145fad1d7fc6f1b6088e534a61814c0b1d49bdd797cf2f7cfe62da954b91aff5ac2f645ac54e02705225ec398fc7faec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002710add587900ee7b1e7e12a1b83b6dd9638a57b5f9cd69938a74731a731ad9d8989fc10de16843c72a87af23e0057c000000000000000000000000000000000b0ac0405c468a0b1675e1f23f336b9725838f4d09099585d5457550a5e60fb64b1dfe5c2414c7ec527d098e26390bbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009872ed07f121a0d5f3d74f7bfcab9b8abbba113337d11e638386d2e8db61a21d12a7241d88c080209b00d0be7d06ae200000000000000000000000000000000103d2c2529febab2293309f86bd58a8fe8224c1fcb82cf1fc50bcfed5c6ccb32beeedebe6e4eec0df327f435f3ca36491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c567e5e8ed207f1ba1b86aee5e687665c6fd5742dfd970febfad73584e05f87922bf3e55e4cf0ef7a0abf874d163c6000000000000000000000000000000000fcd41a407159e9b84971ffa787a5199c286d6ba51072cad3509900be7348a8963941b4a34e4b0c60178a2c023b3f7ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dc4e6f93c80277619259f7b5afa46e693e4a00f260abc801c45ec1e389c527c0f3c0a3ee0bf74b072cd196a571d644000000000000000000000000000000000dd845e8c348bcc0da810f5fa5ec30b899b535beab3f0dff0949d226e199d28ad60bba81729c311c1b720f9701323a031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e10c3ea6609cd38a58d398995878aba9b07c63f785b8c33a988d834988c92cc80094bbbd9f888b239aabe508e965080000000000000000000000000000000012b58bbe3f0ec9707dacda9c8d2d5c304648c9fb39cca9ace411e7bd6a5f530478ddcb7da560a8f19cac4ce6e80833691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018240048a347c33100835d095e9d2d967afd41ede3bb0850adf7b23c17506ab0a0dc2999757665f6de1d99c2eb51bf79000000000000000000000000000000000e98841ba1853b61153edba568fc7ddbdca7bc0d836c3436aa9ca1a5de51622ecdfad0aa72265da0cae241fccd6c5a321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c7be458037b16073e6ebc7b4b93f94a587e1702d09f01d1d52f62cf8cebd6c4132c536a8c986800c7e2c1e7c6a31d60000000000000000000000000000000016a58204a6043c70bb9f5810052aadfbc5a558ec4ebbcfd232a065e201588bb0205dd4f437921097a48a1cc24449d9be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa7c4703fa768e8ee89efaeebaac6a9f448b20c8d3531eeae8a134433c8c5f74ed95f6e135e4ad829b127aae01b5748000000000000000000000000000000000e8e83a8599d11cd433fd3fd96223ae81bb456de03c4219c1a3c9c327afb6ca7967bcc7a7a3a22a86ca04d3948e064281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed9fddffeb795c498da8ca36504024b7c0c2dedf2afa76cb362f80dd169eee11917e5cff391af56f3f8c6bc96d1e46d00000000000000000000000000000000001628c8d0c49595e45b272604753d6fd4828a5e726aa621b72c49af132e5facb48e59d4f9ecd671a30b22ab37dbeac61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ce613ca7baafb7ab66c1b948096ef3d0ad730410cec7fbf4fff3b45fc012554c58c0cd3953144973b35a06a43b24d7000000000000000000000000000000000482642d858d23a72bc577fba84ecab1a3e5a5af894aca65864a363dbdaf2118a1093e74f4c69f06bf5cd6234f5bba661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196753e93d84df44b86ebaf70bce6c999de08dddfbd1af42e63f763013509c30286046accf00e0181923cb866403c20400000000000000000000000000000000190bc1e4bedb42488981b47c79f1bccfe7de13c7a7ea02bc8e674a4cf0179a5bc78ee22a1cc9197b04f477c7b433e19c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000920d8a2bc9647800d415c9f813a7c6bfce10bb499acf61879c21c1ccb465e42eb3097063b81937a7ddc2b2f617707f800000000000000000000000000000000022230ed108867cd285ac8642dbcab6d7bf8225785f1a6d8da8c487da70ebc84aad9f3b53d27fbad44e8815e327004421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e35fad09353a91cb9fe89a6de29b85d727ac235ebe8b81242f762df7c2bc8d9a2b7a436297de06f978dccff857a6a300000000000000000000000000000000144371aa408110e49e8d254ca3982620a3f9849eecf3ec47ab455dc17c3053d668e2e6ddbe008f97519d3a8b3bf5db831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e883c3a400bca3cd7e685557088020716279fb6780a6c357efd86b22e02ab2b8dab4d884f4fe61a2526f020dc1233b0000000000000000000000000000000004d3c46e2baafa0b18a94a3f14cd298a7938bae7cfc8c349dbe9220992142d6eb2769da6a1ce110da76e8f0b5567f0601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ca49ba2ab6ba3e3252e531c3f26b49d6aa98062a876a3d413c511c56546fae8aace2d0ddd92031474f73844ca0fe0c000000000000000000000000000000000c78d0aa1c26e2928571994d63c6da4a0fbb80e48fb96a745f98fe0b885d11797fbe5e64dc2e75431dc437aca9ec85101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184d287f2f9c58be57bfb20ec1dd0993eb6179f2e53c62203534012aeeab5149f40bac87092626ee403a33cd01b2e344000000000000000000000000000000000c852d782c6dcc989108bb76694d24561ca4d02e8babad775c047cf2225fccccdddb9a61923cdcd959f7233badb76f9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b89776b96c69b669390e1bd33247385da080720435909170c4cae2fcbb7de6436f9677516050e5b2c13de9f5b2b49cc0000000000000000000000000000000013cc8c3c50ee26981cf618f89e1da2a6af493f5771ff15cf66abdb516b08604ec7519d239f6e7085b01d943b11e594021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e2c58d86b10c8eb2925fc2f07bbc9e4e3563d21486f2746f28b380068ec31d1d19f27c7122eda43a9dd7e6f085164400000000000000000000000000000000101101f420c1b41fcdea7bc76713f0e8bc52c9bf19bf73e343e4cced7deb13250bb1770ea8a6d26e78a6f09acae310c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075d1dbc4571d6ae605aa13e16d3f78da77fc464af28a032f3ea331bb8d2d82c3ce2a3104df384e7f888703f612e606a00000000000000000000000000000000099fc4f148250063f394acda8d43d13c700aed3b68a60461ac340f9395b1509db02f2029a532854adb1c7128fb7873981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a29fe8f833972b439e48ca0393e8816b2051d3a755b49db17bc887770ca4c3754051475c87194f4b339ce7c6d18c1c70000000000000000000000000000000008c8094216b05f7a56872b735ef825eab2bcf653501ac31f13470dce9726bda321bd82ec9a85a2f4a79ffc91762ef0061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000faa1fc4c89c5e5598a1c1ae08f310e17d9a2b8d075ab837109e7523eb7f8e5ed9f26d64736f74a4213573dadcb7de7000000000000000000000000000000000ef7895a0ca0bdb56194422e3c4c1599c75ad99cb0f2d24b624a8f90bb8a6f95b56c71dc1f974edffc2a7a4d22238a121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8bcc6296a3576179640b34cea2c1d214612f777bf7acbdbbcbddecfee47fdf1e552ba5a1c86a27caa33f8c9d101a71000000000000000000000000000000000821c33a9074a907ff54dc3268b0c701cb49e35fc4a8c7103e982fe3c3818b802d90c35597ea585d34a176ffff943fe21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b42042063eb2de768aa8276dd86418a5f1aa923bd45f7a4cdc3dd49aed83f9a992fa3c00520a45a77ed27aa6d1bb83b00000000000000000000000000000000035315441da71333a4f09baeb928563eccac7f3d7b4df9a9444014fd8ae1aa21ec02f7741a41d86d4e6dad4ae78d5d951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018834d84f75434b8de47ad7f331673f63e6084d33d263d7dfddfcb698543bb19eef11c4fc63d3c8d05648e8654663af000000000000000000000000000000000146d7e4bd2ae56657b159da390048b40c4e97236aeeecb6f3631f702f5e4df67c36605370ffe2a1367559eeb44e7e0b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a4ae40f57bbddcb9e8dbe48ea9c326432d2c3a1a0d2a056437321fb63ab30613862750ccc795057786ec2d813176070000000000000000000000000000000000ef36f20877ab932d26539a8d2adee6c565fcaabf9c5da5cfd29a5898a72e806639cdd73dfa8505710a4bff8af1d9321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060f32d307b47be543d862e955befbbeb4315c55779af943e8b5fc05276418153f7501f7a1864630634d6b3058b09770000000000000000000000000000000000bd339d2ada07b2273a020e7b8c36ce412d8ce147073f0048df04d244389d509b31438406b9f14232853003cdcf88eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bf216cc4dd2c63ed802fc8b1c24683ae08ec3525bbbdf302d1a18be095c1d3fb5ec9d69cf2e1eb46a9d0faf419db74000000000000000000000000000000000129da7c6439ba75877704612f6fb7ebbf9d70216cdfab85af33e1a1917a859008062ec54b6d032e33332f8ef425ba0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b8ee9d3d16834bc45fb141afe54fc1903478cffd1310a90a928c81bfd9bd02be2279778605bb345e778f6d1af45a0a000000000000000000000000000000000875a6f0f79b4ed2b9ee85c4463c5def1ec9d68f6d4aad1d803ddc31b9d82485d459b952a2004759d858b80d8a5614011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000037ba25066090e0a63098955eadf82202a69465ffe414ffb855a7bba0c3bb19eb5e56c76e5c92eabce41a492a3def980000000000000000000000000000000017c20ad674ed9f81cf4f545095c1b5170bdccf3a50bdf5a1d334f5850e4bb52b65d49c7d0c2d27603d76364cda8746de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011fbf855c7425a92e45aea14d693d01f618ed4f617b2ccef6fd6fb064891fccc4458c52dc434014cd4c58877581dd2600000000000000000000000000000000190a957edde27f9e29aabcf1a48378f46b9b7419bf42f65bc28e2d5712e7c6a718a58137513b3e8f978dc92bf19106ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157947113a993c8aadf0bf2f186630cb597360e7f2f757c440b7d70db1fddbe4b61727567bf4fd1ce6e472ef21e73e8c000000000000000000000000000000001848c97f79db84fbdc9f3bf7fdea9415192a4ae90f2b79a778cd34f0b9d80fbbb993f7d2285cf84e063b5cbb97a445a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f1b00c1f0ff8e4a0599328688444a792895fee19133cb01906299ee23e9cb893d4905ae7fa6e1caa8eba18529f196400000000000000000000000000000000117a2070e2550e7a0a13a38579b03087b78d90024c5641d8e8dd434058f2a40ddcf1e23d0af6a6c91ebce263b81f04241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac064716dd170a3bb92e9263d8ace63140b6b989f5d7416b46771d185ba292279fdf03e8e4a12a443487ef5e9335ba20000000000000000000000000000000006bec94d0e8c3c4c0cce39104c0ac7da8da822fda8eadbf95c87f209607239c5bcfede6612af5ab839301873cba1e7971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000600215a1cf4bb254b57e03595e53899109c76b96e56b5acaa0f2a5518ac19707a36767ce7165a9c92012fab1ba1ab6100000000000000000000000000000000054dfe661a29ea7889a15f7502ed952fe7bcc6adb9507cab19f1dee1a076fc95493de9f90250b4707bc7f09241d999e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094666e7366f39ae104e01286236f4e6a2f9597d4abd16e9cfdd8209302123230b51a5f783d8f38aacbd9b84cbda6a6000000000000000000000000000000000143a852f395fd3abfdadb87a8c5ef670733928758a1770f5baf096601ea12c7d6772ec46dc7965894681d82e21c14faf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186f577e517f4c44607d25beb80db4cf436e7198462903bde451d5e4319efa33c87b695be9f7e69edc108ebd6aaf2c0c000000000000000000000000000000001306ae1aaa9e9fd01e4d62ffedeffe7a85d004e2c955176662d4e9c30475932e55cecf3a5892025120df844225c06bf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e35cb63c5068b6d76d5337a8ea384e6546305a08c7a435baa4680067786ead4eb4391f93614683b996b13f00868e5b9000000000000000000000000000000000caebc465d3ddf6bab660774c690fc1ef892fa3122aea14b212cb0dc8d77eb44368e2cc60737811e4e7eb331bb7c20f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cf066da14fd6b291349360732018b14c8c7cc96d4a4e607f7bbba326e25ba3c10267a2fe7f85d6ec66650690bace0e000000000000000000000000000000000fb6b961d146856f1f0044ed7d69adcd945dd30db168670682ae4985bcafa79d91c7280dc321990b26fa97cb7fefc0991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd76672456dfc8dc12a770e089d9ddb818ef65f04e05b13f0cba5e11b07841e07cf2bbb7a7219288767aee95080bcc1000000000000000000000000000000000625b913a7e46d6720129a019f79c9a6d172000260bc36c59f24e6e4fb2f4acf42f13cdcb4cf8e1d3a91081e92a6bb331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b15afe48660dc7a990c1f4f988a5157d0d4d27491c289dfd9f4bccbd1da60fe9e14878ac06d21c3b390ca51723694e000000000000000000000000000000000020de3f7d26965a54065fdfc2d309aa37596ba6bc3c861aa7d61c3f48fae06b790c4dc83c65fad3937d502f217148e9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d260738d6763176eaaa62c6b6db979079aa1c2625b7c0e820c14a2dcd87f8a46e1f5c7e9b30b905d04cf1eb1bfb574700000000000000000000000000000000091f4f8f28068dd6034b261bf9bcfd6cd37ebdcecf4b20c6ca93c2c826638af6c1202200b4ff357ccdad89d70500ca861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc5b4825ab27319bf5ff104789d5d5600162412413c265c03e41a7d8e96fc5b5152ed698a9acb55d2bb22b969b9af9500000000000000000000000000000000013a1f428f0ea9a772a8be9acede71142266f0b8a7dd361c8ca7e1135ebcb557e1e176308bb9677f9a6de81cc45384911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ff9448d4fe9609393af7a9b7f0291766f96e66fcf21e22550fd6eea0e78bfc0acbbf5bb976863bbc8f23d2f58e74f900000000000000000000000000000000170c45b1da76dcd55f2a87e159424df1f9eb0be537c752b7e3cef58fdc77f5a73951a97687613eaf52c0af80d9cb64fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084cea7382e79d557637c6f0d7a7a2291bdf2bb2ccc78683cb98d6f5b276d80e95ab03db8ee16c4011dde023068f0192000000000000000000000000000000000ba624e521dd57413dda37a56661cb41ee4dc8e9c8a599bc8f5befcd52e3e856d9e05837165ed65e96c943e0825f32161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b83593d1a8b5757aeac5a8e2ec2000684357b472e89b23b117fd8574cbe7968449dc735ad0c9786bdf1276a1fe40640000000000000000000000000000000015c220f4da549206fde3b7d22827589610aed2f2b4e2330e174ecda888b8f34cc611fe712cbd589efbd167b412e48f2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177ba5b20569c67c71e34a0b497d7f359bc4f437d6a0926e07f6d6c668ede731a80c0f321edad47f9d44d10586c26dff000000000000000000000000000000000a6b8d28884cf3ddf7f7b14e178c7e47a6861db91f3cabf05743e0adbdbf964e0052c73d2e91594c7405a265158d07051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d51e6ca12fa2bc24f2686908201765168ba36df1f05b01b392e58205ed619c2bbc32c970f2701f56acd3fd6ec26cdc000000000000000000000000000000000a1280fad6a768d2c0688a466f291317ab4e9e40ba672da5792f0d70fa1ecf71460bae1fae6f2e3750db73f6d25b7f211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007be0f8845280d75d68f995e1276d0e8edc1f91155eca48ca8fd0f526001b73d58023610ec4ed71583db3a24e45a600b000000000000000000000000000000001434c2d86cc17165d762a256a4cb6f2d8a1069103ad34c519bead5375698fbe51c335a7bea327c99b3c84158b78651e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000786ac64f8e785401b884b5e10dd256c05385e76ed4f729b7f79c054ee071fc77a21548f50533a6b2e88be44637f0a00000000000000000000000000000000018c982d99d622daa5077dab56373796551e697f8b7d02c71d754c588a2a559280d2c8340437b30b542ffacf1662941291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ed324c0d4ba4347e6e08d11df682873696f01ce1615bca089a2763cace20a326aac0586600ae454139de7e549cc800000000000000000000000000000000000d9139c89f55b10f88cbe91d9e2022f70821f1a145c7d6817e5148587bc53c6cb4c62e33f3fcaa76b3a5424aa16944cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ff97b0c1dca3eef3f9416627117485d15926457aa9ef6411d520c1bec291bd92192d792361a40ec2f3c1328d2833a800000000000000000000000000000000055566657e00529e417bdcb08d8ad2595db8b30e4de1401004645fad41272fe99645b6606f557ad7e0b32db45f2f516b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015768e53a0cdb465806b4b30c72b42848a21fa6849660c948b5cc88ab24f01576365dbef519f9e0370b92a36a5c1c2610000000000000000000000000000000010e3c6e2b8bf2632494ea2426df204a5266df85f3b58ca88e68062d2e7d9f513bed1950ea6e78536e68c959bb433a4de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2bdb884a5ff87218f1d4f1daf98094410d94c0f036f4bffa127434dc4a58bdf12849b45fa1f94e9d637f24ebb6e5640000000000000000000000000000000004127ae1ddd782d81459c289dd3f77dcf3193c2f682b1e8e9078157aaf051f02326a218c31d59f1419306e714664ab841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f7e03b4bb1ae15aca4d2169b012ef5f3311baa8b270980232e9cbe62a99c577c3d2dd66d566b236f65c36294e37205000000000000000000000000000000000854f3d551b677a1f48b0791121612523d8ee8e801f5b5b0310d78693b5514f08bbe2fb24900beca249230aff064864d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001021fb68942a846028108cb6fd58a841f08973520e024135ffd6cbbae1890d9b0946f3dc590db5f9f801f05827ce7cea0000000000000000000000000000000010011246ed5b8b14c5877cb0f5288da70a28f9ac3e8695db798b6125f00d24b2c094452d8f38776bd20ca1840dba5ade1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073ed27525e5a6700502abafbe9cff73ba7b4b9023f3f151e981c45626526b578594fd11a26fdff77364a9717b40a3930000000000000000000000000000000017d5d660705d4a887cd611d42e79f3e69d38f94ee6752f39d7fed623fec1700fad8e969c2985f4c56c4f5e001a692f6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f153ba71c6d6440539afbd559f0ca9de6e106a5f75b2e8b7919bc85836a808a8f765c720fe9db4f694df94593dabd40000000000000000000000000000000001f41a2bc99a77a840291338fa9eb83d3007ce6e45410754ceaac469f4837cf957900db0a517b4e009b4657a950c9e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014d58e09e57bd4b6f4e2f45e4af1895d2c42a296f73a731488ff67076269a2867c995fa3ca42103792254ee263df15d000000000000000000000000000000000bacad14f3727296bc95cab4e5982587ac9d1e0ff42ca164d8ede267a1567a82016d2e14c7b94a6371fe5ea100e14efd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024fbb9ddb471b24290d6a9cdc6ca0213b0efbadb621c27e1075cd832a290bff4c60d478f6d128ed202228826d05ca55000000000000000000000000000000000c64bc8a2effc3ece60a555ab093dacc790274ad287eb6bbaea983245ec86f155d42ce514d78245a14596b61d426d31f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142105d3e847cabc69ba5e7bc5d1196fa5034c017fd44a5865ec648bd9197364b34ce7f8fa32022f058834d556bc3f40000000000000000000000000000000001667955e6b6f57fcf2b7dbcbd11bddfb76afffb4a23457581ccc2b46bde4f51ec9ff010a712ed86134e465185ebcf9341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c0ccf98e22389072725385a69a3872c46cae8fd1851fcc1f5438c20210df7159c10afefc12b5e5edfb6abb3ae2bdc50000000000000000000000000000000014a5bafed2b86ff707e2569ff243d8a0cb5494b22515462196ae579167feed106636ee9820fe0e8331ba3f66f6c0f8221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000399aa610ebd2f18b8a15d22f5a17a2fd5554a5a0601c80dc7370ca2c5a342c311eea85be3640d3c2a9573b758c67d22000000000000000000000000000000001606a920ba1bfb72782e8f3e15c13d6dc942fe23f6c50e68a25c24614e106d5c94ae4100f2ec66612e1b8973ffb202791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf271b89b9756d25b71d33cf31c75320d54b36fd49a07db4d60e4876153fd96d5bae7291f8d8bfccadbbe51eda11a500000000000000000000000000000000190552f52a8619dec191a62fbb91b9f69676939ec8f3b2a4ab8d819b1bb1c5cc3570c4b368c27d5cdefd4b27570f0db21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004491739f5c52361ef76cb2bd90fb935dada845e2434315cc0845c4af3677baf606b8fbfaf0fba3b8626f9eb8629a61c000000000000000000000000000000000f662b72d3c69a0020105f5e184a0048518bc9ceaa4c03b266bf7f1b44c212c3b3534f7e3657c900974885d315da01f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8a95dcb1778e07b26860689c776e3efc4c4e06e3bfcd95ba1274001680105be10047e4d23625ed9fac4fa70bc716e200000000000000000000000000000000089ea06c81ac54a76b0ba392c9ab2df5fc87a81989a13f2bf3b04dcab20aca35850a6430cf88959b62198035fdff900d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0885a0ece785b995056e20c5bff678557681c33dd2152089e0ba03bf5178b7ca5d60d49203cc73a0b7064df02e334400000000000000000000000000000000160d9e1bcb4119067ac0b68b533cc7ea7b903a19138dfcdb1869750bc0b7ff9177e7d38da687a908e1daad56cc9829a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c78af0e1cef2856a17cd14c2ae9f248fe56e84ea201a4475783ef85e0228db9aaff7ed0ecc55b129e9ac00217f2c20100000000000000000000000000000000181b0e369748694d7a08b49bec3d93b515c14f2081f10fbb99d7917e7a19da12b358fa5f6e502dd1f67342a412b2c4721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf7a044ff63e2233377a716e1b64cbffa503a3fc6169069bc38174e19afcd1a0d592505742bf9d3c13eed592738b7360000000000000000000000000000000000ac02fd573f9ea988d30e56c24b6545515d6f3af03c982ff0a82cd4ac7ac205c72551e6151e7ef5eac53d1d0b9fa1e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c9baee6762956f7b39e817571386f751fdf1c6e4ac40b9eecbe6e54d2977fb44c87c00ec2e1c1537ab66aaae4dd0fc00000000000000000000000000000000094dbeff7f3297076968a93d7182a1deb76cb7a596008ba97a1845b4f14a052fba96401a9c44fcf25078df9d38492e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000667243375d3b84df7d3dabe71aa104f23504fbc169e473e91c0ad6119a5d4ff2820cdd7346d9cc79f45d38a292431aa00000000000000000000000000000000078affac52470cc57d47ae2c44e6560f87580ed2ca5f7fdc72e40085d33b11f5ea20c55506220239fdc8e9b1cf712a301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094c0d05e26b5d8b693c12a9323db394cf8549da95b5aa67c34cf15057ed1ca0ac09309b7c99d5df94fca93c5e8d800c0000000000000000000000000000000005b7948118f6e21c9f94709f97d971a61e64a04c49bf719b9e3799a714e7935a4cf140534286a08e0e726bcf6116402f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160fd88d69100714bd613d80384f58e431430d9292a0a73db821696d609b06e9f309c85a60b6dc02eb638210b2a26d9500000000000000000000000000000000021f826ef63b9d848ca2c2edb73e48c476f437c0939f1d0d1a00e03cb03ef1b7975db11be620deabc97253452dae23c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001882c6537e4001a19fd85d582e89528120bb66446457dd1f2ad739376539c4ff49059311a6bed322a2a4404f880d15f5000000000000000000000000000000001137cf840c4147c0047d40d475c78ab65ae3711e2d7a6a853f461bf7070f4895fecd2f95118cba8816590ba3ad9a47e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad20d1555fad0dc02e4ab6a5a01bec6c98dc7659d6e6e0e8a63e65eb712bc388fe14d8bdfb2d5fb33de4ddc1de553a900000000000000000000000000000000039b8969c79d5449c4c0a05a678b5475702cfa990b9f8b9db82c96d08432704d205070ebc4ea7b95e850ffb98d1c233b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000774e5e221649e135f19bf0b2072eabf8714413138b8c3591a6e6d098eb57d5d9f63c830577a56bb8821c13047b1113f0000000000000000000000000000000012d5b8cac25be18efe9f07be7f185eae73b7996c589da67b4f14679970ba536dc66c81ac2f70500abc695875e7f35fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b7ce95be6910597daa839664cc62ee7d0135ec0d7554fe0a15a0f5ffcaccd1206d3668297b5f871125ae547fcb1e500000000000000000000000000000000078df16f5ef148456d0e44334eba0f3ec0e7973ef1e8bca8dc196ad1c5218624427b84ae53b905ebb30236972d8bec6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d3a919c9347825a43e96485d27d031058e1d6fd407d38604c318b53c87e1c744a11c7c7d8ba12e0b42a18472ea092a0000000000000000000000000000000006d2e0c973935f0b3c1d64dab6063417afd01ff40a44f89ae626388c13f6062b8703fe2e4169f4794832fb26ff5869561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d948ec19e6e1851c7d6428f73f663f5ce8f73af55655c4eb30dc994f0a344e520496da240d14164b2eecdcd4a88d9a0000000000000000000000000000000015c6c46e7ef42a17f51b53dff689fe3c57c325103db00c4366a3f83dd6865ab84f21e646c33fc271c299211c02350a911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019abe68c3d541bd0debc1b578ea8b4d3ea3355fef68ebb42e84c9ce395a09a06cf34051b5984a71351c030fb09d05156000000000000000000000000000000000b901f00977952479cafe39be57eea06ad1b51519f8d26351a9737415041ec9604faa815a45c2326f3c557d307c15c291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001803b18c8b7e48a9b7123adf02c340c7ea473d4f6528c1b3f73245b9716d40afddadf28c552a442a2a8808e5dc448c730000000000000000000000000000000010780066e036aa27e4132b5e7499155ba4dcacf999dcd9929cce020e29aa4b310d96b592b17221fafd7e742f92555c711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010df04597fcc7d5ab26f51c1e78ece212418dc156da586cb29e5f300c7da75ace644654a74829e697161ace9b4aa30cb0000000000000000000000000000000013a68b30668270a99b5257a41950c8ee7ea69292bf18a9108a2cab2fd5daf6bd174111a9d383229b8c59c840031e09041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee986c68f5ed22afbe5ddf8920c7e5cfb75d0859de625ca1f862c6d8295bfb289ee647a82d58e969431ac33bce4f4c3000000000000000000000000000000000523a4ccd14ae836b482002dbbee0d423dcf7ed96a83f2dc64d0284e692ac45dafd16efb76cf417bc4ae556b1977ab6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160bd45f38087d834f22f03e9376f522c2a13eb6602f49b021c9cf08f7d22163a0cd11b7fd2d887a5fededd2986165800000000000000000000000000000000016559cfe667006ce075cb64f5c1cab437992868a24fd6038ea4245f196dc1cc7a270631b4711f401e37447566308c6831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000046a5143688a53446c5945b17dc454e00705e3ed855547f889e09734db51030548405bba1ce1649f65a156b183db6cf00000000000000000000000000000000137ff006009f34c6259c4b3f11b4288c95e8ad10f36ef98d4b86d038bd4407b33d42ff96cbfa9b7c4f1d1b7897d38df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000baa74ef2afbc4629885fed9bc9fa50175367ae998c40b7cb9e96b2776e13a562a3fea2ce3e6f05126d3858bfad633ba00000000000000000000000000000000087b64d2639e16f7670a86e0e925e7cb8695545f402edeb5961cfde6e754afe30aa30732178e0025fbc72520eacb96701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166af934d78f24c2fc831e160fe1c88931de166013ba68a0a9c3f04ed39b95931b7def3c991bfaedb7fd4629c2ac9c6a0000000000000000000000000000000004e819b46457d7c31dbc87fed71c8f21243373b755a5b6192bd1f8ebf9767ee959fbd8b18c85e4d01f2f0223ef66a6451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1d109f96afdbe33174afab73e36554dda70ae21b69d5934ee59f54d85a287ac82afb9d312fb3233485e1cbbf6e31a900000000000000000000000000000000010eaf1f255887b5fd97a48d9728325553a170821bb534c000c195021091e42b5b388a31a1bfe0dbe0f8498c6ec69ef91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e9a9056a210f34c75264c62778df217d4bc1f409f7f989dd7ae9d2b7a874775824f1fe5ac71ba862abf4ed9c2d7586000000000000000000000000000000000ed9b9f04daf140a012c307a5eebdc96cdd9f4bc353c830fc68391ce5d5ba68474f440a44427e5af12f127bc77b6b0471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195de1ed5057c6c01919cff1c2190c8882c0733c3cdbe43430b4d6eb5ca4a5bf5cfb7a48c569025cbab58d784bf9b532000000000000000000000000000000001983f9d2e3ff6d96951cdd215c95ddc090c8e109ab0405aac22953db8742e11f29e32523cc437f47e1abf2cdd8d31d461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013364f490ff9f457d8b97040312abd45985cb83c2b081b204afcb0138c2f4797c93c50a5b4d8961d2d2b3bc40ae72b550000000000000000000000000000000016a9da0c74b7a65c047069ce10a5d0f752a94d7aef09fc606114136e8f3a14e3c1c8dc38b6be321c059384bc9715b5441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177ef08e69ae13e28037d2eb600d34d2c264ba3a6da7d275b14d1a2a1ab4fce1c5110849777c3250faa2a5f0a342e97c00000000000000000000000000000000054551cfd637ea60ad1b5fc36afcec4edeb34101711cc49a034a48bae6847ac8e8150b4e13d324c269c6309e57a048571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b462261c1aa5f552cf9990e8c8e4141bf2dd818cb6aa8f641a09a9c41b398dc6503fc0b27891f4137bce25822d46270000000000000000000000000000000015ac04d212fb8b661fce091f4114a0a6e4a36364780f0d6bfad04d268c51a8fed74f4b274e5f1e10e47aef57e605a18a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091cf9e04feef995d6898274a2df5a7281e586b846efbec3ad9ac88cf712f10b4a6809b71707837145884ef2cb1afd2e0000000000000000000000000000000005e45bd05e7546d18b08d6f9a6dc5fa775f464aae3223fd4a63441410dda07f7fc5a1f2203411ba430f5104d2fe7e3ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173943fc596ebd53fa3222c3879ea88757d3da19e7856ae6f84ede4acb580ce75e73f5da011c0b928ab89416e96928e3000000000000000000000000000000000d8c10f28530285378a077729151c46de22578815a06dc63e152796eb1a9ff94a6f3134a131f4aa516312cd6b603d6a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000944dae479de4729414186d9d3cfe1b9e3338d2b7d695f651d3dc7d1e1a1a96568aac6c52636491ff180f746b61c11b30000000000000000000000000000000007188fb6f89814dd35e7da3f377f30164ec67b5922dff3b6c4c175491cdb78c7a0aec962769f6ac384b6101f1679b0e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e5ee07700540faf2ede8edd9aef167d8d6bd12b59a031b589b0a3298f0694276c918e7e729b583e04f02caf5c1bede0000000000000000000000000000000000adb6cec4497fcd610afa33294353c5b5ae3e56308a121620de6fb35eee75313ef6a8e66482af72e7dabbfa0fc7aa991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037fdaf03f6b01d61243ff2d23751e1336307fafeb73d4874d42cb28d3772d7e93c22e1226f33044a6bf6ceab2aa7c8e0000000000000000000000000000000006d993fb518dd43860e452386fdd80451f9fdf9e5b16c1502e86e2b8ebfc1fc87c781e1260055517a1b96beb74d1b3aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009106f7b56dcc27b52e46d421fc06228b3c9e29264ab39c80433880de0761352e003968073fff44c9b9017d7f1e20930000000000000000000000000000000000874400363d26639c1eaf4a875f81bba7a6cd00891e19a1e38de97b6600e50d5c8be4c002d0e0b274aa1753d9d12c6c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e709ff863e368314701a79313510676c29aae9cb9ef84729a10663263c89649d942c73a4f631608f0f9f5830049ca34000000000000000000000000000000000db3700adbc48307ce6fccbfac6b37ef4a62c1c77033b5869812d1dc11ab2ea2ad0392582332323e2659b6c2eed20e401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f2e6d62cac4b859e7819ed4b663e1436ad39d37e6fb935ea3ea8043c05b16923d2e62274aa41de14e470b123ba5a9f00000000000000000000000000000000151044c9ffd6be16be4867cf15d17914f128eeff29e0d4f5d09b6f1f02970bf009bf0dcda34d0c950de2368ffe3329fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b4494e8cbb1e0caff13c61bbef384884b34204b1bdbe7e8fcc5d43b0726cbe0d97f22a615dafccc988e55409530d00000000000000000000000000000000000d7d63665627d60e4e96c55541e644aabdd0726833a3566ce6ae14981d85bb4e9d89953a303f25f2bb0a9fedc8446ba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db465766f316464c1a371b2983783a45ce901eacc33e81f79a4dad71f5649a4e8f82cf26c9c55ba8211662ef170ce700000000000000000000000000000000016222ee296112bdfc17b0121f9b4dcf8690afcfff744c28e3f1b7db44dc6a64b0a69a03d4f6612cc5ea07502abb628ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045c5542264a9ca22b71a03913f5a084551aecfb0e3422f8eee6f9e05916ba5edbd56df66901c271d3f448a892434d21000000000000000000000000000000000832ef8d8ac6db89d5da7d0941b6f2b59cab63ba4c889ae1cfcdae2323ce1e777c2f6ffc3b61eff909f63f3d57173f9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2d148ae5f752b11e1c6a42522b056cfbd8fcc60f1ce731b757972829e4d5e2586a28b66478fd69158c6c62afa1d2fc0000000000000000000000000000000006af04048a891bc2650adad04a4994e9f9bdb686806d769edd6cf70611d28ea4a488d927dd80228432a184223b7a46ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb59379c0a31703bcbefa3af8a8a71b66742e7a64e50ae08f95526943321b84e130c77d6ca78a5357847a0845462fc50000000000000000000000000000000017bbd3e2ac5de9a22c9ae1ae13b9f025be97af6db0367c55801a9ed66cbc622579eb51521e4ac9f1b3304ea6feb346b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001805698d12e161ec482fbdec7778926f36886146ed99cd8847c5daec6f6aebe42e67be09695b2befe2c39b22a4b897b3000000000000000000000000000000000547f1161f62e6cc352e7ffdef1e034af90441d9f47b576e99a6a189824fea9400f7ed451bbd8636f626c745619be9751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072b803f64170fcc4e204e96d7a8ed30a6bcbd810bbfae4830d828e42ae9e65cb238d2768ee96c9eed4068fe23739de1000000000000000000000000000000000f26269c72f5fd088b993cc6f1600a27e296cb47ebe4ae557ba305c1fe89c110c78c022432e9766aa452bc5725e98ab71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182c1d8959219c2c7c45c6c2cefdaed170c701cab78f432da61e71709de6b196e1d3b54ce2d57b366b3c738ce5dea908000000000000000000000000000000000e1ab01cce625b3984466675344676ef904ca6d8a10adc0fd1f50a7cc1c91703789ef5b435c3ce207e8daee3cc7684cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005eaa90dc20c9e41b93cc9ffb817499d51ea355f8c0bf8c690d2c295c038adf719ca3c1b0ed580817a4e7745a2bae7f20000000000000000000000000000000008e6189c3440a0028d87f74207e0edbfc358e80fc84308492e6dda8490d50ce8018f9a06e2ebea4577a62046a9de4fce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fd1b1256db96ff920ba5aa5d2053b6bb616f40ee92bb87a5db74781e11868c2933ef7c13bb89f22e4fab0e8e8e9e620000000000000000000000000000000011bf2ca58eb4b9b40b9157570b9907472776f0f46ff284f6d22aa8b1e3c4a9d89fa8c293f4c541565ec68172296239861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f183bc3c76145ed176659b4e591bbcad73fa7e509c82f3093dbe0a443ecc15d62817931bdcd4cf9ef15738dd30c77f000000000000000000000000000000000e5f1d3846b9a6015e41598a5e02522619d3ac33bad98727c723ace55f19fb652d90b1c506f0fa926018d63015da801f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092e5a45b738293f8553b2bfde0dd252b1ffe9969dbd15a33ecd399d2c8dea89954b985c387b3ee40ba95687c9ae2f3c00000000000000000000000000000000037bde013aa0ca45ae22fa89579b3e3ba97a037396fd1e9144ece55911d27d10679658c2dbd7629430a953fb789748ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011fff4058f1e6c171a3654ea2058c2a880c236e01e083dce134ce8397dc640c4138eda38bf4e7e7ce9ca21f2fa3a50a0000000000000000000000000000000007a1ffaa9b7d18b1a3dc7e2a0915d43a4b86ee4a8f601afc9823a836b6f7cec48a05f012646fc8ea95fbb54e46b32d251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000066765e4233509fa2d587a906f7e1bb4e8568a4664461d19709a86569a8f75ee5a67a4f2b6b5306ce7e911a98cb5025000000000000000000000000000000000bb5037ffd90df5a0d2d92217becad4a8519aef07e889b22107c3bdfa0816343a8ddc7ecaeea5be39d1f25a24fe11f481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f0737564f1bd45e29c052423ab8df58a258610d7259682b74427bfffa4f7da3e62f20075678fe60e6ffb7e9d18c2eb00000000000000000000000000000000063f537db560c480f43f6d2be395ddd4b404e2521ca707411e2a1eab5096a3ebc907c6b5d1e6e029c4e5724c69a7a6921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c6aa3c3cfbc3ff26b853f4e72cd6a0532a34b655ab4f19765b35fd6cab099674ac0560ef2f6b64fefb2a2c3ece555e00000000000000000000000000000000191c47355f12082b7d8bd8058c89b9d123859943d76a07a9266ec21380bd123234593e6f5b78be8fc76b38d59e72736c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011eeaa371882013e715b38fcbc590a9d5f2e291b0955ed485147170eeb22f4bd6d6437b0262ae43c84593a30fcfa03810000000000000000000000000000000010c1cd372df982c089032b9d6bdb1058e914ed7bfb68f5c048f872ce0b18b547316f62444f598b1aedb6eda9d310e2681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c35312b114523f646124bdaeb9387226ea2bb8874284bcd148c5fe66780d50be9e60127b19799d4ca65ac0ce5507ca0000000000000000000000000000000003fba228b9c3acd082b29aa42c11399007ec004dd66cfc28ec51889c487f43df432ce628328ca6947555eca25683759d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2f8455d719d941fea3aa3c4cf2f76bd61442bc928c8da2c9966f4b9f9f31d778723a3f6c1a9da667076289027ab459000000000000000000000000000000000b8e5f572457f934133f898370b5448164f29756416918539c2a9d060fde1044865199c226388cc629921f9086c210aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005a96e24a4994cc7ecf5550ecc6ba410da6f800623d6ca348c2a32f04390219954dc5ce1bcc661633fb98e6194a971d0000000000000000000000000000000008de198cf36a506bdc74b59376dff4f3e993dd58bfc8bd39f8a187993d09e2f451b8217b734e818c3ccb8948a014053d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c274d00f95cea7dba561156338053acbdb4f31bfbaf47b1b00e35578849cff908e661dff2e23193e7313463f8375199000000000000000000000000000000000f0d840155cf1fc84a2b4481758d3597c29cf69ddeb1f779a3b15c1651e2f32b36720f4ddec93efb9bba1b47ce0309061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001943c7cbbfb919839e46c47e9f19df641447bcad347a7ce756af314048488378cb6528c3bf932ad0a55402ad01644c23000000000000000000000000000000000aaac972ce7195298ccc8bfc7a3d2c87d5a7ccbed52f441aad7c0e7a00b06559149a6a5318133cd4ab7c6f510b3a36e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000072b0c76dae39b84c6eca2b009511285022e93d659ce55f7ad57049fa2e53ded33b1fe50f8d497430394269ffa639520000000000000000000000000000000008697092a9b93f29bef74753515df6dd650b05d2fea98b64879d0af85a69939c4dff3d1f9f88caac2594a280d0d017c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6248145717f1924cad4f37389a3aedf55f5088661a8160e15dc134b993c96d0d24884a7e9bfbfa497c5e572819f9560000000000000000000000000000000001365b48bd92cbe282b728e23df4ea369a773d51add1d8c8d8c90036f65b51bbab874810cbca850e9580ec42ed8ddbdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148765f3480592083250f19c793dbfd573c0b1a8172303118964538cc4ff5ae7a4631fa67278c2f9c1a10e3bda3ec3a1000000000000000000000000000000000587307541f6a28fbe08bdc685a63c8a4e1e6fff9c4a0744acaed202cb6869d795c2f2d4a777a91eb375f601dc550d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f53547075d2df69025c158b9a1449711cb1cb00b99fc054f5ab1c3770b02447a0bdada9d8f23fe63077126be568b1ec000000000000000000000000000000000064249595c981d2054cc8efb60506a99a9f97264492eb8fed7766b52e0cfda1454756b1d6f28c9c043a35b9a36bfe911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a9b92cd11777eff0e2007de5c644f2dfd1c928cc587254469e51126436d376e549c816f3a554e40b646f092e257e1a000000000000000000000000000000000a6573e739805764878319a042444d72295540c741414d7502e7bfff83aca2ec9252c56385cca5eec1f848df7ac069281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6e0bce29f4211fdd5576b0c68569a601fe642a6fde71c16ba72f10fb7e5bd7e9f608710e5a7da540e73bda8eddc74a0000000000000000000000000000000009086878e3f915c3bc4d702e12a64cb9b419e8dca084a47ec0be0d646b2285fcc85f48c2df26ccc21d477b1a4c1ca0eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001596b04c9c6471f945b91fe5435d3f3ae6d8153ca5d9b84a027a7c5a5aaa60fc7c4cc3237f0dc53cebefefcd8aed979f000000000000000000000000000000001521728e9b2b73f4bff6a77f05ae8e38e21d3c504a833d204f90d9c1b4bc69d272d16035718fdddf2526e47f0748996c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127ee2c384a03fb9531fe7daaf872ae8860328c4a7c7b2601000a7c57ec2b0879e387ef2653215e5d39cf6fbd032f1b7000000000000000000000000000000001206972f4d820f16c691b70cfacda0272bfac32374ddd273d6c925a3ff5f80f0f1e247845e895160e15e2124bb7ad00f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168508a77dbabeec5ad9a0055b512b31056bb0b502797cab99a4894a6c0c8209aa3e42bc54c1ff63f6e8c21fd41a3763000000000000000000000000000000001668fc859075792e6e0c8e5f6d96f55163fd758cd338d49d4446e8af3b08160911d91279f3a2f285813e3d5a58806b671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e61d7b1b208a3e6be5a6bd2a92113719e9706c825b7cde82280c7ef478be45783ea7adb1acfe42266d8bbde294713c000000000000000000000000000000000a5ddcd761be47920253be7ea95c214fcd1627ad76a08eb5c83e214fe6f5262e1becc3739674df2cf7eabdd4627e306a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010395d32e619a91d17aa692a01a28c5da55acaf2436415c51d899fc83d11039ef689be0cc266029edd73a01b9ed3e20e000000000000000000000000000000000fe6ed5d39ef9a6e876d9f3e268b07bd92481c6c0dc01c2e47ebd2b66995174dc9b05d80d99e29af289163a7baed69021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5d2a542d4c8c52c1769b1d8a3dcd6c8919b4bf0d3a80061fcdafaca2cd30ef9c07eb363fea2987e0a1bb24b4651372000000000000000000000000000000000bf382f5fa38e00bd53289e74318b93c1941c550ee992b61b6749205820a541857b3cdcda2f4f3c1b990735f1d7237311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e88d79be7f26f9a68fe451d1fc66cda047e865c8420e239bf6c5018ddfa0a8b535fb6bf266d2e4be586ee1b24069770000000000000000000000000000000006cdeebc76068b695853a4f9734cebff4ed8e30a1a8cf4f1e8276b1d145e193fcfd5cde94199dd17893840d48fbbbc661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061ce1aba822b75e408d960cebc757b1c132aebe888af361b9e73e1d0ed3036fa3f1f140e76115be4d911d2ca923c966000000000000000000000000000000000b93cd4382e26d0fa5e003ae5c356541db03c0786db9d6917b25a061a839f4a4a0e1a85a5c43f966ec87931f939fd1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080191784fc117543f72245ca290f29c1d983ab82a53958295beaea402e348750f424e2c5a90ac231184b07ae29f3a0c000000000000000000000000000000000467f272253efa6ef414180e32806548671c5e0e6ccb0fc920a116ffe1614947eaff98e68db09d8b47384e7666e173231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000898377b0edace3feb8c091692ea0e8c31e32da56c825b3c458172c98a7667c3a28329771c6ccfd80ae6776fe5e380090000000000000000000000000000000006f2a3a801b95aac32ea50e2605192fd10737e79480401289f295ad41133e63880201513ef8ce7a9234eef2b005547ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e37ea14efef3e5d930626e250ad788c96c61d92f990b6c32cad10d390cd08b7abc14d61f9bed0564556b9369328cbb00000000000000000000000000000000179844bab168569b4bc94963a9198ca7cc4dc6ae730bb4fb19891be107bfa35ae6d57e755af041bf59a85d59ddf5f0ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c41ef4708363dcd85a2517ece918da8d7e29337754ef28a0b67210b2af3afc38498c157d5cf70280beb6905a56515a30000000000000000000000000000000012935d0217fe0057f77742acd0140926de195f70c285cd9e08539be872bf3cbe0aa1b702bff7eb105b5ef6a4349fc4d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e95ec3daf371e4e1582ec1d5e0eac2dee411da2152052f231b4a870548cd088d7ef095fc0ff0e4321b5cb4d468c35ef0000000000000000000000000000000012ac24014c6c7933d819b36acb4d22b27447e538faca06aa06e7303210281e45f57c37dccc4dd0cb5177ba48094ee6101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095ecbdb6849dd1059e30bf0c72d03e273400c025a674ce0388269eb0798428565fc4249760f0c2f96e5dcd73229ac6c0000000000000000000000000000000003358950ebb8113746421e4f85f6a11b1b9949f635408791e6bdb834e864cf695968b1eb6ad6e4d0da67129ff81e52821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000526794fda8e74ac3e48fa942eb38cd943f5cb61184b127fba8202ee6e5ad51621a3a331fd39cf7ac4e49635f9518d0000000000000000000000000000000000075281aeb2da660ee1de8baaff2d9c8dc826379c777481658eab54f24244df5d2dcff68aeeae6f58b59015ea22029e2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190b5dc941762ce5e81f369c244f307fb22afb653e1ae62ae34a1bd07d17aa8fe2a1bad1ef595d06485683ebd355f4d700000000000000000000000000000000013c9192ed58f620f0b32c649054d1b9248252c2b30af6ea73a5563434b68d3cd57c7b16cfd9ff6b01cc6bbe08106b831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4d3f60cd85a69d1493e89040a62565f8bece91a2cc17f749355aa082a69dd78e8577dfb00edbca6980198c7e94946c0000000000000000000000000000000005bf2bb9b2974612a52a064859a020af4257a00f88aac05ed1e46b59568260dc7006485aadc5c90f22d48365d76623461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000930f7dd39ddfb1a99d675f7dde6b3677bffc199690edfad5a74fa459be88468cd1bd92c1440c2fc6917fe8668f5202d000000000000000000000000000000000a9cd73e8c2bb60c4a1c31dcc327d634ca87c8ba54910f31e10994ef8b45cb23a66d504c424154b9738398ab3f149bc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009069ad4564d09f68a84cfc09924a02c07ae01c9dbafee7d26bf0964a03f7deb99b05e6eaaf86631765e603d66890a1c000000000000000000000000000000001075d3cc6597f0d2ae57309c865fff945a9fae217eee4c20c70454136df089b4642a1d24f2f5b6664db3f2d081818e5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001470c838cb5159717a5dd9c9aada90f58d4fc55e5d76f53780793f0be07d12cd5a12abed88831ed265849ebccc22ab17000000000000000000000000000000000df539f83ec246470169b2fe9353147084727d8c28f6c452901f8b6921447231ffd5c57095464bb84ad465a08ac170651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fbc2d256aff20222fbe7f4a9a21e24677fada6d05c3652dc7f9d19d5a04e1fc450212fe041bf15af49123b168f59e700000000000000000000000000000000013ae042886cd885e9380702885e8e05f3fcdf6a5897f64e4bbdb109b1d8983e4be03e7096740f1a12a405ee29aa8cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89a783c39aefa705473437d40b7c0cd141edda269290220479bda76566aae579631bfd792e47dce00cec4c3c81078000000000000000000000000000000000192c0202316e179f13de30114a9dad0a0788e50f06aa7a673551b0366839fbe155962ac02e967488784f0664a7b37d4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfd9ce7c4e842e7a506145c9feac1557062b238de6b76b3765e4e231a16ce1b72e78c05fff18c9f23f0c07aa0d0bbe0000000000000000000000000000000000b3c942b15fa9336de467c3f50c18c8a50b23720c4e72eb4b2ffde36f9b74284f9c9f10de4fd31222bd97615a73b41811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdca902dad1b647de40f044a683d981a01092ab2a809b3cd138001ea05bd48cb570e9da8c06d163044abf37a0f87dd50000000000000000000000000000000009f816f5730d73ad167cf51816e4e3a5d81986c4a717eda101b3a2ed17b0beaa6047b9071caeecb5e41aa67cd733fdcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe8387d5e818c5fa1d853132050b6e97ba493a59828468dbb9c2f7d7e794d3c0d14b49d939a23cd448ec6d7c06abc5d00000000000000000000000000000000171552ec8b1c6ad50902d8537a41eb64d192c065383372209a45b99cb7b6be987b1e9643fd25eb38ed40b54f0e8390311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000661b5e254a083385955d4b1a8b1049c45ef7588d77f3811a2aa044890a3dd881385a40c6e4c5e12d7a5859f5fc4eae20000000000000000000000000000000004d15cb7273d118ddee9adf5d2d488f86dbfc2db40e7e63671f5d1fbd891561474e5de54ceb107904ac66f76168fffe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186243414adf27f27c1c61870f2d10a4087d4e8c836861252653f614d494875c89d4e65d91f9c06eebfc8730ea2a79f50000000000000000000000000000000019ad5ea68e90f7ebceeba1ecb1aab1d3b50ca16343885a863d174c05fe9408c75ecb0027176f2e6ee7a9cd3f7956dd151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003060ef4c1092f82f4627bd0256557b4aaee4f2ab3f6527500f5526d839fd07f4d00398248a4eaf1eeffabe16c4b77800000000000000000000000000000000007fe60dcfec1cfed48d952a37da1fb9911e75616dbb409c55d272fd5e4d6c5422ad7a9217347c1a206846a28941d21e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159324150f19f71a8eb856c4a47c02a6bb86f7f84ca73d8735220f83a87b3cbc4293884bc6e8c69c0445ca6d71ef62020000000000000000000000000000000002afcc01243813dade2c8428d411e9a1452f0f821f59d6b9c3c476f02bde37c98c5ef296ca8c477a1502e3a266555c911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d821497491361921dec83c0525f309ae4c9f0a8b3da4d1743d09824c1c05095e2bcb2a20f070020dee2d16468e9dfeb00000000000000000000000000000000075e785866729323f90f63f2965d25a73e66ed2484c089363e4a9a9904f8e6343829bf4462311be378a9426fd4598a5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b03bde49547b7208abf8bca3fa5ca0448c1b7cc50559c50f05e6eeabc9db567418571c42df0c488b9bd32fd1f2d84e00000000000000000000000000000000004ff2a46e8d7aff33d6111ce1e6fdba6f9c7ce1a29dc3d345251a56127f85c0aaaa53d7df039db3a1e6cf98b7becdb241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001858bbdfb037519e8310d95317133baa291d17e39883536db0fbd4053f586d6ff24e866e2261dba0fb222026a24f614c000000000000000000000000000000000e330f9e3fe74ef2f210277c5337c76fc2db293f85acaaf8759407436733aaf114e0f1c43ae45ce74be8c8a07462fb501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001138b90339b000f6fdb2a8507c3f76047b1bc4986d6b15fb542e053953cfae5ae4256d34250874868b6c5421711d3a5b0000000000000000000000000000000003d1eb30382166de541160dca09986cbf0351ca8497c43dbd11f523680ca8fad96e1b97964cea518f0329a440d1111101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dae7ec19e7e13816d6ce18aad9c28b97cb452510117c11608fa60ca4ad30cdec4aaa39e9342d648e945ae6674da9080000000000000000000000000000000013e5c329012e31e5aabb4c5c9e6e8f6a173b59e0fab66616672caba5d75ff940241e2f2192e614d03db4b2285afd34181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001405bd97d0a326aec71bfb79cd8666e93fc2ae3c03de65e17da8118e6371ea8d99caa9ace4565f55e9d94902f069bb220000000000000000000000000000000003f405fa1903dea0ae421712b0302e689beb4468a6f880e9398515083babc76b0371f02a6f872f632c2db6a5b55f39961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193778d333502cb80b298659809854b2d5364628b0ee19e3ebecd015fc72050297dcb5caf8d73d28e88fe88357ebfd83000000000000000000000000000000000f010524dec19afdadad866d21fad76f5ee0b5106f4d3aa6abd114f329750bbe39393ab3c0df89b0304b9f2d7bf13eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e249c15c5d45bf202828aa14ba91c9cba20596c3b6e3d32ecfdd042998e03cacecd8054902ca2ba5003ec7e0c7b0d790000000000000000000000000000000006e0d4a6fcc1911ab063dff8829037165b86b94be9e60b06793e2b7707d7ebd1df4949acdb7344a97e1c2b538944f8401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014df2092137b79d9d7bbcab97a8d0d1a85385645937f0aaa0dffb8deebdaac54151afa68847e9f50426a26481ae4e9910000000000000000000000000000000015506542c4d7be853ce94855c9b799ea9578f8d57098d326bbda687b21624f1087e5165aba36928fb83383adcbb66aeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001301d6655e460aac557fb7934154d1ede5f4471c093586d29953efd2b3d2c7f95f68d45e0adc23bed3eb9cf60d48b2700000000000000000000000000000000014d40a1c55263ba560fffaf03b2c959aaa2f40787a3720608c0cf065e4c5f5660cb20c0d5ccd913c0eaecb29521f41941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080dbb4d68500f00452a4368cb5f87e8116bc9a0162c77f9a3e8ed8c247ff5c0434bfcde5a5a664ece2677e1e31b0594000000000000000000000000000000001454bc807afb4b75e3505a0f888720402383c3cd65e06fa125cfc3e0d73bdb3437db84ffb94ad3686a59f1b7a07eacab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f66963f609dd25d96c8f0253cdb894c23476d117c84ca6a9d1a5e0b2b504644282b11f5563ccd00d15af1d659fbd8eb0000000000000000000000000000000018b75e0be485c28bf03f96e8c2a49dae9cf0981d3b7f74321ac8ea92686df164375205fb9c0106684ab8b74329d9d2841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7ac90ef43108c1bb73f20df68ba71b48fe03ef64cc64de58f9d859449807c3bae15fe42aa73e53b7c43ab484a3dc0f0000000000000000000000000000000016cc1bf2773b58c734fd2eca0c2f64c0ddee8a470bbfa72660d0b53ba6e8c19dfd358a551ab885348736a9df5315e7801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a81b6c01a43c8aa1e113796f7fb17a166177e78a3cb17e28550040988d15a3a7cb9c44ae683ad9fc16ecbb8b1494ac4000000000000000000000000000000000349662ccd1655875c2a856af77eba5514dabf982feb5e320c4d19f86600691116404529d03917d13f83e110b94949d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f6257ebc95205fc519dfb270d32728bcfbd9437fadf399980c65fed9515109f751714a2c59914bffd1b9c625cb5b4800000000000000000000000000000000101b77933d4a59b6a9f96f1925fe304b90598a36384ab3173497984f94a98246910a1a64e8b7f4defbb1be793d021fa11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c5c5120d7f88fe277a7ac52fd6b088009921d2fcb8de3c4b87c70ffef2d386833524502846adf992cc7bee5af858940000000000000000000000000000000018d99c6940332a3ff9a1cee7c7bbd661a21418e19aa76a26d253e81291dbf3f58b8ff90fdf5393b8b8ceb9ac29e137e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001374bd903a00cac9a983f21fb7d7af0fed9fb908155f8d11267ca12919a73a9f3a065a2914a3e9aa6da52b341910aaae000000000000000000000000000000001326bc136b3b99481747df7663ef9be2e5edad64062329379aa5a7de81d8bee3fdce4d5ea0f31bae6a9f6ef0a9cd054f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d5b3d1e854f14b7c09399d4103e756cd6b763b565338b844798491658009471580fbbfaa93234a62a67baf2829ec06000000000000000000000000000000000fa932e1dd1b9259c4963d2dbd1b8baad7ee1dca1974fc5d8b4195d6685fbce02e4dddc88a2efbfd4c37a964027fd9881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbe15975e117331bd3f67bef1c3984792d3ff9bd54cdd4d743e854e08f49a4b53d9995a737d2260e02a9f5c006ebb7200000000000000000000000000000000117b488f467ec590d2fdb428363b14d72af6eb2f4aa57d7082cb0cd0ae94230b55613628ecfcc3960818209a34b9c6bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011aa5cb7bd6c84703a0ac1b4888ca8980b825b6064810544b0a427da4e62a503e960d1cc05c6d7112c01b9f562ca86630000000000000000000000000000000015e6df709464517031c6ede36fd7a3c8e016df0adab2b965410d920c87d753cb78541debbe0109468fcc1868a09a129d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001981820ce5a9cd926cab53c5fe1fbc06a1bb6ec7988d63fc00fea4a19fd4d26bd7c2e79a5ea024d0538265169f7aa5b400000000000000000000000000000000153c675f6c2e8c90f18ab15802d9682947ccdcda7f8b585cbf01054e548982cd221d327955b099a39d320e5b221914581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037f5200639d1b9d206764a3f0e7992ec472c3925b85d842ca1568e57d1af2cc53858cb3f87b495332f9af764ca51ab1000000000000000000000000000000000c7042ddec8091e407c0184f0e886225ac468b1fd8676e578dbaab46837d9263ab5fff8df3438e07d245f8f41059392d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2d989f81b48de70e248066514b70f1802650707158115d7d80f2d9d83889cd9eafe7d1e3ecd8bc6735cc57cce9f563000000000000000000000000000000000e89a7ef8215bddc217d659a7865d2061b99a702a9359084a8e9691f9f3a236f53625eeddec98babdde1ef5ef7795dfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a2cb5351f416e77d89a10880a81de7306b695c8aaac896feeb592c17c483074dc8cd67eafaf7ba28e40c924e34f0d400000000000000000000000000000000058342c8a066b34b0c8b84e3588b612b72164e4ea9fa8bbe12f222c9ac5aaa7ba747cb718517522680c1068daea10b061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a57154444792db7029a46898bf1998652642adaaa69704d5e7256624c2fabb5fb9d3730c817f9cbd4f0535835f447d0000000000000000000000000000000001c9797b58fdd44aad834869872bbc94acbb7d767873de0f6d0f57301d30f82f34d03dfbac6d55bb68167039d80557b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d6082d961f5e8c92e6d20ccd485251eefa1bb89a8131b73dc786786e76aa8cd785b85765cc0d20ee4673ce437f054900000000000000000000000000000000153029a976b9ac56105dcecdda398daaa2fdf59abe05419b8fae0c34fb19fbfebf8f093f250b587468080044cded618a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026736877a292b8d97308b02b1770bbf5bdd3c959635afb00ef54e72ff0095330da53747093821b76068040b3a2d9d030000000000000000000000000000000017e44e0d4bab9ea67f98cc482b6042e4738ca966c440927f7ac8044c6e4a7ffebbfbe41f098058f7b961836909fe88231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be1d23ab6d11f9ff43d92c274a584b5fb90a25ae5399f37c14a9d7b07c02d3facc194ecf7621a11ff0e602e1e84970d000000000000000000000000000000000cc9230abd2cfdda07ba5e1b2a9e7f108cb231d0ffbf06be4376a1cece9b7f989376482e5682d126e167cd26d71ad7a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175a629de9152fc2f77b341c062872f0db9cb8d9f86e03573c343c85fb44225422a8275c7f1311e10d4db216e16e46140000000000000000000000000000000004803ec7b5d515417bce02670d9a8a23f026b9a75845f3caaab6bdb00f7459223fb6f8ea76888667f0dc05a69e9475e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000511817419050d90bcd51fcd8913ea1066bc4319ee2e114ec87cd100eec2278d28db82767e5fdde3e3fa2f5beb4e7b830000000000000000000000000000000007bf3f989b5b1e8a537fe560a52dc025789fec731a498fa61b99894cb1d13338309f49a1b78947caaf5bb2a2aa2be1a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001079bed1a00eb25d893af30d4337581bac578a11c8ab81de4e3fcf446536925264be3103d0208edcd7ffcda41b8b2c10000000000000000000000000000000000647606a0a95bbba268f8b5b2c2208d25a3b0cd3075480455d8775c30311c8865694a50f00c915d667e7aceb9ad468c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a067ccbae5f18e71acfd43a7bd5797e8af6f87adf0adf6d1c5878998db8a9dfd10ecf06cfe36f1068b5e4a257f06e00000000000000000000000000000000001816bca0a2eeda3f7a8d2e458b5efd2199890751bdd7780a9c000b11ceb253ada24d266b0a58f1d195f5577f771747a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007be6d6a62dedf527ffb005ec4485092c683c0d2d23fcefe8bf802c7eea1bd976ca0094ae348fd96019b5f05e340ee41000000000000000000000000000000000c91e78075e8b55388caf2834dd67e627956e833f502c5df9faeb93d420d6049e53baf7de3232964ffe6156bea40a0681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015df5618e0709bb7e205426bcf2fdb2963dc58b23980b7b9090dfdc4a66c582be60eff275a4825b8138e61baeba317500000000000000000000000000000000010d3136d3a1b43042fc946cd97e5a46daf305a4e11e64ee8d384921472d10b9f783fba9e6972439b462a91043849ee8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ad0149c87537c68e6ad8ff78ba2a209691968a5ed6ea2def40fe7d2d69488ae19c24688840cf2d880c6b15ec9b404100000000000000000000000000000000160c3b7ed995b9d3b1d29edab8ea2660b1a5b59627a08f57c54cf328f6379d5ba5e1a9532a38b09a850f2abf117a38f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000277b290fcb8ef1381cd44297a1d3bd3a41e5fc0a6e2f69b33da7b924d487acc5c9048ee2157a61b36b25039d63487fc00000000000000000000000000000000035e64315e574cf16896373fc3f1667563735a8552574026bcca92390e74cbfbe5aa84f872fd8a2403731a0c6d831b591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019072d7addcaf9e8d1cf24fc1920bfab0a85ce1ad7157502b3c0a3c04f808a1f17f7d241469bfd2d5a13c2860ae025630000000000000000000000000000000001ff345f762be619f24a165db81d208a3bc005a01d96347d76c64551f830c4b03bf6726e80cec5999973dc2fe54bab561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000670f7b47e3be01c0d248f3981d4a87dfe845924f4d908c2519cd100c89db6dee93d229c42af80bf2a05cce8ffa6370f00000000000000000000000000000000187ed7213a20a4d720903b1944a2592e8ae25914b9d67f99762427c17cccbcd512641001b1750cd19c0404ee36e88f471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005e6d78d76356cf2190879248a6cf520204f147b429bff70141bcd8a5faaeec86993a7a9eeefebed30fd9744fba466b0000000000000000000000000000000004ea428181993b93b472062347b1c977e797cda1baababdaab39cb6c6eb2d1d3718a654f73e7d919ea505423727c03d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093ae2a1ec4618c4b39800e6abce822f8cdfb991d0eb6090dc0a6c6e96954d651cf974addb619ba56d3251de6e3e2a81000000000000000000000000000000000a70348af1dcf1c1db01721a0a90b26c3c63314a5e67e93bf7bc9872e8d5ca43300648346248d043030ac65abd404dd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187ef916d050e60674d8409d5d89c495d4db271725dd5740551a78ad975af049450df424f7737167f4d31bb75e4da5a500000000000000000000000000000000054fcbea4998f2df6c510b4c3e41a50d05d9bf8605b01ddce218f63d4c4854c6e81985b6b97dbe368b4a983d5f9f29b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ba3f2e8e51c2f618b5eb9f5aeb78f9ab3e2c546107feb8c09eff9efb56c8321f2bdd726a830cb90f3a2b0252beeded0000000000000000000000000000000010af855ddb859157b11279a6abb66abc6de67eea324de819bd7a6cc93484ce89a4de969c87dd1ebeef78bee0f24565d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018eb485365ff7f1fa6b842101eddd76670444e5b9908c3dc6b2968eaf60fac66759f05395d4090b99f9f69a2ec1bc0af0000000000000000000000000000000003abe1d5312f38a06745cdda9e193245681203fffc3f130bceddc9dc26743dce701936586fb755521c5519f8471433af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6c7b6ba73ff633caf970c83fe1e3aef50ffff5fccae40d52de02c317eef50a57bc4bc92fe7f4d6ff3b60686dab92a700000000000000000000000000000000193b6b799057ead3bf52841a55a94fccdce3e15ebab7f2b00550003d78df067987d9933d43d6543679408ba68ef66b321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013a71634ed6320fa0cdd18a78d39d3c1b2230efb90ad4e6e6efa103995d691c7bbfc131caacd198a606564af6b8c43f0000000000000000000000000000000000bba692670a6a6d9aa297c305d7576a438667898a0c121884d652c7edf991d4e0e914d651fb0844fb5a2088fa00fb531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d54d53a051b0c590420887116085e1842fd9a48c6d77d546ad12c383e59bd05ee86b9bbad29565bd053f8e6e4b026bb00000000000000000000000000000000027a2264a9eef42e1534b8aa48d72b40c4ba5962472228e35efd52e3f2b8c22a04e3e425e24b7dfa4e02041780ecff5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000058ef6d2d2a3af97081d0163a1e0baba0d4280e42b0e7483a81342d72faf731be8c0c7f2bab0b418b87862a24a4e249000000000000000000000000000000000362a99fa453dc0c348233f0f04288a940fe4ea50b1503d46c2c80293e820f8e2d1a9067677708d5491b67c1fb6723bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc96dd8caea981227ddcb73f9c6a18e0394f5e9c42a89f25a993a84daaff24d1652e9dfbb6f27bdef3183bba8ddfa14000000000000000000000000000000001111376fe8f10a1e11310583bef0266667ff3a5dec59ac84d38f8c5f1a49621ef1b6c8267870b66acce1c32001407b2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa07f9cbe4aca3e884423f35ec8421bada2545c1b7651451e884c1d5da8bf6e93b70c0336d7b81c7ddbc182df224ad700000000000000000000000000000000050e0772cb72232d86921d21300c1a072dc00f570a6a2b4f734c3b8adaa1513d5becee1f3e4be4fed7b023e6e19286d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3ce410c7b4b37e1fd076937d3f72a895c14bc278e211a49be2a7751834db4041563830151065cd89336e75c987033b00000000000000000000000000000000159baa0142037e38e8517cde6e9b7f78f2edcb6b1fe0ee877ecd22f22cf0030fd2fa213c6213416751c606dd7bf9b9401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccbb81e72c037de8896da7f4f7de007825e2b6491edae347707bb0029b2431355f4be783d0e6dd096ee49fe44a797e500000000000000000000000000000000011d88fbf3d25d8938b4654d7c7227913d633bbee3cc6d1a5a199aa9e414c4abceea43aa4146574cc0e3cdbdabf2d34b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000513648c2d6e2204edf40dc93222f1f5fdd6cc2dfd10a0158a20ff7b30a1bcc47c851e427a19eb07d18c6e7b118e3bd0000000000000000000000000000000000a7665d23bac858e716dd4d562d4d4a42c77810214f1ace468d013249f547bf0b9cdb4950219f47d5795a6788035308e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000268df8f7fa56c6f519202169f5601cee1808169b7ab63f430928e2db4b5a3d886b32684858f3e3d50286bd731f51318000000000000000000000000000000000c5c9a7a75b5880ff423921675b48ac071158f5f60180cfc61fd965ef730c65fbe5a2f152c188498b0229d5798f96c7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000777c87060b349ad985c877989c718a4f37798a13c52c9fa8a3db7177211de5e6dcec72b977f9e25fe0e58ba11fc7abc0000000000000000000000000000000003fbac6fc80f34bc319a0ebd4bf999a4272970c980aa05d5c5c7006cc27d62b9accbd9df50adaeeead30aa978eddef0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3ad6fb16c0b31d4575289c7e883b9d724d1c76e73cd9705813b0518870735b959b5ea3959de57d69dcb1d9c0ac854d0000000000000000000000000000000018572f4bd4563ed92091fc11389ea676cc084c97786c2b765c0b7097f158e92112b533c056f8a394544b35301e458fdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171f6dc271611b27885a064d2f3227b6a5d2be3f03f879bb3ce51e76da6a86677aef505a154fe290f836f33bf15752800000000000000000000000000000000015ca133a1541846c899300ff3587d22bbd3c2a678b3edab62a1e6cb765a6167892f6c2b8929c1f5f9721fe0685a58d211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f59f626e49e5abd07cef524bedc3550090f1c166e0c1a8b9d81724896df1c7fbb074ec896d9079d153dc08f768773a1000000000000000000000000000000000f75a2429c6838a58f311fbb03502968c19eb092d770bb834f0c38ab652ba18fe0152d43b3ec70eea02c619c45b91f8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3cc95fea0a1be5a2773b01f7c35b04e24590d206bb23e0b8538de1827917531f2134a8c2ae9213306dae150b4fa62400000000000000000000000000000000035d9748285140898c34c99d4e5054268add04d1d02c6add3d1ad87eb0e70eb551fb6f682170639f77f8e384d751bed51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001875c68715f254eb73a0d8d9c4d174ec49ca34c3e539594b2e1b111cd967f908c1892ad5c9dd652f3081172ab94c00db00000000000000000000000000000000000bcd4d859f032503e117d37432906d385411ce82761f1a3e5e991912e43dc0fe3d3c37c39ed9d9a8b12b43beafbfe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fac656894ad9e245c135530694d0359ef129607d8c5b9c0b0b45a4f9370345f0d6574bf8a1e59d945f1672702a4b880000000000000000000000000000000019b6d4d205a6d4f16c1a5a4a92203713d4a9d3cf6620d1070bedc8c46c27d81ce45e1f9d0b815e3b74d7e0d2eb97677a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a9ddb4e0d3f819a2099abb38e74949027c96b878386076034a9e70b99694ebb9f49a09e6dfab1483328252b1c4f4bb000000000000000000000000000000000a97f3855553d628abe26b228152a96612bf243996b0f3138ddb81ebca8b784d6c9011d7490859f40880422f6c02f04c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040bb10d7ee88b70e5a5a6d0a3525b0b2792adf9525e78126f4c6e9d3c83be501cb99087180f08f7f3dc32a71ee00d38000000000000000000000000000000000f8d38e563f4ea7670073820170f621c60281b38368a44d13b8a21fdac7de1ce7e5fc6d410498a6ffedfb83ee82f850a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc92969ed4603cbbd19ea5a9826ae45edc05a56e8a8c1bcc306c4acc83e2595a74fa0ecf3384f9719038370b2fdb00500000000000000000000000000000000059b3ad11d19cd6c1e236f4c9d5c712715b4219d6ab6349b9d2490a82a23a1e1a16a6d94e457e12ffd40a55647413e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108a2993a55c9bf059786adf8b23b0b59f0c2a9b6d2ff200359f9378dd2c381728d753f181f9649f93821a3b1b22b7b7000000000000000000000000000000000b0e2c40634756b24bc4a5419c6b78d640fc8752fa6279a2517813a0d9587bc50bb052538a640815349202d587069e3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b69202a9513913e34759b04f9abc5ab86e325b9313898647cb722cb67907bea4490f94c8c0451de4079e524a955d9300000000000000000000000000000000142b36e6aafd2629f5f71d234d2549c46ca62582cd25232db4faab388dd68996740da5f7d4aee990187d17d9d2b86af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e903cd3607beca550823cacf5bb25e6b3aeb098ab383e04f1d1e16e4f576ecee7daac869b659691a7ad2b06a32520dc0000000000000000000000000000000009ba5dc1e11a67c56df51a27cbded5c23c3af496447f20f4c493859f16cdf2c18042fd0a86ab94c614fc13e7b4b1117c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e12b9ad49403f8fd114f077208e1d966721ffa3bdfde0dce1362e3a47e6f268b55f369553f762f95fd749bb129b2e2000000000000000000000000000000000991e85882c1456b2882f8431df90c422a8a969005e6aec16d5c9f666aa35d2944327e8d01b7f14553ebf65a8ef619051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014933ac10182e37cf3041d7a14d2ce736167555540f86fa2c84162d75004b1342c42ac0398a6747b0e694b21a74371230000000000000000000000000000000009c09e44a0cf2ac232a7323fd68896176595c9ad0e2042e476c0f34451a52500ed41c564aec8548009daff29a73451511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119f64273c6e0ff11bf3c8e7e66fe1d48cb2fb2d3f55a6a0915e8e8159772bbb239a504771dc5555c3fc7a9cd341fd8e0000000000000000000000000000000019ded20f8dad5bac309c9608b601dfaf4a4512f07496fea84bbf5ce85b86d05e644999b4b5c18322b12cdc2305a6909d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073ed8b7e60ad6bd49a0397f3e45e645591955a1ebc239ffdcd8f51213855720ce4fd84c778edb6903297a118c6429ca000000000000000000000000000000000e6836dd05b8a52ee9f2929f7c406a1bc87f6606e72d2bd119c514f816cdc6e5976c38c2311eedd4967b97e8997bd1571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001845685f599467136dad67cf8c0d5d456f8eb46d208b8bb3694664583b3596c52166b370e12547f60728cf96cf404dcd000000000000000000000000000000000e6abbbb93626da88e5b73b71aa87a69d5d42d50086b03ea7b2ed2e1515814a7e2e14290687b5b90a83ebd72616c8bec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199d1d4fb3ac3d96f0a296a668ba00077f8c907d9e600b1e8207ac19493d0cab9153a6a906745cb067f60180ca6f977700000000000000000000000000000000034af3cd8be9d7208e09a5397397f866f2f7f1d3a359793eede42b0e1fd6f1290b4492f01bb245b30d2c0ca7c561d7ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d27bde0b186d027b1a38ac5cdb5f81595ad2aad5165afb4c1847eed5aa705285c3d07546225e021c67232fe37c986300000000000000000000000000000000011c89fbb17895c32e51aef8b9ee2562296bfa7ac6881a2ec880481a9169e257864660de2b7f23478fa76faae2086f281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040b102e069101962753068282b4124ba47e667f890623479904a54304d33db3c297a7fe075f7382ff71ea1f53a546ea000000000000000000000000000000000f6198c132e1a85ec743b23c8d0bebeacf5ccdb709b7f4f5587abea22a5de212f1cae7d52c243c48b14af821793b5e161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ee325c09040132ed7404091a89beb19ad73781e401cfcaf88f3e6f52147e8c5eb9ae9df9b904aed1fa6576010bedb70000000000000000000000000000000018d4d09fa00ea0bbb33ea9d9498afb405426d5306f4edad5ded0d85230e47656611f4df3e3c7617fd5116e7b556219761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016837b7d12ebdcfbe52ae077d7d83cbb1d2e6d50979e60b4811b4ba3a48fb87614fe874367191872a76e8cafca334574000000000000000000000000000000000c7aa0b4e859b4a425fc50b0024f5127f357da51a163063e375b6145367d73a228a1cfcdcaf15078b97a5f52e58a67f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006788fbb0a4139dcaf5b36da3c982d06b86adeb0ffeea53d5ebdd059f9ed65e53be33aa61b90fb6f807bc350a5c8d21f00000000000000000000000000000000126b61daf11191f0d2dbaab4be602ccb4b3571fd8ac5c55d6a3e5dcc29b3077a5e1b5df393e101c921a4e3a32a5188ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002414a2cff9c306e0fb92319b60d01f70c46e7aa503e1b508f31ee249978c6d8864450e13ed18ea8b2f909d5b504ccdf0000000000000000000000000000000011bfec8cdb4e3389c87e1a6cb4b11d086241c2a9b8c812b43e4c42cd98b53a77115465dab3913b0841cc87d156aee5161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c2432ce6174853a469528591df16dcedf50f8128e8832535176f76f2ed1a4bc574ee87fb09ce3b13be24ec3b03d9dd000000000000000000000000000000000beae4aa819fdc59f631f486f8997dc881f54aa97426da0860069e624823c7c072074eb811a9c2ffb0b63cdd0132862e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b414cdbaa033c2ad06a5d56adff9c0579e537b7e14c3389895642b6b6bad9beb277e274b24716f66c780edaa504e6b00000000000000000000000000000000177776b3e2211fa1db885d8013b04859421687e2eb8ff171c4afb645580e40bf3b3082504d8c8c4601e23c58d6bb3a601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6aa32424487fe942b544a5f2d4800dd477452a26ca9f8f8971bb64b3188b7ab891afa3c5c62aee50ce561f2523e7b80000000000000000000000000000000003a8b9578524fb9f8ef4e2b19c43e8a46e1572e8689404f10daf74d7c69984d572c19c3c7c1bd34ee9c31f7cd694b2581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c803bb1d3332d208d9b03c558ee18ca1df6193653c5b4303819bb7d7e3b5a84d53936e07741145287f2d87206b60a300000000000000000000000000000000113cd724eb81d728b7898814737ffd5b45f9d657dd9520b78245bb29e8ef6bc7ba82ffab9ece6a6327e41fe2e75443c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089911369b0ec86ba5cc45cd2e27ddcaffb0fac52d1eab834771b3d3a4785b37b68643c19781ed987d29a1f5ad453b880000000000000000000000000000000015e6e5e7702f1f80f6cbe838084fdd88769f715315be921edd2df6b81662434342c277fc8ef65c9764266c8a914e80c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069d852cd5d8ceb22cdeff2163a0f273e04f92db160a98e01c4325d5ea78dc8b7687cf02d112ff91efb3fdb56e775e9100000000000000000000000000000000024d03df6337e86715911f1a0c9217395c53c97b15f2e1ac3c12c553193eae8d7eae489d0a3c564a06d431c83f3da3de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8a35913a0e359378f371af5d0f3152cd5640cf50e0972d0c90aacf60341b04ddcf86548f3f63870f169a9e6c1b5b540000000000000000000000000000000011a61784f00d089918c68af8e2ec3893bebbea59db4a1173d54b16de7839f237aa33de69b454af927c1274d74af956231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117b9752405efaffef6c7088a2dfca8ed00f0875f47e9f4a0f9c67cf8bd348f75f302d9910b813857521814e97bf5eb5000000000000000000000000000000000292a121cfeec3f134fe9abcacae7feffdedbb67520d9bf3147d8d92e39903d1a63524f9cf2a1f461678bf1ba5903eb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dabb132b3a316a5c4ea0febf7cc5105f668779cb0b9fbe0de85ea37902dcc9e5c56416d3519a7f5abdaa1eaa0aa1b50000000000000000000000000000000018636b2e95a5aa1c3b19757d034afa502110e93ac937a41cce00e61d7e6c75816697f983fd6810f9099bc904086228ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011d641b383d7af018e07de39d1486e7ae5fb9e2f65017c8c17718d48985cb4133a66893a67ce6acb0fcdb7b226ecc030000000000000000000000000000000007f11c42ddcd5b7ce907fd8aa8d26e1fdee1ef752451c1616a4e2e3f0cf4ff080ef3a1cf7af65fa1b5379baf340908661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096f5e5b379b313b7301ca5b478e98bc603a4d3a580ae5b7bd135923d2948ce212f03dc9832b12a9df7626b0a756ffbf000000000000000000000000000000000c2b32bea66c604a275fa115a9dfa5de9dc4c5620cb2fbf4321a3d9aae180e63e9ca7d9faf5e392fb9d408527dc3269f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9cd3039fae087fb1bbb7d6d12e0cf73c2b5864ce9843f7df37665ed6299feded350da086abb468da154e70abf3830000000000000000000000000000000000b5c720ba293ecfcdb0e94470d8c3553bfe22271a194235eca8f1d60133bd3dd54f9ed0d754e032a7bdfaf7fe99800bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be8da433ffc037f97f94d6c6cb1cd696c49c37ee4698e29875417ac427b1ba75afc32dcaabef073d8ef94796c781e200000000000000000000000000000000001221d03a3a0bca806bea4ace393b824f8761fb5a669c7e919fe5856083d140a4c2202f18c3c0d38d25e1302838400d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dd01dc0ecc42430c176d6634a4f4d68d99b5dba42810566e85c7e485286d7ee88ea012e40c47d039fab6103dc9effc0000000000000000000000000000000000270aa2a32f03ac705050396829e343acb4d1ab3fdeb867f62b9a309484174530b77c6e4dbeacd8aa27109ade266ba41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a4b27b9982397c7bcf7a665befe3b160e708b81fb24ed138eb21df321a424dcd2aa3ed6dbf7af369045b302712668c000000000000000000000000000000001349f5e4936d730960e6dfb10fa00e4c9c53052aad9b13e2def43a3ddc6b31aaf09b3ef56a08a74d9789cec0ec3c506c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052bc5d3c971e200e845e89de02af916e1a232ea30cd69ca1db22d2b958175d2db1b38f583ea77f85e5da8c4e2642e710000000000000000000000000000000012ba5e6560e7ddd8d5d78845f08e570ffbf22f68df79333a4f133939157e7962a49179fec9cd4e03748d5844ffa8a95f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a4e15ae507023d1cd89f11b4ae46fb6b9808ced455254c6a9cec276b0a6a248661a44b84ca8dc91292a35d9807439d00000000000000000000000000000000177a39b719fe15ed797baa1ce7e33c5a3bcd71b1d647d708f3e62e85e95acd142cf7ceeab22725801ae87e13189c823e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043643e84f5f29e50bac5866a487b513a0c4e75fa9356a287cc4766d12f04b13f794d3eaff2ed3d6df5ca12fe48fc4c4000000000000000000000000000000000e64e76ab8c59c7fdf9be4760a40187e0df2e5f1e369be791e182070f53faf5a144685e36d307346b3d7b6a04ae213ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001170abb6403d1e138d2ff7aab7d5decfb076b619da1660fb9e237ca96b2a850e8b8bcbd6a5cc931f568c57dfc401158f000000000000000000000000000000000acacc8b40e6bd476ad8dd6f4cc658f952e065d3921e335c7de80d66521a821590259ac196f42b6bf4dd15cc187a59161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000883ae630302997b8e92a47dcd37eae5f2870f76a85c34d034eb2bc3e32476f335871146a8a176969a051d2ad1ca9748000000000000000000000000000000000842c1161c8b3b0721c88105fb0d6cfd6aa83588ecf6913aab2ec14be69cebf44701bf603d8e141576a0fec48f6ec7ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033b220a6f2a407d8b3db401179d09f39fc8b19cb82078ccb2fd08fe0cfa19f0a7867b09b89668f7b2087a23496c2647000000000000000000000000000000000d9e383b599c1b9b135f7b860b157d0422a1b0ea9687557a49faf5d873f08d59d9fdc55461bedb1afdee2a33ef12af2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5dbfd1c7253bf2760fcac21df0cb92a8aa896a4102fa691ebf15656c836cc534c9493abad0e402aa0adef6adb61122000000000000000000000000000000000fac9a6a1906d0818eeba8876b2ec0a83f49a91f6233d0696fa66e72d292d5c21800260f3cae6fa279b36d062335ad1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138c31b66ac1da0e369a5335011246a217548126ce818d1dd0d8100bd5b4340a53138768dea6364797e3ac7da1aa0f35000000000000000000000000000000001846d92180a161af03df383985284b3fdd3ad35c0b577658e56bae74fab06be2603251fa7fbff5901168609797d783e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139c94c8d8098411347b27652f9d42f4e214235639a0676978aec6d098d4828240d74dd74655feb58ac65f69859a7bce00000000000000000000000000000000064bd993ffbf86d08049ea63376125dc5460f07a70ef2fb9c8551f12f8554c0cc232cd1401f144745612b01939f747dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011380a7cafe40ca8e1ed3a2839c5b217a3aca3ad7b33625594e985ca58182ce115da63c752e37f66c029d9b49faf2ea40000000000000000000000000000000010d03b5bfe5cddea5b1bffdbca496eaa20cb9c551cba27145be5e1eff5cc73af530c70c1fa4fabfc2d565119073095e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195edb05eee8943fa8a62c94e65aad4da45fc03a315747e012141022da5d2d333c1b87ef029ed8888011b47ae4cf53b40000000000000000000000000000000010593b5d166a017724a7e8ccddc3ca0b56cfd55b7ec143f091f6b214976c7914400224046d823e6da87a59dc9857c6771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b64ad58fd04d22278bf4d2bcab984f46668f066b131bd1bf0cb1fad285987eba64a7ced070060e6f7aedb70aaccd0d000000000000000000000000000000000e88777d4295cb4f9102af1442443023b2174a9318ebd1af0b18369d413e1a20e86de219f0efc00efafc5f15faddc1a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e9b4a7ad446e953f5d95790c1b9503caa240b94b59002a364f2936c09eec34af1ead5e99b5d9a9cb5ad704450ee9fe0000000000000000000000000000000012d8bb9173c977f2ab3e8eb25d159a95ebb5e6147af0008bf46392dc35d039af382429cedddba16ceb97cf98d08e39471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dc81b524a6aae4a757191664b3c0b0b8c70bef533dca813f862daad51bdf10987e79508e976967a7b8c2ddd8def6260000000000000000000000000000000012e5a2d1083b46d322c4ea18e878415731078663fc034baef37e917c828a32cbc88614906f3d59e9087bbecd51f5ce361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143ce154c47f7e88e11434e5cf0f8f0c35fbd891c5a6f53fd5d6918fe674a80f6d3ddedf4d20ad24d61d21a2c32d5124000000000000000000000000000000000679346665be5a70b32fe3d9013ce91b3498bdbe06ceaf753e47d2a000b28f305c353fffe0346d82e62941cc48356c0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143e92530c85a6e8ab458774a61807ec666d68005f1bdf3647a6e1bbb864bbe937abb693a6cbb48022fe64a2ca1ac23d000000000000000000000000000000000de9ada2838d974a599a8285546f0b9ab9d8f18f30b7f13e9495461e31b9340df6786dfaad1a92b2f43d2801ef41b47f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd00035ab7c55665646c55292dcc66610cb469cbf8ac75dcad016da69246eac903af5a24fa2c83d4747bd2252b457f60000000000000000000000000000000016387ade29a0dd23f86221ea645e3d4b444ce786cd8b9b540200d6eabd6c59a488a62526405405c263e5f8e6383e0e6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcaebd6cecc3472645ef0c54d3d80c63948c2093043c2062748b31e680f8ebb62047b34da9b435e627d030ff740750d0000000000000000000000000000000002a9d3a722e3aa534f544c2c1cffa5fda027dbe34344d2be432d8ecccd557fecd866c0adf747e2c20c42cbe49e1a7b991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cb26b71da29b7422b9f5d6d7cc7771988ce7e01c04e0453104c177ee1f0ecfce5eec5415cb252f28636a70185657cf000000000000000000000000000000000a7bddc22a31487057f1b5f461f0a3b4003139ff51c05e386e36481d0527b5094c1a469a5b6021faff594dce88db285b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2f0dc367b5a4fa5ea6a00e0d5531936b6f2897b026ea418dc3c6cac4607f9b17576ea3f87a062c67d17e6574b51f060000000000000000000000000000000014add8a8d829dde6abdd0ed62eb2e815ccd6d7790df7399445fdcf2defd9665786119be0d110cbce16dc2c89236aa75e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006dc6c77dd06a117efbe0ec4d51ab491094adb420a2f3cfa6caead0b3d8b8ab9caaa25e782521abcd07725367098f8df0000000000000000000000000000000015bf93525e4be9fa4fbf55cff1edb1a53e018f90f6534735e6444321f6405af5fca1459bfaab9c751f9150cee56933021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fa957b164db4c8f426fa42989a1deac8edcba231b49c736595d6b7242dd3638e1bfb7ab1b4a8681a6f8302307dc29500000000000000000000000000000000081187a22952ad0ab4d397ad4d809e536863f888e4e7d843d2fe67d4ce4b5d7f673851f1d8b70501f63226211ddb540e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a98638ddd8ad888a5d1d237eeafde2ec4313df5336d63ef033f57360d334c2984d1594afb190972ba883d2ae8838d5000000000000000000000000000000000e39195a92bdcc68cdd0d3fc8557adfb3e9ff200f26cea133099c84db24418f768966608ab0fcb07b3652937fda818a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cacabf315a40a6f03262725268d659feb28ac9cbe8f6e55429f8e36e6617e03156ff8305eb32cdbd2ba0d002d23bf0a000000000000000000000000000000000f81defe89ae810c223ae455bceed16853f5bea0a1ad30e12d357674bcfb54d11edfa0d2dd851e0f10f875ac6a9bdb6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d389ca5575e17047b573f98f12a742c13195f5fe7febd6109c9603a9951c8e8e46598615667ff2268dbda39744a2fc0000000000000000000000000000000007a2e538b44dc6b077b02224f90c82305660fdbc4cd725accf414ffa23903a4d04fd23a6c421455ccee419658875d0ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c6de630499f97ae3c613078343e5fdd83d0f8f185f7d78e2a52698d317ed5b9a478b5c5661500513475f68544ce170000000000000000000000000000000003119b1f9dc9a6be7a1a0ddfeb2f323884c2a84c2636d6b584e01650ea08420cd47becb706286177878ebc9d291a2e951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a12489b1982d5f435607ce6348dbc7b53cdb3c287a579264cad11a9188cc04b7e15b1c3bd1a59fb350a5d5fb3fd3fc000000000000000000000000000000000671a0e265f44fbf8e1fafb4a7b190076d8ec6b541406fa96003f60bdb24630e7135032be49cdcf3babffde0fa6e63f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b9c7f582d97226549831f4733ee8e00339797af74344c615ba5dcd1058ab32846105a75c13e2d799c63aee1ec46fbb0000000000000000000000000000000006860dc1d36bccbbebaa61971ac2bfe8c31656df5977c7b70454208264ca67e3bc95fa8cb9fd1fdd9fc2d0d4563a4b2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153050d1942c3f00784dba283aba7e8df4850266523d83a073f057e9115e2216822af1864473d564e3b447e258ef1e9b00000000000000000000000000000000004d46188c4a7176fe28ea1847e0234afddc06b70541a11c7a24b340e0697e0aa3149b6f128b166879042906c8daae9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a24d8ed7c9d1fe6312af518e116c314e9b9e47c4fc83ee014cd96f6349db28e261246ea9d1f449fd68c5973d7efec900000000000000000000000000000000153cf2081b083d132db97377da31d6f7f1c9037919b8a6fb081581ec8fe1c0ffbb1ff3c3742a9df481e8c03dbd1446201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123b5be8612689fd54b7a51f7e8a59112b80037eb21857bf36511a111dc84bffdfa44a24790713878ba695f61a33881c00000000000000000000000000000000150cde68f4574cd1fe59d4b564238726dc47b85a632d4255a2099fe9acac32ad79fc637657662a7781de5b386d5e8b511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000201963a2559040627e3319277afc837cdf41bb5afd0c5e7bf2ca54e2fd3ee8a3ed876273f73159940230f71b242939a0000000000000000000000000000000008269189cc7805901027cad209a389b2bc874c5f3c1e9dbc202ddeda38cfa3d5c4a6f0e76d64c9d197ee8733e5a2f8371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d401071d0b8a04e9c675a63eed61a6b3602663904819f1dc6a007fba82ff6114f462d670b749303f60c44d0b4521db2000000000000000000000000000000001024d6295d8ce1827340b93d6d14ac47cd9894a7e4ac1c98e1e27b2f337a52d4116fac1524ec8f53c78d649eeb2bc3d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190afc05e895036170b9870a9e1f05b179e9ffe02e3fa4b017c89614b06c261a4c07f97d5378bfa6402ff98c7a0adcc1000000000000000000000000000000001296b02a572f5da700f05496f6083c5374c936b2ddd2eb9602e08ac237312856d37652dd5680d5f77d865c7db31d2e5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fbdec5990560e72eeddd9ab2d8938056fc1e2eb3ab0b6ba31031147a888425f504936daae6d7045e94060edd72c6c90000000000000000000000000000000008d19fab6ae96b8b2df46e3207721e06531b61b450ff8eb0f06de1e5df6473bcc10ec9a466915ebd390919ee09fdc4c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfeadc59f2148df1fff4606ec606e5d8c9545faf20976f789c50214fed89dbe830c6a8d209e5ac1704304b0ed08666f0000000000000000000000000000000002de702dc49123c7742b65c981da898e94da26e4b4bf86a9111c64452f68a2daf45c82dd8b1e75ef4f67e4153a15bce41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017754bdce925f6e10f51673621ead49e83de7d4210137aa0c3b2acffdd108bf3115a6f45bb0872647986c2eb6d6a6f6f0000000000000000000000000000000004d817aeb2a67533533b6db4d3efaafb40375684cd92ba0c69f28ea045c5a8274da3447c514e30d32044c21a60b71a351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042543a9fe1871e9d78807dee72a0252a160e44495799b2e0fa92fefae95e663814c3d5020fa35093155291fa0c4942d00000000000000000000000000000000028bbdbd96316a5c3418e8c9beb229b557bc550409c1efa84e0f8d8dcbca790dbb8ae396ef3b217a59ed3a7467b614661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ff06fce6692c337abd42859b64920153887d1c73d4a0741f858d9a69f0d78fb44422288ec685899740c1ebb99d79f40000000000000000000000000000000006ebefc9df44d309f642eb4641525169492c72b6e47a922b11204057678be15e95e435c65ec065eca4502cee7cbb22781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006755936219d369b896474f39d14f2100b913275f24d28e4b6c815bbc9ee7d08f675f9bd6e23c3708b0ef47ef26f9eb70000000000000000000000000000000001f8b711e110fe63c3e843eb1ead42bac16fdd7651e2b12bf7b2172651835e941ce098576c19c1e4d5a2ad922e3e25fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046e9af65139407e3ca011044c41e76fe4506c3d435eab9c808166d52db94695af0e9d52653e1f7cffe15c89449a674b0000000000000000000000000000000014f225c106d8231724ef4d84cf1696c81783921e6698d412f1d63a349639737c5feb050bb90053a33602d460f1261f051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f4eb1e6db912772fa878f42912998b9a4956bb1313b4755befac36334ec70b7de2f683ae8e03c122242a1b51ac3c8300000000000000000000000000000000094d115f355571334c0475ecfe2a1af05aa7f32f96a691bfcb6ee56022e081402e92a387767eae0307003f5b9a392e121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164fb59f18a5628acca55f27918b5361edf348a8b733656b4fcc81fa220e672adb9d01be1265cc6d4a8f1682182043d300000000000000000000000000000000179c954c9a3d9230e29e0ab589be535b65d837556aeca8896e777e7026d9c1a5c68eab50c7dd8676fb75387d2b64aa741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9b0df0201a0dd3007e8b8bd1c6dc0a1ae4d97a1db5f552d7e9ced5cc40028fc38e677a870f55714b81886b6bdaabe2000000000000000000000000000000000190bf5fea0cc427ba8202e69481e242d1e538efe117cac1a4df0737a829c098680f7bf087db3d1f17adbd5d5cb116201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bc1ff16c8796c70e1c5246e135d854ff2156236d01a6579206fbea337c34869f1d067dc18588100a67570cc9e3a4d5000000000000000000000000000000000c9694089a63bee85a314c0514f8dee88dd570524d885790fe2e61b9ea0e864578431b18ebbe376e429087a267c8dd631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfd2ce375e96b14036dc540ed9f7c18ea2c121b0b4124e904730e3caf3e2b37cb08d6fb6f32d9d24934c99ef22c6be40000000000000000000000000000000007f83abc46e29bf9c4cde4a014b9bc08e937d8a87359914c4e2ef230db6c8d167fa665d7daaf2357bc30a82072b1b18e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173df18946b98b73c8bf8a10964d8af3b029900f4c5d4b18defa5e94926006655aad2cb086f738752c9fc66870f7d86e0000000000000000000000000000000004bc48ed518656cd62ae5a7ff205347a45f349328c546e066353726a2eb33aedc6ae204f68f3b693593802f307a118bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118c567c53b202810e7496c2a9c9aeb94f41c76ca3e440784a5ba33ab54a0ae27966f8db16efd8e439872166e642afb1000000000000000000000000000000001816b32254567a4b74feb7b01e885994ad7b4d4b5b9af292ab14a478527ef8fb4dbf4b352df0f86765d778cf01cb06401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2512a7e313a9f225831445193d450986181bb182b4b3e8d02ca46c36d9fe9421b8d9ed74e6ee0dfd27d1ed54c2c36c000000000000000000000000000000000fcd56e3f88a91be248459eabbd6110935cf01a60eaa213c9b2aa89203059154b4cbfca4af201809649d13675edd3cf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001787b7e2d9406442d8f8a407bc1e4f038808795a2855bf0933ba4ccca3df79f2f43c3c18ae79aac9d521e159d30ad06d0000000000000000000000000000000001211607289607bc3c405d73756896b47884dcdade02a348363ecafdca5f53f4768dbea3b429b59b8bcafee3c73fb2d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c424d4b0f011ec400149500dca7b5a942247f7e7e7ee566bcc52a40311e169cb85e804959be2d36cb05d9e0ac8b2557000000000000000000000000000000000d297a1b3fa0b811bcbbad49552f26d68016a4d3916488722d877968972e160906eb28e8d638e8132476425747359eeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b06972916fa0bff8f5473cb0102e729aac7914c8d74f8c94b538747c31f2383fd4d876932e74aee52f86ebee79d36800000000000000000000000000000000070af831d3b1e2f8e303b7b82631f56000814941ab6db36e82e291a1ad43710bc64e12ce3d402434bb9707eda73087291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cfa731c777e7d6530c836ed98582c23f8fcb931feb3f3c506b8a01a5e583e0e538e4385eaed7c11fbccd58a3f9c74a000000000000000000000000000000000733ece5d96e443141b792b8f3de66149ea84dfcddca412b6d1f0c205d969753024cb7b464d202f1140aed3eb2979e131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb315504f879ebead938710b9a51626e7bcfdf9408f584bb6a1f85421bad0f227c4e0924d8f3ed771ecd1223da21130000000000000000000000000000000017f8e4eef94aade0e3cce2a07e22eb318663f4bc4e716ef8fd46f323cc6bd5297ea088f664431bcb129d8fe4b67cb5191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a217c3608cd3e40eafa9f7665cb910d4fb58f317cd6a64bd433652368279ebed63a092ec9002fc36a021f8315e0768a0000000000000000000000000000000004056d9e4adb46c9667b123e6a66e53be0dea549d543f97566def03357c24307578db03871e75329b44dec182f1129ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af4a323b0c7708ae28c1754fc925bbe8c10a14af5c9a1427db60ff55679023d264e9f9c2803f92572ced913be7f7d7200000000000000000000000000000000195211e7386cd27b0e57d7718392a09560c7a81f255729d97b156dbdc4061eb656d5b265b4c49916e2999a6cf7ff08351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140dab8016f211f47617a04e7a34eb7675ded713287725c2a1beeffc4cf66d2bab4a2ee9df67f1761f338ef7767f3df300000000000000000000000000000000183d1ba515211ede4c275b4fbcd1ba0c0664b5cbce2e516dc2480179af709d38f1178d0f867de2e690f2ba179c962bc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c73c71a629f193a31bb575fc7e091e61d34846b8d2277ebdd8c2607ad73d2e8a266c95061b9d95d4230ea6ec87bb9fc000000000000000000000000000000000a47bf60c1590c4fed2ebd20b6dd7ddddaf4c16144caf5d99db0eb8f6e819740d21e3937b97a521ed918e801c7aca7281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013726f60b21f838c40890d86d3939fa535b44036aa2c264c2011c00ac811977efd1edfd5e46f733d8c5b7b528874f03d00000000000000000000000000000000126ff6fb3ad7cbe0839b055009f77e4209e414545afd6856918c547cc38b760612c6699d62a363154e60eb9ce085f6271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e90fa89c97f843dfea3edf7487e99ddb9e750c0bd37ce07ddab645276af09ca0a4049c42f83969966aee81a80b0ba00000000000000000000000000000000007d2f99dfccbfd8a7d744a30b3e4eb77ede9fdb8a0c9bc57ec84965be8a44fbaeef08b1989a863193d79b786f869a9d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163b4043793c01b95d9512e71b91c905d378fdaef9b5ea6d65600ac9a04be1a1c997b2595040bad16860e379d029b82000000000000000000000000000000000179491b4f75e733e5ed4072a936f1c00a1adb21506dcfaafc8a2d59a3d1ec3b76e77465c8fa7ae2b9694b10b90850f631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9923c972befaca40ad64f1c93a053fffe1e71b3b8d510cc63c6535ab409bd829aae7eb40fd06d63852960f42b5738e0000000000000000000000000000000002d181470ab2ef7ccc5ae808a812347b1f3bccfe91a612aa7eec5bd1f01057d579a18da7d8822488c66eec6e01b0cec31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b963a11b52f91ed718f745ce62477f764464ca726ae42e4cc3d135d7aa4dd5cf64eea034d12c4ed3b9569b10d7fb07f000000000000000000000000000000000c876bf0a44e29f825d0de9006f697b3b3a01ac1ccd489a815d165dc98b10da82c1cd71e4c5a83fcc0665874f062f9301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4422a0165f90343c339376696417f446cb1622680bf2868474ea83e8e9e51f6f7a7b68c090e0f75f6086c444a1f52e0000000000000000000000000000000007cee964bf34568daa423816ccc27dd061b3c9138ad746c43c4567289a6381aaef2926faecaa02eed5482b07be7483671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011090f01d67847d44d01ec69a68e7423e737951e2d4e6297729d5f9d1a10dad253db00a461382765c8953d1b9a8489b900000000000000000000000000000000155c84999fe4c8b93179713e704f3c7ee0bc3377a785477e70af474ecf6fc966f15f91970e00ad69c9152dd39fa97d001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bc244fffa93300b5179e76649829556665a61975ad5b4dc74cd7a33dfd62b335cf1f16ab6710778b3be3561c26b94f0000000000000000000000000000000010c74b20f18dc98e32fc4bcae52d763e51f3bd0a44b5af0869101bf8a147480d52e70ee3c5f6c3ef5e0abf9c4b13041a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001915c7448d52e8cbf5bdf7e97662bd2fe5242de642b8ae14179de52641d877fad6bb300ce7bb423de6b8dd40157c48ce00000000000000000000000000000000102d4f82db9ebe90f903868ec6bd84f73aef12ef691afbec2dae3d7f442842ac2e1d8abb8f64b05a2b0c2abe31ced50c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036605d1822e9fb91e8c2f4e8238a3922164ddec8cb2a10da31e712c00402f622801d73763a2c9b4215991c8c433c4d600000000000000000000000000000000189bafe34a25d9d0e94b677f8c6d92e417a38baa2c92c3e5f5bd4efb166ea26dfc7a2af97ba2fa7190c23f83e7e34ab71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080ff80a65972897edd715b62f5250f855912ea7df90226a7b0f47a936a7b25c164bead1130b133f95aceb5cc0dc9285000000000000000000000000000000000883d8d025d52ce0e316c4840ebbcef1020b45906444491aa6156ca03143f0bf588ab5871c38824b15e6295cd3729b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011005d4ba614033a414dab053fe3369a858a4df0847a3f161c19d4ae19e96f3470936ce9150ae68b701890b8b3f44170000000000000000000000000000000001619180bb363d4a772a08533892fe7f1b9b2df3a791e687669a186186fcd16c80c89e0f2aa138f6a4c00dc5e25acc98d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052b2c7f72827649881467aca8f83d27a31271872e268db8f5709fd70d5421ff43a31527facd3038c2abcb0202ce5d100000000000000000000000000000000007ed5e0ec694fb3570b4d220ebe13d10a2e41f052bf56f6ce6ec1b8325a854b99a2e5991a117987d82479572d2f7202b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011881698ffc63c3c93239d1d3e323a2d4d0df82a32879f25f2b1d84c4f9e13832acb61a2590b61b51cbb09b94f3a466d00000000000000000000000000000000084baf8b96d01ae4cd6b55bf8f7932cabc573c6e997852b86acb2701257d23a0aa69391bb83758bd701882d516b64cb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a943d030f67762680aaed35a758c6be0291fe4f35b00c8508feb255f54353fc42c5fe9c742c5ed3adcb4962fcdc38b0000000000000000000000000000000016a6dbdd2cfdf0b2ee7ff33c8930bb983d251584a4cef2d4d3e141c528019b3c9f4ca298288bd2b424d567527c1159341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9010e787e5fbabd62e3114c7315381d8a1a1d76c67d5eb74c859796c412ac81db64fa9b9139815b4113667f96d8e260000000000000000000000000000000013c794be94e9ccdb62601bc4d8f12afe5b0276abcaaea97cb89eb33c4e315b4658a40611b7553b43a0fe2669827e06c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5d448c62699967eb0012ca537351eb13622de1006e950720691f0714f44d52fc795740653ca194e84dd6acae41b312000000000000000000000000000000000f29652a15934cbd5e28953f328e2d82a74b9e87a5beaefd4ae34e9fe4665c54d0507d1d4b74d45859be85902238cf0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b63f37d17c68f0475e3db0214b10f3ff20e87a22a4223dcd3fccc18980be018012bc2e16531a0aaf26d847f164a6c100000000000000000000000000000000198493adfbd103cbc5b15c9805602ef963df07cf8be20a0923eb53b64ae462d4f58705dbc3da591b5d787056bee9c46b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054497aa82c55c71b141fb372176eabe47d131e75bf049e1d994b6e8717e124079627ac293ef56d20f0b21e9658222600000000000000000000000000000000014ac1def6bbd5bced059b2a950511322ac5632ed99b2ea286ede171692da44a1017a5809124837c77df571aaef274fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001475a99e3755f855a0ec149b1b35cc6e43f1c717e33f975497cc4192ad0e18a86642618018a867f8323e613fcc9bd98a0000000000000000000000000000000005b81b4a910d4134ffeaf601289c3a7dd73afaf57ae3303dc0842aaca710e620e995c86e67df3273a14c374b08c903a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1347c4e1c5fa59d4bb3b30eea00652d87009d37a1f35764129115f53c8da5c9fc47275323474204114caf67286a28b0000000000000000000000000000000019f1925397fb0919672a483b2bf46e5777d30701c5b99138e4eee953818bb1584657d0563e9a5331ab76e665b610a8a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005474596ec8b34cb06927a34cb4b520202e63264dfdebeb0a83e4047c3516d4cc2949ee8514d7a06882d9ab58a37db0b0000000000000000000000000000000001baf5db373571eca2799cfa07c525eebfe9e993bee30cdb04ecd78d18eedf53a1e84a188b159c51ccfd051e194956da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018717811b337b659036e0842689a02a1b71aadbe503a20304b2276bbeee5e537499f334741fd21bef4c2789be394cb0a000000000000000000000000000000000e9ddf17df99036bf57843567e3eef3a2ca4b2ea0f98cd1e7f91a1fb6ceb3062b4c6c7332d073ec426ff65f0d633a0ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5081286157d40e84761957662756abc63c296438c1f5029db6b69ae5697623f1001f3be92a85c46976359e2533dcba0000000000000000000000000000000011645fb51ac18b81fbdece6f246f73b6dc0e83cb286edbae05c9c9f24637996ba6178aa41fc99b93bea7c05ffca5ffda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c37ec44a4cf6d92f4d70794c120e985805f65e1dd88425db221c02475ce3628a89469ae2ada6cb5e1d0a12acd8663f500000000000000000000000000000000087b3247af0bb89b0ea60ed9e2052c1f65a4a4dbd3b32dd137702aab5767d336054d97eb04c168e705b9fc02c9cc2be41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001116f13891f7d68efa0779d65b32ca048fb4f24dcc665805d33a60fe43d9fe327cfd328ac7738d50a2d738141a1fc4a60000000000000000000000000000000006ffbbe26e6ef58b83edce0e944213fdbd7a924c4cf15c4329537386d253a7b7e3255d00132f93992e82fad7bd085a281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ae94afe20e80965f15bbf5775002ca4d49fbffe62915235e52ee77ade15662246b7785b27b8f1e2dceb0b11e0fe3bb000000000000000000000000000000000ee364d9a38643efcbdce3adc1ab1a99d9e8b1e32d57457ea7d5f4283e50826395569803734292efc0700c01bad6b5a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ae0e828a85730da0c3bc6faa80c7edcc0b8462a476ed0a98a16bfc46f0de14b439e15c2e635c8bcaba00372082c41e000000000000000000000000000000001958c3d7ba82c7a58f538c609f042ef0b9827381677aa1b793daa3135caf67663e4c00a2aeb6b057511986cf9d7e40251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bcbac2e60c2d2503047df3117d0000565bfb03a89df73902fc9de907b5ed011d3f111d10f3d7bd73282049c7ce83de00000000000000000000000000000000158442662776df1a98b36f3e24c46d8a2c3ddf64df0f108782c262ad69ea69c749c3dafdad9596636089ab54c247c0731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0c5108993f21d6f399714bba57b9bef8779c7d179db7a7335f28dd097efdaad4b1295cd6d7fca94fe0bc617ff15c630000000000000000000000000000000011b077f0d08361292b13af72fc5bd5c6fcecf903bf7027f5293eba4162db7b8677f07e1c7e6a1551d1c52e3e2d70cf681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127c59f3b02767161303481f4bbccf5e43c6879b895518a6efa114a17d54a839ad60d240f284095b2bb42bff5ef2d037000000000000000000000000000000001239061bf3c44f0246451ad3e70681b3e4c3de80da91501830cab7eb2499fc312e4f02698768d9417b6a9e6ca6ed085e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083ab987676d27a6201c76029f7e9f6a8ecdd459fb9cc8c2bbbc5ff3123e61811e59a2eb297e6600b276afef8ccbf1bd0000000000000000000000000000000007d6d1eedfdf6e6bbe79c59167615687a0cd0eb3ac7e90aca363bf4b3c0aa480dd83d6b7bd77be21dbbcfaf52128f3321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c7f7582e641496fff87d53b9fd259c68c2110b134f0eb4763a759c0e53a0efcb8c153e3eb8341f1d69234d4526a61f0000000000000000000000000000000018a7212d8fd573444a6d6d461ea3564afe24caa43257ef4f5c40608d58ee8f42cd9fcf5a38cc91ed3d53f102554b49471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001076c511602b96a7e70e612183b14d88bd40fbcb07b6e88b948b5d15064f2f542512c1622146cd96973aaa0068939bf4000000000000000000000000000000001018e0e742184bc795de9d346bf2eed0ccbc19219f70ba57a1f57e9437d78ea0ed2f5bdc5c43c1c3c263fa50d4c7c2eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001908d12f0ce564d4f6e032f46d561a183ab9bbff034ddc3454d22eb41b4ffb8f6d16b11744b27716e6006b146a53864400000000000000000000000000000000164332a0a8edcb843f7499464e2192ad764710cbb1af8c8dec1991b0b4e1a7279ae82a7fbf112d8019e618b2591f27621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000979327714672dae98c4267010617a9c98f3035c0dd4fe0b51c67bddd7a0a3f33c387dc138cc15ff979ad33834d45200000000000000000000000000000000001192dc158a369ba124c4b07f54645dcf7c825f3c6e515468982af652211fdb4a309563f870a69d2688d098e103f8fdf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc78fd54480cd8dc0d3e9526ece7d5a0a010f1a5d76439f64b669ca86e96450f81390f638f01963828dc65fd24f59580000000000000000000000000000000017eb4483f12e68d6273bee33d27447b98f23cf012562cabdf3710d46fc31ec359a2f6b9ddde6a236143616f9da78c1a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001194ad3565fa16dde329ecf41793c0bde4f14d806d18e9b2fab16d79ba018c2b2d9c234b9b9a765a428ea7e188b5c6340000000000000000000000000000000005c77cc4ed73e6fd14eaa930d05a6bbde53cf5bbe2feeba055cc22e5114ed86fe2160865be91c8d7ce5f4685f1d82d841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a08aed2fa9b3e616cfe2be8eaea968ad42eeca456f394453481d0aabdcbb09eb25c82073f7b28da9ecb6ec148de5a3000000000000000000000000000000000d4243136bf464f4ff36a8705cb88eaf4da3d362a85b63d7da8d575630758ab147f817c7f55d14bf99c798f1059ee92e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e11c518fe9eef2c692734520a4fd39ab10258622cd5ae317f6669fb5db60518cbf42a05c3215c0345e10ab458e6eb2f00000000000000000000000000000000199b41f04b918e0393a5e7adc6412cef4875d5bc03dc808a3a02386bddf964c30b28d7839c45a0d92ae750f341e67ec51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007763ed5ceaf0334e494284142117834b2f670e9b09ebfc430bb5513274ba4c61e08545d6faa741a17f05e17123c42a60000000000000000000000000000000014c082b07bda10a27172210e5953e4313d18bee178893364f19ab3d93466fc60cd95ed4b0cc5d348dcce17b46869ece01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178f95e4b974c56812fa9bd57d03d5e6617051b62c28c971fa1f421d4412a5ef261adcfb234dedbc907903615a8c7372000000000000000000000000000000001945808b48dcf24abeb0237b0172f2d8d91db6535dd9acec72331bde2ce6eac34ef5dd4d46578bed3eb6e27bd5df492e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ae400178cfaec36cf6ecd126c77437d9493ab23f0e4054a1ab4618a6ac3574e2b992a1aa3adb085baa4ecad2f18a330000000000000000000000000000000006b15e8ef4ae4affa0472e07062f148a7d2f689bbddcf5a2521a7bbf24a7d56d2ab2a619b0418483ad2a5e139ed9d14b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4f7ee6d5211d7d315816bc5f4b0399a0feb57faa106b8754a70655235f75e241fb6099bf480ca959b41ade8975574100000000000000000000000000000000123fcea6b6493d6cd328aef22bbd435a2e181b3da20d506deb2f15ad923f89602f45e1402eaa344140bacd5840b1a26b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003713b43849400fb86bca5d7b3c5da7a2fc7695042666c19ace1c1375ffb41fdcc21a970f1277486c05f489d7e58a9c9000000000000000000000000000000001735ba468cf126e4b242530f0f6ad46a98d3a04cd5a6c19e4ab8fdbdfda0857f501274cc315e088467bde5765440c87c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001714ea52a3c84a6e67f262620da111b21e5b8e3e1b408f483ae63e4f2969be2698a98f181e2f7db311f3fb6a6bfe60d5000000000000000000000000000000000bc389c0f40bf0af0f81662e8fce476302c2e34d1dcf7c7354e95d69c0e6b80560058f5d56b982dc56b7d25d706017001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5b09130fcd7ebb14f1d4abebeb2cab306def81db20d18c9be01a3cb96e2cc1dfa52f6dd9d085497485aab356d0a4d80000000000000000000000000000000018d49f7eec034531130ab18d4b9886664cb0ae4d22614b386c19fe8c4a9ab57a9817d33563848379d7944fa4ee0006481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2c36ee8ebf65603074e29ce922b85f2d5f42108c203117f0d9b55d99fb9daa5a60571e12312426b58e3b992b9c12700000000000000000000000000000000019fa3c7f4a8fd30b5849fbc41c96b363c427d7c5ed74658a52c11b99ec4154400a9faf3a1fa19469766a003ebd4f488b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e05014b4c4349313b9e035b911b21456fb7326182893b016da710a06a77da823cc5860f8b5913d2cfe196a3f0b4b2df000000000000000000000000000000000327852d486f0bc820758d7220d6645a4786cbdca9e51c7b8f5f3552ad7feef7a7a3e67df7bcd0abef70c5fd677f27451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d38bccd0f60aa32e5be727a7a6dc5552eb9bacd5c4ed69d5e669e40e563169a50efbb76f731f0b9a99457d5fe25ec14000000000000000000000000000000001828e3dc5849fa5602cb7f91ac56b9f65b63142a85aa38aacfe520e606140b90f9d389fe5b908b3a81365f3bce87b3291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab69f688a10b84fca21f4fd684f35ddeec3c5c9c56a3769f43464551b00246493c67728e2ba5bf05a8f1976b4fa898c0000000000000000000000000000000006bb30e8ef6e7818b34df86834a65d1a1b853101ecf98f263009547c8172e7702f292b560a0c2b8a931c734eb829cdeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4090e91a415cf6f4bd45a2019b409b1d2e6fe0c7c9805a3cc569678dc18a4f4c01009d8313b526c7d341f9aca33ec40000000000000000000000000000000010c7bf76566aefe4060b3b46715d90c8e0cae138f4ccf525ee291accc7f223efc9475873ad550ae3a5015017801059ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000611f2177daa3cbc71a63c48f26cc666fdd7c03033e6a00be0b6a3fc88e692f0482747e73918dc97e65dbd1351b0bce100000000000000000000000000000000104449505fee5f8b286000ab1bc0a3728bc95113c27bb5ef67503a6dfde1ecb0bc4da9d3ea763f09616c53cc7c4181f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000defb487412d2c74047e783689acecfb8574ddb902fafed26b72336fd33e55f37a275c3fbcd8b6f577a199c7d7d8cf9500000000000000000000000000000000070be97996e1358d2ec4160def5f2bf6637d9edad972b7c4ef6173d7639acaff511c252dc05d52dc61760ca2511a426f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c588c907f721a8370f1458aca82e4b75b3a2f0baa2c4ad579c84f7936937e81e36c4cbc9364513cc8328a97790a34300000000000000000000000000000000089a72f2da003b65272356d54b0c7db68f0f11f2a70a72a70fb7c56093a49cb4b1974c7174801f606137ab09fcbf87da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012280dbd1e2e391297643900ae37d96cabb7dbeeda97b4940d67916c6af0f3432f0ae9531344e26d8e995f38619c78d30000000000000000000000000000000007bb2584e9ccd1e9eb7ac5f72f1f3ee6d387ebf1ce5b70a3bbb3d47d722548f2ec7760622977b3c3df68ab298711cdec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001166f0b407c94a5a540159c67ffddeb376c281108acc0d8909b46f325bdc11d2244c05a12445e742a883a67111a23940000000000000000000000000000000010924a74f6835e83fdcf019173fad65b79dfacbeaa23b88758dc63250e3d3788ffa81130e3485cd85e9dc3e5dc9509f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bba0d33b345a9e058c533660d05a6175e05ab05fedfc004ee499fe85a73b19dea6104a3f360058e756ef79e44b4a89a0000000000000000000000000000000001e829ba021603f979715f07e2b1d5e8186c8198530b1d0440342346006effb93c008ed134ad4c7232c75d73d25855551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170dcf2f2c3a32f3af069f594dcb1f7b4ecc37611f8f97c7de377aced2c99e03abca5bafa806db9b559e66481413a3c00000000000000000000000000000000000bbf781c376787d8972891957258cac4b90c633dd24c422720f366a2ab04f4d81355ee5c569692a08858415e896f2141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010dcbc6102675f8d7244eca1c777ca3857892852739a1bd01c75dee2f1028b01e58e98d380a11935058998535d2c9a3000000000000000000000000000000000a13880a5419dc6355846511c1512fa1c6b6935450fb90edfdf7208981442119011a068776d764bd1e7aa481f5864e521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d7fbff992dac19d9b7ef0a42cf607ce2c7546b4e54cfb061448a3b43ed93b35027e060202418403389eb9ccd917d780000000000000000000000000000000001ac0934fe886a1d3d0099fb22ed656b439a89ffd239cbe572b38bf5edbbd695bb8971aa2bdbdd432ac64002daa849c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067fd0384d3430ef534d37e55fe9f4e68a7457a53ce0a85124ed2ec259d1b4f4367ebcf0defaca5e4930a20a10b35537000000000000000000000000000000000d8c387d295b5255e8f73a522f76feeaba9a5464955978669ea30d3346c2ff448b2308e722957b5e2238d7b24a1acab91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a4db1cf20278acb2aa644c24fbe27cd50134139af6112c0729ad42c803cacbac4c6fe182e2476d4baf626ed8017f6300000000000000000000000000000000062d241391d72da8c4a9b3029708b321242583c3ba13aad2aa5e1f2241f85ac44375510df448207d02074a1691f11cbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001681a37159e2496d99e15a6d1ab89fa3d820425e5d7b7c68e107f1ff2963e638115aad27e74a7b81eb07bd5b41a2e8b3000000000000000000000000000000000e9ffd3cece19cb759e3d32b9e7ea9537c0002e99920da4f4c4e2c4c9dd9a90db4f6ffa816653801c8c5f558ebaccd081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c80ece557162009cc57b458ca49a0819c15bfee08adc9a567b34b3e6380f754dd25e1f0e2bb0b35310fd8b28728e393000000000000000000000000000000001221229a590c65ba74271382393d822b05ed1d249cb266df4135d1d29691f20d23bc73fd8bac06071d78ffafb71e0dd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118085bf96c359a52bcc33d8c97069881b41b6735a5bc8261f871708ed4a6382df8b509e097aaae73e4694ce309222c40000000000000000000000000000000010f22b11ebba9f0185b02378adf464516ead32a032e4d429c77bcda250140997e337fd07c584aa5570d55c683650a5151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ee8e85fe077efdc5ee35186264d7aa80d41a4e8753f466c5d60b69fe021a9353834ae6e7c4f9cdedf506e4084b36f800000000000000000000000000000000136d8f32c889c32b0b07379dbce0dd2d3aa3c2bbb542f15e383042fbd6df583c119fba7acaef8156d456f03492eca6fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c485629bcb36d8bd43c2a94fc6181ab904d866a9efbee406e5fba99deb6f1344b202a4d60eb31dd364478ea14db9d9000000000000000000000000000000000d7b3aa6e4227774e7a0aee80bd6fb425c307c33e8249855eac88f6befc67afd7f4c4081ea0f1ce1b97a7144230a1b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2215f1de6e8013ced096362460538ab6d337ffe6a62ca157076639b9db7587402d45d199da52f2ec7dad8f570f9486000000000000000000000000000000001316b87f4cdef09b1c789a193958f25c9d22ddc4e960f32a8d928775d7c8e67e13194829714fba6427ebd573bbaca8fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005f88d52bd8c91f4e7fb1eb01929e7d1907d7a76750ffeb44affc4494294a483206a325a3b688480062dc600d97c97900000000000000000000000000000000066b54d2565b6ee4dc419417973a043e83958298f9cddb8b4dc4c3cdbe4f1e872e698d9bbbeb6c960e46dc576f758b561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156b3af859234f2c0972d940f918ac883502a936fca14603bfa262f2d1bbaf71f6faf1851c7eb5d572d7f6ce060cbea10000000000000000000000000000000010b4312c7b8554701c1b39e769f59c9afa29014d001f2ade36bde785e8950847fcbdc8c8f6308c29e8c355e79b4025d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102a2ecf98e918b13eed5e1a40e772d715dde0d13a4b4441e9f0d82ec65d30e11cf6ad73d1ecdff46dea90680950723100000000000000000000000000000000165ee9c3f6f62f7e780b3097c1bfb9a70019318967740d52fa7ac2cbae9754b19a016fdac534ac04c5408a47af500e5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ded56615e622332ccdb3753f2adc3275e8011d9c2f590ea4fe0857c5d10aa4068797ef3d76dcdbe6d9b611f2eb744800000000000000000000000000000000031332bdc675851ee2826c46caec91baa5ae21c285de9c0c64ee08293d5ac5a0cda7f7480466a001fd49e1ca5a64c0791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d0b68675fdf406beb82d7eb14c62dba14664d8972357f0032e585a877d07d7e62ccd46d8164b72375f54288988591a000000000000000000000000000000000707237c7a311eb8f608eccb34f4002bf604def08c1e05f38c9ace1c02ca7c1fbc0c74012c29b9fc110c13d6ac74f1a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000c720191407be03659e04269d248b965487dd80e0c3ac9eb562a14f80c2fd37ce72ef6fb2b7cc109e127126a9c306f000000000000000000000000000000000ffda2e4fa57e6d9dd3a32dcb61f61cc6e402817af7ac94c40906b63d856618657018849994b804aba99ac70fa48513a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129e3166cb6f3fc4d20976ca9733bbf70ec2fde5040d58e975388d6ab43883194dc46d740981ff723610726035a0e5f40000000000000000000000000000000011c1246816dd39f72ad79e9b9ebebecb64aedbe7c83055681d659b631e19eb77c7d78dada74d682d3150b6d1c5ba17fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003077e260dd21ce1648efcd9121088abe78151324374b311c99c6bbb0b2f9d94ca60c34fb56df62712c455dfee02ed1600000000000000000000000000000000054a206499ad991b143be06b21c22a5be618173dede5b554b4c4224e0e80e91f0ca7d3d1fbaea3ab62ff32b7250dd32b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f3145e932f0cd1dd5fe622e0ab8b926e39ec3b2fe670e99037a3799656a1bd979cb2b3be7a3039d26fee9744c935f60000000000000000000000000000000000b853f10cc0235737633d8ab022a4045cf64e1ef14dd231b341ef820d2082d66c3f1dcfa15b0d691f6d959a17a38a8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b4ca42cb0d6d4c48d24c5966c745cf84db4702c583f8daf3997d29c9eddc6e075b067ce7de100c73f9a5d252c27ba0000000000000000000000000000000016e7ce4d5b37d9e9e2f7ae147a982e8d986966a0bbdb332315f72aa568466f56679ca18dadde86eaf7242a6e66c3ec6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf67beb5b99fb74071b3b98b241133cda05c4106e9cc2ae52b1396495db43a61c3a1df52e4c668c1f5a558f1b2cbd66000000000000000000000000000000000492722d3ead5b23cc2e48062d9adf5b0dffc17d3f411d8a69292da6b8bc5adc2245ff9a9d63b85c45357a69b34060881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005084f3d992f528367ee4ce3b1777470e2bd701e1bbc85968d409216059e35488f789d1b9250a4f99bea991dc2c98a78000000000000000000000000000000000b8e89980b1621b5ef11175405d6e929051cc70a59390a9dffdd0d03e1dedfc0f7593ba26bd61c06992767abab98fdac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189c2360775c7a9b1a145b50d06e5d7c29f5d7cafa569d5d2f0b8d1c1f039968d9b7d7f786718a45f7ec0f576fc7b6f000000000000000000000000000000000167199bb310e2e11d2406fe0add46d3407571c7bd0fc49c5666f2062f28a5b91fd2ac479f7c4733347ed463dce6331851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd205118297c7a56b9ba83e471f950b8e88b11e8aa3ed773d46ccb191d62db1ec3b66d57463c019d1640dca3b2f7aee000000000000000000000000000000000fe84dec9dc2899ae1cb762999a85d5a6a00893d5340cb6f4248f7228dbaa7fad15dec036c26a9f342aa91ba281331901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028c3275e9cdad9bb98e01fc1a888735146b3a91bef8002eb6eb4bd3e4940cfa6fb9eb35e4b6ba7a7502655386c9f0330000000000000000000000000000000003ea3fb82fe36d835f9f5ab5558859c0d81ceedc7050cc34e143063d1211455998af1026a32321023bde5671579c0a031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001563cfe5f00d2df0c36e7d210b5eff9c59bc4d1dc3ecfcb4f4e5c710106f21fb73eaaa65af5d06d7cb78bbed8b1e05100000000000000000000000000000000004e2a74d8599b5ece040b4f3b1feb767b70855f10336ab49d63a1b9c32f66baee1e606361aa53e83feb1c6dbe1bc1ef71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072bec02f4ee67a86513f8059b837591271faa901929b6f64808b9091f7a217e4f04448e58e55792f4090f961e6da4e30000000000000000000000000000000018e1e8e0920f3fab9df791a471a58bcfb27c54084e2b2bd3715f1d01b2b1698041b026969ca5a13d809d062edb9142d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c24c613cb51fcb4cc3134e061cfdebc8893610737c7c500768630b93358d6d3c19e81ee83ffb0b2a3504c9f231fb4cf0000000000000000000000000000000002825f5c0622bf9206d96b5d533faf252464f0cb974fcef0abb868b3c1d714d0e052461249cb74b9d0eb88c72fe525fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001551205296d06b5ba542ba25823bd87cc9c9898b48c39dd8fceb74709b888185c53449d92b0ecaae9c30377c14ef69860000000000000000000000000000000008f90647d74d7ed9705293442e54caf4f331c3c40f7e97fa07d36547747461d75afe87f071cc73d84bf0ad29ca86a1721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115daa4e77e9fba59ad4de88b95ce0733e7da1ae82861759be353e70dece9a6178a693f5c59124a6f8fe338694011cf2000000000000000000000000000000000c3a6f9b531daa61de46a494cc3cfc1ea6abaa37ba043bcf8b74318614372732ea04ffcc37e5e3e245efdad8e0b02ed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d15a6eb2d463bc7004717522102ddb7c048bb7ca7fe643374a9fafc550868dd0ecdf12cf58d88b3bc5299e2c9694f32000000000000000000000000000000000d4cb9a5ecd7f5f62f89acd54a8d39751e5077cfcfa21d5c5b73c9b489b24bc249c577399135e0d64549e83f1f69f0fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017c3bf474cb06825f9d31df9b0d983cf475897d308f809e8a0a056c10a302765e22313538ef6ba29fabec27452d4f0300000000000000000000000000000000025d79bbc1b0c098003245f763db91fd53516134a4b19b558f7ec9f1a40508995c8a459767a334ec0cebe503f805de751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afe08e4357382a1a2085439e4ce652023248ab62c74febefa46dbae62a777ddc0776fef72f11b0c5f4c77086d72e72500000000000000000000000000000000153727e76d034693f2b92149dee03cfe7bd3022f080bca053b731c00bdac04c4cf75e627a0b1b7ea85ef7c682cc009231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cadf42f3db8aed3371093348cdd1e4d4892f35356e79092efe3fa1c01348fa479982ba6eaec9d6b24675620486692c000000000000000000000000000000000a3066a049e570b735abbf419b56d6f22c99c8a6b82ab5615dd03dbe42d3d3b7e44fdc3e9b2d3f95b7c32a6235d90f781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f2fc624d7367199404a40d16e059db78a5d19be099e612903d51b48d097d1710114b0e68b338dfc10ea7e3da91db970000000000000000000000000000000011c426147296f53d1a3f92e4d2a245ad517da7e8f976f6c15e2cebff1b200d6c21a7742e48c00ed57ac3192711208f751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168897633c1bd91f9690275afdf6d8fc7a226d9bd675ada7c43f7e996d0ffcf73374a0ab574081a81f378013be38df3f00000000000000000000000000000000187390be1ae2b449c870526065bea90d41978c69e86d1da233094c8aaae1a3702eabd29f640659ba375accef55d7ec461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2998e8f427f82c6cc9cbbbe3a7d2818c86d4708ad13e70bfeb76603adf50e3d76df72450cd4b96da6cb58648d5da30000000000000000000000000000000000f649b7b514bdf7efece32ecf7398afb2c19d3aaf580063bda8c2790e5e67d09729098bcef652f0906849207833323421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000077b4f1cc1ec0c11cda1d5a814d33e3ed25cdebbcbfc56e06afdd5236b5a85ec005e8d7dcbc51fe39602649ce3dc1c000000000000000000000000000000000ed22ba17867716c891f7b4f2a727f9ae479966b69dba7936743a0b2fb229f95ef34964945e47d4d80f806ce593b55db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dd3161a8dcfdc3717e59831831214cb742e3d89c95a501d9aca857f9d84ed00edcc401a2abab46c9051bc718d8de1f000000000000000000000000000000000e0b764ce409d038768749c8894f1bb26a6ca912df517f2f79117d9b9d2cbf78fbcb65ae148a7beabd549ba5616747871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005009b6c6c0123ff561076f28aafe371296e3721ef7f2a5313ef7b3a587c21716bdf04d4fb3fe704641d679ca8a8b6e7000000000000000000000000000000000108108ddc46a214b28ef445be46e8a887fa0469e3c25b132bdecd0bbc1822d5301425ac4d2a78d91e41416903c2fed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128335f6275a132726f99af7ba3b65a1aa13ce9dcf8a12aac9df392ccf046fe5cad198b75edde85bdfd3ff07432e2e40000000000000000000000000000000001279b924fc5001d64713a433e4d8423748f746cc90e1651d0bee4b6f1e13a76277e126bef6bf90a6e464c3349809fef71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f8868a889101735c5afaf9145b73c0944e86c1fc87811d3b2b32e4f1f5e67e35c1cf6f4dc7e0dbe89e88be0bcacbb80000000000000000000000000000000002322dd1a43e96a876b39483c37084c3f51eb1d943253311d3949693f85bcd8f433ffd14680ce17158ae389c6f2855711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c1fff218d42355fa8c5cd1e479f36124abc8ac06f5b8a0c1db5fe59f341985679dd89c9a29d477251310c711546f6f000000000000000000000000000000000d313913d4248223afd7b4178eb2c4834fdf08876e73b8097dce6696dd3c62140af92892e695a43851e9e30b721b65641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013677a92dae64d04196ca440707b73fce0d260145718604130a60f7912b1fdedaa5ab5e624152c9d71b9a77ae040701a0000000000000000000000000000000008bb0489db64ed84fc6d41c62642f92f2ed969d8d7790ddcb618c2a51030543aefcef0ffac2e9ca42b51ef83a9bc5a741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1e2b150b1e5aa7bea43e6fce343aaf6ce512e303fd89c021d0af0c0b9f642293f0d7790826c7d5be31fd2721df522d0000000000000000000000000000000008e4d3375cd225f783db60c8209501b9a0ca1268f57844fe5ea3d794ddba8611ed58fbabf167df6c0d4e74c6077869661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a65464b112c306993c5e43762a2d47a3d937b3c27f826d900c0a30da504c98bd8469e5decb1fa5e5e9c88e2baec36b90000000000000000000000000000000008d53ec9f666b3efcfb8e8c3be5d1b92e747b00628391267553a5f117c0e568f43e510ebb69259f1af649b2c6ce9334e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b4e8fe2baaf37343d10db89743e014323fbf472b0ec6df08ef642715cdefbb005022bbcbcf67a9160a74222fce7d200000000000000000000000000000000011c5ddc40f1d2dd68f7d1ad8185ec622c2008baf72aac69b0dba7b56be57e3a8e7aaba380859dc65fdb5b47862abee921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c708779c8c1f7618b08b4ead0befd4475803f2b262d7f1c2d0b444e7a3cf9bae1322c6356f99e78442d291f986e7d8000000000000000000000000000000000dd914f4fa648701487ba9124821ded93ca3876fc941112a887f80854876ca9645786fa8104002c9c0483f8f5ae0b9a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001604a7a9810c01eedc950302b8d7c6c864ee44f4eb3f6576a893a57306472927927585fc6cf4687804bfeaa20ad91ec4000000000000000000000000000000000b623ab75c9caebdff3f5e2be45e5af8eac5fa59a97cff73e9b4a67244919ddb14655c04f575f71c6834e0982592498b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012943c55ff3e8b939bcd90dcba33abe9485ef534b26e0bd0ed519604e978b327a984b0e2bbde8312afed0695b1ce3c220000000000000000000000000000000002b63d5533af80c6a2eff83e8b81be2469cdfb83cc383a29d55b50896c025bc54c89fb52b1bf345028b62703292fe6851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc8f8c520acbcf06be5cd1304321e58e744287e9b90d6d60563cfa4a489bdd1aeff238d1110f1c1da7297964c2cee1e000000000000000000000000000000000c9ae8e0f16a8d1fc06efa2044bde2c835c29e641981630815c9b7aa0b8ec343df8d0289e14c95a30eb62065f07f17b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d996fceb20a0610a66c14e81f14ec288feb646b6e0ae3d5892ffbe68d424f742e69e5b2a79763e923c665afcf9c29f0000000000000000000000000000000016b41edc29f76296d5376c042a10a7984fab423f6f3b1dc587de2af63dcec122446fb67c6d43c8f3adcd1a5afadf1b0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b68faed173f8eb88bde53720e89a690c6b50fd144dd80d1fddbdc9cb5fe2fd1fdc95bb90bf0d67cfd85162646dd9631000000000000000000000000000000000e128a899211c216de1b9bf5c6dbb439cc8602eb9392d34f524948ed8813777e4ce61b4b2a2787768e5d4766144b12bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dd014e3470ab9bb912df2298ee6d0f817d0f0da5e766e51f0856b5c386d5464580328bcfbadc7069b6bfa4ecc32673000000000000000000000000000000000836b454b5fa1f6643b6ae2f6cfdc7f415067686163ba6f650db65cf403e4d153db6653e393e8fa83a794d74831e5ff51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f750d8d974e3cec5b956652a804fe7336d706a4cae007a71db27c984c2ed60b78219f1e7bad810f9199ab96381dc50000000000000000000000000000000000becb5f31f980facdf3ef266998a376aa52bccd8f045764751d7937317bb1a6524492fe96db9aff37b4920f01bdd58c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000367927d68afd21a1ade7cf74d51b1cc8dee02e16c7c3e23f593441f357f892def1ce21956dfe6444c9d0e8cce31fa0600000000000000000000000000000000009a901358f1416a15f1bab3b7790ad32903fcd672fa7c28306fedbef33e54321e9c06f86add57bdcda0ae23a4de554c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001678dd21cc1eb6550fe025700267c71f4a176ee8b2cb0a1bf1f7f79c684674e3630526268af164c7f4be48ee5162bff2000000000000000000000000000000001796f624ec02caa91d2c6a78a6dab9fdd47b0a46f759a8c573a365b3e728caa486cd4574bbd3b991e4ca402f86ec88961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c48fa017b29e7530faeb7d75e0c0bfbf8c308d0a04c40ad69232ec66eb0008807ad25f161a54868e6b116d3f5b7390f0000000000000000000000000000000009482d5f050426e4e8e2271895eec133e070b83f1056d84eedfec52e47022451ab65914b6e9b2bebc9139193e8ddf5d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e86ebe52d07719f30d4c420d1fae6fec1c62707bbc92b36972b8a4484e309098008f76ec41a3b41ec447da1699f0105000000000000000000000000000000000b720c75db0761011ad6524f7a7571cd0973a59f687b59d68fcd76ffe82f54f9a4c958eb47b8806eae5117f54a3346261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3c6f4a158c1437ba61b94a3ab68e272a1583371df4f47f9f829b06ef62d32e03ba901ab885aab0db2c91d410f07590000000000000000000000000000000000e81a0401949cdbbafef0fdcb1673d7c6577e2d995f7fdace5158bdb56250e1685e34ebcd9ffab7f732bd5fca96835091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172b70db273adbd87b2a338ce4cc299a403a23d134dba5496a838b40836a7f880ce82249e662da7dc11abf6e707cb427000000000000000000000000000000000141bc872c9e033f12016e407bb06ea1d305a8047b84be886c8b3c73e8f87b512ef058bc89a1269e96f9658e1737977c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001501ac1bedcad52cbd1334903a39fd13e40b6e86589f15e5f74e015747c4ebb146975c658cc417e73075c3932a69e0860000000000000000000000000000000014e4e476a483306b71a88eec2b698ddda51985df05f5ec54d3b95799a9458ea0c8466d1bfbdaf7b1dabfdab3ca3ddd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001103c34b7655affdcfb57b6fe661221b066fd1775e3988c0a838f3e325fe02518fed12cfe02daafecf0f1b0e646fb7b2000000000000000000000000000000000933eab5b19ac98145b41d92da1cbd19da751b15c6631bf312c83d918e6bf5cb39e1d37817e22f3a1fd922f7323b1a021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd813171eadb2c692532718c971839b1478975d63f651ab2ff84315040f691b44a636cd77d335b8943de180db03ba6b0000000000000000000000000000000004dcc3f6a1623d7760d42740114363914522424bb3a30bb380323dad3bca124bd25a47ee7f84d1047fc2f0e35b19156d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001957e261c08709e36f873472dc84050d0c5c4f2346da39d0615498b46a0b281ad74d8a889891eea44f9b2406ac15a1a2000000000000000000000000000000000c2b8f79491957e1ed63882fad1739502ca0eb4e031d763ec3869d9ea20d40a71aa141cacbc7ab4410fc8551b81a63001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcd7a1dc8383014c2e53f77a09222ad05177c5f85048422ed33993939cc5fe46c8556999d8e0e4550bade927046a4200000000000000000000000000000000013f5aea8875a6efd8497313d43cf94df191752dc25ba2bbfba24afd8cee7bfef5e96844e3a4db2a7904395ec4b8ce5131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4279b503b0c0c301d76a592e6d2f9c3726465e590c37d3545ca6542e122f5e4328566ab32289900cd945c37f0552a200000000000000000000000000000000031bf47d718b90112ee9fd78226b20f0657c0ba6a37bc0bb4caf2829bc8872edc35a266cd353ddb62af716042d4f216c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f148360d0083c297d6921baafecd9d61ffcd62ec138911390d2b8101b4bbbe3b7008c9043ae0d1d2eba9e53ed006c7000000000000000000000000000000001309c867c4c69a4eca2f6afb41aabb94b024493acaaf959e2a2fa81e1b0ab806cc18c6918e390f48edcc66419915f9a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c245499662ab3e7b2ae00285d607b9647c6c7ae2e204b5a97c0b3996836daf31435117766e07bce4f3593c23321826000000000000000000000000000000000a0760a36ce06f953cbbf1b7f563123668c61d9be4e97cc48fbddcaae2552183f2254b96e2a41a4d8de42c0d193871c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005ea761fd5b0461d1ba9d4b48006df4fe9fb19ff29f146b434a02740c5e74bb53df3576990f18a05114f78bd5d7ed7a00000000000000000000000000000000103b5f50663e57b2722648328ac493a2fccab52b7514aadb5d5e7d7f55ab47a89c3590fa0ff965023b877b1b1742a9fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d9d31925a54c5a157dbed363cfd942094030bb242129f033f1ad99c8f3334fee8c9e87ab462a60cfa3ecbe689d08a8000000000000000000000000000000000fcc340ca5b19ef6016c60ee40378e8eab062e6b1970c6cc1456a9c910e65b038b77e6ce985b41b4c718e8669c43634d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f53db4a679d9ccf8b27953ae848b62ed5ce9eb7fe3d7c3f43becd9b65575e950cc6cc2d50067ec93603478ac0276bf3000000000000000000000000000000000fc27dddb4015a59217352e79de5b64e75b6920860cd470e2a101ffdd25961d19874bbb2c7ba02e9d351720d8074d04b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b026009c5570c19a180b7aba4c7df787bce9317f2f0304f47e36598125fdb777af86d5183954e487f53fd05b63504500000000000000000000000000000000025b7e38fdf50edcd6319388272d90238b1ce36b9da1976c3dbb7decac346547f066d83521d3d0ad39ad288745c8add71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071cfbaaa4b0b8ee4aa60c7d4a78a72217f8753ee92111f909b8f879c9604c64119c04dc261554d4e4f697caa36253ec000000000000000000000000000000001993f1efdfe5a11792f01d16449252f84dbe49ba5fe2a0438fa6434068bd0a607ed8592c29faede46618f5d614d1adfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000206dcace6c98749bed6964144ce12cc48ad114a6d24b8b579a6f80c1b79ea349a95a28e240e7616438abaf2914bd365000000000000000000000000000000000d680937d5fdb62b9bdfb1119677a1ee76cfb88ae5bbf6b6978e3b6952f80990cb24ed1244649792f31b3b81e50c7bb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117355f94435e3f3f8d94b44e60a5f4193ad35a1f8133b08c7248fa3f90403852db5e0df43fe6d1b7763f47c97e29a2a00000000000000000000000000000000125b25b10946497fe0c955cdea32a400c6c92ef29feef6a437a62582a3c30a599ad8946256bc24fca27379ae8f1362841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125f0b2a45e4268728692b9dd31dcb4cfdd4b47ae6af83ef4353e7ffccf49ef0955872ca6ba722b86521f6f3f01e4c000000000000000000000000000000000010b934c017a3ffecc0200a03708216a2264ead70b327366a3606799a32be2af7a9bc4db4e5124f536cf4e64c291efd921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091e899dc27cde1a46164ef8649bbb852c112ae8aa5f04d7ef1c7aa1d000e05db4219131ee3bd1dacbba371d0e03c96b0000000000000000000000000000000015e8a7bdd71c6728473524891d0f26977b9b97de8c81230204dcede5528255459a96af94f149d1b657c7412d14d2c5e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016cd4344819945b32731d44e1e539c004acd610b215021a1b7fc7ba9eafab1041fd4a81f9714379f6f8bda3651c022d000000000000000000000000000000000e4f4821bac25d98c1206c82d75637baeb3ecdefb305fb30f13246254ed71065b7901c97988c140cf485abe8e1b47ead1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8b9358fc990d651bf5317846a828ad350799ad5043299d0ac447a9f6f056f8e5e4aa28a19f0e4311e66d1d8c2f3ed70000000000000000000000000000000012c8ceee3228491769bcaa5d50cb679cbc93962d5e666cbaa0c9c75b9d87a6131d04ec15c75b6f8b0a3570120875c3b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbd830ce4b3eca944a6a0e92e72a29d81c8093b6e345b1328e4e6412ff9aa3cb634d2fe0532dfbfaaee2e59a5a88e47000000000000000000000000000000000f4b126ad4a48e747d3f1424c20fc96a24bae606f69e6d7f8c870feae982f1f6e22e341fcb4246403e2aff38eab83aa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001510b6b360e4453743afe2dba6f842a5ecbac0d24d051d996a819866142c2e7ccaadc51ad2dc3f80d1aa9957e36508b50000000000000000000000000000000000d027199631371e637463feae6b23c79e8640a40d501853b0fe810faefdfb065cc91466d7d63e8af2a2d0f2f80c70db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000953fc9fa991a6d24f4b5817b2ce650f7d6625b811e564b1fb842b3211295ee65cc80fa4223f0cb148a1fb0a34047887000000000000000000000000000000000856fce2aeb9fdd825bb702878c7afc4717c074bd67f6282d873fa00c6b914cea334429c0fde48cf2aa9fe39c20c3d2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072f191646daf141bc7a1cc9143d7f9b045a7a4c7d80a7f6392ee1bb551bfabdac441d5f1c5aec18719802a759239cc1000000000000000000000000000000000c2bf7020c348dd55704a2ad8554666af88ef2566c41fc27132b33fdb9a46d8a16f3fe9093982cfa2d4ebe7ba40a0d631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160929cc188795a485521a14c1f77ae9403af77cb128331e20c52a7ac03702e4a950d414afc376f64ba3b40008508e53000000000000000000000000000000000d412be7af9a8b07922d75259238e21b3e43b32231031bc40a721dbf0cc4665029f4edd48d97e9e3041e721c634d6ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ab68153c029f70d7651fc01dd733b05a3fb39089956d1e26d16792e6fc73b4829b8d124c6a2e2d11a921e9c46f48a9000000000000000000000000000000001395a5572fb70138eb7b2e249619da24c2d4ecb1b7bcf0df9df3c93fe2d19525f73b5bd003029cc33197bd4b789f606b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bfa06f07d6fe983323088ef936c43f0eb6d3b97f10a4f47bd3bf59de7f28a29728dbd4c744b722985fd1914a00d05e000000000000000000000000000000001028d3e3b839d4fd34490a8762f252a37bacd64460cf37a201d841608d9a79b6ae1fc8fa570a6452ebb3bf7c07917fee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ed0876a13154fa0cacb313dc42c37eaa8d64bc99a1305cd3905c82a56e68f4b4d9077fb935d68e5feb0869cd2af46500000000000000000000000000000000001e9fb29a9868d992ec90e667f12e0590a7833c705af3512ca4995e13623e24fbf34369bbddbcefab6bf59c8b82edbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048a0c8cc7393446efa0e4cb9fd17ead656be2207965d9f5f19e799d89666e19816df8b7a25eb6ab02c1118a1867589400000000000000000000000000000000008de71fcc238cc1e74dfec902e0f68224988a536687c9520bea55f39a2baaf219c3071aa167c68fa6ff16997c464e4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018d465e7ade20538a98bc8b3190574fcb5bfe4b9d724b6fe4c5a9f2bc12bd6bab9ebdec9f01ed0bf1f0aeffda075ece00000000000000000000000000000000153fd60245dacd425212c695d45f31dc052f92623f8dc9b42def6a20f82b7b1af282528bbbd9282266c0ba30f6e73a991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9ea6fe522a437648df336d3cd95ee9505e1bc6e504e3282bceffaffd020b51ef2fac17de6d96ca1a7978f4f7cad3ec00000000000000000000000000000000153e9331b2c64dac21677f6e1debd22803576b875e5c516b24badc8d7c8ee1d189abe7409c59616c0fab7644f04679d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004141911511b3b3d12ed4d1a68f4b8fa986f3d213a30ac3cd1a6f3bba7d058dc0b7efe2483658298c69bf9403ff5eda10000000000000000000000000000000011a6f6e45ab920e5c3759058edff6ac5c32622a34c3b931979a8330de1aa148b63eedb8d905218e6d9580d43df989e2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056ee21f9f1be6c5c718af606199d91a8029590bbd519b2ebd562f16e2dc7234c27b2f831eb8f698a3c553f1a4704ac60000000000000000000000000000000017842894a3615d2e0b95771ac9a87aa935c971b22ef0c106246642fd56008eb3d1886b08f2cf6cfbb641f54097ad55e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000202305552441f69c23913149be1b613fa08f62b356abc6c83e1d751be217fc4fffe843bf497b930974d93646fc2441d000000000000000000000000000000001951b70fd53be2f4d073c94344dde05231fcd62ce1ea0932e5d3d9ea6d752c16ceb4f3c4462061f3b317a6edb50a1ec21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c437dc972a5c3af341a51569a6dc4755891c35b2a99987cf241270c1a4c151458e5854cd3d1a9aaf8cfc1f99dea2c400000000000000000000000000000000102c34fc0819de288f35ae8a3b30621e621dda4551661d78dd607c4819963a344f1bd0f450dd3977db33dffcec4ff57c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7d7cf7d76d5d0070a4e8deaf82c9e824fdd0470a0a9fede3c7b1a2cd74b767b5bc7fd57de092728f0e669bd0f06336000000000000000000000000000000000e9807a3a67d1208f9dc69b0d72bfc6a54ceb92c6d29eeb4d77d6eb1db681307f94b5f0dd0156516b354e547e00352251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000523fa5edfd6696fccfcb38bc0f667fa854e2be8657adbd84b35e1293461c44d0e1414c6ff100c1d92763a17604a9bd70000000000000000000000000000000014c5d79520ed5b92d7aa273d1d58dc9d6dcc782fd1a7affd61610a3c8729e9de55282c782cd2b9320ab0ef989b5de7301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f1687b6b712512cc059cccfeda62610d896362d84bcece1174792471852c1b1532fdc44d13324257adc7ad803cb10f0000000000000000000000000000000017e1ea6dad6438ac814f67d4ac5d6d282acee53503b389e9c77723279f015bc02b0792987fd2819a5d85fb8608eae3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa86fffff4db66dd31b506b7617f7ba8ccbb1cceafb49445daa4b571b44b41e711eb0c3d665ab20ff0c25a01d42b8010000000000000000000000000000000011a6d3137447dbf60cb47318a03aa57e6092cdd0e4ca9d1bcbb8cd2a49b4eaff2db61ffde9bbdd0f89b1e39f163e9cfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c3b84b02b287a13d6be04188c32f276e0a697ce1ab71372b68ba58cc56592891cf772ec51c1f3f200a2b0339c845800000000000000000000000000000000006e8b5c01cce52fe6b04a6862a26ac06d320f4ac9953183952b5cbad330c62d6ef47e1b9719ef41e2c14363fb2d5d7ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ccb9d14c2c46a6f3b1169abd7ea38e402cdb5bd6742c2867ec042cfb14597db7d42f762c58b89307038c2195d96691000000000000000000000000000000000ec47860b929ae2b2a64cef53c562d61c8705ae0e7fbb3e164190e92bf561c1f61dce99d4e715aa913e72f8475e9a5261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000522aafefb62af315abb6641a795d08b92eb446ec7fe09ac1a690b1efda72664c30f8936df44a4aa7afdd6346d05d1b80000000000000000000000000000000008fead14260e9f07e697aa1ca4c2f9a5215571c6cb281f75c6fed8fa3b61f30bf2141b2429a8790b51ee7e25bc0ad75d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d4d81980e3cf50a9e9f770589ff9729e4b5ac62761797df747914026b9e0f9ef6db2d95f56d28ff98e3c38e28c2776000000000000000000000000000000000d3c0caa1c51a0a060939e1403aa9ef4426a2a10342c6a6f2255e0b20f65443e9e25b6403cacf3d1513651512500d2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009242e8176792dfebeda21badc305e275046236ba9f885b58fa07223b71bd68292430a64135ba32de0729c6b8a8e395d00000000000000000000000000000000002850d8294f406e15883152840e50077e3830667faecdbc440f43aba0f6dae7fe867362a74719b605af37aadff57eab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193d4ab7a013767ac6d6742a0dfab3f5081726f8ef1580d9efda3b323bee44f63f2fe715de287ae096c60fced81cfdc80000000000000000000000000000000014c84d6b5dde20cd9e800e7df887151bbb66d029109fceb9b176d243db26e10d7465599c0e6944c9c7b18a61e331ecce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cba2968f739aded66dfc79162581be27f19b9b6f52971cd1645b897f21136cdc21a7c2b0c8f67e4a44675761fdf97d9000000000000000000000000000000000dfa7e5e8aaadef3533ac9197f36dd347eab1c1d0af5197eb5698c2586d02a332fe1c74c37353f8d523eec67fa7cb64a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073df1ca45a848054c36204805987dcaecfae5616bf7ed27d69c30beb3361ffb73f17dc03af49591475943edacb225f500000000000000000000000000000000093bf03e24e1ea69e2248c8d7926ba8d1f87fada0ba1203e691267b95b5b293995a6d4b94e3ece2458f4e686b597402d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003933bbd0f2fcebb39476c11d5dcee0affd61d63f4ae21432d5f3a1fb95f29ce95d46788569cc7762a43b4241103163e00000000000000000000000000000000009429e37e8de9b10af669c968232820f5fbaffa4396b6da91877c3387b718de42b26e454dc2bae4b591ce3fd1192e521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec72c5993613691e5862deb3befdbed1f284d5e0053711bbfbcc957cf8e5002a34dedf702b28d16ddd058240959048f00000000000000000000000000000000189335bda22740b5f719bd76e8d81fb47db76ccc79de1109cafbab78981d8766a93bc233f863c3b6699bd71b4b773fb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140525d69e3e5a331dee6760af02707e86d48f01616b75e806f3c4401dc320b16570448aa29e6926803caa5f681e738d000000000000000000000000000000000edbbb746d6ed51d0b483ae42cc27d07784bbddc544b9c80a6cf3ff5c3ccc0545a04c0b345ac5df2231fc6dff60553871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001be6365228494d7057fa7302a4132aed61e8839fd4eedc8a1c77a07fd2c4d9883541d03b793f2a7ef581851580a04c200000000000000000000000000000000032f2247390a70b4164fcfcbc680c292929ed618e3b3c48441a67207f866302763c5604f768260c8ad0cbb7ce2cb697d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cabcd365f53ed1c8b2daf55ef71ef684c4710aa3b783ee709b904b37b333c032524eae931b25ead6dce771f89a4fbd60000000000000000000000000000000010bb62798b89ece568ddb039c9378e9dac1a4bb7db1f264d07bc0c04788bbe8e6e7bd430ffc0980380225b12113883081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187e3d59b300c4843a83dfde7f895ce9891ac298a186cfa5df708b2a6172369ae466cc9f43b7a064339b06b0caf38057000000000000000000000000000000000f9ffed1785032752ca247f728a4b33c1be1c96f51229ec0c29fd6b37a479011d397f7bf4971e6e8c3da152254d6b9281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af96cd0defbc78806c9e763fe8efbf77686cd25d38af9005d4a63000b444da34731c77b86df5d365da1967ed0e549c3000000000000000000000000000000000fff26a098af9160e0f99c5f61348c6d45ee37d5c6025d03431f3c2b66619d7c088f37f61920d095cb96bde5b7bd63041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000663649bcd5437be1adcb8766b2b72db33cd1b0941154e638eec4338514c5be053180d43451ce28ba134f174ded72e1b0000000000000000000000000000000013ca2fbb46b5735a6394ef3c57312b01e6c317d9eae4be8bcf698a422bdc4dbdb0706bcb460332caa43ab73511775cbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fb6baaf4448a7acbf9a36637917f8512b442280089a3b691513929e6efb8f87a64343c0eab60f9b117fecf6fbcca440000000000000000000000000000000015e8a65c9f8ae703cf42c980ef3b8092f781e37f241954fde2fb5015f4da739aeccb58a76e43ffb0ceef721302ed3b301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040757338a4a74a8ca239674bef884be2fcba5fc027b201e4f7c01f7eccc7b22a0dc5b04f591461c27157458fb293159000000000000000000000000000000000ef3422dee73629375db8f079c5b625deb88faac9c0933ad186272d1f3027845821e409a9e8c21f94ee256c3d9f361761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063173b639fdd9c088ca88fa763f994d64a2f3686f0ee1189b5ec4afad1d43ee657012bdc78e1059e5268bb1818d617000000000000000000000000000000000075d874b508e7e3636b2a431ad143303b25c1bc61844d35c48e9f92c12fae0b927ae996182a4cdf549966ab76fb5eb4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000909fdd9007a9801de1d95570c4447731dbf785fac6e062f4c256b1d99662a9fa14b1f1da6a24b9cff16bde7d06dcec4000000000000000000000000000000000da1a9dc6e21733f57a1a33a18d10b85f91102692d9929aa50f0e0c3520afd32daf6e37a9dfea5b6ade3cb2ef10aaa6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8c24b764e0d8b1f50d703abe6bf609f0062f536cca3f9077aca161fe7ce65dfcf49f971515f032eff3a7c0d0c7e1bd000000000000000000000000000000000e77e685370dd6b39c0eec6fcf8db4db494b3ef1c57a362cd24fd6657b103a03a2a6d45d9effffc09bfd21b22bd37e211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163bbb77e5cb8c8601b5fb1bb09ffc0011c86837f3756c9db4c392d886e34523e7823cdcbd4bcdb50e516108cf26c035000000000000000000000000000000000943a59903c980b237c3f8b52d736e041d2a0531d0241360c7877be68ab1a42f9f220f830293e557a14fc1a997a52b6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112001c3194be263338e746a29c4b405eecbca49539e3d8158ed871cce7b3f3efa6e85aba456cd5621171321487a3fe60000000000000000000000000000000009a8bd5cce84162f6cca7f1d9924e9a7f7d8b74bb728f1d499ba3b5efbd61c66ff278756cc3212488b5982ab2ba834a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b47e7931747139f10d4e72de1101209ec8d62d62c3da010d3ea2487ed04b0e4ab7c43a34104dec15746ffb6dfda3bc7000000000000000000000000000000000a03961ac974e169786c09b9cb07eec65ae100d3e378724b7206a1e532344be77ea3b9533f89c44e5647c7039ec7ca991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015be951aa77153fdd9635b7a3b15badacbe4348d5278ab172035a75c6e4d82899f18f61219b6e96a2e7889919dc2921f000000000000000000000000000000000ea70338b206b57eae14b042ceeff73bc2f84f1c199dec82cdc9a9edaebf8b38b1f76d3421acc384d1f0f16c627a52ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a02c674268a3a383b776ea2a0ce972223b41e74b40d24791f9f12dfeeae5310f716b8254d3cfd04ed1aef6a0103b06000000000000000000000000000000000ed602f1c6a6a47399cfae6d5df6c3609fdd7574c0424d074da5ea85827167ea3abf0c672d833983964d4333079febbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f32b9c4d6bbbd7f376d84f1beeb6717bff5fdb6c8b8d6bcb6ad18b977eaf52a22fb2881462dccc71fce685b743a9940000000000000000000000000000000007f610fe504df2c36204508669bbbe589990b54e117c94a7a7c17134aa12d08638d99441598ea82eace7b783a37f28421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010427924d67255ab762c989895699c348ddf8e8450a84299c82865c39b92dfde00606e6a5786bbb779eb9a5938f4e88c0000000000000000000000000000000017cc2620bc9909b4334fbeed4f3af7be5904e40f175035131a7c5b244871638809294d90dd7cd586c00afad77a67d2841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f2eeaa9577bc28533376fc3e1a17173a47e3d5cd2cdcaf76b881649cfbdefef3de08ca3db6cf84770f0f29b7fbf9fb00000000000000000000000000000000133a76b0ebf0f23ab8aec895a9c425de294a29807268fd005f5ae786efff0627f9f032b1246daedb5857f59331c8da8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022ff106000ebf7a439cacb8a19f0a6713a7d8c48ff47b2841ffbcd89c7020b2dc12dd8ecb552be379427c914a837f46000000000000000000000000000000001633a8b62fb2af48f125471e97abcff7b408838e4f7bb14b09e94d09352631389afbfafda128a9adc21c4d7e597014af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5dec39917d12e465c6e5d6546f8ef132c71c0ac83db9481d0ae9df66fd5adf6b83b40bf4b554acd7df487a06b7c7420000000000000000000000000000000015e87fa1b5f355b9b9ae9ac8631eb1597c03ad8db3f37619c081a112cfa07e891869514d00aa26d6d1fa059a76799c531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001389b72d9df5b6a7c98045843f19d75e26317e8d6600b730cb2a284d99be2dee516a7b685e913b977687f3b6db370c57000000000000000000000000000000001749bbed9957467ba50eee0bdc19535856a075e59e32e17d0f7beb0ab6e0ce3cbffdde6cb7407e9f1fe5f013ab940f341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014898fb09090e31bf8f4f7116a5ee09997e148138c4ab82714664d52b0e99d081a0bddf020968cdecad37f5abed48557000000000000000000000000000000000798aa0d4c6cf9830d45b2f2936a6470c7bdf4dfcceb91a119f639cef4bb2bf3aa2668ed8c1dc0732785be2ca95b566d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b2522b5789998e286b10c27498cf1d4fdd7f9f7d3a1f94093956c8c20abbac24d889d711d949b546c96572717ec0a0000000000000000000000000000000001958878c3be8d14182b6a29b0ed0f6f342db8894031a89b1dbdbf727a4e53eff83134a24c5ca9d5db5b6877fe258fa141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006678a0a8dc1fb64baead7d09427d370970d44bf3a4e1311f0b9fa36c0e4aa6af1ad1108d8b15f484dd1732f01781bd3000000000000000000000000000000000ec4b2561edfc6bebcf515b7f0c00c9bbbb601b788dea10bbd3d6b5fd93b8b940dd43ad3422303e4da39ec2a892672da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000846cda4870c3074d8a784bd877582121c0fc3d9ab8af07064d2cd27ffd3ce3d2af205620c2fe989660137406139d03600000000000000000000000000000000083b4ab1690d9cda996996672f2245cd1137f97b15f05b0b978cfe8cb226ea30628523a8b3e8bca0d2869bec385b9ebb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e801a2c295ef5a08548c771689144b051f29202fbf6091596110e6b45186917ebea855915960317714e476232b89ea000000000000000000000000000000001003dbafd6b2b2e3c7de2e58129682db674e5721d1121eec3a037fdc629edd169562d75f1a46d294c340767c03fccfb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113f3c05533ff8107a1c8c7d5fcabeac5de0620d81a5279759ed9eee3c236e2bbe0e568b6b059e2370b8e63020cac910000000000000000000000000000000000d20cec953b963d16356b1eeb3cfbce72404fd96a03f90a294aa95b332d1afb0b545c860b9490f7d1f6694b509ebe1061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8fefe9d1a7db70a6c3ac6403954dd3c392622b890e11827fb86a64d18b52b9ed729f9273ae91dd953e4dc9cd55795e000000000000000000000000000000000da7e157466b0432d3f1e384cc11908ae5985d071e221966aacd0148af8e6363566a61436c8f7ee28fc3c2a5631830c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cca1c0c766218ef42f8f7f1c918786d6be3a7ebf3e9df0f7bf8f810cc57852af6b8bf5f377d81eb8a174c06a3aa20000000000000000000000000000000000107b4bb4e33fbb20fc8c88f76544f78a6d4d5923bd8ec90f573e5730f83b4e6646c8bc1ff5f7470deef4acc5162ca6c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa70f8de2e6bb050f35a63e0e62e0c84c5120d1ad6160d42d25873ecb50180624938dd7f117df66df9b40e9a7142ac40000000000000000000000000000000005b114dac9b66fb65eb56818724740807855af818141bb2423c086a5fd7f9b2f4e28cbef891a74c6c3c35773184f4a931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3a213ede740aa9c3e6ed1e36c32d5168d8de00db430bdffbef15aebef56d7fc5420b52c5ab19126a9545aaf264acbb000000000000000000000000000000000c75b72a641f195b18f5524739ee5bcafc6e36fbcc134068b01638df28e86247359367d350b5f13ca957e3e461fd21441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d8e5f547ddf60a9cf321b5546703a396046718828e646c20a41f606f1a56dcd9a543777e781572e416dbf4a64b69a600000000000000000000000000000000097e7a888ad3b117f5d98e60f2c646fab19cde95ce926c0cfc9bba18a4b2fe755b09266ada7b3b2eddd9304dbc637e641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010260149cabedb03e1bbbdc88cb1f0941d53ef5582b4b821de7489ad686e539eb5523a90b689bec4ea3d36fb3cbf05c900000000000000000000000000000000047c48a67399319b93ac0b4863b5da9f4c18616b183e8ec068d9e410c840451e9896de3b7d64c6a23fc13fda470e62d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cbd7e94afae4f0c5987ccc728915a3c6cb68965975b2e573febf745daa2d988a8ac1d9b41c86a6f0720019f4c90bac00000000000000000000000000000000023938b0ab049aa6adcbc6046808b0b399b002dbae87b3e3c407cdf8d20c6cec77839c5a6f8e35fa9e533a2c2a3d15671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092f46beca3f0bc7e265f61104530f00c6db87dda039a8235907f060361378889fa2b42d7e8eb644751483b10330dc1d00000000000000000000000000000000012c196fadc1d6297d30b4548bf241288cc049e16f79f9ee2109deca82279a22b51b751c15d9082b18b4c5e541c4cf441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad2c50e2e39175760977aa6fdbe3aa99c205d43a402f98e0beb93398edfd143a3694325e81243c416457bedc89be6f80000000000000000000000000000000015b74241056527fc75863a2b59b2ddfb076ac460cb2c48dd7d5ba4d92f36dcfa7cdc4a7782b17513d6879085fc93a8e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf1804c22fa51c6bb601b756ccecd020a105d991cd58386c44bba991ba1a89a4aa900c36215255b4833de151c8a84760000000000000000000000000000000005eeb082c4e15a51dd7e047834e122ffb8c43d7824ef68844102f7484eae9b8142fe00b4c8555a6dc7bd283137bdd2491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000863eeae18fd883887e68fdc27466f991c98725233cc662655d31a721de43855dd188d2a5adc46af7f11bb9a1f0210200000000000000000000000000000000015229dba420427d8b92d0671a9608b36833830f217555016b5b64e674cac9e47c2e4902de959b76f1c8f6f95b940a4561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c25f998e4a620c4e0d7ada6a84fa692465b0840fd0b3291a0c97aadab3d685272a1195ee2d1f5df9bf7ff5ae33fae6c000000000000000000000000000000001815b5406771ddc761ae6faebd3b18d873c51186ace72e57115f7e0105c4cbd3dbd11745b978f034112644ff0109deba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b22c9cae4ae714cc1f543b35c95d4e225925953fdbcaddd4fa93f321d00e82bad9b92d6c0a88e21d77ea969c0023430000000000000000000000000000000016adf022f5bd3d34cbb70f824184392a7d3ec19a4e27132f894798b9f6eea933b19ae0b5925ad7f7c2174c92d5f30f221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128c5faff3e186878556ecb9a88b1a9a554504917c6e5cf5056fdfb9dacff65391908ba5c77fa727f04f2d68fa2b0acf000000000000000000000000000000000c23da7fc5eee2840cdc83fb05d54429cff83f16e7d86193932f1f6624be8f1fd3e4f83e558742bed041013718d509001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9c1e7aaf8e9bc3cde21530ee67f9adbb83e59604aa1f92b454c05dcd44d6a88405c3faf25c424c5d215faea27c8d64000000000000000000000000000000000af9864b7f34e0334dcf718e449538170f28bc4cb4ba05169a64c0e48de7750328851e4829b7b2df27de46d9c82147d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a657439d4f39103f2805dd02150f960037a82d32bd69f275f782e98b406ba5443ac0aabd837ef8913683f05be92e0db000000000000000000000000000000000ba380b5ab7936611e81837265334057e5f7735180a17d25d804ea027bebf8ab2f0bebcb7ea048ace4da33d0c24360ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006eb88263278f07234ba16495f69a343c102db2592592156d6b0b2f52ef9c2dd80c7610d619fc77888a716c506071cd8000000000000000000000000000000001508778b26ccfdbc8dacea81be769a0c746f16a1903e9a01863987b0da4bb210aab273271693727ae633824a06c9f9c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006149743b95562dd828284c1b71a39e88fb3b671b11f26fdb4b9512a01447b02311b5954cf832f2b929b93f2630f3cdd0000000000000000000000000000000009cdcaa6c6fc46a93a785a373b33c802161bc6196e4dd530b6630ffa1439968cc9e5762955c39aac51a878ccd73c3cfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e433e884137ceb3566c3f6fb021ced4a870e5e4791606ac3ace7c239ce1c71c777928afd40b063ca7185ee2290851d0000000000000000000000000000000006b16c5b9f0508c67a5e04ba9ec561e8143e0087dad3dedf530edba58f2ee55c88fb01a0558657b8cb740ed4c5fefe7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d78aa8080884f5011b5387225951e564e9acb244fd30375fb7ab7dca2d987997ae57460dc4d152dfe4d2569253a09fe0000000000000000000000000000000019293184e1ec51d9f647a49a83e7ebb0d44ce284b79ca80ee121b40c2cdaaad676ce246752a583ee3994cfad3228f7d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b94d1fa22dcbdf751559076bbe7b4984e54ea950448ea7f9b7171bc991e174bb6342e2da21fc4e25a2913f77a65b7dd00000000000000000000000000000000099ec2666f4d652d0ec87c169bf21713aef5ec89a4aba2b63ea55cb794273fc06d17b64d517c3793950e1f34bd341bc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a45c2df5d29c66ace36fe9f9c0c51a25db2ce3ccf85e7120f56b5bd70052627f42cbc7d759c8988388ccc624701642000000000000000000000000000000001750fc73f51c406f08a0462604f751abe449f4ffefbcd7cfecacdf6e86613a2594a17c9c004f9d185b1f23f2e8bc18181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000390eb16f841231aa50a666b4ba440648b037c8250b1ad96cfd349f00e7019f475134dd108cde5f915aa25c3ad62d2ce00000000000000000000000000000000096debb24dcbb6c5bdc9bef9709a88ddaca6ba359a15c6baa04b50710498bbc214b2a8ac0ae67354af48bf4c7c1f8cf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012ca70a4768c019388804ed3f9798178790396ba3128fd5cb266fc8ff715d5bfbbb8452b983383e08b1de80f939f7500000000000000000000000000000000001b88bdd3e40c57bdbcfb573a622f0a02c7fe7d13e3b6e6aa60ac105c20f6fd9d6c084dfe9735f8f0744f3d5700ebbb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c4c1cb2c4a404b456a7dce47282a881fd5a971766af43b9eddbadda793cac9264a2a227ea6f0ccc71ce9f0b70100ca0000000000000000000000000000000004ae0ec49b5c718cb443cdf08c68e49371630371dd7057c7f535ce5207cdaba73cb2621deea8e6c83ad858e7a6a5cdb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bcba72b846275c9a54f9556bd0da65c883a18cd257df6d4780c14aacb4f3e470138e0c7793ce8f8505c88bbe8045d0000000000000000000000000000000000e3174ee1f9608f33962a4db30ef247e7ee46a81061bd1bd71fc3fa543e51919df45b30e032375651b6cdec1de1a41861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092643dd854ab10911f3d4e2da4503caa4b13962e6a02f3a8b1aeb96f807383b44f3acc7519887c7676f94f15a6b0077000000000000000000000000000000000ef023afa1164e59bc4d52e1fe2f33622a44f300644eb06cc83ee0af18423356fada0d5107c2f964c68fcf8bf11c7cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001099228e31111d2c10a4f8fd8104c1f67eceb5bec7ff3aea03b668ca0d5ae3d2c8dc8bd878b799d4e4b01d3512e8e70a00000000000000000000000000000000043c9965c26748001c2c6b7e3e7a2ffd6c43db54d0ac293867e9b5c3fd539c4f10eda61b82c5f01315d21dee4e7d1bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c50e0b7fbafb1761729ee402f1a0f9b1bfe87e050d1f9b51542c61b2ce0f9ba9c11ffe2828643eec1ecf682f87d39d90000000000000000000000000000000004eb6361827929c9183158653ec363c398f9ec85c3d5001275198e9445b1829164ce8b3dc83e96a8136ffeef7c843c891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000900e4c9c6ef755aa4e83a6229f4d4f14adb016c2ae0e0a6a7950de16817d055f7e7a520da3e40c881aa06169ec4a78c00000000000000000000000000000000110cb34eb673df99c751ce4fc8a6c04a829b531fc116fe1148ce99a8dea916da2e027fbb6c37aea16a4cd054649496cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1b3f4ebc406c848e108614dbc73e3f179b30ffd8a112902386b7464ff5cbf0e1353310d7f219260dd133b93238c1d50000000000000000000000000000000002c93c51ace18c4d3356307ce30dabde82b606ba3495442f93b90511c7de83f391a14febd9fe0d6560ac023398f4f3d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fd3ccbc38b3d4b37398c0de98cea545ce330bb8796f3ff34b0434a28ed0c2724c1b893d5d2a098fcb317b356faa62700000000000000000000000000000000043be6c305b8ad9231fa9796ff3d8980b0ab970fd1cabeeaea740fcc77fb25a46660223dcc4a6b82758a1b5949178a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f336849e1462c091ae6b7f30cb73d9cf32bcd79a405a28414b12debbbeb8b6f4f6b13d3ebb4b6abd28e1776d3a86311000000000000000000000000000000000472836464480aa64952d8f4a3f5e47fb5e72d3735a98bf9d40bb65980bd68fe7cf39cd67ef52d995b972f0c6c2455f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000917749a077036c0fcf68ce4db9ff9fa9eed138bc29185d6489e7388eab0158ad5b5b89bf9c2644f886767ef4f7e4bce0000000000000000000000000000000005240bc863997f5d079f2faecc00aaee7bf67ce298b5a9edddfb856dee127e548b3bfc8148320641cf3fb5e8b3ac131a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad3a1e0b636f92f925c18f3346c955867b17dd27a9d1bd7a8a8dfeff7dcdbcaee8b0a7207adcd0c999840f7a542d229000000000000000000000000000000000cae099f13d160d85abbcbca16270ef6b14e8e1d56164b58bdb7f51e8d36f4c6d72116423cbc9d44a9d753b55ab890f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb5ac9e5504c6aa9925fa6c1034921eed0d5818b4d30c806450ab5101c962bb86413bee10f9d18976adbdf6125adf87000000000000000000000000000000000d26ebea7d5db77dc70f43849cf7ea4493af4e5297d32f2ad5a8ff5d2fa0939d5afcfd1eda12e0e7e0d9686e8bebae951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f73ba8fd68881d40d7c10e4cd954e0dd5628765539bfdc86b1373c8a4685305e3c0d01253f9c4d0175fc23b6206efb0000000000000000000000000000000016eb923af7a0f173b5b0b5688347a8017cc22627706eaabbd169676edf186b3fc68cf5a7a743726490d515a06364b4661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001046f157cd0d5e3312a76b413754631c3d373a8eb2a8984e064bef03032c4c1ea6dc7a64cbc47ca167a8db2daa731e9300000000000000000000000000000000046ac9f6e3cb96aa5db209fdf837663e39f5288646bfa894033cb7c93c06f7071114e72cdfa26fbbd329f3b0098dcf8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008497141370663ad0f2a0fda0709704d0043716cdf2064ef9e52bc6b8816dae276d5ab0934cfcc0d942e865b2edfd8c7000000000000000000000000000000000f40a40126fccd45652c5ab2b887bbdf617082948cf536cdd75819778514b77b64c9ae48777fdf1350ce541ba41937db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074de88b95c3eed5eaf8f820572aa6e38c35df4a1252ec5547357ce63bf8d5a35ea04f620997db0b58fcd83bc25767ac0000000000000000000000000000000012f16ebfb1e199b4c9fc9780a6cd5aa0df4e274fd00604301a07c98ccef6dcd5524499eabca73774196243170335b4701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124ed5f5c532cd74a1bec08e144c5facc450286d9e49a33182f4f87db23c1092779e7a9e45a501786ae34f1dd609ccbb0000000000000000000000000000000016f703a97727df8c50acc45e8394bf5857f49d7a3127a35382af2b74c834fd7231560c60ea1328e69a6a8a87ee0a8c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001230242be51a3b27f23b6ec72610a64d4a25e51e422949e7fe14244500e328229891b77565d72c7fccc554be308bccc90000000000000000000000000000000014c59a7845d6d73a361d9e5a9b57baeb95d4a4bec542e942121df7aa6cfbe780c603212d31712e4e359fc8b4599190f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3a4c2959886b62b36343f1f777f5bc28a2770178265948233c76c51a826156c2c96b3fc16813606c45826ced6e500c000000000000000000000000000000000daa8981c470263e71a2a9ad4e502e21267517fc19270c1b920d61a0ea60e0a5f1f9ff1e6b20a5e29404e5e3d772bd501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000011f3b5b6cbc6d0f2020033e74a69a547b34601b9d24f3356316b1a1a2598300079b56338eea9392720dac6c16620cead000000000000000000000000000000000cbbd1bc95dbaae3982031caf8037aae5feae9a35bc97fd8bde331d5a7044e4bf56fdb13481f78eaaa7e60b878e76fca", "Name": "g1msm-4877-jwasinger", - "Gas": 10183176, + "Gas": 30373956, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1multiexp_(g1+g1=2*g1)", + "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1multiexp_(p1+p1=2*p1)", + "Expected": "0000000000000000000000000000000015222cddbabdd764c4bee0b3720322a65ff4712c86fc4b1588d0c209210a0884fa9468e855d261c483091b2bf7de6a630000000000000000000000000000000009f9edb99bc3b75d7489735c98b16ab78b9386c5f7a1f76c7e96ac6eb5bbde30dbca31a74ec6e0f0b12229eecea33c39", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g1multiexp_(1*g1=g1)", + "Expected": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g1multiexp_(1*p1=p1)", + "Expected": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(0*g1=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(0*p1=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", + "Name": "bls_g1multiexp_(x*inf=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(2g1+inf)", + "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", + "Gas": 22776, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(inf+inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 22776, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1multiexp_(2g1+2p1)", + "Expected": "00000000000000000000000000000000148f92dced907361b4782ab542a75281d4b6f71f65c8abf94a5a9082388c64662d30fd6a01ced724feef3e284752038c0000000000000000000000000000000015c3634c3b67bc18e19150e12bfd8a1769306ed010f59be645a0823acb5b38f39e8e0d86e59b6353fdafc59ca971b769", + "Gas": 22776, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e300000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2147b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff66513800000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d21600000000000000000000000000000000009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d000000000000000000000000000000001532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e2000000000000000000000000000000001974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a0000000000000000000000000000000015f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a347b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665131000000000000000000000000000000000a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c000000000000000000000000000000001383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d211000000000000000000000000000000000e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11000000000000000000000000000000000ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db55b53c4669f19f0fc7431929bc0363d7d8fb432435fcde2635fdba334424e9f5", + "Name": "bls_g1multiexp_multiple", + "Expected": "00000000000000000000000000000000053fbdb09b6b5faa08bfe7b7069454247ad4d8bd57e90e2d2ebaa04003dcf110aa83072c07f480ab2107cca2ccff6091000000000000000000000000000000001654537b7c96fe64d13906066679c3d45808cb666452b55d1b909c230cc4b423c3f932c58754b9b762dc49fcc825522c", + "Gas": 61992, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e19a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g1multiexp_random*g1_unnormalized_scalar", + "Expected": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a219a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g1multiexp_random*p1_unnormalized_scalar", + "Expected": "0000000000000000000000000000000006ee9c9331228753bcb148d0ca8623447701bb0aa6eafb0340aa7f81543923474e00f2a225de65c62dd1d8303270220c0000000000000000000000000000000018dd7be47eb4e80985d7a0d2cc96c8b004250b36a5c3ec0217705d453d3ecc6d0d3d1588722da51b40728baba1e93804", + "Gas": 12000, "NoBenchmark": false } ] diff --git a/core/vm/testdata/precompiles/blsG2Add.json b/core/vm/testdata/precompiles/blsG2Add.json index a4a6fd929e..a97257e07a 100644 --- a/core/vm/testdata/precompiles/blsG2Add.json +++ b/core/vm/testdata/precompiles/blsG2Add.json @@ -1,730 +1,786 @@ [ - { - "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", - "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", - "Name": "bls_g2add_(g2+g2=2*g2)", - "Gas": 800, - "NoBenchmark": false - }, { "Input": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf300000000000000000000000000000000122915c824a0857e2ee414a3dccb23ae691ae54329781315a0c75df1c04d6d7a50a030fc866f09d516020ef82324afae0000000000000000000000000000000009380275bbc8e5dcea7dc4dd7e0550ff2ac480905396eda55062650f8d251c96eb480673937cc6d9d6a44aaa56ca66dc000000000000000000000000000000000b21da7955969e61010c7a1abc1a6f0136961d1e3b20b1a7326ac738fef5c721479dfd948b52fdf2455e44813ecfd8920000000000000000000000000000000008f239ba329b3967fe48d718a36cfe5f62a7e42e0bf1c1ed714150a166bfbd6bcf6b3b58b975b9edea56d53f23a0e849", "Expected": "000000000000000000000000000000000411a5de6730ffece671a9f21d65028cc0f1102378de124562cb1ff49db6f004fcd14d683024b0548eff3d1468df26880000000000000000000000000000000000fb837804dba8213329db46608b6c121d973363c1234a86dd183baff112709cf97096c5e9a1a770ee9d7dc641a894d60000000000000000000000000000000019b5e8f5d4a72f2b75811ac084a7f814317360bac52f6aab15eed416b4ef9938e0bdc4865cc2c4d0fd947e7c6925fd1400000000000000000000000000000000093567b4228be17ee62d11a254edd041ee4b953bffb8b8c7f925bd6662b4298bac2822b446f5b5de3b893e1be5aa4986", "Name": "bls_g2add_(2*g2+3*g2=5*g2)", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", "Name": "bls_g2add_(inf+g2=g2)", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2add_(inf+inf=inf)", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40", "Expected": "000000000000000000000000000000000a9b880c2c13da05bdeda62ea8f61e5fc2bf0b7aa5cc31eaf512bef7c5073d9e9927084b512e818dbf05eab697ba0661000000000000000000000000000000000b963b527aa3ec36813b108f2294115f732c878ac28551b5490615b436406773b5bb6a3f002be0e54db0bcebe40cb2e2000000000000000000000000000000000bd6e9060b42e36b57d88bc95b8b993da2d9d5acd95b73bad0509c2324212bcf7a94a46901932c0750535d00008a34f7000000000000000000000000000000000a374afd32bc3bb20c22a8864ce0dafe298bda17260b9d1d598a80830400c3fd4e8a8f677630eae5d4aa0a76a434e0ba", "Name": "matter_g2_add_0", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d938800000000000000000000000000000000192fa5d8732ff9f38e0b1cf12eadfd2608f0c7a39aced7746837833ae253bb57ef9c0d98a4b69eeb2950901917e99d1e0000000000000000000000000000000009aeb10c372b5ef1010675c6a4762fda33636489c23b581c75220589afbc0cc46249f921eea02dd1b761e036ffdbae220000000000000000000000000000000002d225447600d49f932b9dd3ca1e6959697aa603e74d8666681a2dca8160c3857668ae074440366619eb8920256c4e4a00000000000000000000000000000000174882cdd3551e0ce6178861ff83e195fecbcffd53a67b6f10b4431e423e28a480327febe70276036f60bb9c99cf7633", "Expected": "000000000000000000000000000000001963e94d1501b6038de347037236c18a0a0c8cec677e48fc514e9fc9753a7d8dcf0acc4b3b64572cb571aebbe0b696640000000000000000000000000000000000d9739acc3a60f6dffb26f9b5f1fd114a21f2983deea192663c53e012b9f8e1cabd4942ad039badbd4745ddc0a26a91000000000000000000000000000000000b4206dcdb80d62195febb6773acab25fa2c09a2e4be9416ca019faeb72f1fad1dfdc51e8cea39b371a045b18947d40a00000000000000000000000000000000100758b888fa27e9258ddd5d83409e8aeac576874bc399b33b8bc50d77fce5358cb091d42f9a1b1ed09be3f200959989", "Name": "matter_g2_add_1", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc000000000000000000000000000000000a69d6d9f79e19b38e6bf5a245dc820bddbdfe038d50932f76d0e4629d759f8ca6d573fcfc39256305daedf452f9fdf40000000000000000000000000000000015f5949369e58487afcecf8018775d1b0a73e913bf77e13d2e5a843bbbeba7d1978ca27ae8bfc87d30f567dd396b980e00000000000000000000000000000000182198bb38a0353b8db25389e56ab0d8679a1bda008a65dad77e4c95bc6804f6311eb16c761e1a5e2a5f87cfada49fa4000000000000000000000000000000000eb5483959e98c30e71db52615f63521378b156f142d46f3bb285b94aef39d80feacec335b797c5a68dc17ba89d43e0f", "Expected": "00000000000000000000000000000000079e4fc2190d3441fa76c2d925d23b81e353e09e9138fdde51234195e564a32c98aa0d240f051298bf966d17adc2d6fb000000000000000000000000000000000aa327776fa7e15000dd548fcdc3a1cc6f9d0ab33046dd4240a3002962131b738ffed579945a348c795cfcb33682cf3b00000000000000000000000000000000179232ec56602d1ff79861cbfa2edece34b296541483aa65fe0cb493f520b7722cfffbe04294dd054770a38bf75d927b000000000000000000000000000000001826b88a6b411330757bb304a380487a02f7cf421115b84b3f468d11a83dbf304ce7a5661f4f01299d3c7865305a0006", "Name": "matter_g2_add_2", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf49000000000000000000000000000000000286f09f931c07507ba4aafb7d43befe0b1d25b27ecc9199b19a9dc20bc7ec0329479ef224e00dece67ec0d61f1ca5ae0000000000000000000000000000000014e6ed154b5552be5c463b730b2134f83e0071dcdadfaa68e6c7c7f6e17dabb7daf06e409177bc4b38cfdb8248157618000000000000000000000000000000000f145e998dc6eb0c2b2be87db62949c7bfa63e8b01c8634248010fd623cfaec5d6c6c193331440957d333bf0c988b7b10000000000000000000000000000000002a1ab3eea343cfdea5779f64b3bddbf0769aded60e54a7507338f044310ba239430663394f110e560594d6042a99f1c", "Expected": "000000000000000000000000000000000f69e3616e7122bf78230461bb1f4b194988adc6149372691d8794d0086fba0870a2255a2c79cc3426e7ba4d032fc2ab00000000000000000000000000000000174752301e05dcd62f7a3ae3357344e64d1c94835b2b742ac24449ee2728d693a0df10c3beaeb45d1b4af4ac2bdbb8b200000000000000000000000000000000051a761a3ceb275ec28a2a269b5ded1d9fd11a617c958e73c07de3a92ac480aa82c7d2a1852d291804e734526277f5740000000000000000000000000000000009bec9045ea89d5d16588e3373cc977f6d975d0e2213b171403a9b2ca460b3b2e1106b474185516d4200655b17a179a1", "Name": "matter_g2_add_3", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e000000000000000000000000000000000d1007ca90451229d3780d66d3aed7c9d8fc82e9d45549e8586600e38eb6763f3c466e2f6ba6ba1dafd8f00cc452dda20000000000000000000000000000000001d017d920a262b6d6597bab532f83270f41526409510e80278d1c3595ceabb9ceba8ae32b1817297ff78ea7a0d252e8000000000000000000000000000000000935b7a59d2e51bbb2f9b54ccb06ebee9d189fa82f0e97d10c8020badb3de7fe15731b5895faed8cad92ae76e2e1b649000000000000000000000000000000000792dadd48a20040ad43facedc109747411895180813349d41d0e5b389176bfb15895d41665be8d1afa80835ef818eca", "Expected": "000000000000000000000000000000000c079610e6f8770d65352f911863b6cb4fcb25cacc4a42f75e34e29e977c93244a6241cf3d5bd1040ce7d8987996f87e0000000000000000000000000000000010d08d8f6fa8ee7042c0891ea0c3b9b59a79da52cf3a91627c79d456212e3f6f39e1f69aa0053bbdb4076a3f7d05e5dc00000000000000000000000000000000069047218b0ac1e07650ac8f4a1b9235f68408f543517c4ae3c0ec47c79b468713c704ff3680edc8abd1bbed7a5fa75d00000000000000000000000000000000137737706162e02cfa75ce2154d57c9a3520818cc04626654824769ad92ff7977942f3881a28284ea47c14f353772d0b", "Name": "matter_g2_add_4", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e200000000000000000000000000000000095353ad699b89ac82ca7ef631775b2b3a6e3ed8dd320440cdb929baa428e63cb902a83857cc0e2621470544c69e84aa000000000000000000000000000000000892559ade1060b0eef2cbc1c74de62a7ff076a3621e5f0f159672a549f1201f2ffb3ac12c8b12cb86ae3e386c33e219000000000000000000000000000000000750df4632a7126ddb08658a4001f949b9764d9cc43a9393cc55d8fdbb15d4a1186dd87a6433d111888a7804540ad9fc0000000000000000000000000000000017554bd444665df044b91b0b2614017bbfcd7acc7f8c5a16cea2861235578ce2b27dcced9fba234999fa478cd3f6e42d", "Expected": "0000000000000000000000000000000004dd5dfe38fa70625216ecfec60ea8d38602552726f0fdfb8f392362ce845fe0fda76894d0e456796e08462bb941579f00000000000000000000000000000000195a85cd0685f4053ee539de7e04fccd2380819b291f89cbcd63d5a0015b3214500284a7c6568a71f52bbdbc38be410a00000000000000000000000000000000107c211bad49c7dd8555e30f2500c67e7175eb98a8494f3d5309c65a93cce89572b7b5489428eaf3f0a5c1be323c5352000000000000000000000000000000000c11f978150ac35722679cf79443b3706d288c968116ddedc1f1d0fca8cd746e3c92dc006330be14886c53c41feebbf9", "Name": "matter_g2_add_5", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46e00000000000000000000000000000000175dadb6ee656ec6aebf8d0e5edaee3f119c74e0ea64e374be9e8ab9fd3d085fceeedf4ed8de676ebe9065d83b0542ad0000000000000000000000000000000005cd6a875329c23e4918976cf997e93e403957acfc999f8159a630d21ab6f1762925c063784237262bedc82402ad81bb0000000000000000000000000000000003274bcb8db35e50164d136c2a98b5a6d2fb5f9767d0ee11c1358bf7ca5ed96d9122f8c1051ba3c658cc89777d03dfa5000000000000000000000000000000000380a240443dff85b6542f75db28b87c39e278cdb8d9627efbbc63b229e6ce783f6fb0114c8e91c2fd6ea71c95bb99a4", "Expected": "000000000000000000000000000000000fb33caed4de22cf341bb3e04d41c0198b064c1d371a24f5cf59595ab4a1edfd379916a40cc405d35f0603b2f8fb987400000000000000000000000000000000131ad6172c20b3a1cc2542db037de1324086fd9cd140ae97987980f260023d91b24504181af6fcbcfa242f48e99559320000000000000000000000000000000004a0404c00789459395f5344544041785d10f2fe74d4bf484966f5e9b6b4c4c8cb113a811a4fa82a1cdf8e3242bb418900000000000000000000000000000000086ba6a914f3f07bdc6750fcf6baf76124a17964bf9eb9a12982e8a28ca04360da3544b69436d5663e4e94bf7189529b", "Name": "matter_g2_add_6", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12000000000000000000000000000000000834cf1b4149d100c41b1bca0495e455002eb6596bddcb94ae48d0c65957e8b313372f8e0d6e57504664b266f38293150000000000000000000000000000000000de2875fbd14760bac4c2cc7d3f239177efe9f7f61f767be420d44f24c9fb863efd60dcd732986db8c5b72470617ea60000000000000000000000000000000000bc9535ebf11c2dcc8c7d3bcd09d7d14035635fccb5fddb7df29ce8855e79f99809781d6ffbbcb33d1227314609abee00000000000000000000000000000000039bbfb4d969d702255e3be7f255a97529a19687ce38cb70637c37894d4102591feef428b0afe8c9ef50310ae3b83091", "Expected": "0000000000000000000000000000000019c8a1a206c0006a3033377abba4c31c55710a094d8c9dcef7560818e90411861ce7d189e2763f8fe69bf75e719e4efe000000000000000000000000000000000cccc6bba8691c210aa0a67d26584a359fab94041d853160abd9669893c0d398c805cc37fa3c33bc5ee5ff915b985c45000000000000000000000000000000000e353c1993c36763acec2a75495560e743d099b565f3de195e011afcacff3d60502801f47695da7dd589af81e772eb7800000000000000000000000000000000100c6123cf08eab6c59d78b414fa504ed10c204851289b0598b40ac31971fa12cfda4ef7cd2d64f9797d4d2b193e0bd2", "Name": "matter_g2_add_7", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5b000000000000000000000000000000000fc09c241899fa6e8cc3b31830e9c9f2777d2bc6758260c9f6af5fce56c9dc1a8daedb5bcb7d7669005ccf6bfacf71050000000000000000000000000000000018e95921a76bc37308e2f10afb36a812b622afe19c8db84465ab8b3293c7d371948ee0578dbb025eed7ed60686109aa0000000000000000000000000000000001558cdfbac6ea2c4c1f4b9a2e809b19e9f4ba47b78d2b18185ed8c97c2f9c2990beadc78b85c123b4c3c08d5c5b3bbef000000000000000000000000000000000ea4dfdd12b9a4b9a3172671a6eafed7508af296813ec5700b697d9239ae484bcf7ab630e5b6830d6d95675be5174bb2", "Expected": "0000000000000000000000000000000009fc3870f88288c680b43d63d3bb5305b99fe461e59c07be981b8819fbee0d1fdfae0c037e830fbbabc40cedac7919720000000000000000000000000000000018bdd4903da4d14fa28af4c2cddcb708238cf68673ce77a04a3926c4aaf17d39a831c5401e84dd042d6adf595a1763710000000000000000000000000000000002c398f0e8ad9752f4aded980bc5de2d91118db06818d815c11e818ead47e7065823737db8e304bae32969cab065d1ff00000000000000000000000000000000180642a633c3aa402e5c0b18fcb6fe8c115575b863abda59b5d91997ab01014faefc975d0aee994f98cf37ce79eb95aa", "Name": "matter_g2_add_8", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb815960000000000000000000000000000000000b36d8fb9bd156f618ab8049d41dfe0698218764c0abb10e12fae43c8810b8e2a5201364e2778f6f433b199bb8f9a6800000000000000000000000000000000000707eb15411b63722b4308c0ed4288320078d2463ae659ad4fb3f9ef8124f379df92d64e077403e50727388adb59ac00000000000000000000000000000000158e1249d5b91614924acb23899c6bae408697dec0982c10d0459746499f4e6739afb9d5129568106ed1a1caefeaa9640000000000000000000000000000000019e841562e4aa75321143f8ce1e5ec6158fa5cb8b98c839a486188260c18ee8a7600930f23aa39eac2eb520d6a0fba90", "Expected": "00000000000000000000000000000000199600699a6108599c638df8f965d73b5de4ca74598df281ec95c539de2c7eff9767569692d8e0ad120fcbb3d9335b95000000000000000000000000000000000c42b11e2585ba93521b3c968e9dee07e4f5168c11087d8d750795555a105df70c969bfa79b1ab4e5fc8d81657235d08000000000000000000000000000000001370daa4699daa99e9940fe04f69150e6f752798cbc0e66c91c3bd46149d935c1815f32d7f14b510e16d475044eda9cc0000000000000000000000000000000016c7a00be10de5732795cc3ee2951e58cb9d42f9b05d02fbff1b83fab5d3ad830cb8178092b76172108d7a53afe8c539", "Name": "matter_g2_add_9", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e97795505419600000000000000000000000000000000186a9661d6fb539e8687ac214301b2d7623caedd76f4055089befba6ef2c96263d810921ad7783d229f82783c9def424000000000000000000000000000000000447f3e20caa1f99fbaccab7bde2bd37fe77cea691ebf2b9499f95bbbb77afe72b7039eb0c05970b61360fcf8ade73730000000000000000000000000000000005e11f828eda86c10a1d7929def547ac06885da278afae59c5d95453caf0a2d8ed186fa7c6d0a7ab6e9142cfa4b338190000000000000000000000000000000003d954e61b6ab71042b19e804efccd4956b56662f27f70a9255cec0c464b86c0e83721ad3785dec62dd4a9dd3d6d5d53", "Expected": "000000000000000000000000000000000669cc8a3acae17f99f805afb9012a38851a9e8d4fd9895a9946c29fc859849c24d7ab7b6278c449cfbc5f1d7ea1fdbd0000000000000000000000000000000007a9095be808d0ebc99bce94e851d2a7cd3e1977b923064ab5bbed2347cf18f3343e60120fa051d12fe27da3146cb423000000000000000000000000000000000f1e7f75887651f67457f6dc064d7c11934035d15fe4dc40bab970160ed1b1aa230a3fb84dc1da08770d847c0216347a000000000000000000000000000000000efbc62ade1678cd70eb38c644038bf19e52b0859f65747068d9f3124762d951e4a6ff05f34b6d14919774f8409adff5", "Name": "matter_g2_add_10", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a90000000000000000000000000000000002b94534aa0ba923bda34cbe92b3cd7a3e263741b120240ff5bdb8b718f094d3867e3fcabeab4a7be39c8f8c4fdd10d900000000000000000000000000000000048711cf6a82534d64d072355cb8fe647808e7e8b2d9ac9ed52eb7fe121647a721dd1234c71ecd163d91701eb7331cac00000000000000000000000000000000141ef2e23a1ecc7ef2ed3ea915492e79cfffe60b5e0de8441e878bd0653843d79c724e3c5ebe2321361df99f8932ddc200000000000000000000000000000000085513b4009f29b3e00a91c2c4be418368560802ba4194cbd2f4fa3d72a55fcae547014434514a8b2a8fe3e0b28d2773", "Expected": "000000000000000000000000000000000e25a38d0ce2aabd2538c95ed463f226e3f29ce7f10e1be27af2d3db741926d557178c4b125af8789b40480d8beec0890000000000000000000000000000000002a94b7c57fe2783d055a537004a3b67e41f5374da0813094f5944fbabf4d27eb576dc8b21ccc15f8339df14ff8785220000000000000000000000000000000008b9efd8abfa4fd71a8eafdba9df38360ef0b0a117c0052528d1c24df5032635eebc7b201439f5de858514666c68cd270000000000000000000000000000000012a2fde51f6f4a98435c325dc3b1ae846bc33a5ffb3b13fbe3fde2f74dec0aa815fa8e42392b3dbf798cf547fdb4db0d", "Name": "matter_g2_add_11", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b381731734598360000000000000000000000000000000009143507a24313ee33401955fc46562c9b20c9917df3b40ccbd7ed43b1349d4551cfd98a4976d6fec5fc289460c8d89900000000000000000000000000000000060566b79df5cc975e669da8ca3a7fa91bf3f5c9fb871c3d62f4a3e79dbc341b89d38b588e5414bc385d5e3cbf3ab9310000000000000000000000000000000016bf40b8cc4c01a87aafae0c4439b623a51ba9a383756a550b69d627d6f45209f0d87e4f9be9edff35c986f7b9c49e3f000000000000000000000000000000001842d9172bce51a164fbdbdb108d0faae07e4642f21c80e40ac31e737657472ae3dfe552b65349629c210a068c4afc0e", "Expected": "00000000000000000000000000000000067265782d58b04a2ef3dd419cee506e076e49d1119e28db1df7f0e22cba9bbdabc560084cda50bc8db3915fa9c489a30000000000000000000000000000000012448a61fb2f6fd8e355111b671f0e888304284b72d5688091f2ed00edf7ccb7e5bd8a733a910d6964dde07d393798470000000000000000000000000000000005f687356ff6c634eb46613be8e98540107e706714434faff54510234d4aff42ef7752e154aed63fa8ff905ec0af628f00000000000000000000000000000000180dca84a37c964b30f5cd11a090e54acea102f1b884319f8d1252a37bda005512ffc39dec8e33af0dde0d37993f846f", "Name": "matter_g2_add_12", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b000000000000000000000000000000000ab19bbddd661e9db8fe4cb307ecebdc5e03efbb95c5b44716c7075bd60efcfc67de0bfd7c46ad989a613946c90a4c1000000000000000000000000000000000120800e7f344cda816299fa37f603ade06beb3b10907f5af896d6b4e42f7f865b756f14164db84411c56cb2ea81f60be000000000000000000000000000000000f688ddd257e66362af1437b6922d3397a7c3dd6dea6bca8ebd6375e75bf2de40bc287cbf3434388191e56b92949c83b0000000000000000000000000000000005252465784aff8c1c707da58b5808c69583bf852d68f96912bc53f8dae4536b09ccbbd25a49d9e744118992b92b6792", "Expected": "0000000000000000000000000000000012a29d35c9af52f172787c90c5a3e77ed29d66feabf5d7bdd6bfc14dd9a05d402976b84d44647628c908d1816f4e7100000000000000000000000000000000000caf3c372e36de557ecd7eba02e6a79b1b4cff30343119df7a23662c8512095e051ae2dc27e577635c74a260be2b084c0000000000000000000000000000000002ceca293a58bc9beb4ee9a0679eab037f5cf7b326d65c0efeefdbf384ad8e4bc08a3a75a02e6b9cba8963e65d6e76ef0000000000000000000000000000000004631773a6590bc89b49a75bbbe2e732f9466ba259ef7a04ae69b6aa5d5a2621c1918eb213101f6f7eeee4656a7b1472", "Name": "matter_g2_add_13", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd3000000000000000000000000000000000e3165efe00f69aee84ac56d2161f07c017abfaadeaad34f8c96799d68bae0e6f9b557bbf9137e7826f49f29c58d1ef9000000000000000000000000000000000de0dce7ea371ad60f21f2cb61cb582b5072408a7efc91edf05b36a1a3b58fd9e6cf808d75157eedccc8f1c93a8ae07d0000000000000000000000000000000016d911943d80427385ebac1d1b293914a9e4dd9db06c1d6a758192d63c8fc9368e02eae7fb0e3a7859408f215cfa76ca0000000000000000000000000000000007bfdc6afb8acec625e50ecbc08a5cdb7862b795866323679885ba5cba3fd51f181078e03fe35e96e6383c077eed1bf5", "Expected": "0000000000000000000000000000000017f155ed9911ec56d71d63d57556de071ebe89be36e6bc9943ec068a70dd5a6f045dfb9fde5c1e29d52c9fc17579452e000000000000000000000000000000000a60d62ea549edf4b11f62f2321f39d41bf11f3c4f858dc7db85b1dab1b7644e27eeb1d022d6082f59c65155068d2c390000000000000000000000000000000009d309145fad15860e556ec4b4aecb415865954247c2034d5bc96026e4d6f7612af6e2db99f4e462acee2b303134b91b000000000000000000000000000000000114ed157e3d020c5397cba7e10cb864aabb47461f166a6724614e689274ae74c505fb6ebfe3e88da0d6c272a15a0527", "Name": "matter_g2_add_14", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bd000000000000000000000000000000000a68dccbe3452731f075580fe6102b8ee5265007ee19c56d95bcb096a3a6ac444f4145b980f41afcb0a865853b279bc600000000000000000000000000000000164767ea55a9038ac2dd254d8c8a4970dba93dacdf5416aecaa407914719cab165e7a32784b2c41652a86358737d831f000000000000000000000000000000000da9441fbc6578c85fdeca49082c9ebbf183de894d67c65158380ee56132d3cdb44b100d72b6d3b82688defb75d2aa390000000000000000000000000000000017d570e4f6e46550679d5d12c347414da207060f594620e2f8db66df8e0b06c912290b207a268e782d4b45db19a199db", "Expected": "00000000000000000000000000000000118e0c81f9157395578f0fb83b179721de2af3326d13189cb8f43911d8c3268a11fd9702f09f14c115bbdc43d5fbc08b0000000000000000000000000000000016a548df8c87f432c31e4e32c3e5b4d48d6f29fbe391d1181174be9dddee450e7e96bffe8c9f23692ccc080116592944000000000000000000000000000000000eef72a5c698c58f1d2ae9415da256b54d7b1ac37a1d1b88727c0afcfd854a41973c6cb10ecbc3a90050fe3d8d3ce8780000000000000000000000000000000019b16ca8f955dfd21830a3f7fafcc97d7de977bafe1983892988aaedd430d22674d97897d24c1643e99bfa6256df4bf7", "Name": "matter_g2_add_15", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca800000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e", "Expected": "000000000000000000000000000000000f2bf3f69276d390c9fc2c15e9f5f5d0b3cf9a6eb028c44811b481f376ab60e17d33a04b78348e46eaa94332c5f16ff8000000000000000000000000000000000bedd0437fb3f4baef87e56f33c77fcdff6a5512571cf11fd9605697abd8763315f1fe4bccf04acc6e971d6aeefd9c1500000000000000000000000000000000067c3ff69733baae2fb4ab77cddb7563047c428b40a257a375f8cf8c9d230a6619f7932b86e0836fff0c1c60d2c4dfd900000000000000000000000000000000057526faed8d62aa10e89add5a338320c748ca1f96ba5ceb579efec69d17475571fc4ce6fce3a93398ea88340f0e969d", "Name": "matter_g2_add_16", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000135aee0e30fbcad798738c10d4aebcdf50c89ce516325f655fe763dce54ffedf94dd74168611e5ae879b5bf5598d62dc000000000000000000000000000000000c728e672cd8b3bf9341bca929c34118b566cd3a80452d7015bee9d5cdc001b1f5c678d4b2cc4f7cac353e7bf326ca1e0000000000000000000000000000000014809aa22e2051e463fba6d49fbb060d0c7f599a0fc5409d34e71f34817e7beb1251810ae6eee1848c60796fb8647dea00000000000000000000000000000000145a4de777d86025d50e12f9a6615ecb9bdd41489992d1b643dd9aa549acbc63b04b0bdfd14b6e45c70f165e9a8c91be0000000000000000000000000000000001c2d8d353d5983f22a5313ddd58fdc0d9c994b2915dbc87a9b65b7b98ff00b62e140a27dc322d42b3ad190c1b3728dd0000000000000000000000000000000010412f3625947b38bb380a6ed059f1677b7a7afcb91517837c563dadd0e285b95740a200ddff6570d4d92bb636b625bb0000000000000000000000000000000015f4f9a480a57bd1b2388532ab045a1ba93d2f6589a3022c585fe06a1d611165c99d70be06251812405c9c37d6e9f7730000000000000000000000000000000001a78e6c5062a6634a56e9853ff5afacb2e7cf31fd0ea5f0d8c8ac6174c88133cf2f63450ec4590544c9a0e37daac1f9", "Expected": "0000000000000000000000000000000004fc19f8fe47e6acd37567016704b07f906e8741fcb196f697e1fc24b0204292693ff424bf1c5e407f5bcba5a3b1ab85000000000000000000000000000000001816f992c3c461fa6d2014ced382a35b0d70e61927d72b4d661434efff3dafe2f4b6cc91bb1a5dbf809f10f3ed7f36de000000000000000000000000000000000dadf7f7223ccedbeffef31c97df7e01f99299da71b589c8828b65715012aa343d7e041dacc57b34a6b5f84523a7938100000000000000000000000000000000167f7e73e22df81bd2a7a6f14e940a401bf414e5d18b3aa610b2a82ca8f46aecb5721d0092b27f8968b2302c37957268", "Name": "matter_g2_add_17", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000009a58b7116dbd6f550f8ca98071813130ecaa9ea86d5275eebc36860690fa048c9ebeb46600b2b63e847bff3e38ed0d00000000000000000000000000000000113ffc0932c041e0e34b2540c485eb74f5029b339cb60bc88a8a749310f33f330dea137e5f340044fd689264af66696d0000000000000000000000000000000002642da3c2c7b6688aba0b19ab29ac72e35caafa044863c364ea8833fca850289de52c0963bc33d7bba40cb5f568718a000000000000000000000000000000000552d35ca054da2f148c119454f6760607b351f2441921a2be17da2cc10902d71571c5554f132e60df79679428fa07e3000000000000000000000000000000000818e567aea83eaf3142984bb736b443743659626c407987b604a30c79756081fa6ae6beeb2e6c652dbfe9cf62d44e3900000000000000000000000000000000193f0317305fde1046acda2c9491e376aa67244f68ef6495845d049e1293082af91f880be935d9d8ad0e25ad918caae200000000000000000000000000000000109224b8178be58ea4e4a194ca66bef9d14f6fc2c625d25feaa4f32e0f4d72d91024d96839bc96e6a624c5ad6221bd94000000000000000000000000000000000e42decf8a987efaeb4ede37236b637e61249bf6245679be7fd4d633e2d814ed4748b73890ad3c4fcbcfb4960cb67ae7", "Expected": "00000000000000000000000000000000041a5783c748247f05457d30d16f93431e9046a236d5025cc07a27b9f2abaaa556e2df65cf0f0015107253fe94d8b4dd000000000000000000000000000000000193638bf69c7508c4b12808a62e89883c34f97ded6e1b5dcc3f28191e5c7fd901a72a85ae386acccc9865f8144b1bd500000000000000000000000000000000180e8184ab583da58b77b8a4d108a366dff3e3b336ebc5c9153fa815188edc95e7067ef25f7d79526c295d634bc98f5100000000000000000000000000000000125b147100f6df0cede8e22151b3423b1dd364899fdee103c71a44388ff002a367627a2342e15833644bcde61f2ef6b6", "Name": "matter_g2_add_18", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018fbbcba3d4b1e548ceaec4a48db62a2420ff29a67af332ee7ea3f902f84e6c375fd33abc33d945c5bca25603979f9a400000000000000000000000000000000072ff416994364bdc6535f36c82212afa822cd94fade69f11eb38dbdcd37c7e22af55fe05e6a826dad822073656eaac10000000000000000000000000000000017bba179b847278a4878b6faeaab3b1f4bd7540d22817cd9aff95557497f8b9d286657b6162c0f89f7820becc637dd550000000000000000000000000000000018e2bfed71aa9b11fefca2f0db8bd9b8c69540267de50bec4fc90a6e9741891465c9761d19282e1100b3707eeb598b31000000000000000000000000000000000ca0d865f8c8ce0a476f7a6edb3ce4bd5e6c3a8d905d8fb5a10e66542f4325a9963c2f8d96f804f4d295f8993b5204df0000000000000000000000000000000005a966f6254f0ef4f93f082a97abe07db56f00c2ade047d2f0027edef6f00a0dfecaa24d50faa778fa29087302211f7e00000000000000000000000000000000121c51da366557c09af1bbd927521da88dfab3e2e9a95b6effb0a968795486f281f0c887e37f51837557b9e3808987130000000000000000000000000000000001a5524975400b1e88f3fff8dd34dadf5d75564cfc0026df31ee9c2c1d48b0f69a48e1e4a48cc4b7db61f023a7915780", "Expected": "00000000000000000000000000000000095fda8adf3981f4468fb82aa0ccf80e55138c922c6422cd8e67f53ee63e7a390bc345469e9211a1f8d810cf4ba27d0a0000000000000000000000000000000015c19b6af21f75e8e53fcefbae1c8d7f97853a8aae5fa62e606cfc92ae71890702ef9dc5609d3ca8fefd415fbd820c04000000000000000000000000000000000007b7e908766d34c5d99cb7cc76d5d5ea83c29ae1d9b83b163741bc9962e293926b1e251b546ce0c1268def728da78100000000000000000000000000000000084fbd6253211f7d66d52b7f14360729d54b2f94c52f2b76e521dc3961c40b4f19944923f64c6425a44eb158a9727a4f", "Name": "matter_g2_add_19", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019efd37727dfaedf697fcda7a59847dbda8ca7cdc92f34e68691d682e20ae6545ac104d6660fdb8f64a051e69298eae8000000000000000000000000000000001225ace0fdce456dd888c9672503b68ef77b2d11caf1265a767a6ea14911e3ca03fc153f18dfe9d95e0cc68b7b8a3a8d0000000000000000000000000000000008a6b059c1c4da046cc0b1b5d7f33270aceffa607daf6d0d078c06f940604e1a0b4adf01a4091306e3c7eddcf3d95101000000000000000000000000000000000f79bae5260a2f114ffbb9273f3049d3ebb002500a57ee0a7d157d86957f43f87a2e026fb9892dacaadca5ee04fc8e170000000000000000000000000000000002b51851ef3b44481d13f42e5111fa4fec04be0bf6acc7e59dec3a8c8113e5bb7b604c6dbdc5e8eddc2a1ffb81bc2baf0000000000000000000000000000000018ddb483ae75402852b7f285277ff7308ff78a3364cca8b0e0e1fa9182de275fd55c1e8ec3dbde180379c4280787ba8000000000000000000000000000000000170539890c89a4f91acd59efd413b5d1059f0c8fd8718e8f722e865dd106a4eb02e6fb0cd71b34ebc4b94375b52e4dd60000000000000000000000000000000001c2e9392f5d4b75efc5ff10fe97f37e2671cad7e4710765866e92aec99b0130e6ff1314502d069fb7b5f86bfce4300e", "Expected": "00000000000000000000000000000000121e7f2eb906d0b31b8ce5cc46638428b6ee57a1ee70e4ec3c2bc044230b9b86875abe0862145b442c0e34308efc690f00000000000000000000000000000000139120d0a10b82737561d0b3fda01b6df69d9beb7dbabf3ddda036f9b4c317f3ac1eaf400013fe5ad664bea44a73b336000000000000000000000000000000000a923184b381027d8cb3f82708802b204566b2b8bb6a72767aa396324d8a26b4e0f0cb92fd1914d77a4e9af2f1ec31e3000000000000000000000000000000000409732f2225cb5e5c002bef17512519eb1a18bf6c3d7f834d0c7ac8a38433c88b550b3f443d259313eb1133620ebf0c", "Name": "matter_g2_add_20", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016d2b73eeceee17d3bff3aacac9df9ac1c4248d9ea7d6a503a757f7bb22fa6970bb6f5cb5ec154785f7252e1508b382e00000000000000000000000000000000081edc68bbd8db7b10be06ee23d090bd54f9ca07ef24dfed7df7bb05f8cc26e6889dbd40ea203fd5cca5cb588199f9e40000000000000000000000000000000010d3478508619ea9493b4330e2fb9150024cd32dc1378f824788a884a4a30fbf39c630f465557bf0c6d69b4cbecf89f9000000000000000000000000000000000f20c9b134db5d8b7756800c031bf5962fc560ba95d4bd9157b16179f1a37ae08696a2be455ad8d018aead6adcc69b710000000000000000000000000000000011bbc566a10eadf16009c1d2655cfae6adfb0f56f5e55b31dc000414be1b4cee9a0b9f7d9eab4c6829037c327914d5640000000000000000000000000000000009b28329096d8644dfcba6e92477eafff29f7477da4581ce76d1493f03034d7f5d3acaadbe42c76a83ca51db79d456d10000000000000000000000000000000019f75a303fdede5d97f3e521b03ef6b9d7c008d770b59ce3ac38900b340895e008342701ad1b41830b9c010936f4ff1700000000000000000000000000000000161aa1853edbb56fa3bd685c9c6b88e466dfa3c4f194f6774b4d9b1f30b016993bd0d65e8e9d6dea6caa196ff735bd67", "Expected": "0000000000000000000000000000000006a200642d5cece5eaacacb36000b4b897e8d8c661c8282f90495002aa515c7638183cf1e80a0b35e953adb92b6bb845000000000000000000000000000000000e88d4cda34e98df4d727fda79b67961b5b8efb1b125ef2a8eafc481a2cb2fa1530e59a091f31c25cc49d38f545491ff00000000000000000000000000000000082f38c1a1c35981f537547dc3b59331ab8c5e8dd261df58fe6f0c44ef1e65d0cdc1980e1a62f6248f38d0afe91e5627000000000000000000000000000000000eda1002e202e9ee4df5354cb87760d4df32eba1eafdad27cb0636879370a8f93be0bf2a30f15f2fbcd7e52c1bdf6b05", "Name": "matter_g2_add_21", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003dce67181d23af9729e9fb0653d7f79c890fba27de42fada93123e112c4a468fa889921192db8047d86e4db77c60266000000000000000000000000000000000869a1e39d42d9bb0cc0568fdad16abbdac3194af893ebd8dd8f8c2c3c855abefa5fc215412168acadc88e658e83f5570000000000000000000000000000000001ef139a75194f3c4b1378c2b66dd304d179460bac0a289405cd8faa3ff66a7b6e54eb7b8742a68150b1e098630135c40000000000000000000000000000000003892b5a645af916be2c6c7fc0bb08fb5f39341d3c68598940554e1be11e1be75af920db0c8710ed13c78edbf683f17d000000000000000000000000000000000ae7289aa9bf20c4a9c807f2b3ac32f0db24e9a0a360c92e5ce4f8253f0e3e7853f771597c8141d705062bef12d4fea80000000000000000000000000000000001d2f610d79110f93145faad2e34f3408316b1dc3a72852e811b324577d9037035e24af25002ddd100cd9283b70ddcad0000000000000000000000000000000012947315d5c0ec670619125eed0de3dd259a008baee4379b82accf2391e70a2bdad264cda04c3bc1b5394a62559fa0ef000000000000000000000000000000001239e687c4d3417c3c9b655035f8d8a649c255f9a8e6f03b785eed0d416a1cd6ef7c8b45563acb4616af24f64dbccac4", "Expected": "000000000000000000000000000000001341cf3316152ae8d57ea2194224f04756690133d2e02d077dc271aa577278e346e0ff66e8a49ff8c983fd34546e1f6f0000000000000000000000000000000016c9093da650643f4b4061e1c6e55da6ebaf9f234bef8325aeecad3863a0a2f53e1cdb2d54aa8b075ce6e6632fb4cd660000000000000000000000000000000011eaf3dee010bf2a16c5fbb1f7aa559cd4d831f087d9dfad4e157a6d2b6495e370d9791cbaaae19339a65726ebfc3b910000000000000000000000000000000008476d793305204be414819fce2ca70754a532682876277bc0586514f2096ba9998ae848c722ead6722d5af9395ff77f", "Name": "matter_g2_add_22", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000264dd4b477f5db65edad28c7153ed919a863c5c5661e0125c5429b323e055fd69c33142dfc6ed9c87082e2be4675e1f00000000000000000000000000000000046ea088a2ec94d3a1f1f97949f1ebc49690c453d316cc46534fa253b34b30323b6071d147d64bb94e02fb4db07bb0c400000000000000000000000000000000013692a33bb1348486eec40a9e93a4ea3810c7b4d3188cd07e235a2c898aa87ee0d17682fd24f4d978f9fb028fd26e2900000000000000000000000000000000115f8b64c00cd5cd344a7b5edc0ef0bb85a3e8f0f9dfb28f8ffe12db3e0d222c2d45dcdba0fbdc161c5d558bc71aa097000000000000000000000000000000001179ee329771b5913d07818e70f6ce5a58d74ea0b573eaa1bd3d97e45d3eeb27fcc7d37dba127af7a38354cb6ff48f7c000000000000000000000000000000000c898abe6eb76ef99f5143cfb8d840a918bcc9096ce25caa45d0bf5d20814cb01b024f1fd2cbecb6bef65d9456070dd90000000000000000000000000000000008e2a4fd746e86f90484f9b9b7b47b6afe5833762e515ccb276c554f00df88dd9aa0fb792c5f419dda0465cfed838e7c0000000000000000000000000000000012b5e6f7070c0045ade96f548ed6428c5030fa20c6f6f37a42fde9dbb5cd01def0fd8585bf8aeef913e7d42b9ef22efa", "Expected": "0000000000000000000000000000000009792d98ab9b90c2467ad0d070ea44f382ec7ad5290a59d889313c5a55d7b8e837333ad7ecfd97221d405cd6c549dc8e0000000000000000000000000000000002b92dd07b61faec23f48b8a7893dae29509fefd688a978bc2e870d4cd6f963d708a0611b4aa65f5644fbc6ba4c5e66b0000000000000000000000000000000011e46a283946a8e033afbf7c14ce3162a05867809d7de94a090c8cc2cdca8bb79add21f6e2fa8d7f39ea6d26cd37ea850000000000000000000000000000000000fddb7cdf1f1126e7a6780e4892601121b289a386ebce0caf96cd392ddc57c47e3f9284889fd8a18fb330d6c40bdf67", "Name": "matter_g2_add_23", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000014c83d58d90db4821a0411fab45f83fbc05f7d0d7a67ce75da3ae568978d15f4c1886c6fa6086675c0045efb30d818400000000000000000000000000000000001e68691123451f4c3df6dae62c6a63855ec3597aae33a8a10ee274e902e9aab1460cc9c79726312df0ee0ce90c8d3c00000000000000000000000000000000018a39eb3e3c6c7fb8ee304e55d15e209afe2fe278dda93552a7b9f51fbd778da1502eb6775cbc3f832f8320fa0686240000000000000000000000000000000017c15910fad1ca5749aa82a5a2fa98b0ebb37e92912547fb1741f18c34e0d5fc3a307b928636c25f0320d71cb9d31062000000000000000000000000000000000fe2e61bc8e9085d2b472a6791d4851762d6401fd3e7d3f3ba61620dc70b773f2102df1c9d6f1462144662fb2f15359700000000000000000000000000000000031f160cde626ca11f67613884a977fb5d3248d78ddbf23e50e52c3ba4090268c1f6cd8156fa41d848a482a0ca39eb04000000000000000000000000000000000eb61ba51124be7f3ee9be1488aa83cbd2333aa7e09ae67fef63c890534cb37ca7de3d16046b984e72db21e1f5c57a8a0000000000000000000000000000000006bf6f5d65aa7d19613141018ac8bf5d1e6fe494a9f30da215a2313a0241779006bce33a776aeedae5de5ea6ee5a9b9e", "Expected": "00000000000000000000000000000000054dedc002c5f2da8c6e0a0146bfe5c83200b276b074e6d6f2c397e1208f152d3ea3e8f0da7da62cfd2a028d4c94fe5b0000000000000000000000000000000012ff307f86e266e7a212484a169d3e81df98217c6f715176913b0d383cbe4e790212da7feca0cea66df09d92544fae010000000000000000000000000000000009c211438dcf8ccb664b535e73eff304b92aa2f568aeaeb8e10ec142f92b211bb8147b250dad77d508cfe353667b6f150000000000000000000000000000000009d1734f4ecc88fd56f412f9243c387b9da659faa3fe7295580a6b7519b1980bd074339fa9b0bef44dcdd0cf0c4a629b", "Name": "matter_g2_add_24", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fa96d9fe01c18732e8d6454df9bb1f482c4b9add837ce9c354c72d49c2d44ec694674aaf0e6d6a095cab7ebb57ccd9a0000000000000000000000000000000001f8ffe3fb7e9e311e0f6949c07c26a0febb181e37b2268bb5e125fc3a100323740d1ebaa5e635dba3770fdc2ce4ee860000000000000000000000000000000012ac42095fdb677720ab3f14bf0afc55c95b43d28d922a5f8cb0bd841306b978751d24546e3a6474976961d0768f29e9000000000000000000000000000000000baf9804d99039c9fe966a696c64bdacc9673b0906b4deab108d34fbbaa3b0905d50892278570564017b96828c7e1ac900000000000000000000000000000000196044a5cdbc5300ee837dca745a44379070e9297697f5db28df4a37307cc740abed45cc778a3f4e3b8c9890ab6c3c70000000000000000000000000000000001176f5de6a3577ad67863bd3d9152ab9e8184964c6ac276e95946788f5a76394047580077c0971d874a40d510eb0443e00000000000000000000000000000000147dd55dff69213c5760e8d22b700dd7a9c7c33c434a3be95bd5281b97b464fb934a3dff7c23f3e59c5d8d26faa426bf0000000000000000000000000000000019efcf03ddb0934b0f0dba3569809d5b48b863d50d3be4973b504244414e1e1db56adff51d33265ce102b320c552781f", "Expected": "000000000000000000000000000000000896a38ce734c550c178786092292e737d44fa5f503d6d3b66c75e6bb70b59d1db9e8baa1ea3e256e2dfd8a942311e75000000000000000000000000000000001231db96a35229a4c7507b0ec193491446a0b43115c27d18b3715fcd4aea14d4e5c99db5934e73bb0b86f1bb91ee96fa0000000000000000000000000000000000d6f95d5637b29ea889c028dacdcb484d8ccdb243da4d5ff49e5ad82f234d414dc1484e9ed6cba1b5940eaabd3066860000000000000000000000000000000007de052fbb76902e06e1783fa8afcbb54a5069b4c5e9cee78d43da2cf76f24843a740a9eec6fe9b8f9bc4ac9baea77a5", "Name": "matter_g2_add_25", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014ce6d88a7c5c782562aa101550f1af487296adebd9dae8252698ba04fbd58b92e2216de6ffd474d5992f97d9f22800d000000000000000000000000000000000ce92a04f5c8a99ca0e93992448222519fc454bda5d1d8638a7bfde968386e4ba0dcd1da59cd81d4c4dca3e584be0275000000000000000000000000000000000cb570796f5c8f7b8aa02e76cb8e870d3365fe4dce5df07ec286a0a821f922b4003d5b69c0f1588206d9544013e268c400000000000000000000000000000000098056a033d9cdae86aac02de3a444471854b909680719154b44d4f55f30087294e39e57643c692d6da725b8592390800000000000000000000000000000000005d8edbabf37a47a539d84393bb2747d0a35a52b80a7c99616c910479306e204e5db1f0fa3fe69f35af3164c7e5726b50000000000000000000000000000000005015082d6975649fbc172035da04f8aeb6d0dd88fdfac3fbd68ec925dc199413ed670488dc6588f9bd34c4ff527f149000000000000000000000000000000001312d53088ca58dfc325772b8dc0e1b20cebf7b2d5b6b4c560759987b44060bf4a59a68d1a5623bbb3cc5b0bc3986b810000000000000000000000000000000012110cd462c6fabf04f67d652639d19640c46f51aadd6c4f9a6dd7806cffb6192d95c198f4c8284151feaa2e2a0dbc1f", "Expected": "00000000000000000000000000000000156914a9137e52abd4579599dea4c0f857eed0457ee1d80635d3a6ccf0c766ba8ab1b6f989711fbdf125c4ff06b597ea000000000000000000000000000000000c60184e8ab32019ce20d2d137130f657c8964406fe4abb26da232c9c5dbfab243837d700c88d6b9ea4b8f0a2f514281000000000000000000000000000000000dc3e6e3acb898552791431859943d0a83fb4ccd62e4ab2a971370a93a99a9dfcdbe4c42535aa063354e0f2cd48308c300000000000000000000000000000000025be02da875d4990d1f0be626ce634c4856ea91f88f636bc27e313e73897c9c13a1e3ae70c1227dfd4fba97f521d6af", "Name": "matter_g2_add_26", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001214aacb0a5e6b7a40369a83c07fa8cf1786ce7cbde2b5a501d9c1292532df7822d4fde10a31fc0cecce3a7cfe3311850000000000000000000000000000000004f9669d8fe4f884ae93b2505710e6e45b19b7aa5df8cdd811f09e547efc27d21024cba05e2dc9d057055f30ec72d9df000000000000000000000000000000000a852b821b31cd27eca19712a636aa05ef2cd82c36ac1c2ca240edc7d0172b42a72c42d3cba583a5b5129ac1c9486e270000000000000000000000000000000007bd8419e791a5cea04993509e91a980d3ae4987a5b322400b6e4a4f2b636891a1c7ba4de96b53426dd556532403d5a300000000000000000000000000000000117fd5016ddb779a6979d2bffe18032d9a5cdc5a6c7feeaa412381983d49ab894cb067f671163ccbe6225c3d85219db6000000000000000000000000000000000dcf01077dcce35c283bea662f4e4d16f871717eb78e630d9f95a200cc104fe67b0d69d95f6704d9812b46c92b1bc9de00000000000000000000000000000000121f212cd7251697ef6a7e3aa93eb0d7d0157cf1247d4411430c36c7277bf8acfccc4ed8590b5e8d0f760e0e4ed7e95a0000000000000000000000000000000007d22d78b486f575e01e21e1239cbedc4628ba7e01ecf4a3459bd78a9716e2969f26ea3f2449685f60397e1ab2aa7352", "Expected": "0000000000000000000000000000000010124c1c1c10868b570d2969ebc3bf5cd6bfab13ddc93f0fd2b8a1742eb8e04d31063bb81c52b92e253128d4cb4413a60000000000000000000000000000000013f89997cd2ddae00cbf24cb66a92146c553c6fae41cdfaef14d49078729f239ad2661937dd0d4d6ffd7076b03e0aa84000000000000000000000000000000000ba2ecf990cd846c95b35ab60d4f97f5814c8189190df9d521b3dae462f2d44db006a0daecf6b82c1459006bf82ef7c90000000000000000000000000000000016dc129b83cca5b3c699628d081306c5fa61faf9dda5e92894931714037628fb829c595bf64d4a7fa295f136ae244601", "Name": "matter_g2_add_27", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005ef88bf38b2f998dec7302cde829076e6cf69df23aa0bf6bbb39fc0d3d8b5eafba74efb928b1de0eeb3d86ec82612300000000000000000000000000000000011f47e9583997b19c36616e4bf78d6ddd6d67937f493986250ff02aef6e6e7ff074559af2f20a5bf1d67158e4a199cdb000000000000000000000000000000000007777c8eb259a836e6459b7bdb642f878d869fdcb31b105d01f280938ef5377f2775874c099dcd394abe70f17d595b000000000000000000000000000000001607379d1cd34e2d0ed765a339b21433e9aa489609b92414c6b5a05d796085269c288d739717def9db3502e055086016000000000000000000000000000000000224cbea61c5136987d8dbc8deafa78ae002255c031bb54335bcf99e56a57768aa127506fca1761e8b835e67e88bb4dd0000000000000000000000000000000018cbf072b544df760c051d394ff68ad2dd5a8c731377fa2a5f61e61481ad5b42645704a2d083c7d45ed4774e5448141e000000000000000000000000000000000740b8b7d7bce78a51809713656c94cf98de72887676050f65f74c57cbe574278dd3634c44e057ea95babcc3d230e3c40000000000000000000000000000000006696058a191c7012a4ee7c973c2005ac51af02a85cbb60e3164809a583b4431dda2b59e1c9ceeb652b3ac7021d116a6", "Expected": "000000000000000000000000000000000a66f36f2437db57473bd8b7670994f1cfeb8b43c0ceae358e63a5e4e52b737fce6b3d24cc4de593bcd44c63f2c5935900000000000000000000000000000000070b7ad970f03a38c8a31452cf11422159cd3331d746031781a5861e26f54efbaba63dcb1db8bab997eada9c3dac39cc000000000000000000000000000000000ba4a9d7350adca1ae64e722df11baeea77c5fb75c5b52c8c46b9d863a70bfed1ec47888e907213f4ed4dcaedd37f20f0000000000000000000000000000000008a64244f1870a1dbcc4bd4d5c9eb5cd5225713dc73aa22bc46b1cea36c88a66f85251a8a9ba7279c88bd5dd37a06f7b", "Name": "matter_g2_add_28", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d6e3068c082b68312141aa68f1540ea1415e93e7f1762b6f06ff408a9995542da1c727a13355c19f8f418a44de1a95d000000000000000000000000000000000dcfcf2ab12b1a0e521ab402aaa4d32ff649a5a97892eb6ad98487c3c73c35601c313b8130ad12e9098d16eed3bcc2e00000000000000000000000000000000013777b1eefa4af03dc44e4e054eb7a3a980a9c55644900b80346be84b970e1754d1f4ab771adc9249e4accf88a23fb400000000000000000000000000000000002f53b231f1209c6f8b52f99a78bc2147c951ac89b341495f4a60a6572985ce2bc823625099ec214bc9ceedb2deea3ff000000000000000000000000000000001522e0a4ccd607f117fc6fc8f9abcd704e9850d96adb95d9bfaab210b76bfb2c5dc75163b922bd7a886541250bc1d8630000000000000000000000000000000018a6e4327d633108a292a51abed43e95230e951e4476dc385ceea9c72ed528bf3e06c42d10cefbd4aa75b134936e4747000000000000000000000000000000001198587188e793ad2ec2fa0fa1d0da9b61ed48444fe6722e523aeac270f17f73f56b1e726ab811bb54a6e42e506d70a20000000000000000000000000000000004bedd94182e0f16c71223ac3d68ab327d28ee0ccdcd2c2db07faf69e1babe3fbf3ba09c28b146eca7ab047b59294703", "Expected": "00000000000000000000000000000000079f89f2defd1f97efe0ba1db28523abc88cdf66efd39918a600a07c5ed5b72ab9d3354a172735e7749b5f6814a48f4f0000000000000000000000000000000009e361b8609be8057e5b3c99eaa1727fdac17edc59239af17f55d72c8b8daa89726f4ae240c742ec4b02fbd89d45c46400000000000000000000000000000000121b475a2ab50357ce80fe01fc461195029de20f61474b0773d80434253adfc268a775e1a0e3b7df5e85d1ff8c5008960000000000000000000000000000000019a76aef4e04136b1ad0d03586a3d8608ac4573715f18d5fd6907d03e5fec7c5659e15c19fd87f242da972b651dff5fa", "Name": "matter_g2_add_29", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000161c595d151a765c7dee03c9210414cdffab84b9078b4b98f9df09be5ec299b8f6322c692214f00ede97958f235c352b00000000000000000000000000000000106883e0937cb869e579b513bde8f61020fcf26be38f8b98eae3885cedec2e028970415fc653cf10e64727b7f6232e06000000000000000000000000000000000f351a82b733af31af453904874b7ca6252957a1ab51ec7f7b6fff85bbf3331f870a7e72a81594a9930859237e7a154d0000000000000000000000000000000012fcf20d1750901f2cfed64fd362f010ee64fafe9ddab406cc352b65829b929881a50514d53247d1cca7d6995d0bc9b200000000000000000000000000000000148b7dfc21521d79ff817c7a0305f1048851e283be13c07d5c04d28b571d48172838399ba539529e8d037ffd1f7295580000000000000000000000000000000003015abea326c15098f5205a8b2d3cd74d72dac59d60671ca6ef8c9c714ea61ffdacd46d1024b5b4f7e6b3b569fabaf20000000000000000000000000000000011f0c512fe7dc2dd8abdc1d22c2ecd2e7d1b84f8950ab90fc93bf54badf7bb9a9bad8c355d52a5efb110dca891e4cc3d0000000000000000000000000000000019774010814d1d94caf3ecda3ef4f5c5986e966eaf187c32a8a5a4a59452af0849690cf71338193f2d8435819160bcfb", "Expected": "000000000000000000000000000000000383ab7a17cc57e239e874af3f1aaabba0e64625b848676712f05f56132dbbd1cadfabeb3fe1f461daba3f1720057ddd00000000000000000000000000000000096967e9b3747f1b8e344535eaa0c51e70bc77412bfaa2a7ce76f11f570c9febb8f4227316866a416a50436d098e6f9a000000000000000000000000000000001079452b7519a7b090d668d54c266335b1cdd1080ed867dd17a2476b11c2617da829bf740e51cb7dfd60d73ed02c0c6700000000000000000000000000000000015fc3a972e05cbd9014882cfe6f2f16d0291c403bf28b05056ac625e4f71dfb1295c85d73145ef554614e6eb2d5bf02", "Name": "matter_g2_add_30", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000047f92d6306bed1cb840f58fd57b5b71a5df7f86dbfa55a36636cb495e08715cd57f2f3e7cd99a1efc28b1d684de1cb0000000000000000000000000000000000f4eb02d687a1a6105b4dbd740e2c7924689d558e6cbfee768dd303cc8dd0fd887f5eec24b54feccf00f473ca3f54ad000000000000000000000000000000000edad68c4d536912816cf6ef039c3dd0535dc52189583270b3b038e2c67b213d943bf384ce69c4a9dc526d7ef309f25a0000000000000000000000000000000006ff4a6b5129ef026d1d5704bf7fc0b474de92b5cf39722f165e73f4e7612d6d3bb40743e4b7b42d0dad5d5d6a2d4881000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c053345501324233", "Expected": "0000000000000000000000000000000013f8cdab447ef9be450b87f941c96d4e93d5efd811d80c6a910965728f7dc496dec132f3fbeee5d1e84ed7c24ca9c2a8000000000000000000000000000000001537d5caa13ddfac93f0f86729c743d9a68175a78c730528b581fb54b1f4d020473b3b766e3882a485ce5d02ab381c33000000000000000000000000000000000b370903684ede24f3df80e3834ed414a765cdbad98f20c49bef8663a82a468d3911d6bbcdc021e22c252e83a857e55800000000000000000000000000000000100cc8d05f071904753776c6092a38db84c5de751bf93216131a0f9a50bf78a722344a14b3be2a9207568d1f669d208d", "Name": "matter_g2_add_31", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b32e613cb38b41dcdf3c8bb9187d731546977fbffd79fa7f66e3d6aaf9e1af6eca2fcdc260c8f90818d7148ba2f4960000000000000000000000000000000007e4d26606a47c874c20e8480a9f5815e5b577bccd783b775d10309eeb3d2102c7a0abc3324679e44362f09e7a4ada67000000000000000000000000000000000cb6f12ac8b49cfa36b957591293c87b21af0a949c55a28a90ab0fce88fb5cb7645e20ab2edd284f0ad1377dd95ac10e0000000000000000000000000000000014c96b5dcbd3150eeaea5c2bc27750cf88b30a91933a3233a4d1d9b357a80cc20d135e43a344e718dff5c79045c31f860000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce", "Expected": "0000000000000000000000000000000003c5498b8c2d4765a270254dc927c6edf02acf0759540ddad951ea8c097bddb949ea0bf19942accd615bef21e8572dff0000000000000000000000000000000004c17bb648909bdddab4dd86560cb6b341e96f58c515ce471281f226181bded16b358b56d72e363f9ec491b8a9dcd92c000000000000000000000000000000001828973958204f8ab8cd13f5af5f3529f368a149bfe931a8002b61a61895457fbcb0cc6874631bb55799c884b998d8b9000000000000000000000000000000000f61460bf61bbf3ce38917850bfd3cece1e3955ce29d200c6f8aa89076c70919c02668678edc0bcf94efc9e9ff6a650e", "Name": "matter_g2_add_32", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001ca1141ba9542c56de8991b313c6ae42fcecb6751b0b81b8cb21ed70d5008f7ffe831766b89880a7fa6dfdb09a2cda3000000000000000000000000000000000e6766b17db165bba564ac63ab88d3f8f5eded07a40b48644e60d3223d30458e7dabe404cab8d6f9fe135712ef0b1a43000000000000000000000000000000000dda3e6c87382fa762510e5cac721fd2b654f002f5b9a3767a8c6d651ccc582e80e3f68d6913cda30f9f51ebcfc7c98600000000000000000000000000000000059a7dac5bb6b504f2bd603d486700fe22c14f25254537b2c9079c2b45d36c7ce56854c5699cc7649b533194f51a9045000000000000000000000000000000001755d8a095e087ca66f8a118e0d2c7d5e4d8427dda8fe3049080f4aff12a8746f8c2679c310f4be0d94c5bef0414a7a600000000000000000000000000000000069c84c6419ed5c0441975ee8410065a56c65f07a4b545ff596b657dc4620c7405fd4d092b281e272773d2281a6359a8000000000000000000000000000000000e751ccbd475fe7eda1c62df626c1d37e8ae6853cc9b2109beef3e8c6f26d41a5e4e0a91bbc3371c7ab6ba780b5db41600000000000000000000000000000000184097644c9b44d543ebc0934825610590cc9f8b17ed08e9c06592bf85591d2702b18cf48a70b378926057e541eb8ac5", "Expected": "0000000000000000000000000000000002c6104b3494fdef86d53f87bea68d313188c0908b935fb3b9f636ccd401c6e9cbd33bfcdd437e1a0150d0e4b9c3a881000000000000000000000000000000000bdc88396f807d1ba8d4d6e284d008b5e40445ce32c23a0178824fdbb6db3c5aede7687eaa2f12249125cded57052ad2000000000000000000000000000000000c7004365c1d3027997b55bd258dfc61ae07a762666fba2a14aa2ca116673fc03a6f694c069f53cd915fef6d37513101000000000000000000000000000000000ec17688d8f53e2c92502091c859cef4fe9a57ae984cb1e72686bf1f0656b10246293cae4b96214a38dc76cf2709bd59", "Name": "matter_g2_add_33", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000090f4b85961ce97cf7f99c342d3627105d790f611e19721a43d8a0febd67ae393d77a02b999108efb56f0397dac22703000000000000000000000000000000001112f23595d1613c47486eadc37f9b1ac3b3c3973b3fe964d3b67c3996fe2eacd9df5c287b0cea8e9475d146fabcf9e70000000000000000000000000000000018f46f7ba3c9af34c1025c2d460f0be966e68944928dbd55cc7fe00e5def598d80b0e3801e48a74963c974ab4727a52100000000000000000000000000000000096845338d5cd2ac44e097607d6a1a05c241eda1941991ae9edbba965d9029032c46da7218b5b2338e6c58898bc4a820000000000000000000000000000000000213e5d2d46523203ae07f36fdeb6c304fb86f552fb9adb566711c31262629efb0b1561585f85d2ac7be174682229bd8000000000000000000000000000000000b3336b5a4f7c0d16db9615e77bcdd55b7cb5b5c1591d835f34f5c1f1468e3cef954608667fb97a32e4595f43b845612000000000000000000000000000000001869606dde1688e5ae9f1c466c5897fce7794f3735234b5af1ad3617f0688529499bbdc9f0b911840a3d99fd9c49150d00000000000000000000000000000000001bfd33df4a6059608ada794e03d7456e78317145eb4d5677c00d482ac4cf470053d33583cf602feb67b6f972c99739", "Expected": "000000000000000000000000000000000a44e6a48ea0a95667f607ee66290cb0094c964baed779bd6656941db28e30a7e9effe49a617be9ab376af4f535cc28f000000000000000000000000000000001933b87310bf5fa60b1abcd13bb7ac3f2ec0a278f6a0a70c953a2905ac1d3bc5a70cf1da885af45d1c7680bb4f7ff74c000000000000000000000000000000000597ce9f1bf7efacdcb0250427d0341e142226aaea060983175ea149912c5c4f3019fe87be6d87d186a8f562fc3059eb00000000000000000000000000000000198b5a891722a237a5e23e3004798c8d3f069af3267152508e283b4549fc5e8388330343f80e606eba30af51c99c7020", "Name": "matter_g2_add_34", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aafe45ea7cb8b450a51263eebc28c1ded662972bee512e24fddaf64f43b74b66032523b3b104a4e9f6b62394436c6710000000000000000000000000000000015cb27e1fedfba2d1679f78a388f90b22bbf3e7d090f0ba972fa8e72f6e31c446f628fff929953712ef6e425d16eba5c000000000000000000000000000000000df9931893cae713042bf722db6ce394b6f346587278a154c271d8511e690417eb6dc47efbcebb7c2fb9e77f1de9fde800000000000000000000000000000000106ffa395ef170c99bb5742428ae88fa4fd7a94476985c099e3b700b7403d083281fb71a19640c6bc2321e27bcb33fe20000000000000000000000000000000004ac6e6077d4eddd0e23f30cfd64b7aa1525c85424224e70c15d7535e02aea7a312ef24ba2dcf70b926acb851da2530c0000000000000000000000000000000006ad07d3e8f45cedfb4279913bf0a29e37604810463d6020b4fa8c8c4977d69cffaa33e1149706f04eb237194dcafa520000000000000000000000000000000002c536dd2f05f4a7eaa33fd884262b22a2ab2a88e7b63cb08ebb67fc0f143da7d6b18dd394c424161f7cf703acdc82f50000000000000000000000000000000002d1d9ff74e20ea9b03c478784f57e7a58a21ca2b1e552319f33305f367f5ae4daf8138505f953db4f86c0ec1d96d5f0", "Expected": "00000000000000000000000000000000047c2ccda315b9c013e87bc9168b3b8dd6d463403f1cefd824fa9f93a99f4c4f98fac5f97e4237f76b1ec91042f99bd600000000000000000000000000000000036861fd0a69cbc851741475905441b51af12c5b2aaee6ce9a27a01a43db810be9c7d6fa401406e98e327703404b83a5000000000000000000000000000000000310cbdf53f6cf8d87e2d178869bee4359a8dd666986d869761a79963680a33ea3ecefd40a1e558acae5ded2ca04447300000000000000000000000000000000108bbb28c73ed7e76a51a78e4d15a2c88c25e05c7127ae89d4347cda00be231b5e70e0b0562caddd4a7083efa4516722", "Name": "matter_g2_add_35", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010b1f8b1c492a56936da905b8738affba6bd29ae5fffd40ba6b31325181d3b489a81b23dcb69f6e71bd29bfb388e5a8f00000000000000000000000000000000116a115303b4774da59844e457844232d088062d920db67b2a8450a194be7e5340ebd4d106454fd9a03c8f50dbb1e119000000000000000000000000000000000eb521edd61b38006cffc43ab72d395d669dec196846fa4d6d43521da6c2fc3bf0994ce7556a3cffec7751b3bc5703ff00000000000000000000000000000000073cea36eccaa1c78deefb6029903c2b6598301bdefa9759719c3b590fcc5a6a4d3d4d19f552b33f4a3126a6e6a84486000000000000000000000000000000001913ce14bcd1d7bbb47f8efd92d7ffd155ed1990a1dbf1ee7d5e6d592a92bcbec6e865199362950afd6c8fc49b3e10a400000000000000000000000000000000020df729079e76cf06f84e3355e683e093dafad38c2ba92cf7a9faa0515f2f44d814f971046ea20116cc4b0014d7ec350000000000000000000000000000000018db123e05404eea8707f9356f417c3966312b9e41765a6fd8449879ddc4c9850c38434481b235a5bc35db1b8ee86d43000000000000000000000000000000000b4162715717e9065a3849a9294cfe39b351e57ab5a6790f3e725ad9fbf0e4b9d6a3554e872af9c37df33bb896dada5c", "Expected": "00000000000000000000000000000000137d23ed3fa0d7e5928af8d1f4bdfdef08e0b4c0f3bf6f51ed28960ce9805eb8fb254233bb18cbfecbadba95e112fdb80000000000000000000000000000000018615147d7a8cce1dfed6de25cf2fb52f54a243bed4913e20e66673f47ecddad9c5e4ff9653f522180de4b90ddb3ad17000000000000000000000000000000001521f12116b13f785b5211aaf438aa6668bbfa318cf0ed6d91aae963f6f00d32cc5f25d3a02bd902ccc25f847ee2db830000000000000000000000000000000014263b23396f4facdacf13c79864157823db724350bc640abf8fb6d62663cec1069eef9db56817660510e2417b51c616", "Name": "matter_g2_add_36", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e3925fa085db73c1e67b29ae90f8773f83be5ec684402e8e2360ffee8a8368911e584843e42b0d470de78591df6ea6300000000000000000000000000000000075c7efdeeb16609b4a47ea442af4d75238fb7534fd96cb236a7886809d6adc2b62c8ff72bdb041bc51c1a71b68219e300000000000000000000000000000000088b4eb0dd185e51b737d797334590e982b7b0a5f109fc7d0524b2465c2c0457964eba5a6d2d4d99fb628f21f15a776c000000000000000000000000000000000fc79f6b38f3356972669290eeadcd992a22bc1191606b663a1e148aa58db3938f0fc65e536bc5811c50d9c7f03d3e370000000000000000000000000000000008be924b49e05c45419e328340f1cbcdd3350bacf832a372417d8331c942df200493a3f7f2e46ad2cdaf3544cfd8cd8600000000000000000000000000000000028cd100457f4e930fc0f55996a6b588c5361816bb853d1f522806e5ec1c455eb200343476feeb07ca77e961fc2adc1f000000000000000000000000000000000f6adad0a3bab3610165be2fadb1b020f25488a0af3d418b7d7cf1165812e17aefcbc23308ebcd31d22ba4ca5773dd87000000000000000000000000000000001657ff792e3d89d5d35767bd0cc788411b0420665a5e0704f4d2399b9d9a5ad3c027ee030fdf495e5a6e2a4c69d05712", "Expected": "000000000000000000000000000000000038f9df6c14f84b8ef8045010c8973e5c2f8d2e37268f6a674298de7b15cae82361ebbfaa00ea1cb2653c5d00886b45000000000000000000000000000000001376f7e2d5621aa9d6f7ce45ed11de7e0e1095ebeea976f78eb83189c6852ee199840c14059c233bc3d40efbeeb5eb36000000000000000000000000000000000c7b0e53adf4f0fc5172f903e3fc479539348241edc3e277f30ae6b4fc419aadcfb73a8f8a09a1ae1dd885a6250de0040000000000000000000000000000000007a00b57ecc8b056436ecacd7e0fd346b906b15042e9a700f54f8c3b1d251c566e0c55bd34f7a9e30f1566b7f2ab16dd", "Name": "matter_g2_add_37", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b87c47605fc060a8e3677e84ce9d14b9309360a13c80d040c625fbf0108f829300cc1fca409a0f9c96311cd4a9a21e60000000000000000000000000000000014c4088f1e7935cf6a1d2475b84497ce6a250ee2c0c991fe51a2f2836388a354824b02d9cf215328dfce3f546713e21100000000000000000000000000000000120e59be3ecf35674eac6cdc559599b273f13f28a529770fa156f8e519734c451eefb35023639f32049cd19ea0d945a3000000000000000000000000000000000f97755b62a8cb8f861ea02c77819f0b58181aecf612d92180ba9b475f0b4888b922c57f6a1c619dd5514620a1cfd9e2000000000000000000000000000000000a5048d860b997a9fb352e58284ebbc026622d9be73de79b2807a0c9b431f41f379c255a2db0dd67413c18217cb21b7200000000000000000000000000000000045a701a3f46ca801c02a5419c836b2ab3d74ebd6f4fd1e7dddb1965b49c9a278f6e89950e7c35ebc6724569d34e364c0000000000000000000000000000000004cb55008ccb5b2b8ece69fac7283f5a9ef9e622e2a0e42bed5bdd77faa550882643afc1759b1a327c4f2277e13a3d4f000000000000000000000000000000001690dee40c6c824dc2588fc47dbf93f68ac250b9357e1112db72ded905ed7b101b5f877bdc42d56afb5b6202403a91c4", "Expected": "0000000000000000000000000000000012662e19e41bfacc0c792f5183596bc7f1986f9bea72c626e187d72111b6ef3f36f5afeeb640cfda99b7044c0d0b846900000000000000000000000000000000050ba08e1b9fe95dc67e6ee1ce60664b291c80fdb59729cdea75dfd18f22fb88f837b439fd119c46c996787d3008194b0000000000000000000000000000000004ea0f488fece967675abdd3c42f8fec25b547cfc45d42fba14bbc55ad7e1a75296a679113d0671cef0aec0c2165f4a0000000000000000000000000000000000f617f51800b09150a7560505079c785ab45cea4705992fc0325edaf4ceb30e1f0bec35a31898db5f810685e55634076", "Name": "matter_g2_add_38", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005860cfb6be6720118623d2d8ba05e686df22744b948421dd3cc1b1691e00d9b5d00d00195b4acf7a7b043f764f3f1c70000000000000000000000000000000012632a3313dd611e8d969bddd556c2d79ff387603462ac78ded3a842981697bdac34ee6f1f4744ed2ff16100874ac24000000000000000000000000000000000112b94c317586e343acadeca611c485c3ea172bc10dd39158c1e678007130062a921b53826d7be6286963ff822f1066c00000000000000000000000000000000040de8c0dadd2a6c2a7ea0fa43e1a5f2f5a6be3fcb0de6875d8cef1ee2daad87125d12f6869c4dd3d931b296f1df2fb300000000000000000000000000000000153cec9690a6420a10e5a5a8ca46fd9d9f90e2a139886a07b375eeecce9083a5f5418e6baf64ef0f34176e432bc5343a000000000000000000000000000000000d87c1f37f83ae78a51af9c420e2584a64337d2d2dd8dc3b64f252c521901924e5eec1d9899594db5e64c93c7a01ef020000000000000000000000000000000017078538092ace26cc88b94360871fc9a6bb9992172158ef3a16467919955083accf8d55d48c7ec462a743dbbca7b448000000000000000000000000000000000289b703157a02fc1d687a5aa595495be8bbb3eb0d70554728255a44b7820e0ee82d984d5493c800f1d9d8ca0c9381dc", "Expected": "0000000000000000000000000000000019c774e968049bde2188e844c3413203bfe2c4355edc8cbc2cf6f977c34c0a42a206194e6eecba3c97b24558048f3aa700000000000000000000000000000000081ccf6f111575a946341759b9faa13f3608998fbf4ea3b547804737e30fc7e33495caaf2aa328b19bd48315c5c7f9e2000000000000000000000000000000000a4098536041cfb808176c7cd8e980eda613a2b390e8d63d607caaac26db02fccad6d87412b90cb4b3e186bf9ccd31be000000000000000000000000000000000d3c784c6587b9f786c06099a62aa639f40535b512ac2440912f04dfcd1cb5851b7378f381fcdf02d4e58312eb7e442f", "Name": "matter_g2_add_39", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006fcd2c4fe848e9462ba1112baad39031c210952adbdd06293a622ffe2d1c6e4fcc8773ec8913717018b97bcb9a554fd00000000000000000000000000000000130a97442f3273b7b35464545e7351faf71ead9b8996c63889a45945ed82bba29bff5014776c6185219a5234d8475c92000000000000000000000000000000000491d571bac5487b866022a0714be11b38bfb296233845cc434a50be1d35f516b8c6b046fe3d0a8f4f95ac20eddea01b0000000000000000000000000000000017e34b04e6fdf152c848f2432b7bd84b3dba3915f06eb77efb8035750aca9d89e92e1d1bc4871105c440d639e8d8b05500000000000000000000000000000000057f975064a29ba6ad20d6e6d97a15bd314d6cd419948d974a16923d52b38b9203f95937a0a0493a693099e4fa17ea540000000000000000000000000000000014396ce4abfc32945a6b2b0eb4896a6b19a041d4eae320ba18507ec3828964e56719fffaa47e57ea4a2e3bd1a149b6b600000000000000000000000000000000048b3e4ba3e2d1e0dbf5955101cf038dc22e87b0855a57b631ef119d1bd19d56c38a1d72376284c8598e866b6dba37530000000000000000000000000000000007c0b98cda33be53cf4ef29d0500ff5e7a3c2df6f83dfc1c36211d7f9c696b77dfa6571169cf7935d2fb5a6463cceac6", "Expected": "0000000000000000000000000000000016fc7c743c5ba747640a6494fb3c30caad5a1e9719a1994d0ca73bd1645fec118a2887acc8876d105102241c10274cd300000000000000000000000000000000058a42a0095a7388fba7ce71dbef4ecfd2018c3fcdde14afd2be26588de4689d8de757e1e3ff22645fb8c17aa60265850000000000000000000000000000000010bb622f649e346834b95e82f93ae83c71c0a65df7842c4ba88df7f6eccb0217ca9377167a6d14777e0474c24821f8d70000000000000000000000000000000010c180c685ea3d0146eb82c007fec3efd129880f18f838f1cd2f80181f5a4884d6b5cc8247430fb0c1701a57f9d1d485", "Name": "matter_g2_add_40", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f1b8df4e8fdfe32eaf227f5af9f2befc85073468f10b81d32d0e126fe2b0cc8e8adb8afcac73213b6ed95e8e843b97c00000000000000000000000000000000004e3fb435ae0fb2d8bd091f250aefe5922b353a64e16abd75627737f3bc56639f8b40652cae69c73ff1969925b0afdf000000000000000000000000000000001003aed7cfb00efce49d6b1a8eba27df87479a4d37bd7fda6121549483b669a1a761204b0dd28262bf27e5c8e180540f00000000000000000000000000000000114fbca7caf782b3296d0b26b4c362bf50acaecb8bc5726b2c99f904ec3d092d5d40991d0d30c8e79fddaa45f04a75d3000000000000000000000000000000000b6069a2c375471d34029d2a776e56b86b0210c35d3eb530bf116205b70995e4929fc90349a7db057168dbe6c39857970000000000000000000000000000000014251a0a154731f73513b99d830f70b6fc4bcf05d11f52d2cbe9795ee8ffc5a5f717ad25770b8ecad6d0e9f8066e0cba000000000000000000000000000000001172684b21c4dfe02a55e13b57bbf105c954daec849d4c6df5276b02872c004fdf09d24f4eef366bc82eb72fe91bf70d000000000000000000000000000000001151aeb9441c5a8fabe80867b5c791420645241eae1400bbcc064d75bedd39de2ef585138fe9f65725efa1b1e5888d03", "Expected": "0000000000000000000000000000000019419b635c3742cecffee02ee7e2b1f18ee9ff15e647ca0abc4398ddc421ae7e0444e3c1ec377def9e832d8e64fd40e2000000000000000000000000000000000d9b4abfdaf3b4c7bf00fa07579befa10a3418d8fa0f3a9c31e59ae48b0de50fc8e6d583aaa4d0fe6048bdd1a9c60eb60000000000000000000000000000000003c96d57034ec97c4abef1c2c81f4d4b0f4b6eb1e9dc5464bcab28572555b9b874df80325941501c3766fd7e06bfe7360000000000000000000000000000000002dbb3d72385b562ddcb9a80400ab3770f00d22b880cce2fce1641042b9da669b22b2fbc97617648c25ab644e661e2fe", "Name": "matter_g2_add_41", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017faf481fd4cb0c373d21d7caad40e93d9a86e62d26136892fbcc6f6e48205543aff00c45e82fdd1d3e0e733de91e7000000000000000000000000000000000012e14fcb9ad4d9d15347cf004745ed4bd92097eeeb41c4cbcb728a234616363589d8f5ad4cbb61d31a8aa27627723c7e000000000000000000000000000000001513dad1ff27e053902e779e35d04cab648939317830144ea775c435a4b55e13fa2fef03a1256abf5c187487c25a774f00000000000000000000000000000000139da29de8587c7d0ca9237c37a116387385e9cea453b9e2003a37ede7aa0a3f4c1df55255897f5975b662be33622dbc00000000000000000000000000000000161b70d0f384e589d8117938602f3d696f941c24e3c1ca5a9be090b670456c9df315d6fde52daed55c9d8335928a7a3c00000000000000000000000000000000186bb9e6f5ba70dd2c66a641d3b711844977939904c59946d4e9f49ac2d8c00890a43ccb20d4a62bfff63ce4a0a44e8e000000000000000000000000000000001995b9d697bded656236430e78726f0f6ef963db9a5a24d455c12db38aeab0f8629e5dc2d04920156f2a057d69613096000000000000000000000000000000001119b13caf82c18fadcb65c9c166914bfd822534bb9def3feae6c9e572c97c84e97fab3b345cf59358436a404075493d", "Expected": "000000000000000000000000000000000d32b00154a5fe75c576c098419744ac36b911ee800f94bd598ff9b6adcaa39c836bc158c5d6af72c9e715a242d0fe710000000000000000000000000000000006e057c13885d6c05f5d92061fdc4d532f10d31d472c371e71367fef7c5fdd3741e665321d1119b895660fba3770431b000000000000000000000000000000000bfe695c3364e15479741e974f838649e789a76d073e552aaa60981fbc6d185eb7b297fd59e51535965214a02f5cd67e0000000000000000000000000000000014f0a27412248e3163e5f82fed02a25d953b336b0201692f08a3e8e9a9d223b736c70c1a39826a0888fb02a314e223fd", "Name": "matter_g2_add_42", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c118b147ee3489f30c6ecc0256a314ab674110588e8b69ca6d265fc270c3e5b767817f861140cca5d7c6be4012d1ffe0000000000000000000000000000000014800790654726959fd876b035bade0da744fb36ee5b304f228663a531345120267c55ac19fd66022752010e5bea7cb30000000000000000000000000000000000193ab7ac2f151750356b6e178557460c9c2672b1736d19a20e3fa28082479ca60021aa68edf2524f1aa826ee70b65a0000000000000000000000000000000015cee9ac55ab45abbc57d0ea6ec9ee49f6c59f6b94f99589dbc08ee877d3a261ad77f5473fedd72ed7206647eeafb6ea0000000000000000000000000000000017d1ffcad218efd8b09c68eba34dbbc30b0a62ae250368ee37e5f6fd40479b8580563416afdbd92c0622c341331e20a30000000000000000000000000000000009f0eb3805ed78aa3952a0a437966258ed38cb72912756253a7a2f9113f0dd9a4e187062b0423e0587d93e904d88f50d0000000000000000000000000000000001bca57e985906695e14882f2aaeef75de5009e8717eb59962e978aa11e9d0a4d9a9e203df774cb1e993b1c6ecd6048c000000000000000000000000000000000695b11cc32740c91546eb7d554ca8b1f3afc942ad977345031be8b94b78b57a87ab049ca2d3676e039efccbf24d0c47", "Expected": "000000000000000000000000000000001566022247ce012b7de92c8495876b4de91c36448f4f7e00f6e154185d38a735e701dda989ae9e37d332a5e60af5d06b00000000000000000000000000000000065aa42560df7990df2098827a55ceaabf3ec592c53d2f20e5dddc1481ee64381accbc8e58601428d33589b3af78a4b70000000000000000000000000000000002d9b0cf8bfd1adf76bca80ca351a4340f02434090518807e07ed76440497042f13a0cd7a9c30086872d6f145808fb290000000000000000000000000000000015daaa131431e3e78a6221091640811fcf88c835ac975a041a7ab50bc1d06b80e6a3c9ae77d2390fd14cc9bb009b47cc", "Name": "matter_g2_add_43", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ef203fab794a0ef29eb2ebf00076134e5932e27c99d6d445695b9df2afe7563602e318caf5d44724a21790ca0ab0d180000000000000000000000000000000013b9b1b1d3e98b61b0f1a0ef3a1a4ceed57b6c01849a4ad66a86332b3d27022cfccadd3567e6709d2de5b23b23dba43f000000000000000000000000000000000c1fbace49684f4be32ef6178ac3a95ea3f50b11494340fb73dc5391d50bcacafb3bf0f2631fea9c4ec47327d644489500000000000000000000000000000000040f82812855aa3e3aaba826d5810c1049cf44e86e44e23cc6da437971b529d2f2676c73e1fb9da52640c981fbd710be000000000000000000000000000000000546a0cb9d9f1ef9ec4a1e576fa0047557a56c0217baed8691c4085b88c84a0e12d44043aab8671393d02c4a764407ee00000000000000000000000000000000131884c1386980a181353548da9602db70ab495a661e76235c4b0a32b54acb0dfd8846e17bebd731e8041c4aebb8776600000000000000000000000000000000135b3db43511dbd8b3bd5a91880d6da1a2bd1383000e0d6f0a521bf88a5836a3b5f7cb9c0c02aa861a1c2d339f3c11f20000000000000000000000000000000000e1337271bd3302a1cab762161ccfbf2a18b7800e6efe58cf897d4adbfe4cb3bf14f4b59307fffc548179bda70c18bf", "Expected": "000000000000000000000000000000001290bff629c93d992ad2cc709317c48980b0e56a32fe239258c7aec75e4523e0bc0b81319e100d10568a44847869a8d000000000000000000000000000000000055d9098e08eabdf2b883df35efebec9f6afb16d651ebaca1067e2129146268664ec51c8a4f28f13a250f3e9883053780000000000000000000000000000000002424dab6f0d18ea8bdded2a72bcf87c13307d27d53e8ec35e91eeab97fcf3398135fd436c530c609fd47a3508472bad000000000000000000000000000000000b25d0db1e28b98d4f9d3c77c0b71489c51186105d93be7fc2cf8c72b8abd8959340114635e705e698b0f257855ea4bc", "Name": "matter_g2_add_44", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000060d7a718dd02b147c265f71eb136d1f31781b12a41866b4f86d7374b93dd10058c192cc0fba928373b1526e1a5d7d7f000000000000000000000000000000000cf29275373c0573ef22bf87919faf5444847203c7dc6d2e18986152cc294be04a5b1a4b0536797158113a15276c4fc6000000000000000000000000000000001016d5b9d4d200d7b4b7cc3836b85d6697fe14db350badba9978c7b56983dd1a7e572640ee0372b0a4e2079ff4c1abf2000000000000000000000000000000000f2768d104d895473ddf8c6b3cd0e7c22458d0037eca6365c766879a07c95037ee0de00d32c974d767080935abbe0be100000000000000000000000000000000113dc3354146ca79eb103b31b61fe8bc6f33dcb9c59a7c39d989bd9411c1afce4239034f84e6b00a084be061c73e69c0000000000000000000000000000000000ae33bf68f24978c7ea9fc58d8d76047ec45d01fdbc880e6a5ba02a22a49a3a8253afe0678ecfa6013f4849da3401df70000000000000000000000000000000012c5b00376a1dd31378ec44f2dc8e321e17185d903cfc5c15345a01c33f2f151b21b938d31816550594a7a1e7216c5b00000000000000000000000000000000013d79f825c44775c68e90932d0496a5cae53f04a1edb19f8abeb5948a3dd325dfec4a8b6f58c7fbca9cf3c09b909d8b2", "Expected": "000000000000000000000000000000000cb2998b4e634bc83b5585b0683b7b561f260eefb826719bdc3c95e8ae51f8f7b442d75d69e0f9228dacde2ce80ef4e60000000000000000000000000000000014d30d1c02122143868ea01b454a4f33432d875f8ba66e6bb1e02fc161bb5f9298e673339a9183a15759f8b94b519cad000000000000000000000000000000001068bf3c768e8c9e9058805050394ea820b5f60bea6d271f8e1fb665d3b7931ab0cc03dff4cbd24577b2c254a956e8200000000000000000000000000000000008b7f4148bd1f4926d2a84497b60a48701057ea08855bb9a2f838d2464e66360a59d058d9072f1416023cc72045af558", "Name": "matter_g2_add_45", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b9ca4349fecaa43ce911c0b256680edb8a0906ef5460fc4d2004579336df1e19560fe960a7a7cd74bb6e8272e08960000000000000000000000000000000000d5b96dae738db59cc67a51c61bec6deaeefaaa51e3259243fa4b142ef59676231229ae386ce699fbe18c4c00bf9d49400000000000000000000000000000000111b79f4b68dad16550a13334d09dc38336a75a5da23a17b5064e2d591aa3dab4c2e982a9f730a7633070504663a24610000000000000000000000000000000018f6d3616a7eaf17c805a88c9710039644d01b61aefebf76717ddcda6f4bb34aa15702de1e92bdb27b27f3409638da900000000000000000000000000000000006ccaf6c08f831be9c99a97714f5257a985cc2a29b5f5c81bc8d794dd0d8d1a41eb5413bed654c0140dbacfd0dda9e1800000000000000000000000000000000144e9cf91580800dfaa47c98ff7d002a576be76d9e44ae1f8335a3f733e1162af0636372e143174d872c7ea89f4c743900000000000000000000000000000000101e143b838c8a3f5f80fb1412081091b875230f1e2f9cf374d4bcd595392f6daa9552dbb6d5834e27b1b3dafe061ed300000000000000000000000000000000072463400b3e875395a1cdd31d73d51396e34347cd86d9f6f43f42253b3cdb24b89ed7434b1522af95ba1ee2d29ed1bb", "Expected": "000000000000000000000000000000000a7843a1d67360b8a6976aeda2e4e98f1ea229a4d84b947dcf5ed8215173d5cf783920a7714f5b048778df30f01a0bed00000000000000000000000000000000035663ceafda9e5bfe934cff725b36b258f12afe749f907a560a06da4abf8380853f8de31adf14d62cdb310d8740e29b000000000000000000000000000000000f210d576aa5d4cdf5aefd8e55be099c422debc217ddf0151b8801f7d16456c97d1e134b40e6d71d296ee2518e50af9d000000000000000000000000000000000219efb35c68540c6bb0ef224e68dae6f7d48425c2908440072f5f63eec3c8e750b559c73e33464d0b5cdabb50fc4d3d", "Name": "matter_g2_add_46", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb8424000000000000000000000000000000001354146aa546754e10ada6e0fe98f04f5f3a3f8a8350d0295e02b8e9c80735b04c3061412e08ddb13c80ac36e5638e540000000000000000000000000000000012ab26513534b4dc1b71eec46b73199c4157ba9369e66fbe4d2d8f62237fc7c6fad31854ebd878f989b8c5cf35c7cfe0000000000000000000000000000000000eb731bc99cdadf7f2280385c7e17d72d34bcbdbdc725d5bc94e841036115e8cb95df08084221696f9be479821fbdd7400000000000000000000000000000000143ba7d3f66445249d9a81a6949f24ff40e7c4d270fa044a8b80200a4369b07806c5497a0ef9e9dbb87b9e63694623ee", "Expected": "000000000000000000000000000000000ce704e650605f747cbc0bc76e82de8569ba7b3d897eac2bf5f79aba17ef4c989731e959c0bc0b7988000a9b0aef39430000000000000000000000000000000003cd3f3d978d6c85d98812ea0e3d21149bf4151ad1bef966ced124ad62dc7cde55f16e8d08bb1ad54d3a23bb73795d8f0000000000000000000000000000000019d37a20fcf6244c2898b271535e3b8f279eaac5d8fb1ba142096da383488eba28a21d038d7a9d3f9e8a008d6d3ee1d20000000000000000000000000000000001ba9c1720a4ef07ec752efa1ddb629505b3586af415c916fb0ed2953cd8943d9343268f438db860f0bced3e690a66b0", "Name": "matter_g2_add_47", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d4f09acd5f362e0a516d4c13c5e2f504d9bd49fdfb6d8b7a7ab35a02c391c8112b03270d5d9eefe9b659dd27601d18f000000000000000000000000000000000fd489cb75945f3b5ebb1c0e326d59602934c8f78fe9294a8877e7aeb95de5addde0cb7ab53674df8b2cfbb036b30b9900000000000000000000000000000000055dbc4eca768714e098bbe9c71cf54b40f51c26e95808ee79225a87fb6fa1415178db47f02d856fea56a752d185f86b000000000000000000000000000000001239b7640f416eb6e921fe47f7501d504fadc190d9cf4e89ae2b717276739a2f4ee9f637c35e23c480df029fd8d247c70000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000068edef3169c58920509ed4e7069229bd8038a45d2ce5773451cc18b396d2838c9539ecb52298a27eebd714afacb907c0000000000000000000000000000000004c5346765a62f2d2e700aadccf747acb3322c250435ce2cf358c08f1e286427cabace052327c4b30135c8482c5c0eb9", "Expected": "00000000000000000000000000000000160d8b4bef36fc3d09af09dcc8357067c22e421f3811deea66faec42a2f00fa4aceca8725cf99062613126a9fd7bf7210000000000000000000000000000000004e8691a42c8f3ce0e7c0470446689e9d2b3cf57d55fad7387d624857f977cb9c6864c87bb4b6a2c17538478ac5fb5960000000000000000000000000000000015e20f6baef033efbd38081d5a10eeb3c67d89ebe5cd652110b778313c9e86cffb45231616d5b67e9ec8b7be15980aa9000000000000000000000000000000000af75dc221050256015fecc2bd8113b42afc9c624e5d28d7ff8312af499e34a603d66a4304f263729b440b6266538316", "Name": "matter_g2_add_48", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f20a07526a082e88630a0256d134a8a5e8ada07b1cead39ee838dcbb30904e9016107fcbdf1f8ba182308dbe0b043d20000000000000000000000000000000014fb7732f67abf60c03ac902577532d0acadb5f3db0d6397a42ba693526ad74f2c61a0195bdc9704aaaf12e65aa6d88b000000000000000000000000000000000018cec4fb81c85d304588d11f8b9c51f5a053df11463e5812a1b2e6c7144522ba36bb91adf219892d0007cee470032e000000000000000000000000000000000b8e52d958a12a9037e8be9bc0d5045cade2d6ea05c6e68462b3a30b5d4ea34e5fbad173761e4e216b2e6958c8983b28000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000f6fdc4e5dceb555c9eb4c912fedbfb3cb1b842345f73ded02cfaf8d397c4378809721094aa4a4113a368e0787effeb500000000000000000000000000000000143ac06258c579c11c05569669a2a10babc63ecc86f85c91791d8ea48af700a2067c5f13d2700b8d5cf59bcca8fbf7c6", "Expected": "0000000000000000000000000000000013edd8f016f6af49e9bc461ca14c438a32eaa3d1270a5acec99a666aba3f0a7e7eccea81720971cf4432bfa94cd18392000000000000000000000000000000000dbea5617e44c82da828844a5a4a1426d43422fd0158204a99f53cf9821f82f0bb0130a2123297a6941f695e172d9c5e0000000000000000000000000000000005f65a445e9f2d57dff2b210209f9faeb1c8b446454de4724d990aab20bd68362dd7ceb5b95de361c129855abba83f7e000000000000000000000000000000001219ecae79d62d3039e642369353993b1ece049331f06be256f06b01a1c3b0c617221c8d8f0bf4b6a0abe1191a3ee8e2", "Name": "matter_g2_add_49", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001468cb35a60898ed129f30c261b8431df6a154c250ec16d85a22f8717593b2c21853d123da86d977a7938c5ed74ef23500000000000000000000000000000000011f4e28e31b5f9e6877192a5e632d8c1ed7ca0c42e6e9902ca68f1c2de0f648c6064436012c5c7b14bb8d1078e02f2c000000000000000000000000000000000b25114b2697ca7eb1e6effdd1054893a188fd382d387ec098f846c1137a9b9baad01653b963a0b0bf3cb50c3ce3563d000000000000000000000000000000000c1d241cb03e642c1752b1e1886472477c19a2801ec032dc220c3243952f882094119bb92b621b654b766bc900d2d4f7000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc500000000000000000000000000000000192f3e8ae2588f9223de77f5e872115f1edec96d6a0f403a47879410c2562e79853c9a706e423b83fbf3154234edb6f80000000000000000000000000000000015084258d58fd1a07bbdb2e90df5a56ae15a787037eff4fe55f660e45f04820c6fc8982303b5e82074cf0cdcbde61307", "Expected": "00000000000000000000000000000000158da32df45fe3e9102010bfd7faf3fde936bb8e52f68262ef479ee825a0d7169ff753aa042883a5403103a9bdafd2be000000000000000000000000000000001800a5776a47f52d2af08144364a6cd7442a0e2fc214a2d8d285a29bb7bd3a0293e89f0a1856223a527100d0abf12899000000000000000000000000000000000a6079d18ff3367c47fa61a57a967b782f3529bee93f452ecebd4f5c404b3e1769c100da9b8aee4258b5191ae1dad9a90000000000000000000000000000000011d3188a927e8f13aecf7f8637be6ddbbce309393a94fef77923c286244f8531d3e137e031d8c1af829891425afd53a3", "Name": "matter_g2_add_50", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c80d4474390fa791ea5f2f16b41506d8ae13ee0993c8d31a07712687298ee7978a724999500c42400d2f788a5a36067000000000000000000000000000000000592705cc5a8875750a4e6ceb42aa3bef5593eda9e8212702a2e08ea70277a2a66526bc5237be33c8449301544da35e60000000000000000000000000000000000facabfbd15284c6433f17b0e6035d4fdd84d3ad2dd30a27d52809652ff6e7a684d7724697919100567ad0c3e1a26320000000000000000000000000000000006a0fc4e2af69ce15a356656f5d182a2cf213d76a6047a05a1a3375909d245f5316b91333d2141c0817438f0d87bb52d000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f000000000000000000000000000000000477b55bd7fff14e0d1807bfc21edb9481be01c12abb1460d78b1aafe42953730167e32e694c2ddfb0d442e8cea57d460000000000000000000000000000000004b884c6ea36f189dbc3c0e9cf88f08baf5d868579998f63b752e61fcce3cf2c901bb9b51959d3597c4ef53cff41fc26", "Expected": "0000000000000000000000000000000019294d87be784f0f8fa29de80d45a697bcb694b32f3f6d7641d4b08d8a7ebdad0ef78ba5ccafd6b7f240e1cbde019c51000000000000000000000000000000000645f7851644e1e7e255d0b3dca769b987ec3ff2c9eda42cab65dc39be2f9858c31f307d59f6a2caf9dd932d873d2b08000000000000000000000000000000000e8e93f39ce05a11d40f3b52262980c79ecc52939dd02b94df3e5034a57061d040b0c8894189f4626f37bee485712dd00000000000000000000000000000000001e0b7c9c3d7456b2c0ad842083e9ce2a00da91cb1aaba371ff4b9370f0f2c08f4b53b8e5a3030c99b2957cbe5f9e967", "Name": "matter_g2_add_51", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f629618e1fc3018bb836301ccdc59022f0a25cc9c5de6e4c31fa08feea525c83256235e4ec8364e77e5df478f5f62c000000000000000000000000000000001120d6af221ba6f4351bbee4c2c664a769adb17872646df2c408f70c99ea991ffced4eab50fa98be1bb9426915f125930000000000000000000000000000000015cd16b028ce3d58b10aeb84b783475d894ab3f0cfdf7104ebb4f3417a038107128f07518dce548271061cb8c97e88af0000000000000000000000000000000018379875b68bc26107f9a068e5034f29dc2ae7e8830f8e9ecddc53fe7991206646cda33d37b31a47a977b46be58d761800000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac800000000000000000000000000000000183b7b917aaaa94f0ea9959273ed4701102346be2a9d72531bd18fef908ecb0579a6ac10ed42a91f1147fc3a05b2e81900000000000000000000000000000000070983b1582a97d9797782e4f960a298aaa8ec509720495acdbf176d8ecb9ec9e041c2b5ed6b7dfb46fdeaae3fb34150", "Expected": "00000000000000000000000000000000040f355021ba50c9a3b2b4267668ac8d76dd88991be984ab5bab9c96faed6dcc6e8eac78ed29cd6f7d687dd55cc5d5b70000000000000000000000000000000017853cf0a39332e3c7d75b08b2940d693ac7cfdac46719787c22b55a2ab1036d6f95b68075f1c585942843aa486f17bf0000000000000000000000000000000008696feb333417a7262e8976d1546b6d0a9d5970095485b18efcdee8993b16f42e6dbfdd08d30c45fe4af6a5e203de07000000000000000000000000000000000ec26926720243124ca505c0e04923f3cf5eeca2abfdaf4388960b87c6c1713fc54cdd1c825e2ea359cc67b3bebfa2f9", "Name": "matter_g2_add_52", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000036570783711b381830e35878fbeb187b84884a9a0e88c38e84124515b470e6ac18157e1499026b27f4f731a961eaf330000000000000000000000000000000008382838c18d56c046a8db495babf8d14c915622d7917ebe10cf7da7ecb65f174cddb9e70d0262ada961b396c5511b410000000000000000000000000000000015f63ce982aa581dad5c71fc79251b7f6336c4e78a4a0f4cb6f87167cabd31cbec987d7af4f11dc6d693a0b0774864130000000000000000000000000000000015c001372fe0530a3f50fb8b30e75ff4b264d673e0448211d082c7a9018f583b4d01790019874596c59c68768cfa3e69000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b0000000000000000000000000000000010f7bf9f6711ba723bb71a004a90109ee22be6643d56d410da18103ef44a1b3d50f10c4b94222c7f05fd3c28acbdc8ee00000000000000000000000000000000007af41f09e6d0adcb1935d6a93ea1f6156fa0157a63f265a3a7ceffe82f6635b8511e7e8f21e8f3be7a73513ff597b1", "Expected": "000000000000000000000000000000000f3dd56c416db1c06fd27e18fb852c9e1662fed42005e253230a7a8f7c3e0b8ce637666e1d20952c219cd2068d6865f1000000000000000000000000000000000aff045afcbefcdcb5255805a86e8af3de881e5482188c487d15ad1b799cf551c1d48c7665028b05ceb2e82e15ea4ae5000000000000000000000000000000000e0e6ed04926aed1f8c6a4e13227bf2a99d9d6d349a9c86214373be693db702a0011b4423defdb7d842bcb6f722c70b100000000000000000000000000000000148b1af285c65b12eef498f1c9e57a673e7a3803088c56e32aaae13dad3977dda8d3e27809094f8d8ed607239610a1a6", "Name": "matter_g2_add_53", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000074d78cdd35ea17a3013e2301fe9f80f2d20d270a25fdead37eed7697a52d152612543781763e6035fa5452ab12cce25000000000000000000000000000000000e572236e1c203a1c0f99e6ec978458c1a143a6a650eee27cfbe406bb2858fe5f30222f468d119703c2f442bc644ff3000000000000000000000000000000000125384343fe132e16a9fc15efe1b3a9e47289e0afc4b44d492e33a6216edbc96d66c1ca66944a8296e7695f27f414c5b00000000000000000000000000000000084c2cbf0d7c932c3098ded7c70d4411eed882feb0f79e0f7f1c31f5fccb6d53fb57de179c3ba5754bc5e532c3784df10000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a0000000000000000000000000000000003a6cc74cc398f38d535b4341faa37c968daf2009c3f05ace1f938b33bbe4002d81d18d30c2c856b21afe7a22b83c37a000000000000000000000000000000000452d1b2da6392f9df1bfd35e4575c565333703b2f83f56e0a88a0c8195968c5321296b07f6750584e23597304a5472e", "Expected": "000000000000000000000000000000001220b3da7e7d03823458bcdcee82db56957e5aec335e9b543ebb0f3cf4fe3cf6ecacb6198c886b9abbdaa42f528b4963000000000000000000000000000000000138233b166547e9e9ee9d11048e2d2579b2b111af5cab372d36159c4c45e28d836d733a1265e8833da64f461c0a32cd00000000000000000000000000000000005f860a0c72034f1a928501d9f549e5c2a9dc72670272fbf35a0b301025c0fc751d55ef6fc2c5bf7ff42df7693f3dca0000000000000000000000000000000012c73105adf97bc0dfec1f56153c57c6fdb9d68341f4397b72f5b6c667873ff7ed5cc841451b391e33290cec256395c7", "Name": "matter_g2_add_54", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004d46066439c3ac559cce863c58316883651023990180470d2efd06e443a7caf3a514b54f15ce6e850d32779215bcf4a0000000000000000000000000000000019ce904b6c9c3de59f7d5017f60f1978d60c564f94a0f1964c24c876d1139a7ffbeb6d0d4884bbfaf5f2f189af6904a50000000000000000000000000000000015f1989719e69be95f25dda9358fb98aae2819e0deb7e2d291e2c01e85ba26a9da421896c6b6e2ed20f609b533154694000000000000000000000000000000000b287cfcf1dd7c6d735c1358dff15393ddd6c82e7a33c5d8005c4234cdf823c76a4725fd74cad74b3ec51df67f09af0f0000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf780000000000000000000000000000000007a9cf48dbe005c5c59b2c731cf4117e5fadc9cb2cd8f486f1ed58b2909092ee8f36d88b8f719db94715641b418ab4240000000000000000000000000000000004ba40d4766b91bf8da1cc2526f62791a1b5f6fc24ffc54b522dd30cde2d29a6a6f81e8429d518710843d43705f3b4e6", "Expected": "00000000000000000000000000000000014933a0923416428b5fe5be7120bf399ab62ca091b07d03da3fd2ff080b9c411c3cda3bfef40c8450ae31c412dc5feb000000000000000000000000000000000214229a73780d4f260364649e9eb2ed751ad3f687a832a3738ca2cc81a3acf12757651e88c4bcd79239bc0b0c40e5a6000000000000000000000000000000000548f20fa375e578084e085ee71df5f8ddaec1db03a1415938d9521b5d9c914b5295835fc07263cdbf49d7802551156a00000000000000000000000000000000063ecd9efe55229a76fc848728e940183c23bf47363cb34c5a49837e6df8a5f0dc29d7108cd10ea08e82ccf017d246d1", "Name": "matter_g2_add_55", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000006b37e2226957d639fcb0bcd6c20b3c7b8372e7347a14b970e01c67c1859fa97c754ce588d0f835ecc053549d963ab4000000000000000000000000000000000c6a5fae8be3a32e3f70a4202a1ab6d97183964b9f7b9a084c49922cd9e0e952b0bb66c5580f0e0c417e079493bcdb4e0000000000000000000000000000000017b6132f11adc0d5d693ae7f3a0f89f5779708083eba23e03b0c9265e4e60624e1fb6940e8ee49d31618fa6389b1b50b0000000000000000000000000000000000a45c5f6df71359648aecb6434bad1619c39f10e279a02b3cc9725d0256bcd126843fc9ed29cbe02a32cbbe79774a330000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c7952820000000000000000000000000000000008ceb842a17953578013ceee519a28ef1b37f73e13564def5ffe08a64dc53aa680784e26138176c89269477ee003d16700000000000000000000000000000000159791b6f2c26ed611ca40bfbd2059c15cfec9d073a84254ad9b509ef786d62d17fdc67ab13092cf0b7b3482866f4c32", "Expected": "0000000000000000000000000000000008a71a08d2c4e2ba3d8774dcb42d3e96c7f72d36fb3b880a4049b078d8257a7a9a51b0b34c093568baf4aa6de70e709d000000000000000000000000000000000daf83b5ad4b91b557982fc4b9b7dbed2998aa39fc4658ba671f5f27b3888dfec7602949cf626c9e6ef21171acb185600000000000000000000000000000000013a7ffca291d9ba8790ca0462c54c147aa22e03a2413b756f27583155932aee65060924e46db321b3fd6f22ff7f54041000000000000000000000000000000000289d7de10285285279aee024e52476fa6fca85550f7af183a161e395d72e1339b629c64127f96bc85858d80e73dcbe1", "Name": "matter_g2_add_56", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ffed009c78ba9af8cd33af7b7697ae4dff863bb92365055baedd2299b7f5b5e8abb84ed434f7223c3e309ca53c08aca0000000000000000000000000000000003b2370c837dd6291818efe7c9af62dd51295c418739ecc509d42c92e2c97d12a9fa582946e176e8153fc9a273140b2f0000000000000000000000000000000001e63438e8b4a0462cfdff64a281ab4a7f48d51b51325817139f8ee683484f8695f1defc0c3efcca81d5fbff06cf9c54000000000000000000000000000000000192fc391cdc1ed6ddbd317f2f366f2ce25ba27b8c0f09c733e7bc0c0697544399a3a4f1186d139a8f6399ffa88e89a6000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf000000000000000000000000000000001272c63693873e1dabe2c2739310f627d3d9b5bcaa615402c3849ffd8dfe72b40fea4a068064655f2c8f46f074e6518d0000000000000000000000000000000000161a8e5e1de10938e5bce241ae73d76173022127822d744b23e656095c28f2f8d142ceb48b72a1dbc36b6143f8af95", "Expected": "000000000000000000000000000000000a4ed8d613cfe4f5dbda1d0c6812d0edee45ffc2667323c3828f8ce4ab55c119e92a82f2c3d06afe3adaa4aaccc18f8d000000000000000000000000000000000fe10c5e185f3f8ba81c93754132d76e05eb3543d8aaa8a2d0c98833ce5fa9e2b84420d6e3412e005cf89d11f5400a510000000000000000000000000000000004ac5f8cc614e3833b3b6dd9eee9ac29501002ba9054554314a4c516bfc8cec870995e811f7892811346574f3c58b2ec000000000000000000000000000000000a6bed54d8ed4ccb09211ae7773c604edc6ce51a05c9acc94e8167026906d387af681fb33a40e72e85cb076e072db7d9", "Name": "matter_g2_add_57", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000002e105e0eaa418d58019a849b89accf665a94ffb0bdf308a11b99b521de7af8ddb150c0e3b2e9c54cf5456b6105bc81000000000000000000000000000000000691a3b3986fbe1c0ea22329364454f37f645d6abe9310e883b9191ce512347e074e18e28b88c2adcc76190a549b80b40000000000000000000000000000000003f3a37a763c8d0d99a3fe36923843a22cb0fa18ced48493b2510fc99afe5b7699bbaa6c2ecdad8aaf72969354f121a1000000000000000000000000000000000f4bbae00205f54eb10c83d928d908fbae342b76050e33c51b6e282e02b3c1f132a4728dee4ea95455c25fdfc112f254000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a220000000000000000000000000000000018a236ea02b1971d6e193a6eb92e1298956679d86864042fb6a0c36dd91c0e385944d779dedd0149fa8a1b3d6a07949d00000000000000000000000000000000048eac7d116b5a7906bce070e2b51ee7c4c493f1415abdb6fd2d35676036d3b741d14b7135419645a6906018e9d3f150", "Expected": "0000000000000000000000000000000004d145ad2575313a922667b897052063139eef8c61dd375eb055c4a5c52cfbed35391a85df915e1eea50d000b9b6bb5700000000000000000000000000000000071cc73c16a234e99faba9b04fafaca1a943f2bdbb68dcae0a1742acfca1f90c5f69464aba42be6c18be31f79ce30791000000000000000000000000000000000bf725a2f4d7d33c66fefeefce13fb5649a68a93fb7086c943a7bd5663b5788a5ceaad7fd2a219ade832dfb3c0022a5a000000000000000000000000000000000fef4a2610610afef43da2161b86b25a8f6e30ed90053d57f5ee0a10effcdd2af769d32ef6843804b2b6590f95eccb4c", "Name": "matter_g2_add_58", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009a3e98fe4a98582ce9f274965f376cb45e8583775dbadf626cb1327c1f8a25b293b97e7f8f31ff72ba7e8e769ff25ef0000000000000000000000000000000018e4785ccb76c4897087c8a4242ddc744c6a0a53a4a844254153c23d6f16d4ddb945252d13f93101613f4eb0b1e2b8320000000000000000000000000000000011b81d344eac04d3471b1edde5e51f31f97bea3396580839fa094db58cf6bee371bbdc045fb60c3ee5c6cd5d3f6d3c4700000000000000000000000000000000073476bc5b1d52ff4ca89c3afc099417f473543fab6e59cf9de8a19705dc4bf2a210b1e6de4dfbde035c312be0c70c5600000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c95384000000000000000000000000000000000003c96c6f20d7ac31ee7ca77d11e8d25ea78cdf13e5f4d317752320e059e19196f14c15b5a18ca712f3a7cc6f09be6d4000000000000000000000000000000000ebd71f61fcddf1652675f577bbaeec26b892dd954965b057ffb431d6e37cc5425a2a42a0059482c2bd75adb2a120b0b", "Expected": "00000000000000000000000000000000151ec7c35a67b878420e198ee7bf359d0668ab61ba1a0bc2e5e57b1b7b18838a015464f9910b659fb7d1e10af2801d86000000000000000000000000000000000511536f34067fe931c6e829e22443eb838f0c938eeef6f839eb322d72e2011dd1c33c504dd044e3cd721065d7075b520000000000000000000000000000000010c486f846242024f9bf40d805c8e33ecf1b44cfaa04455d5584db7ebc32c0d29e8742c61886d4ebae93f22c518ea87300000000000000000000000000000000072e184c836a853fd1153eabb1b645bd35ef72eefde4a52db169acdf2d8d68499398599cb4002994c6f4936de1da75ef", "Name": "matter_g2_add_59", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c414b95b298b9c673001173ba7e5ee3e03926f28068481cfa0b469ab556f8fceba9fd0a815180ae0b82c265fd4c6b7e00000000000000000000000000000000054a242c1cc1a9c710bc23305d09c2d613ee8eb3840b37943bfe83f9c1db456ab4436ad319fcdd8684db129d76c95320000000000000000000000000000000001683711c0c7f02e67374f190eed1ce6559479d6d199f43fb5b0ce7df7774a5cb21c86b3b3498855d9b69c5763acd8c4300000000000000000000000000000000062f87085dfec847af518bd71c078f994b090c3b27c6eaad79772ab58afa43993db52fb08649a32629d61c3db12c87310000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e4000000000000000000000000000000000174ffb89d7715866562d9882acb81ce40758644ca3e0decd546c8f5c349b24fce88214956e7540fac36bcfc105cf34a0000000000000000000000000000000003e06c5f607ccf1e2991828034fcdf91106295e7174b4dca21926169451ee58e737d535af45073e2378206e03c81c421", "Expected": "000000000000000000000000000000000642f215b772d17a3aa45ee3aee607321c02b4f7a7df3884259a25ce78c73e9536d46333fa388e506fdc79c708bfd9de00000000000000000000000000000000145864ce36521fdb641761be541a27bbd3f4797b923a870148bef1d5b4b0d463c0a7c8ef07954dad464510d836105e05000000000000000000000000000000000ca038e667fe68111b583dfaa95f88d3b9e46c0798abccd1476071435067e6c0e2fa81d25db6e1175e60efa1705538b9000000000000000000000000000000000cf1cb1b155e4ea47077c42a1a99c3f11f8b27516a808b5e73498ee12363652bb46eab7e55de93513cc2d6272f26a537", "Name": "matter_g2_add_60", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000083eea9b5b2d5ac5f7ef51ca889a4317322d098a408a741827fb3419eb12a51c07c788c2798cb37635e224e99bbc894c000000000000000000000000000000001312ec00f4b3a4305700b44b3f215779a9a8bfcf5b5d3a7f237a33c5484099ec9bc5c8537fae768e2c0ec62168f383d6000000000000000000000000000000000cf1d5d05d11e1d07074dd34211d0f00eae1df4dc550c55bd2fdafaffa1ad36abd5da30c5d3a5aa2845b1d95a5cb571e0000000000000000000000000000000015223baa9f2ea4b04fdb05b05bf3a94dcabc5e64189aeee39c380de9a34fe6b4253f5795f70bbe51b80e1aec1eab71960000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000b15d92f2301075ab0e3215aa72cf9b130bc8e1bcd9fa36375c4b9d7da430ae3e2b24f417336d8729f44542ee7f561d300000000000000000000000000000000197d90090501e8cdea28eb7963231f1a7b5f716cc3a086acb6e7626600d6544132cac943e8d5cefb5daf0a2f8d400629", "Expected": "00000000000000000000000000000000128c909854a20ccf9e8e396b617b36f233909a5f6c3524c93cc659d22afe0e7058a438a5ee4345bed914288c64802e29000000000000000000000000000000000239fc43718cd27855ee5450cc9be5be5d9bca8188c22601242a1bb4269ca0fe62ad5e12b2c65558cd3dfc89ea31205f000000000000000000000000000000000a0aec9527febbd35bf041a901b0b35e5e0d48a2d6d733bb557d0767798369a7ccf2f1c278710eb764f721821f9aeea300000000000000000000000000000000194931bad52daa16a648ccf1ba9a4768e5e2900fee4f9bf46ae07d1aa605aabbfe96684f5d2233c0b254cb4ad5517775", "Name": "matter_g2_add_61", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011a960cf1978aa2ce1731b857fd91d2f59d4b8d7c6871ef6f4f85aeff549a2f397949d11a4793926fe7be37f3a83d11c0000000000000000000000000000000001954f056834d6e3b16043ef1acd0a47a353300257446e9a1db7e58bd0d7c4bc9ceb3db51ae01cfed9de99621e96934c0000000000000000000000000000000002e2fe460e71b65595ed93a0010e5ccd1a2c16fc4e0d345e7226c947f29720d2f3f54282f79cec086d3fb1999b9629b300000000000000000000000000000000060dd8a7ccb613f1521168a8a322aef9f84d9708a893f704f4fc9a19e2493f25620a47e0fff1bc1e212e65e92873b4f20000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d", "Expected": "00000000000000000000000000000000189ee5ac642bfd0b612058f96e63acb1feb6b4dce125bf0ea1e56e846775af1a8b0864d4ece6bd96c3b5dbb04e2f6c33000000000000000000000000000000000073d57ab79314e38267ee8015de3156f2c1d5dfcb6655a150b9ab4a3bc9eeddf7b37b3681c49611e02abb012770b3f5000000000000000000000000000000000cfa1363275c7bc5bbb9bb7c03e7bb7f6d6d365e39fccbe62cfe0bb93280527c9ea99079fdf9871abed035b62079856b0000000000000000000000000000000010048e4e96f26710d254110650de36460be2a8302badfc2da8b26147da498e4620e79b4329033fc3f3a9c99b1e12aad4", "Name": "matter_g2_add_62", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001472caba61c2f1fe4b1d0912b114c25de103ef4351668f22f3a158d7a347539a7b6656044bd490f036ca3e29dbdded370000000000000000000000000000000015f8cdf7786410b409f218164063c99e77d8f72f03882a6c9430ec725ae574547d3ea3cf30c3ad2c9c3febe6c30b1272000000000000000000000000000000000ccbbed85c2809433fbcf22d6490457dab800b21cb4de414c7dd1804a0bdeb7142f8ffbb2de921c2c9eabee6a6351026000000000000000000000000000000000a404f42c48e3ca408d3f92079b99805004da928f128206d8904ecd7fcb14121c7d9a9e7fb69accaff921315ef3d5372000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000000e7e532ee4b892af39f8a3db7a05cc77a6eb0b3d977c17076bac4a52d5ba003a0ac1f902a4257791a45370eb88426a70000000000000000000000000000000016a556050e4905fa74b5061e3874f05cc7a6c5b049bd3bb7c34adef5a77c393239a600542a4401c3e61978ee6515a30e", "Expected": "0000000000000000000000000000000005889133be5f447013d779f2b9b0033667c5af87e1c8a16d239ca3ed238920004d87e00119ded46658026c26988ee63a000000000000000000000000000000000d4ed8fd88f7e1394f2b5a65588bf1c461a292acafdb77703c2790ef249f2de695524293c826252c94967a3ea4a3a28500000000000000000000000000000000001b5ff0aa278c7e87a89d4748aef13b516c49b7dc9f7cd5e0448dc6fd860a7a8af7183a198eebe6c7dd549fef806db00000000000000000000000000000000003c9e40ed44427cc3cf886ca2db341ae31f015c542b857f6702d25cb5036e3e6abeb8d4bf9a0e203281ab85ad89ce0da", "Name": "matter_g2_add_63", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b52f05365c4df20a7290aee71a7e030615d1a2a971167884d835c24e756a0faf6ed0552341c561446c7fd3d5e887d830000000000000000000000000000000018718ef172c045cbf0bb132059754b62414097eef640a781db6ad521af5a24d78c622d9402033fa939f70aad0510a1ac0000000000000000000000000000000017e969e44b4910304b350b5d442bb6a0b71e1f226cb4603cc8b4dd48614622f3f4e1ddecb1894046649d40f261d94e030000000000000000000000000000000004dacaeb9e05b9d60ce56c17312a092cb988bff426b8a718cdff860186935507a06eddbc4a1a29e4ef88db83fc4b6e77000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d2900000000000000000000000000000000179c34ba9578d5ff90272a2c7f756794670a047f79a53215da69937152bad0f86576945b12176d3e13cac38d26335c51000000000000000000000000000000000dcc715907e4e17824e24c1f513c09597965941e3ed0aaad6d0c59029b54fb039d716a998c9c418110bd49c5e365507f", "Expected": "00000000000000000000000000000000093b692a68536b16913ef38c3bba7b19ba94a6af1c36a2e54b8ac1754a29c29882107cde142deb95365af00f2d1f537e000000000000000000000000000000001035e70852f38f860a1a04f33081e84f3ed17d83ad894a6800e7b8b9259067b755fe7e08d4c1b297c6d53064ab8209590000000000000000000000000000000013d38db0d8575131865bd7acb6cbe994812bdd8bc7f51b810bc382a6eb379d442c47be20a2c8e751fb08ccce8fea68690000000000000000000000000000000000bd114951193e3bd58cd0025e0b0c807ea073b1c1f7bb04a2a00771b6442e70ea20e1124572ef5b74d2bd87c93c82f5", "Name": "matter_g2_add_64", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019829d5799eed5a081042e4646d46fb6bead6d3b9893a4240867b25ed6af6a3e154514f244466d80e3b9311e060bbd7100000000000000000000000000000000156157a654db2813cb9c1b4da0a3ee192fad076bb2767020fc5fc00e967c1a35a367ffa375703e1181b3705ace9dd28000000000000000000000000000000000093385a6a9dd0ab996df54b23f47f4a49b3f379e11bc8331016ecee6161fcddd22f6d49fbb21f098873f1e17424dedca000000000000000000000000000000000d5b5b0f2ce81e755b4030b33fe3a8bdee38c2c60ed3b4a88bffb9207cb762c0a5c699ff424c000ab080d763abc5438d0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c853000000000000000000000000000000001643567a0f22b90fefee96c8e2f5851623384c2c68bce9589cdf64c933d494a8d805edce2fd18a6db80f4819391dd1f9000000000000000000000000000000000e4e40ab1969bf9f00ee3b984947ae95bf7b9579bdaeeee926638f9566f8ab26debb4c8d4009535cb6422b2c2ab7282d", "Expected": "0000000000000000000000000000000006db1eef1f614613ada8383e63d631484015224902ca38f58ee384a70af0a0575b0e7063675d2dd997ed8a140e2598470000000000000000000000000000000010d7b833f050f18ff4e3a8d0df227a9494dad9cbde88f68802b23e87387622a5333dfb7bcdcbfe2d4d137cb532ef4a150000000000000000000000000000000000c9c40ba972ee0be2823625a23345fe352d701cc8bf9a153d5a55c205ef1b7e5544d0a7f65aaa24bde8d77cb4c31ab3000000000000000000000000000000000402f170c4c3ebb9b1e7d64765b66ba9b8d45b2ea9fe9517626f38e00a11d180e1f8872bf80f6322bdf3a8dd90732ae9", "Name": "matter_g2_add_65", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003af8c25bdbd0dc1cc344d55366f15555709a74e1f0d8d7050cb6b487759db6200401b7868fca3c2ad26e6362a30e6250000000000000000000000000000000013f8b6ffe30f9a133fafe64461d305cc6b2cf5aededf68ba396d4e00df651531c750a3d94dd77bc5c6713b939b18fa19000000000000000000000000000000000dde97855d7728f409d873b83b6879b45ace5b73f317687fbf478e594a959ce21d4d751db646ceb20432e8311e67404f000000000000000000000000000000000fea997323cf29710cf0e3d44ce682e039d6cbda155e43c94dc8cefc5e94000de4b9525123b9615b5f1019a46ef37ad300000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000a27fe0a29c761ce29a731ead969b1db3ae9ef4c05493cc370a128d97ef956c55d9a500991b3e7bf9600383633778ebb000000000000000000000000000000000dbb997ef4970a472bfcf03e959acb90bb13671a3d27c91698975a407856505e93837f46afc965363f21c35a3d194ec0", "Expected": "0000000000000000000000000000000002dccab673b26be02d2c645c82a2c73290f0eb053e07d4f81d4d315d9483e57c58b65cfabeb0172934b9fbb52ad519210000000000000000000000000000000011c34a27c850fe319fe89399e7680064caf6dcbad171c3a23c45b9883ee06ccc3482b2b81e5777759ff81b16bcc1b0f500000000000000000000000000000000119adca3e2b052c045124f021fceb03c979e6eec0a270c7f4ab13674e461839a4d3a10fd48da4e9ae750a238a2649ace000000000000000000000000000000000fb5210677e1096cb5448bcda16646d6dd29ff8a0765c5aa51d83fc952a5ab8063aa96e97f33abf701cb8688c989c363", "Name": "matter_g2_add_66", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cdf60e3bb018407eab162822468255bcffd54cad9127054bd1c30705a4ebf1afc7f539cca6ba4cd070b44410ec751150000000000000000000000000000000009a2e3e5993b6a7007dedbbd21737a8c0aef3ecd4607953c4a24bb3fed97ccae01ae1cec024443f300b570a66e9ac3bf0000000000000000000000000000000008a21fed19e9ec2a741ade7767b0c9f39b79c3fbe34aadc9eb3043583768d893bf927d26231759290c7dd9c4f158d5a10000000000000000000000000000000018eef4ff88d63149d2632c9db586a4af0606644b16c82fbb0a3b869f1ff924c59acc8efbfde7bc604497ff68939cdd0800000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000eb3f5d24d1a4f520032534f6f81a6806c54df33cbd10c30203423aa4f33620b474cda321e924802b636daaeb34400470000000000000000000000000000000016f004f1dfbf140de042e4f57303928a576d9064f2da5b3ad392331f5c43327c7d2a6fd57456d5ef58b54a3e5ec27508", "Expected": "00000000000000000000000000000000056489b2248ba672501069ab6742016cc8ab2af50a119239bbd3c0a4b9b56e014402b78bf62b2b37bf4645c3bd3d95b800000000000000000000000000000000046956432001feaba6d230da27a72e8db5c8eb3d52f00616f87b55c951217095f337a302562cda789e5714c4391ac27000000000000000000000000000000000172c2a583c9563fe02d43b2b767c4ee4e3990fbabe4ac536d64cfcf059f0e38672876289bc86915b6344eb398fbc4ddb0000000000000000000000000000000008915b0edade80caee9b386e4a560ff4b9dce33946ee992649466315786e139e3ce241ebbdfa7ee28fad7e6214e65666", "Name": "matter_g2_add_67", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f5d47911596c46c0c08cac5f5e7f6d0609874da4ac1bd4e0e59c393273a5fe31a756c7cfff2a01d19e79d209d7c6d3e000000000000000000000000000000001010f864eb6624132d4436d18db7f5b34727060dc426c109886be88031e3c155490cb3fb09e1fbccb7912875477c6d840000000000000000000000000000000005cfbf1c2ae1b80a8c7cfb2cefedd907b0552794f4fda101ca1a723b18de8cbce30eb54287e1847cee3f416cd8b45f2c00000000000000000000000000000000084fa63781f7eba9c7e911ae5866d485bc7e90603541c55d1ffad8b3cf7547fd57fb24b14002560e58410b828513e1090000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d0000000000000000000000000000000002a36d5efd3381c35ff4f361cd813a96c3e5185141c5985073b45d1319c5f392442b7aa6a253b7eb22d1b5052812be00000000000000000000000000000000000f745dd17966b6befa7f740ea360241162505d6269226ffda90546863d0fff124d8fea13c763cfb69c2f8f12b81d431f", "Expected": "0000000000000000000000000000000005b81843ef3f98c6a6686f1fbd26f77248497ec3d41aff4be5968d13ba86f86309b0ec4792d74220ad8ef147bdee9aa90000000000000000000000000000000019825376b243f3e374b6e9e7e51e0c969bc72b39cde1dfa09187a3c7c5c2c752ee16fa5a4c8fcf94464287419b3a3845000000000000000000000000000000001308cc0c77219034a9fc3018f1d668a41e6959476aaaa5461ec73d7155c6a68fb08e1fdf8140e18270cd338c266a83f4000000000000000000000000000000000fee2a6e245e3bb570c3b605f7ad805bcd68e9a1f2bb2282f92e2a2e83b69e275b21b923f33a65defa8c4224934aa588", "Name": "matter_g2_add_68", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000124870cfa469136c638e0cbf15802f2699aacb66d7e4c2965c6759dbca4b7e47941ad9ec37a84db1afeeeaa65a7418e4000000000000000000000000000000000d4503049a6a53536bdf41dd832a6ecf3f10554887da7e389cf940394e1d88db94369b7947436546eb6c6e82c48dfb9900000000000000000000000000000000053f9a6e1f05b67cf553073358009a172e2ab8b43572a974da1f3de85a29103b13d7e67b2a359297172d27dba5c61439000000000000000000000000000000000abc29f50ddc1c113c73700b9b9796890cbf48818ba981fdab2db27ef1c58f4c2e4595b99eae397d40990ce2f6c9317c000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000000397dbdcc3edf976e8c507f5e70299da8c7765772115bf8edf7dc9024050c2ed98746c2bf7dd4400ab1fb89af991e43f00000000000000000000000000000000139bd5f917f59e2cb6c41c59024c12cdaf95285f3947b80267f36e3bd2701f9548b561c49003fc5ddeee3fe7bc8f5b5b", "Expected": "00000000000000000000000000000000166414455bcd0e8e40397f4cafa9628d1a092beaef62d35211cf49779ba98df5c1d692f650c1fcf0893a9d4ae1926b1c0000000000000000000000000000000003dd898d0725ee899b913042da8566a1379aeb4dd5f0222ac784205b4e74f32858ae490f981801b166a01fb96266dbeb0000000000000000000000000000000019f0fe4f12b113b337361b977aff7cc7dce50bf37c2609b9f311ce340d30225de178999b73345ef49625518e52aa4d7800000000000000000000000000000000090bc07c6270901d706a8d28d512b07fd0e03013d94d4e43eafbee59677998bfb7c2a58aa93571fb49c35518b6331bca", "Name": "matter_g2_add_69", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007d2aae9794b7a7de97f7146c0ee8415e09e56fd42535bce6773cadd6f7ac09c4eafe2e926cb7014377e54c703eaa9dd00000000000000000000000000000000172a4a33ccf99eb0473b2c44d30bd53159afae0c7706ad128bccf6258974d5e5761f9be43e618cdbd96027aede7fd5860000000000000000000000000000000012601bce2171c6e4c2968a3efdf1491285f9e4ab37cf973ab5c8e224ad5b40e1b6459ac89090c73deb8fc79fec7fb8e200000000000000000000000000000000112a6443116e6f98ab348e57daa3971b5fa506e40515e1611fbed3e7dd64c5c1e991e0d2539a70eb93e3da0f573d6b22000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b00000000000000000000000000000000197ed996d62fc0628d8ea4adee487df31c794e05e7c327aaa140c6be0109031bb763c5f84bc35a0597dc61e93d23a9bf000000000000000000000000000000001056c1f3c6ae36be26430d142d34b0e807685c79935496414e004cb85900d85a18454bde9c0f2650f19db35eb3dd468d", "Expected": "0000000000000000000000000000000019ce0f31d9ebaed0ea1d12d4e232bd3ad48373fa465af44f1c8015102b624d2f8330d1323fb2fec524e83de0f6699ad7000000000000000000000000000000000915d65fef96562ea3b76f3152aa1b8e445ef50fa66dc487ad0c04cfd7a33b5ee48aed919eb81fe83b1f4dca59b4990d000000000000000000000000000000000e4731ec887261f29475523f7dfc5d21cbbc1b883439701a33cd58bd24f5d447267707c2b60ea38b04510be7dd10d72b00000000000000000000000000000000146a679d7a81aac5952645b2635f24b96393529ab9571ecc1078c4c20a77e59acc4591b9f45df00428250c5e31b1a8e9", "Name": "matter_g2_add_70", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000030372914b83644fa4db1958831e9335c72ab7a811fb337696221a3290e4c54bc10c2225f8fdc3a9f62632ba2f1594500000000000000000000000000000000114205926609470b6022d24046a1997c048e6d2cf6043397892c967692161c0ceedf409bf5e1199a64eabb1ff8de23640000000000000000000000000000000017cdecbe73779855b7b94920d4bc8ad057ce51c5481a5579650df8a5bbc421030d2ac44568217c4dbb13d7c639760236000000000000000000000000000000000f194fa814bfa7396697bd812d9449d06fc61b580d7a86429fdd1ad376e21ceca139356d7d13964c3c684563675711c60000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f0000000000000000000000000000000008789ffe0a8676c6a56742a30a48e5e65b88aafd71859d704fb9f69e5e274ccb6942bc51ad36c5671406052aacf19df9000000000000000000000000000000000c7607f4fc69a25aff00a54369f213c4587404644358da4abf26d151dfa4905ba9731dcfb12e2a3f2c551cacd0f4e47f", "Expected": "0000000000000000000000000000000016790155e57f7103d9e325a1f3a64c0b8a1875365eaa0c01c515538b64bd8265e8392e755a2f7314c37ec09026f13d290000000000000000000000000000000007bfe690fc4ab166b29de35e341e8faec4bc3c2d4ea2d42c9f4166c0d748b92b743ba646c86ff9e570612c75bcd522a9000000000000000000000000000000000c11b9ccf990162b772099fdb4266716b11dcf46c5abd12d03caf222c571e2a9e28cfb47e11db05162967ad4b430930e0000000000000000000000000000000000bafe02785607bae144d9ef5391fef02b9f2fd5dcd436e2506bd40866d8726eb83c223e09c00f3b8895181c6710912f", "Name": "matter_g2_add_71", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015d4ae1521acf897344c3a76261754ff99742585af4a0ee86dc473a88fd408091404df1da9d8bb291db68bc9c07d6b2b0000000000000000000000000000000008ce160213875c661163990f3f7ac219ea295db5e828354864517ea8689ec15d35c6df78ff14cb276e0c97ffd7fbc09a00000000000000000000000000000000038a3ee211e777d6d6b7ca6c7a0d2130f1a071c030eebec412c3a0f14c3584e7c5cf15de254a8f141a8210a90249ee5a0000000000000000000000000000000019f7ec6b2fcd8b3190ab37a6e843340d3f3fc092f5772a042edbd5bdc967b96e8a1dc9e435b8463496aa1301f87d0e5a00000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000b060965391bfd4afe3271c6ddb91eecb8c7a60451c469d63bb178b1361617000f589c33c35b5deda2f072c6edf2eb370000000000000000000000000000000011c8c988379cd2b82cb8ebd81c3e14d2c01c09dde5690b97623c0876c7554f52ccbaa33d17fb0f0cf331cc85749340cd", "Expected": "000000000000000000000000000000000965966a8a463de1f3bc49d9873668e87f54d95612231458dc8b885681cee8e2835482b4bfc476153c41b206f427cbb400000000000000000000000000000000183639fa14dd74c33e8696496a3ee269160f88e5daca4fdc468724d9b6af8e7d0706867cdb1bcc608029b89b94c531a800000000000000000000000000000000026257fc32efaf241c7712b0a7e9f881763d8fa0711a452d9b71ea25e973bffd88433cba768f1e5b3ea15bdae9cb9428000000000000000000000000000000001527afbb6594dc0f472673606fb8f4797fc855bde4d308ac1acdaa26f19a70f80f2d2bbf3498b53b887b79fd6273231d", "Name": "matter_g2_add_72", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fa7f8fbfa1d4ef5f001a451c55ed261dee344025e599884b29d086e15665867932120d33bee579d5eb1b7e6c7299f310000000000000000000000000000000001f06356f793350b17b47a623059a068800ca1eab6089c7c146182990063e8e23bbf40d95a42bf6e976224b680b75bfd0000000000000000000000000000000008807f6606d2302450bfd8b38fd4147b851ff59762c1ff48f9442c4d7b77a32c5e023821eb47fca839a27fde60e5f61d000000000000000000000000000000000c5b92f1ca9c20d4b6b11d794a5853824cff20d9267a20a7aaa4bed8bfdc728c4d4d50feb8f0b569757b97f473138db100000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000f05a111b41a54e0ca78c3a1fff3b80bee7c1505a06b9a4faf36a73b87121d2952cc4f4c4e0dcb6633cad12b0caffc620000000000000000000000000000000018daa0f9a2bb347517eee63463b9d6a5e850446e8a94d0986f2921bf81a9f7541e8fee9d7bbb6d9181021af945fce3e3", "Expected": "000000000000000000000000000000000018123e82a5572e6b6c62d5db07448838df9db7f7d15dac1adba1fd924892c8bb3c417354e838f706564a9ac282c2ac0000000000000000000000000000000016613fc38997d39b2761aed3485de4d7c273e8392e434185605e968ed942b9d4712cd0d538ed5ed1317870d0cafcae27000000000000000000000000000000000354365566b6e43f8b7f4b94a6343146f35ba3abf61a204e9c976b1ad1a90d4d493494c957def69ff270371c1c8d953100000000000000000000000000000000066adbadf1b69dd16cf19349c82e362be4a3768551599b81a4853ca524a24326e6c9dcc38b5a60ed6fdeb3cc4e7973bc", "Name": "matter_g2_add_73", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001191410ec6c5ff628bd25d35965f5e9fa7f3c3d8c0a9a1ee7ae37437a97c25e221110d892e2c7a0e9c8e386774eadb80000000000000000000000000000000003be30c25a18cdab139277232d8888f6d13112c9556895af8030f1893114d5845d895df9afe3c6f9ff7ffb1919adea9200000000000000000000000000000000197f6b4e38be0358a3f1722664c61e62587ecf5467f8aadc3a236b47682a75cb76bafb18a5c556b321d5da49cd4bfd4e0000000000000000000000000000000002e4ebf7f22d929b7421a600e67fa2e64a59edd87a2e2eb9dce1f06d3c793f1a812bcdd510e654d44fb4c1de8c64ba9f000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a9035050000000000000000000000000000000017d9e9e2008501981068cb0403e73c270d99defd468cc9dc2d5bbc57750a4a58236f8f7a8df4f8b607095b6a80e7de49000000000000000000000000000000000ebddf4fc74f25be3c358b72a20d1c093f980adfc943b898266592f691e11413c60151a0085d6c9aec8c2d329abbac0d", "Expected": "0000000000000000000000000000000018ba8af47c5cfa552374cb1b25ada1ac785381f2da0501f86c9e7b11cd4417e64095a5c4bdc2480ee10d215ae2296063000000000000000000000000000000000a2e09eff98280f6a9863d8b8faf8871b44650496eac1aaf90fc2b256f88e937101407d722c95fa76846776d4e6bf0dd0000000000000000000000000000000003824f5bf25fa4aec5a9e044703e5564122bec11da155c01ba8ab8344265516c1063983235863d826f68bac455327c65000000000000000000000000000000000ea72f8c6768736800b141b477610e37477d926acaffaa1951a5bfebb042c94c065e984a8812430153d529dbf07ce2bc", "Name": "matter_g2_add_74", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011c6f1dbccde640f63ad7d40089779d01075e26269421b4ce12fa5341f58ee9110f17d08dc1052426f2d00da2dd70b4f000000000000000000000000000000000740b147bcdf06705971c113a5cc12fb37345dd59f2cbb5ff500ce2b347fc5a8199cb3007a871670d5093f28979cfade00000000000000000000000000000000046563ea98b5e85b3c42222d5e0d8481e6aefaf077a1b99f2b4eefb397ec846aa3659aacda569054c9c8b9b69750272b000000000000000000000000000000000812d887943506d68e3525ced9b979354539b7b14003a3169e0084c26326b92be67346920c9a99ef0f9638e8991296fe00000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000001fdc4256cc997934a65c68ab9767b09c7aad14b5765dbeedb72ab2429231cb333ab9f9143414359376d76857e8972d9000000000000000000000000000000001362f417875259b47cfd9e4c5feda52b949dcbf5b8178318428fd3e70c384020e58f515b9a24af5597cfa037d42491c6", "Expected": "0000000000000000000000000000000009f1339cff0b58b00a871add058929ffebdc58cd1bd8a9c2c965c63e1843945b28138008cca8bf7b7cc9afb69a11767100000000000000000000000000000000011f65b337710a4043e1fa58bb41d80d505e2aee434b6978129c80fa1b124db89e61617e89bc0e596507566f4a484e9f0000000000000000000000000000000017560f768496ed583b3522c4a013f8b96073197e5b53e9041db6dc935a266111e21d8c54fa33b7bda944a573f6e1f07d000000000000000000000000000000000168a0742af91f42058e6501e122b6fc50dc966c2f5981372704694544aaa68fba2b6483752fa2464526d5072f84d8dd", "Name": "matter_g2_add_75", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004c8078fe8567013e8d05a546934026cdeee7d485e30d739407db16fefaef53ed7bff0f9adaaf064aff014ac919d91c600000000000000000000000000000000107cc17f485af7f22e07cf14c5cad6368323f720511fc9dda677b360567f769e47a77f61274927ef9b7be48a77357ec40000000000000000000000000000000001487f0880a6cbdac33ca35b9b65e4ead9d8c2e9180c993bdb2052060325aff8c62668c643f0cd9b4bb1f06a3dc74285000000000000000000000000000000000d4b2d062e31fabe8d2a329dbd6417673a519f455739d140246f2b3e43e20f390088c08e545bf0419d796ac71aebb519000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000010fb029e35b3f6e156b8751415f180ee3960cd3bb6ba9b8e456715ec70b1ba1410b8bfb77998f744d3f462533b59e26c000000000000000000000000000000001472654d9aa210a41d74e3661e05a9eb6b292719b46aa65f94b6abd514bf05f679dae89d21008245d79a381b0d7f51be", "Expected": "0000000000000000000000000000000005daf8338637bddeba63c788d78faa622e014efb84d3ac1d655d15af06317fe31d1782b2990354bd507632844cc87f2700000000000000000000000000000000185550250e2d9eec798e8b8c483dc37e2a917b304a6036e8ee518a0738d6bf946d99f6b7ee352b1a259aa894d53a8e1300000000000000000000000000000000105a4865d66ed4bc4f51dc52ffcf284615593d573b6beac490c3ee8e08ab83a529c8dd062d762d1d70b9b3290b6e8bd50000000000000000000000000000000014f598e5d0e40090f29aec1ecaccbebbf2a2d6889bbb9439798924db41b70c0cacdcf1e8ff6906f61943e9a8a1ae4fb5", "Name": "matter_g2_add_76", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000811e9b0acfc10830c074c5a4d9f4d9382461eb523a61dda0b77f1c43b285fc5c1ef3a1fafd923addc9a6e904505a255000000000000000000000000000000001113102d015dbb509f0b8d0d0ebb4d3711c4f0e1e3d55fb0af247dd24be4fec9d6fe3ad73fbdcfe206891bcebefee4dd000000000000000000000000000000000085aae9e58fb97b96ca3c089acab7bdbd0c3adae141bf61075f5c13145b0d07113f1075dfb959bc7c2d3d3b3a06ab2a000000000000000000000000000000000bb5eac8125807c10270d94e5bcf278241d6fa82f68e41b5529b28aebc88870af55881db526f7bd221a8c4c0b29a1b7d00000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d7000000000000000000000000000000000520cfc8c536a1d4e685c4eacbc2000d70abd72e1bf8ce3839d79f5cfa069ed31aafb15542f23b8d1af678bab05a2d410000000000000000000000000000000017cfffda12d21c98b79ac31c5bb696783afb7d69c2bedf0fb070cf7714959db14957a4763564b65b7ed214d7b48d399c", "Expected": "0000000000000000000000000000000006b63929ce97554659ae731d60d11abe858383e39a67007877f68233cba8179777c0dfe511fc730448da3f1c4347f85c0000000000000000000000000000000016d4df414c287b0871c69f9745a9ae68ea3a1ff41ecd17d87623338bb8750bf12be52caa81537bacee06cebb86f894890000000000000000000000000000000007ad72c98e2428b90bead3616f1b31b26e978cd3f9b6b759ad53056098c18932c48ba78d3da112d7a738d7a9ba21d84e0000000000000000000000000000000010dfcfc53d0458296686fd7e0555593e0378d2cb176d456abebfd8322012bc9b408bb180d4237679985457e689131705", "Name": "matter_g2_add_77", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d94600000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000007f786ea1cc7cd69ae1061d6b914278dfc7ebe8a714aa8cd04323860314c3b4b36054169dd5c6c60e67bfa3902d216f50000000000000000000000000000000019675b09a4de34af3c6e79452b57b31b6d499200e996008a9e7d1c910ca0ad2a352dc39cb3fd7333182476095b7aeec3", "Expected": "0000000000000000000000000000000009b166f124b5b85875834b5b0c088ab79a2dcf262240b284f57722e78b6eb56a192cd32544c1bb93ef492fe6d7a6216b00000000000000000000000000000000189b9792982b51b13cc3fc1691e0569b6c8d998168d3a3376e63ca60de4b30a84ce8d04fb265bdcf73f158d8e316bdda0000000000000000000000000000000005b99948b635750040b5b59568f0e8bacbfd512db2ae52c5032cd23eac18ad58d83b8f78cd26ae979ce2abeae8e1f3c3000000000000000000000000000000000d0b6561a49c358101b30f714563bfefc72e0febea857b1ce78cfeb9508b0108c2089c9b35cd694bc8c0ea8afc8d047e", "Name": "matter_g2_add_78", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010192b925fca096682acf138833b12d96bf97c9a2e69e4266eaaae1785b9008f36082e23e2d42341427edce24449935f000000000000000000000000000000000d5b24a94adadbf542aa663114096bc670e1b6c99f3b661f55de121922452534faed7f68d6b431fcf6f3e379d7acf6b6000000000000000000000000000000000acdbcae49206b749d8c0d21017a33e689ebe26804d1fe7c863a2ea4210c3559805dcf73685702bc56e644b4e02614a9000000000000000000000000000000000092309d684fcdf44bfa321d473060dc2d8a8c66c51419894a3fbadbf1b56179c31dff25403b970d543f1dd0e19e56cf0000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000fbe421858e4109c51de57b77da4f9c4c1f950099532d9e30e2f7a8b8b4fb9f708cde1a497050d0944e089978b15321e0000000000000000000000000000000019f48a0bf0f27df65ba766a65e831a0801a4ebcd1995a6002a803f88aead1503b7c39fde8ef5c4672020307241958a88", "Expected": "000000000000000000000000000000000bbb59d3e6b0b4d86ffc89bbfcf543a5b8ff922f1999a1e06c501a734b19dabd54632132c865c53e5287f69f06942a58000000000000000000000000000000000a3bb94431530879a7fb46b317d4f3d65b5a790739b396c78521a20e1cfad9c44248c9576be11c70970a49a1914ceffd00000000000000000000000000000000198df068ac5d3cfb9bd6896ab64495f4b9933a72872679ac3a46764478f043e9fddf17a7ef85fb72a8dc1a722804198400000000000000000000000000000000155c1a9db0c90634a6d214e996b13252bd4db3a4ab84ca7456ac3e7899e6fa096904a90f1150026307a1cac8de00c6df", "Name": "matter_g2_add_79", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014441b14765eee30e8131a7ef62c3b59370f2f6f0dda20fb2a3654fa09492bf695de1d1a8f250bfde3c7d2ed805ffaeb0000000000000000000000000000000019d813f8be2519e89d42a9fd3fef09d44a996d6a4713a9c224bee10f0ebb196370d6231fad810edf9cb4c875f08357890000000000000000000000000000000001a5abea13e909bbefdb51ddc699614366f271b2f6490ac8efcca7759833f3feae11057ab1b9ea32311e7b6ea6de110c0000000000000000000000000000000003ac2bf3c5486ca176e34ec5212165cbe04fc9e8c375e3e999a31fe014eb824ea3f2d06b9cf8b86ce3a76960cf2eb4d70000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff148", "Expected": "0000000000000000000000000000000010684ea0303f0e76b60eb96c470e1f0466f1f2b073bbedc1a0c0df1d2f6c66d77cb90ef9bfa4fef6a6a9eff8f5c66f9b0000000000000000000000000000000010e7ced79bbf01ae9f65d26894c73a905514296f19561ab4d00c0cde31737d01e7b4e8b8e6050054a7a17e8acb74d49d00000000000000000000000000000000174f771a98e262825ff2db7571f5f5475007d2f73a2c265f24e2929671bd173596b8b163abd46b868a644dd464dcc7cc0000000000000000000000000000000001cbffc9bb3195672ea2d998b169f853d3d4b4e147379329b1bbe69ce76d08ad78f87fdd876af227a050c31884fda084", "Name": "matter_g2_add_80", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000598e111dcfeaaae66d1522be2a21131350577253a3f33bdd74a04b0bfba2940e73b62fefa8f0c34c4aa91b633f6bdfd0000000000000000000000000000000017fefff7d94afbeceb33714e9b5480c3a2f3eabf9d7f6e8507ae54cb65f69b21cd7d04d23f24e3a272c589f572b91864000000000000000000000000000000001652e3f5a99ba8dfbcd1f90de955ef527947642054be603c1b84b24bebb579b78e2a0be426ec21d32783a0e55f0178dc000000000000000000000000000000000a6c9ec91e8bc86ab198416cbc76239f0ac0b903f40310ee1f2066b01b08191538ca913c2736f53f23ef37fea13d527500000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f", "Expected": "000000000000000000000000000000000fa306f630d06c801e0203525c75fd6065bd12bcb3c4d45c7e02b597f85a53fae1e65a969feedca75068433547e4632d0000000000000000000000000000000004b1bdbc29f19f6484ea4648c70eaa47cf5bb07bbc255bb72dcf68a7b661de433dafb682d51321369cd3372288b2b9c400000000000000000000000000000000136671654b24e1ff2e8223ba747ded51f5c826b6e2c0f02e2865fc35d15045f41952835800406f60f966d1f241914726000000000000000000000000000000001007b5e8ed7f0d25091dd959d89732e9df02561a829ce013f5ad1adb8d6d828a8ce87b52d39fda1b5dc2b581ca420e22", "Name": "matter_g2_add_81", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000072e022c168461905f798e87425f2eebb517e473cef98c255d0fe434863ef5811920af65bc946b29d489b5dee1066c56000000000000000000000000000000000e7a9872caa82d191f6014c845e1b3ee4ea1ee89852b546a2c85ddbfa3c1d4ce99002e3d7732ccb8cfbd57d550285ab400000000000000000000000000000000144be65db373f6401d76e0ee64e51076b861e8fca596dd6a7f3b5735c23b0cd13248404fa0969ecaa701663a1032f48a0000000000000000000000000000000014c9e9c5cffc4518889f7742440053678ff1d9fb1a1a103d0c1f762b10655bd5849ce98f4bc5eae80bdd9e767aae452300000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf", "Expected": "000000000000000000000000000000000fb74d9ad4de11df81c48d10b9a14fde8353ac47dc902b4420be4c086332be480552e26fc42b7c0f30e34f740bf9a4e6000000000000000000000000000000000612a7e23bbb525f91084b122dd4cfce4074c9e6eedaa7cddb58a14e0b1eccc2f08296baea3eb3e003e576fab7c557ea0000000000000000000000000000000016dea145df47a2c5262893c273c6158ee14d44c3740981c161624a6e9ebb982a52c1eab6160c3849f2bf3821d953f4c3000000000000000000000000000000000e920661772b8b737f1a663badead0e89aec4cbb86e6dece5d4db8a673e75b844bfe81662dff671658cb8386c16a7f3c", "Name": "matter_g2_add_82", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000948d0f0c20715f8658e1f2b4f9d32d851e584287225a2f47735a1f4c241b07f8d7c5dd8c13bcdf84e97d49817d4d88a0000000000000000000000000000000013c064548cb756b48600dd535af8eb5b9138f984bac0391df2e90a204fcb6c36017df910031864d802a2ff719856b336000000000000000000000000000000000000b7eeb7c9a01be88e573f196c2a531635baecbc8cff9af385455af3757301436686596ec7fe3618af26953c49f7450000000000000000000000000000000001332f4dbd5461ab9e2c8b3c19c6ff407a071018c92d2c17c1d1d481c24565276c0f55eee8692016c1fd76d70f44627c0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77", "Expected": "0000000000000000000000000000000015930559743b21acaf390b557fb960d3021f3cde80630d8867a063d445f860c8a01037057de1929be16d879416b12a6c000000000000000000000000000000000c6074c54c83f717700f61c5b6bfc641502121b59b196a1f8c5f2945e5db1bca0d7a94fdae96bfeeb6204c8c3f4d048a000000000000000000000000000000000b3a78454479c0990e4c65e4f831606c7eeeaef0faa86596350c9e43e84ae959a0f32c8d03d1f631d9b2ecd046efcda6000000000000000000000000000000000aff797d7572f20b06bac75bcf8cef879df11599ba7f8b86eaa28692d1239cff22841b66e28662309e81a6a599e79ddb", "Name": "matter_g2_add_83", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d3ee70610b5029a28e586f0f3e65bb19a263db3438710fcb8073e1b25f83db50eb5bbb9d75cb20952a225023f747baa000000000000000000000000000000000682f7d5cf9d182b20ee88683f3915e8c9b03074a373e573aa57232de4e997bf155acf680e365aa0988989dfad102b2e00000000000000000000000000000000143962963e230a9154dc328f9583f5be6923a3b10ee7b1d0cd5f5cbff13913d8ff78ca315be7387900a50b94449884c0000000000000000000000000000000000f4f934b42452d41cc20d7b1ec547bcbcbcc10f215364ccf2b864db23a09d06e94c7a87165dcb691f4975323486757ad0000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee41", "Expected": "000000000000000000000000000000000351bad2f1fd9adc84280515c2d9e538b69dd63ac93514987ecace75d6bc4585199b742eae0d357d587924333721a1d90000000000000000000000000000000003e495b544aaf19a6415d5558170b8686968dc922367c5c8c212fa1f2785535fe0e71498b98b9a39c8b1f2384956170a000000000000000000000000000000000c7040f34872eea5f98ddc78737dd01fdafe75081cf66ad5c7c900674fa90257105b4f4fc59103dd5b92727a072ae462000000000000000000000000000000001312bdd27ef038d4a89b12c86281975bb34b435d42642fe0732709baf55e9a0ecc0ede8a4775a33e880aa2e1fa7b7ed3", "Name": "matter_g2_add_84", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005f0fd4080e26971ab16d33aeae04220ae23781da3179e38190082f1d167514bd73bc8ef976a2f333570e9f56a6c05e6000000000000000000000000000000000e159905d29b52ba61575c3a263093017783e1028b3701ccf060c165ba33a765b5265a9b1681c1759bfe2c9c401275e9000000000000000000000000000000000c5ac0bc29a49a7c37d772954da850e6b5e301e230552be9a94017d770ebe2cf4dcfaf104633623e024aef6db57892900000000000000000000000000000000002228e7f42a9409acab49cca82cacf306f6c6c29fd9f7e2ed12fef2d16383cdb7bb2b39ad598b301072c615232db1fa800000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f", "Expected": "000000000000000000000000000000000d521781f60198341d116fa5cd9e2b5c2fe51f91f6c8318f351df007c96086f6c3baa5cd2b9b4f442305695dd9b01ac70000000000000000000000000000000013454fc15b1d182bc98d75947547b3bbebef6d5e2d38ed7c67d76eee8da89ea2be19280af4760282fa7576412d5f2107000000000000000000000000000000000d866015c84de74c24dde252542d0d3823f435203c71cda140af235d88f3f4b736e9d75ec32c09ab73bf74083e76866e00000000000000000000000000000000147dfb5f53a9cc61b6788c911dd8649c09cfffbbba368c1872a31cfe3bd6d6427d7b00163d39f8e0b81fc4c40dc60b87", "Name": "matter_g2_add_85", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000180569ce03e4a0155285e733adb18fbca71225507a7adf01cb8e8648891525305e92087f58378f4fd8455d5632ad660e0000000000000000000000000000000011ab84e42f10154e306a568d7cf7bc381000f0add0500cb508f695a3b283ea69d140aa0ad48fce2d2d6fcafe60761078000000000000000000000000000000001136c3016474d6f475609606e8d0269fcdab9fd3188a512681cbc41eedeadfa3b3d9355e5b4503e8b5c3665e49fdf3ab0000000000000000000000000000000003f56cba1b9cb4302099b16b09c2602dfab80d1151685ef78e5054cd454b319adf8b5998053a5b9fddcffa020595e3bf000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c", "Expected": "00000000000000000000000000000000059fffdf2d79b4a297f6912e3035cf0b07db9372f3485150e00d60bbe2e7d86f45b5c2ef062dd92c7e8b1e2be5e9bd140000000000000000000000000000000016acdc57e7231b020268373ddc8b8a7318ead02a8c7181165ab045208409373eaf57ace9a6db1fdedcaa477c7a0ff6f40000000000000000000000000000000012fe630f7de8ef5a129b99faff2de080849bf3b59aae1af042c29b1cc49c8825a4f28c4ccffedc6d568f306416b5bb90000000000000000000000000000000000d86ab3e49ffdc7c2485ecbd00256af83e7f3f064d212ea91245d86ca75e3c7f28b42fa9496a5ccc0514cffc60c9fb83", "Name": "matter_g2_add_86", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004d79dab9eef873f3415d66172bab7166ce0c71f322529bdeffa915c1b0d3fcd645c91dd3450ba61593ffecb95edb91e000000000000000000000000000000000d611a207d3222bba199fa083d0459675cb5fa00839fb4c9034ad868fc1e79d653c18651771431d6fb6b6b5ce8cf6f7a000000000000000000000000000000000ce802ecb106a4f0ca4efdcc058dd0e29deb6a5d30a2c15c8eda896bcdd3ac19053c10105328d239b26c5ddbdb3a95fc0000000000000000000000000000000001073e142621ecbeff6f81453660362545751f992ffeec3a83477fed3e6215a709ffe0d17b65d3369f8f3913bf000e84000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb1", "Expected": "0000000000000000000000000000000012ba9a8fcb69d15eff147f663a5d7927b6f3f79330eb9ee625e0100b146597554debfcf97a3afb51387a73554522ed0e000000000000000000000000000000000a63a990d6454d4db6d58642eb3489f79e517fbbcabc06f2eaa00c4b6f9a07aae97991f169d90af3461b7a62db276e00000000000000000000000000000000000a95203a1628a6ae2551df832f7ab94ffcdbf985e4c9744e244214c8e8b8079af05a9321d1e49b7240c2bdeeb7b783280000000000000000000000000000000001ec747203be73526d3f943e0af814dbede34020144bf247eef9a6ac2cfc83ef63f18a73d3baae18bfd8d5e83d0519de", "Name": "matter_g2_add_87", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bd84f04b3858b1138b1b429c7216d5d1b1e99c1e0fec26440d59b1ad79788c2d5583122c2ad769fcaa6d10d816a1f1e000000000000000000000000000000000387977ed1ce5da51dca230531bba53d17d3de5d593ec576cabfe6463d5164d7153025dbd4cb3525c4145c4f6b85fc76000000000000000000000000000000000a19c943a90fec6921367a2edc5bc38a5c59839cdb650766a2d2d068242463dd4460bd1d0e7a7fb0e3d2104704b8b3730000000000000000000000000000000011d99d44b200feebe00bd42809e3f67a23cce88a07165416cbfaf4db14420f99e54d62db4280d2c99ca0bc3dc41eddbe0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc", "Expected": "000000000000000000000000000000000eefda9046a950c232c6244a79c33e7135d0896bc57839a4f971030220e3ca8196cd0ad75269f3cb5586a384dcd17f9f00000000000000000000000000000000195ce623693996f5ce9e45b4e285adb969e6771e6b0701fb5c95715523c8cb93aa641583821a3b360ad6f4ea1aedcc9f000000000000000000000000000000001553a4d0f965d26fbaba56294591935bed63c84abfedbb9d5c61f3d43484ea71600935fe3c8b6b137d7a9074d907e86c000000000000000000000000000000001673c42c88e4acf8ca38680694b80458f988403a4bd667468506452303000d13649c4f610b738a94ff88b65053731c08", "Name": "matter_g2_add_88", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006a186aa584a466a860849c78e4922889c95a4ac6f39c99029fbb422c43d699a8baa51aa4ef51ff99557babeb3e9506800000000000000000000000000000000065fb15b5a0923bdb52dbefc7e9f1a898e32f17d610bac829235446fc5e1913fffc8176e0fbd33091505761f1d06d8920000000000000000000000000000000008bd358698fd073f660ed608462cfcef1da9a59b10905f1d98c4fe66958e56802814906430c10fc25a4d351d91f91cb0000000000000000000000000000000000a53638b1b6c6eeff468e099446300ca7c7bd899c6494682d14fdabfa9cead0bb37a0325d99e7d0ba6341cfa1d257ba800000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed", "Expected": "0000000000000000000000000000000007145ce58cbe48405392edda6022ba8942df055ab582ac402e7c9a0a951cc6a38cd147903f042273e736f30849996cd10000000000000000000000000000000011b457ba464ce818a34a11afc3c0007908091fb528836691e6eccaa9a23ea90cdc746769c4b7ec73efb1f2878413c3b70000000000000000000000000000000019ca519fa6a91cb7e83704daa9b92da9bb70b003f9e9bfe9f323430bfec9b19b01005aa9fcd19d5b1ac59dbdab0c0d84000000000000000000000000000000000ae356f5e5de0d7662bab8d947662bf87d792a3438ed477cf6ed4b27c935b1dd76a5aac446d4dc36db544d4aea40b505", "Name": "matter_g2_add_89", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001070b98c6348a67e996626ec2752f45e4c007e9c9668459a777c03fab633c10236a1c5be99f3fd950542d5648ef9e88400000000000000000000000000000000073a564401cb1a3a53334c0a55da261814d27b86ebf40b02a76b20973ba2db92e42c138ca7790261c2d70401c984bf470000000000000000000000000000000004212d8a9e4b01f5c6814a88561c2c6143eea61327b031a2e0e4bd056c12dd7098fdfe4d1511bb441ad42b55b584a7bc0000000000000000000000000000000005c5d23824b0fe05eb962194550681c57c1566b315efa8ebc90b3593d7d86ad18328baab8118c9f47eccc0757588591c0000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c5", "Expected": "00000000000000000000000000000000135c42c10ef97279e3d152b18cbb8dac11ca8c805dd1d80818851424f592e7522589ec7df6748b5c72d0808399e629cc00000000000000000000000000000000083ddf3843434937e05ba9e101096371fd8fb34f226bcd517716200003ab9855f7aea94980c57a6b933494cc57afc562000000000000000000000000000000000be9215d936a49538442189c9a0bd3be07d4b0b1d14aa45afcdebc1fde17d33b66f7dc36da1ea5411549577f5a1967ff00000000000000000000000000000000176a4a4962c4af75a712e5093ec2cd5cb5c0433aa0657809dffbc0bc02b1ce303ac084f39a5721d482d41412d391317c", "Name": "matter_g2_add_90", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b1b3053774ad5515a20bd4c556d2b3ba95fe74fd0c955069c7f933dfd718ede90ac295f5a675f1c29dcd9701978353700000000000000000000000000000000145746ce88686021a0635bf6f0aa2f77c48bdb364cf4ffa804a57f95bd69d24eead05fbee24021c1ef57e1c7c7b894b00000000000000000000000000000000010ec4795a0762b86f3b83de1198698af67fd1b1be3ddef48f35cf82bc96d886fbb4c75064f51a9cfc5f61630c95d0ad1000000000000000000000000000000001465e31f58892466b8ae4b76a239d9f8d1ecb1834886344013cd1df0be13591798868d224d38213a6d75b02a1fde0ff200000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de", "Expected": "000000000000000000000000000000000bcd916c5888735aa593466e6ab908a05af528f34a7901fb60feb1f51737c73612436c192dfdecf927019724ab2a9b7900000000000000000000000000000000187d4ccf6c22381d0c40c9d7820ff8efe6298c6dad0caa25402412661737cb482dba2719c3a50ec08cd022230952dfc600000000000000000000000000000000164510d4f2cf1e14e039561f1baf82bea678d0065e378d5bb7443fa782e6ab2a3bf7e4ea125d6415a8277c60f5346468000000000000000000000000000000000281f2e28b73eca4db9966456b75de9ae3830c74ac928fc4c36b4aeaaffd47ee587d948f68056df2826ca2775415a53a", "Name": "matter_g2_add_91", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f39e731e6ddb7496448c912ae314e833d28208252c7f8e27bcf7eeaf1da6e2310538b4ef0d55401c6552e91fd70691600000000000000000000000000000000069d3612f924961f827497028737000513548ad8e104acee28f014e730d4752a583cb9a893e6169b71966a1c4a4ad2dc00000000000000000000000000000000090899907edcbd336bd4fdad0dd67c578ced4481a25b864b32aef920842689a2c23265277a6e1d4a1dc1b5047a9f79a000000000000000000000000000000000055ba64e2502baf68e46c759fca30247a080464eda2b32e7cfe539e545d6aac6dafb731c2c45749e50513979cecbeb5400000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157", "Expected": "000000000000000000000000000000000cceccfefe04f94e0b67b29b5df8007930665006cb5a59504c3656b8c0bfb52324cdf50fa2722ce15b0ded0efa7fc85f000000000000000000000000000000000cdf34c330c0125f524f0711197639f8aca3e7c435f8c5ea30b78e9622c4bb72a7e584980cb4c3c6ecdd0689daf36b6a0000000000000000000000000000000004b1505d7fb65f6c06ef23aef85b16f3d991218187c5782fb635ba805da463cec9cfdd670c53d680c603adb827a4460a000000000000000000000000000000001104af6bef6482ae64b3b6b39664ec06c39bc18fa91b7b4e5bfcd444c827bab30ef548b28ef5487582d88fbc6d7983cd", "Name": "matter_g2_add_92", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000042f1c8b9fe81cdcabea047d0998a1354ce09d62a14f1d0e9d188e2f35f2e1845c2b090c5e157595b33108c67e6c184c0000000000000000000000000000000018e69d3564d4ccc0306e1e6b227b0f961aa9afcad59d4ee1737f980dc876609c59a4c6a3506f987467beba0764b857000000000000000000000000000000000012ce5883156588cfe0f4838f819f985b09f1eab40a5ea8e30fc5d70d029a01a4537641248f4c21dd203909e0170737c80000000000000000000000000000000002888eb9778a4045feb5899dda258657b9f41345731ba630fbbf186b3be4b58ffc7f48abb65b693b573a73f85440a7a70000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc0", "Expected": "000000000000000000000000000000000e1ef3003fe3181f690224cbc7008856e1251430ce3cff56a1965c89a892604398f5101d1bec7ff1590b0cc3d23b854600000000000000000000000000000000185b4d4b5fd8313c31542bd1bac034046ddc705b41a034a00570181503a6ea4c2d808bba0478900064270fadf3d655920000000000000000000000000000000005bed63ab9898b89f92027c04ba256569e6285c851753e12760129c98899bcbab34b62172906a1ea4cb056d4d0a5717c000000000000000000000000000000000961129a3e212c7412018d7407d7ad16412feba8c138f4f6ba69daa1a25c6b23f3466bfde6f5f0d09ab67248a2abdc68", "Name": "matter_g2_add_93", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000051982b46a819c74105cb36da871fb2415328a1531d155856f6551bd043eca62ddb61f24af429edda830fda31e22cd340000000000000000000000000000000006449e5bcdb5619aac542f6633ee3e06a4fd56a3e1ce4034efc608131ff6ead70ca63e70f494f519d5c577ae7119c8c200000000000000000000000000000000153f4f5dddd5801fbf7f88a735b9170d24d5b63861d50cde9644579dcff277cdb0d5fbfc3b3b819a1172de05afb9135b0000000000000000000000000000000010fdea84983fe6c08cdc4b4ccd462bae2ba791ab5209363b10b3ef342c9a5e92184e9d8be1419e3d88402bc05bad5fa2000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc01204", "Expected": "0000000000000000000000000000000001504c47ab0c410b32d5f1fe3d3996dbf1b21c5ef5aa3a2862a9d561b419f818f0b32b8e931c65fffc393ce7beec70ee000000000000000000000000000000000217e9fddd2551a171a13183ae3aba6bc5ce99e8f3587b92a7cffc738b478d8293b8c71989cabf9a55c5f5077249345d0000000000000000000000000000000003874de865d93650a95af4e153fe557c45bfdc4837bd6e209b8f05ad12b8fdee6432675cd92fd739b7e98e56e7ef16b60000000000000000000000000000000011303c0c7ec1f434cdf07c110da5f0bcd85935c3a0ce9fdf5546ca61edbc2d478562dbd9aa45a5f8d96e033feac2fdd6", "Name": "matter_g2_add_94", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009b011f793d9a939d916d058ffe91b58138820a646cc450389b3074ae3715d06ddec1075afecda71c65c7ca085210c740000000000000000000000000000000003d4d20f4b93c1e90a0a06bd534d8b4fd64e4c4aba77ae42cf4c5b2bd95f8b02ec4069ea246ff46404e6c9eac632fbac00000000000000000000000000000000051e88c3adfd4d6a02d3f03812362a6cfba3a6c69b9aeef75b51106cc7f1750293d61e31f0ea29b5d7aa56debb6d2aff00000000000000000000000000000000086d9c4ea6769cdf49ffbbf7351023b4aea640e8c90f9291222fd0b5984bca4d481bf7e10df921406a34804e6a09f99d000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6", "Expected": "00000000000000000000000000000000101ed22b16502de0d83303134a97db17ce956faedf47256a9ac86004bcd3ed112a71328a58f98a85977a7f22eb1352c3000000000000000000000000000000000e841a88d10493f301af54c5fe07a31ef90de106a6c87d5631b6967fd017f561a56176a5f3544dbb34b9f94040ebd2770000000000000000000000000000000001bde3c0076f26973651cedd3da97c7eda24451bda856026d1e22d3b65c66a3fcbfbf506b4b664b5fc06fca2d712d8a8000000000000000000000000000000000ce553ee3b7d5389798cdc5af8569aaf477b5b74ca1138454dc61badcf3ecf5e0ee8457e374b5735d0b8408b04fdbcdd", "Name": "matter_g2_add_95", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010d48bf523f3909cf90aa58a9517ef5421f1212accd5e8a0f830aeb15a587e215ca9c340bb846b1d0474e43840b2af79000000000000000000000000000000000cc1a3976caf97b9d59f448f6d9f413eef8904f360c0cf912fe942b38d7fcc637a17038973a133608ae769d3e389b18a00000000000000000000000000000000069a6122c6f0ec68834b7617c755a7eb33a80a25acf95859da5ff03316447182f122d20d993b04e79b6fe859b7adf5a8000000000000000000000000000000000058c6f8c297524319bae6722e0a957d1ba0f75ee3a8aaf06148641c67925d15780e419a38ed7e07410e82769da74f2d00000000000000000000000000000000030dfbb89bbe5c14a7a55e68edc4fc38eaee9fb539a6b2f941264c7dc295da5712b0af0f2bbcdb74f785dc9ba038b0aa00000000000000000000000000000000132b4e02fda605a69251a4a6289c47536f9735dd90908ed1fb619b3ab808b3a1f1ca3fcc8f4b35c9864ae311c15747f80000000000000000000000000000000005858ece0bb09e55e012450551025ad2a6d93a15d29619433742851a62d987e7f8bfa6c6faed76493a27060ef5f51805000000000000000000000000000000000dd6b393e6d1b8d546e3f5ce69bc1737399e6ababc628f25734030e10d82b5e9370edfb5da15566d80e23d2fbf8aad5f", "Expected": "00000000000000000000000000000000182f90f5d3ce3f5ff2d91430376144583247def83b3e83524094d57c0f1be98b1c4946964deccc25fc303d6450edfbac000000000000000000000000000000001844806f711735c5ca18ca48e559a9e327b87b91d22a5ef161da7874668130e21a9499728fbc2c88366bdb59f8ced0cf000000000000000000000000000000000815e7cff14b4ceaf26d1cda5c267f432fad294b6baa239b65d886ffb039321f9e24330ae738a35298c6d1ec1ce1c95f000000000000000000000000000000001188a4a2f0920ddeccde1a47a0636aa7c404fd77fb9c828e4fdb5406df80ee6c258c2d4a89dae5e2a2b05210df9100d7", "Name": "matter_g2_add_96", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000156ca5e80be8c8c03a5506ce9abd22a9d4958c372678c0caf6f1329898507dfcb1f06a9464cf080bc6881fa5b7df1ebe00000000000000000000000000000000088174d486b4086b931010da298a399e15b60a113e08f571e096d3a4e94b57b3a684711318796eeca9319119b201abb30000000000000000000000000000000000b96ff68505c088cc03a1c2dc363b05bc8544728a12b29569bed137780523123eb17e68f4632383c252d81bca0c5ca9000000000000000000000000000000000486fc6e5224c5fad56234c41856e60bee4a6c1046f673bf7d5c1bbb603b141fc91074da5f9d3d41b796a2ebcebd9e740000000000000000000000000000000017032b16be8656cf23bfe0abc8c9e6aade223fa9bea6fe25f95a025da79cea6adf38536eae3859b25ad1af1756b639cd0000000000000000000000000000000010975ed27cefbb43bafad0fd14c87ada8e84525e1d199fdf1e77caa0b718214b33e547a42a040ee3bfd51621a20d22fd00000000000000000000000000000000133d29aa41f92de37523d281eebfe91103f017e5fb390f6bad9a2a4419fa4702bfa04847edbca1da96eb1ad563a92c8a00000000000000000000000000000000014af850de7e800ebee4be1a33c7e3b30aa94106db7defa148568ca3c8d82edc97ab5769ac40162d3728687cdac201a5", "Expected": "000000000000000000000000000000000cf42f2ccff2e0cdda7e5f1d7652680650b4afa523c8f9a554ec18b905c837a189fff73982cbccf903ea492ea902b87f000000000000000000000000000000000d38219770f669557cdb623f2476b5f3f7478422b016123bf86a17bf75848548d1a1ce96a292637b8d52481321d80fbe00000000000000000000000000000000170d8722b824e3291b570ba8e4f9279c1dccdefb95cb5b7a94d27ad8a93513737f12d18ef3153c4e12b530bc457af34100000000000000000000000000000000021aee9e5f578328caee3177a4e08303c3b5533e288dcb75f94992db3520a6da16f4201e60367240b29c48d175942cef", "Name": "matter_g2_add_97", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000121fe97c62e068988ebff21d8129d52aa903afdbb62862c7fd99564d9ad72182ab1f3a1100223ae486cd76f6938e123f000000000000000000000000000000000968ddedb04f52140160061828b5f88dfd09aaf37df625ee6f66b9500d6608df31c7edf86296eccf8f9918b051a5e4df000000000000000000000000000000000b7491cb8f6252e3861d7160feb0afdd736d27886863ec0909a7cc711a9b71aace18b17a00a2999dd57ca1a74f148516000000000000000000000000000000000fdb280093ef45b12b694ca3390a865ee18e4c04b231e2c98cc28706d4cefaf4e654582ee03f34ecf1dfa9674489d55300000000000000000000000000000000185aefe71f24281e5b03dd41e6d6d45fbc8975beb175118de7568bff0a9ccf917e9df97dc26bca16e8da06b0e9a8e7bb000000000000000000000000000000000015b326d401b827fdf556e4a24a3dd6c8036b1c849751b5ae3c3728cad88f931b06e3a345523a723481193f7afeb67800000000000000000000000000000000054ca16b4c87293002c31e64ad303e8f040e11de8b45c5fb9aca9dbec59b29dfda8532a8ef5ae6a92ac8ea90ee4303e0000000000000000000000000000000000b65a233a7731366cf24c801724265215a8626b1290d86c60bf1e74b021b0b44d7d6552f936fac7b5e60cf1feaa1d82f", "Expected": "0000000000000000000000000000000010d1b2f595166929347e06c1debefead06334f554dc31f320cb844abdb1810b5f7c4b933ff8072dc03d303f4a6d0d09b0000000000000000000000000000000013ab41dfca0a7cb0c58c2c19e02f675a94d9e73312cfe2999dbac34e6a80bff9472506b48690f24ad3171ad495f445420000000000000000000000000000000015bfd0db53fd4da538caa3aee7a90a669cb84460365696ee79b190d09a6d4c3f08965de7fff4efeae435db52b97d213b000000000000000000000000000000000182ffc4304b911b47b092ab678edd63ed5f5e8a9069daf9247f3bf9c0dd149cc9992728a13b0a236fc9b37714b35882", "Name": "matter_g2_add_98", - "Gas": 800, + "Gas": 600, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010d001a09cf5dc3276482185f26ef3f75d28cd6d2667eb08a7fe06c03b99f3b6c4d82390739b6867a314291cc642a8b2000000000000000000000000000000000587846a460b1f37c2e7f491f9a097b4e86e1943d9cd0999313f65627b3907f09b5d5ac1be376a313a959dd136f7e9b3000000000000000000000000000000000af439695556e86b102926d3b40e3e54cc84464e120de3b4e3c5541a6a5bca44151fb0594009663764c1824518b13f020000000000000000000000000000000003bfd9418c1e57269e222152d321b83ae090f216cb422956dd1fcc464f68526cb4a05cdaefc7bbe6e81d4ffe27d64db400000000000000000000000000000000085dd8bfc00ba517dc8d7ddb49d711d35bd36f9fe3843689019e779624a032d2f023533b8184b73042d1a1953d2885e50000000000000000000000000000000009ba8d5d36e6efe02097a3206bbed68529f0cb9875ab81deafd886d9243bfec8b403d2abe713a2ec929b93305dd2da220000000000000000000000000000000007f8f90ebb2771136a92023901ca85e87fb7c8b1a40f88ae564a124bdd0ff0bc27ea98612a817e2c871fb4bcea3bb06600000000000000000000000000000000152de417d02f1d14e5899201db8fd5db8ecb40ea8d415dcdedce8ac70c28d851db68e9aef94506a50ec28145547a2d68", "Expected": "0000000000000000000000000000000017555399f979745302f08210de5311a6401b6b181100b3bc6b6d450f0f62079d2f02d7badcb164f50dfc46a975cbd6720000000000000000000000000000000014aea86c06e4c1fbf0711a8cfced2544c7624abc7ae7906cd992bdf575a702540c45c2117e221446ba09960cbc9048ac0000000000000000000000000000000002fac56960c4989a84e02ce36e8970c2e847ee45579d31ca77f042bf96505af574af822da084ae64b22ff876610ba9a5000000000000000000000000000000000a481cfea2aef8975c80a297ce5a185dacd25649d41f8466d3c63d786e3c264a8e4ccab5ef6b80ab1260e86ab6d5b3f3", "Name": "matter_g2_add_99", - "Gas": 800, + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Name": "bls_g2add_g2+p2", + "Expected": "000000000000000000000000000000000b54a8a7b08bd6827ed9a797de216b8c9057b3a9ca93e2f88e7f04f19accc42da90d883632b9ca4dc38d013f71ede4db00000000000000000000000000000000077eba4eecf0bd764dce8ed5f45040dd8f3b3427cb35230509482c14651713282946306247866dfe39a8e33016fcbe520000000000000000000000000000000014e60a76a29ef85cbd69f251b9f29147b67cfe3ed2823d3f9776b3a0efd2731941d47436dc6d2b58d9e65f8438bad073000000000000000000000000000000001586c3c910d95754fef7a732df78e279c3d37431c6a2b77e67a00c7c130a8fcd4d19f159cbeb997a178108fffffcbd20", + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_g2add_p2+g2", + "Expected": "000000000000000000000000000000000b54a8a7b08bd6827ed9a797de216b8c9057b3a9ca93e2f88e7f04f19accc42da90d883632b9ca4dc38d013f71ede4db00000000000000000000000000000000077eba4eecf0bd764dce8ed5f45040dd8f3b3427cb35230509482c14651713282946306247866dfe39a8e33016fcbe520000000000000000000000000000000014e60a76a29ef85cbd69f251b9f29147b67cfe3ed2823d3f9776b3a0efd2731941d47436dc6d2b58d9e65f8438bad073000000000000000000000000000000001586c3c910d95754fef7a732df78e279c3d37431c6a2b77e67a00c7c130a8fcd4d19f159cbeb997a178108fffffcbd20", + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_g2add_g2_wrong_order+g2", + "Expected": "0000000000000000000000000000000011f00077935238fc57086414804303b20fab5880bc29f35ebda22c13dd44e586c8a889fe2ba799082c8458d861ac10cf0000000000000000000000000000000007318be09b19be000fe5df77f6e664a8286887ad8373005d7f7a203fcc458c28004042780146d3e43fa542d921c69512000000000000000000000000000000001287eab085d6f8a29f1f1aedb5ad9e8546963f0b11865e05454d86b9720c281db567682a233631f63a2794432a5596ae0000000000000000000000000000000012ec87cea1bacb75aa97728bcd64b27c7a42dd2319a2e17fe3837a05f85d089c5ebbfb73c1d08b7007e2b59ec9c8e065", + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2add_(g2+0=g2)", + "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2add_(p2+0=p2)", + "Expected": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "Name": "bls_g2add_(g2-g2=0)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000a6296409115572426717c73668335a949829d739cff2cb4ab043710d28f8e772f6ef41aac4806c9cb273c490384032d000000000000000000000000000000000cde4e850c721fa94e8890d500e3655b442d5c0dc4fff1b694c6f8dd68f6d8dc1bc3251a37d27e7af96f65a96278265a", + "Name": "bls_g2add_(p2-p2=0)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_g2add_(g2+g2=2*g2)", + "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", + "Gas": 600, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Name": "bls_g2add_(p2+p2=2*p2)", + "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", + "Gas": 600, "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 ee9d50fbfb..9e47f64b8a 100644 --- a/core/vm/testdata/precompiles/blsG2Mul.json +++ b/core/vm/testdata/precompiles/blsG2Mul.json @@ -1,730 +1,79 @@ [ + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2mul_(g2+g2=2*g2)", + "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", + "Gas": 22500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2mul_(p2+p2=2*p2)", + "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", + "Gas": 22500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g2mul_(1*g2=g2)", + "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Gas": 22500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g2mul_(1*p2=p2)", + "Expected": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Gas": 22500, + "NoBenchmark": false + }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000", - "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2mul_(0*g2=inf)", - "Gas": 45000, + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 22500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2mul_(0*p2=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 22500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", - "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2mul_(x*inf=inf)", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "Name": "bls_g2mul_(1*g2=g2)", - "Gas": 45000, + "Gas": 22500, "NoBenchmark": false }, { - "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000011", - "Expected": "000000000000000000000000000000000ef786ebdcda12e142a32f091307f2fedf52f6c36beb278b0007a03ad81bf9fee3710a04928e43e541d02c9be44722e8000000000000000000000000000000000d05ceb0be53d2624a796a7a033aec59d9463c18d672c451ec4f2e679daef882cab7d8dd88789065156a1340ca9d426500000000000000000000000000000000118ed350274bc45e63eaaa4b8ddf119b3bf38418b5b9748597edfc456d9bc3e864ec7283426e840fd29fa84e7d89c934000000000000000000000000000000001594b866a28946b6d444bf0481558812769ea3222f5dfc961ca33e78e0ea62ee8ba63fd1ece9cc3e315abfa96d536944", - "Name": "bls_g2mul_(17*g2)", - "Gas": 45000, + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", + "Name": "bls_g2mul_random*g2", + "Expected": "0000000000000000000000000000000014856c22d8cdb2967c720e963eedc999e738373b14172f06fc915769d3cc5ab7ae0a1b9c38f48b5585fb09d4bd2733bb000000000000000000000000000000000c400b70f6f8cd35648f5c126cce5417f3be4d8eefbd42ceb4286a14df7e03135313fe5845e3a575faab3e8b949d248800000000000000000000000000000000149a0aacc34beba2beb2f2a19a440166e76e373194714f108e4ab1c3fd331e80f4e73e6b9ea65fe3ec96d7136de81544000000000000000000000000000000000e4622fef26bdb9b1e8ef6591a7cc99f5b73164500c1ee224b6a761e676b8799b09a3fd4fa7e242645cc1a34708285e4", + "Gas": 22500, "NoBenchmark": false }, { - "Input": "00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e", - "Expected": "0000000000000000000000000000000006334ba1e361fd94bbd98f44b75ae9ec00ecb4d3467b5528870b1a1fa9a7d04449f12af90bd4c7a1e3f29e717d6d19d3000000000000000000000000000000000bf4cc1626393956915845ea7ca43d30a59c7196fbe309f2d5ee6de7e40c191d29821dd6aae46abecf634b904de8f7490000000000000000000000000000000014aeb09e252cc74610ab956057d4ac5af95cbea8a6baba9e5062643dc037d6841044cb38b22d7dfb978fe0b58f94cc3a0000000000000000000000000000000000fdcd73452fc1ced1c06e6271410a48dea05afbe889a692905e1baab8d72418c62531aab8b74842b51016f0a9cbb93d", - "Name": "matter_g2_mul_0", - "Gas": 45000, + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", + "Name": "bls_g2mul_random*p2", + "Expected": "00000000000000000000000000000000036074dcbbd0e987531bfe0e45ddfbe09fd015665990ee0c352e8e403fe6af971d8f42141970d9ab14b4dd04874409e600000000000000000000000000000000019705637f24ba2f398f32c3a3e20d6a1cd0fd63e6f8f071cf603a8334f255744927e7bfdfdb18519e019c49ff6e914500000000000000000000000000000000008e74fcff4c4278c9accfb60809ed69bbcbe3d6213ef2304e078d15ec7d6decb4f462b24b8e7cc38cc11b6f2c9e0486000000000000000000000000000000001331d40100f38c1070afd832445881b47cf4d63894666d9907c85ac66604aab5ad329980938cc3c167ccc5b6bc1b8f30", + "Gas": 22500, "NoBenchmark": false }, { - "Input": "0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d", - "Expected": "0000000000000000000000000000000010e70bef8eb893377e7ff92168d7acef11c9efab990fbded728b173b94e1d99e471a8357f16625d353287086543551850000000000000000000000000000000014043c1f00221c439e5febd12724a9224bccf0389914461644daf329208e869b1bf149880dccebccd440b1748d15e944000000000000000000000000000000000f7dee1e7d122e410b29a9eb011ee700c2f230cf8f611e196ec66e153c1fc331175532a8f9b060b573bddaa705430c2e000000000000000000000000000000000e1f659470eab7c0741bc8777ac9fc8dcd11a6f1b30ffb4265e96b879e795a4dbf851d1149429dcab95464e89f334627", - "Name": "matter_g2_mul_1", - "Gas": 45000, + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be9a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g2mul_random*g2_unnormalized_scalar", + "Expected": "0000000000000000000000000000000014856c22d8cdb2967c720e963eedc999e738373b14172f06fc915769d3cc5ab7ae0a1b9c38f48b5585fb09d4bd2733bb000000000000000000000000000000000c400b70f6f8cd35648f5c126cce5417f3be4d8eefbd42ceb4286a14df7e03135313fe5845e3a575faab3e8b949d248800000000000000000000000000000000149a0aacc34beba2beb2f2a19a440166e76e373194714f108e4ab1c3fd331e80f4e73e6b9ea65fe3ec96d7136de81544000000000000000000000000000000000e4622fef26bdb9b1e8ef6591a7cc99f5b73164500c1ee224b6a761e676b8799b09a3fd4fa7e242645cc1a34708285e4", + "Gas": 22500, "NoBenchmark": false }, { - "Input": "0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1", - "Expected": "00000000000000000000000000000000119a5147fe9ddca7123f721b5662c1a44b0964c37a214cdf3a4fd34166e3b25210344e65220c38ec84d0e3b5ccc7e46d000000000000000000000000000000001642dad5dacf4295b871fe9b2787f0861f158807b2b6c01c2dce12ab053c9472bd3cb98de5dc33f40053ff45ce5c9af40000000000000000000000000000000005bb5761602b6639f2ecaf79f2d1f853fbdf75f4b3852b90808b858993a83f8a0da8a2ce7072aa91e3b6b3ffd0b3d1e20000000000000000000000000000000000a75143b9551d4ae41fb8bd71fdba7826b994c65904d9189a5ac5130a59cbb9d8dee0e016735565148fc49823d3969e", - "Name": "matter_g2_mul_2", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a", - "Expected": "0000000000000000000000000000000017ebc9446f8c8e17dfeddab9188d0c808565da29c0bdbbc4138a44ca3196c4564853be28286b66660cda36832d6940010000000000000000000000000000000007f29a9583b4ae83d3913dcd72590a3f20f39eb5a6d36663c1ef433058e76550085b9c01bf797d98d0eef45cc22ff8c50000000000000000000000000000000016eeaeb123b12d1913ff1e50f974228c79f2b995609d2e3835c8e1d68773b0cd484df57b86111cdb75de1e19eaf062e500000000000000000000000000000000002f5688c1286aed42309896bd65d1826dc64dda615238fa9043669806968b8e0e1e3e77ef192b7df540aaf0ed282a9a", - "Name": "matter_g2_mul_3", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89", - "Expected": "00000000000000000000000000000000042d0c1941ae0ed5e8787437ad5e2753bba02185317848e8ec2e425ac954e0efb1bca534725adfe87e8507851ee337af0000000000000000000000000000000002db55ae8126cbe86327aab880381a81205e33a351d172c883b9cc184799866a8db5a6b4321496e05d3ef62d00416d9a0000000000000000000000000000000012c45444403dd62d7be3e7658dd85909204751dd7d085f6edd38c0aa9185d3c32407d8c95bba371b380f788d0dc48e0900000000000000000000000000000000111421c6dd0db595ab731adfb4bc76c84a61197cb023b6f17e7176c443f20a4b6f8cd0a00cfa61e831ed20b3c6a84d98", - "Name": "matter_g2_mul_4", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944", - "Expected": "000000000000000000000000000000000ccdb2a0b670f199a9b61198e6a2ce2117075733e6a1568c53ca493dc3674c6ae85be2491d2ed983f52e2c7040824afc0000000000000000000000000000000004f52450d7e041c561c00200d5b142b32f2df2e2156e4f6c15d6c00e185e135037a1ed6be15e2ed920daa00e2f9bc8da000000000000000000000000000000000f39c38c18f03ce6baf1d016cf32d7387269940280f2e8d21db4da33dbd2d24ebb93ae3dff9f79b015eee25813d677c700000000000000000000000000000000189df61f7f1025fa6fdd0a4708ff1d53db7d414019c4828de2520af3d36776062350061c2261e46e746a6475fdeccb2b", - "Name": "matter_g2_mul_5", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1", - "Expected": "000000000000000000000000000000001388a59c57ec8ca5e68b99631abdafca1b71352ac35003a55bbc415b48b8171857adda31123ec86a6ed9e1060d56aa67000000000000000000000000000000001471913b1ab5bcf9336665d3d44232b4e58da70285b7b8eb1dfd7c54442afb28c339f56e6389f89b84db0879e1ee058300000000000000000000000000000000022101b4de40b7180ea17bb36bad0a668a8def3e7361a96fbfabcfc4cdbe6f607ee4ee80d0eb2418b848ad056520092900000000000000000000000000000000103cda694792af5a51e04b6422600a0ea6f50808ca54423cd4f59dfba633daa5afea49c85b900f52e182610efb62fe7d", - "Name": "matter_g2_mul_6", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c", - "Expected": "000000000000000000000000000000000cf5cb957a752ce9187940f63b13080790348814debf84b91e74fd6e822c2735941d61d50d492439475bb3ea7aa849ec00000000000000000000000000000000012e546ff33dee9875510a68301f46d89e6175f5cd9a6e179fb8599a580e9478fb8d92038982551dd29041d8185c7474000000000000000000000000000000000d52fb57bf2996dbbacdbcb4088df38e77e25598b91bcd5e41eaa27b1398eac150586b142f068d5b498e0ce458d3e8950000000000000000000000000000000012295e1d1039abe7a5fea51a04a34e9e8d44a0f24b8c032680703c119d54274d3bc2e548854021ab027b693e43964314", - "Name": "matter_g2_mul_7", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108", - "Expected": "0000000000000000000000000000000008e4c57309339400ac9b6b5df16972c272d47cf69ba7baf89afa4f4e72703999c5885253cc35686f6c8d277399da2a390000000000000000000000000000000018ad4e1f105f16b0dbb4eb089c51e709c25e407e54b64346224b1abbe15d62fabb231e36a69eb05a9ba7860f772634200000000000000000000000000000000019994d20a7ecc0f234ccb6b1793fa7d1ece64b3e157c579fb05a8c6cfcdd6f5456ac1f4c1beadb69206988ab543bb8bb000000000000000000000000000000000d435e74bed382442ab83ec90dffb91336137932524bfcf9753fa5ddfe038d0b98a045c8ec9deb53172e5662d3fd67e6", - "Name": "matter_g2_mul_8", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f8187672", - "Expected": "000000000000000000000000000000001425890b6c46c5a07a79127de4ddbb751227dca4481ab7c2f601bf22b8f6a149767c73bfbf57ee399c0f2d0b12852a0a0000000000000000000000000000000012cce15f53fdfffb5f71de3567b0c0adea65b9321c85677c574787f7048c1bb5e2dc985b65fbc48115aa129e6000fe4100000000000000000000000000000000041398497f975289fb9fc6ffe671a19fdcd3753c82ffd3b2084574107bf7fadc8de462507f4484c32df39967c3751a480000000000000000000000000000000007514a7f246006e714d4a8cbb4e89d81b951b5c41a05bcf35f61283e888074fb3686fb6ecc1a66e491ea1e1ce0738102", - "Name": "matter_g2_mul_9", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea", - "Expected": "000000000000000000000000000000000b24adeb2ca184c9646cb39f45e0cf8711e10bf308ddae06519562b0af3b43be44c2fcb90622726f7446ed690551d30e00000000000000000000000000000000069467c3edc19416067f572c51740ba8e0e7380121ade98e38ce26d907a2bf3a4e82af2bd195b6c3b7c9b29218880531000000000000000000000000000000000eb8c90d0727511be53ffcb6f3b144c07983ed4b76d31ab003e45b37c7bc1066910f5e29f5adad5757af979dd0d8351d0000000000000000000000000000000004760f8d814189dcd893949797a3c4f56f2b60964bba3a4fc741e7ead05eb886787b2502fc64b20363eeba44e65d0ca0", - "Name": "matter_g2_mul_10", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76", - "Expected": "00000000000000000000000000000000048ea2c854a0df7b10a2147db6eabcb16eba340644f737fc99663d1ef26d8ed688c2baaa7d7699c5f540d7605eb48485000000000000000000000000000000000c959efb835d48d3e7a8ce643764f27c365f6248a88e39092e3a6498f04ed851c55b796dacd62ae73d7edf23aa45fefc00000000000000000000000000000000114337b8caa68cea6f22a25c0ce3b247cadae24c63fb02c6a98a728b54f97b12b1473c8e23f55338326b9575a637bb2e00000000000000000000000000000000033167b0668ec650581815cefab61d13661f4cbc6e01711af0aefb699e1979b551d0031c603ee5f6dd4f716ea7aa4a6e", - "Name": "matter_g2_mul_11", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c", - "Expected": "00000000000000000000000000000000142f6b71471f3665ee6269cf598fc3587a62523f9753eec48a2461a2e313e376828cf6d1a9ffc9e64353c8a668718736000000000000000000000000000000000153647cc4a5aeb8ea52f845c415651e167ace9f331c1d73eccbbe20a4014f9e1158c281495206de4b841839438a595500000000000000000000000000000000151d07c3f83217e63b332a6c47e91ef2418e9c658353f8b644f23266f5fbc727562f0935b4d892db947cfbd0757ed61500000000000000000000000000000000035bce4bd2d8261e21476c325cb68e581f20513eb5e0e6a0ddbfd4ac4674bc323590b6f52d0cd50010c13642e7e03daa", - "Name": "matter_g2_mul_12", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a", - "Expected": "0000000000000000000000000000000014e83f87e7f66d8ed880ca46a76a5d3bbbacf2dafe1ee055f04af568738f4c6ddf2a93e1810b616da6f64f25c35a7b5a0000000000000000000000000000000003d14447254b61168d36f92710f95f7100cc8f278b0bc9528da763a18a5386b3f5b83b96f4dc426e4b0fbe755bc986790000000000000000000000000000000017f1a79ed64abfe5e960fda02cf3330e6ef5612c1b8639386959f86c970adb797bf077a468273d37996a65685f75ac30000000000000000000000000000000000d973499a7bf7132541c0976bf2e9bb26a2b6cfa5bda720352fa7a180a6b8fe95befcc13de5a2efe58be934cf7d8e664", - "Name": "matter_g2_mul_13", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a659054", - "Expected": "0000000000000000000000000000000018bb69dd6db0beb468242265c382de5ac342d465b5f72d4e5a24c67a48272d9a1f3af28e0bd3712e16a854c5d91c616b00000000000000000000000000000000072fbcc86b7dee9c2dc177dbabdbbbddb630c98ac3bf3737fd22f99e2b2b690175d9c5aa4b577f78c545dc6a5d2d03c900000000000000000000000000000000161c4218143ab1f0387f19bccdcd08f9caeb2d1331ca890741799ff1b40533076b6a96a910714176c770b25d2c17715300000000000000000000000000000000063098cd9d1eeb899724b40a2d10ac951ba0277db09aad639957f58541dd391fffadc5d97833bb9666b054e12debfa92", - "Name": "matter_g2_mul_14", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746", - "Expected": "000000000000000000000000000000000e43672f1bc25e7e0e64a3fd26cb246bdbd6fb5c9084afdc87c888634916e6a6cc9a351cc67a6ac77ab8e132ed6cbee3000000000000000000000000000000000dee9612527c8ee9c574a4c51f5d3504ccf1d5781b59c78ea15294332c6acfdcc7bc68853e70f1f72524c930e4c3d2eb0000000000000000000000000000000017eba629eb14a0636926275f1c2109318ce8818d8171c69fd371751b6de47bda5b00a0b0e3765d05bab7b8dea9add90900000000000000000000000000000000052f0a4cd9b91695e1e58ead1da1480fef08cecef63896aa51ab16da373b99b3b91767a374645ac5932d9c7fd21d4636", - "Name": "matter_g2_mul_15", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca807f80a5e502f63375d672379584e11e41d58d2ed58f3e5c3f67d9ea1138493cf", - "Expected": "0000000000000000000000000000000019b7ea673dad96c8352870136ea262c9ed105550cb403eb1e64ad598b2145fe1b95e5d61f1b5a6ebec47568c67b68086000000000000000000000000000000000f06ff9bcf2ba284e705b12ef2311f1a9b867ed742ee0737567b5c878547b18394b82c2bb97e16586515728245692cef0000000000000000000000000000000019dfd2d8fc4f2c989c7e1016e147f336174c84d380bab992bf1adbffe96d93d4d2d1d1dacdba3adfaf283b184478229800000000000000000000000000000000068d230422006004cd88ab0dd46a84af3905c7a1d329446cc23c1c5adb401a86a9fa76aaf577f77c2678cd8de8685ed4", - "Name": "matter_g2_mul_16", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000135aee0e30fbcad798738c10d4aebcdf50c89ce516325f655fe763dce54ffedf94dd74168611e5ae879b5bf5598d62dc000000000000000000000000000000000c728e672cd8b3bf9341bca929c34118b566cd3a80452d7015bee9d5cdc001b1f5c678d4b2cc4f7cac353e7bf326ca1e0000000000000000000000000000000014809aa22e2051e463fba6d49fbb060d0c7f599a0fc5409d34e71f34817e7beb1251810ae6eee1848c60796fb8647dea00000000000000000000000000000000145a4de777d86025d50e12f9a6615ecb9bdd41489992d1b643dd9aa549acbc63b04b0bdfd14b6e45c70f165e9a8c91bebb169138f94093d5c1c6b253cc001ce8baf78858dae053173fa812d2d1c800da", - "Expected": "0000000000000000000000000000000015ffdd83355978ebfc386e13987effac0137ec628fff1667ede29cfcbd05e31cf8323959dd0247c20cf28978dc242c790000000000000000000000000000000016b1f810da2ae3c2ffbb6b83c47ef03eb0f298ff4c304ab0dd7b97207949d62858458d789c86c0cd474c34fa720ad3b70000000000000000000000000000000002a2e1463d5e795e6a25998a848b079363efc7d0337c3803385f4f17f11726b04108adfd87a811d709cbb6750c969526000000000000000000000000000000000289a3f472799c06a84bb1f377a36bad910220e1017884545159fe1b2505e8e7473882fcf324ba0d9125495bcbbc7226", - "Name": "matter_g2_mul_17", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000009a58b7116dbd6f550f8ca98071813130ecaa9ea86d5275eebc36860690fa048c9ebeb46600b2b63e847bff3e38ed0d00000000000000000000000000000000113ffc0932c041e0e34b2540c485eb74f5029b339cb60bc88a8a749310f33f330dea137e5f340044fd689264af66696d0000000000000000000000000000000002642da3c2c7b6688aba0b19ab29ac72e35caafa044863c364ea8833fca850289de52c0963bc33d7bba40cb5f568718a000000000000000000000000000000000552d35ca054da2f148c119454f6760607b351f2441921a2be17da2cc10902d71571c5554f132e60df79679428fa07e3e40608bdaf3e7764358a64a920cbb33ab4d571c7b3092e1ae11d9697f82ed833", - "Expected": "000000000000000000000000000000000b02ddcfbf391a2d6953261c786945093b09377352473a86cfac6456a811233809434b566b9301eea3105eb86922efcc0000000000000000000000000000000015430deba91113b841303120f0738012d77207e9408474998df5e68d0d61f1a64afb947ff93116ae766ca5325046e263000000000000000000000000000000000ab7094055919f6f707b458cda552f25104d95e4ec8d020ea4c17ac1d7efef5c4c3a769120718f1d5171eb8630a3018200000000000000000000000000000000161e7209f8c98e511a698fbf01735798cb632ae1afe00870654ffa0ba93a549edf4b97d60f03974ab0964cd39298401f", - "Name": "matter_g2_mul_18", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000018fbbcba3d4b1e548ceaec4a48db62a2420ff29a67af332ee7ea3f902f84e6c375fd33abc33d945c5bca25603979f9a400000000000000000000000000000000072ff416994364bdc6535f36c82212afa822cd94fade69f11eb38dbdcd37c7e22af55fe05e6a826dad822073656eaac10000000000000000000000000000000017bba179b847278a4878b6faeaab3b1f4bd7540d22817cd9aff95557497f8b9d286657b6162c0f89f7820becc637dd550000000000000000000000000000000018e2bfed71aa9b11fefca2f0db8bd9b8c69540267de50bec4fc90a6e9741891465c9761d19282e1100b3707eeb598b31d411519f2a33b07f65e7d721950e0f0d5161c71a402810e46817627a17c56c0f", - "Expected": "0000000000000000000000000000000006cb218607a1f66ce361c89fd20edc3f00421611adc9aa52ec35d45e023174962c863f740ac36c984c2b466cfc4827a900000000000000000000000000000000152b22d46e9660da8b1be4c5b14da613731e750ff7eebaf879f7074bf3c33e1528a2c8479e0178707e3855b49f85f045000000000000000000000000000000000c928cf78cee2c8b9da8215d33d189c5636df1e8e9bdaf143aba7ed40f29490ca2328b4a20cfc56f62e4ce49d9e77f14000000000000000000000000000000001574b7a9c3931933160ad4eb17400b6297210db47bca034bc1b5d17a0cb8c41834636b9123e625e5eb0b01738cd6b9af", - "Name": "matter_g2_mul_19", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000019efd37727dfaedf697fcda7a59847dbda8ca7cdc92f34e68691d682e20ae6545ac104d6660fdb8f64a051e69298eae8000000000000000000000000000000001225ace0fdce456dd888c9672503b68ef77b2d11caf1265a767a6ea14911e3ca03fc153f18dfe9d95e0cc68b7b8a3a8d0000000000000000000000000000000008a6b059c1c4da046cc0b1b5d7f33270aceffa607daf6d0d078c06f940604e1a0b4adf01a4091306e3c7eddcf3d95101000000000000000000000000000000000f79bae5260a2f114ffbb9273f3049d3ebb002500a57ee0a7d157d86957f43f87a2e026fb9892dacaadca5ee04fc8e176bb3f9e512311699f110a5e6ae57e0a7d2caaa8f94e41ca71e4af069a93d08cc", - "Expected": "0000000000000000000000000000000003e17452a80996203fdc4037db072c452f9eb2dae689c77c88b299d7ba266d111ab2b9c4b24149968d72cd143a34fc4e0000000000000000000000000000000014a057d7a50c9b0f34712ff8008770080bfa671650fef43c82726257da180dfb9672b266d4c54d65fdc677d917e6c5b80000000000000000000000000000000013b452c980bfc4a484637b578be100753aee9dda9487d5ee5c017c689dda838fc673804369328192d780d60a9a3de0f700000000000000000000000000000000103aa86d1807de242a6d4fa4a49be6c91cd757df5808501acfca44940733c6a524b851ac962b99a9be41bfc8d6254478", - "Name": "matter_g2_mul_20", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000016d2b73eeceee17d3bff3aacac9df9ac1c4248d9ea7d6a503a757f7bb22fa6970bb6f5cb5ec154785f7252e1508b382e00000000000000000000000000000000081edc68bbd8db7b10be06ee23d090bd54f9ca07ef24dfed7df7bb05f8cc26e6889dbd40ea203fd5cca5cb588199f9e40000000000000000000000000000000010d3478508619ea9493b4330e2fb9150024cd32dc1378f824788a884a4a30fbf39c630f465557bf0c6d69b4cbecf89f9000000000000000000000000000000000f20c9b134db5d8b7756800c031bf5962fc560ba95d4bd9157b16179f1a37ae08696a2be455ad8d018aead6adcc69b712a0c988d97e86dccaeb8bd4e27f9e30fad5d5742202cdde17d800642db633c52", - "Expected": "0000000000000000000000000000000007c616472f9ac60f749979c6f870b587425d514395ed07558ed287fccabc77f0c90872f3885d0780bcdfffedd124eb3d0000000000000000000000000000000019531e9c25e84a2a968a85d9f1ab61a372ebc59ba5bb7a2bbb3c0d6e4c9d04061b28fdc719735e97ccd5f7243a58cdc70000000000000000000000000000000007772d3cff12bbee916a6569edce0c6dbc2bd8a794919a4dd7bc37024c8273245210511b8f6da551fe626b7b840833f300000000000000000000000000000000186a3e858a83a7ea1bfdaac65c2df1076059aaa193961559792373886c68acd2f9fca61b166a0ee55084a6ea122ec3e8", - "Name": "matter_g2_mul_21", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000003dce67181d23af9729e9fb0653d7f79c890fba27de42fada93123e112c4a468fa889921192db8047d86e4db77c60266000000000000000000000000000000000869a1e39d42d9bb0cc0568fdad16abbdac3194af893ebd8dd8f8c2c3c855abefa5fc215412168acadc88e658e83f5570000000000000000000000000000000001ef139a75194f3c4b1378c2b66dd304d179460bac0a289405cd8faa3ff66a7b6e54eb7b8742a68150b1e098630135c40000000000000000000000000000000003892b5a645af916be2c6c7fc0bb08fb5f39341d3c68598940554e1be11e1be75af920db0c8710ed13c78edbf683f17d0b299c14892e0519b0accfa17e1a758c8aae54794fb61549f1396395c967e1b1", - "Expected": "0000000000000000000000000000000008adebaa95d10b9fc0f1a1f0d52dd6741517d2ba23e3f9e7a9221039684ae226ea602dbb50df0efd44b2b5bf7495c0b50000000000000000000000000000000008e276e78ead2473602d37cb9f2f589f9c60514a1fc5c215acf487bf57c935467d29945d3d671b41a8e47c9495dbf5c9000000000000000000000000000000000fab06240cb8cbe9afcc4ebebde50c2881e4bc4d4f2ed09a1065e3620e6344fb3c5f3019250ca4edaeae4902abb7400d0000000000000000000000000000000003fa6c48ead374be1dd45c8417ca8234c15ddefc5039151e6cd7fb27f866e134cef2f59ac9b2ec1b26896eaec9213549", - "Name": "matter_g2_mul_22", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000264dd4b477f5db65edad28c7153ed919a863c5c5661e0125c5429b323e055fd69c33142dfc6ed9c87082e2be4675e1f00000000000000000000000000000000046ea088a2ec94d3a1f1f97949f1ebc49690c453d316cc46534fa253b34b30323b6071d147d64bb94e02fb4db07bb0c400000000000000000000000000000000013692a33bb1348486eec40a9e93a4ea3810c7b4d3188cd07e235a2c898aa87ee0d17682fd24f4d978f9fb028fd26e2900000000000000000000000000000000115f8b64c00cd5cd344a7b5edc0ef0bb85a3e8f0f9dfb28f8ffe12db3e0d222c2d45dcdba0fbdc161c5d558bc71aa0977064d43d6802ad4c3794705065f870263fef19b81604839c9dea8648388094e9", - "Expected": "000000000000000000000000000000001412bdb48546014adf3c4eac4dbe79ba700f90c8030b063828fb01be5977bd73107533a4e8030c8d9cbdde9bcf10649a00000000000000000000000000000000126d3e1006abfeddd810cb1e12c898cf5f543e414438e600ce4c94cd8dbd1e17c0f3b9831add397feda74362eeace6fb0000000000000000000000000000000005b3159638afa34f219513cbcbc51567b16fd5598b85e6ae0d232021133cec25a6269250df2ab7b5ace726e9e2fbf0b0000000000000000000000000000000000c35bfdd1c10e903da6d41e9afbe65b0cd66addd7893fde41dfda8e543a93938cdeab52cc9bbdbe61f93d651bd1c923d", - "Name": "matter_g2_mul_23", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000014c83d58d90db4821a0411fab45f83fbc05f7d0d7a67ce75da3ae568978d15f4c1886c6fa6086675c0045efb30d818400000000000000000000000000000000001e68691123451f4c3df6dae62c6a63855ec3597aae33a8a10ee274e902e9aab1460cc9c79726312df0ee0ce90c8d3c00000000000000000000000000000000018a39eb3e3c6c7fb8ee304e55d15e209afe2fe278dda93552a7b9f51fbd778da1502eb6775cbc3f832f8320fa0686240000000000000000000000000000000017c15910fad1ca5749aa82a5a2fa98b0ebb37e92912547fb1741f18c34e0d5fc3a307b928636c25f0320d71cb9d31062686285a0e22f177fe3adbfc435e9c1786752dcf3c11b723539789b0cdeb0647b", - "Expected": "000000000000000000000000000000000bcc781f144bc148687875789fd8c54dd820170984b6f8ae75855f7e45619c1d2ff85c330b7743e447b5fc831dce9277000000000000000000000000000000001409aaf3c94c9a6b5123c82a7f311af7c2f60e9b197d49fb5b010f84faff972151b383a83c106de43454f8097005f6c800000000000000000000000000000000064a91226da8b9cb587030f1f4afb0d422a51e4d55212f26c621abc06fc0c57a473a9be75518a5f4f9a7f8d4aaba69830000000000000000000000000000000002cf239343bb77865ceabfcc1fe34cc9be4a1ebc3a70f16f8b7cb84eed5843524f95673b01466d6cbb0d8d9dc00793e6", - "Name": "matter_g2_mul_24", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000fa96d9fe01c18732e8d6454df9bb1f482c4b9add837ce9c354c72d49c2d44ec694674aaf0e6d6a095cab7ebb57ccd9a0000000000000000000000000000000001f8ffe3fb7e9e311e0f6949c07c26a0febb181e37b2268bb5e125fc3a100323740d1ebaa5e635dba3770fdc2ce4ee860000000000000000000000000000000012ac42095fdb677720ab3f14bf0afc55c95b43d28d922a5f8cb0bd841306b978751d24546e3a6474976961d0768f29e9000000000000000000000000000000000baf9804d99039c9fe966a696c64bdacc9673b0906b4deab108d34fbbaa3b0905d50892278570564017b96828c7e1ac93176b6724cf984632daf95c869d56838ab2baef94be3a4bd15df2dd8e49a90a6", - "Expected": "0000000000000000000000000000000006bbdabfe104b62d22e78bc8f3446a86cd5f10c4c5a54501140768b55a7e6940b9952c9a90a14d8fdc7c04600195cd6500000000000000000000000000000000172e718c926cd393bf303984518432693c304a2758174dabba303ff4c0289b5bf5376b61e8821abab322d53e88f71d480000000000000000000000000000000000a2f84fbdb5b05107a0a340e81b56ddf6d03c23848448f841dc44f07cbf8a575289cf6d53986f581fddb0f2d07e38d70000000000000000000000000000000005cbc10f143a9a1fe23f670a4c47d385f5c7069d8c46580322d6939122b2d39d185d6a8c2e51e88a1d40fd2e82d08b8f", - "Name": "matter_g2_mul_25", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000014ce6d88a7c5c782562aa101550f1af487296adebd9dae8252698ba04fbd58b92e2216de6ffd474d5992f97d9f22800d000000000000000000000000000000000ce92a04f5c8a99ca0e93992448222519fc454bda5d1d8638a7bfde968386e4ba0dcd1da59cd81d4c4dca3e584be0275000000000000000000000000000000000cb570796f5c8f7b8aa02e76cb8e870d3365fe4dce5df07ec286a0a821f922b4003d5b69c0f1588206d9544013e268c400000000000000000000000000000000098056a033d9cdae86aac02de3a444471854b909680719154b44d4f55f30087294e39e57643c692d6da725b859239080d76db3dcb659eaf6c086be6b414a494dea4bd30aef8450ae639f473148c05b36", - "Expected": "0000000000000000000000000000000011769e191fe258ffd1922295a9fe877ad5a52fde6e343730f8f5ec6cdcd584f8ed1dbe0f55b5dd81f5f78b7437f02abd000000000000000000000000000000001253689089e9192d10a45342214425de36740c120e49f596d24658941ce2b2ecfb50e879be0125e3d159088f88e234f10000000000000000000000000000000017b642d1b5a953f47fff8f0649263f16f41a0ec0397d5a81571174aeb85431c352e2bf6bafa6894d2e6cdb5eafff16d40000000000000000000000000000000017b3438d0ddbd2ace1e63802013b5bac00d31889dcb2d9653a6f6412d157aad2fc45267322a62129087380bec65ec169", - "Name": "matter_g2_mul_26", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001214aacb0a5e6b7a40369a83c07fa8cf1786ce7cbde2b5a501d9c1292532df7822d4fde10a31fc0cecce3a7cfe3311850000000000000000000000000000000004f9669d8fe4f884ae93b2505710e6e45b19b7aa5df8cdd811f09e547efc27d21024cba05e2dc9d057055f30ec72d9df000000000000000000000000000000000a852b821b31cd27eca19712a636aa05ef2cd82c36ac1c2ca240edc7d0172b42a72c42d3cba583a5b5129ac1c9486e270000000000000000000000000000000007bd8419e791a5cea04993509e91a980d3ae4987a5b322400b6e4a4f2b636891a1c7ba4de96b53426dd556532403d5a39915646de2449b3cb78d142b6018f3da7a16769722ec2c7185aedafe2699a8bc", - "Expected": "00000000000000000000000000000000089a07bf63b8029e0506393828d8593b94b73c750815552f9a3c74ef7470b5810bc27212ba02ca6fdcd97e1e28a52a1e00000000000000000000000000000000051a93291d4b912f0a594d45c0264a9073663a9ec75e6ee81e13e79383d96e9330bab845fd1e5163e5b28c41c4a854c40000000000000000000000000000000016610bf2b2006207046e489294a132937edbdf95caf508f0df3bf8502e641aab9c44903cde75cff3c1f86873e06cc58c0000000000000000000000000000000005d33669fd8a6256dc55f513bb93cce8bae62a593eb8903cb7d7902a7727efb8fb4bb2e5058441c30b99f146ff5394c3", - "Name": "matter_g2_mul_27", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000005ef88bf38b2f998dec7302cde829076e6cf69df23aa0bf6bbb39fc0d3d8b5eafba74efb928b1de0eeb3d86ec82612300000000000000000000000000000000011f47e9583997b19c36616e4bf78d6ddd6d67937f493986250ff02aef6e6e7ff074559af2f20a5bf1d67158e4a199cdb000000000000000000000000000000000007777c8eb259a836e6459b7bdb642f878d869fdcb31b105d01f280938ef5377f2775874c099dcd394abe70f17d595b000000000000000000000000000000001607379d1cd34e2d0ed765a339b21433e9aa489609b92414c6b5a05d796085269c288d739717def9db3502e0550860165061073223f066e35242772385c67aaefb3f7ea7df244d73369db1ea0b208792", - "Expected": "0000000000000000000000000000000005aa23543088a9a833d773a71275e73fc3081e13c907b8a04a330df7d6c06618fe69e644e0ee55869e364d3561e40f300000000000000000000000000000000010eef9238d2c520f32243f07161f3e35b15fc949b9401baa1a9c5df7d50b2cb3bdd237747735b235862bb57322fd9d090000000000000000000000000000000012dcc16496c95e39ecfd8f0514b5ab2569d89826d957478cdecd4e827095034e974039b37e767a0f25bf057ed715aeb00000000000000000000000000000000000d0593865fd2172ebf1b94c7511ab7d433a276bf833515146adb6d79b6e09d7c18f4c7f4d3241c14d01a4ad0f31580f", - "Name": "matter_g2_mul_28", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000d6e3068c082b68312141aa68f1540ea1415e93e7f1762b6f06ff408a9995542da1c727a13355c19f8f418a44de1a95d000000000000000000000000000000000dcfcf2ab12b1a0e521ab402aaa4d32ff649a5a97892eb6ad98487c3c73c35601c313b8130ad12e9098d16eed3bcc2e00000000000000000000000000000000013777b1eefa4af03dc44e4e054eb7a3a980a9c55644900b80346be84b970e1754d1f4ab771adc9249e4accf88a23fb400000000000000000000000000000000002f53b231f1209c6f8b52f99a78bc2147c951ac89b341495f4a60a6572985ce2bc823625099ec214bc9ceedb2deea3fff396ee22209271ea0bda10fb5e2584e7536e8bb1d00a0dd7b852b0aa653cd86c", - "Expected": "0000000000000000000000000000000015785bae0c27680cca2097ab52306207a61ba9903723f574091ef5e57c2e871e076d7f46e6e39f65a01e183e7bd822f000000000000000000000000000000000071110a384248664db46f21d87b455a3ad3c43782c68304ce17f52cc8579fb2e3378995d6eb3b8c97665e5fb7de665fd0000000000000000000000000000000019153a01c2b3c5d481474a71e5c67f27fae3232a0c8f1655ddd4da6b4c79870bfb0b6beb4af8c54aaf7e9251ad41d639000000000000000000000000000000000c58375439a93e0763467c6a11dada3e579ec53a968c9b9c1a446cf3224ea0c89c9ec218a8b78de91fc12f087e722f94", - "Name": "matter_g2_mul_29", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000161c595d151a765c7dee03c9210414cdffab84b9078b4b98f9df09be5ec299b8f6322c692214f00ede97958f235c352b00000000000000000000000000000000106883e0937cb869e579b513bde8f61020fcf26be38f8b98eae3885cedec2e028970415fc653cf10e64727b7f6232e06000000000000000000000000000000000f351a82b733af31af453904874b7ca6252957a1ab51ec7f7b6fff85bbf3331f870a7e72a81594a9930859237e7a154d0000000000000000000000000000000012fcf20d1750901f2cfed64fd362f010ee64fafe9ddab406cc352b65829b929881a50514d53247d1cca7d6995d0bc9b2f0d3d4cf46265fc0f69e093181f8b02114e492485696c671b648450c4fcd97aa", - "Expected": "0000000000000000000000000000000004c7495c03fc3fb4d0fd4e0e660d6424de9e060eac72eee3608ba95bac294a3a62d246f42dcf3b575ee1cf8e20a9106100000000000000000000000000000000091140aee42a9dc875f87f3ba29beff95138790140f8bb522c6c15281b3545995f9c13b0b73ae691317e674295db6526000000000000000000000000000000000a945a215b2861427e0fbbfc6fea04e79edeaa1eb87df5db8e5e017cf98fde7b8d5a04a1b2129a4aadd2e3924ecc0bb2000000000000000000000000000000000a43f8d3d92a03b7bd4c8a34ce31729ea0b8e6b051c30241dca2db31a02b6e537071a914d8f0876f944dfdb613540c6d", - "Name": "matter_g2_mul_30", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000047f92d6306bed1cb840f58fd57b5b71a5df7f86dbfa55a36636cb495e08715cd57f2f3e7cd99a1efc28b1d684de1cb0000000000000000000000000000000000f4eb02d687a1a6105b4dbd740e2c7924689d558e6cbfee768dd303cc8dd0fd887f5eec24b54feccf00f473ca3f54ad000000000000000000000000000000000edad68c4d536912816cf6ef039c3dd0535dc52189583270b3b038e2c67b213d943bf384ce69c4a9dc526d7ef309f25a0000000000000000000000000000000006ff4a6b5129ef026d1d5704bf7fc0b474de92b5cf39722f165e73f4e7612d6d3bb40743e4b7b42d0dad5d5d6a2d4881915b717562844d59623bc582f1a95fc678cf0d39af32560c6c06e3a74023c89c", - "Expected": "000000000000000000000000000000001821e14e70e12c7caf2a1ab651eb81dd61c4e1eec9a02fe4124abb865a7029e066f03b62e6ecfcf0fbae5151272b524f00000000000000000000000000000000044ac4a7399d6a67e7ee8cde3f5fe20b0a745462c870926f0ce8554061eba5bd62a8a08c798d8bfe30fba5567d47c7ec00000000000000000000000000000000178b8f061ad9282b3b2057f20c115c91df994ac40aacd05b7669e934bc7d650a0cd88f9fe17d7b766e34bed587ead58200000000000000000000000000000000188311eea279ddcf75f8dd82643ca3efd560ddbe6c8f2696cf7da03e65cc90d97b9f9ce99e29269644d8b881e624cca6", - "Name": "matter_g2_mul_31", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000017b32e613cb38b41dcdf3c8bb9187d731546977fbffd79fa7f66e3d6aaf9e1af6eca2fcdc260c8f90818d7148ba2f4960000000000000000000000000000000007e4d26606a47c874c20e8480a9f5815e5b577bccd783b775d10309eeb3d2102c7a0abc3324679e44362f09e7a4ada67000000000000000000000000000000000cb6f12ac8b49cfa36b957591293c87b21af0a949c55a28a90ab0fce88fb5cb7645e20ab2edd284f0ad1377dd95ac10e0000000000000000000000000000000014c96b5dcbd3150eeaea5c2bc27750cf88b30a91933a3233a4d1d9b357a80cc20d135e43a344e718dff5c79045c31f86d5c1c9fa11c36b86430cbb1f3ec10ebbe3787d0f5641d6d7fb96c810eda202dd", - "Expected": "0000000000000000000000000000000012496dd3c1278b55bde81f6944c4bdb71869f5e5e21db7b1425ea32fa1dbc8c301e7f5e68cd7629c91650265d1361e690000000000000000000000000000000004a1251591efdbdbeda21eb89165ca61a2e090a73426451b6933d939161364c4064a67a90f859a7713fb6a9c5321d5a200000000000000000000000000000000163bcd07d030fd6ab8a8e0bf39b136dcb34f03925c3fdadf55e94a90bfde0ecde5c51d2f4d06954aa6a96c913f2ab4610000000000000000000000000000000016dc065a852ef9e038d93cc583b4a71db9b96a7e7a819dc530598f1ae256368438f52e4b709f15f56279b9c7f9db8785", - "Name": "matter_g2_mul_32", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000001ca1141ba9542c56de8991b313c6ae42fcecb6751b0b81b8cb21ed70d5008f7ffe831766b89880a7fa6dfdb09a2cda3000000000000000000000000000000000e6766b17db165bba564ac63ab88d3f8f5eded07a40b48644e60d3223d30458e7dabe404cab8d6f9fe135712ef0b1a43000000000000000000000000000000000dda3e6c87382fa762510e5cac721fd2b654f002f5b9a3767a8c6d651ccc582e80e3f68d6913cda30f9f51ebcfc7c98600000000000000000000000000000000059a7dac5bb6b504f2bd603d486700fe22c14f25254537b2c9079c2b45d36c7ce56854c5699cc7649b533194f51a9045c00eb20fe7c292f3ad820a074d8b3d8d24506612752d8677c2d6ca24f556cc45", - "Expected": "000000000000000000000000000000000a2397fb3a3891d1703eb2112357c5fb8acb070ba9f3a39050be6f05b49b8d2488e94adfbf849c8b4a42e287077e9fff000000000000000000000000000000000cf2c02a97addbc1584091e411f9a07135f1fcf989dfc8ae29155ac90b214ce20dc11a1fc75dfb697694891d934abf0f0000000000000000000000000000000018fd4af647bf0456aff9ef80969613829f8eb837205df552aadca46bc3bf9838e0ff2515d3fe869f80d78e2357091d8b0000000000000000000000000000000003c5671ea4723498359f29d49ebe974099da3dd59d21065a721f7a4f14dc7fb1de3a67a707bfa4bad7058312632c6113", - "Name": "matter_g2_mul_33", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000090f4b85961ce97cf7f99c342d3627105d790f611e19721a43d8a0febd67ae393d77a02b999108efb56f0397dac22703000000000000000000000000000000001112f23595d1613c47486eadc37f9b1ac3b3c3973b3fe964d3b67c3996fe2eacd9df5c287b0cea8e9475d146fabcf9e70000000000000000000000000000000018f46f7ba3c9af34c1025c2d460f0be966e68944928dbd55cc7fe00e5def598d80b0e3801e48a74963c974ab4727a52100000000000000000000000000000000096845338d5cd2ac44e097607d6a1a05c241eda1941991ae9edbba965d9029032c46da7218b5b2338e6c58898bc4a820f661d7b30fb11bef70e15b257d7073885468a380862202b2d705a84827644b5b", - "Expected": "0000000000000000000000000000000000676bd7ce63d8b58cc1e5399ced9b495baba4cef9503c44760f92d6d9e092d6d5308fa88144491eda6c571a8c308786000000000000000000000000000000000605cebb4c20bc9dff0258f75a825f55f23a32cd0804dce56bf3cf2f19a3504f0345e0f1b839d4d5920aab19b363ae19000000000000000000000000000000001512f95f60a6dc79dd9261c321328ab8e22ff314e7582d8de83aa3bf280805cba8ba6d359a620fa6f0564396a45ca9760000000000000000000000000000000005837474ba78e0700c77141d70af1d8fb95a97cbadc95996faa93c2e81b7c8877d08d5287f83219a24bc0080e630e39a", - "Name": "matter_g2_mul_34", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000aafe45ea7cb8b450a51263eebc28c1ded662972bee512e24fddaf64f43b74b66032523b3b104a4e9f6b62394436c6710000000000000000000000000000000015cb27e1fedfba2d1679f78a388f90b22bbf3e7d090f0ba972fa8e72f6e31c446f628fff929953712ef6e425d16eba5c000000000000000000000000000000000df9931893cae713042bf722db6ce394b6f346587278a154c271d8511e690417eb6dc47efbcebb7c2fb9e77f1de9fde800000000000000000000000000000000106ffa395ef170c99bb5742428ae88fa4fd7a94476985c099e3b700b7403d083281fb71a19640c6bc2321e27bcb33fe2346ce87c847376c8967cc18297e6007dcfacb6424e1d273930f38bb0e88fc5ca", - "Expected": "0000000000000000000000000000000010b2a9b32e431c11ceb474942bbbd6915a3cff64a74d67570fadeb7447c5abcf1bb35c822d4441565322ebf75e61f64c000000000000000000000000000000000b75a0212232af0a59440482a1f953cc29bcd35272ef407925eccd70c1dc4705dc1e97d2da604996d3c52155d05d77500000000000000000000000000000000018751bc59f5907cbd7f1d503bc5aa266f4109fd3133a1c4c2e58e4a17250a40053b4489da4825b4c368b0f4947baa6240000000000000000000000000000000019b41fa1af9488596b09c587fc33e044d51674eb6087c647d5a762d85e38a587eb5482687d9346a1a701bd3a8bd36a61", - "Name": "matter_g2_mul_35", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000010b1f8b1c492a56936da905b8738affba6bd29ae5fffd40ba6b31325181d3b489a81b23dcb69f6e71bd29bfb388e5a8f00000000000000000000000000000000116a115303b4774da59844e457844232d088062d920db67b2a8450a194be7e5340ebd4d106454fd9a03c8f50dbb1e119000000000000000000000000000000000eb521edd61b38006cffc43ab72d395d669dec196846fa4d6d43521da6c2fc3bf0994ce7556a3cffec7751b3bc5703ff00000000000000000000000000000000073cea36eccaa1c78deefb6029903c2b6598301bdefa9759719c3b590fcc5a6a4d3d4d19f552b33f4a3126a6e6a8448639a142c443a666499a880aa1cb9f523411bbc8e5554de099ab485b6c2c2e57cc", - "Expected": "00000000000000000000000000000000054836eb7ef9edbe914bc16d1498e0bc3c978bbed2518802c2f8e1c0b59fee482cce0ae8e805c33861d4cd595f6b8bf40000000000000000000000000000000007dda36d55aa7a890aeaecf2528a390c98d9ecfc8a5c78c2a6def30de55b90ae408ab770cf9a9a4663ba601c4f5765a00000000000000000000000000000000007ff7b24c8ed9fca572069e72b1e93978cea87a0fac7ba60f54aa573d881f21b73012b010e9c0fc9324aa7697bae0c4a0000000000000000000000000000000002d9773bf294efe64021e755e4dd2936a5060bbea5688b6369ffa3b94eadcc58cc3986c74ff365301be1e6c785939b69", - "Name": "matter_g2_mul_36", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000e3925fa085db73c1e67b29ae90f8773f83be5ec684402e8e2360ffee8a8368911e584843e42b0d470de78591df6ea6300000000000000000000000000000000075c7efdeeb16609b4a47ea442af4d75238fb7534fd96cb236a7886809d6adc2b62c8ff72bdb041bc51c1a71b68219e300000000000000000000000000000000088b4eb0dd185e51b737d797334590e982b7b0a5f109fc7d0524b2465c2c0457964eba5a6d2d4d99fb628f21f15a776c000000000000000000000000000000000fc79f6b38f3356972669290eeadcd992a22bc1191606b663a1e148aa58db3938f0fc65e536bc5811c50d9c7f03d3e372c01b7795c2d16b5bbbb1e107be36cc91b25130888956b0cdd344de9b4659447", - "Expected": "000000000000000000000000000000000902c1082ff09bf93b91c9ef5e447bd6832fec9297cdb065f11fc5ee626e6e8834cb5d74775c586609a0394e6114e8820000000000000000000000000000000018e414a40c27430b98246fef556e74dd3dd7adc601e3c05b79f8c29169780a173be9a725df3318d71b6e82abf97930bd000000000000000000000000000000000f924fa88f43c86ec98b34379b9a649c7564ef0dc596c95df19522fd50fb3a37cae031e891a7a7aa6a5e6a9062c3726a0000000000000000000000000000000006bd3340412f64d02d0cb3ac44d1f31cdb1906e56dbfb66d86b60a74cd26c1e241963fcd8bba4109c428db0bb083e81f", - "Name": "matter_g2_mul_37", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000b87c47605fc060a8e3677e84ce9d14b9309360a13c80d040c625fbf0108f829300cc1fca409a0f9c96311cd4a9a21e60000000000000000000000000000000014c4088f1e7935cf6a1d2475b84497ce6a250ee2c0c991fe51a2f2836388a354824b02d9cf215328dfce3f546713e21100000000000000000000000000000000120e59be3ecf35674eac6cdc559599b273f13f28a529770fa156f8e519734c451eefb35023639f32049cd19ea0d945a3000000000000000000000000000000000f97755b62a8cb8f861ea02c77819f0b58181aecf612d92180ba9b475f0b4888b922c57f6a1c619dd5514620a1cfd9e2c712943d8795a6104f024b9701c70b09cdee9494755bbab0576e2c7f7c9d4828", - "Expected": "0000000000000000000000000000000001415fbd8afeeb5796460a9095f14a8f3f6fe0374d4cc4160f030710a6d4d3a92febcf4dad770de3a3ba1a2efbd858210000000000000000000000000000000015792220c7e53262b56224d230a8a4b32019c77548704ec16da5ce167854305e6cdb9924c248f222d6fe95a8383af7890000000000000000000000000000000001694329d8e0f41256b703a8bb6548f1d9e0749a55c124c9b60361b4cb1daee24fcf272327ba598022a92815764fc8570000000000000000000000000000000003350658842c5b6fc5561a14df27d950a00c5bcc13d6d9d014bfd6dc95ec1a030594625f41d439b90b05275a0ffefdb1", - "Name": "matter_g2_mul_38", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000005860cfb6be6720118623d2d8ba05e686df22744b948421dd3cc1b1691e00d9b5d00d00195b4acf7a7b043f764f3f1c70000000000000000000000000000000012632a3313dd611e8d969bddd556c2d79ff387603462ac78ded3a842981697bdac34ee6f1f4744ed2ff16100874ac24000000000000000000000000000000000112b94c317586e343acadeca611c485c3ea172bc10dd39158c1e678007130062a921b53826d7be6286963ff822f1066c00000000000000000000000000000000040de8c0dadd2a6c2a7ea0fa43e1a5f2f5a6be3fcb0de6875d8cef1ee2daad87125d12f6869c4dd3d931b296f1df2fb3d4d77f6246c57d398c57848db8d3f986c475a41a23d424cd3cc2b362c1b99f2a", - "Expected": "00000000000000000000000000000000054c6cb26c8b0a9a4700e0b95348e6fb1190c577eba03a44e84fe7744c543321d02c4d8f55c03f984b44ffbd899ac53a000000000000000000000000000000000e7ab8da5d573cb88a78f6a6ad2b307bf867777f79a643b6ec89d9cb208711c85d7d2cf8f8ac69a8b322000fc7866024000000000000000000000000000000000fbc5926b9dcd9e4d1ca1a2b43dab5c98aa20b37aff0868c54441de44eb014e5283010642717fafaa95000f4313e14840000000000000000000000000000000003671ee05bc20bead72f2306203dad55cf20b13d3bb2cca079bf4391411b85ed4df55e1426645d73b6935889d4450c58", - "Name": "matter_g2_mul_39", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000006fcd2c4fe848e9462ba1112baad39031c210952adbdd06293a622ffe2d1c6e4fcc8773ec8913717018b97bcb9a554fd00000000000000000000000000000000130a97442f3273b7b35464545e7351faf71ead9b8996c63889a45945ed82bba29bff5014776c6185219a5234d8475c92000000000000000000000000000000000491d571bac5487b866022a0714be11b38bfb296233845cc434a50be1d35f516b8c6b046fe3d0a8f4f95ac20eddea01b0000000000000000000000000000000017e34b04e6fdf152c848f2432b7bd84b3dba3915f06eb77efb8035750aca9d89e92e1d1bc4871105c440d639e8d8b05541776ed9d1029918af4c5113a6110139b8bd7f938caa204373a28ddaa51430eb", - "Expected": "0000000000000000000000000000000013fdd394635f42a926a2324b8cb870b5995772ef4e25ebc1da41dc5bf724f747da8d95a28dd703b5ed65ada5555c8b5b00000000000000000000000000000000118fd550962d1de8f1e60c312643ec7cd306f0bbcc932739270595537c8d290ca7e20b962fcde570bd2ed7ea43009fe70000000000000000000000000000000018b25fef4b75fc7649a489d078311dfb6da9909f472de7bd9bee9c3ee353f345c83119269ab797fabdbede41e0fe6169000000000000000000000000000000000b7c2a73741f6944ef4ce8fa20b2900612645c224818b7faccf6597827fa07f7262295f42be5f34a751a6400495f7eaf", - "Name": "matter_g2_mul_40", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000f1b8df4e8fdfe32eaf227f5af9f2befc85073468f10b81d32d0e126fe2b0cc8e8adb8afcac73213b6ed95e8e843b97c00000000000000000000000000000000004e3fb435ae0fb2d8bd091f250aefe5922b353a64e16abd75627737f3bc56639f8b40652cae69c73ff1969925b0afdf000000000000000000000000000000001003aed7cfb00efce49d6b1a8eba27df87479a4d37bd7fda6121549483b669a1a761204b0dd28262bf27e5c8e180540f00000000000000000000000000000000114fbca7caf782b3296d0b26b4c362bf50acaecb8bc5726b2c99f904ec3d092d5d40991d0d30c8e79fddaa45f04a75d3fa64411438542922a7bac10806efaa633d31d37c0b223314a8b6221155b9c425", - "Expected": "00000000000000000000000000000000177d29de8a81db2e515d4241e5f7e3d35de22bbcf9aaa616b057cbf2dab57ab8d98213cdec82a2034964f3e1def8a4e3000000000000000000000000000000000a0cce8113eecb064a60ee2c470dfae8b3921f8da2c7ad8dc918b355ff44542b007add28a44848fa8d8f8671617431ff0000000000000000000000000000000010470fcc723286327e951e758fd0474de394778d0c1ec5fe6f263dea1957c60f05dc8f9d82b3c6a7d73b3e783f35ade500000000000000000000000000000000098a6ed331f03da7ccc9148f07b19b132152e15d9fdaee5cc092524b33795edf2b458b4e8383c5e29affd3f025094033", - "Name": "matter_g2_mul_41", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000017faf481fd4cb0c373d21d7caad40e93d9a86e62d26136892fbcc6f6e48205543aff00c45e82fdd1d3e0e733de91e7000000000000000000000000000000000012e14fcb9ad4d9d15347cf004745ed4bd92097eeeb41c4cbcb728a234616363589d8f5ad4cbb61d31a8aa27627723c7e000000000000000000000000000000001513dad1ff27e053902e779e35d04cab648939317830144ea775c435a4b55e13fa2fef03a1256abf5c187487c25a774f00000000000000000000000000000000139da29de8587c7d0ca9237c37a116387385e9cea453b9e2003a37ede7aa0a3f4c1df55255897f5975b662be33622dbce7002f41c6acab677a0ad023bad2a61b11c1b7221d944018b5ce60bb61e87e96", - "Expected": "0000000000000000000000000000000018a1f1a60172a65abc8f2d855ee7510c1e0af9bada084325027bd493ae86ea2c62c15ace7f63562a82cb80ee7095661b000000000000000000000000000000001736b977fb52eb1b466cec3d42df7e89047784f0e8362eb6425e37adb1e84d0438f5a6e82c7b31d59b0959a5f4aaf9310000000000000000000000000000000013ea0f849830f8e48161e840295637d8596b32eb576560289620b797b14bd395d835e8140b69039c904ef1d07a82127b000000000000000000000000000000000d7f58873701c138cb7e18ffc36cd0e47b07d70448ddd9fdc4b947003fb29cba0775916c752d531e527ab744c277e5da", - "Name": "matter_g2_mul_42", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000c118b147ee3489f30c6ecc0256a314ab674110588e8b69ca6d265fc270c3e5b767817f861140cca5d7c6be4012d1ffe0000000000000000000000000000000014800790654726959fd876b035bade0da744fb36ee5b304f228663a531345120267c55ac19fd66022752010e5bea7cb30000000000000000000000000000000000193ab7ac2f151750356b6e178557460c9c2672b1736d19a20e3fa28082479ca60021aa68edf2524f1aa826ee70b65a0000000000000000000000000000000015cee9ac55ab45abbc57d0ea6ec9ee49f6c59f6b94f99589dbc08ee877d3a261ad77f5473fedd72ed7206647eeafb6eac26e55f09b787c0542878e4d720027d9ea465f829a4e0164cf618c5d9cde49bc", - "Expected": "000000000000000000000000000000000290fb3f38937ce4439ceaa21cf3b31db8a22f9f5ad9db0fd7d38ca978192bc05d41152f8f86ca7b2ee0bb58e125f57f000000000000000000000000000000001775913fc24699bf08f25fb946fc6527178ebb821c654b7bc69f6f86b5168fc42057a5d3bfdc53b3d57fa1ac05f7a0930000000000000000000000000000000017b9043cde8dbf500ad90463250a49f56b35713f2fd9a35d8391fc36c78c083e39674592a98cb857194ef9e73a62a397000000000000000000000000000000000e5e62e39433d443e7d2d32754d2ca2556cf6deea45e5076ac040e3d6de14e9965c53f8c65bd98ae7d17ad3a26f3accb", - "Name": "matter_g2_mul_43", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000ef203fab794a0ef29eb2ebf00076134e5932e27c99d6d445695b9df2afe7563602e318caf5d44724a21790ca0ab0d180000000000000000000000000000000013b9b1b1d3e98b61b0f1a0ef3a1a4ceed57b6c01849a4ad66a86332b3d27022cfccadd3567e6709d2de5b23b23dba43f000000000000000000000000000000000c1fbace49684f4be32ef6178ac3a95ea3f50b11494340fb73dc5391d50bcacafb3bf0f2631fea9c4ec47327d644489500000000000000000000000000000000040f82812855aa3e3aaba826d5810c1049cf44e86e44e23cc6da437971b529d2f2676c73e1fb9da52640c981fbd710bebba67cc47e38a129ab1140fbcf0386ddba2feefc919aacdce6059a27a1e2efca", - "Expected": "000000000000000000000000000000000d9927347a9ac9b0290e68143fbc6a5f4476604c3fa5ae87e729a03ca055e4c6543f9245a4592e195180d88781e46ac900000000000000000000000000000000175e0ee8de4002b18f32f70f1bfa9e0be87288cddf1c436428c2969884112bef5db19e041cbaeb23596e25cabea3777300000000000000000000000000000000074ed9e981818102b9ba818d478ba27033eb38e3fa19cdeb9f5820e59a64dc451342a160359c54bc8ec7d866b62080ef000000000000000000000000000000000a853930020bf01e20816d3aed242e00792b0d0e78fb15403fc3cc255f0dbd99ea6ae1d59d5978e562be4862b3317324", - "Name": "matter_g2_mul_44", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000060d7a718dd02b147c265f71eb136d1f31781b12a41866b4f86d7374b93dd10058c192cc0fba928373b1526e1a5d7d7f000000000000000000000000000000000cf29275373c0573ef22bf87919faf5444847203c7dc6d2e18986152cc294be04a5b1a4b0536797158113a15276c4fc6000000000000000000000000000000001016d5b9d4d200d7b4b7cc3836b85d6697fe14db350badba9978c7b56983dd1a7e572640ee0372b0a4e2079ff4c1abf2000000000000000000000000000000000f2768d104d895473ddf8c6b3cd0e7c22458d0037eca6365c766879a07c95037ee0de00d32c974d767080935abbe0be1705fb566367d9fc142c4194b0525c16672b843aac1160f9056ebb115e80d377a", - "Expected": "000000000000000000000000000000000e9c290ba8a22f7bb3f7dfdcc9f5a221a5ce838d4fa85a00473a4dd830bacf583dd91a6a6f78d2ebb54a4c1bb217f793000000000000000000000000000000000dc51b0ae8bda6d28c51016764fc028258171d7c7646393228692aef7f1dda4a83e53553f63d6ba996d4c0a802bc967f0000000000000000000000000000000014ab155029dd35206811be9ca4efbf762a1673367e6b57528f79eb50008ce7c3b49a2d25da0ae68ac4030ab4bcc0daba0000000000000000000000000000000008cd743bb52e7908aa973c8518eaded75fc2858f4edb25fb7f2e09900f0abd3ac87e93cf1068bbe0c7d99619aa7a6b76", - "Name": "matter_g2_mul_45", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000017b9ca4349fecaa43ce911c0b256680edb8a0906ef5460fc4d2004579336df1e19560fe960a7a7cd74bb6e8272e08960000000000000000000000000000000000d5b96dae738db59cc67a51c61bec6deaeefaaa51e3259243fa4b142ef59676231229ae386ce699fbe18c4c00bf9d49400000000000000000000000000000000111b79f4b68dad16550a13334d09dc38336a75a5da23a17b5064e2d591aa3dab4c2e982a9f730a7633070504663a24610000000000000000000000000000000018f6d3616a7eaf17c805a88c9710039644d01b61aefebf76717ddcda6f4bb34aa15702de1e92bdb27b27f3409638da90f7bfd990cc4dac62a0d730f56b4eb1c1ad77ca9cd58b089c23c2f6efa00b7fa4", - "Expected": "000000000000000000000000000000001746a449993b0684740630f3f0e46eddfa135371e33e8de4dfe553c78845399e63bb3da48798b35df48d27e1f991954400000000000000000000000000000000057e0fb1113968858981c9803166d8b3eacc91bfad320ea0e610fbc5b276da1b46d74fcc54183ba61d1b2fe6743097c90000000000000000000000000000000000b3a178ae3b739cae3e80f3f44db42d8c465a5cfe4943b449d4c3b7f4ad153916c6cf4fdfece14a00b271222c72764300000000000000000000000000000000041c8b293ded0c647f2e4d6f9b35304179b723c3e6e421a5cb103e561d1655b92e74877ce22c99f22a3700c3aba9ebb9", - "Name": "matter_g2_mul_46", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb8424807c5a41ae2baa1e10ebee15363d1d4569f731d77a418998108f5dfae0e90556", - "Expected": "000000000000000000000000000000001103cc395acf81772955bda38f951a81c5a6a476c0b5e1543616a5a7a7be22dd487ab2a8586524891300adec5225b4020000000000000000000000000000000003479a08e2811ae9aab0301d66ada470935984d7466201f3fb28c610c0b5f67e7305f5ad3514cec5f30b51d0aae775d40000000000000000000000000000000005ea37a6d20c1ad0978da68ded3a5bfcc5ad8fe81e39b525fe7d1f2b2b1ab0be7ada80173b1d0b7fe1e06ab6354e64b10000000000000000000000000000000008f2093151a285dac511df1755e99a652a1cad0af3a019650fbdead1421ba8e84afc9eb0a4fea651f365d72f031a0ca6", - "Name": "matter_g2_mul_47", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000d4f09acd5f362e0a516d4c13c5e2f504d9bd49fdfb6d8b7a7ab35a02c391c8112b03270d5d9eefe9b659dd27601d18f000000000000000000000000000000000fd489cb75945f3b5ebb1c0e326d59602934c8f78fe9294a8877e7aeb95de5addde0cb7ab53674df8b2cfbb036b30b9900000000000000000000000000000000055dbc4eca768714e098bbe9c71cf54b40f51c26e95808ee79225a87fb6fa1415178db47f02d856fea56a752d185f86b000000000000000000000000000000001239b7640f416eb6e921fe47f7501d504fadc190d9cf4e89ae2b717276739a2f4ee9f637c35e23c480df029fd8d247c7a7e300bcb3c740fd1f693d4c8915c4c46dcb627f6de6e4847f123623cd23bac7", - "Expected": "0000000000000000000000000000000019f79677ea0e011e5c9a892a407646798b05be05337c73135cb771abf101f450bbffd08e125f077f5ea989decc009b9f000000000000000000000000000000000ed15f35966024cf1de2926108151e976dcb0d51b2736b0877d79de81f6fccb9dd299d14855f4e257cae33ab7455b95100000000000000000000000000000000125e2fabb5cc95c0a7890e9ff2b70102a97a03f2d11d915cf4332dd049a467333e12ebb27955c0310ebdfe2afb3173ee0000000000000000000000000000000011718167000f9b749f1615610a30023db4b986364da5bbdc4506c726624a073548a94307b282590cd8a43b4900a1afb2", - "Name": "matter_g2_mul_48", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000f20a07526a082e88630a0256d134a8a5e8ada07b1cead39ee838dcbb30904e9016107fcbdf1f8ba182308dbe0b043d20000000000000000000000000000000014fb7732f67abf60c03ac902577532d0acadb5f3db0d6397a42ba693526ad74f2c61a0195bdc9704aaaf12e65aa6d88b000000000000000000000000000000000018cec4fb81c85d304588d11f8b9c51f5a053df11463e5812a1b2e6c7144522ba36bb91adf219892d0007cee470032e000000000000000000000000000000000b8e52d958a12a9037e8be9bc0d5045cade2d6ea05c6e68462b3a30b5d4ea34e5fbad173761e4e216b2e6958c8983b28b473df5e282565a0783d23e65e283a103ebbddb5c884183cceb62fc32d0e9602", - "Expected": "0000000000000000000000000000000005af8fd9e79568b46fc42b2c1bac62d115365834e509dab032f66425b7a571a4bd3bf702299d3c5f36c372750b3281f30000000000000000000000000000000018499089f306b3c9f7a645ca2f9aabc4e57c046992fff87e832e21e21875c6adaca050ea8bd7043afec3a36ecf8eafae0000000000000000000000000000000000827fa0f46134e2dff80088129841f0469ec7360fd8b9864e9ed99c5fd3458e6360661ab4c671846681d491b8b823d200000000000000000000000000000000120f829e8d0ffc360a14eabaf52bc653b1e90a36c0a8af806ca745fa306a9739e31435039a377e0748caf5e80c2b0b09", - "Name": "matter_g2_mul_49", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001468cb35a60898ed129f30c261b8431df6a154c250ec16d85a22f8717593b2c21853d123da86d977a7938c5ed74ef23500000000000000000000000000000000011f4e28e31b5f9e6877192a5e632d8c1ed7ca0c42e6e9902ca68f1c2de0f648c6064436012c5c7b14bb8d1078e02f2c000000000000000000000000000000000b25114b2697ca7eb1e6effdd1054893a188fd382d387ec098f846c1137a9b9baad01653b963a0b0bf3cb50c3ce3563d000000000000000000000000000000000c1d241cb03e642c1752b1e1886472477c19a2801ec032dc220c3243952f882094119bb92b621b654b766bc900d2d4f7a048ef7cf5d1f6f625ee3aba091147c389ebebc5b8f3d285e16ef4e8afe5c013", - "Expected": "000000000000000000000000000000001745500b00e5ebc6f71c779ba0b0f8d6601a065c550ca19de9562455423d2ccb507e659b0dce982faa841267fb1a27d90000000000000000000000000000000009c36b54f12d130868ff9b9b61b714fb1067dc91637c09614c51b5aafa2cbe3ca7dce0f3e366d4200cbf603ad4fd630000000000000000000000000000000000172e543708bb853712d81c000c9f9f2378e628b4d13b074317e95deeae98e11e7f917f91e02a0b18cfe9b25f1b83f16700000000000000000000000000000000189fc572ff6a8c6606ba0cea7da7040898d9ee85a58f12fade8c5a22031ff26c2f9cc612bc6e1b82a0999fa93c6fdfca", - "Name": "matter_g2_mul_50", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000c80d4474390fa791ea5f2f16b41506d8ae13ee0993c8d31a07712687298ee7978a724999500c42400d2f788a5a36067000000000000000000000000000000000592705cc5a8875750a4e6ceb42aa3bef5593eda9e8212702a2e08ea70277a2a66526bc5237be33c8449301544da35e60000000000000000000000000000000000facabfbd15284c6433f17b0e6035d4fdd84d3ad2dd30a27d52809652ff6e7a684d7724697919100567ad0c3e1a26320000000000000000000000000000000006a0fc4e2af69ce15a356656f5d182a2cf213d76a6047a05a1a3375909d245f5316b91333d2141c0817438f0d87bb52da9b63c6bf36997118d58600c1e429c105a379b9e8b0de934ab9f433a4fa63dc8", - "Expected": "00000000000000000000000000000000013c6f777df97ad3ddab9b7486d54d1bacb3b40ad3035b47a25a66c02e8866955e27a8ee52872c8222ff7466c1310bad0000000000000000000000000000000014a5eb510d7c743e824f4daab21c43db4d6de8ab2e825d13ae0e186aaba828d7b4a2343a11011a8ec4ea82f456e394a70000000000000000000000000000000017a55d3827b78a9c5ea792b705eba7777df74951930791b17ff5b861e98a4488f83007c073c3e904ed4ee328b6f6171c0000000000000000000000000000000019bae02f8d6f1e31dfa09f4feedd5217ade66f6e8248aa98b273574f72aef83d5048534ed38acab9e0eb4c64f4389af4", - "Name": "matter_g2_mul_51", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000003f629618e1fc3018bb836301ccdc59022f0a25cc9c5de6e4c31fa08feea525c83256235e4ec8364e77e5df478f5f62c000000000000000000000000000000001120d6af221ba6f4351bbee4c2c664a769adb17872646df2c408f70c99ea991ffced4eab50fa98be1bb9426915f125930000000000000000000000000000000015cd16b028ce3d58b10aeb84b783475d894ab3f0cfdf7104ebb4f3417a038107128f07518dce548271061cb8c97e88af0000000000000000000000000000000018379875b68bc26107f9a068e5034f29dc2ae7e8830f8e9ecddc53fe7991206646cda33d37b31a47a977b46be58d7618f228da17f49667c113d2bc2a2c8a338f80be68496f5145b4be21a5786ca6d46b", - "Expected": "0000000000000000000000000000000006490c327790b4c451f93197d7db24211a3b4b5f573a6df409206b4bbfc36bd10d2d0c989889efffd8f4daa4a68b211c00000000000000000000000000000000168f224738db3f07af77494f52ea5e957812a1acd62615f0eaa95c1d363cfceff29be9cf3be5329bb41175a0231ced4f000000000000000000000000000000000321f06b55f7dbfd4900b329c914f9ab9be2794e51e54498e18f83ece5bfd205131fbc254bfbf624d57ec2954b05f6f00000000000000000000000000000000018ec54f3e09bb2a6b112b575f9481bf1c85666133051e9c0ab53369d14eb90e27d2ed02dcda1250d5d539df0d0cda37c", - "Name": "matter_g2_mul_52", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000036570783711b381830e35878fbeb187b84884a9a0e88c38e84124515b470e6ac18157e1499026b27f4f731a961eaf330000000000000000000000000000000008382838c18d56c046a8db495babf8d14c915622d7917ebe10cf7da7ecb65f174cddb9e70d0262ada961b396c5511b410000000000000000000000000000000015f63ce982aa581dad5c71fc79251b7f6336c4e78a4a0f4cb6f87167cabd31cbec987d7af4f11dc6d693a0b0774864130000000000000000000000000000000015c001372fe0530a3f50fb8b30e75ff4b264d673e0448211d082c7a9018f583b4d01790019874596c59c68768cfa3e699431e18a462fba704216b516e819fb3392e315b0c92a7411a329cdafeb511244", - "Expected": "0000000000000000000000000000000001641b4ad10da5089164809d82ae47f74e27eaebffc2a2ca3c1b924fc69c1ea80ba3da78c78e86957f6a24e7f75dcada0000000000000000000000000000000014e781e4fe79ea1654460f4b0daddaffb29b287efd8168cb20d7ac6c729f684c5f2a7cfa87885accee3a797febc904c200000000000000000000000000000000001c9a44547f0c5b1f4df190285644c5a31df61e3de7da085835ebda917d5e4163f2deea9a83d641a4759fa3108567ad0000000000000000000000000000000014c3d2a79d80687fd6e6aa423257644fa5d0cf641aaf6a7c5675a810767904166fabd9a2ced0727e3badb932e46fd181", - "Name": "matter_g2_mul_53", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000074d78cdd35ea17a3013e2301fe9f80f2d20d270a25fdead37eed7697a52d152612543781763e6035fa5452ab12cce25000000000000000000000000000000000e572236e1c203a1c0f99e6ec978458c1a143a6a650eee27cfbe406bb2858fe5f30222f468d119703c2f442bc644ff3000000000000000000000000000000000125384343fe132e16a9fc15efe1b3a9e47289e0afc4b44d492e33a6216edbc96d66c1ca66944a8296e7695f27f414c5b00000000000000000000000000000000084c2cbf0d7c932c3098ded7c70d4411eed882feb0f79e0f7f1c31f5fccb6d53fb57de179c3ba5754bc5e532c3784df12051041bd2f12f6e6e29924139770fe209b7bbdbcd6c0bcabbf5021a7dff2d83", - "Expected": "00000000000000000000000000000000129554de7de9a2b73340d94d96f0356a2d1c0524cfb007d76a75f462872e831f45553de05f5b6a1f9eeae37af7f6b4c9000000000000000000000000000000000b1ea2a649ca13a3dc7882f2423036670f68aa05792a8fcd72524420e37381a9ca80dfea701fa5e6da57afa534059617000000000000000000000000000000000b7ff27aba408f9759b5109600cff66c03cdb4bfb3dff64a4838d0516fa46bfcf429fcf9d5cbf74a27f70fdccdb1238c0000000000000000000000000000000005a99aec88967fe775c691d443e2dbd45080eec97e686ee6d7b32e801efe6563315bfafd5c7622d0543519cae4417029", - "Name": "matter_g2_mul_54", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000004d46066439c3ac559cce863c58316883651023990180470d2efd06e443a7caf3a514b54f15ce6e850d32779215bcf4a0000000000000000000000000000000019ce904b6c9c3de59f7d5017f60f1978d60c564f94a0f1964c24c876d1139a7ffbeb6d0d4884bbfaf5f2f189af6904a50000000000000000000000000000000015f1989719e69be95f25dda9358fb98aae2819e0deb7e2d291e2c01e85ba26a9da421896c6b6e2ed20f609b533154694000000000000000000000000000000000b287cfcf1dd7c6d735c1358dff15393ddd6c82e7a33c5d8005c4234cdf823c76a4725fd74cad74b3ec51df67f09af0fb96df57a600dc3b5aabff5b1034886d24f6fcf035bcacaaec738deb2cfb8f852", - "Expected": "0000000000000000000000000000000007997a499b2194cab634750a189cca6783ff17d866d66f5998603f8639d2242e8039222c65b0d14001167a9b09afb58a0000000000000000000000000000000015050fe6b335884a225efcfea4acd025cfc05e8f5fe9a0e22a0c91b55664c118d79887de91f1ae6cbc081f6f55f0067000000000000000000000000000000000195b23c4c2c087082c30600ff00485d169dbd360643d163f1db363f270cd7d4f177c36b4c291d50da4101e67b229d0de000000000000000000000000000000000df596ba2350ff7d3e75b4cbe5f8d6b2cc0e14b3bd6dc021936e3371ba64031f6266fb1d2951801309f22bfb1c4b27e4", - "Name": "matter_g2_mul_55", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000006b37e2226957d639fcb0bcd6c20b3c7b8372e7347a14b970e01c67c1859fa97c754ce588d0f835ecc053549d963ab4000000000000000000000000000000000c6a5fae8be3a32e3f70a4202a1ab6d97183964b9f7b9a084c49922cd9e0e952b0bb66c5580f0e0c417e079493bcdb4e0000000000000000000000000000000017b6132f11adc0d5d693ae7f3a0f89f5779708083eba23e03b0c9265e4e60624e1fb6940e8ee49d31618fa6389b1b50b0000000000000000000000000000000000a45c5f6df71359648aecb6434bad1619c39f10e279a02b3cc9725d0256bcd126843fc9ed29cbe02a32cbbe79774a3378176412b07eb7f423f23ffeaa0ee642590e0b7016bc063f3fffa93e1e35484c", - "Expected": "0000000000000000000000000000000001fa243b548f8f5c2e5d7736ca6fa95b74dbfd31f95fd532b94f81a255c73e7c0e000e20f9ca6750cb0dfdcd2c1aea8a00000000000000000000000000000000132a893a2326bf61962e1855331a53667e6279ed7358bc84c4a7c218b6cff1d3f449954f56daea72bc2779c60f1113400000000000000000000000000000000000091dd23c75dd8266f556bf27ba54c95c3ccab06168e4e6d0747239722afb20f3db27454c6db3a88daab0ef10659a66000000000000000000000000000000000d3b2e3fd358aa3dae983e87b5d1fce6d5688e66ced6e3a2c96b8d48041557295d5932af6532c13965d4b383fb252518", - "Name": "matter_g2_mul_56", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000ffed009c78ba9af8cd33af7b7697ae4dff863bb92365055baedd2299b7f5b5e8abb84ed434f7223c3e309ca53c08aca0000000000000000000000000000000003b2370c837dd6291818efe7c9af62dd51295c418739ecc509d42c92e2c97d12a9fa582946e176e8153fc9a273140b2f0000000000000000000000000000000001e63438e8b4a0462cfdff64a281ab4a7f48d51b51325817139f8ee683484f8695f1defc0c3efcca81d5fbff06cf9c54000000000000000000000000000000000192fc391cdc1ed6ddbd317f2f366f2ce25ba27b8c0f09c733e7bc0c0697544399a3a4f1186d139a8f6399ffa88e89a69c4b5627d84e153f3a4ecc14ddd6baaf1d62253a0f88d3af51be18d991976da0", - "Expected": "0000000000000000000000000000000005095d1becff61df906815842112c6508d6cade4ef5f4b7418f5f01e8c5a383addc1c572237613dfbbb88bcff80e4a44000000000000000000000000000000000bd2561e7bfbda8a48ee038855e37b03fee805689452e9afaf0da4185e0c194e407ce7149b713c689d25f953da36dd1f0000000000000000000000000000000015ba3ae4d4238175425ac5dcbd9e6e9e055b8c1b7752931b524fb546f7bee8723ef2e69351450c6d1ba3c366a22355e20000000000000000000000000000000008c17d77dcfda00a1d75ea0087c58e74263ce5ce4066e979c66397de8e236708831c3a9ca6b35ade8038a28930655eb6", - "Name": "matter_g2_mul_57", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000002e105e0eaa418d58019a849b89accf665a94ffb0bdf308a11b99b521de7af8ddb150c0e3b2e9c54cf5456b6105bc81000000000000000000000000000000000691a3b3986fbe1c0ea22329364454f37f645d6abe9310e883b9191ce512347e074e18e28b88c2adcc76190a549b80b40000000000000000000000000000000003f3a37a763c8d0d99a3fe36923843a22cb0fa18ced48493b2510fc99afe5b7699bbaa6c2ecdad8aaf72969354f121a1000000000000000000000000000000000f4bbae00205f54eb10c83d928d908fbae342b76050e33c51b6e282e02b3c1f132a4728dee4ea95455c25fdfc112f2542ed270764791aff081f1dc8051d22b8e18803a7e310393f21bb4a495a445cd45", - "Expected": "0000000000000000000000000000000005cabaf39b93d7fe15ef6a7a3031df58219bce702a5a77162551a3d916c22e8ec9af2aa20659e7c4ce5f6382a5f82726000000000000000000000000000000000dcefe1a48d8c239164b54771118f7520ac11a7a6b72d8e17be1cd788cad2f26d3a0d9113e6536426800a744be9f0d4000000000000000000000000000000000199d95a44a4334c87aed273a0184be9602ba443d5b8d34f3495b04e927f4687fb88487f586395c7babb4f218fdbecf8c0000000000000000000000000000000010972032f9cb3e8f45447bdd06df82656fbd3ce38a9f7564c6e5d62ea3596c9b7e0a94046f1c65bf0452ca25b15a885c", - "Name": "matter_g2_mul_58", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000009a3e98fe4a98582ce9f274965f376cb45e8583775dbadf626cb1327c1f8a25b293b97e7f8f31ff72ba7e8e769ff25ef0000000000000000000000000000000018e4785ccb76c4897087c8a4242ddc744c6a0a53a4a844254153c23d6f16d4ddb945252d13f93101613f4eb0b1e2b8320000000000000000000000000000000011b81d344eac04d3471b1edde5e51f31f97bea3396580839fa094db58cf6bee371bbdc045fb60c3ee5c6cd5d3f6d3c4700000000000000000000000000000000073476bc5b1d52ff4ca89c3afc099417f473543fab6e59cf9de8a19705dc4bf2a210b1e6de4dfbde035c312be0c70c56fbfb7606b64eef0460b8f33a0be54451fb655ce0b81db89eb7862f392450354f", - "Expected": "000000000000000000000000000000000f250b5e47ef616be106a3334e2f516061eec8f7ac69f08f6dfaedecd76fb1c9685ecdac2c3ddd534e3947d007ab177000000000000000000000000000000000073819a6de38303725aa3a9e5a7a9122b4d1e60ee8deb3554b5e06ef5e60d71517c2279c5066af003b32cdf83b7fcdf200000000000000000000000000000000070721107ac6dac198f7ed1a7f84697cbbc3199a220d1aaf82e6f015963bad863f99190f18a482f730254cef753ba22d00000000000000000000000000000000169910eb30b8fe1ad8f84c4a132c6c74a6ff06ed6e792af3baa6619e3c8aa6cc3e6f687299467ec9554f9e91bee77aa8", - "Name": "matter_g2_mul_59", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000c414b95b298b9c673001173ba7e5ee3e03926f28068481cfa0b469ab556f8fceba9fd0a815180ae0b82c265fd4c6b7e00000000000000000000000000000000054a242c1cc1a9c710bc23305d09c2d613ee8eb3840b37943bfe83f9c1db456ab4436ad319fcdd8684db129d76c95320000000000000000000000000000000001683711c0c7f02e67374f190eed1ce6559479d6d199f43fb5b0ce7df7774a5cb21c86b3b3498855d9b69c5763acd8c4300000000000000000000000000000000062f87085dfec847af518bd71c078f994b090c3b27c6eaad79772ab58afa43993db52fb08649a32629d61c3db12c87318a29fcc442d0c2446697e94dc47181dca7a314f9073c06aba6dc55aa79978d7d", - "Expected": "00000000000000000000000000000000106e892e336b2155909946ab73b980ea761cfe8c48b13ae8a5302eacea08b9cef3e60d5b33c6ec4033218ae5761433dd0000000000000000000000000000000015daeaee59f3b4cc26d3da745661e74db8fe1ea115d50ba49ef5e6151a9ac2f3135f0232235cac7a53e1e8a70eaf0476000000000000000000000000000000000ff494d17c735b934c2c7fb8f413103188fdb116fa8f4d4e43262968ab0fa1bdec23b0d4d8b1c2defe624092de36610d0000000000000000000000000000000008f70b7e9f2d7083774fbce3bff58a1c73fbcbcd9cb049cba71c0c3f0c363517c8956240bcacdfb7934d4c67b1bfdd2b", - "Name": "matter_g2_mul_60", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000083eea9b5b2d5ac5f7ef51ca889a4317322d098a408a741827fb3419eb12a51c07c788c2798cb37635e224e99bbc894c000000000000000000000000000000001312ec00f4b3a4305700b44b3f215779a9a8bfcf5b5d3a7f237a33c5484099ec9bc5c8537fae768e2c0ec62168f383d6000000000000000000000000000000000cf1d5d05d11e1d07074dd34211d0f00eae1df4dc550c55bd2fdafaffa1ad36abd5da30c5d3a5aa2845b1d95a5cb571e0000000000000000000000000000000015223baa9f2ea4b04fdb05b05bf3a94dcabc5e64189aeee39c380de9a34fe6b4253f5795f70bbe51b80e1aec1eab7196d5b468797b4af1978983faebe59a28f34956dacf5b7f65d25548bcedb518f45a", - "Expected": "00000000000000000000000000000000098f32b35e3b7dc1862ca1ca3c76d009f016c6b91c227f2cebe8f1fe87567d936bf1c54103bec31b3552c077c0242fb40000000000000000000000000000000005380a66d48d348487624a15b63d2ecf6976b5b599901101ea8b1f57736649b4397f6679ecab0ae29573695a921ac475000000000000000000000000000000001710c368f70a2b9cc92ec65c4c2ca35fd63440eb350f488e7c6646f9c42bf680eb62a887d533a91e47988221b46c868200000000000000000000000000000000033c3327da938dbe4630dbe16838229d7d427f3adf18dee6fa26b1c8067838922c1bce78cce08d590ee1acf2baebc7df", - "Name": "matter_g2_mul_61", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000011a960cf1978aa2ce1731b857fd91d2f59d4b8d7c6871ef6f4f85aeff549a2f397949d11a4793926fe7be37f3a83d11c0000000000000000000000000000000001954f056834d6e3b16043ef1acd0a47a353300257446e9a1db7e58bd0d7c4bc9ceb3db51ae01cfed9de99621e96934c0000000000000000000000000000000002e2fe460e71b65595ed93a0010e5ccd1a2c16fc4e0d345e7226c947f29720d2f3f54282f79cec086d3fb1999b9629b300000000000000000000000000000000060dd8a7ccb613f1521168a8a322aef9f84d9708a893f704f4fc9a19e2493f25620a47e0fff1bc1e212e65e92873b4f2dbc6afcdd409e5d50d7b655580f1144de77f3efe5d6268032eccab7deaaad997", - "Expected": "000000000000000000000000000000000404587c60a4bbd8b5b929ca2ec2a9ff2ba4733f4f2877478a669b238d65ca130cba398899f2910d6de04615f8ffc99f000000000000000000000000000000000940659b3e6de7c3d8de9169a28e68dad433bda78de0991fe4a1d404e5f4babcba9d57c7f3d638aef264642f87c61fc8000000000000000000000000000000001676ce240e1ff70ab03f94f3ba3acd31725ec306ce1fd707e29ec22cf91746216dd998d03ba13a79dedf878fae38d68e00000000000000000000000000000000098a81422511f77191ee15d402614c86f9447ab78a89cc348414108f36857a1929f2b92ced78752ab3604f276861803e", - "Name": "matter_g2_mul_62", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001472caba61c2f1fe4b1d0912b114c25de103ef4351668f22f3a158d7a347539a7b6656044bd490f036ca3e29dbdded370000000000000000000000000000000015f8cdf7786410b409f218164063c99e77d8f72f03882a6c9430ec725ae574547d3ea3cf30c3ad2c9c3febe6c30b1272000000000000000000000000000000000ccbbed85c2809433fbcf22d6490457dab800b21cb4de414c7dd1804a0bdeb7142f8ffbb2de921c2c9eabee6a6351026000000000000000000000000000000000a404f42c48e3ca408d3f92079b99805004da928f128206d8904ecd7fcb14121c7d9a9e7fb69accaff921315ef3d5372807347519f114e78f99617f6b147ca833bff7be962c9b1e1f32b5babe6067d7a", - "Expected": "0000000000000000000000000000000010a4ba6952d22a51dbb6762a3f9bd09712c2be5a98bf0ef298d7a7e3a9735ab0d3bf39e40b334895c73a36c218ad24b50000000000000000000000000000000002860f38ef61b497bdaf4faeee7b406007981c17246cfa36cee906452ae85e1c1c6385898ebadc3b4ef8887fff25b8240000000000000000000000000000000002dbbca9034fb17c3f37727d44c027cdf47c36f3f628ea9385fc9fc371d23f22d983656caafbf1cd1f8bdeff4ad7669d000000000000000000000000000000000b7e71b65765c4113a7884771952268a9fe10576f745038912e6877c78372cd261220793b888c43accba1646e902fe14", - "Name": "matter_g2_mul_63", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000b52f05365c4df20a7290aee71a7e030615d1a2a971167884d835c24e756a0faf6ed0552341c561446c7fd3d5e887d830000000000000000000000000000000018718ef172c045cbf0bb132059754b62414097eef640a781db6ad521af5a24d78c622d9402033fa939f70aad0510a1ac0000000000000000000000000000000017e969e44b4910304b350b5d442bb6a0b71e1f226cb4603cc8b4dd48614622f3f4e1ddecb1894046649d40f261d94e030000000000000000000000000000000004dacaeb9e05b9d60ce56c17312a092cb988bff426b8a718cdff860186935507a06eddbc4a1a29e4ef88db83fc4b6e77830630695c8dabe9aded1b5365bf93770aab7e9ef4140a2bbde2f0a7b109724d", - "Expected": "000000000000000000000000000000000e9c1a6d591be4da37fd6dc283b8d899b625ccc96371dd3d7731aca66cd2a978810497171f2aeded64fa2b10e480de2100000000000000000000000000000000006d2ad7287847255002480627782d513eaf1f68a3d583d4762fc156b8eb40deae6969fa8a7d8f8aae923800091386a00000000000000000000000000000000003c7eae0eda08df9b9eee2605a44fbb486e3bf2e409aaa1c8f38c06f969ff1f74338004b01288dce99be26a837e45d3a00000000000000000000000000000000178174d2f569a9392eddd2715ceba8762c5bcc6325217db5e5f970d6fde069d0e48a824e5b6ca017891de175c92f6b29", - "Name": "matter_g2_mul_64", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000019829d5799eed5a081042e4646d46fb6bead6d3b9893a4240867b25ed6af6a3e154514f244466d80e3b9311e060bbd7100000000000000000000000000000000156157a654db2813cb9c1b4da0a3ee192fad076bb2767020fc5fc00e967c1a35a367ffa375703e1181b3705ace9dd28000000000000000000000000000000000093385a6a9dd0ab996df54b23f47f4a49b3f379e11bc8331016ecee6161fcddd22f6d49fbb21f098873f1e17424dedca000000000000000000000000000000000d5b5b0f2ce81e755b4030b33fe3a8bdee38c2c60ed3b4a88bffb9207cb762c0a5c699ff424c000ab080d763abc5438d184ef5eceadfd77b3a4092696ec34d0551c88e434567638623740b7d5f9e3616", - "Expected": "000000000000000000000000000000000ce12c9010b4c4afbddb459c1b46063a8488277948188b4ec0b739e1cebb5653681d0e43a0d2c6b3f842bfc609bbdee3000000000000000000000000000000001123f60cedddaf4385e63758d64d4facdc443854176ec199ca0df0a9c258517f2512594f2441a4b9a68aa9a2b4a1f4bb0000000000000000000000000000000007cc6f77d181d13bd9736ee23a33b25b0bd969760642ee19004e095ebb8e2b3c0e09321eb15a2f7961803c0fb10b6ffd00000000000000000000000000000000004d8dbf2f0c14b07ebed2b9cb4bc87df78ac8a34ef0b05cbc2c6fb8e8156415399fa52dfb968ef0e6ec697030fb003c", - "Name": "matter_g2_mul_65", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000003af8c25bdbd0dc1cc344d55366f15555709a74e1f0d8d7050cb6b487759db6200401b7868fca3c2ad26e6362a30e6250000000000000000000000000000000013f8b6ffe30f9a133fafe64461d305cc6b2cf5aededf68ba396d4e00df651531c750a3d94dd77bc5c6713b939b18fa19000000000000000000000000000000000dde97855d7728f409d873b83b6879b45ace5b73f317687fbf478e594a959ce21d4d751db646ceb20432e8311e67404f000000000000000000000000000000000fea997323cf29710cf0e3d44ce682e039d6cbda155e43c94dc8cefc5e94000de4b9525123b9615b5f1019a46ef37ad3a80d9efab033e920061cee8f8d7ea6023cc05f08340642613628b39e7b7fd0af", - "Expected": "00000000000000000000000000000000172805bc715a8cfb2e25c384214f4005aa6d3b809a0ad95322209851ef92151526a9d01a914c4d7f0c120b9bf3837010000000000000000000000000000000000473ceaa092a5ac12f38b4065477672deacc08e553d8e9e6391bac0d9ca50015934cdbc340deb05aca916cf50c7915b30000000000000000000000000000000012e85461fbd26c2d0235acf5c8665750656819bb939e8fae77a8d526ca23443aee395a985cdd4b1eb700311fb87e91a7000000000000000000000000000000000246d45fdd88448c93bedf4799becfc7c80e67abd483f2a0aa41e8bbb3f38cbc900314436364f1db6e1d88595544517a", - "Name": "matter_g2_mul_66", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000cdf60e3bb018407eab162822468255bcffd54cad9127054bd1c30705a4ebf1afc7f539cca6ba4cd070b44410ec751150000000000000000000000000000000009a2e3e5993b6a7007dedbbd21737a8c0aef3ecd4607953c4a24bb3fed97ccae01ae1cec024443f300b570a66e9ac3bf0000000000000000000000000000000008a21fed19e9ec2a741ade7767b0c9f39b79c3fbe34aadc9eb3043583768d893bf927d26231759290c7dd9c4f158d5a10000000000000000000000000000000018eef4ff88d63149d2632c9db586a4af0606644b16c82fbb0a3b869f1ff924c59acc8efbfde7bc604497ff68939cdd0845111c860f6f5725f99b225c53b9fe1a70150e7ce922bfe214900aaa2790d145", - "Expected": "00000000000000000000000000000000122e1f2081cbde0055fc34d2fe61307bc333b35a1e0772a0cd6fb25338c89824bcf2f066bc7b571b2fb314ca7f45106c00000000000000000000000000000000027ed81b54372d858a6ba2faa65fdc132efbca6ddcd56c3625bd9267cf0ae04f6d342209b995060f584be8d40020669500000000000000000000000000000000002a03427a093a3000a1bed9eba91a82dc2f2fcea1a16a1fb8af29c4988b589abe6a505ec87a82864b3c683beaa6420f00000000000000000000000000000000134bf64871d69a72e42766c2903fb4589b84d7772a62f7d2f8f8d02a914f4d3a278c680c626ef4d69de8aa88b57589a7", - "Name": "matter_g2_mul_67", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000f5d47911596c46c0c08cac5f5e7f6d0609874da4ac1bd4e0e59c393273a5fe31a756c7cfff2a01d19e79d209d7c6d3e000000000000000000000000000000001010f864eb6624132d4436d18db7f5b34727060dc426c109886be88031e3c155490cb3fb09e1fbccb7912875477c6d840000000000000000000000000000000005cfbf1c2ae1b80a8c7cfb2cefedd907b0552794f4fda101ca1a723b18de8cbce30eb54287e1847cee3f416cd8b45f2c00000000000000000000000000000000084fa63781f7eba9c7e911ae5866d485bc7e90603541c55d1ffad8b3cf7547fd57fb24b14002560e58410b828513e109c07041840216d60ff445cf53b273a46016c8ecefefb53550f8bafc79966f863a", - "Expected": "0000000000000000000000000000000018fa44efeabbd1cc47dd9b1a1195ca921c99c77ed43a44502aad27b6c663f5ce2623382c3ddf208f42e3eea741281f4300000000000000000000000000000000138d11e497e3c5656bc8fc0ae4322a0bfb6fc20e249a47a103b164aa3d9fdbf7df4b1e3b0842b4b12568a31992a151f000000000000000000000000000000000182490d6ae35c1208c0d608984df4988d057f3ce5a25073c77cd5b224a5892768badb1ad5cef8f41d1d2022573098c320000000000000000000000000000000002a6e0523781ccdebb75063dc7ad1a9526f9ff8ea1364bae487914f254c0eebcbb2cfc3715fecb9599bfc2f5feaa62d2", - "Name": "matter_g2_mul_68", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000124870cfa469136c638e0cbf15802f2699aacb66d7e4c2965c6759dbca4b7e47941ad9ec37a84db1afeeeaa65a7418e4000000000000000000000000000000000d4503049a6a53536bdf41dd832a6ecf3f10554887da7e389cf940394e1d88db94369b7947436546eb6c6e82c48dfb9900000000000000000000000000000000053f9a6e1f05b67cf553073358009a172e2ab8b43572a974da1f3de85a29103b13d7e67b2a359297172d27dba5c61439000000000000000000000000000000000abc29f50ddc1c113c73700b9b9796890cbf48818ba981fdab2db27ef1c58f4c2e4595b99eae397d40990ce2f6c9317c29b031b82dc8c9f4ea9524793b54207d4e13a548d73297f2aa6241aff57abfd0", - "Expected": "000000000000000000000000000000000dc7488491433d5b3924105c01ffed4f30b755d7253d867fda595e7d80197823e56e4d182d5ecc72d8ef1ba9bca15a310000000000000000000000000000000007bfeeadd6fc468ef6340a2b394c155bf50808cb11e89adb0de5499fbdde91760e9531c1deb23050286a15e5910f1d5a000000000000000000000000000000000f096db706b08485fd577f37b7bd232b5a10c3f80c25bcf82f7a3b666c6efaac8e856bfe5f7dafb7457e33eadcb4133d0000000000000000000000000000000004460d1f25159ce6df59efbd7c693355af4634dadeaee2ced68124b2a887698c10e9c4b40c4f4f9c8444acb881ceff65", - "Name": "matter_g2_mul_69", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000007d2aae9794b7a7de97f7146c0ee8415e09e56fd42535bce6773cadd6f7ac09c4eafe2e926cb7014377e54c703eaa9dd00000000000000000000000000000000172a4a33ccf99eb0473b2c44d30bd53159afae0c7706ad128bccf6258974d5e5761f9be43e618cdbd96027aede7fd5860000000000000000000000000000000012601bce2171c6e4c2968a3efdf1491285f9e4ab37cf973ab5c8e224ad5b40e1b6459ac89090c73deb8fc79fec7fb8e200000000000000000000000000000000112a6443116e6f98ab348e57daa3971b5fa506e40515e1611fbed3e7dd64c5c1e991e0d2539a70eb93e3da0f573d6b2263d26ae92119c7b06d83d7e2922e06559b1740eae315c6623d3e543c9bf54258", - "Expected": "000000000000000000000000000000000f1aa4a7a22c568c41270d24824138bf9ffc763a5356b7c0bc1d051a0a0db12616700d9214972b63eeb2a398d27dc83f00000000000000000000000000000000020d0c2ff8f93db6b415c2a01712034e46bdeb6e665a5177a3877db9f5401d3dccb99907ef843062e394c1428983725a00000000000000000000000000000000088abeb6fc3ead45d5b261b7d684f168ca8f5f163cf338863e6b102dc40e2cd0ede97c47460ad6f560c27e95c8b71ca8000000000000000000000000000000000ca2e5cec212d581c737928512118e2f51a0d74070f40a998b7b06d22b9fc754bb2fa5499308058be9ab81521d057414", - "Name": "matter_g2_mul_70", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000030372914b83644fa4db1958831e9335c72ab7a811fb337696221a3290e4c54bc10c2225f8fdc3a9f62632ba2f1594500000000000000000000000000000000114205926609470b6022d24046a1997c048e6d2cf6043397892c967692161c0ceedf409bf5e1199a64eabb1ff8de23640000000000000000000000000000000017cdecbe73779855b7b94920d4bc8ad057ce51c5481a5579650df8a5bbc421030d2ac44568217c4dbb13d7c639760236000000000000000000000000000000000f194fa814bfa7396697bd812d9449d06fc61b580d7a86429fdd1ad376e21ceca139356d7d13964c3c684563675711c67a02c61a7a75342ee7f0745886c0ea2a73c21500aef8078d21d20b7216c2990e", - "Expected": "000000000000000000000000000000000cfa23c46881893f6c50d238a83669deb520a7fffab4f912f77df7cca43f6827a1a0ae0b3f36c8f116ecefa33b8bf37a0000000000000000000000000000000014b7e5c18d2f9bfe15b0c1af3bc6e230039a341e135837d123e91cde9cbcda298c66b93f692232c912e5d7d3d6331c430000000000000000000000000000000009c8984999ecd3a4144ccb925d3e5cae5c1662dfbf8871013b1cb2946482fcb075c489c61b8d6261f2574b44da3fc1ce00000000000000000000000000000000196e7feab383211e4825cf98219c63bf9f45a72d66030219cb585d5d25237a01a97f00e122db6a51325022e69e7d8cdb", - "Name": "matter_g2_mul_71", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000015d4ae1521acf897344c3a76261754ff99742585af4a0ee86dc473a88fd408091404df1da9d8bb291db68bc9c07d6b2b0000000000000000000000000000000008ce160213875c661163990f3f7ac219ea295db5e828354864517ea8689ec15d35c6df78ff14cb276e0c97ffd7fbc09a00000000000000000000000000000000038a3ee211e777d6d6b7ca6c7a0d2130f1a071c030eebec412c3a0f14c3584e7c5cf15de254a8f141a8210a90249ee5a0000000000000000000000000000000019f7ec6b2fcd8b3190ab37a6e843340d3f3fc092f5772a042edbd5bdc967b96e8a1dc9e435b8463496aa1301f87d0e5a81b0c87102055dc2901826875d5e85a794befd93fccca2b9c0a1f70ef5610d83", - "Expected": "00000000000000000000000000000000005c0282830934ea09c9f51b52cb6dee75b874b155c63076dbac2cbbf220863d55557ff1b7d681fa185435df1522f49d000000000000000000000000000000000a1680ebbb185c8e7d8a197a523a7a5e618f97c46670622034d312b3eeef140150e03b00ae3dff8d9f1d872f3d3dca380000000000000000000000000000000019bd2eb4bc25f5aa6bce206f0683dbbbbb002098a118fcfb060c1353a310c2baa1063a782bafcf6ff6bb8edaf6f1597a00000000000000000000000000000000082edf49a0435e0b9f3dc7f207711d66004ae688b18f5b62fd1596899ee8edfaac7da38973d81f12200018fbe8151572", - "Name": "matter_g2_mul_72", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000fa7f8fbfa1d4ef5f001a451c55ed261dee344025e599884b29d086e15665867932120d33bee579d5eb1b7e6c7299f310000000000000000000000000000000001f06356f793350b17b47a623059a068800ca1eab6089c7c146182990063e8e23bbf40d95a42bf6e976224b680b75bfd0000000000000000000000000000000008807f6606d2302450bfd8b38fd4147b851ff59762c1ff48f9442c4d7b77a32c5e023821eb47fca839a27fde60e5f61d000000000000000000000000000000000c5b92f1ca9c20d4b6b11d794a5853824cff20d9267a20a7aaa4bed8bfdc728c4d4d50feb8f0b569757b97f473138db1ebf66fce49c6beb12737fe05e3adc0a51ecfa9144ccf6253088dd1a7a483de07", - "Expected": "000000000000000000000000000000000b8a715c1c2792a30f7ad752a808b621c34af1fb7f1e3392a36ca9481a019108a21e3ef338a1d05f2f23ac3e2cc42ed500000000000000000000000000000000101375c9de592031c55a7a62189fd3fa3c565abf7c64724796dca3b1c7a6e6834a16ef1c4e2afd6ce2e69487260f0028000000000000000000000000000000000cd385ec8245431d3b1aff88453db7f66a5d7888a5c1e0dd0abe9ac7db752933a343b8be53b7bfffb704768ef0a3dc5c0000000000000000000000000000000015d55c8cddb8715e25fa260d1e1fa672ff76eca7c80d19d00678fb9d08759b810cf266ef0a7e9dd749a576ce07240fa7", - "Name": "matter_g2_mul_73", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000001191410ec6c5ff628bd25d35965f5e9fa7f3c3d8c0a9a1ee7ae37437a97c25e221110d892e2c7a0e9c8e386774eadb80000000000000000000000000000000003be30c25a18cdab139277232d8888f6d13112c9556895af8030f1893114d5845d895df9afe3c6f9ff7ffb1919adea9200000000000000000000000000000000197f6b4e38be0358a3f1722664c61e62587ecf5467f8aadc3a236b47682a75cb76bafb18a5c556b321d5da49cd4bfd4e0000000000000000000000000000000002e4ebf7f22d929b7421a600e67fa2e64a59edd87a2e2eb9dce1f06d3c793f1a812bcdd510e654d44fb4c1de8c64ba9f0305523dc79dc4b905e65587fbd095ed57aa42403d2df5dd489db8f50c99e9b6", - "Expected": "000000000000000000000000000000001311de31229f1825d0bd2c9d726fd71e05828a20406a4705ea65f441537486338022bac4e552bf3c25e15717bee00ba400000000000000000000000000000000052e082cbe36c854a028a041981fed87d39fb218a88208aa1096e260a3932a1155db7f306c32d133070b0a5bb6d161760000000000000000000000000000000003269d4afd20002873f4305018a4432c1925eea28486d657cb458198ff2df9d304bdfc7455233243b1712d8663591d460000000000000000000000000000000013376fb98929cbe7f7d090d1c9d5c4f6332bbf25470aa03c35a70481931e4bc91c937029a5e11d2a3418eab698361227", - "Name": "matter_g2_mul_74", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000011c6f1dbccde640f63ad7d40089779d01075e26269421b4ce12fa5341f58ee9110f17d08dc1052426f2d00da2dd70b4f000000000000000000000000000000000740b147bcdf06705971c113a5cc12fb37345dd59f2cbb5ff500ce2b347fc5a8199cb3007a871670d5093f28979cfade00000000000000000000000000000000046563ea98b5e85b3c42222d5e0d8481e6aefaf077a1b99f2b4eefb397ec846aa3659aacda569054c9c8b9b69750272b000000000000000000000000000000000812d887943506d68e3525ced9b979354539b7b14003a3169e0084c26326b92be67346920c9a99ef0f9638e8991296feac23d04ee3acc757aae6795532ce4c9f34534e506a4d843a26b052a040c79659", - "Expected": "00000000000000000000000000000000021166263d1a443d5b2eee9aeca3678ae4c2b44d556a7cb9631d47e4fa3bb05ecb94d6582f4ca0cd787027fb5f2efab60000000000000000000000000000000015335d034d1a0ce78e1246a16e35e0075f73d4a392da1e05c11388084cf80bf31d499e57c48f4be6e72d3abc7b387ec6000000000000000000000000000000000deac4ae1900a4e1814624fb4b8c7a3149fa9cff2ca97f02e7d6765e034a1532a7b8475ef7aef5ebb851063cf4b9e79500000000000000000000000000000000161e3af03f226278a07ff3b08e5788f6c5029b2c8293e7a7e3ae11c4d78676b60dc0208cec6b82e1714d976007fbb389", - "Name": "matter_g2_mul_75", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000004c8078fe8567013e8d05a546934026cdeee7d485e30d739407db16fefaef53ed7bff0f9adaaf064aff014ac919d91c600000000000000000000000000000000107cc17f485af7f22e07cf14c5cad6368323f720511fc9dda677b360567f769e47a77f61274927ef9b7be48a77357ec40000000000000000000000000000000001487f0880a6cbdac33ca35b9b65e4ead9d8c2e9180c993bdb2052060325aff8c62668c643f0cd9b4bb1f06a3dc74285000000000000000000000000000000000d4b2d062e31fabe8d2a329dbd6417673a519f455739d140246f2b3e43e20f390088c08e545bf0419d796ac71aebb5198586d7ad8fc3e4fb42981a4415224c0d976ebe1c342e9bc1cd66d35168bae33d", - "Expected": "00000000000000000000000000000000120b4434babedbd8ff295a6e2ed5fc7af0548d7e60663110050be797584c0cb638988201ae7707cbedf0c8b3dc5ced85000000000000000000000000000000000d2de0a260bdd241a145e3f68a6de48da4c65107a500e02bfeae6ae7dc428026c7c3e9bdda9a3069d2744705df2eda9b0000000000000000000000000000000018a237906c0e277541c4f00c4c2feba7cb2c9b87709c18b62b7c36d78fc118cfd65c127765e01dc0ae5875b9552bb45300000000000000000000000000000000197485daf54e98e097b6bca24b0738682969256decbf3ebc05f6982e4608829f37e2877937b3f26b88efc3deeb4bfacb", - "Name": "matter_g2_mul_76", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000811e9b0acfc10830c074c5a4d9f4d9382461eb523a61dda0b77f1c43b285fc5c1ef3a1fafd923addc9a6e904505a255000000000000000000000000000000001113102d015dbb509f0b8d0d0ebb4d3711c4f0e1e3d55fb0af247dd24be4fec9d6fe3ad73fbdcfe206891bcebefee4dd000000000000000000000000000000000085aae9e58fb97b96ca3c089acab7bdbd0c3adae141bf61075f5c13145b0d07113f1075dfb959bc7c2d3d3b3a06ab2a000000000000000000000000000000000bb5eac8125807c10270d94e5bcf278241d6fa82f68e41b5529b28aebc88870af55881db526f7bd221a8c4c0b29a1b7d6e7db0fbd2a7327c85054b4c0de9727dc0b051058f8bb4ecb1dcc7f825781712", - "Expected": "0000000000000000000000000000000005de82540aa67c69b962d292133b09e6593961da8944ce02557141abd19ac471f766b4083db85c67a44b65dad2202488000000000000000000000000000000000cd999bf3cb004074fe9f355cd8dfaa7b9d3439d902fddd2fd0688419b5b7f8c4300ab26b658936a90c0b8e1488249d1000000000000000000000000000000000f97ae779429a5afaf7a3343586eea84a4e76f00a1852ce42a4940babd565bc8d61bf72fca9b123922f1ccfb1db8c06b000000000000000000000000000000000935960fa941c27e74234a07857ee680f53c31047235c6152d1669724bdef37ba642cf4e0dd355443ea470e6430def8d", - "Name": "matter_g2_mul_77", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d94685cc8d88273d4aa822f44a447cc22f5a58c420bcfe757a459772825619669a72", - "Expected": "0000000000000000000000000000000001b0aba02b0e907c03d2f4003083c824ce60f2f55f70dc6ec7c7f81f3d0ef4bf533b4c94833e36e8aa7aeec18b7255de0000000000000000000000000000000004fc227a6ae303f3006f75193cef7c653e6bddd28fdb843b41c7d39966a701ba8fcf611efa71abf059d7d98833480e69000000000000000000000000000000001077fddd0bf3d5c80eec653916f9095e900cf165315d74a872219285f62b5412536e43c4cdbc120ec5c7753318852dfe000000000000000000000000000000000ccd90e01c1d4a00f0d9e29a88e8134f2cf68162da66bd343645a998730190114a6921c9b048dda58b60b42a133287f2", - "Name": "matter_g2_mul_78", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000010192b925fca096682acf138833b12d96bf97c9a2e69e4266eaaae1785b9008f36082e23e2d42341427edce24449935f000000000000000000000000000000000d5b24a94adadbf542aa663114096bc670e1b6c99f3b661f55de121922452534faed7f68d6b431fcf6f3e379d7acf6b6000000000000000000000000000000000acdbcae49206b749d8c0d21017a33e689ebe26804d1fe7c863a2ea4210c3559805dcf73685702bc56e644b4e02614a9000000000000000000000000000000000092309d684fcdf44bfa321d473060dc2d8a8c66c51419894a3fbadbf1b56179c31dff25403b970d543f1dd0e19e56cf5b6e462d809f8bf1a62f276dcb27e42d9aa0ce33fc4e149e87181aca70a4ccc6", - "Expected": "00000000000000000000000000000000185520023714580a3f235e24316478b8260565ffabd39670811519066844e131e337bd62ed2069bc6d2305e6638e539700000000000000000000000000000000055fc74cc7cd3fc393d5b5ab2419414effb783ff4da2516e5465a4acc195339c7b5238be4e0744b3d7fdbce46ca7f5dd0000000000000000000000000000000005f584a0311c02d611c15163529130a2fb3dc853083e7225b791ce5ff32d5ef7039c80edfff317ce9ddeef84443b5a51000000000000000000000000000000000f9d5acb355f767cc6286cc09f6df232532f9a0e9e4ed1fe28788abecb200e22066c23f3ac6c49c47071cbb023e70183", - "Name": "matter_g2_mul_79", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000014441b14765eee30e8131a7ef62c3b59370f2f6f0dda20fb2a3654fa09492bf695de1d1a8f250bfde3c7d2ed805ffaeb0000000000000000000000000000000019d813f8be2519e89d42a9fd3fef09d44a996d6a4713a9c224bee10f0ebb196370d6231fad810edf9cb4c875f08357890000000000000000000000000000000001a5abea13e909bbefdb51ddc699614366f271b2f6490ac8efcca7759833f3feae11057ab1b9ea32311e7b6ea6de110c0000000000000000000000000000000003ac2bf3c5486ca176e34ec5212165cbe04fc9e8c375e3e999a31fe014eb824ea3f2d06b9cf8b86ce3a76960cf2eb4d7535b53ab5f1c596eb966f57867e021d0f3b099e17bf384479c959794b17d6a4b", - "Expected": "000000000000000000000000000000000ceb56d75f3aa1548c50d7780ea1e33c3d069b2f37e7f96be6a8ec03266fa8d0868822afb3b2e54750722266f6032a8000000000000000000000000000000000080f15b7f9f2c22f1afacf558267b5b84f3a6d199fd3349eefa2e46c4f332849c0955d19d4513151dc0f3b566c0058440000000000000000000000000000000013305f8ff6080f7da05c28155c0c2bc1c78d855cdcff0bb2c6b82cd5107d7a070d0830e6705f6832ed5baf75a659c8870000000000000000000000000000000018f4e136859b4ceb230450f9abde0325a4d59db98279d7fbab710305ff53250dae1c8789cccc27586c9b9df5c0c4722e", - "Name": "matter_g2_mul_80", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000598e111dcfeaaae66d1522be2a21131350577253a3f33bdd74a04b0bfba2940e73b62fefa8f0c34c4aa91b633f6bdfd0000000000000000000000000000000017fefff7d94afbeceb33714e9b5480c3a2f3eabf9d7f6e8507ae54cb65f69b21cd7d04d23f24e3a272c589f572b91864000000000000000000000000000000001652e3f5a99ba8dfbcd1f90de955ef527947642054be603c1b84b24bebb579b78e2a0be426ec21d32783a0e55f0178dc000000000000000000000000000000000a6c9ec91e8bc86ab198416cbc76239f0ac0b903f40310ee1f2066b01b08191538ca913c2736f53f23ef37fea13d52756e0512ecbc5a1b02ab19bc9bee4d3d9c721278e07b7a6e389c4d6443232a4035", - "Expected": "0000000000000000000000000000000002a0214be95f020c70221fb4fb6856af7ce3845a4b607340f85127b52f8a204efcd94a152835860a4ddeef84946671b1000000000000000000000000000000001767777740a9922a91c39a36e2cdfcd544df902b31812ffc88418dab7321f73406ab142055b5bb264c187f2d4f2d6f9d00000000000000000000000000000000026e6941364c74997506df0f9fbe6b2769839e8b7c7293f4e63d13bd7bee90ff779cf82adc2f23c569d1e13826cdb0e4000000000000000000000000000000001618ab2ffd4b823b9c9776baf849641240109b7a4c4e9269f3df69a06f85a777cb4463b456023b7001adac93243c26f5", - "Name": "matter_g2_mul_81", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000072e022c168461905f798e87425f2eebb517e473cef98c255d0fe434863ef5811920af65bc946b29d489b5dee1066c56000000000000000000000000000000000e7a9872caa82d191f6014c845e1b3ee4ea1ee89852b546a2c85ddbfa3c1d4ce99002e3d7732ccb8cfbd57d550285ab400000000000000000000000000000000144be65db373f6401d76e0ee64e51076b861e8fca596dd6a7f3b5735c23b0cd13248404fa0969ecaa701663a1032f48a0000000000000000000000000000000014c9e9c5cffc4518889f7742440053678ff1d9fb1a1a103d0c1f762b10655bd5849ce98f4bc5eae80bdd9e767aae4523a79fd15e80b694122dddb01f836460b3eff99e61ea6309d6b395c94fb5a43dff", - "Expected": "00000000000000000000000000000000054ce66b9b0b3cff6637d6cfdd788719d4e33516b98402d8fba54725309307711fb576299ba99104d4e7df0deac9ea2500000000000000000000000000000000055e06ff52cda9116a98ad3709f788d39db53844b7db58a57af52848ce1c59ec2a1f083efe79c5994b9291a2d1020fb900000000000000000000000000000000040c9ad63698ec78d06b41bdd6f5eed089b67f106348f9300f822a2d61ea1e5d2ddda0efd1025825c99cb0e243573f7700000000000000000000000000000000195dd00c48186f8d1337ca857aea02c4d199d638133e9cbd2dfc5f633502f656343746ec2a416465c3c0d4e9d53fd097", - "Name": "matter_g2_mul_82", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000948d0f0c20715f8658e1f2b4f9d32d851e584287225a2f47735a1f4c241b07f8d7c5dd8c13bcdf84e97d49817d4d88a0000000000000000000000000000000013c064548cb756b48600dd535af8eb5b9138f984bac0391df2e90a204fcb6c36017df910031864d802a2ff719856b336000000000000000000000000000000000000b7eeb7c9a01be88e573f196c2a531635baecbc8cff9af385455af3757301436686596ec7fe3618af26953c49f7450000000000000000000000000000000001332f4dbd5461ab9e2c8b3c19c6ff407a071018c92d2c17c1d1d481c24565276c0f55eee8692016c1fd76d70f44627cbd012914a96253926fdaabec06944ffcdb4637a05e3e78a9bcf1b21b68b9dd9b", - "Expected": "000000000000000000000000000000001141b59af8fe6cafdf2e247fcb0ee4642a9b4022b6d71163ec9b6ac2f7d10ee3c5c0173ac686b03cd6a7086b039ec786000000000000000000000000000000000f05ba6973c5d865ac5c037583b65eb4eac826b5a04a7ebed1e10bec6ec7dca93b1c2eba70ee0189fd552d5023f2a87c0000000000000000000000000000000002e54475940985ad2115223c5ea3a4c95890f3e9992e3e1a6df2170ab77143bcc5d29b9dcd1ed3bf16e545e9be21a8640000000000000000000000000000000019acc4705955761518cea482b83e3726dea8d1f66a5f19b06cd7ff95828e15d1b139077e0d274b0e6fb86c027844d97f", - "Name": "matter_g2_mul_83", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000d3ee70610b5029a28e586f0f3e65bb19a263db3438710fcb8073e1b25f83db50eb5bbb9d75cb20952a225023f747baa000000000000000000000000000000000682f7d5cf9d182b20ee88683f3915e8c9b03074a373e573aa57232de4e997bf155acf680e365aa0988989dfad102b2e00000000000000000000000000000000143962963e230a9154dc328f9583f5be6923a3b10ee7b1d0cd5f5cbff13913d8ff78ca315be7387900a50b94449884c0000000000000000000000000000000000f4f934b42452d41cc20d7b1ec547bcbcbcc10f215364ccf2b864db23a09d06e94c7a87165dcb691f4975323486757ada300c7e1041d94df0e0201e1135fa6eafc98bd33b2dfbe4c59b546a52538c07d", - "Expected": "0000000000000000000000000000000016fb5839fde95111742255b33f040c41dbd0f142d1daa8abc7c63008ba9f63f07381d9d6128240ae9b6cac5befad84e5000000000000000000000000000000000389a11727c356b8f3bdb6a73bc2f6d2d73d33d287365283359521dcac64f17810bd58c0ec5bef4db253bf630bdd9599000000000000000000000000000000000629a8af1bd0c1b1b6d7e447bb779663d7bae8e895e09418bc350e644d7022fa877496f30e2018f5dd1c9683b2715adf000000000000000000000000000000001950185d2574fe0c8277e3f93f59dc5628ec3487911ba9c3194a2f716116ff0bb9a39dde802dcfaa61633ad7657a578f", - "Name": "matter_g2_mul_84", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000005f0fd4080e26971ab16d33aeae04220ae23781da3179e38190082f1d167514bd73bc8ef976a2f333570e9f56a6c05e6000000000000000000000000000000000e159905d29b52ba61575c3a263093017783e1028b3701ccf060c165ba33a765b5265a9b1681c1759bfe2c9c401275e9000000000000000000000000000000000c5ac0bc29a49a7c37d772954da850e6b5e301e230552be9a94017d770ebe2cf4dcfaf104633623e024aef6db57892900000000000000000000000000000000002228e7f42a9409acab49cca82cacf306f6c6c29fd9f7e2ed12fef2d16383cdb7bb2b39ad598b301072c615232db1fa833e9cdb10fc117afb17803b61a2bca7de1d190a325639eb23743f51f28294b33", - "Expected": "000000000000000000000000000000000024c03edb9b54034eacca4b321d51397348c57f406b074b16a9d6215e03f842380f5358f5c095fcf5bf3cabcbabdc260000000000000000000000000000000014e62dc442135d729f65090475fb408ebae132cdf2c2932582af887ed54696f3cd15b163f11285b99e8d8f809aa2e65d000000000000000000000000000000000438a2c99df216c67d92b99d9ee8cbd0e9751e538074d146767bde9675ae3a05bdae051efcdc6bbddeb1b7a8288370ed0000000000000000000000000000000007c462a8f5720e442e1917bf75fc3c3dafab6c39c80d0b93d81d1db4080f6e199be092b4b025e7b02efce4f30d00299a", - "Name": "matter_g2_mul_85", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000180569ce03e4a0155285e733adb18fbca71225507a7adf01cb8e8648891525305e92087f58378f4fd8455d5632ad660e0000000000000000000000000000000011ab84e42f10154e306a568d7cf7bc381000f0add0500cb508f695a3b283ea69d140aa0ad48fce2d2d6fcafe60761078000000000000000000000000000000001136c3016474d6f475609606e8d0269fcdab9fd3188a512681cbc41eedeadfa3b3d9355e5b4503e8b5c3665e49fdf3ab0000000000000000000000000000000003f56cba1b9cb4302099b16b09c2602dfab80d1151685ef78e5054cd454b319adf8b5998053a5b9fddcffa020595e3bfc48b98edd9c229037751d02e58f3d4234d9a3b0ad9ae4947ae14beebb274746f", - "Expected": "000000000000000000000000000000000e8137c15436264b5960c27d0c22be7fc5d56a12f43b3832ad0d7f5abddbaaccefd140e2f7c476b99e6fd9b3a52743600000000000000000000000000000000019ee3caa56f0329a2e2acb8907b3edb21f4eee73e312352796b51282e097f9b10af61805d5c222332888737c7f8e227d0000000000000000000000000000000012cb9c610391940fed7882a5cba08eba4226c36eca8a2ed22fb5e752e0a1a5ec556673e47013258b499268f1de77bdf100000000000000000000000000000000031b769f606fa25b81a982db86a1cd442ed738019e7e64728ecf485cddcc17d9dc271146196178740b9f05f56627b061", - "Name": "matter_g2_mul_86", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000004d79dab9eef873f3415d66172bab7166ce0c71f322529bdeffa915c1b0d3fcd645c91dd3450ba61593ffecb95edb91e000000000000000000000000000000000d611a207d3222bba199fa083d0459675cb5fa00839fb4c9034ad868fc1e79d653c18651771431d6fb6b6b5ce8cf6f7a000000000000000000000000000000000ce802ecb106a4f0ca4efdcc058dd0e29deb6a5d30a2c15c8eda896bcdd3ac19053c10105328d239b26c5ddbdb3a95fc0000000000000000000000000000000001073e142621ecbeff6f81453660362545751f992ffeec3a83477fed3e6215a709ffe0d17b65d3369f8f3913bf000e844228758d2cf8105f2ef11d83018157a3119a44874dc34d5f0bddb533f50df52c", - "Expected": "00000000000000000000000000000000080807a0570b628549629d2eeee39de773badaccefb76e01efaecb0ef0356f535d32c3947f0613bc7d847ef8c8778f02000000000000000000000000000000000e8c091ea30465d204ace72015cbef29645206390fd92ba7c4aa0fecae4ecee53c0b06e1fece99511efd8c7e9cff1a8c000000000000000000000000000000000c881c678c94d80164bb3295acf4341fe6c726ca64a1a015c890450e719b85720f41f80369f99ad3e7e3169ede0113e00000000000000000000000000000000008a2fe01a7100afda40091eb0b2b14cd00b7a4d8bb5cf9d9a3847970a94f2035fec7f292c04c38d7e49890e612830aeb", - "Name": "matter_g2_mul_87", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000bd84f04b3858b1138b1b429c7216d5d1b1e99c1e0fec26440d59b1ad79788c2d5583122c2ad769fcaa6d10d816a1f1e000000000000000000000000000000000387977ed1ce5da51dca230531bba53d17d3de5d593ec576cabfe6463d5164d7153025dbd4cb3525c4145c4f6b85fc76000000000000000000000000000000000a19c943a90fec6921367a2edc5bc38a5c59839cdb650766a2d2d068242463dd4460bd1d0e7a7fb0e3d2104704b8b3730000000000000000000000000000000011d99d44b200feebe00bd42809e3f67a23cce88a07165416cbfaf4db14420f99e54d62db4280d2c99ca0bc3dc41eddbea417c96f0cf4355a78513c77cdc676a7b09125802c8045756da867e0025a36f1", - "Expected": "000000000000000000000000000000000d17f6d9460566d0543df2666d6ade685565e668521a87fabc58148343085415fee92c32907311c9d04713c34bf7690d00000000000000000000000000000000185da28f07b86885031ff5cda913a85b0e4d07673f456ecf2a9f0fd1b21d99e22442f9b705039252d57380b6a42912050000000000000000000000000000000014a4bde5973ef43691b61b3c0f6c2fdb4bcd6ea88e53e2787a7d93ad6e05ee2e69f2799712520f72b3c577ee278008ec000000000000000000000000000000000d92a565b3d8d0fded054a75198b31c521e3223650cdf762fbf7b851f7ac0fc66b8c86c20b905117585704c23b27e7db", - "Name": "matter_g2_mul_88", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000006a186aa584a466a860849c78e4922889c95a4ac6f39c99029fbb422c43d699a8baa51aa4ef51ff99557babeb3e9506800000000000000000000000000000000065fb15b5a0923bdb52dbefc7e9f1a898e32f17d610bac829235446fc5e1913fffc8176e0fbd33091505761f1d06d8920000000000000000000000000000000008bd358698fd073f660ed608462cfcef1da9a59b10905f1d98c4fe66958e56802814906430c10fc25a4d351d91f91cb0000000000000000000000000000000000a53638b1b6c6eeff468e099446300ca7c7bd899c6494682d14fdabfa9cead0bb37a0325d99e7d0ba6341cfa1d257ba846561328b7689b0a89014823537cf9eeaca6ea5c56a3e58d2abfc2ee455dfccb", - "Expected": "0000000000000000000000000000000008b1ebd753364a5a0a6296ab48b348f91668525c0d5f7edc4f2d29844592f34a209f9e77f94ebb38ba76bdb3f96063ec000000000000000000000000000000001062e0ff0a67372207052e2520d8b2823764a5075c94011afd6c60288e187ec77e08db01c95dfa195f2409b58c9dc4e5000000000000000000000000000000000cc2b87b613d97a716586f371c457fa869c2b8d1fa1cf4b9e8c34bae23e0544752b997df4711d0712ec11d3a9d96ac2600000000000000000000000000000000140eae891c87c2026f0b1293df2bd8ae2dcb0ab3f8de74676f37c905334ac1f53fe4b75511691dcf108fca51abcd524c", - "Name": "matter_g2_mul_89", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000001070b98c6348a67e996626ec2752f45e4c007e9c9668459a777c03fab633c10236a1c5be99f3fd950542d5648ef9e88400000000000000000000000000000000073a564401cb1a3a53334c0a55da261814d27b86ebf40b02a76b20973ba2db92e42c138ca7790261c2d70401c984bf470000000000000000000000000000000004212d8a9e4b01f5c6814a88561c2c6143eea61327b031a2e0e4bd056c12dd7098fdfe4d1511bb441ad42b55b584a7bc0000000000000000000000000000000005c5d23824b0fe05eb962194550681c57c1566b315efa8ebc90b3593d7d86ad18328baab8118c9f47eccc0757588591ccf6c3fcd4b9e6b72853934b306a078b1f2fb17879db4a0a93d484abbc2b746cf", - "Expected": "000000000000000000000000000000000276a138edecfc9378be4e241d64cbb48bfa6fd4fb1788f8bda870d5ec8b2132fc9ec888ef84c43a50b7de0527def36800000000000000000000000000000000153e90d52c747859f88223555bc8bc4e8b6fc846fe7028de728a4dfa085c6e350f9f1d12b9dca4ca8e07377648544400000000000000000000000000000000000cef00e7217da6df0a6d85f40be69f154300c423e86e54e513b2491e65002e308445238082da69aa9e5e83b5f4fc17dd0000000000000000000000000000000008da1da2a0d1da9d2158b9408dd9b0eaf414d237b8219fa7661e40c1a88eac2f9735d0dd6ad67b85aab85952369e8287", - "Name": "matter_g2_mul_90", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000b1b3053774ad5515a20bd4c556d2b3ba95fe74fd0c955069c7f933dfd718ede90ac295f5a675f1c29dcd9701978353700000000000000000000000000000000145746ce88686021a0635bf6f0aa2f77c48bdb364cf4ffa804a57f95bd69d24eead05fbee24021c1ef57e1c7c7b894b00000000000000000000000000000000010ec4795a0762b86f3b83de1198698af67fd1b1be3ddef48f35cf82bc96d886fbb4c75064f51a9cfc5f61630c95d0ad1000000000000000000000000000000001465e31f58892466b8ae4b76a239d9f8d1ecb1834886344013cd1df0be13591798868d224d38213a6d75b02a1fde0ff2f6787b565e8d71be6fdb0c97c4659389c800a2047f668b366214adc716f402d5", - "Expected": "000000000000000000000000000000001484993096c210c7bebbc4c0bda24b44a70e982b2528215c0e8578ea55f1181472758caf935aa0a3d6820cdad753e2f90000000000000000000000000000000011802324a6e03c3174bbe7261ecf3812c1a97e1be27269214f232274a3bf82775d47c5fdd70fe1c57155068b296d394200000000000000000000000000000000050f43c874c1cfb5fda81059cb7b4808492632fa20369dcfb611e503ded81a49dacff253e31d7e27ee84bab79e3c5d53000000000000000000000000000000000ef945b6f210fb09bf0ad5bbd4b5a6630f43304ddcb396807c967eb5146741f7432bfdcbd7e5f3d29917781efb62e6ff", - "Name": "matter_g2_mul_91", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "000000000000000000000000000000000f39e731e6ddb7496448c912ae314e833d28208252c7f8e27bcf7eeaf1da6e2310538b4ef0d55401c6552e91fd70691600000000000000000000000000000000069d3612f924961f827497028737000513548ad8e104acee28f014e730d4752a583cb9a893e6169b71966a1c4a4ad2dc00000000000000000000000000000000090899907edcbd336bd4fdad0dd67c578ced4481a25b864b32aef920842689a2c23265277a6e1d4a1dc1b5047a9f79a000000000000000000000000000000000055ba64e2502baf68e46c759fca30247a080464eda2b32e7cfe539e545d6aac6dafb731c2c45749e50513979cecbeb5440ed91f6ceb2ccf87e4106a16227a3cd7b2821b4f3a6e629001f78ba1aa7346e", - "Expected": "00000000000000000000000000000000028233bf12e8dbd8510f119be30ea1fc13b755c6ee3ca2a3637a3bf8f73776c9d1fe231b713396ffc579ef9320a05b150000000000000000000000000000000018e7c00b8047d64ca0c5df54486439c5fb3d1414c2f71cf8a3ed591b7c45bf18b37473daeeadcb625eda638885ddb9870000000000000000000000000000000018b89c9b6bf9ece36f1eac08fc35ffc9f7f964a0a9b19d495ae1361fb4bc98aef8770efb47d9961aff694b878d659818000000000000000000000000000000000eb2fda2c29c6761e35ca4c9772bb232ea0d297582af4f50ef76c0b74fefd414b535e356c069f54ef5224225e95be6e7", - "Name": "matter_g2_mul_92", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000042f1c8b9fe81cdcabea047d0998a1354ce09d62a14f1d0e9d188e2f35f2e1845c2b090c5e157595b33108c67e6c184c0000000000000000000000000000000018e69d3564d4ccc0306e1e6b227b0f961aa9afcad59d4ee1737f980dc876609c59a4c6a3506f987467beba0764b857000000000000000000000000000000000012ce5883156588cfe0f4838f819f985b09f1eab40a5ea8e30fc5d70d029a01a4537641248f4c21dd203909e0170737c80000000000000000000000000000000002888eb9778a4045feb5899dda258657b9f41345731ba630fbbf186b3be4b58ffc7f48abb65b693b573a73f85440a7a7ae8ddfcdb4748981acb9b2037c017174a140f2457fb0148fe807fd194a9f7be5", - "Expected": "000000000000000000000000000000001239935827fb2a269ab064a3ae2bff2555f89bb3a71a47ae815ef755fc1363a89d20326855cfdd0e13f6c85f727bbe120000000000000000000000000000000012fbba047478b5f5b07a582200271a0c331d6f76864f9b6c6ef8ae6b0965eda481eddaf72c7a887b21719164c633d39600000000000000000000000000000000017eb4353b413437244983554a639a9253d105395ff9652504df7700d879cd9a32d5f0824b1eaa532bcf2fea34f8f08800000000000000000000000000000000054ea45475c01ea0557fd143b21c7bdcab6d287bf6bf4f88b6fb06e02ac6fc5ba96f323bb1fda3a1c4d8f42d01d267b2", - "Name": "matter_g2_mul_93", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000051982b46a819c74105cb36da871fb2415328a1531d155856f6551bd043eca62ddb61f24af429edda830fda31e22cd340000000000000000000000000000000006449e5bcdb5619aac542f6633ee3e06a4fd56a3e1ce4034efc608131ff6ead70ca63e70f494f519d5c577ae7119c8c200000000000000000000000000000000153f4f5dddd5801fbf7f88a735b9170d24d5b63861d50cde9644579dcff277cdb0d5fbfc3b3b819a1172de05afb9135b0000000000000000000000000000000010fdea84983fe6c08cdc4b4ccd462bae2ba791ab5209363b10b3ef342c9a5e92184e9d8be1419e3d88402bc05bad5fa21268803aeb58a2d57fc797358fb456d5cf96afecb1ee0d2b90782aa0d652b8c0", - "Expected": "0000000000000000000000000000000015a145e379b7ecf4566a039b753f91e8ad75d9e9c9a20725ce34a900eb9a1bdf66cabee2100208d7792a963d1fb8c02f0000000000000000000000000000000007f0ca14fc4e34bbdf5008d632dd112c7368e037ce019b7c4ec412000ac02302c85ae64f9ab495361fa5b620e46420aa0000000000000000000000000000000017c00a08bba18426dda40e773d79733030b5b3b199a62436ed06b773fd1f10688e8af00e8a223cdf242bd1ebbedbf634000000000000000000000000000000000a17365cd9f7655793682b72e342227048da0cff88f6ace33ddab548ba126017e4b7f7439373a893e3b5803e662814b8", - "Name": "matter_g2_mul_94", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000009b011f793d9a939d916d058ffe91b58138820a646cc450389b3074ae3715d06ddec1075afecda71c65c7ca085210c740000000000000000000000000000000003d4d20f4b93c1e90a0a06bd534d8b4fd64e4c4aba77ae42cf4c5b2bd95f8b02ec4069ea246ff46404e6c9eac632fbac00000000000000000000000000000000051e88c3adfd4d6a02d3f03812362a6cfba3a6c69b9aeef75b51106cc7f1750293d61e31f0ea29b5d7aa56debb6d2aff00000000000000000000000000000000086d9c4ea6769cdf49ffbbf7351023b4aea640e8c90f9291222fd0b5984bca4d481bf7e10df921406a34804e6a09f99df9a8a4e5c65973b785c1e2637937de239bb0fde34b786dceea66f6bb12eb4169", - "Expected": "000000000000000000000000000000000081b4dc78b74250a82da9d803876add659411cfb467860b2ac6f0f68929d6377deb71d6acc9ea8fc8c1286b8f92056e0000000000000000000000000000000002c5fde71346a255ee9dc896f654eb2e0c66f4cb4c51541d2bbccf2463ecf0085a22b9d2bdc5bef39d80c4477824f116000000000000000000000000000000000ebda0cd8bf6ac7e86a1bdbe44ed1e15f8ffa1fff92afd67fb564306882f35037b61cf0d93f278f15149c04a2e83041f000000000000000000000000000000000fc38aa811f5ec015f10a99bf175f1479d4983c9d2180a5e3da88b4e9b62ef50560ff0a6c2fb7bda4c46c54551f8390e", - "Name": "matter_g2_mul_95", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000010d48bf523f3909cf90aa58a9517ef5421f1212accd5e8a0f830aeb15a587e215ca9c340bb846b1d0474e43840b2af79000000000000000000000000000000000cc1a3976caf97b9d59f448f6d9f413eef8904f360c0cf912fe942b38d7fcc637a17038973a133608ae769d3e389b18a00000000000000000000000000000000069a6122c6f0ec68834b7617c755a7eb33a80a25acf95859da5ff03316447182f122d20d993b04e79b6fe859b7adf5a8000000000000000000000000000000000058c6f8c297524319bae6722e0a957d1ba0f75ee3a8aaf06148641c67925d15780e419a38ed7e07410e82769da74f2d070e7e2ae2751a1f71962726a31f77553c2da38f4fecda435b6e5459d5e833b4", - "Expected": "0000000000000000000000000000000007b46fcfb2cd8efe32754306ff2f503d7434168c1c3cbd7c80470cc5a5c8bda10a80bfc0129da349724d2d6431c5ac90000000000000000000000000000000000e1078f4f4ca993d90accbfc036219507bd22d00930ffcfe1227780c00914fcff845698b2541510daf59cc83d8b947e7000000000000000000000000000000000b7c6d9951570e685d3a71b19a38f5485f974f85fe8cd4b4c196d33a18750b278b6d374483d81dc3e15c9b8b9b5dfdd6000000000000000000000000000000001003a239ea4a2f213f0f646bdb62cbe4f98cfaf7298d8b2e0eaa07bf3f939e779caab5ffa0033467c5b297166df657d7", - "Name": "matter_g2_mul_96", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000156ca5e80be8c8c03a5506ce9abd22a9d4958c372678c0caf6f1329898507dfcb1f06a9464cf080bc6881fa5b7df1ebe00000000000000000000000000000000088174d486b4086b931010da298a399e15b60a113e08f571e096d3a4e94b57b3a684711318796eeca9319119b201abb30000000000000000000000000000000000b96ff68505c088cc03a1c2dc363b05bc8544728a12b29569bed137780523123eb17e68f4632383c252d81bca0c5ca9000000000000000000000000000000000486fc6e5224c5fad56234c41856e60bee4a6c1046f673bf7d5c1bbb603b141fc91074da5f9d3d41b796a2ebcebd9e74d16aa883a20307f5436354bab32b4633e83178f33626af3edb14f82724b8e125", - "Expected": "0000000000000000000000000000000000ea29b1e059560fec21c3692d4e632a45c88a807c953fa23dbedb271b049d7fc717333b498ed12573a896f872e795dc000000000000000000000000000000000de0d10c47df92010a6635e3403dd6e91a1bf35bfcae82c1008998e86aa2d18a6cfd3f2f1207fde3bb39b723ec4d3ca60000000000000000000000000000000005e2aef9cd37430b15e5e76b2c7870630d255f630c12e865caefe308a39833e00319406746dbb2af3ed32135e91eed49000000000000000000000000000000000c229fad41b0d27ad7b5db33188fa70b97f22e323e429ef65fcf98f5339e908c31df8859b863356e0fc90538c5c49cf2", - "Name": "matter_g2_mul_97", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "00000000000000000000000000000000121fe97c62e068988ebff21d8129d52aa903afdbb62862c7fd99564d9ad72182ab1f3a1100223ae486cd76f6938e123f000000000000000000000000000000000968ddedb04f52140160061828b5f88dfd09aaf37df625ee6f66b9500d6608df31c7edf86296eccf8f9918b051a5e4df000000000000000000000000000000000b7491cb8f6252e3861d7160feb0afdd736d27886863ec0909a7cc711a9b71aace18b17a00a2999dd57ca1a74f148516000000000000000000000000000000000fdb280093ef45b12b694ca3390a865ee18e4c04b231e2c98cc28706d4cefaf4e654582ee03f34ecf1dfa9674489d553041390a2209b80f7c64d14965cc2f515d5fbdf37953f75c4a0203bf0d9fb674b", - "Expected": "000000000000000000000000000000000444a00cfd258bd46f659b09eef17be9929008d3d1c65e46cdc762eeaa2f0b52abfd636e6094e21983fad8171194c71a00000000000000000000000000000000090833e68614be5bf298e04e44527480cb35128bbdecae15eb95d6931a718f66869ddb68352130b4dd8a921ab3f26d080000000000000000000000000000000000994015b1b55340c3839d48320d178b2ffaa0bbff038f7aa63d4dff41a217582fae9613bc537fdeac8d0670c0cf479a000000000000000000000000000000000fc486e2a1680c10ca28d4c3bb22dbccc9572036512645bf868e7693ae4591569c973f9ea26342a573e23a06c2fb4b70", - "Name": "matter_g2_mul_98", - "Gas": 45000, - "NoBenchmark": false - }, - { - "Input": "0000000000000000000000000000000010d001a09cf5dc3276482185f26ef3f75d28cd6d2667eb08a7fe06c03b99f3b6c4d82390739b6867a314291cc642a8b2000000000000000000000000000000000587846a460b1f37c2e7f491f9a097b4e86e1943d9cd0999313f65627b3907f09b5d5ac1be376a313a959dd136f7e9b3000000000000000000000000000000000af439695556e86b102926d3b40e3e54cc84464e120de3b4e3c5541a6a5bca44151fb0594009663764c1824518b13f020000000000000000000000000000000003bfd9418c1e57269e222152d321b83ae090f216cb422956dd1fcc464f68526cb4a05cdaefc7bbe6e81d4ffe27d64db47cf23dee8d95d94046678f3bdb4b0ea3d4e3a1a2f07f582e2a98ad6eb7562cbf", - "Expected": "000000000000000000000000000000001375bd5ee66c330796bd8381a26cefa3f40f8cc8de42d4d59a7adbcd3852e6d632422e6ad9a06a6e497b23b17b1df87500000000000000000000000000000000165d8e7be17ecae9bf51a773da705aea42536d0fa3a2206267da50451f5104ee241811dd0e6710a80c38df77b126c009000000000000000000000000000000001559572407aff34969f83c394d2b095a7ae9f53a8e6c923910f256bb87b6ec076fa6acb85465102fd24d34031f88f7510000000000000000000000000000000015ff9ba89b55ef75f63732dec1e64106d7a912a6657fcc970dd011a03b5364117cca46d6cbafbc0c5049db10fa83fe6d", - "Name": "matter_g2_mul_99", - "Gas": 45000, + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784519a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g2mul_random*p2_unnormalized_scalar", + "Expected": "00000000000000000000000000000000036074dcbbd0e987531bfe0e45ddfbe09fd015665990ee0c352e8e403fe6af971d8f42141970d9ab14b4dd04874409e600000000000000000000000000000000019705637f24ba2f398f32c3a3e20d6a1cd0fd63e6f8f071cf603a8334f255744927e7bfdfdb18519e019c49ff6e914500000000000000000000000000000000008e74fcff4c4278c9accfb60809ed69bbcbe3d6213ef2304e078d15ec7d6decb4f462b24b8e7cc38cc11b6f2c9e0486000000000000000000000000000000001331d40100f38c1070afd832445881b47cf4d63894666d9907c85ac66604aab5ad329980938cc3c167ccc5b6bc1b8f30", + "Gas": 22500, "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 24f1c3383d..1fa1084da3 100644 --- a/core/vm/testdata/precompiles/blsG2MultiExp.json +++ b/core/vm/testdata/precompiles/blsG2MultiExp.json @@ -3,1043 +3,1071 @@ "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000011", "Expected": "000000000000000000000000000000000ef786ebdcda12e142a32f091307f2fedf52f6c36beb278b0007a03ad81bf9fee3710a04928e43e541d02c9be44722e8000000000000000000000000000000000d05ceb0be53d2624a796a7a033aec59d9463c18d672c451ec4f2e679daef882cab7d8dd88789065156a1340ca9d426500000000000000000000000000000000118ed350274bc45e63eaaa4b8ddf119b3bf38418b5b9748597edfc456d9bc3e864ec7283426e840fd29fa84e7d89c934000000000000000000000000000000001594b866a28946b6d444bf0481558812769ea3222f5dfc961ca33e78e0ea62ee8ba63fd1ece9cc3e315abfa96d536944", "Name": "bls_g2multiexp_single", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000019d5f05b4f134bb37d89a03e87c8b729e6bdc062f3ae0ddc5265b270e40a6a5691f51ff60b764ea760651caf395101840000000000000000000000000000000015532df6a12b7c160a0831ef8321b18feb6ce7997c0718b205873608085be3afeec5b5d5251a0f85f7f5b7271271e0660000000000000000000000000000000004623ac0df1e019d337dc9488c17ef9e214dc33c63f96a90fea288e836dbd85079cb3cec42ae693e9c16af3c3204d86e0000000000000000000000000000000011ba77f71923c1b6a711a48fa4085c4885290079448a4b597030cc84aa14647136513cec6d11c4453ca74e906bbca1e1000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000176a7158b310c9ff1bfc21b81903de99c90440792ebe6d9637652ee34acf53b43c2f31738bbc96d71dcadbbf0e3190af000000000000000000000000000000000a592641967934a97e012f7d6412c4f6ff0f177a1b466b9b49c9deb7498decc80d0c809448aa9fa6fbbb6f537515703000000000000000000000000000000000031d84356ef619e688a10247f122e1aa0d3def3e35f94043f64c634198421487ca96af5f0160384bba92bd5494506c4d000000000000000000000000000000000db8fefe735779489c957785fa8e45d24e086ef0c2aba2e3adba888f0aeee51385a82898524c443f017ee40be635048c0000000000000000000000000000000000000000000000000000000000000034", "Expected": "00000000000000000000000000000000158d8ef3d5cdc8a1b5ce170f6eeadec450ca05952ea7457a638b8ff8b687c047799eb3dd89c2e3c6ca6c29290b64f5ab000000000000000000000000000000000807d135b6b007a101e97f5875e233b41f12bd2ffd77fe1195418a73a4c061248118ea1049aeea44750cd5ec83bcc1ae000000000000000000000000000000000f04136354f45a85a53fb68527bc8fbc7e8c1a0056878012b548a97bfdabcbd3fb8eb3ff187fbe65e1ce233afd2825050000000000000000000000000000000007b15428114e2ea094ba1e64df4c244f80aa2f75bbbf21a407bc84e80bf2a5ad787d02ae8a90cc1c137f0d898edb1684", "Name": "bls_g2multiexp_multiple", - "Gas": 103140, + "Gas": 62302, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3000000000000000000000000000000000000000000000000000000000000205900000000000000000000000000000000122915c824a0857e2ee414a3dccb23ae691ae54329781315a0c75df1c04d6d7a50a030fc866f09d516020ef82324afae0000000000000000000000000000000009380275bbc8e5dcea7dc4dd7e0550ff2ac480905396eda55062650f8d251c96eb480673937cc6d9d6a44aaa56ca66dc000000000000000000000000000000000b21da7955969e61010c7a1abc1a6f0136961d1e3b20b1a7326ac738fef5c721479dfd948b52fdf2455e44813ecfd8920000000000000000000000000000000008f239ba329b3967fe48d718a36cfe5f62a7e42e0bf1c1ed714150a166bfbd6bcf6b3b58b975b9edea56d53f23a0e84900000000000000000000000000000000000000000000000000000000000b7fa3000000000000000000000000000000000e7a30979a8853a077454eb63b8dcee75f106221b262886bb8e01b0abb043368da82f60899cc1412e33e4120195fc55700000000000000000000000000000000070227d3f13684fdb7ce31b8065ba3acb35f7bde6fe2ddfefa359f8b35d08a9ab9537b43e24f4ffb720b5a0bda2a82f2000000000000000000000000000000000701377cb7da22789d032737eabcea2b2eee6bb4634c4365864511a43c2caad50422993ccd3e99636eb8a5f189454b18000000000000000000000000000000000782c14e2c4ee61cbe7be6e462a66b2e3509f42d53ff333efc9bfe9a00307cd2f68b007606446d98a75fb808a405d8b90000000000000000000000000000000000000000000000000000000004165ef1000000000000000000000000000000000411a5de6730ffece671a9f21d65028cc0f1102378de124562cb1ff49db6f004fcd14d683024b0548eff3d1468df26880000000000000000000000000000000000fb837804dba8213329db46608b6c121d973363c1234a86dd183baff112709cf97096c5e9a1a770ee9d7dc641a894d60000000000000000000000000000000019b5e8f5d4a72f2b75811ac084a7f814317360bac52f6aab15eed416b4ef9938e0bdc4865cc2c4d0fd947e7c6925fd1400000000000000000000000000000000093567b4228be17ee62d11a254edd041ee4b953bffb8b8c7f925bd6662b4298bac2822b446f5b5de3b893e1be5aa49860000000000000000000000000000000000000000000000000000000173f3bfab0000000000000000000000000000000019e384121b7d70927c49e6d044fd8517c36bc6ed2813a8956dd64f049869e8a77f7e46930240e6984abe26fa6a89658f0000000000000000000000000000000003f4b4e761936d90fd5f55f99087138a07a69755ad4a46e4dd1c2cfe6d11371e1cc033111a0595e3bba98d0f538db4510000000000000000000000000000000017a31a4fccfb5f768a2157517c77a4f8aaf0dee8f260d96e02e1175a8754d09600923beae02a019afc327b65a2fdbbfc00000000000000000000000000000000088bb5832f4a4a452edda646ebaa2853a54205d56329960b44b2450070734724a74daaa401879bad142132316e9b34010000000000000000000000000000000000000000000000000000008437a521c900000000000000000000000000000000049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c000000000000000000000000000000000d0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c80000000000000000000000000000000008b7ae4dbf802c17a6648842922c9467e460a71c88d393ee7af356da123a2f3619e80c3bdcc8e2b1da52f8cd9913ccdd0000000000000000000000000000000005ecf93654b7a1885695aaeeb7caf41b0239dc45e1022be55d37111af2aecef87799638bec572de86a7437898efa702000000000000000000000000000000000000000000000000000002effc7b302730000000000000000000000000000000002142a58bae275564a6d63cb6bd6266ca66bef07a6ab8ca37b9d0ba2d4effbccfd89c169649f7d0e8a3eb006846579ad0000000000000000000000000000000012be651a5fa620340d418834526d37a8c932652345400b4cd9d43c8f41c080f41a6d9558118ebeab9d4268bb73e850e10000000000000000000000000000000015f4b235c209d89ce833f8f296e4cfb748e8abce6990ce1a5a914b9416c08e0d3a26db89625915c821a5f152b7fa592e0000000000000000000000000000000006fcacb3ee6650a1044852d61c9c20bedc8ee90aad97de8e24670a9ef57483e678db11dd95428915088d76e30cb01a370000000000000000000000000000000000000000000000000010b4ebfca1dee100000000000000000000000000000000018405e4b67f957b6465ead9f5afc47832d45643dc3aa03af7314c6cf980fa23dd3bb8db3358693ad06011f6a6b1a5ff000000000000000000000000000000000c48e0d4f9404ae0a7f10774c55a9e838bb09d3bae85b5eaa6b16b0f4dc2354368117f3799c37f3f7126d8b54d3f83930000000000000000000000000000000007e61f4ec5bc9e2cc8ca471ce4ed40e729b1790cd2c0d9c1cb50e615ec7f346636e77e1cf632c881c07c5385898607620000000000000000000000000000000011dfaf9281901dd356fc5dfece21898a93d9ad9e4e246dd6e18d3ee46d58ab7e77401a3e8d04057e5638ed74fb95688100000000000000000000000000000000000000000000000005f04fe2cd8a39fb000000000000000000000000000000001796abe0d9e4a703962be528e6a5cb65c60725886f925db0e2a89107ec248bb39fa332bc63bd91d28ae66e0dfce8f754000000000000000000000000000000000fb665f5a7559cb0fa1300048a0e6f1ab5547226e86f8e752dd13c28eda4168492e3d3bf2f8a6b230dd57f79b1afa9910000000000000000000000000000000003422dbbe4a06a4c6c9fdf35e54f74b4ab1528abb7249e99898e6fd7affebc7aef95bf82d328dc01d63c25f6a735c35d0000000000000000000000000000000010aa5504b469427eb3584a286191149f5c3c5a745f338278dd95337cd2336d3c4e7532d98eb189fa543824953e7c1c170000000000000000000000000000000000000000000000021c6c659f10229c390000000000000000000000000000000009303f04d568e289a35102b6df883d5ed620355c0eb5d02236718cdaf99fba6e19ef5cee2996268eb9a53ae1ee09bce3000000000000000000000000000000000190be857d602284393305bfe0a29e29a6982ed3f04ccaabafb7e59cdc7eda85c22bc3e8690355c7a0fb7590ae40f1b00000000000000000000000000000000016efd497a0c5c6b59a1fdf2b590eb67a7da8cbe72f49084e7050783ff12a783cad1859e1a0b0ec8ff784c703617670330000000000000000000000000000000017a957ea4d53f4fc8412cb015ae91b38445cdb3e7078d875c465c941e0d9a852c78d90b31b6b6010efe8bd5117e831630000000000000000000000000000000000000000000000c01a881f8abc4d8843000000000000000000000000000000000173ed58056bec9874464d3f23c3e7d3d429d6c8a167fc7f39368830eca839d0eb8260d64ca823f6c785c71f85893d8400000000000000000000000000000000123372d7d4c91a249df8f3e4f8e669087b252ab5d8cf2529a87e4ed3622e4158cf17dc44b473d5debd273261383e8a0f0000000000000000000000000000000000c500eb55ab86381a1725f339f686c7e38ce9113493736f57e999badc661b5b8494d220ded0711e841228a389abdb820000000000000000000000000000000010a4025d823c4262367c53f50e67cffa046e4a1e7c69ff30373772e49ecb310de3b313d83cc41f40a00205722f233e270000000000000000000000000000000000000000000044496e633650ef8f6fd100000000000000000000000000000000152110e866f1a6e8c5348f6e005dbd93de671b7d0fbfa04d6614bcdd27a3cb2a70f0deacb3608ba95226268481a0be7c000000000000000000000000000000000bf78a97086750eb166986ed8e428ca1d23ae3bbf8b2ee67451d7dd84445311e8bc8ab558b0bc008199f577195fc39b7000000000000000000000000000000000845be51ad0d708657bfb0da8eec64cd7779c50d90b59a3ac6a2045cad0561d654af9a84dd105cea5409d2adf286b561000000000000000000000000000000000a298f69fd652551e12219252baacab101768fc6651309450e49c7d3bb52b7547f218d12de64961aa7f059025b8e0cb500000000000000000000000000000000000000000018461a3d444ec527fcbf4b000000000000000000000000000000000027513925b419f6c581788578379995290ab9478e08ecd1999d5e1a05c58144d2f9f06fb8c7fd1586f3ef6a973a3ed7000000000000000000000000000000001292b2ce751f6f859ec7882e14083eac9841b035f9d5ed938a81579dbce07dec2c0202b7f6b25226831cd9c578e893d00000000000000000000000000000000017f36da49414d7706209d52840250eea6f33970fd7eac448ee122f24c62f6a6e09757aa29761160be0f65ba3ce7a153a00000000000000000000000000000000086d471f958f3ff679805751b183fb6310e871ba72bbdefd59c58e95ea62de0820d5affe601757e318abaa5a0c2715bd000000000000000000000000000000000000000008a0eb53c748001536d7ffa900000000000000000000000000000000090721a089bbbb130c21a529be0ede9271a91a2dde9cb2a8e091a19fd2c0a40c390ac2bda8304085c2d6e38e520eae44000000000000000000000000000000000cc64109c67b342b6dbcf86cb60fca7ad378ed6398d89076ed108685c57a07d26e40ed3d5c4b3560b21e519db5875d49000000000000000000000000000000000b0ddd488f5a6f61f087cdbf011b50209a4460c8aa8c5f48c0b30d9cf6cf24259f4e7badc42e1b7a33352949ae566fc100000000000000000000000000000000038430e8db04d205d81aa1632d23919c06f89260c7ac5850bd8b780f8388e53db3a3ddfe98cc55d1c686e582f85b0c8900000000000000000000000000000000000000031133a6c7d698078a7ec7e113000000000000000000000000000000001800ecc167bb714100f31e7610cd3fd010ca299b394c01b1a89afd11b051e92989f6336db5e6d3212f6b04673526d83900000000000000000000000000000000070401d9bba01c0445e0a682406b099f21d16d9c348cc97156769084055ca328a145c134b8c8b58f019d62882b2965de000000000000000000000000000000000287f071bda99b0318e386b27a492a6823a9664084b12acddeda34cb53f827a362ba97c0e652c37bd9d6023041d8c8d8000000000000000000000000000000000fa708ca7dd917541cd02281e525d3367b5ebf5e9353103e1f83f3b894d03d8be7e4d819c123492788855d1fdb63f2e000000000000000000000000000000000000001171d5c4909480aae3b110d01c1000000000000000000000000000000000ef786ebdcda12e142a32f091307f2fedf52f6c36beb278b0007a03ad81bf9fee3710a04928e43e541d02c9be44722e8000000000000000000000000000000000d05ceb0be53d2624a796a7a033aec59d9463c18d672c451ec4f2e679daef882cab7d8dd88789065156a1340ca9d426500000000000000000000000000000000118ed350274bc45e63eaaa4b8ddf119b3bf38418b5b9748597edfc456d9bc3e864ec7283426e840fd29fa84e7d89c934000000000000000000000000000000001594b866a28946b6d444bf0481558812769ea3222f5dfc961ca33e78e0ea62ee8ba63fd1ece9cc3e315abfa96d53694400000000000000000000000000000000000063376fcdf64c9bcbeeff0f9f9f9b0000000000000000000000000000000004b6570b4a6affe97649b0dd7a0ad0df160b37c332a8a7348dd3994cc6b1eb65623b4a9f0a3f320e7278844e261546530000000000000000000000000000000005f8fb4cf5e5313f403f15c59c79b9cebaec78291f2053c49d6427f40f2db2aa659d3a8fed7c7b07b7a5680c7b95ab5800000000000000000000000000000000045cba5ec3fa9acd1b11e1f28a01ebc028f89f96f814513453c553f58785baca8abd4150f334b405fabb925b71f4f4dd0000000000000000000000000000000013daf00b8f53af776c2e8c08d55d164aa15027611188e294230477dc1c926102088f0451222fd2eff9802db8b884ab9c00000000000000000000000000000000002344b4be368d3b617df4aa8dbdbc190000000000000000000000000000000002b29192945df0a74eed138e431962f1d39978202d247335ffbf29d8a02e982c69e96b58d7d92528baf5c422ed633f1f000000000000000000000000000000000d52c7a82fece99279de7a49439c0ff8463a637cc6003320275d69549442c95184fd75ee5e7122e5575af7432e5159290000000000000000000000000000000006ddbaad6cc16c9e62b0da9ab0196dffe92253fcfb2df9aa2076d3f16b3284997d6558cc4432d2aa1705452c4e951e6e00000000000000000000000000000000175f906a99c9d65c4647807879e5eb781532db184d28a326ef9691f8738af067b6a80147bd69327d219fad7c850a7545000000000000000000000000000000000c896c3f9d64341ba7c5f8a06271dce3000000000000000000000000000000000c86c92c9598dde7e6fc5e05d70a34c7a14cff5f400f33cf6cc26e6bf6d9a0bbc421c00f3360721f51974d76be43bd38000000000000000000000000000000001137d93502ef32471f47890a181d7823b3a86dbfcadcc930ae53952f528d617e742a52e4f243c615cc28163dc31bd80600000000000000000000000000000000088f7f8bcbc6dfcc8005b8308cd4780d574d8530e95e7831e52eb2c9a88b846852e111a8389e3d3a67accf78b08326d200000000000000000000000000000000149e43fc675dd3bde8b89cfeb29456f130bbf674cea0266bd1b2e7de23f9a7294096327b452728411ca58acc949777fa0000000000000000000000000000000474d97a9cf29e85d4a35f6102fe7984b100000000000000000000000000000000186a1da343cacf1815b9c8b6c807f536249dbfdb59d77bf4920ad2198a0d83ada21f7c39de6f06a5599f22571cab288d000000000000000000000000000000000ba1ec44f95121bd622932b84bbb4b3d279f69c494ee44db68e3165c86b627ba5e397ee197313fb5b775972798997332000000000000000000000000000000000783e7493e9fb106fa0d085e7c03eb816468d12c65d9b77643ed07c02583d491f4db5db44e565d50d8ccaa9ad8f7f8e80000000000000000000000000000000010a6a5fd90cd5f4fb6545814f5df065b001074bb3f29f649dd2612815df3a19a320f7754dd3d458e48e7fb1b4953978f00000000000000000000000000000195894e95ca3e59929612e77c1075322aeb00000000000000000000000000000000129c4945fe62538d2806fff056adac24f3bba8e17e42d82122affe6ad2123d68784348a79755f194fde3b3d448924032000000000000000000000000000000000528590e82f409ea8ce953f0c59d15080185dc6e3219b69fcaa3a2c8fc9d0b9e0bc1e75ec6c52638e6eaa4584005b5380000000000000000000000000000000018dc3e893f74729d27dd44f45a5a4f433dcd09a3b485e9d1c2bd0eb5e0e4c9024d928ddc426fdecae931e89885ee4db4000000000000000000000000000000000d6ee02e1fc7e52a8e1ef17e753065882c6fcc14da61da7ffe955fe84a9d2af9ba57562c69db3088652931bf124b0d5300000000000000000000000000009027ceef3ee429d71b58b84919d9a8d5418900000000000000000000000000000000131747485cce9a5c32837a964b8c0689ff70cb4702c6520f2220ab95192d73ae9508c5b998ffb0be40520926846ce3f100000000000000000000000000000000101e147f8bd7682b47b3a6cc0c552c26ce90b9ce0daef21f7f634b3360483afa14a11e6745e7de01a35c65b396a1a12700000000000000000000000000000000090ca61ed16c4c1e80acfef736eea2db0d7425d9110cb53e6c4a2aa3f8a59ee6c60bdce8df5825011066d44bef84d29600000000000000000000000000000000028207394adcbf30250ac21a8f1db6283580bc5e39159930552e5edb25e6215c66b6450296edc80dbc3a2acd125dab1600000000000000000000000000333e268f0b5b1adf76b88981fc305f03ce4bb30000000000000000000000000000000016cfabbe60d1e55723a0ff72cf802f2d1cf13ed131e17729adc88522a657f320a336078a9399c8e61a3bbde3d52fd3640000000000000000000000000000000009aa9a3c2a6d49d286aa593c6ff644f1786fa9ae471bdb3fe70b150a9ed7584eaa886ac057c30005c3642f65ad5581cc0000000000000000000000000000000001d417894c0cce924955a795b188b27951f8438a5485404b921a42fa79dea03c10e29d0390df2f34d7be13f360a7fada00000000000000000000000000000000189b0b3a04e6c613899d51231dbf0cba6a8a8f507ebed99d24fba7ebac6c97a8859ffde88e6d95c1a9d6b4f0a8f3c417000000000000000000000000123717b4d909628d6f3398e134a531c65a54e8a10000000000000000000000000000000016cad7807d761f2c0c6ff11e786a9ed296442de8acc50f72a87139b9f1eb7c168e1c2f0b2a1ad7f9579e1e922d0eb309000000000000000000000000000000000d3577c713fcbc0648ca8fbdda0a0bf83c726a6205ee04d2d34cacff92b58725ca3c9766206e22d0791cb232fa8a9bc3000000000000000000000000000000000f5ea1957be1b9ca8956ba5f6b1c37ea72e2529f80d7a1c61df01afcc2df6f99ced81ac0052bd0e1e83f09d76ad8d33b000000000000000000000000000000000aabced4e2b9e4a473e72bf2b1cc0ce7ab13de533107df2205ed9e2bb50fa0217e6a13abcd12fce1bda1ccf84dac237a00000000000000000000000679956d49265608468757580db6b8b1821c2eb13b", "Expected": "000000000000000000000000000000000728c5e6e69b9103d82358cb6ba3a45a677df1c3eb3cdccf694fd71cee94f1e591b8021b0eef638cd9a1d878937b5b2d000000000000000000000000000000000ba9bcf9ccef956f2af8dc4c3fbf1cc8f3f284b04ae8710af6ef4fb36301254c777d4461858fb38fdeeb72c0d8589af5000000000000000000000000000000000224b80a57d30bce4c752664f3b5b5e3443aefa6d4e95dc334821f754b8b8d8fda4e73d03cbd4070d43b18324a686b500000000000000000000000000000000016909a02214c6c0f6682895aa99cf6cf0a22eab6f0b574437ef9c36e9df32ac3b8c5adb9f6b8827df0ccf51b16f824df", "Name": "bls_g2multiexp_larger", - "Gas": 335250, + "Gas": 376875, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746", "Expected": "00000000000000000000000000000000083ad744b34f6393bc983222b004657494232c5d9fbc978d76e2377a28a34c4528da5d91cbc0977dc953397a6d21eca20000000000000000000000000000000015aec6526e151cf5b8403353517dfb9a162087a698b71f32b266d3c5c936a83975d5567c25b3a5994042ec1379c8e526000000000000000000000000000000000e3647185d1a20efad19f975729908840dc33909a583600f7915025f906aef9c022fd34e618170b11178aaa824ae36b300000000000000000000000000000000159576d1d53f6cd12c39d651697e11798321f17cd287118d7ebeabf68281bc03109ee103ee8ef2ef93c71dd1dcbaf1e0", "Name": "matter_g2_multiexp_0", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca807f80a5e502f63375d672379584e11e41d58d2ed58f3e5c3f67d9ea1138493cf00000000000000000000000000000000135aee0e30fbcad798738c10d4aebcdf50c89ce516325f655fe763dce54ffedf94dd74168611e5ae879b5bf5598d62dc000000000000000000000000000000000c728e672cd8b3bf9341bca929c34118b566cd3a80452d7015bee9d5cdc001b1f5c678d4b2cc4f7cac353e7bf326ca1e0000000000000000000000000000000014809aa22e2051e463fba6d49fbb060d0c7f599a0fc5409d34e71f34817e7beb1251810ae6eee1848c60796fb8647dea00000000000000000000000000000000145a4de777d86025d50e12f9a6615ecb9bdd41489992d1b643dd9aa549acbc63b04b0bdfd14b6e45c70f165e9a8c91bebb169138f94093d5c1c6b253cc001ce8baf78858dae053173fa812d2d1c800da00000000000000000000000000000000009a58b7116dbd6f550f8ca98071813130ecaa9ea86d5275eebc36860690fa048c9ebeb46600b2b63e847bff3e38ed0d00000000000000000000000000000000113ffc0932c041e0e34b2540c485eb74f5029b339cb60bc88a8a749310f33f330dea137e5f340044fd689264af66696d0000000000000000000000000000000002642da3c2c7b6688aba0b19ab29ac72e35caafa044863c364ea8833fca850289de52c0963bc33d7bba40cb5f568718a000000000000000000000000000000000552d35ca054da2f148c119454f6760607b351f2441921a2be17da2cc10902d71571c5554f132e60df79679428fa07e3e40608bdaf3e7764358a64a920cbb33ab4d571c7b3092e1ae11d9697f82ed8330000000000000000000000000000000018fbbcba3d4b1e548ceaec4a48db62a2420ff29a67af332ee7ea3f902f84e6c375fd33abc33d945c5bca25603979f9a400000000000000000000000000000000072ff416994364bdc6535f36c82212afa822cd94fade69f11eb38dbdcd37c7e22af55fe05e6a826dad822073656eaac10000000000000000000000000000000017bba179b847278a4878b6faeaab3b1f4bd7540d22817cd9aff95557497f8b9d286657b6162c0f89f7820becc637dd550000000000000000000000000000000018e2bfed71aa9b11fefca2f0db8bd9b8c69540267de50bec4fc90a6e9741891465c9761d19282e1100b3707eeb598b31d411519f2a33b07f65e7d721950e0f0d5161c71a402810e46817627a17c56c0f0000000000000000000000000000000019efd37727dfaedf697fcda7a59847dbda8ca7cdc92f34e68691d682e20ae6545ac104d6660fdb8f64a051e69298eae8000000000000000000000000000000001225ace0fdce456dd888c9672503b68ef77b2d11caf1265a767a6ea14911e3ca03fc153f18dfe9d95e0cc68b7b8a3a8d0000000000000000000000000000000008a6b059c1c4da046cc0b1b5d7f33270aceffa607daf6d0d078c06f940604e1a0b4adf01a4091306e3c7eddcf3d95101000000000000000000000000000000000f79bae5260a2f114ffbb9273f3049d3ebb002500a57ee0a7d157d86957f43f87a2e026fb9892dacaadca5ee04fc8e176bb3f9e512311699f110a5e6ae57e0a7d2caaa8f94e41ca71e4af069a93d08cc0000000000000000000000000000000016d2b73eeceee17d3bff3aacac9df9ac1c4248d9ea7d6a503a757f7bb22fa6970bb6f5cb5ec154785f7252e1508b382e00000000000000000000000000000000081edc68bbd8db7b10be06ee23d090bd54f9ca07ef24dfed7df7bb05f8cc26e6889dbd40ea203fd5cca5cb588199f9e40000000000000000000000000000000010d3478508619ea9493b4330e2fb9150024cd32dc1378f824788a884a4a30fbf39c630f465557bf0c6d69b4cbecf89f9000000000000000000000000000000000f20c9b134db5d8b7756800c031bf5962fc560ba95d4bd9157b16179f1a37ae08696a2be455ad8d018aead6adcc69b712a0c988d97e86dccaeb8bd4e27f9e30fad5d5742202cdde17d800642db633c520000000000000000000000000000000003dce67181d23af9729e9fb0653d7f79c890fba27de42fada93123e112c4a468fa889921192db8047d86e4db77c60266000000000000000000000000000000000869a1e39d42d9bb0cc0568fdad16abbdac3194af893ebd8dd8f8c2c3c855abefa5fc215412168acadc88e658e83f5570000000000000000000000000000000001ef139a75194f3c4b1378c2b66dd304d179460bac0a289405cd8faa3ff66a7b6e54eb7b8742a68150b1e098630135c40000000000000000000000000000000003892b5a645af916be2c6c7fc0bb08fb5f39341d3c68598940554e1be11e1be75af920db0c8710ed13c78edbf683f17d0b299c14892e0519b0accfa17e1a758c8aae54794fb61549f1396395c967e1b1000000000000000000000000000000000264dd4b477f5db65edad28c7153ed919a863c5c5661e0125c5429b323e055fd69c33142dfc6ed9c87082e2be4675e1f00000000000000000000000000000000046ea088a2ec94d3a1f1f97949f1ebc49690c453d316cc46534fa253b34b30323b6071d147d64bb94e02fb4db07bb0c400000000000000000000000000000000013692a33bb1348486eec40a9e93a4ea3810c7b4d3188cd07e235a2c898aa87ee0d17682fd24f4d978f9fb028fd26e2900000000000000000000000000000000115f8b64c00cd5cd344a7b5edc0ef0bb85a3e8f0f9dfb28f8ffe12db3e0d222c2d45dcdba0fbdc161c5d558bc71aa0977064d43d6802ad4c3794705065f870263fef19b81604839c9dea8648388094e900000000000000000000000000000000014c83d58d90db4821a0411fab45f83fbc05f7d0d7a67ce75da3ae568978d15f4c1886c6fa6086675c0045efb30d818400000000000000000000000000000000001e68691123451f4c3df6dae62c6a63855ec3597aae33a8a10ee274e902e9aab1460cc9c79726312df0ee0ce90c8d3c00000000000000000000000000000000018a39eb3e3c6c7fb8ee304e55d15e209afe2fe278dda93552a7b9f51fbd778da1502eb6775cbc3f832f8320fa0686240000000000000000000000000000000017c15910fad1ca5749aa82a5a2fa98b0ebb37e92912547fb1741f18c34e0d5fc3a307b928636c25f0320d71cb9d31062686285a0e22f177fe3adbfc435e9c1786752dcf3c11b723539789b0cdeb0647b000000000000000000000000000000000fa96d9fe01c18732e8d6454df9bb1f482c4b9add837ce9c354c72d49c2d44ec694674aaf0e6d6a095cab7ebb57ccd9a0000000000000000000000000000000001f8ffe3fb7e9e311e0f6949c07c26a0febb181e37b2268bb5e125fc3a100323740d1ebaa5e635dba3770fdc2ce4ee860000000000000000000000000000000012ac42095fdb677720ab3f14bf0afc55c95b43d28d922a5f8cb0bd841306b978751d24546e3a6474976961d0768f29e9000000000000000000000000000000000baf9804d99039c9fe966a696c64bdacc9673b0906b4deab108d34fbbaa3b0905d50892278570564017b96828c7e1ac93176b6724cf984632daf95c869d56838ab2baef94be3a4bd15df2dd8e49a90a60000000000000000000000000000000014ce6d88a7c5c782562aa101550f1af487296adebd9dae8252698ba04fbd58b92e2216de6ffd474d5992f97d9f22800d000000000000000000000000000000000ce92a04f5c8a99ca0e93992448222519fc454bda5d1d8638a7bfde968386e4ba0dcd1da59cd81d4c4dca3e584be0275000000000000000000000000000000000cb570796f5c8f7b8aa02e76cb8e870d3365fe4dce5df07ec286a0a821f922b4003d5b69c0f1588206d9544013e268c400000000000000000000000000000000098056a033d9cdae86aac02de3a444471854b909680719154b44d4f55f30087294e39e57643c692d6da725b859239080d76db3dcb659eaf6c086be6b414a494dea4bd30aef8450ae639f473148c05b36000000000000000000000000000000001214aacb0a5e6b7a40369a83c07fa8cf1786ce7cbde2b5a501d9c1292532df7822d4fde10a31fc0cecce3a7cfe3311850000000000000000000000000000000004f9669d8fe4f884ae93b2505710e6e45b19b7aa5df8cdd811f09e547efc27d21024cba05e2dc9d057055f30ec72d9df000000000000000000000000000000000a852b821b31cd27eca19712a636aa05ef2cd82c36ac1c2ca240edc7d0172b42a72c42d3cba583a5b5129ac1c9486e270000000000000000000000000000000007bd8419e791a5cea04993509e91a980d3ae4987a5b322400b6e4a4f2b636891a1c7ba4de96b53426dd556532403d5a39915646de2449b3cb78d142b6018f3da7a16769722ec2c7185aedafe2699a8bc0000000000000000000000000000000005ef88bf38b2f998dec7302cde829076e6cf69df23aa0bf6bbb39fc0d3d8b5eafba74efb928b1de0eeb3d86ec82612300000000000000000000000000000000011f47e9583997b19c36616e4bf78d6ddd6d67937f493986250ff02aef6e6e7ff074559af2f20a5bf1d67158e4a199cdb000000000000000000000000000000000007777c8eb259a836e6459b7bdb642f878d869fdcb31b105d01f280938ef5377f2775874c099dcd394abe70f17d595b000000000000000000000000000000001607379d1cd34e2d0ed765a339b21433e9aa489609b92414c6b5a05d796085269c288d739717def9db3502e0550860165061073223f066e35242772385c67aaefb3f7ea7df244d73369db1ea0b208792000000000000000000000000000000000d6e3068c082b68312141aa68f1540ea1415e93e7f1762b6f06ff408a9995542da1c727a13355c19f8f418a44de1a95d000000000000000000000000000000000dcfcf2ab12b1a0e521ab402aaa4d32ff649a5a97892eb6ad98487c3c73c35601c313b8130ad12e9098d16eed3bcc2e00000000000000000000000000000000013777b1eefa4af03dc44e4e054eb7a3a980a9c55644900b80346be84b970e1754d1f4ab771adc9249e4accf88a23fb400000000000000000000000000000000002f53b231f1209c6f8b52f99a78bc2147c951ac89b341495f4a60a6572985ce2bc823625099ec214bc9ceedb2deea3fff396ee22209271ea0bda10fb5e2584e7536e8bb1d00a0dd7b852b0aa653cd86c00000000000000000000000000000000161c595d151a765c7dee03c9210414cdffab84b9078b4b98f9df09be5ec299b8f6322c692214f00ede97958f235c352b00000000000000000000000000000000106883e0937cb869e579b513bde8f61020fcf26be38f8b98eae3885cedec2e028970415fc653cf10e64727b7f6232e06000000000000000000000000000000000f351a82b733af31af453904874b7ca6252957a1ab51ec7f7b6fff85bbf3331f870a7e72a81594a9930859237e7a154d0000000000000000000000000000000012fcf20d1750901f2cfed64fd362f010ee64fafe9ddab406cc352b65829b929881a50514d53247d1cca7d6995d0bc9b2f0d3d4cf46265fc0f69e093181f8b02114e492485696c671b648450c4fcd97aa000000000000000000000000000000000047f92d6306bed1cb840f58fd57b5b71a5df7f86dbfa55a36636cb495e08715cd57f2f3e7cd99a1efc28b1d684de1cb0000000000000000000000000000000000f4eb02d687a1a6105b4dbd740e2c7924689d558e6cbfee768dd303cc8dd0fd887f5eec24b54feccf00f473ca3f54ad000000000000000000000000000000000edad68c4d536912816cf6ef039c3dd0535dc52189583270b3b038e2c67b213d943bf384ce69c4a9dc526d7ef309f25a0000000000000000000000000000000006ff4a6b5129ef026d1d5704bf7fc0b474de92b5cf39722f165e73f4e7612d6d3bb40743e4b7b42d0dad5d5d6a2d4881915b717562844d59623bc582f1a95fc678cf0d39af32560c6c06e3a74023c89c", "Expected": "000000000000000000000000000000000153da66acafe91b6f13cd739ed3342197310e4824e7aef2e3414654c2678b8d09b296c3f928f3cc489893420031ab800000000000000000000000000000000010f501a96b86343a7c8d8c1250577cc9be6ffec81b5175ed07bd14988c5bbf7f2f3e7111df7d941d0cd267ea191d6ac70000000000000000000000000000000015e0d88894f7f83aacb6710f6c03ae60db8844dd3beec160fdb1df746b1f38a5e23def0893a0b39bee47c97af6535fcb000000000000000000000000000000000bcc275115e87f2f88c4afe8bf4faed46e6ad0c0357884356a26120591ba283f06b464c4853217865b1d2301965f2bd4", "Name": "matter_g2_multiexp_1", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b32e613cb38b41dcdf3c8bb9187d731546977fbffd79fa7f66e3d6aaf9e1af6eca2fcdc260c8f90818d7148ba2f4960000000000000000000000000000000007e4d26606a47c874c20e8480a9f5815e5b577bccd783b775d10309eeb3d2102c7a0abc3324679e44362f09e7a4ada67000000000000000000000000000000000cb6f12ac8b49cfa36b957591293c87b21af0a949c55a28a90ab0fce88fb5cb7645e20ab2edd284f0ad1377dd95ac10e0000000000000000000000000000000014c96b5dcbd3150eeaea5c2bc27750cf88b30a91933a3233a4d1d9b357a80cc20d135e43a344e718dff5c79045c31f86d5c1c9fa11c36b86430cbb1f3ec10ebbe3787d0f5641d6d7fb96c810eda202dd0000000000000000000000000000000001ca1141ba9542c56de8991b313c6ae42fcecb6751b0b81b8cb21ed70d5008f7ffe831766b89880a7fa6dfdb09a2cda3000000000000000000000000000000000e6766b17db165bba564ac63ab88d3f8f5eded07a40b48644e60d3223d30458e7dabe404cab8d6f9fe135712ef0b1a43000000000000000000000000000000000dda3e6c87382fa762510e5cac721fd2b654f002f5b9a3767a8c6d651ccc582e80e3f68d6913cda30f9f51ebcfc7c98600000000000000000000000000000000059a7dac5bb6b504f2bd603d486700fe22c14f25254537b2c9079c2b45d36c7ce56854c5699cc7649b533194f51a9045c00eb20fe7c292f3ad820a074d8b3d8d24506612752d8677c2d6ca24f556cc4500000000000000000000000000000000090f4b85961ce97cf7f99c342d3627105d790f611e19721a43d8a0febd67ae393d77a02b999108efb56f0397dac22703000000000000000000000000000000001112f23595d1613c47486eadc37f9b1ac3b3c3973b3fe964d3b67c3996fe2eacd9df5c287b0cea8e9475d146fabcf9e70000000000000000000000000000000018f46f7ba3c9af34c1025c2d460f0be966e68944928dbd55cc7fe00e5def598d80b0e3801e48a74963c974ab4727a52100000000000000000000000000000000096845338d5cd2ac44e097607d6a1a05c241eda1941991ae9edbba965d9029032c46da7218b5b2338e6c58898bc4a820f661d7b30fb11bef70e15b257d7073885468a380862202b2d705a84827644b5b000000000000000000000000000000000aafe45ea7cb8b450a51263eebc28c1ded662972bee512e24fddaf64f43b74b66032523b3b104a4e9f6b62394436c6710000000000000000000000000000000015cb27e1fedfba2d1679f78a388f90b22bbf3e7d090f0ba972fa8e72f6e31c446f628fff929953712ef6e425d16eba5c000000000000000000000000000000000df9931893cae713042bf722db6ce394b6f346587278a154c271d8511e690417eb6dc47efbcebb7c2fb9e77f1de9fde800000000000000000000000000000000106ffa395ef170c99bb5742428ae88fa4fd7a94476985c099e3b700b7403d083281fb71a19640c6bc2321e27bcb33fe2346ce87c847376c8967cc18297e6007dcfacb6424e1d273930f38bb0e88fc5ca0000000000000000000000000000000010b1f8b1c492a56936da905b8738affba6bd29ae5fffd40ba6b31325181d3b489a81b23dcb69f6e71bd29bfb388e5a8f00000000000000000000000000000000116a115303b4774da59844e457844232d088062d920db67b2a8450a194be7e5340ebd4d106454fd9a03c8f50dbb1e119000000000000000000000000000000000eb521edd61b38006cffc43ab72d395d669dec196846fa4d6d43521da6c2fc3bf0994ce7556a3cffec7751b3bc5703ff00000000000000000000000000000000073cea36eccaa1c78deefb6029903c2b6598301bdefa9759719c3b590fcc5a6a4d3d4d19f552b33f4a3126a6e6a8448639a142c443a666499a880aa1cb9f523411bbc8e5554de099ab485b6c2c2e57cc000000000000000000000000000000000e3925fa085db73c1e67b29ae90f8773f83be5ec684402e8e2360ffee8a8368911e584843e42b0d470de78591df6ea6300000000000000000000000000000000075c7efdeeb16609b4a47ea442af4d75238fb7534fd96cb236a7886809d6adc2b62c8ff72bdb041bc51c1a71b68219e300000000000000000000000000000000088b4eb0dd185e51b737d797334590e982b7b0a5f109fc7d0524b2465c2c0457964eba5a6d2d4d99fb628f21f15a776c000000000000000000000000000000000fc79f6b38f3356972669290eeadcd992a22bc1191606b663a1e148aa58db3938f0fc65e536bc5811c50d9c7f03d3e372c01b7795c2d16b5bbbb1e107be36cc91b25130888956b0cdd344de9b4659447000000000000000000000000000000000b87c47605fc060a8e3677e84ce9d14b9309360a13c80d040c625fbf0108f829300cc1fca409a0f9c96311cd4a9a21e60000000000000000000000000000000014c4088f1e7935cf6a1d2475b84497ce6a250ee2c0c991fe51a2f2836388a354824b02d9cf215328dfce3f546713e21100000000000000000000000000000000120e59be3ecf35674eac6cdc559599b273f13f28a529770fa156f8e519734c451eefb35023639f32049cd19ea0d945a3000000000000000000000000000000000f97755b62a8cb8f861ea02c77819f0b58181aecf612d92180ba9b475f0b4888b922c57f6a1c619dd5514620a1cfd9e2c712943d8795a6104f024b9701c70b09cdee9494755bbab0576e2c7f7c9d48280000000000000000000000000000000005860cfb6be6720118623d2d8ba05e686df22744b948421dd3cc1b1691e00d9b5d00d00195b4acf7a7b043f764f3f1c70000000000000000000000000000000012632a3313dd611e8d969bddd556c2d79ff387603462ac78ded3a842981697bdac34ee6f1f4744ed2ff16100874ac24000000000000000000000000000000000112b94c317586e343acadeca611c485c3ea172bc10dd39158c1e678007130062a921b53826d7be6286963ff822f1066c00000000000000000000000000000000040de8c0dadd2a6c2a7ea0fa43e1a5f2f5a6be3fcb0de6875d8cef1ee2daad87125d12f6869c4dd3d931b296f1df2fb3d4d77f6246c57d398c57848db8d3f986c475a41a23d424cd3cc2b362c1b99f2a0000000000000000000000000000000006fcd2c4fe848e9462ba1112baad39031c210952adbdd06293a622ffe2d1c6e4fcc8773ec8913717018b97bcb9a554fd00000000000000000000000000000000130a97442f3273b7b35464545e7351faf71ead9b8996c63889a45945ed82bba29bff5014776c6185219a5234d8475c92000000000000000000000000000000000491d571bac5487b866022a0714be11b38bfb296233845cc434a50be1d35f516b8c6b046fe3d0a8f4f95ac20eddea01b0000000000000000000000000000000017e34b04e6fdf152c848f2432b7bd84b3dba3915f06eb77efb8035750aca9d89e92e1d1bc4871105c440d639e8d8b05541776ed9d1029918af4c5113a6110139b8bd7f938caa204373a28ddaa51430eb000000000000000000000000000000000f1b8df4e8fdfe32eaf227f5af9f2befc85073468f10b81d32d0e126fe2b0cc8e8adb8afcac73213b6ed95e8e843b97c00000000000000000000000000000000004e3fb435ae0fb2d8bd091f250aefe5922b353a64e16abd75627737f3bc56639f8b40652cae69c73ff1969925b0afdf000000000000000000000000000000001003aed7cfb00efce49d6b1a8eba27df87479a4d37bd7fda6121549483b669a1a761204b0dd28262bf27e5c8e180540f00000000000000000000000000000000114fbca7caf782b3296d0b26b4c362bf50acaecb8bc5726b2c99f904ec3d092d5d40991d0d30c8e79fddaa45f04a75d3fa64411438542922a7bac10806efaa633d31d37c0b223314a8b6221155b9c4250000000000000000000000000000000017faf481fd4cb0c373d21d7caad40e93d9a86e62d26136892fbcc6f6e48205543aff00c45e82fdd1d3e0e733de91e7000000000000000000000000000000000012e14fcb9ad4d9d15347cf004745ed4bd92097eeeb41c4cbcb728a234616363589d8f5ad4cbb61d31a8aa27627723c7e000000000000000000000000000000001513dad1ff27e053902e779e35d04cab648939317830144ea775c435a4b55e13fa2fef03a1256abf5c187487c25a774f00000000000000000000000000000000139da29de8587c7d0ca9237c37a116387385e9cea453b9e2003a37ede7aa0a3f4c1df55255897f5975b662be33622dbce7002f41c6acab677a0ad023bad2a61b11c1b7221d944018b5ce60bb61e87e96000000000000000000000000000000000c118b147ee3489f30c6ecc0256a314ab674110588e8b69ca6d265fc270c3e5b767817f861140cca5d7c6be4012d1ffe0000000000000000000000000000000014800790654726959fd876b035bade0da744fb36ee5b304f228663a531345120267c55ac19fd66022752010e5bea7cb30000000000000000000000000000000000193ab7ac2f151750356b6e178557460c9c2672b1736d19a20e3fa28082479ca60021aa68edf2524f1aa826ee70b65a0000000000000000000000000000000015cee9ac55ab45abbc57d0ea6ec9ee49f6c59f6b94f99589dbc08ee877d3a261ad77f5473fedd72ed7206647eeafb6eac26e55f09b787c0542878e4d720027d9ea465f829a4e0164cf618c5d9cde49bc000000000000000000000000000000000ef203fab794a0ef29eb2ebf00076134e5932e27c99d6d445695b9df2afe7563602e318caf5d44724a21790ca0ab0d180000000000000000000000000000000013b9b1b1d3e98b61b0f1a0ef3a1a4ceed57b6c01849a4ad66a86332b3d27022cfccadd3567e6709d2de5b23b23dba43f000000000000000000000000000000000c1fbace49684f4be32ef6178ac3a95ea3f50b11494340fb73dc5391d50bcacafb3bf0f2631fea9c4ec47327d644489500000000000000000000000000000000040f82812855aa3e3aaba826d5810c1049cf44e86e44e23cc6da437971b529d2f2676c73e1fb9da52640c981fbd710bebba67cc47e38a129ab1140fbcf0386ddba2feefc919aacdce6059a27a1e2efca00000000000000000000000000000000060d7a718dd02b147c265f71eb136d1f31781b12a41866b4f86d7374b93dd10058c192cc0fba928373b1526e1a5d7d7f000000000000000000000000000000000cf29275373c0573ef22bf87919faf5444847203c7dc6d2e18986152cc294be04a5b1a4b0536797158113a15276c4fc6000000000000000000000000000000001016d5b9d4d200d7b4b7cc3836b85d6697fe14db350badba9978c7b56983dd1a7e572640ee0372b0a4e2079ff4c1abf2000000000000000000000000000000000f2768d104d895473ddf8c6b3cd0e7c22458d0037eca6365c766879a07c95037ee0de00d32c974d767080935abbe0be1705fb566367d9fc142c4194b0525c16672b843aac1160f9056ebb115e80d377a0000000000000000000000000000000017b9ca4349fecaa43ce911c0b256680edb8a0906ef5460fc4d2004579336df1e19560fe960a7a7cd74bb6e8272e08960000000000000000000000000000000000d5b96dae738db59cc67a51c61bec6deaeefaaa51e3259243fa4b142ef59676231229ae386ce699fbe18c4c00bf9d49400000000000000000000000000000000111b79f4b68dad16550a13334d09dc38336a75a5da23a17b5064e2d591aa3dab4c2e982a9f730a7633070504663a24610000000000000000000000000000000018f6d3616a7eaf17c805a88c9710039644d01b61aefebf76717ddcda6f4bb34aa15702de1e92bdb27b27f3409638da90f7bfd990cc4dac62a0d730f56b4eb1c1ad77ca9cd58b089c23c2f6efa00b7fa4000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb8424807c5a41ae2baa1e10ebee15363d1d4569f731d77a418998108f5dfae0e90556", "Expected": "0000000000000000000000000000000013b49054c3957d1e77ba2dc3ef75775bab9f0e9f76b33ff22e244e897b8ab80ee0749c81eceea259e99b5d2a72251e5f0000000000000000000000000000000012e017e4354ef86f73ec51921cbfdd01e3113cff044a049bdd34e36401712420790cf718bd28afa280ad12104c1851ed00000000000000000000000000000000097f28bee5d903e3c6de14e834d5beea5c847c3106742978e586ba7e913f8b631a69c473aa10e19df9795ebfa3ea6a98000000000000000000000000000000001953493daf65b974b549bb98e735da44b543d6fcfd97176fdc7f6f03617d90e6bb952a607fa8e5791df5dc1c9bba2286", "Name": "matter_g2_multiexp_2", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d4f09acd5f362e0a516d4c13c5e2f504d9bd49fdfb6d8b7a7ab35a02c391c8112b03270d5d9eefe9b659dd27601d18f000000000000000000000000000000000fd489cb75945f3b5ebb1c0e326d59602934c8f78fe9294a8877e7aeb95de5addde0cb7ab53674df8b2cfbb036b30b9900000000000000000000000000000000055dbc4eca768714e098bbe9c71cf54b40f51c26e95808ee79225a87fb6fa1415178db47f02d856fea56a752d185f86b000000000000000000000000000000001239b7640f416eb6e921fe47f7501d504fadc190d9cf4e89ae2b717276739a2f4ee9f637c35e23c480df029fd8d247c7a7e300bcb3c740fd1f693d4c8915c4c46dcb627f6de6e4847f123623cd23bac7000000000000000000000000000000000f20a07526a082e88630a0256d134a8a5e8ada07b1cead39ee838dcbb30904e9016107fcbdf1f8ba182308dbe0b043d20000000000000000000000000000000014fb7732f67abf60c03ac902577532d0acadb5f3db0d6397a42ba693526ad74f2c61a0195bdc9704aaaf12e65aa6d88b000000000000000000000000000000000018cec4fb81c85d304588d11f8b9c51f5a053df11463e5812a1b2e6c7144522ba36bb91adf219892d0007cee470032e000000000000000000000000000000000b8e52d958a12a9037e8be9bc0d5045cade2d6ea05c6e68462b3a30b5d4ea34e5fbad173761e4e216b2e6958c8983b28b473df5e282565a0783d23e65e283a103ebbddb5c884183cceb62fc32d0e9602000000000000000000000000000000001468cb35a60898ed129f30c261b8431df6a154c250ec16d85a22f8717593b2c21853d123da86d977a7938c5ed74ef23500000000000000000000000000000000011f4e28e31b5f9e6877192a5e632d8c1ed7ca0c42e6e9902ca68f1c2de0f648c6064436012c5c7b14bb8d1078e02f2c000000000000000000000000000000000b25114b2697ca7eb1e6effdd1054893a188fd382d387ec098f846c1137a9b9baad01653b963a0b0bf3cb50c3ce3563d000000000000000000000000000000000c1d241cb03e642c1752b1e1886472477c19a2801ec032dc220c3243952f882094119bb92b621b654b766bc900d2d4f7a048ef7cf5d1f6f625ee3aba091147c389ebebc5b8f3d285e16ef4e8afe5c013000000000000000000000000000000000c80d4474390fa791ea5f2f16b41506d8ae13ee0993c8d31a07712687298ee7978a724999500c42400d2f788a5a36067000000000000000000000000000000000592705cc5a8875750a4e6ceb42aa3bef5593eda9e8212702a2e08ea70277a2a66526bc5237be33c8449301544da35e60000000000000000000000000000000000facabfbd15284c6433f17b0e6035d4fdd84d3ad2dd30a27d52809652ff6e7a684d7724697919100567ad0c3e1a26320000000000000000000000000000000006a0fc4e2af69ce15a356656f5d182a2cf213d76a6047a05a1a3375909d245f5316b91333d2141c0817438f0d87bb52da9b63c6bf36997118d58600c1e429c105a379b9e8b0de934ab9f433a4fa63dc80000000000000000000000000000000003f629618e1fc3018bb836301ccdc59022f0a25cc9c5de6e4c31fa08feea525c83256235e4ec8364e77e5df478f5f62c000000000000000000000000000000001120d6af221ba6f4351bbee4c2c664a769adb17872646df2c408f70c99ea991ffced4eab50fa98be1bb9426915f125930000000000000000000000000000000015cd16b028ce3d58b10aeb84b783475d894ab3f0cfdf7104ebb4f3417a038107128f07518dce548271061cb8c97e88af0000000000000000000000000000000018379875b68bc26107f9a068e5034f29dc2ae7e8830f8e9ecddc53fe7991206646cda33d37b31a47a977b46be58d7618f228da17f49667c113d2bc2a2c8a338f80be68496f5145b4be21a5786ca6d46b00000000000000000000000000000000036570783711b381830e35878fbeb187b84884a9a0e88c38e84124515b470e6ac18157e1499026b27f4f731a961eaf330000000000000000000000000000000008382838c18d56c046a8db495babf8d14c915622d7917ebe10cf7da7ecb65f174cddb9e70d0262ada961b396c5511b410000000000000000000000000000000015f63ce982aa581dad5c71fc79251b7f6336c4e78a4a0f4cb6f87167cabd31cbec987d7af4f11dc6d693a0b0774864130000000000000000000000000000000015c001372fe0530a3f50fb8b30e75ff4b264d673e0448211d082c7a9018f583b4d01790019874596c59c68768cfa3e699431e18a462fba704216b516e819fb3392e315b0c92a7411a329cdafeb51124400000000000000000000000000000000074d78cdd35ea17a3013e2301fe9f80f2d20d270a25fdead37eed7697a52d152612543781763e6035fa5452ab12cce25000000000000000000000000000000000e572236e1c203a1c0f99e6ec978458c1a143a6a650eee27cfbe406bb2858fe5f30222f468d119703c2f442bc644ff3000000000000000000000000000000000125384343fe132e16a9fc15efe1b3a9e47289e0afc4b44d492e33a6216edbc96d66c1ca66944a8296e7695f27f414c5b00000000000000000000000000000000084c2cbf0d7c932c3098ded7c70d4411eed882feb0f79e0f7f1c31f5fccb6d53fb57de179c3ba5754bc5e532c3784df12051041bd2f12f6e6e29924139770fe209b7bbdbcd6c0bcabbf5021a7dff2d830000000000000000000000000000000004d46066439c3ac559cce863c58316883651023990180470d2efd06e443a7caf3a514b54f15ce6e850d32779215bcf4a0000000000000000000000000000000019ce904b6c9c3de59f7d5017f60f1978d60c564f94a0f1964c24c876d1139a7ffbeb6d0d4884bbfaf5f2f189af6904a50000000000000000000000000000000015f1989719e69be95f25dda9358fb98aae2819e0deb7e2d291e2c01e85ba26a9da421896c6b6e2ed20f609b533154694000000000000000000000000000000000b287cfcf1dd7c6d735c1358dff15393ddd6c82e7a33c5d8005c4234cdf823c76a4725fd74cad74b3ec51df67f09af0fb96df57a600dc3b5aabff5b1034886d24f6fcf035bcacaaec738deb2cfb8f85200000000000000000000000000000000006b37e2226957d639fcb0bcd6c20b3c7b8372e7347a14b970e01c67c1859fa97c754ce588d0f835ecc053549d963ab4000000000000000000000000000000000c6a5fae8be3a32e3f70a4202a1ab6d97183964b9f7b9a084c49922cd9e0e952b0bb66c5580f0e0c417e079493bcdb4e0000000000000000000000000000000017b6132f11adc0d5d693ae7f3a0f89f5779708083eba23e03b0c9265e4e60624e1fb6940e8ee49d31618fa6389b1b50b0000000000000000000000000000000000a45c5f6df71359648aecb6434bad1619c39f10e279a02b3cc9725d0256bcd126843fc9ed29cbe02a32cbbe79774a3378176412b07eb7f423f23ffeaa0ee642590e0b7016bc063f3fffa93e1e35484c000000000000000000000000000000000ffed009c78ba9af8cd33af7b7697ae4dff863bb92365055baedd2299b7f5b5e8abb84ed434f7223c3e309ca53c08aca0000000000000000000000000000000003b2370c837dd6291818efe7c9af62dd51295c418739ecc509d42c92e2c97d12a9fa582946e176e8153fc9a273140b2f0000000000000000000000000000000001e63438e8b4a0462cfdff64a281ab4a7f48d51b51325817139f8ee683484f8695f1defc0c3efcca81d5fbff06cf9c54000000000000000000000000000000000192fc391cdc1ed6ddbd317f2f366f2ce25ba27b8c0f09c733e7bc0c0697544399a3a4f1186d139a8f6399ffa88e89a69c4b5627d84e153f3a4ecc14ddd6baaf1d62253a0f88d3af51be18d991976da000000000000000000000000000000000002e105e0eaa418d58019a849b89accf665a94ffb0bdf308a11b99b521de7af8ddb150c0e3b2e9c54cf5456b6105bc81000000000000000000000000000000000691a3b3986fbe1c0ea22329364454f37f645d6abe9310e883b9191ce512347e074e18e28b88c2adcc76190a549b80b40000000000000000000000000000000003f3a37a763c8d0d99a3fe36923843a22cb0fa18ced48493b2510fc99afe5b7699bbaa6c2ecdad8aaf72969354f121a1000000000000000000000000000000000f4bbae00205f54eb10c83d928d908fbae342b76050e33c51b6e282e02b3c1f132a4728dee4ea95455c25fdfc112f2542ed270764791aff081f1dc8051d22b8e18803a7e310393f21bb4a495a445cd450000000000000000000000000000000009a3e98fe4a98582ce9f274965f376cb45e8583775dbadf626cb1327c1f8a25b293b97e7f8f31ff72ba7e8e769ff25ef0000000000000000000000000000000018e4785ccb76c4897087c8a4242ddc744c6a0a53a4a844254153c23d6f16d4ddb945252d13f93101613f4eb0b1e2b8320000000000000000000000000000000011b81d344eac04d3471b1edde5e51f31f97bea3396580839fa094db58cf6bee371bbdc045fb60c3ee5c6cd5d3f6d3c4700000000000000000000000000000000073476bc5b1d52ff4ca89c3afc099417f473543fab6e59cf9de8a19705dc4bf2a210b1e6de4dfbde035c312be0c70c56fbfb7606b64eef0460b8f33a0be54451fb655ce0b81db89eb7862f392450354f000000000000000000000000000000000c414b95b298b9c673001173ba7e5ee3e03926f28068481cfa0b469ab556f8fceba9fd0a815180ae0b82c265fd4c6b7e00000000000000000000000000000000054a242c1cc1a9c710bc23305d09c2d613ee8eb3840b37943bfe83f9c1db456ab4436ad319fcdd8684db129d76c95320000000000000000000000000000000001683711c0c7f02e67374f190eed1ce6559479d6d199f43fb5b0ce7df7774a5cb21c86b3b3498855d9b69c5763acd8c4300000000000000000000000000000000062f87085dfec847af518bd71c078f994b090c3b27c6eaad79772ab58afa43993db52fb08649a32629d61c3db12c87318a29fcc442d0c2446697e94dc47181dca7a314f9073c06aba6dc55aa79978d7d00000000000000000000000000000000083eea9b5b2d5ac5f7ef51ca889a4317322d098a408a741827fb3419eb12a51c07c788c2798cb37635e224e99bbc894c000000000000000000000000000000001312ec00f4b3a4305700b44b3f215779a9a8bfcf5b5d3a7f237a33c5484099ec9bc5c8537fae768e2c0ec62168f383d6000000000000000000000000000000000cf1d5d05d11e1d07074dd34211d0f00eae1df4dc550c55bd2fdafaffa1ad36abd5da30c5d3a5aa2845b1d95a5cb571e0000000000000000000000000000000015223baa9f2ea4b04fdb05b05bf3a94dcabc5e64189aeee39c380de9a34fe6b4253f5795f70bbe51b80e1aec1eab7196d5b468797b4af1978983faebe59a28f34956dacf5b7f65d25548bcedb518f45a0000000000000000000000000000000011a960cf1978aa2ce1731b857fd91d2f59d4b8d7c6871ef6f4f85aeff549a2f397949d11a4793926fe7be37f3a83d11c0000000000000000000000000000000001954f056834d6e3b16043ef1acd0a47a353300257446e9a1db7e58bd0d7c4bc9ceb3db51ae01cfed9de99621e96934c0000000000000000000000000000000002e2fe460e71b65595ed93a0010e5ccd1a2c16fc4e0d345e7226c947f29720d2f3f54282f79cec086d3fb1999b9629b300000000000000000000000000000000060dd8a7ccb613f1521168a8a322aef9f84d9708a893f704f4fc9a19e2493f25620a47e0fff1bc1e212e65e92873b4f2dbc6afcdd409e5d50d7b655580f1144de77f3efe5d6268032eccab7deaaad997000000000000000000000000000000001472caba61c2f1fe4b1d0912b114c25de103ef4351668f22f3a158d7a347539a7b6656044bd490f036ca3e29dbdded370000000000000000000000000000000015f8cdf7786410b409f218164063c99e77d8f72f03882a6c9430ec725ae574547d3ea3cf30c3ad2c9c3febe6c30b1272000000000000000000000000000000000ccbbed85c2809433fbcf22d6490457dab800b21cb4de414c7dd1804a0bdeb7142f8ffbb2de921c2c9eabee6a6351026000000000000000000000000000000000a404f42c48e3ca408d3f92079b99805004da928f128206d8904ecd7fcb14121c7d9a9e7fb69accaff921315ef3d5372807347519f114e78f99617f6b147ca833bff7be962c9b1e1f32b5babe6067d7a", "Expected": "0000000000000000000000000000000000fada9f43b29abe15693d047adc277814cb94694cab3be56b92312ab7666649b8e9d92aad81f8e487be0f74b9ce8c250000000000000000000000000000000007f6891775811a325cd7f548011ad4c705ca0327ea0484d938ce061c913a7ee6978293c3258c4b865d5c2325816c39990000000000000000000000000000000016761f859beb90ea03aa35e954d112da02daa8e76de80297afde9c29cbfe8ef4d42dad535917685a99b2a91b1f952ae50000000000000000000000000000000012a4f24ab88341dfb8a60c19993b8abea96dbd7033d3686c40903728b4fd4da7d07961f2584b51e9e6c05976d555757e", "Name": "matter_g2_multiexp_3", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b52f05365c4df20a7290aee71a7e030615d1a2a971167884d835c24e756a0faf6ed0552341c561446c7fd3d5e887d830000000000000000000000000000000018718ef172c045cbf0bb132059754b62414097eef640a781db6ad521af5a24d78c622d9402033fa939f70aad0510a1ac0000000000000000000000000000000017e969e44b4910304b350b5d442bb6a0b71e1f226cb4603cc8b4dd48614622f3f4e1ddecb1894046649d40f261d94e030000000000000000000000000000000004dacaeb9e05b9d60ce56c17312a092cb988bff426b8a718cdff860186935507a06eddbc4a1a29e4ef88db83fc4b6e77830630695c8dabe9aded1b5365bf93770aab7e9ef4140a2bbde2f0a7b109724d0000000000000000000000000000000019829d5799eed5a081042e4646d46fb6bead6d3b9893a4240867b25ed6af6a3e154514f244466d80e3b9311e060bbd7100000000000000000000000000000000156157a654db2813cb9c1b4da0a3ee192fad076bb2767020fc5fc00e967c1a35a367ffa375703e1181b3705ace9dd28000000000000000000000000000000000093385a6a9dd0ab996df54b23f47f4a49b3f379e11bc8331016ecee6161fcddd22f6d49fbb21f098873f1e17424dedca000000000000000000000000000000000d5b5b0f2ce81e755b4030b33fe3a8bdee38c2c60ed3b4a88bffb9207cb762c0a5c699ff424c000ab080d763abc5438d184ef5eceadfd77b3a4092696ec34d0551c88e434567638623740b7d5f9e36160000000000000000000000000000000003af8c25bdbd0dc1cc344d55366f15555709a74e1f0d8d7050cb6b487759db6200401b7868fca3c2ad26e6362a30e6250000000000000000000000000000000013f8b6ffe30f9a133fafe64461d305cc6b2cf5aededf68ba396d4e00df651531c750a3d94dd77bc5c6713b939b18fa19000000000000000000000000000000000dde97855d7728f409d873b83b6879b45ace5b73f317687fbf478e594a959ce21d4d751db646ceb20432e8311e67404f000000000000000000000000000000000fea997323cf29710cf0e3d44ce682e039d6cbda155e43c94dc8cefc5e94000de4b9525123b9615b5f1019a46ef37ad3a80d9efab033e920061cee8f8d7ea6023cc05f08340642613628b39e7b7fd0af000000000000000000000000000000000cdf60e3bb018407eab162822468255bcffd54cad9127054bd1c30705a4ebf1afc7f539cca6ba4cd070b44410ec751150000000000000000000000000000000009a2e3e5993b6a7007dedbbd21737a8c0aef3ecd4607953c4a24bb3fed97ccae01ae1cec024443f300b570a66e9ac3bf0000000000000000000000000000000008a21fed19e9ec2a741ade7767b0c9f39b79c3fbe34aadc9eb3043583768d893bf927d26231759290c7dd9c4f158d5a10000000000000000000000000000000018eef4ff88d63149d2632c9db586a4af0606644b16c82fbb0a3b869f1ff924c59acc8efbfde7bc604497ff68939cdd0845111c860f6f5725f99b225c53b9fe1a70150e7ce922bfe214900aaa2790d145000000000000000000000000000000000f5d47911596c46c0c08cac5f5e7f6d0609874da4ac1bd4e0e59c393273a5fe31a756c7cfff2a01d19e79d209d7c6d3e000000000000000000000000000000001010f864eb6624132d4436d18db7f5b34727060dc426c109886be88031e3c155490cb3fb09e1fbccb7912875477c6d840000000000000000000000000000000005cfbf1c2ae1b80a8c7cfb2cefedd907b0552794f4fda101ca1a723b18de8cbce30eb54287e1847cee3f416cd8b45f2c00000000000000000000000000000000084fa63781f7eba9c7e911ae5866d485bc7e90603541c55d1ffad8b3cf7547fd57fb24b14002560e58410b828513e109c07041840216d60ff445cf53b273a46016c8ecefefb53550f8bafc79966f863a00000000000000000000000000000000124870cfa469136c638e0cbf15802f2699aacb66d7e4c2965c6759dbca4b7e47941ad9ec37a84db1afeeeaa65a7418e4000000000000000000000000000000000d4503049a6a53536bdf41dd832a6ecf3f10554887da7e389cf940394e1d88db94369b7947436546eb6c6e82c48dfb9900000000000000000000000000000000053f9a6e1f05b67cf553073358009a172e2ab8b43572a974da1f3de85a29103b13d7e67b2a359297172d27dba5c61439000000000000000000000000000000000abc29f50ddc1c113c73700b9b9796890cbf48818ba981fdab2db27ef1c58f4c2e4595b99eae397d40990ce2f6c9317c29b031b82dc8c9f4ea9524793b54207d4e13a548d73297f2aa6241aff57abfd00000000000000000000000000000000007d2aae9794b7a7de97f7146c0ee8415e09e56fd42535bce6773cadd6f7ac09c4eafe2e926cb7014377e54c703eaa9dd00000000000000000000000000000000172a4a33ccf99eb0473b2c44d30bd53159afae0c7706ad128bccf6258974d5e5761f9be43e618cdbd96027aede7fd5860000000000000000000000000000000012601bce2171c6e4c2968a3efdf1491285f9e4ab37cf973ab5c8e224ad5b40e1b6459ac89090c73deb8fc79fec7fb8e200000000000000000000000000000000112a6443116e6f98ab348e57daa3971b5fa506e40515e1611fbed3e7dd64c5c1e991e0d2539a70eb93e3da0f573d6b2263d26ae92119c7b06d83d7e2922e06559b1740eae315c6623d3e543c9bf54258000000000000000000000000000000000030372914b83644fa4db1958831e9335c72ab7a811fb337696221a3290e4c54bc10c2225f8fdc3a9f62632ba2f1594500000000000000000000000000000000114205926609470b6022d24046a1997c048e6d2cf6043397892c967692161c0ceedf409bf5e1199a64eabb1ff8de23640000000000000000000000000000000017cdecbe73779855b7b94920d4bc8ad057ce51c5481a5579650df8a5bbc421030d2ac44568217c4dbb13d7c639760236000000000000000000000000000000000f194fa814bfa7396697bd812d9449d06fc61b580d7a86429fdd1ad376e21ceca139356d7d13964c3c684563675711c67a02c61a7a75342ee7f0745886c0ea2a73c21500aef8078d21d20b7216c2990e0000000000000000000000000000000015d4ae1521acf897344c3a76261754ff99742585af4a0ee86dc473a88fd408091404df1da9d8bb291db68bc9c07d6b2b0000000000000000000000000000000008ce160213875c661163990f3f7ac219ea295db5e828354864517ea8689ec15d35c6df78ff14cb276e0c97ffd7fbc09a00000000000000000000000000000000038a3ee211e777d6d6b7ca6c7a0d2130f1a071c030eebec412c3a0f14c3584e7c5cf15de254a8f141a8210a90249ee5a0000000000000000000000000000000019f7ec6b2fcd8b3190ab37a6e843340d3f3fc092f5772a042edbd5bdc967b96e8a1dc9e435b8463496aa1301f87d0e5a81b0c87102055dc2901826875d5e85a794befd93fccca2b9c0a1f70ef5610d83000000000000000000000000000000000fa7f8fbfa1d4ef5f001a451c55ed261dee344025e599884b29d086e15665867932120d33bee579d5eb1b7e6c7299f310000000000000000000000000000000001f06356f793350b17b47a623059a068800ca1eab6089c7c146182990063e8e23bbf40d95a42bf6e976224b680b75bfd0000000000000000000000000000000008807f6606d2302450bfd8b38fd4147b851ff59762c1ff48f9442c4d7b77a32c5e023821eb47fca839a27fde60e5f61d000000000000000000000000000000000c5b92f1ca9c20d4b6b11d794a5853824cff20d9267a20a7aaa4bed8bfdc728c4d4d50feb8f0b569757b97f473138db1ebf66fce49c6beb12737fe05e3adc0a51ecfa9144ccf6253088dd1a7a483de070000000000000000000000000000000001191410ec6c5ff628bd25d35965f5e9fa7f3c3d8c0a9a1ee7ae37437a97c25e221110d892e2c7a0e9c8e386774eadb80000000000000000000000000000000003be30c25a18cdab139277232d8888f6d13112c9556895af8030f1893114d5845d895df9afe3c6f9ff7ffb1919adea9200000000000000000000000000000000197f6b4e38be0358a3f1722664c61e62587ecf5467f8aadc3a236b47682a75cb76bafb18a5c556b321d5da49cd4bfd4e0000000000000000000000000000000002e4ebf7f22d929b7421a600e67fa2e64a59edd87a2e2eb9dce1f06d3c793f1a812bcdd510e654d44fb4c1de8c64ba9f0305523dc79dc4b905e65587fbd095ed57aa42403d2df5dd489db8f50c99e9b60000000000000000000000000000000011c6f1dbccde640f63ad7d40089779d01075e26269421b4ce12fa5341f58ee9110f17d08dc1052426f2d00da2dd70b4f000000000000000000000000000000000740b147bcdf06705971c113a5cc12fb37345dd59f2cbb5ff500ce2b347fc5a8199cb3007a871670d5093f28979cfade00000000000000000000000000000000046563ea98b5e85b3c42222d5e0d8481e6aefaf077a1b99f2b4eefb397ec846aa3659aacda569054c9c8b9b69750272b000000000000000000000000000000000812d887943506d68e3525ced9b979354539b7b14003a3169e0084c26326b92be67346920c9a99ef0f9638e8991296feac23d04ee3acc757aae6795532ce4c9f34534e506a4d843a26b052a040c796590000000000000000000000000000000004c8078fe8567013e8d05a546934026cdeee7d485e30d739407db16fefaef53ed7bff0f9adaaf064aff014ac919d91c600000000000000000000000000000000107cc17f485af7f22e07cf14c5cad6368323f720511fc9dda677b360567f769e47a77f61274927ef9b7be48a77357ec40000000000000000000000000000000001487f0880a6cbdac33ca35b9b65e4ead9d8c2e9180c993bdb2052060325aff8c62668c643f0cd9b4bb1f06a3dc74285000000000000000000000000000000000d4b2d062e31fabe8d2a329dbd6417673a519f455739d140246f2b3e43e20f390088c08e545bf0419d796ac71aebb5198586d7ad8fc3e4fb42981a4415224c0d976ebe1c342e9bc1cd66d35168bae33d000000000000000000000000000000000811e9b0acfc10830c074c5a4d9f4d9382461eb523a61dda0b77f1c43b285fc5c1ef3a1fafd923addc9a6e904505a255000000000000000000000000000000001113102d015dbb509f0b8d0d0ebb4d3711c4f0e1e3d55fb0af247dd24be4fec9d6fe3ad73fbdcfe206891bcebefee4dd000000000000000000000000000000000085aae9e58fb97b96ca3c089acab7bdbd0c3adae141bf61075f5c13145b0d07113f1075dfb959bc7c2d3d3b3a06ab2a000000000000000000000000000000000bb5eac8125807c10270d94e5bcf278241d6fa82f68e41b5529b28aebc88870af55881db526f7bd221a8c4c0b29a1b7d6e7db0fbd2a7327c85054b4c0de9727dc0b051058f8bb4ecb1dcc7f825781712000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d94685cc8d88273d4aa822f44a447cc22f5a58c420bcfe757a459772825619669a720000000000000000000000000000000010192b925fca096682acf138833b12d96bf97c9a2e69e4266eaaae1785b9008f36082e23e2d42341427edce24449935f000000000000000000000000000000000d5b24a94adadbf542aa663114096bc670e1b6c99f3b661f55de121922452534faed7f68d6b431fcf6f3e379d7acf6b6000000000000000000000000000000000acdbcae49206b749d8c0d21017a33e689ebe26804d1fe7c863a2ea4210c3559805dcf73685702bc56e644b4e02614a9000000000000000000000000000000000092309d684fcdf44bfa321d473060dc2d8a8c66c51419894a3fbadbf1b56179c31dff25403b970d543f1dd0e19e56cf5b6e462d809f8bf1a62f276dcb27e42d9aa0ce33fc4e149e87181aca70a4ccc6", "Expected": "000000000000000000000000000000000b219032a2461a5fd1e43361c46beeae92e30247acadcdd241692abe81691c295ba38a1f0a2a45ae76b1b95d7d0fdc460000000000000000000000000000000016905f64e581aafe928520adc27c24703e7adeb36dfbb416a159cdb9b9a26c9cef0821ccf52f5ea5253b7c9d78769e9d0000000000000000000000000000000015cfff195b2123aa140f963628c41deaf19dfff44d26a38de4547c3d15edef10fe9f65b1802dc374d7ba8fb62117c8880000000000000000000000000000000018dc725cc8d8919a7414b7866fdc54c4467b0f87cf99fc9b36cd65c0ec526e32649f9c57495657a93487f1f2f5769168", "Name": "matter_g2_multiexp_4", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014441b14765eee30e8131a7ef62c3b59370f2f6f0dda20fb2a3654fa09492bf695de1d1a8f250bfde3c7d2ed805ffaeb0000000000000000000000000000000019d813f8be2519e89d42a9fd3fef09d44a996d6a4713a9c224bee10f0ebb196370d6231fad810edf9cb4c875f08357890000000000000000000000000000000001a5abea13e909bbefdb51ddc699614366f271b2f6490ac8efcca7759833f3feae11057ab1b9ea32311e7b6ea6de110c0000000000000000000000000000000003ac2bf3c5486ca176e34ec5212165cbe04fc9e8c375e3e999a31fe014eb824ea3f2d06b9cf8b86ce3a76960cf2eb4d7535b53ab5f1c596eb966f57867e021d0f3b099e17bf384479c959794b17d6a4b000000000000000000000000000000000598e111dcfeaaae66d1522be2a21131350577253a3f33bdd74a04b0bfba2940e73b62fefa8f0c34c4aa91b633f6bdfd0000000000000000000000000000000017fefff7d94afbeceb33714e9b5480c3a2f3eabf9d7f6e8507ae54cb65f69b21cd7d04d23f24e3a272c589f572b91864000000000000000000000000000000001652e3f5a99ba8dfbcd1f90de955ef527947642054be603c1b84b24bebb579b78e2a0be426ec21d32783a0e55f0178dc000000000000000000000000000000000a6c9ec91e8bc86ab198416cbc76239f0ac0b903f40310ee1f2066b01b08191538ca913c2736f53f23ef37fea13d52756e0512ecbc5a1b02ab19bc9bee4d3d9c721278e07b7a6e389c4d6443232a403500000000000000000000000000000000072e022c168461905f798e87425f2eebb517e473cef98c255d0fe434863ef5811920af65bc946b29d489b5dee1066c56000000000000000000000000000000000e7a9872caa82d191f6014c845e1b3ee4ea1ee89852b546a2c85ddbfa3c1d4ce99002e3d7732ccb8cfbd57d550285ab400000000000000000000000000000000144be65db373f6401d76e0ee64e51076b861e8fca596dd6a7f3b5735c23b0cd13248404fa0969ecaa701663a1032f48a0000000000000000000000000000000014c9e9c5cffc4518889f7742440053678ff1d9fb1a1a103d0c1f762b10655bd5849ce98f4bc5eae80bdd9e767aae4523a79fd15e80b694122dddb01f836460b3eff99e61ea6309d6b395c94fb5a43dff000000000000000000000000000000000948d0f0c20715f8658e1f2b4f9d32d851e584287225a2f47735a1f4c241b07f8d7c5dd8c13bcdf84e97d49817d4d88a0000000000000000000000000000000013c064548cb756b48600dd535af8eb5b9138f984bac0391df2e90a204fcb6c36017df910031864d802a2ff719856b336000000000000000000000000000000000000b7eeb7c9a01be88e573f196c2a531635baecbc8cff9af385455af3757301436686596ec7fe3618af26953c49f7450000000000000000000000000000000001332f4dbd5461ab9e2c8b3c19c6ff407a071018c92d2c17c1d1d481c24565276c0f55eee8692016c1fd76d70f44627cbd012914a96253926fdaabec06944ffcdb4637a05e3e78a9bcf1b21b68b9dd9b000000000000000000000000000000000d3ee70610b5029a28e586f0f3e65bb19a263db3438710fcb8073e1b25f83db50eb5bbb9d75cb20952a225023f747baa000000000000000000000000000000000682f7d5cf9d182b20ee88683f3915e8c9b03074a373e573aa57232de4e997bf155acf680e365aa0988989dfad102b2e00000000000000000000000000000000143962963e230a9154dc328f9583f5be6923a3b10ee7b1d0cd5f5cbff13913d8ff78ca315be7387900a50b94449884c0000000000000000000000000000000000f4f934b42452d41cc20d7b1ec547bcbcbcc10f215364ccf2b864db23a09d06e94c7a87165dcb691f4975323486757ada300c7e1041d94df0e0201e1135fa6eafc98bd33b2dfbe4c59b546a52538c07d0000000000000000000000000000000005f0fd4080e26971ab16d33aeae04220ae23781da3179e38190082f1d167514bd73bc8ef976a2f333570e9f56a6c05e6000000000000000000000000000000000e159905d29b52ba61575c3a263093017783e1028b3701ccf060c165ba33a765b5265a9b1681c1759bfe2c9c401275e9000000000000000000000000000000000c5ac0bc29a49a7c37d772954da850e6b5e301e230552be9a94017d770ebe2cf4dcfaf104633623e024aef6db57892900000000000000000000000000000000002228e7f42a9409acab49cca82cacf306f6c6c29fd9f7e2ed12fef2d16383cdb7bb2b39ad598b301072c615232db1fa833e9cdb10fc117afb17803b61a2bca7de1d190a325639eb23743f51f28294b3300000000000000000000000000000000180569ce03e4a0155285e733adb18fbca71225507a7adf01cb8e8648891525305e92087f58378f4fd8455d5632ad660e0000000000000000000000000000000011ab84e42f10154e306a568d7cf7bc381000f0add0500cb508f695a3b283ea69d140aa0ad48fce2d2d6fcafe60761078000000000000000000000000000000001136c3016474d6f475609606e8d0269fcdab9fd3188a512681cbc41eedeadfa3b3d9355e5b4503e8b5c3665e49fdf3ab0000000000000000000000000000000003f56cba1b9cb4302099b16b09c2602dfab80d1151685ef78e5054cd454b319adf8b5998053a5b9fddcffa020595e3bfc48b98edd9c229037751d02e58f3d4234d9a3b0ad9ae4947ae14beebb274746f0000000000000000000000000000000004d79dab9eef873f3415d66172bab7166ce0c71f322529bdeffa915c1b0d3fcd645c91dd3450ba61593ffecb95edb91e000000000000000000000000000000000d611a207d3222bba199fa083d0459675cb5fa00839fb4c9034ad868fc1e79d653c18651771431d6fb6b6b5ce8cf6f7a000000000000000000000000000000000ce802ecb106a4f0ca4efdcc058dd0e29deb6a5d30a2c15c8eda896bcdd3ac19053c10105328d239b26c5ddbdb3a95fc0000000000000000000000000000000001073e142621ecbeff6f81453660362545751f992ffeec3a83477fed3e6215a709ffe0d17b65d3369f8f3913bf000e844228758d2cf8105f2ef11d83018157a3119a44874dc34d5f0bddb533f50df52c000000000000000000000000000000000bd84f04b3858b1138b1b429c7216d5d1b1e99c1e0fec26440d59b1ad79788c2d5583122c2ad769fcaa6d10d816a1f1e000000000000000000000000000000000387977ed1ce5da51dca230531bba53d17d3de5d593ec576cabfe6463d5164d7153025dbd4cb3525c4145c4f6b85fc76000000000000000000000000000000000a19c943a90fec6921367a2edc5bc38a5c59839cdb650766a2d2d068242463dd4460bd1d0e7a7fb0e3d2104704b8b3730000000000000000000000000000000011d99d44b200feebe00bd42809e3f67a23cce88a07165416cbfaf4db14420f99e54d62db4280d2c99ca0bc3dc41eddbea417c96f0cf4355a78513c77cdc676a7b09125802c8045756da867e0025a36f10000000000000000000000000000000006a186aa584a466a860849c78e4922889c95a4ac6f39c99029fbb422c43d699a8baa51aa4ef51ff99557babeb3e9506800000000000000000000000000000000065fb15b5a0923bdb52dbefc7e9f1a898e32f17d610bac829235446fc5e1913fffc8176e0fbd33091505761f1d06d8920000000000000000000000000000000008bd358698fd073f660ed608462cfcef1da9a59b10905f1d98c4fe66958e56802814906430c10fc25a4d351d91f91cb0000000000000000000000000000000000a53638b1b6c6eeff468e099446300ca7c7bd899c6494682d14fdabfa9cead0bb37a0325d99e7d0ba6341cfa1d257ba846561328b7689b0a89014823537cf9eeaca6ea5c56a3e58d2abfc2ee455dfccb000000000000000000000000000000001070b98c6348a67e996626ec2752f45e4c007e9c9668459a777c03fab633c10236a1c5be99f3fd950542d5648ef9e88400000000000000000000000000000000073a564401cb1a3a53334c0a55da261814d27b86ebf40b02a76b20973ba2db92e42c138ca7790261c2d70401c984bf470000000000000000000000000000000004212d8a9e4b01f5c6814a88561c2c6143eea61327b031a2e0e4bd056c12dd7098fdfe4d1511bb441ad42b55b584a7bc0000000000000000000000000000000005c5d23824b0fe05eb962194550681c57c1566b315efa8ebc90b3593d7d86ad18328baab8118c9f47eccc0757588591ccf6c3fcd4b9e6b72853934b306a078b1f2fb17879db4a0a93d484abbc2b746cf000000000000000000000000000000000b1b3053774ad5515a20bd4c556d2b3ba95fe74fd0c955069c7f933dfd718ede90ac295f5a675f1c29dcd9701978353700000000000000000000000000000000145746ce88686021a0635bf6f0aa2f77c48bdb364cf4ffa804a57f95bd69d24eead05fbee24021c1ef57e1c7c7b894b00000000000000000000000000000000010ec4795a0762b86f3b83de1198698af67fd1b1be3ddef48f35cf82bc96d886fbb4c75064f51a9cfc5f61630c95d0ad1000000000000000000000000000000001465e31f58892466b8ae4b76a239d9f8d1ecb1834886344013cd1df0be13591798868d224d38213a6d75b02a1fde0ff2f6787b565e8d71be6fdb0c97c4659389c800a2047f668b366214adc716f402d5000000000000000000000000000000000f39e731e6ddb7496448c912ae314e833d28208252c7f8e27bcf7eeaf1da6e2310538b4ef0d55401c6552e91fd70691600000000000000000000000000000000069d3612f924961f827497028737000513548ad8e104acee28f014e730d4752a583cb9a893e6169b71966a1c4a4ad2dc00000000000000000000000000000000090899907edcbd336bd4fdad0dd67c578ced4481a25b864b32aef920842689a2c23265277a6e1d4a1dc1b5047a9f79a000000000000000000000000000000000055ba64e2502baf68e46c759fca30247a080464eda2b32e7cfe539e545d6aac6dafb731c2c45749e50513979cecbeb5440ed91f6ceb2ccf87e4106a16227a3cd7b2821b4f3a6e629001f78ba1aa7346e00000000000000000000000000000000042f1c8b9fe81cdcabea047d0998a1354ce09d62a14f1d0e9d188e2f35f2e1845c2b090c5e157595b33108c67e6c184c0000000000000000000000000000000018e69d3564d4ccc0306e1e6b227b0f961aa9afcad59d4ee1737f980dc876609c59a4c6a3506f987467beba0764b857000000000000000000000000000000000012ce5883156588cfe0f4838f819f985b09f1eab40a5ea8e30fc5d70d029a01a4537641248f4c21dd203909e0170737c80000000000000000000000000000000002888eb9778a4045feb5899dda258657b9f41345731ba630fbbf186b3be4b58ffc7f48abb65b693b573a73f85440a7a7ae8ddfcdb4748981acb9b2037c017174a140f2457fb0148fe807fd194a9f7be500000000000000000000000000000000051982b46a819c74105cb36da871fb2415328a1531d155856f6551bd043eca62ddb61f24af429edda830fda31e22cd340000000000000000000000000000000006449e5bcdb5619aac542f6633ee3e06a4fd56a3e1ce4034efc608131ff6ead70ca63e70f494f519d5c577ae7119c8c200000000000000000000000000000000153f4f5dddd5801fbf7f88a735b9170d24d5b63861d50cde9644579dcff277cdb0d5fbfc3b3b819a1172de05afb9135b0000000000000000000000000000000010fdea84983fe6c08cdc4b4ccd462bae2ba791ab5209363b10b3ef342c9a5e92184e9d8be1419e3d88402bc05bad5fa21268803aeb58a2d57fc797358fb456d5cf96afecb1ee0d2b90782aa0d652b8c00000000000000000000000000000000009b011f793d9a939d916d058ffe91b58138820a646cc450389b3074ae3715d06ddec1075afecda71c65c7ca085210c740000000000000000000000000000000003d4d20f4b93c1e90a0a06bd534d8b4fd64e4c4aba77ae42cf4c5b2bd95f8b02ec4069ea246ff46404e6c9eac632fbac00000000000000000000000000000000051e88c3adfd4d6a02d3f03812362a6cfba3a6c69b9aeef75b51106cc7f1750293d61e31f0ea29b5d7aa56debb6d2aff00000000000000000000000000000000086d9c4ea6769cdf49ffbbf7351023b4aea640e8c90f9291222fd0b5984bca4d481bf7e10df921406a34804e6a09f99df9a8a4e5c65973b785c1e2637937de239bb0fde34b786dceea66f6bb12eb4169", "Expected": "0000000000000000000000000000000007638fa4e8823dacb40ece440f8f1e57cc5c3851f94357a5325207db92380dd57a7c8709e4d00b670e8af1b77368285a0000000000000000000000000000000005b66a6e6b13ea0eb367a61ffe7c620d9edf5563cb4cc0cdfa68b99d9691cf9a40efd967c1e880238eec313eaf4c92ad0000000000000000000000000000000004f7156c69ea88a71a0af2922d1caca24055d40df058eef02bbf95d864156f62fb0e17d9fccd193840c36ad8449bb4f7000000000000000000000000000000000b8f46fd695c5d96d939d42c65c3b709d32f134710a67909dc4bb43d752521a8d4f0465d0590f30f06ce42bf5f8cac28", "Name": "matter_g2_multiexp_5", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010d48bf523f3909cf90aa58a9517ef5421f1212accd5e8a0f830aeb15a587e215ca9c340bb846b1d0474e43840b2af79000000000000000000000000000000000cc1a3976caf97b9d59f448f6d9f413eef8904f360c0cf912fe942b38d7fcc637a17038973a133608ae769d3e389b18a00000000000000000000000000000000069a6122c6f0ec68834b7617c755a7eb33a80a25acf95859da5ff03316447182f122d20d993b04e79b6fe859b7adf5a8000000000000000000000000000000000058c6f8c297524319bae6722e0a957d1ba0f75ee3a8aaf06148641c67925d15780e419a38ed7e07410e82769da74f2d070e7e2ae2751a1f71962726a31f77553c2da38f4fecda435b6e5459d5e833b400000000000000000000000000000000156ca5e80be8c8c03a5506ce9abd22a9d4958c372678c0caf6f1329898507dfcb1f06a9464cf080bc6881fa5b7df1ebe00000000000000000000000000000000088174d486b4086b931010da298a399e15b60a113e08f571e096d3a4e94b57b3a684711318796eeca9319119b201abb30000000000000000000000000000000000b96ff68505c088cc03a1c2dc363b05bc8544728a12b29569bed137780523123eb17e68f4632383c252d81bca0c5ca9000000000000000000000000000000000486fc6e5224c5fad56234c41856e60bee4a6c1046f673bf7d5c1bbb603b141fc91074da5f9d3d41b796a2ebcebd9e74d16aa883a20307f5436354bab32b4633e83178f33626af3edb14f82724b8e12500000000000000000000000000000000121fe97c62e068988ebff21d8129d52aa903afdbb62862c7fd99564d9ad72182ab1f3a1100223ae486cd76f6938e123f000000000000000000000000000000000968ddedb04f52140160061828b5f88dfd09aaf37df625ee6f66b9500d6608df31c7edf86296eccf8f9918b051a5e4df000000000000000000000000000000000b7491cb8f6252e3861d7160feb0afdd736d27886863ec0909a7cc711a9b71aace18b17a00a2999dd57ca1a74f148516000000000000000000000000000000000fdb280093ef45b12b694ca3390a865ee18e4c04b231e2c98cc28706d4cefaf4e654582ee03f34ecf1dfa9674489d553041390a2209b80f7c64d14965cc2f515d5fbdf37953f75c4a0203bf0d9fb674b0000000000000000000000000000000010d001a09cf5dc3276482185f26ef3f75d28cd6d2667eb08a7fe06c03b99f3b6c4d82390739b6867a314291cc642a8b2000000000000000000000000000000000587846a460b1f37c2e7f491f9a097b4e86e1943d9cd0999313f65627b3907f09b5d5ac1be376a313a959dd136f7e9b3000000000000000000000000000000000af439695556e86b102926d3b40e3e54cc84464e120de3b4e3c5541a6a5bca44151fb0594009663764c1824518b13f020000000000000000000000000000000003bfd9418c1e57269e222152d321b83ae090f216cb422956dd1fcc464f68526cb4a05cdaefc7bbe6e81d4ffe27d64db47cf23dee8d95d94046678f3bdb4b0ea3d4e3a1a2f07f582e2a98ad6eb7562cbf00000000000000000000000000000000196f78b64fcc342ba4f4edf34a3080ec950532a5de21a875dd061f09351def5ba3b85745a561e38117a14c20d33a14610000000000000000000000000000000003929c2bc55f323d57dc3529bcf6644e61c941b72b424d69969c1cde7a804d157045bbf6d5b79a3e6686509e11ecdac0000000000000000000000000000000000f6b659818510cde463c52cf00bd99da045c80af4d5cd0e55f9bdd81f34169fe869c519f37a98ff20c56db554469087600000000000000000000000000000000129709e97757724e765f6600c2b1928286efab55ec8d16876a2a3210bf9d31cc5425265d0576a2d5469cbd9a6c8c27c012adc8edb64db5bf0ed6724f3b54140ed6c81ca65ef9d1b38c8bca6a62bfd3c60000000000000000000000000000000009f5f167c9b61a0ef76415fcceff04f3fa57071c2d79f443ef8a7e6049cb1352f650ebd8f358904bb432d42772c29afd000000000000000000000000000000001524a875d73e03c53b92465bafca582479110611bac6a98fc7d76966e9781308a10cb202289c0776cf5c36515733ccf900000000000000000000000000000000002b1acace94a6fe196b217a9aff413fe0bcb55122ce9e344942843e5afba0d5f2cd0bba14c9c8cb9dd1c3e9024918fc0000000000000000000000000000000018e4f85c7663e596182603862adb559635fdf16ba35fbce7278680ea289f871bcf6755d85654b2a37ae77a37e77ba06ed1535bfcd68e8136808edf89967fbbf76b7f58d1a8ac95ebd4944b9e440f20b20000000000000000000000000000000018ee4b4855f866781f38a618c2fe4214c63034620ea5b72361079b0a5c2b2d6fb9ea73fa202db3a2678cf07219cde81100000000000000000000000000000000180870513afef93870ca64e2363fa1aa43a599db97f3b807ada1c25ae331c80b8ead5cd69b6f5a65a083606591de90ff0000000000000000000000000000000010afd546703baa35a9eabaeb45d301bd5be115557bbb4ff2a0e493668ee790e947eeafcaa923f62ca00b8e635994e39b000000000000000000000000000000001089996b218aacde4ccfca4d2f66d79fe161d962baaf2d6696e1a76ea40af4ae7195e8cf9f6417ffd054f20b65ddfb104c576996d90abde581afb58903cde4b9443eeb65e21b0d68c578e04c8f28f3d30000000000000000000000000000000011757ad74a3fb341c8eb6862978ab3fb5e8cfc8fdbda7d82756532a890d61919cce931872ff339843805e00d8c62ec4200000000000000000000000000000000060783a06e93e82cb08e5dc1aa31202ba11676511300e186ae8e45248b7fdec3b7d5b6849f8b79b8f78ad84f36218544000000000000000000000000000000000ecfd8ab18066fe3408fd20f2a4478156e9a19a09b58da76486c9f6a013d861960b6b99bf49cbecfa8c9d01d5615c1bc000000000000000000000000000000000b45709845d35d7b560745375df79fb95df15e85b96cc1b98cc832c74621339c609018d153bff93f2f5493a52b7326073c558cc615b1c61c9a42b8b0ab4668ffcfc9e95bbe958e72e7a5500058e6b0bd0000000000000000000000000000000003f9de90222619216852356052e9819d7c6e8ff91e0c6f1d8cec832770ed9001db4569fbf579ab16964d76ae7d1b89e900000000000000000000000000000000010b7cf8f0d283cc22942ed73c599115763dcfc1ddc98d87979fc3dce2f33ca3531cc2909d94f86736dda2a4e94a4f0c000000000000000000000000000000000b0aa4d947644cbc7df8d1927cdec66a68862e5a806e25554f27cc1a3701f429fc7097497ad0419e21cc403b472c8ea900000000000000000000000000000000146270ecb66e1763437b824f2ae122f72f20eb93fb30474691a0a192ceb932b1dee111fa44954075335ab360d31ee68d61301b4957a468e2817db5914ff102bc96460a2c5c15e78bd42884b1223fa71a000000000000000000000000000000000c977cb8de4b6e2e33d916f74eb4e42f089d22b54b59fac9aab0e4cafc8aa2b0f8c55d7251662b3499ea140e322dbbff00000000000000000000000000000000106944a9c2d2ecd08e109de29095f3460128bb751051a1f079acb58b6a60b0bb5f52e63d47b688f4a382a77c3b039eb5000000000000000000000000000000000d2f8be1c78995d54fbccab61f816b6ec52dd19aee6aeedc0e4bde2898b2d07c2925da0440a38c4c965a823fff10389f00000000000000000000000000000000183b5d15b243cc5d9584842ab1a0a1e01ad87268728d72aa8c0d7ec6e7069063a11fdd1525d2b30b35e4568da7c44c5495cd2686d24a5bdda0bcb118a2c0eb5ccfe411ec452e1beb3adbda7e93ea367c000000000000000000000000000000000f65ad4c21fddadcc49a8f7bc281d2b7901707f51a67122179fe97da46ea5e1bc6e70d68eb4eb6776307510a67e972620000000000000000000000000000000009003dc68cb0cdec4a502436718f066348f1957ae65ecca8d32c5fd776215cb9a098c0ffe56c92d79dd68d251f49f13e00000000000000000000000000000000038ecf0bb98ff2e84b388c58059ba0de0cff3d5881ecf01d668495ce81b76b00323c665ba88309af5552b7950cc8c08f000000000000000000000000000000001924aa0f460659f552458fb469467a2925fcb2420d4fa6249310456853be3d08bd5c37a3f0a9d6e94e434391d20cccedfb81d555d1e2df92cdb487a888fbedad976dce54b5c46a39893edeac21a12d6e00000000000000000000000000000000189c3ee691387fbbcffdb147c880218c3e5c0bf78c44461ac1bd3ecd5d4b85225e46cdb068049607fedfcca14882e289000000000000000000000000000000000260efc08531083db2839d1413c90968e87d79bc1a2c730f0020e40beb92e84b73ef43e80f7c61e1a30c0cee11b3cb370000000000000000000000000000000005c852ca0aae2c575c65ef18b624f50a32c007d299f24a3ec6cacbcef1d6e3bdba9650fd7d639bdc60a3e107ee9c013c000000000000000000000000000000000321c01a9de69d6b89db4ed88dd48261ee28facc5e26511fb2833fa45edfb58051c8c3ce9501e8b4c3cab9c456705889bfeed84bd95fb955d1b1045c059ffd051324dc8966e504164e54f76f02eb1b8600000000000000000000000000000000183d50635b22e4d620130e0d4008e3bfffae5dadd7e34f4496899ca54eb4d9e3e95c54ae1d9664609c58d02ee5eff65500000000000000000000000000000000029e3b4496a379464302b1476a4549db371f5d6721704b1d6bd35e2344d7679f8a61a0c3b12f287fd86fd247f9652cea0000000000000000000000000000000012c6a3793fd23e955708f5aeb4d6efb670d25a38a67813ecc72f899cd5f926ab7ef198bf6d591328383aaf54f756c66b000000000000000000000000000000001914d3e4b6ea96bb91333468fe8f3bb74636e9a4f2ed198e9ff01b49ba02791d5bd63224f6a38538aceb777168bef688e3b308b95f6d496e6d5b910b6aabef8d9f868471653e8254ab4d49d593180d250000000000000000000000000000000007457f2601621a99050d8993244f026b9a62ff7055b325e6f1edd1cf54065785f003cf7c8a4bb1f7bdf14e220e490ada000000000000000000000000000000000928eb76b428dde37546a27f3d77605c293738f448fbdd6d618747b0de04004aa4419cc5601600419c6e1d470c15982e0000000000000000000000000000000008074e9f5473492dd2e536f7b305be4e5c564cfc9218934d03dde6dc5118064ebaa5c26fdd1123a9c31336c37c1234900000000000000000000000000000000002bba1f9b7da6abd2b322c8f11c749b2a284552eab25a77d21b38b028da477a3ffec1901a015e81fe2893576a41e4c0bd4ea92e0e776be341c8444d4040ec121a2847256c5c9bc918adb28618548b0480000000000000000000000000000000003760958eac45397eca1a1d951a80265a728dc3c584f7dae111e7ce04248885321b69b334b00cdb0334a362676c2d32f000000000000000000000000000000001031e4a63129ec40da5fe9dacfe148a67662eaa00e1fd5c30336462371c167348a10e50f4dc18469a1a6b76485f77e12000000000000000000000000000000001412dbf993c557323426b486f18a91d16b4baa2c497b30fb332a710ac901c96d46a577d04ea87afb08258aa6d204a1c9000000000000000000000000000000000da015ca09ac0c3245c090f39852218f46fea62198fba35ebc4a7f14887943c3bd1bbbfbfa300611e45f419b33988e404c07f5188e4c6270a7e9e2f551683c4f9dc943ffc7ec279d15816a7f4910b8d30000000000000000000000000000000015c9121f72e2425cc8aa4c878907628dfe75a903b7f756b9e13728372cba598859d20a92a8297d95e1fbe25fd1cd968300000000000000000000000000000000025a3faebfa53918efa733949f914be08b791794bd4963f0c3fd78df48b14ad214374b08299327575c0731b54eafed76000000000000000000000000000000000771782ecd9980da521618af2f9eb55d91d67b20ba615c7b3cb1a48d483ca405fe99a1cdd17e4dc7aeffce586987d41900000000000000000000000000000000136000da90a76d538f336608ce877be943025b4c8bf15880ea9c1c001c20c954292d362dac9783b7bf66b8d51ddaf0f2a819a0438efd7ec0c1e3eea07ba201af6a832fecec818adbb781ad0c23e81dae", "Expected": "0000000000000000000000000000000014cb24001bd933b1d5866cc3de9f4b8479fe23e4fc26dd210f9d06e7a05449b9f5ac4e2f48fb847599f625824336bf1e00000000000000000000000000000000033fdb2e899427f1cb9757022c5b614f08c64b53583486148b7431311a6f15aea3b968913fd5f3e9b624705351074be600000000000000000000000000000000035420be9c7ae3203d0dec61ecea70e22e62f50368be870e74f9a7349453647a7f61d2a42cec6522164cca0c7081d4de000000000000000000000000000000000fea43388e9f6e31d419c7f9fbb9839b4cec04163a7b401d8f7de73a4560fbfef4e272f1db9c9d5b37693378f139452a", "Name": "matter_g2_multiexp_6", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000039dc2b60389f6c893c44072f4db23e7df4c2f299d6b70b70784d9370d9ff8e5413872c227074d429db999d30dc9499a000000000000000000000000000000001702273db356abe7a3f91a9fe4bf56584f13de4069a91daa6c0b552089bef60da98d32c615aa5610842dd8a507f9477c00000000000000000000000000000000095285e8c508ff12da79e16e0391dadbe9a823c586a049e729596864c3cae117305c05f009f9e8ac032abaec8a63f8de00000000000000000000000000000000078fc70e926decf7aa4c2e4b395e88f367757dc47a4cedcd5e632c456a4c160393837196af474948ce6ad53f830ce8aeb15af019ea2de662bf187930caea19d0aa07a74b49fa7d1819a539e06e4c69ff000000000000000000000000000000000cc3cb5e7b033cff3e5cb01ba29ce8e9f4a93e836ddea7d417f7b07ba8aa71a0efae2e1d7a8ec70bdff12d84d229245200000000000000000000000000000000019ce3c830505324b9bc7cda1fbb328150d71310f06a8424dba861d67a7bc0428beaaf697646d22cae9e00477cc8066f000000000000000000000000000000000f6ff67efefa5636b104a0351c90fd3e89a32b8a9beb0d123d3d6ae42eb5e8bbc19c7a972e27762daf852259c65fce6f0000000000000000000000000000000018d98c43fe5b13b701749f4a5dc25f0e713d241d573639fcc73429226bb131d448283338a909670066045c65789bf9e7064a6af51c1d499c4c28556ad1255af7467bc750bf2db2842d626647bdb3346100000000000000000000000000000000003cf82958d68429503265dcc7d88a3763cca32baefe3c8d32564cf30e8e6b8255d4a9f6a76bce1da473b50287deda74000000000000000000000000000000000bfa9cde6c06b2a2ff8f877ca90b3827d0aa0408c4ccbed23ad461433dad71017d4dd387f49c5febdeafa17d06ba784e000000000000000000000000000000001770fe70513533d91c83449ea52964cd8b449aa81f71e71995db5b19ceddef18e2919439c80e10086e670be669696e4f00000000000000000000000000000000194c20491c9d5ed827cd9d370b9bbec55e4a7b1c34ddd1d80201e7019d9487a747b4fa57b480dbdd09af73aa4f5fa0e9a3daea5a083af43711fcb09282b66882ae5b5b8e1714e9186f33ac0dfe48b7ca000000000000000000000000000000000a79d9e0ff43249ff54526c5e1cd55a9bce93adf272508871326c933d526602dc9dae5b6f129a0f1c38139ed1c39be5c000000000000000000000000000000001458b554e0387c1ddb9dee9f4e9fba9c81c15807f496442f4b7210267912b9439a19f95dc80a1e09a0e5cfe750f43c8800000000000000000000000000000000012c06b19ed4e8d5d1b9fed56bc5bdaa3bf0112db997e33aa14899d53e1bddd6aa91dce7e9d25473b66b8578d398981f0000000000000000000000000000000015369b2228e728894f2fd7c2d8c41ac3550da4f297de445cc0f0ef7134c478f526987643cb5408a0bbb79f5f983c085ebd682acd154f6e16a583ca4968d28471653375ef79df078b17b2cd9634258dc10000000000000000000000000000000016649a8231407074af5ffa93f9db5a2ddce8785be8ee77149602d6afa24ab30b26d2f74bdb5f7464333924a817e242e50000000000000000000000000000000001b990f5ed0b23e113042ff004236646c6eacacd99d1d73fe0c3d9351ce8d622327e827b2c0556802c5657f8f06062a4000000000000000000000000000000000f002a2a5ca90285f9b2fd429721c2daffcae5fe48c571ebacaf475606f96cc8350ce88a850ed75e5aae59d445249bf00000000000000000000000000000000015157fe1a767dabc185a8dc8fea3cb208fd995ecd9acab762638faa987f8367ff7c1a60b657be6e9461acc9df16381e5562223d3fae1d303a01ee4642fb4cc70f21937ba7fe377260fe82262a8455a7700000000000000000000000000000000073884ffbe6deff99cb4b0ae1c0e91e2f4a8c2c7296339b1d7e117d5d47ab055743d643155680740befb379a1dcab666000000000000000000000000000000001995bdc23991dd4cbd973e915a16691fb860490bb54011384c553dd14afc37fe673d13950c1e7eaa29c324fd9304624c0000000000000000000000000000000012197a19a498cd94ecbb3a409337b04e76e1a52715c40203add20eb80f7eac66f3386242d51bea34ea016d778248836f00000000000000000000000000000000101069ff0af2ac4dc7a5bf7bf7b56d82a310d67cebc41a9abf1e1af489e1acef3e726fe9571b4382777573712663e26caf1d0fdab6185e1c3f9f621ddc169ba92584db0b40b6ace7ed563eee0090629f000000000000000000000000000000000849b88e7ff52d8136a120f924b20b45ea9ae654a0fa037b62f3c275f0661091038a4c1d6ce7d50512e628b6b397c9f6000000000000000000000000000000000e50e82e9b368f2e316d41febab6b0f626d6588b7217b4e28eedbdf50a4abc9039be9e66c97790d12cdedc90873993e2000000000000000000000000000000000bc5d2bdf06fda1e1d1f5c5eaa7988dfdd790bf4d952f5d3a532bb59edf619dafcbc29274fd3661a35a3f15933b1849300000000000000000000000000000000162e5ce45499e620d0977fa26a291a8e75943c4b5a2a80be395ac9b89767ea5a06606d6b75ee4c8a286d2ea5a197baa5e910487c91f3839d5961f02a67f3b357206e406ba207dde969498e40d4a26e880000000000000000000000000000000005c11afc970544b96fc1a4cbb27259e19b5fd588d1be1c8f19eb4f111882292a463c951521388cb8cb743e5a4a1b57cb00000000000000000000000000000000013dc433dadc122376b75fedc923386a7ba5a363678fcf9edf165a50e160dadcc151b6f402648193d9ef960f5e401030000000000000000000000000000000001893af155aca343bc29989ec2b5a583d020a7558c7663accf6f3e40d0a8eb98ac548e933eb8e2d5fe3550927acc2ed4900000000000000000000000000000000043a79bcbaf07bffe6c6890d95c7e74d127446bdea51a0ba3adb164ea39684bb3ac552020ca28b86e34692c9b36f4384396d32c2c9ef685120995d2244756bd45591618597306193422f3b5df4b075d2000000000000000000000000000000000e6946ddc8a9d73e5b140af80cc91b31b9a226a945a9574f0629566f7ee7650730c5ed758cc30442770ed1602b84175c000000000000000000000000000000000da0abb9f5bfcad73b3f24903e9ef887c660447332e5457e4a5764f6628c04d6fe903679b8dc8bb3aaacde410812286a000000000000000000000000000000000656016c01d3405dce9f7d40e47976bc8a84abc370e7e42849dd0bd93ef1da0bc88e428efea43dfea37dd834cf246d69000000000000000000000000000000001939b2c92c8299d7ec1dbeb9f291c5e1c9481e10df10e6ba18ae695a780aec5a185ed4c7e82dc2bb5af87a74552c2ea32087e21d775fbc2c20dda715e46c9c4970394e40e991c78ecc13a2a5d0b0f30f0000000000000000000000000000000000942901572722e5005a9ef5f948c8cd6f557be8d114d2810d3cca29933a94de3c7658e7e28675c2a49f138d9c98c524000000000000000000000000000000001908e8b815e95ec07a90861ce53f545f0cd44aacc47df40c24d6cbc61e7b28fb91cfb1cb3c67b6c5b38c34fcb2ca35710000000000000000000000000000000017bad3616d8e510e325d9166790239c8c817c68ba7fb937fd5fb70a4219265edf6625b52ff26f0a34c0bf481c482b2c600000000000000000000000000000000023ff8a50a9c0e9ee829ec81972386ea012df5e8476d8c342df6b98fa1faa1382ae921c2f1018a918868672450355c44f44043002a94560d725da2ac44f30cc5f14f52dff5671c6689efebd803b1df7a0000000000000000000000000000000014675ab3efd44bffae321791e6fb35a24b9c07405d9985c685795df2db183ee9dadf18c76cf4095e1e0695dc2c08c4c4000000000000000000000000000000000835f2cf09647061ced2bdf4211bdaea408148100f864f47ff76c0c63a43e44e8ddd9e01709b6ad129bd574d71a1a63c000000000000000000000000000000001017eaeaa6eba76923ff27e5848e5f3b09e7b2b9d55b2cb7068f39defa8628d1c8cedcbb0e1cb5810febc4ccea712b7100000000000000000000000000000000054c873449c738383e9fc2f0f74a6334904171fdb704f5ac35a483ba19a8f661187d36fb35014af9ecf88225466c86e48624c83d846ad2e53f3f8ff5ffd3fca8723e6cd431e89ca29a4d662e82004b60000000000000000000000000000000000439ae88636244d5e09607960fb033e4217343899d044b21e61335425b94a5067c941e83e5a77f4b0690e1de037325090000000000000000000000000000000003a67653818cece3ff0390d097f1bfbea9ba954a85710f5c24d1de1893f25f2863991fb9f330e60cad725708e70384b4000000000000000000000000000000000243394c3459a3af236189ec6155418c1916b854a20b980ca1044b48e23b725dab7c60a48e89f642423c805c117e64870000000000000000000000000000000004c8c9fd9f278dfe9f5e24e0f5b42699bb9751b56520827afc2fae8393c690a63f10e92f77c4a10b0c161408da9bf505b2b2a8a42887ca6dff5b5364d88962068496bee79cbe74de0e8a06209feb38320000000000000000000000000000000011ba67024503301ec72bfad101a48708e3521c8a23c6bf2994078690041cf7eb75675cf5f20c8e82d11145e31751a2300000000000000000000000000000000008ace953ed2eaef19595cc7c9fb1806d26cbf1e888075e3985b28f8d93b9c0b4c820c8e8b50fd4e0b23923d428da3efa00000000000000000000000000000000054ee6f7247296e0748d0b52148a97b930e69991a242767d80bd6434d42b0865a64d3ce60953fd2631aef873d8b2acf3000000000000000000000000000000000077748b724301a8bc48efd1cd66086e727e9872e4efdaf55ba90ad1bed7e229a9cfb79013333b50efb46090ac0bdab488ecb5976f63a38d7f3d8c8ec441b705563c5e3d899870ab5d2ff84467fffefb0000000000000000000000000000000005008a1d62dad51132ad38a226e8abd7421392414acda61111c728713a2ece284b04d75c2bc58d355bb1d3061415010200000000000000000000000000000000189725b7fc48b8a648237021e9a2334247f1cf18ca50008b813978db01667ba08f00b23b3aa0e015f549ff2d5e5c535f0000000000000000000000000000000010483cf2310f64cf0baf556cb2f2828a1c15922547bec03cdb182a316aa86b5473f03373cf7e59a9a78f73193c1caf520000000000000000000000000000000007f635394301441bdc57dd1f4f97656f4218ebb139c13a17e12839091e2e81327f3353c56880c608de824a07a17b2bdd951f4960d6614b098249eb9420077ea5ad11e38d1694f4df33719d1127338f44000000000000000000000000000000000daf4090a229a1ce946064cda1c4b19c88100c8785c69f2eeec3aed12065787ab0abd797ceed07617d55a9c70ac3020c0000000000000000000000000000000011d77fc28355f61037cae3a8342bdf8d11e963495ba3b5d67055f790b1fd632b23565cad77a3d9968d364e4e2a553c9d000000000000000000000000000000001038d7e8fedea873c864b79d1cf8045485299a2bd4d26c5ab5c8d4a073e2c3fcb38cb230dc6ab7e8e228cabc6ed97da50000000000000000000000000000000009de9209ed14d62625ffbf770e8c528594aeddcaf1aaeedb4f3ca973e7b9f9f1a40370cc74b154f3bc641665d8e4d96b7056c7d93d8453be369831dc0575df6438db488780d518a53d19b8f5d22d506a000000000000000000000000000000000a6b0dc04591cbbb1b82a059e08b488fd66edca0f2d264c352f81cb6ec45e50f0af16917fa4727ee9888f84b6c888c60000000000000000000000000000000001369ae16bb0743f65cdfc8082dbe0d588cf8aa5406a095c3deefc27eb3ed462dda9dd4921cde6a1d878a805cd144515800000000000000000000000000000000124e08d4de6e831229005663df4e4bd5bb7af56dfb13244c50410e6d0aea420ba19208bf1a774207e0e0170ad3a9b4f60000000000000000000000000000000011b2973743034a2c362281b11a1ac1c89f59ace09f0a53afb0c2ceb061726c7aaefe274f6dc04e5d0dea2b687a00609a8aa982de1583c25307e9e2c8cf2469a0b1076c6be2fbf12caa8584f34988221a", "Expected": "00000000000000000000000000000000136ff52e440da609b6b73aa838f2eb9791221291b7b14d902458aa7aa9e37114c573edbe8cef7a98dd07275a8c3fd650000000000000000000000000000000000ba625eb47be09ac8cd1e2ec9015640f416af0e3e0e79d39ccac600ea08bdae7a2bc9144f13168a8cec03ce66b9daadb00000000000000000000000000000000095c51e81b5881b009b28006286c704ce3b002e4ca50ac8ea8e574d1e9665a5b1efdd60568d4a4a656ca6a2d1750a39900000000000000000000000000000000143c0c4b3b720fcd0b044a6f420961e2b7eb5f9f1b0d200de56ca8b02709d819f47f0a6ea7d6b49c4f30520586a45616", "Name": "matter_g2_multiexp_7", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000da4cf56fdbaa9004bf8ffa12d5cfb3f296ba5262dab079c91bdbadd6e41ee5f89912bffd5df1643146bce1f0e021b3d00000000000000000000000000000000150227356e48f29443a0ab4536e7a2f86f9e63840e23bbf1b091a59f52c27978bd6a15b29b105132298de45e51134da50000000000000000000000000000000017f5271c97d84f55f8b7ee0d73267bb69cdc7565c470a4b531f9dcd29596eaedf46e61bd79e71e5ade7d000c1c1d81bc000000000000000000000000000000001322812590e6c22bd90511ed72553c1cdb0ba83487b00e3adcb01a9abb438f365ca23fae9ee4a953544253696ddb0bf1a18ca15f0d931619363f5ee56bd7657b2298f228cae8d185c9d062910193e9c40000000000000000000000000000000007c59f94693320b01b56b36f8d1c39fc9e01bad289577738e648771d8940778276cdbfd59f07926e516fcebb70592de0000000000000000000000000000000000aa71d6dcb0b225526eb92b79891ef920634a007b87986fc0f776f85195ad7ec2d84b9bc684add947df8ff42c33b034d000000000000000000000000000000001362cbd6cca3d5c1ec68928be38aca5de1f224e7cd4f5c3ab1c2cd589bbd7c31022d4adc51720bedf2580d2acfa0f06400000000000000000000000000000000162bf0f38e19ddca9aaa370f988be9b35461d2a0f46143e8663f1fa549d0afa1596f029cf2f800b027b90d1eda6ae8a2b54274927eb29fea0cdc464271c918826d5249b2180a52a5020480d1020c9795000000000000000000000000000000000eb12a92fe65f79c646ba508fa615d09d86e582c3337ae16f66cd3bd74a9caa9dc17defb4b4e67ad62f0665c9ad1b6cf00000000000000000000000000000000058b6ce2582c46c0fc108a37e1d2713ff21ec8b1d8c18da0e69f0dfec7f2f327043e174e16d9d64f9ed4d3818a302bea00000000000000000000000000000000068192bd2ebc0a23092bb98c23f5792e179913c4ff1f23eb27296a77e83729803764b8db3b7ba4fe154ca467475eefb2000000000000000000000000000000000482b16e876aa90da6da35e0d7495a04d5b0a1d084c61821f23e1ad63cb1e66ef5975a3cef9ecdf2e696e9d9b50bf9b65849bffc842c21277be88dfae0040c54b072ff526731947cbec0cfe963f2d0dd000000000000000000000000000000000b712fffce3e63362bcc246da566a14139a3d12807ba83ab3520b0aa3aa20cecd5718e2b7e00f24e6fa705315bc2175800000000000000000000000000000000057a66fb12f27e4a5268e56805fe2b61b5ef019b31fcdd861e2b0beecdffe1a3a69e8d193815f97740324aaa40ce34a8000000000000000000000000000000001080a9e1133f37288dbc3835e45b6611fe84ec4790e23e5ff84a2f72bfa2837f55cae9177e5a3a918adde777b7298a9200000000000000000000000000000000142dcaefd73d7f6342e87fff8c6cd161389b6049fa077f35076eadd2b4aa66f3a1819bf8272cac1c28cc02bb6440dc42aeff769da1b62fde321d46c66f8ee7f2129446d805ab7f7bd586268de8f57c4300000000000000000000000000000000034c0f8249d6aefe4cdbf84d151ea9f84add42ade087048bbbf9de4a412cc805dd9b608fdcfa34fa224066b5f06d18630000000000000000000000000000000009e235ce5eb936bae00d3fecead8859e6d909da3d57bbe0a8aefaa5efdc94969a1cb2e12642c0099bca4e7bbf9833469000000000000000000000000000000000b6fbab498c2706f0efdb4effaf79218cf4b652a5205eabeb84f05a060da8cd18c8154a3d37594485ba50a8228f27f6800000000000000000000000000000000130ab70e17dc73f773df99cbe3f978bcd3fcb92a8226a1450239d209cc6969e2cecdc0bf3cbbe9a9c1de072bffbccaa952c9e56cfe957b924c9c0294e1c1f12474331c662c8e86288c97e6a8b8b5b20200000000000000000000000000000000031a2c10e95b841ecfcbddee4b458385e5650dec9a2d1e50216d9fc261a9829eb5fe894e47f171c8fd2f4d5d89771341000000000000000000000000000000001378471c7f770672ee82b70fc87af5ccacdf8995df9ce48aa9fc2f638105a2fdfa48b615970665ae4869f1e2dc7988e8000000000000000000000000000000001969517c503df5560628555a8780138e4c340d9d49d8fac4a8a11c894d283d49fd06aa81e9f0db8f015d9372762dad75000000000000000000000000000000000f5c2d9b7fc33167a6e9b5a5fb8c5d16ca009282edc05cbc8a048b835b16ba33515c226174d6ce5f9836581611ab403bdecec569d223c724d162250ed1d074ed9f4080aaae3f44b77df05292be48ebd90000000000000000000000000000000000a6a32f2006c4b7804e99011d934ac91b1b3fa6f5d02c574cecd6570bde1e998f135449dfc148aaa8fb8757d0a7299b00000000000000000000000000000000198beb461b59f57b85d858b730fcf853d967a1592e5e5787fd81c6a3d9d9b40c1cd7912cae21a47aaf78df5540604cb4000000000000000000000000000000000955701e84721866683b4eaba82c2df8a89bc906fb0a3cde565d314cd7278b0c56936205cc8ada10b03e69b93c48067b0000000000000000000000000000000004740253653a0d6cb15c76e145dc0b1f811bdc964f7d595b6027bb012b42409deaa8da83e6ddc3f0f7b4b237eb62b537915ac9453b831c41becd3c1f412cdf5379e9cd5c80bc6df92ecfc5005356d2aa000000000000000000000000000000000f88e1e30674934bf1062ac619f1834f35f804a958e82121255f8087ae08f10525e740ee53d7514e0ee7c49e324513c700000000000000000000000000000000019d554645696b7beae881ef62297283c5b68ad3fa9a84a47c29cb53449d33d6ee7a5a3cb83b6acb75cd41ac3f52fec40000000000000000000000000000000004b32776966e52e8a72c88a689d6c56833296d384e2059d8f615ccd3616972074987f839b4689d5610a88addcd836d930000000000000000000000000000000000fd4d21b00d81ec993d2350f1fe360576fa983754a7159c2e81024a00931d84e419e8b5231ba8cf8f05a0ee6ccea7e558fa60bc7cff4edde18301af2348faa69ed4f31d437decb7d4fe51142d179e6000000000000000000000000000000000177830cf34186191fa295b7f279bc819d8a53452e2114dbfe709971584ec7a2da7453aae3e64f4b14c261e22314027c3000000000000000000000000000000000ebf2aac35fe070403a4b7a5c2f102c67300bfd68af7863b45185b37ade1bc53d46772062189f348647e74c77caca4a600000000000000000000000000000000128dc7846b2dc5c453ba5fe4675d0c22f4d7089624ede05b0910c34ae623d4671979fd73455b35b61a57c51fe2895adf0000000000000000000000000000000008e33a3c3735be035b550613c712b220595a83c1953b24b3efd38c5913fc23df823e00ae5a1c2ea8a8eebbb93c5c721dc29be0b271d4e22d39e9e06db9e50845515880f30c5bfac80bca39a2d8d61ea0000000000000000000000000000000000a060a957a8da4384e3436110657110653685bb621c32810b6516c690a00c13e37f70185958beb0ed886aae5cdd611a7000000000000000000000000000000000b5afbc85e274049985eac230b2aede7b2df1485c9539a4a4eb6aea406d0f6515ad8bbece7155fb0dfb2123919fb8af9000000000000000000000000000000000afa722987390440a33d5103445dcef42cc4a3c461daa076d56fd38e0b220016ed2bb8e99b9a8da4af96b7da64ba90950000000000000000000000000000000013ea6b8d327191e53bc71fe43fda305a4a0584cad04048afc0480f179955cb27f2ac8791d847036470ffeb47aae36877dc8c2e971a3a4b9909dcc5cc6a0de50286294ee15f441521e0f1d2c3ad3a76e900000000000000000000000000000000032b490f795ac3242b8c7185c9e19f0440ecee3a65263dd4e4c9a431571deb7339bc6e2d73ec43750f6f027bcfd674c400000000000000000000000000000000076ab4ab3e8ed6ea3b882fde5cacb3bd094567288699e11f368c3f60f4283c5bcee7b4c5debeac541ead983f5936d9f80000000000000000000000000000000012aa2060e421f4f4249e83ca0ae1752dfa2b7ca958821841a18f05071a35fb9c1448619bd96f8a7adb2202d3ffda8eb30000000000000000000000000000000008b24f29ee7571f31ff86574e654a5d849acbe92653ae1a1d2baf4c9ca6e67da4937bfda51a70931a6e60d90162efb4f21c9ae0132a4886820115e71e280d33378a04344f635c769fffe91e89fa7ea47000000000000000000000000000000000c8b41e5c47babd6ea113c0ad9f45a75d1ef6bd313b768ac01e6f581ef6630ada623c1a27d4aadf543af4055de7f6b73000000000000000000000000000000000a0f73af06f8f0115bf17f7c5db0a6bdea77a8e3d8fd0b52b0d4e2c558f1331f655dc272c86d98bf166b532ec8e45285000000000000000000000000000000000499b55964186bcc6986e7744c52babf47e274e47a202abf6f816bc748baf846df2b5ced2a5f61fbb0aa2047bbaf82db000000000000000000000000000000000d6c2a9a3fa5d0524f772cca2c7e72a5f2da1a6a1b9550997e7a6cac5b6b6c37693a01d30bebe4b9c742b63bd31487a1e1067c01d5565d0f387516d9721f7f4e5253d5af8353db4a55500e20a95f3c9600000000000000000000000000000000143220e1cd08ffaa6db4795ed4aa35f3b12cce724fcad005367328972f2364f34096e32f1f1cb7a4287ab636d0030322000000000000000000000000000000000f2de47a37a55edbb75ff0bcc446611d690d7f9efdd09ca1ebb6f1d64a330bed420bcc85aed8b95316fcac3aa7d1f2230000000000000000000000000000000016afb044b8b8c64547e000f80b25576aa329a4319dcd4f1bbe15d12e6f3bbdddbb52140e6297c637311ef0c7a31cafab0000000000000000000000000000000019e6803c07fbaa075093f6a69f9dde05ba3d3f58e67389d7f096e56df49f8270008ed422b64fcdadf7cbbc8334037682a23bf766a1e1c068e6e8e4b60391583ac197ade53caf0f8a43c53d1bae9f13e500000000000000000000000000000000134125416c7908cb4454ce6aadb30df46042ef2a6b4b69b19fafcb9ebafe8b5579046725590266cfd10fa26e1b5ff3dc00000000000000000000000000000000073f4147cce24e13b9eefad7c69b457acf126bf278a58a26a7c7c6b482edea6dca9725d7e5e4138b4ec81bc2505ce2e60000000000000000000000000000000006125caac1061cd6c556f4cfc122df8e949622a46ca707b48ef088ee5623df058bada1bc0cce1399f0be1ee86225f13000000000000000000000000000000000146e398c161e29c90c8a4fc44bfd5b3dba6f9e80ead561fa3d91ca5f416e06318dddcfe5147ab5def858fb025a1562352c505d4fd8287a897e01517ddbd7d7ea9d26ae4f58fbca172e5265e2b62858b6000000000000000000000000000000000944942effc77ad02c5ddb052acf86f3a9dc4127dd032181450295464b49ac1dc0047790acb378221fbeebd4c92886820000000000000000000000000000000018e1d201b38d88665696ee6cef11fb19f7daa7f11c5a5ccc73e6b66ac7b89df8437c9f07132ec8b69e13f63424ad694c000000000000000000000000000000001463117fdcf17f28956a42677b3ff431cc17ccbde067b91ecd6fae51e1e24ba8d594ea368d041656022611ad3ed44a6e0000000000000000000000000000000009715cc5add17395b7ddbcb961269fc5d4739d799fe9554b3c9e9f59c895ca5df8ec75bda05cbef3e6a165f7987e78662908006c06ceb9188651c59d434988cb5b51a5a75772ba71875444c65ddf0f4f00000000000000000000000000000000007c07cf1ac9b8b28e3d2f1f4ce22b8ee46e99914ba20c7362c679559a1618a906c6ea65c475ebbeca4947019cb6fbec0000000000000000000000000000000008b29f72cda71e0bc2246ead57b2f758b741b9232d87be75331275a5cd63afc9aa98b0e42c1b82cc258e93c97e596a81000000000000000000000000000000001512548a4bbd537a4d5baf673fb76ea7e35b2977216e7b29a6375e1f92049d7b7d5fd5d8b4ae6191f5592b738e149a5f000000000000000000000000000000000cc9d646428135296919808c6ac10c142e769bf71bc1490196dfdd4e1fc7b84e58155bfdbe77a9e684622ffd83e97ad3e8e8724c80f3527de5f0b2b98ecdf0b8d0471e63c0763a89da8a21a70dbf8399", "Expected": "000000000000000000000000000000000ae9da7d12d0a03cca3b41ad869f762784cacb988eac7ce904ec9ff47824e058e2e211e2285f9fe2aed0b4385949b4540000000000000000000000000000000005b0c873d20f7be1410d39885ce4f79884eb6ae2b2f27510d6f6874dacf2a66c64e56b7aacac61ec88261624936e695700000000000000000000000000000000076c6076175ad748dd68fee64431e5e4ad013797de4528287e7226c3df90233799ed5c8b36848c1a2e1c02591a013d270000000000000000000000000000000001f7f6972121d38ee2d10c621a38448ed12271f7e0e9e4567fe1b5fcb469c7906196fe92c66c37f8c5abc91160fea8ae", "Name": "matter_g2_multiexp_8", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000139cbf360b10e59c20dd4155af2023d5dfe0681c62351dd541cbed41b6a328aa44b862d1985b132a4d4ca61c95b61ebf0000000000000000000000000000000004af6b5a0f7a02d5c93304be0d31959bb4b1a7a5838dc3f9cf50180c4eaf3d32e68c006263d75f9735c8f0b5f811d3cb000000000000000000000000000000001644937e5ff3b8d2005a2f3b0984917837d44412362a121be481526173a4c61e20d61076aa10b4072b79743c5f7f4c4f0000000000000000000000000000000009bd399b55a59550dd876f35e54a5803058228bd6ab6c9a66e438cae473c63816c96bdf378ad426a236b58b90e737831e14282bc687a00264b4e4678ff238d5205f6b6fcc10040d9b4393e93f76297a8000000000000000000000000000000000f343e5118d7dc3a38e9975a5f40084ee5f2305e45a8aed28ef105f76345d9f5646b4f3924b92978846b4e605b78fdf400000000000000000000000000000000017e61a2ecf9b3403b43f5a10a97cf5088b4f98e5a4513b0912ea7ecef44e6809f10dee60367cf2fe3e903dd68c2a97c00000000000000000000000000000000039f37f414338cab0e12f99b2aa1e3c02cbdee3406d1bd17c359ba899b7cdcff605f894530895aecb469f41628c3da120000000000000000000000000000000001b78bf69f1b7168d735fb4b7b135fe70db79f50e792eedea23f83cee9b48e092536c2ed146c7499cf047c5b4f0a08735307650d6cfc681508fc7b8dcb5291837582eba6588132f46ab8fba674a1f5af000000000000000000000000000000001342346f1b553e29e661c9f6c0a24d8f788db98262d6af86af55d313a37eeabed1183e367ee3d83faa3f284b260e786c000000000000000000000000000000000960c8af3f7e6587cf83baae447491e73cf41e637e1efd730e3acd9793717e57b85530584942e7a030bad3b91a76996300000000000000000000000000000000166daca4ee2cb9516b5178cefef0553115dec8157f6194d24d191cfe6340406071883c89246c0cd5f89bbd5d0f1ee15b00000000000000000000000000000000187f668086b9b6307899d301bdbfec915cf24ac0be10d6897b0677e4f1de6a241f3dfb19225644858be0941530e67d0f7d6a25511ba63f0b7ebd2189cfc4c551083ac92b144e30dd81d27e59dd86e22600000000000000000000000000000000032c3783e701bcb651aef40c91682eda03f9d90f252740612c85a5727f8bcc41a886b328d5ce787031c08ace235ff465000000000000000000000000000000000b0eca06f9fb69ebb46d0af56d3d934b333514d7f31208b4ee2fb92009e6041749028a78246a0adc324034a94503e80d0000000000000000000000000000000019eb24ed35f6c7ae53047814cab14d51ae6cf336d140a17e794d5cf18450b7fac3e6f990e12d340291459197bd353861000000000000000000000000000000001983a596485e657deaedf01614dcd5f4ec515c0050e8068ea02c9833d0b165c0f467107a50da0d8cd43bfcb59db6e710eac8e5cf13de6db37982390c8b6b0474795f479584960748b7ffed881285e2df0000000000000000000000000000000002f1c29ffdf7bf20fb8a13363393d5f1cca5dd9af82888f0102030fdda641abd5532ffaa2669c0c4159a989cef1c5bdb000000000000000000000000000000000bd548079899d49cd368bf5c246aa168fc8c777bb84a7930258502c8424a4b68e1ab20dc9ef39c307e52bcafadb0c8e100000000000000000000000000000000070c18918f037d5fa1aa005e2c80ce6a80b4b24d33ce72a2bd824f9a061af1db236f04d6041314310b31b805b8a674800000000000000000000000000000000014422b173840da655aac6ea4b7a04313d5d0675bcd565258c73039f879176e51ec0c8a9deba9c78c33179a5ba54492012c134652c27da0a0272b0783551ae44db6bf592ff299b48c50c550367d470b5b000000000000000000000000000000000a1be8e39a47dbe0bd19b8108a5bdac582e1d11ef7fe28df1f12da52924e734e1d591e8e33ec20c6d5af5bc8c1161fca000000000000000000000000000000000eaa7a7cec93b8d5eb933103b52a35b3d58214feb8e2de0bba3a0e57e7993a9df0dcf8089142f57f8e0d1d303588ce9d000000000000000000000000000000000089fbfb389ba448eb77722994178ee3cfd15a27be4ed6f4d4ab6ea1a4c10d6ee8424beb17d08190fb18ab8498d4a4fb000000000000000000000000000000000ab02df2eb474735e28c45b915299230ce159816419fe9c99a7da397b7210590705262ee14c2a244f4922c35bcb119338dca9ff432bb483ad726bd20cf96b07ab6f07170a1449f0f1b50ddc6e1a0253800000000000000000000000000000000006508fbef44d36cdc6fb37b6324810ab2a1d94e39abdf09d530df34714168105e23a7d6f7fd9caf31f263b658f16b76000000000000000000000000000000000b5bb1802813f9f8a16991d41275ae6d18532e3dcd2eae091da7256aaddd501855e775b779959fcef2822685725cd43b00000000000000000000000000000000052146ee63ae277911fe491420651a96994a30c7d1b19bab32eded008a125369baed2ec5a963bfd863a83c29bc1afb23000000000000000000000000000000000a180d79335347a8be350a92491760c6bf1fd56604d4d99a1c49bcbe50b2d04b7cdde55b4aea8ddda4bfeb8e79ab6ce4146433a0738ab1b044e059f49a8af8d85546d0e34eaa0edf2b2a6ee466c0def80000000000000000000000000000000015dcdc17a9afbf88b54af22ed2168329bc43ba50d374c0507c790f37f9669d0af167328d50d322a827d45f39724d2b2600000000000000000000000000000000169b83f2567e921a4319fc03b2a7eeefd2aed79914bf608d9e0a54aa71b9cb3e09f1cbfbadaa520c0f77f547fd407ea50000000000000000000000000000000009b7a8ff8388c85a0fe3860f26b09b81b5dc51e00a8961fdba96eb462e1334e9e28a2cdc4be49dd8b96c548c64921718000000000000000000000000000000000243782436fe7cb20a3242a3a21402a43a2c4fcbe77cc7182ee3cc04f4795c269d8a64ddd25e89ba4fc796747b608092de0399ce1ed861c0ebce1d4e811ea0a3d87e21a54ae34e6b5e1284cbb94973680000000000000000000000000000000013ce6856b6df48e4c9e3fc0be0aca5b139e1b874de6ddc148c1c23a846d61e7a531cc889bab99706668a3b69d32b9160000000000000000000000000000000000a459676071c7f3065a6dd7632edd5842db34aeda8fa0e7d7a8ea29f842ebcf2c5fdfa74ee7685caa51481c4f46952240000000000000000000000000000000010c1d9ebf7bed9195cf0bfefad6ba45f1bd19a9a7d340b7c630b9953923efe4907bd75a3da066fe3d49d656f3ed91d2800000000000000000000000000000000039189de73332d5b5a160c296a195cb9d8a736cca23a92948d513da7e4fc46e1ed9c207e86751b3cf1310d8a7284877ec2b034594fa53a0951e2116db1b063345fa42dc8c870e1146f1b00f626dbcfdf00000000000000000000000000000000129821e97c65ad3801c011792f4c099e19919d7d03bf9fcba30b3735586bb7ead7d4f9bd10bc5f0e5cf1dae82d5651ef00000000000000000000000000000000038cfbe45bbdc494988a2dc72dea6a7e36652f5e5a2ecad41b4aeceec05dc4a389e54cd3aab349adbe32e65206eb481b000000000000000000000000000000000bbab53f2be2c471d6e9cbad719a73c00b582d0983e25e1969c0be1faa56b1dfa5b7b55797b3340cf8c7eabc560fac71000000000000000000000000000000000b0db19410e552a2f7889c2204a93c5cfc71c360329e3be3171e88fc7aa1e993a5d089c28b1a8f8fc80d93ba194c63ccc1e6d9c5f8911014f0f540211af5184d96fdfd47c03bf2d7bbbb3bf1a330017b0000000000000000000000000000000019320bb8d29b7b5a7130b87a39e87e271b96656b5a2749f13208520634009c26f9829401d3e21cee5a757782c6bbf9ca0000000000000000000000000000000009b37068d72463e72f3a89b9093c1b09f01770e647b5ff7daa50e0679bb76404cf7729d5575a39f5b9b3b371893967df0000000000000000000000000000000019ff29e41db50c736e12f62d76a28f4ca4f6b0f4f61aee00cc0e9dd4e5a75c0ca965b82698f704c604bb309aa5b457f100000000000000000000000000000000062c352a554dc4bb96b459378c21ec6446e15b868221b2fb745d31dece854bc281bc22827d84ea3b0fecfe5d156712ce6df5a133d3332e1f79f41201f8cb2c8c8d4d1ab0f640c4de6bd6e34884a77aa200000000000000000000000000000000021c52e82b0012537b57fd92fc276e8de842a59355cc15d69a52effcfaa7cc43dbda0c34e1b9af44c2db8e9356b9c71e000000000000000000000000000000000371a6da5dd39092b6108f631a0f4c4401464a109ea1e5d14e262c8a9577e1421d41734d2c3ed73645cc13ef3988e9e90000000000000000000000000000000004054159263ee60f6b1882ad7c376c738c7ed87e6b34dfb4be2fd7aa29ede414c2c6c3ff098c53f22a1c1cd836a6b0600000000000000000000000000000000012d7af6b57c688e1ce90e9f2796b0e525e775fcb6be65f5d2fbe3d1ce1e5d948dcb098c98d495a6e3dd813527b4635258e7219a9d431c597fe9700d43da8b545072f5a27a9f1af99053ac0494087dca1000000000000000000000000000000000e53128fa5392dbae9e40ab1ff0149d5b577d9d30dcb85eb5e4fcdc17c7daf2ff1d6fafd4a1aba88d2e7aeb45a01afc60000000000000000000000000000000012972781f214511e9b78d276767b1b64bfe5b43215c7680c0063b6974f703b209b2929470dbae16f9767a7cba5311fec000000000000000000000000000000000cf6b37c5a60851d03752f68eaeaf37ac67c661f644cf507c5458cb5404d0ce903c92ef66a657b25ce07e5cf5d956929000000000000000000000000000000001835f202705c8b984a4c7a6cd219c718ab27a96671574cf7cb618235d19e9046a15212e0da6233f15f18bbe192df29c38efb8a7a5e48d5f4a011a4aa0dbab22ede62c903414d005d507ea3d77bd47a6c000000000000000000000000000000000d01c6e8e34e646911391b012680f0dd8f4b8d77c10192ac09ce57b6524f0eb8c7f83ff8f26d856e0945d7a909eb790000000000000000000000000000000000070fca42e34dacce0051f9e26c7c0dc328fe652110976df6df77af04202831dd095715af1714b60a99f2177e86a3443d000000000000000000000000000000000063ba43df0155373df59b009a8083b9f62004327b16ad455037487c5b8325e7eaf57a4d05c533e284004be6de79ad1e000000000000000000000000000000000870c2e5a7d26ba54bf0d45ddf0a4c3011152dd12a5e01a80e42bc4dcc784c7ffdb66f9d6d69ac445c1d9aa29586245147f53e2c06664e1daffd7d9b114e12d4190d5d0fa2244d61a13da915c39b8d53000000000000000000000000000000000d84ca02ffb6d3cf6eb27a143ece73d5bf006ff61569f0eab00c5a512c5b46e1fc21e8031d1a578010c9582d75e1faa8000000000000000000000000000000000a41249cf01ecd23d06f6a3bb8573186fe47e5165ec0d447df62bfc236f4c203b4feb8e2a4785648af86646cfb0c4e32000000000000000000000000000000000244fa6caa86fd27e044145557697ea89baf718746711c8dde334a2c5ae3c73d7a0e04fed6289ddfaf26e47a9d26b09e0000000000000000000000000000000017db897060c0a8e3e5d8eca9970407b46dc2c2ca0c004d50a171450852f585268bfa8a379acd01b6d4685e04c0b8c106fb109d9a0a7b62c7c452bdf0a2853c4bf65e5439fdc83aedec8c0bf73a16b55800000000000000000000000000000000071e13963e20eb1dfb671aa4a090973e4a4b7ad3578f8630db8a865847be46c796e6f9e095a9ce558b93d702f8f8572a000000000000000000000000000000000dfc4c89ceaad07e3b4c35d96e8534122ae48421cd4443de478ddf9a8867ffdab279ad745e55c87b731afa7700bbdb110000000000000000000000000000000015dd6b0c26f6821177d0cfebb7f1481a971e7601fb24ea365a0c3127a5b1042eab69446de05b61cb6ac0576752f87aa900000000000000000000000000000000156326c52bc78c82f5cb4aec5de35e3c128c5561dc80da2cb24d68a7e912b1f2dac2078508fdd4ec38769102c082f0f74b0a931b894fbe61115fcf52be51d44afdcb96c94117c75adffcd8729b0a699a", "Expected": "000000000000000000000000000000000b537dc10a6f518122665f7d78326a4728a2889325e5be7da7e25e4752c680fd786cdaadfcc426343a9844efbbce8f2300000000000000000000000000000000085ba3a04aa8cea82b95dd994f5b3bdf0dcf63f13909aca2c2d61e4275a7ea22445c953b927ebc6b0987e98b553469d40000000000000000000000000000000019cec2e9fab640cc88073bd39e46cd571324904b1950fa8f626e2725936d80daacce2487f46ad23fa8af9c6ca0367fdb0000000000000000000000000000000007039a0e11cbb8bd940eaf4a192bb94ff8c6d6c79f775fa67821b5ba411641c09dfe9fac4cf45eb5fae52d2fc4beb6bf", "Name": "matter_g2_multiexp_9", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f73a297cd6444809aa11b0756167e71986ab31b52b57d3c0aac5637129b8702ff21ec649541e79644c27f0017c8ae3f0000000000000000000000000000000016f96d6ba02aab604dd918cc799cee61cda4c0164ed9f07d4932fc4ac3eeb92b1e6b40dd7b18cd8d26056b486e57ed290000000000000000000000000000000012156f3ca3aa1e79014dfd92fbb6c785cf0ee449a8920b89ad04355e0fb7c8ea804bbad082b4edc9abd3b24ab0df2b61000000000000000000000000000000000d51b5f62a6e70816d7671bcfc52f11bdac6221a23287286af78605b99ae8bd0c722e485bd0381b958a85f61e05de68368ce22e379ddb8352d12eb597c179c7089c6388542909876c69ee377b14054e7000000000000000000000000000000000acc52d0fca02c3228cd2e5202c4eda297b8227bf4e64308226bc487e5b64738efa4c07a3738397f90251ea9a1a9da29000000000000000000000000000000000b85b853826a28777a5767d5b1966ce12fa8999ceff5d6deab5c947fd19d19de9c103bb920bad615186d132ec22187320000000000000000000000000000000006b5a83827dc7b3580579ab7976a70ee160b712580919b6f5d4e180165e50f5a1698fa7cc63846eb1f5e6df955c3eefe0000000000000000000000000000000006c2957d8adc55931900145388583e5c2d5f6bd784e022702801c38534d2c92c6df9f95d022aa6d800e1e458eb7f313061529338195b665f1b80c4b95b7c3a26a7229884be1f4be9d49e1274a9ec3f810000000000000000000000000000000014e4c5991f9f2ee262019c1344a0843756157dc85aecb15718217a2fbe23fe0843992dcd3953ebe79acd85517acece0e00000000000000000000000000000000076a18fe710aca2875bc102f21782c9649f107684a4edcb0c4538f1a2890a2ae5b46a182d5470e620375327965b6d37700000000000000000000000000000000142a0fb19b28a034d326121458628356561e50cd3a471ee78bade0733597b8b90f647f5199d4b5b1ee6be4e1870bcd310000000000000000000000000000000018f8b5933848813cc2c1a0f079b095d565e7875ba6693eaa10967d496fb47257c9c674f301349dd8f2d22f8857f9d5ca44d740a72e6c8b5632314408022093618321c8c0a8cf2fcd9ebacbe43505a01c000000000000000000000000000000000db331d2b965dbc053b01a61e671d2ee6b04b072b6494e482f48f12221f23e3b1ccebf48046d92b4be2e4283c77f51380000000000000000000000000000000016704f3e1ce14f49df400592ce29627833ed1dbb91ae5f00779eef94fe9ab313c3e7c8da940085034e1a49158043599d000000000000000000000000000000001956d492f5764c6de0b8e9a716766c762620ebd3265a95b47a8ad2c0614c337692108800e22abbe321d77a6cc17f4b880000000000000000000000000000000017149865739d6aed0f2a4c3c71c2d02f8080d9339025b03f89a37a165fe6e5a4cbd489b5fc90bb2cc432e5baab213c8424872a78e340ccb077259aae65d6c448fe6bfb64daf4e2b6ecce2cc9525e35a700000000000000000000000000000000036804da102cce975f980ed5a69e0464241b5de87238f9892c77fc2b6e5ceb00d7a37a45b5520fce5f094f8b9510f49b00000000000000000000000000000000049da8b6c974f2d680a80d2007333f15702f1517d3dc11395662ca1db945c795bf64167840c4df0fda68a69e127b2d590000000000000000000000000000000000e94cc66f1ffb2112e37cbd5b4feb7d65032c2e57260504a42816aeac85648558f6997ef12028655103a8cb9de1297d000000000000000000000000000000000abf7703ddf6995d5c29124ba9a3f890854fe0622d547a4f24d6a60b036ec9e58f7ec2deca5a71e1fce2210cf810e2f901a1d84826bf78f493417a06a800d58dba688800026638316fcf9ae534436fc00000000000000000000000000000000008d22e456c643ce680f5ea14553a9c249a43d4f92d94135dfec85bc58967ec01135507bd8ac3954b5876c5bebcc1179800000000000000000000000000000000022029d4abec7fc9ab3bfddf2f462660bef7449c4093144d9b7d6f9e84f4f1c947855ca6e09bbb3bee4db096978ae0dd0000000000000000000000000000000014beddf6a3fbcd621e2a592e1c87952ed277163ebf390896f7c668944d6e0a026d3df74b0fc877ed560527a80b981d1e000000000000000000000000000000001414af918645ce0d4d1f670333fedf286b01213408019e327d3cb9321f06fae311b598c2f78bb578e85692e6cb787a52c5a3268a8ab5a12214b266aaa4eb562aa05dd19575a7f3ba2d549a25f1900cb800000000000000000000000000000000129f1e25d96b8c879710a81b727b31d27ce9887c245bf908a3768f3606870ca6bfa70dbf5135819d36582d55f230e94c000000000000000000000000000000000e91eaa33e7cacce4e1d6d0fe905c72221b534a72cd51e1de79a25ef0c06ab454a849a241c023b0f82aa07de28e35869000000000000000000000000000000001379e390f2f0f3636312465469b532d876529d58dda8b024b6b81d242af47b5720af4360d5a3172ad80fd9fd8a14ba2d000000000000000000000000000000000775992d5a8ae0640af845fae03dd0b2197699f413f90f6130d21db0dab042324094b36acda26ed86c65821d2d8a29d9e62a7b00d2be967df04ef56121c95c8736efa95e1faa0196e1f4485da82b3c3c000000000000000000000000000000000f5420156358ddbabf31fcc94678866f899e38747e79dba8ae280704c4b199a03eb423ceed18b5cba7e7ce84583c84a0000000000000000000000000000000001127669ef3ba3785a859aa4e942e8fc3181f2703b0ece6ddbee8830d7ffbfe498794f1ca2e67c3ad39ebd33e838dbc5300000000000000000000000000000000138113386846310db8e21fb8bfe40035cd89e51736b491d5f2d3cf5672e6836c25f62eab80f25ab49d16dbb83796aa5d000000000000000000000000000000001711d74ef4995b473239a574fb8ea6edc6eb7a88793a093df4652da240d069c5bf9249b58e9b1e11f7d6619cdc28a5787a883bf845d1ed04e0664d814cf0b49cf8c3e8b8594ae5d2834c753851ed7803000000000000000000000000000000000d32ccc6598af8156f1c5b35e69e7c7f57f9fe18748510605a2a81b4ee09882bf3fb26abf50206cd57c77924ebeda8010000000000000000000000000000000009043d364e0637c60223f9a5db8c50e983746fdf4c9f7986d27f5f4f3a6df487592ea42078f14efcb3eb1b7e81d058eb000000000000000000000000000000000233495c4961e71cffc2abcde4007c0d587687aea905f3ac5758d0f8d9020197adb6f9d7b86a542b8efffb05dce997130000000000000000000000000000000015b084e773e66ab1459825b6e6dba055a96e4dc1d94ac0b640e906e0a9f12d2124a58537c458e6e1b571311b93acc26c0f474e8f4051c4e91124c14895fe9e2516b315d805b79013caf830524fce8880000000000000000000000000000000000e4b859c679a90c03ea4d4b0b3d38211f685db053aede0f7f359f712e1ae808185758546877502d57200da2c2137f37100000000000000000000000000000000173b24ca19436b51aae22838674c41c752536eada3197de6efc98303eceb3e6e8e47ee6679e61e3cb5c8c734c96c98720000000000000000000000000000000005232b8c97a4860a23999d6ed6d173d300ed50b77c7b3ceb4e8407d9d6877a6004e2f76c553bf458b7cfd8d1e6fd364e0000000000000000000000000000000018a115201e3f4eb308c16656b3ca0635e6284169cee3f28101903ce1cab0659c3d83a449918df6e58e8af2e001036b8d9b3a5790750825ab75ab7422f833c671b95c6c58619189db66a6215ce907381c000000000000000000000000000000000131232788aa3038a6b8a055a896af4f8129e3dd3397dfd90ce86b3e09a775e5b5e19f4387f4c02200a36bc2a1e09d98000000000000000000000000000000000eb8cc0455cbaae97dfd05c1246d3d5ee58c286d263184ae342f5c0ef432355a574bb9fb8ec67634f999b6d1419f2b6900000000000000000000000000000000188b8a85a6b255408f074b3cab66b95e0e1a1b5b8965034246dcc196f2bb84aca3a78907409826370bd65cd4c4d0bcf30000000000000000000000000000000009603984f6d9876e9c235621fa817efe45727fd8c4f76abb7b0796ae721701161b39ff7cab4c57850014e7f1750954ab6607a48ba3fa5c033a1ef90260ada14ee50c95e5167bf801ddbd3acb77c3b3880000000000000000000000000000000009003b42c08b5c7d3ee9f6abb96e08e6f537da25cd0cf7eb85a49067746c03566e133b54153380286ef5725db5b41058000000000000000000000000000000000f09b7b754c255e0e3b8435ade64d6960285759495659dfdb9b117806397baf8d3c87e30bee02c9e1b22fa3efcc58f300000000000000000000000000000000003582c08a8de4bbd20ebfa833517a75682618fba2702b6c71a4785f70dbdede4e86ad8e04aae1f50a6bb75842ab74aea000000000000000000000000000000000ec013f22e64a4d4fb6f964e8319feb1ddbcfb71329186545d9b9d7f97d1f6a56c8aad03d20e9c30966ca932e1f2bc67030db724eadd2f487d31dd4354b5c0321a7983aead21759807bd893217c4d40500000000000000000000000000000000025809fb06c8a31f31ca5b4a5c795bc93355c78d9a2a4c1d707e32ff2a71d94cc1bf7b709cd5d6a183cb05fb6b5f360c00000000000000000000000000000000127bd8c9ee6388905ffe59bb0fec0e42b4aa44be74e5961dc2353e474baabfea86c41c6173db413ee28681a6bfd3ccbc00000000000000000000000000000000181f40dd8581b9adb2981dbcae27c7e906138569ff41a833ed3e6ee4fb0baccf2ccbe5b28ae2ff8e08c4f534116b58c40000000000000000000000000000000005cdd822cb47f35f31e0cbc26f6c957d51c6880369af94fd84daa1f1ca95e41e240b910f031585842fd2dfb170d618aa88e71d0be8fd050f6dbb8b2fb3ae2a9e593bef7a5163255aabeb07282e8793e30000000000000000000000000000000004a06984a3916820368076ab8cad6ffffded2cf1e67ac33f539ea8fc7a79580c1969e55b2a2fe3b31de912d6606c20780000000000000000000000000000000008a1152a581b6fad2a23aa8b0b51cbe523e701193207c896d08b99a672dc047498e565a568b79f8f9188767ba95212be0000000000000000000000000000000003539e82e5b88ef660b6593fdfd9591ec23e7109642f4aea0570f1f8f8e00822d2af277632ba74910459535b35ad47120000000000000000000000000000000015d3441f621c7e6922c489e474f80ebeefbef66cc59e4350b6f803e409034b7f498be2dedc97d902590fc1e296fe983c26989184bb87a586b8752733f9ce9ea06422c6a898f0f402cbcf760a7a21c95c000000000000000000000000000000000f775e13276c2e32dfde955009422557f332fb42dd9ccc3246d2b080e3ec44d910aa734478899698a9b04f6fb1a8f922000000000000000000000000000000000460ee4df6dd0184bcdae6d53cb66967c2213fa878a829c3196664f8d594ca6d60bb2a56f93bda3b0d2e6aac0a1a222d000000000000000000000000000000000fc9bf81d4cc80ba4e4df7307f976c2ec1ea2415df3c263cc970583824cd83703aa994daaa6e5c20450da2ba90a242830000000000000000000000000000000011f08ecbda9a192b232e8330ccbccb16a26bcf4791707f2cf52c2e11a8b3993221666563a772d82f4665804275b03b613d1dd9cc44b30a4623a4d14861688cb678bbb8b2f8ae3ba140f60e64c05514b100000000000000000000000000000000027fe7ca0fdf1cab9a52e304e55350195492abecce4289b0f1c02235412bb012803e7eb59e23c665ea86dd4f74c35c440000000000000000000000000000000011301ecfc78ada92885bcba8af75da6cbcb448e0c49511f3ea306f4ab944f5bc114e72f473cdadee2d0e84021905c5300000000000000000000000000000000010eea529fd3162ad7b49638a70f6f2c26a6844251b2c2f9f8ba54cd334914e84e5a1ba9c7b4e7a8b9cff1a909db78bc8000000000000000000000000000000000b8a6235a7310d52fc8050bcc484e6ecf299099e193f91bea9db31fae71fbd14978984a9e6de10939d0fbba96314b0a55639d80f55e24e05e3d943340e324f6738a593a915a6bddb40f01bf12f73daef", "Expected": "000000000000000000000000000000000de312093622aabdc7523cd72f568060f4236c7287d61c3372bf81d9bfebfda2795c3182d508f0268d8f445f6ea0a5f3000000000000000000000000000000000b027f117583406916a8f139d47227bbea28502ed0df91cf0841345435376c944a587c3b4bd60f8ae0be7c7bad1c8199000000000000000000000000000000000e9a7b96136b26b0044b11288d35969c17146241aa529e581a8fcf000c33fcfff2dfe1e55c0fb63f6032d0b6b0cf81180000000000000000000000000000000002a442e740ee390d87ec657fc218b76adad7f6a766cbe8f34f4824ecd1587deb3706af77a95c1d5f8e79eab1dc482c45", "Name": "matter_g2_multiexp_10", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f54bcf1637d03854cc2b785e52bde25de7e45308048ed8ec0169069c2124871782bd9d26471014d039c9aa022e1a99d00000000000000000000000000000000106698139b096a5a79d43321ea64adb783011f04e5779625c9f77e5c390b46ef0d249387e978e64529bba2db8d7aef2f000000000000000000000000000000001668d5261a4ba37d79c76f44eae9ce2aa3e216c5fbf6cd2e90c6a73cebd8b59600303afce70de3e83a08c20de4609b100000000000000000000000000000000004b1b122cb55e688f8297913b84d466c6f3d99c09f4b039660238c8bcd0b7f6977851a6ea4b1deb01346db06d75180c142fe1e5b3c0245e5cfaa1ee8dd8ccc4ea8878ce2272d152fd8b24032297ac01800000000000000000000000000000000192a28dbc40d5ceee4d33b5c2778cacf8c3ed7d3227e7ea0d6fbaa7cd4a81134b63415f4f1960656b1fed15023ce3a4400000000000000000000000000000000138f296c45594a930b949756d0ae14dc9a720bb2bd9e93c7895268121a086a9d55c10135962a172c02da1eabfcb8caa20000000000000000000000000000000001605ef8182fa13a09a6b7661472296af2b0fdcfd7b051e7cf1d9e6d7c7f4ad9521d7732733399bfd5d09a088f25d215000000000000000000000000000000001928f2e5d47d7273e035114cbdeabaca724409a56056b4e95a4ca3b2222716b3a5368da3ed406d73f43e9571d1e04902253bdc5565b6ebc219a75ab74dc5ffd304c94e67160389f87111899ac07a71b70000000000000000000000000000000009b35f132a903579d82cae6a321c1ec7fb0281c3e82e9af05c3b2830ecb4a941da5b1637c1bf0fe9a39fcc9ceb0d09d8000000000000000000000000000000000eef9c0846064c866ae07b3709091b8bd48bb6b20f995b44fb49e030b5cb6d78b7f8201704b53697190a5e36e9a4541c000000000000000000000000000000000a98a5d0d5640d6399a3580036f0e5cd693a7cfaa26438a00767d5ffc0777b83c516316d9cd4597cf8601544038f4d9a000000000000000000000000000000000e59541068a62f105a0d26a5f79fa5fa8b41b2211f1fe674d84dd853663962d64a7f70e785b51ac3cc07267c73400fe6acbf64f93f6f85805517ddf0358ecfea1fd58a3666b8dd9d3773a28590fb8a13000000000000000000000000000000000157f58b1c7152a7f931bccd9a79073967ec28855a6d74fb8727f59c5e3728fbf07a5032dccb28eb8d8b24229f2dc1880000000000000000000000000000000019f41bbbb853edc1fe3ee82f901e613107dd4ba1d880284ee95a2c4cfb2220ec1408f8bff14defe59775136bc75b4a1f0000000000000000000000000000000015538789157505a0798aa36fdd171e0bb14bdac75339b35805807c18bf9175d877360748f97a8570754af0e28e89df660000000000000000000000000000000010500aaa99216aa979acd66c5b0cea2a6a973f1cd10c412e823c61cb897bce54d783a6c0acee22cf9052166a4bb5adb8d9d3f97893eb4f14f21f68110f612a444815fbf2f76b8399ba6045c8a44270df000000000000000000000000000000000439729e13e6a9b5baafdaac65783ce79a5972791610a333224e61104d15c746d7cf8350e619f0f72cb73635f6795c5f00000000000000000000000000000000092e3c976a4a5424b09e50e6513a9e1f427356ce161e742be31f0e589e9ff862460d41281f0bb2d27b1837a70a5938fc000000000000000000000000000000000e0e51e92ac3cabfd999cd72b67cfc488e150b11b18f9a31b1c2338fd4f2c58937521b5a107752c342e67666b99fc42500000000000000000000000000000000023d8884aa3f556e98e006960293230ac966ad18f3f715e6ab31a6bf0872c04e6f115fb1608cd87ffb369ff31012a11705fb554531f53b8cef8d93566df80878baa96f92bb54aec19445980b1a1f6c34000000000000000000000000000000000be33bc145611afdbadc636e9d7cb7e3a9c92c32f6944a2b7b5f44c248a0754c174e3286ad307fcdb2ea02a3578aa588000000000000000000000000000000000457de1fa8642d302065319b1d32009c64e7d941fb43d1b3cf455248664b1db516379df87aee05a651c132eab8aaccb5000000000000000000000000000000000a711f3bf1bda60ca49271e8a3143330cf924328d3ac6f7a802c15be1d7413e300f398274f338e6bfd0225cd8ba25fff000000000000000000000000000000000a786c5c7b4f1701e292aaad9b2e47bb883409aae0c44ae813ba48f401f4e2146ea0b1d85f2ce862b6ac9ad3015d4b14d79ba2c485f0aa0e35212fd7fecf970258903bd2427c4c8b97c2c425ee1190990000000000000000000000000000000007d03697e195a6b714fc9785b49e54e219694250cf5fe77553434eeced15422de3985f8c736996c1763d4b9248a7a7e00000000000000000000000000000000015841a70a168d2f356a8ad929e2d1433b782351f4833c51b50f3a1af48a85468c2ec02699550d21bd919203df73abeeb00000000000000000000000000000000170902520080c46faae2bf35de396d56921bd0279fc889f0187adbabb9ae52b849269d8097d5b3f331dd5a817f9b2ff40000000000000000000000000000000016846a000f037eaf5953b7c4b477e441ca4fa738895aa24dfb0ef01a4c8fc21a318d40a9424e151380084578ca413b3344c7017258bb979cc9bb8acbd3a3e62eac7aa152db46cd7398ef07edd031e4f60000000000000000000000000000000001a50509bfb12040c0271b231c566d13510e6ba84448e59685f5bfbf5b008fdc64cd5e9456beabd23ac011b071e3a5fc0000000000000000000000000000000014a964c9faf1752170ca40cff1b9b4fa17f8d2b56a4c4bd7ffabb65798771cd624ba61ee43160e70731fb9b07af8ecc2000000000000000000000000000000001822ceaae7bd0a734f57b67e4834cfb00a6b415459d81c7d380a2e5b5c795eb1b6d63ddffb1131cdfdf0d76852c75a70000000000000000000000000000000000c5a1575b30e5470151ba055f577a0ea49cff869614c50194829e53a3e1a95847fa387a0f45d537cabef3a5925e61c432583e821328ae90a7db16b20525228e8d915bc8d46a642cb0a06dfb64168cf1c0000000000000000000000000000000018cab86a0d70fa30b4df3e05a91eef57f6505cbe4bb7284de56d420ef3bf315be9249eedfae92561c643bac2c92301ee00000000000000000000000000000000098ca598ccdffa9bc9d464d51b46ed8a8f22a87ef408cfa45fa7f78ae2dcb9f861d9d6a571f6fa702a71e783ee3395cb000000000000000000000000000000000c073c0a323c3051c302c0558463a5c030539d74b440fdcb16b42ad5ec097e10c16bd9a651d149dd719fb1fb865420a9000000000000000000000000000000000164e622bfb8ecd5eaf691abad9db38ccc64ff0fa1784d26db8c8fbebc929bc6d4dd471321e01233d55fb4a9661780b5506f22d323a740553d6107e651c192c1dc6e0a0161a82351f125f08c77e53fdb000000000000000000000000000000000fa48147388181e8d0033004118848c50c6425f2e5f91945a17abcff4d11928d298c092d60184e75e67c7ddb9eaa8255000000000000000000000000000000000c535bc54df050c1ba8d858a346d3a644e03fe24873b7dc3e23518d44b06fcb3f52b4be6f11d3b66f0180a0a95dddf680000000000000000000000000000000015e279a2893c205dadc8e1cdebd9c85454cd4b5d7537f984c8f9d451f8316620279357e218fef87339f1728fa317fad5000000000000000000000000000000000316e343ba68c8a762f4c8f2a5c20f16abc4a7a8365556c1625df832219670619b6dc70727e9bd9a64ed491dc22cb9d57f1bc0e1ebff8f935330c35573f9fc3b900606da9cca9a36b425977af47c7ca60000000000000000000000000000000011dc72100cdf676e41f21015fa7c57897da8260609467ffd38c17868a4dcd2bd5d4d72e89cd0db2de83618222ea3b5cd0000000000000000000000000000000007e074f73287faf304f618478566b91c8e191b229ab40743081342e676be09c2523681cf7ca6f7a396f8589a4ae18a6d000000000000000000000000000000000ff753a16c16bf0dd1de9fa9316694214aea6f99b81f66b6bffd58837c00d7f5632ed5f8f4cdf32ec59c29241ed5e28b000000000000000000000000000000000851e26675814612bcfa639fe567633e1960578a0c8d2e6568418f633eebc109e6c8af97e77bb28ddd47c6bba8a7ba724429b85fae16200da6eb8f62e95e027c24aa6ee2a145f6ef225139f29aaca29c0000000000000000000000000000000009eb2f172db0fe9ac0332381d929fa200a97047f6e732570d23fe27f5ea3013fdc52fd0b5ee74a4387af44647b75f956000000000000000000000000000000001355f8e1cf45443855f2d62dba0fe45b2bfc4e0d06aa7aec7e4f7f9c4e25b33d9c46a01c224517bac9a1390a9806ed4f00000000000000000000000000000000179d47a62a5c847f47341b1ba58f2c3b073c5282f925f57efed1fc43db04185955075255e4e4f6c209757ddae59101dd000000000000000000000000000000000ef5f74d4b13754ceb3b468879f1a8befb8bbbdbb143eceabf2dc8e68fe6cc8e1ea4f3eca1b23a1175c9f5f5c4c20d3454a852baf21df9f4ec8d711a48e6ffb36be8c09c8c60eaa090876236b2eae37a0000000000000000000000000000000005b70a4d5b91b85971aef26b1521e12904b7ad224f25e31ec6ef59856cc702043a3eb975bf21dc8e4fc55171a3865bbd0000000000000000000000000000000007cf7c3e75a837545b53ca3e175a275dc6fe42fb88678aad45910d150ea9c6c94eba615429540348bb2ba8efacbb20e60000000000000000000000000000000002eacb469f5f8ee6c9f557a6ddcc854e955c5b9203b4ca5dd2e097d3e021479e13629863eb5ff17db46a17d3b0227f58000000000000000000000000000000000905e66f3a051b304b110a8682169fa749ba0de7763d3af7edc3e40f2d22ce7b6aa00cd06d2c82d74f3a9709d955f44e13814a3c6386b19f7b93c2c4e0eb1568e8bd3f0012a1ae1357b127c33808aa0400000000000000000000000000000000060ac9ce51426d360eff0d911d9f97a86494340bc5c5ba31ef146b55ad3633ec57a700f04b0cb9d4e91e13c2cc5e68a8000000000000000000000000000000000df205ed85e27c25ce27270384d7c3e58c4e0a9f214d74cddfbc7904eb3115e7bf204375df7558c3e65f7a81a942c5160000000000000000000000000000000007a220d42ca8906013479442d7204457b3ff37c9ee70d64f9f6858ba788b7fc13b71d33ad527c6fc673ad8940b0f01cc000000000000000000000000000000000ad481ef549de13b174d82fe88fa57b7e31ecd8999bcdb0c7a8735ab619a13b1e684b9473f0c59c734567cc08c76ecd6aba0fb0440b2461ef64af6ec5f15db381714fce1da6e03ca962cfc94bba26d74000000000000000000000000000000000366f604228e2dff2348a462c56e0043037d1b415ffaf155e72c559d185c6b0a0d125585d060f159a8cdad959af631f5000000000000000000000000000000000f69e829a0995914ac122299d4424b4e2e120fa4913939d2f18f9d1496e7255d00ff0829c20521ef47bb0dee06c28dab000000000000000000000000000000000a3efb4a376281a60f5246d8fc10bc23cbb9cb71037f8f57271a9b01f5e0340a562f9acf0e9a95b8c65ab7a5cd95520a0000000000000000000000000000000004a4ec86e2b04bcb35c7840d85cd1dfaa88e17ffb557ac591640ed8e563cac891793b92e349a7903c6c1f88d26a01c88c01749cac36dbbdba5662687fd1ea5391ef9d0bbd24e05bb5904a20fa6a1e11e000000000000000000000000000000000f5bcc27c243ef65dfbfc0de6d431706ab20d6cf6408ca989a2bc1c52b78ab63de6f58b70bfcaf6878a2746f249b6b160000000000000000000000000000000016a4c9e8ad0634e8afa8606a1a7bd1d8cc0815dfc6906b6e6446e0ceddba4a4a2df979d27cd07b8982a12550bc700fce00000000000000000000000000000000051f8d972362caf0a8a39045bb468112f2e73afa392079f8a4dc4c3a3cbb8dc224c21b6633a5ffbad08796ba2f8df44b000000000000000000000000000000001825aeffda04705ded9c702ba30d24b9fe8eb7cb106ee5d4e4ba029dcb57bc42c74e74e92ef8360cf130590b838645429680fbd6e6c7b1b14b000d3d18bf93242c74662ef108d711d85d8d442e415ffd", "Expected": "000000000000000000000000000000000d0ab61b29ddea1aee0ca4e81b5369f37cf45be383f64ba0b1a5a74b790d7264016ee671959444c94b8e6291c5158ea90000000000000000000000000000000000152bf3709c56b3add8e3396d17abcfebbcfeb230529ea8144d6a120a0a6aa83cb284e40ffb9fd9a96f8a2f7244212400000000000000000000000000000000041f516a7cb2a7137746d028b0739c79ffd8f7535f20ba3728ede32504fe058baaf684cc7677967aa46777818b1fb6630000000000000000000000000000000009f1035729c55cf6ee090983a54d8c0574bf96342901f471a2e5380f11f235a075b0e157c38c456b6eeeaa10b87d3afe", "Name": "matter_g2_multiexp_11", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011ada4731ae7df493e405383603a8d79ef77f3fd14fe7b8bd9d2afe068998cb712e84927d5e6ea6e94d7f10270fd193b0000000000000000000000000000000008a14eddf88826dc3be792a0c1f7395efdf91454cec7e26c89f6beda37b194b706dbdde8745129e821b6f4b4ea6118490000000000000000000000000000000011c29513e8a826e6b3eefaa20ad841605d04b813cca282fe02dca0f588b9a579b2195b0b080cb6d12c1a7881008117f8000000000000000000000000000000000689c67d05ca379367fec99439e3806f827218ffaae995bf38dd8e2919fb2e751f426525cc2c6ead3b9aff2e377fc99e1ddff10527bb64de6ee2e3ab4959ebef9e7a6964b7482f9fae396b2b9b0cff9e000000000000000000000000000000000dd683a8e4ad54b1a95826a3000750c6e3cb250ab5d6add63c21b182d736b220d917d4e70044ec7101c3bf8ac620e1dd000000000000000000000000000000000f3e411cc6800b304fda1373ffa60c7718e20bf3e2e5f9784a81b47e398888b366e1f04f48f5aa070a661b5e2148d4fa000000000000000000000000000000000b0f8d0b695e000158ba80881a9256ed9dda5a7f53b550bf3b5c67ab160060fcbf5ce07fe38253ce037abedf4c6f08d1000000000000000000000000000000000bb92d407c457e9ea7b9851770d2743758e162dc9cdff2dd54b8271c046f642729cd2f10576013adac84a46d38623b932943fa2957d267019309f4fe5b6725379d893dcc270ff7f35b3811ad1d8d12b100000000000000000000000000000000023e880685aa69b3480bf2b7f2aed1181e094322da9e79c9263d50a49ba4fca713740bdb55886fc81c81a51045b35139000000000000000000000000000000001707049fb8b7ad278be2949b9eae2e28bde9de1d9eb964eae582541c2d7a8afc4c1489624a0919047a167028b8c77e3c00000000000000000000000000000000062dbb2bfce2f67c32b87ec2fa01ebf7deddfcbeda2fcf0ef094b1be77b7411f657e745350b6d2da16fc83a96f6f20e500000000000000000000000000000000062daeba038c7bc379f56ac371745b91fdfd5b4cbbe50d9619bf1d077f3cde966f81f9b851ebd206f2609a780b6dbd681551a3c2d0391fd8dedade892e8e2171e652d2a9b52f2288451c55f77fac788a000000000000000000000000000000000b553826dd9e2252c9da74c2bf1bf850df3f9c37439859f93df3fbceb7cca4fd949dcaa7fff31c9e06f41e51ae0b30bc00000000000000000000000000000000187810711ea5911a437a62e2ca483983bf2535ff9301a1cfe1b4d41902ef689f8d86f817a2a7c77128e4ce1ef6b037d60000000000000000000000000000000010170cf5f2ce08211cfc41bf54cfaa16584f833f7b97b2f6bc436eecc56ef44463690ea1f5c8c2a8f69d93a25206282b0000000000000000000000000000000001e627a68dbab6b0d05c85e49b966a769461ec38c38fd94992839bd0d46e06410fa7a48d418d65a8285f7852e8af4b318eb2fa94a5c97c28d95008dd1fe60137b34c2e763292d1b86993c02790b8c91f0000000000000000000000000000000011ebe2edc3de58a57aa9ab4d6626d7b93235ed24efc3d75c1ecae376c00beffc5e89ec509d243f693d327f7a4551921f00000000000000000000000000000000088ca2fe0651e4d8f3958454640a58ea1cdd804bfd2700bb1bb8e26ac50f2d7fc8c292f94b0bccef5735c4548025735400000000000000000000000000000000154936de8932279cd39ae803a5d814864953f647a5334bad958222de765250e4bc847e02979689dc9cfe1993486b5750000000000000000000000000000000000c7ce07c9746c6d72dae11e243acbe12dc23423f870f3130b244eef34524d547fe0b2c4b704ecb6b2e6c32f5675ce67ff72ae1def6c988f9242bff0e683b8d2a5c1aecfd6ebb9442131ec5b5b825d0f600000000000000000000000000000000031ea855125d75321a2a86a93e72fb3869dede7531dbcc1cb07ea2a352f3c6cd913275d0d43ccc370f4539f668f205f50000000000000000000000000000000006c4cadb11361f164f5899c6b57c0c6d8af365d902f4575c9d2d14dfd880501ce9ce218544b44bf07f0f04ed68e8f315000000000000000000000000000000000131332638026fd25b1a849c984f9dedd71e64fb52a61968666ba80238673077ac00b9e09817426ceac8c308f475303c000000000000000000000000000000000c7634af796e7aea4d4d83c9972fc822dad951d2473210ad82706ae0aa023ea85c1c467bdda68881094ad2a4f54cb33f331451748146f0564ab0d91b09db87e8a6ba8b14f8329bc041911616195f9fc0000000000000000000000000000000000fcdbf0083065e13deee2020bb6e47cb9e482df3768ce569f1f7c0e1c6083c97d9f08444e67857c2dce40e4a7b8d50cf00000000000000000000000000000000010f246e8ffccc2e752049f638617e122773a6f10220cdcc0603d24f1a94ca7c100f8ee2d9bc7c0a931fa0385eee456f000000000000000000000000000000000f8b68941df75cac3d4b6b3bee43fb357c8f4e56309d8509fdc62620a085d7ee58f52c7dff28525a449cabfd3b7ab3dc00000000000000000000000000000000019f934ef0c7c40786b073d38cb3e4623544cad59cb63440d4a6e76944d491f6b982e3a5e84124996634687d4618418316d298bf591bd927aee24a37c5ba508c3bc121f5150fcd1a70c1f27a79da7d73000000000000000000000000000000000c0208c1f3653fb3a5e2acbbb42f2598b22db1a714d616ee6bb501c3338e80db34d517c7086d43ddc77e0134dc5a4f290000000000000000000000000000000000a528245342e44e36f8e02e7259749e63ecfb38cb0609075e871701f2b3bb0765277b78d28cc3ecb7aa8c9e3b27eaf10000000000000000000000000000000010446583a905864064400f9ef168a122d179d46a058525c9be8a65a5d2ac5e967d51185d4964f81a5571123717210d050000000000000000000000000000000017da91a1d0358271b11a0aa524341ba1ee8c31bed15efc4c9183d60c6e1842ec4383070a09914fda991a63d55efa8f2156be810c3fa86e35bc935fc2b27971c9c41d03c8ab7b6c8869db90b6e0986ef400000000000000000000000000000000176c64efbfc9958b9c8e71b55e9fdf525d4e5a0265ff01ba95bcd5c6093bd063726f8e277d00b138fa4d8c8f80afc4e200000000000000000000000000000000183eaa6c3c605828852ab5e8a9432bcb87411dd18d574cc2491f1a280e7a267ff9ccc80b06c22e95107a72f22ba2fafc0000000000000000000000000000000013319d3a8564ffcd6fc7accdded740127ef205e8299b390d21e96b2609cbb463569c878f36191d43927868b06dcb912b0000000000000000000000000000000000fbde0ad8e89f5458007ef6ba0f01d0aba04217e06745a5571eedaf544443150f59117b56937f533b4974e5d57c41cbaea4445926775a6baffb4dbeb249dfe3b3e0c29f2a579927f540d8f6451553ef000000000000000000000000000000000c044a5116e175ca1d1ae59d400de24e4f47132251b4b3dccdf458623c36b4d3d83abc644a2247ac4d0e3f195d12e7b000000000000000000000000000000000048dff6bf65f158b19b992167ff8adb5c858a154bd68bf0c84e41351bf47a8f870cc735d1be5d9afc62bbcda2fcdb1c20000000000000000000000000000000008c5539746d2610eea22e79b3fe5b33a47fd3bf9991d34c6f9d824a46458480b735c0051d7b4e4909fdb1f2a1a4e4b3a000000000000000000000000000000001936558ac97acd903a29d07c4aea399227ea13fd6dea820813c5519412c157e1a477fcfbab60a787c6b3834eac4522889ee0e58d08779add74b68dd75e82df172b719cb5a772b0bbb34d3401b9f212ea0000000000000000000000000000000017d978d60fc89b0429c1a6424231fe9274cedad5d78d9c4ac5aa2dd5e70e8238a0bb1904bb4b6ee5de5cd1ac514c62a8000000000000000000000000000000000d4ce85a95dbc40f405f4e7ebf9121cdcd22766737c39618ad0fb3e10a6e53be1faceaa96073b2a877ab808483ec9b6f0000000000000000000000000000000016c61599ae4da787fa6db233fc28f5c56f7133d403901800ab5fa19d058fb27ecb34ca2e56ffa7628ed004c9e62092700000000000000000000000000000000001e64e4adfdafbb423b1b9f8973738c690713911f68f658d234e57dc35b9554e0f7ba345dd7920b429a12b9c74775222773d07cb9d20744a2c3ac88082a8d6606acdc892666753793a2b8bb81116cc6d000000000000000000000000000000000908ebe27a1bdf0b9e56325c00ea3814527005793ea97eafec541c01cf2d7c909d2521a5fd475589a31e297cecfd5e7000000000000000000000000000000000017e3c40c60cd369ce5a90f6c4aff14896cf73fe06432e71940bd8086e36c2353d6bf9dd414bcf92889887e2d49fbbf5000000000000000000000000000000000ded856e5b2b139487b3816351584f06582a933af2bd4573a89aab0a41af01ec1cb928a7d8035228302032d399bc7caa000000000000000000000000000000000833b77c5d5c98ad95a144c0f167fd3bd62b03f4ad721561ed1d84c7137dcb19521f781bdd3ddc22afdd52c75146e101f6bb1445e9146b117bd0c95b009fba670a5391874dd314cefc884bdb0a4eba680000000000000000000000000000000005c6f28c5ebd981fff3aacd70eb18f134bffdc8507d1a3aa153e5787b68fba7f4a94c43045d2676aaa992754783ae87800000000000000000000000000000000148ff39e8062bd488accfead42a684f781c4ee579af6204b5b8dabad9022b029139b1f3670fc270710ced9a53253850c000000000000000000000000000000000ff50eca1a92f123e2534b3289f37ffd5d4e05f7678017ac20e35c2deca054dbe376c5529cddb5e58973f5c60914f251000000000000000000000000000000000b58298ba9496fe32891f4c1cff25395ac5a447205cedaadda4dcb929260ee55781916ef5e4e39793fa2831142111226d4158de4e23d793ba77c24a70f0ad07314927fff34361b0d74b25e8922512d7a00000000000000000000000000000000184d156f881f7d10d2f196b7599db85ee826c9c95383978ed68918756f642a2ed1c951503251b0778dcc39598d79fc8a000000000000000000000000000000000952168761380e8fc90a4966e94b8d2b88a784f6e607c99d9af1aa902506f59d6879153339fdb7b8acda178b9bce4ef90000000000000000000000000000000009997621d4e17c76b7798ef2f99d3c0a7519cce278cf718789cd8227b2b1459af7fbbc93078aa0aa361167b1d1c9363600000000000000000000000000000000005369eb3a77d2e26f9907a2d930f39dbb87634346cf10525733aac8ea10eb918d4043d2a05ff8e80b9c69a670e17f15c629ef41d5a2ce49fd81930406f19e760a47074e159ce372dd67e7ea46ad706b0000000000000000000000000000000019bdb390c66f7d28cfaa91bcb34c5c55bf93a9f2345ea396f18ed33ff2221a39cf68c5514fe091f7882e82470efb1fee0000000000000000000000000000000002d0b48d2c0377b0dffca247b7625f9901f86e2161626b4154bc25d6c643a48e9addd260298bedaa80e42caa5b9fc5b10000000000000000000000000000000018a2b0a760652e546eeb42e857ca48f59741eed91822c17692e9c41358b213c82537c9c6898713a13a241cca627a7dc400000000000000000000000000000000079c02f41fca45a56d9d8e305141b4fe8f98d102197e7864065d342e6b07f65b62632e0c12660f37de4d698c0df3d0f3c718651715ab786b4855092ed21be41b499b7824d0bcf68ad31b31ee4cb730d5000000000000000000000000000000000c0448fd4ebe9b5615653336fe0a618fa281b0fd7d72a8f956a5fde84f7d356b6be853bf823436bc0b61a603636db9ef000000000000000000000000000000000dc4f2b4d810c4290e263098576cac393fce137cc901b3be23507cecbda7d86d18022cf8e1a7df4b1298520ae5c9314c000000000000000000000000000000000a39413967b558dd8a6b2bed972687d984fb9abd0662a266680f8c90f1897e2aca1ba37b41d7d3fd47406bc5fa3c5b7f0000000000000000000000000000000000550fcbe5bb75afdd8d5f387798a8e83a8dbb6da4918c24eb2e5d2d8acd3512f6649a4ac9c8d3e6794e6f4f8a87687bc685a2872c4980518fe60c61e2276ef53c007166f7eceb355b4cd533f42c00b7", "Expected": "000000000000000000000000000000001654e242002aafa89c6fdb9e8fe2c197ad2f8aad11868568dd39d68ca35919f94308a80303655bc83fd130de6f9723a900000000000000000000000000000000062b5a064840a5a28b4991ae949f9508586447ad5e8c463593503c0e5857c5233b7ce7ac03e555c2675f2e320e8cee6a0000000000000000000000000000000017d65fbd7caa69629f66be8b201f53baee5ef2957a3c04fe384ae82959105342b52483eba6bcc1442763c677f515f6cf0000000000000000000000000000000002ef8f8ed1114cc9d299e59003c61d62edf8971d65b1b621779bd7b270c4123eb629f56dfa2e2723501588a0caf1847c", "Name": "matter_g2_multiexp_12", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001392409b92282bccbdaa0268e1173e60911754eb3cdc28a52e93f4d82ec99026f314dfdc59b39a4f988100f9c30cbd1e0000000000000000000000000000000016b3c555d5c196551ba715c6c334a668bcae80f5a17f038038d35dce34843f79968a90e2102f0faa22a93d3240b58d490000000000000000000000000000000002daf83727fdf45dcc1a15adf47de3f8a1724cf4d34116f52106a9e6b22dc24a288e89b940cc57e5a6bb87ee70f680a5000000000000000000000000000000000446009fa3555e4a056a820efa7da52117c15eb105af57985d8e9b33b0b22fde6aef9bad30480c2b8c1246519795f61fc067ecd54e9ef59996493f846ecca63bbd7ec28da586f0b8d41bfdc6d97a35cb00000000000000000000000000000000000372ead514d53007690843484c966361661816e0d3949b868176d7a9bea42064f49113a74f2572a6dca7afa0642fa5000000000000000000000000000000001199d3ea66fad87074e62a0b77d3fb962db17dd948f30c38f5beb0e44e1cd11d9172b878128e9a64a08394f13cd786f60000000000000000000000000000000018b7db157bb326ee2f72d4df2b1e0ddf0a90401ccfca1d4ffd6379c62acf5d6e4176a23ded2f81653038d56d848b4fbb000000000000000000000000000000000a932cc9740812c8bde33b68d94220690e0f55618b7e51d3e3fc29d0cb9a8d42b8f8e1efbba5984c3c1007c9a80fae408b5112baca5e0f2bfb885c5041189612918d203a117d886bcb3b27df7e64d17d0000000000000000000000000000000015798d10386f6d24caed3859875be5fb1a43ac753f725f28da6b3583bd9c0e404d36265c2305d7d194e2ad84bfd2bafe000000000000000000000000000000000ef2ea5f3b6e03e3c9693d6db60019f2efa4ea586bdb7623f03bd035c603e8996ef2ea7cf745aa31f60679ca04f93875000000000000000000000000000000001792a66785a3087a80c4b8652c1e4db8f602cf75c1a6955f480a977f92ea262965dad84061f6045177c831dc4a3bf8400000000000000000000000000000000006ea3862318974d6347639ec0d70afe748f4edf32b9e437fd98f38eaf72168a153cac180c2d67bac8a358e3a4d57a2b32db7ad39ec8129e9e9206bd46cec6a8ad3362ade1beaa97befe148f6c67a9c2b00000000000000000000000000000000000974da7500df70d888d5876e7c61bfffcdf830b49bdd40edf65a2ff476e9add35eaf9451a2166e9781805192ffd7ac000000000000000000000000000000000cb2e7152b5b40758b18caea356dd8e095f400282881207c4b79d10d741756e526be261b98b726d5cefb668dcf73a0a00000000000000000000000000000000014aeebb995d464f4d77bbb72f15d9078936b5ab68eb8022bdd97d050576dbe46e6010eb72250c8ccf2a59138efb38f9d000000000000000000000000000000000cf7162768e8eb50e21d3c0a076c7bac4920c70f334336037fb40e57e0efa91eb025356ac3f0988a6b127408a02eb53fe2400a11d9a67041824b97a96f0ea9da8848e7990373655d76e8bd4eb84df5dc000000000000000000000000000000000b1d6214796b4775c2b50e634a549ed104e6ebc0e032967b17eece6cf88c93aac23059f263faf3c3f38463270320135c0000000000000000000000000000000013ffa3894a36226664ff53ba9256d39c6312303f5cbda6847b4f68c56134b7d731e74bd711014fe374f909a081a7d02a000000000000000000000000000000000ae4590cdcb1367392635d0f8dc6b9557abd16290fd1abca6da354646d8585a7c9432978dc616e5fc38cd71d55f139c200000000000000000000000000000000124a7b5574ef52359b4beabcc56d3286db8c8fe4ca4718f75da28d89a8a95efb878c18b48360dbcb6fb50a9f18f0d559aa2d17c409ade92566ddb3913806723d41067540a36a9c283bdacb273c5b258a00000000000000000000000000000000148ab0e847ecac963f0156da025dbc52e765cd8827fd55ba2969da6775649529226ab13ab8537ad0b89e8f1ebc8648ea000000000000000000000000000000001395b1adb6a56b91c3621a4ac5886a7b13ec00f1c74d5317eb74a766eae655e09e269ec48cdf740abc38f4d6fe52dd0f000000000000000000000000000000000f70f77f07ef2909033665bc05cfeea7df6ed55f2f0b1b87d9f247b6c07c7e22f516840efe68005c3953a2702573a9b400000000000000000000000000000000166a334a711416cab180cc498308487b281711f2d1b832c410ebb4c591af54b154fc8c8d7ac9a49a241f7a3840acbc75e5e3d21862b64e09a0893ece646de60cd66aa483662125ffabc46cc52f1cdefa0000000000000000000000000000000008c19bcbdc2ef26a30dd88f3e35dc7fbb3c81c0224cbcd6b12c90883f3973bd7089636f997e5f213fbdcb79514c551c600000000000000000000000000000000058620cba8ed5b738167e809cf71392aadfe8f384a4cf397d10f674cfa914e9e02bb1518e42f16806214fec52d880f6100000000000000000000000000000000048ac1120d26e4173bb33a58c0ce86329cdbe9df6a6f268c8d5ee4f1d6110f9d81cd50c46256198a2462d50be3e781270000000000000000000000000000000010af13ba791d554720f5075d46d03b55c0c1dccd679cef5a7d439ae868d3ff2780cc3ab151feb72b8b92905a205e630449510ab1b7850badf58cacad67fe47135f6524f0d160f3013e8ff1c881e469e40000000000000000000000000000000005c30a126c94b87c54270d0f23a486c3b36a8b491bbd805ae0d5f2bea818a87ff5aaed2d5e6317b786ab5a23f1cb48da000000000000000000000000000000000eb2d4663eca7f8433f10e84984781a57fffcb8f9535518721521ddfc7a4958778915ea3c57bef399a453b8ebc10befb00000000000000000000000000000000161947f57d97a858e5b3e918dbb22dbf28629e51e81335a9bf105d0fd660ef80087c8d69d8db9841cc69fbb5e7f81487000000000000000000000000000000000c52b6a559928fe4ad984a0569c081f3f71eed3d5b0d3c14d1a23afa45594e0fbd94143348390bee178720fc603145ab713aa69664a8c721cefa7d6dd3fe9f92432b4d350621d5297805fcabb21ff8c600000000000000000000000000000000071aa47d392e1a7787b37c52acedbb4632d5549fc11b79919bab7d22f1bbf1c3a239df622b8824b07f6e35e627283b8500000000000000000000000000000000198e72e05388021919dfc1b2a58ca72bf7655cc6c9b62abe3b45cc782ccfd4a2334780e451b8a6b7c311887036813fe4000000000000000000000000000000000e20cbedbafd96c42612e146debae48c7fab4846b20ad0848c4c42c6aa0603e72f94dfc938ed9e3a9886d221ccbdef70000000000000000000000000000000000c861d1878e63e313e672bebdadd3fdbb691cff5fecbc24da895febce2eef0a3c774a8a9d751498e4fc8e2b71daeb40dc040d8bf0a787346560fa3b100b2dd9adb3f7ee716b8103abdd9609363345ae40000000000000000000000000000000005f7cd2205fa2e17fb9896efe3fbe110e1fa59db1ae5f8d6b5f4510abb4da867933d4fe3caaadc4457dcbb35f1b9c62b00000000000000000000000000000000126f2ef6022a7211fa865c1dbdd5b84d96cddff424b06647acc462408f2d31f34ce898d76e1e124db7c39e08dab0bff6000000000000000000000000000000000987f916ad6f718695f3c40703c59ca93eba38931b45d7c33c64c9f75556f075b744dfff8a5f21489b3db6c3846ba09e0000000000000000000000000000000013011b8c72f3853738e22957f742b05ec428ab0da28901800f787b7c3678449acd0359fee93c40c69623aa4acfc0a81017b811aeac4fb7d91abc655f8a4392176f9060346073c957ef903e25d10935a00000000000000000000000000000000014b88c0586fa18333ab11a79acab8e12c6257f82a4ed16d929768a60a3a5d780a22101c32ea9b0099aa2816f18a0351a000000000000000000000000000000000de0fde69efd2cea7ae08d6d2443883002e0b4e11da253222429f6ecc67ba8d282eee84d7f46e0ad00b039a2c2ad226f000000000000000000000000000000000aedfa0a5a8b7577dcc1094469233f8b07e6fc32af26841894d498d70c6a9a046ad636086def948d21e39833c5b6c5a70000000000000000000000000000000010ec6aa0efba4995582585bb67f997f60741648156324696312d17656baf6aeb3e2db0d1a272912fab2fe81d139e971cbd1f096026159218836a46b9801a4f0c43189324d20220aca777b826eaf2575200000000000000000000000000000000004a847c06abc8ae7ce6e6ff0ab856889dd3e9697a75e3cd4d2af9e06d4c2fc48c0562289348ff52f4d9855ad03d83aa00000000000000000000000000000000075673bc79bafa9a64de6bb0e9dd9fa29cdc9c82e90a7348593eec673cbbf22b1eca436ecf767d45852ed888a3f23949000000000000000000000000000000000f3f8543d1e667404b4564dddba4d7c11d13881fcd8ad774c8eab8fc599f55147c353cd6e163cd7b9d5da55ebc13c2e800000000000000000000000000000000069edec7e7d26962d88a89dfad213daa36046bb2851e5d67adbaa227220f29f83ea67cd3747e6724f148dac28308604cf221dedfc21098ff9a9507e493d0fdb1efa6029fcdab23a016515078c76f7627000000000000000000000000000000000c945e83822896974116663d3e2769f3df5a70d55b8392c1f6966e330951f3cc5688742d4588648a6988b928b9fe00100000000000000000000000000000000003e94b7ff7c71d633ce69bb44d0ba1bfc7c27a5ee618e703aef81a45ad61771a2fa8e3dadddf7c8038f1f65ad7513801000000000000000000000000000000001727d768c1b51066d2af87a9da3e24ea2a75b0f75b8ece70727f9f54ab77d841e7ae01c9c0760f4186d02a28d6f8ddfb0000000000000000000000000000000000a273f9395cd49b646e90fd2526d5c93fd46c7366b715546529c9edf5cb3d274c9947c21a03add3e7b20612636a6745ba5b30d1397bf28100f108b84e05107ddd6cae2e82f1973ce187e8c3a7d02f3e000000000000000000000000000000000c996c16a16879bd3194ac366bbd11b5863123ce6fdabeafe56407600e5d49c92ba68ac1256e1515dc9256de14ac26de0000000000000000000000000000000018c584d8a4f14900b2fee70b50b700199ec2372b731dd1380f42ec7fd3d01f0c9a007554059b85946c1c4f4e2fc504ad00000000000000000000000000000000073d6c7d671762e5398e4c9d57f6b68c3d97dfe0d01783f124256fac236f03b774db58b79cb4d5558e1ebf18bb9e19680000000000000000000000000000000008eb2b95e17fdda916b08ff2819cecd2eb031f41c8299b308339b7d9836382ced75e8eb1514a70356882d3a43227a9bc19aadc83d1db9140af303c0492d2b9bb9e2b53ddb62cd2132bdf8ef62aaed683000000000000000000000000000000001029fc28cd502caf3ea3619f6fd04bf457e6a452b5cad680ec2d4f8222a5ac2daa92b880bda76016973494e605ab28c60000000000000000000000000000000002c672c7571b5d8e99de6e47e0a2eb71c6d9bd12baf2b083e6f88598b32c4644d1486aef582c5936e622058bb141db1700000000000000000000000000000000033cda383a77d5b3adbb0809e834993c56717f81f8c66ad2d97f2b298d5a46f7b29a74d35da09271b7053a05af096393000000000000000000000000000000000132da041c6e3e1d68bbd2223f8531eabde8e180b36b2cd0ed4fca248f255cf3eeccdc5f61e1c581ce54edcfb2b73e0787eb6fc40b00246910626ab66bfbac96ea09242d1d70496466e4d681942050700000000000000000000000000000000009721f22bc49f68d703a4dfccc3bae791caaf0d73892bafa6e9da465ddaf0fb1a069ffdd55306acff2407da64c1c5a0200000000000000000000000000000000056c0a4804a19aeaf1b4fe52064e43de8e5d41a8d77de054e2cfdff078eaf468d123d7317818d1bad1bf3469c0070b680000000000000000000000000000000007f1f318aed043d9ad7bdd53eb6a8c3167240fca75925b04795210700463c93a66ed64851195df1bafbbe4227d7db5ff0000000000000000000000000000000007b8945e258311e7672e842b91b540fec9ef4a79296956a5cba3749c0ad95ed83d7b0b48384ffb3188459e997b86695d3bb5926f36808c0024ea7388998b4cc8c6c48d32917f6456b39d514143c6eded", "Expected": "00000000000000000000000000000000086a1ab4c19c27f70aa422e8292752c50b365d6fe3eba21e8f2ed51f283df0446020834ad27c18b5c7285d1156049bef0000000000000000000000000000000007288f40fde69bd350ce1f4d0f68e645f42de319cc032250b76fe4fa305341e244e5b2366751d5311105e3ccd30e701c0000000000000000000000000000000011d0c487c4eceaeac009b694931f8eafaf8eecd6028f14a4de33d2940bbb747025eecd509564721b50b7186910f81949000000000000000000000000000000000366f0c901fb859b4bae006fbcc9ec7e456eedc7366c899f68090fbd457c37b03ab99ae982872c7888b65c1a056c134c", "Name": "matter_g2_multiexp_13", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000072f3f03bb09ca30239dd8302b05e0d9dc4e43ea33e865864a82578c35eafcf6868bf0cd9431b92b76f00990b780ffa400000000000000000000000000000000170b76cfb7944ea5ea055aeedaface3e8f0fa4d0ff657fb9d5311f3af6e736da84a5e2bef5188e20f76fb42591267fd9000000000000000000000000000000000d85300009165a8da9cb8e590f7f8d372e4264df150b1551185c80e49dbedaaf872ef69c5763fc3713d0c087c89f21050000000000000000000000000000000003ba59b682174ee61630df95c8e2b1c48ffc8f7f8508c21f3bbe8f7bb3266521fcc06c8f90fe5126d872707872db6d59f44b0204792359895b448bfe6ffaedc14d54a6d72be7a49718c0a933807a399d0000000000000000000000000000000004e8f16480c2f080a13b9f2b66e6480132d76c4ef76e8bac995a8e33280073ed5610865260e154b32f75f527d89620b3000000000000000000000000000000000f9ca48d732a8055d22fbebf3d2bc1e1c9c815c184f594ad2337731709317ea6a205478ba05ee9271d35a19dcad4db5b00000000000000000000000000000000078013b9290284e7ad528a1bb9a2a64b3ef43964c7226ddff8ca16ab17b4a2e8a2a7d921ba924a718587954f586a954800000000000000000000000000000000004aa76bb1122116cc0c04d65265d8652f08b411632a732a9e66d7932801b77c4ad398d582e446968f7f4966e9167894de25977e7426cd5652559626ff8b195ab7ec679de987a6a22a6a0e366759dea000000000000000000000000000000000145de5d101498bfc7c57830eea2931663ca1165ec85b77654c866b04ba6a28bfe710c1aac9876a68cc6ca119708eaf0500000000000000000000000000000000096f9df9d5723e8379f2d09c76a3fd059be47d2c2ed8905d333b2464f72153c5f50b6345980626358839ac691c26c967000000000000000000000000000000001788ffa765c19758da6eb6c38e793190c64d4a7b116576f6827fc090b0f65304988f6a95cf4397f82b7691fc43960ee8000000000000000000000000000000000746e040d7aafdb06a31ba3d7b590dd28f0678badc261a93dc7bd9a605047ec67ba86b2b6dd72637a449872674d6b5982e7ae497b44f531fe203a599622954804c06d5348dc17eb1537e750006584b21000000000000000000000000000000000d8f3cfe1cbd2629f3899313cff16ca3d8f964ec1cc0508341936a7b3b49240db1116b2c3de28f9bc45cdfacdb5fd98c000000000000000000000000000000000fa642ed31293e44211b34bb28bd5b389ae6d0510cdab46c89756f31795506fccbdacafdff21b0127e80557e5ba9afdd000000000000000000000000000000000715a8951cb358b0d8cc63377799a9a61ecc85dac795d726fe60e429d492c9ca843be2a2633c17f830f199335e5d7741000000000000000000000000000000000b88a23fdac7d35fc135b45d7565854bf010a75f072b32c57ca4d0979c111aadd84c71df6792dbdc8e975ecd46a15df2e073adfb5ab96730c53015a4ab6210a35a37b2331ff5123e00798c33e040a913000000000000000000000000000000001171be5820b5a19c045abea399f2b8ab9905d2aa367c6c8c0f84eac132d26150b759a9c029414f1c8f7e4880214446c200000000000000000000000000000000147f0877321f2709183f0b617a7c5ce898db508a3ced4148cc9f7af011fe8040e90885ce817aa956d9f5d19dd968f6220000000000000000000000000000000000acb005c11481b214a17e3cca02c2af266e4c8cd928e3c4e221d866e9f296a2e913bf34c4e051c7503a5e4e7cd7449900000000000000000000000000000000125f45d0af1c010cdf8438bff0f406007853e566fa646df40a581f65496197755eeebaf4f0f77e1e936f399dc4c6c020e6e752d40d411f1ee6e67f48109c9a059226b446601047a2189ab815a3fe13c40000000000000000000000000000000019cce3f872af5cc515ac4cd7825a5318ead5b464d50349909a70b415a8950206974ee0d4203f208d8e6d14690158f5720000000000000000000000000000000002e08e8accede11afe3e2d085f35c08d7d414c26a9caa992d5a090a43c9b0c0cc1471f3693f9d342a973da65189c888b0000000000000000000000000000000008a984ad2ca60c492cff2e95d541d71e33b269b10d3df107c0513dad5af511c51806068da6cc7226df1cf5e5a2fbe707000000000000000000000000000000000fcd3ad75bb0a5c046cf83be3d973bb3685bc717d7b8262fb8205935db6e632472496907f7c965fc6b52042ce69999f9e657fda33cf4ed1aa89dbc19d58fbe3043acb5795dfb8c0cb97620f16f8f24350000000000000000000000000000000014ccaf7594d8ff6157f9439ba63480d3d07f44e62a86caaea510d0ec456cd8c6c4b42cf9e38713213eb4942ed45df2ca0000000000000000000000000000000015c2061c532cda006addd2fd6ebbae458197d55fb336f75ca7decc05dc6d421a65495b71ed11874aaf24a0ec13a7c65000000000000000000000000000000000101f953aed7f23b5b6208032f05b818e0147079b7764aa3134dd9e4a316bbef0309ac378ca3cff3bdeab9ca56cb78e60000000000000000000000000000000000c76a2bc721a4d3ead95af79ec24be9b7624bc80d7debc07e388e52ec621082b9a69f48d157b168af4aa73629697f784c73458e18d6f832f362dec7c49140e6523ead045131a1b719b0c836c1ef13a79000000000000000000000000000000000761832bb5b530b80c668234ab5996bdc225c0c696ea07dcc61c330320404827ada9d58d658e230fcb39a96b339b830e0000000000000000000000000000000001198b85418421d96ebfbf436193b411a3a89c206d006291bd23254ed5fe12ccdad15725a34d962005c0ae60e202bb86000000000000000000000000000000000c1d7ab83b1d2ad57a407e248492773a357c06b83c16c6ce1490e84bc4a3cbae395f160181d2bcca3edc34b764754ab0000000000000000000000000000000000f1e9f0cf96d7671763739b6c37fd442f0e816c49d9c8e001d322397e9d6741dbf8769ef9eb83d08ab024294e279a02838cb0a2b191f538b30187dc730a8c665bbfce8186883500baaa6c3242a0d147400000000000000000000000000000000063049bc3282934e29f3bb3dee432bdad6193a5d2247270e88887cac565f4b986e1b3b2af5387cfca64f0d50bc0ee1640000000000000000000000000000000019f0f05fc7f8bf2f0b8ed375690b53b6dafd0a07c49fa55d36e040798334700a3aafc4995bb90de9c4dc0e077ee18b58000000000000000000000000000000000fbe702d148609dc8feb3ac11c5eac8e32a2f7221aa135cc33a585e9f4c97afa1658d8962fd96e26e0c4c1d5108229ef00000000000000000000000000000000061fe418d3b440e84728091a4996119b515118900f54a6f2da2ad5592f48ebc17bba50b59ecf435de3cb892a123ae9d18a27de64d41d13ab67c1f7b1a7390ab4dbba7d219dfeb31255f9401d5b3c62f80000000000000000000000000000000011e8ecf1e341f0146c59a79a8428bb01d2399d3f87d90d057f63e6cb9837432154d17975f70df175a016735caf85120a0000000000000000000000000000000002a5bd53e4f4c5b9682e1af1f7e09dd305e7342d1688f62885b5e59f173a9fc731cec481559ad693030004a5fbd90a9d000000000000000000000000000000000f9601f95e12bf05c35deb204558d44a60fd630c05f4060b7bd9ff943946e8eab507422afe00a3e7706b8ed013f712c20000000000000000000000000000000003bf6fecc0c7414a69c2b48e2c16e88d988ea8ae9d8b59017ecb89394732a20e4321cb5e4fb071aec7d2736220a4553780030798960729d63db70b8bc3c0030e80d9b8ae766e3330128557e6c34442f6000000000000000000000000000000000549f6464b657eac28f838c6a8bcfcb7a189d6b3b9712e19c1a23503ac209da5f2ad4df83acd505b0231f00eb88515c70000000000000000000000000000000001bf4a46dfdd70542e9d8cd6d6215174cba28f9adbff31c02482ca38205cb4afa2f7fd65ecf57b39e4ee5cee320e33800000000000000000000000000000000012d04a693d565f96566b7c313c47d272fef0ecc828493b0841d58f6bf690a77cb72824a656442e288460ecca7cf05504000000000000000000000000000000000b33eefd5df8b098e6505cbe655a483ab5c6e417a4ed55420beab95e8614c8538dca9296a7848d6aa0495a173df6d0b80d32b6969af54dd345f42320ea96def3c6f4dfd4e22a82686b7a3c57a0df5250000000000000000000000000000000000fdd9702ed88aa857254c3ba50b484bfc324e583659c57055e4b09eb1662af2f70b547a1eec139193a0d3c75b565d3b200000000000000000000000000000000193df0fbc5f24065008b5e98c4c4bf9f1e743a6ee60c3700ae4a9108639e540384eaf1f9d7a60b8b6a5d79e1f34949f50000000000000000000000000000000001022f8a254d17e448cadfad35b7a54dd2fb319c8f9ba219874bd8280a5077301ff4332d731a75646cd93bbf31331154000000000000000000000000000000000ca1eb350844ddd0a65a4ad56e1a96821de2c6633a4a45be976577c223e367853e2b1ecf2cc40b8595ba5591ae8e40f3969848f1b8b36bd28967b762168edb451322e2f0c4b99b7f9112c9a66093fb3f0000000000000000000000000000000001f9cda056a0f8803be581634562e975223b5311f4752b189cb6bd6df1ca5e3824bbd2889b9b93da59e4f08d482734240000000000000000000000000000000009f43c25de25c5d76ee1a03691aa434de6a063bb3a1133b045797a279346fc938dd2636abf0c4bbcb528c9c28d3105c40000000000000000000000000000000012afc29245da8bcd3c0d96c4ee61617cd9ecf42a47c2ee822003af26aeb4e4de8e432ffb6b2d8241090b814401a8676100000000000000000000000000000000053edfd98742dc70d510f1836fcffa6a3ba9ffd4904c7f5559b48e49dd21071401362d0b39bc0d786b7ee2e84a76af0d957ee08a513c5e22bbec04722575a9b4f3a1343db0ae5beef4e66fbbe1ac90440000000000000000000000000000000001dc3f016ea1a74ae50c21c1955ca1eb4a911026a1e72b316c7bbdc708caef63f0c1efecbecce8901d65bbfcaae429da0000000000000000000000000000000016ce9301888808323c9baf6402d7073fb85ebcd389334cc69d7947e345748ee44b2d6aab3ef818beb21b54a19ae4f5b5000000000000000000000000000000000c49817753eb6459cdb4bc737d3710b5f044bc544c8d92c8ef138ec9d83889664267e1a5691f4bc3fa235ecca2a973a500000000000000000000000000000000074a8450e35f1da18e6de05960e21b7059ece8972c36f000bba9e24488730a44ce3ce200c437e06703addb3b442a790a8e0cf0f590f77d13819001916d2c58a654d0b9d3c47c842f2d649cb2570dc0d5000000000000000000000000000000000bc1f2e9af093ae8235c93af098e692e697ea0ab4c8f53019a6e950f7072b56d5eef6b3237710f1dd1cd1970668d06d0000000000000000000000000000000000d9a63f7a13ff9755c6a3832e3c4c852919514523092367fab7886cac317e564d57fb4042ef40e696edce868e697c45700000000000000000000000000000000129a30657466460db13575dca367105c27d631eead330319b084adfac591f5b3b94988925d778e6d4645d1d2816baad00000000000000000000000000000000005ad64d6e761a9a301589547929f4952ccbfead278cbf6658255a075966340f185d5f356679fb02ff2197468ed7de19a71a8c2a479dec43d644ec4113142e666bcefd6d729d4faccbc147effa836ddab00000000000000000000000000000000077d1e5b35c224e2cdc849c02e800c0b80d1c19f3d74d9eec34c40f56bbdb9e2b5d2ef274991dca843755f91a50826fd0000000000000000000000000000000014f3b653e0df0c608b75dee3496a7af04a828e6fc5604f16ed49c39686ec757e96adb0a667853006a8331c3d63ae4ec2000000000000000000000000000000000aae011375b337940f2a53d9091d3581e8197e79251b19c7fba01de987721a9d6fa694b7978f0abf877f46ec26147c98000000000000000000000000000000000aaffbd468a2eb86a3cff59e2e9b7ab88286d2bdd19c2e789b1a68810f0cdc76171a2661ab54e81b17643ff0275eafd72d2d59a7f138327a20263d6338d2a92fa5a2f741daefe9aa81d06f20a6fe3641", "Expected": "0000000000000000000000000000000010a2434fd3150f6b9b491d3a51226bdd457504077ef2ed5a11ceaa8284900d1b84039a34d5239a863809369bf20a704c0000000000000000000000000000000007934f34fd50a98225fe6578d3f34ae5e5ef5e104bb9cb398b2ca4f09048ec39cf52e7fdbac48d45212e9e4c1dcc6e120000000000000000000000000000000013ee70f1b52cb8b07ad957a7565b3e3c56306392cf7b5aa29047b23e5b41fb3239ac3611bcb16ba7c7ffc4213e3d9cc800000000000000000000000000000000035840f8ecf56359dc3239945720ad08702b4ea8d0fa9bea3bfb234431df4618e960a1eea87da72ba4d9443f14bb87a3", "Name": "matter_g2_multiexp_14", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d04bb9b75bc8078ccfa85e27d32e137ff5f05f9241b19ea835bba2fffc9255a4a3028c0caf9c32d3d27666e1394fe820000000000000000000000000000000013f59c3d8aaee34230cd7715a32e4a45487b9b16ce68d178f95461229a4d0fbe7d31edc7208a7338eed08e65847f8f29000000000000000000000000000000000d63ca2bafaa54e93ea54846b26f88b4c6749953f9cd00c670914cca279b794c1fb5e2664fce44b8c04f01c68698a8b9000000000000000000000000000000000b5188b4b7ef78d3662baa01b1813b4a0b0f855e11397584a460d56f594f11ff2e5d708a23a8e64d0ab337c7076872527740a826d524fdb7969776bede5ada468a0115229152907cb2b050760c18c8e20000000000000000000000000000000019bae57568c879cd743f7def43b6b994f29782c6a0c74734f35b97042a916da00daaea34f321481e6cc4749e23297c1c000000000000000000000000000000001853fd11d4688b027146a07edea647502e80750de4e5e2d105faad3f71ccc90badcc750f76f1b02db3bc0a1a635b2bbb000000000000000000000000000000000b1e45b90e6a7032179236f13f01ab664c32ee5728414ac0d6b9d79510e8c5bd0f5b62e6c59c1a3c88998bf45636cbab000000000000000000000000000000000ed16c2f88b5b8d29d7e01633e2876322caeb740251b034e5e898919f836ae73f0296c62253a0329ee8f71fdb5cac3a1d226f56bf3935ea95d976fde5790ba0584e5bbc78b37279aed8e50389899b9e9000000000000000000000000000000001455764f99e5eb0e0371e89f88bfee1c43224b9b5202746bd151f72336285556acc5ff36bd8ff87378249e82214cc5e500000000000000000000000000000000007fcee74e5335d96714e4d1a7c6f5c211b1a460efa283e0d0578c6c1f56dbd252198eebf0625362973c40d95fd890d3000000000000000000000000000000000ede26cf87e604507230ad996788e85799cc07245cf7191a6c3cecf0bfd5747b3a277cfbe41252808df6da19f005de9a000000000000000000000000000000001855991a4dd78dfc6088e6a43a64b56c8d86a0278b899bc8a1979a40a287979dee567217b006ca71374156a96b79c176c133e1989ac82e4d1c9852a6c7156a34b05784a58231d59e3cc875ac5834d5c8000000000000000000000000000000000cd032a7dfed029af020bfa249e6adccaaf5bcd2ccf33736281c4fce9c6e2b2e87fa828cc20301269d8e0579ffb866a1000000000000000000000000000000000765c4d6c4062cfbf7e24f9772dcd812f7e707f2b0ccf9043faf10018326834934df121924abb74d736b0da47554794a000000000000000000000000000000001540fa51e4580ff73e58def90a6f19557dec3c8306e2317ba0c25ece3eb4f8c39beb57741b3c4b9b8554fd2597743ce6000000000000000000000000000000000d875c822d0ce50dd638254cd4aad5dea1443813689a940d72cfa5db9309b171299ca3d69b137dfd37f0b7538a0852750fdae1b53f6442c4378774a981c90d282d5f8793feb2334470c873491e41740f0000000000000000000000000000000011c230689175cc672c25f3c56ef4eaf2bc5766ce424f6c596b40ab24fdbfa56a955205419c149058dffa4d86a48ad35d00000000000000000000000000000000078d493ce3a8038134541ae5f2a82b5e0590218a499dfd78c7a9c06b92307003fb62d6414d6c04b22f2877c3de0b65ca0000000000000000000000000000000001d53c22a622c5d91df934783f8c0cb7e370043ecaf99a0554987e6c5120a0e5f4ede023a9ad988d30d945a2132ba5770000000000000000000000000000000015b1f36a00fee95e13443c9f6e67935a840cedc7c3fb7833ece8e180991909922f59d4f4ecbbf23f16bf5ee7f0b5851b70f1de7cc5e6a2cf7dd4b6e60ada67ca47e7b9417bb5f599048fb0c9b2abf33d0000000000000000000000000000000014adff1607236910597a951ae169a7f56d6a3b4e0f44ac63a247716bbbf61feff7865d075f79e4108cda6c0731fdcfef000000000000000000000000000000000d740b13885c268da876898b77914bf4a002beef5bd2a3edefbf366e45ebcdf593ec6d9ab21e983fcae9a0832986182d0000000000000000000000000000000002a0827e812e983898351d9f03f660317d41669b0fa378e5c7667b73df299ddc4a32a529ca887a53245d7e1f946623b3000000000000000000000000000000000bf09a2de1a8ccf24a8a65dda72adcb96535ea7235de87f05d27341738b0b4ab16afbc5b37c97e255118dea9bf180ec2ca82cffdf59b742a736ae9a6d36f7840c46c20c126ec054f47ad52a22948d7210000000000000000000000000000000015fbbf7e8c26e2f41be32daee2c81390b9bc4413aabb053e3a88bc6117377bc16011e81ed167370b72f84f0e77c2b8680000000000000000000000000000000013d48a27d06ff00048b19879493a5f8ca52b7154be2fcb468b9de9edd1395750434b0e95ae6dd941e84fd6d8918455bc0000000000000000000000000000000012fd2bc91286dd46d68d87a3f8793db997ee684dec6b2de1c4202e5e7eb0e4a8a21222e3dcf80e1ae4a3a92474107d330000000000000000000000000000000004d8b71978c9025dabb3d1b1b3c7f4f13f166514b8b356fd064842269a36c6f1c07f150c03510af7d0913103afda4a68fad69492cab4ec7eb89ed37f1e7fe898ff49ffac4ef2aeb75d9c6b544109a08f0000000000000000000000000000000007d679ac21bd4634b415ef8e0e3670a8a1d673f6a4f7f3786b92d55458af980b035e4dab165a3b773ff3469fdd9d5135000000000000000000000000000000000fdb82db6e1096e73322050f828ba41b3012496a4fc4cb481f11fee338243aae20b205ee06887e28f6ba6dad00445f9d0000000000000000000000000000000017e6894b48f60b3d9b4184d58ab9554851e285a1d445b4d97cb1a7ed5a984ade8b0f62ab11ca75fdb280cc0e526108ca000000000000000000000000000000000c03b61690cdd9a4c6c83d03749db72c8946c21a944fb292866cf3a2dd1bf3dcd95743227709740ce8124319d0a540555af71c9baaf54967683f8553f72abf789da465041ee5a92c9ce1ad562c91c4d7000000000000000000000000000000000289f850c4834153f36bfc4855f89e9437a172c35a856117f8b841e5ad4ef973d3aa33fa73d8dbba4b9b2101708006bd000000000000000000000000000000000700025f22c0460613c05f8941f8a79a4319325c37c2b8f099cd910df5c0c27121a9de0e40adc7ba0fda61ea637b47d600000000000000000000000000000000069e17e00d4d726e8eaca8235c88967a7c093c70e5a46b1863ad097acbe233554048838a0a486a72cbed7001c83a27db00000000000000000000000000000000016ce4afb84c1a9e0216f23bcd2dda0bbada6a4acca78e1e0d765a5290f6f4929f6d0eeaf1306fed3c9766ca7c7268acc7effc9a7fe773a420ca430c58bb94e7baf26b9a97b618a15e7a18b31e5914f10000000000000000000000000000000018ca46a89dadcd3b54f60fdf9a7b97c95b9e0668ed9329bbe4121e588a1ba773c9d086dc35b699d65487f428c00ad8c30000000000000000000000000000000003ada6835a93310d0ada01bd7fd6778bd07e718d1ce05aee2b4990bf32322fa94ca898a531ec6e3b8cd7ae3bdc77e0b70000000000000000000000000000000004a8abd2b9f7449213e63ecdb435e5e13fe2aaa31a2c38673a6adb5e96f4dd383dacab391787f6c17579c78a1cefa5450000000000000000000000000000000002a8768d98ccda80149a767e9b5a3b0bbbc0ab4b5f696522c8f1c664f1d27f2f0a6690531672ba2070355c0e77095dc02d5a3d0370f4a58c21016d208609f1d3e7cdf43abdb85199bfc67dd12f589b8a00000000000000000000000000000000048fb58924bd5952d3bd7b1cd57a1dae6c1034df3a420c1151737f88760e4b0e78fa3f891a0dc32fcb50f89e67b0f08300000000000000000000000000000000073e9723c80eae7685db774d3e2bced53a52f24504fc3aff98e2becf8d59c6e83373ed024ec1ca50101d2d613abd286e0000000000000000000000000000000003b64c8e9a1341bc6a444a871843b3add7dbf04bd1810e1d6da7d31c7c2b7a264c362ac9a366dc8d93bcd9392c6056f000000000000000000000000000000000064462d424e54f50e9849a2bba1b0caae966a8618fda0f8965b1a841dd2173872a44a18ace1e2aecc8e3546a9558d7013549b86ed3fb880269be22b9cb8be6f24385bb5e24bba81bce9fd5b72ce2ab71000000000000000000000000000000000c40c8da9281a8b43478c28b2fe59a3cbad0a818e2077d40cfe44624dc2e46f72d4489cccf63eb8460d02f895e78edf5000000000000000000000000000000000735d768f6ac999a47c88bc2f3375f01052259dc69011480e468d8963ea8eda74726c4ef32c8feba52878eaf5c0147730000000000000000000000000000000010adb3ad214b17b963586a10701934727edf05fcbdc94d98255632647d73536decd0c91363840e1b55f29f7d32f650410000000000000000000000000000000019349045e6fd25960c03336888679cb53409027f35a1f211b40d24ebf724866c085a978ffa3a91d989da1a7902bca018c8f6dd56906fa13144dc87c31b53186b0683cad220ab2de89d2fb515bb269cbc000000000000000000000000000000000a5d2dcc05e218b0633e0a965b6d69a3c6c1c7837e1fff7ff75cc9ee93a112f8e34cbc95bd9dd8fe6ed22f2e9221aa110000000000000000000000000000000017d2e5d2c0578b1ec26b57c3305b209c979bba6925756892f031a7462ec44e8a4a2527e6aa2fc13bae91dcacb8c7a30f000000000000000000000000000000000d437edb45ace50700db548db68b9e8376b3039fa00cb98dd00cd197c14d0f92c8a3945127c43b10b34bef7894fa43410000000000000000000000000000000010d5a2e442a2eb35aa85fdaecf094c1e1f307dc9bcc540693d7206cc4e0d050ab900f17fbdd0754b59bd2aae705c60149ec934eddc44729d05f193ac927fbcb022288ffb2bc7d4f46d1bfcc7efacef940000000000000000000000000000000016c36464b426c3066aead1aaaf65ca637e93279e8ccc9d838b9b3ff1aa7b896f36de506efc2b0864763cb6ecca4926f30000000000000000000000000000000006d88d5764fc854ed7d7cf1c0e210496ce347bd887da2a149a09679469e98c453d85115afdd2fc4987b64a88c4a6f0a200000000000000000000000000000000053edcc0ca4c205423ee6a7031939379e552bd2d2657f8f25370c9f0ea0a947e77f18b5f218f98d12d720667844f3795000000000000000000000000000000001292909190854cee4499faa602af99dc49d1354a71278b439e983bd89e6c504fa5fcaaafb6ea26dbeba9850bcdfc1f69bd211ec887635ca841c4608fd00bdc0f5fd0f6365dcdfd7d6f4c36f4b25b5b1b000000000000000000000000000000000997e79a7549ada9ee0233b3bf9289df3ff797595f4b5eb2e7dda6977ca981c1c4a2b91b924812b95418f1b1d9d0cb830000000000000000000000000000000000256b830e80f238e8494387429d727a91cf5d323ea87f7dc143058c05e11858796adcdc677429d1db4dc2415cf23808000000000000000000000000000000000cab529c6b86beacc57c874f07108d1df7d98fbd59fce44c48afe9eb2dff823f4869b620bbafc121b4ead2cf244974de0000000000000000000000000000000002774906c1a0acd87de224a9450617db37f8f36a0a192f5daa2774eff0b73aa79b4804342999df761f8572974c697c6010bce61d4e35770e7737636c0f9a664eefa948662d3d22d1f1708fa48d3043de0000000000000000000000000000000012abd02540073017011e186586023adfca36fae454350b2015a796b7991eece65b63964fcdf581b4b51dbd7ddd506ec3000000000000000000000000000000000ccd3f2d9280908d4b30e924e4a862810a92e1a880cb56e842a94a2a5120956e8713f548ca279d66d06ab23e4976e54e0000000000000000000000000000000000c052ed00fde2cab515694d8c004de910e62d07c462345ffcfbd3904a0171b970bc58d99c5833059315283004f3390e00000000000000000000000000000000008fc4860366074ec0c7aed2c6ffae7c93ae0a81067edd8911b4c53393ebc0f23243823aa7aa2b2e987cb510f6e0a55a65c86930c1d142985bf85ce70bbad170947e850e5c6ac7803fc45980dd37a57d", "Expected": "0000000000000000000000000000000006ced307065868b6d082bd205bfbaea3b0a8cfdccf831bf154563b5a942154622b0d7689819b337479480d19aedd85e4000000000000000000000000000000000c0f04fbb26cf85c2c22763f3e78fe255d8d1f45ea47232ab58f5b785ad9f2458b0b28f3cdc25c4dfcb47d59957ae10700000000000000000000000000000000120e38740eebbc3eeea9beea483e70d6a9c30a5abd61b86e5f94bf65ffb40fb92c8d246edbeca425ace175f79c9c8afd000000000000000000000000000000000d5a503a26e50f9be34c2e64e4a80402ca6e17f09db1b334a9c1f6318f3e7e63b3847a7ca38ae6aa7c96ff94bf5de842", "Name": "matter_g2_multiexp_15", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000036480931a5a585ea54b6dbb01759eb1d86804e3f03326188c71f859613722e662c453096431171a49eecf8653f14d470000000000000000000000000000000015fcd6a30b9d59a90d8595ca1758eed7d6810d2916638dc2cb637aa09b16b5ba4920df7d21fc0b923453a6c7d32f056b0000000000000000000000000000000019aa4d8e98808c2fc1273d383e836876b087ad5a7d01743bded01314bc62ced94052d75d312a18839c1b33faa9e2e5160000000000000000000000000000000015747ce0f1171c0d0ff1fee9dbb2e5673b9db0b0c3618cc8bda474f378db58ea42184f907593f3d6fc2fa215cabb7b2308e559e394a9c1ff07a45bb3e022f9c212eea4ee5b77db1c5b93ce72c0512b79000000000000000000000000000000000222640c1d64948daac3ff93e86ecc96bcf9c93559266529a37ef1372a81952431673d69f1220e07b8aa0a4f3164c83b000000000000000000000000000000000db593156078821cd0ce0270e8a444d0d204dce0583774496620bd4752839f3451e505aeb3db568048739c7e71d279b40000000000000000000000000000000019932ad2c7e857c2dd51f7846534050b9243e388260cd47a91444fa050a9154eca88ab4d29a37def16d4a11d35683f2f0000000000000000000000000000000004d15ec653a72256ac6b616e9870b0acc7d46286893c0eec523dc27bbcf5fe596204cbf83ce71c2690af67b3616794225e55826db8d12169a31ca27beec80554954f522b56f7994c62bdb527c2438d5d00000000000000000000000000000000180622bfa9a1c452f343ed21a3e9c6fdf76589cebfb9a3f0a53782a3e7c9d066294e10699c386b5d0525003289f0ec580000000000000000000000000000000006615ff63c856302dba6d4e25d1070fe873e0c4950ee5ba8bbbd4b94ceeb181f1ee450acfd22f21010b88f0b88375777000000000000000000000000000000000cfd3940b5eeefa92d775792affa34371d13f3098ede3007e06510344ac8483debadd5a2baebafb5ddcb45a9449768b200000000000000000000000000000000145be0107a1e3acecc89a116668f9887579ed7a72abed3f4236930edd3f18974465c99ada86c4980c88768824216170f1362e8e39ec661cb3c5af64e0001cc94701194344a7404f1ecf7df0d5633eff9000000000000000000000000000000000820e74e6d0333b6b36590ebae78960d019065f1681ce68a2a01a2522496c840c668575a57f9fd0f50b87f928a41b0de000000000000000000000000000000000dee60d90e96019cf2bb552d016419e92dd358ff97039a61838b0a89ccbbd537f2b435cd11f7b6e75a4ec6675964e7fd0000000000000000000000000000000002ca767de9fbf8af7c73d41a07e1c0e38e3fc971472e11928b65393a27354b2d732012dc57f498f94c0b933565a7493200000000000000000000000000000000134fe97b24e153f0e9a27d3fe7b89999c6a19e353325e0746ead013198b8e00ca6472fcbd2a112aecb9ddf671aaedd9174d3d66cde7c4c8a4499708a0c6f7c4da458eb970b6ca87e23601c702365b6de00000000000000000000000000000000031a9c29323196ef31030ba73827d228e56fd5209eeef0803a189e0c0e5b186ca1f342483eeac99e1e1b12cf490856460000000000000000000000000000000010deea45a01370602bf57a1f81413e8d3b337d7a1a33f9525e4ff7003454d1da2cfb1a9b42c4a654320f91fe7d04b6200000000000000000000000000000000002bafb7b7452a173a3971c2ba1768061a043307d2c32767056f18c1bf8b066176937876a87055e54675876bc1b2d2fc3000000000000000000000000000000000b5c77dba3b4136a7efaa8c2e28f39e88afbf26a7313b52ad6e390da4d948209d96e39aa08eb52200dfb890d7e88b46a389e0d43f2006449fe2de506dcdba4cd0e6077e2228f7d8b6ec9d8a4129c494f0000000000000000000000000000000018bd1ea5ee8e39c43d442e9c6fd22706e582cd80051f18334c4db2ea91ab019f54bc0074c8f0e52e50367197a797e7520000000000000000000000000000000005c0bcd1b047fdbdff25b138248bf4da4c013beff7dd3030c348d6b2b8724a147cbc44d570db5c4b273c94d0b99bc2290000000000000000000000000000000018e033935c20be5940863f7e9e39fcbdc29ba031e58c10beea90cc48e9da9988fdbf108bcbd87948058f386928f81fa800000000000000000000000000000000107d179204db7b288315e8aed7b92ebfe53b7ad2366d5d7944b3df68d9d9faad023e477213f85214047645bc05fd4cde5f8dc332cb31e43bc2e551356cb8d1533c6e567d34622667e7e4e3ddef352f03000000000000000000000000000000000a7b364fbd3bac7e2f2e7ee501db2d248bd73a76c2a12a3e51718b56ca9a8ded14b83b8cf0b5bd46f0c26896a65fdb15000000000000000000000000000000000eafea7128fe20ddf740a6396bf18ff5f2652a0317ea9b6e934927c3ee95b59c7dcd51f7c895b3989d40ae5f78ca508f000000000000000000000000000000000bdce57be904236a8df532c2c0072165b5cbd4103e9061fcfc0a45a67e4b25d11b9f816f63fc0eac4d6d3e10d2764c4a0000000000000000000000000000000012419f94ddbd8275054f8f89fdc27a74afca2eef314393236fca65705354e5cc0a470818999c96b5087997813823e9be0dc7052044251fd360538fa6d5dec9fcee53faf2f07de5d8df212d04f968a0b60000000000000000000000000000000011e4010d0cd7855a92cd5d4954ad735363c0c2ab00053db5e078f34e772969d8c492892329cb95ea8893b4b7ff7aaa5e0000000000000000000000000000000013badc54d90a19b84d76b30fef8e3ad2cb268204fdaa50ae951b63e48aec9cc6d585751dd48e4a8d4659b835f38f8da8000000000000000000000000000000000460728f686b9b15cc19ef135af71312e174860284c3f0e7a84cf85a5c934e2bb6cadee8e482d88afe788a796605f79d0000000000000000000000000000000019a50c06ba307d83452a30fbd862270652cf5c7a09b150fcea858a8102ce3b1e9ec13b6abfb323d63d2c4edf209c7cafc579dd4f361fed9084d9c66a3ec4c6af5293710ba5299df3abc4cbaf5802b5360000000000000000000000000000000009faa74f66ec0384f0458893c0026f73688c764e8df9ce056a88a2ed0b84ed8f88d1b683443a3269a3db838f8aeb808a000000000000000000000000000000000949c4be2708c1aac86aff39290ab6a8e0f332e7a098bbd64227a175473d9dfe136e07548b282f69a94a15e2c32dada10000000000000000000000000000000014f2c7c7da781e2f50803e3a948381c3c439b127949f79824df1e5722c206efccd6c0ec5dd75ef63d8b1fa301c83356900000000000000000000000000000000176753460d241f38aff41bafdad51688ab0dc9a5fb3643977c7b9d282ad4532fcca1e725715227780ec28bf1c32bbc1d69f0f3c3f516ae34fbecf45f4636c22acffbee765952b332c0f3d8cadb9c93f10000000000000000000000000000000011982264c8c078518cd0adb05034761224e9063654904e06fb5e5a6eeb1f45e4ff3da661f1232693b79336215dcc0cc40000000000000000000000000000000010c96c872160d2de03a16e85f2828d0cf2dd16a3389effacce46b5b5eecfea1042a77de653da5a1c0380a84c435723fd000000000000000000000000000000000a4ad2d9956bd407c555b26c192c6bf59bf89e40d9c6f9c90780bba313a39db71a73e7633397d47a3f58f61c81edee77000000000000000000000000000000000a7f912530d27a7bf74e01d8e48890cc66f72d14950554991ed1edfc504062ff6bd3cb6941bb398df9fde3cefd33fc0676618f1954730111e572937cf0c9f7b3298a11d18cd890cb419f732c766bc6210000000000000000000000000000000015bc12aa9ecf417fa5bace8d9e5dc4a418555eeddde1da8b624bf7d6e1873ec4a257d5f6dfc058a8d9b02528e699abb70000000000000000000000000000000015b41567f8c780f83342449f27094bc20a839602ae482de14b92e40017e7acac8857db48a2d27f1f1a625883b6e5255e000000000000000000000000000000000cbe79ac0718555fd8fdc38b68eec8be83b32499d2654be44888e45a2d610b0e81ae12fd56550524ad85b5a632db32ce00000000000000000000000000000000069f46b5baf4357d8010869685b3828c0dbf6e2338598c9b42dfecf0b22d803f95fca716115f74c77778d414cbcbd881fbb9f2400ed1dec7ea63d2b26bb3e9c2acf70117e3026626f6f88a07876177880000000000000000000000000000000017ada4038189c544902167be958e43ee133730e5cd329e572dae2d853b694f5ff8032bd9ab41cddd11c51e8284970f810000000000000000000000000000000013eef75e6d28deec945ddff33128c199fa52565288d63677c824b8d56a6c29eb98d34c5834e84865be35d40c1c59a40c000000000000000000000000000000000e2fb4f9c7ba6bdac1d4ff5055be609abef7fecd7923a753a704da537c0ff41951552420bd78d14cf972dc84fa3f5dd9000000000000000000000000000000000805376b814b8a59435310d49a43081dd7ea36dc7dcb40d38068ae9085b3ea9a3b2249234234cacc76724d8ef84a2eaca0170d7b7604b8951a95d49b6697e2d0cd2a41c3671d8f96e936cca911dd516d0000000000000000000000000000000002288860f2d671c84c5239313b7f6b82e31c3976e6d310e15d3bfe1c566e2ab5d86ae6ed0df02530f9f7893ba419f1870000000000000000000000000000000017365bc096e260f8dd7b189fabe10eb66923783b41fff70a149251576b3b465c13230dd0af13cde562751dacd8298335000000000000000000000000000000000fa8eb9c818df27181b45a74b333ab481dc7212e417c4e12634816f9e177064f9e1101deff26156d26bc6574db9617080000000000000000000000000000000009379598bf02222e1ec37a721b9ea31a3adc33524c6a41bc58da06caa3da3bd730659f0a80f793a0fcb9c07b43ca929c2c2afc06f19e627e9ec0edf1083823d30ac569346040965e1c92e0c15011c90b00000000000000000000000000000000136870e08ff5fabf36410629ce5c23470eafbe73a7dceb633df5c1492e39445b86ce15c22bf4c421cfd0adc6518e78c30000000000000000000000000000000010aefa3cdf1225da09b796430d096807a83eb2fd5a58db3a4bfc5e500dcfcd472fea3077f0c059620f4ff708f37c95a90000000000000000000000000000000019ee2c62ff860338af623c535979ed31c42c0d0b2f82cd56c153e80e6d92bec9ce39bc8e8f285d1efd1c1e969521dbb50000000000000000000000000000000008ed69eb0a16c8a35d507bc3a50bfc97e18143fef611263715aacf5400cb1aa285b6d2ebf2ec219d2fec477360875a03141d0ff346e46a20c2498a74f910e9bb2d5d8530afc7ba47c3525861c9e8c5920000000000000000000000000000000014abc4eec64f2611197d0c1322c3248eadb725049379e64682f2b3d7f83f7bcea11358d88f52711b3020924b6ddd84790000000000000000000000000000000009fd78c5d1d2043d83be30a88f046f5b633c6dbb11bab25fa3037bd250b6b9d9394327aae25d1939f777fea9f3df46960000000000000000000000000000000010f413640aaa16a95afba98660f9e1b03a8f3e0a7a3d7f2b971f71b5e3d09016ac2b410f97d20471f48621d5a363e9e6000000000000000000000000000000000154b5df93298a5a14a6157819e38db33ae7f2d11dfd13f7f2a92b2fd9b053fbd25f10a8c45db3026f6f583bd56eee0f1d688a1aca2a837e0a353039294a9988a7111ac134a6a8a68e4f881e7486025c000000000000000000000000000000000f1893df99adeff5e4042c4c5e8557e53f7c34efcb2a7953d5347f81d2f4a75ca0273a3845f54e795ac1c1f8ae7240dc0000000000000000000000000000000004856b05d58898be6aba07fcffe487dd895144c7ac8fa8bb1a37c61e73bcd062ff541d510e24c5bf005c8351d3ddf61c00000000000000000000000000000000178b22c2c698dbc4929b119474a741ef44d6275fff5ba058d9debe9475e71398e464aa14a6712c5deeb5010d1c7758ba0000000000000000000000000000000005ad09389c35c45f349e6dcaf1cdb3b63648b3df427ea0c2a371f45634635f9253957ba6987df4aca6cba4cd472308a31b59c33ff02791031e7a9424c781ff17a209d132af06f5b825df363fbd902cd4", "Expected": "000000000000000000000000000000001090d83d501373cf07c75effb1c85852019b39eb0d77226823aa3c1054d4e408e82fbf0f4420a30144c611fbb856748c00000000000000000000000000000000120a1e3795f6d5c4ed5b886256c611bdd209677f8324b7091cdd7cab11788b1c0f780e8b4c38b84d7c2ea528123d4783000000000000000000000000000000000d250df34d906ed421eec2a78c2ff4ed4eedb717358d7ca879d58ff5b4d2d72521082dba6ac5d10859125e32c2c8b490000000000000000000000000000000000476adaed9d80cb1545be505496222dba1f0ea85d38d5bece0663461e0e9d47abbefe95303c926db008d08b8aa162e27", "Name": "matter_g2_multiexp_16", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e1a9066289392b0b0b8f0986366c2975463c9cbe7a74f2eafcb3b8b6d4ee3226ea5886aaae374341bc76b53b165e22a000000000000000000000000000000001557cd01b61b5f2361f6b558a87c67f2778e11c21734b7ed25f72a88cc62cbed396d583de4c2190ae6bbfd096c33bf73000000000000000000000000000000000eab68305118d7e7076043719ac1e13ecda4497df2cf392d6aae4b7753f114d30aae3e8535742947636901feac4b620a0000000000000000000000000000000002cfe5014446556b82d60adf874cef25e58eabd035deb4717c93bf0361f37a4a67aab70b95627326bd97f111efeed57f58fef5bc887b7caf72f2a533fe1455ae523841bd49b4adf16cfe87edc6f573eb000000000000000000000000000000000c8fa30f6055357f6b697f2115203428b8005ad03286d2b3c805bf3d4dbb461c30e6ee8b0973ef41f884b91e857c53500000000000000000000000000000000005e1c785feb4c4fb7e960233d431d51a4fe471f10321251d018a950374d2a686d52ee8cdd855a29e770bdc1bc565f471000000000000000000000000000000001158d31faab483832d39f5431a5d8aeb952d6a63b82ec019f235b5b2e5580df8cd91b46cd53d4a90b9db354b38c5a1710000000000000000000000000000000004a389b09be6fb7ffd14d7f3359b17991e93d92a1c0b9a89faceaf71f5ce77a1875aaeb7a0ec3b2dfb363c47dfc9875273b243b83d44158a66eb6d31e7c4ae1f4b3ddbba81b2cf9a654ca7c4ea2147ad0000000000000000000000000000000010587118c5f90b545ee707466ea2c5f378e6795c260235cdf9876aed8bd753aac592ee05e23882ee77f4a13bff97f5940000000000000000000000000000000000a0344aed244b90c4fb9ac337edb01429e09f951062b06025a5212300f5471a95f28e09bbc715417a6d98423b518c3a00000000000000000000000000000000128457cf374e5b8864b8241f476da093f48553d609a5f30c0f0f235ecf7127231237b6c8802f2904a8304c7c237842620000000000000000000000000000000004d55ff04eb09b33ebfe90f2a0966a1b59cc224215c0359a4ff0c09e60f9fe7ad8342868184d8cfcaa1d8c28328864241ea87af09f6e62111c48993c408efd3db9ebe218ac68f61a461ad9ec1306873d0000000000000000000000000000000019e6992c3da47715bf379a668a15668508e7ad27bac647490be8e82759b9b79c996735aa1bfdc3cef217750e4ed36fce000000000000000000000000000000000828f782c5bd4f2de3570a4930db2c020f75f93adc98aa0e48449d29c7a3b0d5c349963d956bab7f985ba6ffe59c90ec00000000000000000000000000000000062c7a730d286e895c57b75907713ebf1d20650b5e621f270f1d22a2ca480d022346def4102a62eebe867210e4b6122e000000000000000000000000000000000d6c29462ad449ee6cd122e3dc00d56dd5caf17a2510e5305aecfe85626cf73adb401ec2192eb693158650893fa67412a691b9635e38a46e2469811405ef6325ae7ef88a67c1d1c5b05806da329f27e000000000000000000000000000000000098de9ab41c289a05ba5a774eafe27d91aa8272fe9f81fadefba9a0cc0e31de20f808ff454a8647c44f5aa632742af9e000000000000000000000000000000000c96019bd5cdd62df1642656f0832ac8ff6aab86f671e18c1c7023dc16b8ff54a8e3e446b19682a23b73ccb90da2fdf0000000000000000000000000000000000178e3b4366b2517d4c19fb40551be6979d46319d7040682241b046f10ab88d269dfc097ae02952d46e69cb1cf159da50000000000000000000000000000000008341bfe1e2fb999f0c3f4e79523c720edd332401f9dfdb8dddba8d1342c2c1fb20ae2fd9dda92c7bde5a0c95ad971f80d9a35f474325d0f065442805cab3beae4a186b252ebae54a567dec6695588f1000000000000000000000000000000001004d60af8c21f7c62fcba1c5c41b94fc77f64b89abcd23a218f0da8f47d2ae6879ddcde52f3e6feeae2dc7b2720577d000000000000000000000000000000000b8e8a7da87aa62ca852e2984b0f12b85052fdd03883f01f4496df0835d1cafa48818b5ff1e3cb0e9ecd66054540a0d40000000000000000000000000000000009c16854580ad8191e3e80a0afa8da759a8b2bfa7e0d556418b5c96d97e88a12fb75a91cd68c2f4336c3ed7ac99199fe00000000000000000000000000000000195ce9c562c460c7e715908991ea8b017b81561b45133427f63cdfbe8f65202bdc8e8958ab0977b3a244cfa32fb35f37c20e998acda67d406a238f16bc2b3066a6d69d2436577b8900a180e6a71b0a01000000000000000000000000000000000107292f77666064b7d80d73ea8f3b623170ef79ccc7c228b8366675a422a0cb8491586a2e4ab1a067c31396cd670a8900000000000000000000000000000000126f8136dd61d61b2a9c0f4af3ed44a3cec3ccdedc74821f341d200601a7bf0a17079c824de6cfe28467e843d0c74d2a000000000000000000000000000000000bcec8afcc7ee56b36d6d08b51f61454c8fb15ec5baee1117ed55af8fc85f68674250334f79b0fce632e75623dd173210000000000000000000000000000000016624d64660b63b70ed197f6a675911b02b0bc6f880348faa6ce4727af74127c509ce8535d8dc8db5ae2d71aa497e0756fb773cde356e2edac3afd2bf703b59161162dc1e915873ecf606dfc0e6efec5000000000000000000000000000000000f57747c20e1b3923c7e1d8bd7d877736cccc0e0829837a086d62d48cb54f323d90b57ca3339fe4b256df529bff11363000000000000000000000000000000001940327a1b319dc4212e7a553d3f49904660722c89636f6a38604d96771fa0fc71f57674b7aa710db4275822c2b89903000000000000000000000000000000001956b81bcf961d16e50c053ca07ae67cb8597138f34a9dad4d82e0e8d23a7e08b751682d588f229311bc63f9598ef448000000000000000000000000000000000208981064443e8c72987945e399b45b74e529a0bb75e99b7d6744728e5c182a6b0a10e449147bcb0b0cbe70edcdd845bffc1a58dd06752a2a77abab835d089599b4781ae51ab998ff3c5b68329068bf0000000000000000000000000000000018c35ca3a63053fec853e8fda5920b560f1be28431f2f4b08789c7a202336c8905a5ffffbf69ae4427f267b1e13288d60000000000000000000000000000000019de96be76bd93886cc486c2671b5b0d731b568638b1b830a52dd4c481b9a1fbe2b3cef14b46e25f1188ddb3c158da6e000000000000000000000000000000001813ab16a11c79eb3d3d47ae7d9a7c05401ee91eb1183266d23077ec4c0c8f3ac7188eece06876025dc3fe271d65d4ba0000000000000000000000000000000004d2a416dc874e956fd6d29a3fb96195019f4136561b4c127541ac171b5a6b229746af6d6e535a8017e64ce06709e52e57f35cfd74f62fa39f919400f4d692855a4b4e9f91920e4306ebb2e772a484f4000000000000000000000000000000000623b7a8a1c24dcc603f01589e6679c74c4ed3452894e536a4cea69e99047092acc877dd0bb395b0cb693cb1702a64a00000000000000000000000000000000013de9dc75e42f12e905d729a52f25bb1a4125f5edb435734649281bdfd41083716d0797b0a80d842c2503d09cc61162a0000000000000000000000000000000006453c06f56dbaabd4530160bcd5312b8a148dbe19fdf9f1e44b7b047a73ee9ef9d981116d00269942ef73537885eb7a00000000000000000000000000000000075376135ff3acaecc0eeea32f8dc15add57e8f0297d053ffaa0fb0a8fc4418c5b142f96b6b9ce9eee2f949c960aed682d1f3709700634653374fba5a94d69163ef616a72a63d462afd9f01c9ddba84000000000000000000000000000000000120d088fc12210c1f5f6cc3d1091563f9a37d4d0e0d2c305b479f4d7e893c4d5c8170eb164e34e4843a21c9eb193d11d00000000000000000000000000000000159de80db3b1f0ffc5fa8c93e1bd54cf8ae19cbc9018a5dfed86179cdbc976c1c312212080ab221806bbe142d496e7a7000000000000000000000000000000001103abb75a78220218cde4bc4c59ddb5fb647ff808754dda200bdf586ee9c47a09e03762bb726b085928ddcc998af3ee000000000000000000000000000000000bff4bea17eae0f2ff3e7f99bfa91e6ae8aea28f6f3fb6080eb644861defdefc26befbb7874f612edac0cecf70dfb275614ed9a08dfd406df00719d5eeacfb0a96413b608974fd0aa1d4c6176b968dc00000000000000000000000000000000012dde607a2d4452c6c060054c8adb6307743edea3ccb6ac34c275717f177f0e454d9e33d4391208198cae39d7eb6f6c00000000000000000000000000000000014cb4d8bc98060ee68a8ddbc44b83db5cb6d09f09b0d608357629251c35e44383e97058d0d68fe2df3bc47424a5dda03000000000000000000000000000000000c14fbb6c844fbf896fbd3cb3464a83aa4c6e9a7f0450ad96a07527df6f1eeeaf587f60a990bd6abe7aeaf5eb46f362d0000000000000000000000000000000001d9468774318ea711b79f16303ce86288cee312af296f1c9f607ef5f97c7d1cb48a7218775c8aef00c227ccb586286e7c1dd2e5e5f630fb1d07e8934dd3ab029917e7775e401c0bcf7e1fd83aef728400000000000000000000000000000000181e7f8d0ec7a4a7858bc96b61484c24dbb9dfeb3746fd3a231a8e442369e3e83516ee6043b1c06e7e2043dc86f6c75e00000000000000000000000000000000184c1d667c0ece59f18fd2eeafc66f1ed530b7d5f4560a6c886429caa13255c63dea01c3e357e3408af58a39420a8b28000000000000000000000000000000000a8475ea694cf607246a1c50064cf90cbe50ad5cf8006934a1fdf1621ba38d20e70860a2b5aecc05acc60943224cadb60000000000000000000000000000000008afa03c2df8e83fb64523c57d0daa7cfbb7af6a4bf2960ebc64515a61a659b2c37ee661050cd538fa00cb34746a371b64e9d16cb61f2bcdef30cf544d97e078fccb999b96a1da0eeaa0bf232f01995f0000000000000000000000000000000008b33a297c8f86f1e9d7166f9e905283c8e1581e582b879caf48585d0bca3608fe46d8d9f6e7c90855aee9d92283d7a40000000000000000000000000000000016962410d6b4b6f91437617e84bfaaba49de0369b8748d2e2dacb63b421e0d7de4514e7fd3e0dcbcfba8baa4915610d0000000000000000000000000000000000efdab72953b870d0e113efa7c183d99aefc100ce59791aabc72423aff70a5b74c577c06ca94bfd6a7722199b4bc22660000000000000000000000000000000013b18e31700987dfa4344384f9b41e72afe92c39bc961333cad3e7d0a5efd3842a5e849cff5655c4673f720fd0127dca35bca9082d66c06761f702dd439faa4957caa70ce0343268787f41a2f4bc0cbf0000000000000000000000000000000008b86f70c8d8b03b0e9a8975776d7fb0d08f95eded0a0124551d363c2df57124e0e89bd45ddd1cc75c258a4ae2f87916000000000000000000000000000000001120eef9eaff7c308b629deafb060d2c12b20b57562007fa810a2191d99fabe9c7d3c364caec1724665ef556de66b57e0000000000000000000000000000000007698bbef6dcea67a2c643342ab2a0f830c329fb6244d4a98512daa8a3c9d808cd2acc0cebbe3da920053ad73eb7cdc7000000000000000000000000000000001155b6beb28fd88d252c6b407bb9f55d22103257287ce77353bea580c90173b5c3d49080b319ea28817d67c52bead96f7980eac6c8db86ef83748d10b210835e53baf8cc9f607915df272b6e28ac6b2800000000000000000000000000000000142b28509d72f9e3be9ee916827fc1a8dfc4ef7ae2b72eebad5db605fdb2dfa4492b50cc3e472df1b52baa6e2b0eff5500000000000000000000000000000000134d6821088ce4a8b42383d5a43a32bb0cdc96c85f304a2601292670633d5e231b9dc479d199829a9ba9f39c162318d5000000000000000000000000000000000636da344fcb0fe50ff3e22f8591418f64cfc722b2860b4a5047f973f42e4cefb93c2f8eb8a14b4d150758ecbf3cf712000000000000000000000000000000000e6fd06d5dca702cc9f199f7583add86c82f7b530d4dfb9faec36dbb669cf7c1cd1260c7e4f3026824eeb5b979e9fdaea256ebae4b204b3888d7bd244bbff26431ab5890098870f13800bb3be3e842ca", "Expected": "000000000000000000000000000000001684f447f8929ec0187811f66e985f0014eba46eaa87de2d4ac2347d10c0550e4044ec7792d9f315c50081dc2097ebdb000000000000000000000000000000000ee0c46efe930bc98f39dee8cc6a792744e84de4fadec035d25ee8ba82e1c53264d0885a1fb05b2b8dc9c6a1846c28320000000000000000000000000000000003a5ef98843099235a2ad9522c9cfce1908bef77b45794e7df9eb38a4854460031829e947a118e8160365fbec3725b85000000000000000000000000000000000dd205e195abef6a4cfa7da66f022a418235e1a1b2fefa6bd3ddf8a3851d8ca8c27652bf87ac644cd189ae55e3cc7808", "Name": "matter_g2_multiexp_17", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000064698182f90c20ed6f6da7248cea32a291f901876a900d344ce4dc1b07822b480519cb8d891b5ee4f33b4efd90742cb000000000000000000000000000000000e7e9d2e79ec4b07015baf69a283f6a4abc8d7c1699f3356fdad6ea9b1c70e41e73bc14e500634d73749f9900eeb65f5000000000000000000000000000000000002ddbf40619ea5123c100e2d6553213e37883fb34f0f0f2124795dd971892d5c9051cd4aa78b9d20f196301ca9bb4d0000000000000000000000000000000017a07b32fbffdbf7a80f0437eac1ec5fff5a68f3b053482f034064992158b604bc34489dfd41a24ffba806ccb871fff15805f2e8013007c4f6d8abf441728eda8d742ea2f1df545f85d092f50ca8275c0000000000000000000000000000000018b4de9c04fde8b708408efb3aa7f24b5f7bcec14e7d06fd5a5b36bab528e5adc0bbb1e378a5ff6fcbc95aea530ffc6a0000000000000000000000000000000010da98267770a47e5ed14ffb3dbcf537dd14ae5eb79522c772a7a2833be214690db0b4e86621de1842d88018fc0f348400000000000000000000000000000000135548e2eec9ae7c3d23618d8286db13a5a628fee04fb6ec9da980f3a46838899cf965c1cc6f562e71d5b5c7428cabc8000000000000000000000000000000001669fcee7804df9b7bef32e2ffeaf285e8501842efe87c9e827fce872dffbf92255d3c3a2fb5c382ab7aec0bba1ae0e5502d777b25f3112ba2264022e2f28dfb6e5d5239ba097e9d815928be44b6a62a0000000000000000000000000000000010ed20c069bb300a27571adabd239e70b767af90b91c4d0e93d88278a6da47b7c12fcfaf62ac0a7b9966968cc9f3770b0000000000000000000000000000000017273eddc25cf41f2d7734a3866711e83d4f2823ee6a036942799f837d5ceff10dd6022ea25e3c1e28c7b14ed8f4e7c5000000000000000000000000000000000f201f314f66f6b2c6e1365c0fac7b187d31bc45b5edaef5243b5488e26581dee24de4a5fe493bee44165cc31d8d72ef0000000000000000000000000000000009dfbdd86633edfacad6b78d292141a1e653a1bfd8c48a96b2f6bf8271ed6033c0511628caf2ef258eb64cc8b63d8e5be7d64b471cca34ab0c91f61ff26719c7186dfcdef13895d37ead407873736a740000000000000000000000000000000005c4a4a5ffcb4a39c8809821ff275360ff937070cb97a791cc9ec45f429256a6d2d6127248b6ab0b6c71c30c4fe84ff20000000000000000000000000000000019fa60f481c5be953c9c7dc86903a89af0ca2b4205be3a00d793d6de7103852e147ebc7d983c6d6e8cd99e681241ad440000000000000000000000000000000015b3b2eeb0f81ff8a2624e2ff2396bc69feffeef62b1b6a1e73ca4b9e60506c2950fdd23a37cf56387b8794449d3237f0000000000000000000000000000000017021a69ceba3446dad9fcfd8cbe5b89b61372f57d43a8d2e2c8f4534bef6b91408409dfda9438f24526f7e6bf1f4240e5723630020fdb48e44adda735943c91ad7d1e12f3c32d823833eacfcc8b02ba0000000000000000000000000000000007c8f07f22a3412fb4638cb704751959cda4e42e4612edaf5b1f22c8f9ea314508353445114bab6c07ccbb4b0d0bfa6b00000000000000000000000000000000062d087155c8722d0102c8e5084f95f5f58ed626d48197297d21d2108ee05f70f16d595ef73e8e1207a3c0b013fe16710000000000000000000000000000000003b6652934f3acd4c91c6c521c2476bcd2594a939ff2e7ebcbb0f451fcf0a656a518dbd4f36f165f9b2f58054e9f778f000000000000000000000000000000000bbf21158227e0ad5461de9ad8bd580f9e65327dd4e23f1ad55618f6b0aec45aa6076fa88557953ad15d385a074bc7d96e9e37bd811b76133c12268d325ebbd6656e7ed718cd777458867dc98b1b3bc50000000000000000000000000000000019e336d4d342f110eeeba9773b8e351f26bb56361c77fbf12fd9fc218fd075ae38b95f4a8a5ef830fc2cd92558b1711e000000000000000000000000000000000a112725046ca3b6cc43207e6b36f38d96ff98dfe3444d67ee3f4b0208f3b8543768dc9989f936637d7819e7dc5740fd000000000000000000000000000000000527682076572d8cca15e47a2faf62b129baad29afed22d32ea47983a8d0b138653c1353bfc6fbf9fdbec2efe36700f90000000000000000000000000000000007e3c5aff373b5154ae66f978fcd66d09cbebc7e0c96b4a4cf23c4fa5f2fa655410c7f1ce597a3f5f155017720f7c50f7d46516db284a3938e672ad3c6bd40313d77c5d643ffcc59e3f55ad983cdc0ed000000000000000000000000000000001865c265ed4606ed16056c0b28f953119751d7272bb33b9865eed312ba23b32d01733ad5446cea5873c2bbe37fdfce7e0000000000000000000000000000000007018aca1e7ac211921cab1cc6bb18874d2f39f00d916b8f3d46a088a378f3c9b49ab8a296d0aa21608f11b144a0c687000000000000000000000000000000000210561c0bbe5a9f4b2237e5bdf88bcd73326d395277deb2a883526978df90792993e6ee520c9d5ec0a6f7ef5c6b3542000000000000000000000000000000000cdd344124b7b5da556f64ac5d651a6f9b74427fd712007310d720f3236724e2284aab812d739a87f3a1bfe8737dcee7586cf63c5e52b44aaa79cdda6dd6fa92c6fce11d867b2ff5a04c9e44e0b3930000000000000000000000000000000000024494aab30849df790185a4f939954b724c387c9a366fbe833b628577654174f705d05e7d7dbcd29b8873aecd55df0b000000000000000000000000000000000863054fe3e4838d2caec7103e3d0453e86a17fff0dfdb84dd819f31756032e9e97b7be89b636e5e0b642718f6da217b0000000000000000000000000000000015c8bb4fcb6d9cf941b722136d8d76d847fd6d5c643f4c0049c9746e76e49726fd463ce7899f4df66d04e5d48e523e6a000000000000000000000000000000000f101bea4e1bf610d2782ede91da95eb2b0be9ce60485465b9e94cbb9530b416c4394862f0ba7ee8067bb48e94c07c53efaac96bc5f686d6b952e7082236622b737fda0dd3900bec71654bdebc8ba2e40000000000000000000000000000000002dd11f4dacf3d9c46579182df1c1c45a364a8dc1eb7aa7d54d0141306f1c23bed85235783a22b8e6dc4adc35f9193ab0000000000000000000000000000000010d1c642fce533039e98712bdfcda86eaa62d2d69b861ec4fd835488732fcea414cfb6f3f8414152f9d5398c73a74fd2000000000000000000000000000000000c6759b75b1e3fe86c00fa124d09c5b7438ad61fd1bb71695743ed7793f39b7a0fc99b055201ac1e3aa07ccec61b24a80000000000000000000000000000000017580c9341789484fb31386eccc9c344539a09f1c4421dd124b1a0ce61f2d0528942f7fe8df67c6b2bbf782996def47b39d6045573dafd09ab2a0d8ab6e97b0ade43bd79d820749ecf19cf7d99792ca8000000000000000000000000000000000d9c48a111c8c74bce8cd78d127999531e46a411b2f0be3507226766bc8abd088638a237674ac62e0fb7dd4a86d09b79000000000000000000000000000000000073675bb81e2bfe6adb5cd929e0b7280f5d60b3dee7f797d65ffbefc2c2944a9c7207648bb096f13292ff4440c3f03f00000000000000000000000000000000024d2e0d5ba1a804520c72331fa23a2a326d461177fa527473240dda130f4ef893870e893e1dbf7c5dbb0178dcd29b3b0000000000000000000000000000000002a4c9487485ec33f8fb347d246ab0d41b883bec30d2a5e88cccafa676569f25ffd8341cdf6c09f68afae442a574f3334c4a2ff4ce4b633ec8fe0bfea42ccc329b7d3fbce96c26989b3c7a391c9e806a000000000000000000000000000000000c1965a745e42853b4d54739b2dc507d68d80b330360a4020e4412ba5422daaae313fb9597c98575c66ccf351e62a527000000000000000000000000000000000844439e6f08a411e61d37b5b2b07921049432e1833e839b00d6cc11227dfc8770ad9ca06037043668fe7ce3bf3ce84200000000000000000000000000000000152ad6fabde2e0310c978404a5244209a9363cab1f3ac9f71339cdad6d40c84f8e5a8a196283b581d0209ce90e1e3c6c0000000000000000000000000000000010eb6af62c7dba122b0e24e8326dc906370bcb4ba791c47630f05f657a228c20e010c065b93537ec84fa14a756b199789af09ef1f27cb83189e4e13f3801c08d3a2adc8b5f88717954ee84499defc0c40000000000000000000000000000000001febb2cf2d664e4a277cbf08fc1fbacd05db415a12329f7be551ed56d67f0b5dcc917d1b02951657bff3a26bd8c178d000000000000000000000000000000000018af160555292b2f7ce27112c1d60038b564f5427d62604387de97dcf48e4473107f91936b5e8008065a1537f7ca340000000000000000000000000000000016bbad2a7f5451098294a7cab2fe10d206741a99b128dde5eade581d02ca849bab3662fc3400fbe055dd93a418aecf0b000000000000000000000000000000000b1e9586cc1b357da6e58621ce09288e62a79517144f6c6b867359251baad6d40217578d49c1501f23206b125282bdf4c72c1dc1efefb775a1bda754ff17389a6b6b6bb25e22697847d24a117eb8974b000000000000000000000000000000000b88892250c848e7bc7bb7e42cfe1048a1f61dc546929211846f49501ad8c7c8817f5b5b99ed092d5a2236d59d9c8eaf0000000000000000000000000000000011680c6549f6b7d9d187a6409d40cc26554df654083f1e8a47dde826149d68da756adfb1b65bbd219f79a10d8454e881000000000000000000000000000000000f9596121dad98bf7acb3fd65fe7e0bdc8924e2390341c11d9cc9cbb0517f988ff79a5e1d60bd89449b5f042f0d0b0c30000000000000000000000000000000008982832ef53bafc23ea817be378532b95b5872217093e7c7c2f4512d03a9c9a6dbb7950563a520781c7ae213fc82897b4a0c7c2e611a24c722975ae882dcb4b45e6f6b41cfc87e8c766beefd5b10bfd000000000000000000000000000000000ea5bc2f8bc2b4088d1fed7090ba389577b11a3ee0775cb3f0657ab5b07a6709d3a18fa5fc33554dea235c60baae4bb100000000000000000000000000000000196b6259b06a4c91a0bb0adecea134c8609cf983c2c87158a69c9de3b6768510fc56543a84d1266dda78d90c3b0516ac000000000000000000000000000000000d0222d8ef278cd0d85dc8765fa7c4256394a5ef61f91301af6c7422b4cb17889224c75ccecd2df3ddc9bac98b493863000000000000000000000000000000000548809ce26cd498816ef1222d062b1ebb7313a07e99e3aad1431f984e9b8ecfd43357ea57da7e0c6c011c5d5400f7ba986d48aa5b00fc16c36dcad061d10937b55ec4deee63cc2841b7ebab84f910d2000000000000000000000000000000000b95455351fbce6f73de0345a195f91bf96abee361908cea6c4dcde72048a13a9a23991a75b9c988ba0afd9491d15696000000000000000000000000000000000305f29b05fed06ffab484cb065d4852eb323fda8c9b7c0a78843bd7143effa95cbe5e50c1a0c3a9675bb5381709b6550000000000000000000000000000000016ebcb25f1b8e8d7a8f7131455ed2be084bdcce40034e7ef24a47fc29e447f912c20c7c9910e025aab975cd2c8cf1a96000000000000000000000000000000000d84a5de7a5fd8592f6cc2bc7c3d93c06e26185787856c922d95eeee345ddfb7cbbb60b6d992c5ea4dfb33101f2ef1dc979d4df836daac0960fbbb8919d2f90c3457cc987153def711d6e8a12fb14363000000000000000000000000000000001377d654f80e933c4598aba1f637d1e37d66a96680c3a89a762f412e187817ec08f0ae897b08206a73f1a423b742261900000000000000000000000000000000014b71954b9bc22ac22cb2d7d7f373c3238c923205b223cce6c219175df2bb6d7258ae46d6cdb019311bd386275499fb000000000000000000000000000000000a08ef83b67bc972a67b9174d0e5b1536af882d505d03464c9a97f68061aa319d612de9db84e1e7b12fc3015fc2973b20000000000000000000000000000000005f716d0ffc30005e4a744092704a9e29f58fb06bf7d8d6fdbb95a4c0eeb5c39452cf662721ea3e0bcc67f25931a109425ae495ba75cdd0bfe200ee24d813e1aa93c100ce861c9ed7fa5537e11778990", "Expected": "000000000000000000000000000000000c53f0ca8901f4751be4a478088b30dce70b9ecc382455049df9ce108eb0a8d2696bb325fe9ebfd7d967ab5b9b2c2bd800000000000000000000000000000000033460babd2984a5d8b7002409349972f518364e92648927e223d7a3b648e952482c06cc713bdc29ab83f2646e9398510000000000000000000000000000000007cb9dfe603dc070151cc477ec5bb5a2a949062e8442399597c5eff8f1decff538cd0aef1384256dec73746e63a6c66c0000000000000000000000000000000016b56ee9b21c533b9c464178d14ba5c92a90e6a54c3ed319f487c2082b1ce1d0ff81131a5fb3dd7d13e0fc1d9ad9e4a1", "Name": "matter_g2_multiexp_18", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000104e0b91821c59290be48b97936458af89078b176b5585ca9a79070c7050309b01df4b0bcd84f137f58304d90599212f0000000000000000000000000000000013b00ece925fd17a8effc43e21d982553ab2764b13defaae5e5419cb9a23ca7436cfc44088c2aded63785e4f07b6e186000000000000000000000000000000000267cdd42febf0706675b60af8c0953582ced84dd5ae870815654cffa46eb14b747fb8fbb3b014e59c929da49c6908050000000000000000000000000000000011c5384d7c3e0f4fd66ba4b4c2ab60f6f78f9930e1fed233263dad25294814d9e2aaba6388ee9f924e2a323693b6e43bbb2a329761a3d6a2e4d9d63d7bbf7fc6fd321ec0344cc4d7d1b6565c475ee9670000000000000000000000000000000018158ad70994584e6f2443b8b96c1e4772a00fa0bf74865c76000eae470eb02cff627579126cc465046d4e088782557b000000000000000000000000000000000d72979d455733756a0849baa8afd79e18960f3f6dc9676c33d1663961617831f3266015cb998fff28b78300c87c2a73000000000000000000000000000000000056192c20cbcbde6099256a8f40c78a32d3fd212fe9c511951c7523a3559f60662e070f5b5e5f87b1686be0bf6cc890000000000000000000000000000000000c7b7e8ab7486012d95af5b2474ce15db612bfe1508852b8d99f4402d0e4f075ba056c19df3caa3a93bb4db89443096143cbc3dd7ec63ac63618a9e5da1f9c3fb952c6fc6972dfec6caf1a415a0aa79e00000000000000000000000000000000005a2741902dab47e8d38992180a9670faf56d1849dbeaa75b2b4ded93ee5494184c8658232e9131a8b08ac9b5460bd400000000000000000000000000000000189077d5130b3a4d7d4c3074633fb12739f95b8b6ccb082dfa61d845a389e6ca7aff835fa0f194dc349e1584b3141507000000000000000000000000000000000f226324f242cbc5f616c4a897f82bc5503ab1963ca38f30070c7c9916ef6bef5caa7e2e26b3f9fe68a1d59f19a9831d000000000000000000000000000000000a999bdfa10e4838ca69694272b0187f7d0198d6db0fd85eae688424fb09baa165c623dc6da567fe034d7cf9f9a0087e733a3a84eddaf3af8c5009646a899f6ae8cf233f535e360e29e2952088ebd7b6000000000000000000000000000000000fe85d976befdae8fd0ad33a4404415304afad1c5698b91bdc15abb4f268807c906410a6ca827320f5271c8fd4c8d6fe000000000000000000000000000000000cbff7963daa20c1d20717bcd47b872b3ecd5f38de1a467ef50936f13d6aebd978116a736cb6c5d676c6a9525bb0b7fc000000000000000000000000000000000c3d20ba17a21bbfe873d88e9221571f1bae7f02f35b8e677c9c42907673d765150c737f0011fdbaf4faa883b0dbf0280000000000000000000000000000000013482c68a5e1084faf12e8aec92cd9f0692b173556ac8ac3c7519beb4bd75f847f41ab9432421c631b14c885c001dce25112b5912aa3cba657d8de3dc8138fec92b391d5f988b82e19f16fe52fafea71000000000000000000000000000000000f9091a0df2c989e12a844c447287b704803d1532a3ecbcc890e6f6a885a54b969c53323c105b3d14d12f2cf766b8ac8000000000000000000000000000000000e54f3a9def8b3a9f972726e606195849584b7197ab70a28cf5644cde15e70bb6e3044042b649825adaf5e37c2d5e614000000000000000000000000000000000cae412d8a3ee3c5af38d7a65bdf2440d9cc2d6348dce0791f4a7e71ac483d7487b6c789be0a401777de3f57ec65de820000000000000000000000000000000014df09fd2ff406707004f6afa366d06bcf8bf18f5fc4b444b07c98b3f358247c6056a6337f5b53c35db45904797fb4455683e0b33b5463bc71283f0625269b2b33ead69c1eb7b23a996c31c514d06937000000000000000000000000000000000a8aa422e1d58fccc84615f9ca4a4743cf5efe3a1066c9819f05042100bb8784fcceffc8b3a739f549b42f34d62629e7000000000000000000000000000000000c737cf78b10e82fc0cc9823891f1a5f1e9229d61e8f369c589512d01e5180246db46e4f09e811464c6e1ad930226d390000000000000000000000000000000016017354434899e2285da6ff4b27fbaab633d962197d2ff4fa5f688c4a85e1817434cbef13a6b018df4e359d7b9ab7cf0000000000000000000000000000000001433c364428ac69ce4f5678aadfed4e6d076241519310686de01572da5cf78af4a98b3502519beb0dcf04b748d08cac5bcc597c5ed7f79173942a0250e618c93cd0917b37b5f354d63a2c02a576080c0000000000000000000000000000000001f8b803f3f76aee9825a9a960cd2f9e8aa931568b32be6169036683b4e6d8c4abba6bb73b137c7c6d6b6ea92f2023ab000000000000000000000000000000000fe9edeab60bb55990ad2c85c8fc9341e81de54324652c08c615a745813f08153bab3849dbeffcf4073f087f7c0cf0f6000000000000000000000000000000001955289b1210fa31542bd89f95188d60751b32e8d54f1d4d280975850e57db7b151b872bd431c528c22fb89c9b8784af00000000000000000000000000000000079c8a56c72adb9fc9baa503db394635abb10264dd43c60f2c82d041d43240321ac1028688d92c4696395d8840d52f15f2613a8e50fbc6683ecdd7c7fd38b4caa8e5dc9778909fc8680a58b16ebf40da0000000000000000000000000000000000b0fd79e62c6129fa115d821b8f2a58a4564f5ccbb14088f59d5e6a17a64e803f32bf8e5a415aac4d6491612d95ee8f00000000000000000000000000000000008d837b6c70468e1e10f6b979b7c0694d65942aac48b5baa829c191579186314ea35fe440e6d843fded02b95f9816890000000000000000000000000000000015a05bbc4607b113b37dc0b4b8add23736e0f1bb1e48aabc15500fa6941b17153918d256b6442687a432dd9ca9a198c70000000000000000000000000000000003546953d97306266bdd359d4daa939e05c0466691de59d2dbe3584e2ebfd9a9e1516cdc9cb643c5d31731835dfb07c657a747bc919991ef9b7b10388bf3f301fd910f807ccd31e322be46580a71b7c60000000000000000000000000000000009a4366299290c3c6651b22865fb22cc972a05ca5981f5682574851e41096d531e375e981c4e1b1cbfebbc70a41bb6ad00000000000000000000000000000000001e6fe2097fca2afb8385a3100dbd5ee1b7ae972e06ef9f5e34eb9fbdc65455e1c822299e06a9dd5a3f71a0c1efd44a0000000000000000000000000000000005ad2ffa8861848c46722a7924ece68580fe44e03157c982b7133361e974b59dab7b75358fe498fcde9f68b5b99f23e0000000000000000000000000000000000adac33e0b7e6740c980a4f297917fc4fc13f53a71909f2eecd0067656c6f82c3b371cc638509151bf937f8257aa415d86ba09829f4bbb383e2e131d554c42edf1065022975655c07df2b3445a3e6cbb000000000000000000000000000000001462d509503d2c33829c3fb5380199b79b970c2ae7f944e54a6d0f0deab3571976916cfc311ea6ce6128c467665fbbd10000000000000000000000000000000017f6fe356cb0dd5bddd489c26669f0f365260bb48a5f862e9bfb778a7ff5392938b905759718d050f7d93f107236cc75000000000000000000000000000000000d9b3ca93c5133cabf3d3daa565bc6b51e63b7e37f68f3bcc43b9b3ee7db15f8bb33052eb7e332ae3e9ffafb17cb77d60000000000000000000000000000000017d6b898d9799385990c9dcc3f72ed93333486b98349ef106a230a71d768b75cf56cd946f5952075bc41f26dca9c83c003fd5e91f590fbe171aa3f006617b20ad645626c970c2351e048b2ac3773213600000000000000000000000000000000158e5e008796c10f6050826c29523864d06e68977cdc95d281a8606924aeed0b475ab152bec5bfca8e0ec53691b307f50000000000000000000000000000000006fe8e75328c067546eaba93f4be2b15513bae4a3458112c3ffa457d15c23636816fb469f071889380f31870d713e949000000000000000000000000000000000b9b21cd58f8742ed094e9b770182f6f3f855204d869e53c02d0c242a133e957c53c9fabc827d6379b39541170be313000000000000000000000000000000000014eaae1f0789f0b1e8ad3b452b4ed3ff87bed49ffedd13c8c35c35668c33537b63050c06a5bf3d88d516cddac13b4c935ee16785c004dd2a01920c52d3244e2160fec2d17a519974d4331527cc627910000000000000000000000000000000019f976b3584ffc188424614fd287eb79f060c55e9b3dd2f3eb99760a7cb5b70e2b62a0895b05e7cce2e390853fed61b3000000000000000000000000000000001117181241fead3865eba4804ec2c14f571aef5351d5bce29399113d007cd4e9c262af1c77daf9183346153e562864b2000000000000000000000000000000000f823f71035a4870be2ef20bc94e97d74d18c0a1be9895fb27c54df1f663df6f9e6e45ea5fe4502143a84c05e517b02b00000000000000000000000000000000141250f392fabd4566e0cd3a472a4b2971a432a3a5e1d9c924866c7a9516322bfa691e9dccdd5ef14c561bca6dd70ba204a6d6e29336015d99e107cd312e300bd54f815c785f6008c47c99fa008452700000000000000000000000000000000014d6827b9bc782863491bc7c544263f58dc04c18e08a87ca2fbb5799c4aa70bc039416a85dbba67dd83bcc27b70748670000000000000000000000000000000016c2816e93ea9d4bd6e42a9720cb89d637d88e00074da3300c6409be98a03403e9ac15f83167cdeb13800ad174ac47f10000000000000000000000000000000002aebc0116a62f93a6e86c7fce86745618e08f4aa9cebca7b520e9176bcdf1521cb2bf7eca7f7af9487fdc82dce76bb50000000000000000000000000000000010684e3254207c4ccdd49e4775198df981afcf7d9f89b894e204c5dd84ef42b89fe3e2f6b9278470e6cde4d3f4abb3b003f9cd3873dc6243748e16e4806f8eaa339edcfdbf4408a8e41a3df80c9816210000000000000000000000000000000010ab1d5494509060c9784b4744a0572a9466d6c374524a6d338ea12ac5ad89519217c462c3487e398325439311bea86400000000000000000000000000000000197568cb53ce03f00aeb04278f355da862be757366dad14ca6d30b3a537df9855a1196010773768a91cb4bb664a34f0f0000000000000000000000000000000001fee249315794d30eaf929f44b99e07927194c6015ff34a4530698d7d68239240c9cc48530d52ea06218a826a655cce000000000000000000000000000000000645b5d701bf3422228576467120935f014c754dd68bb3555b50aff5ca04001a26298982c97a64469aeac3432784efca34135a2e7853c74725bdaee1ceadead7b4c7d729650df6544bd525c05c94234200000000000000000000000000000000113e17730f8dd7258157085c30cd9d1950a26c848b55e3a8a55865eb567edecfb09f32ba27fb3e2096ea00c30f31ced8000000000000000000000000000000000076db9ccf8df9530b64cd43ef7b496d1f432885062406028901bbfc5882fd12533f84eb12aa2ce8b7adf9dd980db0870000000000000000000000000000000015e487de49f1e494ce9907cf0ed31fb0a159c5290538ad969b2c8a504986dc9cccf7c74a61f622154e928aa2dd689c0800000000000000000000000000000000195e887083a98fe3f50a9ff4b342e004398cdfee55c4b02a4db0f65a77d3c0b142a45201674726c96d5f79f8604d61860033fdcb731830951dc3c4b33f06310eca51762cb7279039b3d7d9ace93c5f2a000000000000000000000000000000000d80c7e50973205585b20a068c64957cf4572eea40e32ffa8b759c38c6ad6f4468421f2fd6a6f5da1b0d008f625b3e6600000000000000000000000000000000009242dc1de055aea82b3b917f88b6232c550c3aff41241a7e54caab4c234d29b5d8138968846f7c754d73ab3b4e7913000000000000000000000000000000001188c31a9d8359d737576f4ce7a7900314aca0eb3b51baeccfdc9245bffec49143a11b3331f9126b01de0c307aa4e44400000000000000000000000000000000104ef4835124fa6b30dd551653aca25db5a544af6782cd0b1e7d26178253e0e33cda77428fc1dbcfe6114a758cab5c814c8112ebfe12bf44e84796e8b0cd03a93d2164d6edf1f06a5c520330a177da87", "Expected": "000000000000000000000000000000000e79d18633c18ac818786bba87d09c9bb1571e179d8769f8fb82e2e2b7a6a8695c1f4f06deebcb84524e8facdcb49d0500000000000000000000000000000000149d0231fb030a1bec170decd307c10e72cf1cca55c8a1b67aa94ce61e4c7d2ddfd0b8e71598e1abb054355dbcac1528000000000000000000000000000000000090f5be784dbafb0a8aab1516c773720341de6176017e0fb43a275d60de54c1189144956d4876d989232b362b90851c0000000000000000000000000000000019dba28eaa6706361f285b3abebef68f764204c74ee93ea011db01c19591ddc6f98799fb3026c3c223effe4489a7c676", "Name": "matter_g2_multiexp_19", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018a6a982acce5693e632901f3136eded40071e8c7caa7887f302c32621c5bcf9478991ca519978b52f8f69415c0d070b0000000000000000000000000000000013420ab920c8ecad5b2f9aaf9b0074c2386b0b08c81923558770d4c4a6b206a865af8322e9755706cd5e595bf0ffe564000000000000000000000000000000000c0e5bf5465d564e3ce86d6b742ca687448e6952439b1ff44b86ee6461464e07f8039e8ae7a301c6caee7eb99e38fab10000000000000000000000000000000015eb8751b750af62f57971e88b436658758bd5712f98861fa07328d2b11e8725fb55a2a00252e0be06b0c73aac0f7b8cdbb32a4fd8b9dc58a382a7e436e23f49a134915372553eee8c605436221acc80000000000000000000000000000000001328927910ab502e573188271108706152f562b1d5f6ec074f8f9ec5eaecc6cd5e8284a060b65d26463d22c8290ea4ca0000000000000000000000000000000005a1fcc348122350981dd5090c865a2aeb851ba8b6e0443c32f48b157ba673ae5652a70390888b3458afe6fe975321700000000000000000000000000000000019edc749a9799c8d3df75d4024791943a8fa02ba0cac90b6819f0bc42687b044457bc7cc6073506e8fc19af37f224624000000000000000000000000000000000fff20fb2b554b63758963c1583b996ad450cfbd5ca9952e38f38a8994809096086ed86311f7d73a0a5898ac261ce09e57df9664d3e17d9d46a886efde4e37e38859893113558843bc019699eeed8ec00000000000000000000000000000000002a7005dd32bddf1031f27c2ab999604c048a37c39734db48a30baa86c61ef626cf82084651ae9ba8a265333060a408d000000000000000000000000000000000421bf913a25108b8f520b2becc6f8064029dc046d0d5effbef31f0af59eee71cfce83fec8dda7983d50c6d5cbc8329a0000000000000000000000000000000016c75708f1dbfbeae3b06e5e9a7fb676c27100b99deece14d979b32a9c3cde6e9e96c8560a00aafbe6e7decc84e7e2780000000000000000000000000000000000ce23c27b5128bcffa424fd1d181d21b06b77bd6549ca5eba9a28cf18bb9a979270f6a5807c640dde57a0cd4f3af8cbe2b433b7a95c26e598002cc00b7904816d59baaba79bae7c6a7c26dcc48a487e000000000000000000000000000000000690c7ab321c0c93b5ae4ed77843ff4030e4ffb504c685d28573e98836e8e56dc19d662ae9f496a346bf2a8be5396741000000000000000000000000000000000fbbe3861a8d202b10801cdd606b50db0ad6ec7b923b90ae81ff5443676c3399e249e9efeb47b72d2b0a54cb0594686500000000000000000000000000000000148a27016968f0258e5eafe0a8182c22091873a5a58b27aa2160674584e06d5b2f46fc57a00617af18d0688df75294cb000000000000000000000000000000000148449d00b3d1b5b43b08a0c6e909a2d9c66920b60224a2c6a2521f0bad35b99e3bff8be0effb2f7f34438662d7a4882897583b53567bcfdbc63ae3e864a9cda24bb732694a6b27415c5212c7f45a9400000000000000000000000000000000026b55509b81befaf6baa682a3e92a0ab423fdaa84d2897613fd31acd9e1590f81581ba0ba87d68af76b01c36093e183000000000000000000000000000000000c675e190570bc5173b8f508d5bd2768c83e7f56a08cddbc636792dd75386939942827617c4aff8628a74b74195adea20000000000000000000000000000000014f59f38ae9e77f3a76478ecd47f32200567bad11f191d303cf15d7801ae7b5a3286095fc8726acc9818914b27a776bb000000000000000000000000000000000da89fe9493b2d9d46596d80162f5831d4fd8cbb83b46e84e95d5d684eb927022ee62ebc3519442007fdc543701f97bd2f7ff17e54d759eb9c51e16cf6f12d645bf2d091427416b4edbe1dd21947b4d900000000000000000000000000000000170e52a240a7ccf2d57ae92ea8dabe62ca4b458a5da42319ae89cad22ebf13541b0daccafa1b1d3cfcffe81b500c4cf400000000000000000000000000000000174879425f3bfd40fb74a88e3dc578e45b0e0eaad94da009e4076dc42d234d78248ec3a035666dd6de235f87e1a47bcb0000000000000000000000000000000005aee47acc3260d11fe0ca16050a29f92763b3cf8ac78da52b3b2b3e26d8ce7b6ccc187fcd81695aa456e9b94a84269b0000000000000000000000000000000005eb297abf35b51d57474b4989dd8f793005bf8e82e49859c41b786ae39217b2321299829198bda4aaa261a2723d43d6ce0a097efee666c22d1dd0ae8c8e11283aae781e1deadceb3ebbcbc5e5280a61000000000000000000000000000000000e49e94cfa35d8ade2b76865cc8be04737d00b48b195078c8085cbe782232a544cdb548373bd8ad0282674ba5c96fe0700000000000000000000000000000000047d59661f095c41bcc27da5f260f13a3fce334bba216b45df548894bdebc691fe779ccd63d99a9872973ab165a90c01000000000000000000000000000000000772e9a9c22bc7352fdf74915bc464de99ecd96420ef1af6e8bd5a05d73fff89c78e28eb340d4967e906f28afe1320490000000000000000000000000000000018bccff27bf9d7cb2159b9f2d1faabbf8591b53ca8e67e661d9f44f6dba6296e3e46ac32c50128bb5fb076cb8f214e277b2baa349884b54b542e3993210ef002f70c6467c7d512801f0003da789c00580000000000000000000000000000000002d947e728a3b376de520bf78e56452930de42544241180906719a24d72df65f8250402ccaf14d69935b1ecbb0b4d34c000000000000000000000000000000000d5614ec77a9f31915dddb3e4bb533db001702891a45f0bbac49e73d9c19a235a00442b52d452d77018f883706a616f1000000000000000000000000000000000dfc6a73a8e36b7b2d0614b1c6f7bf1ae284ed740c768f08416c0c09a601fadf3e4d7b17a93601b1803d19a04ccd570b0000000000000000000000000000000010d6a8e4eca2e818d6dff13faf0fae44a7fb90be436a9ef3aab05515a35cebfbd53e9af866cde1745f0e2c3b045486dd2b94d087c3ea101649ed57ff308dd3ae0d25a1ad8884763cea1b0b7c56a3834e000000000000000000000000000000000d6c5a6fe9b4d4580f8e1d89f0510bf5dd04e113d6ae5db04af2553bc0eb3a32fb881300f638fb33f7c4bfaa10b063660000000000000000000000000000000013e001b08191707ad98e21b3e0830286c6f3bf587b971dd4ce39e55f06db427676626a5c31c4a67a996a5725ec8f402c0000000000000000000000000000000012f86ed85113ed1abe9dd3826423911e63df0dfb51ad3d1e0e0318ae95991a6a11150176cec77f9c83268a322cb7e934000000000000000000000000000000000dda719cd2cf1aa769f94c21af20ab076b8f024e0a4903e38ddaca21b6bcd6f00baf7e1ed23259f135eb8bcf9c3f97c44f8c35b920a35b71dcf8d15a8a826e5a7c2a2c4f1ac2c2e3a6d100363e7f541800000000000000000000000000000000195ccfb9038bf9e637b88c83c552ffbd562357792513b15f703bffbd373ebaed715a6772fa7e6e5678c2e6422811dae1000000000000000000000000000000000c5a110f31d71b12cc42974003ba39d99dfd91769c2e93393449083a9b84d31473e3a7dff7ca40164e6e7215b03f44ef0000000000000000000000000000000006233b2dcfed96559b565928a494f2a50c2c375b3d7c60ee6b286c538f4fd5ca6f8b2a61654fd04d679bb3e05b9bcb03000000000000000000000000000000000d42233b7b5ad809c735c89c455ba1e8fbd623e1602bc729c01d362368666e4f90e7b076e32468041f3f5665c6fddb0d0ae6101fac82c10267770e74a0ee16b5be6eae2d455d742303a3c624d52aa726000000000000000000000000000000000f6d53de4f8b20de19b2fcbe8a6b8b8ec4bb801bce7363f89b133532ca7ce4925312e23c618a0182d158037c0d0bf07e0000000000000000000000000000000006ce094e24eb14b9bb1b4a1838d8b6da5f53b5c5799ab8dc8934b488cbabf698b99abeb016259a4e1b0f626d27f2c950000000000000000000000000000000000874aec7c8ac360e3980a6e2cbf3f7468f1df7a8d9158f8bdbb0f387d19f3b05326a081129576251ec41a926f670e58f000000000000000000000000000000001711c9b2ed7e2f789b29073f180e46d0c373d6e75c587ece67b8aaca1e9d9b43a96d04dfdcd42f943eca48e240b72ba8002fb31d0372e7730499b26d617b53ea04821c6eae922326d755a0df31b559ae000000000000000000000000000000000e8ddf88269aebf190bf9bd7a8276de92ff6039e479e42a490fe4ef00f646b049eb8ec4b8e073caa000bfcd86ee8724a000000000000000000000000000000000a9623655c0121ea0575de714e53c9e304fa3309f00828ba0e786112781a38bd458cd67864ab17929448171b5937c1d900000000000000000000000000000000198fccc4a333322599697e904e9096240b9c54f89ee6db97475beead62ebf730da1a179409133698ef13abe1310689270000000000000000000000000000000017b059ac08a3fcebde5888bec4d7cc2c70b147b3b1483fd001330637ff1c036faebf292801204bf2ba49350795708dedaa846e68337f4e9c99dde506a3af792732342e3b836376d4816557fc1fc9b916000000000000000000000000000000000a36274f33b4dc09e03a5ad648af0913e5ee95af83df8b4f2a158456aedf0a0528f9b4832b11162dd67e4d22b26e9f940000000000000000000000000000000008ce96d8bc0aaf2dea732dea188870d398b1f3c266b9bf019e1046cca05002416c910e02e998a1604a17c333c65c99a0000000000000000000000000000000000c1a0e4a80bb0331a94ed14570053f941a0438794e6f19d976cc62b3806a565697720ea03c2531004f13453991bd99bf00000000000000000000000000000000184bdae93abbe4d931a6a51ec85bc330d6181da2d34f2cc530e56b6803515ba87f5719fd6fce6a1a8bf1ee5a968bbfbedf9035283f1afc294ee68b2668870aa45e483d208483d9e967b11990cb55d8600000000000000000000000000000000016c3782daa55312a7cfa02c3be73ed75f4b726df5592351fffae19121b5cba73f427d35d5a2df7c63e2a5c68bf57f3800000000000000000000000000000000018b608343616eff759d512c97257f2103cb0909afb4c24a1cc9d8204274b7c9ed51bc762a6280e223a6116a9b23d1f1e000000000000000000000000000000000c687c11a879ec285180cbae3d2e4219df4614e238d4cbdff148ce5a8d21647c489ade3bf6f738052f149fdbc76c8bf6000000000000000000000000000000000936b34fea3a2633b9aa32244329891e332745876d05f95e4efdef859b23ceab4869db562555e5c8edce87a6fd075ae54005df80aa522e889e7720a9f2e44e6e7e19c3160ea282ec87a4b446d7b1c45f0000000000000000000000000000000000d4636a5e13bb59878319af6bb7c98e5d247c2c9cc970b9cec98027de2d4a8ad12d50906fe302c3d055c499a3742ee30000000000000000000000000000000002b0214bb1ee887a7ff10d458fe35208573456f685ee2fb93bb470762c9e27595cb00f2eae7574c8467e417c63c2a960000000000000000000000000000000001710d130f91861230562cd7ab87984ef45916af8e1168fb17b9765183d9d3f9b2c81c649687842de495a757471e28067000000000000000000000000000000000dd15fe505b1364f134ee77e5e3c1a497a20849b6ec7e201813677a1569a9f5a9edbe3df4c36bdcf9ada139b20e048ec893c9daec43032946a9e892dce960e07d29b304000378145148b9a24afd151570000000000000000000000000000000009a48d7c55d24ba49f890791d0f6a8a5ae08a19177575dc0d734fa37b52c3adc45b31b5e485a5d4a5533470c3549f5f900000000000000000000000000000000090f680c6fc1f0588add04ee03bf821868b1ce588e3ebe384dae657ba7885ef74da0bdc98d9d9594a9b979d5b50b93df000000000000000000000000000000000314f6aae1e99dbe3ea9ef85db7e1693a30869f48e05cdb073bf8e14865a671e75abb875d1b41f13d4eb74fc802299c70000000000000000000000000000000013c698b76dd68d1b9ab41672c2b07cb9a63168497d1144b51509b602c5acd71ca6cd049616d949214d95ab7a906a8f8bf685e6bb7713f8fe202c05dfd18003eff261456026a5185ee9e68aa821fe7c5b", "Expected": "000000000000000000000000000000001747f6d3154e0717435fa023754f115ce2a2b3241b62525cb2833473d84a8ccf4c95e3ea030f2b8b0ccc61124095ac86000000000000000000000000000000001827ed7d84a61c21268857036e91c732b304f609f285cdc4736c951fd8954b10267a8505f25d8be666792358632058b400000000000000000000000000000000121ac61f59051e6e89a7c1e2fb4df4b3a5b7773f46495a99e55348454e1d9d42254e5e11b841a1654ff9c80b157389c70000000000000000000000000000000001bc60cd06879980bc6ef2ca109d31f12cac28ebe4d2a934076d720b12f430e1bc4d4260f40045cc7a862726521a69dc", "Name": "matter_g2_multiexp_20", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000012a6984f0f8967c5ae6b13569a62095b5fe61ec607daff1845961bdd827c00fd56ef864802673dd21d90560fef6cbea00000000000000000000000000000000085ececa080d0f4c996d46c80a1fbad2ac9cff8b3e324aabb67182d79f941927050f025b633fd5119f30bb29b8e4b6f2000000000000000000000000000000000987518a5edfd5ae2616fc60000e117a4f1dd1db68195c3fb68d8cc639e4200945b2864d41ad86fb3e11c504fc1f9766000000000000000000000000000000000310939c7e11b93e5773cfd36fa70020c85396e525840742f994110e20019769abcd339db6881291639c193b987b68ae94b3c88e51af5822177b85978526036a426c9ca1077d594618ebb8fac4cdfc89000000000000000000000000000000000ec6922dfc74009c3750ce2540558c7c1e05cb45a5d651b96427c615d8fc563219215a0ee431c0a4827e40b26c4f8d3900000000000000000000000000000000040a4189d002a0e1ec600e71303575e82414e6400f06b9abf57151a28835d454f56421a6dc4049902bfb94dc0e9967ee000000000000000000000000000000000dfefc7c163c34cc004e9d97d812b2717d4736d0d1c722b6bf1a29676a32c8b46878d05a2d137cb7fff5fed8c0f02474000000000000000000000000000000000e3f0c9cbc778693c8ba88af8306d45477493ed6be1bdd9c81c65341239eb510fc948142cc30b73f570819b38f13e20f6e456b39f4efe6581657f5c701c696fde8acb59e856943f15cdd639c1fa68ed70000000000000000000000000000000013705ca4ecca16559713df65b376c7c5825b4f63d001ebbfce9cd1b592af5f2ddb38ac7c5ce3c5f7af4f39f909887e8b00000000000000000000000000000000179efff38ea1044e91ccad467cd2b49438079ccb4d0fc692e79e0bc374abe064fb9979c4a1f4b92c15cd1b042b501d5f000000000000000000000000000000000b6fda2dbf6339af225515681184843f1a9bcd72f7b1389f186f8d0e048ac16e20967c28e087cf09d7bcac597a85398d000000000000000000000000000000001946fca8c816e1e11187aabc40dd2436533d537ce4639eb2d08630ed2ce402c1806b6c2b3e04a960408fd4d2049849bae5d306f46a31c14de7b2940104d0a4424ebaff805a81f1c4a910566057c81604000000000000000000000000000000001802064095d029d3897725eeb93ed6e3b090390769026120aab6977d0de264a262aa312c5777ba322c9eac29e5396fc6000000000000000000000000000000001410f17820941e6a67b1b4993496cdcf0d4fa2d4fda3d43ee985f2606b1408aa9c9ce412c80c90a0c876cb5ecb76878c000000000000000000000000000000001514e9b2c65ca86713447f2d5bb8395fe8552e059829afc68bc43ba9267ef41ec6d69d06e7407a731bcca77ed5d9716f00000000000000000000000000000000025b5bb18cad46179fab15b2ccef17858f9259a90ea4548852b8c6fca69f0ecdf0b175669bacff1625a7143e762514194ff6d13bb0967945ff3b6fbbc104296805e4fedc3c25bb55b75cc997834de6b700000000000000000000000000000000146eaf5da57b6ac788f8caeb4b2ebf7c8999e03dd839977046ca834fffa7e57cd949e3fd44999a007b5dcf3c8621ba2f000000000000000000000000000000000d859632d3424ffe4227ae14856e05c4e750545cf276c97aa9ec03ebde334144eea670dc68e92b61fc775e477a2154040000000000000000000000000000000010b44279c0c80886e52fde5e71726422da2f9457ff86b21426d80356fad95d5ff3a7491002364d9de5ca99c2500f344d000000000000000000000000000000000851b769a691f0ebb53ee3693833881fed8dc6d9e5f1dfeaf4ab1aa7ad54e2fcac246b70d81110451ed78044a98d1547de4fb2dea292b76d8130e6aa8aff5edf0097de935b252d42a777d4d9b8615ef100000000000000000000000000000000131c9a76109929fc977a0a6eda0a7c71cfc744f5f3654e2221ce84c70787598e24c5d8049f92a7c4d78fdb869cbdd1ed00000000000000000000000000000000049872d2c7d472e090d2975daa64fd96f33e7f934e739633b1d7fcd5e771673ed8820752a0d5c8b0c6933318293a4f27000000000000000000000000000000000dd68fbb592a3957ef893180dd758f75978042add36c91b7bf87c4493b0baa875e1854fbc09e6856688cc241b76ab5a20000000000000000000000000000000006143699816cad8ab7583a72b6064fadb6caeb51c8625ddbf7b2911426cf438534da1bdd13e22cd545495c486c9733f7bac5c50a3a8a37111114c22839c88ce4072940c06f0d8b6d53fed155d0399ed70000000000000000000000000000000006c14301984607d569ad1bd774135e7c9e328be1fe54c3b543276bd06bc0bfff11f299a5eb43b5218c3605011d0ea6d80000000000000000000000000000000012f0a848022f95f4884380a5b8e3637a41e3c399a8d2765aada85dcf4b7c2b559122f792850430681a58ca153be2768a0000000000000000000000000000000016b4cb233e1bd59b7b362c64620eaaa5029c173a05e2278774ad6ed746c70a2f6e76c237182f5d9d790966ae69da5d44000000000000000000000000000000000c277d54a7a72c8528188f6cf29d934cc66471607e5e30d493cd11be6b203bdf734aaf37b686cd7101e8599b69446991c3f37387bad1af3a896a7e66a80dfce2df1709fa252b6fbe4334d02bdced432900000000000000000000000000000000169a3928266375dd5793b7504727f939ef0ed52d69e569b1b75a0e094698b37bc70472578beaeebfd0c3df4bce6177810000000000000000000000000000000008936d470dbb86db1567bb2fe7c09971c6d12b07208d9b1b403c20fbdc05ef8984dd576457fc6989470e40ebfe4ceed30000000000000000000000000000000009cdec9d80f2bf3ebfa9a3316e4250741d0d089245df2fd3c9bba4bac1c2dadfe212682166a0962f78c4bf25b618da900000000000000000000000000000000016521411286cabf3fa2c8f72ca62ca311738fbe63717fd12916a4c9e6af9b05d1f5d65cf60e84d9fc5f7b7645fe9bad570fbf5da3959a49fab7e97b3df3f2a38d16d714dd798a1f04ec2cbf84fce76910000000000000000000000000000000006a827f6149a320a74d9d8c1ae8861c1cb963b3eff899710eda642dae6ed4dbc247a22131758d9f843c62710ce083208000000000000000000000000000000000c83a9fd96bcfd4adcfc6d5a47e84108bd763366e91bf06a7431c6c3a107cbe5647da99ee6c1e57c376d366b21a923df000000000000000000000000000000001604d5c0364afb5503b0e1d52226988d7f7f043ce95e7c0a09d7f96e24a58f089156f0e6d19022138170c1b4b7dd33560000000000000000000000000000000019a11c86f78ce462f46e0462052cc3d342596b329fb62a282a59bbd64c345bd266922b1540e40aac147681754643c2e3e538bcefab5d8d0be5fc143e632e86fc065af3f2f621f293b914980abfd6a0c70000000000000000000000000000000015635de295c16841bf44c73639f047f735175e8906301746837838d124bf0d2a1ebaee142393ce9a0d58107c7cb036e90000000000000000000000000000000004fbbd4252fb901d0737d1bf4da62010c06d690a9584c7631ef5d36f1d8c37486a83f2a1e2db21f05c993fd117c662e8000000000000000000000000000000000f4cfcec1545a08e0e0298753ebcef5f61bfdb7c1b9af71cb4c2f783e4fa3948945d357e8302d99aca96df0cb0fc01a3000000000000000000000000000000000f543dad6d4b797f6fe0b00215a5f70f6340ac6bf7cb0bdfc5bc7698dbf0647e4098413dd19ca7af01685edaaa190c6e30b921d8cd2ca46aa6f3e0dc6ff08d77972fb0a248bd39e90a1e9f32be9e892a000000000000000000000000000000000ed552e94021d0912a0e7563462570cb572b189569eb847bd12ebf976d22343b9ad04d400ae98fa184b10ff36720f12700000000000000000000000000000000178727c3e6ff33be9894ef26347b104023ea0bcf79c1a33afc26ac0ee9879344964fada757118829214cfcdbbc0c5a30000000000000000000000000000000000b0a6a575afe5b0c1e287815612fdd3838ab39e8ee7795855837588614715f6687910c42217ad52c1b8721a9e1c908dd0000000000000000000000000000000018cdbf244c78cae1993400ae164b42c09dab4d8e3707a69e25ffa8d0b96b8270c022c0375f933f16f45c9274132a0a633a5ccd9436b15d4d04a8ee9894c116190062c4e7cfabb047b585f3aa1eeb460500000000000000000000000000000000070636611f903f55cc9499481bc3415a6de62d5e6bf8bfa82a8ce665f85bcf01690118441961ff46ff701e361db208500000000000000000000000000000000013d22dff8f6f86f659ad17ef91d90a70c180538f03e10de20c445d22e637015d51a311a3daaed90712d04c9a3d992d12000000000000000000000000000000000db3535057db95fc262f8adfd7f08f3237fde5f0e2aab589d4ddcd9c23aadc437e13644dd3b3534dcb17936a7c610cf200000000000000000000000000000000044c177d4484c07fb04d1dd477b188a2c157973cf26075001d14d2b07ebb9dbf8e495dc23b32a2419621e1c129b08c5ac7a5bf2cfedd7048be7ac7d2ff19d4f8bf0a94295ebdc5e792393e0e4bc27d56000000000000000000000000000000000e10fd069f2f5fddaa0112e70ae89d1ecf034defb24e2923731a7c0068780177c186fde92a3c254a1cbdd255111a4b7c0000000000000000000000000000000018363e01e86e2e922ba435651ad892bf9288be14b54dda821c397ae6167f9478c8132e92b1c2cb0c4037a4e020f08291000000000000000000000000000000000301b5ad2d5c35ebdcc7e7cd1ebf0405cf204d6f5e30ae6f46d20534eb6d7013682c5ae1bba76d2811124ebded0d2a590000000000000000000000000000000015fb3a8afad778031d04e094cbde5f02dcc89ad7b7d452c6c8f41be336a4c8b26e75cfc685b8776cbe5a487f09c304083563651d5f5729a0ffca6b383d884823aa3b0215fa057bffd8142199a16e4ffe000000000000000000000000000000000a7880b00f6a3e959ff1bd207fa503eff6e7279e701e37b40735e2bc8bf49e355e92edcaf23aa3654bb26fbfb07b5fb100000000000000000000000000000000113d9b792f4e3dcd958664a8778dc4b177c430d8db9da7805595e40293ef2c0a40f7a843bfa70ec134ed89a453f9da50000000000000000000000000000000000d7f92148dca4a9c96c47a0eb284f1834cf3d141be7c0d9a7a060af6e28e45620d8255e465e9a0d8f78b2ffe17d6b04e0000000000000000000000000000000004e7917a8f3070c656d324c9a816236842fbd6147d326652667e7bca0666d214233ed136dd9464c4ac619d46c28e2393833323c3a668541ceba18375531c3781dd98525b49dafce4c4b3188c90f3f4b500000000000000000000000000000000160cb05390b54151f6b154b396bb400a91fa83d77fabdf31fba349d1bf3b5dfb6476ad4d714af2a2963e41b077bffcb90000000000000000000000000000000012885f7ec8e780cbaa90a465b5706cf07d45bda7755ae3477c79adbd7956b926e0ef5303fc13f0b97349ff8b754dab500000000000000000000000000000000009ad7509e9e7f5018ae3d1280e881ec12129cbf825cb6606459211ed7b358a97cbe430e94dd9f5e4f6b74fb7287f862e0000000000000000000000000000000014d5d2ac2dbc3d5a061f4e52dbfa68e1eb1d3c818ba26686a3171e310c63cfeb188030b83407070019dc5c42dd079413d422e21fbffa7d55270eca9c96bbefa29dd915aca266071673e970daa0ca9c050000000000000000000000000000000008ee93fc610712411634079be0bd96c3969b48955fe5478b7a31c3ba7639c18291034167eb62e6b15c16b0dd5145edf500000000000000000000000000000000158cb1731b71905d7b958c5407f090a2c8a9319017719da143a3f4f3fb3982abb83b8dfe14facb014321b4f5edb5e41d000000000000000000000000000000000a9f98f775f06055ac1f137cbc1f95f4afa0d1c4935f536ba2e0569d874d9d76b7b86f71afcea07e2e785c7a6ee1c84400000000000000000000000000000000072f8988dd1ab0fa8037d3620068b34848c65e20dfc90612d123b6f9dbcf9d9d699d5ea73739d31ad54c22116365ab983ba7ea9ffda87131452b24a9efcdc91d1262d0d7550e5a6b787eace3577159b0", "Expected": "00000000000000000000000000000000161203d8db1381722644f87b04f47e4be2ea2bb105ea0e67678bc8d29f8a8a3247f8c05e057af8f98032faa93d896aaa000000000000000000000000000000000d3af4842627a095a2dca99b52d802b2ef8c8f3d09873ffe39d224333fceae84bf74780956904df6c1dcf5ba31be218d0000000000000000000000000000000001c79fae014e55e5d0239645d618593bfd5aef665b3e636dac5d191a8b88949d207cf0ae9822ce8e1997de302b386b8800000000000000000000000000000000136314cc68b372b06e7771d82b7ce7bfd0e9fd306787e07629f831c7aee853bed80172121949a940bc59c4a0b76f0819", "Name": "matter_g2_multiexp_21", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000099434adf799099f2e6e2fda4c905e1543893462133ba216aace25836db37b3dd5bd80af1a8c31c7fee56b5ecf9a0acb0000000000000000000000000000000008a6890e5bcacc13e116e3fe2d772ff49839803e4f81d6b088ecb7835b1ed44f2bfa04de1d46dd352346cdee71774e37000000000000000000000000000000000e94fe40225e863b7bdfab4cdc0c1c8d1399554ebbfa3f2c95ddeda74b3dff03d5cc78e295accdc9f02f3f89b4953de3000000000000000000000000000000000b23f2912fdc7a5fd1de69c1f479228f8ffc9f97c40845808cf17a6fd8131ea60285640d32bcd64c9be71d419aae82fb16aa2cadacb129598aa459bb2e6b7fb26d1bcb7a49617b6ef8e57018c3db1f510000000000000000000000000000000004c6f5aaac90132b2d0c6a4e70354ed2e724df7c3e6298eb9ae4ea92e3c7981944c89140c52e893ef2edb2773ab36bcc00000000000000000000000000000000021e813378be9ec30395b917ded5a0424fc7eab0abfdcd2328f725bbd6a1dace0a5aadebe40e10470df0c09b3f4b68440000000000000000000000000000000014e3fee16a833f8c543860ca438d763f764f488463601741a2331fa90efce9f6d54ee0fb7978460a1ab838039d398918000000000000000000000000000000000dec8bb882fe6028a4155e6e2bf48ffd314b5519dc4560f8f7410209214c4a8e37b2b36facc53f4db11ee63ff11f9f228c02014d5392d30863a12102d1c9315839b5611dccfdb489207f9186625138500000000000000000000000000000000002d107029bea087a2d53b6b371aae06c695fa85631450f4ad92c8948b09ed568b28948f80f1455cd22e2ad44697290b00000000000000000000000000000000002fab10cdd8bf17a633c8b3ee8ed2ce783f64bf978c384fb7dbd7e4f0da50b65eb9530365d982bcc17ab91a29eabc065000000000000000000000000000000001369237fb3241ac291a868e6f4610a5103d93aa915e954f18bcf348ece1560a12451723b96ad5fe162a6107dabe1c986000000000000000000000000000000000cb70b7064a2f94efc86060431ba4dea38bc64822efa73c76f3a4500ad23c452c8f2e72713b066a45bfa49559d14a719d960ff678e1b46ada4f866adf354ba8c1514df10ebe7d88d2c8de117ef5ea2490000000000000000000000000000000005ebb9c8202cba234851cf5e060a4114c6fee0632f37e0c52aeb852637f362ce64403347d336c32617cc59f23cc7c93e000000000000000000000000000000001126827b6a0a8adb698854c0089276861e3cccfee420512f0966df78ea0d9c55e85a0536f14ad40e649b8fe4384c836c000000000000000000000000000000000998549680649b294d506c529ade746aeb087f75d62a246b7abfb69397ed67f0f2ccb4811219b35aa894b2f87e3fcddb000000000000000000000000000000001027b604f877ade32df8de6162251acf2751a9bd770c21f22dc819a4f5515bb276a246ad667fe7881965f0b083d1f76304753af76295f72295645243ffc87ffc2110c9d8dfd20b464760ad965d7a97940000000000000000000000000000000005d1484bad44069b16d1ef4e9ca1db70ec6cd82eca645c2fbd4029ab4ca33d79780ebc144d8774d82518c1fefaab38530000000000000000000000000000000019abc7063361ed64a5750b70bd59283e6a61d55d49d8c2ea2f1be8ea425f040d3865c399a66c253bf38355360f06cdd40000000000000000000000000000000010a97b13b3b579ab5f7fd9801d9e4fc40f3b2b2acb9f21bfcdc6b6a3168720fd0abc2f77ccad01be6a6e268fddf3759c0000000000000000000000000000000004126b5454050d761047e5da23c0b2f9370996589c04f255a1ce8ef37a3a7c8078788a0125e4aa86aafce8df33f322d3d1b8760cc40d093912fb073c5012f910ae90f0a979cfe6d81c603adbb98289030000000000000000000000000000000017aa7a3f1ebbdec6abe12abea12ef50a3daabbf96a5f2ebfb517885f0b7aba1e927c682b15521529cb9e1f87c59be99e0000000000000000000000000000000016e23f7effbb9dd34ec1f6974115e7f0d23cc4553d86e6d61a0c98f47d09510e06b3f987c5bcf4bc30e20ae9684da74e000000000000000000000000000000000f3905dd4f99cfcfa6152db53106b4d1f6e24518a822da9388d8ca1dd654a4b8315697328571691f105d1abe9aad3dae0000000000000000000000000000000006bfd10d33df9326a55b35aa6d2bc3e831d4c3b5959aaa35613156e5e19343b74e34ed2670c43ba1a45cd3d91f055c9aab79d640b042664b23667d6c60ef9a5d59de72aee57a78d75752b350ce56d8da0000000000000000000000000000000016ca071d741363e7c3297355e49cfbdcf03d419813ed7b329cb2b2a26fc6a46cc52149ca3e9ca3ccd7284cfed97b985d0000000000000000000000000000000018da360fdee88e806ea1a61c01e86687f8e5359730c36c876ad2acb0297bbc1ae13d790d1edaafdaed65db9dac02a74d0000000000000000000000000000000005a46e4572f667b46aee36b8d377c249de25e797b31b822474aa647ee68cc7d40b083fd0a1d938e2b8d85508004c73f40000000000000000000000000000000011701bf88d4287c98996ea561c1ab2f29a5da9138338c7c7539a5fc8355efab6f58e240df4b0e0cb7f01df74bc8010501d1a2965e995bd4380d4ec52fe8e65e7fd99b1ca9f4f0c656adf7051c4b9a99a000000000000000000000000000000000576e79e507d250eb4040197064b8898b0142b3a2551875935f91f22705bfec6da156c7858fbf77028d4a00957553bea0000000000000000000000000000000015d39a325181d6d1a809b1236f4a1ba66a9bfa6c448470425aa5c8ef9fd00b5481c51e8752088dad62e928b3180408df000000000000000000000000000000000aafabc2f68a4933c7d734660e422ba154e37dd90114272e948f79db4ca51d5ca75d504cf74f2dd0479871d69a08386f000000000000000000000000000000000b017c731f63bbaa8fd0b0d9c17140060429f515d2e85a938d10f6529deeae4818c29b9a628802d0ffbbff720339b7bf2cfbf2abd851d2c1f55c56d4f8b11b196c020c2584cb03764580d410d66784d400000000000000000000000000000000028c4dacba5f33ba66368c19491f4baa6aea4f309afafcc8f464f2886b1d05b6397142d02f0295fd50825819621673a1000000000000000000000000000000000849e1b630e8db8ef039f280f8d401957f807ca90479745b68c3db1b5ce3a02fe2c099ddf9c387d7ed76ba75d6a9be9700000000000000000000000000000000013b43fabc3d4df82058db215a69776ed5dfd4c773d7a013dba3b4ef5cf65e25f79d7f76a06ca99132d6fd1fdadb59d400000000000000000000000000000000072cde8eb3d3e1a7f7e4a9eedb8e56f5e103db6de6ccf833f818f02a0706b2043d4ba0d5473bbb6472e8aeb28364e1d8214edaf16742762baa58a3d22d5bb2305cb03a1326adc68adcd268428f82a1e00000000000000000000000000000000007a33b95f42cb1d1ddeff3a199ccfd9a5d47c9fcb89dc09b5b3f59dde2b47d24ff29931920b76ecf6deacd70e83576970000000000000000000000000000000014c0a63e0152f06cfc32e6034b7829f9d9d09aca0a6ef821dc61ae8d99b77d76c1b2fafb2a14938a82ec72c4041ebd9f000000000000000000000000000000001433135cd913b05b3f58b2e9c1a3bbb951d2cf6c92fddb21bd5e1d9c44e464d5fe98f0791044d56e50b81a83ef6cb271000000000000000000000000000000000be12ce3bc47bf69a13762343b5e39c2a2f285896e5d1b73c55203cae2f32cccbb4f7b8230b2026a0c8b2f63db5e5bedc1f38916d6bdd5d379967dcd058ebce5887ef2bccd5fb7c2bcd758e374a195e2000000000000000000000000000000001494984d478784b2ab3ba27464109f99172033fcd5780a48fbd5a2144354157f6fca2d70b15b0081dfd306ab4239cecc00000000000000000000000000000000078aebc22025af53c6542abe56cf72ce5eb11d3f19212a0f7442d0a0df907c8aabe0ec01d1245ca237a691e685011bb8000000000000000000000000000000000415a1804a46f4595014ef29b12d99b89600aab1d98352437ab8342abf479bb2215bc687532e75f140918b3d030ad4520000000000000000000000000000000015e7b0dae7e3e80eee3c7a9ed4c739288ac2192f7d80b2c8cf9934cea5719081803b207623c771051d7694e705744dbf1cb8c8303157f23987f8a2d206f3add697b9d0a303393008429e93cd35711f74000000000000000000000000000000001470f82372e197a21aaf46cb2bd3c0b77c3428bf2ba073311e75eb65471a8164753ff1d989560f1ce477952bb6555200000000000000000000000000000000001645b5e5b4bcb5f6d34ac841e3a80f09a86a5edcb7f2a7e7bf549b022c0073e01be82e4c9e5c8e8de76ba367595639af000000000000000000000000000000000b43f6572553154e2530fb448d5bf20c3a182cc190149d3b1d75b60e45baa048f44884500fd02c434f9f7eac01dbe4170000000000000000000000000000000014adef5a52d76a267f87d9a8b5e9f570e7775ca4f6a55a5afbf80baea311b1866fa0689271799a654eddcfe36a6bb64c61ca9ab9c3df673b7ff8be098cdadd8354c17becdf82e7e99ce264174653007a000000000000000000000000000000000345a2ffa21eb06fa1d76fd81b1239147688093c6a44a40cae37f2af26add812884bed3e8b4643675b1a45320c64f7a8000000000000000000000000000000000c58eeb5ffdf886d6319ead9e6e190300ceb91d58abfb79c0a322de3987eee73ab82092eea8e1249e83ab67e33b303e1000000000000000000000000000000000763a3fba513b6731fb501aab39a4697f3e4de89125c6884f9782bfb73e6e062f17d34555a04a8e2959ee4e1a2ee284100000000000000000000000000000000024180dde2d23cd88cd29c8142d32435d0db57b8ce8e309701fdb963533c1cdc2595e3bfc01d8c0d08d594e096afb34a681a0861df30946911d789a5da1f5b89c38fa1a8c0407b608122a18be05955da00000000000000000000000000000000022d2e7502c4d9587df7ecdbafcbb813b1812d76655cb7f9f57418d5ac83d4f60b84a0ab5b53a5eee3c3954aa9fc70cb00000000000000000000000000000000083212aa1316561a079cb8d027bc8f89161fc828d050c8837a24fca6f7f94b6dbf10d6032fed895a427f07827deaf3cb00000000000000000000000000000000021552b99dc02a051ea3af1b1bbd0a7ef64088c3aef4a58b18a29ca05e1f442f8ea2c8fdb3642ee94c5df501ff6898f40000000000000000000000000000000001015a7987d329cd1eb5f991c270643a05b8e1bc35467130e9f53c5d96fc3c8336a00c060dfa2d3165358b51b6a521e56f0798b448ea0d10c84e2a8896f153b1ac3b84c5fed6a4ba6c932260bf01d34e000000000000000000000000000000000c19c3b9d7c7f520968d8531966cccbe6f0c3fa0938480ca3591b7489febdabd56a70ae55cc309e04d7acb3de6f41a3d0000000000000000000000000000000002ddc64023f0de2730d3affb695927eaba50ecb91cdf1f369a511a8cc8dae8913ada2d8f27a65e75deb9b8b648e4e2e00000000000000000000000000000000000311ef260debf2310fc31fb8ecc802200e11400909eba24b14d9500ff47c1c36ec540eb970c9262dac947b0c2053d6200000000000000000000000000000000199c19645375dea7602b74301adcfd9af259e1c7c20f377fd10d56b719f7a6e0e57d780c976124e0675c2a54aae3e0f5a8b7de8f34053facf1338b54cfbe38dad73121a0429663f484277af9a230abe600000000000000000000000000000000123fce6b793de0ce2d31f2c7c4218fb20f9db68946a7d57914174ea773d6e6fe1fbb1de141c742e0a8154fa1d81a91f70000000000000000000000000000000019f75536e004a61c6d7f466bfa06ad0c9375a1028eb7746406e7c71e551dba249b5c6284f635fe26989aeea69075b3fa0000000000000000000000000000000013088eab16ec77c7ce7e84236337e395690169a4ed7e44e23d233d36d5d25e6afde794cca2bee88fe749851a71aabe24000000000000000000000000000000000e627130da43a6ede3bd6f2fcdf008c8f5c7b7b1fa56cd3b367d3096317948bda115d732346e73b731d1921a1da6aaa18823cdb73dd076ad95679a9d7b11145c12a81b825477f799300d1fd761417c2b", "Expected": "000000000000000000000000000000000e3b85a3d6628e097a3d962f3c9aa37e3c5be43faf2a12cd9830ab33c4a904eda23027735bba563d38ae5ae8b302864b000000000000000000000000000000000c92be62cb091056d981ab8872292017cc22ae4eeb0cee03a60cb5d57d37b264fbed2d752ae9dfd76c0bdde1f1dd10500000000000000000000000000000000019e172b23249a17924b890cda6a65287039d0c32b2c0833409816cb21ceb73ac95928234ccf566287400a2ed7d9de771000000000000000000000000000000001276e206235392fdf65e4ea6210d22eb7afd7783caa0777ff0af719cc1822579d5b82fb4c30f07dffe7d68c649b9e2fd", "Name": "matter_g2_multiexp_22", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000a3d974770eda8c742e5d380482d36fabe18901b0217485141c3841003aeac4459ee28b280550e4643d0f50862bf2e2000000000000000000000000000000000369c2bf3beae4e8761f6c06d9bf5261bbedb177e609c81c9bd81ed0a17573b6e10e7f0512e06109cacc3d483918ed9400000000000000000000000000000000030253d0a050986f49c77ee20ea8e3e07de3ba72c39ffda877bcfe569eeb29598588f5a7cedd9e2e34491a059ac4e707000000000000000000000000000000000ce201f07353bf82ec894ec66c7012d17f3c7968b28b45e88f091510e1646380f902c1c5b036084f9497e9a91476dc2c9f2e54f21b7f2116c30d6e444ca82fe800435cbbd72a98a6d22bac92039c54070000000000000000000000000000000018f493dadbcd93df2c614af310e5aec4fac9e502843b8ca8c3de739315d9e9a380f826e2470c96bffa8789133f458d0a000000000000000000000000000000001768f8c3da107b9ac30a12b99f2f3a0f21483c0be334377733cee6024d85af91b03c7ea1c548b42e7a7869141816917a00000000000000000000000000000000076cfc99c16c270d2f6e34aff84832f9ee6493ab757b6361cc921823fe9c30f1c9b1664b650548dba767616bec0fd5d80000000000000000000000000000000006c5f580c9556ed31847b1a3527ac0b5b5f15b9c9197d3cff061c1cf72dc5c96cb5fe98535a4dca8c4e20c8c02158466c8cecea241dd6a924c9b9cc3d390fbf40ab897208ce9d3e4a148b2c30c25e7eb0000000000000000000000000000000010e2d7eb4e874a9c72a98e4c36701a9fa11051b683ac8ab9ac20d14929d72ff7b92a9048a11bde92dc2696467fcb48e6000000000000000000000000000000000eb29e621e9d0af8f661eb1ba90b307eb542dd84a486568f85e19055bf7b8f0a76d34acf276897a01349eff2c36e4b43000000000000000000000000000000000b5f890f22658b207dea2d721d90a8f5991ea2c5ca06b8d1b293f60959ed424dbd7052e010e594a5ee0feda1e93bcef4000000000000000000000000000000000082cdd4d8452078e8b853f196dd76505ece5e98df3e6a8bbb21f422755af23c5ab261accea48d8e4193d6c884773cf6e428fab2c596f23bc3c9e9855b74295f52caf73cb7371c93c65370583f7fef4c00000000000000000000000000000000077501a457d5f0946d25a4c5eede1b7fd80d90d502bca47d8cc40ab2f9a6d827d7323e7d4035f3d32b02401141f0a89d000000000000000000000000000000000985410246c1db01b42728ea46758906883586cba5618b66c21a3cf58cb98e7c6e0dfbabc5505d1d11ca9d047fb6d25f000000000000000000000000000000001775f4008f688882d02355b6eaa1ab108f239890f71238b36c76228cf2f575cd15f15293a62a72f6ad0ff17d7e8ae79f0000000000000000000000000000000004b6967a5ee180d8b92e95c5ef26baa56d8509e1acc710237083d19269c1c5a1f2d1680e85f0bf040747be1d301300b0f7d3d755410f77a0e4b2fad0f184fa9312b559785fb04c6020432465799ebe22000000000000000000000000000000000fee170589e8a3d3fdd93b536347af5002e59e8ef2ac8327a7e9f382560ee9bc36b3f636a3f99fba8be7b5ea3dfbcfc600000000000000000000000000000000032380cb6c043e3f9ef7169da12df1c6529d776b049c7061df660df841840933e514eb7ea3152ddac38daa2c52d66191000000000000000000000000000000000620ebccfd931eb70ec688110975ea24b7ee0f9937841aa1b7bf4f45af88b732b76a26299f0fe48259fdf08abefb4314000000000000000000000000000000000dee6bb8c198363fa4107996331aac07216b82208242c73736be31e14e4e04d97a56a1c22479dd94997acb0d32abd3b0557b05efdd02ac9d8e1453c82a321d798f3106bd18764140faede610ae01fa80000000000000000000000000000000000eb60e98d6cb4e4b3e58271d47261d05be892eebb9a37f6831ff19d0bf2fc235e655f0eb9b01494868bc082c58ed82d40000000000000000000000000000000007254a64a0d94340bcc2b0142faab2d73e8189dbaf52ad0c3a9206e802193168b8eb03cb18b0e4f1cc95b98b943910db0000000000000000000000000000000001e0051fafaf454072051d2aa9512ba2367778aa1617cecf6a7f989d69c7627c9070c349d363f56711f172d43f5730cf000000000000000000000000000000000f4141c8a45448fecce09908ddb42f7b5f6b5bb53b9e1ede0417bee327644af5c98470e8b5364642fc7435f84be1ab443313884abc4d430c06ae843d263f2efc1bba35f6cc270de05551e1f86096bb7500000000000000000000000000000000049c28e0bc677ccf54f4cb46e953a057ffad624752332fb9ee5295438fd5bd61abd2199a0bb729bb7678cf3077e32ec10000000000000000000000000000000007138a996356ca3f5d63bb5a36dfe901254459ed515e18ec8d91fa747a691b40a19878d9a6f1dc74e4f18374a399d38f000000000000000000000000000000000a621b36a3cf04e6a5cb699fe4ff7fb8b3361207186848e81972fdaecf667ceb35f413bd68772f7c1f77c1d3f43a3d610000000000000000000000000000000010becda5a06f3f077218d4387158e4a1ca5e0ef24d4ed304723ed5dd96da7cc9325f7e4ae16d9d6c348577697aa6017b8faea236e782a8fbe27ab15f051ed007a61e25247f1f259b9300974f521f30c800000000000000000000000000000000163ee307e0d0c3b61ade05a022ce2bf315d820ee8ece60f93d63a150e02be843a2eb2240a4882c29be2c7403932c348e0000000000000000000000000000000001fc8e9ca23e8dc8457df8f255db3b434f52cddaf05819dba7df1c5bfed438f756c8b57442197af18bf83fe9ee2b765200000000000000000000000000000000109cbe5279ccb592bd0b33b1a482df53459c48cd0913549739b784ba7ad32872377c2e3924c4d45064b0cc4764220513000000000000000000000000000000000d789795d556a37a375d83120a022f57e26da6e6f9aa3e40e1f32ed04b50fafc4d40d0b9b20a26e4d230dd789e20823013994f5645c6ce83741e48ae472674921bb2d9b8abb7d04ddbbb85a3f2f7f090000000000000000000000000000000000960654bd6e6a6b2f7d87c3c4d6e3fe6c684a50b62f7acf82a67075139a614c056a41cd49769960e229cf07468fc2dcb000000000000000000000000000000001727f2dbcc8d889127060de0079207eed1e094259b59a20fa42ab2783bfd176da00e61a65709dcd60402398fadf30710000000000000000000000000000000000c17805a01e64c320601e0ef521b6573e9c2eb354157cf0412e5c2b13f826759310907c4b77164f5899958cd30f78c030000000000000000000000000000000010fb286ce797c0429ad3385c709259b55cc962ae02c814e537e5261e897b7ee1b7c660273ec908110f997b166c14f5c181eda24db328588e8c670ab70431ddeebb0749b431bc1bfbd992c91f35d59b180000000000000000000000000000000015d96a0f988f4951206aeda63af85910db49ab817c83e218ec74cbbf5f34f81279d8a3f2fd1f3000f73b8c5550af3fd600000000000000000000000000000000186d2eca1cac226227d8981324859126864b84e8dac563b4d92357591c2416c93989cfd9e1ab6ad257dfeb168d829a09000000000000000000000000000000000a8a7247a3b09583cd2d4949721160573f1f88221e6eae833128914555a594f21a3fb2bfe3b1f01f3dee90f7772dc97d00000000000000000000000000000000132361ac1950756549c957c174cab9ef586eb2057a4eb22f49252cae032975f56eb0cb7ea70810afaf5716afde5b88015bf25b5070829e3d5a66ad24ba9930f3ad64767c51e432b51bdbe2fab470688d000000000000000000000000000000001328e22bb83331adb09dbed0a8c58040a3564fcae0ec85794f26c077de69cc0a7555f011e028879cb3aafac4dbecab33000000000000000000000000000000000a93db348adb3886802bab1e993f5d7275360a5b0466845055d5274e44716f3e1d03a6e1796ed4de4c157dc8a2d92c39000000000000000000000000000000000dc0879a8e9556b7d9b6d5dffce5e648f835f10acad3afca7a73b0fdd5d5babaa74a1ca80aa4f6880d9b015501e218a20000000000000000000000000000000003f7ae8207de4a179ae48cffc8c6e926455e46ef9e109c08be3ae7401bd36e0876642ae9ac4fd75a74c67ffb7790e265a9535c082e11b366cda0000d8ed0f92ee30fd2c4364c163a718518321c5e85d2000000000000000000000000000000001078f43093602a2dacf9b5dd7ec41d47bff02e0dd27a996b58c73febca06e3d977c2fbd73f63508243696ab5d8b97b980000000000000000000000000000000001841869086e850ad97b3122fa51c437113d2bca14deaef5715c354d3845f6829f6aebe668844352d5af3509c0d8da7800000000000000000000000000000000047c42e83194143b9e977fa1babf80d455fc86cf6cb491ef8306a1c32bbf8c868e11bb3308dd5f65fc2942b3e49ff5c50000000000000000000000000000000000872ce87ecd22b39b14c9036e971a562d51c5122bb10939cdfd1945dd1445ac9f5de06b70931aa5c86cd0fda51b89952c4cb49adce0292e259e92b229bf7965864a945de86eda3ce0bc9f1a6dc8b7b200000000000000000000000000000000157820de2a134081eb47b1800ec72630348583d77d512b4c6a8c8e581810471a2f57a8eb6b0af87a91960424009ff124000000000000000000000000000000000378cf11b0a2848b06412aa754ddbee5660730001db073724caf902d4b4894959f035a8838e28554b0efc2388f2b4f27000000000000000000000000000000001301d15f290dd11c3f8e53407195e02dbf8f13e4fe25fe38e84740753b5a0032f8dd07df3ce46ba424f6772b3aa66f4f000000000000000000000000000000000d166040d457187232f8f38f2beb1e0e0864105595764022c282867346166e46eb789786a7ec7c00b0446207e9ac1ec05e927f57aa85b2df54b4bddaa041d43766c8929c8b9146d723806ee0cf042275000000000000000000000000000000000793797c5bce4b1cc3bcd751c5ae1d293477af96a0e7c6bd392ab4410f806a53088cafeed51754ee7e60e61dc200ccb00000000000000000000000000000000019d595730af1f3039e37494b86a638a528d8bd24c429e3f8bc97076c7463e7f2618e23bd3f300bc7e7a4674f14f8295d0000000000000000000000000000000008e245c7590888fd8dd58f93332b81f48b6e3acd3cfcf5f3b28df654eae1172f52ef5a121707aa9cb111b0b402d1bfa6000000000000000000000000000000000a7c6403659e1a0c2dc7cc2e9b57a452bf553e96388676f4bf4a6e26b3ca2d3cb82006850d8340dacd65aaa0d20e6fba606ee8a5fdd9890b8017f6c432a45517d65328f13f3a2bb42d7115c02929db7a00000000000000000000000000000000054c37e8acadcec8a795619647d4cf1081a0592de02bef916f847936a1736e74cc3b7ee018717495def8b4ef1d098fc9000000000000000000000000000000000291d89d152b414fb5e7139d6d0bdc7b5b9de1fc44b49f895ae08718b631f7652bb4a895fa11149b9a9db30c344108ed00000000000000000000000000000000107b30992ced35e4ba874e436bed5d88aadf0a0c944ca3eb8319539017bdd652feb7483ab6c705aa17e845723b2cb46a000000000000000000000000000000000895dd8e04114fde4a4cf19925004a72f617f2ff146dd650a2cdbeb12977dd2b34ea7d655dee16ad9560b144b81212f5c1a77ccb4b32a762d60b37827ad6c3448c33af6af861c131adb5920ba3c2b85100000000000000000000000000000000005cea2e036a8ce057e4dbe2d9d786eb759c2a75934580480f78d2e228c3150a0a1d8c95ac5013aae3ab6e35f524d37b0000000000000000000000000000000000e18c18884209f9e4fb17431248a5f8d29c616a58af16e949f4317c2e117b80d531a39800dc70f6b161b98ba040a8af0000000000000000000000000000000007c42ce885d1bae906128589b72f2e6c18e4eeacb78c853e923e6eb785c073b6490b2f6b3dff2276916d96770ad5019800000000000000000000000000000000132d809c37c341eb0304ec933a6b11bf9ac0d2a13ead818ab6ee03ccc94160b405066381dcdb13b6ee3f5dca48ee10ef47cde609c38eabf457cdbd1e0c5366bf523dd5801d66a0282bc187d80417f455", "Expected": "0000000000000000000000000000000009406918e2dd6f06f4782ed110e29516a911f47133ad8adc58f5780de916a8973ad60e05ba931d66de7545a92f388c20000000000000000000000000000000000041cbd52cad2a5f4c8353c7153b5711ec23fa8bfa2f34f5e1a16d8a14cfd47c237766880debb992a05ba9ed0353beea0000000000000000000000000000000017d4211c827379b310956371129011a92d62d11f0ee5b0cbad9eea2d3f2a95d364717713fd0c544747338725adf27248000000000000000000000000000000000a61903fb81064614c9c6894c7f3954aace7611cedf6bab8e751f0c203bcab827d296016947c071d7b6ccc742e28ee9f", "Name": "matter_g2_multiexp_23", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007f90813f8c3eabcef04dc1bc9bbafe1dafe220e2db24e4b714aab2b164d7ec9df3e6a3f903e8b7b96df2ad8297381d2000000000000000000000000000000000e34371e51c4c952a0f38c4aaa5fc2324971ade310af2f36ed511fc5fd7a602a551ef77775fcd0f1fccc718710239561000000000000000000000000000000000787edf7a6ed6b50afcd7c0d3876d8919273428bc49833e3503f650e48e788b15cd82eab2672f612025d796bb62d72bb0000000000000000000000000000000006b49e631ace4f72c959919df5d64c537537ccaa3d1890ea9a1d70f9eacbaaa2ec361edf2d4880c9810976c6073028bc3c79fe6374bf8f91bf7851ff935a124b54fdb5db498d2d37939fcd43bb93d29a000000000000000000000000000000000cb63d7eef2d6614d1f629756b3a619a221033207d1621e4ce4791db4248500649b91ff07cd2f1f06eae3a9be5b6af080000000000000000000000000000000019aafbe56da1569959019033e8cc785c9b98bba6b069603969e7ff1150f023706b461913ea7949306a44c3b7d199e86e0000000000000000000000000000000005cdc3a7004f7a7f79ffbf4c4ba7c5dc30ecc62f270a5c231406fa63d82fc64f45e94779cac851ff8443040fd3b2ea6200000000000000000000000000000000040f30dc98e8668194c9278b189e0c0f7b76a4c686ce26a4a96b93190938f07c5b813670e206eb6b5da29624a1b6314ba59fcd2baa47621ebd90c5cd12b89f2a533ae86d537fbb61a14b1a80982c9257000000000000000000000000000000000a5a1bc231f803ae272e497f812ebb663c2ce8b43a366717fc6349264823ca93e29e30762c1a366d8680f81838907f59000000000000000000000000000000000a88fd59ee380449d632d7e1b926210d984d5298fa807570a63a63828cfa55c6e2f01b7745848281795dae36e562181b00000000000000000000000000000000025ad34537909e07beaaff09f22e91e76d93c668d1b45cf6845ab8ba0129e417b758e85a7100a31a9037e307f454bd370000000000000000000000000000000013590106126231b1c616a5dd7aa7ed6946aacdacec963b507907950d6ea11cf1f5b59f819a43eeebaf51a1faa7daa8e719ef9fdfc5f0c4ac41255eb172d485317c124211498a8b9a74c0bfda15b986c5000000000000000000000000000000000938d43b9747c926c3e2dfaca2d6f1e6d61d5a621ae08c66a5baf33d9241771509689f9ea7d75af607d76b66faa8fbc2000000000000000000000000000000001889a48a74966b9748f4a6128dc3d75a69499db1ba1bc9aa3a9428f0efa898b5f78a9e2dae942d3794ab3d1157a1d305000000000000000000000000000000001129c9bf343f476541980b85229c5c25289ca62173e29b75de431b572c8f01f64ec1aa4625dff9e7df535194c7f4e6e7000000000000000000000000000000000fe95c71f703dcc71cf409b332f66fd69c330758d41832236a510ec4bd9a28c4732434d4c3f97445e6301e3070153dbbb8ba028831f429d027319a92fc0f30def8b97a43da456ddc79443d9f8df72cc10000000000000000000000000000000007649efeb3e0bee49b9adb13f8e5d7db1c06d7fde08a3f3082194153bf4b3615aff1450e47fae88ac93f55a389a319da0000000000000000000000000000000008334731582fb1b6125d7ee1da0124fe88f0c70a0a3f6188636976c31ba6a72beed927fe598386f328e4ae534729a57c0000000000000000000000000000000010b57d80fce5cdc90bc93b3bc7a1affadd19fb00aeec2ca9a6287bf4e40fb74616986a44f2f7d945f58501a965f37f3000000000000000000000000000000000180dcae46ee41bccd422b3cc2b34cad26f6816dd08ba51b2f12835e7439ae2d46933de28ac04bbcad68a188e7e90ee8dedf8a6d86471f58c69c1a5e7518c69c34165e72ce84fbe0b7f69d9c2717e5d4d000000000000000000000000000000000b419b675ccee2509daf66e5da4031b08792e1181140b30489ae21f7925305d8cdd8a104580ae5938586d6b8e74f750f0000000000000000000000000000000012e070ab7118991a20b27f1a87fba1f5815665d76269f0d3d460a6b701e57ffdb4fed2c53fa63a3121c74f67e770f31100000000000000000000000000000000124218ca85f235eac3471e0acdabf73f79afdd4bbc159c1e34c641b97f03735e4c3430264f2d94f640486488dd1067380000000000000000000000000000000011c24f4fa1862779f22a628edf9d3cebe0f7593964b642f889201ae85e8fa01e00e48355053f5a7c6d920dcf6a7ee1d60dbaac3f5e25ca3d1d50ebb31258ec4450feca1e02c84672ef15c49b4de2cebd000000000000000000000000000000000266bf0d9d5a4fc713dc0fcc6ea6edae0b326e22cd97bc49c48a7ba398fc87d7a0c7141ba24d80df454de66c2b5a55fb000000000000000000000000000000000aa8f95c7cd61733b0a260149d6608a73d6c1f989afa8cb2aa4098e1fb5a66b4ad5a5c1c4d901aa79812385fd507f02e000000000000000000000000000000000a6b4929df13e1fe7f0a0cf699a7fbfaa97d7527cc3ea1f728ba59def2e75fcf3490199bd42e93b7d47985a307add07c000000000000000000000000000000001719321981d2085ba31c9fb131d6b79c7df5d10d6ad0b5015454329697860121e781093fdde1f19e897dd6f2c272f87a109ccbb8fcd4d4651b84f4708799d84ad0a717aedaf5a76d2970a7b93bd23d37000000000000000000000000000000000431002c9926aa7d2b06412f544a868a7d48fb5f077dfd098febeeafc28b876c434daec809e5cbf50ff2395ae7e456560000000000000000000000000000000005a15f713b6eafb09495cfb1c89e9421515a07a99ca0f208883f11c430ffe6f2592dbc41bcee5db36385a26f67cd26bb0000000000000000000000000000000008dd30fdd7767486844967c5da0803b52282178287b8ef28e14f07b487132fea3a82d86d414b4d0a25b3dc538be11b500000000000000000000000000000000002dcee67e2d17b3106dcb9f4117456a037ae1996e8f7a09b179baab1ee8345c6d01eae554d3f40da86bd79a04702fbf76326fded2b8a3fbf7637bc25bd201d20e3d4d724806cfa678ee039a39c24e86a000000000000000000000000000000001629fcc374e99fa8303a715fb5077f266b13367bbc0098b5463d3298c0892f83127d6b7f751446575b88858bc742586c000000000000000000000000000000001100783c10618752d25c235e1e76dc64db94adce05651fb8df0a5ee7c299d35b1319f7009b857892ddf9e90c91f7d23b0000000000000000000000000000000000ab6996e4935131becd5df288dacfad1e69b41e200ca7dc841ecc180a81b9d2ca14fc8a76a4e7bd6f924bb9f473de62000000000000000000000000000000000ae9b22f8dff29e5e0a2ec5b5641f53fb5e1ca03130b49d0c26696ca4b439a9d998d9a364ac9cc5ec52df699318cffeae005efa8ee75dec8a013029292976e107a507ec09e3c34fb4baf2979fb759f1d0000000000000000000000000000000019c557ae1c12ff8a7c00b7c9e4bc3d65c92753549c193311a38a84bccfc090052a2219461a9691affe2d67ea4357cdeb000000000000000000000000000000000cd35c5dd126bd4b90dd671f29953c5a49a14b6b3fe946991416edf235c3eb3d574613d27b05cd879518fa7dda3ed39a000000000000000000000000000000000224392063b0825fd332bbede23588c1912e7670a013a99da5507f650dc4284431698a5b4e8c180269af8bb30e4fc8450000000000000000000000000000000002ab8d3250d4bb8ceecc8ca2003f91420d0ef8a7dbc2361e5e7fbfcb59471a4c525856bf796a2c2608d219d215cf83fe3917f8baf17f71222166cb9b6c4beb2e57d0d054cba3f7fd3a28cd3dc4b409490000000000000000000000000000000000911417908c2bfe4f63a388f699b31b47df1ea0ec289ee3f96ffd0c71f3deade00d1841aa56b4bebc2adcd3068adf920000000000000000000000000000000005467c7e58e82089fa285c28ea22c759c7806d86fbdcdcc8e09e847d6330922a61bc331ae3b5acce777b7809ca98213f0000000000000000000000000000000010f376fb47933b1f701dd81cebaebb2d8d8f5510a26fb3e9e156ac5ecf2b943c5fa2812d52da542e6c335abad8ecce3c000000000000000000000000000000000dcbf467432acfa4eb9ba11a7cdf02f9110f44ac371128ff8f1f98fc70e4554f057a4608180bfa54d99fd2da010594f6f0f73e1b62561f5b0fbc409e6534ad9e37d1c0724b35cdd3f94bf6489e500fbf00000000000000000000000000000000179aaa7119f6fb986714c03b6db16f25eca7172d24cbdd318bebb633bf08920f9e2a8136c94e3ec7c19e57ab51531b3f0000000000000000000000000000000005937c484213ab5b2ca8ed1c5c90e8d2a2f1bac044b88c04b301ff2fdbe67dc4ea42779d919ad510cabfa2ccd178cd9f00000000000000000000000000000000183cc23fd64514ead63f55d375a07af7cf2a56aca64a887dcc542f8a396468a6abc776170a5d4b4bbcd4dbac285e7ffe000000000000000000000000000000000ce12228dec2f84219904d9ac7923f122a99803a9b34749ca68ba385c178811685c19a492aca2e1123ee82a8a9cb90fc3ea24fb6447f2493c78a267daa158eabb70c1b60af8175d0d4594c99122cb4420000000000000000000000000000000009612bf9130e17110f8b15aa6f3317071daf3433bf6d008c383bd5c2fdc7ca03f25ff4cdb483de3c84c0ef9e579f38c6000000000000000000000000000000000c40172540a7e20eeedfe02c37aabac07165cbf04830f20fa76fe8b05c826e7762c9f7567a0fb972212bf736e627948a000000000000000000000000000000000f49e5b1929ad3ed5c07670c471710baa24e8478a50f72a5b7bbc23a66cff91d30a3d68961fbc2e6e8003d08196f325c0000000000000000000000000000000004ba098f915ba9e934384682648ed8d4e1cbaae60d596655fcd9c05f4b049ba0d278730dba5ce3fd4892531a3153bb955ed307c01d9e29a0571de07c62d5fcfc80749f02b8dbaaee9f69dc9263e99188000000000000000000000000000000000449b15ecec6d6fe5cd32437b54218f62527157aa6344c635fcec8f8305c8b6e44c93105984e0832536237606f07792e0000000000000000000000000000000011e40e8aaf75f5ff8e4040f725ac27693d7b24805a2539ff54b3a6e90c048875ea9609fb8fb3d8de63ca1118876c172400000000000000000000000000000000006ef2a24445f728b53cbf01e5b076acfa7761a84d8261cf1a1b99cc32f330f32fa5ded83d5cd51cc284207adb2451ee000000000000000000000000000000000977966380e772670447b15ad9917035273eb71a21c37607a761aaec808909fcfed50679769aee1573d73cd241de6624877f31ddcb55d961bf9bc09903bd927451390922d647d589302855141cf5cef500000000000000000000000000000000074e475c0ff1a51a24be3c964c45c41f767f890dec82712d92a965be504fee43fcc6c0684b2b17c5b294a3eb7ceff1cb000000000000000000000000000000000597b7dd287f3fb27e35a9e4e1718b6b1a4addf9e95e93aeaa25aa34023669368b794a08fdb178d9bcda2738534d1962000000000000000000000000000000000a492d648393bfa317165ccb552e045fefce5b3444d5ff770f43a08a68efefe7fce1216114ed1495cd00f832538198180000000000000000000000000000000003d85cea8063828ff025ba599bdf1efe0412ed5ce06ad5faa841c6400e4eeb6aea1470d48f4e66fc768d7e7bfebedb37145c1442ab82241f56c27dec2cd4dbfa9fc3cf1ab72bc521ab32a82346f8f6070000000000000000000000000000000008ecc3dd40da2a7a348b4817d9c84242f2f07c5d0ef810dc08311e9d4090d6d96d68b6c725ee6c24de076c71754bc4b50000000000000000000000000000000018fb3a1dc4e0dd9227fba310236a6db7953f0b716fa995b928a2a8de38edb97eca09fe2ab385037dfdcda2ee577e677900000000000000000000000000000000062fce7fe7810273a80760d9f4b3be9e7c821f38ed3e075210d3aac6aa7a763e3cda56465f88b34540b408ac850742080000000000000000000000000000000006fa94466cc47990a80ae6a310ea765590a0e646b5988925f03cc7e30f04fc0a8044b403212290b2fc46c77e84a9028dde4d1470f6cbce027465b4dc2a3deaca14e34218910aa76cb45d47139b31df88", "Expected": "000000000000000000000000000000000f41bad0a932e28096e51482c646dbdf294aa7b91e0ec258670e7674864765c76989a936fb440bfbf4268a49f450d3230000000000000000000000000000000018282b76521db98f589b1c14e603b6f5d27af357553bca761189a38a944a11c66480f7ddd89d17e4aeddc8d78a2b3a0d00000000000000000000000000000000007efc4a90dd97f1312047ac78a3163dc014c42a44c7054daeefd5b72cd0488832cb6396e02ccff09e4171d790954fcd000000000000000000000000000000000e790fe8323fffc96705a42ca071532d5359641ff7cf8714789c9c578717a054c811cdb581df8b6a43729c6c3e3255ab", "Name": "matter_g2_multiexp_24", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001304e0ce6a4baa6e0545fdb314523fc91f73eee157249b94f284ba7390b12b23b1c849c45a563ac82b62a2c48aec24e1000000000000000000000000000000000a2d0e9e222db70d49d1e85f587d35bdf5e8328aad14343d296f95b152a79c83a4858cafc350a5df1ad0194c49bb929400000000000000000000000000000000199efb09b34d0699eb4bc1c57fef9cc5d98453bf522c504fe7897e22bd0596a3a6c310eb351e15e3f6609b074b240f7d0000000000000000000000000000000016b69f12ce30ad1a65150094e29d4cd82fbce5dc343517ba9e5d89245ec083c44af9a3dad2169f713d3b01fdf70d20642576b42e0728db912a78eec2b7b4c96575e341e86a7592a07a660c11e0044839000000000000000000000000000000000b3ce4ac12861052c602e71906a7c9f3e2186bd2b6eaaf222d8e80b48baee537065ce78372ed936e6728b9642ba1fdb9000000000000000000000000000000000e8186561d23515bc58c77769c93db76dc9c62bb715b283cbfb71462451120a6ded736cd8a292a6799fbad7617d9aa84000000000000000000000000000000000368a6dbc7daaab0a786257c813b1a25c97468732c27cc759fb921cbc3c9a37a46d7dd0298771c447d36ef0a10579ff5000000000000000000000000000000001348d5e34cbe54e3a6b357c4e651acb82d2dc40ef9ed8bb89f0cdf0882ec6a737998f4e4dd61e296d101cbaabccdc3e779f9205ef0e3a85199c60ad9267349fdc7b6fba4cb765ab21750eb3dcfc48d8b0000000000000000000000000000000004ebb53c462239a78bf13f29856ddc4d78645c457a656f3cccec9d3c032ec19c26488f39e0f5bf0d38424f9e3a9bcc870000000000000000000000000000000002fe1949365831f7c38b1cd6cf2e22345c4ce40cd73def77889c214d1077d70e39578e8be4fe5998f59d47cca7917280000000000000000000000000000000001152f2df1512013a42ac056b75802bc35c1883efb345cefda8276c594b061a0b0f4a49d8bafa6fe251658ee76b2493cc00000000000000000000000000000000094f90cb386f7933b2ffcdba5e46e09cbd7d537c12bc223e76d3a88ce9063a7b3574d3306365d65dd4c6505f1dceea53300679b7be7c71224247e8034f5d30a63f8707d92d843a703f0fa93160f6571500000000000000000000000000000000169d9469c53e55768c9312680ee82ee581727e28cdb1d6fcdca25d0c03f3da2ad6572039f12c90b09cdb843bc506e07200000000000000000000000000000000174528257f6d3542f754ecbe97eeeea7d196ee4dd01852f6cbad87fbeb4dd7d3799588f17aad129a15549bb787468772000000000000000000000000000000000c9ab635bdaca1c488538c0830453ec6ab3b2b62447c03ff6ffd2712bf62e02a63c76c79d41644ea412e733128685c45000000000000000000000000000000000172ef0fda359bab149c8c04f583f4ace4d1b148426e993996d278f79ed2c6d3933d6cc5fb62ec4869aadc773d3084ca0454b01910548432a0f706818a98151e38ff9e854f1faa95ad41a7239b5cc4910000000000000000000000000000000017060fa73b58957d12b3996d67b7baa8b7f0943ad52e80e5c4f8830d33dc74c0a39e08594b647945b402299ca861f7b10000000000000000000000000000000001efdc7f783f9977392e2797a3e0bed222d5b661d056aa0c7e04a493bb9b18048bf72aded134941ece78d63df0a0868d0000000000000000000000000000000011355198320af05f2121939e6489f31e9e13b3cbb2cb30c9e675854cb8ec038f80aa2f4b6f995774b36f5f1b6a84298f00000000000000000000000000000000172e18c490d0cd5ba2449362c0ab296212dbe69ac25515d0f91941d300051320f067f946dcaf999554f55f1f616adc0f3685617371b27ba8898ce7f30776d817ff09ef68a9d6721d4a923ed244ae82060000000000000000000000000000000005854f4dba62d1dbbf3ae16f70792f1bb39f111309b454a6400d2916e619d4f70764ecfda7eae5c28cf1d178ad53fe6d000000000000000000000000000000000ed0bad1f5d69a0e621d137746a9ecc764931ab89f24ca827e0340ddc03571ed697f63e79cc58b946e8462099ce4b1d70000000000000000000000000000000011de76edd1cc2f9ba06b98593a24a7a011f2701b451ea3ccd04361ddb678e06d91a676e3f11b62c68cfc05242cb8a859000000000000000000000000000000000599726b5f5b93d414f9310383ed9414e4675d644f83ebaa63dceb2bddc7dcfcbc17c7aaaccd0ee32b0875952554b4e660cb5aa2a0cd1e8c3fdc06a3a1f6f9b6d52a8cc2e98c85b8e258f72d03efc25400000000000000000000000000000000031110347cbea2756b5fdd549d6c0b8f4036f5718d41dcd6c854a91c9df29bd464774be479d0efcb8a3f82cc7441a6c8000000000000000000000000000000000e24a52dccfdda3689c87395e45dbd46156676d9eb2cc09dab22ef7ff0acf5ea243ff117c82b147994d65aee8605b2fb000000000000000000000000000000000e0cd6ea0bffc591c13c48bca0782fecf8e128b0b842aecb06f803a223d32cc350db869b7a77f8e31b05f36bddd587ea00000000000000000000000000000000042ff4ab4596d610638ad23eea904a82701cdf61f9e2dc5832a70e11e717711a2d0e72f32f74706d385a9567426b4713addb1fe778c84242953db87d2307b40eeb776f17767c3a4311b5d2ffd738f151000000000000000000000000000000001517efd853800946aa37868b525e58fb488bb69755ccec806afca2d21bd3a30ba46c39cdf694ad0ca92841760437c3c1000000000000000000000000000000000e5591c339e88544660380d6362f4119c5596f910d4ceb96ccd4c4d9672efc50805b6fedffa0a48d126aae69b241d3640000000000000000000000000000000010ea5babb0de734641f63eed2eba6124377b5c55e429987917c0bd109d7904766a10b0d2dd123413816d0fbabe25050b0000000000000000000000000000000000efc89ee2ffa56193129062ca55a3350bf50e8fc7d586fae3636a70e3577987fb0f8674d383def4b41225e490d3d81528416b4b4e965a5f024723fbad6ef2f65a1381e70201e26ccb40188dc3d0fae8000000000000000000000000000000000dae4277d62e3f3dfffb80818a5ba5c371a48d73b92d69a168ebab897ae8be206fdf776e9f955136d7f7f7b2903040270000000000000000000000000000000010ca635ee2e49cd6c951d75ffddd11557432726d26564239c611b139329a28812afe21f094c0585675f4f233233743050000000000000000000000000000000012378b2ec31119e508fd9ae0ccc4c2603b6820283284a278fe16864e5a18cf7992d850c1d6ebd1253103c219bd95ca4c0000000000000000000000000000000018cac4f0660240045214034cfd8a7e40bf0aa12f97a23c4e27db0e05bb25f4d755276a91a4e882a0be63437a522943ab78077a51f88236dba6d16d7fd681c631510106b0eb7448df456eb9ce758e74cb0000000000000000000000000000000002fd5571c818322d207d58fe0a898a045a26c95c2490765dc9ac663a0de78ef5fbd05b20ea96dc5388d5b2ccf13a5e320000000000000000000000000000000006ff29ccb768da45061ba4e01c90459ededa5e79513917401e7e37151095ccd4656aeb9cb7c083cf27b69377295934cc000000000000000000000000000000000414d34eac47430495be735eb5c4b1a68372abeb43658f27613a9c8b78f17d9074174a8deeeebb1f9cda5d6198bdf89d0000000000000000000000000000000010b11bf63b8c39c1370e8fdbfdcd149fea88eaf1c0a94a51bdd061e4c41abc626a448030bf9ba880032e9f1642caabae871716e790e1a0120fd26d169b8ffe3fcc0d03683dcdba7d2f953f05444076ce00000000000000000000000000000000023eaa08a44eebae674434b013ae9992c75690a3d0de53e4b05d1c0dff249feb24a12432bcb5defe25ee4e44a56b27eb000000000000000000000000000000000f146ac27e685cca04afe8fc58fe853825f5b0009e8831eb0d0121decec23b25bf8521da2fab1508a3ad8254865fbee70000000000000000000000000000000004af1a525d3c33e0b1629cbdb90c56a88d70a28037c87db81c59bcbc811c8f0b98aa9dd574436c9f600c0e8e2d194c0400000000000000000000000000000000170efb5e0e69e46a21ec3b972265bc04b9d5ee926254f61c0e18fed013922e00f1897cf69889576bb5d54810486e7f2776ed0a27553db6ac6d3959ff4c9bc5807fb7d4f0a56095ed2bbe31dbfa41827700000000000000000000000000000000111c832a96329d6db203fc8b6bb5b7db01521529c91c74d9cd71dc78d067b36cb7eabf1af80129a7a3f44b719235927400000000000000000000000000000000097339c17816795238629d4ca6c243a14e9e227e9bfc30370dbb9e1475f6d03020dc35559675121792436bacdf9eac4a000000000000000000000000000000000805870a1efd1fc34c9b576b77418ee8c0d36aa9caf9994a051e1d55b49275f34cdb55edc74ffc267c5776c8d0e113ed0000000000000000000000000000000001513afdfc2f000e3b725fcd0428fe72ab2413ff2aa91b44458a5249c9a160ee27bca01d2fc2e230f4a80454769961af95ce72b30d989889c8779c4056e441bbcd93629efc2877d36d27f670711e21c4000000000000000000000000000000000485b3b1f812b4a28ac87d16f86d8d634e85d49d6dc460646e1224de662e906002c44a1a269c3bc011fd22afeb2d58df0000000000000000000000000000000013ba0752444a794cd00c99eceae51e61c382d0abb26e5e0e595d59321447400e8a8f7d97390bd217fb50bc22cef34b2300000000000000000000000000000000184515a36024d0bf71d9fa4cc5165363ff94ee9f8579bca653ebc0620a9d3146fba70a2f4a9f6bd3777101de0d32e327000000000000000000000000000000000e041422088c0343f7704e726d65ccc4216c4a1bde3668108983643663cf0249e992f9acde2dd8ff478dd26cd8d9434d06d220f64de05bdd6e1140c1e409fdc13f43bd31cd94e633be38ecf22ebd77db0000000000000000000000000000000005bbb0c55fdbc59992c83fc0ff03f677e58b6de6f8649141d88963ebfead9383d692015a7b765b727eacb6de250351ad00000000000000000000000000000000183057eca610b8e07fffb60d21bf2eb87981e6e881bba04ceff420ca38228fce2f94d40a993e2aef09e209f3990dd14a000000000000000000000000000000001231bc55242bea6b589cedd1d82621fb71c606ca9306b268379dbf83ddb1420dea228ffc05cd8b67c38206f3f006ef18000000000000000000000000000000000f2c943e7a8b0ee00fc4e4ba912b94f68f504d2783babb90a3781b666b31bd161af2f97a77813eab9ebba76040b04155257da8ac7d23c5ed965d8bfc76a642a36ea6ec4c45baf6882021372e8643f09800000000000000000000000000000000054bd97b9cc979006f734ec433e215a4e8afe468e69173384bc895e10ead3749d991ff8ff203abff30bf5cc0d2fc8c6c00000000000000000000000000000000066b73a98d5f5ae140a5784c5594892c849aa7f2db3b5798643f755743d401ca745d810fad5f4a33e5b3cf0fd7d96f7b00000000000000000000000000000000007caea93ff5cc6ffc033717220a215ac4ed7283945ae77e62320a0bde13f2153dc8dd401297cd124b4c67a4f3839dfc00000000000000000000000000000000094568035ffff439e3d3201466f3a1d43414e3f6455627c5479c8b7c55130ccaa5007ace7ef6a2b3e2e5a4c9543dad9163d017ba8c7ed138b1bc70141abc5cdc3afbccd8b1db5a6b5f775efa62b8dbc30000000000000000000000000000000015eeef8bcbfac04112931e186f6fd48b7a8ea891ab364ce8266c5fd15f072f08fb3655e324795df182a5ed1c917a5db000000000000000000000000000000000028916fcb3b30a7f95321a0998e544f9f4f578be7a9f866cf72d6b8baccd93f8935f105ed26aceebb3f9c96073a8be180000000000000000000000000000000012b11f356a7e32f3d9281a8999363aca0ae5c1a058724cefb51583e5f217257d47ca76d21e54ab62260796b95f9d3ad0000000000000000000000000000000000d83c75c36cc8dea4aab47823edd26b4492da39b93a15fa454aed4175f28a025ad2c576ef2d76a66e666bedae95cef1a7a16e23e37ecffd514d47199cff249415a6d366fdfaa82450f0744520258955c", "Expected": "00000000000000000000000000000000059443f363ef0c65973d36469ac651eec6e52485a07a6d28112f4d0711802d182b7e6fc56d4f1aae51fe1c549247d885000000000000000000000000000000000d22118a6f1cd06ee14c63f0e005076bfb061bb85ed184b5444c08ed9dc35f77217b6daafeac89a973f2c73f00e0d3c800000000000000000000000000000000180430caa9917cbb40e3ada2de8d685b4daa99639669a643b8f5cf9a4a55d6162e9fd7f5d4989a1a6588feb0273669b90000000000000000000000000000000015d01fba1192f0f1acf8fb32fe790f0448c6563cf8ef5505d9378fa2fdd38bd99ba938077f71bb8eaa91a99e787e840b", "Name": "matter_g2_multiexp_25", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012d948b5268524659e29cd407dbbe8f529e608193ab9452f936b2f6fc0b81d3a63a0e929329e2d89b5475dc2d73ebd8a000000000000000000000000000000001219e20a081837f4d4e33bdffda08a946bb9cd876e42e2f561ebfd18ec439e0104b43de61f47b8b7a0c346c33e632be60000000000000000000000000000000000a135c72c45f254cc1c260af803e14cd0f89c2ac3029629a86b05acd3440465aafa4cf84e69551ae772bb55802a90ef00000000000000000000000000000000052750c3a99974f9044531dee9129110b99572cf283b61e6606f1137a87de7344bf01d2ac2f8a1db8d815b6d9e7511fa26a9bd0a71fd58edf81459152782733536e960d27e35f9f84d00da256bdc118c00000000000000000000000000000000136b2f21aba94bbc8e5235951b1b186fd4ad221e6ecbea5c7279cc8ee8b01edecedddf48cca47624ee9b155a4c167f140000000000000000000000000000000019852d2bc9c8abc92503f3e7eec9fb20df108c23643ba8a2fe16c2cf085bb4ac079d3f065a1241067daaf401b662288b00000000000000000000000000000000018bf1a4e74ac9507b97a990f3a41cbae3f32e263e9937a8a62679bee93296ee5cd25110833eb5d136425bae0e9dcb8100000000000000000000000000000000096ae4bfaaf4f18d3e987d9f287fdd3dc9b497cc84867e757da52bd5f58688403e1c9cb432a2eb87e239879d52990ab5f1e168ab93674bd7f2bf73318a48ef17ef4464fbefd39f77c17ebfdb24d679b60000000000000000000000000000000016ebc2ee18515354b7af5d924c895ffd5556ad088560f89c59a4ceec229279d4075f732b884a6ef2bb2eddc11d27572500000000000000000000000000000000110282084ab6f3e76eeb9e5e8c56749992913c2404b003df9c2d01d72751f879538d23f612c8faabbccff45185f4c6a40000000000000000000000000000000017476677ebf052d13f60ac0ec5e572c398f1a478d60ce92a3de88a74a28688d786d30b1ea8008409e45697db0adc628c000000000000000000000000000000000a5e4239d938bfc7c05f3b3a850ebd5f7784eee7aca48c861eb4bdb1ce6321fc9c6bba997e143aba13a42f69ea14937397fb0d947d71a1b032070a12588b85065c19affd0db53e466f194f04f58dba2e000000000000000000000000000000000b6e16f2a6cb821abc43c447da207cc3013f2f750c844f42f0fdf47160a38501bf502073bbeb565122bb3de61b3a5ab800000000000000000000000000000000040f5f3aab5d416e9a084fa298814f894ba599315fe10af20f836e624680582413b4a54623cda8ae2663ee094e4db775000000000000000000000000000000000d32ac715a094813c7b46ce2e932365bfd62ec5e584e047b0c56ed6eca3c58268ae01be31b833be7ba5c2588ebb9859d000000000000000000000000000000000850b9044f129e51658a02cfa49d40a2b09239823cba4d8fe423fa1b4815750811daf745e7e02b317a7318aad0734ddc640f850bad2f22049f2f8aaf3ee57564fb38a847e428e252f003eaac465f7d670000000000000000000000000000000010c703e31f2d488812a387596c797d8d414e406bd82f238cea50a459d842502e11220ad82fce5dd36635792ff5770bc50000000000000000000000000000000010c11caa640708850e1dddd48bae22961a45029971d823b53030979b7d8ef2eaf2ed055436105697c5b0b31b1a9d0a7a0000000000000000000000000000000006b98568b2b7f0aada97310f7e14084a14bffe580ec65bc8fe5d19c6213c45dc1b8e1da5c6c1b8555729f6c781575278000000000000000000000000000000000f2c506f3e41c28a748656d1dfd87e812b3ba21815637e497a30eca4fc5de18257846f12b67919dd2d739477cf5ed0ae8bf91051da5bce0a51bcba6f4e1b3c9063743646f4e75e3e5a8cbc84e8112af400000000000000000000000000000000102b6d561172adc9316b3ec11f05e66e7affb1bdc70a364faffa57aa5938c2ac08863be8fe79ce3f627558fcb2ab1230000000000000000000000000000000000c5e72c271a1ee186d443a96d53f0ba0ce226c76aff2a7c3215c2110f96cb3301bd586f509edc45cd20e662756897b78000000000000000000000000000000000d546fbf485bb283a04fa05aa962ae8d77ec4d26f749d83b208f77247778e32a9a2f1483bd84488806e27b13eabf41d30000000000000000000000000000000005a42c6ce8d43d122bbf984e9777f5d1c15057f27e70fef44b97c2c6e7e2e303fcbad643027b7ff3167916f21a723ea98da771e0e827a52a2f7e79e0e5d93ebae04c1ed78cab87d4353f24ffc52099b3000000000000000000000000000000001788323aafb95f8761f87f771fa05a8e49be71e397849daef5877a7f486af13fa651be7a93bdd9465df7be4ff65825fd0000000000000000000000000000000014b7a56f3f7c12e39be76b3872c1ee648f62f9cb6a1842d869e00a5dc2ac8cb4ecd96ec2483d5eade5b0f9113133bb050000000000000000000000000000000009a30623632b757ae8d03ced0c1fdd1877718f8d84f34ebb42426284f73bb7e8abc31a5e5ded57a02d08adaa90abfb2600000000000000000000000000000000020b47acafefce7f617081e22b2bfc566acec6d2cad5063a79cf33e02cc8931bb698b72184a11fab73e0bb0aaec76c61d6cff707bff10fd53ffeff8e9400966d8ffba6d4ad6a8e7e456df10f8f5ebed2000000000000000000000000000000000d1190466f0e8f03d2cac4a5e63a13d7c6d0cac9f2065295e2de818773199d731f8cb7b2be5f6ef0a246401b345a2d560000000000000000000000000000000007d9c5d187494df79c25b6292527b0d6d8c50b6467bf76a1a1316556e48159a3b5dbdbd9fb0bb901d857f61f423d15db0000000000000000000000000000000013e4401fe76e3f1ef73bd244189cdc81fcc152f71449c11aab24c4fa1d123c5aa8c68a2d10fe88c1c6631778dc0bcd420000000000000000000000000000000004ccffb4296883b8690b2f3fe17e4e9ab24390084ac917ed28fa1e04b9758373abd348290d24c915dfcaf0649ddf5a87e00831cce307cb44e8dbd5edf24f1535b837277160d2cf6daa4e862e57fe73b10000000000000000000000000000000000f4baa5e531ae462b95362292d5366daa89f2fb2707c58568c094c58578e84a8d253fe1de26b917b84635c0aac3a63300000000000000000000000000000000109057e5c5451eb9f85b95aa5ed2615d2faccd0539b1e4481923e04cbdbd2ea9290969022cfa508d3fd050549c74940d0000000000000000000000000000000001c3e147ad9c31927207f2344fedd541316f4010e3de194f924c4a1450a221285b76ff1894f8b1670731007f44965100000000000000000000000000000000000909cdf5c56dc177daa1f3fd7cc31d79a4f6dfcd462c07812cdf629426b75bdaa297b9d7e67aefdbb58175a21e29edada8168d56385722f339a5b27fc25a88034d348e3d533ff4dc99d28536c1c09a770000000000000000000000000000000009b4c6bd1c460d2e93febfe523c1d54d6bf6af50838e7a10b732c1be8748a0752a517e7103d0ffa4507b086626fbfa8a0000000000000000000000000000000015bf2c13891dfa8dba35b5da1235563d4ee1dac33e89006f5c9fcf06f2fef7b31ca845bcaa8ac608046e8b01c8a61fd2000000000000000000000000000000001898dfd6a0618df821474b90542f261c1febbf2e566978b0fafca44f6dadc57202f88366b19d2c955e4291ac21beab520000000000000000000000000000000019287e1ac6b3eaf412e58511b40d87558e7cbf90dc8af2f5d33825b40fd2f2425d0be3a05d0a49076f4114350dcc601eb929ae82ded73a4876c041d2e52fa811882fb8e22690a27cb4ad3ca05169bbf0000000000000000000000000000000000c0993401c024d32cecc0d86d4cc52c200e59acb34fee2ae052837f467905e736a1118260ee12a963ca2df6e1a6c9d0a000000000000000000000000000000000103f78f0e7c9a5628a66efa91f150a87e67623ded2560aef278a8caab017fdcf181981952b450c67e3b4d3f362822a80000000000000000000000000000000000df01ff335f23652f1c34480d23c62d705572321c0e7fe92556e033dd3cf5b78a3d554585403a7f3c71744c20d17579000000000000000000000000000000000a0e2c9e2e34e5cb36e96b29231f702abb127a011c7ea3e21d59e5c55f745a02039a68d59ce8e29afac0752d1939106936999c516d4acdfbcd488d39e3073db9db6cdd0c0fd1d29d58294ace6d2d199f000000000000000000000000000000000eabff0e6ed9dc358881796441c48e722ea171f26011ab898c5a06758f61a629ae21d5a2595a22dc9855fd2e516b30fe0000000000000000000000000000000002732155a7a2791078dedfedfd3381281554c389bf9b5baa47593153a2acfd22a08557d7a1d49be298e416051b9137dd00000000000000000000000000000000116faa2e2a261e6a3e4de6ad80d75ee05aebae47872e2eed9cd91aafb94a706de673a05f1b86c0b0131cf148a90b2b7900000000000000000000000000000000009a04c09c2a4fce22d237bbe930392dfbbe5c82d480abefbb3be876015e2f5889a0922df6d00d4e94be0e9fb8d2f4a1fd0bc405e3970dc2bbd7dfe0c54b7c64543fc241000adeef4f7aa2f1dd2506770000000000000000000000000000000002a6402848507062e5c5d63b1207a1a41d3b941d21792391f2feff95035f1b4625541770fa5e0f87585cfca670976533000000000000000000000000000000000904095ce640605c957715e378ed733ddf1f94d3beb63543a50c8922ab9f8092755fcc65e2a1ed9232c8cddcb5816371000000000000000000000000000000000ec62b911b08d3e8618880c3784685b2c6cbb07a4aa4e348ab72e4f918152622ddd7748bfcd79f35675cb956d11fcd650000000000000000000000000000000013f651e9104d48a081cef2ae0648816b2b4b5f644a791514e94a8e3dd3001099c27d1f9860337ced1b177b4ad7cd5866c36afa3c8581df069292d53b8ce3e35ca136a0b3f95a894958105fde9c77e39d0000000000000000000000000000000016334abef2a21b9c1926b2086075471bc2d2d2f66b963a41623af91fd2fd50f254c008fa3bad6b53658c2486edcc94aa000000000000000000000000000000001063002a5d17aab2bbb5da49e8bde63a1f3c4dcbc8800f9487f47c6d707109c86d3cf7f9171643418b195e50d7483af4000000000000000000000000000000001213004f31fdd0b0df5d8e3677c4f48624691e2534c02881c6cc6875b9abaee56ed5739c2acd66cb1b10553ba066ef1a000000000000000000000000000000000fb7659081cfcf8beaed9c1daf9e92702977c37a54376597d897082a25f9882f1ae14e7724c0aeb9e002dee708c6b4eb0f0a2bd678c5858be2a49ca54de8716fdeec84e1935b8f44545c740417efa7e400000000000000000000000000000000078f06bdfcbc7c0cc491fdc8069314c8a395983f9a2e5c2d1bec360f36e365da377885f897d8d711e33270e3ef9dc4d80000000000000000000000000000000007d43394d5175e020b3a5d768b60ec763d60cb1bb37c0343930fa82e92fb1becde0a178c4565df320824bdadd54ecabb0000000000000000000000000000000012f9fc96355721c35a6f5439065d89cfca5345622b3f38041b41c036b9bc6bcc980498ddc7bcf807e1b97831c099505300000000000000000000000000000000105307b482467b881a59eda1434e31dffdea531603fd3c460aa8d4f58d32668228bfa585bbba2dae7346141af59190e2c8e420db340ef2c1b5c6a71645e303eee95cd93228770b639287b14b6a5c59ba000000000000000000000000000000001576521fb3be8c3178549969e54bb17b0a3546ac4aacb470e935359e36bea4f43dacc06c151a527f441ab9616e07f7b90000000000000000000000000000000018dff940a21768ee9b9450fee7259663bb29af645bda2acb4d43f4e9d631e0127073f2db04293266e6fd6fd3d005e3f0000000000000000000000000000000000ca6a977016c1ebf52827a5ad52e5efcf7517ccc3ff40df8141f6335fb6c77c3fb8f6b0dcdba2596ded7c3838577e28000000000000000000000000000000000150cc33b55586fac30d316cad6580cee0a070900fe7d540167560b79f4cf9690a5e02cfce9946cf67a95dedc9a7d9aa35398541eb5a03271e2ab5ec2aeb2da80e634f63a050c25de98ad13e9d63d09bc", "Expected": "000000000000000000000000000000000adf84ea7681c442731be8db9508a050d4689c42af8f7472491655356a86fd9a0afd91435bdbaee98db3b1d8f26203fe00000000000000000000000000000000090a7dadc0a14df481e44e2005c9ddc6e026ce2afaba7badd18492bd3a338dffc349b4a339f56221eb795314252d53640000000000000000000000000000000007390fbc06077cd167f53a16f347eaf50ce8c9d111afeabf3a672687441b80e66a66ba3fdb28e2ca8282f3ae3dc81be80000000000000000000000000000000001998f98e85285a428a2860c22a00d0b317854da4190dcb4dcd182ac249e13c51f5d5df5db6a0fd61d01232cbcacd5a1", "Name": "matter_g2_multiexp_26", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c868a2cce65692f83eedbfeef6f9823ae9382fa5ed23395ff2444807e72403d4f6ac861ecd3a51db841889fe22a033700000000000000000000000000000000111c9aa53da85a63ce1870b963415f0d5f812e061aa6bff57425038d1b65fff57a78bdb963bf2450001525a93011a28e0000000000000000000000000000000011770810c16367d075c695981dfa69b072b82b034f8ac371f26bb157f9f9d667aa555a5c6baca69d08f421cd569faec2000000000000000000000000000000000df6146b29bc8226dccfc95a325d791b30cba8ff2495434d75622b170a634ec7995c5b4c689c73582ca861dd21d8e1e49f99387baca30b9cf63ad10c445daa142fcae1ab3c0a366a068bb5efc9abb3a9000000000000000000000000000000000fb30aac6502ecdd3544f1879bf1b3f4c19fb897de6c3a7cbf08f36244aa8e9dea8aaf781f7509d3ece16ca144a601e40000000000000000000000000000000012304be931a1d7440d67740f50b1a281468b412e8b6c54c62b993ec609012c7056fc7e62405c7530e8f5136cacb5926f00000000000000000000000000000000182320f5d9211c08f3ba5d40ccca45cb0060a6d362b4422084617b9d8212e94a9b878294ac176b8f0e959bc124a753310000000000000000000000000000000010be6678910072ed9f932ab01a2d72f7374a2cc82bbd86a6006a495272aa89fd655e6719ab8b3a0643d002021f7b7ebb4283a1773995bbc97a6df107082fed4ba40e2d30c5472a25a7643ca9e78b8b8b000000000000000000000000000000000f1ffed9514ee81e9b3fef4162c8f4980fe0429e57bbc224a9c9976cef7d26ab61ea7b0cd42eda30da97e3f8f5ab5f0600000000000000000000000000000000035b9b349b531d85361a4618a172b510dbc924df671b3fa707b474d0d8b17d30dc8ed208d66be91dcb7632d2f05ce31d00000000000000000000000000000000010030dcf6695d44ad3236032e47f7aa25b9f55869f5207e7ac8641db8c01f5b59627dd3442a1834b8b1fc595e47cdcb000000000000000000000000000000000f91ad5c923572a75d32962567e7b1b0eb84a91d485c968b5aebf8b3a772c2f94e47bc1d5b333fe43574308a78e768ac7f4202d670fc3b48eaa92e925f48821d2ae057d90c5f184edcce9ea900ab51a6000000000000000000000000000000000ae11c60537bbcfa46a08cbc219122ed66fd0d42f90e68243c32010eb99942554c349c021f0e3635bb50f7ca3d106a3f0000000000000000000000000000000019a61254aaa5b51b4d354f444706ebb0bc3edb87ec2d83e830ffe0282bcaa3278e947d053d6678549a098129bace43da000000000000000000000000000000001100f48a07456f01e16bcc833ae0a2835c964e9b0aa850574dfd8b4a7f06d03059e9b4df8931740ce0621ec7eb31218400000000000000000000000000000000003072392a824c386859735e2d203c9d52c19796ccf8538bda3b1436b2f6815bc86d05287f29fd0bb0569a81a57f0c22a76cd8d292a7053c449cb98f13cf768c6e37da9d702af28c16dceacfaf9cdef5000000000000000000000000000000000392760f98883f9cf6c0f0a324b9a645cbae12b780896f6a3eee918c44a815daed156248d6afb25901521b323f6baa240000000000000000000000000000000006375c6629f30b7a36785269d691772afe1b95d6e1bfaaba9459c31086c2697e4ce77d148fe2ea166cc330373583f4730000000000000000000000000000000000aa8e338df7eac5a7b070a69d3ed1553a0c52fcd894c2bc8d1b8cf6ed38983c6c392a9a045ffe8ff40b39d18e7c87c9000000000000000000000000000000000cbc73b589cba1bd47161282642fe6f51f2b3edcdcad6020bdaef369d3f2c11ea9cafb9a7fdccfb89bbbe13560d42d1d97b7bf8acdfbb148814afee1df79aea17261dad6f78772111a6dcb021d8c79d0000000000000000000000000000000000e71692cc2342d1e93e0ce72be69013023d012dd2294249dfd69e1d610e2236ee2cdef22446f1996bd3309825989930700000000000000000000000000000000013a1bbd3237dcbe44e05234f7e41982f4fd951d3741a3e90345418af1c922d35edf776a27bfbeaf7a15658db67164bc000000000000000000000000000000001197a2ee5c2541e19b5368c97abf51fde3dd0b922c3d701d7d84552c9f47b38ca09a8aef8240abfdcb03292ade1ff04c0000000000000000000000000000000010ca3c22ff8a47b1c683a58086ed9d831a5c25b6ce5a1971989974b4760cc9e83a1bc8d819825989751405b242eba379efdbd5953bc33bfba09fe7b3ee22c46c3a86f557e4b5f272853e67fd95a0f9b0000000000000000000000000000000001306f8047ba1a3417e7993bba0dfee9077eabfc275af91d0b882a53199874e0777d8dfd29767186d922d49087fff38b20000000000000000000000000000000005371b760380a6d287e129b329e735413447969eb9048def44f5c5987a64323d2a5c81484c40b20206832b86a4af9c4d000000000000000000000000000000001552eeae620c42d0bc4593d7c8e2c8fb4d6dbfcdde68d57158a7dfe837a1870a73b45a97b02abdea174a475a7061331400000000000000000000000000000000033a6dec61540a5cd5773b76847dc5016b309c5a027639598f51ae5b1067b3f7a02f5ea11b0e1be77a3ac236cba15c929a331bb218b99fd38451483a10e8add23c9641b975af3897670884efef90d4520000000000000000000000000000000012ad5ff49459fd3a7940a69e2a78919876e9b3a4f0c142499e7b5dbcadb5c2b5d79c5dea972f0f0acdfd10ac53bcdd92000000000000000000000000000000000ec1be9cb379bf1e24bd5429a4a91857bc3ad45095d15bc5537c2ba39407e9f2edc5fbf711ef4287a73ea466d4f53c3800000000000000000000000000000000173605df66aaf51810793db1cf2021de6a7645ae84a5d439ee035b917d037d9f9ff072b5dfe8b9ac69feab60fe2d70bb000000000000000000000000000000000d0bd336825381ae1e18ca37bf6160ae32b653ec9f9dad159006e92c24b661f22b5629ba323e9e06ccc5887a962ec23fe9301dc826bfe2988cf93c29ca9f01421b75ba63c5ed2cee1599122012ada36e000000000000000000000000000000000f5e593c6588add92cac2c9467247fc6d900f20b4d3216c258f88f3334eecaccbf3eacda227e2da46cf520e5102a9cdd000000000000000000000000000000000458177ad6c190222e53e054546413c13216286d414e3509b7dc794dc0704afd26bae93ff630c6157d05d46d805a04470000000000000000000000000000000015df8a7720d389e6112707e37694afac2f97282676a89964deabefddbb3a0f1cbc885d4c875b945b8303c1ed2c0f46b8000000000000000000000000000000000e3c7f1af7cf5923dccfc1d25bd86088706a3a44f5fa7f97171228e8f2a2b18e9631b2a63bd5a75ee0bb83fcc91a45c30a1cb530e8b828542fa4114de6aa936bd2be5ef3a9b7a0e20e475022381d62d40000000000000000000000000000000017823fc8a56e6e5cb9924037ad6ad1b43237894a877572dfe3d3cdc1120fe83e01de112b55f7f334dcb5c6247c210613000000000000000000000000000000000daa01f90cd14d82d4fc40b60b463089fc6c0e567fa46bae69184d0e3cc5acdb1d759e3291e2781fe0b65c734ddde28700000000000000000000000000000000164e742b123c19e52e2d7a6727689181f323990a3f3238072f7cfd7fc0f55b7be4274c0df194d85060a81f3744d3978b0000000000000000000000000000000007c03a1678b6e91c1bfc66ce8fd419cea13c7cda3213856ad21823b06db94538153a15d43a9d4270edf77b9a5ed490e6cf2f0c33bd044e8c4468b4b7e137ae294c178e7b6c9f19878331fb93220db2cb000000000000000000000000000000001865bc91e645e2e24c3efa3afab8b0e278dcf16b29831f75b3eef0b342479e997b9c5f8ccf67c789c830609b3cc425400000000000000000000000000000000018dda7857f919a6a49f6bb465c27342c8fab6afe6350c43b98e91a3105276f3ac27268454e9a9c6dafeb2218ddc7d3cc000000000000000000000000000000000b098258ff8b185a5c59b46150954d52db5a5f68bc7975234491406131e4f1286ce79156dd1290aafe688f936ad34e31000000000000000000000000000000000b294e9ce904fb9e243d0790147b6070b10ff611a06e3f639aacb744154d02016ac08f6769732d4f6944ce9257680d49e5f460dacc592bb947ff6f1c15b8464824aa5c957a645a763138ac1581ac5768000000000000000000000000000000000e541a22a7a36adc06e445f42497596e1017a1d99de85bb945a195cb3cf0c14d39eb7a2aa994cf234eed77f6307cf6410000000000000000000000000000000002de753e41a16565e5ab1b61debdad54950e9930e04badc6e356f10711d7688befc6827040356c0f0a8ce4f8d7121b3a000000000000000000000000000000000f2202e34ca164f1a6c0afbe179b714b303d87ef14534fe3f4230180f709dc63af17f04487264b3dee6b24ec4d0a423f00000000000000000000000000000000004044d9e3b3a77d6a309780c870a65e05e1ac531c5420f6ed0056f5e728e2b83a968ca90d579db50c2dd395f7e40beaf26a9736f728e16d7b8ce0cc59e2ccc848c181459fff4321982c08e9cac5794600000000000000000000000000000000166d7692fd30dcd06b9f01ba2101870ed347840509b3242f7cecf91fbed91abc24b08b08cc39c508e6499a2f8bc3637700000000000000000000000000000000076ce6dcbc77812b4d5b44a50edba5a082cc36dc24a5cc348283a4ce1518198b56134c9807ef850edc9e36e9a282b9ff000000000000000000000000000000001261d9412245abd7ba3fc1597f34179e54766c49306725d42588545e14f4e450ee1c7af913ad7225275c57680c23aa6300000000000000000000000000000000096602b4eee053998555ce522c060d5e04c7961eeaab0145d38c9b13362624f54fcc8d0b77f2bbaf8c312a3279f06e4eccf0a9be4775d65bbfc894f8ca66fa6f69d4249ea7f6b076fe193f2805e64f940000000000000000000000000000000012be34c18145aac51a1494f4052edbeff14c2812ff494cb78198cd7d9db9e951aea80490c55c4ed926f6a96a2c337c880000000000000000000000000000000000536e46a63ec5ac0f2f4eaaad6df98322c6a981cf2fc8ef253269cef20a76ba1ad089c24cba4ad4680dc4192d66595d0000000000000000000000000000000005363b9acb66ee95713b63dad076529805c0dd8921c738e205e7b1d0410a3ecca0870aeb2e64cf45270d49b473371ddd0000000000000000000000000000000016749b2b09d889b883b6fdaf518345d4cf097a728b833e92c4d21b5c41c8d5cfc0758e895b60ad101a74bbb6be6ca0c5fc6bfb37cbfb10a1ffdfcb91d9a52883cb9a606f4ffa8849a6e07386dc9bb34000000000000000000000000000000000067a684b55fdeea39a29252b355700a4810f083909cf2c07a80b362ac1b4d58f5900c68d266f7ad81ea278c0931bc1ec0000000000000000000000000000000001b1f78d194d77cfb4a2116ce9e29438dbf38c52733b0295198159d7cadb2584d86a75c24aedeb36234a0becf9d38a870000000000000000000000000000000011fced2244cd959872a25c0c7bb4af6151d99e1aac079c606db4987b9ba111261d4a16e7d82362b865324824445a946f0000000000000000000000000000000002659e7016ad615ed80ea1ae020903431b470bc0341f8e0918de9b8d2e933dd9f2d9123e9e9d20bfb05d49f71c3c454cd94959e16f6d780628694075ba5aa1a476d89d8fffcf4b4ab7e6343c011fee920000000000000000000000000000000008f3c5de8c94a98dc5ad7846c53980384f997d1657f7349ad9b51376d41f4b21861d212fb6428bcf2347d8774f44156d00000000000000000000000000000000110b245b1e788da41dcbf60a3ac4987c1925696dfca85d450107f654fa1230adb9436d60c9e742dfb4e453ec4944c56c0000000000000000000000000000000011043b975e01df36a36307ba9234a18b97aadb9da509513b13e4f3c80432b0cc5e69a3bbb3cbab8df41bbcc92cdbf60200000000000000000000000000000000120aebda10c52a67d23842e2bd9a897cf38c58fcd11e4e8c5614db5e409a7c03111feebfe2f1212ae753497dc59d6ae9122f3a5e940ee7e5038421619daffb8a6f433605f37e78d863f814b51b2ec4e2", "Expected": "00000000000000000000000000000000021067690e6e001e3d0d01449a7257348c4ef68e66dd47b9014d7687d44749be1f33e6be95df6a204169ab7103dc2d3c00000000000000000000000000000000062efa0c36462ab0734128dab5da8635705bd1e1b540817c5805ed9417f176723eea92425db539e8763b1c79b9923e9700000000000000000000000000000000176c9af1970f026bcfa87e6f85a20ed498c28c6982e21bc050cdc29c0f0af832ed4424082e4862d985b78519cfa75b820000000000000000000000000000000018718b0d0fbdf4783cd0b01524ab153b891fbf08cad60241a3f3163d2c3496c36afdc6de62ab3c9a037f88ee408ce5f6", "Name": "matter_g2_multiexp_27", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018adf92d8da050c76118a3a3b2ee43955ae8b14ddc8ed64f5672f40de475f7e0ba6ff60c4b6ca3e863d7914e6de2cc330000000000000000000000000000000013d1e19011a1ea90389480d14fa608985d895e05edd9c28fb34646f70fd7bdb7857fa785b1e3c8a2997da6c3b5337ccf0000000000000000000000000000000015764827d9838c2b011660230ef9805af388fd997cc229c939bc5f4213d517dd837328c45b0b8ee1d6508cb70629b7bb000000000000000000000000000000000d58fa30a2d095ee8d946e50a027ac4cfdd557b3fd9c82dbf1536ddc0f42491a176ecbdb026306e6ebf1bb182a4e8199b3908c739d505a1d6fa85a6dfb7a155202710b45861f1a8a7ac7bb3274a180cb000000000000000000000000000000000cacfc8d0bc6f9db737c8a316043a6b52fd5946937467afc09ddd14e509a89f2445065ac8a8c56454d529d67793edb0400000000000000000000000000000000148b1b941f159d93170fed949d5f53bdd2603d78a49443ac0e2353130ff914376e018c3db3d12b807d105f2d50eded8c000000000000000000000000000000001382a3e98cfd072807214479900a8602bd666cac7f19be0443ba1354bfc05666f40384e9ccac314b5d0a2bec1c90ef0c000000000000000000000000000000000c12c2222f67a5adba78f2c0be5be95ed743e835857f4204cf47b67fa2eac45cd5985fd82c7a3904944e7b84737374b17e0e27a8a416eb38c989a66b84f037a5a24ef3358e20cd553f037a0a2461d31000000000000000000000000000000000197ff997d6c5efa3d7de8e16f26082bf13a2401d6df5f5c33c6614c36105f347e40216c907bdad9c1df6ebbd44f41c3f000000000000000000000000000000000f27a0bf92329730d776a83583177993b2b354a212a9c004f9f8892a750c477b8d1e68c13127f03b1629bc8392d06f5b0000000000000000000000000000000011b239cc6914a321385d907527b85713a0d842f5be80752f4c5758586dc1de944b6e4578bbe324f16838115e9c866bca0000000000000000000000000000000000cf93c5b48cd9de51ccaa45124217cabf466d07d6fdf4a7bb810443339ec4af5b74931bd07eb9fd31c284c05f3f539e0a3cbab01c34856b892aacdabe63d0a0c241ebc137a88c83ad22cf38997b211b00000000000000000000000000000000137b12f731ec925dc51e20a9c90323d14e1497e16b3a4b5651135054ef0e58e9b18167da15220b9a4f7d81e9a7648fc20000000000000000000000000000000000b2d3ac534e1e5b2c9ff4092c2d8dc5efd99121de7df953e5426eb33934ef07e41b196eca50f5a04a936881a05f2b2a0000000000000000000000000000000004feae2377d950717695606844a4873ed7b5f6703d7a63dc8b960b99b68efbba710c2db0f1371acbee314875b97ca054000000000000000000000000000000000f49ce3061e7254dc1bc8af3636a05e098cb96d81fb31e25da97c6266adf3c41a74d46ff32f4fbdb4cb7e4a3f69e827bb386bebe0e49b7f07b0ac61b15306c2515a1ad6fd76a1825dd29a60e845c0e4a00000000000000000000000000000000064ae3fd67250f2c6332e1e149ec09946147e12e0d871403e559b49aab68190a1454b3ae924727b6dcf6e1ab327c9d7c000000000000000000000000000000001131f91c7a0e1854bba3958b36083c27904cfbdb8b8cb3fe68cf578bd1cb6f7c6eff91d98e4b99086926c5d4272cc1f200000000000000000000000000000000071c6a92a8d460ff72d172c204c8a69d6b6752b8c1f731ec63f7f394c0c3a2a1bc15e865172f693f523c11cd4ab1f88e000000000000000000000000000000001193876df7f4a1cc9b337a41c9faebac2f209b9070bd75294c2a88d3091a1e55b51fad482fd2aee8f90458eeb7e981fb8902a82d33993a10c56b2fa3333cabf1c5d47a9c78354d58f70ce4807cf2062800000000000000000000000000000000025c20ed5572dd1c9a098f241d2965d8739878ddc57c017632afcf6e54964894adbd6d30f62f316c9c3ec7a08268afc70000000000000000000000000000000013bc3e930f4fd5766db8f04e1ebfaab2b67f620119c39d687c68619b3564f3e8b74666c9f8bed6c1f080a9e23e9c0f22000000000000000000000000000000000973a3cf19312f90843f1f013b05484064032557807ca67b2ded4a27fdac12d6cd0e1416c8998cc8635ce10046adfbb900000000000000000000000000000000108903617c78fc608eaf007aa13861c970557f2693b24e8a278920897be9694570ae6e6c7749c3eab84d5fa3af5164b1426a4e2317fee033a226a91a52a5830f9ac2cf5f329feb6bdb382438b8a39f2a0000000000000000000000000000000005695975c140fa14998e5916268bde2135cda80a45414fa85193fd6e13c6b5a6486898f590d76175d8ec2629c923e33600000000000000000000000000000000033f58b1cf67e51e9ad817b31919530cfdb5db5ca4a537d9b006b63399da49b2a5077bf5c3b3b4fb10b2478f466542540000000000000000000000000000000015c532e40ec04d9143e308895b2e7e3d3daee093a5840e1e76ab528fcfa5be57d9796ffd58ad5ab7df6f88aaf34706f2000000000000000000000000000000000b55747d1e8b66e2b2fea67229f2b7b17d58ef547ca841bea8db5b53fafaa18390f11b8170c41a5dd29331917fa2e348de0390c05fb0dc9b4a3f76b51cf952a11b909ce13f9abc9fed6a349b8efa98ad00000000000000000000000000000000001ee5ebf73bb40a5c0822350853bb5aeead3262380dc274faba6b04e58e7fb9d5a4ace109ffa5011e73e3d89ee6fd77000000000000000000000000000000001427659e5ab1f8b47edddd27c613b578890d4c66c835c0cf8e8daf19d0ae842f0bba5bc83ed7248adcd75cea5d222a270000000000000000000000000000000001d4560185690ac05e56c2d629d599bceee3ed2919c29e3d1ac54e80ae99b5eb2f93bab865e8c1eef7206f96b2bf4eb20000000000000000000000000000000016ecd3589e3703e5b0ef53790130d5074d2bc0fd5839d9c6ff905746a77e393f73edf53b98b99d9c87a1fee1086aa8657431db9e576643f93505b5b25836218759e736c0d650a5221a652338b0073eb600000000000000000000000000000000163850016261f34de2b831a0a8dd3f224adaa3cc279cdb40e0ae976bbf736dec26c55a6c79cb1c623870b62ea216274b000000000000000000000000000000000a79af5c054cd08608d4be1705058ef7b4ec38a8727560d960f0325d0ef915c049a89e76956d0296bcb6c96333c3470c000000000000000000000000000000000ca89379e558c7308edd25bf06dc05db857204e9351299ab66bf050c8f051341a6c15a02864c679f07373038de3fe87c000000000000000000000000000000001929f42ee5d9dbfd1f6656f61e6243ebf0eb491762b7f3608db3f3e9abf565ab1524f770cd2ade334885d7479342c92c6745a32591e359efa41e9ea93a016d2eedf1da112cddbf31818e8d687b36af2e00000000000000000000000000000000193b6cf7300e47ecd21a05a71b13a8de45418d3f67931789ce6111b8633b9f44063ca13ba8c8a598ee0725caaa3f277a0000000000000000000000000000000016884d982e2ec0fa7e59fb34ae8708d0bf4abfc260837ef4432e8e04474e504b85450db8af8e6809413c90268801fb3b000000000000000000000000000000000fb48a8331f278845979beb8cd21060355566af215ba44029455a03d0c016daf0f6b7c5773d1a99e893e76b4411a53c70000000000000000000000000000000007056e30143058eaea89a3065e1de768d49860b170d4c364a28d38475f90711fba62c1787adda90dd2d347da72680f4eed37a5f4bfca6b77ff9e4f7e03bfed52ecf02a8f84ed3da6da2787a4ee81ad9b000000000000000000000000000000000501fa9af88e28d4f0c0590a2624239bf1724ac7174b0f1d5fd7527cff1de9971d6aaf28ba4005e88e181daffee6b20f0000000000000000000000000000000007af5e30b5aa9ad206645ace12cb2b36cc1c6068e604184ca8bfaac5a4ca327f7c43a74d43417918da7df84e3bffd282000000000000000000000000000000000bfc0538d52f277d54749ed0b69697b4c60ef0c5483d21dda76533e15efedc9e2b2ef07618457d64bae8ef922c0b41f600000000000000000000000000000000048935cd352e999bffa613e3be0a9f9a063d5b5eb46cb5056e41ba214e87f871f216ff41ee297aaaf2994a7b6433f58d81633dd6e729bc17ddc596cb1f17dc6f0e50c052a0b8c5a4c83900d918a9eb560000000000000000000000000000000016ab1e8b6f41891e0b65f14397c0887b27ff27e7463333e0938a7a1a181dec603056afbefdb23b41bbfb2c05807289b8000000000000000000000000000000000980d0ea9ad5c87bbe1aefb708061f85faae1e1e3b01c55bd577631e5bea2b5ffaf5e2478f5a8df89447fb8a73559729000000000000000000000000000000000784d0c5fa243bf0125cb2c83a4040715197e99d507d71a3bd9ca396074cfda652c1ad0dd95c3cfae369e68d3431ee7c000000000000000000000000000000000e533bb33e6d269dfdeedf7d17c3e0c19f694d151e8eef801c326cbcbc463a42558f58cbc330bdff0d8d91e2974eb4cfc6b019d29219b57404baa955f66cf1b2ee6571ad5b80d471ff6db569e32a1a5000000000000000000000000000000000050f005b00f371a7308b5d7d7f67f7c00bf15acc518942607f32686feab5eb503391f964eb7ca711aa6c7b4e494d7eba000000000000000000000000000000000e2ee5092170ea3da0b1397023b2386c65ec8b090484353f2e5d64694aaeb8d5410ae22c92662fcfa21566d70173ef36000000000000000000000000000000001549723160fc7b8f5ef9a84bd1803f18b76698aa7a663d9c107c9ff6c6d02894edc80fd00d436f3a942c05593c5464ad000000000000000000000000000000001032f49e3527cc1f1355c65edb21220c6afc88919ff67ba99c65645cd3b8ca6662dd0146f6a90d92558b3f54815a361d6a76411ce02b4dfc84ddf62ed26508a2dfa5edb5a98a6a20dd69e8b8e7ad2f5900000000000000000000000000000000170b317e49f1304570a3a3e6bef78fcf8537a451ebcfef5afe3eac4aa1aa87dbf95d0f870fd3372d37efc9e663621cf7000000000000000000000000000000000269ae0677d71b2537078e96d2593482e4d41b6d1d2cbec755f307735faaf79c01fa27f1103cdfae1a9bdcb665f592c9000000000000000000000000000000000b115d5a9fb9fd9361d0573a8d68c5193f02edc1cf3fecf004c6603f118f28ff394220f6a9e1051a5d9d4b417290b7f800000000000000000000000000000000107b45614b18c2513f8c42a0032cf0f3f300157b39d2969ef7b126f17a9b5e8e9ecc5a61a2ed4db92134b0797f6a0ea35906098e4ad7e4eb2e996075c7cd660fbc399bc942f9080404b9d0758c4ae14c0000000000000000000000000000000003de39b056f8f0248b138437db1536b7bfee29af00c37fcd14c25c88f0f051eaa07c763d94c8ce497696311736c0b7140000000000000000000000000000000002b52981e828f8dc1cd371e6821d001e1f96d57a865a3c0a255298c43d52741b18fc60903d1a5ef6227061dcb243096c0000000000000000000000000000000016b5335f0f9516f52f2ed45fe723ded427206ba96af0879958f1f22795485b2867e953de3d9b3a9eed2c37f26838e1540000000000000000000000000000000004c860058c7ea2e6e4eb2a65c1dfc20b3070f89ff58ab99bb51a4eb9e7f0642f7b32d1d9f27c668a36a9e053a8d585f394ef8c281a9be3766fe784ae017d93f608dc2cb97cbb7dd3e3814b5ade845d370000000000000000000000000000000019cbbc125ca1b89330c21ef5b42fe0dc1e795271ce4a9ecabff04eec9029f756f180520f0e7b84be2e9fa4af395536ab000000000000000000000000000000001630cf0c4f3282689a3e01b5c8f9be3803f60238bbe9fecbb0d9e8e49f4ec9f6123c44840acb8cf55f8f6bd15579e6830000000000000000000000000000000012afb848bc0ade8f0c25c6c342bb651a7481be065a48944bbedbc14c095af8a4a048fd1e776126e2128f904afbcb17ff000000000000000000000000000000000dbc984f9ff907ce5553bb11a458deaaee0efea49d6816ed7abf1dee7b70cb18cc669d4808e75678bb898359c7ebedbe6feced33019b3b66d335f2118cd22b2952cdf9757fb3a0cff55b7c4f245fb438", "Expected": "000000000000000000000000000000000be6dee62b8c85e36a216d16c5477a7c58f03b992277af83d9b53b3b2169414b72bcb4a97e3667482e888738ff17c94900000000000000000000000000000000067337c69c37ef6f0ae59fddb84c46a2afe7fe047ddb57b3b80437609f1a21fa5a73420fa5b44704ca1cac6c7a99d9320000000000000000000000000000000017fe6f37d2410159e533374ff3812714dcd07610d75a53a5d502cf2f51e750c48858db1e109f6aaf724292c1402382f1000000000000000000000000000000000b8ecfe1f5f5d95777b0fe5d94fe81b82656e6e5a62b7591788baccd251d93e4bbc6857cc87cfe6b4ed470c33631ae22", "Name": "matter_g2_multiexp_28", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000126d4a9ae3550e31185aac9011e3f086517cf79a279326c264f51bee6615dbcc730d78055489b5602e91b08f96d23882000000000000000000000000000000000aeff5fc04fd06c26af8b048fb2d0d493525ba5c2bde30664e7371812d529ec7dbd584c056b05fe02179b7eefbbc45fe0000000000000000000000000000000017c6538d2801947cbb646d4ec8b70b1e24453f7a984db7ba73e3a5dcf595bdbad9703f2d846ab02491e5e3a5bcee0762000000000000000000000000000000000badf551dbedcefbe7c303a5c8a52151b5460caa22004028893af4d8a3fac30cb1da1e986f9124acd5db7a634657dbd0cb5e7df372d346fd13faa90b0d6961372ce2f32ec379e5e50e7ed8a13942cd9d000000000000000000000000000000000bed71c7d878e7ecccd8233e3e604e564cba0b1ce75f726f846f3a6e2f3b4f5b12a28b8638be647f5c33226edc2bc7fe000000000000000000000000000000001914c20aabaf1f6f82063223053809622ad82a3a54668bd600db1aafba22aeee5c8a07584e263c91cb0fc5fb809da63d00000000000000000000000000000000056d9cd8f79a90d16b36bde77e546f8b3064ba7dd0fde78d6bc538bd6ce12a4f32860205d5d396bab3d70deaaaccf9450000000000000000000000000000000012f7e420708b66132157a80753678de292998cb6c4f00244d3c47a6077b3401132b73c7f52369aa2a6a90892f7be4ed913a5fa1674c20c97d08608d200f3f7611010e6a25a790853ed4ba0c5aacf111b000000000000000000000000000000000339aa1471eddee8cc0a4e4db5a29c3e4e92cfbabe023995a79624614aca522cd459dfacc0cab346b1cedac347e1df100000000000000000000000000000000016cc4ee8cb72fe09e65616fbe9bea1a0077114ca841ae335f1f9eb5a0b129a4bdc77cc6dae8727d74fe21f0d870a43f2000000000000000000000000000000000098a21da6e983228ebbed0ec3704c9d2521e935506c0567e3bbf9b9c379ce6d33c3d0dd8f5e013b431f740964db634b000000000000000000000000000000000a7a38abe8e282544ec6c8740dce8559fd264393d0a5c9af9813b2430bdb92b3150eacb6732b9cc278d0d0e622b263ecace10870acf190b373c19ce615e20e5cb96d3c6be3ec155f2b29825f8476b7740000000000000000000000000000000019ed305bfe8d8bfcc20794832b3c117715b6a658c0bfeb629e5989f265cbb456e857e53d168932589e4ed2806db7c4b4000000000000000000000000000000000e2ffda25fc316a38f556b35a7a3acb1a2bfbc1f9469a1b6427ed1f216e113a379932b0547f5370be1017a1fa0266cfa000000000000000000000000000000000ebc493c9a79b8ba58f48b90b9d287c74f505dcb484eabda79ada987d63a4df04d671d4c4ae4b32f8ad5db6a1b80f37f0000000000000000000000000000000019fc715d26c0c7a0c291ad8319e2e8f2920c63b4d4ed3f0e2f376aeddd4f7bd9269175ac8d0f421b001e2e48634f3f238d9e38d9383f09cf0f8a8077f1d1dba091ff0abdf7e77c3b65c2df48d6c6f536000000000000000000000000000000001285ff533da833a3daae7d815b1b86feb6f20b7592af8b0eb76240f390ea48b69a75547b040e7282b71779f450d3510c000000000000000000000000000000000813d38fa21c1f3c87b9c97ac03e6aeb8fa23e0340a0dff4e3892c774595648743d0b8980a7bd21648ce9b16a245ac3400000000000000000000000000000000020a69dbfb736c64e4cbc800aa415729b24ec05e901f2c7ba38e49a21c3851dc03bd4f7ec829d4326fe6c13867069a07000000000000000000000000000000000d518f3944053c8f74c0aea1d054d89106312880de4479b3dfb45b00945ff8bb58b12f9a489fa9fcd87194a71475d0a1abeffecf9b404c6bb2e2d0c78fbb8609a38e3d3187587c3848e8f9781b7e9f440000000000000000000000000000000018c82052cd483eee7aaa421c2b998ab0b4b32326dadba03c1d923726697d3940b40d5109ba34de09439e833ebc19daca000000000000000000000000000000000e4feddc3eeb3fd1eff8316d5b0cba554714713e8a605a55909889970ea2c8c58bb6c568024709def73b29a5a76563c100000000000000000000000000000000098da4cd0281a16e2e3e542ebb92269c8208a3d373394b0af92dc8a2676f9f0b6e85fda9161e32558e0569cfc7b1f3df000000000000000000000000000000000b7b54b51821fc037f02167d2e640f8dbfd1472407278b4bdf47b958da39f28c64569c3199846c293bf60e86aa45f205adfe53846c0038203d8b8df0cb636aec7d4ed7f78b0b0c1734be448bace08f340000000000000000000000000000000003058abd4e3d49c86ffac9c95b1f07b66a22c42654dc4a2e3b07b87c22024a8bb0ee084a558ac22cc9fa286861fd77ff000000000000000000000000000000000fc9a89ee26c323df22add487a6bb278ca3f4c9a91eba4e067d5abc9dd3afededb4f98263e10083cc7ea224f28d3bbe100000000000000000000000000000000058eb015f1e14da860215d59165e12feb8d1317f652eeb76b3f08b38ed943c94e632dbf8145233dc93755e44e027553e0000000000000000000000000000000010897d5c2b481f9937d830b333e7649931e801a6bbffb7d9a3ee28ab1e27889691a9f0b9616a8437c3cda942bf07282206e9d4e41b628be51690b86aa8938db066c052f3adff774d35eee1e332312d3f0000000000000000000000000000000013b88963296d8c8197cafe160846ee11365b7a991b35cf5613dc57714aa48307f4dd9c6ff9704b29905c18a41a48010e0000000000000000000000000000000016a97fff65fca5ff282a818deb8100104308b8d9dfacddcae32fc2b6082331b44fa70580018930fe1ab9d9c1b13a59a20000000000000000000000000000000019cd2038acd84c2db1f0fa1b7eccc5f7ae3da803cb72c4a1e8390d49e0adff1d88a85696d9daaebce9c6b8a2f861fb36000000000000000000000000000000001271338587f06847770c72dfb3d9a657d05f8c7a012bec77a7d40a98cb1637ae99281c82668486119608b01feb25e6dab3d349b1546a8c235d60c41408c969a0fd42425f8b5ddc1fa5102d2821bde2c600000000000000000000000000000000173ed7c70f4683102cc6a276d192a8f3b189197d5ea5dc813c7d0162a1649e906f76a1c9a1cb1ace6e4d937934b72338000000000000000000000000000000000936d260b789b1a2a9d04388caab364049395be61d320aef66ce50f052eb462faaa2017731518675bb0e4a2f050e4f7900000000000000000000000000000000070bd1254cf4b209ecb40afe248f2e53c390636625460439952ca2977be021d93fbec264c31ced2a810e8a5e54d750230000000000000000000000000000000016ddc3312f8ed359792bd213d086a0ff1540e3e5a2dedf6c450fb96a9b6d1edff9bde31fbc04de382cf44694a631178229b83950e79750e9827ed92856e4d1e1b5f0b47c6bbf3611a1fef8f2fc47659c000000000000000000000000000000000aa4bc6e1a3e6c3c45a29db74b27af27b61856e2cf385ce0e5094ad53db4d31c4af45b5b234c66a21bf15018c13ece8000000000000000000000000000000000188affc993bf6c99103029c1e406bb1a693e4f1dc650907809ba3de1471d41095dc1866578962c72538ca85d09fcd22d000000000000000000000000000000000e487a7151916694b980e62b64ba49ffc54aaccfa0b0fbc5c14fa4a50d1bfda55698df5cd8570c07030f145c49a4ba9000000000000000000000000000000000084a05dced107d29a0fd4cf817ab67017ca33018d5c7302167d08c64c45c5c455fb5c907f21c39b8a86d037a126df4e76b5ac07fb4a184dfed685b93d2265cebd02a3296a3b0416cc6a115242079752e000000000000000000000000000000000ea7060a07dacd84287007a05b494bf19a03e5a759b0ba67624c54cac3562c0ca3fa6e444206614d00d6d6684b86bcb5000000000000000000000000000000000eb2f332f4481276f931d2192c1a9f6d7585e85f248a8ac95aed398cb61bda05230bf8b9c041c6f78be3b34668a9c1a0000000000000000000000000000000000faa038219f844e379d8cce55cb8f0fe2b55548a0a0e1e37e25ba4f432e6b1a6451b8f081c171490bf055f81cbfe5f8600000000000000000000000000000000037c70d4e8befff257c4bc98a4726a961f3e2e68e7e02f9f2c94aa8f5fc67a1da44d41394dfe376a6c04240e4cd5825f3a7a25ad9f02bf51fd73550ccde12374d9b151f2f6fe535bfaa43efc391f789700000000000000000000000000000000100a24d21c0ddb20d76b6d9fe642da5ac1de28afd642ab5c08574206b8b64d1fd822d295476bbdf2ca7e9267138034dd0000000000000000000000000000000000aa7e4f2f77acfe8b4c8f3fabd56b17415ee9bb182bca1db15c399479ec60382f980067b9d4c4ef7556d621259ae9110000000000000000000000000000000012f7a7f91a988fa661c661013736f0ec92b40f571ac15a47067bb847b09ba128d1dcaf8049b941a51cacece5db4e1eb40000000000000000000000000000000007528b0ea66b6ab8d5d318f5e4d1c0e9a4f504057dbb0397b614a1adb160032127f2ac35a1a98da70f023cd343a35ffd47944c8c814f143f746175ba0b2d75e2ae73730a265d869763f0e986c088bfcd0000000000000000000000000000000015d72b8d4e71cc092c2875de80f3d12e003804d980a4b1dd13cff34e9336397c4533b6ae3a03beb2f09312a605947a270000000000000000000000000000000005976027a98f7b0caf4cc7d0d71440d3e4fffb1ff65fbf32dc890b275b646f2a32600a6215d6b2f999eaec8e58cb6d5c00000000000000000000000000000000111583b7734be53a7d4d090486070cd3d9622156c52871ec79c83ca024880684eada56a36b58cfc3490e65de41e10579000000000000000000000000000000000fb670b553c2ed4c81962b149efd4b0c77edf6ee70eba88300cf264dda98190e550540fb9fb95748599bca3abadd752030f33b187df3516866f259ff959d57fa9c53323d5c851fdabb96e5ea470518ac0000000000000000000000000000000003900e7cc0a8e891dc4dfc45f08d97e73ccbe2021a560a92c493aacd9c0614ad100294b5d7ebd634ffe4e5ea301a26170000000000000000000000000000000011ccc136127189728a7036e85d233fd150d5483963c48074f9d8ff83a0791c950da380e717f2bd0bff8fc115e9e886290000000000000000000000000000000007d3e76bd1f22679d228b4ee50a60cf1bd1fdaa171372cfa34bf4136a091abf7e5ef3c6b3446fd41d5de68b563fc7ff3000000000000000000000000000000001107f636d9187155357bea75c943dafcfba2394a9300054026b46d6f9db31eacc06d1f64c2b139af297dc4783026d98f4da8401050f30459e026a207ca631f0684a10813c64ee86dbdf06b7b29cd9786000000000000000000000000000000000e3a4101f6af3cf0d5d5aa5a0ebc26852dc69f91c06e96c5f1c7f8e4528c3dd92cb6f629620136ec356f0657fd9ebc6a0000000000000000000000000000000008d34dc3e1fa8bc22258e23b504d442a11938370325c101f1cfa52f313724e0894be722646195fd078c1a49720cde8c900000000000000000000000000000000163730996c79787e7ab89030de2c26e26188187762fa128ba4378a398ebd906dc56d99cf228591f394396248665c196600000000000000000000000000000000008f0a8b3d003b6727834228798950fb7a3cb6b931bced4540693445a007b474f7459ede17f87158e932e4c9c094ab904d940555d48649f30026f70450b2caf2b8f7148b28bfd4349458ae89c323512e000000000000000000000000000000000cc2d30f7d3869abfc34719f40b0ddaf00f52bcee7ec09a16de51785d55531fa7fe3ca1544d7103b9caf7105d60d9e930000000000000000000000000000000002ebd8af0bd3f82dc9dca585feaa83071534b2bc2b3d2aadbe0d01d759ade77ecec3b3f7b72f82087365a14dc205add80000000000000000000000000000000011aa3734a4b9168d3c46944cd726bcb203b94b25a97437a6aaace9c84da708bb073ee10585f28bc41e0601567863c193000000000000000000000000000000000ceb4ae5a8b506d31e77e2a43f3af8ba9459b887a927ca5287edbc2ba7c7cbba85a6e4d35c099b7ec7bf7eb2814cc38ae140e30424d2cccc91be1fd3a62d9ee49c9d64fa062d9350b3fa567ec21bb06b", "Expected": "00000000000000000000000000000000192eb406b52075513584ae3c6093fb534270d716c79961d0a3c4bbc44096a2e8d28228363e2c8da54857945f1b983569000000000000000000000000000000000ee0d95748b13b531821ddd71a15fc529a2ce2c99a66f14e28f97478c3c2d524cb7c4cd7e71a1027030765554b8f50f7000000000000000000000000000000000610ab3e064532ce261aa2ba4f78721ac4f78661cc13fa09ccc279267e6f703f1bda17265a5eccb0061ce24d31e000ec000000000000000000000000000000001966a334b16e64e4dbd66119af97bd2b8d6afec0eb1b8207f437c00ab134ff369b3b3c1bf51b871a7fe8ad1ce93dca4e", "Name": "matter_g2_multiexp_29", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004c22bd94b82ed3b106532a58a0253daf51f579b9d746c624bbc6b58603942eb139c1b576241ca8fab5bf1c457112bd80000000000000000000000000000000010c6f7551d758d1128add57b110227296e060074e4cb934132368f079a794770ff406fc7717867df0f461f5c9fe56960000000000000000000000000000000000048f88afaf6eee5039b76c0c5b4b49671f6fd04f38bdee1b1c8f347a9dd4e6aef387b742c8f9a8aa387ab4d01fe4267000000000000000000000000000000000e7be987d0411dd7138e47ac00f9f07c4737d93aac501edd16362ea5a633c9071a6bf542d4db540d75edecdedc3a8f0ca57b2c351a7946a20cbae1fd789ecc5f77376b09e911749831e9b5680185b15300000000000000000000000000000000056a29b523b0cf85ab04b0a496e078dba5529cb9699e567ca42f9ee3e3f07b61ae29b0ce17cad23131375f624a366157000000000000000000000000000000000acb91d1f057c7aec1f7561614a95f8db2252cc879bbc2595a5f607d8b0ecd6e6e3ec19849eacfca62d870b049ce84910000000000000000000000000000000010d9459e07178af8e125c2f66de699cfafb5f87a63454e24d0ed88b6c804a9ff204f146ecf4d6db62234ace0a944acb20000000000000000000000000000000007256a68e23b43a3b6475b3cf209ec108bac13631ca448cc860672c65c1760a8299fe941ed5bcbbbcf63a683e86806ae8fbff9f8ac4ad10718d46a857ba28f182263bf2d13c8b6a00902af737dea56160000000000000000000000000000000003e33b840426a6bbe15b23fceba829bda9a5ab89d37e60133874f61bf1b10e05d460bb5d228cb178cfae2a5f41035d32000000000000000000000000000000000a9c5460c6443364d9f9440d101d92a0037343789ca0aab6dffcc2bf81e1aed312299a21556d16e55b1398334d9061f00000000000000000000000000000000015db251708253f7de13a5eeae5aa76fec415ecee1ffd88d882580da5da8d9f96c6ff90d920b329096a103dd71e7cfa580000000000000000000000000000000014c3a004cb6ab8465e05d965dc720b37084d98de424b160062f225dd0b67a8e62ae11a3c7bacaa129a568f3a243357ebb061de16f4f609c6947733b58c6444fa9549721fd9a2459652e8e4b8c69b5d61000000000000000000000000000000000c8fecac8bee21d916cc47b96a66b7a522ef4fea76fcc86ec490ff44b46fc01ac0446e3885e36ae7ab62a409ccffcca60000000000000000000000000000000011676ccef54bb27ab7db0b5ec025a9d1f29217030f3686e71564fa011d9fb598f44a8bed3da8fa7fcd10d01e3f66d86500000000000000000000000000000000093aecb91956215980854c6f19120777983a160e16026560c8076bdc4372f53065f9fee0f5830ea192aa5637590a745100000000000000000000000000000000035d773ef15d8d99b600a6a575eefd661aacb49d6540639223a454594570d0f00ba37340b63a2c8a0d4e53ee7dc2dd91355ed5b57b28451ad98fbacd5ae87551b7304e4ef5cf7b7dc443a66432406f9a0000000000000000000000000000000007b2891e9cea2a464742c7f962deb1566c9d4f9e4e7cbee1912a72c5b064211c39801bf42bd888bc239e6b4ba71d700300000000000000000000000000000000169cf5e706dff2945145d5ac14bd5fc8f7e7c3e5f7ce733c865e1882d236926c71853efbea26e13efe4eb0d0e7ed5db6000000000000000000000000000000000de9ee19c4bc2fac36debd4c91317e54f57e761866b134ba9a0e84a8d268b11674110ee8f91aa8a6b80eabee2e5e75ae0000000000000000000000000000000016d91408a670e4ee43ab8e21cc341596709113950d22bdf5073cd90f520667699e94f64f76290f1bebfecfd80a9e051430b6eeb01874ff4b0fb07dc9f23d8e45455c1480eba7fb3033942214e85a7720000000000000000000000000000000001982744a15e8163a6f2ee681bf27a68996682216037d67d91993fbbe040e16ea21a9cb600fc6a40e7289185393544c3f000000000000000000000000000000001131d7dd5a5b96ac1f4c4aa210afe7af8d371cc16d32289aad38c93afcc1d3be53716f82e9d14ce6b1c833f7f5871ad00000000000000000000000000000000009adedaf19fb8823ec55b803c9509ad98217730bfc6424c8b69a071e99d026492e7c8c4a06509491a3bbe5893988c357000000000000000000000000000000000cc60733a783c7df76541daddef2245e6d2b694b94649b13c21aaffdce124c1cec3fd8ed5a5d4d4eff3115ac933e5df989a697a0e8d2cf512edd2a3c3df354eb30a3eaf697779dd9270234b367c2b5ff000000000000000000000000000000000b366a80247a8e3797f1c711aebd60c99ec7caffda34514a3716154e900f2387c46f87f81af036a383e3f9234bd1b50e0000000000000000000000000000000004608b7cea13d08724a2cac691e61255ea7472537f7ff59894d511af7fd99ad72f0a7406271576300a7d1d56aea17bdb00000000000000000000000000000000141abedc914d3d1ed587162acbfddde60f7dbc1ee5e07fdb5f3515b87d1a29024c9e19f24e4c0e3979bd938aa4e798270000000000000000000000000000000010e72c6c0510495dd2c4ecaf13c1c6404654e1be369d1ca485c76d8c2304d60d69b90c2e171f18bf55668232e747825820b72463d54ac1d8f1b3f56f0f98861768b05d5174cf1883dd8eb0410420d56200000000000000000000000000000000081d5a229481fd297363e8e217bf1f94a00f54eb6e8a3f95f4de30081bb2b9edd82d53cf287e37b459afabcb73fea1d1000000000000000000000000000000000ab55f52ff7dc578ae8267fe3fa09bdb8174dc30bb835cab9851dbee7a1aeba82e83e07d5e79aafb34643d9fc9a0d1c100000000000000000000000000000000195245c7a762776bc1e81d7111e3b814088f1e0e7d686c3ee3e500cd0a7ad4015851563a1b8b592e491e00078187c66e000000000000000000000000000000001850c1e8edb0d6dab973a9975833cffee8b5243654bc4ebe64972e423799283707f9ad343bfa86548cd2acbe04ede5da3de7997113708f9d092836c2b0b59abf710d8401baea6de73ee0689436f035fe00000000000000000000000000000000000007e9191fa9057cd7df8fb83d497ad774735c242bce9bd34cfd21d3f8f2a8e37d1f38b592a61ac8a8d22a4287fc5b0000000000000000000000000000000010e36db1460fa65ea229402f558397c6fc57e9c8a4b0b9e85d9ba938196bfeffc951587353cb7c7d84479f60c087e3660000000000000000000000000000000004d86938bebb850fea82acd336c3900b241757dd937f831dd909ce548325955f103dd57611c0b75bf71412a6ac3d6ed30000000000000000000000000000000013990c82583007b693c1d6271c1e5820d7274c4a729da21a76eccbf7abab1f2bdd6c5d26e78d51476ecf154e4fecd1b87fc3d0560432dbb721f8a0610f0db31dfdfea8cd5ebe8da3fe3b8ac5358dd4400000000000000000000000000000000009104610d5887fb7cf6a866584cae30cfeb00e1241083b017ccb82ddc9d72fdc0d2b1d227c22ff6d8497495f44828efc0000000000000000000000000000000002235f959b071f21fd63282fdbb46b1dec27cc193f3e9988def691c73dddd789b6a1adb977a68e2661fb41d62280f229000000000000000000000000000000000ccd46984208f183f0b70c9152c01fdb8ac078ad1d85f41e3a24819da321d9dd9321a8d70103282abe6d8b981447f202000000000000000000000000000000001711057042a54ca76b0c3e7f36f2fd49e339b76cbd2e053d93ec2838848d359865fdbbeb9e75e408b4b316d60ce2741ef0b271f02031a126f8632e30d8b17cc5b57de7b8b873e0971ff392d4246a40f400000000000000000000000000000000001481684941fea0f66c78faa40aeb4b5254bf78c44df7e37b191c095ff12fc94248acf01d2aac5637e9536e73a82c9f0000000000000000000000000000000016b72eff2830f49b24b1e1317c95143cda8bc11b9dc4a91ff22a24e0bc1a244c7215ab1040fcfbc292ab236ac73cbd3d0000000000000000000000000000000013535421771fdad616171f7348cdf32bea7486bf4d836b8b95c69b71ea9915c099e256287aa119af53cf6320ad86664f0000000000000000000000000000000019ba0f36dc556fcf09f0a4a6cee53de485d03d846af7afb792d16220551fb5a42a4261f936b008babc096e6f8f68b63af8b5c136aa5e2d670edcfb5bee9ff6095d85a332ad55763fe1e5e8babd145c070000000000000000000000000000000014b2da0add872d6e61253d6022559f668bf192b4aafe0acfbbf341ada55b404d42b2b31182c1ad50c73673494ea5b7d40000000000000000000000000000000018b76b74e9e6cda8466a354ff66baeb935b5645cf9eca81f4b7342f7914c9bf35c57be402458c09781e66a89cba6e67e0000000000000000000000000000000019bc8c1f32ce934b7ccae6d8ca39a263939585d8f94414c3880fc7bb5a0a27d728708e7ebc42c5a935f769adcfc083f6000000000000000000000000000000001636b62bbbe34bec06253887b78ad5b3ccda1bc5d8baafe450f2d1a8e07334ca79a40c5c4a50b58aaed96408749e6f68285193e7c10646a4601787edfad3d76e19d5b013a0a954873d92bd5293d325820000000000000000000000000000000013c0fd7a8441b6eb2dabfe8c152aa480015f81139c46440741f3da1c50d18c17526c47e8b8c2fbcfaefabbad5f8a0b000000000000000000000000000000000009da839802e7c6759a87eeae5a05146e1d226dd828d4ef6d908b4a0431008f352539f3abcd3e4c532a3d8204e350a8510000000000000000000000000000000014709634973e4554d2379e439d099e9be8bc7ef031b6ea36a7a85d2ff5090b0e0de7cc1c6b6a004465edcf868ef5fd5b00000000000000000000000000000000146779393d82bde1eaa6205e69907a0536c782fa7fc6e11e5e62ad5468f4422b3688f2ff4da2af396741ca5e0f97de3835bb2175fff61894ccbb69d90375df627e925f1ac430a349e75580dd39546e44000000000000000000000000000000000ddb7d0380370830803a7eda2e9b694af71381990f182b5d1223992abb5afe9531bbef8b9dba239f411fc422210fdc930000000000000000000000000000000018b685009d012d72193043d09f8968f9a41ce2fed598a20536fe54cb26db1733214add38f73148e754e632f6d78f524d000000000000000000000000000000000b967a7b4ed1bcd9f3da16584b08e0c28d967cebe7a07069abfb3bbce94d26b6d95d8a807879b24fb1f5ea00091d6dc300000000000000000000000000000000039349785fdb7d38707d8136e9a8f650c4491c50d7425388b75fe30da56147992c3d662f22131ba7173b2550e613477fa25856e5fb9547c48d41783bf2cd13493a1fd71e56b9c7e62af84a1f6cdae1c8000000000000000000000000000000000455d7799cc1c2af1e219b23e8683113fec126bad1dd7a441c5d113b064b552ccb1e7314dfed1b11f42a18acace706e50000000000000000000000000000000014d2400aa3e2270714b656bd755c4bba55866d6e313f619e10f94de6d82b5343ae9a9483dc10c1a72a5a21e619a20a8b000000000000000000000000000000000a6caa6cf8609d23b7873c908e5321d064a9c107b5492d296d04f92c308ee705229dfecb1f908bca0024ca56bc125126000000000000000000000000000000000b31c384423c84316f65e03ba9e01a8f626236f76e4df4b8ce2fa053c1c1e6a9b8f0afbc253db8c9c5e2ce9f9dcf05c71155c0b9c4185025310e8020eb52abb6f2f1780da15e4ba81f3c9a88ed1b4a6400000000000000000000000000000000097938bb53db8d0aeca3f2bc180039a5dc5269748e9cf065cd88e59b30733d527e54cdfa224e9690581e8c7f0881241b0000000000000000000000000000000002d52d97d4dd415fb18348f4de78c65e2933fc45d5e5e1d8f0f0ca1cd52885704ab12609b91d6d2d1ce13eecc7fa0c2d0000000000000000000000000000000018b926a37a8e0ad836846d06c03a9b84db795fdfe5f15d1fd3e0f8fef1b2825b29ee3a503ffb2f75765cca49c2b3d4cd00000000000000000000000000000000073bac093e958a3a09543e060c81b35b6598521a8685629f77200cdc73b372588e66c247097e7c03492c0943bfac4d6bc5610b2707ce84ce67e82d5c0e5f5cd2c90925aefc1e39468ca86475012df045", "Expected": "000000000000000000000000000000000f79110c74f0e983f3d3618869af1d9b96dadba61f1d596294ef8a9412f946fa26cf63483528a57299dae48f85ada81e000000000000000000000000000000000e1a9cea3af1debcf7d6ef6f7b8566b5bb52d5548d4caf85925109228d7c9b50d65a1b24f089631e75a694f8e8dcaf040000000000000000000000000000000010efc1081f079e841eaa5a65cd7c945d4f37acc92c4ace9ae6c69a9a95d8cf569d604376b1c7e63558d022da90d269fd0000000000000000000000000000000010b7f55ffac8d57c89b664c36c20b2988a493de32f5a956c91b16ff67cb806298a59adcde12ead42d598b6ca3e1b94da", "Name": "matter_g2_multiexp_30", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b139e5dddd53433362c49403838b3e2ecdd850a8df12d4dfacc0bb98f79d40966d62dfd0da1e721e7c0f298457d590000000000000000000000000000000000fa35e9c2e37bee1020ed99516174408ba2cf443fed115fe3a964ed86b5e5369e40291dbfbab477e339003ac85eb7405000000000000000000000000000000000e8fb87794860237066ed1b7ae7c2a783c48c52c2267f3e7295d1f17598b96232954e1eb6d6e80e716628f1db8afe48600000000000000000000000000000000083521e3a6d6e3f99570b747498520db5c89092b0077519c8421f9f41772c7a6e177c9cdca52f89a26c6036cadfafa8b32fac970e52778cc90396a5ba92ab98e26499eb1ff17d4bc4c1f78b64887d3f1000000000000000000000000000000000b1415e1dc2d4c1f5619b40e616d258867493d8624857e41d007f82ba8dc53f7ebb36d06f8348b94eedb794899e97df80000000000000000000000000000000001c01656fa47d62b4372361b80ea61501cfda47da5534e3e2aaa27b1e3c4de0bee0aa322e60c476fd4345340e5c00e130000000000000000000000000000000010caa407d9d265721d55f01dcfca52bde851ebd918e8fc4c752a41875940709c64599f36fae5e3ac7f211e1f67890d1c000000000000000000000000000000000b54a86474dd5f410290e4b4ac738fbba5e88c6debec17e38a52090b17ef371dc8feb0573e76c4b61d7688547a89f6a36583bac9672a77f2fe62bea4364aacf62d5e10eb3a757fa0595a81f76543e8630000000000000000000000000000000001649c78147fefa91100738e50034424244d22d8e1bb6a2bf471e4c9b29694a5c9476f4b129912bb09fece53aa87deeb00000000000000000000000000000000117a3e040c1f54b96c2435891a45fb9dd95774b5a55cfb306c22517e4ea72172332d893047f7eaa665fcc58dd21781f400000000000000000000000000000000105e8d80d46e6bab2bb9ce0525cbfc82e8b3320ee4a8b9c0086e21cf2b5895cb35abffedd1b5a9eef21f62a0a1dc48e8000000000000000000000000000000001437ee33abadc8ef6bfeca16c3edcf05480c3dd97db06e396e10d5180472f50074f43f9a031a04dcd11d803462fefadc5a8e1d77c9e42a187054c938a8a5b4bafa834021b727036ed3941b1c1deb9d030000000000000000000000000000000003b51b10efb54dbc2973e001f0bb634e36f689264484eb128de2882d6600a43ad548bc7d1def4541f0ed88a1fb37f3270000000000000000000000000000000009dd80dbfe6663ab04656856f192002593df9ef7f792dfa81f6a51c658c4c9ce5586a5edaffefd507f51ccb7e8c8101500000000000000000000000000000000144160d5ca6b2ad626e6a3424ff5139adadd3319940afa9bff7dc409ac1fc3775d5413ef4612b27fd22c02c1fe57bb86000000000000000000000000000000000e375ff490a626dd1d933a5c751c88cbd61803986fa8dc089ccbdeaa0a922758afbcdc30d29268fe0a34b7b79d0f76c139c02150e4e89b25563985c7802c0c43d00c721d521b54e767c1f509f584bf2b000000000000000000000000000000000997ade20fe9c0d3eb79e61a66a5c272d02af668b0f3c8201a1ea071737f3d2ee3b0764f859480e95be75ab8845b407f0000000000000000000000000000000003215194b6a363d31ece09b18700479e6093fa3472a23ef0133e3dce60a3d56b6fa984b900162c4ad56a6899aacf35c3000000000000000000000000000000001647647bbc399f40124c43510469cf613732d0919e22b478b2603d7553927584cd4b3a407e3ec6387c4a93e9e5373178000000000000000000000000000000000bacc8afdd70e927e21521b3f62264ad4f22adbc872439ff851d3d169a1c79a0d02bca2aabaa0b9941ab1c71d092fac12196ec0e9d2f572856217521fcc5e2869f16d5ec5fe76f7d350698f55ff0c565000000000000000000000000000000000b0c5981bf6ef5b85bbc504fb0196ba442fe87302346688165aa7df8cf2642548760e11daf5b3fe2e37b43379afbfd4a000000000000000000000000000000001086828b9560aaee5e28bcb50db8153c40e632b18c61ed4105bb7f472b6a69ddd8a2836f6605102931ee66b2f07e441f000000000000000000000000000000000f4d7aa3d1a281af6f8afb3d886774f4e4a64490232f63dbe16e3b8c4f626e9d07f7c668d09cadab3c92d6fe852427af000000000000000000000000000000000d92ea3318779b532cd81c9be44b1abb179a8411319a6f8fbd7e3f158bc970917d3e0b25f3f3f6c8e0764011f9bab0398df5017c9c35604f061a7095d976d08bb3570ef8fb518cb606cd39a3060157ab0000000000000000000000000000000000dbd83910f304d0fb2b6d8619c3a308c719f6454a357d9ced03b2882a50692c06cda7f4331f54eb293ed5aa079121fb00000000000000000000000000000000019c33ec829367dfd2610ccef9842ffaa5e4f35809657c22134fb09b024e07949d8370ba8ba1e9149060e9bd3babc19c000000000000000000000000000000000ac468b42925d2daacb8574d40064d393caa643f08767d20e72ac0fad1447a64d8743523312f3a91a118d3e51e1f52d7000000000000000000000000000000000202d1971fef2938cfd10bef5900b91cc4811939f66f1f5578a8ae0eacb2538d2a51c1e025449e1637b5173ab7fa3b6f7b82e7e565f8a521d1a9d0ecafc029f76b70042e1ec36c20e3789b49c7e50ef00000000000000000000000000000000008b6709123b9bd501360fa463dd08076c59177dc0e8035c49fa2f541eef3831e4c584c5a9410c68999dddda6c86fd9d5000000000000000000000000000000000fb94eb34355c636dca909cfa71f52471217b9bc241cd3e98907d4a5c7eb67d5bc9cdb0c73c1369d7950a014fe6069fc0000000000000000000000000000000002e2ee515a5dc96a664bb1f862f21a8d3b7f903fb87f6dac41c3541f3d83633f351ba8dc4661607d24b912dd1ab097da0000000000000000000000000000000008bee545e00e3fc283185a85511e09fd0253e191f52d5c0b440b10228041800c013db3c9322a835e4927c0ae0b21bc1e8260c1b7a249ba215f0dc127a41876f858b20f4422140bb7695c8f98e4c474d00000000000000000000000000000000006ba635e74538748c29aa7c5690a0530f2b1970554598a432d4ea6d2713a4d26786b6e80f67b2f39e218b19323654ea200000000000000000000000000000000133ca9e5e0d4a8200d3522d8e87dec3c72edc1cf16b7305af4abd466aa7a0e30159388d34c36ea030450ef45b7940ec20000000000000000000000000000000004724239afc773688ea92296bae8845f20793c05807a18d6f35f03bef295da06f8ac9dff438b720dbea7ea93f3ea9c4500000000000000000000000000000000149c12922fd69e1960274a8b91384e929fb354936c020911495e6e3c49faf16899ec0c6e87713ee2f0149bf808ac8abfcd68d2b074d038ee0d9887168dc16805ed55df26329a4c0e062c2124a6e5066700000000000000000000000000000000148a4fe6ca67b6c785d5d8a784d5e68fcd2bd08294ca37f296b6426433b805507b554eb9f0fadfa9d293e8cdb8547d4c0000000000000000000000000000000003700600c2b7bfea54801ac95ff7a2c069bace31ceadab2947a0641462089fb43f0b9697acc005a23007a923ffe97360000000000000000000000000000000001705a769ce3c9a7a91283e4068c602d85808980d6fb457345a5f9b2499ff8fb3ec8383049b9b7cae96bd2ac6106a07fd00000000000000000000000000000000052b1f4e8a48a5eb2b2580614c656393819b4f0ffea874be899e4964c7e32d54757f2d48ca7b50e47e8bf6d6ab8ee7572a40c2e796148ed1c539b0584b90cb386844fdcde5d3766cbfb1d1b58626fcd10000000000000000000000000000000012ff8ba50d587765e68f95d276e364c8c40c00b55abc929f9ec240985269eb096dd3cef5826cf6269ecf54bc67773510000000000000000000000000000000000959492d74cb34c8c9ca4a21ddee97df99c8a6e627db3ef72200f39e0402d56f0a9709596189c80aa3aa50793e0f1a68000000000000000000000000000000000f7e5dbe884597054d6dc5e80bf4d0d333025bddebc1fdb1d61482cf15bcb4c8a95ea29cdd0925b5b816cc0bb307387200000000000000000000000000000000194e940c041d71f43ffaa51fbb31eb63c23559069b42dbf8777f35eddf14edbc3f7762c7b354174a584507ad714948234a1e176fb26983e549aefff9aeb220f50e071222073422dc2c44abd85528ee2800000000000000000000000000000000101a8e54d1fc2357df60b0ef8872b729295218f29ff63f7a7b6a70b3ecdbfc6809eaa8dc1f62a664b9987e8e86154c6c0000000000000000000000000000000015b5ddd012b42e1a600d738e05b551d91e7fcf3cb36018ceda9b689b92022224990c11a6fa0b421d5610b7e59b7463c30000000000000000000000000000000016130be17fceab55387d43179cd943c85ce1ff1881c07c937b2cc0645ec9ebaf0e10718ec7fe0d720f49bed2b8caf15b0000000000000000000000000000000017d73650680856bc11619e6acc139e137f0a06476f5f8979b5ba7fb8123d85916915da60d1f2e8c84197eef518b350c2a62e07bb97ca3805ba2d30f39f44e70a7b2917889c26b84bac8f9739bdf764090000000000000000000000000000000007d26bf37a97d532ec93a3eac00d9d39b064ecd172ebd5e18228b1601eb7a2c272aff9d88d63781b4a587c2c8582eec4000000000000000000000000000000000108000e850bfbfb02d7acef97592e15ca721334eb51197511b0eb2bd3bb647fc8f07713487b0a0bedbafb106992de4b000000000000000000000000000000001868c0b2ba732731f7536851f8005e8bae7b16545b39190251eb2bf93dedbf0803a42ec24cebd151998b690c38c0346c0000000000000000000000000000000016faafe909a1f926333b12f5463231a71058aec31d73893687d3169c4c3588436f6178447eed307b642490199c507d63a14278fe7a08174660c08323de272b2110047a1d1d8bd0e3c7d76dde030e00a6000000000000000000000000000000000331338cbaeb8e304fbb9257bb80aff5d3e043d07dbc476dec2795347e4c25248caad06ad14f56183d2b6276c49ff98700000000000000000000000000000000167e9578304a1162de73914b02791468e14faa2e0f161aa57818b8a169b5933dfcab787ec0f4b23737011163dcaa02750000000000000000000000000000000010aadfd5cc781e73c31f2fb64e7981b2e28614aa18dc7b2d96d2bb4ed8c2ee9089d6ebe0cf85479b272cb049e934739900000000000000000000000000000000128d7ea54f338064cd2f041f42a1a1e77d8b9be4ee55f568786a36f87f965d8142207e518798061eb3e32fe3b0f1541d1f516ab5b36a59e6300a54d17363ffebba35fa0c64cadb21e541af5078545b400000000000000000000000000000000004539f22654b3182d4fda5ab8d4bce6f1268d4e402b6c29a4cdff3b5abe0618d33db55ccd1ff12b27b2cb0196ac53e0600000000000000000000000000000000177e80ab6aa8512cc9e4d65b06b2bd76e33bef9038cdc1ab97fbb9d896ae2ad884ea16407490653dbe972b14e9c30c0b000000000000000000000000000000000c280a4431e41df6515979a694ce292f220278178f7f36e23c8a4cb2b8a7ebc520901ebe34c72a26b2c8a60aa1a155100000000000000000000000000000000006a0b80538a6c8093f3655905af1c59c235567d22192758c28dad1b715045189a412e4c1edc26e1d8ac95a584277709b3bcdb23f9568e409271b5f907fd64b0cd81939a52a6db38fd8d95de76213f7b5000000000000000000000000000000000eb091007672a212dc4937b314576963d7561657cf1103820ce9bc34e4d46c24f4891a4a4ada648f8cdd2c30f670b86200000000000000000000000000000000166389a37e6e3c02317d68d54f29cc98d1d1df5853940555161d71df791cd92c483eaad87dc0e765b12408d6ac344f31000000000000000000000000000000000affd0d5734cbc27b192c0c0e464db48d3d76799d2c6a493b172127ef2df6ea18a33898828effeeaceb7a203e35ca41800000000000000000000000000000000155708b9756752c9b44048c91d71970fd2cf2a4cae6b0baec00629c81387c8261150e78f856093d81e816be6403f1ee91b716b02b3e94600867e019be166f4532d264e0aa65d723dc0e117aded59245d", "Expected": "0000000000000000000000000000000007ceeb14945414d96088a7900c1120ff182b2a93b09943c2fd1dc2b0b223f684b0d4c0b1b5803502582f2daf16d81d2d0000000000000000000000000000000008df450fb25534fdc456a8f41cc143a84729ccb082aaa2243c8f37e34a6670f5195750f8547444c49f7a898aa8567d980000000000000000000000000000000008c12d360078d5645b0e095c90d4fd37eb20f0ebbc6fa93fa5beda7e7c78eecc06e0d839268e2c303422ab1769402e0b0000000000000000000000000000000002bd594a21153d7c458b9f804050d05caf2d90bbf9d18def79eb8148b7f89e3a3ac21f84b87fd13c39df5b91cf73460d", "Name": "matter_g2_multiexp_31", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003e06e2dcfbd695e9bda0baee1276ceab637fd1fbe2d2d6458c923c35b00edc7edf4f9e797aea59ff8cfceada0615a02000000000000000000000000000000000a04a2ed5e42fac7f064b43d64151a6c517ecf22dbc7563a3e9f35f555a9992fe45cf6a728ba94607df7c96f7e0a334b00000000000000000000000000000000090fac97f9f524168bc930d26ea1627ceaf187398d6bfc5a019c8467d75cd31a41c7eb9fda35fc85bd92b4cfca92dbff000000000000000000000000000000000f37b91dc935c28668c27d38328a511148c1739b65f2816dc53e42a8f059c9b2be7417a6f97c9a2597b1a0f06b7afc65bcfdf0495e49dbb8a8f9a0dc517351f39a6d823dcd42715f329dc78400bd74fc00000000000000000000000000000000090b834a587521729426d5b134c6058bf7999f4d4bcc0812e8d8b3ebb050961321b5e93356e87171a6f12160749394ee000000000000000000000000000000000cd5148c7eeac4aaea4288b38a02b5a901a6e2805e2b1695ed98ed86cfa0d259d87b65bf3cc9d00b8548100a60a371d200000000000000000000000000000000026db1079b85411dea0b9fca383956af50b938a465f35347605c01f3b72b297630ee2fb5252da20ee0d8ba5071974ed70000000000000000000000000000000012ae26c193e02d7ae4a7a01181551085dec9fbcac811c45d5cef19abf736ca2514e1259811970af5913891abe22a75ecf095238bcee61ec1317c0f98ad4f8f9b39c5940cf37a8a3a676787d9dda99438000000000000000000000000000000000ed5d8a609aa4f3c65a89b8dbc9334bd3cec6c7763bff298acd6c260e4d3bec0088e15c5d82618571d13b74a2031eff1000000000000000000000000000000000c28f92f018e6f822912b6eccfab37432ab0ab9acab751f848401791bd2f16e32ac6d97948bd8a0bed2ddc1917f0db3b0000000000000000000000000000000014083be2539d914883172cdc70950512dfe7be8893b1ecf085d837c2e9ba7f03656c5a0e15373e04d300869620eb66d00000000000000000000000000000000002561b77cc2658c54d29f8d1988dd7448f59c80c02ee9256404d8ef5536ee50104cbc11b6ee1ab9ccbf0ca55e53c52aae45a6d64cac817cd479a501c77b6720c6777c6026dbee471b490fee9f242a6700000000000000000000000000000000000fff05aea33a9d1e8f7b227c80ae87c9e7589ba2804904b7d8386b24b0e5324e718f29531251969a972870a30c310630000000000000000000000000000000016ecb8f27a369df13e122c981e7ae37882b36d5492fccbc86d606aa1198f3e4ee7bb7ad0555e11949e6c1783d8f4cda100000000000000000000000000000000187f425b675cb12719a01ee3b78ea73d88f70805f72d6cabef6372ccb9d99008bdd7da54f155454c4c59f041deec86f800000000000000000000000000000000151c272d5cb67b3f801e103ee901deb4b3d3bef76ee4e1b2ce1b5e663ed292845ba012c732d38f9209f82e77f1f73cf354868215022673de608cb43a3cb74ef2073ffff34c54fbb43f19b22a02bcc2ad000000000000000000000000000000001791bd59815309f2aeb7b07df8afd89a288eb6f19c7e613f394353ac5398267e1388c97b17d83104446e57f94581a79c00000000000000000000000000000000154cc72ada5a9c99dea06ebec143a14271cf332b57c631725ab30e2d308d6b688ca08a79efb6fce632cb1216ac3d077e0000000000000000000000000000000012b4c6fe8c17274ef57539563a736c2f83c4cb473e9d075a976e18e193255057340f45de373c7d6e3fe5e08ad0dd97d20000000000000000000000000000000005aef16e11bd4e7787bd5ab4427276ecdf9c6c134b9fdb2ec39e87ae4a5b3b674b5ceee29bcdf804ebd7e83960d8d7ef7068c3ba82e52fce0223a9f28c1d42681c7863c94797d1786c1adbc3e6d10dbb0000000000000000000000000000000008e57f905fa202c7640500746b590791cf9d0f160a77e5eaa5a30280e513e8e801c4b6b04cc3f80d9403388571d180ba000000000000000000000000000000000da3c128ae234bc27824062832ac10aa9cd4978f37855a8b4cde3822f5b485fddb9a475a9805e795519d7f138a8199cf0000000000000000000000000000000000ec11b7e07710161fc557a56e04337f71aaa1a0f070cd84525965e53a1fe445c91ac07c618ec349997890ae893c165d000000000000000000000000000000000406b0eafbb8782d11f5dae2f6214282252af9ae9ebc5c17a81d4ddded40f05d0b534d14019bcb6cf4e49c4c182b90f00042b8005283c7b91ef4b3ff7e20a91349c8c3d1301c9b54b901e8348a7d186e000000000000000000000000000000000b1d456e66671dfa72ef3a56523eb939146226111fdbbeb697983928aebd5f50b0518db841a3d48912a7a780785c1f180000000000000000000000000000000007a15b2253496b78d270dd55b80bff90583a95283a89d40f6df71fadce56d103f0d365fe79256fa4f93b2d2bf4c06a2e0000000000000000000000000000000010829223166d38fd2c3041dd5643c9784da366a2ea8cbb3abdffb5fe43e975318c86de0ac9ec77c0126ee75bd209f7300000000000000000000000000000000004b124018e83e1e5e77bad42eb831798d450f8ff4a79c9b14f67f080047c491fbba45db79b2cf6015188f9fa6329e8be0a3eb64ce8fe140d94956b0685f91a5462dba1a90093e803dc617559a66d20da0000000000000000000000000000000011119be42b90c7857079a51695dd5be08e59374b0d1c7e12d0ffe870202e1f0c62bff84c9691679a82e610e788b7b5e1000000000000000000000000000000000c7a64524c5dd1bf10d16da7f15b39d05c9ee1620d4dcae79c60316a1f522b238e7934d1be897a441d0c8e621b67d44c0000000000000000000000000000000013045613a090d05d07310865d977c8e0bb1caa713b2249d6676e7cfd6f4e3ba8e667deabf9fdf7fd527685f7d251b178000000000000000000000000000000000dfee7f8259701b5726b6439a7ce77b92245499906502c7dfb384e29cafea61f3b1f21fcd7888231569ebf29d3035a61ec88ed0eac8d0f2f618530e91cdb9ea36b8d56c1001a6792a09e11ff65fc02aa0000000000000000000000000000000006d77669207bb2d064824cb56fc786c631936d30db630be3c08e18d7e95b1c26e2d4e7b2eddc2f946fba6e99acb2198a00000000000000000000000000000000168bd8f291f8bcdf8b5e9fa915f7f24856a62803bbbeb9bc38384149008d4e3129338035061631f1fbaceeccfaeef4a700000000000000000000000000000000146bf2dedc262557dec2b4545c94a37434e20e4900b1693e8fa9bda9a94dbd07e0a3bee5f3bedfa42148791f4951db7500000000000000000000000000000000138467700fd5088c76af2f77fea4b746f98701fc0578571997b0ac2fc343354ddc8b2dc57d5298dd4daf767573d8bd3d5f03e53ff983fe4886a3dfc03a353fb77927d7a0d1998a1c55ca7421a4bdac6f000000000000000000000000000000001536da0df7c91687339fc93608eb404c5f46adf4b9122b99b1e5cee0012e27ddf30934d8f669bd39091f8673aa3b3c490000000000000000000000000000000002deaa8f9349e7c551e39751b1454a00f8f7896d63110e8e42607e8023ae3070c4abc9885ed54ee37a82f6e5c68451e900000000000000000000000000000000079a62eb17f7b07d4117956d3dab5d16a7f90e98948d5c3caa124fcf755c73f060a90d002cf880f5246a87342717b4dd0000000000000000000000000000000001246f0f3ec2af7c0250ae14cc67b5a1d42309f06c6f47b89178ff7534c47e8413a26a43f27454c0f946c66634563d41cc1b04dc356bd348211ccc4c50d12cb382660a4f9526539c2a0c52b021ed216500000000000000000000000000000000046e4a08785de985c66c7417f9262d363b9acee07e250999a4a7124f101ec4d82e3e4b2b0d9736471329fd61d0cff13b0000000000000000000000000000000017bf1e20ac181780ced62a18c78b378fc0dad157cf30d6026680560b681f5755183bd30b4e454764c08edb93297590b5000000000000000000000000000000000a57cbe93254bb0796eafc0a57330e38bfca37f8b94c4d21ba656e5616239e1e18ba6d632c0129d30291736fe37a4ac90000000000000000000000000000000007f31df7dbe9abe15f4024d8f6bed93c92ff5bfbd7835e08e870eb1bc4a6f62b3809b922c6d5a7350e2e5a978c80a67397b584ee05c27d45390aba36772ed49d571837567e95f1fd3ba3fc1ba5916727000000000000000000000000000000001577abdf6e915c9c3b3fa50a4601709cd629397f2f91784528e4cdbb140065fc2a6ee3830983dcfd49a928e78cf530aa000000000000000000000000000000000d6f98df9e41009837cbb05bc3e3340d38e56a448fe396bd48acf03f061e7489d1402b36a84b3c56eb859437e9c406f1000000000000000000000000000000001912afae5361c3d8c6141755deeef26d1fadf6b0036b9d05b2e0c4d50f42328741f0423ac772fc66dbc922bd4a837ac40000000000000000000000000000000000616661f049b5c784ba05334b2931509e1e033bd203fe17f04cfe12e80e73eb7075beac9d379fc1c457bea1b6adf365752542cd551cafc5d50852526ba0a23d274317e1e4a6e75c0d19319e5853b8b6000000000000000000000000000000000f98fed7e4d67a513c746d2fb188597a605165d5d299072aad6d621e077845f93804d575a5796bfa726f529dbd90e014000000000000000000000000000000000adb2d0b6c02e4e8fcab11c7c8819e87f73aab673ff9dbc5c50fee751bc7a6a8d386c8f9fa830b5545f94a73ce6e1f1f000000000000000000000000000000000f08e05ac40655cf59ee3ea9f10fc900315c6f06ffd3b80853560559f580ecdd65aba5ba660c729e0bb9576eee3703710000000000000000000000000000000009da46469f4b8fcd8d2b016e96f6e6582fb01c75407c36c7f87b4a1cd8f08ad06e962a0ec2138ed6fabaa1cb0115f97e2f76a0fa585828f79553fbf3baac6a2776b782de66dedd6b734f9342e734ee3000000000000000000000000000000000047b45ad2ad4f7b5b72194f98b98b2150b5d73a9df2aeb2377beed9a1275a882fa2d849037ddb56af632489f892a48a7000000000000000000000000000000000e1b0d9b52c0c5324067857ba4701f5f20eec165be418871fc0f0adbc3a0bbdce5a33277a33b79013109b81e006c621400000000000000000000000000000000179c471e01e340d8e6fc0f737ec09f0180bd2dd2a86d0817f753d1e9a9f8cb18178e9de68c596dc6a824e6c3c151d8b80000000000000000000000000000000019405c1e571a9b200ff2949aa74647dae59d92a8669d4876ba23f1b4a12a1f9412412503c68acbd619cae3ff056bd346f638e6a70917c89811851109296a7225f9c7c5b3d7fe6d6ba6c7d1ee77db4458000000000000000000000000000000000ca8566b9bd088c471fd33fb7b1bf760ee12cc8b0cfa9ad92b45012cafef5c0772d9bd3bd9b266d6c3e3890c8f00057300000000000000000000000000000000055789839e786ecee7fb7d10f3876359fcc1bd6f2c5cf25c8337aff7fdeec9b43ffbe932cc4936bb708571a59e4339990000000000000000000000000000000013cf827bd57d8179d105f34c147665a072714ccbc114aa4e878d04ce66ca78bdabdc4867b3968c75dead147257197c6a0000000000000000000000000000000014a8dc5ac1858442ca627eaa194e1ba64091b5f9ace551338d770c92fb49ee12449dc200c8c35d70f9e0652b4d9b90da1c4ac944341dc68fee586d221db2a8167e833f18f012afa7c3844def6dfb26bc000000000000000000000000000000001124ea2b97a6d73c81387a51e814b9bdc951a773db2a32d50691be60f1d397cd4aadd9b06e4f49c32b12254e9f824fe80000000000000000000000000000000014cb365e9780feeeff3548f34a56548302ae0dc73402c40317fc819969ee9c4ea2a181381b94f82dd97a236671b456a000000000000000000000000000000000064b769c4b785d45472038aeeebd3ba9b28b3132d72023640ab2d7512cc6e31296c5330be5653ad6902e4e15e57e2c3e0000000000000000000000000000000014c7bfb1f142d69c17f73e23011aee0063a97a99d982d25ff72791a65c7a68941a80fc216cea8a49f3df2d0748b1f95db0eedaee9347b10ab7b346fbc16c10cc9db486f561f88b756c269ebbba23a7f4", "Expected": "000000000000000000000000000000000fb1227806c750e0eec0b865daaaf51afb74a88589d1c035c60dc1913f05c8ab18de24903ea876fda27b97a5eaa2fd7c0000000000000000000000000000000019903e1341f0285658164f9273b5c958060bf836264502b9dc298f75d4104d7a43b8d5dc0bb934a506ce1273ba839d830000000000000000000000000000000006e791347b54057195189e8b9f10fd42d170f37d455c0af5e92cc6a12e2c23990253be6855f4be6c84a708852c19a6f90000000000000000000000000000000005b72c361dca430fb2414b9d5a326cef8b77cfe5310153d6994dc1f8b9e74e8fbb43079e21956f428ed8aa48d6897e32", "Name": "matter_g2_multiexp_32", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000052acff88605f33a0cf1201e8101c95ca0befd443c087265821a7d954917a026d41ab24d29bdfd972bb52ff4ad6de14c000000000000000000000000000000000e134b2aac3f6270e43afd994302426796b1e362031638fe0263c0ec212b828a30d8321af34ef7bf260652150cf2293b000000000000000000000000000000000d6628f675008099e9a75e1294803e86417ab22670d36316798680289ae61a26821693f2f9efc8468721a1097c3bceb20000000000000000000000000000000006d66ffad1a2e0f39488fd3f6e0214c9407528c8bfb8d1ebe6d75596a3e3cc844d00fdf46ce7ff6cd6d67732874a24a484adc8cfd2e42abc2f0e0d7e9c4b378f73731905760bfeeef01c94f8d5c3cacd000000000000000000000000000000001160bf0f7f2915cfc64e12a5a91b7e2aac78d4c2ce362e7677dd0e9c0172b37fd1b52222a13c65819b87593ee32a9ba6000000000000000000000000000000000c8be2cbbd302b31b1ab6dcbeb57b4ad428447bca9159fdfd007f5375218d121673a010f2c7fdf83fb45883458fb068e000000000000000000000000000000000363d3d492e6e6901756bac13b5c32d55aabbedde878115aa41b57d27b49a0f017a61fc90b13a20e009989374b82f5dd0000000000000000000000000000000009302fc26e6d750ff9441d7471903cc296b320128de71f86c4eacc80ce0725e8eea6acd2af056abde2f61e0a349f9bb5bbd5d4a15998d733326ce23cced86ec5d5b410c29ee98a4de19f2662c3933dd1000000000000000000000000000000000b12aca17efc103cad500b3d773e43cb24df6be651963c0f30bca489f1dd7911ffc7204fcaa4511e161c6f75da4a5ff600000000000000000000000000000000179a36e9292d3f78a5fecbec1175f001bd4ac0ff3610f596aacdba29a12ea4844885a7c465e66d3883c7fc99d4a7e06a0000000000000000000000000000000016bfd0758b31f54f90eb8562bb693c45a92a297a3d302279c9e3cb8263efc0f31579a3af8e8f5a091d9a6a36776f445d00000000000000000000000000000000020f6c66fa554a5cb610ab05d194e7583e6798a113b8fff336c986f7358bb9fa6a7aab0b04be9b5c44a6fcfdd21999e83717aadf16301a9c8741d65c86ad7f849101e30b7b1a344643b100a8582a6ad10000000000000000000000000000000004bf40c1d2d3574ad7fe128ee376364591b6f647f939b0b556ac3fdb5a92873f17c007e926b8a39a97c814728f355bfa000000000000000000000000000000000b8669e10e0a538a421b717287455620b82574b96ed09f64db444ec73a67a3227503e1b4fd6869314214071399eeae0b0000000000000000000000000000000006ddea4adb703d7205b6d2af436b41b4bde3a8c5dbed9dd161c9b3b466ebf06beced64fca25c3bbb97f232315daa5565000000000000000000000000000000000d97248a25ddf0ebd0200c6abbcac9ecd9775cfc5ec8da91634e77488bb592e5ff277a9607fe721990f403dd73f746e622788b3597da7b9b106203dd0ea97527aa8f5149754bbb0c10bb6eca8a46d94000000000000000000000000000000000135bc4f28663a6d7d995f6b876ffb8e6ef1d2d0f232388aa5f390c57e8c48cb84d370ebc4bc267eae4466a019c9ed56e0000000000000000000000000000000008b6a9d13dd9d7014df6acb59f80b335a751fa2ba4dce63467aed18f68358f5cb743718112b3cb2d0b5add34bb6989000000000000000000000000000000000013a5389dba4da195f34fbe798b254403f0bc5632ed98bd6017ef24fff33640ae493c1bb7a77a0d3c97649230e455eb51000000000000000000000000000000000a69803a4cc237ddfebc51df2d90fa1ad03359f9635ac1646bc942546575d1558f5f2c3010f6e2207849ee697be41d093c21276fc1371060c226424eb9886de6897b15b075fc5a51aab4710e9dddd384000000000000000000000000000000001939c2431f8ac4ab19d2735f122c0424af2ef18c0028e155611237e86648bf1d74fcba3008f5c6aa30feb5d4a14a3f3f00000000000000000000000000000000174473eedb54aafc522973244ec2feb3f7e95e50a1e996d1100c8da4fa59428c280f76e9e7364906662c4d2802235aa5000000000000000000000000000000001021d15f8ae2f62dfd3862944bf3be88d86d8113f4be22544ae5e925d450044279c5bfa1bfca44cd5934b42a27096b510000000000000000000000000000000015e0f20efae92e1fe8dea2222ce808a7de9e9e861c333db139f8ac11d7c4fa9ae6e49f51095f6e16bc738dc6d094b4cfccbce4e92cf377f67244995badc72db0b80fe37c9b7d443595156fa41abea17a0000000000000000000000000000000012d70691721f5787ea2e2a652f9c65edaf763637f95c285a62d32dded18579b7257493e01eda19631d00ecdd4e27a9ff0000000000000000000000000000000014da9ef6076e646e7d5b52d1803d3a6d897664851c6de2a9b330e48695737e05f0369224c3eb357bf557625bb94e6ea2000000000000000000000000000000001554f68124a91be5b9f325394db23ed5db8f6c46eb46cb50e57947bae00819b151afbf4ab4949290ad41625499f42dc00000000000000000000000000000000009fc0d459e28cd1239d227e1d2f7d530b9d14ce5638cd308569300a791c997a51dd5a98aad703239a23cfe7cef7f47f6ff79345f31c107841ae388f6cf116d10bc696aec4933de56bb9affe7e20c649f000000000000000000000000000000000452580d6a37a07038ce3564a12c1c7391fdb002cf27a6df7e194b38f3c12a3026f2a8acfe5e634cf89140da256d0a420000000000000000000000000000000004b73c9a4f9d41b8b84e53de538e4b15198f50247e75c274c14f136d7d91dce4a62c5346bf11a105f035e29ccac3dbb70000000000000000000000000000000008a8a3b2705a82b551f8913853f682253e7f1f68c8e42f349337f4f1eaa5103f59430af0c4a124b6a739bf88298c5f6f0000000000000000000000000000000012f4220609899e8610809bb3a4da46e0688c285ba2e8750b4bf44a849cf15fbf5c016e8e8f9372239bb562e7f38916e921cf773387d5351aeab99971eaa3b207fa6a318ad60f1c3e16b7f68251f9c910000000000000000000000000000000001884558e709635c046bd6ea8872bda936ba4d5ebcf7a0208cd0a4ee08b69f36dd2e136ce655ddfd89a5b1cf8e48f5ef7000000000000000000000000000000001357e2dd9fb603e5190d7b7ee105668bca2ed23ec6a248aa71aa430c2b2755747b8dfa3b147eb51ea644bf0354a61ba000000000000000000000000000000000009b0b0a76c6980e62e4893157b85f59345e1ac81e1aad1e48acec44c4803e2a9080f0d193fb799e0277ae6f1058839e0000000000000000000000000000000014c984ae4ef5d9d319fc89895f34a7db02747f57b206b0b30e8c9757d4b47419e6c0c8378fdec5aba364936a3b1922ca2d69cfed6bb2d33fedcbd215dd4e9632a3cf86a4b2716406305f6a85e6090a050000000000000000000000000000000003e1bbb872db172a1fa615155f81aa75ee9760f8602e4135ef9f1640b7f9d54bda911a220d211dc4bb767bc2b5e6e23e0000000000000000000000000000000008464f23cf693b1d4545b6ce4aecdc8fd182cfb288c5ddb1f78ca578e9b16342c8178d886cbb6b8086c0fd1318c4ae09000000000000000000000000000000000af574c4d0fd86087e23daf6d9ce98765e1e445ef9152dbd68152fa4833ada0be440de4abfe7c07dbd4ee67f1a4aec9a000000000000000000000000000000000a8227b982f9286b03c4d49766687622206213d88cde007360df9b4ca5916c44ce44dbe6443577998b4b0d527d22593379cabae288f8a9a8cd54523c20825b8fb07886bbf0ba0c5c807956f268af4fa10000000000000000000000000000000012e31070a501a7df7be43dc23e23dafa32ebfbc10ffb4c53f5d36bab2af69db5a05ad64b9ed116560e40b71f9217189b0000000000000000000000000000000011cbcd38ec3c6a6d49df6a8d6e1029a0412b42bd3fe8b42ed625adeb5a2f631e97bfad302de82ae34f715962b5ba0289000000000000000000000000000000001019b1b619fde9fb885d3c5f03a4373358107af7509754ce1ab2deb67df536d05e07ca7d60d927c15b549502750054f90000000000000000000000000000000018f1768b7140484105cf3ad2daa7c565e18eaba834db3f6bdfc9ee37445f2d6f7dc2b4c986b7efd5373224d2c92aa5a81973977d8e8c592f9063c5a14a658990f9c3405643089eb58324cd3f05b5b5e4000000000000000000000000000000001847b14146cfa2e1700f368f414b6a66ccaa02ca2a90b40a8e2be2ee4eb66af77ba563d7507de63362fb18426b6149610000000000000000000000000000000005c028d2b344ccb6400b53134bd179028b8774000ace89369bc655bb9dcd1643aaeec830407ee941df5432ba27987e8f000000000000000000000000000000000c4a680e2157dbdb53ae761209d505b4cf6b18fef5aff1c5009ab41295e0ce2ca23bd7a4f983fb9d085e1d0dbc75ffe40000000000000000000000000000000013c0cc77a5d771f1df99d1530e65ba782604c1ecf67d08572609de9f18405b9b817c2643226cdc7c9ad35beebf87dab0a610bfd375a7b8d0b034c17c8fa27d4366b06c681131fa7daaeeeb08e25c2ca60000000000000000000000000000000009f32f2f83c21875963818872d243cc8c70b75234f53490eccffbf060cb3b9c53545c1c32025b271514f500b20b00ec10000000000000000000000000000000002491b571087a9e89dbdd039ccd2c37d5d8d25587495b2d7b0066e9dcca02d44b2c134b0128a9a1527396729f069df83000000000000000000000000000000000264e9c47f72b639597de8f26a42ca7d77324f8c0db705986fc3b40dfb46f47764b69c70037a68d76a5de49a278779a100000000000000000000000000000000090614b3bb302ed9fb78b8756524fb78d54a4390b27136087181342571f994b1a93faee28256d765a8ff4f448cc357c199ffe1dc2d7526338462860501d75380a5ed9d53e675125342afb6652a97437b0000000000000000000000000000000012c716ddf17fca0d974e8d6003d99aa90f06b201fd141c74d8fdf1167030d14dc732917d3c6f736c68fbde9df50c098a0000000000000000000000000000000000261ef2b47de8e1576aecc6e19ececf80ddc1f4e28b2ff27953a65199f65a6211db7326632cfe04d543895c727ef8b600000000000000000000000000000000044fd6b9b4a1bacb8b7d4c53c106b025ae78f17c3baebbccca4e18cfbdbcbf8b3ef88ed5bd9bb36d9aea9e24f4117e760000000000000000000000000000000007721612515fd075811ee804314acec9d389900c7ef883e866f71fba00c49d5c4dcc7a2b8e2366f5a93f4577926ed171fdd97465982b58e69993711a6a64134bc4e76b88ba1948af91ba3339e9b9d3e900000000000000000000000000000000122581659ab1712afc23c23c2986394de8e155bcf722e944ec05e7e42e05acc366d9a7abf2136b5dc68a8dcfd4a640bf000000000000000000000000000000000188842cf4ef54cf77c145acb685d3187cd9c842ba6705bfed846ace83dc4400c45120fc1d6a633ea879840d3d0c902f0000000000000000000000000000000005c8966862ed4458a753155ffe2c64655779860149641ee5511a46ec576798fdb5cd9521528df77bfebcdaae2f94b865000000000000000000000000000000000cc10d888d2b7a97666de99ac14a501b7e2171f074d30d947efd67d85226c312a7977cf923ddbc88c533f08a99f2045f786a2a3974c84752b32f29707805c71992d5d473f4b7bc1f0757d126607a1c07000000000000000000000000000000000e5af1420546c1a5a0e0c2bd9241bb7c7a26dd52f4f358fc868bea457a60bd4f6bc5b60b27069fb4f6760813a91ada740000000000000000000000000000000017426a65d239b1d9505bef2b476799c394fcc7bfdca36a1ee5a600351334dadc238b64cf8a667a25d4880a31b73c53a9000000000000000000000000000000000f151587944aad17429b51b1c16193c1e1c93cb412538d1475473666c997e012ce618eb841c4e9e064a08ab83d7fa60e0000000000000000000000000000000015c2e049c532db585807319c23ec077a51f288fcffb2cb6528d3697221e8542e3fc85d18b079ea1b217fae30858a36f285d33a7fbe6ac6eb42eb932dfbbca2f771ffad5e80fde686e5df9d34e9f83ad6", "Expected": "000000000000000000000000000000000c9be91da9bd8774f18efa3ae9248e4b03d11c49b377c372613b7e745882b2b23c49d518672e58eabd4d9b510a25d8fa0000000000000000000000000000000019687b9eaf5d68b0e795cd57055a74e44efb3e997cb038b7f1cbf08ca70e80a1655cdb04402c542a92ae4e435c22d0b90000000000000000000000000000000010aa1514402ce348d1d61b8d38b53017cd3977a84dc14445db64799cfe822b56a0adbfc5332093ce7ea1f0f438bf15590000000000000000000000000000000019ade30ba0faffcaede95aa272be042aef090f89d9ca25cb825846c4bf9e4c1dc575f8968c88ada51fac71f26fb01517", "Name": "matter_g2_multiexp_33", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a1346771f8ba25fc44323d5290068e46b3f756de6d97aa934d511979a1486bc32173575639a7e54aea8eeb60f32a8c3000000000000000000000000000000001958ae7fce87db47a65a03402313b99f659ae02e8b62db3525d48dc9075aacc5e5abb50156e704701f3ceb18747e0431000000000000000000000000000000000f98778311e28b4081aa76a3f9546b94c29d86fe8e66b905265d74ee21928dc3ac463049f70d355d8caee5b59d65e07300000000000000000000000000000000185cc233ce72770ae26406476c1779858523e7c940d69adf2750695cb12440440686b6b918f4adb3b14aee9aceb6422119582dfd9cb80d44c17c5f62360e62f6736d186194f0f8483e34d8d18d832d37000000000000000000000000000000000ae2f565a44c8e07f2a136368798a44926cffd3c3a6d4c2fbf91763c20d2bd959271343b80eccec4d59a84394c7a3ce70000000000000000000000000000000009481a5fb276c938801133adf10dde3e7da2087d0bcecd3c9435b7de544271eb3b07a69efe7e168869e727868f24b0d90000000000000000000000000000000011774e0197866b1c8b3428d353d2c9f6326a77ab30d5595e2402a0486f03ca6ebb1e8dd335a60a772dfdd9a3dbdd3eeb0000000000000000000000000000000011ed2480d79f73a67a2adaa6da3ae4f1e1c28feaf0e4cb9aafac658901960129e40f6415ec80a31d72004899326f714bac0bd9b8746fd02aa70d8b8a2b5d3be46baecf9449d8cd3d620cf9efb3c615d1000000000000000000000000000000000a73b0d8c31af2deed481faec54095875639233bb09f31b1c7c745cb54778d1c8bd0a230e963ddd2ec8d178d31fc14740000000000000000000000000000000015a889b16be93d0b6dced01f5e2278ffde1cef0576d0b04b49996cc5252854f879e04b1ffeb90e222f4b9d5fa350767c000000000000000000000000000000000b53dc4d72e90330ffad17012bc7dd2e497cf8aa6ec73bf25c10427e23fd28137631249eabe9d0308c956dc7a9e92047000000000000000000000000000000000930cdc5d04ed2d1eb62937d9f72fdd733c07a5a0e392fd5216100216b1a2e3cde7053bf766f046cc470d92bebaf6290069d889881d5bb87dd65a9a02a7fe239bdb55ee54a6310bc987e7c5772404d7d00000000000000000000000000000000131c4e590400b69b3657f7c67272b1e3491983997993ee87c94043001d78e605965abf3c1a8c8c39cc08d5a5ef05520000000000000000000000000000000000124f71c136dbb032504da910958e8a7949f1dc5c061f21d50e439e01e67919891633b3bb84fa8a54c69b632f78560ca70000000000000000000000000000000014a4b1a05f1060853f4294e669a20b91f939793a6eada6dbc84fda8ab11509b256d8b785b252a3795f1d2b99a51df05d000000000000000000000000000000000be2489f1f91d7adff356236859679c46b6bf8c1b375e8bc8bd1e97830b5ac223ffbbda60ecda168bacc2c0b90ed25d3be658348e299bbf2438a0c013f86eeeb69a013b8004a4996189472f3372b326c00000000000000000000000000000000111ebb796e8770d5a69e724a8d3ca62ef1f13778baf4ba12bf462211d35e325ff8e455c85237a73a3046e531f2e2255e0000000000000000000000000000000004308b76b06067e0a07bda143341220809b481b40b78edb2e24e83aa0f003d209198825b5fa9bfd92597e27a4054d3ee000000000000000000000000000000000de74485713f5c95653e98b96aeefb79b59911a610c2a848a807653c19d50394fdb52178947c779134d24b6d396ca36800000000000000000000000000000000069f47a71ad765591f6335b962e7c2d87b556801e1e6c25b449edc83432612fefd405c952397a704e9aa5a924769ad4e9b9d0ec92ae7df3f52a95747659f8fa3ca2cd01e8d7ef6de384111246886bafb000000000000000000000000000000000a3f89408ee43c0ba6a7c9c479327ebab426d430e3ff212c65da6364b16195619d27eee83d701a2ec50bd4b7acfaa06300000000000000000000000000000000092715831af983f740ca2c673e7c9c47727d64165c59fce19dc3fbbdd0b6a7be66288ea1f033ebb5ae2b38b3762edaee00000000000000000000000000000000071ca6fa9e546d4bce965b2bd0f0fb97e6833f05cedcf66d43ec88aba411dc4d6db9f1591de22f493f49a1dab1a2701e0000000000000000000000000000000018f89932ec032fc28775d34d588169a1435bf4ad7e2ee11c9d6934dae31324ddb96b3ef88f95d1bb2e52c3c8d9c01516d2ffdf1237b4e03c219806f2dea745c94bf08924e1b9f11deeedf0db19da6f3f0000000000000000000000000000000011b5cc382164fc21c9a72cd85acf61c2a78d00a16a2dff938f0b36bfb3bb7075845a1616001ab53271a9a257a38312cc00000000000000000000000000000000139ba2f27e545d45027a0b11253532e28fa691170e08608472ce3b3f9a3e9398c5ee76953b1a1d01a5e79f194c32d1f5000000000000000000000000000000000d875f44829555cec695f3f4a28078b0a6f168bb0985793d003443b75a141936f3c7c633518890e0f7238416d46573cf000000000000000000000000000000000675420ed817ecd24bc5172d3e7df60ac4281b24ba91e8b5ca8bd6a8321f5c7312a6ba043fbcdc467c8a5c957590a692cca0751c9534cee7f14d11b7c8ccbb2c537a799df59f850bb125c6362d72e9c400000000000000000000000000000000107bde844286cd3958cc7a1314127322251699b51d8af8e6b57495497f21a84e05612b1569b54fc5639a75e9f9deef750000000000000000000000000000000002355b1a60e24e4879448437d2c1b12e58f02d7eba88583e96e9634f7e2c8c6886132ef0488918f665ae3f7b6977c7c4000000000000000000000000000000000fed531e437b70bc4a19ad63c61ccaab49afc50fad1f156b1c8ecba0e1b703f8aea61882c6327d4d8fdd072df9c4e73500000000000000000000000000000000182177409579ad53786539514753c696c8757b8c4d9b8360392f24b591e43ec20e84c0abe468061a9e5e879c5c81314217f890a1120daca4a1bc1bc0fa7529f0a87b5fd6ec385f12b270bc0f1a5281b40000000000000000000000000000000001fb25395089228772d6000025cb0356eb510c964bf7d0c12d47a6608fc18cc448e44880eb5ba8475cbe6418fc9d8fee000000000000000000000000000000000f3b9de9980e5afaebc59c56e02fd75fdad13013842ac035f8d5569a46cc67f0cee461a939aa5a3d8fec2966294207930000000000000000000000000000000009a223ac0edb164845eb8397e0cae4363fb2c8c996c3c5d722cb50be56cc3789c732763cfd4b61470886dc991be39f57000000000000000000000000000000001909f17b229eb351dfe8317a8273d846edf14ad5ee0ebe8cc2b595ebfed19b73983035e19ebaee3d05b1dea35968586961ca18257d9d989ec13d4f158b18ec17d59344f4558b6dae6c0aa0c2f37affb500000000000000000000000000000000081fa9eb8ca7d9db52380e4c408e6d5d668471bafbafd62ba9023fa08f6d300a45295b583677824c29ddc3254439cadc000000000000000000000000000000000e2e613043b1566674f791dca9d860a49a75dfa24dce3fe18f544a9b24ec5266a64e77386b672c93fc4d079eb8e76a01000000000000000000000000000000000f471b86ac5783d720e7d73e8871474c8665e8a109aba27c1172ca24217eefb0f66c53232df1672dc0af6ddf9640e10d0000000000000000000000000000000010667cb22a6a818fa7c729e40a7e70e1f31b0ecd568b54a4d352d5c9df8cf1072ebf2ef1e612efd96bddcbeedd8566430fc004ed8a135ad97cdd1bc4d0c3ccd15e65031ad7e3cc13ef2c260958bc43be000000000000000000000000000000000a0ed87b01f27f26380c6285e82bf2f12ef3016c7e7f3a13041d465825664573db47be6cf099cea615e21f6a5d759b6a0000000000000000000000000000000007afb2a1bd50fa0fd3174d70f1c8d5c229627a496bc9bb89d4f52d47b1862e14d704dddd80045e58d00336e898a996eb000000000000000000000000000000001698f30f824ee5cb71b3f2451953c371987433d2eda570f2a13262ff9e5e529e316b06ef6aadffc152803b076f22db9f0000000000000000000000000000000009eb1d5f3da7cfe9b40a70e1b3c3dae36436e8d068a79dcaa283905614676645c99a5a165630ad46b70bd6be8b1f21a8d8cfaa1037e2c81c6973b221dc7badf25ebe3fb4b42bbdef1124265df2c7ccc40000000000000000000000000000000005c4390b8f37cc3fb9f248470b505a5d9502d44e4a4459d1f56452cd9aec89d114f1402fa45935930fa00888a4860a9900000000000000000000000000000000163b0ca84b5cca4f124bfb5a13a4a3efa677a84dc89b6a61e69d0aad34fade528614e549a7b2326d1f6016bd0d35465a000000000000000000000000000000000bf450dc8af483a9f993a29cb47d5362c9f5ef38afc2fba8040e14514eb834fec6520a413fce5868aa9a2c7c3ff6617a000000000000000000000000000000001063619f384102949fa1f8353f0aaa5031234d736c54103df6ef6fcd0df02a19c3aef471f0413a1e19febed6395459a0c25ecc5d37659ebb0c9e21ea2f8fddc518e3d8faa99627b21faf105445f69d7d000000000000000000000000000000000e35db3017963d3a9d62b7e7fbfa13ce4f5fb46a90c1285ddc0fa481d9379b95a77e8cdd4aab5c33059bfcdcd82473fb0000000000000000000000000000000004fa27c663c8d21f041d15cb199d31cfcb96a56cd673b730dd111bf03cd954cc33799456674ed4d58e8e0dfa826a6b26000000000000000000000000000000000e0df4e7f943db5b5c27bafc7e1ce099b2caa64642bcd6336ef926352682fbe81a1945b266cba7eab52b16f4aa63eb8500000000000000000000000000000000020167756b8c68f535c4691b1249ca1ccf0a539f7274623ada824d0ba789ef44ebb20ec1ba51d46c0a42da78653d287e26cbb32382902d9b1963779070d749cbc4df1e7605f840819f2c04aaf89c732f00000000000000000000000000000000178037c6b5fd1c6c396d8aaadb712863557feb744d2cb9165ae5c36376d2c066f7b1648e083f81c2c96da6562e0b3c20000000000000000000000000000000000b805b4e1cd5d45d8b6ed9d4f604ac0b40f336b8123f7281df43a6e803f8688bd8087fc4d5fbae695d06efb0fa35e18400000000000000000000000000000000000a947562dde45f613ee1d15614940a2edfc770d733a60374f8e9188675d4cf973a5c1081c11fe5a1d93bbe85e6f47800000000000000000000000000000000059473d80c82c6ca06b4aa71d072f4751b3b053b53ffcfb4a84906ddfc36ec5918668a62f07054af1b241bdd4485edba699aa549077a80ff8732b5fc9df148a90f405bccc14bf7305266836566b7a98b0000000000000000000000000000000008b9d0916a9f5689b8fdac84bec3a49d0224dbadca6329ecc156da633e1332bcc6735ca3ecb228c22032dcb7b2f372d3000000000000000000000000000000000cac0c264add10bdc1217384a7379f65b93cf822418f7e4e2b48eeac45f068a61f805cedfb1665dda06e04cb726d245c000000000000000000000000000000001578e98a40a64da59154b1c3d757d8f1f8cdc500482c7b7d65b9997576f745442fbac654c19331977bd210df440372970000000000000000000000000000000015ef69f82e85c81d28893d94927068f14c6516eb7d09898d5d055cbb7a9b55c6d7f686f067ab164160e6d6a8f91ea19d40e2de1a2901f1380a383a741d79fbb0a041da5d7bfb92edab74cd483edf95230000000000000000000000000000000000a6a27b498285085139b8dd0c37b700997134337e696c84b5e0cf70ea3991cfb40ca3a3098a3b3a2fa31e91aac78eb2000000000000000000000000000000000bbd7ebf4301c5eabd4f448b89f1b227415cede3247a1c8dc56a02247efaa99dc78cf370f644ffc06cd2158fa25197dc0000000000000000000000000000000004535a402540474d53c084d4fb6d9e12dba6716ee13286ed758aedc1ef911b55c572640180a54cbc084ff57ceae8a4b4000000000000000000000000000000000759de2a9e0f3c04b4f629a682dbcadb2140e5b935845cb55bd267e230e08c6e8cc5426057473aa03ea2196203bbf6dc062b323592118868d547e83b731d15ba2c7bdb1ee4fdf73600c2584f1db0b45d", "Expected": "00000000000000000000000000000000134c29cc5c33c10f04b6c09b5db71b10304028d06ad6acd4f4b39b16823288085a84a0380a1549f04b3dc692cb8216d3000000000000000000000000000000000a0a9379d63527ab9b5f9c00be4acd54e5fd683a0a2f37c85ba570171c705eaadfb0f4e4be1a8836c9de86dff46138300000000000000000000000000000000006ce78f135dda5af34a0e069d7ef13fd589cec5a6128512bdae7f45f28b09c6e4b3cf638628c9f4783097cc00082aeea00000000000000000000000000000000141e710ce7a979dd1772150d0cb2d5b269d5cda50d1bf7bd0cd827b24f9cd8c1e2775f495cfec0428519627b7fede464", "Name": "matter_g2_multiexp_34", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018aba8353cc470b287a163fdb9b8b4cc46071543ee8261f928a7b856287946637d9b36b728a54e1df5f185a47f1556060000000000000000000000000000000001129541b2e3b2e1a553995b603dc3eee44a5ea440e687739ee9e1339dd79bd96c67231ac753d483e0ca96b27054997b000000000000000000000000000000000e1cdf3591aadeb56dbd80890ff7d5639a64847cec771a19c769df7da732a6d3179d3a89ce0052bd7c982af0304408120000000000000000000000000000000000f5f5f0ebfd2b632e15381ccbabfa88eb774f2c61801381ca73e6970965ecd54f5f3a9af7c152186af8fb75ffb5bc25764ab6f4c43630d5e79e8c474d76d8973a7b7bd1c7f1a985333cf1a6be5ccff2000000000000000000000000000000000e527e40c311edc5dcdbb4d0b70497eaee14533aa8ec57dc7cbd7d839fe6c6ae62b1fd0be2346a038de687d5cf5394d60000000000000000000000000000000005f9fc63027dbee5e0d55cd6c57daf5df7af0d138393a2dcdc71ef9aeeb204ea347f7d574e71f2ffdd37d8f05dc7979f000000000000000000000000000000000f8788034c9f1c9c2018a52326c046cdba8997199732152963819b663c6e58e9d6a0065289e2e25a97ce5627505900f20000000000000000000000000000000002a747bb3bcccdc6ea0af1bf1d0ce55de3f41b93060361b30c76063346b606322a76ed7eb260219c83aea0806ac7d8583280f1b1e78d2339f64b5b2f2bd77aa24623b79fe2c9debab4212f4ff564983b0000000000000000000000000000000002148c043e065132e978e89f018a5b728d278c95c9cd1a6f276bd13f0cb708422a62fa22f7b377adf33055fcb09a6a8100000000000000000000000000000000024c4c721a0574e53118bdcc3fd41f73176bc8264d2ff39673210525166bb3513016b5c9af67a47a7032b74a62effcef000000000000000000000000000000000797dfa8cad94896916b7d55fbbb3eb0eeb74f70231205388d0dda69dd8abb436c22addd22c1e3689093739af957b65200000000000000000000000000000000010dd2ea2d45528de8bf1b5c5dc3267fe8951e48ff5987e67ec52d58635521cf1905f1688894e3e23a659764880b2301d4d27ff9d03ab9120ac2adfeb36b070015f0e90782255ddc9111704c5fb11177000000000000000000000000000000000eecc0a4edd3cc3f70d3e0e43ba56b04cfb3f1ac23c657048a94318e622217572b0f929c73f545d6f5f5613920c0580200000000000000000000000000000000137a098ea8d3aed32c197a2d244a2e18753045b55cfe16874f79c728c664b7f23b10476f20dfffb2f80417c26dff4f860000000000000000000000000000000004a7789b02d7d95a2ce0c7bac39d5b057509200393450a47fd9d087a353f866921aa11185550537b98f3073650d9a1370000000000000000000000000000000006ed63730bae06403baf705da0e30c6c00739799eea4a312d06b8d7dc35cb43a4f1e941a69e55ddd7ab8ce42d8629fdcc66d5291311c7cdd1f33e5365ec0689608b3569427a8f6a9cd0b94b671472e66000000000000000000000000000000000ee7ddbf43f17f722dae84d34d26add8c1d732918b8c75c6b295f2f584075cea0c655911410b32c06868c1acf36aeaaf0000000000000000000000000000000018775682555d9f5a576cf9462170910bcdd083671ae2e4c8c6fa99a702548f1ce9afe90e681b00d194322b1a2a3be7ef000000000000000000000000000000000f3935bbbf58b91fe8176f3e25ad3fdeffdd6b369ae70b704d4e54d4fe32fe5987e73aa5aa975e958497340274577cf3000000000000000000000000000000000c088bc439d638d86aba6bb1e6e9f7540ac2da3b96080aed455edd1fbabfc141e26f125cc3a9cf72070a24f298dcc3ef4b718a5129659250640e333f4567043ca749063e63d87efd86a9995adfd3b8450000000000000000000000000000000018d8a47d1a13b9b8fb5a1625f9616ba120d5c677bcc996f694b7e15d251fc4bc938b0a7cb5b70f22b8e9f5b416c513210000000000000000000000000000000003d0646458bbee7ccab27f858b8ab0af0cf583da12a40ca5a954d7eaf97c897d379129a63d8131036f29c30c6e644149000000000000000000000000000000000d5466b50975c5a2dad96e4e24339eafc8c85c2497a6f19e12d96603596498654cabea6995a92c91b8319ce06f18d56d00000000000000000000000000000000191a96d62139f8219b9e4369a783400d045d72ab2dd83fd229e08a4ca73de59a11a5add86c739cb3bab4adc5e9f79685708891f45d7bee38fe382820260061e212c6cb9a8572b4d1854f3ab09409b05a00000000000000000000000000000000032eb1f7846b563e98fca0cd44ede4909b6e16a893f5ef01eaccbd7d8aa11710606bbbd0ee6480f7cdbdc9ffe66c3a9c000000000000000000000000000000000c31bb6fb537cfcbffe815d86ebfae1f5053ceb756818ede8a58cd84cb34d0eacc70ab9095f9db1691e4fb4bb816d570000000000000000000000000000000000a8fa1dc2f28277a4bf8fd9665d4b5c3baf1352d89890d4af94a3657cdac7fd72558da1e65cbc5bfac142f0e817be74f0000000000000000000000000000000005ff65c22ff0abfb33518791823c5f2202ea5f7258c0a507ab84460335ffc2cc8d7c7f670752a7647d6a6487ca0c9adb85ac0f94f300b004c7f20aafcfd9129d6c2590749504a3f08c4cc708fa30100300000000000000000000000000000000190379b7629f74bfb88096dc9ffcdecebae0d653410f032a35a811a09022679c9be19f3790af95c3205a396819e068e1000000000000000000000000000000000b6f114fc277ae8f0b5374dd349985bf955dff7fcb0095e0e1e137fb539814be78c924074bbab54f29dfb42f3e7df24a0000000000000000000000000000000002d86b0507c147142d03d3461bfea4c3af7e57a6edbb372387de24a27cfe27c44ee4b9571325a1b3f5e83eef450f2fc6000000000000000000000000000000000ac3b226d5e13c36c3a8ef0c8896d9af55bcc0cb67ac1cee57a5c6519617ec77af9af60ed44e0a8284a2d59816ebf848fdbb634bc0f99c5795f3c4d6a0efcda7f71427f1eaa1c5411caa6cb05ee3147800000000000000000000000000000000079cd4511e953e4d1b3f4f3bbbc66a62772018e809779fa39aaeeffac737cda9a6116293848f967577f03017f33231d2000000000000000000000000000000000ce3cf48be423a2fc0188b94f2a22579872e9ba140798e560ad107f63ab2b8c601831f89d06a4bb8e7a758cf836ddfb3000000000000000000000000000000000a6a90f735f215a79216fc4e7daffbf74775f38824952af72ac38c38a77a277483e34bc95031679494d76f109c0aecc4000000000000000000000000000000000d55fbce780d885cf817cd2126e7acf115ae9c72843af23c376f3a5d4307d1eefaa0f4691e7c09b5da1707aeaa5b675af5e4695c01849259fb969183de385ef30c2403e081067c2d9b6b5522c73fcf200000000000000000000000000000000008924efbdb46b9324bfb79b922ba8b7d83f5e5e4b3b736105e5339805838171801bcf17208f3dfe5c7475d4e45b6ad970000000000000000000000000000000007bc0096fd23f0c93f0dde8a3974ea3105574e031202f6316d5940c85164c6d6bb5b86078a0c68dc822c0fd1b3dc8cc10000000000000000000000000000000017276b3208b347388a5657b10e3c8e4a187b376e42352f76ee3ee88873217b6b8185022c93097cc116abdecf3cc64467000000000000000000000000000000001915ff932acbdeb52f07b664bcc47c3a5b096c6cec32da4d7044326dfe84358e49539fe50782538a901b99428446b0f50ea6fd588db5efc5fb2248634cca683d39d610886b59eb3077fa9612c368d7690000000000000000000000000000000009e295d229b543a17db1cc85c846111b7097bd169d19b410de78f8da9684e664922eae77c64b0db430aeb422016cfe7d000000000000000000000000000000000e29aab30a1da56b8590e9df67171cc1b9c847696b51147cc57ed6c3b55819cfa0992c67e15e4ca6de2573c9e16231c10000000000000000000000000000000007cc9990c6722645e320dd16a4be8adaab41f958f769ba0d22e235549a7457778cb9b14aa6ea5caa9e0bd43f8d04cacc000000000000000000000000000000000b2dab5cf37ae8e76b71dd8748c86e8823142792445fa0b140de31957d35bb7267e3d94e0dc92f4342d9f8560c5d9d86dc2060a3421c5a8336c80983c9a160345901a496c3a74fc5248fca081d09953900000000000000000000000000000000128e2aa795f8479da3ea2a4efd12aa90a6fb019d4da89fd372e6848ff7ee17da689d766c9e49c88c962eb4f682c56fff0000000000000000000000000000000000fd68bb80d6b2200297aacae1174275f864669e962d85c9105032d7a352fea548e9fa0629a6749c789fa0827a40190700000000000000000000000000000000175bc3918dcc972fb728f1d8cc30ce9887efc6e0b254d8d22af87f95cd4182129d494c43d11b028c4b9849f5520a4fc00000000000000000000000000000000007c5363f507a01c0b6935fee0413345bceaf1336cdd20f69060bdba2e411521a61a549e6159b2e006ffa16e3bd77e998e27e4afc3e6d59d0f5871b35eb83b46cf15da6c326e88dd8edf84031f58e23f90000000000000000000000000000000000efcd782b89fee74ebc037160c6653ccc104260b5f8989545b40d51ead6ad6ce6252e1232281c813e3c883af86e68ca000000000000000000000000000000000b68ed21f76ce131c089dc454dc48ef948cc7c6d5fd87d647db954c9eeab2f7f76ccc51a1cff8612e89bceed16ca03ba000000000000000000000000000000000cd776670d5171610046fa294fecefb42f9bb4d71baed4af65a09018b09ad9341789abc23c9feb85adf96b4203b0c0a0000000000000000000000000000000000ec4ca0091a28b73c9adbe7120f2bf1a84a62ebba1e86b1948389b1a1966c1de4c632a5e245ba634b53cb932f5847f6ecc7efff04f143e2d038de153861da5e04016a7eb17fbe6365de13069d088b1a100000000000000000000000000000000022f319bb5167c2b945a69a438f712df8975a0e262438ea687e2b0d824e2d1d14bff1065f50fd6ae92494f6f3aa9472b00000000000000000000000000000000198ce9e4ddb6b423788dbea82d75513f43cb43ecf1b27c8788f041248f01808644f60fd823e5862cd7afb4f7e8b6b6a100000000000000000000000000000000119dc1be1bbb7e678319db73055ccb88ef7efcf6119f8a9c43c69247ff264879a627f653a10a950e0dbe69155ebca4f1000000000000000000000000000000000692a0ef5a75d42524e3fd52ae073b0f2ddf6378f18a5dcef05af4868a899b93c7f1d2691883e5c85f97052ef1f4177d09a2c3dbb4ee4f485dc60dfbd94a358a7c62204c021f2d7b140187ee9ffdc4ce00000000000000000000000000000000102c92272571b73a7df754728d7293fd8050d9dd2b8605c3f7722e6de541b7fc6a81b01c1cf15e5241ee4ee1f81ab39d000000000000000000000000000000000af1cd6f23bbd3e9ef75eed6d6d99a7cdd24574881b3609e45c4adbf82e08259d14701fcc5b6338ecf52166aecca003700000000000000000000000000000000026a1a4c3eb54de2ba4509dc806db9efc7e26247d501cb59c525b8dd15d03b91abafa9ba5816c22e1f8ca159cda34bd500000000000000000000000000000000170b510ec227fe8534a2cbb0f405756491c4f6832df552bd23980ab0946725371b3c24fa8b93a38bdcd47e1026e1d2a0d9b15c065497392e4b477a556ad620d44e671137cfd570d53590b7528f8ff680000000000000000000000000000000001423d1707e49d2215f639df75ee0e13bc724efc7d099259179260ba0f17157c4efc4276844bfdc46c61ac2185f64beca0000000000000000000000000000000019ad06d215d3c819311938f89609ea7cc63fadaa11bcc86cf5f26370a966eaed1aca312c18176674b5aaca3ed8ca876e0000000000000000000000000000000013bf3f13e87f3ce29f0524094e2ab8e39679566add32e779256006dc92ce09f60d5bb9cf0452b90ece71a5f6981d77f300000000000000000000000000000000112e4901efca14686c30a883ecdafdc389303f4cf46345e229885c76d900b0aa084a957076009ce22ee36d4e285d410c9e2a72eff2ec29a65b417767e7090b73c2fb530de6c8f4e4ba30543946423b12", "Expected": "0000000000000000000000000000000016d1fce53fc4cf40acb0347c0983dda46383e4828c16985459ac89a2ce8d3c2a26cd9acfaa2ec899cc63b4c6bc351f560000000000000000000000000000000019c9626363b511a79f297dc79c5a3b7a2e5127fe49a2fac5bc43a4376f170404f044f9f84b82cd09a306012fc81e3bdb00000000000000000000000000000000062e324f3d7c5bd39808b762a5b009cb30bec14a9591477959339bf2de9ef27eb42a0eddb95aa5fdca9bb9d89b278cc20000000000000000000000000000000000f05225a4d3bf910b0ac0103594a90684ffc0c09e2c21744032e30470d5727be3c27621dc2377e9845ad78be67b856a", "Name": "matter_g2_multiexp_35", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c64577b78ff306186dc44131cf8bd946a68e65502c4af9613154a7e3ffea4fe4e59cac4a500894b470a74e66db1834e000000000000000000000000000000000b4311c295bd30174f17b9ab3544f1496b9655302a4b6026a113b1aca31b555ce7b2d812bf8fafb6b075f67cdc59b77f0000000000000000000000000000000012d7dc3db10ae6b4e3e99c655aadb71124a0bdcfa6e30ec13c7c977d39f83aba4979a1f45881813a3a68e149a40120a90000000000000000000000000000000001b958c47cfecd619c05a2c54315585d15fe377beff889602ecba6ea3b29d51f6480f09a0a8490e4c754045f0bfdc3eb7b9aa7e0bfaf135ff24720773ccd1e0a46fab6d678d91a14de137061e145fb9d00000000000000000000000000000000010db66653f2ca73e55d85254f62e8b558584d546913e4b8f530968088d90cd5c4bc164fdb77325fe0bb2fb1a5683896000000000000000000000000000000000a1af9bf84f0b351c8e8c082a79c7ccae768bd2ed40eede38666aab1901a6eab0cff258f440c8c8eb4854a824b9aab4b000000000000000000000000000000000444fa654afb57f1b01d10be08a330f23667af58e3a40c630a2e01c1809125b3ff8f76e8a39418688a023293ff1a45e90000000000000000000000000000000002ebb117ea107a3598b888dcbd5918dd0ca307b21d65843c6c28b3efab89d0e276e5d92283bbb345b674d4a300595425c6733c9bb7bd195622b96c4181e8c8837d1912fbadf77d6029f7fc44d793b48000000000000000000000000000000000105818a11efaeab4801d4fa7558b09bd56294be7f58e3e54fab1f4f7c243ceaf08c99a14c3128ccfd866b6f93caf989800000000000000000000000000000000091ca092e5f83a04e872e621e71d54dd6886d088718f60ed5b62d3e4c165d3ff2cea1e50fcb94fff251df0f5ee453cfc000000000000000000000000000000000b42051a1ef52f87536b9bca459fa7070ca17bf825950b13b3bbe9db183ef722f62af6c05c174c65d59b722e1d2f5b0e0000000000000000000000000000000002fdb4a5480418e43aea28e5041af6ad55a6c226e1eea1a0449a99b5a937375285feecabea95c2652da5113dc17d8ef4410bb66334c677397d04f59eade9630463065cd7da3c9d50580c7d66bbaf487d000000000000000000000000000000000d8f93b589678d4e93bdf8da7834bc8edab648ead731b7f5f0cc299488f07262877ee9bb1174ccc106204dcd3f1f416800000000000000000000000000000000160f740ffca48d3a10c43e591cf46c129507f10e65d76a031fded2930d6c2dca4c79d7813f63e4ff71aee09d672173680000000000000000000000000000000013c768a4889315faa3976c8e43b4d466ea594bd94773f270a198f2571ba9662d10435d1e541a492055c333eece9bb29a0000000000000000000000000000000003dcbcc9e6a0cd5741d77da88fbbc269202e8f944a5df5dc4f9145758654934d5e1eedd596325080382458961ed3d21ed97a16fc5b2c70829b15f73615286eba334de1f520b5f0f6a83d2578399cc0b3000000000000000000000000000000001344fb37c1d7dcab01a4bf6fa50c6bb7606f7db22b85a3888ffcc2e9f229f196881cd7c82160730727e49b9e6fea04320000000000000000000000000000000010c7b15a6355d3152eaada7a606031f28809f278a1d0e04d264b563185ac7d9e351295191a6a90ffc9c6dd33995265db0000000000000000000000000000000014438086226a061a1bd557dac24d9333e14cdfa3a7bb00ded4a450e8889a3028b174bf38ae1347e6aad19ebc1cf5ff7800000000000000000000000000000000105165703c4592cc4f1f489d78426a56434dc77327c13221b582dc25306f4c5bfe596f3e47abcb741ab553fa14cad374bdbac08202bbe5df1229e99c76c1727f7789e0f8c2002f0a2c195bdfc00acb36000000000000000000000000000000000ad8b55a198a5e788bb54c32112761ccba9863cba16d95ec9e30181376e7eccaa2741660f2c5f708300be058e566ae27000000000000000000000000000000000b9bbca7db413964d2ec113cdee2d7a7bcdb712d285655f6b2897dcac61456ba4d08e25e8c28627231824829bd7d13800000000000000000000000000000000001ae49c10675256651e3e038a2150d85993fa6f2a97b9bc02c693ed97ad52af34015176258b3b2546b81010a4381d85c000000000000000000000000000000000c8f9668a0a497420acff5207a07cf780e0b2ba78083eb0ed8eef76beea996210541bae2e64d825000f307d54cbe3b2b43da827b812ec6ac23b00208cbad0f2e8b3a32434aa61dde029683c34c1ab1900000000000000000000000000000000012990a66c132a31d60d182f729b52d9b57d9d1eb1988b6f0b4d9fa2847f26983078ef9bbfd0e888e14bf7d1f92d09e54000000000000000000000000000000000585215ffc2673a197bf9cc6c6424547886abc6ef5c6edfeab2ef0c42034a4a458fc7155c35c84a8e9e9d89fbd4aa25c00000000000000000000000000000000118fb4fe0d3498dd2b55e62272e95a1203f9fd22314921d3e044f1b162376aaa7e8154a4e2184b66451aba98729330c0000000000000000000000000000000000364b9032ab9cd9f599979c8a93acbdb831707f1f84fdc92844b58bc7e4d72472ca5b09c51b1b04271ed9f0e391552463c7a8f7bf434ce5e63ac9365448da8663745f66689b4b04968f9b8b1b6805893000000000000000000000000000000000ddf9e4e302169e195f4f88fed06e0c93fd1b542abbfeea5da5d47c662ad9a16b8f4aed7874354fb9008d073920e1e7e000000000000000000000000000000000043fd1a4b781f25e8747ecb3eec45ce90760e0d5dd701e8193a7e726684ccb8ff21f0219ba15e9e777d339a3d87a1ee000000000000000000000000000000001117d2ca429048056084e4847c7169b4c8ddaefe1d48079949f9f14e4d74f0e0b38a95d0f17389f61da7b2a6d8cabd1c0000000000000000000000000000000007adfc7d87b1c533b4439f6b30d38c694b65b3b321f3eec13cd7d923f1d5f117005be6c3ea901a9479d79fc553e34e6c51f2e2bcfa6ebf84d3ad83c57257b9032e5d62a8663ed5d77afce00f33382bc600000000000000000000000000000000115a81aebee0329b174c01458f8714b13ea3fb2dbfb051b27b29b940652f27e01a84e522626d12be80da7e1039e2baf6000000000000000000000000000000000d9e37d2e5e7160db30acf5593d1c282541a0d4ac0482f0759fef8704b9ec3ab1e3ed248e37c6be285e890ef1a520d0b000000000000000000000000000000000c198a22c2f590df2902c8dc2bb1ee427b33e9687767666140f9d3b51d73fef18a259d43d86fb3559b1ab0abacf547a70000000000000000000000000000000017e705af54ab76145a79e747167a4fec6ec3a16f3ceef86b1ddd1be144e616ea7d686bbccbd1c5c258e4546405be023d6d8b15ec8908bfe008414757c0c7f79b3079f9db86d91ac3ec8f38ae2c94d48b0000000000000000000000000000000007c4c31287ae0b3bb90475f84abdda36610f887aae311d8e97bf97bbdbdfb11d38c7de331cc9dd022926678e5180c0770000000000000000000000000000000017f4afe28adc4b24d16b9cd97aacd171c2104b13b079c643d664a7c924151a401c352832c4967c0e5cecec5f1d1dae290000000000000000000000000000000005a8aa8a3a91461e0ba256e44af56875f8d07e24628e738ffc057249d8380417884f40c84e76dc6ce5816ffc05c0d686000000000000000000000000000000000f84bb7385a6936b519e881a708541570a31a9d7897ab8b348a350adb0d30522567fb917c9b6db661b6f53f98b5e68aaf4723e85076d48389c3fb5a5df16b6bc6f7a69ca701632b1159677bd8a6f7bb1000000000000000000000000000000000a8726ea352582ed52ab4e440102963891f059cf5a3f4901615733ad560a99930efd8692f3c30256d58e5cfc4f0803bf0000000000000000000000000000000016a623dfeae872639d99e3b8209748642f20af796325630596b6ab6146783bd4f2247c7ae38d53ba9a3fc0cdd6f29087000000000000000000000000000000000e40709656e569e4fe90eb85d8761c6ce44a4272793ccb7635ce75d67d97464e8dcd8c32bd4ac9a36fcce706006915b20000000000000000000000000000000019e64802756896206a9600f2d888f3d307ebf958492b1b5153c06a11231e2d7d2f1786368447f380093a29117cc25da9a632938a6df169fb64daa55d2f874ef7629d5be41dfa0d50827c082333f0fca00000000000000000000000000000000019c7409cda6084edc6e559da9b361c96cf207f1e2cd63cabc9b86c5bcb07a59b43e9c6ae3e90a61c872f168ab89cb2c9000000000000000000000000000000001101bb63a452b766a085fb788937f6b751417dd8d905ee50ab5bf96cdbb9d7b68c1735460a71eaf9e9bf662734f495c20000000000000000000000000000000014a103871fe523cd01053a992eb9884ce83c6023bd6a8c2cd9ca60b8780118c88502c6980904f2d2bf9ccc9fb597d535000000000000000000000000000000001929f25d52ee6b9a44333237c732a63ce2abc80c5510bd67faad1d7adac96eac5449823f3a52ed18bb90b93d9640d0d1283a4da7f71bde54d4b7e28b2b23e2eb05d8b025e77e15810625d71faca6d6e50000000000000000000000000000000015b0a46692f57ccd2b7f53040dd75f30af0196aa3c5499049eb172b4d927f96a59c42a129117d6162a1bb31d2e8734a4000000000000000000000000000000001366dde2d9070a2c057744fffe78effdc328b122e356a6aadb10c3fd2e8badc0ff70bc6d18293b3c52428e2ba78766600000000000000000000000000000000016fd48b067b949ed75bae3e4db29b5785bf672bd01032a925d653f8a605998e1eff6c77ec39dcfccd417f1e0a9defa820000000000000000000000000000000004cf22bd706dbb1cf8b97187ed97636380871402b3ba9de58f174bf50a7a0b528749762c3f55f5f835a276e43b46e669d402b71c1fc5c3f3a4ed9edc73457a27ea427f83a784796e01b7a1451b3305b0000000000000000000000000000000000ff424ae9372af46de34210bb0bd670eb173bd49076df5caca4bc4293e742121267a20506f931a4ae77cc36fcbc8df4d0000000000000000000000000000000015a6815b47966fb84aad5de62e6d4280f9135e129f33fd01e667f4d6e1bf7204317fa7741f3cff3682e251437927131c000000000000000000000000000000000639dca43483b79ba8043130e508e91fe3f43bc362fd1dbb135a2eb8f3b94d5cc4af70f1101c790545a0eaf2408706e1000000000000000000000000000000000045f0a04a642bb6e4db34fbffc8adb19a24648554f36ca371fb1a851384a4516a57f1850f7d6be59ff67029ec4002de310bc47acb3aba7eaa490ec104ed9b2985f65c7347f69fdc67b76f6f43846a99000000000000000000000000000000000e796fd500cb1a25b834baf7335641f34ccf04ccf60f82367f0e5c8c7fce8e3030e7b916752bac8e3adc01cbf4b319ac00000000000000000000000000000000142e8bbac9cae69ba3dca48aec045e0c4d7028f73c254433f921b7240761c661cf8e774a21da249f7758234cf7607fbe00000000000000000000000000000000045a3d80767d116e89bab0e9de812ffe7ffdbc41b61f5f17ad16be5bdc9968e34f46b937c5f94f8197e21b358f44b5240000000000000000000000000000000006978b93018bfdbaef0d40f1278e831a1fc50b44fff39b7c93820a284d90b699981b1f422f751a33094ae7b5cedbbb2691b88ce9888e5dcfef70d6f960a456dbabc792571f2a98746b7d833e7fab98500000000000000000000000000000000003c3561f5d255cf1f83cb5f4df8e3b8d5655d965826d56867ae66da631f8e7d489f733f5824c36652ab00586d9c593be0000000000000000000000000000000010b3adb0017e2cea1b71680ca33aee368429880759660dce2d3cdf57b6cd7339bd8853e5efafb9a5aec3f7e22da676c2000000000000000000000000000000000cdf976e4c65edb79ff15178f6ec5bf0a77a30d97b799e433f216a2fe3eedb10bc6ecbee2974167128773cff43f1922c000000000000000000000000000000001599b60ee70d927849764880830b2e7355daf95eefef39ef61569a2b83b2bcced4dfb28047a1e5350cc87ef3cd5cf1d93e82cc1261ac3864266379b4d518e25c05bc492a8946b38b8a64acf47aeec4b8", "Expected": "00000000000000000000000000000000123af49ac2981e14a490a4a6792f21343497b562266a47487cf6c650769c810852e357445bc68f3460e7822e8cd1e3f000000000000000000000000000000000143e79853e4bf6d031e1116dac2c6eca4991b8a1f822fac1d352d2cf1b88df239d82df886f0b24b3e7f305286cc1257e000000000000000000000000000000000b621056a9de2d83c946b1e2c7a07f9beb8e053202407323e412c0d8f60123cfd5818067f57034fe1b1b5a3d1bb285a50000000000000000000000000000000001642fdff2c52d58d38201cf44c31e00df47ea1439e9896b5ac5e9372482f4ffcc698be46c2d375d57a72fc677a9fc8f", "Name": "matter_g2_multiexp_36", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011f78204afa05c3717d3908dc7e4356ef96c426ef380b6abba3a5616d9ee01addeec3369967ed42e030c4b8ff9939c4e00000000000000000000000000000000175a19c86e7eff0f4e809a5105503ed223fe327ee4617f7f51257426fe408373899f39014821292a75e4cc4eb9f7f31e00000000000000000000000000000000052130dd3cd17840385db424802d869d7eac781365be25ba401b7b0e4025353c8dbf59e5997b5aac74c252192061299d000000000000000000000000000000000457f4fc7ac5d7d4fa07e8ed125df4c4e950e6ea926be9c04b6df3c3699a10e99af7ea8546b8ac70c3003468a75c821ca2a1148f1ba719b2da92c418fd137efe21a44dd4cce013ab36e57d97dfed92990000000000000000000000000000000005182a3af2b52102e09214d048a1a29d1e10b7ace6afbc4e6b1ebf16790be372dfb6d65cb8fe08c3dbbed8c5435a59a3000000000000000000000000000000000f2a1261463c09a88edac443ec3cea8aaa19659e8b7ec2e8a403dcffb1e50ebb3d07217a9ab057d8d097c075609c13900000000000000000000000000000000007d6525fea8fbb685fcf89bd772d48c406aff7377429fb199f27c3c3337f11f8e24c4d81c9026b469600d11e8cce51be0000000000000000000000000000000004b6d6102debaec16c34fecfeb444e7ba573b13b83ec375f14d2c541a0d1fa528ed6599a0eff4f8ca527c5baa579f762fec5d6167d7777169348cf81ad3eab5153f8f2f18fb5935c5ee5e3a759f9b5af000000000000000000000000000000000ba1f2b2c3f1c57afa0ab647d32af5d036ef18069a4abc9795dd9927ea274a718b67373230e337cb9374ef73b5e2303900000000000000000000000000000000016458ff2f5d600af9d2983f535c965a2a8aee48c0d95095bee642bb7bbab8bc87e3e7c3b52a787c53f0d1e00cb4ff32000000000000000000000000000000000d11324e812cd4fa65d20cf58f88a9bc9407657834d7a92f80bfd32c7085ffa2f9f78d7e18c1405a03de939bd0dbb06b00000000000000000000000000000000144a0f4d50bcb16942d22a12d28bf34d2b4c51512a3f11c130f1566aacbdb63ec3984df5569f41ef621f50d138883d0dda609e1c8fa42a993ff355a70d44dfeebc71a801daa36acd437daec5d7b645d10000000000000000000000000000000000d7b138fe445d7b7e130134db653022ebb389075ffb62ff9faa544cd0fdb9e78e313d0b1cb19bd812421d38d1e9996d00000000000000000000000000000000084411aa2719b729a1e299fe8a710f767009060f1b2becf2aaa92efdeea8c91239aa5d2504c6e7ad2e3f39d89ef00c1e00000000000000000000000000000000017e86dc0146c9bbfa5ea1e48f49918167dda13b31ba73311fd5cfdc12845b95b9e90972a9a4d36203be8c5920f8de5600000000000000000000000000000000150e4b6fa9cd9a609241d1de8a637c6ab25207bccf8e5eff4a97ed633b67826135172880b118037649407a3e1b1a0661bc5f7f5d096247ababa51852724ce9ddcc6acc7ab6180beaa1cda97dba94b4ea000000000000000000000000000000000ad7430b7778248d63a06e26119e5600ae97071fe8827b24440587e8bf6887b646f342741af69d20e243c9b45d7dcf24000000000000000000000000000000001230cba1a5a66197875240fe00c59b796ba1db5ea5653cc76bf43d6adce0db3a109168593beb39bb45688c1d124b9eb300000000000000000000000000000000144652474c58413cadf9b31715152052b7618e7093e931367a7ed0340e66d84c0471b6ec178e1730cf10e749e01815780000000000000000000000000000000009abdd0210f25d12146f2911a60035867f59cc341b35c73bbdf8f7a5a90d0bb6566c6ba0e868a3d62d3557436190f3f63222b41a59f9551e91572ae00582e1e41989ff5f8e2cd1ee1a78f55c2b28ecb40000000000000000000000000000000018ced3cd0c169693368fcf9c3dfc49fe248f0b9b5511e9407b8634d8ed7b54ae2dc4ac6ffde8b3dea70ca86ddc89449c0000000000000000000000000000000002f6b227e699dccf7ab1e0b1cba4cf9f05c4dcaf9fee6cd94bbb79f42bc9598fa23eb2c653a7654db73feb511b24829f0000000000000000000000000000000019785959766eb8b00ac2600d87240f2876e049725680f4504f59db6642ff8f82d4e1b856929643906c3be7807a2443180000000000000000000000000000000018285acdf25a475b37ee4da872debba4297fc8731eede6b22be3b0dff12117634de44b84a18042852ef419c3ae18a46b7431e5c1fe5f8d38c759bc48e8207695a3cdf07d4c1fd02f1009088539085da10000000000000000000000000000000019c7950b01e15669cc1f96fd94957535f32132ff6a5ae788f6f660024c332593942bd3e9603f862756edd4f3ab17b20b000000000000000000000000000000000bf3a6bbe10ad91d687a135f4863ba0332e9b04271d437a6a4770056e6b1ca34319dc895f9186482bbbc815aead03392000000000000000000000000000000000a3ef4d4f7a15da04a91ff079cc40040993a90e9ea21f53e31f7dede52dd513a97ece780374c5f3aa8c8b2e525ee31d10000000000000000000000000000000017749fc7761b06432632ac686d93484f08407504e58b04b3890cc2101f15d21f46ec0dc1e9028c8ef8df10f9ae929887d474e755f6ce9045baaed65c80f5a686547089e8cdf4ad2b7c2ce7c255cb5c730000000000000000000000000000000005a36af876edfdf26175c185c3ef005530e02474232ea659f5cf251c5de5721f1b44a25714967d283525632789331d2900000000000000000000000000000000130a6f5edf94736477143b1efc316f131b36d9658c484821be08e7f5b9c93f60cf34042858664db0ff0240addad8782f0000000000000000000000000000000004fedf49e6d49c074dcca96c01607da2105d8053861b4c677a69cff0f82e66a2a63f32f3d9fac8e6c844a1f77055bf31000000000000000000000000000000001528541de3a9d4a216c0e60c31d2b7c7cb91b839fc31307cc70f18e9b87b92bf5b9a9dc4eaacdec6e6bf7791e547d8a2976c8775b0eaa1e4aa384d222efc476305c7ea2d625cf5c67ea4368d7a9fccd10000000000000000000000000000000013faf7b2b8514f77021d8927a3b63bb7c57785e581f40ca82882341c13a9daf062a26b668844e58291366ea6ae2f179f0000000000000000000000000000000009060f9e1047f15f175fe95cb0914f4941bcaf071f24e856eae6f36263c812689a9217da277613c10c8e254a0933c80800000000000000000000000000000000154619e4ae3901789ed3ecdfc76069d8026a3e2cf142a144e8b58482233380690e378de6b81af0ed9b6536da1cc2a30b00000000000000000000000000000000040c1bce922503699e1fd5ac67725f11d7f9bb6903ff9204412f65355be69d73cd7330a3f7bfcacaa9b078ba6b9a9f839db274233c46caaa9c99690fd00fcbfa4eaaad7c41f8ae84313448c787165f6500000000000000000000000000000000103d91916d537379d6d8717b17ac5b7e9fedd98c24890b51c027cc086458259767d989b3ff9d6adad72bf977e4d378f400000000000000000000000000000000159c01ee371622378339518217dfc0570178aecc938b4a008dee1a6661ffa605c0f1472c107558ea791e0959d7dc1c70000000000000000000000000000000000ea3e10cbc3a55ef2dc7bde7a2e80666557e9e8fd9ce77e2e92c2c70777afe43c23072e263e1def56cae4b6d3772db96000000000000000000000000000000000cf1db638331c47f9080c04117ddab4ba79950563810d50e04af819f14ae0981f6e1e94a635fc90226c8d7beef0844354ac9f9ed46ae5aca33af9ba1c0fa5a2138d4ca02b962fd1d02b4636114ce19970000000000000000000000000000000000095c82c58182ae9a1ba14421c2966d687f7225ccd192b24097f997b471d13b46a048202712cb2d8b1be0ff40755dcc0000000000000000000000000000000017410aca05935a06942f673d1937a593423cbbd226f6707c5922306d28a60396baa08a941122dd4c583331c9481a734f0000000000000000000000000000000002c1d3a1262ce8aae42a6ed10d8020c31a468127e1a59d57d2d409ca9d14143d9fd21353b260edd8b387840580698846000000000000000000000000000000001512e29256b6b9f5a7ba4f79dde2c915b162e4881856258ac2050f02868842381518da4ed824243692b131710d7201f8ab300ee55e90ac046dbd772da788dacddf72c559d9378b39507987a9774301b0000000000000000000000000000000000ff83bf1d50fe35bb3d1bcb07b02d78a1b44d2e0c6bf82c600feec3897fae8b93c0ef05006c1322af0a732392dad86e8000000000000000000000000000000000d70c4957cb3615027cb950e4224d41849b9ff1b435ce936384fe17c4d7bc2883fdbba5123ca0c0c010651500557e1be0000000000000000000000000000000008b16fe9af45fa913aa7e5d01b5b58f946004eaaeeeb493759a5bc2b192d2dd71af24ecc5c6838b5e267ec2dfcf5c17d00000000000000000000000000000000038ca027c985af3cf60cda13e770fbe4919d3a5b413763c8ad155cb4903312822366eb986f2ec9e0804594ad4894e468275b22db781d5e8fd07f36788bc1219c4b4a13554c28d92a381adae111b265730000000000000000000000000000000003a313d6d41f1ebd6b98b2061a2d85943e52d89e4b8680611d41ea182385e154da24248faa1563e6ad79172f91a8763f00000000000000000000000000000000038d9388fe9169710e1a205ecfd03f674b47ba2275794469dbd5f193a55e00765c8eed026363b41afda417bdd8910ea60000000000000000000000000000000007a75f53d9b8e5eef19ef6f5fe8ce5d5308a1a7d02e0bf46f91a1e0cb22555752d82d8471c123269050fd8f35a272f600000000000000000000000000000000011f313127a036403652fb2f83c5122fd12c362ecba2251bd6c357a964dd758eb2a2c3053dc668b9a4bc071898d45cd46ec69b95dccdbf193d9ee4c51615c0b7be5ac6bed3f2559f0cb2755c634839ce7000000000000000000000000000000000a43335eb6ff3bf2daeeb1eaf44c2782eeb517e82e55203a247b7a396e26fdf85f93695753c52c68819b58c95f361820000000000000000000000000000000000c240b7896b3dd0c318dc9ffcaa001d20bff288def3ce42752d660fd705e1544e292a5a0aa3a9a80ae91cb47cb938989000000000000000000000000000000000e5195bcc4ee8b149a769322165b6a3157ee7d04546643390adc812b6296675dbd31168b268df869a6722a7c8f51c79d00000000000000000000000000000000004af7dc8a5c552f00d55b996d193a9571173ea829eba8fadfa7becc2f4149ee7c6c4d2c8c7b1970df33cc56e450657331e2bf1816a84c190eaa850ecfe1a9376123e0d0732d90ac3537668f8f18b9f70000000000000000000000000000000007860c3403607d4e13f738357e18bbcc4df10fad4aa25776f84d3c2758624a83aee0996146ba17a812384e1d67a7c54f0000000000000000000000000000000002169148d86b1f7a0ef75d9bd19b6d7cd66da4293fcf33fed9241544dc2564d980161a6bd959f3b43569312bff7a23cb0000000000000000000000000000000001897c121cbf5e82424cc50078ca7143a0c670f1217a9180cd2a4700e06aa895cf84c0af94b7c04bfce047a7d1f8443100000000000000000000000000000000040c1a0c4257f90bd83fece3c9372842a148132d2dffa956729e741ce996d229aacb04387d51a72630329230020b2235f4087feda4bd8205d96cd0bf6eee44c27a6669d7ae8e16c731849cfbb2324e1e00000000000000000000000000000000058c001ee1343c6cde55bbdc4c538f5d14b0e8c199fb822f080ad96ee764bd1908f92260ce60cd521919f223301ba1220000000000000000000000000000000000f8943c35e7fb8b58963719f1b9820153e0831cf81dd208176af7527781ceabcf6ed2e2276cbf374e0525952bace0c80000000000000000000000000000000003b43ea8c32a13c014b05326f7b4ad5b5fc1bb2367866a69373ba91402f4b45409c6d034898e8b0ec3b93c2878d59b72000000000000000000000000000000000101c371ab4d57ed2cf17dcb731117b1986bffc586529fc1edc630de1c6f4fdff1e10b0895907bb81d2ccd3eaa96c04a67b81583fcdc9afe5f35974dc9b6310ee8e1c92031a49c08b05555fc0d33517f", "Expected": "0000000000000000000000000000000007152d538d0f750901466c1ea34a16e7b0e1296a2a3740568812587affa5c0c76ca2055804e24f3415a403f06a717c0e00000000000000000000000000000000119c0c282d22a01524d87eb850789c4816e7dafdb2782b57c32409b1016615beeee2067443835466283543773cc8b427000000000000000000000000000000000d68137c3df081a519747c044950c3231ef82295eea5b7040843668195d4549c8ece4a91447e0ec89530bc51277535fb0000000000000000000000000000000000d81a4fa2d32ada3e08a7bd4471d45a6afd2cfad5bbfa3d378b1df2e0749f9b05b465be61cc9d1a0f4abd56dce03dbc", "Name": "matter_g2_multiexp_37", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004b153d6554c9879359052717457179d8318f8127eb73edc1d6ac2efb1ea9643c4357cc813d1df49730b77f995d6d449000000000000000000000000000000001533a450737b4bf8edada15446cf21ebf82aa7bec7943025dccc4784e1070fbce430699cf3a37a36a3ece692ce87639c0000000000000000000000000000000017b8afc300bd70a3221120f6fbc37a8e6158c48b476f00992c6f41808036765071bd0a76f7c641443b97ba523153947e0000000000000000000000000000000012f686b4759a3d5db2325508f148bfd6217e027fe261d3ed7b8fd0526036044dfb563e1c4399ec266e140ca372120e289f3c65c2c25c6c37aa45b1104745cb8ec511a165ffdb7e304f5478aa3add4d7e00000000000000000000000000000000061c8288b7bf2856c075a176d1086fc49f0359ca3e7c1aaf5f151e6462916a4e1b69b6decb18823759b620f7593079c0000000000000000000000000000000000877af18cfa0d029e7c9a5833b346c7fdec06e54d9641d3953d3cae0e8912bac7c990f8864c2adb6e576442c634865b6000000000000000000000000000000000331490f42993de3ce7cdd53afb4b310f25881710a23f601ed95961bad4e9cbf57d3077803908a91b65fc32d1a84130c0000000000000000000000000000000005aec079da804fc572bb8eb867acb93a24ffb6611eba920d2ce799c4c80cd8e73b3cefe989885167ab685365529b4f2a8fd50c46bade91a13d6dc5a06ee62e5e89e0ae7ee885e5516ca6c2dacc36f6f3000000000000000000000000000000000ecc7abf4f6f9692cf3a118cd01abaab4754c90d1a59468d402bd699992800c2994f47b2094878604bf7825f125133e4000000000000000000000000000000000662396427cc596458e880bb8a43dbe046deb85601e3c64556990de36e8637e8ea3b142a8195762910a83609ca311c3a00000000000000000000000000000000198b9c52be68d073910f5b26bdeada9e9b308e4541561a8ffb21fd8e69ec9d93b01ec966fba65be27ee53d4857a43e120000000000000000000000000000000005201975985cac810248e333ca714cbcac0ede46bb915d8c857837c80c805898d0f9ca0940819878a26d269faa02cb86128db1a106328916ca5d63c0b5722642febed26f00a89430d52ec3eae25a019b0000000000000000000000000000000004e61ad4818ea3c98ed3c0d247798a1a6ca6bcb35a1cb60bda9394272ec092c385661ab93a42af439f1b55ee8b9c0cd4000000000000000000000000000000000ee0b71ebf39e4009bdb310fe3b555cdc860abd47a67bf481ab36b5ed0c00bdca8082abfb75691d45e10c2f2d777be19000000000000000000000000000000000e9582e3b5bd580f3ca7ca1f58e39379918f2d04b82b418a91e133117a9703f7df4aad30d48a47e29aeaccf5b8e33559000000000000000000000000000000000113b4c068fd040cd3300a2d1ef658955b014e571e7c77594edd31968037c1fff241da88e7a88669a569462564e28cd7d45665afb6a864893e389511a0f7b2df74c9e45a86fb69f6bd79854e3a88c206000000000000000000000000000000000d8b0bf633072f19db61ea263a1dbeddb326738396caf1196e31e2cbe99a68e8c70f8db13cfdfa4fc4494e54c1ef28210000000000000000000000000000000009ceaf2a0c63604afb8a903195933fd1ada0e5314255be3d74a95679c7a7845785e22d2c0c206f3afd62110ac9810c2e0000000000000000000000000000000003a135b405f46ae3f5cbdd63f4964cdc5014c9f3405c2062ba17423dcd22b8f2011638d520ce0ec7bb0cb5b03e8ec01700000000000000000000000000000000066eafafe1cea67aa6de267c767f49d4a3fd44c28d45a920fe9b3cebdeded883d8960f5e9fa4cc179246918942b1428d28f5fd09c2c1819adf8e6d0e0f4e4681babff46757edeff3839e9691888c13220000000000000000000000000000000017e37a2f1c892fdc58ac3f72cc5a5e2b7c0c87333afb06de89f7a84b1267695bcd452925fb2f15f8b7b20aaa85a6b5650000000000000000000000000000000015b2919343962337a41b54076d6735a093190e1965faa33eee800f5eaa43c35f349aaf93f19977b6fcd19360b27edd6d00000000000000000000000000000000161afb1494482f953007038557c847e2cbf84c57c5f5b806e3b0178e71e3238305f733943bea7ad6f2bc290778638e6a000000000000000000000000000000000c27a2170fa584863697292e626e2539aa15f3c8eee65cbf1f1b7ced6297248d059fdaeb9c955437a51cb016d1ee97c3e6e61390ef88f20591570ec1fe71c3ed769ee8e234c7cc7303a4cdc065717736000000000000000000000000000000000313a30edffaf864d0f1c6bdafd7d1e563cef434d45e71489e9f9e4cc6700e44991a99220f53f0cf5e7de5f6e4098bf20000000000000000000000000000000010429081ebd2ed6fa07de6ab0b7bd559a26a43df99fca0a2252411b4554dc69821ccf3df1b05114da84a616ccee0a9c800000000000000000000000000000000131a31442f80da4621f7691664e9f8b467988fa039bd086a2d64f9810878b557614c27745b2e821016f648ec36ee797d000000000000000000000000000000001160cef9f5e4d022baeacdf10b3bf9d7ed5e50627a99e29df1be3667cb872b2af333f803bf426314369b490c2eca642aa83c5af2f9d10c06552ea7d1749cbfa7574b238433c1c0e4788efd0cafeffa57000000000000000000000000000000000b20ec53bc643bdfda1e3947b3773d748cce1992e2ae27c6b7460d90d48e08eb9240879a5a7d3dc3189f486706438dbe000000000000000000000000000000001024bae4a7f71d3d2fb8246e82d95664c4ee8bca4a380c293ea084f749911f984aa4c6f266ecfff69c4f57e20c0660ca000000000000000000000000000000000b58472d81a9f16d2fe7af87170ca0c8c51dada62a4b2a713cae053a0066fd268283a785ccf269e05d8873cd686d2f4a0000000000000000000000000000000016b68177bce92fedfbd90cdb752bc332f46fde6673911c016fb9cff4912d79d3267bf629c33097cf8979f2b913c0936d4bcc88d85a5a8a29dfad37ba97ab3a5defde4ec356146db8d10f33bfb36ddd37000000000000000000000000000000001030d5791bd2a27469d242c62403883ca167303d907839e608acd827b4118b752840a4eca0acbe5df0b447d6651e517800000000000000000000000000000000106d65f922581237f779ba3e66608729dfddb2c487bc927f34e5e39707f2c8a82e8c96af68e3257c7a9876a05a1b01d800000000000000000000000000000000115bec40b8fa914305b1d5a85b65f0811517d36839494ba69c929fc2422f7e8b85d78df4e1687ab0087287eff29c65430000000000000000000000000000000018d78a75ec057cfcf179fa2ffa7dba79cabf6525dabd69ab95b23dc8f293aa077e46e562caf447dd0913ac9dd60ec76b29d5d818e62c9791c320e01a3164e142d9804e9caa7f96b4c3b76baff38ee2e600000000000000000000000000000000023f7736d6de94b08d9e9efb6f32f8c17cafb1e1b9b1f3db6e58df72a451c3225d11f4304eb0d702b07a7966f95a11fb0000000000000000000000000000000007b3204f258c873a6fcb48d0b36c98ed5f99b424cf4f92a028174e0e93db2af549648ea95fa8c7bbb42b2a10eeceaf8500000000000000000000000000000000165d6e769b7df91374dfb44e18d43e03ae12ee10d8a618a20f67332cf96492ff514eb7de06ea53096e823770c686c32700000000000000000000000000000000012e69ca1e106411165c06ca15988362de583c4a05425e2f4aba4c14cef6d8d04c52c87b4fb26b1557801f55b02ee8ba971c8aad41e401ab6c49dccba28ef26acf4961978e94e633b72c581ac03621e4000000000000000000000000000000000e8e6bf1c8837c31446959242285e9b85978a5349e1f0b3447e380a7bcd6bce758bc6192cb880f9c09d6ad4a0ee36eea00000000000000000000000000000000199b361ad0b435d7a66b46a43d06e5898376a6c260b68c965f7b186fc75d2f321bf883646e7551eaba03181907d3aad1000000000000000000000000000000000a76e3f399f31cddc4dd4bc22187a68fba31fe2371291ab515d22730d320ae4240911c755750f687c7d26aed09da4210000000000000000000000000000000000cbc8dbc004b9253ba91b2238c92bbf7883360c7ce39f6e15592a8668654950a3fc5a94cfa97f5ddc60add40c32a3630659ff910eea5280dc5c24c542516053637a5dbea576a94a22acefc902e56568e0000000000000000000000000000000005448b623604262a9cf1a9a292c36738960e132bcf0ec8e61a510008c2ae0b51b31da25f2bcf0d7c0d4ce15b1d7179fc000000000000000000000000000000000b61df56ef891bac07a873571f68fe43f79438a31038cf8ff97393ba44cc47408e5a6d64e9ebddf0195bf914f141e668000000000000000000000000000000000d196ced22ddf11132bbebf6c85bb3006a194cebca975d74992ecfcbac546f0f25a39ed5d6100768c1f1a791f3604d12000000000000000000000000000000000f727cb947849d2d7b046218f084283e5513e8582229085f9f98fca522879543429cb8ab435aa3dbf01b68ed258d82c112ff32d44eb442a711250875d86a401d0dccc95e5ee39bec71738fd812d487c6000000000000000000000000000000001044bcb16b3384a1f350cbd62bae568c96932a364c16b34d91ab9b1035ddee93a02920ab4dbde2c6f254031909dc3a450000000000000000000000000000000004a29aae48210289e5f588aede0756ddf60724b8ac54de5d9159ea834d5da98b7a9d09a6f37bcaeaabc559dbdde58b6800000000000000000000000000000000112ca953b5ba652c715fd20e3b85c5bdfeaa7d577aa49aa4656d142c9c2afa3d8aee151338f59a199f3c0c3f6a430d6a0000000000000000000000000000000001ebc7a17da7809f9e744cf7f13fc437de34d3472f022493f58bb979e2282368f989ca0982098a7c377498f1d8d32583666b820fae2459b98f9bff20275a3c96ddcaf98a78f3f5fa4a2c0a26cea79352000000000000000000000000000000000e7c3d6bef4b1723479ab6724cf7858c221993357b194e5055db96b8168f8d78f72aaa4a2046be17ae9a7eb00695ec510000000000000000000000000000000015e85e85cec08133b86738e1f7a738de455930ffd5073997a1f1692c28044ac00b634b90eb24938cab56e286ca0dfaa400000000000000000000000000000000164646a4767ed69f9280f96be9a7f988d17c187162554239797436a0bf4c4ffa7e4f8387c3d2406a7528c021f56081df00000000000000000000000000000000197b1080bf3ac3ef7bd6123a55f20f1002f366d4efea9e14ed92fd2ef147e2b5d9251a302a85172235438bb2d35943a740a9181633a146d7f307ca7606cd45b8e721c46b955a6989d421baafd8e40139000000000000000000000000000000000db7cfdfd58a6ce9dbbcd5d65cbf22b5e1a81acc70f1c85651ba962d61fbd7ad83e5524fb9aa019c6bd75dade96f7d4e0000000000000000000000000000000011e269a390fd15ab1d52d38de78ec97eb6202604fab02c4598ecebc7635ac91ee564e751275a485fb43b933678f11fd8000000000000000000000000000000000b8597a00d2401664405dd1fc7d69786353c86cd4699af981fe869f266f9087b00df22a46ac34883173bead870798f650000000000000000000000000000000009117a49b3f2a8a850a0179b558319bdd19a5f1f4a45af0ccad0890e63b222d028536e9bb612093cb3f1068d262af90d662ac80797c633d8b9c8907acc2960ebdcb5bdad82d9fceb4411d5173b7411fd0000000000000000000000000000000002e1311abb9df5e4d76959276b6f725f13728844f8c7dfe5e25469cb95c6937a822282b3baa38817e24a6219601132bb0000000000000000000000000000000012820e6ddc50e19a8f98c15013ecc38901a4ef8ec2b79b85c7f7913da24404afa1c79045f1318cdf271028126f9420a5000000000000000000000000000000001794e653c5673e51a3ace631c1a1265dba07fb74235506b2149d42b90eb16afc26ec0ddc54d03f7ba2dd6a2503971fee00000000000000000000000000000000112479bdabb9dd057b325563c666910c01ef66adf47aa32f5a41bc9cb8234750985c266fcc329ea3704e2b8d9b15bfeb59401af15d9b83e2ad68cc8e2ad1508391516ba0b26fcc5ec6eda8b318a374b6", "Expected": "00000000000000000000000000000000168c90045dcccef35cfe8eb642924ec2629db886366fd9ebc082019690d103627865f0dc39ffdd2167111f68d8d03c89000000000000000000000000000000000b6f0928a32672983664ad15252b3f145afaa04f11d5f43a6169a2fbdc0b0a04902a183b25e38987c45579ac6d11011f00000000000000000000000000000000195c4d796989630f85df4594eb8353d44bcee76d82b73ff7a57069466337b49b875b3c1418d22d79716ffded7e704a6c00000000000000000000000000000000032db644ff8ca6a3b1ac7bc51ff783ce0cdb7bee8b2c21dcfd3adb56a3e210390756211f22feb3dd4f706e13e5cc163a", "Name": "matter_g2_multiexp_38", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c675cb5e90e45300619be91c752a5831ec47b4143c28330422cb57139882e776c1c5f000d6032cd87c16ab3b1c08ee0000000000000000000000000000000000aeb4e78724d46a55e5f101564bc05e0a1be1d80a781ce8a19607322e82c7ee59db9f53ec34c70bef0766a5b965f54b1000000000000000000000000000000000933e8d7c2420cc553afb1c88b5f64c7a39f78272b34b5611972dd5ced3f639ae2ed2aaba470abe829be6ca6d666ddaf000000000000000000000000000000000ac0a9b46323ccabf4b2024e3a5b4717cd8de9ed7de8a78e33a38037f802651a4b43380a746890d93289d547d94b61bb9c351c585d1920b8cfb89a5bcd72fe041b17f7bd091ba505b287778b0be4e87c000000000000000000000000000000000196597114fbaefb8108c185a85d0fff0f6bffecf056902b22d61cc70b49a747bb35638f5b663830a8d2ee15df9fd5a1000000000000000000000000000000000616ed44a5fe69da994e2ada03a1e09065964223333229f5f30ba7a452830848f599ee21810a95e3659cca495897bb710000000000000000000000000000000012d0631e524ee9d3c776c79137499f8c9fb752ca93e92497d89973033d60971da23f672f140c1a753b4d00d08a00babc00000000000000000000000000000000111159e95d131c8cbe8df75853fe9b3f24013daa083e57c5b716e77f6fd3872dcfe0156382c9d2778fe886621be19973ec42da11e95cebbeed0ebaecd31be24801fdec8b81f4046fea52f553c4e7910b000000000000000000000000000000000a7d253487591fbed97381b3a430404b87aac04073e5931ee0bfd9ea6e0d38a41090c6dc7f6a591336fc58a97a3bea8d000000000000000000000000000000000647c67f1816ae6fec39033c3169eb1ea89e5e20e755cfdea33572d6397e7e87635c7439eda4912361a32de313893206000000000000000000000000000000000e0cbd54634d070aa3c7a503df1171a5cc435d050def17395707bdf7a61cfd539348ee5a4c29c7845cbf0e5df0531f530000000000000000000000000000000007d006601dc1e092a616eb470be35b5d32742dc6a2a4d71cda8865f071dbba9d8a3a8cb10b486253b1633e4590e716dddfdd8996780460757702e34ad98f5f64a8c1e0bc8851d6c97f02749b8f77cd03000000000000000000000000000000000c502a19770a892b2fa1ba59900a36c0ed054a8bfa0c4e32bf471b90d0da9edca6c06b133c8f12e233b104262a81dbe00000000000000000000000000000000011801f159086d07833a691182595a42645513d316c084b2841445c4a63c6bbb402664a9a9a100e8d6436337ecbf398bb000000000000000000000000000000000f2b9bfd8ef6286bc41e9f47ffdd3efe437aad553c9da02b3c22ca04b5578d634c0543a07bea966bedf345562218c2190000000000000000000000000000000010be5ffe0cc9f580c74e027aad09c213189fa4b7aa92160ce813b8d398b2e2803294e1a730cf5c891cf1546c6bc91414f256ff23b38b3b986a62074c5a3e05e86ead9431fcdeb67512f6d502fcefe3c300000000000000000000000000000000132cd5220c125759a18c31313592eda774247f97b5134111b01ef28dad5c3ba4d3f13d1af9076d663f7e217258a6fdaf000000000000000000000000000000000f06a5b03daaf8f92f9a302f06413044ca0dcf2be81d9cf016120312fbd41b273650fbb542d419595fd2815a809c4b960000000000000000000000000000000001b11acf12cf46e40554a1d6a833566cec1b2750f3f72ef77496477831d5933f477d59463ba19c03dfbbbd02fcbb680b000000000000000000000000000000000b2aaf91827ba923c8a1c2fa1d6fb92384c9f48f8f77273056b94245114d1f3cf66fdcab330673ceb2e9dad6c1aed0d4c01b3c8bb0acb17198bde9adce3b0f7ed4cd8615f837aee928524b0984c99d0e00000000000000000000000000000000051858339be99d1271152bb390e9a2ec0c0760b7686804ba072c46db3cfc4472404a9f87d868a28f2aef16c9e989d6e90000000000000000000000000000000019a33f21d0bb8303f540bf26816f145360bd1e9a8229dbbe7981f1cb5b099e814f2691fadbeeed8e4c4b772bbd27e60600000000000000000000000000000000073eeb49aa7e601732dc0888ae6b0f5e8dde3d97b818155221f5ab8c599eda75b25c86f15ceecafdfb9ee4abe3419e10000000000000000000000000000000001507073b97d494de26e70f18bd1723d931cd2a88903ab6da2aac3b80fea78ce75caaa9b99375780d759fc4a1683950bd458f882b63c99ada33d8215111a6df21c8f7424eb2fe9f429256201d099413c10000000000000000000000000000000013b5422deb0e80bec71309d03fdba007eed33c3ce0fc6d4f9a0d063136b3b85a6fce90ee59956a9b91e1caa519f813e8000000000000000000000000000000000829a11eb50f3bb1a47b72cfeec9d1f63e02b9f7b2592174c481ea7b72a121645ecb36b3d1964b082bc6c7efb4483a180000000000000000000000000000000003d3aab53814f55fa97285af2dc6d32cfcf5a08032d2c15ac83ea036603e08a53e0d2b8d93a25dd969937c113e78064a000000000000000000000000000000000c938a68688138149cda64f168ac1466c401196eaaa44a464d9e345c422948767ad1e25d1ce4cc5996ac5d5dab61516b804d7a35e5731b111a6904e0998d90ce86cf612914152fe3d2fca0201a41166a0000000000000000000000000000000001ab96f0b60213855fe221fdbe2fb22da6bd6cad8bab8ecb747c9528d3511976236ffefb34afc462abfde13a99503cb900000000000000000000000000000000182fb121778cb002be3f90e2d6837a406edbb609bfae8fe59837aea6f5f6131a10791f92188958b57059b7b9a9d3a24500000000000000000000000000000000159cac269098d223ee6d145a4489f05875b6a546767c023dbea62b3cfba9f8518c9f4d2594d00ceac325f3d8ef551369000000000000000000000000000000000c0d2e4e7aaedec7e53bfebe8f7fe5115720e58768469b6673cee3473b08fb8cd1ebd0514689ef65d78d008889e3ed296f1629a801db6bb4066588ed79f75223120728c3a57f7129d88f7f877149223300000000000000000000000000000000079c40bd7fd2ce0f48806dd2e88850ba988e5adb0cc5120977da8110b07da264318fa034c0c213590a2616f0ebe40f21000000000000000000000000000000000905f41389be39361fbfe7641394d30870a079f230dacef89149fdcf81a4d1e0e10b9fa1c0c3ecadced9aaa19fa9dcc800000000000000000000000000000000192f50e08e497f902403df40a504a1b4b82f1957572a9ab7ef97f5ab93c6fb876d8b08f318244cba95ad5200fc2a6e34000000000000000000000000000000000be7ef45a14871dbb344a69c4036af4f994a22ef14540377d1144a92978a23c2d678cca47cbc18e8c036714112d11f7cfe80ddbcaeb784e24975b9a42801c89bdfb842cbde5fbc0c3d70c0632cfcdab80000000000000000000000000000000018d7410f0105ff03cc4ddd87a6e0b65ede4abd4609db5ae53720851c90255757e63c6482de4651eb1d3669b1e1a2f8d9000000000000000000000000000000000d4223be106693a672da890b64d2653135119983639f7052eb32051c34113022080ce2355a93a2f64a75d8e0578b2f95000000000000000000000000000000000764780391249d0c987270bd181a44f6260ef82eb00c06585db7ef09e8b069e46c4e0e659a081ab0fda491534b71b0ba000000000000000000000000000000000a8546031e6466ae43643462b7617703a63841d6d4cb0c09ce63b2fbe2c2ba7cc35367191d0313717b1daa665bcb54551aeff13de7bcc4bc2ac1b37e28ce466805757dda29c9c743eaea9da33f47f4fd000000000000000000000000000000001922491dee4e0f29a1dc090c9b48fe8e6d70c3441e532021985932005b22cedaeea7d9ce1796808d756b740ec63f8ca80000000000000000000000000000000005b34dae0e630be6a59ccae17b44eab4e7f10be2ee700bea15f9771a724f0979798617e129540901a8aa023630a446f800000000000000000000000000000000095bdf612289258b31cc79188566ceeef6fd66858b4dc060864d378cbbb69f951e9c6bfb3d1384014507ff29f9446f410000000000000000000000000000000019f06f11a833c06c1c9227255e3a1d74172e73b06675c547844065dbb909ad66bbc150ba396fa1ba22b7183c0fe80e96c4984739882bd2f882e12660815b96d2af7812d7ae87f5be034b88e9e04fa2890000000000000000000000000000000003de8082f828ec51e23c864a16147546ff60b5fa71897ff4c120556af5c6616bde96b6e53fa673cd1f8af503070bfacd00000000000000000000000000000000093013f75b6a19b5433b3b5ff044384ddfa258420c80fe81e0424e3102cbf9e550a946e56ba9746423ef745e33da51e7000000000000000000000000000000001227cfc3e9a8d6a71738c514c05766ed4f1f4605198f5a3ad8309c0a49499e4ecd34ba1ba7677d6d90203e54d7611807000000000000000000000000000000000a635221d514e58170ef299eb7f5b679050ee24c589cc7e348b2905a3cd1b7bcf2010cfe168f5aa60f4bfe15e59b4436e7f33141d383a1a927b7645656ff7a5795901a997e27003c5672ae4fbab4aecf0000000000000000000000000000000012ff0494d308d3e7321ad4c4000e9dcd19552d5e4bce8504760f066e2fb2509279b01f1568e3c3f6216bd5328cbf72db000000000000000000000000000000000038c6e8f0fab30b5c8e4323c1fd29527845c29e1a26c70b8e5284f7ca55fb55ad4ad5389b5280927b98907132f26b76000000000000000000000000000000000aef946b9b9e9fcabb36507c1cf441df2f5ccd71ef9281dafa5e25bf07d69556e4143ab402dfb38aa756bb6ee009a6890000000000000000000000000000000015f69bc7b0a6f2cb64fd0897b421e339fcc8637efced8bf33f5aed809a38b49a2e6376d18b1bff0ef70df1b7187ad048fba4674313a9727aa4b733832a0e06666d3e38184836edf786317de9dd055cbf0000000000000000000000000000000009e8450887137cf45b04184b3c6fedac6676cad416a7646e9980dc99a6d6b62164dbdfae7cc20edaacb84432627e6e550000000000000000000000000000000002acbd87ddca9dc775da01ae026f1c60f1cb5974ce40caef80cb0d2eb7839777c1f61eae0472c7568ec9d0ebb2ec7dd20000000000000000000000000000000017c295c458a9dd995d848e3ba585f8dcdec4185a953e4b8e3ca760eb3e815e39a8ff60416e1e6f974cf7e7b086ee4baf0000000000000000000000000000000003cd8725e1cadfbd80585bf5a19e086abd631d6787403edb4bbc785d1a81f6108f451ff642f4df17dfcf94dd6107352bdc0c4d0e34d8a16b3bfb51ffc9b3c353817e8e357c608b5075c173204963606e000000000000000000000000000000000b3cc99db523b3647937b694fc23281a74010079351b2c7d1ae4cc9167917f06c06e627c4ec44af6b09f2886ddf309b800000000000000000000000000000000001e2681dd123994627adc92e6ddd3ffb006521d8bb03040fe1989e4f709e4797d143cd0bb749de33c8109933c709e970000000000000000000000000000000017df13f532bc9894be932e72c609c0386d32390dee95dda45821bedbc1067043d46007b39b6ade871bd36d39a17dd04d00000000000000000000000000000000162db4d1e956fa5b5f9ef244dbc0c6d27718eca7dcc512d1d7b97bbfd2bd00cce7941d1b9a170da6341891773a729e9ae4e31f5b6629463311b9d3c8333c33c5b2e79761ffff9863acd9d636e1a9586a000000000000000000000000000000000f0e4b606ba0a175bf57d4478aa286640ce4b5507f9f9e354fd96c45443333f6889a93012d663d78956bbfa7c645bb9d000000000000000000000000000000000d85dc4d733f0498fcb10e1e814eb61245203d6c1a46181e5a388fda2680640a1271a68d645f8fb179c0dc3107fb788500000000000000000000000000000000185b02140f6314cb62bd7977042ffaaec41ba8788d356047488004d609ae680c2f0cdc94e59a3cf90b6651298b6a81d000000000000000000000000000000000038ce717d08d367a9f882f2241ae4cc0e8a31418498bf68d05805db2e162d053a10dcff85403dc473598089a78dec27e03f256e58f60307ac1888a1b0b14b56c7435213e271eecc79b4a6f88d102be4c", "Expected": "0000000000000000000000000000000004cb919a72e67c31b3409c28dca1d57833a5066c240d2889f5bbdd5540ab2a49484c2462b25da197ec8d93dc8f26ea83000000000000000000000000000000000e1ac1dfcfe22ed7ac52c701a7221b542ce72bf59d62cc49f95f8ba64c05060671098d40c83947dd1952494833a19b55000000000000000000000000000000001331f6ed8ea5ec9b9e1a14997c2c9bc9af2ca305b313e2bc5c5bd35308b7b451a362f8ad61d636dbf77d1b2388702d8f00000000000000000000000000000000186b85e656e45cb5ac9a2a2009353e45749b53dcdcdad4f378431a0e4a317652301f834617e14dfac9836c3c11512aca", "Name": "matter_g2_multiexp_39", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e6292b4d3031fcdeabe62921f0c562606b1ec6139b9c43938971d7851da4945cf69f39652425396ed1b2e70e65b9f55000000000000000000000000000000000e94bc63f3b8944ea6bd7bab811c013fd61303aa7713619faab85a271308bb220e2a94b26f5c7e4136a3d2761dffea610000000000000000000000000000000012313ef65ba41f8e0a57e9b810c13d23241e8430c6ab967a1a9bf5bd6308e89c135e00e789a5610694d146840fbd877300000000000000000000000000000000165ce83af7edc9e701eb57b332597305fedf4b939f3a13a95a0bb3d119c2a9204a4991388f7fb344ec8f15d32cab0eb5eb850f01feb55bb99e4accee0aea8fe6ed0bd29b2ca942ffe09456733aff10ea0000000000000000000000000000000005a88477765bbc8290b7eb137e6de78e62bbd929ca511cf0aa701f926440f21d33bcc6ac8f2ca5de57ee8116c685ba38000000000000000000000000000000000738074a9365c707190f882780b27dbe96179224103392b86c628b601e33b092a03e24a89bb6d1d1024862a9df6fce8d00000000000000000000000000000000188c713945046771bf852155ba412b4222173b6dec8320ffd1c59e9b36943c2c18b0dd3bd551b7b1367dde3e8031201a0000000000000000000000000000000017222294bacd664ec37e9b214407e5325eebe9753b430589de2eea13360783be52a479e2b0e9c5dc4907dd5f06a7fa822b373fd7e5806d227ca1f49ab0a7f8be2b5950906c8974de9f2cb4e13ed20a9a000000000000000000000000000000000c97299d7e18f41e538b91b75e962c3ce4e068202271b40469c58cfc477d7820e90a0e91d647e8ef5fc0cb822daefd29000000000000000000000000000000000bd1e11a3646c499a240bad708f97a49acaeb653aa5bafdcaba41c1c9d32d32c516c94a3db8816e0a43d1b1eceac7243000000000000000000000000000000001223ecf82c4622653ce84460c39afe8a967cbd87a2d75cbee1609161837c15b522480c4731c9e6de9c5c392ef1db18e10000000000000000000000000000000016c5e98d3d17c723548427868e3e6d7ef4bca339e41acef19e0710459bd4732de4a556b22cbb49b823c4ee656fa354f1babde7f3fdf9fba868b5eac61337be0d73517ac3f06c39b4eaceeb27ab6311db000000000000000000000000000000001125735092842142cb5387f1ef8fb69a3535e1f0ccce59661183d3104ec1ef79dd87a7fb36159bc67bd73ad403b46c1500000000000000000000000000000000162caf579539574199d56f4e756f1532c66278a55b4f67f4f4090368260f46023543a8a18d49e8c5783cb65f93d750480000000000000000000000000000000003accbc87996a220a625e36d5cdf05d8c16fb353068ad819f94ba8223cdf6436f8d822719153bdba620a07c5dd955fe5000000000000000000000000000000000b53c8a4b62466c998327e0c5ad65818ea383650bf0977d98a8a94fa9653fba276f7781af9f5a4e99052ee3ae65c283d5ba1635cf82b25b2d7e466717f5716c33f5f3e826bdedf19dbc1d95ff0c8052e000000000000000000000000000000001264608a59c0ee9a26568cdcea8801cc8cf6616773bcb0971234b2d987563270c7b2291fa035c8f2069ac99e16c68fc0000000000000000000000000000000000e839d8d982d6663ca4552527f4fcab6ad5e0a444e7b5921055c774871601d342a151133ae15bc76c023b7ea643182ba0000000000000000000000000000000012ffd0696b7e29b305412fb840c596b66b77ac2eed936fdbe0562541e4de6b3166a9991dbdfa0f79b78b4b86f11291de000000000000000000000000000000001777ece357f82d7303aa816237a0dbd3a1398574f4061dd2fbf6b32af38a65abf5ec9bc53bb8ede932db9cfa0842d53a1a0a832e5bbdf897553c1aed35fab43aa3f4510c1782115e14e5d56229de2dff0000000000000000000000000000000002b41743325db9550c3a84af80bc20c54b8b0b685d7f84d05d14dcabed2f450b91675aa8c5c650eb81151bcfbf1603b4000000000000000000000000000000000f3d3e69d475fe1d4259f18f193cd84a90b91589a6502588106f0a577d1c1dc4b2feeec20a4fc30b3e403d6ca9e03894000000000000000000000000000000000c10e2bd1335363fe958eb50981b99bfbadfd1c414830857b5257bc8fa6e26b50989d9adb5b3a2fa610b3151f8754309000000000000000000000000000000000008c825371319f4ebd684f76b567c4e9a389dce96068c101568dc8cafcc10896e3c20202b591a344d9a1c1be02310be9b75e0582e9ad7aa4a02ed5ffa22e55570c9f20e6a24e2186e8a2a2f838fa45300000000000000000000000000000000101d3f92fe64af93468229608007f50e3406719572acf265fb8b2a7051525a9cb67cf2e46fc8e098cf081e73f3b20c770000000000000000000000000000000017b1422f8208c2521e3896820b22a65bb2a9b47d7fdcd2ce57196123c1ce43c1db6d00f236d7582795d00ef33ad6d585000000000000000000000000000000000e261500a9c64f5ae107d6ccb57fa9151f5321ef4e80f0e271515f1eaaa5e3714c59bf97b39acca41b15d90c0505ba9a000000000000000000000000000000000c08c955b6df18444ce3726711d29c2088721fa0aa6e317c52a05f73ec7171ef8bd61047174c74afa1dea804c68a28e33b7252f8f3cc6341d490c5c4464bb36e012f1b05057f405aa907ebb2c983f646000000000000000000000000000000000985cdfb3934e0484805a1965984028d6c459654a3eea6ef66e867dfc737e1bbcd92e31020d5a4ddb7f8091cae2371f8000000000000000000000000000000001998c5682209153a261bf981e16bf1f7a6f8e5e566c1b0f975253ea62439e5b36c5e5060751f21941edf0d348bafd18a000000000000000000000000000000000c8822c1d6412bc45fea05faef33c65d5a6dd13aacf1279b9cfda2a2ee34df3146d45e3434ce8e5f242e9cf7d3ac27180000000000000000000000000000000019191b51d6664a3047aeb5590df2939b2cbb115ded70fafc2de4c2e8c2a955a957375314081a8838bf89d5a140b7b915f10427f6e461e7b63b781e116a4d5136ddc79ff86b71fa754f00c797c035412b00000000000000000000000000000000156fcfffbf01ff3c8a97e7bd99e59327d38c6f7f1083d068ae158d1901808b3c9ac96f95c2bcbdf5f74b36dd8ce58d7d0000000000000000000000000000000014c64256d1cce124c01fa727482caf8ccf007e4ae00e5277d984f31a11ce584e7633565c61d47bc8accdf7c28bb266b200000000000000000000000000000000052dc9f7fce4859c852d3d9e1e77bb7887ffd35d4d550726632acab3d4303ecf8b3ec7f4114dbd590ac20d748570899f0000000000000000000000000000000017abd1e5dad7ee06116a8131c05c9b48defaa92efc636ee34a2970d701c02b6be0345a58cd8749e582ebd105c02f10a06440c89f8b10ce15806938b7ad65ece194d2fa3cc8d7d5591bc1d52d010896af0000000000000000000000000000000018ce0fb077dfefd57f7943d432e12dc9bf92dfaa30f8341397ff8906b1abdf0c02b599edf85ba1e5bb6287aadc72d7a50000000000000000000000000000000019e5e9e3b0632ec10a26b7c1ec40248a9a8b230806c38aa24e47489a8aee5abb5450f6e5679e3f13c6ec7a79560689050000000000000000000000000000000006e257a74f45142817ea8044f403e98c99db8355d626c59e1d11c6859eb0dd1dc8af389f07562259c1f85411be6cbfe2000000000000000000000000000000000f463e345b004b1364894c6e8ab5d35bfbdf6b7544a576ed6b5c5398ca2074f67e2d80af1ff5b721fc126d3afadff1ef43f1bb26469b778edd10127e634fed4d749e25b41d8eba86eff2c068c33e714f00000000000000000000000000000000174231581338fc8c461c981d4949d18f5b753d27184ffb41568f11e178a271bfc69f8c73f2daed0fdbe5bdc7fdf8ef56000000000000000000000000000000001532474399d6a73501801e5f3fbfc6f13bdaff7a3ea7634568fe82745752ee15af23b16809be18788d295e044e29c05a000000000000000000000000000000000912eaef94ab1f3b3257b26c5e8bbe3f99eaceb8c7ae8da577ef98e24f3308abe6e6005ff674a2af01b4242f8ff87108000000000000000000000000000000001925cd635d0ce770f4925a3117721e96c316dd96708b096901ee04ce02e7b357428e4364cd488eeedf76352a26cc1d10a40251ec7a7e9f7cc29948b122010d9745752df3f4a9c67427a8b58122ad4e7e0000000000000000000000000000000005c4a7f26ef0416f34750badcbbb3bce075606435ee7f69b3589e21e37491f0b4a7a98c825ec222848f5e29618828258000000000000000000000000000000000381c5f6511c9f06ea1a76ca84adab4a26a3cde13e0825b3d81899d6ad3191628894d0f57787f854aeb9e4c57fd15d32000000000000000000000000000000000bd706a5b5ef0d4ee1b679a0af90c217ddf9242b7c39523c39657962952dc14e5e07d02154e05693bad08bfb24a2b19a0000000000000000000000000000000009f28a84aa5bd39eeb09f13fc8770fa7e2e053b6f5d7e6021da77f48b9c3807ad917ac671de88b28dd343c2847c5e8eee03e5eb477506c397bc1a5204b30872085a36b65b7a8df3e0e187f3022736329000000000000000000000000000000000a8ff1b15ddcc3684b4d4ecfb53473497feb8a04660350ab84e5719fdb0618d61acbb555174b0900b32341154eb7bec9000000000000000000000000000000001464d21df798c0242ac6aaaf3c579eb66eb8cd53eb1e5ab2727298ca61ea8ca4c7cf815bf5c9f94c2b76bf659a4e2da50000000000000000000000000000000003a25752a4360c84e9353b7f1ce74d5106cbd637ec5ecb03dd0752660fe5c7622fe2d0475a4db98f785307c6961f14b000000000000000000000000000000000163601a86f02900d214ff8fbd041934189503438c557138b6ebaca8ce3c109af50ac28074223fc81d6476a3a99559ac565cb04110bbfcdf00616c2826e253f61cf955756e94dffcbb6001f59ae4a93c100000000000000000000000000000000189597e6d618a20ecf9a87cc70b3e0eee69ffa4dba75056ebae93cfc3c2ebb368532b17d9f6c06f09e44d9f101397b2d00000000000000000000000000000000086ba610e490588e9385c8b6944c2bad1eb03058e927fb2f9740dbefb779bdf669a51af88b45985e8345b8cb168c13ec000000000000000000000000000000000db8b9cdd4a9bcfc9f7de144da0b33981e4dd53744cd260c4bf045d643a4ef5f25aa19edab7be0c7f8f5ab74a4b7f1820000000000000000000000000000000010198384a646807b16e2ed9186aed99ca3197b05964dd0348086f446d3ebb847907624f4e02f71a1e866d17a125e07e93ce1bb7cf7d7a55f0624bf5c4c35327b178923d88be748a9b079720c27b500e6000000000000000000000000000000000a293f07dc3f0da0da4bee671951175a4480a719d44cad3d627878ad2f17596f0dfbd6f43acc7a1f9857c5d1f453e5d5000000000000000000000000000000000be6382cc7a00d590f2aada3b4b75f01f8538caad2ade90227ec71e5661ae353e68789807a13f28b23b17dc0dafc19b70000000000000000000000000000000015a9ad5a6f1a511ffe1891ce260ce442996fe4d8515ca593e3e869cab9b18af57956b1daa43aec98a0281143b0c319fb000000000000000000000000000000001807a4ddb73a9aee58b54bab2b878bea8429cdc91384c8fa533a8c9d15c966350e892bdfce16d37a4048a763cbf25d71e2b4c64b363efef0c5525b0337bf407879755f060af451075f4345dea7e681a30000000000000000000000000000000015aa6b865796f88ffe770bf25612ad27942213131c566a446dc149fcc70a018230f1cc8b20461ba2c55300fd27930bb0000000000000000000000000000000000c39c4f229b23c0f65ed720d655121eab50f695864959a2aa49771b848730494d14597eb85ba35743f64eda897f95917000000000000000000000000000000000ad44cafa754f06e45dfab801998c40e5a9f56e4add5c8add1d7ed9e05d12459f2efe3f3367cbcd161f524c714f7782b000000000000000000000000000000001437b1f1a1399ce2a860f7c6517b14a2db264b2602c1c57b8eb04e165205842b483497e98e6b6f8a62e25ab8b0e722f04c85e47ebe2c26e0aa25661d3353b5d88c632182aaecb35303d8d47f01308a0d", "Expected": "00000000000000000000000000000000077b81fa5997de07738e1b34d8e17ef4a9bde516577a4290253cc759ceaae745e10a457204b9ed0069942e0b487d106e0000000000000000000000000000000015e79be67a752a46dd0605e9d07d738c5732b2b605457ce056deaa1f7093b0bdc91b4c81c4c5462a51bc713a7fbb86c3000000000000000000000000000000000cfd2e6043263bda2b97798e1a7dcb24c63aa7197f2749f92524329e97f93dcb56429d82c1d63c067d7ceb38e6c65b5a00000000000000000000000000000000026f352d2f93e6407c59d58742dbd91ced464a3746dc1ad9059e6bb9c146dc1e74235bd54b1d90bb3399865cd3102f3a", "Name": "matter_g2_multiexp_40", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001387fb972f997ed0cb97a5ccdaa759dcc3c2c7f4f15e5cc4fe74685e42cba75e778772d795847b45f274d32cd4960de600000000000000000000000000000000150b1ad31a3d434c1cbef877fde2e105d4a047dc34e3889d21544c2143e7b41b8e0024443a774bd1e09438293860a43f00000000000000000000000000000000065033cee91f5c4d429a074be3d2a8b001892455a11dc708ea73c0082bedb1cb8e8b567a6ea68a1296ad2b80e4b5b08f0000000000000000000000000000000001991ff6fb57e8cbf9d228f1a99697f785261ebce9d3c1f592389fc860b8d7a069896dd48debb8cbe0c43175cd2ecfff5bc589e7d89994400c511789cbcaea19b077e0b02d625e549bc6f2673ce40128000000000000000000000000000000000a0fa2d39d868737b9a0526296335256ab4894cc58ffd80bc6334e80d1314bdf017c8226b41ea135f6adefd07650ca1c0000000000000000000000000000000004334f7985211061dedc794ee8931ded12acd39d7e6a6ef44a749118d19ce8204d07935fe62fb2a8ea4f68f99d7c5f5d0000000000000000000000000000000018850a3fc8c851a06781511faaded1ce0752e7ef66da82c2464eccdf78c32fae306da3cfedaf76dad371cfbe012f2bee000000000000000000000000000000001296ca0b0e368429b122537b096fac77d6367988956a7f6cf70c7193b7033ce42fa0cccb8b84b9c78b16a68fd5f4c14c2c3d2a0cba111642a6354c117d494be805cad5b5c486bc47906a2d37a9cd9f850000000000000000000000000000000019deb7de7fa5254fdf5ef34fa616651ec70548187fb0bfae9f512e0bfe1f662783f06a9a99e434ced84229deddab9d240000000000000000000000000000000009c199ef916e6f6fe0677ab07beeff221a5687fa8da3ed3ad99a950b7f27159f857d1b561006bfffab551d240b764fb300000000000000000000000000000000148a211fb58b38072cf7c417c70d3ef92e9cbe22b31b2b626198add01dbe1ccfec32d333abf42140b9316312ac48aaa2000000000000000000000000000000000b551b57045365d842133e46814d5d0084248904960f8d2fb28e9623660bcee658582928703f86261cd70e95cd20cf3a530ff74626657262fb49460b2c6981155871f2eb5562581a74f968233c3cbe3d00000000000000000000000000000000185959a297a8f434cb9529a1f7bf9009fc1af3d09efb0a9dce1b9e7d30699da64e4b1d32cdb05b068621db092c1eb59c00000000000000000000000000000000106ef21e9031d108364e93ae4b5d21b0d6d78c2e86e0f8a7af27ed3d38dba0192954e8c716665333e5dcf21387d3f2b1000000000000000000000000000000000185d21efd7d613c409b6ddaa66eed70c235440974b2a9154f3711e3969061461f8824b4547c65e9db09ce875512ca2b0000000000000000000000000000000001aa46b22451afb12962bec5c6309feeb4acefdf3c98c1ea14275409b7111aacf7c92a8e024d01d4dcbfb1c91fc445a1d182ac912b005e90ab81d4f2a906da8309a69576a8afaa160fad2540ec049913000000000000000000000000000000000557370d81bc3da4c50980106b8e65ca2edc757a475194cef201c9edc0f50363cbebcf2750acab0b67e1020daf5660e7000000000000000000000000000000000462f1c1379be9bfed97a1a83a00428de63eadb6360393ba162af3762a99d7eae8549d0cee218e469e4997ada7b35cc00000000000000000000000000000000008aa5ead309fc703f6de980dd43c294530cc2b38b94d5281e9cd9b0d09f82f747a7107b700f1437f3abe36c01bcfed1b0000000000000000000000000000000014110a19d574f26e11e2163a981c3388c04854c5693e9033a474f1020d5f980666d84c60370950734c46663e194bf0ec42a002a460b51429e25f85ec4abaa580ac1a14315b1627bd52349b7b81a641d60000000000000000000000000000000015beff8cb3c79098bc73dc1ea4b240a4e0d094b3dbbd51592df6adc9c9847beb436ec83df6c55666e296fa843298446a000000000000000000000000000000000943aca2a6e57e9897ec764ee2911d9ff0a59d9e903c70a8494340cef2143895e79d3e6c03af2d6461ca199dfbd0ca0d000000000000000000000000000000000b812ba87c4989af07af44f3dfa87de119fea28ad598cb8e52247cf41bb8bd384c0d8913fc82e4cc2878065e797cc581000000000000000000000000000000000410ed148d1e354653f9d9d17c50026957fb03fec64964f2bee5eeea966b430e77f7b3538d9f4700a673fa07d0daac6b7a650dd3765032ac139d1b54ec7a5457c9e3caefa6af45d198433e5949d149ad000000000000000000000000000000000de0a9bbd63c59767938b555c7f9284d0885ca23019818c213a7d4f1594b028965da871cc5818240d155c05c69e4e25400000000000000000000000000000000079dee5649cc67700e9338799a9810d352a5c68098d0676e42e00bac31f37513944dcf47408288cb7f1cba121506a10500000000000000000000000000000000101a650e84352aaf3817b400da0aff40907aae3d2fcf16739f8ee8d5bfc62c2a0dd518201701932728a41134ea3f6278000000000000000000000000000000000f1f9dcc0b55d0ed327f667cebc052c4b6116fde5e3076dd6e447c3214d4c8847885be9547f95f341c42e7c7fa7e2c71bbedc44d54349cff199befba9531dd4120a51e2b830a3e356e68cff31bbe365b00000000000000000000000000000000148f706b4c93e739324e5db40d42025535cd33a32bb3f211add618c0e2022068384a5612da67150746896a2813a664e80000000000000000000000000000000007204ebcef495ca8232078fbf1539a4b46e89506a09dc008da457dee2792acafb6baac4f6cef2de15cbeb48bfd12bfd6000000000000000000000000000000000bf8900e48a4a56b653b1e02c3b9a7d81c2045dbf6297f1ac2acd69d1bf9e06480ea917e3a616243c3a30235abbc426f0000000000000000000000000000000005ebe0ddf4cd1aee76d0b3d03eab754664c8b36fb20ab1060900909e0e0a4abdb45bf74a0b1d40fece9bf73360f580bcbef3956ac71bfe97029b8e3f85923c2fdf9cf1ea6582b68d5a4eabc6b044c80d0000000000000000000000000000000007824d1c48bb2cc0f406e356f6e52b66392f6203f49dca7ce03ae6302ce3e8055d071cd812f97481acc654b318d6cae2000000000000000000000000000000000ae89f9eb1abe452efb7ca48f8f939d835f9a79e05211ed9f4abee06b93e34b17d920ddbca3d8bf18b96c3705c1a064500000000000000000000000000000000119ac787a7f3e9b7ee34070aac1a769430eaa8cc838f1752b573ac7f3c02a9f490de9600c856a55448598b149f5392e300000000000000000000000000000000193a3655a80e6e0b1278730600fd4f645d54947d193484131176b890ac197702333ea847317568230ad8af1280864096392f5b4291fbb18a93248e830b08fadbaad6434040c02b45cade73b77f22c2bc0000000000000000000000000000000012f66629836f0f57bdfd9bdeb2c9b7d6d5dc55c586e15d76aaa04aef06722bc8ca156fd1295b3063d738a85b3e8746d900000000000000000000000000000000097825c5db7289b1b9e640d19ecaaa81ee59e5b9884713f6d312604d8ac367634a264c316d73a9cf63358c8fb15f8c5700000000000000000000000000000000181133d027b97d8e2bef308a93b7ea2a35824dc7d01a3ed2f404fbe12ba3b3e51d94ec86cadf3da7dc9ecbaa23b411cc000000000000000000000000000000000a28a609d0bb015e375e74c087ce426dd3c20fbd8b374d3817c626faa81469cfd11a2a4e418a44f4d7ca621d0564bc4920a96f963375d7a294b584f2da699a6a00eb5781f46830987346cf4fe922a2f6000000000000000000000000000000000feca6f7e3cb286090fa3df9c5ebd10c06192fe14af58d46b827acf48fbd462f3f76d9d20670803946028437410ea52800000000000000000000000000000000183dc7085483bd05c27691c25588e33296fb610bddaac253af5b2262db38091650c1c3185d71a69d1a63770f95f381d7000000000000000000000000000000000189f9b9ea528bc2377ca3354fccf440fee059f5732dfdac320fb58541e74e444dbdcdc008c7b47681c05502f0b302f5000000000000000000000000000000000906162085e0e299a07e41b9d62668d4810b97d4be317bf376da537de7adb06de011f5f40af834593761b774771a80e4115cb4646c8996239f4fdda8c27a335361f0a19550d6eb0225c008408c47258800000000000000000000000000000000030cc52d7901d0360d10f344cecc8325412788cc30a912d5de3fa9bdab18db44efea235c5d34bab526f3b8ecee2cbb8d000000000000000000000000000000000cda35f561c19ebd85a445ce8bb1618b446c7013c07606ce58e0b5627a5c9e7cb200e2b8ee12a0564730279e75b469b500000000000000000000000000000000055ad0655a96f6dab5a432e7d2fef57a6a11113070444089df23b4b911e0994b90aaaaa2c62d06756f4704fa218f7c350000000000000000000000000000000011d22438d7c162d34802a664c254abaae07659902e1f1bfc2bdffa6c17eb11bff5276474cc3cec9507e28685f1c21bb0c8a8d98c93c392aefb64ce0c7ea455ba14c48bfbad0e3dc38d43abbc3276caab0000000000000000000000000000000001d04065373ce5d1ce47e00476f07708bb028040edb9ae7e8e00e2c6c460e1ab8b730ff510a25a3c8114c1753b7bf1ca00000000000000000000000000000000001c87217f150694a84a4e5aba8d188ebf7224e76b078dcaba4a91de6b4ab317966ce1a9267a5a27ce556c3386b086620000000000000000000000000000000003c8422590826e0999e7ae3ecba84edaed20fd7f1eba02b9daf1c46c2aec74d5fe63319047d37f5115f243ae0ddd4ffb00000000000000000000000000000000136ae093c3bd55ddaffc2494f3ba8176947cdf2f1ae408e7e786b23b6a65ba8c4131c83cd890386ba531b8637b3b042c8221622734dc6ccf6c7b84b387a3dfecafe187dab70ba373b4416ce3c505bef2000000000000000000000000000000000d09b92a559b8efe5224184fb4f43779d0b8c8f23587f4f74e2fc6fb1f94e8d2e0d591eb0702cf51a9eb402e79b46a0a0000000000000000000000000000000014ec2e4702f1ee1074cd1ad29791cf4903357e62570d16ac80c5e8ff73b255ee03a5ba070091cb2f984b2139de06a97d000000000000000000000000000000000d22fceaa48193756ce7331952a2d9a8057b67bede729e07cf8422bfc79f9ed2aeb99a9227af256deee9f8a6f227faba0000000000000000000000000000000015d9322c3a5a7ca404259c4cc7cb93dc3d46dd8dd9475756d2ce6fea527642f9230c7e94a804ecb0b4adec7963fa9cdcd3d1f427a25f5df025fa71244cb92dda9391d65b04756c41de0f67ea072c375d000000000000000000000000000000000e16fee11affc6714c7fc8fc5e7cce44d8afe645861dd2f0b8e58aa93d4f0de9b7e73020a1537bfbb0e2c8327c4aae03000000000000000000000000000000000b7745a4aaa8ab4593daa61e375d55f9043fbc7385ff229889fca514562168a4e769c5eeef4d564b41cff28b4efdb7bf0000000000000000000000000000000017f6c5b1fb00746b50ee4c7c743ae57fae2742617e5565241d012a0ef6067d9ce59be749a99886ce9836b648525d2e92000000000000000000000000000000000a3be81720e80f6aa0570c89613c78efe95d87ccb374e7f77065800590bc71d23ae097516ae1e97b498cd233221cf717b55c943fd9b11f2fb8a89f6c08a6eabe9434062354d845f1ac740e6043443f8b0000000000000000000000000000000008080a7d91caaf2470f9632575b43990a9523219d75994f1944979ed5b650be1e3c93eceeafb0875f66a40651f4c6dfc0000000000000000000000000000000007a19c4a6340e39230a33b12fe63e47bb0d1378420ec9e439f216699e512e4d70571a1670eaa6b60a5c899ac63360a250000000000000000000000000000000016898d22b2c123003480e3a01965a72de94cdfa39b20898c49e451dcf6a4727a1ebd629172aa1a1aa6897916cea192b4000000000000000000000000000000001217a373c78de9d3005690023b9e56bbed3073f13ca2408a27a3480578d8013fb9d3ee5cda95c3cdd091a5cc68d928da7b0c1d54e51b8572256aeb72bb032a5011a3e8ec5ad7e8b6e0397b9f6fc64c9f", "Expected": "0000000000000000000000000000000005829c932c80baa420602bf841ad9bb24fa25c61f33f5d88693207b81271c94eef54bb524aa830fdad8caf8c082bd4990000000000000000000000000000000000b8d184316c2471ec6875641ea83de4f9b7227041922415b38b07a0704d01f2585ec2701bb4ae0bf6a0c0522efc0c630000000000000000000000000000000001dd81e075620914254b38ca5a7287eb56f2f31f6f8fe02fa51488d45c7f4609bcf49972d0ae5ded76eed5a4c096939d0000000000000000000000000000000008067feba36999b58342ac54e48b0fe28245f8ac2498b60093082822d19854df5c3168dcd55ccb6b2cb397b77e712333", "Name": "matter_g2_multiexp_41", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016ed84856b9f41be9bc6c025a9b79e2968e2ee6bbc27608093256c541096e2c9eda1159e6dcdaefe783aa59d52f28ee90000000000000000000000000000000014aabafdfe8c7369f93d5472a9c6c4d426e4b02c943488be993d04ed24aef5477f6d455f82b4af78381b8bd16f42b56f000000000000000000000000000000000af34789c6c923103633e5b1b9fb447b671ab05265c16488ca7224e49db21973487a5d3de4de40b9d8a97ac9b1966619000000000000000000000000000000001123a6601c5351a586f27f8264d4227f5e1df868a03e0c3df5c148cb523cdd178f96fbe52464fdab210564dfc22b29536f082a5ffb8baa38ffd684a4a70114343a1e723bfcbfeb57d0a85ad5e592d7410000000000000000000000000000000011b82d78cd9b53b8e7e5c14a7371f34f08546896bd59d1e7d8be15d21742180aacdd01b0d08da2cb24873ce75e166bd500000000000000000000000000000000161ae0d724085a6e801edf73443cca87995c2d6b37e962db5719f4c480cb830e379fa778fd2f29e75173e1c31daccaee000000000000000000000000000000000a2c2b89d00b7d19f2b0530889905c30cecbd4ed0b56ca82208d666e7576c32a6e90cf867ad87f19e4fd367a10c449a2000000000000000000000000000000000b65c0226743b573dad7ff25bf1885e3dec686cfd5da2862ab300fde4fc8fa9b587d0f2d11ebe1f6a6770bcaf2588f8f5160286a6d23c30595809dab6ee6523d7d235114d1b295087e024b4f6ffc80e50000000000000000000000000000000012d4f299998aa897db9e3194244fdd1dfb95225e3271383b5cc296bbc51c4e1af52e849d8244f82421cd198158918d8900000000000000000000000000000000110638a2f7cdb7104de8fffe29be32610063bc656e13168921501e1614f282bdc9fccff4eb3c479a42b240a2c8014864000000000000000000000000000000000b0adbcbaedbedd376efd20a417bcce562b87b7449cac1e90d44eb05930e6f558b35ef755457305da012a231b5675bc2000000000000000000000000000000000db6fa926c7e02f633730569732fd9239bbacf2042599e79a4bee76619872901c6f4ec4d4fbf3f84143a0d17b167130ebbca29b94b6583d46753473143d13a7aadb0b18d6d35d7423b8a004991fa1ce500000000000000000000000000000000166578f3087772545c0f47fe0b3efe32874d26463e4f262be65a3bb6b0fad7d0f779808f69362f3fe63c72f24ed03d70000000000000000000000000000000000a8e61e8193228fa1825cf14e94f68a5eecece9afb48b44871c5ad62510ee1fc4e9c60d5f2529b8685e6aa13ec91979b0000000000000000000000000000000008d25d81bc4bc92508c8cade33c305c11d71a06bd46f184b05dc406f0939f0e0967b02f15b4f7f6984c9fba0644ca8e800000000000000000000000000000000113660a7d2152346500a1578641aad4dac2919ce63d01d8ffa6dad72f524c888fc2e9d2876859859e47d8e884f170f86607c80069dab2a16e39370de32df20534aca46565cf573159a93c64f1f0c4a1a00000000000000000000000000000000160529ff217934c85cbaa8b347151539e252dbb502c015e8e45c128df2b8a737866737d5cf0eca6f76e4a16790cd02a200000000000000000000000000000000127f7b0e4f9351836db9c204386a199293955471dbcd7b4ee9186f0434b46dcacd1edc02fb46b4c377c4e62cec10cd6700000000000000000000000000000000094abac17b11600d7447f7ad0f21d98c14e439c4a4a6572b00c90e14d9fc54e85045d0576f74b054d384179afc0a70c80000000000000000000000000000000017165c32410a498add8e1dd55ae43f94be234ba3859fc6b4816d7436746add313f42b1fb49e0cb6c4b7341f0acd09db841c1f256e866d218b3ec20c132446945177d518573ae3f0e739ebcc8821bfbc700000000000000000000000000000000060e503ee1c5d3eae4bc0eb30fd86303a5c48c10cc7b4736d17b8774c78a8c97ee05b40d366b2cc9bc7781b1e4a192f200000000000000000000000000000000034e7012414edfc6a8f7b2c6049236b6fb77eb94b05d55b218851fc1e553514e6ad388fac08a24c33bea63ddabdfd8720000000000000000000000000000000004c832477a90683d417a00a698b69c643d6dbf82f5afbb83eb3946f8098d80de6f2d457c0a06d0051315f06e93b5e13b00000000000000000000000000000000048c3339996948974f2bac14d8a6b8430897644ec8e9cff9eb369557003aa2827a4f3fc3444c4df73663ebc9325ff317c72a47e2267010c532d676ee3c3ebfb2be2b7569f6f7a22f76733d7773ed383c00000000000000000000000000000000082466944ee7c62788b6fa77816094ea623d03c7aa2af249cfbfbf78eed26a76cff8c23c2295aac7ee1ef8dc84630003000000000000000000000000000000000a8f88adecc3f50d8eb329492f2c031e722f36627cb3b21415781156ef44954c5b8529ceed5978a37ae1248909d38b5d000000000000000000000000000000000e08f628aa014152b50a85bb6eb947d53c596d82c0d03594ed3b64c486b8630c880adf43fb1575b02e4eb8174a04034c000000000000000000000000000000000776844f28958d3e12a5c163dbd039e50df44b1c6215429381790175a609a339621475a5b9a06c3276c9177d2dd2b576c52f48e84a68d99124e678dabaf376c956dbe9603974283a9efc7c27e830e9590000000000000000000000000000000004477f153c0510d8e50bfdc2db69182c05d5ae9b94bb1880de239733e380e03d50001378432312b24b5bf0952c38396c0000000000000000000000000000000016663990dbe529a5658f2b3044bbd390ad430adaeffbd5306f758d86bd5422391bfa1d21e88c63300faad55e6a2d1d3200000000000000000000000000000000188f701658558033ce2c41101a611f74ad6d3cd075c195476bd2cd59a1a9dcfe937020737250fe418b4de435f8b3a0380000000000000000000000000000000013f8d3625309767841603329f56686a99e196d697802cfcf31f8b48f9c76f77a321276a0158a22b94e91d6907f6ff451e4fe662495bffd8ace4c1ddb39e612b361bf90a0f1bdf6c7fde2bcf63df1bbd2000000000000000000000000000000000f184d22f3c0431b031ee0ee7ae9598ffb511a2a56f5c9f15c9a4b0c53af2a10d22a311805786e303e234239326dd74b000000000000000000000000000000001062725b8c576e79e314f6a56ef9c41f05a65d7d0d57d8414e2ae9cb1a520b16ede7e418d3a9413c9c1660dd7508d5860000000000000000000000000000000012ef02fbe96f9a191804b6c4a0b65b6024e3e2b1f8cff986f5a950cde9a32ad50d4f7a72804b2d18b93250a63a7ae97800000000000000000000000000000000000b3b0333d61fc46653a7172f5a813d13ff5a48056f9689c78c4b18b8aa3afaeb7cec305d98dd600786351338a2185a651e67e96f64b80f4978fdc1cac90be538774e34c2f619f8b8e60cd2aa20f2690000000000000000000000000000000010c91e1dda48dc528f618f01abbe01db1a7b6dcb0d47b83c7b7db3331f7156f7b2d0f081458241467b0078935a7b4a4c0000000000000000000000000000000006f87f782979d2adc02e65b56a4906e50430cb4e0913636e9aa0364535c9d7ecd3b9433358e00caa8e90e84b7705bdfe0000000000000000000000000000000004635089c7706cfdb5a22ef643d1a9a5021847646ef01ea559d1b655299b65cd76a73b04149adbac612e7aa756cf30060000000000000000000000000000000002d83d82bc9fd66c558e00547a8c25633899584c9b855195c00eb3c8742d22c601982f244a03f8e0c5c21caee24405481a6ecd3db89a7f07344b5728efffd35a11f7380c740669f746fdf565905a1ca0000000000000000000000000000000000848f10eeba8ef9c7fd0e679767f6b6a2392922092916da8f13573661f84ec97c65717e55c65526cedd59dc1e096f0840000000000000000000000000000000013781974518487de12661bedfca5fe72205c51cab461b5757ff14f319d081e7845cf8e099892ea85470039713e8e48cd0000000000000000000000000000000004cc1a27d1aa88484fed40ceef72e6bd201e5ee276b5ec27624286dee112ece767b37c6f1f7846d71cc0f4042f04dc170000000000000000000000000000000004f7335d6a1463976d9fd86e2baa45d08ec65059b14449ebe4aae99971c5666cdc6e40cf0510ae99dbce97ae8b4598067db5ef4c1c174c2e5ffe5555f54f4e845c463bb5105381fb39eddc01103b1bf70000000000000000000000000000000003c1b1e0848bbe37e62f1ebacef1a574400d5048f1e09d935af2052da29140dc4074175e4d6ceb7c2c071331b2f3d1d3000000000000000000000000000000000e1c84d6b20553ddc5ab09049ec488ea2839c5818e31455a7b231cd0455e2945aefcbdc6c1979821a80bb4f77d46e91e00000000000000000000000000000000199ebb31e8800395a9c2e103c9340444c97004186929b52de33cb8d9396e7ab8d5af3fe6035d4463701ea41e341f577300000000000000000000000000000000081b3882bfdf83e67d2dc42b211069a4e93c0f173263f9f20579128391e7f2de70335df949b9c0e9b834b6e574f2f8cc14018f14c50d40d3324952ec22ed247c13c4cf10eacd32c3671757bd12b041e60000000000000000000000000000000018aa45c6b3898a5fa618f87f9a08a7234c1b94fbe38e2297a1f9c7a2e9de0ed83023deebd56560b1928c012c14dd7a860000000000000000000000000000000009ab80da6c519aee8aa1fa68c35bd0fac78b55f88d861e8fcd445f629054325d63cc4241f61e5596dad0d54c94511e4c00000000000000000000000000000000105f8253f37f5538a2c25587fd33ea61fdc744a7cdf4ff23a55e2c66a39040d4de5eeacb7e11c0d2a483d59e7c3186aa000000000000000000000000000000000f6b10cd6522a1e34c87c702f58a07858cb753d67da9625155bd433020775351a9ec4ff879f91a43f63be1c969afe675ed4a28dc3acaf2220ba56d026b292a7d017bcbe358dedc57556cf638517bbb14000000000000000000000000000000001618dd5de43a6bcde91a6a03fcd88fe59d1c8c51d3d85cd44a1920dabd2608a0b17a987b76eb8f5b20c7f1dc0abb383e00000000000000000000000000000000198034b7ab8fb8ff267a52a9423da95bc587eef8684f18639df5db44e50bae7fdea5c5e5ef37ff14937f86cc948a34e500000000000000000000000000000000106d1f017da463176bdf55e3ada78ce70da4486be42dd0095e3a8a0f6e59ed503324565b717b45ee38d90dd3ad13c10600000000000000000000000000000000112d425765fa2fc28486b95e49db63346188fc5a6bd0b7dffa4430dc82703eb44d98d726edfa4a275aa5db5028d01ef530fb17a38b7d0888eb02394eed26406bce9e92779251bdbcb432153a550c0850000000000000000000000000000000001326581ac1a1a960db1ff2e8b89b1debaae46d1e2d0aa6ffc6c7398f207abb699ac59186ae7222b5cae3abe64cb61c93000000000000000000000000000000000218753594c63ebe5fe503aab4dbe1e944b24138948542c7c43d92ccfeba5854b7bf1bbcf8078d85fb0b8701b8b092fa000000000000000000000000000000000c3ce8c17f75e78a8c9980e9fe125290d377a32ac46411876ef011e169e86e1458ac5e71cb4a446f6c640cceb8d5617300000000000000000000000000000000176966eac1e20586ad2a03b4a1598b4db1d7c66be70b1b22833e4afe0e0b3783572f791ddcd4eb70a88f4acc28b6fc7a980b5873a5d0f78c3b8582581349498fa997fe3c6b1abe0edaed594253359d8700000000000000000000000000000000099ac8430fa411e74082cf3282f9a456d3826a7df4f91ecf621e645a1abc057e1bcfaf9ee73f149bc447cf4230f2f6c90000000000000000000000000000000004e93d7fedc9e2d7423c9e111b4674a2bd83de28dcbbcc54ce4b324c96318a11603fc9ea385f1c02364ab1f6b5458481000000000000000000000000000000000bbb29d70fba5b12fadb02a24bfe3f6a5362c71fe5f964dcd0e01442781d0462a873501029192858027d612a8572e9d30000000000000000000000000000000010daa9960005562ca2d18eaf4b4bf081f194fa824cc77515c81b2c836627f21b732448f367e2cc1830ad0fa4ceb928e1619f5719c320320a3c45dcd6207575e0d8527c458c56d3decf1d12ead8a985a1", "Expected": "0000000000000000000000000000000002a61fead6801f41f2f27603cf34cfb4b917f2f85cba1f9c684995227653c9dde559e1e8497234fba9b2e4c119cbd9ec000000000000000000000000000000000085f73b8e835a10bcb9312931eb08d916d2b93a1da843fa2f4530cdb26e93b5dc95a555dbe8e50ca465b162661ce1d3000000000000000000000000000000001442fff9019b5476c217ff725ad95c92c17b42471ed7bcc121e8a0506755ec279d4e56d770a322d56f56bc6a6b0a41160000000000000000000000000000000017e7710c4639d51c4a79c5a2791101b52742df202b1827192872f168bd21020bd068160a587fc501782c1301c231a0d3", "Name": "matter_g2_multiexp_42", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001213b5d5704c454845824994769c8b300676e75bafdeb95202001161aede276ab7967ea7362d38e97ca1484cf9c342fd0000000000000000000000000000000008c7c1fa04bebe5a1fb8678370563db63e7a10b30747c2ddeb4aabd4fc0ec93220d578b8110c6bfe8a3a6ea2820f0db8000000000000000000000000000000000c4061a295120a00de52300ee625ac46566464e6702489467316e8c182ca2168052c50b5962ff47285866c17d213fc8400000000000000000000000000000000086c153169a9ed1aba10a6cbebff4911b37907d6398c441ad47da17988d512d822ee36f5217355b93c9d6dd8dcbc8e0b119d33d32affaadbf6c2b6243bb7b344a971270b488cf887334fcb15de2818cc0000000000000000000000000000000017929edde8f9940826ed739bc9f59099ce76e85950698ab0140784647023f96afa064aa4a49b9728f496515a0a807e5900000000000000000000000000000000198d98f430384c1e7fa9e2403d9c3d2f81873fb7b204378cec95b97e674e10a1a43af97db0488209904469989ce80a0a000000000000000000000000000000000afc9b5138999bcef35613e38bff4f81cf532e00346f5205405470b2424622826c746ddf0369c7bdf77467dcea5cff290000000000000000000000000000000019ccc05724b3e9966bf918f01312c80e8422b697be89365b6ca00eb31b0bd08fae942e90a75bf9da1b3d264e416060f1f1d832b355d7e0ac3653431528ad0a8f6819daaa19292a00c910ff0ff39f46d5000000000000000000000000000000001568e52c2760d895874527d1ac8597730578176bdcfc67aaf69ccda253f6616230811dac59bc27cc1e57b94b5743cb3f000000000000000000000000000000000a4ddeb8b56f105ed5f47a538052f3d38a23c0ceaa2dea241554e6508f82f47d32415ffeeafe5ae5664c936b78e07648000000000000000000000000000000000b3b335a390aa0090bfd6467d6cd02eea1ced347cdce3c9ed85dd46e38e9f2ae9642392c2875a27618ba8f2c555d5b190000000000000000000000000000000012baa4b29d116eec749353b7658af70d4d216189133db707e56068c8483af43ba86583862e6b39df13b88058536861b9e6dcfa50f6129544835b5a4568954264ea68d9e2e5d4370ee31026997a3fbfe90000000000000000000000000000000001888b83ca28c244a6178377b4ee6844dc916e28c3f56312ecc0e29d08e6254dcda39a36ccdc317d1908303db3c028dd000000000000000000000000000000000f4b73d9316fee42d60f8de402a7d07765508b84d8f2c1be1f3f9e802ed7b0c6c5fece3db95d5287225026e73de98ea4000000000000000000000000000000000f1b48122191e1bc421881de831293a80566b9a7f2c9836f7718afb69592d59d2a714cfddf88945b94fac7a50b743eee000000000000000000000000000000000f1c6b052dbd03795433d7ad122473f109484d50245021c8727d252145e7db7dadc015265d1547f9c748409d74f5aa33f7822767391d3b2331e8e1b81c659c6e0262f7355063decedabac9797a84f0f400000000000000000000000000000000011e8613c3a771a177b4b85f0c6f97a53fd7900cc23566aecbf115058d2863189c21be36dd5dd736f6d0ffbe88182b400000000000000000000000000000000017b2c4e8d8aad0a12fd7130789188bb63a08f2b243c8f7700599dd33d7e176f70f2b1818e56540ab3fa507878d96a46e000000000000000000000000000000000e2b5ad5ed3578dfdffa414a4a2142846b1232cd2de468725283e3f92b536d8ede74bacc236993f6f68a16fc6a7828d3000000000000000000000000000000000fdbf06ae4cfedc462f5913bba9bba2b5c86ecd0e298bf27a21317fe74af6ab15014c62cbfb617356548cf808599caf4b1ba1cd6a4a6c433624dec63547119c0d492e3f38afb04e5153d82e400631aef000000000000000000000000000000000b48aebc6525620b99cd83979658a35afa233d17849bd0dcabffcf3b550f875a386b6c0b4ddacf18a23843629072c0150000000000000000000000000000000010432e5abf862d3be10ac5677b9f296ccdcedf1480e45de631b6bfec42f20edf62034f7205f659f11fe5a6aa9d882c7a00000000000000000000000000000000011702a3590e7aedd6948bb94bcc874e0b8d77a18126ed4ba3753dc98953ff941495486c14c6d801c71fca3564ded9910000000000000000000000000000000009faa427c0a7da26c92b451c61f5b5e8804fe032a4cfa014397e430882cbfcff81bb22f9c15a8747ef455773c1ef65b0a41e184bcaa0721caa4114d6393ae2251fed84aef57c7927a170145308bb136700000000000000000000000000000000061a1ee841251bad461f89c52196bebb1cb4463298e88abd62cccd21bbd325ddb33d1306ffedb2734be76c18d80c8dfe000000000000000000000000000000000d05a5ce6372ce34b0bf4b19d8e05aab74abc1cedcc35a2d1d4db38813d1e5c1375d63ca0e8bbf29c510a4319d2aec27000000000000000000000000000000000dfc57aa8de28745b8d28db3769ab5ea26b5115d3e59e51ff19af8ba37efacdccf763ce682cfdc77685705781c3924870000000000000000000000000000000018c17d87411c4f8e0ca51b3eb4c3765d3846e0d1b75574f8e511b2f3e8c5ff53bf7618959ce18dfd9e4c6285e88f094f63cb451d8eb3565274793925a1869ca5a25fb19639449c71a761809f785568de000000000000000000000000000000000a0642094b89dc9c6c7c11c1e57ed542982bd246112884969d424a3e091ec4fd73dd40a5ac116f6c68216fd1e733cdc7000000000000000000000000000000000788c7a63eecd1cbc26ee6b14b09d0a3b7a17a848fc0551d50cb7497bc98287da2d9b898260eb678a8a0f446eef5c6670000000000000000000000000000000017a1298f90022ddff3fbbcca180e3f4da8760218dba595a067287a2473a6e10b93dcd54154cb64b6c078b083b42cd09000000000000000000000000000000000116e999b808dcaea0566c0fbef1807e160612dce91756b2cbcf4883b04a90320a0759bba21b41e6f4d8449b52e52f9a96a2f94d55f784ebfc6b6260327372217d6a5b9637ea5f9afc1a65f99c221c29f00000000000000000000000000000000064c95bc9c0e2be48849a349f16713791c37310f71b5d0613cf0706febeea3a56a0f0f1ac6b504524eba801e8b759f2900000000000000000000000000000000007088d2f41fc7e1147b92a2ee7062b9bec194d3a47eb9985ac1ceeef57e1a006571e7247a13dc95afcf9905be57e2a7000000000000000000000000000000000e6a0770f4315acd9e410fe58395ab8b20a08240a6948b762dfbbad3414bfca0ced4ec9da982bc9b8798b60dde78a96c000000000000000000000000000000000a70b53a6d71c83971167afe329ffacdd417bd7b228766851c3b43701a439f253a8659312db7e83a398142fe19332b527d889a3362f551b88e63463b7f0cc334fab3fdd302b630e419e362ec1eaaeec000000000000000000000000000000000002486eaf9b743d3aa6a1f3e1174c5f213bbf3e3cc0558d63ce40e3c03e1c2f6e8508248bb649aae1bc92f3eb8118a2000000000000000000000000000000000042b03959b40eb0641d39117f7af50dc7ff048697a57b80723aaca164e2dbc647ffe78fea0a6a4c07671f7db6d5b2dfa000000000000000000000000000000000e141eab29f52b9bd0ee44861f154ec1bd30abd715935a7958a19007e789a41cdb0f4b9cf7b3fac0b0d4d77637b510d00000000000000000000000000000000002cc2eaf89cb7a04d425d878a30b5e2e9858ae0b2a2ab28fb28a6db0c7283ad861bb6a92067e969e5721b43466e857db8bdd400ad873cd6ec546bff698171942d536b94e69dfef4bbf316a471d4b45cd000000000000000000000000000000000e0f7595e4c136b4d8bbd1eeb021df7dd2bcf1d9f98e4fa293f7edab635e019af87c138275fefacd806213177af40eca0000000000000000000000000000000005dc209d6c86f1871637998c10490a70371f9e00a68d1363dfaeb62046473dfb4bbd3b18b943439f75c45a1ee7f264a90000000000000000000000000000000003d215567d1e8f504a72658d48fa51374ac77234552c17db4033af780133d8516bb0769678ecb50b8b9eb950c2dd73e80000000000000000000000000000000004d780849b731012e1e5732d5f6d32c659a95c3e1c8f5ef4841fe82afc6f0aa309b1e02dc2554a4a4ee781be2be2149f63b496a64cfd15410192aee9912f869deea5a08eebd6b160667e12fdf23c44510000000000000000000000000000000007ecfb753be501d9f9b7ae7ceaabaa4fcb7b690ee04fa1a711a15dcf67e4422adef64a0f8118f93e67f24a2d1a2bcb36000000000000000000000000000000000a459e403d85972f7132641c05bb842416a7135009ff46b617bf0918e65cbbf33f76b98c10d901936e589bdf5de31ea4000000000000000000000000000000000bc6ec31a3ff92b4fae07cb73ad7bfa8423044048337b0ab9add09bf10fdf190a5f7996d157483d29fb29a681ed585520000000000000000000000000000000004c622e2bc606fefc8bd83c4a32f7353123205a6d3716b581c2c71360e5200ab069f60c256dfcb04b466c53cd61fc94470de38cb4627f53509eadb0918e562c6fa68a4cbdfa9f7578a8aaa8182f5315000000000000000000000000000000000125688e44f593c5f585765f30e9fee5e4f15247cf33ac78ed1744453385f49ac61128e23b1569ea33d74b207a5e72e930000000000000000000000000000000009d77360ea37298fe971569230159967012c4991255fb5337ca6d58cecc3cd44a024a9a044ac98a894cc97dea161844e00000000000000000000000000000000056b2dd9569f0698c732367cfb217af90a3d6dc15e2555ce0aa845616e4067a7fefb304f6525b539555a0a685f0ec5f20000000000000000000000000000000009acb138abacac351e03f7589d4bf29cbd331e93bf538578ca9466b759ea070931c786d35f74fad42261e2df431fd00316732c583e8049a5de38642cebab774d90d5f87601e3599ffc9af692ba532e620000000000000000000000000000000013515b0022ea946a8e679b9c0eac6cd67dbc4efc820f0b3d8984f12b7d154c0632a8d7207747284d49c498c79b6bb5c60000000000000000000000000000000004d6765ec6aa8744225c1e652ccddccc91fff7fa8182931c8648b3d8bd33b2177a9af03b2906da02bf117bea59aed3040000000000000000000000000000000006f1d858c4b223552f0aee466cff35d14b3ac6da35b8f482417e8f597514b065be315aec6662ea5c7784d3a9e2184090000000000000000000000000000000000345eaf0d72b9c11fe72261a2fddea318a8dab92a67ccb9438c11e61fd298a333cc42084d4ca127e09792e346cfe0f004a037e7562adfbad6b1ac48b8e4b6f277a788ea2f4416ed2900ed2791f09bc2400000000000000000000000000000000029ad10ed6d6d5bb591771cbd597a3a0b841c2347c89027126bfd1efee2ac403933beb99d08721232ab9b7354fcf9aa800000000000000000000000000000000198400d4e026c2463a07ba5a3974c869ed8ceb1f029bfc7f41b23dd7076cf4a83b17c27ad6506c852cd2cf7c4987f93100000000000000000000000000000000152bbf74cefb77fae8e825443e4ce09b4e223242187f563a236695294d0a5f540f0b29d6f93a54cf0a77900e936e61e000000000000000000000000000000000079f4759eaf044a80417345a1b4029f8d4cfc7e00fc625e815cb7daba2243a97d21e42b42ec968dc8647158fbe467088fa878f6a2e18b88d6badc5b42775e92c17974f3a18817b7769d44ceecac46b89000000000000000000000000000000000cf3148d0c30774104a097562cc83456d5d18643d5f7ad58aedd9327bf8e9450feee50ee893442b1cde87acb02b62045000000000000000000000000000000000011d4037dcc15d0c50337d71816a2b77428b8ddd530bc3b3c8550606229f88286ae94ba03578cbb5bbaf118916dddc90000000000000000000000000000000016160c8ec4e2fb780748aac279bc248b2e2f1092262f86d368d2f06a78ebcd27e929930c8f2be124e9d92dff5c6c6f42000000000000000000000000000000001980375281735390f48ddac9d00d4c6ee7312ed0797333a26a1684e09c9575e57bcecfc4a31b8d9597a8ecc703835e22c4f1a7d2b66e6202c957a649384cb277dbba769afd60708b457613f0f3372515", "Expected": "0000000000000000000000000000000019ff32d2901b7732df1a924eb3c099a9d36bf36cb32ab322f46a72d99d81c7942d0f2193a4aeb55cf079a2cc1707c7aa000000000000000000000000000000000193561d0433e1031fc51829504ca70e92e19bead2e0bad655aaffb6b41f5f75d18f04a162db7714f3f23da891ea91af000000000000000000000000000000000d010c36acbfb38d9dc2df6e6e21bd75deba5708fb1012eab23d06d78b1244d4daae38aa4f803d12441d91adfbaece7a000000000000000000000000000000001459ebfe65c3b2c9b2684042bd71201869db1a0248c740a54fbdafcf18fcdbcc7b677af43abe803362b462369237690c", "Name": "matter_g2_multiexp_43", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005b9860b565fc64146020647d1902e2a2d2fb2002b54bf5e21b6601124edf14d6e8836f938843fbd8c02ed8530953dac00000000000000000000000000000000104938181f16f16318d223febec3be3877bc57067fc23729d1f5552099125558cb21ee0eddc32ae0b0cc3555219eedba000000000000000000000000000000000211f809b624c4992a43e78a978ea32accf9e61fccef6bcd05155e52adbf4853340dfacebec9fa87e5417c045da25f9a0000000000000000000000000000000019bfe94a18da9ab4ea744389c17870ac96218d02178bf2ad502f166a3a1da8c14e3fc52038021503cd24042cde8f306d0241da9d8505208b4d3ba2521a42f28df7d06fc212e9e84931cbd30ae3ba2e150000000000000000000000000000000004fbb396eac2a1de9953febed9fb6e158a3b5a366f783d2105b562e8143031d7a1ef039e3fdcdb675b3d3aa4f4dcbe4f00000000000000000000000000000000155e23b5b70f1ce34fc229ad5c8bdfde7fb5dc0eca19596c658c1f8c38716a0a7b5ff59ff19a7a67e12760fa90eeafcd0000000000000000000000000000000002cc82cf87e7ac05be236104c1e668b5573674d9bd741f2d91d05c8a11af1f72aaa1dc20c73953fea38e6e069d2a43de000000000000000000000000000000000a7d1dcab00db0e7c0a239511d630526fb120defcd9453fbb57ee328f974a98721274144e48d22558edf25595b8ff4cc6fecab1334668102e47f1e7139059c1d715a1851a026a1580f93c2daa3f08a270000000000000000000000000000000010c9293b3c58d646a95c620a0e0a7a0a55cf43b4abaa0de1d5570fabca8d97c91afd67bd45aa234273715457da5a2894000000000000000000000000000000001454f8682f3736847cdb3f784a098f7c9e488629efc3820d49b36a2e928bbf736dcb3e1b30187c2c0090fff290dbf97f000000000000000000000000000000000a0fe3c635a81f20258db4f1031589afc8c7fd07f2fe1e5cfc8f3c40d08a958a3dbec537c51be2de99b849e006870b6c000000000000000000000000000000000728876e3fdc42273e8d71953de61dd5c03e7c31ab6ec56fc03cdf55c8f0aa4b4e5c8ed88c23c28568be0d864df026af4e2023c64a3b51cc3d82e262f83260ed4a5e9e3238b85077852fd501b52aceed000000000000000000000000000000000c9ba542189ec1828c397ace9639cf2ebbd1613356d8fb26d3c40dd00af1f43f5bbb25032561aeebba7b874bf39cb0d500000000000000000000000000000000175aa6e94a9e42cf809f48f51c48d60e74d61388dd217b55f3f63612c4565357581e5c39751a65afc3b7488caf5151720000000000000000000000000000000014c880d35d1d31793145803182584a8da003b0ee3c29c978b64bbfe4e1da82910a4539587ba350d393e1bf3169c5e4c70000000000000000000000000000000002a063b3fcd77180de632deca1ba89ec4ceeefefe9883ed9e7e06301a268bdf377c3a6e30859e5a39419e449dd27ebf5dc0a88f0aeb2b082dea6b50d591018330c2276830ed554840c10772403561ed700000000000000000000000000000000069edfb8a83760e09726f6d1c117d4bb3e499084b65e1e830ab30daf1625c37f851ac122f9f5c795912b5b6f7907ffe1000000000000000000000000000000000eb6e9b55869f65ecdf3ac46d0ee596d07c573f88724bcd802b4429392b9a56730a217a03286deb5103f70aba7a9bc46000000000000000000000000000000000e2803e1a646bd70c51806b676591b328cb20359aadc8e79d59e7c31e1ce2f1473b0b19f7a34f23aae09678b11b37432000000000000000000000000000000000b3c9fb5a39a6c40343259e12ff4fe5058f25619d145922e1d80c3f5d105a7495dd9a4da329a2e78afc31a87b2c5d5e2f68c9e76d9d8914f14007c968a31089041e67312c6a3e5d30e65efa55894ba740000000000000000000000000000000019da372143e30307a71c7b96ae0703301ed723814a35e270ef6a6b0c57144f494df1d3fa0ac369f59f3daf534070c9120000000000000000000000000000000006521d89d810c7542108de26bbc888482a3bcec8cb9b542db42d5d4af30d6c339a5b4e959da4f98dd6ef8075554f4017000000000000000000000000000000001387d9c684a0fbf615e7023c0f3ff47f4d2c5a9f748f0261656a09b23066c745420df0eb180c9716d6d0743aae7689a10000000000000000000000000000000014271b9d0b21cc69072333a6c03493321b9d9028149d24964a3773bcbe5045875c457aee11ab0682c2bdd44f098f363d80eb90c6cc25b3a48d93b94b698eff513da37210ba79d22d76a270aa97fd51070000000000000000000000000000000001dd881f3d2063adcc5638b4b3813a30e75fd308de3c9f42e5382fdbf097d5796ee9e03cb44752515b2459f131f58bb90000000000000000000000000000000010f491f4594dab938115343edb47b0087d1cd1bc12ef908e150ecbdb3a54d8dd51ab24a0e10c585f235ed99fbd3172270000000000000000000000000000000019d1665d452ce7fb6bb6da9782a55dcf12a1d9abdfd50435b8f2a1bc5b323c004fad35ff7e9aedfd414a9b68fb1eb1860000000000000000000000000000000013828087beeeb85e43e8540fbdf97af189878f5ddc1eb35c95aa06a26923330f3b8a2b43f835186865d6f5f6afdb2b9b067bfd893b12c79e13659ee9b5f22de71d806a85410c9a23dc43363915a606b100000000000000000000000000000000014964f3576b97c00a8c5f4372e2501944a1e4374a3c30e11376ea62e09d52d40d428887833bc2f06279b859c00c98a60000000000000000000000000000000019ed533a3bf469ce5b3e4e9035af177efe9e4f8b0a0e5dc9721dde49a7fc66fa31c8b1c8d5bcda1bf75a532bd2be356d00000000000000000000000000000000064ec4ed48d63ab62373adb7898bc904d246bf2b3790c3cd850524e50ec38e7fb4a364344a6a1dbd26f2ad2d0fccaa1600000000000000000000000000000000134aa3c6b72d39bedd8f9c619d206a295cbc05c611147d38aa7304e995089ce34ab1fa13c2d6c6807a88797dea20214b34abb11f7ed6d73fb81ce2777acd6bbe8839112c527ef4ad88b094cabdb4742a000000000000000000000000000000000a2a4c8b457d0d2554a2d439fd3b74b18843386aaa00d1b89a1c2d8ff7192cdd1d3a888994376bb7ddda4d16bfcaae3200000000000000000000000000000000155a7dc763caf6f0fe1ba9537c0f75d3e455c2d1c749dbb4aa7242b40a9740fe9e8e88af6017e8f743a9e4c5dc6ebc23000000000000000000000000000000000a693da3aee178e2f0489af77f671c734423032f30c0b7b48debd3b71e65dab7db12ab1e0e72d3ef686d6c1922aebbf700000000000000000000000000000000109c3476016884386d6206c94073c628375a02c8fcd3041e06b8b413508188a1d26ec5ddf84a77d059e9a039dc5470d08d6693acb1eb73f6ed1bb4f74f1062f720a7f2c0ecf2b5a944ff89feb2688e19000000000000000000000000000000000a07f457f5dee69e9ee746dd67f982914a2182b5cb2609d273d4122d57a32c195270c956361d78eb65449cf5e13907ba0000000000000000000000000000000011f149ce84c2a11ff818be3ff0f86c1b38a9555e169a8cf791c79828207b7aa89c84e8012a0c5d8cce4e89d758b90e22000000000000000000000000000000000d636e5b027e41809d7ec8bbbfd4bf641a56599a63a7678569404ec8d45c3b88c1d2969e6101528d4edf1ee9d8e793320000000000000000000000000000000011878eefa5ee49be83ea1f7a9cdcd4997ccc59a9669778b3f006429e1a22d3b2a051924f371a228856523e3a09bab59b29ca1b157e6a2b5b88d7467e851282491ed30382ba217b82ea5cc9ca0c6986930000000000000000000000000000000019e9a1950f663b258474b24c334bd256d3aedcd26dc971a745857bf1fe007da0aa00777db5c3e5d21294e99862bf8ea1000000000000000000000000000000000329a12fa0add36f259e401442bbe6e5f9139e4a46d5d091a2110d2561b5629211a1c1996f20d19327d1782340e7ce4200000000000000000000000000000000032782c94c6e45a88425438324f3a24ebf37f0be213424b1be52c878985633950a022f57f8d64af1470486aa3744f3f7000000000000000000000000000000000631556d52fdcee3529023cf20d46ea09ab3c642a7f4eca2878e4af88801d21b80b829c9aec9e73317252639c148676c40bb53575662fa0b726469da01c39df389efde3936d2eee18d7035704130ad6d0000000000000000000000000000000009eb122c61ec44afb56b64929040058a804311e0e97d3fa513a162748091304233480bbc883f6fb66080b563b308a24a0000000000000000000000000000000007d1d810fb8788b9f0cd04235771d7adbbdf8c6e67e8538b2c6f0f278755cc5e57ad720515ca558412ae1fe2cd40b74d000000000000000000000000000000000955496bdcbca8716245a130fe6eef44d13280b2d56f15bfc772f8ca66a52ca0a742e6bc273c28cfc858a3269f59beab0000000000000000000000000000000000b27aaa0d94633912c96f00ecc021773e5cf5e164e20c7a7222a58b0465e7baec4e67fb56ffe564c7a2904f36c265e61574a30a575138c44881c1c126be214c6b68335d7338875b8a398196f27510d70000000000000000000000000000000012e0572f5c84f6082dd05705a3fae738920ffff840c21e444f0ed002df16394afdc21c249b6f1837389c48719539f4c5000000000000000000000000000000000c26bb3ab52e3bddc219dc223daf472247547544e3a9ccc31123b82000b17ef325148935621edd36ced4e702ade1ee3e000000000000000000000000000000000c13a8f02dc3f209e9abf3d316fa843be9c4dd98ce1ca2edecf757bf2bb498750f6d96c28abd45d9c6cf5b8b6334b63600000000000000000000000000000000157a50d9034024dfc7b0f0db4ea0f45323d76c81bc844844ff9bdd0c13f2059066ec3060210aaba61bc074afd7ccaa286dd51553c4119255b31cb0aaad7391694f7dd29420420b513699747bee819a99000000000000000000000000000000001054edb092a7053eebc542f690e03139f2e25a0098c665741e8711c8a6b9582af47e467f74fff9aeea098b7732be72d400000000000000000000000000000000084f919e219de15e7f9ee122383c772415741e5b86be6ee7d2193a4f6be5c9cc9b2fe5e8beba26cd768bf2ea1b6ebffb0000000000000000000000000000000001822b4e8fae5bddbb36f5c226216471862af238be770d33c4fc1ec2777350db2f42e33a7ba468c317a128e8446ceff300000000000000000000000000000000130f704596ddb28ec6e335d9527707a75c97298407ff3fe17d3cba0cde4c21bfcfd1ae46272018c1db768c036f215182d88f049ab3ee2b01af449abce08ca14ea3b065f06a8665ae3510b4c04f42308200000000000000000000000000000000194dde06f8c54de9ab0ad72ba0de2241fef32fba30fd6f5e83fb7750bc120d51c461d75e495cee0d1e85f0f39aa9d3620000000000000000000000000000000010646496be02c658c82dc68eab86a4f784cf64494bd8441f884e8ff384cbb6ff3a4bf5126bbacaa556aafd652397a8a800000000000000000000000000000000109807bd4b6613acb3eb7d386e84166219e52e841c41185a269cc7cfc5f34e9ef5cd1fea29877749e0cef93a3b44eb1600000000000000000000000000000000020a388c668c9339e7aab15d03108317dea97720dd27a94cd3bb59b372b268d1a7d7d7409780bc4912c3f95acd42a57619d6e227185c538b122858ad5ae594720fa7f743f5805552152a213ebea64aeb00000000000000000000000000000000161506c4a2d57c852fe8c3dce63ec6673f05f99c1e032c8e591239616ef4469c4240482ce5985fdfd4a80f54dfa7024f000000000000000000000000000000000486c5b106393e544852c143c5ac4a882c79870363858b2c910ef4041d8803876cc55ef59cd6a41869bf5247f0db2c0a0000000000000000000000000000000000fe765ebf3c4edd3035c7bedd4aec918426898339d7aa004fd74bbf0e3236deeb7d2bbba56c31fd447816e301100a66000000000000000000000000000000001917c9cf16032e22cdd3f87f098a532a33c9fec560a88f9d4232f96cbe0fe945fbae6bcfdd2095cafe6e0b21071d6ec53f53123f01c4d0d4c18dd72ea87ebb5fcb559df255773fa0165f1432c229deb6", "Expected": "0000000000000000000000000000000015a88bcfa39f444cd66d0d7e15c4040561154c59b832c5ca895f8f8077659487581681cc8f13be136a35b4a573551ad00000000000000000000000000000000009fb6b87eba1edb3d1d23e566977eac68e8f1a28386fdca9d484c7e341c1b210390787418e2f2dff7a228e1cf10962d6000000000000000000000000000000000978de870dcd8d094072897707313b9f1a18d525e60a7cba2b2a395ffcc9d0f97f84e0784df36247d6c98824aaf3ec82000000000000000000000000000000000fbc6832c324d40f104bf82c8cda941212105131c26f630af1d3f7040ef43c6eb4486766b75a81433e46966f79953647", "Name": "matter_g2_multiexp_44", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007517a941bec38d0e84d21508d8bdd6778a853d9fb4c5e953bcfe3c8fba3732ca0b7f6cb5c363f33d7718b1b1a68f8e800000000000000000000000000000000150c0d975481422ddec2a58a55b3d917b6b7c0510e75442c81ee856e267d7efa09641c6b79fb9e699c6b473cccde7f4d0000000000000000000000000000000009d37bf938ac30fae1cb3ffaa971ff3746ee4090d4bf8b11dff7710b3f2e4cc686813890e03643fd56fc99e847ae5e940000000000000000000000000000000010fabc4048e0fadad73d0481e290c81884f4578cfb66e0a83324739652ccf273b62204f126696a2fc6469ede39e00a9fcdf2bbbad52a3f5c0b3959d46a8c42f6f5250a93c3dcc636712a4a2baed289c900000000000000000000000000000000089b167ce7fa997ca0ad3f8bbbb358824cb41f525bf60352d5df99402af62cc6d768113d2c1ebc7fe8190c5f732fbfff0000000000000000000000000000000013dcd35865e27bf98f1f6508b32c7e9a989d528df0626228087bda0d8b456af3ea2f4be6732edf1bd8cfd0ab9576197a000000000000000000000000000000000333b0612d7068986d21e1cb67a1c7af423e98cb14aace2ce02f84d32a38f97bcdac465f2b22e5fafa6aaf0d40380e4a0000000000000000000000000000000010de7ba4f50b6654fdecc4fc6c41289bec50cff1be18be9d5c9d1f906ae843189bb43f144aad4d2a2cdebbc2697c974918adf5d8fbdf81f8e4bf2f622e2d481fb2dea06a1aaa289ce4f6e783eb9a98dd000000000000000000000000000000000fdddfceb29fd79c31b138ae8e41507f324abd5e3750da14f4f86176126a06380d53dd5f7efd00e7f94bc1370ac9816a000000000000000000000000000000000d8371c602e393a4be250583c299d069270a344953f7f07a5fe27f8617cbd3ebc91f423dc176b272339bb3bd8a9a348200000000000000000000000000000000193a260a417c9c46da0aaf139e3bbfbaa9f248943048396d95716b3be0b8a148a3f0ebcf7d6f9a318b16d2d850ec2f5c000000000000000000000000000000000be4d0f2bf6d746b930034eea8a19d73377617645c29153b6ae6d3ca6fb35a704b6a0bb658282cf93555c998f6fd054a650e995b73b63d068fd54f596cd9669fc3061f0c1da77ae7d0f5bec012f9ba69000000000000000000000000000000000731c0a5d076d6addb15c1e5d3143d41371f4835d77756418bee452d2f03b1e603230c59f87905fb67d5eccce65a45d20000000000000000000000000000000013bd198c023009190c65686468523eccb57c5fe7b159a1c5ba30c662a275fb24d69338ec9c023ee6a10a8ec9dc7968210000000000000000000000000000000018fb369923ee655839c7d996e264133c49f102978f18261faf2f8eef376eb0bdcb5af375ada2bc783e50df16737f78dc0000000000000000000000000000000009ab8e16e1d0b406adbb37e950bc3820ec13c882ec4483528ebac836726ba202bcf796e84abb3c16dbf6d1131b3854cc3350d4f13e25052b1162dad3ace76e5cda71680fdc89460d8fa88c0d157df426000000000000000000000000000000001401029d7cf8e7d2690a27c01b32008e273b5a33842dcf52d84f77dfa4b2a1fb290f56eb4ccddbb420b27e06a7a3a3b4000000000000000000000000000000000c464c6fdba702f2fbf4232b34d615e66dbb5bdf80233f695e9103272111a06a79f8972d1034176859d0e29400f5a9c10000000000000000000000000000000006cc97a29f4e694f0cdbb099278fa94140b40147f4f911de96a762f2bd28233598a892899a6329cc3cb854b56076787a000000000000000000000000000000000625811cad7c740758388f330c4a56ef30429ea4cdb9a00e2cd1b7f310184a2e6ba36ebdca57c87cebd5232f52c34d92283f0256766690c88df6cf7c968b9a96121d26d19672ce9adc84b699476a32db000000000000000000000000000000000d0a16b5d48eb062c71b91d74a0d25eca0d4bd7082de25199f33a9d3d598d137fbee2ac36e8f877c157be7438ebabd74000000000000000000000000000000000bf93533bf677050d9a77a5dbdbf7cf084b5d934d55318256712ec361693738d48ef27536476fdc93dd8e81f13d67a8e000000000000000000000000000000000696fbd8841e60300602aa5528391aa8b196d8c186d6124c842a0124a8d8dcbba637502f330c980b2f5a900be8e04d020000000000000000000000000000000017b0c51e699d2252f35619520af71775f9dd8c57c2ef146adeb72640bec2ca02a59680153e5c9f66bd513bd8559b9d66145cdeae7fd3f7455dfd2ea9a064c135f0a0a36990ea34929e292e4cdfa0f472000000000000000000000000000000000eee94b5148ccbb3642e582cf0a517b72e6ea019676a13b1484982de7f4be0346b7ed22979ba7303f6367294a3eb2716000000000000000000000000000000001502bb3964f6b3e862279e15fb105073e876c4e48c55c42f3737dc9efed82b10fe8e39438ccd39c933f5ac3c6768497e0000000000000000000000000000000016cd8c4b3be55474aef7081cb969b75ef5e7cca9bd0f9627928fe9931c6f869a9a49d0ae2cfb8346116eb3ced25d4a8e0000000000000000000000000000000012456eceaf32cbb6514e6211136475a750889caea18ff4f9d5ed7b378e6d1d265721a646715aee6b9f2098e954a88289d9cdaa979ab08b454dcb961e3cc4bb18f706bed93a72a9c1e105cd69c0b691af0000000000000000000000000000000007b5633f4a7dfe62f11065d44581f5060210f8e572d960eb85ffd0a903d8b989ce10449fc90b7e5646784a9f6df28699000000000000000000000000000000001710f252cb35d88f6bd151ed596f2d6455f050c5e25add394dbaf60fc036016ae07a5a8ed494b95875c02df3c523186a000000000000000000000000000000000bee19779dc6430ebee993f82a054fbd42e5b7265090017e5b2d2f1469bc96a5a188adf471d576a416f6a841081043df00000000000000000000000000000000038f9fb4159e4e6f596a17ddf45a00a9e4aede63b062af5eda045efacd3977e8dfd61c307834c08bb4c284638696e92ef262f9f7a26353193939bfbbdc50ee35614a3c099776f08b21e0c4c97521eb8e00000000000000000000000000000000197687895f22c4a639bcf2f494dd9e5a034610b0297528235f1d806cf032f5a86c5248a83ed6b12f0de27f5c6e6f49420000000000000000000000000000000011ccd5dd6d6ce553ade9b31503a9e6a6119ae329178706f051581e3cf0ee9d6fb527b340bab8c79fad1cd451c7edb4330000000000000000000000000000000011e9f051aacd69c8bfd2f0ecb566e6d38eabc43f276ba7a1b8e8ab093917dd1c672c61d6dac4651026823b9938d3601f000000000000000000000000000000001362c3b2e6fd9b3618df26ed28f96530c1915f0a4ecb647658d1ae4ccf4c000f3bd1797696c9ac5c5000dbe58dba8de44f0d2915e82c9a69f9e9af64a2c5cacf61ead492bf69912a35ad6a316f9914a8000000000000000000000000000000001819d13cf4522a9362bbeb0bbbb0a498c3f34da1c9e3b2c54d08f7c8acd9ee756983fe80405579effb79d673407390ef000000000000000000000000000000000f870e5978f4a6e3b655fb2a05541ac0673e7b10136adaf28be4dfc9022d4cc8a60e17d125dfe53fbe10c644ff37e02a0000000000000000000000000000000010207ef774cddd10db2bca0a051ceb12900c407ee265dea4615553c193d7475b5ba3198b7e0160740e4fd015dca33e1d0000000000000000000000000000000017937be546e06fd2eab4c969a029534c02fb770646d43edeb5e6c8bc0c2b5f35576c375bf860fd1087ce099d4377d24e25ed3f13198b69604c08b414562f67a67aa8dd4a7bd3c066874182d21ed9004d000000000000000000000000000000000db02fcda340fb27a3fd7da468c5cbed9c8dce8471843a8ddadae43dbec9957a0479aa52855d7a6dca99e7922432365c00000000000000000000000000000000163503d24f9af34058cb5afd8e9d5aaf29e141c8521eaac282f138466e834f0daa9ce14e0590b501680d5b47f866aa8c000000000000000000000000000000000fc9175e6d20afd9d194907f2eb311bf8134aeb96da72f6423610612f2ed20a074c113fe8bb632d9ad74b2f6e7e2417d000000000000000000000000000000000b4621f5e4465629648b62b7f2b77afe6470f9706f9bee5b3ccfa66c596842cbae26badc689f7f623360cb7fc1d416b84ae188cc115e9d492be64abefa4bd4c93b61dd42a7d213e1100b8108611a61630000000000000000000000000000000003c77c7efdab9a9e71283b034ef581a31faee417febfa99be3c18e8ab724c140be684ce719bc5a9ac5d3855ddbf3651a0000000000000000000000000000000011889b02b4a1150fc2b7191a95c5ee767f3c9b82a3a53591018242fa8685ee3b3542526dfdc00695a6cf046033b8eb760000000000000000000000000000000016d7463159c4e3cb635f24bfb944bc518369e894218bc49d7b7f0ea99240259f7ee2b4c26c6083dbc4559ffcfbd392bd0000000000000000000000000000000010a85df6294fd6406ca651f15494153e9802f0068bfa149e87fe4b1cc3071ba74940a21dfd55a8a77e7e2a193468a3d2eede725a693277356ce71ffd7814a77fcc30eeb3a2b8863fb91ca03da1cbe37a0000000000000000000000000000000016beec57d3049c382fc039ac96b890412c5e8075afcab599fb877f8639747a587e82241d9a8059a0bb45ad49959777d0000000000000000000000000000000000a70fba1b061dcf587f133035a3aaafcdace3b1e771d71887ae914919e5f52a99d9933307ec15b5f0a1623b9592824500000000000000000000000000000000005064161136c04f9f50e42a5cee5dce3fa0ce1dc0655b3785a852cb9741927f6c9b357ac1010d7212533d1593c83dba70000000000000000000000000000000000d50b992bc0eee37a15cfd32eda2c591fc4c4203ef84232d1a1e7a9888005bc00755d76b9d0345bb01ffa7525f2aa1e9d0618f898594b23ee3754fe390d6bdfa7d47fe749d6819e306935c1eab6b0460000000000000000000000000000000007617e60d8f67344ce6d2fb65cfd5b423a1fd091626da837dc8a51d6ffdeda9712864e8f30e45ae8df917e0e4625e59a00000000000000000000000000000000077c4aad14f870ba24703397ff0b33af2e50b026f3e0f13f3ec1aebc9ea3af98cc65ab56cce4045538ae6e5f410196f10000000000000000000000000000000004a31d0eff18afa87f9a53098cfd5d21e913c7519cb171f83d0b73abbf3e893a3ccd5aebb9f2bbdd3b0eb0326d37fd1b000000000000000000000000000000000393052e6dff65e01e79254af757f12eb1931e0b386f8cf0fa0782269f962ebc5d9bde46f5a4ad3806e88330aca59ff01e1c9420cfa91026286d7f986b538c13e8c97893995485308c69f053927f962200000000000000000000000000000000033aa108d252e9107f29cc7da79585d4525ff2a35d31479a099c7c011a9c4414d7bc5f8498f8a204134b2d14c5fcde5100000000000000000000000000000000121214465992bdefb970d420face6db75d531e67314a021d2877643ddf738fbe57625d286bde7f40efc1d329a2e85b6e0000000000000000000000000000000017e14f6cdd916b1fc949be8ba3ef9ae6cc16d64da4dd498b5458ea0c14eb7aab8f970f030aab26397110331da11a232d000000000000000000000000000000000c56ccda2a5cca61025253407e72967c767f0e7f2aa0b97d4e4a09420dcb882ff35039ae504a9c62b3f9e7bb0c2e7bbbe5095ed9a9181aee392888e3194ebf9c4a6d87b503f4668bb6cc0d290880a44f0000000000000000000000000000000010fb3396b0674b9285cc5d5a4e7a41ac002f2b43332c20a56f428d1e19e1d1bb6f886d3bf03f7b0fc509e52d75965e15000000000000000000000000000000001196b7c253c50da10815bdfd7930a69608187fc3ac5fbcfeb35b95754d3017a094afcdaea867c2f08346717dfce7bce8000000000000000000000000000000001021f178c53b7d7d2041a6419203d12ee162f27999dd8f79baa15c37a7401e7a6df6aa4192a310cc1a23bdb0b427d63c000000000000000000000000000000000953c75910165f11112583476574f3987495d33e5b1a5c650a2b30692592a442d9de36da49255b0c01a7bacaecc9b81adcece8ee33d3bf3188574e94a889794077035ee92473b7266d92a3c018771b4c", "Expected": "0000000000000000000000000000000014da1d424c936453600a4acbd3666c6188493d4da8b34d6bc508aab07e59e3680a9e3488e69d42a724c9486d70ed4fd000000000000000000000000000000000048c637348fb9a4c631a82ded1fa08d693cfa2cdd6cdffb8bffee63d1bb2ee8676512a1a8d375e7ab942b6d6bdda45c80000000000000000000000000000000000443264e7dfca91f17251c33cf72c56b045902b4db2eb10d1fd856f79b4130afa6f29f3283af7d3b8b2a9d8dd63718a000000000000000000000000000000000fb386f875190ac7a49d4742edb387f72c1ae0366ca5c71d5b7e385c11442941ce0fb9fe2014fc624fe93ab86ebc7aff", "Name": "matter_g2_multiexp_45", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016a539a21320574fc25ffbc0ff10c821d6ad20674413eaeda6f4a31f9a028e21cbb3b224c225a2e3bc3dc221cec084cf00000000000000000000000000000000104e44989e2fba9ddce8e309f5d3fa3129f679d6456ed11137149b50adf8b22c1a148d47154450853e6797aba2b006850000000000000000000000000000000008b33b8cfc992efdf7d733803a6d08a4102e27fc4960ebe6ebdb7949c4ff5af76e55002d93a4f7204eff5f2dc4e37ef10000000000000000000000000000000017c35411c571c302c746a9b79cae892e988d50b4660564660de960ee09b3937b6f5b61fe37d09f1c02528f554210744aaddc845ad867f1e2664ef0e78bced8ff6904c5836e7c63ea3a9c858fd7b710b60000000000000000000000000000000009cd32594094d4744f59690cf8d7fd260b5ffb2a22945d938c035151861507ecaac9ea553e7b44fc4b3beb03b33783540000000000000000000000000000000006f4de33731b9b13b9cb395798769e54a0679d272c2d5175455e10c790debabae4ee02b6df08975efe806da9c4a208b20000000000000000000000000000000011859798a8383b7f994a1535bc0a96a114b90644d19921f0eec774ed58dbaa899dd3736cd1f4a4ff9bfacbc7370091d7000000000000000000000000000000000376c25b0f70427d4974c4fd1539d40996b6847fbb67822fa01cfd541cd3a3f8a9f3fe9f7ddcc3ce920a6ecb27dafca0c78cfc6a30cea34d3d3505f4f897631f67ba77913734f6c2895d871fd6d5581c0000000000000000000000000000000003a178f91a135d59dbd65eacebab293a3817d30e734c247f56a08812aa540a5c80e3f9908d86ad787bab27fbddd21517000000000000000000000000000000000672b3544dd2b91a626f37dbb389aff073777164e3e20dc572b18a2e5223bd323094e41bdbe2dec9bada227efb37dd22000000000000000000000000000000000f40f2d279c66f22bf0fedd129e02c96d8906f9f1ec19f5a5c1cbd5beb10942a066dd391b69920a0a697138f627a1b180000000000000000000000000000000016ef3caad858d323b752e5c437ee2043c8f691ca0f1862e80857f7cc478a689df97bde5b1d1350892c1adb03c5d2373ba1e40df9e1f7c84633cb3dc2223296887de7281ea66c5e1f2d5816334f7b280a000000000000000000000000000000001276e133fc5e708a3265646ef0a0122048ef95d7fb46f78b8dca57dabae0164ca986bdc74e581604ff31165f9f28dca50000000000000000000000000000000008a77611be0502d2ea7fbcf73774fbaec68eba36038e2f34f79caf07f2e4b7444efc49a4e85f88af585fd28a041f26c800000000000000000000000000000000181ab176e391190b1cae2e9b4105ca14cc82d15890b0ec127d8cdb46f30b704a089ac69e76f5b50575ed66176950e1120000000000000000000000000000000004031ce77fe9ee319b8db8f220ef4480c81568b3f6e4043c8710b559d25ad69dd38dda48b2e11d5aead18db0d1cc09b98810b9ce0020904dc1903338089c30e616ed0be03741572ce46946883874f4ea000000000000000000000000000000000f26e6d71e206c88dc81b8b8a5c05ee84a9f185e7b7f155253aa39104b5de5be7bb6cb6662df4f8e63b37fd1682721f20000000000000000000000000000000010058d13637c8da2e91c8cda7dc2cf1734a2f14b12b798e5c563ef9ef3624255a6e1c7550c37b547c35c55dc736a17ce0000000000000000000000000000000019ed470bd514f8bda8fdcd9c64f7626efdde0102907bd31551b1d1972aa14e1d361e1d58b17948909a669fa4d99cf3200000000000000000000000000000000013277afe1891807e269c22c9aa1598c12081809d888e0eb2513ca3f81308700893f74f176858ceed9c7955dcc0d8fc6893e7702da2ff9f3f14586a9ae80c8713743d61b915a7c379c1faa1b151406a9a00000000000000000000000000000000083664daa965c4173d6028e047794703a16e52ae459d3db0534d13c72d749d603edd668b9ce500677715e45216367c63000000000000000000000000000000000f4e87a65f4720cbfde7868eaadb34ec1916925ffd84e5407defbda0c39e1c7afcbc90855b275d528e7b63fd3707bd4a0000000000000000000000000000000004c9f689abe0d2dd3d927bad4b39ab44f6704014ef9a1dcd1966777129e1c72515b43c1b92ee60e9611245454683588b000000000000000000000000000000000ecc57b08b45037e62498135643cf077f01d216b5106551daab391446ce7bb37d40f41378c830081bb6a326f0105c2c4eca54e365faa35d2c9be259b53a1157b180a373813382f47c9154af18a2d83270000000000000000000000000000000012b84341bbad1eaf7fc8ebe56f67598821017365b6f3b4cc1f2355f868e8d55f9c0bed2943ada202a7d85cc884d8e6a20000000000000000000000000000000017693721988f73d77f7a41db108e428b0ba781ea88eab463693ec352cc13d394101b9a2792e0f30c77bebaa395a4776700000000000000000000000000000000093245e2919523cd57a0abd2e8a9c5cbe774bee957f26d3cb502b9c8c06483b850b031461dc2cb033d399651724f4fe4000000000000000000000000000000001530f7dbf6a0fbdc8b4f7a4d298b7824c15035428cb8df834907e25c64b8985186bb13f397b7b99ea7014ae65c428b12abe2079ecb3618de3accdf291d9479bec32bca1f9fe87b00b64a12d735f5b9a5000000000000000000000000000000000f323f01f2a63bc6eb1b565594ded14043c4ea5d1f0fbf20f39299052617c334e6126afd4273738aeb153c3561348b8a000000000000000000000000000000001525d1e1fa65f1b674feef74f6c81c82c3eeb709e597aedabbfc2b3262271b31d93818613ecdeb49c5d3a6a64f17a5d90000000000000000000000000000000010458c15bf46947a237dd1c61882b1561121f64890681bae5db6fbd24ef6c34b7fcb826eeee1fa328d9ef4d859faf238000000000000000000000000000000000e1f29275fe1805d02e069082d5e9a7acf69be17013e6c4c351277408d49383fe06f00137e777ba4aa49c29c25c6c0ddc541a44756ebda14aea95f1a1d05e7366dc0285305116b907fc89e777ce45f79000000000000000000000000000000000efb7373e11694b966d0182a9b01d1e52ec1e89cb18275921294e2d36333460b1e49fd420f1ab781b000d1491ccb0b11000000000000000000000000000000000cafcdc2c58fb3fad713ce1a38deadba8636c384243f9971e3930b961efaf303cac4eef1e8e4662636ff91eff1bf52a80000000000000000000000000000000007ea7441e1b2b0f1e42bd511c060b646c2d00bb3e6507beb5d17ab93ff68515b02f82c2dd43ce035ff660ddb0c104a77000000000000000000000000000000000bd04b88caf9dbd0ef5f89d12e72aa47d64212332b0ed871b7eb96b16295cf4810f6f20cc85fd4d1ce72119f80697c1b37d521d31de52681f1d9bbf64a12f9bc8fe0ac61aaef14d7e8d048ff09e6578b000000000000000000000000000000000c3d2d978e23a690e8422fd54f36fbee1f642611b6c3b2c2413844066159bdcd3703d1a392b030446af04b654f8f73b7000000000000000000000000000000000ae652fcdbd8e467ee9b447e61fcb811f8b6aa48840476c92daec3285785a06a81c1705fc2896c0843ab48eb92555b9300000000000000000000000000000000007088e6441cb85aeffcb4a9a0c81ebfc54a61f35c542be3870c2bb94d7081353322d4745747b0dfc3e5db07f9e48c560000000000000000000000000000000006c11f3e0941ea3bde0dd3a562dbbdad433f0b1e99ba34879e86f7951ddfb29b9e04ca62d54d7552a74e8cf1c3da3e704904a876d4ac1341e88fc4808508c89c19dd74aa8fb1dd7673cbc2d28e7d920e000000000000000000000000000000000c665f4417d0163820ac96c83cc2f09b1b3c000023d827e2690aad7357ff59e278832b992703f5f0016051ce0a4510cb0000000000000000000000000000000012f4b6688300b253fe868b3790f6d2f4fc16d81a49ff7a2edf821de16dc992d79482d66e443e0abb5da43df69f8d648d0000000000000000000000000000000009e033750a118d998b136cd671d0e760e3a617f1d6a994db8f6dfc391619f408720cc57fe550785306184b0c824705620000000000000000000000000000000018cbacd471e528535e22f714a841f110fb0484826e30f97842d65072b2790dadf0bd7b28df96bec531fbed1f3f93486b68911b04d8155f90c7c5c0cb519ee6ff14c0ae27ece0374f30fa148235e8cb49000000000000000000000000000000000c42b6fd52cc52034b04078a6565af2b43948695851393596e05f37f297dfaaea931a33f5b4c25980c093f8a742c0020000000000000000000000000000000000fdc7aa20e63743dd6ab32c82d2d6992b29779ec06eebd452c17d844159e90a7f3221f3e0e6b5805dc0f42dc3836d90f0000000000000000000000000000000003a2342a1bd528d701c2a6c72708a16df632f4e4b6cdb3ccc224b58b57af30b44556cc968ba3c0396a5e3f11568a73710000000000000000000000000000000019ccf76462668905c5687b7612a0bdfd4aac70f291d8b772e84fd5d4bcb591556317426471242fb5f44fd695c7d49279481e894ecd52a252cc76547513e2cf0a5cc6b20c3dc9c64c7f34f29a488258ef000000000000000000000000000000000c8fd4a171c5fbf584f567a1c10b20628e7e0d5d796eac4a9dd2376f8d488da25b9219c7c70709999b5553f8bba915ae0000000000000000000000000000000005d791c907984f2aaebf903a0ace52147745295f0c5e85964999a8fc74b64c8871dce358f26ed1b4af6c6f7f18e8f4c500000000000000000000000000000000110a453bbba72ac171876e0f6b4acd5b178816301e02586a143c2bcbfffcdbf593655408b9aaa4141b2a210599f452ed000000000000000000000000000000001025d5065f9801fcc1c1ebebdf67923b967ce985b5ca27ab5db8af7057fda23561a46b84fac5e793dd9af692c4d56cde72780ab3c48c8a102469799ba2f70d2fd9d324cf558a8c8b49e2ecdb71ae1c9b00000000000000000000000000000000023e5ea1909032676cdb79111a33da7ed788d2affbf4029b932eed843268f355dc92905db283d6617fbb530da3d704dd000000000000000000000000000000000b46f07de520aa17d597586cb0a6894a356757941ff9bdc2976f620e1bf1eec1dd9801d6baa2d7efbb3cc7073412ce8e0000000000000000000000000000000010022940611f418de9f9210b1be919d7506aca468fe5853675fe159d3e58685bcff6cbc2c1cb9e7d45a7bf305fca0eaf000000000000000000000000000000001888b5b0dd1648d9a27345f570a1278238957de1bd30c195d554750ea4b119e98b3989b912c4fad531de416c1533467f84ae1de8aaf498bd2d91bd828bc64e56482b225322b86529da703f47289c65670000000000000000000000000000000011dcc334a5037719256e514b2c3b0f36396d8cedcd77f33545842c686fa0f35558c397562a7e245f8cc412c776a2b3930000000000000000000000000000000006efd32c6afc56a07c813fe19e71f0248666c87e1df7e79b7afbd70178929e5660e85cea35d1c6f42b4c627a94ae0d150000000000000000000000000000000005a5fc2010798c793c1b407a577da0bf0e04b0478f19b7d0cfeff8e4e4fe2d581461831db165cfd17146c49a732c41460000000000000000000000000000000011dfe3b62eb87b039113152af74ae74137cba1762d4ae62d3cb0746272d1c42d3cb4a8fccd845a519fd0650a23a897a13256548db55ee9de70ebf6fa347d81bc50494b937ab1c3079977234a34cbfcfd00000000000000000000000000000000110e73e44734b7ab63f021727b75e735702f1acfa6669e0dc27111794ebee371734764bb165132af3a7e02f3605456480000000000000000000000000000000005fbcac7c7334cd0e6468feedebe077b80390833eaa4c28af80d29e75d692a10cf13058526fa5e5ab0fb635335ac8f220000000000000000000000000000000013f537ecc28685aba2cd60d0e3e787bc8104a3373177cb93107b63d39919c583ad3ad7a42e322249d7605ef035fe1af40000000000000000000000000000000014791f94aff42bfca13ab328a3e47b06f7da52e13436ad477cf55e53b54108d3aa531f0a5d73ae5ed7108d5cca1ecf7a575ae146524544307ee51e58a654d7324983a87e1b37d46cea1a4ec34114b44b", "Expected": "000000000000000000000000000000000bab02defb32b7938372d656feaebfb5431de1484361542c02519d20c6a500f0b0b112c331fe6f4eac3ec7f6ae4167e50000000000000000000000000000000000796b38c67df1361115bbf3a4afad2651664ef55b1ed02d3172f024f90a003fc3631753d7142aafffc64c6f6f57bf7800000000000000000000000000000000080d91637a93a9025e8691a400254af37cfde67eff7d3037d428596a808a01d9bda8025b7246fb00785cd1068b2752d400000000000000000000000000000000182a97624249f0c6d24672f04e2c93eff63fbe76cc11ace0f7193facd0655cc1e1ccb2d89d9547bc352a395efeb95afb", "Name": "matter_g2_multiexp_46", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000115b14c4eb9cc78eafedd2072be4555a3db9e61b5fe0139bf3e40a92cc37b4936c68576fee5692a80e4a9aef05a9b7a80000000000000000000000000000000019c828ea555a3c8d28cf0981e98609361b5bafa8b62e860d121c0f6d0f0dcef544784e8a5fa6a9f1d1a68b30e8e8a6f8000000000000000000000000000000000a2ef5146d2658609fd4eb98fcb5d42f6c6aac4fe53597128bbba3ba3539042ee5824f381c41dc76e2c6e4dbe0665657000000000000000000000000000000001807a12ae5f289ecde8ca0a913647d44209b13fae9dd6aa8fb4365a3beeb81652ec17cf92f6784c9ca5a077824ff6dc31129275f3ab3125db33d43b36c7de0ad60a6e9cb4457aa03275caea9635f0b0700000000000000000000000000000000186bfd109ea2369818ae2f466953eddfa763960caeee9d6f1ecbf6a3f854163342c26b56d3844bfedd8f227070f75546000000000000000000000000000000001877077daa2ea074b2868e86faf14efc6ed35a64161a77aec54624d9cb916c45de81b40acc3797c6e3338fcd7a42bb0d00000000000000000000000000000000054be1650d9bb6cae6a1ed08879668e4aa4cd139c8b07ce21d40fb1cf37f11de730ff13814a02d2d6d6df5eec4afe8470000000000000000000000000000000001612b5b7c613cb66d4134aa867d985682f6a544147e7865732887d4fbb191a9f5bdc27bfbefd397f38cb101a2d68b192dbcfd8680258eee451db60f3f42f02f388f87440d00badb0a725964042515c90000000000000000000000000000000015e2b23aa42f1e6a07b0a31dd4acc27e35ce1fb3333c3f330f2d88f112375cf24e6dd5afc4d245531e4e84f1f82230ea00000000000000000000000000000000193649f3b7efb346e0c1f7bc05b0910311270cd44b5803fa16e06655d6239f609363344bb7c16c2105e20709fb5ff0400000000000000000000000000000000002a6ee30841f471dd2ef13888ba03c9cb93c85cfd0f1d0a3927205e3f57fe291bba7eccbd2352f25cc4047097fbb63860000000000000000000000000000000005482d4a47d6e381f755c4756a761f0310d0d981523afcf288e47a1a643d6be62ac6410521e0f25828f469af6150f41e5a6f194abeb6b7c1c561aa820bba658f0277870e2a32f972f9d18ca361929b01000000000000000000000000000000000178ca460993d503e496633fe5230d895bfcdd0696d817a23ae94e529bb145a0861e4448d3bd48c55907be762192a8c4000000000000000000000000000000000015d2db77105a8ed6eadc05d3d1f26a54b3d1b812a58ab49a889f5b7fcf5ec08c2eea6ad09484fda29cc007037a1f6c000000000000000000000000000000000fd5628d61cd0835fe49fcbd2f17058f23d0ffaca4474923a2c0706d9333d9881125efa2fda56234a82158da3eddb5b70000000000000000000000000000000010ce4a0bcada5f92cc8898dbf5c108c0897322eb6a467662be569d9ed0f6e2c808e214b83969ebb86c84d38f67d20754579450b7aa155a3ab61e47e337ddbcd17b197de2dbb76008cfaa09d3fc806be4000000000000000000000000000000000fc4ed0ca43d5cb172deef02704579187a480cc977737070b8ed2dce48d3f3141619f37e985c220a2840ac01dc5667f900000000000000000000000000000000047a15e96760affa4e537a45aefaaab1e0e18052f63514a9f6544136c87b7cb4a5c8dfc0d9544518adc7932ce9cff5f1000000000000000000000000000000000c9be55c06f81e87de58a5c1df8d16174cf4115f81091937d98dad6c4780a9b8dae1081f8961fadc4f994ef62927664700000000000000000000000000000000165f9b1a8f23831a91be8077b18563c7648e54caf30895983cc26580241ca7c86b9b30408a9b27776286ed9f07bd8ecd4be94f96ec4a3d4e028644c63b2577a9ef849b403acc55e42432c3063a918d160000000000000000000000000000000006edc0d62ec31b14e87b2ccff3a21a7c8d38c3ba0ec48bbb8df27fb1acf58e1a87c4458dc2b770172460adfb9a9bd50b000000000000000000000000000000000ae80063df8d41d45fc43f3aa0881364ab5fcb9ac526ee22d3870f2edb0aa379e9d81780b0ab08a4cf308d819338deee000000000000000000000000000000000e0898453feebb51d9a1cd2bda36a307ff2eebf44dc8f4c694831218c42b51f723ffe521b356ad4e5f0dbbca9af9ab47000000000000000000000000000000000fd186dbc046dd02217cec3c7894972f71e5f00e00a40fb1521659a33e079b7a1f60b026d9055a50ae18aae5757ab8490983e6618e9e4208cfbaf647592e42b2d30de9e74e4943fb2bb49109a66302aa0000000000000000000000000000000012134b433877e0a7858e6c3b95b2a1dcfb0548b290b68c209642dadf550db1c636598ac43d101b13c2d8d5ed9602a73800000000000000000000000000000000102b5de123c449a078f6f06935c9537efc791ed8e5475ffc2d9e1d098c814abe56d4b7fc6501c315edf7e64a431c5183000000000000000000000000000000000bce703ba78f45a1c59c69429d3dda18243ba2413c5eab46d469f504da975c434eda451c85357738d6c7054755d5cec1000000000000000000000000000000000387724937bfd817a65c0e0411678cdc78df26ebd4a814d92b023710558701163349b56b80e6bb68a4401f2662a0525506615e300a924ab962e0b7fd0b044cae9516d96de603ee80695718c27d7fba0c0000000000000000000000000000000005abed9305bb79a0ef1cc70e7fc2eae35a8580cd3d1ffad73d3bdae541ad546b8f74b4ca76f8f374e31dbdaf1bd14be9000000000000000000000000000000000199b29da8d161ab3061a18debc8b7400415caf029ced47131e27d81a0f7f79b6ae5e570f34a4c74fb85fea1411bd6ea000000000000000000000000000000000b8a7c42f5289d20b1a55a42d53d49510d3871b6efbe560bb4d87029b85b930f787c3a42e225006ad62c68d5f96c2f8a000000000000000000000000000000000e74aad2b29a210cc316181863e71a1dce8866a088a072ad5972af57b813a2e968a5b16b294273acd6e81e9a5be2961dd77d3e9e64e00b9356cceb62209ad48fc89e69e2214aad2edeba1812272736390000000000000000000000000000000001587e32753adc85c98cf1322115772b0e282ef4e6a75944fc86091e81aad076508e3d727f4df0e30924fff6b67c312e000000000000000000000000000000000ae96d3a1b79985e56f80df8ac4d9792229ca580b156dbbe71a9db470447fa4dfa19fc8a8a2e2f0fae28a24b7d6153d100000000000000000000000000000000114101ad0d29ddfd2fc436d2a270711c444c8c257785f4b4c549e9c795f6dd9834d3744995d2188c0c968752a7f68892000000000000000000000000000000000d30d9cc1e2273af745dd47a596a2202ca4fb655f9f9beeb0a87631e2461f29206163fd921761fde69654cb02e23505c41f75c89ec973f65b11786e186f4d42ee2e85c40f29745d9f428af08a39d5681000000000000000000000000000000001611787ba658b64467b4a28e55ea24a3b230836af6c2a7072231045ee4ee38e02302a62688d6f988f76cb5e50eba40080000000000000000000000000000000008badcd59d6d30f26ca674753ae9257a853dbcf49a5641999634a9a35a97096b6096b7b058360bec2f9476a51eb0d781000000000000000000000000000000000d30154440d8bb5fa6538953a96ba404658817be8047fa7a3a86493f02399543220758e649948b804f2daf84fb86f7580000000000000000000000000000000014fbdd62f761fa675e4cbcb61083a910bcfbd1f8e37f1fb1915f60929b047c970b87be0730ddc20f9716ed8c9bea7f19c70cfb76a04d1a9e0d937292e5553ef371e20d5d3dd33611edc0da178e2e4a1600000000000000000000000000000000143d1f811644e3a51c735b708cb2f8a2a90311f9971c90b9ec8e45bdd6488638b6851dbc882205263887b4dd5dfb4e120000000000000000000000000000000015692a6b06e3bd3100e149c6be3cbf1566fb24531eb29036fc48f85d5da83316a38af4e714a17552024c1ca4a5e39d9d00000000000000000000000000000000172b9c88ed9a1fc2d5a7f147d034fa243d420b129343ff92b79bc4d836e380e5a7e388069e9af9026485e9d3f41a7aa300000000000000000000000000000000012e8453dc64f72653c4e9b3f6f43fdd01b896c642d21604f992dc5591f2cadf71de4099e1075a4ca4b7539f84dd5a908db878b7f5fe817599add432ecf262f19d80ac834bb0a0f983728f6e2c189c880000000000000000000000000000000003e9b6d23809781f50c0033e53d245dfebbba9e0c4d9f676ae61b80fb6e774509f62fad854fd9ea841d9905d48d943a30000000000000000000000000000000016a1ba62bc684bb1848b0ccba59597b19973b56fd9b1d9d06352de44aa79c6bf65409dafb54f859d4a7c32e188bbe19d000000000000000000000000000000000e782741a4b16c5838a8f6e542135221ab3c6ad180c85c08742992ddf0239388e273735eae76c656e61614da386ce2640000000000000000000000000000000001cf6752e88990c221af94e18744790c30aa6a158b10a1f6a56c2ee3c3f0fdb2fa7213f16764ac9e9f4f65e99e715ca170751fe88ad289c91dfcd3c3c61ce1e33f4146f03fc0dc77cde9b32b51c75fc0000000000000000000000000000000000810b0175d781256053c3c9188cee4f55620a6624bfbd2f4d2e70ee68a105bc7b60bafdb76794a048e9f25da976390d4000000000000000000000000000000000716095f8fd72d9350ca62ca3ec34d2228cb563d4e89b19b152787d42fbb750435aa6233d0a97196a9324319837be14f00000000000000000000000000000000178e939d87c37d4a2f49e1e5596945879f2f0f64419e3dfe2afa06bd58098e1ba57a9b60c32cd6527481ab3b325ca827000000000000000000000000000000000aed480a1da482e40ae610a9522f0a18399b0130202f9ca79e3573987f5f7ae30724feddb52fdd05817a96f7937aaf7984bf139cc0b6ac94697b7dc278063a74e478d47528da3f84f55fb0adfd851d09000000000000000000000000000000000133adb236d9eec3544fc91852278abe37a1da0f32a84477c0d93927d64af613b7452a5f64ddec7447779f42873cb157000000000000000000000000000000000f6bd940b51b7ec5a0d92ac77a55c296215e970e9a499793864dd69c3a8d583403e95c08b719b5d8eb0c37a8476d3b960000000000000000000000000000000007d4444062ae06e65b45c6105af53c487f6b275ecdb36f87ec7b71d5861a1bdd6d735e9a1fc5dfb476ab8c13a98b570a000000000000000000000000000000000e043cdc87c67157b5ea3e5ab1b243aef479b23861f8cd823bced140ee03dd1f8bc6cebb4bde4683ac3340823f4d55b8d19d9496e7ebca44354d5c6e1f6b8211eb06ca23a6444c307f92f5bc6dcc2dbe0000000000000000000000000000000018c35112c27caa6bfe9cf8ae55f51755ed349ee7e7141c99069dea07c21a6d8634778a91f4dc3d17da04966a9eaccab5000000000000000000000000000000001800c8a9b146dba27050ce63e78895bee2016255c59acc34fd5e6cb926c16a8fcd2e8a579fa02559b3c571cb08011bea0000000000000000000000000000000014afab23fd4ea54b1ef576a12a2a62d42b493612ef466483ee8c4e62908486c038598e72dbd9256166960db73259def8000000000000000000000000000000000899a99ae8b10da4bbffb6590d79aa33bb2adb2444a11627f05622c732b70f90cbd2779362349aede5b591e84b53a8a06940e3509e1fb090fa787fdf633a74380cd5de722678826224641e46a6e920df000000000000000000000000000000000567d6458d1a3e012c63adc8b9dcf32254c98c0b7021ec6a8d579dad47d501715d2e42a0837def225515d663e663c4f000000000000000000000000000000000178daae121366ce025c1dc2d3e72068fd40ba9d54b2b3724f7a2071a59d4f17d4766a82364540bc31a46398c66d0e7da00000000000000000000000000000000147b2851311913ea53662082acfba785d21915cf00cd154b1b495246e109ac37c3fb6c63aabc4fe71a0d37c81a40148d0000000000000000000000000000000000122b7b1a81888aee37fdd6c23d31c38e79f28945cd1798cee3f4d674e923fc68311eda8ce45a561abf9c5f0bfeb4297b27d21c1d6e06d9fba7b61fb87d364a7a6252c70b8ace2d3679ed87ce0fcf7e", "Expected": "000000000000000000000000000000000f5b941cda417cce69a30c1ba4a82cca71cb4b953d06d8e545c1b792ae22738dc006627da02b4344bb8be93a5a0dcf07000000000000000000000000000000000eebf4ac30fe0ffb905f81577466889666f801d4d6efe0fb8a663fbf1cbe76b2167243edfc6cde3f49d97d3040a9507400000000000000000000000000000000007ae6a99b86dc7ea95801776589472547ffc7a623009a592403a9710ca365510d85bbf20fa4519ca0e0ca208bf86a670000000000000000000000000000000004b5abf778c72bcc5b887855c582c042a4cfff489b0548785e4c1b735b19159be8a3f4cecf34c769a34cdefa722ba783", "Name": "matter_g2_multiexp_47", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b47384e6302b140118d0a9247aeae2091607ebb413ffa232223bb42d16753b2ae48e5ad0265e33616b25f0c4234be600000000000000000000000000000000167be566292b835a42ac7c099d80e8a0b5d4ff91d842d4ff6026876aa1570ef9641e9c0cbd44d8578f6a758717bad6f10000000000000000000000000000000014f692d195979abd9c55ac132d0def925d4e158fe946fa7b0a010c475d60171a0951d4b68ae3c463bf1136600a1ddaed000000000000000000000000000000000ddba1f4236c5200aa52f8cb7e15fac1f20cc66dc65ed180745a3eb8308f2c851ed6c1e27e1507d3f902ce672d6f8d24facfcdf87c6ca0506b070abff83ce7812181c31729cc534497aa8dabe243351300000000000000000000000000000000023d08e255b244cffe911e43b9b48408f9fb3562edc2c27f405bb657731c885a58392ebbde9fc80cccee2404cc8547ec00000000000000000000000000000000088ef289adaf206afd2b72c93049fca2cf9292bf6471133c64ac4f42015b97bb9a23f6c34653e0218fd0abdefa56bcc60000000000000000000000000000000015cb78c1440f74b17125c547fe7a37611f01b83b91a351664c696e0f647bd2db3ffead880b96a327780026d74c9abca30000000000000000000000000000000004d1a63607b9a5c9ec31168d85fbbee77cea0ae93e98c8c1dde14d0baa72f91042b2b7ca489958344916ce79bcf286456546fa692d9cd61895526282193c90148099e2afa54f7903a5431f932bd5fa06000000000000000000000000000000000ea6cb7ff6a7f4ec38ba11e9945eb406dbb8517585fef6cdd64edc970efba244b071fa162f7c8e184acbf71c5d1e12160000000000000000000000000000000001ab80c0dced33cac8a6a085efce71dcd7021f6255684bb631cf5c1716021bece57b900b819e6eb6f5b755b74c677b6c0000000000000000000000000000000005465fdd51352cbcd8b804cd509526c3b6232976b8278cec3b7db7da14b77f78898c6240c30943d1418462cb7a5abf8f0000000000000000000000000000000006b6caa6a0d5f2d671b10217c0ce5b3962b0c3edb4f2918497c316ebbdbe1a15c803d7fc3413907346f0e7d03920005aa9c1460c1cbb2a552e3452d5c5535868ee9c2952ec3fdb52dd826c16ae3d00bc00000000000000000000000000000000170db23154805a04013052a388e14b5da00e65b35b8ce2dd967213a74735dcbfd28782cef1ffe9d384be3ecadd101e9300000000000000000000000000000000082dea309092976408a379f1dbed9d8cf91f768e2921e49ece458859c80a1d9efd4d5e588470bd669c777d16f9d2e7de000000000000000000000000000000000adba8ef34e197689228e6c4e13be75b3d4732872c99b865ce7733b7a42034d6d4d7520ef7ab712f60f1ff87bc4d9d8d0000000000000000000000000000000005df0788ec39430fcd0625f8e030d917d8e7c251ee6e3b0e79fc6fa5f6fac2ad736c818bd833e58ec61cfdff52c9c6ee2c36204b6a005a64819b06804eb94c311d78977b557e7acfa82e147b4d6ec62f0000000000000000000000000000000000922d8b5db6e415aa3acbd0d6065db1b492c92313260019ef1bda0fa091c4bf091de95846af1edb34516b1abf7d278e0000000000000000000000000000000019af4ecc4f278315ed90d67cf4d22ed6fc9af5c0d0ca654f6a74a3c4bc98588bf5347b4536f36ca8b4750c18464f9b7b00000000000000000000000000000000021eaceb11638bda8b4293991983f11cc60c1daa2287f4b4a6066374bac82d117ac3ea4ec73afc4372d254bfc433b8c3000000000000000000000000000000001037fe26a10305cc5dc11a65edc705be5a0082656cad53e63038ee57a79e16075df54331233229a129483c34d6dd92ec9160c5a553479a10996704c3eda8e57be88eaaf5d1efc8371e7e10d7d106e4810000000000000000000000000000000011e63dc251a5a1e2ec83741682d90588b6b185365b33dba45458b1f56324a4900b04d61af155a0edb0bdc2971b7aaa210000000000000000000000000000000002dc1bd5448a2ebb9a02509af8777616ba9657bd3be65519233f0187df77c49fc931bbd3ec0ad5856b2ec0dfde476a870000000000000000000000000000000019f0cf8baf100451313711bbb0a0fa318c14224933897e74fb727b585cc8620b7d741c9ca2f0d3cbe14a8749aa48ef3e0000000000000000000000000000000018448fa9e05f87d4991ae1c248413edc9a8c3ee789c9c005e691bfc9003191ff469e26db9e42e5758fac79309a62942c5e5a50e5dbabb7a56897935683f80a5b16dbef3c23461e241fbdfceea38e3ee200000000000000000000000000000000109b71c19cd36ef3078bbae25ce6d0e8f7b58e129407fe68ab09aa747bfb3e90c04ab804fa6b7a223c172146fdb14683000000000000000000000000000000000d297750ba112da88beb84b8bbf74ed134b59fc9496da3045aa6dbcd97c68425fd68b75508de113733602a5565f4c8a600000000000000000000000000000000149b8ba6e05b66d07b353f46ace4e583bb61ed18fdbcea0e941b8d9805d3168040186d1c961add494f98e4e7fe68824d0000000000000000000000000000000013a6877bd46557d23b9aaf371ee5a101227d7938c64503b04b39cc6cb4e8ddedcf5cb6865439c9f8b1bfebb807ce52e24a95b293daa2761cc456b9667517f499c4d9eb9eb1d82237e7a7819b5d44f7a200000000000000000000000000000000073f440c2704fae6c86aca3cee34591ec03c362c2c5153a5e82c7bcdece2af0c58a3484b448c8bf4da851800ead959df00000000000000000000000000000000075a2c26372b482a2420bd3c9952fdbf9e5fea906dc8a4deb9691f8745372805bacd68a4838a3fefc381a2ce946ed1780000000000000000000000000000000017575b016435782cd09901afd2ea6773b11f5a983bdd19d14668d75362f95d055b76e5bf6966b1bd7bfdfbe9a939e4b60000000000000000000000000000000001569d74258298fac89d0d91a9945780f4c08d7af7b942d06255ae590db6e8509c908c16bd2c2bb634279debb72f489b5e22ef32d111261dfcb5a2e8d23c8d920f013bd9602bbef45e6d4e0909abdef20000000000000000000000000000000017180e36b925e2ce23c46813d96b919ca181481efb5d1666c4a4e9c8031abdd9521eb8228c4e3f16de0b33da4c73588e00000000000000000000000000000000138965bff7c573546d80ef7efb3d45e87ed20f59adb0cd7ae148d09a97da7feaf1b0ef2455ca19381762768a7d82f486000000000000000000000000000000000360bd29c3f07c5b560e2ac226112a628839da9db18b052991eb2d9c54541c1b5ade9b3c2d7f446ad50050531228120f0000000000000000000000000000000007105978bcf13bbe2bf5c8f7d165998c3ad99b6a2794c90f5b61fb7bf2472d307df8fc9f4afe7ae1e40e7f0eee8ef9466e687c0ac8fab70de2416642afa1553bb38183d2914050602874491057f78786000000000000000000000000000000000f4434c5180ad10cd45dca62b8da790cdb912c255c0f33950f7039e3885b38fa9e9297c7b0a875380545839d8c4d4ada000000000000000000000000000000000d0dd1429e512884ac209f788b5832d31649a78a8966d3348a93f841be23c8e4e42d6ff0d6c27e8f43daf495c9582935000000000000000000000000000000001307377f55dfed30ac1a406671af1895218a01d063b025d25bdbc53f5f9d535e4cd8053c09b2cebb25d3a08365ab8ccb0000000000000000000000000000000004f5c06f505ed15aa7661249b7edd71855bbf47237e049aa951e1ea3ff88f98591518bac975ac628e417892f8e9e5523428f1a27ea15135f044643dc36a3f9c2b4446a3136bb11f696b0a430a7454b3f00000000000000000000000000000000083336fa0b79691b4875ed27b2bbd2d2586992940356f6ae5ddd2021c5ddd87f07f0a5c1e8d8a2654b99182cc2233e84000000000000000000000000000000001880f3824f7cef95ae5743de2e17191848d8d30f0469f455461c6559ebc75a7afbc86dfa3ee17f5470f74018ec335edd0000000000000000000000000000000007c2b26353e86223e5dbd4ed6d59f1170b9cc9dc600fdfbc6c73b96f2c667a82128b1ae5af0542b11a7d1efae87c75610000000000000000000000000000000002427b7eeb497a20cf15c10513cadc9ea612f3ae94e2ae833d281734e7b5d1d50e240659ac01da7864a95b4cdcf88744ae21ad8a6c9d75b51133e81ec34d66ca70a52529c5c3a2307b0e8d6f1c5e7d97000000000000000000000000000000000e72845430ebfb84f8e3cd3dd418f6dc528bf521aca4f9dbd798ed903ef0ea3cf21dd1409aa3759351be32b21d8e8cbd000000000000000000000000000000001457ad87f0957006192dff7d99815c35adb3635815e5d157542b9f52f1e9f8c0143a21a3be4dc1aea3a895689f4a316f0000000000000000000000000000000007e8544b1037ece2e5a9ea387e0f43b72e895e9c2ca4d205f12bf6df0b35ae62a4d62756221d6fff65b928b7358f48b00000000000000000000000000000000012c5c3167f6ef118c4044c0aafc85a337d305437d694a7bd6fb406dabb7364d9e90d74a8b327aba971421a5b3dd5d06988a23b118179ee2c34ad030993a2d2d70375311b95254c44254a32508abcb612000000000000000000000000000000001995d7cb79da7b6c5a0c8ccc5ba075d8d6d8ed3cfca85e8ecdd2b589986fa58c4cd4f045983e9184d79173678d618f310000000000000000000000000000000000f9f7f6bcff0f6fd621f3f8fcfebac132b3f0d52a34af33bb9830bd714d2982f3cc6674ad6ca668131a5062e5589df90000000000000000000000000000000017699b298a46829020e0299ab89ab6411af0a602dffb0e149053ff40ccaec71a908da02c8e611723cd06c16a8e5c0f2d000000000000000000000000000000000523b287383c1e47a6f31d397359941fe0bb8167aa11604ff8569969eb5ccddf4c4f432d2b6fe6f39204020e850d4f2b30eac099ededf0087275d1af828bbf79ef7fb0e77179a068f2ebfe4c749a98c90000000000000000000000000000000004760120239593cae5bdec813735ccc99a88129c707686cf43efbd48fb08d8da3086879a6042bf118879fcccce0736bc00000000000000000000000000000000105b8191431f701b365c66680cb4eb267681ee4da17ba55d47cf26d21ba1c0c3eeeabcafcc79dd87b6457bcc91e9fec600000000000000000000000000000000126ab502f66e732aabe02fdb2f7a665a9a43f6b4ff21c22fa976e7e434b08b606e9cf0f02459fd85f5a80a332fb3a62e000000000000000000000000000000000b2ef01adea6c00250f2f14c98ec6d6083c45019f3d166419e3a137667324f80c34b6b72e991daf72e2eaf9985d0f9287e8dcbf708682225fe3f71b7a687da23de5ed188e40585be0553358012132577000000000000000000000000000000000ff22a0db4f1b1679bde5853a7c2932501f191f4a9f25eed968a796219cef028e26070851a9036a05a04abd73bd6bd4e00000000000000000000000000000000097e9310749f52a4b645190069f4d52315f0eb2ff9cbbcd31f1781a68b2664bbbf27166e6e74fc2be2e5b1eb3f3d77a00000000000000000000000000000000015ca218d7d128095bd4f4b4f7bcf7666e92b905e551dd22745bc743ad0783b6ac44b841f87d3deac44617a7c9a341c55000000000000000000000000000000000a1cb723a4c378e5db2775f4dde9a6887ee3313401a64130a78b90d65dda3a5d9c8bcbc1a0d78c310c869a7fc4889954532cd42a9b698a2c2d22b1a620a7ec60daa9d1eb8ac36894603be7bb9b5e37be0000000000000000000000000000000018b30cc461a4e1fbefe209a709a21ae201bc6094b2d15f0d6dee5a55dd84ef56b62ab1b6bd513b27c84c638291f4205a0000000000000000000000000000000008a6f2082d6d510b280a270c09044ad31fb18b851ad2b38859138c9c2e4870fba6b607f682a798bf21a13bff116014d200000000000000000000000000000000150ef352d494a97d0a7ffe44903aba1611c8d81fa2788c0f42a6db48a71101e12f07318da5ceb1f0af3aa10cd4c26341000000000000000000000000000000000ffdf3b133cc926684e4624531569bfa09b1658e29ad9c3efbd5e9d18353ffbbfbf23a2ad80ccee88f8fa597416d47173ccd5e19892765e549a63238e664c732af781fddea558a117cb927bc4a1aceb5", "Expected": "00000000000000000000000000000000134f45e5409998e657923ca76ce92b7d2acc932308e0694bb22f121f8324d16bfce86f96c67111c8080289eada4b4fb40000000000000000000000000000000008d9063b7845ffc8400c0b7585e819043884f92e28f7e3ffa47a39e808cdbb034ef4230b6e19bebf083e939b6b686b0b000000000000000000000000000000000e95f8fcd6b5bcc9e00a580a99627d92fa7486ff5ea587df5dded24d1b0bb76d339f6765a5a2058a8e227f633ce36e91000000000000000000000000000000000393041eb33f2c63df3f40d8ea1e1a9eaa9eb0a46151294845e542054d503ef69b40b0b676b0e4f3e08f4d26c36a5d4b", "Name": "matter_g2_multiexp_48", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000042a220276f12fb4e81c40ecef3a0d86634b4d1c0acfdc463df4e7501289f0be385e03808d44be053e6ac98f403a8a930000000000000000000000000000000004e3dc92e155aeebdfccaaa1d24f49efc8b02e4d9ba8500a5b953a96e0fdd58519bbf1c279750eb8b98616e6bb9a3f6d00000000000000000000000000000000086bc212a83b09c7361540349767896058d5567d4342c607ae9c07fe5f123d9aaac95ded6cdff0825edb5acbce3e2b6d00000000000000000000000000000000062598cd6d5680a155b6349cd51d636c1350746d17fe0fff5195f164ba2fa51cf52f8662f43d555f7be6bb8bcacca39448da17551b2369b723bf932173a9167663f8389d2461b763d6a061df78d7ff1c00000000000000000000000000000000193e2c749e5bbe87dd5c306d822740969cd69ad6e156c323d217c08b18bb3f97c85aad63aed1e3a455ffa1b6d2a670340000000000000000000000000000000012a3dce63a88ae32a746e3812833569959021e1dd9518621793308f8f11d04829b2c3d0e0ec39fc48dfb8285b6852746000000000000000000000000000000001235488d01c380e91872fc57cbf618c3531a6bbf6cba9dddb9f07168cd459c9e866e44e9e5336369cffd8cc3a36cddc00000000000000000000000000000000010d85f85d6242b63f8421e92f1c37f64d33fed67e0cd3dc4b2b2cb4a7fc7637f9e049fc959720eae6d1f452159d48b78def52379c8b9e7c24d971c3456b85b51a63ab03761ec66c8dfac1018833e05940000000000000000000000000000000010889825c752d0ae8445a1d0f3510135b9672c30a781788698f637c2f535e35788d76492edce8ea091223d016b5cc141000000000000000000000000000000000577175035c86c022e634ccc9a5beb96a36aa068cdc36e5a4fc2028d5dd099c5296d30a916d3b720f2e051e7d72e4d490000000000000000000000000000000017b46e49ba08a0abb9394479d693d8097a140094d0ef1d1ba7761fb601a686b0b2b4d49abc2e393a99c5cb760299992b000000000000000000000000000000000820f8e52c1b09986a70bff04909b044f671c3933de43a6bdfcbe3712310274ed880d7adc4947490c7de095ea651e578b2225be6985b9c8fa59a2890da56427612a4334937761e24a33d37f0f951a794000000000000000000000000000000001776b92f683069fdc006904fef8e91f716d9f6bc46306b042228088545f0e11a41b40b60722d4f0483250391febc0ed90000000000000000000000000000000010d5052ef2504115e9d9d4ca81c7080c0868cbed605dc7673f7f94f5959c793c96aa5334175e58499102ff76f974ced80000000000000000000000000000000011d1e719bb69d842df4fc23e8dc4393067d00f6fa8ee42d89b462a546414b91f68dda5378fa093b3ffa764b5fc63b1aa00000000000000000000000000000000099d0784a200e5d2d38773912cf1a49e813c871ede8c50da03abff58ec1943d2adefe66bd2feed1c57f5a80253e091d0a64ce8ad619276bc7a00cb49faf6cc84b917ae6b37654363f5719a727a220291000000000000000000000000000000000d7287adbe0bc3cbb35ab8bfe69064faa83e3e64d73a0c64d960949e10070081a99c35d1dacea5a3b9bf312745acd6e600000000000000000000000000000000034f1995eb8631e080378b22a51ace902ebc9da4589c89ab557b6aaf685fcc74ec1fcf95f6b9a31b7a45cfc5a1610c640000000000000000000000000000000009f56712a46c0fbc199c12d5eb7abd60e660e2c6d437007c34954c6234a0496ad0adf68cf759f8ea30980c9a78175e1a00000000000000000000000000000000073fae1cb78c776188190a4d7223f7cdce9a36488193dc06898919ef4d5136099c3185d352028760c753e9eebb52ac240b891d638d7e76e0dcb230b1f9a7c3b35b35193c43a6c86f345f5a5bc9c708f500000000000000000000000000000000019944fc459fb601bddf10a3a7eb55f34713d396c3208a10089b8f21f4bf0a5e87e95ccf73e0bd90474d3e043f37a72300000000000000000000000000000000158445bd2b6d396a390a0bd5e26256587f980eae84d7a592b2b4d788c452d312b854427185a770084e1b4c7898962e50000000000000000000000000000000000ba44a1b912645354da7d8d9c694b1d5a9ff2d642fad31975171deef3adb0f8d92b2d3a8bef6ecbe0b8e90470b3938d00000000000000000000000000000000012a040a72ab035684bfdf57bf473ff59cd1ee01ec949dcc6066e5c8afad775ed55123859cdd74c7016a092bade7f991b571175eb91888222085fc2dfe0f4401ed6a1fc5df86c0c6b8e44fba6454305bf000000000000000000000000000000000317ca8fdec8c7c56fa3812157f9ca8e9bbf91013dfc7052c0795a04a1b4649b2147d9cb1a61f2c114a705e5133729920000000000000000000000000000000012b893d50fe5ea2eb528d1a04bc8596b10d4714a0dc38bdd5f0a275c07c846970106c3f7b5686685f5c809e93c57e2ff0000000000000000000000000000000014f018a0d13c4c494f4a6b7e836f0f2f46c4b7975d91adb93616a0555910f53574add03b905000f8492465c9b5488c1300000000000000000000000000000000146eb4ef1103b525dfb5c31bcb98e550245732fa252a814824258093a2397d1489df8ca0228d4f5df0a00d473d1566c454c9e7f7ca14c66b8431e25e6eddb4f20507d03bf124eb607957ca2f43a0c17b0000000000000000000000000000000010e9962dc19aae8e92abf32fb9c8eac44d77f587159af4e3b3a080748322715a958d953d3c057999839a47dcc840076a000000000000000000000000000000000ccafa9761e654ba54a46afff51384f1c6331264082e23f94fffd6c31a1b1b568a391eac79417657f40ce2fc9a154a670000000000000000000000000000000007276b111c94130b2608827156021815faf2be29ae42c454f3e2f95de98d2f5b98cea3eb18335a8fa00e5464f8089cf300000000000000000000000000000000053550896e867e237086098f4493caa2520e8c97a05e14d0ab7012d37b7fbbd42a90accbf0fe2ac99e78ccf0be5c9c58000579e1ad83015c8f02a9db5c38d0220368a80b309ee45bb952cac824817b6b0000000000000000000000000000000016b5bca8537059362147911da9e69ad3ecd3b4a7c43ee7d6d809f46c74c16bc7d69bfb5d7c727b4d5d8a356a0458b59e0000000000000000000000000000000010f3a7eefeb3033a733af7d20c3c5caff4c409305de8d71e08cb9cefbdfacda41bb975c92c5e5f2952c3c1e2bc6ca8cc00000000000000000000000000000000148f5b2bd65b71184ba6974678f709c5f9e3f1a020e3d4bedfa5f5f66478adac47f06ca2626c4a759b5eae09756cfe49000000000000000000000000000000001301306d1259059b5567154ef6e4779fedf98c29ea967ce34b78147c5730f202e1c12d5b5094219bf85fa62834329b45909a45c8b78350e3ca21697e9f56d5fc8fc2a01817b78a7f5daeda487768ed1e000000000000000000000000000000001741f739459f5d462fc9ab55c68101a5a3f2741c05b4c3eec6959b2aa5e12493a19d1b33a9aa89337add642458089eb6000000000000000000000000000000000300d8b7988522706c0690da52d0a67ae41344e43cfa05d22feb91eb8635bdb970810e993e0ebf8fd63ab8fe3e048d660000000000000000000000000000000007c003cfba125692b88feba85e7288bf61bb25e04b1462f7a39b4198737010224ce4b73a320c81b1f70119af34d381d1000000000000000000000000000000000a4870c9de67517f4353de23af21fcfadcfce55365ced33a61a19e5de52f98721b17c6eb382970e7c4acd81b80a7bd2f6d4e2277da617f0ad530b6209df6264e1288122b1b4d92da04fe334be17bd8320000000000000000000000000000000002eef52fc72d5aa0456c13808ba548cb765e11cd0bfd0599544793f57c8a27ee90880e6577af1b76b3fe32c4e71f4104000000000000000000000000000000000ea99a4f6772f8114cfb3ae9dc20f11a34880a86088511e5b7fe521d50470148b43f866eb5bf4f67c523266bb55117050000000000000000000000000000000004bd802b889e6d18df7dbd65f39a908cf5889e14be51b5ebd423ccb63e4e5b35e429eb0d4f384b811b47975143ea2ef60000000000000000000000000000000018dded357c546d709beffff2da0c08e8059c720023234c7b53d0ae85750b3e166cde7faf340697b546b8dd7c13b1ce7bdcba6bed6b8c42240c01df5fa0ea81dd96168c6d98ee9d5d4653edfa5172eb28000000000000000000000000000000001405ef521bcc60c55f8551fb2e2aa7b10117b2f96c03e8535e5bff48ae197b7e5fe69a40eecd25a67f430ca02edcc9d2000000000000000000000000000000000477d85a7dfffcc5a2a1048205362ec42b268e5fbd27ee7c8d4ca77b5c9db84dba482bc4b164f92db2c15cc518b3d32800000000000000000000000000000000060988548ede00aad3682fe827d1e993ed1cf118bec7cbe6f69bc160f030bf87c299d40047a4fb5ee27dc2814649a4580000000000000000000000000000000006b9e0579f82fcb8bc149e40b1199f5897ea48ae5eb58abd2002c923efd0f5275d24a579bd904e49b7447c4a03e3fbe423d168e01657e5c2da89a27e513bcbc6620b8c6082bd39880619bfe2b3a7317d0000000000000000000000000000000003cde2bfc5a865cac624d9018c37c1b5746b5394597d79c171b25f84d5fdbc76bb90ba5cf9db14b3b8e62ff91cfd79520000000000000000000000000000000017596885262075e45db62ca68ee5b99d12223bd476e36ed4ddbf5cd56a0c6e9db5d79e7f95b96b1bc323d7c9fc5447d800000000000000000000000000000000018333858871dd41cddb7ad2f179f1f341b2ef20bfc7a1d3cb235e3a1a181e0da7251911886f0788e0f868e16520c5a200000000000000000000000000000000098ce44092980cb14e89faa7efc2906051c9a51cf7b2757dbffa49fafa3a9ba145f809f1212c27aa620bf062e839f83c2a76fafc5e8e33852bbeb7ab8229305be84f5474427e0c6d2ed35c7bfe99faa1000000000000000000000000000000001180d554fd523a51e0decb92e0134c6064a17dd3aa7b11d590b9b6022f76763b1e20562da21e836e65374efafd78b77e000000000000000000000000000000000488686f793dde899a3f4936f07f9eda7918450966ca85b4715d6fee978d9d091bae1b5d2d04943365c076a849b3359c0000000000000000000000000000000014661fb2d305ec9e63d63e9951d0f081aeba99972b094c922d2797a1100759cfe150812821411205f563e22f01ef29c50000000000000000000000000000000013dd681200608466853cd3bfd20f146a6383151931079654962684d6c6fc3bd6900bb049483c1ca6d2819da456f67e3be3c7e4e95167faed1391e269785918a207490c6d186bf2537c02e52e414d564e0000000000000000000000000000000016c8c7a2a1a76ec05770f2d6c8df35003104c034c76323fedd49663daa759caf2f4fefbe8d44b3abf1dadfec2a06cb45000000000000000000000000000000000837305004aba2e322ae29e8f0109f1c756a44b21c72733019e63ff9886a639464090770d12d35553f0002ad028332370000000000000000000000000000000005c8f82ca2d4f6785e2d76ca3a3d1ac67aedf78e9ac833c52cfda6289e6f5d7a83befbeaf753abce12376889caec312f0000000000000000000000000000000013595cdc9181ca70845c613663367ff774f073774688dc58edfd0c58de5ae12df5acd04a673b645371940d7f7e1601045d335e3d96a9b25be7f3916e92fffd75abeef5b91a1ec577ced52a96f6a9b10c0000000000000000000000000000000010f1b8b39ea8ffcb6a96bacd1c00b413c93d3f8da64dcf9257a7cf0264831be23ca63ab8d3d1cea21ed8d83ecaa3a0c70000000000000000000000000000000017a9030fbee573cb71330007900723f85e9e82530283f713f72e68c1d9a5ff9552d0da469a4f38b66e30df1514f922a40000000000000000000000000000000018b9020986a49213d4f3b4b052cf2fb65f82b9bc2051f20b399f2784b984ccfa2752ca576d352c7d65ab218bb8d5df870000000000000000000000000000000015a375a3711f5e9f85ad7266b2d307cac09ace9ea36e149dde5e0d5acdbac3f62e1cecba8be51d88f2143c3070eddaf0fa563a70780837ffcf9a84456f0b4f6eda0d60cce6a8538ba10960eaf17362fc", "Expected": "000000000000000000000000000000000b668f602b9f56182b74be413d36b03d2266d7165386a7f1f0d25d336d06d2bc5659e80e54dc71f153883292df1cd8940000000000000000000000000000000013151d305bba39734538fe9a2717392bcd134ef1f8c1879740c8cce981a2d70c94b23f1a71a0596e7ead55a55eb186c80000000000000000000000000000000000e5e7c268f93d8a9d3ce45db2a95be906483aefa3831ed2ab2aa357eca0ca231927c0e5031daa200784cba33b96e51d0000000000000000000000000000000011d57d9a9123123f9fb56e990626346e5c76bbd1a4b3349c3f7bc44f05a899f9c4dddd67ce5a788f85b4fb172385faef", "Name": "matter_g2_multiexp_49", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006a7946b50749147573991c91f13cdef4e9558be37736e3d990c5750d31ba9711721b88eec529ea4b1dec1c935fafa9a00000000000000000000000000000000078d8a565b7f58b915c220882a73b6aaf100f2d54cce2524cc3a80d9b526c3058903668d17427a617ea045c3322ec502000000000000000000000000000000000733c6562cdcb28d740c64f50ee9d204af4ecc8de2c1719fb73c20f2580fcf01e1e494faf4386764e03920a4162049fb000000000000000000000000000000000421365fa828affe963d145d318065933d4d865f2a3d24469ab0db66dd09a574945f8a8b622d079a7ce1c6fb6c795a8f6e2ee781da12b984e7a08730a60f50c41cdd7c7c8b3f1f30f721923ddc34fb79000000000000000000000000000000000a4fdc68bda287bd819ebb0a296212ddd19cc76b042e134f1637c894ad64bcd8431392c9791f2eaaf94f6c8d189846760000000000000000000000000000000009d974fcb46fe81d81d62b24b805ab5108c9450e162454c3260ecd0d5356b7c263be5f78f6214cc7254e461166910d23000000000000000000000000000000001081fe3579cb4d8a7e7d43ca8cdda28e1f9ea8df83c6069f4162a2a0e68e0d5876b283193649018e754c5c8fef101f53000000000000000000000000000000000ca4faaddc4d14a6648e3515a8b9028190c17f771c7de086fe4624a3008d7e6e374c967f303d9511b9da1a95409e3cb3d51e0b65be993ddd2892ab8f47eab78352b177be4b3fb68f47c65f5c59fa866000000000000000000000000000000000117318e376f2c130e5bca89b3d700fe76e9603adb22a5ef353bb3b5a8f641c85deb4640fbaccf94e025a59fbf2a41370000000000000000000000000000000000433428497ed89a43ba07d816df224809a827194ca899924c3844650a3800952cda8db82f2f8e513994ed9893fac747400000000000000000000000000000000064889f1cb7d6ab216fcceef7c4abf89be14ef93be2d39bbba2b74d06999dec5ae1941b507709d093b28e030700cf866000000000000000000000000000000000957fcb8658497802e78b8250373f77acc4ec47fa2c87e78adbb2daef70240da640a7945895940f76bbb80bd36b4ba24fed4dd284df98923bfc3c41496d6e64a10815a8c474275e0cdbc9ed26e92b0ae0000000000000000000000000000000013f9771c105462fb6b975b0b2fd20d0accdd2d95d879c8019b08db394cd785ed9f151d0eb1adeaa63bbc2686d1172b0f0000000000000000000000000000000002062a5f2db0a01114a1c6e8c739f80f598f4e905952101a244853078298eb443be6839b59d4f0c7745b739cc89ad8220000000000000000000000000000000015b5485439f1b94fbb3a8f5ac6197f0dc0577863f39c44b34d4c5437b6a82a704dec17529654b3037a9ee1ebf14c8d8300000000000000000000000000000000154d750e2a660205812d428cfe79aef4e1059f4e231024a665889d112af37e6e17e04cd7c926b6240bf2f616a1f572dd7c36ec97c1eafc8a20a772fb7887d75568047ea32458b9ce74ad9ca058129949000000000000000000000000000000000231223930956bd2d36a89a0a0a47aa46b4763919455ad3a3581439d25a82c176569698fd5ca2b9429793ebb16c98e50000000000000000000000000000000000b5dd675af51c18d2dc76e3103da4409f6e8c1cc719a622d4a33aaae3f23e529c78b63c55b67fa999bdcc7095a4ece300000000000000000000000000000000010c971be55cd02e4c97031d3b25acfbf722e47e5179beb26eafaa72d4bd5f47cf280a99e0c3c4cdac05bf1572d01fcfc0000000000000000000000000000000002c1370919e6445994df1e25ff4a79c8cd8805f12e5d8c781e58f04dff68a97424b35d162d875ca2b3f805b4cd6d1fa641b2c0354d2f7d92b05043f193b718d78b457ae76e19069c8e1c2b77d7999d6500000000000000000000000000000000169938b4d3c859f97a0627bd1a83fde725eafb7ab77b22cae06d2a776569236d834702081e78d61386999c938c0259b900000000000000000000000000000000091e922f00828488e324f9fea652ce1edff83d9f479e843ed4bffee27805a5025e7a150719b354b5e61f381ebd24d4ea000000000000000000000000000000000334ba8044d7d47795b59eb089502808a7ab8f18e3d5e1cc49acdb5020b3973fd21d6d82557afd748dad88e45a7623730000000000000000000000000000000002299bf949ef249b5057c103ecd149444635b4f636a2fd0d073484404c1ff4ef71820260ea6529bee6f5b07f2ba94de35615370a76bb0a5f64d61b97bdb045b9669f6a0b7644b101d21a50483d8b04dc00000000000000000000000000000000076ab7838db87727fd653a3b561a2a5594518f296284bc24a7d215b1fbc0a6492d425078fd98f92a414dfcb3c92cc1d000000000000000000000000000000000022b71fb467dbd6d9b130763350bd06f52d20ff2cbd46cdea5e8b1525fd73bfd08f5ff171f9fa28050e9a3b296d3e9e00000000000000000000000000000000007e917cef0195fc589317d4a71c14022867dbc0db26c653052e2e382d0dbebe67a0f582bc0a27dd1dfb4703c545d0da30000000000000000000000000000000005b1d8651b86a403ad993c5cea4b6b82a0f8a9f8a59d4b94f10e68e9538a559efdde2007736aa9d04f585851a89af88fbcc38cfd3c6bdd32ed1d583f2bd14e175d61448c627f195559b751aab1ecf7cb000000000000000000000000000000000653c5f5b2d97239821d173036929dc716e78d835a80af55868dcc3e218bcebdc2a052d31f6a573572d13f3bbb14f241000000000000000000000000000000000cdbdc3cf52239a6d4bdadc273b00924de8730c03ea82bd20ec1f04375daa4497fff3a1726269a736706355e72be83870000000000000000000000000000000008e0285b177fcd768d3519062177fa1314c4370f872eaf10f3e0dc94e716dc6a67894d887f40104552336cbb5ed614f20000000000000000000000000000000000638db8269ea4c2fecd5b45955609ef6a1c2c6faf6ee5a8d777e0b38f16d1acab2da7fe7b6f6ebb315ccb345835a21d94c41471a2e4edf0f688c2f032036d41ef5f8a966871dd099dcdbced8b37e1c40000000000000000000000000000000005b4f74cd099eafa6ae59e7105873d4a46e8e5985faf2d26ca564125dca93b1c48187ed7afa02cde8b52df878e1aa618000000000000000000000000000000000cda7f9eeadda16ef757ee8a98be147d374d3a1d40790d20a1ae42c9ed38e4fe22be76ec4f807cf93fff5c6efdb50d1c00000000000000000000000000000000121219b0b0d236a89a857c02249cc04c22299d041d95296dd235b3639416337f5be4a2ebe92a50d192fb748d5d4dca0300000000000000000000000000000000112545a4677ca7d60645cb8bd98689c4aa85a68bb62dc68c0affca5a17ecf0a08fb9b91589d08712b5af4aadf31caad2dd297b192f1c907914ef949fd27a5ea5659aab659b83239c4433f7a4e24529f2000000000000000000000000000000001342460712b73ca0ef07d953c32d280a3441e108abdc2d133265160608986481df3563c5dca20f209ce078b13b49707e0000000000000000000000000000000003580a5b4a7f6d6e066ad9073f7105f6cc1ff35ef5e79a0aba7f48ff2b732c7aec72cc9c5f9233fc9c267d8aa37ac17c000000000000000000000000000000000bb7f32db8a4e341cd9f8dd3b5677dc650cef675f0923bf2e5c8b84c33d447daacbf68631c2388eac5698495e1ad5a3a0000000000000000000000000000000015bf9cd1aa585eda2910128f2b452569abc1c94bc8bd308ee92b6c7315a56fc92d6cba03334bc36c137c14eb1f198b07d30fdb174a3f5c06b78cbaee5b6e7a4c90551083d78c5164de6bb45ee5de23c100000000000000000000000000000000091bca266255d692cdfd10929802d79b474706d160033495decd11cb0758136ec3ae7fd4bb99081e44dd7f25224e009c0000000000000000000000000000000001fbba1ba796416ac22c92f3741e3b268d89fbf0307edf0f25c7c12b5cd230c41582ba69465686ffead9f8363dc0c297000000000000000000000000000000001139590315fc4d81e3e747a53e63ad856635050367ffc143c1422e324d5fe9e4fb90631ff8bba764a87b8077b571aa0a000000000000000000000000000000000dcbba28afd445a57db762d08338a26980b4efbd11668e4050d18234ce35a909d6b563a5d3e8e72892514431fabf0147aafc42f7fe6854866cb954367fa65c8072bd1b60173a2d45077421d6e25f2bb3000000000000000000000000000000001322b1f1388a9dd2853829bda1a5120250ed08f07c84fa398e59fa2577454f38f0a76a1e8db897bf15b4b50ff52a847c0000000000000000000000000000000017020d7de1dd424de53992c168d924c42f26231d184ea3cd9cfe64ad9c82ad067540b2d9ab18b0fd28477ac792a80c4a0000000000000000000000000000000000fabc0769b95e6feedc2165bd6d324b7d16247b79eebc1f09d849792255136538e628bd6ad9b86af7bcdfdd991fc31000000000000000000000000000000000144f39f792bf5585f4b49dcd3fcdbb61cc7ef471e08af4c15cfebb855f0ac8d5fd057c9486e53e8e1ee4f66bd5e943ad106da5f98d5e7cd9f4a1c8d6e50ea2236c2abdf1e08a0eca54555a59bcadbc6a000000000000000000000000000000000c27ac29db98fe3038fe5f537d5ca6faa240602abe11c6f530d9b18d763d6dda3fb25f9538d316e6527c114405ae54f00000000000000000000000000000000017ecc872183413d8065a99a2d1a73b70150e2c1fca2c13a731a39b52aebc6db79772e91f115a63f7b23e5fa231df697a0000000000000000000000000000000016b9715ce820b619274202b52d7e7bee9a17aaeb06c2ecab8bc77c670bd4c714789e4478178d94d2aad57e7bb0b7a4040000000000000000000000000000000002d0723a3386248d8597d2b63289300de6a16011a38985170a1652ff81ea70a78459b3ef252cc5ed26ff1ef1ecaf6a42c971deeba2f757970bcd4f5548a2767bd6c43e63f4c5fc4b157ef060a1f45aae000000000000000000000000000000000eb1ddb7306d8d2858fb57dac71f67473b813f37f02d73b17f375be86028176cc1dd84347f183cb7d427b861be34c3d70000000000000000000000000000000009a8811ec77eb21f2b33a591f2fe6d7b74b40c5045ceeee275912aeec664838f332bb49bedcd958ede0af0d0232e76ed00000000000000000000000000000000156e28ee3c40c6f18c6059e06ac8f7b39fa23e5962f640ef3afce13c169346a4c8e5c2bcdac8fa15921a4740cc5a0f2300000000000000000000000000000000084371522a6ebb1925c8fad3f20277c34e657aa71abf8ed7d323a10c14cbbb1a9e0e54bace32eb845e6709c1c58afc34a5262a021977dd79ab96606eb24a7c5ed650300dd68bc79f4b8378f58c6eed49000000000000000000000000000000000be2ef9ef38a5dcb42ad31b1415c8eceae625850db4306a26a0598d4a567936d75b701c81793fa7b42d158df2dcb0d5d000000000000000000000000000000000851b82b59fc15b89e33fb618c56d11a07116ea35850583a07066ed97b8a864f3766c0cf921d007a6cb43931ad4fcf8e000000000000000000000000000000000ea8bdfa3c5f000d7cb1b5cd69537e4104daa15ffcec06f40a91b972d8011e5fccfa911c55a07383cce6760c145c39e4000000000000000000000000000000000652a4165602978004ef702103ef18e8fe7decab1522a76486c742d29103e3bdf6dda2d3cd64ff1b5d5a76f4823bd363083b3720c20044fa41712039b6e9e776197391ef393c0935a0e9990fbc1b7a4600000000000000000000000000000000015ce5b43e1fd950b77e2baccae8c99b82f38bce09989fdc5d402420e7931a38b7fdac5a254b0cb9bd8fbb488d02493b00000000000000000000000000000000018c5b3ff46a04ed114bbf56399738e5d594ef8dd1d5e2e8dc23a0097893be3da4fa4662686a6dac04418fd2d344e36c000000000000000000000000000000000efa3e970a5cd0c7bdef6a2df3be9be18cce63c10c331a18d628bbeef30488ef73d866f3c8804acb3bd375542e99eae6000000000000000000000000000000000e966d9e2f2d47df5d661a89fafb6d4518fa1544ab7a56716df511cbcca99098f944a981c9da569cf95debb455842006d6f846581848f5dbb9e8d220b881d0327c4f3f5d4b79fb2c4dcbdb9bcf44b02d", "Expected": "000000000000000000000000000000000ef06b515addb951b24e5d61f6e6eededf5f93f9f17455e1b563f187f73394457b3b7c1b90ed454218f8782d2bc848be00000000000000000000000000000000167398608a87490fd17506166bf54636aa4dd6d3e8c4d42995bcb0262268eaf2a6d828b295434f45e3e53703aa67cdcf000000000000000000000000000000001602ec6519e4987a052f97eb222f505e241d99602c08ea9c41bc95796675ebf6a819aa0bf87319f29dfe47f45f3c8c7a0000000000000000000000000000000002ad4291ece7ea0fcc9f4440e88eef693b8dd53060ec847bd27d74cf71218eb6210a71895ff1f1f4537a901090f14de5", "Name": "matter_g2_multiexp_50", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000129cc9cf82aa30671e969148f058a0b8d275bcbb1c8da66e52998d9555dfaa075e2fcf39fc18f305940fbc972cc5c0c0000000000000000000000000000000001252482c1419ad72229a00d90f1c09d464e896f47db91e9680efe36822e99e1ca7a2b5ba8b17b5929fdbeff8993bb18e000000000000000000000000000000001287d5054bf5db038ec2f7b7a3b79848fcc8ca42f9e19d5e21d36d2256f97e0edc2608d19c17d3714024e1e9e86ae264000000000000000000000000000000000f6262669e30a5db67550cdce8a4611b9501d02cd4e950aeedd1c87c4f0f63c74f35c802dafcf91c988a154dd690103c67c44f7c8513472b51f96d526422bac628aad4c40c521cd7cf9e86eaf92838fd0000000000000000000000000000000019cccd010df3e668b1c3ec053e76c46e45d01a4fe02eb074e296df2a48e0e4eb647b06c40cf64a0048a8fcc2b0cfa6100000000000000000000000000000000018e07bc50657f3bbf736c38518933e91af29e3bafd776243296cca3a1d975116e8b428b050045a61069adb23baa22d3800000000000000000000000000000000154f51badda1b828346986264b01fb1be4c7e9b570ab63a5eb15cabe9412a2f9bbc6d5111c638ff5118a4f6d08ed055200000000000000000000000000000000064d4e607a8994c0bb65770a14a14ed1b68c766ac2aed45a44c0f7c7cd4c3ecdfa077206812cf9b24e35021060a3668d2d6f95d4b6216e4226f78e4fa5011c9becf98fe45a17dfd740fdd0ef36d8ba94000000000000000000000000000000000b9bae5f720d9bd3271a71d751e4c35c39ad30fa8a67846107ff769c455e42465b2a39dfa32861634d5e323878f56f4f000000000000000000000000000000000a1077046cf5c7a66452cec2193ee21c1ace50dfd79f707c9297737f13806dc05e9e1cc5d1fb4c87b250ebea5a4ca6c40000000000000000000000000000000013e1fbe1a9b5f2ccff51120590ac0cb00cab502726b43a6fc12459e27bad4aa41537d6f3cc94a81a170998768f6a0fc6000000000000000000000000000000000a02c551ecec1c7a415256caaec1b5485a42f9ca8d897cf26546ace1f2bc8c2d10a353b8b84495b8dab5e3c60881185a58c25d36216b811ee42d0ba629ab7a0f9ce7edd7234620c28e37bb3df3f042e700000000000000000000000000000000021b9ab3ad614816d7006efe688e1ae8cd99b0c4437d4363e557642a7cfda2000db6503b32db36b6d1ffe40d967c5efd000000000000000000000000000000000b7fb0ddd9eb2be9cdffaf8f8c593a9296c4c7deeb1c714c11863d71dab1e6fd309b75c41e25de3cb6089726b43427f0000000000000000000000000000000001277065ea9d208777d0fb7a6726e11c8330f0b3ed3c6716acd559aab19b2fdafceca8126c9facc43b9d80534c07035a20000000000000000000000000000000015e8c12065d601dd5ede75bcfceb7300bf6f9fbcdf68d2f093b7654d80d3e565135d64137dc401d691a45fe052f58a6850a5c6bb6b87fbe5ebfb0d182d425ee173973c6f2085c556b0fe60219b9f3c32000000000000000000000000000000000484c4f9652427d0649c33e93d666dcb15bc56669c00980c53357ecee874bcdbaa016236df65a4339dfbd44e4eb0823c0000000000000000000000000000000013836a7275c29c989891c94e756cee9d6c54a8f634fa570655ee44b7c1e34137edc33323dc0d1f3a0218039fd6f7013d0000000000000000000000000000000002e88c7d5fd87e97a0de1be95021821942a8004115fb4fdd9ad26b7e0fd171f9c7e6f962eb179bdb95ef960cf9396372000000000000000000000000000000001636e351a0ed1a260ffe0d1355e6da288792fc97a7310b040cb9fcd5c550d85d90572154d58a9847dd5a8a06456bb2e43b4bdeaf6643ed159f4a3e23c33ac486b33e1edbc5a097a47a6c2c753e5299d20000000000000000000000000000000007579785c14fa012cb5d6c116d34dcc15dfc908a29e90de3bbfb8c9b44e0b4258644440d7c78d751a007c10f98053bd10000000000000000000000000000000009f023538822ceba0883a0e3454121dafe8e5e61d4754b54e6417c989efa998334641d458591b3076b615937de065cfd00000000000000000000000000000000130fe7f2d5e0ffefa67ad3378690c53a6e68de5504f3691de0df3a24c309619bd3a345bc2bec4dcfb4b77255cbfe09980000000000000000000000000000000015bf85ed997eef4d97a81f1d75825bb4409cf86b8c8e5f4368cf1e4c803f9e1e23a2a96f7b0a08e5cff55a78761ebce21d18596bc392dd0b71e1216bbb20a0e5e2559a46789c36a146cb78c5aa8e3921000000000000000000000000000000000a95597e4402bbd17c20dda088f0134d42f14443bd519b3511b28fd8d395a0e50758386498388ea6ad0e7634587336c1000000000000000000000000000000000079f348d3de505875c5192f795cd77e2f7385ed447b06f2dbee18e85c832386b201cb3eeb21aac3f258d2c4b0434d48000000000000000000000000000000001895b1891a08ea42eb1f68698abc20394ffd66bf0c32979668950bfec5cfc8425314eec2ac17ba25f29133a8becc9f5e00000000000000000000000000000000146160336d881b24c6258a3a86c08d346900680324632b6d5d4582ee0865a7e5f2d01677e5e49c5a4179f8382e49d1566fb3669c0789ba6a5b00f14c14fe2edd15d37a742c9e36cae9ac010e632d75a40000000000000000000000000000000013cadc6c394efb2f93e00f3976dde34efe75adff34bfb6f5e1a150b79bb5baf6bf29fa149581fda48faa68653cb61e300000000000000000000000000000000005fd25362d87f9581a202b186d2786d2859faa9966a1ceae747dd7a48749abd424eb9813e44caada0e456ee8bd12e99c0000000000000000000000000000000018e6b279e2b545acf1da29dc0504caa5982522546f83d4d3389e1fd6cb5328d4a167926a00ccaca402b3a3cdc67d757400000000000000000000000000000000089a9992a36b476fee21abd50977dfee01d7c91b24b3e26d7c15b2301352069dad920f0ea93a3e477a48029eef35605f06c2988dd6b8e9aa116eea4e1f63dacf100019844d37d163c047567e8e1188620000000000000000000000000000000005200b78dba7e423bc23e87c5937b464e97405f6461d05bd9d1d0fbf8f3c8e64a39081f9e43b4ec416198dc44db897e7000000000000000000000000000000000bdba1ed07c4a570359863a1098a73830818b3fa5b222316a3e0692a4ec65e59ca6b4bf5f72f8c1384e73e807d272d6e00000000000000000000000000000000073fa3eef473707b6aff37fb6f829f0fdb7ae808e85ebba4d4924a185c3656eb2856896307b671080347cebc32e958bf00000000000000000000000000000000076b56330f07cfc0ab34e98e2fa0ce4702b296a00f6ffee07c3ab523fadc048a047ccea7a9003c090951e4ef698d14e5fbf8322f706b1972f73fe4e22a3dad29c4ede09163561b2810cfc3eb2ffbc7ab0000000000000000000000000000000007252747c8275f87b21bbac4071c1826d166d14e6205095e5299315d6b6a85aed995f9ba59a2163ce2c51a8e60eaaeeb000000000000000000000000000000000460a000fe29cca24dec469ba5fb729edf3e443bb032d488cc99102a614a5251915267db003dbf395132d815ba78f262000000000000000000000000000000000161c01cb4d0942faf2303c108604babbd4cabf5d3d30c13d7db9428a445c7f72d96a7405e22e4e451058a94e20068720000000000000000000000000000000010ccf8a8ec4e6515b20e07057fb8cbecc5defb87480f3e32a1bcd0cfe239e00daf6a390c4815ef6b85be1f07a4c4bfbc4a46618381ba6b991b2edfdeafa67aef1cfea066fbffdba24db25385963326bf000000000000000000000000000000000e6cf781162502d2a758d0f96946bab887591b7c9ec9f67a1b0b962e74ee514e84c14bf67ae3c0a9ea2a3e472b7ef59c0000000000000000000000000000000001542b4e97f1e8a64ffd51ca43137b0660f897f6b3d5c6fee598fc4dd03932c3658ea55e1e9e73376e51df278ddd3a3f0000000000000000000000000000000016dae882ba240343e752eac68122424320d1acb1fbc4bd26c3983dd91325f25e1b1f06213e0e06c142997a13fbeca597000000000000000000000000000000001138b71c95d4de320f02e68dae9bb0de3e5b317cb596532c5cc18ca588cc8566c21551d7d55d685591126b9d9e466455cd05fce871e4ff11e7a4e834061c65a0aab7bfa8a0128d460a493337c6e63ebf000000000000000000000000000000000904f6a09f3a5f5baac902c702b059835737c06f62c2ffe9101bac32f854e4d72f74031f5410a5941612b1aaacbb50920000000000000000000000000000000012f39e7022150b2be12cdd621ae23525581405021b21cb9e55972724a22b1aeb2e15b135ceade132d3310e050e607f65000000000000000000000000000000000a92b1daaf23524904d74c3f149fcd2c98e3a4c257113533e7cc59c4656b785aacbf0ba6b9df0dc17cf7c25f1ca698c5000000000000000000000000000000000a20a5d7c0aeb16ff498f46bf05e512784d120b9c3c8b2877411852d7da3abde9e83a6d00213bf69ed88bcbb051a486daba9e37ae0dbb733af820743d8e307fc02a3ce9b40032b16d0e9466903de9caa00000000000000000000000000000000153918807d7da07ec7014154f00a558ebe0d5fb48fba4c16488d61a826a1eec28e3828d6744300c04207e8ff1cb61211000000000000000000000000000000000a755480457896c5a3fde35658e73fae821151c43fb92e9ffedcb05fabad37cb68aa24e029fc33a2518398d723c4859100000000000000000000000000000000148798bdc5b14b90aefc38946db93be1754f15d78762f38971b1e64a53fda92b96b0a70ca2548baec882887ae7f636910000000000000000000000000000000012299fc413dbaa77cf8867e331bc0602c4fb32fe44a150217de9e6391374a9ed83781034e5775c4933e13cdfffd25a9e6ef151662cba4952416eaadebfe5e0fa0ca1d31380e1540c2d5e0181af9e317c000000000000000000000000000000000fdfcbcce1603198fa344487d2d4838b3ff23fc0a73a76222707d9f8623f0b87dfc816be8717b0b12667bee460ef40f70000000000000000000000000000000015036dff68139419db619912e2d19b7d2a2d637fbb8bffcd941aefe2eb4d24c1f7dc32f4f53d4cfce67785e7c328d6c4000000000000000000000000000000000fd575be9bf54128a9a1cbd366339c993ced315a840d60f8b77e035352bf705c01a9def713e8cae3001dc1062cc0723b0000000000000000000000000000000004015ed456125cf0f46fe0093b81ff9315d955d470ad756a9303f548819f339e137305c58e6f4d8db3c8bbfab90718d4f0a3851bd52ca52919dfd21efa6efc56f6dd5060ad969360b1a731e8f38f0f5d0000000000000000000000000000000016d31e68cfdc5823970c8c2ebc53c3d4517792c44e90c10f920a819e72e4a6966c59a691b905c8b0b612065c56d86ca40000000000000000000000000000000005096d516e416fdc0df552c2688c74f1c067a3e5e7fd782479bfa468096e6ee3e601bc23d2e38ae7500325765483250600000000000000000000000000000000092c994e9dae287bb6450607a4263bcf6267f0f66ba3e63436292af7f6bc8e4ba794a12792b6af49ef59b5fe50ff6d3400000000000000000000000000000000175a645988f33612e969e1d91b2c30e47ec655ad655d89cd8dac151c3bd194cd5a8c28b498b1cc2f2966b7fc37cfc8c532b41960417047a2258b6e9e228f3cc1130b296cafbb75f58731a81fcfe8c83a0000000000000000000000000000000008d09ee15c80facf7e32b15418fefbf7e80400acf37f2a1bc6ced88b1591bcb8f86b45b544646c5fafa71b5b103b927400000000000000000000000000000000060865ba68ed8fb3d0a05779c278352b22d4244edb7add23d985a2836d2772dbffc3c82c3134916e9b0900c9db6ead8f000000000000000000000000000000000dce53bf8aca1ed44bee47096dd988689c1e32e1e65a5f8dbabab7c4edba866132ee2c036aba5648d0dafa9a26405fe30000000000000000000000000000000003319995785be720860bbf48692d1507185d898187993865648ded74d3aaca45df939c6dd986db42a51bd13579a55b8f71a6f7f091a6a21dbfffcec2eecaa22d05252b60bf91b56811a833dde3fcfde6", "Expected": "0000000000000000000000000000000010643af30c3cdefc30144c5d7cab17c9c54adccb3294ae79fe5c69376011c159be1e43940640bf5d9012ccdbc997e2090000000000000000000000000000000002a22b08904ea9ca99103a01caad745dc2afb7b6d23e666770e81a97031de921f9d4d1c04fa941c433b8cd9cafced3a10000000000000000000000000000000010808e5518eb6cd61eec8820b9f279dba2423b1a3677e21fe3a0ca2ad49fbab2995de1c5adc9ac867de79e3b40ffddf30000000000000000000000000000000003ce1270644d71e0055345c7463d72dc119495bfa04a818dd398d944ca46deb0aee8c7936557754fa18225522fb79564", "Name": "matter_g2_multiexp_51", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000059234bb6d1b66985b79e6a2c6cd158d37fc50ccd6e50ad2fe3b6a02ae2ad35b8b2be92139265957ea698441e780532100000000000000000000000000000000066adc7083a7f3dd75a8e431a36632dfcecc2527f261e961335bbe8fc8329d992880736bb41fffe41484f68c38fda61a0000000000000000000000000000000006aa0794c27d3f60debbee292c28b430c159cb2874b9467312cb857a8777058580f8a2d3b9bf4b8b732edb185cca6ac10000000000000000000000000000000000d81f222ed6acdf29437adf26d2b785535cd6d61b329df98be04114c3ae68bc6854e275792fd48de3eedf6ba7f3849a2e56b63fc6ba87cf021c2f92baec248756ddae0a4f070df840db281283a4c9b20000000000000000000000000000000013dab8066757b8bcce2c9965e600c31b792463623cd5561f7f6d55c5a52c22efcbe48b8684fc2dca87e2945765bf565600000000000000000000000000000000198a0594b5e606b18201fe2706bddffe7bee6c583147513333230715d18295714055b984cd3ff8d1127f9420863e3a67000000000000000000000000000000000ef77ae1e991daea1fe8338cf236ba959b22df4b24f00c6c01483b6956c609b805ab89712f80892bc0160fa3775907890000000000000000000000000000000004d30f5a866a100dfe469d4d0c47872245c4cdcfb18d3ffa0de422691044b52d2b9335682dcbf67aafa9275712ae3f5512a50af55f47fdaf176d4885e4910c54428c8ef433ea0cb1d009ea77783559470000000000000000000000000000000008010bd5fb5e222618bf4f919c203dadf9a7b7597bf90e16772020614481a0963a8e8b1bd244661bd33e0d147be7663c0000000000000000000000000000000007e21f548efb869a28d6fe39b999ab7fedae9cd6cfa531fe608476ef30c8703951839476811838608dac1aaf9cd87eed0000000000000000000000000000000006cc674c464f80cacb2156fc1eb680938cb38cc166a99f72daa50f9d2c40f10ff07e447d7bd5e59b6b22f0dc407dd8df0000000000000000000000000000000010b160c58ea82bc3904302b1b4fe83d1883efe3c8f52c4e05a3d8681e604eabb1b7f533e61c51e9a172987383506e7b189a012158b3c18e19471fca6d5aba5fd004a337d49ddef5db177da187c8cf1c8000000000000000000000000000000000d4f8372d1138489913654a7567735be1eacf8c7fd497c2216bf77a94f483bd4a7daa2c8232581d6815af9898a7569b80000000000000000000000000000000013676a1f72cc2ed80fa24f70fe1c52aad9ac13ad6cad1f519649fda6ea3787d86ea164d9ac86de96436e9db4fb4aa44f0000000000000000000000000000000003f7644f7ddc9276ac36aea5c36451f3d5d6e4c508932b16d5677977108f04deace5e8cf0b3b3dee88c328b6030f3567000000000000000000000000000000001953cf03effb7de9e62937572850e9fdeecb74fb4aa655de1abdc6e065920e6d2e51ff28880f33341443b5e6652eff4827dd109f6df1d9851dae28bcb9e552c6b1e1b2dfb331aa955d3d0b6c4862253d000000000000000000000000000000000c76a5bcbd2a61172fdd53b351d143bd30d460e398c9d4b7094a604ab2c0d46d6112bd8a5483c9935f0bf6d84df04b9500000000000000000000000000000000116b15825b780c49fb24617dca620e939e2528e10c49f34971736c82cd35fd3965088595deb86eaca3d3239c6c78a84f000000000000000000000000000000000a0cdaa541dd96fefd46b303b88f1dd4d24257b910a596817f1d946873cfd60ae58a88aa687ba573832331e8fc158db50000000000000000000000000000000016259f7285de159a2c6d6d8687ed348ab97e8cf329ea5de49b6d708b6da5b806bd012ca3641c50f479d85921e20fbaefca96785c1ab66cc5c8e434f59cc1ddf76bd78b6fe660f7cf74cfb79d7f2c7f84000000000000000000000000000000000797e815a98d362e1d7e2ac1fdcb477ccdec8ecdf340d7bded36856ce30e92b661669b38ecbcfb0896b2fd75df9b734a0000000000000000000000000000000017916c559db6b4b28b798c2027e2c70ba1b940212df8a1649b9f6087120660d698bea81258e2007edd4aa7d0d535bccb00000000000000000000000000000000167170a76db0783a8c3228f8246502b15d342b019fb44a46b514f4ba2de3ac66e435941adc3d91874371561870ba87150000000000000000000000000000000010097a585eb9264ea96904d8534820be185d8d9e4b1616439a926c0ff8ceb6f2bc082e5712454690c9c05b8018a996235aabd1fba36142bd768339e091b15b7f5b4ea609b57947a7187c498bd9833c2900000000000000000000000000000000025eff57e1f37903056835d1b4133ce064c86947f35859817b2cccf1a5c3923ccca766b3e0affd20a4a6df62a45c31000000000000000000000000000000000011158fce4ade070629162b2b6cf1924696f1f7776f3d623cfa3d54c66fc17fa0299c6650b709a1472262fc0abe8d9557000000000000000000000000000000001828a65fb90dcebe25413566deacf0677a3993b39d68854b264fe7807097fbd3106ac618545d3a6a42e197c65f0d2a7100000000000000000000000000000000045eb8164b6ec874467286dc3626fad3c01be61f6a8a88e5f88797978463db648a9b8a1e1a2589364ef2879cb5f75423fbe608fefa5472c7d1611abfa402d2eddb1e54542f45d4012db8ac6d1e5016100000000000000000000000000000000011847bdf2f67b40aac3426716391da488a8f0462b68bd35a8c1c762591e2f426f48f979a646a094bce16bc99cef7fcfc00000000000000000000000000000000092d61e408120b1549fc8d2174572eb7ed3f679327cb89754f326fa72fbff79e98cf5ad9c94c14dd86135e9aacc98b98000000000000000000000000000000001440e2f4ee2ba254a780a31b02babca093a38e5a1ac09ff388080b6c60918ae5b26e1c0888ea0976527ba103b257d02d0000000000000000000000000000000019797e49808b756128866fae0d6aa7e755a1d6f07f7e6a877bee150fe9adf0cfe612350c5a0e31d68cbeed226fa56f2a28d57066cce439d8d0385f647ed5e9b29e8fd0528c1ed8455f37dcd81f4b62240000000000000000000000000000000016d723a64ee06a7a631509c6e64b1c8bbe199952da532dd92194147bce9942cb4a76f2358e6c7d263916fa36e2c0c09d0000000000000000000000000000000003d04ce655cad1d63748f6eaa9912d6474a34820986835f60c812aee9980d3ebc18d6fd856a6de9546be024b2e95126a000000000000000000000000000000000ea840bd7f76f8e944f95146cdc9692d97e6a2d7d16d4a7f054f81888472da4d60ae5faccb72d3a05781b399536ccb1e00000000000000000000000000000000155a1c43c39e9dfc6d96e01c981662900fadf1a46aa1c2fdb70bb34e94dcbe86c4f255e259c771ea8ede50b388ceb2f61208d8d328014a6b2c8b2b9edc70589cdd63d38f4e70abb41cff1b7693bf9a290000000000000000000000000000000008f189d97f7d82aad87fb71d090a5c99d94079c0b74beb3dc860d440c0f46727fc49104d671bdcbe5b9551552e18afc60000000000000000000000000000000010c4edfb64b8932a617c316820cd27d3f6ffa89b471949362762af8e10d25265b84ca2aafd3b14f33c39a4b533da60d60000000000000000000000000000000017ef3bb919b087fb6745bbf115e2929394fbc9c89f65e7d591f15da93ab785aa6828ebb6ced99d3506810647d28ed814000000000000000000000000000000001591d8213ab349017cc93f1fbe6aca6765dd33ac1f468621e2c79e30aa73bd7606a0e5ba1d97ff03e0029dbc8ab1c5f4d3a2044ed4f938c17684413625bdd281f685abea2e375bece77c03d697c82cc20000000000000000000000000000000019b3a2df3a9571b066eb451e34d8a38c0d90b6e365862bcd92ae76195956c21c59441f0cd03cc69abdf4ba069759b87f00000000000000000000000000000000082537ef7f4bba5f32db4443abc8eabceef643b0878ef83860d75ba508369a3b459cad96f1cfd872df99548f656b0f9b000000000000000000000000000000000b2fda5ba0c405c9481edd598181ed8a59a8a18462508af8c5d66988a7a58a5c9635d93b5e0ee310bd35e0091fcd4986000000000000000000000000000000000af7e15e0052576f82e36e7e2b614dd835a290e05f2ed9dad7f508b4c04e8d437e7e937a7f4c88b5e66b06e0beffc4df7fd81e27a577b5e79929614c069d6d52146a6183822d25cf1ef84d8afcc1f6b40000000000000000000000000000000017a1d5add5601010d138263b4793149a02e8f4f7cfaafb69fde7b843a51cf5f0634e26b6e5e3315420d44b0fd205230d0000000000000000000000000000000013ea863ebe1b1cfcf4164d78dbe8fc809d2b82ef3e5a2589ca1357e48dddf2696e910a90301ed910fae77a1e462a5b1000000000000000000000000000000000012b40d9f25dc5a61454ddf1fa9c38e87eee60e55938b411bff9cf2161ebd7d3fc930131a198e7e97dc90cc245164e7000000000000000000000000000000000054f19ed8e2682caeda10c252f11706e7f3b65c81e7ae0a617469babc5f3268fe5c0ce2e85d44fb6731e8ac132b97c3ac5d47ce35d4ede84a83c9860322f582ec00c872b4b035d5d340981fc29884f13000000000000000000000000000000000ef0378945ae4683666099be36de3e60b5bae9c3137b702e5e4e35afd5c1e81d033c3d6b1debf5bf36bdfc4e3af37759000000000000000000000000000000000c37074af84ff596ff2c7ff963d96968464d6c8d88b69af64ae883457d02ee9ec80720661f39019230a6531a0f2952bb000000000000000000000000000000000454e8aaa2830f07d86eac7aca1d7589fb06aed646146a1b90f4959b5caed73131ab231313b50c15213f89566ed87a3600000000000000000000000000000000143516cd7a1b8da41226cb828887a0b3314cf4f87c207d1d84e9c49f0f7e548ab99e635bd126d49fd2e4dcea98f3adf784ae256d47de2d49b1e755cb0e972f3b614f3e7ba779c65ce175ca3811021a7f0000000000000000000000000000000019384e15a8754c6d85bd298ed550a26b51b714745bf2980b4920d6e73f59e657d85d3e86baa9bcf7e971233daff99d02000000000000000000000000000000000229d233d605a1a9f060605ae366a263594d8fa2b7797358ffe4c62431b9718d155d24d80bf5af1c806f447b92fcfbab000000000000000000000000000000000bbfb66cc0c7bcf251141c540f712fe9a359d1ed36d228379a1f3791991cccb7dfe1a10d40667ca062cccd55c9e6b08d00000000000000000000000000000000150a4d7a003cb81423604c13d0c5175183ab5f459b96842939f5c4cfbb9196db4667bb4382d2d5c92b70800adf384569a09d0136d4dbb3abfabcac55db48b1ce302067f413283fc1a21744f1c16ef7b50000000000000000000000000000000016352fb8e2751f126fd0f889f2a62a85b95c50d6bda7704112e4487dc94417218b0daa1dd6b998662af2582c44b011c90000000000000000000000000000000016bf4c60eeaca103c90643fe0969c2c261e9697ddbc02279f0d5afb5c905a984ab2396db93555cc2dd5682a1525446d00000000000000000000000000000000014be742feb1215cbdcde21e974c74e23c7bbc2cbfaaace28cf1d4f2b5a77dde2f3910aea74bc200277e6fe0475208057000000000000000000000000000000000bf98dd3e3a8b13e487d8b1a35615b0c6b0f514f9b8da7d6402586f113974c8dc9561db797a96f4f8040c1765518d175650a6fba1a5eace6b455ee780ff266c324f49801832640856a80098f0eed0b7b000000000000000000000000000000000362935e552dd01b5fc5a15a76faae937d7ad086b0a67e9cd3558287274106623deb85b6410bb4e64c424d44335f3b1e00000000000000000000000000000000096f23a54cf57aa3306df0a0a4f45aecb9b09bfe83878d551a59c53e18efc5a9f177cb7fdaec1648f66cdfaebb15c61d00000000000000000000000000000000135271fbe0cc0987e82f3430eefa8e3cdcc1be4a441393bb3fac0b8e8f78dc47ba2b833d9dca4277bd60befdf33275cf000000000000000000000000000000000dc1b7512fa5f9d4ea3f4229d947f43d7dc46b7770aadbd7351b6d48d525d0144183f2c84293c63c68d5262851401ae0282cb1f8f6d6dd81e7c49176503a76837a96d7f2b084d29d11dd9c6548cf0a57", "Expected": "0000000000000000000000000000000001c11610b63eeaf9e00552a230bfee290ea49bf9c93cfea1b6f684c9b5a07f341b718a0070534e0da9e6ab1239d800830000000000000000000000000000000017e8107113714ebb1743c34d83be3acde096bfb6cf140e943ecd0831ecfcd097f58d25a45005db61551a01d9da46de10000000000000000000000000000000000c2eff6c7c25885c514aadecb8f0465a0fb4385eadffa082e8d4f497b10df2395be5e7760a87bc26772dd78701146b730000000000000000000000000000000011ad4e20f5c1518c72f75d67a897f30100dbb83365ef7729c3501c6f266d6002edcab8c8bc1f449c30ec3624cda13809", "Name": "matter_g2_multiexp_52", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010a26eda028649789d9e01232884e4e5a6b8e0b17169b9d64393e2568b09ac4d3e61a5996108655c24e76abe9e3fb7380000000000000000000000000000000015e4e36bcad524f8aac7f909fbb884e879caa735f80fe9890d7874be919ee727beb2a074984c047dac1d02b8712afa3a0000000000000000000000000000000012458946f1e853a7a45861a92d4ce707e5aebbf69edfe69190c0bb130141a10869e2a73e06785b568248d5b1f647e63e0000000000000000000000000000000004d8061f25edb5a510a2db9e1df850518156138c78ace50f4c9ce47734a0b14352f5283083a232602a070c3ce94c7bd93d7f8fbaa4225f3008649eebf42315785ccda2b9ce922170e606876881825cb90000000000000000000000000000000000baa40ea518227b007b9714ae6eb5a4e92883dc75e6328caa780bb2ffee7573dcd7e9ac47821ac449187569986bd2980000000000000000000000000000000009d43d61f070ae308c5c285915600dd9c17b7de63cfeee6fe33c9ba857b3c72e057bcb4d4ac2b492797e7d785997c18800000000000000000000000000000000185215a7fefb96b3ff9229cc3239c3ce5202a97e275ea9b1541d7bc0a2931d7e3b01942febb45c6e96e66e3605744afa00000000000000000000000000000000103ae58b8066dd62c46c14c593c768fda91b90e4840b5560c974ce69b86bd6d2c13f689b72cf9619e57c9dc8e3d3fb15e71e6cb3d4e19f4a70a4465df6eec6326f558ee1cb99aa540ad2a73c363a133900000000000000000000000000000000075585f862c0e0e031efe12f31e159f2a8b89825ce80fdf65906474f0155f397fdc666292f6a7384cab790f071335c49000000000000000000000000000000000eba3d37a5cae738ab99ed9475c2c7fbb88ff54edb8490017162dbb16c8225102158a266fd4ba7570ee6d5ff6cf3f5d400000000000000000000000000000000135a0b0a38c036919f8389eb7bdc505a375fd75d513eecf0cac134645d60fb6030a437ac6a0fbbd167b7a77a927b3b0e000000000000000000000000000000001688fabd4ad751598ca036ec5ef6d7b314980dce7d8652163e89fad01b233af64defbcf352743ec478af42587f58177dbdb2b3c3b8e91540dc2724537526fd8c0d4b85d2cc20323d71fa5a4f61b3f12a00000000000000000000000000000000062a74a9ba0e2e8d95fca478be8d18fc716243b1faf7365a55387fd7188021f53bbe780e973e7d16c9db236faff176cc000000000000000000000000000000000f949be3fcf9b38995624570fcc9e7df9964d038eca189336ec39d9e0bd05148ff7df0b48436a2cf6e249e52248ee8a40000000000000000000000000000000007472e7c366419a0cab844522c46356acdf6a12cffae941fae3d3b78e7a83f0446c945bdf7b247abccaeeaafec49026c0000000000000000000000000000000006a564e6860b97feff368fc9a349282112e591a7a6987fd10a2d4de8ae4384ce229b9db9a93445f727eeec55a6fe5a9def0c8574167a3bd3b794f057ed01865ea69c38023dbddb0afdc55dd9523ebab7000000000000000000000000000000000c073d2885eb125d3e7db48127178bea2c5bb0f09eec7081f15bc6fe6cba156914fe1b1fea6cf14a21a328d831523ec300000000000000000000000000000000010d93564b2facde13d29dac198c5f5fa314a0398f30c6fb7fc9575bc83d4e97edcc1c1d34f78728729442777718f54600000000000000000000000000000000136a4ffaacf0b4a607c677ed343c1ad41a1eca49c7c48fe73ab2f74084a07cff18f07f54a7f8ea1bfb7fa3667863bdc8000000000000000000000000000000000fb0c007a907ecdff7bfe2242097caf0c5001124d112689a74544fe4fd85be9771632e7267a1cc7e9f66d7e4bb4c954c3ccc75501428d3be8bb469ed0f2df7dec10e1d205e11a907cc30c4a76eee3cc000000000000000000000000000000000032bb9f20fdb19f578fac3008396f5dd0a70860f77f8ae7771fc6253569d47b72751cd56bd373dbc5eadf55b99578861000000000000000000000000000000000c4a4bfb5ca6f9c1bd69d7377c6da405afc3128338dfddd9aea19aec5e1e0f547e3febd28445af5e27469c87c4ac15280000000000000000000000000000000003b551547af253d07625028db4b9a8da2a857bc925620c5d561bbcd3e063eb460d9407cd4d4813800551e5d0d23a2ea40000000000000000000000000000000006d5c69a251e9a042c66bd4ee92d4f3cd4e79704b1b215c15b319e09cae0d798eb201be24f407340dbcefcf2cb87da5ae5e403f555fbc800f1342275f18a73dbb679bd31873ee87617090912a52d6a55000000000000000000000000000000000a5802e388f7605bbacd0bb65ba96689e223379214fd7a92de9a313f55d66cc71ffc9ab3f9979b75edf55647ad3b6c94000000000000000000000000000000000f86f968b5c20a81f18074803e1ec55ebd73bc87451c48d5bb61604ebae46538dcc9d21cce062abc07b4b9e89c85bf60000000000000000000000000000000000f9fceddfa8fb5bd76fb7c8986372c32ab9fae3c26e9fedae892bb55178fa2f3432e6eab5043496dcebef46b20bf5824000000000000000000000000000000000dcf7a118881aea4e6a0e4e305910d4e4a5f3d0a8800f52659ac26f122bd63c8aa2c5583f1121275adc9af1800a007fc97ea57a38598204c15bf65e7270a175460510848540ca4004286f3ca09eb59260000000000000000000000000000000003ee0ba2b1de438abe66769124b97a951ce18aedc8d9ed005628aeebd90efd316e7a3c60cb5a103d6f72e7a40ed8f44000000000000000000000000000000000119597c99a7a16d8d35937ea15539089741363153ef898d6bb177d9a9b6c5bb4b79728155eacc5d82571f398ac6c32a200000000000000000000000000000000116184ac845a28c4f96641ec19a07e1f8326bd45e2106148f40277ae6fcf200d64e326915cf5c927222def8deccd4ff8000000000000000000000000000000000f890258e70b973c0d69492b2e7d10ccb3997798503c0943af4255c13b3856ca4007b18cb9d638d5d9cca71c368cdfccc54dd8cbe68d5151e4428d35ec2d5b5cc7f5e455207c0788a695c2d7fff6735200000000000000000000000000000000171035755bd519af04efdd477d407267c5a8108bd32dd6d3f1b9555f15f37ce7598c096fb5301873809f0c000457a4a2000000000000000000000000000000000bd35595246a8337a426c50c02299f297036f710b0979c7f981c6909e835c0d9556cf64e2676baf952a787e10d604f210000000000000000000000000000000006600ff240aaa026941290f49ae8968e72293ae7c2af0df1b4ebb9373199b95fc91feedd2782ce819440286aeb2388c50000000000000000000000000000000015b2bbffac097c27944143cfb22e38ff8e50e79f2336e64c8496b0b25892834efb18a765e26f1408df1d64f4b9b78fb947ee5651c127d7c8ef65ec68fcd97d1dc228bffb5bf1278aed3eef8115a5ae72000000000000000000000000000000001064bd04edf96a3c76d2ace669ff72ee5edd87d32592213cb5a6a4a482154c1723bc19c7c530d164c31626dbf758d43f00000000000000000000000000000000176ac06390e3629bdfa282bf825c0bca9bc4e0b8fd90fcf2d4ee456d5bcb3ac2882d8406d2fd59faf10c8327b1962124000000000000000000000000000000000b58fbe4e14ee0af03d9aac4131abfaaba43c7cd92d530802516cb67343b382a6d2af9399d93b43d6e05f7ec827d5ae20000000000000000000000000000000000bfd241e3180cd5ce9de831b24ca50db23685bea7e008be0c6ead11abee338618728968c25a8e5a916cef8aa516667214ab6a1d0d3f87e7c9df0c14b6fd2f9d0cd755d5fce5f40bdc8174790901549b00000000000000000000000000000000183ccf0ddeb8573923694decc02b8f02162037156a8f6523ed178c13113d094521c3d9257febcfbd8f15acfe3d5d5c27000000000000000000000000000000000cf716097aabb07979ee435cf57ae36a3034283eeec0771bea24c9a1a15ea106201af8606d3fc28ad8ffbea2cf274458000000000000000000000000000000000b962565763c4cc155b2d9ea104e754e5fb4745303240688fee7e2256fbda82dfb515a51096be5ba0b111637b1a25438000000000000000000000000000000000df04aea745b9df2df0e34153269958d3640c1596fdff3fba696801c96371420a3619c5ace9210af7e0de4f408b09a7729b12cff5a72f27e15032844fae50e3cabbe31a69568bc4b5cfa884f62e7e204000000000000000000000000000000000e6be3275371e533a676f8d075bb2ab8b0216642ecde13425bce4ffa8ac51cb1b4c5c789d82387f5355c27f18da556400000000000000000000000000000000009fa3a3df5195203f967322cee54a15d1e0096922b6b881bb3bce54587fdb82931c0b87de7a9dd1a21b4389a34d161ba0000000000000000000000000000000014dd5455deaa5ea4f9b5a6241c2e8b2230fabff9e1ac08b359f029f4c7838201cb88a92a5b696ed47819e4866512fff300000000000000000000000000000000181085d630d1e24ebf79bfafa134c08c0e75626dd400ce500392adf4462028bc714ca07b28b8b8f15c9cf2934a299c3092c1b10d980826351c3d193a0f54a7dd78a3995efb02fe5b4525fca8791b1c4f0000000000000000000000000000000013b60e3be9d7d43eb42f7cc2c0a7efc81c175b696e82b034c87d1238db2798d9ad6534b86992653d86755b4f00cf989d0000000000000000000000000000000009dbb325624e698c76b9d697e4f7f03e502ae1cd43b49a0957fc067858e20e8c7ede3577f336eeccee58cad53eb727560000000000000000000000000000000007f2f50be2c6fbc500ea347cd14ca195af08b835814ca515d14dd2f6078eb6def2b9475c2ce370780acf394065032d0400000000000000000000000000000000109803d612b9e27be5725f162d061b9428f363493c17eb39c097032039387d96d0939a06466470ab62ff507ff762fba78f715f35fc967837facb515ebff3df502223c29e7089fe6d2e9120bd3ecfcd120000000000000000000000000000000008a9fcb462412c1065dc7c3623ba5a980e6f86cc813b5d8eca6b1b8a302ee4176cebc233411f2c9ff171332c66a0d46e00000000000000000000000000000000058d2e7ee02bbd4896b5bcaac0f2b09c16d1664209710945c1f7f1a53e24496d7eace99488debb32afe10d7fea442cb800000000000000000000000000000000084d7600bcb68d5e375457078672fa07ba2c87c8ec5f9eb7b61a0232988b197aff052e7125b33c6657729ce8a1c668e2000000000000000000000000000000000a07c42468c7c65fcc984bbfc2f05bf452daf17d57e669ee5992ce67517e1c93b5f7f4c9434d40f3b9bbdb3446ddb982a9e49fcb12c0b1e9bcdbda52e9852ee0e98fa0d43f7476b3d65ef5370c9460a3000000000000000000000000000000000ec380d15e0efd71958978b1f9298ced4cc3322e472d03830ebbaf2a4601c8371e6bc1cad047b0e1e429ecf6fc628208000000000000000000000000000000000b278fcc53b7527545ae1340c24158ff662683919717c220e7d2838a853fcc84ce3915f105a932872ca7f64b7cf096ba000000000000000000000000000000001520798dcd146c0b39ee727e8276fd998de0157a68587c2fde56cd82a9779b6ffbf745ec151210d1e9143856f24f01d600000000000000000000000000000000175d53b992d750b34f9daa39aec918a0ebb2f539db8057eff1409492c90f79a00f14a4c53445c028bef5d6372c9f80c680b0d6316c5d62d41fb0399256c5c46ebe2a12eaad835d2c7177bb7325e21d3b000000000000000000000000000000000fb3863bc7b468f1a0ab0e4701ea392bd820ec5cc2d7d86b58949002f24c972f51f0f82400fadebef13b750884b35f9e0000000000000000000000000000000008fca1b30d4e01991811679f261d11723086753e816239c8c7ebb60ce9ac0ea207011a69cdc29e3336e8f589b71bdfde0000000000000000000000000000000010696ff9d78b48743abdc6c1f4b44b4c960aa516623a24da515206d95e65286e453a8f275d98aaa09fefea29e71b5643000000000000000000000000000000000fb4b5eb18b6f6f8ee7dc734e8bdb625a403dcac6d0cae363e5a7f3a834c8eed5f01fbc4dc752e228c41f3f9d992bbe01b96434f34fa3e00ee0cfe548a2d2ca29a848cf1c52f940685caa9a227e32a61", "Expected": "00000000000000000000000000000000165baa8b143e3734169986e68a848739ca05330786012de260148cfd0810ffd5659210855f19ca92566ea0d6c48086ec000000000000000000000000000000001225672112e0476418288f381165292a9aabd009b0d9e44d9f8f00469b2c56698f5f985ab6292c9dbcf73bcf610080a20000000000000000000000000000000005418cba24a43fc7edaf2fe77422a0b2e8b38a45415e13654c6176c8f7cf6bb2b80401534154cd3b23e977af589eda9e00000000000000000000000000000000067126ad59105621cb0931ab8f386570b54977563ffd69c2231c56e7961f6df2c5d7b114e0b1ea176cbfc1d657127286", "Name": "matter_g2_multiexp_53", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000139cfd67c3365c5b4422063d7901108c9f33e233bf6413ba2e5b2ad62d188cb50dbd3dac0f298aef7c1d621249d4b0c50000000000000000000000000000000012fcc0d5d09cb3d86895f76ac3d3e9fa9b2495110b0276e7a039d7d2fc2e48fee646fe331c1d8e6f019898ddb43dd09b00000000000000000000000000000000159356eb3ed0d4f146dc929aa6c77057be5ffbb064432d3fc35d346f19f6c1f8552c7079e27f3188bcf29941375e62c9000000000000000000000000000000000fbd4e9a57aaaec40ef9bce8b76b529bd2261d373f05fd69af58d1f23c089497473e44e937b2617a92942af1a99d031f10e0acc22c43080ab9cea11a60866feedd57664bbe6c3f0366beff177f66318500000000000000000000000000000000022ce2d2bee57f7567e9b52ae8e913c79e3b2dad381802ccad317b525be0b503bdfa92722eb0c21fdaa31fce2421ae300000000000000000000000000000000001177074350288dff9dd85dbee758fee1400cebc173793198a96c0be3bb810d352720e94b9bdcc6f5a8951b3a86b2a0e000000000000000000000000000000000179e21de58ff76427f5ed7c8ca3058d0e5e81e436280aecc75a3d989d1cf11d41734de22bda74cf0dff175ac789532b0000000000000000000000000000000016abe94a49f071fcd5e24b5f3a837fe3fe7c7dc53416f59d0469d71f144f71ade4569bac3aaa202a8479c794bd251645cab0c230c354cbf1a3c13c23a36ae5f2d5d084d7aaeb427c580cb6b9bfd9df600000000000000000000000000000000018dee638031a3c9b1198cd4a4f267cdd66849e2b80e3d670897d9e058bbe772936d827eaa4e78283d42ecd25eb4b22e200000000000000000000000000000000009c04ef31cfda7c086a31341434a1698c1132fb5916d359a523b98d05d57bb38a1e2e2bb779d4762f9d4ec24fbf2564000000000000000000000000000000000a788450652e0bfae66889c66b0dab8d1972a626facb690f8e4ebfefc7e1a7b2b58f6eed02c1f10a74b140a49b6c5de50000000000000000000000000000000009e48b52f2b0548dab1c0d260144ad2e66a22e0f1781f94071b5a3a08311d11dcad6963b4339fa63bd82b4ff0dabe685290608899cce4b3d25f57519cc881eb748e9ee7e27f7b21d69f5d8ab3650c3e8000000000000000000000000000000001319607058637d4b796020cca79d62af5862b1c186f32d99c0ff53a830888f297ac4389582f9fd010534d824522e6fe3000000000000000000000000000000000608ca0b4806f17b59a805a3f9f75e7a33ac0791e05050d4eb19f2d4c845fa4e4c738c3309e24a4524b6bfe716949ab5000000000000000000000000000000000a6a6201ec077e113995acb81d4d07d0c4a085d367ed740d26c4a0c04ddf28697c1cf5e648b25148888617ba77ced5e50000000000000000000000000000000003eaff54800dfc8eb3ce647ec4ae8c1aab6a87d4853a1ea061a5e6367d8ebc94243837d4752a1933f7eee0ec1ffe68c8b71debbd9f3be5d6e65e837bd78605d5653fe63025c320cf49c035ae66d8ff5700000000000000000000000000000000122822c91bfc4f761b65f4066a94c0eb1f53133a1355c019f04003e84edc5095523b2ce87ff24bb42425ce979743ce31000000000000000000000000000000001928bc315800ae9936e5b763bf29b19a9aeb71268cb47706494598e0ea057f9dbdda6733d9ea165acade87bd89b3ec12000000000000000000000000000000000a87c1ee17bcd7d348ed1a5022bbc7438bfad06172584dd8e3b51db4b3b09645290382ba991df37db0ce562c950c0e6600000000000000000000000000000000127c80da591c3ff8d300bbdbe27e0aa21b5edc1c1fd8a5da27f58a4dec3971b3c4f9631bde244a7072d9c19f1c0a46be250f62ee2c2972e751b36d95a578efd2fa5e0a2c1e29475a3cee48a28080cb0b0000000000000000000000000000000004bcd0a0321c3c7e6161cd53254353905c27d965f57c9783c3fa7cd5c55a5820116415ce45491d5d1ccef6017ea4608c0000000000000000000000000000000013a30e19c43a1f466c0c3ebb5cf1b57c44434892b18a7fde18a2a29b09a5b4d13d26cef871d689d9855a73a43d22119a00000000000000000000000000000000066d6b3c9a949049413300ec0398d605277911d7be327b1d816cf25543d1b2d7c31d912f426021e612b56ca288b462450000000000000000000000000000000008549f4dfdf018073cc4e32ac930397659ae7a59ef42ca4f864b26e4635c2b7669186a107e9e91c35f04674d2be46051ad08c3d2c36085212542427c1760c72f22838be5286402ef87403f816f4fec950000000000000000000000000000000015900fb486bd2c066cea98e51d30424681fc3347a1cfaeeab65989d1adba104a362837bee51b8b953ebb520feb49aa6c00000000000000000000000000000000198ccab1f94fa910f755936e357a92d358e00cf406894b46adcfc301918c4fd7cf7200a1ea515343d577d920680c83640000000000000000000000000000000018d9380a8568adb92f8f9f67c315f2a837d542b32aa82d9bbf5db6dfea27260738bd0a03683a9988c6c3370563e7bb8f000000000000000000000000000000000528ad42f23c4e21a687f2303f495e962b0a90713d6ef3abbdce38ed166ffea9c132e50c5b002b2ddbbd4933e9a1aedf6ffa16b6fc4cc9509a2b8d8434fa0f4f38b4cb4eb1bf7f545f9f43b9190cad890000000000000000000000000000000017eb2587aef34b03943a170d91d99aa16ceb2a36df3068663382ff4c135083c998743f9145a2fd5dd4ce3bb8b64cf3fe000000000000000000000000000000001256fb29c7482e5469d64183e3e848e5bf32f9c495cc495c3f8cd8e46f71c3f9880f875cfe429677615a6803f849952500000000000000000000000000000000146e2f329f86ddf5b0b17c37aa2905122f457c2c812782bdc15e132468af48c49b715e3080da504d59414ceb367596f100000000000000000000000000000000022a8e385972592430e76bd952a700df8d35b32deaf06c60173d0048d6ea22dad95cc62300bc1a60c6452c41b32b504a1271d29abc5f972809461a1afa5eb186dff5e28f20311a1d8416f8d54fc4b2d90000000000000000000000000000000009c80b3191783d235814fc86653bf2f9a32cb7938111408087b6ab5bafc480583e7a2a32c6bee0ee4aa867ad5dbbf77a000000000000000000000000000000000a09af60eed6c47a6c2615cbfe62025530b35727b42fd812032671ca1eece6694aaae259b05906faf7fbb54362ea890900000000000000000000000000000000055c5f0818f41e5d73e8cd5f70fa77cf477cad8dca2a88b8970a3a25c8f38382268e439642518f1974c5b470cbf29699000000000000000000000000000000000834e44669043aed8ad47cccaaa7476ad830e38fc1def66aa7e8207e889ac0fa1a931eb1e90aa6e1cd694bb95056c3e63ce55b3b32ad29dca1a0c99771fc8f7179851995d5eac804458edede9b8dbcd000000000000000000000000000000000190f8da34caaf472ea9b0f41851f808bba402b9be4baa5d02d1bcb2f66acc3172abe78a49a653cd24dea402dfb972f670000000000000000000000000000000019931343d0e59f0f0a060bcbbeea92fc4670db510c017fd94e0650ace68c2925c627f373d8e755813c199b79c70369f20000000000000000000000000000000013ee811cbc036d2786d8ec0339627d6134b10517c8858f6c6db19a9319636459ebaa217649825ffba32a224175267de90000000000000000000000000000000011039d587f3323ea9d3c50027c427fbcbbf7e097533d8a5f7a61520f3eb548c399e401df0f51884395ad6a338c0a3500c6fa7aeb016b3e3f599846af83f426b9ab85b6857f901c49554d03d27a390f5c0000000000000000000000000000000011d5791e9bc632eb63bff86aa433e6df463a84570b779c913f67e77fcfefb6af48f3df2174096a511ac35eff64e0e5f3000000000000000000000000000000000282716505907931bc93748ba1729777b959d65aec5a78c9f829ae6f2a94a022116715a8c2a653a832a62625473a0cd1000000000000000000000000000000000f694a16ce7a69f0261a0ae19478003dcb61bf93a2ff39f940fc4718a38b9f4b6ab13527c5b438d22499ba29c0b5461700000000000000000000000000000000031eab53440757e4065804896e9e811d459665598546796d67472054fa60e5da8685d8e847eae342e44730056757c6287275a8d16c02389795d54ebdcb70a39fa885320d00cd4e5aa15967916e46c61500000000000000000000000000000000138862ee422bc0f38ce3e27ed3c1b71f71a03d61cc474d989b0cc824efc512ef173ef17bbfb2090997eb9435f4d23e0d000000000000000000000000000000000fabf1fac2ffa25d9c8cbd49b3db5dfdbee52adb947ebc1a3423c9fa2f9d3d29329b60ce0c1c739c7fc6d5a5d3b9e96400000000000000000000000000000000090d92e8763d4df49b8121a50affcecfcd632923b5fede480a3ee79128781f3f49b592d8f65d30adfc75d8a1922c41b0000000000000000000000000000000000074456b341565b13ee3862bd87b72f9d01754c7715751738c5b33ee85e3d8a6f731d7292bb485b5fb59bbf3ddf9b0d0dbec9767ed2dbde21fd8f315ed6292b5b0b1bb6daf2b62665c34daed00a679cb0000000000000000000000000000000007b85110889fed72b3654a8632625835cc041ff0a827f3e1b86c090d816d98cb3b4be66b6e573b3dc05b1998f2772f0e00000000000000000000000000000000160524507679ee021f4307e5a9fdaf01459cbb9a3fb9dc8be5599431e2a8bef38bf8a05d601580085da503dfcf57aab7000000000000000000000000000000000f98e2e7ae9cef2b1d954b7f26fa1755258112c496605c3c77408786d4b210e51c76f10870f558296993e0ddcec3d76e00000000000000000000000000000000068841825f5f5d8f622c1d43bfe090d11c6996688589c3d644ff5da47b94c0638128878d51dcf6d43637781f0ab21a68ff634fd89223733f407c242e52f034691036c7ca69f30e6cd444c561de9ebdaf0000000000000000000000000000000013ec97016dc3d6a3cf41edcc18f88f58b1b88cb2616bc2a8f96af3e7774ec1aaefe86a86135a20ab7592c874a33a8e1b000000000000000000000000000000000021dc7e4be6462d64ba6c09c2d326ca0164305dbf5ca1981f265a1e50f1a646748ce66ae07297230325937faf60709e00000000000000000000000000000000121bda2855503ef11b043301cf331a0fda6e5914e5ca657890ffba2542d908f8fb02c2c93cb4ac4fe5bb92eea757ca7b000000000000000000000000000000000386fdda56c778a7552dce451a6ade55cd24bf9eaeb837ebef898e2e868d05eb5edfe97bfa8eff8ab7cbfaca3c918910461d349e9711fa701b92b62dd3e3569d1203b6a35ac8600367a4df9a9484bdb0000000000000000000000000000000000763746ba87e8bb547180b0bf18699ff74f11154a06cd77a76cc9c264db7c48286fc52e3ef2d30ca914cdcc5c4ed46ad0000000000000000000000000000000018037afcabd273413eb4a712f5d1888249dc987a6fdb8befb92c02660604bd11deb33f283b37f88880cf1be2b2e71f1c0000000000000000000000000000000008ecca3d1652be4764720ef13a6ed6164a3ae89d160cc8c2c8c37bcbaa52db0fc0de84fbe2a19b93b8100556fce0fc80000000000000000000000000000000000c5727babfbc5c36c1d57b9f69c5b41823882e0196e9e0a89d5f4380c4257818d90b1fa6d782e774f2424209bf2e6b5fcc110fd7a6ae46ef78c0e26183e707eb5e0a2944e3afc09e435d56e91584b93d00000000000000000000000000000000142d41630fb9db2f9630e4d5f9c13069242fbcaf1dd02f93224174567c3f944fa02b9791a409d9236d89df6ad785e8ed0000000000000000000000000000000002fb5fa0b3a7cef16e5638f217bb946085fba870836c618a7db9b4394da9144850572daccbff8208f14c8082aaf1ef6f000000000000000000000000000000000a6be9b4a6a9b96d2096eb3a95780f11be1e13bcb6e625517191822403935c52cd40481bce2e782c42b11321cff2cb7f0000000000000000000000000000000019e2d94e35d608a50b5c8b371044f6410dd6c1988ec7a677016d4b52cc3f21b82fbaa7db897f7107d81a177c31f8e52467de5b9bee26b26b28f81d96e880a3f07dd04eb56c15314f1a789436e01adcda", "Expected": "000000000000000000000000000000000a6f3fcd812e3878cccc6967d49b104599fdaa80cb5dee7298c3fdc80477d277f2c68f1c941f6e03441eb176c222a448000000000000000000000000000000000a4007cc5586d677e7945dc8a5872b4839d5b256999166e7fe8efe4d56895f93be4659f43aaf68c6070babb6d3328168000000000000000000000000000000000cef5304a1077c8f31d72e6f1f91ef5a021d8ba64719b4527225b34e615af388d9b1391f65511eac209ff5e86244039f000000000000000000000000000000000c856e7847ea0b4a8334d124417b45a8689d5d9f113b99ebbe3af3f9aae1cefb236d751c40488a861a8f0e0326b42c4c", "Name": "matter_g2_multiexp_54", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001805009a7fc3d1705936696191c163a07ea992cbb4bec66884a2d58ac3fc0e16b6e0d2292caccb3541f39b7fd6098100000000000000000000000000000000000f3bcfcb0c400d3d06184563204bdee465de167c7d17bea2e2150fe12eb9bc3285f5693b222fcd224181f8d193b7d95f00000000000000000000000000000000028d60b7fc3790aac7f6b3ec32c4be626a2c64c6348fb8a1f39e58ee56b81469e04886ed9be1388958550c02ca9a75b9000000000000000000000000000000000b60ed8052e43e99d3c10a4b97ac3197ee3cc04ad857c5cf4d8ea1df2671084d02fb683f28f5d499910351354d5e6288624ab43047c02e30ba2ec671511d06f869bf736a9866192c5f2eea6c065acea40000000000000000000000000000000002ddb1a9a88e3a0697540cb008bceb075e87e2331f6e9b68f8ffec48752d93cfda5fee121155ad2a142c0ec42808fbc200000000000000000000000000000000144b694018840835fa9c50fdf62c2e32261a8350d2ef074dcf7d016af982316a0c6f9e5d15d29d3a54d8d25aac5534940000000000000000000000000000000010a3765089ada75e9eb61328756ab9ca7b8362cf86cc82af3cf43f390a0745954f28da72a6ea4eb904a040596795639100000000000000000000000000000000056b51dbefab453012b35fb6e06af06ee92e4e84e92a9967b379af760fdca4a3f10f938684a646fd70a2188721c92e98edfdf850c0d3e3903404fe3e0f523cd230cabc45946c4fcb6d0e5e05e388c23500000000000000000000000000000000169effb324d60b71dc7ba975e3d5f18700b34cb9017f482f64be37c4df01fb66ee9eb5870e43649225c9a88a0d499b890000000000000000000000000000000016c7ad9c5f7b65a9423f642d87621a5192d7548e1099d774a99a34dd4ec9623aa1168b9adab092b3cf450f369bcb627600000000000000000000000000000000123b35bbcd791ce0d00148cdb3d35ba39054a7126ca5ad3351fef1437461379ef639896b271276a9561b46e270f7501400000000000000000000000000000000161fca2deb729fc55f1102fb75ff466319f18510fc66d6cf95a8256118fca618682f00318b0a5297be873a2f7af1915afeb34852ce0f3b5730962023418ad6cb860716dcb526dc53e8ab6a74a6a3910b00000000000000000000000000000000073ad8c2f713288313185c3b2455ade93d58e70d5df6b8dfaac8eccd990fca6843778fe42cc8aa6f34ee44aefb49397100000000000000000000000000000000012eb9cf288a366adc58d40c9ea5f2cb5dcc5b04108e3822266ff20eed71f56bd74f1a2727f20d55917adf20b6c4d6a1000000000000000000000000000000001463db177fe5c0dcb899797f89da963731dd4e9e8b2eb77b465b98415dc95f6d5569df51bd2b08a13838f4cca4b62fcc0000000000000000000000000000000009c0bbadad98361209f36eb23a9eeff98f6eafc7d5327fddb6bf43898a2be704520a005b84c5b45c6a68bb7c98d65d6dcf25e64093bd92a8fb394511215a3fa674db86d7329ac5ea70ec77d24d4ac58e0000000000000000000000000000000013c63973ce6549ca3dfe8ea8e3bcd6b0bd88f7c73730834d9ffe2076cd4345090d0364d161ae8998af1048d102f22e5d00000000000000000000000000000000060cd24eea4177c9a5c37038d4cb62aeb709218fa8e64b9084e002f53a0c4c411825812c20df282345bc4a6aabfff6a100000000000000000000000000000000106ea864dd52933be02c1a79cbaf6dc81ae9a2d619bb368c4abc36226104f3b74fadfab906e36d4852a6412315223bdd00000000000000000000000000000000192e45153e4942c88bcce76098fa51782a81b53abddb4c07bd79a2391be68858e2d278969b9fe75bc652d02fe4db1a130b40db4f9e5c27a3208899f4f536880b97f4c69e7d889c0726d87c3fa27e097500000000000000000000000000000000101ca1625e9d4a51e08f5eb81387b361f6445eb307d9bc92acd29d62735d4e5078b1a9b36b94e4ea0a314703a85ac4cd000000000000000000000000000000000f134c460c6d931396a0aa397558975ee973e642f1c4a32a3d397051fe250daf4215ff5ac4b2863d570c87f0e32c8cb800000000000000000000000000000000008eeb127a38104351298ad77481c32bf51bc5d3910b03da0cc34062dd2a8766adba6891cb9fc579672276666e1242730000000000000000000000000000000010c896ecd4bdc1ce010da81a51dac96409079853635e57e5c3a5733956a5f5a9c3ea6838849e286ce0405dd54d7e32d6730bc7f68d8d371d0bc51d95f8a5899249b8db5cba0d21fd88ba6f86d8691659000000000000000000000000000000000be489a1c71246adaa1c1dd6d2ddfae9523fd1d58d00d4f189f56d08632dccc694e63b371db6922a7f3faa05afbf487500000000000000000000000000000000174212b6840a797f0fe9e209b41f55aa5dbf169a2e2ecf05de48c44e608f6cd6d98ff5269e5412defb431caadc8a09c3000000000000000000000000000000000f4501715c0c511703f6236caa82479b3368de430f2c2d95b39193537be0b990fec1ed8e4d94634ee6233cfa359b043d000000000000000000000000000000000f3b4712f95005004d99fd739affc532d2c4c45970316c1a43f76fa9b57f6676c709e8791c276237b92750f5bdc94492ef06360717cfcab15be966cba2836b97deeedd20a52f88c73e2a583b64c8e5f00000000000000000000000000000000003abd36736fec3e8b89863670666365b169d8510090a89007c7ff3a82fc62ed371544013a1444fedc4358e92ceec62470000000000000000000000000000000008229855468fc63f4024938cd6f41c6e6a5653319cb83f38ab7efb9e9d281166261e7c854bfc08f55a0a9ca47e54dd42000000000000000000000000000000000463ccacb341fc5874f6ba2d44efb5cd24e9409b2ce7f43e9d39466288dc833a45988261f45d34332f416a68c5d10ce80000000000000000000000000000000002baa086177394203a04ce1b46415983399e60986531967b690b1a13cf8ae039b56f0a00bf9aff357d51ac57f8fac8b282b7d8b8b9345bf13d0e113b662141f5ebfc5888a5ef8ea06f7d5d137324ebef000000000000000000000000000000000b25a203268100df0510e4155c594a144dbdefbb0ac95e02bb4b3799aee4e738ef4c52f03c6937cdfa7275c28f130778000000000000000000000000000000000c432347a2534e86e90ca346a7b8b40f45075727847fa3ae2f2e297baa14aca88ac6e08342f0d248a92e2c272841fddf00000000000000000000000000000000057ec8099e1e30329762ccf0641b45e1a226f7b66b80644fd551d6fb1f2136afb8e8ab5c6905ffc7c24e67d7f21863e4000000000000000000000000000000000a9e472aa993bea05961affd6782efe8f50d746928efb8fbd328fb50a254db861c90db8df7faa7da8266ceb47fa1a13a2396fe15751bca2c4a651445cef236a865269849908df53551802dd378b892cc00000000000000000000000000000000025484652f18e2b32e2bbe79916c8bad42902db5528fc45993e04daeca008f3c2ff38fe4b48c292f70a7dc57654233400000000000000000000000000000000008e403f472b60a6046fd190544a1d6b249dc97cbd8641c62613f4de0e0fa9f5456d843ece4ac2b9f4ffa2c0278e61829000000000000000000000000000000000824e0b9b03198597fa54252b3df9690df678e9c6d82301848939dc55ab25a7751bcc2b99786cd31960ee7030bf68ac80000000000000000000000000000000018d1d8c7f2b20f0ba66db616322e48ac8f1d6f4205f228ee8ee6cd13d1f64be9af338c11f511859baabea3e15d165fc09a5897c9596223ca4d6628ca1f793a000aa21a739a37faa28637692b754148f80000000000000000000000000000000002845c4255819ec6e97abddf4c9db7d91658dd1d55328ab0565144b377e20ca0743d93fddf68acc985ceb7f7431e30b0000000000000000000000000000000001577a5691f2425e65ffd59071c2bb167ad05a8fe23c11c7f7464764442ebb2f7a75a8d02594d4426c1ff022f7a6e19360000000000000000000000000000000012c6ffefcd3964362f1373348404d04d1849e98ffbef7b5ed5704d74b9550869e30a4df26e74b5304b85c7503f7487f1000000000000000000000000000000000faf3dc42113f27ac27aae36725221d04fb1ab46b59e16277be0758b8fad706fa237c0c7627771d8e8d3ad610f63619bf20a2973faf886556e5329363bd9b9c96424fcf2e953df90bfd011ec07bc66eb00000000000000000000000000000000044de166200ec06bcb88720e57b84cd8f9534d1fe303a26aca08cc35104ffd7e81a6473c08b28037118dd8a61d090e910000000000000000000000000000000000f4325ebaafc67945de2418c81f5da92da4e67866ab5965eff0f392cc527fc34ba4e7e16b91c26aa370b27eb6a07f6b000000000000000000000000000000000e1d77ccc1c196cf1cdf0dabbee4829d56e937372e9f5613e261ca07e19b3fcf10f7a45c490b98b5a64b955eab5c4f2a0000000000000000000000000000000004ba2e81f901b0da1ead004c76d43278d372456c0c0a8c6752597823d44994177734ed3f355aaa22f325ea36b7c9eba1f4ddb773155a27badba330ae5d26096f350e9ca2811feb227c4eee09d2baf32f000000000000000000000000000000000c115e270ffd6f2cb9bbb2a62e04c3bf7be9d7db783d292bed272c297773b39e9e51c75e5c79a6606ff7d0bb9ddd040a000000000000000000000000000000000a57b637126b16b23bdaa6a7cf2346f33778cebdc0c9943eb2985ba5c4114674cd596ecdb6959791139c36c22148ab8300000000000000000000000000000000177c7ed16c29d99d3d98c6facca9cb5ffe72e6aa63959dbb51d9382f0fa49b02a1652a398eb223e093516ebf134448c4000000000000000000000000000000000d6bd518678828f582fbb3b1bef725e66f442c4d3e6325fa571e13db492300d03c0188399a2ef9d5687a76e647873c0f52e4030b5a4bfa767ae20cdea7f464dd2dba51c9c698556d24b8f3d4d1afc82e00000000000000000000000000000000085d4f90336987f99d250067c2331e7de8f09a80d71fef0570ecfd99e409c1f405058bd3461c9f8ac5ccda406db89bca0000000000000000000000000000000015f310660ca6a0c06b458d0b840a5c1c476d5175d9ff6dce6334466d363d319939572a2b00662247be1ed0f4e6676f8b0000000000000000000000000000000011e9352c0f81bd3857806db678bceb2150848f2224ddfc43fb0c733f0689ab4fffde50d5ce04d54055d27d7702e5d2d40000000000000000000000000000000005d835d04dcf4199130d6a16e86cb97f4ccff58c496594b83524dcd88f5570212f06b744379288f2a737c7a82e897cedd32e0429e7934faa526475c5c7fb977c3030ed74e145eba21af2d2cc8461580f000000000000000000000000000000000f7c4e621c37bd3068a972b9d4211abf9026e438ac7f8cb341516f7e6aa4d8bfb3536389e9155029ce9e8d5d376eec1c0000000000000000000000000000000012a46cab2624797513f2acaefa26fb22c4bf29188881690c350593fd1949cbc243c9d1d7d27d9d76aaccd347359a45660000000000000000000000000000000002dc383d4f9b75907f74bace1769bb5bb1b27a597c9548310f2b5f90098596fcce6b5fe0c72bc8be9037fbf31050d74e000000000000000000000000000000001900deff7ddc62ac302c941e1d2a28a4bd2351edd7700042ea4c4a48145ef91688666d8d7de503913ea259f0b58809f21f700d651c67ca5b8d95fad1a8e412befdf691b074956bb8092938bda2ad26940000000000000000000000000000000018ac8048d58f7b1a9407d3101824e3640eb20633f8ffdcc97d43d1b25329a2a1e91added42801c03635ec904e627eb690000000000000000000000000000000000b499fbdbe2ed41dfd6c454796e1ba57021f355a4de8f60964c78dc685e2ffe9c90f5a1f6c9677514ae4a9c95c8d6450000000000000000000000000000000009d10e5e2bb69ea6fd820778f75a2a60627802a49128c3f999d8c1cc2ba56ed18acef354a2e06fbbdfa7e7a4ade7529a00000000000000000000000000000000082839d66a18763656c2ef7196a1d83bd162e1f109b54c5a6095cc7c436e8a4888c4001696958270f54f61b81b00b32d83052a3bd7a13bb1ccc22b9519c7ab12d2dec67924fd9f15f96069de22e7b692", "Expected": "000000000000000000000000000000001463ac5e269d286961036db48ae33fb868a28b0dd828c3a66592ff9dc115303bdf3ab78a8e1f5df68ed1f3b4c6c3f2440000000000000000000000000000000012c64ca0ac10ab616fc733f75fe6181814e9c204f9e4eb79487ba49e3a9746b9b7916a1d768f2ec573a4c4e226365f48000000000000000000000000000000000a06b5b745dd92adbe1f4cf30c79ce0c48428b3e3b05af1585c4ca12eb2e763ffff46b55a060913e1f77fc9b0b085c9f0000000000000000000000000000000006271931ce9c8b9cabdc932297f3c87128a5af25a9f77e71ea4e588f1e88686638e89a8e212c92f6472692be2e05fa5e", "Name": "matter_g2_multiexp_55", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000001bf5b74c1ac89d4bab4663943e19128619731e315d2d7b39675f7c43493b338020190a72cc7a6edf0b8838886a7fe6000000000000000000000000000000000713f413bab7919cd57c2de3349394121d6bace3c10df0e41a0ab895433d225b05cdb1587deb93ae6e56ec26a29c39f4000000000000000000000000000000000dfb11c9c0bab7e4d1ee39941d5f6b932ab473567be2329c94bb0b146c46fc1c2cda25dbef8ff9b0066bd4ca3b6da67a0000000000000000000000000000000014e399169243bd619be7f2120b2cae5d19b2f04185aebc7d948007c4d3345a9f45249273b6290c2e86448648868ac552c40774f67a651ad70f17393b386e9ea9e81682ffd78db7fbc17cc5084f3c7052000000000000000000000000000000000a67bca1f8a0b386b2a67158e80262f025b225535a294394584118f9a701e31e91b2c7eb8fc7e28538966b967c139dc400000000000000000000000000000000185e8aaeec9b9abb9f0d6f34e2480e9abc30208eb1c6e023d4986d544b356a387c323c9edb5c52f5a2f0bd59cca7df98000000000000000000000000000000001877ce1ca6e8b30df86de688d950755f2708fd6f933c07ae45fad1b3e43337f1a8454ca5d2a80940e8fee98fffe953a700000000000000000000000000000000117a0ac9d27292f967ff5bff2ebed5d2ddd9f453d6aeadd9106eb52b53447974561b621fdc1d973c055f1cdf824c367bccf1e36e063a5fdd4b735dc18bf07703b80c6b72f987c05641612d7ce73562c00000000000000000000000000000000009fc4e9e816ff495dbfd4f745106fc90c023d95bc64b809801d02dc7cead905177ede5016f537243660e4b7f54a02ea200000000000000000000000000000000180aceb6e9851a11a1e34502897299e7db3e09f4970337612634fd9848d1de2bb3de8ede690ca051a75add5810ff777600000000000000000000000000000000199f3c43d429fe8f73e20f81ea00c4e78294eaaa29fd67563664381db3cee2186b387b880089cf96fb99c2e22c95449d00000000000000000000000000000000040b20ec4e685f104be188d0f15a79f27cf34dd01f813275f6019a9ffac56e234b6c967c80745294d9fa46e0083cdd907ea75dd2f54fa6413ba77f10a11e12abea3a4b947116e1e7c9334a0a37c3963100000000000000000000000000000000189fba635109ca215bf3a09c3e44ad65f7eaf653e0929aed39042e3b9c8b1132c5fe7cfafddfdd0646514aa1f9e7e1c0000000000000000000000000000000000c28f598c80ac262ec7a0e0d1c867e01ef26f182c5df9ea7f88fdf8bcf3a5d2f06128526b1ce72cead8ab4286a0b8d030000000000000000000000000000000008051be3328df43b79dc9040ef0a0263d474acc0edc023f300cdf7c13088d1bb21b5f37ed81b38dcf8718bf6441605f8000000000000000000000000000000000d2d474723c6c246dc59e683be147b1a6bd6e7d3cf12aff7b636802a99954e7a13c9ea429b19833a985ca5649b1a998f6855c61bb7d72b022c16290c6d3ca9c1255cede8e0b827b43e40fbf01840397800000000000000000000000000000000058bf424fd68aac77c42a046f78a55729e6b5b3fcaf436d0d98354b426a95904b55cdffdd9a8892c9f56f170ca8811a600000000000000000000000000000000142c1ded08928fd155b89bcfaf9c8194f4569b4cdeb3bc7286f4dd79e822f5db497768220533b71be8c71d121e557020000000000000000000000000000000000a9c753686534bfcc295eba0a617f86d7f9e78d3fe6d52f26cede97a5b1f107210a757a2d89361645856b7b20e89185a000000000000000000000000000000000f745541841cc4b5352f659c2b7cfa8d51b07f91b0cb8c787b4492bb4b94ea27117695416e2806e57c38d7e565b9eac67fa8503101f392a6c6c27300b6992af3fcc48d47f73db67615a44de883770d4f0000000000000000000000000000000004445d4464b51d6b12f164a49ee3b610f11738d60cfa6e02f8c33b168d9d5db90e6cc558cd12c56069571567d91183a30000000000000000000000000000000009e4b96c2b533a16803a36f8d1f179313b7adbe6c4b90716855474ffb2fbe087df3fc0b4ef14cda7d958efc5c92574ac00000000000000000000000000000000104dff7c859eec61a0ff8e0d831bf9667226d5bdbe298400b4f9e3159a64b1bbc7cb9f4ff9604e3ced40bb0de0455ce300000000000000000000000000000000134bc2461459ed6f0d96aca02b62e3110c2009e1ba7d3258656e9cf97c2a1685faf1f61733ce6ac3af7ef4d73d0b43b1dd947617bcb7ca1c8fda0d49e6d950a84d60230bc2411d42ac32e3651f48524b00000000000000000000000000000000104e5709f8edd71f50eac1770ff1c2b21f5ee8cf5a310fd1201109d1b73cab69913bcfa2d27a8ba16d974e9841586ebd0000000000000000000000000000000003a4bedc6277c61825f6ea1f438c058a1afd494c384689a8479195646888eecc7953b8b8aec849fb5f19a20071261336000000000000000000000000000000000856ee8eafb9b3d25fde7e38da4acec624d1444337b87b0b1a660bf497ff37929b1ef9aed8e1fb0ffc6cacd8f0d1a1a00000000000000000000000000000000011b52192c88264df56de3d7b14372443e25183bb816ea1c0346f15a1f324527ef8531e27aac3112e2a497a0eff0d5485b4cbbc6d537ed2b69c2c32c84f3cea3d2db180b64861859368e98aca32bceea6000000000000000000000000000000000a696c83010719161b6624aa7756e6e84980518416554ac045a93b63c2561a68ca2ff2fd5b6d2d667822ae4e3b3a2ba2000000000000000000000000000000000fb8fdab4f177b0dee52bb5ba615b1d548130deb87b14d05d427984ec148a7a94efc4674804b3660d0f7aae2b49f7b1e0000000000000000000000000000000004914c0359c8e23a7e431e517cb83e5735cb2876e8b53ad45abf1e9eda06e736378ce03ff75002374d47f1bd45b08e8900000000000000000000000000000000139abe340c2d773cc45cfc75c47ff31b2dcdce27ada3e6d6c0823f37e4e693ca30342fe41eb96dde464d14668eb72c5e457bcb8c44a2d9d1facb39ba7ec8ede5d5962b3256d9fc2e68a1ee5a733ccbd100000000000000000000000000000000180345fc01e3fa349c45b1a7fdccde5f9ee70d7d65510e8b4bce654f2541fae7641ad86f9bbc1f02e93e94422433f8b40000000000000000000000000000000006cfe7026cd423be189c5ade8de197aecbc9aefd4cdbbd2aeacda816247ad59ae06a5c49b0e29bf1140f400d46845191000000000000000000000000000000000cc4f240a317ae9ce75b44fae87c92fe9b6de10e1191cdebdcc37ac200957683849d8a957216676db1af51fa0a2a1136000000000000000000000000000000000ba84d595661e5d9bdf9d268a3cc575fbb6b0d469b58b3e43f80694c78f4e9e501c4a4f9c42ee4518ed7189a1c36ca0c19f254dbf75f1c42046343b0060e71302bf6c94ca2fb8aec74fe7a47a3c9c3ff000000000000000000000000000000000fdf7e2372b01b5d926a18ddd06b4573248c02d7debf944312dc06f76ba08a7be460c451d296b71e9e81cf0956b974b80000000000000000000000000000000018326d0e1bfb4a62ab6f772b47ed7188035a62141e6b2eccf53a299028902a172771e8e46c0b1ac4833ab12045922b3600000000000000000000000000000000072107574145c6afdfc7d618f2dba2b8bb01d92007dafd476e4ca62e6053e5e9f2e34243ec2dd16ffdbe3488b925a0f000000000000000000000000000000000070e8491a835ae96087013b0f8da267a7ca5b0a600d71b8c76fee35f41d8b5c1ad82c5170b0e8d1cacfc7b7b13938e96f08cf27a47d89ae6e2ffb27870d613b9ae586857e4ea00670944a2883ba325af0000000000000000000000000000000018f4da37ff63f66d68c875def8c758d9a5adcdc408f0c12b3a60ee4a285e6702b1d5b9326c61f443dc71ae83c7bd21e80000000000000000000000000000000013a665e430141cff62c25577798473a645d20321490bae7689de6ea223a434c7d3b16ad004b24a82e2c62879b2408cf90000000000000000000000000000000011b0108562f53bd47d9f8ada54166854bf758ef3769ca1c3b7b006fec8707107fef0b6c7e59feb727646b74c27ec699600000000000000000000000000000000028799b52107d8965066e2f629b30c0edb490a0f4d0b6cdfff89a9f7763afbe6217bd42c2059042397b6c0443465fdc050aa333bb6b44086fe6211e89cb70b8467eccc228c09aaa1d589cfc24771a11b000000000000000000000000000000000c42cb42e389f32926ef09584516249ae332641b573ed29bc0884feda08d35c1bdc6c3d4a69fa15105de95010c6cc24600000000000000000000000000000000006c57fbf93c7959c562e0f3ef59966c1640c706fd18a6b539dfd711b0ad79643642038954bc866d42d1c04be375b95a00000000000000000000000000000000039ca3ad23b71693e02af36a4abe6ccd0dd4f4aa709f74d900b9fd015a2eaed55bdc2bc0749c995783a7615971e8a1f50000000000000000000000000000000009a08596b29da34466c8a7f46b805f1b6f2e48bbba614d728562981d3d4884de9a3c1980d398eadcf69e90c851d48526d9f7f74a5ccbd01afd985d3259739023cd012cd67fba3a4ab5597e94d8fad43400000000000000000000000000000000123dde5bb9b7ca11da9e08a9489cf07d147492be8041a5ad0b70715147e21d6017a58af23c47d77885a7830cfbbe5e0d0000000000000000000000000000000001527cec3c393d03e74ee8a7b1d6a8b6398945cd284b59a93fade9839863f0af591c287e89b3b45e6048f2f9b518208e0000000000000000000000000000000017ac3a2d9458bbd5f38d584b0fe4b35f3a452e22161564a7582465d2068b3ba4dc5e1e24a996596b1fb553d641996a4e000000000000000000000000000000000ee5ed5610a78dee181750e35a8ab91c001446f04124930c2ed85de74c6167009af45a6cbc3c59c4915334d7853ee12f85c00be7e66e318bed8e66cc41e7fd0593004bbca20f0dbc28efe4441acfc9ae0000000000000000000000000000000014d60c1d436e4486f35ec85bf2655ba6b752a36c86fd9088c0ce46363e75abd636052f876986fa0f4a59152998c0e4a800000000000000000000000000000000083328e38373f1de1049deaba78f568db818b1dc38d981ae92b968134d369ccc399bc3bd55c841755beb484cbbd60f4b000000000000000000000000000000001788850a5508d81df9af1f087356bf8e63b3c8a4e209403c4de7b3adda07684a08f9de6f1f8fd8dd4b2bb9b75be329cf000000000000000000000000000000001506a37d222173f0098f56b7c443e04ffe08b376e1563344e7bf22b1c9df0a1292f70ba51cbe554843fb93a7f535a4aabacef63d90ad11bbdf0c5fa2db2838c238ad3049a3f47b7f67361825efbc6526000000000000000000000000000000000d5f153952defdea9309269bc996a7714deab12e7644f8f8344140fe53034de538aae6c3af7b06687684edcd2c5dd19e0000000000000000000000000000000002da67345153c87ca65012b8703acbe777900953abaedca4770fd893275948d150ca3d6694d58bbbc9e62904448a8d2c0000000000000000000000000000000006e8c95d22f01fd9d56178d754f0892f46166282a27e6b02826478cd39119636e811c03fd835c714a59bd2f7da5ce5e1000000000000000000000000000000000b5ab6233d8dff50648d89cd65793640c06ea784d00aff329e882ae04fb466506cce3fb6c381b4eacef8b5305953f7b6473fa3d16e6431da14b8639d4fe316692db087a167a2c4f07307e770bb9e35ae000000000000000000000000000000000595edc440a5c94506a79f3b3fee818256d7c4185be40c1953b46765b2f925ed16a476b07a267570c727592dfc4a0d8d00000000000000000000000000000000079ad05473fca57f26fd068ed659e4aa4919847dd96e683e7d4b3a731cc9ae0562a693abeea4fd550e644b43b553118500000000000000000000000000000000176a9751dbfe727a442797551254cf904862c4d590892e019a54b72f6a5a124d268777b82e19d557690ccfb81cbe949d00000000000000000000000000000000164ab74c150cd151b70fdd7d63d0404214fc9cdafba3bc642aa798b1c301c287ff6d05ee7b3a3ce997072b8189d54aa62774741f87af1d6942dc4ed79b70b2d706f3db6b6d083eef0475334ef1e2410a", "Expected": "0000000000000000000000000000000017d73e29f1d555a10272043ac0900e80883c185ff7d087ee7f5a3b762213e658a42d1b4fdd435d1acb9d5587fa7e8243000000000000000000000000000000000ddc440795d0e4308577fe8439d43418641538711972c9744dfc8a4c206c193aa17958404bc387c7c2fa30bc678937f7000000000000000000000000000000000d7e43c0f99adcb02db99974e7615b4ca0de72117792ea515bb04c4bc8680a3fdb0afcf6a3bdfe16bf54c1d7336aa185000000000000000000000000000000000bcec1d7fc9f2210be80e90631810987801fdf60890ce197db041b6a62682fd7e181c6110956c5f5e9c196049e39100f", "Name": "matter_g2_multiexp_56", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015425cbb7075a97dfa9409d7b014127396056dee6d4bb63ea285309fd91280fb691f9cb9572b544b332324f6cb3b1276000000000000000000000000000000000c5b9634e6748d5819396051322d9b7e0377554613a7fd8dc0c71cfb7886dc0ac29add7265af84087a9df5ae3799ae30000000000000000000000000000000000534226ad7324ed5600b5438b659c7b1e96f27ee1d77163f2d3073418f7ded5c613ca4b1a686764ecc43ce3388e0c32600000000000000000000000000000000198267e2bd474dc0415f47f5c87a11fe0945a91cc0bfc37d504ac53f9b9b0d087cd5dbc9b03972be03d4b3f9d2123945d10ffdd3797ad13e65a1115cab6529d0f87b91eb41d6265e694eed8f02667214000000000000000000000000000000000389a084d95445af6e0afaef21d3676794e45986b9520035111ccdbac4ddc1b23974a686a900616f878f3a06eec90db500000000000000000000000000000000064c75d1129753b5f399c1a5166a0f6a8f427d65ec2fd84d0c7339218e0a396681797bab68b33653ffb9820a6005fa7500000000000000000000000000000000147e199e8c08b9af38cb457b623d0fff32242b11e695f2adc0f136c5596db313b03c2466fb58e37c94704152e5c8f9dd000000000000000000000000000000000e8fe5436baf3470a19891b85d15486d1269e1b13098d837b0a510e71b0e6260700ea85f0bc6476217cc73615370cf003e5da5568a9427e0cbd7973a34c147ac2f3577d06f68280caecf8588ebf1591a000000000000000000000000000000000a39a2032858a57ccbfb940741f4ae21b318a56d5567cc0088ed52dddf1e0d5de60bd2da9b675212a9a28ec17fca7c0600000000000000000000000000000000039e2a4bb1b417f8a94b02cad60a3e1c4c4bc5a86a23def7cfaecbfd97d89a5104e0cd13870c9fbd010dfec3ad9b1df9000000000000000000000000000000000bc29c5623f9f18ec2af5bc651a65d89554705a349923ee15a9bfb82c114246b404a1dc1c24d65c8749e7c9cf62d963a0000000000000000000000000000000001496d76f7b8583a64c1627151589af876a2f5e7677611ea15f14606538f6052c56e9fc3ed145c313acea69a51547fb6145b5f1f156f3c823cc129568e7602694107608c1f9545edaa897df58d27b18f0000000000000000000000000000000015f83b2f998691e504aa740b4db38f5b0236ece3bc1ca933b79999d55b737bfec51e590c2127d57625a9b7c2960c06280000000000000000000000000000000001b7b117f5d722e320b7e90307ac1423aec5e30c29602d314bac9e5272ad3990d31999bf3f516ac78b2be0e16c0375d8000000000000000000000000000000000fa7992cd7fb679eb5f9f9a9febe9c3cf41a717c8f6fffbab5748572098407174f09457e13468165f1c7275d52f6c84b000000000000000000000000000000000737e95f62aacd12f8aebc288c5cfe052f34c4d16e7b44df4497d9a713b77485fb0efc09aef11c7b86eec4d0cfd9b03ecf6760be82cefac2843265be5fc0fd6d308c1ed06fc684c4693de25372f09ed000000000000000000000000000000000004d48d72ad4e77954ec6a5a62299f0472bc52b556cf3857019f8efdd694758f13029f9d6832ed672cc210f32033da8d0000000000000000000000000000000009b2394755d0319741d131b012ba0ece7e2044def20ae73fe73bcc276af9d807ad75be79202963f9a5c512a6ca53197800000000000000000000000000000000128f856fc4790d9fa68cd2a3c152d675453dd81dd64f0ab084c6dabce456f78c2bab0e7f315439b34f86e8fa61a33ffd00000000000000000000000000000000173dbb908ed617ffffb6aeb212cfe6c03f7ee51c84134fde67de2ad9561a897e28a0efa66257ae0c21ebcee3fe4fa68cd9fca4d166149ac9e6159ce95a06f790a96243662373637f0c6a59764b77b45e000000000000000000000000000000000bb7b84476d4b17f4ada0b6f50d34dfaecd611356862895c8d2fee6707c4aedbf565560d4207e43c179c5cd33cbb739000000000000000000000000000000000112d8b10c775218d318090dfcef55a903953f7466c50417125ec0b2c20a24fb50bd172331c0377d4f47aec99bd87a3fc000000000000000000000000000000000cf4e4b3c600053f45f350c8860e47621f50f3849872a91ab115f71a2b04657991217e2f0844b296d3a6bc33ee66e6a80000000000000000000000000000000008f625da164bc9d96be3e78df63bd1633a2951dbea0b98e359c6317abe6ac5799c4bb00bbc2c5d02048539e753019a6241733039312347a0c9d760c1bb9a1209a34a02b359a9c52a57eddced1575867000000000000000000000000000000000028db057ab9421eefd1fd481c91153b5c1ceb0f2dacb0097298cac986f036572c6ab0c8709325b3bc25bd494bb46c55400000000000000000000000000000000024be09301c9be4f726fbf7796e8336c50897e8534614c25f65c37bcfc6e724d530c2782bf483668fd08e91ad09484af00000000000000000000000000000000037bfdaa11660111ce0a9c3e18b5da74c004cb44882b1aea4173e18d3a17f04fefa3b319afaf4af9dbf3d4b9ddb2c3a00000000000000000000000000000000008f2138bf621237a286229fe762968a224358b030f6c20db58043c13727b516097b42d47781bd0f0df2b155197ca3946b21b18d883ef62084ce4bd353d7434d7e220e9cf6bd0e8d0bed1ad0a4ad94c7e000000000000000000000000000000000b4e2b058d6e77cf95be093375233e5c9c8ee0cb2a3aa93172c08faea111df81b9721a506180b7b45bdde4b58b0b7368000000000000000000000000000000000f7025cc33424a7c11eef47baef888535d938d50c0f40eb83ae86791834770e5dd95b30aebdd2c13eda3447d5730ce3b00000000000000000000000000000000088270ef05480ef8aac5c284358d8e06c3482c26279734b8513000019924cefeb396ae79f5d9bd863bdd9b22e3ac3c54000000000000000000000000000000000df75afafb138fb06bfd905c87035bc5d18c45a29267c3965131083d7e0112e10556d7693d424172a53e8d3120f0cf2aeafb6aa11296facbc13936bd2ba09a2cf9bbd9dab6ec8cc5f73d78c90b471a3000000000000000000000000000000000122fdd3c83c01c7cbe71f54d783181860e7dcf8406e3966e910f4d0ccddae3a245d6b1f94b1182d1917fd63960cd75d400000000000000000000000000000000043592e5797cc1409d6d42dacad628448799b24320acbda83f6ea9d232968efd021058f540e3bd73a7f95761efbb5fc400000000000000000000000000000000025b5a8577ec1064b5c557415a50e84c2302df97eb65860f979e5b1e261f47c0f305461681beb07e521cf03f0e21fd030000000000000000000000000000000017e86f3ffe72bcb71d46661a1537918d52e886e362d78ed756140a6b5083a4eebb5280b9eeb8a25251dec43a5cf509b13d39a61323c07f9f4656a6c5e6ba139da8175ebfb8a641de50cfa2290884662900000000000000000000000000000000122f26b4561d1f79a70bd0e401f25d50891c0fa0320579ef21aeed7c191fe1c75403a09260c3872cf74b798eb1587ebe00000000000000000000000000000000039a261d9f48b9eab6e89046f333ac328cea287993166057e9b99fa8a7d7eb3e7c34ecbb353b7427b235084f47f45d1100000000000000000000000000000000015d5e297317684bd0169c795d9dcd209452d024ef9a450c41beb0f6c7e6dc5fa0f3ae24c7cf2d7eef97bdc51788188d000000000000000000000000000000001487564f0e9d3e0d2d30ec9930a00f10093e29f2f195344f567960be323ca21231efd8528108dbee4d5ae4de3930ddedf6374d0849a4471eca96c5e715b10505c4c49664f341d04705fc688c8479cda4000000000000000000000000000000001965ac3a520c1ac39b86832ecbe226ae0474b76659076ccbb550a0daf41c40d424ceda084dd991f22cc53779085828430000000000000000000000000000000002e970a4248823049bb4339d21583fdce9540ec103d6e9530b89e39ea875b1c333f7f5f859be39baad34b374055baa770000000000000000000000000000000003460eafb3e54ec03fd5cc1d460e1359b97f5543e6231d61614c1225ab7545fae079ac8e65668b83d022031a7a54746b000000000000000000000000000000000321394863e7c70df3934d874613b7c9d6c331e59a599be593c82edb7a26eff9bee8e4befbf122240d2deb2d527bd38c0b7cb52b99abe10d1367f8d3def38221c18657a1114ceaa1c0673ab13a6e10870000000000000000000000000000000001a5eebe200ec041476457f8585cb4ccdda936cca4977d7701c44e0d4fc5d9c206682a23348013a055117028c16914400000000000000000000000000000000003519bd1dea70245e521988336eb41870599a877380c0a9eb19301f9b2caf963eb559070e23eaeefa4de0173bb1fbd8a00000000000000000000000000000000125707f5a8e26b28968dab97ef4654c315b0a118c20935e38a5a526d9ac0a0e18355d8c9f3f58c082de98691957e2d5e0000000000000000000000000000000010b58dd683f73a16d8bd5557b35b7003a761bdf7d90ef576de8acd420bc74f5219fe7f9d35667feeb3ddf1d568b56bf1f49b1fa80a321d4d100069b2c4b94cbda255d8e9f1a7f14ddf4762b76e4a386f00000000000000000000000000000000018267d8b83ca59d4efce7ee3d73f7b984f09556ea4fa5cff5997a1eeeaeb8bdc9185176d77ad0f4d86f2e429f4015350000000000000000000000000000000014114344d6b7c976cdaf2418d7f72c120c2fddcc65c3ead067482e7073e2a3a239af19f862ad247e3181b13f5236d1040000000000000000000000000000000015db961a093b248e83deea0ceeebfc3dd57c7cf8b48cd627c5c566a4f9bea30ff0ef9cab9287a0f520a72b02d9092a0c0000000000000000000000000000000015159439fbfb91d1e24af611563aee3eb498fde666a1014a9f645037995d72dca0ed5569da7ecd084208b7c228e8a2b2ad3625b0839cc1ab8c9798b2e9706ba6d7aa623f3c0ce0985bccb2ee5c05a313000000000000000000000000000000000e1780b32a7b17464cf514efc4bdb02283af396ffcf6d1ae023e07fae02becdcc3c467f89f8edc9173a71aad27b200da000000000000000000000000000000000c3e7fd95dd823338bdf3d82fd46c265a3f794d4065d83873b1aca66da5f80c5962c9dcf537fc315d024d8cab7bed89d000000000000000000000000000000000e4eb722080e24f54fac7eed4b94e7b1eedb081c3edd7aaf5433d00829929d8bdef940aedbdd7dfb0376b3ad5544d9cf00000000000000000000000000000000158c1ff057f7ffe6492097e339cc4ce56bbefd39658ad55e08d5407619d1cbea7c83b977a1583ee48897a5e9c0d9ce3e150e53fb45ba8ce5ca917010f26451220be51141fe21cfc1cc06a5557e8e7afc00000000000000000000000000000000138e8bc8cfaecba9fd1322a3c1682c9fc1286d78e5b6718da00acc69f811fe9f94c9f0dc9d80e9002c0022c6dfcf156a00000000000000000000000000000000021da679a068b2f5f473ceed588f07adc7f485003f7d2286a18c07b09b835881f4ab94c7d4ec742c33a7cf01801116fe0000000000000000000000000000000018a62c2f4a02b73f5a91f503b53332304afc9cd8769f236259789277599a203b8b304b38993835a87d7cc970ad514d2400000000000000000000000000000000179396865f859386df7c1b8fa84c4ee71c14daf695fc0841c293618e6f8c87fb56b924f3f91a273b969e8635d7f90985d69ec73df67feb970f1c7a3880ee84d948eab4d8672a6c1481d61efc6cd710020000000000000000000000000000000004a8cb437297722c0c1a9471ff083ce60ec40c908af4ebb570c87133df705e725e3209152bcff26a0d6e4602030610d3000000000000000000000000000000001832e55a9e703d727156e4677ef4f82b86c6764123c3ed1dd94ae3b46d7eed459114993968eaf8e21cf24c59d042f41d000000000000000000000000000000000f606d5ee57b188636334ad60057cec4008ace88f14ea06324edaecb26da627670b44b6ac57b9fa2717d03096010785300000000000000000000000000000000145bf70f90a9d98f56ed38b3506556a48a1340ca6161806d055d7a1382eed54e294564de7fdbf525b0012de3d25ab5c838f8acba4782dfbc02a14d4b1d7b2b0a582f9bd75642169707a475b1a7d2d7e0", "Expected": "0000000000000000000000000000000018ca453b9d832f029ac8c7c70df846be97b530e6e42de3ba6943a7d0dc00296942f88eba6a9cc3352900ff124efaf7d90000000000000000000000000000000002e4514102aa3f772f2659ae9f1e2a91c7fb749ea590a3cea2c1a2e0f7236f71e182374cf7ebd2fa086dd921c29013910000000000000000000000000000000007c025696cdbf403494c5fc7f9a10ad0c549f84d1e06c5c4bb22f7a039486909c540776224bcdaaeb3880ae9d745dbe5000000000000000000000000000000000b5b5b70fae8b3953ee6661a0f4a1be25596839482d78710e584d3bcd93dff2b0bf4c8b20974744667e25fd8353cec0a", "Name": "matter_g2_multiexp_57", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001265e90c564693db716f17d1a8815a8449e43b5a2d5446ca65160d864718cdfd413d5aa024e7581421c7222c29eb452b00000000000000000000000000000000133a6558baa53a2b8d239198e1dcd81af1ee46d55137177be467a99edf282edcd47b7861a3c822f9bd0df2e86aeb5dc2000000000000000000000000000000000d8287564bcedb1e57c3d74b0d484a9b475ce3f5b0322bda0e980de8891e2e8663abda99744b58032b8d7d3adddbac9500000000000000000000000000000000013cc35410d7fe07eac96abd2b35ff656e17b6b1eba2bd1d75ce5c87c5e76755ef9c2cce70f05cdec15d1bc44bf902d4cacfb05e5d10c41b06a487e9f8afa38759eeb55f0a5bc8640164bbb081c1fd2a00000000000000000000000000000000193f0cd6b4051cfd89f358cf6643528f0f042ae30ba3627d297b4fa2c2936426a9c1b65145b8192f65dfaad1f2fbc358000000000000000000000000000000000a92ca8943e64a391aa39126f093f2b530f556c1e3ea1b55bef1c264909dc93d260eec6420fb7a4e4a45f932d57951500000000000000000000000000000000005c7dc5832f744089d5fe034bc93e0bcca042ddd1b221cdd5958be86214831906ddbf82508dd91dccee467fd1625dd740000000000000000000000000000000011b11b3d24f44bcafbcb9baf62cef3f18b56ded696b73577375dae8108dcfb663d437e4cd9e44b7e6bf49741e058f8cb9a0b88d946231cc484550a87a548719f0a543c0698411f230a966cf602dc4de300000000000000000000000000000000073872ce0d74ea368df132897617aa8f941b67cf3fb395ca6c2f5bb2c551f17d68b0c6ef11e742206d6559796f06426c00000000000000000000000000000000156cc28eece7bed943c8410a44af112edd8576807e25701093eac0c9726f93da68a19c1d7b294f3ae6c84e32e7c2d5ba00000000000000000000000000000000050fe5987d5fa678be3d34c50fa6c5296f883e65ac3201c333b97ec0de00dee6187d2790c357a3f8822a174a534539a900000000000000000000000000000000177fee6e2d3909c0536acdbbdfc716f6ca19b6bfee7920a78ac9725c85114c69cd13152467e72270e35006b3c6caee8c74e3b5ff944bbbbf808f1f469a3380ee7dc37ebecdd8fcdbbd2f2561e0dcd68e000000000000000000000000000000000dd147bec9e0d1727c9d7597dea4a5b6b15c0a603dd1b586835580468148a502289fcc38194b2fccdcd8fdf0d8ec1904000000000000000000000000000000000186501fa4f3a20e80bf297e8ef1885b7d157617701839a3b524d61f35b2eb843ff0af13e253bbdef653a83e07a5871e000000000000000000000000000000000023eda2ed9d34aa253c8bf2f3b66b3c0c2551cc0e74f43dde2e429d9dea113a62572d245b44708bed79d662d9cba487000000000000000000000000000000001041cdaeb244803556e9b20db95f2a66830cbe47a68aea262865da50ab15ba658116657625318fe46fef393eeb6f3e2ec23064970a4ae4ae648a79edb193d98208418d3489e9b5b8517ebe99cc32b4d7000000000000000000000000000000000c27b1feeeb38068ee52b0fa440af2e3bcfd16601c8af983d259f2d15316b513ac3e89069bc141f02b934f2e474253ba00000000000000000000000000000000183f966cdb28f344ccae4cfda63ba6a6f29d00ab942ae7db7572cc09305e4f80c11305527b8ba38c40aae5f23165cf9400000000000000000000000000000000049cf59bbd6c26ab3e25b3cb94878271c73c0b4436573d612311feceed0f1668f4d79aad92360c1c97d60b540239ae630000000000000000000000000000000015f35eb8e4c40cb1297f7128d99b109ca75944c1943abe9158813432145a4a2a5663b55dbabfa48bfd9dd01907e1e8d3972fb60ccab83b6ce042c09ead82fea3d2cb891e21ddc5af7b5d8e334d5a3264000000000000000000000000000000000e5d9a671862733804f517dc9cae2190ef0005f26394e3161fbe771b9a486368871f4b1f10f405e45048362f437238260000000000000000000000000000000008100c6f96ae7af5fc86d9d91fbbefcc1bf5873dacaba9c3adf1b2833dd529d87f303a55e5d4098153377effd0f8114500000000000000000000000000000000010e4863a9b037d4ae6dff827a34be04c7f1627670b40e5cafb1fbca2fbf56af9ea6b24548db58e3119db64553d18cf200000000000000000000000000000000036a298ad5e8b32041a18e3f6c5847eaef20a5b63ddece41bd7dc4c4a54deb9c6d7002e6621aa01d78d64ec9991f68fbdb68c389b94c82f006fdc637696d8085b24897177d2992f504d4bcf5ff04d173000000000000000000000000000000000f62c0bad83c41887bf1ebd2644cef0577d793c2f3d67cbe43974f460a4afaf2e412fbf9ec97404e5e882ca0b23bd1a400000000000000000000000000000000191562ec9ace63ad2aae1f7fa977b9e0606e1da9775a978b2caafada4f6b3d9104562f2055fe037cd06df6093123a08e00000000000000000000000000000000156702c3feef1baf5ba202a25b9dfd5c1fc620e837501b0c5bcb85ec8b6e3e92bad1fc842bd1a0dac363e4bdf0fac87c0000000000000000000000000000000013a4b7e869ed9bdbf9671a5d8ca9145a2e97b6885d2a93b33f378e649e0e576be65bfe849119381057337315363bab2f4510c100005f2306f4b474d3843b4a79d04f0171afc5c66df70f631b0481dd330000000000000000000000000000000000a4b273438168494f0db235f535bf31893bb70f4119dc4741aa3c5e63e93b9a8bc001faaca10e37f36e130ef53853900000000000000000000000000000000010936551b148e16249dd934fcc83dee55279495c2a70d46dfc45945a69549657c3dd7cce00d8136e28d64b0c800344cd00000000000000000000000000000000115c053ac0b68573c3abd5f047b8fcd897e3d514945c5fe6efebf1921563d0079eadf32f7428ecb703d9163bc7811ebf00000000000000000000000000000000162e86af01daf552589b62be849e6176d74fa5da9b214a5cf2285802dbc44f346eaee5cc3d93a085740f74cf7e1b17e1dc682a2be4d67852d119795988c52230d8273648cc176ddc012a4b4da5a8636b000000000000000000000000000000000d77cb5045f7d4578621c76bf5b3db076661c72174508279280de3e92f0aa57057ab50180f0f908561a87d412636d964000000000000000000000000000000001853f9cdccf5e6e4b87231b153ea5257f52ff10dcb24cbaaaa95426d0231dbb355f9c47475d125ec1079b9bf26b23b560000000000000000000000000000000000fab825e06c2329a19de853a05c4bc65f16fa047eadba8e79607bb31b84ed6541b00f7f14b15687d67cb4cae0ef9c600000000000000000000000000000000005deaebb5f31a62fc0bc1af13da63d0af3c716df8c9bf00f1e831af5882b88974c49e8d35db2545747c85ac35156bb668af6b200fc8e6a57a954226d9a0254c8bcbbc55fd6c3db5cf8532323d4c50b4b0000000000000000000000000000000016faa5e91048badedcb33e83684d2670051c82b7a1d0ead0e28f4dddccb141a8ed1fa7606e4b6a3a893c55344263eb4400000000000000000000000000000000019b2c8758abe5d339afade4ad0c1d44d651f185f8a0030b81b136d5972510b353d43cef616ce04827d56255419831a400000000000000000000000000000000124b1e87f343a890fd690e384cd156da57f4f0fc5b1ca99c73bb0571332ec4c12d3ebe955e3ae792efadc1d5c0c67a410000000000000000000000000000000014cef10e4a9a41bf117aacd2fca5f1364a46b0c4aa0723a369fc6ede09dc76dcd8cb67fdf87ac49bd4bd9981a2e589647e2036f73e8cd5e42ad86914e192dd969465aed0c3b752986b84a0c2444c90b80000000000000000000000000000000002862fd5f38154dd452f65de0d3c1d54403cdd2a397ef416fb92e570913c543d3368a95fa114fcf48c3bb4b68895ba33000000000000000000000000000000000e7185443e5dbb656fcb9ed100949f8f7052ee2cdcba4f5c687a65a1b45bf66ede5c60b0c04845b9a870e004f8af8450000000000000000000000000000000001817be6d13cf2a67225b2eaf073e9f1614f3bd32cf5572766ace4a91f6b6be56f498b989f1c3dd3dbc9a819c029431dc0000000000000000000000000000000001cf41fe428b088a17b8ea93a653677705d5c024db530b8300752c6b100f2abe4c46dfc24afdaa2b3d53cd8ce0df1b6a70cd5c1545e76027c389645da1089fa88f675b5b6ef9217b584d7202b797f8520000000000000000000000000000000002eed272430ca3176988272e6157a18df7151bbfed5b90979752a02619ef467af8083208dcc9c7d926490b1283baa21f000000000000000000000000000000000a644f6137bde232c3a909b742d30bba096ef88b711ef100144276d0944487f9ebe8331483978a47c07d3a42c441310900000000000000000000000000000000042c67cdc10efa8301ae95d6d4f21cf152f04b235bad2dc5a61724cba64083f690b3158676ee6ef10f52dcc7061f7c7d0000000000000000000000000000000007018d0aed5abb744cb998f84140331fb2cef8d9e09c76176def48a85370c6247c2ac6fc726eea891b2041ad5edca7f0244041bcfc21ede8023ad80b6d4af4b2777c0204ca5f61854e6da34ff5e1145f00000000000000000000000000000000141c0edc966b7c845d4e68272c6a71f8ffb7fd8d56b7cabcd556a98422f830d7a81d123d701ce1479e84047328ac1f3100000000000000000000000000000000105c1164d721b6dfb05b6b69955b2f25db0e9fdb58600a3229dd516076087aaec05b837ade68bd2a19917eee7b9a22bb000000000000000000000000000000000da3dd97e693948fd6955ae52d493b3a2d2896dd4ad00a0b549d4d392e81593472e4f9435a8b7977f3d58e324c5b9af800000000000000000000000000000000068c531ddb26a2299cc584b5bbfb0235fd774a2447134c06e7de8b94993804958bbf1ee80728cc6db647e8a244462372ad7572da641373708bef008057aa5af1cc76ccb882bacc50a77b37d7047b1bf3000000000000000000000000000000001881432f4742dbe41bf774930413c98d49a781a48d6c64ee1a18f3076bc6c0e1214f92d5bc84ac65ee1c586c437d697300000000000000000000000000000000067e0a95f3eb826f3efeedc1882ecfa30b8b96c92f626aa324f4044ee74531fbfd50a221b1b0e0182d759d149d51427d00000000000000000000000000000000173f5be7098b756ea84f030e374973feb4f8811118ea6673db1db75ec6909303e571ec5a1d55a6bddf32fc80480cf103000000000000000000000000000000000f28540976a6ddb277df5951fe58e7310861af837cf31fe31c24f7b979f72ef1549372e7ea1ced15b655d24293dade7854b51c78093cafcb57c4c1f172d08257c379a9caeb5b5478cacb4887119a08c600000000000000000000000000000000188f296e218719bb9cabefd4f33d5728a1d280bc59c3d826a0f3b5338f92e6544a4cf36f1a493458e0adb246c01a415a0000000000000000000000000000000007dc8e4222c7ba78190a8e72ec7e6980e2581f51a8d6c41669b6fc9e16d50a2bf4d422af73398e76b2f39705eaf8a6da000000000000000000000000000000000b25a44523323301cc01b50d58726768c2cf61e691203dd34a0ce8d58fe4f72c1c33abfb2a56e0425fa9b7e2fe48e870000000000000000000000000000000000c6f11ea269d9061d2f462ac37401def1b2b28c47b84344d04d1f026add3237d99a586e3fcbae347a4ecb5646c8c569fae3bbf55186a89740af4da6c073d8c0e331542a2c972a49dd3bf65261dda6e49000000000000000000000000000000000c41a02e937f8cacc0be5d9f2d9fff0d6d4302fd252f32145974206463854b3a7d09b3b147cdf2d7536e970dc13613ab0000000000000000000000000000000005f9367f4e31f7e4d6e21664ac13d55f501f5368c1ca77fc439db60e1846861e6c4c3c44909469f88e02cd973499992300000000000000000000000000000000131fe6df7fff97f132bfcba1d2599a862c1feb514a05b4b7b0bccf49e00aaad043edae9346bf726e2eee498dbadf2067000000000000000000000000000000000e59044f0950a741da3881282697f4a1a522b026e493f6009227da4c0a963de622d5e421c30e0023f4118c9a036274f859b43915b15c509ab8930979312dea2ec9cfa9f679b004ee526aa5dbb25759a4", "Expected": "00000000000000000000000000000000144433ad3afca0a9581e7e87220a4944e26ef2eef6b887ce77d2a2559ced058e7349b36efa66c492cc75b014b3448ef9000000000000000000000000000000000267b90e45d7001edae01fb198d16dd37c43cadcd2ca87bd7cd1f0f65a95148144f5ddfe75d344eb4573c1376aa2728600000000000000000000000000000000050ade28b09b0394b08d128c089808021e4c65dac49d9fb45efb93792a4faf210230b650fc3ce810fb8d11947e9af5060000000000000000000000000000000003b1d7dd7c6d944d16724fd1bbfe0f53b6b50a70e133dc5998c82b51f817f489bfe1e0c361be36fa41f5af7c1577f2ea", "Name": "matter_g2_multiexp_58", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a081f037738b0d812da43a907e7c624e331108ffb72104d82725b9c14dec8449f5ba0e8c1a3f1379cad2c3e7aa99f70000000000000000000000000000000000937fb5d8b3c258b7b28555fb59620f114816f0fad46818a5f100bf7dc3332a03d285eda18e31e4047cb2606bc53b20c000000000000000000000000000000001574e355b7570043bf36ecd52f9c4d9ff556146d81a1e9d088444805db9b3b678fb55774865ad34d21022afea2c154590000000000000000000000000000000009f70a5cc658cdab280ed65e13aaa319049b9534a222217a08168047ee2491f25a9d2620c7343a6426bc54a0700bdb4fa53d5989b63ee5f157cc44c684ccc7cb4c74338b12fbfb534ea33db341fa6b460000000000000000000000000000000015a76e89c8938b8a27e4857aaae8c942371b6979605adf774827e9438ef739428fc53b65d32e4e152cbc6a4de42b8bf30000000000000000000000000000000019494030ae0507eeff20b69b4913596c1b9ea6927157945c8295e273707013ef1f2cd08c058f6b469a6c99ad73acc28700000000000000000000000000000000122ea7ac21a27ca7c4b00207538bf561f688429999332c45de7545046acbd6d9e96d31f5f6a00595eeb212918a28d2920000000000000000000000000000000018b023e7da67cb8d9159746bf700f9e151fa60ba8f5a28b3739de005822929cd28c49b9dbb4ca8a10729dd24771730ff4d840680013af06920dd06bacc0ce95cf0cf79e8ccc0b10027f2d28c1d0049980000000000000000000000000000000007811c759634904765029e955c3deca648fba6a9da6433b50a6d2086a59e65811d52d41ed8ff2e9bd63a4c0828bc702c00000000000000000000000000000000182c86cddf5e20697462c829f41c7b49e7976880311b01ed4d12d7174340799f19db0f295263a2617182bfd1b49e0d1b0000000000000000000000000000000011824bc20bd1b27876b4f48aa8fe3063f826b6b2c3dd777fb8999a25d9139f218f6f288955274884ce96ef2dc6d34d120000000000000000000000000000000000dd310d5e141e4eb13380db828caf74f62878959b6b2df998bebf9306965f723fcd4dae7c25bf2f79ece3e8e9b92de61b67d661ebc9008669bb4e5cffef81a32baabd71667a72f1d202ced823f09c740000000000000000000000000000000005667d8c4f8dc3f4aa0021d1026a1d0dd0bc3576c49339262e84d20198fffe33a389d28ab1d782e9d19af761a2f097b40000000000000000000000000000000002803d5ad6393d7072e149f1f2ebf70cd8961ba3bbefd648916a8ac5a5eb893b71bb6015e201dc241537ad5890024239000000000000000000000000000000000122e1d0e0859b04143f23c4d2d2ffec09ca2ce5eaa9429dd0c047032d180bcdb10c106071d9f9701c006e5eb8ef88130000000000000000000000000000000008347a7bdb3b4f381b58ed3a128134c09563b345380ec948943e738347de5b5737540b57c28d00b9d060c60942446617ee495199ebdebda02179432d42d5d9c76eead4d4993cd09a93d46cac997716a5000000000000000000000000000000000b26aaa46a279c482fb395ddb84d5b4c9c70102c336cd565ca9eecf62cb96f59f634adf46af748826590fe65beea752b0000000000000000000000000000000012cc63256a9f73f450e86ee38c54ea78baa5bf87d3bc01320f7fbd85bf11e19f75d787b9b12b8f2c7634368a9023de880000000000000000000000000000000006392fe611835f6fd50229725d71d435f704f78cabd1b5569e1c5a89d4b11f911f0e34ec034369f972a80eb407938b97000000000000000000000000000000000f4ff2d6a991fde9093000d7bd9cecb289383d259346d83bc9bf5389d4c39c82a0e1d7deb84b90ef370e0a19fce28d2b3e038e473d6f965751ebc5f69eea6f37be88cf001de0c4e4b700823d8326f17500000000000000000000000000000000193752c40fa0f466f7c8bd26658f133d0283d2ac3b02eadd27b3e9681329307f91a1512fbc53e537f9e1025a3d68a7ca000000000000000000000000000000001106d751c9e1637f00e51e0be856405e6b69421d81bb30b9b8718cbc9cfdc36c80d2848bab0d5246da84f10b478fe48e000000000000000000000000000000000827a83f28678c4e39c4963e95c2404a70691885788e5457e149c0c45d4e8c74eef55223ed15cd75fad9f7209a6ecaee00000000000000000000000000000000072667f02b781c8e0a75d0ed8f3d55e668ddcc8c61937c80653e240c3a744c961055c782ca41b15211c0f1e1ba800bf5ab2af2590309c9b9177e4f6f0fa06339fa720cf1c9fc7c001785d7145a3c9030000000000000000000000000000000001419629aaf0baf779feca264d0d9846b987506125b0049ebc8b307c4e3ffe00da1284a94a012bfd60456a4a937b2e0e000000000000000000000000000000000119a801bd0a5a1c1b25cebbbcccc7d2bed9baa4995483f4ae94121a8c6cd0c3f90a26234f51590d66cc38b8bef9020d3000000000000000000000000000000001125bd15fd9814ddd15be0997a6961b6f1c05ce7944514371f10c8e5bde271c4b936d6537d91ebed740fbefe6b281a0d000000000000000000000000000000000982a2904a524b1fafc50d540506b8fb07c3b4978310bf3cf53ce570b1b05e746981bcfc06d59a78d170573b09347f3fc9551f12084ad7d4ce346f841fef785d644821b5c2d3c8db3145fc26e65666bc000000000000000000000000000000000b1da333e508ec6b0329747fef35cb926d922091d4a45eab7cb5358f20496c66e17e46874ed9600cf4252432c29aeb07000000000000000000000000000000000c757daad8f3ed7dfd64782548eedfe904f7ef3bcc11eefc4781fb37159d07825a4c9f3fdf9cb3d8f3944277bf25f88c0000000000000000000000000000000011160e21503d6fd61a2ca0212a7d48317186f259a987a17cc3eb04a6d9251736e4a66b739a8f3095684b7d91ce6f79730000000000000000000000000000000007440ec0f9197352a3148f9bb3d3dba9b1d5add903e48b50ef3f6879859b22ea0e31b46ea4ce566930d8853520abdd14ef5823541696ecb88d0c71e00a15282c40d4826220a202be09c47fd6891b93ba00000000000000000000000000000000070ffa4d522df8b9f62aaf36132bb1b857e177280a7b6d3af6bfc79b73ad3848241df18ca7f8993ae3d67005ead9264d000000000000000000000000000000000e32b65bf035bcb11f86c60a334622d2367797d0226761b58a7db8c7324fc4bb498a558eec509c2326fbd0e7bb8d3d19000000000000000000000000000000000dd291a760393c6e962818986727e5ca5d46544dc47eb49dd828c6f74caf0599e88c4293881714c425b0697944faa861000000000000000000000000000000000f7ead0be081467f3371ab92c249cea73dedfefcb6aa16a162c06e30605e104844c3dd194b4a89ad5230f596bef64f19e32d695dd02323d40ac1eb9452cc53376ef941237563b1ee380c9824a565008d000000000000000000000000000000000ca545b53836899e507880329799e4c1a1acc17275f5d71d87b9e41ccd7a090da854f9936254448c988ec772a813bb6e0000000000000000000000000000000016c9b03fd01394560497d6a03add63c034f96744d96a13a4ec92d28719018d1eba1465e4332e53f37f2aec4d93d4ab7f0000000000000000000000000000000007019f5201dce326d5a6a1ebecf3fe50e22335593bc9d3e62256351c591f0a1a577d916055d79c0b4abe191b6b8011fe0000000000000000000000000000000017acbe72fe30c386e463f3e9b35a474b902f6712b30af88ef340e6fc6ec0fe2e606c7e26432c2a4de33a12e35ce41868f5e23ff8acf88d18e53bb31476f10fef288e20e818431f9f0d2ffe1265e8ea8200000000000000000000000000000000057f856ae648279f2b6dd17584e1388e4dfdc9e870db48ee6ef5f58389ccd4ba17e074b79ae12b728c59e2f91bac5709000000000000000000000000000000000e0f39f4beddbf05fd700458448067b52c11e963b22603f10d697d6b6286b1449b1663e032bf7bea48f2051d8ded923f000000000000000000000000000000000022cfadc1dc399ef5f12afe1349d9274cd595a9ab6ef7ffdd68f8bd2d170a4a783ce0a7303878d809a16bb8073d79860000000000000000000000000000000007e301565124eb66d59a70897f2ac356e7b0c1bfd4e3b57e508ba0cb5c9c881f9de86b91fd5133aa2977c8e81138d66971927817449ba5f053d0ed1e567b53b1179c6b62a554c8be6764d7ce203f74e4000000000000000000000000000000000edf3fdbfb03bc07871079aa4aade538a97e1619b54d0692a7f5f73d7fbc8abbf680ea3a99325e03c0501ef174deedd1000000000000000000000000000000000b8c1b5d3c926d7da6e0583f67d981af5286a04429e857b0aa4b1120604f9c8c93f04e763da169137416dc9ec4839a910000000000000000000000000000000006ca2aa4c7109f043da9cd90bc801404685db802eb8bc925d9d098e7af3d9f95ca490790b2b1c77995c050aaebb935db0000000000000000000000000000000001f40a2090b63f94f93e8b61b5ba1ac62a37548342ad81a9bd99ce8339435a7d7477c3b9cee9b531a1ecdc85a72041555ce5d6f0e44a20d0a0e2f1cc523455b001dbeef772d84b2599daec66b285027f00000000000000000000000000000000021464dded318cfa86db1e4329f302bbeca7095d910c4260799cd2a60ebb20e60152868e67a48b86f44000f267d11c33000000000000000000000000000000000ae45fa46fc8e043c3df99bc0d87ffc5867208fde0eaeda782230341a8624b101346f35fa24e1dd67ab200f5d6fbc8a7000000000000000000000000000000000795b9afedbb128a46c1eb25c52a71375903adf7d3520535372d9af5023dadb1dfefdcc0cb546e9d218890123252946d000000000000000000000000000000001852511855bb368cec51c54d95b430259f05dba6bae53b5c42d69f31371c30cb611037fbd81393a896cbdb6240114549d37f7bca1a59f65982294755ddf8af7f1c953b6e482fee854e0d89e9b269e0e900000000000000000000000000000000113b883c6bc41b0673145bfeccda414af45efe5710f436977712e7227f38911cbae851dbe03928f38e310033458eed72000000000000000000000000000000000853e32773ef1f95a3936aacbca50cdd5eed3d08dc467d7ee834487e445fbdaeddb0df394bd0c91fdb06d2883c4dadd60000000000000000000000000000000013a7f9cdebb2ec37fad172d31a717f4b538a8ee74432c5a5e6410460eaaa3b5f24d223b76bde4277097e93087b7136330000000000000000000000000000000003d6f141b56e1e2e400fe821524017cd972678a7d64f660c313e6a8910b72b5ac04328d45945077aa2946931c8dbd11706d0535e3728b9e358d9ea82df4f1137db7a02f79c0cd0dd672e24092bf7f6b40000000000000000000000000000000016adbeb3530f6b451d870b2d8292a01143986cd9890c79a64764383575771b8608ea61beb2de87bc034d3b8a085958be000000000000000000000000000000001125d7cf83239e4341c286fe0c8739e7013b234814b26a079ffbffa329ee4705da81fd12f34f49d821690a11b8f83c5e0000000000000000000000000000000005873dc5c0baf0f3297d884ac7b652c749abd0405b96ba60fe396efa179a79fa55be76924b0690c9a528c605ad4f9e120000000000000000000000000000000000fceec23f479c72e0fea0d10d3394d7121bf1673250cf1ebe72eca60af82f232fbee342e2c8705434394d4e519fbb40f56d6810620e8da932c202628c2fa9f0a9f3fda3aa07c262924aa51685d2c9af0000000000000000000000000000000005ec966cfa28e105f3496f977a2f046fb206a190fce1a6062df0fa1946f274cde9f6fa8a71089af8cc2fbc2b60746cf40000000000000000000000000000000013c77ab66fa92a2411391d366a331a40accd120db1c6a656bdd92858826fcbded296293c13ee189ea3f34635de56732c00000000000000000000000000000000162795b6feaf6a63e6ea2d34f2bff2a4985ad26463b8fac69f8525eb0a005bd377fe7ff4aae820d361592d2d88f98f5c00000000000000000000000000000000044c9d5d3bc0d99693f5a0605ed467cca8b5dc7c7093294d14015b59bfd8ac6bd479b73ed52fd30d8bd891ed971912c571e7f672ad398f5c02c989b475d12ce86e6e242d36784308e56178f2a6a1517c", "Expected": "000000000000000000000000000000000c3bed2f51a60f9afa6655853ec2f0e9d46bdc1277bfedffc468d9f36cfc7ad9e70365fecc84a5a40d863dcaadabf22a0000000000000000000000000000000008c5894a4f93b02fa1deda8b556798fb7d71f53046ccc305588bfc00b68bdfc34b3f0bf154ce7cb50c9536ad45e65f300000000000000000000000000000000003699501ebb9698e98dc998fcdac54dff895457d2e4e0a0e2d65d275b5798dc016e921bf1f65fec0f284a563aee66ca70000000000000000000000000000000010389c73de7f6d860c972c1f09dd24137c898e92935c45c10565ef3da3406cf521647ef80688f6e799eef4879ca9a6e8", "Name": "matter_g2_multiexp_59", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000114b9c33bd09899c684e81a5a4e620eefa4e620c01c391a4df5caa75be462ec7ab027a9ae2c31d6643c48e3d75b6ced6000000000000000000000000000000001925084d2a1f537329e23c77b8a820c385ec5e12e4a145888882ec611e99b05b789d79bcab48326db4424309c24d1688000000000000000000000000000000000a1dc78c25cd16211a38bd0c70d24c84da1b83adb219e1b9c06fe6a6669d6e0281a155b4cec32d32751fff653aeef1990000000000000000000000000000000001daa74f19cce1086a87232464ba903938465da5e3e1f9ddc05a4b4dc13f1026e1b07af7254d515d2ad6960ea62dca1f77f9a79850b2fd5a281b22f52de085f12bd34e56808496e1c1388804f534d2da0000000000000000000000000000000018810adf0cc793c21726e9a27b7c558aa16b81af73f22629c478d293208a107fbfed4511d9cbcc25fbc2826bf004e7dc000000000000000000000000000000000356b25cbc7cf65107438125c930dff24b7786cbd7eb744d7f27967619d5cc02799451ac8814782eaf9aa331e6f8dbe7000000000000000000000000000000001164ab32ddbeb11c2c8baf7f311ffb01bcc367395bc7ecbe5642d344a8e879c74a554b3f9e4b6ed7db4ea0f872cf96740000000000000000000000000000000017704b1dfb111807d1f5d90c370a5b2968008a5ee9fd72262b6543c93fa168285c04931198f5195f1abca648722ebdc5630c1fdad9338fa5236f817bada168a737dd3685b327fb59d8a37329920af4cb0000000000000000000000000000000000a336a04a8fd8e18dd9a582da897016983d9beb0fdbcea6c88b7c0640620be52bff32afbe700599e3c08669c457b760000000000000000000000000000000001765fe4faeeb13fc2c007682c031ea7ff2899090e16a9a11959c5c3ae7881a1dd2c6d2b7f5f708a92349a2b0de4b92d5000000000000000000000000000000000e7c57db660133ebeadc2cb2054ab4ed16355466932685d4d11038e1e1f47b0349b68bc4e918dd48ef8e1c5d7cc53f7800000000000000000000000000000000169b629ddd7add588b91d9866a750570dec58662e43409031a5e25f1b2913c5c5a7a7cf666953c99835431f091ab1b140969599bed4899c3c47e1d4081027203c73233536cc6e45aaa78a4f1150a51620000000000000000000000000000000017d03e9855f3bbee719a15208ae24324ebf1879972ac134b027c9e03444a5736863bc55604158e81b38c7fd78ba4bee7000000000000000000000000000000000468f7c5478cc0faab7098dbcc455bf18525b56272c2d02cc1febc1825579a613edc6b455764ffc71c903a0704224a4c00000000000000000000000000000000067104ba5366e7e11bd4d516565d9cdd93d4390f2af3c1ef2ea3b1e84ee8e5c0e0fd8ac11ec9d2553e4cc13b277d473e0000000000000000000000000000000012e10495ba15b29c669cb9683b2fc7a45fe7ddba743b4a39677fbf85aa738480eb9da967eee69b02ef14137e102e240eddd438de35651328de7183dd38820ea2983488ba31d401094e59cacfcd1d031900000000000000000000000000000000078f8c17427847ddaa1665d206866231a5f36d3a7b4e8fa13910161566163006b5aa5d9696f423d0c44195de65326f21000000000000000000000000000000001613c465b65940f43c61b5e3c93313ae49d92728518d9cdfc57b49d6924479b70e281e724e04fa5f165b5999f1c1ed3100000000000000000000000000000000031741b6830c16d730619457d42767a51037fb4118e00bfd6cfcd8baea35ae76a5159bf1f4639fc2951f0b57446110e70000000000000000000000000000000011a618ffbafe4bad0a435d04084233495e5f7fbeaeb66d0d49a8177f562329b52a5ed4fdc680b791f273a7b0d3d4b349191f2b2cc76d848e456d07c84c0826a8861981dc84bdc671bc9b5882d387a41a00000000000000000000000000000000043c09eea638e524661c60ae3704fd1c18c46443ae134a0ab7b9a98cd398377febd9026c28b3e1e50de98766aaf0083600000000000000000000000000000000105918aa1476cf52f91b9ddb7c23ac18af3bd5269dbafc369713687010720affed6b12af9414cecd521cf0c7f5416c350000000000000000000000000000000019ab4a3eca904a15782f560bbbc8819dc09275f1f6d7c3b8e98aa0a96ec33dcb528284636b0f42ad0d503489d17161ff000000000000000000000000000000000a2abada18e79c548d5829991a65491ebcfe0e1a2c89a1e05f06a0ecd197797c5ffea0ae90b61f54c6b3fc844e0eb3ddaa76094782d0c06f2080d699b81aa04a60891046e0053d2fa757c7029df8f848000000000000000000000000000000000d457cb2c77acc8ba4b19ade0c724a2b6b0966ecfbbec8cbea745439b9bb7f3dde2febf9fcd6c5e6139fd7175e57b1720000000000000000000000000000000003154466283addb0d0b5d86a9633f8300960cbe8bf6a1405a3a040472542e9da63fd4f79a43d641a47c2b69a31298d3c0000000000000000000000000000000006599794823797f8ccea9daf0459b9d26e0d207f5fb95383c6b61eba38516b272e8ae6ddff2a9fa791e69c0eb25f3e470000000000000000000000000000000018be316bbe0416ad7deced1486d4e31490f5dc7e379c17542b7d3e9dc77bbae9c992e657c884db320cd51c2141a4abd2049a751a406657dacceb3721461417571a0104e11c1e00805becf71ee77eadf10000000000000000000000000000000007ba1ec5293d169b88ca4d2d92eacd51f0b8cffdb403632ea8ffdebc37f3997baf736771231335d12717cb45b51be31a0000000000000000000000000000000013505cc24222fb2ba9e25f5f3497653462f5b10bdd0dc88f9b16d5643a99ddd4a7749dfa6b566f41cd2da7c2b1ae93d2000000000000000000000000000000001465fdced698ca76d5faaa7e4faf1260cd5c4fd2939b16d3593e3588c92de3d003540ec989be9632fdba4ecae889ef180000000000000000000000000000000013a20cecd5e8f161ac70e40b8e9ca4c23e2b267690a3abea941c293b03acbbe4fc68a1e7b6d35b79ac46f65edde73a3e0502d56084d1be7179fb735e233978a5a3c2756d780cc0ea6a8aa92b1d1f7c4f000000000000000000000000000000001936436783f02f3a5307bfc0bd8c0a00ed8013508a440d040ed4f45b37a4e89986102964a328e93fabde6d9dc7ca424900000000000000000000000000000000000f16408b869303181b4b4877b554353b26a7b4750b711f3c41cc4b6682b2113cc772cf9bfcd0cf60e59ef29a5d0814000000000000000000000000000000000d5880e2ef94663ead736687ee725f7ce98fdc594230c1ac9e8345d39754bd616e261076aa5362776a6026129bff105c0000000000000000000000000000000006865ce3cdb5081e86535beb990d95ec3d75f67c7e881306607e4876c42714d627f8d548849aece4382d1c8f2b693bdc9787a6720b8db1b4f0e1d535833ed20b519a0e4d2e9fef75022aafef523713750000000000000000000000000000000016d941b6a0dc023fa2699c836b74e16c31b4cd51538f73fbb271d163519d4de1cb0f6ec2f8efde22c74ffb532c576b16000000000000000000000000000000000d10a7bfe9541a7b22d455f1b68cfe2422a83a070d93476aa0844670f02aecb36e9f41b9d66e8e9d0d67c0ba85c99f44000000000000000000000000000000000d7873f96d45fa8c9ba9cb4913a7b01c8e38876b6bb2a05506d23df0491bcffb42983ef663db85bc3cf755f476291a79000000000000000000000000000000000c22fdb83f9991c85b3577d1ed5a171f28460d79dbc6167b0c30b200235c512f999066eb1fa449115aab55128f8f2dde10b47b662e8cc8dd005bdc81dc6d98d0eb98f86b46c0c8f24481af9120e84a820000000000000000000000000000000010faf9cb9d0fcb487c9e86a2d2123105baa8691d82ebae8f5bb7d5ae7b7d8154837120eea86dfcd35ea5482a7ebf7f8a0000000000000000000000000000000014e40640eb6e8e38651a2eac05165f6cf5e0178b3711f34828766ff9db951e1348f0cdc652a78840dc24ada8b1c835c600000000000000000000000000000000129db7482ec62873591018a8399a8c5e4bf00e8bd9dd78dfa3d0b4cd1d93ce5ec7531e56d58b7a1cb3e58f062f6895ee000000000000000000000000000000000d8db3b54b6e71497faed107b31f5e44f328780cf01c62cb5ca00f99f10385ebb22a367cc89505640d1106a9ceec98c4072460e3c5349c8fec9944dc99762625262e84c70f10d0a92077a351335127470000000000000000000000000000000011ae9bc3ce04df2add17e57f260a72f88f19a1e44b0b074cccb7fd547035038d19e5f2228db46843343a69823decda370000000000000000000000000000000015ea64b6147ef76212bb5223d6d5ab9ca866799365683720866d8ce1117f60bd552a8e9981c095894258ca3c1bb5150500000000000000000000000000000000173bd5cb455b80b78951b15180fa7f8fb4725c1a12e5c53df1b9b31b45a29083e66c7116741d9aa93448c81b5e6014610000000000000000000000000000000007eba059855ab058c2066c643ef5268c864d09ec9962537d65a1686322c374eb5ab8eba4c4260ad0919dc18b4289a694f3177c4d865caebf1ef6565bc85e0b0bd51365a6f321e26b97cce887bc3f44d6000000000000000000000000000000001598471460ae082c2e2568602c99923193c913b9e803cbb7a4503ceff369e8c4bb3a19ad245c08192e12a2e9b3e75c4e0000000000000000000000000000000013b289bec9d97c529382388f7037749c10a64f915746d23d8f37e15db9dcb173b3a6d00bf45e67b8c70959472148321d00000000000000000000000000000000094a99f9b031a51b7d54f7b8865621b204c85d23fd66fe8ce007f0b852f8b5b895010745b2fc469abb670e38fbc41e50000000000000000000000000000000000e36daddab2134f65696ede36c50f90f9a1c56165e09243cd56fd3d9902d3c78cd85e7028f6dd466f6a8655da62ecefd393654ef7ad8687c8878c55a8240ae9df04805d3e2f194e960d5e498ae3ca17700000000000000000000000000000000050a818ce247367e8b57673d205d6bff8c650bcab7bf794dd32494669eff865fd4e05d7b4d35eb579eb475a3a0320ff80000000000000000000000000000000017ae5d612bdd46e1351dd1367c08c16ceb002a29832eba75e48d4c82e364f17c58525ee653a0940955b874da6a5bcfcf000000000000000000000000000000000eb2075367b42a0b3dfa30799ce1ab327eb583316d15b8cae21b716e6c7fd8cab96c67bc39e353f5e842e74995356c070000000000000000000000000000000018ca4b533da1baab37f05afc3ae0afe976e4f4530401d2f97176f5c73de3eaa75b8a34e8c6c0543ca0a08aeed28e478bdb9f942124a381b150f00a59e4579d0a2b7b728f62715633288fd03d01dd12dd000000000000000000000000000000000b3f4bfec920018663bb39c5520491da5c538f82138f03390c768e088bbb2880287196af937f1f70e215edd49d1872ea000000000000000000000000000000000037e7607a60cf235d8e4ecbe69d378dc02f0a8e40b7f23745e15a73fdcfc971cc8707d55a8c5b91d9a5f42c2f49c455000000000000000000000000000000000467df75c2703ccff1a01fa5bdebde210b61b5f3fa33e76e55be5dc953f4758c3a2c499cbd42b256ff5a2005949d9bbf00000000000000000000000000000000010d574c69050ce9e909dc23a76e9a2106870e8d8ce2a0e30d42cbfeea56ce3167535a9af1d453d4d8e6a450eff870638e6eb65778a328cf899f66581ac7a4a89e0e824c15573bc68c02cdaad89cdf24000000000000000000000000000000000907fb825f247c85d93fca36dcede9c22a409fa82fcf540593e8247c17875a1385fe009f0ff43853c404f6c96e2809ce0000000000000000000000000000000012bff10bd4162207870f6363342f2541804adc6a4e3f7b8be51d361be34def7a85fb39357c85a4e8df670fe39233bed00000000000000000000000000000000014f7e61ccd52bbf6d050c9d506751e03c8771b320872179a9f0161ac5736edc13bc133bda6239abba1ae09bd6c16f0c3000000000000000000000000000000000ca78624563584f8929d72668da70218a2da12b42c4b894108e6b103201372554fdd6b3bbbf2d94a9d0cf4053eb07d460940e3620c59504062e4e98b5d4c8cbccdb017c47a094d06253743c29465731c", "Expected": "000000000000000000000000000000000de8e87899b294575392d523ff6e153a7c2038302ac74574bfae7fb222558f2b4c9556be1bc2757b83ebc180ae710187000000000000000000000000000000001881c7688debe3ff795788c90397c3fe3d6d9f56da9221778d7b12f5a54d8c0a00e1a8d4bb9c0b1d578dff862516b5dc0000000000000000000000000000000014cdfdffbb956a20d8521ccdb214adab14975d22ffbac107b2c15f42e97bb823c6a3945a5b299d3226e2044e64f8d1ed000000000000000000000000000000000eb769b301cb7c0c976623badda4db8ccb18dc7322472b5fdb969393d5d82b3ce94bfa59dae06ece424bfcb88e24207a", "Name": "matter_g2_multiexp_60", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000164227fbb787b2d47ceea93faf1cf7890f48107ffae3628192235aa57658d9a2861db13fec0e58c347571c2ab0cd11ea0000000000000000000000000000000015478417b6758826b1d6fe0c562d43451e289dd50de31ef365ec70faf961ebb65b510c4788b6c7da2dda9cf56d3c8a74000000000000000000000000000000000f9e50d802ca8cbf80caec6489fbb24a2761db1245d9f7e820e6747bdd0855902ff211c427c00157ed9b1bffdf39eea900000000000000000000000000000000128f69ef5dbea5f80dbb9558a25f133b9ad77492250e0654f8fa5b55266f2fd26826a5c373afcd74990ebf768d6d8fd20f2f697ef6783390724e04b81d0e18dde6533eea9f72c1e10bc72c7b954659660000000000000000000000000000000005f7cfb31492dacae51caf4036d99d917fa13b0d2353bbce4e6547ea744b3a49b162deac2f107149ebc2f79e74828f720000000000000000000000000000000015ed4627efa9b318cbb52f518b734327f5d1cfbb097adc6184c5034620504181a298ac7e52759586dae2e107f121a9b600000000000000000000000000000000023e832638849599d9d7854d3ae18648e67e8938ebf606a7c86c3a7ea21cab8d4dd5d9cda5c482e05d351ea3ccd854710000000000000000000000000000000001849665396bc36d0301f4c9adbce81fd2f2d0c7f89925487d91a25c6bd0730ce31678694a319666cf42162608ef15a834680b934e67bd7518f0d6a3a809dc7faf845eb71d0247291d61053d5cbe0ba20000000000000000000000000000000012c9b607e29e35f260f3c4617b4217d5dbc6953eaeffaaa903710195e080d593972e7794897eb176aae3539401a483b10000000000000000000000000000000019cdae8d1d9035d1fc4b4db09e7da3c20d3b8777523155d407cc6565a71a6c951eca609d328ddbb165c2b5a3e6b081da0000000000000000000000000000000009c4629b67c1c50e5fcf316136bc645e9e62ffadac8495c084f97e32b0a3990b3b1019261f78de576ff7ffc89e36e2af00000000000000000000000000000000070a49e8892c5b523f5914e2341dde63127b694eef556de6dcff603da109a53b342363d9a854dda3d2833e25afd5b57eefc024dbceb522c02b88810ada9a814bfd085fb63d570663a64bc0658e5ad0220000000000000000000000000000000018d3c9259f70312c803dd6bac6488541f92482f7eb61ead71fa42bd5e2cca9338218d62835051bd308799beeed3b422b0000000000000000000000000000000005e0da6859601b6ada82b1826a455a846f8b4e54d9f22c3c639835a8a89e17ea2d76e2f49fb151f519de3e9adb78f0590000000000000000000000000000000010113d2fdc1e8ce0027b651cee6f9f6832b531d843db3ef7bf209aa00018715c1c42c68a82c53247a267929ea3c9363f000000000000000000000000000000000e7d1152af6448aca78aa7983013395f0dfc298848d86def6f017780e9cb144bbb21540a14a4d47b61d7a9b8c62376fc2c136f00c97a515076f6a0b63faf7e378f2cf04f8a90ac942fd70e25e683cbe70000000000000000000000000000000014125c81d4d7a8ea18004d798311f0d80c41c8e3a08366f686145e867192bbb13244f9f77217559cae72a150faba12a6000000000000000000000000000000000fdcaaf79c0607ebe9c8ca309d29d32284f3567a18dbbd23da9d96bad7269395ec2445d153711df4c883e8e7f7b02ab2000000000000000000000000000000000d34dd6636ef18b14f011fbeb62d33ec4358166f96f38a54c36b8797b51c1bedafa43d9f51fa4afcc2acc0cdd991997f00000000000000000000000000000000017337fab49d545caba55b763c23ce9bb3d3cc475f5ca37a15322e94c37825fc800cc7ee67bdcac66f9b5c22b03bf6558b033f2270ad2416d03dedd4bafb78ddc598810768fafd349a42438923ddfc930000000000000000000000000000000013434d32deb96edafc9a0e855281970b7c748c92b3472b34cc758dc3c17c4e6fdcf3190c910fa54a0259ef8bec75a3b300000000000000000000000000000000137df92ec14dd2fc02c0ec15a4e63547492154b4d4809e25f3ebbf24fe84255babfd6949770ba61637cc67e8ff299a2b0000000000000000000000000000000012fb20ef106e8cf3c79173e15dcdddb216c25a4de6797e411fd11d5632aef1304b36f8135c915c8c38caa2d778788f060000000000000000000000000000000014ef5cbe5711a815b9ff845e9201745f4117149b54ea3c6d1606060a192d513aa8ffe73425e37a42537773796b6fac8f202d0d506bbcd56c92bfc6fbab36bc96716de1af02aa166e7db2e2a0a4c19cd7000000000000000000000000000000000b1581a5def94e95e565bfd402cb84f2f21c181639c047d8f91044da84bb7854f5cb4eb3a6cdeb66569d99410ca3ec6c000000000000000000000000000000000d8029828f4ca245cafa7f396c25592ef08f6768e1a5b806450be6ca5b548cfb212d8c4787c3f15fe922f466dbe518c0000000000000000000000000000000000f51e01a044b6da437e3850349476437e4ff8b94fa190387099b17e6462040918cb2eba3b10d6044ff2123242005bd6f000000000000000000000000000000000991201229a856f88348381e1f2e282f0487e7daf1e5a4ac3854e66fa3d1303e3c20eb9eca605859e7d46dcfdd7615cc8329762dde1c4c91043a740a8b9639e83e809f749fc8c4853966cb2ea520620a00000000000000000000000000000000011f1bff5df413ade311b0bc3b46c4ecb11e386b886b71226987f14bc1a3a4b986412c2bfe8a4618ad5d70afacf4a3b4000000000000000000000000000000001972f49fa8b36d11d9c9d4ed6197261506b892ce6dfa932b87e686cb197560dfb8718aa413c38ee1bb771a5618c17224000000000000000000000000000000000e563bd240f5e18b518a792750c00aa5dfbea1f79b80a71369238ef15df9885d341d6901fb9168a2e74249f036e9a688000000000000000000000000000000000670e59ebf6e30b458ea505075840ed5348563efd536c31003d8d0bafdacfec7ba1ed401c616a3bab431a0fa71bb6188ea46572fdb37fe282203172c147715bf0a16e02a62bc79f33cbfe36703c95a7300000000000000000000000000000000071319574a93739586eda876ffd3be5d982e6fa04f5667873dfabfab83ddf603513394e0dbb9f418e725b02d2dc7b876000000000000000000000000000000000c6a8e0261da2ab499bf9a639a6e261e8c479f3f2b2d12992b41a3267e034c25373d4da4645626e6343e867466bf3626000000000000000000000000000000000045a0312dd5fccdd19edb65e24d5ba50e44689a9748ed9ec208320bd9eddf8d606b9340cd34ebf983e69a65c242fed900000000000000000000000000000000090b3dbebc7dd49e9f764e99c43b5915b67bdebd00d22c80e36e08873e5c5186bcd082dbce94f4f230b237d60cab7107b9e49472b9b74cefe5a951febe595b0020c43fd54150445fcdc4292c5ffe65f60000000000000000000000000000000007b04063dc315025b8545cef11be6b601fb4ae02597d75979b4946f3872764ffdbfd309f5ab3b36fe47b810f8320c1b40000000000000000000000000000000009361927d02192433a8d3c3d7871d76c6d88361774913067d16b68625aaa60f5a4ca19b6fd4140a5a11f92dec57d783e0000000000000000000000000000000012501f19b73fc6ddb4d194895e5cc2b89ca84defb7ae94f3170f25417965102fc195f38dfb7a2d88aa4b24e4a2fcaa4300000000000000000000000000000000141d0a0be60c32247f6cb0e0114251ac68c90fd43651d58c3108c728601ad6efc27c27a331a2f086d55aed54b3585fd1b6bfa1ec877010aeab030b96e80d2e27b45a93c6a99e2aeb3ccef22527c6e47200000000000000000000000000000000043f74a82ebfbbcf4abf3fd02eaa4483108a3446c9cf041bc67f5078d1774308ddcb3f918d7999d1e2c0876177cab6790000000000000000000000000000000000da7d4fa72dabb314ad8f68b61fcfa38627d1d7719bc07767f596671c58cca16e005d36e42413d03da3c643eb46b1eb0000000000000000000000000000000019f3f8f1a4008f9db1b604373d3566ae7c14a9147f80597a31839b83f0f8dcdfd829f7fa933fef3499b671867c3121fc0000000000000000000000000000000018bba4bfcf7629fcfa47935e36462cef4fa3751c7affa2ee2cb2fe3e3532d46ca1d247393ea190fb3f48077270d6a8b22810705458845232e851b33fdbcaab01966b8ed53b455873a966c1d6b89363890000000000000000000000000000000005a1e0e3a023f67aa7ab0109814f130a05c8c739036b98c70c8a8ddc1828d2cc4e2fcd16de4ef038a7373d15c78e81f10000000000000000000000000000000019e2bb467409b3dfae0b06244b4140de7f75cb105ab897d1ffb999c6b53bf3b60a3d11354815621c5d9f07962a237ffe0000000000000000000000000000000012e745499d5ed626b4762b57923bbfae7f1209408e7ecb8813a545c4ece0ec7c48a4015e0e264b47fa08fa82c39d3a110000000000000000000000000000000008acfd3c2a2e17be41a70ebbd1ca2cff2eda8a359e0969a389ab0a6fa51db5601b386dd035b26232be08d704a02033a7175fa4954e56dabfd1808f93d2686e0b4fd285bcb78b80d15e10e63ea8c7b646000000000000000000000000000000000fb464af51161f9c2758acc09d16754d4d8ac52a37baf2fb6ccd3bca3058bd3cd204de6c8a0bfcce8822f16ecfcd0601000000000000000000000000000000001819075eaa6d9e3f0568ecc2e507370f938a65169cea1ecc40c9cb4d02c83d7964254602e3d041ba0f93c24369fdf3940000000000000000000000000000000016c179832739a8129d2ef184f4d1231d24bc8d4093670a63d73771983152ec322b6a8c954565d61c2af76c4f6ef5e8a2000000000000000000000000000000000f6623578a4fa45614f4b74768adf65a753a35dacc84af005fa4d7328d733a09f12f709a7bb7f89060f60d4fac85780ae7dda7e5373d0e0afc3da1507416f47ea8b467a5b6c2fbde484aec8777ab7559000000000000000000000000000000000189724a2a0723e7727d224ced126e4288f4743f6855b035722f2aa36cf2f0a6fc23f6835c25222b670c15248884451b0000000000000000000000000000000009a57d85140f31ca58e38b4a99c4ef103f0a4af0d5546d416134fa8adce6ecca6588c3c56ba06b2f59015acc1a081099000000000000000000000000000000000dfc67b7644851c3e928ea33aaa0f745a18983edb7488b148736e81ec0c62345c11e3f0dfce729d893dce27ea249860e000000000000000000000000000000001712009a81e06a85a225a46fac056b139c8da05e6b72074ee4079316e490a06f51c62241e380909b86239d867d631be16aa731f9393d2bb32adf04f19884dd1a5e7aa36e46408b847222a153da95aea5000000000000000000000000000000000976746ae4d9325d5e8300b57ce99650f28055b5e020700ee5f124fa76ef3bdb9923101c3a1f46b6985b8203b4e8c60600000000000000000000000000000000057310c3b6cff6c849938f533b401b0cbe10b6ff3736c79a968009b2c0b90708b6b9a98b8e594cce09c579a64ead846d000000000000000000000000000000000d39511e47f33e310332178b8a0210e76e4d4c7408ff5c2374f5e7bde8335525e03897cb3e2bdfe59bb76b21cc6411df0000000000000000000000000000000010c46a621b7fb2e7ceab8943b3371475d3d6f132fb658b8c6bf299888711f1b344ebd4a5793ffe6a7a7eec8c66c80303985f367919b0f3c667b1c1cacedeb0be1f9cb175c899992ef55f14e9b7aa6ad10000000000000000000000000000000011ffff38891ee56cb1fc062d02f6c9993100f991a556445b5ee1b1b0d56d8e64bc6eea4d7f69a6b6dc55ce7d8b4ba300000000000000000000000000000000000d6cdd95d1ab2a11ab424d7aa596cc7e5de025c57217da0da143887d7dccd6fda0addae7c2fd9e0996bdd0d23128e807000000000000000000000000000000000499b3e69214fdb4db7dbecd619ef9c6b5c8343c808e4953f593cc89adba02b5cbc56a5e7a3046c6023c5cf305e54e85000000000000000000000000000000000d267e21606c16479065e47da8e3c058cb59f55a1316a87117a73dbb067ec26f406eba6a40b30ecb00f506bfd3c32f4da3041cc52c6f1bf62dee4c61b1c5e35b72ebff7e8e89b05353388b551eb10010", "Expected": "000000000000000000000000000000000650fe9f3cb3620e0bf1654a7f1dee503b79fe2218739bad608dba9f1e5330f325b4fb7c340f118eb10dd0776fbfe63c000000000000000000000000000000000bcbf1c6a684dea5ad6c1a540b3525cbc64c7c431f37213bc8b08c8d8915a331c07bc899d3a2ea72a9a4bb2c539cf56b0000000000000000000000000000000008fca1c364333f558c7284afa1be486e84bb035b049a2108b0df99395149de83549de153a784e4df2b0134317c85292b0000000000000000000000000000000002784cc1d11667bbd0759bca35a16a1baf49a21765c6c2c3bcdd4fc9697ef20f1274be5caa0f820d37e843bc38c68957", "Name": "matter_g2_multiexp_61", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000051646993c3aba532988d7baa07eaabeb8366853436b8b19c0fe3e14ed45fdc65448d749adf745291ab5ee62d4e824880000000000000000000000000000000002cec01290d8e51ccf751183dcad20bac20b8231804a2b6f87f886aacb61d31b14f2335629e97af0ae0546a17a4cca49000000000000000000000000000000000762afa7b94ed580fd07d5141a8e1299c6ec439bbfc6c1a4d695d9aba4ab5d6dec93dc4de47096d72e5ad87d879eea190000000000000000000000000000000014769208ce8a9682c8e0340f68a0290a7782c2b04e3c13027f0b23966eada2ffb2156f6e20539738535fa0ef097f78d6709a2e80dd96eb12edc481e3d58893bd0d789a499d5289072d58c2ea80b036cb000000000000000000000000000000000acc4e3ccc3574285c19d2545839d1da9db6770b078aa399262b7c91a7c41fb4c83fe7dd0aad19f4e3eb2b56273f664f0000000000000000000000000000000017851c99881677b89956fcdf1b8c5ca5dd0997d810f3fb89f7378dbf7964926cfde315f8722531d6d715b4932179eeb40000000000000000000000000000000005e374a4c7118a76e59cdaadebb1c4e635b4dd18665010249f3bc78d559455d27d547856573e264c98ba39f6f3abea69000000000000000000000000000000000a532979cfd5263c774f629027f7624799dd0f9d6a77f675d790a85fccccad6e93c00ff2e5536b8e9a92443af14611e69ff35bc510c86a9e72c3e9c6b49d2abca546f7a62330156ec09c6fe6847a400e00000000000000000000000000000000056f109801b7a4a36fcadbee7219c06ac74e4a3f7b81616076c33ba2a71d7ca0776b596fb25d29992fa26d416272a4b4000000000000000000000000000000000c02d7e6ec50b778a7ff36fbe5751ba32beb1c2024b17bd99b46239e6dd5a708d2fc689e8e8924902e0d80287cdbd6e90000000000000000000000000000000016f18df97f48aba4d1b64e71eb894904d02ee7f6ba425e58f38a08542319e2498cb0dada8dbbb81bb398c9c924ae44270000000000000000000000000000000017dce98b335f536909ce01647aaabb918942ba2468d9a07c5516cfd347e1baa02029d39de1b2602932630e4819f2f00f391dd27628d0808d4a0773509737597230d7849418540e1fe4498fd70d39d16c00000000000000000000000000000000005b23d6f76b8bd4f334e91771383856794d1dc65b365fbc0c94f21fff049761d7379f0d512c42ce13f878e0661712d100000000000000000000000000000000009dcf70c16f524ff540f132b35074cec6ed7dcc1f319432a0dd09b3ded0778ec9ad0f05d67ecf3ebb7947951fc4b25d000000000000000000000000000000001075fb15240d532a9543dc59cb0098cbd03da77c3bf85a0ef8be1560958f8ab57d3777fab5836ba98d67c721a4a8cd460000000000000000000000000000000003511525fcf6fe224eb87b13999d2548b6b8bb8069fd354f298a025b04a33f48be72d8e82a99b9aa34ce5ccdc1f1a59c94f11b10e4c45f15d811e3db4b947ee6414e262965d7b5c23a731b019e63d5130000000000000000000000000000000019039c69d52a66330d2d8572a1308bd88159f0383c041ee7605d0aa86f1d0fe3e884d0a2ad9c72405149b5fd204ec3db000000000000000000000000000000000942163eca08672af3827dbd876b9c1adeefcd5ae74a2768fb55f1e8b342aefbf76bc6546853a2b33e26fa866e60a4e9000000000000000000000000000000000c60c6bd103ba5bb5323b5107373cd8d706038bf5ec2b367a43bab72411523bea35985b974c756184c346626ab2622d30000000000000000000000000000000016c4a2fc8a9b3c54f65cd150c80a3bf70ae8dbacdcd37128514b4a881239023e427f0b0c8984ce219207c458bb380da970f7a0ee05cfc3f63d46a3151c20da53604628bac70d7b521b3be65d7b2abedf0000000000000000000000000000000003e3df9a8ce220be05f15904a3321a6805ab68bbd539479be56b2a870c3d61234e9cda8190bdc89f48e7f0dd9374e1d800000000000000000000000000000000040446db3ec43e3e67dce62efd741a4157e8ea2597a143f7d6273b66c7045daf31f72397b4b9d374328520893157c1f1000000000000000000000000000000000c3a7dde5b02df5f7c1e750a9ee5314a580cc6ed53d326a9157b507ebd6c2da314c37a7f1837f7fcff7e8754ab603b7b0000000000000000000000000000000005e617ca4eced853f8f2e9fdefef810c97eb27d5c8bd06c5b4ea50c03761c01e8adddfe27d2d72eed8cb25ea7514a4aabd991eb5e8ac8ad7cbf8fe64a5889b715a2409305f2366b278adcd2144d7be8c00000000000000000000000000000000104ccaee210aa8196010a6478702a54cb7ba49c80a98ecbf5c0920408ff8b4a7568212bfbf3561b6a7790520bb73bd42000000000000000000000000000000000870ddd51dcc76c8a97ac4b4f23819df48dc8a8798df0450d7a45d273f830c908541dcaab7b066bcd668b289c846ea000000000000000000000000000000000012fdae32b020a346ad5edc3bab360fb5ba55004ef3dfe5f437e841b5dd7284ddb3880051956c8068e49a3fd165143ac50000000000000000000000000000000019081bf768dae314fbecec408d687df5b6ecb32ec24b41f9febd583c05693f80345e6b9d81322ddc72616c1cc39a86811a9caeccc2a2058c2f5a271c09036d73320f9bcb31b7296a796ef94ca4599757000000000000000000000000000000001316b5ce5bcc168d76d2c862230ce604d02cd3d242c51c250bc6b6fe5c380c9e83fe7041049f2272481ab38f44648f4700000000000000000000000000000000079acfc2b9629da9c9f3394874e64aa00527de21e726f02db180f86cc0b9a97138c2c567832e287635721ca40469e00c000000000000000000000000000000000e11807dcd4ac69fdcea71e3e6a93dafc27afedf12c2998dbbb2e4f33e37ea736df73af791eae69bff84f3bb212bab47000000000000000000000000000000000e834a34fb63d9df68d683a26d79ecf8ff67066586e5f760d4468ad196c66d4ebf8605ebfbb7bde201f47b35cfde3a5d8ed4eec02c2af286ae19ad5f05642587cb9ad93196756d269c783a11f23393bd000000000000000000000000000000000990f115519d2125d47b925b613edc3303110e9040fa705211e0d772edb2e0f7f88ce521d1738a5f65c9d158e9d360c2000000000000000000000000000000000bb951a16decf9be8381d0c88726b53d90bb32cd8aeff962d48e43863e4eab1839bd80d7434c7eb808bbc0e32e92a4290000000000000000000000000000000013dbd5bdb7caaecc42ffd81f14be0ff3d8fa228ff121ed4f2f3ad5961fbce617d7cbc8133fd49e03caa62f7d1567541b00000000000000000000000000000000195fd9b85e19d0e3e1c93bab0380cad6f6f3bdbdcbf5c6ec32b7de7972421d0065cf0b265f6250c02eada67e95284bce26f20eee9bd019f9e0f5c794e22e770128737198b5f5dbaf5b7d18040443a0bc0000000000000000000000000000000009ca977266277bdeb985750df47353a6b81c5f0c473eb3369d25a01df67610bebf66a6de5727a465131404025e90441a00000000000000000000000000000000054410a13287ecf4aa18f543916fcd65b15cd5d54617433217b0a2b91a79fea764b511b3b270de3e8985e8f6a2fd8c380000000000000000000000000000000009a9802a03a7c9fb63c1eb13972cd42ea2df614a0972b914c4015c2e8630af319d12fc8108b4c88db9508a9a77d9e57d00000000000000000000000000000000094d83483bca296b20b7bee124f538ae9c659a84541f5c9d9fd22e98251d2b48051ac55ebe07bcc9d2e9109f526d60a6c470a66cd3428a44a7d095ef410126257175597a333cd36ce6c9822d1ee9bb380000000000000000000000000000000003f2d93ddb6d5983fd5521c1d1726addf662af0945aee54788855037f47a013d2fe595231792a05e1259c5e5a8c553a900000000000000000000000000000000004f4f4e7df5dee975fb440b5a217c27d9d1eb83a5ae280a2b147896f6bb864abe04459c17ef56d784d3c4a0b7ad3f3900000000000000000000000000000000069da36057aaa89cda458af4ee27fd9ec969c8f7612cbb153da0e010d67bfdddadb2941cfbdba8c43019a9f1aaf9c296000000000000000000000000000000001545b8325a80176ea148a3d9301debd7046f33a1b419b4ed01916a3d0a072037fd617d96e0bad32b208983ac3be7dda4e53fa8fb708204e619c221b8ecee14fdbcb1f94731ac2c858787ab33906c9269000000000000000000000000000000001536a81b203df2640bbe7e695b5fde186021d21685f24c25966cf11dde554d49bcefca64f16697509a9ca86e58b75eff0000000000000000000000000000000014348a2bd4907cf081f2f7bc944a98d3fac671abde029995377df190f7f60319b8de1698b99be39c821328e32a449c760000000000000000000000000000000000e18d4da3823addb2a6cef8336c83f99f390e23d7129365d57035d4363aac7e9c4da9f8000f086f7d2206666f990dac000000000000000000000000000000000d6ba54e2af9afa57ff4536a35e9b61c8d8fb3d431b653a0c66a2a4b8f11d9b5c45389f894d64485233d4183895921f3abf8de43c54ed59b936e1d55032eab5c9d9e04e83e4696d969c24167b4239f62000000000000000000000000000000000d88d5719e07e2332c54ba41f330c7763d2b2b7c4140d19b8b0972fae6ef902415de5f2abcc2342fce24d3ed8ffe156300000000000000000000000000000000163aa2c768eca58194fb76822deffc37cefe04ceb70aba38a51f507be7cd64c0755abdc2e49e7db234cd5d68575c2d7a000000000000000000000000000000000e443d9953468b8cea4eca4f5968e214888e2b95bc20ece39483ac551d4e180c0b0a41c4668c8ddaf761a0ac03fbcad3000000000000000000000000000000000691930530ce86a1354d73cb21ee32d968e6d89b12e5a09a7991c7d27dec302348af7f49c3e0de91e1a1838aa11651e795f59041329b6c3e6aef01d3410836852f79cc436fcf23199e0985c56f65c4f0000000000000000000000000000000000d7c6f9d4aa794f34596bb9af4d62363462d9804898ebd7c7db7544be1f46b4bde488ec59004adaa0cbe40aef525ce3f000000000000000000000000000000001094629b1428c4c284b7a64d0623e10ca0c4d395bccbfaad89d1a737a3887c10b714541f2681c33e674c3b99a36b7a450000000000000000000000000000000000d6812fad9c5ea365a64ebd3150238349d88b76d041ccaa7e637fdfa6c715d9d6dc3d3315cb95fd6919fe419d028783000000000000000000000000000000000eee5cb772ce02fe2a4883008f17570aebb902ad7c40b4024a5b24ff75b3aaa2b54ace6fb4601b1c62837a20204194dd740e4a207ab5dd4a0621fd65697f5d30b8ee1440a5f5c5e74a0dbc6b6391c1b0000000000000000000000000000000001026d21e075fb8921dd849c98252a565d39ca9f5a62a825e7e3e77ab5be6620e76e45047e51350c48d9a4cf98a1222a9000000000000000000000000000000000f6459a8287bb2da77404a515dd7a35f46a4aa49ef72cd2cdefbc5e5242872df5f7b7aeae6848d59afa1dd142ae7caca0000000000000000000000000000000011e3545151d4e0b034b950cd2f1a3fc2d29e9d53250ade2482b7ea6075dacf7e8e777afa1e8e612b45028205235265970000000000000000000000000000000017a869d75144ece603c04d39cb56a487895cc882fec613f40f6a66601bdbbbb7748ec755553257d654d1558b1104a981f49a3f82d25c6e0d69207e6dff010d56f0d99b28fd986c5711878dcb6665b1f50000000000000000000000000000000011602a23c9b5cc091a700114e5d3557bd4857c4fc44cb8628ef327ddeeb728927347438f123e2011f9cfda9b6dfc42e4000000000000000000000000000000000c4fad264ca95827e9cbb9783e36cb0b683fcc33038d47bc7ab6b65998770325588e5b910e811cf7d61fce13c3378d6700000000000000000000000000000000009b4711aa67e84434cabc289a78fae48ea86641a162d48b79bbcbfd56237705dd2d1e9ba3a18d737eec29eb8e940e58000000000000000000000000000000001160fc9e2a488ad9385140bb62ab48ee613c2284208cf2f92912e1b973ff81a5d3de338d9aa6881cbe437907890258fc8390fa1b452f887ef3afc7129ad8ceb9a8397f7625c2b249d7442566814ae0a9", "Expected": "000000000000000000000000000000000cd0d8c746ecc8d92fcf2232793282d7e0e17e0ec27ee851487eb7788f590db3487296061075f36c24f67cd4c4bbf36f0000000000000000000000000000000010c5e1d05070c27f19c228813051c6a830254542eb71469664c842695b219670dba8ddff858e2d147019847866f01084000000000000000000000000000000001799ca7d8f2637da761622b793a3ed3317d50b902a1cabefdfc776b0d0ef88b707b8a5c36786d5ede3d8a381de4e069d00000000000000000000000000000000129881a3b56e0014bf1dac4775f509f309c33406f2cf22df9a0ccd15c87ea48a868d4437303923127bf580b8d6ed0a8f", "Name": "matter_g2_multiexp_62", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000d087c1b98f8c67c1bbc4389f21d9dab02faf46ee4223c609e7b9eb399132ae168bc12847c580f58edbb9255dca3b000000000000000000000000000000000065ded24bda39d2b830639fa511bce8dc770eb95e349d6874ce63b3355d23c1da3ee9771ad44e57c6c661b7453076fe7000000000000000000000000000000000fa3b2ef40a7c3d41f0c3a5f86afec252c6ce89bd1bf1f2192026e22fa256365360589c788753033658b1ba151797feb00000000000000000000000000000000105040ff4dc2bc435c2a82e1174e2ee0b94043d69074f01e8ed013da8c431f33c94a438a93b06774411780cdb72abbc8414ca9894bc15e6bca798544138689b2471f8171a5dc48eccfa36c83af142b7d00000000000000000000000000000000129c8c1db08ccd0dadd59b04df67a91fb6547d97ce23e59aa57cd3d38458e6baaa67285800809856e7e264d812e584390000000000000000000000000000000004a0be934248b4e142fc51745233b6d0ab2c46f53a8f9d4c84981e5eacff146ee6227de289c713e4ce24a4341572c9d70000000000000000000000000000000005916d14a8592af57a40418b10376e8e20f70929d2ba568c1fb70e343a1dfcf3e63c791cb639bec49c50aebd2f816fdf0000000000000000000000000000000018682c66a461a69b11d7c32f7aca07749e05a23fc46547bac121752aef64e9bb98a274d15a14faa93af8f284790acb9b99eac8ce85a1bc70c725a2f04aea3749d75d22c0df7c0755a5e76ab4d82ef9420000000000000000000000000000000001552053742eb89ae3d0b95be919c84e53919c898ada92d3eaf05605a19ac910091fc08a65e9764f3108877c837d478c00000000000000000000000000000000118e5d22f6df0e6bc7447177ce06659f94315478385372046b649fa6d39fefeeb492e6623e0160bc47233f4d3143e326000000000000000000000000000000000dd02c30cfdea5abd3550a9f28b546d82d5b3043f012de622d892062945847748ba820555fb811fb3382791ec43ce1f700000000000000000000000000000000050373898b396d9a641e2f2ed832c7619515fd9070852b891b4ce0b5bb5ea8b5e24248297d53e9db7cb946e76c4433fa49b25140d7967b0438e49f59a6b04b75bc8745b84d7350605be548c6b4b3aeee0000000000000000000000000000000006b465f4b9d60a3a14e119c54a7c35172bd648c86a7cf331e80ba849fc87b9dcd48410e3c9a07b634e83fc7dd71e5b9f000000000000000000000000000000000283ad9c77f549042f79c47b8a69e72164f0ee77aee50c20519d2b89029c63ea86dde2744cd21eb5d37e896c3abbdf56000000000000000000000000000000001668b08a87787928afe92d941240e503da07b646a34cf82ed09d4c2f4d479aa24358c8475eebd9bcfaa6bae17c430cfd00000000000000000000000000000000150e5b28bd901f7a2a9af44bfd6b78cc84900dc05e334de306f9a45f1e67708adddf4dcede8150a39670054f97a643436e30a51d55a1ac94089d0f3217c3a2182da6b02ce70ce7dd8e2d4e938bfefa9d00000000000000000000000000000000060d75764a92e30e80e7c1a6df1482585f4de901bbc36dd9d8978a76c12c739f85a9ba16741d0b19ed480fe2dc331e5b000000000000000000000000000000000024fd15c9e5b8872d2e9dae9ae96102bfb0e31d15e92a24316818862dd8ca7a6fef271d499fed5e0db6dfebc4c72e0200000000000000000000000000000000058cda551e1fcd701c6a3880b276a2f7536a26aa366a6425a1c42cf31eec678551f489a27f23ed5dbc76f19b0fbfae43000000000000000000000000000000001152e2cfdb584295563af8120c523a9f4c01cf72da64fcbe0a90a284d693a3089f299bc760166be062cf9f8efb6a951ad3da3db6492ff36102747d9d663bc6e9cf8f75b1cf77044989c7af3f11d66ae700000000000000000000000000000000116fc24e980b2e7ad6bf17bcd7c4f06e654bbf766ea0238a66d738bf3c2d41c8c63bd52f81553cca5fea91f5f9b74a2c0000000000000000000000000000000001078f19ecf785a5e0d3e764b7d6ea47b2d077b5eb222f4e6a9451f134ff0d77a0b9a3b53caf599705d131e3b17b6ca9000000000000000000000000000000000e44c07f00a1f198583a8ffca43da45d8e54e1f2a85bee7afff6c1c733b5d0b5712961c4b6d344869a8e4de3b34218e000000000000000000000000000000000083c78b3568cdf808b75d9ee2b03b98cd516bb16ca8cc35757f53f12119747bf6b5b0605bdffb2f079cbc69e99ee0bad6de8753f3df8be42b6d6ab578096426f852de4ff545d2e4ac12c3943b044b43800000000000000000000000000000000087ded6945bd6fae7a0aebb1ea68d3cd34588035531a6cb00fcf1b83e06f7ec21cd3486580165c1364027b43e238e34d00000000000000000000000000000000005a2fe8a9871273bb60cc7ebef44a361300a1033f3f0230a731f5723fca124ec9d305cfde45802482a45942154398cd00000000000000000000000000000000121eb94a41f9e133adf082ef651272c178d780a1c31ba8797f60a208ad36b4c703c9b6c08be845f8844dd14d6406734d000000000000000000000000000000000e5e3da7c91ab4cca1c9286020aab9795e64e667d55a5a700241f9589aa3519639f168d040a0027ac057f334a9f740aba28f7ef4b12c5097a15fa6394a4dcc3ceed6cf3c6240ec2ac949bc21a9f6447f00000000000000000000000000000000041f9117b426938acb40c905bbcba443c043bb55cf9b876edfa2ca051b6354124f0fa54d6a88ea172c3f5c10c6d921b3000000000000000000000000000000001828dc0b9533274db6afc802b2fadaacf57f28126094b6b9038ed5f6bbae0112c873fe5eed15bc49b970461abc2f5c3200000000000000000000000000000000107df6da02f106ae47718959aeba7b4fb4a8f0e2651560e2f2266a62566e13a5af86430b8800543f5eb6b1e96be79c69000000000000000000000000000000001628fd4a598813133de75cd7c96ff3711b6bc826806b96d07e5a89cd549592f0f51c84aa9ee0642cffae5630ca1ebae1a3d0eff3368b10d00566f35391bf43c9d204a4444b7eb91017f1b2d8a762d90c000000000000000000000000000000000e8fff44163cd9c2a4e148eef3cbbee19ab8f648da1a8d438be27d2b0bcab393fb7d49e096d9a7abed3d8f82c11c4e03000000000000000000000000000000001274335d8bde3d14924f8d7ba18fea82bbc85427892f18fb741c8ecc5f2d6d7bee74c68058164c55db3cb8da8597bfe40000000000000000000000000000000010c7fc728c094e47569f0e75446c399d20a1239b511e34d8d6193dd32df607dfaa4377a1825b3892a9f74ff4efa0d9df00000000000000000000000000000000067d904122a6581b5d5a60acfe8156dcb6c10ed083840e506487b5dd9117927663e0ad883fb91b4914778ae082de0a7eb90d76e660389e570bef756e9785e39b9748aecd7a34556bac8399aa5564d12d000000000000000000000000000000000a909706e3ce45c86f2c30de5e820c8c9eefef207e530fd504511827f5e6422714d3f4224afa6bbba22ffca533d647390000000000000000000000000000000013ff61472ddc0d70207692648087c283763ede668ae380b0b9d6ae6593498b0adc9d4e4fcc73b5cce250e7563f7577de000000000000000000000000000000000a81db69eca785373c4dcbafd8635b23a9f41265e91152f309fb2945622937e65b5c17656abf8aff042a1fd1e5e50341000000000000000000000000000000000c66269c3ccd9e91766d1a640789bde6de752d08ffe3b2955df8dad3d2a0b6cea9013af235cbfbccee8271a7242e310614f18dae096e4de75de3da284a5755efe51e912e180020a20adf1f5de43cb51800000000000000000000000000000000181f3f4a16696980bd0eb9bd10ff1084ffe90bcb65f12f505b25f0a26dc1d4e16987d486b2c0b117fd6f2e356b83a5250000000000000000000000000000000010d7be6788da3ec56c87acee68ea8a03e7d467f816060207bb163dfcf8a4e7721651bf2bb23d5bc390d50fb1ee6625a900000000000000000000000000000000196c1ac817493f51d9ca891b55fa65ad5192df83cdb63eb1a634ad54e2d627f7feaa68780418f5354e6cc09cdf2f6c5800000000000000000000000000000000190f36690b8d36f2e295b9625f23afef9d9babe87c1ba0303f60c6d44ec952ba6bf8356469cff9d952f8e26bdb86ca06e32d4645ce0172000fd74f30937261de89753caa716dd03a8b3269747f2349a1000000000000000000000000000000000f77df606f0611856c449c58393f4ee7a6225a5bee667382a48f59dfc747736a895d598f90ab26002dd0ed3a5a8f5a200000000000000000000000000000000012aa50d0ec440884fc6c2f7a0e8db8a5e79160f0c482209ae1a1aca2b9dfedfec6d6ea09252a373ea57905130220a4820000000000000000000000000000000004773f46165cdb19cae49cc42663316df39586c62be5b827535f138e1fca8dcf62ba42ab60ac6dcec85e8496f32b9eda0000000000000000000000000000000010c91923c2c7b3eb2cd9aaf0455c0eb035e38e5352d218b07ea23f50040ea58fd548b373c1bee9113d3d44fcb25f6ba08c8722e3e929ba21f1ed6c51fe5ad4940fb13d63e0293893135d0da5e6e0389300000000000000000000000000000000044b95fd5f0e049abfdc2adc699646afa5b0f64464779efacce85a5279477697090615933069992bf30036c6ac70dfe50000000000000000000000000000000002778e7dacc5566354c24ea1144613a5ce8a38eb56d53d230ca145ce83d5ed88596afe243df22cba10f423e64a7c103a0000000000000000000000000000000017e87cd2752d8674c373c557ab2b922e02620a070aacf6f5b3d3d07ca35d89ed2666da7246b800717c0e4763dc35f5f6000000000000000000000000000000000a3ed312e5f309eafaed486629d953970cb73f839bf30f506c2f393df4c283f299d6c643ae6c229430d919e8aeae8bd839bef6ccc893f6eed62e68f5f2a07812f2d3066b89653431e7e39e8596bc3652000000000000000000000000000000001082a0edac6267151c8ef11fac7614b74cf58b39b72fb71e4d66467ed4fb3264b177c691e569230f2a13a64b4a48c6fc000000000000000000000000000000000073a8d5f96ee580741bee1f82cacb6139d962fec34c44c648c8fcd0322796429bbaef083a11b4c8fa376d4c00cd79c00000000000000000000000000000000008d41e51dc2822e0f14b992511de799fe4db3783a05ddc1026a53faa89af000075ba5aa830ceb7551e51f0fff144c1360000000000000000000000000000000006bc4bf0bdf350af417160d06e8aebf2dde02c9b50be39b0c4dcb3a045f9e04f1f041f6de10328e287df6121247dd4e9c395ba8f2553e3eced8a42b221a710a5cd2a5ffe5834d3084dc260ae0f51698e000000000000000000000000000000000802e7b71127a15a279a629e89f194b51d19c4f329efd8ecf9fe69d340dd06068c8467da6ab39be25c194077d3ce2428000000000000000000000000000000000250172c787afe866b428748be8359d8e0bad161832abc108c850362c5839237483fb38678d77c94696260508907726a000000000000000000000000000000000d46223c1666f314f9a1e32a94f83d8150755d71252e19af91a3b460ab0ade2db2364d8c6217cb422095f0d9a1ed648a0000000000000000000000000000000002fc2849014717d1c07935efe601325e1842ed333897222f6de322dac8b50bf4d9859eed8880a34676af0d0e3277639053ef5568a766b6c39854ba059f3130b75d7fd870bfac2b00b626e2d71c4968e10000000000000000000000000000000004151d78d65b0c9eb26822e20d90ace8fac209a1f08f62ce722ae3effd7fcc476f4c0179e71b09fc181db96fb2ea4eec0000000000000000000000000000000013d17ef429483be98411947ca0771ce671fc38e27bd0aa4abcfd5ddf1af9e138404d86f4c2ed74702f80a573638d92f500000000000000000000000000000000178f2a7eb43b9f88acfa892b5868d7f7c5787a399c1c566de39ecedbfe88357fd5256ec57e1ba12e9784382c14331756000000000000000000000000000000000253a391373974beef746c4397654a30a68992fe9163f9518ff0ed9b7be37b858ac60c95259ab894bb6acfd123333b7fbadefc3880ca8dcff10b8b763f7d15f88965c2261b72ba879e3540a90c59effa", "Expected": "000000000000000000000000000000000710bfc39e92b0b9d15ee9bdb4959daa3a78f66aeae29eaeb50a0aa0460f3ff703c86eec8903011b4b61a0dea725ab08000000000000000000000000000000000856fe7a074d37786237cc14ff1bc53c735ee8133b231dd3fc63dfa0dbd1979304bcc7b55cd1bb66fd7529e15d15db5800000000000000000000000000000000014757f1fbfd4fa7935ebfe65e150519d6eb4f4831890df4b236dda98804b79862fb6699b587c3e568fd6de1e582409900000000000000000000000000000000000f7b54e4961dab9e94b1c4b897177dfa74be9937694a38207ddc9d6290dae1d5e122cfe4c8c31d853db3783999a7f0", "Name": "matter_g2_multiexp_63", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003bfd2535c6d8ffb44670bd02b5aa6f050f5cfae7266fc3225865bc3f34320820eaeaa952f80da51671f6d97b3df9d4f00000000000000000000000000000000026c1adc0ffc3fef9ccf018ff9a647ef5c69c5133fb4a6566cdcbd3180d9ee784f34d667edb1dd54ae292253b45576b4000000000000000000000000000000000ee90fb541becf96b4728f1859aee5ae74e30ba9193b90569b66b0e1d087eb81f30c21774298cb06e7dbee8f8aafb1930000000000000000000000000000000000a4361867bca952446f64c273735764e141eef43d156d6cbb6e68dbf3bc940e935f7bf3a77b57fca4bbc74bda2f26532c1a5abbddc02f453519563d6b6e05959d8de5feb493f7c58ea5e548cfec2df60000000000000000000000000000000004bdef85b0da28e0531734016e5953256c75c3620937736cf65de5f05b8beff294677668047a3b74f0f135b846a95bd6000000000000000000000000000000000b754df2aef855b4a0eb6f6aa03115ee8f38a31fc852381deef2b59bf23e2c885ae166030ccadd5673bacc35482f81e9000000000000000000000000000000000f1d760ac6dfb65b39c999211d4e4c3623c3fb8ea59cdcf926249a07285a8e4da1890327fed20ff07f12359f6d9035980000000000000000000000000000000009f2698239c8b452748126ffd83abec768edffb83dfa3dc7943fd499c8980e2d9aad76dc38b336a4a63eccf5c4150ce0b406eb0c097237556228f3a48b7e770c1707fd583b91b4b6b70f398b7dbb0d3c000000000000000000000000000000000cd724c51fd56528dfa688df46f71bbfc9144ff98958b559fca8fd05eda01c38c28630ee19579012b9913a393264cd90000000000000000000000000000000000aa1e55f2b6d9385ec6a9cbafcdbad157f7ebc06b2e30e2380ac54e71db5259cb919e17042d6ba6e045f1358aef276ea0000000000000000000000000000000010181ce9ffe235b6b271d570b3c2d6e1be60c53b4a98ef5e8d7d00b463e5bbc9d8d96dda881e58746090983d6f8edd35000000000000000000000000000000000333deb8b14f499319ad675f482fecd80f9a69ba369425decd441cd2ff5c3c77f11075f61bb1d90d0be850ff657d6b7cccc30cf1db4c6be6dbc5830ee37b5782c6dad215334163a9d9e4deb962186f80000000000000000000000000000000001581a5440fe892ee6eece5fc2227fe072dfbc440e0620a1e5fb505ff0b16d9e6033d83c83576b4b6ff87a807dc81b88400000000000000000000000000000000099b070a0d7497f33c1c478ac424d5564fa645d836a3d572d98782f08713d8e425b571433fee928475688db2b3a9a04c0000000000000000000000000000000011e1cbaa09a6361aff9e199e21bc52e98dfacc49ed83e732d4b4f2503b3bfdf85d029dead4412b6f3d7ea447e20d669b0000000000000000000000000000000005503e151d620e9a5a142e4f7940ed88375e7efc1109214141c191e9f38a32a40d3a92d6094584e763e0cf13cbb54bcc99461c0f12019b344a7f322900b64fe81e0d8a052c0ff5e977f58753b1b6edc60000000000000000000000000000000007c780f119bbccfd658f3f1b69ce9c56b1f5269bded713b6827d97d32b2a6deadcc02c410138d984d977527f3609cc2c00000000000000000000000000000000095aebacfa33928a916ca7b0ceac699c71620781b35cb2f3b254bdbd1544b728a2ec1fb35416ed7a8a3a630bc07ff8720000000000000000000000000000000012194abf7e411f4961b6f8a1e2ad052c27624ded863d7a9132d9c7ecd3b4074ef0060cd86adb73056323f4227ba5fa9e0000000000000000000000000000000002fde2be9ac1e8265f258a09eec85a70112ef1eadc3a91429c9206555933e2b89aaf7493fb833e33e5d61be28a12a1c2338ef9fa825e47b46483ed8fd2df64bc7b56da8aecbae704b7eff2e7d426f27d000000000000000000000000000000001586c65405e810e1d5b59304bb4555ca43c04a593671ec64d5ed2d2e626b1f8a89f48a4b21d38fb49909b8c614209a460000000000000000000000000000000014528cdf994e774b8fd54090cb45b68098c1ad9a351bc1f36a9393f3b4364f5beaf58fff6e5f8b21a85b67bc427c0e920000000000000000000000000000000000b48d8713aee51d80c79109fb8b4e0c6e32e25a7ca24dd3e7700f8f3195730375208b241b2c722af3c2295a1704cbb3000000000000000000000000000000001913cf6328429cf2966a48117dc74db0d45be7800f93cfbebf597fb48a8bdcae4fae2df7835f9536481f67261755da2a1dd6656a34f3b12e5568b9c348fbf4ecf50d65a89e63ec0936591f01e6cc7a4a0000000000000000000000000000000017e45a481449f167fd579accc896ac65aff6f1f7392df47d006b404de3cb7ebf6cb59d0913438f3a51e55a0ae3d446c9000000000000000000000000000000000cf4b7db343bea29af6e244a71880538b41b826bfd1d06a21512d00ce58f5d7500ab1ed77b446b1e3782df736bf3dbb6000000000000000000000000000000000525d08e134779ca7614784818876514e14b65e799b7832f61a63601fc491c8b9cb25430547f961cc1c22100170a2065000000000000000000000000000000000450cc2156c4716d0343f32aca82fd2d0712389b1aa984b31d51edc2aa0545c88ff52e470b15eb6b2c22e30f79864dc85202f32528e795e0fbe6deb4ef6e45efc70019520b01fa1d71d5505e42faa69a0000000000000000000000000000000004147c105ee8b4db68482b9d7f6a716ea1474b6c62efc41b9444ed1ef9e92e2b7010a1c1ecc59038ac37b385074a6bce0000000000000000000000000000000018a600a85c5c38be835d2e91a35cce4b59e5f5ac3b735fc007bf5498062beca9befc9c8ead58f9f21f6e08266b149d800000000000000000000000000000000012a476fcb81ab66e3101de2364cb609b17e06eabdff5246bf736eb9d5c87fddd404e8867578262f07a05731b04069164000000000000000000000000000000000c54a888678c28766ad17a18507e4bf5dc57dd394eb6e9b69abaf15e645cf4779bf6ccf4314d2756584647cf27af089ba2b39f2b893be03ab4da77ed518ef35b2e24278d707a20b67ab4d1e5972f9722000000000000000000000000000000000e809152c44cebdd8b40f0d22d57c3b31f29700e0cbc3e69f660bf7270e59093d84bf7ac358be7e45e799a75cf9c13df000000000000000000000000000000000c6c61f98bd4e3b7095fc7f1196baa98139087df00fae2a795e76544ca47e453f75929cab07c11cd3595de6ecbbbaff000000000000000000000000000000000171c70446c19fec3c152741925c8db28ab0d140720cb6a6c45e9bc66c012a421d12271889ea43fe1524944ff572fe6850000000000000000000000000000000006e4baa09b4660c69cace151e60320b771e56e7460b01442bfcf26823c17779034ac241b9365dbbfade770d2056eeecd892eb7c361f05e114a645caffce9437b7b43fa01dd66c1e75b30f3abd0209bcf000000000000000000000000000000001917a23350e94963e3a7488ac1dafefe9ab11856d405eff39d655e31ba808f02954b63e822613d3c6e5f358be04be4a4000000000000000000000000000000001620211b06288c16aa02f4404192e9f57a048e900f0ec5db9b478475f13b142f924c6de720031b3fc12cf869b422af470000000000000000000000000000000011e8ded9ad57e46713e7ac0044ee4edec12689cdfb98838a74adf1a35244e3d9a4a34c81323b089c10422abf26b044e70000000000000000000000000000000006f85c7478cec590fe3355a8d6e9557c5be084c161e090c72f1281be4ee56f36aa1e3c9c844eb45d9e295c15c4cd903efdafc3f57d6116163f1da9e70ea645243c5911cc4ad4a969a57c46c6b5c73acf000000000000000000000000000000000d555d9f23de97318dafb257cf444952bdd3e844e9ed5ce193c10b76f5179f0c6851f93af1553b128f34d3a7e75339f3000000000000000000000000000000000132704571a12a58f629dab48f1a3956392b40f801c2b3757c15f7be46ef1d9115d89920c460c0e2bb062b3cc1aaed7400000000000000000000000000000000152829eaef900fd2f19d6fdbb8f7eb3b02df35d218b494d075219b69016256e572eb7f555f6fbdbe17c59a666d190055000000000000000000000000000000000fe5c67c949b7c89a867301528f0ab24b04d31d6f18f575c475ab5a6098f7187eef20a9ed6e810684da9afd8de96ded6660a77b2be50eb72fd108644d913b9253209972fdec2d107213ba47357c96e9e00000000000000000000000000000000128bf3cbb5208d84dff719ced229921a889c9a4d02f5a508187662f03852531fb8be1f4c2aa9ef01de7720c352dbd19d00000000000000000000000000000000158d89a44b8fcf9ca8c96a8e516e130ae8af19ed71c2b8487ae300c3cdb546e248728bc58fd9cfef21107e0dabf44fc20000000000000000000000000000000012b70b42c8af4551267a94a795fe18e8d054291225438adaa33fe2edafa87742fc3709abcc7bada5d26e3a14649cb47f0000000000000000000000000000000015a853160b7666ea7d64aacd931314497ac7068a4b8bfe3a7deed85df2bb8dba277716a9d1ee50c56b2970016ada509d1ca575cca348dee9adfe68f8a78d39bb998205da2a5285c12141a77ee7af840900000000000000000000000000000000087c7bf08e085e19f0cb301d2e36478357e835620b1cde6e132c237ff6fc63e6fc16a8753550d50fb93a0a1741302cf9000000000000000000000000000000000615299ccefe4da879e5f4b01d6b6ef8358bb59ed8a2b365ec72003c16486d3266243db81f48855d81b6a25440bb861a0000000000000000000000000000000001498fd20640f39dbc03a474f4514e5e283256ac19468077af1c9ddaa40759dcf93afe256de1e49be6469fa106394193000000000000000000000000000000000cba50fc4919a29be2f4e74c261487dbf855db1856e8d5d008cc3f4ee5eb3babfdfaff878adae49b96db99d424bc4dab2e1e4537f855eb478274992cba4e3f50fd9e944f6246cd52dd1517b55bd7f71f000000000000000000000000000000001369dd82ed013474581ca1ab2d2133341d7c1d52065060d72b8317e899e79e9077bcefe6c76c3c7f67e54f76dd3c246c000000000000000000000000000000000405aa84d3ceb02bf8eae989a9cd65afa15451443af6f3cf5e70f5cd7bb8d413c57ac3893a7e8b888ae93a92dcfa2b20000000000000000000000000000000000378d003988f3c6c16d3b12ef47a4a49e2d3d2c7c67e384bcd510939581770aed92e06291ed3b7c742769f0d1ef740c100000000000000000000000000000000048bfa6550711a17d52f48377821baae6f3de6ad99ccfeb8302466047dfddee8005240cdc65b3ab11ed85b11f128624957f9a729aa01c8bf0271052202a077913a9e0c87201a367845f9b271c130e95d0000000000000000000000000000000013370ab697da0ff0a0efa8ebc7589b465374c983c13daee7b5451e8b299933eb5a4d255ffe4aa46782ae0916fd3990230000000000000000000000000000000002ee77be6e0b6fd260ad660a96100bf3259329faf2ff9796102928e70cd52c2bda8d0d1da1d484d7b023d3d59725d12b0000000000000000000000000000000014482fee88e02e61b847c08e61d7ae6fca2d993bbb69bf1653138150d5d7fed09cd5cd4097cb4b6368ea8023383477cf0000000000000000000000000000000009d0380d0d6fa39c9e242b9a67336d86445551658bc29fbd594239a76d7741ba388450caa244fb186afc36d35c8740e93017593cf311989ed8fedff72bb1f14f72cfe5bb7446ace5274d8ded54c1372f000000000000000000000000000000001537d4a47247af8f60f77d309666056c412ce089f3f011457e894f74fa4ad5168baafd36ed3294f5f61cc9cd8f87554500000000000000000000000000000000119e43382a846c8945e58dc7723a0f24b24d9cd487d436a156156a6da97795cf3f4ce382d21435695949b5137a2bf1d3000000000000000000000000000000000be5fd015998bd6043f124048c82e4d848e1b8c87442d0021390cba41c294de17648a47dacc06268606ba73cc95ae6e70000000000000000000000000000000000e05a3dbbf3da8320c40d51ac44c6380d56ecb460b0e7094819aa6af4d7c70d1541d4bc1fc5afd453b165f3d48d09a708bbe9e7a307e380c238ec1f8e2010a95fff8b03923ecd9b012f99e56c77a5cd", "Expected": "000000000000000000000000000000000b00b5c14685ddd17ee99c74598e6bfae5bb1c103f8ebfaec3a620ba57312f3093f9ad5eac820d81096dfece90e72ef8000000000000000000000000000000000dd81552160d449cd787ac27c76685ea0dc993a9fcf8ab182f1ff5d8a484a47c14c1c1a785285b44336c7f6fc0732a0c0000000000000000000000000000000003008b6d97a12868554d294faa26e2ebe2920add650f841adfbf0ee89af72fc4da5dc23b45b7ff191a58c17971b50ae50000000000000000000000000000000013f438d927f35b04bee8fc55693d5c97229c8548ff9de39fae6e26c26f89623d3b0c810b9be8dcf0445910e8eac5c58b", "Name": "matter_g2_multiexp_64", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e1f825b71cd9edcb231c178e160e37bea70108b369afb248edc7c6a59114c22e843fb5541e0f26c77a2b589ea88fb3d000000000000000000000000000000000d65d777e91920b17400955a4afecf82f67cd13f3e7c5d9c2076c4a4d8f7f26383d22d9977dfd0987f219a625c8a621200000000000000000000000000000000045716092850318c343f0dc5337df1a72f8c74dd729831d12103b46127c9180fb50cece34986a94fee6119e72d16a55e00000000000000000000000000000000083fac698ce800786719d1f6063c87d9f728da03cea2545b4ad8831f6c24bfff73e80f2c2fff1532f6d1fea60e7d438ccc5e9d01f6ea67dc3f943d57d9d8b5791d823592f7fae6719804c1ca097e651d00000000000000000000000000000000171d60b76698d4d3f14b4eacbdce9fa66b8c3cc7ecfb989439330fbf0d051d95f3007c389113346e614f5ec8cd170a2100000000000000000000000000000000151a96beb250bdeca3cdad1b07322040bf1cf2105dfa854bb24fa76c8abc25ef4fb924ff995da641244f9daccff2ff970000000000000000000000000000000007e5818778a8331cdcd1432b46abf1efcdf7e4aa8907fd42d5e7d14b57dbfc48125246b57587755ee1571be8b52d2c57000000000000000000000000000000000693eb562e22fa8ca4a655b76e43b50fe487ca1d65cc3867eaf793e50496f0b4658bd92199104c2ab92e4ac53c44db6f57b8fcb85e4dbc1969805d814e75b2b80f5cd1e5562bfc1e28becf731aadfc58000000000000000000000000000000001059d23ec6e472937d80829256db506d2d2deb37d4b750a980568cd5b0db085358a4d610d59009b64db1a9225f9f6f5300000000000000000000000000000000053d9ffc47672f1058856aa08e51aebd469111dcd129ed542454d6401e7893323f8a9c63641f499cd8617c7389518f8e0000000000000000000000000000000002b9b30a5e37b18af4bb02ae8cdd56f6a87820716ea1522a174a0d99c3716295ad0ff2daf663697cb56bc6053c9dba610000000000000000000000000000000019d3230c0bdc228fa0cfd5e0d8bb88be959e70e59d931d9f9e3683d5e65d8ba0d121fcea329b23c5905b80dac34de33b03edc53ced9ec5d7f302216fd30a81c3554a3fd04994f62b5e3da74c8b71bb870000000000000000000000000000000015a619addc75f425596f9a51c6cf2259087cf32afe9b1f07e346a2f4e1f8caa001dc10098d1287b89837f426d073982d000000000000000000000000000000001660598fcd3ab6a55423138ee72a4ca7b57277f6ce140f9f992dd9934bcda78513516df0d309a0e8ea151b2742dceddd0000000000000000000000000000000004cce7d84e0763fbbb54376833ddd7408afe3f741bc2b7e42fef3789a005134cc5540981a15a9f256e0e541ac58ff3b10000000000000000000000000000000019c20a0064f89d37548e06d63d8ff4fbf3584d5bcc2fc2757339b7c89db6d5da76d43b31da7364259187ed602e79bf4f976568ab779e335b8dc67a64f15b947e69cd3896ff393f51fbd3c3e3a157543f000000000000000000000000000000000d7ec5a27ac44daeebab7658011624c441e45924cce97d5bda354f1daf9362f5bce2ddf57151fa07f78740a7db170e8300000000000000000000000000000000121ee325f4252ae5cdd3e3495f36492d68d9dbe13249039d1185760e6e48a789744b2a9946a3d6478a64b378f76b0de300000000000000000000000000000000014c6c5b98c1e214f78b82f1b3be4c32c5013934b1231fec942b5591d3f0440bf63b1505cfbb7a8fa78a85ba58fd4aa90000000000000000000000000000000016aaea3bd0ae91b9d18ff89a40ae27b68d74f3a227383138ed737d59c19ac578da03df83f04c8d962cb9d6f84a15302f3aa5eeded490a17b1cfa66d409811741643b7beacf312b9d6c8e7e7e63579c8300000000000000000000000000000000188e5aed425a768f89f5ce09b2cc909b28c6a0165787c8e3750fca8e8162128ecf62ef0ff853d206d23bc076335008e70000000000000000000000000000000001cfd330da0d1b5b92b6533cf5a8b6b70bd93daec4373f28d669f5e970a947fd813ab1d1272b61afbd2748922b87c8c300000000000000000000000000000000002aec750fd085c99c3b9c3af62b6deddd85e49eba0293e6e8160b26a3945af546a760b8f8f85120d6a51d22313cd33800000000000000000000000000000000162a109abce2edef753ca6351aaa9cecdeac20919681c672dbb183b5b26649e885ff081b9d3687f802dbe20fda43462af9f1f9313bf966ea3b8f09bbe9dcb66a7f9e3e94e2024c49a72ccbbe03fe4662000000000000000000000000000000000f7ad6a1dd9f8cf52bef02ae1e82b0d20dcacfaa5c169a485bf8becec8b51373fae851ca29e64385f0b7024eb0bcf9270000000000000000000000000000000010412a7a710f842fe836414e2729d0ff2e145709d8f7b5e3964af3e0ae267ac53dac3db1e6d2b7f7671ec34b18c844a10000000000000000000000000000000002d3b96fab0e3b8fe44e316fcc5e35f06dab83f2c531a777e162f7521cdd5767ad0b6f877f876f73d2ff663d9b71f462000000000000000000000000000000000c09a98bf623e82a4d2d4b63fb867fab5d3bb1f85a0669c4c11cebaeb357c0717a0f246a9ce4064b7351dcf1e77cdbd393be64fc3763d06111961bb208a2b858aa1ff181781dda630ca41f0d45ef2a9000000000000000000000000000000000114270d35ebff55c0341776086d893513595aca3b200ab98c8b586029b19a360a04f2e77e90d382174296443ab8531d10000000000000000000000000000000008b88849c3cda9a23d37ec9f4700904edb24be95fbbe6d9e20ced0d52208b597d44bb9269830a1ac5cda35d0c0a03c9e000000000000000000000000000000001144466b13427c10ad7679567067dc47c671107064fbb9bad287924c9bdee653c395dc2654caa5b3013ade932fddd5e50000000000000000000000000000000008e14e3cff3bb57f0d87680a0c09d745c7272bd3c216ff9fde7c03df2caffc27e0bfd9f99912855c156a787200752c125d2a2b6008a3b4a4cb3a8c28864214c7fbe154fedab1f9ff8c96eab6a5f28fd30000000000000000000000000000000015cda76d42de9fa86f900a5180ff016155f31b9276c617ef664202848d2efd2876d412402516c0c3d26d49f71d894acf000000000000000000000000000000001307fa2b963fc19583b7e4ef2e9dddbe93e2505e8f4f00ec52db26ab411002136c1f646b1cda71e19480c767906a6d03000000000000000000000000000000000ba87b08173c841a2bfbe424584d4685c39bdd0f83f278f9fbafa8111102aa3acfad5aabbe032c7123631fb8b454255b0000000000000000000000000000000016c525c1dc247fdf34344168b7cc245579585fdbdd6fd783cbe60b727cd11ee97b87a86647f78dda207c98e65c2ee7e6854e742ef7c76ad438cbf30c30103741f57ebbcdca4d6c4f14e554dd1ed81b24000000000000000000000000000000000403887fd4429f44f8da7f17ca072f867e88ac046922ebe3e1e6c4f9d8e174399e7648aca924a557dbf7b29c540db33f000000000000000000000000000000000522324700fb6b2c43eb5b39e0da94cb60e234369543f530ea47f4aa510ec0fd79cdf4dd3ae046e21d78b9c0e35107900000000000000000000000000000000015e946b90984257ffe3814dcc3ef065fed1504f0790f3564c8bfad4e97cffdb61c0d73bb0b1dbe78c4266c773abd56b500000000000000000000000000000000078f604630074ebedbd836c463f3879cd5d4a2c947da0e47740ec369112f4fedd787ae59bea69aab61b91f05d92061036f4f00b2494a32844e01d0827ca78b06f5eb40b6769f36a04f20eea229c305f9000000000000000000000000000000000f722bfebd55f75f3bbd0a55492499c3a3f637ead0e54270042fcc88853df5bc5f11a3677efa26d31c28368e00c8713700000000000000000000000000000000182618bc8a4b3f6556d79848f90efd6883df90806a8358cb6852bde465a27a70644ac5d5040d4f64ec355763f1a384990000000000000000000000000000000015f717739a1cbb2eab30e7b1bd9b25f57ad56f36016b59128ea1f2089f2d1dd0128b455b1b0e9e3b320f68a38a1bdfac000000000000000000000000000000000b855788d6b6a7748aa923dea3163fe525a7b43f4619c1eff3f9219ec3d98ceaf34b97bfd19aa6f91f7fcff728728978191e47a0b0c72bd17319063abde7df51498cf0c980c46946bf80ae4c9864e2e200000000000000000000000000000000120048ace47bc1ab3fdc07713b91a9223fe0fffdcbeaabc8a61351d756f936e18177f672c5a4db7b9dc29bad16bb7c4c00000000000000000000000000000000101275492a6e843306f2927b6ab540d7a5ee925bdab40103b4ddd885e444e6a6ec2d6e99c061284a1967797d8a2e9e700000000000000000000000000000000002c12f17a5dd2c56aed0d308367f37510f83c94a4482e5f632161dd0517dc2d4f46a90bbc13034c63dbd04fe4c616e320000000000000000000000000000000000e4b9089155ce2178f26b058f4bfef57b73aafb83b0b78138a01890a167709f79100a1e4d797c5849473eb3486cffa4b7baf8816db56c0a602cfb4caa9089136ebde05722ad4838671e45ada5c716f20000000000000000000000000000000018180eee7e72b6a4bc2e60555236da335fe05fcbe2b3cca4937e73a550aeae6274122ba84ace78eff84d323b4196f58400000000000000000000000000000000147659347e0fac7a16c92950ea5fd115416072f339d7de3cc0f00ef369f5122ff050d8515effacc825c807f7e19650e10000000000000000000000000000000017bdbcae7f63052af9a7d8bd71dc98b6eca7ecf5eee7632959fe56ed51278099690c534ec33be4ace4612b0f516794aa000000000000000000000000000000000d6fa233be4d6d783bf973cca3740cbaf0f719827d7f9310f38d1dd9d1c1f125cdfca6d12fbf6a8e8104f79bf30b00647d9ac1699117bb9b8b90e2fb709eff4ea0f7882bdf6acc6885c9458703cbfb3500000000000000000000000000000000082f3beaafa575e86be53b4fe7b93835b00759f921933402282e5bb0e643a812e0e4b676ad51ff2c6f5332d777641cc3000000000000000000000000000000001760b87bc4d2c13122fd7acc6d629c9f9db9bc9a2c49634aaf33e258ceb3106bc2755b227c6660a1df1d92c60067cf5a0000000000000000000000000000000016a819d7109c9a12199eb98537a730908a693767cdb35a69b4c7329761939afea766f0b91ae405e273227330761a53dc0000000000000000000000000000000009d14d7138440349e83f5ded46d18b886ef3cd63e0e5bfa0a8b50985142b21a4733813ec347e40cabe28e6ec1e068c24a22b6c1a24eff71f0fc64b6aee8d3d2dd0827756f5c959f68f1216c2dea58503000000000000000000000000000000001676d7f489219b56c198f8494e156fc0672ae28dab20021b7a6018436c7c0f107efd2493ddc2a1cfb3ad490ef146348300000000000000000000000000000000001106e89fc098ce7bd8bead5d7f6432bc54501370ae6544f34cfd996b3b610f9cfc7ad366751ae1211b848aad7d93d30000000000000000000000000000000011f8f0bd037365b5427e76d57b018c1c644034b28d06c8f68c59bff45eb4a2c4d761d066d96c13f7e73dfd80c81704a0000000000000000000000000000000000fc826b5957613f35bfa36d3ce088dfbbd06c8f2e88056a22a9f35db561e06fa0378ccff29ba8b81cc12c7a504f8c704c0431e6877166686239f014008959332d9d009a801be6a1e68c2de52ee264bfc0000000000000000000000000000000014f0f64acb0d9638a68278099abf5b5da3aa087792bef15192cfe3689b69b7ec1aefbfa14e659358b5410d98d2eedac50000000000000000000000000000000015ca79c92e98cf8314a2f6319520e1eb7d4656ca6e51278710cefd9c768a25691fc58e983aaf858d3c8d0ed73e2beec300000000000000000000000000000000007a5192f1dc906693568291f163e9632c53e1f418a87cd25656064adffbf31863680468f3ea451fbd22ac990dc870b3000000000000000000000000000000000131d2e3f6956da8941e8340259b8a15aee9fc6f23573f9a348ee9a51bbca1308dc54e7b4675357e3a9c5971be3a5c16af833a784d22b99537236fb07ab7b59918783e35b89fc9692d7f76a03e024c94", "Expected": "00000000000000000000000000000000163da4bf7e159e05eec90318a8ddad4a59fb02d7ae2fe18795d38c3ccaf797188fa16577e6a421ccfb12ba1ed573c4e6000000000000000000000000000000001256654eef3352b09e0027277aec042519d99eb2567fce2cfa50a0c251c12d3593604739128171bfc13b3bfd1ce8f9e8000000000000000000000000000000000b8a46123bc863bed525f97166bcb77504eeeb66d2db207eb8342a3d18f7f5a99910fae3e6423c6e84e437a2c4b24363000000000000000000000000000000000b73cf08023c8572f48c132add67dda7a15def638a01b198361b9d21a4634ba76ceed9819b37c12e24f148d255483856", "Name": "matter_g2_multiexp_65", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003113ba8b216d933fe0c81f23f75942c0065d21d8f009d73b1f698281408874e33dd2750fd4298367b81827cf6fdad34000000000000000000000000000000000b8a921e840fc665a786d826f83ca5a9c8f00e7c802bce5473a7d1ebf63e8bb6cf5c4b426153508d874064d1f1dade09000000000000000000000000000000001492ab584088d23d3b0d1283904f9a8f29f9efe47950c6e9ffb9db2123f3f9820b906d672fc7f97f0bd38b8fc0ef44520000000000000000000000000000000010d321c2538f92aad4631af44ae39e63dc06becd2460f0cee0e526328d167fd6cfbcf4edfaafe32d13b5fe66c009533bb16c1bc60e1a9be9a82c93b7e0311e7516a57d687d8907599918df77b3b6caf3000000000000000000000000000000000ae75d01481a51294003041afc4802326ab878a3a75eafcda43cf873cc65e300d28aa986fb82a2d1d649e5be00f956820000000000000000000000000000000017640eeef8982250f88a4d187dcabfcc9adc3ee9194dbc3c04c741690fce5bc7cb07cd0b7c3497191d9ed8558fd0d24c0000000000000000000000000000000007527fd8dacb81b8d1abc746688db6a47211fa71556155d38361921c4bdb2a9e9921a3a540bcf55c6dd751b84c04a1040000000000000000000000000000000008de9109ba354d7426a5313d66cd747a54df347f0f86a3c0f99e9e4b68fc79641fcf98ab39fa23ef6f1a781c48f53f76cf301dfca76a83c70552c9cbc9c80cb20f0d82a70a9d887b04b150fa0764ce2e0000000000000000000000000000000017331b8367f07756e789f7edce4d22f6886656fed78ddacef6987a2751dd3d5d49011a050e7b2a3e11fc8d90266c9d710000000000000000000000000000000016959c303e11f23392f95c1402d1d1ad7f38343c711e96f18d03f832f76e3e81de789a6eaff797ae51079b13571334d40000000000000000000000000000000004266fd13db1ca80196a91263c79d1583b717fb61fd9ce5113e4cd94c59e605152b244e10e364b468c5a561c6fa9715800000000000000000000000000000000026f67cb263be83f3163856f091e9346651c29d4634e242da53b22eb6e66018d235b0f30f8833310dff9f3020e5bd3811cfb94c4e029a2126a9cf5561c677687f52059e4b7f8b7e7e73e5b1dd7f42129000000000000000000000000000000000114d8babd11c81ca2b8a7e193afbe0a8fce426b83996bae6f77201870e51c9355c319dd86b985272f73e0804c0f53700000000000000000000000000000000016f5ea7610891d0e72975816c08e6e25a75c7c42500655f26efdfb384241bbc825358a21caff347d00c8b2391501d15400000000000000000000000000000000199c8c74a79ee90c3606906bbb8cc163c214259e4d0127cee3283bcd9c1ebe4090ca7d7b180201910d3f6f51566d3bdc00000000000000000000000000000000032c785165ad4c1a2846e15318bd7cf5b42ce8b675cb18fcc4232e28701f225f1ea384b276e7a38b2c9e2e8b112f1911d8386fe6f4303959e58165b422e98c4813b1bad7808594473e4e66df09698cf0000000000000000000000000000000000842c65006caed9b53add048a2eea89e1b4584e1deb4365e3dcf8b9ecb02f337bccbe5d6929ef8c20461847f171fd4d600000000000000000000000000000000100dc23e6c1c6f6756419a9bad3133bba052f408a424c5239b8528ad4429a2bce64b72f1463625f7599ce43865581e9600000000000000000000000000000000125b4d71333274a16e52829ad5eaaecdda5c206063473dedec5a8ff4424def70e6f650926948dd2158b403f985a3421b0000000000000000000000000000000006a031e3c002702837e4ad28250b85cd94d42cf7b0d765b980fab95edded7636d13bdef1be63e66682c4e297d0cb2b0302e1c432f3b55ae87ab815647f196be3e138b2f6e9fe7acb9459650246187eb90000000000000000000000000000000003f7091a25da7d5afe6fa6b254604a1abe7a0c6ea11cc1a4167f5f648aa973d888383bc7e987b620d23e688868d318360000000000000000000000000000000016637f888efc3e057227cbefecb3037aebf8e330c3a794e51d691e3bc064237b98351beb746868aef977a83d1fe163ac00000000000000000000000000000000126d2884487984f851d1bd7d61bdb803321f263918e88e0677831563bacc9f5207358d1e9c76a5a25a66f0294f459e3900000000000000000000000000000000125c61b387a4462fa3bb2f06a4cfbd7df082d20cb23ee974aece2ec9a3b0c084d13a7ea83725a05d9f31b8033d2888ef9b0cc0ac499dffd627f5d19b87817dcd67e87561d5244a4b5698265f8c5b767e0000000000000000000000000000000006cf2bc7c691c4f8a64d0aa1ca3760d715b3188a2dd299ab09c723315acba8b0b4bbee819ba06cc564f0c875a63a415b000000000000000000000000000000000bded3d695e471f30f9d723f55826eda112eb0e3fbfb9a377cfa07d6233ed84108b92a79bb491a2971e9afdf83db8e9a0000000000000000000000000000000009b0e9928cb267508d4f9444c6ac3dc6f64f49a70c82c0bcaf4022e97854e5d9ec2612a2cd4d67642dc0451583bcb24d00000000000000000000000000000000009347dcfebe93a2f7674ad02ac48794e7cbffb04dd85b0c8c192fc85cfb9cef40fd11def6f63ae9a923960424eac6a02f3875f81fd39c9b3ec74eb269903dba4173d8eb0e41a196d3131252207ffa040000000000000000000000000000000013e8215c7bbdca445555c9fa0ae44e1905703334bade3294fc047ec262b9e4903880d52851967339eeadd666200b25ae0000000000000000000000000000000003b0bf4498103ac03601a8594b154b59a2a93d663f98ff8dbd2c85a1902e572a9456c629a12651aa87a1262102e1c770000000000000000000000000000000000e8bfd7d3fa0f773e6bcfd0d43a5c436862d1cb6a4ed715093c6782cd94699090c4bde597f65768e963fd0f8644e09b300000000000000000000000000000000064dab4d0d0c6b94c58b067337f2fac7d0d922cc822562b6bc941a794d96aac5ddb83d1d5844440d21d0a72a69303b8b2d8d4341822dba68c6fd58cfebd07b134c1d0c4e32ff63f7d59addff4df1ec3200000000000000000000000000000000098dd9a20f84fc26e78993a9de4d519aa2f8d343fbee501af945e5943e88425d29beb7ae54481b04175a07bf69b260a30000000000000000000000000000000007ef43e7a56e4e7d532420e152ce566d9055eadb4ef13d5698c49da905a4977fa8a7d3f51c8f5275582e1647984be61e0000000000000000000000000000000003755ee4432ea90f2197c7cc2e191dbbf7950c52a2c1b723f26d2aaf7a38c1b97efa29a312fed599f1199cf186400adc00000000000000000000000000000000150edc463f0a55fc70c2ffdd1f73a3abbdae459eb16adf79e96d18849ca638e6f41c6805b73755968be5cb110d81faa4efa3dab1d7cdf949bd938ca6ac371f953b3bbef1aec7ae76bda37db4c940b3d8000000000000000000000000000000000f7149602cbb3e5f2c5f8edfe59fc0fb8e1f03f89ea192bfe3990d87ccd28d4a80d7cd3003a8cfd669e1b6ff7e3cc5890000000000000000000000000000000006ffbc965bd06de07d8c0a9db8db5ab82d5f11afa1ad8eb92ed4453489f5899cc8c46ff02743956bed81229f64cf6efc00000000000000000000000000000000164cd3271ace4809eadeb1c0f769094272f3b66968690339bdb5da92e920cdc80c9d577ae4fa5b6426a5a6f46fba80bd00000000000000000000000000000000098f0a14a511ff424847d2b4d1b80a049b1f05ecd40af96b7a81def54486e4969011c122ca7dca3444029daeae2ecfc79848d3c53632dc461619c8c522013b83550ef3dc7fda197ba37c9cfe4340f5a50000000000000000000000000000000018409c0d0f37f4932cca87e24eb4d55e75dc98f938420ce036d43689fbdbbd839dc608b21d12a8af1d0a780aeac6617400000000000000000000000000000000109f2294669422a4946f926b1f106c2887893a042e3bf900559429c7fa484da4909216c8dcf826871534981021256741000000000000000000000000000000000a1ded19846e603b958d0bdcc9b554beca784b017d2a35ba117890fd0dbf729428bcd9823c7a378706220377c82a215c0000000000000000000000000000000000eafc89e30e4fc0544497e27674ec5b37ec0849fb382e608e09d0c1c94cb78bcb96ef4ea48e374aad1038881706fbcfcbfd192e917f2e0c4d6253c4e4755f30812149d1ce1ee4ae5540faf1dbfbc13a000000000000000000000000000000000e02cb3e099792ae7508321ce7afa323fd499de90c4006621ef5ce1054d0c934ae058a97ff8aeae0c88709c4d8ed0adf000000000000000000000000000000000e19318f5890320f17d5243adb4683a97e3e9763102c4fc93e3c3e3d24f4f61e0500be916c249dab00094b4ab048fe99000000000000000000000000000000000989faafcf6156472368b282313e076613cfe7ff135eb131b49e58932cbfafecf6585009d1f17ff8941d7f871be23e9e000000000000000000000000000000001167419d097ae8b96993b2e67da79b658adde1e12e43c71f27835845c7077f385612158d3e59fe2cb32b9418463e672679eaf11b3a30c7771ce63cec214416d798de20432670280d997b2f0631007d63000000000000000000000000000000001579b7d03d3d2c8a280e8ca113bcc98afa6a2705a5d228d92807a85cd5a1ee97510f632293a478c3fe0bd383f4b69cdd00000000000000000000000000000000107cc2e6bd02251bfd565b4b848adaa84babe9d4f083e827ceae6bacd9c9c221f0dbbef53278175bf27ebfe5949fcf8c00000000000000000000000000000000018d187c566690e4edd8d8abe5e0a448e352f622c96680378051228b6d081a4914aa51383326aedf45e351612ad6c5d000000000000000000000000000000000197427117a52f82aa6e931ecb0c5ffeec7f73ee8f44c5816935d26c06cc8285200ff9240d98cc244708e00669460f98b43077447b67f65e16a8aeb3564b2d13822e478dfb4a82a15a1c8fb7cc8170cc90000000000000000000000000000000019bd947df5a437a7f1ca2340bec628f2783cc1760dbc4a97ae10093aedd9f64e25ba79d9f4ce678f4fec91a3b1eef2d7000000000000000000000000000000000770e0c39988c9d8eca076464a3e10e274b06b1d2f6230e6dbd8dd59dd9c062f8958c6870c44ff196341bb9f65b8db38000000000000000000000000000000000a1833ef19e2b8e31577e5cd26e0a7fa46a5d25355d8b3dc0605f53714a60423556f3bcf17649745695f68f26570de0b000000000000000000000000000000000f449aed4120f3bef05506f2463f4546c7ea67b9e9110d3942dc256400d063dcc571305b1d4cd2bc3f18cf25319286e8eb64479b496c17d0587f6f26c62752881b6a9228643e8c43f21c441eeb643107000000000000000000000000000000000c1f9688ea64165f894e85b21761a9b2bfce891070103119ae71ff7acd164a57b0e054319631180c22f19eab8607f5b40000000000000000000000000000000005ba18dafcd3552af464acd469b133896e90c9ccd7e3bfc6e05db883f3c6aa1cc4610ec47f6354f6a7cff4385c56d2b3000000000000000000000000000000000fefbd9d78f48683b378d2d6311bf7ffaccaf7aa73a0bb4ce019a0c1d2e1673e52c724bf3a782729ec23d258043efff5000000000000000000000000000000000ea47ebbe3e858c5fcbf5b0cc9017d6ea23bda36e235d2aecbec827fdd2e4b042d1108d5f645b6dcdd786304e6bbf81b52b42f75aebdad1bf433917c025800c4f4e985cc077db3ba36f7484f95764e89000000000000000000000000000000000a313e1bf72d9a176bbad609631192c779e94c293463507edcd1c38bee8f33cfe6104d7169457ad5ffd9f045fce1cadf000000000000000000000000000000000af8db18938c51742b351fffddd74bf1137092ecb50a7e749391bacc9c1a19c7b9cf235b52ed577e7855d4ec1fadd940000000000000000000000000000000000febaa128de79274ef11d3e6378809d5b319796c653604723693c335eda175014b645604271429e3d449e756c85bcf6f0000000000000000000000000000000006adb29cc4ba053fea56d07225d2f7735651c0046f5cbe4a350dcc20431ed9457651d46a5d23d946959cadfc5500b7eae83106e9ea63791eb192e7a035bee27bd049b3a37f080076146eeeea6a769384", "Expected": "0000000000000000000000000000000019a5b588aff8853adcfa959afc5135807d00196a75acb3536ad4fc9a9df3803d919a2de7cbe9ff762913225577ebdbf6000000000000000000000000000000000ac8bde939ba2f164795804d96dfa8d3a1c4d9e4eafb000cfccd956c24f4d594b30bbf961917f625c86270cbe164cc5b0000000000000000000000000000000002de09fdf52aec0b91bbe99fe2eb9043b19975c6fd503815264ce030dd5e5444f0f4275ac9a07a49de775335d52ea3c40000000000000000000000000000000012457bb55876c482e5b907c765b476dfe6ebfe8e588cb7f630e58f78942bfca57e6c0d5d7b0ce80e48960e297863d212", "Name": "matter_g2_multiexp_66", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008f3f1f04fb80a23d348e3e25dac1d732265fd4a71ab8dad3718d268e49c79578e8e1ad1720e70357439e57df0791d64000000000000000000000000000000000fa4c15c76e395fa706a55d1909ede2163274a68b3e7afb8d2e0bb176f60c06f5a921c9ace35bd311bd79ae86340ba5000000000000000000000000000000000173633369e00c8c5528bd5ccf95c6af8b012e5a31941c134ad4541099c7c33c5ffd29a5a31e18be720f7ae85132cd6cf000000000000000000000000000000000800f5eaf7c8b1dd2787305ecc637a0bba8eac807a7b449410e48aed3dae2b4645b8459fcdd477fd92fa5ac6291b800ea4d710d2f632e3ed0ef69fa0219e16ba30d3efee99386f1a5c921f4548ebf64b000000000000000000000000000000000ea8057b2d609ac2130b21e0b4a41f0aca20ee7751f55d816ea42cfa4612b67c3c556b01b0bb1c5912a74c50a420407f0000000000000000000000000000000007fbccf8ce8d1a92756fe80b15c7d9342af4e166d3c1c7e35ea2fac34851cfd983633270c877224749365720fbcea54a0000000000000000000000000000000000885e173b73118721d28fd26f3a9c562bfbb878ce71091d7ae4b37c1f2625777d67955a2b7458af71077db7557171f2000000000000000000000000000000001754edbfc3f2af94c92e6754d6bb096bbc4b39bb1128dc6bba8b4d4d9fac6649598be90b06b9d5db44c4e77c0cd1537cbd9ae4597aaf582857b40096360ced0f044ea172551c6f9fe3a15e0ce290b56b0000000000000000000000000000000008a1a751b5f9a08e2bf5b2a58f62f0af6b8773f88e50f658ed220c0134e83c7031a288eb50a8a35016d2362b431d809d000000000000000000000000000000000d7f04d4a6c36cb3d105dc3915cd5d57f56692132681b3abca4b00e078c700931848e34ea1b7ec663f3886ff766fef41000000000000000000000000000000000a06c3ac81d6d0466e1ef21115150d04c8bd6dc3e4078e46eab213203c3226bb0c6500ae4fda591d6b8a791de598edb90000000000000000000000000000000014d849ddba2fa79b6a7107efeb46e9b6231d65384c69ed183acfb922d55b790d4fc7546afadc190b76f7da00103ef565efbcb4bad99b419820eec388f6f62ac8d87866d7beae6d431dfa48d4243b4a4b0000000000000000000000000000000014dfcb5fdb38cf09c1ecb284dd4f2de0c3d70f90d7c167a442d84e9a29bf43be62cd319b2dafdb6ead2c6596443a00090000000000000000000000000000000006220fc05c53f48e7e4104422b0660ab67fd88a695a201366de570f0ac0ad30421d5e37a1575e6b5ba35f45b441b297200000000000000000000000000000000077cb8ec1cb83c4974f6452ce0de630afc82e283eeb55d3b7e9969bb44bcf0404deae617393f82ac228b836c3cb6f95a000000000000000000000000000000000e2bdf539eb45a125112836008effd104e881aca397457004fbda4a40d152817801bd259434481f0509ab1838cdd1fd060d89acf5b49fd1f70fc54756c4bc1972cd8818e36efc37b422ba6a9318fa134000000000000000000000000000000000a09843630131cc6feeeee8aa8214408235655e4733badd6fe20c5cf1e45f6a61a5216e0cde937799437962706d3bfe2000000000000000000000000000000000ff518501614ed4a199ca9e9aad4e8efb8e9cffa9b4fa683093a49cef4669198a7893db998d5777f2cc8f4bb130c84360000000000000000000000000000000010ea66fb5224f4508ec100cdb611be133c4895a8de1b4c475b097494ff0f1ecdc1bf8fe467c630233cac2ddc07935fcf0000000000000000000000000000000009d22c0a45c82b0a19beb94eda0b93cbbe1f2e5f2d61279e1e1c93ba073cb766f5637195e6964a4814e588e44bb03f03386af376b9b393dde994da419d1f7aab60023546647f7b069ede939386bd6ee80000000000000000000000000000000015ca795fc7f0d169ba8abdafb1dee80b67e7dc616e824959f84c61284d6b2e0e8b9f99b414f5bd96d0e59b66ee706fd800000000000000000000000000000000042f473d1fa228961aad526efd003461935954abaae347dd6c9bc7fcd68b5f5138e57ab2a160cb19d1983089b58b51ab00000000000000000000000000000000188eb160cb968b4b048ce14bb72be27c228df1a6c014fa7dbec09a30aed8c71e8da59d3d5f8073b6a7d70d94c0e59dda000000000000000000000000000000000d467e6b05f033f3923667a82d5b489a5c90c99c5f68078aec700fc67a83d9bb4c09f3f00b9fc2cfd62bb098f885fe295ffca78eea65c00e1128f8dcfc96b39af1c4472b461ba5262307003bc972023d0000000000000000000000000000000003bec45d94f3073b2ca54d6332d36fdb8f5c801d9f70ccf6e3666b66ee06c0fdfd741f74cde1997aa205fb0318c9c4760000000000000000000000000000000014009b777b660264eedb35ec2e13ea586aa9438c47b3fbfd095ea3d8688a89c85bb4052bbd3edd450c19acea6372d0070000000000000000000000000000000017f26d3cfcb40fd6b4f3f1acb6d47a9b54c232aee484c7a8992a3d1accea794dc384fccefb0418d43e1fa7b399bdacaa00000000000000000000000000000000153c6cafbff3c53114c96d8caeee2880dc063d7db5edf5f14157117387f368c76b739553542bf6a9bc4ace3694de885a92837b4314e63ef5a153ea2ec4bd373cc3cecfa3e892c3a12aaac8ddcaf5905c0000000000000000000000000000000005d2481438c03493efc9f1e8e9ae6ab05b7430f7fb82e108aada0e886b14d769969d54b17b31e5bbb63d40836748f541000000000000000000000000000000000971deac599b2161a4baf1178feb81fd4798ad5cb063b1a0cbee7cc33b8fcec6c3f43d1d46d9ed45555187db636af99e000000000000000000000000000000000222acaf8df647744859e04104a5fcd546949feff6244e192a9031fc838f368aa465a3799779c637ef0087183f30731d000000000000000000000000000000000b8e8f1889816f89401b070db687aae47f7264c9be192a8d6e485ee71a5a688070d57ad8928d09d9a4925f1050e2c69e127ef2309c699a3602b0d86a070baef0eef90f539aac3cb6ff42cb19f284bd99000000000000000000000000000000000b8a5b0dd422469a8d6d7603e9f3179f443ef3fab0016afd94e93e2ea9e84b332da4b59f23a5257b99460efdf7d2aca7000000000000000000000000000000000c28e7068769c3a79bb8d92c3b89eca5d6eb42e3e18c2a7154f43a671f8670f878c4b110990c2e2b163ba4d1155319fe0000000000000000000000000000000001804302246fd07d86f4bb23f610af38deba8e324cdedbe5e61cf0941281cda8fb5dc211fbc0ce6fddf30aefa9563a0500000000000000000000000000000000015813fe0d6bbcfdc8e7e40b6141db21e1b490d846ffe82eeb3edcd9a024315193259612155b0179a4971e205738af74ba0f9a93c2fe35877ddccee5da39ce5ae60a6a19e72481319e3b3fa2eac614890000000000000000000000000000000011ac1ea4dad0f650fe0844ac3ab9434ebac6eb70a5f77c8f9c892cb4cb06639a15c63a9b820ef8f7a720040ae5b9e49500000000000000000000000000000000117da7999552e7886a25a939ada0944cdb15b5c468e9d1c3bf5b6af920e470bd648d24f3cb7f91e670f57a52cd65f7b3000000000000000000000000000000000a24147ef5f2b8ad888899c1db8df0a601eca9d76f1b934b1627e7eef3efe542f51205b96b5c00916688579ece81336900000000000000000000000000000000151863d964b12287ae4278c905341124985410f1ad6a72bd5c62230b7d8b0cddbea0c62cb2a7147afb5bfb03348be53363da2f227d636f10e814e360c2156e686e26ce3401dfd15f47c4ed277d05353f0000000000000000000000000000000001d32ea5faa6303c530790146df7cd5cdee93c0933b4cbc1c2b8030bf0a8d2600dba1907df1756152625cfccf8cc7fa90000000000000000000000000000000017b05f549751d090f42ce8a3ac5d959cf988ecdc485f51734d52c40a3e22a097917345978209fa74a0a05be0a66e5c6d000000000000000000000000000000001481fab7750380626b174602d9fcbc97555c516f4410193d2849443cf25ec22840e4fd00b225f98d81b38619e8844ce90000000000000000000000000000000001d56434066551c5bfbaf8c9007874abe57a6f78de9355a297bc117f2bc5e6e3f44b248037f400f7caf83fece0c00ba0ef79e3b6ce752d140c3dfb2007a08221d989038c921efff3bc4e150a6155a33e000000000000000000000000000000001667f1400973598ad3f56c2e49dcb5b556cc38ee3e5801ac4943f3c4554205d8fa69831e582a084aae1ef584feb0a1880000000000000000000000000000000003f0bb26ea548e498f05a5bbda8b8e536613f10e7165607ab77565b193f794664c8ab0a5ae2368d7483b77bc1173d14500000000000000000000000000000000176d8d294b4d975629c6a89bd6d45f9c3924a621259ab43d33a3d5aa1f423b68e3cef96dc103494bbb9036436c170f5600000000000000000000000000000000002f8ed87c584e69de59cdde02b6de9816c31a6efbebafb6ad9cecaf266f5bb9c8880f062dbc9235c91c668bae5051f4bc08091af8b8c6ea5c26f1a7d795132521350d774042d3a8c0523e86fdd23a3f00000000000000000000000000000000085fee95b859c52e44fcb2900a9aa590b1a5c2f981a388d6ad7b81ffbfe033f648c4a84e2119cb0484e178ebd3e220d100000000000000000000000000000000171e6ca074aa97981d2c2ab000a8bd12cbd5f5d574cb83158a6ed734e8f9b7aa4b74aaa43b7aae31b3f4fd3d82fd30ea00000000000000000000000000000000004fe6099a52fb491a0624a8d787d95617f6c64d16d20d1b3769f60d4721f7af66d7e3e905b3e08b2946ef7bff4806ed0000000000000000000000000000000004d3d1a56af91377ae6b00e192ad64fce6dd43a37592fa8706c9344b3d96b1f930e03be85a5ead3007f9016255d2df7570363101b87d685aa7314f6569fca0775bc6aaffabe136e6c336e8fa43dedb8a00000000000000000000000000000000155830eff04ec2f4dfca4f73403e408a68830bc031555433fd38ab3ce1035b5f882bcd6032aba69ecc43625546b4a3a8000000000000000000000000000000000ed5b698b1ae23769cf5b6dc2e39f8500fd8a881eb43452d67c6b84ef9f0b3c7d81db1909b646e92412acc7365923a940000000000000000000000000000000009f28ec2f949cddee9bbe2fac12c2c029f4e472afa1ea56d0edfeacdeb9f43a4a43b79ccdfbe8957b4cc16bbcac1857d000000000000000000000000000000001474b435131301db9e232ddf54569ba99bc476200ceefc15e4aaaf1a574c1de8bd2d63c8280e23127a7a036acae223b1997ff3852cd97c3a65bce9083ff66197fd5c70894641195514d556102f091e8800000000000000000000000000000000168475854829d47356d9a8dc13a94e8d169771ea0070d9ef45e666d5378dd676d603c2eb57a3cda072c11e0926b02d650000000000000000000000000000000008b493a9f4c19831341782fe6285db2f7e8250d72952351ddcfcae6f22a2ec0935e29d396ba32f72dfa4067d0e7ce7cb000000000000000000000000000000000d9e72e22f2a1522babc5f2e8dc7857ee690f60f7843ffe15a080d56bf63db86f124cac039cbfa16fc8ace4d6268a1180000000000000000000000000000000008f3db1f6c0e5e7b3bb27abd34bd877cc3c373c681a3abc88eaa91636924ee477ba5032801dda091dbc51936a90c84685ff95dfa306f91196849d752569b35812e1db7946708cd06df9db9ee75447bc30000000000000000000000000000000004e34bff7e9e3ede02df950aa0e8c5f4c5f85cd3be89d211e957a7de95b8e321cc11400c3dd5b2ba0d1a3008462cebe7000000000000000000000000000000000fc1047097f01fd2079e6357ed379ba39107ec41ed6c6dc17fa6248d52be2b1cc2593c9735a6cb48e6d6e0434028f755000000000000000000000000000000001896fc5e990aeb416cf21ccc73f02c41d019d0a2679bd533d0811b7c16ad3ad3a6988170fb2db030b5fa7c3e4df5acf4000000000000000000000000000000000b70e14ce1b54d7913b9f3782b2b8ff249967a6b871dfac7f54f959954febb2783cf20e20d1710e5526ef8aeafecb3d603c4308f0467520343825a91c0421f9c9c9d06957fa2fc051970f14085339e26", "Expected": "0000000000000000000000000000000008056d4dfcb593c10a877cc8a4accbf58f360256b76876ed2b33a07be3110f8e295ef459dd6fb10d12bd02a8276351f50000000000000000000000000000000005686da1a0da89074c6b13fe9913f5cd49e0ecfea46e06493510625f1393ba4cc2e13f023fbc7ec2e130bf9a4f7483ef0000000000000000000000000000000010cd660001f65876db5b2cb1a56d85171d4cbf037f3bfb0e01bf4430c479237cde5b6cce5839a4fb22b406846e757868000000000000000000000000000000000809d7711211d37df76cd1cf71001cbf02c76df67c83e4eccea3e05b11d196b5d52ad7c3d0a00d9f0ef5b018717fc3eb", "Name": "matter_g2_multiexp_67", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005d6cf50e3add0e5ac3016b394ec363d6145ed66ef56b07bcd33c90600e83b4277558695222062e02d1e2b0693858e73000000000000000000000000000000000de8caaa810d4ac39258e3d1656bf7f2fb7853a5963ecb989346abe90d5d35d3662f6e283cec7bc386a6a8638ac395ed000000000000000000000000000000001849ef86eec16b0612f214c5ed52c0d50a90bd65b623402879f2654fc578ab680d49af9afdeff546702304597a20f1fc00000000000000000000000000000000168707730c4e74eaa4e85e48e7239b9ba3e8cb74c24b7126a685da0fcc963b9f9180e252adf7d8c521deb1a2ce0099582849fab097a4f71bdfcfaf435994a0c6ac3671a4a9ed0402010be83ff95228fd0000000000000000000000000000000007d4fed2fbd9e9dd19e0af5c52637b2cd337e0bfbcef0384f182a56189a7e7304b9d2144266ffa79044be90cb7ede1b6000000000000000000000000000000000baabe8c23a10cfe85494c693d1b09fc8e43ef5f233052d5b6294dae14b4ff9e5ec240a1c00a16a9ddc27cf7b53bcc7c0000000000000000000000000000000001c595f193229da9acff04ef67ca444b0cec75db5b2c1921502e37eebdd2bb43ef47290fc6f1980abc75ef4c50034df00000000000000000000000000000000010fe7f3110ed3a240366ad7ba31d56ab993468dae2dc1b667a46c7759baa37b865d02834e14280a2ccc062af5bb2b7d6e6558521e301eabf09e80a509b46cf8ec118ee8586f4e46a7313a96dc37ba69900000000000000000000000000000000150350d8a771c79268606d6a5e1c147dc9d92e63fdc60b20be688bd52eac697aa5d90fe1b7b91321b2af87c47ac0d5060000000000000000000000000000000000fba8f4da448b8f2bbd99014bee2f9c581f2a974bb0b54f41a84a7fb359e9dbf88ba59a705504140284d486241e94e80000000000000000000000000000000003bb92d6a603bd93f8e987071a7385de68d10cfbde389eaf01ba6480caf1ad8aea03c84d1889b7d5b5c5f72e62a2d75a00000000000000000000000000000000193342a9f15109367030724946342e564507b26971caf75190e0b209e429a948d8b21ca16041a01010b68222db66a16b8f2f7c525fc0f353700fa823a5d32a93189699206c5ba5ed271a158ebb47674b000000000000000000000000000000000bc4a46eea57231cc64758560e3032a8ad8f1907b3cebd7a8faeb98c4216cb8a0c8fee09929ecefc4bee7955f4e799ba0000000000000000000000000000000009f9486257ae3f94a2ca48eb203e2ef44ecf866ddec7824e1a4bb3b89b320c38b3c46de8202480628c53c415433383a3000000000000000000000000000000000d8e2b5d0825b11344d16dbb2cc614c6b84eb1cb43f70d70e272123867b731775b429aacde611318b2700aa567a84c7a0000000000000000000000000000000007f720929287a70873e9f2f2031b66693eaa6e604668219aa5aff3f50e720b34c5fa3f5c66eced5c3e86e8b34a81b984c7e8adc0f0a042a32c733b5c3356cf4a7d648be51c1d78534ca65dd43a0c13e4000000000000000000000000000000001537ed68e203e56f31498efa314322694ebd74cd1dcc3145d534299fbdadd4256f20b9f74b895931a60753bde6ff9030000000000000000000000000000000000935c6ae847aa7f47bf427988665e5e18a32aa869e196cf9d5bac1349c650219a8d20e01bd8d49bc7e4bb8d464aee84300000000000000000000000000000000013e0661d7254428861cc3ed47c3fc9daae8b86db35d1c64f8ced3bc18a89202825f13163ff94ac0ebf046a0a99727e200000000000000000000000000000000039a6b0b2cb91e460d50eaf9600c29fd4f82a81c283ba4fbd9a7d103efdaeb1e82947f5cc1a7a1112ae6344c51119201650081a6720845a20164ef7c06ce1e73286a32dd64efbe57fe46765008dc9dd500000000000000000000000000000000071a6b0267806f2b9e0ba493960fe0e43f135c739a54c8daf5ef9ee348a281f19876f80c0dcea59dfe9457b49809c12a0000000000000000000000000000000009ac83690c30a4afd78f94b2493674668da4efc84007d2a08fc78bba271ed1f43e2a9e5909149bf0811c44dbe07c52f9000000000000000000000000000000000f5d523612fdb2e7dcf5da56720057dff6b0b80707cf5924d146c0c072edc0635c73fb04256e06c7c9355cfe77a7af0700000000000000000000000000000000168431fc569869ebba9b4a72371e3df232545b5fb95778baf3d9105930d9a89b4cb7eba430e9162a5589c7465e54ca3ac067d18b95591f7f14261f95513e1990f5a4f6908f94a015a93fe379726d5120000000000000000000000000000000000ce836522b983fe3ef6a502a0de4c599fad8a36a60d914218d5d2cc4d56d69eed8d27b2d50899639d1a0ea9dc7597f900000000000000000000000000000000014110ac048ac4c20e53f2214df8c06d77f0b3150077d027691cacd3715d4630a387d5819ef58eb1bce2e8669be330a3100000000000000000000000000000000178e5cb42f56df2f1b255a028a00df96c02eab0a79aa0ff3e9772fbe3eb62174728259b3a15e356e6d9666eb65fd6b7e00000000000000000000000000000000045197f136649b61d6e0e7b9a56674e769e2d26716ee7a63fd2b83b767a9ae96694e9cf81375d0377a1b27ea6dffaebbb448bb01a1963bf74e0fbf99329005af8e932074358d855ff43c213e02bf26bd0000000000000000000000000000000016a6a58301c243b0c59d6934bd926d6440b87b49f004f411ab0fdd924480175052f63f594c18007359055dc776e7f2d300000000000000000000000000000000176db4845cad46a13d9dd0f4077cd22b3458f64084c7325e9885f8ca341ce3ccd4f634f41efd6a70f16e1f0c9ae103a900000000000000000000000000000000068ba68f652c4f072a64d56618f93a1e148274b1b835433be878c06e11f65ff45b7cba0f67fbe80327abace68396da7e00000000000000000000000000000000047a699487964c98453207c98cc91c980c1ed37dc26e17748e6ee88e5f4c0ce424d87c82ca6db2264dc8aa9e437a5f25441fc4cb1ea8f86af8839aa40c35c0706f3a159b4bc902347009f744b73cee35000000000000000000000000000000000bf7e4a9751d4e3baa7ce9906f4378764e5384136944f6d3f3074dce66ed017759783c64fc381f0dd7512d6f6e55b4aa00000000000000000000000000000000006ae2a4fda156818cb5ea6120edf7ea39370eeecc3f306890f47a6dcfaffccbb69fd21f33fe491b7065838b277ad2b2000000000000000000000000000000000d3ce00c2f5febfeb232dbbb74fb0405bab86474d1d9c545c93b65c7892bdd58aa56225641074ec9b428efd9063085d00000000000000000000000000000000002552a8c1848fbefd6b039d6c4bd47c34dc34ab307163c4f6d337946f1d1b41aff2f7e37f5fd94012f0ebd21f97d18a83020a1ab853ef2018976e43cce2724105a2526b28d23b0226c49ff3d4a03d40c00000000000000000000000000000000105320cccd67b6ea78e96e66425a10a6911d2d348fac3231af583146273609fcd7fd27a19d4614fbdf05bcca0f92b927000000000000000000000000000000001204229ee1f66fb5a5dcc4ee978327e35d703ea310901be9c100af824e39d24a028ef8fce42370e5d734df02a26c145e000000000000000000000000000000000dd21f31f116681c1810bc36141cc18096cc113faee7db2c189abb7a746e398e272fa0cc61286aea0a5ec4008c8d03b60000000000000000000000000000000007911297718e98588844b9022c825bc4b37f2af30e1fc2d9cfb58b4500dffc8e9949afddd051e971fe78d4e1e7ad1b4a82702398b8c95c3a8cd163a8a3cb2a7a04030ef99404c325115e9a9312e8c1bf000000000000000000000000000000000760787190048e6ec8bc3bfc368f010e2f8aadd53164693a62b0d7207575bb2597bcec4bb382c57fe9053e90fe2f7159000000000000000000000000000000000ec525abbf13da64a8093c5d3fb800440f4c1fe798bcc71eb97bf2e0aa9e8be4b08afd2313f9143260058132d2607141000000000000000000000000000000000aa12c902084eb843daf7b351989bbab7a86acb62eb54eff0c7599bacaf44653c9fbf53f47f6ca72d22ea1671842eca800000000000000000000000000000000082f330d9a693f2bb9386fe5274aa79ac73a17688821f3c705120fb2aa76903627786a8614053f21a93e0aeb555de64e338468a325384a9367c90bd0450816a22849b845aadaf187c27b3f09800e791b0000000000000000000000000000000002ce7f08b8d5052d8bd07090744ca067700eaa1db61dad3e5086661850337bcab485c15fdd36c309a9e5169fd2a2b55e00000000000000000000000000000000073fa834cb4dc4ae120e738059749bfbd86b9e64fd71b1d372dcec8474f3341137ce8cb97a38955e9081f9bd5e07ab830000000000000000000000000000000001568df6806d8c3cfc9231802ebe5edc5d505198747a0adc24d0ac59f28d32b7b379d1f2c6b8352389057c7465692ded0000000000000000000000000000000004fb4b08a4fbfe197e924be3f7213a769a2bcd24109ae69a32a197b6212c5f50dbe8f46f5ab6044a4c779cd3e09d13bdd29136cbc4764346e7ae1af92fe64560f453821f96f32a42a2006b6edee75021000000000000000000000000000000000c07ff656904a47b0c7bf77540abc47cc6eee3e76b6ff0983151de9468ce3a860c427f3d5d489d096264159ab0567cd20000000000000000000000000000000008cce094ae1d9fff246a0e76cd67dbf9808c94554372fc4aed4879487ef240e45047dc201dd8bbccb613feb9c4623a0b0000000000000000000000000000000008a25297940a1bca1267fdce450b0cf43105eb4a21ab14562116039bc8379b1a3f58a7c117e9ba735bdec40f772465300000000000000000000000000000000000ae17a9b1fc3b0b7803ef48cb26643e8e78ef133f94bff5f87739182e662e2641e72383efab1f3ec58fa20fc816d56c675a59418f1462247d3bddda5937553e96d854b5df64a68145a193b2b1a7eb250000000000000000000000000000000002357e5a04b0dbd7f9a1709bce9b7afa12b10c7274b440b4dc3bf51a801d483804b1b4b9a096c3205a0e2aa7c0100c6e0000000000000000000000000000000002ff20af67f126c80293e44bb3c9ac74a94586a2de4146588c7ee8503530398eabc30f7e89322727739618087fa55de50000000000000000000000000000000013c6d06ce509fd557946479f2768f62474e6db04b2c92c5cfa86c023f79d05a387bd4c9aa618888476d4ecc93ba0995e00000000000000000000000000000000000fa477870c952f7506b879b17fb0a1c31771ee832ce0ab21a513fdd91b7a2a78a03d297c55558b834e255462b15520544a345719b40f973398a6fdaa2044037cacd7f6c361921c62053cd51f2e5ff700000000000000000000000000000000181336b8fdc03c02e23cd06ac975855caa2bbc1fe78a2fc7a9d0963c90a1f1f9330d50b88bf2526db6132d336ea5b8e6000000000000000000000000000000000f2d94d3fde2c0f67dae5a6ac12f713ccce2621303762e01961843eb9924d1d3c732b4c977d8cd0e5668adcd7dbf7dcc0000000000000000000000000000000005ac9ecab11c3368c75b0d396889dc34bd43ccf550d817c1dcdc7143c15d5c0e241add37328a7bd8556fde87d75d67fb000000000000000000000000000000000184704eeebead43f85b32d7f3efb9b9469f3ae10b73a2f034bd33e6e66da0bc36597d8e29ef5585443a655e24ffb68fbb38b4cd72eb18c3ac87860aa58b4b439712562f742f112b5d769415e9c19d0a00000000000000000000000000000000046751743f8f747e378738c265c1df3a368cd9570a2bd7636991045974c34039161fb0eddc6b813003e0908915b402170000000000000000000000000000000003341bea6cb81fc5e7baefd386a518d17a6f752c0e1ace5a9580a1b1649f5501c7b4639ba0cdbc33808d78b025a31f190000000000000000000000000000000016e3b9e8e189df73574a00a721440379589a7a6df09eca9a790e04c729400323b2110f63d547d83664c35227bd15b5760000000000000000000000000000000005ebd94e4640344e99e7e0f1619c6288665c985b90d99921ee61bbfce921265c4881a7e1034bcd840a665bae44467f5a94a849f6fb5a53bd5957e53ade1baee05702185b4d0fbb7c1cc0f46cb75614fc", "Expected": "000000000000000000000000000000000d993522760839abc960e99d62dca1021b52ddc8147929c4a064ec72570ffb3793205598cefab8490446453fb6da231600000000000000000000000000000000105db1e83fdff735d06d34574f962e70d84e2c1ceef4d8a8f14c2673633d7dbc7b97ba6dce9013f06fcfb134ffa2ef98000000000000000000000000000000000363be663cb0d36b8eb076df283b075ab9e568e460be804f197c51cf7ef611d8783ced304407d4c2540f1a4a04c18467000000000000000000000000000000000ab2c00473a2267682ecb356422aeafc893fab96a3bd27ae58d9b0786624c8fde446cf68bf8a003d9449702e345b1ace", "Name": "matter_g2_multiexp_68", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000a575d896b06c5ebd7459a70b9321cd0de082dce7dc0ce7e39581751d01b7db810bca80f39f521df0bf70ef642bd66a000000000000000000000000000000000ab497a9590deef40f6fdc0d4db2ae7b6ad9ab59f112a5a0671b48581f1f2b6a71602c73784ca6c0effce66a0a9c6500000000000000000000000000000000000af3812439e44981c91633f73d1a92298ca1ed426c98cfbdb50643cee36affd5fd02886349aa608f4b8a27452a51a96500000000000000000000000000000000013126db8b642d33dd988b745b07084ef86a228767f7e8bd45aac830dbce4136ca5febca5fda9644d3292203e27439d9f5b9d270fe31c772e9a0bb409d9f08a07887f045f906f30e2653d293b6c2c277000000000000000000000000000000000cc12f75fe5e6d6f082f9977dcce64c7858f3b6378112e7e083caf0c4b33b5811d62a1130c595937983905fbde8db1fe000000000000000000000000000000000308b803bcaf4f63affaea0206aa9f4770c21b4d191890602bb4151b80fdb42af0cd9f8dd2b1a3adfe28d0e49712d2290000000000000000000000000000000019f83af5cbee858fcbc9bca0f499222849b9e80dde7ac79b7c46785a484fecf274e0d4326469eca647cb223068a183d8000000000000000000000000000000000d0a8334171571bc63054c032299824523bd2476b1150a67eb17b84bba01d8a65295624202c3874e0302159951734702dcbf4fe86140c50618598be9185830bc1da11429162afe0528f00eb6698ec088000000000000000000000000000000000141cc01094391887f46391bd49fdedbaaf524cfc94d741cc7c8cf081dd7c425d81ea3e407be48127550012e39d2b0580000000000000000000000000000000014db31972eb242d6c2912b418ddf416fd7911f13aede9194559b05d1c9e12056deaa1e56c155cdbc231b39f4f9aa91ea0000000000000000000000000000000007b361beb6c156b5c8b92b489e6d6c05e32a4376d20ac3e1a54c94e678c88480779bb789c3e1ff7a021aa6d872c98551000000000000000000000000000000000215d270f2d3c5c5b9fa99a873fdc337f4edad6889f7a55556d8ccb5ee86b592453b74a720ef6a907bc342710cfd9cf91d7fb7121ef0baa85046567014620e1adfb9e8b3bc95adccbf2e0b0ea8f37c670000000000000000000000000000000017f5d31987655f8eaf046d6ea4025444924befa51c319b2bcb02dcdfde4d80a1c48049514e0b580e4bb59dd2fe40bb22000000000000000000000000000000000141ab771c08ad7c592725630aca0b2564de1ed8759eb3afb10a4bf451eb21d25e8d917f49bd5f7a06894baafdebbe790000000000000000000000000000000012dd82703c939cc5e7dd5bc3b924d744f0ef1a95fd0b9e57617e822e3fdda05b2e5a9959ec48cba0da40079da2253cc7000000000000000000000000000000000c53ff34d875fec4c7095af324d15921cd775873a3ba67740b2c123d6d482263b1cf93585dc810d19c68965cdbd9e102310d3b0535e78d803b477e5dc26c71bb18acfe66bd5ba5892d924d265afd6a16000000000000000000000000000000000a6514331035d42f58abf98b805f159921d8c4c935f88bb5493c580a6ce14a65e243424b41b3a9188e26a7f0c912a378000000000000000000000000000000001351e48b2d3f619887f4e83823dcd9dc15afb2800169ab78a2cd5ebdf25dcb6310f1051894bd2b549e509c55f5286f600000000000000000000000000000000007900972b84b6a76b2e686fa5757e98b8395bfc99da86eca122ce209afb39e8f3b07603cad92623774ed54d637e350d30000000000000000000000000000000002c68c42b3924b89a67764990478e48fc17aad4b5543bd38bcfee34fa1cae7535671f3b885852aecac53a30f28b0d4aa2fc9417e65cb76aa0093a7deb3d38c111c68f461a4aac57d8f09189f94407ee8000000000000000000000000000000000152d2c0e798d85e4dbf35dab808dd29d724e9b6c7ca7f53ffddfe1aef5976f2d3079eb1d3099e91b37d9fad7f1af5750000000000000000000000000000000015059423ee4e7201aa65e39116a2a49ba715b15e4b9547d18a0efd355de6f5a0159bc9047508bd3649407758d62887f0000000000000000000000000000000000e5a823fdc69f3928b22c542388f982f8131a978b08dde80d44e51d9eaed2ac4a1d5fa7392be6c7edfa33e833da4832c00000000000000000000000000000000044285f4e4ce526f96f9f512c5be754e0b0953744dcc04807ec6f041ba5c6fb9d5d395e93317064d50e61aae26810df0aa0b2d714aff175a0be2ba9e675a2be8936c42f15e304a146622a95dd6b3e3ef0000000000000000000000000000000019c457e369dbfaa130ee79bd33ca70d00a3797b6cf62126baec0c5d7c3fdcf5ba7f41195276dc412b6862b71560aeb77000000000000000000000000000000001206f67dee6521ede85573bbd5784d675fea42da16010544857d4e2d81b720b6f85f646fa23540880b44a6cde9a39f5d00000000000000000000000000000000142018ecd7c7acd4f4ae288e1c6a66594f1c7f31bdb9bade2b4dc4c6455cdc685b716382c54d67373831a19100185e850000000000000000000000000000000013b0b57463a3e4cbe063c0d4f4e998cbeb132a41c2877106ee60e83d4ef7d339a5432d30a3c149a42dfb1da9d61f34030227c3510ed6e4c7f84b11ddd2d6caa55e0e79ed59e1cc0cb325d55b5d145aa80000000000000000000000000000000008a463003900194e45fc2610fb461fde538b17c4fd516919000d423f5a1b582342ab9ec20d8eb6fda8fffc6a898e46420000000000000000000000000000000010eef0f7bf73e35dd75fb924bd9759c09aded9cce46b05e5d3c5eb3e93e5d5032ecc459e2220aa529d2f773c4b8b8c180000000000000000000000000000000002a0247f82a25468ee74da555218cdbb6405871f7097c24e89db3f3eab59b91ce48ac06e8eab2c049346436c846226a3000000000000000000000000000000001895b58a50c025e46a2cd0c59d5437f6eee75fac949adb7ee12d455c96206a33ec9ac17d5088fb773618fec131981ab6ad930000a9f82e082d408999b396aca2b0e435a66faba1d95e10fa0abc0625cc000000000000000000000000000000000cb0f13b0680c2f7de522a59f4e46fe1d4af3a64cd3ab97a2523ad3c3dc42f5e6760e06cf48e4db22ee64c5ed8273dd90000000000000000000000000000000016517038ecd2799d787c5b6ee93079c93f78de4a96449bc82699ddd6eebcedaa1d02981ab47c529652cc21663f1a665100000000000000000000000000000000067ae1dc093d4aa2ddd8b7127dc60745ce9c462a066106b099a7a07525597c72e4920bf64c2ea8a3fef3de51c703de8b0000000000000000000000000000000016374f51023e2448eee7c64115d85794996fadf4f76fd4266c45093c266f35be09e861d07ff194f3d15e310385705f0e1a6799cab8964c7b79b80e76be237ef49c2bdef5c99a38ea873af6e9d49790ec0000000000000000000000000000000017479396aeac06bd624a47e75b066d6daf5a37dbe515650cdf3e16be21e7d3a1f52a695c1c06382589eb7fc869c7d9250000000000000000000000000000000015c31ff36ed4eaec4d3927e62c111d062236e19fe6514236e6e3f7ff05ee96e3e4c084fcafcd21049a81faa1f84b7e7c000000000000000000000000000000000341b440e6c6273515fa7940d2f77018169bf6362b70a7b0cd6d66cd332ccc30e3ac48f7581edf47ebd137253a9c1369000000000000000000000000000000000cf424de046252efea9320b32b79bdab58e0e04f2916b4e8ef475da7b8ab85d8d5fc793a45ec6e6c035b6331a895d3efb206dbfd70e4b24bcc09ad35ce7b3aa62d17f18347f2bc5f15730202909c93770000000000000000000000000000000007c9111a85a6acb851e9cbdadf182096b720913ba3fb357dc2cbf2b8e796e9a8044b6df3ccadb740c73a16c3780c640b00000000000000000000000000000000059543a955c84a197d23cac22e15d82363c881026e41c57ee924da2a8c044f3021b29918d1db7926ddc2fc7a662ee7ab000000000000000000000000000000001355d8bcbea65a50c9b6ab59881e48e8e5f5592cee6aa69d5d01b033a84057cb6e74d911769bd2ab5f9722328aa204640000000000000000000000000000000011232571c95d0cbadf8e70454c851974efa4b326370249238db159a1224cc6d34eaad690e1840ad887a875b667ac1f193a607a7301bb7dc5b9c82d956ebb0bc54568d0654d725d4d5f13ceb6231e862e00000000000000000000000000000000088b7cbecf91721e01e5e4a08ea3b261febb58cdae3056d9316c3840b3e5720a289739568bec7b899f4b1f4f5372013b00000000000000000000000000000000001f8835d4b0e3b957e46b718b6bcd81acdb50ab85f10bb70c6343a23970efbe72bef89dbcb24d66e6a6be3eb55665a200000000000000000000000000000000046500afd292a31bb5a4a9bd7b5bd0fe608bb1265351edea69162e61f1623cf58e34e8e1a8ec58ca166e8203c86f84c00000000000000000000000000000000005d6cc367ff9c88fc8b6c35383f147b4f9e3eb21268a5a7405794441d449b3e1b44c8f66e30783e5f6c3567adf0d80171231e0fbbc2d98bfd1039a889acac471110d568b0a24ddf5eb3501adcbaac6fa0000000000000000000000000000000015bab57412cc5c7ee0147b0d2511b7836a14a82df06b4eb2b1baab102840ed04cad81da6e920ee000751e0727091c1460000000000000000000000000000000002f725e61e82980e6164cae7a2e30a36dd7245402f4933697607640d53fab2d5db57698be33a0c9b5dda14aa846db7c90000000000000000000000000000000007fdc589448887f6986efd817c63954d350511401333cb0df89214317dec0a82b06259ae9263f260fc7f21f98ad2630f000000000000000000000000000000001324e3bb46a1c69fc550fa8f2ae2d0ea74bc2d7159bed03c13a9d232233449e271ad1c3922dac5d84aae52606f77dcc0393c5c10d4bc4cd1567bca6960051f818e5c53704ce44dc4582767fef1092a870000000000000000000000000000000010adc26d73007e3b1cc58684fbdd7d197550658b4c66c702e9cd0f4e481f23a26c94c6798cdd9763110eefdca3d802050000000000000000000000000000000009138258ad1bdf6f9cdfb943fa32b42c4f1d834be536ed365d00126227c78b0df2776610fe5cf66a937cca3e0b088861000000000000000000000000000000001991db3a35bd2cd72377cd459502a84315422bed92890af906fefcc0acc4515fe7cacee1e4f360ba24efb23292482b8f000000000000000000000000000000000d10dfb682ae7a78b23b37b081efba32ff2011fcdae7b0f8a794a6ec33d71f5d6055f93e3b68a37086ab190d7d9bd7aed412195e347b680430c4528987859a1552ba8383cdc075c437ef19db6eff6e1a00000000000000000000000000000000182795b905320ee69281de833f37e040a3295e23be05ea7ae4563bd49d8b1fb02e95782c5c19645244633951cc29c5c900000000000000000000000000000000053368ee1412723b5c6465ee5ebddcfc00812e0e12e940f8485f44bce475c8897b324eaf7e66c0351ce9a6c92758c337000000000000000000000000000000000279f26c1e76e5f5d0fe1240c0956cd6025f6520ec303feb383b69525ebb6b2f199808a578a91368c3881a4044f37be50000000000000000000000000000000000ba4012c24dfe1038ec4b4565e1b321bbfc174cb197f0b0914bf1c126bdac9f423845f6742129670b7f3dfeaaa62df45b6701bc11c1ef3c9389710e4dd090e3db481c5400ecb91655c20694207a71f10000000000000000000000000000000016c27a3a950fc4857fc775441947f7ac02af9b3df6422874507b11f7b005c61d7d6a4a115d3759fcbd64633a8ad95611000000000000000000000000000000000e92954034df4f15450c32be31d4e146c4b0014a2b81e2afe755df79aa962afb05ca4d03577f15980fc6d8a34f2cc50200000000000000000000000000000000032db3e3c3617c16ceb1c8fae83e806744ca40cffb56bf9b79997cf48c55e5fea89db43b368cd922cd7ce30dd3984d82000000000000000000000000000000000d153fadc3854be49b2376ffcf4e5a46b9dfb4f54e580986767db13127e2d4d10e465f1ca932d79ca90f1971ddc0993dab45b07c059738ead9709bf36ab20b09fd3368f7aa12c6d9f3acf3f145c83fa5", "Expected": "000000000000000000000000000000000e1968e131e25d3f911284c369eb63aaf264ee82f4d9bd978b7d02470feab68ae82aed8509ffba875798a292f012c9180000000000000000000000000000000011488365570d9bff018ce6aa15e3d7e078368f09873ed5e0b827d1c25ef369d6571899c8df38a3df3135d0db814c87a700000000000000000000000000000000161973f4949bd72b9f010f017398778e0d7f0c8f77e12a87db1851af516b4540e3f4df314381f295c4d167fd9ac091a6000000000000000000000000000000000ae16f0a4a597159195aa47862585839485615095e538b745c1081ca73f202115a438d279dfa45bd3aef8d4043ec67c6", "Name": "matter_g2_multiexp_69", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000046eea8e5af344dc8600ba7e506e923f6c356f7ecb3b78bb3805c4561e808c1f570e122c4fc5a1fbe433b48ce0c15d510000000000000000000000000000000006f1ab405a46c825e104bc963d2b2f573f0d345bd2b08a952d8793c0297dce267a754b802ded4db478399cfa88e7e255000000000000000000000000000000000a5fc4a09019ac9649c07b623d2cbcd9f0cbb89d28c01b170b62544d8da8ba3f236ca3172ac754175a3db85d9b846cfd000000000000000000000000000000000f7580110db2549742f69bbc2850e4ab35a6e415bcd1b06220b9b009c1f4c99152289eedbcba2aa653f38f6b8460386b3ca13f8540eaf45ffdab5182883d32a1d35e7cd956092221cc40232efde6cd1e00000000000000000000000000000000026907ccf4d501265cfe67bc1c0b06840e9dd94a614c873d676b5416457d98a1dd744322887f1f1f86176b11a27d2830000000000000000000000000000000000cb08e541a5b32fdf51acb28ec64d3ea542c7bd75179fa3f74e9588156815bda9d027dcf5597d714aa001b2dd8a9553c00000000000000000000000000000000103ac1c03c16706d5936f216a6445577c96acd3a00a3d8a9c2c66e6ce568dd84a4c4db187a5fbde24e6ce60e037f53a90000000000000000000000000000000001da5cedccc02d0f8d1dd7e4d81c3ec47d432e81e941ea1452b112eaf40748a6634957c90f32fb0385dc5d642bf65acdb3c8b045ef559b76005875bce09a66b36f295070a73ec8dc66c86bca51fa5d4d000000000000000000000000000000000a0b8dd68918b58ca6b113e938f8a00b2595351777aaf32dfbf703ef3884f02c798f1b5bb78cfac32f196c1fe88aecaa00000000000000000000000000000000121a4104e374566f8d582f75a3c9b70f09628f116b7ab22679ee13a1691b0b0bdb0d737833fb606c746fafee5859f1ee0000000000000000000000000000000000b8bc89d718572ebdd6e3100769f2571cabdd79ef5ca9a4b9bbaa432b1a4dd752f9af9d2a9b1f1f32d76d4ec2d1636500000000000000000000000000000000129f1d760a12eb1a75fec1d2ca438189c933e87095b9fbf9a0371d64eb205d8f0932fde9ee2ab9f36f8b6e5d4b5dd31021953ea264f74bf64378a339461bff41c5193e17913c67be7e2a249c9737b825000000000000000000000000000000001499e5481ceeefcd2ff672df24e8987fb60872ed106c496178d71c68e9078409a80016e1f9727ed0d5922c93e821dcc80000000000000000000000000000000007bfb606c005c7da6b4ce2d974f9fdb2e3710c8f51f18257ced7663cc341ff81fe2e46308a2b62b13408965949a6f08800000000000000000000000000000000003fbd951e860e3a4724b667427fd9916ca4ba511a0dcac7b1125b14d8a4f4da82ddc0b0edab8ea50e911b0fcb5c200a000000000000000000000000000000000b43195a5f0263307e85408ae4eb046e06ddb1295a490ac4e0e654324de53d0dd023b8cc159d86b861dfcfdf7ebeee4a505655d72f1128ac0204539f0d823f076cb3a57a7e74e896b5019c9161d6486a000000000000000000000000000000000743bed2c17bea1ebddf750da504fe120f457cd3b1754c9413757cc48f7aef07eb4fa0572cb853cb72d68427e875456000000000000000000000000000000000102ddfe3dee27186a9484f74b3cb3aa366a79f0d2e36063af6e484f6a459e9168d7a4a6969bb720ec694a52db7ab34b40000000000000000000000000000000009bdf5b86aba4845adf9187ccf9c74b1fcabaa05764e41fcce4b38356b4a0ace8e7b16abfc7f7b96b785ad47fbf8e90f000000000000000000000000000000001934fa903b71d234c4341b2f49f8177334142e7c401553dad38e66a2c157fcdf7637165058955b7798a59051846dfb8cc4c861cde3f445e3a78d1498d98b2b947056cf578652e19be88da4a786af196f000000000000000000000000000000000ddde953f59b8591a83b0cdfce780ec23d052037c26d60cef36522d0f984f907315d7b41c8be9a9632f2b88e0ce950ce000000000000000000000000000000000b8d7bdd94a994901a434e6ea5d03ea45dcdb859e560833d8ea0bd9d20c7db9c16b2427eac27d8f1eb640b7d28a530fe0000000000000000000000000000000017b5b3a3097a74d9c1f1b23783723235b6148023b6b060234dd9e2f6fd05e38668167136c999d91249963e224f9bbcbd00000000000000000000000000000000133da0c217c31ca052800315aa8a3b934fc1f179e6247801904bcea1e28dec0b65632ab2690bcca3606bb1461aeb147b99762c5189cf154e24238e4b157caa1d8759002f69b289cfbf3f24f5dabf20bb0000000000000000000000000000000012778a6fe79b1f2b768432df036543cade95504bb7735ff547969faaa8db84e3588046a074838c9a551a4fb48f4a66140000000000000000000000000000000013288a3413d7e7edebd118463d5eea9f9ae2e10f51965480f9b5c244b05775d04079a1dc75ba0885aaa9e2e4bae1ac750000000000000000000000000000000005b766ad112b8d69f1a28079688942ea146f8f31616611909f539a57c58ec5e857da9fce415d683c1c6dcb5e74da9d17000000000000000000000000000000000907e5c3c83d3f12a68d6bf812e310f5a04f1417094301fab7d4f41007b9d01fc1bfbf739dceddef756417367ed5b1d0298b5f6b43074b8f0807086b03f5028709209310474c35c7ee232eec8579147c00000000000000000000000000000000090be6ce5ed09e45a6fd9ea3a9223fe43a835141c1c29d6b386e085846869f9c5798b80c3bddec8bc15171906dd417dc0000000000000000000000000000000019bdf67eb16f2708ca55fd20af8deca66e2ae270b2f2f9736fcf49dbdf7cee034cc956f6fb799f0e87c12f283a11448e00000000000000000000000000000000124a69c723cbd366d52919a72dfceb7e4cd9ca5b5cef1784bfad3f125b11d810328ea1c849602536af500261aa684f5b000000000000000000000000000000000bbf05318ffd81495efa4f4c271c8b1c669041a6446501788f49b8739a934f09de9d976fe7300b0ae861be567d35c992177bfb0218ecd8cdbc6dd9484e74e41be6971ec2911bacc8b53b9b4b8c70e5730000000000000000000000000000000010833a3e7329ad40c1a8cef296b015f6ac6542c612038ce00f13a99f673783cb7eeb14796485c168d21cc169065d051c000000000000000000000000000000000d3b1416b23453b893c92a6c7850cdc0e4a395459140391b1dce11055da10fb68f318c5561e1c12d991a28f3f544a5230000000000000000000000000000000014721dc58eada80f2d0574fb4e2c1c94c45fbd90c2d2fd666fd618a96f4736a5ecf34cab34fcbdcb19b6cf7b44098922000000000000000000000000000000001905d34029bf84617a956d1edae090853dc1b622f560c5289251447ab6bcea5700bdd80d6ffb2dc12fdf3b0267e74543cac52219796226385aebf9e85f5f179362d4149c33582a97b7d2aeb05a8e6a99000000000000000000000000000000000b4d380f4f4eb976e6121b933be8418c536f85994491b0b93695d50473615e41547ead326bab795d4d59524a61d607cb00000000000000000000000000000000104b7f4058c9b355d38908d715c311a53169b42d2434de0876f1c4ffce1c39603c4876b33fe3076528be15fe42849d3e0000000000000000000000000000000017e2fd647e7739366ebb606e8a326daa5c03cd2b726cc4cec7747cb3468419f1907126d7cba98bbbc659478ce3afee7700000000000000000000000000000000183be0a976dbb3b5385b544c194e111729c7a8d5aa98eba3fe1c0a5b69b5fe6e5d0164e96398cbc61eba5b86d91b3c94e03afb2efea85fcd035cb4ba09977b2e1c84a0d98edf88e9f8d2c4f116d0f50300000000000000000000000000000000023bc7eab817fcb9982cdac242cb6cc0ee1779bcefaecf144dbe57d5ae2b2ebfe9088f39f416a56de4b4dc04d4bbce7a000000000000000000000000000000001318e728c271746905788dd8f5ab22a3a10edce3fa063438e54ebadba22c29e461b2ed78a95a8f26a65b47022291b8df0000000000000000000000000000000010aab000b9c5de56623f18861b343ffa80da5ed4ae0d7767b7ed791bf3dd507fe7286447b6a07ea0fa12c19f2e4d8e8d000000000000000000000000000000000770e2909b5795a08d98dc66389655b1718e70b93c5bc6d805c3945cb5fc0092a5b390e6497b550988c28c58b6e016a3804dec43760dab29c161b8f4bddc52379a17f3168f684267cfbbc3505e32d5f1000000000000000000000000000000001259a4e36f5bce7d5f97184948d57fccd458cf7f2ae0c9e174f537bece01d744fef544447959cb73a678fe2c378ce3c900000000000000000000000000000000131aa575b2b94232e06879fa1f6f145a0bf5dd12456b698f731a72bc587e6def5054b3b2afb6dbbfc34fa5249dc673860000000000000000000000000000000011d64b923596c316b097a0752043efad8b61fbe068c58bec7a6766d9bc90ed965b3419dde3b96679426f72184adb8931000000000000000000000000000000001653af784cbad5a804e3f72716bb51e0c733014d587952c47395f953828566cbd7da811a3da1d48681998d569db00a7bed2d3daf616df3f0061f58c925e9dfbbf6e9cbfd4b0b3896a596919fb3d243db00000000000000000000000000000000077a9ab830f7683b7fb46676df09f72d773b65286c5f5ea86623306e5de51e63851c18d192c4c3b20af582bb7f017ff70000000000000000000000000000000016dc185f4158e249939541d35ae8230fd749988b9174c40c40b8c932aec625a7e94beaef9a07f492445d4675a01b7453000000000000000000000000000000000c107a895bfb45d33136db6251c76dc0461a235fa5d1ba7a5d216bfebe15691261b46c9816315c146becc328acb6b8c7000000000000000000000000000000001151cba240678efe61e3a36e169e314b3610e9d4df6650507f53ccf635d8f1277a80d86baa85a2d4c7e2af73934a7299e16797ed90581fd8c3cef1f30abaed10997f13461374ea649b29101959fd506400000000000000000000000000000000090a1ee6c611980e0421b72a122cb39257dc38d1e74ee41b809ad76e440fe307cf45e79afddd8d40b94382d48cdd4c450000000000000000000000000000000010f2e6e610eec7b7c2b95c1510af1af342ac19fd3b01dddf81b8961ead2cc57a8eca36c2f5747238eded5914e484c52e000000000000000000000000000000000acce0789cfff975b09d687ef79535c536f3b799157d3ff731915ea5b323ddd9f6f4750dc8e00a879d4e516bce8cb3e40000000000000000000000000000000008d8203dd13aee7363f6b10a9e1ae9b713bbc8b8fb2c56f05fa71e8d69ea571384d150e8fd01e855b1b0054fe7967a052f9f29432638c033ca84422b12ca80ac4ae85fa30ff56c913c5737aeb2c84d04000000000000000000000000000000000b332430c518d7dcd120b346440e5b6b48900b5c3656d84840823a96e5bf002816d583a989898cad9e09ba978ebc58a40000000000000000000000000000000004197b43877b833de7f69cc1a43ad8d6d3544cd10d42336d4b19a187f31337a37b10cbf48e72b77e4d8e1a1da68e5e4c0000000000000000000000000000000008887d5dd08f45034584f40a2a68254baf2104f9d6a4c2637ef79c5ff2503c246f7adc36559758a0c07533b66c3637d40000000000000000000000000000000009343819dec1d4569683de4596621c19785d5ed14ba13e57d94b1b1a108aa62cc8c55c58dfa18c06883ce50cc1364b95e6f1e5df7ff90c4a4fb9a071c0caf3a3997569538ab9837ed41d9d0a8d7305370000000000000000000000000000000003fc7f9a0804e7f1664f8cd3ca67b70ba128529a611c24214fd09674072a6b8d652ccd37bf5d4611424688213a41cb3100000000000000000000000000000000137a869cd7bde696035bd9353662e0d37d2aa0731ae55357df3bc43536b9210f360324cbb3670362cf9ef607b1919bca00000000000000000000000000000000045d9d39c04e257fcd912c54e57c86d2d4304e6a7cb95a83d2bff07964d0a5dd8b4e42bdb91a8b245e512395e6749f1f00000000000000000000000000000000120e5e4b04b8a744757812fc331e7c98b35624faa1cbabfc1470e4c0804248bfb0c53a484107a677a7d3f0d2b533e7530cf3283195707c30880e50ff5ef605b561c3c3c354fbe8108f93b36f212f9ef5", "Expected": "0000000000000000000000000000000002bed414afe9c7a630441e7b163280be10e502cf877e94b6521d14baca0087c5dcdfa39ff4a51c8376d99855e1e6f36a000000000000000000000000000000000dcd54727a7729408e682c6e213005687ed51fa7935c522312793fc58cdb273eec9c61cd8b056a26619fc8dc006b066800000000000000000000000000000000137286f4086763e6ccd5ee82d3bda712b26814a17c6a71006a3e6dbdd919e469bd0e744bcdb2074679e78a1e7d56ee7d0000000000000000000000000000000012d75de1310199c0e556d61d6c0395b406afba0f13bfb37486c05d66b446809e8b1a024e8fd2c55f1b82cf2aed99a5e1", "Name": "matter_g2_multiexp_70", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008b83142b22f6d6496cad0dea23c71355e7c5d98659580b5ee6e97eaccb9fbe523f7e3b925abbca3a38f67426f3fb35f00000000000000000000000000000000035f655a1b2d22ea21cf0081e78d7140bad08c4e66dd45230a113ff3b7a77e39f0f1a72991f85e2b00ff58b27d5cb54900000000000000000000000000000000105d04e38243ef1ad2f734a3c97e91506c5a7c5d95e9b8771b7fded8908f1be933a81a5769044b633d501c0df7b5d7fd000000000000000000000000000000000e670ae4af94d0df34a7f2d7cfbfcefa6eebcf2a6b2dc5b82068b023fe02ce8a279e1bb96d905ad4f2ffbd8214e47d702063b046a71c2674e35466657a85d8e02253b42517b033619e31a536659172120000000000000000000000000000000009051f1e636309016c5433cc7eb019c7dbb75b3a4a5b27f6927de08fdd9577e8eb9e12919157ed35bfd6607be7fc4de5000000000000000000000000000000001953b7a33695ede6d0792eba85567aa5052b8a58c1bdc94ee82b5001893c6b996d3e8f7af8b8effd6cf50656d8b85554000000000000000000000000000000000a2f769f00679b610bbe212c2f8045e7579a96dc6bff80899eb7715aabb1afe79421ad5000f2c7b85d4e0904e335ddfa000000000000000000000000000000000ec962a3d00fac14d05774adc49bbabaf46ae78325083c0020587fb85eb234387aaf6506f503fa988df8e9ecafb4a59992fa325cd07502c6576dfb93ee952fedb304022656597bf3bb03a2bbc471b32a0000000000000000000000000000000006823056a4da801cae430fb9e3a8663fc8f46bb6c180b743b7f9c7c7e3287f3feb1aad4be0e98409c74ff58004f8732e0000000000000000000000000000000015f7a3f692d55252fa5af5ec952f581b796d54089f13971fce2ef9062173664816dd9f37174294ed78681d8c8c5a9cd800000000000000000000000000000000154743c76f7de590a31cb96d46a0ec0fa88008b7d6684bd8f6fdaec70722afff7b6e88c1f0fb048714fb1072d30780e60000000000000000000000000000000006f3191946d0e7c1307a1a0d1ea9a26db195ec98ad88f9b8f08a03a3d48bbff1fa53ffc920f7db5ebd4c65911392bb834484e688799c3f0a3bbe00cec7322fba6245570685cd7df0d744473b72f03df8000000000000000000000000000000000355018079cd02dfcca15fbd2934a8e47c5ee89e679663488499ddd4abdaba7679fb1c9d2102317cf2798c47aff1ceec000000000000000000000000000000000c417d489a224fbba9999300eb65a23749194bf5302fdfaa33ff7daeb8d896e387e56600233038d5c5eb59f644a99b6a000000000000000000000000000000000f5a62e9d711293d4373bec1bc2637802938eb789c828939e6c42f10062ec171ac6110261165bd179206d649713f6fe3000000000000000000000000000000000b11f9fd0ef8dcac2e21ef09846ffe9f5a624ec246e31393b39082a47354fc9523dbd247f0059b6cc740d7a387b137f0fae2ef61a024e4d8c4ae277f6b1d834193df655ffb315da67afa4ee4ddcb7fbd000000000000000000000000000000000fbb5521cdb9c3a69d58e5c9cd7e4a50bf5469bda2603f5119f3209669eb3e374d700f851b0c7ac5ee3cc9de79e6a7ec00000000000000000000000000000000131ccc37581e64f6f9fdf675b9b63ceb67d9d5844bf512166f39b5bb09d8e031437c06b0ca01caae7ad6d8c9bbb9fd67000000000000000000000000000000000531cb0557fa18ef054dbff2e7e994f1af08aaea7557602a26fd6ff539ab3c0a73f1fe841177012dabed4a1223ffb5a7000000000000000000000000000000000a180e7a345d2b635be92888934608e8b6c17384c48c560f4cb9809ff995f8e70d83cd4cf0e96c458fc414e1275d2a993168a1007abd42bc398e317484149f2fa61174243fd1748deec6cc75e7c720a200000000000000000000000000000000125c83184f63dee35ffd2c0c7dad9010cd6a9735675099f24b465554ab3db727ee76b5b7ea603ead78795d33e37689a400000000000000000000000000000000141bdf7e270dcd356993327cdb5dabe38a5c5a9b53470d9a4aafc041c46fe8bc841089e337469bddab5d4f7fd3d6ccbd000000000000000000000000000000000f9613f6d05f38e3073f14d0c2557101a4864a7d6d0b5a2b931d0613f020adb99a1ab2037a39fea6e99fcfb47929827a00000000000000000000000000000000192d812e05a17d22c60b78c53fabcc55a0eef3656f8e84132faf16686ee18ab4d35767db9a384d42f392c40c7b0fe1c0f1525bba87baee35023d0976b4a2d87524ba74158f000e5501c6d06aed04adda000000000000000000000000000000000b6e1960e82586de19ffcf29a8c5f16cf2fcf5286bf42febef832767919abddc655a0d1bfa240cac8fdfaed5a1e8f389000000000000000000000000000000000fc1598454caf04414f1930f711d762f0d72f5cdc7a4053c92b916c742b00dd0f107aee111976c1b1218c4577deeb006000000000000000000000000000000000455d6e9e9bb848e0868c9d725edca1f50b279d0acef8c597927eda72763e3702f46b216919ac36b080b4865249fd961000000000000000000000000000000000174463cc7804796b4a6d8ff28d2e8cfd8361b2e38f368de30166cf3c20c474ea0a1e8d94749fc3e6468924a7d1369e62d3d7c014416f33724acaa46412348d350f93d334588d39c77dc0b8ffcb4cb1d00000000000000000000000000000000144e4b615ddb871bae85484c308423adceb5de387d0c7ffffdd2211b4ea28788eba9bfae96ffc46781e6d6343e2f501b000000000000000000000000000000000046e39cf43fd707ddc4b7ce9a8a22a2aa1e55aa63cae1eb23082f7b4b5dce49f32d2ff887b5108b40f98062c02d5613000000000000000000000000000000000b75b5460db2baca86528569b47209b5ac24930e2545cc6aa08c401a87ef2c4e233de537e5a857e533d0ba0981b24d7c000000000000000000000000000000000018f53b83072fe7daab226c831a89da63a0930ea86e301c97e639d0ee1609e298e2789d1a347bdb4afcd355fffd16d053bfbb1670b7045b6df689871d5d012dc93e8be65faa4a98a51db8501a4b7677000000000000000000000000000000000185b296e9c7209a9abcc3194b46be9a545666527ec9b0634a3e3be579447cb52330174c19e40e1667124552392a7a0c00000000000000000000000000000000158a053c788e5b914fcdcf1aebb4e21cc8bbfbcc20c4d692256b2ae48149f6644e1578f98d58b3e73d9768d0e7df643b000000000000000000000000000000001318ff4150bebd8fa612f4e84f89151d5c56c272969bc1f31a3c1fcbd8ded0e298914e98e1ca48248e9023cd12db0fd300000000000000000000000000000000076555254f382707fdb7419772a4978808a7409f59d1dbb8c9e648372e19c44573f5ce1888a2b570a83afc20e698ee44f944ee8d294d189226a6cff17456e2201d17d4dfcb78f58f8501870377a6e431000000000000000000000000000000000f4395e3f2e301ee3e18df3c23cdd142716c7fcfc23caed924f0561795948b0bfbed948a6f7c415ca615ee0ba4d5145c00000000000000000000000000000000176ad308c7fe8c3a1aa350fa82b8f8ec638f77bc703afe1042a6da22e5385cd8473ad789247f205214c9980532b12c7100000000000000000000000000000000092b0ec86c511992c66f320ad46c9d6d7c82df118a9ab2ce1f2c5611ff4e5cdc9193a39c3fc95f18ddf96e139688b00f000000000000000000000000000000000b4f671e334b7f22bd8d89d8c4eb8a52b04bbd4dd1259cc9caa1872093736680618930f3a469b3af4a00cb6e44b573f27de53613b7a31583ccb214726482b770029c0ed42f9528fa74da7d2d1dd915e100000000000000000000000000000000123b64561ebfe085238220eb1428b3a203acb01846d1e4428f3759db6cff4ed3c1b9d436706f28b77e3b92e2e39ecb41000000000000000000000000000000000ccdf1973693e4b43b6133563986f6c96e2b924895c813f8acdd0f39585e4ee95ef26c0d9d51d6ef88bb62305e51594d000000000000000000000000000000000f51693bd44b12188131ca84801bfee0ca853640c0a8d5b20123c97b369c98299ac04beeb27d75946cc6f45f8a07b5fd000000000000000000000000000000000804c6597810d2c75de94484873a67eae258fcc9577bafa778e13d4814ce099a5684b1cc94e0df5a59acc7b19328fb8bb0a9750cdfe0910c544668bc9b11ecdedf1b757ff69b61fcc838c502c2911bbc0000000000000000000000000000000009b02eea05c78a24adfb0187defb6810116e21894d8782605c1d590f8bdc10723bf71a1e5e5004b181504ac2deb142cb0000000000000000000000000000000015882389195128e20e50ec4f8d278e8b8791e362341be93c475064d640e1f8bb1c92a6c777d666f8644d471409bb9aa90000000000000000000000000000000000d89295f845f989e0fbc6e86e97400b08e39b2968fe6c9a141d1e92ec9c838a3d8e1ada5e44bb08189a5d514ebfc2f5000000000000000000000000000000000dea05d8e6ab50b8f8dd9632337948a60568724d5a03c7914e4a03e2af572dd8153effef1a7d5c2cb27765ef2c17bc5b4aadecb1111ff43894123648eea9e57685dcb7a25553233a374479c24f2f8899000000000000000000000000000000000bacd14447ede6af0e92e19b54c4f5b6ebfb94207efec3e9f385a4c84a7d670514ecbc28ab686b383e239ae7f9bd673d000000000000000000000000000000001698bc92d146049174b843dac8c5dadcee12d1d503b2d0e46ee68139dd43d3aa797fd5bd06e2b214cc9ae3647c98394a0000000000000000000000000000000018d20cf6c84446cadfa1a26192a04e16d2b2a053705a89abc51bfbfa35c2b03cd58021ad95a35364ae1e2da5d233208300000000000000000000000000000000113268e360006294fa0203ce58cbfd05d05fb625e1f9474c96c89c0ec1ea80fe834030592c2f1c182ef8a3d5c32caf71adde66cf749daf69a30f41ca00d251f7f1e93b0e7f916a1ba6b994d946b12ca0000000000000000000000000000000001727b6bfa9c601fe84a65c54f556887c4538cb5383a288156fec87420ae7f15da395886e1ac0e10b8fbbae8bf040f4ba0000000000000000000000000000000012127cdf02ada71f28ed036a417971b87fe443b8c65b7739795dc7067082cbc9f06f7bf10c709969281cd072490c06fb00000000000000000000000000000000134f1fa1d277d01e2811c118cf10e2de6324e2ba14efcf717a03c1a10dca0862ebde0f6328839da63d7d85f573e8501f000000000000000000000000000000000d20a036b715d18ac9e2dbe009dd0063a4b13b3ec6fd060a64c4ad2b98e05e069060179530410d154caa575d504c63b7b2f9b44c73a1a6dfba6462e1202166b63727f45dc3b8b3b73b5d06459a1beec20000000000000000000000000000000000bd5375e7f98d3972b93420a39fd6c31da86d0d9349ac3774bbef15c2240437cc0761b2f1245e805d2538cbca6f778600000000000000000000000000000000100232139641c8cd5bdaa75b77e1e1c8e33b3f9554e2ae00ec6315b82cc00a6a70d576d744e68938a299ee2b451558250000000000000000000000000000000004224691faacb007bde3e37db6c7486aa5d3b4259a24c8b7653238e7522604ef4ffc1eb3cecf719a1b7f52ff00c34399000000000000000000000000000000001156ceaccfe0396374c6dec5adb39f14b6f08a32b88ef7499756f5cc324a9f1553bf5dc106a97469f2c49be5d563e1100cdc89e668f7cbd53a2ef6597a48b93d7d9a78950d4f821f3935edf72649e0000000000000000000000000000000000010a549108e77f0ddeacdc795517ccdcb357f909264457cab22fac2b982d10064756d66d0e48af02a59f58eeb1e8ba14b000000000000000000000000000000000c68703ef1c1e93c78faebc5f7ccc69e39046fe8af92e12469e9fd6baee62a2e8cc06fbbb3def81ae5cc57f488fd9c9100000000000000000000000000000000064ffb6aeeed432629242c3843f8cbea5bf7fe78585763926c5c45dc3cb4d1c79b3715506d7cda18c531ef890b22a1f7000000000000000000000000000000000e0eeb69f28a552cc6563f5fdc9919423c4358a2b70ccd56b048c22111454f67107513cda2a5aa0efd2af25dc74a1c47e23b377ed80bc90a4645df09e825509eebf57f59d7a2aa1b9121ace80926ccf7", "Expected": "000000000000000000000000000000000b1913c672760f98fc6d4e96ad1ef200f99add6f233b17291036e187ac6692ab0a29a4083dcf86a532dd06efb3d9b8c6000000000000000000000000000000000323b703abed59a9824f34d97851546a5e78441accea4e3a933b9270f92a9dd1aa056858ebd1739659018a0ca13b96e0000000000000000000000000000000001603cb3ed75c09ae5da6b94eea6017dac0c40b17d9aa8b65b78f2ba17de051bf3f21109d9afb214d260a09391f5526c10000000000000000000000000000000019f3bcdb8f16d9a2bd11e3f9491266780aa9110f447e19f12f7a2d62dc4f2c7b5fa18e13792007f5f361e20656c8ffdb", "Name": "matter_g2_multiexp_71", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b7d06c16c77a57b5ed74d829ad6acd665e73d20f1d9285ebba67b60c0d1571e1b02cabe5dea44499ce6d40a83288aac0000000000000000000000000000000007e6ae768ee3d149c7130022f9883ed51e4fcf68c91327ac1fe85aec8083aa61a37e9afc25d3352e144aaf888f264ab20000000000000000000000000000000016f2423478e0388e8495a898c23d63a0929a2ee7cf848034e4c1adad3460c7070caf47631eb930678d3c85aaba044dae000000000000000000000000000000001587e63cdf50d6e0b6b3d7652ad0a0a2497e70259d73432831781641d3a76db4ac7cff1bef165fd8ba29200d7320e43475888762fd1de395fa80b6d8a751f280eca568de2947e953feac343fd6bd592d000000000000000000000000000000001181bebe3256dd6ed754b8a1d77ac07e9a341789b3f4a4988599c7c60a36f1e95d3e3cec52c54c0f0abe312ac358c28700000000000000000000000000000000189d224b2904bd45cd1e8fa72570a1e35c94680d03d30292892462664f9d7aca3cc45ecc0773e66a10248df28ba9a9a1000000000000000000000000000000000f654f4c8b02a891e14fccbd5a96228afaaf79ed8306c7c1267715bc934e5f2568ea06de2bcdc2a55ef708689d90108c000000000000000000000000000000000c0a413f16e1aab8b91a87e7027f067ffe7de65097da37d67f604a184c7e7a7af6fe59ced8c03fa32ab036862868b35018ce7941da132adec1eee8d81facdb5012a15ddfe0cd6751ebbf66ce6c495043000000000000000000000000000000000dc972d55b7e68f97191d988ae7be5f5301bce5c654b323d4c17bf6e070f7227c0789ee38af3ccc07b04f0793090c6130000000000000000000000000000000016288c405bb42b4e71d12fd0a798cfccc7d33aba0500f939f5fedbd0e071166169d3072befcc5549cc6963b6dacbef4100000000000000000000000000000000171ea4f6607d6efc875cd9cff203bc62eb83bdc05c07f702143c23ab2770f50f42738f748e6bb3bb5d6f51f40fea1d910000000000000000000000000000000000fb729cc9716bf2e9e30a598ee7c4281163b287422ab66b414da85b0b960102991c24cd023791e4241bda5b0f6ddd3424a0497c642dce3937d883ee25b0ea577c729366c7d67e2e5ff1ccde3b19a5dc0000000000000000000000000000000005720bcbc598c4eda697406dbb390c2aaf4bc22c794b4b664e9b85b7c2079b90f7678e69496a4a5cd3b46580b90a7a30000000000000000000000000000000001159788c3edf619cc5e6f77c4aeb4860764d46afac4cdce54cade63155040c631eed65c2fa11b9cdff14847950cddc2e000000000000000000000000000000000d61bf02587e2c61544ae8a98b4c742c26a3d6ca49c6ae1b19a9d69c7f8eca43cefd555c973145566f8332902217cec3000000000000000000000000000000000cc0da96623432a2c170f07a3aad2844c1c2aab9d1bb5d2183928c818e681c66cb3767be372be4ae65fa40bf5483258ce4e0ad0d478ccf5381470a3fc9b882639dde4a0147c7c82e50bb93431b07a1350000000000000000000000000000000016efffb5d4ecbd01567c1e6099c0f06644d4312c599579b4cb780fccc8a425f3d1263a5f0c957dda4508202a354162f600000000000000000000000000000000115686a37624ffa8272ec7dedb7a632ac568245918ed91be6c9116e0fde290c26b5291e5f57ba6a779750685b0f126ba000000000000000000000000000000001852662b92fb49b2f0359255db8a7a2d20bd37705b7994cef1eb8e318aed70fc37bb7af9fc0c32ab3efa8c0afad640570000000000000000000000000000000017a691c08724ccf0e668f2f4eeda692e9ac21385fea243dc62c37ca73421eaf51c3a60771da3fb3e3cb578de37d2d45d38573db9346a3c8de41af54048cc51a0edcb86f36372859d0d794f7560c8525b0000000000000000000000000000000006fe4276e8f2e23127853eb929ee4e0c6ec4a190d46ac222dceb995c2e1d8fc9f822806a877e6cf87cf579cb2862c25c00000000000000000000000000000000044dc671bcd516cf03ad98ccc55266688856a4e4e5a59d6a6bb93e9ca77c596b5ecd2db6f3cc6377a0086c53ceed5487000000000000000000000000000000000c3ca83688d20519423b2b5547afcccbfaaa088a90523272c7cdc9a9b0397340350f2a5ced2a8153d69c81cd79732bce00000000000000000000000000000000069916c468f22bad174522d7fb94b4b7d2a664743b4689daa5423f470014152387a29425642b50f9e50fb679ddafdafa02257ed12262d00e78bde574a9ebd2664484a446c03fe8cbb855bf92e56bc1630000000000000000000000000000000001fd452b8685b0806545e09783947551bc5f6446c9d15d079a8968a448a6fd6f8b7e91974b71a4b2c50954be299c4885000000000000000000000000000000000f28bdab0b0fd3e05d08ee2c51f1bc0d30380e3a7aa18d6e04b47018d6a8d2b35a8f06df3866ccb95ffbd9c5333ca94c00000000000000000000000000000000035f3aa1cff72df0bb10f1a6f8414aa2ad0289cd15f56d84061a7cc70562f1f12304c402c388e48dd3f34082aaf79eef00000000000000000000000000000000034730e3ad7a3373b97279a00dc7a053aadd088557e0da61b9aa132c5b402fd9aef73cc45dc1cb7f2076cb2ff27ae2fc76b9d21a3da0359a377c11a6d0a18bce7ea81d4128dc1e7618e6c35b9149d5c80000000000000000000000000000000009c91d800cb1d52501520b3625dd4c20173684bad8742c7ac4b35c0ce028556b6529de5cb7541e3c146b13f58ccae57800000000000000000000000000000000124259d345bf2f8c16215be4b6b7922f4e2d6b32f91c4b1c4f1d4974918fa9e6fcf10e46f0c0b55e2a7210d1a5336eed00000000000000000000000000000000072e6231244ed14aa0f5de06e2f953371995a567684b00e459113380c1434a8faaab8b28a0280336ae35bf1f90f1d4d10000000000000000000000000000000010289a63e0e5f1f35b7af22137e117a85df27874ba15df39b7c26801c169667a3afe9a14663d7ac0c2956f4eb70cf11fc9cd895d5d1ae0ae704e240c10d8ed4a01b319598d7885f7c3fffcd9b491f5fd000000000000000000000000000000000d0f22a9bcda47ffcd034618c15daebad8160f9ab6b3148f1cacb32e713df2ef19f706f14131f8ab1181b7ef7598e3e4000000000000000000000000000000001680314cd79fec583c8bc0842e1750b1318f94aa7700c6662aabd4c592ca61ad51a6876b686ac3fe3f508cb40192c31c000000000000000000000000000000000a172bd8e49637fd9eb611b590c68bda707931e403db35cde1c10bb74c389ed725aab54dcd7048285352c56c8bc5fd920000000000000000000000000000000012589683ff3f85ecb006c5c435ca7bfd9d5a6fd06eb625bcbcb18577cdef610d912e783f3986c965710269b1ff79ba972467604875028997efdf5139180a8d530a1e9f18c62ddac7753cc370bf25254b0000000000000000000000000000000009720c2b3a0658a4aba8e76e196a558bd155ff550b3e41bb5b43e7c5946bad803b1de64e342956a11627e7f24f69fef7000000000000000000000000000000000decf2262e8369d6a2b1ce07fdd257abe1c7610084ae2f347640c0cdb98c7cfa732dc609c18b7b6a51b47ebe4b07a586000000000000000000000000000000000e8a0158702ff6d6c3a7ed9fbc774bc329681130840d86ca3f26cf6642cb49e5f14ad95fff1c94151457b1d5a142bb5900000000000000000000000000000000035ae66137629e95539e09ee99b001d5b9a6ede79727d7deedcbeb5acf081cd05ad469ab06c265a5224fd5236db160b62f47637b64d28fb4facc31d5bed34b22e7b270431f54a689cd0fabd205e001ae000000000000000000000000000000000413d82d0b02ca706f0266051445c04f3ac594ad82e2f1fb4e8e0cf23a6c1087c29383238ad3677f170e99259e2fe93e00000000000000000000000000000000070af21f84895c0193f0b8174cb20b11f45c845a8d782b1f58182b149362e1368ba076ba702185fc54b5da94c3172f5500000000000000000000000000000000182e124ca29d66f9f6c370f6065f60928b6a8f445a74800d59209219add6cab0d1b79702c31d60e61cf56874a4eb6717000000000000000000000000000000000b94b733f76067a102cce9659292f31f3df2cf2770e3a83c1524536e29d0a84ea5c4883cb4e849830384dc7e157d8715474c3ac61d4fbece967fbd0599c9a92c3fe0e53899861f044308b0ea8df137880000000000000000000000000000000004b2feedd5badbbdff6fd0f33a4bee17b38cc8967fc72206246c349e1017ed0407fe08e0cd9208fa9e4e21eca4cfbc2a000000000000000000000000000000000df0d74d5cc17ea94457c0ee26ef24071700a0fd6bfc762e3ec69b8f1c096887f679e312f07cce8340686eb2716c9a96000000000000000000000000000000001878edbfff2efc5af64aa9a23589a52d63749b7ab2970f256874fe0cc15091c4511050b0a243d421dc6536f19b5977cb0000000000000000000000000000000015951da3b20494a266e4d014d0ec70fef4586c8656baf536a0ea9a48dfa041624e8154989a2fb106189217ca979ddbe8eaf9da65e0e1752a982601e9a070a7cc77d5007eb641fffbb78d2a1b02dcffec000000000000000000000000000000000657fdf40c829719db134acd6c2a9ff904681b1869f28512cbe2a64d93e5b62114a73bdc5260ad9a1f24a3ff191b7a3e0000000000000000000000000000000004e77bf63eb9c4741028dffd0591b4f525d533b455d35e51cd86c7884d63419a162b145752bde188d2a622251c087f870000000000000000000000000000000016cf02af01fa6750b4d862f0cdd5a87a79da7c3fbedb0fa356ef2e7419e25b3a2bc8cbfa97463d463d0ab349efaa3f2b000000000000000000000000000000000ea4468fe6a85d36ae990d0ba959ae050756805c4c769c829de475a2990ef1c46de20d5b466543978faae0f6045023e85158bfe535fbc342e31f32ab4723c0d9fe95a2c64cc4e59bd41d13a08ac811780000000000000000000000000000000018d42a2df8ca475be6bdc468a82c313599239b974ec3d27e8b8c534aa4d6b85d4ee9aceb15c38b3bade2bb1706a2c2cc000000000000000000000000000000000124d5dc60527faf48f5e9574308f8a328b410de1cb49f2cc6f76b8a1f2707f2d1a94bcbca0a97bc38f24545a8013b250000000000000000000000000000000018b690b3d1e3b22946a91ace004e1d8f92eb5beb284eb05b52ac5ba003d7bc387540d33d088a02711522e3aef7f74f4300000000000000000000000000000000103080d8bb379d961da06bc4c148cb5b056ae115b3a0e33f0a8c99a7fb7b7ceda35d3902e0733156d354dd0240e4bcabd66f5a8f37a7c6a32088897abfaf5a98bd4722c411bf4b52f0f5b5648e89df29000000000000000000000000000000000f4d068354cb5b51e5a86163978386533f8f9b6e388c5e75f7d9ff5e1ab6d1637717d251f2b723b7d683e26a274d610c00000000000000000000000000000000001ec5a0d408c55f247d62ffef172ef26e45c41029f1d04e36f0dbb4fe8af414b0f7fe7ec0cfda66a2855b58592486fc0000000000000000000000000000000000cb1b68045076f457746621cd415d743701bf3ecae8d52dd5582c3e0bfb38e6cf2651a5ebdf521afb1ec5b8066444210000000000000000000000000000000010f5672f813470378fa806abdff90edeb0239b00d85ff23a3fc6798779f46d6b43071d66f7742897a4e53ebf6c7dae719acdd24190589ae7823a42e8b59598eca12bf13b97aa9a0eec17f5f79a01e8df000000000000000000000000000000001422fbaf1bc2908be5900968af61ffa7b3af46e7250e4663ff321f42e2db057bcfb2106c433a9eef8fe20f7138b71d280000000000000000000000000000000002176e68cdb0ada2d7baea437bec8754ea293d14afb85a811f7a5d740d645a53e511b5605445b110174ceb5e6720e736000000000000000000000000000000000a69e992b6f4f7eaad2682cf9ac2e58faee9b3341e852543c2aafbff390ae067a641b2b5693319618fde413fdc64d6c10000000000000000000000000000000009440317af8f5c753b5de4648b06212256a39b7fb03678f1913b0a3d402a50e74e2da5d29c211cdf0b292c132759c36d0291be87a213b0a24c92df5ce42381ca378dc4b9aeb4cb9b6918263bea827bf8", "Expected": "000000000000000000000000000000000fa31d16d9625200c13a415fd61b7552646c62fb8db307e92c1ac3d2acc92336765a1db42407ab0f774ccf01291b9ee800000000000000000000000000000000156a77678873dcbe4832b9fc7f516eabc1a10f4a6576cfb15765cdf999a771a6a6d41021897dd783e9beb2db722a6fa2000000000000000000000000000000000ee4599a6ca9642cb4cf38f5f2af23271cc8c5bc6e2cf6bad572b618bff9f8677837104b93ca8942843fd5db5c30dcdf00000000000000000000000000000000138986714a4053618e66a85835d105f4aa2ef38ad18e34b2ee7ae30a4282f7e543c80c94bd12c244506e7fcba25f4c1b", "Name": "matter_g2_multiexp_72", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000083c515ef8509b12ab85ad7d0a816d986bcdefc14778efcb3bf7c2ab61991849f279ae6a9f5342880837c0d0f4a4eba700000000000000000000000000000000020cf5196b5d567fc429cb9ced7b55e4925e18c914caae216a736886a8d886c4bdf6d704bbd0ceebdc1975ef530c665a000000000000000000000000000000000f3d0a217c224434604d63cef559eed3864d2da62ac00d49fab8c2c6e22c688496adc30c8d591e21bc0be404b62083c20000000000000000000000000000000003d0bf7f25bab0bf2c768b44e10a6022650f7d5b7d568d502b9d0b28209ee69b1d952ed848572d3e966e8771c20becc4b14c6a38cc998df3583228080ea10f215a6e6a4b02ddb6d43e8f459d494a1ec1000000000000000000000000000000000cc4c4b7eb7e358d4133b65e635fc13b8a92229706a6dc5867171a60a99a8e343045a794c368f1133ae6cd2788c3a7db0000000000000000000000000000000019508aa39fda9c3efced287d2571db97045f8b7b0c7a9c9d51796aa8017fc0e5abb8fc994700dd5c9f755edb518e096600000000000000000000000000000000049f68b0ac142715cfb385161ee70e453f0e24e2e93f3f96c3d69447f3a28b180fe76989427b2e392c7ff939011e04ab0000000000000000000000000000000004903c0f8e0757dfd3f5edb4f54a0e292df15ff70757df7b0b04c99f590a3dd13c6ce7bbabf3e14daf9f3ec60e2379aafee8614394c8109338432ec72f2d9babba06f1e7b826b0f2558c3247c923b23500000000000000000000000000000000041128064ac768664f076116247e0f8a00adaaa824cd6fff33bf524d0c76e61203408ac13b294aa41f5c462cd42d3cec0000000000000000000000000000000005e150c27979ff1cbe307511816be900648957624caed1f08d88347061cd783179c615258fcf3619bc4bfa53d2513c610000000000000000000000000000000009d2b3d97d29386b93d7af014ea8f1cfe2c1db5a9aa0c17e8430b0fcde974a4e7b8b42ef041e9a7b1a8aecb97cefb52e000000000000000000000000000000000d86096ebd88b2cdaf5cda1e9ca6b7f12ed5def629354b0570eb084bc7139cf20bb8ebe4438f87937b8b554e2201344c28728d06cd90050e44a827b44f14ea35e83c9b58ce4c3a7a45aed6f31c94fb960000000000000000000000000000000018d677cd67e96b10b671d2ed9234d7708042ddfe6fb804d2e9371a80ad167004f9d6b92d26b3d3af34ab7caa0e03964e000000000000000000000000000000000e34a6c85187d328eb33c2d5b2ca96b5210d47a779ab810dcc380dcb7e6b3c334ac8fccd7354aa9108136e4f6dd4ea0a0000000000000000000000000000000000ab8f7274ee3fce1511c58661625c766ffb0ac68bdb835a948b09b7510bb573d49000000e3d3cea772bd71d79681e1800000000000000000000000000000000135ca42f2103905748a1c416d82170f7d24b49ff3f859d6cb7493cf89bbae0217529a9edc835be1f9890ce105877af630fda665c40d1da93b1f132070e0b7c8c2c0ea0e66993b5a3d7419a33d118d25f0000000000000000000000000000000007884edaacca499491580c8c7194c0d60ac6eba95f7a81f63742451c8ed21a223ca545d5cc1e648b9d2dd05016b4fea20000000000000000000000000000000014c78d5d1a93760096bf6da73bb41631e94d6a1b251ed0be7bda93e4c50568420bd4d49e4a46e5be4bb204cdb6b0ad5000000000000000000000000000000000128a860c23a183c5bdd18b4a1853cb53475f1a893420bdf3271cc4a65a827eba6b92e1f9e8ac0d10c73edec5160c640b000000000000000000000000000000000ac14b2170042ee6561c34f77fca40e1bd2d40d01798417dd954905135ed9b7772e5689e6d4e543d44a4563da8c3ca40c14f014117a74f21e0b698a257ae8e3d6091ba76bff7912abb6bd94d41886d0500000000000000000000000000000000144df2e76821c19167f60630f50c939b66867a82c2a5f807e943676c876aeaa2aef2126bef7fc431f0c7b39e648542fe0000000000000000000000000000000005e463627bb2d22c25520c27c05cdc75e1f2ee3b91e8088399ee42ad13ca217284596e5404b4370995f71fdbf1c1c7860000000000000000000000000000000012323010d6aba1bc6b1d6e7f7e8c7bbc0838564b279d5ae6279f7f7d3cb5d96273e27e7096e9a8540463ad16deb3780e0000000000000000000000000000000019102ac6bb33bd1c5a158a584ce32308b6ee5679dd6d2acdcfa4b9c54674fecad7489d1e39c05b1ded88e4ea93620724d81a1239ad2c945f1c560fd1674ac7e87d49aa41a1f4a5bfffeab1147c0ef7c6000000000000000000000000000000000faf210330693663c8a1d1fef78e211ed2542f7ffeddca3e19be3ba77ef211da1b8bb5abcfc96b692d74f8c7df40b0ce00000000000000000000000000000000134153a252fd8ec5d9aec08ba09a94c4416f95ff6f4ccce59bd400474c836af5bfd941f03384ca4bd5c56fbe81d96ea2000000000000000000000000000000000b4532ff1ceab2a3a177cb83a75c16a833a2ff28df447def351134ec4fcd608b2b75b1f8035ba7d40a737087f3e8c1c100000000000000000000000000000000127e3ed13384b69819b34ef8705fe9a66dd01b275f1f74c2c724420546b39c70cb7a8295a6c1ec4075ead4e3312b8b603a02689cfd2c353fc1b4d3913f5a43745fffe6a87a7c223ec3b25b321584a75c000000000000000000000000000000001351d0d5d531a63a5f56aaf1d7906b7ad2bfb4e9d823e2659bed4e05e7edc9179a7bbf13405ab5cf410b25c7d476c342000000000000000000000000000000000f0ec96128e058e8bfb6e0df1331887245dee87c4f9721fc7f1d20c20a2feea7a7078a4946803ac093477707598d59b70000000000000000000000000000000009399034e4aed13cbf197d8c4753285effa72fc53493ca316db11b39d5527b009aec6350d579f9dee22cd6d4cabd88ad000000000000000000000000000000000002f41ed0dcfa2437cad7b12a94501266d670ed6956196c438241aeb90474d17214eec5d5217090d28892d95f4e40055af95ab3fd062088ffbef6ed887fd39aa1d527fe7633b876187ae12e736fcf2f000000000000000000000000000000000ae208978a751f8921c6067ebab4190ac8d3608dbdf50222eec59460095b8ab2abadd97616c240edd0a9c53dd006e38c000000000000000000000000000000000905224b317a1e64d8af075b6db9de46ca4481458ad6bceaf726ba0f63e81e2a0322e79e70a5a82034abf00d47fccc300000000000000000000000000000000007173c3359f0c2e315d11d646a76e6f500c0922401e4bf9f4ccf2f0801a567fa653f287fdbfb878ba0d9ee12e25396ef000000000000000000000000000000000161d4cc71621e5df13d121c77105af195c2adff5fc6b656b0fc1dd6eb2518f474444d8bc526ae16387f23a4ab3f342f6541c6cf8217c2a95792900e8fc39581b177a57ca00162c57131ea4fb80a4c60000000000000000000000000000000000266af9991c393d3b55f9e0f22b0967d47dbc5b0c97947125e220c4bf9f4bc58d32ebc7bfb02b2e329c933ce41d0d8c00000000000000000000000000000000004cf5748aae8dbc1e4778dc85da575de2b6d9d346f5dc5ccbfd82513166384111f5e5f2f1c2f7ae367a22146d1fac027000000000000000000000000000000000095dbe68521b2cf51283a8cfea1f20eb7ae37e6e945c5f879ba4834d20918b74981f9e0eff4543a79ff4eb36d84a9c60000000000000000000000000000000007953cad14379ffd4309cef1ed6a2dbb73a93db0bd3a256753402e525bb62b10aaf22b662bb2c704865690af995e7d284b7c3f3c4ed10bced85f36fd6dac2646c65d3c810e6d2d116c38aa5e10b29c2d0000000000000000000000000000000010e99f318111baeb1b4611847fdaea7cbd5e3ae532af667ad2498fb2e97b1eee0297e2811c7ae854b882f616da7733fd000000000000000000000000000000000e56cea75b4c4e4c669a492a6723fd60e351a66dc5c34c46469dc36cb04d2c23cfd4aeaa23d0e9e83d5b78a1b77696ed0000000000000000000000000000000018f838d6a582a52a508cbd6bbbb9cf515e091deb7a640e141dea4018af6593c001dc43a8fe4819a7877d9ecf53d5752000000000000000000000000000000000119aaa2ebcdb6379f7ae972cb709990a3e8254f1025cef308281bf7057295e3099d1f3127f76bd2f9ce0a03ae0de8e8d7e33f394e96d17efa30d34f57eecc45d7b4ca150a31b8d0484578151d6e65c2b0000000000000000000000000000000008f837c478e874b857f1c939a26a02e13061d50728c10939ffcf5e862cb177993e204590699a28cabc7593056617d433000000000000000000000000000000000432d9e66dc78bb58ab98771e7e8b5fe51835f286b488e2df6c1991fd36c3c537f2ce30abf24f9d4fb13941189972e39000000000000000000000000000000000b202de3708984f44f7d05ccd9e574a2a93a285d5ca262017346580be273c58f13165437dc90d1d4103d3b9eaac536ce000000000000000000000000000000001873e1251d9ae9448de8e7ccb7ca59a21bcc0d07a2819d140c06ec33cbba559ba90647494a7ecdec8b609b58cf7995cbfde92a31e571ec03e509ac8a70ed5788869854eef0bf578efe6c5e6468315553000000000000000000000000000000000084e07b6576c73aaf43c0ef9c5666dc988ed93d1a106b71e4882fc0cfb5e710b91e5d5eff57327f5678f662f4a451d50000000000000000000000000000000008a29751f1653236a48adb5fbc59059c7137d36139574c6af97314bfbcc22f77a4c5162092762a26b5da7887b94f2da6000000000000000000000000000000000a4fd84c4d58cb9e18aeee180fb05f07c3e1d7ed8d09940182e9b4738744fa6faf600b6f720441e0ad6391a4d502ac040000000000000000000000000000000018b356be2aebca82c54988ab2a2ec58751ce7a815f3dd58a2218a638753d4734d38b74ca0e00bbc8681768f5d1a02b646f7de01ad0f7b4dcaee1123bb80a71d3bc1e63ca577a12b14ae2a11d8c0fde46000000000000000000000000000000000de0f22cf05620a5d4bdcf50ae179f23a9c089fd6eaeb14eca937d9e2480f1782a1c67df76e06191a9b87514daa8bbce000000000000000000000000000000001981cd1f260e7d96e55533b8e29867f37af507b4a58abd69e0ad6af2a55228ab1c82fc2de52deb7b7b7deae2fe621e10000000000000000000000000000000000d22a7a567ec8826391ee711768e612c403e3c16e20947ca5861185c24728b6c7e7756debb333e7acb53d86032d5748900000000000000000000000000000000016fad52e1e86b9e092955cefdf93a10f30db896fb519fd2ca12571d8dc8aa352cf4f8092e0e973d0b0c66df78433251e2c69d21d40813ee40a718f0ead36b51f3a50e9e4e4b2de8acd33add62bfc1d20000000000000000000000000000000000484bb2452158bca93dfeeedb40745bc5d9a9ad49afa20e6c29fc9ed1a8fde33ce508cc252ddd05fc486f8ef78738ac0000000000000000000000000000000003c2d6ff6f292b0f0e505fdfdd2940e72bf8c2837da4ec9c74fb593fe3318a9b9a8592524bb5d40f6c38ad871ab7b6150000000000000000000000000000000015f888ae2722713e1b5b02803a5b48d53116c1a4bb1191c9da77ded8c6ab49f1620b0f7c7867957d84503cfd3dca1be7000000000000000000000000000000000fd96baa382cceadc252eaf000d47d8c1e2085e9f274dd9dbb571bf85bba612836e1da2453fd914135842e2750796b54762d89025196aec4f87da2fcc5a9188b4dc7b1c014dd1d705223bf9fe1e7a7d1000000000000000000000000000000001820de289f62058920ac3d4bc60da023ac29c431ee429a10066f305d2b1a333ffaa906404af977cfd3212b53e66726b500000000000000000000000000000000094e448db84421e25cd03be3867125cedc7f77f286f404524757f3c1a9cfa28ab6771293da490a4d75852f515dfe1a6700000000000000000000000000000000097dec124970bc63d8f62f9133157d412f5ad3fd5eebb444568cf0fe2825d6ef6577ad302842f35570c9977638c6a827000000000000000000000000000000000490bdaabf4db27dce906cfacf3160c0fe25959df4af89301cbe6eeb29f72e4c55bb467841ba7d0750a59a32fc8b03d0ffb9f3e1d43aece3af1f59319a8228cd81e668b1e250d03350958dcac9e23843", "Expected": "00000000000000000000000000000000193358b283147ed5848559d4d1533734822b0248dd17b2effa80920a853b70e7fb683b08aad6ad4dbb91f964ad1b3bb6000000000000000000000000000000000649be60ba72734db4cc307a2fd8be57857f60660d0c496c0dad73794296552e17cb2eabb3537ce677edaac1c6997341000000000000000000000000000000000f91ce27345e86003c99d133eca50710c0722cb35af2ce442ebd74b46d659e0118be9bebf32111c258e4cb4ab795a2cf000000000000000000000000000000000d76ad65233522b1e079fcfef4dfa80f163682d7984d5062680a5dd4cbccd5044de4705013c6bce2140f7950032f90ec", "Name": "matter_g2_multiexp_73", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013fe4afb94d08ae311b7442de7291a11e733d8e555f2da6f72bf99da780a8f8d357cbf3d8959f6aeaca7bf3f5b5bd10500000000000000000000000000000000025af713b18cbdb5a960371c2dd0317f4bfd0182f4bfd6b88d588b56fadc1a0398412e7e0a786c326aca8779ae384243000000000000000000000000000000000581c277053c15df8eec05c34267f62e63faeefa2d124c2b4b84d2a739ce5484641ce955fbecb901d1e8ca816690189b0000000000000000000000000000000005355dd304b9b60498a3fb1f08e1ba0c98db327365ca9a0365a7f1e5cb56aec43b7fd2b4aa104eac7b1c30b6f53cd422be285a119dc8cb32b1a0c5380af736114a32e9d1ca870abdf278dfa84444f70e0000000000000000000000000000000016b5b3a6fdeffe5b9a0244a333ada4444a2e03771f94433832a4617be696e467b4e88ed80b174809dde4242bbb51248b0000000000000000000000000000000003dee846c5b84f89734016e547c63c02e4be07dbbecc86f811e2d8d3245f91205bfc055882565371db532240da1a845900000000000000000000000000000000194d53bbfa962def4da2a9bc7129fb6242a3922fe26cc4e603528ff31393a31d03dfc3463704250ea2ffa973ad175153000000000000000000000000000000000333768faee332d7468119b9e0469bbc7bc98a482562ff2fd9aeb6d9c67daac9c3da1db41c9e12224a2eff2feee51778bc0535bd504d7b9658e459c2e79b86bf4e718baa82b8d6e624fba0eb141c7260000000000000000000000000000000001910ded86d79f9b043bb79cc4049e0652c13d0fb8db2f070d695124d7a42cc3a2238282fc8a424fcd8d9ecdab4bb6fad000000000000000000000000000000000dc8d6caf97416928d2d58466219f054c6f28f49b2bc04d8a80cd46a308bc95aaca3a8df1914ab0c7da341862fdf47400000000000000000000000000000000004380ca7b1f7ef96295589f78a1683a51bce4b2afe50bd6076ccf5d07d35e6cb2ec7f74fa35097b2c0b9fff3f4797c1100000000000000000000000000000000054f492d7442b1c0d1293277d95efe822faa7d8881b9afde20db58d6267e049b90d0c8828a6c12540f4ba1e7c9ace6d84f3fa09243c01748954d84f4deeb460f3ef78f9c34296c6a092952bc463d7284000000000000000000000000000000000bba4761eda87a304a80180c2447a1d5a52f743015ea7c728e70d6a5defe3139c80696f842da3f06586be8d506ca4bc90000000000000000000000000000000019ea930d5733f4a1ace9fa0139d412d65b2886b659770e388894592de0694d38876fcd86d14580f9b92518d5496fd44c0000000000000000000000000000000002bf5d9a36d641d1259c1b30397aeb071b88844c4cf17e3de0984129d7b4d67865157ee2f682e7cf9d968fc07ce43618000000000000000000000000000000000f9a4f29868654abafc7ba935aa22d3d010023ef5112683a037a6c69b9e89374b256b8e1329eb5ad306d9f2063c22c335d84733ccc41f71a11d61852fa336df566109c5538c2c5f5cf2af961e93797fd00000000000000000000000000000000004f194f21373f09f8cb4984169890ad3855e814a4768c84e9fc97dfc181c60114aae534a27d3eb225b2125131c754ee000000000000000000000000000000000e6f88880e9645e35806d193f5d16799d63e2f9edd8ae28df54d19875c61857b0a34819a70ba3e9c31f00b5826b0cdc200000000000000000000000000000000193293c6cfae9ae4b24519fb23469e2f8dc4eda8524ee0b00c7141587b07c8a26a29841d41cafbd24bfbea2034a9c18e0000000000000000000000000000000017433efadfe9873dea9a68177af3d5dec4a13dcf4a710422d52020d4d145e2523ec0b48acc533a1ac7068c08ae6aa28bfeeb95c32362014caedf2a9e066a775e2db0d1322edc86759faa99bd70c05b580000000000000000000000000000000011dc003f7542f6822cb872117fa658638dee2a15429aaa9dd576a7e895bc0a2160bc120558a32aab9e646354233a1afd000000000000000000000000000000000fe9ed8ba572ef7d1176176a31fa92a5ff3dc38b0183ea1e22618e3b3214ee78c53074d4c60b5056901c6f046f8210070000000000000000000000000000000006ef1c20c3bd88bd6787598dcfca52da4e5e0e7c7643af983c709b916e71fd15475da30d763ddba0899b182cbc070ca20000000000000000000000000000000001a38a2e54a44ade572ecde076038f5244f266cd99532024a377829a64c20fb2cfe1633367c74b5990febb08e776bc34edee2ea28b93b2daf4ff927991769a9c69ba16490b5676074e64f5e91fa994a60000000000000000000000000000000011ce7b2cba037e5f3ff19b36371d34e287eec807178dad4118c6d43aba68623e182aedbf911a2ae5cf3d0e690ec3ba790000000000000000000000000000000017a617453f391e6e2437d56ee831ba895084f60d1a5f342e19a242b9661c703219d90a157e1b55f005f5059c15c179dd000000000000000000000000000000000746ab134c7f4bc19583a4ea4991c7cec3f651a60582b40c17b2d18cf6e252d93d2f3c2a1a3399be70512ec9eab251de000000000000000000000000000000000698daf214f2de44ebfaa36379862bd9ffb40987dfc8e632f14738c93c8e5c3fc7be9fa9100fb5f7440311cab34fe1897a07e50c1fbf1b388e9264c762798c31fe76761508d070f06adc63130df07641000000000000000000000000000000000e4ac65ce62180ac602ad68098ee31cb747886e95a183e4f819d54af99850d70496e6952076084dc7bc2d3f7a273383100000000000000000000000000000000182c718fc9e5cc961426258e82594a5cafc36270af0eb50646d161fcc192c30d40d06647e14a282421638b31f378de940000000000000000000000000000000002bf448ebd27cb6270e1b87087796ca6534ff51ba0962f3290ee1d06dc18ed39fb736ec95632b483f44d3a9d0e45d1d50000000000000000000000000000000018b956acc1300e60b22bb936b2b52e2ae82e256f15f1415263157965179855137715c321d3765c5227dacb63ba2d6225f0056903b4508cffb6334bb5f645cb553a8cc61ea6765283f933686f172f8360000000000000000000000000000000000f5372651ffb40bf853f6f8396a7c7483c401b89b67e098ea888fde8d19e7552a006a127af1f3311203434126ffad85800000000000000000000000000000000050d7e89b21c7484cc5831885422fe7aa8e898df85cf7a3a275370623eb9660611610cdb829d3935f0d0955e0ac97506000000000000000000000000000000000f83a3f79f1dd110bdb8521e18a64490d567210801d77fa3c0c6e5cbc7285840da325cab7ab08494c8d516511eb189dd000000000000000000000000000000000f72904131be66380c5a18af4857ada7c15e88572197e100de1cfcc9fdb4306e446f2f330fefcccb41b676f24e3e0bf88031f363c8b0062b34d48f4c2e5bdba884005e52f77ac04c2f29dc7ef10fac0c0000000000000000000000000000000009ba6bbf102d390638ceb9259205a1856def2b3a4b5209eb3e4e54074347f71b6c06b70764fe85c8dfc9074067b8d00d000000000000000000000000000000000339c30631229eabc1230240942bdbcfa6e18f23bfbf88b7b8a8fa92f18e35d2f7336f0b819e875ac643b43e6d931e68000000000000000000000000000000000600cfeda6033ff51c3bf9182d22abbfbeb6db46c0fbe15ba82e72fee483744ba5a57ab2eab6f35927b4ba6d2b150063000000000000000000000000000000001530bba4db8a60bb6b7a05f72dbcd23044011d75221d114b839aaa9535400874472f94c849597174322291b5cfec4974cb146e27a9d36dc698e1982afc945af9500fc5aeba719d06d0c4e4eb245034c6000000000000000000000000000000000c636ac98557e22897fd101dc6c54d87060f460b4cf2c5a88ea14641e2a8a9395492fc5a946eebbba36dbe38f6f5c0c60000000000000000000000000000000007fe3a557aa93f2e9aef4ffc55d39a9172475e6595fd57409df3a7fe3d11558c4d3dea3396ee62f61190add83b85813d0000000000000000000000000000000015b04e0daf4a10541623e7523ac5fbe57dfff9ac17afaf4293c493c1982f3395980ec63046cb1d424c6dec91899202c10000000000000000000000000000000019617b191e9e493751b0a02511a18757330bde56722a72a29a399ace983db7114f84795e2b70bc9d670cc0095220454ed983f98fe5112a55c23591bf4e259d072f893944741d9941a00f907749e3c9990000000000000000000000000000000017472b8c1cb3ec528400649fe7c39e3908b16ed69b42d967e4d225b694544e8bc7ce5bec87019db5539f1de39dc6807a0000000000000000000000000000000012b1c4884c37037a94f84c15061df5ca6c05c5a35ad9b37e3ab8e8297c9000e715fd2bdc3f2b485e86c415bf656392a10000000000000000000000000000000002c21af2933029f04b344be76e18ce499def4a0671a97dd9b6a108d0fb23852fcdc56f882be0319978952ef04a207a6a0000000000000000000000000000000015eb31e80fb162d5fa392fada8d43648ef54d4f9ebcb0e9652dd501f55a8875a16a148d42e283ea8bb2c5a38bfcc8843a62f99ac46f986f2f29f0ad3da0310f061e691955c711850a2816ad7464614a70000000000000000000000000000000015e68e011ed063a9fd9cc8a806d8e3561e4f449526ccb6e5ce983ebc4fc49d61d26dad7db64f56ad5ab0b54fbdb76e61000000000000000000000000000000001617d7387fedcdd772a34b267a44315212d21b798c0fe1e7a9ed3caafb678910d9c9c3bd1fff4a3c8e339d0c90a865b8000000000000000000000000000000000e2b3c9b9cc10f41c4c0129d34c62d526aea47c77ded91a5ca3afa0da1801bba81def3ca66a978ebb2d1f3227ea82a9700000000000000000000000000000000096b6caf7b6f29e91bea370f91c2576c188b08b95f9df6c7df995fc9879c11cdbe2af86809468d472fcac8a89716d1d87ee01b0c9c6a6ca1fdac35d89c803bee3595f03d9d200affc5292d8a7c6720b80000000000000000000000000000000016daa86ec04f57c72395d96b6ea5d6ba7cf2d9d4a50eb90f7121545f17c1ee16216f4086481d91e59fc5ed8542baeb7e0000000000000000000000000000000017a783d60be67206241e0bcad20e371d86d47d88ba1293b73f32999b0a1646967e5d031a5b28517f035168d7c7d7927800000000000000000000000000000000058f24fbe4e9befd8abe364c961f0ca4d9083260234a939bf6103a3e8f10a8381a9e3d74af7c13f159e5c7dcf456df00000000000000000000000000000000000485c9448fe3a069eb024ec43aaf563a98da09c02c294da2a94a98a95430e25b062e8ff886fb5fca240fba1abf7cee60297fc700698c56877be6764f48a836d210bb33e99b5735da9837882269af9b45000000000000000000000000000000001230577527a0fde2e8e66b8c4d17594bdab8be1339866819c8890c600b35889d1e3a749fe15fd8182001e30e6420ca6d000000000000000000000000000000000ce03cccfa87229fa8d560884d8c7963276d79ae9873a23d550b4555cc4bda35a242dd2e70cc730b70cdf898609b3d8400000000000000000000000000000000174aab1f142fbb7a45bcdffd64c2d38b99c8919baf9651aa430bcd39613d7565196c18f0f4ee6fe05f5c40ddbcd4a67a0000000000000000000000000000000011dd23f59ca2a033ee5dfa50afb0c7ddeaec6d4f50e1866cca3f061fa03594216f005bc65b2c97ed1109c305e16222671b7ac02db15cebb8af459290c35eb5a86cf98b86d8336764c6bdda6698b49b640000000000000000000000000000000014e1cdf4f10b11f47c15d0b6b7dfccb6081d05d116c8149989cce4f1c53dfcd2d0b7443677b03d037710eba813f6f597000000000000000000000000000000000c8415c7d5508010e0db1878ca663d359525b290b2f02c61436e945145a7a4e1b3ff4e27ea1b2c8d3adbe737d8291b14000000000000000000000000000000000e424ece68003cbfaf65a54dba51e7b0942cc53b2fa9794b4deb6aef1dc1ba1719cba285f9a1a59e71a881eebffe2eb9000000000000000000000000000000001404f9a3146b7201b09c5fd678fdbf2111c48130e82cc95012e5aec1df7e64a3b3c727afee4f603e620925686e126c0f5d1a3f78a2c2ab7b85cee68ee670f50a176e988a341303afb7722917f442fab6", "Expected": "000000000000000000000000000000000e9f6bedba1f6e2a3ff33e0e4b18fbf8e77558bf42e89023df6338b03a648c591486c63c2ecc8ecbbce23b3ff9a7ae6e0000000000000000000000000000000013d2526d83b4495b5af645d5a1af7bd40bd0ebff125e0fa14f10d1c08511dc29643dcfbd25ca0bee5705a56b26c558730000000000000000000000000000000003fa442ab532094d47f1a9111c87deacb15d80ca6e76bfb5f9b9a209bfe196643351d778b0c6d6b274b4799f733abacf000000000000000000000000000000001278d51523d5d9aefc0d3783e745da54f74a88620f2161090a398defdebf82d13d5b5a21a5cd466352ab8685b034fa89", "Name": "matter_g2_multiexp_74", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a497e74635fde8caaa5c9dfe666b1b40732e58b93a72d39c8a60c1f4b262e1f18f62229a30fb8257bf895352ac4d249000000000000000000000000000000000c1b2fcbd7f78d85c73ae55f67110b575750bec353e55761de0ff09a9f8a2d916c336655d8f6a78dfbae13fded5a9c36000000000000000000000000000000000173893333d998dd32cc3e82fd7ad8ce77003192ad2bfa1b1d2b43f9466898313276b922f9fbd8e83e86b67acfd9ad780000000000000000000000000000000004ed01b702bbafc73dc1e6846bc944be297ff08d1dfef397603294c7fe11668cd0670d386a8fa0f0f02c52d47f54a11b34aaf86eb77ce03f1d8eacab84d5ff98a565fd33a9a2c40f2a19d7c041a7e2a6000000000000000000000000000000000b5ec74a2150dcf5ebe09f39234c4dfec623318889d92b0bc1f197a69650bc48d28a1112306be763176b691c6915dc7c00000000000000000000000000000000028db19af73ffdd0111dabf9c7d6879cc7389320a249f108b41be8b1d4c259d5889dbcbb48b30a288e26cd9926682d1900000000000000000000000000000000172fe526c62f9cae49e6d3284170e6339d5af256441590cae9507c61f987eb495d340500cb761896163cb8ec631434690000000000000000000000000000000013bbfcf9cd3167b47b48af5f5ed7e6d45a5fa38192756c9e140eb89a85c75602814f767c57108cfa2f726e71f31548f808ab2065f1d2278caece0939cbbab4bcbe3eacdc80cfae6e4500a5195883de0000000000000000000000000000000000052d7a0f93142b36489cfa21d76c0eb96904a3ddd946a53b8a6730036d88d30336fd8aae3ab29ebf62a48c6e849ca66200000000000000000000000000000000198350abe8cc91bd675f26516d771422c128d5dc0af844c6c1af07bf04a1d3ad9654cbddf2de5b7828d1446c45e7828b00000000000000000000000000000000198f35692d5face8dda4b464ff48d650145242852fe189748783b1a2e48806294368ae0a99481bfe739fb4962f3b86a4000000000000000000000000000000000e3cf2e018a7e0acfee25bc3a82cb282cb377bbd72ce3044dd20e109d948f68720c27aea3d4663ee45b2de6f178a00ac58c69b55bac97a633f3ed7816e77e2a26cccc029f7e7429c86145ca4645eb41500000000000000000000000000000000150e6b03a3052d043da6514bf4ee09baf1a35b2a909473db33ea0bd4c6af7d7aee9a8366c1d08d2adc5998635eb0dfb0000000000000000000000000000000001370c2976b0d36fcb955e797087e6ccffc851d2450cd63833d6cbf52e1fccbbbbf9dc695ee45c7df01c2828051bcd79700000000000000000000000000000000048b5fad2fe0af7ccdf675328d8ff5e63b564d8436d04c55b23b6ab7d2aedbd25d614d1780963fcd03d569bed2085bae00000000000000000000000000000000141f94b4e7ba542707d0c3cb69f8dd79e499602952be2374cead840dc669c5ac57089c5fd60c44291703b872098fa2daae7faf23e841bd53683521cb3cf215577fa51f0f751714b6aafe5c740f66208c000000000000000000000000000000000eec51e0ddb8cf9914304e7766a7418e2854ca71367c1d2b3875c12b7dc5c7cc2fbc136037bb7ff72458027104ed3f270000000000000000000000000000000009fe5e8d1918f9b5865a8b97c2c2cfc8bd750a0ccbe2942070827a09d8e41ca795a86b2262b10462795f833c73e788ec000000000000000000000000000000000b95c9146f3f560ad880ca905b5f297e48905680b4613e91f393f72ddb042f6a6201628fb5f75fc23f2298cde66a6df5000000000000000000000000000000000a29a8fba7644ac96d77ee73a93dae23b03d81a57f6cd8cb4594b23571cc1f658f163081ae50d72e09c6513d1cd2c8bf72022cdd6d942158bad47a53a9b0c3be910a41036874975724a5cdd22c012871000000000000000000000000000000001807dd8d2bb40a642fef693739b1df12fc787db0f031306f31970d0f59f0c97c0894afc34b9a9913726a20dcb7d5191200000000000000000000000000000000096fe8bb5e911c1ed9985ac08d864c7020367f4259a0d074973a26cc421a44e8034a7007f6d1639285cf8acb8b2d64a60000000000000000000000000000000014026d43eceb26b9ab5bdd4139d4f94349b273e43f27737f9ad26d23454cdb1d35ea793d21f057359d28328a82d5290b0000000000000000000000000000000003dda2a84bd1f92524a8ede9f5e81f0f64b41b24510f4e0b8146496a776d5b509968f188c12c2d66cf755e5000cddb3b800ae0b956e38bc34cce55bb7e88f1370a30fc8ed0e3f1126c68c30792a2cabc00000000000000000000000000000000011246ad07713d1916c662679ab757c053e33def437d7a976533f0ce80ff6ffc259489c26524ea96898c3747c4127539000000000000000000000000000000000acf66265811a57e47a4c98b40b12a37c6f439550b18215fcf856c167b7218397d7d559f852fb45077945a5074f460be0000000000000000000000000000000009badf2799f1c43a2e3859123aca91e894f86d6298a06a9127249100ba270f2bdc79cf511691bf2d7faa45ffa17490eb00000000000000000000000000000000069438b1d53efcc4277ea7b41cbd28a19f80b5380136f62121e766bd2845e13d5cb40b2f15d508414876ddde491a3830a57c3322133d6ffac661c888995e7cb067ca1309f3e9178a266f1a410a79c01300000000000000000000000000000000112c4cc34da9e83207b5ea8a9251ac5f004546596f2294b3fd51b77ad8d8e98239d53ec4f527c7280801233175500b1b0000000000000000000000000000000011dd8627748c9a2b08524f88e560cd3944bfd1fa17e1d6e2e9cd025b04f2e3ed35125197136afa2848d24fb5fd19508900000000000000000000000000000000093219f9ffbfdaa60c5965b45a5d5bd923eb5d3971542ac147de3f591a5fbe31b30704a0061a524e2ddd05a45dfcb6a10000000000000000000000000000000006407dffb5580790e250a72dfe68a488431f61f45ec9df279217b8800f0ac1ab585d84e486487d5688735fe5aae75bacebe67f3d067b0d011abb31588d1b2fa9fdf8a56bc46b1a0196e926d4ec73040500000000000000000000000000000000107ede23f8e4f273ac2647fc251008905966dde32339c023f1da3c4d35d483a55b54f4157a303e68e1dd7fa3f3b14c8d000000000000000000000000000000001739327f282812fbcbeccb12e40df049284562d8986b8d4559787e1d5247eb6c83d6b838d099f36d8d0e32da2a7999a10000000000000000000000000000000005e5b6b2baede3ceae776da5adf075c1d774e83d6129ccfe7e835862686bb4064b187cc0be0cbfed37e5cc039f3a3fb6000000000000000000000000000000000249554dcfa53f73ef8f08daabf20c55301f75c8ce095cd794061c55e195221602a54ba54260980bcdb35685e41d0f4ffa1d6d0d1876a67337d66c596fbcd7eb22ee308e4a5f66cedff584f1441be6a700000000000000000000000000000000048b7fc5a71787231f1c7ed2134be528fc8d8f77102bda806ccbadf4f9bed79ee94b43c0fd3e5b1d776fe73d786872d1000000000000000000000000000000000152a1f005a64e16949d7249c3b391d5c1e0ded4893d0ce926cc666f0f88b64e8dd6ec4f92ddda18127ec24cad7e40b40000000000000000000000000000000013a2e1e7958a53307adf3beb32a88b7c493df0e37e074c9105da3c09bbaa01fed092fce2b1800790c6e8af3d30ec5a81000000000000000000000000000000000e2d405806764c75122c1b5e410673b28759f26af7489cfa6f35c6c0dd16c508af045009853f3329cda4a67948232bcef0c4ac919efdf3d0e649126da7f8ca3daa30b6ca6f3be6854c0f447a63cf2110000000000000000000000000000000000a71d61dbb3ae37230a2dceb54061d5f8c1ce645e20ec39785c229cf79aefe238959b2745e3b50e4b3c20c7a8e2ae27f0000000000000000000000000000000010e82b8dd5faed6bbd5755c4e5a88edbb3511d3f4442d1e44b82cf72a6414bf6558d29e8907b07f71c00f537637605bb000000000000000000000000000000000d8c93f1984b742b5a02777b706970215c7d8eeeb7377cc26c3af9005648c2eaea7f7a3177b6e049b132ef6bb4b188da0000000000000000000000000000000000ff082a252082499d70eaeba6d5514fc8d641404b48b2ecb256eeb40d9c6b68ad5af58556c9dcfc5667621c549b8ee760d8bf380bc2223efc779a747c0a36f8c2b18c3e821e96163bae14b18f3739f9000000000000000000000000000000000f4cf354b8de6dd2231448bb235af3c84daac2db49abed345da6ded50eae93982a4f2c27b07ce725a062b07fdd9058fe00000000000000000000000000000000076cf19408f0f0379c7e65a6675b9856782990986f5c6d7002e9c9c74b95ab875924bd7ad5e4812844f6d1f530e58deb0000000000000000000000000000000007acffe32f96f5e56557965e3db8dce87eb7140d93608cc003bf4a43fb261bb7360c576da0b7c4dccdbdd9cc53b5c5f8000000000000000000000000000000000eba1c668fd9323d42d6a82d9f075cec2d278cc57122e25ccd72cf8b5a569552cc6b0e9f88d23b9b7af18f3bfa0cc820006c3a7b5ae971e4b0ec34a1007a02cf8c55f067115ba00c5967f70a7dcef9d60000000000000000000000000000000006157cb6e2dfa2733d4c489ec0334f0303ff1ad410f329cb59f99a5fa3ed2cf84eb7d2f231078ba5db0954badb58425f0000000000000000000000000000000003dfee394f4c140e2cad61e8675b26f91244880d9a0b6798d6111090dc9d080563db5c89b7293dcaadc74ea5849a08aa0000000000000000000000000000000001aa1e0683014d5b6f99f469a0b7beefaf05a7ac0298bd1a3e2da409f6cf856f70bc067610fd705a851cd70054df9562000000000000000000000000000000001571b129f69f3a6717272ff75351fa053f46294f68ba3f859208d6c91ba5eb9a0f2133a5e139d04e38c7f7aa303451768f29e330b48230de23e0393bf1614cd26685cafb899db5a164497955d3e98be4000000000000000000000000000000000c4e84b7c8e46daea67c8090b27dc28b7867b89b92f56232bfd8ecd9968b865a057957292e79c6dc08162f9e91e6a4b2000000000000000000000000000000000b8d1eadcf3f1de6ee608a4a0ebb7defeeaf4e251bf07717a6a8e50c07223ca32a2ef290f26d0de14b1942e02acba39a000000000000000000000000000000000e901b546a4d3c68e4432f376c97f42ecf0724777956c4ffb1e6ca4fda562e57be788ecfa45ba3afadb439c2ea546ff30000000000000000000000000000000007ffe01da4fbda9fe5d47c3bedb4b92fdd71ad73fa272b071a7a7d1cdce7743a535da7dfe05a43d03368eb97fff54b2d861ffae8f62572938925593f7271a56e0f559b56bf97c454c38547a2185e2ce70000000000000000000000000000000008da0fe413e31ca68f84032f23bdd5399e01eb3b5ae47033c6834a39645d7b5cc2ec937067b91ac6d83035a86fa841f9000000000000000000000000000000000b950b982323f747782d9065dddca5332940058a604829e31560a6bf9b03ec72b09cfb87a1cd244ec694c7cf192c37ac000000000000000000000000000000000f4afddd25eac15d2248c71d76c9aa27323f75141820efeef1ab4f5003141053f138d9a7d1a901961d0f2c210ade27ed000000000000000000000000000000000217b1800c53d53459b00b8e463df1882b2cbafe85043f08093a5414e58ea7fd4dd933c601acfd7c154d0e4ce187468a2dd907071c2d39fe710215d174452459cc31d36007a1b5570a27ca2e42c8be55000000000000000000000000000000000046aed1acd19201553bb6a88fd6a6c0525ed44822d2a4ed3bca48a0a2b75e76cfcdced8f342b81ce03ffa72e667b3bf0000000000000000000000000000000009a5adbac43cca3402db016a2138342fae89285ab1fa16d7acaa9c3ee2b4e3df2641f7392355996bef7b1578ce1ef119000000000000000000000000000000000c8ebbcbdf2ac3fbb553a2e589f4b7c259a1621b83b14fd1927f92d9f6cb27e82507d7943ff5930f0c14b9fc38c9857900000000000000000000000000000000105b729f678db31d04ceae0aa37f9cb0b0319c4da9a1a4702a11bfe3a5f2f1f2af09b9cbd5ded5a930e2e65f4279a31699893c06db2dab559f2c374df4298707dc1815e55034dce920ae7b1df2ec8d23", "Expected": "000000000000000000000000000000000708e9b926f2536731b02b6b75305c549da58e312d9c53701a993624697af2f3469af34dd4634467f8c98a0f721cd9c00000000000000000000000000000000019185b84fc0511a048e3c39bc10334c91dc1052d323a31c8bf325479a2fa3e4228f8260c0e725c2b89d5a0319e6fbed70000000000000000000000000000000013c7c441d5cca81b48d43e908d6a3bf8b5057cf19e4884227cefa9b235103b46edbe01bada06bb9b620ebbd016d537630000000000000000000000000000000000431182c8a1eed66073956fe5798a894be396403c072e766cdc262b719d1779f960f4aebf61c1bcd4d005d3c7413e52", "Name": "matter_g2_multiexp_75", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000199f555aa5c651183f52470e36cde438422f41c9b2d1947510665254b74ba0bb9cdc6e6a1283b0c8f58d8f009eec46900000000000000000000000000000000018f1d8f22f43b4649300aa23ac92a2e8f17e7e3853b912bbc8e90588125c371084cb224c2d54dcecb4946ff6db53cd02000000000000000000000000000000000efed0bcc83a52f0faf9e260815da8d4e5286396081268485aab052a96af8eea0112be6cce1486b10b60551ad6c810780000000000000000000000000000000013a3b1ca3b9b7d50083c10d36997f5f521d4426af8d2905aa5d074ff37e218a0c96c74387485c2dae24c0842b7a74cf0d8555388bcc6791802ddb6c0f4cde44f45ac0b5d7ecd918bc34fb9fdedb65b94000000000000000000000000000000000efc5a5c506e94ad2754e235e2da866d9c46342f14d518f12510c93f13a619f6bfefec50c146d6d6170f190497eff229000000000000000000000000000000000fb91f34356005f38c9804250549554cfe67ce195d5e218e4e1b1a4fb904257bdb68d6dfb013e8e85fb5a4cbdbf0f21a000000000000000000000000000000000f09903db4c41fe3f11c6f0cdb7c31a131033e30f52cb66ba10c2e7da1ed8a225ef280d313630121701f9a490e8a0f5c0000000000000000000000000000000003484f7e8f7d67ce40b4cccef110bc255d91f61a4e1968a9ad37e25058eeaf39e9f1ff89c9b2e515388a7c1b49a84a2c33e5999498978d14c9de06f7beb2fd870f6f16dc42125fa496606e65c7466c0f000000000000000000000000000000000444215c3d4a7d62201ea1b69890e2ab90b5f5c6ff56fdc9908634c7489e785521b8dcd7ed409cf09c585cae8414a3250000000000000000000000000000000002d70674251a0c9ba76b8bf3b70547da77cde5592da9204954abd6d8aec82799cc0fa4fcd42139357043fc867b3d0e0d0000000000000000000000000000000018c57fafbad2351a3da695f8b523443e8c763dd7ab875caaa6a494a498cc40b1c0d44488e2dc80d1f0bce00a2c90c67000000000000000000000000000000000125d5a87ee3f558b5e1e7664b0cb95c195bcebd5e43b930fb47d15eee4fd50b3fdd0a401c9bb011c326acc77645440137894a51dcfe5a8fa4da1745a696c870b353fb03a31238b8744840a78084bde480000000000000000000000000000000018790123ce8b3b72d626493a16936c47770a9b06ca45b17c6fa5c7759f088cf98de8ce7b3b5d6082e9e42b39acf76f79000000000000000000000000000000000fea86cad8b40f315d8378550f6d3d831149339a8e8dafa77295859ddd2417e8f5c0ae2baad25fcfe00de14f45a537170000000000000000000000000000000014ad78bb2bce966d52b1fe1a273bc07f2f24b354465edef6dbb1e0123c7c3d7550983b3793ff1c7db846e88eddbf33c4000000000000000000000000000000000c0daa6fba40ec59f6b34d413130df5d9137297d1b7b71b83114a6570fef8e7f83d6f5689527164782f92da4b1ea12e8fb6a294589c816e18859cec34262df6490a2af6acc7daa3de861198c5bcf4b13000000000000000000000000000000001186b7c78952e5c32a9393eab07ad4532471595bc2c5d8137c61dd7fe6b6ca3aaba82dc205a559bdc15421a001b7270d0000000000000000000000000000000012d56b6fcec3d6511d2d723601cb8c9faabdcdd12efdd0e2bfd7c9292f2c3bd7f39c6e9aa53e6955727f88ad69c5b4f10000000000000000000000000000000006a5e56e4a42b04c03619c78232104f1f1f39e755058a19354eb230f2f09bf486b2586817aa6b88f27b884957ea0226600000000000000000000000000000000118c8521dd4866df907ecb252d9ce7a489f17d0f240d054a5dbff6c35895ef20b205236aa6e5be6f0825f9df87878ab783c4a3460caa35fc0e7342dd2da5c7b6aae818eeaf5a2cbf4794387180b95dfa00000000000000000000000000000000092809d18926c20456857826491f55cec17803e9e7d43f22faf4da18ede3bda15e3319539017ab20ed1de2bff490a33f0000000000000000000000000000000018d736b967eca64234f4e0018e5d6c902608e265037d9b8ba42dcc923b84ac62599e153e1c7d00e552ecc5aac57d1a5d000000000000000000000000000000001804aee99219354d4a5c46328f0658a417c85c6bc89af6db29a4911c4b0cad5638fac5ca61cc997fef3450cfb4a6c666000000000000000000000000000000000bf99dc4a400adda5bc89762e9011dae8ada23b284e52e2d49f75f1c75247f6282c95a36f7a72f896ea308131215404bd2b65c1580bb46e3a4cd9d9c4eb7dc998168c66982448abf3a4e08cd12f612b1000000000000000000000000000000000604f8bde85c0b26894e0de155cf896c911bca47533362a0b59ccdad0dd64108d33af8262d3ca2ca399306723f2482a8000000000000000000000000000000000ec10d3777aa54cd0cfd84b4062092ca3ac840a24e8e8aaad5f4c275e4d45091f838ae522efb1b2a0fa42229157297d300000000000000000000000000000000132cc70638d02186116773b31ec0e571a55c1cd78ec055fc647ab09cf4d3c543e0552d559b3daa4e99cef031e583e61500000000000000000000000000000000194a6a32a269692906b64feef9e4e8cd204e560b98db8c66380758d2123babae871273b4c571a1570a317c13a51d0fe9120892aded230949b83bfb2dbac054b83a9dbb852bd0ad85dd1d7f715852306f0000000000000000000000000000000016d05912dfff44912bf34f242ac85eb55bbb8a21625d45496c76d057f518352528c6632d6e8adbbccdd5983d13c26953000000000000000000000000000000000b10aa1402c15fd601ce605ade8f25531ea8f95cf592bf4ed86c4a3aa847dc8aa2369655ce5348da30a897fa8d71ffd800000000000000000000000000000000183f5a2f40da0a0f4598c6b9ea7b99f8cda1d85cec0e6da5365d7eaad1e9a3167bd647e5e654985f395ea72257f61e5d0000000000000000000000000000000014e615e2d5072c1b536ffa607f3a826ce297800b0da329fff397b6327800ecdc879e91f1e3ebc26c18e188e1ca66bfd66af9777a58539e5aa8b1fce0994e0e1cdb5877d93ed4db715c5aaf74d6a8bb1a000000000000000000000000000000000f3cd275d72a637bcce855e2e20727c6e5a1f15bc8d799231d3a7f61311d4cd2f58cf38448675aee9910c1a3d0b576210000000000000000000000000000000019efca445312f568727948c803d06b8d4e2c5289015740f2626fedbc0047d344aead06ef521ff7e139312fa41d1c107200000000000000000000000000000000141384e1c9f79e38bbb0bc1025c079741b93f56e150df58cf9a61ec27c2877c4188866fa197242965e3feb47a78c68380000000000000000000000000000000010638286faa6c45cf028e8e3d200edcb348560e2e35902927391401b3155240b62a40784db88e02b874e128e3a2132b5f37e2ed8e96921a0f9bff8b43d432b382d7b59938e269c381351ea49b8c1ba2b000000000000000000000000000000000c7fc4216767ed298206bc142862c138d78726e2d39afa18fe5732616c73a965d95cd2032d4b2f5a4d562be48ba6885a000000000000000000000000000000000928bbbd76b87f58ecc850e1aa4a2be11b15a81786aa7ca8cf0f6cc342db87b66c435f009f88ad97b747400fbcc651e10000000000000000000000000000000019f5ae9f06f2bc27a39bafacc7f3745fcdf8c78c9ae8a3c066ffd704aa4117eba773691ae43387b93e86d2e2de3688700000000000000000000000000000000014360a7ed73c05ef5fe651321f7e839c920bbc1896636143b88357cbf76e15da839bc7e1f1e629768d447c9d313cec8e23f4a77a2c34a370a9b59ab1cfad77212e433464d0195f0d2fd20c69141389f50000000000000000000000000000000000b9d955f9d28f9485d0bc4a961f0acbf09ee5fef38ccd81a2c73cf87a461ff1bf28d4dd1e0db3ea522299af67bff93b000000000000000000000000000000000889061e71866001b0760f68e20c7c0c033d782e6e6752f11502a0e8b6b70277a985dd13dd83424d1e5cdb9eb96a01c0000000000000000000000000000000000e05a26686667f44de2bef53c36c82f1fdda13dd3f7f8fe1fb026273dc4dfad18241d732ccb757e2b46ed8317dc69fad00000000000000000000000000000000038b55685b02231905dd9a62a709c0f015cf5650b3fa469462b3e9d06e3af8092d998c8e08ee61db1fd5583b0809a38996c59b0bc6dbf66f42cfee34413cc4cbdae7a61e232757c75474818591764d6f0000000000000000000000000000000006649a8eabb25fb7793344a0b29325a88294343f6c69612ee9d9002154a49791f6cd7b37b2bec69fa8ce11722e9f8a03000000000000000000000000000000000e10f2f3de16fce9b9817085f0130e1839d9aae949170ec16834732a9b12f589a2b00f17d2fd3416ddd020b7421ca20500000000000000000000000000000000016b51112b3c7c42a8c2a0fa7f286ec05cd07b6cea5675bf1132de99cf42b450b3c2a8f02ec821529a14a2a0fac3a751000000000000000000000000000000000f471ec8b65bde22e003500d1d422dd0d163abb424dd261fac588333755cc5124acde328085d8df852c61e024155564781c180924f1d982bf4b6a2bb1cac590cdfe84198fdecd87364e163dd988f9b1c000000000000000000000000000000000ec162d22b6516c309efb6a4577c5631a5807bebddc5fd1be5446e4a64785d49eed80eba2e89cfefe484ecb8d50440a600000000000000000000000000000000070c252caf6c56018af6b281b829a4fb8dbab850ba0446d233dcd4d87bebac00e3e5070bd41898dd561526498b153199000000000000000000000000000000000a0d76d1205c1f520d82c85bac4473ea7cf5f68022d95b1f04d06062197973001234d86921e70a94e478eea85264f14a0000000000000000000000000000000014c6a07f0d568f2103ccf8f61278e916458820bcb61fd91479b0dee874fe36c063a34bcb14ee434b68681d297637b5bfe44748b9eb1f44b5fb143cc8deaad23047bc5ecb8059705e7905c37625d5e2d3000000000000000000000000000000000aabac129385d145243c3a1f357ccc963ff14867ad039827488128ac639dc62fba82ace66f889b47d8eac39802bc1af900000000000000000000000000000000062bbbe8c72cd6f8626484bac159b7e28c6c8c3261edc6a05a30c308cc9e56db17eb58f62ab755f04a5c87e58c04c7550000000000000000000000000000000011a4a439d18501142350229778f67bbe0c9b948229dcecf70a8b09d1df6c54801a111c603301da2377d4198d09dd51e70000000000000000000000000000000017de3d9bc6fc5f415d04ecec013a635fa200699c496f4d0bdb5cea7d446274dddd0a7f6b06058fde43fc4f1457361558ae04d7723b7c9cb0574ba744bfed8f8a347ab740bdab99136aa71a6d635d0d98000000000000000000000000000000000c86590a02fb5c9568af4e69611f09980cb5a7e040c94ecdbe64e40005783fd3305a5657a5c6bebca7d20ee123a872b4000000000000000000000000000000000bc873a9bc694171d2606f4efa409897e03198a61b1bb16ae90f0d12345d2650d93c46e0c22b717e2f0504b8983515990000000000000000000000000000000001df9160ac3bc54c0121a9c69e9065f4266202f755c961bcb8641d13720b82ebd73eb3804ba44769fb2d75144442f1c400000000000000000000000000000000045e9c8ed2fe1e5c9a2a5bda75dd60f6bb5dcd0a805f68c1f662a5960b025ff29c8e21857d2a61bcd65c747d2a2da8ef6a794685a342ff25dd706e4df725e3466889d8f08a27ed2f32523b117f01a84e000000000000000000000000000000000f94df8d267339bb4f51b21014ca6d685f7657d0f0bca189e53cf19e0e5e05bfad773c0553daafd80c86f302b1907ba5000000000000000000000000000000000d92905addc028a1dfdad50e909c77662e10e4689e7c8a4a0174a3e1c746b361665b65e17fce02b6c067a5b8d7a6a6f500000000000000000000000000000000183444f0665790c48bd3c07545115a11f82463a092774234e7b33aac1094761f213235895e5e61ac1b0a15603bffe2140000000000000000000000000000000003cc2cbbf181fb023a5f6088d8a9793b17984b3dddc8c3ef1a9f82f8f436002610df60b2d35be212da9945bc8108c0bced3f23c51953e46d400802dde46c374178ef379d5c1b04d25449891f0d5623e5", "Expected": "0000000000000000000000000000000011f85691799cb76213068ef4f997af66c349bf707295b969d85fe637d4eabf54f3f29e739152aba5027c1b55317a27210000000000000000000000000000000019627f9570f07f44f326b5b3ee19bc477e92d813be2865e00da93135645e02e6fe5507ac4d50085b02149667794609fd0000000000000000000000000000000018fdc97bf0f88b2348b436d70ac4e28b5ee5ba21e21e94808b8b9e401c0c7d688974fe203ebda0b23abe38018876f4930000000000000000000000000000000019e28c9c936ea5a0b3b41871c3afaaabd53a93902e44a96dcb7651bce7e6143d81cb695fea8b94aa32c09ec030dd9ac4", "Name": "matter_g2_multiexp_76", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000703481cf48efe78fe8dad34184edd1765a1d01846de74a45b43d4721bf1af116c229f969868b0e6e851f22bdfb0451300000000000000000000000000000000063d316d495b1e82380c5b73bd61ce7f2159e7714c50e374e8a91dd56731dbe03a3378bf8afeccaba5fda73b4c2dd166000000000000000000000000000000001012cb2f6578065c93aeb673f447ce95fb42927ef9d12e07968ec04b6a604d785944620043dee5de4de33d59e67d64f20000000000000000000000000000000018cc7cfc360801ecc420d77ee171fb3eac3be0cf26b3f36a6cfb7c6adae7bb74c18071daed8fc56b8fa639ea138267928c8e071da1ae8f615631759cf33fdb876ab289a6bcfa6fba2693a58f8601dfd10000000000000000000000000000000011e0dfc437a65c6fe37bb9e554b5138f68a3c52816807bdf7d98f13cfaf86b37e9669f4e0db1b7865d910a309f16cc200000000000000000000000000000000006f2323e01591a7db1d3c7fa1a2ce4540cbe0396cc55baa3a3e13650a6f6b926a7cde0eebb45d359edd52137152fe360000000000000000000000000000000000066bfec8df4ab5f5f5eb369b34e8e22fe32abfc00ac58b68f2d3841248fe5843d6d29ad012249fb9ee851e40b940dc2000000000000000000000000000000000f4ea977d9249bc05dafb682a863ed17f7fba0a06c4a13cdf5a836748664183272eed96bc4109bc5beff61c5469e221f8371fff9230243d2e6cb6bdc4cd97260a8cf0362d18b9ba8df512d2a6f5563dc000000000000000000000000000000000fa3e3e77112774fd6d6b560ff88cc92ef8d009675d0ed65705398ce727cfe786684da50bcdfaffae97d19bdaddd81c00000000000000000000000000000000019e98284b8b9f53faf3b73902cc322dd80fc330dcaff2a7fceb55db6a4b0f7f667297f5e4650c797ee337985dc6b54310000000000000000000000000000000004e30acf2ba66d842575c8679caec607fd090f0aa2350464f3b6eef22e2b9a1d9d5fabb0f3909f1c19f6b8f27c53b040000000000000000000000000000000000ad76b86e32f84ad74bac68909da0c271571606e071b13bd92e387a8a16a1c4002c5a5e94ecaa1e8d2d6e051e19a45c763016c9a9cfbf336ebda090d3f2a1a1b265787e1917f0148f82a9c0b66b21dc100000000000000000000000000000000019bd07479b234bba974ca2f39b317d5f4be33afef66c1d69e53c44cb5e44c679775ba141f82486424110d186561777f00000000000000000000000000000000130002de0d453abe9052a5f70a9d55de74939d1c8e6ad5871a669a867861b1359322eb98539f4a21597d806aeca62d18000000000000000000000000000000000b2f0c649fdb37216c10762f510c3bb4c789dbd29c4f9a8ff39f74ed1a96609c60473a50f5ce3f6535e4af0f2f0a150c000000000000000000000000000000000893b9af710787361a32fbd19c380161c9a214a1bcf3761563424b8546f6068ba650d9caff3e42be63ebf4b6afa2de516c9f679167d5fbb29250834c9f65d3025606e2af20aedec309718f95ba01e90c00000000000000000000000000000000019805c0de5e232632228e2772dc79712e3d863bd6fe56932b29ee99870d2ce5eaf90c73632d1dcddc093e9b6b5b0f1d000000000000000000000000000000000405d77f4b3c44f99a956ef375879e62df033aa408127e0fee013b74675a8c7d999c6abd30f459693086bfdb326d67af00000000000000000000000000000000110f2c231998aca3d76e40055a05feb37eba76cdd10106719f2300f57906424d7eb6d9f85115b78b7371ee60e26d02b5000000000000000000000000000000000593a4721a67caa7cbbe1566611a1d48532c68adcdbb67f362c9ec21e08aaddf6b5e09a9a96df9a89bc25f11665f3a36aaa3300f5a2fafab132f5f4662c1d288210e7502ca2472d060aeea6f2eab2d7100000000000000000000000000000000151758f1921743d116f1c4adfc09cb68b3ff911329e2f6d6bcd04beb9c109568c796f328e1f04381a995fe89aebbc49c000000000000000000000000000000001388c73b1db46bdbe70540c99db46b730e157a23afea97648d73f9d5f7e8b073ed665eed9e9e2500152c87715f1c4d4c000000000000000000000000000000000284ad228867ed14ade5a327ed951ca50c87f0a669e59b7a75d17feb54bc5d685245448a912590179db1e84f1eed1e5b0000000000000000000000000000000017d3da7c167733dd88f1c39315e47cc80c3310cc431989d4cc50ddb22e9fa481c5dc02d94dbf806c4c8da16ba5b24905f6608f7c036c8fdc335601ac55e869215eb4e626f52bae813d45b827df2afd490000000000000000000000000000000016064871cb68f748939a839800afbb018fd5836914a2b76c51818e764628a76817c7ea329e6b2f9de653c8162a2a2e0c00000000000000000000000000000000082fa03cda4c617a780caaecd7c859c5251b56b61f70fb3ea8c05b4c11c030adb8a96d715c1325ef3dce9b20e8065b6700000000000000000000000000000000174a245baedb7e1bf1368212620b850151be41ebb00c977d85da499223c207ab6f1a1d94a51aa9e90d07764ec3615b3a000000000000000000000000000000000df5b81cf4b008480775ff3d7644f546a60382e92a98b03deaa4a20f831e69e14a893ffa731c4ae9ee237d747149a9080cd68c59b1371c7063dee5732182961be90b95247511a5b564d7eee8d2c7c64700000000000000000000000000000000019d36b8dae5e1083e687743f7494b7f9dd0923024df81e2f83c78743e227ffce588a16630201b9909daa6c9207b5f430000000000000000000000000000000015659059cfee7850e1cf0e49abeef2fe5837cd128742e62de20dc734f1bba343aee1c9f1a59d920a0519995561891fdc00000000000000000000000000000000102b7221257c40d9adabd0db3ec9f6348487187ea1110773fcb2ac5ce210dfed167a4d15e605e9d9e666fd092147a1c7000000000000000000000000000000001402ff9770d27d2d82efa6abe4a181e3c1d944e97a06f670d9e46b24f9900fb4a838b32e17482f25be9b6f3240870c02ea52329555d9b79eb1fd6d186df80b25245ba9225553f402cfa6037592f0b10f0000000000000000000000000000000001745ea52686f87a39fa42ddb5b0f69368db3757394fa7a1a93eb20c398c26415c8a7edeec7334df5b15345d6174126b0000000000000000000000000000000012b580e6fd228f087c7584cd95826e56d1c074cf16c35286c45d2067a362529d241c1e24fd22cc9727d423551de1a1f700000000000000000000000000000000104b46c42a706c61610f8c0434894c7cb9ef878cd0234f8aec0825cbb8297bed3de349e7f6037dd19a159103ca7753390000000000000000000000000000000010b781b3cbe6f415af15e37be7c60dc6703e6e79618cb3d8d9a5ea3b17c00822aef1eddacad66a646c009dac887bb070caf39f2a517d432d1653c37fd9a6c4a8a811107dae428f4b2af3b12e4b6acea30000000000000000000000000000000004b172c360fca555e65860c7a294960f506b562e012ddebad5803bc3f4b93159c16cedb73f339def9cd1beaa0912c93c000000000000000000000000000000000242e37775a042ccf59e99da667c67fc49e80e54a1b438a74fe306d668059ab4dc7d9e457adb45e1f91b3e6bef0a130f00000000000000000000000000000000186eb83ce3abe66b8760dcc0d375eb783d175b0b2f36cc08793d8a86cf76b7618b826f50c6b02ed586394abe4efec2f1000000000000000000000000000000000bf780324df1cc5de325a796f1fde367eb52dac76c0632915dfcaf01f5acd6ae890dbfc2e505bafeba7fed8fd63018c2ff0bad6dae80d5f47dd8c208fef0f3046cf1040112d18c596eeb934762977cdc000000000000000000000000000000001231b52c8a081add6e5c250caeb9467335933c2ed66826e4ab44561eda9259acf926f22ad0df8e8756aa51279d12bc9600000000000000000000000000000000051c46bb04d3e035d324de681c772e4561cecc6a5bc4ef0a0cea56618e09b3f39f5085e208229e50164bcdcd4abdefd2000000000000000000000000000000000ad7ee610398935a02c3a7139185409d7fd4681ebb74a239e15d1c092ea913016d3f585d8224cb1d109ac111660a94aa000000000000000000000000000000000903bb16efb052b99e9c46f3478b4acf800a173b35b0079d7728fc25c9415c8b05ad520f31e6a3c867245f64355cbc080d0c40e5d422685c5c83716380eed82392ae1dc6074a7edb5759fa34a61db2d0000000000000000000000000000000001788efb21597aaac29b7bcb9ad6cecb89267c757cfcd8893c32fb13c0f3e1af7fcccb9573dcffe8d9220292b7861cac90000000000000000000000000000000015f85d3686148ad62d7fecb71920981117cb8759ab249d0ceb45f9e4687914536a1eb16ccd0e185d1352a8d2b4a8ee7a0000000000000000000000000000000015d8ed94c0415ee0f7c9854841bac5821253bb2ed4d86a61f494cbfbd61614983e4279fb17802ca68aba4a0302ec1d8a000000000000000000000000000000000f950a4c8aa18f4605e1252c367dba1e170ad00376a8560c2fccfa7d5487b0d1d5885cec16a0a17d81b5a584d473853f7e93a16a443d5f981a02f0b6866536dadd276abc0998bedd76b168ebc8e31b82000000000000000000000000000000000da25ed9154121205ab6843f603a38a6892887d2725f16ff87a5218586c6139188f46da5a42b5e05982468e8115713ce0000000000000000000000000000000013c13ffbed4a60bcb8659013b022012ef3a4400f506d65aff7ffb1bd5a9a5e030a298e417cc1ec8ee7ebc06455dbe61b00000000000000000000000000000000132d83bd141c434326d4772de7f8772c30a6456de7adee7de66a04bece4c0d20bae5526c8eca5af5ef2eebd72c90d54d00000000000000000000000000000000131355c5e359081dc86e0b15c8aedb4f2016b41e8428051f5132258eaf4392fdb63a91452dc56aca20b7ad3263ebc8c92a1d13a64c03585715908744481c79f340b5bdcdd88d685ab8b91722ee7ab7190000000000000000000000000000000012dbe1327162e4176b4988cec23df0c1b0075d0dc51ea8afbbf98f00891511d9023cf7538c5705d59b6d6ddcc90b101d00000000000000000000000000000000036c12c7f7627b6d6fcba9a303248c38d784a3d1d0ff02e550565efbab68c5116e9a88faaaf09bc72bcc3358e9dad0ee000000000000000000000000000000001578ffb68cf12dc9a5ae6fb5d822324cec9e3f576ce08d45e24fec9203d36a6461c5b8ea6ac50233e8893b07ea6e71e00000000000000000000000000000000015cdb43c82b20b8ab270b942b9e625ada9283962a7ce95eae156aa4355e1123ff87ddb1cc85b2a94bf36102ccbec33fb2bc6979fa2e386abec058683c6d74de31af3cac21283cd5e4244d7edd94da9600000000000000000000000000000000017041e16975850e6445c7b4896955eb5eab383ad3c3031aef04e8fdfb65a6d52c9e647330bfbb0f0eab630c9f9ef7a12000000000000000000000000000000000b62757ccfb913ac4264692053f766e142697f598a3fe26e998119b63a3abc7fee03db32a8af36aa21181fe9ea89d12c0000000000000000000000000000000006bbb842a889d7ff3c1eb5e0b16e3a921a11d28a251c488a8a17a29edd93672fd15974a7e972a34c47283c583cf2d29b000000000000000000000000000000000e94e685fb1751f8720b8af79aec7b245ae8daa195f11f485f2c0c5dd68cf39eef848a402ce2342a6b3398cc7879c6010f1937936cc3766184e47f39acfe5af4497e8edf77ab34083135a9ced61d25ed00000000000000000000000000000000100d3fee47ae6c8c7981c8cc615870924fbcb34c2ed817d6862e2e6d0b4612222a4c8332c7d51b58ec59df6832139e1d0000000000000000000000000000000017270fa71c34ec84043ef64c5dfd61614b5b3bd99204f9f70994d71498219818a5f16843c67c668b06aa5ad3a6ba8a0a00000000000000000000000000000000057948c0ebd14664bf33fb282e200fa0e641764a353e8347586465dab0c79ca2caffbdc2c6d60b2d7c8cb6b088bd16fc0000000000000000000000000000000012747eb070f2de18f517648395109bc08b4af3f04d98e23eb6b516199b4eefc5df7d57baec736987139c7b03b573941f639a8b60a1849c71688a11e612b315439161717f525b5deabbce75808470166e", "Expected": "00000000000000000000000000000000128c6c0283ea35c10330502d6aa849a909df6b8dd927a24f08072135b8e21e40c495c42e742160363772569189d73ef40000000000000000000000000000000016d78dba1e0feeab46f8cd38681a9c2f6490ecc3a6e79b31caead256611d133090a4eaed9691a87b66dd1c2ee50d5f470000000000000000000000000000000016de93e176c950975abcbc692384996315a98065db6d6a6214472e5a338e291b36abbcdea1b8be6162fe578acd669abf000000000000000000000000000000000d7155e239e9b15ab64a538b0a0bd53936df4ebdc3ec9b0b1d494e4df780bd014425759e9743c9b262cf48cda01e945a", "Name": "matter_g2_multiexp_77", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a653e0c24eee1cdf8e3652809de0cd159f2c541981a4f43936e7d41c0f97ffe2f1e1e0d1032f0970023f1d27241a16a0000000000000000000000000000000012d1d8d2f96db0e5f97be096c961e3b90ef3d88492fb756894979d2e8104791a5b9a43888043ce9e543691f15d2fdb650000000000000000000000000000000006ffb94dc3c2d07830498260ebe4641b2cb64df61cebfffaf2d4ab5b6ba92cd75de209e8d7915ee744c4db5352ff239d0000000000000000000000000000000011f25722cf9db77ef8adb9caa250175e12412e6350b494395a86c31e1f5dee6c89cc6603f1dfd08a70344cdc44aa0c2df3efcda934ec9d2ab05f25d618e5a483e830d0452a88e980589fcd7cfc39e5d80000000000000000000000000000000006177a74e3551770e7d906222590108bae7b97a5dd3bdd2344fc12e7005f2c1a188ab9dffe68f5ffb0cc36294106f15800000000000000000000000000000000041b140c46868767119a6ebb58562570732198854c92bcc070f2a8d9be91282a70c5ab99e75cc9e5064ed628aa5c59de000000000000000000000000000000000f318ee33fccf455e46add44922bb6e99afd4354bbc79d7550f8d12d3de4f75e5ddf4e62624b116f91aaa80a148adaf9000000000000000000000000000000000fe012bf88e152eb62c0c906dccba469abe591687573a59d3debe747b7d895e4b0755f16e67fa9193a2fd338c04d243a4507a696cc57c0bc49fb4d1686752c71c9c816d7d09bd66910b23810d475aa02000000000000000000000000000000000b26c6e0106d4efbacf2dd0d15df17209b1306f388f493c096429c031bc4a6a535b64cb02b400433f948fd6004df2fa200000000000000000000000000000000061853cf1a32fdf4c370cd413754ea584d3722a08d58575075a7371e57a7bdef95386ed72f91c4893377f6b551dd6b1d000000000000000000000000000000000ebf17e60718c8563a1029ba035dbbba75e7191b4339d5d33f64bb35f34866081f26f4815e01b02e8330e7b7e9c428cd0000000000000000000000000000000008ce40f92efb5c5be48c814018fbbe45f1be45f5b607a6600cecd50d8f791de7d91939ab61204c2a1337c3f21b2c9d26518c1259f23de4cecd5e3a40abef5662b497ebaf16240f40ecd651d2ba50af0700000000000000000000000000000000123ef52cc44f36326b33234ab3348893bc722bac3674e43385b201f372fe4ea3569d69d4d561e26f8ea903e017d7376a0000000000000000000000000000000005b1707ef61ff9acb9e8b4dd6922daaaa2d8a7558cb55b1b9b96eb6d57c23f50a7955763c9b5ef04f52b09be8d55f4b50000000000000000000000000000000015b6e35d14da61e7a7fcbcb0dddaf0071d8d2d89f7179f44851947a2b9b0535d6fa86b5cae9713a73bbed909a4c6deaa0000000000000000000000000000000013463e135b1fd460cf042dcd0226e229d60cc2beccd8a1832df241e65a644159722a14297c0033eb499e5890f0caff1e5561616c195ccc1345421d8a6efec48f0a4dc8e89ee89599839efaf95c386551000000000000000000000000000000000fbdf4a533d355e232723fbc97352fc5d7d3d199934883a61a9ea116830bdf9e40d423256225d9a3458134332ef6e817000000000000000000000000000000001195f0ad227941c5e383c48f546be34762d158e6cee585650b6ee987f7b98e802f678abac6646832b30b6e12e90948cb000000000000000000000000000000001820d5fbb5a62140c6e8cd105a70fc2f1ed84e254c839deadae5eadbb75e1c33a07ad12ee92900f55478e91958a3147a0000000000000000000000000000000013849bdcae33fad27f16e91c6d46b9678a00491e3d70a8db905db4b1d2c6f02a29392b5b77c1472052d6f4d49f14a16737c77734125181c72454bb2d37c3725cf1f9b6d6f42b721bca469fec154b3e2600000000000000000000000000000000188fe1e394b567d71099fa13b5c8a5891636d83b6b8a08f410b080658a0663deaae4dca1afe8b9023b5e8e573c752c92000000000000000000000000000000000f66c65dab8e1b2912fd5285a4c87821888532f5107075cdfedacc4d7f75c6a74b4828d0b4c3a2c0ed94576654a7047d0000000000000000000000000000000016af44a6df79c8c9b6f1d8aeca24e024c454d7b94c9ed386858dd35c4158cddcad1207f9fc3ac9e3b748c2314f875dac000000000000000000000000000000000315e5e4f78e9fcb93aac78025e95b8bf82ce4c840cf565e0a868b0aac22950d62f7becbf8039a16ca3ea66a7498327d981483aa66e04351f4340fd2b461165b9a9983e91c148da78d3c8e0c69e77de4000000000000000000000000000000000f9a61dd1b3034b8cd7408b0a44c8d02f4fe0e87778d5d34f5e884ccc9e2d51eca6b6060b46b66843e8247b3c794e19d0000000000000000000000000000000005c47fa7799a0fffcafbbe4694dfe8d0f47b60f712d6319e9a56ac459a636460e700e2af80f9c688208978aec7c413af000000000000000000000000000000000ab1c55fe2207865ecf12e372a341c776d24c08dba10702fce1cd2c01eda314852d81d0ccf1c3423c2a12e8960677f060000000000000000000000000000000014f8a1964aa3240d788ea40bb51abc50fae2736a34120ca9585fb2d5bba4e5cfa201c83be1e00ecd1c46fcb2ebb4eb809913da6f756005ca8ab900ab686484483af07df768209a16d807f8b88b9334d30000000000000000000000000000000006441fcaf5e68b10e7e511a95e56b9613453ec6468bb126c5eb12f204c9681c69b5c296320f92a6fbb0b848f8ab5fcd1000000000000000000000000000000000141de16aeca0a2f991e9fca4b6ce8fbab3d66ee3ee4dffb0124384a7d4ba51864a53e005fd34516c92ecab33165944a0000000000000000000000000000000008543656b5495bdb726109cd98fa18e405648fa88cbe2e5fea5380b7d0ecb207f0343dc7888b9945e55156977336226b000000000000000000000000000000000b53d4e392f304225b1ef363a3528daca1d3a6ad64ee99d58491863ea432a29cde5edd4f390de45a567cf32112ca5929188fb33fb359f21bc5bdfc85d39676c2ca0a1e619bf8a8e8de62da8818bd6cfe0000000000000000000000000000000002e0c55a43078df575efb2c99b27c5632dd1c08bf28b6c0558081a78de58e4258d1b57d94ec6fa157add04aee06e7b6e0000000000000000000000000000000006d3f4f0791431a56fb386f4bb8e6744cd19b10bd0f2e65e927371ab488d3735e3b83400ddb25ef9d740a8620821b0ab0000000000000000000000000000000011e9cdfec8a8f8eba0de6809485911711149ca0ebd0cecc033e2e5ddfc195fa7de671a686edd2f56e5f7da7328dfbec000000000000000000000000000000000171f188afd5d9568cc5648aefb65cd715c0293344b9aceac1031f10b4a1e4b9fa2ab11114bd58f28aaa58c10ee0eeac65525ab4c4468a2ec0beecdb7fb072f28260ebb3d9da1a4c274b2c11a087e814a000000000000000000000000000000001651d9bddf61e5e54f86609c2479513ae84b000ad7defd840d9619a8361922dde81c999d0e95d8a3044c46fe0360c2030000000000000000000000000000000014a68c248808e826a3bb50f3c1c1438483cbb9da8dd67a0c9633a47f733e6aa7deb4a13aaebcd50de6e8e8f00000424a0000000000000000000000000000000010c8a94b9e0ec9965f6c8bd0c4279102ab682a14fc3c22e9640d68f240ccecfead9a2c6e69f7c8ed369cce7e2da50d5000000000000000000000000000000000181493e8137fcfae203e1b45189fb828dc9eb56887c89aaf9aad0380fffada423f0ab48ed068ba4e67a2b01a16abbfe55ab5a55a5cfc49cf6c36b5718e108f8d006bf7fa1ec3dc7a7f9c02a2d1e3fc57000000000000000000000000000000000e3e33fa4d85a35e8707419ca6d4fb6a61ee6b07ce152adfbaf6b5f1d7ccc253b59f91e4545848b3570bfaa804ad9767000000000000000000000000000000000c923a4de074dce3ccc94698bf6445af5847c0e6f22f225c589f744ec83ed0810913af2a6d04bd55200ffc738b31b01200000000000000000000000000000000186961ed1c6039476eb6f13bf1b5f6627b3b017ece57a4a5f33db8ef12347fd507398a421932d3d2a1d009f65d06e42c0000000000000000000000000000000011e10ae0139f95a2f1144810894fb98f6e5e86ce67877b949a2a7134c446dfe53c23dfbfd12919b24975f26eafa249216ce7aa7dcd01c1b7059ad3cc0ebf5d19ceaae633160a968c33aac5dc6adb942800000000000000000000000000000000029265ecf3c81aab289c98d9cdb917749ceef56e2e4d59de2d6c83907f394ddd1cce9d093a20206c2c1c215493c41c49000000000000000000000000000000000986ad139381e4dbabd6beba179600e1c782f436f84a7bd58cdd96a22269f1d937f88f25059214fe2a781ac519aa621d0000000000000000000000000000000019e296d5b17f78b3ffbdaa2ef5228fa9dd65abdf6b2c5b0f99a708c4721797b3b156b8df98a5a879f17f095548555da7000000000000000000000000000000000349677d4719445d5525cd65e2338463d232eb75721ca51c48fe52d0fbd299ddbd6cbc12546f056bf212d5700c3c4100854bce63dcdc0cf408b43690abbbbdacda5f3ebd9d9e462f89f9f50a9f7bd44b0000000000000000000000000000000016f5d5eb3fc3ff178843a7d21d3dd628bda120321ae44206d88f07ac001651428e0da95d3f0676e1bbb969a300406ce000000000000000000000000000000000029121c539ef1d7b9888497a362fda2f8402adf10a1bee11b53cf3dfcc6f99d5026bc386f86a2eecd0c276494878104f000000000000000000000000000000001320a402922f2a0bb287464854be6782046dd9dae4c0cd94efcb8ad8e0f37b7889bc97a3c8b4d3b3670a6924c8ee23ec00000000000000000000000000000000101fa8bb2c90b755bfba9cd7a98790b7bea2ede4c806fbd9f2006d10cf87c44172d4ba46ea40fb75afbbaa2abc3b6e9d7603824b834a83c1c408243b51cd2c2d31e2ee763d69e2ad6d369bb6aa2396fd0000000000000000000000000000000003285cb099b04b6acd333c7ac76c839b6c09388792d5fa1f2af0821e49dfbf40a06803c4cca92512bb76d073129a48a00000000000000000000000000000000005b2fdbb25381b3b67814bf6cc0a4cc17271416d16ee369b723b1711d968c355b755183f0bce519709723250515ba32a0000000000000000000000000000000002c7062ba4f642b95e028a364b0698b801f48af3c336fa09d13d83ec6cff10d210b55b23cad1d999889c83df7d1ab7e10000000000000000000000000000000012cdfdc10bf46097083294259754453e084010f7ee928cf540d44c80aa4f601247223a318700bc24114e7603922d15ae923c86e91c48582f19409b962be361da5936db02b6862eefc288f9a32d5f54760000000000000000000000000000000000669d760352e34a407aef8e141fcaa9468257b12ec08ec218f49f0769f3acd5068c6dc9d251a1b2af02a2d091f8ad0000000000000000000000000000000000064a7b4026ee3115cb730e56c4b9bf3e1527dd0f0ac6015f43d30a2f3d8d8c2659cf50247e70ca3c93d7e0a404d9faaa000000000000000000000000000000000979ca2e81663ed61486c1f841c19d83549388d798da72feda82283406d4964bc9991f876a6032382c35b605441ee7da0000000000000000000000000000000008d92cf77b44c516c243f3e6a8a8d3f9d3d7405820ab972338f700de1dd9a66d33b4a70540a30f630aa81fe1cb5bf057e1b3071b561a80aaaadb5cc24b348a2b6012340d3aebcca7e2f56983a8a13bf900000000000000000000000000000000198831a40fec54a210a63f5e00b132bb1eca6408335b85a75e28be6a111beea3b99d9f2fe5091ab0eba0f082c201c14d000000000000000000000000000000000fe457f8d215f390000efbb7fe7193ba02a2ef78e9bff6539995f01604fdca9fa3c010276afb90215890f5a5df3ae21500000000000000000000000000000000076771823180422495d89c301443a9d1fa141716e5e27205b8cb6b461a3ded7e6f196c3976cd6ad56b2e6ebb6b3a70860000000000000000000000000000000007f666efc677f6f767828e1291bde0ba0ca445ddb2d69d5d2fa090ca49e697ce4e00f55d2b706454be6d68f012d76efbb6863b755d3dee61328a60f585531c436663bbeab9afaffac49b6f0b57614eaa", "Expected": "000000000000000000000000000000000e1268a5e2f654c4038647a910e6cb4bab1d6ca3562ad4a9ac18444c8b8a3fdfbd35acf37f9203041fd587a5175ce86d0000000000000000000000000000000005e701a8ddd15ecb0231b7625f7868c81467c140b2617e60440a9b348a192e5248b1b3c087545cfb6d173fafe48d32f600000000000000000000000000000000071327f52b1325bb664d32c513fb12afb96dd8da23dd91bc4c3e8ae5f97d6bf673a5d03bb8bdeb6da3144dedac200dbd000000000000000000000000000000001852b86d3ef45aaeb691f454a345ed61104cecf0f444e4d841f2bc0402ea1291ef056eddb3fc3929ef4623f31016c3b5", "Name": "matter_g2_multiexp_78", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fcd3f253d018ef09a7c6e8f36662ab4190867a197e0c42a0b425dfb5fe61d57596ada28dde0b093676ce15d03406d20000000000000000000000000000000000df00598337060d603607f3b8dd16f277ce1882a2e9ced48e1944662323efc29b33c807653f31583a5d2198426019ba70000000000000000000000000000000009876c81a76986435d34c6d44d51cf1016c19ceed2432ef1e68decd64da2e31e42372c1a41a514b0eac0ac103ab6f43800000000000000000000000000000000121cf298ff8f610c64ca4a887c52cbe940333506ef2afecffe266b5b585ff737395e2c64adc23b5bd232250e67c7a62613ca0cfc742607bee58988df361d7cd5d809ba4fddb209c898cd555369fff566000000000000000000000000000000001885d5cdc3e0e0c8cffa7519e6914e5d85962d07633970c4174ae4587853f13970a1f5d7ccba97458b9b5046847ad29800000000000000000000000000000000105b7c0ba96d5ce32d7447351ded3e3f491a0e741e921447b91f22a23b64c2d749055a0593e5b47f0ff7815e1a4c9943000000000000000000000000000000000cb88fc10c94642ae7e1d7275bbfd51a2d40e9b29f3d51a1ceda577beeb131eae4b17418f9f358d47b4b9c9ca4960a3b00000000000000000000000000000000131a3e080b1d4e936d97d255b07b09a6210b5fe6900da87b5cc595a72de2b6ddb01809e2dc63ad460a2926dd8d3b3b2ebcca8ab454fbc576a2b910f140b23c23b14301c19e1f47989d78eeecf279862a00000000000000000000000000000000066b31c0bc4b3b9fe420dc095d551903a2859556d86e210c96480f1d31d449d85ea292e2432babdb71c151c7b215cd6b0000000000000000000000000000000019d79a60793957745077f9233aee7a4f096515eefa7c49473f09bbc73fa0ee13a2a30a08bd7f3bc1d5c412d671fc37ff00000000000000000000000000000000006882160e4fa8ae2c2d48ae389d8f023e2775adb7a815edeba13728b8f6b343c45788c8e9116445e9989e01eb43e1500000000000000000000000000000000000ce53ab2d81ebaf4a85b3e12a6175ad7fb6cfbae207a69a0fe2195ab916fcb582b097f09d9fc565b837925f68855c4b59f82ceeb6160d3256228d7a41fb3caa6f305b23142ab979e728356a13309e27000000000000000000000000000000000a30d335c035afe459dc262fb1bd24dc0bafbc08fae0bed47e4e204280eb96595fada9c4332df1218748921bfb1274c7000000000000000000000000000000000e37eb189560211d6fe56faa3b6e710878a21907fdc1a9f8becabca290c24b8831e28ebb48d06bd822300fd09b4d103100000000000000000000000000000000104842b88b9df6a7b8243494eb11eb62c89d1ccbde9f55fe221c2366d6bc9149178f177628c6fe7c7661318640295e570000000000000000000000000000000011df8599d72b85ade11261076e02c036be5dfa3b6fab4ff72ed7413a879c0a0742be6c36a32d0829a4e3171b0341c6a3995f7d2038ad02deddca34399e5b5653fa471d998c52bd52241840cdb9202b2c0000000000000000000000000000000019f6634435be45b099cc739fe5c2dfa01f61fd2d466d5ea464053e2d5acf2e0e9448b1bb7770b5ad426f8a872c5764400000000000000000000000000000000002bbd52efecb10b3bb6f8bd04a5751042d8598cc34e2837184cea2b5953ec125dee871d1f2f57ebc84849e3a7ee5abe2000000000000000000000000000000001962b716342df9c13c21d89ab5b8c4c0ca191440fa709627e0f240a7ba518f4c95adfc5973b6ed0af591bb54bd00937f00000000000000000000000000000000089eec676276c52bfbb2593ef0362c12a5f3c1a0566d5aa862f5f5ba1580f4dadb36c15fdcf0c3910ee14487ff146c8997b67e68bfe2d7fc256e6aa610dd91dc1b02c64186d24702ad8fa9f715b582a5000000000000000000000000000000001556d081a489eba4fbb0c20e22b8cab432a9f6ff459ab9b0e7ceacbbd46c8e24a2ee70151b019a1b4bfe47d934afede30000000000000000000000000000000008fdd7391113e8d9865ef48b60acf921b17c50744e6ad62fa24abaae54836b3d59a7441371bdfdcdb251d252a43aed7b000000000000000000000000000000000cc66cdb1fe32beb91b05922f3920060e7a95467381d62f2f036e6268af4128c9516780ea53e873993744ce932b901f100000000000000000000000000000000151f94dec958859ecaeb810c4b1cc7a707d0e1671cd4a1e3c811910bc8b95c6c944167dd280c7fed22f92ce7650beef998115b9f84e3ed6947bd6f0e3c65361cf360a65bc059515da852a72ec5cd178100000000000000000000000000000000004f88568c7ede48d7476175f1d2e7ded4312c24934f0d47794705621f8aa8a5072b86cc41e187f4aeeb49bff17a4c9d000000000000000000000000000000000ca6c579e86a68b4041150fbbc36da744d359028993681c34e66c537eb8a0a0d55aeb9b8da7fecb844104dabeb507805000000000000000000000000000000000fec63c57d3d3ca98cd1735b2f59217e163ca53b07b4fabc4415b98377d87e75f0fcc9b51c99a57ff61ca8d0016a206d000000000000000000000000000000000940e9f93f3ccbe74c7be93236a2c440b213a014ed51cb57fa053495c3d6f6c8edc08ba8e10be26e5faa898162d67fe327370e1037b709015e0bf178a41ac55774a813368e11ef7a764eb48abe75dbf500000000000000000000000000000000055e4dd9da22201b5eb64e3b9eff2eab614c48450424491a85c18e05f50659b88e862490edd11ff980b06696b60c35b00000000000000000000000000000000018fab38f58d3d541666bc29b9e94cb3940f1794b2aa851d079b9aaa1cf742b07cd6dc7c985c7e4d7d3fe683bb15d618e000000000000000000000000000000000534de5e1c1181e951b437fd17993e995fd4aa2f6b28fc3612cd4db615de742e12d66c03b9ced538c1c7cde27752c190000000000000000000000000000000000aa8580f1da71f2ae9ec26f3b6466813a40ba5bd3f89ed0d42695d420032540194617fcc2f13e36219fc0cc3886a69c36bf5fb297948e0ddc60ba26e49ef2892ca008e64a22ff2bb21ff70c56112f710000000000000000000000000000000001804ed7677fa3842bdc3eba708bf4fb7f7d4eaf2f1a46193c861595f64196398622df4358b9526f33663138b24fef1310000000000000000000000000000000011fdd7e1d0c5adfbbbaa69ce63c7c54525091289e4dfdfb3de772a8d5a958581cc23933deadcb8856540e2d0dc564dbc0000000000000000000000000000000013fcf17235506fb194e3adaab881c7aba4b87e5aef739e0547b858410e3cdbff0dab1980b1b30a7d03d617179ae545c900000000000000000000000000000000004eed0ca479cc458231ff969ebdd4e33732953e9f5610d78d4753b99c5f8cf73c742387b8e71b9be074fcc67acd71cf6b488b6b63cb8bf34efeedd9f95dff4d3d8c067c0d807bd1e20bd267748275d0000000000000000000000000000000001082b7796d35e387df689bcdda6e0316d343dc907822d1a873adea050374962b164ed27cea0e1b834997f8274e4c5438000000000000000000000000000000000b1905979a90c7a61f4ee2cf3a9f4d6ed4c724c9e216981b8ec34fb9b528018d237771ad620020efc2c3cb104df667cd000000000000000000000000000000000752663e72390108288ef4de3c3ea409c74e7051505b12083c41a2e8937eaadbd8cd61f96f7991722226fdd02dd8d252000000000000000000000000000000000f8e4eb7a3c78b8040a115c42b5d2fc69405f8334e948b8553f444dfef29bf3920892da431cd8394cf61f24e356e95694f661845e91de1c09f581c7612a25bfa0889f77c2add31b493b37d20bcce11070000000000000000000000000000000010884516bb9916084709351ed8768c6105fa451e08d5acb233511254ddbf4e72baf9c43b56b4d7dd129a38f5b34ee5f0000000000000000000000000000000000228fc5fffef746419cc69abb17cdc63ded44892b8c5d02f0c72bc8506a61d15a74ec4ea0e1d78f555ddec07f418539500000000000000000000000000000000048a4192c204b7441e871076d91d4f610c347c2d71cf495ffcb2e2ab808a8c1a549eae96e657d756d9a3b94db2892a2f0000000000000000000000000000000017a94d2472df89104ed96e24d166f922bb852b5ad80f80188fce65b08d39cc3ecf94991c6bec5dc12f9337e7c087db2f8b3bf8d5e529912b1b6e445f592a6d151c6f5d01d3b021a31a2669df4ce02aa3000000000000000000000000000000000f6293fb0e19ec85f43a1a02df9f59ad4fb0e49b16a216ce097b8ec59e781fdf176360d8492e8b77674ae2c0ddb1da70000000000000000000000000000000000e354d09aad68fce6cde40c787ba1e4488999d5b9f3fec25c9994b56bcccaaa746c958bd16ba271485f461b0d4e983200000000000000000000000000000000014fca0851b0bfdf2c69fb346f23b46135d2b7914bb49e297a0c1304d8c2851ff6bd0a0bb364938dd44680fe86cfe12e300000000000000000000000000000000164e23a53103dfa332e5ae09c7c898b95773c20f019d8b794a6b49594040e2e090db6a8047c943885dca95188e89a63b30e1c8f222019b877e66df0b6201b5bfc5b6c10aae340c55e74410a536ffb9b200000000000000000000000000000000146d37241ce4f71017e4423dd0bf907a12c1364ae9fc6dfe535c25e5e99e03ce157cbba2675829b396a69f92668107280000000000000000000000000000000000d5a992f5357615f436d95fa516212812f6811dd1f1921ba4129e84e3d487b6c97520995d8a65f6771dbba9d150c7ab0000000000000000000000000000000007b01f86574a9cb7eb3b9a19b6040055a5c11b13e7071078d16b9ad71f714ed28ad25db9511964b156ee34db22385cdf00000000000000000000000000000000154c29c6e2b21a75b14159b183e625c98a04be1850b22d314225e94b313619f641ead73130c1d6feb85abd8c9e172f6323a258d66f2296fa1c71065cf23c994eb8c6c35d35120d16790fec791ad215fe00000000000000000000000000000000075be2703b8416fa07a7cb6ae8841dcab1e36b0ea24231dba617a2fed3bebf8d952d31f68c149dd17eed136fe37b01880000000000000000000000000000000001156563f1401b731cc23c4be59e69b0e6a0827df4889cd9ef9e11310f679c1603a0d9c9679c29b8dab75ae51f49bfe3000000000000000000000000000000000663faacfaa92fbc095a5dd6b1f2dd141e248f84eff1716ee71bdffd4d28ef1f4c88828e3457e8ebf0daba1416d2d6070000000000000000000000000000000018f2871f5897aad9ff6ac45a9c0e78be8f312f07af5f1dab2bc4705558070abf367f1782af896288a7754da82bf1a5141ef4055b85f37b548dac2b64608d99ca293548bebe1e24355393520c34eda60a0000000000000000000000000000000001618a284286899f501f46c4761c93b68bc8ab3157144e4013e242e1678cba20a2d978ab53b4b43145dd6062748df541000000000000000000000000000000000c25da737368775e41ddcd9c64cf99a824afacb1d404f1ef46ec7fe4ffd89673648c5207551914e6e0d12c57e7d7682c00000000000000000000000000000000097ff49c4872e2da1f6c24fd6dd4667f0bef4eb30fc197d13e8b66adc425e39841dea011d79e4d775106a19ea1978f4c00000000000000000000000000000000147426b7d9b0bdc2be051d8f6cc4249014e1bbc2369bc32eca94684483f50ced2c07be6a320effddcc1ed5cae455fc92212529248c51c95b5b26961f27e6d44ef1c2b9233bb2ed32c3eee79ca6c6eb750000000000000000000000000000000000cf68f7ab056c4689af95b361ee3e3b1c1c48f18b5aa655cce1a2be217010814b3f07dedf6f9a7b835cb13e2afd7136000000000000000000000000000000000dd6d0fb94048dab34410dba4e682f020ed54a655099fbb6f6e94a31511960f0447d7e94143eea88195291b225d11246000000000000000000000000000000001864c6ad3f2f794239a179647d68734e23b3520b79952bda20acf2f5afe1b76bc18e35b852d35a5cf3b02a3ce86f640700000000000000000000000000000000015ea24562d7bc59d813b77b2a4943f9e98842b5a41c0c7026077a02ddfd3d5fecf352d4399f507fb12ada4ac495ddece9888dd839d9b8c236394c44d358f452a4588ae65d24ffe2bd345fc745de9d37", "Expected": "00000000000000000000000000000000080f0e50f90e001a442965ba7900997fcc89246742590b99add6d90428d3b61516664654bc8fb423f701e85a342a668100000000000000000000000000000000003fa9e84ddd754047649b7cfcf5bd78852abb298b3bbe6575c4c7dbc2e7595499a9f42f379a2463aa74f29e5c73a9040000000000000000000000000000000009e72d3c418726f6400b8cd8b9b649005f3b25ade40cd6f77a0c3cbdbef461e917d4453c9e07ded45301d21df4ec44db0000000000000000000000000000000015a06cac223217602ccfba4f4586cb184994bf08b324bf977dbb3884c394aed0622da7dcf5712970554d73b18e2733c5", "Name": "matter_g2_multiexp_79", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007340f432a5cd5aff1a1d98c6ea1c94be24de2d15a4e112925586c30979e23a5db93643308d3299e370b1f26bdd09eac00000000000000000000000000000000155027caae88381a60af71b2fa770e58efccfbb7642f5ef6b1591bf77e415eb117ab564aff8d9ebcd576f813b793ad2c000000000000000000000000000000000f604238d1b28f010ce8e45f2fe61d3ea20b902a4debbabcd54ce0ecd44a9540fe2bfe847178656fef0a5fd7e6d012b3000000000000000000000000000000000d7f503ede395dfa5682aadedc98bfe28d3fbfb52f42ecabc9eebc0e0a6616d3671604709f28255f50b62bee641d2711f812322dc2a7d5faa9e4877638faf8492d84e0f4c4c65ca3aadcb7eafed2106400000000000000000000000000000000176e1f9eac4dab0d253c0ff41b7600437b53a5ac5278d544a9620648e0bc4dc56aff0bda973fd1338f77fa174d8b13b90000000000000000000000000000000012919a18343cc166e2dfb92ff07bbf838779ef0479985bb85b3b82f9d0632b3f7a19d387f725a21729a77c58dd4d1d1d0000000000000000000000000000000017eb269ed75fe0403021ce70505bb60a711c91c551931605bb2a0773fafa07aeb47cdda382c0aa64f40f5e6e0e6bc77d000000000000000000000000000000000bed8ca999a4691646124a140fcc17dec02b74bd28b599c807abcaaff13bff65aff3892897652cd33b4ba5e4cc0198a9c1f6d538c5b4ae15c84581f8fd4c61160ed395816557fde197e1a013ba41ba0f000000000000000000000000000000001344d6902f5fdbb59a4c975847db0191beac284eb17cd92360e59f42cd7796cf2aa282bbd4cb074c4ee10b489ee3f2f60000000000000000000000000000000002158eb3429d0532792532fcceecc404e95a879be68b3685ae94016ca3762438b3320553ab6d5fbda3a0b615a04d996f00000000000000000000000000000000118f6fd8f60edf7088a0b4b49338bfcfc9c38be230460d7516f317b27c07600f504c8cc87acb0c95515c3acdc1b125ce0000000000000000000000000000000014eb422d44ec6931ac9860a6a017a907e8ed76de91bb7557e818dbacb19fb51457a1f45cca91f1d1d75a3567a3375b5cf2f6a4713eb692f7667fba2a3dc35363c3ba163519d95757daddefae11a95853000000000000000000000000000000000f2c72c53fdb1b0cd13a1f20407c64c46e4a0e461778b0e2d48c4f20be7c655c639b38f758fa9199b8395f706df10e7a0000000000000000000000000000000016e6c75cdfbc20c5dbc2dbd1caa66be92911264d407ce3c689ef3ae1dca44dffacb4c0d8a78ac959e47ac5c454f607bc0000000000000000000000000000000011c5d80d52e864b0a46fb48488f497fb85f51ac040c77b1d01336860b972858c0a6e59914112f6cd6c1612c604d26f56000000000000000000000000000000001136aa7eb63d6f85d665d0539975a9a51a9a3f5bd8731910c32130b1ec8b07c39eb42e4f61e7d22bed933d9fce1810581022e50c3fe7b2a65aab79de6d9e47c457d197e145592dd0611b1dc39941513b000000000000000000000000000000001306612f5119d33f177b8804443d14d04c8e059e28f63aa10ac6a1b25975327f378d5d24f0236e05849f07e99af93ae20000000000000000000000000000000017340f8887292264d498f84fce4af83573aa6cf1d57d99d364f2b84e1734fa4f9a1e07ddc81a2135ad5f5e0ed2989585000000000000000000000000000000000f65073250019ea69339379aacbeae7520c1ae10c8912ff827b702bdab2e15404cfc939389587364d811054b7d9f2b350000000000000000000000000000000019742f83ba0c9d36aa1d595fcedc3cdfa6c6f08579e66b8956fb32ac03530114ed4266738c57175e7a10313c8dd42deab80011c7a4aa905d4db6d4f6ae46eac9eb8bb18613d4ac5e5567990d7e8fdd96000000000000000000000000000000000b2513f906db531d052e8e6f1cb8d7d3c41c7ec3158b370268d1de204ed8fe7618b64ae35029d1718153b5bdb8439dd90000000000000000000000000000000001664c367a2d4170f463c90351cb321608e2a49fca6f3258bf10d32c39747084cf9d2c38d5241888aaad97985cb09a450000000000000000000000000000000014de15b86461cda9f1be69f43a9ceadfe7b7d1548a206f3237d93c7c01ee554c4245fb73827ed0ab72b99a62215faeae000000000000000000000000000000000b25e458522be9fbdde4554b1a0d9af157aeb7d3ec1f89185b193c0429125dafa554d7a531ef9502d443a26112b940b8f397789685a736375ead2312874174795586e12b230669a90d072fa636128c7d0000000000000000000000000000000006862c0b0e3d7bc4507bea1df82080745aff21b7549b372085776be2f88aedd4cff00ab8258aa21e63340963bd0d937b0000000000000000000000000000000017199c5ec3a2dbc1f1e8d74648cf8da247e35cb07df22629b3845274d29e473819a31bc344f2a2bd6c790530cfcc0126000000000000000000000000000000000e7fd1ff41d86a02014229c5085c886988dfaddcb60f5c7c81063e8289aba846337d61bdde57e276fe6c65bdfb48751f0000000000000000000000000000000010efa6aaf7650edb0c74d30125e36cb67cffd1c7f57932d92ab4aaf36f8d9245d7c75dc2b3bc8f3f328589b16e26230e28e325fea39d61269c576626984f85ea43cd683b08c3ce111aac0005adda39c5000000000000000000000000000000000935de4b16f5f9c0accee77b5820cf36c24aad9953d40a2409b7e6040f09f85da7d2252843f9f8005316146caae539800000000000000000000000000000000008a8c542111951b32bb0b50f7631f8938d22e298193edffefa3e0f5c861ac8205ea9b865f9420ad74cd22b37c5cb56200000000000000000000000000000000012ddd660879a1f52ae6284e14f2ae6ea381ff3f321458cb76bfa566b04ae19f3793468d0aab652a82671be74332a3b7a0000000000000000000000000000000005eb148c35732f7ababc73861b71fe4ea5e25bcdd675e975fadd0a9e0fc54e175b2e39dcf0323f4a9802a68baecd25df3cfd9bc41303803a0b4edd121b818a126bece309dfee4133aa5314cb8a91d08d000000000000000000000000000000000bc351eebfd3f3c332268055af1655c8729cea44eaae803607198cf747280adc0d3dedba137828834af3e7179ccff4c3000000000000000000000000000000000d8a6cca17e1c6ceace7c0ab1333ba76ed6c3b114bf99ff80127c6a17eb0585bf6fcce871deb7385e9a8896a21c065ba0000000000000000000000000000000013222db97e31e28946adecda10c9ccc9aa9fce33e0aca51d6483d2f0c5bc3f33994ad516215f8333e22167164ef5459500000000000000000000000000000000144d3707b1898d35c65ae2c89b1570971a9494e8bd23df835f565059554eb7b5cb66a6eec890058316aef43d6c6ff55c8e08fed30e422868f37c422d1efdcc93912d55b0a731479af863dca4705e0c5000000000000000000000000000000000138da93a9a4948d41a6fc6d057a217faf5efad863b45ae8eab311360c033362213edb0ff90bad6c95f60b8e1131336e6000000000000000000000000000000000f41766d9b57b3210d315a2b8f90aabe591c1de6037ec79c0d72a283f0ac3094436bb97b82b7ad12ff4f471a41227bb50000000000000000000000000000000009aa4f5b674782b7adce6bf75ad676480f96a58d68dd7ef8d1fa488cfab794f06e7754e9315430189eed265913db8b300000000000000000000000000000000004e2a4a48f02079c0ed50c1daa91b1216af481a982c7aa64d8ba90449ed886cdeddd0cc08f1f8764f7f8c5988fe677f5674ecdf795b48d62f0db0f9cce057fe570d15c78f2eb7a77b66e4895a45804880000000000000000000000000000000019c927bbffd96aeb9342666e1974d30f9dc215e8eca41c24244c63c106331ddad20d64c79faf8c5baa45cd30b561e167000000000000000000000000000000000523f063de96c9b77bfe5c5045a007e155b45dbe68c5f1162884f1d942bb385bd34c2a37e5e67e6dae4a23d600d75d1f000000000000000000000000000000000c221006f5bfc8baf43826258d0588d7c0fc345d68de1add1693bb897959c2cfdbb9c165e82c0c787529cd7be85afbc50000000000000000000000000000000004218e3d52b42a4504611929f94024326f38e78bba2aba105db3ffb4a51f8906b060ce2302e22ded60714d652a234c1f288fc80d07393f629ef2732879332a253b49d26ca7b2bef7cc49ee40530b2b3400000000000000000000000000000000189e5063a36b0edd736bcd9f997f4b08c62d33b27560e2e2b7b40039e7c63b75757f23746e70a330110d975ca683941300000000000000000000000000000000013393485ae494b1f1467cac9a8840c695d619aa1a78c40674038c053f264c1e20481f2005abc7f0545346f5a982d05e0000000000000000000000000000000003f2be501504f4d37e12acdc54b3280671ca0762a063fd3bc04473ed5a051cae3767044c002b7ed1abe88b2143af08750000000000000000000000000000000009d5952af88514996336e1ff19409e3e4eb3079f6dea22f9738f4a331ce842b151e0b842b68cddc10a711afa6d3242b256e69f4ce8fbd8f86f546fd6d129f9760edce7c5e178dffaf987bf565e9bb7e9000000000000000000000000000000000a79444c673e630f46bbc5a9e06e8c023978a78e3c58d72910a04c3733ad873c0d0de61448076b2fd3764cc17d86d94f00000000000000000000000000000000110cfd215d67d4a091578203855fa0e85feb4dfd0076fbfad20bd092fb91b528a4117850955f5fb6568fc5844e17bbfc0000000000000000000000000000000012ece0577512182c50dbb4a485256e705410108d9ba9c8d57780d49e2e25a0f89ed1fe917797b902aafcb8f7d98fe931000000000000000000000000000000000217cf1dffac7ae162181d43ef12e3e88da4840f1573d7ffa271f64d8d54861099be37b644e96e650dc613975d8a00a4ab40e86212189e6f5925df810141c132eab20c123166cd8d3c6f40f5dcf1b1cd0000000000000000000000000000000010bec428b2865aa7c077c168dc28dc549481c6f8367a5b84cbbad661b0225cf0fda3e840d96c4e4efc36c20d48f23d5d000000000000000000000000000000000ded3a1e9e2eded0a11211a217f9355070361f0a5887a7e19c74edc8768000311cb9dd8513977ecfb45416cda0908cca000000000000000000000000000000000b99ffddc79e825f0b73f2d0229d66e51624d854d00bdee5aa7a884dcafa1888963e2a2149db0f6e40ce3c67941a391000000000000000000000000000000000147618970c71965684bdf0d6cbe1de189bd23bddb2b861c9636efdcb7a96dff27bb1ac70485b562e78485a1e8e56531cb96a5b6129c58113bca713e6905c026c0bfdb6d679c203cbe2b256b0a49ecece0000000000000000000000000000000001a402aba8fb28dd37f1be11fca037baa99a6b57188ccab66208a50bb6967dcacd1943cca73e34f6b2e2f72407103a73000000000000000000000000000000000c0bd64d043fa4e3ea566cb84f9139091891231ff500b67e5fd451805f79003f6303352a4f0c236063d60d9088fae88c0000000000000000000000000000000002861fa7d0222711ffcadac86e7b9e7b494f5561c22544bd0876fb6e1b2e680d0f7074c2800312cb233de2412ccbbc8600000000000000000000000000000000015945f0c83e738a17cb1283d08d63ecf12a7272bc62812006ed78254bfc45ca7c42306cb79bb16ed17bea600a4d62b5d9d8147c4453cdeed971242d316e350abead3dd08e93ee54738a4a5aed23affb0000000000000000000000000000000002268793f6872f7715d802c0d96f3b3d850249d8e70aaa97f19793d2c92e7cef384aaac603eb51525c7ceccdd0211fc40000000000000000000000000000000002507d680a2db16746810e966d1ba5547ac98d08c8402aed0859203e6dae0cbd87a9ddcc05119c1ca08fca2fd733882200000000000000000000000000000000192426b6438b2abc7386599afbe09081ed4908fbeb807a65bcb7c6676aa76e5e0c2c87612cd109cb124c73b9c8e0591a0000000000000000000000000000000017f125a2ef5246e7a19e1b2741b31b9224511ffefe63ccfffaef1b7949e88af573e267d6c7617ea97bbaee6d50eef67e1ba8e52986d3bb0421eb53b18ca8c21b9f7e631f16b99ec56748baeb541b32e5", "Expected": "0000000000000000000000000000000018c2f533f464f9768308a56209711cf9b6653e8d38591d782ae2374905f99f75c0d42c63af4b534056c28599a9da874400000000000000000000000000000000071d4d708f00875545f381e164f77183e14faab599e472b2857c15091254ddaf5c2e9df809875336f92ebcf5b7628da500000000000000000000000000000000099b207cf6ed022289c27393c32d0b83aed6c7b57323e746374c1a8e2ade071a5293168e72f7aab82f6c2e39b97b03830000000000000000000000000000000005dada01b4dfb6a52d998210a67ccedc11d6aca2405e0836280e2f7c8fd7c8dd271c815a2e9ea1dba6f1ab0d6e89d756", "Name": "matter_g2_multiexp_80", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000195d3f440857011bf9b764ff270b8ba1d9d13daf48933e49c12ea20d335b58bcbef1353d9698a7e795b4370ee385f12b000000000000000000000000000000000716c151efc6e611b5b15c749eaf02816a86e267428750741b167404a21116f2025d0d07c447b9c7bee8edcc2c7b76d30000000000000000000000000000000012ba0bf62b35327111d09b402db2b75b2e835cbe581638af2fdd6d06034774533e6501be3de84e7075e4184e11fd81a8000000000000000000000000000000000329b14859d004c146047b03870371f53936e078ddc69294ff1fd6f42cf2a354a921e5f2e5c125c454e20af97dcf769e7d39b55aadd47afa3cd35cb85a89e729ca236ada965b99f64ab302a84952babd00000000000000000000000000000000042286dd205ac86fdec3fee779059e2ad59adb62505f7b78606c128244b031c53dc40ebc2f5afdba348892d5ef4c10e7000000000000000000000000000000000f960010d4818846b3a0291c6fe1aa53bf0eafbc0e0968e3ee82324452a7c1a8041c06b4db9cd36a07c119c9fd2f9038000000000000000000000000000000001876da0dca72869708b8ff9ea0b74ad6be25ba82ccc76660246413a04344f2b72e5a7f6fddb58e9dc0bfaa6b33a5fadf000000000000000000000000000000001538ad1673f117493d998941d9356fb9907f70c279bde8ae8813b9c7b371344456f8e67cf02bf3401ee06d55604cadf9c41ece17a6d8b4a22994227b37a9d73e17a88859683afd5d226e113246e70cb1000000000000000000000000000000000d91319b4a5e047ffc8a68e10c34b2b90e7f3f08f9e3ec53ed12bba5f66c168c20c6583ba2016f0137caed834845f7470000000000000000000000000000000018d5542919674d2fc32430175405d806ae4abe3e1236df2188bf4c9ddf66c0974036e28414890212ff8dad244d11e3c700000000000000000000000000000000160b128f1ffeb97edf0e62dff85e3f90fa48567ab777a7937a2c0e4659df180fae4565107c2236a5f2808e42a03a4ab40000000000000000000000000000000003ee74d214ec491331fb9db8243e75570daba9feb587671496cea4b480d80ee162c6294c082203534bee450c384f645e69700dfa3b6e5fba735d1fec3b3adc90719ec301c406ac40673f4e5677da3227000000000000000000000000000000001951afa33800a366944c43bb42b8c5c8beb9ea2e1cead8b84e0f94af51e4a156d9454c0f08d1b13c692c41cc480fdefb00000000000000000000000000000000077f4543fadad6f2f8ae8d5d98f64965bf9626971e7efef5221cb4d95d51b8764324cf4a11d0ff5330d58df70cb79d92000000000000000000000000000000000417251cd0c1b32505377e51bb30ac8a8a3c059644b9ddb5a058b3c6e1110e1c71ee19f549b15090144dcf4668d0d50100000000000000000000000000000000052133be345adc562238c4ecbaf76ca4159fc11ff563ab393317b03065ab668e7df401831baf7027f0577f5791b1ca3019e8eed297661c06c92075629e163e80a08835254f7af8c0f179400be114ba7b00000000000000000000000000000000067bd52b7a3193d31a4f1ffb76432c8d4108442616f17056d310fbfee2ffaade9437e2bdb8425cf83233f0c632efc1170000000000000000000000000000000011b045d6eebe1bc8218b696b5e81e78db78eadf1b5d987060c1bdd73aa65666f77e1d6bb6f3d939d64cb3e6bda08994c0000000000000000000000000000000016eb5ea5067413b72632f5300efbe0d01a284b2a59b68d0333c269da9302bf0f0cdc923acb27e51bbbbc1d4086e6b06a000000000000000000000000000000000ff37b8812963d9efaa1e6deb5cfd34eec70620fdb65808739295a819e03ebcc8f501b8194d0b3c72717fc922b785194199ca6fb7f6df8a2e72971c5738ad75d84935e922587acf3a6b6debf3c37bb5e00000000000000000000000000000000149b5e0df255281c1b518427094cc0903fe89eac9a6dcdc379b8ca30f3696d89824c201601fc4b0795a3c859a82893170000000000000000000000000000000016ee9e7d957f439d078f3c5da98d114a1b5bc4da9c17e117e1f540dcbf83a349bba94def4b87b63247f190e3b5813cb00000000000000000000000000000000005d4f56bea105be4bf1fcaf4f25df30f85968d59e60b1c438c28ea0f480851f5ab9c05a7ca6677e6f12c7dd3ed67c2e0000000000000000000000000000000000dc0e87ca5a8b339b485ff3da2b9854a07e9663c43344dfb5ecf3ea055eadf67405c43013e15367fbaa55f1bd8e222f98159c6b98bce6ed31c30957280d8f7820e9376093d1ec9ac68ce0777d02b084b000000000000000000000000000000000b0575fe2adc9ad66209cb2191efc2946672e4e81b96d50493d2125d9c83165f0c4d3f714539eecef9de0706cc20da9b000000000000000000000000000000001511649f0cb6b86111d2830812231ad37df5500d7ce1086241591dc3cf40b30f1c53dda3133b2f7fff253c94d5eb98720000000000000000000000000000000005b15e4e32f4f4e46c1560792a9973f6ad63f5176694734f379375f16a08c162a4a820385d3ea6c191bd87fea4f5c8cb00000000000000000000000000000000089218403fef08dcc6e679b49a74557dafed3278d41ff36a9801db091b91de0d46d779a40574fa4a3f2baaa1a14be098ef1bc580e0b52b10b049f07d5115a60ba96d14a39e48ddee3c219f11c3b2a82a0000000000000000000000000000000001c35a3fdea92b28c9ab4bd9ea592b998853a73be844b9dcb500ed6704bbf3ca4ed4216dc24b50254b6ca75c4ca3e7fc000000000000000000000000000000001815292d2a365dd7f41ecf3f9a89e040bab717241cefb3155a097eb9885d64fa55f5de7023f2ecfd33f483ff304666520000000000000000000000000000000013df522c72805b890aef97864ec6769f569504fca2d6a6beae97f80dc92643f8014daf3dafc0040dd7b985c0d9b2c462000000000000000000000000000000001155ad4373a8304fa6301cf48b4ace135d6a0c08cb06d624f42f88073e43612ced3cc37235422171b43af2b4ebbd5662d06f6ed682c56611fd060ed2b3b1dc48974769ed6dc504ca3e0b9f68b77e63c5000000000000000000000000000000000bb9afedf7417ca31beb96486b024af13c06007585d785efd1e78444daa9bc3c03e1d64b560e8d6a18ccf77a8c3c8d05000000000000000000000000000000001652d3adcf1612e487a9ca198801afb9ec30267148502684c2b91c05ebf6c48e2ce33f9c0a986daab81d5359ec1b503c000000000000000000000000000000000baf3d34bf4a78e3b9dfa637c6392c7f4d7ad0ec315d10748784b5b60221bd9da0f4b75c57c139ac2db329e270d559de0000000000000000000000000000000000c30e553fa2324d552bdbc7d2dc86531340c4894495ee9a38b64f5bb6f92314021a2a00c4bcd8837e55a0ae2676a9b761d7b314ae9d9e78f628ec5a207d12e2dcb690688d256fe46e0affdfcc9775ae00000000000000000000000000000000159a1e4e87c35aaaeacdf21efbf8ed99fd6a2ddd7e990c12407b1417edaf185b8f1df9bafbddfaf3d581b5d97d7718300000000000000000000000000000000012239ef7b1e1009c81098aa4aaad8ee9e003530db5afd49867aec47f46d5e29d44b5e62d80d9e832937a299633e863c80000000000000000000000000000000016af6f74392461a9294d9f848508651ca5c0cb50494ee7c6a334bd770580b924a17beb7824b489e7e101ccd50aa0d5cf000000000000000000000000000000001912a0f54ba4fbecaa55c150ae93455e1db6b238c032fa7992bc8456f183c09b6005dd6398a77ab91cf547919ce7485b03a0c47621401fc20d2c78f7e30814de9a6f838d4328a5b5be628b833c31a6fd000000000000000000000000000000000cf1cf7a09a12f51d10059425042ef8e140718ff11d2f17897a0156034f73ed29496d93b8695cdf609280d319c9bb742000000000000000000000000000000000b2c4d26fa1eb72eed1a24f27229d2675e0c6f91e3a4eba7d34b0fc1bf5a9b4eb49c3492d9586669abaf25a656e1f95d0000000000000000000000000000000012c5c83a03087b2449b71e9037591fa265d710ff6d869bfa18ac37cbdcc93024f673128db3dbad9e3517501af12f2540000000000000000000000000000000000ffe5824245e43953e3d0adcd5fdc1a97ffc87f8c5473fdb0fed57000fd126a9925ba7415c698248c51c1f3e12b270d5e4ac6a5e740e073c5ef8af389e70c2cb8ee8c4c04c2ab4c48c579e83e181005b00000000000000000000000000000000036aa888e40882b2d6ac71d66c88543e32b4a0a7c959eec560e3d26114d8aeca63fd87dcbb3171622c989a6c7a204ac60000000000000000000000000000000006a5e552e6d2dc95ab8636a8be16bc79572b47860bb88934bf04c195ec01fd71eb91e45f24c58bc2812ed5fa10c8dd7d0000000000000000000000000000000015fa3ffcbd4e562a4bc29975cf8c1eedf442e37374fc87128e6f68bcdf6e996f6f054e0b8c608e651753de96655b2c100000000000000000000000000000000019bba7c0b170dfc1f8fdbf7a2e09ca0c4027a6aa6930d15dc2772a0f20e5e56f0d11644094dc866595f801ba5552e6c4c1e20d8003fec60f68c03942185fed934ebc197c2863174442d1a1c8d1424d31000000000000000000000000000000000341f46ec06a8def4f044328bcdaa308798469c767d10e5db34b0ffb6f550421c67c6fab7b63cbc7504e55847cee419e0000000000000000000000000000000006952e5f791c37dfebcfe69cdef196dff66563b29e94927e3ab34365773b93e72251a63af4ff294af88d45fe0899a2c3000000000000000000000000000000000874dfe75b31450e99dea063c090e32d24fbff9b681b64a9dca5f967f82003005b003d17eb869bd3b37d4a412bcb28fb0000000000000000000000000000000014203b69e8af4e25232777f503d5e82d6121256fafdff1b037f65d5aaad0f09ce882151d6bb4705328400f00089dcc7a7713ea72a2ee99442232472ab3dea9307a02fa1279129d994af5588af4fe7af4000000000000000000000000000000001403fa3f418107e0bf7f3f4bfcf621812d32b1b744ab5a4c37b5cf946a5e5dabd675c2b70bd355590a9883436c5e32dd00000000000000000000000000000000069e006f168bed4439fb46db9ba4f279f72ed608c12a05eed172608693f42cb1f04aaa54191f4b0b35f967bf03d0e63b0000000000000000000000000000000003f9ce029f6fe605802de64701ccdf52bf4aa299400a6e1c36f5a1f9173bc11a38e7628f123fdcae01d2b260f77c577c0000000000000000000000000000000009c9732809f60635115cb479c80457c6cd8dad092111d663c0cda0da1fa71c9bd6795ad013d2efaa4599c8ac5c88e5f26f128420cf6ab4616a05b287191105f25c7212f2c39c3230fa56bc27cd06ebfd00000000000000000000000000000000115e08d8e4dff7adcfe46a416625be0ac26ea2d7900f5fed497809a6d46e7faa5b47c52ab3bbeb9fb16d82b549707ed6000000000000000000000000000000000dd1b31446e44f64ea5046dca5174ae854f6bb5d95886fb95aa136d432f1a8c03ef1a5f9320f89c82f764049a7f678a40000000000000000000000000000000014879783c07e6986cd393fa1e0ca8a7e23b2c9efa595229fc0b6a11b9c232ba33e92962a1087fe2ba0532d7b541827900000000000000000000000000000000013dc6e2bdb2801333e7f914b99f30b40125fa1ebd49b141d88a8c090b15ec3250a13812a19c3c0751a4e5ed100a6f0ba12bacb3419c34369dbfd1c968334f76bc50885028758a975cc812a04e6feabd6000000000000000000000000000000000a2cceef36ec78dc702b6731dbaf8cea1dc2b41fee1b235673c6941729bc5631e69ff37900479391a4d10b300fbf3eb40000000000000000000000000000000002f4881fd626f4ac434bc1e59716e5e5ee14dcb9adca4d639ebc9d86e323d274ad8ec0a4b1e6ff92e1fe7928d48924b000000000000000000000000000000000174cac80e7bc63989f58759e123513b611e9849b44d43a362f2eb84421ad008f3ae9e9f0f233e49fc8e10c1824ba948200000000000000000000000000000000143641099c8a6c8153dc8ce74debe795dd6c4487e8234f164f9f8dcdea6a53619c04a8fac215421f985557b5b956c20a5b00f26af6f59620c7130a6d12cf2091b5f52a6b638484fc1f242dc1773be256", "Expected": "0000000000000000000000000000000009807ffe8fa881b235b1181d2d3f147dbe21042524fb0c0b4c90fb122d160c7b895034ab32e20324dfca564ca6e3183c0000000000000000000000000000000010f6da88525da3e86ee56cd5514a436e3ce4128e437a876be130a70c42444a05ac269326c84dca532ca2e546860027c00000000000000000000000000000000011396a7317918841ba171ea46bbddc9bb5a08db7c82b90008c6982b4b79a4dafc151081bbdb7b9fb79784e603e15eb9e00000000000000000000000000000000070b8580f303b83c643a484dd031b780ff4ca2ec805d8c538a0b0c791cc7f8163654f5e5a41776a8681500a6690e24a4", "Name": "matter_g2_multiexp_81", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f38906bd058e4d32403fc3d39fa57bf49c0da65ef42fb129332b91c184185de4f9f0bfe8908a44833ff4ac4d65b88180000000000000000000000000000000014ea6fffa6dc462463c15feace841697698bc521f608ed0d16be5097bf42aefcd1f73182f37b6279f989e9668a8076d1000000000000000000000000000000000f56d296323177ce53c6977fb60e445278e59ed1cf92e3f68c570eb7a9e5f8afbec5e2ef64674bbb54d7016c829f72750000000000000000000000000000000001b29012ff3460cbe4a07bdc65885718f217cf177866823a7cbeae18bda67f65913ea20bb69e0ffb31bd82f19862113dacc5a8ec806f2f273120457865582b08697904a2c6510bfe9ea21eaf682fa4fd000000000000000000000000000000000a4126bff91ada057ceb9a75d577120c7ac8c9ba62151602414364cf88a3e12dfac90b5590db3e40c16163177ad4e7520000000000000000000000000000000004a3768d326c4ebcd5ffed89341e8d04f89e674f3f2aded3205a7193e11c20115b3c4d595b959d6e39a03d76f6b5925b0000000000000000000000000000000006e0ae4a9c45bb69c3a1c65e26e4869f2eb18fefe584e4598ba99c0044e8d911145a5db3f57194ceb6201e7eab9a81b20000000000000000000000000000000005be2ba6b147f3f2052c4877c90ca364427c6721ab64dd35e89f14f3179564d8812b9013e3e3db22f69afd739229682b98c15a259b4dbb8c300a39f0af558a9827112f6b4c5eae3d43bbfe057eb113cf0000000000000000000000000000000004c36cf955fc81bdba4ea8d2ecf934adaa57fa4073199f77bd0428d3ef80a7d7102179d4a44ef0de887bcb3ae915408900000000000000000000000000000000138bd3ec7a1b6fb65d1df6bc1d2ada35aa52b06729c10b5d45b9bb7cbbdf41677942b99eb9c2d32e3e73da7d5f9cfed40000000000000000000000000000000000b0291ca10245e2f7a963fa07ec62b15f6bf9e7a5a7839840ebcbe538dfecaf2114c7864a16564a5b3c85c15d97fb7a000000000000000000000000000000000b436e912b8a71cf8050d10d59017eca6e494e5440f02d2816924ac9cc2034bedb1cce6eff5c42f3dc57a74cf1b51cc0a0e68bdc97fd642581f7e62ecf134df2c05570713c96fa733d3db96ace88f0f0000000000000000000000000000000000c105ac7475ed9517a0b07f25a030a5616952d817f3893181e352907c7cf4ec9f5f3006e37b1da97e9cae4a1213584e20000000000000000000000000000000002c112c18268934823d5946d2322d0faec497d8e18736da91d2af744d90f74136c49370a4b43952152c62820d25e52ee000000000000000000000000000000000fe2818a397d70543e752e7022f12bab10f1b1289cee61a0230d545296ec872e34d8df6edf7ce9980f3c153e6e51d96d000000000000000000000000000000000f479e6a52bfaab3a31aa9a461adbec8a390daa8eb6273f9e425eeed764a6dbad44d12778bb888aa5808df272edde401e5512cac411cd103fcd7497fdf47d1221999bcecdba30467f06ec356483484fe00000000000000000000000000000000016106cb42ffc41d5b23bc5b06001473bdfe556d375fac6a0cb0a12494e9c02ca2dd6133356846e1759a2c485faf5e890000000000000000000000000000000003cec25b0f5d1db0ead5319d6dd15517657d1fec442facda4335ae0bbeff606fa9caa6a4c00445001180aaeef895d7fd0000000000000000000000000000000016ce3573fbe27a8d23b3ebd22aec989d61fbd0e41a519c5e2f1d650f2ad73adcfc8c840fb12bce83b722a0cc69164e21000000000000000000000000000000001434d13d44fd8dcf776c2a045734dff7c09ded31c9e3a4b5e765cf26fbfea4cbb4ac15c06599012a7f2cd572bfafd78ba32f6861298bcfd4668653544b4551d7357d64f733365a5f08ebf297a09fd4ca0000000000000000000000000000000019923ffba0d08ebf1bd43393142d61022430356081c18e37804172082c7ace987ece2594f4852e84604a77235c7795e000000000000000000000000000000000123acf9e1a86846ae27d5fc0358afa34fe9d6b68232c9ebf2d47cc169779c4bd24f225ad30886fdf68166adfd9898abf000000000000000000000000000000000a6061d4cef29d1e3535d54a2e36373e2c16f91543f53e1aca94c4abdabc663049673f2327ea8bb574244d7f5c99e981000000000000000000000000000000000b1f3e1d43575a74584ec7a3280f8b7196f9b99b5e911ed33ba6bde1188c82d906f0f8e6fc2b285fefa0ce59116e449524301fc5c3ab842d7f6a278fcd32249f1daf86a31dd254ab9a21941fffca98a1000000000000000000000000000000000373d36dd0fac76a0fc46ba5da279ca3be5a1f8d799570004e429256787110d4fb746f65a8527d0ba681a81b9980bd5c00000000000000000000000000000000057933c2b3e482ae026159211c4742264f7e890efbaeb6e14f3bf66c80923289af095dc97b751a117e181ef917d049b000000000000000000000000000000000068816ad2369bb57b3430c657284858d3736c327284e7410b61ed444786bcb34a66db9c16aca583aa9722aa8d7975b440000000000000000000000000000000007fcd7dbc062d28f6ef906f6a455337e517e1d6e6c02c7c0b2b2685b79f56ca3436c1bfa0ab96e4a5eb0c2e2c321c0dc17a920aef58100de67c482ae1fabf7ec87cf3447bde1e19d9aaff825695706740000000000000000000000000000000007bb0ab060cc12002e043724c0fd0c8bad30e08b65ba9f2fe5d09d18cac4bb2d50e29ee14590ca7bfc505f3ee3d4f93d000000000000000000000000000000000e680653d29eb5d90f21802f543eac3102a1de6d2a5bc943a53dd9b80bdcaa6951ced2eae5e2a25448b40468f1923ebc000000000000000000000000000000000b7494b494019e3ef36d5c620ac56483fc6b1c8fe5c6f67537b19f56ef01db327812095fdf805d3dfe678a3ed8bb6226000000000000000000000000000000000291e5b98ecaf7aef0374647d28fb9f8785a64d9165de407d062403047da14d4ecd19fad8575070b278608e16b71d387d76d5eebc3d099448ce4a8ea6dec047b0f062c6361ddb9e95ec898442423a31800000000000000000000000000000000186536e3ae3edd9cc6bc24fda6589ed26e72e06121e97e1ead65b200fa0578c6e53d1154dc7b14e7eccc3a53237685060000000000000000000000000000000012fefaf6c76ae7197b99571e41a19b14846fc4499e8e964ff750e7c3ffef6ab3dc19eeb42c5f6ba44a573bca7a15166b000000000000000000000000000000000a135db813a44a21174cea3a0b34fb49f273877203ccb66bce44b2b58794818d8bc1df27544ecbf780823467e2e4ee6b0000000000000000000000000000000009b08f70cdf4e349e1a73935de9fb2ad9f4feb8cf5f835be78383fda2af94d81af253ebce08cef825764151d5713ae60cd4cc1453dec7ae335db989886fc0964ee73e12bab69ce1f1458d1416471176a0000000000000000000000000000000007976df2d47c14374e554401c4d3330bbf6f1e6b8fafcea1e1974af61e8ebf493dc0473d34b30b0b1cbee082550d85c200000000000000000000000000000000177cd64db8334dccb17fb207e467e5b09e891b05df7658d9b439e3cb72bf3e0a70e84f96fb5e448f33c003c279cb38d800000000000000000000000000000000094d739a02b8ea6ff8113019597f41df4728b270770edc5e68b1f5c32775f0c706e3f31c0a82059c1ee150b89097376a0000000000000000000000000000000006ed888aa4bdbee94ec67500e30d654071774fe22464dd5b900fdc17b445754293504b10d044aac8fa0c289f0b2d9dce6d207c08e51d64a9a47f5353faac77fbb184e1123d38e39bbada85534cbcd3150000000000000000000000000000000014a16b856b04ac4b687c79f2b4e1dd6d45db25b382e0ba6687afac648c9b6384cdcfa89812f1a726bb4d1c22ebaa6668000000000000000000000000000000000764088e337df6db30ce8aa23aefd91d9e35be911c9e89ac62a1e06c3d06e28efac256490400fac4490f595cd03c127e000000000000000000000000000000000894856fa1c8488fce182a9c7749f7953e6a73879b6e743fdb8c780275447122f512806fa83d5ad528f8f61598ed01d20000000000000000000000000000000002b33bfd09e0ff452c3336bde08df0102162488bc83c27052447a1e5d16c9c68bc529f96ee3787a26d2009f22a1246342e1910b704d39b6a64cc7a44e44ba3e8b7e64ddfa90dfa6b5ef571f9ff7d7f0b00000000000000000000000000000000133e2d092352d3ecef5b67a09c2be268fcd4fe1f7360a8ce3ef5f33bf689242961a140d9c8afcc1e2fab3ad4e3dba49d00000000000000000000000000000000101eb285f0c462a22406846d82ca6a278520b65132d2008b124f6647a642c221b0c3bbd4a0abe8af7417e7aefb81b5b20000000000000000000000000000000010958cbc317f1186aab69ac24be87647b8013b678b0eabc6270167bdc9c0cefbaf4d9a34dc41524b709f1b881e6bfa34000000000000000000000000000000000d92c47257fd0c4d6baa4c81efe65852840479b9bfda5cc06b253f167069ca7367924c0c67d6497a1e9abcce7d0ce9502eda0eb154d5f9b0e25a828c6f77541701004cd0293c61ae4d36aa3038d0f1840000000000000000000000000000000014ad0f935ba129b47ecaad63b9dda44e7ef7933f182a0f5226141c8f0ede026ca2f11db7f4924b5c582461688dad6359000000000000000000000000000000001453716381f13bf6ebf8fff2ed7bcb90f7beb44269008af5880a355dd03de5c84c14f5aaf69fda043b422aab0c694784000000000000000000000000000000000e983c9e9b799eccfdb56444d31948067d46adf275d7f39a70aaa8bfd0fe1b83632c23d87f4e993c8191901e9a607217000000000000000000000000000000000267c8b8c5e09b59277736caad12ec6986f206d1c1f48023356d8bc877a594c8bbd98981cec6382bf9bdb9a5fa38275ecaf6dcd51a851eb200c7f5fc3e106ac5ffc432f756b942b1b9a5dde31cb2a3760000000000000000000000000000000002e28c245e71a7f6206427ee512f3250612785ce29b369682fbf767d06ac08f91de8ac9f82951574cce46cee1aa757720000000000000000000000000000000019b0dc35eacd961e0ca7d54a0e37c4ace37eb0200d5489316f3371412717c57c8f17c1379721f4dd67b3fde24f50d4cd0000000000000000000000000000000013b9741f7a32e5e5b1ae5400e32dd6fcc1fd43b68df54ade57c934720b1289a51deae77b1726e1955b6430f37928e2bf000000000000000000000000000000000693980b347ed7ee6cd93f565c87efb36fb304d7e9ae24e2b9f902bfc962b6c7fbab93287147f5ac892db2a709c9ab42106d4a893a68b7fcb8be96faedef65181c239dc2cd752c85ae7800ca84fc2dfd000000000000000000000000000000000ad6b7cfc6cefa5783093b7d700360b354d0698d27ecefb7d5928ac5bd6c299e4001474d205cf3b85a32c600ddaf1a360000000000000000000000000000000017172c3d5acf59b70b340fc703e9b7801aeb4857ffbe7a9d5daa0f32ad80d1c0ef2f0b3b7d1fd83a757c076872425fc7000000000000000000000000000000001291f55fa7d14b14c578d57178cc707cabcdc4bfb444cecabda271cbfba2ab361947d045ed46d9edbd215fa4c8164e56000000000000000000000000000000000f64ed6c989eec5222239d888d08dfd638a0e35eff2266410dab0498941fcd1683654064107fb7e53b8c02fbe98a25622b9e1cfbf140f4a3b1d06be656ad6ee5169a9cfa7cbe6efbf8173843d406acd30000000000000000000000000000000001d25b5bfcedc6d7ff7e9fcf729f858759936235d23ad45b14dfd0229bf3e50fc68799d19ef019b36728285bf7ecd0b4000000000000000000000000000000000326e300ba07935e0233a03ac891f18dc7b5a9ad9a28264136228e9e23e8f2aa31b7f5e5f3cb3354984f57a868a5d00c000000000000000000000000000000000dc92060e3403df3a92b15ba3e437ef0c403fcfc9c3545e544a78874e5d9b5e63b9ba6060c29022fe2594c2e6fbb6a840000000000000000000000000000000006a01e85f59dc45b1501309a350137d71147c30fb70da6b7637a9b1dd884aeb7e554215474784ecd3bef18d15d2c0524dbc68f77d40330ad5b8cfcda42edf57899454571c6c6465c4107e662a269aeb5", "Expected": "000000000000000000000000000000000b7fc0b44723ff0d1cb7c43e470d4d432fc4bbc7f9d98ddb3d91434a5574956fdf15f898e579236426ea44677998665d00000000000000000000000000000000176586b6f157e408138391e3767d0c1c8457857f4cfae571267ed64ac86ff8a4b61a28b406e1caecffaae6a399f4ec9c000000000000000000000000000000000a420992f850db20d4f7d2ddff33e4dc79bc0c39caee533920c5d03d1c2619d8ced769ac09f664c0921829bd7edb446b0000000000000000000000000000000017e4000f4d03a6707174c3adb74966896bcc0eaabf4ff83cce92a666fbd13b59efa2c767442062b6c8b1a3abd604f0ac", "Name": "matter_g2_multiexp_82", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016ac5146ffc26d1f0c33645931bddfb84756e1c7b03f4838467d1b6701ee9478ae03c910b6b4f5c14135487bd2c14bf8000000000000000000000000000000000e1d082f16e4d5c5f0b6fbe5178aef6f781a6fb165f775cf0cd4dd55f2b498a79edf373007113dcdf6b977a87e1fded2000000000000000000000000000000000bb94be280df1aed761651c0292f88037d172b675bae1933ec12323b947023b437d080aac9e196fe5e06e5c4137284d200000000000000000000000000000000064190f9725bfd5d56c31aef7fd1590c975e2ce549fa6d5c71b254851149e0a0dab0b9de3acfc2d64231c79bc0ebaa37ebb3c942d3a1a15cee806fdb0fc3635483743a5b0ee9c40a48700bad5da53ae70000000000000000000000000000000012199d02d3f1bd8c4005878c3302e6a731ea69d69accdd690b4667e847b079563d32e18eb7a440b8005ca936da5e73cf00000000000000000000000000000000125b0dbdb0058639513b007a84d3a3e6302f5d846f22f99a55181f097e200981d9013c00d688a11eb976120f1a5da64200000000000000000000000000000000081e723506635433528fe4a40fe4ecb8a9c3d8cd701c043c0418d149951651e21632cd85f03db33b89efadd69e009ebe000000000000000000000000000000000956af2e67f8ae676abc783c4ec9f85c50ea130410cee8216fe036cd0521b8ea38966288afe7d35c28b30f7ca5c6edc0c193d751c4f24f4808621979f07f03b2eabba75f08bb49682b9df2da7a85a7730000000000000000000000000000000003e11a4e9dfe82cb495e9e698b16c257ea3f4ecb24749751e7334e0f31fbd6677545e4bf9ff78a82853560f7e7ba2ae2000000000000000000000000000000000caea2c527cb3aeae427e92fc364365b1f55e7128a544009be2ff7a5236d1cf8ffd5a5cefc87820bff5bdf1c6bfa165d00000000000000000000000000000000064a3186774da8bb5d013debf46ccb0d894592c414f32de6f77da47f4d42b0c8a13a2ba4f14b9883d564fd8ff6a4c90200000000000000000000000000000000072f6c48b6a05039e3a4dfc6b73501d6d4ca7e840b119da9c074bd4cd2adf4f2c6e9e6325ebf6f97c3f0b00e6b9bfac6dee4eef524f133183b4af95e4445f3ee5084b96c32e284ebebc5b87f3d76150b0000000000000000000000000000000019ddf708ab31f6f6f725f0e4f65d11248d3a79af30927a6f2673901fef9819b189502cb952bd4742d2b8e84acebb5196000000000000000000000000000000000d928535c47eafa5da4ce4f91467fc31aff8b86b850e4582a597b334491b14da71763f9aedb15ed32856382069c094ce0000000000000000000000000000000004d6b3545d067aa0768cda9dc3cca0f58eb546345b96f7d6b9355d47770e00286d962a6b3a64ca2ce22fdb4834a4bb6e000000000000000000000000000000000f4ef9366d342b309076299816c1ed9b424b68886a5c69e21e785f97cb0f99ae3a99ff6b5244dab817094449048a7552da514f21c8eab0edb2405e673297bb595edc21027890ad680f1663fd960ce478000000000000000000000000000000000236c5b4c57ee4facec5d4ff37a478c505217af66e029c3382613442c58875c75cb423789f6703ff3c1c0d80991c9e3a0000000000000000000000000000000016c052de3336002f362d9b0cb386b800860527e0fe81a1a6df0ccde31f3265e6246191b3febd1ea48e9391c44593ab0700000000000000000000000000000000078dcb04ca93c676a9a924e59f924d9d3af872849bc30ca633d4025aecd981ba12e626337635ea77886a45f4da84104f00000000000000000000000000000000027df6394b195222bb8357bd684088e3e2a398f0fb0cb812ca5dcdcd1fa1279cfd03db62e0f8b2800d4b8b48238931656aeac9a669c962817c01069cffbd948d9d8ce764e92859f31fdaf85f5aefab77000000000000000000000000000000000485ce58b387083172102145fdb3e26c6ffca8b35af0e1d84ce9cbd89055be083bddd3da56443924049a056fdb2ef092000000000000000000000000000000000d998b234a69d584c78ed054b1322ceb33f73cafb5b23c1703a9fd609edcabd44f1a642802b9c0b6fde6a6828b50c1200000000000000000000000000000000019235ff13567bd007d77e4dfab139cd57dbb309a3cf6a6198a548c4e6915778094ddf2b05a91f5478169757bf5a56cb300000000000000000000000000000000110f6ea19a7f62bc3e78f4c5c1c6d3efdf1a7f563576e758218b2c363fff8ad8fab0e72431619e4ebc93d2d739fc786c40273bda92c9b1b677edd905d76d75875e5b77841befb2bcaf1fca7674dffd5a0000000000000000000000000000000001d45da76e3016c00fe65bb50f7067e4f06364ad8348184831c4932ea0e0f3a170ab5147e4670ee1b16924105b6fdb6f000000000000000000000000000000000b3468206db0613369b2b0750c98da65b660fc07c30cab4e459c311dab683b6b313b99ec0fbe92ba07f8aab43a12a2c9000000000000000000000000000000000f58a57c449a41105837d5e2419a34201cc921ec77408d6c0c7a2eb227be98ec1f6f6eb9fc088daa0d4c78928a1eacda000000000000000000000000000000000ba53b872dcb9fcabf35e673b467523ea77accfc1b38a5f92d7b9d269c28aa00d00b08d70eae6ed4d2e82bdb06008f9ab77e16276f9464fa2063230d6c1a4152553536c610062f18565c030e80b5cb540000000000000000000000000000000002b82e2b582b247271543117b939fd17ba8bdd617a223873296f7bd75de4790f0d5d8fe523792bc7fb4764d3739669d80000000000000000000000000000000006eb554347efc5f2ee79949bafc012e6d9964ce19459b3867865709d903fe3d11bc617f30f6279a9e62ea104565953600000000000000000000000000000000006a543fe5cfbae629fd3256575e3eb4e0b65864aad6c7f359e169038bf090ed9bd92fef32fe1ac20b2a8c90fbb6081690000000000000000000000000000000013ee42b0693b2f3b9b977fbae5c856e9e4c5e70120b5c29e0a9f898f6d04b7fe351e17b02716a44febcf0a00a9cdd9220be15b654ce22ae4e32987babc4863ffe2bd8a459d0f01f68fe84a75326889900000000000000000000000000000000001ae7368f84e354e5758554aa9c72ab4b00a644cfb9a4ecba38dc72227d297749bbc98c8f5d6149143b31442359d8013000000000000000000000000000000000abf087f77c79cb8c69e4289fae87b2ed483442daec3851a5ba32c43e342be29433b2deac6dbfa7a787547a7361ed0a00000000000000000000000000000000000fa01cff7aea64b649951a8d85fef0bd475f31e47c706b96ee2753df9987508b5e5456cc49e88ec3aad720a2535f6940000000000000000000000000000000018874d020e2eec0e286dce324b91f15b2a4f293d32956b27524f478983f0e0c5b43df802b60f4f001753f12d449cd821c8f1fe94bce21966427380b6d357a3599e9db03a7694159335ffba26fe29e4650000000000000000000000000000000018f7d19362e2cba91023455e115cd90f02aeafcb026349393ca4105e270ab1cf589621b40965fdc9795f66ea0f6a053100000000000000000000000000000000170ce0eb304e0e1047617b709c834b67a8989212e5bf1cbd5a33242be94bb141d5366e636c01a229943bead9a7baf43900000000000000000000000000000000077a17356b3b31faf90f709042938b9e901817f7379b7bd486d18e47d22b0430ba70fb3006e9afa67d7dac71ffaf152400000000000000000000000000000000064aca92c41561e195fa8239800c97d5242ff0f8ce76b0d119063e2ffa09c26e01d23d5728765a59bb9587e885450ad1c6d34471ed00035a484f97f4e8123d40ca23b017b94df65540a5551b905e57b3000000000000000000000000000000000876a57dc24ad58416f910ee3ce220630a1297e6bc691c908e6cc16f975b146872d71661bbb869361623c61670627eb0000000000000000000000000000000000760fc65097d215ab9aeb3d5a5153977e1e399e2cc0b0cb9befb0266d98ac13512a0eadaba4e051bf56794621c551ec60000000000000000000000000000000003c8e205e53075a96c14ec26345c75881a0d67c7ce0d62d73c83dc353cd7b555cde52ffc5659ab0db2179a899f0fd694000000000000000000000000000000000d7e8a7fe6b751f7f478698f4f0d30cd0a435a2295a958cabedf4668769819b4cbd4e8b7721eeb5ced3f913156abcaaff3abd467168bf5e57f71017b5779bdd400dbf416f34f105fe747ea2f8cf4a21000000000000000000000000000000000180546f697349adb2918129f4d0a979bb114d1b58e5baa6cc221a09d7083469bfaa61f80f1e3a6ccde0da54b24d59db70000000000000000000000000000000004074338380e3d7c0facbbc71d83e78b53191af9ba13ba0cba6015bf4f28e4b0b52ffb34c7867a335848f57b5ce5ef5200000000000000000000000000000000148a800ec38cfc2386497d9aacb4327d5953a6612cd4067ac13fb977046688e80032125d4b0e7cb49913e489796a50ea00000000000000000000000000000000132438d18d942e6dd3f69d117abf83c2fa18418e5145cc43b3cb8d18c873935e41279a9e13596f2863be7aeae9b73d172809801eb18d38a61ef8a80f13086d6b1f85ba751cdb8d17fbb9ad5f8d0f835c0000000000000000000000000000000018b3102ce91af86cd10162d3a43e488a0d7b7807dfb9624c3cae76f342e86f8ef1200444a57e2ed7f819828357a6dfe80000000000000000000000000000000017137b470f3c8d1a03e7252e18f4466c9ff809408cbb2043d6b226ae2746d890b267ce3255114b2e073eb66e93c55eb200000000000000000000000000000000054dc1c981c9166d0bd3a54064c33f15ab856b240770ed44adaf9f32d4429babcd0baf2c5b8a1ff80728e9c63e806cd3000000000000000000000000000000001897595f836342ab54bc2e1b72f433bfe3b5bc989727de48575abe89386aaad9b1549af3ca55f39feec14355b29dc9e33521c9cf035b094d754db994fce3161842a9509ec8288699680c0ac7761eac68000000000000000000000000000000000467f1a3093c72aba4c2d9e8171057cf88146eb32f38db0761a5ab2027f2213c89e12c67a338b4b342a73384109988d2000000000000000000000000000000000ab26c871d140c9c4e0512afe9fb576409ffdcb95417f8c6cdc0d964011dfb1e745045766bbbc08ff7dbd6935934bba300000000000000000000000000000000183488902b886200e63465098be87a905810b2e8ebe0364316da798e423dbb267743a0d2e3d93303623fb17df0e74ce30000000000000000000000000000000012c7e79f9ba36cc47762139d191e6625c850a03d5b6e0648032d1669575704c91e48a9ae432bb3553ec66e86e082de689c8c2998d141b9cd3a82507b6dd97e8d32e9e759169c575eb484e9a1559427da0000000000000000000000000000000012ef4988956e026a79e5e904ad3d7ca56793321d62cad46de3cbde8570be5f0ac86d386216152b37053741fe342de7c60000000000000000000000000000000014ff7804312754d23b251a42aea65207695d4df65cac4f87fc96cb920843c022f24cd27731224db751cfb621886249540000000000000000000000000000000006ea693105a1b2afc79dbf75504c256c519f927ea0d79ddd1997a49638a67151dc81b84473208e8078cf71d456f2de0c00000000000000000000000000000000122d367c147c91517679432d3c7b56f2d529d70040109f803b89a04fd8540a6c565354ae420e1bd4ad4ff61427332629dc83c1ea9e4f4fc12a7190e6c71c4f35d1a676d39e30fe688a05820dd989664000000000000000000000000000000000156e7f8f1412cec315eb76f10c92143157313b8eda0677a6c0236de5fd27e5660ec3eb7369f1604082c59e1aa5f94dd900000000000000000000000000000000018ca9f505a88ed2bf595fa9b55d2356748770af16b35bd5db448990b7d41c3aac53aa490791f7ac09d2f5a087f938f70000000000000000000000000000000017c76ca9ddfcc26b028928364ee35829c6e57fda40773a6bc0c259a1b3cdea715c664d7bd0340192aaf7dec7ad20a2ed00000000000000000000000000000000082a255966c4f9d0ad6bd3d88b136cb2cfca09ed6ae378c914c28ff3338a2cd466cafd839f3fff4a30b33ee56e684f4e00be1b9098f1873ce155a66899877c7b48ddda363ae1d2353cb3816f1ab15ef0", "Expected": "00000000000000000000000000000000075c71e21ce327a97024c8ab5fcbef4fff76260a4f8c8489167166c4a85d25096c617cceef73097a4bb956be3eae8b780000000000000000000000000000000016270f3ac86c0ec43b9472499c4d845eab488a34ad9e2148c72cbb1db13623c5dbbc8327c47ce596521bd1f54f119a660000000000000000000000000000000007ad4914ceda9fbc161121c818bd05953836a581dcdc78bebcd82ef548671c899581681c908a337618a445f77c6b7cf400000000000000000000000000000000173f401cb78024e844adcc88fcf0e52d32de134f6300216ea0da7747752ae3ddf4d181b8d266b53d1b699921f9871425", "Name": "matter_g2_multiexp_83", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f40eea638a3d4fec417701c936d61c5b233c9d6b3e94ba9addd0fa0b20adf9f8e07c6b629977445c7750acfd18001c0000000000000000000000000000000005f1ca1ca9cf67c33e3ff174a65adfde2db62e74edf30b5b0156d6b9dc86dd619ad8863c055096685d611ac015ba884f0000000000000000000000000000000001683dc67710880b8af76b464291c17fb0ee4eff3f648ac0772f4a777025c8cda0342d8f5aae3123da7fac57b965685900000000000000000000000000000000143d919ce2cf00838b10fc65374e770bec3db8ecb17d2db08b6a10ac38657bb109f54c1b3040b661c3914ded6f7eb80fa9cbdaa0ddbf854861eac6621255b2102e5343666c735d0384049d5680d105d4000000000000000000000000000000000616299341f2921adf083d1190c212a7941bc0d9fee50b05b265f2e8c339fc3dd9f94607631f485e394f5a7d71ae73d00000000000000000000000000000000006b2f12e22369e8aff45b6c05a2bb72a706dc46a5d1393aaa9e5a7931ccff33a5df2967189114c3fc5dbf69d080e39dc000000000000000000000000000000000981e1b119d04343e075a80dfc189000b4cfb4e321575817aece6009e6b3a6233d1409e8e584f0ac9caaed1f43e40d7d0000000000000000000000000000000001ce4693e8c14032c35497e0f9a586a4541d8a1a68ad014b0850753a04215be2bb60cd7c2fa9be4f4f09a562d7b29f3892073d958260a55b70b580f3ee27c42553b5b858b66f6928fe74b4de91c34bda0000000000000000000000000000000012d634764207dd7a0201703f855365f7750291c810ff292b3e8dee682d7d8eebd6d6f3b3dc8b0c9e25bd2860e031311b0000000000000000000000000000000000eb0859d79fcdef546026fcd380f5c936e64a5665d73f56d92c03dfb50c534a00c857c86ec43275ce69cccc0b53137f000000000000000000000000000000000131bf000fd117ef722b33a1cebd28899fb012e1113f767d0ed46fdad82a32e4327b883fbe29abba1bb7ba3ecc1cbab2000000000000000000000000000000000e24ef1e44029366ae1daf06524d8beacb2b99f60f419cc2ec1a49013b79fb7a4781dbd37785f32ec67c0a28d61a3cea2117f11d78dfead915a94f11fa7e904a96204ddf1835d3501639b83cd5f716f500000000000000000000000000000000067b6eda41cb8da47a424a02a142e2b98b9c69e7023cf616040993f41507798882194229cb6572806e82e9e5eb837b37000000000000000000000000000000000e38693cddf130d3645fd60ade780db84fa700e5bfb74ebea49cc95ab001bde442f363b4e4c61f683b3e67f1ec8c2af80000000000000000000000000000000006d593005cbccc55c5e336e19aded70da65a7fe42b6a85070e491a4ae54e18ac213556a91d5d62786b6d4d1305525a76000000000000000000000000000000000ff86216f5388114dc06deffa7b52a273b22fe0bc8d50804b491fac83e13915c2dd1b8c2779a46b5c313c4e1c05eb2979087caa1e89e48f05bad1d720477199410941a6105f911d589e1f94a851e0715000000000000000000000000000000000262cf4727703fb227bd7fce6cd3f25c1897011ab892e79fa47446711d6867ca82b9b95f129f7ca24dcb60ac75173d4700000000000000000000000000000000136b5a304807e029d0a77b2ed505ee5c920248242f0f95aa07e9bc2e13d35f6f67451d028dc19d26095b55cdc2fae4fc000000000000000000000000000000000b511b2e19da7bfeb183f0aec91bc7db3e7c913f1c282e12d5d2f422a49e7fa78a5f35656dc9c980324717a5ad386dc30000000000000000000000000000000012eae443aae59fdf907bcfe3ee4366e252bb57e268fd569d742456f348429f009f67bf92f9dadd401104ccd2549cecc8255603b470c056b3dfb3acae0dd45bcb3d014765a5181760336deeabff3f00be0000000000000000000000000000000016a827938d8b98e3446445ce23f48a7ba0d634de826dd1ee3c71467eb57bd4c24e0d1b4190f47bd841183baceaa2593e0000000000000000000000000000000011d360e0c18b45ace82eaee902475127d8f18aa4a2ec2081a453f1c85ffe3c59c0f7016f966574a7c51bc14f1935568400000000000000000000000000000000186b5d452c6dcc1ddb4f47b07e01b6d64644f6d01cba8498c3059cc494a68bd25eef35cae05885b9f2689683e65161410000000000000000000000000000000000ff826e5a62affbfd6d2062bd329fcb561f287046870b8be461767759cb0d5f1ac904ecd1f136c5ccd784bc11088233e0eab0e2486316956291feb44de6389b20f8bafe9cc890d86d27a598bab0f3c4000000000000000000000000000000001010e75c52ed0acebe30fc588961c849b7b6298bb8d859f9a9401737c467921c5e3cda101cd4e38e4318233d12b6c7b9000000000000000000000000000000001884db518fbe4d621403ce00521878c0d419d8cf476a1dfda59b7d3c7af2bd91058bbbf54ac0c5cf9a217beb78e3f98e0000000000000000000000000000000001272cf0ad917738bba052e88baf88347d60f63f5b875d604cf0531c1ba7d43e868bc70a682b7274067106f611f08ae60000000000000000000000000000000006e3236f6a66bd37af4be230d4edda6eaaed661f206ca4852d3004b5f358f184d80be6af81c62e5bc8c88e7a1072fe21fb9436456262e5149d02b33a1078e198bbb681699b3f485625784df444bfff670000000000000000000000000000000004fd1e2fd0d28db08224fa7e880abb8c48dfd0e488df4d2ae5f6649f448193acbe943baf22af4b12fd763e3e4ddaa08d0000000000000000000000000000000008df68f276f356ade28500eeae3b755c9af9b5acac5f5f60827b5b2044b2405129b00e5271baf9a80847d3b720026b3a0000000000000000000000000000000005e683d1556f513e6d093704405f312687c3b9e2de3b2840fff32e88186c89b18d1ac558d960b1196594730a9bc107480000000000000000000000000000000018161f8d23c394d10ba576fb0ceee530ebb95a670f2589d84c0646f693086ecb7ed80e556f3ed9434d7fa488430ccf430e2724d3501e3d79b85266fd83a2a6156eeb48e749a61676a1c92ab9bdd6b8990000000000000000000000000000000017860708943449c2227c0f50cf1274652dd32e999d5f9b1a8d672feedde15e9f1af484a7b9462a62dd745bb6d3c7295a00000000000000000000000000000000064f8cb707494f82ffb6374641817a466af65f5c7d83cc2964e6cb8efd021e0c40934a3ffbb0d91bf8a7a616dbe8d220000000000000000000000000000000000eb37cc9d56fa0dbf050b557aaeec76f9f6d0a6c448ea298af78004e41ecd8a1df8fe8640e77cb76b593ee17658326ff00000000000000000000000000000000092ab597967544fda640b145edcb3ae6c3f027c2111dbc282ebdd48eb93287ae4729cb30e45c1c8999b3a45b099dbf0ca49344fe6ea9274a103f323f3d9381e91ae48233dd579944e12afdeaf854000f00000000000000000000000000000000124fa4d48ffc5732fb21d465b559e995891fef98370a1eb73c9264988f75caa93fc134fde7f93c794582ba5cbf6bc685000000000000000000000000000000000b71d012abc1558e49831f053757518643ae04f79234fa92023db9c5483bbd872d24eb87a78960f12930094c4f8fb70e000000000000000000000000000000000651cf0016efea086d98e5bda8e1959e20e4947e302eeb021d196897cffde3e2c28f783521b2a28b8de1ad1a131f5e67000000000000000000000000000000000555ff8a930cc11d320afc3e0635a6f93da1487a5764d56636be4e5803d740a73d84666f6141ed5ee6b778a463823fbeb44aeaf3ba8b03e7ef7201415de7365365b828f2c1a38d09153e51432d35b9a7000000000000000000000000000000000974e769869719f0ee30895df837cff50d47382461c557abc4b8806b04776f401b76a5e630a6ccbd3484980d03ff58d300000000000000000000000000000000098157f0190e6bacbf34c20310f6471166750ea1b235e46a5fae313f90dddc799f21548088322910bb0fd7e41beb23450000000000000000000000000000000007f00d7d18719db9d91e2c32f51083b42c4fcb43c38087f86879ad6bc99600d4c395586187d26d041ff49dbbe517fca2000000000000000000000000000000000510cea4a7463bc5882d0cc25fa967a0b02072627bd57f9a5863fe5255953732846d4907fa301789bf02af9c1b25211c53961d33104649cbfccecc7eaf33b7a2a486c77dca363ffc9fbc9ce4e8c1adff000000000000000000000000000000000bf264c0b7bf68c595b89453ebbd7fe2e64f4ae2c7268ad51f4578c35d48040277f3dac9021997af02e492039348efaa00000000000000000000000000000000083a4fea41cb1e02e5002259f5f7b335c81e15cca93cbc884dc1b08ee981c55f2dd3c0db1a35ac9907435edd7f0ba625000000000000000000000000000000001468e508a02ed7b61f752ac38313345338d2b2d018f719f391c0f3fa1dd1602d9476f3d8829720d17021a459a2732e96000000000000000000000000000000000629edb2530c38ead8717b289c08036c12630cd8c9ae875111749ed893b8cbce40bcaeaf13df4044147bb665ecc2319ea04e97c20b42dc265271740f27f1a833bc5b324bcb843a8f9f8a68231c663d57000000000000000000000000000000001635830ebf227be126e13c634a84f3649d498e0999ad2dc73b9c7360db120dc2216addfe18c00676ed185efa1e789d8c000000000000000000000000000000000471e3cfca449bde0ba2b1e2a5b63d53badcb34da3251313190a35daf694d70ba385976d1f875242386fc74ae0173d18000000000000000000000000000000000986cf3f1eef587bcc70f66f25c60f353e6b15bd105fde9254487e9b522159658d0fc6b6a8a3ea38c27865f1ea4d76490000000000000000000000000000000015a2eccb9c10bc273cb712ee04bef01a11e486bc6a4d220a0f653582af6ba1bac0b5108250626ddf126f16f4015c9d2cb688426bbe9ae054acb6c1fdd4195f8a113727f5617642a5b3c0c65566e22527000000000000000000000000000000001213cbd035615f09189171b3e22630d72df2df93fa8c14427bb00c34f5b55bc8d1b1a59404bed6549b582537a397eaab00000000000000000000000000000000161072d8ebec2841f0f34cb38a3e1b2094a597640a34178ee951e5c993646ecfc3a4c0dd753e7e76f3a6da5a091f9f7100000000000000000000000000000000077e9c95b6c6f726902392c3a16b5cc71cd9d4cec58c00eadca6091e45bc095e53006ce8ac8827565e867531013821950000000000000000000000000000000018cdf909bd9f38e57ee24c0f51a5f9f703eb3d190dfbf75be00969e9e8f8fee331cf32d93c3a956d12f374f8752c2c79cf365a86a8d08db5cd95f239a2f3d22279556975ecc3baae0b774b0323dbb1b6000000000000000000000000000000000cbc27995eaeef2bef14919d48a008a0b0467856f8a6659d6e68e47a2d9d41d217c5913aa1d67911325dbd4fc38e36eb0000000000000000000000000000000010639740654bad5c4ec93f2496f4dc54a7642bc92ed03372ad4edc5fedcdfcf37158d3f02279d4e15078e9d5a7f8b5df000000000000000000000000000000000155ff4d6dfa031b0cc2f57df41c1e1b1c81bf5a5cc1e3aa93920e93c2e2e7a71b56ac410a87855400025badf6dae8e60000000000000000000000000000000018e637da048e7e84b9d1654113978fb148a54d86e1d011d7f5a86cd4f1e5bc15abc5b67d00129f53c0c021cf933f399c528715199c9f47fd6337b6b0e807e230b1397885fded024431c70e453f55f3650000000000000000000000000000000015d8f6e47b8f07b3e07ae0952a7c8f79519ce2828e3e26b284b8f2fae7432b337de17089b5c32f0081ec6c6916f2f53f0000000000000000000000000000000010ecfcdb02cff772db667266cb3f99f1dc28004ffcadca7a9c64b3b5853c09b7793ca0aadb155257bd64fa7bccb390450000000000000000000000000000000011096a52f3272955947304ba037e8b3fce6b2f07f2352c08d5932f4d2306ca511a74dc044d0f0e1e260ff40b0fac5e0e00000000000000000000000000000000130facbe0c1c6d077e9dcab647a44b049a1aba3df500bf27d1c268f71a59635e702c9ee1bdd68fbfcff7ae5b3e6bd83bc32e8643f38f8177b788b8c2bdc25b668308d914fce35c6f9023a769334a51d1", "Expected": "000000000000000000000000000000000b47d58802579e662f34908a4060becd40434e4934ff58790df2a69a759223ca29f42e658ab475cb92bd9c46566811c7000000000000000000000000000000000091d3a4c58a669d3bf0377abfe28d1817168b2a86375928d95df3459c83334669a59aba95ab2b9957d5ded0bd8925910000000000000000000000000000000005aa9c3fe0067338675099ee32f93bc8a5e9ead94b120dfa391651da40cf1ef5ff79d193b0b14b5926f10660aca6c11500000000000000000000000000000000058200992b111461f4d737533301734a5c3731c9f2e7b55e18887ebff4d5b74dbbfd23773606f54cd6a930b85b89aabd", "Name": "matter_g2_multiexp_84", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bc3eba5594666cec699a47fa13ee74722a80b4e5a1b28553de37c3163f2fdb8b801e35a19f6d99cd207d1642c0d4ad400000000000000000000000000000000104b334afeab36961824611f0fb58bcac55c9d36604ba73e9c8809085c019bd967cae7147c766df6565ddfcc0cd5fc9700000000000000000000000000000000026c3a6a4ace8638bf8ba7434b59c3aebd4bb274cbdcb898ec6a547b215f32d10395f3bb85a9eaecff5ef6d5ef2b50e000000000000000000000000000000000065bc419f9496b5e81ce72a13fc1bdce4738c2e3faacd80676be31db65ba3e7941ea75e370b6d6c0e7b2cdcce80a2fa14f8bfa3d47ed33a05fe3da738797f18ca5d5b8658055de5a9f85bafe6078f7fe000000000000000000000000000000000e7f1f5ead0f212439b4c47599581982712d2e6ba056f36cb04033ff5eebd81b5b41b874a78aeaa98562899418ab04c900000000000000000000000000000000095e45da9a4b2578cedd13af71e289d0067ecca1f09c014a294e0b250d1e8243ff98a9761030ac855a9d897cfe9fafdd00000000000000000000000000000000030b44b150d1337a3ed6a77f7b6332d7c8103da1aef0d445ff7467b4863e4c830fb782a81d01a6bf97e8d52bf333e78d0000000000000000000000000000000013bb76800375a45b847a96ef6edff3fc3c30e3d45bb4afe04230107f6a1802794e1dc23431797bc5e79e0d5ac6357eee4b0d302be94d437b8055586aa77ec1fe616e30552b4d7d3471ea219c148be069000000000000000000000000000000000602e0bd3d34415ddd517a73acaed5750dcfd68b633d51003edf79a169ad7a3ca2541d7a131c317c957a9597a753b5080000000000000000000000000000000007a964539081fff51e0ec24bb71257f6a1c513fb0047aad84b80180b22133246a1f62958ead75e4b2a68f973d17f1230000000000000000000000000000000000f48fe0f5b5a95e48bde4d8be1b2f352d748c1201b064bc88309a709b285f81260d4535d3e1dc7f1d6ee23ead35abd9f00000000000000000000000000000000135b480fc8a72248f7a4898fffc6c18b7f2f5b1af5cc3846610c299c8da252fb71190d9f761e037c6b47595bab6a03e56765d7f1079b142e513e604d577e7caf82cacae59fb98c6f8990522372dc906f0000000000000000000000000000000004773cd2884e52c2551c1ea0abb78fa17caacfffe13f18b75588484b8bfe781e623075bdf827fc82c6ed7e1d4d62081d0000000000000000000000000000000007e6023fc0e409bfc7d0b7ca65fa0e8d88bf1b4c202a8d1f0e1c3479b0963a646d16795fc5a128a54e624357050fed4000000000000000000000000000000000039f6eaaf99bcc9f4d8fb994a040af0d29c37960e9015d4e48466a9e554da30975c5534e76a1f08a55ed8ce7375b70100000000000000000000000000000000003d2b097d4afdde83a01cf2b4f9d12f77c8e92a8cadc225d40f974ccf385ae65bed1972a365d55e24231d58abed4395a2eeee02d9309af8c74c78e21836f4e6a7a6df5406617e2b4e9d300e37d8a2bfa00000000000000000000000000000000047b8c550310ae246e43b513d39e507f1dace7bcb543a49ae0854a397f62c408ae3632c94d172669ef3e013781796ecf000000000000000000000000000000001592914e260afaca80c0a240426c2828239ad5e256a707530f49cd65e9da2e4bb14a7d6d5978f52c04130a0d434cf4ca0000000000000000000000000000000006c0b8448ad87350db130373778d414deb738d3be97fba25c816826f59e3e926f44956c2e2056b7d769278cf56cf6fe0000000000000000000000000000000000a42d716fd83071bfa014a9b7af6c164d494f0347aed953bd2c1c97ade087a8bbea9f53c507fc0b22d520f28cc5d480cf8449caedd55f0a08825cc1a9e985201c8a7a54d1c4dd96f0ac54214743941810000000000000000000000000000000018026c9f6c86219d0be88955ce0afc3cb637b1c3a531aa2722c56816d368688181ef2fedf1525daec6d9b1651b71f27c000000000000000000000000000000000b40b15bb0621209bf9e33ebc27a7502d90fd3af62a1bb8f54a874a14c105df34ae34a43fc3805c1e4817ba30c048ac7000000000000000000000000000000000465262367e30ccc24632d39bf3af9cb160e97049d855176f665a185c138d5c529d11e53e56c65506e3e30be7b48c6730000000000000000000000000000000009485991319a311052d883b45911be12cf7648b5ca104ffe77594472f7047c803b8e9fb753b98645e630b9913bbc947e28ec5f9dc48931da70ba0cfa7251953e24c4c95cd019e00ac6fda095c1302a01000000000000000000000000000000000fcc0aca0d873cb8733ff7e2ea02b3736b737821af2db06ee6508e161f6159f9d944372c513a03cc4c9e30a707dca0930000000000000000000000000000000015c3774f4e0b30c9532beaa2f7f9b777f8d46bfd3888d6835f4a5a046153a98062efb17f78807fa17b3a995ce720c0b900000000000000000000000000000000083d48e01d2fb58244861a74a1261063f7d20b412c8a44f9945fbe373cb4b9a7ffd4c4ba4054ece0abddb6c14c013ceb00000000000000000000000000000000133c4976454b7be427c4c2ed437bc2e882854d2ddce42d2f97cd3fab1fcf60c3272aaa123a0cbecce1a774946bb7a8a0dc6046b43e6982f11f39412cbdef14f8e330d37fbe6dfa9ddf3656b86f4f60e7000000000000000000000000000000000f6ae7de1dba3b3030b208f61d182013231c4666f134b007b52d36bceb6f3cd77577be7b11abc097cf9618d351d61e270000000000000000000000000000000005803904e3e640e51900805f930638ddd8b86cc1bd50cbd32a142e10d85044cc52ff769bf1b40dcfb7269c913d00b01e000000000000000000000000000000000e6997b1f8bb649c56de5c4bf9968d19712abd22fb7dabee19e0aebd1b13adcd3e8b202975b4edc917d93adf087fb539000000000000000000000000000000000a32384fe03280962c5f575b47192e5ef3111fbbb0a01bda2db1e9733471f11eac0a37df8ae1a891de311770c482c06b0adf4625ec80149b7810767c985c2aa0187987b3649cab8c59a892404ff2aeb2000000000000000000000000000000000531fad86551ac6dee15fbd62cb13f38d8d5c89d23a031b9977f110efcf16501534757bc5b93f0250ff02d6cfdf2009a000000000000000000000000000000000e6d78343049a68514271fc785de053ed7f50a7774b87f264c42e03e6f8f86285477f8cc57ae066ef0fde237c8d1ddb30000000000000000000000000000000013e313484da4d6b85634c5306444bdbe45d7db823616d72821eb64a2bb5f352a4f7e4273fb6557039fa563ce1b091bea0000000000000000000000000000000009a40a984be66c3442fc8946cc42eca722187dd819be9ab34a9c3b4b0de7de3d5f126c175fe84c51a6f09e18623214f9345fd17367ecb06b29d764b22dc1e262ba1a339b6f0e0c77384245e3d41cda970000000000000000000000000000000008a76db551280cd43d4608e9fc629a021675bfdf9bc5a021546b92f3734acff1e97928850716b94d15b7dbcc4a1e0aee0000000000000000000000000000000000b2262872c268782e8f27ee8fefe0827d45131555e755c0a65a7c8b4185269bd621412b653348d7c1111d681f38d946000000000000000000000000000000000dabcf0f847045e01ef70ceaa32455f4c962e4657b840f97a1cff7cf5073cbf4ca8ea75a4887076f155e27e8d7406c95000000000000000000000000000000000a9c0ed94170eddfc485d9f1a770a8b493d4a59bd7156d6cd4b95b55bffa1b597ae9d6fbe529dc0833634d75906a4aba5ce5e62dd15958e6298cdf4a4e899e53644a48494d04fa6d1f73f2dbd645817c00000000000000000000000000000000170ac69c2bf9b48715f445524cab902b18ce6dea7b258481cc59986ae61c8fcb6708b1457be299a6e2f6f34dfd936fdb00000000000000000000000000000000107e855593b6f3bd2982a65167ecead47039065c9ae6e1bf963f81d441f0ebb411eec4b3ed1cff73044f68a4c114806a00000000000000000000000000000000063b470d158ebb4828e875c3dd0ca29a4fd2cd2af356233885a871cb5b77402090f29709c6d6a78f612c8ca4df2f4119000000000000000000000000000000000db75a60fa0b425b8cd2c955e21846ce3c407cb3f96c472cb412498143cc60212de0dfd0bf4de53ae3b345232180b4ad853396021d32530351deec5c266a65519471dce2087485781f33a1423755ef38000000000000000000000000000000000389e79154f627463a7966252deab10b5e809b0c2a9e90989c56d4076b834e2081ddae1c02a9e01b71d96b772766fc680000000000000000000000000000000009109473c7aa614334fde410951a69ac45967f7550890e01b05279b6dff394775dac51d583ae0aa82edda18ecc5e66240000000000000000000000000000000019dd51ec6783c1618a7f12298e38cc75d4fa32fc31438f67eb15419a2f0e9d4b5f70ea59b69e531c868475cada519569000000000000000000000000000000001121c7a6cbbb54d5e30a11a73c158237dedac46385aa15d93592a30fb64fcd94a674cc77afd21a611f704734337905596dfc62eb59bb84b3b6599bf3ce7af229096a8fd5925d4743a5ea386a26c9a6d000000000000000000000000000000000178670fb06f5eb8a4f182913f46f66147deb3f9f634d620ed55da2ccc88895e75f76f55b979e1ba3c3db29710050c7bd0000000000000000000000000000000011adec68ef139716ee081db7122e911ec5a6e1fd7f681a96a713dddc2b742b6e7cf7485b8f45e7ebdec8b1174c02eaf100000000000000000000000000000000089dac9a47cbdfead8536d6cfe8b94d316123bd92ddf30091e16711ff4651c4e2d8dcaf6c72bc159d7de9fd832c6f5be000000000000000000000000000000000c40b871930f0c6826a943a229112f8bf9a3b7d7e07139e1a7d99f97601b6ca8cf3638e0265743dd732cee17fadf996721d35ee6d29ee4816b91d1664b5957767b4b8066775b37c3b3d08729c949d6e5000000000000000000000000000000001040c4cd3c28a752295b115fd80c8ef0e538e1a3906e0d326e46585d633140bd6b8231f50d50c8e7a9018a625c4bdc530000000000000000000000000000000008b966d9433bfc3bede4ddb005cd0c256a168437c31b8ecc83e6fefa6f4b1f2bfd057c78f82bb76279b74a2f7de493b5000000000000000000000000000000000c0f75db7a17e4b712666b16c31b10bb935e7127eb9a0e59e35ec54814a9de9012210ff1862aef5f765d4f7f673c4962000000000000000000000000000000001015e63589a8b56aa643a79c5a433dcd8f4933a10edc9921bcaa7098af435f7879a40868e25d1ca6f7852800df29c2eb3d283067bac390f556891a531dfacfc4795358229bc9a651c0aa71d601bdd56d000000000000000000000000000000000fab22ab380043b01d312004057488ffc958168f8fe4d9c86af622030121e14a46c4308d711d5fa9a414b9ef75d51ba300000000000000000000000000000000047c738fe5272e695f421ed463ce0d6308e05c23b6bd0973df9b55ca96d89c0771a45d53b4d17f30d8cf08edbf94490c0000000000000000000000000000000017bcb3ed735e5a302f76002ae82f4ac74889fa0e966f0fb611fa6a6a09440bc923f447eb6aebe47eef917753b7427efe000000000000000000000000000000000b189d5b64578eb53ad850c826082265e506ab620a9ab9684cc2a53718f26befc35e9431af012306a6190f144a9632bf873724ba35e4e8b731db36f5067aeafd33f2e966977bd0962fd57cd5ccbfe87b00000000000000000000000000000000049fff545ac239696c995eacc560580a0328af07376f5ec819902e30d5e7e40d5fe07295c4ccf54d5c06134370373c1b000000000000000000000000000000000bff448d5ab544a8cae0cacd216a6b6d48f0abe1b4bc946d95c1a8c4ae44bf049c3b572675a5e20c1b4188fa27a867a70000000000000000000000000000000011dbc52baa00712f66def2fa8fc77bcb07431d3285774e2517dcca65e611f07aac265856cdef0c1637def44c382230fe00000000000000000000000000000000090af0898dd578123c65d1f818c3f33866e4acea19aeafbb31bd8da029ed1daa2d7ab3b22147eb32a09021f7a78fdf2acc5934c02b63797010cc8474e90fa5dc88d73dbe5f9be605bf335057fba47ea3", "Expected": "000000000000000000000000000000000d52fcbe9f1776477a9d2149ca55e0651fe9d098a67209ce2e7d772d4901ff2c70be432b53dc94886651865a81ba8c620000000000000000000000000000000006b54871379e2be969f86c72cda9acab9bc99f73de987f17ab8b25c63c55ffa2cff61b87e8c30d9f712afb62a2b9cfcb0000000000000000000000000000000005652612b19c38650d1babd4772722ae2c560e2914f2e246725cea86dbe1275a981a592eb55077ee4b7c6090e84d2ed3000000000000000000000000000000000ee37a6d42ce69aa67cdcacb19efc230c6c34969a2e081ac77e8f9d45128a6e8fff923c7647a0f168fee18342bc6d845", "Name": "matter_g2_multiexp_85", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f114e56d10dba7945d125fe1ab7871d9510771548d8388a2aec8a481de92572645b73631f9a60285c3eebcacb3bc0f5000000000000000000000000000000000667d3f31955df11e4e7896a1856fbd4e573f1cfc906b3953b5806a5d01dcdb96009d9f148156a3828e822435f722c5e000000000000000000000000000000000d7740ae776eb4766999f5671315c8965ccc84ff71757e361fbbb55babeefb96265c97df8892acdd6a9166641f656e62000000000000000000000000000000000166529d1a76ad784557384cb971728dba298baacc2f2a39ee36516bc7a761e9a7c29e385cf5784efb9f6e60e998b01e864a1ee754f6b0a86923e5501d54e6f47d7ab9e1483294ce98be13b7db52937100000000000000000000000000000000133e0b08430d9318d98bcf58b3d8f51c7b717fab56fe25f434bf521f830c7d4247d87d3df910490be2ad38adaa8eec26000000000000000000000000000000000e15afaee4f1ce6290ddfbc13cb887e540efc3fd8150dfbf3a5e7c759ccb8f334ba26953c7bbc43b5234b857159f6722000000000000000000000000000000000e4cc685524d42ea5e435afec7b3d7d025e93ea06407a28c246a39dee8ae77514a0bb2d5031f7367d658027299762bea0000000000000000000000000000000001b231237f7b0538d51adfa4ff92bf313507996cf5255f191875970ed4d946cffa8620b44045f4bcfd8f89baadd331fd93064d187f7d21b8b0a7092943de13b96c2e1ac9b578637a6e64331e2d40f53900000000000000000000000000000000084128f1848b2b244e4812eccba01287b9d07e85450459c8c42b01180bdd843058d9926f39e2fb5f610651a00233e31f000000000000000000000000000000000055ee70765f2cccac966dc08abd4bba0d004b379a2c6bf188f300f5d413f84e77ca1d462219bfb820d7f585b914a52f0000000000000000000000000000000002dd8f1d1cd85a5e6ac793f7e1e3cff887204aa4a5fed92f2088c06eae95842ab2c04d30d56f4b0fcfe61379e8e7c6940000000000000000000000000000000013e318f8b6f4165a8096c76ada440154901de42d69c38e66d9df4ffe5476666ecf7068e7163f29f04972682c43f3b0fd5e676b40c09f80be5d9398a9ec20cb811cf6819a130445203d792a4d34fc3e950000000000000000000000000000000003415c8bab713aa18d3f0d54e0101ba36793e6e9dd3471f8eed9a15e00d8312732a9ce88b5f0c30207aed92eb173ac680000000000000000000000000000000008a7e145e9576be8ba2fd980fb1735a2b73d1bf5f3e108878b721b6ed8378b5e0f03ecac179a6d148541096ba483b40200000000000000000000000000000000029e5554752db8bb87d58275268f24ccfcf3e0923744d57473d54a72e2cccb847eaa8f3bf638833a934c43930fbf30990000000000000000000000000000000000e0f2ead2697110a132c4ce1643b97fc652dd0660deadaa4e0c45e7ebfa64cb6a6fbbaac7c4e2b725beeadf6881ae5893f63a87972dd11f5239c35ce269e4b9239e3ae906ab117f1f045d3acfd16ca00000000000000000000000000000000014325fcc087aa108f152b42759cbc02cfa24e7e7cb995c78ccaa9a283ec2029c08cd747d599e0685d365ee99eeafca880000000000000000000000000000000011da603d3a1128329af19e596ebeaa4bad034c59581e9fa2e42a0260032f84654bf5ce22ee32c34eed7515d7fb0fade0000000000000000000000000000000000189cdb5b934cc1ec7ea0cf4b8158a1416712bb59c1650e6d244de33bebfffd3691b499b3ff8255b1b513deba709f7d3000000000000000000000000000000000e7ab2b279d0d5933df25d8fc4faeb8ca907e7bb8588e618b92737fcb6959380abc205118d2e3fc128b89a2ead5ca906145e3456d5ca6aa5910430e5a19567c327b757377aef98c4f46fe9a1f52cdc5e000000000000000000000000000000000895b6777e677732c74cfa82d5348c4c8ddd63ce10347836f5140b9a64dfe631804ea3be8e20bd4438f5e7fa14a121d80000000000000000000000000000000002422cc4781f007f732239ff9eedc126777d6ca0f0365dd90bab6b68c9e3d02ce726726a6d30d7d51a1f0b45aec1854100000000000000000000000000000000048af8a79663aefaff77a934f0af3a09ba02077c13a794ddb88e5c679ce348b3ab0fa217954ce1422f4e212d1383ebdc000000000000000000000000000000001190fec6c510b0b16e1505f737b25dc2401e9fc2c95bca92aa5d6e93b284b766bfed93a80b137e5fcb339983a86acd41ce27de5d3a5ef941d058a458f3ad2a386f1d66945789e51fa330fd65da4cd5080000000000000000000000000000000014fbf4d005f43563fb7408d1f20f672c8983120c66462ba9156b64a287e66960fecb41ca129b6b14466a5a0de91b81c50000000000000000000000000000000004fb283724950174d60f64af7bc8a7d059431332c8f17769df33f6607d72633aae3a8d595cb8d5af3f8909297844b3a0000000000000000000000000000000000e187476a19280ad9f33a55c50f37f765e343f92938e247ec9fe099c7f3df65e24af14885539bfcf3efe3bde9f2700ce000000000000000000000000000000000f086e6b9e845fe3b0c5100f82bc8aeaed166bed9fa4d34bc03ed86342a997101c508a4c096c4f67cb5791cc1a1fdb8187bf5c4624e86aaead712987f313e5db8f2fe6787fc33481ed6e5c4d3e96d5be0000000000000000000000000000000018dbe48c54347635d4b6bc17ff5ba390a73925f1b180d2c516eafc0936aa9bddaf7317cc0c211fb2a7f7bb096369a45d0000000000000000000000000000000015544c177a4b8018ed60c2639b43236957c2d995fb0f32523654584b0bf052e0930366a93406e1ec5c6d2edb955e811d000000000000000000000000000000000802d2cdbc5e15b25c77ded4bdba087f1d5760e6ebf9549a37f3314b1e88d3d6f58da9d8c6e9ef85028a271b83dd6242000000000000000000000000000000001577bfeaf213ca8b0983cb178e9634dd18f74baf02f6ca31b2e3b287d80a32d4cf11afc71df09ca5bb0bc8e60fc7ffa968cfa3fd0692c9ce56538bf70e77e2a47534d9472ac702c53f2dbe68217d53df0000000000000000000000000000000007c059044ce0c15bc527b19ce85cade8b1d5a9cc6dd304ce9a3c461e631e17c4feec52a0ab5cfab6a2270c75f73df86e00000000000000000000000000000000076344286cedc8c180e3bd762f12ac08f0ecc51293b9f9b8e7c0056ceba1bbb6fab4ee39cf559fdbd601db6c3d201199000000000000000000000000000000000bf6e708d0a4fd85c7566804e19f21f7a00bcc3bd7135f6639ad30aafef2ed1e72c84c8995b0e59738c2bf1e4040621b0000000000000000000000000000000018ff3d0ade15b690b6e306adaa5c10796b78ed7f8a984f637271cccfd39fd17c1e8288a11b051ca94de2a9bd04fa96d7a36b13ef742bfe88882a4e635b5fdbd9b079e1adf3423dd4962835c68c9617c500000000000000000000000000000000025cb808922f6deb0bed979b80a675d9324cf25c53de373534d771afd919a182af9aa1dc26a2d0284887121bf4d6b6470000000000000000000000000000000018970aa4f456c1b203817322df2e222516bce67ff9ace069599061c6229596e506c0286171f3551302e45b7d3b69a39f000000000000000000000000000000000a57d0da60f03fd4a5664546f9809c771ab6188aca5102c31f26b09950cadc26b0275417ddd9c4f4cf29794b739733cf0000000000000000000000000000000004ebf2bd93d7921d8bd97ee71cadf91145e064a33651da2604ed6fc8e08b1b8305005f12fd4e6b68b7b6a3b5cf123b1324c54daa7de8446e5a26cdbd6741cc90bfd26c544fdf221d47d509c978723c3b000000000000000000000000000000000c8ff29d0333e3f38fd8af91ecdca49e54ea5dced71b60d693b1bbade99ae668e4f994f7a5417a08a8ddafa410d437f300000000000000000000000000000000078ac1d0898a9e6cae29fe6b50e435e5f543d0ee233346728c46d659c4338295f27b42fc4b2851ad5035feab2bea8871000000000000000000000000000000000b3a566d2ef4467f21c27e4a3dec99a26c304b32ba1fcce8276a8518383a7de44de5b4011ba738dbb8761e67e36115560000000000000000000000000000000015a0aab8c3d51fc3fc8aa35dcd07f8a08188976883f9d3ccc87ee148525f2115ca46726a2e3c550167c169977b216d6217ff7a416011549f144a3a65238d62395f4f76afc09496902c064b27739c6d0a00000000000000000000000000000000115589e8e1440edcfe72c008f6e9cdf13fb7baaf70aee16166e7f32f4651db784f4c5cac15d91ee13001169fa777f0d00000000000000000000000000000000000f86710678b01c8f648bab2289e8f90648d9470cb13d5145ade526696d22508a4a59164290586c2c000dfc55b4a20350000000000000000000000000000000019b300961b40b0d9fe6e292e9357d04f0483ab3a8cc6f8f522153c51d22de8e96a812adf720d13ff7d05d1e68264638a000000000000000000000000000000000a80b61ab051ce413ec838167fce393f88c8a25f403bdf07cb60391fb15306a5271a7042d36f7c46b5978106a7b5293c4615de9bd7aebf1acedd9d40fddda34e4a85bc253c5e92c20d984f6c4cec533c000000000000000000000000000000000567c33d22805319418cb1ea7eca6205a6c44f1f881c03e37bf3c66a1baa5153473cc73b8c25d497b0b0057ceb0395960000000000000000000000000000000014d7a2bfeea6a746e709f6108eb32581ba38a617e4450b3567c77a992988d91f4da31b209286f8e9fd0d7b8628aa6c4e000000000000000000000000000000000ae6c9fbf0e06f2e38e91699cd21596ba90f92f6022a4f3c7c8a6557b7e1331283bd4d7a7d31d77d9d7cf70a2945ea1600000000000000000000000000000000066b8132c73e1da8ae7fec9169770a188b686f223fd0306441356040bc9070f34a47fe1bb8c94de9fd7606c18b1d2b1dd38f1a0417a5a366dd2d8f5ce229afb6f34c1b663ad6eb1d9ff12f38412f00f7000000000000000000000000000000001460040d0a19c37fb0736ebdac0324d8a38c94a73fc5f602b7ea5b7255be9d4b6ffc22fea5043d948420e9ae3476f56a000000000000000000000000000000000b37c0078ab8babcefa8874c6cd1c5184d713b976852d087ed84337073fab3054899859d0fac2f4351bb75ee0e534fa70000000000000000000000000000000004150f3b98e6166d9d6b0388342042dd8eff9b8e1239f479330b64c5b316f98fc7bb401b737efb87e1f6663ca4efa26700000000000000000000000000000000043e6131c1ff621fd6f8caf0939487a927550343e24425ada33cf622de757e6e75c9affff9f04373a954557181641617364da9c6b07aada98107447afbb189626180c5eef31f7f2cf26d5d76ab0c74590000000000000000000000000000000009fa1754bbc957d2a8317a2eed859457073571379cc7c6d65bc6a0b5829f8142db77654eb98a2bb0cfa5223a27d756cd000000000000000000000000000000000cfe8b8fbbff7507d3d74f4f550b4c85e19b8929d3728a462e12b4008c79014103153c69ed8dc6b743e1b6fb4720bad00000000000000000000000000000000017ca0c08c320c12502a1dbc841425694bde68b7806eddbb40702e58ed26c7e112f9a821a6c67afed174f51896ec2287300000000000000000000000000000000014d08df9cf825b07a387642ac9959e8cd15ea8e752231a3047fa30816acb1ecb79f1755484af9a98b993f50128c2bf5031aa8d860e3b598ad0c4e9f93f26d153f8a8d8d0dd614ba868ed055c517532f000000000000000000000000000000000273b64e867a9111e257c9b32484655e4d7e676ec50f174d9ebc9fc4262c037b176ada941dd8c1abf645e275dde04f4a0000000000000000000000000000000008a63b9604e96a5034d92e3790411f3112c2c7cdaa056f9f1bdfc0b164c37fc9f58dbb566337132cd1626f9ca2618f800000000000000000000000000000000006a661167c9fb6c26bfe0a3902f309fa683fd22729bfcb433756182e7e1a406bf44ae1d13ef0228534881daa339394e400000000000000000000000000000000193c6c5ec200d225c43c6e37cfd15e16e49b7d87e5515bb7b4c918903966f4f6ae0d42af6b98f6efdedc9b0301fa1c0f290c467c4827c9252b82ff523633ba116c52d15df9cd4e3121ff0e9f754ced5f", "Expected": "000000000000000000000000000000001403c7e3059135ebcf5e752011fdfaf66e348135314f3f4239b066e1c6192ffcaf89bad4228fcc2be19a64f4f5386f5e000000000000000000000000000000000aadbd8d0e53d5b409f7fa508089337bcf36212a3f613b37a95757793dd6b0ca99d1b3578ad8020d46e29c9c4197ea070000000000000000000000000000000019e43bb32f92ed187fc32d9dbe24a486e38316a3cec0fd7f7c19b313af43a10fd63738b78e609e04a083de6761d53a90000000000000000000000000000000001490da7d36ff16304b27f6e57412975497e9f3a6d35cb162464bcf69fe141d34ae27a33afc75a2802eb120e90d4897bb", "Name": "matter_g2_multiexp_86", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000038ee0c2c409d8832437ea450ed705589c82791b8319fd0ba6fb4d302d3c5b73ea0521a0253716e5810f03fca2e9dc720000000000000000000000000000000018c9d748aa685bf6e11e6e4b6ad2290ceff59c8837a088b41a08983fb2c5ef077adb0730b298c5df9aa02a820a19a4bd00000000000000000000000000000000015d248426e362ad2489c0c6a567d80b22d54d6a79e198198a771fae4c4e97eb317da9feba8eaafc9460ef45b1a5e5690000000000000000000000000000000005a2342412801cb37911a04d7ee3b1e5d3dce2a06e0658d59f2ddcaa9ba32804a1ddbe8f4d00f4436aad1346ed1ea5344aaa57782608de34c6334ce5039c67767f6da7b315dcfc772f03aaf3dd1e67b90000000000000000000000000000000019d49748f05458cb9b316e433b0d341e23bb5aaa724b824bd147596761c11efe8f4940eae09e302e563e14e96b814f4a0000000000000000000000000000000018011e7ee4988da168adbcf81cd14a9232edacc06bbfef0fc78dc0f96b5ac86ea67be8661442b5ef60e3889f3137182200000000000000000000000000000000175a2ae3bdade6551b23656c16884ba0fd4247df4ba7471cf81022d7e224b23490db153c8289f95467ddf9671f8b6cf90000000000000000000000000000000013c58c0f55c46bced98faf3865e3b6a836252f252e97b6d2a799b574dc569f09ce33082880a4d0c3b8a2c7c0d4c30eae22c1cde67b0e8ec7217c6ec72f36d8a1e73794297819de9ef6f1e52acbd3ec4a000000000000000000000000000000000ee45d5689a8ea6132d5ace000699a157c1cea3c0c98b38d504153d64fcaf1702ac7a1cb0889539d6b15489fef415aef000000000000000000000000000000000b320e0cdedbdc1fc5733488e6d2aece6386a030adc36b0a69dc3809827319947049f3861c2edc859797d30a3689322b00000000000000000000000000000000194096079b3a1d6ab1080dc71bf6d5734bc7b5e7f30bbb0f9b95c9495a6bc4adf76e198fc66accbbbaac215a8932d8c5000000000000000000000000000000000ec07be0cfa9b3d3a64c016471d9e6d25228b46dcaca6e197be00b9ca5087162c35f1d6326a3cf83f568cb06da8c5220895341f4363b688c4e9660fb0cd17f6c111a5c92e732205fab0d0da0175f6832000000000000000000000000000000000a7f3a3fcf2e7b0ada6d4fce179bdf229454002f1271a39d5e99daae72da549c6ccfc7c574f35bb9784100675c30b1120000000000000000000000000000000000fad14ab095fa09bea919ada313727e7aa5aa06a1cc7746d006e3eaf70f79c5e4001a8a8de03540b45e0598b22710e00000000000000000000000000000000015345ade62c5691690c181da09d8f39c1ead42046987b8c7c975d40690a286a816f8cca519731d0ca23349c54b30d8570000000000000000000000000000000019f0a32361bb6ecd8b1d87c2e15d31c0e0cf995eac9facd5eca123c0799c465f156b0142d98e0f315e9b3595974a7b824c5718fed7503c5e2a97fd6ab0294d6c42b1d35067e9d5ec1077176a4bd3126f0000000000000000000000000000000017af46e78904915e348734d2450fc6e1938bcf002989f855082e3b4ff3366d81ee8d28293609c3c3b11568668b1305f80000000000000000000000000000000018b0b3859763c2654fc00792a5193b7317fa5051bcfd15ea42be2fda0f43adf322219f34e54b2446ef73a4562151f9a70000000000000000000000000000000015c23509a1b324c649ff878d004ab5f253d041670ef172ec4dabec7a525d5ddb8f9f62f383e3f71b0e9c98532e247d560000000000000000000000000000000003a38564a55fdbe05b047281fa153f736edbf48c901749005473255333590f967171a6fc88751eaf57a5335bbfb6ebe86d055ad484f5054e8bd0d073cd556deba05418ef1235d08ecbf8717b550933fa00000000000000000000000000000000100322c4a92c136437714a6586c82a6842027ee218bf1fdfffaf95ce47c9c8b6c8f61115b092dff81ff2e645d0a7a4340000000000000000000000000000000013a91ed8629acb5e770683015c3c248255d673d4b2e6c96334d1c80326d1a8b4b655c81175e4a914a45fb37c1f178bd10000000000000000000000000000000019075c2eea3f64f42be82fdb8f83f2c68c08e858702a0225d869143c0b017b76a7a40d809116ffbdff6700b288f5ca3b000000000000000000000000000000000598ee9ba9d56400b59c7f5977aef1e179855a37179fbfe97b95f19137b6034568e5c7f616943b4aca804272955d42334cccbb062c27a67ae2783ab65a47ce166330cfced1f11b85f87483e0250b138400000000000000000000000000000000025a526b137aaab5ac1b5f8179a18b06feb7c905b4a843cd55e31b7464c2b6d432b569e9bfc3222511c18255102aba5b00000000000000000000000000000000090c20c9f78a242e52daa339d5cc1c3f35aff7ab802a3e4366597db8b6ca43d30fa0fe8d9484e49fa4fd0bf5509f19e6000000000000000000000000000000000e928b2173e32e5fc9c373a2a6f126e1a3a472c01a5e87677be0d29907022b9a7dbec3340cfc89e67377ce472c2d5d4c00000000000000000000000000000000147b4eaa2dcee39b918b7cdf24483b29466120677e5d42b51353a9b2fa207bd911d9b391142a13a212d0ab38adcbe10796111cb1181f048f51349aa2953bba2af50f7b7b5d2328d435bd63a7df5cfe5c00000000000000000000000000000000007790cde9ff8af2d7597d33909f00963eafa228817de1ebf4233ef0831202700b99641318186aec80ac913a1b1143eb0000000000000000000000000000000009d42ea1386d8b019dcd26068ab156f399c35b7d492722a20da0c915f7abe44ba688d9486f4bbb44268542c5a49168930000000000000000000000000000000010611f233bc1c4af0a14e1d1b945c91c077ec3dda592e2f852e2de41e09331664e1a92f9a0b7416c50327bc943a17b9e00000000000000000000000000000000048614243262dd070a754f40652b96a03326fc51273dddabed85df0654890ff38e0da7abb8190e4ebefdd6f78a5fec509d7f0c0c7e927bed3fb930fe2d0109f58678969ac8e14fabdf4ccdd0823f706d0000000000000000000000000000000008451d24fdc873c61db44e57372d43c35a2a8098255f9aad3a6b244913b86bff6444042e391685b1244f009c5ccde935000000000000000000000000000000001177c2da9972a2b96afaf866f97dc149482fbaaa93e194803c09c8334c2c7025e08cad4f7898959a57b07a545ecf76ad0000000000000000000000000000000016f40426cbd1f0f4ca5ae1dfa4c3960a6fbd51a1b5b24ff5d03fb9911e908406a0ecf4f20a78a280d24dc9bdd1c0799b00000000000000000000000000000000194a8c55f549da1842cc3173f3eb7bfd70df26b43a3059a3590992e34fb19b2caac4149f64d442965e166225b9013e2b11ce517fad2609f2ab8d44ae6263623a7903b2cbec683570949a96fad78fc6d3000000000000000000000000000000000a97664c1d7624cae0e969c728a84130fe260581305435ff8ec701cdc51a73977f58c891ecee637eb6b7c972069ebbb80000000000000000000000000000000003f4ed6a9e9f4229f0fb35394bbc10da9adbf4985d4453da64eb312ec88cb15bdc189a3b5df1af3107a36fc001ec92ad000000000000000000000000000000000ac552c5f6170a70563fcdca8e0c6a7c6135af2f9d5ae6f60a2c459d1be4cf76ebcdf9bcd891db8a1e2fc905a23a97b4000000000000000000000000000000001734a46c99e776d1ed4b807f5b313562e0989ad5c67dbcb961c134f8b7b7601c23308839569dc224bdf7c370c4498303b17d28cbcb9efde6d9cdc4c9cda385ce598ac8468d4fc94cc8e98ca3bfadf440000000000000000000000000000000000a523182c886671435ccc75cbc78293274802c6142465acb31a1809e43b1d656ed9c808068de167b1ab126ed0f73a4490000000000000000000000000000000007c4616080b5a002fea3589d54c7510884a3ece705d27dee315851746b1ee748e8a08d3516d8c6afe1c0482b960a9c62000000000000000000000000000000000dd1bd9b4b9c140aeb97887a0266bfb5696813fea034b78bb7d0cf1cca15b5bb0ed92a97841c8d8cc614f7721b8b7e040000000000000000000000000000000012a41a8941b6f0e4c87f8188718f9bc75305d41d6f4441eb9682473340fce0bbb463e1b922d3af8daea32b8a8ac9c3b4a9516e93416bc7b0f3c5ef5da6112abb73fc285a14093ed19d8eddf241169119000000000000000000000000000000001763ab2b361681955735ae00b69f26e06469391af993c8dc6f2e1dffb52ca01e49d58d6e2249e7433ccfb5ddaf8fead40000000000000000000000000000000003858f3bb01b2393aa4d4d7889bdeb0bb9bcde0dcb9b39c4ffe0fcd0b865baaff75b676c715be275929ff4303c416e0800000000000000000000000000000000086d64bd1302b0b3a620b87ac29cac3d9e606513ec8b47898cd852bf552c1364291aaa842616b92c8936e076e59451bd000000000000000000000000000000000967c9f59c15ed02c9b2da6e76fb0bf3d445ba849010afb7f9c994b1ef6a05ad577570d4adad043796eb90e51537ce5187fed462636eb57506f870ed1c8f66e211758327f4c19bf909a6419312c58945000000000000000000000000000000000e6b0da7b406bcac2dbb90fbf430fda6442cc2860ce633ab84404dfbb426949d55ecd72992da1a2e8e1ce229b599232c000000000000000000000000000000000fbe3a345ffc8fb85cedc4b8dedf9d952c41b4ff6f1c7ff4cf91b2276621969d905aa9aae5fc89bc516f96b9bd1bb3c10000000000000000000000000000000018c2a7fcc35099c41bb851ff66abb047e2af9cf4fa9fc45f030124ea2c7efd26e594abbfc7a7f258c8081a3a80d15105000000000000000000000000000000000a27cd33c2121c9c542e27b52a13275ef7e81dc0c6ece883b65e71d2bc3e7246f95aef7c6b41eace382a1400568cf298c373d64034c78482d6673c6906553151887c8aa28ab2930659671b8cb98a595700000000000000000000000000000000158bd8e6198d22b52efb7f3b945668666e1190a4a8e70307ba5c1b737316a8f8568092f219f683c0f53f56f25745d4e600000000000000000000000000000000097e64e4553371c81a9bf553ddd9719f59b329284eca0d76f023d603c29a034d123ab777cf173c5f2bbc66412d69d4ce000000000000000000000000000000001298cd5501e136a06ad4fcf87a75c0c7b96c73e844863b74bf6aa581a0ea98c2b1f608c668743a3e37ad5ca2074af9340000000000000000000000000000000017ff9f1336d7f2152f17daddde9d3e1679cab8120ed2c0288b0908d4e2099a08c9bc6f79425f004ea3ac4d684abff6dcf29c901f9769a42610958a8cd53eaacd9e5c4656106fab536052518b4989911700000000000000000000000000000000115baaab8f0331894da531ab557bb454e2003010ba1dc1d96e3d983d49b1312585c6d4c43d85dc074b23b2fb28c8a1d6000000000000000000000000000000000db1621b721c8a54ece26a355b190af5f3e1dc1b43e0827a1912ace651cbad4b980e77a4c3566aa809157229b234c808000000000000000000000000000000000c594e0ed3f7ee55886e251deef9732aea3de11f094ec53907a843b755add8fa5d00779a66621e615ba7772ee821c4030000000000000000000000000000000004e80aeff6c4b85188903b4d2dcac4f94f7cb4285a38f94b0becb556d83dce8735d1db5810b409d45a8dd1b9a6dde29c125c12599e84b7e648aab52cd68fcca7f1a5f56c854f3c36e0445ab7e2df2b740000000000000000000000000000000000371a74468ce2ad90e19b7fe3f57159dffb1b0422b32ad693b2fe6c45c5d371b97a90054095da887019d25c1ee8197800000000000000000000000000000000010575e1ec9a3e609ca086ef8bca679c4548482d9e0da2e51878158ac8e5b29d824c31ad7ff642041e748efc50c2514e000000000000000000000000000000000ef36130380f1e84b2f462b5f970abb8535431b79813015261015c6d7e74f038b47504de01794840d93fbbb4b386e17500000000000000000000000000000000018419e85fc2d75f007d1e0e02c1975332e03d42c3b41c50c3538c3625e702161cdcf8913babd2995aea7566ff15abf2bb9a1d051e33a617c25e17b7ca8ae6b02f16c759cae0df7fbd403372eb2407f6", "Expected": "00000000000000000000000000000000125406a942ae0119575453beb4c093d2696d3bea7bc031d7a586439197f848e1d5a82b925b4e96138a3460eecf198ffa000000000000000000000000000000000befcee6bd1412c54674a3d519dd2813b87b18f2ab3375a731197e9f539f8f8fff634f15647e7fea3c65b93594343c2000000000000000000000000000000000011e4d432ee6babd502a9cbbb5cf4839dc6da6176b6bb0ba51d99a3587465f5f3f83f4d4cf2c7e6187de93b859ca61d800000000000000000000000000000000168509010b867aa198fc294a5879ce14a51503c1d0e8fbc02ec08cf62afbd357ceac24b633bd0fa99f83dda92e10724b", "Name": "matter_g2_multiexp_87", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000070a0d060c6e9bad0d1bb15417578daaa8b7a5c984c4947dba10fd874d93fd1e3994337c87799d78a674087678d9168f00000000000000000000000000000000128985b69d5d6ea0ad0b19eba7c2b430f5242a7e89626c66fb83b58ca7cb65a479de4b2fca6886cf55b8cfb52394102a000000000000000000000000000000000bb0bced708571662af042d18956b5b7d797b61aba70823618682287deebe69bf1f9a94ca4059e0570e25a39e60b9a8b00000000000000000000000000000000193f0793324dc78c40f356dde030b632feeb1609a1bd75ce88f0d313a0864dbf1f5e92826870866ab9b3c98cd1c12aa508c35887835bf4497d673936f40ed44145c5d5009fae16eb0f3ee9168831abf7000000000000000000000000000000000a61a310f90a5ffde617b78f784b2e699cd77e7c3e7c483a2ccb768f94d68e59a2a4521410c22ef6f21ba589ec3abdcc000000000000000000000000000000000e6568c83e0f7e459b27a28e5bf954983c5dee478a009c244da16041e710ddc67479cdb3da6f47e7203fedb8f765b2490000000000000000000000000000000001c5cf6b948b85a1c426fe932cd87605f1fbf6c932756eb1bfb43beaf012bec4612d8dd0840efd4cba3f5394beb65112000000000000000000000000000000000e02d5bc20c40d7cc2165a21ab37c6e4eb71322c01a43f2085f93b5b02bcabcd668dab90323db0f9288737d757997631a0154f7f8d52319c9e5cd59052e91b84640efe83ac814d95370e46aff4334cf400000000000000000000000000000000165287d72eca1ecda5fe16a555245b0a34a04beaf9177466bfd88bbc675442d206e70f7a2063b6ed0e15e9406232f5ea0000000000000000000000000000000004c0608bd7e01e65a15716b0c505111a3abb0abac3efb846e05e8db59c063950dcee052f04d1c4e9e492bc6740fafe6d000000000000000000000000000000000de897f7ebaf9089f7e198ee41e1efd7d84fbec7327799b9293a489965cd36159442eb0dc1f79f6b1f122f592b013bb30000000000000000000000000000000009774586dc359e5d20486f00dcea6ff93948c5a8b74058645d1048fe46ae3330dd56d85204d328f43f15e674020f353ec252ac28ea29b5459cd2ae5bce4bf08a102280c093b9962cafb481016a212709000000000000000000000000000000000438ee51a560aa419ad6ae45e1014c38b7c43f1f6a512bccc2d4f10a35838369b71799fab4b6a754fd938c1a1b874fc0000000000000000000000000000000000c1491c85965c0b74d08f5866ca727fd30bf641a6ada0ab8363ff01916c37d10b1b7eccff79b396c587d9beca2c826c0000000000000000000000000000000001452f254ceae9626443265ba31a1a750a425f2a7789e69cde16b70eb319c744a6221e74a9e2881c6bafea161d29638df0000000000000000000000000000000011bd6a1bbded174e9cb95d74492f7b07a755339a6c40f2a1a76debccc0f3a32c7017ca4e6679fb2c038c751f19986f526d3bb5ee3410dfad575b0fbe71ac5df2048f74b52e777fe0955d6e244d434f3b00000000000000000000000000000000139157c34aaf70cbfaa82be655281b085e37d6406df4cf8e291b221394e91d9e3cf04d431f15436064d0bfc8cbe13701000000000000000000000000000000000353fcf6e587e71e59d8f05d4085961d37b1f62694dd5c7f40efb5875b90459dd66c4d2d6c01a40834307ae9e82c2e08000000000000000000000000000000000a4975c9872fd167d0ff4cc80a6ce179b1e6e1eb21c8de80321451b1deffe68d8a13db26218f14935b64af25d63644c10000000000000000000000000000000001e8a2824f21cda745a24844ac0336994fb18e30608ac61201a932c0a5a58f1acd56cbd9353bfab4944efcf2859ad5915c30684c596976bf46384e6afb2bad6f821c4a62338d7a6eb204ed75070b1973000000000000000000000000000000000537d7a9d7d9dc451cba4d50630caed32e182cbbd95212577b8c2855c327530e447a4f3d73c7d63fa3ad5111254c9ed90000000000000000000000000000000006984b32955fac4ad3c0d181c81b98534ebaddc316d51a40baa1028bacd6a93a20d4bd6cad6a0f8cf7ade96bcd4d68dd000000000000000000000000000000000720c392a663884ad4d8daeb7279ac41717ea602108c76519da13a45a77d2acafee842828f5ccfcd786bf7ea88afd01600000000000000000000000000000000081f1d3e37ebaacc11671bfe1670ed65ece2aee0e3b5d746a8d618b44bd4b7dea905eb8e958bc026a092b2bd5a7b87cb11009058bb8e23b0a4294b5cae63aff10265e729d3601d85dd7f1e8063ce260a00000000000000000000000000000000005af33731879a574f39dca99c5c1b9517eda13121221be77a0c1bac82fbf29b37889c15a9d32531a3f6bf9137ce82dc000000000000000000000000000000000c62939f00d70a07a85804cd97fd34b9764565bdba225cdd7549729ceb9735bf4d09a80ec3055c483e1e24b66c41e403000000000000000000000000000000000e415677988c9d4656e59f77c608926c83028f91bf4c0634120b5f774ba07180b98141ffdf727cf9d0fc7a4cb52f4393000000000000000000000000000000000c9c37eaca857151a0c4a49b079f2f061e6a8ebb77e11eb32b29227529562f8dc8e2646e25469491eec5a07b11943f203e5489447bb9a5b661bcff2d9a4153a5aad975abdec380301b6d4ce019bf2cdf00000000000000000000000000000000015113f8f9100cd18427ff48038e1070fd835fce6c0812b7bafa679ac733c80bef56492ec3ca08c1117bd0edf19cb26f000000000000000000000000000000000789cd90c0be1de5d0b359c030d4b9d8aef93951e26870e37c375b9e7879cf277971a05babd319a3a6ac53f00f3254e40000000000000000000000000000000019b1cb91c9a1b1ee49c3837339778806bf0c093f171c92c9931ad43e35fc61cc08dafaf55b7b9e0f49dac28a12bcf92d00000000000000000000000000000000066c7864631333226f191e313436453e59f48f91d42e68874fa4da45eeda1f6f7f6342204e64e124d5ecd861f02ef4f00444d520ee01d87407747a4ac37abb7bd4e4c4f1735ca7458cc2e4dcb1d6297c00000000000000000000000000000000129d887d694be0ef2f84c343a9aebd0a2aaf19a4e78586470351ffaf0b1309593363bd9c6e7fe39a6e59445d935414ef000000000000000000000000000000000596d7061c2399b6a9be7d4d495e58c0377b18db1e45cf3eb431d10cb8b15ae42548a86a26086d57b1a71cb5857d7917000000000000000000000000000000000cce7181fc87dfe1bb493043279a5d93cb2d980eed38dab2ace8c9fb335c2890447434d80df6e7c95729933ada7b9d8f000000000000000000000000000000000f0e1274ff70bc6d3f1d0d5b251ae528ed94aa3a1b9bbdb260892bfaa6213892071b8a6407abe26105b2f81df90569492035cab8f8120ea8e91389707a290db4ee69875d7429c6857e74e8bd40dc7360000000000000000000000000000000001192050735b114c19eb2bb9aa01f04d1fd9bed4df877113a14f7fbc9c31acc10db3ed0e0d15d8433e7408bc237c985b9000000000000000000000000000000000a8a66cda780790311b56836fe69479c7b94dbc6c82ed5886887dbb539a40390ebb2683c04078ed105e639a2ed8732a1000000000000000000000000000000001678ddff677b99011c73e0c9875b5b2ba063170f4d565d261b4c6d3263ccce0334b5bbb7ee08692568037fa96782e48b000000000000000000000000000000000ae15f79ad7f790f8ceaf7709f4b5da71642da0c1f7c442eeaeb165c7dacd8a4892fdfc8447a03a7c56e12513499e43c4bec711286827f0941ffbb451a8eba871239341a60e3aaef23487175c9d2e8260000000000000000000000000000000007fcb5ea5358074d06b64c5f46454e682dd9ac2127374c83f3ac5ad46bc5fd2fff7c5a80ffc669a1c159ee8c9a01bd37000000000000000000000000000000001010ada1bd493d6282ac2d3582480f50074a02fdf412c63e93c5857974626ff464150c20bdf23a87692bfe69a075eeb300000000000000000000000000000000086bb5664a8738f02af5517aec4c6db47653a6d76bd4b5e37ba4d8b27a7819e82e6a4c7ba4f8377e06a5878e7c0bffbc000000000000000000000000000000000be1463ab76e468e47e1711c158dc9bb10d1278f5cc676cff937f60ba457061bacdad7b8d3286f40219963b147cce4bd369d91a4d575d4c142b98a53115a792ec50a290608ad316465487762e83f3a86000000000000000000000000000000000c3329d1e1c76b0bcc7ca3766b2cc5ec8169690f45e0ea3e37b7173bfd6c884921c7523ff25391a85b47d5de395ca63b00000000000000000000000000000000081ff066c008d5a4c893a636d24e9752c6a06666dcbf80082167610e73a32d70aae3e58c88ffaa27f05260b86b11f72a000000000000000000000000000000001178e88c652d257888cda1c0b65ee2c0636184194fef9e6ae3791a85417c43a31fe75893773ff3e7b4d4cda9eafa8de40000000000000000000000000000000019657ec4604ab5e8812237a28e5ff320a0d728c60c541142ffd87fec2c703665638e5eebc33e308d5582cd043d08d788ee472561535a7710db521976cef0c92a4ed89861ecb397cbcfafa477756e8e120000000000000000000000000000000010789200f69d8acc70f108145804b62b521a30a04176c449f52bedff5975ad7b273aaf4a32f8461ced8e92b2229e2cef000000000000000000000000000000001178c36174cdb783b5b09d419ae4a154512bf9ce07368521d1576b2f1bf39f98be29bf533bad16ba9d96aae621612aa70000000000000000000000000000000002580f2115d1814667b6178b6bffca6a4d992eb66e9601c0d21e32a5f3b69e3f85e1205c877b2dc2696a0e872c5bbc6c0000000000000000000000000000000002c94d7ff016d57bd5f589971344c6499577bc2234e18e6c8dfd7d27a205442a4236ac54fe279d1bbca76467530140b42cfdcb8240f183abec526344e8ceca6a007c35b757928803f854225d3a6ca36100000000000000000000000000000000108b6fef7396ef71b46339d421726f83b08320599d66da18234011720d2b524d24075a255d2771f1ae904958c50a9046000000000000000000000000000000000723d5045b65c0887da1bb01d874714ac86d21441119a93a1d5758957215f399f5ef1cbc00558db01b295bf0cc988cab000000000000000000000000000000000994914a3df9d3094dab0c0c41a45315dce5968a99e6171fc609ac9e50bee5ccac771efaa04067467e95709bd924973f000000000000000000000000000000000ac746602f804f52e9a485c30412adf92eb9af3f6daa8f23b974339a0ffa6f5aa1b70a80a9f19cde2a69a4b7251ecf5d60659743dc1977a698371cc302b7579b6d7d13632a31b47df369365fb02aff790000000000000000000000000000000000a2ffeaff148dc5f70fcf53e7e8d7b6100cd6e7df5b3fa4aa33bced243f15b4f77f48d25f74366a693404b6ed7d3075000000000000000000000000000000000f3e1b34ac8fde4caedf3d8c3e24db02de3f91487db300f09c779e7e4e96ae55229288abd946abcc3a8adaf18a0c89e000000000000000000000000000000000166a68c5191dd7f9d44eade2ef1a9b522dc062bba9c55e2ff03aef400e5d2765a12816b4ba51e10bc21e06113c8ddc5100000000000000000000000000000000109c00de20f7e827375c1841348e684fdb248fad116e9643dbda8be2bd06b71db264e9f2c40dec2092e7d518540a6d82652a5d4fdf6d6703c857fc7b10a741b95fbce91fe823d827cc7203be3b3bce0a0000000000000000000000000000000014ddb61173359514226c150a3343576b04fb1b06fabd8fe2f921fb3b90baf5513447c107f6d2f96c8b03274bfe451dca0000000000000000000000000000000001d1064860f6c4d62a282147308e80ceb0c5dd62f39b3232a231b1b287e497df31cbc5a3905a7687eb2f24447e50a395000000000000000000000000000000000859611bb3962955f92bff861e03d07bab7fe1f69e90c6bc7928be8d1758c9194ff7a52b16472d04564607b742543eaf0000000000000000000000000000000008a3e8396901a205a071aad06ba9812207171f33775eb358de4232826a5f0ff50ec3e137b1344b583849e8a5b424b46676a30abda185e7d280804952fc0c074ad907fea2aa54da4c3190895270169b20", "Expected": "0000000000000000000000000000000008c9db83241e7f3ae6c2eac8fdcff5f2d35318e24c3b4130e9bb7048a3b84a52fa3f222a8190121d2a5b8835bf911bb200000000000000000000000000000000002db79cbcbabf41bd8c715e024f4687bc0d058d76b8dbe58ffdb80918212ab6e9b35256fde583c0fe903c34a4c41ba70000000000000000000000000000000019f37d05f5c9e65c6f004e1aef03ff0e1899f0739c9cc4e9038e18f9d45678388454d144495b2cd993eb3691bf3e96f5000000000000000000000000000000000d8e0d7715ed71291729bf480f5fee7ae04264015732677488472bedc0dbacf8b35eef7adcce196e3bba9cac0991be81", "Name": "matter_g2_multiexp_88", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000064a134260b753af73df3764ab662e3b1bd624c8f3248e9bcf7676d8fb0825ab85ea33387d4641c81fb8ba3757e0870a000000000000000000000000000000000d67eff1936a395cd3f808ed7fc89f8b6a227c4849a6941d4bf762af6e41ae41c8114aeccc2565ba01fd902df530df1e000000000000000000000000000000000110ca2339832e7a9468844b94b3ced0c9216654bef1c8a5cf66385a99d5d452f978bbb7fe15fb477f56753488fc909b00000000000000000000000000000000173210b548d1b98b926539049996713f53108cd2911105235c1d5258360d5620d330951db67219ffaa304a67fd6219f39f4db766964c7855daea58d1205fe8da572aef06e0ca64912cec7c87bcb2f51f000000000000000000000000000000000f7c3795ac3d511f93a3d85e65261e4c09cd316787f74ced6e472a3993b7b5b0ce5a7c91d99559a8e0791f712cb4e1700000000000000000000000000000000018eacb2c5fa9221881c6311256a69c7616748deb3235c61cc11412860450151a25e3d6a220bb23e0b3e3325044fba68300000000000000000000000000000000121827286873ad31f58cb3889fd01cb7d0f91ff1c241295f6ef2dd0e8aa8638b63a7e6061efc2e7ca1d3579b4868f0460000000000000000000000000000000003a57315175d70880b2b53c67d61831ab066b08d7ac68637364ab1c1f3efad96d42a3cf5189c45012c1f73a1b97bdb4c1deebc727d98bdec47b5a1fc48916dca1e42345ff5474a5fd6cab0ae99e9f10800000000000000000000000000000000180648e5d0bf727101417f515cb9578bdde3e9f6c4176d516454ea7c32c1712610cc8bbed303bd1afd48f580ec11b77c000000000000000000000000000000000d6ffa9b85d69b67abb77f5c8bd776eae82d1cb055d2dcdea31ac66b1825014ec7f7a2aea320ef9f6897c9aac8c0706900000000000000000000000000000000073214fedbade28cc60ecfa4e1fe2fbc05f3d71528aca315312d50214f680956bb9e0fc12783843b00b3f4f0f52efe2700000000000000000000000000000000128f87e7da7b53f28944aeb26ef0f6c99d84038af51a1d242501ec84b5a6a8593ef1a0f6b523478d9fa12e36c2fdbe694b964d74259c216c1eccd7f2b52ffa5fcf151d47bd69bd2768e6466b32eb4fe50000000000000000000000000000000001443980d7450af1e19949fb328776cb7238a9b26240cddc565aa9d52c5592083b1533e8103dc07eac80e4bd830f209f000000000000000000000000000000000afdbea7f1cec534c03d3269d50017372f7ccbcba9f096fdb2754af4d6b4956decbab2b0afb69f97a03beeb20b4ccc31000000000000000000000000000000000a83dfa3197dc65097601457a97d0df7710e001e90657b150e289515609f13997b454167a7589ef218893309460139f300000000000000000000000000000000029c362244510c342358130f877de947acad5a379295f3149d5c713274316e06a169501f889e4b9cbf86f10b9521c1bb124ceb1dbc8004a4b1f8b422d394b0480bca7c0f38aafd8f06ba090a98a1d3c60000000000000000000000000000000010a83f13a185c70ca3f724dd84efcfa3ec463d7c05360056f8b5304864b20025b0a82c9d542ba08b645e2334f176472d000000000000000000000000000000000848a6a18bcf64d083e118190805d68f7ffea8b5a66e0807b9cd3733d31ffa5cc25dbfa6ada604646dcd8dfa622e08a30000000000000000000000000000000009962205c0ba43e5101fc3d5353f429a57a97bcb84baa0942a7e7facdfb0d032b9307aed8bd2ac9094a2e5b1460db7140000000000000000000000000000000019b1012661a10d31a4a73d0cb31f7eec0e7be729a42baf560c1e90a9124fe8d5fe31ecbb6d4954dba7d943a7af773eaa5a2bf15b2ed08b33056a0733c920741f86730dcda9c06aa0e3c135a844cef916000000000000000000000000000000000e7f02c1d2ceae60f314f51374b338c329f2eaa82553c3fc1643c7f1910ca24e277f3d658f552a47f780d4d9e0ac5e030000000000000000000000000000000014b6b56afc4afed5199191ec13dbeedd797f14ed493c25658a9658f031ac8d43de12e6a8c4b1671c9e5ef78da1a55e2600000000000000000000000000000000194d8a50618ff55ba3fa5602d41cbbeadc01a348ad1484c5e9aee5fb7241fcd9018f436e3c6c6dc64beaa241513a6c8300000000000000000000000000000000052681eac4bd59e160b67ebb27582a6d3ad5286d652787a0e160026607acfbfc5b9f38b9b171375079d052cb242b87fe8c3c919f31d72ab414f91938089430bbbeaa53ad7a73224fd3f204b80fa1ab87000000000000000000000000000000000d96ce83d917204e674ad9f5e5728651f5f23df25236b0fe769be48adf482ed8c36ad9c9abb6efa3719bd35324bd700800000000000000000000000000000000107f55ab0e5b60dbcc0632c345a9e93818014d7657b264031709275744e1c6722ec63aa209e655878a57704ca6cb3bc10000000000000000000000000000000018d97fba324431fa28b8845d94f62fc9eacc0253134b923908f06889d375405b51610ac21a75bdfb27e3533dd4debc22000000000000000000000000000000001667856804a5471238ffd64bf3bf266ce3a2351ebc68265674bc86ce6faa8dd50a3dfa00c647fb4265951b3a9607ab99f749063165c6db0eb038cb9f1a573de25bf377e1fee94f31df5987f7b2450aff000000000000000000000000000000000fde2fd0349e7a47a9b6858014d551aea569ef9802629bd9520e303ef0487c9d2d399682ac16ce6fa03adb6f4b478fa5000000000000000000000000000000001858ae58920dd0abd8ad94d2f9f946c53e050fe89c61f62fccad37e17f8723a4fbecb6b1be1e3cb853f045d0dca8e53e00000000000000000000000000000000093615a7f9d12e92c90706a47abe9620c4db41e95e42e478949745d6b73e021422e40b969e9e34263778c8a4d4907445000000000000000000000000000000001006ae7963b1e1c4d8c2c85175aca958758fb380019825b09ca3f728b5356254ae4fc670aa29812320b921b48a069df622d292cbcb836843acdd5a3fb404024174cd5c1cef632d1b9b6a73f2c5f705a3000000000000000000000000000000000ac407b75ea77789748e7607b5d6edb1d891875aeef2802715ddc393818fc8cbe82cde9f96377e3ac60107ddcda7e6610000000000000000000000000000000006e63e49356c38b816736d1d7c360ceaaba875c53c98ec68cb825962531855dc6410a125b914b0ad99f6f4327f5450890000000000000000000000000000000018ffb4ac95b8ffde112c8bdbf07a1c97b1d30a42dd4a97c82617698617ceb169e8702437ff6082a2ae387b462cd86256000000000000000000000000000000000497c4b3788c4d6c9b4cd8b3d3569ac4b4332b2f76c5f03f112e089bb79d33152b2469f7ad3eadb8b954775aab73f47de816dd1bfe025685f2eff0856f9c162d73a58fdeae0dfbeb5ce076e9f9ec1a700000000000000000000000000000000003e16f2f5a2fe15fa02b6217aed7dc688dd2670c09c02791cafeccfceb7d99ce826bccf213f6a7c6064687519f9283de00000000000000000000000000000000095e6638ac74815dc451b3ec85a6a8cc18643b541e8be99052ff6dad39c971f2e8bee976ab2ed5e1cdacf92816249ded000000000000000000000000000000000f2703c08b1d707fb6de215de80b53ffbf2ac48f3dd059d2a952b1031189248fad27beec5c8591ac93625a08e3420f0200000000000000000000000000000000024ae36412ba6f2fdeb0777b892f1ed7bab0527879d93f7b71b62f437f5c1ad1f04a5a7380ae5990a455f11870c7208304f117d41a011d36f55d0cb53d4f98de3b1a6cb55dc8a76b29d393bc21826ea0000000000000000000000000000000000f7ab1908c6d4b152835f950b604b55fdda7eb55c6b90c05e98626ba7cd014683bd3e219fd0d5983e9dcfaaa5d389e560000000000000000000000000000000010b285c2884dbdd540d6dfeca704e00839337f12d2267f6a3fc731fa0f724cde19e268782b4b9c2e11ec3aef9a72a6ed0000000000000000000000000000000014a40cc55570e8f45369bd9dc622e05f03989bce6a98a0d87f4fa7add67eee3e2ad9a297615dde05e64203e86153ec230000000000000000000000000000000007f2b6a092adc595e4857e821579801301396321d4a20bccb3296a031d74a62bd79ea4ea094d2e545943138d2fc930fb6b6f5ee0549b28a1bb317cb020ae0e031dbc381075772ff582718fa49db486d200000000000000000000000000000000108834a685455dc0be10aaf54607a06100673140b012ef23a16d3df204a81dd8505d62ca3e0278a2581abc59e0fbc421000000000000000000000000000000000bca7130de9896e8d6858022f24308af7ca66fb4c91f38b30f717c5491996ef4cdb01f4d38a730f9ba9ca5af5ad1de7700000000000000000000000000000000007d60ded107a06114afaf741dc8826f9e14bac6014eba26089c4e31a73b0f30c4b6e22533ac0db7e73621cecf753590000000000000000000000000000000000b538213a703f7a0bbcffb4aa8ce25ba2a538bf599d3c0251f5e8acddfd596c9912d4cf9a1bd8d3ec070713328ca992205edf9812adf95c9844b2da06f75d96e742c0620d1cb0d47dfd9b68d0bb76128000000000000000000000000000000000cdf0b9bc829cd8537918d665e5bf344d309678d01ee80c71a6d6efb45ee8a7beca35bb5ee046e0a3fac76e1771520ff00000000000000000000000000000000014e5be9dca2f8ee4da18e5ec9c4caa891dd78acc47f553af584308c72988435b85ad21b14abf8421bdb9e25164d568f000000000000000000000000000000000accdde22a1c479e47a17b8da6f1d2b7f780ac278c68a68090e5402977d897bd734f5af8164118d613f480c1f65e5d8e00000000000000000000000000000000029614458afdf6b572bea02a0af987d178c43650ca1c80a297b1d31e259aabd3e2a2c8e4b2c044466924dd6e5e3483e6f64a71e4e7652860038df67c99d97b1e5a063370e65217531253419bf2e6365b0000000000000000000000000000000004e45cc43d4d10ed878e18df156062c799a687b8e6beedad9fa6f66ad855cd053af6918e234ff9a43561da7e67f3dee10000000000000000000000000000000009c9ae47a76c199c93c38e7213c8d6c030cfca709714c703839b9ae9b65207e83486f9c8c16373e2b37756f3fd4355fd0000000000000000000000000000000001594ce9c2e229491b22317452938115747515ce62a0d49f4dd12667f5b3e7b541b3775c9b1363cc185a539b9f7596330000000000000000000000000000000016bf68e05e32168c69ad67331d7bc88a6d130fe8aed3e42eddfeb1d92add266eb69487b246a3ca961ea6ac0a35f8da78059bebd962501b8381b67c22055ba01667d916932713d7ca427cd80d8f76b41900000000000000000000000000000000080d165c57354f87008eb97610d4a596f180e48ed3190779591a0f7e07278f8d2fa6cd21d1b10e6347f11bd9731fdfed0000000000000000000000000000000008d5a1e66ec76743ca366be80fd1cbd5efc9112dbcfa84ce6c44e8df03140ca5f07d4bafc6c6ce5f2f190ede55fe8718000000000000000000000000000000000d0e1d2e5ef384a4fb314fdce54ab7895f895b3bc669acffd48e92c6320024d4f371f42071fceea550c8cf68615b00960000000000000000000000000000000010beae4ffbb68cf6e5d0683dc0629411ee14563f84788d50b1c8755b0b06092cc0f0ef7b55a39d51945b5178e374f8e047b3448b9b404e184f7ff20466aef3dbd4e08375673ca31fdb303c88243fface00000000000000000000000000000000161486d422462460923bd98834f0cc270982087697747fe40eb9153a7923d48eda191e4e7a75964f18f1df9365901a360000000000000000000000000000000017ab168a4ec81c8db4a74d529670fe6332b3870004f696f3a143cd1a62abd747d94afac9485e5dc19b0f4262dd379c990000000000000000000000000000000001e9cc85f03039ea53253f0fa2420012171fe39ed8696ddfbed57b80b73476171e59631388d75fe43aafde52aa14a64100000000000000000000000000000000109a5d5449002f4bdca44c0bd141175d5ca1cee449302f0314fcb5f282f022a7a3cef77f4e9fb515107e797726ff51d767d9d30b38b252a0661c12dc69127ac380f3f756144801633e99bc2ffa2f463c", "Expected": "000000000000000000000000000000000aaa5de171664fcb45439b17a024806ff7e07d02294e0592ca74752a5b66f3365d1b49d6893b3bac3b8b0d10d026e48d000000000000000000000000000000000418354ce1820ecf848321a07ce22117303e5a15169a9cbfd141fb4797de8871d84d577e86270a9cbfe31c088ceed0250000000000000000000000000000000016884caa03ea641e0660a790975d77c5bb03568f873800d0559b69e3e0afcc10ddf031bb5c25c46f136f0791bbd3cc8f0000000000000000000000000000000002bdf659df76cbaaec030448e8f4bbd6b424037a8dfd7c4b8ccaa2224b0852c168f49c6f45c04f23abc85b8df21953ce", "Name": "matter_g2_multiexp_89", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000062bad6816308f1c8c6941980caf71929a4006083dd29827902ffc92ebd9b14f1ef662f3a0125b1e74dabd039f9106400000000000000000000000000000000118e4ae76e2c321a5b89eb19b58f58f44e80dcbc7bd6d619579da40e1156aab32fe81df8eeb1bd047f96d65aed8b3b6a000000000000000000000000000000000c8c93e1beeb4efe52a96e5d5612338721e3e487c13c18b02475f9ccd8fafc2c95101aed291951f2031bee5216dba26f0000000000000000000000000000000016fba44e9aa39a12ae27e3c36de1f14e3f37ffb0ceaf5fed2a0d9815eab02c5aae91b254812a8f3a2e3654cec01a341caaea75e63204e177d404898aa51555767f813c3f3ed283405ed1ee829b04c85c0000000000000000000000000000000013716488daf8586719c52fcec80d35f17d4c595b66c7f2138244f3c8cea69b819778bfb50e49ca1d092e57c51674fca00000000000000000000000000000000019cee25c4731bf48602ceab23b5fc4f764993443e3622107b4c33b29c23d1b5916380431b7ecd94a0ce99811fe6dadba000000000000000000000000000000000562b28b245b7c1ee531a320fa0f4e12d7c171c7e3932ffda6cfebb123fa7f5993e5ed5e7b7d295405e5031b339994bf00000000000000000000000000000000180c4a8158a26d34123c870bc694382352a8e4de712b650d3e45e6baa16d6950ec15d3a4e032c1d1ae8fea18faa6f3d8db48a90ddcd791e6a9debfabcb1c71c88e7ad98f9e739ee752b381b28d7656f20000000000000000000000000000000008472d40e0505d6b8b92500e8e9711112048611fcdcca2377481ae86a7f6da1571f179183301e2194a42dac3873a3ba5000000000000000000000000000000000e2c5b61c050a8a12298f76b5f15383e72b90b001fa26889b67a24bb374b63c1e00979b05450e44ed63e72042af6d46e000000000000000000000000000000000e8723eace9c7a72b3e6097afc9bcadde61462e2ee03fcd5ad1b1c0dcf39f437f80530c2a1c5e6ecdaac14e8715f02e30000000000000000000000000000000002e21e0f451d035a5257fb09e9ed17b27f0994e6d85ddaf8d33153628adb194c97db17656351c029be4d3125bd29dc22ad1795823d3834496b0a1c2c07431f9d76071db77834005fa1228393ad4ce3f40000000000000000000000000000000000dce49634595869d7858e95a301bcff8112eb73dca8a22042137456d6d4887998a541489ff09f8e006176e6beee4e300000000000000000000000000000000010835f7336dc49e62706da4ef21d8e3173629b16742c317c1b397d4f17ced40a56520ea63557d7ac7f251568f4eb3a220000000000000000000000000000000017446ebe659a4510a362ee3b406b636bea8f381503e51ac21031c7cc92acd23046d62c2f32cda01b680c0f107142ae7d0000000000000000000000000000000006ef82deabd8983ebe4255d8e06f4a1b3585c057b2a1ca3c3e1cf04b582b65792e9980e3a1735a8ad58b053b16ca03d036d56e38fe63e573b02203be04ef9e1a044e1754eb2db50c6f9804abc4a40f46000000000000000000000000000000000cd8e7422ee179a0499178c3848cc4fbc87fc25c8c882f036a03cd9d3f273f7f2bf71bd3c9cf5e30c42b1ee6e90b36fb0000000000000000000000000000000005005a471d77a35e922b6d6a45b13a90947c2b31d8e7a2e4b6388265b039ce23ed958495dbf904186bef60fd547b941c0000000000000000000000000000000006c337380065eb8a5f63cb20fc61a9eec4ccf0e23c4e0f231a5bc4d765271b9c5697bbde692b4828ae22ea12423ad932000000000000000000000000000000000f7a0080cbe72a6e6473f66ed729f58683a80815a1748e52f7b67a6bf2846b7df8e7dd8599f87fe63706e9823bfe00d21a6b36f4674ab19202037d59fd8e14369e5d3d71acc3c76985b813d81ca6e24a000000000000000000000000000000000c94834474ac91547546d7d179b2091e33c8812c1b582ff186e69b63011177283a74b549aa342a7f3882ee82ad8ecc03000000000000000000000000000000000d72c4308e9ae695acedb9413445bf6a40d59ca78bd4f74ddbc1bcd8508cfb521bfcca99c98dad8022d3d1ccdd98bca9000000000000000000000000000000001487d006830d00d84a567c5d031019035443fae4791a05253f91249b32a4b3e7b3ce7eae885b8caeaea411a90b3445e0000000000000000000000000000000000d94f17aa100503f605732a48e4f55c394a8df1421a3d7c78bc85f4cb7a53744eadcf76e1620fc54204b123d6071cd3bad85286877fa7e5a9a61dba9df5ce35083beca7c2f5ecad13d226fa32b9720e900000000000000000000000000000000101cfa8d9c7522277f2bb4bae6c09e8b93a876c749c91c61784feeb105be61c2479375abdaa81deafc2fe754ed6cd9da00000000000000000000000000000000089ebbdd489ff670a70218f5aaca78d4e7ade483c7f20de4a84d39217be8f560fbf7bbe36f3f8b8361ba16d17ce609d200000000000000000000000000000000094f094372b2315fabc219099200e7b9e2f3a2f6fef2ede6f83c82f44792da03aaad06b8cd06dc3f140746bee2a45706000000000000000000000000000000000cde6cf9a3a7018b2b1c0c26b5850820080c7e4b56e615d577a78565431c93de78348d2851d5ad9f120ddaa9ff3da31b8fa5387c5712832b52c9c72e10c6f69e9c1c5b278aa379140e75e404c4f50a2c00000000000000000000000000000000059bb8e5dc5f0cd31cf674ea78b80b67b8a8a753e51284a2ab37d3f29459250d904e70ed00481b73556970a7f5424e5900000000000000000000000000000000043c6a53c413bfa2f4bb14ef296afd97ce801a37fe63d11a842f8d66160794c1a651d70f4c836af2c73cb1bc58c706460000000000000000000000000000000003e7b67da1513656f7b08fc5a77682477349ac57e53687c82b6d98772b5f929a2b06b0c7e14481d522aa94fa3a6e1cde00000000000000000000000000000000109e07928216eaea36fbb20a38711e73fdc26e18a6967b54f308b10116a5c8af0c8411406ef6ab1050b61c23bb746b0a3023298162ebe7f4ae6aee45a8a6ba602c3942a8bd6b35636fc6b85596a582e000000000000000000000000000000000166f26d3d26cd48e498578900a8c830ce9b80f162c4b430749651b945d9f60ae6a26306ad7711a1f9d3428946074912d00000000000000000000000000000000165f1bc59c9c36d12754097ea83e9a63fb4ae5d1b93a1b9239a6f338cddf4a9b30415d58076852288c6a467ce9b6b9eb00000000000000000000000000000000198e73619cb93fa6a2bc700cd400519d11a7d3d6d945ffac9754a6faf37da8596b49b7a3a4f2cd899ec9c84f1e79b7ed000000000000000000000000000000000a4740820d60034d37bb85e3e622783852779d36d6e61f81a7eabcd094993dd7d81900277550bb4299d550d2805466aa8ff2430d2f82c6d5e7424836ecea15af0ba2d0bd6498e65c65b6cd281a7b8f28000000000000000000000000000000001714857b0ee07b94ea928ff57aae9fe003c0c85d8564456955d14fc8d4ae14a7c9bc303983af3e2999c6db2d000ea51d0000000000000000000000000000000016512cb60aa372cf5098ad514291d8168ed31bd755861dbd9ef020252c01379d343a9c058839cdec8d14f2fb9da0db80000000000000000000000000000000000af74d8ac711b6590e7041e80ca40dd4db659e42b950bdd68c56d676de654c1a47867bfe6483dfe1971eb7c1d1a70bd10000000000000000000000000000000019e56ca1ef3fffa9e131fc5bc93100577b062cf9b2acd234c79e5e54aa799a389f30002b4bd683edec5fb100f1800d66415eea22058493dbf6ac248fd2ad8b4734ebe33761f2177089a3feda396001c00000000000000000000000000000000019d1d1e1e2dd4ab86df81a8246c902a573d1fd1598050663342e411a1d1b3c8849473c689afcc8e0ce5e51a9dc9c3b6200000000000000000000000000000000190d7c923bdd6336fe3e0509563b2eb6067354d8807f66e6052e97d5997464b9f07f29f3022f78779a5c4ac155a703ce00000000000000000000000000000000128591bb699c18a7b9e6e4e894654853f6a68233dfe8c744b42e057711b8d0efb3a98bab6aaa40ae7675d9200a8427d600000000000000000000000000000000045e0560e0936b16d1e055d3d3f4e0fb42d129546abddebeb78e871d1442f4796d939929d354b0326b95e50fd5208fa9ff79e3ef5d32a751b713180be37d44ae55c59c5a8121c132c5098ff972d8a97400000000000000000000000000000000092373dfd7d4375d6bcffa415e5b36a31499e881a80be32400105a6d56b34d64f4fed09f12640a43289a710f034b71e6000000000000000000000000000000000fa75d6510b3b58a32635a7a6cb4b9255aa7af46905cafc893f29b7866e12565765bcde498dbe87df3d1dd53ab5628320000000000000000000000000000000010dfd3456cb6a8bc853b390380a13f045ab43abd289fd05e7f98839477dea1fb1fbe38ca4f5bdd6691446ac0219e453000000000000000000000000000000000112567397f3fda84db6042817a99aeccd0c46a11fd3ba44e2600deafaaab7014dba98cdcadf81b97272fb7f275ee8a4e039bc7274a3ab172285d853d368da0950203a48ef61b3c7564644762279c1ff30000000000000000000000000000000007b397f093e69874d2bd3592489d93c80d0191b157e71d08a6ebe73063f77e7c5e084a24b34da2aa6354b1815a694185000000000000000000000000000000000fcede3a39dd5f905d072dafdb6f56d85726f6f362f91f079fcd47a8c1d3bdcf199d64edf17e3db1dfc96a3e59f69bfe0000000000000000000000000000000010cfa13c84e750d8af8bbb88bd6d16adf3bc7b532447c2e6accb359a5576be08c1b25f336047fb8e01a4d7f9080d0392000000000000000000000000000000000ca0e88b5c2035bcd3a65e8bf1aa219cf428b6f80617040ae02a0ed41559804844df373ac61a85899bec83e5a6243ed42c47d0b1fd24c1c66a3cb0deb7d51ea19f0fc492f637ed5d4d03e102cbdd055500000000000000000000000000000000021f3b793680e0e3127fa53034e9fcf286f5279cd167ac1e8ba051c440aa265ec6d28fcc2f6d3bad126180efd4503fe900000000000000000000000000000000182b429f27996ee070ed27e7015bd70191b814bd02ca6558a9be81d6898161aa525197c1672ae75da92729f2fae9fa3c000000000000000000000000000000000a20b3922e07da4ef6696de85754eabf1f58f7f5d37accb6cde4f62066e789bc64bc8ad6ac827b8c955acc858b03d053000000000000000000000000000000000814faebd3b60fa1a8fb86b3cb57d36b9c85d4b28e97a2251e6bc1fed1ccb18f17664321f38f3723cf8b09a2161c6aeaab4aca860ae4bc20d33808533c9a70108b153bc4b2256003ad4bbc11dc92898500000000000000000000000000000000159f9d329f929a65e41c7a0d4c05e11db61ca7d6d82f8b92a780bac66568694656f4c845a730861fde9a313fa49bdf0e000000000000000000000000000000000d556bdc8dc959b00f74209dff27023c5521d387a40bf20ae2a98f3f55318eddd347bf1e9d856f43a4b5fcd26c3567ad0000000000000000000000000000000009b4b0cedf477ef1e0f99627bdd7a7afeb9e29afbac553a516fab479913b23a9be5e0b38994215a9e23849bb664201ee0000000000000000000000000000000010899f4dc55ac5d1f56a7b8d55ce7f6a5e0a8647bf1ef6e9050f00c5fcac9f679f138018b9aa611be73d3bdc0af2056e297500a2747f9a68b2d8d9ca5b0390369d919897c53d422cb76c5a283c38669e000000000000000000000000000000000226c8a6b27437972ce29c2ed7e5cca4b6691e3a5dbbe713b5d309ff2f4cbb95e8f1571314444d65ff5fbc3281f9354f000000000000000000000000000000000282a49d0c560d873676967700c1062013a2d4beee96a09af7e14436fda4e3d2a32ab8ee4e591decec39a811ddff130400000000000000000000000000000000167bfe499f1f4609e67134e12ad91aadc37bdabd0055ecf7f96162c39a02a86e62a7b3d39f514f63edd82d04beb1958a00000000000000000000000000000000191673ea5470e4704e361f5ead1c56371d6aee3035d92d9e1b96fd119c4f877cde6451411e441fb45aa9fcb90fe4c66ba87ca4cf226c212c80f3db5e4e781ad7391fb73b1124d01cf893169d1c50ca99", "Expected": "000000000000000000000000000000001488532d83fddf0bfd69b32f965790b3fe4cd9f64e8d17e78189c346518c91e69db2f0b742cdd5804b3db3777dd931230000000000000000000000000000000016205c470c6371d73b012a14d519bf214ff10de458605097da1b798977bd938727c5be19a10f4f492f301d2ab6c38ed000000000000000000000000000000000142cc08f61d3c9bd4c7bfd0b7a0b8693af6120898fcaff49a7fb5abdaf1d15bf70eb033d6ff09a75995547e6856c595f00000000000000000000000000000000164b2807e19135ca3b66bac9aceb371165c930ae063f3cb5a06efb8985a1e0c39023d8f01df517713796083e8c2cceb7", "Name": "matter_g2_multiexp_90", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000023bec14deefcc20a90e439bc16912e90191dc7142234b1870e4e8d70c56f695d5cd30a68930ff9b007bdcae8ca90d870000000000000000000000000000000000053a6e226f3bd82150e08ec3690f36616d5ab745b36a9990baac7ad3429a41bc60c7f7000ceda4cc9298b10043639e000000000000000000000000000000000b81b331589ac332093928faa60d6819d3b5559d32d37d2cc13c78aafa1cc34e32d317695c1c4b4979baa1865ced90150000000000000000000000000000000010dbac5e52f9a046ab88aa36b3c5f6952720e174bf8f1732e886e66e5803aab63642185aa24ea08c991edaf8375bcadd9abfe7e05e8a210604355a77f64386a01323407d9f25397769cc6dd141bc6643000000000000000000000000000000001875ef3f90df03d49ce6cede2c791b4d8503b75acff2dcb1c7c88026394dfe11481da72de4ff58ee9a98e75577b6398c000000000000000000000000000000000c8ee603d1404e64ea3ff08c70b3dbffd318736ae95f9a96ca07ddaa449818e6c5a17b2970f572f53c90be893e5c323b000000000000000000000000000000000f31af63c68481f527092b261d29d5c2daa95873b68899c28ac7753d95a64f455ebabedfe6e72246e494cc5fa2a9bd040000000000000000000000000000000009fd06bc51d4dc51de9fad6d1eb763809cdb5ccdba8e0427859d878904bdf295983b318f311856728078e7cbbecb0c5b64be08e7c2fd15ac0116ca941b85615c6deb38fe85e2c0fd22997e394b8a67690000000000000000000000000000000003ce75ecf6b605ce73f4e215b1aad4799f91e624daf0deae3a273968490bdbdbd0250686ee91a1c24c2e2f2b6024fa49000000000000000000000000000000000e4d9b65d71b7593310fb5145677d170663c0ca29636f7b7c50ec1988bd2d2f1c41d542d4cd8fa23fad94bd6a84aef5b000000000000000000000000000000000fa4accea53a6362651f6c6ad2a68d20b5f549f8eb961718e0c14cd05249a121e442a6a588eafc83d6a43d8baa66882400000000000000000000000000000000121e325406767852620ddc45677495fe3e0851fd3c70922896a3e92033347d2fe8d07f4db8f26b8127ec39d619d596030c391dff1c0c303c77b2a1fff24f50250dc793338f7d7f8f1d54bf7d87ab37da0000000000000000000000000000000003a0ac3ac37932b71672b9c48bdbd368d64c11f57ccb952f633bcd10ec19134c65fb2cbad655d773a90cbec2d9232b3b0000000000000000000000000000000007553c470bd8f38a48490dadea29df81ad901ecaaf1eab35b1f497bb58acce77b883e03e78702930dda72e2277139a2b00000000000000000000000000000000044973913824b3326b72e62ccbabd8c9f1b5dc81b423d0dca37b6f33972d993a681c326730717036bc6f0286da9177430000000000000000000000000000000017b0407d2864cfb39dbb0a5fa8deb4ed4a690a4042153e829f51c56bd0f2953a440d8305a318e6d6f67970d473753021a2d728e013e5fc3e1ca24c105a0c268cbb4f152a97e318f3aae33186ea6bc93a000000000000000000000000000000000b7478dda7053590ed013b7c23431a21626e748c3843e2332bde0bd3890ecea95b6104bac420a8be5f3dd9b075203616000000000000000000000000000000000e6dea641181cf796f62b196652f952ee2a26ba998cce1cfe9d65ae49198d10badffa561e2bd818eb2a7f350c122fa820000000000000000000000000000000003c79917ad5a9c7f046b34e5491ed015695aecb00760f3009dde4cfbf88ad1c03e44117fcb6cdbd5ecaa8df8760a3da100000000000000000000000000000000034e22ddbdeb9dea46c71ca2144ffcc8356c1a525c5ada69a6d5e5c1786aaaf0cf532e31a2f78371e04a72e8222ed4c7e8da0c8da19dc441f53c54551579fec5d820ce2e3599824b24b7c5bf1847c5890000000000000000000000000000000017964112272360a38d3bddf89da922ab50be076bf71a094fc8afde109d3817cc2db633e6408f5716b76d70e30ae00c0d0000000000000000000000000000000009bed28bbf43846ab97b92aab9ce094b077bbc59db648dbb469f21842058ef20318a1a8c18045b3de555bd8c76132ff0000000000000000000000000000000001297110789c7aecb0fec577f6f4a4de14608d9aa26a8de68289adea7f6b53b766b840d315152ea346f8c10b2d2729e730000000000000000000000000000000002b551c6a7846b96c6895e55ec435397af70eb435dc1c562ac71a44c36936c2c6d3e6a1e3545513516513391aedaf9ca76e90965adfc2fe52e4341895e6b6154fd7a097e052b59e4935c8267a6f0e63800000000000000000000000000000000003d463ee4d177d78849fdecba52b7e83ca90d54177ed39e82b4e80c17994a6a2bfd9c46edc0ddb256f8955428f30eca0000000000000000000000000000000011dd976dfeb8ecb7d7f5cd10c235131709fb16d8a827e83d7084266c2504cd1f5276ae3333bc7fbb4ebab48c0d97a9930000000000000000000000000000000005fd19477fffc246f5991603b48085d95256b273631bcfc16f19c6980a3ba01ac098061faa149b475bfce37d586464b800000000000000000000000000000000103ac3dd682aee109dd7fbf60b50c28cf7e37642f05b424773a06f6cfaf7e9fb01d5074ade97ef6cb0ace2e1fe07d54c7f3f352c7b7a9e2eb6c87edfc99e2df3148966760168f6abb13ee482f223a01d0000000000000000000000000000000003208ce7f51a96dee053cbaa66fbdb921c2c3b42ead78b39b4f1df7ab49f05cb88d0f4ac18de5839749416eba5535d4b0000000000000000000000000000000001ff7f9db52aaa0fddc8e96a67b99353b92d7032f59d200bf69da3b446d08435d2ddaeb93584d3b68a1934566187922b0000000000000000000000000000000005f05ccfa5704652cecfb42979c538823fb9d11a00222a963d00f1a4b9a040a0222dcf45baad40c6574d85e5617dbbea0000000000000000000000000000000018637b8c3ef111f6ad4538464c250d780e7f081802bdf720f4c925154f4667c5d50cdbc4dbb7d0b2747b97d2ba2280bfd35c4286f19a9fe8117e37132ce4ce76e28afee25ecca2f66de3cd5e1c83235f000000000000000000000000000000000eb400becfa5521b824a4288885fe46642c31576238e94f95e9b4bcbf62845ee9d9ee122f87d36fbe668f0e605fa2ce00000000000000000000000000000000003c8cbdeea0d09590e1719ddffa0a116723f0fe85585583f3f271ead66fbc2107873181915cc41eed3ec6e2c5669e9d3000000000000000000000000000000000e61c0768561517405952c6462f1c5df95be272251d8a7060624b62f9be310cef64436eb2c4c04e8352d7b75fea1756200000000000000000000000000000000036cd74a8efa8a1fce7587f07d5c2a6c4b7ef161b0faae037c9bbe63bd0c92b83e514c8c1bae4a5d9866c0889b1b914f3c2b40b7968a39fe8e4f24acc25b6c727887c3c44cc89cf62eb14a78ae47e8680000000000000000000000000000000013019d0fc8b93da2c79e473d713d94af33eaffda65a7a49d0cbae9f5259b8323e6f29b83da9608ba7d6ec004fb0710eb000000000000000000000000000000001505d30bf8f7c51994d896d91e8e2259782e2b49bda834015477f18c29e64da4d31f8b96edd080267b77a9539afca06a000000000000000000000000000000000eba929531615d9c0f59c4b33c1fc34b81e9c77cd8c6887099d850b3e39326d7caee1feeb101222f22bea1e9853d06ea0000000000000000000000000000000019d88f62cae047ddf2cefe497495f890d9ab8499e56f72488af65095e992427bf821f63555a67b0afb00d6fb441080a010325465403dbd4898beb740884cc325923ec3e1d7483540377d8bbd02c11382000000000000000000000000000000000b7c8f3d0c56b3b7d96c0a24fea3394551a186f87acbbbbce41d1313b23762945bae2e911725da4211614b456b508c0500000000000000000000000000000000125316f64bdd0c5bcd26a0e5bcfc3139045b3a44c8a8dd1cebbfaeb83b963c5a5abd4a5961465cff261c0e49189278d800000000000000000000000000000000095a327f488b901fe7dcc9f9ce6f4f25876bb09b053b64e9f4de9506a0fb95fc0cd443473c2cc5436750581d39b8e51f0000000000000000000000000000000015d406b31c791ae2d25ce462304c0bcf341686d7967c9dbb6734bc28b02123b1730d0a673fa8071dd90950d9411a2b3909545b90dbe35b0d5764bc72d45717e0c3aca6aa77c73178fa8a3ee9fec9cdb3000000000000000000000000000000000c7029af9422246d0a30784431d6bf9eca09481589438fe9a6d2fe1d5e526ec3d176a3d550204aadb85353d99bfe3ce50000000000000000000000000000000014a0dcb26c40693ad19a1edccda05055a27ca24544e933d01dfb964571071f94c94233f81e1ead0925d24e6d3df2c21500000000000000000000000000000000147a55ebd83c746128ba9c7ac57be125ca5c95f80f891e2c5893caa779484bdc1f9c3b3ccc4223b2343ba939251f7fdc00000000000000000000000000000000125622a040d8b157432ad81b8a83a9b1f0920b92680bbb65050b4862b89017b3bfaf81a3402ccb383265ba7200ce677feef0f8014102664a300ea9a30fdc7afeae3cc338fd45cd421a1bfea98e304c810000000000000000000000000000000013b394fd7a0f3d94e5fe4cf5cce3627d425ec848912395565b3e61ffe89e56be799c4779d3b9a0222ecc6538ca3346e40000000000000000000000000000000014ac1a87b333caed0f557fa5692d1138a8c1e92d1f9acdc9f357e2a46f27513dea42f367b046d389dc831610be4fbcf40000000000000000000000000000000011fa243a0aa8b0c01c7636387d60021afe6efc223b7deb69d030651c369643188b9dd5e08d6d031d71dd11eca1e825ac0000000000000000000000000000000015bf8fd7fe438407db7f1b0b586b2c285777c5b6dbef9e45b46cc0a50dc831f32a70e7d4316d4869bc769ff6de58ac30c8f1e08cdd72ed200253211e3b9947cb2a5fa24079b6920b4a4d3f1fd78146e80000000000000000000000000000000005ea57c269c9d43d3f17a83df04c95ea7e7bd85aad1dc2dd285ccdbd52bfe707a1d2476417e848ab119e62fea30520af000000000000000000000000000000000b99768ffbe95e315b244bf996cf34f8ac356664adda5aa7f4ff8d513b2eb5934b8ffe0fd9af94bc9b934e0a8bbd51ba0000000000000000000000000000000003b02c259df189370dd2700c5cccfc8b212a4b332a083adf9771503f5bd0c9ef040590320fe4a86c555a4ea87531268100000000000000000000000000000000003ebb1e610bd055d037a410cce3ae06aa654950aee0210ed0ee79f7a332be7342e308347d7b17a146a8b4c623029e08a7e25b1a60b6c6080ccf1bfdc37aabbc2bf92079d9356844f7f12867b3e2b2800000000000000000000000000000000015c4da691b5e6242af870e06b29bcde467b4644f01080eca60a28c7f941590192be30e6a4270a36dc8959b80235600aa00000000000000000000000000000000080f3d3d5c35ee24179f51ad854a37ac4ff867a2736a0e3e8f3312ac98c7016beea6ffe2bad1dd4842d6ec77995ff97600000000000000000000000000000000130c29dc633aaefc831b0bccb13fde1212fdce8cdd17beaaf1d06e74ef5b1b69bcc219c8d63f054690af1b6dc7c0d647000000000000000000000000000000000767290aaa1ed4c1dfa5603d976df0715b417599445ca577ded7d99e685118bbec71443fe1d9a65e0f23436353df152cdcb456eaad2b7c71ca32277206c1a1dbfa7e0e84950cbf14aadd455fb58e398a00000000000000000000000000000000133e997857f47f8d6278b8ad86f4692ba0dec9da336f2726704db593af368dda7aefc0b218ce1674f415e0d9e2dee5c60000000000000000000000000000000018db87da1272bd386f7d8b5245dc2de30e82739723b680dedd36f4ac4cf5042bcbada1e1bb307ba444431d73a4248f9c0000000000000000000000000000000006580be3e67c7a615408aaf9c95c0956678af0e2b1f536f1e69588193387f8a05b03d5e1060ca60c4fec9eaf3e72d39900000000000000000000000000000000050bd9879ef9eea147678f552cedacaee84562e6561b3b7338fa8f9d514099291c3f2a3723fdb22c88f1c9243d411ccba6e7b19245341fdfc5927cdae57f59de5f3fc8c37f8653e5aaca87db682034ce", "Expected": "000000000000000000000000000000000d8f69d90c871c08ae09e7b3e62e36514fd056c41fb596fec2fc9ce8509ab4f6675d7e85aa6b4b3197f5ab781f6f2e490000000000000000000000000000000011c4bd3cd156c34065e408efcaa5e13ad23d114458b71c2a6345f4aaf82af76cd4362db7ba9ee7e1e92ce72e242f570a000000000000000000000000000000000712dbbf20e9b24d20511d01717a3783608386408a258c2261fcdad5fbcab36c6bd21473c3d93ef8518975256c65a945000000000000000000000000000000000d13747be82153aea8076fd7813ecd7f60a214c31e88e25b14dee5cdb9336599e40b136d9ae6deb85606d35406b2675d", "Name": "matter_g2_multiexp_91", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017da08f2faa32570d95b9efd2d2fe358faec1ffe304750dca1dc3a273be3427c70904d58864f76afa19b0fe33ab1535f0000000000000000000000000000000017de677b713202f23baecef2b0618da140af624e56b876f2d7a20cd437c3868ea00ff6cd9c8908c1ef323ad294edd9670000000000000000000000000000000011d50aad957c54868aed6d848b2e67094b129282cc2df56c41d6ffe976d02ee83a592c33370d3715588a074db503b3e8000000000000000000000000000000000b8aeb019d120959b21627c1dcfdfb67ade22a948fe433172994d4a34084ac9e1c11333a9c663c87acf50962e21c728e92898d9cbad829a5346c0925c15b585de18869adfe796e46cbd56828540571b70000000000000000000000000000000001312ebeee36fff8152324a3ed24c37eee50b3099619a33c7a6316470ae722548b4b9e0f0640453caf53f374dba504830000000000000000000000000000000005ea81d2e5d9edeb3ed6c200b75beb731c31ad666e6e37db72ffd0265378bffc2724047c7c0c6e3f1598345fd390e9270000000000000000000000000000000017617a836beb12e637c5bbadd4fbf1ca2f5cc3280814ff5cbb5890b31cf2d2faee9e3ea8134af97ad4feace50aa194140000000000000000000000000000000002606deb5d57dce5b3d2e5f7ccec3ad036992beae238673641ad6042479ec3cf83bcc0fd03b7dacb9b4bb6c181ea9cc8c193fe87634fb0bdaa1700466881b557c470a62464e8521be311a95dff65eca6000000000000000000000000000000001203ef36896bfad2a2841689a964328fe4ce3d83798671630d0c8876e67ceda03d99555aac46d984f1d3bc38ffc134c50000000000000000000000000000000013e7461c256c8ff9144b17f8cc2e270aa94b64be62588280baca2ae6b6efc4d32b3800eb84da62561e0e96d5f0387a3f0000000000000000000000000000000009454b6a810647350cf0b364eb1c2b719670af45bdba9d7d1a534e23d4e810c3ef4d9318532e46fd104a83bb10159a30000000000000000000000000000000001034546c4288f642daeccf5b56beed2ca2d946bb4391d056df9c6fd6771048903fa330ec16d59d05540cd715333c4bc73dd9c99a5aea019436e3c91030d03ebefbf6ea6ac69222f1870fadae32f55ae6000000000000000000000000000000000d7782404dc6721f52648fc6969db33a9aa209f8baf5faa9678437c76c9e1635fa6d22d94aedefc90112223bb81ce33f0000000000000000000000000000000001e442e548d3045d1589817d0b57dfcd66fc64ff978186f784bd576faf57607170d49364a72189328c9837c9a2d8b0a0000000000000000000000000000000000da2b207bb7720aeca2e6ea02b65076770b960d4b7a96ed941a7f409757b952031a472384298acc3948bdc485088501c00000000000000000000000000000000048f85bc05ed78c692138f27c3541ced11b6b0ec158b43d133c3450a905416682fbb8c83dea06a06d294c48289ddb829e74ab390c3f73c62eb1435226e9b4f9b921ea1918a61a614b9bdbe9eebd1cd790000000000000000000000000000000017134f787c920bc15cf2228a186dfa1d10194087f28b6dd8f03e1c86226928f0eb1c27020a5cc74d94b50c4b4e36b8020000000000000000000000000000000012fa1fdcbaa81c4cc1e37447cae51beb29e55bb19b91e2b575afa3754589ee0151cd9e83573edaaefd341f381d34f4f8000000000000000000000000000000000ecafd00cc87a773a13909512466ed11288c842716e1ca5c37a4d9a4cd7585136c86f32140fdf02e2997a6e19e3d76a200000000000000000000000000000000104cf007ea863dbd473d7dbab6f55e74062b18986e9bc09bcfdc9c23e4bff8683f73aa998a5cce59ded10499d18a0ecc4dee3e2bfae3820f611c30df232c1d9c6bf58d40b3530858c79f840720d78d72000000000000000000000000000000000ffffc98e55f4ba9a642c40678d625690464bea39d085dbc9c99b4c36ea8bff5154eae3c315e1dec29aa669840accf290000000000000000000000000000000000a3df9595167048c52b8170596d4127968194aef7fbaea4594a27c6af05c54bb772928a7749d74311038d1c115e91b2000000000000000000000000000000000b317a3abd808e94a7197e0d3b2515a147774f78d0cd7d36e1156da28a26e33bfa76d75c6e3ae346f9ace050c9911cc6000000000000000000000000000000000fb5fbcc2f74fc30ae7e32143f219db7dfe5db6ecb09cedad8f087b6df56bf9693c8b7d78aace064e7c31785f6869541795fc8e20dd30622876a94afce1c1a76e3b689d6848903c21103cfce6a8a95680000000000000000000000000000000011e4b907a72f34af899a6c4de211af5fbe0265e5bf24d406798de53ecea273d5df4f4953d13fd7c9dc3bb0f0c143e3e4000000000000000000000000000000001623de5e87b6e1ee920e1b7d979fb9c431c12abb47b93876f9ddfaf28a7b673c18be634f96b813f7e0574c55b628a8790000000000000000000000000000000018ba994b02dad759ee79301b42ea20d7545844c0ea4bff2f95dc9420194cc4196fff12cc09bc0cef03cb7ba868c273700000000000000000000000000000000004b3527c8d148bd9e6006bd298ff8d7fe320748dd3f6d23449e874fc0c2f58d933c1e038a74f60fb6032cce41a3dbf5725b49f325e76733eb3c1a2cee5467157b2ee80987abae43d2c4b93e5157f083800000000000000000000000000000000129641af11fa92056236ef135843b2189d46d870381261d5781a5fd6f2c5cc1861ebb2e801f19f3adf2216609a9e196f0000000000000000000000000000000007b4007c55e47f6bf3aa420ad75fd191ffe0fe824fd30c3f1961a8168922476fdb3869822704999b044feead470e3b8f00000000000000000000000000000000174209113e2d8c363b04f49487176dc6d9eb4ecc0b22daa7ecaa5548d038b3b7c23ebda4f1b6845425cee13493385302000000000000000000000000000000000a58c80a02b7f93db01d2f8e0005839625e6c4f121f3d69115f435526a7f7cb53177caab4db86273bc2d2f0474235f31df49b30dd6aff459f64906eb1a9c9b2067d4f1b75057874b2fee17923bcb906e000000000000000000000000000000001738a03b46a8ca3f3d1f4f4447497c59f114005400f06813b24ff462ebc6f27c1c3c788b5f83f65958cadb34fddd08f40000000000000000000000000000000004dcfff2bc9ca0282016f38df484655cce7b872b1ff047351ae6b903e05f457d7fefae93104f9dfb549980394dfad2760000000000000000000000000000000017cd89434225dba07be137a73892faf0258b3fb19e6c8cec412fcda912c0613f2a925ad50ae485187020a371ff2dbc59000000000000000000000000000000000f1f9f87d3401e7b3b59331a89d9535adc973f869b81bfd8892a37117d8597ebab2800c966e623469792f4ae2a8eb232959e0a33b1fa12e0ba960761b09921b81746b8df23e808a8de09e7f5cbe2bf41000000000000000000000000000000000bdcb1d2a782541ff7884dde4167ba060fbd4b117944ae69aa2ff685b9bd7d475f45adce0c9f92695b4f4ecdd48cb9b50000000000000000000000000000000012a55432678043888bb9e7e47efb17700b3e702e389d0f58dd454224a02da3f190b2fef4c9d3e2074c7bef813fb56fb0000000000000000000000000000000000efa51ba64f1e7a1a269dc083179a222afac916778a967098582f55a41394bff3747f8d024261959f6d399f44a40d0fe000000000000000000000000000000000845dd0974c5789a85c3cb09ea441f2c433f0606928ee1b177eb851530d6e6b620b4fdcaffb8f75623435dff99b3ad9526ca68383528f6a871c237ae5214b49c18c4f3e2f3ef5dfba39e69eb181143d700000000000000000000000000000000180beba92bdb95c7803fca0407e29929ee64e03d61cad96ea0e6c469c5a888cc5ca5eb20983b3418a8da6596a5f1b2ba000000000000000000000000000000001322f7356eb3069fe20063f4be22c44426162dc8fc117e4e382bc4e33bdf3d971ef662fffc1d58ce187c33a43a4c853e000000000000000000000000000000001601a0aadaba846f11ba5c9f48e13bda1007ffdc1b8bbc9e85e83e569e9ee17a1e9e780a50ce617e6c780b8155675f2100000000000000000000000000000000105b2c213aa43ead42d9cfdf1d6c0559c25b4b86af43d4493bd75b76986d0d4f1d9b3bf9e3922b5c08a37a1629cab7d8f1f95a9d1d4e8e7d0f17a954177253709d988c3a77c77d35b8bf70294bb358c20000000000000000000000000000000017bc70346765b7160a0a5e556805c7944304acbecde06cadba474c51f05f22445c3d943674cc8215f973cdf11b9ea2e9000000000000000000000000000000000bfdbe202619a1d95359941c249b25462d3ecf09fabb878943a8a37cb9eb94abd7e6399f8d82f90ffcf904f4466cc5b1000000000000000000000000000000000f048db8530a288fef10a5ef9bb3cdd9f3d3b0ef4824609efad96bdf52d7c3b10ef628fa04f8b6513485e55f653f4b990000000000000000000000000000000004ec35f59287eadb1738bb50b0e2ad9d280bedfdb0a201e72594bfc4322ade0b7ffd6b532ebc7796cfc71f88a194bef4b481f986998d863c98e55a7661136a8f19d7d4c57f6036cd642ae16c82cdcfb30000000000000000000000000000000014424c77af7ace8ebf66f556cf219919712d96d24438466ad620221ce1ae9b2cd75b9c526e25df7fbf3c9250583757f500000000000000000000000000000000198aa00723781714152b3494b76ea3ee043b363b3fa81806cdf7e440b4cea907f226a3c038fb95c932710dc9aad4c9dd000000000000000000000000000000001360e4c775f6fa5e987231dce25ec67f61429ca9fd8160c3074383c30a8c0d7ff068b1d1215b2c0cc87129d9c9aecbc9000000000000000000000000000000001280ee6160800c4b0f82d5c2775238b4b223d8a0ac9a8f8013f138d554ba31c9fedb30e0eb5c330da17f5785b2717422ad872848d72367467094675a819f9aa6107183aa0c8685d5d84c27b3aaab33c1000000000000000000000000000000000f1f84251204d9f9328f79a45d15b311984df0715579633a82b5a9f680f6645cbe748b0fa64b9ce1e696e20a5645d6d300000000000000000000000000000000156901506e502a09917f76d825614824dfbc34d019ed53c2ec5395b51512da512b27541bc53331444eac2f618ffd5357000000000000000000000000000000000ea8736a97a33112bea9d07b729e973e3a942422f1d2b24c30e96637b535ccfc10cb5930bb59ed90bef604453df8772100000000000000000000000000000000187378477f60e3eaa225e89d8532bd95babd4a5c51729cca800d364b61575704992639dc5035138664e8e074ed0820033c2c60541fe17fa8e71d58184a055fa8b1dd0bfd16ac2baa912b4472c6056122000000000000000000000000000000000e5281c1c9210269a7f5ccd02cd5a7d3648b56d9ca6a4ee50beadf151c2601e0291fe7f1b89b694500e6c636d4e445c4000000000000000000000000000000000d5d5399f49697e46013558dfff544383b25f3b60681ba5fa2c5e6edfd3924267d0992abe65cbd5109ba8a1c6eadc7e30000000000000000000000000000000012a2104aa92871dd8e41ae1ae6dc18ceb7d0f361a5a4fc67936454b8866b8aec1602dd596459cccf6d9e1319ec3299d4000000000000000000000000000000000268795f6f9892f5b476c3a534673538647300203a51a8ff60b530094608b5fdf16297f02ab7ba41d6fe556885f064a4ff07c19ad4f10ab47e73b6698f9febf3f28087614759e082e6e717588c1caff7000000000000000000000000000000000a5585961328c52e0fefff16e66e3367e34339dac1a20cbc5e89b78804b8bc265e6e3fec1da6a62cd8a46be2f08a6d960000000000000000000000000000000016fbbd698784beec5a636332c0b20fdcb68fd3015cc6d18b541346a5e6af76613e6fcb14c888a2b8133c0f4132fc079300000000000000000000000000000000041805e0adf2a32153b89d1131226cf0ebd77cde3116a168e792ae8b88ba2edcb1fe7275658a384251b805d282ee039c00000000000000000000000000000000024213e4a8504cbae4875617b9b78473e7842ff72415ceacfaaf2e8b415f9f7e411989bada8101be72f9295dfbddfa3f240c881fdbfc414d3e85ead1cdf166ed6929d0b2ccbc35f0811473757b6b41af", "Expected": "0000000000000000000000000000000003c4f051d528166f256d9356aa9cb885db5680c51990d9474a948848888fb82a9b86daa7a2273725ac8ec564ebbf15db00000000000000000000000000000000010a6c4c7067f511ca8f1b66bf9ffcbb275c7575540909262f7c4332c3d75b2f6d2f3ad2848c0d455410afb1cd60c835000000000000000000000000000000000ee5e582554b3930c5670d4e3542bf32e8b871849d7859eafc077bb2b533e936d462f614057f9fc09c4010afab501c1f0000000000000000000000000000000017fdbcaa065d301adb94a60dd20dbae71512d369fc82c556ea0dff66843be768be942e060752591c6eb0718985d8e313", "Name": "matter_g2_multiexp_92", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001353960aff58d45691c5378a0676a8e837260f5819cbbac9cd75c8cc4c6f1e17b9dc9843eabc0b1dfb27ff7631e4e52d000000000000000000000000000000000d6279a43d3526c035e88b0b640b04d42ea573ed07323aaac1d9d5570a8be64782682892415ba2be5cbb13f56e3a44db000000000000000000000000000000001250fd14fd003f88eb6e0e80e9f2ebe204475fc6c06cd10fa45608a17b7039afe0326474ff80c357f86c2825cdf7a16d00000000000000000000000000000000186cd91cfc8ae625e302946f2b393ea67e1107c0bfe938f5f36d28879fa0c0780c847aac77d0310d43211152c1d5f5d314d5455ff1717bdd545f4daa37e145121e7bd9636d7a2b65633e5ca5a63f2d98000000000000000000000000000000000e55a98e8b1e59600e86cabb5e8db8ee622009b1618ff0df3e93fb55b80985bf2a8ed060aeaba53773274d4186934f75000000000000000000000000000000000bb7215fc43f465f51fc8265477fc8c79493966f040e02f0eacc4ebcb3414b84fd94ded822bd24dd5ad5720f12bb8313000000000000000000000000000000000b23328e15cda8a576ea352b5dd7ce382ec781deca6c23f646e42f0cf63e28669539579ea51e3c0afebbb58e1e8e3243000000000000000000000000000000001716019236169bdb4af7bf7d7ce0aeee7900b74023acbb16f6965c2abcf28917bf88d0f9d5bc26a81710496f7821fd4682cd8da62bd901355a60b37ca14ce65d427bcf9551203cae7c346a49b4fa8626000000000000000000000000000000001718a4d6f5e78524d8df23d2c589abf04e3567d2176539a30b9f73c6251de573caa60c2881f3da99c48d48e9aacd7402000000000000000000000000000000000ce0e35721379077e6eb3b572f7f7718bbf775b116521c14acbd3ff19549c75d50bf70ce84326cbc3f9e5e53605d8ecd0000000000000000000000000000000007cb3305ef0d2cd7de4dceaf25d2eff44d4f437e065f6b244bf1b0611c891626eafc4b759d55b45d76e94b85852df1de0000000000000000000000000000000011cb56d2ed32a46bd951836f8e0f92d3824a4cddf011eecf1e2d92d81bff407a04abdfcffd60ccecda6e9443b328d51eea2c7fc2050e9c1ebd05d15f197b4b1be61c6820c8d27ade57d85109d7f982490000000000000000000000000000000011ba705da23100f853882dd166d81ee1d7621550d156b14f7c2123e2681887ec3724626061db68b2c63987325b27d6230000000000000000000000000000000014271414fe078a80587269398afd127ce34c8dc2a4851f76613b81dc99d766d75c703949c1093b04d66a301a79d89bc30000000000000000000000000000000011b7935ff284b0f812b5da5b28ed338dc4c21ebbc7fee04db834732b11fd76092db0e8d80368255b0f1205129081e9af00000000000000000000000000000000104ff0ad2e3db08d3b4890b2e54f29e456e627cefc3a4f07c1109b764dae4142480e3e5312ada43fec9ba96ce587e8a4e3bf7e661d54796c71437354d7d3182770f10ab450827512a423d3dc82d5b43d000000000000000000000000000000000c60749ef36d63960022f3127d0ab4e12acf05ba1e1a136dec89be388b9d7144c1d78c04df658727763dbaa9725bd8b90000000000000000000000000000000019932b1c205a765bc9de0cc136999deb153222a9dd9e9ec3660fb6daef56242d08791d440888e69ca0da2bbe0fcb7d79000000000000000000000000000000001764790d12f5ff79ee4f2c9fadd5dfb1cf47db70b9e86018bbdbffd1be18df193c7dfa71533afa381053a77e02719c6400000000000000000000000000000000044b2b0211cbb407281ab2abc4725c2cd791b313bab8779954a2461ce445cdae60d4a9efad9f90f80e66b1438514e0f0d3a364e7b217dfd649d1e08f76393372d8768bb0fc85c79ef4652417ef1637fc00000000000000000000000000000000175cf9e7eead650e7ae4fd657bc288b6b6392773bf1bbea48e17172a5019637fbb2bc0a3d0d1e3b8054564935c908db200000000000000000000000000000000136da2a625cf72403d0861b9cd947cdad12b1f1e6cdefc4aab6756536425285a7953a1b892df40ec12ac3430fec889cd000000000000000000000000000000000c2d10c6d71cff4e1deba1984bfd17166571e64659ac91b64c343cdf587c29d52a2266c00a57c01feddb1df6439d21d1000000000000000000000000000000000384a782fb31278f49c840bb8f0552ac2734ef36bb3d115be7df20333aa747c92db990f7e879399235d122fdba0eed76eef7b05d5c725ed31269ae9c56dc7ae35048af39ab114319680d4af69be7e7c3000000000000000000000000000000000a9a821cc63e7c9857b0f39f7444a1e00a422f7cd5d0575c26bc5c6b98313abfde51e3f6d5f4c817193bdf391344e5ba0000000000000000000000000000000010daa8c7194a75cea757b6ae4eee85006eda459ff2cf155b1b5f19c3ad341972f72e28b781c4878e8919c7e5abe9a1d5000000000000000000000000000000001154d5d5764aa2b8818a9dc5dce30ba2197a86d0bdc7dee3e600462e295cc3a69dfbf8db34acf138e7a1f16b62a45717000000000000000000000000000000000b4243a09b05a958d78ba8ae25fd3fa85d520b95e56f1dff44e556b221a075f8dd3370313886d9dbfc56a75697454d72acecaee3dd4dc11e341b3dd0073842d90f641d4dd467a6596f337a6147bd30a9000000000000000000000000000000001820f953fd22b71ce00bbe9e9b78fcf5fb28bcb925f6b5dbf5711e00470ed7fd2f38d7291d40514ab4258807f29150270000000000000000000000000000000007b737b56a2ba33f76bcf66c0b26fb44d5f79879273f6ab21ecbfe6a5744da289464ca2b46c55edaadfe3210b907f3f7000000000000000000000000000000001735d1b39c5369bbf886c5063a96dd12b85e56fd9d8ff9d84520918e1dfeccb62bbbe1c2ab440ccecd0fe66f6ec55853000000000000000000000000000000000e591b7709bf00bb2a87e9edb95720de19adc41a42378cf9ebb930c6d3f5993a1d7b6320040d5c69908685d978be8f980cba585b847bec40515a257cb839c7e5d677d17b7313c258e83d630e65cfb5d2000000000000000000000000000000001732ac410b2a7d10110bbf7709dc6fdc91ce742f8cb9b2c3ba37ba5f0934f8622c675753a26d04a176e24a630d090d81000000000000000000000000000000001111a52da6aca10cf40127fa8ab7683505305e0d474eed28a5e1735ee6877aa00c1bd598420876f2154b814660f3fe7600000000000000000000000000000000098c6d19c2ff42c2c57a4924693325de1a91135e3474ec699b70439d034469e72e844a5511e23dff3948a66cc2a2165300000000000000000000000000000000175fb79e5e54963cdbb133f38dccea2d1abc3cdf005c17e8f2de6dba9b9dbdeff7719983aa9ddb602f0cf966fdd430e0b8cd305c650d2e1cfa91ef0aca9dd0d785d7570d6fb67e61fb9b6817116a05440000000000000000000000000000000004e88468d35d72dba6b3e4b9ca216b75b5d20c447064a48bee6a6ddf994b1e22fd6ee8abd60c627622daffcda219645a0000000000000000000000000000000015eb2ae16e3310b4c4ff557f0615519c13f29109d9863418fdfbe6309b5bac4463456df8ebb0b6d9022e294cc16265ea000000000000000000000000000000001288ffe0ffdb96708558d914bc412758770d048c4d50523e2b134f8468d11a57da97e42bea303ab7137e2d26c0b3b8f30000000000000000000000000000000003ce563b63c50b09a80b71a1a82995238a9de31aaf189c6d29307924b6f0990854507b7dc1644f689c5abcf931dd5a3c825e5f9d81273f306a065fd064ae24bc2c5ce8dbff6b22128753663a218da8a30000000000000000000000000000000009e39ce653485caf699ae1d1d9cf2b8c5ea85b80ea042279e57f0beb81056159e49f73d67e7b1f9ece9f9ece7dcd2cf50000000000000000000000000000000008d6492cc335660c54e4a34b29b337b5800f1ef992d124524c799c04c852ccd3cfc01bf39515cb8b96151753147e8c49000000000000000000000000000000000ca779d87aaa3a6552f9f1a10b0d2e635be90022326db04e6072f326b919ee55d4124b9268f55751dc0f18172bd327ae00000000000000000000000000000000112eea543d6609d0acfaeb7be98be609f03304f50c3814ee8a010283146e6b5dbf170c7314598cac06efb9ced1ac2930307ff9660ad0c24cbb139486638a2556687f88fb93a290a1d174bf87d780b3fd0000000000000000000000000000000006624dd7f6eb043da41a36a15752f370eeb3cb2e6bd88b337b370fe0660c5ba8fe64f62e112f91d2524e9324f3a049fb000000000000000000000000000000000415b964484c9246385cf95461ab955ed0390e20209ed405d84fa8c8af9fa7ab39ce89049691a63c61b12bbf6aa2a4e80000000000000000000000000000000014411d7b2db7c9ee78ea14c6a315df3d90827b511db2e2423d660176384d8f8afd284879b22f5aeed73afb2eca4be52200000000000000000000000000000000105bfb471340e76f28901edbdbfe2ba246a8824b501ae2d4a73cffd2690181347c1e6530804614e88e2bb13a8edef8f4bfa8ee3b44c70ba2512c00a1aaecede2180b08ac3ac8c550d70407f0c12e027d0000000000000000000000000000000002b17f4b0b0231be229d87f075998435560ce9046a8b0e8f15e3a9f07cd52f3316f6d8c00d6a872362e7066715cf990e0000000000000000000000000000000003110eb232154f8a06834e2ddd33c0207ea552f439a6127b652bc261158209a00654e50341d333cd1b206a915fe0691d0000000000000000000000000000000007940e209c8934c185e4392f12fc0afe3d234dd1ef3f92df18d76be8fc42bdcdd6d1ea8d5bb6f07b3f3caecbeb5ef27f00000000000000000000000000000000012ec903a8442f68c03300ab02ddd08ec935d97bec9050d26a5e276584592df3ab87d596f90768d2c0918099b28963be58aa85b50e5f4ffe375599cbb912f41d35acbb85a324880148f9b9003c4265bd0000000000000000000000000000000010fdc16bff0fea02b325c672fe06297e0669094e2710d0baf3838f3e234c3f776bb3fd41b967c9ebbc72a6bc6eca70850000000000000000000000000000000009d64ce322e39d5b2d0872760a61a831877c450b1cfac6cacec52d4070b0f179dce90afbdefdaa8466f6a6e2e83ee8da000000000000000000000000000000000cddca46f3b24e05b76e61b4584bc716ca7036afdd914731a61347e453a26d07549e9808e553ee056bd47e53c75eac8f000000000000000000000000000000000451cccaebe1a188d3eaadd40090ca594f071c8b6d0e0d82f5b2d43fa784f8437e4226104c4cfdb24ece1ed75375aa616810c6cd59b14ef4f6a4c2702cc53c65b3dc84988372c1195980417c583fd7ff0000000000000000000000000000000005832ad778dca8dfcfbe741dcf311024d76341d5920b6830cb75893a112c9d86719583d1dfa7287281fb73fe21650c3500000000000000000000000000000000044feb86b4816e45ffb98e9a670fcb039fd9d8844a2c7ff9b7752f20e619195fe6ab1148f30afa393936d3605fa4c8da0000000000000000000000000000000018db9365370a8c703364ba6d9c48b3512da46cc603a43c3fb91c0a8ee59777d7cf9ac646c3e4274bd950d7de92ebce840000000000000000000000000000000017bd82310e251701cafbf8c4dc5b9e6c88085b0df287b6dde7887e1f64f2d9487a25b31abe07aec7d99a75baa5983195c5ebc09190ba3df49d8ea55cfd18370b9d443f9d9084cf84f2236ef4723d2d470000000000000000000000000000000002c1df194f01dcb503dcc8a283f059b82d141274c8f37cdb6441aa33f84f16dd288d566752a93ca23d26ef5834c0658c000000000000000000000000000000001700fa4459dd4e609453284f4f7dab479342675a87c1cb42b601908296557f39256f1597ed3b9ec38ad0a40a2c728f0d00000000000000000000000000000000135ed4f475eb99397cf204f971215a0303316a3ed8b62b303b4bf756ff753410b7fe263c4e97fd4c4b399c319ff3ad98000000000000000000000000000000000a487e179bf1b73627af9d7d2b43bc0e43127a8fbfeaea7ce958ddd53ecb27741eda187745e3917f1cbb60adf0286f5413a56b176fc835b7e825c817d432b9ec6d51b0a66483dfbf12166ee979b664cc", "Expected": "000000000000000000000000000000001327c57e16f03fbf652bbacd16cf574113860eb87b8f2f6e498dc5dcc4f2fa63859d922d88ccd6683d503d0962db5336000000000000000000000000000000000cb06948c539cbf686f6936b6a1ebef2e148d98c531da36272e0334afca5c2b16a52da542a0fdbc3bf764eb877f5778a0000000000000000000000000000000003acddfb5bc4fd5579d3f592977365840be4d3cff96434e5ff4f01ea798e4401930a1f5d91f8de3ff98504dce398c2ef000000000000000000000000000000000a5a332805f704613eb085d6639f99667d0d9247cae34eabcfa399eed551f24c5d5cb05d6458530ae270b1be682e71f4", "Name": "matter_g2_multiexp_93", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b1b06a76e5bdcb6c1c2f1952b49e1820a9d8557229fbff8740269a0b819b91cfd0de20db0afd76a2cb0fbc5fac12ec5000000000000000000000000000000000347654df2084082efd32cba2b270f66b0ed30fa8713b27949fc9d270ee8eaa9b9a7896d7a52dfd8faa3e0cd112a24e0000000000000000000000000000000000bf5b7a2c0c8bc223ab334bd1df5d9fd4bc0c635379ed2b32da13f6178e07217bb88a4bc2eae0b975f2e566f657d23aa0000000000000000000000000000000017042f8585a07304995853270b1b03bb08484104f7498a12bc865f2a0e37e662fc4b0331b94ee5690efe74056567000bdedf65658ec3cca48fd48e844337159af090c5d1f5e9d713ac6d0fe1e1f193d2000000000000000000000000000000000fcbc73d0628537eae417f8efc67af0a4c9c375d82406086bdff669911fe1307576333c389f189f49677cbbfe2ee98730000000000000000000000000000000019d552b85b1445660ca49518d202afdc67b0eb5be02c8d3482dc1b12e5d40a4ff95a49ce47809e4d6644d04aeb67b3c2000000000000000000000000000000000ed536c0f19f592180291bbce59a72ce5e516199dcbd4fbba736cae2edbe3cfb860ead0325dcc8f8d9be1ac126dc6cda000000000000000000000000000000000f5d4f0c0ae3e76b1c41edbbebcf1ff17c7cefd41e7ef8f75dfc10170834d05820149d5f721a8c6460cd0181571fca97db65ad6bcd6f485eefebda0badfc64e9e7dfe7e911f3ccf4f4fb9528dfebdae6000000000000000000000000000000000d6207f6684f8d2f083c963551bbf0a674ba40e691a34ebe6164ff80ba9bab2cc23024a896d7b906fb74c95016a9adfb00000000000000000000000000000000145855e7d610b50cde39db8995b127145d68fc9bea3f075f65b7793acbb14bbb313a1a39bd96fbea6641baae02612b000000000000000000000000000000000005b533ee83cf72f0e4d9c9ddcc6b91f4364e50a106becf766987c490d559d0f733839ecc706bbc9c2c75b243814068a3000000000000000000000000000000000cd8fba13b9ba7557c7577da183bf50810fb14eec7380e3b3d4f2fed62bb36f2b5ff288736bed0578fb6f47fb6d22ac86e0fa09884a7ff4c801ea0722cf6bfa58a46fc3d36058e8c395ea8fe56d9fca4000000000000000000000000000000000fd6a466f2eb12f6337ae9f9b847ac1481820013142af1a474229c5f5f5e1c0bb2d9678c19c7a3a1aa22cfc7b5052e0e0000000000000000000000000000000002a0340f5a0caf5c66719f7d546972bb4b89147989280542787d281901ff036b7c69d41418c21c43127c0158593aa5cb000000000000000000000000000000000deeee37ef96f26a4907e1a8a8f3f030dc09102799bd0c6dbeb1d208a0c86a423d0da6313e0be03c026da5614a6a576b0000000000000000000000000000000007220475449add59b3cc6570701528dcbdedacb9a3d39674ad4aef4d94114f24d2bff32f40b25af97ba883905ea6838a27a3377d7b9ff3aee2ce1194a22d7115b09a9fd53fcfa5e7f76bd9fdd35559610000000000000000000000000000000009d7023ebb73df81455f74cb2708c14ccecacd49521a0cf67ecb6edc8756e286ede59eed54d89eee5f77f178ea8fdee900000000000000000000000000000000002ad48fc3192634e7b01604678473e286afb0efe67a4377bb885d38b59ea00202241fb28c93232ce7c9a3dabb136a53000000000000000000000000000000001934664f2bfffb254f0415d6769f4e2ac710ee88cd822bf5da5df3a2541f887e4155dbb7e8056efb2a0370d6f9173e3b0000000000000000000000000000000019df518e1ebafe95adf683279729a3298fc8d7eb39c9a3dfe4b6665153f970e243e50dfb16fb87b3be54192f69766659446a62ef5760c995cb3cd0984d607c232c1eb0df5516a501ce448a189a3134d8000000000000000000000000000000001870048d360f397877321904563d35bfd0817ce464e0078e9605a4744e2723f49f9cb21dd3d6f37f1f9aff5a6a99bc530000000000000000000000000000000000e29dd0da13ac451d013d4a38408827cb0e739772e1f250d31e4192ddc13d651ab576ed6b8f4ee44e928fa663244999000000000000000000000000000000001646183099579322e0115ab0b3bd6c814e216ae6b2b80206354925565b7bcd97bc12668b7f3530a95409456ac99bf01200000000000000000000000000000000092f6f594ad0d92c9c64f78c819c44320e6bb5dc1dc8fbe58acc7ce3c101e49a74ae6d50b1a668a3b7436dc445e3da345f0c1a7c2dd281f7d2f006497f99f65d6a1e22f1d9aacb08724b3576aa19e19f0000000000000000000000000000000000428ff447de18dcc11b2c5c679bc2efd125464f589013c6964ea6cab33d9b7cbcce3a5d6177bf43114ee256f23fefa10000000000000000000000000000000000d1ded695e88dae6dfa702375959831f4bda688fc0faa289dcfb90a07f3a7963f2c9070958561909a2051a852cc15e1000000000000000000000000000000000c39bf1d11fc5693167890246c81133faee93a8639f459429757965e0b62e372153ce53c61f2c539247dbe7747b27d1c000000000000000000000000000000000e84ecb6dd9cbd4133c22350f07a976ae13dcbe4c6ae09ccb023f2118fa2dec68c20ba2266f9b571bbe30dde97480e0a94c1476ae0a62c502aa096a371e30ca885dc13fc417e3dc9bc00bcdf516764100000000000000000000000000000000015e040fc8753f06ed1112cc06e2cb7142a4fc984834f01faae718c17cde782d5953547857ca9aeee1c4a7d91df060d330000000000000000000000000000000006789ac15d719a7159b650b757f7d3cf58fca02d3b8f3685478ad5e5b1dca0508dea7a8203ece97c7c6d32b2f194458d000000000000000000000000000000001824d75634043cac3fd17ff0bb141daf7010f70b5941d8f75f1ae076713afaa7e0a0a25fc71038baf1b1255d64c914c6000000000000000000000000000000000a2f71bf85af6392a8a070596e30225bec9e3dc12c70e8df7c545bd6bbcee56799db2c9a8d2504c4f90ecf6a5e18abc9b677bc9f1f7572f808e969aa50efc519192ab8653c71090e5cf8cdeb1a3544dd0000000000000000000000000000000008bd859ff1f22d682f86e1a0e3bdf3a332ae78d64814720687a3de44c9bdd7506d2696b4daf81a94d33f64983967fdc2000000000000000000000000000000000d7b4b958e0087f8edf18a4370ff98700764c126808d5c52afd3e71ee326c766c1e5712dfa351cf5b3c518e52133ce780000000000000000000000000000000013a145331bdd9c93e63edbabb9f6c541a7c4dccb1705f07eb353a0407074a76022a8e5f5f2535b41ecf6474649e257bf000000000000000000000000000000000a12e461b7439bff0dddb560dba21ec53ce88f71fd3dc10723f3d8742ed63a1ab725f7e9619ca1ccb729564dfbdb1be7f5ca580a25a5c87015f57f7c23cc51a0beb5926c84d44659e45512da51aa0cf4000000000000000000000000000000001430a8184c5055008a06ea22ca9c997d1a24ddce7e374937c32ed1e487c80537b238a589b5e50b86fa194666bd3410e80000000000000000000000000000000005c78c94f457bdda242deab79524bd2beac82bb1cb427dcb2872b56d1f46d11fc9d69ba132004958fabc5da7d6d103fc000000000000000000000000000000000e985e8ca038b5dadc9fcaf22699e75cad9d2effa47fe7d4c579ee056b1e34ccc540372111a665041062fc6c39e05d170000000000000000000000000000000018c865243534fbde740de0ffbdeab0d38ee878c20f5d84c0226d1f2b14ed3359f5b5b909808b6b3789bfcab3be75c4cdfa1cc45c35e266a82899d8ea0c9c1f96f96140eace41a8758a87975b088f0231000000000000000000000000000000000c5b10541ec34dc0a8b8e42d9d6fd6f4f71e1fe56b5afa323f4ade35c0170b5e224a66771326d9edbddf2bd38c6c68ce0000000000000000000000000000000019cf33c19936f7489a1bbc095d0f5c6ddc1f43bccf7e8d1b30fb8e8cd1ef747b483b9a8e9faf21cba7cb17fbee887ad70000000000000000000000000000000010e83916faa7bc9de9feb8a7f34ac6f2aced06a771b662cbce846107245edb9c07632782300e838957788a8d88c8253c00000000000000000000000000000000066127bed5ac9f2871500fdd68a03ade57c35449d4b4186b9fac7c89e91b4ebf2f2a02e94d0b578aaf60b32017f147a493d2908aa9266844eb265c2b1c17f8357a5ff039836ba83c837909f6a9d0bc03000000000000000000000000000000000cb5a734a28b44f04d39ffae049fe8b63b138411661ca6dba00c72cadd47b50ad4b71e858e817561682d6ca378ebbe870000000000000000000000000000000000baf4d689baa09aaf763ae7e142b801223c8ff58f2b541ee4c44ab2460fb8f6dfc1e9f61a8d73aeb92d7d08c281cf410000000000000000000000000000000008a0c736f19bd0005c9d25f88565b1355e53fa3403021577de536712ec986567184f4dd626127ee80dd03cdf9044b2ba00000000000000000000000000000000063ffb7a3b4e057a9ffe233296c11fb462136fc4b187be6f9e36f9e6d335a3d673ef8b9ae6f60c146a075a1789f389cf3b94325aad8a2c80971a781bf6f6bebad63ee37405ab7e903fb7094beef14d06000000000000000000000000000000000c33d89595d039722222b9b9ee7ff1a0dae896a8de97f202d3aca00bd81d0169f14676efc4b051bbd339dce862d8b60b000000000000000000000000000000001109a24dc6f70bea47e040b24df395bf561cf5f1ee79e90c9b0480fff0795677483a85e6f2e9ded4f36ca849ff39d6f60000000000000000000000000000000009c7878f3a4e4e3149b72149a7da91bf527c4d7c94b15ba80b02e0e50b02a2c482ecae9f458a881c87e669986514f6d70000000000000000000000000000000004284448e42187c128578b801f76d421fc508cfee9360a7203a91d6f9cc7ccb6ed3211fc5df9e15f14aea98bc298b2f95143a8e734824840346078aec03d6760564870c5ee2b2dc13f8a39ac452be9f5000000000000000000000000000000000271ec1a3f8e3364ba8e101b49c0bb17e2b7c7f27a4aa4d4db5c07203195050f30c1a05d33c524a84b1a2f0ce31a587200000000000000000000000000000000082ce9d1da5d7f192c537b2bd617b36b65f88b308fe1ff85e47c64b62dc62324458493d1cd1da9f5fe308d27545fb6510000000000000000000000000000000000b30356b59eb04258096d0c3f357fb04471583cfe6a060de5279bf2cff4413678c1716ba87d0b6de6b6e79a96ec26030000000000000000000000000000000003c02470a14211fef14d754f6f71efb33a06a76e099093a5b9512f907ff819e1e0e15f14995febe48852007bb5c380bd0dbee37fea759c2a58cf360c654f85298e8ff44b3f900e8229c3f838345d053b00000000000000000000000000000000172df3290c3c5044d590eea59980d02e02d4fc6fe7948168492362de8f0a85df0c3d09d8cd8b206cc4d1608311ef4c130000000000000000000000000000000010e4d14065315a0d9e48204e47955ee9652b08318251a7836f32e6fc015d4856444172de44b3b88efa1b54dad346e9b1000000000000000000000000000000001549b9c85cb2fc2c7495d7ef6aa1452e58937baf58717037069e6bc6d72ced3a163f800991cd26510e71aa64c44f66170000000000000000000000000000000007814c2f1734fcc8cbf9fcba06b936c86d0452a2370f8c9480b97105e42f9babfe0869cecda7e15500e9d8d868290201b92f9db82d0976f4c379622c4028002ede2ab17f647bca3bbfb159045cdb342b0000000000000000000000000000000014f849e9749a5ff6b7b10daac7f5934be5f783d49c8593367c4243664e01b1d3552e878802d7dfee823e0122e9fd46f90000000000000000000000000000000000d0b32d7904dbf08269ca3c6ae3fe582501f55e32337ae361fe4a58dada560db54205e56a399aed33bce8758a05ebcb000000000000000000000000000000000cb21440baba44c3cc6943c8cfa2fe544a652f06423d3de06c2ff734ebbb544da07ba8982b3009b6c4857b73ceca570100000000000000000000000000000000174ef591975fdaa0e3cb05bbb4140abcb38f685ce4de77c95e2cec1911985557b77d9229940b8c9157ccf9fb553e8e0d98df4ba50cd5cb5a02d5f50b3ba23e5f5b0172a46cc315a0a94fed05551a68af", "Expected": "0000000000000000000000000000000006da1222c7ae02843ff289931fcfcb315f621972f45e4fb4160b8bf48cd8102d50fb53d2c699afd36892d91f5e608784000000000000000000000000000000000523048c5de2d0139965c976d8c3328666e99c249104712719e992334442245e955cd6b14a1e3d666220617d78edcc630000000000000000000000000000000009f669d4e7d89fa8d999d8d5a6323da9445583344276bd6a29494a91174aeeb29132926a893d5a0eeee9c3048ebc0dd200000000000000000000000000000000099ee1c33d6f09a8d063393d2a8debeaba93027e31f7b23c5170b6747f56bd6e6494de966dc280dd67a38d39ae35a336", "Name": "matter_g2_multiexp_94", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b46cd281a09b85d977e88cb2251cc61cf13181522cf1c344b114783c4fa22d08f2d008faea3dfee8ea7c56aa35ee39a0000000000000000000000000000000012b530bd34f5b31161355436c7dc444d41d634b0ac3292c0096558618005fe82d189e4b208a48240dfdb4d50ad44dc620000000000000000000000000000000014d334e7835d4bcee2698ca4f643f9692f28d8090ebb8ed8f67c60639c64eb116067e5e8a6d04a0c88c765c608d57ef1000000000000000000000000000000000578cb4e243b4b20c99afefcdc0e0a9e308ab4bec6d655a8c4981a711515c807067472a6fca30060d776213b8ed98d74e49662df81f6bd455ee554704ff0c7d5a589d91e017d7ab4c500d36378c17c8900000000000000000000000000000000046ad1212696acdbb686543d284d7cf2e1e8e8c10af76c6ba51d55f060c006dbab25d3a789c71c428f5bdde9aafbf6d5000000000000000000000000000000000a6a880d52fed6a45bdc61d9ee78d8fe472e76ccbe155bddd0e2a967f4d116bb9f2dd4c62cc6f7224b835c8060213ecd000000000000000000000000000000000786544589eda15edc433edcbaa46d4953da72473f04169ea64dc114b99f0a58181d41dce1fcaf7f3109f66aef02e53900000000000000000000000000000000030759c3bdeafc94fc8fc0b03ddcd96869459bf54ace74582aa06c179323ef076aef89c09ce8e7bf9109ab2e8c8fb0be79eb26c79d78ab84c4d7e48e56889a601fda17901037a74fd79355e7536f3953000000000000000000000000000000000e6addfe0db96a7377fcab1fb92183fd7d7f13ec003fdfe0740bcc8cf03d8cc602d5d808b4bc874f34944a65b249997a0000000000000000000000000000000014a4337107e716113d8ba0fc7f75e85edd1c132e2b3dadb3f9cdec1440f261513646525314b5c0de6fd372472aafe877000000000000000000000000000000000d472ee0484ed831f8ddf7ad86faef5443df8b943c6fd4c3f94c8d52d9eed6fbb53107170a60f25be52219ca4816788f00000000000000000000000000000000035d06ffc452c65a31f80c3f8a0c1e2d15e32d993ec06c50499bc0fb8f669acd3d2182ba23d942489ea922baf61dd49cd2918ddc2bfb7f7cb3d7e74b43b9a972c5b51ac20ea83f41d5b51034b5714c0b000000000000000000000000000000000ef1f5f6b3041939557368d613279043d1aceaf5fee3ed90b3b756ad409d700fb41e62b3758c8c2d325db7a37f339c610000000000000000000000000000000004d66040a8e055399bacb6a1e762b698afbfabf789caeb957fb7a3dccb01d7dff5414e90f5a14961c4e980b298f834ec0000000000000000000000000000000006efe9e66078000c26d375e87ffaca643aae9cd3f8337f5718e0e268b74f4b7838f7661dc0ce60f557e162a21ff467160000000000000000000000000000000014ab782a3b2c06af7e9c2f28f1604cbfa8a676a874853bf38195780751d306936cefd1cc38c2192cb756e28793d2abb3e9a8159fd7915c15db69355514d9dd26c66fbd14af969ee576401b1b782fc6d300000000000000000000000000000000057270788a199a894b37a526a26bc4d293780d365a6b66247e7417884d543dd752ef7c89f2f4b38f4b51e6f9d86b45ad0000000000000000000000000000000000b59fedd6798487ec09d226a7406b27f04f7983075b4659ca6a78c6bb8aa83828fafdc6488518e2cba6fa4193de938c000000000000000000000000000000001105c18d92b4192833302814ee9b176831e57fb64b703ab3c2d3f440ab302c8fdf7ddc81933d3b1adaad16038dd6dc1f00000000000000000000000000000000020509b08e6ed980df29da649051c7095edcd4eed4ce95cd797da430cd09062a110bae21b6f73daff2053fc0289041fac818ce6e33e581595e83cf8d33a62edc26ed38c22f20c6949a94e2652bb954cc0000000000000000000000000000000007be348ccf6a76827d3b9b33e7a89378c133c9b226e47dcb205ee061423ee6e1b838bc262a7befae7c15aa385ced00bf000000000000000000000000000000000689787c19192ad55b9c6c260a5ec3aa203ef71f0b746eebf10f82526c4fadaa8570936d7049c1a46e7f3cdc455a63a6000000000000000000000000000000000306965b09678d481aa4c754d56a0bb4565f16f7523cd0b404fbd39dfc3b6ed483f5239fa30f13aa3e87918ca039d5ee0000000000000000000000000000000000a2586143f9610a96eb0ef86593988770db5ed49663eab72f8c368b9388bdfbcd02fc6bee09f4fe055813d140ca0fa89ab338e94b31d22947dbeb20fce3150127249d2db6107d95bdd032eb24c49645000000000000000000000000000000000018f46dfdde786a88e582ff6addbecb4f58e12c2625e3d6440f2e5b5781beaa95cad6f63b7d132e84700e7bd344fe3200000000000000000000000000000000185a4fc339a95a50551d53c18bb0dc3b74e9c164729c2b0d919392f7aad2be3ebae3b8f676ab81ea05233b3039918ab50000000000000000000000000000000015395b020a9d0bb336066c1347dd91c557b6ae7b8817cd8a2cba9e5bb149ca3401d661227c26d52a9be234faea894c8a00000000000000000000000000000000103d9d7e33a0767554e13b57dc756981488a3c7dfcc026ea84b35b0af21193e301226cb5a4760962707d19a95841be9296acb797236dbd0316fdd355f07b9b45c9bc626f73105e87c376af4d7dc075d30000000000000000000000000000000018359aad8af59cdda484232b885d1b14956ec04b5584684b13a64d97b8310c283e5d66637dd75de405f5f4bc65a6879a000000000000000000000000000000000849fd55e4f3d4dfc643dfede6356826eef21290b84f7e8e226deabbc84273d95f7be5479e9656dc907ec367a7ebf8f60000000000000000000000000000000006ee01b54eb7834b4de53f821ad46f467cadffce6df09751b728d0952bfe615253d7ad173892a52c6181810a815bd90600000000000000000000000000000000161472d45b56dd9fd276fc607f2eef84c5c843ea05799e732d7eb6dce96c632335949e1b3a06815e410e919f4cdc3fb360bc12a8b34e717b2c410d026660c14182250d7c66f8f88dd4cc94e550421caf00000000000000000000000000000000107ef91cf3a3068c4e5644676f7bc7c5f9ecc361524bf3fe2ebfc606f22f8f83b38c0d4bae89f3cdff6119cc27fedf820000000000000000000000000000000006a7f7cad2fa9db8824e4e30da7158f7737d2536554b904ed835c37add0341c07c5220db0f9801da2587a456300c7b75000000000000000000000000000000000f6dc3adda42dbccb1d1e3fea8918f5572e8b26ba3011429e754edd28559b731853761d33777f4e767094f80e63d417700000000000000000000000000000000107d93537a79173ba9367732fa3a28113ec37e053cdf31ce6970dedfa8a9b4cd55238289be9a6f40319e3dfedd132f95537f0f732fee8b882d254a81704d2310c05dde186232f3cffc05401fa98302150000000000000000000000000000000019dc19a1663bb05ebfc0b7cc23ea9e07376de413f77e15a685a3f11fc19bf0ddf38d5671e2a5e6e31624cbcd47a19cf60000000000000000000000000000000019e78aae57f327fbe8ce794afc22bddde08ff9bc9ad3527601cb1fd5dc0b8ed8fdf3b210f86760954b48bf61d74162220000000000000000000000000000000013954a533bf871e99f4a7d81a8b9931c480ce7fc47260c3708c590ade42e6b7bb887d4d24aa18642d010a8170cf85d34000000000000000000000000000000000a561d3f64ba31a6d45ffcf1bcac95f8f665133a1e962e31351ec78e369042bd3afb0c43d12b3087168c1142107241f31a22bc0bec2501a505cc8e00a24792bb380ed451ab6f56fde07ace8b6c9348a20000000000000000000000000000000007149094366e29537b0ad7239ce04bf49f253e4b746b9fe440dbf9b425bfff21064fce66e286e08c87dd83e22a3b499b00000000000000000000000000000000045ead132e0d03c842656cfc82a45c8b4a3b0cee7a5d071c5f235791ff7b5ead071b2c529b446a15aa8837aafc11222d00000000000000000000000000000000013159458f2123698ad4e7d41da47ad7d5083b928839e346a32f2307ee69f643ca11335d50e47d328b0079f1873cc7e800000000000000000000000000000000167edcf807ee723ba70e352367705448047c6b5223fe703381af6bb103cbb24da739ed005b14fab5699fbae6574505a7c7b10c801fb9d929432cbbe994b404d3baa5633628f396d20d047fe2c2ac2914000000000000000000000000000000000feb6f6f85903b3c8e4d6ec2ff234775f12727fdf7c35eade09c9773b004270f659b00248338f0b749d6715778f1f4d90000000000000000000000000000000003300794df19b9e472e8b869a2762c07a9251cdb96b508dfecdbd62fc3c3843b37118d216a64519bc3bdb71e40f9bd700000000000000000000000000000000005fa144135a5d6cf1c73055750ab6582b4c6d368566172b75902b1fc7a6f5de2a251ca7efc7ac6cc6c0bded14df02b700000000000000000000000000000000004239a7bfdefbe78116a588810328024b1bcebaf8f28f09387dcab66dcf2b02c94002df09d12db369fef9dd960783c0b84f2f3f31d9869799ed8bfc2cb129dbbeeb096d771730ae2863c4ddece66158d00000000000000000000000000000000007c8a24005575a3098c12ffa65095bfe227ee59e5e978a7ccab7a9a72391fea61690648c102ce24af723945bbcafece0000000000000000000000000000000000323d57bec7dfbb4614c8c3b286860fbadbf71901fa006149053ea614dafd56b1f3d6a86fa55bf1cbdfe8af4ff08dec000000000000000000000000000000001180b2b0b9c4c12f6d06eec07bbf6f5a220722015fe5365d1c4ca9e58ac9c8f67964d8230152d7a2220575c756bdf8b0000000000000000000000000000000001969a364c447f07d0820586bade587ccc816e50696aa0c5ea4f1daf6cd577769a890b44caa013d93e7f21f5ea269aa85c62206fadb762c23bf77f69f69bd492674bb92edb39248ad2a432f819304e6ea0000000000000000000000000000000008a51c01c3bbed13d42a4da626a8b89e2811db1d83d7de3332b36881ad14a5c8668ece4f5ed2b71204810457aa3d75cb000000000000000000000000000000000658a56aaf627e3f776d3f03caa2c00425bf197c6fa20c92f563f48260109a8f935d0d1638f5039486ce0c0100834fcd00000000000000000000000000000000126d1964f2d964c290cd7364e175ca4a855149e5c4ba488829a436b09ee5e21f6c964e439739f15317873088726bd51f000000000000000000000000000000001803186f88833393bd853970ca4fe414a43b7a619ded1f9c830444b4d43a94e9146146e2284d690436b395bf1e3fad15a6f950de53d07fda75ab43f73982c2684edb06317568df15b8712dff2ef782830000000000000000000000000000000002dc3756c7f4bb47559cd720a3acf4159290d7413e0498877d1fe321cbcb7cdda90b6c8b4ef8e27b2642b82ab9b3174d000000000000000000000000000000000c7490f1ccfdd91aa37a3044d265cb0612bfd9c065c370adb813b2d96f02d44041e79921d1b8935dcdb8c83ea4460ef30000000000000000000000000000000007beb34bfb9ba9b6fb590c7e830400888095d1958b252d187c184de91f165e12599d66345341292fdcb662deadcded030000000000000000000000000000000001ce203d58bebe1eb5b7cbc6038f75b2f7534bce9f50e7e4c91d6cc5ac1bb68d9fd8ce99206c5ec92bcabb71672c6ac195a373fab5176d124f783a36eb2346dddd5c4eba9e24e4c0cdc4f925e2e24cc9000000000000000000000000000000000765acace3e238e51bdaa08c0f6d737c9de55b5ce9ac3523335f0d35bfab6f4e7e2944b8aa4ee031ae9d39d4db96e9ac000000000000000000000000000000000b0fd488a6f9e92c4bdb5e82b52a0035f9a0aed7f69ec65303632017669f34d11552f849326e4dd204d58f50f3ad124800000000000000000000000000000000033991f66588b5e39eb78c7cbf62a74bbde2fa1b7c96164cb58040f0887c485b372e0ef4def9d38da9c6f5c4df2d59a700000000000000000000000000000000187d41fa7905739078d2c2f8775394f830d20352a9d91e97568c6929412f356009239bc9e1da3a8c766e89d09893b5b5319d855218eee020f9cf8e4c0b6004902f0b16eedba8a1c911476af34f65dd40", "Expected": "000000000000000000000000000000000dedf92894c567ee656051a7f02384edc7206152af6d3c5f662ca02559a3cc349c6b034c6fadceeccf652a396dbec6c900000000000000000000000000000000089deb173bda620678247a7218408594efff7ab0cebbf627b93ed37e553cf944e09232b92afe2f5f31d29bb9ae442c26000000000000000000000000000000000178bc39b2ca8b032d3cde53d2da3f8797026d78c76c51381b377c79992f027cf55ba4e182773c99c99ea6293a948e5c00000000000000000000000000000000195d9cb91537e77e7a4be4370b982b6d36190342ef6ebc2250a9cc8ef6ef45211736ce1f41da899178c1adcc4927a9ba", "Name": "matter_g2_multiexp_95", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004638ececd7f626a069b1bc3ad9d0f7cc71e5f0c1b11711fbfee1f81466b574f7a11de8161e55eb574ab367f56b9d6480000000000000000000000000000000013ef4f403f139771afe7e97815d3b3777818a3054d02125d3a25138e504c8c2c6696061572322aa19ace9ffd8e3ff308000000000000000000000000000000001910f776582f5acbaea626d2378e9da133b63afa087f25c2cfbcd1e7b34f6a237f2e9adccc303f9d5efe22496ee2ab75000000000000000000000000000000001963bd62098614c4ca2fc2a9e2d679c2b74bf9d322d34377cc63c3b8e7f8a4eb7d6d440d081e044606402fb3f51b0cee2a397c2f19a8c4e66df0e062f179be2f45a0c5e104588222a1a78447512f299b000000000000000000000000000000001935ecdf4f21cc6b510321b4ed2663e339954cd7399b9d67f1d9e2ea7fb9bfff8531f83ab59d3f0546393dc289ab2dd7000000000000000000000000000000000f390b86fb4cd4c1a072a83e1d1198a57a650fa6e94b69d983b693c592bc0c8fcd9a46c6883adacc4c7e2546dcd079fe00000000000000000000000000000000136beae11ea54ae26a8d69015ea7793675625b2013dbeb081a5ed877832849d67ac709b81fcc4fb322b262ec3776c0c00000000000000000000000000000000011f1df574f63f679b6464df463b58948fd337a4b3f159229ba0313cc040303345e75a3a2b0ed0dedfbefa89d8331d074f193d5a575c80a3e7599923bf5a8ba8a48e8f98322d1d8eb1da42e446d518c1b0000000000000000000000000000000001510378fdcde4027999edc99d49bfb46423ceb0d740829e310f8a381a7632fd0d6b6aa3533c2702a5ca76d386ac0145000000000000000000000000000000000bae237bfcc061552ca07eb14300cf557c974611885aa6894f7933f7dc7a0a1cc3b5587bbe1ea5fa604e3cee1db5f7c9000000000000000000000000000000001743207a1814990c798dc3de272a02b1b194a485bf09faea382dedd957861dc15cbf981f9906cda50cce2899785b9a6300000000000000000000000000000000106f902004c66c80437392e92cad73bed6b73010bdc7b6a75de4c01f0b6fbe5b8d1f47378279bfa42b3af05120854ced07f2013742ddf2d35448feb80b6b7aaf2925d3975ce28ed2b1ac789886ae26e400000000000000000000000000000000123362e41268f7821fcd2294b032c6a51c6d80506eb052ab6132267fa248a1a60c3e4eb2e75a1674bee1c9d46d82b9180000000000000000000000000000000006296670461ca67081cd76528446867e1a4905f88742d0ed8d1f7baf86e0a5e5ee86c8b0eeef07c14dd821dee0143bea00000000000000000000000000000000058bff9544e4e02c063158a52a68c93c7544e8157d37159dbb99b51b09e3d8f5b307bfe63a10fa409e20a35219ac244a000000000000000000000000000000000b135edfbf53187004d0977db94eeabf426ad7bea84ad76c6ac771fa186a073d430af76d717070e3c4057a7a2da095984e637a80a4eb1b2caba68b6828aa18f956c62baa7c5e9e591a15156c5abb605000000000000000000000000000000000133d3a223112dc5665e78fba8fc8d040d133858d984e66d2382d5e629f9369dd127e93c7a4da77fad98a0520ebedfeba000000000000000000000000000000000e88515db391bcdeeed2a9f64d27387af0391bf832164fba79100b560d8150debbd703c140dae3ba9b1ec35c1f45670600000000000000000000000000000000042583722c69a19f413392c6a2b75c8ca969be85eb951056d7e1d94e046dba49c346d5774009b8463a40b0576ccc1a6e000000000000000000000000000000000ee61a9eb6ad497c57405a44d798868e22b4fd5b8c480e9938cfdd3f1817eaaf331a9988368680158c59c2801add0a7a27671631f9afd9d2e86f263f5c17c3c11c7f6e43efb6d75cb2cb8250094f228900000000000000000000000000000000020352de9b4e8ea1acc8589bb22e23dfd0ae3a80de9e21bdb3f6391dd05a012e635de9e1f5f450bf4aab05728c054f8a000000000000000000000000000000001733593b94ec800bb59ed97dacbefda5ad882a8023346bdff8f471c5613c67247e27d72cb4ed8cdaa0f236018dd2128a0000000000000000000000000000000011f272a3b25bc519fc3e229211b846042031e22fbed22ecd0d1a4ef1d05feacf105772d71157e3d7293575aca257cd5f00000000000000000000000000000000153b4b4d7d65f7bd13d20fee4812f04706c96cd1a0d27b7e139c47299805e0ac86e8941aa38d90331c78a61c2dd56aa3c2decb1f482f3eb48e7f52b89f6452b659812ef79bb42fb25f03aa9969faf9bc00000000000000000000000000000000143e1f6dd9397f0e89a46c6ec995bf6c87ec8a72b309f050dc5b3134e00e2a16327767cb0573ca5ea9776215a5815df500000000000000000000000000000000186cb3af2cdb4562bf2d0c180079547cfb345cc3943fd7f9203fabbdc1547079cb9ed854f9b1a47f513e318cd409df83000000000000000000000000000000000c8c9197fa5a1e66b371a653c5d18c01fed8d17a8aa92d89b2cbd954b9fd2931fa61abb6676e4851dc9481732c6195610000000000000000000000000000000009026b259e840cb5264f6aad6ebbb09661f5b6d980389817309aef99e4e0cb228d3a7a06e6c25bdb1aeafe5acdc44441911eb1de54fa8ccb746336b681504fd08f995c864a8dae2aa866862f81f0e7850000000000000000000000000000000007bceb74ba86c07d0fca20e4febd3b12b1fe9f786c9a5da0531550244f40261d7ce728498fbfcfe16cc235db6ed42e11000000000000000000000000000000000883104ffcc0d040d70bda04dcf67c1197c39e200d4d9daf5f3c185638a13dffe3dcac94fce4175187dad867e8d2b78c000000000000000000000000000000001404e48e86f199486db7d40076cc8dc4e2aa2c1b6d4bed8f027512e2c71817905b26ff4f0551f9c08a2a7a27b2075b6c000000000000000000000000000000000b789a6addb98ea43c0f9e85831a75b8ee1977936c17929fb45d4c06b4f1ec33b9b41e32b52cde542c9e4b64d27c686cfd0a61dbcb0c657e824cbcf4670a31a95ecbd47a9b93812cd5124f3ac9450c1b000000000000000000000000000000000654e7f3985bf90dd1e3169382690fdc0f804eb6384ce407a060f539804fe6e0451094abaa0dad611c15d3ee52f31a92000000000000000000000000000000000deeec957d58a2246ff8f7b7448f5198647576c16c1717369ad155ae36d5a6bdb42c8d6a1f0a095891fb0890b6203f950000000000000000000000000000000013a01a6ca4c296f59cfa4a5f5399d28af76ffcb8b218c861d5e6dc603e140f730f632028c8da46c823d87bff5ca703280000000000000000000000000000000003698f659e86b96613ca74a480c81e749bce4b74324976c1d241a0911d078926fb2adfcc3f901a7a015a02f525ddbb808118e9c70cc5def8e7d258e05273937c514131f39e0cc9fd2a3620dbffc7ce3c0000000000000000000000000000000016ce72e1798ffd84b52ac664a184c6cf5ce1ca2aa263c9d056355cf610517e9c7bf7f057c342f6e3ae801b84c2082c0f0000000000000000000000000000000010992af1438eec10881b5e2e3fa3b1e91b6b5313ea58dcc0cd2159f8ba6ce5912d81b38956929620e04b3596f6835a6f0000000000000000000000000000000014315dbebd532d0c835e8e85a02c0814574cf040a20c18d06573718223c8ea15b7ea69f0cf342dd09037258398ba4bef00000000000000000000000000000000136d13a83e72525b2d4af54d14d5e21d8bd9bed18543836b02ae0a7e51d433c93aa1943e85f978a8a9ff4454d8c5d120c445931b79e2b826aca02d1bfbb00c2dfb6d30ac2ef97a4ded18243b1afce7730000000000000000000000000000000002c1bf7dc75006c2941b89a2de52fdcdd1b4fbda5b14fe3fc165915b90fd9d93cdb8105898ef59d5b374707f0afaccd600000000000000000000000000000000049a16efcf81de84e443666bf990f6aad2145f9c9c2c61a752e256e8f447dfb27b462e4553544971807f909a666af12f0000000000000000000000000000000000aa4702fb69d791ef958826753d3f74f61c7a591ab94bb6c1bd5d82d94c5877121ecfc1e769d0d16ebe491b775ad96e0000000000000000000000000000000008cd7f2562eca6c53a37382fcdb04be53998f45c2241bfebac3d1fb08d8e1d4df3182f2bd63861d0de72d58072356ccc982ae6de98df906922e660d461009ba6c04cc6497f3645a66385c775b21b210b000000000000000000000000000000000a6b30c4ddb692ae33c903693cdba00ba48efa48e90b9cec9dc747004e57a8d5a05b5522634fc0de306d38c28390dbf4000000000000000000000000000000000601341b3c4057767a910bf30dd16324ad7abcb55b7e98e73584f26d7f87d8a8d24ff2113c12ceb3077bf65e0912b2360000000000000000000000000000000019dc9c50f613470abdb5c763c0272e88e34ed38e617d6757f4e70d05b8ec9f67a023b4ec1363e7e60e38cff64e18f0510000000000000000000000000000000013fb1858f7efeec5fd03d9f7f4513e3e9103c340eee7bfe48ed3cd3dd073b96add9450a17f12e161f1d44669b1b2f813000674ac5d09c6c599173bbe9a43726c120c3a60a96d43954727a2f33ac4320d000000000000000000000000000000000d6c135bfe0fc7af93571a69b7c37ba691f051d69582cf159cbeb0bd59b48342172a82a3eec2e3d440805934e1574f2a0000000000000000000000000000000001b04e56cb3bb221caedd3582943f89a33b955f624f9e473941f1dd987f2898339142a654d11d87bf8bd2fd0fe0d4c1a000000000000000000000000000000000f185fd420b761a1e38d542558b0beffba916f369b37296fdd8878a7c3d2ac9d3ab1d8e45ad799f0d81bb439b5e5058100000000000000000000000000000000002d10ce460c414fa1094ef2b7de8f1ce024b6d086d10067be0fed4e45dc25c8e50bef361d39a2743be1e1ea4fb7e2ef773f8e9637886d795b75e7ecaee512005c1780e7ab17b9f20ae9232595478bb2000000000000000000000000000000001972ea36bae504d7047639ce6e0e6c3b16afe89fa3d6c6b33c910c8d4b70782d8165912e5bfbe8bd84f78f9f23f7f956000000000000000000000000000000000ae55c4fc1c01f1bbdb060191e8551a7ba5ebd3dbadd138202090d7dc6765fd1ef5fe8204ae76a8bcfa03ee5985a35280000000000000000000000000000000018ebed295805e0fc14f1c7b0e6ee12ca48cb7177c1d367a613e0d6cfaaac5128fefce0e8f38d4e2f11ae0d327be466a400000000000000000000000000000000157068d89fe48e77e0f62e3b5b0293423f35c5f4ffb9e0577f5aa49e91cea6bd312a0e65ec08af9c1f53de6499409c8d759d0bab12ac790cc3a16e88f1a108e670681f117d4fc7d01f8c5a2d6ca7fe8e00000000000000000000000000000000120e4a8935c08032dbfc19a43e2a770b12b05cf1dc229e12f683f0d7f604bc13666bf318fcc38038b618ef83c9448b870000000000000000000000000000000004e3f851be46bd85f37c8b1d84507f4ed63ea76bc305cc26a6f4cfa2135d5affcd3b319d9f57619e21c964c6246fc3f600000000000000000000000000000000138733f352029373b19e1c40d5958a04257e2b344770e1bbb8f377bcfb1c7225ae7a8b0b0e57795ec06a08e13c90d7de00000000000000000000000000000000093e85783c556a017829e28bc42b607b1035890fb9743bf0e279df4dd8a695c1dd07a76a213087c3a8a7e614b29b7a1ecce865074a8a41f8a3f40228046c5be68bdb50ced10bb73ac8472f0525302938000000000000000000000000000000000be1ae00f9ba0a2e57f94728508e0029b1bafd52c91ce718ba41790a3541117d1a9f846d68440978cdef016c3b9ae422000000000000000000000000000000001947683154204c9fc93e3aeac17b417453a24d01804e8acbf6f67947f5962dce875f49d05e6ae65384602828784f852c000000000000000000000000000000000859dc1c00b49cd1292cdc65c6aa4b11e27637b949c7db508930c557ee3ce00f98f9cd3dd0f6d73a646d176a91d75c070000000000000000000000000000000015a7a6984b5f42aadebba1e1f4682aaf1a2d01c9ce2afab7fed2269373467787bb1361b493dcdd862180e9159ec2ad5785e2f9597c9b687150864e90ab042f4f012a54d92cf9d2ece09e4a081ec9773f", "Expected": "00000000000000000000000000000000047cc33d9decfd059724bbb014fb9cd95de187e2dd29cf4a9bf9ad06d415e2cacb5a4e49266c13e0c38f2563d1a21d6a0000000000000000000000000000000011c79d93fa870d541e79ad4037c20b85d3cec053587f9df60dc11e7dc2727d79059f75bef76474c09fe61ed10b317cad0000000000000000000000000000000003df3f0db20c5ffea4dc9f4d9333d76141447bba50da18e521e89aae1e63750c71b392570d79e597967dfc9952e903c60000000000000000000000000000000014e83ea645b1019ac2dfafe370f616af0c5baeabe217ac1f9ecf78877717475b25911b339557422526a8163434439923", "Name": "matter_g2_multiexp_96", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cd1d25f285c2073175ecad5bba4987cc52012eadc7b19dbaa20fa82d7a6cfb8a52f33469b6308d921eb4b3b23f7022d000000000000000000000000000000001707b67a23d9212d30c06f26f0040c38389b185057e80236d2c828a8d9ade4f72eee1d6eccd78e4f4d71e2c28ee9539e0000000000000000000000000000000008e5c04effd14d915b9afc2083afa2b6d4008cfa0e47144a41982d8b5a8e77922a2609384e2c5d18c871ae24a7d505b7000000000000000000000000000000000f414acb056fff2cd6d9b408adb6eb7f34c8f66a66ee93945a3381d46c2d181613047ca6d4067614c190da444223cab685431a1df7678e49ee049b75ea968ca255ef456dd58cce57b64edffac1ac223c0000000000000000000000000000000008ea841aced2d0b8dd688947648a8ff18d0f6f03f63ee1c331f126dd4fc0da3d386535156b80902bdc1f65add7769cd70000000000000000000000000000000017a32ad2763d99c38c954f62466e78c0332e48875e15afbbe9c78376f1bab12346c73a573738353e2162d3928091dede0000000000000000000000000000000010ea738884dbfe5bc35d031bde9aa4109b1fca529502e236aebb5ad0bf71dd2f3db250d924415b0bfca56519f8ca5d290000000000000000000000000000000013699e29cc1871f51a469898be8b3c732b5cf7860286e655e65bd8176832804d17b48d0ff85eb023360db78162581297b6ccbc0b600f11f1b89061d94c6fbdc9b1d389244fb29a5d140dab8842d44eaa00000000000000000000000000000000004d504e62b2825651381ae862fd33407309851d5291591cd0f541fd092800d709ede00a9134e65ee752eaceb0a344b50000000000000000000000000000000016481efba290c37aa4ecbf940c76ee5df199b0c1f90fddebd2db28120bb5a14dd9f4a067b6d4889aeb683cca0f6ab337000000000000000000000000000000001400c89942cc63417ca4cb05c9d81dda3251e5611c27fc7727c3e803170672f103bff26f7216a0b646533aac3171488d0000000000000000000000000000000019889641be9db08880543ff476b9d4c72167092548ba49a3f3ace4518d3874f4f7993ae7b8cec90f092f144ec9d66c1a54dfe31190469897c30ac3736ab166220dd3702df5bc897835347713d03a8d04000000000000000000000000000000001927fe80adc6dbb581349c603103ad8831e645d9275af8669939b83829182cc6e2a30df2fdeda6d3aa2e2a6126e00ba3000000000000000000000000000000000b6d7934d5ca1098a85a0c60acca075220105e221b802b1be97c2967820bffc2937fc3278ed0f26905c60d44d5fd8dc000000000000000000000000000000000057acc1379f23c0d1d37427d400eb1b0a89f3736c83d3ffd797ae279e01e2acddd84082f13f3c8b8f1bf7c275702a9c700000000000000000000000000000000038dbcd7e08d34c553850a52336991a7d48968e98057e930790d78b5c6368eb2fe01571b60c4aefb653ec04122953d56eff1ceff9e5184dd9fea44da4f07529823dc9b100f776cef6f6881120f7de11a00000000000000000000000000000000014052031b88af979b7edb06c99c2e46bd9df2c862c7e1b71321754841fad67fc3242b51141e49ad86b61344aec913f40000000000000000000000000000000014806a86d078ee9bdde99257b67f50dc2ddf9bbf01dde931742ee6f739aa986cfdca06cd32d23d86f2c14c3b09033d29000000000000000000000000000000000e0561e795d35ceb8bd9e3b276406ec1f697a38ada25d1dbe08715a28bdd3d6ce6e0aac01f7dfc7c2b403850ab213b4700000000000000000000000000000000146a65209b09487e00e356e3b29952280ebc6a06343c4ce14efa0c6281bc2482698bd02295bc35125275ff5f5bb867dfb273e4c6266c1f5cf022902fe1310d2191af91c47995486342bc61cd361eab8500000000000000000000000000000000021592cd7f4cf9cab3be53561c889c9ee865961aad51339f6393dd6a0b7dcc8a7c48b753c947b15cd3add01abd3d76d8000000000000000000000000000000000f9e1a80bad58055a8577700c177889c4d702de04343c1202eaed9485a76493158547b20bcb552b66c42a0c86df809ed0000000000000000000000000000000013908dcff1945cf06f038e3caac9a7fbb3a6466ca18627e93468a875759a2b5599a96834ff21fcd6bfbba82b79536b9a0000000000000000000000000000000001b6354665109c5a64613c3bd7d805b3a34098708f3d41c7b77db031ac6fa0b2d4e2f2f70c84ac78687b0c0f9bf334771342b5cd4ad3179f406941ef6ea15d0aecdf9f6d96dc334c39b7dca89d256d4f0000000000000000000000000000000019394063202186e141dcebce7b8f0f267ba6057a0f993bb1cbe22a5bc528323823bfd1597a87017d478186a18f09a47800000000000000000000000000000000148437bcc43d432d70b47dadac8e738616c97d38d0f84dc132599626612f7bba74988bb23ae47ac15e6f70c059d607ed00000000000000000000000000000000180851594710f4bb5be7ae0104a383081c50f59e4e048614660ab5a4e2661e171510f5b112d8cf97a6af27d56d137c860000000000000000000000000000000000599f3f82f29b493ffe9ee3a8363b9a599a5ef3c9c5c680d4e003f4ac5a7de0562cba8e2a4c6da7d07cbe86c3f7bfb85b36620f65ed84fc0bb344b4b73f4eba4b1680a47b28b47f6d10f9ee82398125000000000000000000000000000000000cfdce7997601afbe484901893a1b5fc0b83e8d238d41d2f889a58fd4d884df1c667a000b53b587df2c42ad46aa2c3e0000000000000000000000000000000000c50bf3e06400cb10494cd09bd89f3c96ff49c9f74dd5325f9489ed6be13b59bd7b0b2351411ac854d430405b8a2a3de0000000000000000000000000000000001db313a34ca4073e4fa2287e234ac32bc579742de22e5218f7873b922f5804894826e6054925a394f125fce850f33ef000000000000000000000000000000000e0627a66d286e8d4d3654b32fc5f552a7ca12f0bd47eb6dee0dde22ee48165247c067a0f4c3d422bf3562d38a3c0cf1249ca9bcf879a770b0a054422a6ea97ae795118ae45532c1523c842696de6d170000000000000000000000000000000005285ba39f5bd981fce2fdf853706d70992acab2dc6d4c4198144fab397392a60d631056b580d0d98f3f350414ce554e0000000000000000000000000000000013bddbc1180f155872376fcdfaff2fb12d3d9645b81bd1475a5323ea855cea820ed7eb693791caa9bd3fa5c66036439700000000000000000000000000000000125644d32df397def58dff875d7e3f14166e765ed49a3991f45b38d74db3985fc7f5052058d85594c8b97afcf850e11b000000000000000000000000000000000fca4662eb1b39f576ee820385fba88ddd2fc01fcfb9d9f874453ad725cd5defb357be028fae97ce71bc5ac26d11c1bac014a0aa616e809b674390b4553bf2d9bf325e73d3a935eba94488dddee4e8950000000000000000000000000000000015b97d7c74c8ec102083b41d7ce5490466e1c0e261b5ea5c756d3f9ae79dd2d8ec6eb5075cfb76dfcf7bfdd80442f7d10000000000000000000000000000000016812f845faf96b8b69ac7a6af3c8947aa25877199e3c12552527706a17b768bbea259ea61ea82c4624a96cbcdf4040d00000000000000000000000000000000123ad55e5cb5ac5bdd3ca0a5afa7c3f8e4b98ad91a205f073fb546fe799ffc57b3c1c3a6209547ffc6ef05fd24be6f5d00000000000000000000000000000000017719f31946aedabe0e9d88ef3f90eb6ceda884f5e3d2ece368373785b2d8bf0f9677731803b25accfcb6cb716e0aa4ab722a1c20f068b6955a44073914c418a082345796912ca634e79983a24ec4bb0000000000000000000000000000000000497e3480d58027c780f47cc35a121ee0cd76c4e84d9a2f9002c04a1c286be990167a0138049ad70467132818f48ec9000000000000000000000000000000000ec0ddf938553105400f70989140ca322d996f48ffb1b35641ca36a6ba9ac1daac1603c100822f80cf62ec3bfb442158000000000000000000000000000000000a0b6ebee28a792df46d2f727af812c15fc91a471e0d8e34b25b26048f3b9606d8375b5b268c40fb04ef8f098e1d03340000000000000000000000000000000017843dd19bfabbd0cfa41fb58e70a8900397d17ccea783087ece90962560f5cf090e8d9eaa873a6a6ebac45219ea97a68b314f83cc3ad501caa44b4c3ca8cf68c70ff6920f445d3a7ada212b6a19ba3e000000000000000000000000000000000b27c82d71f7e4aab9a68596669596df3f62071e921e131ba4d9e59d8d81d370e077e93a4a6a43e059661227f40b38c800000000000000000000000000000000093004917ceb2fb4a1b33960ff74943d520f86e83aa02b9a6c85e4b9a489e9331863cd30cb6ad6f099d03289b4ada5520000000000000000000000000000000016f04e35186c7deaf730708e1678089bf3e73c1164bca24bf8f70c4f6cccd5bbb34bbb5dc313ee428aec4ac9c638a01a00000000000000000000000000000000011052348cec9dc3e85e01abcca5a652461f08a9f5d72b3fc27140a6a571137f0065ed7ccf9ec8cebe314ad9a214d5ed94ffab83099c69845cc87727d459ae300a5725ec53176424ab0ec8bd3f80eaff0000000000000000000000000000000007083dfb0738d58ba8933a1f60283e5da8bf90af5aae4053ca573ee7223d3b80e4bdc30b4a831ce6af9f52f393e9742600000000000000000000000000000000130c627b7d3a527c94cfeba9f514e75eac047e1b6088c082229a8c95d0765a0898ce1e45694ca2c7935bb8e41e44e8b10000000000000000000000000000000009610645b074e652a08f2b89dbe594afa3009d795ef211f7c036a56274b1e1bd69a035c4f356b6b21f69b9cec2bf7c32000000000000000000000000000000001020f3cdef468af700269aa1e9d928e71b8c521f23586c9b0155314f0073da7de04ca41ececd5edcc052af72c05f0e4bb1d80be637e2abd98d0433150e14b629d98fc0918c7dfc179204669ab465e90300000000000000000000000000000000123540047f0768b0af841aa4aeceaf3dac31ea832daed86c8cbd1d33ed0282c6f697d5881f9022af032e90ff82efb6bc000000000000000000000000000000000113daffbe413075f5f4f6fb42f37b6e9d5e5822aa24d6f865792f63e6078584246bcf8b17117385db1d6233974f6ed9000000000000000000000000000000001067b46fd221b6995d25d4bf0adb088e0554d858d4e5d9d6b59e1ae2a7d57188d559b0208918a8944aedd62b1ebd4f4700000000000000000000000000000000087dae77e483d5c0baa37b9b96dad5ca92b5869fa253bffad24dd8747446f7ce60858b52438e58233210d86f470f765fe670a57ce4dcfa680e60ef33ba99c437e4fdb160ea1012de36f4b59613a6af8500000000000000000000000000000000039d09a094d655c139cb9714aa258d9548473162548048b0f07c9317a41a7e5dbaa5aca156992c8a509d4071d9ae4394000000000000000000000000000000000f0273a38b1b9d006efa43c15a53f026587a676912d0275968608519e97994ea9c6a147e377f68b1738ebeaa178f9c1000000000000000000000000000000000132cd92417578d2e46884f1c1a1080b1916c8c8404d2533a4de02bf8575c80ce7e8097c2ddd1f95737355521c0ec21ce0000000000000000000000000000000019adbf09a268a3ed8eff936d25fbe8af2874e44d2580c7941dc14fb89c5da963b468a7088c4a763eac89f4d15deaaf5e54a999fdf391d3944318c54680e69b58ce3778683b6f2c607d64450ed32c6d89000000000000000000000000000000000756dced467ea32c3c425590b7690a45e250e464ac6927ad3f5d2d8d2826961b8dd7572db609375c8d06cc3b9bc3a157000000000000000000000000000000000b79b4eecbaf1d0f8a89f9ef8fc144b3aff38148ae260da7c20e9dd3866d946585df7ed12c8b7005e7b0e1387c9db41d000000000000000000000000000000000afc403b008b70e19f17b1ef37c9c396577a585b6c34b23d09621b891efc00ef9460c3f4b5f3e851ef63620dc06c824300000000000000000000000000000000024e06f3f3b18c026a166c41f75d7bcf699480f5b6811463c27606c9ec1232fd249a46235b7f5b5a2ed3b53231b333150563ae7b444cca7ebaba36b8d59aaa5c0e6c1454a4a2907866247e752e640a7d", "Expected": "0000000000000000000000000000000004f2480d0b7e84a996965b76055f6879aab5bab26656e4e5ca7220adc17f14b5946047484327bbc5952d9f2ffa5f92af0000000000000000000000000000000002f7260c55c500b54df4391a55eb4adefa7d19bcbec82a107fc0d222c898b97360a679a02ab3023ce2ebdcffd125ddf30000000000000000000000000000000002cddfa94c8f6b3f29c2fe018b1f8679d0e98c8c2656f86f327b9cbcba574cc52643ab423b458994a03347460deef6570000000000000000000000000000000014eb4c84f71ef5935e707a11a92ba34780677ac7eb198e160585ad92aa5c1ea21e3a77be940fe344e7e170680e2a8d53", "Name": "matter_g2_multiexp_97", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c2c4c039047d297049afd0e8f0375bd4294d628d3a22078d93b684b737e8c4b6ad3ee544ecbeaad6b3c75d8d217f3a20000000000000000000000000000000004c77a2c0943c6f997ce2e785461f8ec253c47273ded4e1af43ae882766ef8c168e66d831abc2b3b3a0849bbc210cbd40000000000000000000000000000000004456a6c267a5cc6b7d9a9f573270855186a1b621cfdc465fe71ddb4d614565d9d36b13985b31396587919226843c6230000000000000000000000000000000009487cdd8a0cf7f40e9087fd3121cb480730f4302339d25fa12128033239662ed65579a59b837bf1bc5fa87db15b15335b59d128b5ac47106b4114cf225dceb621d177141ef5783943f40a54ad94e990000000000000000000000000000000000ba43205e8392168824f77bac344d60c1a9a0b14ab55538c3bfea4a64984cf381a2f61c64f1ba1bcfd8a7973e43f6e80000000000000000000000000000000000e95e5ac415c3e3e7c9feb6e7a2af3e8189afca06ae1fe54bbeb31783810860921ab3c76a475fb227b3c8299e3f1caf00000000000000000000000000000000001e3cb2106a23e77a126013087751c4d2a419a51beedc3a33faa6c933bedb3d34ee9c6450c583642426edb352e04da98000000000000000000000000000000000ab5af4c98aca1fc3fa55355351d12f3bc639662bf8b5b772152988d676b00ef39f767237a2fa3be936e83d1dd77da86a057c0405e24b7373f67197b2109b633a02589711b6a92ff49ca024f893d7ecc0000000000000000000000000000000012f3d927316ba638bd6294f7dd2f3f166d20285ee1662ae4dc145835704a17127078343d26042a5c397bfef31754186200000000000000000000000000000000162893d6252361c340057bcac31986458b8b55a8a4283f5a06ce1730098f9838dad1bca264374e7261bb9d08c177c1820000000000000000000000000000000017264aead0ec41a079827296f3d32c12adfca7cb6c674070d54087438d57b6ccca4822b2337263e60075d469b4ce0ccc000000000000000000000000000000000480cae035bd3bf1b4a4a766bcd5f188833e9587e1aff0e1f10e36ebbf2f3ae76bc0946e7c336efc3ee00bf42e7efbb9677b05905180182427efeb848b2ba2eafbabc7519ab33db14de0746afb607191000000000000000000000000000000000d13375356b1518e37a13b43b7d192eb74bd69636f91c570c41a741a8763c03caf8d13c7364f57c867a4a3983e88060f000000000000000000000000000000000f6f78dffb404faab88ac7373e0c765209c0af80514d438e18393bfcfeb60d9a5e13158d399f43162033571ee4a75dbc0000000000000000000000000000000010c379860638ccf3b6cb8479aa38881b0004197e3e367a1d5ef7c7fcf075689d283b87022e2825b5c789ac6a448467320000000000000000000000000000000002dc392872cf2fcd8e196f10c1ded175300070e4e38aa58c89c81e1aa5faa08d770a5ad90a8295a890551f9329a13cee53e7f69582f4c106ee5bfccba1d5f557736c1b75b6e3777cfde47d552e6bdcac0000000000000000000000000000000010383a21acda7c8f3f3be980bff2d57fa0a5b2dc424164dd2ce53c0b20ca399d6227913b7b550462180b01c231e4813200000000000000000000000000000000078aec90354721f0a31e1377b3652bcb1f388ab36f1866c955f3ea8dfe6ac2c25bc4cea14f54aee71595c2c1bd2dc4910000000000000000000000000000000007dfeec77213d952c183452b98ad936e8854608d950c0c1451262cdc7d6de5aed0db07a8d74b3e8f674967cb4839c4d00000000000000000000000000000000015c09e4ed2ea76d10d196f7a733ccc272b94dc436d6bb5fafad2fae4a96372c2c6f1325d1554746814ae292d8e6b1e3634c87bfb629b817e7ab97def7400b0a83e47af8d628787ff814733fdf34ba8d500000000000000000000000000000000138656fa091cc6613b1fcff04a3efb4f9c393985b2c78fa838eecbbbb8b6dafd88d9c72441f9bc735649480b5187acac000000000000000000000000000000000a35cec4819ca3321917cea5aa589db8cf61882fd1135031dc41a8207a8e71d326312799291b160a646148c382ed086b0000000000000000000000000000000005b6e4c02c9c54630c96271073513cac3a42d47a7272f62a21c7ad4c85c19b60b70d04719626cf4273f6c5691719931700000000000000000000000000000000166a20da734a47d7e28cce8f0c2d679fa6c738a7a1ca9089dc67ba2b1c92a83b024b8991f131e7e8802a617153de4554bebb60069acf431e1671e3d00e4da0d70fa11ed4099b21d45a2b811f99dd9cca000000000000000000000000000000000a4432a544deda931b1f62759320ada2963062e722bc1b748c9bd0d026ffae10f228be36ea0ab076358924f4c06b6feb0000000000000000000000000000000000e955b1b1b28d2044b6be371c58bc85097c77145b239e913bb0729757518c465d9e69338066f7496aa6a2038ea604f900000000000000000000000000000000017ca2a7d52c3a82ab8abf9fc1bc187389b6e4904e161541008e5b3ba0981870e01060d1272a6d59bfcfb294c942403f000000000000000000000000000000001870649a50e0978185551f213eefd9305d33e92b3f8c39752b6ebe18ae86ad97f92acef05971dceee3b3729becea18168b1ee2765e762f1b8c2451270cd5a755758fd733d7922a537aa9f1fd7d0c95960000000000000000000000000000000013713effa20d5039ced751ebafe1516f062f11ee05ffad37281cfee9d7a49ab14c065709832f6674bfbf2c9f379bc9c9000000000000000000000000000000000295f7ef148430209b48c292b024474f05036edfdee082c56aea05a62f1fba3ee7a540955423f78614c8385da8ef60040000000000000000000000000000000007408c97321b6d7c27e5e442a9e35b054e743c34d845874aeb1ccf4e903ca7803ed7fb1288327865f9e0ff0a388e92b400000000000000000000000000000000081808d03722a2d48846a693059c2662dee614f181dc406825544d30a6adc0f9d84a712eff80bddd4a27a036e4bf7359d5009fd559714d5692de5500ec8cae9c04ae1ab1c7c6e08c8738ef22da19ceca000000000000000000000000000000000880b646a674723c15b240ff56d2031e5db724251b1402a68df8b26261ffc9fb60a81abf165c6832137dc7a7293142d200000000000000000000000000000000172354b62bfb8d388b5a984411414738302725a508e8abeacdcb46454371d5e9cf762028fb65921d5c3dd8c67d42a981000000000000000000000000000000000a1af459bc3122dcef78359e468f4094d609ae3da09ca5aa6efb71a7494dafa2373a3906bac1f324d98b3eaa982a27d500000000000000000000000000000000092ac3b47253c7f090df076914cdc08a715faf153e8e365392b4859fca1db14d3f7fb998c97de9ad99b7d0b357252f086330c755ef708d8eb129475785f24be9e7836385ac918c60ad36e80e2f3281b80000000000000000000000000000000003b23eff722c078a781771d8b75d519e7a062ca3e4252ecca877845920158fb20d79a9ce449d9087426b113da0091826000000000000000000000000000000000c9026e8d3fee6282492393db504a2c41db19d8fbb83260624b05ba4107d6cb2c90d645a3c16862b27cc3fcce9bf89840000000000000000000000000000000018b8648d0a42285d474f809519696df9e1ad5c35d8e848ad74fbee37425aee8844a8be8cb4d3331670ee294ddb9a290200000000000000000000000000000000068cad37ee8578f4b502ac2ef4371a10e5432e57fe20d0cb074dc427831872113d3514a0b199d813b796b8357fa2a3dbc2431888d05cae840dde4c26911db1893659fdc345d5433556d9bf75e51fe3740000000000000000000000000000000013200f0aea4c60937be47213b6149b0ae76767f3559e0519f774af4a5d9431e2dd7ea74b42cc3ceb28ccf0d2f01116f30000000000000000000000000000000001c5bff08fd16ecb68f21289a3e7b9a2ec5da1357d604710a18e78ab780f8ef0343d5d9ee7f7988a009329b17e498beb00000000000000000000000000000000125453772eb9d1335ce4dbcc8f2ab8426fe89a0e49fec51d4e96718a38570aa82dbef452368141be2df260fb131c50b2000000000000000000000000000000000432cdd445519775b9914a986a0941cc829b4a15cd361df9ae7129547b24f7a6a15cd8fe9393fa1551db2d761a208b8ec9a72369cda74e5c86c6559cbc4f4db1b3ab24c5150c7decea862ede3c02c505000000000000000000000000000000000396cb6d7b44f92b716ed02985d351b4e8cd1bbb95f239e4f29d7379428470be395e2faeb8e3a910007aaa490d3c336d0000000000000000000000000000000000ad0c0623fdf50c2b504777554dbab3cde1b9705e976561873d7c22b81f49c7654a7c76e558fad1518ed73a0d3c3570000000000000000000000000000000001241d5bed68e02a2ddeb3ccbe109a161abe81edd7affb72182c5163851211c4763e6aecf766053b61ce575de893985f800000000000000000000000000000000183696d2a48feef6088f4e9f75a5055e8c54b3813658b593958490ddd4245ac495a8ff966861b20f26047f07fa8609a0c2f50989b04fc29c4c4a0090fb11e860c15f89a66f3bb8281e4678ba63ff3f9a000000000000000000000000000000000fe0ce41aa9e7cb2bcb4e01721b7b1d99fca4e9b7c4df09bec00bd346fc57c25118ba70d5333b7f3eef2659c64520a470000000000000000000000000000000005c932e09c62b7ddaf3f5c420c60740befa7cdff5bb812e0f089c45098d71b57004b7a207f0cdd34daaa3282cf6e9f7e000000000000000000000000000000001874200ead9776c1ecd6a54a57e5d0f9577910a4b3afb9b051622f658fe3ef6cc5070af60e7ef910562720e9716158d6000000000000000000000000000000000c2c657e58e400a67e59deee8c28234ff4688e781a2f6f2f0d0b186a5e4012695a522dfa0770cfd543f55939a05e20b09fc9abf1c76ff11ab538f46ce768ba597eb5f2f63073ec67e8de10aa1d666720000000000000000000000000000000000f0b561e5860321249b9ff434c604d26c3275824fc4ab9c1ce5c5858605ddaafae83ae27e523bf6006932f6c7f33d0a7000000000000000000000000000000000b47aab85bbd909599aa85c5eda363b67790ac6729fd8b1f4f53f66dd796cf2fa3496407b1bfaea4dc8eae53519054e70000000000000000000000000000000000cab1ebd23bc05c53bc9e8481c469eac3ee1b140af545bebed10a8fe50698d2ed883219881929207c0addf2f687198d0000000000000000000000000000000007742de55b799950e6f786f4eef45d0fb67e0475272ad68a183135b70047abab6c2ed51ede16c39be7b986df334e9e75d4167723682bc0e7476797b3be5e14b8de3e4e23b4ca33c50a2096cda8766dd7000000000000000000000000000000000923861332988bc843a65ec5dd4637f9dca8a15e71b82c780fe60d768213d118d8948ab554e30bb9253e900a9b7d87f200000000000000000000000000000000132b1faef49e7966a05783ba526e71134bfb577b13116548352da37e91e617d7c72ed2645e672ebbc517e079247dfb0e00000000000000000000000000000000000a46a8893a194ebfe077afd05fb25d4680f1e4991a3ec29475fa5651d086d20b38136155a65a4c70af31de5a78af59000000000000000000000000000000001344eb957594028b4228cbdb8efb03cc7cf49ec43b2ca5481eae1df6f2df3d5be9a7c4e4e78f8c39be546e29a83c92f49644c3727f78dd12811092190d5d10adcd5b9fc581dd783c97d4e7b5130f309a0000000000000000000000000000000012d7111303563a6358e5ce9155d7a153b5781062c2f6b919efc67ddfb4c61ef03be8828ca6339397b84763a5f8a7e8330000000000000000000000000000000010a2a0ea9973728d3fb1b5906ee84b2635c687c11398ebf605cad30216df3b7b4e3ee1653d4b323a690e6ba614ebec30000000000000000000000000000000000b93d5de37b892d4de9407a820c73ecfd6cd9fa565db82e7e8c14c8406823f705ff0adf6bd6add5ddc5f72c91e52e840000000000000000000000000000000000dcb320ceba5436df8f099c5a77f34376c96d830f5e8ab80667d156d89f6bf8998c148ef9a53847ed395871ab86f6d280df9846c84354ab7f947caca7800e12e38d8e6651527e6831f4d8b1bd66c4f3d", "Expected": "000000000000000000000000000000000ff3e299e6b9fc488d6db991cf9d226d330846e87c4a5cd3e5d4ac955bc2c3c2d1ee5ff230098b48f594d256495f489800000000000000000000000000000000097fdb8fc95d64c7070d8c71e0fd2a933d1e1ad3fefa230f079bc5743828317cd1b0c6d4253ba9c3c6ec6b12d53afa700000000000000000000000000000000002448bbb179d82eaa453cd5452752b9a083b52694cc65c5d9b47f72eff118d7aa06b0fba18eafe93d2937d7399c001af0000000000000000000000000000000009dec4c0aff2a46b07855c87e08832811633709ddfbbc30dbb7e78b3de43bd95e383baa6ff4c58188f0c7643e0ea5a40", "Name": "matter_g2_multiexp_98", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008afabec8a9985cbbc6246825785654c1d2eb7da5a01f76c4af4d0096b9baed3c33dbe492d14a6f9e762f06eb3d198f800000000000000000000000000000000027c592315dee4bcc892acc6f41a6eff5219c308253f7cd715d0e4a32c03c6d0d0e8568e146e9e799ac3025486c77fc30000000000000000000000000000000015b4ee27a3aa518a1ec1b447bb8f9128301c85b7176296d68dad3339b1dee78715b2f031a7fb6ba376145c97ceafeef60000000000000000000000000000000004b7e30ec7cc024ced863ce511cef3cabe954a4e5843dd636d776645a44225a36ed7e153ab5bf5d18f23c6444751875c8a71abe11a893fce872f6b8a020b6d84241df03eb934b50cbf3571df4800a83300000000000000000000000000000000119949d36d8d8e2bc1c26ded5f5fb01225a980a28b934ed3862480dc9297a3758e0f08ccaab3a09b5e5c0e4215e3246c0000000000000000000000000000000004a82dc22316ee6af39d937b662d1f1f2dc855c2ca8f33ec3274d833e87d594633fc7fab247911e0f46564397910d6ce00000000000000000000000000000000196900a09d8504ed960d41f4a8a2cde2e5dac61b008d3f6eb47e86d7b2ce6fcdc0f85157e3ab1571094d9fdaa75d0d500000000000000000000000000000000010c52ef9407eb4ec57844aebbcc3ea5000b1940d035dcc2a873327affaaabdd79e3560cbd29c63ce04f6279056d6eed1bbf28e5bca314391550d3a0fce50b1220965860e72c8c3865a2d4c599d31d3f1000000000000000000000000000000000e43655ae05dc6cfa93113dc26cea895d1c5bc73f20454c7b441dbc5ac80035b290514b13b31b41931ea5336d8d9a6a7000000000000000000000000000000001199a873958c63147e6b82625dfea15ce90dd41ceb4e315f67221eb874ef32c6a2953412e7e981659c72239a7a72bfe6000000000000000000000000000000001845af5936b4d7487ffe59137ba2f86daea3770cf37fd560969ee48243389941a1072205e049ddaa06c0ac56b7edc8930000000000000000000000000000000003cc831177f24614f93a118b896434105f05a277051a852fb9973a775fc54f779c2a1f3d64c457e5231dc22d6aef606b58b208a6845aeb2bf31999042c59b7b130a7ce5297e88023953b1aef63616fe400000000000000000000000000000000005e63584bc85ba58615985f6a466afe05268e545e0062cd7214e0b6fc8b87537c745b754cd9a1144948bc88b3c43acd000000000000000000000000000000000635b6a49090ccede3ed2ef203f0ed164783e3df4d9a7d93319515cb9230bd841b61a097f39e30175793b3e934d8e426000000000000000000000000000000001861e65f47a9da1584c45bc79a66045d86bc1709c2d1cf6cd2930a9fcc8c4efaa6536b5015be8d54789e8f574f93f9f70000000000000000000000000000000009290ce63d55eb436794acf11be9d896f03e7608a1bc8528f61ec9473f054bc9fbbda1072440e58e2f6ba080a01180173b53b6cf9e0ce1661c4960283be790abf956c2d6433529b8f3a32b92b227aebe0000000000000000000000000000000018feed9500bff884d2bb58554da2180c68267b6d3a45c2c7cee4c3f8524252d3faaa5eff971bf40123587e669fe66bbb000000000000000000000000000000001441bd3b58b4a4a87c2459f873c0692f5977b775af984bab46dd76cb9f775d2faebcb77b2854c9f1faa33f6c5de61c6a00000000000000000000000000000000123a890c3362c77e5b5cf9846d9c9e43fb3242d5a831e640ad080993fa0547854c8d11cc22f7f7b426528bf1154d2300000000000000000000000000000000000ff4a59ea98d13cfd353ae61e18d3c7018688f755561e6a1da5f09acc4277e8d49645087115acc64f992ea778a11f39bb049228435ade4c4c565e65f39f13a84c747c312afcdaff352560b9fb3cfebcc0000000000000000000000000000000006b019d005141e82393a2ca04469d1f6fd7b9456001ffef4c34eff6b2e91df58e99fd07944f52b108bd41ab6c4d6bbf200000000000000000000000000000000109ae87042029856befff0c916db5437e1e058a96f2970d8816b3becc93a1a50d6d336d5451303715f3e272147a36caa0000000000000000000000000000000000fc381b8dc9dc02d34db13e34732a10d0dfcf676c224a05a3bffd888b0af7c415b38af0b6afe6b464ffca42947c6ee5000000000000000000000000000000000087040d09c39ccd06c9ecc360fa02147a32e8036ad6e4b6bdf5b3883722a4e5a887dd022d53706d2585fe558696be6656197f5ad17062d2ecbdc8887bcdd32e5ed4c48cefd9e14d622a0b800d970330000000000000000000000000000000000e35c27b29df0fa9298bb9ab6a38b3450782223e2115d79152f9baa924d762d583b3ebe88e42f33028814ec78e5b319d00000000000000000000000000000000190c65667627a16f0af0ac7f23af0803bca810f3986b906b7b4f126d98473d52badf45e90e2e45bb390242fa8c40135100000000000000000000000000000000103f0283a5673c16bcc0f74f259c2eb077061947da04e467dfebf62aa005491e32b85cb73418b624a30dbaa01672921e000000000000000000000000000000000465466955c908607191faf15f0768dce42488c488eb4a065977f21ac7484766bc0abf23961ea2ba46dcc04956abf6c7721d9d7fe10104cafcad71307e785321ab87b2b69593535caecbf0e166cfda5b00000000000000000000000000000000082346e352e845a54cd4267f93b85b2c8623d4650e00c1c56082b73ee31f63588d2c117d3cdecc0378fbbf8956b082040000000000000000000000000000000001a7f43c2bb19cb32345c43c950536f8e85815b86364f278f6ec8169eca80917c2b8fc08d59b20cf55f25dc468e7bd7f00000000000000000000000000000000085a5cb020df10f9b4c7afc01b1d11700579dec1e85e766507def2e6cf5b714174f7be9cce3b18533a5ebfeec2b4e481000000000000000000000000000000001836d7506d1cc984fb777b8ee935d6f5b110644f59e96ff44d8329336d59a3e1d2b53a05d35e97f634baa4fdc11a6cd8461531ecb61365908019c1e8074a4c322df2b356eea3f3eea9aa1e0e1fc5525e000000000000000000000000000000000c1c59828ec6257a02679cff0bee0d665d449d2a158bc6d877e84cc0fe2161c297dde09b778d5e1249c515833e483004000000000000000000000000000000000f5e82589bfb7781e4110f1486752b00cbdf96cdf4191d75053c6d6d646e1c989add011361031a11559e156d64139fbf0000000000000000000000000000000015053afa7fb2b4e4b70f3c8a570fef8288fdc22dd951b6ba8a40b6087b9ab04ede21f0ddfa84d6d18914041bcf244c110000000000000000000000000000000003f399800cba51ab35624d866831ab6506392cb3acf549787153ffaf08cc451acea46c7a612821dd96c45f8b75133d88569c1c1ae2d18bbe36ed50db1bf30957802b09a982fbed49d4968815552e010d000000000000000000000000000000000e26242c8f73116079369ef4265f624abd4377e4e3485c28197663de9de9f5618c3b6ee602ff6bebd1c242aef7295b2200000000000000000000000000000000066ceb3ea6067220bd28fa1164237782859d27c1d3087a42b4d09bcc343611e4ed2be014a27f5b394c67643dc00f57cf00000000000000000000000000000000157f9d30de52110ea7a2a35ddfe67d9fad7223c5e3307e797dd0df3621520a421958a2835205e3c4777923f47d47e5310000000000000000000000000000000016ebb41beb85b9489a6d5482f8a3330a5c5c5e5718e8efb8b67362f9d8e9c313e9e563275ba38c207c5bf3d89c406ea62061d33b2f7e786effbd2e93101a56ba1bb62c1a773a08b72ca82f5183bea35b0000000000000000000000000000000005d1c9109b5b7409f94ae3f7dd9e8ae4908a9b378fea4ea284cbd33d1e59b605577b63892aaa8ec14d415f34e22fec520000000000000000000000000000000005afed05e62599f20f7eca019f41d770c630cf6359cb5601464be821691fba5205c16e7b580e6881047214f938e5104b00000000000000000000000000000000105637a2aa4725d8e080dec3b731a111ea4c94b79f898dfd51f645501ef0c8d68ea8e80fde28ff96e927e44306ebbb1d00000000000000000000000000000000080cfeea754474ceb37973234d5dc3269f8ca99bd862d4d2d1a602321fc709945a3209e5ff2cc962cfa6d03017c9a1354129b150752d2d5551a622231ab067931678454aaeb23f76168219406f0d50ee00000000000000000000000000000000137762ea5c80033aaf17570451b15a062feedde810f11ebdbe9a79a3275dc12613e0505835c122bd5f9afea7dba84203000000000000000000000000000000000d89c04e45e60769a63fcd73df2a138c457bb549195f2c4eebb3be1ea46149f286756795be8328b5b886f497d8167b34000000000000000000000000000000000be43d515083c8c10f467618685a43d4d5f6457204bacd278445943a9f44f7189b561a0e1bc59d2757fcfab2e3f93a4a0000000000000000000000000000000011a52583227c6dcdc1784d3633fd584612a9f3bbc1922477396dcd5af84413e5e9382a34a71b3a72491ea09fab2fc6bf366c32d5d3c132f32a6ac3cfe1dabb649c59ae224338f747ad98b193e8346729000000000000000000000000000000000073acefe33525dd2d5204cce72371ed82c7e4b58d1b4e7f4b4994f9c58b02d9d6206fefb3552446b6b355e860ace43c0000000000000000000000000000000007344eaeaae71e17930e769e02bcb4f44ddf3d040ffa0b081f25901cc125a37a58a6a5d13e7b0ba493802ccdaa054e29000000000000000000000000000000000a65fec6ad29ec3eee9ddc7ded2297f49d03ff18a255f1e6d29d2a67c20713f319d79d513af0c58ae3cddfd1f6240ff50000000000000000000000000000000019d5f00d9e2b271f4e9ac779a096386f08ae124f77fb8183405d48ea7f16e685805442dc67a392aefc643ea95b4f1fcfd997516cac28a3968ac6946b5bffaace0856a52e38fdcca11ddfa16cf5a568f50000000000000000000000000000000018230bf1a873aa04855af1426da30f1b3ef4b64eec613b9f660222e3827b325c318baea031b463c7e9f775165d22ec8f00000000000000000000000000000000017faafa1294fac53e1de8cae9601acc62d76a5f01a39ce49d65f3f5d2cd5cca33eb90bb4116b3ea36f912ae2b81b6cf000000000000000000000000000000000fc3ef5ea59849a87fcd45500989f1744cb5570ee88e34a952cec32cea2eb5900b64d8d0d04ef5c51e8fdcccd46412490000000000000000000000000000000001c53aa8aaae8422fa4fddc86cacdefa89c37592c8e67e472a23627514623a90901a619af79e93561a0dc65215837274e881ec65fdc2f58e46d3ee45a06d0c5ac844ee5b62872c7ba21f6b48621a3371000000000000000000000000000000000e3db6885c2db9244548e11b8c49b73f85e4104b413f54308497262fdff1957495859830114528a22c45d39a554ba82700000000000000000000000000000000181b1bfe2d9a1c563e73356d73f4ed3e7061a79c610bc97c911ab1a0213d123c9f83ed6706e862087a796ce14c5cf53d0000000000000000000000000000000013f5fdceddce771588869b945bd6025e5ce485fe78a362356720b474b83998f27e535cfd8d33ee51cfc68e5d514f915c0000000000000000000000000000000007e8fd7ba457a3cefd50c641847425cf2262deb1d6945a0bd740eadf38dcaa616edc48c3912508d663349f089b8b56fadcd9b95e49473277a665ca0f9a8309df9ed6ee4f25d803aa967fb8f688273e650000000000000000000000000000000004b20b0408da7b704694b47607928a655077015f2174fe01bac9a0b3a61dae087b0b593f58d2947d8d84f75bbfb327c900000000000000000000000000000000106d623b2007c5d7128e03e540325ba763e992a651e2e5c78936f82ee2ff72d89a1a914345486cd0a04440c75beb190b000000000000000000000000000000001847348e5ef429cfdf1ba4d265d8c5ebcbec3d5dd4611ba36e2754fbd3d327273bf2eb7b7ba4b3888d059dc87f034739000000000000000000000000000000000bcb0a9dfe5189bc965e9721407b4cb3ed4171510aa4d4e5d5f0823a1c2827643e1278f9c0ee960c54ef8f6c208eee7b334582482a9038ab906880e43a4a9d39e73b6c63604eba0c8f6399eb5c288638", "Expected": "000000000000000000000000000000001205b70b29ee04212589f8a70a71e004f517d3354e714c1b4fe42cf93faf1a8ed40dbc1b5089ddb53bb052c9cb74c0e8000000000000000000000000000000000f619082734dd9de653b61cf2fb927199f228637db70797bd2a21fdd48b6ecd4c4f712097037534024880a436fdd63680000000000000000000000000000000000592eca560be6ae256abe1796f7ec394a8085c127437f6590c8d41501a482c61456392cb320b9e801044dcba7802df9000000000000000000000000000000000a6d20b8009708ca01a274aed6dece732c5eed5aae5e4c2f3793b5fa1f8cb8c95037ce387bda2e7476e9c493507c7fbc", "Name": "matter_g2_multiexp_99", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", "Name": "bls_g2multiexp_(g2+g2=2*g2)", "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", "Name": "bls_g2multiexp_(p2+p2=2*p2)", "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000001", "Name": "bls_g2multiexp_(1*g2=g2)", "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000001", "Name": "bls_g2multiexp_(1*p2=p2)", "Expected": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2multiexp_(0*g2=inf)", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2multiexp_(0*p2=inf)", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", "Name": "bls_g2multiexp_(x*inf=inf)", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", "Name": "bls_g2multiexp_(2g2+inf)", "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", - "Gas": 79920, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", "Name": "bls_g2multiexp_(2p2+inf)", "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", - "Gas": 79920, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g1multiexp_(inf+inf)", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "Gas": 79920, + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(2g2+2p2)", + "Expected": "00000000000000000000000000000000009cc9ed6635623ba19b340cbc1b0eb05c3a58770623986bb7e041645175b0a38d663d929afb9a949f7524656043bccc000000000000000000000000000000000c0fb19d3f083fd5641d22a861a11979da258003f888c59c33005cb4a2df4df9e5a2868832063ac289dfa3e997f21f8a00000000000000000000000000000000168bf7d87cef37cf1707849e0a6708cb856846f5392d205ae7418dd94d94ef6c8aa5b424af2e99d957567654b9dae1d90000000000000000000000000000000017e0fa3c3b2665d52c26c7d4cea9f35443f4f9007840384163d3aa3c7d4d18b21b65ff4380cf3f3b48e94b5eecb221dd", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e300000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845147b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff66513800000000000000000000000000000000108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f000000000000000000000000000000000296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d00000000000000000000000000000000033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee65600000000000000000000000000000000153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d21600000000000000000000000000000000038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3000000000000000000000000000000000da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b0000000000000000000000000000000019b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4000000000000000000000000000000000492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e2000000000000000000000000000000000c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f90000000000000000000000000000000012c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad0000000000000000000000000000000004e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a5690000000000000000000000000000000011c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd64647b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665131000000000000000000000000000000000ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1000000000000000000000000000000001565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d00000000000000000000000000000000043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28000000000000000000000000000000000f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a561247328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d211", + "Name": "bls_g2multiexp_multiple", + "Expected": "0000000000000000000000000000000016cf5fd2c2f1b2e01cc48a6d03e8e6d7f3ad754d6c7d4000f806c18c28d8d559cf529dd159c74946a7713d1906894718000000000000000000000000000000000628d42142df8d620d1f3709ac01f382ba950eaf14c12863885af5838067deec4bb363ffda427fcbdd2b8ec6cc5784ae0000000000000000000000000000000018168dec2441ef462e9a769c782f81acdc7fa49dffebb996764ba9fa96b9200ceb5edd9e96b33c383bd042b4e6af191a000000000000000000000000000000001065aaea2c4aa1d2bee7f1e82a2138ae7016dbbade8383ad912d81eca5fb260086238f95f8cef8f2f491969d4cefa2c3", + "Gas": 112320, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be9a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g2multiexp_random*g2_unnormalized_scalar", + "Expected": "0000000000000000000000000000000014856c22d8cdb2967c720e963eedc999e738373b14172f06fc915769d3cc5ab7ae0a1b9c38f48b5585fb09d4bd2733bb000000000000000000000000000000000c400b70f6f8cd35648f5c126cce5417f3be4d8eefbd42ceb4286a14df7e03135313fe5845e3a575faab3e8b949d248800000000000000000000000000000000149a0aacc34beba2beb2f2a19a440166e76e373194714f108e4ab1c3fd331e80f4e73e6b9ea65fe3ec96d7136de81544000000000000000000000000000000000e4622fef26bdb9b1e8ef6591a7cc99f5b73164500c1ee224b6a761e676b8799b09a3fd4fa7e242645cc1a34708285e4", + "Gas": 22500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784519a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g2multiexp_random*p2_unnormalized_scalar", + "Expected": "00000000000000000000000000000000036074dcbbd0e987531bfe0e45ddfbe09fd015665990ee0c352e8e403fe6af971d8f42141970d9ab14b4dd04874409e600000000000000000000000000000000019705637f24ba2f398f32c3a3e20d6a1cd0fd63e6f8f071cf603a8334f255744927e7bfdfdb18519e019c49ff6e914500000000000000000000000000000000008e74fcff4c4278c9accfb60809ed69bbcbe3d6213ef2304e078d15ec7d6decb4f462b24b8e7cc38cc11b6f2c9e0486000000000000000000000000000000001331d40100f38c1070afd832445881b47cf4d63894666d9907c85ac66604aab5ad329980938cc3c167ccc5b6bc1b8f30", + "Gas": 22500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000158d86d94d3fc700f62c8cb601dcf7764e6101cbb8de01f1f7b55fefc5e24e94f70746a7e653f3cd36e70f6f9eeb19a00000000000000000000000000000000017ef47a5a61b00edf11c076760ae3295ea98f5ea8e883133166ffe1e9c0033a3fc3130568d60fbc4ca34dd28143340a90000000000000000000000000000000018a20502ff640f5ccd4ef40c5b2536862bb45dd6d399d32ff4690e2470249ec3f62e5adc675b88097960810714aac65b00000000000000000000000000000000077c18d5153f5fe43e1cad6627c4cc91b9b05cc1f1661770fe873c5bd414ca06f6a660c3b1242dbb7658fbac2a4ec2381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000003b9f634aa9bbe5f1f1868c851ccb6d73772466f13520fbe90ff62ac1a4e9dc259c34f52a8ff80ab0d6e9a5c34e4b6880000000000000000000000000000000000a4e221babe00556ded0646a5dc2413eb0b9f53901ffbcb9828af356d7edf19c92161a3a0f2928260dac7a3748051b2000000000000000000000000000000000b832d19041b8c20daab73c63d140b89cc85b0e93c3e94ddb47c50f4551bc27ea73a8efb29f49a1ffa728eb284d9884f000000000000000000000000000000000f9a7b4a2d3fdf73bf527e56f711d5a774e49c39872902f2504e75548378c77a60d563bc80462a50552ce665327c3aeb", "Name": "g2msm-1-jwasinger", - "Gas": 54000, + "Gas": 22500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001f3f7d6493293d421c83eb753a4a2e951d9b64841bb6aad436e87817fece70b87afcdc7ec0689b330c71462137feda40000000000000000000000000000000001c672bc28d52311f5b2a5dfb484f2de97da7b791b7280cbdcab636337a8c3ff92ef032e972a9cbce94076ec7a501df1000000000000000000000000000000000cefdd12c2460bb7a6abf1c562acee8a37aac4e080a3a181c5b2a7e4389058b3706d96895e7fda4843de4fdb4e24a5ed000000000000000000000000000000000b28cbe334ba5304c21c79adb2df297fd160cbb44e0fecd63164e7b77b5d6f313ad145461f21ab40c978bce695e40f5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080b4f0f275a065d13ec0757df5f9f5ccb6853690902202f06120b3df7438e62ef8d16dace6e5f3b2fdc461b707fe7e7000000000000000000000000000000000c9b3aaf853954089743824fcb7541a17d25b3b4ad821880280103e62429efd1b450df5636b1886c90e6b9b44049c7770000000000000000000000000000000000efc2727c83b7c58685632373bd043b1cebeda8ca5dce4441092b02c4d9f115e026602f614b3610e9443121285057f3000000000000000000000000000000000f674d8244e3ad6e0f624b9fafbd04da8cca5c0fb72a1029769f702295de353a05bc722862871c883cb0d33b6e31ec131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000140cd965dd0f87812f9dae22df3c53d14f957a3c72092653e142a2776d7dce04e4a4a398155a72de4ebcaad84064733100000000000000000000000000000000152bd340c9a33466215173a7e46c9741f7bb938bfb7c4128eeaa47952ab5d1ed78c5799026d3f3eb3b94876a1f4bd175000000000000000000000000000000001896288360604d3a63f8fd2d9da480ac11c1231f3d6bb9644a34aadf028269fa2ce10e04ab6372f9eacf21af01fa05c9000000000000000000000000000000000fa85a31024cbe2e330f3bed313e028e80a37c45578c429f82c4d15b3b3aeaac8cde593b35700357ac0c6770148ce3be", "Name": "g2msm-2-jwasinger", - "Gas": 79920, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012955d833439825eb893a3d4ddfe5760dd48d620099a2b18d9cda6a9ad219025bd01db7672047710d92f09403c2b742f00000000000000000000000000000000192ba698fc0ec408187c156e4de78a475cba4f40fa1a707b4a845cb6160ee09e84a7ecc3569f9620895d2e50885dc35d0000000000000000000000000000000013a841e58ec34358fff2921460f9fbed16d68a838a64219392245642c33e61f9cc9b53bfe1489f868e8dc9073d8747bc0000000000000000000000000000000004434fe1406840cca10e0d3b172d8ffd3989485a774f87761df7a3e162d7ae1f7eba45a52f34b5f4b36fc1759fb728251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dfc2680bab8d9093e90c5324e2762c988ffd2d687aaa4c12f1903b468503a70cfe034e3e1e09d4a99332a7f7d2fa0b0000000000000000000000000000000000fae3fb5ca951839ce3bfb0da111a528fb1f8f869fa3d855f4131849744ad12f6dba88b6b22a8b41936dfef7fdc4f6d0000000000000000000000000000000005f26c825332db72e845d750d67db486d5ad3ec46fd0c138e88a01d878bc3074e4394f206b1182b96996926bc3a602c70000000000000000000000000000000018527a6c30b6f68e9a288146aea2fa4ca6cdf7e3f0539b37918f6e70c7ded725f0e1b6991858fd14b6df169cd712fe6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec5b78fcba23383a949d51c7fa511663a72e5e9c3ba97259dd1cf5b69f5775bb071c9ebe4d3557f3ff9a799a90985da0000000000000000000000000000000010053b3de4e313e2a2f3cbf6e53b62e9aaf31761fdf9ca1ddf784a0a7932fe219309d2fbf184dec516d283e0be02f5b5000000000000000000000000000000000ee6c39b3cd62e89b9c1ac3303acaf53c5fb15ed565eb4c7a0471e546610e1dc1e431a26d9e5362535ccb6c91fb59202000000000000000000000000000000001374bf0d6b58211fd62b6a2e674166044b8dc4c237c2ac28fe953e7dadb5a8ec128d2ef25949da1ca5d9131edcb8ec1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000011196b5b47439a23c884c0a809b7dbaab0776672b5c7f0adb2ea5477a731cbe9b2e0bd4a61a77f3bfd8739d2cef8bc23000000000000000000000000000000001647a9e8adc1d49f81a8c3336002925d37855e78ed9641656a392613f25f09b63a03563f6f169c4f208129507566c28f0000000000000000000000000000000009e90cc8f0af86e710bc9ae232f17a821d09ea9fba7bcb1f1103419a3eda7a04f99d4ad4613c5bfe0d768d187595958b0000000000000000000000000000000012258ff09fdf9ccf5727768ddc007b425e5f4f4bd93452d9bf6e3302aa9ff83ee59955a9dd0c66eeb09c47f18178ceae", "Name": "g2msm-3-jwasinger", - "Gas": 103140, + "Gas": 62302, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000034887c26f5c3fcf41e4b6c823ca04b7f6bb3daef74a2c144e0e7eb7c67805b9d22eed1b3cc85b1748a9aa55c700d5df0000000000000000000000000000000017ea215ca57751c8959c5b24e9357b3d4362b22c8f8221156c8bd878ef04c9f5ac933783f50edc2f6e00b1335932e5e70000000000000000000000000000000016c81317773b0089f98201dc34c15512859170ace3c5f2ef2fac285df27c24b261ef8a53615ff4c4f07668d4a1a3144e00000000000000000000000000000000151e1f3f6a122d1aa6f70bdce5b155a8a63727a95f4d47cd159529155623e184b3a31a1481600c67d579597577dbd9141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001829dc871ed0ccf6a3c64f91c32357ad63c81cdca6ca9f73bbfa203d3c2f1288ef8f2febe56f32dc4fbd465dc19e63de00000000000000000000000000000000021abe124ca0135fffc9a0ecb1d1cdf4166d8119bab824dca6b980587420faa0a9fcc96c4a8e4a7d803a60a6862c5a7f0000000000000000000000000000000005e4fe11fdf781275b73e60a19a92f986fb5a4946386d5addde47d4c126968c57aa89a52cfac949045ef4933ec8852de0000000000000000000000000000000000c38b94471eddcff4677f91ee3a91628f19bcd7a677f092ee8311b1418b7cb8fd12d2d24466ffb18bcf4a6d6e5a21231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001952d3a09b2645bd2a01e51b8827bdd5d95fa6731fdad1af01650375f750f1c0a2fd792d953e2fd891e687e279209f600000000000000000000000000000000138cc5807661294959849bed4ae41a1e8b3ca1b79e21292aca549cf53f164696a542eaa61e37045a0b9dd671ee2102bc000000000000000000000000000000001619f340ac11abf2531d44c3a5a6ba0ffbdeee769be768edb86bd4d0eb65293aa8166af3cd5e863f03e7cd4585d5f2d20000000000000000000000000000000012d57a6eb9d4e8eccf0a4827a1b4d88c482b0cd59340ecac9c4444275cf8e09168d4b399538978c4fb77dabaf6a3edbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008882034cecccdbd8c4f2f8287d3496c4d6b1e31042ac8cb0c0c0beda3107a933d8f630607970abebb6c32413bbae0cd0000000000000000000000000000000017f66da5b28f21c8d29d8cef1c84ec6b66c387c5bbe86201526f61e6f4cda43d949c0f291f2ef6e5ad407d92c2649dfb000000000000000000000000000000000d5e6c4bd580f345930e39da587fe206dac9d96c0708b7abcf80bbbe4ee999e139c5b25964946e65f4d20aee7381ee9f0000000000000000000000000000000014d246f0c7f806861f890f1466b4e733804f2d647a133cb1bca2a41fcb0fd56192f5cfdd19a62fe8a14ec05aa184a4111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000002e2f0a92817ef3c58396993b0e467c5dd2840182da56ae69dd7c435491b3e8a57b5b092ae2189281462baa6c02577440000000000000000000000000000000018788afacecd0e2f5907d81074a97bbc4f293776b5ffc54c89d4b3aac5e4b20e68b2d3ec220ef42ec406ae1c18090d6e0000000000000000000000000000000017638dc3893ba2a66fc9e0f3055a3a5d44d36678a4e1a6d3475b7e58eb8a911b28feb1ec42a669bbe3b2efc3b669205c0000000000000000000000000000000015709e5378f7029bae3df1be83e7df9d072ac90783fdca4cd655e21f8e1e027ef06e36a49f7045230906f0fdd0619679", "Name": "g2msm-4-jwasinger", - "Gas": 115380, + "Gas": 79560, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000264b8e6903cde9b853b7f6d147c3a3cafc37dce033b2fabebf812aabb024b7ddb479b347cc703667abf147622cc717900000000000000000000000000000000007fc8ca5e0cbd126c27bcdb89f6017af6e527368b74562dd56fddc36efdb890a8b6ce76cadd2ef90170e4f56f3b1dea00000000000000000000000000000000148a5a728d7cc081384160f8dc35fc9cf9df8700759d619db548991924eb2f5e794e6ac1947fafc0f00a3126f62c882600000000000000000000000000000000015ee82faf674f3de7da345e57145ad8b1c0264ed15e7c47fe73719759127024bab8ed56dc63180ebfb325bc936c81f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c77818e372824dc38d94210d10f68b3a1c09c05e95a85f9e37e2d66acc7d20e79c786d51f586a20228dddf893ff1f0000000000000000000000000000000000334b81064fdf6aa89b1abfd0668639c59cd953d5d056c37d80eb997ae7477928d82164c084bc191af7f266b1b6a499a000000000000000000000000000000000fe8cb86e2cf5d5f61d2a4a928e3eea222d6d04eed35eccfaa86ea7ff7367766622bc95b2b38f82d6022fb1e8d51e0090000000000000000000000000000000011a3ef26f6c283c089b11c3f4603e465f122e7e46141e8370435431faaecfdded7c818d6da4055db864698b52044abe41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076a1bae6858691e77777cb47d827a392f013fc3d2e851a474a0cfbba57f722f8832f1346193a93555ea2d43e0620282000000000000000000000000000000001485e7ab4a1c4e92a31614ee3ecc32baeda2bc405bdacc916ed1476f1909642a0831f6e31ab6df57dc071dd1ac09bdbd0000000000000000000000000000000004551a37a27f0e8bf915f4d5e93f38a349b4b652f9a603fac21b62668f62d1c018b5f614c0f14ff3462f24e1d60a3a22000000000000000000000000000000001144381bf3e4e6a1e6774e7b8cc596a98f815a56eea4f4e264181d39edf75d903efa2dd7563fadd6ad8c3021b8c9e5f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011083556bd3f8638dad279a2cea30ee99e9cf7a5f0a074be6c475df455618ddaac84b928d1453edfef55917c505b31b700000000000000000000000000000000153239eca7f451fa384fb7becf009fd5b7bd2ca95fd23a1c42c9b0f3e55588f31cf2f7c20acda746243e61a6a68acc7600000000000000000000000000000000021c3ba5d1b1959f92d48acaa7bb40780dc73e5890bd292bfe052bdac67463f78a466940e9fc4445809aeadb138941be000000000000000000000000000000000e7b12ccd28eb4c20cde041035e6045ec6e0dfee905a90efa0a0e09eb7953552427e5601511b3adb19810bbdb96ebede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c8676b23e1ec143a3f7e0e790cae44a35d43d271380c0a72f5366cb74945f4e15ae03bd70600e1573ad44ac0b677350000000000000000000000000000000000fbb98e64634c44fa8637a2b88196ae9e781e148ae763fb46a54acd104b81ebe600fa38471378cf8d8ee975ad41aa8f000000000000000000000000000000000184994efaca59e5fc9061029a072994e6a4cbdc5c060f890cf630c1212bc4b13e79b2f67ccc1a2f7a1ef1302689223500000000000000000000000000000000068bc7e51eed6639bcd29da806227dc36c635055806135516aa6e497d52263fc130ab70982268213a19515a0d378723c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000b9622dd89ed150d7644fb3d6388bcaac3c1b83f3f14f0f0b41fdd9b5cdf3cb88dafae1dc7f093ac40324001ad6b4feb000000000000000000000000000000000710b44eb17a94c7374e7d1ca6ebdccdd09ef9e2e6a04ad1ede1676961c3681cdf8926e6b1e9ff124abf1441b72822830000000000000000000000000000000001cd993e8997fe74746cbb2495236c2f1cb60654832505ccaf3dfd4eda333f86208cac0d47afd11e3684a15e45dee13c0000000000000000000000000000000000401204a6fad559d9f80bdb5e88255368f12d8155466aff06aff9ce61375d9138acc6fce5ba43ca18a8bc67dbd71f0a", "Name": "g2msm-5-jwasinger", - "Gas": 133650, + "Gas": 96187, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003c28b0e784c0bb244f4aeb7b7a50c5b19fdab2231e83303894c16f96d14a58e913ea14082a3e7090fa02ab805fc8201000000000000000000000000000000000a1b92586d69dce9343ef029dae1adf641321ca3a1735eea98c334830c5c97206572584c01756e3224a821ac0da31a59000000000000000000000000000000001179e11173afc532d2535ed888fe9574fec8cc0973ea480ee7198d90b62253861bedb42ab61df556f0a96f063cc3f672000000000000000000000000000000000014081b26b7059c71dab11feb84942dcaa645501bb45c54ec46bc9d0f0daeaff5718149c26eed1a2586b840de48cf4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e8e05fc7786caf9eb246b98ad0db1ad087c64295c644d8d7b3664b062df59196ee502573c897ddc9f5f802da810c610000000000000000000000000000000010f3716b42ace8817fa1598b006ee09ba2b722572778acd13f09aa338a046c90183f44cfda57f279815e2547b4105096000000000000000000000000000000000f7b22389505f89531fb39dcd5a19305907df6bd07f838d5e5df07deaae5f4690d5a80fd0e31d2b00da582c09b318d36000000000000000000000000000000000fda566ba950611732fa913093ed4de14d9ebe7d464c3ab9d3e454982dd73d061fc514d718db01e1f23a21e8820b5b991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb6f7e4922d351180e1837f120ae4e24ee16b25319c6392a1b0760b399cb9324ce32322797292e10e87cedea04230ee000000000000000000000000000000000c16431b689d0352afea68f471810267c7a150f37f023d1e5fa99a1ffeafd52b6349b110fd9034ee1757f6cb62653fda000000000000000000000000000000000cb68b09f6b8664c4c7ea111ba4ecf215ce0ba778fd21e26080b754ce3e7dacfaa1f404e270c66a6563423a731d21c560000000000000000000000000000000016c851bd4c7c31d026dcbffce810ef65f519e047496729d853f61f48800a0057cc7b19c62c7edda4da979334cfd94fd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122d96db38649a223d3934173c89879709b9fedba7deda40755731b4e6439942dfcdb3b1ccad148bee73e333558e9a3f000000000000000000000000000000000602cfc2fa34b92bdb6ae12abfc12446a076924fa685a0b0a3425019c087c9bcdcaec7b7072348fb8714afeb9b9cf919000000000000000000000000000000000341350b4b583a014871ddd15cb1667724ada0515a4eaece6692290b780504cd92a3fee6c90d6170ecbf2d5858470eee00000000000000000000000000000000141a45f966ca47d33f352480b9e1cdf5aa3e64d8c64a287ad29dde9a00a2421e7d604034614b90089a4e7a98daf7c3871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010605c2ddad43cc6960723b6509bd8c69aa0b92e886640bdeb592d34eec39fed15595a518f08c0ab87670d7fd75cb15c0000000000000000000000000000000011163e5f6702fe70d4b40aa76dd37352a09d5a8771fbc891d469dc3a3c8be59824a853f226ba80d09861a757451af3e7000000000000000000000000000000001184335a7f4c179727827670e21279bb5ae3e95eca61bd73e4324dd29a2c5eee159341d2bcd8aecd2aa3595718bf51690000000000000000000000000000000000fc8b8c9304f1512a9c8106bf807f8f7503b4954e9e30ad6aa1623349e59bc5fede56d5f1b6136d212c6c8147ce9f6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011ad0b137b369e1e03de266fe9a50fd643a5725ab49bd14c5a35ac918dd022354dc138538018f2096ec129104925273000000000000000000000000000000000152b72b88b7ef02ea5131b256a411cd1775ab63e1d1bdf6ba29ca03e532a964d407fb6149b11c12db0a6fdf371691120000000000000000000000000000000012f4cb12482d070c03451d5beb9f01dc3d9c4aebe5a6d33d730e1a3b1259e7fb038f6d34f8a377408eb76d4744a4489100000000000000000000000000000000182eaf77de135051f31fb43dfc13450173983628fc956ad82140b22ec8b8f15441a526c90d796a3b64fed0592f0276291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000012bdcc0b1abd50c9389903ded99facce7ba0675a2101428f8d2632cc67304c07cddab92beaf5ec72605718604ad1bc8e000000000000000000000000000000000d489d7255979de8ce345cb2187cd2ed0308bbc3ce3d567365829cd99394edc3c77db561b1daccb9744338496cb8ca6d000000000000000000000000000000000da9c3d2e7cc60a2b2e39dd3ccf2f9552dee00f9bb4b578fa99c0c4042b1bb1735f3dea8d421c7e1c05450050fcaa274000000000000000000000000000000000d7a574aa832a8e388180ce22d1de2e1e22e5dc475f7142a6ea91dbacdc88577e2d4e14fce96465c6a152a878ac6eaad", "Name": "g2msm-6-jwasinger", - "Gas": 147690, + "Gas": 112320, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001568b92db6295c37f458af466eae1c494332a6980a29076bbdd3307848ad30e4fdbb2d8af58c4748763c28f0729ce4e30000000000000000000000000000000012d5925beef25addd1cf1b698126ab62b315acd1f4deb017ee0d04d14d1f76c78838b3dde1a09e8b2acb22d8857d84810000000000000000000000000000000010f7748e4119b43556445137ce528ab783c2fc1c8760c0686a17965bab9662e9808704016e6924fe2c92cb6c3794274200000000000000000000000000000000151a2661adfeb23f6e9f00a0b6a0f74b79cda8eee6e7e146901934986613dc50127d6b59a161f3b0f522d65957a3494d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009712947b359bcd80ef6cbd93e00a64f77a00a85d8884c029ad492f04bfcc644f619e1e1b72aaed4843f3529ff36c699000000000000000000000000000000001945ced21239e584a0387da586bfee54b780691d2fcab64dccf34d71501e0d8d91e3581ff5194a99bdf58a149f31e84f000000000000000000000000000000000aa17236fc61c15b162505b8890e51a535cdd3d55421fa770eee997e0321fdbb0ddb7fa8a0b3854440fa3c42904f9a81000000000000000000000000000000000739c89fe7ac697a0f0204ca6ec6e809aa838524de3c1c3021c0d19e1f04e988d058941d43253b836de5e783aacd7e351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fbbdc17a4f5cb310b2cd0687036a4f968e72cb1f017b055c89989eee9e9e2e91db5ff84186e217346855abce33d990000000000000000000000000000000000f6eb30723f5975f9a79541332ad9a5e153e27a5c677f32b67c19713b8c6e347875e1f5e5b9542cde5eee0f66002526a0000000000000000000000000000000008ddf6c1f70c8f94643f85dca5afb344862a93ee5add41625861734848f0e3495a9dc1cb2c8c2d28aef48f12f68eac4200000000000000000000000000000000120afe3fde19116c36085a2d772af34e5499ca3eafc2f6fd6e4d58f16c1bdc895cf4e203155bfcea1c8b35e7b64dcd251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193369de554724ccd465adbb18f150f21d6def7a3d29f0a14407d9f5a8bb43b680b76cbf2904beb9668b55006aca587c000000000000000000000000000000001920d5d4077a24827c328dd5e8f4c9b77d47d3f1e22b33025fd48062ceb2d2cba18dbfe284d3347c9f7410a13f2e0d670000000000000000000000000000000006d5f676a9122459516b3b0dd88c9ae1ce682e81989a8aafa5af304d65c84db0e529c13fc1a81c09d80685af94230f3b0000000000000000000000000000000012bffa58dca487a6d8db92417ce6a56abc5ef22679533f9cba295e782bb8fb6cf08b342dc69ff44d69544ae4583938401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021ef3b8290f8b747896421c775add14710260fadbbb7c9c9cef6fcf94b9284b37601adad248f3e9671e380b7176c7a9000000000000000000000000000000000b4de709f6b68efd9f9b2d4a0d4bebdb7d3949c2abcaab2c55b296ce9bc7794cafddee83d96fd18c577f92442bb31aed000000000000000000000000000000000827ef6bbcc4081fdf0f58ad097a0448749f2fa50c7194102dff18f1ad55306ba9ba7bebf20790e38e8353517d48a3b200000000000000000000000000000000094ea63e52ff40098c2fe212edc93a1f81bdf804da9ea0f930c79d733f3b100414523c8149faf3fd8b90b133010be1561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199c117f57283df4e23d9e75d150037f67e48add03fa07b474b2ee15f4d9061258118f135471652506c2a4a20ac3ae4b000000000000000000000000000000000777bd3743b8e43955ba3f62e1f27c2df72ff787fbd69a25841b413c2b33f213212284833be11af2e29c6cd7b5d4f6210000000000000000000000000000000009e129f8c61bf518bbdecb3c87d8f82b8fb51c5644e9bade9f83cfb09e74ee764000df01f8be72cdbf7875fd23db803000000000000000000000000000000000109900bf0b6b0a6187b3f57db279f34973d6d1c7bd8e0bb15c27154ee6262d0993f86a9e0738954a6bf6fbf4ac54b4fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084ac228ac522f5346dcf9c904724827874bd4fa988f9335bfd034c0b4266bd8e3f038ebde74bcae289e25a20f208cea00000000000000000000000000000000157daaab922bd0f73d1d939360c69f11f06b4d2e08d6268df2521c2a28cf27d9b2f361d5051c0f6c6d10796a9210396d0000000000000000000000000000000002c39192261482337d32fab6a97865eb32d10f04401c760f6ff8da444c25219793977a3f9bb7a64516b407b07c38259400000000000000000000000000000000079ab4c19fb32a14516e55048ae47e3b472925fba7e0e14da9288c618b5160cb58cf387c859169bed3b7adbc957d2bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000012a89aaa5ca532374c26dd42588c6aba4b2257208fd39226001a462216f36ba62565ffa427706c194c1936895b79fbef0000000000000000000000000000000008b26eee687de31a2447034696aaba5246d903c5e91b6e41a685ea823cb47ea4435c2ea656613b60a0a9bbab3ed3900f000000000000000000000000000000000eb4e9259adee74de0f091d201e6ebc39ad57cbeb007920fd7b32d1e2191be06735845325ae194c2c74b9a20bf07427300000000000000000000000000000000044bb10e1908f5779587f03ed1475cb85667c472b147c216ef297f240ae8b3c0acc21e8ad6f556badc3a78377d5a6d4f", "Name": "g2msm-7-jwasinger", - "Gas": 157500, + "Gas": 127890, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000575ea1f8933e5f55fc5ccad48f195a0da35ff7ca84b8b483fdfc5ab3e4acb73f1074444d43e8c49cb5c555924f2e93700000000000000000000000000000000004cad6b13c7f09505f16e16712180063285918b1219bb9573413ea1d145ff9ec99601d6e7fe95af6edae55b0fc66c4600000000000000000000000000000000093e948124e2f221072f3711a52acba600f1f91d45ae41df55779b8f1f800e83bfecae3208dbf820259dc1ee76f747a900000000000000000000000000000000139a5f3f8ff4441750f4cb325cf45c9fdeea444aea56ca5c9c7e18f249c91bd8a7d893e53df72237a10f3e0048855ad21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045595c3980dd7a591051aa17815635cd625aeaf13ad30bdb5b034d4068945f88645d58ad79aa9781c1b86dd8f022862000000000000000000000000000000000cdb542b7c6645599d126284ef1a2b2e58e1b2054bc676db8ae97f623e2ccf37bdb02d8b6e2fcf2d6ea04de12256469b00000000000000000000000000000000014e1ef7d3a85eec28a763ad5d5b70e4a391f24cca27cc704be084325f1e2f6703e6dc670e5d5a6ea1040fc77ae9324b000000000000000000000000000000001013fa3ffe53d4f310d14928e8c71f946f5b28f8c7b318808c7b352f0e95cd2818590bb8e9512afae75dbdb72dbbf96b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d8b19883c03b99c6362c6dcce333ee1d22255e0bcd0568c0755b60c63243062b9dc587e675b5f5527e05ba8c7a02890000000000000000000000000000000018ecd7994e99a01f1b6fea527c9d3e9ddb64872bc519343853bfbcc0de8ca36c64f8d7f797a04aefb614cf58ad1b812f000000000000000000000000000000000280de32de8d34b3e0a2e81383d0e4b8dfed65bd5c7d260112d6bcf3301dbf4ce8a86cc705c03df34b1e30d7ac8a7e540000000000000000000000000000000019cae4d6a686fb66981a69b4c10e3f991a74b2857b685d396075a97e639874998675c0ad274067c6851cba90653440541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fd66351e373bdbb9436099988f4f27f65381089396ecc641c2daba14b0c058e10de17d7d5a9b73345dcfd47738c4400000000000000000000000000000000012079fbcab20c102f74f72bf8de614bc4f8f995fb70ac5184c3c3b465533708720917b6600d92728a77a6ade55f5ff3e000000000000000000000000000000000a45023e39efa97008fd99c0cd05e05022ad007fc166938f5a5214194603f7b4302d675402cc1c2f56532c1011d91c910000000000000000000000000000000019a01ad236949b0b09037538063d6915021131892125383ba16d2f27837df5de0ec68f413afa9cef1c5185525326a8761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152600e1bbdd1c1b39f31bccffffbeb8d555b4c36372f1fed0d76ed3fb0ee7ac3e1868acb15e235b56522b51f71511900000000000000000000000000000000003c7e41c5928906e5ad26bd4bcfb575321cc1461126faed835b1cb578cd1b52ea83eb1d9abdf7141cb0ebbf5031968970000000000000000000000000000000005ce5b2e43f16380a7cf3a5a61f128800118784f3d27f4d8b525c51704285c3c93ff05c1a39f9ab272649163f138abb00000000000000000000000000000000011ba10720e35c7d9c67c3b86e9fabf64ffd82939e27d5c747890691cc49547a5153e5c32b63f8515d47daf2f67888e501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e19a37aa40fa653a1dec08e719d27dc138732c5f6f7499b852ab3a1625e372d1249d5493f404eed1bf9945dd64113b3000000000000000000000000000000000269294c8fb03e274b3b14f9cda3ffab5051542d71021f21d1f37266ad528ebc720c27024c97d6bfb7662a2d4081ce1f000000000000000000000000000000000941fd8e25bdb097fa74d5a4b6b2b7d067d56d93ada09e1c8565961747b3cb1a89822381a6ce568627aad5826de57d3c0000000000000000000000000000000008327f9bf13158e2ea8b03eaa2ce779fd3b326873dd9e081751c0eb3e9391015685d363921018943918370552d4d4f991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001108d1465cbffaba39c656b0dcd6e6b57503de65de2b78e17928d85c491bc6e5e52a59b1c6c1a4ba7ba0f19d784403f30000000000000000000000000000000009f09f6929e664fb8478688c1a7521e775419385e4fc2b7f0753164bc5ca688a6b258fcc42adf450959748fe606784ed000000000000000000000000000000000e2e60f3bc28a0d2b2304f46bea5fed3c46c9b7c8feef3432e40fc3749159b076f25116ba508b0fbc3e522d2baf216ab0000000000000000000000000000000015306378e771b076dde6587595cc9034f424d63cb21805d45cb8953fe06141048f8f6d7a983e89d329ab9a6deffc51971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e8b7adbe0527ebe07a97e53603f72ded2f53b50e8ec63849c858119cea23be3517227579e73c68fcfbd631663115fd0000000000000000000000000000000003de60f3e9eaa460637b693daa0aba0b7a819d5084bd9bcd5714eeca0538ea5f737756581d9eb3787d1d54f8fad2655600000000000000000000000000000000128acb8acd9be6207516a91e0a33e8489ea5b23f8edde083313deda2efeab74d0b3e6a38cf0d9d3b770950fdb4465e270000000000000000000000000000000014ebc2a17b6aab8264e824e70fb8748ea812e7ea7ece5b14f4fcabf51ae492b3c0618d309ca5aeec168b84bcb6028d711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000a8bad24149f85c641f9ece6e047ef5814be0fb078e11df9608325f836737d58995b8b6e616dacd1b7c978532e0880d0000000000000000000000000000000001153ef4fe4278ad03c1a435b15aed7f3ff6c1df8c630e5670337dce06a6c55a1a53c52ac1257d96799449a04b4fcd9ed000000000000000000000000000000000b61e5f1e81c7a07b9657133c5aa033e812494ed2b9bc54ff6f5bd7c87955fdac77aebc6275764c974978b38bde1e21a0000000000000000000000000000000001e02d5a5ca3334a2015db20a933fda95e1fffc018193ed0b8c8548bcdf6b83b2055831f523e3826ac74d1a7317b14f9", "Name": "g2msm-8-jwasinger", - "Gas": 163080, + "Gas": 143280, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001621f0d35f31fcce74617ec24a1482ad75ba0789b0fdf77a88c22dd1cecb4de349af00f7aae786d58f961b148260ed580000000000000000000000000000000009b09b16a22c62519d577601b8bd1290da4203f07ccb2d7b8aaa3b871d089362cd6ce1e702b9337b7c9723c0526fee9f0000000000000000000000000000000009f39d9b34bb0146fa90d238efeb6c7f84b077fd84649169fcc279d1863e35a0b9b8f9e78d41180dbb017b718f10a73500000000000000000000000000000000190924985457ed18019749c2203c853d90ccafdafdc0daf60a0efbba8b8fa3483a3091da0d082075a579c6de85f55c0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165a09a80c33f5330bc74850e219e0e596eb0775555c4e60a52ef6ed1685b4696af225f179317a0cb9b34e153f41878f000000000000000000000000000000000edb9f192d3a29fcbf0aa47dd7509da9e1cc8157f679e517a20b75d2201b4cd33c77c2143134558ecc4a18621e93a902000000000000000000000000000000000f0a96e6791eb2a3ff16e24841f281b9a97867ab50152d91cd231003ca27b4ae619ad50c6bc66ae27c87387355eed1910000000000000000000000000000000015110f325518a5209e6a1af8add3fa7d6f049c3fc39e5d1b2b0a875cbb3a9f5e28cc1c2f4dba0eb13a28f2e90d3443d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e4704c71440c2f02173335834d75420e81575e6d48ea22d1f98468e5a38ac437180a2637175040c5756c9aeb276c7f000000000000000000000000000000000f6567cae1dc0099851c488b5021c1ae1abb89c9a2f4e7cf43697f2028c70fdd03bd35ae85a318a4b54e881a22ef64dc000000000000000000000000000000000514714b7ca31130e691ec29c263e97ab07df083962929bcfa66b7f924360ad02700fa34f28774a452eac57b995fd82300000000000000000000000000000000025d5913fc4854ab584998dcc740c98ae35f96246f3b19970bc2e17dc417f57b969fa741cbe7e667556a3ee1d57261311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a002aef2af04d7c6d7ac63fb6edb72bb234cbf632d74d43d9c5f231084a0908192f265001f22d0aa5f5129bfb4d69200000000000000000000000000000000002d285f983183ce7e6de746da4d1d2f1513afafba16b813078105d06db6a096dfc325d465998473e86b05ebc2c01262a0000000000000000000000000000000006ef7f5be82136df386e66920d7d9e8009a0b39092f03c6c43e2393f08f8bd95db151f45bb15cf62883e580993aea81e0000000000000000000000000000000016c73809dd371e997a90bd9cb75b439bd93ebb6865ee31b0864fe4f45b79a7a20102035bf5044bf67803b8e7684b16501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059957fd17f908efb9dc4a69e50d35df422585e2d3fd3d47155b87cc5d8b083631fd735926cb74d5c610f20822619d7e000000000000000000000000000000000da4b42060d9a12441735659893d5c31d5b94b5e9afc85a7947a82fab47ce90f4c598b29a27c662e126331d7dd71577100000000000000000000000000000000003447ec2ab21ade701eddc7a8e9605334f45aac2c9f45d1bfc4608322fe175e1f4d70764cad5f339d91ff818c0667c300000000000000000000000000000000060993a10a1856cf73b64bbdc1ad2f0cd9ffbc6e97e515afb0c14fb8b6a44d7407137bdb17d877785e893f286a8f27dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3326aee61077d4a020721754ee581235c8fe821463b3127bace73e6e4270033badd7858fc7400fa8fec9275d5683420000000000000000000000000000000007499936b653675f6b60acdffe500856c645d1d2c57f71012c188e6fc67d045f12bcced5f8af389c00d6dadb59d019af0000000000000000000000000000000014521e78a2ed57d798a990da4a62c5ca0f375aea24d47001676e59c2e089cecc84aaaff6d6a4d8718c098382f678c0200000000000000000000000000000000016410b170eccc178224c4308cdbc26653c7e511a4e98ebc8ab15c34b9dbdf9fe81237614df77ba59ea3fe88dfb4971841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000104216a309450ed821c26fdbc0b3b3617dc865f20969ed176c2409a7ed4a3c3c7f45c28e740c3fe06d61ead435a750300000000000000000000000000000000080ace8581134aa7c459826ef51f6e75f3a9562609fdd525f0f2d7474d8c77c1ff5a8258aa4e1a5b3a26335caf3e1ba600000000000000000000000000000000084b19b0de645043b101f6bf675b89d3d015a45ebd50312a0b4c5b5ad7221b7c1d513cc809262e5aa7b2b3b6807668c3000000000000000000000000000000000edd873e1689a60b3d0723aa3250f438c8fb96d74358e692a2d394d5cd9f25c84a125faae13fa3636dc8fa1da197f4171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001947dadc31b975d3c5f91d8b95a43644da6420a3edc85abbc26ece40832d94ad67347a9af59e9a663c4cde3534552529000000000000000000000000000000000cf895c88df23ae1d14a37e00e4bfdb051ffee35083af4c7af2e3a7e796bc0077db6cba5a9ca07773db9ab4d3e1b5ffa00000000000000000000000000000000156ccb455eb3272ea3a1b1081b83055746703cff0eeb34805c5b3989a4acdbef2c4fa55d1721e14eb25e717e9c2c24ba00000000000000000000000000000000189d0ee948b73dba11d65b5a88389c97a9720ed47181f0d6d1e2aade537b4f75c779c7a7c33045d4770857998d77f7ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dfc85943c1e0e44fe73bbd1c3a196d8ebe52dec5f9b33e96f9bfac159533b6dec84ed5529064c72261f9511664f21400000000000000000000000000000000184dc627dd2bd64c20a3399cd92242d177d1b0603b61c85e312ebddd2d58c1360fb893ffbd60db3511345c2c9e59bc380000000000000000000000000000000018370f49f7759cb978ca6313dbc18e4fb9dfd2f1f7194fa07632300e7d6163429a1f69a69eceae4d80a2eece38c9dec90000000000000000000000000000000018fb7d2608372060e6bea3c84650c3242d7590fb26e3d919bbf1a79f5174ec143c879a6df46fabea0300f9cc9394a1601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000000f1ed819d666836c267529dc11afcc81e44e83a4a503879c81a835eeb43468d229d3d6ad210e8c1cc89edb6561bde400000000000000000000000000000000007bf57030ad51243c4da76e66bef2024c0200d2b8a735975946a2086074393748269b6359494a12a98993313ad1529dd000000000000000000000000000000000e8e004b23ed9319be41f44ec4d58b2dc17daa7bf50f51eded2b5603eaa5057ddcca559893e9936969970840b1c3de10000000000000000000000000000000000674ba86e7993e9c56d309de3a5df99f0fffde0e991acb8f1222858b2635d073da8799134498e765d9f8a5638dffc64b", "Name": "g2msm-9-jwasinger", - "Gas": 177390, + "Gas": 158355, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000be25c02ea5c498e387e747aa2e976363d1d0e846673f62e596b964bdaeb5f569276e4a45390ecf59acdeea7f409e3e000000000000000000000000000000001438169d876ee4d793c8e19aeeeab14ae06638be9cbcbe2ade830d8e42afe598c59e762eb8d2d68313ae5595f953002e000000000000000000000000000000000eb493df804325610ea6350d7ee9f46ba32c2d0e7e8bb7f7fd2c14f3e8b912588522fd98fd6f5f1de4ed4002632591300000000000000000000000000000000001a6e862b2f27f1914bba24e3cbb1312695207d1c9fc70d1b144903e371c7edb941881455730097e2253fd1d76122f8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000022fdb3e6638255f2d7289f6e3a0407fba28fcd8d4e8cbf04fff7a9bf4adf229c59bb59bec91c6c379ca348d107ac3b00000000000000000000000000000000084645b242d56929a911c9e3867248b1bf4f0c105f7053345e15b181fe72b7c819575caff968e3b53d9c2432fcc2c8bc000000000000000000000000000000000e4cd1027858b45d04b67ea133382331e6e328aabd2b0a68ccdbc6c9c6140ddefffc9a0e79b2b84c9d17ebc5521aeeaf0000000000000000000000000000000008756525a1e56e20eafa20d8beec1769cd84ca378ad81c24015565c8f9b7f371b48254ab9aa6d3ac02700b772cac49b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096f7a561f19ae8c02c2a3caa1e1d2ecac7a4c8b7f6bc77cbbdd01bc7978ef5ddf1505228cacb5093cf1cd8b0a8ee7c2000000000000000000000000000000000f57b593530d2d8df3f492697f5d80174f170f286833e43bbbc5001356b4b24a5e61d9a43672b0ac8673f781e33b47d9000000000000000000000000000000000b8229376c3daef017c82e8dd090ca268c154b8e8a8a77ce490eb4607621c7fff3d6cc26eeaea2f52fb4e4417fa1c7f5000000000000000000000000000000000458fe40dbca2d845a428c785707a7a4ec05b8731cd064e01a4e138df58aa13ad7e16cc2a87f48412ee2a12b191ba7a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188abb04cd4e91731b30688f8f1a550bc35aa195859549cf505ac4d6fd44f3f38c62ac7adc2d2507fb91112134a98fc40000000000000000000000000000000007dcc5f1a5b6c8f1c27e36195a149755760860782d2da5a865ed51993e7ab601dbdbc1e7c5669cb28fb33a2b221be109000000000000000000000000000000000c6e5945dc170e0885cb29f8fbfc8f597e4a0a5e9bf556065286ae0fb950b9685755bfbffd8b4d0c63fe2d8ae885443d0000000000000000000000000000000017fc476b3af209c55d284dfce74979fdf09e6a07546c76a7ddd0c5c3eb01018a512dea01c1802e76925a882ec9cce1531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7a6f882f9025c37148cce592b2761724ddd51c2489749bf64613cf5723eea93ec37f3c594a814e894607fa509516000000000000000000000000000000000000f4a306f58d80368c6c0bf76a53ded3da11073233b1388b744d760fcf5bfba1e13e509a379fb029e76d794d462abd010000000000000000000000000000000009599f6e3aa840698aeffff5930b5c60a94e3073e9585bfbc8d981695ee9267509715cd1333b0c67ebe62d18c1740bf2000000000000000000000000000000000230ef7858576514567ce6256b9887d9f3d29d8b25db893321f1ecf140349078ee1b61b5efe7cdd751dd3c5e9b8dd7a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad1aa5f390dcaf34f7763fe580a04bb3469b2aed70b63daa31ab223239a44ad694889235d7b540b6b8abc7ac78fd62b0000000000000000000000000000000005694cc9a0079ea096c12a177727df08ad58b93173efb09a1eb4876638b43a55c946b71e490e6c80f836f37a0b04991b000000000000000000000000000000000ed0fe4777908b1362ade390d97e6871450ee7d9a972503a4b7dab054d5cf6a5d4b5ffcdef05fa5a42413adc4e523a5e000000000000000000000000000000000300ae41ebbdb6968ba574d7495d160d72c66e94d2ff8c2ceb756f6225e28184424a0d0dd1255ea0dea760a1630c76561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000811d99bae042fdf2be044e7b456ba056a8338accd05d32275c7c04d52400164e1851c7c202ffe6470adf88e7c86228c00000000000000000000000000000000010f98d0abe29f7a7299aea362f135dd1cb76a40efea8b4bcce060a11b52ad432c196c6279624ce6bf6927a0938f57e200000000000000000000000000000000001a87362c2adb0d7e90b9bfb08ebbc8518830020cca53c72035b82bfc08ccd618ffd00c368cc3bfab9b17667c6ccc4700000000000000000000000000000000116bc061d571eb4a105f29fcc990fae9c350cb46747cc261124271ea1f7eb2c80d8e0daf70eb1550563197f06239bbc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016faeaa0b84257f18bb5bc8be672bc6d48d863acd8de48131aec15f21be9941775b983e20ef06675ea48d434f6c7a3c7000000000000000000000000000000001704979d11998af752d1633420809ce7a5276dcc3b12f2d9b775f76852ae804c05f3a859f872a9c3e0ed40622fafe405000000000000000000000000000000000ba589bb52347b7ee22979cb1a66d0123f438fed02c91fb969c8857792dae814ba15f042e57761efdb9efe9e06b409dc000000000000000000000000000000001485529f22b2b852870bd7d7b949bce855cb39331f0e18838363cef8593c26108f3614e73be65ce7de4beb02d940c3431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009239584f9b79df4953f77774ad8045ed80cb9d3bf3c898c35cc8bce486749cad2f00859f16cd82d368d68b5242a217c00000000000000000000000000000000142af6949adde4ae7a4e64b69e616cfacb0689f19c7d61b89bd1a9ad9df9ece9c313432b526213b4d1628fd087f4685a0000000000000000000000000000000017b56b96cb323797ba88f725fed7ebb1fd6b77c51af559f9e549a10085c97f0945791699385e0b7231c889c9bb58e92a000000000000000000000000000000001327dc36c3fb1b15b04c379af912558d9362789e390cc7a95b9a6ac9e34740300d8c5f3c06c92ca0ea56cd00c23fc2ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004a27b190ee24457764c53a326aefe801941444b8ae154afe4e767fb02b8836c00080a3c55308bab4f999be28beaf310000000000000000000000000000000001c6c3af694bc0c4fac3c2f57b3b4c16dfce24a4617c231dfbcd5ad5b01c042de3938828b8db14039865f253b33a0ccc0000000000000000000000000000000015b7b2777d09bc0d839b18d0faf666806110d5680c0f5e15963616a0a5d44355844ca88ab40e9bdb3f413b6ae40cee6d0000000000000000000000000000000005417df517082cc414895ea608a120915a89617e5a27998bb0d84c3d2da6a3092635f7a02e83164c653a0071506afeb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000001774b6bf3891cbded4214b6bc9ee92a87909fd0a40dc3c30bac5f08ab53d186b3ed644ed825c1e7e881d25fdbab221d5000000000000000000000000000000001731dcf5e3abe3f72903661ed31dd8f8e66d9fa415bdf54afac1082ef4d21ea78bb7e05eac2736805a8afc73172bfc5c0000000000000000000000000000000006be2608759b08776e344d3fe093f0c04f963ec35f01cc9019aa5e9e4a7593a9f42ae8d768d60b1cdd1055ebc53d9284000000000000000000000000000000000a55f60914e2e99baa61758d43a6e7fbb499265d2603b5f2458952c596e7dd97588919aba8a7707e20d9e0228497be61", "Name": "g2msm-10-jwasinger", - "Gas": 190350, + "Gas": 173250, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000170ba2b9c5b83714330cf91b901672c659c95ff93b21c7007aed1fbb93097d096c20a96187ab3e79295801a156632f77000000000000000000000000000000001910f1a4066a17511fba37247cee3eb00569302016e74ce655c52a4c6b5fd571d463907d901f6773e77c6534ee6234ae00000000000000000000000000000000152c08b790bbaf46067df8f5def65e2d045e3695845dd7729acec5ee3860bf609197885500861c95834ebc3e7d96184c000000000000000000000000000000000200b959936e0660fbe3453dce595f686fa297cf21d558efe485927ca636e93f9a0bea0afd730ce6d9820bca8d2cf4d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000030e531fa2d3ce4d87b1890c712d881e54e22779f1b7db00d806f623508d5a997a569a00c32c5af12cd32f6eef89b97000000000000000000000000000000000c281190700084d7a2c3678d9ae67bacefd2ae7e7e43f8bb3e15d684c2381f4f4e6e1df446566e00fd9c177df60582520000000000000000000000000000000013595138de00cb7cc7f1df4821921cb2078a902d293d625c3e156e7f0d3b3a3763ee2451a11944829cd18b7b791ce99e000000000000000000000000000000000faefd77293fa9fb19f6ce5b55fd7f1b7c2de2cff08a0176f4f44423a63b4454c39aca4dc7a10b7d558fd951211b6b6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfb5f495968ab1eab77e9a42dccfe5886e81e20aedb73ec3ca106fa75886675a5e918cd01b6b1f0ccbdfd7993cb61a40000000000000000000000000000000015f89521b26cba44dcc585f464728a0556b11fad52bddb563734fc1cb56514bf3279dcac05b87fd105d615be9ef0d0d40000000000000000000000000000000012cfd925e29d9a8163b2c1b609d1fcba42f1432bf4d222e570bfface3d746d1048ce64a4c07e4eee1280d6436bf37a70000000000000000000000000000000000f1a40935cc6777d51ec6c422a0cc431be6de885f594013d9c2a7ca52f8f0dfcdc85d48e354aa37c533df55abc6c8dab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a16837140505bc33f7a508f6bc2a60f434559bff7f8ddd073baf74352c95ad35c530b1239b46a6be5d8571023b4c85e00000000000000000000000000000000088a27dcf4cc2e462c42fb38cff1b9e57ddbaced3d20c687263bdd96931bc5906afea98bb04f5afc509dadb839fa3c1c000000000000000000000000000000000a54940cfd303d07d2c56a79e907eef6a78b7c0ec3ed2f69f461d5d5e04d72008ac484bbfb80300b54adb4ce6dc97d3a0000000000000000000000000000000001dcfbd3af189e55c284fc3ececcc4810983a9898a75fe03e2973a762180f9d4264a9bfcdb21c8f60cd915518a93efdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d4548b7c765dfc7c1472e4439a969350d06543cd6b2753b8428c4907b080773f0ed7b0626f176bfd95ff89d5bbfa260000000000000000000000000000000019b4c05fb99be599c74cf2fa333c47fe595b9b09efe59187502a71b961d39f34361e04973c07aad4befd081366c21471000000000000000000000000000000000c7c6e726567b74f1020f6d2c5c233cd69dd376a5b8663d881335453f711af80ca19021427c1bd023428be15b4da5214000000000000000000000000000000000836222ea956757331e86a9a0699b0ef008a5bec05e5195ef1464b5ff6995b87d463b1aef9c3b0d2c28f0649126df8141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac183d4075b2d856c2b26fed5632eb4eaffe1958964b06c3ab86f2da7be2700ad7c86bb4c0197e8a2a76e7f50f490f5000000000000000000000000000000001695c676b22f4d2d9afc01450b6adeda6acc29a78b076650d7effc02ccd1b1a91fae46ea443de6b9e86e57be6648a2b60000000000000000000000000000000016e30c84efbde796c3a87f66be1c0dc1b3cd7c70a65f040177da67af4a2dadf34c49577bb962ec665ffb6954845edf43000000000000000000000000000000000ceb83a44e92644d77e68237bf4764f9b85aa3308cc012ae54df2e3237d793d635de23bdf2d89b97c22a922d687e90f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004fa38d20e6b8795ca83d38e4670e915c0bd9d2267a15269068f633925398c42f3fe75fbb89ee6aa32c15a9e46ba27a000000000000000000000000000000001764cbebb4c2656c71832dc1be7b45bae8c1787af59f56f01f74ad39182a3a53de209f5620f5fd91126d013ee6267377000000000000000000000000000000000e7ebe80c143673b472f0bde0a6405084eed72b536c4991a20d1a0e9bce6e63f0dea19aa4b225f12cb1c93d5c4212fc50000000000000000000000000000000000b3848dc47d694547b8f954859950d7fa69a75dc777c1ea967623a910538d63f5d648499dbc100ecc84770c1be2ad161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001518e9502ce3b13b7390aa476823aa1cf04205c8bae47212b204f8f5d395d9875d9e918b92050faafa6b3fde5f720412000000000000000000000000000000000cd206e4fd5098630169bd2a4c16b50640ea23ad96faf204fb1d60933054eb2189d3be0d0d30b7863d0a294fd46f56c9000000000000000000000000000000000cbac5151187ee126209a12cf4989d73a49952bd5d24fd6e53b382569299f8c0b5dd4e99fc63baea1d9f76e7e2f70c71000000000000000000000000000000000f5a897b7fa734198caae2a709f0a0eda5fc66a4547b454d855788d131442ede46aa2711d2a59b55fdb5c1a286a4757c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b8ba4b924855323b1f1a83e7e9294ad0797dc9c60bc4c8976a200f61692f0d0fe38998cceeda4b92d88c4d7f8c3ad8000000000000000000000000000000000d9c636c1be4533531703081f055b24a826ce1ac3f25cf97d26ac191a09851544f57eef4a8ab9313e31c9c423b5c292e00000000000000000000000000000000038feed24f8fd1c8adfd6a25eb4c60744095c34f88ca71176c698132ccb14dc781033cc0b575c9cbd530462cf379ed61000000000000000000000000000000000f4ffe09e20c53261709bc3c6f67a784a8d7ca92bd954dff9792db5a83378e4fa72973b4bc5cfe86b1cf39ad73f781a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017374f1a5f4e3b6a4d9ffce7025c2d8237ae7031fcc821524fb7a3fee1cd061c47c3882c7b9fd98e4ce1d0c04e2e80cf000000000000000000000000000000000a5c9fe4ca4ec2e2c1560002beb08fdebdabcac2e577dd34df5cebe1832ae2ad0a66f15bbc602fb3133e30dc1a58cbe60000000000000000000000000000000007c83e2fdc817dbea9c27257d745366e818729b8b2748f995edb51edfc748beef40a7275aea546feb2a6a7a2637c7b55000000000000000000000000000000000bae4ae44ff84cce8501370210aba32eabf6065d403b844a4b0e00a5cde519f2e335922b1b31a7a8603e873733ccc0fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000743d56ccddddf1e567a29fb50ed926d21d06eb7c46c693d19a61d2448e6312f7093a75592288c9e0513f8ff29680d08000000000000000000000000000000000e7c082ec15767fc2f74d1fac953f4feeb1bfdc31f9d55ea3304445d1aa590d8f19f3f8e882c4848f098dd893e665c2b000000000000000000000000000000000ff5c4d10cc63062a5f9574e65b23a562b21ad4f1d4629ef5b2661f112d8489ee4646a78e5e9959177cd9a5d315cf62b00000000000000000000000000000000081c117e556c502332efc956a20ae2880edfba794618bcbf95cc9b1f437295aded5ab1d9ce69277b57fc115b43f3fb7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000168fd5aa9b8445b584d6c7e89c018f6c89ccd1f79b1b356d8ca678c564a0addb3b0d8c1848a7f8e977ad9367eca547540000000000000000000000000000000003c787d24b0c6a00c457de286e2d2e169355df03cb4e979db68ba20c9a43aae4cb5473b9f840cd08825d73a51b549b470000000000000000000000000000000001974f33d54fb3a497673dbad193f554a2c6072d64212118c546f56da8815346cfca88ea841ed9c93940c6473ee9736e0000000000000000000000000000000011d585d3e76a4de65a870d6fee3d3a8bb574901746378c41030fd1ae5f24af9b88b221a8f1dff355975da5a3678ac084", "Name": "g2msm-11-jwasinger", - "Gas": 201960, + "Gas": 187852, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008021059f40f3611cbb0b6fe88ab8598717fef4d12a6f97a8bcca2f1b8d8e26a89ef6f3a8f10d8abc4a68e18676a4cfd000000000000000000000000000000000258d198bcd3a192914cef9e8071938afc873107550a236620d6971d27537aa1630a396fb6aae498c5372cedd03473ac0000000000000000000000000000000018be441b4c96b43b05d940fb673ba3fcb2b60846acea3fbc2f9f1c71b8e742e8b22dff6ede7b2e510e83b2563aed1ca70000000000000000000000000000000005be810660776cf03efaadac7c7bf0b0680481a8e022586492da8a003e3d76f3f2383f58fcc72eea001df87a2e7d75bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000686e71b329505a4cbafddd5cb2ab81e139de8a91886d0c916b5c54d8b21fa3b592f5b53612b95c94a047c6c58f59f4f00000000000000000000000000000000153f839f5f5a2fd8ab02b6676b01434d724d4a39cb8e149c45007e7fbc87b73076f3007e4af7cb87dba60dbd0ef593b5000000000000000000000000000000000132e53ebddb09a8bc4b562ffac215c82e0a1b2980a4067fd314e642737f3f7b2dd6386344a751f30651e51758df23ed0000000000000000000000000000000005951a024c8d12d8a5cb9cfb73fac15bfdbfce7c2018c9c2201d42884a93d5bef42f7b29440b0887f6557636ba9b2e941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001596ad567e8e2f2e19c61c118b59c3f89016625775d5c0c39df741c7b9f7f18307f17e11c9073ea718fe35e8d5fb46e70000000000000000000000000000000000f471320998958ed942f6ab088718a277df4e69f9f19a6b0be30ff7742ab98ac4726a714484da9371638bd9b8a6b4aa00000000000000000000000000000000102cfa0b735abe2576d93e05cca22f0f387e885972f776db62fd66414e4d354e54702b0f4b79b4480f4c8790616e9700000000000000000000000000000000001419ef155c2b746153626f4012a64627342388398c1dad29b1736149cb6709825b26d7866e56d6bfab5044ee889751391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e4e0705b3cdf80277d4df7b6fe465c224ac77c2f69d8e105851e29afb580d5c34de95d6fd0a4becf286c4de20a9504000000000000000000000000000000000ad556eb3cefa77e243d7735f2ac86c25d052b9348d84431620e83ab137df38322d3fe8dd657074c3cb0e345c38a9079000000000000000000000000000000000fd08f7f0f236568e382ea7dd0de03122450cf85dfa64abaaa0cf04c9da1988f927c6caffe881c3f9537c43f69c133470000000000000000000000000000000007e530159b887ddf2f9912ff7bab6638d5871fcf0c3238fd0fbea7c0a6fe815036297950519f6b30ce02e4fc76177a1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f89dbf32b2ba6c568d2ce8a9d05c77970d7d3f83eb7243ffb91bd9806d52e952ffd1029e9d319f93852c250c459457d000000000000000000000000000000001665200a4f370b7398e448d58fa8b9d7aec4c66f4fde118349666ddddf5ea97eabdd658f0408f3b6cb73594374a5784600000000000000000000000000000000081c14e77b6f7c974e6e03dee7668aafae6a9196dde851829046a784498c6ab2dc258ea2e1355fe73699fbb9c56519710000000000000000000000000000000001fda7ef679cedbe3b920aea656826fa8faba78020fd43d4092ad662481cfc68cb3c39a7808a7a757aca4e5a6039539d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001548cdf40e4daff92ea0970c062b99203346339a8c49acd7e663714366ec2ac562297a3303f917c50ff5dce1473d94a20000000000000000000000000000000016c67ca3387951e121c711866c5b33182727792ddd8bc67a01c5004c7615d6f96bba71b7a24f1f858b01194ff321c9d500000000000000000000000000000000128b57874567d338e1649f8c8ee0b5f7812909310f2e3085d496d64a5b9177b610f0d69800d7342518dd3a94fb67bd620000000000000000000000000000000013eef06e342eec5793bd5d8554516f88431d5078b2130cf00011912bb1da0104f85308415e6b24fba8ae526a2c5323ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004140cf4fd41037fb79dabce0b9373cddd2d48440774f9ecc560b5fecdf0d20d93f6c460883a8be058da750e25fbf0500000000000000000000000000000000050ab0cbb593a2ab42baebb7805a3af12e76b7a5b66aeb8f9697836a296b04670955c0932447d3c9d019208d28d18fe700000000000000000000000000000000185218918dd8342f8939e47c28cb49d00306eaf05f155bcc12ecdf8e29f9723b1f401a176444c9bb56a5c6b357427a4000000000000000000000000000000000151e609cae21ee71c737d04fcfed42f1fabc2047ed308338791211b3b40f8641a17d70391256d8a54f77c2d07f2b2cd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4cea2b372eeb1a7ba9db02dfa31a3e5a44676c43159c1ab0f65c61ad29260503927240d1dacf809b82bdc077ca5bdf000000000000000000000000000000000e3c22343b86af2dcbfaa6f5542d6f8005eb929d4239e968e99ea2357c781a0f1dc5f2ad3bbed2d9a067070c5362120300000000000000000000000000000000052439e0377729712c4736d921ee1d6e68ddd7adf1d4098b5de65bfc6d70981b535049d83728e47b46d35a64df877d4a0000000000000000000000000000000014ee22f6ce93805f2ff60ae79179e9d7e9eda9ec0905f9ce02f262d45d3acea76d510caedac9273e3d0f4c3a7d6a15211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e741397829764310a8c9ab4d8a4d99fda011790d5ed1c11b5c7001e68135b6e8aee43666f73f71a02902af2988a679000000000000000000000000000000000402056d655fcac456eeec6ef33f10abd382228514f5fa0c1358d580bf2f71c35ae638ef97ae602e75ddd9b4191f56620000000000000000000000000000000010815680bb4944b6ff1a3423c9cee175d085684c21703155c466d9360e7b8c82662c759f89ff468b356f89b83c95ebe50000000000000000000000000000000000b03ac823455b72a4e57e1c390118b5b78404e7bb7e891587c03963e496e356a3a1486e27563ef9a52c618daf7b10251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3aeab4e1aab27465954da4964dce671cc10fbf41cbb4dcd33b8b9a968b350d57269e7870c57cb7843bf002dbf408900000000000000000000000000000000001a309e3bc566c782e0fcc425d2ff84f308eb6155bbf3d11ac1f54412107844b96c46a9e69152cf9116d49190c9b962d000000000000000000000000000000000999b2cfee89a0b5e04e5613efc3f2581971e17b9fa4d416ef5e44888d57219ef3e85daa5343329a85dd65c81ed839f100000000000000000000000000000000166c133e98496c1e34dd0cc4f70d320f3a8607c69561751900943eca1293cbe35df8401beb774c33d3579cbb43173df71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002f020bd18e83d6983a2d88684835d77fd138e6881677595795db09d9a1ed51961b39f80330ff133c4c4413f800d6050000000000000000000000000000000017c8d8ba455223931394fd8c85132e0299cee989ba1666a5eda573410348faf41c7aa8be60207da8f4c50edf5d2b74120000000000000000000000000000000014525a1c5fc79b05198350921e931b491a15a92c517f9439d6f2911d51974fb0924991f94ed02da3c7ad65ddf2b02d220000000000000000000000000000000013803248afd68ea1cefc20c1ed41ab14c78c7067ceeadb9425aa96d28049697a53d1db7668e7bbb906ba47522ff5b08a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021340102cd47b30fd393ead273f2e8fa6a8813a46ca502ee01cdaa77828f961388c3a0f38a24b595a5ede1a4e42549e00000000000000000000000000000000089f53b73dc8d0fe934a4b97b8e757b2c32f74597e986637915b389b890e5e5866671ca9ace164d26e615991c01582e50000000000000000000000000000000012ca1e5ec9dd9da00af5d5667c6b46aa5023b4ed7de24ca4639742f6fbe8edcf8285acc8384929f6ba9eef096d05bae10000000000000000000000000000000001647c594ee077c3d0a162f920760f124a5268a065f7229738293aa7114c5b7e37e1980aa80b1870aa7481dcc7b7bf701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000008c64be86e3d75be980ac5f5cc4acdbf7955c8beef520c9c6896386bbea4fb32e22a76aab04f7840b818967c5b9dbc7b000000000000000000000000000000000add9213a6d009e0d5c16adde0bcc1e6fae879ca75bc2363669459ba996ba73a2c7cd13afabef4440fd6b6ed048ac015000000000000000000000000000000000291033ee24f6fbe0d33cb26a7f67912575b4b2cc595fc697446a5cda40cbe41bd0b78fe45e7672b29135acf12dcb0a90000000000000000000000000000000001f32b2597ae1bba016f607a76e9468b89062c67b8eb3e4106a16ee6af9a2e02e15038757083dc257692535941533ced", "Name": "g2msm-12-jwasinger", - "Gas": 212760, + "Gas": 202230, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000125e569dfc47e9dedacc395712b13b765659635af6600c5cf41375c02178508736b4dd941348e3ff812fa7561d07d9c5000000000000000000000000000000000da114714ea8f220b3bcc699f5b493e73f88282e2be12199e174c2fec0787b4e9f17c4bd87c4dddea090c9790b79efd40000000000000000000000000000000011dc057d55baa6a3bfab1c68946afe661493802a3d351517512edd516b8043a3450a8b8d0020a546139084b38622d8e70000000000000000000000000000000014138f5e86be6cdd3770fddce9fa72f622622d16493da222a09162d26330c75f1644289225a3b2150f067d7e3e10e6401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cac7597bd1b94f2700b6aa8cce78c85331763da801f6f8369eb7df9c2b0db5a757a86ed7e7cb47c6a6156ccf1f022b00000000000000000000000000000000131302fcdd3337ead2c564956670ad4acd7167e13d68ca5c36d6133a2273c07ac3db3654d93716bf4c192ffb24fcb7f10000000000000000000000000000000013e44c6898472b9050205d16a44b777c7626cf43e6a419685f5dcc29b5ebc43ed4bf6ae42966b84784414b34a532444d0000000000000000000000000000000017eac13bc51ad518dcb1b5c1d19e375e5311ef394b852a13ccba1955d63682c05d83de6d05e82479c50114d4a2e43fa31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007df61b6fecd86c1ebd8eea740e0a0c5b9de167ea8aa03a2e29c1960289f1c1be10ea48c9482a0ce9bcc977232d10f3800000000000000000000000000000000049a3d0f286c117d095ccd6729581d2faafbfa84459a8045bb6ba705cdd0c09e22aa56f66ff748d82684a996051508300000000000000000000000000000000015db9c16a6629b6b2871438ba769ad4a3bcfc0b0f8639081b5bbd863c7adb74b89340d10e98f8c20e40f31c02dc27e880000000000000000000000000000000008b8ba2a3ae2a886965702dc67c7b822b44c9b909d2717f31dba040389ffd8eb6dd5574dc155733ce3d0cbc1ee82dc571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000421e49e2c24c266da1880c54a13bc9d8b4ea469289cf457189bac4db99f6cf83ed9acee2938a7afe452e9b8440ded4d0000000000000000000000000000000010c6b17919d2d2e1a80438f23f9c30166c388471410e498064e8169ebe0813d6ad5d9b2f058973d0f8f3574e22a219cc0000000000000000000000000000000001f1da97038674de5c66144c8a582a46aa7d1adc2d6227228c7524bb9254aef1f6468b7b2ca305edf5c38afeb843e4e90000000000000000000000000000000013e5290fd76ecc159cea7f0740b7848e5ff83722c879a90d2d20c77962e524b6661004379c7318fec1257ceeab1248841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b10c3053adabe7e8a94b78465a84de70451e13f91ba74951de1221547a9e81271039c4c6196b43d39a5767b09fb0ca2000000000000000000000000000000000bdc31f3ca6a8d486d4528c8a6ea8aafa85323b8497d615c5fc0e8ee9f93f8793a956c80339194dfee43ebf6460f4382000000000000000000000000000000000f74f8ffb11b40b8a9ae19578243c67bf66fd0fdf0d1222f66957144681bafe8bda3a5aad2227b0aa68db3675a964b04000000000000000000000000000000001155d62127f2b1979d7ca00c7bd65b5bed5801f9533d80c47e917513b5dca91c941a389cbe4261d84bdbe1dae52968af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000810cd62cb5db7725014fba3ed40992c573c6ad46253af574ce1d32a88be655708edc6e988e6702739e9035ad6252e520000000000000000000000000000000006b231076cfe15fb8ce6f5e54bcc75352294288de0cb6a01770cb6268204eee6a56004a832ea4348f64f2d7f0c168aba000000000000000000000000000000000b06cf163b8aa842ff3cd9a6107e50b5aaa8a869ead5562b14004ffce96be46f9661a902a13550bfc2ffdbda010f502f000000000000000000000000000000000d0a13579ce2b8a6b85b3cea96c05e64f9a3985ea29f3b7ba0a13c0ba56d4d9c3d829dff0009b620e91a944d9e5973be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177d8cfbfe0b13345e557dc914b917707576db4d3cb65f75ae0760b0fe748ac7e503d05252dbdaff302c4e201faa3faa00000000000000000000000000000000168e90e1cd4fb3c1582229e92b71edf59d43d9767c477005b81309b454bfc0b2f6ff6bf56847ff4c1bba3cae9e9a496a00000000000000000000000000000000013b89b6c0dd84befeabd600e81fb02e95bb943d67755e6838a670fa53448410836c1d779a78d370d0fc5d21c9075a84000000000000000000000000000000000d9b14965044f35000ffad89f1d9131a89f9ee6d1286b7236cc3629ebf2bdf49c19353e06a715720a47753c279549ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bf043d64cc021a08de60a3c473ca3b55012eafe82ed839ead4e0e2e61d4e95fae1edb44a6ceb841e77adad7b140371000000000000000000000000000000000d664ed33f6832c2633d5db1c510fffb446e3cec65bd4821cee132efd188787100eac3af8b6e2a626e6e7d26cfe1d28800000000000000000000000000000000161f46cd08d9dcf23ca2bc51be9d2cfbc46a210c21783b266172c7681d61b02176822fcff928beb50e31f8ee11015499000000000000000000000000000000000fa301b13647501e6b70a6b670f23c3f72c1c8b9c210e16dfba2afd9a718158a508d9bbe7e6305979dcfc739bc1df6161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c5f17579be7d1088692df3f5301ba493d2c215bf37c57a82f059513e54fbd692ca5ffb9ddb7b045cbd600a1e06eafc00000000000000000000000000000000073e8ab2f834f18a39acacee258f70a69c81957aaee5f0ddb5c22fbb3c68be6a15d76e60d1332d8bf8fc6e3121f6413900000000000000000000000000000000123bc15f394cf989f0b949c7afee86e7e02c24982c1ae01797d08104daa1936c62a0e40ca247bda4c0f6165ebdb2a297000000000000000000000000000000000b6233a74db1f492e2d6f853e46de58f67c6e01f6b677740b29552f5d7f4127ae94ab4d5c052291f492ebc4e04caa4361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c582636d12298774561cf0f44c80660da80410c0bfd92c0a0e1fa309a1f4dd8a410137a28b5a805c7b02aa3ca44f3f0000000000000000000000000000000000d7d89e3189649323fd75e67a2e087ddc225a68dc8c55933c0675d237c8b0cd9b46a2e70512da9470adb44455a654a40000000000000000000000000000000003583ac11d5525b073f3bd4d51b0b640ce43b751d28d30e07da35238219eebe56800ab11c18918af833ab953ce72e1a300000000000000000000000000000000116b4ba6304cb6f3b79f80a61d9a8fc083801996b7097e8575960b7167bedb7e997ea183f0dd0078aca51587e45c6c081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140629bda15c8496f6eb5e65e71b7416b54490a35433f005b8b922b583e619509cbf3b57a71d404a4c8c501437dd2ab500000000000000000000000000000000174419792016ad53e4451853ebf36564184f691159de8b8521c2333ce60b5ae71a63c14735754229261ee0bc67394e5300000000000000000000000000000000160292b0e2c93330dfce76b71c8783a3e29f3035986f9cf8bfba2b5515e92fb779ef5c9223797382d35f9c560d8dc4e40000000000000000000000000000000013dcbd7230e02adf6497817996a7d1177ac351e92b2e501849a7f97b608fe3b4936eb715c4eeef2c9d63440f943161db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75a9895b070f695ef417c1ae7cb0f31846fba4a8393ca068f5bf8622c272a3590c60268f067bc90b47bd8cc8903ced000000000000000000000000000000001333bf2c3439a6b3c3a994495ce7cab11d878a1735d57dae8b7d5c71a59f592b1b3d98cad3fba4bef9e33d06cef1adad0000000000000000000000000000000015c6696789fa57c6ae894f11c27267be467b9d8effcd1ed26e5f9aa79ca136fa44fa07799c0b892325853aa613960bd7000000000000000000000000000000000961c6e90f910424abd066ac16c342f87afc52f0d7ac0a8070f7e0a5fa60a5bc8ff1075e93d54ec88fe11efeb548c6c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034cc93ea8fd68c3dcf53a433fcb6b9d785f7a340f6fd3be806e395ceb055be37fbc7d8eb670719d592d19feaae16b210000000000000000000000000000000008581cfd3298278aa6652880bdf1c0f036f4106b19f9aab539710096afba38ff7b8b8a0775e2393981306b0a035aa52d0000000000000000000000000000000004ad80923ffabad8bb20319955895b919ce2e35ff7a1bd16de3044fb9dee9e229b106ffae4a28a27aeada9663103cc3c0000000000000000000000000000000015998a21555b39b3f93d23e1b5e4fdb8413189392571493629c4d0fbcffd97d678b8a5987009d93a2aa90658fc3956431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000013baefee1d40aa57eb774ba8b5430ae2d35f152bf0f514f5bca34a3a45a50b07237880853cf7a291d628a4dda2d00725000000000000000000000000000000000c1aa48826c086f959a6c8af040e949178bc3d2920c18ce2674a2d300b3f9a244ecfa07a5e497a3140cc1b7d33a4e6d70000000000000000000000000000000019e80fab4bea14c6605d2fe5fa80950f4f78df3531e50278439b3da08fae1969aa60ea6e192a70a71fc386255f7b5ac300000000000000000000000000000000142a13d159dc5f323036d6fcb848d89d18761d57e0d1d5029b02b5a04a3ff898188c6e77ec1f4e050e88cd1238faa72d", "Name": "g2msm-13-jwasinger", - "Gas": 221715, + "Gas": 216450, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001675b0bf5351afea5a97334d5f60b0759707e92455057ac6d2ab6da4c0e962f9830fe34a573a4c15d5805d3fe9afa5df00000000000000000000000000000000053284f9e73d0ea661124f1570e565cf53fcbed871a257f0ae7ad2ad6eee3308ca74a9830f1c9f1d967cf41713537e4400000000000000000000000000000000058fa7935703a53f92c32ef09ce838682b3fb9a6dd62e399d8a12a3834a90a2ae4353d57102cca9bc2091c2fd1e3f197000000000000000000000000000000000e292c94c7fd4572f0ac922c3dddc9933e3e462b13f44f7678bd0fe111a6b098f77569455473e128ea23a92585e11a091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011df2d502b32752bd5356e0dfcbc170a006a644cfd576e15d2955c4b2c084187b016fb02748acded8282fe7f80af4f3b000000000000000000000000000000000c07470b495145abcec20866a4a039142b15645f2281ba1e6ccb831156e90684159fbc7f8251bab8c79bca56283cd5e900000000000000000000000000000000162acff68e87be85214f0471990a76885e9ee2a9146f8e98e59b62ce8d7613fad2b380bccc4bb73303ac22d2d6b8b434000000000000000000000000000000000c46fba20486fc832894e97c866c4a3ed48fde23b76b4c43d3f8c9668c907678d4548d713d18eaf069db534c543bdd8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1787d29ace74ed80fb185966b2cce3832af345c97ebb1332c9796caffcb3930f37b4bb4a81ebad486870f7dda6a56a00000000000000000000000000000000103a60103eabc9d01fe5e3502c0eda239b0bdf261fb0a380b2178ddf2f4fab23fd994c3142e0cdfc3791831f5ddeb77f000000000000000000000000000000000ff536a6eea1bdfd6a8b49b81d189eb75915a2de2ecc2f79d684a519f5e8692340394cbce21d12152757cf88b98bcb4c0000000000000000000000000000000003f3390f1cc81827c177ec45da229ac2a7b6dd9e130c30220e843799d561052942fabcdc73e154bbbf649dac8f23d3851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a017b226f990a17b3bda171913d0e450e37e5d1dad2af29e42678b7cc16f37bdd3589a5c6b498a17ca8a02f442a0e0c000000000000000000000000000000000e6587616992b13eda95eb6647c5860d07f64457fd3a94797be82cd4720603c9b8723900ff562d3624d5e6edbdf075240000000000000000000000000000000004621a0f720cb397c16cd430638f5930a8bd75b391ea7e3c8e135a9e1902aa87bd6f2b29eb69a958052ac8bb3b7c4cd5000000000000000000000000000000000ee486313ef3b270ac16f4742ddd872fe2416fcca96b14a504494fb8138d2e08545658beb27863ded434e7bbfe9575111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2a119b161a6b8665d3d384a3a5068c0b1e6e363a17bf8e6250e2f79c7830bd5d2bd4f07dee660b22f353f3421f980f000000000000000000000000000000000226514feed408e2c7700582c4bfbadb11dc57a20a60e590401733e957fcd9e0383f1c979c77dbcc2f5ffaa192a0157b0000000000000000000000000000000002891a416c475d3ead18fafb3e143e0aa1bf707345d853ce713b96844a5c434cde0446b818628a5c11ba6f46e94b064f000000000000000000000000000000000bce4a7b3043334fb08ba6a2aa6d31fe7a69a666049120b622477d4597f16b9dd181c3a6846cc562b34cd96a05fa64d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192e7b3717f40cadd221f33ec65d77f7ed9a1d9ee634c03788cf51c2bb7a41732940a0986f9713f9fb16eca1cf36c7a3000000000000000000000000000000000c6432bfe40fe766e74ea73777997f0b144d4b4753a70c38dcd0a3f66f8f4cd976be4f3e97e4571b0c4ee761301c7472000000000000000000000000000000000a91c1d5c93caab9622915463e8328a16ba8c353d7b22cba4a419aaf3c11866228520a15440eb7d7d86c900f32f45b6c000000000000000000000000000000000300cee80b0f9767b241f1ea2ce2c802fa183bced933f900bcecbf8bf1bf5de564c93d583ffd60f9f2c8a894ae8d131c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f3bd9225d1a0a745038cee676fed3403608b6c42d8a58b572c3ad9293e51316f6c8930c02e025bf2aa0186b3de970700000000000000000000000000000000010da64d9e61a2f5f12479bd1d3b60031e6bda00cff35b3aef820515c1fe9ad9f01b575ab5b8b22c3d6a044fb48538780000000000000000000000000000000019e94f3b31d77564a30db21e030c0a5cbbcf02df2fd723c8956a5086aec711096c44503ef8c3e66daaca3d9f446455be000000000000000000000000000000000758f246d5b42a281e7ba140bcb397f0d1054a1558765d4fd2be6b1290531786008e3740cfe4275198b63240db224add1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000625cf5efb135dee7b4b3a91dc942c25d8f4c4b518012a6f1d18179d9aa147addd8d75a6bebb5063a55750ad0a027bbc0000000000000000000000000000000014b1c5874d7d7e65779a0ffdf05239e4ca96252191048702e9eff22475d2464fcfdfd0aa9640978b1ec710cbfa80a675000000000000000000000000000000000ddb149f99ad4e32e44f2fa93cb6a55aef7909b38f7b9c3b4d048420924de70a37f626e3899047d93adbb645db37f6f800000000000000000000000000000000059c97b18d9965647832c12f2e90359c765bfe38102c4404282b5d8efbcbfcfde91b93b3784689c05bb6ea29d761928d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ed6e17c926002070f77c00d4e781952a2eedae5bc9a6bfb7bb708dcbea68f792251fb0fdd3657488de4c903b2d367a000000000000000000000000000000000e0fd4f768d2a1e554f6d96e40d181ff0213c0364def9b2963691e764eb871dcb6c763dd552d36bafe42344c07994c5e000000000000000000000000000000000c2ab5c169b8ec27e154e7534a996fcb5becc8f423625c71ac853cea8f8e5a3435bb655401e0e79c268224cf01fb17b000000000000000000000000000000000026266f1fb7944b47b9c46091c7879909a5c67e02990e077010a101ea68cd53a812f7a42ed9ab9de1c135315ca0ff0691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a865c262cbaee16a98b8410888a514587e0646d65de00f85e0665232f0f03a9883c6a50fde8f266cd048e3c573213bf0000000000000000000000000000000019102286fcd371b8fea51f06c98d10800ce161c40586ab07890e14d704224187c25e269a5ad892c0fd087ff8aebb1ff0000000000000000000000000000000000e58283086b6244ab41798aa73598e37df131c3ba16943798d6cfbf29db0ae6cc1a0778c4d48897c54bcfb88b46206d5000000000000000000000000000000000938973335eca0d7bc31da6d707514f62fa641905a3570fbb5531fabc1117fe9e1bf229aa13baf0ca541f2e972fcb0151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7c7237076158115e0527ce32b7e2f0e2bfb97b4dfb7cec6b7ffab93edef896e37495c4b8309fb2c43c2d7ca4d0ad11000000000000000000000000000000000b22212fb5acca5649b04d1e1766302ac0599b8d93a0f1206efed2a2db9eaed1e428624a9241575b350512baed0a7e8800000000000000000000000000000000090360d266e428b00594fafaed2d35545cf42b98be6c55ffd7d9316e5f0489f65d42d5a5c679ce253f7ac9f2bced7f430000000000000000000000000000000015639a3d2992df101b79444b1f60b0eec1c23bfc9107c097693d1f1e01000011c0469a684b1f6f32225088a6427c493b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ee6bfe90a62d612516a0b8aca1c4a263b151ed0cb49a086d75d8c08ea3e7361a979fac5c0a61eca2df384ee036afc800000000000000000000000000000000097de8660434a844bf7454a5461b5adf3aeff48e1bacb9a97e3985f085e17c9ca8c370b62b7d8318b11e89bd7d920ca5000000000000000000000000000000000898081fffea5ea32073311ce63e4a99d4c98021bdc653cf67069ed62353bdeb7517e22d68e5badd91e754d99d9a53160000000000000000000000000000000005bf8b59c0584d8d1cd29be3f30adf4cd3c667294c4431c35c502b3b33613ef8f9749b1d115f3ac4e8223fdb43e6f6951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126d53c89900329df7644466505fc0597a8b32aad1144c9b7c797fc253553e55bd82f6bfc32457a32ebff6c58f5f3782000000000000000000000000000000000c804bae4eec145e11e986dde8a4d4c1d8a2319716df5d415f58ea82d68d533a588a244671e9c4455607291fef73491e000000000000000000000000000000001320146088f9048353f1f42236354d9df724f3a4b3a267e735e3d3982fda8f1fe49ddbaca66950725da20f8c7722d8660000000000000000000000000000000000cc083c86c4b5b482d17caa3769164402c85facc64ca7bf93b81822741581dd9bc10ca3e0137cc2e357e0d7a41f76121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000effd30aba827113ad2511fc92e47ad92d3173ebd158dafcb6f1521a0ac1e0f93e95dded5ac38c9a281baf51a272c9350000000000000000000000000000000009a11677280ef6388dbf4578fff30cdd72ef5124113df311f19ce81de1275a3bf2d3564e065244a976b215fb1fd3bee80000000000000000000000000000000018f2f7019fdb19e3a4c817473ed00c45f4d9300438f18b69e52704bd2f526d1adc77c4080fcbd192d34160dbaee8d14b000000000000000000000000000000000e88533f0bd693e96b4820962109d47adb1959e765ba7fc7b9fd968f71806670422c0558c125ccc0db658d063c3dab691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000010fef9f726a0fc131e54a66fede4530131b39382d031a79f1dfa457bb44e931f18c8c43bdea07d5faa5c1c9263d304b30000000000000000000000000000000018923cc680bc64fabebf1d20b420f8720ea5180a568a8f1cff39cded6d8bc7232ede266d9a5dbd907a9ce4685a633084000000000000000000000000000000000fd2d1f1ce4d1e43303ef0dc602b5b8e9dd9524368358625185530542303eee46634c7bd5da93a58b9d899cb5fb6b8650000000000000000000000000000000009ab87a9750c466b7c1f7a9adbf6b9f9ae5ce722346ae99f5c9c1d537f5ee63b5f4bb423e29f0f5983a587fa644d1ec4", "Name": "g2msm-14-jwasinger", - "Gas": 229320, + "Gas": 230580, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009585f82d0de4b032fff9c7487bd774ba390b8e0c4160e892bb05f80e5826aaf772ee2ea082090e8bbb8d63ec2c46d360000000000000000000000000000000011f2b894f97d30ad271af2cd13d2524424d7ca4e40dbcef4a8a1f09bea98d304035394ad82c1ecfe4889cea7282fafc7000000000000000000000000000000000d7dd773738b88435307f1ab371f424c6afe68d056367e8d60e96e03be384f9bdb852db43e528e7611446852b19adbb8000000000000000000000000000000000d5523327af66e927af025f46dab15136ee9272c89926ea30df5101d86eca077ea38658dfd982efd8aec7b359bde452d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2c1a78e8801ffdce4c00ed6f6f5ee92cc0572e26347828ed548ccb57979885769f483c7ed43a2807b418cccc0dddaa000000000000000000000000000000000e40f7ec8fb2248a8468e3e9de9e18a6178d7d80e8690cde852c67aa91e69d494e3eef846ecf8fef485a4e9fc8fec15c000000000000000000000000000000001424283a510a72eee9c53632a57ea483e5b7167c2f02de256360277486bd60f74489ecb1f1841b61faedf4b625799e8b0000000000000000000000000000000010830aba1e3673d8cf5eb4bec1d70f9e933a13246f5f8dbabcd9f9de1a399e29a6d459a33f865a044703e3569b9483e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001363ca31097d9067054e4ec6db6f3eabce58265a7caa3cd3b0b85d3e472db354941ba6edcfb19b1c302180cec245b5530000000000000000000000000000000018c130e92263de9d8ce0edfb46d3a1c3cc3989b7bcd02d91b8135361503b2eda8e9b78e3f47887107cebeb0639ff538a0000000000000000000000000000000001b32ec18187b4580d01a714ad705d4fa21620f9377aedc5d493445a26d5a785c160892ffa81757f707497f94a58ef2d00000000000000000000000000000000003356c415e602b72b21c742b0ceaad89d77cfef996a14c8d947498a0f1b7f2cb64c153f07eb46647957efd4d9589b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182d682205cf2bedf008ee4fcf6f6f88990f603865ebc076a16f4f88d24d257b934c4a8bd0d23a7674064d1a961b9e97000000000000000000000000000000001096756e101c086d8a028f13003ad511e56523848d1e01d014e336df1d9a6369d5b3f645a5ddeebd723e739f54eb2d560000000000000000000000000000000012ce1c90831c762613a0444810eabb2246e7c029d6c507d95b9ce7a126e54fb57108b6c1fd05944c9e923ce511200351000000000000000000000000000000000e67837eacd96dac48560a5bb176fcb640c04541f13ab4165b5719027daa3a5915413bf8d349a82a86e124df183b6ff21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123cac8ad5c2d6fe9f53756a6b5a0e4136fc7859c1058511d00622729046659b38cff450ec4652b66b7d79ea68b58b3000000000000000000000000000000000196e2aee93d2870444cc0efd7d4b0527e18d0671dbb4649233da2728502b75aca534564c3a927a2612d9514731f4079b000000000000000000000000000000001210ebe4b49081c7de032c96ce7aeddb38b0d4f18e0880bcfe6ac4075700a8a1a64157cb2424126134111d8f2638a0010000000000000000000000000000000003e1bf0a5423be6efe9ed51d9d6b6d89207f256b2c333c94a1770084ea880fe726a24a7e07e2c326609b30d7c64aa6821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120c8afdb5c3d6c962ef29f6d6203dd8378054ff1e80747e9f32d624bf1a6f9566cd55e470d0b897818ae20c8d4691c3000000000000000000000000000000001076dc9486c2fe188f96fc35a8bee4bb5c63b73c75ca8f52d1bc85c35bfae3552aa2701016131b4a1dbd9e4a97d0ac1d00000000000000000000000000000000084a2652be51d54d4abbae4fdfae4a25059a32816ac7b85db04e816df302497a4612e07afe55488aeb0f962be2b332da00000000000000000000000000000000031df8dd51547546488af6b6e457153fefe1f9e9d4f86b23df276dc90dd83d3426cb5e40d63e7586a434872c4f67389e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047659e6f8231dd8b3795cd677d6735c7e07654ca9dad457c10c312e834860a7e2a5b9abef8fbf808e60d625aeaa90980000000000000000000000000000000017bda32ae2829163047d52af952259cf1af64fc173fc914216f44ba4422ab82264b7858a7357337584504758a9b209be0000000000000000000000000000000014cd7c5a8b141a3411e33664761fb157b4b30f8e15debfe7b36b64e02828810a42ec64f453efa7ec60dac56af86ebe860000000000000000000000000000000016a89b8dadfca75f2a079a977a0006e68658c3cec2f7826e6263e4bc0a8abc7d290db071979340f0eab780d7085c5d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192b75967186020c75d8c09e4dee36974308a1462edae90ae24133827f9c3e365f31353ebf16757d23d64ddb8be39f30000000000000000000000000000000001901b5f019822bb210ca9bcbda63d9732fcbe2efb726e54dc2b5dcaaa6d4dfa0e5a6df1a66f9403a244b4f2d35d9637d0000000000000000000000000000000002d175081b980e410615d6c701ba77e8c22f09c494c430f1b7ba733409fbfd023572281a4e1a2d295b9a321c01735b7d0000000000000000000000000000000014309db5c7b3ea2e71ddfdc55b7bedc80c70b9297020cac7c7b52b3d43f8de899f7a5bd98c5a86d428ffca44e8b0391a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017af2836c5b7807288b15832ae410fdf595907159be55f55bc6f13e60b99dcc7a5f6d8a3177ae9f2479170a49a1b32e00000000000000000000000000000000001e11b5c1c90be5bd374b5dfb18e5ce201866ed908dbe20b21b5d58afae00ce3292e13cbbeff687dff38a4dddbd78661000000000000000000000000000000000df3a20c1d6aabdd7c98b4ff45d891227ed7d8fbf07c9be75f5c3925de96417edc53f9521f90fb176f56db4e462c053800000000000000000000000000000000075bf5763f85ddbb8fffbf1cb3d1e616790171b31a3ed46cc651a39a6fb2d0a7d6f370591412cff181005228390bb0bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca9cd18967ac13f7d2a7643107984c03263fdfc1bd6e365f478ff5df9aa9aa2bbe85bb3c52584ca93a603c3c65e20d40000000000000000000000000000000018359c439c1c3df752f26d1eb6da9f54947c3be0551d18455e93b491187bd159458cbdb516ae71d0c73d3e52be02a84200000000000000000000000000000000060942e464929c390b65f0ae0cf461b1499feedb18645f186130129ce7f3c23f3e920288db737d978c677dbc798fa56a000000000000000000000000000000000d92732d969bf6863daab6c50941fa748bd1da03fe31914f3c4b56285279ed890df2b38e17d077001c675b737e9b50c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f39146314f46c600fe075bf609c5aa83212615f3277085c6253aa04812d0bda206eb17dece35908940b98b579f0d1400000000000000000000000000000000156e50026a5e2d186722d40537ec19f102a4c928f3ec1d9d53fb8aa605ee474a09d2423078afc40e69214d1907e0e330000000000000000000000000000000000ee619d0510cfe6dd9d1f0f562d4907fb1081c7dcd58d37bf46e0b1bbc2595780716a210629e1037036d1abf5737f85e0000000000000000000000000000000013ed553587700422ce410305b20ac8b8f50f683997441b9b11faf5e264e3b82f98eeab1c1581a4df17b4dfdb915552cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b785bcf40b4501fe8918afcdf707e5f5c0daacc18ed5371bff0667670d8ac50c7210c8013873508895cb2897fc29a5000000000000000000000000000000000fc7151dbf7263fb513ebfe8c2f3a24946b6ba1e2fa9dd29f099db8684f6c17e1e39b63db98cc4b123e6c416c3b5900b0000000000000000000000000000000003312557c45fef275086b9b824664630ad351e2f25533d19fdc51ea5939e8c3b7a97716717f036a7b8b3478ee00c71c000000000000000000000000000000000195cda923236334d66513744b18e02a0e165c53ee170339711b4df0b72faf44e5a7d46f2aba96058ea7f3c5be3ca8fdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101687419fd635615bb013542735699cf5e3f0e048505da3d0dc8d9ff3116b225c839e23e973427f4378271df1531e8c0000000000000000000000000000000017f8ac8887b5646eedcd9403eaba4937403ef137ee9825d6c5e1d8012099d03ef3a1e49142991b5230f263fcdc7c18ec0000000000000000000000000000000016c729f3e215c2306c7aa24ae4f72c56906c8f00cae210b83d3edaf554e1ca4a73b38b49bffc3bb2025ab50104c21563000000000000000000000000000000001184c64ffc045de677baf6073458307f979cc152e903c6c737af828b6c59e350fdb69e4c9b8fef4bb178b1ca9a4e56391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193019a29a6d230896a62b27548e61bb23739b9bfe57acfcbafd1759d7fbd34339e2269462a5e45b6c3d589a7c2348ec0000000000000000000000000000000013cc2181e6c14ae4770f4fc40702b9df4907f958b99a16ff4ee3f367ecb0f7eba587f0c009b7a28562af3a3064273d900000000000000000000000000000000012387afd79057813c08dc751a929c79c44dac1867a4214065dd16274ff213dc786f1f98d493ccec9fb350ba49b22e4eb0000000000000000000000000000000004b32ca64b1f63b214561253ea1a3ccd37aa1b7d5a5ddc7b913a77bdec4a59d269188a03da94d615ae956f93f6bf31a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008eb48d60f08ec50d74a6f9b4fb7fb162cac8831cfa684facb06cf4372179b55e99c0cbe7f075cdefd30425f9902ec460000000000000000000000000000000014dab58fdc97677ac99b80c22ee7b9d39beb10e3028588d2e54e24336e5a25ae60b90b1117c79c4acb62c9853fd9e2780000000000000000000000000000000019f44ef09d41fa011e1dbcae0dfc85af938dd5d5b9c054238fc8bb79f19fe37aaf31bbf440eef9319609881b0cedf0d0000000000000000000000000000000000eaa75e3c57fbb857eb78519de3d75b5fd9b89d2f21bf05644fd3d0cd1ffc29416231a763ef93a3638e3aa718b4eca3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000b2ff0eab9f556316e3cdc9f3ffcc3cca500f87e78b6f0ea0ae236dd3eccddbf83ee3d2006181bc4ffc7a0c557e5649900000000000000000000000000000000129b1ba7a744174176b6c3c3e618f6eba64a61a77edbacde99a16f0000f4f4ec2f7df293ecc40bfeb374e23eb04d38da00000000000000000000000000000000032dbc598fa6ad4e672103f29ff117693e4a9f38cbea4a02c6a33912cd40ce5a19a940c902bad20554985f8adbafb9f3000000000000000000000000000000000357321fcfa1732b1638522f15cc85e5c1bb7b26d3dfc1b1f5ae401e40bd030d55bdd8a92ff9cd3ffb58b20df8f6e58b", "Name": "g2msm-15-jwasinger", - "Gas": 235575, + "Gas": 244350, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001058d1c8408794e876eb0756c8e3912f4351845642c51cfe647f5929acbcbf5b1ac73ce1fdad37b47f9d7e398e55ac830000000000000000000000000000000016b559edbe17138dae65b7e113deaf062872da451d283b9883436a361f939ff2e4335c361ddff609112887f3df907bec000000000000000000000000000000000f2f3d3cdc02fa73ff20d86b8ffb0d87b44cde00a835b87c19305ee42cb7fe48fb6f6d7eae0cac84007c4c5461c0ce2a000000000000000000000000000000000af87ff37d502fc6b6799e086784e26bdb9bba9491a1e48f0d17ff3544efe150c1cfa6dd35fc8d068dc73af110c8d2241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001648f0cf7080e1bed087a10684b89e4e99205b76d4c557edd5b1211b1214fa052ed609a3cb7d681311aeaf46ef19ec70000000000000000000000000000000006fdefbacf75917ff0b17ba08cf4bd0350de01ced463daeb8a55f149da95abd4233dea334ac50799daf663adeb97e59d000000000000000000000000000000000f286dc4d59f9955f63bcac9a2de7259c939f25075fe5099a3a3cca5a061e9357b9e443430dbc88509aab699887f816d00000000000000000000000000000000052895c6162eee3f9db6561ed540b3b2d300e38ad497f86cfd779220df9741043426212ca5d1d7bb9d7b84251fd847ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f1171e3a146490f761f8396e1b25d5499ad0d9eeda355cb0d9d2c94e00e029567375de2c139afe5ca7d1c34bbfa79f000000000000000000000000000000000744e97177f935081e73159c0ff179fd1432170d8a1e4f49a04a3fdfac29c6e1f6d323a4279350643fd94d0b5e6a54fd0000000000000000000000000000000006fd7d988b54b60f695bef25547d9110b55046602c9e46453e3eff69fdbc65dd13c77687bc44526e73c5ee9bc4d6bdbe000000000000000000000000000000000cc27777d17b9cfc921afa67345a060b497446e85d1bfa4fc18302eeb6c88d5114813322d475d72e66b76caba7d418731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000928724f312b832cc0448dc6cbd9f23846b6369c758e62dc8c4b4038a0ce85b8c34fd872a2561ac0a1649879e16c9af00000000000000000000000000000000019403353bb0fdc9d31246428f8ca07f371a21de827bb6bb7b23f7437a2196a3bef2b6ba78c0aacace2f1d55bf2025da9000000000000000000000000000000000433241c6b5c3b7fc4dee4c795f1725ac92b969ae8cf7efed1385f6bedd9d44c1d2595b6922de323e3548ca46e2d19120000000000000000000000000000000019dc1613f73c4d972dc18ee6b4b249f61e018b8498fa10949d9a318406472e8f62a678f643096025a00c9283c10a376a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001615400eed4603bcf9c2d843f9d4e1399f475d1c7d90715e83e588696805690954ad81e3128f79945d14d1d8489701100000000000000000000000000000000009841383263d0e0028c8874f69b621a776bccbcd3a50705e1b9f3457f5283ed97812dc8051915d555ad94f8bd1e4bab600000000000000000000000000000000119b5b19896d206db2a688043730887d5f4a8443239449c180a33164b4ffdfdc62d4f84c474e4009186e234a45705aff0000000000000000000000000000000005a5288a7ad559e3c840a9b2f04b077112acbcbce27f75ba54e78a160b3de4709532162ad973a3daea30589d27c0e7e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2bcccf91f2f92d8742f43b3ecfd0e86c5c0b571592a4b0229e5d758e7547099622150be509a0eb73faf60b8e6f32c30000000000000000000000000000000012a8ba2e96931e64a4c8d922128b6bb9b33759b4a8b90298dd966e24bc8f2a62c93578a51f1c69d25a985998b0f701b2000000000000000000000000000000000f08d45809ff6353d79ed446a61beddf32b8c10e80320863c14dd6f3963712a82ec08078d870be39c894ae7a115761d10000000000000000000000000000000015b3aacd68e406cffdecfa1862a05d2e86c18f88953c9fcacf4f57ed148b75fe47ee7d520423e10b253812c069249ed71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d33f05473dcbd7a6f87aff2c4492c5ee075dbeb240ac3efbf7c10100349a21414d7477a2a9bf8b820fa22cafa8fd2f000000000000000000000000000000001909b11e06993d3b3f8dbcf53af1f84f8f77f2a3b2099e43ad2e388a9f50cd6dfa3016bb8331b9c88f72a5644cc4304d000000000000000000000000000000000c2d1377a29d0f1edb540183986f4be344bde6b0e828e660e237ade096cc93951df423cdb31402db6a58305cd8affc3c000000000000000000000000000000000e00541a59a064e75dca4a34a7dc2b53166aef07c5304d4ef2958eea89e0c03731da0b1d34365d21f6a96abc3f5f3ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199577c6aa52005ebc97fbb815f35f5536b32d01832fcd38a928c45bdc74979166b2642e1f5c8105a7c65e1e3e91be160000000000000000000000000000000003b869f8fe45a059b2a0a0e7f881109c82f3670bfde042c5308e47feaf845ce74e61e706a9041a35fe9b5ad1b4c25b64000000000000000000000000000000000402ed4ae3f01663f6379289751b684083d40c08fb001dc3338452587716b31462e1b9edd0f3c958119ad3a99cd6e09b000000000000000000000000000000000dd87de5373639b4e472dceb52c1526489cae7db9449a76c2b6918af7be3324d553057d15b51d62ce4bfdd3eea04142c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb336ef38c387b531ef1297a3653a8ecfde7e9568efbac252f51cc34d493b1d287fcd03ddddc773aa753b075aef804000000000000000000000000000000000002879eff0355790a7c1e598a848c2858ef74ca6026d2f3982e60c0f5d4ad248ce5855fcadb171e959e63e4c0ae2fb7d000000000000000000000000000000000971e792f0dc832dfd3d324afde0fbcd1169565c8ffd6cd90d5e34ee97a6ecd47506f016878dfdefa4efeee1e97689fe000000000000000000000000000000000f01e28c11307cb75040a8c4ee1efffbeb204d5bd9c9ea4646216715cd38ac2a8a78d6960b9f20091a13ca1824c1e7991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b028f2577947445327e7a59d284540e4a70d818d923ccb094a964f229da2e8bc4a8c384e28bc1498971819b752e7b40000000000000000000000000000000000486fb86ee6924a74a6da138e4a33aee6f571fbea13a091dc5d36aba1220046fb5475f1df45846fae5a3bed42b2f086200000000000000000000000000000000128878f7ef1ea3a7d68d82805231665d6ef319e0c6ccd33f8b69574a9e9d3e94dced576aee30f8cd731964da3209a7a4000000000000000000000000000000000efd61a5527cfb0bdea34f81e3c4a0faeb06ed5fbb1b49099219af9241fa1504a2923e1e5d4921819caf74c1da7d20581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ee99d683d95606465110a6c7d701e28b6005f55325ff4dc7eb0530ed76d72f29777001f867e881bf88939a9626743000000000000000000000000000000000005be8ecd6eaa8a09dbe42b5aea039633f1af6a23f6f74dde1af31786d3306c2a2b154763db48ebd83ce35050bf2bffa0000000000000000000000000000000012994045e0a6e31801f8d811cd8474563252114526a5bab5e7ac6aced43bce1a456c1e62222beb6f81d5ad59db330f550000000000000000000000000000000001110a22468be14ee606c79e1982612f270e800dd4d9e5843b576d68de839da7f4c371720b26fd334abd05ccfbfa52161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b63af19ef755651fea130b411999a332440484ef0e3c3a8adc57222cb9e73b8dd54a33ddd2840ef7654611cfec8bdc300000000000000000000000000000000190107a5b7a3daa41257ab3a21ac2eddfd20d256a180bdcebcda2dd36fa7c98f3e142930e7a94095e0f858be1ab0728400000000000000000000000000000000074bd4deb184b3146130e2661a5f1c4186ac692450d40a43613e7db4952ac1275d609a9dd28eec54116342552172d1d20000000000000000000000000000000018455386ef333c7558f7258760e17d5ef2a6fb7c94b740e2cd1948abbf06620e2314c4f75fa1706c90c740335b8db8941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f9728915e60dbd472b8f381d0b3b96c850cc63f8a3175c95f82bd14f6e3a91d1587da029725e17bf6f1c4722c7c1f100000000000000000000000000000000185d005d561aeaa3c552c2fb8c7631bc36194eb7597a0f9bbe26fa77b6dce66670dd61f1938acb960a045db1aef98c4e0000000000000000000000000000000016cd91a64a95be7ace42d45523013343a4914fce213f25d3ac3cfe474b8e651df277ad41fb153fb0e3f7007553c8aec20000000000000000000000000000000008e9338c058917689eb01bfaa478debe85ddd665f15b6ba01bd23a8b0f7dbe7ae24c62171dafae6e72114af83044a18e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cade5e723b7b7f9c642302470b99c10eb065bb11ccea7929f6646749af6a49e0397c17db55ba1a1f5d210569c4f1820000000000000000000000000000000000fd4579f392c16763016a702f5e1c02c5f9e7ac279fc38e3a43f124b925ddf09364c33aab23fd178244ff5b8e51f7916000000000000000000000000000000000d74330f40790da1cb2788bd12be55494010969e58a3a90d780d129132a0430ace5552065333d4df33a3845f82e1cd990000000000000000000000000000000014125a57f3b50a5042898fa63221a1b503b6c02df4b30022885f956e7948ba7c98a8abec53ea5179b3c6c36a0fd5847a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b81c9ec882ea6636b0ef5c85d1629bd5c6cc9dee96d8aa623f8fd84aa8edc0d18ea82ce9319d4f7d52408e903325dad0000000000000000000000000000000015c717d944bceb4d49742411ec8e8a73bcc11e208e023e68f7b01f98ac7be8e557babe64da5bf4fbb50c86158748aa1000000000000000000000000000000000109ed3178a5daff7b565664c000192c4ca0270706fc7a0183a071c8cc9222820ccbba90c2957bc8eafe46703f971b58c00000000000000000000000000000000083db7baf34e5d542bc2194cc6e392366dd5895fde33c7a4654f5be6910a37bd2440d32ed6341c4b64f73d1b5f3fad431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179d929ef49df8ae1ebda88a578d530b91eec073b9c31f3f8c81c4d5873a260c97e943714e5831ce5c593a6a60ad081300000000000000000000000000000000071b51a611f6aae8d08dc5a56ab3cedd5eecc1e699dbdafc9fb66094667f4fab3e5066a15c65d84425f72e4f4440ca79000000000000000000000000000000000a3f84ddd786f48da54558b275c8e27afaf4b9fe709a5aab1363011ccc85627e00e949ad78bd3f5e237513d683ac718e000000000000000000000000000000001517a3b22cd6ac2ef59ce2817776f3313b1ed96fe4db283baa431aca0740e2d2ef5e2fc12bd5b0b66c86e6093fd8fce81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000013b03cd0cd2b3da6bcf67f1b66191e2ede276a1c6949a552784d03b02b0377a64b5b9ba19837f751a64d9f15ca5bd2810000000000000000000000000000000013ad666d1a6f34c1f647da9179c367efa2a7c29660913e4c3ee46d47f0e125bc9e264aa48a3c23e4a2d9f5347bd5a4980000000000000000000000000000000002a6c9fb6ca45ed061bd17513ecf6508d8d9ee2d8f918426f65058cad0c5e3aab205874c4452a45ea65aa2bbfcb67ebf000000000000000000000000000000000c2dc22dd05c745c5f9012c6d47075cd385818da8c91d6a70ee9c1e0d7bf497b85d5739285278e51a9fe7f283296d546", "Name": "g2msm-16-jwasinger", - "Gas": 240480, + "Gas": 258120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001104556aeb45e44cc8c466a67466a4bcc9ce6b62011bc292a2985fa6b43d87bdf8e6206fdf952703c7e441dd8bc753c9000000000000000000000000000000000198c04fb399606cd7cfd4a6aeaedd05cbe8daf953a63c69326c9b359f8048941c888c77602ed810aa83a218ef24eec0000000000000000000000000000000000f0f91aa814be133b06e6cb830cd4b97c8c548e6869005ca34c83dde8f03c9d9ccc879169b4d37e646a3e8df9b3153620000000000000000000000000000000014c6813606a7f77084c0f28b071905c9fb0189bc9abedbbbb30140b3894a13ca851717cd8c91d728fdb22c0bd4aeca801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000376af4856ecafe1e4482d3334dac0b730492eca9c77ccac5133570e2a3d3bd563b4a07e905353a1317d8ba83e2658a400000000000000000000000000000000124a5ef79681ea5b556562c237a35e25ccede8b9c871f70972b25d035dbd30f72ce04954189e2f9cc7add3a94f59bd5a000000000000000000000000000000000fa6de68187bdffe5275af1f590bea2a84ee8bbeb321f60c4c5f885c15d01cacb54de29326693bc239a14d04f012503100000000000000000000000000000000101269f6cf51841f76147147c90b881815476c62b42f7b71961a073a1f184cc4e01b6b3d656c791c1e56ba27965bc2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ba1a5fe02833c8600e725e2ec1a2b7f54be4dbf5ca6345d502c1fc9ab10c00c99d9f6120ece763d5532e83e426a596000000000000000000000000000000000e63dcd5386a32c287783a51492797752924713f7fd1f4ca41064e73c001ea057e9f976e4412b8b68b521837e8eca07a000000000000000000000000000000000d6e3a776dd6e7dbcd71f4666aecb51d214adc4af861a71ff2fbd7063469cb7e0086dd3d6ecfea00e9661c34a0f1ad670000000000000000000000000000000008609cd85edb79f4af9b9b2d68c18bb780d63fe0b2e4b4cb4a6ae1d64b25d9b39ebe3cc0055bb9244538fc048e8518941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f077c324ea0932c6e714b608140ad8177f304e0b133e6d9f42e668dc9a592848099d14b7116e650bc3c2bfe8e8c0e3c00000000000000000000000000000000021e2a8fb0962bf01b8e0b06f6824ab03ca53fbf6a5329c1c7572e6318514a2f17a6bd04b58b5f78a95671b0aaba1d57000000000000000000000000000000000ef2f38be769797fb08c80a01a842e1aa0d31c97ccc668a40efba145e533e9e8ff27f0c16c7699d817474f3195e7fb0d000000000000000000000000000000000c6e68098be8a66438e9bc378426f8c240fb6cf7b85ca5af8802fe42705392becae2f14f6388e11c75840447d0f5d36e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2320c070506d317ef35cdfad07e47b664eead07644a8e6baedcb92f26a725baea5a7b433966f6e09cc4ef0a25438b100000000000000000000000000000000030509190d69a4193a2653b430af65a0e420ff2da2f7dfe7f09961a814f40921db2316035982c60bcc3a4b6d24bdbc77000000000000000000000000000000001616ea2634e28558e4a5c11064315629bb83aefedf8e96e4242dca7cef1873116f8e32fb6d7cf28b772ff2b664fab5e400000000000000000000000000000000187b1eeefddf013a2a643e33208488114b67515b025d33b62111bd31a2681046de8912cbe3f9347ff5de476e09d368431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d4068ee6abd320dcf4833f72fe17405e62ccdb38fb46cda3c328f1bb5769399a0f17daceff5ba72a5d0c0e25b89c47000000000000000000000000000000001581ae43f73c970ef95ec34bbd406fe6298a9ab90196a01d20bdbaa207fbdd7405b70de5b2c65f5d5795e2171cfecc0a000000000000000000000000000000000ccbe6c487d3363119acb7ab34e19f95159aad14e123a0a8ddaee7357f311be2583676f24ee0edc702290813af0039660000000000000000000000000000000008dcaa66df2b5976dd8f035f337fd5a8571c7ff68fb97d1194b247bb9d17325e7f9e47dc485986e320748f00edab1aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2b306ea42fa2f504d4641755f00b8a26496b7c1491c9827e335720ede523e72cb1b458861fa0889696615615651b17000000000000000000000000000000001071834c5fbd5be9fb9d76b74597569d912033d3912e15b2f8425c7561cbf27ecd114e272b84b53f325aa03895ebaf17000000000000000000000000000000000aa85beb2d031320e646d2484f60baa7ba7f19d836b46cf7855403c02363accc5a585f6c586975ab090684e4600c6c9f0000000000000000000000000000000003a1524524d3337da6b2598dc50a4d8f87bc0cf5ac1728daed21b2ecb4760ad89725cb65a1cf25d1018602e2ece363011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007accd88917e5ea54211a1b729ab5e008f430233b7d57bb3274e22abc3d0b721dd6d75fc192f5bef97d6b532d4829f1f000000000000000000000000000000000756395995c8e82c4e132df5deb98471e4725b6c0fd65499d64e7f60feb421b831e2c7c664091d2d6ea19309e693281200000000000000000000000000000000078472f3bcf1a22b836a71d0fc26f1e7ef1d1d2449e53219800043a86c55b616b3decb36b6a0dc09d897de07a8a7885300000000000000000000000000000000159afe20a5b84c33f0fc97ffbed58a47b8818ee1a4f7a6a551ee1fdc9f0a4713a8fae4659d1ffc786d3a26a4073c03ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000731250638b25d7c233c1ccef3de8e5a21b73539d2a066e40a6361cf02976bb0f808ce5412ea59bf29d87011f39b17c20000000000000000000000000000000001b6a3ba61fad94594c410515f98678d6a57100e1e7782eaa86e556494995b9af16a03477dc224d2d81c67e29aad02c20000000000000000000000000000000016f8cecf491d78b7ef48dc84a00a509872048ed8b8e36aa8195bd743ac383e72c9a1d32e282cc2d6f35f28a05aaedb8200000000000000000000000000000000078531036e75d83a3acc1b35eb0250e340f2460570fa002f9407fe0a3c7da9591c710162c9b9ec07472f3e7706cc51e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9959c588edda60c184b9d22de33453d9c338c7892217b07e3c6c1d95b8d7a8b35e6a650bc14e419d0193123667a34300000000000000000000000000000000029a4f9a79e1505d72130cd287e67abe9567151a0535ad973525a4f13384371ad57c96acdadc2410a8d073638d29e380000000000000000000000000000000000b1d866eb5f67a442a8fd367bd579f96b3ee1f05bf066a1f293a451cf97b211d6a68f6eff542d6f46fb60ea9f06e27ee000000000000000000000000000000000146d6a623164f50a81ea9552be321c26d53e32138c3d23f1b2d1d2cf12e43e65b56ba4fbf5336d5b9e68e2ecd6413541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0ea54358992c5a4c4bbf8e93bb07b7df6ccea95768e4248741ed3bcaa8152dfd13406a6cbddc9a22e440e410a6fa73000000000000000000000000000000000d537c497f954afda663c54144f38e6cc24f662a03f762225617d0f5e4357c6a01eac7f3b927c1978d76d9e1eb0d9245000000000000000000000000000000000db9b4eaaedacdd13132cdbeb1c1bf593b9aac552645604cb00d4df65bbd1efc54417de5939ae478e1394330b0d79ad6000000000000000000000000000000000472a33ba55805c1a1646720f72fded955ad0adc74992400d9a98bf07087407a11d255a6b6f70fb50cf0b57f595a1c651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017983879118e9102e8b2ac54d71799e30bdf1188c638e54b7fbeb5f2bfe39eae62ad18560ed29a2fa2307a6a1d9db027000000000000000000000000000000000e19f4b8defb1b7798eb74a885461373c368ae17fd101cac4039f0de41eace7df689743fb8f9003e7acd04723303682a000000000000000000000000000000000a85f33e410287e5f25739e2a2afed580f12ddb4ffc0c8c4352375589b3b56d1d55cc3bd145aeab54ee3cf039edd3dfb0000000000000000000000000000000015da8e3e3ebea1c51c68c0f3af09dd442a56ba75ee925db8700bea0a5b75f7cddd5d9bb5477dfbcfab6eae9897172f4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf1278667922f7994945f1688c96d373b6a3bac2fd6b277290c9f7ab86e049c4c661de7681b616823a64a6204a4c794000000000000000000000000000000000892aecad822fd54ba816345d36ffd9cc3995f435f9cf5c1990922a8ec9342680cdcfb076f235527e2b504080b1679ca00000000000000000000000000000000106af093f2778f6bd217876fd6403f28413e885f465e1019b83472ce4db3908abe0155334cb497fd44197093f06b0eb80000000000000000000000000000000007011bb29fc0f42ba45b7807be97ab361af719914b501d5325db1110d943af902a8fe070401ff1d77b78a35a5313a9491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194149f41f5859428a7a0fd746e5af76a527e460679552cdbb9db8de0afe261d7bd53ab72859fdade8b891b6c2d7cc1000000000000000000000000000000000105ab549dba17a7235ad523d02709a222fccad103a1086f8bf658a2c08875122274021aa65017a6d12bb414e9e290e0f0000000000000000000000000000000010667b321329b2bf6219387b9b0940c15065eebc9dd12d397207c94a8b3a1bc4603dc23b799379152a46a7e666ff5a5a0000000000000000000000000000000016a57f08a8ff767661012fca04b227033b418f06f1ae48f11e2a510af89704909b6d830ebae761010ab27cfd333969db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce8f0ffbe14511437a93cf5d5a6f41c8b141d0e2203bc72a54123cfd5f4a0bcc2af21d74ab7cae02e64c89c77601bb90000000000000000000000000000000013af57bd94c81ea4a2322c649b7ca7a8046d6dd71f774022a2ecc8214a7f87495a7361d62077740fcfc8ad8162188c760000000000000000000000000000000007623f4ae90d7cf1e3b3b269849e4ab2c8ad42530de2ef36b4ef4177a4b42d52ce1d5db26487bfb66b3bdea1ca5ad9800000000000000000000000000000000015cc4825d19a5824a24e147532588686141a2220e76e4ee45f89e181566efafbbe2928face6c1ba5e7d76290c503e5421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188ef76f3f636614fbd3d9be8dc5ceb80cc3b8ece05fa1ad3bfc2361cd9942decf6b5c97ea3edf5420a8f5d530f4ce5100000000000000000000000000000000105ee34bf0f58fe297ea264ae6307f3f0a14adc34eec12512ecc85a9509176044cdccb1ed1e7234dd336f4759c7c41d500000000000000000000000000000000111cb92d59590dc3c5d97b2ee4ad42be6180e076c41e0360c71a031552fd54665a21b462fd9ad9af9ff0fbbd1e3c111a000000000000000000000000000000000e5fa87346d31866aa046c6597d6b7ade36e71453ba2106ed739b512fb6168c61e2f7d1458137237279354b526ae84a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000beee9a81cefbcfacd5eba208142a6ccdcd40556483345155e4eb64d98eb07dd21c05246b3f4ef786fa45d606e207a1c00000000000000000000000000000000189891e35736b0190e6fb5ee9959380e9a1e1815590e4ccaf0cfee72cdce0c9eb82f87c7ececd102812debc1a51f2f51000000000000000000000000000000000d43e75c52216919c08749cd87f812ef0a95039d22636c8ef7bf0796ce4d84a5d0d25b26194129d071325e64a44594b2000000000000000000000000000000001007fd530a197b73dfa671a8aacc929a94b201f86d56467a72199ebfa39709818e917cdd6663cdbcfbf6bf7a92fae9e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000ae34591f4972146fffd248b35f012ab37061bb015d87b8019964079e8288a814d997c2c62b6d460ee5cec0f445114770000000000000000000000000000000001fe760c518dded13a56b10b8e266ba621b65ad81ffe5d9b7f48bd1f836a50be51449d8bc2bb50668ef6665a7f500b9a0000000000000000000000000000000011e71eb57d8c3fdd4ff08bf07cb79b037d08dcf554688594ed8a1a982678ba9acbfadbf7344a4b3aeacc5b2e273c8fb800000000000000000000000000000000149e4e3cabf0cada1cee16360c62699e4560f950269310b79e5b50732515780e489b1cca49695e4e607ca0258b97456a", "Name": "g2msm-17-jwasinger", - "Gas": 252450, + "Gas": 271957, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000035719ed98fb006b91929459ccdbd9ec3d8a4ee3722fc7a6dae78885a022265c1cc591517c2ee8100d41dbeb6d7cf18f000000000000000000000000000000001996319f8063de95135c754433001dcfe4e07519c069f38c81f29b5c21315f19e259282500996cd64ee7a4cd5cfc393d0000000000000000000000000000000001b88d958e0aca51e2d31040da8444a92ea3f34af2ea0307110baaf16ca11a2b91f27e44e52bea856f2a8000c334971600000000000000000000000000000000102eae8acf7ebc9150b37d09a0cf5b99a6d114fd9fc256e5fe0414ecd5a3a1a533f3db8cd8c4b1afd3bf48f349b404141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050cad5460e28bf5d32db9c3986733f148ae9f36dbbb76a5d8728d29802dfe53f467893372c01072d913c0b83e9b92fc000000000000000000000000000000000e71d19bca2853a29452ae941263071d7b6f6103e2b6f6641aa943a83ae987c2a252742ae35e1c738ec9139e21aed4df000000000000000000000000000000000b78e8d86de0a4927a7a8d25cf0a0029c25b8c6620a7ef33cf6747caa71e29a8f0182f4d00e81e8668c79f3cabd6ece400000000000000000000000000000000033733fa7e65bfa79119196911565917edd32652d0bf11cff8a27569bf22c00d5f3468aa66fdb7e433ed8e5fb4a07cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b7b2dc69076571e574fd74bc86b1d47327107874e53ba07529ec3e3deeb1316a199a8499f15396f966a815f64bbaf30000000000000000000000000000000018bc97f141aa016ca6ca93aea5805a63c18873fc5f955c5289946d66d5eca77090a347f1f1d39dd8b153f1d855e00a910000000000000000000000000000000002aff2b3dc781bb0a57f04564e299aea6c2351f08a913a7a24ad97f97e1dee894ceac5e2aa2216941d0e689da5ff6773000000000000000000000000000000000d8e5168d7711280795053af55a7eb6822fbd5e0cc413f5779396b345d9b7497405b0c5084f7871f0fb834b2b563448c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012128c36a1d438083dd79a43aa0df1cf069a5f562252c1f274c4c08a0066e8a592dc0ff99e1192f744b9e4de83bfa7d000000000000000000000000000000000ad959e43c6e608ad264fcc133abb4917b54e3db6673ee277aff84774e02a6376ba9b3950cdc413b6fd4051674ab18db0000000000000000000000000000000000e423d1aeaef918ffae49d269c8c8a0ce9158701d60d572ce08af691987803e8c5561a16438914f3b5c8810ae0aa9f90000000000000000000000000000000011634f65fc32ae2271bb957e31314e4cc7adee902bd78e3513aafb77964957a09dd7afbd988fb3debf4eaf32a4ce7a2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016501daa96be2224c9c53e2d918aec64052467edd47d4a51860384a082d487b70ebd869b32e91fa7d4c14caea76fa14c0000000000000000000000000000000008b9f14ff60d996bfa5150bf5a3c2f2559e3f7a9ffec965afcc48be2d8498020b55eb2f64b347bbe8b8a17297edecf680000000000000000000000000000000006848030ecacb1b42fc4d2ca9ce9b67a3b719349f60bc01b663a876d96df736d33e58d534cd71b84b655f5f1356f7be600000000000000000000000000000000076f075f53dc9def4207a6c21a7d85991d4c6e1045a540cd61a8c11f87c91128276fba2e1cfe708627e9a1643bea37481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001489e34a5245bb4198096faba6093cd65f2941e5ef2e2bdafa9509db89e36b0b0d93c260e96cdca3b9b6ce00acfb69fb0000000000000000000000000000000014038bea6c0852ef99321b14c2781e46cb8cf6ecfea7e015a57d0e577be3c60ad4b72cfea35bfa7bddccf62b2ae74350000000000000000000000000000000000121a942d335349275887731fd8134623ff7cfa6468428810ed5bec46318bc0b416fa4daa2e75bf10797d2819cd346780000000000000000000000000000000019b621d92198088a212dbd1c865f5b43b70f96ea719ea675a46e0272b704d89b86cf6dc0eb0738c107409e3b060970501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c35d18f35a311138652d7bc36f0884a2dc0f8b91c3679dfb596f25b5ab4702d1c262b88d811acf363b199d1a6fc2e90000000000000000000000000000000011323676de68c724929dcfaa5f52e4f9aad2e43cfa30ef76afa726ad843f6841befd4dcece238f623e0b9331651cae62000000000000000000000000000000000d695ed55b40264d16c757379e2b38cd251ae2ff0be327b2572cc415554b6a3c4831a462b901b5037c9c55edac28273a00000000000000000000000000000000185e3e5a4c19da26cd7516cdb0176dda8ae913f29a92d69c609d1a6bad1f535eb270756addbb791bc3ce3f7f5cd1ef211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168c03cde2800253784925dce9f31ca98c20b01e2b22d174a10d769f97886ee04cfbb9ac2f9d3dbcebd2461ee4b7b9f90000000000000000000000000000000011074252ab583d934ecab393706005ea724d57f7d29b3b34912a1bad84e599e5ab13f140f80c183f08ff2096bfa8c019000000000000000000000000000000000b36ff32db6dfb354794066938a652d042ee9647bc1d1520a8f32a4f66d9344ab843eb3d347d010503bc6c19b2c9244300000000000000000000000000000000060afd6fa713ff18d4d884b223dd65c4ef16c8e209d32805e51efeb176f43ad7115d2050ac2f434f480ef96d64ccd7761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dd20d5592e48445e11c35ca4eee5e97ddb657b71b64baeef20c158b105638adf9bb5540c3dcd2cf42000a785fe572e000000000000000000000000000000000a54693a993d3f6238ea8303ff857c56f2f3e9e75069c8ffb280ab6b3a12c943e3afa6fc06f299ed0550a5d87ae6aa28000000000000000000000000000000000e364b04ffeb4d738fac3ee31acdc51381606bf6e86b5c27db8fedbfbee6bf7b368160755950f1cfa23764802af4e3a50000000000000000000000000000000015c1c0756f614d002f1365925e73b4b00e618baf5c5e8894bf4ae72665f3e3b40783d309970b170c88e017866c402c221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ccf1ae26d6c43eedc0c2403b3367dd8bbe8750fc3ebcb5506b75c81678f94f88f6c916579701d77bd11fefdf18bdc6000000000000000000000000000000000eee7577ebaa852710e6854dda56b99f4b459816f81fea9b5084431580960b7349664340174a5469e77bd7c3ba13308100000000000000000000000000000000128be48b19560b21d6d40a73b8ebe5b63df73169930d3facc710e997e7ae195fd641a0cc70ca835e8840aba48a5162c0000000000000000000000000000000001338804d0ff749c8fe0136e01b1f7f0e73783e03d991bc5109842f18205735a160fec54636240baf43a014783382da1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007008bdcca55692956df3519a9c945a1e48d2ffa1c6393276a7f577056dad11972396c3f1298d6b3544c8c135627817900000000000000000000000000000000179e40e314439c7308e4f6dff7f9c7b7346fe7e3bd5d09848d0d8f6095fef44b9462909447c6f97899295ac682f29e1400000000000000000000000000000000136d33c2ca515c36c0d265e07b830064c6964e7946876154094b37ab7e8e20bfadf3f93a4fb9b7985cfa098811e4df850000000000000000000000000000000000c08cd7dc791227e25e3b6c14054472062e0fa489e56d0861c21be190b5e5097a6e909536d297059ac00b3ae7374c841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd4963bacac22f80ba7c11169b304eb5866c70a7186625f365d289eeeed97c43e061edcc9e4bcb67edbb4147d9f34e9000000000000000000000000000000000d084653c685b7e36f64e9641f6041c41b1ecf4c30066adc642852ad628081cdd714c48312ae62b7061ccd193f9297f90000000000000000000000000000000008b3597e599aa1477eedf0f20e5276f8ee4d15811b7b49f9fa40ac5fbcea5f53879f7beaf5e44dc2dc83bcec370dbe1c000000000000000000000000000000000b3dd0f5a7c7a0b0a2427e86e2003275ed2e2a8bf62a51d6f6abd18562fc113d999394d5175c419d2c22b2ad431cd3f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001581b30764a1d414ff4e72e5707619ada81b04748d6465d31c5f59ae5cad0aa4b7436442d3e75a1b653b63af791f5b120000000000000000000000000000000010891ac43c75dc38e151ceb409b5085d9cf78307bb27c0846d7e44618bdcc2312ad65374809ce8789416a618ff160bed00000000000000000000000000000000111009eec61f58302425a1d0019b05d5437c447df221ed8d80285c565d5f50fe03a8e4d28dd20683a2184abe648a69710000000000000000000000000000000003bb86312fa9b8155d49c2a975b05a32eb057431a570925af9132e64c29c73754fbabb2acd97d7c6d283e343293096251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d2ae44ed5121abeb05710f27dea8a01218037869a4e11cf15d00ecd8e2603906dd7af6c7c3fc1865adbe9060c2934c000000000000000000000000000000000922107b997a88cbb898dcae58f4651b7e4f4b5726e6da2f591e3619800138899f780d16fdb4e91c31fed5c46cb779b60000000000000000000000000000000015287940736acf6538148a79c00457e0df3bd9bf4328be2d340d269d00dc7ba5037557a352704bc9b0f3eb8f6b69748f000000000000000000000000000000000b15be9d58cc568ee15be155e70506cb59e768f7186d7b563b1d2d1271ff96e170e8a5d9e25fe62747a2d44f32cf4b851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ffea71fc64f8c12a57568133dc46d8b8af59dd042f9cb6e62e276ed98bb9308e7e7a9d86cb372809a114e71f2ed460000000000000000000000000000000000aae2c13efa33d014785648c98fddc09130de67d8255d6d79250d408e553627d0cbea4d677d426bf1f9a25cce21c4ec9000000000000000000000000000000001258dccc658812f666a18fd832db1732ff84d08cefaf4e3e9bfbb72357c404d5721ff41cb7753b88dfa3e2209d10795200000000000000000000000000000000122b23779304cb6b46bc3417bafd9f5725309cffe74fe4b0b1daaa866594b8cce40d761cccc32c2e8991955dbe046cb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca71ca2b92d46b65ef609d058c3c7f2ba1614753da04fc98b0e75ecd3b701f397326058804c3162a99def024d9b99880000000000000000000000000000000015137873e7a55712fbc20c7875f599b52bd20ff8140de5c152fcdf38aad4811517a2a0d1e4c4323b98c569b37eb6901400000000000000000000000000000000080caadcdcaa4f67763f120e2903071b7651eea27fbb4ebf693651fe986ae63a2e409975d65df7b26b302ad17628efc10000000000000000000000000000000002b082b2cef0a5e458b0a498f021055c1df325f829e7770938bb85ebe59c55011192e8b0d89d70d54760c3433cad19061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110ac8b1d632cbf5ff24b13be7be786641a93138dbf10da4d0d8d64dfb421848075923bf928176e7eae4515990bf0da9000000000000000000000000000000000c76aa56b592213e39e31c24c5183c7ce5c5b9f90f0f69637e1f23da8848e802efb0a579273f329e841b95036b4423bc0000000000000000000000000000000009c74f81ce87f33f41097fb21031e4e332c5eb0539b58e6dc5d8fc780f434949564ac4e5a4b362c565f893942ee0abc9000000000000000000000000000000000d8069dde5a23fa45228c3af354a55a9ebd1138363d1e08f00b4aec37b606218614bb62205b5d28416aa24e1f9b435fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168bad83d30e07baf51db477b513955fd5dcebd46233b36958baddabd191fb02556d280cc6f2bf53337838423508f438000000000000000000000000000000001208bb4851ce728bce46afc4889a9c90340bf5d9093d84c1cbc275114fd478455773619e2168913cfb77eadeecbf049400000000000000000000000000000000113cef76c69edecf152d69ed9c2e402174ab8100141ee041e90ca6b64af9e14c62da0b589a8c461ebbbee6ad276fe67b00000000000000000000000000000000109acf09c71e4c53b15957073f3148bc719d22252996bc350f8f195f7324913febdcefa9aa417ad8993faebb50054e511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000007690d3e54ece0c6dab5d93090807691c391a91f63b9f05721373d2eedf91cd0c6372209383785a25b8891e5cbb1a4cb000000000000000000000000000000000e01ea6d7db007525fa4563493ea8b1dd793ece30c82ad6672bff6ce95ed270f0ae74ce6d02860006c8f1ef7298899620000000000000000000000000000000006fe092c18f6fcd48d7028e1b3f73bf4500b22453ed16f346e1a9b806861f288298db51d8d9a7ebfc0969f6b33b4b2da0000000000000000000000000000000000715059a9f4f325f23fb59c655b0eca4dadbba891249c6f3d0258c14f33b2fd36b7e708b98ceccaf8967eae9c8c1af2", "Name": "g2msm-18-jwasinger", - "Gas": 264060, + "Gas": 285120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c91bf16071c210bd2536006eda967351e05136448c5d117c5cbb1688a7706e4da9db374b1de6326dd1e51bf44521c1d00000000000000000000000000000000034d41776748962e7e90570ee764c555d2246c02a25c71056db7db526b07355fffc18c0fe6a63822a51397a19c4b5f6100000000000000000000000000000000026282a86efe2f67d7b705c31a432d9751af03c4dbdc0575c2052ccbcc24fe8fd08874d5b9db7b8432c8375902bbadb30000000000000000000000000000000003fe50bed667d6446f8201bdba34cc92faf2760dc71d0aa0d13992874d74745377488eed34874807d08864d14c0683d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b1fc64541cde28fa3ddd640a33d2d010a65af5d0877a759f7d96c07ddc34469c2ffb4d3b22127d9b88e33f6166c31f0000000000000000000000000000000008e61926c9beb2b61a33e2331ae017d2edd5666d977301a307ca2688066456f846461f60df878056f907850de48d96ce000000000000000000000000000000000b03938811b993f6c5e61f7436573a642539b001628463ca899585c76633bc312104ad276dd8ef38e0711f33e02f2e5f000000000000000000000000000000000511de2e37e24388e0c35cf0014aa305456c4ae7e832c8788cbfb361ea4bd2b7961c871081f822a488f3a7d80ae5f6041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cb69ad4e9b3c07932626844faf207f70d6a4ad387e97d584c0120d2cf71811c505d051efe796ac6c2afe5c8b89258f0000000000000000000000000000000004524e95283bc2df58a3df1711286908b4e6715ae78294e2777960c314085bfa863bee6bb8100b58fa47ab9bb2d3d5e5000000000000000000000000000000000e3b36c1922c77dd0d6f1836d5167a776f29b06006126f86f4aebe0ebfd3239c685fff16fa517d58c2e3bb52bf8010970000000000000000000000000000000002235af179058e1dc3343cae012b9788baa21457a846e276baa10b8c21a598aff439d44bc5c0cc1c33b2f41935b5675e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fadc8f674a9e2c0fe747583f301c23ae9f9c7dc39ab78c80a54ce2bb38d29000dd085e77a7cb7d4dc3b48321d7d2ef3000000000000000000000000000000000439234058aa9b405cc364087ca30784521696700e88ba11924dd90c675b740641dd059fd0d780880d8e916efc2475f1000000000000000000000000000000000fe208f0274da997e803ad54051aef3995508b46439478c03a4626bcef7716ae8c5d8310cf2794f4267c823f6f4aced800000000000000000000000000000000009d280383446dcf7f5242332848cd2bf2926c11eb51dcf17a3be10810fba75b55e3ea9ce9bea09ba9258b3f3bc92e631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c2d912d5b704077d63f16b64aaa8488f9c287b545a5a28ee0794b093a84221c14bd2187c7292450fd18b5877bbb46d00000000000000000000000000000000093c34af567e20b280ca71023dfd63dcf0d6b13f86c1ed5635d4970aa51d15023e9a1499094a81497de6765b2b2c60cf00000000000000000000000000000000137ee6e7169a7acb41ada9caa07ab4c0e4a3cdb5da3a9e9187c990e315c772433609e84eca600e07303be15cd66ff3ff0000000000000000000000000000000000021461bc73aa216fd499b71581581bfc909638d358aeee8d0959aa9e522c90b08d0800d0babc2b62eedb09f5ef72961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e3d9ea82df847002f31ccd13eca5e3a048c74bc52a8a44113119a2c61da28c186e8175b6400ef8d6331d189ff93ae6000000000000000000000000000000000c42b746f98a83238fc5c1c46c53edfe7d78a71071f255d42c2080e6495fba8164ca7cad2cf609f3ca7d28296b7d0e47000000000000000000000000000000001240d63ba7b36bd6db5dc681ada6c70315223631c02f17f1459c90ba7ec1dabc9b67d2d23812c367d9b74814037604de0000000000000000000000000000000014ccd4da05c7118ebb426289e45d214bb940c43dc8e72af906aec699e96826545f214a87fa743475a7c4397d65a740f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014be2ac2cc81d88aafce14ab6e2d0b957edb01c6eaf88da76dd4fa08d7c4754d5cb290f26e96e2c3f3f159340f2dbe360000000000000000000000000000000000e692f453e2568b88f22ad857032fc8bc91a26ca19da612fe1050be7510366f1143d57d6011ac7f927cbf40986002c40000000000000000000000000000000007165af45a85c1cd182c7bf81bd88cc8d6e461eb471acfe357795b99e8fdaf5efdefcd2113684bcf27c2a0fb83fd3fa00000000000000000000000000000000010dc9748f27e02f4fa0ea743908b589a53a75e23a8de853898d883532d660e0c899591a0f7390e02c340b7d8d3dc98d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a1890b4d4dffa5a4447016ae85772c0bdbfec6c5d26be7677714af485ff59714d340a22052f2698c1837fed5515b1800000000000000000000000000000000072990f6c153e3a4a5749eb17739336d433f3668be36cd186d2229e0bcfa9a1ea70befa3cb5639d72f6f2e5f34f79626000000000000000000000000000000000bfb221684b2ce498b5199a161ac1ce04b8790c15ec5bd550bb42df81e64205bf5958887a4d89cb21ba9185ad75f5cb9000000000000000000000000000000000d5fa435a1739ddfcaac1d5b3c14bbbd78af3612903473e9834a52ac2ae5a42027182d52925efcf7e700817867b19be61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024026ada856aaa945fae34944e494022545bdf8bba383810c68d15824d0a80b274a0a46ae8c1241385f975af9c3e1a6000000000000000000000000000000000427e0dbe0878f7478f885c4cc5786d3e2ea5149cac6d19beaf903931affd277a033000fa95e11bda7ef3f5f3d729e1b0000000000000000000000000000000010683dc1fd8b4bb10a0f6eccd6a2795392b1787602f5593804ac0d30d821c6003aa9369eff358ec28f367a6d595ef419000000000000000000000000000000000fdbfdee49be804da8ddb8a5460dde677c99669bbd344606be6dba6a00001df826527d78608daa041fedb600d6d32fbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d0ee130af57a0ab9f28e370dff9aff4cd96c98ee81b11f6c0eef3bf04fb3795242720e6984c96ffba1aa2d46c55fe500000000000000000000000000000000154c7802c70aee1fa597c413cf598c7f590cff095cc54d635b36086cc81f56bfb3477b70139579298f45095077678e5f00000000000000000000000000000000108ad6d3ae1d2e0dcdbdf17397323fbc14f0b48c1dbeb78dcd91d03695aaed3d1df15025f0dc8e262931ebc8047e57ea000000000000000000000000000000000cd0950ea8964c285e0d59c954625246b2523efa09bed7be352625fe9669cfcb73ef34f40e2ffa72e7ec638a3aea30601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1a0f0f572d2157e275391323b94e2b2dd34dec5b8d55d046db9af267ded4954d69c2474ea41c7a9d184ea5666d2c2400000000000000000000000000000000096d572953a64e9d40b1c40d43b60a1e807b22d5562cb194374da03c2570a29448c7e8f06b73bd31098d794858c6bb8b000000000000000000000000000000000465a2a55f415daae86e6f6b9345a4a0fb8b9d2c5834b7d8b23a5c89001a549e5757a3bdf336aef693f30fbe8614162c0000000000000000000000000000000015fa5ebeb480bd25dd0b8c4ca0736b0027bf38c54c3191d591cfc03b1d7214fb976cc81669e049fd63938f07d7831cbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121a45ffb7266cbefc77f70ccd2980e545ea958c8b1670c899aa5cd796f1c0e67756ff64f0c16ba29321b1d7739df4b0000000000000000000000000000000000951dc5539a1a3aefc8e5d19c12a0ef501b980f0cced470a5a7bae1705d451be6a37a0601132f470361c89d8fdb6acc5000000000000000000000000000000000552b54cd7c46ece6bb050b6bcbc648a72104bf9a6302c33e34b25de9edd9a6c1c6b16cfcc72d9634d1691fc0e7235470000000000000000000000000000000003ace193ca007420d21e327ee11e192b76f1f3279edc95abe8211577e0f00aa42c20b5c98763bd194c7f6d8ff84e8b6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000862deee31a4267b28f68c6b4d8072fb96649e813058835099e6f7e0089bfa2f65dde0ae39f26f08377d3462b62d4535000000000000000000000000000000000e67769410a7d83423cf56816b7b9c16b0bf7cf65774430a7e5b409971b1cf3eee0d7610e2a83a18d202c15142e0bf070000000000000000000000000000000016911816e58f03c5afd11b3f594aeff05cecb58adfabbce0ab3ef9518d8b57c56914c7da80f0c8dc694405e4bf0e72d70000000000000000000000000000000006021b3c75ab2e839e644f79ebd78dbeb6d981f7485a3c3a7785507f8706e31d268594c7ca3758171723b3f022eb68791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f60a8ac58cefaa986ada5161559f76f315d4a3941926f6039fd42ad046ea4b17f555d645e30b9086fe0ac79db72d73b00000000000000000000000000000000136d02c317e369484beb6f8ff5bbd248e91697c911ce7ec86138686d242b49c3612b26def46b689572a37ec8960053ee0000000000000000000000000000000009eafd39d08da0610701a51742c5bd7f445f2f3f0379ad227fcabdbadb5c96ac962486c32e12a98b68922a2c019a0311000000000000000000000000000000000a688325c3cb618324257308ef898b01e39b740efae721b748ec705fc0b2bd53e4cc4ac6c0307d0823c149203d08cace1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127ee5548f43212192f8e529605729571c2c331dac3a68cf86ec0ad79dd59edbad5e2d70c8d5152cd80af89bc63e73400000000000000000000000000000000018cfd9991304e47c4fe81d116e55ce9b1dba7367fefd654592e739d6269449a34cce78a29b26afedb86b2d09592867850000000000000000000000000000000007f0acac9e1a56123a261ce6b0199c07b6df27974b6212a4483185a4e9cc026dde4bf0ed2a6a34e46a31e62c663aca9000000000000000000000000000000000089e1f4fd8fc4f640729f44735991e5cacb3a1dcfc66799ae6d75e473a17ce738f1dccf55cd3f1ca103f825f277c7cc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e2a0683a04828cf23330a34a0d83da288286cea881bae946d84538cf7fff827bc46b7e7efdbfd1b8e97d8fd0969f0d0000000000000000000000000000000013a5de76f1230656c9cfb6a67efa77148947f2c03b98b58cd9352265f182788aa0128bb8f022f0db290098e393231d050000000000000000000000000000000012921b5ebc6a93b6e408f4c1c39a949a1937f79376cb4b10264e1313c62662ee5a638be4bc063ef0255b66754dc974fd00000000000000000000000000000000123e91bc924a36ef4ced5f4bcca7e95ea3101689d211d67176e3f69ef17d59ae993ded716adf4a860dd26719d1c722bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005024a8dc8f20c6f9a9fc082d79ffa62f08f658687c65baa99d354cb70690b00e3fe94dc98de823441eaa17ca92ccf9700000000000000000000000000000000196fc80d0ea57973027f2e9b30de3ffced35108534b3cc93a9425f9093f94b47836b81c3e6740a2130b155bcf8f3c40c0000000000000000000000000000000014b67f4b6dafbb2f9965d9bc7c5055c05c9662ccf6e4384ca68e2915502594c31e75ff5e37bf2f2f739ca1d4f5189baf0000000000000000000000000000000008dbd838a78bb3a44d26670c295611de82531c23611377775411a7897aaa06454a63fd70eb4a8abd3e40273494e396911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001025f0936d17d59f6cc4e2acbe9ebe5219615d319ec8b275b4bb9f5797d995932905d9399d4f3217603d8eb10a6ef48b00000000000000000000000000000000037402cb72cf583e2240c1f72823b98b76c67aa670733836f4255a0b132012ff86d4e0fb11d675175a6ad893f638671c0000000000000000000000000000000010eccd435cb96983304b01fdbda592b621bb6987234ede0260a16a5fa0fcbbfe48bc9c252212087e09683eb2f7d6ac970000000000000000000000000000000012218dcee30d14117028de2334c5fee50ec2023fe1c7b92d20acb7b1e7524902eb6f6ea4a3ac933a7b693801225ad1f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a666e5a713bca8f6899b90888085ca1f8a1b15753f58cba354bd30dfbcc6a5ef8f4b1cf869892bca1128ce06ecba670000000000000000000000000000000017de6a3422dfff948b2cdf00266e7e084de96422aec023d50383b55dcee605e469d8179789c96db957b2e9081e2d45a60000000000000000000000000000000002d935542ffcba215be258b759cdf34d315022327cab48a669bba812f2a307a01194d88a37f4d911d5a911feb95195bd0000000000000000000000000000000010d3adcc9dc1072da84e2225b5eadbe64b3a7d3668786a1d9b8b0da378ab47f55f0ecc439ccfd80f323491d22c0aa9ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000ac45f63bc2426d934848e994fcd07ec5353eff9debacda0c9e73f94b90cae7e8ce658d8b6ac43e001f2381587f29728000000000000000000000000000000000726bc1ccc50a031774ab909dc13c8f90829bd187120319ea5f8691279632c55a3f3d0a9f85ef35206b8eb624537e06a00000000000000000000000000000000119a0e0c1d5ad07b72313753605dd1845dca571c4906e9eeeb172dfb7197b177989604c01ddc8575a254801503fa5edb00000000000000000000000000000000146a7ab3b15a558d91e5d8bfff3bd43837ba9db09f09c58c4007c0d42bdfee962ebe5d09423a67d49cc0509d3e2db6e3", "Name": "g2msm-19-jwasinger", - "Gas": 275310, + "Gas": 298822, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000148b8cda14be26000e73fd38bf6f5f6363b6ec3bbe23e7d54688483f31d331cb8992e45b71220d78f45045c59546c0800000000000000000000000000000000013ad017bb43a34bc478917cddb29eb9de0a6c02ba18afd26168a4f627dc5e35784428aea23cd4050a57d8ddece5f52b10000000000000000000000000000000002d8f0459a0bfe3235bf985e028297017185c83384debe144a86051957701ed2078aa8021cf643063e38de97bd7d06900000000000000000000000000000000018a837d7ba86539449e8a0163cab22ea0beb3dd56a2c163c84aff64b1c7b2ea291d687c4b14f0f9b66bb760c23897f301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193e5f6939fe4e092a7f74072208c815a91743063c0e91158824f1761d250508095477813270a30b69936cd95857d9ea00000000000000000000000000000000055143a310fe4e1cb4902ec611790b859a63de47702e7edce614ee82b74a024c12ac7755a43c64555f545774d2fad240000000000000000000000000000000000bc6f4c38059a65130f4d104285dddc5d4ae2aac4515fb5199e3c679dcf2c20da5251c93ed240a897f37662225949c4a000000000000000000000000000000001018c9bd59938df5f95ab82df112362fcbe7c17534c74c9c3ccd9377ddb588e3ae5a5c0bca356a7a7e5a59fb6b627f391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9a3c19f426c642a26f3d793d609c2a86311e3702c2fd9542e648a64c6570b97a83b0582392b575c1ac0df1297709460000000000000000000000000000000001dc8e6013dfef3b23943e6cf756550e197a400dc0b7132db5f863a51e8f80b78ce25cb70c8c59ab143ca5266e388b5b0000000000000000000000000000000008a02c4f2817964a4d39fc78c102445d9a61bc5d6b5bb2bf883537f56414265d863df173bea34645f1e75c3932ca485e000000000000000000000000000000001256a12c75ce894d69e8454679d753b348c4fce2174848cea041b8d8c14ab169b999a00325bf48e5583ed3e628e9d2aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cd0ec3445f279cad52433bafea18679d0f337054d02b7dd14608ab1955320001a73f54e5a46f56ff3e9692e8cf9a0a0000000000000000000000000000000002af09a6d73fb9fedb74c75f3e164adcc565f0e46c0aa3010a2af82bb634c61051ed85b93f99269f4e8f8c8bbbc8333000000000000000000000000000000000115f7eb05b3872eaa27c5ac4f29f02cc9978169e69d94ac6c2543e7b363046ae38c080ac076d32b1ba48d168c3018b0a0000000000000000000000000000000017f6a0e9d3f1e9989543b1a0ad2852a9c140facca300feaa124eb73ec85b7da627fa3e51c5f8ba01e70a8abc36dd88201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ed7e1acac29789aa95c94a129d9f713ccfcf6f0556a6a78b170cc22a93ed9a6eab92c3a491b48f6942e21e2e318a0b00000000000000000000000000000000191050f1993a031ba286559964f9645efe8d050d6a4b7b5395645a508be3ee9a0080df7c6725d70758c2af623683b8410000000000000000000000000000000018302c4c6ba7874aa0ec9b4da43f35f55a4e0c48fc9b62c47b77da24966228499c99807965716efcc17ed0276ca56811000000000000000000000000000000000d33ba1b47da75fe1747fddb27d8f619e3601bc23eb9572cd0ee2593f59b968b4bdf976cc9dcda7b892e1e0b4d24df0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf42d6d9ea5c339b24e16e8d3b4f3f41c2ffa95bca3c607da2f5af709b2d720c3f9f2f4b0fd1a3c01b483d194f13b9b0000000000000000000000000000000019787ed52be8ba34299af93d361fdeb2dabc58468056fb42e34f5f6c846c8ce527556b3ba746805aa7edc57499a990e2000000000000000000000000000000001497374c96893f08da5b90dfaee78d4ce4082f2b18dc482feda4070de15e1e4ad791ac705fd579e2448daf2d1106f3aa0000000000000000000000000000000003f89d9b704acddd21bfb1e4c0338230ee18d8b9c423a732f6a58776d6a937ae1da0a1a0a7f9a7005e14e13ab0ca9e481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000159a5b54f953c591855ba624d478154575d59c8846e00372f2453fa2601b3433f751964e51cc1409c7e96f487b37a880000000000000000000000000000000000c100c5b8da9d9bce8f50e031dad674f1c92c822b09a76cd086b78394d9790b5b6a23afa1f61cee066b0041369f5b8600000000000000000000000000000000068baaf40e36e12e2932b799c4422060e71f9142903d7e8492505228bb412f9e31c1a62368206494846c274df4643d3d0000000000000000000000000000000014bae9f6afbf3e5c8463d07cabee017794799f2a9035918f1f50d9ecd1179179400db98c030e4ad491c67ad12324db541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031ce7aaa496cb2021a57fa45f965c7f03b9f262f69072ffda3d9468c5b93a104c9b70a55651b1ecbb2e450041bc7d8e000000000000000000000000000000001222937b7f479ea3ec1af8c3194aedf561ef8508ac32f8d83105719370fb329c736fd9031f630597d3ca34a8520de6f8000000000000000000000000000000000c72a1737932a5fa47f9dfcd147c390dadb90cdaa8ef638d49aed6403c7f317bbf1f8180c17f2446e2ba05a79624df91000000000000000000000000000000000f5c314bac423a7414f97ae24b2eb499eb1a6aed5eeda0b4e8a3e52c392feabccaa586b8c793ce0a8dd2ec57b12ea9d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189f35bde68355420dc313ede7bddde6da4134033d08dfeb20d2177732b8c935846d8863d8513e02f7f8276bbf9f9df0000000000000000000000000000000000f85b5be789da2e739d08e885b9cea05c43da75096742cd947a80ce34d7c92bd7192875959d632b95e628f4062f408ea000000000000000000000000000000000949a909353d639529a1036c3811b63aac0f1e3bc0f0dc7f757ea2e79c82ff83040163c1511f4d77c4043bd6b29752f40000000000000000000000000000000002087c2aa2ef4ec5703205acb991b8aae33f33a4818a481a56316317c63296e3a2acf0d3604d00f84e6d3ed0e4da089d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098c85d6098e2e3cfc54c17bb4b00698deea5bc7f04018e514fb162398148cb81af8e0768d528fe0853426cafc5d004800000000000000000000000000000000076ff0a79e54a5fd716861d60f463534d3f9d64115ec72bab2ed6472d0fbd52face7e79d0c63f581e3978b84518fbc44000000000000000000000000000000000c2fbf304a4afee5df499a9040ff36b2358f5281218b6c884021e481f1b0ad2c480b3bec36bcbafa92b235cbcd6de8120000000000000000000000000000000010e8ff204ab55889910d6cde29219ec178d64c78f321f4a4fd98633b661330a474f7de7e0c91222ca5af7636c53416d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fab00a8d97972d3719825ffbc3cad064bc6a88fb4a2df8956c780f07930b20214aa29b339254fdd533839113a90dc780000000000000000000000000000000002f60f27634587c7b567516be673cc5fde7e4e77b00d4da7db2be2ae193d356e101e278d35bd49e114a030f8affb6e3a0000000000000000000000000000000012314a8014346575107a0eb34f7eb359d40e3b7ed29baeb5529cc73f25a151beaf2e3bd0700451c56da61caea596c8bb0000000000000000000000000000000014f9ddb4a24d4729684893936a27123398b340fd96aa763819f4966569c4fa422727b6bf035ce7b399898b31a23c5f3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d1239444f495c61e3d6b3fd727fe7cf588c6127a0bfd5b3fc7ab9bad9b101c4c21790c7ac05cbaa17afb997dff5310000000000000000000000000000000003514e67ffb9c0b317ec0da5ba6d8893edd3bc4e76e230cde3de7d9c05e97527accc90e1fbabcaccf6f0f9a5a96f56fd0000000000000000000000000000000000da40fd0bccbee905f7e0f1f1e3fac02403ba83a0a3c15be1d3f313aed30feca69907c4d41277f7ad619bb0b3e36f6c00000000000000000000000000000000063f9dd09573d73d89bb783d939fafd6d1b333797a64607985d8317a1091fa4ff0464b7e8c6fcea2c4ff1bc5456a78831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000655d886f504d57faf1515431240c93c4ba13a04754a846aea59b8a779886d1d9b21182c55891018a2c87da722d3a14f0000000000000000000000000000000019ec8f737643ec3cf9af44503cae1e8e5c8028057103a62a7c3311057d208c6e9a06e80b09c63a0c7d5329b7c79d15900000000000000000000000000000000010a504bbee291b5bf5745a345d6a145d6d0a1ee614635923f45f8907dcd5e5a5f0276ce50c27e474d91448a35205c5be000000000000000000000000000000000b345c67a5e86d0b76f9a4e8312180b9dc46ee82208b7973a8c4de268200910bbae6a166d1a032ff0476d4871c1c62801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d34cbfe16be9cb89e4ca692fc9513976e24d8f826112dd93c1864dddf5372b9fde11559e0f17aefbb1b7b84932d3689000000000000000000000000000000000d4b1a482a504e2f47381959c2e43756639a1cd9ae2db035ac12263f040f582488598c2de0affed7acc255f0b2218e9e00000000000000000000000000000000161a4fcd013259e6a65a9d3358d756be6eab673256a73c13df70d4b7f5820b5cf96c3fcd6f6a20d393a3b3f76fa6007d000000000000000000000000000000000603fdd5d73f3d57d5e84c1d7d70d50bdc006df5f30a9eb990b243567a2e05b0c92351ccc5bb6e4049b4732eb9574a461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f75f8bd3d5da8b57b30085bd5dabd39b44c871c7b11f2099df1a86a2af3d963896397c523b7ff540f6e090da10d7a2900000000000000000000000000000000190abe7d06aceb09c4d0436c27c7c5ec5fc7aadcc223412bb5f984a3341148829b0fa4c4bc4eef506c2a91e8ca3012690000000000000000000000000000000004cddbc5d197cb038a32f291b154e57292d471f906dc786d2a7d185ea1521ff6780b51142a4db4e91057fef1ce1285ad0000000000000000000000000000000000be8608d4344ebdbab466ee582ee14f873f1490b6763d1cf10a3d6138b2ef0e95d4f854048fed396a217bace73fe1291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d99275b0cb9e093d87b76f7c7a71e15ea9822c22e7cfc4f0864737143d92e5dd3101bda4074de326b844347761c06f0000000000000000000000000000000000f7c9b3030fe62c02ff067e23d9e8db36052b2746013051aa118acd3cc79a53a8af5fa016e72827a70e08c9c20c5773a000000000000000000000000000000000a915a8a18f1a2e43133b88515e645ddee5e99871ecc90f31c1697670765d892445e347f7d1765f48d6a27725048dad40000000000000000000000000000000003246e960dfd5644743e0654a65a755605f28f3c8bd679fcb9d11ffc67227ee4169d91b18f947c3507070eecd6bbfba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000309ee42999c1333541620f60dfef1aa86e2dd0048173bf8739d116d3912cc38c852a56c15c2bd4a07edfd9d9673d998000000000000000000000000000000000b42acd7799718e6dea5bf2fb76bd9dec576e9ac4f61b92687175362aad0256c8ef845167b4216bfae86ab029390d7f10000000000000000000000000000000005008d39e608f4e4ede942db4654bd14b7ec8def70df20dda982fbc8f0e69a30d2f91adde2b99cd8c468d84620e2df7500000000000000000000000000000000013a39a75098ef70f1f89e24755a708b456997e5d44ce66173a1c1d43366992308f72c7c88e60da9f9ee1796773170071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dad73f84474b92f3a891918925528e7c81b7773cf88890ceddfab0b3c535a5f0637a71b27a6c02ac964998e56154ac5000000000000000000000000000000001196b0c9577a810e33295f5625faba44640486f4b46ee744665e66d271a04383979f69fb68044259bc327e077f99733b00000000000000000000000000000000181772b69f3c8bb7a4c4a8beaedf29297b17d7920020e57b04b58cf8e3e20b74e056f5cdd4de775963f6905ebc0528300000000000000000000000000000000009638b56b40e2dd2857c7a42a341f49d9b32f5fa861d0802fdef175e38194a776db7e9b58023b6cc1a11e283b59412311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e26d1c036e1b0437ea51f331a78863c57267e5de8f7f62d437ab3db8df80750ceacc64c27c75061cc6d3148e419c0de000000000000000000000000000000001413dc9007ffbb3a4ff36ecad179e00da24f49fee810f73b09ce7b219627a471a5bec302f71ba003e8c5b9a3c2789d360000000000000000000000000000000013fbfda0ba359d71604676c4809329de14509e7ff0a076b818f30985579d37b097608700f323ad1cfe1b1525d596df600000000000000000000000000000000001c25db3ee3021ad7a87e6225339f2ac5b8eaf1151a86cb9934e852866432bac0a047da92ac55d26053b03204a4d18e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d44f71bf6ff77fe7fd692213dd2d554b0da78f5eb38565b36ad75b341285a3e8fab5bb0efb5a65c7936c50345f98d70000000000000000000000000000000002b7b2c5916280b9882754f6dd9f9509a9551315eac9f44006115abd594920ece186d591304dfc23211fdaf2f306a7e00000000000000000000000000000000015bffe11fdce13627f1c40c04b102bd66777d8b2ddb430caefb6c787d9323b87d3504d7c7343f9a86598cc7e4a72102f000000000000000000000000000000000948c6669b9593b2a1083aaa6232dcdb25dd2e56b3312ab0aa0a6a226ce5f0dc1ff0fc5917605483bdf071ed2b376b6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000101fe94fa6ce1d05f7c86cab15308d6c6238627aa7666e82d65e8d47135eb27271ac4fbcfbd3c868977e0b3074c48399000000000000000000000000000000000c7a99db64113cf884eb7d6c5f74475867bba483ebcf7201c90e78d54cf652c1d0225c4c3330756f5a145dff43200665000000000000000000000000000000001439d8413d0ea71bb350df353fd3e11309533f7330018a460b5b2bcec56a5ee768aac159d44b480e02853c9fc74f951f0000000000000000000000000000000014f5eab5cb3d83daf0b7cb9b09a08f7d1c8a34c26fe60bdb656907a6a0d921ef70af098381b11e95b94685fb88dd9236", "Name": "g2msm-20-jwasinger", - "Gas": 286200, + "Gas": 311850, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d39a25a214788fdea5584867a70913b76172e4b2a1e189fa8b6bc2761a5c242efbef62af940e3e094fdebdfc41f167500000000000000000000000000000000115d4efa0fe0c68e0fd4d05a577639bdc8c228f2fc725a4339203236c49555929d1a5cf5c5c1629d998688e1775c5a620000000000000000000000000000000010376622c7b197ae58cdcb741b337ecc712c62f7fa84605cb2ac1a7e8a32467a83a5460a7e516e145f1ab1385a300be900000000000000000000000000000000064af86fb8f9d5939874a1afb6a642eb9f3a9e06574bb5cefc688bc30ce78b3a33f0d43c6f4f0d80416ae090cc03ebc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139d330667ae626b29eec92ae0b4cf8374a26e1058192c61437bdd88c85442942d7e2c37b3c09788bb1df54c7ca2fd75000000000000000000000000000000001871be9f24dd650763ddc222611b6404cc9bbea21ea340b7a6dd6b4fefc3342f34409193ef2f8bea4ba55f74ece8270a000000000000000000000000000000000f278f73c7268f3e6917ba348b7a64d0ee0a976474321e04674b765b5bbeec4e3c869e61a3f336c568fa772e7891dcb700000000000000000000000000000000133274790ff2cda11cd64a8b65a8a9ef4e0f5abeb9d5f49e9b9c01259f94b8d895d059011201203ab1320c710dd1de831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150a4ed57d2ae3bc2c1b03e5917665a9ebe58c900e81139f482892824fde86ccf91b5805182fe2f97828956c4e5dc8880000000000000000000000000000000012810a6931ef0e8e5ee3786b093575cdbce5edc12734b897a6b9548ad4bb18205158af64e800a43273a0e174f901a79000000000000000000000000000000000141586e1111fac7509c0a3a53a37fbaed126d7372097cd7b71ea30a5b5610d1e8ec954f868c8a98d2c37a304f0694aca00000000000000000000000000000000178133ae5e01f992ab21bd72d14df795ff3cc2b3d094149e2201be50f224afaa2b0f4b174cc4664b9768f383ff143e7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b73035aeda3d68f2cb94dc36ec52fc9116d601c133945e9049a5d5abc58520e319f2d8cf913fe3148592f3755ebbc5b000000000000000000000000000000001563a3151250d5f367c1fe2b805faa422d9d64e837be5dfcdd9282ff3c680b1d6c4661fe0babdfea456a7708b1e5790b000000000000000000000000000000000ea5f235859c59bdda2f2691783592b77a22be0ffa146848e7119dfff71a0c136c4af026562e8075e634df4d6bde28b2000000000000000000000000000000000238590423c229e5a438dcecbe1fbd5a11146ae3c1e5fe7def6e7207f6e0414e0c072a7b245604521ac35bc71c9951a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6659018a7c8f40232bd15c83dcba2aa412477711315c903c78f86b96d6e32db0a458e44a049dc5cc69db8ace9c6d0f0000000000000000000000000000000011e3493dc45a82fadf2ba02ea9860e61b20d6d0ae4327bad0f8b19f4a8703363f7d327aeb8bf3b72635294dad62f131000000000000000000000000000000000002b997f9c44465a398942548e721218fef999f1ce33c35f28ebbe5979313a21c11a02d4132f873b859b095ac34c6247000000000000000000000000000000001597bb4d6db0485e8f69d7631acbe7ed5768b3c6b3e5ee62fc1340ca6552c8885063b3c0ab0b2da91c8337a7e4a826fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114742609b293f5d0a2802edbe72f4493d43bfcd9ec14291724f067671c88f1ed2fef6f557f575f45ea863d465f989db000000000000000000000000000000000477e9694604e26403e6aee5c1fc2a38122c169ee3d5fc00dfef401091cbef2ff13296d6c954fe3923438a6795586c430000000000000000000000000000000015dbabada04bfbdcd138bf7b568e3d51b980b727a4f4d7e12f36e209e2629c9a6687b1871cb7bac70d7557d0161fb4ec000000000000000000000000000000000a705d0f03a2f42a6a236e0c51ddf4c7307cf03750638c4a1f2526db4ac81abf34607be7b130afc8716cdb889d5366321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000089f530739a88ffe4399d2b0b802d67f63424ef8d86c3c7367d04d9c92bb364d1fc2f8119385c33d8ece83a7baa74c500000000000000000000000000000000114c85dfb2f0fabe56cdd50ff499048134bb3d6565988d2f5cbebf04c408cea7ec52051669e0e5ca943849c908c6d1a1000000000000000000000000000000001420aac64a5660c7feab07e9181dc35a13c7bfa05fd60b0fcaf22339884fa71a518a10518ff4284ce3efee9851122d34000000000000000000000000000000001434b08a2121e59e522801045a80f1aa3f92e40fd823f468282975d1880148e01dae50f0f95535b702ce8ecbcab817cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113b776460e5e8c89a088efc50fe10bfa1014a6d56232319532829f11bb1cd3a9a72ad67e680d89ec9c80c0d5317bc970000000000000000000000000000000017281edfc803809453a01d4ddf7a3e2d7c7f282775e6bf64c64e776f09916842b9bb1fb4e3f3882f4a81387c156a8d7b000000000000000000000000000000001568cc939b0dce41e38e59f381a3f06dc9cd1bc6cf96a277474cabe918b430f17d3618e0facdfb8d0cb3e4b60f7b72b8000000000000000000000000000000000e3f5db953a5a53f73befd628e89a96dad3cdb0a0db3068b8160ca2bbafcfb45f6294fbf07a603398b4e010b0d28e0d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001983452b7c305ca10487090f4cfbfe3c5d750663aa4c2de7a7e673d7909601117bbe20c85fb5a9ad374b078436876e3b00000000000000000000000000000000183df904a871ac75362334dbb8ef9d2e4ace53c6ff87f3595dcbd575b55e5288ede43a13ec48010de6a062f9815f7881000000000000000000000000000000000b5a16aa669873ee0bc44bc41d77bc16847c7d4cc8fae9cf2a89e652b77732efeac2ed8e92c2ea23c1dd9b0cb6d2a8a6000000000000000000000000000000000d208ea376c4c3a811b3f751b3c109eaed74349b0b3fbd35e78656cb6835badd6bde3169e8a3e4fce5a8cc59591803771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124646570cb501af343db7fa451aef55069ef1d400249c7b19dfac380ac6787e4a92b6008af86b6b4f663bf93f3bb0580000000000000000000000000000000016b0ba55c6791218d7643ae750b800003d27bc6677d548e7425c10cb9e56063cf0734704cf04723ff8932b8ffbe87bc70000000000000000000000000000000009f47a0596ef35e028550c0825919c8ccae551b1a2ef85ff8a0ed7a67fbc172feba2d1c9099da6f3662b89db1891cf36000000000000000000000000000000000cc38ef0fac3f0cf0f5b48aa71935aa83fc89430ddf6a7c85c95c3083fbf4d46181b1e2b65fec95f55ac8d04ba86dc9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124cf45b64fa4b4ba528daec19307d92b4feb2a3e6846e92439b22cd1db80acbc40bc43ace22f801dcc2bfeb0764d03c00000000000000000000000000000000100d8cf3bc6a20208b7cf6c359efab17fc2f339a7cbfe2cee62877369c3e4cb1e371e892288d54edafdd345df8f4800c0000000000000000000000000000000006476bbda0b56a134261154c1c06a50fb322b31b094921dc7ab0d9e8c02784a2998996b7160e0b88386cbce2e8d42f8f000000000000000000000000000000000f0c6c1bc8ac491099afa7db7c6f7ebbe97d4fbe63da41f97b3bf20b77dd898d376d6097dd8c52fc993deb5daa6606071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4830a361ca30a0d8e5d0d15e2077a455d9c5573a268930c6d737344d30085ec55632ac91fba45bfc8e125a400b2bbc0000000000000000000000000000000001007213896f16df9e2fd8e8d1d569b77581a0c30415ad926103b49cb79fdd57caf0cbd948040692909d95a05662187d0000000000000000000000000000000001227e60229a3cb8fbdd7cea3defa0bc5ef5557e9c8cd41b9503319092b7ab1572e36df10d278a104720def0900542dc0000000000000000000000000000000002af15554df9ff55d3992e7af78215ea0f7e1959d2338b2b0c021750e7473a243120025e0dbd8b0f11b03807efd900ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c77b9b533616491f85d5225ab9817e165d6cc8c5ce03892c5bcbf7f7e7ca9e6b8a926c2fb90cea6a0994cf2dafee130000000000000000000000000000000018d1338f46a28083fb751312500a34fce24f423583a6880e8245b0fdf1cea4d68f239af7d781dc2b5db27b8a0ca53eaa00000000000000000000000000000000072cac4e346e8ddff9ce3fd6a15766e03288b7519085cfcae8d2fdf89308dec58663106660ffe5f923564c84c9b327210000000000000000000000000000000018f2dbfb9107af43d2618bbd33b4ce6ccd6045e3e2cc715253f404213308ddf05fb000d291061a82428e670e1ac99ea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000268ed056ec6fa0c7630d129d74b4a8826d3e40d754a4d7e4b10e7929824e332c8fc26fc42d5da72299f7699cc8762a300000000000000000000000000000000165506025da6ac77470268784ce3d6abcb7b10c403d2de773d4a1adf96054034ff69baa6eb8af2e4662f4ea5a423467400000000000000000000000000000000156f4ffa2e5caca2523c59dc9f7f7c2489895b3979b2daa31f8b9008da33711d778721d9fcb6fb43efd27baa17e6be020000000000000000000000000000000013007c98d5f43ebc81e6328f40b8bdb53852b20237faed89c4cf11afb8d8a510e91addb16906e3198e4812aa0d575aa31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ae38e4448a06b3652c0b42073dfffc4b2713d322df0586080d43cc8e01ae16e81569999ef35d393a6c00aad8a2709e0000000000000000000000000000000004f35418dc78dfae10be7e95c23df39c1cf33fd2a6f7db340b3208d782443c4c02ff963e455aa64ce05b143e9083c1ac0000000000000000000000000000000012c7091126dd9119b0d8ed1fa0036c2edf864342a693d8d2f44ff6a121b6f9c4249e2a54718a7771851eac9fb53cb2bf0000000000000000000000000000000006227458b1b300f3b4f6c9e288b9300e9247bdbc33fe06de22eadd58e0c97f140eee9fdb23b112867061921666c810ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e58c3705ed5374d06aea1b14dbcb8a3418147cb6325f39e8b249949ce91990519fa9f8e45ccdd398b1c77ee56dfb656000000000000000000000000000000000839cd9d0b4a10b0b22504886dfd681fae8b66e5c7ede7ee589d236d26f25b146aefd9e73c0f3bbf0ab85e10a49beb3c000000000000000000000000000000000fadddcb58cb45ea6f26b114fa1260a5a9725dfaab21ab3e016868ef09a106a75cbfacc44081bc18f8177510caa5bbd80000000000000000000000000000000007ff48e3d179069032a5944c5d6debc6c138c881651c92be73d0679962cff46b7ec33b934f646633e45d18de01e2a1f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be26a3b063ad70680f41812d645b60317a493c3706ea342067972eea0ce73dc7c9b43223dd9c99c16d03a7906d2af1100000000000000000000000000000000012a58625afd46dcc84e7495f4b691721893b6bda15e3ab29ec26e9d58d5309de4af910f6955a6ff156339d7826195360000000000000000000000000000000008435e735cc279e17d8d788ea4405e31b610a30d0bfb2d95c7e1b7c68f77de83de77423a2b72da8f504bfbc453add3ad0000000000000000000000000000000008e5158acdefd9bad46d8db77a773524530c013d4276d5a1146c7ebc3668c4644f1c30caa4f56b6911ecb0e19244bab91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001752b8fc94768ff1b283e49c15b9a9c1c34a4a7b999269a3c998b7d1f0044f153594e7ab6a647c530d8d2ead8216684000000000000000000000000000000000197d128fee889d77d8ca5b7fd759f86d70fc3768ddda49e0646bb493f0a670f84e1585e0c761b47bebeb05bb1f2ae3420000000000000000000000000000000005b3a244b4f6de472c8b49fa6f1a4e76f95f3469d95d7ab85ecd3b8b4b0f1aaffc25a3a7f5813802e506aa52cc6bb937000000000000000000000000000000000ba9510e0e2b5f01e35f0675bfec7c755cf4e945001c3dd4d2cf54c0daaf9bbd7c952b4fa50f7d2a3cf97b85162e12961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036cc22ca8f20a09460ed5da72468bb69c07e734d8eca32e9c9831142de3b7fec683000077e6db4955e971f4674947cc0000000000000000000000000000000008f6461e3e7aec375db4afbd8931cee2ffbcbce5f75b55428c34f4d418ca2aecde09e694d6a613e5a52847d150d4190c000000000000000000000000000000000b7c120d22959585e2876ae06ed92f95091d28999be71e2b692c4e875191e677ca8424270e419b6a2e77008a184656fd0000000000000000000000000000000001135942126dcbf4f0f294f0ea18f287959dda46524a73c31ea18b7c155a64d9bf908a564c535522fb1797ef97cb63111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181a429b07c620cf367096b0ca536b7c97f86d52a87359ba0a847b68909c548b8c30327c9857e71293bce838da140a4c000000000000000000000000000000000135b6e86c3852a6d7961f2bd7f4c5853592bc64d3842ea2ee2b8e088ee84af1f73de34df9c84bd0a352ea788758c455000000000000000000000000000000000e09cb6ac5cdd6046fe06f17f4622c661ee17d1b7d3ac39bd8c59489a187b0c857d0f5aea06c297348f001af350b241b0000000000000000000000000000000010248d6829bdebd6efa3e136ce1f9346929427e19324a1626ee537c415e6e373b8126bfc18643aefc1ef80c0071d3b6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a3a209680af4f754fc1178bbe7f98353d05aae0edecaede00b0c3b6db2e97636325d146286906096e333174c6c0223000000000000000000000000000000000c542cdbc7235badf21918d050c5b6ef59383c476362302221a2a2ac3991b1f0c10d923cb8a40db5e73f4e69594bd89b000000000000000000000000000000000464a7fe7e6ad12deff11477030210cf9ca5cd59ff25607fe16b2fa66011ec29f864f556219a586a138ca5f7745d227c000000000000000000000000000000001201087aeb3b84a41c2168798df567b8c09e71fc4b7261fc74b5f109a08197e54bac4a62173fdcd38f002bd27ec140af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000dd225c85f603cb15f8b19f0c3680726d6d096bbcadadd92eb074341befaa1698cf47bf83cb9965589b53e10193fc76e00000000000000000000000000000000042fb747be70bdcdb93b1be8a8828cbddb19dedbcb383ce417c25c138abb2d086a2d84fa3fe3d6b22ec97efc1588414a000000000000000000000000000000000c810d6b798644d14741635055bc5e3b79735985eea7bc6dae764d5290ab0954b86c2edc32b4205cb3009a9ea446f8dd000000000000000000000000000000000c0024c00b21fbbc0cef50bf2572e3208387c496f74a437e1691c94ce3a47d6e61345a81283bcec4837f3c8f37b1f0f7", "Name": "g2msm-21-jwasinger", - "Gas": 296730, + "Gas": 325080, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b8781c78411e83b994dc6b0cabeefc6bce0496dd4b02d1bb048f6d1c124af3eb812243fe49e16e96001e2b1a854c36f000000000000000000000000000000000f2aba4600491cc17070c314d6606db197a165deba2e26e5817274961c8f51b2bdb5df3bfc6ebc57243e684f0488736300000000000000000000000000000000140e9c7412da3284c6927f9abd69cb854087f48a874db2516d5f6df187ab7cf8c94adf2ecd328f1654be5ef406b031b90000000000000000000000000000000001a11bb463b2d349d2865d1302469daeff2078e7a0e28f5f60208701f49cfcfc8788618fa68f6f8a1bff98047e2e488d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6db6feae76582eb0ae8aa799876c5fd985ad37b54cb3ab758673b508c75b3fe2ab6ea13c068b046976fead1f844f210000000000000000000000000000000019bbc682ae9570e586cd52e2cef307fcb2e107dcd19aff6a13b1648f6d3f594def99a0e7cdf928e2338ddc38ca7eadcd000000000000000000000000000000000a789526f4e2930d81a190df174134bdd1073921215706dc9bc21b61cede1417d3e11647909bd601d78cd0f50c719aa90000000000000000000000000000000003be552ce382a274dec5b8e3bc8fc4da584b77dbee4dc7afaee856b50c992303fd0bb74a75a9a1b7886ba42c90c5975a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024903c05932d6fcdeb0767306df033b35afaf1404a19918c309f221660d987536993427609702f7019948c6a6afbd62000000000000000000000000000000001034088126b90c116f58a7ac6db4e5f2499712e13dececdd535bcf7b911100f522801c0592d7ca34d41011f6d54d92bc000000000000000000000000000000000a808eca3f7c1d3775bc2991dd81344e54eb066cdb6351e5cad71845753dc5597f8507d87afb9ad5c7de6002eeb1660a0000000000000000000000000000000001487afb91406d1d284187b8209d5d5fb58f0b38d22324d66a36d2d562f68af38d36f1a6c1d35346c8672d03e18b4a251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dcf3408622fe3e87910c4f1c22a7a827ffa2f948f3c0b6cb4d36678c4786acd733f1e12cdb6220bb61d65ad6121a7f000000000000000000000000000000000adb7fe6e7296f71c60cfde98a823c006b6320d9fb4eb9b1fa6d4856dcb8ac5b85c4fe40320e19df112bc4d2eb0e1a740000000000000000000000000000000013299080e68b93a62069c350751ab6a5dd5c8d8ebec1df4549a1f18b89b7395ed81295b022d554fb48810bd37a18b8430000000000000000000000000000000016acb9a1c265c10d8d6d2b1aee4f8bb67c52ea534ec80187d8acacae221fcc5586df92a026907c88600dee1b5bc9f1c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000815e455667ed67aff8ce2200f5ded020385e0746e1b68872314bc7ac9e1682fdb8cf69f48a1b65a2d6217a64833cecc00000000000000000000000000000000021c1482a976ecce6bde5a240849407c4e924bbcb2cf6a504c2ae952809115ab3fb34ae741ae2a92e32d0c3ce639911d0000000000000000000000000000000003d318dac2e4971427c12aebb894c138f7164492723ce4b319422b4e9adc7c8dcaf870e42adef866d7585b105d74e0d9000000000000000000000000000000000df017287bd512f80b4cb62633150e64bb41419ce001fbcdd1a273d04d7c64bc773bfa1de93550a896254dbcb8a777b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f4d8d97484d5ef0b41e33ad7368e1708801d418c43ede1932bfc660cf55f89f592a82e67b4332238d64786ede139b2000000000000000000000000000000000816a4a5ef1ab233dc6b8cd5d40066d27cd8953ab220a47745e27073c324af2b8a4a13e531d1ba79db42166f3bd938ab0000000000000000000000000000000001de3e52dae742e81b2881fb7da2d2eeed801df2d5d52f7679a8584e4be23ab4e7738812c8153c2128abf452693af2cb000000000000000000000000000000000d44da7bf57931175eeb3b0a0751f5e42a2f26aa9e1ec01d2521bc0b54c7d12bc6a783eb12c5bfad8c1956791a25780b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1c4ae2e37fe8f0dbeb08cea7ccaf428ba2738069494a8c6353beb14a1530272d17f8a20ce2a5aa7196a9bc20e7670f0000000000000000000000000000000002f0c69da7751d7917e3d8d1d0e4ecd37222f27d8929e3b885ad91d735b915271cc13ab2781d866f429b1802090c5a5e00000000000000000000000000000000193ce4b6ba605493d34a199e98e7e21262dc2989fe962d6009aa8b1f9e58e5043ce75fa616e165996f49496a3daeeb360000000000000000000000000000000014b32eeec7d833a6d437a2319f9efa5047103cc18d6ddaaaa17449395c25ecbff0a03020aaf0ba3a859d048e37467c111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1c90987486f88c8b2a91370e946f2a474985d312d783067c794ac2b92f394aa902058e85370c99324740f74a88ef0a0000000000000000000000000000000012b04200b415af8abf6abff7554f789da2533896f79d8248ec6ce07bc1dcbe66f8fbd154b0c85880d5ded1b0f946da70000000000000000000000000000000000274164ed8921d5623c92bd1e788ceb29cd282375fbbde988028a6def27dcb2fafaa4b1a1d21d20bb8b29b5d7772f97f000000000000000000000000000000000b57883385337edf5f0f96e1fa72a2b7157673b595d7e8525cc0402843a1ffe87668bdd2c2f8564ecc00150d0808dcc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000783188b04df2608dea14416ae634dceaf5c8d1496fe3e956a560cc4835d34ade4a7b28e7e00e43f7f74b240b26ee9eb000000000000000000000000000000001372ad6f9f9ba1328b01ea4bdc8ceef33d0e222049e16086254ad119827f4579233814ab4dddb8115fa041069a96f43e00000000000000000000000000000000054c387ea38fc362a4ed61f09210d00b699841ce86555a95ce278e61ac8f0a5e21d258a093d04b41f32751c29082779a0000000000000000000000000000000005c9afe9ee25fc0c237d0a6eac9fdbdac5248ddcff48432c2201fb114602c8bfece4b40093fe1d1c103ed36f81ae5e721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d83e3974a7cd31419e1421503e0a6b8f7f1fb00f39a25ecbd51bf2950f65d077d666e221c0b786e8e565b67651c178f000000000000000000000000000000001811efe5aa2e91ba296ef5eadf3ec41f80a698c6039bd13f1be6c54dd128f290b262374a4959423cf380f044fce59c1000000000000000000000000000000000195342d27afd5ef6dd1fa88841ea7305092ecee1d789fd7d148027fa60e0fa881a4c84dc2b94373716f55a1eaafaaa4e00000000000000000000000000000000033120cc5ca0252faee9505697932ed25da821790cddef920b5371fe102c92a407a91b356bd43c4c733cef59cdaf768c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000466179a79a138ee6ea87e83525bdbf65d3bd43b619c8e47c79e1baa930d2ceb4324d551b788e2a0d21e2dc0db33be3000000000000000000000000000000000120313a281a7305ecf80d91fe2fc609c9958e9adc4e8804ca686d5348e75bf7521e29c539153adb4d24c26c1745035f5000000000000000000000000000000000e6ca13544d7eb6bbbd8d7d0a1b852d6bfd3339e3ed28f3d0d412c048b05c6a4cd47779bb546c9330d618b953718a27f000000000000000000000000000000000a2671245938ea3bbf536bd720a667ec57bb02d7c60cce0cd9e1efc42b56185e99ce13cd95946889a54190a321522bc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b82769f03958450f004bf7fd0173290b61ae2c0fa898b2d5ff7c0b67d37fd78e6b405f443d5cfac46c65d28c87bee6000000000000000000000000000000001500c48bcc0030640923b2b62c1a6aa1f53c0b187d7d80ad2d60c822c74ef25f3744e616277101cb5d449e714bb037c60000000000000000000000000000000013d41057ef9dd8bea802a7e9a9943016307545f15b7929da36dc9c7644eefbbeb5aa27ae53d39715db49ac9dcccb8b9a0000000000000000000000000000000014750a69aa6753516e69084a89e305a23b2a9ecfcfcebaf3529e1683dc3aa8be0905a6a4ab616c0b10bdfaa5113a47211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009395af45db78fb3d959c19b106e3a792bfbb1d52813d03f712d344ede0208b90137581e4355d568ceb5493fe85a3726000000000000000000000000000000000730f7dc2707a1d448d656f1e2aaa764bbdd2bd1bc73739ff236d433a3f1ed8ba211cb9a396df2fedad8039c19522f330000000000000000000000000000000006031dc4f93d51c1efa4aa895d902b1886453ceb4c5746e9df96fa15f8c741c607a1540897aed955ea439367d365f427000000000000000000000000000000000d804efe22e55bc2db9066c82c9b26abac303da499b155bc07c6121e369f5be11a6f34c35f604c120553fdd65c54b6be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fc89e4ebe7b181578a07e3bcc40f6eb4c3d998abb13f12510f9ee4b37a63e265a155e2331bf78ef349d4a40222f8d900000000000000000000000000000000176d554a58c23a2b19b267b10577c78a44bc6000d638d9adcbc8cdead61521cd643810db4888a38f24ac02afc63c07a50000000000000000000000000000000008734821dd3bafe78ddf0cc20828dbf46b24cc3e8ef4d39cd4a45357525ed77bb2632b09f99cff6c7afc85950643e62d000000000000000000000000000000000f5e40bbb52c510e1ffbe42f35a8c845a50a2cf69238ab0f00ea6f964e4cffb0d23ba711d1b587d76bd81cc31afb81721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cbe4974098167d71d8a7c1a16350c6f510028be265d3ff3b452112f379b779ba7209ba99e8487d581ec0e97ad0b307000000000000000000000000000000000be87a4237380213a6f11752ce78704a95b99282b696a502df73f354e33d83ea1423ce2fd273836ed7f67dc7dcc93f4c000000000000000000000000000000000becb32187a437fdeb82cd7c2a34a3462ebdbe599849dbd2c2ea4aadab9a4d998aa8e83acc7e4266622075781c7ba6d8000000000000000000000000000000000f2aec3af375042dcac3e812618cf1bf6fd5368cae27615ea7bf56479aa46056a0d3bdf5c98a499b3295d696a289cbb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011aa8bed00b25bf550853f2b075e289f529c0d658fe3933acbeb9bee99918de1a3e6d9f9222e9fe48c9d83add14c83f1000000000000000000000000000000001887a7094663697f14067d525c28fca573a6f111f1e27f4e4a0c4020d6a21d430367450df8ae6ffe1686c2d49a33977900000000000000000000000000000000120e067b592929533aee3158882404493fcc832e981ea2f21f752af7f4b46a7b6d2e7da7134b629f8781653dee9b8435000000000000000000000000000000000e8c216b7d50257c0daf1099d8820be90a85e3d689545b3112d826a927498d501b56c98c32ab1a4f71150411f06e68611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d6339f062886fec71687f9a5001a7850424d7a366f8588e94d9ad9807ae439869a4b6b6e7410f961689e20be7333590000000000000000000000000000000002b6c32061cf3cb70f1f21531ffacc2b4b9226d35a3791602a0095a50c44fac67dd8c7cd708e0adccf5b443c71ac4d010000000000000000000000000000000016e78e3c098056af180109bbfa7d247a1fdab81fd02c083dc267a79a9186df02be730304bf544a12727e72cf8271ad45000000000000000000000000000000000a8436b14fee40e5d1614f3ab43a2a125f97f1e0ce6b3fcdf44ca0d37f3471823dd372799bff7e96ba674d22a2e0456d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000721767593139cbc8cd3c3cbfc0b50697d3b37d9ff557787ad92c8a0d72dcea6768fb883914135ec3d8cb1408636005f000000000000000000000000000000000198c345bc278efe6e0c81d7dbd6e28fa34a5e8c3707ee0e25d7dcc62e864f74655181913b5e1966b5430f1c6c79023b0000000000000000000000000000000005587de601e4d93246e6c0b482d1d6dada7c6b5b27f6b4fc56b99150ffbe7c0f092069644c0948b5a5bb520e3ed2c133000000000000000000000000000000000a9e1e2308123411fba1d812c1ff457cf2d6d86710511845cb3893fdf9cb69393388210cec426334d21e627805ce76911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017faca5f251941d73582ae287db133e0a57fae8f064021bdc3dda70fbaaa155d058fea0d1abb6b16bc272ed4deaaac230000000000000000000000000000000005615e24c9a8db48083019cd55317738e800eb5f1ef2aad8ee166ccb6e197f492380798255fdc300765daf2b9cc02e9d0000000000000000000000000000000004448b229a54a1b0f5783c38b0b888b70bc6d540d6029854a58d8bc7a22be4f5dd484f1ac712f36eb03fb1d831c33c75000000000000000000000000000000000cf1117d62bdaa8ab5e3b738649c64c3ef57909c9020d20a41d7ffb82f9c46abb865f95027ac03912716de511d429ed41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009173d831df901b8c85e739f6129309c81f804b7613bddf09267a102a55a02057d0cf7ef1b3f6e07a13969fdf264f8f70000000000000000000000000000000000b413ed93186f076903eb41b9ac5638e288b317c70ec09c0e5abffa3b376092e6e08d17f9967cdd95f35daae27d38a10000000000000000000000000000000013f19b6f840efeab4d3002dcbce9bdb3cb2c7fd3a47a7bb57937d268146ade463b1c0b1c246edc084d31d84283f8d308000000000000000000000000000000000a73ea2852b9a49821bc19784e8d6beb4bbe6f7a4b820fb6511b3a494d3198e44e5a8ea4ef0b64ad6d5788be9f2a30771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005223315fef4e0b783bffbab63fab52c1f71d27dd8ac1a85acf430eb29b81a51c21764961d1019c2cc4f1c4b31b1b395000000000000000000000000000000000cf89bc10bf946e0a74c0e21f3b3e56701790c778b51bd99a35f9b1b9fe2dece1a15573d3c9776213315126190f462be000000000000000000000000000000000020e8bce554499dbe0f4094ae2680f1466043d2dd21b84a90f3100b5b4d855632ec6ddc11293dbdfeab56e4d6177b70000000000000000000000000000000001030db39218d9d54cfefc38f41b9d298d7e3ab2ffd15ef33074d4a88a74966ff44255ab509d41ea30a393926a88ed63c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dec914f41fa13f1a61ffa7bd48efd3a121eed737000af4cb6eadf45501fd9322d00ad5f280e547d53f814f5ed867990000000000000000000000000000000019259c47668ac612ef14c2580a14918adb3268473940f0945c4e8a26ca3ca032afc8cb054324a021075807ad9b6ae74d000000000000000000000000000000000ae2b72a50c2aecab13cdb040041b727452da7d6a836059e49931471b29c3223f3867eb240437f3173cb023a5a3ee5470000000000000000000000000000000017248f40deaef2b0c64d40af50cb6f0223783880853a2e7ad39e20a60da7e18abc5efaf4add2d59a41ccf94f11f6aaf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000170ec5c26a0557810786be0b2ceda3b427e6d79d8950fd695f2322090f476f6eb94aa75f88910b42ea179bc76d2bb60c00000000000000000000000000000000075341ead4a03c50340461e34893fe82f8bb0144a4cbceeb6fc49f1dc7460e5a7dce7e8f79a8aa9170f7208b7273f1220000000000000000000000000000000007bfadaf2f7444c8890e8390260dfc5089f4b9880dacde3c30f02a8ade793454c4685fc4e88ac484fb54faa18f8f03920000000000000000000000000000000003c821fa013622a2347a90e8f740222d10c694ceff3b8ec781b6262077964313eee3c6733a3109171fd0801fabda4843", "Name": "g2msm-22-jwasinger", - "Gas": 306900, + "Gas": 338085, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000573dafe5336fee19fff6eb837c3c33f8a618365fc85e20737df081bdec328c796f4a038cd958eb93a6f27aede21658a0000000000000000000000000000000016240923f684ebf178fcfbb478e2b1a32e276a35a1e07b9d5ae167154d31aaadf59f10fd412654f68abae35f584e57e800000000000000000000000000000000058980853e950fe1b9fb7e6f4be5949fdd76bcea95a8a21cf42dab68f0986752fc37a11a186595c2395edc301ad469bf000000000000000000000000000000000ad882d1125d9e4d5eb533ed2da808321462f4948a46c945e65a3162a459e3d5c9d7569f4767cbf207a5f4e7b02aa2e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ea173e06b6a71341f802606f01c066cce64c10c787b08171eea333acdb343ee22982a8ae467e3142bbb048d5726e5f00000000000000000000000000000000061bd91dcd7920f741ae362372c2e8295e6b91d2b8ecdc58d1beee0e6338304c3573dad7336beabdada2b8b4f4f5b9760000000000000000000000000000000009794e4064487f8664138e4a238441f32e10644229806e779f8046316e0a9c5a7b2f5b46bd56ddbd70b2927e31cf60430000000000000000000000000000000000d123371104c4e592193cb56e2fd2e71990208911b7b26b5f901ce1d11e0253e3b7dc68650eff589a47d6196b5457171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113f9b34e20f2a1c3e8f541eaf1a610470a7b3feffe0fa293cccbdfe7a5c32410c6d9607b00bcdc37c7c99963fff68e70000000000000000000000000000000017c9e7ad85ac4cc2dd17dfcf8c2bf3310cbb16564f2930e619e31f870cce935e502092250213c58b8c07fa7c8f42fc6f00000000000000000000000000000000026a38cc01863f603184ea9253f24865cd1050caa6ac5a1bc415bda639f94334c83cfda5043533459883d77f61f9bccb0000000000000000000000000000000012f015d7d9b7052c9d6b61a4cc28866736ea93767713818e2315cd4dbaa9b0c6a0eb8fb26103c83041e59698c37fe89d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ebe96ea53e5765440d990112c783f40283df08450943f3ce441298fbd968bf4520d0baae2e19ead395498956c0f07700000000000000000000000000000000032a0df00ea111a501cd8afe935f8ec18eaf10e03c37a1f1a271ed6dcc6ba2645d1cfd199464892e3c95a44f847cd7110000000000000000000000000000000006665d4044afce84b0b19b2b3ebfd759ff10354c3a3a17cae4efb3f66aa00ff467a48d5c916c5603b8d505cab3304b360000000000000000000000000000000003a0a5b8ba0512359fa5582d8249479635a9b27ae7f5d36afdbcb1307c2c83bf82364be5d4162835d57b9a5e75ef339a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019480e0a025d0f11a1cea3632c2d02f581d593d1d46d91b9eabb5c7c1e38298f9ab668c091da6d4859a2519916709b4900000000000000000000000000000000185de88460a81409b1ff4fe3260caf19efc9ad9855eb08088c2152d8812cb7d2e97677d12acd7388dae3442c4c9e85a10000000000000000000000000000000002eb5e8459297296cbdf12c9c39ed1f29c2e4c127ac1bed778cb96364445ec264149237b282fd22c1b75f735c629343a000000000000000000000000000000000af81f64b37188155674193d226b8b8b0a238d47180191970df64b2b5faff2d1776c4e653db6fe55ec1677cd259d7cfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001699ee113f8973fa0caccbfd4c1788d97d0072972cf17876befceed63989f07d73ffa266239131c17926b22b0e05956800000000000000000000000000000000049596b37fb9789f016afa032e5df2ae5f745a9faa4f51398ecefa86b4a37f1eff390b5870fe1dd9004d0f9290ac2fa000000000000000000000000000000000176d2a0c9d4b28e4faaccc74c21a100b3f4da7aa53400ab46ab531a56500230f8091132e4d125bc6d087d24a1c297219000000000000000000000000000000000e24da23b7dfb427a0fe7652fc793495a2a4f4b4ddc1c6bcb2f32947775acbee98d0e14cd50083d5a43477008232b0c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006130f031080bc0d10c428e2eb39670eef0b99a587fdf69493fbb6919dc85ffad86790ea6050cc799cbf70d880f0ca9c000000000000000000000000000000000077043bc028ed97005d32b39f81ef0e16ac3534ad2ca3de8680b5dd1ee47adb7654730c1893442ae08c2703d660e70900000000000000000000000000000000130fbb574c5277cbd50ec6c601874e33b4318c66fa884d095aff8aeaa343ce6d3730328713de1b736b346e7411f9a9760000000000000000000000000000000018d4f73a8ec7a988b35238d2327d5a468fc32972a09297102290b3ab3ac21f4ca73667e71f40cfd22579bff0511c57dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001109704851a82d4bbc01db3067e7ffce0f43b62bc41e560eeb7eac2b63f07fa2334da0a54d6302d59f286b55987ca1f300000000000000000000000000000000048fbd6d4ed0d746e5018fd4447bea9ae356f16a0a04b5c0f498208b82b9609d154dbe1c914243309ee3886f759d11aa00000000000000000000000000000000057366a4c2a65d7bf45036159fbc7fefe02c5240d582fb4c35523edfc399edd808cdf1353a5117a66a42664b8388c0ec00000000000000000000000000000000193108eecac90c8c1d70028f4937187b4663d889d75197ed16921a2c3313265e4af4263dcd13eb6e6128f42b02c58ce61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8b0a9c1247a2afda11ceffa8aa82a3a2d189434eb86389d018c0beee9e5c94359a0c273704690d741630638bc3d80c000000000000000000000000000000001389bbf2f908fa04c139b88ae891ced443597634c2673d90a5679f5fa803331316ffff653e50a46b019ca76cfd732d7e0000000000000000000000000000000011c8729fc1eb877485875a85be4e10d57e1899a5227edbd716c54c037e2b912f11dc1852423e38414016d9c799faa789000000000000000000000000000000000c4f5d9b1b68e08ebec20c793cbc12bb34af6742cc43950fab789f07adfc377110f4f4fc1612d3ae13184e69ee9fb5a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d63887669096f0c94ce0fa7f2a78b90b83f688d94455cf87fc1cd480995d09c7978bd28c045f2bb84e508cf3f2734fe00000000000000000000000000000000197e3f8cd265ef69716196ce9f33b3367aa3ef19d52b8c878a4f04034e3b8fa6b7b4dc3d3cc21c2ef36d358be7c0715f0000000000000000000000000000000001cfd18eea100691c9d9ddec533402629c3b073a4799bb5e69704944223199fa58e8f513c5150f53a42a16ab87123f6e0000000000000000000000000000000012d86d93700ce189a0672a69c57b639b8ed964aa0131792ae99d5f8e2db87d9112b68283fa8cbfc475ab7ac89de388d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004279f12936723cab202e5ba813b1aef587837a86d58b77210d9c3f39df1fa92480cf4afbaca6f09ba5004b4df011a590000000000000000000000000000000018b75e3cebb5f082bf79a81d20f43d685930ed6eacd6097872a295235c0c219e54c4452378d256dbb90a39b1803f205a000000000000000000000000000000000d8ac4b96a331109c131e1e840f4f26ceab1f518db33af30f3516ee81dc17ba3f3d0b913b6abfd81c65a7ce3512880e90000000000000000000000000000000013db89f8fc14a8e7c0d2f1a87d32ade1355e866277d627e22db9396b32c266993e9410b346e375e5b84f145028c0574c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ce78132de75936116985afcf672ec342784bbf07d08e1c464f54d4cdd1bbb2394e9db13e9b6c55b50e99cd1c75846700000000000000000000000000000000164dca10d7f37bddb4933a13af0f4c43324959fc1b04393e5cb34d7faacef97db9943e2dc081d1b1aed83cdf7c58271200000000000000000000000000000000183339f492ffcb743bcb9b263958f9c301901352b0a3d282bb7ff77619d596ec9afdd579a40587fa6f82b876834c9b8c000000000000000000000000000000000c0216dba404b7877367ff064e45a1276c8dfbbbdb322c037fc6ddbab6ef5c56340aca6e74732688a0373711d2bb6bf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1f7fd5c2dd07416e8edb2afa28115c4838e4fab00c3d316665fe87c19856b33753fd5ef80551ca1d09efef47230414000000000000000000000000000000000605df65deb0f98ea718af6f16808a845bfc3598b8188d3faf8d4dddd597862e21b3a5433bb0f5752b1de8aa5c1d30e80000000000000000000000000000000008fac76cae6ee474cf3c5c4619030b7cb0b6a4f86badf439f0aa9a235ebd7efb9d0c593e012de498043d118c4cda1edd000000000000000000000000000000000d5950d75a16f745dcae762feb6e63f5b39bd34de624f944b2f0528d9a73bd8f3b5d0dae6cffb4a5aab514b2c36e27f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c6cb30fc014742a6bc8b7a22a58e87cd10ab46a9fa03ada3878b26f4c6f5317743db80fe38f59e5612a5d8e4c70c3c000000000000000000000000000000000b4248c32d9a4366082f54e5018164294237f3aeda1ddd5140a6b3df7652d1087f5b6d5c42ffac9fdfec3d7ad2818d210000000000000000000000000000000012c92b23e5e574881569cef70fb29982c68eb7678daa7f704e645498deec1d61329be4b23c292435fd8f6312209554f300000000000000000000000000000000124528f12bc7bb332dff69be35f9525876533a6e382aa35f94c88d4a365f1a6c140d8169ac89eae2be4175a2087fde8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ce1046a283576be78d4f11a43d8bb85bf47dcf59357f62d474464108160b58d6b478a588d7a6342990b87696b4714d000000000000000000000000000000000b6e69287718b1b8e505e595bb16fca264c0cf8e6b36959c2a2bd3908bf27c271b4dd5a677e9576a32924efa2f03211d000000000000000000000000000000000a6ca15a4485ae81ecc20a775994a87196ef2c144c662335a1cf8cbd950f902398343132cfd94a699f7d5e260c7b7a4b00000000000000000000000000000000156183c19a7b7544a63a807b6cdfd10cdb6d4d7a453aa2ce73f8a6796f24e8d2d30d26ba8bde792bb75371b0c6f255ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000210da1f9f2fbcf2eb109f16c68fd5ff6b4a3877c20933b104aff05e0d5e67ab69431bbb2220fb9ef78cd546c1262ef60000000000000000000000000000000005c9b764256d66ae8e3ed136526ebe0f448c4ba27101b982284c9ecfd33aa80e4755751271922889e07ad32b888d05b400000000000000000000000000000000052ed5c5ca63156239917b2642aba73e37cf93b97364e1b0cc187679f87b030721947ef8da01ea6339eb566fc8f5c98d000000000000000000000000000000000bf4f1a50611bcc0636df65a09cfbd29dec18ddfcb193c4a8413cd73e5674257a9e10d53ef8cb68606aa5dbb94069bf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179160dedcb63e2f35917a6cd8ab70ad59a1af65e51f7d6363460188f6fe596318aa79547722c382575835d5edaf876f00000000000000000000000000000000017de38ba68583930ac90dccf618cd6e1b4e7f3bfe6045dc6299c0e490c8275b426193322b1ab0596e2eed2d4e838943000000000000000000000000000000000ea93d7529e69d6eb18df69ce0530fd1484409ddae8e23bb484abb0c3a540b435e4915acfa0cfa273f7bc1e792031960000000000000000000000000000000000810b1a008474b4914a6231d0a69565120518674fd04ebca8c339a2173629845529e9ef6cd29c522e5753f15b3bf66c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e866151b715237be76f147aef584e63eec98916f28e720fdcfd0504fc3b13112a76f1b14728223dcf8cc4ba00f78d8e000000000000000000000000000000000c471ef3c43c2214bf15021c932e216ebf211691922d7c9b7a3df80468001cc569ea4bb4c83ecc3c30de97dfb9afbbf10000000000000000000000000000000019f1b445b70e55e70e7214e18889ab6aa500844fbe1ccfde75c5994c43f602221c3e697cd6a016696fa02e6205370ed1000000000000000000000000000000000ca7b3ecefcc3cbcd157b61f7d209a01602eadf6e911218eeb8d1e4c80f9222b57cf33bb40c3be4fb7c2494dc9d4e0b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009f8cdfdcf8bcb083d7da9e8e72d18e762486038be553f6677a28301727604fe8ac046b9cb7193c30417701d4e188f5000000000000000000000000000000000153aab72aeedb8a97a2c807822fe696bb4aa299471923c31d20de2280031769f0684ba4c24f98ca7cf70c592c261f8e0000000000000000000000000000000018cd85387a413c60a6ab464751c4dcc35fc0187613defd19b184c64e3afe6dac57f496932c2438b6964a4085efc871c90000000000000000000000000000000003a64fd6aea7fbfb9ce2cb4fff2a0306983b9d90c8e8903c8619f1ba0f760d2391ba6923494a528bbd632d8cf9aee8fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000381cf6a29715a70ce5286dc86e828173ae3fe06c90246079ba2e8694d90a83f6e90288155ae98fdc0d696d98c2fab93000000000000000000000000000000000a7b4da09d96a65a9a3d6573be454a992534fedd1d424855f83261c0fc21835737d4bebc6f99ab30412fb91ddcf42856000000000000000000000000000000000b4d407e0a054b173b8fb03c1d2777ebd98375925e182a71675639d91721295118a1cc95027d062972aed98fc4e82450000000000000000000000000000000000c57240f97ff949e569152100e495927e4e5b0373ca8ada334071947cbcb601026595efb96cf2616f89bdbba0fa7be171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0cef50eb7a5e3035849dfc6eb98979ad86a71d465a193324065a9fb62025cbcbc1af4e96d9f394c32cd027a540fe5800000000000000000000000000000000144297119710930d924376cc65fa3d03cd2e949102d6f1265aded48bf392a89ff7088b421d1752524f27249ee92444c8000000000000000000000000000000000b71324f41b0bb47c1b77376cdd489d84b10d7a44d78f965a266f4afdf73565d549da3efcc4bd01c80fb95d0040ab9c700000000000000000000000000000000090234962b70396d5768f2b38ef24b5768f19a2ce75e1b93566e4c04db71a8ca13c0f80d6769cb8d2555e47554f050151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f377850882e693df1d80382a8c73048463865b0eabedc70787fac38a8ec1bf7d84c9a723144bc29ab5480aa6754e5e000000000000000000000000000000000492d9a94390ea6f83b91eee5abf18b3fecb9d4e5a007b853f9673796776b9f846728812e05eb4d62b912b6b831a337b00000000000000000000000000000000072ba7af7471dd664346819f03068a14dd172dca6688a4553607de7fabdd9eabab0afdd4c16cf4d5f8c49544b5a3cdb6000000000000000000000000000000000e33913cfaa0ce59e7d228465ae74c9ba7cc10886f053aaa8edc9547126e1ffad4de46df8deff9fa32f2e9647e8ffbd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150d2fba6b32294ac134add1744fe56e672fefbe58c26ff6bd1594975520fd6fda6088b1023a98ded22059a3c1d06c7b0000000000000000000000000000000001a383888abd51a0abdb5e9e6eeae39a8347e4b504c92e74fd7e70699ff1165105f4d46c72b18fc993ef0bb66acf2b250000000000000000000000000000000011ea920a04b0a0f352e1377f6738e9444f8edd2618cef4a881920908d296cb2a4e7894637876cb64146072d851a5965c0000000000000000000000000000000006e4658afb854426c63edf7573b26cc0b7d9762bf096d206e5353fa5f24591b67279c433702a3f8bf4b9d1933e20aa121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000014163749a57478e3de4ec207f38805931b6615f9c416cdf03cb2efe3b3523d4adc35e7153730cab351ee5fb3941dab47000000000000000000000000000000000ea40c9c694647efb74698246754599948db5b62df56f60b4d1371ec9952aa0e56b518283a804f25009c5fa1c753f1fe00000000000000000000000000000000195036913cad2da67e2c48a80049daf94b3af739f45dc2ecf2a36c064477e5c5e7c6d93175e06075f6b1cac8aa642c9d0000000000000000000000000000000013f6c7710f3b4aacdf93d0dc262c57a31fed77acb718c6a23d2ea903e9b24a4fdcae4be85d85e8fef721b6e4ddcf71c6", "Name": "g2msm-23-jwasinger", - "Gas": 316710, + "Gas": 351382, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000109865d1a2b55309aa396cced61be00ba4168f8eeef80e1be234bad67e7d031b3be285f3c686be19b4ff31e1a14c039b000000000000000000000000000000000678ce9721031074c11f59bda6943059a4fa1799ec7e2fecbdc633ac793250a427d78d69429c7eb5896ee03eb9490aec000000000000000000000000000000000416e926f86de98af6222db8f8b12b39e390254cff1b987c61893ef03faa00616bd941a7163af5d117d56f98f51615800000000000000000000000000000000005d480012bf94bf1159e5645171e7f3b93fbcc5bb1298807f7808f375dca8f5228dd31f3d4c21c24d77f86e025e351e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001132153104e9603afed940009bc5bdc487b94bef819bad3af410df82bc4487efd3e94fdb37fb359c79832f2747de487d00000000000000000000000000000000187f290cca42b2cc54eb5fb6ef0f28a27eb6832c12f7b69ef6ebc53d28086dd2aca836f8f70b318d24d18f22c3c786fb0000000000000000000000000000000015c3b039b5792ab9d020a024b9e1df28907bda64adafc3e09974a1b59a4771eb7967c3f894d93026f7404574c360c7de00000000000000000000000000000000152c1f9a5e74580a46aaea0245a3921d186f4a718fb82702f8eb0d47690bf6cb21ea292b1f11f48df604faa06f4301f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049616bd63733a3db1a6dc7d8e439641372325700126dc6cc542ba62d9edecc9e5130927a148b7234260cbfe6c08c27600000000000000000000000000000000198cc6e1dc43604503e15369162d91c8b225e142f7996cce939f6b90e691fe81de391e2fb3d0091a8ffcde2f6bdcce99000000000000000000000000000000000de50d0889e7ec35951847bbfc1a3eefbf4802ff1480377786963ed42c41993f669ca90a19e0342b9cc4fd1884d179f9000000000000000000000000000000000a9195097ad62e62fe1da1814d81974b6cdc1112129e22a3ac50fc618cab6ece88b7a286e9845b7020c19c9d5b9b582e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e168213a4ebc47a3265f345f3550e0c55cbb0468f9958ae9abcaeb2e78f8f923d8b72399eb454a60866959efc0785d00000000000000000000000000000000128843c012e52f69c4f8aa3bbe56a746956346d21b8df78be58cf5f06c8856f7cbe168e5d07ebf8d2473cc7f042c1e8100000000000000000000000000000000001dc911f409f178934441c9cbc6d77a229589b1168c1ca410578e9f53a26ed8e7d9abbad5e8971363723558815c054a0000000000000000000000000000000018df143c7f1a1c34cea98df652e9f505aac522934bf46a2f6a57df15c003dae677a130cd9e4b5d4ca9eeeb38cc45f0e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0d7cde992b6d094a1708e7e0d20258503cf1021a16709634b91e419d680813776e7e6ee9bd1877741b15ee1044df53000000000000000000000000000000000ef1d11338728cebf8c63a9e24201dea161fec32c4345053c2019aef589cba80d7a23d2b30486917de7120739ef391a4000000000000000000000000000000000959e2bc5063d75675768853a1e42cb488c0f7b8ec9f72f9924ece5d759ee0de3a0e38fa9c0663ce196d46b3f15be1fd00000000000000000000000000000000142afc1e9e4fb841ef2237f8f6a79ff58edcb1ce7a6086d520b41acae8d5606beb3614027874492b4e8e38913509b9e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001684545c1218ba9fde0e8325bdd8667f9b561e5d55ab77d46f386876de4ae532164859fed671130bbb540445ab9691f6000000000000000000000000000000000c2b890e62130fc347ba8aef09cdb1fbafc35185c86163680024e5b63c16c7a5602f25c5d37def475bd694d8074b649a000000000000000000000000000000000f7297bee7b0846c636451ebb84c1c38ae8274bab0282a9f83af7e36a3d32a492ac1d970374ce17c9cef7fb810a83e2e000000000000000000000000000000000c63c1709faf67f8748ba31e308dca68569cc86d5274267853151aef56c15398fb62a5ae1a1f269d66ea94c674af08f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7e1a6a94e975806963602b9ba19d8ce66712c91a58da1d995d37d01fb58017de2c1b412ea5d9d5adb255c81e736aff000000000000000000000000000000000ae4084e66e05889699c1f568cddb577151fc0e6869d3436e17ff47519a98cb622dc3fdf8ad27d30360957a1c95f703500000000000000000000000000000000182a0d7d43a3955edb182051ee9f0aebfb63c7464704f01c1f9e2c640d2c0e3828c45fcb34a068714095c26bff73bf3c000000000000000000000000000000000f5f0c64a135764d7a9cd31ea971112359dd4eb88dae09aad5d4dc62edf2b10d25ab35815a836b973b8805e39f5778631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009471cc5a5cde491e67a5227bc94e301bb353c3359070f0a0f7177e7e5379ca1df5f0da6fd398150682b6ada6ac3b1630000000000000000000000000000000012c46fd7ec8568f48554fce62a4a44e0b0c22856c4ef526e7ff6741e9911ba4053fc130da9e6191551077a3094dd6c5c000000000000000000000000000000000343947892bb2623d67dd2f51d7b09a8e3af2e3fdfb2327068a9d7903545c621ada924df136e21490d244a427f114d950000000000000000000000000000000011e68e8bc35490b65b1bbde34f3582a10913f1147b8c3ee96804096a83375f36749a9878543d30d31f91033ea1df79d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009582d83d23e74c2ce61641406aed544d6f68155d6f172ed323f94781a0c9c1a64f7038cd4e49b643905b577b8cf02090000000000000000000000000000000010052709b2194ac65033acaa2863ed2c33db45527cf53b3a9038b2e07c6cca08ea497b718c149c96f2a07020ee6ceed60000000000000000000000000000000006ad74180907d6d9550979d68e9b029885d3304f583a5e8758d18dea17b7ce5efeb3b45ece098270e8f552d7c28f381d00000000000000000000000000000000194a7be0f75b3eac392bfd37ea515254a06b64f2880786ca36693c139cd54ec4cc7e0b809f0d07be98a70800b92406be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016be09ebc431180110219678bce1da6d680cd6ba44488a64d0115ef5cd954651116bdc205281771360bd63a8367c121d000000000000000000000000000000000c11280343ed187e208fa8e931a4623e0f7640310af5945f7a12cdf0e0f2083a5adda0fe5f27828a035cdca6ce9392d9000000000000000000000000000000000c4eea08962e98ec2c581a9b4990c89e63a167c157989ef6c806cccb24c51e6e10cb8261285d2d94f5c57b6b83e3df4f00000000000000000000000000000000043b3ff24ef58a0a1f156475311f27bf947ffd210aa391f954ea270f09819e83cf0247109af6ad8df78beae7faeedb481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f277f567130b1d7ec01364e23282ed6d1135fd1f32a2754d35d370c0c7127be2c098c271256208e0ed1e7acd45af72c0000000000000000000000000000000008d74f5ec8885cc079f6c05556f3845dc00c4e36d53ca17e167272c6ca3a28137ebcbe824438b85b290648f23601e34e000000000000000000000000000000000e665a7a21ed9389ccfc957f3d3f1cf57123f07e74d94c64e4d073cfa90971c44fd35aec59ae07bd7d53c36d95e2112f0000000000000000000000000000000003666c7119c745fc22355e9bf5300131b876b331b0c6f552ae9fa4ed1f374fda4a4077e9043e04809c1c0f93c65aff0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a49705939136bcfe4ce068fab6b2f180456acf483ce83b665167e6261fb4e28e2fde80bf1eaf4689900db6d4d4e4aa0000000000000000000000000000000000c3f57dc97bcc76ef1733f7907b4d07e63bcf815b55bdf19999137bba9485303ed6d767cf05c8af912da82359f31641000000000000000000000000000000000411a1136ca402475732f0ae051b9ccde80cbdaf4c6432bfd8923442c47c8b89669c00832fb625983fb9e391ea8a2dbf0000000000000000000000000000000018216a0ba8cbe92f0a09a4b7c5515f538b2236e40031c415538ab425b7d698ceac1941e5c9a5c3857ce3fe3688a388981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da00c4674f9cc01e66d129ca5a47fa81581a6a5e8527b7638742e2d04a5be8219aaab38ee1df821e91dc2db2d0c9e70000000000000000000000000000000000b4f08ccd4951d4bcb472279a72f948bd104eda4670ca22e4aeeda4dd7f968d068d60a0a90678a65cb13153e88eb588d0000000000000000000000000000000008244cba7d088ee6f4b92d418958263cfbdb0f83ccbaf263f20d6d3eaeabb3a070550735421082f0fe251d159fa40333000000000000000000000000000000000607c9a9caf7d099076b179342779c2e8ef5d36d407b9076cfece2417bf8c37228f2f033b06d827553f4652e50bdb2821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c568736ab3dc7f5dac000bf84a737af6070b557902677cff54b68e524fc9cfe3b49620b95e8289b3796c05cc26ccbee000000000000000000000000000000000ee224acec26335478f915ed9cc0a52e5ed7fb820e89432a5e713bda42c2a981656c5d379276185f7cce6a4f9cbfb6f200000000000000000000000000000000095593da5879ddacb5420ec46cf7aa9af4e26e62f93eb8576544803474c3abcc5b35629d7c5186699d27aa1b7f84e12e0000000000000000000000000000000003f3b1c69ed04ecc14f68bac66d07cee5217ad71fd02d0b5f3d496df0930a467e2abc8ef09043da4eafbb8e02a3ea9de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a6f3b41625d46e012d4a40ff1db95aa22d211a576eb7025973da271fff61d4d95ae613f6e16e538e2f252bafaf1690000000000000000000000000000000000cd1f362402473fb90b84ccbd14ba9e72ecc792b2a935d2b8dd38f941b30a5a9ae96c0fe230410dcd728919d8b7ae3fc000000000000000000000000000000000684ca05384a96e4d802634b17d3c576931c3330f827e2e0f8f198e1158f622a1f8460ae77519283da1250c492ffcd430000000000000000000000000000000014e1d7a84085208e0411525ffc2832b7fe4137241409ea386460e2401c574ddb81c75806ace5e4cfec92ae128875e6731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a9c663619826060576336ea35004faa2a2cf0b860e1915f7e1a5bb9f3ca8ef5dcb48d5bf05674e9667faf79cee1cb2000000000000000000000000000000000b5718430ee7dc2a56fdb1280c0ff90e0884885f07d2817c279fc720880dcd1333d951d56240ca6b271df3d717b06d89000000000000000000000000000000000d71e58b14bf0c658b59ec38e1c98f9f5c6108c2a1f4887f1e685c36d410b0e5865fdf0f7b2bd7c468d9601d55a18ef800000000000000000000000000000000157fa6c7e879115ef7789961438bc159ed50117bc4bfbea6c50a2978c31827e00aa63ab6aacebf7110dea6960bcbce9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040676a107ab7bcabb5d1bd41a37e0227d8b646347441dd0b8362d4798380aa98d23469b117b5d2692a5fa07a42db03c0000000000000000000000000000000000d5cbe62a304f16b33a210448259bc49c67a92aa3909d3b8796336de93eec26e254b2a078e3f03bd2cb3935d8df19f8000000000000000000000000000000000a3c38fe9efab7fbbc7899402d29e8dc99123db5be2737730a8b077b0dc63f162fe8c289f51cfe309abc33bee885f0b6000000000000000000000000000000000988f9016f721b0f418692c34a4b02232a697e08bed812bdf2bf13f5cadadd09a325c4b46f0015219a35fbc1766bcb5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ede42c330b01942e717e3098ee6692e6918eb1091fb896eacc4ca3b17703d17e6b9fc7ec3b193fcdef863a2b2f64a2000000000000000000000000000000000aad48577ec39dad0b112a2849de88a18c991c7f55168223ce384c8e2b9ff9fe0a243f66c50be099807bcd0bfa98093c0000000000000000000000000000000013f4a655e94a1a71926b92dd7c09b65fe121b93af61433bad33808d7d0bb17a276b71020bb541c67bdc8a8ebd737930b000000000000000000000000000000000cdee44aabb91797019f10280cb5b79917e306f574e21b2ccaf7b0a00ec9db3b36f3247b368b031bdfbbcbac827ee9571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a77802ad0e9f7c48cf6a3228d02989f9ecb00348cba3fc2ac5b4ef4ede200333579e43d4b1576044560fea52f75f57000000000000000000000000000000000be4a23b999a34c94887206f7c1afbfd13d8def10d46041c816cb5bc5391aab0d2d2a843687df527bcd5a635dcdaa2f20000000000000000000000000000000016407c14049f61c7f9b0f2e49d4cdeeb701ce4a4839422147fae1e773df88c6b36c2971768a9246c789ede4f798b57c70000000000000000000000000000000008a6577554240e7bbee830553ac0a38b732cf3ae4713e10f174d391cf6f1e58238b7365ab440c7e872a6dbfd08b2096e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2d366e236f71cfb17bc808ad7f3a9249379648934f9773538c201a5ef668390345e0f384ea2b82fb9941cfa9c126000000000000000000000000000000000013092623bd946511781c9e0c8810f4b0cf78cddb01c3b50ef59c6253ccda85ad91cdad81484a4ed9fedd51bf93bb82a50000000000000000000000000000000010c9e1c4109630faf19401c9cd51ff8b51e5434a79c4421efe87e02a571c14b333a07b6215d12d9a68dd6c42873209b300000000000000000000000000000000190c7d2704b9a55d1592d2f1124a20ff72f545c87ba705f714ebd87aee19ae3c74fb94409601e7d862990b9d1b8368801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018da80402f3c38b1a5d6fb69270c8e2cf98136f6ac7ba24eeb4849ac58f7a4462a3d572ffa5b47bb63615cd83dd8d0860000000000000000000000000000000011b8d8dce5a8c215dafebc1de7f0360c6fd9dfbb382b772b62c81c06d8f65e8293dcb2c8614663dc8f27d0a42b12306000000000000000000000000000000000146e85d62b7f22a341dfcd761d6ac6f1bbd6911847d7ea687f7b0fcd7a8053cb34857bcf444e58eab1fe1e56d4a138430000000000000000000000000000000017d5399f688c96bbf592a160497da7a43f226e1038f9b1b5bccf8ce5e8a8d7af50e4ec4220b74ac1bbfb0cc01c908da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f81f4dea7cc81860c1a2e571e7d2bfae72353bd064e1fd86d8f625935aad1e6da4b271f4905a986d45c75257aac315000000000000000000000000000000000bd6e1e69d59b79a7ab2eefd803f6357127b920acaac711781cc0689ae04c971418157dfb277a9c0dce4e3deb441eb2600000000000000000000000000000000069c9d5bd9597914115b26ffc743504958d20b630f9124ffd41fca76789320a8dd50a14a37a5466dcb8894d7f671aa910000000000000000000000000000000004178ee76b930cdba15a9e4a5cfee483f25313e03b48cd996280c666bc647305037c8396e951f95696920abb28911b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fb86a7adcdad34a6e76ba34627b5baeb0008198d484302ad5952940410991d6bd5c806b98a7272ed3f4242662f39d90000000000000000000000000000000002e917174ea7b23eaac04026abeb2d0493d8fbebfe44d17330f5fec06d08825161ce4a1ca94d0786c7a9e57486413d2e0000000000000000000000000000000010702803c47d175e5e1a7e84aebd2ec1864058edf5857fc5725ec7c5b2d2081655caf4dab4c66d0d7e54a8f3c7fb18d000000000000000000000000000000000021f48eaf074c2721217dc547d7238b8ab63fcae68d2515bb9f4b95ad3f4b3c6be4f637d7fc7ca108ba59fb3243f34a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a3efa39078b31c23c23a240e9bfb8d09663b81fd81df214cdce9d5aa242906db587e46c373724f2bce325caf16ea380000000000000000000000000000000010d037ab19e47513a728afbb2da278ee80108e39849bdf3395a84efed36e34d370dcefc550089fc7833d29c8cf7c1b0b00000000000000000000000000000000049f9a20d5193d133bec5d98096e17f9aeacae5f83563de13d7e79e4adcd5a841c9d937f0a824ae1b42bf1c21759156e000000000000000000000000000000001959339caae71eac4e92b41df82650e6bd00e413e2334e5efd14cf7ffafb6da4ce75abe59253238e4be0ac3244fe9db71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000137654cf93c749e5264895a0140fb7dfde588c9255d3c6c2f57bb7fb3e6ae91629e79064ad56be0cec161c2914c07984000000000000000000000000000000000dc0bb51207f05f0fbab1114abdabeca56c1284f64881a3afd7dc1b16f96c496e07f90942fb33080a76cbd0f25c105d0000000000000000000000000000000001440d633a7bb379dfe305a829f7ff91f5f282c2d05e127881495a8160e6ec0c735a24ac0c97e17f96c93174f988c61ab00000000000000000000000000000000026dbb34ecbfaf430a029c5cc94aaab214bdec44a542e83ed94d65675f2f66ab31e5fd7e1b7ec491b3daae043bd33459", "Name": "g2msm-24-jwasinger", - "Gas": 326160, + "Gas": 363960, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001e5b0e9b9f0999306f0d015bcfd39a6330ad4f498e329db3be3d777fc4a06055f8729297edcc8a233749e472dd14c72000000000000000000000000000000001141f5cce35116ab733d2f7e50edbc316fe97a82635438683f212c9edd0aaa82134a7ca98355df16e843074c01ec593a00000000000000000000000000000000021d98390d8c8310184fc0d6c385ea6fac59e09b80c1bd8a8a8843ca952945fb423f9fe9c3eaa7cd5b9d0855248feab400000000000000000000000000000000095fe0a3219857cc8e8eac816e827109a94420f8311ca015c101321afefc894d899c52995719f16b96a0fba4f104a8971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be65aa653fc0a4bc3f076806e486e35c1d1809789cad5399fb69f9d5e73924223e57349234c8e805dadabb79176d99f000000000000000000000000000000000e1312bc5792aad3ef860f87c794b90228b1d59ef6497e78fbc9d8e24aed1009c18744ea5b00398d2c33bf8cb2dd8ce80000000000000000000000000000000006b73f602327857007ff2c91da9726eb5ad84c20808f042906c4e02659fa179e9748d2b2d578ec4e2bccc57256a365340000000000000000000000000000000006455303efa265248a283b4f671966f305562d18f11305a538652ed6cf34f8af3ea5328f15304c6e82ef759b97fb15401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010f08757e8c93a21970f87cf55bcbd870eb5098159354ae37fd620d204b74e253bb5bfc2898656715483d5a7b51168f000000000000000000000000000000001236eaa4c0a1821c732d2bfe0b11478caf4be4c3c2fefa42ed8718b901a3bf45150145dbc71557a215ce2d26e8d586710000000000000000000000000000000017ef5bfea074047c5ebf6e91ac65094fe4c480ab9df4de55bb7323d2e6ba5e01cf07698ee2e24bbc1456ce9940d7fead00000000000000000000000000000000090d0b63f5f7463941b7e768eb6b69382ba4d532363df7ef413cfc9fa3aed5c6a18ab978be63f277028f29ccc54d21fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158689aff14b4ae475a25339d63129c105d348d6be3f3abe81e66a87640157070598b726e911d7b1b144a389830f68bd0000000000000000000000000000000015e89d2fbc7602324de017b06da6e0069561d96d55ee40aeff172dd6935eccb0e333205ac0b51af925478e15e830fc76000000000000000000000000000000000d00904cf9f615c3e88073740d06b49f2fadbaeb079871b711dbb03df9e6a0281f3f886e3e6c6a0d15fcd8663430da7500000000000000000000000000000000082a873a3cf582b8d6e2da576ffbe07bc4a7f39059a683ece1de5e3cda20a86d99dde9ab9cc20893ec82a600a52750511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000096f18a7d453f59dfb7f0776c8f0a73823fbd4e18c6d1387f02096471fb98f732d44dee7f639cfbabfd2bfe8e984b2f00000000000000000000000000000000188259fcd755917e7b00cd50254fea2027bb9e094fdde8883df2275260e6a03b225492ec21da987e308c531399d8b0c9000000000000000000000000000000000abe68e995aaaaf1b11a1d50c971e789a1e21d3f27f15fe4eb4e6f04f6389507f1206d6f6d2a178fd37667ee4fff830b000000000000000000000000000000001813cb814229c0512ead9c0821aecb71654ce5c4b6050704c0f0d9f085432ff9a8572e3f77acd9a35d0b865bdc61c3c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122881fd1f5b60ae6f906d5e79cd6f2dad2a0823eecf0ee2547cff1b95388e0c788ac6ff7ed586baf4768dc2dc251a0c000000000000000000000000000000000116a1b8b19f1a1b0b8041fe5fbd86803230b78d641f64c3a263b2258721b1f30e98360c753a36e8911e45323bf381780000000000000000000000000000000013c7a6e5504372ccf7af11b62d4b5c03afb126e491a87d87103abff27af5fe31b94d39ab9fc24608cb47e5e4371f55c1000000000000000000000000000000000de4fca6d2c0a35398e7dbd0f2d1224edafe7aa4ee5eff131436394de5559630355120688e42740168c4eb856748cf5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000185b5813305b5e9ce03d77a3dc58171f6f51fe0f3ee92675abb245a6d367984e0ccab9d08e947b0d44683dfa2fbcce10000000000000000000000000000000002108d9d924de220e1073c91c456134a1244cd16ea8ceb7934c00b2a96b4eec650050aad11c28a42d738ebd5c86058b1000000000000000000000000000000000ec354d211e0030ff667abb1484612a4fb56c8eb69366cb72229e5c1290e6c5580577a6c0def70de131c490743bb90920000000000000000000000000000000001778c599860ab1d85b98ab1bedcb85eeb7823af2eba115c1963020aee5da5998d0942c87d5908f5a7e035e305d7a5171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166c237b65bdc5c0b9b3ea1d87a6a011c31eb734e25858578bc02f378d731d869baa4294e31af49ce371d2466a05c11d0000000000000000000000000000000018935715b8d63d4b1f4e6b1fbb4f450e5b3cd2dbf3a1ff5c0b03020146a506ff6c493d589b257f63baf9ccd273241d1e000000000000000000000000000000000b000a8c079bd2432b4fbc6fdc2a05db27d775f60a5a353c25a531f1a5c0cedcfa13dd08da2d9cd86206c54158993dd100000000000000000000000000000000104f7191090aaae74bea16f234ed3cf942c089cb3821f555f400755ef4e7026323d632618575f5c2ca11cd52500918871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114b648f0fe373644644f42e2a6475eadcd951e82dc8d1fd0d67c0679ff0f64e9698c9fd1173cefdabf6d2718c01ca0a000000000000000000000000000000000b064556de57d8f946087a403368e99b7c2f661b54b874fb7300dd71c011d7c5f13d970e35f1a9618b3213bf0f79c281000000000000000000000000000000000668d923a8e5104ea1ef7893ecb3195a2d29693da86cf4bdd357eb3870e643337fbe65d043fbecd1b9c1e6a44e3e5a5800000000000000000000000000000000000251ad44c3e4751a686098edc96a00469290e8323ed1abae958ff0a733c4fcd31ad59faba68a961cffad78716d40571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013caee76d15a9f200d0a33f2390d68837821c4a89133a09bcf4663bafa953765f10310648e3edee2555970f44410f8670000000000000000000000000000000016549d4c0bfb31e9c7f4cd050d32f8a8d50a6ab9ae380f8539f14a04ce171973193d116599011ba33f6512e9ff041fc6000000000000000000000000000000000f30b18ea024e3c5d773df3188ad08633fed7f02ad734a3af765e062f0195db5eaf7c9a2d096df4bc42d0a6f478f708a000000000000000000000000000000000eda93cde7dd23345b08c84e84ef379688f7ed8f9794628801c2ef1ef345bc3df80d2eebd9b6dc908911790fb87a75ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181414a164d518599eae38992f79c6d3b8e5d523f939baaf67d7aaad7044ce59bebd6168018d06d1de9ccbd1b6a5aa0d0000000000000000000000000000000017f426c40d9549db66b9fb56cff2b60f6e8a145bfc688b4c8a8e5b5784e6ef776efe474e24de5d1e4a4082deeba8bb4300000000000000000000000000000000071b3af6ae3bb0a65ceb2a40403fa97146e206069fef1f42147d485605cdfc5dc71be6a85a4f6879c0b7f51b3115387b0000000000000000000000000000000017cb7152a5494bdd8590441aef8298097cd4f0205cf6a74b466778a529746847a948c47b5acbc9a229d9b44e3a485a251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd9718e8c66c5133124643b5ea1ff00f02dfeee3bf8f578129e53bee10c82ee6c979e2bf8a4d6b958df4f28fac1ca560000000000000000000000000000000018be48d039c5963aa9d1cac1f9bc95286e08235cb083b45e5a30159e48b050be7c9f49174923d041e027608a12e4f46b000000000000000000000000000000001569409c6b6aad21c30fc7a8eb76e3339a444bebe3f184b976e43d011a527fa4fb0909ec08e1b366c010f9259d5d5f7900000000000000000000000000000000079338ab39171dfaad8320c8d1a5f7462aebf19c78f80c71be95c98b255798dd974971fd96953de700cc645a02b803101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ac1633d6a9ad527bb793767ae7c7697d58d6572c11b246be3b7607cc443ef655b7a130b07407b7389632a21dacc4da0000000000000000000000000000000018a9a4596efda2d945704a5766379f8a63843af8341aea8fd63a5abeb1d43735da19256212b72833253ce25d02d3b8e500000000000000000000000000000000000c6d48029bbde34cf9135689fac4b7bb7a75fe8813a479fc1fb6fba9660eb0e4b71ac3fd89521a07e84063f080be07000000000000000000000000000000001392848d2910b35352fbbd10dd899264501225e3347f47e6ac3d0ae6107eb8165438d01cdb9666dc2374b3ea93a7a0a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041ee1006c843e70b12b93e9ec967c4e29012a2814cb8f06f51351a5df2700489b38fac7d1266f7fd61be766a220eb0d00000000000000000000000000000000177dd92c5800d9e32b3f616948c61de96c5d76bfac2eba80b563beb6eae1dceb66711631c0216c636d629be49e7feb480000000000000000000000000000000001bf08730acc28ba0bb2fc4da448187e3b8801535c9a4ad3c070908b1cfeb902f885b19cb6347e8a15463c82b84ce75d000000000000000000000000000000001322149794ac64e852c27b4df3741edf3c1d68aa217b867d78bf6a6cfec09cfa02e3e6bd9424a1389ac024ecc5b5f2aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb5a9b38afe3636f2fc349d1f58f324fe14b9dd2393e393dee1c85a7a00994c6053cd570ac31796b7dbc9cd8d065aa000000000000000000000000000000000192889afe5265b6174d1dded78fd56bf9b8cb3d9b3bb119467522f895c5d0cbeec58bff48977e89013143eb5db5b31410000000000000000000000000000000017b78fb572364b3d4c741ebb05018dd58a701cdb5a69c193c03c742a45b99d1cb69f9ffc1840a2049535dc424b3a136900000000000000000000000000000000090dab3dc5e7c6b336ef7509058a24a0d4ba582c1c6e94cba9ca5df3d54fe040a56a619accf3218189f7de98a35bddd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c20d82dd42a30f2c0b6fcb126e68e8fd4d3f9ca0577c77183de57e0e874c76e2a0078dcbf309e5dc030e0339b56088000000000000000000000000000000000a494eaad0ec56347d8cef8e4f836c80c8a1e69f8338645a50541a5040da2f8e36dd5f7956ffbbe180c831011fc62e02000000000000000000000000000000001665c0ed27e3a8e39a36c407542e00a3bfc5b9f6b83456bab28b79132abca823c66f4d076df802260024e0b3bc3d8e0600000000000000000000000000000000155430ffe4bdfe8f784ef854bb6c813658cf0707830f682176af31b513e480b169e98039dc4baac67636db60428cc26b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181becc4c9890613a2ae6d96fdc758bd81d89b9363fddfe63820fd2ad5e8a997488a54370402272de2f2ccf9af2214fb0000000000000000000000000000000000ead30838406e3c82046b545e3fadeedfd843743796f41d71f3c8fbc07afb94460861f9b527309ac4ed091ab7b02aa7000000000000000000000000000000000a3f7d7fa655ffd5fb79ed55afe6802dc3eda60f9774258facabc2f3ee220f68f0bf85fd61350571e9bebf990715fd7e000000000000000000000000000000000b73ba70cedcf6c211c72444126533fa068509e5ab6a6bebe8270ad3239c588d7e51b80cbf6b5889fdb8e3a355fc9ea21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf7d8d3afc421722745e07f37d6bc6b1bae37d84ddb4a8ebd71b608af6ba690f0382779713a3958235347a512a41836000000000000000000000000000000000a0f1d38913d0a87293c9607498eb586225919d44cfec8119525db35aa2eaae63c62a9fe907f50e97ac3274047337b25000000000000000000000000000000000c9984174e19426c4f891621a12b93a867ae7f05071616d1dfd349a1089d47e5667eb0048c809add6e1c78f281ce2f520000000000000000000000000000000006c5b5b848cb195b0344a9d1c03825d1962a520b69d8c2fac21528ceef4a7bf222afe62604c0243601ab6a1862ef580a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cde4d4e374afc2e31c201f7fd2ea48e59395e76a1814f025a706c865d8956b16a601a28666e180aa823bea72e28dec0000000000000000000000000000000015903dbdeaf68d21a53b7c1b4508df8b5f394015213dd9396db0b828993e2d6e6299efab44aaab10ce11529c54a4bb35000000000000000000000000000000000bc260249b64fce303eb35cc60408f701515156b336b0ee783fceacf3ba6f6a5c974e84d069e105714126accb2be99b200000000000000000000000000000000143aa8e878468eab92990f99f2558b09168e6c1ddcd198e92ce189463885592f416b92f5f8efe499e37956faed45a34a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011124c28a8d4ec4d3009264f1c88a959f0f099a81d0704d2f92ef44d34a85faa4f96db4d26bc983e075df108c8b1a6f0000000000000000000000000000000000a5ac8d1dd5dbb234907ace0a736fe80b171b14568599725685600d26e9dcc7b3ca8ad3a91c47b09c0a5d21dafc9c70e00000000000000000000000000000000016a0ba5e1a61e820dfa1a8bb70a149a5f2c0526c98adcc4f61e683bc6e8907ae04af04e65385a6208a9ff6c33c54dba00000000000000000000000000000000181a4f5a13e95c7928a2609cf45cdb8e8bd34f78f8d92457d877badd0ff993bea93b52e039cfd4969a56e3cc62f7792e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dfa1b914057df5e8ec729ab3485d16cfb64d23acbb5268da8f2bd46c91b4aadfee745dc0b625356aa65394d96589c3000000000000000000000000000000000dfc2c9e99a6ef09aec9daa12c39580d42ef5cacdfd6fba66759320dc5c3dca73273faf2a35be290d40634ee57fd76350000000000000000000000000000000005a57b840b7fdb736700ea63bb7f9f166d284afeae2070dd1355fb0d4eaf78f5bad2783fbfce0b0b50bbc343c9b0084a0000000000000000000000000000000008848359f48c2cf54a9d11e9525b2b62f3ce5d831e5bd4bafb12694ca7d56f05cecff05e91f1fd4b3a138359b53f99a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e1645a4f01472d207fcc367ef179d101b1066eac6155e20e01fac7894551603bfcfe31dd1f4bb39631dbfcdc59ba48000000000000000000000000000000000ea97bd05666fcafa7234a745622de8819b4d0259c2d2838b6345c160e4d309c73a536e8b53cd3b5843e79ae555cff940000000000000000000000000000000017a6145a5ca8815b581ac7ce6cd2cae1710689e2c10f104574e3076a133be6753387f03050cbc41723c18e751a790ff70000000000000000000000000000000018d77dfc4b2e700314751f5b1ea97157214c59d308c200fa3c473f7a7741aea6d19186073cd312aa9e95058e98366e031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a2d6ca710cbcad434cea93d491ba77383230c90488a3ae274aec1670fe789b1724f8fbb542a2ed59215a4d866be15900000000000000000000000000000000114f44f0bf5787db5a42ffcddc4184edb2b982ef65aa45e69552ee73d60f14b6ed5fc310a82bcfd5f2ca35a5be77ef600000000000000000000000000000000011de3a286920be37bb3725d5f6f46a27dec0d58718d7a8aa8db024a499a2a03135f2de656db900efcd0624301bb672a60000000000000000000000000000000001dd2e17de5afac749761939c660f24aab48482b18ca2d433d4b3f1dc299daf29d84979c329f6457f4c456cd28e7b2911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001e501858e820f6fcfe4d68ac94672bbd55b78a3747497ccad933679973dbd3ee5fc00460866f4ce0c535935df1aba20000000000000000000000000000000018a2ca2c471567905c6347073dc366f099f71e4dbb22ea262827f43a3513bc13b274f2230f52dd867205d91fc662c3c300000000000000000000000000000000143bbeadb69f9f62398483eeba5f31b295966a2e13512ed55220e7aea80dab981266e6e218fcc15a997463098be88f84000000000000000000000000000000000a04948d7a40e6e822dde1842c8d7b233cbf2e0656afe9f1f8f4145252a76f501740d2183effc4b7032dcbc6341e5dd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e54526b9ba6727fe4d0b78a5941f01a88bd46fcf3ed6177aa6f7fdf907028d3954ef66cb64fcd7a3ab4d09a3143272000000000000000000000000000000000652522b515d5eb665544948cf5ec2798c77b89b82b19819df0cea4da797b4925d02a8c52cc23a46abbac023a30a9c53000000000000000000000000000000000e253d61845e93a697ab2233ce346ceccc490f6d7fda2f2333dcf982e7329d6d1fa9b335e62a4fb66b43772529b1702d0000000000000000000000000000000019c605dbd244f09df01bd7ba506120a325ebc06389da8e220564ead1f191aaba38a3b8ef911b574d9b3f4e50ecf250fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000129206dc100439db26a0f5442328e35213167e677976f0d5a2a967f16c4f80812c20a088f7be4b09feac7776d61ee443000000000000000000000000000000000656eda529137539dda942ef083bd444552f576f770ee8009ad91ac8a40b3af38680cf632d629213b363135dcf8a478a0000000000000000000000000000000000e907a8f9dc2f2886460a374ec6df1111337c969f4e4c69e567cf7d31eadf9bbd2d8677eebbef2dbdd887255b0cb9610000000000000000000000000000000004c59906f69ed3161bf4769734a2c2a70f25a0873bcdf6b98abb446dbfb63268fc40e50f3b1872db89ddbff968f772d7", "Name": "g2msm-25-jwasinger", - "Gas": 335250, + "Gas": 376875, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013dd1a8152ebd368d8da76ce266836f7c379ffe033e27ed4976f12cff52af857a14284bb5017d4cb4545cc331402752f000000000000000000000000000000000d800a6eaab1b6d3ed548a6d5c6f8e7af4ca695b8af8e0bb94027481904ef0d7cb54350c93d64c5df969eed85f65a328000000000000000000000000000000000c0007f1f7531e77aa343bae0090a5a747d43287972ba52f6e825f318508be57978427adbb02f6d235033cc1e8c3eeb30000000000000000000000000000000011bdf642b99a1f9105c8f121c712625e02dc1cfdf150eaa01f8cfa8306c55f8d6e280e3f3f77d3ffb06f78d4dcba37c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060884cc5d27b3b53a08b09a35e50f61060d35260d07adab24d0f7157879f85399dc756a2be322b61520fa778205c659000000000000000000000000000000000e9929a6775cb6368baa8a470042d3a7b6c034de3fe5ac6845b5795fc6f7f5abf5dd48e65b3da824172f4abd8d9505580000000000000000000000000000000015ce595ae51fdcb3f3c0d908e69efdb31da0daf3f7cf4a878d96ed0f427fcdd3156906d326a517b287e0666fa33acac9000000000000000000000000000000000fe2bd42dceb8166a57fa05fbf571db860537de12bd55c03654d72f805fbb065dc33d20e017d6e2a6f89b2125c0c5d731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001492b2c433c2718112ae39127d5125f4d360609bc0087d8270fdb3c3c78f84fddc57ea9c5d27c1114075fddbdf54800b00000000000000000000000000000000134386f82ac76bfddd6959ab42cc45b7698a398f475b59b8a35c450601ad8d73abdefc2f73f6a77cab466a73c0259742000000000000000000000000000000000f6deb7eeb6abce474ad01528523ffa39e02a5460d087719b8d00919cabb1b1a1ca739976421ac64433c1f01c55c8db50000000000000000000000000000000009d0ce63a7d8558e4711447dc182cae1df9e3765bc4bb4f52603716f1a2fe093dc2e3b03532d340f4bf97e64eba4b9bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c6c71de74b5de2035f35f7bc79d487ce73e4d53c38f541bae929f17036ef9fea144c3017a10bd45766dafe1cce17da000000000000000000000000000000000ad440a37a68764365002e8373a3a6a690849fd5baacb2aeb1ecbcdc2a6ce121a405f5dc4c5f073b791ff29467566ff50000000000000000000000000000000005f88814ae4d13df1622efdc55cc164732fbb7d673fb661a2ebc77cf3af0862c14ab51f39bab40a57402d8ff55e8be3a000000000000000000000000000000000790087b07d0cc4446030d5af3e655e567ec5bf203475166cceb778cd281b93a11060617f44385fdefa8ee6533d30b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161231eada139db25be678e11bfa18bb940da23262b444d005f33186a951b28df6f415a334abaf36706771e1f9ed13d100000000000000000000000000000000148b9d050ffba4de9d217f7fb35e181f8ba13a41588b0d280f911540569236157901b8cf54c5d8b121a6538759865477000000000000000000000000000000000c08c483cfdd8879e0bbce35a74dd4c338c434ef1a321e43584d02774d3df79c52891f07e442dbddc14f1a31d73f8075000000000000000000000000000000000e0170851505091e265d3e01f6b44b777ebd774a25de3b48a3049ca0943562a4c2a4fff893dfaa4e27dade075755179c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012709e704164e1eb73c2fb05b0c775244ea24aca73eec420435e02182ce093161e510478542b4f42fc9a1478085bd49b0000000000000000000000000000000010ee54b9660fbf5f28d3c8069225291c1148fa3eaba1ede6f64def59881081514de640bc8f2270099b6865904ca0649d00000000000000000000000000000000021f022db589032b3ed58f65fcf69f1cf94f8a99eca279a78520042dd3dc5a5b790a6c02de652e3fa3a790bc388a8da700000000000000000000000000000000111d8975b2911ef7d003fb8ff9fb3c75bdcdfe4d3f5773ad9c0b68abf478d8b0c0dbcc26ee02cc6b20fb5c6a73b4ad421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015179afbc87e9d9546d3d1cebeb7c9af8957f0874fe4ea50d5af9b0d14e0e67c0b11302c1ca3bbaa0cb371b62c9ea4e0000000000000000000000000000000013819bd48580f9cdb17e59ab8fd70781ac73e1e7e3ccc75d897eea5aa7e30b4d39d264d1d6800c9aaeabf74991232fa80000000000000000000000000000000004418df4824ebde248b877e71631a6aa23c17dd5a800d80422ce540fc95dad09bd42637b4092906b53e3d8d409dee4bb000000000000000000000000000000000f8666c460e334789d26a01116d74ad0c8686e86d28eac52fa52b24d6b46b4b1aa3678353116226c193e57b9c2e296021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011deaeaf2ce4f55ae4450c02000e60018162a1736d7cf87d642838d7dfaa753f43d44de1c3e3bc58ef1121c193db685400000000000000000000000000000000044f060243e928eacd93e1061a25475d43ffdc8e8b340981696129bb0af50e5bb075caa7a3c6bbc95cab39f7872db290000000000000000000000000000000000742d18768aff82dd6c9497cd19a5a0a69ada2f1f887de7b2936fb6e2a8ba1bfaf0a40751e0bb49c9c6842b29e14526e0000000000000000000000000000000013b6680c635371c13ba2bef217e733e8f60a568e68b31e2096883323d2f7bd9d34dfb24942a51a6a5d8a790e0ff0ff271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001803419526f3f72df28d9d087b06127c66520a2d5f75bf00420b24ddbdd58b913cb9ca092031129eef5ee0738cf499480000000000000000000000000000000014020aab6c106805ba033d124dea06cd0720dc3e61893f1d9ab6cb55eccec27a49459c085990c67acdd2b26e41dcbc150000000000000000000000000000000009a5b97ccd6b5d544996794d0289ba3d84cf0e1303431cb1a3f1f421413548264c7c7a14458f28c46cb3aca8742ba89200000000000000000000000000000000014e3b14a186f8008e5d25bf9fc39c604a82ea6cd6be546a44be6f2650ab1f9f365b4c3fc989a285c9fd0156b47391e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d20e3e12d9b8d9775b6edf748aa50b143d052b14e5c467ebc97baf6b165a8194d2a684d4f393075432ab0ee22048236000000000000000000000000000000000e0461832b1eb9f83f62c39abccf9dc590823c2ed8819a27b9e739719147c3cca93e3390ebfce521d51b23e27cfe8003000000000000000000000000000000000c2134c12e4ce7e80b2b8ca73353380edb76ab4524531c122b1bf0cd7dee4dab36755df3cb34a77db0187df8c83eee90000000000000000000000000000000000d0695e2124054082dfe79933f13a7a79bf39ad0fcb9b27c41d8df86f2e7c1124d071655a149701417e09504cdc36e561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a68897c046971329440530e969a852ef7c9da1a009772d2280033f8f29d94906dad61e5631fb66cb0b7ad2899d76a14000000000000000000000000000000000964c8c14e460f2ec388e58187b4ad3857f2e09ba7c2e598f952534a93e5a934f063b814b7f7244bc0b7ea98d3b210c50000000000000000000000000000000000a42167b27eb20a61c9a1520691808d6c1eb6f6088bfc35a3684ed8ca11c5e152423dd124c6a17137b9400173197ac900000000000000000000000000000000102a59307c0165316bf4504b0f47b1350e122e29ed9a4feb95a9e4848fd6ad8c41128e46e5e84e4f900ea1159501f6b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004697dc1fdc1949bc1629e5ebbc69ff84aab8cd4a5defbebff8e87611b1dbf2d77985cc931e40ba06e9d707be7f89922000000000000000000000000000000000c9cfa3c76637d5394fa9a1f5fdb712d3af88e29382432f352666903dca9942ac08f278d5c81f4fd163c3c3938638ab300000000000000000000000000000000140d1072216269370197dbf30f307692c6699c2ac994e9b6176c7247f8897fc204942ba22ca5e2031656c99f80b8a39f000000000000000000000000000000000f956e3e0547ec8232c36488a7e24a70a9c6d86dec59893477c90ef6904276471056f628250c614f81cb82d80868de991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0f2e13dee86f099cc1123ab9e006ee7d0ca1c14d80f5268c1f3c21cc74adb50c63c06b1e7f837687094fc7b3d9b87f000000000000000000000000000000000e42ea636f6c4fbc12d0cbfaaea58514c2f984013ab8d6065f565deb436a8578d432e2b282aade0f98f64708dc5306c9000000000000000000000000000000000616e759075d548e20cfc9559f21ccf5259871d3d27da8a77bb346046d95e34ee736cc2139cba2586dd74d8deb43503e0000000000000000000000000000000001bd1ae73d11d4c9a0028009fd38dc305b7cda654e92361028c27363fc09436adde8f4b6a08ef644bd62547f418392851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f50857448d96536d5ef5a3d4a33eb14d511b4f4d3b0ac99e9db29f520157e7b6d6c2d2627b65a3e5613c872fad8a9a0000000000000000000000000000000006854b2cc04bcb2465c58f121ecdef8a6b423cbaa9253bb3e0aa3e7d605d94acb93b0de015f2a4b85b15f3ea3033e88000000000000000000000000000000000187d884c47cad9a3c1c41ed1f1bec9e54c623328a8fde5008d705e5d53d60cfcaeb63e48ed9027add5f24dc85a6089ff0000000000000000000000000000000018161277b9968d0f34456be8dbb7d8994f7301011267cde3e50cae92e58fbb6643a2ae16fd769d6b97d250fdec3f025b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccf14aa0285ac35afce53ccd0367cb845bbf2e8cd5bddc7e9128a78c5e96e013cd3f538e25526583f4e0910b147f1d5000000000000000000000000000000000dbc9db4dea63cc29caefe7ceab9a72868930efa5a5b4a12b16aaad5d6e826e3bb88b8d1cb82683fe2fd09645c293813000000000000000000000000000000000c09c8100a2d8b5719a0c0f54c6aa8d1e06021bde9e98661ad3818848da49008f21db3553749072656b525ad5e0e5a39000000000000000000000000000000000ba759a2d5faf75978dfd8f5a540a551b9dd2c67f60df87b8bfe991f1b21fbce7ebe5d4835d84108a85f3240fe1177101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166e832b265aecb3f5a6e2ebdd45ae7360ffea4f64bcf8e2fa0b57dcb5c65587ffa87909995d1d2f9fbb011ccadb652c000000000000000000000000000000001640bf86712e0c6f326929b546c40a623719c9fa2af4ff8d3630f5553956c27f7a7af27929a60c202bc911e34fcf27550000000000000000000000000000000019a7a55d357a58a9153d03dcb9cfa12ad277e14138dc25bafadd8304978403fe45f992f7bb92e544bd96fcb287954013000000000000000000000000000000000d8936b3048ef98e2876c7b1d50c4715fc04121337cb3457e707fb67969b7b464091f9d29431b5e6eaa22f8861c0e2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f02688856c4fcc6f6c570e1c3ad32c96319a7fb5bb95991a3e62ccc1c1b09c6fa756613481be9fa164784b734ce874000000000000000000000000000000001093dcdb9c449293bd6494b022f54bc96cd8da05236d09ce7c2e9422f78673c21433fe1191f6b7a3ae6f4693d07d673e00000000000000000000000000000000016c2353d0bc006295d8fd13e2754683658eeb4e0e9584700e5f1aed9d5d90b380af59d3b10549fb84e34f8fd8ae870e00000000000000000000000000000000107ff5c291597e2e877928483302890c1129e5cf9124d91cf95ce53a58ff94c3cc5d41c4cb6a1e41f8503f17c60e1db21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001302655a302b412023452ec238ddc572fa3ddf3966757813d19d44b5eb3cf251f8758e63461ffcb9c8eefcd152aa83c5000000000000000000000000000000000247d5f87ce634fc0993ef00b1a1aa26b62573060e5682cd2e6d7f4409923c706816da4bf8cdeae32a3ebedff3291a46000000000000000000000000000000001145a7619ca369b7f721db0fc4b3bbc8e7070bb469f9e1587f665ecc2587ea9e738122930df2725cdf25377bb81bd42e000000000000000000000000000000000007b0e1c6c3f270345beef094a644c9c1ad0eb443efa124088f4d519da693d9de271cdf135ea00b9805cacc75adaede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aff7bec9c59d4075164402350cbd7248a272c7ddf7608797ca4783391bf32db5e4e58d166a701057448ebfa818005f100000000000000000000000000000000142e0524abaeb71b84a8b95f1501e1f2ee87781434b509f9bc97c95716f15d28fa755ad905a99e3b09b5a88e44cad716000000000000000000000000000000000ac2a1de84957ace2622630ba3165c44b5969ec41a767a3bf1b541e3064ac633ee8188e2b884f8cbfb8259ed0d5bae6000000000000000000000000000000000187d392cf2d94198fe036404b56bc76bbe6ae9ad153353cd3f70b620da22e069babf34eee14939db2d602cabbcbaa8571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039e33edf77f5f20adc62ea7f2468f4074fc507d92b470a29541e76758873d3419644d3052608899afef4dd984d0b25d000000000000000000000000000000001372a6a3c0fdded5de8cfc0f6792246b4cfcebea5a53edee7e21d9a8fd727defc50fd9c367444b38cf78de35ba5aa0f3000000000000000000000000000000000071d7ee9db8811bd5b325f453f26fe83adffb6ac8ef7c7fb6390d86426c535d7577e499fc2aa5b133bbc694bccff2350000000000000000000000000000000005f5e5610d7905ac024fdf8d45efb7856902f0b608c4ec3aa6ac35d7281bf442a07890d87b04124a1c9fbe6129a689ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d5dce62126f2de014f073841b85b77d7319366b856dc30722cb417d94be30921074d0f7e79d13a1e0ebf0943c999ea0000000000000000000000000000000004444a5232e9d9b6aa04bd1e066152b79846f43d108cfd31a6542efa809758e6321924a5dbc119d831c4248326abaaa70000000000000000000000000000000008095fed5191b647fc6703ae68e3abf0a5a2baa482997ae69b477f5e9e06a6ff78c74c6158b6f02d6fc310e68970d74b000000000000000000000000000000000bce8fc6340a5b7ff722ed27d5ee321fd7ff776efbfa7265893ad39b1886bb10d693e3a2f43c01f8bc1c4de19622d1681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051b7a9c0fd37b4c35229c52e75820c84c207fe45abaa6ec40a277a1d27b601ba4a9ca7834fd4a6df7ceb26ddc7e8b940000000000000000000000000000000005773f74858625875b7bc7d0ee281f9fd75296cba4a8269ce3281f6abd5d2a3bc747dad608831ff405dd03afc5717b030000000000000000000000000000000011b7541f9044e38eb7a5e796a00de796b711d5ea7ec6e58877b6a700f808509f4db6e957b1fd23be66204d331e09798d000000000000000000000000000000000038be568c9556ccddfde756399d9ce9381d94f8f352e31811ccfcf2910753984430c8e792c3df57b49d1b4343fce3a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f7e006167a88c4378fcb43b96ca9d69a141d76d3a41457beda5c24d4ce391fc11afff933cfb9436307f87e521bf069000000000000000000000000000000000c069952ce03883d72dc68f51bf515e5d84ec36453ed17863277cd27a90a3705b9f020ae6e3da2f24baf07ab0229ea1b0000000000000000000000000000000019f2653de8f385f4db69f0ca05398025108f71250479a701abe8b7fbc0eb54a935e9546ef3bcb40882232a23724788e100000000000000000000000000000000022decb44afa4c15fcbc3691fa33a97c3f0176983ddac54165c095e118acfe334f11d0cfd22429982a963eccb6e6392e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f5ab67aa74823fbf4eea840040d959411bf1d7ea277cbd7ab906b4b277377fd2aa42d108354b256c5951a040b01f2c00000000000000000000000000000000184f7dc075fa7368b0af95ddb5b936aa21c6594fd9c50bc0879dbc9afa1b82e82415a72dcedf90c68f3eafb6246bbaaf00000000000000000000000000000000059235c4ab09f4a5fe5c2310f65d589a52276ad2c6443351ae18bff6fc165f057e3d82b393cafe3bebc419dea4d946e4000000000000000000000000000000000c7b1d062cb1aab23bd1e5ab7558137ab6d1d0f8189437c9029556feb9b0f7b2184063ec3ea2cc5f5b03176241c318bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef32bb3e895e074d577ae2f77cd709d215f7eef38b29a721afb4955f34cbff48f6d9ec9122bcac8ab0f5bb4038aef7a000000000000000000000000000000000202d0a71cbdf77a1b4abbe226c04c9e18bb814623ba74c0d22791398e0a4374111f6bcd0d2540a5a965528bf5bf1a8e00000000000000000000000000000000182b9ed7e3d41c69a535669783b2249d8237735457edeedf1da7767489f04b7093a2d87ca03cef263bec2f9fc19684550000000000000000000000000000000009f0b7f16bce7f6d68b22cb75c59cc25c546383ce9f4df786bde94110671f0c9badb591ac26f21cbf6221e8c61daaf361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea27aac8cbbd3851ac4ede681d8b4af2db899cd0fd7e4a006c362991f820f5a96f9f158e8ccfa8baa16d6e8825cc78c0000000000000000000000000000000017ae661ab033e69e0e2a9a29900aea6a30f96609cd60bf7e3f000967e4c3b07be9f24e694956fe551347f44a532e268c000000000000000000000000000000000b99875080448c455aaab8565995c059eff1d0f1ab92d77a753e7a855a189086355e2479232fabe87a9b30aec020e96600000000000000000000000000000000059b301d1077a1a5f9f83b3a10723754aa6dce8995de68df75d8267ac578417bf47c391b0acb77e47f396ee519b74ee91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000010e177a9ed4aa48fa03898471df1568ce90b2e827533119e92362e967b5590293edcd9130bfc9c9dfef6300cde93b70200000000000000000000000000000000134a2c70f369fe2404d85a8826b268b3a9d1407d823a04bf60ad7a17229802c1c7426fde5d165ffd9561f42d8fa74057000000000000000000000000000000000588eb0c6c315f04a2f785367ace8a2e7fcce3393e743dfd7e12fdb360f4d64137b3058ad246d0986f8399c3f7772adf000000000000000000000000000000000d518bb657230d98e9293ef49938868d069965310d4082575c7c9721102cc230a4f8c05a104b41317a7d9f0b0eee156c", "Name": "g2msm-26-jwasinger", - "Gas": 343980, + "Gas": 389610, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b466f5635726ab8cc4e790b3a2b25cd4c895d00057e8cc2ca81111b1857fd336f5b94ec18dc3069f5069cf6a2a1d0b000000000000000000000000000000001491140e66fc8f6b753d1c1ed7f4947d57b5c4e94aaf5883b2f8e2725d586f917bcc2806b74b057241e52ee93a59955100000000000000000000000000000000058a38d7c2a69ed5c8d42d377831fbabe2aa9cb6c9730eb7cbd740075b21fb905f012e182db2f0a7a33a3e579833c8950000000000000000000000000000000014a5dab2f2e5b477a776d2dce6cb194e22b7123a5894c493935ab0049dab148289989a790f44b2615a9d4ad17f4534e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151bbc615a89678c85f4afea0304dd1a061e62ddad74721a92c8f6d271d2589a41efb06594e2e311a5095b4ee49ba055000000000000000000000000000000000e32e24fa5e12393a0c2872556bfe3b15c9df4b297fef463fd36795754ed10b78df15b765a61b2851044c1d844a6db2a000000000000000000000000000000000cca7edd74278ce7547be9b6020bd09c92f77f316f94f2604e2b5872207eca2e703c0c77dd8cfedd82ce15c8943c0bae000000000000000000000000000000000cdabc0c0d08f2a46bd407d82235c1acb4e8175072b10cd719fde744534338729984487d5595cb28dea61ab50ad706a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abc3c5c082c9575b6db14b67300638acd81ca8c633aafcd87747ebc53450e3caad1dbe57da0025cfb9ed48c366081c3000000000000000000000000000000000a8a9e81a2742f8ed63098fef9305532fe03697026434846c345ef34bcae6f03f68312bedc10d9619e678b7e069f0013000000000000000000000000000000000aa8a864a3b2b1be8967400f782575a2bc8f43d813340a16387f26f78f0006b80cf82bcd3621ab90eecd3a85e6d2e9170000000000000000000000000000000012bd87a203e4635ba35eb2f150ba4b33cd9246c83caf899e5ddfba4b0adf862c5d0921b49bb6d40fa9b2402bdb3ca63e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5400b15cc3638cb278188c6d608d0314a370dacbb47de8e41a0ff31dba6a56b0c65f7fb1ab1f4b9fbe4f3eb51d38e7000000000000000000000000000000000a7a2dbd18c4e3bfdc3aaead6addebd1c3a0d3c1b61d93d79d2bec6b021295e5601ad3bd03ee40124360a0f913c5cbe00000000000000000000000000000000003ab5030ca9b102ed5486e6ee7c4f10232a761a09cf552e90c0d039f56f4343ac4053daaf92361254559b2e759b19e150000000000000000000000000000000003af1027d3e0ed0cafec41242a1a63e2850ed3a7892bc519729fb86aa163e2297f1176e284548d3099cd14a2dec2c0b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49e1ce5f171c5d42950a3f8f52cad144fc17ac907cd00077bf201385fa71b7342ac626f9b8fc00faa23f84dbbc80d6000000000000000000000000000000001233419883f2cd06173325b95b2d987f5e659f480a94d44a17f4186f9e7fc293f209de645a924202f8ca70c599e1b5820000000000000000000000000000000010eca16b9389b9a281aec6dd1267c302d2839a342f7dc7b65d24b9fefbc852eb445ebc3b0d9606f1679782119332519400000000000000000000000000000000162b7d1f9cc3aac5cd09d43c2a914272303749b747d48667a7c02bb923e297d1fb05cb56f92da9e650fb56154e3e97de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001757baa808967dd431d3c68f602ab5d6e662c5b028c654701915c8cbd744fad0d1613a4fd619984f7732b947d2334e33000000000000000000000000000000000baf539045f029959312ee90b4c222c2553ed343192f5d98acde57bf7d4b159c036e24b3607be3c8adc38f93ca157806000000000000000000000000000000001177841f00f3e1f6ac23563bf697972fb216c2329a66a3c3a2f91b48d1608842e537bb8003798d14590731a423bfca6f0000000000000000000000000000000004244e5cac4d05bf002941ac9e026cd2f26afd0fb7afabdccab4de13d263f86aef058673447a4182d3859441ac4ebebe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f835602b4d70043985f2056dd8553fc62dd28f894271e2f09c58e088237ce5d60048b1c36ed82900f407b8e57a53d400000000000000000000000000000000060fb494ce78f7333f21c9becea0f427e4e471396634093e121c4723c31e555e92fdb42d112d2148d4e7f959862064fc0000000000000000000000000000000019d6eebd41c715ce733c4a84ed434a5e5bc8d657f0fc0a5bdec47d1ef5f496ddcbbc4625524fb21e6dae2c765e5e63cc00000000000000000000000000000000084fe95871d8f1685935ef338e6dc5d698c8a22a7804b1e1a4d399be1ab5c55c855a97db5b3454d347e2bbd89efbc98e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019afa23b7d9bd52ea1cb6d70cf77b2b82395d3e586a4050e84cac1d3c3a834ca9c7ec1141c5f72bcd015d2b5b0de6d3e00000000000000000000000000000000009796f840d334711268390c02e5c8da4f513a7168e468aa6c9188bd47a4ce8c416e59952a5003abe83ab56f8f63a24e000000000000000000000000000000000cc0d94736382cdb24104ee6e698590c9cc6069cd2fbbaf5720c97ba981a187eaffe983427012f997fdfd0f13eb2581b00000000000000000000000000000000070fbff3c4545862f54c8313949fd9eeed684fc2550ebd750d34f6807249674b2539d2ef4b47b3a8962b473091076cb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d51e907cfddc7d34fb58668d264ffa7570afc9fc50b9bab8af566e0c135eeac33a39f7903df7a279f96074e75f240e0000000000000000000000000000000019513e63124c4dc1b4538440e07c119b631742cd53a02ed551293b6b858af0c9af8e55cd6ff5d827bf406f613628f80b0000000000000000000000000000000014ac194565733db257887988048e6f1c3394a8d3b8234b5f2c7c8d1e16c8e2ae8d47e5c49f23734838ff9a075918edc4000000000000000000000000000000000fa82dd5a9c3f4ac2009764b398c74a14c44d0baebdcbeddcd046216a5ec686a025762c447e6eb143978b9a428c621a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bc878d170467864321de521599563a9fcd21679d30bf8e9a5db6ef8549d4c1daca297af108e04f75f1a445b9ccd4ee0000000000000000000000000000000006fd6ac6eeb972720cc434839b9bd16391c0c83792560beb4064b47257cd217f1180b83a38ab55bdf6519dc1ffa02c760000000000000000000000000000000018a517ff253ce3179f5ec9477e8c77c307efd8401244d3604d1e0c473dfc061b9d8fa6d924ad1ab4fb2662d5cb8945850000000000000000000000000000000014b3791060323ba216cd3e458f5184c05ae4603f80f1677c16146cb9c5fd9d5009a4b4118cfab9f07b67c20be2d898bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bebdf5100096ede591d6d13ca10c58275e9f8328b54b33ee8d2d852c7345cd29746d3ecfb64168359c2e3b8770a50a000000000000000000000000000000000141eebb2a0071453cc5ffb21ea9f345726fd06987be26e4bb34ecbe34a85a287bbdc906d9677611241829e029f6fc16000000000000000000000000000000001343c588ae6a0c06232647409611f5f45f3f0ca31e2a269df2122f13b01fde6d85eb3af1185a8b4ff45a9b4f9486d3d10000000000000000000000000000000006ee525a3b4564e57b24b9b1d1355897b912f778ac4cbb17f4bd8f25f96abbedb932fe35b6b11ddea29c33bb223d3e3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f69f755437bd334fc131c71105c24f0eacc161abe06ccd7bd102cf85aef33d01c24a15cd429b25b227be0962b99bbe000000000000000000000000000000000476d24733c3e642eae49ec8234e7874f4bd8aac0cc38f34b94c6d40fb1fb201ef1aceac301a158fdae38796de335fef00000000000000000000000000000000173848165e601dcbfc32d91f8e0182f6113608cb693dc6e27ae92353444763f4f52402d92ca9c5ae8026e3efda2e82f700000000000000000000000000000000005a7c5fd80b145d071461f7aa976186e101157e8129c4cb3c1c724fe09c96366031a46c8bb15fcaa210643ba2c21d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001497ced1d027cf11ced861566b78301ec4d2f9ef815e80193cdb4da398822b66b66728596310c236b054c9c9ce85d6a40000000000000000000000000000000019400c20c4f93b92b21014e081ccf88f80d9df55caa43dcb6ad638d9ae59b6db0b7388fdefafa4a02c226bd6d94d01ee000000000000000000000000000000000ede5826c6c31c6a5103cdbe9d26c250dca6ed2143ba7bf9158891ef4cad5c30ab8f71dbeb481b23e0a532109fbbebe0000000000000000000000000000000000d1a9307e2b3ff45d45252fdb7bf85f052d6933706029b6db3d65f912fa7330aaf66a0ff65cb9c66b56a57fa3954b19d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f117f548c43bfe134a1a8a2e1861d3da3a1e3b93819e7902097fb426f35311c7d2b67ff09557f6873415137d8e926ce000000000000000000000000000000000a17c85d4a209c992bf910592ed3fb48de953404b1b0c6b31a18afd84b47d9201ec115fa829d68ba8f662d28ddd09f4c00000000000000000000000000000000006a22a4f5a69a39fa527ee223df809d86e60df03b084226ef55cced6e7dde476ff22f1f09c9960f91c42b651c74408f00000000000000000000000000000000123ad07333d2440587cec7c73cf058f02dfe6c992ff539b08391f54efd8ee7be10b40b5ac66aa6cf0b6a00f957b381361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077c9b6e94d1aca3994d5cd4dc1bd6c8901a7d34cfaf149d7d8c02f0232d71533c7b2b1579dc68eb87f000fa3dd1b24c000000000000000000000000000000000b6cf279da391cd5d062d10ae52a981acd28b1c7d3fa193015ce625776d7cc9e5736856cb7b3641f594960b98b577d5b00000000000000000000000000000000127e22eb1897edb2830385baf710090a88fee08c4bfa4a7b3370503c7b602c53ed466bd7ef2dfa88727dd676f57f781b000000000000000000000000000000001279071042c07e5ca928d5e7978d44b944011580dfecfe9474a7a64d4552b259de1fb594c57382b18931d1f10bde74021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b39deb6eca09dfeba991241178979e50f267b297a3cb94430b7366269ec87a69838cff538a4d01ab155c6cab830ee6800000000000000000000000000000000074de9246122562a40367621d2ddc9a6ea7412a54d5b3a74b591684bf5c00f7453ee1d4f48f8545f826620f38cb7fd900000000000000000000000000000000005cdd165ac48c4b0c003025fb1fc91b67da2118d0444c5f13611d392f5f3463064ff921d7befb1d90139c05b00b8b8ef000000000000000000000000000000000ecb107cc78107c8f1b743cfc4bd408f3f2a45632e664e3837729b35dd0cdab30e2a78391877d4b5c6211c3305587a2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a76848f53b0031b5512386e1c695b26e1de06a920bf532ab10cb7be4b22ab87df480970a8ff8ecb35476c6181cffdc000000000000000000000000000000000cd966ee4a5e586fc25e89003e5d14fde890bc0bd2af3c563cdde68fe028fbe9c4496c5b88e8e1c6136bc248f207a88000000000000000000000000000000000031199b879ee7dacd87ba21dbcaaa692a36f4cec0b55ab9fce0dfe7adae1dc1e5e582d0297c6a05325ae578e0c8d8a460000000000000000000000000000000005b7f517f3db32e15aaec1a08685432c200ff98588a6fdb7484d265b7915a758db9bd20360810ffadfb98bafb1b574281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac6d95f36e9d04bc6903ffab8714b4102e6b98f5960387bb7aab3b6c052a931a859baaf813d663a0c2e4594f02fee1c0000000000000000000000000000000015be3da50ff8bb3698421043ae5044abe20d64fe0b71b637140bf911b118eb835f2a5db65b850ec1d1f465f635815aee0000000000000000000000000000000014e0a2918eb0ef192ff517f4e808267f11085868c5528a68f1833a3919fa1f0913409e51703134d268eff3bc5d1aa86400000000000000000000000000000000063bb03518833e242962521dd732c20bdb4f672083a593141c9748515da0bbdb698c3c6f4572fbf4ad628c36a355d78c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae24172927010919010d0addb5f9e1e93a360e015db898f4e743bd02f94cefbeaebae1a42f29364f67a57ab01690885000000000000000000000000000000000d954d74338179804f9e4013c6bc89f1ac0bbcfcfea325e21975404e730af896de9a4c9748d665ed33708a754ed6a23a000000000000000000000000000000001402cbc269a4f1ce3a2194ed8c3d729fe76e7ee202d1ec418e83e1d1398ec3c0abf9f47687d7977c23b1890f1337a60400000000000000000000000000000000198321c68182fc313e1fe922ba70bf4676ef1fdcc011ba3805dd8248a1154580caf8944ba896ee4f00d2d9ada0d323fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001014a533e87e44a11c6155c150763c0efdba3f62a98de9c688a60b2e9a19823e4dff26db690f9b648b004bc6a609e8b50000000000000000000000000000000009b9467efbbb1fe42baa62735b4996e52ef5b29533c65529a4e730f91f12ae36dbdb7ddf582f9bfd2a69a223f81f1fa90000000000000000000000000000000012d94723501dc809147db9e6c45c9c1c7af62ac122132a59d71468088d2332f17a0f31bcd460033cdc10ffd26cd62ed00000000000000000000000000000000016c60366c8815048be831b797782150587d4036b6f65ba649d8a785d2b9b917115924b424366f3ed53c7d597826c54181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e25a976a8a12af765aba9215a395039f56236afc43c923a51bd3ce1c1dd016aa6cad6f74a0f5ea4d57474b9b76a7c2400000000000000000000000000000000007698cc2ba5cf928790a90a09aee40d950c1fc29520caaca0546d1cf8c8b024fedac2c6fddb3477314ee0052d57b0dd00000000000000000000000000000000079047c3cf347eb68ef30058578113f00937c07b7319cc0374b94a0fe1ff4c8542aa35bc18461b3f0f962625f1158b910000000000000000000000000000000019fbf94bfbca1bf093acf58a78f136fd9acca8dfc626676eb9570ec9a698f14bc2ef4042a8ebdb2a8e25378993fa819b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f1af6d0309bf888f652d043cbd16528ca3c86e2f05af1bb362d2a1067eeb49d966b401e13cf5665bced8fcc263abcb0000000000000000000000000000000008be680e4e2c6c4417e401d971fb7275df79ee2ff3200bb9aac0d6542f8257a6af3bf8ca7c95a838d86afcc15f157747000000000000000000000000000000000c28cdc2a7019c6565b9b92c47d2cf047534af6d799c0a58047df9a249fd9f36790e418c1a3518ed1b8e610824d2ada80000000000000000000000000000000004896da286ced4feecbf29deca38853e3d586626160024ae1f1da515f81abdea9fd5625f632651e57e6262cee9e876231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cebf49b9900cda755bbe105d60ec4a47eb79f870921535a00be7c6e2b6689c0437e4478acffa8cdde448c4711e0aa30000000000000000000000000000000004da75fe951f17da29b34fca5c924ad4c6df5a5c6b2b612d25542bc6b779aaf533da07b2abdf646fc24925dcd29829160000000000000000000000000000000004e6f4bd82ac78bbe67bb3522b0f1ed7d632a39d5f31dc5eb2f876bf201f181f94c39e5ecdea60e718e565d5e5c65ba0000000000000000000000000000000000d61aebfd0e86f6e14ab12f38061b29c9025d88b983c0e843f7a438d41f956afb95e762861e732473330a7bd35b65b361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d27e2be7309e7775e3aa1dc94e63d6178cdf7721ec1f64bca85afb84bb20de98204c8f3ba40b36c5aa483980b066fe000000000000000000000000000000000a7a8913f2df351fcf75f4d7a5f1d0125117ee3db2f214d948e7941f9ea8bdcf07f6869ce3ee99d2fa321d5d15daafb000000000000000000000000000000000197fe14215448d7753bfa7d238df37dbc905fad4cf7eebd5103a9cdde6ba93c2d91f87019c387667724d2f61e8cf80680000000000000000000000000000000016e3048a474ee64393bb9913d980dc43a5659c8a37bfe2cd2539d6b8cf4eb75dff68548827662bf9963f00271cbb39e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d90f9f255c6551743de5e571fddccd5c98c844e70c78a90b524d87d894bb854385820a48cfe38bc5e6732ef2ba73ca0000000000000000000000000000000004f139f78b067f05e8bc1cf3ce63370b32b8a163d3926bc661bc5109a694df5c76984eb2bd30e3106ca48bec862d7731000000000000000000000000000000000fbdf8f4c88903aa0e9dea70dc0d21b32af3684499d0a8cfe7ffbfc729513d09f52e83f5670f952ad2789d9b05e3719600000000000000000000000000000000106a9b356cc42a5b1adff8e2e88ff6ba1e341a47211f98f4f1fc5dfcadd63925b64c4849badb2f889bb79da65984b77f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001232f968342d779eeb01286888ce643a1d388648b7868ac866db73584db52d735142b4cd47be856c5def43d251ef6bc60000000000000000000000000000000015b06e1192335b10c85fba76ba8ada9c23846d3e6ee42cc49b5827b57f5b225bb69a0a75ca0869df79e4514d2ec980ea0000000000000000000000000000000014227d905c9900053710d283d7917f5621ac787e22b861cbb5637a6b36df560c2c23b463dc2b1fc58566b36f05b6d2cf0000000000000000000000000000000010121926165535e2f34f413683dc960a3a4a700aa0d80d7e8ec207e7741e8d063b57d41d56118dcaf7b0972a40ec86a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1411b6078aaa7aab7aa1ea0c9c70b13b28d53b0a04a1b4a877aca37e2c9f5cc48b91985b068ed44c38683826f5ce0a0000000000000000000000000000000003ca3eff9a5b1625f84b479afbbb314c6348ce313e691d8c54f21e72f24e205c8ddafa875f1f2edabb85350b144aaf56000000000000000000000000000000000f510fe91a927846b3667d6a6566cf86d17bf024a861b06095849eb3d2c650ba1df68788a9ee21db8e3cf001552b915600000000000000000000000000000000154cf8d5ffa97f8b855ebee6561540b92ef7b6882deb6f4cfe48adc12c0397292f053ffa84751b49aea9018c5bee62341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000daeffbeac73086ed686e84093a9ae24a9cfc12bd858863228fc9f6b27631b4a11ae912c79ce1b1f610980f5db4daf360000000000000000000000000000000017b27cefdfe6b389f1316f3dbcce81887439fe5709f6cefb8046eef4bb45d93a42a4ffc1790621ae35cc8ef2fb6829a3000000000000000000000000000000000390ea0bb7e10fb98aaedfb38762d0b5a559eb0ce5daf83d1029b9110d3f11c81c2f45ac815440f650299da806f027ac00000000000000000000000000000000062cd79334242309b75cbad6fba6494ca7f79110aab975094484d794c1798508b9eeef0b4374c5ac000ff9893465ce38", "Name": "g2msm-27-jwasinger", - "Gas": 351135, + "Gas": 402772, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c32c44fadd47baf1caf5f5b2697c249afa20c8e1c4f9c6e09ad5c6af80c9a8b114d264d75a5dbb3bdb5f3f445cdc50d0000000000000000000000000000000002385341a7ca7b442a4532a15311f0c7cfec23dfad40ef095b2a94ed105f386a254025601542be63a4ac001e47b3945200000000000000000000000000000000133f14dee2ee1c61595a337a61d929e47b335ec0b3100ca7024eb97978df4f7c86bfffc6d30d162bea11ea6738a617ff000000000000000000000000000000000ae7788967f9d0a394a2cd395a5877457b0ee584b0c6f008425cd935f8f793e3b918ca7d37d2eef0721f3ea234c7a8341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e467650fa56c6f0681b43454f8eee10569b8b47305ddee63213e0b730c9d1a1fd38a590f5978458721b48482f69cc600000000000000000000000000000000043148f352a9f33c0ac3ecac702f6c684b06cc7f30862d14ff4e9a86f99e55045162320270b7466353c1d157b096f1c900000000000000000000000000000000032479ecf2080199c137f3a0eb9506bebc1d107e83b2bb0e432e5cf6dfc3aabd15daa43fc32a8f0a755bd1b90c9baf080000000000000000000000000000000015d256b0bbdf546eb925584e7a352f151f0921ddeb471d66c8362e8d986f56b7c2a5c2b614976b5c2978dacf0c35e1861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079fa7060654532d8609dcae11401a192f2530314f77bfa5260d767a76742a4abdd6ccde632b3b4da22a8df194e89d990000000000000000000000000000000012fd50ec71c0b06e86b16772acda4b0d2786953df25a837da27534f696f0cc60d4890ebaccf1182b3b73ccc9b726187e000000000000000000000000000000001383fd9023e827f3c834c9bcddf22347f69e5aa2e5feeac824176c191b4fafd225850723f14051462fef7922489c4dfa00000000000000000000000000000000105eae88ce62a71f5ce436112f44f3aeca3a279a16176dd38ed657cdce280553402e2edac3457445177cc3c642f9738f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037c5c4d37eecbfdd4a7d0512186e8452d0eb050ead1fb8f471135dae07394d5b1ea1196e0038a3f1fd4b2c2f18ba726000000000000000000000000000000000974519652446db6592e810bbd5b0ad1691c248a6d09345a225aab4abfc6da327e5878c1c956bd69237f6dc5fc943154000000000000000000000000000000000ca49b517793586030e93bdc32d969ab1855d89735354168d22ffa0dbf240667c610758bd52432841a9cf6537c3ae1b6000000000000000000000000000000000704b031a6c530ec15f84fd61710d313abdf0244ed47bedc75a605eeab477c8b4c6aa1a3de8f83d5b2125e57a27731801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aff348b47627efe9373501b6a643f5e0318d032af1c17b73211e8932dc50602c3866b2c0cb42e605ce0494044a9e3c000000000000000000000000000000000c19d8f3c8f375124eacf0e8effb27c04c54ba5ee44de223d5e336f4d0903197c13107372d00c92f8a795eaa7920f8620000000000000000000000000000000014b7c1f79389acca1370808ecdf9b30aed431f2d317faad299716a423731ab3fd6e1b50ed20a6dcb9cb2ea7cb21023d50000000000000000000000000000000014613edad5cf6baba2b25387c442199ae84883e9b961fb671f84bd2e55b44ad4b6bb0e7d6fdb8ad893354459686c05931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8add0c4d1b0a0bb17f6fcb2d6d0c5f94202293c7232967bc59ed9cc8a1f59a643a8f8c3619c6584c1b7c1dc860cc13000000000000000000000000000000000e322b288427637d1b8a892c1440851d4b4a8ad53f7a449e396e80707b52101ebe89f7dad1b8a3df99b334b55cd5e03200000000000000000000000000000000029cb43a3f28d085b6179ae8d51fbe6ce1dccf627d3eddbd56cc0360ddb2c9a841e0737bc3a40bcb819d2ffc0dc09cd6000000000000000000000000000000001669ab77d48ff744eadf86f37d86e5bf5627f24ef117750bd48006e9e90121b63f28bedf81aae6fd5165dff675b6b33c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145a016c0e4433f3e01868b4bdfc3e3e05aa88146357548eb02061642b442067442b6e4a307de8a4103a22a59ca59c780000000000000000000000000000000000f2d793d9484a116cbba46ebc6fe2db533548046ed49a9e5e120056969ee6f8c0390aaaeb57f7a6ab3ce225dcb15bbf0000000000000000000000000000000006043991f7fdfdc31c20a0c5cd82f79f7536fcfa5dfd161cd866b8146feab8bafa4e722e8b8cdc7778136e74ff7f8ebd00000000000000000000000000000000038443ced42df60ad556f040ded32506f6e409a4481cde801ce3deab58c6b20e8718cd0ad058d55d5da89444de5428f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afad495b8844a566606922baa029d7e5237f75368a6c13818c4f016164a5016934393c6a5aaeb67246599f4e6fc6c0b000000000000000000000000000000001357d99be4aca05dc46dc0069c5f13ebf6b6635aa0ce83cab4ae7117c15a89ecaa6b75d90b99f87d078967a5aa25e582000000000000000000000000000000000233364039cd0d66d175197f8a13a47fb91b9323ca74364713f9deca73ea1b1e97cce7a33d53b3a4688951dbe6ac9104000000000000000000000000000000001780027a0b443639533d9ed9e2182064a0a8335fb5c474b08f1ecac455ef4e8476c3720aa328e7c9d2c60c76b4fd87dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a092f5f4ae37900d9a46a8f6a0d92d4bc8703c73332814e321f1863a956c7ece319b6ea7c3a1258923cd898627100e0000000000000000000000000000000011e4e1a1f683959b5193999b41abd9ddd647f830b921d69dbd736677e9c865dba82403a0408df67d4d98aaf55099189f0000000000000000000000000000000012308c4376c8bd463f5ed0e861f1b33c30e9c493e6e544b271bd89026edf3d94bd8672a4a64dd9fb0f2c27e23120279c00000000000000000000000000000000003e52b87815031c54f782777a42b3e7f5ff2bf87847d4c3c7734dc6f962e00202f9fcaf7907470dc5e631e0c9b997a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000169802dc492100fefc1058a40c669208fa771fd608608bd8d3eebaf4c6311feffa46d510ec400ae13b08637056e8a0d000000000000000000000000000000000690cd65076937b1c38e887a4a9526a79b67942297f4a53146c834fbe94ec6e6a393361fe90264ea3ac857ad5f43921b000000000000000000000000000000000e96678f6376db41792c9d97ff37479f1dca2ba363561cdcce41cb36353a378d7429588e6588adfdf4d2f0dc74b2945b000000000000000000000000000000000f1e9042941d5a0498758d1cc55914c29bb140129e1a1f1641be5c5b027634f7dce7db76426fbea9890a6fd62085356b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ff4096a7853a31be23cb3808f5338fbbf18db4a719d977e618410888f0d54efe51acf5fe4ec30f128807ae9d7c7fbf0000000000000000000000000000000003efe21c56f305ff3479e06231c54ea577185204731009ac3fd7ada0d71c5283d9408d4238c412cb753bef6b30d05bc20000000000000000000000000000000017c741481aa830cf2d7ee0ad2a137f3767a055318977dfbe45acd66f977959def711cbdf5e325ce6a3b27b8c2cf38dad000000000000000000000000000000001621907bc9e869fe938a37fe050fd5defb558fe760edc8fb2f91069612c284946f8e878b5b7b58a9a7c79ea3457bdc2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1beb674ff1f0b97386fea532b49ce0daeab0eefecec2af119e16df7ce3e3eea7eba74ae5681720c3f154653fc416010000000000000000000000000000000008a333a20485201dcf576e1577f61e0f0cd979470f94888033b41d51bba9acfa34eb134852d9c6d1de948b1cbccf3308000000000000000000000000000000000399cfdc19a26417ef48665c98a2a4cb2da888f5a604026f8f807d7d852ce774e8c09b8005fd066b1a098ae123828771000000000000000000000000000000000f16207f9b7d25871d2d737bd63557d199e7280393a129ef6d021d1c5bac51d6c14e8898b058b84d259e89f8078ce71b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000062b5555f2779d87d835b064616c117cdb46ddc254398ce913d0303a074d165738bc568f9c6522b8b92d7dac752d32a00000000000000000000000000000000132344bf1edd8092e41e9419ec846b9ba197a641068e4dd8f09c7ad9643c21312b6c4f5f95bb6fa002ae155ce76dfcf2000000000000000000000000000000001936e266066d85d12f7c7831c8f6401150ae2c6744a8d1883c374163af75abdc5bb666ac90945176558aee0586e7f9e9000000000000000000000000000000000ac8c26dd493caaa7b6f8777bf89306161a564d9f369a06aa808306ce49ae4ff2d571670c7dcfc1a17f8dad65d8aef651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174ed45b0721698524d545d3ffb91491dbc3a24011071142fadcf1fc0aebea354773ff6071b6e3432cdfe0d01626fffb0000000000000000000000000000000016a297df63a1f9af115382a9cdd33f52ae87b637ac23c13669ee583e42e3304ce26a517604d6eb5f3592bc1ee24103cf000000000000000000000000000000001558093984ba01c3c1d7eac62ef6de58e4c340f4268d388537e2de71ad6da16441618682fb114f7334937a79ecbde3bc00000000000000000000000000000000046adec995a961ba78d1355ac54942f48a2d040e86732b874e45cadd6dec8c97a72e180926c607d220d25f56f320b2551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a3992a2f7493af523a9b8b864333388d2b8990072b0cb927357d072609710d6c2c8ba8faa8d0144e44114a1ded2fa80000000000000000000000000000000007b27fcc27c82eba1e8898e176ce248771144f5b5f989b7cbf9a604e600bae6fde2df0b5bc580a2d8d0bed9a158426cf00000000000000000000000000000000004a58858b2bb28766b4d6c508b15a8294461f98f65b69f257caa6a2885ceaf6a8f69d59a194e8e375bfc2c280ee09cc000000000000000000000000000000000f891227e5d7d79913bdb80710c56ce1c96bff76a2caac15efaaded0386f828389a0d8102ad688e6150613ca35702d6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149853f23488e6b24c4890644d2563b758ca2fd7446069507f5aafc2552a73483b45867714c617ddeec85c085d5919f3000000000000000000000000000000000de47334e2540d9d0e37b9784a4f49cad9b0195c61648b9f6f7214ec3917388fb50cd5ab449ad999f2c92b6a10d559030000000000000000000000000000000015f00cda6697922aa399d0e1860df291a7cd7e417b7bd6a6e8a65ba585afae4f87bb7459de1cffa616be6f9779b9a66000000000000000000000000000000000083cc36154ec20b0b42a1731fafc41e6355a7ce70213914a0c355b064576fbdbe00fa2c626af089bdc9b9c3069f955801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009feec7f4021d9c295007f4dca44ca445c73700159b3f27a759edb0dd09d22856a43fe8a1c1d07629c901fcbe6ed7e010000000000000000000000000000000000f6880b5541c0443f8850b969c4bd280c450a1399b19e2c9c9fc30b13b9862806fdbf1c1bf81e172eb4ea443d5f9c9f0000000000000000000000000000000004f744cfe41d9c07c84da805be6fb0f40db2e26aba48e663db442f0083232b84984b26b27aa3dba491d30e6afc2ec298000000000000000000000000000000000732a3b254a5e2a9d660a196e1afd9e722675277bb4b79074745529410e0fc81581cda9bd0c839437a640a51b7dac4871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001848f8fb198eefa7378d3139ccce119ea9ba588d09c5bbe9782e4f88f996c20f325db0e1e02f24132be773ae7a963ef0000000000000000000000000000000000f8e7c9042b0ec43a0cdd9cc0d0e1a4f4ef9e8fdc891bb3b81d097e760d9e3048bcb342aabeffafeb00bf09207bae1b70000000000000000000000000000000005b323f1fa95529d82a4d458f60a534cac2eb934558a4011bd70a1844d9b82c21824d1e7718d7e93724c92b8b6190059000000000000000000000000000000000b36f327c85d4708708731906a2978ff213f724281a84f80310f113c2c06235a7ca22a185f0ff54de827ee3dbc6f04341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9b83bf1a2b3f7715cbd6f9f89cef4da5c910e91d796515f92980133785726705175960ffcb84c88a3ccd6b48baeeb50000000000000000000000000000000006859ba4b78789a8cd11964b098dc8c60164977ba05fbd96994d7c3567acf1eb65157cb4c34ada4fc14ff865e5900bc00000000000000000000000000000000005190eeecaadaa56f976cfde4f7c686c1686f96026678554d653ce440f78384676a60413d1accc366281e68ce691fc3900000000000000000000000000000000124081bbade758746f7f76015f37d4eab59184d3c9f3171cc21686cdc2394471e820c2a763d6af6c52c46c0d9b4b6cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f6ed89d26040c3bfcf2419ae9c9cd83149640ed66c18cac5fe774a15021df2c9257f7b9ca4a894755963e8c3296e67000000000000000000000000000000000d24f1e8d955eb6b4acf8f85a640779eab0e4449ef20a19f40cb20939f0e58821bac93a345be29ce35e8db31a500bcee000000000000000000000000000000001835835d74583072dc033dead2f95407e54d59164ea056ae8d97412db161ed221e2ae072cafb66a4d78f3f0f82eae0bd00000000000000000000000000000000010ec7d42aa2b58e37614308842682d3a069d772de4efa92a6b3858346193f9371e8c334be145c048f5e5330c55974b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003908992f3cb44bba40bef5f87edc157ed299aacef07be539fa78ebde15d1389ccdb32d377da24ff520984261ba5a13a00000000000000000000000000000000177ee731653245970aba6dc8d30dbda17f1a91466fab337a2472eb6303684c2a9df92e3d65fc73b51e2648368923f16c0000000000000000000000000000000008038c18d14f64c15e6f7f9fe259c549f44140b3a9ca19799b717e661975a31b9ce9471e28eb465ef20fb21c1be783a6000000000000000000000000000000000973e0946c2be86276e8df11f8bc0a42e61752f2ee408e2b0e8641a5b0827f360b0cc947db90beef51cf77619ed1e1d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001691677dae70cf2d936692499e9d4a71c4fbb18bf37cc257f76cb13f61e3917f5aac5650400e4a0fc69bc0c43c578eba00000000000000000000000000000000124c792d0920bf766a3291ff82424c2161e3a36285c0d7ad4673fe8b6757dfec41db4647bbe36b8c4b75878b0f6ac7f400000000000000000000000000000000086d048134090c7b521f713efc2c924153de75c6d5386f1a1e2f64018fb066207e9b6286713779c5867bd3773a31e22c000000000000000000000000000000000f566fd41c7d09b728f29a01730e06fce26039240c6cf6ed8e19af27a3add6aa934dc79bdb520bba6c3959c00e15ee571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bcad9a30a850e6127a0aff1742559d23dac3da340217d7e61abf76035fc8e4d42f3d4dd7501fbc511f3505f41052660000000000000000000000000000000010e1ef4952ec07f02fcf5cbcc0b61afc96da97b13b05ca378e486c7e43ac413c06153f8b528e0caa056f37c7d36c02b1000000000000000000000000000000000dcf74043cb3b1311c0f002e467e568d8e1eca2bd51680fc03e4c53ffc3c270fab376c9560582445ad708d1f33fdf7f10000000000000000000000000000000014453d3b080c057cd112b08f2b3caf148461c7ebb3674c14ba6b43e0a41ef04ed568be719175345bc884e867c411fb221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001769a225954c320889c1d762db2cdb782313e014539c69c220c756b1ec086f457807a2d88cbfc5fa8f69ae2c5579c668000000000000000000000000000000001290789de39019dba6084b3730da0ff035be2aa88aa9c314c87c963923fc90d9948991d7fa88fd02364685702f5fafe30000000000000000000000000000000004d3cd2d0f407d9659ad176606ee02064af373a9dbd46e9139d7dc1032dd1d8e408c4ad8a373d7680b87e6fdf944efdb000000000000000000000000000000000bcdc70c547abf66fa66276cac98b16bdf2c31627ca3cdf9e7631f5ac29b7de386aa5f3c94432cc99730f2effe581b851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060edef5431e31c1a3296a5b4a31435a10de20cc0d2ef1e041da56f92ea96180d72f72576213c63d6077432132ef1fff00000000000000000000000000000000145019348dff4d7cd9598e50e9771a4daf6831a6047ba406758be943d8a48e3c2301d7b0b4eb781f78b79ad7791205d50000000000000000000000000000000008a2d007c3e1637ef05893491fa77a3fec188fa73cb4b3090b8023ecbbd0956e0fb1b2e3a6f64e7ae4c2c16665f6d49d000000000000000000000000000000001262fbb56c9d23b2ff386d83ec24a702805d29a987c434e917d9840d0bb03f00464200c2bc291cafbc9e1f229aa348321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084fd881a84f4cfde6b04aea35235016bef0bb8ff307741a8cf5bda7727a3140cd54995efaaffce708a1f5900e74084600000000000000000000000000000000052b491d09383bc4a2dbda0d567086f78b64ac9c851a5845e474b884f54befa938e396d822fa23d2424c3340464471c000000000000000000000000000000000162370332c6f840baefcde9e4ae3dfbb19ca656d2e25c3b89b05ce2bb023f3daef25e99f62837157f6396709feb4b957000000000000000000000000000000000335a2a4e45bed5b0b14f3e02cdaf6990bedf08c8e50d3e7d0f77ab7cb400fe1641e27b4b805773a1298b005dae155601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000832626850b08f620edf4d26245246084b559da0a08594c2ba791fcd644ef74b984b8ae6c6774fde442ede4d7dc2ec61000000000000000000000000000000000dc369fa7327c040c5cd1df23cbcc608e3cec5714ceddf4fadd34424c0204a050de74e49ec0bb05a79946c19fbb63587000000000000000000000000000000000d3423b795953bbfa552165d1935173fddf8efe251c0f8df75da8f48242e5cd61d18a2f760500064a7418da6a2160ff3000000000000000000000000000000000ac01e53065c5e2e5ab865df80cb1a8af7db89241ecc8d235bb99eab0a085fdb3dad0d102ced54574df4be0a7abdbb2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c09cf2c96829b2b3970b3da4bf26de7201f264f7bf34d2c464b6f1fc7a43a4f9118672d87899160e34e8aec4d38f2c0000000000000000000000000000000019e32f7bb9eaea3f5ff3c0f3c05c862a4c0447765344b6583e6c1602615328754c373284e90658328e14df3b206fd0c00000000000000000000000000000000010296afde1bdb4547ab39b33a3d5bd13dd8669b35b5160c8d8a3b117987e02c1f8fe78927720eda1395ef2012bb107b3000000000000000000000000000000000ed73744daf4c697365ba066bdc52ea310e964f43a601687f93a83e03241bafd55b9c6bdddceb1c4eb92cf36eb7c5ffe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000da3b3e467719ac6846145579f4c1504267ff4f3c6d24f367e80ed4c6d30853c7829aadcbaedf94a5cfbf7ebecfdb755000000000000000000000000000000000a09cd8e7a9fa2b2eecf507f6555f01bc96c3d4855c82c0438da19437a52e2ecb6f8c8c212ba1de60b1de36642549f7e00000000000000000000000000000000140c29dce8df8b8f9ec681751aa9edda15020e64f80d6571f921ff82be8537b90f0aa3d26bfafeffe2c0e4968d0da9700000000000000000000000000000000003c7f14c2138ee4cab84bfdd13d7cb9da96ab0f64fc24f6bbbe1c89d0bde17f8eecd43dd3e1f32112741474a6b033aae", "Name": "g2msm-28-jwasinger", - "Gas": 359100, + "Gas": 415170, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aa48fafe78a2b4376a28048e4c4c1e12176f6c56103daa1606ab6202c8f4eb72ebf5fdf670585c9978e1e87edbac9ff0000000000000000000000000000000009d9deecd468891e55d5f1bfa6723336647cb41f625c3cb351043501b595db1ce4dc200c1db776b69aaad15477280b06000000000000000000000000000000000357229e56063b99ab7bfdac216c1fa7ee5e9f80818afd64ba4108f8ff2e372bddac1b2551ec05b7bd747d3e1364d1710000000000000000000000000000000007d4e5bda6d0f9164758e4fc3d3821fb3a8c0298aa99683cab239ff339b80013909819eeecbd5745c63741d06a7874871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001507090a640fa7d99fd8b208fa6d59aefd7de175d0673d419dc5ffacd857a74f55cb7376ddc6e811f45c8b5dffe7890600000000000000000000000000000000083f9e6c3f0f2430b597099e5267ed7ddea3c59cbeae2c4b4ee8cb2f80b1a82d29c0e2145c126c95998de937d3f1e9190000000000000000000000000000000007399f120fe005bd2b2c6abee1748e915d031311a4a52bbcfb59bac197fd7288c8d15c90167fcdce7b0da325f758ca480000000000000000000000000000000005b0ddd3ca56c70298b4f528d823325171057f4f3b4c9936d4f1a6553a6726a7f5690ac1b5abd07044bcf955b9c809501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016587812fb8963dff82325c7f05f5887ebfa57c57ed541f1c3975ebc6706b252b022e58c38fe1d129c710a627574a28a00000000000000000000000000000000171dccb6214661f66c8e36f1e54206a871fe316ec6fd3d495f2cbfe3404f46c9492edbaf0ded72cca404b82336e7c40600000000000000000000000000000000112f344b3ef0b3d5fcf1d5523bc8141965e0b38c59753d7be12c7d690b4fd7d36037fdd6ab4185c6b330a1d6b4a6516800000000000000000000000000000000083cb4eb6316f22ad5aabf052c5fc95ea61a51f68824f752c88629175cbb74be05db55600d16dc5fe314d1a8e0dfe91a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abd7cd92ecc3411b185d21213b4b3166421771ebc297c2a64b72f1038fb8b1a09dfea6fd9a2a011c0fe74de560308d300000000000000000000000000000000140ca465273d0e99428b79bbee4c8b447130ae4e4ebfd8b21e6f5a103497f23c566f77c4362bb94d061be15797d4e2090000000000000000000000000000000003e458704d3b65a6b5818e45003866a244e3dd15ffdfc305f513ed3c188e363519b6bc354e5218cf2348997b436668f9000000000000000000000000000000000b75ebe347b33a775afc9fec184387d05461f34fcaf45571fd62d119e7d767c7a268e8b3c81d97bdbe09bd516489752f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000829524bbf33e3e8f436de9779c236c0ea4004f339b75706f7fcb188c6f5b0e870292a725191bfe8adcefc0398cfda51000000000000000000000000000000000c34e44c99a5b962b64bbb0e9f270ab7a524ff6cc8af4606fcc71a600ad2ebf8cdb4b60083f264eb4e96d6c4dde7dc4400000000000000000000000000000000113f2713e356f55b4e0f246f94a28ebf8dcc4e71d069e5a4ef76ca34842704a109b7394a67c98334eafc5191e9c40ded000000000000000000000000000000000f1f106b73bd14746bac12561a70326690608e88a37a8091f7c137127de179b2b7923f6b6a1425272433cc96ecbc6e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001539b41e46f218081ec2a02e6f59aef7bdd3d050ddfd350a34561c1b5f00aac65c1386173f4702aa472e2293407650b500000000000000000000000000000000145e0084bb792c726fe629f488b5f7bc07e46f17234c42bdbbae979d333c916b46cec63f18c2e7a7bbb9d3ebc52c7f72000000000000000000000000000000000605c56237757b00f26ee97b2de1e2f5b55033a071ecda57abf247a57c5c2e8a57834331c450d2b7b89fc39716a47972000000000000000000000000000000000c8e2b97dab2733698b3720081bf4e772f0f9de54427ad6a871a37ea6c0d0ac404cdbd6480ffd483b3e1341510e9b4431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e2972abebdcff1cd356c5d60b0024c507a8693b8efd1949049e086d9a4230c418465546badd09992a690814f1ab9110000000000000000000000000000000003858d6c30c4a87b317b4bea982f4191a98850287745a0ab8e72c5e51570bd1cffb060f264baabeef454bc05075c2d550000000000000000000000000000000008fcd3871c10813e27b7c10b5aa7a2b5a829d0402536c4fe0b81c80f581b52cda68bf0f08dd79782d4e41268d6f840c8000000000000000000000000000000000bd97069ada3a0190cf7c9a55ec0e03ac9b3bbc9c71b349be528f8e87f638bdf8078fb373f4358acf136b642293c8dad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f87ab0a664060c237e8ab4dcf61d10ea8002331fde5edc04b72fda604fc4cf9befa9021ea7a1590d601e6ec27d9d990000000000000000000000000000000015b880f1312695ec797223d9aa08e63166b7d958f988ba70f8f39c003b5abcdf993aea7e580d70384434691a262959d00000000000000000000000000000000000da2f26350a8713b6361020a6ffbe60457c55b863179b4e8f38a66b935f45474de7365374360cd36d9a77349bccf91e000000000000000000000000000000000522c27225a640224b35c0ed856ef628ddd614d2085855d687058d132ec7c49a69d660e7899428344ab93318f54cd2331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011528cab84ba8758244c3e424cfc235fcbd04b22a59550e525281cce226572d6670a45d4181910a02c09092b3b4972a50000000000000000000000000000000006eb7deadf6e2c1e4c006f7d97cf17d818e7758ba5d40f840244cd1395aeb496fe78972035c366b2b2549e337b8b80af0000000000000000000000000000000012fb39dea4aab8dafee722c01aaac139e830c73c57dbbdf8ee17b151973cc88492ed9c39832e2be054c57d437ef55ecc00000000000000000000000000000000188c3dd0aaded2140f4d7d424479fb4e2eaa72499b10791b448cdc78c6309864102aed3239dd5d7cc80943cffc63bf841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175431f2468db8f49b52d5f691004084b75d7655f86785f0a829495f637d05377805394ba70653494c11b6c67a0601a20000000000000000000000000000000015a188d2333a58c2acdb9e30c437de9efe2b504b3dbff7a75d5d69b31ce22aa16f5be833bffec2734e29425a6650d64300000000000000000000000000000000121631e432a98f47b218643fa8f0231825df6de554c63711be0066d8359053dad766422471e8bfa2ba10e00b1c47a47e00000000000000000000000000000000001c5f2697a18d7d4b4d7c5a97c2108df05d1981ec9f5b4663f01d64bbac16aaac73d6740eaf7fc5cb0a8537b5d80e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa6d2680a8ea7a149fc7895547aca4d27c83e032f4f4596c5723b1d731838c46c5d8be8f43dc2708da277b2563010510000000000000000000000000000000019bd4e3ba469faba7b4181b340457345eaf5926d79e5ccbd99b801897dadbfe881fde0de5335028828d920dbae86186900000000000000000000000000000000029d29427b363979a7f689f96e2cb698b031561520a18481ac3caf31eca411ccf853d44a3f04ac8a94072f84cec0a14500000000000000000000000000000000178198f30dc0c6b1f0e342b2730fe87198dc3c6d295edf3715ec690346a482ac7f60320a9271bac492b2a821b83ebea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002793b4dd7f29fdb3476f0f13a4a92376f88b0080d0cce6bf8a65973747314b19570df538a5e58206073d852453fa27b0000000000000000000000000000000008571739c098e0fee34025e3ee3868101a66b07fe19f0401c3b66ee1ae2a96e749977d67cffa2dee723ba01db0400d6500000000000000000000000000000000154e5a901b96124aeb581e239b4deb88f8b542e63edf24eccb907bdb874701dfdf99375848cca31b032e2f96547d322e00000000000000000000000000000000173149e0d6f1105894e59780019612636fd7ef4b448a471766f3acfc6caec551e3f8760a3bb65b423d1c79589f3561dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185a19b65d380bf4e4956bd65a5839f71596ab2233adf1587eb4a60b2780fb28877843724845ac8065b1f74b616f678700000000000000000000000000000000063cefeb1291b32c8e45754c6aaa6c363bf06de7bc611f7a1b4927f4d17fbd8da2d939b17b2afaeed8c3d412129bb2b0000000000000000000000000000000001868356d5a51c3618b8280f01d5b7a36e74dc2cf4313a76c9579b90cae1b447d11f4a8bc3183e8938b95010141513118000000000000000000000000000000001299fdcc6953639c3bcb86fd256defbd9b278041f3f58671b02d561417fea98db8236022b1fc2bf5328d7f54699e489a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dbff820a219d9e74dd850fdc91c5a6b6ac4f18e3d2da9cdc06c1098c2bd7e4d23d33da731630eca9dbacd37cebc022000000000000000000000000000000000612f23323f8b468b2a5f8b222af056a4a4cb619e2045ff9572e13221928be2e961ec6bf08870dee81271566ee94a0ac000000000000000000000000000000000617f7aece41db9c7961f063e73ee8b6851a2e0f6bd3bebcfdf03d67e5cc8704433454afd862b7d1a13e8e5bca1ab5030000000000000000000000000000000017fa0bc3d544c0f299fb6ff83273ed28e918bb278726ec2aff725fd5a9b9ba1a16958911ed30249606d35af6f5925c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c5c7cdf872a072005c11085c7990b78062e97d203763939b5bbde1b43021cf68dcd64260ebd95207d0428ddcd226eb0000000000000000000000000000000008e2c5d6b5261cce780717cc04945c6e6b0f056fd343140baf30fdf8d8e4c7fd0ce274c7761f1aa786b9797f63af931200000000000000000000000000000000008729e66b5f0040044489addc00ce4ed524bdadf835ca54da76ce447e6564e06278e4acc7b27f2ff95e9b5b51a119a20000000000000000000000000000000006dd04ccbb74b57fe14fa4d564ae16f7da40aebd9da05037145f1917e475a51784b8d7ac4ff7c54424c89886d193e9bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d88f718ca5e4bb66cf7cad1587cbe473be2c18c706d7bd3b5032fe38135db7b08df605a401918696d51054dedf3cc40000000000000000000000000000000017b644ac7b6e6fb8468eaddb8bfe45d65511588bbea98e5381cfcf7fafa4a25d727fc7437a0af08e4d50663bb29060b30000000000000000000000000000000007edacbc4649823b8bb1ef798d4d3842fd5b451933a92b1184a5d78c8415714a36cd446bceefc23213481d2495690561000000000000000000000000000000000ff036a27d6c0ab6a2930dbfd99fa7349d45354823b95e097a97f78a82092afcfd61d6550a4dea0012b7a1316653c02a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001313459c3a16c613f2b60d84103b35b34bf1c16a03f5bc24bc2f26953884e2d40a47f10487dc45ac531eae33d35b4795000000000000000000000000000000000ce4f22668073da84dcfddfc892056ab6b20ec2c7dda4ac7b3c7cf5423e7ea59d07a6a7516bfb9c2f8dfae876f94e9e30000000000000000000000000000000007946a3dc57a0fc19ceafc7429e4460f04e98a935c373223cb1dfa6758cb336d2d17bb2484546783f082301a566725790000000000000000000000000000000012a548ad8c81060a43ab54e482b9f7c54cfb63d62e30b94bae95912231ad74f04a03d47d0f33d2ff5d21e41db537f4be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bd994e7e4cef99edb0d02fe1330faae8bae8d19bf6ede6c21c1908018b887eb654392e5e10231c297850cdedcbdb83000000000000000000000000000000000b27c5be6e5087fa9fa84600a13f676d185102b8138326fc7aadad39079f4cd276711c033bd90117e9ac81824a1b54df00000000000000000000000000000000002d22fa29a3b931bb38c61765b093f3c9692a9b3b1967dcee90f669142ff5410e8880c5a52a2e558de01281a8dcb24900000000000000000000000000000000137bf2290e637aed7d8934f97cf8eb4278c8697b7736fefcff8b738a54e8f340ddc426c113dca5812680cf901aa73f4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000887db81443eede54af3efdb3bca266929ddc9e9a43a120642033f929912d34ae60a9eb88e0ef03e338f49235403148d0000000000000000000000000000000002aa770576dc800b4c5316042c809f3b6f4d24a6c0f646a65b7ef163ba4930a590f361ab9ba5bd0c85625bf120e64f4f000000000000000000000000000000000144e9b78e3d876551d5733cd1df770f74eb23fab0c4505f7904129a39cf82e0323a2ea27174f1eb98f69a40dea6ade2000000000000000000000000000000000f2042a342232e512fb77ffe9c73751a789d79eefd89c2b4d20a2bffabc421a05d3e935c038fc99b20dc38654f4bba4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fb52d54a514106d10da8b316729a1af301be2ac319dd66c5cb6c0749c624f5c91106e8d42b88f26320598db46edcac000000000000000000000000000000001373329f07b87be139bc5a2f245a522f66081e79d9df80659b582649976d1b036fbf078e9056ab416fae5acea3ffc3f000000000000000000000000000000000160770d40d555dc2ba7563a54be90552411400a0425f9876420665b38d269a202d6926bfb08e5a343a2d32611a9657790000000000000000000000000000000000a4fc529f6ce817d254934d9160be43c28090f01c21a46b9d8a343b945f13a6054b3251f20a8be03eed7952f085f9401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199a57a493b04e40814c9a844de681414df247f5ecb879c495e3f5d01a4fb97beff515ce3d717b6d5c560c190132026400000000000000000000000000000000083c6c6d678aca761f4389324e72cb884c695fba93a992c55e6282e7f57e36616dbe6f0922a1532277637dc76ada322d000000000000000000000000000000000e340e248005b2be75cd19ae8ba96aff10541e70b2d8597c3cec1d00a89f7242bd4cbac0888293f182cbcc00db65fb33000000000000000000000000000000001513bada8318b97a8be4a26394f3f11748ef75fbe438f76573a371260e5359c3f711c45392085777d29e94c9d7a923701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009217278e4ebef81fd3579d265c30d086b782240f14966589992fa8d64f5f2508504db8fb07ffa70f0c0adcd7a42e8360000000000000000000000000000000011f8d5fd83554d971f39fa2fb518733834be58812f3dad21eabca81de0110ca36f9c15eabf4d013a9c7724a552a0dd50000000000000000000000000000000000306260b94b2c4b5461c932ad85a7d7dae1fe6dad06460b71562a08004988fc9e529813aa09c15c6b6f77dfca7e8045100000000000000000000000000000000023145d719e21530f2ead68f799cf2b2970a6bfcbe23d3880e7f1ec8188736884c2e0f21ee1b4b374c3df11268cf2d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001576a4966ac550a5d8bf6024dd2043a71485f9d43e000092a1a06efd63c6e8278ad29c38de54812497ee7fd1af8d83dd0000000000000000000000000000000004c1111a2b00edd4fb0f39be5b576942eee469d37f7b21a523567ac2450846d743291d3bc48e1660600c33c78e3564d9000000000000000000000000000000000e0e76855fe748d3b4f9f2ab7fc41bd52714c446b4a663e849def5e279c6cfcf8d29c0e18dfc4c45437ba94bfbb761c900000000000000000000000000000000102d7d4ec73b871ff72406acc945d6fb7dc2ab4316942b235b0be1a02f97d973e75d0a1e55478f21ccc52a568f3223f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193c1e99ed56aec7f1b168bd7aa359bbdcb2fcd92d918eea303451b639ceb00a32640b44e06d960c146bad59929c90da000000000000000000000000000000000b5d12e7c8db75ca0ac748d5662a4263cd420eb9a32beac5650249b357b9197ee3eed6254bd4a0820011a2af4730b7e20000000000000000000000000000000007a63603bd9f94ab8250c4582429a0cb63d4056f6c49aa018868c40b8595c1af28e66634970354a10f5bafec32552955000000000000000000000000000000001419ac2ffe8fa879eca99a745fe41f215fe61e8dcd5d882ba4a836ccb29c70ecd3489a25be6be7752f244a9f73197a4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e8065d43f90763d365a9ce2ee22a4788011b10cb824886d068dfc3a17177b79910464569bbf41cd66cfaca010c4af200000000000000000000000000000000002fdca6495ac5f397ac17143d39d3d1788471621b54b40441a3ba1cb28dff1b993021089bf71adb661b1521678c17d80000000000000000000000000000000018a62f766a85f8578cca1897ed333d3ece770d10c800c0a65d6412d6ba0febfa495435a270eef1d0f83e05329df1094c0000000000000000000000000000000011f3e53424a279d71674626e26f139367761ecadd085c4941ec45b8d90e25581617a00ca13896cf499dd99d7b223bac51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015564d15414b53e91b52f86bafe8028653125e789fdefe2f88ff0593bc9eea73cc6d76f258a1663ff8704aecd67f16b1000000000000000000000000000000000e3697eb5a8e6c8db1c0ad2caf34267a4fa4d04e919c7b833536a2bb62096edc9ad82d564badd5f52da138fa3db8d43a0000000000000000000000000000000010f6c326a779811325392eaf53be300ae140f35655d53a5f0b69f1492ee4d8dc2b6ce9296fc269b03e9eb555d69b8f420000000000000000000000000000000017d57fb2cc15b838e55318e7d46202ede40ef5cc05e4dc8469135b96479d201bcf72fc6ce37aea70286354f1ba08f5ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fbf328148f76bbae0b3ed2272cbb5233d58b09da8061b720de301a4f35b4a4ee8ae8e97d0126558861741a060bebdde00000000000000000000000000000000120ca59a1dfed010d8edd6d45a5e6aaabcb146c8a1d969f0c673984ba08657d49bde5f673a136b6f792894cf7c3440dc0000000000000000000000000000000006d2d5726ffb08fb2b7c28079f652c551bb298779165bf1762b674f737a27186860e8f411fd5d985f01377c3b2b6477a00000000000000000000000000000000127a99bafb47777b4fb7ecdded23b54eec37383d5943c06c74812c73458bf2ff6a7bb48142489fdfe21ddf35567d51a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6ab8b871dad2ea46d271be5290d1815a7c412c400abccd177db6b31c8f143c7e9c3c618682c6254184438f77d4e035000000000000000000000000000000000ecfee9da433ed8ea9dac251f73d92a19fe25faae8b3b328efea227de7ab405652f1f62f720916096dff6ff78edef9270000000000000000000000000000000016463b46d87866de38dda7008c70ae2cdb7bb9d30c08dabca4218633f396b81d70dab5a621a79f10640a4fcdcedf251e0000000000000000000000000000000001a323dca99ef212926bba5043689788a4b666acc6cfcc3610fba1ebd4d09d37b0692839dcc85d202236252ecde751e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038efc596eebb9d84bd941e08c79868525d8d384075e7c9c7be206c191f397c6b64a305f89e4818e36f87dbe11b67ffe0000000000000000000000000000000008f928a5d9986521766b72f15fb235850f5213e2fa85a4eea57ea040c0669bd097e291ab87983049a3122756fcd1db5f000000000000000000000000000000000d7b0918dadcef8419d6baf0ad897c976e8355098ba679ec32405d153abdad29f4288e5d36da4d6c94ef1ec13b4fc1d2000000000000000000000000000000001251840c738bd99f1a52f65d9e7d60b3b303379227773e5c2bfd7ee720c62fe8756c58d6506af3ffcc0fce5102a3dcb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000148142228d70d5530cb6e4b5d9f1cf8b9e3a5f589c04eb17254d12477ccd77fa44a4bc38cbe28927303c50ca98cfe44f0000000000000000000000000000000016f448dfa986ce9f305223d47e5bace1e29e481299892c90c5ed8cbc1456179029b06c4124f1c5f42a5cbf426b632866000000000000000000000000000000000d8d49a7ea64ed2e965181cd52e1d73a0b118543db26363eb8c8e29e50f14fd69fb01ddee38ed91f28cfc3ba16656182000000000000000000000000000000000ce5f7aab86a9c402ead61a6d2bd0a578d80868bd643b002c6e7116662f9dd244f213753fb38a634a591aeee8cdc4384", "Name": "g2msm-29-jwasinger", - "Gas": 366705, + "Gas": 427387, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001843fba3fafb6163d2d6f44be87432830a0c3ffc97674301e63daa5bc30f624b619330016fd5d3b25ff1089180b0911d000000000000000000000000000000000523cea9d2c4a053a5711ad24bb4f93c25c5abc6c3b0fdadffb63029a67abce0406b3dd65bdd41d4e65a10d126d9d4ae000000000000000000000000000000000d5a3e2285919253a4771da89c36272483411f35d7d29722889cb5e59d2fb9dc1a9b0ba74ab100aafcef4519bbaa154a000000000000000000000000000000000c460f2632b593f9f46bbf6151d92b9d90c67b95ca011f33a845afa8d182be74cf5e7cd83c21ac1e95b0a65ab79d0e921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130e1c30240f14c9ad3101094c88d52b364dcd4e3562df00a0574564f6ac25bf7e26bdd182f9606ee1bd781425a1b7e60000000000000000000000000000000010ecf8ff470563d180622842b4cc4fa073c6e83aed8899ad2d78a542734a31002d9120808f219944b59a50306537ab32000000000000000000000000000000000ea41ded7e4077bb6339e54b5ee6cb498a8fa3fffd704e55d7fc74c9cd5785b53183ee9302c140866d12bd59283a38aa000000000000000000000000000000000ff41ad8bc71519dc5582c7d73912fa3c803727e229e9182e331ff0d4cbd492ff7c71b3b0a4c03f44563a7c53bc0c13f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cb7973898106279b32fa8794081bad3260eeb70461a316052c97676f85b11d1fd427b09b4f5d07921182a26745cd9a0000000000000000000000000000000007eb11ba3141550bd52f28f0f71d9a0eb4416dfdf007de21972ffed256de46def48221b8036449711ff531c8d4cd7aef00000000000000000000000000000000122e123e1bf9949f4ab82c9b6297f9ea510aa1179bc5c04d8026eb5f928a791d5900dfa296e45c21a3db278117ac0842000000000000000000000000000000000a195a6529a4baff5a4e300f31633a122cee97e5eec417cdeb5cd5cf2d5d38f2dade528304bf17e6c46da23fcf9c4f211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002663204ec5b181046b80ea44b88ca0576b090b99b44aab4e9142f51594e92b064ba4c4e1bbd2e624df87164d4132a7500000000000000000000000000000000158d39819e15d6caa9727efbcd86449a48f9e240b8eecc7da9ede44762ffa7366811d09edaf435589258a6031416afa900000000000000000000000000000000052a0c049a806fde78229535b730ee06ce511590c887c331c7e1f389dccb49890eb523bfa6be7670f4a4b9f91c3b0c1c0000000000000000000000000000000003a59518ee1fd48dd11a6b69fe3a791da090d51e68c56db675c0b305f5545801aa814f6029e7b15e51d6f38fe2cae24c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d6d0239cd85c5c7b666294fb673a1ab92dc54059dee72f58127324dd0084d9da277ab9c75ef2b3b1c18f564f20ae66000000000000000000000000000000000fa6b340557c8d513832a58ac7254b46ec6f13579f0f76a241ac767496812b8899b5fe68e969ec22d7edad56d07cdb07000000000000000000000000000000000e67e6469a5fc08eabefcf2b4dec7da375cfda17efd21253e5f09adb6258c1bbfae1f9160cfc70698b27aebd2d0012390000000000000000000000000000000008a907f0f5438cf58308780265f215f9661c6bc18f9d6891dfa27953f39cbdf9aa2dbac8efd1890ec0aae51739ddf9031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144a68ac59c084d38dab96b5f7faaadb642d53af5413f369b340c15e292448dbb6f504e95a26696d9ccd32f65437021800000000000000000000000000000000104824e1cf15d29c96954b6808816412898c88cb5d11bf08ffb718f9df7a2299d5f9dbe287007d51bb7d973995031ffb000000000000000000000000000000000826b9acc6109a8000ed2627f7b57512a2258c94fbce7cb7b3b4bcd0ad71fc48518494fac9c2c018d8767830c1e611e6000000000000000000000000000000000aabbe550a2147973080cfa0219a5926aad45e10b912b651ac03865f4db8a515f162cb5434b4c563441f741be786cadd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6b1f70807ca67555ce9ca2970b715690d87b23ef0b76f20fbfc3779fd1c30cb3d6b259790514ef67024832e7a746c00000000000000000000000000000000005fe5649ded30720a66faa746f44dad689ee39ec0a0ca45effa0c82bb18bef9601b36b352a40baab6ac774f0ec3ab3a500000000000000000000000000000000194859fec7c6fc72215e641b079e75671d2cd85647cf646ef53bf89d0702acdae542a94ea81e800540d3aded7527a7310000000000000000000000000000000007f85d918a78589754bc8eb9e2e7234e7fb7e2bd3d3addbe76e76884e926dc6f796743f8973a44539b7b999ab3fd85eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163873a4a926cdd600d72e98abd92c702fad8b8a09a88d8c967eebe2e38799de75d72d20ca3886bdb8b4cefe0d2af5e1000000000000000000000000000000001100cb70b45ec19cb3dceb7d0859a2aaf9ace57c7365f9a8d5076824b93925e999a465316e776be16c96857260d01bfb0000000000000000000000000000000016ad120eecbd21d1898e4906e421bc737f24c27bf86572796ed9bd87928ec9bf764a8fe739392f5ba3c9af285f07e60f00000000000000000000000000000000194dbe8faad718436fb8b711701c707c8df619b53a03e809f6f6e258f3e963e3a0dcca644dbf41ae1a9e0a435783757d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd7f3a59b80f50b8b00c5bde398ce1895a3a39a008bd637ad51ffdce62e40051f1dca8dce99a393528286ec78e3445f00000000000000000000000000000000108ff554e46fb6dfa1be318919f2c0e2fe7c89d9a64c46f356e50c021a0aafa1641038a4ae18de62533dc6eaf548689c00000000000000000000000000000000050f861a6a6ae79cfb2ee14a70cd20324d64051c2771197fcb0e0df0a4be9e8b075a58ed81d330b605bf29bb728aaede0000000000000000000000000000000003c1e1f3ee9d9b1ccdd1bc7d3f82e0e9054c84dd522958f9c8fa7ef480a42ced10022b1ec21328e83845439dd8577fde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b788b2134d0b2f7ac2bc676c2acaf9ef949913aef81770ae4c058eef26d7d1228164feb78ee8d1b56921d1dd80a77a000000000000000000000000000000000976417866e74d5058419e616560038229db329d12959d5d38843051e7f2924495bad8e9c5f03a7a94d16da290762dde00000000000000000000000000000000101cb024fbb74e39c4a608f593dd1e3c52d08be36a8795a34e52c7ac8569a2e8469fbd5b962518f3cd27e46b01664a1f000000000000000000000000000000001706d4f03160a84dd89be4db244646eae56373a614e92f7323ec55fb57d7bb4d34ddcf1de3afdbee1d4606ff5f88fad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001533fc6f0d483320f6724b8a1710891ad1d7a49e740f32a53ac86996439b4ba306f0594850c82f9837da589c51bac1190000000000000000000000000000000013703a221a1328cab98f3080687dd0452531bb5202413b3763cda20b2e1e313b99cc616f9ce8092d62c8581017323ec2000000000000000000000000000000001583d535bf030af9545ae68d0607488bf68ccddd54692fd699aeb1194fdb0d59aad7c9273bf62a8a6625b87fa37ae0f300000000000000000000000000000000089f5b7c7d6fb9779f12dffa3c4ff7a565ba7a92b0b9f9944cfa29fb3b6f083f16fb6bf3ecd50a237f26b28221df3c6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001346f358d75792dff013837c8175f2396c77207b6065c7810a9d7e3688d7d6b00e0b0aaf9d2ee204302859f857e68a4f00000000000000000000000000000000102d012929c79dafc43d2755091a81742276156d354f28ae8d0cf110b0a6404093b6cb2fa78788435b27a9de0763da2600000000000000000000000000000000176c297a742c3fc9fa766445ff945480f580f2049795d5043075289e05a6e395a056ea7b1b54d68fec03edbd281fcee5000000000000000000000000000000000f946c72debaf9ea49e336a43ee0c71c52ab5e273000d786f8d1303e94f30fc3a949d03708257811e06778424bc667211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001787a88e5237c4b918bc1e2a9ddc0c2490d97d4099586c87d49d1a0943503d3ef00ecd068517510a8a5a29809ff630040000000000000000000000000000000007e47859b162e5b13c4d5be78cab0671e4be52446cb29831152b44d4bfff567be2c8bea91ee053d022461f1221c47f1400000000000000000000000000000000096299d93953280d1efd447427f758b5ff7d2fb8ca4f32dff24671633040be456984585d963dde42afb02c444610e73e0000000000000000000000000000000019d947ed09cdd3e5638653fba5c27bac4c7f65626ebb8f6930c0e6ad5d0fd9522ed6b3341593eeb1f5828cb9536a4af91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5a990f728f2f819e364116b77dc29a07a8f31850c1a4cf9a9e915f376828fb552e69e47582f1fce16d6aa55e489aca00000000000000000000000000000000192616c750b9aa9b3f59c17c061cd9823e15bc13958150fb4e738e118f31c1a85cfde10625628da689a0b8a186219273000000000000000000000000000000000cc9df7c72e928cef3fd126ab0689a215d5120624b1e7a872d75d6bfecc113f2ee46027f884d953e8b87bc3f6a747227000000000000000000000000000000000737e28f65ca6e0441a15397e426fbe1a74c459eec561a66049a73ade79eae91aaa6e58b3436285e9dd1f644d0066f061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005646eef0273cc59407ce4c434b4355bb20afecd151e62de8f0de271a8f26ddf0e35b1e23bf206bf815db4cf1aff3bd1000000000000000000000000000000000ab2861a429c5f7205931e3448d8f8aec01b85709f7ffe5ff64b00e2c0ead637df4edb1130f183aed1724f96eef5c6cf0000000000000000000000000000000004d29d7eae734c9de809a505c32444c1f61584a0dabb9ba85773b1a631f8b3e96270b9f7e07e1a1a6f84e6c8d23ca57a000000000000000000000000000000000f329426296056160ba748d6be674ddd1038836a5b581efdc3cf2bcaf558ddb7226b5f595ecff119c01515f68b68a3d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004201010a93c7e5b284db0fb34473f774c6b81c0b819f2c9383c4038f747ba48970520e327d351e2a0f89c0c20d0479e00000000000000000000000000000000101c8a81ff3f734924362ea64c95779d698eee63f1d7b954d570f7532bba45d759e0e0665e737f47b292d31ffd7ab65b000000000000000000000000000000001395e3a216e5e64fbb24e7396a36c14838b46ecb62caae32ef2b39126d3280aba54614dcc41ebe5b91de8dab918da085000000000000000000000000000000000469c734608c7066224816adde8b65b53647f36d5429b3bd23d2448a2cc6b04c93675e1a14a30b2c4a207a939ba73c061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ec79483d7421ad9806f7ec1bf1aa860c2aaac94c9eb0ae876f4c8296ddbe532b44b2a3af39eb976c160445ee6308cc0000000000000000000000000000000000ddb1749fe901d7a3b21248afd78c311f8ba04d1d7096efa85dd5e1d4d3e441d840bbc9a5deaf81d9035fd89f7b2cea000000000000000000000000000000000fc7be1a4872e0fdd4eeab5d1a42258a86e367c7fe146e07e0e740bf9f1ef741de892c21fcf4c018cf6876f5b775e272000000000000000000000000000000000b674bd417ba339d0dde56f3338674edc8aa212b405737c81109783455b1970c1fdb8b0db4609c5bfa8db9f8f4e3cbe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001157fd9c45c95da07d1df13a04b604f026e77d68d3df4b5f5522d24a647a157e99a545f70eb890f158e43564b1a266c7000000000000000000000000000000000a31b41affc520d7ac293735bdf8ec7f8e68ef9619bde73fa49476e727e01a89d6e510e6f68e3e759044e0977c3f1a77000000000000000000000000000000001076fc06ecf326d07aaf682e1a295a6622b982f350ed995faf270e60a438b1b0cbdac1dcbdbe0ff90ba8ad77f1d7ffa10000000000000000000000000000000002927b28470b7f95582253706eeca812af425245eb6920f3da6bd73083c5f47a3ce8058e9e05863c2aa6593041b3861f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001470166a197924188838eea04ec227248cde42e72530ca83d77166c0ff91b41edb78dbdef084d7203e29d39f3aa97df7000000000000000000000000000000001227880b3903da9e50b6d3b6102e5602b520ae6ed27030140d159e30e6f9050ab3d93ac1d4d91f8f4ae7528ba1a7fe6c00000000000000000000000000000000018b1e4f7d81dd63718a302ea537a87ae033c792157d5bfc13cd25f605662982448c88ddef48a063d2d8bb72af3d15730000000000000000000000000000000007074d5efd2f6dd3262421185e24eb1d023410c4162c5c6696c4b8795d4663674f395d0e02aefc4597cd6a453ec86bc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f80ebca2d855537542705c2915662052719f898bbd507b590888026d79d3fd17bbd6589c288f3fe5be6d2cb971e6130000000000000000000000000000000019b9be8fad1557e6a590bab42fd41e1a5d633113f7241c34f90d36298f66ef2cd2169153605ebb7d8e32bd22da8cbe0e00000000000000000000000000000000142073e8509fc0c1dae760f9daa3d98396cd3a101c1bf9e88884ba9febdbf12ca23c13d238ee8fd116dcdcd2be0c826100000000000000000000000000000000095786cb4075df368d450d4f18756a8ad38e69ca43c81b7031c337ed5c0cdac9e5ea263a9c47b28232604a4e51ad4df41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012861d7a0b8f9488f514dab456d2c155666c3caa5a1d824403d4c26b2c9570713924fa714d46c83a1eee6dbb6995d69400000000000000000000000000000000037afe3789bef1c203d2fed1d093d2faa1efc15a5f8498610082392cebcc08550a3584406dfd5c7b28f39beaefc9d9830000000000000000000000000000000013c45a37b2675bb887bf246bc82f8e28c0e4e52cfc02d6933f80240f6bfc70977732781a7084e3c350a59f7d1c41ec16000000000000000000000000000000001622651600b43e59a811a132218d9a3e40b1027d597eaebf047b381ba666470c74de071615b75d15d55386598ecb7b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aa74edf17ec4dbd09b27b87b9b7208c7beaf78f5e7644b51b8db62cfb78eae71cf03ee1e1c48c89835ae269ef206d800000000000000000000000000000000136eef36ee12581357f142f5de9ba449b93ebc6b784200296bbee002cf6f890f7b1f24b79e96fc48b161360a08bc5d610000000000000000000000000000000002ffe16cb6282768d13fd7fca6ea1724f2bc79e5a06d87afa14ad2b16cabfbc67edceb7b801120fe5cc3da787b3125f70000000000000000000000000000000012ad65ae5abf06cee0d290e631cac315eabaa449a22cf439434993cf1e3d0c777b2ddebaafcb3f066948bde0cdbc663c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f43a66daccedc45649ccaf0a8c7541f2bc4b36fa0c2839497d1b5428a3aaafcc5f63aebe3ecbba79bf6c3e2919918de00000000000000000000000000000000115249380550352bcb74aec2598f89186eeace342f91e40a2ccac444f51dbf6f2e2873c847869b897628eb51f2d4b80200000000000000000000000000000000057524a376cd560ef8c4bfdc14f447caef9c3bca9604333aa91a83b4a82661ea177071a4eacb42bfcabd00378bc4d5c80000000000000000000000000000000012b1622aa90a0e2f8153707556a0d754c58b63747a9a3c9c6fd92353b4bbd3a7033177d261caba53f04b011f69b6f39d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b68a1d5ac080c24e1abd5795f2f95fb588f4195527d2527985ccb6b0a0e13c2e8248ffe217711fc441cc5cbac8eed20000000000000000000000000000000015474001a7826e8c308c8730d9e9c7d1e72f20a1f810788d7a6f4f5f26f09aec5d6fc5964c0ea721992bb0d7be559f7400000000000000000000000000000000129ff9f9709d7a4810a0f897164e7fb83d5ea5bf5cfea1e110563e74cbc6df57ba7bf9cba37d4b42105d53a4600bf6f40000000000000000000000000000000018331a163cae4ad3ee137db5ba17268ada85814e0c431f14678679e5e903a9507d9fb9d081f1cc740855ba04ee97a6d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012915ec653a9ce0e0ec7062b3dc72d685e9c89382735016f65ee43e2750835da61584cbf3e7c594c391f6f52195c6a25000000000000000000000000000000001222c5f0fc72e6ad7b725abdc45874524d2bdf3dc2dff2788e04a0c671b1673fe922c90b9c69bdb287eb23ea4d30510100000000000000000000000000000000043f665bd1371cb2cf63d4ec877d80c8bf9a8e5ba08d5e997369d16524a069fb6883b651f8b29f29d56e8683018c27a50000000000000000000000000000000018a654747706b458a8acb41a3a5c9317c4856f47f051e623df2ce9ddab2224f53ecd65583d5f712c8e4608a8cdc08e7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055460d8cf2dcbd9467091e632576c45d14225827e27f2693048885094876ac159b01c15fdfa09deec7a0bdeb974d8d40000000000000000000000000000000016b69aade8a21ca56679366b0375c659f38f51008705a4dd73cb85e44c60133c8a928e3e173aa479972f0c15668eb325000000000000000000000000000000000d8a7c3dd7c7ddd6a8f9750fce895bc6a691ce7648fe7aac5abb68969b693eb9b09dab946bd87f9c121171a6e940d542000000000000000000000000000000000b24b366729449d2784fed14b74646c53b909065b29407e3ecf04cbd442592ebd00bfff6acad8c0460befbc7e3dc93001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae220041fc997adffdbb1c1798faca8ef4a3fa72e45fb2bcad05af58bdba057460563aa39d98aa640a11c4aca4ad7930000000000000000000000000000000016a37a5d7f6c0adacba400db65fd4dc1d1e3c32c5a0b157663ea2d9366634e8249b9c0254904427aaef27ec6f58abc83000000000000000000000000000000001354ca37859865ab93fa9ca8ad87fb5b48bb258fe5d31475bc269ec7690fae75c0acf1b18d072e6762d11afa9c13805d0000000000000000000000000000000012f08b54b97e74929f00c0dab3bbfe8133b213edbe641531b01899602d05ff79b3f92f20dafccef0321d9b0fe66b39201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d982372cde62abdc22230a921b05da1e0ca46c057ccba726cd08f1a4ad5d0a45f96db343277b5b24f7a9b1b3f8960490000000000000000000000000000000014d64115525a788139d4cd205f925cbcf6b06781d07e388d91d4ed79a0c76c5c075fbc77bf67c9114263e259589bb0e500000000000000000000000000000000184a80d3ead2a24883117724db5d5cee06351ce180465f8234d85467808d7e0b167efcba5526f50c5577014109859ad4000000000000000000000000000000000b43df100affc20ee26bca4b9f7f28d9dd1ca1451d2847dcaefd131bfa8ee3eeb27d1e49acdf6793f8de21841c1368821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008edf51d1538088179b0da3a42a9fbadc107b7667cdcace78bbe4fb65d3f12e10b7d60fdfbe436bee13ed51489f253290000000000000000000000000000000013525950b14e9b0bc8a6e87889f917e011359b05107cbfc10c9b2b9e5b351e8a89fcb2457575d3f4041051eadfe70c3a00000000000000000000000000000000011947ee7298b45484eeb476389378240e6b717940005865c226cd2b8a354424ec4995e8e8b5e73134bf5890f62ab8330000000000000000000000000000000002d0b54ff8eca3a8664e233a9d2d345cf537b853fa7a59cb4790dec7ab5a802b7b47acc8d3ec503ebf690d247c73aa9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b32b8543154a1af01763f4a8315337670d6bfc96392231fbbc7785489432accc1e59d245538bb9d6636ad54962ee5a40000000000000000000000000000000002c2d62de6b255d663f148f8127425bb1be774cf6cac7d7031b10965085fbfb5a4df1ee9c16887ca174fddee005d8366000000000000000000000000000000000efe96a0b3791b046666b2ea5fd4dc8ca2b32bfdd53d022f6d20a6f5a8ee21d69b7b2ee30e1290ac6870dc686008f29a000000000000000000000000000000000572c70eb109894c77e56556be9cf7e4c3fadcdb08b37d68b2b8cfdf82df3dd4351fa056a258bb008b096ea4de99d8641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000013fe2dc53b7954a55cc04fa0956a88afee09015466cc7f06f0bc0d7311775fa9f664c41532a38c26c70e5ed1498dca1c0000000000000000000000000000000002d3746c037827c9026557a38f9bdc1ad421a52230582850429e9b019dd0f4c53a47a2dac14950e7e1a5a69a45ee1b8b00000000000000000000000000000000036223c9518efafaaf8cbfdd21d6b2e347e77ec9f6d4b123ba4928b335ada4298bf5c6f8bfb513ec5f98f4832d97f7d300000000000000000000000000000000148863742ca4fcab2b49929f9628a088c9c67343cc78558598c770eb3c8bb355c52e8f4e10899eee16c23a052a6b0f29", "Name": "g2msm-30-jwasinger", - "Gas": 373950, + "Gas": 440100, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011fe294de63c0370fc14599ad86839dab91487c8fb4ca8fa3d4e2c5ec7cb0581ed5a963aa4a5ccc1f4d73cc2e45763720000000000000000000000000000000011108c53295a1c34595fbfdd24437dfaa9595e77cc46b828c3a28e4f6974297f18c6381e35c092943839ba327d91b529000000000000000000000000000000000c0cf7592723172d94e9226659032fb0d603af2769fdd97f41094bb41e375975f564040d9be764ff15c2655a0b495735000000000000000000000000000000001342dffeb8ff7daed381e8f3096651fd2fe6faf43bba2eb83d776660fea50f13546576a1fe5cd40d444458979ef61db81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169ab77f5f817e1b7af302d857f0399af06577e10ecdf005cd46b000acd15ff7682f5e1673b6e9fe0fb560ffe1a5af1800000000000000000000000000000000100d5f6162d969466851f26e2e0e362f8d7982863f4ddaa4542ac02e7574cc062b3cab0081c6debf6c0e3b0bb4432b04000000000000000000000000000000001774aaee8665b850b3e5cb57603bf36238b46268fdc00d92215e561c93027161c292d80906de78f473ab5205d7cd41470000000000000000000000000000000011d078f58850cedc57fae057f929e456fb7495a523802bc3a18c18cfe476b7061686231c26f7c0e3ec9f7bc2750d20fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071567180e848385f452f184c508777dc547d55069b3d1001b41c6ba5d2ee9340d8cba37fc8d09fe07098a52e32fec0700000000000000000000000000000000054cd3957217fbaf0e63e376b1c79a50538332bc65906319b2fb2e59f6eef9e772aaad85845661cb88b5de08f3d23ac9000000000000000000000000000000000495a7fcdc1f9abaa599f70d17c1c73386c89ad2de8bd84931b87e96f67e1696bb82ab522a6569e3174dbfb3867698f1000000000000000000000000000000000c27d5b85d3c14ab4f0520009af609b18b87bc6963a97a46428261346741b8bd750e573c80fe3838c420e8e234104c121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8de7ab91b842c2e247bcb5078004264877aeb04d726c536fed17956fb5ca4def676b7b6a20f105970dbdf518fd9f7800000000000000000000000000000000049d68f46e7bb4d23a5891af9812ff534da4f7a3fb7d7a703bba82ce7ba1bcdbdafca2cf3651e1273c10a7ce39eae49100000000000000000000000000000000145467ec4f02eaef135691c38eac8123a86f47dcbf5078346ab230511ddd94622263bf136db41144b663355cbdaaff4c00000000000000000000000000000000066158ac9a239bbd00e3041e8444ea5e5cc43c62d722ddb81a19b98937a060b6e94beb95ff7ea449bbb9f05986345d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090195d26d117281a8598c374706b3f71747a22b7463b5b589576aedcd773f09420f0ca8a63c5cd39cdef2e83b8f8310000000000000000000000000000000000095b90af146fde11c8f400f1246b9c1eafae0788a0d5cd7052cc36b77117a4e4154a0a0006509a5e91d88a6ce40dca10000000000000000000000000000000017aff59b368f3903c9bea49034e3c67c7d120b0e12f8a7a067f92ce871674d3a58764cdf7cb528d3d243f8e8bdae9969000000000000000000000000000000000c219e407dbd8d4b2521cba1dfca35ff2e33bd204fa96d410784c55e776218d8f1cfc9dd9d2ece2845f6c5363d3280311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bcda99a0fe589566296b085c63231040a30356ee10cb693d084f4d7d3c5d61bdaf483739f5173f1f95f6ac1d61e2f000000000000000000000000000000000034026d7e3173caa159b4cf311efa8674dc8b51680c5c6aacd762092fda89e9a6948534fb231369a2c116180bd328b0d00000000000000000000000000000000022710c84ba4081720ca907dbf2860814ec1c1adf017b4b27917c174f604675961c70ad25fea3522b8da13384bd9f1e10000000000000000000000000000000007e2d29ef5eabc6e26637deb393d843d09d0a7c599621bec0b921ae6adaa6e334c1c4438499d3bf7fbb6deea34c0a6fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3577e9c77f0366baeef1729372b7fad18a00d140cae134f5d6eaf8b334349c29a5e949698f9792ea9ffd7e1e6ea8b1000000000000000000000000000000000262fc8bc37a12b14e3945d0f901f892302ac0ad4f6d572186e354f9eb0d510c6d5c9e9e99bfbaf8850ac6c5a3b58097000000000000000000000000000000000d383801798a9536c46a686ed00370c21ce165c0e830053c67417966a4e8e22359a85771cbbea789fea671e74cb6afc30000000000000000000000000000000004581f63e62464cbb3349e41eb2f3aa5a284b0cefd857e16a938b9357b99cdde6c6d1c949600f71795bb2815d1d5e8e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b9e86b13bbe4d72b2a74296bd40fcc7f9688880d4465c4aabbc43b7a9242246f14e218475366739af239f0ac05c46a000000000000000000000000000000000659d60ccfbbea3fae789fa1ef668bf4a0b648b879cd56d45af104bcda9485a2ce68d25e9a76edaad8b7c2891973b10a0000000000000000000000000000000010416c28e8cfd0d6d64eda4a764068242dcf4af0e634c90186393de5e4374dd57d88f6cfa21b4134a92019dfd3dde2600000000000000000000000000000000000a073658f93980c037e9f6dd21e0bacda8c4b5551104d460384be22217e19bf69ac8702888bd7bf888bbb183e3707e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e2c2d8cd631f08e251436e47d8e9e1cfbfdbf27e96f49ee02286d3cf8238f8aaf01dbaa2c134a72170195a5f17494a000000000000000000000000000000001458704068da33793dd44ddd3ca25deac8b82f593baf30f005a77ea1b03ad53ba86f6c6be28d789207d879c9d6ae529200000000000000000000000000000000068b9099a85a6b1de2cdc22ad7c88bbeba607983b168f87c0974d9889c8497bdb6bb0d8c733dfb0a42c124773176fba30000000000000000000000000000000007a02d1824be9c7c25278d2ce3aa9e18d4750e2e733d4145158f9dd61f149afa7d27bb4f9f1820a0dd6484777f3e78331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ed40e8fcdef5b8c17087674872ecb85e653af040eae611b3e487444d5a09cfd77d2e3ff57b616fc7dd02cb134169bb000000000000000000000000000000001509c9550c5c016915f24635c1df6800f610df803c7e693dfeba3223adba3350d4ee2ea23b43203170bf4e631aa9283f00000000000000000000000000000000037e346cd4f033f784c7394b4a13dd4d6eaff2ae28106938d2725f4f4ecc7e031b4d22fbe4321a9a97d0243508260863000000000000000000000000000000001994633aa59c4d85baeaa384f350633a117ba149740507e44d32b46fd7ab7b3e6e2e10bd3b95c6b6a5bd56cd6dc3e8be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117187e61a3ed432dd1d21f1e1581a320207b93d2187697deadc134a150be15ecc665c5f33405375a28a532df2fa016d0000000000000000000000000000000011433b8af3549304e4b2878f8e988a3967a2207e6e011603e15069f290128fd6c7b435bdff8660307979b28485d9ffa0000000000000000000000000000000000d7af0353a8e5d8d8b0b8d355ce2298f2c6d574ad88cfa8b0f2ca231261a5b8fca2b288ac8d259ef064e5ebaa5f05a4d000000000000000000000000000000000149aa6202bf4a90810644e46ce0f37af064739f0df82fb1b826a3f5b0daf0f8c8a1db0c14788a9a64eab5a236a7a5fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147533909f6b564ff7188ebc54684f9f1ae46f5d71412a95dac50f3fffeee02466b048c3a623f5b97ec9334fc0af3a6100000000000000000000000000000000104a30ef64a113c0623192f0ed5fe8ca6e4526afe5d8f6137925c3e0d0c6f714cde41e9862047e12ffcb435bdedeaf8c0000000000000000000000000000000017b34c485532d4ba630a865df6bc3cd32a2bdd31556286b685b1bf722077d62c7864027cfd628a2f92cbc357070d20460000000000000000000000000000000019f346e3494f71e87d7af358b7d5685d26f1604e5b87b88e93ee3cce63eaf0e2170c7eef55db14e964df998cec3b088f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d492b8a337b28efe2fb8e76c96cbac2a5ef84a4d5e602676350539858d1d5c50ba34ab7c7de1bc7999fca1bc1dade60000000000000000000000000000000000c8bb2849d9184c6494531450fcbc8bd0988322b6053161e86d7cca130e993a80d229bef4b792f93d75e1890d520344000000000000000000000000000000000e9592f6d1d65d53115953a86aa131ab8ee5e4acd45ded9a888f39552e1423bf35326a66924f350decee64c4b1a479800000000000000000000000000000000016cf54d46f12fde30781fcae890dae9ae1dc5d79ad549e973b3fee0e01285f9c7e8b275fe58805e5b4093e1edf1a30d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8109c209180766d1e01fc7b3307752fbf717403a63774a180c60c07d171974a997da85a1ff5fdaa52a52899ca54b8800000000000000000000000000000000183c720461fe98527ae1cf29d11f6aff4ddc87cee9eb94cd2b7e344e76577bbe354233f2d9ea5b614ca4bb87b094b19c000000000000000000000000000000000a99c91bf62ca2beeb5908f57e73fc5e14d20462f2ddd20058619e86595a44226c7f13a87ed8a31e7ac58a77613e699300000000000000000000000000000000173486da0d9efdcb111ad75636ea21ca864f127d594ad4c78cfe7d6a60ee216254cc4e7ad9ec4c1c94a2c03619a2468a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c9a3c76ad02ad837fcd4f5d85a2d8baf84f0df4fa49ddee43d1421796425d0abcb45fad37bb0d95e77992ce6c4c114000000000000000000000000000000000e0046f3a53de94bb63f960224c7383e0534882aeb9109067c8bd6423186700e74314db3b41368d2a88a5af837fabd02000000000000000000000000000000000f05c7bae8cd2fbac933ef672a92b758ca90e94b5898ee9204258b593e2ae220a816b5021803a5411044429db180721d00000000000000000000000000000000137488ab6873a900bae8a4f42306565cb991b4f9ab0a68fd7321eac4e718b3969719c27cce7b3148f59e41e7e695d2d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115079a34042a252da93323b47237847d29b1f85635874fdd7ca9ed1ed515399636fcd325c328fbf4ca4c337bf4a74260000000000000000000000000000000008eec5be190930f05af995d91858cd097168bc304bfc1de514b0eef4850c9b0e387d8ca2cdd7140b00086679eb8182d20000000000000000000000000000000017125e1ae68d18dab9c37fb8789bd67287ee10a5e1553d141f6d9a7d8339876b034eb01174f407ddad98854601b7c09b000000000000000000000000000000000837c59843eaa08bb887e20d6814fbd9435767d2e2be78753cec2e3e3fe6c2115ee6ef6d4d465a7fb6b55f50015ee6bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcb8d4f0253a9281aa9ec35ff49df054a3bf255e9e69fdd6190a9bd0f50c0a53817ac490984ca0a627b861594f6930800000000000000000000000000000000152ce805c36990c295bf13ee179dbd2dfd05d322564e3d2b3f11492e92c1e2ca2fc5c7776714aa18c7d10e34f97bde290000000000000000000000000000000011bb8f4c926e04b290848d903981c66185a9163905fb2e41951e53ffd3602352148c5b88da2323782940ab6125a4aa23000000000000000000000000000000001545c8c909716babdae2dddfb2dd9dbb21aa687796ae01bdd8616f2b558d6e71938aee86fdd92556c8378b88a60090571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a159dcd8519222e375b4664c03fc50f55d4ce5031c48522c4899922f498671348fd56ad2943484a79e72011604f17a00000000000000000000000000000000000168726d77c4b4ae3cdc5fd66af544e7cde0efac521d6ecf27235486f4b9febbb532d7de2be62232605cb6f95ff137000000000000000000000000000000001220c8c1f4bfd40fd6ad5a0912188c0275e0acdbd5dd064673098211d514beeb43660c3b3a3ee15b7e7c4303407e90c80000000000000000000000000000000002aa452800fb4b967c34f3615d795a497be3bf0cd9fb2783a304d568d8eea3821a98fa4b1fe1de314898966df3f9526b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017008a6c1822705ffdbfa5d5246c3ebb4ee980ec1642c1c8c9ef3e77ab384278d0547204a5052057b39390cf18899bc700000000000000000000000000000000154a4ef11cdd579e48b58a2f7e0dfc8457b6572e67ae7a87dafc137cd3bb6d8ec46e115bfad7f2589a643c1381a1c0610000000000000000000000000000000018f5fa3201a574328b57a266c19df6a3a5f8d55338a51bb618febe69ac0dd9e3a62551bf3d44ffa8c4f283584b0e9723000000000000000000000000000000000b19c5e2bd7183a3afcc14d5ef3736037525b8b3ef404eaa9e0337530f99b3a009f7a5b6648c5cf4471e89bd175bd6a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e55ae39c17949200420cddc2bf962a4bf817b565b05e7aefdde76785bacc9b591af3813510e008dafc113e97c1bdf9700000000000000000000000000000000045c7b30658a547968a430ca68d161d47d3b4f93adef63846c5db5ae921e4eb03c9d9bbd24f537c885abd2ae39d8c3d7000000000000000000000000000000000afd20180357f3ad21307794c6882ea7a705952fa0ef101610ff695b60f1463e4b91aa90f44e07348a1db27cdc9b17430000000000000000000000000000000004ef734bbfa1899f219bff8612f5de6f98ca801daf055f70e8c46cb6eb564ffb0e4217145295ec0d6ef7b207bf78bbd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011679f986f685fbb7d60df586022cdcbbdaf395a93b60fd2b4999fedeaa0ec00feddd7fb96fb2869a4070483345afc7c00000000000000000000000000000000199f6604aa198dc6a42d7b00ef9dd6fbe7f4d07dcf13d58817e8f39a91d59388fbe2f8b04e8fbba9d09c5bee680897a0000000000000000000000000000000000a401f85eafa0a7135efaacf971e11ff3b9612f2f40ea470213c3187efea095dc6c722535ea5bc0023a811771415d8780000000000000000000000000000000001d40a84c8f8d83f3a13412257c77195f057b33d0e7514599a0cc3e2d345974a25d92364c0ae54ade8e9cb589c0ec0221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4ecdd7c4d05eef4aa878283a85250db6cacf2f022bfb2564f325061f5dd72e01b39be9360fa407fdf9ac735779f63000000000000000000000000000000000044bce2fa18795bc62627b4de89d489f2505167c54780bf051881ebc332cb3df398dad4d05edd8702e5df4c0b27177f8000000000000000000000000000000000a1568b982e176e393eb1052a9d8a74a07a01ec7370c9c1fe881d71fd80563d91b0e11feae1c1871e2b92f0069fc315b0000000000000000000000000000000014ac398a9d7df2dc317ee143ed4e56f8ea2a4fba307694745f72695928468ae2f66282735663dd594acba9d83e2c4a4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f53d9423664106a55b92b7945b88f32041187eb44836a803b1a1e61f660c1854e30179e8349d116a91f20f91eaffcde000000000000000000000000000000001895f05e99783ee68b943698f2bf2f037851df090768db976070fd92842c17642de474a615362653fbc01c744b80270800000000000000000000000000000000158dc7ea08fe72554d58ae70cdf4c791b7c9dd422a822d820526c9a545f7cf580beb4d405db438ee7d76cf32154d06b10000000000000000000000000000000015e9c5a8c20097f0f5c9afcd1cf03c8984496dd616241ad0af7cb6942a5a9c9e10b6cfda24e6f918dfc038e0c2e2bb7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008d78b43d9f65e2a4a9c1053ce262b8598fc6fc179188f717af8ad7542f89a10d4a5ce2430f89e49b9da24f62eed1a200000000000000000000000000000000169697779acbf79518f014f42603a4e9a145272edb13d0654e9b6c9b99a32777b8a458acebf1ea513da4b7f5b8659c8f000000000000000000000000000000000a5c767eecb4a98b08e91af9f5799448655743710b4138f180d465fa2c370aeb933695cc7b9272ce9d1209c29a953d050000000000000000000000000000000012b25728b1dee57e12932bdb2696189fbd443b48f79f91bc50ac71d6492fd43dfcb13a177abecb3907cddf7cb05ca2d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001416abef055929ff36493939c670f43f50e16041e9af07e7f60a10b6f35f4b80a5c7b08f1a6f2c7925242a5558cea65500000000000000000000000000000000071d0473d203b27921d1d18903ae0fe2047dc488448fa651afae2cc1331fc266eabc544dbde502b5a52343fc4473b9870000000000000000000000000000000011a723724fb35636f2934b28720d7f2e68ebe2d61b585011e1d185170e1d3205a78c4078ecc58d4e6e339d8b44374f75000000000000000000000000000000000b89654356408ad5f552ef2edc48d19d6f8be692bf09752005bf4f4927a2697226c6f336b036c20cd54f77464fb083171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001255f8a9016725700a6f19af155fc606f62b658d6032d534506dd02682ac912aa326f81a3d50cff51825473ba46d2b6e000000000000000000000000000000000aa146e10e838e6b89a9b73d2d227a828c401f28a4bb1a21d1ceb9d6e33b824c6c07d745f0d2fb12018184a044b8a1b4000000000000000000000000000000000051ce51eda0c3b3d15a1ddb65e0b346c64af7862b855555aa51a6bc29174fb70c7acef46a0901d197fc75436b2098c50000000000000000000000000000000010bbde38f70dd74040338e52d1e1786525cba7cabfc18594d1aa3e5044b13ba4f972d92362bb40b7470a802cc8ec21261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bce24cf790ddf610333375b28840a261e349fc2f7155636d420cb9ad9728ad4fb13b0a3e88f4e0e8a9beb6bce3dc9500000000000000000000000000000000159618ca7ffe96d11baa38ecd25816eec598df4822587e826716c9ea4a5c81a901457823ad18a1e659d2f414aa1d24b00000000000000000000000000000000007eb42b5851cdbaeaa1a24d202f82a851adfabb852f11f296964d2928d8a8f5f30dadd54255285870298a4cc1d8b5b400000000000000000000000000000000002432af2cbb14536c8c0cdc18f7f56414e432b4b9e07fa31ded9aca3ac7dddd16d7dd93aa274a011f72c6ce0a20c064f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045fa125a9857620a592c8bb6c8199a884880c02e19db7d1694cc28bf5a956279017fa69ad3980a2474d6ec43af8eddf000000000000000000000000000000001359ca4a3d7dc25be649e77561b672f1a9dfb378bbce1ef005ad0da02a73e2a684202a5d32fc930054c4b6fefa6200460000000000000000000000000000000001d57f00981b049cbad4e205e708885e37f67ef40c791b77d318cb0d2ce341be3d9ae58e858dc0eabca7dbe7bf886d220000000000000000000000000000000008c935df115ce7daa7bf178b06bbb40ea9d4d0a96676bc95da9cd0fa6b0b60a5596a050891f719b4d4b11e311ae5ce541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb6bd846ca774707d8c7b539201adee8fa4acbf340d15bcdf4e484ccc9e0b3757344d3585192856ae2c92e4f8dcb9070000000000000000000000000000000017b6b83131c964b15ae933db128b1019f24b85d2680ea7fe5634f23f7b2194c45d041d6ecc80769f168041adb5289dde000000000000000000000000000000000c9c8b38baf6072326c18ac99f08a1273eb9b1dbff9c10b5591f5550d707f2df7aed02e16107444c40dd0e2cd9701b7e000000000000000000000000000000000ed4f6b55469a2cb3ba732adb4f1c2136601f4cc4ccf20ef9d5d9343b952add1d7eccb7acb45b24e3d72ee83d697da1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7a0be376cf6438431c968822996514a62262a634b9b0db438e7485e2f991fd99d30f462f92d3df139f7ed61ab26feb000000000000000000000000000000001970198c9db46369613e7787e56d5b185c17150cbd0a0889f6f9ab8b02c4581d35efa33f26546dcd05fef1163d1f27e5000000000000000000000000000000000cce8d5a55b1aaeafdb50ea2c5470bbbb8dc506c8276cb4ed618212be6425172d8013eb9fc07f39bea77f299d442eee2000000000000000000000000000000000cca501ed9200a901f30f583799d6d5453e97d4d899c8b9772d57ad0bfe9da2d06bcb77d20ae0650b0d5a93b040262ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097980da09d6f498d76335a9eff9d93042c85aebe7b07d047641d0563e4f1fc4daacd4cecff48640bbb93e453021decc00000000000000000000000000000000009c834d0990ca1e4e06858ce7de6ae4fa76b8e9c4d46f88d1da3afca9707f340316b14618b7717f07c22c934cfb07c200000000000000000000000000000000029ac91f0b9df5a39b8a5e1f22e139ef6385ec9ea8fd547fa5eb3912bfa315b5f474a776730ae8c5dfb68871dd96340d0000000000000000000000000000000000d964c9d7373e6ecb40fb8b7dfeeaa63084cc51a0d2e359dc9a88aae2fdce01c7c401289a89ddb779d604d6e612dd5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000952b3501d0fa50d25ad5e135e75a0f50eaec617a147f7d2b893364aea650a2d47bd58bd6c52bae8d7dabf4c4915f4a7000000000000000000000000000000000a31e469510767cc3e0cbb378ee8e883f8e062c157833b4dfafc6bcd7100c4bcd992fe3463cc2d40e7eb0d88a3aaf20d00000000000000000000000000000000083c68123a5175e1bf4d10edef347e8e39cc2241e1d1341b284274b9c380128c963d22df99b8bf674ec4d9837b5932d80000000000000000000000000000000000b12a1ddf39fbe68e0eac6b77d9397d54992f7737958a2270391d9bb716afc477afe6f7879a8897509c720cc4942bf8", "Name": "g2msm-31-jwasinger", - "Gas": 380835, + "Gas": 452677, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000096035d973ce54172e18d3efa7bcaaaac3113f1233af789b5cf0efbd009d63b6a996bf81d7ecf5effbc7ce926bd8d6d200000000000000000000000000000000042ac0a88b1f08c391c4a93f60c7b0bb145e25d2936ee5cc93c2a9a220cbeea14cdd4b597b257bb02478d2ac7c7537fc0000000000000000000000000000000002dbae06ce6bb0802cba7050c74e26f26d5d2be93786e5419865c815902e46678fa80d5acb7bdba0641f641286f71451000000000000000000000000000000000654470bdfe54c60c22433faff0bf66bfe5b80bd70b84befd75b0f302a77294e65344ab35a031fcf298bc16f4ef123ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca87265eac01eda9b2e4fcb35410d543f2abab6edbcae49f8abfc36cf19f4b9005b10b7cb41712d83f08602135200510000000000000000000000000000000018369ac76639691c32f2f45da66b4fb0610d9adadf5412ef8af250d86b8e21e80703f35bd825862dbebc527c4b424d0b0000000000000000000000000000000018c13080eb44986351f442d49e93f6186526159851f95f799aaaadf3e015ec38eea61695d25d3d932d70149c3c555e00000000000000000000000000000000000fcb54a6a326c991a1c6c50906394e0907816d36b4699af6fe09d523d5c173262228778e10ecd4ad3f8289740ee0e3611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b94ff282e5b6e6d9ab33348fb5faf40df38b4c380bfc0b1fb3fd820ab46416d43341da75b9e33cf6b56d65268a5c38000000000000000000000000000000000e5bd9624278f9cfe7693593eb05760c10f04e1178b75346fcd9f373055cb62797cd7c1f8c34823d4fa065cc33090fa80000000000000000000000000000000019ebc3c19dccc7fe2102200180331814f05c7973383bdd98c079c3752ec455851fa779421ee2a02e5c710a722e1e2d5b00000000000000000000000000000000170e11a3d287907204b7a0dbdaf98eafb96118746ca4899b3bc86b5aaad98f4e1b751f447cb485cc990f217b112480ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134428bb054ace91bdc1ebf6f03c0e95e42e333370b07f80510aed1e592cb44bd5e0e617e7f1808d30c5f1e0a7938db90000000000000000000000000000000014be34db195e2a84109e79f2c1fbec1330fd97f84b5e09e5c281d06db2280692a49de70b20fe76f1ed835ac38e12fd4700000000000000000000000000000000180e7c05bbfc07730276c245c58f4731e4ad49b2e06a45d17901b558a7a52f10118a10ce3c85d5cd237b5f86abfda2ba0000000000000000000000000000000000af23524683b3620396b512d7d3140aac7843289f35ae9a325d2a581db78af816a4c6636f5d61a622385e3533b4bef31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ef19e1a3450e813ccd3296d7fc0825014a9723bbdeb1dd64270a562b5656ac25d19f15fb2b759548adf8052f786e890000000000000000000000000000000019d54b2909ae0f3d7fc1b642732e99534463c81d77b0535ae52599b75bcd233d2f362a6cabfaaecfce5aab852479b27c0000000000000000000000000000000000a326473188960f55d5c92cd85d51e365803e55bebe3163d18bca388f8c570e8b972e46fa5a2bc99d7b0887636b4662000000000000000000000000000000000b6aa6729090f9c6a6d87dbd60246acf6bb464636e36c477de0d3394461d44cfb82e472f26407b45eaa8a85567f30b621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010aeec1339e6ef01af6db965058c1d697162cca3d1f88c1b31fc1f9c54110eca0da247460cd5db9eec9122a25813ddc30000000000000000000000000000000001429d6f4a5b69f171cbb8e9adc9c7b2e14fcb1cac6d1e440266c93dbffa69b5f5f734272721a96c9e0078d72c79ffea000000000000000000000000000000000825648a95dec95cc130c3c345cf05481d8a571a25d72799824d56f8b64f2bc2ec2190bf5b23a3325cfa16c27829bc23000000000000000000000000000000001779388b901d0f78b95f50a32e99f32cc5d8079dc5c38123712c1b14c3dda3468dd13dedcd8b53665f707293754cceae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034be8fea61ec3872dd0c9e42c043e6732941759188c5586ab73cd57f0c304e1a31bb7c9c40543777f7a6299e673e5ae000000000000000000000000000000000af8dbd6971aa125e51f72686b577155ec4bf2477bdba83bc65d61dc59f7ec05818e02d4af2b13d7a012a5521489978200000000000000000000000000000000054e23ce1d67723d8bb675cc2a2594f73bb2e33e44cc77403d1d6130045e98d7943afb054859143250ed488d30d1a070000000000000000000000000000000001605cd5008efaa93cf562a279679aab202356906f5f39f4a50c0acea0bfb03d919d3844c5031eec99e3b1d79efee750f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019360391645ae62ed727816e3a58f41cc6a3a0195e455956e1a00f1cddde7443e95f50e88a6ae5ebb803259412477e11000000000000000000000000000000000f5647c7ae5012df5198dd77191a758bc2c519f748b07cfc6807b23c0726ecd9023250f3106173c4a80a823e074b9bbe0000000000000000000000000000000015fec9a42ea91098a0d063e7a984f6dcb0d98ede56b9dcad263b010031a57f74afcbaa7c43edf5cc50db582be1f02485000000000000000000000000000000000090afd7343d13004826c6b62d668f4bc77ba770917910b204232492d724f6c50d360bc5d63cedd936c5d47b61bdb30c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6f6c6ff2613957d15325d2e4d77e2a7389d0f9aa70fbb48d966ed2960b15e6756843ddc61c2d155fc6eb7a5deec4b300000000000000000000000000000000053dd983719b29e402a9150f140bd08a3d737ef356b9decba631bd6af3068add920ffae6e53556e3bee9664bc8bdd9f60000000000000000000000000000000012c9383ff3a5677fc23d6720d4e88bf2ea16cdc0cdc4b4f6da570f71c7214b0e224786e2032921ec9e36c3bd5d325290000000000000000000000000000000000ef513c79456610a1b4176a501ae9544ec7106e06691adb5cfa39a2fdb8a45a18f67b653c203848ad2a743dae064cdd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087e5ce2d5ce45772ed7325eb0816e528d6427c3465148312664e855371fb929147e7b0fb8633e5501ad606133ff72810000000000000000000000000000000001a7f24909ab8775290e5a071c635024586d818e80c6d609d1f16f72b536c91409ae3311c97a3a6f093f03872e9d4180000000000000000000000000000000000b9a4522e074034278659c7aafe736e35e4a8377ef6bf646591573d468373ceb306da971a2eb90a0920954e0a4a3645d00000000000000000000000000000000154674bb8cca85491f79badc76b0b84cf6d788ec3bd729d9c0a46cfc04d5fe7c5607189f07284e8b00c8eee51fdf9b9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f17af3f1b0ae6d8e66b976b3ba82c45efc912e7fcffcba99bbbb516ecfd05439bad343260b50fd89e3d3ed31bf9c3100000000000000000000000000000000041d4356e23e1c13d459797ffc4166070e3357bacc9d62f78d38bf55b415d6f5921271b2b5d83c533272b5006ff898f10000000000000000000000000000000005842e6f29660e99e20779d258b6823d663f618deaeda49a2363f1afff0d9fb6f6044918dfa0df48f9646a01b4b688fe00000000000000000000000000000000147b042eee20371a3c1639bc4f9fcb499a5aae71a51c92fe9255cac836025e7f3c7b0f189009aa8e7f915864702df8881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d114d526f4ecd35fce12727a110b6ced8a25925f957cf493e7261ba14eb1943d80f2c65a0b23953bc5208075aaaff190000000000000000000000000000000011ebfe2fb900ab4e233a6cca08a7d6c9d29780a4c426c89ed94626d41a75a3c984abc49d466ae7600fe2e3df350233bf00000000000000000000000000000000138b7b1575abec5a43c95af492b111865f813991186d9f3eb0efb3dbd810bc7b9f91f60271578c045dd8dff93974ea83000000000000000000000000000000001177c81002b40d881d83e3b9dcfd3c19feba2c51e33769326f6445fb3fc003a70592443b6391149484d7729b294d85021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000adb22e2c987bb0bdd1bf86dcc9f514440826f8d5727e563003bed586d07a0cd95a2da8236959a2758eef7f066cc619a0000000000000000000000000000000003092510625794fcc3487218e5bbb261cecbcc6cc3e2c4b93056876e32eb461239f18071a0c08a276f0631e51a0ed56a0000000000000000000000000000000006098f0a3ef777cf5dbc284df2ad6f445e32f87d7bd8d596652d564112163112802f19ae1e32e26d6ce5431304f5bed40000000000000000000000000000000015a1e30e0a367a56c438c5a83142013627cef89ecfe8ca6b0e277743e64f4d0fc6a744d019fd81c3aa896346611369711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000145e51d24bf7f15d99565721d912879d39bd583bbac46f5f652164eeb94bf6dd68530b462123b2bce078ee32b0b4ef500000000000000000000000000000000067831f84432ae2057ed869bad04a5153b33be7a42777a293dad1db5f323c4efbc776a047f2d3c125c3e4b04621d4e25000000000000000000000000000000000114c7bfdc9546cf2f57451eca30885a4aa10dce4ead3b3b7b6c527f6f3844cdb066eb7e0ea5d76e2f0e50ed1e8e629e00000000000000000000000000000000087dca605d1dd4b52fd9aa12c57f61791b46e7ded5479a0be83e39bb8788ec852d6fca1cb1415a92b9c3d787c17aa0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000500972dfeb78854173c0ae7ed51c8e25899dc3acacb3a8542d8e337403a983b85ef5e5a1e86b509c0364c3ebf5021820000000000000000000000000000000010636bd45a02115f460b927a734cb03f8900532cd8626d01de14bff9cc925beb166f4495fc06094e093bc31e7586bed9000000000000000000000000000000000bcc32fcd96859eedd8d32a12d3ba7feeb8903eb80a5aa118e6feea1095d2223dfad89ba57f7d0233016d971877663a70000000000000000000000000000000019bac8625796126be24f4a49abfebaadfc700f66abc0f327baa1d12b7d6035a03fd31a1b7e9ed9f08a5d25fe08b9f1751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c373216173e65bfa2c619c4432b1009bc10dfb3af495f00ef1220fe0be2d0a415150bdf0f39e590158bd2614e0a7fe000000000000000000000000000000000c5efb0f8f23047f4470aee07e63ddc65c7bad54c001163de4aae5f03e5584137f603ab84bac48397344285ac927d51a0000000000000000000000000000000017fe23e4cc46615e24bc2eb4dd243c3c7eac19fcbbd186dde2646641339800e5c5b0eec1d12192ac29a102c32cbf575c0000000000000000000000000000000007aa4e74a47b7d0dbe47d8d5685745f1acb8035bdab63888402a018e7a8c242441ce375c568bfd6eca8c93aeedbe625a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1444700c2c2e4d94c0d612f6900d82423c4725e665760809823b5165abdc5790be920c27fc3ec39b80d646fb74635c0000000000000000000000000000000006b1d5073762393a3033e4e6ed6030ee19497cf9db86f020502b993da18e3aed1888eb53ec2b43ac92a78f77b0cf10bf00000000000000000000000000000000126b371f95ed69ee2a36c9cda90c94f77ff8d4c9b3c8661a6b9112481bb0f347b930f7243fa1e79c36b720c06efdd28d00000000000000000000000000000000005e1eb4ac90a1197015c742c8bc80a54e1a5fbe6bcd34fda52b2083500f320e6073891dbda16110235d85a5a5ff204b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056d0361ef2f713a171771475bc84d2476f837019530b0df4186629e7f60c30b9bad5f022d213de07ec4c52f6e1611cb0000000000000000000000000000000018d714bf6f8e4a7394ee1076d4d4b99ee665b3ac23dfe4d6be37cf72f15882e16a6c9b7ec382e9cfff7ff3ba89bb243500000000000000000000000000000000194ec0f45278cc26883adc98707ae9034e3f895286bddb8a33824d1b631da5fef15ba2ae309f0fed790b80e3735d64b00000000000000000000000000000000006f1882ed50baef99619ca6c53c04b73e877842de023d655fea59c80a061ea2d264872c5e1f78ad10f8582d92d8a15b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001455d5376f953757729851c2b54b0469181afc88cbc0b8599d432122da820ff7814d81e06bfa498f3ed2c1c5a52226fa0000000000000000000000000000000019ca2171153e3c7c279144092d4e9dc6f67a858f40f66ea26ee637ae4589aa312c1107ad2604a8c4acda291cf41fd8f2000000000000000000000000000000001418deaf6dc21c51c76fd71d7c0c1a21480f729476770472c8d7d62e93a072ed2e7f734596ed2489cfd25313cc668eeb00000000000000000000000000000000128b88c14927d35b378f5bed440d1e5b9fb83854960eaab1a0cfd4446d8080fe384dd9fb4a4996d0f808b02b7adae70a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ab43ac49111f81945767ed9e858dae6be3d065fc39f0648237f07832cbf1ce128478baa5a8f000513e36010b4e9f210000000000000000000000000000000007ad77e8e31aa341f39bdc587389bcd33c1130fe4ac309f93de220f4d13a4d7a2f17bad4f79f3b32828bc5b4cc2fa2d800000000000000000000000000000000178592962510883039b8e536dd32e530a90770032ce14f3ab73f6b804c8e52dc7e2e6e717afce6f7a4119f1eaba9a966000000000000000000000000000000000fa47605933552027b8bac7e44114cd6b00f90d510b2b2cc6bf6cdc522aa2d6435f231ded9759529de44889230aca5201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001888718e6e0bfcff9d95fcbbb291a5d270d430e66c6f1d30a3f3c0bcb1a85598520e04886b33e00211119ebfe035721b0000000000000000000000000000000008b4a088592638d2f36a7217351a6dd76c57b7d33b4bfde09fb2e0cdcbce7dd06ffbe5c5c76ba1d6844503ad3d29e542000000000000000000000000000000000ddecabfac329c34fdd110a30043b9f2f21f60307648453bb99e06d7e73097fb840edf4e9b04ff4f25e013b9ca2a83750000000000000000000000000000000011564d38f5deca9f9c34031cfbef0c479b7266b9761f047c05e6d50047d7575802e727ed2a7576cdee9d072cd872b7c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012148440ca0d912f0a6402b68fe3a31d2f541014b9f6d8465962d670edb9482a57896d18d428317bb8a2676dd579930000000000000000000000000000000000c983600421e36bea09022fcdf0117d08c9a7e6f57387bbf2dee790fd0336d5db2cb939b2c7eadf04e17702ddb390d4d0000000000000000000000000000000011fbc2c581174bc26347d71af22d72cf725a6b7024a995aaf4857d464db17f4544bf61394a4a2c76bbc36cc89239b6720000000000000000000000000000000019c5facecab3b4f71edf675e0e74e218bbd756fd9af55b0c7c4b845460821d3eff4cc2d28cd8f0d681fecc1051ad63291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001488f3ac7e7e6a3264f6bea8812b499f09b869326cb81ecd7703af1775fd068ec5e551cb67fa339e15c80d66a50a199e000000000000000000000000000000000bb992f0ff3c80f5c1e3d055693f4a86ecb41400438d310f63f3db8bd106a9d6e383fdf8bab37852b31c63f8735e8077000000000000000000000000000000000608fb9d1352c66d34c1ead27caefcf0cc29046440aca78e1c70bda76180bbf6392419ff1c82049cc6fc306ed90b8b8f00000000000000000000000000000000053f74c09dc3cc6a0067ca5fc5dfaa16b6822ae648d4e8516565ef30c89e5d3e618f3e838a8eae7d4a5373762c123fc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025c4334c1dc4a2e9bf3f34ab3352ed5ce2db0a62fda1eb0c35359ea6ba094cce088c71f35b5bebcf8639b9480553493000000000000000000000000000000000c2281a34c929848b68394352566cd14dd2019542dff89815637898bbed8155bc774ac21e9f06eaccfc9316f64c67a9d000000000000000000000000000000000183887dd5f90bad6f03e362b7ec131f23ea1510c44e14c2ef3abbcc7f9b34432fec157eb1e83ed5f2b2cb66fd372a90000000000000000000000000000000001428a3282554314a7c08d4034204758b84a9e859a74f68bb19fdbeefbdea268cc176eec04db2e3b2ba1d3d5c0e22f8a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106f59a8907987152b24d2e06b6544fa476f3ef59aa1607a6f2c46f4663e4ee180c734cb99226986389db5f16e24a48f000000000000000000000000000000000bd56287c531cf005a478b2e902acdf00611d80a7dd2fe3a4d8811d83b803ccf64597b0b306dd7c8268769c4f8d60f00000000000000000000000000000000001154483752e73081a2e810b7547c1fc850788608e1d9e535f4858b14cf2a26f25cc1f925da040d6ba8c93e08a8f63af900000000000000000000000000000000077b1b222af0ffaaf18f3b757faaffb2909c861a794e89fe4d176240a9ad7bfb220adaca9f87c3178c986a83b5b3e75c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001590df6fa7fc8e4fc1294202f185bd14050a6653d2229fbf80fa5af4160889c021ba06abc023e4041146291dbb18257c0000000000000000000000000000000001a3e3b925f86b18aadd329b4ee5c7b6189038253cb35142429d83cfe8e27da6c08d3142aae2498c7788f6fb38571990000000000000000000000000000000000173a95e7b82b260b356451b949f6818c94a34f14bfd6abea0588faf5bbfb62954cd36efeeef1afea83009a4660f3c790000000000000000000000000000000018e5ad3fa9e7392f29fffd5d8a8b9201c77fe56414782f40cc3dba1fe45382ea334265f334e9c1362a388ebd3462c5bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005559d24b6d99b28e29892ec08132fb34a5b776d761026e9501f7f0aa70dea13d233ba78590133cc0e263276ab10dc6c000000000000000000000000000000000a3f9eb578d2a5e737e34a9f435f388bc830b4e408740b2b6776d7ba7518daad0e37cabd4266f2da1aea0a44ce4c90cd0000000000000000000000000000000009fc460c171f54a6064955a27b2b559e6c96e3e3bc586ce1adaacc6c3ac09c9ffd027cfdba522dadd2a92dee37dea54a0000000000000000000000000000000005b05fc30a6d14e36c9bdfd07fde0db8c002f24866ef0ffae195f6a56c8e61f026770bf08e119b9b2e7bb63dc16350851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010148761dba4ada506400d62f873df235cf3fcecc858149445c08a36f73c8a0b24c71a5f4339152efb64e765cb151b1d0000000000000000000000000000000004bb6836896e065afca43fd8fd8bb34f470a3dd63102eb01ef700bcbd084625967e03465895142b102ce22f7b763be5700000000000000000000000000000000107b5c3de487d6e22eae4141e4fa6806a6f34ff7895d47926a8023c078a03ce52d2a68faaf692a4b79a21446c2d85aea000000000000000000000000000000000cc0a79cdf9cd11421900358413d16b9b3cd269fd784d0a0835a7bdaa7cb1bd10c675352059af7bdbcc1bec42b21339c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118abf8d965275a6229d17e6b62a4e35b3d3ff078592cc1d76e9f24c9a2b2dc3aeaa75b8ffa406e20c899b0a6b3966f300000000000000000000000000000000192e9cfbd3e60ed2e4f962285c17678f855e16c5301771d2745eea8b069a31a9154860ee77968f5b355144c8fb25ed3c000000000000000000000000000000000020b223adc51f9a62d1f51b7723b837a8025076d6318a4221fbdecce8cb6abe297601d4b305cdfcebcf3f5a8d3a38300000000000000000000000000000000008f14be65eff387e98dca761f66e91f0219bd98e87d4dc42daa6f3fd42c0d7b73a7b358f5e2afb06d89af9290dd5bdce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145d007835d6d1b37e88e301e1567987312e3708f5fdfeede2b96030dc871e442fe45f188a027b214754aa7db707f1ff000000000000000000000000000000000e2c098e63fcf1de15be8b8c2c97819085cd4d949415cd470043374f71127b9a77f9ef8909c47ef0fa74a6c73b2e173300000000000000000000000000000000192bd4353222a6bd22f081a768e6bf23c4c8cddc85f1185dbf0100c9a08aaeb7b8aea464a37a722b5fd4e013ae88d28400000000000000000000000000000000184218c6ce4da2c8fadaf539aa776574affcbafc1b096fb83a20a57a928f584fdfff1834104f590f3c43482e52a748551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029c4a722d92fa5428bb0806321c9cea2043b55de07e47e692e476e4c7acec3786b83dfc61d812253399d3856fe796530000000000000000000000000000000000f7d8390cb1da7367d245a655b1fd2c46255bb7c2ee4ee81d1ef959163154b980001bc40f0f3a16a8a200ac423307070000000000000000000000000000000019cd2783201bc606f6d8f06ea8480d11ba0fb2373a511be2d8e15247c62df140d2a99fa0c285adfeacd8c11e382e22750000000000000000000000000000000000af5ca3391c1cf5781501237dbb0d111f84b6325e217c5bd255a701dedac5ba52c27fb14d34f9d7e9261f35839126e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089503a2f6e76486d5a6feb2e46fd53d3eb97539327e03360c5401167e2de33ad7130cce65b25e3a898b00b12f0fecd7000000000000000000000000000000000328997dd3edae175c47d3b0a59046c97205d7565586c09431f7f2e8d48136c67db03498ef6276c578cdd970a63b873900000000000000000000000000000000042392927e1159f7fc371fd15cb47ce534253f4902b08221fee9e4c6a57e87d8ba71d3cb5fff99ae11cedd20328153690000000000000000000000000000000006eeab2bacb56ab57daf95d03a030f497af1a6f84a33ccee57d9aa1065d496d054519a730cb9a03c21aa22f089257db61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001219e12304b160f2d5d7ad794af0700a9b05aa2521bff9b7161d935576d2d94329af954d07df6e464cab0208e64e553a0000000000000000000000000000000013ec3e1fabe23e08c543871ce8ba7aa682f12a857b6984e56ac8898be44c213028e320eca9eaa1a04ac64a3841009d510000000000000000000000000000000010d632d747a3760b060050c0ce3cb816ada1fce8ba9a228b6b427846a8680d6a31c065b521c2bcbb1e85453fd5629ee500000000000000000000000000000000155a76cf41e808e36dc5946ba4016c14a0f1b55fa3e52ea69bee3af6547c39872628363c57b148fde707fc67bb4da54c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb805540a2b017b3ab7a7514626784628d6c8e2af0c2e881e6f48f12f69662a45fdbc7da18a2ffce52c9d8f702fbe7a0000000000000000000000000000000008b37676cc30d321bcd50525a86363a330e36b2e02a00a882d8ff7a9a8684fa9f47076336a00b3d4a217e7e42ff3c5bb0000000000000000000000000000000019275a296cff3b1595725b57be0a2192808576395c5e2b33981f3c2f0da24699ce8190e459e22b62ee5ad66ee3c81d3b0000000000000000000000000000000014934d0b9c2dd1141018c3ee89e5e183baafd0144f3ca5fccb79b932989cb2245414679ec57a88cb74b8224dbc3958fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d4f6f982f5a24f092c2c1bd613e7b1a8c22072611f5a2d9b89f54415edf81070a30333bcebf4d7d65284bfe716b6a0000000000000000000000000000000000af87dc1fe049fb1c739513b4a9214c0a9e62a811e2e0b58540faea2bd73cf174987e764aa3e83c1ce78e2cc8cfa4ddd00000000000000000000000000000000021b72d4c6b4d84193aa47e41899bd982ac8051e76e7203ca10bdee2b941a4b941c04b51dfff170691e62d99857a377d0000000000000000000000000000000003292ac965b2e6952c4442f7c8927bd042b9acac4f41befc047e572f39d85eeb3ac42ddc064734a139a317132763a0a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7cab94de09818e92d50a78da93b7659e46c855701daa95fb435dd73e289f388ba3bb91359a504a4eb577899b6604c5000000000000000000000000000000000e868c81096d55d09d5289def0b9b788994fb9bf4a47d3c15c5a1a4622b2dbe071fec69ecea1d0a8c82af19e05022989000000000000000000000000000000000267233c3050ecaee9a068c58a710927cc440525f4dbb8b3f8920e11cea0c6caea772817357ca9ae510cf74127112110000000000000000000000000000000000e37b9297f6bb78fd6f7ee47efb5d6a27107e73650d3aa96369a666b9a72c98f3c0a6515d280aafe04e2a95da7ddb62d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fea85a96b12b300808f25892c060a72b52dad197705930899221c6a321e0614cad478e09977598341751ad566ad10cf0000000000000000000000000000000017dd12c8e43454363eb1590739d36fe2d9fe223cee6547a152c19dab114092e83bdca6a8c912ba64a656027d97cb32550000000000000000000000000000000003fb1b0a6f08f2f03bebc687b77903234582c808179aa78c1ec160ba76d6a662be3feb5a07588b01c26a370ce8de2ef300000000000000000000000000000000190a14e84d1cfcc0fcc759fb58e700d46d6228970ac4035067554a4070dd9a62fbd52efe025dd8ecef50f0cc53dc37f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000445d7d657e12332b549826b0138f0c47aeb5f50e6f68b6ebc69999622f12bb98fe494aca91babf125562c694af271050000000000000000000000000000000016454090b9be3f3d4ca511bee73e6abebdf81ffc0cc6b1e19ac3e584273721ee006454e0e16ae951eb9d1196a0f69dca0000000000000000000000000000000001cc3df73d05ae25cfe5cd150c66d73de3e2cfae2d3e22c97534e7552220a85a8ef4e9a94e3c74987fb2cb0e3fbf767000000000000000000000000000000000070c5fee39070cff04484b42b11348f950888c492487d101bfb195863d5f3ec93fe5363ebafafed19ed790c8465bf3431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf5142432565c7bb2d23abcc79f1c99ed3ea6b03443a0617dfcae19247c30f9e00fa5ce599b26cd5650aacac8d89405000000000000000000000000000000000180a64ff5a58f505520f62bad618ad50cece1dc4f7ece679edbf688ea597bb31f7e363fecbfcc372ea500bf1c2dcc960000000000000000000000000000000006a9e0e71829899f7b4e93988b760174eb816bc0b8c4040e492658ffa4d331346871f2a0513a3fd10b40a6dc9b6c044a00000000000000000000000000000000099a2f0120cf4f9e503113f8070f0424cebc5f8146c8f44f4e21f09f578d311ef6215bb39ae90cecd17b4ffefe32a1521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000118b97ab86279e157377e79587d93b45d6abb96db28e90d78350ca5e0434bb2b40be33bf68f32d220bc25377a43907b000000000000000000000000000000000c3541d8ff3c798988deeabe76baa8a33ef8e42cdd3c67e24eab2fbfa3ada4bc6353d1ab6fba100cd3d66eedf5c8a88400000000000000000000000000000000156d586569063d4e2c15985f3c9f1b5686d71772e02587cde456bf8c08ab9556aad7d3ca30a155f171923c6f6ae14fc50000000000000000000000000000000004436bbd14611049c6bc011accb248b798f69aa3a130a799fd72dd510f7ab2e2db850b60510c68b828c011c9c229e2411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018ae33f2cab26332f89c8ffb983817a6954c88ed60582ab84936d476ce476b29e6da25e770450403b85f257d61d19fa000000000000000000000000000000000b07df4bf883a70a326095cc7e289bb71ee13936939b7245b2b10500d34e9e2cf07d334d149a4c503418629855eee08600000000000000000000000000000000084c8ec19b2c62155a3a3d595615735a4960c0d9a3b50c06d464de088efdc45f7bd359c5499cfd1046abf493a047f5f800000000000000000000000000000000040495e7d8e7e9726c880793452c80ab5583c539f9f2a05cbaf354b702e74d0f8a6aaf860597cb22aec455e38dad0cd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098c1ac4462089e04f53c4c1b6b9b380aa92e0ae6d0bd189eabdb94db6c53ff0dc0485397e47ad1ed812aa20a7cfca84000000000000000000000000000000000f51b4b2cd49bf76618865531bdaf018fdd42d5a883d6aed4abb9866c8254c1e5aed9f6c9cc1c085e0fa5067c4cbda490000000000000000000000000000000009cc8c63a3891ccba0bfbdcb72409d933471f76518b30e709a87e9db47737acfb0a399f19a44c99e6a22b40cbde3958b000000000000000000000000000000000bc46fbd5022780a1862c9b3bd73330f1b496c33e8fe7fbdbb3349a1fa2617fec38b0720da4242c07835bf3f2cb739c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed1624555d62e854eaddd66c65bd0c5520a8f01efcc08e1ef76da1c0a42a68c6639e7249b7e0324e86e2a55407d61c3000000000000000000000000000000000fac774e6a9736aa09138b00b08966bf0c491bf0e00dcd45d750015dbcd93b1a1a9d95815fab6ef7b293138e15895d690000000000000000000000000000000016f127cd5bb2f055e738351d713379482b2758f21e6b38ffae59c74994ef327e51939f89a746f65debbdff5cedca23c3000000000000000000000000000000000b34027a1947e4aaafddbd47981cb504b85214c89384d8abb3fc7c17338c413c94aee995d76b87efdf1b486e6fe6f9a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c70ddec848fa4c3ebe8517f614c9ed8889d9c5d349295b81ae8d0bf5bba3f34e878c9ad1b2d23be5c73d03e17349a50000000000000000000000000000000011aa181f0714fad33823d3932d9b07cc1d86ae31959a332de520e685a7f05c317ce7ff0739af78c30b5bcecf03b82e60000000000000000000000000000000000f0158a3de674f7743d4bf831523a3053a851a3fcff21f5212ef43a2e2a32be0bf5c3200ba3ff623088a5b50c3b457ec0000000000000000000000000000000002b1019978178a49063222109b4ac92beabddf1768f2805e6c3d2f8e8a4051a468110d3782251331a5399e94f43d57a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad7012462ecc64ccfa21a7f38f6a4c2cb73f72b85a1f60e824702da284151a87d3c5d6176af15b3e231098887221377000000000000000000000000000000001458c575b6fb43514a697e59305752f005abd92a50088867f6ac3328d61cdb66729c8acba780b7f5e1dbbd6ceff72b4a00000000000000000000000000000000143837e6eec33b23b50294b25eb99f8ba70459f55cf9c4c29fb89c70d3f8f8c69bcf3022687f7fdc887145819e633c790000000000000000000000000000000000690676d5e3293abda1edb565641519c6e052a84446eb9cca60e0ca61214d01d9c91080dacc77e92eb9900a933b7dc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c103b1d585bbdb1374ac1915a2056769a82deb25eae6d0b3dedd7023d3f4ec638017902d822d7e11009eee3c361eb00000000000000000000000000000000003de5b171452c27c66a17b9b06cc6dcd90582f3acf005a487c8dde60a0da0c1a9eabae9b078e7bb6685326625c7983060000000000000000000000000000000014f3a8f6fb65893cedaecd91bf97c436e3c7f3d515c20d160ab8a407e14d4613a21b906cf74cc63f4af5fc0d34eab1620000000000000000000000000000000007fc0a2e72c524b0f17e48bb17de67288924bd1286e85cbc8b42f6fe73d3311b753a26076c3ad62968d2ce929c94f2421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d3ffd39a341fdab36e0c3435d3ed1051d5269a5f0b7b6fa430d72e7de0a79a454dc68d098fd648e684b69b8ad59b5a0000000000000000000000000000000017ff7c02f11292749f8299fba00c82c8720e200f3b119e04d5bed67877443d28d79bb23c417110f0496e1257f73c5b4e000000000000000000000000000000000e53c6688390c86b74dc2c29afd4d853a9265c58737135eeb10db034bb233a747dfab6a0a9569ae494657f260afea7360000000000000000000000000000000013d475b4349cf1635a8ee6c5f81fda22d183a1c87f9aaf1c155b598ea08f1c94c30b9fd01cf10d0af87b5882dcffc9951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007698fd918e02cbf27d0f67c587a2394268d29a71553a2b68d21b629cdeeb77bb83f5cc05e264387e57237f592f835a20000000000000000000000000000000017f60f5ad4b8504e33989a9b139ce8c8361eabd0ff10ec77c777831c38d12e7544fed6b392310dbc6f7b65aab5cfafa20000000000000000000000000000000015d402fb6640583d6091c374051037fed0aae24a8f105548779ae9cc9abe95dde78a44a14e54d83bafc4c0b2df7014fd00000000000000000000000000000000187eb5dead0367e3e5387ea795fcd4c82b4b349fb9c19537feb5c67b4979594220884964505ab9a34ad8bb659bf579331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a16994ec5ed74a8bc7d4df0fa6d745addf40deb79d886065556581908204f3d914c62371dd05c08a9f4730ac1181f4d00000000000000000000000000000000103f6a92ce2c3e1fb12b47d46f7f8a24e895c1ef48af26df066f71b94be8b81468a62912673d532fe1ae9cc9277dec5900000000000000000000000000000000028978b42ad0b929ae98890122581c20db193a28103b472b8a337c0ef0eccf4b03157314753bab22b6894e1eb7895216000000000000000000000000000000000e30470638e4f7c5f9acbffcff5d6a9ecad746c2160e1db09b349e4f8b52d6e93f2899a4f00bd595896fada60bbdce3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024b06ecf1a79a587780396122fa407f36483272e265abd577e38349dfd627c433cf55f14a5cf2f86122d394ccb330cb00000000000000000000000000000000108ba761933bf2abc8e0f8ba0a8b60079529fc590463d25b3f8b69f31f1deee0200dda237f05a9e44cd480ec3104034a0000000000000000000000000000000008b509a6a62266b0faca794348adc435977149bb1c8a676b3f5447f4f441363afafaa3354f589ba9e0f8ac3cc6bad6980000000000000000000000000000000016b1961ead0f7a684a41cb6423deec76240f6b8e25f86dbda3d9dc398cce0c4c734e5ebbe23b9390d9a67ea6eb0b0d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6f4be5e2e7bc87fe2635f58b64f40a5e3824421f3042441df374e4ad592122e765c1723c5df55af952ec43ccbc38920000000000000000000000000000000004354fb79eaf507ddd913f7d22c8c6f9788eb709497f392820d0bd2d29bf5902f62702d3db0461cd078489da4ed0a3f1000000000000000000000000000000000951e2dac11df138e1bdad50f95ebbf07fda31db0e5880b66dbd358c5ecba7781a3b5a75277a1dd8dd1bb89c12aa8d930000000000000000000000000000000015f1646b3093d159313f10cc5df1beb38b7336e772e1403a2b59b4b6ca2a1e7f4447bc9816638503578674b6027a33bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d71c933dc5dc3b49843e6cc0a8659cb621b1ceaefb46e54bd916decef3598f6c24cf53cd520afb8da964b39311406e0000000000000000000000000000000008051472975077a123c20de5fb1c6136919f34d09540715af9fe926b142e061b931d81bf07e59bcf0d96c0b6d9aa51b20000000000000000000000000000000013b0cee58129957ba87fd87263a538aab45e38118aba23fd936b450a1254bc2fada25f33725c4bae050ca2079b5de35200000000000000000000000000000000042a0a8e30f7554a5407bb0327d4f320e7f37cec75248d18c9fb6bd2681024a6f71655cb319ae2588ae9a38f65fa95171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bffc66d5f8be4fbecfd8c2f681be9a8b0fec5fb8b6e29727cf35167489bbbf994f38b5db3b693f8902ad21a76c2cc20000000000000000000000000000000005a09c10dfbe15d15256dcf73c1c6913576861f1fbe9d23dfbcdc62971438345385103b1c621141c928f0588b497b5f900000000000000000000000000000000141c70437c4a1ddad21ac5d8ea3a4c44468a3da4c71bf250f759b094ab652fc5b4ef9dee94d6a215f9c1620d7231373b00000000000000000000000000000000127ce51b386a00d1db60fcfc087daa9447d0fbc0f2c894f8b3b0a853d492713c073da1422090d4a5a0c6a6d16a6485f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e33681fbfaca9dad75d95f02d0a2f2c0ae458675f1a5d8a242b657716538b327f464dd67d5c441e43336082264f4817000000000000000000000000000000000b30970e14724178d5c3db7521103eb7f63a28b5222d3e9dc54ad456f698c88d5106e017fcb87de1570c75d743bf7a30000000000000000000000000000000000bc4d1f80113580f4e7ae3addefdae0c8d9ca2fbb07a9b50f01e435cd0217026a148cfb0d6627d78b995781157f51d6700000000000000000000000000000000157fa23d6ca8db81f46fcff9ec6bd9a55ea8ef74b92b8bb825392e843231c439e6be414cd61ac7d942525daa82df4e781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebe1fe085560e6cec63df2e9be5e4b93fddc0d9f2c106cf2bb090a6140f30dbd750e573f828c3e9995c47aac23e494d0000000000000000000000000000000009918e777dd9d2a862e842b35d610ab5e18131bb9db600a352a8be1404db5e927f5489dbd52fbcada228b940b7d05d1f0000000000000000000000000000000013eb8fd8e3a7ee57e43393b3f04c00b94003aa0bd303f6f9cab56eb0a11aad4f3febb4b851b3a854668d6cd1ae28e95d00000000000000000000000000000000128e836ca52db8703e0ba1aa225be766c866858df0e3d6faf9385a6b2336f3a027b294ca67cb7c9c75989398d02a361f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130686df1ea7843cff4dc3df6beb1cf53b51cc60895a292f77076b006d5f4dc0a902216567332c7f0952571eab09f4be000000000000000000000000000000001508fc91d30635bac7a8d98dac54e8967226fbc34547c6e284221bc75880fa8ac2f2184005a4be2ca06b41cd587b508a000000000000000000000000000000000d4d81edb5697e2e55c89ba3edc8c5d0155de81f1aad06b8f3765a91f92b9f51a2bb51481b98b0e5f50f66ffef2b0d4600000000000000000000000000000000186f3017bc3057bca6e168309521f1f8a6e94005de3d84e1d63f329ec1809327eede1424784f00251bf7f5518595776b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd8a1f7a0d6a6cb86ab876a2140ace1604f81d7df839c50d70b86ce71ae695bc1b531559f1220c13bedc3628a411fc2000000000000000000000000000000001416f6e7cca8f3408831957a64b2351b0b43ba7542ea21d2495c5990c5641315197f14cff29daec0bb5db6c608a38e6f0000000000000000000000000000000005bd126859dd60b6fca78d383556003607e08abd0ca52f7149504ffe204e4101d49759fb0f32c982fcd3c205f32c0b7100000000000000000000000000000000046979f08654aa9411aecf99580c5b07f3192bf5ced8e55a8e225cb9ad021edb3af7744e939be339d7c39e4e8f36e8da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071159f89a8b3a02906941f0aaf002dcddd336b235b531a9cff21c1e072073cba10ae3077181efae0acf0ba2f2202cc300000000000000000000000000000000120e0f802a66aa5e9b582fb0ccb60878e1f0433ccbf2a2f88d2c7d9ea0fe61201d6213ed2f854b17216243255878259c00000000000000000000000000000000136148759086cb411bded88ef18e1ca0574a6b3bc766e3f4e826a21f39b6da4de56301192dad4e00c148b191454f0a860000000000000000000000000000000018bc6cf50034eee58baa3a8ad1a54dada9e7ff4164460435e6c4592db53d3c60d635f27c5bdf794f52138d10bf7a4a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e70178995eea1097369b7868656d24ee7769648d874bcd37484aa03c67b4126277ad480d28a820c20cbf6fa73e5f04b000000000000000000000000000000000adaf569491dd6e7a7b44ee30f6e091dd5c27850811fd82d267dffae514d2c8ceb68990c38b797d66a1f99beea3a3be00000000000000000000000000000000015c4c648991d5049534eb1a008149b869deaae0bc877d7b09f27bb916ea7bd431170eef3d4d28d558e68fe57d9cd371e000000000000000000000000000000000e5667149b1e9420dcc273a0b9309ed888a41163baf627d55cda6a826fdf5538055aec3bf149c284fd64b60e231a6c9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002608976378ec8bd9cc7c0295d67c18a3b46c479f2268385e92efeb1645c5f586ee258d8b38d415bac5ccde0adc2a01d000000000000000000000000000000000c3d0ca717f1ec16c9bd1a8b61b99448941d75f38be423bc5a1a3f26f9a32612fba6ed942a00c676332ded0577bd2d300000000000000000000000000000000006eac2a41b22783bc665f4d05e68e386ada295c00e9eaeaa23167a8b5b4888b925c3f2a9ac3164467b499ef77eff5f430000000000000000000000000000000014d445a2fad739c2b5dc5dbebb5cebf02308fd87d8d5a5ed228c174d8dbcb41b8fe876cfd04cb1f4146be1420c2009e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018943335cca4825575ed886566cd3efaf6282a39295b7e376a58daaaa57571134bfb36ea0d19a3d0cb95437dc40b3a3a00000000000000000000000000000000176fb128d85a741e82b72e182732c8ee8064e4625ec743cf675c95f2c3dde2fc89b09e26d260bea408a6833f8d66f974000000000000000000000000000000001987925266de60ccc4a2ca212885a66e9e09987413c8c8b3e2d7af71394b0c40d059d38ff17e2bd8ce6decb2daaf0be30000000000000000000000000000000003fed60acf0fd62308eee4155ae4344926ff113742ff975e89925838c0f9b1bd075983a4724e60775264e55e1363667a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd19ec56855801d0a0ba2d50eda2b17905ca6fa183be5c7ebd4b9ba2c5ae7a5445e378492176c92eae1e717aa88188100000000000000000000000000000000055cab4dbb6c8635b95e4794a1a6d7b7eead9beac6ea80a6fe885fc174744077dac552afcae981069afe94d87b2816bb000000000000000000000000000000000db9311384e6f983bb75da4d0cf191186f3dd22bce3968dc4d38de07f00ab8d08edc32b015fb1b724189242cbb10f18e00000000000000000000000000000000009be8c974b772e3593086fc429c40e0dc4c5fbfe0b1ae3b29d98edf975f825571f3fca8a3fa6a4e1c29c6fe35ee864b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188257dc1f3b93621ee506da5519790912d461bd624ec515e0f611df97431ff44cc5c0bcfb0379ba707b1d2f232270210000000000000000000000000000000001e8ccb33ce64442b166eb1ff4a710fd4f8604a4af9820590a274d5ebb204b9d2c4ef25ca1e776c79f8a06c3d74bc1ce000000000000000000000000000000000a7217e53c5e98ad07c30f15037beae626afa2b396cf679d0eed440afbea745d124cd352bc099f6b62bdf61a5bc15e010000000000000000000000000000000019769842bad8bb905bfbd787c5680359023949bc03d67135666e8b7c88eb2a44d486c5706dde88962dea791f5125fc1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7f6ee7b57e45163f18e5eb0de457a3df53a1e5e62b81e12b87fab099b022e0d44e08dea4153e7d9f02c2789b3df2fa0000000000000000000000000000000018e82f6683bbf6faf502e88e6c5fb49f1f04299761d9aeaf1f6cb6cc15ead042d7b65f261edf503122fb96f5d19fb13a0000000000000000000000000000000008e8898f68ada22262019ff926d6c5aa6c16ebcfcc0d326cf5ce8f2c211cb253b3faf7f2aa31d0e3a32ef76371c84f3500000000000000000000000000000000062620bad9b4f5421ce177b0fe758faf0c5d404cad3ba2387d711ed6bce9d91fbf062846a1dd63d548431e565fba6bc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000968e7834b782aad8c38a570a98172e7234c0ea09946e5dbf81b78a1fc8e6b7e897762af504f774dd250c4d5bbebb9480000000000000000000000000000000014d4d7380be984e0269edc8be18f7a8028f234dafcd8c6690392a7e56d6797ae7dce4dae2848d2d7cb9a20b5bf46b90d0000000000000000000000000000000018b68cef920fd129748369cd6967d72d53b569ae272744db405e70baa3d9c942de536c9c28e640999bf0bb00e153ea130000000000000000000000000000000018466c3fd278b30ab4551c2d7346a87b6c3c8abb778e388b18684f9051aa9b797e1f87607388d35dd3b18c4076a7a6ce", "Name": "g2msm-64-jwasinger", - "Gas": 639360, + "Gas": 838080, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011bf95ad1772f69ad45ac319a445e66408f564ed3daa1c38b617ee03f649f85a099e7a0d73c7fa47baa85b6cb775b6e600000000000000000000000000000000021cd661e557d8f48a7bffd200b55f235a3f004e10230214bbe2be93da31a2f14edb183b68027df610d07105824ba5fe0000000000000000000000000000000017ea617f4622808f353828b1b80a1ea192a4c0e7fcadc9729e88516b4485878e9221353a0f4e83ea32dac98971762efa0000000000000000000000000000000019ca9fcdcad78d5582b52ce9d659de99b7745ed92ef709daca9c4cff3720ee67e84a2b8be13e3ff943944915e4bf70821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183d05207ac96afd59de75aab7126369244bf25d579a1aa9118272e3412225537515d20caa24801a4465165d3206b66f000000000000000000000000000000000b237f18e6abb7eff816b95ab7b520c371bcae2fe0b3fb2b497ea93fc9821bc2d821d4334b1bd50daa0ff4ba83582443000000000000000000000000000000000b4d3411c277de9c6436dee21c1dec262ebac011861c57790f405671bb103f92bb544a70f68d696d053e22cbe22959b2000000000000000000000000000000000eb9950966acc0a75ff84646151c2bcf0ed130f5cb4735fcdd78e49567ee94ce5c5ee1c6fbc2cec5c5e25216d31ce8581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f818f9305781aa9ac1f2d5747473eb498c1ec52cf6a04ea6850b6d4932631a32fd0d81200ab72b42f72440eb5407f90000000000000000000000000000000001e16b86c72788788152815091e905de94cd7c4544634b5786be5c9c7d548f0b470e8b2704694ad10baefb825945fdcb0000000000000000000000000000000006d22fdc2e0195cf84cc7e1beb4124f197bf294bb870ffe59b155406c9d4061137152afb4cfb0ee95a328f485a04437b0000000000000000000000000000000004db1b1dc6e48b7dc1d4e6483db63fd83f064e53ed49e369f7a6f7d7d6f2482c12b8ce8bbbf7a7a1d50ec85a0e0e7e421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016181cba8431a6a6ba44f0ac2027aa758bc68cfc9c81de414b5382efa57dd2a222003c70825a97a2768ea167451fd0c5000000000000000000000000000000000e22561c73c06767102e03ade2083ee34441ff1f5222f5dc170b5cc665703af8926568e46e8672ec9a518cf87332b7400000000000000000000000000000000001d96bd978693dbcd0b3d193ee0930ef8772773f644e0e8002cb600d59d20a2f632d2b99bc22624ce794f92f9675b5c90000000000000000000000000000000011d53975075b9a9ea263da477138d597938d26eeab1e61591543957edb8407632900665b5e2da92192d8e0637d050fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000528b8b49b95cce73bc630270ce3878d80b17e14de2f6c15543caf4246600069925ddc3a88715336a70196f63a0260c70000000000000000000000000000000005b2fe13feea37070faaaf0ac37b9ea86f12925f43f0407f6d20ac324bd72dc0fb17a80e723a20e6d52134084ff4533d0000000000000000000000000000000006f7b18d990002898e98af11b7aa4281bfa76fbec6dd0412c58db4d1ab40ca763cf337c78bb39b228320d0ab58ed2de200000000000000000000000000000000163f2c6b661830c103c69a21750bbf4d0624d62edfa7b272f717de925dc88ce8735f9231b34e722008259ed01fd8e8491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d3f67b80a7ea1dab0e0738a35d3c93940520588871565867755ef1279b44d99d9f228caacae8d110e3d7e48f222d54000000000000000000000000000000000991a65a302543152d436e398863e5cf78390fa621fb1ecccf3e27cfeaeed08df571183f238a18243ea17c94ee16d8b100000000000000000000000000000000095c56f87d0ac73281f15793d98a388a6ae48aa3eb5a3d2e52f7a0fc2c6ac508a792526aeb54ef936a70110a3c031b38000000000000000000000000000000000a6e112510134ccc1e0eed83d958b2dce2fa8e3782077cbd418369095e37480e21bfbb5d42dc8e23d23702c5cf3b4e7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017df7be5dde1a88a02c2d41fc0ae70306fa4d43419223cf8bf688bc69f1410b986a7c595e9a7dc350e6abebac45d843d00000000000000000000000000000000036f844b7eb9375b73eda48a93a46ba6f6d1d9447681817c859454382262b323015aad044bfc43314462816e4f8408000000000000000000000000000000000018e2d590bb7f4f5afb796ec26175fcdc6b297811ca0c839ebcc6e7aa3fbe7e31a9cdddbe3014b14d17095b8b1be9c89800000000000000000000000000000000154c986ff4adf5da8c67a1d9d3cb7b72f33091f44ecd143cf08a03bfe2b7327e4d8e062076c9b837924f59a5120ccd421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dba9d7bf522c7861e59770e85c754826b6c0a1405581f8c0b951e395f12e526189ee280bce7335d9fa600bb6e4c0a10000000000000000000000000000000001e3b35f5b9841c503be6b78531fe35dfcea0621200b98631df020877dd07c464988fa7394b006b72be373337a705cbf000000000000000000000000000000000ffb25f224b9398347fa2aa6c480b0f430ed181804a89ba557b52aba392a46d585d180c0ced63b63fed2aff1e974a20200000000000000000000000000000000165df20728116af2c43d4939c9bf9d574c206ac38a4e5bfc83f74e30a3f7334630171e21f7a435d0dd0f9ca4412f8ebf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a9caa935578255067a7174973e0554aa3a19b95929e60c4d9dc5c6f16ba9c1cc79dd7b708e1f3d2a876d3463a8e3c90000000000000000000000000000000009e7cf8411280bc0193b0a731be8102d0d859be09bc9f209ef1528d08dd72a1ef358a8c3ea5aa8c238951b9ff603e6f00000000000000000000000000000000016989f0d153be7bec06f267c0f05dcdd40d78fb4b166eba9e3a6ea713fdaed4b5fbbc6a22cd905b9c50f6ad9039cafc100000000000000000000000000000000115ac4aac8100852d3e5a0694210a47f13a0fc03d3247529eb7f9c631cb3de95aed6c7ec062d1609ae3e6ef6bd942f571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012f31134bc1912d49dc76c721e2ed2da1f8b4ae0869509d7dae4898a971cd2dfb9317f0bd8482b81053d2fac12bb55e0000000000000000000000000000000007cbb903eab440c287518e1af691220c6261879106b5a93a00521b62f0cb9de25ee537125a8bbf0c411c4b353ef129860000000000000000000000000000000007d005d2afb9df74302cc74383d0252304e3bc8c97dfd74b199a6ff66ebed449689aa9e043548ee3c9630975179bb71e00000000000000000000000000000000184efa9721d267c93dcb18e28d8c46efe05bc940fdf04dbc7de5ba6aa8a6365a0f9509dac55c4243123a01312b79c0261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3f526772ba81c522a45bd5e6177e30bf50d7e95abd1e8ab8ae867d7f3a0a454bec9304fbc7c0a91ee2bb5ace139847000000000000000000000000000000001134ee079e575481300539d0d9815e8b2c2e7e255a15bf7928c11139c1d34a1f4c977a9380532f8940d5c1dfa6d2b7a1000000000000000000000000000000000a83a4b6925852afe2158959a8022e40cb2d4cf980a2a96675f657eb263b42faaa18e2917c24d2ec3d382079de47993d00000000000000000000000000000000030c559fb1b608433bd824a26471711dd7cee802ddd5440f9aca4ad4bcb41097b47ede09f523e02c785a63a0102b9c941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001799796f61018d14d6d87764b0ead89baaf8d7baad27e8654b9ddad269e93928e62924c91f119f05e6420d9b1ad90b720000000000000000000000000000000004c99dc947e4e907a15758d68e48ddd4992a77d4e8288f0612f477323408340c2086e1beb3ea2ee139f2aa6472b3f08d00000000000000000000000000000000187445842a928286f67fdfd7983a775d88cf0c33e9dedc9b1f5de020415809123221e290ada1466e47489d17f9bb490d0000000000000000000000000000000010a169368c6222a06eb6c427e02be4d1a98bf3a4e68d59c3330336a0dcef460af33786de7beb9119cb202444fdecc36a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001032b846395fbd00575eef388436d9667153141559c11088ada3b632c2e821feb3d383501cdaa39f5b8bc1f7273fe62c000000000000000000000000000000000b77ba55af6021fb5482b3ceb55c6f0595b5ad7dc21c2eccace0abd6044f90988deb6e02f8c21cd1c60ec47f55eb0bf90000000000000000000000000000000007eb939057991684219eb08ced81f7fc07e1c2e5d77584be74dd6e7eacf7f37b4236f45c91e2a6cff5f8c37da002571c00000000000000000000000000000000131f788b2be988ffda7ed22cd52199b3c287ad44f9baa2fdf7f36a7bf875fdd2b9336d0083a864d8c93c8ad19d1052191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198f30186cef7b4412668e4873364e94bf126dd00ed3afbfd65c168d961cc40f46372d4c996a12d4b83c1a2c315e18ac000000000000000000000000000000000e8c5af02e9019849426957ba7d11272708879643644165b3eac74b99a70a071d5f287bebdb8f76693fff1017bfb5a1a000000000000000000000000000000000012e046aa90badc0cfb78adc0d06d6440860969fbd884395cc3887eb9d2829785a0184cc2bf812fa9cced0590a694b30000000000000000000000000000000002fd0481d55b95a352579b251a41d6efc5c5ca2888b221b9067c57ed7d64a241a4aba6a2fb72d86c56a6596107b9dbe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddd58d0a85d73b8a443b76aac1ae70efe56eae01e8f7431c18f28b95341f9f0e136171f65dfd5dd2185c88ced1505960000000000000000000000000000000017064f021904c483279aad0e44627ad492e52482a57b53f065802d4406d19e91bb488a6eca187f904fac67d5030902bf000000000000000000000000000000001370456afdb9dcf3bbef4a9e5747b3ccb93e342775116f54b4826bd8c90f6f63a52d4b0b5f1582d8e650a9782933c21c0000000000000000000000000000000013d318d0cf0955267170480a7b69b429c49e8ac7ee3b3389f360229cef394ff8d80460369a049351149371411acada8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139f8702b8b767db78da045b4846e55dd13395cd49df355e53cdd4a0e39734422b9d9a7e778f71850f14de459a989beb0000000000000000000000000000000018c2eefa8c6d35ae23e12431fadb12d0a48a2b7cd5902ffb17cd84855dcce4779aad3c7a4260397177b23b3bfdbf49cd00000000000000000000000000000000158c0c849d10c5dd247fe1e8ddcf3b364ee8d27c7da5de8cd482641dd225264f8652815e28ff464da2fc3be2accbd427000000000000000000000000000000000438e0a810626d58cf92e85c365cfebacd6f9c503b540b3432d5278de8f8ffc22a5e6c822e3c49a1e8076ce3fbed5b511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e0f28dcd092149d1ee75ffb1d248162909de3d4ccb434d24a045667c7918b860ad57f29d26137739d9db7adcee000b00000000000000000000000000000000060a0281668b98e6eca3fb0c66f894cbc5af2788355236a8dce5cb4e7e7b202393de4787f871eece9b62a88417ada91e00000000000000000000000000000000197d56944796246c98088f574c984da3db7898c63527bd2a1625f96cf3fd1a16ee52f4dc93006d98e975e1d0f10af24a00000000000000000000000000000000055e939c9891a4d8c1850004b7f27b3d769cadc78dd533ca47409a18f39e1d4b97658cbf3a6829ec60efafa93b151a781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1d69acfe9fe709bdf8b522807659034c32933f6326600cc4fd10ace2d4c7ed5ac590a22ab54c82f27d44fce704be6a0000000000000000000000000000000009c86b430aff2a061ec052a4427654229bf654622cfced2f84961af8941f74fbe59df1802cbff705819b7c62b8d59ddc0000000000000000000000000000000007048feb29124210e4b66ee35a1de37eb993780db55e49ead4c96a5c0c124d9afb4a9116507164f42e742b5ce72667cb000000000000000000000000000000000c4b40e2cd6fbe96903a9268dedaf4f8e15579aa973314a0c3004332bcf42acedc7dd8716cbb17887d926947c52c9ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188b14f21ddd890a5bca4a2270513575d9e46c95f3cb68c6b98616e2b1a0eac508928296548589d99d0146aeef386a46000000000000000000000000000000000f383dd7a06bebc5b9656774d1a7b9274a91ee213e5492cd1bd3325100b58b1c050c873d5b5fcadf083083a1b9956efe00000000000000000000000000000000139fe25154f059b556489e7e78713ab9d989ff788b75e32f70742f0311d9277c339be25240508d65fa91da115c7c4da80000000000000000000000000000000004f1fe8e6254fdec1968f807c061448a28746096d64d0f1919f51eb3eb23f65b3db1972abe985c48ef47c11b0400ec091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c82b622c68df579283e79c8e5c797de5727fc47956b69d2236f01e3272bd5707911b3c015a05c50c0e55dc7bd81e145000000000000000000000000000000000c15b7437c02b11331a9ec54128f20a1795ec4caa4740552db1d7d6a4b2b4489bbef556b21ff6ed5313236779c5260df00000000000000000000000000000000187f4ecd88c9aaa12c66b318c1e46a5fcb33c96bdc535b2eee47fbd2e8590d9c3a236e59322a367aa74668f3ca55b765000000000000000000000000000000000091fa89d41faa7c66709260fc30efcf8efdbdb2154311e79c1e7ca85aa32f1c431363f4b8e5cddd807fa32591c2ff6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be9ac27751f096b806d84bbe2c6073a3bac48d6d9e0e3cb78d57d53c1d5266bc3457ee4b7f608011c4acbe573ba0a1e000000000000000000000000000000000e59da4d545c63b3a206b2e096421d89fafad3ea2e1132bd1ecdc6e3c891756cb5f931f87c69a4ae6456db78a98c52b30000000000000000000000000000000013fb1e7bd0e80b1bb1080b4c24eb692430a0c7c00385634b4d626a3c69301e0ebc5f1f3930ac0edbba786c9d9f87ba6b000000000000000000000000000000001202bdcc1a174f032176807693c63135edfe432f014d1054fe22abf7a9687e0833f920c114ad4b4c3870572a2c06f48e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4ea28d7db46ad11c95f8081b7ad6520f3906ad1adc747ae04958688ca3f52d08664e5f779353e889f8a52e78f4fb960000000000000000000000000000000015650b4211fbaa984b2fa2045feed77ff29e2f96128a5170d86f4859f881a4d2a212a5b32c0171ffb05edce458a23dd80000000000000000000000000000000014820e8d8989e298cd4bc9294ecb69533db5da7e18e072e0b4875e99c9c00a90c84cce168d8b618c26845b34e2e65e5000000000000000000000000000000000008010a75425d3921b5cbf37e33f342af25297c116e623a2c3da823265fe50a05e67508a04ef0c94142b7a95bc380ae21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001617b619ef259deca8bfc5d2f628e26436ef1037d50fe9750697937f16676b8e83d6acdb79befa04cc8a62a8f6f8336c000000000000000000000000000000000d538ce271dbb8e830cd260c038746170ab7485d2649c08feba271254de32c380e996ef068a7451bda5aa07bdf2e4b0d000000000000000000000000000000000f476f858e7fc0cfb1c63e738ccc17bebf58a23ca3ff3639a06ee8151a886c9c90603b7950b5fd2a3dc5313bd8da9eeb000000000000000000000000000000001891a03697e445ce23b08fe548e40dc7659cc3effc25cacb0e1df2382b0a920a45a49d01e40858a0eea191ec66b89cbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a38bd98b3ffcc24ffd5bcaeef7b3714dd67e8399e5fd5205f5fd666c0e41a03af70d696fd3242e14cc152460680042e0000000000000000000000000000000017309c2771f7c4ef4af81ffe7150794232af664574ec45502b677f90c94fcdbae7eb588b73e45c526f25a9683cac2cba0000000000000000000000000000000013da92d3139de87fe537a6da43748dea4306936cbc7366c7f0cb9fad1b27656e2b2537b3c2b940fcb0d5c4811ed0fe13000000000000000000000000000000000e48e63a9d2f5e830a52389f696d0eba03a91c5ed34ee4de8a98bc2172fbe52bbd2d51b371f009260b12e2d5cffbfdf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085ed6826c51ec127d79932edad21c18f882d2b98f6f33a49add86d4e1c5860356a03f26ec8e9324c967e81e1fa91f6c000000000000000000000000000000000a276b914c7adb3945b88b95bc7a237869b6035cedc606c1f31ab23efd8d4a9a07996e74876acc218b8b42534340d45d0000000000000000000000000000000008ffc3e72045c442786b342ee1f081a9634f9398bc383d752336d0b4a6919012b307bdbd330e7eb3622774262934ed4c0000000000000000000000000000000010b15912daeecac9aa40ddbeaa033b874c04457ff17cce889fe4a5fe2bd0ca68975075396af74d9fb60bea04764e49c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee9e739407b62524d511edc5038651266bd31b635e65c7efd25fda8c1d9f6f135742681372eb318256014a9817a00f30000000000000000000000000000000005c866e07aaabbb4a332e2b3d46e193cfb42a325543663acf14badbc521dfdeed259562c2f4f72ee93f587a4a737984e000000000000000000000000000000000417a4dc3d10b3b04f817130b25697a191abb7b16deaf8dec16d5ff7ed6bc90418835f8a7c98e9bd8ba711d8be83a35f0000000000000000000000000000000019eab00927b6837d3456992f0ac5c57c9109c725ed3a750cf3ee39f3338ebf658da128dc799bb1846cba4e4ed6481ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080ac3e2223c56dd5023776f306015a4437569bc21e64f4d4660f244188ce7114bd93ad4c054ce8c508bd6e9bfe75154000000000000000000000000000000000753deb5fdb6ccef5d503fcfa0cd8970ffecb85178aa104581231c26e6b1231d21e4c405fbdff1ac71f75f382f0e3f910000000000000000000000000000000005b31ac04ef418659b5c731e19334cfe4a79357db0eac49de306964d855e1f01e3ed208830aa9c51fa2143922e70934d000000000000000000000000000000000f0e51a992c5a3b3e0d00885224b3c0db8ccb9dd1fff3ff96e4832b06576ddc3b183170ed618d29b428e0a41aef7b3021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000edc2968c5e465ad9dd1e6603ef89e0621acbe64a4d480780d6e8b6b4d4bd6df6eebce7a410fac1dc4bee492ed2afac3000000000000000000000000000000000011f438422c6982811b06e9194090470de878fe605eaa6e6a550c7d4dfd084f5b854fcd1886d589732cf0b9c94c29f1000000000000000000000000000000001834b6000e3b60782a1b9ac42f2c8e5434f3dabd17e47f7273d9ed59e97a980430a62bc686d4fda780bf620dbd8618aa000000000000000000000000000000000182ca9b3256b705d1f55e3c9d318bbdca10e6a220d858689d185ed499e40626ee2a1cc0c3683572fc8c614b01bc00331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf42df84fe1849fcbb748946839eeee5bc832a6fdb3226125321218aab7ac67b4a149aa826c7bc879390e6fd116df55000000000000000000000000000000001517f9434b1c8614c5bd1c19982a652eae0c97ed865b1bca6a66fb62da01fb34908f9f167533ea59fa51ed25a2ae12af000000000000000000000000000000000603640cde6791ed619f152a2e3152442132b6bfab93b08e7df79c8aefb2af9250cdbd5c27d54052b7296ed9b0db10ef0000000000000000000000000000000009f90ebc9e335e266ae53f7f857d228d07675ca1617ad96869b9ea1e5ce9d7e28d27c72c02cab868812be61d6c519ead1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4dbd1ca6a1b59bf797cc715bc9916bf234cf00255d2b7329cc9f69ee6f7fcdea0f00d02bc710cab9687b0b169fbe15000000000000000000000000000000000c6e677e94f191a9768f220e900cb01c5024330b62e2e483c30618513762462176012cb8fff1ac235ea520883735d9570000000000000000000000000000000001667eef259b8fa9367a8dff793a922378313c26912dcf4510f00bff8d551b0c4d83a29522ee86ca4f58040ce969d9eb0000000000000000000000000000000018839d4765e380e66d7e4419161434fd34dc3fb5286fb28451f234b70d7e75b32f2cb509865a9bd76c6667ab504646ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000673f4ff25fb2b482426469ca4b83bb5e6f3db3d116daedaedbfdf6eb1016d4e83eb46fc50cc815f5f1b39e188ee215a0000000000000000000000000000000017da33eb99da88916b42d20ec280ac482b24cbc81bb8ca9acdf1943d7ab7e3393cd396a0303e23aa37a3f42aa9de47ec00000000000000000000000000000000058b58103c7fb9beab8d6e1d87fc4afbc171d3f65fc41c0596c7399796115e3e17f795117bcee8fdd0d0db6c83d6ce590000000000000000000000000000000006d9311b2628195c4a032e976db91d3921e0171dde1fc455faac598e0d9396cc9f02d4cc6ca0a976b934b2c45190f4721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001626a6e4ef0b345fed8fd06564df66890990690964f3f64f2fb26c11d8aba05e3a81e6b3f5f331ed3269fd87ccb957df00000000000000000000000000000000192f4fb06bbc52675c2bebc3628c97cf4568a74d71a80eabccbacc138d0523f348d97e411dcc665edd2c0cd66fb7cd9a000000000000000000000000000000000648884fc143d1f9db240e51f1cd57d4949690fa939b335aa1b61fdd9c6d88f8c6f8a4ab2d821c91c974d0317c9ba9960000000000000000000000000000000000be2344a007a4bfe708d037757e791324fc7f6d6e08e7f8403203f6dc20ee271f7b2a14a80aa7a4a6033b98cf7837741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013eac23c29960784fe978aaa687772a21c01a91979b5790947b875d6801e07c54f54a49273a75cf807b4e717a7d9c2fb0000000000000000000000000000000007325e10d81093d530b6918eefa8cb455346d02cb104185e3b7d114b2ee1e25ce634653e3bc5c23f99d2f9b9d6a091dc000000000000000000000000000000000f63d667d5ce455c517535efcafab8c39aaa3c11c9b18aaa6d4265916ce805e5c1f6765a8b22093788a6a41edbdfb8680000000000000000000000000000000016508f06b512677cfce2e9372e1ecb04cd82a13f3b35e8a01c052ba1571e56688d7b9bc0d5717eddeb1c6cd680276bfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1c4bec52ac613f60844a9cb72880dc11144edf1c728679a4ad0e013dbe0c02e731fc7d64b4716716604983285b955a0000000000000000000000000000000011e88d8a77fdedd2400896c1a6c435748091cfbc51a7c0d69a2b81dd1ea41d5d7129147ea407e1394a1fc9fdac4edbfa0000000000000000000000000000000016ef1b1492f2396e0e5eedcadee07325ddf725c26b4acd46ae872f4e1a9f79f0762e587b5a64409bf29446b3ffaab01e0000000000000000000000000000000018a952ed206bdc5a50e5ebdac082d2599f6b1d3b9b92d5afa54ba6e16b51021eb254b98f1ae6a24db9d55cd89cccb65b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001596bdc0f74a54fe803b986b32d91adc15ba757f56a728e2307c1ccf6a1baa646cdf912a48ce16be39a3dcfcbbf9812300000000000000000000000000000000095a1957d04b344839fe3524ca5f66b3012d03623e9c2f625dc6a94be197fc262a627dc0b77f1525817f5cb7ee3257a8000000000000000000000000000000000b09ab600f78429dfd35753f37cec7cfc3d9bd266a01e71ce3f7ec4cf2b0ac7029f29a21a2b6c61ddd0fe62439cebd5a0000000000000000000000000000000015c70627b160251f895f192779cc8738c390d7fe9ee899716547cf0420a832e75715e6408977005510a26dbf394ab95e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff3b12035e7918ab07539a7095c8bc4dff7754c706201ceaee303d13c0563a15d0a0f2747355c86e3b506a8988a6cbd00000000000000000000000000000000107a0765bdba2ad4bc1de7ddbe8b463358bf9180d76dd46b4005ca22a5cd031bf0bd2e3d7ca843d1265b32e303835be6000000000000000000000000000000000663baf7649adc729dda22d3810596c97dd1c35a22cb1fc436da13e0d7f36d0dcf3737a5779d7fc8c5ce2fdebba8630000000000000000000000000000000000019450d43e61a2c9c6a37cd4866afb20cfdb0cc520f6f6b12d7fc207b1319d4e4b60e0861147bb8b7e88c637ffe705181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b36a968f5bc41ad634c637a79e59039391e9590f6c92b20d4d492e883b783650d362eb4fb525b3932d4af12f9faaf300000000000000000000000000000000186d970f4268f9cab04326b00ea495416645b4d2dcc7b81939f33eec046b64506032739e6d86cb9dd2c70b0b28d8cec60000000000000000000000000000000001af7ef21c0dd79420e1b0c100f09484eeefb99daa4d3d4fd7cb3eaf41f1b1913a43f9bed22a7bf7c67e446709ed914a0000000000000000000000000000000002aa0a78624084204ead60fe307775a57c99212adde1747732c89a1d1f8d950bf78a2ae5dfd9f2be9c8c498d22c727471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b40e159d00ef05e7a516d06dfa3e2548867cc5b33595a7b4d9d4faa0a0f1986b4f73bf1996fcc91eda2af1418ae1b700000000000000000000000000000000084ef0039a12dc2b25b119ec5a24de11bced99a407e418f05a762bd6eeb2a37bbe403a02e277719b92fae19e57932e2f000000000000000000000000000000001790009bbba5c2d81d84037341452ced7ee5656763d1bf677a9a89e80fe3ef641eaec4df62ac7fe6cfc7cfab8ef438690000000000000000000000000000000017897e305c70487ec991202f9d6927257292dca4a99ad9845fb5c30fe9c0c08ccffea99d9015ca86877f5ecd4c53e7381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6ad87103dd219cf3858d66f22ff36fe9b1527330de1a6f4e055ad141df4b8e91ac5e509f63a73b11c7141296dfb01400000000000000000000000000000000013e9e162c38eb166ad82ca7ce5669ebced416e9217b9fdb3b11420d8fc65ecf947750754ac89449ad042ef6f091d7a8000000000000000000000000000000001584660a054e014a22ed8ecf959a760e5c71884b903d40d105153f212d4d18248cbd27f2963e97152af3ec713669935d00000000000000000000000000000000158951e10fa0b55ac24df62261912b87d70568fdbf7af3f4ac35270aaa653c6117ad081dafe34838e99de1fcc3cd648e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae1cd835fb836b1d20fd6e191e0ca3e721bcfc76e783a125f9eb8e191854eab77a5df6bde3a8739778953d2c7ef79f6000000000000000000000000000000000de30670a1ef79737dd98631aec3c7bf10c93f1ec852d09b86504fe9849572ea0b7d36ce2eb998fc338bb819c5b5a946000000000000000000000000000000000a8185e739ddb9a6be17b69702ed7ec63fec7383ae609a8033ac935df77c570cf6e6bc270e740168ea011f41a4f618230000000000000000000000000000000000c0c6fee5bf17d748ba7c6100c55bcba2c0360dcae8618820bb21c60add795af981df3ddf31b4681f8033a87c3487531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c6b0d5645fe1637f9cb1c37eff25b2b58aa98a4c8eaffc679bffc7b47bdd4c9b7c42846de7e71f58b14dbfbb3d30ab0000000000000000000000000000000006d290c3b636159a3b2f0a603f5d516d4dacd6b2416b5b06537cd9dd82d95c9dc1cbd354b4a3bc98633db46766d5216d0000000000000000000000000000000014ea73e8d3071f7e6037f18e818891da140e0c812c5354af220653a5a5f7c86df5ed38b049bb65828d100a6ca2efb4520000000000000000000000000000000006cdbdfe780167f83335774e7aa4c07f8691d1b303ed32dcd6e7f2572eb7ad51b555cace7321b1344317921f9023e4a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024a8f3cc11120a71d8a1be7b81758a7ba3420bf93d05273e678c7601523574aaa2a019034cb128536d5b3fcfb99603e000000000000000000000000000000001020d360f80d5832cbebc88c5758ddb1abcbc3be8ab24af389a104a60d67fedfa658f7223528cf2a8c8a2995c11faa0c000000000000000000000000000000001229decc46e3e1d3752f13af576a7c864216fbdf5c330f603f78d8792a3c38bab42c7a1099a41e608ba54b17584ac2fb000000000000000000000000000000000b210ded3b6818b06d6ac8d2607d2d8abe2f8948d8b82f82648f8d9c5e097e06864825a6a368d9fe96b4fe2df03cc3351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171c7f718e6114701f2b7a11d4f3440c22799ed210cb725da864ad8d435584146a982f71ea5f2dd761d1c0e326f1cd5b00000000000000000000000000000000074c4eb5e88651c25eeb1e0a6959cb5773281cb43ce2012314315b754e359c96c454c28821d51f00eb8e0ec33e213c2d000000000000000000000000000000000b98d81e5b4ea53e613ae0c4a21f9d033caec152776c7f8c2a214b12588541122939b24b115422294541a9214d4619040000000000000000000000000000000019ac99459d70817febd9159a8734f58963473c4b12b132fb2e1c7a3b2e1ce6f13abbacee4ad513e6d1b0dee70da17a611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016674e3e544ce80f249fffa54f104487f01303683ad4c213db73e1dc4452499e338eabdf66eb72641ac8a24b96155d26000000000000000000000000000000001483bb945661c9d57f62915312650015607075075b3335a744e6ba005ac9fd0c5846a89bf375d657054bd25210e6e58700000000000000000000000000000000131843d43d526c1ffa234ba01e6f67902490a73578f69bec299c8252e1505f6efed28cb775488a48c38bf63e4161990a00000000000000000000000000000000141cfef8f8654c2dc7040676b24c8722f52f429bedaf5c945d71d661bad6671a35e61b2cfb43a8199d4071d25744f3cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000663983693bbddd104a0b5ce420c872f3669ac9924dc28b25e2ebd0b09b8d9abecb4ce3a7454a5a359ba9feb68c82c8400000000000000000000000000000000015df74dc571319baf292b5c5ce44ea7140c90a5349ef3a17f06aaa3e2eca84f68ffbb0966c795a1c3256b3f97b4f9d8000000000000000000000000000000000bff4764b1b12ea3b47c20cb12fa6dc84184f5601bf37ede172c901a278aab456440a42191d8887d63d46136216b88530000000000000000000000000000000016d9aadb0c95e8162b3edbd5033db4a8757d66210f5fe9bdcd332770047627200ae1c87f45e7fdda1bbf252c34c751851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002991d4ff88e5dcc8a3da5b612ff8e67677529e44af8d921399201f356ce305097d11f62c427e455124bf4b3fb406d57000000000000000000000000000000000547a3b000e0038c69902bcb4185331be5512f7c3dc1d1b03b2e7a967cd37b2b6253421a422a874b96f11561aa9e9d4b0000000000000000000000000000000009332033579e17c5af88af7ff4bbf14008a7845f0831a4e33e565b06ad0cd562866bc0c8e80b9578de45522fe67df4790000000000000000000000000000000009845f21657806f7b3fbbe058375d8ef9c41247e6ea1ee6c0dad2bf0281e77ea5aae7df9bf29d362a384d674ec8fdfeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee973406dc581b232e02ddb24ccc01a284ef1a2350d324f6262f695bd8a0f48b2a1a1622e1e1e72d71e2c2bf62e808e000000000000000000000000000000000fbd8963f89e9bff2f3c1e626b48713258cc855140c1beb5a444585fad5142b3415b803e1f82975a47a0ab15c3d0928200000000000000000000000000000000077204a3376a937906764d1ab8290ba929fb020591bad0c926d0d8c0aee556b4b57f8ae30202f778cafe100e0f658b6d00000000000000000000000000000000066d43af5cba695f03bcd6bbe8e6f903e7d59a5e71bd0b97737bb75629dee3a709fac383ae45fcbcfcc35ff0e31ca22b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007c0eac8579c428bcc340acc15a0c520bf246c1c3e9cef2b9d4ceaf013643646251815a1e8f1a13a7d1aaa455c039b50000000000000000000000000000000005810a33300c8b7ecb77e5c52e0c40966c5167aefe3edafaf27dcb4ca5e0a7574b1e5359a046eaeaf00d4431a014ea930000000000000000000000000000000003fd8d60a61347ab3a52170994689df4a74692760461dff954f004697e377503b05766d756f1a24d9774de6db2d2cdcf000000000000000000000000000000001551c5c08c2a047f835a6482950fb31b93db8e0d89373dd2d206cf42dd421b4f0593b9421bc0cc1375ee67d1a3d5c15b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017db90497a8fee22fb0118f674aeb19148981276e2ddaa0391d31f7c9100808c491ea1cae6cc3f7876c75de6f88d7d900000000000000000000000000000000052b1c086e15d5aeb19f4cb9d701686e81b3dd8878bc3e15612c9ef17da3a2d820ec08efc3a0793e320028f11785e1fe0000000000000000000000000000000016131ad203c90e6e92b4580598cd42e2a8aeb8a3a48e3c89f71b37fed674a6235feff9a6b30836f3030411a2579519ac0000000000000000000000000000000013c2377612c9ee77ae26fe113b7932b79d62eec82ffc19a14a06c3f4622ee1aa5c394b529fcfe99152d6dbf148f415de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea0581916c62da7b0efea831ca102098e92dbc02ddfe38cd4244a151c60160f7bf60771cba4bddd4f6f0a851c5ed5f8000000000000000000000000000000000f0fe9a7f3487e60c776ba375e074425968ae1503ea5fd926d0514432e3b0d04105de98c9181d7660df4d6001924f769000000000000000000000000000000000a518de68b5d47f69165b861d2901c44c0963deb85d0fe84dc582be77422cbd4884113cdb9eb4eea52ab95d8c28d38c40000000000000000000000000000000008f0a654c24ed18b75851895722bf6f127d61c232093ad49e16908c9e0487e8c0f3b4c74b9a85cac5ab2a69bdc8899251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000137319b086088dc00207556410c9870a3aa9c0990c25b473170c1ec46e9f19b718bde81adadddc44d7f13ac0488fec0000000000000000000000000000000000a5baeca2e97b95f561a89ca9313825542610726465565d039a7e004241607a638c47fea035aa39a92254a4b2a47f5130000000000000000000000000000000013bc66a11b569689345bd17316d8a0e4d01f6aa9ec28d73bbc4f51d2d05d771e3c722c0ca782f8b22d39cc06eb8b86c20000000000000000000000000000000009c10117bb32e7feb8d17ce58d33cb74c4c2ce2601caffe24d1d74969c2749c2ed95063e785962e331047ca1bb9bd6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9dd59209c5f7cc27a789d47c7381354afcaa30ae6c066cbbf7538b9600a32c94d19f28d36bdc4abb6b54ba575605e0000000000000000000000000000000000e299453866df6adc6dacc2a334bc944fcee3d6b6f62c9d5a1138589bfd60529623f943f318148420b7788ec912c873a00000000000000000000000000000000189d491e56da3f799f409815988e282b342f42db6ec4d594b40bbaaa144ac008234d664d2c458be840393832fb1d785400000000000000000000000000000000105341369d7dca64970fe9801bca580041421521f38064d6ade2846e1569ec96c6f4e89db9b32cfae29b4834f9145efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de0b6626a2d05ee2b9a7852f9dc6beb1cd7f13a024b542cd6fcd01cda938b0cd80dac458b2c7c4590e80592a02760fb000000000000000000000000000000001171ba982883c95c49bacb8517c1a74bc3b887454e3a07c981f94aabb040dbff89b108a8ce2b8f95327e655be3ce822c0000000000000000000000000000000019d0021d984f4d1089ac5f3e146d69c4122f1c721a15b705e434ebefce3637bf80599a8060a967b8d0a552f4f0cd7d6200000000000000000000000000000000090a63ccb5d8eaf564c66c60d89f4c4f04171a36d80c449e5c4b9352c56480d55caeb3e3e3d657c60332fc095af65a7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014026585d15143719a66cdac1abd41fed49bfa1f57af5213a863f05a38541c591a675a4c70fa9a734bedab87e61110580000000000000000000000000000000006e94359d2d9fe706639c87e7fe357c28b795566d5a6d34802b6d67b9c5425e3852587d79ff096a9cef6b220748ee6cc000000000000000000000000000000000e732efe55cd01508e48d62d1115cc4b08eba81da9b80a3e51950c62411330d5e209bbfdd3155593431a98b1550aec1300000000000000000000000000000000023c7a805c284b4da5ffc03a8e2548354b4410a95662056255874c34d43df3738277382782ccb18e3b758bf6805bad2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037864e3243d6339da3bcfc5727b2b62f6b058dd4a60ac852a3dc3e23b374f9be8e7d6d36335cb23eab4a734a90328cf0000000000000000000000000000000002f8dd46f8740f1ef2180a6008383e4375205f0bae3131f899e97db31b3a89fbae51a797a7dab4a86d0466ec0b1a89e70000000000000000000000000000000015ff95d0320c39ab2531ec0a3ad1b62037ad05957e1b2682eef2cf314ea11fca435c4db084f4066ad99eba719bce762d0000000000000000000000000000000003c8d4dd2360a3a994b8cb7910f47c7e6589bbb466b1762312cb59b1f2ce21c6ae15a09dcf79a8eb376c40cf669cf7bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ef8979cd77124c9d200dd32cea1a5135e5926e92c8ff90ca5a2a3450429ff761b6c5a53bdd5db8eb4cbe0953e7184b0000000000000000000000000000000010c52bcbbcfdc032fba992ce7774640efa94e0a54fee0b99cf9a58664092da94decdfe001d9af89bc18fbea0e1a9153a00000000000000000000000000000000022c240aa672cc3ec13d6d5602d98a36c1c20841a1eb927e2656429fa8dc8af7057e578708bf12ccac5e764b8f5f75e100000000000000000000000000000000044e8e9765e97d5c2e095c61257d8feb3d93553dd81a9e68a5d07949f5404c10c5a45c20338e1b78e64da0279a11bad71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f838227d011430e8910af9c92e59575581a1d34ec13c8af8471a8615f90b98f30520d630a3186da05a2c9df888b28bc0000000000000000000000000000000007bae9130dfb0d74e596e0f76074b114fb178e98e0ce5ba51ac4997684a068530e629a0665d291c92ea99fe29f60935d000000000000000000000000000000000b553caa1d3ef68096226385370ee4ad5c740086ffa3e14095d03785969fb54a4d34e217657d921e9b99985451b751450000000000000000000000000000000009ef0ae1a7a3ba35c27b0433057d39e91a37a86f8ac9a528c9692748b5bc9fd286b921829a224e50c070626006460d711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034eb2384107b8bca53812d6a061667fecbd25a96ca7b579a71a33acea69e6abc4f0bdcaff5a7c8b028633ea0bf6fbe30000000000000000000000000000000014585b64a280c39fc81a1aab94bf2ab6d89c2e6c883b174ed948be878a442c5914e0ff771865a1fe78cc2253f2cfbe5600000000000000000000000000000000029341146a0849b22b8b88ac9e029a7163176d7d3ce90365281fdaa56cbf5ac1f2ea42c26c29633798f27faa8b0c5d78000000000000000000000000000000001211b75613bac800e4388be3029b520562786925e379a06fe76ec4c615d1dbf25a7e221ea717640d11ebe52d4c6fe8c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069352e6bed45c60c8e201af87d5715dec3ffea9989e291faa1cdb849a3f51dcaf58f872b60319c69db9a4f75a3194e3000000000000000000000000000000000d96171c074d1039795985de56223820ded34425ab4a0b3f622001aa5b8372aa97bade946e80a579c3afc66937f12a61000000000000000000000000000000000d57fa895acb5faa49144c3d5c9ec5193e6a243b905d9a97c65a42a4d01a2ccbccc87695346ae0e275460eb2a41df8e2000000000000000000000000000000001797725e7fdf649d587c72bf4a08f8c96b52b0f3d57dd27160ea120ede9252998735c92b9b6aec0757a19bd1aba961a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd9abd6818f63f9f9a4623261f8adf87e2110058b6934b62c1cab026fb2072edc748efc494036090aaac55c8ee93eeb0000000000000000000000000000000012e78acdcbeaa0d996aff35367f2a81f03398a09ab14b6250c7f0c119d566b3a05887ef1d709ac7a56a2a0486e38ee22000000000000000000000000000000000fe14ca2f5b594450129d97900a680dc021cfcea0ce22037c8446209e40994a05fbe4aa312c589a008ef27470c7e2453000000000000000000000000000000000b997224e72a651a8b8c4edadd8a6c2b8805087e0f30e1f170686ad5937129db47840232a4f4b7de92c0dd3b7c6937901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e37e8a1962fcf0d02112a21666bdf1fb5c047bf2571714159717d693cb5b6d9cbca40d91100410aca6bc20c4719cef0000000000000000000000000000000001ce0d6374d0d265edb6a731cb98e4e0729d21d6ac5d34404a9e1b761eaf8ed1f567fad3e67cdac197c9a2812296d6a90000000000000000000000000000000004432341d99d0b52d58643f547211a427788722497a8b78dfdf1cf54e42d17e26b39f33834fa9466ae1e9ee0a337f5010000000000000000000000000000000006388f558d15244f910ab1d23b1894eba3182fd2588a2c792d530431da4df31389c0e3b4080284f075ccbb34bd1c8a651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112250d2f8aef73c7f90f94404af5cd8b335f75caaa1ad7981d93cc065d4f7f3020986e8a59735a0a8773d255c93aa0f0000000000000000000000000000000002100ce50ad29ee217a9d9bafd5dc4bc5c8919b50dd1c01f005339fd1734a39a8ec77542deb5153120ee044cb7114874000000000000000000000000000000000e19f5ce9e9279d7ad05061cce03b47a502a036f81e2d228611a26ff25da7e9ea47203cce5a3c1f16a45d2a96c20add3000000000000000000000000000000000418fe7a1ce837291072f043d6fc63407c0ae0bef0ece6d100e5a90cb10d1a2be1dcfcd90f332c61a28a238907ed24741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e30fd14206f5b6771818deec255780c9b255d079f43d1adca5654019bf53b98f367d07bd9786580ab52c482cc60bd600000000000000000000000000000000098b450b9d1748fe62cea279fd36e830367ae22760f53b8a8a70a26ca6dc4d4c853bbce7997eb240a1c8b37c0bbcaf4f00000000000000000000000000000000152ca0c0f25a88750ad59b07a8af8f394293ff7bec218b784cf2082c3e507bfe65dfdea28ee6dcdd570138e6dd6d8a27000000000000000000000000000000000b044765d7339c0e7e915585e9a29d21ce4866267cbe81261786f8bd4bb0f92cf625dfe1522f849aae215ef3ea67fc221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000036a95be13aa6bf481f2b887440763237fa52026f9710b0847e0787db4e0e452d5f8edb0c1e891d1d3f22b09550863200000000000000000000000000000000165ad369a4b9d1884f1361a96832404021783e8cd01c629462c91b342721bdd5f78d9d8ab395a2d20e23d827fce5306b000000000000000000000000000000000fb0278d086895488935464da4958a87b1409d0adbf6b70440e2896e0d848f783d2760bad64e505196521063f25facdd000000000000000000000000000000000d700621ce274a301b022b0054a95e07f94c4624c2c6ab4fe787608bcc8d285bd102b42caeb26c5efb6e182d191cab3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060a719d92873d4559f91786d235a11c5c9555a10fca4dbcabc5390484c892e7a36307ac9dc4e5ac2c3832f028ba23a00000000000000000000000000000000013d318a9a73d487ab956436611b853c2d2a37a9b47265b8ffa5c0ff61c114919b405d7ee186a51e1cb72e90d59225bde00000000000000000000000000000000176b5f52b45c3790ba81a55641a585322f38a3b6b382bd2fff844079f16a8b85d0e55967916de253cf7124ae6813478a000000000000000000000000000000000ba59d5f9d5583bff1f545454fb3e8d8d7f51c409566cb34e03c8f9523ef5114a1c2470f93292f29a81f403e67435f531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e356ccba886651e0551493cfe83d83f9ced0c818c6bb36e5775aecbc7f4a6f774b3fbcf005e13d66798db3e1e47bc21000000000000000000000000000000000f3fa355acedbf4bc5eaa555f3550a8bc88f081e00bc868976b7f3245e3241621f5a80f6a673a00b552859c341f030490000000000000000000000000000000007c542aeaeffa48629ca01c2f804f3d5aab46498d2d9355dea04060a06ee2e3999fa26563b80cd158cacfd439e5afe2200000000000000000000000000000000112aacd15490a9aa6b223bd3ccf39ff1fbb95e3e2141aa3110c508766817616f15174d358e41177c1d2eeec2cccf2efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dde5936af03a239f90b09583b58126df16ddec8398a9f92a70dfc96930041e4c9932f636bda0c150000ce12eee6d340000000000000000000000000000000010c2e9ddf62fb4a6c5193b95bf83389d48801e838d017697566c74cc570b6f49e0088a7c07e8e9c8518137db572d814c000000000000000000000000000000001710029c0a63921bbd7e84854fc55919dadf4951dd83791fe9579672bf85c885a545f4a72646dcbb96f40216850c33ed0000000000000000000000000000000006ae2a0a0de586aa6b6d4792c29c2d5dfac28f532084105c497418dd684119a15c2e9d12b9e9d831f23ab7ea40aa94571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e153d7ac9d57a2054b9d68d824d54935c4bc8384a2ae8f2f44b71f2252608539097bfe7ffe0ed1c99f54809c73d0240000000000000000000000000000000017670f813b6589cfd24a1f3b5cac66c4065bd9e18e334cb4ba90216a31381a7c91133608a9e9a853190a5e1f267bdca0000000000000000000000000000000000cb3aedbf574b480d4c5c623c9c303076961c848c128a0d1260ab06a05c9fc84d968e94bf531b837dac766cff3ba6fcf0000000000000000000000000000000016f465087b927ab1fbc557154f5e785542f08f16ac614a47cfa9ce3a18de62358ad7b410590bef069e605cad87e490961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003699d395733bd61e2546f5314cdfe7fb8f2716c2a19c6333b875bca03c98324b4203655c1b6df3275d76beeef59035100000000000000000000000000000000068a43b91a3aa42af7980e51eccbd85bf1fd22b37ca9efcffd3acac62ace0854107567638e120213e89c99b5faca19fe0000000000000000000000000000000005bc9a4edfd56dac254cfd76bff4fa36a589aa3f1a879976999078175882f5781b4ec596c080dbcd79a4db507d01676a000000000000000000000000000000000543ef09229b5d7daa99c7a191e5847d530d6f9806570eb031a86c48fb37c360df2eea17b6f3b0faccf88228e90cd35b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fc451fc06132e6f2be9a4f6831b1a3ec17c39e5f9433cfe1b16f376d200c06b5c2c4d4eaa520ba892b28e8805dcd5200000000000000000000000000000000012af42e1fae6850c0b8a34542a914f151d59028de32fc8f593ab4399cdbbe70816969b78233861bcad080e33d56021b0000000000000000000000000000000014a64566665979313aba10cead1bd0f55a7c871a0c9a4184d56d28ecf05597e956f4a3da52ae36261151f33d3224da8f000000000000000000000000000000000bcbfaef9a59d14a67fc9aa7490a897acc087b8ef06f8f29ba8b74744ad7821d088b7ff135bcd6419fc685b5d19f43c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000999080b99dcf945fcd23bd1db3b4269800465b9bea3caca496ac7323304dd4f490b8d56847dfc24e9198a9863b479470000000000000000000000000000000018c39709cf0d94730f3bb0e391293b8031cefb7e1b7ef8d3bdca427210f480a9cb84db80fec0a1864d5ce3b76c19da520000000000000000000000000000000019175f2745d381c285e7bb7efe9c4a605a2e148c796660c9343da686d11bc5e2b62b50ae438d0dc8fbe34a29236adcc70000000000000000000000000000000004b449f730dcecb2c6fa2c964f6d8de70546506580e0916ca698fd8e19ec920e037ff4252fbac07f944fc6983038190c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001892c6be68fd605a592f219d3f80280917d4cedbccbd146c23efb3a8a71acbb78e5ae0aeb9054837249a3ba62a9e5b1e000000000000000000000000000000000d083f08561c3abad5f17bcd5307057b7f65b0ad248d9ffe6b2166a0cbda68cf0657811171d9e8e36ec7503aab0850a40000000000000000000000000000000002724edd9374e87bf13bee0afee2a79e9ce7e7146ce7d3a0cfcdd42a3446b62d44027bfc5ee7b532212af1782ead22c0000000000000000000000000000000000a74f0a0d679dc5b9164e41a1ce76b8b455cc96e0386efee40cc6375d2e8bae5afad2081fa52794ec3d2326472e8004e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e84e2004d4d0eec01dd71a137d210d0bafbec3850c458b98ad4fadabaf85652f80fd47835f8712212db05723c7d1b3000000000000000000000000000000000847ff35f58aa2d76c6185a8cf4ce21a35edf4e2a18fddec94043f0872f47fb661a305114ab9593980a9314afffc8aa30000000000000000000000000000000003610ce1dc87e416f665b629a3f4e979426645005a24acdf719fdc1e21fbb13c0117c1aa43d2782f613af0956cbcb5db0000000000000000000000000000000000075efaf745c0d382156a2f346119c40db8b16d89210e0552481902ab5ec3da708254a559387bfa262c467c0948c9041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055a55ef212af9b7a931cc9861c1a0a401fe34a3ac5b15c0ffdba249292d5047ac24c4d903eaad924054cc9916e240a900000000000000000000000000000000123c6f2bc2ae7a22a44826b16498333fa980d4644f5f5b6e1234aef2ba87886f70f1003dd19a5ab5289737430c9daa500000000000000000000000000000000015d755742c9dc5fbf03658f729e0c76ac4a2a7ebe715ad3de9216b99ffa7e0ab55f3bc70c14fff441f29439beba8c01f0000000000000000000000000000000010a0aab9ae64618f7715972dacae1fbef65afc26fa056264e0a77a6a070751d0e4285b5100641b2d5ba35341f9581c371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006aaf1eb1774dfe7fd6244c369b70be72772e83e861d3e7b3e486174a1976ac6d0cec7da0807c9d7c4e3e802775ffabc00000000000000000000000000000000117eb9c3494e23ecc147f22f91e88578cdde99b0255be8c490fe1c5b10813488fc88fa059f0957536817b8dc8a97462200000000000000000000000000000000004da6007f31527853841593d737b2a3135126ca70d229d53ba67bc0837c45aa07f787aa111d85aa90cf7338ca5e2ec00000000000000000000000000000000014a3fdd257a31cb26dfeab9e69b92ed7eeb45a3f88dcfe111b6607f3b8bc8a120998a2698467897bfd1aa1e14a59f5f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db90e94a8ac25e5e5b7d46400c578c1b8157d615e8e5f7c1fbadaf834f3f5803405f39f0c55ceca8b40134eb3ec736d0000000000000000000000000000000002a48fb6311bc682ee78b9b79addddb6339563d086976489bd55cd92125819f67033a8e4d7c76bd31987a6b0d208416a00000000000000000000000000000000087700c640bc9db46906be04caeafdc663111fe7eea167a3a9d1dab59e1bb0e018150d1dd0a9ba77d14419f92e6122c000000000000000000000000000000000198e9f2d7cd6d84f73592464240389fdf0414a8e17bd0cbc522b6968bb8462ef1f5fd673aa1a939f0695839c6014093d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49f6c2507386367ee39679c205842e6b3dd9844118038654b8d8d9939ac2e18893a3224de878fb048a7529001472c30000000000000000000000000000000004c572bcaacaca048d5512bd50f9cdda833e190db49909b595ece1ebac2c2ea74a385e8e0de575974c3586cd5d50faa2000000000000000000000000000000000c752eb08309a190000cff1e5cd6710cdd15025534ff8fafcea4a80476b904bbf4608a40d1ce0548a3151750f2b40bfa000000000000000000000000000000000b18d25ed1dcde57a7420692da140807079768c202af7aa185e91b597304aa1b60de620b382b7c02c74ccbe4bd41d3af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121bba2dce6e02380fbc6c77fa80203323289c719e30a11f913736d496e4dfddfb2e0f5ddc4d56a63fa8b8b46792e283000000000000000000000000000000000233223b9276480014498120031e9ebd475260cad0b2bfe86cdba9965bfe0267b870e8c9acfd7be572072e51d5cc2b23000000000000000000000000000000000bf57af59d2d0dfe08675b6d132f24b74f094024cc162c0c7a4bdbdcfa2a39f2415e39b4cc3de5803f3d8607858b535b0000000000000000000000000000000001004172ba68e2c986f2f988648515fdce0679cf2eac66962b31b1929d29e34954956a8dc385f2aed9245567ac52ed671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012474dd50283468810dbefb6ebfdbe34fa5a550a1c39b3990155b176d6e2ae99db78a149c13996d17d0e987cadb1534c00000000000000000000000000000000155e61116bcbbbbd02bb1c4b70abff06e76214be953db7e22a967ab573846ffd6090be688b28ad7fad4b193ee0149f630000000000000000000000000000000009265f830ce88016ff90e50021e4c3b68ff3a38ffcd566aaa8b515668f0c69b16cf6c2fc9ce00cdf3fe0ed15971112a300000000000000000000000000000000013a8be1851741ec6e3c11cadb2287d63e7fd5652e5d7e2d6510dcd1badf036462918cad4247b50c24c59a963222f8811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142be69d657cc54f8a08a0e6bf68030a8369cf84ba2e1127275d5df5f0a1520d532b5126e068ce5ffb4a025f7ce48dc6000000000000000000000000000000000b35abea80e1d5ea189bf2776cae54533d3e4cf521adad0342a3658b200b3033f8b02f4f4ef98a9435565c0f77f6befd0000000000000000000000000000000002ca8d5af9a5cd39fc83fb22def43a6acc7aaa6cb518bc94cbeb1f606d738859ecbc71eac72aa5e63c54eac5c2f5a6600000000000000000000000000000000003bdc3a4f0c7bf0a80008ccd90f183c27d24615e658ef9ccb58736e37bb8bc8011234200fb6dfbfcd78e283f95fa7b841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8567915c8615ce1ffe4e686063128b6df754165250b0ca0ab8f988afca5c4887edde4e8c3b76560149874f834f057c00000000000000000000000000000000185ecc17ff65406d306e845e634fbd47e9d14c819cf5e03d8f8d689e3b84423a36b620db73b4b86d44fe5a29b21af57800000000000000000000000000000000168d01cf433fa1b4a6b1aa9f5fc094257568ad8782b60e4cb7773a0a84420e08d73d9b7f1dde5a9ef1eee07be1d3a73400000000000000000000000000000000121ceb2b2a4e347296de32ab01cf56c6d6022696d7d896123574e99350849493fd9794532ad391ce4234cb7362ca7ee11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000664aca6737b5cbfcc7c417a9a72ee73624c0a1a9746dd4b610c2e2fd7454f45bf02187054b7655c2045f34395c881b7000000000000000000000000000000000c4287f903cd0d6da4b5405da626f9ea7b02cae24c4315478ef6bfeebb666829aea8416a721e013a46e97be6b73448fe000000000000000000000000000000000ebe121b457bae4f35690ab7948201787ed6640c1eb6b94f7832fdabed91fbba9d24429239528669f6fc4a98b27b2554000000000000000000000000000000001230618fe528e07b5159189cd14b3499f69abba5c5f2fb3e7984864284030f632bbabc6164e257f49c362278237f466c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cb1b7008f8ac267de74b57a3956b60f100fd23904288b908b8c7c402643271f46dd4b495f6a0d9b0153900f4e7636e000000000000000000000000000000000e1a3b1f5223a66de87c03b9db92f829a0130988e7da6fa6f16af0ec7d7e21fc521f1a5abefbc562a7233fd39ec015b30000000000000000000000000000000002c44b67fb1810182a3b7bb9ed724c81fe4d77364b93183e9a3eb1252fde901138d5c214fa779d7578b6381bb4fe0694000000000000000000000000000000001385220c4c642d2e9be54603f2172d51d3ba516db05d1e85a98b7382d1a9a8b512f140c1cbc777f0b0e7192e30bbc1ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a7146f5a2afcf4acd8b0a4b888452e920fb9d6fae64da31cbdcab803d2b3f86f53b9fa5a6f25d1de4848eee472de9d0000000000000000000000000000000015c7062ce2abc98384adc6d78eb5a31523352dc717fb933dafebdbd4b850a59fd008e1256fecf37044619185df9392d3000000000000000000000000000000001682065104919181ed8ffd2ab1b60be876760ffbb047fea1c34e0edabf035c47a4a15be0c5af4829d9502a346c4c96e20000000000000000000000000000000010d87c41226c61c47c0a09a67803d2bee457bf1e0c110a8f52b40430cd201d6281feefa07ca3cfff336363cf2cfdb9ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000939e145429ce755135aad7a3f7e5dfba0cfe204d87cd8aaefa295560e5529319fd033dd07db2a783d8e9047cfac55410000000000000000000000000000000012e743a38a939caeec7941acba1fd0d18982dd2217906b9029dee933f3b55d44c85b49ce8279c58742b0b3b3e631bf560000000000000000000000000000000013c3b3ebf45fc33ccf37dbc3e88f8bcda87c1eec33dcdb2115640a7398114993a3979d0ca883f96345fc844054bb34e50000000000000000000000000000000008c378d2a8566e416cfd98edda6f73ee8f847c647c8c459878411d564c825d330f725cf36a3de497b7e05249abc8e7291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc651734d4db0303a9e6878182c17da646ebceda8b43366a74113ba1aef62f38d0988739c7351624030e7e8c891ac3700000000000000000000000000000000115de0caea2b1d3a168d4b1e89343f5db4bc74da8d138400f3f4fc432c7f732ee089593a192b9f56d5fe2d15b89b727300000000000000000000000000000000016fae4f4134937e909747adcbcb9ff0dad282fa4fe32f87a019cd3bcb9c6b266277cb858aa5aeb9230cdcec4250bb45000000000000000000000000000000000dc45d58ce36d265f110d866af1f4e13cda3c9076c8cc8648cd40738385be64beb680feaf6e3158edae87e19a7e96f311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5d0c277b597f86c5a0e2fb0b3da8386f409d1935f3e2b5a2e4d030fa12247c7d33459e4f8641780aac84c75b96f58e00000000000000000000000000000000006b9e66cfc126e4da7f39093ecd1591af77cdae13131d044eaea775528ca2ca7e64065c375edbae365f5c6fdbdfc055000000000000000000000000000000000233cae1335c93c5727f63ebc33d488d39d5a172df4a7f565b72e71db5eeefd6468746b969fa3895daef15c04c9de4150000000000000000000000000000000009fd9c975726c3c99ec00adc91124a93bc886dda37140eca2b492ae640f80e9197548f748a3ceead795446ff21933dac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f7942ca574d94fb5be40ea228e52a4a01f657fc09e8b6a7d42ec700b0fee7844662f330fbfcc31e9f2ee7dd7aceef700000000000000000000000000000000090967de755f84727dac7b24e04095690dcf52783e5784ad1419e7c2041a20ef1d97cac3fbd39f87a588cd6da216f6ea0000000000000000000000000000000001b3c4ff74aa157004dd3dfe52a7828825579098b77e5bf57bab7df8158303ccc7d505773014e54e574d1ded3b038cf10000000000000000000000000000000015b567e838e4fb2140642f3d22df90b384364eeb7db835725c03bb1d8ab0cfb84bdc0de9e0598c8a91c40187aca5366b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001027d35a2a426ef27e5e755e8d3288cdc33a62e6e7e614cdd8cce0e4cb8995966a9bf06d649701e500d683fd25e19d0000000000000000000000000000000000ed67981993e50e897d5f8a6de7f9870ffe508958ec2e1b6606139d478253fe5a5013deaba8a11678fa91d03d29257cd0000000000000000000000000000000017648aea20f16940557f5420a688e547696e58a6c4cbd665c6666886eedaad7f9e6db67f16722d3bcf8d261a197295e700000000000000000000000000000000080cf4d4eeef4eb7f36d3cf312b4ae33c4182ae0314d4a4bf0c76e1a6db03faeb3c4682c8cf6758a2fe635b9aeda6cb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000736cad24713b435111346b91659de945ae352904cf3bc5e4e8cf2b58b0c33a447c48455df9a9b76d0de8926d693f1e7000000000000000000000000000000000bb1e1f0eeabe97ea3fb96c1719585dd63343ac84518823e14423717ac8ed123423e8655085704a02d08b885aaa2f6940000000000000000000000000000000012291e706597cf8c33f09830e757498363532bdc3a479f0788ff8a5626da24c195662f8162079520f22727386e3f71fa000000000000000000000000000000000bd16d235d99633dd4519e8797e9d26f3e8d3912123d2cfdec3527ea56b1675d7c5592191448a0f1ab2019776e370ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123bab130acec842184f52a8485f83edc8e89d6982df2eb4dc5fdf8239ad41d795946c5b10e431698ae2a9ac53153397000000000000000000000000000000000abc22fa93032d6a2feca0b84e2a875d6a88e695de41b8ff1c65c76d9eb78c2b5590bf891d0b45e5f887e72032add5b600000000000000000000000000000000164d4bed37ff4aac1540e7a11b3d7673567cfc8431c9123417c7f8fa276083136771eecde7f896c18bfdaebbc004238900000000000000000000000000000000168cf6222f7dcfadecfeab5ce2d4a6503fe77e65718b39ae8ab02e2f75138419be60775ed908c07772411c1dc818d8ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bc952dcd24b9c4e1006e3a3e8ceddf5fd1ff7ffd9c6af89753866250c9882c5fc1c0b9ad69012b4ca6b5e7f593d9400000000000000000000000000000000019fcbb31695d18eb5a64dfe2c3ba575da2cf2393f3d6e66ec201bf5c7e904b9f70a25e470ba16f1439850bdd173a3aaf0000000000000000000000000000000015f534d3a7331e1ae6d34f13a87e0bba435d6a674c56221220de63b428fec59649d5c6247963b7bc3583efdd04a17b3000000000000000000000000000000000118f2c13700ea22ffc79fd7630c933496e02fc61dd4465b549bc7ba2a21d02b2c08bc37e12eacb6da94126beac48f0961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180ef9a99379b6263c44129c177f19260a976ac05ab80227b0bac04adbe82f968afe56e39366695cb457c687e122e62b00000000000000000000000000000000054d15fa41a774bf1c99e1acfbd9508bfb8f44b155b513b871b519a70e535977405717a894af1c365cf95bd14ef09bad000000000000000000000000000000000ba5b049fb05eee77bd071d6da31a87a3871ce21f4c2762896a2990384466fde12f820f464c5d009b4617ef4ea04ec3b00000000000000000000000000000000161bae716290446d85e89675d04c68555fecd0cfb977d6fda4a9d5d61e15a520fc333b52988e98893a8155a7780eda761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b8e934e84219047d9a620f5e9632d1193ebaa7d68194d80944ce9e100b9baadc8001572d8a28e1dcb0f450527a2e890000000000000000000000000000000003bc0baacc0e11cc545fe0bc5d7a6c8827f6d2f5594310132badf2aafd0d19d6bb6b9b24d52976c81ce182ee1e59a319000000000000000000000000000000000208bd3f0e94480070900df3951f8d95a759ae7b569c1aa9c1755abeda37ddc567ba94a9bf45c7e9822e3b8ff907843d00000000000000000000000000000000098aad8960ab71bfb8619a8c4474f1ae28a48c97e9c614e0888be6c84555cbe0c030f363b55144fa4c3bf6c16e16e7ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000510699e9cb214b57dd894d926506d76f760362df745356cde004a1241221c3c5f954306e18869cc020cc1078320ece2000000000000000000000000000000000fff4f28847d8aa4e965b6670645e5668360dc1dce32fd122712f308a70de0936fdbb7e455f3b24cd0213f9b47b01ada000000000000000000000000000000000b51490480457f89dadffe19b0c03e48ebcc20f84c027166ecaf2ce09de183efc0628479068e2f3fa929fe21fedccd6800000000000000000000000000000000067fe13f7da4d53bd158199af2981760771aa311eae69e8870030a7aba4a38517f1443d2780af9088bda0533ca74da161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e45d4ebf9f9b7aac97334a4b8782f522909e05c9ee7588503c64ee3774c40f53a91f27a39a2fb7e28b58b9d133cc8b000000000000000000000000000000000083d2c1af7b5c4190ced6fb566e85e33b274cea7ab3c7fbf4331b46d09be788c696ae1af1aaf050d91044c47fcd177e0000000000000000000000000000000018d806607a6abe8b31bd96b0a34dfff83e66a9d73d788f0cebb16a6cea1f8a451b2bd30a88e648c7ea00ee5de1f2753b00000000000000000000000000000000102b23d5d708d17b4fe8e0868b09ad9b7b37295cc2e14b1c6ee4b5c4ab4af33b0f99ca4d87de38385f35f6630b7ee81b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ec23e9c4baf84b672be2ecd4db60572da83a3d4d452343e6043921a6ed6ec93fa2d6819945606c086ba9ee03998eff00000000000000000000000000000000079177a1fe610e33cf8e37512f71d8bd80ef53b1500889b50773334b3fc5a61417136c5a4fcaab405cbb1bd7c8fb30650000000000000000000000000000000012047c7219f9af5f30e68abddbbce22e6579f2074512d796231bd5dd9e058b0bc16ab7c4162b1f97300455bf6884d8d2000000000000000000000000000000000319ce6412427e20d85c6e36c365e1405ba8fdb689d550fddbe17d3e8dfd900e76182a6cd02617f7edcab84e4bcd67e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9a6a548753c33dcedf77875a0e8835a41c1162d1907d59ccc32b85975c6c1a817fd6315727f21f9175fddec0ee28b000000000000000000000000000000000062a50907dfd0b1d441d4fc73244605e2570483afb608d1632c80fc30144e4709c2d55f9f647e9b09f7b0a3e5f5bf23600000000000000000000000000000000168ffa81b1ab744e941f04f446e9a7b29e499c8dd0d587afcd2c1443a28fe2ee42eff13d00096f2febfb556fb758126f00000000000000000000000000000000189d3ebd84691e001d40fe2fdbf35f7906ff43d5038528eb907e2feb1720fe39a9e37b83a896e50d085e1a4bc4fb954c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008258d5ad6292657fb5f7c661bc61dab6b59abb466f85317fd1b765bfcb2f95c5edb728beabe8ceeb702a690765819100000000000000000000000000000000011c735ca7c5042ef18faee3d4b26886741f25d957e3426b29c706c64f285db9688a9c95c5f3e27cecc5416d45442b3f60000000000000000000000000000000007ffdef518946ed28c840c1f1e4af58c25f6c5351e119b46fcb90dfcdab41111ffd2d1f8df3144436455d4eea6da65960000000000000000000000000000000018deb3bf9983a1fd937a296325945aa34e06cd507288a9aafebd940f5ef6fc1caa2eea0d0d8d3e51bcf822b6be2fafb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005425eeb6220b311da9fbf054aa48924e72b58ea713ce540197bb909318b1cd259a051907deb6287e24f7ec180ce1661000000000000000000000000000000000913ad2ab88cce183a0281389e3c5b942bbb857ae2ddb18227335e3fdd8e7f6e6ebeac3bbc4bc6eac4c0b12ba31c2634000000000000000000000000000000001733be13a4a6aad302fe202b2b32f14185a5bc6d5bfac1005d09009b45bbbd1df6c6f0bbdee5cf9354f610857a312726000000000000000000000000000000000a446de1b1ec697d826b6819f3ccf8539f973410d0cdeb36bd139cf24571bc20529e023dce524fdc39518dba50b824a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c95827c95d52e65cd9d99a0b19fe20acc27dadb3f536efd4c6124adefd9d957246adda7b824fae8df633ab7aaced518000000000000000000000000000000000935c4e890dd6710dcc178701a3e8680a3f4379e362427f6ea4a4a08cfe05f5a2e85d099a0dba81351b37cba822e898a00000000000000000000000000000000183e8a2562d8356d312c36313e7a2e224f3b171f0ce6bc652843ed3d5abf5f4f87272da0008ac65cebfcc559567a62810000000000000000000000000000000007e5e6df50a1f7a395f77ad166d205ce6640f5a3c47afdde1b70ba07eeba34139607aa4763aba45d82d1ac7b95783e931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000301dd736cc81ac82a330792e849992d1b1914abcefef007da494b3ee3448bee05f103f3112bfb4e7c200d9d7c0e8e7c0000000000000000000000000000000006e0f298abafc46146e65bc7f733c4c161a0fc9f7374517438997a3f0a583da5282c43db2859639cff7ba9c6eb664e7f00000000000000000000000000000000097b16c06bb885675cecca2bc0413c9605911ad7a32036e9ed13e22d04a9f139029cdb5e1cc9c19c6ca408a7f981bafc000000000000000000000000000000001142cd3bd1b89020c0afa682ca407f71440cc77a6fdf9f88cc19b134bd904c008b3f13e7b7dcb0fb47fdc78ade63e04c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001553412a755ca7a354b4f14c670a0d4e41a2989780ecea16df3ec4a06071c5b7f5f4e2aa9e21a74a8f8e9fcff0d3df800000000000000000000000000000000006f91acab3f3e47120804f6fcb8c01411636b916f9811a4bb804ffbcd084713e6135a80a08b6c4ceeb5f1d7e9282412c0000000000000000000000000000000016a3f21943570dba5068fa50de758ac895fa9d5b1034a2b6e3c6b3c3ac8482f9d5e3e5801092f7e5d00858c3f209cf2e00000000000000000000000000000000079674dfd4eb1ef4caef2148e3a632482e8f9452d4c21deaf4a543fb23d667447e4dedd02838897b33914bec99554b9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000999e4e00bf45a7d30faff2fac3140d30ee40881c0fe49c765ea9f817f67f2a97d07f6a51a3f01444eb661c217925f61000000000000000000000000000000000f5a0b7c3ed1634d4aae86e6fa88e2ae8a908364a27fe6d1e974e33ed0c22b8b0bcc8aa1b215c909a3bacfeb43608cf9000000000000000000000000000000000df8c7c8a0d5b0cd283261e80deffd88324af393b3cd65ec7f0d746d6b80c7d6d0a9ffa5082de7d159f89a4ad5a25022000000000000000000000000000000000aeb8da0e7c5760193511a00dc7a24e3f403e5f9a158f2470553377a4f4824c1554d274ffb43c3c44ab72449f045a6c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e60b03df5cc29e90817908897d7fc4322e968d333906ae688beb15a71e5feede0301e0959ac98b9d86ffffccbfcb104000000000000000000000000000000001555da6c3c96117075531a1d3c8fc3fbe8d154ee035135ca3436fd3913aba3537531a1038901a4b31659c694923351e10000000000000000000000000000000010f1426df0ada5b3ec79137ba46446b90d0c1dfe1c3e4d87d2240088f698896a046abe0c2043787c7e36120c366f39630000000000000000000000000000000013954acc7a990a2e35a43eb1c508a98f7bbcd153a3c29c9b51fae3217a01fe9cdaad543e3c4a9dd849937336cd7edcdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000676e2c73390a2602def22d9239af9df7029965346f5bf62e40c16f2303a3c1aa7ea8ea3003bf0e7557c72f77e2eacea000000000000000000000000000000000496c5fcabb30f850c7f31f4be0847d597aa74bb30c0c13f26426d829ce6df0658564a1d0f06e1bc81f74bb111939f1c000000000000000000000000000000000795f3de7328773c9560ff55a0b96cc08f3ec305735ec3d3c789447e1559eb4e74072b31ad071e3a7322c6e5e913fdc300000000000000000000000000000000174b75fc43cee85bd5b702775dcba2e7efb7e01dfdd1d1a980bd1ebf5067df28d25eeb84b3b58a62cea9946a48d827b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000491b8431a72e3e3623c94a52677980843e95223b965be0e62365201dc949f61ebd06c6d53a4c6e948a8c54df151fbc0000000000000000000000000000000000312afbcef9ab0f503fde2acd9404c3834e3488d1781b1cb9c02504ba5a140421b3588cce9e71749eef4fca337af9c190000000000000000000000000000000016e9311dcf5f5e4385e01bc1aeb15e80ff4cacf1f404fb98d184d65dc58cd2ac117627b7d2ca01b68666b62bdb401b8d00000000000000000000000000000000152b69b04bbfc6698123215e3580df72c60b243894786243e7ab161c3ec1dd66ee9adf02512a7b69808bf917437890be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117e4631d82128c697f34ccc504fe19d1fecfdbb1c27932e798e881526699c89fd616695868cb5eb5aa812773bdc03a600000000000000000000000000000000118393f67df32c5f4e300573cbeda3d115056163b8037e49c6cb67d5b7e614f74840b10f11300045d5a2bdbb12bf5152000000000000000000000000000000000ae07a0ac493daae9abcbdc48b9b284d9955e7983a62180f7085d1c22c7aaa870490e647ad502000df64d4761aa6f7c40000000000000000000000000000000019fdda4afd7f3b6859d9629e4e7963c3b17b74b3bfc9e67c016c83fe5b30baf1dbd5b82aea23b095d95666cdd8f7269c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b936da14f827c19202eeb2478dc0cc3cfc7104993e946be07ac3009366eb63cb1b904a65214242fa6e6ef64dcd6f0d0000000000000000000000000000000018eca6b02fb5e5aa27d54725ab17d5c8198f4e21fd38fa50e3fa4b11c72fde69153ce25e2af4d9cf8e47308c9d0579770000000000000000000000000000000006d8f04020b86ff219097f7b221700342b6b8a03be1d2ac51cd8b995e44309e3daf8f03c384ac96bb82932334cc6318d00000000000000000000000000000000111b9676a416b368b133f7958bfb11b7db9bb537fb7b3a9b2c25d0608b577dfc9c53dea6a30b2fb87d2751b7751df3901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c68c9d41ee543fb3742b2aa639027e18412bb29498c15393b117c99998ad4d4a7bb4758b33c5180eab0402028529f10000000000000000000000000000000011cb0106d12e1b5501c68600fbc64ac2825b537f875cfee53802cc66d7373379d182fd75f02bf4cec3f81b1ac6b17e1c000000000000000000000000000000000812059f1d48f43ae146c9774ff63e6f6a8863be7a51e238bfafb53f5635a316e0e12219bebaf84947d230c42693c3f6000000000000000000000000000000000ee1a7869f5d2a4ec0c04666d554ddea0cd95b8ad32a94a3288eb39c72b55fa3c838a41c173369d64a6a0235d3d3e7d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019109c6756eb217fd6536c93493334c04a2889d42d569e4729a55139032684520c47fd059dc395cdaa0753264a7868fa000000000000000000000000000000000dd46066cbe698d67c58b43cee3b0d9396f76d0af8a2d37ee0a0fbd0d2eab23b52b07207447af104c75e61c1844ff2980000000000000000000000000000000012a3195ea56cc3b9839ca96fc6fe308219f747a40cc64d21037ff76c6ac1e328319248ed8fe220abc5b4fa7f5cfcefad000000000000000000000000000000001150ae374d46aacac3f5899ee44f65a558e4c7e9df35ffe952d188035d19d14e0827081758c7015a54c5cbab7d3f6d211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000efdb95daa1dc32f1faa7bf6a99a63930ac91bf7a2417c50e812f0f9817caaf5a8ebaf24ad9077804d37db150cd018cf000000000000000000000000000000001989b01c59456d45031dd73c837c46a18a1e5c0602f0f78e3685f16ff1b068a66601a8e6ce9dcbdf6542fbd7ffecbcac0000000000000000000000000000000008636fe67257406caa75cbd315deb871f0cb4b99cb953a6e47ee98da7960637b340dd17c05581463598605f9fe295e0600000000000000000000000000000000025ba2a380a1b31aea06d22b7f7098c14caa3088a8816bc45f57205d5b96a2d294c60bc6e0ef017efb368da7a3dc08951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007eeaa19b0a784e9c069d74525c9a6bcfebb4daab47da697f38e0e450ebe8bea5b9264e32c4792dd9923d1b821cc98a0000000000000000000000000000000009a9c7bf3461d9dd5221c2c250b53f911b732930508fc578e4e072c3b2668a03a3dd4ca489fd24370c1c72cb15ebf3510000000000000000000000000000000009b5c5935a8745695108602f2214b0c8c0b6400bcaab17bfae9565145445c0dcd0c212354f448fddc1530cc96ce84e480000000000000000000000000000000014b816dd956026b2e3191470c0917b2963b4fc17e6ed2f463bde0d1d549ed51478987c528ab3d9dd3ac31c484db6029e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cf88b8a310a19cac10acadac6fbbc9657beb1a149ae2731ce034562efe8561652d02a478cf6359315c2be3e74fb1450000000000000000000000000000000001beb10d79840fc88c8c98610f788d82c880d5af50fc72db1774005670f28444a88d12063ba9c366dd46614f281150360000000000000000000000000000000010f1e8bda7fbaf356a3c20c2db310b0783eccc755fc531cc832b5d66f3f3866070b419591aa18247c37d5e2ce3642e94000000000000000000000000000000000abdcffe861dc7f244539548a79922910289312da5330e2b587822f1f668e8e61e7851d4f407b1038b4e8028a9ba9bf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008dafe40b430f0ad083f6b153ea13fc3d06a1d60d3957b969dc2b1f66a5384e52fe4a91e1b3b350c27c5c59937ba14a000000000000000000000000000000000772234bdf8c375c41d7f8d603dd43e18e07bc67b9755d9c44a101100e6101f6ebe1e0d74bda04840f1c6579de5211b30000000000000000000000000000000018d57a51607f295a3867f58350123d1fa91d51c53e55582d927d30ddee96c9f1980fa12584c92f8a1babddb2397b9764000000000000000000000000000000000560ed1bb3e29b4c7a22c9e4b2667cae858a61f52f560ea453ec4021a47f10361fdbe32c9f757a80ea6a00fed1ffe46a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdaec6bdfb15375d40c3f6f984b4a7b4c0ed9f14a352c2d88436f52a7324f2a1027dbdc459f2c836ea47b6732f1241f000000000000000000000000000000001442d0b17fcd1cd1b96b556e8dd3688f58ba5ef002bca9dbdafc3c63e3a813ab606a88c5a25480f25fdcbe5ba14dafd100000000000000000000000000000000108e00b5d01e6da992a41e18f4bcd250ed453f948e98e795a40d2749252a9b2aac81f0976c9c1359a63236feae4513c9000000000000000000000000000000000a96587606f9d878c4197b314f6bc5a630ff9a830e72ca00ba3085a16d2a8ec41bae19111c8fb4ba2aaad11c650b12941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001841584bfca3ff8712a517890fef4fef3d5d8c7fcc4e1b86aa8487948d2fcdf30a256531caff574566c97ca8b4edaeae000000000000000000000000000000000c80c68ca1ee72f797e142c948c56ec532e1898e992e8f12efce52a39821bc3207e4756dabf4f52bbeca1564a83216f1000000000000000000000000000000000dc844a4d7eaaa74bdb517f70b140e9262ed4a9dc8a2cbd5a6114b0fd100b00651cf0ca4db0620dd46ce914a336ccafd000000000000000000000000000000001132f03438b1daec8220e48d682e6281e75368fe7baab65a40204081c789bf4e42be42ff03e265e6e61ae6dbea8435901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078ee8a3d04e4903d0d7774be33f80ecb55491846f86ed243b63a2fffbfd71f214c4027a8455aaded7b54a3f9122b85f000000000000000000000000000000000298a3ad5d9e7b1c4ed117d00047ff84a486b9feabcfd58e51a653c1edcc532e7622b95294237d137b91c5fec0d11d300000000000000000000000000000000007bd73966a3425bc1ee9d6e7d5f995551df93e9f2b64eec8e7814561aa36b1c878c9ed9507662411001aaff62d0c0e6f0000000000000000000000000000000001d7db3ca29ee1d1ba9ac84cdfcafaed57ae9b78ff6ee8e06f3429cbb8c359a1c606fe9d15ae99ed04cb52006f54defe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109998905009cb999f6535674f36e3fdca7a03b8b02aa6e2b6a704c7a98b399d8336941aaa3c71ed9db866920075f3cf0000000000000000000000000000000013d976203309cdeaf18072b66eeff494619e1766a0411e5df028285e75d6160f1ddbb1dee762087fea9a20bb3ee69a2f0000000000000000000000000000000007bee56f057d8bdd35a0a251585f471dc77032a3d5b501f1995e52eb90f0e985f0543c8ecdebac223dfb53ea3fd71879000000000000000000000000000000001247c7a7d743fd64d798b0ae036fa114411adc76b3bd47164880e39d494b1bc69bb0f83f74330a1c456b5d1956ad64441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c11343853e9c4eb18513d75cf9f6b77fa22197b56e667e6a7fe4a3be1ee482834e4081c349040af3c95c0acdb3d24810000000000000000000000000000000001a811cb3a65837fcd8ba2597ec0ab27e1a27a8be92f928e193aaa7f6b2ce08bf849af9d88c24b72fcc99f6adcdf7f54000000000000000000000000000000000df55d7ba54e67fceb8959178cbce0405946980041a6e6557e58640347ad9509e8244d6d369cdd9a75fbf3b8912c2d3c00000000000000000000000000000000086d045d3ea24c7bfdc4330f2aad5131b1f8abba92acd6161b2d83114888e95b37fb0c80d4d53a0ea7ce28de7626c2d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b6e5a667142805e1f89b703d2808453e571e788bb731b06f4eba667ad390ea6d87c4cc9953aa8f6f22acf4d9992677000000000000000000000000000000001223ea8ee9697cdebff911df3cc9dbe019942c74afaba9597c1679533e5a8a4cfd5eb3572aa43a89b0ee7ca6b4cc58e70000000000000000000000000000000014bbcffc4779b8064cb13e4877c012a4bebf44ec7a86fabf2c94630c54815a613bda8356ba12bac86dd90815da6d2eee0000000000000000000000000000000005266b5f86afbb4aa17065d03255eaa02b5f4c2b85a6ec8e339cca7d3b8ae2fae09361a31bdc48e0a2787a038fa2e6281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a63325abc6d1cb5c4caddc18032255c18510f13e93e937d2cce58599e64a819a663370fa96c3d8b8b36ee20f15ea591000000000000000000000000000000000a6ccdedd5b691fdb969102807174937039692a6a4082b78df39edfb20895b9c2b7c478b6611e038aae5d195d75ca7d70000000000000000000000000000000012151c07bfd1af5c9ebb76e5b5fde6b3963c31975ba5be2acd53c6749897ce83f0ea3e03d2fa434bd5382a5dc58914630000000000000000000000000000000003cc1a08f580e8a8aaa6d87411dbaf901f4041a93f4203cb4687c0b18d62e00e9d872c3fe861f95039fd7367cc6d789e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167f0ff730889c06edde438a6d806586701babafd03ccc1deb366dcb7c97051b9c441eb48f8062ef568b965b442a2acc0000000000000000000000000000000007deb2cd4fdc3562df41f517e1e05e444b05c2f1063e7b4c1614e5336e8998a5f7423be09990430c07135797a77ed8c9000000000000000000000000000000000f06eb2c2e74aa089918e012607e6da6eea4f6c7f1de72fe3eb8c8c021db110c8f97a21ca74838ff888317394e6bcb95000000000000000000000000000000000a295dc5dccb8986f29a4aed5d2e704be649124d9df4d039dcca9987db7e87041c30f60f7f7b6fa5f028187163a21e571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010adabfadf7d1631b1237808c2103bbdb0e033b831e8fd23470b4241fe660203957f502207c66167ebf2ef1b5764cbc0000000000000000000000000000000003e5b25259122be028ee8178fad1bb8bc834b3cfa71d9d2530eee683a812a5bff24cfada3d973b164d1b8bcc1394bdfd0000000000000000000000000000000017e70f567389d72dc600bb4df7e4319eb44b367adc70a0b7fe2040733cfa4d156315101055fad15b6302dda8ea005853000000000000000000000000000000000f79679ec963e55be2066336623e3aee4675afc4cb5b1ea1715cfd6e2612bb14029d416a54375b4a8eee83e04b5aefdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176f95697d95b3920a99aea6a68af38c03f1e20476830a4471938789ce8e111483cbd270fb41d4b3a009f678f723529c0000000000000000000000000000000009c42533681e7c2297bc57a35d01890c3a23d4becbb19e4ea5fc7a07e88679e1c328b97f3e151494b5f0d9938f85e2df0000000000000000000000000000000004968e842aea3fb40c11baf33b00816f8d8b26d84ccfadcca9c6b5b2e873a1858abead404e1a19aa59b4fb4f0c8342f1000000000000000000000000000000001247a08562ea50581b0545da7fdaf40b2ea4587d6838149d1f9eeb78345728027fd2658ad577806ea5bc79d1f04595c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b91f33d80d6569dd2b047ce31f5df752e6cbe326f58f07ad2655fc083ffa1fde9510d43c902e10d268506717b19731000000000000000000000000000000001338f4b650ef1ea266b712aeb1a8eb8e68a57f22fed737bfcdd80ce8bebd36f5d02744376b4d196a6cda89387499270600000000000000000000000000000000002ac28e9d6d48ca54957e8982e00494d96d95cfcda61e78aeffd9561082ba783bbb21f4bf4859ce06c1125bbc470694000000000000000000000000000000000cba2dc2b8c45a02c5d90431726d030c97a820f4c04d9704ec8d091abfcf43d4208eef3d4598b4b5eebdbc1fdbaa32b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d18a19f27cd59f3d0f8728e4563a296f3593bc473ec3ebd8eedb49d21ec42f8572df213d96acca23287f2973bdfaf900000000000000000000000000000000111b2928296d566450c4499e3bdf1a2eeafa84e78b671c176c8df54a7308b7167730cec98db889c79780c0ffebec636c0000000000000000000000000000000018bac4d1649c2bcc1e9c4d9eee2625b79da2cead2a9b23388b87f1cb4db42cf9dc4698ae4dce98ce9c11e8913e32c4690000000000000000000000000000000016b0604b37b08cc541812657f126c8eff042a909401e65d699f76b012408b402419707ad568e66d0f5a9db31aedebd491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157f59c2710056be69998ab705af9a19af01a3386de568442fe1302a6b3119c6f5db7c1f74432b74644b044074f9b1f1000000000000000000000000000000000cabbe45978fbcc9f4a898bc0143f336b972afc4e9ee8e75fe69e7ac303a36b57ae1b08c0ab15f6979bc831a54b6296a000000000000000000000000000000000d40a14f6cd2008413027908cd0f17c7ea5b3809f016754c1472b8a326d7abbeb12deb351c013e01223cc32c2c70e599000000000000000000000000000000001874910b6e36f1d067a6320acf59ad21edcaacee5e198a38551e26ca3ee0a33b26a5fe9c322873425b0c590cd8590b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "000000000000000000000000000000000cb25f65b284efb8a6e02a5040105e87f339d261d9f81e3f152a65bfe9665ebf1b01aac96a527ee79a00b58fffea87ab0000000000000000000000000000000001a42a5963e65742812174174ec1a1d28dbf4b2e5c11b3e6d26779e91a81c8680484edf5f5288936b0365e184292030d00000000000000000000000000000000041ba796453f671c3f4d81e1ae94388c19cbc0233b15228b941628803ad9b6b94a2ed9e54c8af448428169b93e3d194a000000000000000000000000000000000c241833e69b0bd819f24c754e5726bd9afa80631f643550a21324ecbb362a086df145bc21470682d0363270b9384e50", "Name": "g2msm-128-jwasinger", - "Gas": 1002240, + "Gas": 1509120, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ad11bcbbbf592db9e0bb0c97033f732437cfdbd76261dec844136838fdfe09657711a1db7652b0d13058989e876de6d000000000000000000000000000000000872027f5f6ce0e86b926d25ee4763771d276e9f09ec4bd334fdbe869284df3542a6d2fab481ce3d16d82f28c64030490000000000000000000000000000000017263ac18d83252ec4bc85b57047a9ff2902e408f2cbeaf1f88c2eaeffdfcbd51918eaad661ebb0d7634e9d6ff0a0e990000000000000000000000000000000001d368165be8de0cad05e3e98c6526df84a28fe9838386f8ac01d6043cb4d12cd6ddfee625e8e25b03540e9208f384b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000819d94543cc995710e749ca6e874f41adad6ef823ff96ae56af5e7fa510b36a1643d99f9d3d681e6b4197cfd7a858730000000000000000000000000000000002fc380d5d2f76352bf885c442a291bd3460304f9f770a17cbaeda77ceb9bd895eedca323dd2ec39042258045e408aa60000000000000000000000000000000016f8bf2c52d10e32059231b33cc9272d47ff0a77ebac97ad847c5d5a4e2843ae93d207b8330fa76486619ea31addef540000000000000000000000000000000009eb35e34d0311fe5803e2bc22eec8e45c5489f097440848394859858398f3dfc1b32a63031ed2f4d41339fe821c932e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000173252c8f9ef77a05b9510dde93c778434b30afbf534b3029c3e4cc9dc713628bae6ebc17a6b8f5f0d8b88751c3060300000000000000000000000000000000053b2f2c539bd4b4fd76717d2e8e3510910d3f0b5c41961edcc0033d62033c38f2cce5bfbe75b3cfeb1850b5e27b45d9000000000000000000000000000000000b6824b049a59757edc31438bc32b1bfde3056fb07cb3aa4f4b5cbdb2e06f93fe5f0c90bbe1c246c2bbdb42f926d8ef6000000000000000000000000000000001589c2238bec47aca604dff716f9ee389e0f554c5c1f20e0281a79eff41f2ecd1264acc12e5a627c875fb55c2182b6a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb31c82ace608d185f70b387ac5c679885a98cafad74eaafd4c9780da7b5c07c82710b063aca870f6b200cc666bc54b000000000000000000000000000000000aa43f5026eb7b56f1c8af016a2b86509ed822750862b8c264116af52b05c4d5f730a9f9fecef13784ff5705aa2bb3680000000000000000000000000000000019fe715a85302072c2a2d8ebccac7996d3371ded0ef8c3bd6848a06b778a6b11fdbcda1f9b5242dd1c9149703db87c250000000000000000000000000000000005b7bd38dda881c6d9f39d4073478bd9ee57b91291add017788f71ba0bb9deec24c955ecd1a1fa933fe00cf9a912c01e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dcb334e962638f3b65daa96955cd28d709c367dd6b619fdad4b37e52f6322dcb739ece5d32488ffec729dfe1cd7bf4000000000000000000000000000000000692e863b1ac1828b2fa2ee7218395ac1a5971e9bbbe97d156f13eb6e45913a87123c3949b58f21b3fb5c3cf4e78765b00000000000000000000000000000000178df65da50877f327823b57f930a0b734bf81c707c61b3a83eb2b9b6686cde4fdeff5cf2fb25d76d916bc058c1eae8500000000000000000000000000000000123841e3a9ca0878538fb2ed4b6ecce2b450325862e6ffb442ecbe1c6c45e6f757d47ad20b3548228ae76f0b37c6e2531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d671028a0f71c3f436691fa3cb72d606ef0e5154b52f1cd699ab8f372f397c93dbaec751e495b68364c99c4961499e0000000000000000000000000000000016d183df74c8e6fbb9098ad395670e94c21fc859c6859dd0fbf9187c051fcc4ad3cfac16db6ba419594240df0849920b000000000000000000000000000000000f8ec6886555f4fce6421f9b6e5505e349597bec6038e104dddbb4f019317246abe7338192d5b226fab2479d495ccc4c000000000000000000000000000000000816900dff573ce3ba2fb3fe7d0ad7c082a8cebc2803d5e3a15bec2c69c4e3db330a29a4926fc710292708191ad38cad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfb0993d237bbb255c6efd7c24b2ebd0b0f49823c4ed4d44446c338183d17e13ed5488ee58a7b1f9084bc81fce4bbd40000000000000000000000000000000006b0310e7aa60323868df4a4228bd8b813fe8aeafe0cc1ae7a8d2efeedbfd30a6fa7167f9d9d54bca11e6690a2c7dc3f000000000000000000000000000000000d06cb585e868bb1e39d2f03176ce5527859ce3c1bb9a41f79c505e2d2890cd4323cfff606557690647e22e084a99c85000000000000000000000000000000000e883e559db42ee7e026e479a8306ca9e13cffb4f9c44b85beb7f19f08d928388aacd9e5706859dc95faece1011719ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d4f1bf2343000a14f450a96469dd310b78d975a32bc83e2a6ae0faf261ce7f9a4e2f75532a65b60708e4b499a9e01700000000000000000000000000000000118262d5ed72f0433eb8e6207c922a26b2ad218f9ed6a0aba77e1bbd5f1fd2cb8907eb7081b37f86e42a4f6aac7161be000000000000000000000000000000000796b9f919b97e67a7739cdaa35501a431d295d13940b95b30470269cb7326f4a90d49f65e2e0a21689590c61670cb0600000000000000000000000000000000168c9146e402259d426b2e2b1dee9b29eaa3cabaa6392f1a1912a1c11096b6c927ccf22ed8918c0876d0d8d126a0a4721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e3702dcbcc68b3ca7cadff7c04262e883d1a25cd92faa5a383f01265259e1ef023572b63f0405b3c4284c6bab31bb0000000000000000000000000000000012faab84e08ab0b2f01e41585f0324fd1036fbe1b85c01964be9af3c582d72c9f1397807470de55786fa68b30e182fcc0000000000000000000000000000000007adfbf062434f76bb12d90467795f648d9baa2c7747d19e669a28859c62e38f3a48102e5814910d344ca9c98dfcaaff000000000000000000000000000000000829258faea86aef33925448d44746d9a9b8266df6dddffb72130fc0011c7da262019ce35e1ade7cf348d31748612b921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001198c37ebdcebc10b1e639310dfe3919f59459d69bf6edb12d086b935ea2638dedf389ceea39ef9f6a8ff202230cd14900000000000000000000000000000000106cf9a8fa8ab304fd917aff5bda9de6fbb338d548dea56ff1253b2a2d30a0c781c4a5ad5f8e31f41fadec3d4576598500000000000000000000000000000000117c3d0336783faf61724007c78ff7f0f038a35736e65ecf483e81f6b9d5feb5c587fa6ccedc1c97296e4c233c096ede00000000000000000000000000000000004ed03edf1b036eb4f7fefa589fdedd2fe843a8909ab6cf1fbf47dd5d91bcb067c0b3281c8d772dbcc8cef1256d5bec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001d94f333d893e0aa4d429cfa4e6563d4d50ea44020195cb06e5fda3a0a10b0d9eaebd8c273e89ee2b78411d6d2440d0000000000000000000000000000000005a1ad530cb9b77c22d980fd6d2a577230484380cdef7258986a93015ddfdd706b85debd37c183285625ca8abebf8338000000000000000000000000000000000dd2c8de00df7395bf2404651229415d4267efbb859bb340b1e4a83bdab7a63c5828ed6d9dbf41d7cd0447e2e8c03dad000000000000000000000000000000000205de65e01062643aa52fa84289688ae63c2d7c0e1af7e1dd28793af8bd49354607c6fbb1d003bd371d67ecca245fd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009a6f6881a56cbe02c718920b0adc7ede32098a9aa85b2f8f6feef11694bab41c0469b76299cad687310ce9da23180d0000000000000000000000000000000019a7cffa4b3105fa424bf069373fd5aac017bcba1b054daa8b16f0b757ee26decdd8670af8556a50398f56ccadd883ca0000000000000000000000000000000010494b89fc3f5daea232059aee0efc189344d36b946e1c83813f4734b4fcda3d361e1d1389e6d114903ff5297c8bff320000000000000000000000000000000008167abcbf9d09a96476742db3c84b372c73203257846ef2d2fd4f8802f03bca21650a5503e242582619455d8a10b81f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173ce95e28c993543e4d9ab1f3ede8b0c85226cdecd2f97022f411d45c8122969033d68b4445387b0e433d0a0af5c57d00000000000000000000000000000000199b1d4e20fffa301f4c0c00d61f215d057d15b268f6fa5f9685c8ad5aeb1e2bfd65faa2f04ec0efb8d857b71744063e0000000000000000000000000000000000d5ac3d2f4ec7d5eb12f0f7e2389cc5c0d531fb8f8f913f5fca996e05d761cff58989465395430268846c270db6ee050000000000000000000000000000000012d196a3af8466b4d9cf0b5306821fb79cdfafaf347b69b623438941c25e7bf5abe14aefd556cb60d1df48331d4a86541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe12c7a5ce8e9d69a14e2b31a4bd3ab0f5672186f0ac5107062bc5792f4e449c9db66f33b9de8a9c527819e7a0203c0000000000000000000000000000000000481511be3651ea9ba7afbaffa7b0d9c9df7f2826e259d0fa76e776d81a71055908478e93d67cfb91b342dfbd130b8240000000000000000000000000000000013b33e3efb1a90e005873e88767ccc2fcff2608513334c23de0ce92274354a8cb7c9bbc91a9186734990219313256db7000000000000000000000000000000000959f773ca3180495aef67ab2c7e3b60a6d2f3b2012ef67492a721658a65bc8e9640f4c446fbca486a572a3a450230e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001130c03fa63b0be2e6ca5d70b8b66190f6db697ffe4888660966cf7966218461559d8f8ecda4cf5571116fb6ab5a3476000000000000000000000000000000000f7c36acd03a15d0a8223439c400d99f96e659771a59f99731b4ab2215af2d100bebe079cd1f0be338712072aff189b900000000000000000000000000000000068ceb20758dc0d736dcd957db8d3ce1cdbdff1dfe3cccec3aede6c12afefffccec65585b75050051bfdc4033f262d120000000000000000000000000000000014a30d60a368c79c0a080b0ca879c752ddc016b5a2da551774a8c80254e548c24ebc25691c978cb0e631f242a7bc5ab71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001064014f60540f73b24bd2af7096ea0bc5a9644460406ee258bffc72b79a3e6c1b8569f70c09aa05dca03cbe8d5819b80000000000000000000000000000000008acfd7e36dbd4647a6a5e09c24a3d633162e8e774de3abfb2b4266c7a6da14437cc0065c2a3652ced9fa4f5414a4272000000000000000000000000000000000a1876e0faa2d6098743468e6a9863820b5ce85f7d16d9baff0f8fc125b0f1889e3e8531c1ce148ce48481d8168b62be000000000000000000000000000000000d2cd6f7079d58685ab8bf4e53e84490656043ddfa54ce6df7da75e96ea963cc9a4238edf8344531a84f2cdc198a420a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c477619f311a56a1f94a47f675c40b7bd3433c1d44170348d523ce393fc084994a95de74f5673cf8b2e57ba6036a020000000000000000000000000000000018004427f9a2f481ae6416268921f34343a7dcb4ce20a9f1eaa681964bedd75b05e075a1afe6ed1251b3b6763648521b000000000000000000000000000000001647f4ae2f905ee9576e83fe7891bb1a92509e3616bd44d154b0e6e425767827496a9983caf359a958fa0d511fd8f47e0000000000000000000000000000000016cfe6abd168a9ddd49a05bb8b5ea76edcf67fccb5035d8059852249fb47171ff4a44ee8ccfaf23972da4aa3862f81211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000902476e2fabfc8467068f438eed2f2b79c5d6d12f4551bb6253274491a7c41c82ac5f2d3999e07ad24eb19cc5a3eff90000000000000000000000000000000004ba2aec8fa838c20aacaf2bb87f552d9b312bb15132e2578052605818f4ee13b6b918b5fe0bfce6cb3a0d222530c2ae000000000000000000000000000000000a422974a2199fc5409251cd337208e4db9fe131fc82a2cab283c06ab8785b9d9dcd15449a03083f8f19fafb05884ec0000000000000000000000000000000000387ad9d31f6f292bf84096f7bf14eca71ea71a20a601992f3fcbe9e90a45cdb310e9d603a611a72b47ca2765410dedf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5bfab89ffa5ab018a248b6cd5689d2c035bc563b9c006b00ef73c19a29b8d2ca3b0433e9923797d7e6183b76f7229f00000000000000000000000000000000001722bcb0d655d5517cc3c73b11a2f91473885d9c7c7ab5c16d3461f9560a84e116eb8bf17feb68c100c34e7c4f6f6f0000000000000000000000000000000015833256f99cb127eee594b08841e4257740860e72641b35b60f280e2427fa2fa912807888c3b3e795f9b156f61021ba0000000000000000000000000000000017969067f014ccda9420ed03e09a4740674e37dd9766b9260736d471c4d99431cf93c4b23328e02d7137a78ca4ba4d8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088c8fb1bed82a11c239bd902fbf56e49546e0672994a24d3ff29e12b61e25161d21e89b2a5d4423c26c25f64cf94bff0000000000000000000000000000000017b2b65cdaade32d044cb98d5f8267e4976d1aa5bb72bacb4d92ec5a1ae4643ad9470ea7e07ce298691c0260d192f47200000000000000000000000000000000064bb96fef71d3f5fbecb02424771044396bd3d95ac42de68611e85b34b05a3f39754d0a781d406596b89d92df6f590e0000000000000000000000000000000009019fbcbd5375ad5564fb9952e101b17568995fcb1125e2f74bdf849a0042641cd56fdc9ce3b944d021fb09587762791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d244238af7f67fcdcac60b1cb5910dc36c213b39df46401ba6b85add951f30c0bf552e62d8a5d1f4af92d7a35a1d2ce00000000000000000000000000000000149bf1b9434d0350b75c9035a2f7fc60e33f5457194d2e61b9a760ae3dcd610b9bc93c4063aa81444bc5ef7c960d85a4000000000000000000000000000000000aadee2641fe7106361a441c9da151a39bf483d4ff511c903de64121deeec8d30d0705c6c86df27ef340f439be0db7fd00000000000000000000000000000000139f6ba23b15359665294d0f8bb5db7f3e134b7898a83cf8439f39791fbb7747a9d971281ba0b598e26fc811fdb43f141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012155c8e851393402ae6098089fef68b544916c2af46a46ef0b9daf2ced8c86813c532dd0aef54fe57609d2974a2099e000000000000000000000000000000000a53b852938617201f6a0920854130712a3e93e187721373f66836e64525105a0ce8c046c2f36a8b5e9eecc161a91c7e0000000000000000000000000000000013ed6995a4b334a220163e0360a4fae4f2f89d83816c4fe9f91d7c97eacbee4adc5636befa99422443030a7d4f5a39220000000000000000000000000000000006846ab5b892b54e8598bf4e880dfd1c99d059c2762340e1be60c5b42181a9b05e0f816ab2056f86152056400deac5be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f296d3cade62b2af314a4df35fac58eabe8b4ff643c218bfcf5e040356a48af5530ed7a09db577e25cf7bf4e2489a9000000000000000000000000000000001209e11b1e1f50156927cb574824b1ef638e7e21de50a45988e4a633fa331e037d5bb415f6a686ebee273dc66419d3470000000000000000000000000000000007457bb3dbc9900b2fcd4884623ab8ba2f0a2c414811038f2fb547a15f005f6bdae4e6537b560b9b88f506c79034f8b50000000000000000000000000000000002e98498231943142cfdfa5e429030ad5f7171bd09bfd5a9e9a72ce80177f6e9bc45c97b062b375d528fb4c4453f0dc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d74b7429c50ce597610b579870590ee92893eda14d9bbb3c8e1b486758e5409682d20ba2256586e18040699eea98f5e0000000000000000000000000000000001af81a5e502d6acb2b09c4fb57a6e37ae31221b1ef182d5377b6a132e52cffc81dad800eaf31c1bae32b44065437eb70000000000000000000000000000000007a289472e7bcdd44f1dd89df7e0a4300e4ed1b3ebf8cb69501d96f4ccfc5cc3daebfb5a0f9ac9ab4f8ed696d58093320000000000000000000000000000000003b635213d689be8c890372fcc03e80038f9f22bad8ffb932e063831014b0a7aaa2c161f7dca216185933e89cbccaa091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015481d84f55a0aa9a7631ce320940e203a723e0b2b430ca12d6d6a7b1d17389305480c3c6e4aac5ef5f31141fb9742c400000000000000000000000000000000195abab435ea8666c8cd86b364d592a5a287a29b126d99acfb44a49b4cb34e0bf94ecc8f01d4147b23f53e73782ac96400000000000000000000000000000000158525f940600794b63f36284af5743c4871c9e397d4aa163bb63c5220ee0855c2703241998f7185aaa8f31faae01596000000000000000000000000000000000ffd1cb0e142d53be55a7c9d4db1893e317ee45df5b5ea2f55d6eda640bb566c81d38b58edd757bf7fb3c227a3fca31c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c85e5eec757fab12d7df2b1f6d18d8439749f4aa520ef7891c29245d0f54554b15b5aeae5cd3d52767d5648fdf85140000000000000000000000000000000016ff0ceb0af2f932925fbfe49686bf833a095a32f2a0e1c04330e4aee6e6fad6bf2b027c4e5f6ae6c0ab9c06ba4ebc4a00000000000000000000000000000000063920264ae74bea33d625175b032171d6412c58da3c17c98338365bfc14ae20040de40a78c681a632e843891f3355300000000000000000000000000000000007fdb9c61b9591f607bbd90225dc2c6b5b439344b163c038fd0fe7d26af5fdd7c7bdbeb99c709408712d78d4d73ccea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e5e35214db0789c725de8dd3b88fd9a6947aee235b94cc9d5e7ef8be8067ae55e0ad4dd5320755af04b4fad06ab6470000000000000000000000000000000011d67d493677b4ed0df628e1fa2e6972651387ba2386026dea21a56e87629d71efe1c78185b6c59163a3a69e07f95d63000000000000000000000000000000000325f09ae03abf48592bc1be1e68b0f3324aa38e2b4a415d127fb0362ea152bc5178820fa184b4fe96f91c27321cf31400000000000000000000000000000000113ea4385695d17d8911df9196e89ab05143b51def50c04fa4edbce7b0e550a860637d0e5feee921ccf56bedd7dbbc551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191534c9997ebf1b209f0010e189dba5f875f6e8fe4fb84f8b067f68eac17177181cf2e18f97f712a4682db35a98af320000000000000000000000000000000001f7180a46254a353cbb66810ecae841a3b16bc5678196a32a8ceedb647f3d7779ce7d4674ed1686186fa98180f0ad3c000000000000000000000000000000000203cac9d66e2b6c8a79e6768aaa9e42c87f0ac07ca12f3add022f4e512921e80d750c26cc3df54619fc1555f0c8295a0000000000000000000000000000000008da29096db7aa601c67a591de8fd4fa8fcdbe1361e7a1b9251f7f66d6a338456e80196ec562176b8e73a100ef34ebb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e2a630936f77c19ae45d618f978edc523e22d494743694c43e69c24f00beed6693fa44f21fdb0e6054abab1325c2a6000000000000000000000000000000000365472a029c53ea32f08063329da918756cb226e5bb67a0db2aa82f668d6c32b4bd4e2331786c8fe82045d7937fd0330000000000000000000000000000000005ff0ac051d6e06b8e4a1dd0dfe0733dbbb3195091bc98708945387993d4b561b4a69fc9a46aa5486691e94398bd038f00000000000000000000000000000000177ab4c59ed4067f5847449334f84e2d675f4bbd11bf01fa461655dddf0699bc843cc18fd0f525626c8cb464238db1321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001200cea27118cd52902cf86aeb08c9dcc29459d342ae956e9040ad516c06a79c0c56608a4d47d995cea76203decbe77000000000000000000000000000000000bbf072782c907749bc49de96a1e077086728e108731f7d56ee98e95a381211844d8dbbed7d679233812810c69152d68000000000000000000000000000000000bca5ed1692470c5d981b0695bf0c0fa23c07c1a784253acec9b2bae16598f3609100442b8d4b96e64eb73e77d7f0d110000000000000000000000000000000019b5345dabeee84f7b7b558dd9142dfbbee73b6e63f27310e88a98d799a237f063b4a188bf4fa11e88a91326dfd0b82c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013456a04934143da14a97e8387b72b58c47f290162037bfebeb2c1a095d2ff728c4cd79b8521d1f7ada1aa593f2d5f8200000000000000000000000000000000124052c7f380a2857293976ade77772130afac6559d78af076bfead8ebca6aa6b3b54c61443dfa64b771eda374e02f7e000000000000000000000000000000001671bac1992d281b2b377c5c34af17d7984d270d1404abe09303a4a70b911ed77e31fd0dc2b7ae730976d26bae5c20760000000000000000000000000000000006bc80dad1f9ffd972de97e2f5a51367ebed67602494035ef681e53faa264e92c0bc12d1c606a75d23c66f17c677f90c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000636632531e70fd162fc7fad34938cfead9d471e7c33144665f122792918e95f243b6ddc650f8196dd2f48424459933e0000000000000000000000000000000016354159de5164284dba467e6ab828ba50e6cefa2bc9382832d6e043d41cedd5fad0810fb0463e92950db65b7a88b0a100000000000000000000000000000000004843a730a96566cf86f4d6625fe16c90524db96962e0042489bf874c7bf30127b9c6c73248f956f6722012cf2b10d800000000000000000000000000000000110b1847a4b65f4818b90e55a4245524ad3e674968a6f4602c044e45ea955c821fcfed89b34a01fc753d6e55069b68ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cac2326ae8989aeecc5518f47d934d952530f7c3b96aac25e30b7bdf7a1d96c2d4a020ae098e39c665ea81a3a8952130000000000000000000000000000000008f3a55c5db23d98f19dd3c2719a2b478be1ac8f509ee4ee2cc29e381a1c873d58f971077eb0ce74de9714545525d4bc00000000000000000000000000000000130e27f453dcd6d9f4dd4b4e8c067a97426217d06ea4efe78a661fde2affadaa3efb39ca7205457b613c1d82d24bee120000000000000000000000000000000009cb5634314aa5068cd48d02f3140814e1e30eadc7b63a78157aa5163539356591de629f0547aeb05d6494645ef543e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000548b4db02d8e4e99ff08ab722e6de7ba1b57ac1829b35615608a4f525d8a4eced9da7c127cb166e0de991ce0bff8130000000000000000000000000000000000af26433f64808886a9f13d4c32c27a48b837938ba8c0ee22ce9b0768b91076e1eb573702592e0dc8c6360b2212cab6000000000000000000000000000000000ab153a6df9bdfb7518a5ea9ef27ff62a935f3e13df467685e61bad6f1c9c2baa881eb0a29b29e746cf82a93f00298aa0000000000000000000000000000000003d00bd940a8348652ca0f5529b73e05484ffa66c4e9abaf9134f0948553da4aa03234737775798006757d4eb8e897c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184369264c8bfa6370cc19cc8648432fef2cce41e98cc06dbd02730a916c1329878efaf66797eeb214c7b71438361d62000000000000000000000000000000000ab9ca1e7cadde3d9beca985109775f43d31bd0a8c24f10368458c4b487879ea1f718e630c9d71242a60144a053f1dbb000000000000000000000000000000000d4fccfb5335abd3ec0849a02acca3dc50f084c95e70a6305a76612bcab9dccf2d2a17efb458959841a6e90993b0e18c0000000000000000000000000000000006d3e9f6592cebfa1447afa88077c82b001a2cff1561d2d3905e606c1789dc4170b55f860b8d16af2a26458d9984d1971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e17796e0e1e854fd252a61f6927e8a66aa3d66ad1180e947412f6d4254b53806ec590b2a5827e51724f432ffb336830000000000000000000000000000000013030795e5e3efb1d7781a3cc77269c84ae08232cc0f77923ad9938f254c724d748d807cda835b5f229cbba25bc2c086000000000000000000000000000000001486bd1cb89dd086dbc111433ee826539bef52a882b558e0d6361e4a27ca3e22cf16e5ccdd30920b435bcf1d7af3e1a30000000000000000000000000000000011d10c451eb7bece593d300cac947e6c243fd18567a141682df6e3da4817cc02fad43e1a437a45d201c26d09153887ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c95cab40f706213e0064985ea58a05331873795b0f79385b4b64dd901432f590ce29c67ad50dede53dd5c3f35a3cf650000000000000000000000000000000016db74f7436c2bd18dcb5fb9637bab86d3f2e3bf57ba78d580f0a4c0bd453031dd2376c5d5a3fd3e072d3c5801541c920000000000000000000000000000000009cc2f5651bf08437242a7595fc5db53d32986951ff20fb048f2990b019c4efdac9a86fbb0101d6e4320f23c73ada7cf00000000000000000000000000000000021df241a9d37d6afe3554b934968de3235bbd4dfa037fcc1c663c6a6113c3da0307ae8511335e5e8868b6356ddc8ec71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105ef8dad89d8807190c2b58f1c73f8e7551dc416dd6140c194eff5c33f827407db46ad33ca29d7094932056f1e0dc4f0000000000000000000000000000000007b0563877e625942b75f87b0def5f4c96f89372bcaf0cfe81a65a2c1c17f3621789cacd503438269cc8e5a3938d30e40000000000000000000000000000000013c6fc6651c52ab1e25a6c9ad56eb8891eaabaf47ecdeeedb3082a472f5b871e3407b096f473100a5a56933761bbf809000000000000000000000000000000000d79d884ed467701b586049610a94080190feb302bcb1e5b518b5fe5a43f3cec6d392f731cf7dee8caf5a0d587b60c701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173ae734505c698a7edb40cb9cc1b33d166bac2f51f81d8a6de93334a42543d09aed72952fc440860e6f371033ce3b7300000000000000000000000000000000195d9225602576cd4e99f62d1c0696b30ffc785a22269e28bad05b8953f13041df70dbd95209f3adc503e9f3cad72d8c000000000000000000000000000000000694db4e4b96b43cfdc7a5b8b643ca83e1ba3ef13941e1fea31b6f15153e8fc8adc9cf1ac225538f36f48f7bdda333bb0000000000000000000000000000000000e00aa1b504e532e077cb71e1a7cdd5141f52383d5a3c95bb90e79b599147425b89fc67f7ff430d9cff3323706c6ef81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c1afc4c5eb2b007f7ebf51f60bc5ca3d5d5cfe688ed8eca9368f0550cba1bb1f2b99fe3460193dda464ac1f2673927000000000000000000000000000000001771f88f65273d708ebae98ba96b1020010202a1e8f53f5aec05a1d56a24cc2cf83850054ae976cd1e58c31b83a09722000000000000000000000000000000001608000189fc17fffca28b0958adff32860c664d90b85726450167bdd9be48d255a19a3c44a0a8757293a22522c81507000000000000000000000000000000000cc34ae5594baedf21ed26904db71e610632b43fdc40a51395952189269976791ec67810a7bbc6c20cd57119514ec8b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000766bd2d757009047c8392f595fbd24e2a981d5863ba8750d2b633966d16a75c85840df2a2ef36985c8df7a51f94ea9c00000000000000000000000000000000052222303f3fb4f41af3130b400f96c7c53927a67866ccb1cfb1de86609d35c9140d1a2299a7a14b73d4d80aaf118daa0000000000000000000000000000000019739f7c04ce73c50cff6810c690394ec7d9f4cb5b50fde79d71f7222eca5d516d4d1c3730cbd90a7ad38dcdae798aad000000000000000000000000000000000c504de8cbb1d4761cf5008c28ef752d66f5e5de6d4c3b90f6a4aed0b49aa0d3aaa295347ff17f2a3be1f3821b6496a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000683229ad3190c5c937f9c3ac033dd16b2350d13b5399f63ca029577b9725eeb138485048b67c32593c00a037a7a502300000000000000000000000000000000081dd4f491685cd0cf2425880d5dc1a19c8edc839a502319d881217306ea8f3969bc448bda26f98303329c56323d0b0c0000000000000000000000000000000009913591d488445ac5a61ad6299f2632083cdb602f413822273bf07c5af933f534f74a8ca82ad3beea846d1d37d654190000000000000000000000000000000000966f288801378acf8932862b9bd680259fbcac3bcec8ab7bc7b4460af8e0b0ff83ea764e102288e6b3a84b73112c491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168a9e5b507ce272e1654346f45981fd2bfe4c4d33d819999c4898ea64a505c9637a990a2834a7d136094194468394890000000000000000000000000000000012011e1aca1b25caf596751715dcd8846d4f91dab9db5b0856e3b0117e38b734de887092d209bb35065f05116a095a680000000000000000000000000000000006adf2834569c39ff4e6c92e6d3ff0b2568bc5b20d7d5864764e249c3e4ba41f84c39e57fb3c4c8daf856df96f9924470000000000000000000000000000000004066dcbfdb0a54537150f7fe994b1a2cbaf82c48eb64fd793e763fe8f5ee5f9a13658adcd582b927f8ee22e61d296021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd0e254a3e9ef6fe034f786d3fbc5a1e4adefaa03c668b9c007797fe8c04aae0610471cc8ca9df846af76ae9305032200000000000000000000000000000000016b40812a13b2c0c736585bbefa446e00b83b49fe3a5905fb1c526cce4760fceed35aec4c1972fad26cb4a6d2ce06f1000000000000000000000000000000000dcd97c5745adecfe0190d5d9717cb2ce2a55969b81d035bced4e527997331903cd26451bf96b448a33ad3870fb8596c0000000000000000000000000000000002e6c5da094d341902eab34443d829e9fbe106e09c97dc444fc738d3ab2be85d9d1eff82e02189a9458c4437a3d2b4751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018930335964a936ff68ecb8b8423f740ea7e16b358c9d5603c89d42ebfdf83e17a2e34b6893e1f699072d39d5720e0540000000000000000000000000000000012d4a4a451cff24de1e12fad8434cebdc5b4091aa3bfff60a4679a565a0b26da0392cf923475bbf4ac1620de76973649000000000000000000000000000000000608fde1cbc5346360413b14f42916b1a4e1445df29ffc1f9dabfaf4ca0d60272da82b84978a451273ba0eeb31ba22f60000000000000000000000000000000010629a8a5aee9452d7c96be5370c9614831a5977b7cce7326424d2720675c7f561d09c0cc62ec71aa666753d3039f2361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014312e8de997bcc7163c60f2c3ca93be147c3982e2eebe61f6e903f2b3fe36e4d3986d9a9da202f34362ab120b06a8a70000000000000000000000000000000008415d3357126ea3ab6f5ed47fd91ad116d0e36a9ffd6dd261265eba162ce9dd795275eefbdba5c49ec9d254f224668a00000000000000000000000000000000165fee9fab28be5dff85d977c8a7a1f53ca97388766856c3778177c4c6fbe6a64e8407bc50024c3ffaf0f9d18b5b9a6d000000000000000000000000000000001496a7eb0321eaf1cff120636340fe47212912076e9d7bc627689a18327f55ad5bd7f17d29e36951a2d3473e7a21c1241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8ca23ae28b0aac591b3ce787a9472afc1eda5a7598626601e9ef565ec6178495c7ca0a91e60de6ebc77285825178fc0000000000000000000000000000000011a2327eb645d6480ac33006a7c3da7b028f1d310550571715bbf48f230955ff3088114b736356e793cb28a70c7eeef90000000000000000000000000000000003970c4cc6102aea9cd770c66ae79d8270dcee00fc4a45523ed7745a4f85e85a7d51310b28c5ba52eed510c9c7146268000000000000000000000000000000001390f44955e77f2f54adeeb202e857d8313bc08c16fcd89523fafa53147b432059ca40373869fedda304ebb165905b7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f722fe9eb5a4448a0c54f6bf7be58037e2acdf99ec92a7b5bc0d2c180131269eadb88a8f726b14ff12b8ffe6f3c34b1000000000000000000000000000000001378a408f340d94a992c27c1f29d72469e24003e8d027d9334a8be547464f4901d8546c69abfd5b4afb18861aa890cc2000000000000000000000000000000000f9145d64a26c2c9c163372ef9ad9093b9a25ab181450022e68c18378bfa583c360c12e2c6fde9367f7814d72c76904a000000000000000000000000000000000518737c592ab80e6546f97225cb8a09d3e4e8d9c12af3a07fae5ac9c5d34aaec6a1843ea66ffb9b3aec8f477447419b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005e505cb6c28ba517bee7aa2928c10e9b683883290839d9ab6edfa7a4178d30383c35685e9734a355be332de20a062100000000000000000000000000000000096dd27df3963af8e771d7f593363b06a123c90651e42d2d319df36b63abd8b2a7fb432d26de9237ffeed6ac39e88a2400000000000000000000000000000000164f23157a58aaf53634cc0a79528415729f4cd3acd0c513ded44c762e6dd1df98bccdeaf18693b0f03ca2ff3671fa070000000000000000000000000000000011602f353fbd06e93c726f7060f344da137aaa69fd24ba098137b1773393ac430dde9a274f7d193e1725b3b76bce21b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004a546ea332ffbc8bf16413f4ef5f34ff8cd7a1497ac2b96696daad82f74d08f679b2e731f99759b732051d6e9360640000000000000000000000000000000019967c1c3cd1db9fc5638dbc4d5fb7ca65f3a9a396f786bfebaf1bcfdb16e5f171a3b5fddfdf8c4ddf84e60b8eb3cc4d0000000000000000000000000000000007d7b8174b61db9761fd152270e3f76d82a03297d256cb95f1ac7af46a08d00dfb9d10066f819dd10bf703447324488a0000000000000000000000000000000010b31d6bd727dc3d27821747e798badd57c2afab652428b13de8d3e1bfae4f4679994ecb929c1a603fe79a463d8b13f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c198e01125410f6320bf7a4acd7a640de530ca27689a44af984c9a15334c03afb96f63307caf879fe7294956eba04a8000000000000000000000000000000000654d9ea5ab3892b243a8e8bf63ffed15d98452d4ef13b60a5ef8d860569bc4b5ca5a170b18f03658322874eeadf7c010000000000000000000000000000000014c2ed0f1d27682596539894614f581f7578aec7a2bf3d8d922b66c0a436194f6ab675abb60129b9ea7aadb383857989000000000000000000000000000000001773a585761559aa03e9b37be81165e189a99f33bab22b55a0e81e78f518a0b6c099d1ecbd7a40013b02d68b96bb35771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000410d641e0787b095fac2022226bec6a5317dca35934873569c26d0aead6485175bdbba5f60c644c083e11dbcbfe2f100000000000000000000000000000000012a0eb417c707237f2f8070b675c645954fab113f650862f2c589b8964f7fa7a022a053ec073f75e720c8ec55f58c0e2000000000000000000000000000000000355b49c718f2e72ec64ca9941459452206706ac88f9b6152b5d2f6727efb136413befeae90215d60e1c5c2e04c6d20c0000000000000000000000000000000016d2e76de6883ec5727dc38b5c8b1421f2e559c3dd79fb985d9422bfdb7ec81084379b86b3f267e3d581611c2f649cc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f7e46b261296f33ab11298e40c87004373ac16a8b3626776ddd0eb4b9222be3611b2ce9530f63383a6f98b1d79c824000000000000000000000000000000000ddfd49dcf4476f13c90e92cdcbd932c41b0e262bcafe6a4fd68829d279c7cce5ff0ec8c3d419836d055dc81899a4ac100000000000000000000000000000000144ab9a165388c99ec8fb6ee42e166699ef4221d3921599ee08fa8513fa8877d427095d3dbc1cfe3ee087b9ee7e8fd4900000000000000000000000000000000062389ee0d36bccc1e18f5263091a2a2b1fbb15d2f395fc2926d5f01a5c59c6d8f50db7ad33bfc6e9a63cc1646eb08cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002029250649194e022128b53404b6b532fc06f69c2b5ee60ead3cc60d91c0627af7ddd615256d7974d0eb1fa33a8005400000000000000000000000000000000005816dd76bcdff34b0cd1a23987799844d64ad61cb3ed9efa8ebd3676a4a7f5c7647ca2a6dc4f6bb710e76b1765cd1d0000000000000000000000000000000013cae4b0ed5ed32061cdf024e10c170f383f0c7e9b21b2f2842d21c1d1e6e1f48685518d0c88fa4bfbf75aa513f3f0af0000000000000000000000000000000002446ceea2cd71fe39f09be26ca1cdd494780c586cb222572851f824105b7a0e820ff079dbda3eb180cffb68c32820411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003aed39a259e4c3568ad4ca6ca031d0bedde6ad5e7c72b7ce55aa508c09dcd3b80affd5186acfb981a1d0a84b01f770000000000000000000000000000000000043757f55b145bda8efc3208a450a3a76ead947ff1db47ae240515fb0b251769626b7763cba369ac70cfd6a3a07e669a0000000000000000000000000000000006e946a24b46d345d84aa08df517d05a0883a8411388561a6e7ee3089b2dda4af2d690c0e9cd9d13a9a7f77a3988352200000000000000000000000000000000156bdfeb2cb87308f73f3af162b7ecc54c822505d9a62ef2368c4c4daba4b5caa1c660b177f336aef6c2cd18142a382b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012eb74a548a1d3dae079e689ebcf3860bbd524500371f110af5becb7d4e35d963e41e6ba4f990f3b1afd9a77748837e20000000000000000000000000000000002f5e9645275eae3172f4d169d618adf94e29679d31925df042deee5a76df489bf7f1ce143d090f5b2fa55a9ef4ce8cf000000000000000000000000000000000ff2a2e428a9d4e78bffa713da5c3628292cdcfdbcd1b0f76e84fa6f888c178b02356f66ba66af7617e7ee1b1af62732000000000000000000000000000000000e3aa36b217c9984496d67aa442546ba3fa3c94904010f27d38b48faa6db6d9a356cec7b5e2c7a9972d4fd0e6576006d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dd3ff146ac7d19a5343b1988e2d61cde9d073a5bb69614e12f61fcb3edd07058d983d286c7750ee7d322a4b48c3a3a00000000000000000000000000000000038d8d0ee045c379b8f1e03a5266be5c56adf2f877a256b96e7d86dab3d044706d4563a0f89b397997098a4b870704980000000000000000000000000000000000ae3d39dd2f6e211a5a7607768cf412ada6183d114864d9867fe0b756bf778e5d64dbaa12d8e469232e184e82259b680000000000000000000000000000000008e98ec751f9630746ce0cf76eb60988dd598ecaeb4cceb1b104249d1e489dfbb5037709d7942adcdffe8332836dce181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079738ac68fb9accf8e9ca7ba392d765965b5b8e80db2135d2b61f99509a7d56e0e1743e7549ada55fc93d251790bb81000000000000000000000000000000000b80ba11e833ea904fdae34aa6c85cb445d34d56a9dc85395b144def496efb79fdb83c1daf2fba8f9f7bad2d75e85857000000000000000000000000000000000a8423ae8ca4ac2a5a96bd2eeace97669c5529a9496d601f7390e8d934053af12c9c345b00e9b58346e057da116d68ce000000000000000000000000000000000a5b6be744e34e62ba5d8901a58d8280da920f06ceff0a31e71df6ae6ef6e9df40c8fc6297d14593403eb279a62c6f371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c0941f5b6529a4cdcca75761e03c633564a46a727994b7fa98fc88c08b645f5b6bfa15eb6cbbd68c6d44cafd6616db000000000000000000000000000000000f6f45b3eba6e24d28ffe0fe0218f11e5da6537c1dc1d9abacc5c4477ec96cc3a06c035f9ca75fd742af1e550cc9341c000000000000000000000000000000000dd39c6e93e09e0c9cf445796387649f6042c0a25c0ec2b354f56c1045691b3a2e3b8d94619cea8c5a820be60e8a28170000000000000000000000000000000007d76a1cf79f0dd7380de524d909a24940daf36acce417e8c8c0c33eac57ca246283a359a4bf6533b963fb26d5a557121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119e06ae46adbdeef04d7c67cb860136a91c92c1bed8393d0a3a07159828cbfffbda22c3cfd68374196139ba21c85f4c0000000000000000000000000000000015cc4ce7b76c1605111526dbc37298691d8493391168739eb7a742c55b8c25013c6a0df9578949d61509f35ba463a3dc000000000000000000000000000000000a8b0a36df049be37b4f0866a1f41159d8dd9d507544c1267394932be02e11502cc1609f64338c8d8583a647351c11240000000000000000000000000000000003a80c653ca122873ea273b3a1e0764c944b542414baf07745747b7ce29953ab82e4815af7d9b556ace7a423c7f6c5ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7d0f058317c6356dd2c637b29f305b0c13d7cf173a3373602622f953955e4cefe661e709aa755da700765a74036f7e0000000000000000000000000000000013c09a06ba5793083eac5d26d3d6322301f4b5c1d28394bf3894b370c6b8971cee2d83e567b60fbca66b26c417d747a00000000000000000000000000000000003aee9c68ad01518fe494e9898fdee7d321aa7c5b19e56b47689f3b608e90dca019d552dac286f900dd86073d130403e000000000000000000000000000000000819815295994857911f23ef11aa4c3e87d47addd68632c8baed783632ecc5fc0334f83ed97b27c1e0e2b5ae7bc260f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000947a7d5745234134a6a92fa82bb473952993970676c57111f177a25f91f7e320debef01793b695f9d0ba9e4e58d9fed00000000000000000000000000000000017a716846e63bf0eb295a0d5130b76312698dc014d2fc81ad1547e04aaf7589d2f6086401d067c308ef5d4af0bd95ac0000000000000000000000000000000015d713e8b563ebfd793a9601d9249af5961a5e3d9847f66c092d131a96fd2b324849c0a7cb7d6614c6c4e579eb5b26f40000000000000000000000000000000007447d1ffafc8f2707ff4ae54b52e7698478c6ab603bee5980c8d752be14a50710aa5db0f85a6c5d5a00d8274b086bde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122d450b292b6490a838b29a66a884f284f41d7cd06d10c8449762a05de84ec60f632aef87a98341d4b620413b6321810000000000000000000000000000000018753afdb6d354cdf995e8ce5d6cf8c26925095138e9cdcc036d29baf371cc767c90073748944b99ca3e75e4262c6e86000000000000000000000000000000001616f322206a510bd6cb941dd5b356002d9553ee380bc696aba51dde1b4ebfddee526c4d053d4c332a4d3bf371206426000000000000000000000000000000000e37e8bb5392c95f842b4dc5ba20847b395dd655c52273c1545b88b73e776405712d9e2c5958b664eeeb37a0cf02e21e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ab751f154b374d605f7578c4f67373ec40d7cc92ec4da5147187467eea751d367c882175d745886471c0b1096b8461000000000000000000000000000000001067bb335c4932df6bb43cf8e7da53026bdf1d7075e7ae437fc71ff6e44dd2ce8ac44e2400bd096f3ba585de00982b7000000000000000000000000000000000039a4e4a9e5b004c783cb8d63ac99a7d2765eba6e0e23c165257375b6d178f02baa400af6927a6fa19d1324069e0b0de00000000000000000000000000000000142a9b02e7c0a200a1970d8c692eac5e9f3a0c01168fb77201c25b72d50713e838ec284b897a5c1a95a25aabb226d73a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a7b1453c14088090b02721ad06a420df029e422a93a1d6c810a4e8352d1bd724cdbbbaac5b13483e83b31e5e4cbd9e0000000000000000000000000000000000221853aaad3007b02e306348b3d94eddec8bc8efac253db3c30916cf57365daad5520df40f8cd707c5db75a7244b43000000000000000000000000000000000f08805bff583b845ee4975e882c3bffe7f8e3a85b68ca5edda6dafcb1bc512f4886ab82ebee7b3685a3ce024fea2a820000000000000000000000000000000005f1325a3287b7c1908d7c55d0f6b336570df5634602beaf60f6deff7f581ce3fcba2ea1d92fccf35b3dfef8e290fec81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f205bf971908ecb4a65c4e63fc306b9b461e8ede63a68c561dc1d551df3081bbee4cbe7172a77ea1ff915163b3cd79300000000000000000000000000000000073bae42f2a4660e23a2cfbeb736d8856846f5b52791246ee827a0a08264cbbccb5b4f71a386f839c495efbcb8f8d64e0000000000000000000000000000000019abd20b6310c806cec9bcdcfbda88de5b768ae0a7586a8fef782ec30a6aa46c39565016c46820fb3a022e7c9f4c54e3000000000000000000000000000000000e40edfd794d78a8a12e5554102cece5d913d9d73a631eb5bcbdb454e83f25f95186c0d473c1ab5285a69fae7e7f5e231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac3f140b916ac41f4951bbde752373ddfcd16bc8751513b2b4dedb0701a8d0506365729babd550eb5a0522fe33eb9450000000000000000000000000000000017bd5b18f07462c8125d319d6114581a5bc062e875cc4923332d764116b046ef3ce5291676e7320a637a51402519d0a700000000000000000000000000000000128fc30d5663160462ac5c37cc7d78b283f581e8314c95483e127cad332c9da6ef806d0fbaa9bc84c2e9300bce8a54f300000000000000000000000000000000108dc8e698873a0986dddac9fc7df093205a310814a3946333809f59530b4e693c1ea76823eacd23a88c1bfd0e9e2ffc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001677afe25bc2001bb94ad58564ea21d03ce47e8b9eadf1aac423ae503e530a5293620859826fb9892d286ca5a125dbd40000000000000000000000000000000016a9b7045ab93e06029d496f37c0734d281ee42bfccf51dc205baaae5955c714950eacf781d9d2b988fd0bf824e7497d000000000000000000000000000000000a10fef925eaee2a04071b5541202fcd6a682c595a92442c12d11ccdabc7b856d840e176d0f6e72471b916ffe7391b6a000000000000000000000000000000001199e205ede10a6c03a46948679516b0a7233a060f09772ffea5f9599aea2b7ecdf43114aa971f7f6f5a16a37f0d97ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000918ceec090ed53acb35e344936e5596cf2a49b3012ac8f3fd7d567352bd7732795ba09ececc03fb85855734012affd60000000000000000000000000000000007bd7b4bc967ee3cc426a2c88b38bb9f128e38eeb3385dad84294d07c9484d3b950d074dab4d050991428e21dd9e216e00000000000000000000000000000000045a843bf4dc5e48ae5dc86ae52d5cc12a90a7ae793088c3a8d116e282b3cfe5807b276e9e200ea56d6e0189b2cad68b0000000000000000000000000000000006c6a4fb70531e80e2a74a95ab73671ed1cda57c09a288cbbd5338a3aa5c5b9a981dd598da0150be5312fc375132b8541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001214730589398bcbcc6ed54a42bcdca922882b2de89cb2269b17d05373353a27c7912bed4e72c523a86987086d16601d0000000000000000000000000000000019837596c1decae44ccc730825f089dcabd4c76e75af7d60bc19361b48ddd8844a1b514cc9955970fae28c1d644a7e21000000000000000000000000000000000060fdb650d58ff7d51630882be2824f99edbe66b5033e5ec9d2f31fa553ebdb6fa449278325f142234e77a04a5189bb0000000000000000000000000000000011e98099d16163377acddc2815759e49ccb966a8f9c576e76f170052ec657ea430529e38ec45f8ca081428546b1eb5f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc737a7d8f52197ecbc2146e824af51195d274a54e9e5dbd69e19990e340220cba573f5207dea8b40721e0f56f01f380000000000000000000000000000000001542b62398ff36b3b8728aa7b3ed6804ef413f23bb7e12ea15878f02da86a04a6e9d8a13efc269d8c14581f745856ef0000000000000000000000000000000011810c75066175a635f0cf7754d2e33a1908dcc9bbd7cc3cdac75ac833e8181ab0101c6dec9f224c9aa5574897ff458300000000000000000000000000000000001e094ef463e9a97defd4d56ce3ca1bae2e0a60dc41f73ce40bc079d87e8af49efa159dd9e8342ac66a6bdd6130d97a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048a6225474b874eb2da78811c547fd1e3121c0b50bf6796cf8aed75843d213d697b7d191638013c76f84c471226e3cb0000000000000000000000000000000011162f656c6a7d23f088d9fcd49571916d22a7e6cd3ef2fe86ff726de1bb17c0e7b0b801177a281b859909c50ff0b25900000000000000000000000000000000170be00763f37c24ea9770e1b0d65f0da228fa3058182492d0d76a412716932da3aac7c1475ac7d24047c010c75da50100000000000000000000000000000000042d05e315baa0918953cbaaf5e0405938d530da7b2af79b45d08a7626a350a805548404c227734fac6ec3d9efd275a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c324e5464d181537d0927981369dee4c5096f954c3107c8f833e2b7dd074ee5975309632bae27cb9e9c4452839cf43000000000000000000000000000000000327d814b133e3acd46191a54b1f76c12774dc94b32abb981eafea3fc4973fd9f8b51e6d4b7b2223fdf5dac13993057f0000000000000000000000000000000003acd25c84a06a57d1ab647f4696bad89008700feb71ff5113d33d27de3e8c10cdb76163998bb524e264f58b8023f98300000000000000000000000000000000098f58a050b09257dffc6a0719df7c981d6db50c613c6e729c79e68bbf56cc906d57f13e4ad5c6185492ba4cdce80aae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eadd934078a269b9ec187565eda0995cc5f897d787c0a6d9920795e7e5fd78c1db4a539e8a5cdafae345c6dee076175000000000000000000000000000000000603e7eb63cd030b17165b5552d3cffba2c7e203c79d326a670bf2ca8fba23a61d4da57fca5dc50f0ce7c6979c572d8e000000000000000000000000000000000999ea045d4d06dbe91897679e0be156630a35ab621b608d42168e830ae98c24c24367b942a81f49c3380d93e059e1de00000000000000000000000000000000023104b2cdb9b9b5971c83cae56276f84fb6025d999d6ce6dee6565a0c7515e1623392af69440428f3bb2ffbc879a4371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026edc1261c971704203e2afb96040e4a70f6de7f36fbb12d7d4a81df000da1c5697c89d8a40fb4e5ce369776f72fef5000000000000000000000000000000001210276e48310085d930360a3fbf64af7d66852709484284ec21a63021551b7473c6cfcd0c616df74d983037e9feacca000000000000000000000000000000000a26d98b75d0c6a58f462ed42c3381b63047d2f0d84fda5c6b6130b3fa562f88170546162ca4da276e7c72e4c20756e30000000000000000000000000000000002823783ca66a90030f57c021008e57600a248ca2b6af1e4e0c57a60ca5d569584a64fe2b5d8bd2960500fe823ddcbbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191c3f2b41c25376558e2a3d49b793e24907867bd44a5d19f904d564225562a566d1f65a8ad27ef52873355b63f930400000000000000000000000000000000008c325b1a5a34ca08ae1e9adc5743a3dd773eb221f11ec139a7befa7e40f32743db72e6584fa7f29a8b101e6edbd8d650000000000000000000000000000000019b8ba112353022bf86105b0bc2ef57aa723242510d368f989adeeec423a8b5fb49f97f0866ec6234c45f744b31abfd9000000000000000000000000000000000915abfa431c9f0aead9448094aa436f93b6296dedc09f3bfef135771ffee99e7c15b998d79c408fcc944a370db8a2d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014ec8956700983e52a2c542c1dca1e416f30dd70c9e2bf7fc06d2385f0688989a17939512a3f06ff4baf7c28167e0750000000000000000000000000000000009578a388e8ec2c6eac0b4b8041788033e92ede9949ba4b2c0877407fd1f08d46a408e2fe8052a6f22a677d8f120d1860000000000000000000000000000000009ba315c61fa5000d2810a2ce4807970dc369a7a555685345ea225e972e75463e6c4bfcd67880eadd92bd29b469b6c6d000000000000000000000000000000000590415b52aa566db9819046dfaab890988e7aa849cd6a2a984e0fe3f34aadb2d9f9990968cd5d231227c5da6e3236421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a12b6d55161025d7124d1010d94a78c2023489b306a114b9ce5b6d92c7b4910bc7081fd8f1efe365f5380b83c6bc9b2000000000000000000000000000000000150deabd12adc63180d68c2ca320bbd5e13b4e6f1f5c08dab6a01ea6976c25bdbb3c7f821534b1bcf67303a6117e3430000000000000000000000000000000001622f25dc9e1942f210ae3a2c8d211879534605733e1d6895d190befe51a94acfd7281da48b49305b37be002692d11f00000000000000000000000000000000043b2de44a3114a7d778227b87cad83539dc9c2ee591f5b12867bf0a7c767d3167eb3650d179db0ec94c51e39bd271d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a366673494482520c33b209f32c884eb16bb28f3b84b0c814515fdd81f5a24c75ec036e29388068ddbdbe3f22a892a000000000000000000000000000000000c2fbe0263cf4dd2b938552ef49ca435f96dabfa799b09f234dc3a77d6dc3b616e288d1712ee51e08f5e24ad3fa184b700000000000000000000000000000000041a6b57f98541ad3415eba58c7796a850132c4028788436172c3ad39e792079a3d1427c6ed968bda1b84b95b1f30e890000000000000000000000000000000006605f6d887052822c1c67e9d327482a3f1efc29ff812fe4d929bdd9b055c0587544a2a646c0d224503a6ceccecfb5461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af33b7db5b9f73006a38559b592e1a7020f4a7f4be7428e27000c3367566606ee7d38c32bcee41c098f58a1b1076e4a000000000000000000000000000000000351d962c78a15fe1daf5e2b865e928ef5aaa3cffdae9f97d3b21acb6177d39365b375fd04de7922bcba3e5da431a7f60000000000000000000000000000000008f4697a47749c2cb8aed7f0b71d56fdb4f2c956fa88e6b5fced446529513955873e3479706cab0815447ebb7fdacfa10000000000000000000000000000000011c17b8d4d15586bad4ca93ac2e744043c59899c8b83ec38e3f9aa989384ed9daddcfabd75842663968bf32f595103ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dbf698bfaabb9ca004e08a97413bbb0c1ba0e95d9f10b0776746f38ce9fa8cc0436cc8027c397af2a14236540544b2000000000000000000000000000000000f1e697c01493493fb566613392b2ecac783e1e9167fd3a58dc4bf059d58132684559cfacc6f814546630bf50eca75c70000000000000000000000000000000011d31cdcb0a0dce0c26d46966a85e2f9055df822cb552a9a7a507331b064861882ce3e011ebe2711d670ecdd0149ce460000000000000000000000000000000019847a13b4e9c1d4c2558dcc38aa99d82585d9fe275930ab9cba66f099dc5034eeafab71002509a86fdca96c166015a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174053c2a210af01ed770e465b91c9fe68cbb4ebc66d7fa78e59ff2020f4bec3bc9b9b334999061768abaf45d47f91c000000000000000000000000000000000186e0c335e42464c15be0906241ce4c825000752eca97e75e5f9aea54c08a17949a38e95bcd2ca22052fd72d834aa55b0000000000000000000000000000000002dd632e73f60bdcacbfb283c4b31e1b13d445b07d27fe8314a9fed1d92d31bdde67511507fedf32923d6701dc2a06b40000000000000000000000000000000001208baba47d33ae9a759a975713fde99ed83753e42d53e7d605d62ac559f41ec7c1e6744cecb4692b53e6abb504a68d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9d16daa2e85bf133889ad7f1d6f0c109785f9a452277df1b09001e42290305c93ba390b12c01859f53a65dc090f5fe0000000000000000000000000000000015683968b9536b8e9671e73270fcfc536800fe281a00d0ba9d94857f901c5f2597ed0ee83efc3b852f542d209c8c8b6e000000000000000000000000000000000ddc09a6a07e48f8397e420aab41ba83b252b87cc4f2c3ab9db72b723186cc58b8c406e98e8990f8aa7f34f4d97bfe7d000000000000000000000000000000001911af855f9286c3d267c3ef5f754dd478790ac984066e9da6fe94b9a4e0435f5324f2afb27a7334bcac4bc16915444b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea86c0d9142263fe85386c4635dcc0370cde6bffddd6f318b3065a8f36de77d9350bef213ca8d35f2780f0108eab75a00000000000000000000000000000000179428fc33588671f16fc336153cee277c14d2832b985d4d2f7b241b60ba84934564ad8fa64a51b69a9dcb3889bf0329000000000000000000000000000000000830a1ed942f5798e4b2f9d4c52c499a7e38467eea256e4ecfafb086863330857cefe616a4f8295a7ffe284e6d6aa01a0000000000000000000000000000000012fc90b45a63fe384e2d4a28be0ba84c864c1e2f0017748b4ac583231bcc24d3f3f3789f0626af958aa9b853f81a2fad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128b32a0869dbb75a60e111f477f7be506e2c1dbaf60077aaa095708f50d46f1f798e906aebeb61b1de606dbfeb69e01000000000000000000000000000000000b58c2ccc697ad3faf62cffae10b19f397a9cf06e48c44a04fd88e892c94ddddf84d4ff5e704fc8dab885c7191d60fb000000000000000000000000000000000082ebfdee49151e504b0b655a331b3a6f7956f69c9743bac327ad3c409f074bc907fba028b666c7038cb201ff4d80a200000000000000000000000000000000004e7c3c30347b99099171235b9c1fa984f46a4ca28447d25c3e76607234b6c241c54295ed5d02a8f9cd1f461a08af1871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138590925d44de1094c7a96e4655f59952b029596eefc866fa7ad4d0e01d921d522e9c1208e63dee1bae32ec3326fe770000000000000000000000000000000008845e0b9815a4a52af52816d5c16321d6aaac1c626e0c6a56f87ac3eeb3258519d3dd2187ba7eb46b26498c938c1ed5000000000000000000000000000000001523105e3b6372f95b245151fa3f88d48c807f07d9923bf7c070b91dab92a60b632990ff7fa6c40c6ba7e563bf9136f1000000000000000000000000000000000b12962452ef2f26b4177aa5e5865a67dc7991566fedca688d328c81b6d371470df5c31e816d23e92e68be8efa4bcfb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110b50fa5dd26e83c68db04901f9582d31bc2cfe9bf1aa0485e778a4d0d3a0c23d46c0618ab7cee7a99b045d81a50cda0000000000000000000000000000000000cee5925904ec52e2d1bc6d85c001cb6ad950872f5ad62fdc3f43d786672f6d49b09919d24955a3fe0a0c32d94c28690000000000000000000000000000000010881b06e37f254317399198d97aab0199063e32e0356085fd39bfafbf940a82884873c62fcc77358baee9b27b74be6d00000000000000000000000000000000008e345b7d8c70b4e5d73747d2eda4a728c25f7daf95908f5849f64cc55f16e833473e058f003d49b988bcb9618d56871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d26eb9b04cbf4ef20ac9971c07e097bf2aa2c7a5a7414b70436b2d224d7dc914230f6fa11ea0d09336d37811a593f800000000000000000000000000000000141962f5d7779326e22ad5f832e45cc722fc855bb9a2282e0e8cce5c127da56349023953b5c9101278708f72f6856e8c000000000000000000000000000000000349055eb7d7daf85d67ef573aa9065b54e27f2e604a3b231cc79604e2227674ff97adaa85dc8b93c1e413533564485400000000000000000000000000000000157d8a568192df21246abc0881b3ec5d923ec01cfbeb3043255361ab8d3e511f844d536f85c3e4fc8940c4d7f47a99451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0990ecac73ec5e0f2a18235ad112cee766e077e6fec2734a7c8a26eff5df3cb086e31284a57e100c9289c977d990e50000000000000000000000000000000015d3e5aad870be61da6c2ef5bc7576a899d3dda98ffb44095ac6b0d5f3ef5700dda3cd6d337a313859b4c20f43b69809000000000000000000000000000000000b6cf8bf5b9a24094f2c5552e6bb7719c43642e6b49011639e627422025074069940a0f5c081d8b7a81b1323e46cf26600000000000000000000000000000000132111b9738632e6324dc37d28f26c4f6056b89cdf0c3fae88ce8f2ae4fe45cdb142c22d4e23a038ffab79b5e2ed52f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190343f783e1f07ae0f1912491fde13c97b9ce6e31f36b58e85ff72d77a76afdcf6055255e4649c26d4f551f8b50714500000000000000000000000000000000010d32ec06a2c8a0bba5aa78bc1aa4d6245e7d0926439a19e5a8dcaa0098a405c6f9de55d9962998aec93458e88930bf000000000000000000000000000000000f89b7c96a73e04d78d8b830b3a3a9053b7cb26435e600566328fc00f7aa7d360e03584d266a237ace3181d4670cb95d00000000000000000000000000000000011f15205cb90f8172f6a20a3e8b79f1cf24d5e501656753027a1a10a348e73dc0f367159f2d231d61fde963a0facf861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028d061359e877e5e0b47d483ba7c4300e165bd82643db3c4080c6687f0ed0036bb6824c5ae2ed2aad3ac23931041a97000000000000000000000000000000000ea1f117083d92e37dc5c4f18f382cb9c4653e3e310e4aebe8376cacada879bf78d02264d818b5d66a11751577443eec000000000000000000000000000000000446c345cc07b77c126cab545f81bbbb2bd032f5bab08f48fa20a89b2f74734589f5724af7ebb3d3ab8029f8ddbd61c7000000000000000000000000000000000158641fcaa72ba48f3b7679374bea18a982f3b7c99ef9a3905599cf265a22a098f574d51b0c76db5046375a198172ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ce5a15102f54033d4d466330e84c69888a3f85b565d2be3cd94c07f50e2ec49ebd8693a27fd6299efe11c9697ae980000000000000000000000000000000000ccf06b5f37a29fc123d4ab2e93ac9007bfc8090101ec836eea6b0dd134658927d4e564d20165583427b33fc831e57cc0000000000000000000000000000000011152f9a638bf19413201b6d23d0a48b62cea08483c07790748b00b94fc6da4c4dfb44d5b9e99f79cdafd49e8de9347b0000000000000000000000000000000005b86e7d7b9cef3577ab1334d3135dfec56608b74c379da56baaadec95a3a756a7218554242ec424f85ca1bdc6b482991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008995fb9d42e98ef10a903667b51264568ef3f94272d96525208bda18b53931feaff4637ae5159e069eb87d6281586cc000000000000000000000000000000000964831905f925e37f68931b28dffd4d3a90041ca45ea1f1ad4c3bfdc1119c5f3b0315d9f5e8fd10a1f67bde61bca38300000000000000000000000000000000051482c6c3ef5e5d61ba4a9887f9e7a1676ae7b75de2d7e67fddb3ee768e9e0aa2ef124ba09c9276c463b1f5dd6f5b9c0000000000000000000000000000000018977c22659c6b83ce7cb08de4a5823f5bce4d519b68c7f656773023df8baf75d4ed199fa9cbf1cb9ff656fd8eba96be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128c4e9b32d7bfe385b98110d836675017602a42e8df4f2b7e77e737ebfef996090c0ebfd1bda3db070c612befd51f4c000000000000000000000000000000000db615e4c3106bde31029be8d7f5b5c76ee5f5ba8b7d702cd64f0a047b0d1d80ba97d82db1304306fb73bc9a8140af4d0000000000000000000000000000000008cbf29a7a0ec4ae170640cea4801f7b3ab7c8ccde680838b06f81c655672e9aadfbb608098dae657df1f970a6107f41000000000000000000000000000000000f7c30bb58659b39dbf658d742e4a2205dc65132692fd7d72859ef97e465c958c7bdc651c63778106a3d9406764b53921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000259e94891c1fbec71412fcc61e37b29a42724cb7f90c7c875d96ec06d112cb98d24d771b7b9609175f3deaaa7965880000000000000000000000000000000001359ba3648beda0473c81d10adf3a85889a2a6fec9c10b5f220154fa9b8a624b576c9ff5d64a4cd8d17754d110c181680000000000000000000000000000000005b100daef0a9a86e81d7c39e9bc4c803246a0b8756471b4c7e0e1349074ec1103453dc6723d63d7b13c47daf1e2d21c0000000000000000000000000000000001ceae1ef3bf4500ece7ec465172c4f8aef90f376a0b5d9da5178025c601bafac663b28da2172366ebcf4be9104091711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050b595b77d2d9f109128c8c06d010ae9b8b25aaf8658aeadb51cd6f83346d7a021d93c74f764abda540e33eaf1f0f4a0000000000000000000000000000000010365c72ca04d22bbb30c79537b43bbef502fd75505b1d90b157a0481477ac7edc14181cb4a3f74d257ef0b2be6341ea0000000000000000000000000000000012da222e5586098fed478d3ff55f8c6a8ac89f24e6d92b5357da0eeda4cf0552e001e932054012515842e9548be31e7b000000000000000000000000000000000407c50f2da3f27a8794eac8457d1af8a2885fedf929a1822acfed6af9e0800712eb1d8d14b6e6e0a99cfce84d8f55a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff45aeeb951e36417ef7f1c2978c5430f50b5361e3371d20e2740e2784ac9453ede05704776b133cc649066217d403800000000000000000000000000000000150ed0351c03dd47035c19233281f6e09a1d175c90b54c95142f3e2ef6cf1c08501647e575ac7f6e531180ec26efc15a0000000000000000000000000000000013ed61f0563217180c85f57c62d822139e6a6bbb4684dfd98f0c9eeb053439c447eb0b6f4c1105fabfaf77b1cf5c5ce7000000000000000000000000000000000e1ec166540d0e5cdaada7d7f06f6531d67ae34f784ee56154c1fb4a403fa27476c4516df659a617d44f9f8c7373d2311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001306911074201c6fc5c7befd1f1322edc71eca8aace4cd00edddb86251a03f7d195496ab87efe206a09b18e78b511369000000000000000000000000000000000a34e81ab13d9388d0c22dfa481842adbc36643960e5313d1ec7ff2bb8f3fbd2231b1e4a4fc704cb26a7dccb4b46ed7b0000000000000000000000000000000004b5e015365361589e4d1023d5017362e2ec60132da4f995e533840d3037e155727343d94215897a8caabd3f3399334800000000000000000000000000000000152bb3a60f6df60b43bcf16b4ea92c9af7f2bb0af325632e9882b49df12d8ecaa540b7f1efcbd28ef6a98eb7e8e471111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa8657f202973be657d76c5f04a6b2003652a37ef1e2ba1e4b8ea28d9058bb56516d000b8c1fe5da602ebf11275df70000000000000000000000000000000006a61a1ade9dcaae52c7168eb4dc99eca1444a01d34aa00e9234ed4ca5578460200a43be568943817f94e3bdccd9c74200000000000000000000000000000000006d00305a5b5d58a9d7ecfed94a14b53f7ee40b3d1fd471f42edc3509f303116357f3e914dd0625dc8b16b6d37963f8000000000000000000000000000000000ee4531ad2131a6af47928b7565ddb06f3100e1b773286a558a0f8104afa928a65155a9ab7ca3c641fadc0ff2d5df16c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ece19b680195af6a04fed72fb4f4b053a78b229ec228dc721b96cf64138763374960b2abb176fd2f1a4cc17a9db130000000000000000000000000000000000efc31e647e5ab9d6d2c0f1e0b150744d0f646c0a8d07b13ca8698cd1fcfd03bfb495f171b2fbd05e7fefbb2a66a79a3000000000000000000000000000000001512d2d7b745536b2e11ad76096591d8188310c1a12d9a5502b7ab288806182dbaffae07c996a2cfd7417f68df13b0230000000000000000000000000000000002559ad9aa48cc71e979b24cee9b726d2be63c8eceeda88dc6fc38e5d8057f3ea07a7c3014da122ddb445fcd455faff21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018efb469a3016d798d2e06f2b5bd3bd9b950398abd6e99aeea62b81b7dd69f239bb8f840459ad1f133ff99bc07f10bfd000000000000000000000000000000001868069b022300888a4232789d8f4b6ef18b80a8bd169eb428cd7d901bd9e5298e5f175b7feec01417634c559065fb2d000000000000000000000000000000000c38e93398649ff7bbc106bc8879bc128740b0e99deaa19088b7fbf714ee0e5803a95503f64eb6fb9b5db1002d4446ae000000000000000000000000000000000476664b4f273f369556759d445c36818468d95b17d6cdb578b02e48014e4e50dba33e1d788b8477356964c0d3ac1d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072d11e49ceff04761075b5bc7baff4f29358c8add84eb9345f549d20ae187d1364d0e90a69ff77ec6671ac5ceece5a7000000000000000000000000000000000cf0db9697145ed6675cf566ace767b3aa3bcf500bdb7b83a226c6564a77982a66f326e7bd96fd38c68caaf1def3f9880000000000000000000000000000000014f29501e1fba6d83667bf0f375e86616c9b8664b0cb3b063aedb182f00f681ad968c3743a226e5a553e6ea6e1a7513c0000000000000000000000000000000014162d123d9bfc2011e8cae0907d34fdd23f81fe523cd405bcbb6c3afa6870d6082463bdb1c6d6a03fc97009e54ccc951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f79a1d41d66a9c297cec3c6700118e1e6f8753b4bede4c4bf49c0967bea8b88f2dcbe3100127873ecaf818bdc828530000000000000000000000000000000009cfc26a7c40ca7af7ced150cc8252fc7255b514cbcbf337c2a71a718b893025bb97e8536d0443ba1be16a9970faa963000000000000000000000000000000001914cd6232cba23e7ed1e4d3033382ac5f294258a582727a6965b4b6a83df4532c75d815027bde64e6531e3e8bc1afea0000000000000000000000000000000003f8defa6d3005fcab86545b77dff0f07070df0f2f11121a33bbcece40a05be565f189b4251067c380ab3822be2237ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebfdcfda8097e504d1af86f558ca2a05470feeaeb8324217490fceceda9a734583fa8def330c525522c78b31e29fa7a000000000000000000000000000000000310d9b59f6c2c4bfa8fc93d19bd25b1a52549825d693c11c24671bfd8254b8d0fbf56797d7cdabba838620a4f196a2300000000000000000000000000000000079092b483f43135f66d0c56c89e159b7cc9073c314e30ae4339f6cf5743970d0714e61ff9904ae4876dd050e0cae5f6000000000000000000000000000000000b6753396bdcc6e1ec4889d3e387db9cc531295af8d1b342854307316064a082c0b9ca4d17d28dd1bf859117ea3444271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e10f8260ffeea3a67d97b16d8fa7cdd998574d524d7353f7b4ac3f84144ea06d02e0c79819b2fa88490030611fb9df60000000000000000000000000000000003de4a6f22fcf08900b1c567275c297e18f68d8910f35ad796783982852beefdb026345f7c6e99446e318de733eb87580000000000000000000000000000000019634d1c6f0c8c13f3b9e8f886f4df9978c8fec85e0da460e3045f2e6e18313f688e1c49bea57d3b592c551b7f8b4e4e000000000000000000000000000000000b64bced117c9c9706f1176fa14d06e64b744d4fbab32724c18805a6eb328b99be8b8a291a89a0a17113f1c1343b19f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091f69b517fc60e9f42d6ba5eef840e0f70274807344b7d8f245f7eb9f7bb3c41117849923a0363fbb4a9539b2ec7692000000000000000000000000000000001347e16462a3c64ebdad419905daad06b660acb3d260cb366ccd2fa00facd142e90c7453714a5b409b8d0eaed54260630000000000000000000000000000000017c5063061285d7645e59c59ac251dd1e3431099ebacde7d115ac7e10dd1fc30d99793a2b9c163923172a816a26fed510000000000000000000000000000000013062499401e6da94bce3e5dccb1e7d9934d0f53c2d52d86c18ccce7495c2e5afa423bb77c20ad394612517dcbdd47b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ca8d5dee12cf738f2f9f9ecf53d6c2eacaf8d75a492b71500e1eda35da7184ac9ffab308b088f20dd58b551e1cf0d9000000000000000000000000000000000e1974b5a749145b5db2e4ea92a2069d883ff1395cbe86c1b1fd8ce805528f83be7f6e930df5650dc64bd07801e9fc11000000000000000000000000000000000609542cef4458e08646b3cf17810f78924fb8312e78c1e103c29f8bc1abdcc035c60e80ca7707b9edaeb99269708d2a0000000000000000000000000000000019bdd888ada82bc286625bf541bf77eb35c2da7a6f8976bce668de54abc487f1db5c430fd5ffa493468b5e297fa173401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000630ef92f342dc773dae4651b6fcbef4c845575807ba9cd5b8dd6f981cb7fd2fd4b163dddea3972b04d23887ad974680000000000000000000000000000000001fb32b9489d3fc282b2a70b2cec39d99315d186593c3d304ed26c0b14fc20fa54507041dbf43394f0da96a56a0a6cec00000000000000000000000000000000022c499172f999be2af9a93089c80ce7fe57c8ac6e8610978dec5e495b64bbd8ad517a1a61587dd72d043eaf914922610000000000000000000000000000000007939a48a63ffb43539eb30340928d6c58110f4f557f8e4daa197ebf4a0fcd61f822b3b6a52773dfb9bde2b8d39ebd211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137d5e6ea7c1dddaec5baab08057120b40f196859bf80b5918a2d6c8a3606ef997acfcc3fb66279c5547a55888da2d5c000000000000000000000000000000000b59f58af7ba84ecf55e34aa54466a00e3f998f6f3651d5dee1145324649b7d8d82735e903fa0725c39861419a9ff7b400000000000000000000000000000000051d0cef4f015624d6f77aa843e3b56ef52e5850708fdd77e0c7a0741147c9bc4b031d3397c93c246de9491e9fc6c021000000000000000000000000000000000254db2ea46942d91266c024da71c90893910483d9c9c99e3f8c31a815ce833f4c74744b2e88691bf188b172c6ab621e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f112b4970bc40e072508f6f933a201185ad921b2ec5a3439a0365c6556fd27bb2530b662f1284a561a5267ffd644fc0000000000000000000000000000000016d5ce6d71a3535dbf5be62f1010d5c47c54e9c8b357d829c140002839ac6ab2f3c6ee137811adf197047c1664f466810000000000000000000000000000000011d9be0a5c2a25fd33ff440ab2a0a8f5841c0907eb660d7d1504ae3e62e03994fd717762149124908d7def0db9174d0d00000000000000000000000000000000031206778b98195707c3718cff1cdf92b85d1aabd6757f8dd4dbab0d5120aecde9335b015f83560f334343a81ea9f6161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018cc580f11f3d2e20f97c1970ad668012c5bde978c440b48308fca0016a5474fba3cf47e77cccc9e2ccda2744f39fec00000000000000000000000000000000034d9b5945a68018c6a015180d78def431f65b07676e979e136b3e31e728045be774d97442c26f507a232bb10171286c00000000000000000000000000000000105dd3f37c20bcf2e4ae08cd3149f787e8922a772185e849da92ec0c16aa488adac2fb8109ca26fc4224668c708ab7390000000000000000000000000000000013997689e929c469d8a8f1341f1d8ef8724062c02204378c086758196caa180f632f36c2f2a1a3d1077d15ca355fcbfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8cdbab20f0070a72dfa2db96b4fa7bf30e215d6672c646e5486421b35316a5b80066188e9f64c82aeb198dd800296400000000000000000000000000000000161b5c23b3aea5e0427ac36e9f633d5db4525c7d0ef403951c53c022e662e285ea98e3e928326b0c288a6fc8205de6fc000000000000000000000000000000000955ae20d3f9172cf2ed4d45030111952274d7ccc1eaecf8b520cf7e1f146fb14cfc33e9d3e0eafcce2bb1c3418570d500000000000000000000000000000000179e08d68e86a002f005f6f3b21d6d123c7d7911f5a5073cf14a9c61d9d19be26917c8ccfdf406c38a5861acf9cf3e5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000104fb6888842a21c3eefba8abbdf60bbc28d68aabaa6e90cc3265e3ceb2c3392b8205c42f1ac2ed96225901737100080000000000000000000000000000000010356d6bf42a6c0f58607b4af0159effc96146b244d64fa5402153fd589cdac98d0a35e330a33b24ed68647717766f410000000000000000000000000000000001fe1b4eb81a364e2f85fce8f81245baf3b6b2de5881589fac07e4cf3096190e70b7d5b21db9a4a35822344daa066183000000000000000000000000000000000713173f9e67e528a53f70472749965da803700d8c718f8179acd745839d9a431673a6baa3748d68d7b5e51e08a1c9ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069bf07f285e7fc1d292933e840253cf3861dfff44d1f4dc48bcadc731e326753d898a6105dc5e109a9382868bdb20fc0000000000000000000000000000000008e9faad86dd2f2f8aae2b155b1afd990d8f1d0529c18de847e14577f84cd2dc9e105d805c65cea8ad3053ff56b59fd900000000000000000000000000000000195caf3f8a4be451e7423b3a1a3566c4b55d925f85385182f775d08a93bc50d7fb78446e1842e90776aa8dce02d38e3d000000000000000000000000000000000eac817c9c66c36ad0efb1b1fc92da15a068960e615677dd704b6fb458ed88812854449c2690bf5c9fc31af179c109601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4ae5f3df2d025f567b37d9e23dde8a8fb23994475c7b85a7ce8a8c56a4fe53ebcb77b911f61cf8818c9c3ec16e5a9700000000000000000000000000000000059f1b087f545bc61192eb91d099a1615216c20d4965ab3246f53205718737bb7199c5c9b09225511b688f982c2a7780000000000000000000000000000000000d09ac5c318c3015dcd1db6ebcc6eabeb1839361c8a8b1e439dfe0127d5eab4b049763fdbca2cd5d1f8e40e823377f8e0000000000000000000000000000000003aa110a7a13a3844433f30f43e4261979fdf7b5aae401cc6d4cec740abc0ec1b853efe4dab9e3835cfda96b59f278061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f56d4a6b60eaa5acbb8eb0d8d143bee088c82731738dd83b74e99ae612525705f62f3ed347d5514f63bbe2a10aa8ee000000000000000000000000000000000474a13ca39f5f3d450c7c6f09fc0ac6f66652999062d41322786273f26eb41fd79d6d10ef5990293adf14edf46b78930000000000000000000000000000000008dddbc39f46dc472b75ae1dd280e7e0b9629e21f1c75b8cd70d951b1bd508b61f814cf9cd2afa15419f1b696ea0f77900000000000000000000000000000000124318028a059cf4c6091b1875a7e8da8325680ab7e71723b3f5af3baa0d8bfbd318208f0a5a8e65e07c26a731f6ba811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f6e589fbefc3b685a86c0804d73157548e741b60c68915a23bd4fb2a5b13976dbd350bffec4d6b699387b4cfb6aef3000000000000000000000000000000000373badb1e0f6de06235a44540801f95d321b9664f0b26b6389e9b5eaa9a3a6f066547b8560bea929c3331b5b56e04760000000000000000000000000000000017b6172dc2bd00fb3e8bda3b141ccffa52acf302dacbbf66c074c8c94f912c6e75190815381dc247d11d3f1d5f8441bf000000000000000000000000000000000beea1124c9f899749d867fcbc1b1b218ea3071ecf972823a3241377436e9e28bc73dca360b5da9ebbacb9d1af3f07961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014851ea2114886c5cf1c7f622d9cb09c0b17d8cb5e3f5338e1e876dc6183e06b3abd0241ac95fbebb58a7993122210b70000000000000000000000000000000018f556b21f923e4af217c90f0a80cc16425b12febd074c9738cb2d72b3cb2f82dcc562b3c012246ac8cd7dbf72906c8b000000000000000000000000000000000a2c855fe630961b9263322ea653187040bb415d2795596e1b2506b0a064163252ad3b12afc20bc80668e02664e33a720000000000000000000000000000000013e847dd86acb7d4d5a95f185311546959c8fb072f08fcc4b87ec2f191db3d96b87239b2b793cc4573861d4f84a12f4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001666d9bd55595213d99f1911ff0b08c86e4ba8688fb1a1e0a4f50474d41f79583c0c60ec849513d1d23a0486a8bb6063000000000000000000000000000000001114c8b5b5196b8b1223bdcaec062f5f25975fda1b6ed1298d6479c0a1229b371959d74fa29ce3f990bb90ab6a374cd400000000000000000000000000000000032c5985b2473e08a258f9aa189dd811ca7f63c5c8f040b7d5c62365f3a0d0c522a2a93927c2a4fe61200e9851e14c17000000000000000000000000000000000be55a6db7193c9953ba680537e7b5868d6395ed6db1f2e34c7ead02cfe86406c32ca17abf59534b7b6525fe01a4e1631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ba83bdff23b63043c05966c7d2713627f0873e47de995d73e273bf8fe112a0fc71ba82081484cf66b037252be4f51e000000000000000000000000000000000e360198c75e4b15c2b930a05ce3c7a59151550d815ff0f3c76f557e3430922e44958639891bfa29b97f33a99a0948340000000000000000000000000000000012b3629de66cdf4a21244d1c1a48521f4498302e3282691c0c2e04b0e8b1ba8a71bcba330e0d7a3829f84e8a59c1ceff0000000000000000000000000000000002a8d8c8ba8f1c3afc2acfae25a898e70d26aa72ec6ebbd61aa878da0a20db105b1f6e6c3c0a07eb8ee07e03bf55d7e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c569a35fa824913d6b33b5af5b1e276e42b7fbc79a6934d55872e33b14249a87e360fe55fa9c2a5c20b8ab99821e71f0000000000000000000000000000000019794a5eea6cdb571fd35243d49f2353081ebaab54f03257141af243acb5d10fbe5dc234e3e3a2b7079a8e764873717b00000000000000000000000000000000157aacc621ad418dfd8918a318311bdba8863683059848fcb9a2de1e53040edf628366482003575b362b728cb55ed15b0000000000000000000000000000000019f1384b27b50225167f47e60adfcb300d0a8ef76a0e6c7d73899db94d7aaa88f7f2071fdac9eb5fff12d48fb08c87bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b23938eec7c38a0fd5e23cb057645f05fb1db34d99b7e9f31feb96b9b614e01b73a84e4679e3aa31da923fe0dab0970000000000000000000000000000000018b47de2d462472d81651156dbecd10a0224a6da783c16d105918d0e1bfe7da122f225f4a8a90395c6e388c909862d6c0000000000000000000000000000000011992a81ada40afec631857b796538a6c80509e3304d9a0ec5d3a4c0c57c0104f69eb5d8508c70df54209c89f908ce9c0000000000000000000000000000000013bf6c1571d5cc1e5bad3836f766949df746b8f4ca801e9cb4f3ef754559a015f66eaf39d39d37dc2d61265769f8925e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000484da6582c0b120909717ca7d6ace183d752661282186224cc87d212badf4414dcf16bea2c8545bc3ddb7d64042b71d0000000000000000000000000000000002a9a4bd97f25d78751f8e777ba2556cba3d2ebf80ae0c7114820e7775218f4c9cee6ef25c767ff49737f998876665910000000000000000000000000000000004a4ee59f280272ea71e3ed2a1f30b604ce3a35cc64bd03a62ec544003a1a73dde59e3492c6356da5d8d2b63661092ba0000000000000000000000000000000008eac18e96c1b4d4cde118d3a81b33687ae5cfd66a02a78afafa47872509d7fc09b44e59c658b46e1ae451ff6b86e6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bdb50d214f8401ca4d4cb9cc2d82b3149679cbe28ad88a156e29607f27c737d2e29296a9cd2085259df5730ee659ef000000000000000000000000000000000e9fa2cd963d1af04102e15e89652997a26e94dd61b6d0211f05d54b9a3530dbf9f7901c6b5402a31f608e7ea807639400000000000000000000000000000000194709c73d0eb70266dfb890f7bac77395f94cbbd82ee08fde88027065bbb3d9574d7320135755ac1b5e8229b486ff47000000000000000000000000000000000767058abbd3ac26cfdf0e0d134962810499d0da5dbd3f3878f05ae5ddb397bdd253c5b1042cd0c159e91066ac2d8e3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d93d44ed9338d5e3443901544dca6be218d1c2f7366fcde2d0500d90e2a08a962dfcdb5e5fcf690dab3eb702f03598200000000000000000000000000000000024369733b502268af50b48a142a0ca7b187696fce692a1ba735bdca6902ce28276b154885a4571f5a129f20529c40a40000000000000000000000000000000017993b6eaa970f3c3980caa3187c075e0a039d3b03f44d90c979e2e8727c76813a02b305b810f95ecb2011767fe96974000000000000000000000000000000001289023d71ca945b684c661db8f4cb67fe473ad241eaea27bc8508793934b69e647d794c9ff6e1678a564a927e14b7ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107d582e8e252379d6536ea1c679fd877c4b081313cad7b5ee6992d10e3f0ba5acb82e1e00ff38e57d3f54a06ad4775100000000000000000000000000000000102c8e8ec91062e6a0cb23afb8ec1dfccdd006270133e1d8bdabfdb4968e83d078b0444e3bf812d1f6f7a4a0aa300b07000000000000000000000000000000000f583cab7dc9d7ee1497123782dd181fb1dcf213e1b4d3d54361d98bfc941cea0a7600d7acf2fd60fb60e88013bf40bd0000000000000000000000000000000008fd545c8c6a4a48bfee639ad9fbc5c7416bace5524117e3670a02aa7ba41146ce8c96961a81f7fac66deb6d891657771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f56c81e0b4a1c039f4a2a3582b1ff9cb15f244287a6f952721f05139ccb9453b85f37d811e28be09a67a49c5119830000000000000000000000000000000000441ed1314c4116b3b80abd10bf1c8a4f9f096ac224318541292110fd0fac4fe1689a63ee1c21ad14f69d123e0105116000000000000000000000000000000000f2874662e7cce59438e36fe378f7ab47f10845ae0053f07306363e42ddc803d1710141f6361c165444c0c48b91091d5000000000000000000000000000000000a74df92ca74c59c1050684511f90a94861569b8629827799de1f436fedc4339a7a7dc21c947fbdb72845684617a6ed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001140b749d2a793b72eb1f3bc6b7bf399afd699396591879649d3666f04433de7a87d195859bd601bda7be3c0179580af00000000000000000000000000000000000387409869ba81ab3e39e021d50036d7dda56c68c1fef803ceebb6d96903686f52e45f888c7d24fcf2e57912d7c0b000000000000000000000000000000000166e863227ae03b8abd021ca3fbf62d2307a9d78bc0526da8bb483a905ab9a04e66cb828844444afc3926bf7f3f67c6c0000000000000000000000000000000011b4fd5a0246d81cff3acda857b6522ad35712274406de0f9791b4653c404fe1d132520d2f9d02776fde09d2f9cef3c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f05d4a128a71a58cc7b5a850ec072b4fed58ddb433b1f7676c5117745e88d91b19a5ebd3889b6fc4442eb8d4f98659000000000000000000000000000000000f8df5db366f3aad5935a29b94098cd492176be8a29622002ec84eda278b5b66082e7a49d8a224965649308599ab9f7500000000000000000000000000000000167e6977839b5c8ffd01649c661fc6469da1823c641dbd55964d657fcb493e958436e298757b24e8d351d30f5ab88ff10000000000000000000000000000000005b92d340cab98186c56556f50ece3f4e32a655557433a074e282df52e444ca79a4c92374d4047cdcb5de13d251f74411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000229d1f6c9973db384ac9e8e2cb0cbab109e34a9ff4313bae1b410ba4a24e7f6415f757419ccd999604bedda86e544ea000000000000000000000000000000001620c340ac98b2e2bbdce5157faf822fa8ff7a14e696ec2787427d17f8eabdd62c469e4bfc2bf3ffa5dcfa66595fc4ab00000000000000000000000000000000022830aec36bc081c707db713850aaac4452bc48a6e6605895cb3982b3fcdb2794e636ddd79b04b193ce28aa5371dba70000000000000000000000000000000009f026c6a4dd3bb0b534c21a6231d5d5cb870716cb986e7b643c4e43b856c98e8badac3ecfca2bee155ed81927f2ba8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092aa2d6d3b465ab5e509a3a69f91cd362ffecf726ffacbf948bbd1ea92b5ec77a5eb11d3092cab496fd5b791254eeb70000000000000000000000000000000015eef2ffd527782b718d83688175e9af1f7d2b2e432eceebfe07a165751de5ce5f66c241bcd0083eea5683302d874a06000000000000000000000000000000000524795efb4a67c0c9b4d056a0c4e94929388d44124ab664cee1877836a162d82608b4fd69b7f698cda03f59eddc6b740000000000000000000000000000000003c81503950319b3d00ede11ba9e6079076f977e3e882e635091c5ab13f8cd0e4f210d9dff7ae1a8f82a9c56fdcb54f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011430bf125f791ff10023d0ec99286222b96037d82980dff5776ec225c0b7a4d9406ab0631bc821f4118350dca8d10e9000000000000000000000000000000000cf8318aa3535caf14a4a9a1fc6ee354d7277c8297e67861e1057ee1a3e4d8dd14f9a924962cc68cd973fae63c1b844f000000000000000000000000000000000aff41c5b5537dc65f460ba9b9345b0c499a03cf40599250845569f79b5e5f7d4c29585e97ff0cb55973b9095afa4c8c0000000000000000000000000000000006b0c2f5d4f393eab7183d56f94ad7eddbad3a64678f68fdff8b5a567d63ce4dc79abea3f9d51e887e75718d4c281bb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167b9f8504fa52de2e41da1b8bec5138016d0c63b18528a4c92bc017560ba989e79bd2d6147050b6eb8f4785cff173fb0000000000000000000000000000000012f9e65102808da959f421c28d22dc6e7e4daa540e00d1c59ff0ce39d70a24bdc08ccc69c7d7784300a625282eab28c0000000000000000000000000000000000bb3e841c32d79115470b44c15f658a3a4025776c1e2f5f1c94b2f4d599a09992e9c0f598bfbf7f4627a2f9e39de9426000000000000000000000000000000000058012f4a8c3beed3054e32d1c2c1e216a0a41b7f1e64c3d604b3f8ae839f3b5e1891c6d3d1e50b47ac182511cd74c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194cec814380c21010c5831c74b3337d2569a3ccdd65c02e1910c7fa24929b66cc64095ca4d7d1abd585fb610d33720f00000000000000000000000000000000095cbe2e66e78a8be9778a983c806d3c434044df1c49d32e26dddfdc4c549014d368fbc4056110576548c8fe367ed7b500000000000000000000000000000000047fa8f3288b40cd26b03fb394aab6254ece93a0e11bacd90dd1a8900c00cf23470fa3438368c7758d16193ed8dc4ba9000000000000000000000000000000000ba4a684abb610db708470cddb163071a9fc01abf2132d839801d3a391559dfe65aee97c96487175e0e014d3d97fec9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161e988de7034af750af33f638c62fa0a8a51186a0f59f17c746a51f926203d6180987f8c6fe486adf68a45c3d4d5a0b00000000000000000000000000000000156a3f22f153f2aca6244e31185359aec663a6d3cd3a15965bc63772d82210cfbc31f5a97780b0a4a9acec0fbb7fd80d00000000000000000000000000000000167a9584b916b3e5edc750001a59b6e93243b72b229340375caac62d17483ae33142ff4ab6e4bf46b8349d64808637fe000000000000000000000000000000000a079db6f23e4945ad18c43a4adc5bca36386f02078435c493f55e0310185d4304572585b409b2e764a2affb950cb6071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c33234da7eea050e79c955469ce0ad23dc8b24f9fcd8d1a5cf88e0aae8288df8047b221f9e935a5de43eb2097546e62000000000000000000000000000000000ffca4840f9406f812f4c1d336d03fb6259f4cea3cda10bfaba7a8cce381fedf3cf140459769908150a3a82e89b283c8000000000000000000000000000000000cfd3df51daf18e7196a6e4995350cba540ae047954373e8117157f2f598dc1371cbdcc72bd41a38fc58e5b60afa012d00000000000000000000000000000000121c8146ecf87a6f6741c9155b50def6cb323fa7529ca64d9d8441585fe5cc2f489a026d5f73c09e030310ef8feba36e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090ed22858be244a4075953b0451357e973f78a5496497828fd389e75f93d1cf125af790edbc1af082fde1a8ee43425f00000000000000000000000000000000137a4207a05c4da33bcd73c327de3b3d9e489a23ac30ae8a3762ce285ce61b8348d0ac0700da5398f078bd916f6883d20000000000000000000000000000000005a8f6c8ea74004f67cf1356f3a142116208432cd060d64aee37720892ab903ad052b0ba60b329f2d2005b6fcf3d1f3f00000000000000000000000000000000052b2b29c3e458e5df5767e0336739756bef3c146f1caf914eb224e5462dedac9e595bd2b4addae60e6d14c6a2edb67d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000945edbfd6162454a85622f3dc7af74ef158da53e4391f63532af2cdfcc5aac34ec09fa674c68c6b09a7c66efda4877f000000000000000000000000000000000d395e75abfb1c613ad98c5a48bb38375bad804f409ac1c34373eeb29d3507296e71fe5e39858dc23976824f68319aa7000000000000000000000000000000000652f6197928167a06d890679ffbc9ff72bb323ef8c7a918daea286a3f9266a44ec615934fc17c27342460bb2dc425b0000000000000000000000000000000000c90ce4c02f58954aebf368124abc39049fb3d8825fee47150c0d0f85334cba2d76598a28fc19092723d8f8e554d27c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158bd33903cb1dbc901c211e8c308ca3b502cda446f7434e7266ab254b51cd9edd96a598ba98762a29c31c5d6718a9550000000000000000000000000000000011e7594d2b0b31bcbb390caa42fa9e332554d13d86f3aee127c65768c119a302d9913cf201e5072aa60996b2039f45b00000000000000000000000000000000003bbdd1dd2c1875650c1881642afd3c0ffc996b1f211f9a48801579afda7677a67f5a0c49361307730fb62ec13efd99b0000000000000000000000000000000019a8bfc09f840a7d959e5675881cb1f0da62290fbe8b9412b2c00f7b0b9b5fe7cd889e615701affc2c890e16f1f3628b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af9bcd5c687f5d1904b45c1fad3f12fa92e41ab546d4badc4da210da832a5dc139c191910345161e5d632417cba45cc000000000000000000000000000000000ddd84fa783bf50e77276ab6cf815359e8550973fcec7a3aa00c43d156aa36df77cf9c34af2dee0ef6945a68528e041b000000000000000000000000000000000ac0fadb2ba465b6d9e1e27ffce8331c37ecaa6f994a29d84a3fcaf574aa8a1945a370f56d136aa006ee660493c620ea00000000000000000000000000000000072bfb0c3352cfce2e8173468a66ee23c81dd7b3d4322ee8805be1d8ad1224bcd81e02ef8e6af594c42d2bcf62f6bd3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148f8416c4f75c02dbb04fbd2840d214c3da50f7cb1ae3ea57cf51171f9fb754342ef4c2a7e98fa01ce010a5400c6a640000000000000000000000000000000003f30dd8f1784e9ab30f07233094b67c22437518f4a27210b5762765c3094b9509ed5250e0bf75805e2b3957d43a55b4000000000000000000000000000000000280830549a36746e1e9f2f221385f865f9dcb0f8a7250335a00b8064bf327d2a6859f9ac730347efb6652324fdac00000000000000000000000000000000000050dec11250eb3b516e6c292511e7fa99eefe5a2ec08e0ffa3ecd26ca6c9cc7f683184c2c5019d6d9e85c229dc80e5aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013be3534adce776187a79a1acb16656195dc4c286ced57d10917d768d1ae4dea1f248dc9f12e33f352a4ee95c0d0ed6d00000000000000000000000000000000068f39870a08da3d82f9ca5e82814ce41a301b5c47a326f3f3e66161e186d7fc6a5d8e408bd18f3ffa1c1c91e326419c0000000000000000000000000000000011bd58c82f5d6f2ecb12014ce577adfe9d5dd5a66ebc82d09ff5418ebb1f567e6df884de19988bedf34e386523b7e4fe00000000000000000000000000000000157dd6392b841201c5c95fd92379b1e0547ebfe704168bdf434a227704fbb7b1b6b39aadf95fec74a8fe0e2eb5d9a77e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1ed68d2f589049fc661fa95678cdfc3485b460fe496e63d193cb7f67879b377edb342f6b1e0b6d500b1396a0adf88400000000000000000000000000000000157633302c718c7f2f771b4e876f3d3ce1822ff0419f6cf151cfdd91e9174e37e9e57abbb3e9330f63a3c45a8a8cec100000000000000000000000000000000011e8a805da50e60360a8841c13dffda894957209aa7a802a847a111403e1b20a0ee6339c3c60927f36ead0a62f3c349a000000000000000000000000000000000d3479c79fdee6e7aec7640a0045de0b399c2c8df4bb785f639d81270febf55bc97af4cdbd1eba5c514ec5343e57e8211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046c07a1455c91ae8d9828ed569805d7451f9e45c8a2d44eba26a3582e3304ecc9c6afd03b7de00298ef00420a3984ec00000000000000000000000000000000072a8a431e2fbbfddd7f6793c100117f8be2dc2316a603617ddd2c61ed3a56baeed1f55f1721dd78c90d3580d1c94c9b000000000000000000000000000000000033585efb4822784072950e92a259f621739a8ebf70bb39d30c97d3b61924dc1b0e5ac4011a441d564cd2ad58f471a20000000000000000000000000000000000bed9f30ff5c9ccc7c9fab8107294da619f10db4aad2985d5cf3e194d6f88f993f07443544434de0665a24987d668a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a41329637cab7a6a439527edb905c3ea775d86098e24a24c9e4ce94b13174db56a8f6921a6718a06e39e4c2cfd149e000000000000000000000000000000000130ea6b483974b61b14743ab9dd13a21ea2792ececef70604f6d3c5824e9c94f85dc7895ec5af0ba526aa22f00d362000000000000000000000000000000000114b153bdadf64d5af36e2bad386c1a12194ef3bad5b58d4a2e9d57e94364d92c7bb9de2b282545170057ddfaa70ec900000000000000000000000000000000014985bef69873db45683d7e7ad160786c9b97a302345bfc4ea6cfc4bb141ae009bcccf786658797b2f59645aaa6206061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148fa58969a7e14df9547858325b801fd732b66d33e81fa73b994b462be0b937b75a816c47ac9786c70489cb1ef3103c00000000000000000000000000000000029e14faf13de377569f2c92657a617d57de6a2fac40d771a7db8fc09dcf6450582bd272b8bd456aa4a70114202c810a0000000000000000000000000000000011d45c56fb6ed8f16ea72539ae9bda7feb51737444a58dff3a4b2931a5947438e11598be29474270a7fab273682046650000000000000000000000000000000007c099a6c3c5ff9658b21e6fdbd5bae7f72638c40af8bf756cbed4e38a73ce0ea6b46b18c8f5bf3b9d2ec86adcd7f27c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d6d31fdd93c3b2777b3ba6c000f6c03ed95d0eb1ea3fa749340a2ac64a4abe7f8bcbf7e97017ee187cd269e83c5e2e000000000000000000000000000000000a6f32032d64ac1942f2874137c17dc517f184f31568c7ba663d8b9e8f80eaba363f7427723a8d645a70fdabcb767d3f0000000000000000000000000000000010cc8847166d54c47476a41ecfb43bd13dcd2aa9713e52c7a12ecdac81f6934977809d05e86ef47ae9625a8a233380030000000000000000000000000000000002df6dc7abaec263001b00de0263255dfcfefd1d62dcdf6539fc54d9e5a1c1c6762e369807db5d25d59fec7c016afabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e956695307f67e13142528c389ef03b1b30f6eba37fa39fece565ef9efb0d27bf52a1b8e63131561511faf269be0a1f000000000000000000000000000000000dbcfc00f7fef8b6cfad3a14af3e780b3aa6f24e05eccd1590f9e87b9ea902a17c94a357d14f7fcb4adf6bcce2b45755000000000000000000000000000000001323fa5ce5f7143096f8915696f386993945cccef09d34f178c5fd99a5463cdd3fe8b7e938800f990a89b0622e68478e0000000000000000000000000000000005705b775e8b955ed8e7f7e2dadff73f5471302ce81f5ff9e9a32a94f405f52fab2ae4e178f3478bbbdf2f18801c118b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118ed3b4f1abdc298bcc89f1fa21b3491e8a31d479748691b741c1638be6aa7bcfc3fca88f1e3a0e3b061a4375b2d85a000000000000000000000000000000000241996a5498ceac0e5745015e687e96390a0febe60f779925d9bc280c67e1d70c79b18aa80b0d45bd99e8d4584e78a90000000000000000000000000000000006716deb77634e0349612f6cee427631342f983c1d34397d5e48b2b33834ae2be01aa0d90cdcde637de3207d63df250b000000000000000000000000000000000b38dd48dea5e3ed33a78f484c64b4054b7baf2dbab5bcb6c904f2d3f68218f66ec2b06b2bf8f1e82d349d58103419351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6fbb53397b1d8fd41bd0f67328592efef653d1e1273e1f6d9e5fdc614517fb778062c79dd10aba8fb0c9b71530ad4600000000000000000000000000000000124a8b3c42bdf68bfd1481a7530eaed4f8b479b0519a66141c88b8ac22e01f438cc1050cdbc0b76e13c7da88ade43db000000000000000000000000000000000023543819ac26f3ff2718a2b17bcd2ebd9bcf7e646b86e80dc8208591a50c18e02535d33afc901b555cd0fdddb9cfa6700000000000000000000000000000000031adace62048946f92d23515d4414a1091c26b44250f0b3197ff6d6f9b6241874aa6d41559221904500ad05edc49bac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b15011c164379dbbd6a62b9f6d7c169fed8a0535c1443b0d46cce088192a8ac239a23c6620a420c1d1430381f57c47000000000000000000000000000000000caf0edbe7865541405c620a4f8b4cf2383a9dda32e2cfbb78a21461630bdb998095a7ad020aa4d66319b10844621b14000000000000000000000000000000000b5e9a03f7ec113035ab45b42f31f9e8853a99606d9cf798378e70f38b52388990051d7508d34a69a298db36b87f52460000000000000000000000000000000010f4de7687f5b2084109412094194111dd4af2e0d8a8a11290face8217b9c5bb6e633a858276f3dbb58d3372e99e7a141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106b4e04353f6a8a8d671c2ab617b6335e83abd0d361375cfe6061dcc22e2755121f1e1b432246c318b0b3ff20c2283c0000000000000000000000000000000010166f90b34b546f21a3c82a4181e20ecde8afbe594206da1dd66b9c609f77df06174419501e8cad06bbea96b35898da000000000000000000000000000000000f72e13fa6546ca33fa0349306bcd6646c6c84347bc288076ad7577d04c71145551a84959f44c8d5fdb3ced1dbe7fb7300000000000000000000000000000000191bcda76b18812a7214e0a4a0be055175e1c6b2a43aebd9a1a2413dc32ab8c358d3c1fa5900cf4e09837fa52a5a82bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107358017387b20c5db682e717595b0480661c1b921e80c8103d2fef217df55aa02e3f7d6941c0c6911d4406f5742b0c000000000000000000000000000000000d241cc4577e78cbd37400a5230bb519d647c51ddb062b892b6ec8badbf86f02e169b9284bef93ffbf857b743c28e1ab0000000000000000000000000000000011a7382f55fcf4539fbb6a9315f65c21a51cb4853a11de2e1faba01b4eb6d7a47a932ec5f5d2f4175d5a941e97dbde81000000000000000000000000000000000842041e7fa19304a79e8c61787cfb7ff2bd37967f685f0ff42cc784730a060b3392202698270584fb7682beb4ebd18f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193a9dbf6afc1bb9f8852fc0a3e6467e5440816508596bdedb0308522df062ea6c72ada06b7a1023981a93de76f7a16d000000000000000000000000000000000c2cb6bcabf77177941428f632cde41ddbfe6653accfad9d2eb06dcdd587b62202d674db20431ba460a3d9e5eba75e2b0000000000000000000000000000000009dc67648b10fcdfef5113d992404eb93217e048b50c65270bd925bdf64c84dfd6799d58bdd3701f7a904b47091fea000000000000000000000000000000000019eeaf62c27199722fb89f5b119acc8dfd1c9163253df05caa138b091874e31adaa8e2951089ec76682e941cd0fc3c031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c26d32e863b5a0a93a502f124a44e7e48c41280c6254f9f4c648a5722a189ff59295308895c39d4f75fc3b1cd6d732a0000000000000000000000000000000007302e6c17e291b19fabcfc10a754a5a4ed9b7de77e1f4c6f87c1ce162f6680bf942eacaae689bb885ea44e6b7a40f3500000000000000000000000000000000195391871b83f086459a8c078d3b25a692fbab2cbe47a6287cb98b47176aecb6522123195bf829620c7163643ef6267f000000000000000000000000000000000683c641c9549b0ac23b42bffa198301b519840b6e92c3586837de2a5925e684b0661384e51a0b8e93761e9fd1e6b2781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126c41359a52c4b60c70086eae8bac5da31d56057c395ee4b17415fa88f5a0fd04d55c217f7f9bc3d442cdf7f4d418d10000000000000000000000000000000018169da30a973e7ef1f491906acba73404c52055fe272e969fd9a7c25d11ec0771d9ef571e6474f7ea479250193b2fcf000000000000000000000000000000000e8bc103708ed76163b5e355c84fd17865b7fa8a0950e39d2acf8c6f3abd9fd273d8060f585f2799cf98a3b0dc10d93a0000000000000000000000000000000016e37d22c7d3c66a114441c96b677d829b53073eb4329ae0f6965b525b6e32166a0eb0cd98e7d690517bb56bafc9f79e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb9fcf8d8760a1b8dfffc1bb281f1fc991b14f79577c2f8f95dab4940b6c13c1d88c37f3b7ec047939fa4120e5c3b72000000000000000000000000000000000ac99677d25a78583d559de1806514442353d8daffb44a4893ada78e1fd394e97b4290b81bf2c85af42ab919115f7b5b00000000000000000000000000000000016b5b61b3384749f935eb7e47072aaed4149b54e1ab5b4ad5608d3c7557363ee84fc0107fcf150fd80f8797248e2370000000000000000000000000000000001983ddb827ffa40ec0f97451108d6f2eb77ed41b379db4477a0562c3865e996b54579d70049febf82880e194fdd73fee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f64f53696bfc1742be9c9a36bfda36d7e830c822221521b0927145c0c5813727eac4c4697aadb732c7d89ed3e1f5c080000000000000000000000000000000013f56691eab06db2ac30a39050189592501c16a6b846943e5a9890dbd466cb03e7e7b3bac312da602bdccf1605f12101000000000000000000000000000000000b8917fb95077ca894642cf29ae1ba5cde58c05f10c7a67e472b03816828b2133b9553feda4d81766b8857e609ff36c7000000000000000000000000000000000b4dd66857eb4fc0aca1c6dbccafe8adeb7b1c9a701528e92acb5055b51166beed04ae9855f74ac5ab3e419344773ca61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012feba07773004ab5abd5863aba51c9eaa6239a1ce917f0fc115afc8c28a2f321ab0caf4a6afa243c4e578ba2c84bf7d000000000000000000000000000000000f6ddfd920427a4cfcbfd24cffd0253b3235c84f97dddaeeb79feaf71adeed50ddd4b35463bacbf31c70da0c7dc82e5400000000000000000000000000000000012499f1dd5c2da4632230d37b1a870b6b12f705d867d46d92e6ab3bf7caf4c2da9541b119566be689564390edfc57d60000000000000000000000000000000017e789b489cd4fcfce278d7223c193f96b5df27ce79b7a02ed73c79e8c09e862d8a88f23221fe6234f38474c979a2ba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011334414efc070d879c30dcd8496d5cb75e09f088c8ff9b4c4b71b96f0952315d8c840d694ffa8be023c5727f0f2ff0c00000000000000000000000000000000051171cf84c64652b00a15342c9435c31f6335b8d43e48481cd214a794f97c9f1cc8c53e00d2c64e3596eb7a1c8db37b0000000000000000000000000000000012e19c2d63b1b17a54e9f7d5daedabcf283a45a7cba86f778f0c1c16d84d42e75cb1a50dd091d33f3d2d02df2c9fc40b0000000000000000000000000000000005d5cbf9554efa3e6214f6353be67f3ab014cf7ac979ff7020932a454dcf9746f114581d6b8ae4055281091bad42125a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001948194d15391fc54b26e989d233bf5080dd91f60021c19c50d81f9a6b465c6bf9d3ebbf6804df8d0e271e20d5739d2e00000000000000000000000000000000044b65f359abdf07142773bb7029f6a779032d7833650efd95f913943e638fdf538b43735c6fac617f5eac5ba88f94a00000000000000000000000000000000008e097ac73988395c07099681f44f9a151dfa75575b86a7c083ad8110ad8bd4d9c24bad6c606d1186ce73c10d76ab7dc000000000000000000000000000000000c5df1bc05244707d6d2a86c515e7c5ea25422679a244fee8056fa513b0ead278d0a3e1addf3bdcd716ae3faa1b0533c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007c1506da644f85a3e1825dd9b42548b0cd414af498782030ca34a3af02731c4eb25650179ab0f2b18af27b55cb0b370000000000000000000000000000000003e7d6a1dda11cb7f1cd33a71e0238e5a0e11e029bb5f23e21507d3437bbd6dca4e57925eef6760976fa610a3ba574be0000000000000000000000000000000018d72461bdf1f2a43fc932cd6bf1fed07b8670615e356cb75f4470dc6d3b30c58c76a4381ddc275b363d490728315c1500000000000000000000000000000000068fad8cdcb135842dd574542269fc1230c2a07602f3f934d06f24f39188dce6ab32cb7c4e2cb930a118bd6c3ff4e03c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007caa0ef37a25592f5603f7859a9844e79a178bffd60d997013a28fb692547363b2a2281b969d1e1cc18bf0ddca3e4a900000000000000000000000000000000165571effccc21210797627760c7a4fa7fa2b9586740ecc7129c7c2b20b0e0356ce5c29bd59002fc9146c82789674d640000000000000000000000000000000009a2811b3ea7ee8b1d2f742a28ef7757c65d91902d6d4ecfdd908c998be2dfacf03f067e867c5f5cc91342917f528dd6000000000000000000000000000000000c4f3e2f27fce562a06f93d30714d13ddf734648c2f5212c9e79e1f37b5df00cc1e748493e3e47d7282427f4b96fcc661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000319a43d7814ba5af3b66a901d4e39fbf5513c377ecefb4cdae6661f0dd3ed37932d5732c7a308368c1dd162dc4af7b700000000000000000000000000000000064e7386d535e9431e56b743f04b9852f8350afe12a1c11393d03d3f842141c395bd47119f96247f977924089460fb63000000000000000000000000000000000e204c2ede2084e29fbe8057bcd9145dac9537545a631eb9643923dec0ef1f6d477feb0af3ed0946d012f88464dbdb620000000000000000000000000000000014c2750d4267971409bfa62c1692f745f3a59e78667f95b1cdcf056ee119afb8808c1f11dc041227878305a79bd8cff81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a33ea2e5e38d2dccdb7d2fd25ec72a9c8e28679f5af1d30b51bb78048216653f13f4daed2469ce70213947cc71e5d2000000000000000000000000000000000dfcc2f18eccd32258aed1e3d2f13240cbb653e5bb8479ae730e99a96dd7b8c36a7caa052910fba8633b353259a179d80000000000000000000000000000000010cf7bca96576960f916386f27dbfcfc2734f41e87503a16740fecfdb1eb9c0dd86b7490173743d6c2916a4ed022d49c000000000000000000000000000000000dff35cd4eca984221817444ef8a88e478885c0fa981a179f2b42a7ed0c93929a76f83cb3a4ea5ab6eed279da50952971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d13abe80c13d81ec602863e52ca9e599d1f7d4bc952c26b7b9b8715bf1f6bac74432979eebdbdd2393d96b3dc9864e0000000000000000000000000000000006adff586cff085e99925a25aea0c437a2a991beb14b235df6e978a1104330ee152dbdae977b0b72a4e85f710db684f00000000000000000000000000000000007ee67ba0d2a0240e1ce44b8108f7a3e837878ac8d43d916a0a7a8ae0216243707f3f16f7ac05d319bc218a12bce80830000000000000000000000000000000004b25723569ccb3b25911ca1a07f341237f2a053e1325052e6527d35792e4840f2e9d02622a1ef8ecb0dac21df9b08391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001484a040ea2bae04139a34da6f809d74f80aee94af1ece6d06b29b91b2b8f21bc6e15cb5a953320651df2fc5e75380b40000000000000000000000000000000005242c250821bf498ea7a5247d38827286ce758d73c742af398a7ddaf59664944f329268c895dd52224fb0ec500722110000000000000000000000000000000010f6d5b952764d4b6cda0c36fd7d26546fa8df045efcc49db1d766d7d7c0cd76abeae3a169e1aab47e1aec289e1a8cb6000000000000000000000000000000000fe94bc1bf5d8a00e0917ae3886945ccd1df42a1f3f72a3faf02f0aa74cbe7e4b88004052592fe1fee6616c3d61a9b141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039207eb0c0ab8d79fde1e0b0b551c4781abee336d01ad1cc6601362f298d070816ebc370f8fe93b3fd822d4a50428ed000000000000000000000000000000000626ebb9b76ec89ad3efeadb96ef186bfd10f80ed0293c865e440974f8508f5625f329455f42c9494d0c8bc1622f7129000000000000000000000000000000001451e402e8d5487d08e2d3b0c2cb7098e751a4464a24780d1514f1166c33cc376d722f6a10131f561aaf6e2a0b1c03af0000000000000000000000000000000005e5c8ddac9de05efe4bcac5caeef10b2011927b33eefa0626c178fc2d05392e38ebbc5f587ba9bc91ecd846687c63411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162ec183605c2511dde4bea1a9fbd6743162d26ff0d0de184e0f80d6e3c924d239114e55b9013caaf42bc139a0d05a640000000000000000000000000000000006c39bdd03c1c548c2d2f56281e679e7bd9407367d1367929b8c138ffbc63c3ec27505d01d5991b4b009ebd14efc3b3700000000000000000000000000000000133bbb87d98dc5027357ea143cea22f6136f1c2513e7d843283555378d6460402227f59e2a298a96408393bef880c2d60000000000000000000000000000000008a76540091bc9d3b0f3e717faa9c120806ad922b50ec43f09974f63340c3de068b1708be15cf2eefe95f6a845f83eba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010634708ca838cef03b96ffbd149f32460e9cc83566ce2585c524ba35af17954f78d7e4c38f066886a63df282a4a4708000000000000000000000000000000000b5bd6d673588012be3f1ba0101022924eeea3f0390edcc4ee2fe31e2acce9bc50b6f597ae97cb3c8571c156602f650c000000000000000000000000000000000afb476b6caa7ed864720ddde1f44209a4cf2a0d919464011cf0412e6ab34fb313f7840740ba43cf0a7492997610e53c000000000000000000000000000000000b3a7a785641cfcd2f1b0bae1026ad90ff68b88cce7105856f672c630435b0d924cffdb6c4177023c7123bab00e2d49a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131e849c2526dbfb0c026e63bcd7a4564897d12cf9df178aaddfb1cf7124f3c7e3dc505324d9c733b0cbc568e52abc440000000000000000000000000000000009dfed16626c4577aa2bf8b1f18c7a0f99b0baa67c1f3b605bc7101751dbd958ce2e70091173a0cc2ecad77911368ecb000000000000000000000000000000000db74538bd15c5cf5260bd1513ba24e93177f1b8fb7cca5bb38407f60028b114e686bb8a42af786ab2d38971c26cd71c0000000000000000000000000000000008cb7da1a1cfcae739b2e70da75ebe5ce88003b0e64e76a2bf14f014dfe58668111bad41bce8b04c6f936580e866de5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001910f1b7653d0f6c9f3321091688e0a1af42083a6aa8d857121e0eb15ceb013d5af2596a6d38ae51b2c370a388511f900000000000000000000000000000000007612d86773d41236bdddcb64adc9603c3d3fd7260b02b2bc799ebfaae739be263047f538dd9290704a88ac9173de20000000000000000000000000000000000196cee11ff27df206575e7f1dfc1e66bd34d4e56e12efd4c3336d10a4e8b42fdc5f9e6922c1bd17ec51ef746b1dea399000000000000000000000000000000000434fe2aff07c2cd6814f1200c2b4e3ba8d6a490bed42364e60ca5f148df5662095a816346810dd752fbfdc4a1dbfc681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a834e016100229c31418cd1656c294aa45f9361678eb739771c11b03a96b0a0fda7dfba97e819d32eec5f26d17e71c20000000000000000000000000000000014f717546a63bb591db133ed2a18a9c0c6c17a368064465fc6c15e05e2fceedf301f90401d1793d86d14e97309aa6cf200000000000000000000000000000000129224d30fb0c002970e954bb667769c9419b4b3d9e6cfce7432ec9bce93801b5881803bc76f36d123a453527e014a76000000000000000000000000000000000d5e845e63026b88f86bc1549c7ff33d0bd384be28e21a1be02ffe97b67b31af942995f15fd27a1d98ccd47d8344f2c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001593c45bf67558f518c90dda2a98ceef55813cfc5984522064df540118003ce50e25ed26cbeb13e3de795830d67cdd4100000000000000000000000000000000064fe133f4dbc162e320d7097079ac13bc3b524ab34b354ddebfa2d866e17f9cd7565f3d37e4db1fccec47345f1fdf0c000000000000000000000000000000000b37f17a24d92c63591625e4d664a6e182c25f58915ed1acd53f0d510728289b6f520ff6a83ae5af1adcfc4d2438889f000000000000000000000000000000001951fcb26d7c36ab06b43f8e95a514c73f09a91e798d9c22c99b22b48d4adaac7e052ac8ff662038fab0474a32de36501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0be046229986630f7aa765ece759c26fcd20e027db3da9320877c45c8ba62c9ade50dcd371f0474ae2417091b439b000000000000000000000000000000000033a48e75b898762d71ef38fa87891420befaf2defc79e634db65b694f6e104d6594ffe7a445d41d5e8b846e47804f39000000000000000000000000000000000631aa4436c3791fc0e76387c714efdc12c84eb8516581450731cc3e256ed9c92a41733d497e8a37a00f6603a3a36c35000000000000000000000000000000000c6557a4c602c1a847decd784f3214021536272fcf4593c1e27fb421f3f66e6e4b553330a25723d15ab09dc4c088ce5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8bc0e99e3162d95cc2698c6ee5deca568d160c6f0c407d71c7bfba91e284994b2a724ee10b58c206df751be0d9b5b8000000000000000000000000000000000a554a9495d1e0d2bfc3c43196cdecf63d03dbdb4a647c8dd4bffceebaa5eec05af3a572ca98a0dde92eff2361ed0adb00000000000000000000000000000000046aabecd5644a4bb82ba4e839e7bf92d2bfae8d9c60f07420e0b255a92b6fa0e62a284cd9cce83f343d5994d1d95ae30000000000000000000000000000000013bf2e9ba6033c6cfa448a4e3e35ba2d03fce76ff9c23a780b5e8aab54606caef9b12f3c5593611c591be380d093f2031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c039bc5dd2a0d25ca847b615a069d462f9abd3a7049493c8adde7cc8aab803066dac3ce56cd087c75acf334625895f0000000000000000000000000000000000c1a747f18a01eca9723f9b5ddef72e08371bfbdda517ef1343bae1504aa590b236b5b96446222b0eb5666ba1045d460000000000000000000000000000000000a22a6d4dc38ebb3a132913d4b26f4a0bf6d0d057c5a6db71f0dd05778a50f9e2e9ff17dd9ecd4b1afc69f3cef186e290000000000000000000000000000000003b6fd55fed34f7a8391a289abb360b022c46e4d2bbf4e01dab31a94b871124212a46b3ec663629ba107440a434521801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fa0ad44811ab60f326825657fb5505552af3975646bc2c6b582596a6a9e8a52b331cfc40d782da02ff80610b07631300000000000000000000000000000000106b7382007607f35444f46b3ce4cd66889257ae2c5abc72231380b6e53bb844ceb1756e71788b5b0712ed886c2e1c24000000000000000000000000000000001261c3effa1338ee06a44e6e1cbc3da526396a577196d101cd802443e7fdf11da6c9982e636ee6f44df6ba06f9602146000000000000000000000000000000000707788b1548bea0788a8f8ed7852902d49bdefca9d0402603221bd36827ed4713d99de87d8585574dbdc86f1e3398011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194f1163ad738aa88a47a87701fc3dc06aba35879139dcaf518230fe43524958ad1a0137e348b8b9c13d8ce11ee815bf000000000000000000000000000000000d4c6a6b092a4b6773c06ed0d78641b422750aea26912449f2e0383305d42115fed62b866b01ac35dc9859f201183cea00000000000000000000000000000000097604ba7a791f3e90b439f5d9990d853e4bce39fed54a3f18ebd0582b9fdfd3427bf3a9c8b6074622605f57c85b63160000000000000000000000000000000019171dd195539cbf7e56a577b27c38600a920dd7638479f485f9c2b437f386e6858222dc921490ba0645b5199222fc861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142ed612879f07123c3affa95d39e9d18ab3dd77b837d70750b1f42c14842a157081179b3ac9daa91e045a9f6fd9f957000000000000000000000000000000000af6f8db1de051835ef33ceca7f978fea1470148ae46119c0b3d24e173b077d5498a5f6d4728651d4b760f73d7449c8a000000000000000000000000000000000eabf34306e207b1987472d9819ffeb38fd30e7a3cb5d99285eb8c8e98c4784806da6ba7456349c9190c7c4b652e6b44000000000000000000000000000000000a774137e2b7260175dca1db65edb85efb394d9df79f68ccc814c057d3a0011743d8f228b41d23cec4519f774f84a7a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011949582891f35b0f5c4c8ade127129470754461055d1d1004eebc535ae0ea779ca6121abf62da3c4328420db28cce9f00000000000000000000000000000000197749429a268b646c8b8799eefc77034edeeace7f9460fdc4ec9df3c2cbffdca8ba45950b8ee6fc6c7abe7bf941956f00000000000000000000000000000000167c2aa82ccb44057850f8b6bc7c9b87ef7683014cd775aec6d0a5b9a261085b1854b0d2809433a049b8eb87a6821ff40000000000000000000000000000000016f08b4c09b3cc4b2c2d7903e06adb29632119fb6e1308f6ddce145bffed791b3a1c888d0b4b95027281131f0060b0bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000771de8e8660d4f9e1c4600da0e3d0abc70ff3ab5da56fff062c05c4e745e54e678c3c855b3e907b9571fed7b1202e140000000000000000000000000000000002826fa00daa313a80a2682720260022bfef9e31f4550ef3344ebf4cc594a6baf2ee29e1eacbd52cdc3407e9e5f72fe20000000000000000000000000000000002eb50bf8ec8ad3439e7ca20445d7951651845760860c1f8d281708669c34d032eb088b434c37757e00f7a1e6ac4961f000000000000000000000000000000000b1811eed32675e657a850f1025370cb22b027f1caedb46ff5ab77cc8a5b62e2dd652b1a65d48691520ad32e8085cde01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191315f046c57742959f2282263f1564f1a0783913bd70f64d752662ea7a14206b13cc685b4d3cf0c6bad5c85674f2900000000000000000000000000000000004994d47674c6098709dc38f2c1a8eddeb5a9ff8f6db29854a0efcf2d26f36d7685b3fe031aba63353e640679e6be0d80000000000000000000000000000000006a1031a1bdab364ef70fbdfb51419d92916ee4ab0112e7c0990a940243ef7fa528494461d016f3f512a005bd33d4b8e000000000000000000000000000000000966b18f7ab411f9f2d4dad1fbf28f466c37f6ae2f3a47c7057b93faa5ecade56e9485f321405b52696f52faafaf66741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091c096c661c61b35216d02dbb1ccc4d639f7cef5f8f611f89ec85a82b4c5d053312b4c7049e3bab5d3a1f914410dfc30000000000000000000000000000000018483fdcc8bd85e12832dc4d1c39dfc5c404d5ff087cb55e89cace3986927c06d45f12376da0e5b2aa66a2b052e3fbac000000000000000000000000000000001597f7397f7fce61422c28a0874c77efaeadae214ab2c63894377de5f8ad56ec0fc22acfd1d8c356c4a614f189ce048200000000000000000000000000000000113921f6c2a0e55ee7bb6727e9d9c879295549b5d340fcf5b80ffaae04c9d9c4c15418cf9b78220906c023f1373d3af81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e550be0cff8389005ac05b1d618968aa3c1f0164141649d89c88cf329a4fa645c4d931474f4e43329cddbae25d8747000000000000000000000000000000000e2966975469fe5feea6bdeafc8a66cefead784a49f7c2a5a30da0542d5e9d482d161a7d2d6814c63bf53074d4bcc0460000000000000000000000000000000009c2ec3f0f37968a2d77b4e1610c5e4055bcc7d6891d82abf1e7d2e7a3412af8bd5e644a7dca6efeeff6707fd3f5d8060000000000000000000000000000000017e6f1048e2195fb1ada1532f41116757ddd5f362a1f586047cde15c646a0c045255cfdea17130924ad1223ce0e719931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ab6e2fe9c3d0712e019e992d88b61edf4b6672d4c2fc64e2bb8f686b8708605a139d6f501d9bb5a7dacd28e36aeac900000000000000000000000000000000165246c7d90359dc3f602d5472285ab448b57e9c7ec21bc573879ea4683eba828c5a3d1d42b51a0db562cb526a97169300000000000000000000000000000000131d7adaf84c2af6320904ee49ff7ea6a95c49a655702135b6f4366fbf40c572eaad85a0300c5d23b70f7dd3bd194edf000000000000000000000000000000000f62956db7f0dc593387b399d1a5df2ccbfe94e5faac5ffd2d675fd39f736b260e8807f62a3cf4c98bd03f04656281c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc9cdde86d1778a13d90e1f93bddfb2dfead644bc1960f165e4e8d183638b4f95fcd81bb1ef927961a4a73f0c5627fa00000000000000000000000000000000192829219b8649d8e3c4f8682130eb60b7600eca8ffb07534ef55ac99481eaeb94454d4cdf0eaacfe4e1cd5a7e41458c00000000000000000000000000000000192fcdb07a469717219f34eb84d04400b93c1480986dd89451ee2d40b2eb7eb8944c9dd1b75b2492b3af66f7fe6bef5100000000000000000000000000000000065eca88f2b62fbace2ad31e2fb6eff4900aa8abed8d52d8321eecaed1d03dde09d6c59a019d7ac5ee0e2fef4813c4021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000225162fa81cc1ac5374a949d80c8e647765912cff7cd540042c8cacac963ad3b4357014bf90c9b6575374fede6e267a000000000000000000000000000000000df20bfc6ea454e53ace1c34868e01c0032d4b8434e93aa485e73169dfcca9fcec793b80a1efcca41d71a9c86704fa960000000000000000000000000000000019fdceded049ca0c1062f44ed6dac70976de325046c5472aca8145f00dcf41bd9c574292ad492473cd65c252c58987f2000000000000000000000000000000001470e6df5643e4c30eeadf0bbf2e5013523edb083caf916ff04c5602e78a4cc8fc94f2e2ce478246b85d2347d1e7aa4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001292973848c3142cb601062860cb93df46bf2994901258cc5053616624efddf6d8b56add48d07a213f8e664d62b97f020000000000000000000000000000000011d7336404919b753f7172a0742d495123e03e26c7b561a3282937f63d48111ff59b085f60d0c70a014d91482bf546ee0000000000000000000000000000000017df9d3f3ed74139bc2635222d6fe82650e3dcbae9be1b77d0de8d750675c47566823233bf6051c05ef0359c47a13bf600000000000000000000000000000000092ee128f1843bb015296ae245e321d5a26105f20e1f915fc97ab92f65e440f086f2ccc134a6b523e1666790f6c724fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f98bf2a27ab6a1a8705b26767bd75792643fad01b2b4ba57c604d14f1dda13e8a8849360f3ce25c00f7e19b276f2f6d00000000000000000000000000000000042ddf099c17007004d8429164b7972e86c0034130d37b73d4a2930438a1a570c82817c9890f0f03b742c27abb009eea0000000000000000000000000000000001fb470cb125def3930438cf47465429fa81ee23919bd25dd0a815e9c03bc869d603de16b69a8f788e6fe9682a8f9f71000000000000000000000000000000000246b4d5404367ebda04a0538668937f59cfc33eaa40252d51d90de826b392591ef52773fb020cbf9d8d80d346a9e0a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ff5eeabcc968caba8758c5a16f7f99576d9b855eec26432a79b29fb9273842ee04890270c5d13632d9dfd0d01980b10000000000000000000000000000000008ff475df5cabdaf64e953da4ef5ee57f3d781ac235a8aa3f5635bb9538481cec6807b1def40f405400872f2d6bc2eca00000000000000000000000000000000043c5af3ea49a0346cccea47334a7f27db6a5452a21cca7f696bd19cf1458cf9bff0c6a28a21f9d202de761b715dce9d0000000000000000000000000000000001427e0fbc36df1b1e526c7e54d0453107640eb9b3ab95c05d007de80e245eff513b0f3fc65ebda885eb2e04f780f6551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073b3da9bfb751214df7b9c54479a027b62ad4c242ed74f46083a5afe748262a8584a8ecde7e754eee941bf4292181a300000000000000000000000000000000077dfbd5f9d053e578f21beee78927e35d23dbcd1ac61888c37d1a38b70b78055cdf5af382f031bb1f4ffedd43fc83aa000000000000000000000000000000000be94cb71d04b05436d9133883296c6b8786aee9aadc105704eeb39703e5b47eeb0f2310fd0a2fa951877178ae932408000000000000000000000000000000000b41486a755dd51239442ba8262317e26651577e227e12065943cc94a5abe9632dff58d9e35b5960cd24292a39bafe5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019752af76a6e4fed03c3a72d22237ffdf886637095366536436f679239f553703c7ee09ac4833560f931a0da512393be0000000000000000000000000000000016fd40c0ed3b939570ad108a1ea61410c515ebc640bbe2cf204a912210ee502ce933237c4d9ba200e8b10661f32c32f5000000000000000000000000000000000e8fc48dd82fc0b78285b18379d47f9d3a547be383da3eff27fe6ab5e00b843f00f72785836f90c7315d94cde90af6e9000000000000000000000000000000000dddcc29eb358a23540f57632cb784c846e84435f4afc8c300ce9f429d0fc6808fdcfb2c0ec8541692d737d1e9d4f0b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc5d1dfc3573bef2ca271287ee24a2914aa5e39d2f8d8d0f382803eca6092bf58cfe66ca5fb1489402b6efaae851bb20000000000000000000000000000000006e653307f7470467421b1299bcaa72f5c272cf599cae6f50ad4581bec5f78361f86617eec683c491585b83840011f8800000000000000000000000000000000186803c8071f6f80ff1dc07b7e5524678be2c82fb8eaef6139f23a67b323cdc309627099cfcc5a0b382121b02ce253e500000000000000000000000000000000012ab3d61bce2b2b6db63f9c50eb7b40b2a3418803e4018a6711fc8c7cd30f5c2c75fccc884267ea3a16a76b49c35b0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102a867e19c660666edfe20063f26a58fb2df919dedc80a2399333b52f3d6bbd88279917f851e5c119f9b25b6ba4497d0000000000000000000000000000000011caf4ced309a00ce8076a0220179a4babce3cebf396f8d7346271dd75eb7340ea0d9438463aec43a82c13279246afa700000000000000000000000000000000089dbb0e0787df6f2ea08d64cb5cdf9b83feecdc8704190a791eace58e65c0b4c736a6c7cdde5c2992b504a92d5e957400000000000000000000000000000000152c968c6dec3f13f22ffbd5145905a667bde90e6dcc07959bba3be9a1375faca94ca030c86af69767f3fce541b7d1e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010594f91e0c1640c3ebfa908b3296912f79da618504ff4a552ba377d7dc882d336906463b33442303d188f0ec3d09d3100000000000000000000000000000000147626ed992710b7471d03e9d73ffe17d7462b83d21058a88782fd13b1df83ba46534a047db6a5e161920c6168232bbd000000000000000000000000000000000ea2119c595b81c2cc2b1aaae0cf883b0ef7cd9452ed59369d8e61c20fd7d7c4faa6641bbad00d985cad2441976d7f66000000000000000000000000000000000c106eee2bb71a42b800d40eb28c9711aa227cdbbb7099869195320abafa564cd0d374aeb14f74c9926becd04073ab741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a042bc78a23407d5c42c84feb93663bd5ee833d61d9bf67602586c6e12abee2cc18202e7b13d11988d75bd09624c54600000000000000000000000000000000163e8a4eba3d3cdc2cb0a5575e21e7eeb4740219798d558c9965501e114828825850fb6cf4e8523f8dd90cd9a4266af20000000000000000000000000000000001a090a8383b76048a7f7cc4032d3ee5a13e2e06aeb51ebe96ec7148a0e6d362a64b22ef4935b76b4a72d14474b0a4340000000000000000000000000000000001a7d6a0f9245b39b8bc474cc6102b75f8e44e7870e8040e4cfcdb9244439f8ba478257d7b3cbb3dc47937168dce1d011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020558b0bde515d9f4688cd3d40f08e149866ef0d9ef72ab15c8be20f6e838135d510aeddf269a365a4c2cdd01b2f0110000000000000000000000000000000016901140ed918b7bb92934eec91233fded0053405849c7a752025d4324cda4c8380994bd96d0a71216a12f2b9cd91131000000000000000000000000000000000c4166f5636771c015bb5f960ae052f0bd30ed1947bd0883eaaf0601781041ce2623410f0e872564b486b38cc3189c3f0000000000000000000000000000000015aa95732fbab69a9a0a9eb70c68998aa3b582f0dc67664e25ada1d44c8eba3c073142c1121587407ecba648347eea151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fd6defc299d868e4c5ecafd2e80564ee369602c47fdb5fc162fa11132dab3afcded49af1ffa4cef460535845c90fac0000000000000000000000000000000013af4acbc698129722f58de7e93c5428347fb3d96dad7b308b516ffa02507d6f8450bfec5dd9289ffd9ce891a1986f150000000000000000000000000000000003cc553bbe0184b73133187de0fda87ebfdd7c02ccef169d4fe1576d7bad8e0842ba3217f3b02f79c1c416e4c92154ee0000000000000000000000000000000011abf9ba02b519ab6997c8cb86fe4fdda0622300eb64e1e50171d072f6cee8b8cdeb7f8c0f0de500d1cb44f194d3de981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a212bf2fb60a6f59cd94d916bfb0f77156bad56d4801854e261bc4836317e2afde6ac44855ab1020807997aa18440c60000000000000000000000000000000005093f26bfbc1edda0f4ff1a4f3dc5a7aff530a2785a307addabfc665087a9c3fe2721bb25d97ec5f8aedfa9efb06a910000000000000000000000000000000006ee42ce79e6f194fb96b2c47af26be1bf41ff732b1dc2e743029431b0554c201b41c1246c2e6fbd893d8b375bbea05e000000000000000000000000000000000e7b08abf0706690c0cd56165edb7a17ead5afab9c3ce39e65a0f6042802e18cbeaa45ce3a1ac928f0a361f35d8476c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000431a27b284abfc6cacd5dc404563fc6d524adc5344128e4fb9410db17e8ec91c86e3b1f282f56ccce20decf86f1e06b0000000000000000000000000000000000193469a53aae61229d7c18bdf4b760ac307165d73c1d01ce845dda5e0a3f08b70acafae0798789ff46b535e3043dd60000000000000000000000000000000012b288599902a4744ffb6fe1c7a8b2d2bf445edd7f040becc2d66b9bdb4550d1ed31b18d1c2da0793c0602a82e454d2a000000000000000000000000000000000e731209a792276d07067d84168983502f28dd1fd1cd19d7c9d6069bee0c4331e082ce457b98303932e5ac66f3fe56691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035f24edcab3b860eba731dcaa5eb6d7a5b0ead22a9316d860e1ba7a71107da3e457c52d714bf62e167b2bfee67f542700000000000000000000000000000000121525f4c709fc48f0769324c281a37f03167fd8651cd720a6db56ff20f7daa39ac3aedec2566a69f74a3241ef7315f6000000000000000000000000000000000e1ec42dab5ef9e34118b7e7bd2a3e47b333c2b43208294b22c209636570a0f99df5b094df0b2e2fef3ae1af0de157d100000000000000000000000000000000076f51d368e155dcecf85015e7cbf61dce92a1f1eb384ae11bad76903964dca6dcf4eff24fbbc4e962cccfb0e711a2f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807ef356d6e5c36fc52549cb70b6d87d3daf62904e07dddb8cd7d50e55f3e3584392cee98aa6f5f9cb466588dc0f86a00000000000000000000000000000000193453a9df6ce4173b68c8bf2751e3457bedbbd3e6938f3cdd8f2c9f9cc10ecde889f546c37f158cd039e9b66bf5963800000000000000000000000000000000026d4dfbf419de80a9fe1f366b1e590a037a4fa36d30e482547dcf10df2d394b03c6b469ac140c256834310253d062810000000000000000000000000000000008a19496fb44febb18f51254ea41af88640f34f06a26617d6cf9802299684690350a3a40af9adf25e3985eae95f364db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016d5e9786a845c8db93d1dca1af58e34d24e488068564ecf1dd8bea3dde857da7ec61d904ed4a24503d5c4e664d016d000000000000000000000000000000000827a9737aa644c9c1fb2b24dd4c9c1f350e022cf39c60501688f20c6503bb009bf46b153e1cb15025e3393aed1491f8000000000000000000000000000000000c7d723c336ecac4fe15f3307bf430a76ca5d4c389d9ea2009e895319bd3ee4f1c7d74b2fe9d977a3477a58e2c3b263f00000000000000000000000000000000158d4cc467d9a7de2f501c37ad6a99df0c7c7c66f9a08de30de5bdef78aa8b6a7b13ecb31def2d58ff1e59cd53229c551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf63588c89bf35346eaf8dc9cfdeb1a88e499ff22b53bb8717363fd4ef90bed17bb7bb45c300c4f52fcdaae4c11b361000000000000000000000000000000000f74d5de8335492237a2f666fc505e7998da9b9932a3145869f2770322a8c5402dd47b6b09e557fecefb69820b9b709000000000000000000000000000000000115eff20f7c87afafef41598bdc5b38f1585aef556eea7becb87f8fee0960f27c2f527d89722c011bd12f47762d0f52e00000000000000000000000000000000003e7e41acc2aec7f5911a57fe5ea80041587273d11d1540fc7f49aa777afbf4dc90d44971deddbb139ebb2862744cbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2be89d0029915ca37194ee8f6687d109e1b6ea43fff92ef09c4e0fed23d271fb20b0f211565b2896043f5d04ba1da100000000000000000000000000000000184442d2e9dfbff934937ded2bf5e31ca81d7dbe14eaaf77f808ab6288ecaa85baff333cb38accc1fd8cf3b780b7527b000000000000000000000000000000000fa6df31dc666228a444c54ab05a3a4aaea059dfb116ad16fe2ee36ee1676dc5a9a5c3f578337e4ae4405720737837540000000000000000000000000000000009bbc1da045a4f63bdcdb8884d260073de2fd461946d900419579c079887ecccfb394542b4a35684a66bed06144bbdaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017360695c65cce74126ce0de693c99f96c5030889e737b36e5cbc83d25e23b861f7ba2d1804ffe8e3c46d7e4341d83e0000000000000000000000000000000002dbdc94348dba998b532f2e7f3c181ef59bd11c4d95212c81a2780f71db6f25d46c5ed5020e9f17bef240fb316d2f0e0000000000000000000000000000000008e97c3bccbfd87b2b6652d6c17c958de3343253eec415c83e11ae51b602d2480436ca5af4ea12ebf6c053cedc7ef53a000000000000000000000000000000000336934e0f4930b4e18cba0b381437e525da3cc86a83f85348126e4ea0398f00f523aff05e3b460206bb87a8936f06691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a51f80fca3d163b04444cc59789545bdd28ed3f940335ae35f72b697dce043f8cb3d321ca47ea89b0aa08f487efb260000000000000000000000000000000013125a60d6e35923df1dca921eae3e2bb7aaa507fbdc42fbb07956f77b262d921c27fc458a29ffb84cf97d344d0fc3fa00000000000000000000000000000000028c55767be963f97abdec60f903ba0d5cdbb61ce8d5a4fa888050aa37f6451cc548ce9f35acea443efb4eac919bf6c100000000000000000000000000000000006f949d5c3465ffd62181a3f824b230bc7b8e5a06aa70152b32031ae97ba211d007e16fe19953d0c3143fb16b9ac6321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f05e3b8bb4a91ab52d72e0aa085bb31723c1df4b61740d532e50e96e17a1a6fca49b47f290f9b44e693db998fcf66e40000000000000000000000000000000005c16c27754c4631e3ea8200f338df7fe8f53609b94bb1bea474df51b379ace9e37f558cafb4fbe09083744cb8dde10c000000000000000000000000000000001178e4d321ade6015f57daf59eef6608f89faba1ecbc1e1cdbfa2ca72df02ba3894d57243fc3b3f24d5b00e77adaaed20000000000000000000000000000000017e68bfc11b18df40ac2482387209545d4bb6d2dc75b12652516f01fc6e818c5c5fbdbf490172b9273c1fff7274fe43a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cf7ea90f19b5c0688df62591816fbc43a9262e0eabae4c1bad98dca79772b65e967c594963267d2b3cddaea5578b6d00000000000000000000000000000000053142bac426b797be19429c9c1b75cfed8fdce3e6ffe0ef346fcd8b72bea5c7cc2cd7b0732d8263006a9b070b6141030000000000000000000000000000000017e51585634b3b8f4b9fca43ad903354eac44ec4c69fd7e38d583458f04fc50f66c36e39d6344a9190cfa860d74e8d1000000000000000000000000000000000180fa7820a301145f9c67b829b0312c9011e0df0eae7541f941159b50fd7745e2abcfa705e0de48132164c4d75f7ebaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018691d5f24ddc2c3e342992eb6f0cff29c42ab5985c7be372469995949dd010ab6c3819c77726189b4788bc9dd64f540000000000000000000000000000000002550a8e94233d6778f630962ff75aa68099b599e3a89dd620b3e572ec9fc334dc18235dec7ae67570de9167a814694500000000000000000000000000000000198fc1cb660126f81ac33a260c983b0cf6ca5c877b8c29d1ca1ef7d8c7eea976c21c6b06e0a2558ea12afa40ac1f787400000000000000000000000000000000067c38ca55a91c3d0c16f9ba792b9efa7d44553f79e35d9c0befab943b1c863e93ff3a7fe29c36a0b30c44c821f8a5da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c68af23703d87d31700cfc90f70df92100712167754288d0e047f7916ec12852b5e6b197000e96eb561d67844566490000000000000000000000000000000019fdbd3c18a77cb2521f9b958a39366a982c395c887e64957dd5a0964fc3b3c03f37ef724897fbb89a8a29b068dd485c00000000000000000000000000000000087291b9a2f977f53a3f7a9650a9cc97ead897acfc014056d36693999fa727880c10434b442a4aeddbf3497ad474a42b000000000000000000000000000000001785a50d655afb09982bb31e856f5940bbe1b817ce86dea441a0fecb4af9b8aadf27a999c23e34f296c063e2b82cbac11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d81cc6285e18d3600d87880b8b619bfd4bf80d794590b01137051264625cd6be49020bcfda2a39aacc55459de8eb63000000000000000000000000000000000fdfa381fe465d6a832d2a9fd94f4c1d6e4f335b52ef2ce12f242e43ff8eede7a3137899a8fe5ba332d06a668326db920000000000000000000000000000000000ed8429e0e1588d94cbb616c3831096d2da8837229b7c1cbd562e10aa2061ffdff6258a7109a8b3a35c4d5f434616af00000000000000000000000000000000135324129d218f8fa88502ffa3445212260e4766658abce6ef976a731a960d0d4f415735f18657e6152a16bf5531c1301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012502a89815395f8b23cd9d9a075cc59874ff6b884fbbbed3487fe2be27c0c103983e7b13f93698bf4282d94c00da22f000000000000000000000000000000001988e82d8e941de540c474e69dc014bd5bc1b609f3bd8c38dc77cab9f4f95c9486d3375a7fb0dff270403ae0f61c05080000000000000000000000000000000010934e07c97578ebae43c01fd7a30be4d2169e78003287dcb3947f83285d2825634d37faa98cf81841984cfa4f4becb8000000000000000000000000000000000306c0210de723014fa448151f2aa96a85433cb7ba3ced712356b13b3256b8037b58184d4b19c3f22b0226eafdd979031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159ef4308b9c089b96f202e27f078c8a10d54e5f025eb7b5e7db5e1b3fc9f05b7ea804a854e2e814b5a20ee15ff520e40000000000000000000000000000000012e9a4af4c4eefa94b3b9c7fbea5911c055c93468df46da67aff464fe8451cf171c50c096724f8ca4b26e2d0a72adfaf0000000000000000000000000000000015f39f05f518eeaa76d12ff47026106cb84247c21494bea3d4377f96d22599d0a2e36ef32fa7d46bec6226b75b1b24100000000000000000000000000000000013b5b9f7bd3a5e6dfaacbc76a9052a200af114369348f3b52e6baee6f9b57b89c7e97240b467aa71a33f43da6ee528ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fb482a86b75849fd7c8e79546469748b42b667630fa40ca76f9768dcd72086c69f6130aeafd5aa7f474cd70e2f1dc600000000000000000000000000000000020641a3ae3355c13c35725f9084cd3e42a0c839fea4ade23760940f4223826f947da5f346f32178dc07425bb7e78748000000000000000000000000000000000c41edf2531e2ad31a76c74add2c9be2e8eb4beb12dd716a6377808d2ddedc193839a39152ae9202e737428b88db9069000000000000000000000000000000000b965e655a344a82b8cce3aa58c9de7a647ec3496231d217487cc91722fa7098cc3ef8b4b363b19487761f229f9041c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107920ade33c19eb09a080300b189b6cafe69ca3ff83de9a954e7759898d76e221891e215b37d0c29b536a689b6a5afb0000000000000000000000000000000007a616a02a3a9688dfbbb0846b561a6997dcfddff303b3e1b8f0c2a2fc219ed8df4a390b8ccf42ad713ac056e0b45cab0000000000000000000000000000000009c37ba212c697085bc6190b8992a254d0258db7a2dfc762cd2fce1afa9bf272824272ecd0ff7f13e53beeffb95dc4d9000000000000000000000000000000001257c1434440891e6fccec82aa2f0e768205d5a09972391df032759b2fe1b55531b43497a0313b93c4a56ef5458cded71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0410d8c0d8ed93d3c4dc7de5a145dd769688b1a7b46f16291d9cbda775129dda2fdcf24e55d06f71f3a6e63e5e6c9b0000000000000000000000000000000011cb62af720b1b01f400e8d58f6b9c5919f5e703dc8ac589be2bd07e2619b214a9be451d2af8a668dff0516b6915b3e0000000000000000000000000000000000218127e535f1cf99b651f24cc1e4f2676673872d6271f6cdbef9130243e89a6606cd1850b40e23cb5e85381d6e721410000000000000000000000000000000018323dc29b6a511c4f6314f40b8c1fa91e8ccc5d4f81fbcdb779b7e037dd720174494998936a5d78e8fbab73cc0feaea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ad82660767ec97aed57da0cc4f2b66c6d42bead4645ab36a29dc72c825aa9f2b3e234e4a2fd9d25a98cf1a1e63d6d4000000000000000000000000000000000e10bb82e15b3b3a6a1bfa521ca50af7c3f2ebbfd2068fed3764f3fde6f4bab50a87daaaf67426d5be4d2dc7cc7c5662000000000000000000000000000000000025c9bc9c10e9d39a328a7dd4cc6c3bcca2f6a850d7c6d51163041e95b6f2740cb9820267f27370b1f44dcbc6a1ee9a000000000000000000000000000000000ccdc248583c4bfea8d68aa455898b0727179fa389e14108df5bec476f287c355e2bd78e0d641c16578efbcdd2c29bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c78c033b4bed84be35191bc56ac0b570e0339348625943b8867c0c2b45466eb315576119a58c6aac246e21d6f1974f0000000000000000000000000000000015329eb9703797782968359b382d490fe1278d4c2d28836a2e93c6aca67e770b095cfe61fa9f87c78e31862385f1f7ff0000000000000000000000000000000017c519d3aa05d7a59f3f36e2a096e4d5c175405a6e7db050d8cfb117e973b5e1f7a8b008a21f89decce295b30e5eba7f00000000000000000000000000000000015d2e44d46e0b3abb8636de0e57093f7fe238afd983f1c6587a16ad9a1686b71b1316c3a609d523a840db04d91301d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdbd1cd3bc6cb80a20c7ccd2598d36568ba9ace898b03576f99f05f988f062ff2ae7c5a7824f415ab92a708679a126300000000000000000000000000000000027b72f8e9d039eb44c0d25828da054daa9acd9f6456e336c6e62afa035ce431bc5a6787934ce0ed0f04d7b06d811dfd00000000000000000000000000000000002f9d2573cfa2db40ca629863f744d112628f3618889eb9fa4f75399714d1b6221e6fddde39816cce997cbaf8155fb50000000000000000000000000000000008bb491bac92c0bedc61d62187df1c2f88cde3124c0e35b70c518c82d341931ebc8bd0f3069c6032b080f430aa546aca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187bf4089aea6fc1aeaa28980ec47bfe5d2fb277abc971585276d7df4ccd12a6b2bb713b48ce5c04a078a83ac915b605000000000000000000000000000000000c2f38943e918932faa0280f0c99f46377ce356c01199eef623f5acb4a3fb8daa7bb8f12db427294f85b2ba5c26893ab00000000000000000000000000000000118bd3bdd8cc20c2de66392872b11c82e26c42186ef3015c859f3a1525707d5498add4fb69c23056a55ac1575e3825330000000000000000000000000000000000ba480f726953f5d1e8dbd908c1eb9610d298a1406c88ac48e7c01575dde556919e8e7b158a7ec8c7ad8ce9fd7c10401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135b88b5d588f46fcc6bf8418004496c9b9fadd30d4b31eddf6329977772004d617bdef80892213745da66492b4a77c2000000000000000000000000000000000ba32ec4f32b8a86cc8dd6f42bff7357d3201bdd26f42f45c8c2285c34b58e4cc2c094090966dd72ed4bda7f622a07fd000000000000000000000000000000000e19a55b28e1e4dc78977b88a8e42cb88f7a0b6b0527164961bb2b8c80be4b687df514336d5ea6bb63bb838ee4a83f3f000000000000000000000000000000000d46ac62cdec0c6831e784a2844d1933b98fbbb32dc026fdede8f934973cf573eff7e962611476b0dcbc3964e39befc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067d8678440842e1ed3d4a61805e65e2374d58064344ce1f15e57d1c9b582b81d4c4c1532bb0ca981c2615398ab80b6a0000000000000000000000000000000008b6152f76ed27ef27a6296d1247a0a14dc9303eb4d235e0391a03d98625e1972ccb4a41614308f73d82283c5fa5c7510000000000000000000000000000000018e6f93db5aa60b0bc4e3d1ba43314fc0f7480d888282656f0eea31cf53ee887e41e4d056b4b32e3cbe35aeadf5226350000000000000000000000000000000018c5dd8e6b76ef860f6b68e308f1dc898fb024d36ed795bfe66731758fad9aa36399a85709fc0ba8e3795a85681550a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c698dd3b64edf7de51d4deea49759f447a97eced9941482b5293d6d3e793cd6bb221bc598e31bc4933e7d1ca96904e900000000000000000000000000000000059da03769444de1f4e7a7fd1e622b2cd00b9ea06c70145a63fbe310c338b2fe060c228cb427a3e222faf57f8d4a36b8000000000000000000000000000000000061e9295cc3979d5b17a73102e3604665f151045fae25046ed408cfe30e7a05cde740adb5f66a329c4d7ac24e1d937d000000000000000000000000000000000b567647ee214863e5a0d9ca9ffec691fd9774b3f8cc0d683602a6e2f81f49c67d4b24b9c8cf00fea346900efd3c8dac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cf27ab35238ec70f40c9a57b13f64253a6fd2911394d77fee8084892a4bb9f68d3d05e219ef888faf56f2e8054ed500000000000000000000000000000000013da55c6d3e85bc4cfe183ce9ae6ef3938b25e699ce62fe464f49a770bc1b66c1d1508a150631ea09d0fe843f5aad7af000000000000000000000000000000000bb64d76dc1beacd3bacbbf915e51aad1be1119caa3ce79b86d47055f5148aaa3a2570ad1a34635107af1d5bb3c1e3b90000000000000000000000000000000010a27e79db2c8dbd48567b153a835fddcd441e61fec4e4969b3778251c93e1c700a2adb8d30ce05e22018ee4555acc5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f187fe6c1feb1cb91d55140d4f50c7ee9713180c3422c6cfa90c7a9943490998168dc1df5b43a10bc85c41481c3f99000000000000000000000000000000000c9c5e69db4011397da44b5533e6278322a3057a1f778c0cfc5b191ff854fb478df4982e3163e8b5c4cc905e1afdd647000000000000000000000000000000000337f13d6ab830850ca0d79b9bb93d3fb05d6a1ddd61f625d4510a8c44b60dba6139eb3c72404c58a5a8ab758f098a5500000000000000000000000000000000115e9c8f77e585d65a5aae1705df3d2c9a3bca1b719ee9bc7e7379e80d7a28a149a94ac4dd426e6b93d722ae6e74d5051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d33f79aa4dd9116aae5a1b2acef224e9a372893860f45d01fb23c3e81394e6c30bb254dd7cd6d5b682865a7fba92162000000000000000000000000000000001093f868172833ead9ef39c296b5a6049a3be93dad003201016e8fa750bb2c80f30bef185616c3f5f80dd78ec267adc4000000000000000000000000000000000be69e73f8b8af7c876d93488a4190bdf1901c02528ff289ee89967faa58cdedee464a22c905de6ef889a491a5680f0e0000000000000000000000000000000014ca3bf7884b857a43fde4825a2b0cbfc942b418a60edbac1d3a01bbb03e7b7b779252ddb408cb10b4a4fab9bec4278b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd5c024b48219670b9ed72759538924f701bc20099030690b74ad04ea020a41fb6c6f107c73987b5565ffaddd73bb7d0000000000000000000000000000000016551b21419dded301fb80819c85beaf463c9240ef9ebd08d10571cd5041c4393ac9c7894c3e4ae84d0bd7d7aacbf7e3000000000000000000000000000000000c5c703df9a581632e2b4addeb69f8103b1952ab741f5a9e4fb574c1d2a97606e453355e55420735663aac6fad22f3bf00000000000000000000000000000000066087eee4912553cd200d0f3f6f59cdbc658879ae794bb3c5d9a8ba74be1d216fe2ba6f75f6afa510977a608a04236a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077a72e5e85764ab92ce17db7f9ada64d95a4a4f6341fd6191b4f901dc489b4fe955de2fb2bb55da479ad9cb57cc48a400000000000000000000000000000000026505ec2b1ba0e2e497e9e6f1d8792d7cfca3948158b22e6e7664e8f9675851883490e166b5c22f7e132af5d311cb04000000000000000000000000000000001438bfb20e3489fe2e2dc40e5e24d846740bb7947349ae13c7b593875b8e8046cf9a6bcaa2e51941d6530eca211edce10000000000000000000000000000000000954a59b97486fae92211927183babefdea29542158b94ed5f44bea4b0a7fe221c627d1f8d1d3e8aa5623ebb39644761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a641d93e11ee8884de7cb432c61d1c810f7243f3854d36eab9368b579dc305d6360c1f16a71a79088e692f5d5993070000000000000000000000000000000000f54663ae6a97bfd2ea830ab6bbf2223fb11dc7baa55323aeecdec6e52ead211c9eca69d4d34687698556f0c7b7bcd70000000000000000000000000000000018312e5f79ce033f2b6219403ef4a01bf1287864df81cc575acba3571b1281dca7e2348917c5a9aa0be9cb2cc946c4e100000000000000000000000000000000143515bce7314ab8799e2f122ff6c2c495d9a5d570c7972da04b9d2ce19731836f8caead3a1981e4e6b2097d3e0678831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076d32e9cd6145afab1201cfc345eb6e4f55b52c5d8af871683821d0d2e87042117c28b0185059c5d1cf51fd39c43e8e000000000000000000000000000000000367cc21ae344c80f2b529ce27d18fc5c1797c2fc0d68b5c10ba90c6b6c435cb75e7007e33ce1cf416671f1b4126180c000000000000000000000000000000000871375e0cdb52f2eee0b8329f9ac0a44b85f9a8954e8e0420faad9c132a93f6c0801996a8c5ae24f4c3042e3adfeaba00000000000000000000000000000000016c60b2494afffcb1b423c9611230988aff7cca174f7de08d369a564e05ece4a508cf839408a4cbd580f7f20a1e8c5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000374e858c211b479b593dfc63f62adb33def8655f5e3c1b90cb41b62a4055dc9a20f1f534b295e7028273e2c5e9bdfe7000000000000000000000000000000000b371a79f241721c39031bd242ed3732ee07fb1d5ca2bbc754922c016fa63e6543ec0fa7474dfae1bba79fdf1bceea37000000000000000000000000000000000859f389be87eb0d345a5c1385840f9c09d073855fa1550d4fc1aefb6d0545c465ae19fbd8fa313ff0ea6ac30af903700000000000000000000000000000000018e90d560b734ad1e7c949bee7a3875be5cc108c23df9eff40b09259755174048b90209b05278ce17812548ce437c4721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1a42cd7dd56b30e6dcaeab4d521984833fab20059316391a3da58f2a95a71301bb171dda31b9914d36f4970fc90532000000000000000000000000000000000fa25bdf0705b3e3f7f52424f82c54938ebcfa6a6b20454c8ce6db013d05e586c07ff2effce4775553455f50c36437e30000000000000000000000000000000000384f4b5fe0f8dd1f73370298b4958ba0644dafd9694489782c37d3c98a660d03de1113143997b31e15a2667afb612500000000000000000000000000000000162bde8982b7e47561d2d3fd9fee1afef17bf4d46bc329f4346dcbb8dde1e8eec148381abfe39355a3753d6b8aa0c47c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee574dc3ea71cfe44572d913f5df8474bd45fad041da70d5fa8cad8467c6714567618c6f0c3984e081eb106586d2d31000000000000000000000000000000000a1942dea806be3f2d51c8243a8e5534d1358d42fee32cc463ddca9e93d718aa302e29c07d8bc0620ef0d73080cbb3a9000000000000000000000000000000000959b050e5f7215270e7aab888d79ecb704464bf04920234d09af579ba5d805b51ce344fe76c1772551cd116c6bd8b50000000000000000000000000000000000d074dcd6db84d9cb79de6303dd87c7c36cf5649ce7b7c4716f6558733f47be0d450fd8f18d76159c1a16d139abeeb281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000300df5b9d1540b5d3f814f58aa3965323916cab7529f011991b56a20bdec2275a6901112fdc81e39b33c61842448eec000000000000000000000000000000000fd9ecb90022390f196e3d93d3f032c1009c179a00c2a8fcc4e7687c3f975c6b122db61976330ed645e0bb8b276cee180000000000000000000000000000000015ff3f48ce1db7b0cf57a1a497b64104dd5f7bac4f0d48dc344799e6442715c11998d302eb10a89ce948de64956f19a0000000000000000000000000000000001244f202f01ee5f0655d538854e11ad78bbe6ad23cb2564cd87f210b40e1df8a00d69717fa522526236aecb4282fcc6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016bacfc3f203a97b0a19e2c2ec28c4785beb54ddd0b62b6b6cee09030caaf9422b29461b54d038d790a993ca1520819000000000000000000000000000000001888da8178569a652c12413060a9248ee34616e020dc99ff8e960939dcdedecad91643324cca50f10fa530cba697b16e000000000000000000000000000000000c2cf85bbdd6bc0d79502810860eb9b75ebefc81e9933190dce85cc30ddec103ab7da08d633f2a7dff259ce3085dd8bd0000000000000000000000000000000016165312885fd6e9e75abb567bbbfc51b3fdf03fcfbe56317f5a1b1bd27797ba165528cf4cbebee73ce42bb24971116d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000681c0ce8c01703b2615e003c08e3c3345ccd0cc540c79081d6190743fcfbc2a7ec57c996e7c8f3cc8b4ead0f52fcd1c0000000000000000000000000000000008bc643417bf77e835411bfd3491070994c1ecc818c4c91d375b2c3acf35c641cc35b98734f5f396ae842daf25730ef700000000000000000000000000000000184dc9bd6176f9f46f2f4e30963134672c68ef7bb9ab700fd3ca1e5e527eba87aa4cea14c5369478f87d631ba002923d000000000000000000000000000000000894c681c5f1cafc8747c50d0e7948299c9cdc86ae6a06dfa95485be11e8a88af9d17d11ced0faccd0f076a38895372d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f264fccf147b10cac6b2ed684b4f450a4e3434ff955952559f885c3ed936dc63e234f5a0466e5581a74042b520c8ec0000000000000000000000000000000003c7be8aa562a8444ed9111dfcb748088763b7c9b2beae9081a2a2de537123f2c54a4d78b762d35840d63583bc8e153a0000000000000000000000000000000010a6db4c53813ce311119760f35e4e99de88f03c49cea3ebe24c7ad82ac30cd9c31eacd7a89e600b8eb800ff4ec8ffe6000000000000000000000000000000001835815b866e55387b4ee11087fce9cb1818b8126d76b8ff4708d57deddfecd53745ea329c8022c04e698caf4a79ea421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004872105d33ef42dcda9c13373882d8cfbaeff7d152467d542c4289e4575dcde512d4fb4439f9308722bf9c9ef80ca0300000000000000000000000000000000035be1afbd8dab3ce5fbd5e193596990afdc9a2fcf229e3f5986b9e43934e7c7a189ed7745029463e11060561d0f554c0000000000000000000000000000000005bcb6629ff60cb2f2764a1246b7ac6678f66134170c681114d8977321c09a037452ce33c0a212d8bec73cb13aea272a0000000000000000000000000000000003a393349ae82b0c03b605cb7732d0c46122b6c91e84458a15faa17d988067e4618d4a27533cf23fbdd458a994d8710b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005af5ec6c2d823736e7be7d6826d67bdc603d13d2b03074d09760ddeae1a4c59e297aee84dbe2e1792665c193785c038000000000000000000000000000000001041a26288ddb6e13ac17cfc35fcb1bfeb934c48c802b5183b51b2604172bb5586a8cadbffd90f5704b2ba248a2dd0f000000000000000000000000000000000120bc86e2b282ac9f5d2b765ccdee0c7b732c7cac453785b7e2605682408c2fd3716f9a046e41de56bcb5ec9432e443d000000000000000000000000000000000b074d02f0e23793922f4e7af27c483311179484a6c4beb5ef3e359ad49708f60a3317a78ed00ceae623e91b0ee9b7a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cf2cd1795caca3f7aa0fca4b54ad4b0d323707b2aa768776baedd18abeee239888b04dbb46a17b9d71aa2ca938f4d80000000000000000000000000000000001b099610cd80b5b0b354b86c92fc57925a88a79475eda2c4becbcc4c871d6f4e50f4d251f54cbea357ed9abfaf0c6ee0000000000000000000000000000000016bdf9d0b7a3c1cf98a92e24e9b40f4fba2312460beb2bc2f70d6f078953194bacabc8c55f04eb8127c56fea3a08609f00000000000000000000000000000000055ae8bac25485be86bc891661fbf4393894465bc5d422dfdb46bc56ec51db2ed83d96a4c8d5a3c1cd003aa59db70cdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad7b0ccb4ce07100ff7371d7bd1ad42d22a8db5f085f335ee7f05a9e23625df0ff058b65af39f9defebee5b1d82abf500000000000000000000000000000000106a963a06874faca6a5ff379f0ef6fb51eb6240329dc5536ec6a9b5eafeb45dfe238c379b69c84d23c62ac43afbd9d800000000000000000000000000000000069c42d8a62662682ec991dc6cfdbc1e9fdee55a4a9bfb90788927758aee3e6693ec49ac7f5aed93162b1487a639725d000000000000000000000000000000001801f5cba7bb4b0aba9168b8526fed7a97bf1dd3ecbc51167dd894835226bbf35bf039da3ffe77cb68eccab4c70dd0f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f290e373105740129ceb0040e0385f74875d9f2d87257ffdd8ff3925ed8768fbf31d361a9dc7acc4b2eb937b30b6d0000000000000000000000000000000000fdbf6af8b698a71ba5c9f79cfa2bfd4eeb901f76c42c0ad6d4bd2624439fd83ba28fa2e463c5f681bc9ac76687894b3000000000000000000000000000000000571b85a217753b2e6b90587cb2ef1a33e3446ec14eae7195d892cc2113aa7f0aaacc80b5a35da87ea027fe35ace5a83000000000000000000000000000000000ca3d90b67300e8a1f661dbfd8fe77265655a9bd6484a08ca75e9bb95d577db3f0d5bcfb080729e8423c3e7fbc4f9bf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d18ea6c7b11be8e0af5aea5e9485e830c6011b82da82db1baf5f245bfcda85236d7b415d23312117853c85b16ff046000000000000000000000000000000001450a498d2f9f040ae4117e82df848f745870d42e9e05cdf8b9ca679c892ca8e8f8bd2ffcac959b1a216602149f50677000000000000000000000000000000000197839384739d425e2ec61536e04c70141ef315d68f9fe621775e60014a6eebf0c16226b13996c62016d313e7ed7513000000000000000000000000000000001727eb823dfa81ae9ace88d8f5c6fc6dbb4b079d7a2dffb500e7549239ea13bfadac590646180897527d2d09459329ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006604f456d2950879f3c2d2c8e0e91617d6fdaf7048c2f86d66c2fdc86c6623387070c6270757f5ed6ae2cc14c15ac5b000000000000000000000000000000000b715b310f7e2553feea1125144778fcddbe86f471bf868aa93ce7b2eb7e1e3fcf2d0aa7569b66d95dcadf9c98977d00000000000000000000000000000000000cdc16b6fb1a4d5d3ef696356da958139d219fc561bc2e5bbafb799696a7da9f2da55bf6aab22b856599f64bd74368c2000000000000000000000000000000000402dd55e9764dae5eb3dbc1943abe11de7b49e949dc96ac1409575c75ac1c4f1ace45db823771644d020b8b57cbf7451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055a7c1e2d6e222d0eaddad2977e0db74424ebdd93e30bc737821c00e45deb32d87452618bfa3bf43195eeeb6237686a0000000000000000000000000000000017e71cd105bcce40d3e141ce768fd38dd57e8bab7b22d33f55716f9f33eb002ea659440f894682f6441eb62b41512e6e000000000000000000000000000000000ca1a9c2ec02ddb3c79d8f5813188dbb77d76e32eb40df0a1e25136719decf1c9c996c1515eb1826c8ce24a052cc50710000000000000000000000000000000018f60aec758f64ca2ed60ce09ce62a9e52f2364bf394787127e0771183f549eba5d3ce2f7d1bb4b3840f6730e6f397cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7dab1d47b57d2a32cc682adaec1f832733faaa8ba0af94ff5aec9b4c64e4fb34fbb8206a53b4eda0c31cee7a8d64220000000000000000000000000000000004cfdcef8c0432f68f747ae3182440eee5d9cc512bcc56a1598d0da66b4acb9bb07178521043c2591c9459cc146fb44f000000000000000000000000000000000756397ae20adf42ed477d8e7914c7285e7e7099b5d97b7499b3fa9eae20e73877ca25903b17d56cbc82ce6b323110680000000000000000000000000000000015c148594133d7cacc6512d325fd91a5d4b88a39f6224aa639f81b6586f164bee9883273bd07aa41bab4f7f2d739dfa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8dabfd710d786f53e10aafcb67f03ef29b39f969dc8e6d8d7d48decc72d19f3222da6329124f8c6c40bb61637d01980000000000000000000000000000000004091fd0f1e7be058d0a41c7c6f67f5b7307715e6e8670961a2df9505426a34f47ee4e292154927ad11c9dc14e4cf7e20000000000000000000000000000000002f1f99a7c554fce8963573327e9124ee677a26c1a18dc68ac3e259edcc00db46ef1b8ba91aaa9c983036fa4500af3c0000000000000000000000000000000000e765368fefac0a6505f7d35c6fc71b06b39a8209b3b9e42bf929d6418cf576315cba3b3c42e26315928f39419609bf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f69cf347464c649dcc1c20507884688b7074bfbb1bcd049cf6bf686bade6b08fd0f1fc68e3c1cf1276eff28c2e6049b0000000000000000000000000000000000bd637fa3ca62fe693130899d96b0d1301e1ed968670499921517830dce791f81e1254ff245ac154e5c9b5227172899000000000000000000000000000000000b4703d1e7d7c4a3d9b2eacd668b8cfb1211cb80caed764dc541767ead7c99cf86b2e335317fb450ed0399886098ae66000000000000000000000000000000000e7adbb14450d2ce1c871be9d275879270227e6991abb6861f10964a7cabab127d4194c9998779d5a39a7cdaf64e29881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000940c8336680f64976adda4a129e32edbe205bd2a5b22ce67cbb2e4a3957aac932baf58b7b154af0edd0dda6860dd3c5000000000000000000000000000000000870b5417683657707a81e28bdf3566ae425f96d040f59cc5ba7b329464ec799d0138048d7ea15ffeb6a38c2fffa83d6000000000000000000000000000000001282c29a647ff6c0da2b6cb4cadba81aadc519f2d40a2b284eb73a4d553ff85a0874f20e12a30988a574c3fadbc8c570000000000000000000000000000000000c1deab1774321229b54d236660d7acb156a1d6bdfa2eff01095db76e2203809244f11bda9a51e1c05b60bc8333bb9261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030e176ce74b18a030abd398c5c7f4afb23c70540e0c97fe37ecf425724cabaf51f4e933a9a0f9c71a755efa291ebce3000000000000000000000000000000000b1cd0dfea1ea74350e0bf37e4dd894361e60f7db9159abfcafa905908f0e194a9f3127141c20d7cd74b2b1e8f9c527c000000000000000000000000000000000a8918a45b1bd109ee715ad059a1700327100c622ade353ca093965d0f383a5c53c1ac52a1d9c2cf2fd3f8123ecd826a0000000000000000000000000000000012752ac0b3f9f08353356eaf524226b9595263789cac18d2c4abecf7004e6cdfbe0306e787cbdb7906df1b119eccb35b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116b81bef4211fbcf210eb74b9ad6a488a587565c80607989826ae30fc5900e9005534b650effdea7fb9e6ba287022f5000000000000000000000000000000000fba5f5c2a9460f5257389bc7e13d1c3aedb3bc060a0ab66f7771f40f5bd708c8c1d212ea7f641fb7edf6894ee5918a2000000000000000000000000000000000904cc70c98f52d08a4c5d375a83ce52a02e4d7f3e9bc17318a35fd80c73a6bba4939e1f88a1bc53a3057e6017d3d60e000000000000000000000000000000000bb534ccde98988422445227319124d8c879e3bfb69eba324ec465a6051a0c4e5d691ed16fbcb3e074936c6c9c5aa0b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bb258439adb464a31a5699ece630f6e82bb0fc8e8428bb65411f0017fe2f42cc2a9ef2b69919d16bde00c661bf1fb70000000000000000000000000000000009bdf623b962fc724b0f25445114f2ba305ceca10755c2e47761d8a15b382aec53e217abf0188f4f6fa025f884d27cda00000000000000000000000000000000143613a42d42318104df1e89968fb55b13869ef40677390e615d1d46b469fc03ad48ce444bbe261bfdea3dbce2eb60b600000000000000000000000000000000127ff9ec0492e240b8ef58de89ae240f5ed77d99efb896b3b68e7d7a86caf70dcdd66a44ac6ce3baae6c63aef564c5071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e10455177e8a37a3cb0704fda8ca376d4f15e56aefcd596b9b06f4085ff2c13816aed1b23746422b07a76414643eab0000000000000000000000000000000015324494db23007989cee1357989c1b38241d126366090df57f1b4ed4be38d687b38a9c4b449d29d31b33cf403ba81090000000000000000000000000000000018b804c8362cd9cd92d64aa19f0532eed011c5ef19fcecd6d2c8eade77dd24ba87901a0a3afb79ec19b1a34b59000d1a0000000000000000000000000000000003df787365366eac38bdab6f64756166eb7d26e06087d3d9c94b084038385d39dda4edf67c9b28be029e4cd9869ab34d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083ed6f5fa455608e172661824e7ebeffaa2fb95e051139d6a0d81cabcb3f1224ff7937fd1ad936173604d7b375588c100000000000000000000000000000000186ec401a2543fa8c2cd754451d4fb7f0d10116929ead484f6033343f75de2756e89c6dcd0efcb41f3832b2bd4678b1d000000000000000000000000000000000a6f2a54455681646ebf030a368e8641bbf9b5ed21dfb741b0beb96b2035f039922d80b214655135c689081e2b5f7599000000000000000000000000000000001762007452670844790e28272ea610d943d13ea60a19f0aa0b472e4fa3f9e996bb1fa4cb874e3b42464b1ce9a3944b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "00000000000000000000000000000000014d638dc4afe028be7e3089b7e6c10a456b999d1969e042f065dd1b71658937f5f1a428362139e2fbc65b153897217a000000000000000000000000000000001593404f32e08c40ea6d6f9181742dfb8b0bbe9a6dfc884c955428ba0cc6c252b336a7ebc75857b0eeea96920be44089000000000000000000000000000000001618e6f1c93bbcd2d0c58e615251a7efcfc066c6ccaa881dc81cead71e00e3f3e8b42e65122f93b1ead9df6ae342f5f70000000000000000000000000000000002d1ad7b474fd4df5f41ee64a45813dd76ca997dda8fff0deae486eef6670446d1578cae07a8aa92ad9427af7c126efe", "Name": "g2msm-256-jwasinger", - "Gas": 2004480, + "Gas": 3018240, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000052871b5ba2c2f23baa335931812cc7c400a707d7674b38fb8b03f6ddbe2ebc165bfedb907180b27dfc924a1441a42c0000000000000000000000000000000000a6ee537b0790f94905537f08cee4fd9d4655ef8cad394d41ef72dbb3cc1b8f54b09fc2cfdb6cd45fdbb59c255ff387d000000000000000000000000000000000a20ea7b3622100144b35031cc9a209c0bb77f2f6963445dfb5b576498a7728c8abfeff156d74d501d2475f62aab806d000000000000000000000000000000000cab63e41999719df09e92290dbdf7e0528760d446a9e4a57512578d33738449343ba1e8559801a9ae914bdaa71119731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c479f4cab473402b2754300b1a4abccd5ee23a4cf93c6f477055332abd6b711d4cf574e68ce471ff64467d00d1b020000000000000000000000000000000000f38e7258c28d592fb77645e7a86ce4d1be3492bee45d150dde2fad3fb726c89662d5cf265512fa7c834fe057b33f2060000000000000000000000000000000000bec3fa8a2281238f2477710775e79c6e81ed44efe5c5c9464653c6e05cc9c553ea105aee04c70043fff8bc99388e5200000000000000000000000000000000083b2b8855bc25c16e2480ef4b6c2832beefe8aa7f967bc560d25042e3f5ca6ec1ba8ce64104a20a8e53ce51fa54ebe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159bdd1f735123ee7bb77a99d185a3ea65c77a37902b0c893c0ae8d6f5a8d71661115951c2a86c65013c311db7813b0d000000000000000000000000000000000bcc7766060572c440b8c6954224d3053325e1b9b1bfa771116ad60781e900fd3d77492ac08de0641ce1c7648c341ca900000000000000000000000000000000125827384b72387f50ba2cfefbf7d2cbd0d569b98a9aa74deab5236a037c4ac1d64a22c9131bfa1cbec1e5910306d5a000000000000000000000000000000000134b17dae92e50bd24f1d035a071adab470232a5fed90a2bbc6b6b215589eac045716b1b4b353e4ecc9d843a7f37c9ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045504927bd2921120d367665d789d9ca3bda8055506898e85065c8a31c09a5915021991e1bc05a2074f5e058cf9374200000000000000000000000000000000182f5af7da6987529f3603d1236c39a474d7952ce373dc6eb7f169cfa2a3b27505312a72c9b67ec0aff603c258aad6ec0000000000000000000000000000000013c53650e142466ed115a4b09d58621a631f869de013da0dc46149fe917197faa6b715601df6684306e2354dcd4b4700000000000000000000000000000000000030eb07e18eebfe7573fe2ed5af27f30c26d745805a8b5a6c661d9b167c353f2724a8e927a1a62524f6a241c42f62941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000283385874d144e6b9cc94b6f68de7e7bf5726e6abd1eff86310f7603c2e8428553dd87d0e3547acb2808de059036ceb0000000000000000000000000000000019e81a5675d56ce2167cda8dc7b10770ad7c5320a0e0ede8bc686b6df971e628f3f24fb37b9b3219e1000e7a7af74a1e000000000000000000000000000000000153d7ea8b437a08b6d6f94e384dae16ef0658e34fd883fdb77cf095f8187551031648090e4ab81973a138be0ac393aa000000000000000000000000000000000ee3e64357327e32109804a5d9cd16b140d8edfbf08ec38a49ea4cecd1ab245904ea4ca79ee71be0d67183104d2389061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d48e73309c1bd5690f67b9450fb474d48d7fd564cae67d4f3aa865c8c43457a932963c6ed824a0983b7f5a94ea678280000000000000000000000000000000016b42b77ac21dae1c5a09e445243070fac959cc30d625cbf72fd1251b6da33d907e642a411f57fc8840a6bca0a9641490000000000000000000000000000000006eaea88444b7430a168951e5261df18bf7aee2729b54dd5b1580ce27a4690aa459ffa676512678198a38717ef64db1c0000000000000000000000000000000019bd1938539eaa4fd6f4914793cab607982a75a3edb672cba99e45515c0e629136f29a378d960130c483abb81ff3c76d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000261308d64484701aa59a28e286f26bbb62057e06cd5ad4090c7f7238e00b292f9cd52520c989b768ddc31d2a5fee63400000000000000000000000000000000160cdca8787289470723963383690b20aa2c9263bfdc474b809c008667fc32c9c9a7ba2fba30fc7fe3d0bb9400959f40000000000000000000000000000000000e52f34db06ee6a19351fe14ce1cd2e74d45ccbcbe82b3d19c60065c8f80ef20d9ff64c38e52c52bb4816136598103aa0000000000000000000000000000000018f07a5f44255955860991622112051b21c49ae38a679903e96207c681fc813d36e587adcc2fe9c6e3b1a10c190c9e521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017018b2f86ecff208be4b1ce895a379edb2904df68c92c5d66485728b4c81c5bf7c551c73a0cd38f708ce5638fe8d633000000000000000000000000000000000f7d7abc65d5b6293aad06ecf49e69dc5ae19726044cde1ce9a386e982aece1a0190a8a94b7b53203f92d94eb50cd142000000000000000000000000000000000c0a38ef3bbacdbdbd251ebe8c8aa24a3cdfe820dd9ba951895609e35becd703f96f2405a5f666f3007c50ba2a3390a10000000000000000000000000000000015086203a9d471344ce7393273a2dda2df786172b786f8b76b5e4cd77b0431cea5258e4c1da1fd5165372b2226b803f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cf8c388634f5932e3fb3b83c4e2f211fa00108559fcdbeb847e04dff68993828cdabedd2e489c6139dd5f6e053474400000000000000000000000000000000056aa9ddcb13f9c58f448d11d0112b661ba189be679a10cf68554e263ccbf79dce4aca8ecf542a6636702326a1d3d3f50000000000000000000000000000000016a4f0dd3e42ced74aa6f26e57cf09ee8e8f948260d92a21f8d4112efac83acd9052f5ecb19fb1a8914d61dfacd917d7000000000000000000000000000000001682bd8df2af2f2a2cf570a91c57bd8200116404bfba98f43c8fd0dca19c238309e4380da49bf8649ff53a43f295f5471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a482318198aa984d6e89c5840c3ca0e5f7d35f7e53c0001e1edc8fe9482d73f170ba79dee147793e228ced0258efb30000000000000000000000000000000015a4ec001143961b29423af3ed71abe72249f3bb7f3950b21d61cb0594366c8deadc0f9ebc57f32a197fa85ecebbae9200000000000000000000000000000000133e9511866cc253be65603789882c4abff1bea8ac2ef9ea4000625dc40fe11fb0259abf2ad448f5bb6209a793ba7e89000000000000000000000000000000000c583b48aff376e01aba68e58baddbd834bdda13a68b29f55dfcc0e321fa4e136ce222869434dde95b6f8e890dfaa7711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a1a078166adec647e3ab6204b28008365e2bfb8d308921b22eab86810db0005169c1bc80674649b3c82c71371f262f0000000000000000000000000000000008a04282d81ef3b5e438a0d9d0965efa92dda03abe9e8e2cfd76e7f1e6ec598c26aff96c12e271feb61c41f1fbe832a30000000000000000000000000000000015232b871b58a6748a8980e3dd6a21b35ef9387157643415cd5870dd0509a9e5d56d83eb86174407269cd6da69e922e0000000000000000000000000000000000a1f8ae179b5073d4395fabc0e64f1e03735c24f0a8bffb37966c949982e6495bf4816e5ceaac89ff7b09494b51dd9c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a28efb0d782f6a55341be11f305633c4f7467859b7bdef48046cbddbe1b927dc96ba88b9fef900b1e4102efdd35c1e7000000000000000000000000000000000775d5e9a86c7f620555672318085d3af9c2d00449904a4bd45c56a3c831f6389f30e84b212ec56b4a191a6335949b3e000000000000000000000000000000000d949485f8be75e90d5e4ce4d1689f052d0b59f3acafb6dbaf6584a7fb65eb85cb37751dee0a2158991c78572b0ac285000000000000000000000000000000000d4558031672332824cd59bed291dab6411edf7d108e085b69ef93228012344513f968c9bf47dfb3de6fcb8aaf55aea41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ebc1d47370b8689c475b703bf10fd48035618dfeeb6e707af3b7e010a646bebf10fbd8d46e432ded47be7373aab14e000000000000000000000000000000000864c45727beb709e81786f848a80042434e90c3fa54f3e882df740e3d3bd21743c2d30e694765bacc283a7d372c3c4b0000000000000000000000000000000017c81df6f19e945a94e180f11308792d615c6a4931c23cbeea8b0079ae63e18c77219bc8fdcc7e0a14127b1bf9daa994000000000000000000000000000000000faed0ccee4cba59ff6180824c45c010c19e5e1239f48a69976c8e80dec91f3b17493561a5c89c8273164635a593ce321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000067b59c35dcd09d697b7b9d7427f6dc2a45ef79371e4ef8bd6bf1f660fe13e293e9349d14a3c6ce83d78011f0c3c7690000000000000000000000000000000005ce370ed332cb3aee56d32d7012fcf0f1f68c6f73447a55be9caeb26145b4712bcc1c1f8dda6692021018cbecebacc6000000000000000000000000000000000e5035fd1d8798553c5ab23b61e3c66bd4662f7d7b50aef44094994163d0a6696679b7c58fb14ec412697b9c29915c2c0000000000000000000000000000000007924dff85364965c207b191dab946951142fac7a9f7bdb4ac2958f7ff0956ab9f03f32d8f8fe0860aa29401156315bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bf142c242098d99f6f04dc5701e1f61b005bff70d33d4e7a569f0e3ca86655f219a1e557022abf5782b54e552d1552000000000000000000000000000000000b97b596875e5166c9a5b53a990281095fbe95e130635330f2d7750feb01a0694b49b66ecfb798c3a4c87b976e5f3b85000000000000000000000000000000000bd0181ab31f8b707ac8bc9421a9db3e7b7897b5eb494e3974fd146d41fd552dc5ddf0ec9952653072fb778f4b853deb00000000000000000000000000000000152537502998b7ea9d7707fb9d96d5c41e5e801049fec075383b59945c032b52581b186f3bfd5cc869b06e9cf1ca062c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b71d2fcdbcb0614d34c009fd3f0b87fe92b2c30ad05bdd85ac322742cf9ec3ea61c7eb6eba6fdc97ac7a045e21b4ba60000000000000000000000000000000004de114840cbaab5bbc630a8666fcebb3fd751965348538eaea15db32095c4a96c04b7064d3747a60f41af5071db38ec00000000000000000000000000000000107baec1e9df7ed94d49fca487edb18148df356654c7ac5fbfb66fe6944792fb5c5a6b919c2471cf56bf4f97634980ca00000000000000000000000000000000052606d51306ef085659da365be47d9a1ba3e02fc26295a87fe5fdac15727d9d7cd924decd0bd1673d725acc0797ffb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5fc61472ea7cb8de64be1ff5b3e52d7c20a31705b1d2b56d8bdaaf2466da4f3cecb6f7b8686a14a5d516b93aa031960000000000000000000000000000000018aa652edce2f8fff59b5786cf209cf93b1d2fdda78c1a109e87b3797a3cc1ce393a637e90dc0217afef449381c6bf12000000000000000000000000000000000bb4a1d4a6452df0ee24f8f2dd017be15582b6f81882837d94925c5f6fbca4a73a97d3b02d329107139c78fe74909ec800000000000000000000000000000000154b3442cde404083d5cec21292006beb14905aa841f042e1bae2ab33be9c341c7b950632226ed5f2f86a932837ab85a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194532d2b9054c0ff2968f75e7f8ce94fd368628f28f8ca8e0d80cc252030aebdf931e03a82f1871db50531adb32074d00000000000000000000000000000000096858709792a32e47fce14b1910548eca780a96cf92d36585cde7646a26a23ee898824c63b994a5e3586c3d727e7dac0000000000000000000000000000000015e1871332b60af53706058454ac4d2452c4e075d6759c15bd9584c7491ab06df2d45c2552f99173c35dfa173629e2a500000000000000000000000000000000086fc2e317b0c1441256bfdbdf633b08b05d95ad99dcd3a25a9eed51d4f251d5b6eeec0185238b8b872ad3c822ef68301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dce295e9fbb91b1f0888f9bf97028f7bb1a47a47803817be27635145ad6cf1df3b44c64db6661617fa1c91eaeb0549f000000000000000000000000000000000f42365014da8f144407e0e5cbb04703a88441d101fb0e32a23967ee95db5cdda0aa32f03247e44399b2828e874b574a0000000000000000000000000000000005e96546c1086cb355ed9af196ca7cd62b5dbade7039b39e6ceb5bc22522ecba9888707e4a63ff08a24aa13bc5c035eb000000000000000000000000000000000153316d66eab7a14b1d08379e3f614a3b4463b78b44cc20e217c90784b2e3ea2d2b0d4fd023ecce34e3a905d66349361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001271d33938dd1759c6452d947099ac1f91c9da921e48cd76bae17da25ef418899741ec47f6d19832d84c3a579fd2dd4a00000000000000000000000000000000188fd6819263b6f500ac8b92f1cdfe92c2c781290b8b22660010e5a7a3160bc1c69c8bf31884bbb413cb8afc44ec0e5f0000000000000000000000000000000007194effbc9a6c3eac8b7b91b88d3bf8bce25f005b927a6ed4b959c472ca57bf7d88f4a8374add5483ca62c7aba5ed720000000000000000000000000000000008dbbe0ed3b96f0ac9c6b5f376f28d514f8e9895740c28e2de00065a4bd147343faf8756fa00d05ffd9a5e50731833751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c9a1238c8909331dabb8a83aa122a818be5ad93461fb08715006002cd04a2499272bbedad21fd6e4cacfcbebca1886000000000000000000000000000000001080ad0e12616f197775f0e8fabd3828e130d283b77f4342b265c459ae35209d15dc09101ea18959624aafa0a6c3c862000000000000000000000000000000000d1ddeda081a119dcef81a4d8740c72ec7bfc9662e0bbf21d27ad68a0fb1eff768b97ad3b482f9115d565b5bb33476df0000000000000000000000000000000006c0ae82584e1f4e530bcc400444a73c3e2f4abad8f282614e769524698ca798d8b4fd104cdf23bc9a8c2b6f7847aa071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bd232992af9c9116d6f1c91f05e672366728f8876ef15948d0ee413a198ba0d9e993713298d025618b322f89873c370000000000000000000000000000000004d51f2d438fde7f261d2335bcab5d2d66eeb19e9c4e7ae3e296a59e656131ba71478e7907c9a641d6f05e653a4a8713000000000000000000000000000000000b16c3ac2b14b6915de4baa4665ad1969c025a788ec4914c15081e737276df1fe6079771075a627cbe18f6241cec87b400000000000000000000000000000000102048acff5366c3316ba0f7101f11e455756da3fa8e6d5294e542986fb67be759cd4c410b1d1bc9c9be778e4819c1c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e067fa40b492a2441284394453b01597714a2f8e269d73e75bf577061a7e383ec69f188e34913645cf791bed526005c00000000000000000000000000000000118b77ef250fbe1d54b2c0124cd5da0196f83322e8cc5eea37ee657aedb44f7055b49177c695dc24d956b99abce8e3d300000000000000000000000000000000194b536d940236b8d0b62fd501badacbcc6a030c0e69936d391ead9d42c7fc198453ea944213ed1493387e8f857e6c42000000000000000000000000000000001864c1133b4c09f719d608afdfd5ed5fa3fe9eba835395b41a1c76831db45c753877e3ed22062dda0c5951410459f1731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f8ddb1edca337f12d275a08f2f82328a3d0884c95222df797a74e3116ad2a58008bf0bcafb951345e91588a89e9f9c0000000000000000000000000000000011e320aed1fe1432aaa829bdf9e35fad456530793ab68502c5f7944a586a3b8deb3559e730f60165ae4ede62fb2f6e14000000000000000000000000000000000b47c612b1bee3152fcf5280b81ba34d570295ba67108b984fe50d54227f2cfdeba8ef9198e57b174121016c5b71d1f30000000000000000000000000000000019e49448544c55c99c736e60339715a6096e0283ecc5e300ca11e81a8f584067984c4f904de56e1f047c7c0fd90c36be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019f6185820fc36dd07c975cf05fb2352257f14723c7e74abd00d1396c56b3206bdde2efab326f06ea36d9c50496719f0000000000000000000000000000000003f25d42845cb51fa000facc1b8d41ac60bf2bec4ab963c0dddbcf3219bbca76a0ad3d3abd2d8686693b4251973a72b100000000000000000000000000000000110b34eedc5669f8d4c07a1c6cb61f5a91d25be39306cb99400156e936664a58fa40a22b1f30d702040c1acd14302358000000000000000000000000000000000bcc657119c54de95011e55d1a3de24605001c938be87af72faa65494f5e77afba27df183496c1c1b9bd8db58537705b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bc3e3c92528405273313f9789d652beb260126740d2c4641de89fa33cb0863927bc9ddae75d346c1397c7b1ef41904000000000000000000000000000000000c302090d420f500b66c4b5515bfbc90a11d2ad637b115e51fce2807b04869078aef954c520a109a395d6ec42504d66a0000000000000000000000000000000002d7158497762a5a0fc790d9c04acea583675ede5c7e532bcdabac6676c1439e5755b9c194a3a09924e81cfa04ccf3c1000000000000000000000000000000001491bc1c3732f503f2aa0931f91a61ef67d0e1e83d9451fb0f44e41535b8254ccdf7480e565c52cafdd5ba509966f2a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021ae11a089d19ffc0822ee89e0d4ee6ec4742a5bae62fae0b350ea698515e83f82f460d6f57e741d4e4091725b360250000000000000000000000000000000013c879ee5192084a89b7785e1f9c7f5fec30fcd850940a54202556f9c11cc7075e719e6a0abc22955af7a91de439087900000000000000000000000000000000098e4ba133e12906a347af023f60a1735cf0c3b696c9cf0fb587f1afe7d8ed3ec98a7d29511caa4bb988257e9c76b35b00000000000000000000000000000000135e7650ba3f08a32476a8554c9f9fef33928a54e25f765ad77bec1a3899114232cd796bfbb1b6c234e6ce78109d698c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116daf89b2b04f02f5a5d208ce339a2b9ba2f71c94b5c92a39a316821835bff50df867ae9cb274318b6f08185e81adf9000000000000000000000000000000001179182cc96a5a333f24480d6172d9940a2ea115420b12bdf71319f45a91e2caaecee5de7094f853810c46778ff88f7b000000000000000000000000000000000425136a2218ed28393b87847458037dd5df34b3be356ffb615b67a9293a17a0ee3cdd76682e833b4525432e0c995e32000000000000000000000000000000001101122b7fa5b38b1eba5f10660c4d24bb8d074cdd8351cbf2d1ecaae31464034c2802e3e35a47035a684d5fbc8bb29e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c46307b5dcb53fb17070bfb5e7a4098142d5e43927db5685e2a68d123e46491fd831d6187d1d0d5e762322ff0afe510000000000000000000000000000000019edc903165b7ef0683a2f1ec4354fc0a2e943bc99baa1b2e1e39f65dede5d22475cd109c04ca2bd278b19adf97c59ce000000000000000000000000000000000fd15280bc9d74e3fda0637f2e145982bbb12bbb8c9141f9cd1a878656dd02d93d467d7014a5c164e40e10bea721c9eb0000000000000000000000000000000012f174e7815db551a91c954879e9d03e0fe9bd818e3e29433968dd00eb498854b7c8dcf20fadfb920981f39d988b7d861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001513b9e950811ac4b3c9aff93fbc2e3435c22244057803f08f0084ea0231953c15ca504f8e359c9efaff8d7a2131eb170000000000000000000000000000000013541c11b878dbb6e45a43b4697032567e55434d7129b5e580b74751c26b4df6726d5a14526177fa0477ceb9e3122246000000000000000000000000000000001051fb83caa28fba8cc3ca1a68a04e03a9399793c59c04dc274057b56515eda2446005e6a70cf447b6b0b8b526dfdf0100000000000000000000000000000000182512afa385310852aadcc5d206ed53e721698b2016ee51edd664d7a64b3e4ff6264821f801183222a72770a095ea1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080016371bcc6718563fd706babd77d630733379f75d58c71ca416f095a16be1246856056a89a5437c841221d14b9dc10000000000000000000000000000000008ef7e000727c7fbbdd2500c76d8b7af5d55c01cdb6d374a632834638d84c47702350aab9190b72e6457db48770e100d0000000000000000000000000000000008d656e9214f56abb1f80ad880e4bef024c1e8623f10333d6bd4e401ade2e8f31aa1135f9431f0e11475d08a0f147af900000000000000000000000000000000004ff1c2c69b27174767ee98e5ae81933aad68c2ff13b0ab9030883243fbd313f9de69de67a89fe8f91a34ed30385f6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016806597ba79852c4eaced0e10463111aa3be5cddb413171688d023ad07b4c4e30708387e1af8a5409aae423a12087c000000000000000000000000000000000143ceee08cdad076340d2f9ab8a9a229dd2d8db2b6b4ac9663902c87f6b9ba3fc8e52bd4087b7df92ccf61d5d59da0c80000000000000000000000000000000002a8e9d5e20404bb416b9d3c3f37545f7374f7136114799e942767448ee3b4b2e35c8e18359a6c01d11ac382803894ca0000000000000000000000000000000003f4373155d2dc66faf10522d437e73fc3983ee916d9d06c5063846f8133ad5c04323f3fb2ab26ce88b1ae15e5c53ecb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aabf1fa38ba197b0295f00472fb7bcf4247c800d37adab9c174e69b3c5fda5e37300a56a49ab9a8f84967c51530bb8000000000000000000000000000000001497693bd1c85926f6ac7c9d598cfa9b8c1612a6fbea72ee928722d7834c886e6c05fa14c2301e03d0614efbf0eccf380000000000000000000000000000000002aa49ea07cbc663c6910ddc49a5c15d7432194b67ce1958f91cf362146763b7eb00e2712fa91d4a42013136c004ad7f0000000000000000000000000000000006a971fd1e4ae54d487c52de6d2636c05d02c6591694eea7ecf569e3a37bed0c003f3d85cde5bdcc4451e14002d0bb521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d22cc2d0772fd39d9797680e2ab3de4e9b9ca25079d16480b03ed41cea666ba8c23ec701c9cd8abb297a1dfaddef1100000000000000000000000000000000157acb8b4c371f16835f6f61841087d2c9ba58993d2a8ee13ea84edbcea4c9f0d670e2502c4e08b54751ebd846a52d090000000000000000000000000000000008fe6680d7e2e7e211a0fea79ec62cc290ede1d8a7011e19339784db155cb0601e596b45e0050ad81a136713b4b84ee00000000000000000000000000000000017bc88a3dd41d13d6d92e05a6d0753bdde8c4421cc6d87a20a9a00fe8356d8b47be94d2df11330ff4231cf600234070c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f4f02d3243c54be9e02998a690521c4d6a8566e438755a38e0559ecaf988056a7ce6a9e52b029b2e1d81a122637cc00000000000000000000000000000000013c22a66db668e64626b8e864df8071ee5766692b390f533a6268a9ab8f4815488738919ae75d0b73e893460147374c300000000000000000000000000000000169e805461e065314a2d3fba31a305c8bc0291fea3ff05427faf05447af9d1c2725cadcd9f3fbbc9142561c62392ccfb000000000000000000000000000000000ebe3a54234cf4bca0384d73e9b30551ca0e1a35e41572ef7175bd765610573ac5745a2f01805f21473eeb665e143e181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f637826b6dd5383fd29cd95fb1eb54fd798a41c82e99ea41d87736d580fa00557184c1a8382259eecd4997ae62f8700000000000000000000000000000000016f9e2a84a0600e9b059762cecd4d2abd7e0c2b5cae782f6c7a194fab6ae8d4fa121ec2c84f7a66fc7fd0165cae1d841000000000000000000000000000000001412fa940b347f60aa7df350ea8a97c0c652ec2ebf6c459b8f370ca170aa0247a04b2e3b8ce2e9ee96c14ae6ce3ff605000000000000000000000000000000000e18fcf75dad2ddf3bd29db5b16f106a4f0ec46a478615acd6e26d8c5a62ad1700203a785f4a996a473575c5be88d8d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075aac8cda9ebcff86cc717da83e4e2a000680e9978188bd56b468b0a9048bc0787b42c457b2459d18828744f4bef4df0000000000000000000000000000000014dbfed78ee4b8c85ffc44e8096a130738cdcc241cce36a1c10b5942208a7a08fabe890201acc0610f1e267c4aaf4364000000000000000000000000000000000f704c3f081b8ac59df7b78e31350132dbbb2c3017234d489cdddcc370a463bba1533b799d4730cb2d7ebd06400e3e6f0000000000000000000000000000000005de7f7f83267349944f0e87da4c27cc0328484e24355a14f84b4e1de2a48fbbe7bf40d93084401a75d10b477bcb919f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011475989ea243e90d4b896d502862947aa04743f3f910eac8b8b0941951130c55325db8b9f443503f9209070c0bbfea0000000000000000000000000000000000f029768a2f1c1163c493fa77d8568e302e41954db9080b773133ce6b0e8ff0b8cd38a7f88a972656638f854e4012ce20000000000000000000000000000000001c1f0ca237e3103c16d7d0f893079f5c66ccad94484ed53233e7c892c3a0b1674e2e405b8dc5630206456e0ab8cf4bb00000000000000000000000000000000155f724688c35f61e598023efdc8f410ba223a2cbd3150c14fe1429a672df50ab66c54b4033063b3ab39721522d791b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003308b9fd5b8ed798470cb183ae6d40e10fb020b3381bf747d9ef62c2dad08aee9169f410faea7fd4018f3cc09164540000000000000000000000000000000000f7c4f05e489d249ac723eaec7e75ec85152f9df38e963de89b574a6cd49600a8362f4c100af745a4c4d884d9e64443300000000000000000000000000000000149604491248f289c581ecea262f000cb60d893474dbc9c778a77426797762786eccbbdede16474881924a2ccdfc132b0000000000000000000000000000000018ba607f1613fb968e38190808e5604cbfd4146dd208d5a6e15daaf15f37801e36f0a96e924787f0bea8ad6ef7269f701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004d74420a393cba3c540376d78849be97c3520b52f0971a42a571e8ba0872c04a66785ac1e353190265360a442e20920000000000000000000000000000000012add2c21a97d832ffff82fb252593ad6c850594a5c3baa2c4c195fb2421535afd278f69f3b78896babd254fe5656d400000000000000000000000000000000002679f842475c6465e9bc2bc527bded4019f8be092879bd3b6d52f25599b0a166972947f0e5cd5048371128c3d18f76400000000000000000000000000000000166b11888ca58880c7d9104ead2f0c87dfd6973226056d796f9229e6c0353064019aa0c7f1cb289aa12f942131c6d99d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b2f4a146da613da4a32b837db76ba1db12defb10b4fc9a55a3da3e758e2d0c2712f393ef8930bfdc723dff4a0d508c000000000000000000000000000000000ec3b21f1cc682926a2e7826168045f68a605fd7b88b572eb75f5a712dbb367829f2b0d6f294ea9d42c9f610f803966c000000000000000000000000000000000f81d1df9305c0dfd891dfd158f0b95f6e841aa54f4c20dee110214ce7f07918e540391d76633abb574e49aa573c99e60000000000000000000000000000000019101c3d01e7d498e407976ae80e04f87ed7679ee7142161c5f35bb18e0f670d4f40489f1b78a7f66d98afea0ebeaf971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a1215dcdc1e3e0410f6acca62f31e60c528bbf66e42c4e995886f8d49f174ec66c4e64ca0bf3e272524e43fe184999000000000000000000000000000000000b6b0b2d0ece956fc3ddf0db430e39b20b8b5c6dca60923f1cd816817ed3b360e74bcf1115372317763299ba1566988f000000000000000000000000000000000b8af9b73a44674153096210edaed8d4aef5f8b7d30d183b9a9fcef63b1c327936e63aa09b0e8820fc1ba7d262baa77e00000000000000000000000000000000154fc4cba0f1b53da2927cb01accb60f2b45d8981f293f21c3953b424db8e4c8f4017690e544421a151e1f17267e86491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e9c1cf901fae4ee0ad856cc340f74f420c92d71ad76c1fc52108a2611fb4ef223a5f7a9be2b61b22e3063845c7bb65000000000000000000000000000000001907c3b981cf8a782e2904e4ff1a8f9875ca37a1350769dbfe1a692a35d24b93b13c04d8a1ac272eacfe0d4e446e8cc700000000000000000000000000000000080cd85d1e5cdb02fdbb8cc099102779c37e93d8432ec0c2637cfd1e8135b074b01ff63dcecd694334d7d182c65fc777000000000000000000000000000000000787b19c39cb5ee1dcd8f9cbc4535a689377168f3604284c2854bdaeb3ea7ecb5c17a264d78655fc479bdc25beb62b2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bf9885d825e010509147e72af4c784398c43c8493667ce6811d68d284b6cc2052dd9435b0b7644d8b7505ccde4cde50000000000000000000000000000000017d708e3e1509ab7dc64d1aaf485b17f8b851764dab33098bf986eae3c4c352b72758e4c75fae75c04c794ca68124ab20000000000000000000000000000000003081d02c97fed3af86ae14ec2feef7729714dd29387cb783745d3df6b36d3b60580707c2216ab8b0f890ab0f70495a00000000000000000000000000000000007b2ba4a3dad0dc77e7a9f8b6da7fae907e677f40529828af0711cebcfaff075b9db7433badeed00c5eb6a4650a9c2721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc32fa0801df7f97aefc9a0d43979f5126825220e990c972c48744df7efa8125a4410c6cd6dc44dcace7dc1ad120d890000000000000000000000000000000013300235bbb90bf30531361080d54381e5e8ea68cd530333a487fc96d81764f944c6b3bb6f6e02cdfdaa746564a5b04b0000000000000000000000000000000006c8ed0dfe282ed175208edd2c45cf2118718dd8564b2dd8ca77aa47e225234d302656e2ba50e8594cc92075416545f50000000000000000000000000000000017f74fc1bccbbf3d813cd90f91d750c27027a3f6fe09459d4422cef0e8b25b3fd99a644786861448a25a987971afbdb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195e461e3c7a58204dee46add8a41aef184e4e117e927f115a89aa9223110648229406220bc98f6674b13d86431eb72c000000000000000000000000000000000631721e19fcc66f7fa82e73359ab9231550bcc20a6958b9567e6943de5d744387eafbc8d298c0bf6c1fa3a43b0b1dd60000000000000000000000000000000013004653d9e98ccdbb88b8f56c32575d4cf227707f8dd595d6636d5fb92069ead4f1350cf0f4d51564aa7cf4d4117d6500000000000000000000000000000000153f8e7d62c09fea778aa23ad3485ec99ee604fefc5980dab2e2cf18e42992c56642544cd75136e56b089ca3357e1afc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003423fc99785ad4f2eff7360f6b3229bfa9c6deb3581fcbeef82e6b8aa109986e1891b1078c574dfd9ccc9632fa3268b0000000000000000000000000000000012495f9411896638c70261604df91b5f6f3689b9877d809897f84a3c9f1cd60be2409e37645d529ceb4a041fd5a4dbde000000000000000000000000000000000856a4fb80601f8ce0abb3679104e16d19ee6eeb15003050ace496d54260f298698d402b1a513e687f15822ff929d62c000000000000000000000000000000000c03948fd94be7f0954c9e4fdd1e8e133fdd114b625e06f115b1d8b42f17452609899cae392ad5f8c868c12096cdcf7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001113b93ab9a7d6aa75e26cf836807dc4d761b8114f2d3dc0a4f3e343bc1d5e420a4dbecf8b7267da857b52985b4f7aac0000000000000000000000000000000011afe31c565162a0e89e3e13567953e6468c0d62d3a30c584899b81c883ad0a0a9897668292a005a7135a21628fa07b0000000000000000000000000000000000a996e1b5a5cb52c23f682a38855972d312499e65e35aa3efb7a62c8edbadd869572ed273247423f53dcbdcb3e20c5fa000000000000000000000000000000000d88b734e6816916e0a48ccff25cb31503c0af7e2a28c8935867fb53f4f6a3aa135552c22ad254be869a80c3ee6362eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9fc3be3fba07f15295d5e48d4345d2e6000771f69aa082a231ec25ec602320a64f6491b19f973a8bdd030b4ab4c5040000000000000000000000000000000002fcf026bdafdae38274ec666889be0a0cb4c9fcc9acb477f3d7408e61a901145cfa1d27472fafb18bd78f9f2e20005c000000000000000000000000000000001570ca33d7e4118ab9b6481a8a9fd78bb567dbc1666ccb4afab5b4ddae50daa134b00cc71be7f6cf11bfcf3defcdf1ce0000000000000000000000000000000011fc0588bd80b7e54d18247c439be386f61ed6c9f5d63863e0f334c5fb97cd0e8f1f77dfe7bb3eafa36bb928ed1ae0ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033cdfb5d0d03470fb5844ad125de8ef4f0f626d9739078de01f74cb785c024a0a55fc54f70d362cf401616dfc7c23ad0000000000000000000000000000000004e66c04fe2e3357c222f0f8f09ea24e9957a29154bfb2fab2a5866d090f82a933ecf1538ab8b2f9b32d8bb191331c360000000000000000000000000000000005abefd27e32b06c2f502f29b9da74211589b58a3cb38cbd7781faeb22ef48ffab0307a54efae1335fda12509a50daac0000000000000000000000000000000010bbd7901850676d43d444bf19396e9dc015518ac71891382685be941a5c6008c39298f84c81d679fcac5eee75a712391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b1a08be282a7d227b9194b8ad60aac51aab78241033c5e70623690aecd71441a6d5e841dcf709b399aaddded0abae6000000000000000000000000000000000911196b60cb518f555fe60c80e8d21426f32b195cd0d5d933ee7a8be8f11460accb69a06f749fc56de495335bf6216200000000000000000000000000000000087eab91b23a6a3207db7e933856ce88842fe47fe63b52ef7cee10056d056b9a187af012cd0b5ffbd39002627d40203c000000000000000000000000000000000c1067c54e9004d7e9e82d3182813bf6a41e0417f584417530844ffdfa924f4a280d009b056d24879b8a0ca561c182701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085028cf5d9983702910f40ef0a354d5b984c82cfbe814e48e39e726dd18a6269ae4a6f2a96617d8340d094fabce85770000000000000000000000000000000005a5fc500e302151c35e0a000dcd5a402dfaa601d74bb37a095aea95d1e09596b317cd406a40364b7a2db95c2ad4554700000000000000000000000000000000017a12f89c6d86ee41352eb7bcaf82caac5d1051727dedd6fdc801d2f4c83ccbf2e9ce5a4f408c96690bcec496ea5ece00000000000000000000000000000000189c93c80612fdca38cf00174c3c322de96b53577b75461fa3882375f29bb1e7bac53747bd96b120e0ba167dc0b102691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191e972dd4db4b25ce7ea746e90258db2308f7bcb2b267beebf1115dd1ea284982f1ae95f6c17af2b4ac556260cde7ba00000000000000000000000000000000021468418a523c2109c93de442d99608206503267c2e9f3b36d1f1913c892af48db5048c764adb2a342398e1e1cce7ea000000000000000000000000000000000391fb11d58ca5c2a706364db484a462a5506277465117a33cae8cc76716cb4be9604fb2e61b9350fd4773145be9695200000000000000000000000000000000047061e9503407173569feb9486faf945e6fb1a9cfadc4b630d3c6629c89816e589c7655b589ae9cf4bd0c61a0ba92f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158855085dda5a4d28fb6d2e94f3afc6b6383f85cc5c5aad70a70370a60a0b8eef477c77175947f3dfdcffab0373d8850000000000000000000000000000000016f62b6a1a67579bc67fa228f1af2a2b1fc7bb2be63a90967b3671f06ed7fe6eb53a41567d887c363e28c03b6aa52d390000000000000000000000000000000016387a95a3757beeea17f6ad94d23531a30d79dc0a30b945308b0740bfc09f238f8d19349143d18570bbdaac3fe691f50000000000000000000000000000000004fd9ce59f494631a1590758b4001de8259cbc123c6254be7e6feb9f199f86e33acb983472776e9691008f63f26bd1b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b9a8019ab6159ec14003771cde97a15ea91b0c86ae7f42804ba920d657a8c2260c53b91c59534f55a9c07885cf9d2a000000000000000000000000000000000fe2dd75e32eb7a130c0cb484f2f158dbdffbbdad245af089a65971ada34fab0a9a8aa924d1622655e2e7747372e080d0000000000000000000000000000000018d6fbf330ecb5de268ed7e4775e7977f13f229eb21200370d08cd0678186716856c562d48ce6ed51f1661c93cbfab1a0000000000000000000000000000000006ced36d057992df92e3cd78876f2719eeee1bbd27bb7dfd8229556be82280ade8d1e0155cbfe8144638bb892ad608531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032a50bcf20bd4220e02a110bf29e059cf35f22ad5583b3e80f92f58162c7fbcb5eac97e7411611b66d90a7766668b750000000000000000000000000000000013fd121e2a6206b3a533305643a9a3c204a2f51a4368cd226fc8cda760770723bf153436a9b261bb9cb908655d6cf4de0000000000000000000000000000000019afd0c671403eb0bba36a4b12099e981af5dd18df80e54f6294e5d052f4a838c94eb11eb80b4ba96897ce1845e90d070000000000000000000000000000000008ec5b712553a7a254c93ae869ea8897ec6aa6fdec32c5e119bc6a0dc8e273fb3a9b35cb8c45eeaf15eb14e00454e3be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbbc0639df7ae17b3684ef5e1799d28cec6398294cf2c99abd6d8e207d8f164c3b0e9639de51dc0e60b85efd824943400000000000000000000000000000000086f459ba06e2e90620e3950653dd448f270c3d499af4d9e0bea18512a0c8f7924de5f1adeb9199decdb5e050791933c0000000000000000000000000000000000a8321e522ae78fc865e12de855d43cfd1bd93e492d5ca4b3c7eb72efde855bdfee249ec8e9694b9124c05362f7aa1a00000000000000000000000000000000179ccc5e9a2dfe6598d6887054c8a08f5900a33804cee26468aafde44d8b5ee538bbd7cfb38aa019927950174036ca3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133ee532d074b053049ee14ba6ab530ed28ed4ffb540ece4f7d1fbebf7a447d986035e1beb7cbe00d8614ad1e0498ced000000000000000000000000000000000630ea8c472e38564eb180c82842ca1605b3129dd9a8cd4b67c1a438fd9aeb74e40bb03f083bdc8adeb84094a21108c5000000000000000000000000000000000c281f5a33236606cfa25f222fe9c37336bf9afd06dac8bc7095e66d15d9f5c9277876ecd0c22413442402fc23937186000000000000000000000000000000000e3cf86b0c56029987736111796ecb12f827c3617bfb505802d17dd9c333816c61362b1709817db4d4892702409272541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc34a62f7380ae1f6078c2be739059397107b0d8e7cf84a065bfa37af13acb5aef2ac854c55c5dd8735ec8617a829500000000000000000000000000000000006fc70e8649364dcb50d505417cbaa81f1e851a2fac8124edb9ba8583ae930bc89829c730cd70f6bb5e54ccb1a7ba9410000000000000000000000000000000009c38bd474646318944b3d6a67ab1b8f4ff28b69297f5bb29f0f366840eb2b39f907617ba43d32204b4a1e8c1d4327e800000000000000000000000000000000000761b0d7b3b6feda82f6391e26f311e85c0f889dd779b8ef39a6a81e24ce7168d3efb0abbd5cb0cf7dd695ea3312c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039e8f44793dd2d51def595508c06016e85602bf124a2c4840bda18c07c1100cb6a4d54532612c8ea28cce9b7e943dce00000000000000000000000000000000003e58d3c4cb61b94c2a4ef89267aa7d8d1b04b2c931f835b04af955229511f9ee18d489353ce25f8803f9ac2dca35fb0000000000000000000000000000000002a019517fb42629d881cc7da5da0795d184701ea2e7b1da1edaf381a3c09be10309824bc6639afbb55145fa3edd0a68000000000000000000000000000000000e5d715d19764daffaacfd70bb91846eda01eba04ca880ff11797a02922db9493ab3957421668599292ea1bf5a7042b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e71755cad448836c83ba58684c5f439d919ffb76b198ad7f998933983505ce3cdc89251bf1ddffa5f24416524d8a310000000000000000000000000000000012453c0e387f3bb0b6e8e5030d1cb2d57323cfb44ccf4158ae9ac03f30846fae20c656b42e6f7f1914dc5ff53a29c69d00000000000000000000000000000000132c2fc27d55025e748964c3e736effae151ac258d6d8b4b48ff149b5926793c9792a16412d3f01b75d297061bce3f530000000000000000000000000000000001db47f50d5a44e2c1c316936b1dee0beef75ced351a0514038b1dcc442cd72e381a40f4702dccccb89457a02dc675a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055ed694419eb1602959de5215c3314c12b768b8335d4d28c657ce96a27df566653a8a86279f3f75c70969f831082361000000000000000000000000000000000e3cdb690db4bd2b726b80451fc1c6dda7be4b6d441652a46995b3c408123c047b9f69be72e17ecb54d31ab5676ec6030000000000000000000000000000000002c1e18947162d1dee8efea07464819bf22de853951c896bfedc0894bdfa7e5cf432bbe14b8f52c5fc60c15132c851140000000000000000000000000000000016e171cd3db118a187d554ae05d5a18c7c89ef22ed5406b7e6c4d943e2b3ce8998e378b22986b4246c5ec5dc9c3ff3d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e8aa91e2635f006bf780f41e25b6d63f8d142f9028abe0823c892d20816e2a2f1f6030404e7685058ba1e048b5f0d700000000000000000000000000000000085092039a355adaf8961a8c69cbc97d0ebabcc315c96a66106e7b1ee34a7635308e507206e1d1ab858838047082c1e100000000000000000000000000000000147a71ecb74be2f395d8892fd32391887cc003aac7c5b8c1c5d1b338beda8bb8c4e8d3e996597956804b1dfef173342c000000000000000000000000000000000623e15a03d69a04c425a559fa7ece093ecd63fdfc85eca5ca2bfef3cfba72965e7c9d51a8b9e062c0ecf74c613ae0551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b9138af4a2e03dcf085fd96df5188f57deccd8a3b3e460b12d88848ff1d6a25517ffcb3e3b1d02fb6b2d20face9eb2000000000000000000000000000000000a83a2a2ec639e847d64a9ee3544623d7ac4cc69bba6796fa78799f43a787d697bc97add5a4dbef03547d99734cc26440000000000000000000000000000000010db66edb6b34eb0b0420fa2e2f3091737dff9f05d8055a0e13d0fe521b59c424dc5c49298e6b7b4bc6b76bdfdf8d5a1000000000000000000000000000000000cb065b2143a358b98b015bea98fce319162869a30dc3b52ebc83707fae8bcbd8a7b50d29f755c8b4281637bee0268991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8bd0008c098fab2824b81ff4c1453583f30f94b0aa7ae778079b05a686eee0b96dd9b29caec6a68efbf0d94bec9c50000000000000000000000000000000017115a31b406c8fbd918b50c41148303fa9698d164a81f4bdd5ee7be6ca0c795dfc81738da07a64a9b0c03a2d7b3056e0000000000000000000000000000000002f255bf76896b857941230ec3aa40b90cadb4f25f540e2a2bec5fb8113f4507c9adc5b7c334b3b69ace9421bff911c60000000000000000000000000000000003663d1df92e8d9ef07daaaf50bda0066780a606fdcf0dd347331904eb0161c9ef97e9a1cabf120a8ef4bf03de9659541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a89e28ff57cc16f5f94b5923120ee4f9c9ef20f92a3ba2e0aa2113b09e93d9d962a9b0b5ea95ef394babdc84a94fd000000000000000000000000000000000144feb467d549c3dcf5d5e3081725d005e00d7d53619353a3c12878d8ef34bc4b47b5e5b93b8151b7f8a0063a15fbdd60000000000000000000000000000000008478f5471e1e36f3743079c76fa50fa768e2b35c83a38e04ca3c9c932d86cb4411f75932dd670342b852f725a58ce0b000000000000000000000000000000000e1f390d4433ba006f487feba0fa4ddeade5496e9fe6c9c151948ff175e5a1f130baa7ecd8c9b47c50360aedb8dfdc8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0611f844e12e218ab92539401b39084e38ad3ca13ee410fc5bd6540059095c81163e5b3291c7816a725b34a86ec1cd00000000000000000000000000000000096ec435bee236c2480e2285d4a2cf8de15933acce4650203bc4bbe7c5c6e76e5463074ad6a1f4f9804d39b8910c31dd00000000000000000000000000000000066dd6f01444ec294f64267216a43d065cb6f3495b4a2b2b0e5472838052a0b37f5c5d25f48ca0f54b216e71e9920d640000000000000000000000000000000013a95a519f0663b81354760f9f5abe46c87372140b050e5778ad99509c578147ce0a585935639ba6d5626397c6b723f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036712f2039ce7561a5e8182a113ea9b8dfb43012dc3872055ab39be4a7e44c1b1c3d59e1b00a69eb74dda7ec27dffa8000000000000000000000000000000000152a753ddccd4111b38197b16772b681eb6fb76fc741ca6b126fb4d5c7b69d03c2bc66aa797dcfc75565d3a2cea6c50000000000000000000000000000000000b72b538c64701858f4c9f19f6b52597487bd8f482209ac39c06536b2e7c6f50b847090a87e6a6c6911df330f3b0a720000000000000000000000000000000000e2d4b97d4d16d74e69f018fe5bfc0a5a1e770a323d4f1b8f46b2f3315d1a8e24961613d260a41f4938e7b31682539251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085075f9c660a17c9d200416492dc33a11f1260b1856f65a4f8ab0595e94e0651b29f3b894b06f0b54378827537166f2000000000000000000000000000000000638fed6c1fd4c764ecf3faaf3d2f05d2c57bfc9264133c3cd857a1e769c362408c564b158bce946e8f3de793258599b000000000000000000000000000000001635375c2c79c55ae715893eb621b95fc2dab065e4d7df8a22fedcd686588093008dcd004206fee7281dcf903e1cf93e0000000000000000000000000000000015e70440bd6249933ed2842590db0149ba71ec1b9852361c931bca8c7d7304ad0ffc9afb557fbd254e26be16300abd7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175570400c76d9e368cc656f48223052bc4544383f0c523cd2f30a1f415250f5279813dabf0b77f060a217b17148283100000000000000000000000000000000170692f20c0ae0c3396dd21073f77aa504b0b493cd3027643640aef1244eca09b3a0fef2f8e36a50fca918b2620afd4d00000000000000000000000000000000000605e2106b7d8369e6cd4f5c8a476c62e7c85354924e5c692ad40ee5e3e40bfb0fc62fda94547d1f72de4d744c6b0e000000000000000000000000000000000f12a6a810cc4247a10975446d826d47e077af2e346dfddb59f3cab1e3326d58520c6a09e71cc5a0f2f529b4a785f8b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008886ae0fd358d4dc149b0366c1db1d50cb26363598b728a82049696553e92c2dcdb2f810fe07b003e328bec08d09030000000000000000000000000000000009c814257e55c44f174bf51a922f9143a2aa2674b70de8953766323a07e25ede861c13321b8189d3d6e6955043c1b62c0000000000000000000000000000000003eb001098f5981e8b966a7ae01d21239330373d5371ec7a12bcccc1bbdeb07358ba3c12e72101451665608f65c15a30000000000000000000000000000000000ebfb130da225e9f8e5c755fe7b21c402285e1c1a5d5b61e1efd0f75caf0c93433937722da0b3d42652846b08e8ec2361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001709a81aeb16ed6b9c4549f906c1a9d404c8ff6e3122cc084814f2d01c9cf16f6055f85e3c63c8f6c7299c18d2f83398000000000000000000000000000000001032b231856afa4071f49c7d7f58b4afdeee61f3862c18c75ba9a46243db2edba3c68dc9c6414d1ec501ecf2c6fabd7400000000000000000000000000000000179bd02b7ce645e658b589743377b5cb49548ee95725b8bdb03edca25a0db46387fc257e533b4c9974f0da7ec212169600000000000000000000000000000000108c1de129985029b73be854f0c13b8d0e9803472839ea68dae7bdc28a04bfa5b640d277362577ebcd27de379102df461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e662365260344eb3f929a99e08786662ffa422e6a5a6bcae331db58a68c5906a193bdcfb5a7d733cbb3c6dbf76823b0000000000000000000000000000000011f73a0e4fbffd8be1047d69abd9e3bae8f2936faaf497045ca740008bcf943ce2d51724fe23ce992cb8e58c042d70ad000000000000000000000000000000001147840d29e5cb11fe6e62322b9b995e46fe5c2d6a879e10f631b607b280e5aac00769b04d9295e676f4cb6067a244c900000000000000000000000000000000180b0dabdc65d76aa6f3961754540bfaf96ca0af31c5092edc632c693e59625e7affe0874f40f53aaffe40636b00c85d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066688e510fcaf65ddb11420ab667c8736718abf790442298aa5c341dbe31382aea702b08702abb788c7be73dee782bc000000000000000000000000000000000da45b1775a48aa8f4fbd264e22b28e6f4682086ac41fd384431c7ff14aa2eb0fac3553e0692f58555e5cd53d897a2280000000000000000000000000000000015ec2c09df35fd9acdc6ed6f4251003a2e2a9882faa038c5ed4f76fad5c48bcdc0ad1bff4da148deea4a0e28123ffb34000000000000000000000000000000000fba2d0fff5a5af498726990dd2dcd0f42fd1efaecdaf111ed8cc6fe38367648a07573eb7941818ee94f2dd259e9cd4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112cee8d07c469f9d4d3efc7b8f2fe405b3ae09cdddae5515010d8eb381f2f1afa8885f4485f1e746ddba9d6b49e925700000000000000000000000000000000098c4e4ec37bfc1cb012d649c368c887864c973951412b470ad4d419005962a3d9eee80af3a7b8957759eff1792b941700000000000000000000000000000000199bd20a602cd70779a9f672639bcffb6562b0d865ee417584af691ddbed10480db780ac7ee946dd65c03d019c506fa100000000000000000000000000000000161962c0eb6a6ea8d94aec981dedbd65ee0d4ded2d7220bad3099daf6588cd7da8115e68d46288dd341306533376bea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019159dfba1593ecf52fff3a1c7e3d23288bc3c8db33e5cc12874a6bb022e35792003a2944a9782a3db866cb67dcdba2300000000000000000000000000000000012212fb5d4152c4a8623e9f5aead224fb12f3cd5dbc3777f4c573b96033e2ea3e7683385e595afc9cc297802a9f2c29000000000000000000000000000000000632f49f610baf38f0b9718b8c1039528f4a1bbc242143d065b1b74bbb5797ec550106c74b5e49769ec4594e5ef783280000000000000000000000000000000002e72f5b22e1b7130055d1cd8797dfda31d39a4c65c4fcd0def65bb3094f9d412b0a675daea6ac3d1f6764085fd370aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc8ee00fa425229b850af08845f26cf56d169b380d888460f5a2d91291fb775081d706cd2b0a713cd6f61f758427d500000000000000000000000000000000003b4b65e9eb74a94b07f9894b48eb7f4865c5549b8774e532fa54fd73bcfeabdd10591437bada72811d419f0572e00d90000000000000000000000000000000016e4b70e02df08d385829599cb1f8fa3e7cb3286039a15972a9ae7f94a8205bee7a4d82f7db926bf4e107fddefb65ca10000000000000000000000000000000004211b530e029367b40a8d775ac519cfca639c1a092e24380e05554917464437d50f8838936ab71515e5d0af0ffda55e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f70d567babe34fb659a7444e42ae43e4334fffa09f2b9bc32e0116750696f2cad5781bb1f053f249d11058d06c3a31000000000000000000000000000000000c29ed1eae99265188e487d056da3b3ff9314c41c27cea3985fc340cf6698447dcb49d97247f8050fd9025e5b997bdef000000000000000000000000000000001455f3e89ce1e845c11ecf3acdc8a87cc1bc212f2729463ac31fc41f9255ad5a60beb42656f3a9ccfd9f0b69ce83a5670000000000000000000000000000000017207c79fb1b4f03c17f8091dc9fda49e21f47b23028b629ce453a0bebdc77fbbb3d1f850da03afeadcd427d8fd4094e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152f28834785a27e87012c0ed6d722b989d2056f49133aeded9c5b99bc2dfb0613357442ee0bee2b22a238f1d05982620000000000000000000000000000000005b6a87546d5308af3f0b460628997abac8d563fc14cc6d4dac998a712b57e1c1c018c2fb5b73dc138ed9b8d415debdf000000000000000000000000000000000de2183b1782e661b788300548923864cc203c2d5449052accaaf5f79e32752d48ec05e2b1e833c8e6fb9ddab954774300000000000000000000000000000000110d66c8f8ddcdf71be1833d2c000f4c2f85fdcd9cde4f65b765749f9a63a368eb3673679f6151dc79cf5dc33022b7bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a5e4a980ea5abea6412ea30825338849fcdc844099798a2b33eae3e0d5cb25e7281cef2f90efd65b868946486a5130000000000000000000000000000000000d8e60949c5b9abf56fa4f509ae6acdb90c753708cd4a9eee23285cb502bf2326677b4f3b855d9d3f95332498d02a1680000000000000000000000000000000007e1fcfeee96034571d72a1197ce05ce34e53697d7a6294580ce56aa3dd49d494babc6e4f9fcc22d26ea8efa2e6d4e4f0000000000000000000000000000000001ed8ac2dcd112cf7edd79d51b7aed1bd2c5988edb02a7eb8ca01c4e30794cc246819e24550538bc7e166dbb653875e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148b994874c5ec173c38d591369e80aaf7b23a2a052ca2d280b612e23a23c8d66f70ba15746fa72aa420316767e38da80000000000000000000000000000000008ec0ab60afa123b776e5ee1b0a22d775251a465045f0da9c8f90a28320e3a4b5c2f7f5c6215bbb765b68881290583c50000000000000000000000000000000010394a5855c452bf39bb2a423518444405dc893e767fa9fd42a302b2390a7cdd2ce2dd965c1d334e774391e1b5fb2ce60000000000000000000000000000000003b6ae31ea537db4e2000516316ff3c9f520244ad452705bb576a2a5bb74ea5f7028865587a7766c515c5b2912d5a0c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9acf78e678875babcd5fd3fd9e5f62f19a90929402fd2920016dd555f298a92ea34a049cf6a741a1a9f1543553d8540000000000000000000000000000000015615f7463d0add856a62838ad0d79edb99c7572fe1d6fbb13abb43ae8d3d85d8f708595331802a921f3a357b215a23c0000000000000000000000000000000007ef456a488a08f49636aebdb8690e70520ec29faa8ae60a7fc276b9aef80042f84aaf1d636de75f9473465b9a8a4b2c00000000000000000000000000000000068d732e649bf661d279bd27264b24901c577de167036b52e5b9a091d99e83575fe503f678ff8992a6e8ed7b2f7d5d051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092c48ffa55def1ce34d0dba7cb7b8030f2fee81c2faafe7e149e565f4f70b01332e4eb9fa7c839b6c7939b9089d7eb800000000000000000000000000000000140c67c448118587fb0a78859369d05ced4cd823348830181632291a610b20f26aaf6addb7badf7c8c15977f16e9c265000000000000000000000000000000000717d34024b983f39cf59d31d426f9ff6f76ee8b6089cebf5af5ef9e0e30824546e0e64397fe0f09e493d8f4c4b215c5000000000000000000000000000000000ef10f691ba6b1223a1cf9852f015dee0858bfbdb564b8ff6eab7cfbafc5bfc18881b0671b78c6a8051daae774f9889b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcae3e13184daf32364bb7986d2d65b91037530127565d70b6140a71cdeaa19f08dd95344a9dc7abfed1d23ce7d3194000000000000000000000000000000000418cce0a2f81969a385a8b210298737133140e07544a2961d05cbb97840fc5074d27ff305838ad3629ed527f88d7d720000000000000000000000000000000006c81ba77a2f1a59e348b3dd0939ee8a0edb9436c1edbbadfa6d9b7538ff22215b8a4ec69b99f731bc6ff3943c44e0dd000000000000000000000000000000000b7b5305f8ed0bb2c848006a036117a7d89b4c216e813b223e1a860a7b26555a6bb0de228010a92551a060cdb9480ea01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018220097f007dcd0a8122cc44be0d23364c7b68f3ec0e6332902eb3ca46ba8f0434589de0d35eaac5baf3f08b5a5cff200000000000000000000000000000000170a44f73678b017b54c58422293acf6dcc8be832f55c0cdd5e124f3bfe1c3289287452825c642de85226977ce75475c000000000000000000000000000000001572796799892e96bc6ec55053c91598edbe707ccb0376ab8759b6b9486f15582ca87323f1308e69c9e690554e895502000000000000000000000000000000001383a327f76862ce0341278bcdb0bf4663edaf6d33e8925440fd2e9fb84e534f2bf340bf31dad16a975a2829367dac461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bace9b608c575d5456ef2418e19bf0e5b40b0aef913380190f54b049dc458852175326bb51072660189fb4489b1a4270000000000000000000000000000000017fba5033f5f5fa6ff7388759a432060de9121c58aae3300559f77e6ad214c04e06ade066c513776d2f2713f572cebf8000000000000000000000000000000000646954a2e21c5cdd51e3743f75e89f1bfbeb99e8cdcc2e1dfec4c14ced9d68d37912c9dba9ff5a1d5492ab2d04946420000000000000000000000000000000007bb38977b6584338b0d40a09b5578bfe1c4350f361413123e4cb96fa37d6ad9651fe8a376077a0a29c9c3d33d133c7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0c79818f4db2049d8381bde101faa48326cce226c54ef10fc9fb0997176046ba0ad2b1ecfa7fff08d06cf9685614e40000000000000000000000000000000010b2b8277d11a3d204f99bb626ab43fe9f5750a72bcc872fda68c4cddd6a293c40cbe9b610595b1f2c2b6ca78292ad7c000000000000000000000000000000001137391b4883ddbcdb4b22caa8eba53ff82c87e3f7c62677ded8cf4ebfc326c4a0e00dd699fbdede47ba7185f96c14740000000000000000000000000000000018cc75b7d282d192d95277f8889a0190df91c4347adaa0198dd76d643b1852c098658885b5a21f7d4714c221307aab0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001587bb8badaad9d73f4bcac7ec27267748c0c62160fc4a6db8655140671d624b7e9631f9eb699f15958aff07867164020000000000000000000000000000000004ccd119d74c8fa36e0d3fdf8dca487b6b27da877ab548e86b804aee6c1462350818239e438c1fa8a147d6749df89226000000000000000000000000000000000772617477bd9897f27bb602fa3b8e6a447fc08ff9d9311bcf1d35f4675a61a7eeebbfd8d5e5b6dd61eaa28405b101c70000000000000000000000000000000006ccf30b015b1bf92cc2ab1e5390cdd012494d933e05aef7772cbeb2d400be49ca4e88794f8b00c69a51c3b3ee8d35421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037e653978a769203edfe1d17f39674442c748f728bfd6bd8897517a14ab4c045c5d590da5b6cdbd116a645d591d019600000000000000000000000000000000013fc5225de46f535a68a5a21a9ac505ab3c81059dee70295ea18d24b65cff44a081b3967eb071aa72c0474d229cd9300000000000000000000000000000000019e6315c31698af5364366b788f5311df6d03e034e1c5a99fbbbf7f4bf0a63d11cf39c196ed92654825325d3c1b5f1f4000000000000000000000000000000000f84d1bde84578b57da85dc401a8a93a228274d4ce1cb36a602d7b38f9dc2b2fcec870681a92344d39651e23400764671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d2c25f41e5dcc785e507952143db7659a4cab91833372e9ded28d8e1f90292a4a8305c93a9d476377247769ab232c70000000000000000000000000000000000f8fb27adfd8236b01b48cbd06e9d51fafc7c5365160e5bafa52606654c638c1051305d6a2f45d465d70fad27cd641f000000000000000000000000000000000b3005d5e5ac6ed721feca1c9b2a6693a89b5c9aba8e0e1e6cfaa673651fe07ddf05e49723b01556eed7ebac513315c4000000000000000000000000000000000545971faceb6aca0748df65d42ece7914e2e8b9e1a3a8f998dc99caee87453dccc689523777e80fbc65dea6f03a17841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030560e81126ce3a748c2a9003d2098c9cad1db18a90c7bb817251bf032180f46955165992fc7cb2d4dcb74f6969f9da00000000000000000000000000000000036122082a8a317bfddb2666c7abfe458004fc9a3bdc08aaa9ea6b7bac5e116c13e99dc7db41ea657dd07111bd7ae3c300000000000000000000000000000000029deac2cdf87e1f6e86897c9faebd91a519bac1e87b91754176acdd99c4e6adf256b4a90dcf4283ce79e3a425848a6a000000000000000000000000000000001627e51f4c11cb74e3127c4412701819b70477c4ab2d627fa674b1e091dfc4f59085889d76a052c92f60a01e4331f0401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a6d3fa1641825a2c6cb57ebc290f63032889458dafea568c9231a109fc88c17518f2567823e10b2e997de46d2798c70000000000000000000000000000000016322f7ba19ac68a362f93e76610831223935c80481c6347909e830b18a3e9080a415ca03f12005ad0980b5d02652336000000000000000000000000000000001544753b9c8fe12d74edd9e26f912b0cb6f7045a9264c724241e9e21c42e053e5eac56d855736470c8563257177423740000000000000000000000000000000004f7a96969a19c3df7b596939c99e8325fe2db0e5195d8fe0975c4a2323e4493304a904a812f2428faa7616fb67ac9051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018412445aed14377f37cf0883540ecf97086c6761f3692e932c9c1db8ccf44e88b5c91883f90a5ad4f9c8f61a50eca7100000000000000000000000000000000140526c92d058e26d578fdf232a3d982695e0061201c83eca14639edfac4165fbff9b5ee8f231b4107e9d8ae3ef8805d000000000000000000000000000000000669562d2d796a830bba80bc1716af8cff97e03a4ab069b410f491c301c6cb732e571ea280ba1f8fe7121353e2b0827b000000000000000000000000000000000f4165223e932a354e966c8a1f22c6ef2c78a3d97ae65b3ce3484d062fc35d53c5f111d231a7310e083de349c56941691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ffa02cff33f07e0a5357a410527e99e1b13536f669d9f14bd57e0352cf4b8b7558e9477bc3e7b3387ae7f340221df10000000000000000000000000000000009075885df8a5703965e26f84cf78e1fcc5d89b1e5bdecb9ec6493277797a049197c606904fa3693361a96af99a442e7000000000000000000000000000000000852bfd13d7c103d9e5ec7264e6a1ba46a415368bc2ed35cc17132a23301153daec7818e4c0b368cff8fb094261de5a30000000000000000000000000000000008261a627bac489093caff59154ba5353ba7226061d471750d5b301121e082c1a919925e56812ad8020cd444dfe47f131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa54c8111405d0c03f35100b7c10f8989bd574398e818cbacdee17019e68b938418e5d6534d83536f94234c3ce0e796000000000000000000000000000000000908f4029605b99e06360f8913bfa9df9663e1f8581d66d4e477ef3d6cca3390d8b4f8c37cee26a4823cc2417faecf98000000000000000000000000000000000b7b9eb8d8f7e84f8ce76ac2a2d9ea6743974727f8e8024182f64390c942cd982b9ed8fb61cec2dda50438799f967bf3000000000000000000000000000000000fffbac2ddb46c588620d481ae491a2e59dc852cd4c1180fbcb5ab1af3e90626951e8e351edb4d62d0e3f76227f744e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019352a2d4bf1b414a33d6a7688e8fbe1dd15c21592ab325a5deb35549ce0fd30d3d48917cd95df9658762b8c27321585000000000000000000000000000000000c3890a1fc32cfea5ca8a2f35b14367dc04c734a1b69dfaf8d92a8a15dee11d283fbcfa58e93af067855f2c57be2d2c70000000000000000000000000000000014bb622ea21d1878bf27f3db4ac182231156c5f7073a7bce2e06b2341609ae71509af8b2891a3d603f44581c0dbc26770000000000000000000000000000000003b0151220d4858605fdb2d361763faee72a76de0907827994f3bdd4f8a296f44b04e538c91465be19c5d0bffd23e2be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a204612d53db78afca947e0bcfd1cccc2799b519513e0e36c19a9dfa3cc76a25ae86a810e61b034e7c1bb02c5c205140000000000000000000000000000000014fe93fb6683fcd34740a322a6cdb664d2228c083702f7ad1131912fc9e0c65ba67c7b11a864a093c7d3a05a25dbb3ec000000000000000000000000000000001476b6996a63c9bc64488d79f797d19c6b80e067be01bc77c2bc17cb5533f72b1dad5019d76aae722b730408848ca878000000000000000000000000000000000a2385a1f49b090f35d953313bbe66c24ffb1cb6e44aecae6259a66555074316f8f4dca99d67670101e1173e2df764b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d33d6fd3642682b2eb0fb6670b51cb364367eec72be0a53a3cbb18188c84339db3c7aae6e53d7dc93bfaced96f73fd8000000000000000000000000000000000de0f197cf67c821c8ed5deab6ee2a055525d64a29a46a452f1627c27254f0cb7945c911751ea5519eca2df4928a901800000000000000000000000000000000043d5f77b75dad9a05be2548f487cb52df4e5708974823c2e1d06d2dfe1af9f48827c57d064d5c45cc06b6e42829816e0000000000000000000000000000000007da8a0b553346e3970994a40fa5379c8e6c8316d512561e422c34058a01df801abce2bd719fa38ea119823188d2a8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8f51a0986a0c35674d96ea24b8d2a0ada8a65e32682b3dacdf3008f0f5cb83b7749efee23f27444d731d3eb8fc1ab300000000000000000000000000000000182fc9e0c8d0bb9f79cc8a66c242ca457bf651eb8d1ae530ca11a7181c3ecfb0232ea038d2066083ee6b60d2d1ebc03000000000000000000000000000000000109b3ea91b1490a7372ff2e093fdac429d713e4e96c07619e9a42208a172abb0ede907907dd4dadf18463b7d7ea4fd5c000000000000000000000000000000000b4654e698720ddf4a036401e94b9c39c2bc8ae055a6a1b19b6faa2a0e7ba824ef2f3037af846a2a2f727b982fa77faf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181af21f18a7d595564aa96dc3f02f5a6233dd524a962b76966d594204dcd4b7bb1f480fa568b3c2dd2452026661e25b0000000000000000000000000000000015c1e972c3db61c53664585426a709f873bbfcc068a93c1e86fb7790c48da425b5eacf7599d7171ae93e1b3e8f43a4a80000000000000000000000000000000019b1fa411a8b5c7c457953337185cbfdbdef4cc866fa7899a68a6f3af3d630287a4537b5e8ae71f80d05521eefc9e7b200000000000000000000000000000000152ba8a41a83c201b6e7e33dda1090ab9261313d219fc5407845c65c4e58c2ec0c58153d2bf8df57cc1dafa3b7f8aafc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a7b2ba163195a1845b37661e537a13f3f3b0c1ff63b2d8cadeb327b8b78fa5014eff4c07e1902857d3541148dff221000000000000000000000000000000001115c7ce999d4a332bd74ec9b6ecd67ca6526de7b043bd6f9bf24d0664393d381250adbd326207f60f82dcea2300978b00000000000000000000000000000000114fe0966f42826b191b7e046156cb2a6ead458bb9d69f8682c7e8436157bf1e1f3ea3b143724dbc6f3d24b9652090c0000000000000000000000000000000000e2fd360249488aabea29ba6d2a778b272676125657487f13196bbfbff5d1fe0c8d6833c8c2505401c7aa3e8ea05bf491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007032fb6938856b7b6751c8e44293e15afa939c41cc2eb7947b25b4959521568bb8dd71b94c6fea9d31abdbf262311b30000000000000000000000000000000014cfc5e63024d9fb3972e15383cce25cfd6ebd107da68a8fe736dd2297a97e209a9ee21ecc1deba8b0ca119e2a3bdc6f0000000000000000000000000000000004b52860377fc13f562103935809800507ebe7e7c707eebf64a6cc18b2f73f0ae1e9d7b9961d8342343b8b92923a0390000000000000000000000000000000000f5e1cc23e9610221a474781c6f3cb44342ae3471d457f0411f369e472a7efda951f81d623ef70782982c3cfd4c65e431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b7d8b4037b6ec3bd7fd00e99e9f116f9a8b51eeff8551443f862ed6a6f4a05ad1c8f5a905bc95d57cd9ef1e541c24c00000000000000000000000000000000184a677ea38273f7af7f689f8aa2e1b230802b9bbef501f08779f42d6fdf82eca5949f70cae268a8f61a3ade8aa453bb00000000000000000000000000000000090edb16254336cf902f07a360730d22c6f6dea915bf55d4e5ff00799b4055f5a9f467d4a6a59e7d8d2e302a2a461e99000000000000000000000000000000000447f0d73530ec5b68e8f47e97a77aaa6a1abfdb4b046760f50478c33d8b4f22c963b19f146d1c600059ac311658ac6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001165da18a43adcc426c8d1422f8e43ad33f406112679cd702bbef5442617f5defdbc1f7a02e2c5f643b13bd2d4df72a6000000000000000000000000000000000ccf19a5f22b8e3bc419d6a870032431793b94790a60863527b58855bcdfac5ed0496a9c50097067c0c9a9b14ef0b29c000000000000000000000000000000001085f5afd2808c359d2a22cb6e50e195a0b1525f04d8f95b73312ab7c09a15e732c35fd5292868a806b8fed952e1fa6c0000000000000000000000000000000008fe2f68ff11afca8a236fab884ff4ad5a97ae6637fc1f2adb79be630b7587bbe0d7b659b8b8c83efc3de83c7cbbfb111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f33b5121373d8139214ab8359f28791692dc33de2673544458ab4058a02c983f0226b38e926eb6455f15414073c55600000000000000000000000000000000195ef0ab287f17cc11b667e627b69c4dd5fbc976e81a48451e28c6be371256ed682761fcfe9ee5302dbf7078768261c6000000000000000000000000000000000e939114c8cd332043f5e01b8b3e606e48dd4c259264dc02afbadeff9488279d2427734cd1abd890c00364076c1ca5a00000000000000000000000000000000006444f86ded8a99414ecf6ca864321ac29b075aa01337ee689666c949c9ed046b140f31f109733d9d949e9a5598c14821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000aeafd00ed00f02f1c9a2427675e6f2bae46842d02d9864eedc27082f64bb70b47f3a74e65e4565f1c1f14198a2b89900000000000000000000000000000000040318c66bdeae1fbf2195f7c456f1421baeda98240c7bcca59374ea315f04f233844b2f826b79a6d28148ce1044ee0b0000000000000000000000000000000002b727883399298c762502c10c920a5f0ecbfdff7d0f4819b0e72df3657353e42b9817c76ac817910e4b048574284b300000000000000000000000000000000017a22d333462b4d53313f556efb9e29400852051f46b07455f98959578b40705b6bfd01cf4ef4a9c7a0ad8a752287d7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147c2ce6395844cc949a4a963abfdc14f1090e149097b6a14198560114266bada4cdc8861a6070add3a30766afd1b36c0000000000000000000000000000000011570b6e940f932ad6d0295daba39f0fb8705c538e13f877e1ead99057712e34276422bb6216ea7b61340532948dcda30000000000000000000000000000000007f6bdc504a99ee9cd57fa5005fa0e0f26762b646363e61bc507d97f82bcd453dc681b807e31e7d497b19d278dd0ee14000000000000000000000000000000000805a1dd2afd8a1a47fc363a4dc4c6d19f68c078ec58982249576f10f1ba3452d53318087701f2d3ced777955a70d8161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e10319d1b233a6eab491b9604ac2086685d29c19a484155439c1bf8c5ae26dcbfad52adc283a3df59b048b19c95590f000000000000000000000000000000000b17d5d1d1c6a73214ef95323e66e40653ec7069f8b109466f2cefeb1a359948e477df27f55d6294d274f633cc38ded80000000000000000000000000000000002232d2020bf2677ceda4ccc52afedff832115a71d4e589a57f1466ec09e1968621f5c55e126d70cbc02ec2072c693040000000000000000000000000000000012bca67763792c838e436882b59e415b77808d37cb6ba90455a7ca74784a8dd9c63a035cccab545128985b59cfb7e5931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000244b7a88515ae470ab4c535452514bfb99a605eb74122e481247c0332d9ddcc098377ea9a35238ef8e0004a1d6551c1000000000000000000000000000000000038a4f4a41219c9cefed9764ed2698c5ee36a47123080c0fe29a81f4d04ab6079f7c57420b889ea704c8bd5d3cdc5fb00000000000000000000000000000000034381085e74f8717a84e6cd6969407fdf50aeaad39e42bb6d6ee46759ddb5cbdea9a163a5c7f928ce65f69301f4abf400000000000000000000000000000000070cc29ced091bbd0f8ac95ed675cc3d97df4fbe1e7f89872fa354d8a8105a9d15dbdba00b2935f6d18b84b824b3d02a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018606dca928287ab29aae1875021e2f988f9ea1ff28cb82ed1e9a00f983544be4b21d13e16be2abd8b36da001b81fc080000000000000000000000000000000004fd5f248e14dce79fd25766561e88d86a142d310de56e1b132d2d49406c2dc768ed06c0b299145b9576c886f6889bc70000000000000000000000000000000000333f28dc5371481e29c1808b455a5941d3e3a2004767887366b698c208bf51a586ac74075ff23794b62e46540280120000000000000000000000000000000015a6101d66a734130f8cb44b0ad89b0fc57abe45d6cd48f91d35dc57c2b374bedfc5ffaadcae9ef82e43ee0b36a094861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a734395608579021e9ca428ba5f47a0235ac89c7115c467c22ecfa654d6e26ba08243cc76b037bf8d38828896a7f1060000000000000000000000000000000018d19f3448d52b16eb2f09df1d92ef62846097d809a9e4f71b5201716f8b5b7153c6cc94d4c7d6dcccf62f1490c47be8000000000000000000000000000000000e5563686ed6668f70abb9f59f5206b8ba1fe9ceb0efb7ea9785dbdc228a0eca6fb0652ad8e61dcc785c5cc2cf0e06120000000000000000000000000000000017242d006e41ede3dcabd4806431a784328f50b840f05dd4cac3a0d09c8134d1f0e88d41bc07c05111c48d2871bf6c021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000960fc8ed6359bd4f52a4be2042326a2c4d4f6efa191a206504737d171a1aa56f4d07357f1834d645833d0a9f055b56000000000000000000000000000000001407670157b31d38812a82a8eb8b58d80331a367a87d5a6271b93074fdcab2635a3262c36b820e639938043b3bb93ba4000000000000000000000000000000001339ac3270951d45e020398233649e07d1e74b1fd88b6a9174449ae7b6b6bed15094f346aeb5632bcd254a8cb502e45f0000000000000000000000000000000011cf85e4c5fa591ab0c0473a09572c483cb6f4d5553ce4b99ff07899b6f66e5414133dde4ffcb026fd71eabfc55d7a6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118a3b5bd9a8367df6af54b09b83566b6769bd71c95453f8e39ef9c7d452f3b3b3f1acf1f8efdd69a434a7cf308c584d000000000000000000000000000000001499c3eed43d3e84064bf99f64a9846feb2d39855f36371d280dd64e1d066ebb6b530668910dd188f8150b45f9b7fee30000000000000000000000000000000006189be0d9b5d75b72de13b4632344701f7c4544e6a5c0661e9b7cfca7d9c8f2c921778f51c3538a2bfd374cafd88fd1000000000000000000000000000000001835ab6e36a6dbedd7bb79a48186cadc8aa8af6981024ac2057b412446ba01bb322c5d00d2e5b678615c8a296b080a071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e49f5e9c6650dde9bbc767b5fb8eb8ea43455653193fd0bb6aeecff8d592eb9646b8c11343dfddbd0a255f4ec4c22800000000000000000000000000000000114b6db8ba79805e930ace5577806707307cd5fb644d01c6b41af665bd90e8b39a7cbb8ba1adaaae2e4db077f980fc38000000000000000000000000000000001215ee646eefb826bc986c6adbc591843aa3e318a6bc6886725185edbac6b3f22bd39593c57c6a9c5249028696dc9a35000000000000000000000000000000000796bc5b4770dcd90556aa5aa9ce03bfde22db4af927970d682af1d1a5c383edcbc86abca431c341981debf16b527c451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190fb3ff260b07bf49720d832ba515ce384d31a8bbc34bd51777873d98d7730830a4ae9242ac3cfbe6c80a56ed0eadac000000000000000000000000000000001882c15afe9b86b08f26dc6bac2eb69041e3ab058a7bd2fbc2a582c3647788276525f1e3ebdd8dc9c39534df33c14047000000000000000000000000000000000ebf9a3cc852c0e662b770a70b45b946c629d1010fde4248ebef31c50bc7500a809cc0e8cafb3465c2e06a245958859a000000000000000000000000000000000539d0956445a8b86685d67dc64bff935f546641a408c2a506f3a2dc1e57f41b4444841562063cd5ca7ce2eb8d58bfcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111a80b8e17a45740fdbdf94f5fc15505f4ae2c979874cf897bad03c603eac375ffd33cf8a75d71b88f348016b47371c000000000000000000000000000000000890117269dfe3986f2ddcebbd203422d631e93a181681102a691c2553b8969e79a3f709010e4adb25013fe333dc5b9d00000000000000000000000000000000188af64b5818fee9be86e9c0bf11f4e5a51cd6fef97de84df00b6355564bd00f1748b43ec5849dc11282ec4954eeef60000000000000000000000000000000000ca6fb93ce8aaabe7505f059c71e264fcb810dfe2a49bf23a48418666786f29f2b5efff04f459b862ab21274653500591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e2c1b55579b95f8ed370d7118fc276057e73d4baff293da1db3945dd1279e23136c6378d8293668688e45943fb4d430000000000000000000000000000000000c410da02c7c32f2eba77b8e2a085faf20ff9fffe799ba81e8b60c29198fd2a22f12bcdc9553df432861d59a5e307120000000000000000000000000000000002492568d25b596057e1013fc77197df068918bf75bf2095f7f337be7c9aed7e368c7282b935d41ebe94c489cdd4efa4000000000000000000000000000000000a0cd8e4bbef4537fb0cfbe75d13c709c263dfa64ea1b04258559c512a1eabae2d1a36cb7156e509f76ffa8efac7acc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129bfef481b0fac1c327a2e47af1f9ddd42f782cc0d32b16b91be618b78cb0d0b45415f6bdb82ff5575b7a05868390f800000000000000000000000000000000163a0b1bfd787c1270164997b7ba2e2f0592570972fc9bd6a11d92c00c995c6c4bbf4d7832b88e48029b0cce424d4a550000000000000000000000000000000013364d52522e84ff293d03b7ad2bef4d8fd56612c0a60b8c8208da701166c12415d1b226992580c4c2f1a110aa30486700000000000000000000000000000000142931ddb4d4ccff2b29ead016f55c4effd2ad855afca77b0a3d58e34d3a3c07030663478408eb8fde9b775b67d3a9491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f4eb6e030980cf76714a2e98377c4ed296a248eaa65b63825c71a9df5bd69195782aff300a318c5b0135bee6f180310000000000000000000000000000000008b33313b29587b3d8f892ca9db1d924eb14836cc8926154379fbfde09b11c72a1b2e732a5267862ed1f61257e74bd3900000000000000000000000000000000114e0a4e0f937fbb5d1ad42c8747009e09b6b6fbcccf392ddfc724c57c2dc23215c2a9b6d784dccf21bd099c93d9c3d2000000000000000000000000000000000ad5b8f329bd0ab0ec2e330f92cdd2d8d69ab01415b8fd3b4d743a23290f0c1581f3648989218cb3021e03be447e8e031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007712221ffbc33d76b18787503a3e1049a67af192e78bbeb7faa5d51eff21e1489cccc82d6dd7dddf53c3811c3f2c3480000000000000000000000000000000000b19fd27233e9ac26b011c09d0ca875855e18265133e1a8ec384bb6f4ba317263b8538a37764543ecd16d67594b8ab300000000000000000000000000000000053abcb1a7507e1d94f033666b62ad1970ea372597f13b572db8905f8c94c715888a9ad31e0dce1f56a42e3cdfe9b19000000000000000000000000000000000036bbad31764cee56070df32db5fa3d1886179b125e5bd342a3fa93295d0238731febd01c7d22560bb64b1adef0139271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068f84c19570bc5eb5d6780f2ebc0419c78dafeacfc6ac486d093114dededa2d2cdcf462559137b79919ce79f5debbe6000000000000000000000000000000000407b5d8793da299da23e747342605823080ed74203a415a9653f2ddf8b399f785ab8aea87005f1a01f35aae247081dd0000000000000000000000000000000011aefa333920867e9bb933a0a72431c09adb236e16274e5e83648cb796fbecf3d1f0a4021aec6ffd0c75e42a154560dd000000000000000000000000000000000584ee068921e9b5f11ae53953ee4b0b49524784c86fc4fa09d0cfcde8fa87417c63a448c10840601293a1e2b46142c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001812281eae1212851ee34d25f27f24b0d931e24cdf04b7323f87a9401966c50d2d9ac4b389c7a9dce4edd4a9f6317662000000000000000000000000000000000a08abd9dc218d21ec91e4377d93bf1a5d673504ee9f60274be05df7dea164391a36c53739c4b174bcb680d5ec0d677b0000000000000000000000000000000009f8a4348bb2cd5f71136125f3049cd8cdc902ac3da99327228364d2397bbd1abda4ba66576bbd8bb0a7a002a90087c70000000000000000000000000000000016d670a483bd40b836b21f39c3b6641a19e7ce61072dd3b14ad371553a1fd9bf39f6d73a7490785d75619bd6569454d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019305f1f36507e0e8521113e3bbc2adec7ce1c049de5a674e0085a102bf6f1d42338522b4f09a3961353b057e6db97b80000000000000000000000000000000012d439f0b94eab2216747fbbe257b0fafaceb41d38e4326023e4af91c840232947bc1b4acc0a2c8c283001aa1f42f66a000000000000000000000000000000000e0d7ebb5b7ba07fd5449df40ffb5f5719079ee0971878f2ca9607139e68249da6bc15bf7519dbcae55e3b1bd1a61fac000000000000000000000000000000000512c644575503d35739f0d605b5eac698a3325960eaf107fef2c2d46ff5cc6cae446a42c2dd09bd2080d060f349124b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147eecf5f54d9e36215cff57a3104e228dfd6065b1c26f900455e39c04392b3bb183d755349b879770bf3dcc1627e16a0000000000000000000000000000000010432b2166989b922a30f29d2f0beac393c404a4e07c60c45e68f162930d419e037938a499d235d9c800d8257af734080000000000000000000000000000000019e6982286bf1a6e395c043e8c3c96eced51045340fb00d3c1054f1c946bc99c860330ce75fbf901327ef7516b6a4ea10000000000000000000000000000000012d700492a7fb1991c82664a6138ac7d1c9a1cbe684a76847d7ee970b0eac2b7ba990a3ad44054267aac03c8701cd2651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024f7cff881f2c0cfdca829a0a2265c4b129e28c5d57fa3da878b3f2f7474bca258fdff29994333d8ffc11de9bd6a3b40000000000000000000000000000000007ebb0c5f4696859943e60ebb0bf0f945f01c92b17464263b9a0b50a03d54609273d45736c633f5b433729b788b935410000000000000000000000000000000005b614db814123d240cfad4fbe8786649d1e591067b8531c18bc07176e39744641be4d0ad0d5b09a8f734f69e016ccc20000000000000000000000000000000019f20d67b9b6e3c4d62ff1fb6392c8c9c647c014b2e8b32e6fdfd0c3625c0a35c6c93cacc4c4f4a8f712c331daf11eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b57ade409f3c95cae3672e11894fe94abb3a619454e78bf56a585c511c1374778a809f38985a66f2600a7d3c3468906000000000000000000000000000000000397596b505cef9e1cebb8539635d421954b00c4ef709262f932a27e2c5cce29f005ee1703d725e6b38189c29553626e0000000000000000000000000000000013dc0221eeea9740f34762289859eafd1c4e14f76dc0e4a15557a652c0062e76da199bed52bbfdc1902318e710ff88db00000000000000000000000000000000071e13a72168087b6e1ccca65f7beda0d1ca96bd7dca5f917986868a17d643f20a6140a649bd7ac024cb9293e48d25631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011365b62b61c0f3f6e021cb815c7c8d1b5a005a2169eaaa27bf8a230af1f169aca2ac71a44c2e6139482f0908c95f25f0000000000000000000000000000000007ccd54a9f3a898585d68af29032babb808197c6e60b3f9e41bdb9fb518a3bf5c90620e4bd35e7c533005a1b92f3b4c50000000000000000000000000000000002ea122b9908389c346cd77b5fa725bd338becc89dfd423b4a688209adf9894f34672757c009f2db07d4208c743cf5eb0000000000000000000000000000000014e5b66d4026ebe0bf79008fe22ee9dc3783806f7c0b96a76bbadec13e7312c412e11d63011038b06d32a1a2e0da93c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4a459a3b459eac8ac5258a501a6ba25c8fca39ce1dd89bc921d4bb313db4a536204ce7a1078d27aaffebaa29bcdef700000000000000000000000000000000163ea3ba94263b16e5fe968221a5c454e97d1c15462a36d767478bceadc21f5973d9cc0b3edd89295220655ba13c16450000000000000000000000000000000015034b768dedfeee249b008ff78a64a8bc5582ce06761ea2684b249e4218406d42d56e600235d83463c4bffcec8a9e7900000000000000000000000000000000175100ef2d14210b320998f4e2c3106184065036352b4d7b77733d7b3ea5d91173b16b42ecf04345717644acfcb5c0851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064ea2b66e11cf7da1438edb1f9e3f72b622217d5b4b2d353de461b0272fa549064eb948620c368bfbe0fb7a6ea80ecd000000000000000000000000000000000c591e5b7b0cfd05435b9a56d0928a2a14c276b6a3896b637564fdadc5153683d672493103122f136cca6143978e2e11000000000000000000000000000000001625529d10ce4564f8edb8d4157afa00719f451297b75e3d095df0a54e4302588caf229f21de0c0372a56f9ec2d7ede0000000000000000000000000000000000bce063fd03f31a20c277434295701e20ce668c4e97ae83edc39336a81d9bbf5725118b608cec15d4becfcb2596ac2601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001547818ac7f74d0820a9786e0ecc319696a2c40643a6276f6bd918e5752e49f148f93d1efdacf9fd4b685f1dee3d09a70000000000000000000000000000000014b92c43c212c16334f4d066e00ffe68fab8c9df45da27a72eba6be871c1edb5ca5ab0697d7a7ca1f1fc7007b357a8c40000000000000000000000000000000001ae36b106b160c1c4ba7df26cdf50dec457b3077e709f80877240be5c022d676b3614709679abf7e671835d5b28f713000000000000000000000000000000000e2e0b144cc06e0ec1d6031595786dcee7061264fae10897e2cbc65dfcbe0c1954f7111cfdd30f63dd5a0a33791b92fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000edf04176b736c041bd82b913b9b788ed2b5b9404589d044a672a6069806c01ed07b25b37a7c5310a127f35e6e23925000000000000000000000000000000000fbb3e0f75dbd302453e2b9893decd0dde996860b530027d3ab9261b0874a28da530a0dc5da6fd22c293c143110b2f010000000000000000000000000000000004ea48fc776b6f64c683c8aeab32b0e483040e7c6a569ba91ce2762ef6dcd5f031cb8eb252accff2c90af515755ad70b000000000000000000000000000000000d69b8b4be292e41edd5e02879062477b67f76c483901d3de33ce586df982431b857b32da783ea9deb057ed971f324e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001643b8063e6b0d19e4b6da312c7c50a5c8a9f87ae705be985be581ef99d0df7a85539d0ea9f4680a338fa59ec3e21389000000000000000000000000000000000e244ddcd204e701874401aeea4aee55d4b0d1dc30ea2e486cc7f842ed6be9f39be2f2a577c7088c863a43ac7d3f4d28000000000000000000000000000000000c20f27c6ae0aedf5f7fb0c134fc5a5bdbc68ee6e4109b867bd3751edc7b3f8aa02549d7dc944a24fa69d7f7ae30011a000000000000000000000000000000001129dc6deded0ab3f53c60933a96ff62693a4419d453d8d240ce6f7ebd0a3a776d6100f35428001eb755528f342321941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfb714de3f8c310b0b70525670b5950ddf94da002f74a9a3387a5709e440e805ee8b5f7b631858f51e665c253108c8d000000000000000000000000000000000a20ed389c6f0df832a5ec5bec9c02bf890499d864f9ae088ac755ab811060185bbf9a53516f4b444cddbb0cd30d5468000000000000000000000000000000000d534736b52a7707d863f01ed59f96dd9d3914c03e119a3dc201f302941a26987bb53c77a27a5f06f19413ab74a3d06700000000000000000000000000000000090c7391a190a472f5ca9868f506625b0955138764be339ccf351a0b8e2540d129378cb5528bf0059a040173c56853741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083bc547c87a7dde16ce9826c9795944885ece1d2ce1031298af010d6827dc82a8ce2cc90fe0052a814324dca9ecfdba000000000000000000000000000000001398fc827f4969ac1a80bd0dd1503a34ed0699779ab6c8d902d71a829d786a5f688c694f99a47052c629007e4ea463440000000000000000000000000000000007e1b442d323d82fff49c42a0a48d695c0b14d0332c1c0c00f35d604e12ab70b629adcdb8c94a72c20131573ce495419000000000000000000000000000000000f3fd71f10d3c653f0c89e58ce4676fc148b8ef937b5aacffe7a4208d79763fcf53f26b3280026871a12b68bc511206a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e9d4a5748f2f56c336d84ee51ad589d2c250566d61b26e06357d15b0992ed64afdc436c2b923c5e6e0e3de85bec2a500000000000000000000000000000000172dc799eb04591be7b8680b86653a1de219bd1b91bd8d4a5381ba2bc3c3d769f45aebf1947ee68381ea2040577d45830000000000000000000000000000000000f6d5bdfa4886b16d98f5897b7e412f97e70b39dfd321ed77d479b4cf25e0b5408849fc84235147045007fe8f2156280000000000000000000000000000000003ff23b6c8fc42e3468b257f47efda211668e1ed644c84fba15ce61865bec4011d31e265f94cd04874672428dd94ed551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009effd5f8f5fdda8ac58c42773dffb2255deb9419189648d53f0aa9319f4441c63f9d2649cd3749b82158ff82c48e38c000000000000000000000000000000001356a417895f0e899cf6d330cd0a01db2a8459875dd5073b543c6560dda3cb54b40a5c25f5c15625a4272372d5393023000000000000000000000000000000001405b823df7a69d75f6af34f2cd076eb31a1fbd1a4c4a10b39c5fba46c12b30192dba27c2de47d05344ad496943449c300000000000000000000000000000000078be554c6a065c3c59f9917fe385f5c39bcab66055e4135772b118ae2fba3d5f8b5fb666e35fddded938d9276df04f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019208e29540af53fd32c26fb49ca26b0155610640e03857d8c21e97dd4431cea4adecfa3f94c0ce553de59f1be6664b0000000000000000000000000000000000eea9748af1282cc6922a74cb2907d0f81c112fa61a72b26511cd6cf0f561cce86024cb01f19a1287db4487d392e521c0000000000000000000000000000000002644d56f62dfda92dad99b6557441ec0d4afe5017aabdaf2dc536da0543daacea116ca569ca9c2f37d1472d6c05356a0000000000000000000000000000000000fc515a41dcad4ec5449f73889b9f8d6e3e2dccf73d6af8185987ec0b90953b0c2462dfe64ace2c4e777b704ea321a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007729f8bad404e2e6a20a28dc74d3b6c5c858c287db8e02469e606727d217a260502227dc6b3f5285fdc309f567d2cde00000000000000000000000000000000094332e237f3ee7fbe59b0d7bb355027534b6e6c48fbda8ff4567d336e378866c90e63db33dc411b37c29c84d02abdf700000000000000000000000000000000163336bb5c54f1d4e1ef4f4c8362dacd23a11c3c17456b5b303f749706194ccf15f716a17aac2a42cd187a0dc034c689000000000000000000000000000000000880af8fcbf82fa6054a320b3254df62c3af5760eb5c3498c5a91a44fa323ef0edbb76a8f8bdb98291ba7e9336f0f7231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093182555767eb1933e7f13d4dcca5bead5439c9dd9cd37204ca5079b33bb495bc120552c70fb3202948b5a5a64bc503000000000000000000000000000000001964d32269e0cf5d2aa0e87dacaca0eaf6dcd599d77e39dbb2f0b4623cf95a65a1582e614e85ec5672223753fa345565000000000000000000000000000000000006bfcb0003556f8b521b8d68346cc3d38596da9bf65af64d9dc2dfb4c5c32eaf0d403ce5fae467cb6708cec2bf62e600000000000000000000000000000000053f15ba0aec62869086b6d059a00e1b9c667706c4e3ea50fa2504e5965b3d0629d3d2efeef952f65ed8fa0bb14e278e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012781c6d5af21010d9df03577568e44b3fc9522152d75207a10ba055d1867d1ad81892d4ad6029630b755aa8f32e98a700000000000000000000000000000000012b14e871ca77c2ca89f1a833d277ff4ac297391414b8515fd2f5a25b04f84f03fc32e6cf2c1a7d2b4fe278e1e4a992000000000000000000000000000000000eeca068888ec6c2708e8ea65adb016b48ab6f4a0803f75fc8fd8c6daeb2ba7e38d773d2de2834dcab7115d4ce6c875e0000000000000000000000000000000001271e62542135fb74cde88f9bd8cfb559af51ae1d1ba8e0aaaab010051a6d1964fc21e818a14d5c54a39290ef0c60c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088d7158364a1e18738d292efba065a3ba87eae7ea9ad1f39516a848d8657dd2bbdd51d4e04561f3711c46d28788f77300000000000000000000000000000000188121891681db0bd2f50d940f649b88ca6ff65b245a0bf5813262db8cfc5776c48629adf71370d9209a87799ebbb90a0000000000000000000000000000000013fb1f9c9c9700617568eeac2f224313fb6c4f6b51aa2debc4a8633e7315386091cb1f23208629a1a71acc71f7bbb77d000000000000000000000000000000001215edb100384734710f8c4c1638ee02820075e93fe359c0acc8fc008822fee0cb83487b486c636d6e9251855b8d491e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d92394bd48d316c86b5e12acf36d408bc345433fe8e10f761ebe4482d1f2a6c9c4530ee51d24e2c6fab5b483b43522c0000000000000000000000000000000018ea43458a75a40c39e041bdeeff36a9871c79fe2f23fc9760c5c30724f6eabbf133d34f817f6305160af9175ba87e0000000000000000000000000000000000038766b05933250a640535b161e7a2331f02eb43eee1423fa8e0e6e0aed58075547e5c6b4168466c700be9c9df22d6d2000000000000000000000000000000001614624332ee3ef2568abcfa71169db6dad3b6d0d04e1dce911b1d6de41922ff688d41e8ac3f78c991483d2b527b43421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004101196603ebd4ccf814d17c48a7536067a5df6cd845289ed861a95732b3ea7cfc6c429dfe1e6ea60095bf61e8f699600000000000000000000000000000000045fddffefd82b8023c0166b571b39ea192dd2ce113685a744d22d61383565cf1117ab311a507889b79e8e8fd8e25e480000000000000000000000000000000001db1ba2a8c43da35268eb174d3d9ab3532f3a37594161fdf2e7daf42431d5aea1dbca463bcd35b82a13fdb4b06be7e30000000000000000000000000000000014c45103a5dcd1696a2df687d235bfc17e35a907c3a28c789da44c02453dd690879709c9b9e4b7046c446e9dc4560fc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eab0e4f82c02f0c8ed3dc09ff105cdf8995f512bd321619c6850e35af1b2f0d0d68765f69b1f797f371d051610a189700000000000000000000000000000000057ca23796e4821fe58a5422c546f16c7c6e30c638d0de046d90f2e36e3ca6fa3bf77d5e3b420b5b73b7e9feb0b30c5e000000000000000000000000000000001948178580392a71683b2853416e187c48603033cdd3c8f0f525d3583efca121616b018e1b582b87cb8490a36c9121d00000000000000000000000000000000018dd06b4ebebfb3e97b07ca4eebdad9864021748ce3eaf95222e379f52dd6ab747f398455e306dcd0bdd41f26dfd03031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de9acbfd8f3516f5ba689950f40c97da6797387e8bfa16a97f0d549980e8786d3543f42ce3ecc54aaa4ce63f2a0a7ca000000000000000000000000000000001788fa49c930163850f2350b64fd1a42c217bb27cdf3be7f8d524698c8c18e20c9488c218afa8cf01de88b908315c10200000000000000000000000000000000093b672f370f43a47054c01d361e894e609922d2b6651c57ba7058c85a98a3b420833c265224454e625ee78c33f6c413000000000000000000000000000000000f9cda8b9316cc24542aaa54d2d0419cbf1353e14d49515192ebd77c3d7c20828a3453cc94ddba792d4579450b0eebc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c355bbdff9ed673c80e79d64502109c1512648d71df0f01295e0611d705e405333967ee20856bf982b9463e625b0f10000000000000000000000000000000001535314b0dd4c3b3a597e552907af0f3976fcd65ddcdff390f71f46a8b9dfdedae6c84d8bb12ee83e22d31423f46c960000000000000000000000000000000016f7a039ee125b9a817abe9ec3efbdf46eacd1d1ec08def6ac458fe75644cd24945e74f2d85d3ec6221b5137a36f84350000000000000000000000000000000017e4911a30c85b4f0e993d9f94592cb5c560b0b2ac07283ea98ee3dd6b0318f965ffb1ddfc63abbe0e20c742bc2373731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014367eb296182917dcb756c6b987828798b308cf337d62941ecc1723b85572590175561a7c8f9d8af94273ff99ddba060000000000000000000000000000000009dec83d228d922215a70c50863993a02e99477b1bb0ad898d234af5a9f6b01d888acddeeec2002942b9939122961d7d0000000000000000000000000000000002f633bc90b897c01dfb41bf97652bcff9ee0a1ac57cc5b2d0ca2cbb806dc7eccd29ffc65a675980aad07c8682b3b775000000000000000000000000000000001205cdd1e8f1e74196f0570b078d9c8acfe49f842e0ebc9f8e6e41fab68c26e12aa8ba216d53fee71fa5dc61fac857b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001623a0433b16555d5bc9a004f8c63d5a09d93a78b05ea0264163e8e71de36c66f5900e33506039d99c62ffd051f0dcc70000000000000000000000000000000017963710245fb9e5e8181c66669d4e3f014bb4a637059b26d9a75019f96153dac17b0c663b1d65a4fee6c30e1b80a909000000000000000000000000000000000e21598e5d0c708ec6ec9856fa9afdc6a1dd0133dc9ca1233f739cb1cdba82d5b592e066773c295028279cdfb4dd6d440000000000000000000000000000000004c418427684be1ddcc1ece492b7cf8819c0d3a3ce9d8af1598e0e4b90a24aea3a840b1e7d83de581d15af61a37937b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151637fc0e6878455bb3412da853ab64b0bdd5ce4d247a4b4832c4f4f6c9711ada3f768a27657acb2ec20bac48b278860000000000000000000000000000000015ec9843feb757e81394b8cfdfe6a75f7750fa20b2f307ecba703844ca942cfe789377dcf121e50165264c9e2c72504400000000000000000000000000000000022eccbb8538d28a2b8a624e4326dfc389584d8cd5c3045168b8e5b92fdd5f54a2aba937e25ad51efaeac582465e2c550000000000000000000000000000000010db36d0c7131e033e7583d5fd10b4a87f46385c6422f731303687581cba08accef0d8a5c5d8474f8bb32ea79ec45aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001977a828aa8ae4737760e4b64e927e75742569825a08d78020eb2ffc85cd189411db95dd838c0cec4850d885b36f6b62000000000000000000000000000000000f7ae64558472c653e9ec0eae5a54078c9d2d3c6569f271cf85ffded2b3366abfcff5add8788948e53c2a4d6d2a2f45000000000000000000000000000000000000efb4fe6e3f12150c2f4478f58c572694f92d8c848c1f3d91b248422228bb9e2311fd1b2d3258c0105d5ba01fdf13c0000000000000000000000000000000019cee947468f86c679255f5f27b5dd69749f4b91b370cc15a159c85b8a469dbe52c8c6d13c0db317db617dc069f351cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198affafb3831c650fe14f2c87e375608e44452ad1117b766807c1de93421a969af08aadfd194c6c51534fa5b394ba6700000000000000000000000000000000125ac71b75ee42bd44a3d45d58c1c4a36fee4b98e5d2049ec6373b5a26a76b28c2dbe48626882493ce4c67ee39121fb1000000000000000000000000000000000cd0ee18860807d8e8e6584f64f53633f691343d9726b4b7f995c25c49d2caf276e2b999c2856d9370454f63cefa2d88000000000000000000000000000000000b0316d713a7f948687843a4a034f11dddea2dcfd5529eb88bf94c0c94608b444b126e25007835080c27ac9ec3c9abe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ebc7e5f0f9074bb38f8588f189c5bf8485dcb8c8bc8857ed467c7c49e2b9e850b852dbe04ad0c5521c3a09dcb29113000000000000000000000000000000000943acb721210decd22eca5e020ab9300d503b5c36f50d689b9b73c8f31f88ed415bf4e4f1644a643aad52d8a930e0f30000000000000000000000000000000000f15253c7895b4c261987586c69ce860c11052acf3f63fc02d29eb9342ebd84e1508fbbdeb420a9d731a58488d0684b0000000000000000000000000000000013b7ca2d77a1c38d7108c179770298ec3fb978129b4aa9a93f4edd5c614f38dce233f72b20dec0ee3669cc36570dd4651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ecbc2314630e9bc001b99efa8b29eb494f2ad3072ef750b6b3a7db18705965ea40ecbcf4590830cfc522aee67fc4f60000000000000000000000000000000006cff352d6ee367eca73b0447e5a5a895dc9ede9ffc2afe6c109514bbcd90fd4ad767917a018e0682952cafbe72794840000000000000000000000000000000016752aaca020a534d2032065db44e6a2b01e13a53816fe332b7fdd2a85f77481fb052d29829519967d4c1d965480458e000000000000000000000000000000001884dd42206f54aabb2bf8f47d1f926b5ba2415434dec1799ae94c0d336c8be0055d83af25fda1dae00079826a39d9c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033cbe5e6f424886dd87787a5b7a7e02a57f2e05c38dccb1f688b44513882601610f43f457c680d646d0f7f95238bcc600000000000000000000000000000000033ba3f62d8108c6e8b7a8c7204b7801f703a8cadaef024b78ce3b4bcad766211d2508d8e4bdbbc7867bf48b533ca8c9000000000000000000000000000000000967b1c01b12d9674dede0ea2f0c046397d0df2e0d992c87a912e441ff165b516256854b059f464fc80bd9d26cee0cc900000000000000000000000000000000078157ac9967d21c88b0ee816f006b3ebb54e8c7e975fce8f1f09a5ffb5e65b78167f1c599479bf31793ddbff6a7b4341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017376f10006af96071a4b3f472a226edd81a2472deffb5cbd27862e726f3ef3b79387eb1615bcc647d7e6c35e60c39d50000000000000000000000000000000005c13ad000e2ca030dd0acd6edca973e6835f5882fb50ca4e117830005419ee42502dd83c8ea3a08779128442218665800000000000000000000000000000000078242c3b98ea9a6b4efad294381aaff208f7170419005fa6c90791cbc371801e993081b5273d5d7a5824e3a48fd0d4c0000000000000000000000000000000008165587b2f3d6c729a84d225f66fd5d19a751889d686509ac397afda27b8a1e97dfd89eac60d649f8724e17370fd89f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b93119ccd3d7ec4438405ee44c98a26e7dd98049cd42fdb0b3f33dd27002471f966e6c64f75d6c2472556692c9f2d9b000000000000000000000000000000001801a069866f02555d4a5cc624dc2ddb8a496a2c5cfcd97c1cdb6a3f412e39f81437855c1cdaba353ad71a0dc5b8529f000000000000000000000000000000000ea85af9d5e266be36cbb8536025ad2cb852d065e5009a02e15b59f24b8418654b47661c591548f16056801235f380050000000000000000000000000000000000aaca07b3991ee68c91354052523e8e005bbf97ab9a5a0d4962b7310590347a2aa2f8ae66b04f64fa637af2085009971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000851040dc774acc6429188ccf5ff419e737383ce231c8afd990a061a1f4f25052acb287f31fc204e11c8ecb43b197149000000000000000000000000000000000cd1d0a5198f5763f1f75aef19633f8cc145cad79dea6a738a517554fab881663c31b61673f7e0481c15a082fb534b13000000000000000000000000000000000cd876970e1bb865f9991bdfcbbba9429768ebbdd27a693fd8da8b04d17ceb822bbae9b6121a69f59ff0d0c262a659ea000000000000000000000000000000000d432cfbfd8a3f3879c6277b50079d137c9b1e93a2207a21d2d6cc682cba9e9477886e24dc23e666feb2523d0b4530161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018f46989c80f9e161fb24141626a204502036e8f30f5d0f72c0167da9e52d28cb1fe99fbce5a7c8cbcca2c17d53293d0000000000000000000000000000000019641ff726ca947e96e7c607d0bfa8698910542ff9bee8926ab7e2f1b9561dca31a081bb84b699738c905d13f31c53d7000000000000000000000000000000000955c3ec513110766d11c00f5de5bd597b7d8c4968fd30e46600e92fa8117581ebf36f1b8040a22450581239b6d3b22a0000000000000000000000000000000009073fabdf52938925adaed1ab13185126bdf44b2e37f1487a59071ecfc1a3a38e4f6fdc654ec91c46cee2682db373e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5dc7fe04a3da23c66e9d27e602159907dd0bb7b2c9aa9f0a4c3fda1dce9ac96403b40b5f316d70bb8e2a94f54ddc9b00000000000000000000000000000000124eb710ea6ec67fbb1014302c6f01a63dcf53e66d48cdc9be5367777ecdd53d0ffc661dca8f3b40200d9fd0a289f38700000000000000000000000000000000178a403e49fac1a8dbf292f32ad0d05fc3f1308842e9ab0a861605f13260ed805c160b7df91b4aa2623c80f4fc7a1a87000000000000000000000000000000000bc2ef3dcbac9ebca3281f134394646aec6179923bddcd1a6c59959ded0fd3b694176b81b9f8b87aadd2f2cfe6a8031b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb6a868a0302748e50445e7f01c08e4c635032c10e5313478489b01e18dc88b76415a9ee0fa617d29b200e35e5759d3000000000000000000000000000000000b30fc82e01dfee16c891f96980bf74613d93f7c3271efd99e9c7f120c08d7042bdde202fa63cd8423dc2c83eced25190000000000000000000000000000000013bb082127cc5ed19d50a8daaf95ee590e6b797afe6bf5e5a783d3c98351618c40504466d8a8f7bf7684b92b7b42be200000000000000000000000000000000008f2b843fed1baf1f0bde17036e6a03929e4a6f3a200ecb7d8133e4f06216ead55a074d8c913a9cc8f5be08333bdf5b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dab7bef886bc431677c5e31a8cb79d6b975df74a27f62722ff2ac715492a01eceb7c5261169518e3b42c33a6639a94700000000000000000000000000000000144cb81fa9051d520aadc390b183ae653677033b536792be194a161b088e0edaa1025d79b6cc038c253e90c8940cff430000000000000000000000000000000002fb9d2762b88be54ff0f1b5745bd121f3d46f5dc4452263ae881475a93f12f3360f2348010c75ad0e0ffc360acedce7000000000000000000000000000000000452a8ec8f7f8a99324fa831cc7ddd62dbdd899a60ddc60d066020159186f9a16a293e670bfdf2e9699a3825c78dedf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d430638323adb96658df5c8eef5144616723bcecd595d904af14d5393e0bfccddd7a64bc8112918f5698426e3cb8e9000000000000000000000000000000000e73bc0cc8033d4ab206ebcaa815f3e8742cddfde5606738cb0045174a684cef5a195e12a3053b35f6c560315a2748e10000000000000000000000000000000005ffe4f98a97b8a32e6b85ee45b9e94bb53c7b5785c42beb3a902a0b0bcacfb2327fe54e38419e83da616487928cd5aa0000000000000000000000000000000018ec1d773274d2ed0d3101e6e64df2bc373e9edcd02d5dd267bc39f7094e7ab5b7fcad85b5392cdc41616017eadd8e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085a30f8bcff54fc6f022049e57453215719371d9d12116efcb3fbefbf3848d11ddd66c5855e77db578712d64994fb30000000000000000000000000000000000219a5512287c37ee7865e1f6a5ea2c6d9d24cae15f3f6bb4eb9e9d31bbc23f7a22f43738b686cc66f0762ce975461a60000000000000000000000000000000004602db3bf19b1c8c3491f3f13e171760dbaa2b27b2f999f8cb0d9da6dd3de4a61de6eaa02976dcdc7970498fcba56e0000000000000000000000000000000000de25216f1ec24a522d8581e76714459eb00f09167cdc9e29ae5391fae174ea7cdb4ef3d77ecaf253025d4dc3a02d4d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123009a43a0e3b3344604072fc6388b7cd9f551fb099042d5993fa18a479c7604653dcdd797b2a99b6c5b3fe833225a10000000000000000000000000000000013fffdcbe27be0fe1abed71f6c84695297b1e291cdb9ccecc7f366089bfb0d55c19c195eecb851ede8aaaf39b877f19800000000000000000000000000000000096d505aef28676375c5a5ad3293b6b97ce14dee8007013236dd46c9e0a06ce233936ca8039ab8eae72b749981c36ade00000000000000000000000000000000070e653ac0b803173cb7c853051edff065d8220623deb0adb1f5e06f0c5e17f80a3d45ac2967ef7cde0d9823c2cbd6b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e82dea70048e69cab078fc84834333d66734378650e8a1c90dc937b96f3ddcad0ac0a3eec46d5f52d39e31ddaf92ed00000000000000000000000000000000147c359e258a21832c6f448ec55181d1e5be3901dd3285ac509b2412089b1205295a37092755afe5ca1e9ed007cc064800000000000000000000000000000000155ca4c17a0bc1185492bd07749fccd379cccbefa83a1ab39aa688979dcf5546131d6e85444e0e016491b98eb9c26294000000000000000000000000000000000f92027a6c93ce54bfafe5c2e0312dec1adc14ca81415c6381457ec060efbddef5443c09af2a0f4e20a55b2747ceb4b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000add85a0ce098de0eb4ded550a51c56c2012a7a1998a61fb1c81d5f10182af726fdef1d4f5fd115441efb165e351fb8000000000000000000000000000000000db192936f4bab12411a2fecdaf1ae59917c7c89a3e86cae197d673137223e223869661055dbaec359939297a9cd300c0000000000000000000000000000000008642a35845ed8971b5de3fbab667c8f711c7619af107f0e3ef0a70c9d7e2cb802a4a2d5028bfb5d3b6eef5d6457506f00000000000000000000000000000000128003aeccfb8a57d70c8fe3c5a182dd8b6e6a14860073f75848a844c0c6dd3d8005f3a040c05b74b6be14c59d4775c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090c48f656bd1f6196a7d2d3e64efcfffbbe5b6b7c6ca3e696416284c1aa8fb0cc63be6f4b963008dba83fcc61bdeb42000000000000000000000000000000000c1946b6a22772a27175332c503aa0d9cab20a794962a5110c6b8428da6b1ab65688c49b34de1a5a38013dfd86cb447d000000000000000000000000000000000f77aef75261f71eb7ec6bf5a8180b1c877bcbc8b999fcb7c75327756a28c19079c652d09cf82c77340296c8dc03142d0000000000000000000000000000000011d14bf0de1bd33abdcffa34a2d3f0d3f0e4011d9e3a147b937b0f4ca4bc2acfe1c440933b5dfbed8dd08f4969bc34631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029b8bedddfac00eedc59ece1be9fcb8909c69f3e9b41b75658c7aab829a80c42aa6a43e78d0e819bc2805b12c08b1d8000000000000000000000000000000000b61d7edc11a58bfdf0c270595979d8dd522412eccfc63c247a98bc8d9c7539ab45fd46e41d50cdd35ca6d835e4071db000000000000000000000000000000000d629048427119a0a320ebd42f0c7eab263b1e344b41ac8ce01c7417a6846019a23267b02d70720da0b07183597e0a690000000000000000000000000000000006eb8c206929fb08b0be2760974ac71e31f2493af0c05595e4ab6487650a0447bb00fb437af29beb9c0529a18c901e501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105584388cd1aae21d6e541527de075dd6fbedaddd63071c0c244b0bc26ec8e58f1f65041ffbceb0cd5f094ce409105b000000000000000000000000000000000bafefc99e5a7a61cd3921bae2a47af5abc231ddc65027451ad800e3a57a3a2cda972c2a93f517222fe8cca56036960f00000000000000000000000000000000174187d745e3714e1c65a666a39df1c783eee92dba03fb0c9abd0df2a19a6a246ecbfc3b3787775a32ef36fd3bf7d22f00000000000000000000000000000000168bafb285d57b82bda2883d2eb7f8af2941ca337ca05474226c2c33f451f00a2932abe2824747673ef6f90c8b3a1be91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145f65a72fe59d45099900953dc949731278a0a01189d29a44bbbd59a3c65fe16e7e430cd6663ea2a31a29001b04b6a6000000000000000000000000000000000409c5e09e71d5ab19776e27d7077c7a004df2ee215502907730ee93d812e5829a791e39bbfb4c7532c4e775552ea3a8000000000000000000000000000000000645040cbe1ab018ccd42becd0d6136a30b5bd06a1847e07484091d06d031e93d410fbd8ad3a09594a42908ce487bd720000000000000000000000000000000003589d8389f2e3b8487d38c77cb3ad89bf8183ae51ee612e64a1685c52fec1434166bc8054d2bc5d8b796cf8999f7aa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105042e46e6d772f7bf84ccdac8e78a913af633e84d9a68a5ce17900c81cc15f29728acafe208cd9a5314f55ff9af315000000000000000000000000000000000230ff3ae2c883676821b6f2b495c9b510a0d33f4fd6e7144ecef2ba4567091c0de942554692e2898af380c21fa2740800000000000000000000000000000000163b964f735ff1a904613177e494e2c1455e2ba2fabeaf7ca8327ef26770a9855587cc08e2d883104babe65ae244584e0000000000000000000000000000000001f9790483298ad8208f86307ceba8edad75c002bedb5d17520993facdcace6ab8b628d48033782889cad91fccab2cda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109169e02a4de15fde8ac561dac1c5b20270f7e5efbfe2ccd01cf89a12b466e6ed5a4c3e3dbdba3f8a239f844ae8b37100000000000000000000000000000000142bad8573fb25cd4546ee6491941f732f9173c5ab8cee1646a15eee54785629b9c77b14d77c511522f47820735b7340000000000000000000000000000000000f44cc1a8e05be65e79c326d57210f22093ad14f8cf8a829f41b18cc3429773db8dfdac8589b020e1dfec5a2044cffe60000000000000000000000000000000009c82a449a746fafbd3da8c11527c7de14a65d21179323aecbff344f343b106b69bb566bc38e9115244959d99464ea751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005c7e8ab8044d4d32f086b5a028afa5fff9f4e90a8d6cc5016a179f2a35229a6bbad2f3404092447d4c0779d2216fa700000000000000000000000000000000002b5f26901362b209ddfc3bfae8532ec0079f702e3ee6036d83659fbbd6b326bad7dfda1f4fd5efa38372dc3f7399710000000000000000000000000000000001dfd3ec528b8c1e6b875ee6498a1dc7cdbe81fc0acb739a7af033b992d8d1af5c3dfa4138953004dcc876c62e34cc320000000000000000000000000000000005243fc4f50f736dbfbb774c1d5017899d381a77db3708ec10bcd83c629bd447f7037dc2af119b4897db28d6523066111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa48986ccd24a3bb0f06890d2048c34e411cccbbc46368321e56ce2e5b5278cf1c40fc1d6fb6d7b1bbc03f0317faab100000000000000000000000000000000176889454bfe883b43f13bf76c297f45a28a480c84f2b1cf28b34136cf848dfce900800232907b7826583403e82162360000000000000000000000000000000010e2469f64c7d0e8cad10ffc275a0a34166f1a1c8cec08663fe8be79d134271ef9575dac4dc7173f4b7842d405206d910000000000000000000000000000000013e3d0599a97ee929f5eaaa32545517f243a0d68852d4c5cd971e51a7e3584af3c3f8b96178970318d9f1cb4e0acbd9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a000c96bbf648b42dd699ad7d4d69aff4916dff43aca6b157475697e8998f30010c08dde8fa283756d111827ae4e9c10000000000000000000000000000000007cc985dd9746b0e7acbd0e154231a023e1d6c8be69d468f6775d98d39eb38d3a85ba688e464078002f4d416be47bc5c0000000000000000000000000000000001862e5eaaa9becd72101e827f69dfe3de747857f951d7e2cb2f2c36365bbe2fd16c7520732abe213bb4089b601643ed00000000000000000000000000000000172f379a49a6fc3a8fbb546c83a4ab5361b372b82239c47730c8b69199c5ecd78cc99d6a1190726882e8f130df6af1291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001081bdf9e4b488c9b8fd26aecdcd75693693291c9ee22e20ff2be9a590c4dd4594de5ab96afce3eacf425a3a65651a2700000000000000000000000000000000025a6dc3e32a537fb29f717f818a3abc48ea43f0213b81292cee0400020b494f4710a3ea1136769260e4e7f458ba8c53000000000000000000000000000000000b6d992714594214c4a787485432d95794937717fdc301b177b7b147b43fbf6683fe517859303c1400277d8739dcd38d0000000000000000000000000000000014e6e298319ba0c8baec5a1a822a5573fb8145766fbb4684ba28fdec64943c5a962249ea60b0f3d3dda74812511c39261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001430ad4101ca9ace7553a6ead4e79942fe6d845af8f9e754dbb061eb347d18699b78e54d9a12572d6887998ae17815af000000000000000000000000000000001658800d9decb68cebdc024162f5bb768913a359707852cc96d3d52fc51a232e69626b4f1ce59dde7e2223d6379797cf0000000000000000000000000000000004dc67c66e234fe6671962574f6abe3bfb882c43c539029dc7c1fcd030cf47488463ea8cb58a79954b610e796a596bba0000000000000000000000000000000008d07b04b5d0869f161d1c28a5821b18be7f6d466bfa5ad39d0f098bccd562ac1c258ea3f69ef669bae6a897d3ed98611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f45b8d66ebda8efc12977b7751b5148eeee6742e0570bd1bb4ca772dec9eb1e8a59d50a8c1d8f8b22d062251121cab00000000000000000000000000000000102310fd67a768276f77edfa1616b637a7d4ef4459432b5fdcb0e16a2c8cdf6d8a555f826e4b17769026d7697e73ed4c000000000000000000000000000000000596e7e092fb81548f327349e2a57f76e115ba228035d74cd5841b5ad416f70c3d15e13c6ebdb61a751cff0a9c8944a2000000000000000000000000000000000fb8d9e3c8983a79399db179b7026cd4ef57b7be17c206b841ba1fb2296c8ce59b10fc78e01075668142cc0cd5c13a1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148c755c34f146bf8333b7dbcd39a315ae441a5f361149aad25d0a655efedfc3d493563a08f389999cde5f24ec30f401000000000000000000000000000000000ff0e24e95f26f28e27e2c01abbec9c5f0e76d327cc0afb3a818651e5664d51d69328c604397cf52547a7d6f101f0122000000000000000000000000000000000615bec32a13443f559ab2741b214c9110d45334178c5d05ddfbc769b81fdd259b56071e46940be99f0865533c153e9f0000000000000000000000000000000010c1fa0ff538b11ca3a4edc058dd0d792d875dc40286eab78118c6f038b6afefd69e0e2fa9eb2f7feb06bf379862f73d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046bcdb532cc7b8cbab9f1dffb6a638b87605d4720f1077389fb5905dde94a29a180ab4435d80d044594c4290ffd4242000000000000000000000000000000000c5c7fcaa3956c2de88288bb7edbfd44a79bb275a449e2ca6c81f26b1482523bf4fc0209ab1969d4f602f2fe189d3fad00000000000000000000000000000000183596269a830feb8a7f7a7260a642fa2a85727b7d852f90cea8e00e42d386f316004fd7f66944336e7658c8cd7d98b500000000000000000000000000000000007c885a86c7134888a7fb4626dd541059e2260ac20d24088e48b1a1997ea5a126b18fc2834795a173df453c40c6c6fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a38aaad5302e51e3b27be1eaafb13784cf8845401defa2ed27ea258f736fc569cc73e883a221712eb6cd64bbce4da2f0000000000000000000000000000000014f30c9f023fbd7c3a03c3b181d5f735c1313f618064ff941cdedb8371eaa728da8629482c76bb0a8eb411a15393211f00000000000000000000000000000000197a1fe4138aa14b24e598d9c9a4803298ac8acc83612c49aae28ea4eacd980a9f296e34d688302b449d49d2068e42a2000000000000000000000000000000000f3c079216373162bffe8b6c0eff1c620522132f5ba5d474c6d8da65a80797a4322b0a1f4efd80f32300f958a9f2078c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019e29eeea6c85f41d82170b5a75b1f29fd7fe644df25ea8059a59eeaef6c2a2b38acd6938bcda7971b9753a51a4ae5800000000000000000000000000000000141b54a97c05727802988800cab93e73a3c07acea689e59f1c78e9595373a18d0ec2ea25153bee79bfe4c85958251895000000000000000000000000000000000d800d19c38dbe4f331ef7943b364f6af74e8ee0fbe9096e6fdeafb1f44d869ea843d12c90513026d00d326d66c631130000000000000000000000000000000016db97696bbf0e7398ac0e5444b3d0b3560e417d98aee6247a7125f8d264c1221f1931c7cbaf203792059ffcbe20e5ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e3ce33f11b07dc24a81884fecfd81fc720fc64208a72c79789d8d8f7e85cf239c9d01ca0171bc86a5a6655352a84550000000000000000000000000000000010fa5752db91a6812c9d5e1516e96960eea13d87de2a2a2deb85406fa0c61674758e20d7f5e853fdc2f6042d6555db10000000000000000000000000000000001971834c587a1db1fdf56ee8a359936539393873b886b7d13e55f50211677662e10d073a085e3c92f7091c6d6a007ad6000000000000000000000000000000001848d32240b36992a04236fec35b28ce57d05da145bbc5286638e2c94c9b3ffa21b0fc2c4a1c7deccaf0e2356808746e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180e90e534c01cf113e326051fd249741419269676495603accc7d774745f76798ae8b038313013143d04bb91d93bc9c0000000000000000000000000000000016b7f4897c1c6a52d57927d6aef5ef20d71bf14ba05509ed91611fd47a945d688e7bc07e181562d6c771dcdf62f58a3e000000000000000000000000000000000b189795e59ffcbf38766b70fdbc008b66e4123367f671b2c281ab3b0daad4f3395f8fada834a4837fdfab87a3c84c030000000000000000000000000000000004b903721cce4e2608ad9b4c76104f78992be9b51814a45cc67ecf26182922f100f79366d1f138a990c36cb24c73736d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053b2b2fcbe1e1f21c8975a50490944a2ec002eae2a3787fe1a5f2407e748eeaccb71ec9253ae5baab99bba68244320c000000000000000000000000000000000324e2be2500d713e3d7024e17bf7264b32d4682b9a2260908e136524b21898d13bbbdebe9c0b114b60d3865dcd3e3b50000000000000000000000000000000011555094fe075c812a9bdb67cce6e5276bdd9aa2cd47e08eda8caf27c64fbac993e783a67d4215829361a3d9bc08aeed000000000000000000000000000000000da6bb32156d43fda1e03c4f570507d96a5cfcabd1d06f2ef3e044b338d9fc647b6940d714ec6b6f5bd53cb9813a358f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000152f5e3a4c553685322ca904c7240655c2478d16e1b6d6f0303f1afab9612bb120f52d4cb7730f9a213b6f8c9f70c7e0000000000000000000000000000000005acee9da915ef5d8281ef1713d841a89be846c6a607be3209b49200076f65620c7adc6aa87dba17893261984726bc330000000000000000000000000000000008c4dc3c0fa77bfe29c060d1daa759750de6cc9aff97ebe81c8ffd10be465e7e57b39f1a545ba2f896166d99d38978bc000000000000000000000000000000000a980e08cec0f3a8bef83b9d46095a4081004ace5b70d28cc9cd478c91c50c55cc0220387ec906d28cab94edc821363e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa0a980b24c369c3ed66332ee85ead185c25034bb37c58e922e88c64773a431aa3356e8ec7f13960a187c7fdaf4f5c0000000000000000000000000000000013b303817316f19776a4f65b2f6150c484ed5583e0903826fdcdb1ec9dce7da1152462571047eb72b47f483d0632bf6500000000000000000000000000000000174ff23320c45150a950deacf5594b71bfc471b1a9ab2d67763402981110150c2f493e9aea5be1df0f951bf31869f172000000000000000000000000000000000a888193e3158791133bfefe0cb68384a69d180335f9af7d0d7143b072c4bbcbe48e97e5d6658501528df20ff83cc57a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d000c0eb1c1c952486478e2b81126b7b26cfb363451577dbabd7e47f7f834f04c47f90c74dbca9981f97105344db3fb000000000000000000000000000000000357a4e86818a660887d1a8ccb026bd45af74e1261fa4f8666d3d7ce1bcac676b213809d8b1be7619fd5cc54167703750000000000000000000000000000000003e78b2f2495ee9ab2a58f7f699aa7dfa11625ea57e3b8b89bf6e8474fd1b148aeca27e2bdf3aa77eb1803ac8469f1a9000000000000000000000000000000000da0111d3255fcdc941c72d1f099a8412982436be5414301c421fad34cf9fd8d55c79753619e229af030471d912cd1391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ef489090ce97b1f2e868153ffdf92bf8bfc451b14162bdf902ee74afc7ab25764fbca0709aaae47d74cd67e1d1be4b0000000000000000000000000000000003f4c7c3215125bfd2e01f214c32f2cd64331d0f6c0b46910455085162f9e1e1bc66c1d6e3bcd76e549ffe011fc85450000000000000000000000000000000000669ee967d4003f1691044306501b978aca86121c68cea892a924bb97bfc47fdb009047d43863fdeec4ab658c8024bc10000000000000000000000000000000012c0a7cfa7b1ee48bcc268dc596cc4be3c2c71083b24ebd2c3f29a5cb107fd5032a30a56f245238b01953d7c6793b9921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f807cdb1c92baa906a37d23688c0ac08754ff42915eb1fb1454efcac3180e2d57f769fed53ecc31c4865f831428e55d0000000000000000000000000000000008857250dde17e3a4147401995094a9d2a24590f6933aad466415f99c8d61e96ba464e39a6125dd27e92c0d615c77c350000000000000000000000000000000015a47094a686dc357e11cae38b9faeb3d1fed87795202df0080637f965aa871f407192615d519ca464ce0b37267c25200000000000000000000000000000000003a29b4a8a846e17ff0cb1df24e74f7513ad04bc9c6f84c0edd0eddd55ef86649ca331367aade80f6276e3b9593c23651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001585c9a3e0c3a1b302a8e09748a920602163e80a26a57ff15c3460518a348d2f5094ce317904945bb24b875e63ae5b1d000000000000000000000000000000000647dbb0060242d09ecbae5e1b9107bf1884de18641e3c70a4dec87fba584655f282497f5084ac3205a6a236d626d85f000000000000000000000000000000000b7c15137c7e6e9e0a6141f184e8343a75d578cc6408d476d0f7697bd0b054d52344fc30c3592c74f02bb378dcdf58be000000000000000000000000000000000120056c5750ea8c09d04fd86ff12650c95a5f5e35fd76ad46e12d78cbb90c3a2fe65f771e6f4363139577b72401daa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136fae3065a9a2b332b9ba939d3c861adb4ac28f2cfc9a6774805abaf0f70f2ba8bf74d9423762bea089c0b53f64fe87000000000000000000000000000000001331b5b2817da4c8d91ad601149be8a7a5dadbf91d3c364e71ccb6f33a0bd6206bb53f1ad8b7b8778612efacae6751d00000000000000000000000000000000016f9dbabb5810c09e6b66f4fcf40200c7c59919bb96ee4b5ef5de2e85c3314ce189c5ff67285ce4b2b9cd454abf05a8b000000000000000000000000000000000d029d622e6abff6e6b649da12699f3a66de04a3db4445bf83297fa98372c4dc6ed3854a4b80c3bf89e6edde8a024e3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001050a610075da9409c58677b537b3f7fe35937c567fc8ccfdec23097400e2524188dd29a04e651057de01a4f9805084a00000000000000000000000000000000071a18a44b5725b9a67b1fefa7f1a5bbb68efc4a140ad732ff22f2988b0bb5492328beed88a61b25d3a8659186fa1cee0000000000000000000000000000000001f1da005f03b5e93097fe264e84ee6f9e78626ff9e7e9fb87ef0929e92d866fa92ee41f32f87308abd1c289cf67a2170000000000000000000000000000000003ba117ac29758582a66279d8d36e7ed06c830220eeeff06a6353d7d863805e53562c9aa0ae78a16cb37c54ed92b00661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc7d4095871586f1232fc3a1ba9d17639d08a4e0994b748122c0789c6e8ce9750ac50a3573ade3fae607671bbab6fcf00000000000000000000000000000000167346d1b6bbb3c8f969f4e57f4414e4bf22b583b228290cb0e48cc29b1894f6f07081b1d33dbcf0c9583720a5137f7600000000000000000000000000000000104a7e4713995de51dd913cbf88afcb00b6c120fdd9bf76af55423b682e51239855b4b3094147ab925f716f52af26ef5000000000000000000000000000000000e8264d23311028798624c0ac5a4195cf16d220682fd07e603bfe40a22e7ba68b6e7e74fc73785fd78f57129917d6edd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184817d1ee6df137aa76d8283c613f7a0b520414bd04f696517dfb543e493abe60f57203072eef76f8e444a261449b4100000000000000000000000000000000151e7f51922d0c0089c2a0b86e1906773b63eb385b8930be938061716cca9eb011dbd78e333e0acc3ce96bf400b1a21e0000000000000000000000000000000001ba1f2610d99c896ef6888748ac80e6f154d50dd4d719a48b58403549eab6834d1c719fc79664d3afc490a585750d80000000000000000000000000000000000faf8a7543818cdaa68478b81be8dca24c92b60023c38638483dd2e3c8f5ed5de8f41503570ece693b2a39fd274ec5411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048995f6d9dd8a63c0e0c77509a56e0f1a8b4fc4544f82b59eecb4e682eb09866cae72c33b822c817e83253b1400e51e0000000000000000000000000000000010fb277cda05480c9f366a020c6a86691c0c2d4b25c4383a615a43dfc3c8029d3dcb34042732de5c359107d003c5173000000000000000000000000000000000104d8087aa849ce076ba721ce7b0dd74643311fff2dc9738da9788c8d5576a0a42796992555c4c219498dfb0085e09dd00000000000000000000000000000000187dc6e5b87bae5210ebbcd365fdc9a6dcd2e8cd0f8592f652cfeb88b037abf9359e231e4df32890c82d41babdfa84641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f103c0fce55208d3aa190db050a6bce9086245289306987304bc0cd8113b22788ba712de1ea9b07458eaec574bb67700000000000000000000000000000000092fc2bb031006cfcd801faea952757f7859fc111ca3e9da8be67f3c553836fe0955001b45d8b9478e8ca3d91b08119c000000000000000000000000000000000bb954c28fd36b42e85f951c9e0d1e1aacf96ac35e7e28c6f3c47bfdcb447d2df853955cc13761870a57bbddcf1924770000000000000000000000000000000001cb60101f1aa721e6252154448e541d5270c4758245eb8935bc45f3b5938a002a2e02c6732e0eefc6e7c96fa3579fc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dab3920c3f53ddd302e395c2ee9dcffdccdb2d5281f85d8bdea2d0ba2cde652b37a2dafa180f329123b9fa6b8e83ec800000000000000000000000000000000056677bcf92d552494a17cb6fac3acf41cf6d90bf1c4a74f62d0f54a85a5845e4400e691193d2cd98012aa15bbece41a000000000000000000000000000000000c9e26ccf504ab0fa912b66625331ad5bc8b34bb322843eeb6a3047cf8e964801623b0f771a96b13dca419a003ca6de6000000000000000000000000000000000318c2279316ee0829ea06e96638da096f8056574a500920e39a8cc0194c48e38a51f1c15ff46709a385edec4b1c7da31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d34656742cf47c0a3b70cb106f8591852c6f607d8e2aa3a1ce8954e35d8eca7a98bef8ae9baeb5a19febcdfc66f9050000000000000000000000000000000003aff8954fde8205cd299108c76a9294ec6cdef3b6992ab3895e36ad7bf598c9f98d293918b281e5b864bae3f33849dd00000000000000000000000000000000148a55f0bea0e7757ce521bead33b750f1defc04a750ccc10a69897cd358838e981a11494ba7b6dfec8120f263bb106e0000000000000000000000000000000006d167670a7c8e34b040615a1081d6d80a857bdeddda6bbdc5e5a889937c8b370d1df5d7bcf902984ef858aa5be0ebdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040ebb87878fe33475aa8de8bae409a4722eb545185632ce865c0dc9c458152b73362e3e4fae7153cf6f56fad0a397dc000000000000000000000000000000000333d99289b953538306f12bf97e4c7ba4b235648246be74c14efd491d6947d9cac4983e92bf2c3c64ef1bd467b5e6eb000000000000000000000000000000000542ff7cce89b479b80019b9f2c6d8a872ea679965a2c4c6df6d31ba4948dd2ae2e3c00361d1412de7b829fc7fb0b95000000000000000000000000000000000030193b79c84062c2fb840ee25a95ad4cbe3d35fa47d7c42350205a3cb3a183e018702710ce096db8a7cdf1940f803221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d30669dd9d0a13782caabf8be76b8309e0611a05be32d233fcabf541c9e01ba340e6f205866796446d643b78c2921800000000000000000000000000000000090fc764825b02e16b463d59558fc80f7cd1345b26e989ec16e0027c366117e6fdde1c39a882a5e969b4a603e91b7c8200000000000000000000000000000000047f4d4356626f56c41c023ebf7b752c94bf27a3db272e22ae14dacbd3df6de973e2254a7eb8b4844361f17edac7679d000000000000000000000000000000000270e63b6b9fa5fbbd8780c9bbe4f33072244b56b3dbdabc0513ee9b4a0672a47f92221c09f50a63198294a57a001ba91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d4723da07481e5bd1976e5434f793331f0c11823f8c9c27f735c64916bbeca0773692b0f88a0dc656071f9dbbe97040000000000000000000000000000000011bcf27234e13a9391c94c8b76cbef295b59fbf6f2a5ea094935d91387e617c885dc2c85701372c9f61edce0b413f1de00000000000000000000000000000000160816cddc7636d146a7c697625ef3826f9625e826073ce2c618392acdbafea02a2f0a1bb303771692c89c610fca096d000000000000000000000000000000000661d8ed7c6243baf08248cdf291ef9d135b84d10df07777c16d7ad109cc90ce92966e2642d6e5f6d365bafefe6cc76f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001078d7221fd4c1f603f43623b93d60484a71b86f2f515b2f6a31aff4fe20b7165f247ac5ef05dd4310d0f4262afd283000000000000000000000000000000000060ed7b37deb1bd552eed11f8180fdd7386a64b95640115414f205c27a0551a6c3522abd96209198c4b9e50e86b794220000000000000000000000000000000009f0734857c490439ddaa82cae4900dce340e3ead4dd807b41bb28bf1ba477b8b565f16a4cfd73fbf11137eee6458d58000000000000000000000000000000000902a1639d0b1deb30068d01365ca1970ee0644c5e704dd06f7da0a1389c551a27d2795318c5c154a27832e6509199821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004449513367249d021033ca021b459199deaa36c4b1fb7aefb64d720fa66d63e541a5047dd5daa3076ab5fedc2a0cae00000000000000000000000000000000010fff398f66c7d4ae193db24e78fd94fe2bbad10fdc08b93ed024aacd5dab6e657cb3ba568a133e39339b4d765b6aab6000000000000000000000000000000000072ac009b4a4e82db458fe5e6906bb17e6607639f7bf42fd7c203fb03e420f2fd9ddf6d0439c07d5995540e655b8d5500000000000000000000000000000000103dcbaf1a19e5e2a775467c896a65ac61dd5d5183d293307f20a7ba520bc6ac3ace5f911b841fabccbd78d64c0a7e491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ae58b2720348bba4279c824294bb3ed99e54107e6a934198366b9fdd5107bf36f8f9fd396784bbd27238f03e3d04db000000000000000000000000000000000ad2b2a7d11d080fbb931713f1100431eb36172f69b1df4b94fadecb0fd596c40db03508b82a56a3a4932995b6ad5544000000000000000000000000000000000e7fc999e088e01bdbf02e18a38952118e6209145f9aa07a5f6dfb69642319caf721a090cbbf3e631d3befda49001955000000000000000000000000000000000737ec60913434b7f04d1c8570b08a6246dd0c9952dce266c9ab9e72031906a1d350255dfcf7d01aa844ddcfc9902b351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fe219574c6e54ee49d7ab1041bee1395f2738fa0e291ebc3d65f4fce01e84678df22ad370b312cc97095976c14f12c00000000000000000000000000000000025f86f9e7a43106518578d54889e1740f9b2e7bc2635b4ce31031111c9813b9f06f9667b741d03d71b7f935aa8155bc00000000000000000000000000000000152f5bef58a0b7412af239b3e071d1bf3ce0ec09a5cc6a5c3e1afc984c4a8745006002f6fe4d715ff9519b96d1fc32bc0000000000000000000000000000000012238463418c1546770df24a4177c1f3d65c022c6ed47d0592c6e52d089d538bb0aa271cc817f8a9914087cf4a6ce1831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015549c80dd9627118bf4126eb8c8aab23f955a5638461be030769fc05ee9ec33a400700aa6ad6f85fdd4d442423ee2a5000000000000000000000000000000000b1556d30944b820702de2932be12be563acfc162dcc571b355f21be351a0f0f86ca48bff36675fee1e76cb028b5d3fb000000000000000000000000000000000255c6ad5c87aaab7465d7540b5cd8e5d47799247d3bca7826736026edec1f4e88d8765098713dfb4567b1422c8c29d500000000000000000000000000000000194a8a6fbb2ed1a88771a134417d95429756f3c70070f5149acb6ef74bb347734d08de67536a1cda8203ada6622fcfc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000902ab4576ed4288b7914b9df1aeb6d0ccc2f2cba035e036708d07966e30a782be1acf5d57174d3a418ffc4e40320a2b00000000000000000000000000000000055942db6a5bffea962e757eef91066c6722b53154d0ad6bf0b953e93800ba5a986868a0c5f43bc0ff18c25c37c74c9000000000000000000000000000000000038263fb5773d444b843c830da1c0f0fcdd7fb82208d3dc196fab5a2e4d91727da828317e2a386342a340195e20dff0700000000000000000000000000000000111224fe2410def534eeced92fd2fe1390e73134ad253d7c937cb3338bdbe633c5ff424eb2e82a1bfc85943d80fda0381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fe3184b6487c9f2b6b5fbfbe50a41bf48a0e36de219f384b9742a9acf4b48879c633782af09c148eb00ba47fe50d75000000000000000000000000000000001935040092d83014a76c9568b829f043a9c7e6f43d9c70449852bf5b744266f2d91f36b3282f43653cee49264ccf01bc0000000000000000000000000000000014fd3040f59ab59bfe7f89defb8eb85e85ef7ef788e07b3adb088687a3c59c304e0cceb4934a684da74dad8d26ffb2c30000000000000000000000000000000018688fc83cc9c9aad55c3ae01bec4af3d90cde232dce82071ef67f84cd665588e4f7c55501b815a3079f068c2ef3d0181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dce5e200f59a7d24ca96431785cc8bc073e46e27265690e897b04a776fbae6e216612f7d23064189ddc36b1246a599000000000000000000000000000000000a32fb098eab0cef5d03628b726a94e14098c051a174761a3a96a30e9e3ed6d611584a675656caf16d53c772e5448ac20000000000000000000000000000000013293bee73df1b802148b4de537e20591fa3c662089deb9954b09fe0a823489b026713b2d63c7bab65d30c68ba266a3e0000000000000000000000000000000015276d35edc7a82ba6b98144b3d988f67cc345d10730e663014367858ea8b593448c37f69289ba8616fd3dadf946644d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000371c497146bf8226251db21b92ad5a6df623f4aef37587801417bf887ac8e80c612958dba15e7115a4a784914932c87000000000000000000000000000000001986cb3949ad5041c2ec2cc3994a6a97a35f3661f68aa68b554605e07a8d98e91602b7ff8cb315e9f628b7aca7eab869000000000000000000000000000000000d94930e790eefb208a414d210f5bdb2bca0ba8e4f97ee0ce10a6841230a940d65416d16d8c5a1e304b79bfdbf0c40510000000000000000000000000000000016aee9dc6497bb8a7db71280b9b55314ad046a82462ff55863de4bf12f52d3926687f4c1a151531c6df95cecda6de1bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d54ed6c28b2e15bf939809d144535feddb97f2259a9c0ddd70c3de5410bce4370b341218cc98bc0dba1f68629394b940000000000000000000000000000000009638b9955486d9f6897b85e34b24a0c2b7a5f1f57f7e089256f89cfe4b546281b9361d53ef9cfa45315150a534c6b10000000000000000000000000000000000259807c0b89b846f08a8e62d4e26355aeaeb4f3bb1a97a216ed26e56d3eef6cccb642e7ce0e0879a07080b5eccb04ac000000000000000000000000000000000558c3aac0bdee118d50eb7ab69f67ba87598cdf14aa8ddbe29d04b14333d360ac630db5db4050aafa1f1d3f3a706a741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007aab1673b80eac52a903d3b080f4a2a92e88021f555ce5c1f463a0ae097df183174366bf961d6a61ef7dd67ae5aa5a10000000000000000000000000000000010d7d4af18b5a912891c66424f740995d041c1b7583bc77a8fe3443afc58bd5bf468b0a8e894f0a886c0f0a57d3f63cf000000000000000000000000000000000d0cae1a2d5e97f2f52fc46766c1615b41028efa15ffa4424abf5d8e7ac5121fa0d2a0c716a6c6ab6cd230e5c8f776e30000000000000000000000000000000006d943cf00dcf5808537fbaac9cac62a493f461cc78290a7d5a9d5666b7c13568efbee8d6567d9721db4d1d253f262f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009446f8d5e39970f6d22689492ca6a4be496260a993e8e5a5069edf6e761e6968901b72fd6e6634ef3282913d84856f30000000000000000000000000000000000a638d97f46497148987ff80bdc38767fc3bbf3511ee4652c4bca3aa2992f4677d9c4adee41e50f694602eb6ca5f9b10000000000000000000000000000000008119c87b12859a05cd6f72ed8b2d6f64bd9027b9cd33265b58b16ad21e2c3001a3d7cd063401925ed788ad816d4856e0000000000000000000000000000000013af16fe9e83c565ef2137b8b9ef50f3fc61c3ee17bf38bb980ef33019e08d09c04ebe26df56729925e16ebd9e43cbfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bcceeed550e115a4aa0a115cdc4d6ae3a1869c0e5fb2c049889fe0e578aac3356b1e13055e6e2de7355a2ca5748c6b0000000000000000000000000000000017053c8228bef410fc0fefc06587f008c00735c3fe1c9d3976fb23f953b7de481ee94a23590744fb3969ba267ccce02700000000000000000000000000000000050ef4ddba5b4f035fb6fac68b5a50d824f699047e57e03d4aa70d34209bd85e39d9153505d0ec0d1fe80a7b3f1d2a0d0000000000000000000000000000000003a7e3636d3318c39ae88192af7c2330b81b9c061f6072168d27ad3f430f4a62b76dd7580580fa1844454dce1ab89abe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c023a194965dbd6d501d0b14e5b82431f72ca8e89e2ff5af6012628809df362e1fc2c6b5a3ef53a8899844f5c6afae8000000000000000000000000000000001331fe16b8c6f12c3aab4f60b1b3cfe233380a91cb3644e02d10bff29aed55f2e9360e35d499dcda40daf3d6d1d1057e000000000000000000000000000000001394c8e26c4914f0508d383c91fca90b34a1743b641e4be784a8a8062b578b9757b5a126af0195a4fb95ceb65ae6a2160000000000000000000000000000000008e0eb45af2b1b6287e4af8d99f7d9c8a4804009bd0a9514a4eeac8e0f0f22523e5ca3df80340be8f2e172d4713bc6181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167ba605ab88724e15581b02c4716519d9b08fe668107627ebf08f89c37206ab2cb197250af8117bb16d7d37afba08d200000000000000000000000000000000176f4689a652748952e6f0afd847228d8777b0393b84d7b0b3b864739bd9a9b5bbbd16f04e7c44b5c3df24cc3b9165f0000000000000000000000000000000000f19e05fa2a6c1f5e7d76d60cced73397693b92b2c4fbe10043212ff3db0aef54c55de65f589e11f25e82d08f831241a0000000000000000000000000000000000bb2ff9c4428875df45bb1f94f891b90f9fb4368fa5aec469ea4677a1bbdd3e3dfcaad5647130b31e625a4a2563809d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a8281dd9312c99f2f2e657a20170c37e312263c761a63927ea50455bb822e408068df608c9a779f841884bc3fd27d3000000000000000000000000000000000f6e79c687ce34e8ce32b49953a6673a26ecaae69d51b05350b61e800bfae2ea608aba08a7b132d752e07506a656186700000000000000000000000000000000063b606195d719cf5521b21696d0903c4a320868fc4dbe0c9dad8c58dbd778484a9fe01073208e65926b79cfe240cbb00000000000000000000000000000000017b1fee862b90bafb504bcb1d4f9a70a9360704b581c720f49f433142b7bec48b96db31e3b0f5786be4b3b134d754cbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016828dfd30eafe0397ededb8af873ec96e22bc778cba39ab082c4d55bf09790a4e4a845a87a9d6af74b068fe6f86b008000000000000000000000000000000000cf63ba474dbe1525d538fe6a9ffe9af81b1eb9dec37271d51d510b6a8cc21dd4b8f3f02997ef5e7307920b3e3ec40f600000000000000000000000000000000002b53fbf4800506e6e69d45910de04ae542994f7f337ccf97189572d82801de2f283f0d612b739b23f886b69a312a280000000000000000000000000000000008a46670066e0f629705d7446a265e2699369720a491a1044893f0bcce12697b69f155a01b38c53f17dca6f2de87b7af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001330045e6b6db0cd8fb80e4b3b8b804b2830f1f3db171eb54aa3d6c9676ef03a2167df3ff83cdee6ac93098a44740e070000000000000000000000000000000002379177126ff4a8c99ed85f9a072df7e4a2810de0bf123b1a0424540d250c5abaeea65777163ef25c8013383b0f16fb0000000000000000000000000000000018bc9af6eb4a92c78791952b3b63d51258ace3b6d3b0b6f68476e8ce0f893e8f942ef48caf6132e216f24c3450fba72c000000000000000000000000000000000176b33942db6c5e30a46c5bc739d9317f97254c35db71b7d00c9bbea681923133644ad97661aeea7042c3b2798498581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012befc00b4b53c5d2e78be7470bd7a11dde00e8e959664432e295f0665285473512cc3abc24ebe1951baceab56d793aa0000000000000000000000000000000013831f84aba3c6b2d42f3a1bd6ef0ad2cf57af1ecba781f065c8bcf624920c5a1a9e4a352ae8b8e47a8febcb4e289bee000000000000000000000000000000000ab77f632575fccd5d597617a9e411270efaefc276cc42d832cc48100b6aadc95f87612f1b6e2f14d7820349b053d7f3000000000000000000000000000000000589fee99190ba1b47810c8f32513e4cdff95861a1127feabc2eba21a45b46297002e014ef1edf87c186a1de252d36281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b6d88f46d8618d0f64e036d58f39a37f4d33a265dba378a628602d94668bcffa49b37a171071a0da576b3689c40a8700000000000000000000000000000000015bd0c3a546247eb878c789d4beb1b721df31cd78e019834f55970edbc7ab95c057ef03cd6102195e01e222680bc9f3000000000000000000000000000000000ba1d6f73dd55f6010730b61a49c85034315720ab5eb1bc91d5f2d33bf2fc6545f6b1f65b8e907d9147a7e5e97f8cccf0000000000000000000000000000000003a235d5fe02c005de7acdea89bc95bcadc2317082ceb0276631eb4a0467595de0d42463dad70af3e373ed2f6e60c5b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076b85b71e867a23446ee38d46c28b64be9bca94019d50ec47dca07d89b1783056690813812c46b124cf762a7473b194000000000000000000000000000000000bee773592ad08822ded635afb6c4ed9396ee7a81d43463d86d8f67100f55b823880ee41c776fd4f79d273088a6d7d3d0000000000000000000000000000000000cc25edf9db70a73996217897df0d652f93edef2d23878c184d68e1aeb49b00b49a8ee41c71213776318dbc54f2fc4b00000000000000000000000000000000148bae47bd452e29fa49850b3905ecb9e8dcff38e2d30dc27b7fdd99480b3d2c8edc3d3cf8994de941d69a5ae28627e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003719ae6c20753f989aab56d1b204416ed5be8690f84ecf1c8ee085ac917a85aee9f7f7e1c509dafaa03aea620ca3ded000000000000000000000000000000001736e3c4b13dd3242d0645a89a3c8103761769eca64dfb6e9586fa70042b2326f78093de3ff044535fbd8c3cba1495ce0000000000000000000000000000000005ee15315d44b213fdefbee28bbd1ee0d437d42e03553695c26df2324c3952b42b05c5e133301514258aea6309867b6e0000000000000000000000000000000016c3b0cad107b7b2a080cd497b8438d8bd427b7a8c029f77f34ca59a285ee747ff371b21d525100adcf9360bb9d3110d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019910c103644718ea31e7c21f2534dfd3b3fc4b9cdcf72232dacdc7aea251ccc91565e2399a5c1b864826b8aea9ba942000000000000000000000000000000000c794e0d9125990926d797272c7e356242b863d7ce22bd9157419ad3ec1dca12f582232abfaccbed584eb7aaec272fcb000000000000000000000000000000000441ba689544dc52a39c4d0b9c5d2d00f09d28afc8355b95aa03fb57b86abfc3653dce49aa4c5e5dead21bceb683819000000000000000000000000000000000084b5c26084c81a2aa3749be06c2223cfaa534fa3080c29b53205ea90182433c0d2ed58db2e500ac4197770741e215e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148f9044d350b8fd93e2514447f78b71d7d60edfbd49cf806e6f5f210f19742880b7fc41fd2cc1222675943aa2cf1807000000000000000000000000000000000b69968f8df265356d6d6706c9997763e896533a9c96b47bc24a9d0548b060df77304787157507a8417fbb0ed59843b10000000000000000000000000000000005049744786e8e11c226fd8ea9f360381335d93b3935cab343b8f055eb4891760fbeb61265085fd7a77175641701eeb0000000000000000000000000000000000c5022b5aec608817ca9d0e2b9982e2a4013589287c50ca683a05d7136c4175dd1ff97ff6ededcda73e6e07d1b407b5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d087b4d2f7223516b2570db01dfd91dc711f9fc2b9feb53d639b378f9fa7e74b2402bf4f8874448c4eb05d12e6694e000000000000000000000000000000000748667df3b0794a5d327f584d47c31d41cf2ef76ce2bc417a426a83f783a5fde90210ad57c297a11bae77d0d90bd7cd000000000000000000000000000000000fa8a8942a7a1e9c5fc47e093c6de83eb09459725db1ba24ae7cd8a9846e67e877470826808767f981112375793798880000000000000000000000000000000012be61bb9b4bb6fec48b7ef143f8404b6adbd3fedf70ae0c92fb04d766aaa28e661d069fbe697100e964fbc662c480011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1ea3f4098d01b47f2a4dcdaa2cd5d71bcf2dc32645c6a3050a5da911248c45a12facef170a1158b129ec61074f60bd0000000000000000000000000000000011ac8a39d315d27f0862c0aa9f26bab07035924296195a8f4aa5299a7037a6648649d252c384762a3b6e9ed4ad2bccbe00000000000000000000000000000000003ebbf5543e0bb713c776aa84d5b9fbbc81e4c76fdf5f10dc327fe9c64106a66f316bc0adb7fd78b9f3db9e3086c5fe0000000000000000000000000000000003c65fc457d6d9fa8b1dce1a5709acf397cd6acc3a0fc7b72a4ae53c245e090cfa3c90a3d93d1f9fcc3f888ed221209d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001745d38eff77a29d163c85c17de38c93ddbb7fbe995c30fb2ef99a731f49327f86b83ed0773e68cb224a5e985dcae88a0000000000000000000000000000000001b2792b5f82d1cfd4e38305a2bb663dbbb968d92f70d278e5e3206a47c14cbe7b518e45b3877e4392ab6855926422300000000000000000000000000000000007c77d3af4c342721cee88816ff3115c0d6b4ef40f47f0c4a62eebfb9304cf52f446417b8670f23807b5b9411f7fcc31000000000000000000000000000000000fd28acae824f7ce4f8e466173e6e9e3640fdfd669de69405f4365e5323be37634675d3afefdbdb37be419b04d5784291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7389237d19ff78f72d0a9f96236f90ad87541d50b8a52220e87c16048f776043574bfc91600f7a6a0d69300795b0f200000000000000000000000000000000093e0b1f0d69c759602b247dcf5b98f71d151ef99bc2f5fab37f9bf6275f7b56c43e6667a36e312e78e4fda34b297ea20000000000000000000000000000000000710bf0b2734786f3149bad14423f062854cfd5780b78474ec16ed675fefd2e42839817338b1d713aa9e5dd8c8f2c86000000000000000000000000000000000d46a029c4ef8ac1782dd99bd0932287bde183f18df85b284ae6bfecf96548ab203bdb684f87d1166ade85afb4c8c0d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c22ae873d52e326e25531da24ae6fbdf5e33871433635646f6a4cfd59d13c1edff1445cbe50d5fd1a1894e06679294b000000000000000000000000000000000f388ebafa4f4c36a654bc4c6ef7bada77f3958ac827a5351e087c03fc8389169e99024b67ff7a8f96d481b20f694dad000000000000000000000000000000000d73561f940076c52dc74564558a3f99261ac8658de94d429276bac7df7cab74e492683eb1eeacfd20a85720c7a93457000000000000000000000000000000000c624810c9d1cc475556d5123d6121686c4ed06ce71abf3cb724452b0a54b1bb4b1c64db2f2958fb69604620ce1ac1031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e4e9a57e009c2b6105868ce993e8396f210f8df81a1c024c07ff708b599fba6db1192d9b5bab96d5880d5fb4aae4720000000000000000000000000000000003c5c3795fe1d6bed101c2884b8f9720e4d2fdd25cc7ee2626882266476fe3db0f7d716f55ae84f21856237ea676f1c3000000000000000000000000000000000fef9fcd12ab36262109788279cd29ec85e9e4a3d8ca680f98514a75a3cd614b0c75f85a566337becdbbcc607530e72100000000000000000000000000000000050976ba4ed35914e5be75f5f9de3deaac5788fb0dcd113ecd14fa1e2ed5bbbc358a3bfbca32f72228b305700f929cb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2db543374d2f05239be800495b209f1381d47c822e629d0965cf7f77a18f347e23fd20ef473a5558107ff048eb640c000000000000000000000000000000000b55ef580c6f3a8e9c17c412a743b317ce684cfb2b12623de5d03c48f07b3b42be6a50920292413c20ee309d6df2f75e0000000000000000000000000000000002f4928f98d2ac2f1789fdd7341e9698a504b682e6d9e97a78b98550d2cf03e329b77139ff73c11fc0caa21434dfa44a0000000000000000000000000000000015dff7df97f4c9edec3c5b699aa2889b2349056248ad95a02b520125522081c0634e13890bda325bde935ce414fc382a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eac19552236e6e800248ca6037394e45e94b3d628f6e466a8bac835ce08c5183b5680d9f6e12b7018eb7f12faad5a60000000000000000000000000000000015c4046a33cabfa3e938d364cc78c64fb37ab69dff7d462fe07102ff0591b2aff4973371e121ee372b1d3a32dd0f2795000000000000000000000000000000001914c3017968277e4a600fdcf912c7b0476fa6623a503c490e1ca24e764cad562ce2004218a9a5f44d8cdc34edd9dd14000000000000000000000000000000001833086786d28b2ec1841b9c9af80c8a5fdc90611f860b9b2f8ee69cd33b42c44eecd34ec51501b34a8288a1e0e46ea91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127c476d2232710235e4582b06406cce2e262e6431a638608fb71c7505f27a0971e12fd188cddf3a160d7548d6949065000000000000000000000000000000000c0643520defb6fcf90157845e12e5a94a938f7fce958339768eb2ab54c73c7a27059b658a27fa7303643398d2fd46ca000000000000000000000000000000000aa655149b8a0e3a725123814a95189d18a61701665b6d077abdbd18f1c3bbe63e9804f443aa11433c0a89e1a6f0a8c500000000000000000000000000000000177dc3bbc9983fc35af72839dbff7d84fd3ca425d18341c4ad7c8fd981f2ac3ca6c6ef0b125299c386ef9a2bd56a2dee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb000468f2da1df0e4d3feadf8b9e3eccf0d9f74948b77e8e8551d1d34300260a14b55fe9303bc440cdec44982070a40000000000000000000000000000000011d2d4f0c7302343b731d5a6afd34b35834710496d1b5a2b524480e047b1e87e8f54525b2d93a831cf33923195ad7475000000000000000000000000000000001823dca2011a85949ce46bf5d6eae540f4f1c766f9091e9e8c8775feb64986262dbe28450628350229c0715626aeac1e00000000000000000000000000000000048327b645a1c739e3e02df83244c0cb22beac3ca2f23d02b61754dabb0d9e9b0ec52079a83daa6059ce80a0cb8c04c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5fd51383e04dd3f69b1d6e6701a88c2da9ae998d81aaaf0f5978b4a1020b94be62ca959d3cf377c4d350cc42959dbd00000000000000000000000000000000053b3f3353dc9d983a392c81e9d809d42cedf1c8583affabc7b6e1c8a8f8ec8db4b860283890ac8f8aa0a11a50a8509b0000000000000000000000000000000003b5f4fcc5555c9581e0b19de8d7d1275359efdffc08ff2facf95856ae4f78830e7e2d59d058d7bb2a5e9ebd735f309e0000000000000000000000000000000019a39d175ccab502b15e50ea65d3354ec6564502db5168c8f77aacddd8c2a241359a958089f9670ce9e5752850fb4c881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcd58a2dd9b4973710b5962c4a655e8fea442f277ae329574740ea3d6a7d39a6697857442a392a2cd4ff070530fcc240000000000000000000000000000000014106676107ba48b462546ae6d0181ba4c18fffe5e27e26afbc942dd0377b0d3fe2c4ae05ebfc56307bb69f21cb3866d00000000000000000000000000000000187e1df43c0637fa537665bf29799de57f9534adc1c46fba91d29813f07bd4b9a20c0d0c802a3f009ab676ae8e1be67900000000000000000000000000000000069798f6e6ff969caf189a99ebc7a946f1cc3961cddbde818345f4f158298aad1cef4414e7232532e917c046262b7cfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001070d9232e7fe7e808f3029dea44fc24da8496b4ed0d457f782dae4c449e27de8fa8fb0ea3f02e05b164c7919b2c15e000000000000000000000000000000000037f4ea013024ff2d375fefd45a781a7c1e153b54f7d829b0c18d85c8d07d77187bba9f75a4831af67353b999de1185a00000000000000000000000000000000141fd5d38544443b981054022e6eb097508f9d8b1a29c9dfeced3c1753a7d1366ee9126b29c831e0c65232efd6ec3a970000000000000000000000000000000016ebcc73410981f7830b6c36d53dc3749e96925670b8a20ae45ebfbffdffe4616ebff0678b232551836b6206f13b78541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083fb8c8f435b1302a7a640d45fddc9b1e4f490ecbcd7eb23a701757be87325498ee3653654b950a99f0109b50fc476f0000000000000000000000000000000012c9b6cfcdbddeec0f0f2fe30b8cd55919a991b738bf5c6230da517933847896fc0673773d82eff70609c30ccc7f5ad40000000000000000000000000000000002fc4fe5a7e0a08369e0187d1aa291618106721bbff8be4bff451f8c1b004e8208ab49cb79cfb6f155a3078f17565d6900000000000000000000000000000000194b09181daa18cb26706a4ddd1fa1227815dd55d844b3ee1aeec37a08c619043ac06ce5dc68032b09ba49c530bd65ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153fd2a33a19bd3d52451c83d3d031460857345097b38321745f437d181a2ccbeba46808ae513707415be4755af4ad02000000000000000000000000000000000b3b0b3afe0b2c0c315b1576eb0b926ae240fac68e1216d24391c7c230fab211bcfd6b82d2ae215441c8bf78a9e4356000000000000000000000000000000000116a63cb7fc0edacc8a988fc65249e2ccadca18761cfe36ea5cdd621d81b03a8984260b576b2a0aa795e85429389a267000000000000000000000000000000000fa0c8239ed77a227e879196fe2af304e9a6a6d6e48a850802b4de8b7c75ae0ce98edbeb6b7c1af1fdc689c1f6e5a1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d61674dd08be7e14534820ee1a7efbc0fbb9fed751a73af7a832a237800941613faa069f2d029b20de61dc293d6f500000000000000000000000000000000023ffdc232d52e2e5b5a84c2645fb362ba036549cf1878620693bc8177dbefc66879ad2fcd4a225e460381ed04fc6734000000000000000000000000000000000eb782b9405415b138ef2a6922956adde509ce08a67ef8e31c3d39ec9d1f51e11747766b29954534977369ce52b6b0cd000000000000000000000000000000000d0ab9a78b95064056e13a8fa2f60cf66ca1dec33d939f147580d19ef117906b5116662bd15c928095a1e1cb6442e9fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b9c041f2f8441b944fcb591e6ff558eac982c81d325403839adf8065dfd9aaf9b30abe1533e825c5709fb48840dd7c000000000000000000000000000000000b63536c900bb1eaac7b95a01645fe22b7c5fd9230f757048f519113fe5d46c75f7302fda45c2994127b313bfeea6c4800000000000000000000000000000000035f5378da22d7c4d9fd51609b03c1127b4e254386e0bf959592889f2d1eedb30ac85532e6d78966f91f5193c567467200000000000000000000000000000000151a45c6d93d32dfb47e2d89843145c9f6e14d0996089895654b55194c57acf67d2688d2589cb00601f0a8331202d2fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000033c987e7134e090ec98ee57d04afe43b3a03b7f7d77fa4693a9ff48bfb3e04cd49707d27c096659223534848128c2c0000000000000000000000000000000014383c9014e65602495f6f447350474dc2f3aec7494400bc238dea1470db4e56b66cec3630d09cab8c6a572ee4f3ee510000000000000000000000000000000011876456bf1d967ed8a1642e7f9b70498149f1d51949173d9d24659f00bacf5df33e6f8e8d97fa709139606b1347121c0000000000000000000000000000000006f4b89a3aa5967917768caf9850b7adf3c276fd5ec312b6170e737d4943ff5f7f672c64578992df6a7b020cacc2da461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddf3a89451e80848ce315884378b9162512de0d9ab41c749b40f946d026bcd9f70d71b0fb889b23c9fbc764e3a31ade000000000000000000000000000000000e79fc011d79a4a552dc2b9e6466de01d450b7f9a0c3b7704b7ca2a13b766c2d6b28c3a32f2cdc00dea7f7385eb7c799000000000000000000000000000000000881c6d457010180fdf9b120db3a713d905fbe23bfb3c6ed520eb32700ce2c0c9b1a8bc0fd7467a25b612236466580d30000000000000000000000000000000015a30b2c139fec2ef7e50a2bd2b639c6c7625b0de4a1227ae0ffdc20bf694c4c54eafcfc02bad7994215dcf157cf74341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010aa5edcb9c9db6e18ad3cc111fe3fecfa4d8881eaaff662aa9963458612f4d24ca50ea267bca0c2ecfbd36ec0f856640000000000000000000000000000000009b4f263411ba3d5f2a54c9c01afde206a9881f6e8bb669b5c9e37de7428562b72ea9b27c824b4cfa35558d16a20c1350000000000000000000000000000000014355d9f2147417862a4d1ce7121fbdee3ae2e1fe3a7ce410157fb723891fc1433fad4394fdbd9fa68ce42a86c072ac100000000000000000000000000000000087866cc102141fd9f375606b0b4e862cb57b4b56d3d0eee92d05e0467239a906352e42d4a01f36ea55b0d35360754141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5ed72801addeca79b072bf5cb40e3caa818ad5a13ae99e4fbe7147293ff1b86950939e510b9abae7e47d2c53f80ee10000000000000000000000000000000017337eb986aa94d13ec6cbf277c2de721953d91c82314612162f8045cecfb2fdc7aee12ba1bafd71708ffe742f98fa130000000000000000000000000000000019cce38baccfdda9d3365f8eec5df1b14066b8a1cf16a027f553d8070897d47e05b516b55724f99d329ddf33833c1dcc000000000000000000000000000000001918d311ef01fce4f84c47569dc0bf1ac4d908dcba56d420b59da072931755a0c164022c3b4800cb4349cceee050bd211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001147630c19ed87597e257b2c06ff754d4f9f3f2329f3f081c62b5c9b1e6306535cf306d617e4332316b6141a956277ef0000000000000000000000000000000018c55ef22d9195cd21be90d91c8dcd2d9b87505ddc0f37622c05ecc4c614e21af017dd400caaa805e30c3c23a4e0f9f00000000000000000000000000000000019fd38d372aced7ca491e273d823b21c64369d5bbc9529bc4c5a0f757ddf245b38ab79ce3f7a3eac61163c760450fe170000000000000000000000000000000016fe4dfc4a5fcdcb5f4c28e153797be37939d5b7085133146a3be0ab39dc83045ef2a3dc32a61c2b62a29b7f6c0256231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005188a5227d4422623fa652f099b801a9cd34b5690342d7106eb9a66d2621b956f5c943cea313074abcfedc105785fed0000000000000000000000000000000004d28154b5197f878835f0dc971086e3ae1cd6a99fe0649ee69e2170e1f33e5739cb19656ce832555d29781159f1e0b300000000000000000000000000000000077e59f7631d5def46c78a39fb28b6a47dd332b86ad2c53d5158f2adb28faaa63548ff6f76c2a63104c308a8b0d568190000000000000000000000000000000018b23c1adc5d2d5c939914eb5cfd5db13e3603349be404ca9c0cfedb9726af7fe708cce2510f5ce29235e5d876e5ee5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012714f767557c677daf293afa80538592e374b21648921d5e489b6b3d4b8bebc5eac36e33ec97e3689365f6da0ee3a07000000000000000000000000000000001419c0641f6427dd0ab08d42ad885fc6c4c82078065494d1dd735a4843ee9dacc913d5fabd59c439e1ec3bd6a46c47b50000000000000000000000000000000007e4af3e75a92a99432dafa5d3d0bd6b3e8298650e323887bfc3eb76c3f57e047574599d7f578078461c5fb6e6d5a7b000000000000000000000000000000000199459fda236248101c948f8c10131699bf7b1c7acffb186286d0258d2051fff764340eddd9ae21dfdb288c97056e9581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ee2adb697c9f957edfde9c9e1079fd67e86b942af0a632a8818448e398acf1195e399e8496a2739efaec4df0878fd6000000000000000000000000000000001449ea7f322d55954bf0bb9873550eb2de170da04a34131387ee0d0376a1f62b5239c360a4ed3b9257f86b6031e021c8000000000000000000000000000000000eb578417e2cc2ad2db14dc03666f6da952738ee308ae0b55a0e4307631a4bffc69082ecb08ba1c13d9ff5917909f936000000000000000000000000000000000501dd7777ce9fd8a4b05900aebddc83e9227b74972f27a305ea0510debc45633e584c7e50d272ed230cd19187202d881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001415a0598ce2bf6f8d57693c04cabaa0c3e92cb277983450ed66294561caa1c6206eceb8a71c3397e3a2753563fdb9fa00000000000000000000000000000000096ff981cbda6dc16d80e473a3d8f8446310256a8d450d37448c8de89cc179ac9927eb357d07283afaa60ea11a1f024700000000000000000000000000000000042c914c75aaf1792f82d1d8d369cb7ea2b4dc70413d66a5545d408d2dc437fc24b7f0207a838e04a021245d2ddfa3ea0000000000000000000000000000000002797844f5a14c86f9e5e6649fb82751fd67afec1c349603301facb5b0b7ab9d4f97a466437fdbdb8dea2e34d97402cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dd2d066b8b5ccc3f76605758ef5e23dcc633f86272156ee71b8ba8cf29a00f8a6e68720987f5aa354f7b265135147d0000000000000000000000000000000003a2b168a9da3a3c0f2e0cd23716e8fefa0128eb65922806fc9a1dc6d54a954f731fd4cca74d6cfa09658c7e9c1857f90000000000000000000000000000000008ab1ebfc50fdb4865dca2ebbacc0f4eb8cfeba3461fd04d94cda523b1e774e71a2678f833b06bc3c1f7890945f8a0d70000000000000000000000000000000012d7b0b95e0220792f45cce9d0e7119d88fbcfd7b8250f7d7cf234f2602090526aaf59bbc2422b15cdb9bad58b73f8cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071699a71df00c4356670c329afea6ac2d04a705b4124a1139597e3cc7bd42615234b726ac301558a129cdcbf430aadd000000000000000000000000000000001500b2f30811891f6bd2f26c410b4bf60ccd65f47786ea8e92582267e50e1710ca3ee692291377901e804a14e4b100280000000000000000000000000000000014daac9bd679388992bc2079b64ef035f69c83a42e0aca06c20ad4aa45c7b846e82de49388fb72ca94457f52bb692c53000000000000000000000000000000000de63e3221cc20ca09f1449a28c632df37bbbec582c7baa24bcc9e1e23b0bf46053e2899ac97df7ea847adb54e77d5801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198032c8e535e475616f4bf7991d77a0d4e79f4645e6a53c042ae255610d7338db7cce4cc8c044b070eea69a3b249edd00000000000000000000000000000000120b243262ef837e42acae5478bd0f4580361f1b1c6e87e915047ca21f8170366adad9b290ae11866780b63cdb068d2b0000000000000000000000000000000013723d94c7bd5a94db119ee890980f2966516819b36947c856aced0b44b375c2fdd29666434dccc3108e8c23855beac4000000000000000000000000000000000820815ae4502f962cebd25763aeaf60c2c93dff78fb938b38b6d24e3719569b8183abd12811c1b9c2b5e662be6246391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c486710ea3db8f58e98af9e52ed16831b1df5c8c97c76bc8f11d81808ff75ba5b6560ba491cedcdbadab3631fb8ba5000000000000000000000000000000000332cd53a6f7351f59e9a50c0fedc6758d854eef0461059ed93b83474f981f2aa52469c124da285ee6026c6255fdae23000000000000000000000000000000000c30bd95fd28232885f019565c22b281f5c3a397978503813cb7911c22ed3c2797fcf936e7d0f6807fb58a45614f916f000000000000000000000000000000000bd300799944e6462cec070c5c57d1179b05a5356cec3e4a1bb52dad4905b27b53a822c6997e2f8569df3c04d6dbdc461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010121ae2c121ba4e165f0eb40c9049ce5f55b027cfe9e27b6ab5e0124b8c2d11194915a6fdac9e271a27e6c9afd5dc24000000000000000000000000000000000d077b079d950147fbf08ebf5479d31e3b94ce46c512c7b9f1e5b4a818a2bfb0bcc71ebe4c39f41a15667404c9acebca0000000000000000000000000000000015a60fb4d100fb649fb7329d458f863a2492e3364d5274ce43ca2b0a0f749127a1fa3e707184186cc862ddf305f46337000000000000000000000000000000000ae9c89a034c0b47a232f23e168509de2ebf10b7f1c6b422ca3d50c2d42f3f3c3d027f523d8d83d8853b16aac5e071be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009883f4f5680cf2e1ed65c3b0ceb125a3062245a1729660816d8d6ae7712f45f41b8fcb069708c90ceea1299623c7d92000000000000000000000000000000000f627209e410dddc44a86d00ab677198dc8476d9acb9652dba2308bbe213b953eb3bacad470ba95bd232f8095128262d00000000000000000000000000000000024e5a84577cb04f2b6b3c92b0057354f6a19a9477acb8059a1fcfb81497e87ca472f7cd71f8af0a72fe1967b91d083200000000000000000000000000000000170d2081c697db5549d674ae72d89672cb8e765232e90bb5b7b58723d2a6a29d73148d4110a61b0093cee013d151570f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fdcf8d8c4e3c01bed8081559ca5d460194b2c5b416cfe4c4f58ca49631c4c501dd6ac3066069a7635b42f429b3b8010000000000000000000000000000000003c9d620b256da3a216a625c0bdece610b91ee3e7915e177c756fb71bccb0d0114d9edd8a1038cb7da49c7d2c5b445900000000000000000000000000000000012e4e0cbfad1718eaf1afb77aa92f7842d60e333436e1a0756a838c814156a308e936d6e648fa427bcf7ee1dac5936c70000000000000000000000000000000012218ea520639fc3a9e0893567dbcb26df6ac18fffbf8fa969683cdfae6cf572328fd00d1f0256f4d6caad36a0b317271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011492a3635884b6a630d355a17491a2b5390f7183f1977f2610895e9be36725bcc09e65f9e386876e8da06145e15875700000000000000000000000000000000020ff996af2df9baebeed729824e5b12030a178d58ddd41ad36cd6304ce850dc26235b560aa820f891ac28dae010881b0000000000000000000000000000000005d3a5c95972f4ebe79f8770e23b7584002111d79fd960f6bdaed6aa5c87ea2e74f7e205cdfa265199a501b3f445aeb90000000000000000000000000000000001439eb89121b5d9d75af8f7546e2f70599097ec0b6a29f086d60e6ef91fdcfd837b0b3fffdc1d77773aa206ee351c471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e979c5e1f98a756cd280a61c8568b79ebcbdbd6123f4cf98eb8527646b565b1e0f0fdc274847bb6737bf3b18a654c90000000000000000000000000000000010571de2574ad8fe07ad642cc855b3d92da980fd67e7a16e5ed942f20a7540fe67d58c926c30dbec406732f1cd363db50000000000000000000000000000000019c75d79f07750194f661fa22b9f75936a5c30f2b2dcd422941100c80da6f9c79d87ca38ed2afa4192760ee2a092bb160000000000000000000000000000000007115882035f763bb070f5e76c9c3b6ea8dd002918ceec24e511dbcb8fe6da3e9c2b6dc40c0b49b9e3cd13213d64a37e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185a3ca1c44d30d9bd3f473b1b6f69ff705a44f25fedf4b63e902100b2d794977e2f2b49d1f04eee3d5b1eded45a54040000000000000000000000000000000013b1d42f33ef2ca84c5ea45edac152647c342e76509f61691864c4d5caf64300eb40ac00d891ffd154d5d97ca3fe050100000000000000000000000000000000088c5d048db83c7ec3a0889c5a928eec23ea7f4c4af52a9dcc9d6e5ade5c24d979000c5ce2a6512c40122dcf0517b655000000000000000000000000000000000ca37b17c413ee21979406ab8465e655156cafb57da0b6ffc1e737effb0de4c80e75482d58f5f269cb81ee8f267daf691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e167a36f639a19aba1898d28c727a9d1699ff5c4abadd55ace4af81d677bb937ae8986dc80b41bbe0c3398d4e8b0d60000000000000000000000000000000009033ca53e311fcef91914345ae157cc6a408c14f8b004060005099886e85cf17d816e3519ebf7851a5ded77d61182e4000000000000000000000000000000000426fd54ca458905c613b2e5ac8ad87a5c3d834800b9e40c06c7a8820c3fd3e67ae7ad52dc2a9ca671ed73d1996963d6000000000000000000000000000000000c56ced3e3c519bf54faf1a00cc9f6881afa0f1f607b51ac156b42bd5dc48beff6a0144860a5ec9d5b83b2f3d4b2a0301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c65cf0ae1fa9da0f4dff226a2e34934c5dbfd711559709da9d324a9572a6fa88f63e5075cd8d4f77e218d9ef4b063ec0000000000000000000000000000000002160ce5add4f2d4f111449d353eb8491296148d6a1679dd85f535b444c703277ef496d00c0e5edb6ce0277c526df4eb00000000000000000000000000000000188c69a16df6cab28205c4875659e9638ef7c0d7192ea42604d99e66e9cc007e490c95f4018921d0cf1d2a09005ca5500000000000000000000000000000000005b7031d0da9dd7f91e6cf9355dfe10bf9a0d61f0bfa5379e5567c453ce146242e8892fcfe8579a5e2eef371c2b5781f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b6510c1d380531114c81c5023ecbce33f2a4e833fbf5b1ba3143779e3818d4437557c98e0c69fb0dd67fc36df0d401000000000000000000000000000000000d001286d4e64fd378a0798b5df0877f0c374bf627d06b7d408069c2ecd841f3d20594545f9aa60c030637155b014862000000000000000000000000000000000f377701d5b3f46a1594f46aabf6e082c8504b9d21e56145039077238bfdf38995bd69a4ed2774618e8586a27611a8860000000000000000000000000000000011ddce00250022a5f729f8272cd912c6ac72f7191935e359775c606bb0c6adc514d32289d3c200619c729adf082b8cb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d43bd24041ae9cd23e5b56fd2d84b23e2a7d892921ca64af8236d2a53efdd40a241b272ef8a2100ba31620ee5b977c9000000000000000000000000000000000ce5480b091f1a30feed8c761603c2f6f73666a676ffb8f709273261863e77a144b09c6bf18795a9198d25689199a2b9000000000000000000000000000000000149ddaaa50629b55a390212adf85be26b016f7facd55110762b002608f2bcd8542e727ca7b4cc419d4ece06460597580000000000000000000000000000000015cc7e476873dd3e373c0848609d1d6e6ca8a2e46da28fbe504875d767c8039bb52b50d97d0703f1e111a3cba214c13b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5c4a901dba02cfe056e17314a9d8b289f518d485128bb206fb5be7baa8b3ffacd48def87b1aa28210fbd9d0d2978ff000000000000000000000000000000001049b47b3de96a8b2b8a9f49c4c59b5bec2c3faa8dd4ff3ddaa619a7998b80bee527b8d062e2614cae1e559017123462000000000000000000000000000000001839beadd746456c6ebaf62553389a62970063534bfa53d523638b4711ed1ef9df79c42bda4d48251efc554ed08d8c23000000000000000000000000000000001410e9aa38301705789b21a6f7971ec0ad10aeb8e1b7d3d6251c047468a2695ae0502221c1f817b9bdefb83f2b16bfb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001504ced093430156036a3c14d619f91bd7b2ba41551a4b6ecddc267e06be4dc3f2c9660cd9c5fb29339c4b0b71df4f72000000000000000000000000000000000c84890b8499b8938c5cdf77824f84dcb5dd5a19821e6ffab80b8ae859e26b4d19b11d04adc5a06b1d05122c4ca51bb70000000000000000000000000000000014eaf94644211db5540eed75e9c562540de9420763425ca866b3919ec3c8d2088682102ee1f42c83c29584728a49007f0000000000000000000000000000000018ac41971257668fd19daa64b629fe7df98fa7c227612308eebd1125225a44162c6a4c4a5424ff04a2fb8dacdd7a7afd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f82fdd1ec962e0334b93e1dff0cf01c5d7f3eef0063914bae6b29ead04e3edbaf9492b20186f580b9e83eb824ebbfd9000000000000000000000000000000000e5c5d38e12208f8c7c4a2d1bca12a384c82bcd93fef7e9e0a5af71dcb0dadacb1606144add1b4e6ab11342f297c50e4000000000000000000000000000000001026dfeda22285f45a3025fbac2184b8482545ef76117f2dc6d5f27ba868ea7125f95587c36bba2a8343910c7e9091ae00000000000000000000000000000000031af3147ae2d4c85f64f16d546737dd8218325f51ca1498642cdbae69bb5193edec901c698ba1433c0c547e217901af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167be99385d7ce93a615efc1d22e11c44789ef828836da3e666a372f8c32cf6b5d602c4b82fdd6aeb53cc5beb850fc96000000000000000000000000000000000300ecf977e41cb01f4d9521ac0a3cde9af237c4bf955d651279d6208158abce0d47290952946a82e9cb8e8f04f76b68000000000000000000000000000000000d6395fdbd07667917b592f18aa48d21edf609b593b27f480fc5ef9a0533bc9bea6c6b0d9e7f4c3092a5ca75eb64ed94000000000000000000000000000000001247acbfd3dadfb9b42dce312a307d40e37ca8fffa1ebf483f5346f449d4609e31eea3571d7d68c6ada08c86f13856b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000627c03f89ad7f78d278bc55474f9e037383486e83d58ada072b2613feb6d9c4d531fcc9fbd0e34d20bf15764c7feb1d000000000000000000000000000000000e144f1bfb8cb28f49d8d7bdbd83c8beac281a97df4152bd17bfcb5c3e72c482c1b8a5047d5619fa3b4f9dee5f667be000000000000000000000000000000000150161d39f6fce15a73c20a4bbd21a875562d03339ab55509ab9714e4352b121fc7832096691f96622ea4f43339b16d80000000000000000000000000000000013652f1b11475fa345c51735914013fcd0df2ee71be5203fa69cc1071a2cf352bfde97b78c819fc6b516c0394b3420521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001607fbeb5ee534f226ed43d05db846992e5d8b0fc79f3ef0cbf2463373caf022f3ad3b8252e1b73ac49a6e94d5c651d10000000000000000000000000000000017b8cb020bfa3356fb8f7c7ec14f10de3fcc54eb7c958a017f02dc91436d7477e873bdc38f788cd5c0fe97dbf5400895000000000000000000000000000000000e51485a12fbea0ab00895c2a2d29d77afe502c54764bccbb02a0fc98d9639246755cede24ad293bcaf6f8821a44f1450000000000000000000000000000000018a30e69b692aece041ea30f5e7016647f7586e70712f1c58d6aa89d4d75d34776cf3b8c30738e9b41dc760414310cda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d51f2ef6ab5468504dd55007cbd2e71f812ea7fdf10c8e00462cf413b3e8126f42c1b8fa26fa46db1865719e67ade5d00000000000000000000000000000000109a861362d8515c87cb5237f5bcf666e232c2a4540a6c2ff9db7e4a3c0a0d191641915bd1ecb8d1fac619bd991d1a060000000000000000000000000000000010bd509edb0c3327e4178816abf369ba51cac6feadd352f14bca366175b7d91612733bc0d0a43b2758a64aea18cb82bb0000000000000000000000000000000004dadf23688c4367f253d4977f0ef39a0d6da3da8b9d9cca9fbf29e1613a6c8f93ef996fe89d4596cac1e549788d453f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001002c22ac5f90bda3a214f37ebf9d783e6e7319ba617bf2665b872ad05d27c36376c87b80d3f841b8ff927cf2cf8158000000000000000000000000000000000d0ef9aad16171f3832b8dd42ca4ad8f70c240dcaa2ed840fe0fa7e018cffb4fc6c8917e740e3f868727275b8c2eb07900000000000000000000000000000000131de01d402e8f3856225105e3a57b1a6475783c88136b3051d0b56bd0c881b0718ccab8a8ba145a55ec75fc984fe37000000000000000000000000000000000163f65ec4cba28256af978c07dc258f4564255a6c028931e5b80879723be6a8a2cde1f040b940634827c41a24f8f67f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151c950ec89c6a17ac000dd8de3b7b71e9d6cca040df38a2c045c2cab7fedf772618725047a7c10e1916df2e16ecc2550000000000000000000000000000000016c2d6f218a5eaad677c58a6fcc6c4e9fab6adbf3556245f69cfded4ac96ae9b734bf084006208d9d1c3e189aaa757e000000000000000000000000000000000126ca5b3059c9e1b7d3affc4fbf979ec4f8166670da304a61d0eae5b993ebee226b97ce497383fd154bad94a7cf39f190000000000000000000000000000000003c1b024b3a9b6a396fe00ecbff2327a21f0d31318a64c9b620d3c932be1b7b3e895c6f6b1a4cb5caa1fd82085cb86181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ae685dfdee9af24ff299148a0cccbe4b4ec68179c048b7969c6c7ab6e39becaecf88cdf54c8069bf99f34a8c3fdde0000000000000000000000000000000000fced4567e6a328feae68b91f9db6dfd50b7c382e3c48002a5f9a692e99b28352a16fe7416f260b4dbb0dfd893999b0c000000000000000000000000000000000cb7f7daf2a17aba3496461a7fa9d643288f46e26c5a0dda60e53af7a4b79d95699bce96ab2d35255fbd7d392c0b7158000000000000000000000000000000000d6ddb11f6720fb63bf69f90a0131d0d2e2397b0b9c294f4f3bfe5fbdcaa4bcefd979ebc63ffdb1217e44bb5f549dc761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de0a8981edff6100977073b8f9f66047195cf16820cc7687a34ce3ce75f0ce2efcf4d2f15e8ec02800c355d0119f39400000000000000000000000000000000107a34c8605f711bfcebf0d3376d65a9047edb8e00a80565342dcf58f1f96bb0aa046ec4778e29c6ffccee8d08884be40000000000000000000000000000000003ed2ba135df2e2ee1c93f735ec475adf299fdcc46170473113b4c0a6c43f587db1d1e8b8291343a43d3460bdfbb4749000000000000000000000000000000000cfd85e1f117cbef0089e240ecdc62cbb15747c7d0cfb05291f9cbfd0c1612dacdf3e55fcfdce3cf9ef4db92669158f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdb53466b02008b2b0f84740f4c05d3762f273efe7ec8b2503fd364f319ad97a715ccd9e833dc29c71424b63bcba19c0000000000000000000000000000000019d167d29bde6e55c7e65ca47069514bf86ef3517a3180d033d64f37f7e9665f8a076d86248156a643f9ed1862775dd7000000000000000000000000000000000bc278eda03903d161032dcea257527869deba9e8add3978f9fe1461a17eee7474f58dab1cc13ef30cb2abaec1ac74020000000000000000000000000000000011a5f4af48bfef7e9132c98977f7754795ebd62a3e0433856d55881b9c6fe58f7cb84beaa1bdad79e54f9aae736e703e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc5eda907f8e7df718d783b80a80b626364d348abaa9fe827154eba6a4b854733d32204e051c9290ad6a83c6999d620000000000000000000000000000000000958c1040f210a636f72076dad2d10a305fc5fb908033e8fc7a958453ae0ba3c186d4a902bb91fd2592196ba6a8308150000000000000000000000000000000018e9a5b8687c334ab67d4c24b3b9e4e5fc3e3b65638e1c41f7888b582029ba4069864d1127c4008fd3f207e9f9a71da70000000000000000000000000000000013caaad600b4b9b65fc05d4ee4ff77158bbff844839a0979ef18f25e68356f9ceb68082f57fd5c7f0a2a5c70f5dc4e081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9e0e938b405ee2877255fc9eef70d264bd21d6ebbc7b4946260d7fbe81e67dd481eb0c16a2c439f07aa4ab6642be16000000000000000000000000000000000b62cfa4812df202efac51189f25ab9bc09c6d877b4a0774a94d830d44a5b133e66dd66c865eac32a444903c10c0a37500000000000000000000000000000000040ec42488043bba3c44c1f25bd002eeda76280b1c42027f0db57c23998634d3ae1963194a57afa3a3412bf6e99f9871000000000000000000000000000000001448596144db1930b323c1da7df385c14c8e24c46088dfa88450368a7bec9a1a9371dcb39e16f3c5b9c3c99ef72ff1a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfdb7c92ec77dce4902831a9b19ea91df6610c97cab6a62c46a2ddd61a5ec95d766162778991ed2b5bbf074a0b0002c0000000000000000000000000000000019123ca1b5e08967b9315b33e9fb34645994c2c2213f89ae36b48a7ab8eac567784e0269793171f6a70cefa4c549002b000000000000000000000000000000000ca81300f7ce8dad4928dcc837b06b74b427bca5ebe52fc97eadcfc122328e6b0f09a7c0ec66ec9b71c1516683b22f12000000000000000000000000000000001627511de7e9f2d2af38e0b5ca15e25aea87f1299846b875300d77346afd1ed1e47685ec08e375b22d3506b053a595071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078c6ab24ff115480c0f0e607831f85895f8aeb2100a1602d716d11a309063b7eab8b2f6a34e384deab016eb365bd884000000000000000000000000000000001139c2fd9caedd11470cfb671adf4c5914fb4880fc698c32bcb50ba8aca0e117ebf3c436c687493e1a03e178a0f555b200000000000000000000000000000000147bb6d621ef12c03b4aca79f93523a488c1eef9e82fd65dba1f5070af7bbfce9b52e8979e9bd6705142273e0e0aa26e0000000000000000000000000000000009114eccef8cfea317dbf8cf6bf7b09cc0b074f458b9dee490ee991d00aa9f4a688eadf64370815cddef502e032cf8e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003754b8f215266866c673796a51492615545c1578b7388b4c61e19f18ec6b9c9d2b4a8cd8f01be05d3b10413a463474100000000000000000000000000000000130c091f20eb463803705f5527f64b67b1abbab358bb3228bacaaa743b8db16a604bdb0a12771b0f9e3cc21938b8c91400000000000000000000000000000000080cbb4f9e69b77bf0e5777ad0e6add6c162e18d0699b27379b29aa9bf33af8aa3100349268a645d1f188401860676fb00000000000000000000000000000000162145aba6c09203b6f155ff61d434294dd90a2a2a2b5c6c3f594fef670b7f3553c0e122c46e1d03b0e6da477b460c221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118bd1f30ca638448536b76fd5521e486ce185b233a95623cec1bb546f228a229e51709cae32a71e791d0241e508ef14000000000000000000000000000000000bedfbd2a373aac9443a761a6f30d43426c0963c624f918f95fedb45b814044606e43436d1912731c28175605d8954ba00000000000000000000000000000000165f1d110cb5cfc51390f470d835120575f8f98931f9cd5fd3ea68a4e57017faca7c248d776d62e0bdacfca6b142d0c5000000000000000000000000000000001311fa6c7c6faaccbdaba38278d587e2dcd4119ce2b73001630f6b2331fd42e3c2d4ba8de3a44ed16f3b634634f04fcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bf1127e6d95a13fa636f9d40c5411d426e6408cd3b3727130075483f77688074493ebd1206f5591f2e2f604ec5fb670000000000000000000000000000000007e65289d44ff2e83dc806783599b88a6f8bc97c64036a65376ebd2d12129ae9cbac72928a5d5e9f98afb32d7c83b99a0000000000000000000000000000000009dfd75b2d0833cc5b5f8abbe7f45ac5db11a18964fa7699418daf2c169be391da7a3ec0eed882664e6682ea0bd3f7ad0000000000000000000000000000000007b25a92b227cf1f715b00f4dd533afd2baaa06dae0176bc4c7b5cd25a79ec648e65553a812d80849827190ddc678ea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001116cab8f8e33cbf79ae02ac214983a394355c9e7d9a0f296c5943f048667344449009804c7bfca870b9924eeffa5347000000000000000000000000000000000fdc3da06a6d3be5aed09e9463f4b56dd4401769b89e868f08b0d11a47bd9513fb7050c69660e6ff18723beb543f02e0000000000000000000000000000000001928afe0d892f8ec9e40172b56a4ce09aa49ef9b41c7f0ef4426ce9f8401d6d06e35664c926e873fc750bb69366e7e890000000000000000000000000000000014632d1304075974d90aca417ea48073898e607acf80a5b05c09767729f6601b81cdf2dc5c923d5790b58c181883f9c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f000f96e6752fb8e8865d621fabefbb8635099c4839d4af797db158b3a6a4ba0c8cc8edff5ec9fffc637a9180a522a0000000000000000000000000000000014a117e8595207889f4a7a786eddaad1a08420e8307434d4f4ee54294ce841bdb5d797479bfa981125274e999d75177b000000000000000000000000000000000f9c1af2906873337ecb6d0098498987eb6789c8962c141f8f7671cbfd56ba03a7de70d20d5fdd55cce4b8275e41a8a1000000000000000000000000000000000eafce8cc3fb77ef17fe45a5483fa76e141e9f8f56b8dc6b0656e4554562f4804790bef4ccf3a3e6be43dcd99816668a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6acd0b2bf66f847f37c1d8c7b83d7efcb7be52163650f6fe07e8f857344830786c6bb99b0115311e3a14171b085667000000000000000000000000000000000a65c3e4a1bade92daf9c8d3fac5c5fac6bfe3081454d16ec178c5d03480b54e29edd8412d4e066f58e09009823dab5a000000000000000000000000000000000d4ccbf3b6a1df77874153c0d6ac75b49ccc9f920297755089bdb6ef496e088409c4028db914b5ece11b4fb54667e489000000000000000000000000000000000626d116c34943527f77fefb43589d7fc2a0184b842eb768d923c811790058f1dc2044a8433f1462ad7c0e59ed6d228e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c425f567bab793982b10acb8289d49c5844db59ae63cd9931da260458c8d545d251b639d359177b2b393ea5839230b0000000000000000000000000000000019f2bdbaf499e5048d391b1a1e3a066d2967bb255cba8e7fe0ad51436ecc0e6b6b37541e6ea1f232574e9259d56e59c2000000000000000000000000000000000c93384e282737220f2cd98ae97ebe15b387e7b1ab9ef6cd1c2094bf0737f6680b84e3d45aed64caadb5b3b581e14295000000000000000000000000000000000eaf9ddb54105337f9a728e1d7fa210765fe2f2f1e0d5aa52ffa110137384a233ef859d1667b9a3aea4db87a97fd3e701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105b4374aa10db4d0c8b0157ac945fe219b98203025437ddca05d29060a351435c2f9ae5cf9e17071e7a43944b5e3526000000000000000000000000000000000ac410b47d70f567fd4fe1a65203e27fecbe49ba4357acbb9c4ecf50b80245b2e69cd0ed5906012d45c717c041f651f50000000000000000000000000000000003f3560b6e61b58d6f6109e6a152d248dba4e41b2477a794ba40d3ae1311e4f4662a2e3e6d7b9ac65e84921148e3e4520000000000000000000000000000000016b6dd9d69231df27217acf3eab8f2d3399e91a990be1561ab67187ccc2fc12107535e734d3050f6d9c2f22dad9b738d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b337f152f9c24eef68acccc9ae3c9caee085d5c5fe26723b0d9b8389ef71d6f75d391067a913212b30a83d8a484af100000000000000000000000000000000061d7ef5a0ee32c264a6cfb9239b6e1255c4d0afce6cc63f24ad9c2cdd800dba5f5b5aad602b7cafe4588504030341f60000000000000000000000000000000006062cc2b33a680bb1aac8f61d0ddc4639524733f42e50950fa04451afefe8c21c1aab2a2aa4b2244c4dd2968a9d349a0000000000000000000000000000000006da48fc92893d3f9a67cb132ace648027bb1e9e148b993a25347af62b4d1fb95eb233f7bd5c6f4131051b08df0efe361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3a9f342e6e9cc17498c680f5ee464eed2b63a922746fbf3dd8a5bebf049526706968acce68aa425aa763451ec3d5a60000000000000000000000000000000019d90a9f6f24ea34e5bc22e34aca3ea9c04ac66f004089cf48e36ace78309c60d8e60db9a9a2065508be992ae094e868000000000000000000000000000000000bd9ade5f9572c3c019b24439cbce753ad59731bb88ead40d85dd3e19c447e0cb9f1323037bbcea3c2b365cef48fbbfc000000000000000000000000000000000d1827e8c1da0f25ea8dd88d32e39e915309a090afae6e4008cade7b4d9e85fc11a78cc9326b45e17a4857158f1187e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3b8676004b4e51b8d5dae14a02842d7e03fb0f2afcad563299a67612b8d2c6a496b2b429db19d413df9cc0b5e750e40000000000000000000000000000000018d2e7213e234390a0dcb74bcc3d4bf39b05597cc3e2dc321dba601f989736a554999e288229e3128a4d304a32894d6b0000000000000000000000000000000019be5a5ac86a997888bb5f4624b6a9874d6296aca3101efea97193e472900119085069d293b5f92cb7b44c371dff850f0000000000000000000000000000000018fbfbad011fda2cb17615d99cd43143ba768f3388604df385b84ca2caaeac79a8d14c13326bf25af59a87799acc87ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158335feba235ae619cc60ce3ee8d12b0d96cff3a7c1006d38ebf079983f7765f8ecea1244f59ae4e5bdac376c9937c700000000000000000000000000000000080ed9a85756152ad208c793bdc975ebae27106ff680c584a6f598962129b88b6f403582619c0568f20c347c8f4e06b3000000000000000000000000000000000673378e8c9888932919bd70e24e62835242fa0f210a32719f252485b86e938da53bf114189d66d1cf7e5a01d49c30ad000000000000000000000000000000000e718e1b8c171357c5a60cdbc534b5531e3664db2b7e1952cde878c791fb6b0967d21ab6b4902a4e12fb8a8a28548b9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfba909ce9f84150415553b75c139a7fef75b160a0592f0afa720937c5f10285a8cf21a7eaed3783ffb3375b1fed6240000000000000000000000000000000010844b9e27d1bc8e107aa5fd12810b863aa9ee9bbd24d62bf73e2a231e3993c4ead08fe7724a58c89396b5dcf6da2d6e0000000000000000000000000000000008ed4c7ca4be96d8ccb392a4eb7ab61d1f0a717688b327513b34da93910d1630de5e7f2ec9b7301f9d87c4f4c9b4bad80000000000000000000000000000000001a3778ebeb6d8d896f8a72ac0f7d71fb60e442d3fa4e59339155c24ea81a06ab1c02ad348a05e5f0c6e950a6538110b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a1e4a2602b49e1bd8929699ae37f5d45bf1e9f5c154216161e53e253ae143c941eeaca47ec0eb56657c72d89fccea5000000000000000000000000000000000ee51efbb17ec2aca4b42042fdab789e595bb2c1fa3c39c67e1749c9c92e03c77e9266ad071891f2de1b69cabe2d28f00000000000000000000000000000000014324ee89d4c1cb1f128a4ded80a63ef271cde09bc1c1e9b1d4d4310efa599e7fe2d448e48533a245fdf04910e8bf1e3000000000000000000000000000000000e15739e76cc2567420de9739763f11efc2fa2cc1846718de7a8d89fc4c40af00999ebabdab65e66083642f1680c123a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dd0cf97101c5bb63ccb8f340af277de5e0584f3c3b4475591085cac7db1123ab254c01bc2e082e89b067201d2075b7000000000000000000000000000000000dbc679954d0c48fda994fc25d6d0a044cd98b944be043bf1752838b8e892de075fcd76fbdc8b83722b6e82050d762370000000000000000000000000000000011048a921d07939b7efdb0c57d452e5b0a6b7f0c4fa6c91147442fa4c1556a1fe5cbd15f234ae64d40c6cae2fb75c6cd00000000000000000000000000000000181db8a577109077b6da18d5d01f919330ab5287694467168d99ede2185033460f86016d96989e6ae5f32c3ff05a26b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ff50cccbf8abdced8ee12565eacd721b5834f037e8ace716670707cb82b045a0ca2729adb99f6c3615c164d50c35b3000000000000000000000000000000000f13075033ef2fc4c74de4ccd865998f6b9826f9f4aca52b84b429e21acf2a5c0f7b2c921ad3c66b9ca51ae8c39a66e6000000000000000000000000000000000317bd3ce1e743a827c12c8a89c6f7e654f4f7d2a92d16c3403145c1c02c89a5f3c8c558a4ce9edaac615fed0f39ecc3000000000000000000000000000000001606a62751f73cb6fa4645094994215ee0a85797bb033b24d9f1c2ba6f851f9e52d2c9b9faf6fdb1cb8dde0aae373c121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001910db38a815e2fa228ef6a21ae58ed9be9c39e041e2d14a4d1d7c8548e874de47d124b8d80cb366be8255f27bbcd4a6000000000000000000000000000000001357497d0ce360df0a4277970ebb0bce99c688f7ed08cbd7072aedf76b13926eaeedbe6c6ed7c4007b47d9010ce63303000000000000000000000000000000001072297bd7bed45ea6a616351462fd25b5f7b4d05b04809d1c169dde548f84cb67f74a243a3eb579ad84f32b485aa8b50000000000000000000000000000000013ac185bc16c65075d680000706d760650139e59933b9f5b88cfb2e54cd686b8dc9b80cc2f73311e966d8aef1856158a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ea6ea89e1d2fb8622a973966e7dd61ae6f561f881fd73c96eb5b877084305ebb969c54aaebe8c270e397083b3188c70000000000000000000000000000000014817b91533af60c29764c4e8f9afb55d61990f28d02c0817016006a2e4da28065b4c3d93ad9f8664ee644422cf7ec7e000000000000000000000000000000001096f1f31f64dcb84671ce9484e80d6114841958b66a068e7b905a0578a9e3d261203dcf62e8b097fbd27ebcf8279547000000000000000000000000000000000ffba6fadaa13335ce0ec0219e1dfa78877823bb226819a4783aac88bd3911ce3f09adc8ffee17e0291b99bceaf312cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075d33b8c71bcbfd368ad0b57e5d0deb7059ccd4ef60e82097dd6311e2d24dfd14f205a8867c77bf19df85d7e8534e6000000000000000000000000000000000041a3a6a3821996f58630fd442872e3aab26ee2525c4db82ed49894fe39bfdffddcbdd182836b027e0d7824c4df716940000000000000000000000000000000016d507a9b31ff41fbe3f77db15845b872de8fa205362f730ddbe07b1b7adbb2a30a2e3a26000f5895f0105718f5c941b0000000000000000000000000000000008434c0b05990d16e7fa6c90169c7aba6d668427d514b3b2846da2b17fd3df3b236754a78f52fc2aef041d7cb341bdf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001752888f3f4fc2091f260cf2b514e86e60a09b5e4b65d66dddc97b9ac6ae63306d5bdca12c6873be687203adf7afb8ad0000000000000000000000000000000013eaea9eba97b2f707622fae8cb46bb075420ec56152d2ad7b013d067d337ef8cbb65c5bc697a699228d204a1b4fee18000000000000000000000000000000001459d872af072da1b207bbd77a5499e661b68b8cac646aa8768e2b979d184e9e764eb05a0bfbee7866cb8fffb58bc9bb000000000000000000000000000000000708e3ad8f488e246876cc98449e1d8d71ee253777b52d700649866f1994c2fec1e022db240983688e273eb5d8ccb34a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014913800445be4b67dd7c4a5f01bd10b72b875429aa7b3b665dd4bfa7402336f0df6e81cfa555590677a4e6b7e3f12e30000000000000000000000000000000016e1b3ee069b5199b0acb75f3c41bbb4d3330f4d08c826c38a5f58966379a6cff0633ba6ad0cd63871fe1276c6298d0d0000000000000000000000000000000017540d56d9612b03aead601d4a7c6c0dec229ffb0145c1303c35798199ac61c05a84bcf8d52ccd364994def9c3b69db70000000000000000000000000000000006640ec7fd66f3059377b1e9f1b221256bf93bab6f2a32e6e3c8392b6aed4ea573de5260dcf10ff4ffdd968ae2a0cfe21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000099073083ed4ca646d5ddf9de0b74af4448bf7c7b1b50a185e630ce37a2725c599bb3cc2ba2bff3bfd86b950e5ff83d00000000000000000000000000000000168c9b647315cf0a4f037249d51d6db74eb89dedae9af2e092c4b3bef08b247e7175cf9b8be46ae69319d52a6608a396000000000000000000000000000000000ae5c29f68910065df260823ea082d6716f47d444a4833267628357320ee0dca4c074710deeebc2d14da127f4386f0c800000000000000000000000000000000189332205cf856c026294a63d0bffe8a033e4a342d165186c111da7b93f61495843863db43c561f04fa94404f12294d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015917c2199ee06fde98e0b2f752ad33824548956fa29d08c313f2ea76df5d7cd1ff87cadea3be11ba884c2b4532075a5000000000000000000000000000000001178446f24e704f70f7c0dc1906561f94eb3fe4d19300f8cba44085d90605d09c4f73363bc4f6b92e043b984641f965d00000000000000000000000000000000061a421fd2f833da0aacab23106fc4ef83f5a5cb69231ef4bcce0ac6ce6f0ee559630a0ac69602370aaf627bdd93a02c00000000000000000000000000000000150e2261b714a80df3a66c7c941b189cda47d1ab111248f0d9973ff09e6e7dfdfaa647cd9d2c46e3c712ebce1730775b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041fcb3ea259e62fd94740c2ecc7b89805345b9157be620a2b11b69a2dc9797a526ade8bf22b21ef483a36fc09e87a45000000000000000000000000000000000f79b2d6a07c8b481becfc673835cb0cab0561fc22efaa7d12f4f86f93628c2641af2ac83f77cb2575397a4ddbfc915c000000000000000000000000000000000fdb44a327084dbc0a0826533923e3b16b1e9c159059f011b3e453fe152fd4c6192b66dafe7e566c799fbe756325f993000000000000000000000000000000001218604085494539799f72acc0daa7fe29b565f80f4d589e17eb82fadb8d7ec2fbd32786aeefd44d066c2cd3b5cdf2f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cf0832fbc4c11dd9071a018eb79b17862abeadd210a45a4576518f8850af5307a6962b104d1d09a855c96d94fe0f5b00000000000000000000000000000000026b740f0f0f05e9b88e3a068c973b2df967da1a0a1adf44c434d4bc47ef30f560719b01317a589cd4ed56f04fda92d500000000000000000000000000000000037b0f64c4672215ee839188b3555884885d2bcc1d1a61032b17012ed8b5afd1cde33959f5c3e0fb21fad19fd76fb732000000000000000000000000000000000f43c031e67b97c09774799fc325735cc94cf2c45ed02185118c076a2f86a4b074ebab5563b02c130f9f757856774d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c899cb48482b18e3b5b0992382a26ca06c53b5342ce5a02fccc51d90f53589867869c7b8c1bcc71426bcfba6ac3fdf00000000000000000000000000000000014435908d66fecf9baf3274960c6d40d66ce30eb03084c75e17695fa127f335aec2620679c3adfacc7c30b80d9e2f6b30000000000000000000000000000000007ced172911f9c97296af3e37315d63da0a1cce84944a33e4a7330a185fe816aed14617ed185591dda3c003840ebfaa6000000000000000000000000000000000b86862d92115712d3116e8c78f0a225257f11eb7f14ef752e93f456e0dc79d2fa56aa3583b5271db0adf2ac0240b8861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ba616e789b84f95a39a65ebb3200f6fcc893734f568a9816b127a7392e441e6fa11850012feee8aa247327faf63e590000000000000000000000000000000010c040d69f55e636f82b58d0db13bb34db192ceccb2d6d2067e7c392688492c49116041ee074f1149f7d009a09e36aaf0000000000000000000000000000000019114d9094c833771cccdac6693d51c2c7c1b4aa88ff47cde479fe57651200f301b1920de7615f7cbf877606329fad3100000000000000000000000000000000164347ac00c50c8deb8a3ae98d27ecc5df2b304c8ed287efab6177973d139ea2bdd5c3fb19a6c14fa5c7bbb24e24f7651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c98e8dad75ca42e980705f690014ea2c9e65846cc9c3ee48fb43a23442ac88611a2db11401e1aa4666e0a3d6eb3315e0000000000000000000000000000000009ccf597d764d0721fd5275902ac3084384334554ff6eefec90c791baddc1eac9aad7d7b4b790b9986b0bfe98289175a000000000000000000000000000000001905f28719f1954996dd4c25941164891614e477332dba865857edc85a3c243c7e07d4c343b9fc5c7f7aa024a61ff115000000000000000000000000000000000023a0e9905e03833e0ed31c99e2fedbde47516f4611bdb3a696ce4b2c1890645c020365279edf8560ad5da75345fa811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d82eedad1d74f255fb7c9742078d4dcb51aef276cc6a59040dd71fed8c3513f50c73afcee25cddfb85cec36b4301c80000000000000000000000000000000009f8bb5e9626a113181dd00f014b132ca3b1a76d83c40fe65b2525392c92ed1024fd3ba0e80a5da317d20935519c556a0000000000000000000000000000000010fdf591ea23576378363d88ee2c1b77715d6a59e00afa2762f11b83f6e3181a5de387e4cd1448d5cfaff578a48807b8000000000000000000000000000000000f0589292eec654117f961ee5fea9e04e3fec4d503c93fc1da94813642a035adaf4a69ff7d01a031e6c0e84280803eb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000837420bf7eeabe7f8c4a2a05c37555fac408cd8efde02d3315526c482c592934bc426458084578ffc4037f79af312ef000000000000000000000000000000000fbae4c6ed4ffcb5c3d09109a95ded66a1276a787f919561db0e211bebcf4d6a68fde3a50b4d69bc54ebfaa4e823a3fd0000000000000000000000000000000013fa947ea81006533fc77de51bf6ad0e4314c9e96be064af08e5c0722b187a8368bf5901f491247f815c17f20f57cce0000000000000000000000000000000000c8b818cbe42774efbab957f11ac38c452f6087d661794b8562ddaf6f48ac8b57fdb65887e911fe1a501099fb50a89981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c6db3b2bccecef2a5812941fd3e898c7b5cc09d7d8e091d399616425f8bf1cf5125b76e3afe0f6f35222e74d3ed0d0000000000000000000000000000000000f784fa3f16c45245b9fad88fc02d4b296f00f28a1f800d7cdb5bf70a6b7751fabebe40dbf2e7acb7c423f6c7883fa560000000000000000000000000000000012f78d4b0d4f92d4d506fe670ac221efb2e88f244fa0eac46a16510d6402b53844575b77229e0a9563b901726c4911670000000000000000000000000000000009f9a6148d9f40fd71f97528b87a81140fb3e53f375a9f2c070e338f604c97c90acae7d346e627894219a18b378b55901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187aa84ddce0d93b6f60d64a4fb02badc2d470ff7d4ad87f30e3113e0967346eebf3791984c4c0e4267d96a17deccbed00000000000000000000000000000000001896b60aafcf0572d17d59d7fa0946ef6c9605b69c2c0df0718ad375327792b736c61b4fa62c4b7fb5e19182502b20000000000000000000000000000000001536a55c0834df904f2febdce0ad87701adf0ee6654087f43700ae3ce7c5753894c8c6bbe11221a4e7b2c6f9c8b121b5000000000000000000000000000000001961d1273aeec167d23e2308880a23fb32f1fea5eabc01d5a01ae6cadfb3191da1bfdd55c3fe9f442210454477209aef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024e40160806508f174c96aa1bd3b8f94c8c2a6d77e57543e9b9a921f76d273375a67a2d655d8f735ffbb7e46880096c000000000000000000000000000000000e7cee95448c9f02702310cb4a5f4ec39a8f9445b00709ce7538566e3da308c76ea601920d8d5bfaac9a4716794211c80000000000000000000000000000000005bdaf41c7ba736a454c8441c5fe08a73052f579c763d867a557e6f9dc07643bced8217c8aa9f14ea408c33135b2100c000000000000000000000000000000000ad7065571de6f6fc8d3bf4085954e5b9a7511f07df9ba6cf848921b0e785259fab379c92c2f88159d2ac29108605c3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001371695d1fa94486c347f8cdfef256e45a1ef0e02950cb0e3a0b6116d304774dfe81815134e6a47f448e93d77f872010000000000000000000000000000000017bb4224391e03813e2317bc794a0de456fde494f270d50df1bfd4779834417a50fcade50c40230f1c49f970b83cf2d00000000000000000000000000000000002b6a799280d902a3b0c388b6aee31dcd16ef9c1c8c5ca689a6e6b74e8567ebdfbb54f00ba69f624f5c80bd5336d1b8e0000000000000000000000000000000005030c6bd9e0d929e7e75624dde3079391bea3d6eafaf7dee07646332cd92d96a0ae6b2c2ab42b58a47e2579e66fc6271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097e13321d25d900703476cf779448540f1b13bbf4855cfb33fe273219b340d4593547f58bc80f764800a8cf053f7de2000000000000000000000000000000000cf9e9e527370480c464b96045e78c0426adce4b52a89ac9e455bad6f239b028fe0ae5aa8629c62b727874428013179e0000000000000000000000000000000014a313d0c6d8c7ee5e3b8ea2c3ce0c7ecba7dfb17a4900e268ee1d0629db4a6b36846217fd74fd6f5b77dcb198b54ae4000000000000000000000000000000000551edbcd2191b4dfb1847b0c47ef5455b60a367742c3681670317fcdca0228b30793cef3be39031865d011b25d929301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164c6ed712557b843f5a034fda2dcb67dba167e3ae0b4e07c2b7dd5528f69475d751ad2a75657831932d11a9b440775600000000000000000000000000000000060b222455819523f4d013533bb6d30929edaa6b24f7cdf1cfc598118f431786b06438d1ab1ec7c3874e895d81ea71e80000000000000000000000000000000007e6e99c324773855810cc1b269687933bc9215a2cbae14f217a433c731a562092b132b3a5d1941763ca05d08d8e2a3600000000000000000000000000000000159b45de2af00d9c014da15a9edc535dbbbfd6f916037a369e2d8e8ef4573014cba399f2253b31a5b418af85ad02a1f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010757b5220c22f43332a305d424d22fc36d27e0d1d22fdb88f4b06e63f7b4000b1207e1944283ecd20461df068e730070000000000000000000000000000000009fb363e408456f4bf8c48919dec4c2cd5483b175439294a91877a14feee2e22a657f435150f0875fd794765ae5a3a10000000000000000000000000000000001859b0db7aa0692a052803f2a484b7b92026d19cdb69d42a325983d67edd6604134e0706335bfe54ac7f1473dd16260c0000000000000000000000000000000010977a6d115607af211503888d2c61fad3d9c5e477309e5c392e124665bfcb1c564dfbc49ce51259d62efb8b40f7ec6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f9aca2b5fc5dbfc35b31bff6bd2970945995075df2ef5dbdf4c248c62856994cb4958a3e7a4f13c014809a61b2071200000000000000000000000000000000181c436480255c1dc070e0822eb1d57e78090e63229dfe4c651a56f84c76a5747696fd19b81af76201bf05621bb711160000000000000000000000000000000000b38229b8aef7cf55c2838fcec8c938e79b5912fc79a6551a925cb404aeed00c491d935e1414019fece1d30bbf82ef200000000000000000000000000000000111edd5e76c6c1be6ec8d1a679e53b74a5c093b5361c8cd1ceb3893c81e5ea3b23657d6b84689cf973b8784ea53958511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6c904d0785fe05a57945b23a50757a05a1c06b6a9dd4c8160bbe17b0c43cbe150abe51ca99cb996bbd1e777f0f6b0e00000000000000000000000000000000034a0bb9f53b6c827edaae4dda09166a9c68e0dc27503bb64638049719de46e9fde92d4f6a582a80f43659ce9d4aa30d000000000000000000000000000000000c7d3d5f43bb643ce937be3028c744d380741903d0eb2926c1daed222edab22365c55970542ed1afc65304766a901bfe000000000000000000000000000000000d5caa56d76c314fac3c624f84f6863f81455c16c47a5a272af4ff09524ff8a077c7d2d5d4b2a8d8d2c88b83582e545b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7a0d86713f61d447f7392d2c440de5b4448cc20d18ff649dac7e3dfff1880b424b0920034eb67404c5c41936e84c190000000000000000000000000000000000ae83d0b1dc1ff9c180abf0fff030ae57605d0c1d786f02e7346b885cfc2952e6de3db17d34c6ffad0ab8109ef532b90000000000000000000000000000000010756234b4fe401763fe4e76bc75d8235fcb043cb77d854246f2408272b3df5728f874a7eb9d6f2f2ad777ddc37c7dd20000000000000000000000000000000006d91067f71dfb7ef83a34724cc10b0ee7a2ced2d3720382e46091edf645d1ad167406ff8929a349f6cd06d7ddbda3ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014073e86b2990b9d220da0fc00d2ae6630a52a8f535de8aab971d0e521537c538ea461769ebc6393cf5f51630a3918280000000000000000000000000000000002259e9ee4fff4e24764c3177d75206de5b7179b90c7c5bdee4464264adf393fc7211c619ea0834406926da9b708beca000000000000000000000000000000000b4fb0bba50ee27380e2d5aec6c1d603f2665f5394b6518d051277703ea1c75bb786551b065cc962e60120e277536fd10000000000000000000000000000000005f6043b4cf155e86137d25664826f50077028c91fe350c5b47edf295b368677256c9e399ad4099877091ac1573b741f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff564af0ee4b31fd5ee56e33e63f75df0aa64a3861287d1e849c9af73433d0539157a1af2787552c37251e7d345d9920000000000000000000000000000000014b6709020de73555841ff3b01a454b23075542218d172518aac55b6bddc01ab63e65422cbb4d42430ff12f7fad6e41a00000000000000000000000000000000026b5b8a9bc22540f02eba500132917ed104f828b38cdd46854be42018689b0d52445ace9dc67806ff7b7f84635969c200000000000000000000000000000000083d370a1b82bb3a4f2149f27c59bad2f0cddb90ca28ccaad867e202b91bbb80cfb93b67202fe79c6879dd3cf3c3600c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5ee512c097d61df832be506a76b4bb7559a5cc580cd946abc03bd99e964bc675d938b03191c9f6254d013d8d2ac5f30000000000000000000000000000000009c0ff98ac1dbe590a8af1b5d094e86aa3a3a9f1e92988b93def87e9add14052c152e5057ee04f695191c4350076776200000000000000000000000000000000195b0b31a599638748725668fb3b6f117852482ad5462121a2c661cde5043db6979111b0ee46ae075d43acd2322d2d730000000000000000000000000000000019860f5df2d9fbb120150a85e0888c092b89269a00f992665c6809b7627b37d025c088c6be4febcfa1ec3baf4950b8ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108e144a5ee2554ee0a6e14f9be152914c17d063a0f1e1168796aa36ab0f64b43155314c2dea756a9e1899ea9a9bdc5b0000000000000000000000000000000007e75959cdfc19a6d23e6e4dda31f15375127cd5868b4a12a53bfb9f73f71ab9989fed6c80cb2efe9ea93fbe195845f400000000000000000000000000000000042df5c72b66683ccedbade75ea6548c12c51088cc804ea194096d7a4de4ceaa91c7a130976afab451b1a8d44962fb0800000000000000000000000000000000045c95178c37bb1b0ee9dab3522e67bcf5562ebfd115a82a9717ed1eacdef20da49ea87324fb75a2cb0c9493b11ea7f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7cd0d8de1c803d7332d0db23f03d950965483791b2386da9fa80637f4bd664ece71cceff95faabf5fc398c747921550000000000000000000000000000000012b6bf384758da9a1baf0ebbf43863d4d0fb3737ba5e2d27d73b41fcbd0d2ab9f655bae0df88d02574066c26ad9552860000000000000000000000000000000019435743f2abd08fde7e4497bbc1ad4c8aaf26f6978b0a60558bca2a48c279bee9d8ed00a8ebed4f61961beaa2c658ec0000000000000000000000000000000005b6e32abd2fb6d6ab084b750450e2c534e7d1def6a6ed36a3ec81d5f27e26c0e317d9514d368b1279438f102b8538fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ac65d65e59fed9da765ca3ed94e4d832757d961420ac80ebb969dc391da5b65a0e04f5aaf3611a439889599197f5ec000000000000000000000000000000001909ed1729926833cad2c38b42992c47e496761ed9e67cde8d328b3125a7bc7a2c6e046f63203e4354fd1c61e213f5cc000000000000000000000000000000000d0cf89e34ec73c96faf2f006923b963c1eeddaef92ac4e81b21b5bbab1ef77afecf93f423a5e350efeaebc2b0e059a400000000000000000000000000000000013abe7f3a20dbffe873260925c72a3b4745c2e673cf05f8ed59f06b560d0ad9d380e3950b880fa0de05f4a232f26a311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090769d359ac8ec162851f631651ade4bcccd8d116b1a49517511eb96571dbc50ef4034231aa49563bfc82d90a801017000000000000000000000000000000000c7093f63d9d73409c6332ea941cd8691436adbe222c62acb59402bc0ca6df0426205054cfe2c27a9e03e788e4231bda0000000000000000000000000000000019fe0998a0cf4deb1e1de4ed8806c9bfb9b746ec8ad365c2ee3511e72e4fd828d2ea431cd4d6dc1d5f89c655fe0ebd810000000000000000000000000000000019eb8bfeeddd31649711702f81b2a1384c3592baed2b404aa169ad594f96b69d80c83bc2b206684b359f36bae4e16bf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024122957e3dfec5ffb2637c1f8b6d912c983e3db7e3d7227bfeffcbcf0e013ae57e03a9293bc9fedb9b1ecd0b91975f0000000000000000000000000000000017a224ecfdc6f7e4e8e3bff0c81a2bfc15bd51181d875ba3c2f8cdce7fff2c1bdd388faa26c0a99b100804a8f705440d00000000000000000000000000000000036b03eb3d1c24a8c98c63abc081a3f948d95b6164d0625f7c7c0068b4c325c291cec9cb85ad30e3a2d1760e6c0897e20000000000000000000000000000000012602a21dec118b24acac7d9a3d4e1e7154712ca184c4b643b4c9cb3b04d9fd760ba0d3104d6467544f328c4c7b243a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a954856119589afe89aa3ff25a7529175fb112abea4d71d32da93dadf8b5a86e38c5816eabe729517bc37a07ade95a0000000000000000000000000000000003f7edc857c26edcb4ebf6f34feaa4013a67782f4edd76826cc0a91841403cac5772e7406a60033ac3ab66416906c14900000000000000000000000000000000063cf811071daa91ded9ee1dfe5bb2dbf94ea05f8ba819d44e3fb9fc7d56f413a9719bd075caebf12ed0df959809eca300000000000000000000000000000000070a3c9a9aa79edfbfc2e18e08b6f527c1fd23a4664ce8d976ab5787cb7a4b8e8fef6dd6b19ff7b175e069b23be940731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6f1d991ab6ba65d097d58cb736c592efe7d4f9365ebcd66a37c1c9ad1155eab03576e4da2e42ada5d7d7d8e9be29d70000000000000000000000000000000012d654dcaef0afca1fb609daf1f1bb165aae11f97e59c88765021eb2bfe885c9ee00a52ddde4e5073c5bfeb30d0d1aa00000000000000000000000000000000000ea7c891cd5e51618eb2ab7b773a4a787c2a1678f57c20de0517815d7fb70e974d6c9e6fcc05f3f575fdc3d46e3f47000000000000000000000000000000000048d02d1d0a405a947b14f6425cc781cdd6eafbc9a569ce15dcf9ccc42137834fd6bbb2ad65ecf8db1482a48c64dec591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bab387e78f9394f4df650a9816731be88d7b1ed9f1d106055a0387966b99e58143d0f520c04e2721664030490661ed0000000000000000000000000000000010bb3075c1c08443008d3142587146566012550832aa6ed4e41dfcc75eb7f363719485c2d088483e5267873c25c5fe0e000000000000000000000000000000001669bc2ae7e7294195795f3e47a675c39778e6a61d839307d7290d976e171cbcbbb02f66e6d7ed3a94581197e9edb2530000000000000000000000000000000016c2d8416e21478335ef5e7230189d1f930077690585ccd642d6925c88fdcc839240ef7f7474625925be1bf2b17bae741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191f14203b564fd6c2c4cb768be0197c8a11bd21ecf7948458bcbe31e89ec153d0655778ced8ed6906a17c83b8c6ae920000000000000000000000000000000003023b0d5cd394bb62d9c4f343ed1a73924269f14c71b52b81b5d4e775cdeae618635ab47b4d548909c2623c427daac300000000000000000000000000000000146d979c06e1347280698d81bf0bbfdd821b2e617c61bfb8bff72ce8d45188ac3adbb9425a28f182721961dba5dcfa5e0000000000000000000000000000000013983340442ea5a707aca6139df906c316d230bcb0ecbe97f63e5e078c480f31e49a730ce12c734c353e1868037570b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040c0b02a46f3dfc6cb7e2db63c369ae521c90aedb00b2c0b1146bb9481e4fbb2f80f59b81e392e4d66f2ea6ef34cee10000000000000000000000000000000011eaa51d7e042300d9768c26b00ed8eef5222004cc05a2bf71ef1c510da00cfc9532947ca807d3c568c8dc4e1f2fdab8000000000000000000000000000000001559a0a4a4050f6d7123804ea775b0c5683e39da0823fe5ebbf771760ff5a8a08a01003ba72b91df44365483456b3b2e0000000000000000000000000000000009067766261610cbf5dfd5c8141d12c4597edacd797146120c2d605944c6a58757d19ce96881faf14211a6f9db1914f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161c1d18b8ba8fed10863e5f7489bbe5ba86d64e357427075d3336d7d26c604b60bd68cf38cb6fff8b5a85241fa35cab0000000000000000000000000000000019816e5c0b26df636cb97407ed8855e9ac04976dc4e6cd7b380dc2ee499c80183723bcb7144126e907f051750bc6ad610000000000000000000000000000000001cc0b57708112486a7438b0c2b0a2cdfe18a7a200b6967ca7b8d6766a8a7519e6f6a7dd26fb5ff8734caa0e52f0b562000000000000000000000000000000000c0bb26032c50e4582e7cb631b54afbadd4dbd288f144e29fd67706c60e55d0c8011cc43bf40e2c329eef7dda582e97c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df2353ad63b41264e649dfd712e45b2e9ed7890f28fd50b355159ce067bb34256312ad788a1c579caa5ee0c331e2fb6000000000000000000000000000000000d9bb27d5a8e79b60eefb8625c809e2bf767e68b18ddbc439d2ff0e9fd888ec55d055731b3c30dbb71af2e8188797ca0000000000000000000000000000000000fe65849378b854ff69abf4e1a217f3bf1ac4095ae7572fd773de822aef7ddcfd0b249ab5dc34c627489544863ff17bd00000000000000000000000000000000173274fec7bc9abc6adac1620d27600cd361d8bec1c50e0f81f5faab221c23c8e2047c88dc52dc845cbcf0e7557069e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c43e67f5134e9b73b8c2d2f44f0d8e66b561f5e49c670d3966dffbbcfd3471258bc931fc441bfbcf8743718a2d97a500000000000000000000000000000000013c83909e34a332d40b84310d664b7d1000f5b67c352bb552403ec7e6791ed20e3b2e627acd5d43462b2a5e8c4756cc9000000000000000000000000000000000b7e7b1b9bc484d5117b93a5b9a6c6a4a3714ea54a220e0e38f31f8aaf97ef6738118cf1f8de76f070db27d56c0be9910000000000000000000000000000000005f13ecdaeb40cd6b71a5e0f5605b5c10dacb000165c038fd48241b4d85fbe3b880960eb3c6d239f3f8712e26ef509ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fbe237bf204bc7b36abb0243af064820bd9505d80e31a1f7beb74c82bd76295895e055d13676d6e432b18af81882f000000000000000000000000000000000136b3701676b909c50ed5f757a863806bda73e64aa78cc1c5b5cfd8a6f4897bf3228237e18d325039e5ae0d30fedc246000000000000000000000000000000000903aa04553b4c71208927331e98e6c42110da7c86f05bc85dda6f9a3e0f6f207f2ab94069f401d1e072fc05fe00c12f0000000000000000000000000000000005a0fefeb20466a76d325f04faa24f5734d8fa557cc9a74ddaca1f283ecdf88c6c018cbc01f9f2feef5da71db1bd9a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffc6f3ad6373b90bf4aec29056caafc0486a3e87c1eede2552fc266c43b7b29412145644d1e87f3a202e9496db4837b0000000000000000000000000000000007a94ada61c0cbb8921ac9e38fd66d3200f798295432a39a9474b40f3cc2d0f24957aae89e5433d714614747f1f5b5e000000000000000000000000000000000020f55981f6d148029279d24577332849ee60e7e9457723bec470c6ba69cce4d2ddef9781063855160ce32e794ec14cc000000000000000000000000000000001831243f125e9270100483f8766727c34e01e52323026be9fba9d85799297eebebffe18c33b89547ec944260c99430851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a585dc65e48c8890c74f000f7990a5a5ab89d849296b679ce71898b1f1e6f97392d152d430cd4ae5fb7daee7d07d3400000000000000000000000000000000177d94b2d9266cfa324069cbb4c341f08cf027346c8b8249d207509e39071e04ce8d70aa7880a1ae0fed509f8c3feac200000000000000000000000000000000112e81570b8f39024fe459b67f847d7122b3ce28f22b2aab80b1fb4473bcbd074d8e12e287faefa4c8728430c6139ab40000000000000000000000000000000005e6b5dec7d1decdc42c14b91e6a4d468121b8f111a7b2072bcb34a8b13b4734593520831fafaf4ce6178d3d80ce3f9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006138f76ed8eed9de440fd118ede46edb66c6a616c0a1640f71119e2ec99be693b1a5cfd70ec07282f76df25b8af2560000000000000000000000000000000016735a7a58c2c38226a096b65fd6aa9a508c3d4add600de29666fd64c68009b46498058596568d326ab73b33507a5bec0000000000000000000000000000000014885fb4689476067b26e56f8cc60d4797648a675ed88b15ae50c366bc85fae9403b54ceaecea525d6e8bd249b1e1ecd0000000000000000000000000000000010c798c1624623c561c251dfadcba65f01d7f4ca9da34ff6ee057c0a59d5f12f2534f668a905af62fb6516cae46fb9b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000306e2bdc27b78d82da73694d88126809a99ad3059aaca44d0e721bb9abf44f571adf67323209d10ba47c3e4c76568e200000000000000000000000000000000117ee1240b7720274811689acc4487d951b7ad69fffca8e0b6c026e0be18937b37773d9d6c0275353c73a0e3a28d1dd5000000000000000000000000000000000fa6c0eab5b15c5e3a8e1c3daee2a67005e4f22420a306ce458d5afceef5ab6825172a94e3988cacf3e18beea0a700ac00000000000000000000000000000000028373079f51e476c556e4a50be844d8e41db6fd059ac2614f339c239472bdb1aeafed47b931a4f672322893e2dd285a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c9170baf2c611d94ad265d0f9cb57af0bf2b72d0cecec91b43b229ad5c1c6b7aa6219e4abe44d89896225457a8e915000000000000000000000000000000001827a249ab25b2f317f6cfdfe90c8b8c444ac0b32b0c4dad70841d54ae8ad055f890b1e4716b089b0325617cb42ec9380000000000000000000000000000000013e96db93c926e93601656fc2d63ffa7bcfb697a0e83f12a60c7bff997ef7696bbdd1ce2de65c7966824163fed96a5950000000000000000000000000000000000c758dca53d785b8b3310816b1e252ee9ab334946197fa9544878c18372b257ee61eac1ae75836079c65cf33622d0a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffda2ff763dad43d0d7a56c612d810e50db6e8648a0672b1680bb396a0709d8bd1c980a999961eb9dfd0a0f814f231500000000000000000000000000000000157abae6416c66f3020959c42a71b4d5ad76fbc9999413aca517973db9ad7ab7ac6e954949610129653a8e74a6d348860000000000000000000000000000000014b11367f18e78867d1f3ae681dbed58e350c4ba6c9be075ab34a2b1749e4f650d84abcd99ad2f33c9b408c501d7637d000000000000000000000000000000001588eaf9445226a36459378d3423c3aac666d5a8c0a3ea732bfbc5d6661cd39cc486389fdef7a46745f0a8acbccd29771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d1139d1df3c85e4da6c15b9464749c49c6d3baa2c8fa1b610353ad262880ef7221d703d11212575c61e6376593c4860000000000000000000000000000000010099ebe6d81554c4889028b01cf5b986be147d69ae94b2ce1fc12684b17b4a82e1adc696633b3f9b11d49e294032db700000000000000000000000000000000196ca0167a571cf4eb744dfc1a39ddb4194c074d669bc55f82b20f76dab6b21619ad7ad2612ed48420478561e62dd9cf0000000000000000000000000000000005ba778dd30fd54413d74efd987530536e126595494a2b377a3d3b1d47be7e967a7d7273602b3033e7b697d6cfca5ed11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017eca5aba857534fef740e91fe61adf26da89768eb974cb3ecdb66e21216b99a72c41c88477a9f00c4c9d19468b510c6000000000000000000000000000000000df5272ad64e8602f0b7d03e3dbe34fc16d3c078adaf2e089d6ae3d11ae02e9af2785a0bb11ddb2f40caf99119fde8460000000000000000000000000000000018d6a774d0955a764abfe80c5abcde4c12e72dd4046b01f475175092cabb791661956404d22cebc272e354bf5b3133f50000000000000000000000000000000009d0c610edf48d449e762bcff5b487b7cadf177bd7619ce96bdc92b4843531f141c864f8511a7510334aaa4975b3876a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091fcd8c9edefd53787331797963f9dbf39df879ac418c8825fcb3425c74009c3d6292d8e068688b3049cf05bbd0429f0000000000000000000000000000000012993a4aaccc2e1dcb7c33b94cb7b0d08fa333913004c6245497b763e4576042488bafad29d5911b2168d730a1fbf62200000000000000000000000000000000103dcea329675155e89d772c253cf04a660881e7fabecb4c226d4c8b912998712b43323b015846ef92f1c9b120915ec900000000000000000000000000000000038e53a9413150b7c8a1a118f2714ce045fac51945e9f216c9c3fb0cba914f67b3d3db9f2899277f8203874b6c7a83f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a1847c3ad9130d159e48a89c596eb4b39eb6e5bb64ab89970787793577d25002765210cf5db255a7e24853722529e200000000000000000000000000000000121473b53137efb57317e89ae08961c9752c5ea98d29b90aa1fb6dcbf8cf9f2a10510f049fb9318b0580432521c4db55000000000000000000000000000000001293e7ac15e5447bd1a15139bd43325cec7b1cb7d97dbbc1ad00f2c8a201222bbcbb097047183b8b83491ebfacad68be0000000000000000000000000000000004a6c289207b3ababcf55457da0cdb78a3bdf83aa194ac3c2b37ea924d3c5e9da9bd2bce096c066c8e5df253dbfa66aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119e4eb01df72bd9ba964dac23b475c2fce5da9be34d50d69afaf835965c46584bde125a674c884db58e21ee724d5a61000000000000000000000000000000001081282f9d052e2459f6e63b85d8adb7cd78dd56971ce2140a6edf29e53a89d7f311fa0308ef3329ffba4f8d8d660465000000000000000000000000000000000e96c5011858843f1e0e16f43ba8df284145e7bc4cf287d87ce2a101288ce9aa0b24fa90836f78ba0b33ef0c3f81f3de00000000000000000000000000000000101df9af40b7db25ed888951fae3e75b967a29489b2071a3225da848d19751532f9d068e7c6034e19c2dbb43f305c01d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbb8519acb4a38bcdf5667b2a8545f10ff88c04b7843a54526d2c78e1a777720e2f1d24327ab44e9264e0a441c949810000000000000000000000000000000010615254777726ab4588cd91e44f746004a2f6b211a2d8e72fec677c9ff03de201f4dd5ba6402414e8ea13da35e3eb3700000000000000000000000000000000183ddd54c5bf1f9fbd06de49931072c37b8521083d92282cde36ac25d6cfb56061c1fd8b4dd05e97a6b35afada12d07200000000000000000000000000000000093e32f236faba44159b1c33d2437aa2d2da3c67a8126ba86a41c3f4a4a7bd2de24c0bc58fc19e93c1cd415a37b183971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073af6337d2247ba5bd0c6c033110528f083b9ab67665712e6cc7a0308d311a7d8435dace8f9f64557ad0f1a0601acc40000000000000000000000000000000018cf2e780cbf7eeb0ffd2f170b49c169aa6e3d784ece12f7e4ea731e60cabae068d6893f0c6391b8aef5493af10694ba0000000000000000000000000000000008d073cee74a9803ad78e5c1281d2961ea287bc0eb93656b381cbc2d317c57b066723163f583b462916bc3f49b5205c10000000000000000000000000000000012e721203cc6cee14bb4f677874ef7714e69368d7d273ab6e2bd77b62a805435cd869a50cbc864a0d7c6cd649b3f57e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051d488c9770ad6b8dd0bb618b02526fc3c54c7950111582ec2a5fd45ff825a2e2bb2004917a9a98f0200d52c055c8e000000000000000000000000000000000031b4322972391645aa129057a49ae7dd4bbfcc8f6034585cad806f0c14e86f4e566bea1fe20400060d85e34b06e23ea000000000000000000000000000000000b2ff770ce1bf9f84301ad2b3b2487a75950dbec3116ac939baac7e83b7d257e6f99979f9395f9d06cc15c2660f7495700000000000000000000000000000000087cc81fb51c6bb7eacdc31d05cc19e451d6370c25476572976f4192f49df127988077beb820d0e536e5a4cb28e6b7fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d20b5d1510263aedc8d286950c1c5886ef59a9a233748e6e4359eae5f41ce28045e95ac882dee7148b9f6c54416a7500000000000000000000000000000000146b8954bbdad63bfab0d53c260bdacda1750e1165c10b957c01362888b7b3ddf490a7c086e0b0041fcc7c4271c34c04000000000000000000000000000000000f6d3981b0d25e8a106a29ddec0fec8af95fd20392646a6326717f2270cbafc6abea36650c00b505702ca0d4118ca9c200000000000000000000000000000000038ac3666a19d681b6cb298b778fdbd1f154a80cfc41c9dae6d050359f9840b6ae5f55eb3d3a0fa4b1df7777c681eeb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000165bf6b5a388332f425d6e369f4467f22cdb8c5bd42cb9f91d8cd09993d52289d4e2c1530dfacf3a822a498075d6210000000000000000000000000000000010f6a9119279a8f52fca8e0ae1f609ffd558b70be135d6c3e27bfc9d9e3ecdaa288980f5a1bbf7a85127198d19e4fc290000000000000000000000000000000004fadff49f07d0d332570c52370aac3e9e64d8571ef08eb2e9df777f7093bc0379c704b104beb67e57771c8ead87366c0000000000000000000000000000000008de32229e26f148933b206ff617d7b6a2a89902a0c8b5e00a352b0e75900b5152857632c00fc88061e781c875fad3271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015e8adb0e995d561e3cb84c681ccec3448dbc81bb52baecbf2ec70d92fa2a5af733e4272bf566fb283046716343c9c60000000000000000000000000000000018ac8b7be2ff56ac34852a8dca5b7dd93c75ac710277b95b846f1e1be05ab2af44579d55acf56cf84196adc88cbe7ade0000000000000000000000000000000004102fb6d360f719293136e5a1ed7afcd2a95f5faf52a6b5ca74230f0127c7bd70b6694ee2c3de2d51b2ac89a3880a67000000000000000000000000000000001097a9a5ed0789a9eebae5f1e06a638cda6e5441bdfe31821f55b6d3279b618bef3beafe44d8f72f5e448a63000eff501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171d8df72e533f4489229b78253278d10c3838ac864270613fe7c02d2b48414ac4563392f465b3e20538fbc720dab749000000000000000000000000000000000d814b590d96568cca4c86f251024207a07953a0bb00e63f2498db22223419c2e027bea597981b8630463d2883c662da00000000000000000000000000000000035a58e3b8a9ad602e9d3c20773a2465841580fb59c486cca7b8fa1385685ac240eab9334742d5ea018ad03feea49d13000000000000000000000000000000000108396dcb7acc3cb44cd090bae59ca9ab3577951fe6bb2cf5d24a4dd3520b956f237a95b8f1885240160c147d3f1da41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019115d734ca7c4dddd9341144098b1f3b76e2018e24e0fd29384b8a43ce973f8514b8eded63284d32d6575bf7778650900000000000000000000000000000000098f6ad035f4a15e4beedcf7531a44f789fb3141f32a2c610b352153132e5fced6e1661d02ccbe0e3748778f944097630000000000000000000000000000000001f691e8fc5c50217de6d5458a500ee5930bdc2c1430462cdfda3a63ef5f0a576c4c141f15dbaa475eebebc76f800ba9000000000000000000000000000000000eb1a3b3bb50b7f00fb7d272816f885e63952e6281556d19c18ae3dda12f894821e286da45a811a3714c90a94832d3831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076cd4e0524f1bae32c15f3f626787a0d1d17b844fde15667f9e9426364716ad52ce75d537f472f777bd6e4fb91473c1000000000000000000000000000000000f9f2036039135539feadf46dea0d4fdd9fe6b0a5405eb1123c10be2688fec9381380995f54521c2ab2a4357eda5bac9000000000000000000000000000000000ec011f3c1f012fc2598411a4dcfac4cb2c71722abba66dfa43686e3ec2bf31b2b64d66e909d4b0573d1122ed00a5d0e0000000000000000000000000000000016f863a9b2af372f6656735cf6c18215ce0fecbd6c6c044334eec5e9ac3c4b6c84c307aa7a8fcd25849bae01f6a312251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093d6b0da998bd9abdddb6d835b3942f09015c7d97349ed7b8368b20d806480021d368d553102942504032cfeec1334600000000000000000000000000000000094353b724ac4a83c91c6842541443171654b4a00a89736ef292bf61aa9d23ae4a0753b7486dc2061fe8237509181a990000000000000000000000000000000017d247da746446a7a8f7ae41c73a48c8b7ca1b50549e1e0ab28cfc35e8926eef3b22e6b2d060fea3d62599dd5e8db936000000000000000000000000000000000e257160db309af9045ed985d182c04a6b0720d12c5b030e32fe35ad25be516b64f439739a076af13b6e9332af1945fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058a251a92d10727fe08d3f04f2a5b036d77211b4a1c5782e7079d2741906a1d571b8acf83bc050396cf624c46a3735b000000000000000000000000000000000ca7354527093bd3eadafefd6ca855a07f6570eea4f11042db844bb172dd396c9ae47872177ce43694dcbabfb68520cb0000000000000000000000000000000014d4de2b61099557e8897588bdf3dc34f4e7db6729011af9ef8e2d0ad946d6b66d4d080d9ebd10ba950ca00c26acadfd0000000000000000000000000000000015540eb28e1d79bb61f3e037ca3249fe2ecc45f246dbc8b1c2d38d45dc16e56484ba5d61433a4e70bf9f094ad831add21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001562744906fbfb51bbbb06446ea91a5702ceb42f67d6956d640495b9764b1d7f780767a31e2f8273f41b62e0c2eb246d00000000000000000000000000000000130e51539984f815e52b2b344d7e1b20fc86803937e0a6d564fcbce7f978bce04dbb6576036fa0c5096356957c1873b90000000000000000000000000000000016b67dc7c4cf8c2f63a087f17fb5dda391bc93847f9a4b4aa9adb39e094e4d7508fda96c4bf3ee91498beaab69ec2d39000000000000000000000000000000000aaef46d58e246c8c8d71fec279b73cfdeb5d6753b5cd1c05c04f2354e351d4571ff30f2ca4df80a8533c0b03594e4af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178b8e030c7dcfaecd654cb0302e3d194ffcaa714d76751c508472e745486fb7566d36f076c46be306a2e77a1769eb92000000000000000000000000000000000d0714bac7744a570928a237282d00cc0c837eb4d0687c404ae594ec6be94ed3bf998411bc5580da703078959b021bf60000000000000000000000000000000011c1ae0fd2ab07edc84ef4c847cbcf3f3b22224d7c52db891aa3744838da1c71c89763eed650a1b665568d455378025b00000000000000000000000000000000140ec30b8b229ee2d91f8556c3072cc43b2c24af80e1876070d2de0c8b82b89981c272f3ef0032c7c094a2f2251e4c031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d6fd8bef026009a7ec04ab092cf47ede0d1d522ad3c33da521c99247cc8f4489400b456c13febe5ecad23ecbadd2560000000000000000000000000000000017eb8401e5c78543ddcfc1c5f96dd07ade0e24bedb1001c18064eda866cc7f4e157dc1e85050e83b31f08243d1a6793b00000000000000000000000000000000148317a22edb80770bde7f651af49c4700d2f907a1f49c884c2744e50da893b92c0bd76c101f93ed7d2adc5eb13cebf80000000000000000000000000000000006a7725c10c82b4acd6238e7c155a80daff66dfc60258b93cebbb9e2bf14362d324f5d08b4c822c483f3e91c9b9426931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7bf2f2a2436984b7bd2a85fe840bdfa6a3e48456e2dc1814ad13fdf77d487904ec9b666b16d945cfdb8bc54060a6a00000000000000000000000000000000010cf79538515f7392124e939ac9deda43c379cfb8e74f06723fafc8ad69ec97753a9a2453f0abef688a1cf5e507f504d000000000000000000000000000000000916fa40306bbce7e1cfcbd7ede9cd1ad5a7b158adb351424195e7757ae7d732d3f5a728eaf7b1991db45d88e07879f0000000000000000000000000000000000b4e6707e73e7ffdb2a2e61f7811b4bef34935705c872859c30d14f52f8cbc63e2e269283a8d1583c1db132a1d726d831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000663e52411ce13fb94dae915d8da80df35c247a9a444326a82c2d8632ef5e8fe926b2b900a8c7b897d597a6fedcb5a6e00000000000000000000000000000000122349aa9a90337b2eb05257840145e05f5e51f63bbdd77339df6363f214978f5d947a70756da7eecf96899a4cebaacb00000000000000000000000000000000186fd30e62f6e9f799a501c19123580fd447d8243553fe6228ab9b1571cf3b9f07268d1918f4f06524d33813f53db58c0000000000000000000000000000000017a6bbe105ad54882151e15659c0207f5b8442213bc36621ca05ee03e1ef422f133ce59c1221d6aabd01f25b1ec1adb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f4b4baa96bbbe725c195b37da2c0e2ceeb1095c89068028b7b515db98c83b44e986132f4a0ab9735e28f008bf9ed84000000000000000000000000000000001161e9d28fff8f7263875cfce715c509b13d880963dc53bac2329510f54d99323f171f66e04b79b93504dd11df1c52d200000000000000000000000000000000136d09931b17a6f822eb4fe0b2b535c1718ef3011d58813f87e50725fea40825feab1f1597aed5a24f9de143271ee0040000000000000000000000000000000003027df0aa589a673dcc9343163c2110dce0e4a10ac81684bc0bc97fc6ef0256e3393de90ac05ddc3c8eeda5926a54d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a01637bf194eda5074f195bd8122c80ff04748dd98f3da2b13f893b3c8678be1033e4b7a6d17de73087dc1a4a4209c000000000000000000000000000000000c64d41fd1f5259b2f4b33f6beedc942e2851dd2f6addd01fb7dede00bbb374e73d1beaad2ba7d60f888a4433b75b06d00000000000000000000000000000000110d9b36155548e41ca1a74d3b3688993550162a853f4ab9da5dacce3f221ee736ac7de41864d343990e89d2b0a665fc000000000000000000000000000000000ab4ff8d6e2ab2972349f5631a7a09b5516e766120203a5ff8329909a883c4e0a3561920a09250ac285b7b845e0392641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afa549faa30429e622335ed6b494f29e97e7bed0ecc4f80a03ed29e93740bb26f0f8d00b0d3a93e3698edb40fa11f78000000000000000000000000000000001025fc76d9318b2c9eff1371576ed6d5775dd762b3371b333250357a1186765c487708745a34e60a5c50920fb7c2a29e0000000000000000000000000000000007a220e67a8a4de1f22ac98eb646e115479a1c700befa3d70c4c33f5e2f770e5b457f59b3ed3134c98feb657e2d5bc900000000000000000000000000000000008c9ec26cc10365f6c276f01565a9210c85ced2b96adb368d964b0ac93f248f097e550cb2d48bc4d04105a677ddee6c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028aa73b70cc17b918ec5ccd0f29e2b417a34ab0db8e04522dd39e35a8be0aea3096192f0b81b60bebfce1d22f61b07a00000000000000000000000000000000081ef1737585f73f925eb0d0eb9c3dc03ae3e8c52f0f4069c96298eb747bae9454730b09edfede801368e32a4b59797e000000000000000000000000000000000148cbe1799cac79fe94abfd10e7882109ad82e7dd69925d609fac5f0c5cf61f0cf5de9bc9197d6b0fab77806938f6e3000000000000000000000000000000000e51a233c6065c6af57f613f10428ab17403e6dca59d96299e1e42fcf3fe86af62892b0299fb5cce06de93e3edb71a3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a8ed4ca0e944857a56aaa3d839e8b5548d6e626e8ad05c5813667af05ed776b7cd23095cd9f9621b9eb6c6baa8baca00000000000000000000000000000000176f456b9b28315c3a1a26d1fcf6e863ac33fdf55ef63f38d47f330b5c5ddf879c487b07f603c98ae3bd4823eba6408e00000000000000000000000000000000161da34fd9d8f29c356c70572cb9f90ec9d6a236f18c0464bb8d20e996112dede08ebc1f76c006c5a194386d6ef4430d000000000000000000000000000000001279e0305e842f0b34bb882b7fdf41988852ffbace2d48619fe0173f8819cb6fd27d5c2327d23a14397123750818267a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e970df2b1a6c9e6baf82f1c99c09f2b09e452e08ce528a900354f4d0854777baec0dae344b5f6edcf41cf33e8d8a20000000000000000000000000000000000c36466964f5e4e4d2f307d0df33805067858eb4e6d4a28c12e48a225ed40271706a57168c00e25309b1699861f31eab000000000000000000000000000000001727d33b75915553668558c92fd9f52c40091c59a17276cfe8ef32fb9c93e261443eef70a7dcbed62813be55ac5df63d0000000000000000000000000000000012df9358dab9da9e847c89455b1042fa94c9a9010c178baeb4dd8cb790be25741e450a73ef40977bb1c0e6b0565be3db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1a7dc8e09f30c7daf552b910b1e6d9dce8c3aab0afd7fc8391776a42923ac23653656e1e6d28c42e31fa6cf16adfd7000000000000000000000000000000000819c3d53327d5e970fc63101edc0045eaa61061e30405070d7f9b474e530236718c96d65b170409345571684891ede000000000000000000000000000000000038dbb62f57eac2de66bbfa072dbcc6f0e6be3beba8a3ac0dceb4c51df86241689baf2eb79621741a50905616c45fa410000000000000000000000000000000005fd424cb23c095c9a6cb35730a33887a8eba7f8b701e422e5c88b617a48338131eda7914cec891bee983db8afe6aa5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071e06ed9d7ad3de3feed90cdd56850c0d316d78e25676f7510444b562a38dd2bd3c87f2b44ed1678901bc5385547928000000000000000000000000000000001682a9a59ab618bec193babbb69434562aa1f2bef691bb69acc2231f2f6e001489504ae6af76872da7df4b47c53e0217000000000000000000000000000000000b46205181a4f65266298631f1bbb8a520c783cd3597c019fa44668fe51ac3fc06a16810e4899bdfe801fa91535378c2000000000000000000000000000000000cea5aaa93ee5feb0af9b29af0e8015b8fd5cd13f45f4f1e740a521c3d90f5aa8619b2ac517f8b3b2a8f16062c33b23c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f9515b3aaaec44d5798a40e1fd7faa87cf5bee610c77918a8bb224cd5a064452d486da6a9c3b4b1a0f18fd4786bb91000000000000000000000000000000001696098bd18e1ae35068af30b352d9e31f610b7136faf976044c8d576b5a4a348a173a484e0a28234fe8010a4cdc55a900000000000000000000000000000000053c8678348b795eb0e9635aaa3b9e0f5ec2801c3f9d749fc26f225a3e6fac8b9794bdb44a8de2904b78cb20ee26ab2f000000000000000000000000000000000f222aa7cd6e197af805153876666a9d959139b7f22537873bbeac9b012fa9a832f7e3e70a7b2834d3fd1643c4b2a52e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000140da99410845d47701dbe9ce0e2451afb065a7a37c3615e954e21fb920dd7475f5e492ff850b71d91cf95b78e33bb40000000000000000000000000000000017851b713293f5f5fa4b97bcce3a28eb362f72582392bd90b1dea69623154a2f9907f93e895c579f3fb0e9f680c923360000000000000000000000000000000006b2c5837ae2c4f257ace740d2bac569c9d269b0118fef54ff02d2137dc770770a8dbca479cb8dc484e6862e8914528e00000000000000000000000000000000171c41e295db325aea6a21089da400811efecc7f39c5a2b7dbd89a2307454f7b364d289bb0c329c82af80607df78dabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003d4919618b8c093c2e3f1bc8766aa309723873337f58392a3186b6cae103df78bfd30366e3e7787a6518348f23f1b40000000000000000000000000000000014b3461ba810acf08b43f30f0a823192f09e56f8090da155ae617e008759ee31e6779d09e65ee178e7a0f935035598b400000000000000000000000000000000193d468f4ba46f577d061d9e5d13c9c1f1596d9be63104bb395f4b9f6eb46001f5d580d0859d84612212cec289db0f3f0000000000000000000000000000000009e9bb67d436ce09d22f1065dfcd598768954a8366b0665a21e3631ed2dab00b83eb560c7a418df005f86d0e1accedf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ecf18b15b1913a8d62999fbc9b63005760326c68d8c1ab99abfec38bc60c9b98a6b2e5b51564ef6e852033d1b4d5110000000000000000000000000000000002edee3aee20b89ea1b63a8971a31da3cd78e5fc449f71c5763a22f9d932ed34f8f02309f6f27ac7f47eb35fd4440b10000000000000000000000000000000000793b40f5cbf4283110f0ab18db42b1f8e7ce8759937c521788e101417194502f2b0e5790a6fe13a5cf0aa53521454a200000000000000000000000000000000101c9542049dc352f7d7aa0a2ebcd204c916abf087f64cfe6dffaca3665afa6a07cc8dbda9e0cd7d6e30b89f6db5c65c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009da981994226d2fd4ef921154367646552d830ab8a603b63aa5966aec7dda6afdc26fe241a01884da970ad0a2394ce8000000000000000000000000000000000d015b1b7b90d26d65bc5f3cadb093870e0da62eb8412b28787e57061490224ab71be8f778213ffd35585c290cdfc5b9000000000000000000000000000000000de5e758fc3a95382f141ec7102cbc8bff65bb68cfbb42bb3d497ebb3726e0de2cff1fb3e44cedeff33e3b99150155650000000000000000000000000000000005ea02ccd8d4ae83acc97a8d7970d81515f3fef5a9ec48f5a8b2dda1f112ffed53c4cd9bf467927bcad618d636acee821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002466c4ed7b01e9779358cd4cb2df8176be3693c934446adf31f430425e923e8aa6fc5801b1206c1fc180ab51e79998b0000000000000000000000000000000009262e2c61fe866ae5604cc774f0cbf995b97c67901a93fbcc2174b11a72994edcf0f653be07e5bec20378d9c1ea1695000000000000000000000000000000001592cd7d93cca45a3e8bef8086ad6bbd2373c0011d818bcc7fa922c45403d6928ac6834a7c4cef3715678826db387626000000000000000000000000000000000ea86e8e3bb90103a24e3f5d2d87f38956f1589ecf40cba32361f64e6ee0d73d9a733bdbac7777fc06e0a33ea4488f531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000192ce668a9f162b8f3bb078eb2d116c65ff8e3ddf8813568d98a0d304362ff1d75504de2689d4fc9a6eb24371d8c0fa00000000000000000000000000000000056fe3e69b69e2cde9bbf303af9a37532882c0f77e87d68ab435d4b60e33cc19249b69dbeb90d4c7bd1ff789f96d5c060000000000000000000000000000000002f90136f280ccb05fdebf8a4afd566c21a1136b98dc875aeb58761ce21d6d657304c6e42366154d25831727b8541e89000000000000000000000000000000000dccdf054c7fa1fef8d413ad389ccb9a74f3a1b69473e6fba4063b71bef190bb2e8da68325a2602a3c6919d454b8828a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000553a9d57ff225c1251744b7bbef77afa32fcab4bc04a03214dba09d29299ef9a7f6d64eb94475453ec1ee46d46a68c6000000000000000000000000000000000c29b723a9efeb891dfb4d2c6ac4da7292d283e96cc51509565dad2623001ecda282bab0a15c966a5adcdd21be0e752b000000000000000000000000000000000d54498733fa68d38d0cca8f0d8f12a76eed3ba7057b448e80445c20a3b54b4d53ac5545925c923a87c37820685c37350000000000000000000000000000000019d2c37968b5b7600f025898310596cd736ba739ea16fdc07d9602d81e49448d88da7c5ec07c79886d8ddf663cfaf38b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000749f9c8e8a202ac6568279abba7981c94c2d81ef64eecc6e3e5cc47cb5df5ce536a2341bd85e1c1e8c5168f5bf455ae000000000000000000000000000000000e4a9d5e3205361ef8490d14444b4bfc0d2883333072f03b7f2d3f50607b4925362ecec81e2d7f0d3f966203492db7040000000000000000000000000000000000f8f96e04493bf61580c4882e4e0b2dd0e0c41899b2c7c2dca8e2426556b047724b8042ac5da4ea167d6790f0901409000000000000000000000000000000001967aa86c51fc1c688a1efcaed6dec94e7fd0fa3059fec629fdb3d816b0d73674aff57bef487f7d70049d5823fcd5a921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058aed5f1c4d9911dfc0e838b9f19ec117613316a5d956b1b752b9a692790fb80dfec4882acf7bd9719464e11fd95713000000000000000000000000000000000b8fad375b6650daf07ad8524a177da8c43aa002f06a8f7df561ed321e7bc64635b0a26e096342d631ee1c28eb2d1f2d0000000000000000000000000000000019173f1014c8ba22214fd9b43aa7563ac47e3454349fdad5b38f4ad3b987b0ff763b4b51781f093a0e379763d6575d750000000000000000000000000000000011f150858655f94c78bc521c66a65d66df43c515ae503e986e06dd5472c19eef7f1f66e01539749c4a3d38f10e16b94b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e040eef71cbbf816ff2a6e97dcd2202f186a3422bd125502e8f58b3c763416913f660e0c2fe085885ceade21d815a27000000000000000000000000000000000584f38d9e3b117fc078f396d43bf4632fdc2ca9c8760e04fea54183745a3af347c06d3f9fd6485d57fb5872811b0f2e000000000000000000000000000000000c007681cd4aad14ad171d56d9ade7a979c533c7eacd3c67112caced46d14f810ed66adf78552a7c1a753ac45eda2c3b000000000000000000000000000000000c2574a5a87178a1a7c50c7c52a49e25af4bb9e80bcf5017255709377171ff3af28622ab3b73d6732f5c8abae199a1991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d1fb347504f44f3075ba9fc8efee0ad7af187deec47b23a484e12535e5a1e057b513d164339481bdf1b621116661e60000000000000000000000000000000006d60b4cba1a5ec145df68c5991598578d2857c5112abf2459626818dae7824548f0be94d4c994eb1998c6f6ef775ff800000000000000000000000000000000126aa9d653ad940910d82d4399c79988ad7cc11e13c1d01cd266aaabdfafe6adbbecebc2f2e62e2b6c521f1cbc99f8a10000000000000000000000000000000002bab14af46ddbe3568fe83a98dbcf466650b1f358061d8457ed862ec21bae8905ac0516e5f8112b8282cd137f9c34321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d0174fea59346531a6f9c9df63e0fcee2fe66d9d26d51849024595c20b0e37bf780bb5382b7a1fa09ed92850133b72000000000000000000000000000000001995e537a78f043281be3e56cc5244a46ac65e96bb104b3e7334660aaf010f910f1f49d6d6f685640ffadf511483043000000000000000000000000000000000112f6ad4238fd03aeba61b6ded9f8eb215940e61645eaa5485dc625ae114372c96a90bf750a914e78e35b69dd9c55f8e000000000000000000000000000000000d76230929f88ab08d848e02585d75902da73376197d0df16bc8e3ede33a66580b37b007f64fb1ee76302b98006ca52c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f42bf1faa226d1d2011d769cdc180e5e0afaeadac3c3fbfbd4c6d7d051f6195698c71a718c3ed830f668a8f9a43da04000000000000000000000000000000000c94a68ff2a3d815b65c73f8b79019c0c90bc55d358d337c42cef8296d7dfd17b70dadee89097815a202c35bf2521e2b00000000000000000000000000000000052b39ae3f7d5b22fbd800c8c77dfb73cb325011584085c4d4d8190affd9671d5431af3a19a905a9c7d511db79bd0427000000000000000000000000000000001382e81c34262f9dbb0e16833d7412574de6cbaeb702e203c2bf64d6090863898dda51feb144e5b95703692f5755a7081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffab82f4eaa01fde821cbccf7ca413bba724fab563037ab147e5a533c4f99595f6a4eb513af5d261e02302fd5ff43a2000000000000000000000000000000000cd4de9fbad27e66cedcd4ef2418ec7901631c05cc4d72ba6d3fdf108b159fac209ef4337f98b47309f2dd5d867ffe0300000000000000000000000000000000196402bc33c82bb2eb4615f2139427858b15432484ee2adac67feb4eb560a321387936d0c0e1f64ee8f88111b4ab1aff00000000000000000000000000000000096e2f7de7fd3f3cf22ff5aca99efdcbb6b5355d24e74f96bf0f6400e57571536e0bb340c02777bd103e1332127b0bd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001775889c8c3aff9369bbf1a92ceab1b1de0fd7a0720d5ce437300023f7a9642e605662919df661a953ec2524483bb32500000000000000000000000000000000174104a77d2df75a692b25361faca47b16e04dfdd49475b88505818bd1f01907f4f3e22cc988f12f57335ba557bcb1fc000000000000000000000000000000000a7e16d4e5bbc86ef3238b8538387f8d188a370ef4bdc30e44c2e759760df78eb05203fcafb95ad324f7e02b8d1bdb420000000000000000000000000000000011e27c3159ed5d2552f597f34e3cdaf2318174ed03892109344c81bccfbf01fd322324a00a51cd66f3ff4773693a862b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f5aa61b6d11da86879ac53893e0f74314b791a7c597ca7fa4c0e0f6232235220272b4e5c1a42266ac75508b88becd00000000000000000000000000000000013805ebff265bd9468f3ce46a52977af96491f40939c0f99b727057037fa46514504680a757057d6b8d9266cf8c35020000000000000000000000000000000000c68bbdd3dbb97ddd79a56ff0922099268083e131843fa68c51f05f16e4050374806d4eaeacc3c6a84252d6ea80da83500000000000000000000000000000000133c3d15973efccafb18ef4cc65a64f2ea5ea1753b18b82b50a9282d70e8e88d5bc548528ec299f069d6f33e58156e6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078285b536cd3ed8d6d56ea3ad2b73ca842f24e29cfd58b3b1e48a2cccb152d0212abc03040d76893bcd0b80f0d60be70000000000000000000000000000000015ee6c2a8101732709db0c6dcfa3d6f7d3cfc2a6421bdeb3efb83f75d0ccae1663ef7209037d9ced750ef08d02d4a94f000000000000000000000000000000000e2b9e3dbbee317ec7a7d6dce3e58914b6bce7bc5d88b2b809b88deb8dfdfed5f5db56590643c03ab1f7c25bdd7162b400000000000000000000000000000000072b0b3acd33161c0b5a64dfc344fca2d5493f8cc1fca89495705c99829db60b158b0168d7acfbdcfe5e6780966855b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018410837b67fdca6fe90ed41b2016c7e6c1e1e3a9654e7673a893310ea850eb22f7cef09795eb7ac19d242e073497a9c0000000000000000000000000000000011d2c84dd7a198f9a7feb7a845333eab50f130d649c3c41d711bdfe6905c2649075fb22f3578a59abc8d7519d03f28050000000000000000000000000000000008ca2f9f5d53befcb82f50f33e40c497abb84db4489db52cd90b30004892608aaf2168c1efdbf6136a7fb336ef5a862a00000000000000000000000000000000038914c94061e0553223424607c9a2fa6073648367a84177d3b225bb350156cdf613805908500941ed0af1b4b2d910001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001004335e05f22dcddc16b676547f05c3506e0ccc7779a2286f8392cd0f53486f1ce626fd2f83524fedef81022962b52400000000000000000000000000000000174b99eab6a1043dcb718613b7107ec174389ad65bcae5d7db347250f5bbb783a3a93f1537005f59fde688d9dd4b829900000000000000000000000000000000008d2ab5b814fe56a7ec5df725abd3f57474181d1565b37f126de53f9b576ff7aa790a4c006f58283958742a39c56bc4000000000000000000000000000000000db257a1640668e86c1346d87d50aaf631578bb222c1a8dd11564de41bb5e2caab9f794c4276c0afc59852d781326bdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807d75e4bca80850848161605bb8d663a0ab86843c7f844e72e2591e50032dc255be5f2cc861a1034fb619cbee3f33b000000000000000000000000000000001855bab65fe3c6f743f8a8283dbe70e665fa7d6eca033965a8466dd603f75e609a4fb34efa4bce126b70ae035ef10045000000000000000000000000000000000d433582fa257e610c780834806aa84487d46a7fc3c270178db00f4b390c1d5fa7e37dd2c5a17646a2bdd42b0678ef6f000000000000000000000000000000000a1204356667744d1fc8feed47619037cd030aa826ca86c2e457fe7e4384d2baa310e85b62917e9a62646a7962698e001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cd601bcd60a127592d562d7ec90ec95ff727c3f712872b2232a40271f61c9b11622df969ed462767ffa4941831446400000000000000000000000000000000136375639818ca53fa66151b66a3cd5c8c2d7c02ff2d244b57f2500b143be9c78dc0de9bd9ac59179ee48d102b3a8b640000000000000000000000000000000011f0a41746f628211c2cc5b4dc69023a88ba5ff47fdccc37a63cb8fed7d71fca224e095b28e22549fa1061f071247d6d000000000000000000000000000000000721f6ac28d8dc81918d9acfd0dc1c270b2327226ef1f7a28570dd6c0b20cab880eeb4e04203da283b7381f514bc437e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016931e5efc15bcd3cb42c2a499b609297e87aa20380877c98195d11e877368b6fecc1b7cf34422d84a59b9e34ab0daa50000000000000000000000000000000009eab1f6698c48f514548dd6697da5bb7f70fb2cd4c642dc239e4477316760e85cfb91d62fddff43a60c5c432a3e7a17000000000000000000000000000000000d17751a1843b99634577d6ad06a6fc531e64be3d69b4a446f6f85773c1cdf4e0c001e75378f284d36ee8fb0eb7c6e4d0000000000000000000000000000000008002e976538f21fa9e6c08f9865ae976f818126d4218ac99a21b9e46e43a087b52d5c4adfac3912a2d748179adca9301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188b3c7918cec9938c635c93ec9be68f1da22bd1148c9eec245aed9c8a45c5eddba6bd56f5846ecd66f11d5cf96dd3380000000000000000000000000000000008a622b09b9f6394e9792381e735367f0a816902a1e03f03201a37c5dec0836518ad7af15de701cda4d1f06f93e7f9ab000000000000000000000000000000000be9c62473c3203be33614525bc9bfe4291128b7dc340e566ba2c1fae3d62a07139298da3f199c9d23beb6dd9a097bfd0000000000000000000000000000000009f66c82895e7738b21171fa8064800fc0bf8f7c29a94304896e37ecfa715a794d67bc2fd92e441940a0c0da819786071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024e8ec5ae4e6a10671d78cd892ad1c959176ae3ae6e7dba532fd24d6c93e80665be61ccf9912421fa5c44600ceec12b000000000000000000000000000000000d6feec9e73e8e980de822d5c99282101a94737457aabf18cdfa1db6ee08c0e7e2662f499f51f7e32915d0a6d639aa8c000000000000000000000000000000000f65a619f1cc78bafda329dbd10fa87020b79e199e9001fcb71598d3749cfd98914dc532e5ac64b307f3ebf413cab2020000000000000000000000000000000003aa0593fd022d636048d2da4aac9572e1e7f00aed2e7f17561614f0288e106e9f39d7bd036f2d874067b7a2abd4f3d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f782e0f6a0c821cb4857a9b8ced530f84d72c47f748337e28f3336ac9c9cd7ab27e98189f6874f2ff1b53bedb38ba780000000000000000000000000000000008f7f862470ca9fde7026de47b63a19150bc9643a9c35bff58af26e3260cf111f1f1eb220ac667e09e623e22fc8bf5b0000000000000000000000000000000000eaee1381a7559c4871075f396d4c94a823779ecaa78721b9eb87b1fff40b09e7b90252167651f54018ac6f00e6c1111000000000000000000000000000000000998af1a34d57327491a763171d65fcfa16e9276e024a5db0dc15b5afd585d2be74f04ac76bdb1c48a166043576db9161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ba3d97b3014b1cc21993c52db64e142b999e6b4465a601c47fb024d8150fb088ee3c94a7eef795ae44984207521847000000000000000000000000000000000e1089c9a02f037e96707f7dd7a22aa87603e0c20c2978febda9c1004fdeaefa9d594eb665f085489128a0510c5a9207000000000000000000000000000000001213395ebeeb024cd3e48649c3f9cdfbee182c589753684d4cf32a804729c33b689dae2c506f28711de5142106375dd10000000000000000000000000000000003d790e95e5548a8e38200becd2c9c4e5e2b7e6323c9aadea209d0ba4257b7822edcbb9e436d024a0b4745fb8b3d6b551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018886c20058aba8e5f065d3ba8cf412610228f7ee6e7375d7cad8fa6333c453b076e1cd84bdf45d13e60d929710372f2000000000000000000000000000000000744f24ea2a234caa355f76074251f6b08c86250ef8065c6c7d22b2e0a493fb4e50075eef3b1e18dbe2d404ab5b807020000000000000000000000000000000006b94c804ead83f59511acfe276908b23ca670c71bb434b9e4924ee83af305aec25d35a6210909891d8a93591991f5e60000000000000000000000000000000006eb1e523d3670f219dd581701088ccf2ca773012a09e8f26b719e220f6ca961748eb488c59ccdbc593817116b3ac6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018de2eb6dfedd4051304932995d53d921bb42ee9f23189044e46a64d5f0236ffbc7c4e6e976f69a8ac5fafae1fa755b5000000000000000000000000000000000222ad5c50d6a60675822794ba6c0ca1622bc79bf2d9c99bf31d90245a6d1c78ca69d94e170208d820688367e645cfd600000000000000000000000000000000051c980111309cdeef42f2c49bc237afe7fbd30dbe99caf47fe05a5d5d156c54226b8c6326c6f15c313a71ab1fcac1ca0000000000000000000000000000000017b004e656bca2effe85acf6c74bd54025a2f5101c7d3ba8555b303a1121c0bcc144a837a2c5037a342b5ee185f89f2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dc2d7dee31ec70af7db920be7e7a0301860c1c0cf0cdfb2df51307a17722f02743102d59fbd93c35b698bdec9ffff800000000000000000000000000000000127267625917b97475d75842e7000a84eedf8c5f7dd1195bc081a91d76e1a4e183472c4f5112c33273bf27d0e6c3e9ab0000000000000000000000000000000015f24487c96c9d063f0d77fc9e45355074f0519bd41aef22d49fe54565f62d0a322dc11f11c12ea67321488b6aea9617000000000000000000000000000000001796b0be2e9cb82eab98838442b972c679eeccb1c6ebc3e09ec3b31790df36a55ee0a51299e82f9487a9a1dca581c9291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130dab481733f795f53615eb4d9275ba3886556b2ccb1592bcf7ad344e72d2e3df254df66df5f43480c13c3e940dd637000000000000000000000000000000000371096973c7f529481ca98db317ed065c3ed8db284e33b6f530fb3419e6ef880fb415d1d5b866664c22f3f1791b9e930000000000000000000000000000000007ee6d74c425ef8dc9498cc712128d1f4790c5a1a1929e26cfd6cf32321b795738f6f014570a125f52310aa8287dd7b80000000000000000000000000000000007d592ba9cbb8409c485f29b53f2cda358cb0e3cb01ad401520c61f7c0de8eb9b40ccd031ce2262d785838cc0f50fa471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fec88aeceec8d7a550ccdc99c9e1df73bb98d6208286edf6460021abe4dc0f92ecdd77f836d509f6fc529713980e1470000000000000000000000000000000015543244453a07058a9dc04d3d3d7916d632c426958b67f80d0529ce219a27925d200899c2dc44404c4f9d6bd8492fb00000000000000000000000000000000015d129ffa40b8229a084cedea2097a3333cc8110761fe0184f77e400d945399350f51a43a2045627120a1ec390dd7a2d00000000000000000000000000000000049aa89cffc789daa86503b6f81ad398b4abb3e406cce3aed3454e5afc70782f33c4de9bb469f93faa4c43d708dcdd1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111c3d745df57b5c1cb9f8fddbb4ac59b186b12a9585d867cacbe74b8b51c26ad8df2c3e6be641ec4d44168f4d39ba40000000000000000000000000000000000735bcece0fe809aab55e85f52a5a688af3f3e47ea989a53fc8c45de02cbccef23e2fd603aaeb0a9a6c96b1a90a01f8d00000000000000000000000000000000118e13a2b2301fdbbb346de018e41c5ac2d55f08064047e8cdf7270a97b9e04579c52f68597f16ada4dcf0b10a2c073f0000000000000000000000000000000012cdc61d5c0161e444db495e731f966b2385345ccc7faf62ce880d8fb861f4d0663734444e8855c84f62fd22fcfdc77e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145c8f7f1f1e67165374172bdef4bbc13b35659c19e45c6f5a88ff0e469f2b3ac207e60f43ac89aa06caaa1d01eae82100000000000000000000000000000000128fdf4aec3b2c58f0461073ab1c1ae3062f415e6e3c507793f0060a1b831f6d0b54a39174329e8149072f3272d330fd0000000000000000000000000000000008f4720b4801dbb425d3501cb1c7cb8b9fb937a8771232497f0497bdbca6fa4bf8fa5ba5dd5080805af6babef72c4ad70000000000000000000000000000000013d01bf4d28eb5a0d47ba8664968ce1a47fedcfb400f632eb7e7c9441344c5c9f66cf7115a15618c5abe83455a1257f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a734999ebbf8fac1d7bad9c580f6288c88aeecb2dc56bbbb78a1bc9a1bada3e9285cbd9a746d5c38fa56e7ee6b1b4220000000000000000000000000000000013eb920c4d49e4ce2306391c6ae3155ca42ec66451482515698dcec23d14a3fa8f588a18366af430bd3588aae112b455000000000000000000000000000000001680973fd55f212304b4794fcd73657f72d9c3a2a26f711dc992d7848d6b191d7f1b291a5a05b44c8be74853c52a583600000000000000000000000000000000138e48167b972cb0a6ace87bd447df069b08f01051868853819bb8b1d4e89da3f5df8ceac1e891fc6dde7f0931f63d4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180898b912db5aab074ff174577b3c97f3834d2cbbcacfeb6cd71d8cf8ec85f49c29b27e9ad8d35bcb0478ab3a8d03c00000000000000000000000000000000004029b306cc7f7b96f28bdb6613dee65404351beb8a320b5f42f6f0e3c7740acb5763652bafabb60a75ad4d49e868cda0000000000000000000000000000000008234e079d4f066eb4741f90307f3e23d082ee81fe83a866d8baa8e0326199b450e4a44525ec3b57e32d155923357cac0000000000000000000000000000000006041fdda835f8541dbdbf5c3cbcc1747bdd6058680e6fd28f0b6a2267f59e8af70af94b012ea5ea3e8085f02b4311701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f797576dc02d8479bb040a39d65ad8a26896c4f86eba7798d562b62a1bc209cd5c393377b237656df889d7b55f3b7d000000000000000000000000000000000d3dd73f97aab7ffef9e6166e234f1249a0ee227e68bab100a7e5bbd3aa9bfac4eb539f24750848671d803b3806985bd0000000000000000000000000000000001d0d4a2455395d6a757262652fc8247da224a1b9ea787c73cf60ed3615f58587b556a228769921823d448fd8aa6cb14000000000000000000000000000000000df6924fba8acfba46b353e2d0740a51816196d0e02fb5229d7381f0fa17f65b976abfb21eaa15a3ae9a440d1b93e71b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab2a294c4be1b37002ac0a799d5c7029f9314a841e2b909f699b1e1dbca7f03fd25f66637c06a4c7550ac6fedbb53ff00000000000000000000000000000000156f9944e24b8a584d886f9617c638e94d9204bcc5ce96194cc61d438b07bded0328634a21a06a71e6e8b9902c9a34ba00000000000000000000000000000000020a455603c3db1da1b5a1e6bda6820a13644ec47c85925361b04b77ba7814c14c782be41093114078918f098a13639f0000000000000000000000000000000004a2a3aa9fddf69b08716e035aca16c6078df90aace92eff273228dba332255e2b97f630b29aa4d794839bb4f3becb4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048dcc0699771555fd796049b07a73da3c51b659270920ca66005f3fa6a4eaf5dac3f915b96352e427639f873f650ab5000000000000000000000000000000000bc65e331774e058f4625b61cf204aeacbdd7949310f3eb0e89b723b03b0a927eac1550dba7da6f826b38107fbeac4d5000000000000000000000000000000000e7db32142d378294a614993f18aa71c714f6030e6e9a23ca584ea07b8515abd268e5b24912ed7132a50af40feaaab0b0000000000000000000000000000000004c623688fcc110c33295fa1a67c5625033945991c1bb61020e4274ba15e13f1ce0c7f61cf3d99f1f117bad16be3bcfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002761816f76bacb5efa092a028aca0189c9d9c2d7285018668de48dfb8ed0f698417031c6161b4c8683c722b9b767c4c000000000000000000000000000000000766b5b75dbd4330964f0dd53802960ab42118fe0addb13b021b439e1cf0c8ed83ea54292c547ea9e57013f97bb1b55f000000000000000000000000000000000d4e44ae0c1f7500a503c095f29202e427209eec47d0fed6a8c3a7235175024c10bc91b58416e0f767fb2532898401ca00000000000000000000000000000000002fd7b9e3bea99a7cf8df4d190606c1ae21bbcfb929f077ed6190d694fb69babac8ee6232c6984ba6ece7f53dd148fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001547cc973208431fcc7c9ae7139b82cec1fc2e0f112a459935cc93f6203c7c7399b674361c22da069182409cc6423e500000000000000000000000000000000011a1edbce56eee33c1f8ca488a4f6186634835470fe4b32614d978bc05f17447404b95928ec3f8da28e06ba1e007d7d2000000000000000000000000000000000cec04d085f4bee0e0b5c1b9ddd908681c87d619b166c572208a8d5cab63cedfe748bd5af2104225cea873e75129118c000000000000000000000000000000001482fcb626579a9ce02a12fdf961316c942e9fb80a58a4115b0e9c7c151ec7f58af4ea174f648755944b2497557e82451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d972fc019823e4aae36eeaef4b85caa5c88385a2d41597e843275b84a9f3e4bb698c8d3b56b7b244502e1e44a92f7b30000000000000000000000000000000005de897555c15efd2510243b70e0ab00252feb1ec0136551ec12cca1fa6c527108fa1c8a2b30a33fe3f3c30d8c4b47120000000000000000000000000000000018935f3b9a5630e88d791c32b1a4a7ea727af82d7dad934678f801239870b95a66f5373e1a3be98ab8f7922f7e21ec1100000000000000000000000000000000171648a63c99c19e2cbbc2a62e4180825a40ebfe8a1c4007e02a4159ea02a4a06e8fe8c204e1d13100df299df2c2f9bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084d464cbe91ff06d34e8b5be2bbab31d8460e2838edaedfb485c95a8499b4127bce7bd9b009abb917e6a7da87bd73fc000000000000000000000000000000000aadfdf51805e6536dc5a8ec9605dca01975a5e74b1c1b730232b84cf3c1c8bb33dd520e68fce55513d545d404de9bb60000000000000000000000000000000016765cd7ec4f04dd855a57f2ed5139db164fed1e8cb91700b4b1fa7605c7c2f9138197691fd12014a4367d5f4f6516050000000000000000000000000000000012bde76dcf910eb1569434f83fc1662606178b7518416739647d3721d4963fd9e77ee14dfa866afb1384b80bed7f86781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e04ff9af791c7a5549a6f32fd7017bd9a777fd165153f3d6fdf9266f3417cbce52c557364f54f4a5517738a7f981920000000000000000000000000000000004f41415bb88dd908a061caa3216bc2ce297c985634df7805ca62f3ad2bea3e3021544720f5dea5b97df60be7d94bfcf000000000000000000000000000000001484523a9da1fe76be8fd04fd5fca187109661b6bbcee44b6c11984e79c48bac2d0fe8c1617d1189c7904961c3255af600000000000000000000000000000000002fa75a986e781bbd295a2eb613de0d515769a090c5e43957d6fda23e91a5d203c9c5296c849d76551643d96a8673391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e01cc12acb6c871808d7c64ae26aac9eff4b9a827520eca39be5a9c414fd351a11cc8a36a688c1dd9deeb60b14619e0000000000000000000000000000000007686101ab3993c9d383f06350e18771205134a8611439db97edb44f024f397bf69f662b4303a8b8653786a9d46a5535000000000000000000000000000000000116858a905b6f82f225e588b846c1c7a7edf9bac0241c2828b917d100d241cbcf5bc00d25848c2471c7244c9e6cbfa200000000000000000000000000000000045914d3c4e48c5f99bb9cbb0716e62501f64cb5ea8a7fe8ee18add2c732d9386d05d00e4862f3e865185a9f0cd6079c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000998e7995633119f1daadf2bc5b3fd55e4f12f024fa965b29075178d826dac0fd9304c8dc3969ce2e99e3a9d8b4054360000000000000000000000000000000013b198108ee1a629ad004f55f742fded40cce51e36a5d6366e53c946a062cb2b40ebc7cddcee80f5fa1866b81f7028ce0000000000000000000000000000000015cad80c664792f0279e70757cfa32fcd4a55e4879289bf3bcd02856bb00baa0ac43860b6da4f58c9f5f3677b41a9f67000000000000000000000000000000001895c504538b1dd783eaca741b2eb1cfdac62a9a8f39dc705fe167c354c4498d725cad60807afa97502ae52d6a75d70c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036e54c23922b2729c6f5d2f4d193ac65d7f0e72b74e1fab8ef74580b8d6bb52a70e4881d6b3236a6d30fe0b585cdb69000000000000000000000000000000000089f6669bfe1fee2599a2a291947f099860c70e44ace42cbd60eb4a5a7156218778bc5a44ca480a4ec0363cbb1ec42b0000000000000000000000000000000016fba274570491f8577aa8acdea156f7cf362ef2f25d42cd2228d16f4c79fcd3dd5b19b1d2dd8c1224761b688a3419780000000000000000000000000000000011a7f75f88493c545155f3ed3a4c77ff9dd1a0d251ab1f1f51a89f72d81772fc7c5bad0042329584925fecebd4e5f25e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a81cbb5f0ed38c0d55b3526a5039a858b9c87001cf363e45d619684901de11a11192dfa1a616f9e836f7a3272538d800000000000000000000000000000000089a9cd7169cff75bfc41a71b4d6f2b76fe16b37ae60640f785c6856f57f938704eb580c14a92b6e71e3cd9f01828285000000000000000000000000000000000574c2842e397f8a633da2d2905739916e6c8889baa6a9ac8c4fad446ddff2542f0aab2af703743d13fd3adea11ff823000000000000000000000000000000000c4f1622b505f09796f765354db60f583e75835ca2137d1dbd115c187fe894ea2e46ce334a122582dbdbc96c9d88dae91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000483748eff10b3cf9debaeda46400d785a827c5545c04f711ccf54143d382177a4bf892f8b6349620820d1d3d0b6bcc30000000000000000000000000000000009cfc6a3677a6093025a829071c32e80d96b669f2fc56be9cabee0b85b160c80cdeded09d24147a81c8f9e8f43338af200000000000000000000000000000000068793a2cfd31752177336c187420486bd0d11be0923c3605affc4e29eb449c442871ffade9348132b6a5b42b134de720000000000000000000000000000000007a4e77309675098bee58b05e6c1e71ca028c1ee9a69d4e518f5010bb0140d340a3af60bcce28c6aff14904be09e27fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e87387196947f1d45157d02b6667ceecd4f8708ccac70a7738bc1878f008c62a7bdbdc0c5049a7643cd17d594df24700000000000000000000000000000000002843e0f085420f74e12ceb8bb4b683719b6f422e555fa2178186440e3740a8de42feaff88e35280ff1a5e9423e23dd50000000000000000000000000000000005267e1ee025371c3bd478d28f649f3a5b030ad58226bc7e6a4e75c2f57fac05e248394ecba6ff0fb9d494a50699acc50000000000000000000000000000000003d2dcc3fe5eb7c7d9b5cb6b7fd023907195e9feae2eef03cb9fe74158223d0d7dfc7881657416c1816564b9ac34b8fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a0b64dc2a5613cc839228d6baa418fbf1c138d929a494e9d56453e8238c9aca05855b2a3356fad9d09c1737dc9bd7b00000000000000000000000000000000079dd3e4fe7f1230159555102e029578a45e763709231bfc1a06a49a555ae99f2edeb2a012788c382c7f28a84a5057380000000000000000000000000000000002adf35810a203b574508e16e0b61bb35250b24e286fd02269aa7242096a40947b377a5d11c600b8509a304bb0a041520000000000000000000000000000000017653192168c165be38380fc102d8825f3b88273ae0f96d0cdd73c0961a35b8951a5f9f2b527a623017735a7abfdbb531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2baa8da7ac3e766373bb71e220dadfc07dc6116b3c51c76cbcda1f0c4d2afd4ec938efbf72c3942f1d800e5735195400000000000000000000000000000000079bdad850399e251dae9411f43b4d5ac6d514aba9dddeb6d81f1de0b0a492ab81bb55b39512be473a6a4c8851608bca000000000000000000000000000000000d3c0eb82a2ab37b09fc2f8d5c39c5d406b903f0adf71e4bac445f4f46ad406ad66524657207f5757fd853f0d09e985f00000000000000000000000000000000081ef04b174d0e9caa781d081df596a0a7c5e264a46ba9698e5ca535c3dd9c26f9dc1ba9585829bcae0a7b70e00c28831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001650af0e9b1b286646dcdfb398badfc7b7a7e07f7d841d67377e589321f3ac11136975e70852e731c86c6f8674ae4e150000000000000000000000000000000007515b6d8b201314c3e026628f9bd8c58c23b00d89926b08fdccd3ceab478345f59fcfbcef7b5368251f327628b128cb000000000000000000000000000000000a779ac28fae4ca9b6c9ee085702c9c4468d8ddd91c6719c418ec1f61999e7ff6ceabeb9cacfcdc633f50abeddeed2840000000000000000000000000000000012eee851d91854d0ce299be5d84822e23a22c9aaee84f5a728fc48afe81b6d9dadf9ff9de5137ae65b5b5e6f9f6695571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9711071a703e43243c372559663c3aba6d54177c2331b4dc5956fc568f42abc96eeeb68aafaaf19a0d2780c47309da00000000000000000000000000000000061199fecfb76c34a1e1128e11eb339a335ea2f6826dca8ee079c07e01f06aeb44bcd05f05ad8c14b6d7441d962336fd00000000000000000000000000000000081d1a83d642787a68f4362bce9efe8ececccb93461a1b44a0965e887e84bb830062c8940e64f230d07148ce4460dc800000000000000000000000000000000009b0b09d5a07883f73e01039f19346e0eda758dd9ddc459ea0d58eeb07ef9944607a408a09f96b0d7f811ef4dce3be371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f627f9dc9d3b51460899183abd4c9121843a6342611b82bbf19ae9ca53c18959cfb7675d27d7609d664b9fc030f667c00000000000000000000000000000000037bce7919e8409205fbf65a6645982fefa6e49fe0e792116892d6c656f09511e7999e574b70ef713c14e53940f40dde0000000000000000000000000000000002ebbade93249f52d5981d2b4556cf6b2189e526989b14f6d35b8fd0a0b6ca4037e89580e20b03c7176e9739ccf0cb30000000000000000000000000000000000bc2745232b97aba942415df7710094c4c3e5cd5e82142a697ceda5d16daa87c354ad4c616ff62b49e1b50271975bf5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006599155e7224075d1258ec5f63e9c881c862bdf1405aa3500eb8574f1c6693bb58d23302b71901fc82207a36e53a7d80000000000000000000000000000000006605230b82faa3d74c7ef52a6ff047949fc2780080ba2240c004a35730f5c9631845b3d705a36efeba584d92a1c40f60000000000000000000000000000000006244485c5d3e9a163f7209a8ecdceb79402be005047a0efe5bedf706639c3fa4e865df3d6479d3c3309566cd688b03100000000000000000000000000000000007a9e92a27b3a9b4db4ca1bcd4a9d904d7d12ecaa99adad4edc504cbe5067e698bf84189b09e0c5283cfdfe3a4d904a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee03886ea8a34406dd0d767e49e83cb7ea2dc625bad0f15aac376f466e9704daf048129bd0e491f8c2ad5cffb0f10c4000000000000000000000000000000000c4396c2a0bd1cbdd410f37e4c77c164fb689e6cc57ef076e3bbdde160d856a5caa0caa9f1cec81bf3ac91e545bcdf170000000000000000000000000000000009f34c33d7b517858190d36999df89efcfd6b3d067537f9118baf4da70b112722fdde799105911a8f7a604c2029bd0cb0000000000000000000000000000000018aa91fe89bb9581763259c4b9b2954df3acd31f68741441b68728e9102efe8ffe135151779d54fc8ce9cd549ef6e2cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180b20271e64ac7bd1b54213088283daf4d8c646415484104218b893e5133a2a9a910854e255a9e597af6b5b97a6ab260000000000000000000000000000000009f66ff5ae096bae9dc1a13208501a33ef43b19e3e5d2727dd76aac07803d5c1b89b4604927d10ae9f1112e99b6a1600000000000000000000000000000000000fb4abbc673972249fb451235faccba59eeb8c08535e1aa513464aad83af4fa9a3daee59d873f2eda5248912422b4022000000000000000000000000000000000a838e4905685d4d877dbe8a4b624a7ad7d06d76b14bbac5180f51811034425a46030475a5e6af3faa4c3803227a78551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060a7741b78e3cde771ca4c2d15b84cf3f0b9dafed26052a66f86b03d6ab5a1725b081f9ae5569ddedd18febb81f7d9d0000000000000000000000000000000010fd5fe1fb483d619485bea22d90174303ea7270507eaa783fec24d2f0c1443510bf8f7d61d5266a04c330efd9c05fe70000000000000000000000000000000007d5ad82f9481c2ad0599e9443c5276c844f48dc265bf5d7495ebdcc1ada3553b97283b439f20b7debf6d5b8d73af112000000000000000000000000000000000d2b0eaf78ed718c12fb9898c8fc6de7cbd8ae0f6a7297cee756164a2a5c29404f4bca988ab7a0d10ee588aebadcb1df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b15b90d34310badee69370d86535c0e2e533576fa7300aa2db533f0347a796b340949ea4934116cdc514899ae5047000000000000000000000000000000000019181b2eb5b44b2667b4b4ca18383edb5a340326ab476c5e854c3c9bb8cec3781d2fe3031eb61f536c9aed2513009ed000000000000000000000000000000000f6c51e7444c88172c62d68f13883edb606216d86f1f0a5d88d644db06f0a9fb9fc3df0258785a222589046bc66dd4990000000000000000000000000000000012670fc922e0e517bfac5face797cac3dc9bc360ee9204209a3c21434eb220ceae4afa71228741999c5a811c7e541acb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085df781c636527f8ea89bce264d34ea7fd4b08af97bf09dd53af298bf43a978115f2102abd621885d11e4483230a7a6000000000000000000000000000000000d03014a968946e85ca58c353e2b287796ae26d8bd90b6c33e92b382434a7eccf94d64e561934ce3c803ef81d96c258a0000000000000000000000000000000000e819c2293926182e21ef5951af7f028caedd9f681e9a89bb99fff9521338136f26742aa01a3db1f9a648d1aef9370f0000000000000000000000000000000018601fc5d88915215378376689fe9ef7da2884587d21cae2f0be72317d5b1742d4d25909517ec6014411a08a64e42a9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003677129dc0a5ac34362c385929b47eb56fb1b1a96b70c0b9ddbac0eef34e653de287d5b40d166e1f0c1b590e436481500000000000000000000000000000000176056f60e1dba6fa443e230c2ba463bac40aa74749141138059322e7809ae7913cf8740077a4f163b7857ac08bfe057000000000000000000000000000000000e3923f40e6e07e116cc68b1d7552805ffd0ae826190677b71853b34e6cdbdb57d433da1f63560eb76fe2994adc2c2ec000000000000000000000000000000001206b8693c4758b90c365457e316b518907d40fdde8e200893b8aa1b0be86d3155ef03fc26eb53774a8f7db079dddbc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ccaead2fa5aab80cadb887885ee5fab421ba6064ecd094f6b1f16cf9e1295fded7cf072d7e6402ef9cec211b089e5700000000000000000000000000000000061c6e714c7e04e5ad7640edf94cf45b6b6598792e3d6925c7873aebb4e1816d93f703b1dfbc05e3ec30c9e2cccf01ae0000000000000000000000000000000008ba9d619dc8f2334c826ee0aa350c9e876d00c33cea8a61b89faae8aeeee0238e278237eccdff898482123e91a96aee00000000000000000000000000000000124d4f3b11f691fe7bf025d02ce8dbac0f996e0f1e1eca6d0b189414632c7dcde0b452b5db9d2d08ccce26c911d9e6001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a1e40d9599fe0c919e0ce3819e67df6a818cf23077740d765041637888f7770cbae1275086d1ca43b7f613590551c600000000000000000000000000000000097ac62e470175fd7229984c9baa3377b1f792a16fea74775d18eb16ab9d387c8d5aecfdb1b83db620e7bb798c3c72c3000000000000000000000000000000000a91497cfc273e48857d3907a1a845f165abe5a58c6d63d5eb2a2c0c346de19881c79564725b0f3528960678a169289a000000000000000000000000000000000cfadf181cb5f16de2b7fbc6fb3967b1e01a5983135798f398ea9737edcc4da44d6d55faf27867cd89eae2da9c03ca7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d67734e50c6e91a003fa82ad7a69c4342ef7a3b2b5acad0a0f86a3155da3b4869032b5ed00a7035c4567961190333900000000000000000000000000000000039402ca2af5fb8f0872c6dd7f2f9110ab070f966296101bc4611d45171bcbd8c9686bcf68ca910c64c92142525b9ee50000000000000000000000000000000004a6ead1dd6897c61541222bece0f4eb175fcb60b5c41543858b7093f443d49150533b0a78027e3b7769a9cadc38fbf100000000000000000000000000000000105f2fe3c76a28ef1524d7340b414587f689d6d47ddf2fc68df2b9549bc3be37f339d19a50316c89d64387a4f3075e3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bafc3536259579595fec9e0ff45176c3963fc5f84169c5dc8925718421b5532972aa4823f9894c46d2b8031e9f70fe800000000000000000000000000000000047c6e0620974480ca05708b800acaea025effb6f576ad634d69357049b986968c100c05e789097eb7308b3c9c8fa1e30000000000000000000000000000000000959f79e75b4d8128de58e9b8c1cf0d800b3651f78a5a67c6a0e0a34fc780a25ea40f94031d635005f39da5f072cbfe0000000000000000000000000000000004087cd376fffca5d3002428b560dbc056a113710dbdf966241dd6068888d590aa1186acdd4c98398d0bb5820f00aa871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009305f9f1c40ecb59155007bf63dcb9738e9773d140a6193b2c4ac23b68a56174901f9822e930ca1649b6c1475ce6c7a0000000000000000000000000000000015575a0be5c6a3bd9ff313be58e70fc32e7e0bc098146816a95b776cebdc5062004fb2208bea054a463dfab859c5603d000000000000000000000000000000001172a7f96705b9198e59690c4439b3e8b4d3041b9a58a482722fc8166afc27906965fae78bc73082d5a8988120d2076e00000000000000000000000000000000115fea96f22998a3e5f8d2db4bba658b2802f7b182744029a9133bd6a4ba1c6c1d4ca9ea188fbbb0af56da1d9fdbcbd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098642c2a1ab05b1f23394151c1475362b50cf1954cb645e6c8f3019c96fd1bdac1ba74599c874f7dde168366a838d93000000000000000000000000000000000cee556e7445c10d0710b39ddcb3f81d43786d767ae248f390a2c9bdcf33b0a4db4670a6efeb60169244befbdaa157240000000000000000000000000000000013e2f4b1d2fbc4fe49d3dfa4e08e6e2497afaba8c91ca49d532d936e5d9386be83aee1b30d1731ce9cea4534770041aa00000000000000000000000000000000172ff02c00313cd3177393920aa3ca2b85e7648638d6924e7c4934bc5eb3b826e4c17ff1d29d067ef09644a05cbea53b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102fb317485392c4e425707abc781dca91c7f2be60b194971acc2c6a26461e8ea703f6a5a4fc15d2bc1c6e2a0134b8880000000000000000000000000000000008823e2ec6a98ee2273f5e558b9ef98c35801236c0da4387934383819d6736902ce305ceaf2cebb84e8df147eb5a63c90000000000000000000000000000000003eaf433cbc029c6e0878a2b1c4ef0da210f685e5053c62bfd4e4431615f69d405227748fcc056bed19d46aa279b687500000000000000000000000000000000174928f3976ad6bbc0f2c73c2b31abdaef6701d98a24502317c5043d999466698f65276039edb1c1f71b1acf639349841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121dc77c2eb128285f299e88e12a1ed37092bdae219198eb70d3a20619dcf0847ec92ddfe950aad1e8000c872db82f75000000000000000000000000000000000022a9c924cf5f9323222fabafbe6730426d57235c0049bbd7a2b1600e7f333f7ff0361ceee589495ff70ef2a12940f20000000000000000000000000000000015a9cfcc41ae2210a70572b23d8109e437f356a107651f8e3a32ca18c242f4a7c8dcf2e654a215979143f1e100e897ca0000000000000000000000000000000012df1cb21d1499ea3c1e25f32079af0b09a1bc312c08e5aade2e3eef9c796261821b7022c2da93928591645c44bcfd851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6db84d49abe48bc8f8e8a25d453ed28a7b1fd919b6782f470c424479ba53b780a3b0937870e1ed68165d194da80a39000000000000000000000000000000000bc70a36eb091ffd44bf898cce1f46c54525ae65290080bb20ba016cb24763a68b81dee32efc778d0e831cc3956c7837000000000000000000000000000000001929e3845d5c5d79fe20a9d5311877080b1349ad0a545d87ca912ad54cf48b78289f6dc3712b04cbc0c1eb4dd9c66df5000000000000000000000000000000000f337010ed9875291bbf22d45c7b9d8cc2429a283a75c5a0f5f16cc34d2c303e3a06a4c569dee4cc6f528dda824d33db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008562868da4df666f6fadc303c73067f18c37596403c801825325106b343dacba5b772499215607a7941bf61061f41730000000000000000000000000000000000274a95afb403d76790a98bda6e49d45bd8ca75e759a425ef5d4a3ef344a1dc742092ce587d1bdd5234812db2bce9c700000000000000000000000000000000114d6b8a3bb801fb4bb0f5a0e211cf0e2335bcb64c51913dc09f8b77b93db54b472f8f94cd4846c9840f0b7ee903e7c80000000000000000000000000000000002b136a50f5561e1a65beb09c1cb57338f5af2818d1dcf5f9dff418ba3c1d0b06553d0e781e241a8cc9100ee7df62ff11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f99f79640ce10014516355b393f2a9cf83b10f5f833507ddce813ca951388368eb5378655bac58753aff67d5a1cce40000000000000000000000000000000006d1aa852572a756019df2a77ed4fccdfeb401409c08025930fefd0a0266531a94eddad1188d6dce6a9b26ca118cd3d200000000000000000000000000000000189d7e92a192b8872ba245d2d7fba9f70922345d05d395d6a20245b4c1015f6828050626457a65f2334d3a1ac8018992000000000000000000000000000000000363297d59fecbbacf7ec9cc9ba49d9565c5090188e9ab9ce422cbe97aa98bb035a28b2f5eeb6ccfe471d3d541572aea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001068bcf6ec709042fa31b6e478b30c81fdb5e33233c7d2adf85c7aadb8702556091098318379c2f58a3e88a425ccd05f0000000000000000000000000000000004ac71370378f28d54ca43fb2d03c9e7fbbef33a73e623fdab3a4212f0a6e000f92b72c294bc8e57428ef28c7465b35e00000000000000000000000000000000049d338042bc91f54422838b9cb86ee9d10f36955d88c0cfc1ee50b81a46feac0a5c997955ba33aaa8b7696c8c613478000000000000000000000000000000000dfad4992b9a6defadae6eab9e12ade725b4bcc9bb801a6fccf593862a5a723a8c672a42d8828e4da701de93ec4f03441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100fc9e940fc569e9631bbe389ac999dfa7990481308f9b992e5bdff872c2ccf8af7b0235c7e33b6824c31f91aebe93100000000000000000000000000000000123e1e5e5c7483564bee4362659c66b9811f02f8907d877004a2c30f80279026b0f00f333f5948c8a4542014d452b41d00000000000000000000000000000000159d0f525998d58716efaabea9853629b471133b24a2829ba29fd31c75b981d73f15f58a5e44c37470db2e7ee26beb5800000000000000000000000000000000199304bc110ca16482e5833be1d8c3d7e55b12adf2b89cbf14b9c1c75d34fbeee1beda17b8cc5af49658efca25fc0ef21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166f3360b936c172bf49d8b61beebd8b56a436c04c91d63d351a6d94be9a209aabf9b41a82d8e1bb942e8bf8d104c1930000000000000000000000000000000010c3dea2e35624b07df35f45f5dc199f8b4078e3a86dfdeba72e2b8be4246be4f8cefcde2ac1d0989e2eeef275c9e240000000000000000000000000000000000365696b2c3eb56f2388eadf9c473781b69c53f89b80e9bb4635ac209b3cae58fa090b7df45016aaca67a1052ff9da32000000000000000000000000000000000e869c2987fb7370767816bc4f7fd4ff559b1ee44ce1687f0048c31103c6adbc1c63d42d12b59fe844abc693ad49abfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cb6e0dad157a5ac2718ef700131b8cc85509f7d2b899b7686779e8d4607026bbcc4e305ed46a827c331114a15d745900000000000000000000000000000000189e7c222456eccbe6497961098d58c42de91f2273643755c186830c987191b241d48fc20168a0594906f0eaee41f5a40000000000000000000000000000000008dba00bd1a0df7f979297d2807059d58326a95c5c4fd543a051d030a74e79b41ecf00717f5d73433942dc55a0bd5c62000000000000000000000000000000001065e83484accec90906e206f1bb88d70fcabda7c3779fedefa8d39135d650d3ffab980d883c6032102defc698b9f1bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b41fef828be98119897f15c380decc81aa6ecda619c44e782289e86eb6ca396016dbe55c426ccd238c0bfb0cd9f67f0000000000000000000000000000000015ff69a1079e09bc20f85eb30961a85eca011475de021c806ac4b4a5a9c0a0feca5fec9e865f9d10656b7e7dd641da320000000000000000000000000000000015ff7a1c0e45bc1c60ceae370e74f217fe4c135906f278ec77620bab39b8d4a52bed8710d362b5e8c6683e50909364c0000000000000000000000000000000000c3f599b48fc3c39de3a9eeeb87e3013383354aa951ded0a6638bd1041c6bda1cc5cb26c6b6fcc8d285fdbead22535481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045b61660d47d114f18f40ca88e045701c4db0aa6ea45e76e2b640015bd5849c82d92c78ebfe25d481ba3cfa388d0c74000000000000000000000000000000000f1f2dfbddc073d1c6df10c2eaf9b07487d70bcf83ee34aa91f49619ca0f4b3642ddb8a43146fd0145c9ca6c7c30281a0000000000000000000000000000000009a785d47073a0dd21ec43ccb873368ef5e0289c497f79203a6eba07eba478e6c1439f4381060f5b025aa136bbb2c9c3000000000000000000000000000000000298f7a3faa5a0be707257f0315a950401080b8299c3e2d8fe716c6ac9217d78473c8f357a5dddca492ef1c677d16ef91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cb599845b6155dfdeca1e896931dcc9e48fdb467b098167fac418b5b1b2deff444cc62a339107ec7196b1b9f01fd06000000000000000000000000000000000fbbd0c1e32c0966c42a6adaffbba039db93e09a76470e964e180042bc615729ec1c22a4df40613eacc2f10bba69e1960000000000000000000000000000000001ee478625197a157e3672e05f2e374c81bcff8b1602a4393fca765d98f6e4d655bb2155a7ccf49e42a04260006c7f65000000000000000000000000000000001345f35ed240ed76b6fbc11d59579c35d72bd17f46f2345761b8c71e10c066fcc1f66ec4534e63b0e881b54343733aea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fe304725c729db1c4c1a211658abc844de913b3d6c9298b67f52254d644a211b7468e30256658d8e8f38abbbeb7a3b000000000000000000000000000000000ac59f7fc9967d0baeefb368cf29c5315c2e54b416131e89fc7621065423e79a3932c7ff648fe94f578add1a5573cd6400000000000000000000000000000000199da56d17e8a859f4efb9e4a3b6056be11c2b14f3bafee828b99e11b05d3638eb706e6c00fdd3faaa13878afbca9c8e0000000000000000000000000000000005d3aaab68949d3cc3c14ea18496b6a6053b59f86f9dc50a7fd1daa5e5357669fab91c25a1cddd86cddd8c2a611834fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069d6b32fc6bcbc5ca5cdf4416eb76d8f4710389501900d2fcd2c35a9224d66e1917655e8a64372a40f33f857220e3c70000000000000000000000000000000002277c1091add44571d3b5f60041807b3621079464344b6733c91588f6f778cfc16d1716b94443b5dbf837d5e9b372c100000000000000000000000000000000040bfc7ceae02a883374d2736a94f5d2746b8f208615e8e7ce26d98d954ab5ede7f2dae2b4a209a6f26ce8623f56417a0000000000000000000000000000000015a3327bc495ffb0301ccbc51a16fed7da2bb7a53bc39031d693fdb457d134170cfcb2e08aee757e3f1d857bb4a98d7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ecef1018565e58c7a7537797e6d3e08b53868f10c082a593c8aa459683ec1c34accaf1a6641c74c68960d04efb028d000000000000000000000000000000000cceb7b2e914ce8b2a3243c0d7a2d2a03bf26f6530f44ae02c5984653d5ebd8c7db83c1df6bd250502f1a1144a2127d300000000000000000000000000000000079a6da4ab24946500335f7ba30e604dbac078c19a81f40ba2133d3182aad8ed242b61b62024e67c7eadec4527fc40d60000000000000000000000000000000018f8be9033e761ffe9101da1e5db330ec7aef9c4dec87d69b801d39e5d5aeeb1fdf593d749e74bcce799ca885108ac671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182fce21d076888bd5926c9e60a45d2476b8e4675454545a0d7a39cccf85270530e158508e7add4433aa51862f1e3f800000000000000000000000000000000007eb465241c5ced98645bc7334941376a492f32d23d8f9111830c658bed22cb0ab03e0359947b13ca605594a0b2e02f000000000000000000000000000000000117127e51f4fc17b37aa9dd4c5af6c5424c436a0c7bacc70255c5908edb7ee3e09e3f5b337f55878debe52fb099b5a050000000000000000000000000000000006793a788a2697d792f8ad18430713bda8fed6450952b01091bd2119b28a7ba09f94457fbbbfc0daba4351176456de6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d91a947c9f80f8ddbebbe6e9a4b519090f8916667112a782814dbfc4ce233331c73fcf6b9c4c3d66025009362d2590000000000000000000000000000000005c2548ce07194ca016ffba12b58b4e1a93f9c073fb82eb8db441a7bb88a25ed624073cb54bea44a52032463cae18a5f0000000000000000000000000000000010bd2254d04f03c6913d92b9e0df8c581a9c2c6874909440d3591fb82ad95cdbddeb8cc8d43317b47109d3f62ddc0420000000000000000000000000000000000885f665b0105787b484829e469008ebd2afa4a414c0c130663f1bee92c24ad58d590f3bc2352a220a3c2d8f1c17144f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c5b483cb4b8489eac6cd02d242b017085e16653b6239d247eb27d5e8dfd8668ed22d7ba2d53aa5891c5090e081f0ef0000000000000000000000000000000013f732b8c13b77c42dd118bd051314e8e30147922fccc7be7c2b3f4af4d09b8fd74018f7ed0c4e114bce804fb5b7272b000000000000000000000000000000001697d7f748e3f4398e19cc7eed5ac2efd02019ffd363e07a7c099796535b220d6fe0f2bee53bf76759724b75824fec110000000000000000000000000000000016ff3be41145787d05b25ed74d951fbf48cc3787279e74a0627d4a7d67909d3657118bef4acd08dbabda5235a7d95c321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ef6ed9c1ab4caea80f4da22f128f61a1d45ac07a4fd4617eb2a0c89f4f3baaa613a58e635fc214e38158a88221193e00000000000000000000000000000000136216269dfa5e67bd6e037dd199f286ca71cd1439aabdf765f534d31f6a1a6b033b47607e0c418d7ce3e6289832269100000000000000000000000000000000065eaf4d47df87c637b8b3e2b5c0099dcd91dcbe3b3ecab6ee798e270eab1d0dd1b31f0db989d4e6dd74c048c3d5aa8a000000000000000000000000000000000ee25067233cfb1f191f543ebb28bee671fe5e49f3c05e3ef37f2ee82d99f6fc5b55975f19f03aba359e670e32d8d0391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f125f528fe6f5be6550fc203ad7e72dd4db72b1ce8c92e8a358dcdf74135b7edb97a4e40938440aba4406b6d5be92720000000000000000000000000000000009d7856bad35f707bf021a795a338af413c2d63b558aececd15fc534b2ad9532329cee8f577c4e31eb96fe0746effebd0000000000000000000000000000000014753e6916318e366cf03e535341996657d8e0d35999dee3f5160dedf10cd96d60371a2bd31c6d88e67356f70151e91d0000000000000000000000000000000012ff8be90144c09c435cd5aedbc34f2b649855d3ad31e2c7e08cdc61a23ee0badbcdc0384bbf3820a64953f45a0efa031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a8ac1b08de2c765039043a9a2f0a0ae5093cc6a4cf42245a06da09c4081f29d0ef91db8f26688ae7e5466032963b990000000000000000000000000000000013bddbbb3384ecd7917cffc7615444c288650c7b78b00430d04434cfbf77a6dc7bb4973eb4a228a0e63b5b03b8aed428000000000000000000000000000000001631cc8c5ad7af65e58d9bbac4affce7769c7aecbf19002906b830ffd88cdf21204e357def9375eafe9634118e9283230000000000000000000000000000000008d07215ba7c04ec32622b15b665b93ad9243ee3f5cdfe9dfad648b3d134cd307f6469cd2b9b1aa1cd20c5884621f2ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e486c3fb3fb3d4fa6258d08c0b7caf52e2996a27a42aab81ab9c828160b3620de313e0599cd7a0c9139cc8ea4b6e77e000000000000000000000000000000000e637bc6c98dc20cd86f343fcee3a86c14fefab8e8b5a1dbbd256b4f7b2f11204a6ac879f066f8ed6cb060a265a33e470000000000000000000000000000000017de8da98536d6efb5022e6e6063077e03950767f95285bc8bc7b74de7149f4c5e94212879fe3603f5d1bd757f914e4d000000000000000000000000000000000ddfebe58bdef6be0f54e18adcdd79d09c63df4e7b5c7e7707f2511780473abd4103523be4452bf3701db4e788635aeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011451868f0d217f629a090c4a8463998437677d904b869e5e5f1aa41187546f80e1cb2fb1659591bead773cfa0fbc6f300000000000000000000000000000000029dff210f37540248a22387ef3c43da6eb4583958a37fb23648cb642570901874c5fca27d9a8733a698ec9f19fde32b000000000000000000000000000000001130b8e8493166f5895a6f682f4b2137196d662b7146b046e06bbbddb12689fa652960f2ab7c772d34c18f151e37ff8700000000000000000000000000000000058847782f9c5fbb3abf93a5541866ec2eadc9e6e9f0421c294bc92127d8391a70fe4ebba64fbbaf4bbb7542176547cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ed4618558db5815033acace98338a9ca114a0c4a58f0643de71bb412ef66aa10158ffd543469259cb1c6f7a861c5970000000000000000000000000000000004bd2b1ce3ec73218556c9a341e8a621e256f0a8551473d74f48bc41172377eccaba85ecf1d16663a902bd3471da091500000000000000000000000000000000180024250a23278190c87f4b7cd471c2d685c88d3d1996ea9c7f9476d6649cc91dacbe107d895a7eeea18dd64a1dff3d0000000000000000000000000000000006028894c51ee25f96adf7d1f3c828cf844196bee002b8ce05c33abda3ff977a424c74e36c18aafb3847671e8ceb102a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e0e87fd33d616efc15934e87ab2a2971926e36fdd5a3c1285d13ea693a37272281628350d62ee3acde27c1443908ae000000000000000000000000000000000aa3570f35fd5f81e055b90a01f611fc42d4fe2f84cad37fd7b2b60229bc1e9739f3870f1b8d421aeee846b6722196510000000000000000000000000000000007fdba171b5305cc946d6097b32a397c028b964d20f34b668f8fe999fc1165e712546cb61ae324f0d9c6cdef97dfbcda0000000000000000000000000000000009b0e76be2e962545ada81089ca729c7537692d96c4a924ab1dbda71a5b06162862a81203dde1e5ef542f191ff487aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a5564995ffc82c950b3bb4e4564a3f2ed08848865fcd45de2c6e2508e70eaea47fa933a383b1bf54f429eb31cc15dc0000000000000000000000000000000019681c3fa8e67edc98bae675e441decb3bc0497ebb487c7722ef3f447f22dfea59684fd01b65b8226eab3052601070b00000000000000000000000000000000012ca7b4534ddf8df0039097b98824c1433f47f2ade057c1717431f0484aeaf479bbddfe51ea0ce71ef6550186e66d55b000000000000000000000000000000000dca22f8d6feca38e0b7cc0a3357b305c98cc3769e28987bd910dd88e0e2a0c3e28df225e83554de8307b3a1361ce7421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014846b3cf2ea92ae0372b23f224304aa49af11883780a48fbc8414a8ea00620ef32c8fdc938c05cba51b4de629792b06000000000000000000000000000000000f23b95ccf2e44c71dbae29518cca6826e6128fa7979d95a753eb2d8bec165d489cf92448c8ad743620dd9116bf49659000000000000000000000000000000000019ff5ac47c9ed48033ad33aca786d7a52cd7d169c8623a260539608427b4bbebd61543c303df6a260cd884d5092b050000000000000000000000000000000003b1de62ac79445ba31203e219a0f60a238b21f9e498491919c075371228c616e32122bc912c8ffd0dc7f327119742dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151f65681e5bd0954a4b6afd23978983f0f15f6e728805ce3fd20c7b2a2842a9d636f22d807eaaa31b030bf1d8d67c850000000000000000000000000000000016b24f4fb6386dc6137ca2c019a9520dd40841ffb055c21033120f4279bad13a525ff1e8ce1bc6f1d258172488b49039000000000000000000000000000000000a485ecfde32027b1f02d2734d3d0dcf757224a08b184efcbaac1e016e599c49c494e3da5f8a02518859b5a0332fe9f4000000000000000000000000000000000b6752d929e91140706d7564b1a490aec47be82e7eeac93c9c91ca5e3ce472d4168421c3b0544e2da47133820fa01f281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077b55af1df16da0f7515d0590026879da498192e6a7071df3407e67010c0161f74e58eaa2162226282fb939fa8c309b0000000000000000000000000000000014e7e08d0a4f852ea8593f2330ca6d0876443777a0fb5412661d254825018f1ebbe922fdc608f8fcda72bfb461fcf0b70000000000000000000000000000000005eedc2f8e745a44214e36c6625fb5aaa83fd65241fb99120a43f5072fc4a3d838de4142af40c7b7edeac81435de740300000000000000000000000000000000187d0fa57ae0d0c5c300c58b818197a803aff8d37beee10d895970f7aaefd7e5fd343ede07e64f659ae76b1189631d361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000027ee2508cdcbc83477ce5f0c1c156a0fba981bf887553b4d938824c3d214cb24b4f058addbd1168c01e0da56d89673000000000000000000000000000000000718862216acdb39c9fbb046dc1919567818b45fd4bdb105a5269628085093b26a5daee54b8fb684a3f0efdc0a14b3d10000000000000000000000000000000005991444e1e2c3a8bbe251c043e5769f8b4bb5cb3a4a7635b4cfd981631a099f93f4e183d217ac791e09c38b0854024f0000000000000000000000000000000012a63930bdcd48751e52b97a4002a965472bca25af9d39c3e2e95b3751a383dcc836d026bda27092dd7b8e951dd7d9c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a4798d8553889b21e62c21ad2938193ed25cbfef1eb19b0658c84e80f37c8e8fd0d027949ec5afc670a4034edb1aba0000000000000000000000000000000007de1465cf4e827adfca882f38322885c64305909ff9bbf38249756af76de26cf5c0d31ef035db8783b9df4d3918aec70000000000000000000000000000000003b0a2a5c9458c8b22b5cd92623dfe2f34d3c9e33e03b3b0bbd3493621dd9f67a4baf61c3ff3d8914a00e7023a7c4815000000000000000000000000000000001726d680008a7c651f4d6f627639acfdb1c099bca6ce910cb55bfbaaa67214951acd245b0ecd3e9aec1e13aa358fa3f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154b0fbcacff55a4afe553eb168735008e50794ab436afd0c66135e234ce418b7cf5b2f514069f90977edea17163b4d600000000000000000000000000000000086a8056793c8555c43b1d42442c10342c2b8cea661c83e5e7f52d0fa4bb85968ab4a6ad94d42ecc5237ab076e2fe00a000000000000000000000000000000000b8d579293b1054463c61b1b7779ccbc2c03b08c4ab06064c4dca6ba99d7351993899f609dfa08460f5993d75651a43400000000000000000000000000000000058f18fb003b5c7e64a8b10fb8d97c047d74ac862802ff610d94b646dbed6def98ef817430228d04730bf61fc53e1a691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005285a0027a75801a12acc133182476b1fe6a1ee65408499fe5b1dad6aad66848b1965ae45b9e66ba6a0b061723efa110000000000000000000000000000000003d4ccc5b38612615b30d4e16b7f96dc4f38706f17a56043516dac4edc2329f1accd574d4539a88176eeeaefe16dd5c00000000000000000000000000000000014ee5fd0856a7f4dc525fe29f2507b5228722c04c136224438add5cd5fa353ed07bc6fd510e2809b54539a112f41deb50000000000000000000000000000000008793474513f0c93cf3007eaf8c94f0fa18c070e24be56c295f5c80b59318a798fbf8fa15a27a4e0f2ecf7c3140bee361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e8a2b63899d53c70d2641b9bea7221ee078cc8f4f4fc675d25b181b4b596f6d4cca45a487dab0373a9e1c5f9c680be000000000000000000000000000000000e8be53c79b90d6a41c55da1594c188b5bf503560ed6bd2d4b4c8f3831cf4896319960003c7e8f78f7f91d471f3569380000000000000000000000000000000013da69ea41c38b5e14978f1bf42a99d57023ad95922b78fd6dd5ed52bc15b91aaa2766f4becedfe195240d8c2236efe6000000000000000000000000000000000c0818da2dc99ddde67d3b8c6e31f1396c533c7d1fd34693107a8a969c1ec97936e25064ffd5314d16678bb44fb19e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150bb6f851ec10aff0aa158ec3683af344e27692fd9ce61ed0d23f0622a03b87c2497be8516b3772974ed39fd31009d7000000000000000000000000000000001501eda3bf9d458def5ba0d85fbf0e05b441ecc357fcebd0d14f07179a50d4073f547a1415016efd23fe7e20f0b7e79400000000000000000000000000000000002f0c1f2f5b93f4ab5226d9ae969944d66e8ce9f8679e60adee78b55de5e981f04310a4f24e6da9eebf86d6585596020000000000000000000000000000000004343d0f8397f63ef2f96c63d8128154ae1031b5c1cf0e7a8764a56a1ce7a3d4dc4d1b285b47e04e4fba1bc7183170fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e04d1812d8e6e8ad5446aaca4850947179fd81b3670565d2c798b1be39c542d1bdff65030658ec91ea1e8d987a6cd00000000000000000000000000000000018a93b641656ed2da5a9f6a5305c085a0b9c9a45c9869c98703746b738dc4203aa45db947a67323c6176ec27cdd74eea00000000000000000000000000000000005ea7fc32d63aa6d5d5b45d9deb7f1fa093e9c61e4474cd6904d358c8125481659ff33ff2acb83bf226d18f5f016bdd000000000000000000000000000000001185ee05f1e6f9e6de989eec90f6d0fd7758193bd3bfa40c1f00799eb599e0eecf91f6386feb2a19cbf6a4bea1aae4cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001911ea309315b34c220b753037f439936d02d89568e8d3c5890fd6c307675adcc98924c30e472c2f21af6ebc9a9bd1e4000000000000000000000000000000000a2570005ce6ac6bf7606e2642f4c6b7d756efb4bd453db709d47f3abfb87335452a1ac1247f13dc83bd8ce55f24ddf4000000000000000000000000000000000fe3ac2c4658095130414244a1b8ba88377493ecb92d33e2d96227d31420f8cd75cf553513b2b762c117ec9bf6c6519e0000000000000000000000000000000012b51455b8e2eee2c65f35865973b3a6422abb887efab4b44172c5f94963d79e0b3c36117c4bfbc01d2a38e907f2ea2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001835b8a330f182200a1af6a14753b80755370cbf3e2ca169772543b10f2f99b67a69892ded8ce882b99cfe6cf98e913100000000000000000000000000000000174deeff4c838748f322fbeb8765ae3f461fe901824e3e71d4fab4c9f5ddd4e68b8d8c22fb56ad79735486e963f2405700000000000000000000000000000000101f11f303abfef0597dcf554ce4e9e597127eee719594ebd0d96139e54541bb86bebac47eed9086dd78c1a8c4f9d98800000000000000000000000000000000145f3973aec7c38b2815c75323f9efb33424d26215c174460bbf1c3784525852943e351d721d1091164f95708fdad01a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1093c67adf571f9329ce8e5aafd8cd8dd813dbbc58ddb426b1b5cee3cd49d911079a1a56d1b9086fea56fa104902ce000000000000000000000000000000000b1c4fdd7d121163b6f5c30c87c895decba76f7ba7b3c6628fdac7e51ae5154498deea8c20644a9f13aba4edcfd15105000000000000000000000000000000000485dd49f9f7129e6127b78029ffca4ef83380f102dbf649d0b341fd7a465e7797e1636252bba6dfbdc3ae87d49f079a00000000000000000000000000000000131cde4a18f8cd0b88857717a241490ce8826938ed96754ffeadd5704002c9008d3bf02868e51b830be00c239230c8651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ba2e26d146be538e176d581d4a2b852046f08aaab3856398cc9c16a5c5bc808436f1b9f03f73ef1bbf3ca5398d5f4d00000000000000000000000000000000153742eeac8254b9973a5c6498a2c2e10b41ab3df3f15cc161e6e138d7c0a60d1176b6d4716b5d79c081cf543f00625f0000000000000000000000000000000016dea8dd5fb50a0414a13e6d8d7e909d3b7e96f5e131f2e312983e8402e3bb788d698f1c1f7fa70b33406adecc16a0cf000000000000000000000000000000000ce0921987f510a8c37de17c5b5aa7a531e4ce7cda101ad9c73c274788329f3555581008820470ddeca406e8e28b05a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e336e800d0fd36235586093f9620219e8559722bcd1e763160f181029acb4857e782a54cdd1d193681a96bb00ad278a000000000000000000000000000000000ffdb8b65ad621e42aa9e4b4bd1894b5046a8150cb73e4b24514e832598156f463d8f5f77c5db5580fc65e014348a84b000000000000000000000000000000000df3e1603856984356edfa26d14dbe26f2cb82195c0414ede41cea9d34fdd2c818d001b61bae751f2198e6430f5d3ad300000000000000000000000000000000093f8b217df491b4692f057a5f44a8d042b4b9fe53db11f086d9c0b9dc39728d7912a32341abeabab5b7a1051ef879a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000624dbb6e7da4983c43c0744c996481cd1aebd92a886256da9378948a47860eacd6e31e0640a19c24072899aa2c611aa0000000000000000000000000000000009d3c6d149b672a970b62c44bddfcdbb1661ce134f1d6e87b604d55e8910e00791c2973f14fbbfcbb3cf936c4814a3ac000000000000000000000000000000000b6a44dcc907446a1b8ef21153dcd1df6543231dddad1163073c34442ce85edd4c370796961c5748b6fdf822a8301ced000000000000000000000000000000000538b099aa287a524b87efe2ec96841be18831f3121c39c75fca9f9993eb0d4c6605e64c798ef2e17a14e6642247bbad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c518a751fc60f8cb331eb286b87c314853b71ca61ec9edc72658f96cd7786acb8fffed438f2969f04eb250443524289000000000000000000000000000000001372c1107bde7297cebd8d60123b6646b9a7b1051bcb7beeb272b07b22f1f634b7e18d0ec106c287b2fa91b7460220d80000000000000000000000000000000007ed1f811048b4fa52fe1c04dbc62b9c1c550b32dba824a2b061cd5f6d3f8a3fcb1e68aad20ff33d6bda5b4d7df2e314000000000000000000000000000000000ffa259ad9d606f24509ec338b98a9873c312dad7e2f8c399684a12e203cd78f71296ee602bfd68c56373815b31ca5681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e5f605b936f4feeb1098b6b3dd0b259b6280f936820cb31219db085d01f6d4e774660f65f6707fb082ac56acbb0fb10000000000000000000000000000000001bbd14776c5d4436a90b32cfaa6c0295a267760ea755fa0d4bd129aadba09a45d9502534ec02f9d96b056535be0b9c3000000000000000000000000000000000714408aa3ac01c2c3474dd6ae0464d51e0e9e288f984044971ce01b5900d4fada740dcf75dfb04f8d4923d1033aa0ca00000000000000000000000000000000053377371e22b1ddb94652ec17e17e90fdbf22b4d3db00bab0140e723898e683a8e921b518fefed37e755b4a4e8870741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010000d04ae001faa0a3564b66c4d174cedff410814fc661e3d58c0de2ec7572d52b60b00654185a6f76ffeafc02ec0b8000000000000000000000000000000000535df025e88e673efd55e750bf9a38e95bc7a0cbd22fa7671e0e659b82ef85a0cdf119a9721edf8969600897aad16890000000000000000000000000000000011fbecc80c37f00be295dc338911bf3b1d28015e7e90bcd3b5017e926aec352d3fd82ed8e4719e38f33cf657cbf7104a0000000000000000000000000000000014a00653278b1bda62541c2c7657874cd776278d81278750177328596d5234342011056c800a30341ced0df4b97883981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001104ecd145ca25a781046a69690b30dac5a81a71c87515e74ba19614e14a68df2780803fb8b7147581371ad37f357be500000000000000000000000000000000059ca2bf9007b391e5a6e7878816730cd620e08afc6caf0edefe540a7bf38fe4becae1407ab73a6226e801b0e6d06a7000000000000000000000000000000000123cff1ce16805cd2e54e6dd09821d1cac5d72d4e418575feea8324bc63dd268a52453034f539515114a166b1f0baab40000000000000000000000000000000006be06853d2313deb3b601fa8afd660aa29c1a381ac88e6021c4ac528ef60a07b417afa7f896570ff3940ffbd8ec6bee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000798f7b0e947891a511b950b5a67c78814d62c2c5cf558fadcac0aa2466006c0ea6ca4a086acc0d9f2ff2062409adf510000000000000000000000000000000002d2315395e64ab3a3709dfb0368484e21adccb0e64a0863fae2085946472b7f92f9aea494f0f5e316350b0060892948000000000000000000000000000000000548c41965554c24f1dd5f8193adb4b08a2b6ac9534e02d35bdce7f446ffc4d01f63d3bac174b0873c878f1d23709b710000000000000000000000000000000011c07e776d2e3d8744117ad3926678f266e4caca400b0414c4ce8ab03fb996267f1d0424a065baf0ef638493d25e985b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba0719277e7aad4284414cf07c82cf1d61cfecd25cb6c9092fbfb61c0508b5b5140cb539bff6c253b910ff8e07e41bf0000000000000000000000000000000015681628562ea0d7e74702813e15e28fbb0434fa54c5ad6833c942823c887bf6df5aae96486cdbb43e0babd876c3a2e20000000000000000000000000000000005e44624541b6e2933e107366661276dcfd2c4b9e324ba61020c9761e41d8715781b187cbbe5a5149faa4f881ad85c880000000000000000000000000000000017483a028cd64e65dd4dc35eacaed9bbd774ecbe6a9c18e56977fcf57286f06ca661950ada7c5af6803d846056386f161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001200a62fffb752ced0a376ae8bc2094499f660c2094eec9ee992184cf83431d7895bdf5e3d9a4e161d15331fbfc3bf93000000000000000000000000000000000fb1421b05bf1b57135e4ad03d41523ba116aafbe68a882c11135f01daf6496d7e5f3b0c0604e7b2ca148dd1b67d37d00000000000000000000000000000000000b141a990a43130110c0dde64235ad5c28e0a6f449deab2853860cd6824f98eca6e494b338eb7b8004e67244df9d29d000000000000000000000000000000000201b36256a2341fa22b18244d92e50bb3000929919ecef6d0c7578d8c77640cbc8ae0487a53e4f8190c7eed49192bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ec8afa397d83c38751b863761ffcd808d5fb12a8bf2a88e2e31dccd25f2fbb18254e40897bfdb2555ba6d19033888400000000000000000000000000000000062a18e095d22451a9bbcd9acdbc7279072df860acd5a268dfe6dffa86f4578038ca2faff70d16beae6ac92891cf331c000000000000000000000000000000000addad44968db4686208b9d7b931c28e46078983b55c8d50b1d006b387928e59a581d77d4d648c5f1318b741f32b6876000000000000000000000000000000000be82a49b884ef629e089fed23612985f5e684275f6cf0b04a8b3a050d0a5e0eab63a55099e48aba468d9712692a4e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a3f0bbef7d6857d47df9b0c4417cccb79fa270f6156c2a6bde400a3f3354d5ef5d1427ba49f941c2eb74a505a70fa70000000000000000000000000000000019f32b9bff59047894e83ec1ca60a361c5b747de2b260533cca16a58a75207b79939e1fec4544404bde69f9941a2096d0000000000000000000000000000000004824c114a7a3b110b002703acef48f91692adab97384918e49417e44aab2aa782e4eb9886e66d3ed89896d0f4402634000000000000000000000000000000000886be99cc60559febdf89a2844f82f7b1877e0d52f0b729c7ce8643c775b845c261420bc2c5918568c9f91b729a2ad91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094dfeb30a080a8132da0211782408cde294dbd9310d4619a08b750718d9359ec46ea92f364611c13f26b06be6635aa1000000000000000000000000000000000ab92fec8913e8d505ea83c99e9e2005ed0f344c05516ad9ba6abd2ec776c21be534196bef8aab146893b487f2d896cb00000000000000000000000000000000166d82400c9cd8ae8aac933c3f635a82572e2cb46178640b50abd21d84db9aca29c4323c40a32178f978b1b0589143f9000000000000000000000000000000001754fc023d49780e4f48fd42e61b62c2d4826dad2be65c3ee69f21b83101c7ca384fbcbf155480a99d3015744cf577061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b49ff9649278633b9386c342f55f3e08b9fb29972a4f3d274ee32c675cc18b7254a8f008ba94d47652b074e94d817600000000000000000000000000000000011e2682a363b1c3a8ae5832159967711a62c0ea16cbf2a3187117807a9c33c4c8d5a01a51652834805163c15246326c00000000000000000000000000000000063a34737682b06ef9324f8d0b67aac2d81cfee69a7317150854c8eba4850bdb7b592015a81d6e2ff1c2e954072d81740000000000000000000000000000000012440f5cb859efedced0b9022317f962983711ea5880424e2cd5b06484b1abc50608cdc5d202da14a9dd41027e7479621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cfebfede1d1e9281e22a97c63d3211d391b5fbf3e983f086ff21f4290e48e4a885aacc45e23c2abef01e5cc2f70a5d000000000000000000000000000000001925b00addf78c4f4b1161be6dc8e38a723eaac696bcacf977b6994823a9af52c1eabfb7568db4ecaa6646565f46a8eb000000000000000000000000000000000a46159616d391617559fa98db65d4df06d0d27739c93ec33a56dd622a4744442ff832b97466c07946dc00133fe3f69d000000000000000000000000000000000f243b7cd982d0e22d449d4cc898c496fa5ff9a49f60161e27dd82bbc73a96c1a43b721561807293e155a2eb8effdb171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047db7e40bc65e70ea3967c55958f5e472e58cda57d53adedbf910fb45f55aad5a14c03c3be38289c435fc767169257600000000000000000000000000000000068ba3db9da6c3bef087e3f9e6ace7a83a67d94d43a93824b064a8b61a11b3f03e3358b2d8e3aeff88ac9e3d9ac19ad1000000000000000000000000000000000ed52a27cc0bf47914191330aaabd04985331604ec614cf090c54935946f78e3ca60bfd6923674ba2b8e7c6e5d06a4b300000000000000000000000000000000112e10010bf7f5b6361a358a78f20080f7aca4daa9d43133ebde22c0386ecbfc6e954a9526466765764bcabdfb57d28b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a16af8202db60f9edba04ab21cc07f50eb784d8379808a7d03757fac35a46cc8bd78744fee49d3aa4704a53173fb44000000000000000000000000000000000da9870021b8c70a25e58a8355b6e79bfed812088756efdccbd079b1cefa0887f2a18045440fdf4e056bed91090a8398000000000000000000000000000000000a607a1996b03c75711331a27a13e26ec5c6c297869f9d83132c7cb7690fb4364c51cd066ce50c0244a97c59282e5857000000000000000000000000000000000f6ec39c4db9f398f02a38fe8948a65e7e29b8ad5e19a293c278e3c4838e725dea179fa71dfa9362a8074a33fc1b2e741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080ecadd67299ce3cbcea237b149db12f5ca6bcbc0e5ed3b47d758862df545cff830be94ce35e6ef02f78f65decd426a0000000000000000000000000000000000fecfa7681a39bf36b0f2f53789d8088bc5c2c28b263c9efb81c06d43d32b782170e61f4926df1857c1dbfca8f095a100000000000000000000000000000000198c9619c92e20a64faf201f3add85ec756c148a19f3cd6256fdec42bcfe43de8281675bff422993918a22dc75e1cded00000000000000000000000000000000101bd2fe482e6dd02a6a3c2a772b276b238e35fbde2fdc045bd14da171e770f72a25e36adb10ba499c39ca98c53ba0f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fb10c44e28693dd029a001433d135fe9660639ef55ce219b22115c622fea17f435909a78f81fbac7892b6025e3f5f600000000000000000000000000000000080857c80813bb00f125d418334a53feafb7c91700912b9c6a68f74a14b6e3390bd2b7bc74915245e0e4eb229a57f9cc000000000000000000000000000000001405e2b2ee36a65fbbcc8554780c3478f19c5c4d483ada8b0b62820c77d5dbd5367fae79c6aa1c95302535d14d392fe70000000000000000000000000000000006000db7012a30a41528fde8af185e42c6564c3c0b4f6d13be6ff81bb321d58939ddab0d68a14a9e1c0c0399948882301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ec938b24003e961cb597daf4f2f79090402c5a37fcd5cbabf9c28a19a68f7f919f56588fb0f44582e55fdbe5332dc700000000000000000000000000000000076beb5b3a6c353512e49c365e8ee9b007847a951366e4eb08ede898d6c9b933447f851476a2125edc9e9093d08d6d80000000000000000000000000000000000c3855f8edfb32fe59c85bff768d6c93dade8b6aee1d835df81b9dc6f30173f7213cf1439965b06dd575a852b330bafd0000000000000000000000000000000013b46e91182c997a9b55b5e68185bcee920e83db225de15a274c22c618958b8a4f945e7873e69ab8798bf4647640a0421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f296d079aadd7af995512224e26a93bfa01c5d898a04192c600290a5ff203e2655be1a1acf366a5251f2adb0f66d95000000000000000000000000000000000d0be753f8cc7b3e8fd1346a2abe4eca72a9a13ffdf6d36fa0c8b85e0209a7eb7e819a1d14785dad6d906d86542bec1a00000000000000000000000000000000022c53565dac049d98bfa351f02d62bf3d6977ba0ccf0ec1c93a82b7578786a4be045d30b7d4ad9310c885a5f5cde0260000000000000000000000000000000016e833f68a3175fa43ba6dea78f39b0da6bb163652cd21551fdce566ec8b0c1b6900a6ece8347064060d07fda119a68b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001303037e5dc432e448f9ff7ab3ef59507238dd8fda8c61b206726090dc6562ca2f1ae78cccd252d2cbd162d565e91aad0000000000000000000000000000000015cfe2c3bf760ebc8e44329e70571f80d839bf012a73fce7d44cd154ba6ca84a7987ba2d1a2e13dbb9450105c1e1a74d000000000000000000000000000000000d41ff84fc4e101c7041893d9e166a22ebec64d2a287b29fd5c6c2b15c947452366a649afc7afaadc1477ba3c570def3000000000000000000000000000000000f3c143e7f382a67bbb673143f5fe9ef05bc93915c5e683ab5c674d834329d7a4bbc86f9f725f268f59fa6cd79c765501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000769c0ab8072f03fb7c64d7ec9db0ab20196fcd9a3e6ba82b69b49e21a68c320b24b8efe9e43dee7f375ce0daf242b470000000000000000000000000000000008a30a5da46a0e00c03f209b7bb75b32f405e00d592046af2d9ff6cd06ee8ebd79c0e4f7182f18f83679c6a54363d44c000000000000000000000000000000001435037f20451a9f59acc08b00ffd8116f3da7cfb0fe13d9491b4ec755382458660e5d9b997e6a664f0ac77fcacf8bba000000000000000000000000000000000f78970698fdf47c5aa4c36670b7a95a18ada4ef44bd5cf5a563e7f60f5833a36eea1ff1673d73f7e7b788abd3d332941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001428e9cc62915f85cbd82fbb4e84c8f224d9cebc4bcf2a400882444831b6a3d32d7511285933c436dc0a4f0e45213111000000000000000000000000000000000ebd385c73d152a6e24bb67139834e3f2950a8cc7ab4dfa2ca5d050faaf4065930b48b29e3fe69d58f0eaf5e9739ac120000000000000000000000000000000014fc3c0a541e6253981eed9705721aeb965b89040a16c93e94ff985da0e0210c06a41313a9761b1e0cfd904e33a75563000000000000000000000000000000000d97f8c89b991f0d157c42d82f3db9810cb40482fb2c83bcfd3012ff5d031a2338bf55bb05de7fbff4414dc4ebc7800b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ae994375526327591ee21d6b070521704baceb7a23ef5fd42f8fd62182696ece2fb23d38e66dac53e776040e0d34d000000000000000000000000000000001293a72d784e26b49fa2c5bafacea2892bec04ee970bc2d8915813f10a197b8055fcf00d22a6265c0a284da3ee3ad461000000000000000000000000000000001999d54e9e475fd17313d58f8693e49856f1dc2bda6b2a7b35b1abc7c572911e2c635658f7c30a5be7660116037aeb2d000000000000000000000000000000000b0959db3feb0815a17cfa8baa889d8e8645c0431f189453df441bd83cde19978ab687652b80d32ec96207ebbe9e97261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028fab5fbfcc8b3e8c49b742d9d84d1ccfdaf543f0dfaba9303b086858e7f550e88148cd1342de76380fbac084f98b70000000000000000000000000000000000ac31a70f04565d57881cb9283ab48079b47dceda1a182d21b72b3a7ff48fb46a2a9878e367286376ba368ed686e00700000000000000000000000000000000000966b277a027346e818015080a8f3278afac6b501049e354fd31399ca17fa927bef5c919e759aafe31d9db633b9ca41000000000000000000000000000000000651c0ca6b07d5426413c5bd9be11d9cdd0a4fcc57d469681129a5c4d6cbcbd2d1489026bb85523217ac7a8cde86e37f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012d4156b4bf0b87b64d157a2a42daff0703b1b7f104ee679a8b16b17f4dbe24732f62e95373114735f729904318787c0000000000000000000000000000000006240ff98ffb41ef3984750591b67995208f5c6b96099a73370730dd310f79d382841c32ebe08ea7c0ca5a4e25b1854c0000000000000000000000000000000007904a97aa815fbc0b07c1b2c35b173313f87fcc24040b69f0f6ce8e0d9355b69c57ec25013ee591ed826c5e676f9b9f0000000000000000000000000000000015eafa3a9eb18375826a3cb86c4c8bdf201c12ba4bf08482dc78925ead18fd69ea7e53168696b1fb6b7d450c6857a2011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120ee461f7f44cd60c9567b19e93c1571fce77ca9f2564ba79470b1bbf527085eb519073f93b03501f47ebf4fb9d0f1e00000000000000000000000000000000033f8c64e2878a91acb28f1ab595d74a802194603b3bee8ac89f2d49b6ec8823b28ff13665a01795d57b03246b6fa690000000000000000000000000000000000d0af92e18fdb3f38d86f860bbd6dee233d30a69ed238ad308e9803962c7c8fa03b24e204da902e7839b6d03bff71d1c0000000000000000000000000000000002cb4fcd4d1706731c5d3f873235d63a1b3f037401cc9fcfa7de5342dee5058bfb587c02648515f4c79c00568993f50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000994dd5c22ef4a8a4818a219f959daaf4f010b9311dee31592b14a34498ea71af911abecc4f0169c99dc3f04d3d6333000000000000000000000000000000000bd79ea7b7a26c3ac6a565b1138e1089d27ea1f9f40c401e838d700d9c5282ef2d7dcc06df440844c867bb19118e53ff000000000000000000000000000000000d8cf04b9a4cf1e8fc07f434e759bc9d2240e53ef1a2d919d0b1c76ff105ed46be998d8398e9b41b0826a11c6031a1b800000000000000000000000000000000112053cd14453052e97c1197d3b9210a4f4788c47e0f13a26066ac2940295e3f73092d9d87003e463d810e0a11a638031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001598bf5da4c6299c2987f71b9c9410c0ce4debb3e6629f4ed5f1e7f81c52998eb874ced3bed3544986aaf277028f2c9b000000000000000000000000000000000050071b7400131a557086bd5cfbfa8f0a2297d59291a21172bce975f7f16e7adcd9412b19bfabab2233e41b02de56bc0000000000000000000000000000000008cca7310581ebfbbf9f5e8b80ba57283de8e5e5a55e3c1666052c0a5e9798faba884ce82d23d0416d36590508fddf5a000000000000000000000000000000000d38cc83d8c3deb05d467b8bcd22fc718ba215a05890f2a4d3db5fda1e3962068999c8c50d36ed8fce7cb24f4d0e1ec71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e015cc35f0b62efcecbf85d1f1cae8c9677ea0b9ff8b117dc4ef6784d9e9015f9b2c19fecfc1fde40322ed84860d990000000000000000000000000000000000cb2c5b4a6267c6ae9cc2b076604ef3a8cc83741e575ada79d49e191a1a83f23fef5276c3007cebf3afa9bedc13855900000000000000000000000000000000008343d7e1392bde7511d19c4cf43267a99e5148c74fe910cc9e477d5e8a49f70f2962a7ee544eca066736dace0f8258b0000000000000000000000000000000010e231d55ab70d9fa79098e3c572f79233301467c2f43cbb474edeefc70f8e19174573cf444d07b36512512f98488d8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000008629fd2f1aef6d9773be17fe9671d15c393701b4493ad8aad0c21a3ef3d4196c8df009d09250965f8562af6f2c448ab00000000000000000000000000000000190dcd8ae4a739c02c62f9100aae52735255bbb96b6557145cb306c40788307b2f831a23d3131e832179862500f106e900000000000000000000000000000000022e9591f2055cee7d31125d9043e6cb45b514efce76eebc58f11dc7055ce42022becfb86e2ecc092f886878696e6ed90000000000000000000000000000000006c5036f276b4b3a88e4144a848a57c931162aa20a684399387684e95ec0eb7c20c7ee1d6a96145bdc1a43d534b56554", "Name": "g2msm-512-jwasinger", - "Gas": 4008960, + "Gas": 6036480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011b0c313788c4e60520eadad1f3685a4581ea4a4594fabe5e9cd9a9eb19e6be56656421512c4d316b19d4086aba226500000000000000000000000000000000011b4b99dfac236e1212c87f4255da6104bb4ddb3ee1730f517eb6d53d9788b64d1318bad43effda15ae154c43771d03500000000000000000000000000000000029b0560d22293c6525d0e64077bb90f3755fa9d7c67d299224c39064f64c8caf1353ac7ed83b00cc63c982e248dda5c000000000000000000000000000000001081844e26fb8f937e56ecbbca277f8ad87f4ed24e3d57d2c4884ee10bf1dede7968bba2c73434cbb873ce1c2d2bb2a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054cb9a695a5c86c47b29473b23123a72206bb0d522d534beb06453d9cc6815f7a2c4bf63ac6090fa335aa6d391b8a43000000000000000000000000000000000f52a4cfdad49bf02c5ecf9664e33af45e717bb087d1707bdbff10be3f90f81768eeb7e45e426a2d5ad59eabc1c003af000000000000000000000000000000001652bb1e05bcdaac957b87166707bab0728e5c4d8fe288fdb86bcf2e3b89219b8ebe773990a1a0d8df6398b40b3cdf8b0000000000000000000000000000000017b8b43010f7ad716970939bd3a8e61bd73d93de4d8ce4ae3253091f2f1ea4c1ce7b5821e5e2982f90c5cf6b8dabaef61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3f52ccb76597b1909861f89518d59bf982951f7b21c52c7ff8bb78e49f1dd1390faa6a6c8f4615328e7585286ec4e7000000000000000000000000000000000e1933193f6ed7f6e243a84823efb3f4faa6be40ec95506950c5e479845d85e7f65f2469ca0d18d9f41d1d5fb228e4680000000000000000000000000000000006d9fe4034708a5d4ba1b74e1dff28a9a77971d8d1680dab413b7baca2a996a44d5d25d5504975ffd99d919ed420f06e00000000000000000000000000000000113715359f0c8d0175d1242007962d4bd4c1058d628226f69f52ce4ebfab8466afa45c53bc75a63a8b37fa2962b1f2f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b4c421c64e22fce3153793f03476b256fad36d42edd97638d8557b6258b0af40495136111a9b41bd558437d8222326000000000000000000000000000000000668c35d4f9ad37f6b3a3fb4c309c8de2b4f2c5cf3c48b4d490fd337d72df4059ef9b6a01847f6eedd5efbd79532644800000000000000000000000000000000063087722c41cc680f59541191c38fd9c716bb7b82cb2b654a32e4972241a4e35b503966e2ea75723a72e3ca6a260f1e0000000000000000000000000000000014e8c5334ed84d0ef98fc94be1efa631c64a5aa4ccb2950811ca0a108b77e3ca5122f2208943c6f07fafd8dd5fab06e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002ebcbdba6bf202df969c191a91fff9e84126588edfc0b14eddf044c013409f1deb95b36568f9def69cbf6d6e7dfb6f0000000000000000000000000000000015c33e391ff84248c925ec4810a59693bf1a62542ad4163a7b63c15440529713fbbb1de069ef869887d92917717efad7000000000000000000000000000000000a549924ec10abf35e1a854222aa8cfc903a8958917c8423ed777fc6f3e55403d6f165835806fd1f497fa2d6bc806485000000000000000000000000000000000d2a9293d373f242d0788a3a40b12cd17b4ada39589e92839c05154ef51c6c40dc94cfdaa21e7b5fa5a762e13228d9131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054dfff327423b18b418a39c24dca35189daec8a2253c8a2a46614ea45d837578e747e6f925a416f6d6819572903477a000000000000000000000000000000000e8743fee8e5447d5f2ac5c7fbe464b68b851632645c0b3673269fe87ec1debc81854d847cc2c5e0225917ec3546d14800000000000000000000000000000000078a1146f485142222269bac6f021e5ac318f92536d6db2f0bd6590d76345e9688496a2c7ed9d45090e43b9d7857af540000000000000000000000000000000019bc4932a07c037c6716c6e7495616373d37426c95f0d96d3ffc8b7908700de1b5a36fa67277f87c5f8c091a9de322221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008599c2fcc99d7efd655f590ece5e1b3a58d571245f7b63d48bd8f766f30103873981afc482f88012e06d3899206b737000000000000000000000000000000001922a85965903dc172dfe553331755684df947974d3a8939d0d4a6263db3cb0b41bc4a3c61932476f88d787c1f2518f60000000000000000000000000000000005180e5e9ab82b50daac72f2c3aac3433acffaeb8db96bf3e9fcd5b0225a6f550f27bcbc4f3fe249a96cede5455d593e00000000000000000000000000000000035bd07269262193b408d8768e87f7211e25f801b708b1d268caa5dfff380a2afa76dacbdca04c270cd9a079482aaffc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004314aa683db34da4b6eec837870a015456c1e8db4e46ac0fa48adb3de4d13a6e9d24e301841ae6a3e81f74561dd665c0000000000000000000000000000000004f14d246a646b09ae80051d0dbc9cd2b5759d86d19cdf4e9cb4ae94b077bc7f81fa09fe3a0e003e3dfa9f528ccc815600000000000000000000000000000000190c55d788da26dda1a1a188bf4a1988951824e31cd9ec1d076bab1c05c4e134d541cd48cafa0b7a0100009315cf89660000000000000000000000000000000017a01aac43217c9db71d8dfaca68b6a6eae3789c04fde4a0824a0077b02966c8e4b4f42e9a62c2a7de6dbbc3f28755f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000257e3df13541d4ec4eb6c136264c77b20f85e21a20005ada610e3b4a854b19b6434eda2d576dcc3f27ebfb7afe6282c000000000000000000000000000000000741fe5c535492fb3f0b37539045a6410be83e9d2502ab29f4d0ae4aa7b3bff074357a289813510f4f794aad957dc19d0000000000000000000000000000000002146dc9e0d0bad909737d7d3e947061331267f7b62c3b56d9150ef404f6b70287577be05d59ca9ff6edf23ba9f8ae4e00000000000000000000000000000000094c1876f5423974b04fb77234fa040f54dc931996d3e9073a639b03df82ae1df4afd53fd35ce8d79b13df722eefe6e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c05cf7db37aa0e7ec5a78a110e943b066817d226d63ed39b57cf182f2f02dd1737665ea05edbb000c7eabf7bcb67810000000000000000000000000000000018e9bf6260df1fefb5b3ed0110305ef1453115d602eda4dcce0c6c3fb8fa4e69d78a8f020bdf78fb7063ab89bc220aa600000000000000000000000000000000198c757619f789fd85753e78b4d83c12122adbe456010ab1a98ed3230d0cca77b31704b903816404c5d0278309576c690000000000000000000000000000000014a7bf8f118f46f0b354f90f999e23ea72cba1f1a3b217035beda12876b27613a81b7d279c6b563915c879dec32c4a071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047f301a329f20a66e9de0fac40d9ce43ce2c2e3dddecc21f4c0a14ff9d82b5a31146a26285922585b9f62a0df3e2a320000000000000000000000000000000016a58e3d8caa87160138964786dece59edfdaf204a7a023c2bff47cbd444b30ff8cfdcd194e4b23b5bf243250b99abb90000000000000000000000000000000002eb21d8c8ce36ca0d12fdfe8e591fadf399b61dd2bb2e79adba98824e385fe429458177102be237bae294d492e0579200000000000000000000000000000000077ac450ae8608d9c0550c6df0175a9a1becc8f785ba45a96471e901c4860dcd671270090452e0339d34e75091021e761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009befa3f21e4a42549daa43eebd6093ccc56bcc70f36ed840951e18dc41227cd5ddb94c301953f40905fa30ca6bc81ad0000000000000000000000000000000003547c1604a9e4e07cc27317be52d0a7a580fc9eb058c7d6b327357ff62adeb7bcf13299bbac73da41de0f3dea4763f500000000000000000000000000000000036904f0b220ba6168e1d9671470a53c958612e2949ba8e8cd23e8cf9276977c1bac8edeb600fa6dde4906205cc2afe9000000000000000000000000000000000792491c8866c279be0a740c3b1addbc979eefba1d7b95ce25768af822749d0d1251f38ed3c3846ae120d4b7c854b1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f5f1908b357005e4f757953082d598a24d5ed1ab4f0e087bcede2a09d764cd9aec500dd267cddb68368dd50616ec78000000000000000000000000000000000df42b815dba924ca86aed618a8639fa1340c1c166ff0038cefc431517f9191148bf1bf128cb5d2ef6ad3713cd40e2230000000000000000000000000000000017e7d1d0bf1e3e714f2d5133624602cc77d193b4a03ee99d9b4e3bad83f558c205849ea3b0e13e72a162f4c9a81f7caa00000000000000000000000000000000022392b0a5d83d3b69fa0ccdae7af9d490eb76d1a577b3d9625ee1c49ac5caefa9787e0f2ee355ff6c8e917511aa8bf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2a40210729417a699e48eb963c957d238bdcb54ecd2d8f1ab3c04077774199306f6e0b43d50d8ac565f0f8577c8cda000000000000000000000000000000000b524857d616a4b3c1e2fa5a0b4eac457fc9d50ac474c2789c4d856a2e9939319ff3a87840a5c8ea6954e0076f54b2b60000000000000000000000000000000016b7d0da5c058fcd32b224b598b6775fa77e50d071116839704cbe10b30e6cfca945526f1188cc6a58f8d64e8c5470ba0000000000000000000000000000000003fad7e14729f77e09e6575095485f709bd553c6166c705b00a16e89f8436fffde277390cda206ba9ffd5608cae1bc5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c5616c2f24bd1de048b41a7b890688dcbd1dab85690c817af8f1765b9b043300a2f377dcb80e496c0d0ce6f42e8d51000000000000000000000000000000000211d408ce694cd3e5adad31201d0d370e6fe2aefc7820e4d54bd8467431ccd1b49010f653402f7a781a277b6dbff4b00000000000000000000000000000000019d5baa76bcc1642f7e6522d13bf17c6ee0081a7f401c0312982e604438f9db0bb182f9c23a9084d833836bd70c1ae2800000000000000000000000000000000057ccecf7b7c099e1acf7f6df123a0dea258102c32641ac116b5ec033effbe319178dae3b35037518f3a931242eb80cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001d78e1da3bd442710c622789d29e94833a7e5bff88bd9af492e2a282aeafbb7ab2776fa2674da8ddc199e2ae35a5cb0000000000000000000000000000000014355df1d7cd9ec9eb0c0ffb045bc0096b7e1a54e6284f9f857bece09d7549031ef92b27855c1d07d2ad5b435a124a02000000000000000000000000000000000a468268d5af8aa11e04bbc5f0202b458cc2cc2147cbd36451855cd792df492eb74178cea9ad13436c9851ad10c9eadc0000000000000000000000000000000017f452b4f8c13a7613a29a15efab119148c6adcda63212252bce2f615543f307ac6221027792f6da85472138297b948d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e776a5779f5223ea00ebe7298cf83f99ee55ac49c3595735512ca7e8f0c32fd6973842257693468c4364a7041b07f6000000000000000000000000000000000c536e780a97e3dc52ccf424ab983085c1873dde4fc18dbfd23134bbbddf5ad023a373fc8c9b0e3751aefd79053fab34000000000000000000000000000000000389016c857850f90e0fb2570fe9c5dfced8c0af1c60311d509dc9b59f07fbfaf7954acd2b17f140f80bcb4ced35f8b00000000000000000000000000000000013e6bcfe7cf2dc06a9f281848a1d1c19d276ca2bf4cf60b4fa3dfc097ba5ee5e99056ee802490fb4cd51c836ab65d8721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024a1dc0bc3f7547705f08eb6bea518393ccb907ed45232b90f01c4533ec3887b7b18e886373e58cb9232ebcebcfe1770000000000000000000000000000000000410b2d23721ac77bba94713c0a5cb069a48ee8cacd10b8272fd91c4a16d9571ff74b2da47b84ba3e98c3a281c3a8620000000000000000000000000000000010fe420883c99179c351172adba5dac4dd410df42c4ecd56c502eb857f4d51fc69205e9029de79226257ad4cc557d67c000000000000000000000000000000000c32ac932d1101fcb2ecc23ddf2e481ccedeb31a11de4197ec14baba29afd57545d6b3175f2a18df384ac9501196d7bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122afa709f5cc5dcd006cf9af2eb0fc9f9675e77516d0c3ce9488b497ef4bd47b41fd8ffb618a18ae7e640851cae264b0000000000000000000000000000000014805a2c043290a53ee6d3d84d20987efd9e7147194059b57c59171984039ce4a306c6436b42a2fa0d2f489c282d9ac4000000000000000000000000000000000c42cc7b5dae0b06817b7cd567331cdae7f8b996d7a6a055e8829b78f20dcb90aa469fb88c0549684738b37f24caed490000000000000000000000000000000010cde6152b1ca69fc4a71cb53c7d33fef87d164f52705353ef254f76df6f5c4750e5af1784d9197e9b95c8ace44ae93b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c292f508462c38d4ffc391976ad18b86e89e551d169995269252f780d178febb3b2e939ecf1f4f00c8c16446c7a03000000000000000000000000000000000d67539b74aac48ca78cf7cf0065de74a692d6e802ec3959ec227a2febabf5b51b6b052e2448c7302502ba20ed722dd40000000000000000000000000000000018ebe9d93206e330560c9ae29b3df79b64b1cd7cbb84bff5d0f243dcc557e263a24df1761d6c4a5ad7fb6cf72fa7c3f900000000000000000000000000000000013af94d1d9ba772ab2ff59899680b41165f9944a6adc85209bb1ac2f59ee5f22a2a498d0b98aaee00d3f39900729dbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d3f34dffb58ab18291103bbe0c44581d88d932ac9db046e42adc2b74f9adb3a801b56d7fbf59fc201bc39267094a3a0000000000000000000000000000000009909e92441307c62032c11846dd94ba3bdeb79d5cd3860b7eb719412a06616a11d8dcf39a3e02744a3161c5563fecc30000000000000000000000000000000015ca1104d0d0584a4f6db38c31cf2f79b28c5067c2134c2463e2231b70b0640fe9153f68e080ba7afb51fdc61e6ba05f000000000000000000000000000000000ea43795f3c2fe2d5bfc3bf9d172efea82ca0a3c42bd60a612457f46ab847e1b60033157f49fea7ab2f067195472bc971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bd4394256b1a04ef0b69bce01f1736331ec4757ab9ce744f63610f5b1d8a754805483f9bc8470486b073465d004b440000000000000000000000000000000008b5652d8fe0ba4617aa000e29b199f2acb77bb2968a93c77797f3f27928f79b9e5e1db195185e66de6663173a6900a4000000000000000000000000000000000f8634fb757e5cfd173dc636f6929235bdf73ec8886881f14939aee72aa5b544b33427de72d1d741b5a46f861f4ae9eb0000000000000000000000000000000003bdadcbfea971a38e11ddb1df62ec1b761e3c86dbd1bb690f7e6ef3746c1bea47dc235d8a0ebea3063da2d27109d79c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001661b2af3297740cdad612d5ae8eaa640ad960db4fe74b7ee59c2100a7c4d2f3daec6eedfbcb581aa3871eba9af9a69b000000000000000000000000000000000f3054182e756f299e661f25a91e6dcc64e2d62de2321f2d056ee0f4c8b2a37e00a272ba000b4f65dbff34fc40c8cbf9000000000000000000000000000000001290de4784ebd023bdb2565b1bddf2203672d020cb6f8c808d4d8e117dffdcc7999b59a2ca3a744c9481ec5ab546ec79000000000000000000000000000000000407d338b8e1b27cf0d45293fba0d5d016304fcf69b6cef1bc26482eb84755114b67c7b6c3472b1bbaee38f4ae9afcef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a10b2298a6cbf67cecf71df8760f49a11a5a6a55a6fb7340f4081fd51681941a0d5f79794aa718a72d3c8ad8d4e90e0000000000000000000000000000000007d0c1d57d5679869b0232ca104d14916231a0e07eb09d269870b0d4df664878f5387b4a25bcf72989de5022189cf3c5000000000000000000000000000000000eb379aac9460add24ef081539b46418c4c810e9c91083975590d6bb9d1d7c4bdef418e7a46e9d6a26771ab385ecbe6c0000000000000000000000000000000012b8cf7b0c4268ab5d5c7e08b10e25f1cccb91655c961f21f117084f3436dabae1324b75422a29a44bb5d641babd97b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001363dfcdb7f0dbec0c2a265aa6532e66c5e7f8316fe29658f2b5f47dfbc7fc829e5ac3679beea66ead02611e0c4463bc0000000000000000000000000000000012b580d164f1fe47fef6edf43a8cd5aa323b87a146d098fd7017251f7ccb3707f4440503be3140ed71f6550d2abeea160000000000000000000000000000000011781f417c94a6f599ed6690321bd960ff934204361f148cdf6743ef175369708a7bb0d2d9d69c79f72a3961234d05080000000000000000000000000000000014222c251d59183b4af49760bb58766c5c9d3cad52307964b940571bcf9b54b9e82c9b60c17a60440e80ac70a960840f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e1f2f9e9c45524e52a46d6258320d19419b25921a75cd6138e7f406827cbce9769ce67b450e3c7c2dbc7ae81b7e1400000000000000000000000000000000015f3bb29b69cb7d911349392b2b17e8134cd54432fb59ca1566a7f12c5903276286a1ef528e82735ccfe7cee9839432f000000000000000000000000000000000d58c81652d25ac74578aeb22258b6efd65be4f73df56989c1e63c12c772f2c1efb1c738b44310976caf10dfb1cb4dbe00000000000000000000000000000000155b78aca4b8b2e52773ef29412e2080fa3e29f597e8945c86a2f21d08c8cf814b80a4ef1ee436039f047b9878df1cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090a260db5ed4dd9588b66909b974ed9010a5bf5e9fdf93aa06a805d402ce2aec0a47cb254275a598350c6e1ed0a62dd000000000000000000000000000000000514fd7abaa89c3999d01703a471f7285ae2b3868bd317c215176ff97f1dbc9c854304275153f363ea8440cf39dc3db400000000000000000000000000000000195546c56bae59fed1db1caa08912e0bca3ee3e5a7c152e2bbfa65b665a0cf99d494dc2bca026c44d44d11dcfc630b41000000000000000000000000000000000b4071b0109840fd1bfe6c15992965ea7cd590d59f2439cce10135069b4cce0bb48ce338f92857e4a12ba011273708641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010869dafcb30aaf22bfd4c5abf4aa45f375ae0ee854fa02bf48fbdda7bd8664df67f2ba4bfb95d43444acb3fcd5ca85f0000000000000000000000000000000009e5af86df74f8fb4c22f4d3e30e403075777510ad72f1e8575dff5a39d7d4e6326829744444556a6055c1f775b6ed2900000000000000000000000000000000155fd97236d2afb90c9483f6f2834501256cbab5c3a023bc3c661fc03f9307705d22f239c3e188d59ded071660e074f5000000000000000000000000000000000381a81a97755ae597451ec91e506b944d86fc16983debfd14ee890a9750c23813bd6d1ffc8f89e771cf664d9194ee631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156be6088e70212d268d0bf75eb51134ff35b005cbdcf8d954d88ba2f86122f6105ce6dbc3d2d417a938bf76e4354a7d000000000000000000000000000000000be4cb81bf15920d9516c510733a0d8a70a8aeab1b745eba3df85f76a20e75fc3cefb6918827f34e1222a2900bc20850000000000000000000000000000000000bc71ee969c4f361646718e379a0ad81bdebcd02d8f63a00b2aad166bec55314280a6b075f42c855d6f9dabaf74cb300000000000000000000000000000000000464bbc60408a3bbed72ed4a283307dd948c42005f4c5abc84912646a6e08a1e75624b997f548a404ac2e0f2f59319491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001675abe44e4a833e6727afbbcbec4670ae170745e9c70788d66371928e14fd1475b4fa504317dbbdb166b98fd0ba84c30000000000000000000000000000000018ba996bf2febc7b561ca5d24e78d47e930eb5a4896becd283e72eec0b2f17cd2de265535a01d98f9346f08f2eed371000000000000000000000000000000000057fcbdabb899ad458e0aee47ab3d563aa9c761956f05b9fed93158890d1c89f6d44bb8d915cd23faa5c86b81a8d5b3600000000000000000000000000000000032d09ea67932a901d4317e47834c3b891ced75b04a820546431ce2cd1f779ff238cb9fb34e7a93e32d8bf395fe728621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001229468a6bb1fcf705cb1c7745507f506af7da14fabc6720a7ae256589dc0e418b9904d32766451a1470b1b48d43730c0000000000000000000000000000000005dba5c5ed25666be7a90e2b5d8ff3ec0f7352f1495f2035a3208bd318586037ead089282f6918f60b8518cd8c99787b0000000000000000000000000000000002bb2345ac84e11231dcd43b7b2a974f71b3b35cb6672d30fdb787002d11c0fada61e869825bff24219eaed8fd1ab68b0000000000000000000000000000000006f9a4c1894b8eafb51d7c9b87c2ba832b9d3013457a5f0d69901f27a3adfb9c2d66fb5e8ae9fea730e075a5610134e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e8a192ceacc1a78e4a46967ce011498edfb9bd3e62e2348136ca030055ce89dcc6d9e6e1c2aefdb7482e735800173400000000000000000000000000000000105f6d597145e31a4bcf771ea2a8215c60608b8275d9efb3883c9f71b31ab4f047824a9d2e41ef31c2d7033ee58d511e00000000000000000000000000000000132b19a33e16ae59839c69ebc9edf9c7e583a5554c513bdbf177d0b905fd565ed1aa339464544d0a6993888f838c1eea000000000000000000000000000000000f0140c57a3415c4db34a264af2f7ca85f25d6307f22cf74c55c97c4d97c7defb25e6f7371e6c8fc73319fcb2a7976401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e366082f445c45b8e25ba492ad780f9aa4c9b26fc05bf5214766ac0c832e13527fdb7024a3fa6e144dee4a94285462a0000000000000000000000000000000010ba69a2a73c96ca62bdd1553414451cd1de7d48ddb4c137708dab3e7da22b6105cf30c52dc6ddf632d5c065ea041f64000000000000000000000000000000000764c54be883ae7026e362dcae6e05e3947b9d381de9c4715fbe5f0c71137d53bcef46f4b358e008ebb6400462d045a80000000000000000000000000000000019ecced2a915c6e3428fe5debb83582b37fa195cc5c6002b16fe035af14a3c61ffe6b3ab031c3062d21c9f086dc7e7721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d16e160b04fe6cd69f86c88ebe446f90403ede270f1eba60fc1121224ad7475c9550130dde9e8d96f5c492196e67be80000000000000000000000000000000012b97fb3bdf47c432f544e31aa73ec634a54e0fc345319f99037297c359dfe656e5028e8a13a65ee52fe33b8b1cb2d1f00000000000000000000000000000000068d4108621be8dd28b66995f9540252ab7dbb7d9d5594aea6e5ff7fe985da413da74c80aacb55c4fb8772e4d5cc1b9800000000000000000000000000000000079dbe7ec178962e85fbb98ccc9be5f41bea5f3599dc9c9cdc223662cca80074ef83cf8deda5c6bc96d5241a620d7c841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156953a513cb621948cc4afd37fd317f0e054679cae810b47249fa6d40a64b92baf0e651cc85e10a56d6368a2890b07c000000000000000000000000000000000eebccad4f99b480e297cb308ddf265cc5b654fe269aa18cf058317af40f05b94c7786f070012dc82803bb2f184fa9b7000000000000000000000000000000001981a0003b69c0af8dffca9e312609f5dc75a8814bede4e9137d0ff54c60afcb596652f08dd3e4312d0a38a9ac78f2dd00000000000000000000000000000000037612d6913e17b3b3557c0f8e8c4ebbe919fde3f552b7312ab6e2f1ca483ffbf8eced4d04ae3e9299906ba4ab9da2741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000460c0d5d5f0b43e30ceadd462ea274e786e8422dfdbfa410e43ece8452e0ebd66aa04eb6f49200932e3aaa9c926782900000000000000000000000000000000084ba030ac4cae39935d16fab8cd8eea78768720f27e065ee79f0a16670d3ecb94fbdee21d8dfa6f7f392747d36f5a69000000000000000000000000000000001753417c4bc941d0a468d8273251927aaf430611f18b840dc72b8e4838fac52ccd4a4f901117a6395bd571881e27efd4000000000000000000000000000000000720d7955ef2975be8c206ab045040a03cba4963ac3bad65bcd3b0c1e35b146f59e6879e78b5bf9cef6f16828ad8d56c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c17a9c57ebed95ffef219fd166c4c8e61021f3ecc5a6f95bc67799c24af329c3c9608f747a7db8a5d9e32356504522200000000000000000000000000000000054ff100ee9e7cae3778003ca8047c78a9caea26a12f4f5aaf09568d03571a2df637ba693b5366b4e6608382b6b81969000000000000000000000000000000000d50b0caf2f16e76faca3536dd05371e1c05b7f1e3b8a1ca58d6f97365299822b075888364cf6163e11ecaba828b6d970000000000000000000000000000000012fab04d7f13e27fbb3bff43f41dae46fb602797348713521d4758924c6746f1af4ef8445c9f969deae5e9766fc79acd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000332ae5f9be519465d4a83ac584635dafb5132afb07b52a6a20e92a7c01ffbe6a0bf44cd14e9e09b2842c7e356a4ae850000000000000000000000000000000010fc0bf3ac2390e7be17f3f7296b91c0359927a4a85099e085290b52ba7103a0eec509ea456c07d6391b88c7e7af93cb0000000000000000000000000000000009162a59cf32f37ce7254eea89307436ca7e8cd576b28049c4ed14b790403bc0fb87235b61a5652f3b2cd3882ea6fe7f0000000000000000000000000000000005ef225db533d5ac0fa33f29a6b776f5993c63892df47dc68f00fa8cb3d17f4934f8513f4a344e4058828a1f6e4007561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4006ee51138caeb6d4cfb7fbd828ab480cc50102cc331081959aec97a3d1ea6da11359e8279603dd57695b77c3e2220000000000000000000000000000000008f4bd4cc7c2161673f24b78d959d1aeb4ef38b504cce10c417ffa33b8ac207c89d634fcbd48907e4df4f434ed8c6f7e0000000000000000000000000000000017bdd87a4cd699817ab5005313e1d6a6ed22595834f26018b8b884d3e0836d1272d192c606c148d9214ebaeb56fd6e8e000000000000000000000000000000000ec7ca2feba55fd6ebcbd569dec9def55e95ab7fbd626db004f8e219a0940306a68b2536f32c58c1bc39248c2ceae1f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d05d89a2fb7af5c9e3248ca4ee3508cda574b862d2c77e2d1382f09e8b476dacc530030b80dd14b5a7e7de5cc43b7da000000000000000000000000000000000af62cf1a4313f9e1950a074725b52886107a2d83f6b8a5bf13d29537b0cceb44b855e643f7f1f22024e872cefd94fd00000000000000000000000000000000006771b6f9711c959ec639dc151e4549eb6c9e04b19cf6c3d7c3e931c41c9a38ccc63d8b7a78dfe60ddbf0727865a0ac50000000000000000000000000000000018241ab4442ad7dc01ad6872a1bd4a67352a1d4598d139e02bac607a239ef7bc220b8d279013dd866ffc0b7d599234fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000500edf138cee4937ec746f5d3b9c1035408b6490203fad14f74670ce1e2d86efc60ef879f4ad3675600af903560a88d000000000000000000000000000000000a2b476ce78fd98e05aa3044b5b0a28e1522065e49cd60df3091d2edafbd7c324a87e6e6ea57c6c6128118afec88d0b80000000000000000000000000000000005d1696646bc02832ece30eb72efc5cb81ade55ae3588c0eede1a47714fc093a9c1d6bc9176f228532f7c8ebb98f83800000000000000000000000000000000000d7b6c67782dcc2ec35490267e80864abbd4f89f0c6d1124c35327738617c434a7479e70125ed025677bcb6720e27d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8c8596336da232b706a17886c2b1169fd4e8edcdb1504bde8924617bdd2c306903effc0872b93f2702edcccabbd717000000000000000000000000000000000bce5e4b1ff568aa112b37275b96bf32854692af89fb28aaf4e72f541d9239ea910fdc429b5d40d3ad3086a284301770000000000000000000000000000000000d3cd438abcc1d2071408e4de1150ab63dd267ff5d9e14383df16f6f590c4187b2fa1547580ce2878f3af74ae1aae7130000000000000000000000000000000011fa1868cad43a3b20078c96090861f3fd6e964abdcb14c9895f1df9ff65f20be50e47d60a110d7f9ca9ff4c8db5fcc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001906e31af33349ca63bd6a10d1f9744d5298eeddd999615c4d18a9dfe4dd142256e9da657e2c2ddf153a1c0eb4e9d7e700000000000000000000000000000000146a890ad84c66c6263e6cdae7966795a3d3fe6baaab6d9dcb4bcace75504686a45d2bfbfaa290dfdac5254a750223ee000000000000000000000000000000000f4358a9282bc67ea0bbdb45763d9553f2aecf46f830747a08e7841c84cc059e8a6e0d832711f3553fdaa2bc59fa5e89000000000000000000000000000000000fa1fb11a793de883a97c33e1852c7bc676b65452c0de6883fb8fddba8dbc607ec81a715e1ad5774524ec682022aa9371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e03836c60a3cfead50ad0603865b6280b5409293b4a154d56e60308a30f8df3c90d5a92ce8a1a9cd10f3e9904c679100000000000000000000000000000000003a9a6706f02a677d45c87b6e0a81cce2cad32af32623e9b6f479d1094357a04231a20b08657ff07bb79d3f58853756000000000000000000000000000000000aa9d339a4d17f370c2f66bbb0e9a56d4395955c63d8ffa95bee8b890c7df037399f91308cb0af610c6ec46f22161d070000000000000000000000000000000009762ebf13bee4711b9bf94be2d62d53a5393ce033f6e70273177199a059e83a4d7621a1b05bc04ccbb8427f93a52e7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073db19c240fada52a067d45d4108e07ee2c951a6272b529d2429f03b7cc33650e6d426a104e60510b5571d12a841510000000000000000000000000000000000b1143f24f3e6c757f5709590c2df88afe089735ef17962650c4244aaa9765c05bc77afd93dd8564215f80d99f5825550000000000000000000000000000000011b4360e64f0a6d45865f8dffa32d42b34168c5cc16bc4baa209e44b99ac0ece9856231c59e9aecf873cff4f547e2761000000000000000000000000000000000f8907d7c23ac7e80af23f661ec22eef8ed79c3e73ea762edae9eab0bcde5843da1fd17a239d23579332a84b53dd2a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017cbc6966fdc577914413cc3fc3498f402e58d93ec0693f831b557c62c2fa1ab3d0ef5f0f13466a270fa67768665b5a000000000000000000000000000000000f33e99fdca45494a658c5c60c917ffd61e523281cc2d4d3dbee78f8d38c7e4f481193c5427e702b7b96341e543e0be000000000000000000000000000000000032a22641b45ca6ecf99bd3edf7155bc56acd971fbcaa3a638dfca070687e3ce3c58e0a5be1eefa7cb2720abc9016ccd0000000000000000000000000000000004ad230c32102ad6457a63ef85ee624acb83d799435c80ad5d8f0be16474f42178ef4a104783d9a1be73e6596aeaf8d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e61ab298954f3b737ea23a9aef44661bf6f42d8e0b9906576ed786a30c9fe42fdd835af8b5fcf596fe5ca074fa76ca400000000000000000000000000000000015f79924291d107130d8da6e23104b17229fb8cb903f718c9331f4f044a07459159b3b13afddb9c212c97e7fdda63370000000000000000000000000000000005fe913d8e9546eecfafb015a288baf36bac413b640f96af607dbad70cfceeb6e4439203f5af2457b0aec1fd40b004b0000000000000000000000000000000001055b5d4162b18bd2bfa1decf2b1bc8145bf83c77938e130fa666b23408f3e7c46a172b30188cefe66d6e3b8e84ba3aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c1c99dc30b914759d98613d78f857aaabcc233e8b5c2b2167e391fea479d34b059574b9ba68f565643fbd4b178818300000000000000000000000000000000084dd3cae520eda2cb8a398c3e34a5dd5d1f790c7f9728d13788b3caf776b8eadf06760f89a29151689c94dfe8fbd1a000000000000000000000000000000000153ea85bb9c51e6aeb49c6b2f2d95cb27f3d58769d98ecc71d4bd0793ab0da0c893090c53f8af714a7f0659834616175000000000000000000000000000000000014f2b3c1511ba8ba23acfe3926dab3198cbc2cb5cfc76742ffe1d34a936cfd886a8ab621cd68aa161f45584344b2bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c589772f4b5eb3acd2643ab1dee70641ce76385fa4cf9c6582b4acaf8ae9a041889fd6a3f26a8187950bcc8d21ff3c2000000000000000000000000000000000c9a5e3b5e77fe4cdbe7c03f09fca02f150b3d65f63ca6eaa43e58e85ab96d44c2fef4da93d667f6a32c354c803b6d1100000000000000000000000000000000185ad8d9e7a7f214f5ebad350a67effedfa89157d84621974c6e28d09a9bfa1d36a32b09a925383be6154275da6cfe7400000000000000000000000000000000128c410094b18ef99ca51c293b40b6162d339197113f1de3ef1ded94f83af65b8d10283f8c9bbbe2aba87e4f9de358b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d4497b438e636884ebe0b0d181bd93815db97f2978df424804bcbfcb07d5562dea51424407268ba4cb3ebfcdbd4fb5000000000000000000000000000000000d08d7baa6cc3dde8c4f4dc725e2e86716a1a1c9ba14d156151bde0c77e233adc88ec4412ad77bf092b07a0ca3ff626e00000000000000000000000000000000017404580bfe227f75aa08dfce5b85c46fedfb06e16d2449e16cf9bc81238e2734131b7004882d0981762b68bed574eb0000000000000000000000000000000007b2674c1865836ef7026a8579e9ecbb39a5d7806fd92be31ad5af45f4e4372943a8f67dbf6333d15507feac08d20e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e011f3eff4ad27b3e1cac496ec95c6985c3d260172347f38e39e77aafb78c7ebba09c073e6bd0e3c8324b2bd9ba3a900000000000000000000000000000000117eedc3d1c9d06663a175fc891a42cc316785b1ba2406d703fd4bbd396fb9990963f264d9785ceaf1c26af2f731a19d000000000000000000000000000000000e22a6017880f63b2134dab76f1b27be918e0693923000f14ea5e0e8195c8b643d3a4589adff0dcb0a881d468e8a7a1f000000000000000000000000000000000abbd069a9f2918fe37fedb343166250d3fd7562f5e70893ec98750655cf1acd4742fbba0de008c3378df8316da519161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007692a0b182fbe1784e60b3ef86c7ca06ace852f26c9f32f49622f9844660ebdc6e43ca6ffc75c3f9f0ba8eb30625b9c000000000000000000000000000000000aafeb601fdef1f076bd027ca4720844bd1db6de7a48d182280da2f81f8dc00cd405765341c7f16a8873d19cfe2e1b8a000000000000000000000000000000000b7cbee977b33dbc59cf5148a913918c3e46482c859fbcaa2bccbe2327da10d0614dfd229646717cffdb2c3a5a2b099300000000000000000000000000000000015f5fff1e874e25648f9d7502e2f7cbe3a3dfed251b26b530c36e277e92da477b1e83c3589c41b1dd6310a94aadbf7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b9ae9122b92761a85741255fe7183c9b7b239d4b21bbd669de945d37295ecf862691d93a43a3d18e9854fbcd26bec0000000000000000000000000000000007bb1ad0ecc377426ec89a238d50b0f0ac28aa76e32fda1b5873984a1c1dcff80560b463f9889a6dda81ad70466c6d3e000000000000000000000000000000000da826d861474eb69903060a262f79eae4bbdd61adefa5cb53a5fc9735c7c66d726326fa07a5e2ea55e88d979e98a6ff00000000000000000000000000000000023b2d0cd06ba7f5ad356602a7177678d09b2e490aa5ed6ac57e08a1938578d0b7b5cbb87bdb875404169b630710f3221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb3b100d5ec3422df637970c18c9d8ca3da5966e158b25af12ccaf3dfe1af666e2f2570b91a967ead19f87f7cb92620000000000000000000000000000000000c4811526deabd94a7e837736f3588f3786f9690b3edd64c91e6da2baaef454acb258ab06b85b7594e467191b30e7c580000000000000000000000000000000019d99db246ebeeabee8383ff13660dc49befb6cab8bf254032216d726fcfbd61e35019233519fac46ec45a17b2928103000000000000000000000000000000000b216b7fda65e88c2ac675777dea28a52f23d9acfd05a855ba0e471f5d1276be184279ea1175dab504180d963ec1ad101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001513b6468bbcdb0eabbe0f4a53a70e21f37273503d4d437683f666dc118397c6055e07acc07dcd55b50345ddd79ebf4700000000000000000000000000000000003ef0709f2b15369a1e772665733e1e827f57ddc0da706eeab748954f5a9802de2b6906035195bf37a1751e1e26793400000000000000000000000000000000017a7c7622403061d29f4ddff05541a6dae8ce9b7be3c50ce9620e51d081dd34ff6a2cd51e78f87181f71ecd2d15877c00000000000000000000000000000000146665a1034e2b0d09beb5886a72849f3c27e46010caac57dff6b58388486ed49829a3c39385450be371da07ebb5d6791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050cb68ce51b25935935ae47c35d564a25e9a9a0a9fc391662ceea18724e663c2577c780f3bc44562bc5107f28330d82000000000000000000000000000000000ac4eaaf5cca3898fb11d70e591949522473b3b58a6ef89e377f7b391b960ef3a61244e97bd4cbd6826ef13257a4f01400000000000000000000000000000000079e3029622d7bf192a3b2453f642763ae28a9105ee56ece44950061745678846a9e9f89c379143ee69a0b53b457020000000000000000000000000000000000184775d86b8c5acf8f8fe4c9647d55aa33bbfa8b8ba61aa4c73a1c3523698160b2c5773d5bb03f135480c1fd25e2dd971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f22f2826da1fa1822d2cfda5e629d977357951dbe975432de71683c9142c43ca895279f187fb0fec08246cc0a71e970000000000000000000000000000000011bd86ea3a95c7436fb3b8d2e9b5912ea86ad236a17e49d86f3eba4b0768361edecdf9440f825e9faadbb6b97459e35e0000000000000000000000000000000018c672c269f91c84b5e0027d3dd974d6bc86b7c2dc0641e8001b8a3881b8eb092e767b63c234de0010933f2e08bc30bf00000000000000000000000000000000018cff72b5e5273f6577a3e3eb7d8fbfa642ff5f8101bbb35c594e69bc08e991bb8041d195f275c85056e57e33b1d0d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ffd7cd5ca0aa27e773a7191d6fc03586f14667f6c556c9d09013fb83f84cd97c7ef9013385c12bbcfd9051bb87f44200000000000000000000000000000000091c05ffb3b28cf8e1c163fbcd3139b0d5fc1d10293e4e2f25f994ea14bd08dc9ac21089d886b704b31f68dd7d3b5c7d0000000000000000000000000000000017c1595ee22590c96134a214a77472410ef609c1e1db9650ac4e1588042ae169128673a05bcf0c8ff2b12d06951d3466000000000000000000000000000000001833df4e5cc1048381445de8de3bfe1d4f241459288478456aaf34978f6a380399acaab868083ad8582185380436ab571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e47184b023d6d35c7ba9093dacb7571947828312ed459956ea2e415c29f5cfbe02b84f1ab648550b3eda24ba13b26c0000000000000000000000000000000013c73d6e310a56b196270406537d0159c86bfc5ff877c852711a7dcae18097278f68945055e0be6b778162e711ca1f43000000000000000000000000000000000acef48c90d7ee271a61d50b3d65aaa1b99ab2f65bf32fc7b7999a7953670507e1ccda97d8919f70148f511506345d660000000000000000000000000000000016acdb8da4193beaa227351df6a55b670210e2a7124e2366eb95214f3ec3e343b5f0205ff0f8c830bef4afc56e17c7311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001395439f868feb6745b64ab1ef355a41611aaacb2a213e6b897bfef3d3d8b8314b9bf12885d3925a4b1db1b5136cd1b9000000000000000000000000000000001400604da6f36e62e8beae30fe197604fb33ef0ba99735f9ddef4039bcb1828114b2953b565f3938aeab320620cef6de00000000000000000000000000000000026d84086887ebf4291ba87a11a30665a754765dbca74bb2f235e570595aa2d76e3d0bd61f0b095fe0f9808ef5b099fd00000000000000000000000000000000005a513a25e59fa12bb1c7ed8d89212485d5d01ea1625b4437745409360a3dc5b9e27a394e818c03117c361b67209b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce8569f08169de51a3706d984b1f4f0c08c4c916138db1be6a57e4e627e0706c41768fe3f49846af82afb43438cf898000000000000000000000000000000001498ef13205ade219aec50d0069338c4fa45bfd6bd689cae24e2dcd9003717a98084a8641d4e9ef30540b29757d252830000000000000000000000000000000005558096f859e13db6fe84869cd99ac7e420294eaae9e428114d32e3391a54b41a5cb200ab4b379a5c0189405ff2968b0000000000000000000000000000000010219ef05b58f74890372c8d3be53836bac20b30c46ed1a4c22f11ed5f019ab81078a4ee7ab1ecfb21f4c351136ae6a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f759777e731df2034c60d29674755f58a2f6092be37e1b02db33c1729c949c3867379bb6279b88c426e0c7cad0265450000000000000000000000000000000015d507d804e6597320433ef73fb505a67738e7d333c989e5e1f8fd61324d29905e5af3696a0c19c3109099d2800106e6000000000000000000000000000000000990339a2af7715452586d9df922d2ebc833fdf2d89d1940a643b11a3d8ff92221452ee3a89fd69c6f5e2a210e61d03d0000000000000000000000000000000014ecc0e4b804708ac7caca8cccc886c910e077875198ae0c2fb247abdf4c599d07437517681469ff8718da2fc628a4d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006efa923c0509e127066c2104122d9c40b24a338e7a3ddf0b60f09721b9f16533c91556fe01ec8d72fbd79186e9d52cf000000000000000000000000000000000278daaf62d08182cf2a0dbf0954aeba29febd95fdef299f38dca7c336495b3c2256d0611aecd5230455f24467d3d9b70000000000000000000000000000000007f9aef123f0bfa3c315fe544c4766e88e011cd9059969b3967a187cecf1c1227c04fafb15508911b927be3186eb941000000000000000000000000000000000051a36e77081f72706e3560ea51400892088bdc7b22b3bd5256a2230ed5b9c4e097dcc093e4162310d520b199af319c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e3eb9ff83995b7f95408097ea4ef531fa92c9523b3286d1df6699646046b9eea67dfe13f9ef9a2df28c7dda2e31d090000000000000000000000000000000011718dd69b25f7abff3395e9564a0b9b5f4a0c00ab4aeacb800055b615e32adc5036690bb186243743660800bfc3b640000000000000000000000000000000000f50a1f5b4f06613074f70ea562eb8a5f844f66a74068e9a2a11a73688424211542a84811bfeb71c6eb27d0b0ea65e1b0000000000000000000000000000000004a005a4d7130848c68b94af93d5fbefc7f6f8cb657931058ceba27724466d2e04579c88be18b77099bd738da6683ab21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d1dd1dd217a9cde2475e654be17f3a78d85890301c52982dd49706920b7b270cddb2c0bb3671c259a7f8c7ce85e64d0000000000000000000000000000000019c4e618261805f2b5d70a4ac68b00528ba923146b283bd2e17af9fc2b686afd41e658e67b5d704e8ab764c39efe70fb0000000000000000000000000000000018060aee01635d1b937d91ba72e51516353ec0025e3c57669643b00cc6b4b820bfb0b56938e039a53240c94266aa7b06000000000000000000000000000000000abc4cad0eb6f65d7fe0347e7985fc05d74fa937d874ff46794b826ff94445fa997f987ea52caa1e68a1858aa628b95f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030d154a0b134c03ebb9f336789c350903e6c12e775f825f47d24c919dda0e7dc9a722a41715458d87e12ea32de43c87000000000000000000000000000000000c518618c5fc3a8a2b8760d8220e04419d0ac338d6b6f9694bbed5343faa77f850e70475abacb2292ffccb3ffe224ce0000000000000000000000000000000000a0cfe9f3659319f97b3f3948e294b34b42d95dfb6e945dc7a7e03226b0a4146a231864c51c22d55ae811d123a64195300000000000000000000000000000000093a40b8b4643bdd94d7f1571c589d9f3935f09a458f9f16b272f40602e740f8152e45f553a65a7e6b7e3bb3f481dd091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001795f115c7945f0561c338361cee45305215f6c57381df27eb4116fefabdcad82768890122baf6ab393113c24ed7e0da0000000000000000000000000000000017f2cb441759b475eb760343aa2570470104d878240790beb992c747cef57b775c0990f205d5c3ff10c6e909ac25a0da0000000000000000000000000000000007ae540d092e8180a02ba99612ce7494532b7739ec1fd685206c2798d1e61fb04d659a5bcc3600901b559f453cd268c200000000000000000000000000000000125bc7b95f90f0820b39f9450f7e55a85eb743d14073fec50c8162efcbf957fcf664576a73f4f4b7d22ee69af7e209861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf0175f5e7c50e0773ee91508cc3253a95588c2f5a35627443ed50d9f784fa7d86e88ac909a7e2a741130c1aa5c8d95000000000000000000000000000000000179b4e50baa1fc88b34116367889b47c6060f53d62e5c5cbc14d191e2e6d856bf28fdf1a4775b5332950465112b08b3000000000000000000000000000000001449a97876659c4921b4c8d626e008ae6d03a6a015535a711182fefbe59794e1301226f471e10627fe1101e1099ec129000000000000000000000000000000000659493c9cbff875bd2bf2baf02a9496c9732037e6dc08f914b4af6d4485e4232fd9d0d6b560ae1b02546f0794880be01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000859262db2cdc304e4562cd623bbd46490ea59c3937638294f95ff13a2f9b273de03c5de72fd8e1e0fc4badeceff0bc000000000000000000000000000000000c8ed88f4fef993946d877c7507ed9ae1f918fc4cc9b850b8e0ed879e67ea62f46de6ac8a77df759fc89cf0c7ff3198900000000000000000000000000000000046fd12d8ab0927102ab263c49fb1274871e0195b3cfb2d634f11aa4baeb1965385a4ed64d77346505288a4f91a551b8000000000000000000000000000000000afa60724f687e94e1f248dd8bad2c038cafee52f5386d2b8ad8654d59e007127c8b6820ca2a04bbed69bb5434f3b5df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077418a3c46b379eaf47085e21007afffb658a4cf1dea497fdd27b19b69dccf7ab04ff11bfb9e48187a4b7adf056b7830000000000000000000000000000000003eb945cea67d1d5727c1aeb37433bbf15044806882de00b7fb9bb706f8ff9819345d61858e3b9aba336d5b26e630a6d000000000000000000000000000000000477570709fb0f57566649c3bcd126775b706d49dc4267738fc1afa92657dbbe3af9055e066be4ac01b98bb9404a11ea000000000000000000000000000000000d740cae77e960d513050112b469c84de9d0b108647fb8bf73c7e2bc85dc293b12ec1b95fd58594d0d45e52411ad144e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131c1f2006e29dca0ae2623128d37597261ba5dc652fecb77559882c9c21ea3ad87d2c3d982aababfd83cadbe2d1e348000000000000000000000000000000000aeef643a99ffecca76fa57914ba6fc87b3fb7914adde621f3f16c370375b575178c2c04bec0955323f9ce2b9d9e5db2000000000000000000000000000000000eee97728c17fd8cc4a14b75308496861232e73aae58db3fd6ab96aa5505c64cdbe8e71ed274cdcaaa0d62f1ff47f74d0000000000000000000000000000000011209b5c07cb451382e767805150d26c9d63b1197ea73231f8a0d95c934dbad06bf1d1ec5156e96724137d2a2e4536291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c7e83627dd9bcb4ca46b32cf79bdebd6d2ab4217f73fade21315a432fc516643239467a57aa035957cbf5eb89072ce00000000000000000000000000000000084c5e2fc847b36cfe3ce7b9fd0471be0c899a759ac435a5328fdf1c29350e293e17d2d9b8f293d435f65091480127310000000000000000000000000000000007d76123b68212141a30c75c013f8e410ea37bc879db5b8a75fffceac0c96bb56505191e2ca6e44c4f894d873847f38a00000000000000000000000000000000148d142cce37b830b7de5b38cd97326a5a90ec5391b0163daccfd7199a4127b31b1335492925b2b6fe576cc1712182511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d3c1d2f0f11f02edaa76c3e790e99f01f5a27df3177dee4a6853c9ac85c5af8d2306390b153ad57596fd1ba71aecb5000000000000000000000000000000000a2189b3dac8bb078c41ae74c8fa65d51191c8a441f621d6d942c8fafe1a420b3cbd7f5f5e44c638755b006adc98e1500000000000000000000000000000000006b760d7f6e3becb686b27ec56987190d0c3db3777ef532a7ebb7ab43b990aa148d210eec51a10662ce8727878eda19f0000000000000000000000000000000007c343fc7c677e6d96064875ed91fc76805a7108fd487534ef7dd1a5d84ec492a1062ca481b2e629977ba6aa173a6b581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058e7d62ce9ba970c64679541ae2be236feada2a97d87fe7744e632d7a16c52ffb75dda0af8f8bcdef489b6e8af154030000000000000000000000000000000015f2ba3723391e35b101653700f1e9ed07c4e7554ef2d4f3d2da90f655d3f2e9ab05b0d9eb7d3c37e45347d0a7ed0452000000000000000000000000000000001672f7465e171d0cae38da2ed21055cf9b546c492dac944740e2710d7e5bd2780937b969ac7b99871ddaa3beb99c9d98000000000000000000000000000000000c2d56b6ed9dcc38004c476cd8fe9ece8aaf09ebeb32ed5e41ceb05fb15fdaa92987cf2dd0bb7d1b688192f12d4beede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f8034bb38d294c61c33559c4226c5d8cb1325b46260e5bf840d2d2f2685de93c6df86a75b26194ab54e5f0d68b95fc000000000000000000000000000000000ee978d7c0b2e3e236b4867229cd4c887b58b5f723752f91a77c6f29dd3bc595d03dbd505718194da745755d7f9fb84400000000000000000000000000000000010d329dd25a76c4b978982bd015a73c1e3c0586f3ccf3bfa2df81e4adcdc51e13d34489e17808d30c36a57af58c332800000000000000000000000000000000013e96497276fdc44a087e6e1d62c0c3c04fc78f5233c4492ea7b9429b68e254a892a0b34886bb3abb3bdc516004e6371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121dd21b17baeac663e9792966d47a5d715e61041c6fe80c6ec186820413ada72ea12b955c053862d3f7773d83ec847e00000000000000000000000000000000010bf9f2343ab0e208a66824309ef6c51f512dcf8e1e22eecc9e7f56fcfca439d01894519630df9330f218bc87cdd5ad0000000000000000000000000000000013f86142e0281cd038aa57650fd59678de43e7f76ad5391bd0ed20848cda53c1cafc57f130cdaaab308257a4c19659ec0000000000000000000000000000000015da547eadc3d5a99eed8031f63d67c0809e02392a7ca2d28e1b3d94899065f7cfb8069960ac845262e12c83ae6156dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b0714339dad73a7de22f9fa0af58e1585d92abbcdf57d47b1f66c11f3ca3f6ffe903a7427f53be05260f61b819954c00000000000000000000000000000000141af443a4df61c5546c4949086e53596861c900637d3df286a8c68a7566973f073a482076478f18c3b612b2d88f9baa0000000000000000000000000000000009be71b461c07285c7103c92123f13889e6969b94875245bee78e9c98e1003173a698fa967f3a846a7f108a7eed739ac000000000000000000000000000000001562d1c1599a7a4310841e3f97c700643f4a111268cf1b9c989c1f7ca531cd650df67a5ae48dfd43bce0dd0d7f7adbb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000031939d812542c9ef30bd4f1c21e2aa3e33d494ec10617d05cc36757451628be03baea5fc51713a965c844d0c5edab900000000000000000000000000000000122e35986741489a38d97e4248413e5fdb3d887eff462712a27a30b4dd1a3480052497d758206a9760ae4384eac87fe200000000000000000000000000000000095abc9ba44ff55f6b81645ddafbf9f599558f864aec27058363489e4c263256623bf3a127c058c7bb713472efd70fd40000000000000000000000000000000012d06e65f40c4216cb077d5de93a40851fbba01b74fe7d196f5e32b6bc1b332c221242b84f1e9b34042e06d2b6c9e3ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001638baea78946107ec22952918913f87d3018e31378a51b0430c2bd2b1071f63b99c06ac7f4f9fa42555748b7a23b522000000000000000000000000000000000a298e52754fa6cc576a3b578c07fd9718e1aaac6a38d70fc913724af2e7a9b5786d556672f72360b36be598727767fc00000000000000000000000000000000142fce650aeffadde07e3979f7f0d0d22a8e9bf9572bca66182dc412310d23385bad9e2641e462aed90b779be79820b2000000000000000000000000000000001551f9235db2f36d114c1faab8fa3384dbe7c99f78d562f4269296a254346c9990075891fda5697c2c8e05a7282766c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014740f1a7b5eb588b656c234f0ac9f019c482e382e16309bbf1a2f89c360c06ccb5ab60c042e1b628104a886905ec40100000000000000000000000000000000164c2e7f7eda9e0db0074199a2a57f2b406f07008205bcd54dbf0934cc39d5a930f5eadd89a3dd2fd257f0c87f489c1900000000000000000000000000000000055db08413b3ee16a71a93e68eccdc09fe29f60760e69340243fb16c215dd58153ee160890db7f983a2cb5d9e27b3e18000000000000000000000000000000000bdac21c9ab4620ad96b62b2245b1aba6ada4798192358cb6869d950c646dfabd2717a81882c0a5b0b3599f3334cbe401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bc63b523e089395225098b4813c7c710895386428f7c50552036b01333da723c8a2bb4c79455804c3edf0fccea987f0000000000000000000000000000000007f85e66b03faaad161153a1eefbb515a926ba68416d523f8b54e3846a02f3f8d3ced29d5f2129e43f0a974abd362ff10000000000000000000000000000000016585a5da82e782612b97ef9d12dceb6556a437a26aa234889b68e06b950854666330210d751a59d281df4b4bc0a153400000000000000000000000000000000149a2887a0270c240075deb21c1703f2ab2a15496d172251c7daded0c0ccf55742d0d9171ae0f89afd0d168487eabf5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000852cf8a375f3d008cac0d19e9cb72bf5fc1c9aa5b0a3adb24c4f6628558928703860d381869acf14bc358b084e0310000000000000000000000000000000000d64b64983eb51e5a8c012ba571e5d832652fce1f99339a3143f4db0cb206186b5b7888b6914178fe4e5c8c3ddaf4d6700000000000000000000000000000000061019f3f06a4013f1e24356c19732937d4edd4e81beb934f74bbb0ad20c1e7bf85b106d13ca1f1fcb22a0e1889582260000000000000000000000000000000009b023fef413e9ac43f0f87de5a3abf1bfa246f8c415aa18e300e49831164db63c3fb957929e8548af07fcbf8ae698861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb5c7d4f467c24f80654f743a9f83225712ce63e00ba1a86114c86b04fff414ceaf24518c3e936ad444979e21ff381d00000000000000000000000000000000052b32da77e600b0f96b48db6679e6c8a8782cf16d7e86aeab87bbfcfd52f4beb18c2b71d904058063835ae00f2482c6000000000000000000000000000000001553f18e43b5ed0ef74f8f5ed87d30cbc95a0dd51138e9ce556d7bd6107c864d30d30a0701710b6c829236f1c0e003030000000000000000000000000000000014fcbb9cccacc2def9e49866a0f528bffb84cb58f88d852d2ae27c405c75aa28a0542cb7f24678072faff7b15869c04c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098a581ccb98321b916c2e995f960196235a4b806de94212135a02ae2a537a8bf7a58e39be7ecc678ebe1e3ac73f39aa000000000000000000000000000000000e11165ce3d64b3ee070caf89b4f016f43a3f48dd2f5007ba6ac6ff0ff7108015b65236a535798153e88356d4b77d96f0000000000000000000000000000000002136934ad93e33c5e22395ead8a7132c58231c7ee4ea82da55d79795c9e23ed8521f6234997453529c5d4829df3c9f90000000000000000000000000000000005f78cb942f25ac11adac9d2200d308e14f0640810a35b4963e3e75858f6384cf2e9f1e4491a192197299eba9df5126a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f691ab4955e5cce03d8068967abc194d348753a73209f15ba4cc5cbf3f825289f9dcefa659a739674714b08ea712a10000000000000000000000000000000012b3e9c5f4deff1b919d496c6e420bb22e28dad4c15c0f9c5ab9f17d6eefece81094e5fc42fffe7d78994becf63e3221000000000000000000000000000000000748fee3417c6939978ca6cba04cccbdca48dd1f95bd75fd88ad14191d92d218851c2c68105605fffc16f91f7540cfb10000000000000000000000000000000008b9ad7d833160ef1f56935e6382c43d04c0eb9a7949b5cecb4abf2b9bdc3def921c50ca6f2320053a88cd13536d2dc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016685084dace53c82ed44e49da76e0a13d87096422cdf4baf2d71d18c50de72b8af64f14f5cc6f1acc3fa5111408bb9a0000000000000000000000000000000017b59bf54a27e11a7add43a544d2d2355ae858212ba11ed9c77a0fde7522047cc4bcdbb40faabd80249e70de83169ac50000000000000000000000000000000003fabebbcaa3ce87dacf181b647663a66cb5d3958ac90d72daf10d3043fc249e773b5db09af4e771d4d1517c95d2945c00000000000000000000000000000000092625d8620a75cbd09b6e66bee32c597afafd8871734dd69874ffba53730208bbce11050bc204aef397b4e159ede8591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d708b455a03f86b396c70bf267a220168c7a6fcdb657517db9290d159b8bc33f496b2aa2f9cd0356822e00cbb65a840000000000000000000000000000000013196e82b77ba7386ac233535c3a953c25339131f22a6676b9678b3a9133690c765ad16b06f259b31bd6a86c84ce8a9b000000000000000000000000000000000e889e33c77bb11c674a2864fabcb9174901a333e58bd75b48648bdc870d12128ffedb7f222a9a3543cede121f48bc480000000000000000000000000000000006c84c529828fdce11084e75582aabe6b2bc173f4dab3d4410adbdedbdcd2b84835c32241ad344f1043fabbb9f94aed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137d1380c1f0ef858215734af63afefb588077a47543791a0133e90f33baa1cc71ab5f41cd477be04280068a63f0a63200000000000000000000000000000000187bf6045b561af33baa41772435a6e6323f95aeadd195659778841e2a7edff09fdc0158028eb9d62bb60e0f5d2907e90000000000000000000000000000000017b30e1355ad34111d5f7dba6c696ada76ac491f08040b405304b052766e38ecc9475a059357207e596756494f241597000000000000000000000000000000000cb2c01b4927a8726180c5986ea5561ba21d62f781f14f51f95f44479a669c5231c12e3acafcbdad38b2a0a55c9b47a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc703e60f9674a359346992e790078b49fb92bf32bc484f3295e6e73e1a417e2ed885e2fdc7f7286dc4d1839f0e59a50000000000000000000000000000000008d469bb9ddef72a7b90032b3ef2792cd367d2b3f43310270913b2a1c347f329cbcc8833cbcbee036e0ed58b394a64ab0000000000000000000000000000000009e5aa3df44e8817e5d62145aee1c5d769383698e4df692aad232b481de2e0409ac9ca3262c2dbbe7d89ea9c3e809b0400000000000000000000000000000000057f94ddf81a70d2569ff6dc8be4a4f82343a12c878c217fd3d21151645c73031af9458f4ec958a6faf82e4ef79f23ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006167413857edd62f44b21d23ec857228429cfba8a0e41115044080ea23c387b73cd15871a95f9a4c5f777623fd40c7300000000000000000000000000000000160fb4ee7d8fa231ca190ca3c0cfe685b65785282915cbb3afe2935cd2bee49da6150742945f2c37ab7bed4a15b42a240000000000000000000000000000000004468e5345e3b7e28c2ddff769cf421c7942fd1f5541b2cf47bf7a477159b1a080a2cd54da8815f91b3861522acd476700000000000000000000000000000000154a0846bef0146652b797d0b4e598ae1a8eff6e5b5034471eda1c650a56b6f0c2b97d38c5251f90ca93c090fa7e5b501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab3599f00b4a21f09628adaae8ac30108a6d062f709650c8322c77479c04ee589288f5fa3ae9a82ed02815ba2ba899a00000000000000000000000000000000176176cdd4845029f4cc6b5011bd490bbff7f6069a7a5d8fd8cb5069fb3a1b4cbc69c333c6d9e2aa89b139e1b65980190000000000000000000000000000000003b72a3133656b482dd7049bb544acd19924f1451dd86e32d3a7212249e67bc5177fcad037694ecd597ac86c66f274aa0000000000000000000000000000000002d655431dd3b29ddc096a4e664c23779aaad98e16dfa90df14f72903204c0c9f4f66e3992aeace3fa2338f74171263b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ede393b158fe5591f4da6a869143bbd2400365c04539cc12a559acf01e254c0d601a6a12544d636fcf7e3d3135c123c0000000000000000000000000000000011f97f10e4a8bc45322f426c97bd049ccb037a12f4c741ec33943404b300582af74f2e83d48bc9f10a313407b867721d000000000000000000000000000000001497ea1e46d7e4fe89a84763fe3e497a78b675630234a1f1ce3f60f958b42a6aaf0eb509aaa43b244d7ccb9a991c2e1f000000000000000000000000000000000a4198412821b04ba45de4d23c8a9a0c59e0920b7ec6549d75978f4e8f7739b98dbf5f33d7c4507bc47df61ff79a1d761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000053132dae59596dde08c45e7060d07e7f3797729c5b9cd0ecb8326fdc2d1c96d404caf10ee900d9d72c030c6fb648d0000000000000000000000000000000011c5e9d20b46e40418e06f3c3d4188699272c73464202f875951902cf32e9b9dc595d04a80946032352b66fe515fec30000000000000000000000000000000001751bafab5df35df8bd6c28191e88eb7249c42493d18afbe8d6ac7514b4084b7ad4dc49226dddee549622e3c685ae829000000000000000000000000000000000d0ef2be5955673aad69b717953297614ed9aa323541b459ee956b27cbe7728e10a894db3886eb94a75e76249f8429741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000aadac19becac10482a9038428ab74e0ad51016c6557230d51a9138085803970f36af3e2a36f811a3d11b363db5b99e0000000000000000000000000000000018025583b1fa53a790021759b82797c6fa54acd22f7c74f3ad1f5e41f4451e5ea3e20924be461b910bc9e5c28efb7eef000000000000000000000000000000000898956a4d39ad8896fc653525594f44c8d975e088d15f97139b9bfba87d8903b866dc64c45d682367cee414c459c49a0000000000000000000000000000000005d234661f2f86d33e33a48baadfc9656bd376cb825ad86531554858f1269030c93ccea336a019067867b4a33259ccbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a7eac3bb63de6d876acfb6e3eb81c2a8dedfcef7d3abffd6346e408f795d6dd9c10f6d7f134afdcf75c16baee518190000000000000000000000000000000009747c6f8fb73013a5c3e1e2ea678043e2838ce8bf24bc4f1932d0de55b01877ff9940c3a42c33fef3d5e0bb24aae162000000000000000000000000000000000655e0f82d1044d4805e029cc408b4a57843f5b7e96ac10f488cf51eb41a5b0e09af8125c05685f6623b4b9b1947627800000000000000000000000000000000178d2285aef475e34042db7db1ceff79cd442b76ef98f3a97c33f3777d08983150d530d227a58d3bf14a92e0f57b73c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001218ecf0226f565edb56cc9c0ecfe200086dc34e55139c91e871a8b676c6739e8927e27cad23b894fcf3c06cdb24b1fe000000000000000000000000000000000be54935250e1d066a78c0f09d0f91b33c3a13e5fad51917d901bd99e277923afd80f1047deada6dd37169c845c65e450000000000000000000000000000000017a151f2372cc23d0a4a06e9ff3fd4b4bda0b79d73f43234eab224a90e17a8160671490bc658a0f8b931bbb9a0679f780000000000000000000000000000000011b11b501d68c4cafe67b8c180f014cc0bf3b8994e75dbbe6027fcf6de79ac2bd6234ee5877622a050c77fe6d3cc16f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fb50fc64280893acf058da72aebe217ae6b55dd5b6f7f37929e6f3c3181c9019a1ef3c0dfe528d2d559126476069c300000000000000000000000000000000075ee6faf0b30c785dcb45521ff2b9825991a2074436bb7883fd6477a2231d64df2cf31e7da31a05b0d0fa39388f26b900000000000000000000000000000000072dbf2b635f58a2f439d6ae796ce93ee56370f4e6ec80d384cf76d84d15bb1ae19d6548200621523d4d26318ba41b360000000000000000000000000000000002276231690e7de1f538b3392e81d370f937c4d6c2000667cf383c244bd52b16d29795ca7b81293cff969638f98af3e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7395fdc354e072439d74381fc7812f9df508adb03e3e8c32c553e32400cdb45f48f017df0d2cb044be043526268c580000000000000000000000000000000001fbe86b8f93d2aeeea09cd6bea21f601fba7984dc52242ee42c2ed3d6c4999efb56bb2c4a9aa052bbff848b5a43aa97000000000000000000000000000000000d2e568ba0c18a91ade9c289be0f1ac36aee4b08d49e5e771ee0dcbc0b217049b51fd4572e860f75054a7bcdcc933aec00000000000000000000000000000000088c8e3868d192f6a5dff3c9059dca389076ac83c9231d9d52b0e2b5a700c51f77d2d5174e857ea1ecfdcbfa6a0b51ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012597f5a75aa5be46fe55a09f9e209bb879bc4558597b95aba12009b460cb8c3461e9a22ce2ec7740943aa9cdd9946c6000000000000000000000000000000001510b29eeb4159cc4b4404cb06aa19c542fbf57bf955c349440269ec85371fe877204f57100ce537f33344ec8ce9b9f5000000000000000000000000000000000d101b8d0d5e8c7193f2e659749b2e0630300c985cf6e46240a48e234c32f766c8c52785982f1c92fba1f13682ef8cff0000000000000000000000000000000002d1b45f1dd4c736a4fde4331161b3f6190fc902c29497a0e85c1bbc16191ccc4d7c75190b05e80c7011cdad49de38651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee30107e65a436e10af083f982a791eb18cc4f2c667ed31569c4595a602a52130d97eda52ce2460b7acb4a14c95e05300000000000000000000000000000000147830064915009206f9a826b0629ad29f63c5ac9f8371d86f66fc2ce5c67ed6f933a727efd8d7bb358cf1ac60ba71de0000000000000000000000000000000019d437907a3a4b86fc1c51a248977e2d12baebca7ba00d21442e33474de71ef5906fbd4462194cad9870b1caf2e5011600000000000000000000000000000000132b1f2ff463dbaf42e4bc83241ec394062f0a7b3949b351b75d9f4f67de40cba69b0facb8d4e122957b9148c6fd49321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c0560ea5e6cac09e58892d9ffcb6c72356894a8c71734157f74338c09ca0b100f63fea224416d0761e17a6746941cf000000000000000000000000000000000efb9fdf0d97d737b13ff0dcc5101735bdb62408188a97ec5a607f2eb9b1ae4af3b1d83baad3b46354bb72d345b667ce0000000000000000000000000000000016dca7ece2f687a6975fe2a836db5d21a96f2549c69ba514a2f57eb29c59209cd2a00f8f46981ad3540a85aad2a1694200000000000000000000000000000000118d6129651bdc2a65413911685dc58d19efa153c0559f43ddecca82f96db70d0b335b4c12b8428d473c5dfa025f60ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a09a4a488c7f1c90e0684f716ca4c5c608d109e791be322c9c4b42fe4c65778846ff3309849c58b36b65a5837cf73ac000000000000000000000000000000000bb4b27a306ac659d903240605ee24ddd1bad4f3b5b5aaad299552fce13578154ff7cd5749a71f618e4c4b3e2d4a061300000000000000000000000000000000065043eea876ea9093372cc2ba7efaa9bdeafccfeafdcd173c19f02edcee289f89008f00ad6b115d3c39ee5a9fe2bab20000000000000000000000000000000014b4ae24a593533f7daeadb32aca1b81cd4e6bd17b1ad85affe03f83515a03fd48416e694777d5cedc77d23c4c756a3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e4fcab4ad53f82427b7e3fc5c6cbe388cb183379fa071319909f853743a0fb24d1ea34393cc45b1054c51b1615a9050000000000000000000000000000000005ad9dfe88a00645318ef8ddb689e470b43059b6d0a91c7036deaa4af9a4ba492ca6b540117c69d79eceb89750894ee800000000000000000000000000000000072a2d5f16e29aba211b2871e9083176881b9075d1e40b9c76902c44dbee784a9c98673f273c4183da0153e0ecf088c9000000000000000000000000000000001229d894c862ea3fadad286780f940123503d7c2c5afe325ec0474a850601bf245ed8a203f4a41597be25599a086aa3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ae8d656429c5f3735de690db51007771e3bdc36cfb9e908e5ed00404833ea9cdf17cc35761a18aa61910d4857b53dc000000000000000000000000000000000ec32b6a6509de2a04ac21fdaa3ed0fa8ab3fd8d6198fe3b3d5cf532d9d962f8c6bbafa991df50991cfce4ae8ceb50c300000000000000000000000000000000010f25ce41d4d831b3037ad030e0c18f5b14c7eadb8632437e75edfd1aeb3355b7c58d62913542373111fffb70853407000000000000000000000000000000000950761ba344414c8ca2738acdaf439442d7fcd7918608cefe231110d6cdb1f3d674e1a1affd0427e46fa87c83e347e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001061bdfe95ebb87209d74b96103dbdbd6ccf9dd7d614d7366ffea4919873a7317706a646c17b16d70e3b32fca3ef72e8000000000000000000000000000000001156d5a3f278c0c3fc7486dee78c52e26f30b9e25e613d147449c558d5392c1f77d94dbd4970133566f7898034e70e2b00000000000000000000000000000000123c1d5c89baaf830bce5f3c65bd5441befc270b5ce189a97ff4e1d2a3a8a9697a50fe66f523325f2d80e34fd620e8d6000000000000000000000000000000000df1065fc6cc99295908df3bb2a3b3fd75862a69dfceb05cabf6c712d97268476ac55635a51372a9161487f0f1bf2e1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000769f5c831832b201453c76bd672a423d2db4e05b93536a9e7ad1d5095e2910c168f51ec10886663b05ee087343e29c400000000000000000000000000000000193d74879104dde9b74379e7d7bcac1d65990520b93d00e8de1c0bc5dc80de91f4663154c5ec8794227aae8bce958730000000000000000000000000000000000d54f6fe9102a6ea945e23192a808416a5b5563c0b4e3f5c6862620003b6e77b416126a7469d5a74b1ed979ab1956ebc000000000000000000000000000000000239e1ab20fd7926b71e7c265e630dbd9cc4b8f208d93273abe9b4dfe19b5543bb478b43a84e85fc97ce4c50aef57a961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138a62e89c56f22d01c7203cf9bc70112725d4d540ba4e928755bad7446a62e863d15e324a551a539e4d09c2443a78e10000000000000000000000000000000005d235de829d7a9968af5629c2aaf756d66535452ecb6e89121bad3c1641b5283f93c1901346e07c683da326d662b0510000000000000000000000000000000002e2af1bc34878948aaadcaf1d878fe76118276c0253bd034bfb1132c491447c8e127ee0af67595662c42566796923b60000000000000000000000000000000003e5a0aa48246add90dcd48225bf3e01e7e97fd09c1714722041a9ba6208f33c465aaa8cef7d0be1218f2ec0e4d889581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003942cf5bd72b278797346f28252ae4654716a4ec429add3f22975af5f96ba2eea976a37310876dceba9eca5197e163d00000000000000000000000000000000052c2cc3ac43194b1b933bf8a64bcfaad5d4f9a38e547f1ac95a1c72009e10e80cb479a9748869dfaafdc62e8a32aaf1000000000000000000000000000000000dbb927492f61a01c2f1aa23a6c27547793444667ea165bb3effaf4e2e618194c07a7b6e6092033b10f3afee7da875ec0000000000000000000000000000000001f3122dc1a0560e8573b0611c789e38080744f94cc774736be6dd1f54222cf2df53701ced4ea4c8900d400fffc39b611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec2caa8acdcd93315a8bea7f879d4d7dd23e20e2df2f8d325696b9f1ebda9a16d7007d40998742166199930d976fc4d0000000000000000000000000000000014eccc8599ed8a60ff883b78145d6ee2322789b5a187e5555e73e74fe6825df39b7a13a1b578b3210951c341d7446a0d00000000000000000000000000000000094062cda05cc366b6058ed2b92a86c5c5b9c295626c4bb52dd61fc1bdd49e9d53c64aa8f3ca6cb58bbc091015ef8ee9000000000000000000000000000000000d530662c8d163a3c5491203577619a323d42d293eb1d31fc2b5029a13c9b1998df11ddcb9a6dc7c35e473592b399f1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002582c6041056ff4fc1d2367dad1ed78f93eef3f4b5e0f78017a77a5498a0dacc454c74954aad456c4002cac6216260f000000000000000000000000000000000f61690e0c89ce638c43f10b6e57c0d784336dba9f715a86ae59433662ab267fb9914f54c0bfa734f0cf7e3fcf17fcfd0000000000000000000000000000000003734378e57b0ceded072693877931bb8b05fd0152782b888e0f7411c93fc2bacdbc62bcc6b059f6cb7cca5ac467476e000000000000000000000000000000001459d737ca0a3dcc867bd1df41a2872f05c9d2c5dee46bad004b5d04bebca3fdaf2a6bee1ef42bf0f603772ec82654121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4b2767605c0139fa3bc2a0be2d437c1538e5daf87faa9f2f8742e91845f5c61fd9daea20c3809bfb822062a12a0a150000000000000000000000000000000018a216adfea965b17378ab05f25184b3a0a31c263baa7b77990a1c5a481c4f29036e71c79e9cd81dcb81e68ff3b6cc73000000000000000000000000000000000158da59570f52f67677a544f0333dc63a2f6cf4087514ef3012ed967cbd6156455cbab587dd3f73120823081cf804220000000000000000000000000000000018d531488160cfe020bc1c45932f0e5fa303963f81b2294da7bdce32b5c17e101531b01c3821464efdf64676623201a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181d8f3e9a3ae4adfe1c591810c0b4afce2d00bfdfca492e16f21daff95db61b345ddade1d42dedef897646b10d040770000000000000000000000000000000016da12dec4bdf7101866b2de49e261f676d2c82b90038c18a82c82b2f70a4d9ce9b399c394177d93167de864632ec2ba0000000000000000000000000000000010d4fd88a97acd43233cab2844e7b1a6985bd2cc1a82e85185c8d7453b5ffd14e554e7641b543a978d4bde8357b65cc10000000000000000000000000000000012e3824fd448bc2f6a00db0007a2c02b6a06bbfdd9d51e08e709d9897070b59db6358d097ec89c886e6a803dd49af6e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150781b0769c415d377bdab84348ab4bf9ea0278a46781f761a5c7f7d5785e1df86b88a38cc1bb9b20020bfe608002900000000000000000000000000000000012b8748c5bd496e17a03b4004db93528e2541c9b5fcbff687a9c4cfe7bed997e13805180d4b6db9442de1877aff66d1b000000000000000000000000000000001836b670c9b94be7bd732e9dbbd0ff420b1d1d0edcc8ea08cb61f4c7cb8b125a2d9d15a443cc91ad43bf33bd1fcb10e50000000000000000000000000000000010dbb3fc1a2f74a303b1c9ec5fb4182d68c29c695db59d3947f8a13a3eb45e180306eace0b5e958bf87326bbb440cf9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d53418baf851d031aafa773dcec128ff596a8af0106b94c7cbf1605542bcb01ec1bb6015e89c922a4d2d8ca4ad6b0090000000000000000000000000000000019475786c922f3663b5cdc04b1b61b1957e6a5185329c18c7478725307dd2ce013e247f6ac84f1bdbbc79fc87e388da2000000000000000000000000000000000370879af9df10de8f606dec85944d78bdf46e5bd6321d89513b3b4052e55386714e818c156caef121d5b55dabb95e61000000000000000000000000000000000b68d40a4ef98f44c07b979b897c0c6b5337071946e1fd1f02be3d31a2858d3757115710cde795f8f5180060e9733c191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000942586ce3233de1a402661a12cbc229edafeda4704163a98bc22e05589964b211e827724cd2cd1a346ea659bb5e10a10000000000000000000000000000000001ca2a3bb9a199aba3a8c02bdcea6d3716043a73de5562a911592e4a78fd29009898c7ffb1c4ab7189a620eb7cfcaa860000000000000000000000000000000005234d991cf7018a8ede89a30392e66da4149a34625e5030979d79c08e7b3880b1963ae1ea794f0961640ba896593a220000000000000000000000000000000007c38370bf85ee2217e71068bdfca769fd5c6a58adabf39425ca8aa6d8e9e6be18a52ad7d6a6154fb8ec711baaab919f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c994d8cf8e4499251b7c70832fed4b86dfa255788f8d1c90199a17afeeb705dfdcd87448eb0f3e76e913441f5b732a0000000000000000000000000000000010f8f9bf97c3b41c33a5fecb1095018b7031099385e4382dab1a57d3831ba5af8a04fabde1953d657330ef9ae51bfe1e000000000000000000000000000000000753bff5bf384e0916bdcfa5a5acee046ad0276a94384359722d6fe5d7d42920660ee2e920c6eff2c111de895195f55300000000000000000000000000000000197cf040eb92ecc3d0182612a3f47540955130858d4eda38ab06e32d3eddc6b58152db3fc6efd3febf471f00ff178b0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dac6e8a15015ff190a74f8e144e6439079f217988955c0c3415369d11397d855d47fdd35f9a381dc7c093180e39a260000000000000000000000000000000002b01762ef3f2f2082d22ff4d0703344ce25ea5767cd907e0b98effa50dffa9c610d2888c3b73e16d132f1b652f01742000000000000000000000000000000001890f862601f4d7948764f29ca6fac6b6d4a7e719d92474b7f03c26ceb7d225c91a20adf0aa8a362e580e95a24121bba00000000000000000000000000000000193bc5466d999634cd98bdf0e73c5f456f7f80663fcf3126e1dbab5ede721b7c7a4d906661967f68861beef99a2de4e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010df820a10ebacdfd0bac38fdaa746d422d991995ccc366b2681991186600fab3e9cfd9101bf4b5b0c786f77a049bd300000000000000000000000000000000099a2f4ff62aa4c792ff1dedb84119051e2c4986970c6210fa793bce2969eaf0ef61705a231edfdc69dd87f1e55d9bad0000000000000000000000000000000007ff8fbd0d1981e77c14a1d47a2aec3333dc696eacc01cfb23c68168c26da8853d31220f6beb7ddae19b3c9d85d29f39000000000000000000000000000000000d95d9c6fabf3136dc210dd43431b62ba27544d965e057ffe8a93fb6328a0bbda40b35d6d21d975a8a7e70cd0ac8feaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071a984a893a7af2938fa210ef750c8bb4539213062ba53d4c43d9284774d4c2d6eb35b85a46100e16b393e0fd564f48000000000000000000000000000000000aabd48953be8e03867e84347523b40e44125d9899772261a253422033cfa0aaed0898ad4657c45ad31c3b9a216be18a00000000000000000000000000000000117fc1f279706494470571a77f2cba6553dd82a81e25d0c05a19f4a60419c7bf3c8321df5b2c597a2a76f8f424962c870000000000000000000000000000000015eaa9d89e3f651d0399855922bec54945c228e08dea0a2fd6f9b9de5e50db7ed56ee1226d2464712c1a7cb5748e46571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f2dca96e423f4aeba9263db88cb434eda320e17a442be55621c2ce775e2b143c82eb2e6ba15a8bb5938198fe355d8e0000000000000000000000000000000015e154683f585fdac2c9a2faccaf221b0c9d907f0d0bd7cc5ee41f88a9d8b08b8e5eb70c8225a476f972c585724ec82a00000000000000000000000000000000075e59a1710ff6a16d470186ad54872d8b26485518ffda1da4933d1bfc5be9d61fbb121d2d1c00c8787de073f6522513000000000000000000000000000000000fd9267402d667ff53c7cf7e3a7282f11d42fec1653f8d0a5294fb634207429ed63ccaa4ff053881718eff08d57282191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000430d54b947ff648f7399d86f345611e1367f6693dca5ea208fa450fcd0df9f8dd64580e99a0510b4dd79d0090106ffd000000000000000000000000000000000cdc0ff0619d94d8d8f467e7be9682b5945ec4d05b0735887fdd0fbdcb6c71ef4223ed2e29acba32bb1db599638c4fb10000000000000000000000000000000002de61321d844f72287f79372cbf3137a51fc5c277ab55b4c02d7a18fc6b7c2f5c59c187cea4a87dc8c9c744e4a5d7ee000000000000000000000000000000000e9953859401421c7e4f1eb31663cfbbe44766b6ef4929b9093765ffa61847d8fb6072bfc3bc0b0dbe4ba53392d15cfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144197ef8de3e80faabbfdea2e5c174137236e5677e2e33e05661ed3521ef95fae1e8bf0039d8cee18020b089c0157d900000000000000000000000000000000191c3ec1af9cd31cc55ed72ba96eceab258547fbc0df9c45e89b2510a857a2c1541e9b4153ff1f0f43e5a9608e8950e600000000000000000000000000000000032418b0cd38f17f1927ba62769626095115677a0a4355563b0ae2684c6958cf44ea2f3af5157ff6ec3498c5080f15c8000000000000000000000000000000000580f646dcda9cd1b6c866b83e3eb7376f144d61918b21eec578ee1f3ed14e70549964cae768efbfc4f3029d6155a4c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc7c4fc554363ee1c8971e1bb5ec2277027814cec4555b181d9c074ed6bcbd1c23aa18ca60952e719f4dece2e7234960000000000000000000000000000000009094da02420ffac37202103cefa6007d2db43217ad3fe8713654b26809958a48c63e45df3a418a0feb03938f22af1aa0000000000000000000000000000000001332bab83460db2dab8ba1dfedb2a0a8fd2dbe804b9df1b632ca7dfc243c276607de5bb7a57adcd2040ebb6c6e8a5f800000000000000000000000000000000131c61baa69159c6b842cdb0940e7db74bc2688fb028207d3c3c2dff3b04ee66d9eee902dec1852d3faaea85d3891c251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c7f0d403a9f0ffadc72acfb6d5d6ffce010e287a103108ab388e15e710abd4b6763b2ba8dbdc7bd65251d7dbe18130000000000000000000000000000000011829e649bbe71605e9dcd7cffec2f693b5bb8376d94bef35780bddbb3127b61233cf657b4431ce2b53f7c3109af91ba00000000000000000000000000000000044e4cccd338f4ca989cfa137db4b62638462ffc5298c2a4319aaab008f9665416dc41032eeacad257a3525da7e180b90000000000000000000000000000000014a9741fe8e4b389d59b454950514b26c5e96888b2540f08dcb0f6940935dedcc4580cc216df578718eac8ef2d5232751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000869bd184e03442a72e020987e53e22b78a8e19ba85f4bca24feb9ba25d230e2e5f1389c3a72d80970e73d0b2b9d3ddc000000000000000000000000000000001392ca32d183c7be512340c3f281843a0078fe122ec772c3251aad67db97f7f29424ebc9dbba9c718e49b584eb97bc79000000000000000000000000000000000841a7fc314edec4fade78880d1f55a481d1c59436ea6d10ae8c873b777e1095f03b6ecd02da4aee6badfb06c3d515fd000000000000000000000000000000000cb4f57c6a4fb92993e08f90e7ac8691f5743df915db919414852317c5dc27de5f015ad35f0f74cb20dc253220229a761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000661b63be1a6e5c8d517f7bc1efba732d28aa6a79d29a0e46016115f3601aa4263b7690f64e3437fa0c7347f0a43134300000000000000000000000000000000054ba61abb44247da16f99ce39bd2a91d893f681d787206be6177ffa6286075dd44ba07ee0138d86cb169aa9094f992d00000000000000000000000000000000079c02e5961dd0bb9f0646f950f5c956e09b6dd495c6b8c2cc4f075fe5cc4a2b2681b9b739b1f38cfbbfb1a7fda814e6000000000000000000000000000000000fe5b0112e3ed319d81de39069e15b6d75b27d66f4683f77691755a60913a354e1e5c20f28ae19dc63ac8cfab27ad1341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b449d7ef367658ab4431d14276b18fd6820df160f799ca86c7c4100ff2722f99012708ef9dd8dbc8e8df7938857a7d00000000000000000000000000000000071dca4416b8eca004e53f870201ece759737ba88e769ca86017a77aabdfe94bb3d721879491d9765a139182e462b7ea000000000000000000000000000000000d0d352661eff22003c809582cb02ea1bb8e56ea97ecd02cc2e0e86cdacf4950044d5f0532323ff22d0cf2d6eb044733000000000000000000000000000000000d7a0cb8a69e5566e52c8ab297b4778fa06852a1b6133bab46892a04677d266548caf9816cd59d83afb389cb287ce2ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041f5f361dd0d5bb7fa89d6a3b9e85af7dd738f3069612161d8163ee17cab59e9d3430415a97f375d25bc962c9863d150000000000000000000000000000000008240c6a28648d4dad94722d11183bc2fce44559f73f0b1cfb2a11b389a4a448a49e38f7368eaac139e56f0a565c14060000000000000000000000000000000016760f38df08899c79dffbec406ae694a18f595c962631cc1269e0d640b69a54dff5a093eda11b42bd21153713fd39860000000000000000000000000000000016f8de7a13d0e7ca228209e066dcc8be4bc3fe2a968c6daab94cbef53370a0c6bda63ae1a488ace02111296cd833710d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128c2f8ea70b34b66c90071c62002638e1ecf1594f1efa0b99324d05c805583b44e1a4d385896fbf33de6fe9de7402ab00000000000000000000000000000000169909590f3ac5a4251526376d95700c40709be28c69ebae8d88ebd98aeff63fe54cbfdf205210a694c7e8ce7c9a2aae000000000000000000000000000000001567a3311837f99f35ea37fb6526b3e80776e9ff3907aaeae91e43891d94f3a6337b5646568172763cf376cd4fe1ebad00000000000000000000000000000000110538bd9fce5f280c7e0d5ed7c6e90dd117221e7dec283c8d87315375b5041867c6def97449c370aa118393f38d59a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008501f00568391601db35a5a80a53bbe84f53d28a45b26e9694771e82d453d941dea772eba964f3af0f62eb9dc7ecbc1000000000000000000000000000000000049c816ececbdf6b0add77ab1ead027448f08e7433287eb8a67a44d5d873b36f4d6edc8c2558fa881f52a808c34b1fb00000000000000000000000000000000008fc72234996bcdc1714715d24a2c8bd7e61e4402e7ac691031c816cb74670a2554d21683e8b8090381cad0c52a9c8b00000000000000000000000000000000062dfe200a223cf3cbd8efbc70c20a61a42fe6b6b8ba90d3c717ee6cd224504fe726680f0ed89ef31abe3fd3221ad0191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001ea085a42dbf1b36b2fcaee991e460a83b049e3c19ba9cce27e47670810c5094172e1a6a3ce373ce3e28d7ef87f6f3000000000000000000000000000000001979c2c21a5b78f3f1238ff99df2982823ba683f047a98d1c7cc5a2bb1c2bd6846974cd5733cf503a2d6cff97ec2b50e000000000000000000000000000000000aee615d2d24f25e8c9897c936e99fbd183c8c789be2ab3785cdbbdb2e5fd85831bfdad3154777370194445058ac675300000000000000000000000000000000127fcb6860c393fa199bd6f644fdfd2e2465b7c1f68cf4dd62b5c2509ad76bab7f8d7b1f351de695f59bd401407aa5c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004b855000650d5fac7abd5cdaa58ccfcbf86919c8a7744ea69bf0e966eeb0f2011fff71d94bbe5d4f60ba678cbb9e3f0000000000000000000000000000000006b0970b71690ba25daacdc9a9c36d57d02aa123ea2ea76c58f5c8bf069a35f156e7b115e491f2cded49e5bf93e1f55b000000000000000000000000000000000775f4ff6c24aacd1e2a1dc738031ee8e32d6e47ae6bfdcf539822b7efaf2816b8dd58136bc6bf6a14e725ade134a0a500000000000000000000000000000000188285946e65235b22ff05a2d4aaa9dfd37238c872cd663385b42c54cdb813967fcfbf852e6db3f457adc2b2ad70cfa11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ecfd019ffb86b58e8a5773482b3ac8b58b705c1da2896b885c41b6053c06e25cb76d8dd222280bf5ed1e81d8c8478e0000000000000000000000000000000000c249ca53663917212d185d472419c8777276dcdac08ef9610c54f07e326ddd7ed60198fecc7b6b4fab3ae858fb3f8f0000000000000000000000000000000009922a9469e46e07be39cd9ecfdbfc1cbc030b8bb48f57bc5c8feaa447a3573f06d397134357c48854486d717058151000000000000000000000000000000000177c2d7fd5136df5bbdc2f220ba4b92c1ae97a1f43541afdbe67260f38bd2b0f556ce034212b85cc2a26acb210676bed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001565c7c15bb1763d3289a31155eb9d28243427f07b8db224384fea64d8141f2e5a3592c5ac39e3e373148bf71cbfdf6500000000000000000000000000000000123ba9c99652eb0cdd19fe95a641b1dbcffea425bb3c07f2f099ca226001e6df17f42271f246c595bf872b69e830eb2b000000000000000000000000000000000a25e0580ffde95097d303a9ce76948e40fe7e5b6bf172f7add2f66de0ea715268174fbbf20313ef7ae197b656d4571f0000000000000000000000000000000001eec81ab2eb68675f031af0b425767917a400cf5a0fd02a9178e4486ca9e7367271c644030244532c4d5449daa04f801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004a266245f683e5443d77d63d7995501a5bab7539e980887dc546595f873b88fbd6a84f4dcb5c6ee6d3d8a3869be6dc000000000000000000000000000000000e5e2af537ac763ac1ea6bbd1fbd0eef4217fc53194ebe8a71af44e20f78dee17178b2a82f0471f90ae80ea73521d9f90000000000000000000000000000000017f7ddba179d67e69eacb523cfc100a5b9aaef7c2d8f8a5e360c1f3d274a2816c391cca0e110ceddc7c9f5f62c7facd30000000000000000000000000000000004881af530e0ccb481e7b5b2c0efcb8cc2224cb13d9c4d15f96941982db3db3509641cd5d10aa9f409fa8fafdac896801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002014fee4aa06b8b54df685fa317e6ae66ffe03400bf00a3b4bb9d8582f3cafcf20eeddebf29b42cf38182eb2c9f5969000000000000000000000000000000000e7bc3acd7c665fcaff176bc371d6b1619e71f8ff0d98c934281fa980955a872eda935d312d2be51d1e18ccc794f505f000000000000000000000000000000000139f54c94fd27ed1158ac68a963a3be189e3c5321b5b339734d467a01183a7afc20af10e56a04d05a40c3ef66e5d5f500000000000000000000000000000000082ffaec3f71773b0a337001f7eb83b7127f4bac147506985c22671e5845f9ea43c2fd07ef75ccec9f0b3c4f999d8fa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3188ec56b89efdd4140eaf94729db68ad1db5d8409be8812ca2c55f6beb41e288b5f57b7e0e320ac9ba524d5ec775d000000000000000000000000000000000e5d2dfbe3623d9869b2370b44bde33263c983c2b127b2771e8998593dc74b7e95dd3e06331993e02d316f58209f9265000000000000000000000000000000001846dd1057c0c1611d130392b6a85e9c21dc97bb4b7e58a1f2b29feff4189a1d0ac08b848a0d8514c7acff4fee8c9af0000000000000000000000000000000000de97f51f406382a0afc5e8727f78d528e04b138d3e99e38c0e285c556af840759eae9d61a65c99ef08a22f3a97074301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159f056cb7492c136a22a9bed3213a3d719648bbc94c62a11368a59b2df53b2d064fee6b64453e75efe0449c891a2ecf0000000000000000000000000000000008917a967024410371060e279a065f42add5effbaaa3f0d5cc9d50a2d11a1bad2b277b8d20e9a8e0704895b383bc2bec0000000000000000000000000000000013ed48213dddf23ad4582a18d944d031995dc1fd8911aeee63379006adc8bca790791e45994c3950b336a8801badc037000000000000000000000000000000000edd30ec921b9e05f15e506814960d49b561bbec136e4717aa58d217cd1712e45c7a5fa81788d1aac8e1abf37eca463c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030cab3e0e518d8ae1b59222dc4efe3d0df221cf3062891f9df9bbdae0db7b3cc691c19316c563b76ba7d2eecea5768c000000000000000000000000000000001439f17a3c3c78166c8ad39474c3959f34fce0909b8073ea397d5574d61915efa153518005e03896f180adee8dbad2ae000000000000000000000000000000000428dcc93864d930d05371cb0e8cfbebe26e3df67611ed045c68f86462b43144fc47eb7a7a8cd2a60f1c83702112e99c00000000000000000000000000000000009536646d9c7120a3691a347e100da139cc05c2bf8ce351f0710aea25bca104e6aeeedd0463103f459ba920e42f5d401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020489f3c57221e2e98823e40267d8dc7fec5ecc16d6683e6abddfe664d1ec19ad95ac645caf184a6a5a9765cd88187800000000000000000000000000000000141c336c6cc6b48ebc614db0b4a3f06a471619386444b00a16720e924a8afbfd71a262e8639eedc2e58bd32c8a161a000000000000000000000000000000000004f43c1d4b9d18d1859a7b1a0f2694cd619f1d05662ace8095c19d59bf5baedeb8348a6584f2530e2c9fe34c31e505b6000000000000000000000000000000000d1dda7763109331eb3e777b94b9a9d2cd4b055689dd31f26baf3a17f866714a97729808abe2bc7f3f107e4f74fa65551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f64fa02c64668b8c31684dc7d028a674938ed86cb3654695ad4b37c093dd21fcff225927938917a14cb59340808b0ba00000000000000000000000000000000147f9a2ddb46311e9e25784ee360b367ba4566f06a59ff18d525120aee4903bda6de92b8f264d2cc9079594e9df590cc000000000000000000000000000000000dc9eec8d41d4461394585e662b9cf53e71ae86633e7602ade1ed48ca2a249194389a46bb301ebb9abf0aa946a724adb0000000000000000000000000000000015c4b0513f54009dd97fc0a1369f1c4f9f6a4420b88952baac38cb641d0f4bc75be8d64ff2219f0e1eb54c9b117711c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9450a6384a743c172c50548c5771154fb701bf2676f565ce4ff1fd542c5ec67f5e6246029ff25aa3bc124b528ac83000000000000000000000000000000000df5a88f6679e81e5ce2b04b9f40ea04c0716fe3242a5ea38df33e4f704ae3ef9f0a8dd22d0ec80c739616bac84c6e70000000000000000000000000000000001198ebd3f95f5901c323f5363efdea94bd9504a91f69177348fb0e6499ee07a1c90c1d22c36a6bbfff111f538c36fc5100000000000000000000000000000000190c2e4d307a9f4cae822c5feb1612d89d5879d1e5ee7fdc65006b30f81eef7a9328fa030791a892b2a01790c2ef37551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057ab7a09100254232f3cecdc9f8029948ba29bbe4c02dcf7840c8c9ca799e96436c6de292dd74284f0a1a3b4a823386000000000000000000000000000000000f24cbb3c25de6a49054c22a7312037ca10d7cb29c4c56d8cfefbf14203740b5b44c57f1d94c677b58abe4a7cc862f49000000000000000000000000000000001763d329b41d215e5c83d305a5ada860123eaae55736f1aa9af00113a30911e7999e174c4bf77ca28b373c4ecf1f6da500000000000000000000000000000000180e78b606854b01397b6be1d2d399aa5786de6ceb9dd71b5f0620d6d9a14d5ba8a8d3725c6c4e04d9b627d5a032175f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4a7ee6a5d8a800a5a6dc52244b4a16be005a5d0f56e26b5f484ae6741bddf0c687864ce91d7034983def161065562500000000000000000000000000000000199ae18d3d872a80c00a0032e086048ccd9f960a916179fad150428f86b4b4c34a4d68402b54e7930c2b8c5e18424c690000000000000000000000000000000015785624871df04325ac9a1adef70b61c5095fb7f04cb8af48e28b3a538893f1ce77f5ef7bc46c9360043e2200a236ef000000000000000000000000000000000be56d37fb902564b9d67b7041fb126afdc19b71695273ddc7db741ec33c5f7b9bee392e171e2f86b2a26d156055f10d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000237fd377466aa897cce1cecac822408d835bea16ca81e3f4d78de1ac9c88f99f7c3060400d576288270db785a11c7690000000000000000000000000000000017e97a5c1180bd4bd1cf6c22f5b2796783908d8920d580131cddcff5073a9c04aa4b6312a010367a72db94e3f71cfdd30000000000000000000000000000000012bbece809142ef3902867698aff9aabae77f30efc79b32f3ab75899b06fbb26618d03661010c92f2c87baa88dcafe19000000000000000000000000000000000ff2bdf42031e500c7dd4796a417ba6543e2dd98ee7612fa345d631bcaa518c7c6f7b66f9cbc54722e0f519752f67cdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa59c8bc43e312392ff3a9e6dea839475962229bc408bd6adc0da18cb60e2b0b534bbe1c008549d597454391c44e5430000000000000000000000000000000016f101a351d3e0b1c4fa4598f1e3177e017b73fe843e0bf980fb570423f91eb9c334827c77d845432dd093ed205c9fb1000000000000000000000000000000001196ebb311900d6868117113d90c552cab49803cb0a0b8cf391b2fd9cdf1990c7649d47dcc2410a0cec6a64a749343c7000000000000000000000000000000000132a5483eedf0731c8659faae2ca4f5a3fff34223ef351aa7f06e4c981ee82945f5beed4682f78d4886c7d5446f50f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010077db5bde3b49ba046709a79a880b655b0f11fa3e4b9912172da0f8058a9a418d609d9896e79418df1ff227737c9ce0000000000000000000000000000000018176b1ad8a805446038336a04c69f98e29980e60c4dbe42dc3a9a69f9081ddb9507a271869169ae302751994ac2169900000000000000000000000000000000050a78400702e9d63d7f9b1ed76d4c94b80b0bd57860b01bbebba1623a859697802de1078f42f699944edf021d75e53b0000000000000000000000000000000019763ddd75a07fabc1ec6ed793b7a844141d264bb439c4356e30497904ac9fb51879252e2f52668970b7cb9a0810fdb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3b26ed3bfa1080d26fb1095bb7aab4da72c0aa90ffe9a7571aec2e623f0951eed48e1b811e0b11deb4e337bd720c640000000000000000000000000000000011241b13882b91e400b9a262be668d516af35e6e5142c247121bccf2b66b0d3e8b597cedd0d845beba4062424286464e0000000000000000000000000000000018d65ca084d05f17eb56bf4701f73590dd942bb9a9835b5588d66eefbeae5469eeb65cc04db75a57155ac24ca253245f0000000000000000000000000000000011043d27631cfddeba611760746df2fee3ea3208ef1b603f741570a98d88c3389c46dbabe5701402758ac12776a198cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee07ba9c2316d44065fb3d9b8d739da7e6d8c4226b8184567e59d14e787123918269c153b3f5e0da0dc077461be3fd3000000000000000000000000000000000d01499b5c0a3ebdc213938656d3ffced0a54c236cdfff93e1a0490074eb428516464779612efd2f683e8693029bbe2f000000000000000000000000000000000aaa270b96987ad5935b4f8a987381791952d8028d2983e71ae71c201d6c583bc2aeff5ca827ee4a1b0bcd801646824b00000000000000000000000000000000064e8e652d228d78f49ad75a6b3b0a273cd4dac8b81e5de5de45040d822a09289460475e2f24260b48d0be2407526f051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001981ee496f2adb595f8d97a1720264670d87f1860486e16f00dea74a945663681b09fbc7fd793492406cd51f7722a7090000000000000000000000000000000000d578a8badf0380362f42eef18a115e482bb2b14f5f7c896ad1b248bce86fe4282804f44ee9ccae8a29ee860b4ee8650000000000000000000000000000000017ecfddad4e5a0f335900d19057274a928cec1a6818f5ce0d81c0bab5bcbddac68a94cc724ad67c0a600e45d879cd3d8000000000000000000000000000000000d81b219565f8554ad1f7bd139e77a96642b51d73f1b89f978db4dc1cf3e781f14a659226b7ff2c524970dcb02a462061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000907c0e117ca2628517b6807a0d023d17b2a5a7188ab50c3660f5a716d05fc78f51d98fa739adc7959d77b16c832f5000000000000000000000000000000000006ccc067a6886a88f7a0b1f370c0ffaa7bb18ab4f4923cbc39aa292257dc69f80ee2d78d6785aa5bfd321368c73e02870000000000000000000000000000000010c13078cbf02f1cbfde48e11f52c5e9b6d74845244316e6482a997bc0c35db14e8c7246627ee2e6844864a775fc168e00000000000000000000000000000000095aa56fdef1eb2b268a0b996c1aa5342303f3dd2b50923c99c4b72ee81f742f7273e78c27a7ab3984af493b574a566b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004349ae0f80d90d9b92e757d4ed27dfb7a003e22719cca7661649a55dcf3a79192bb19b92309cc32af8020b344fac02700000000000000000000000000000000085e2c5493255e911482144788920ebf311bd5e93fe85056ffd08ae76ce666474c11bdd9467515621dbf65f998138a72000000000000000000000000000000000e9767ff8d73500397a43d644fcb3d114d6ce336b75cdf0744978051603e891480613096c6959f279518a49efbd3cefb0000000000000000000000000000000015785fa9647aa5be46d82bc5b257ba4317a0c8bd75ba4f0735c718086abc35b59e9d8761023643fd98d0ee82e4988da51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b5c47ac28de1316725fc048d06d172bf9e5205222802f5293bd3b39869b9451d1c23b4514d7f0d7db1d750a641276a000000000000000000000000000000000ab2fea3c7659635e3d37440e49233335dd18cf3cb4d746738d326b89853ab04da01834a35b02f3eb9c555f4204abf5a000000000000000000000000000000001603ba50751ba1d3af8f8b9a56edeeec42eaeb37ef89e2bb445f058f9a0aa4e94e215f97e51ab747f3357193ff56815400000000000000000000000000000000047e7e88c5e6074ef0ce938ecde5f2d378d510640f049f738d5999c01762bc050ffee6eb9e05cf3452404fbd5c52ca581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065f0436ef74dcd0603b4b6921a150754232aa5a0b36631f9435fe95f189f6f9caa5d41ea0296a77556ec1e6be69ac0c0000000000000000000000000000000003d518363c68dde58f596c2c83424c04aab530359fbc288bce56bdbf0a4275cd9ab5147feb77983b148864528ebf9d56000000000000000000000000000000000d2fbb6f8220f4d7975df76ae86be37f448d13392623942a4dee4fbc16dabe86ca33984c429e1732bad7bf2bf7a63d93000000000000000000000000000000000c1f2e5c07196d59e61cfed0282dbf84aabbbfe0e5aa319dda47f15f663888533730dfc62a3b626f5d647a2174b555c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b63b0f91837899fc3a5c8cebf4fd03de4997a36d7fb2ebbc46e3a0ca62b8d4f5fe193a669ad6499b004580f9a6a67ea0000000000000000000000000000000003fc02cf7a48737eea8e699b090f8a24e597227fea2c4e7c78f03fde6601df9409ad84b3b71204266136f5ec11961224000000000000000000000000000000000e0bf0e94ec6ceb784a16369d446408292e8b3be7137ea066956c16e75bcd29ecba1e76e6f6010189a63d64424deb206000000000000000000000000000000000f4cb04088808b3486a5dab785fefa7eb8bb01d66a9e4b696a2fbab2add7b7b2ecac6905f28f4e53df460376ed77c5351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a001a571fd2a5427a678066c3283226c153f41b38260923a9235717a8f63438ba4630d968ba8b6d35ce6f10df559b300000000000000000000000000000000187fd7ddfc6edfe8c168d0c39f8ebec03bbcbcf5d660a0b7faa4c9c02ab6844505835c97337989be85da128ddbc2987800000000000000000000000000000000191696547c4f4aca3cefcb2e37da58960b2acac1cd7fc3c6ac2ab6575c777cb8c643d51d1aa4b7f1b894413cecd7c14d0000000000000000000000000000000004535f298eaabe35018ea1aa59309445b86c90a6098157ee3514b2ea5bfde659ebb197673d0e84853e006b4413115ef61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c37aa4b763862f685ba6ef89b4d3fcea7cfb1c40c26710a428d20209c2e006ac7eeb04bdb23addd60c6603673d1a12000000000000000000000000000000000af2d501c2cede3ca33e62e38fd9cadf61b1e42f39ca5d8cf96094702572b66fb0a73007bfd8f8bbe35e7f94a83f3507000000000000000000000000000000000fb8aa0bf0065003fe8e7b7d0438c00f3c1d4709c2982380e9c5919f1e1840efee59c01f72a619b092ddb4af50ddb6b3000000000000000000000000000000000030c347b5b289a2099f05d51f576d10518503e40932cbdfd8b2d8728d6ab67731ffd3553ee5a501fe4b256f6f0a8aba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000092003e51e8ba3c7184ce5fa1e841519902228487588950d551df9c73504d26360a226cb287acd00fadec5019af35cb0000000000000000000000000000000001623545a003b3a0dc0f832fccc1ba420b353c2c2a15d77d0d8bc7c52587b79c7c35765cd1cd1de008c7e6bd96d994ab000000000000000000000000000000001986e9f839530a8b6a7ef4bdc2b7126a72b3a73ed2f24d5c7558a34578305ab82bcfc4d6a449a0b844844ffd2386bdd60000000000000000000000000000000006992656873bbdfcab7f4adeb4fd4c8090c132df16325518e4e9ecc94e7e9150067026d554fe333248f5f357e6acb1541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c0644ad831033eb4e58db3f76c94a9bf31bd0be767ef15340d57e45844fc3f55fd29457f81c82bacc9bf6cb97b5b490000000000000000000000000000000015926badcb95f762d0b86c430b67fcc471b9a56a29740d2367a71af1c3c97c8d41b97395ef9c825769986216ef14e5c50000000000000000000000000000000007966fbb5222ee7c60eed0b50be7f52cd4529aa1dd0e8144c1885329e344cf8809728a026fffe8e0f22e5968368aaccd000000000000000000000000000000001900e496c37ed7e743a76bbf121b8998af95a72e624618a5bea3cddc410902242dea40db1a5059fd628bf790b58e17581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000106d9034694c29483e2cac1a3f55e88121f3dae32d08a15537b57058af93e0b125f87381bd5b0c3332e6240c8318a730000000000000000000000000000000003e925789cf8dcf78556647eda280c0f786a86b71d17bd04f8097ab478497f9f3388efda0f8cdbde83ddae70a61ea74c0000000000000000000000000000000018f2826daec8c239ca24395a2d4590b03544b1135558fd049e0eeb4e1e2e68924975527192bbc71e7a7984670af17342000000000000000000000000000000000ce9a748558afd245159bc17244e90df35c3ce08444d3313b8b090e5570bea1ace9c05adf80a381923d87da4cb36d6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d3c247d59457ac3feec6efe5c1aa07d91058c2f127281f8fedbbc2a65ddf5fbda2b07f92232f5b3f6dae5b28a0186a00000000000000000000000000000000085e33841f02c3883ec3b0184e4502c1277d45734789bdb2ce86e5ea3c03f73d9dd295be09ad99f3709d6c2b657e496b0000000000000000000000000000000003026ed8e4cf8c1b665f396e5c2cadf02c35853a7557d47477022d89a0b1fe8649ab073923f773dd39160bb5c02d6c6800000000000000000000000000000000096775ee4d2b24f1bc76e6e67c52c679a7852e64051b8ac0e0f448f42c4a8739185d585ece6bd91084fe6db7490a0fac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001179123c4e26298dc7757431d6427163d1458d0f16a5333e8cd695f1e0480882fb94bdeb44182e0243726209fc9719d90000000000000000000000000000000010dc8414f9f66cfc9539ef33bf3282d41e4bab53e3b97b88ab19d9bdcfa821532044ac081b22c17a1c7d6101c3b33cc20000000000000000000000000000000009d4f24f3427dcd4e64af0788d9201a2f081657907fe82da6d5a2d0949813aaf7fb0a2a276f4a426eaf0e19baa6eb1c800000000000000000000000000000000163cc177fb48e108539568ce153fa04dc95ef8e394c4cb50e9f087d81c4cf57655b6409aa97ad47849445b2b1bfa24f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cccef0eb0cf89675827ab514e56f05c973a8aef9b9b13022894e9ac115a1f57fdc6e579262aa11a81c38676263620c300000000000000000000000000000000034653e7da449c2084168697fa1b29048e592b6ecd65c4c671c64612167be749effdb3829827c5e49b0e8a875c296add00000000000000000000000000000000192a4dac703e856a587623d0727d8fe1759bbb571757ad70b69757dceea9b3b1d243549ba6ecd88d4e7c505179c8a1b9000000000000000000000000000000000d17d3d6e5c6b07b7768988f7c9234006faa7637d914ed7c40b4be9eed65a9a0261b42c1803c02c3c7eea5f7fd1ee52a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e964e6f7e134ca54bbdab74a6ea0bc19f52d7ee610887afdf058a5e6a855bdf0e1ddd65c40abb714291808d41cce6b1000000000000000000000000000000001705bb063994356c83f2fcf95abb8701b763437a38d4f0736193b14148f6a77cc96de59116a1d64601aa0f5ee6b498890000000000000000000000000000000005182ddf5ce75e21cb8b43367185a90b8712c652cc9d5a8e4931cbc2a347a8426eeec5d034e667c798939095991f7361000000000000000000000000000000001734837acfece89bc74d6b591eabcb09497b6fd9b08c28cfd4168ae75a951cb4b7de8cf7298aabefd1c8a8c088b102e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008140cdb4cb8cfc8389e5cfe143bad14c5d52859418ce201b47e44b591d11847c17a9130de072e3b08b6d9b622628c600000000000000000000000000000000017f9e770eb975b1da79f5eeeeff3db2c256c4d9d0ef26ef6b9c7e84d89827d9e5857f80f3689c917e91fe35ce750316f000000000000000000000000000000001759f95704a6c088d7c32dc9457e6e79e64126f87bfe9e8ada8c3e6f6877c1498df2f4bbded33e8f2a591150f2aef0dd00000000000000000000000000000000042eb28f70e9cb5713ae0f99911b895af1fb136765cfddd49d126ac89c5205f1a9978222b06963823dc327e3555203d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df43fe1fdd5f1db37abe99fc5cc7a0d796c38257fe1cb483ca915acb35f9356051963ef03b3fc7f0896043acfe20007000000000000000000000000000000000de3030e07cfa332158e8c6739651067d015d3cbb7f13e2267d8eda3341b488c792a552a9c4cf37b9d85788858a3b741000000000000000000000000000000001815d4074d940078ebb29d01fd4440a7e903e2594400beeec5a49099158074d0892688d625d90fcdfdb344355865942a0000000000000000000000000000000011dfbf5993989b0918c3e1552c575b34c2ed33e27303480ad6911e9ae406d06f530fbfb75313cf9beda18b9aca8ce34c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015588b2ac123a52c7dba167e56a06abc3e1f54ebe28812a658f208d57ab423bbce08876624c10095132fed8261577f83000000000000000000000000000000000ac654818f3b71caf47cf0715208ebb5bf2afa87b95b85911b8b687f9d96be8cc6b8b94585e12b9611542990f1a1f137000000000000000000000000000000001759fa999db74bcd803aa956004422d9b389c51f5bdd399fbdfe3fa95e180bc0786358b6df2a90dd3bc42ef811213b140000000000000000000000000000000011910f7f1e572a2769b333d622ffc29505243f95d2c14d7cf477a521ae5ca562ab86a40747e3a99aa7b22b78d3c18fdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003110ffcbca535770efc3237fa1361647633fca5d26a0c1365742326e42ae71dce6236f1a394a4cf3457622e5ce2b2d40000000000000000000000000000000019a808f34f27f28d1539aa96ac98f709ad2548594dfae76db7221d70f0358b6cc01b160302017deea95ecd7826d4218c000000000000000000000000000000000456cad0d6d602e87bf9426cbfe9681720dd0840dbfa72a88e23f4dd5ec48f3f6ea6e68835985ddf5e2388d12c380ea00000000000000000000000000000000003fa2d484b9203b926f52db3ce3862ec438ea01cd2b94a98485ac074b92ef2eda7330a8a2968926e48f4bb17268808ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbf62ecf0e0f1f43d05ea4049114d316858feeb5b3f4c87755c8634831768a0ce6fe7956cbe9782d52f7c2c6daf743a00000000000000000000000000000000043fe2d93d8667b324daf6d0c78451469ec4addd89ffe26618cb3513c20b54d1667c4f0f798e0bb57dfff9544b0f41200000000000000000000000000000000001b7562ee8b7c0ca113c1c96354aeae4ae33cf1b7847f9763b8341f47c71f4614d7e6c35356f0b20cc9daeb3e2241910000000000000000000000000000000000da22f72f4c534b4f6a182f55778326f03966e1b6232526a9f61324fa21cf4e9829da54cf98f09f95d2d3d39ee6edc371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001614a7583c4a0e9e75c5c05297b634b23f52aae53fd14fa298e7b9e5e6f396a41b6d14a5172501b6271f38887cd149320000000000000000000000000000000007e13688c00c2d5458328df8a761eb2940beb1d47e5588f6101dcac85889c19100c28e480332e4dcebdaa8ea9b2aacf6000000000000000000000000000000001919ab7983805f8aa845de443968bf0623a81aefe20b92756078f4768682f4ed974b7315ad60a44fbad335957d7044c90000000000000000000000000000000012fb65a7549fa68cdd4c595cb07c0aa17310ba329c2dc81de4ee78e15f801e492be9ebf389ce9f746fd10a27c555fe3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9dcb9d4e1731040b186c9749f12808d6f9befda70aeadd88ed342c0a655c783ad7c09136a3a8032afe3bb0acd88d900000000000000000000000000000000002fbfe6f827ccda267a37a178718568c327ba19b604d3838e4b27f0690e06d40147171bfbce6533c6fd68c06d9a205f30000000000000000000000000000000019b8bb27f0ddd3c8188dd442a5581ab45512ef49daf22b8eb3fc1c468a0b8835f70986fb036f9fbd571b2eef1d4734d1000000000000000000000000000000000bb135d756b526bb06d728bd1ad3078bf844a8abe2d3cc646aff5f8472f24aecc2683955d1e99775297072a51744918d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001997167a030a1e9b630aa66fc9ef1b5a756cfb164bc4adc1fae2e2fcbac0e79897074d6c21996d7257ca2a8ed3a800d8000000000000000000000000000000000cb934cebdccb1aa8d17d27cd69c11c6afc4f7a4371a159f7043ec12aba4ecccb489733fa0de3ea3dfe5ed2181c47adf0000000000000000000000000000000005f37a6783e54e8652cecf1ae73985a1a032346a2214208aa987b7aa20ed0f25b6661166ae7312fab7cfe4caa6713446000000000000000000000000000000000e43dd67e0e746274dfb00d8d447c8c476225905f82d881eb3d5443eb8ee2e186d0b8e2fade98da52d14c6135ee0ab7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a3199176836da4cc11b9222b2577335a492710d9550065583e18376f184525748f42124b18f49c8ee15091e3042ce000000000000000000000000000000000104f3bfd72a17e08e27c1269d029b9ca5cb0cf10578d5188cc6959041097982d8ef4c69347571f947f488cd2aea949120000000000000000000000000000000015e173d9a9e9b97a37f307795f5fcbf913cf3af37d2fb6831d6b9e9df56ec0d5bf277d6cbad64edd584efb96472b3e6c000000000000000000000000000000000b33774433dc1b6392d908fe01e6b5e6971980ad9f4c5be1be9faf44e1565c7a595498e9f078bb7e4c94c3aac3090db11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132e2a31b62ac16f46166a9d6a77e49d627c6d7215165e30acc96ced4ae57b8653a353d6916ead2fcc59886c65b22fcf000000000000000000000000000000000c655f8b367fb8019b19f7f1a72349aa3640f22dba3a1fcdc749c5bf9f5f9c86e0a07dc7ff5cd4316691d977eedd0f4200000000000000000000000000000000171752d3d4f9e701c3514df071f78f13271ed4886adeeb65b4425d349a1c4a2bacbe94497be48a420abc3bde4f7d15110000000000000000000000000000000000ba2bc6a9d908b8760208d91b744543e3e8acc44241f480883c96d3beb169e6ac7229d9c9b23206fa745e3f449fb43b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065a69c9bb85cac923021f28072283c1a4b77a9a629047a9fba87654365e1fb55833725f699b82d2a99e06214875645000000000000000000000000000000000126ef73f13a52afb960c11628a568dd181e97f7af44abb29f007b3f3acf376d9a428a0eac6ff38bd824835547beac630000000000000000000000000000000000f2846efd22b202ef8cb7fe91e3164749e69f66f449b72dcf34a7503c60c46f4d79da2ebeaa35d4b8bc3a156a546c84b00000000000000000000000000000000088e1d55c8206b4a2034ca0edd4d397c5a10ed3a93d2832e846bc128cb19356d33cbf4b89458d5b5ebedfdc1c7dfde231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a14529c650ce5e1e570a1ae183727810e20f4eabcf9c2352dec714448997a10ce044fb08fbf153da399bc1b4e8f36a000000000000000000000000000000000b4a0f2f1ffc49deb3959984f522ea271d171fb0e69fef232b6e12c50cd4c5f98b8d615b1ad8f53749dc396d1a3556f0000000000000000000000000000000000f08a83857984fb0b25fd2fdf4067264ae0e8940ff73cdeca74530fa85b997264be8bccc439216bf5612a4730361a442000000000000000000000000000000000326b846cf8a34045287effb1fd9f456c4b04dad5e7bb78883d9b938b0ee76ec09f0ad22ab23aefd549613d49f9ae59a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d9b9c8d3b6c3eee769553717b2b8de4b51dcff950444b9644e18d87b676f3dde2732f57e41ea7ceaaeacd8b479736a0000000000000000000000000000000005ddf6a5fb4d7b28c5d4b045245d870415c255815802f9964321c13a38fccc29159e91d630b891111fb1047e1c45c9d80000000000000000000000000000000015e00957e6b97d936d60fdb331f0d78e992cc098d8a240f75caf80ee285cc414c7523a3a43ec90a72ce864151eb0c0770000000000000000000000000000000015de781c05cdaeb24fa6a8fe3497fcff4c4b102048c1a9e758412e69d15fa2112d52ac1f62ae155c967e52e2d7d4c1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f34fc2e9e857f06ce231cfde4dffff2dc84dbe773dc4d7627bbdf126fd855efd60c644157fa84456be2160b08d397a300000000000000000000000000000000005aeedb4c7e91c93560dfc93aa484bc6180501c29f46a706400db27f3074d69ec239a9d0bab6da90e4233310cbe07c900000000000000000000000000000000170bc381622dbaeeef978b34f16f169575906b58827c0788d4ebf0c635db4e6c5236d3e2df9ed0870e7813863ae5cf3e000000000000000000000000000000001727237da4b3fddaebd04ba922f57675f52bc581edd75502ce970ce24449dcb38e53957094605dc62746e1ac5ae6b83c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f043a8713b5c0cf6b865feb19113927a089864d51918d10bae89f9971bf768f69185107be13e6ca25f60b7c782918c800000000000000000000000000000000187bd05d8348c82b4dce46dd4d325e8c8847d1ac954b888f5e8cda299e5c8d808f04e0dd0eb870ce1141823ea990246c000000000000000000000000000000001244ab6e621390501361028117d7144d0a2662fdcac9fb92c2189f2e1254c0acf4610810b0ab221332e5afcb750dca0f00000000000000000000000000000000105c16a2eabf83e2af2617eabe2ea68afedf9915bbd3d6694126d72df8fe07094014a1c833ee89ad01f3f77bdedf8d611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b013c832f10d4b31b0162c607f68ec74ec96ebe7078117318438b30267ce2e592e1acb583a3be6f8a714ba0d3d747b0000000000000000000000000000000007766ed0b47b107587682572ffe3155b27681d8a273a51a6aa15dd599fba1109b3cccd8f9ef070263897be0c238f6d0a000000000000000000000000000000001243031f2537fb8ca314b1a5046cb61f2ef464d2a0aea659a1fa38f2ba2d7efbf3d9c6cec33210fd2b511d1d2625830500000000000000000000000000000000069a1819789546594db0bf1d626f8eb39da9256e648dbcd070014880bff3f8276ae15914bfee85c68761ac2ff7e0fe0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b84e51d82ec11f438f79c7df8b7661041c9209e249ad47277cd6e0aeced61026b9af179fcc9856812e1bde581a57da00000000000000000000000000000000033176e1f0a031a70ef1525e1bd05c60a3a771aa3d08cb30c44a637eec12ab429a6643fc77a5c3e67365e187a2de3dbf000000000000000000000000000000000eeb5a8714038d775912b3ac5a153c3008a86b1033bf4ef66bbdc5a2a2e408fca069fed9991d08aeadc1b18fab17fcbf0000000000000000000000000000000014421e823b5deab8fb5b3be584f8ed7f5dcd54016a1b4e321fad29e7c6c60dfcf706d3c648ca8a35dd293d1fbda17b6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000321e7a6a771006db61cf7bd270c2a7e3fe0e967fa54db316fb48290d69d1a1a6579fe257c86bfa27f99fbca3ad30ebd000000000000000000000000000000001373ba6b8d7dadf1f714a9c28f686ef2b8a6c14c03d776f10b2ede5f3b9b789f5e2fe89b660ff4d16a2a2c1e4fb55f100000000000000000000000000000000004949a7b91d9c068f874f2a447d8ae15f7460c5e10a30ea97d1f19301e6c199d83799c3cb96c574adfa3153aef92ce180000000000000000000000000000000004786d19e3602c7e0717bdd04d6a709291cad672df856c52b2602090ef47c7d02a2cb80095cbc2092e79c009d3ba81441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c86095c7a6d66ad54a240b99907aeb19946f899cf4dc3d60cd61ead53f765d728b4009545b36cc71b419762d66e49e00000000000000000000000000000000138c6b9df8753afd528af139fa1d3b419e2abd4d60e8a78695b537b0d7d9adc49d60a8774b69f98263c87422bdbfc9440000000000000000000000000000000008b499f71c538063606c0bf691615b29f9c05de70ad785db0e18e8fa955ee7d5553a3fc6f7492531bb6703f625ba7f4d00000000000000000000000000000000061c4a989bfecfdc2f83f448c2e15f69b87d9208d63c1a5948cde5bfb6e102dfaaa87f2b5448255df53c335b998de16f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bb7cfd39e1869149d70091d4c103c7504090cbdede75e68464d065c9a535959d9f44ccc7b9185c637fe36526d911ec0000000000000000000000000000000008206f8096d24753e4ac3ddb360a4356dc0960940bd14c796804b4fea6be6c90cbdda053f2283f6de0259a4541f0972a000000000000000000000000000000000a5fa157207c1cfb658a430210d7cbe558962a6c3a9e05a60f3f20217f15a586122bc088a17246b999a3a5947dff5091000000000000000000000000000000000e87a8604f361e3bca64f51aa12636a908fa0792ab0448d6fdfe60e95f0b70bcad7522469f037cc3d53e02424f8e6b711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aebb8de8351e521add2550f82b0c5fcf2ba3a04278af304b90d4e87627ef822e391b7d01a43be4c3fefff721e95839000000000000000000000000000000000ceca7d82f2880b9667ecb82b87cc0b0902dacc204572d43fdfe534f8fdd9c95e993fbc6f5089fcfc86721378e3934ab000000000000000000000000000000001945eb052b2b18f4b24ba8be1cb8699477a0fb954589c1d54807562ebbc406e0b69afed0da654a43996246aca5e2d03500000000000000000000000000000000068ef5a9de112f857e2405a17aa13d7410e53cc0626a0de84bc5e036b364183b7578948944fe49deb8f1a977e50e64c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016aabd078fa8b7540e63b11ae13cafdfe774e9bd0c10dcc0306af335cf5d6b66059602c0257c4a6dc2bbef489894b63000000000000000000000000000000000aeb8dee867f9ef8b90437f3674ab6d9b6342dafc6fab273567bd09d6a5193ddd7832701082b86a91e81cfc3cc7b66b00000000000000000000000000000000005ab7b43f34f42c768ec878e5ee673e91cc83fa4a475c80462aba328f108ea989e62abf879ff2141cc3b53854336d6cd00000000000000000000000000000000176a4b3ec9d206a83e7584e21224eb9aa150c1ce954e8c9e6f6b3f76b0cadc716022decfe7f3299ba073743d416783421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed417a3b8bb8fb8e45f60f4437544cbd79160ce4d347705a391c2d55bbde1d7b47e32ccf7704e6e7c1b8a10e915cd33000000000000000000000000000000000f96bb3fca666c578a2f7a5369aa18e47c75627c4ec4424449535405bf40ba7b2916ad79897b084b34dfa315c78dacf40000000000000000000000000000000002768383f66145c3ec1759a0980b6dd0ad3ff237b2f8cb4658fc864b9d35208f3a5ea5040c5e8fd40ed9809dcd9a960e00000000000000000000000000000000139e24f49dbc498318fd8a8f64f273958c2c79b8918e0206b6af76a666746e64eeb1c41a55cb8e906bcee31733225fc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c26537ad03e1d638bd5dec664e1ebb28fd2bc88bca62b722da21e2f3faed434142ea0b01c949ae4b9b56666e015ba4000000000000000000000000000000001107723a19cb9b2e556e8c2ac1c51455c611066e50c3c42278b799e1d84f4b0623f07252ec9c46b330f92f15086c85eb00000000000000000000000000000000022183865069ff29b06be9d6ce9ee9bb73d4e7ea7a0c7192c6ab1d5d72635c84d3b9dca786e024aeadcf891d58a0365200000000000000000000000000000000138ace168e274d2c6951f818a6e56a52451186ca413def4f0961aad4630cd64a5039e410bb66207b6d20238739ae7b4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108dae8e88406a1fa26abf9cc78c8bb3e27645e4548ea7edf4e1b98aea1be4ac546c5c8e9003ebf76cc83723c3590c67000000000000000000000000000000001250067057913cf430a3318e62234b53bb02a33f1cbdee6ca35179eb564efd2d547dab883ba7e7211c2c8c5da17909c60000000000000000000000000000000018d94329a21cbbcefdf0d9665430ca682f1ffea43e5a5e96c7d80bd77218e6ffceb58d8ba6e1d151d46270c948f60e24000000000000000000000000000000000dcc981a3f77ade9711f5c0a248ef6373bd9039e26f0b1c06b1404228283c506b5ee64a4fac7b61d12b94265cb9b5ddb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002595099e4ca262d5e6fdb7becebe3170644f02a9a444e9e2c6420189f02e1e02529f6cb5792186eb8a124df5ba1775d0000000000000000000000000000000009c893800f2ecf608b0b9d993f47b2adebbe2450653964f20351b25c11a491d93c0bf6bd80f791bc65e469a8e10f3cb900000000000000000000000000000000098c347acc5fc1dacc8875a68da38f997cef2f95438c7243e53f8036153c541ad78fc24e82505038ec830a6213b50bff00000000000000000000000000000000179a8b6c115b77b6b77e7a9a140590bf8ea52d753d9f42f866d199faf11b495fef7bd384478d184fd197e7736231a2351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001965dae74f5c6ee804d755988dc4a3b73e7c93bc552e88f6a6d5f467011583c3e7823d6a233d44a783d6622aa5a40b650000000000000000000000000000000005a7b26c59d24bb7bdc47e1d71c3cc4520af964a05dca4d4ada5b409c6e0a952fddccc8e7e386862da75824f4d4544e800000000000000000000000000000000112df4a999cbff49f50f150ad8f55357cf56cb0a51f3ecd31c4a9450a6848c5a199fb41432549a529b12a4d9984e175b0000000000000000000000000000000011ab6adaa8c4c8134f0c008f8644fc2c4b8b4fd11080166a8cb87ae259c8f20318083aef79de76e2c64b5f0493ab94391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bb84d67d6735c35bbe5e3f2fae19cc354965b7394310a822e71012a246c2c240676e2f4278f464ca43dfeae072514e00000000000000000000000000000000048438d5f8f0caafa487a2e52a7ec4db2ba770920d9e3232e63b1d4d66e0ff938927d970e7658fdbb93eaf7dbe32935f00000000000000000000000000000000179f8b4d7bc4c19c4f278d21a3f211d07263ac924716cf4f851f2235d5a6f162594815f6d4753136343f8c6f5996c221000000000000000000000000000000000b3eca2bb18c517f168bcd9e9e577b2750a0d28a6ee7ef412bb8b1147639e4ea0bf89d9b020ba7b45c84535603b709521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e5591dd97664dc06500ad3137921e46f156ee4645caa7b8db0a8c80d7f733da5cc30570d5b3d0715410569b6feb98700000000000000000000000000000000041c61a9d5cf64c543c755c229a0e1a969ec48bb47fee8fbe605fab879866d3ea3c01302c4b0aad573c9fe3c440c52aa0000000000000000000000000000000016e8cb7b3fd46af1a2e9c2064f19d2d37d7fdc3e33ef1ea44c6cb014dafa525bad99407f35c214d61198a39f79c22a6a00000000000000000000000000000000185d87111e9d9baffd69cfacf1f63ecb775edce00c44c1664140b94fae1805f66104adfc77e1d8526cb474b6ba5b83661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084e8a74e7ff97735620353e3b4b45c6c2e80c30b94c04798ab84fc7a47dedd46d3400d53e9a3d47e0567ae840c63c800000000000000000000000000000000001da152972a8d0dde24c788bd13fae8f28f2b2d7eda7617b4512f353d5c17cad542c39b89bb8b1a4d3832f89677bc16b000000000000000000000000000000000d1892e9e5d80fea8ed48c2f4ac9d196a1f98f2d4c1ec02d05da820da917779dc8d7c8257cd326d762ee7a718d715bf30000000000000000000000000000000003dc59c0c5981788515343468a8017e01f1a742e7e83480053d8b970243858859cfd9250d9dbc1bad3ea5d56f893b6501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009982168571eaa4b2d303c69a34a7794fb757d77c5930c4ae2742cc6ff69d3820898306ab8748ee7a2fda37dad051f9700000000000000000000000000000000128ee1222077755c7e8fd2451f2cb15a6ae1c2c29cbca2784b442e00ecbdc218e106ab9f5edeafae693eb2063ad5eda3000000000000000000000000000000000b12e0d0f716c51e8ecf053a8106a1a84768c0dcec09af5eba1f95d3172826294b50f7982df46b22ce0171ebbd25b897000000000000000000000000000000000b540b1ecacd4ed1b433fea300b4b2e17a36e8c6ce0a3395dc8bf7912f56ce8faddcd27ba7d9e3c401ee441d8c6d62f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077b8a3b43bbb3e79e621e533c93f5691371920cfc48d336fb23f18b1648a718069d61824b5df97e0cf08e14e7ea5af100000000000000000000000000000000189ee4087eb020ca6507bc39b2f41febed4696f3ede735f94256f5b78e3f1b6a0dc194bae5057ea375f3cca6fe9b103f0000000000000000000000000000000002dab31227e89c44c19acdb6d52db136e5e601a73143034b8d9250f06c087be74d4e47a6f3a83f78dc6ffb5aa2ecf1b40000000000000000000000000000000001aeecb95c081310c99a8ba044c06fe35ad7384d2dcce63ba66c2514937d3299f9ba629f723e12f5b13be292e205eb6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005323b2e94ab16fa4150925429c6798b81c0911967f77125ee7b0116eb94b21dd67cc9680a1b4f97cbc849a2d43233940000000000000000000000000000000012fdbe3244c9333142532fdc8c09011a83edd16f96913f087931e215867581c8abccced2f05d0e36d17fdb3878a4abcc0000000000000000000000000000000014daf0112a5156d1cf5a9697df709f18c48f43776263e888123b3deb218b80353d9310bb09eb843855dd2d77aad627e8000000000000000000000000000000000ed7f356223a8b7bce7f935d6a284e20a4457073d44e981492df185c3c159e2abbfe79dc2975b0f7c6a5878eaa5f72651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000985fac75ea1a20930bb698cd4ddae6c35ae385a6c8baf55ff3d5a3d16b9baa6c944bc98de5ba3d63de70c3849e13570000000000000000000000000000000008d7cfd17ace82ae9e8abfb9f7048c8e449775db821f84fc3306a96f35a4fdfd32961ab8b77c8ad371cf2552f4a3804a00000000000000000000000000000000038a81c8b851c445faf6a4af2a16cabc0a177f995d65a88fd97f4a7429266748274d430f57fa5be76162480caa40d76a000000000000000000000000000000000b61ade03e3870a0d6551def66c5d742a91cd75196f0dbca323903f15d47eccfc0135244d729b190d2e2ffb662c29ad91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a761939890ba36010fbb173ab01f4b7f3dc60c034630779061b294520517a4c3828841910fca97987b02a59a9797deb00000000000000000000000000000000194c81f568ba893882c81d5c84e15789b19291d850e684855f27a32f0c621b3a5d7bf9235e845a5164959b4fe06d0b3e000000000000000000000000000000000842987c242e4d98311f6fb0ae2ea80614013700c9d5cf0449bd5e07fc2d0b7306b516aba534883d718635267c09c2440000000000000000000000000000000012609a9ed87e6568a6ee5896dd3a01e58b173d3feef634051fd033b27aeb78949d162b10da14097ca327aee8b2d5c3a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067fc0a69718226b192ec4c8bb4f254c579343e40e47269e6109776d0e127c3a90ec098ac9aaeb448b0174c51bb5ab96000000000000000000000000000000000fe0e2959b4d38a9e42d819b8386e77b7322b91b9e5a40310955b78385b8ba6f2a0341d84a1e5b26db60e126e4d502a400000000000000000000000000000000111507ab1b27ff88e79d0cbac5a8236a5914692165a104cdf32f93a0435559880b569761564567386fb3a4156569e2cc00000000000000000000000000000000015fef3c4e58d5d0dd073f9b2bac11de877b5cebe571874213664d85b880735e2e289915853ab4bc96516f8f0b5e68911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041e1fcb9927b7fce1294d3071ac15abcc85e6ea26758a50610d0ffb3e114c92f31bae94c30c2b4aca787cef1221e87c000000000000000000000000000000001430c8371e5fba95ad5bb65e6d53405e5667e0e9034c0e27e34213c423eb4e87d8a97d6acf6210e3e61b8665e8fd1ba30000000000000000000000000000000003e9b1f155f9458dabae1891a9d69d0b8f342c7e3f86cbe1d43f56431b5ca210779eaef73291991fef1624f161c88b9a0000000000000000000000000000000014d2ca7bd0dd239a4930644bab12d1b350eb2bd33367d777ecb695a08ba3f6e3ddf1bd1495b5bb0a04973556c3f4dc511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017afa77238c5e0cb667e08b2a8c8a9508edfc2bacda648703fcc9efda7dad60f347f01ddbffcdd2a8c05c15b26352e74000000000000000000000000000000000dc197ccdf45b4f2503363983229918b8b69fa60778a2a7bd007a5751cb6a383d3ed36ff7b266cd66e68d248cd18263a000000000000000000000000000000000c5ae5ece084e9e7c9884fdd015047f6f7d152f687b887ee333f22a95cb9f3aa3dd23e4dc869ac8a23b5ce3851eda0af0000000000000000000000000000000007b9ed5fd063b75f9fc81d8e6b82d63fddf9c238600a95b3985c9dcd1e31d05f9b1e91f8150b14db48872571a4ef5cff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084c430f0ef1f01b7416715e51187340b4cefa4eb3adbb7a1f5e8459d2d910be20251bee0c8bfa012be3b90d7624d5b40000000000000000000000000000000016cfd5b2639f3298f40ae81f4faebd1e69c08462833e28125817b2732a871423bd4983efb71c12cfed60144311b798c40000000000000000000000000000000010746ba5447ea73a7daeaa61e60334a06e3a4a4506022a07c083fd86dc72ed15f9686a8d3369948704974598bcd89afa000000000000000000000000000000000b225fa5d85caa77fa823886fb2ffc5d7bc9600f0818666eaabec253211af94cdddde8ec8feb4e28972bfde8453f60c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000465439921f86e73931221d277f123cb43621670ded53d220776502df6cbef2002116dd46b8d7bd1cbfe76ef145e400000000000000000000000000000000004e1fc63250b42af245a6b32a21190a7fec583ac87c7375134aaf212d998c7bc4ad3cc00e2f2974a5820d2b6a3056b9700000000000000000000000000000000015466e026fec7d63696f332fc7d8a9a8b0b4919f81dc25e20c8d37cf2b9b6df7e3aeac625a3899dc1091d612e5cdef4000000000000000000000000000000000c33b599cfed8c337472164c9fbaba5c92081ce0d0662d0b4cda47880868c9f6ca610558147db95b653be75f6d8091811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f54ddac20f8ec287bcad0dd245ab866c68338a696aed87a21d7c122943c24d199fb0bc85a56e34a921f508ba847f11000000000000000000000000000000000023e090da52dabd4dd69b66e08f9ab5ea31e377e0a4ba89f36b9756548aa256cfacf52f8825c1596b31644c402cad4200000000000000000000000000000000058f91536572b5f68574b6a8ce16d177655cd92bb3ed56552f797fc4c03d45d16e25de704b7d33d3bb529dc4e8121c60000000000000000000000000000000000bc90836202a58a064e392c63de291ed768dd8ddf44867bea99f6fc00ab8d1a6fcb0cc5217aa4981ab8e0decac715ed81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f63d0a841fbf2d9121c16f09787156e1d22c77c6191ff0e60a96c81d97bb6ed84868a5854d4749053370bb0a5ba3260000000000000000000000000000000018e513210a37174836f0351243fbf23b200af071051822dbab4fd2820e14ab4c159d3526c61cbb396f302211ae5e2e7a000000000000000000000000000000000beafa2465df84f66b15f3e6102f4d0cfb88c208f1583e69e520e83efdfccb2291d62ae662fbfd495e3adca1d11f0965000000000000000000000000000000000cdae97ddad48eb80e89d801ef711514580cead72c91ff40834eea8321c76af62f88c3ac980958387b190f76a606b9801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035af7869f993e75ec07ab76da417b83938a3559a84ec5bc60413e343210b4f1e9eb6da7ae04fa787582378cdc8ae08c0000000000000000000000000000000012a313a5bdc30efa8c9d5a90cd4e91e43eb090aae4cdc594b484dfb4ddf6089dbfd708937940d2ebf583ef5265c6b5350000000000000000000000000000000014efc201d62ebd79da6d97208bf076c8380b8b849e526bfa1d8595c4330f162496124d63fe255f65b56fb285b77917bd0000000000000000000000000000000000d5760211807036dcb74aea4106581b126724692af0eb45da3d12d571a858dffbc564da62ec61dcb70e1a592e08a6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a1320c4336f9a93e02b73efe85477e66abec2f6151db7c0fecf734a27ce7ab0d5d12633e9ceae5d223fcddec16a4b80000000000000000000000000000000010b537e65eea8bdcf573c3cd3d89d11bab36af71f4d50b12050201b80ed55bee8ed2d9029f61b407755c20bed2f6d6c50000000000000000000000000000000017a0c6ec237814a3207e006779fcf80b0a07e7d7681b358cb9b07731b2ae4511b251585bca647b9b1896eac90e6c40440000000000000000000000000000000017f95ba366fe9282b139b30b8f1a9821cea66fc5b105c4a2e8754fbc8d42e24337e4f06c2b12d286ecd1ef2b4dfe88cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ee38452b1d060d0b5b594b5d9ddb3ab25804800c64c5ca4f6c95d7fa23b678c7443794c809196a80bbd82193e5f3d9000000000000000000000000000000000fc028a0939b82cd60f0293978bbf62baa5ce2c05ffa9e5121e44afcb5bcd380636e8a4022f29baadc6a89b6f413b508000000000000000000000000000000000f04ac782872244d617c637cf0670decb9661f5b4ef2d602cd6389b888627294118d9ecd50d54d46a804e3820ea91d500000000000000000000000000000000018c843142aebb5f3459dfe0745006edba7d8cb7a258518b1cbd25f5c33b274a94099fe4785ce43994569d230ffe8eaa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161e2d36553b1c03dba20e683412d7d90f8964ebb1a3d4f9eb5b220c32f3e408d178dd8b4017bffdc64f0565402e7228000000000000000000000000000000000a0dcfd4482271b5c9db255f36d011e6534a571ac82ff0f01b85d1655c5851f07854fb748586f7b0bd861f9b0aad2aea000000000000000000000000000000000ebfd8cdf970e76860a2cf7432760cc8117850dc77383178993b62b48c7c04c36cb20ca97d27b1bf43aa05e574a81dc6000000000000000000000000000000000aae79cea783414facc2a4a973b429aaf4443bc5f6ac518b0591e24f939db49e210a836d057917b44bf36a67174a306b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b494ab31945a3a615315ed9e4b9b89e293a55920a66242ca71d857987a6bf85e3c968acd588977e56831f241da124a000000000000000000000000000000000913c4aaa8cf7d57c4de6a49fec1056d6127b332b8b135501899d28e289162d3cfb19eb6bfd5eb2f8c015230c75dd24a00000000000000000000000000000000022dfc79a46220fe1cd8a764d1a0334a90f1f001f408787969bb688e9518f3035db065d645017301af32536e7aa3461800000000000000000000000000000000134c184220d8e8b13400677ce0756f8ef3e00da7d3b4a72458859034b741e45884ce32f3d26288c188fcf1ed1ce01a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2bb32c2267b9ae69df73799299683583d2d442bec64457824bd2f1efd0c15696af4f0e88e6080f0944648ba1630f410000000000000000000000000000000008aa84b6d962f58ac3312a36d79331e9eb065633a7781f339bb0f7d9fd9af83e0f4ea0a58c0a23bba5f36ce099de39d20000000000000000000000000000000011e6734b0b64a57593e345c93f1a6214d3365c420b28e91d719985b4c09b81a77fdbd7027ab03cf4a369209bebe1ce2d000000000000000000000000000000001753cc3b957c364899724d73eff403e3e4c932f39060260eea3217b8227809dd23391ac77431e35b81fe6b1c76e8d0bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130f6e728bfb833172a003389a6f4bff85f8515804c41d385b2da36979aa035364fcf3ae0ff8c8bcfe6c05592d554aea0000000000000000000000000000000001344e8c7291991a9d96759c0bfb793a1545492fe027ddb898552fc298a4d2054d2d4763192c9ed5559cd6dc20bc384d000000000000000000000000000000000b6616290db82e28c08bdb193d2d17e6dedafcd5bd5a8061fb1a7ca72f4431aae4947a5fedb1026acd350cd1a11072c70000000000000000000000000000000007515e7bd725eadc39eb08229ded6af8735e032ecd6bbe1ebe828cd7bfe242de80e9d62e3de02406bb05067e4d7ec7fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cbda9dedc1b008da733210b9eaa0602b07f8cabf9e56943d64012ccf4bb2c93396d2d03383ee68b65bc102eaea2ebd0000000000000000000000000000000016d7ee91de2f5a3605194a1d3336b724035ab8dc91ea460dd5e560df7388a58e57e6a6a45c27665de88339a7dab6f19900000000000000000000000000000000064af55ede76999bafef4108ec96923ed74da10f3a9f50c993076ba9669756fb3aca5951641e9608f5cc42416f83efdc0000000000000000000000000000000017067ef5779adc304ff48c7365324a405bf1a48542d200b7e9b4dc4c9e9fc1a6dade7a1c4eea3c2cd0accaf24e7acd121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d446b46a1da8860e7b1b2e5a4c55e002568efe4ca3d89a6fb50611e02171bef6c73cd0ee2c0183a68bd4dcd27f62e0e00000000000000000000000000000000001ec1a911224d214e20b8887dd247c9884f5e935dfb10fce3a282f59beac5e1eed71340ea51ceedf70bedf2614e640c0000000000000000000000000000000013ab6e89eb8ed1d5ef71689d7f36a329a2330c2574142eebf1a06e3ae9fab96293901c64c6303d4ef65f01fc4da140d2000000000000000000000000000000001083204307cc9f15f6768b4b77df2f8a68995dc1ed35e5ed596aba4fc34bd5c1e1fc964987942394f64eac5c2abbeed71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004328e525ed1e89479ae6cc0364688a0e522cd017d13bfee686a3fb92d65055456cf04dd8caf56551e38f21960eb3ff0000000000000000000000000000000000db6c5fa6af10ffbf625d1f69536c7bbcfa4d1c0e8cb0feb7594560b17cb8e81f6de0e840b51f90695f3f411ed66a2f400000000000000000000000000000000124ec35c7026d428a5898aaf4944ea7c7085ac6ea4382486f1f297e20e49990e3961f1a734306f336e0598abb816d92100000000000000000000000000000000073d42fb3dd0e4997957f56f0c177f8b3ce6a7333acbc9fc4f4af76d4d99ed85f23df1bacbfe856e9d5c555d394e59891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000747dbc33ae074b9959935ac56203582fe20645b893084990efa71447e55c824bfd6beeb090066dd0df662543ab2838f000000000000000000000000000000001845fabec5e37b75d9ff1fef67f4132eb2ef8e32dd7b62c5862078ef6d6b3eb5db2f6fc1166f4a23ceba9587810738d2000000000000000000000000000000000c695dc7471908de469d84930d84443560d0defc656fd75f2a6b2c924c43714216100a965fd9edb7f03a812e97c9bdd30000000000000000000000000000000019553238f598b7189f576219db3958598ac7f793418b839d75525b4f2e46733f3710c32488f1dde45012ecb6b56cace51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e37445856444580b397fd12fb7f1651b0ebecff3ca9c46e781571e435bef3ec81cca9baac5c94ce9ac6b8b53d201d39000000000000000000000000000000000e33d411a9c7272e71ca372f6158d42d03cbea01621412c389558bfeefa3135cb9fb0afab676ff669061b7d56604863f00000000000000000000000000000000165a81c2aa2edc8b3a032fbecd022b989c45e67533be7938f65b0a09097f20dc80d8954bc97d2660c8d61c877a7d7ec5000000000000000000000000000000000527e608fbb76005616be5d3bc3f08e046f9bb7f994faebd2f9bafe9e947e0dd8aaa0bca0ca99e894f0aeb010326732c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001019c6036ee2a0fc7445f44eeffd2d5db0b005df7301518719d22ec06e35db46f329c1ee202f65daaef64d930a1c16f40000000000000000000000000000000014960d55e06f8163293b022caaca2a6e5a5b521fc65eecee47a512d8f0d5c242178f0639c2d8566e3541b887b090e0210000000000000000000000000000000009af79097fd2a17735778b799aa7c11b6a5fab703e9997e4b5fc9a1cad3c72f8ef05350ee6af74215e75324a5b7835850000000000000000000000000000000017dfd9e10c4a6e2080892140344dffb971fa0c3a2ef473343fedcf14be46bd6c203b6573b36d30906ed31eebe871ed101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180f84dfcf52a4efeb2eb62c66bb1bfa37045db287b111c2c491d37e7fcaa4bcaab57c0f9348758d05b7b8d742a60e5e00000000000000000000000000000000105171627eb5209afc2f8548f7741c810aae06c8cc1fb9f10a7b0aa570d9f99b58dcb096b5e24a66851af74e83648cda0000000000000000000000000000000001eb49a075e95ada314d6520fc0ba7b69cf25219e4f45f9b61cc715af4b78884bac6ec0c186cc85091ff00b4d6d4844e00000000000000000000000000000000057d550fa32942ed34be3051a40bb62109c17e81728727e30589c089ba50fbaef14b303f45ae344020f7c24ffc356d441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f07436cfafc0387e4e91a9bf4ec6c2d647cc32cda50a087a147dfbcf56f9816969eb394d7fdb0651a7fab78ab9daffe00000000000000000000000000000000047281dc56046733642436fcc44a5a696f3621b00c6983da544decf80316c4334a4492381f51406c602f2adcb8932bf0000000000000000000000000000000000820f91844679e3a0610a62ede6d5575327250e2fe09cff50dcc3ec86b4db46f5d33dbfcc4af1cdb87803c236e5646590000000000000000000000000000000012b39125b4f0d7b5abd1571b1f70e2a51b9d1f26675b5e66fd5f1e815034cd46c5f07bfa131c77dce08b96868ade1e3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018381b08dcf7497935420b01d123b56b3d6464332f5f3ae060ad469660b3bafc170e42986a5d08b20b917065baacbc7400000000000000000000000000000000198bf25afcb3cd6ec7a7c63d81ed6f659b3a31c31ea6ccc4f6abc62cd816b65a9d3804f259fefd97ffb7e57bbdd385d0000000000000000000000000000000000a09b90a42456589b0c2959267c3f0fcc27bb39ea331a0b21c33b4dc2139c89dc9bc5a67bb7be9a5f26497d7e941e1a400000000000000000000000000000000138ffd4533246fae7d5459022bddc29d445719a0a64629d6d31265889124accdd7a134b093c23cd4d1492a595c9407191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133305807ee9bf53cb90f0456fab5a6331ce50c5858b63e53e66abf70751939a2ce20dddd4eb1cd3c6521d09709af24500000000000000000000000000000000003e5abe0ce05207439166ba6cd4daae1a42b53a3ae69311e5b25e431361af3119d1a15850d41fb6244725e8f5672d7000000000000000000000000000000000147b1d6c406648bf43800f70e2625b50cda14ae55eb97c5eaabc4d8d408d7ffbbaa196e961d4a1fa3e7e0a3e402b671f000000000000000000000000000000000dff3e5a5c8a1eab0016a13f52b9914e9165a0de9252fb80eb776824e040e3a4d80b1213dc2c7a0f67baa463c52c182d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fc66a36e3fffc39e0524c65e587510ed1142ead5658ca4d2d2fa41703d1aad0b2e088ce3ebb41873af5019d44e98760000000000000000000000000000000010ab928c40e69811f64dc00bcba54c0ecff044a39d5b8dcad8306438793edb56dbd8791942be3d35124d36022b169230000000000000000000000000000000000b1cad3934f954ba05cfda8d62e9dfd821a43c25ab2ff414b35e6a774865725f7ce62270fa80676fc1adf754ac6094d000000000000000000000000000000000195d27ee66a6f9dc11ed948f5b3460a76c2b9f6d83bbab696027f660a6846b79f3a11099704379f56a08e32f5b1c1abf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ab75b888f1ae21333fd83cfb93e171907d8b1b95d45483a551df1c92f213b1de30201e7b04ec8e35e337f35d4fd109000000000000000000000000000000001615776a85a520867052a8c1ea19d8d1536179b7849d4ecab9ec5612687425b46ae84342e0b8b07aaf85d3568b0483430000000000000000000000000000000012d06192ea2a19bb822a2565fbf9f3e76c09c3fa48022724cf44bcfd757775d6c14fd030298719aa3f51d44ac26f3ef0000000000000000000000000000000000047d169f7de3196f91182fb3c78bfb50ffb0c528e3d6b76c97d6429fdf6948f5cfdb3700e34e013745d722e4955c33b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149d4deecb9afdb80204e897446d7d060b7c2d32d1209974f1d0d9683d21bd3060d3bc596286fccd52bee350aea761a20000000000000000000000000000000014b4d08962d26b0ee461903793b60b780cfa7516a322b15ad6694f05f6b6ea4879ec0c406b2d72db315d041ac3131ce00000000000000000000000000000000019cbe0432490e9ebb9072fc995e5666935acaa49adb0bc9129a1fa1799c75dc3689be1bb8a432928383b644adace0bdd0000000000000000000000000000000014a80cd9727a3727e3816b77beeb0c2ffebf164cabf94518cd61a393dfe17df25a539ac59b328fba8b5e2a8c34fbb50e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000553a50fb49c1dd6471d61f6714f12304098a893f56bf84cb1c752470b64350d3250bb652190758255eb5124700c0e9e00000000000000000000000000000000012f049c16b72edc3f9280997e0c4701d877297443af2109931d4e699c3eeb0d842640a96b97de9dec9130f7d14e21fa0000000000000000000000000000000009f68ecf06f2d2921816375c5bd4a53d51e7ed05a1edb368bc26a528cb11c3d1cd57870b96fa6d898ce9cb0d07aec0a900000000000000000000000000000000181850492d5e6649331af0210c98b7f4b79871fd4fcd30a0575ab0214a265720f3fc745ef1826b8c0132124ff09fa5051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011c4673f5daaf8d246a8536a11e2a0cdcb5164a1e159f5a84c66ac812af2ba01068f9aa0fc9dc25d717608db73728ad000000000000000000000000000000000a4e182f39301aac81b759d0a02cd916a1773f3a84e0e6cf334e5723305642510b9eadc550bc7bc18992d8974791e3570000000000000000000000000000000006831a8f215b2c672807a6e4e83df2dceff10ef7c9b9c588567d7084c9b59113dbaab212004f18978bf386a12757fbcc0000000000000000000000000000000005dd8291e9d7282f3ecaacd9d3496a42e0ed2c248cb737ca0d71738b5f6da02237472689e4c3e015e58c4e25559986571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189cff90fe76fd51f189b00ba1ccc17246e46b2d8ea3a19a92512db3e9f1a99fe118526488a3de0be0fa6866558622590000000000000000000000000000000013d699c4590c6f3b3fcc78c3de7b194195251c0f556ac641f7f87c6cadd75fdc9a0ab340b340706d17d53253cef19ad000000000000000000000000000000000179ef69c8072cf5d91192c38fe5737d3b7435089447ffcca5d3fce53ff4b013d7876498f47a9f718bc9119b5feb2eb1c00000000000000000000000000000000020057b3ce97c01dd22fa9b9a41d40fb5341c25ad24b5511e6f1cb76f7439e485dc4957bc302f641191bacf81929f9731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df71bb08fb418533d6c515712ab5c2d287e4e3635f7ece08addc8d49a938f475b62ae0b5a598a1dd0fc24b1e52ceaf1000000000000000000000000000000000c075a8624972a038b9e2254cb687a463ea70b82a5982a951457fc1223b4c546999b2645530a7947b9fd79f9119d7c85000000000000000000000000000000001410084d1ac9f4c21013af8f58b21f12a8ec3736d8120771ec88a14e00a468f4ee3183039f99dad7bfbbea3302b4144e0000000000000000000000000000000006ad635e406c52381d509d01235b1fc3c766fee1468faeadb861b8e90185e64b3d1415f965bab67daf683442ee1e3c6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053654574e8f67559d97272a6a63e0e19bbd265500661c974f087e3c669be142fcbb0c7cbe8a1a3a40b6dcc291622cd6000000000000000000000000000000000cc07861c5d539bbf67373ff4a2c28d78ac69ef226789e34ae567d4e717bb6f6a3605fec897561a0680f421d516584da0000000000000000000000000000000014bd17548e310539800ec617a0cab956fc4697c1b667d596a386abc8d8cd89da79bcf563319634324574db6b2a138150000000000000000000000000000000001707b7d55315deed5050e166a9b236d12a9e8b70beea93eedacd6994646bc99cd787e99387848c2a68166bac34fc585e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134212f232247bb0146903fa71298799206e1dadc81c8a5f310db5af337c705f9e9558c2f2e209a945ee1e1ecb6969dd0000000000000000000000000000000018ea6ac16702d131745da69b4d528c257a7ef0defae1940b224e22ac565a14bb539249192c8aefe1f763168d64125a610000000000000000000000000000000014dab5d9e7201254b90e20b27f224fa29e3593c3dbabc6fc77bc56a5b897359ed24dc887c574aa78a9d80be912f7afcb000000000000000000000000000000001508d2694d9dde8f8eba5913cce7971fd2ff9bc262be0b52916fd9863ef8ca2e92117edefd9e9638f6aeaeea8f1267ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063ed171793bd5ea72f4bb54a7edbdee5fdf1994e55ed4fba62098d8145f95ac6aa14e2b10e7b2c9a6c716c4eb3171360000000000000000000000000000000002a301c64fff7deb7cec1ac0e62fd85f88836f6fc982f59d7fab10681592c6f083d32fcad434e7d8f55e7928c27c70b000000000000000000000000000000000028325b5057a14876f6a343076681dea465c5eeeabe48496462dd9366d5a3fce059ab8d1cb72389d1f8c2e61b426147a000000000000000000000000000000000c8294dcad1cd634bdd3a61999d0fe014ee2a3bd803c9c0fbbcb8e3c0f9a41446ab3ce51fa26bb243ece93e21441cf271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018073daaadccb7fdffcbd0b46d1e9ba0c9b6fe2ec2e2d5fc862fc3870b9f0e7d18b26943c526887ee01b6c25448c22e7000000000000000000000000000000000725c813a8a04e5f5e49cc773500370e994e0000ab38307e2de0e7c66dbc45154236bd100df2a589dbfab6bf7a970f4c0000000000000000000000000000000003b5a421fd3727ac7680427a3e95c1a2ef43d6383677e9c3df7c54dad239af2812d6873768bb4a0800ff01182d18472b0000000000000000000000000000000001d7474a2c9b17fc62fe996ca755fb34c91aa29ac56337d5cbebd2390246b6a6e400d5b6d2710ffd7012a2f86c6a403c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6c095c2d195ccf82c2b7eb53ba940b535289df2315f95074397cb758517c3fddfb3c1f03bf73ef02974ed0af5c49500000000000000000000000000000000006f1a22ee51f26a3c9351678c5818a7168bfa518858c7c7a54df8267fb99ce3216b9f502f88cde8d3dd51e5dc75ba4d400000000000000000000000000000000008dfbf3cfab95dc2b8cc9173758d48171b77226d2613f1aa880e92317d20b5a455e668f5e7fa362ebc90fe73a569c020000000000000000000000000000000009d7e5bbac22580de9b76c56128baa3ea7469b861dd441938df0e90ca7f9697a83a78d82b1bda523feecbccc82623b4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dc883445fef661285378b6e053f72d1b35d6370a0b720c4a65c3d0a017cacfba8e43856b46ea4fb1a423fe1f8a855d00000000000000000000000000000000102e181f8ca99cd94ca424e8471b51a856f58e2b9b0efce070ab53e48836cba89cff48b174d4c53dafdc0a34226483bd0000000000000000000000000000000005f36f1884589f4943d653266157460ddb048ca3eca86f87a4504cb03494ec842d4a6c7af42512cdbd3cf8e680661da0000000000000000000000000000000000a30548236a367de4f5293ab75aeb15373fdea9013d151c253f4555f751e2ad157ea295024f73a77bb0dfaea3ed386a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f28a3d7bf39c023e9dc1525c40c638d78d67a6aebd12edff007f6b9b45218d9968d3a98990ad6b14b8664e6a23f8f2c0000000000000000000000000000000017b70c626bc47e587b92c66fea71159bbccf3d3c3ebeb34879984aa81dac1fe88ff0dffbe60201028fd8c08740e276840000000000000000000000000000000013640dbef1de512d49b7e7a9190babef1238cf7fe7d69ded9387bd618b4fead5441323454c5379d624a53d1f00c81c500000000000000000000000000000000015094ee89fcf148fd0066539de3b6570fd5b8e4d47da981b275781367a5bf47bc59bf0a24f47e8c40b4847ee28376f201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a1bd75c543ad7af0c979d3b9fabbf20c8362e7a3b7ac2e23cb27c73c5afdb8b67f0ecca73e2e9cf12670e9ae25013700000000000000000000000000000000081567a99428365cb7fed72e455aa79fbd789066ef7a8d501caf02e6978f5e3010dd904a3660ae5a195ebfa2d47444310000000000000000000000000000000005a51918389a1c09e14fe965fcf079825c5704060d100e1574c797d9af0e177c78ba4644aee8484dfdbe98b826e7177000000000000000000000000000000000143d0cb5e6a7527e62a612d35348333b4fcb8280272c1639fecec02a44ca4864e7b017e46438b0430fb3cff4598fecd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fb3399d231aecfe1ca99625dfa94e4fab53de98304286abec4f14677351890978489e3093ccc48223b2bdb2156d08b0000000000000000000000000000000009ff9b663e90ab72f7a37c47d4d4397c5fcb610daa04bdeb2c8c9a6a66f08ebc13b76252d7db7663be78123e3d4c4ada0000000000000000000000000000000014fa39d8892b67375717446244c3e18877aa4bc6bec1d235959acde5ecab625db53085a75df043f7092d91f586f26666000000000000000000000000000000001468e90a48d3a9b78e8b35abb9096fd11ec88f8a7e3b3da091e122472739915c6aae0677ce185d466b27eaa5235c720d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d9f1aaecec18cbaef602501e20b313ad72679d940edb729b1095a6657d467c80a91eb85877cebc62c0b74322a2202a0000000000000000000000000000000009afcd48687ca83a80da905908744443cd05b3d9b12d7bb311780bd5c6292cdb55a9bf2e00bb8cdcfe861d8d841ed0f4000000000000000000000000000000000c9fa5da50ad903a7f66d9d8aeb332dd26e9e0090199252f53ab231327029e55754b446e93b8dc58d7509a5175a98aeb0000000000000000000000000000000013c30c1cd7d26d9240477f01ca7cfae0d06f1ad4a6c6151b75b4e96b3517fd5c6e4af8480c4e7164b70a2e8b7668e65a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167d0387d68c150151824974945fb46ff605ff5b66d690d519f3143af1116b5e71a6b173881a455357cb0859f14ef39f0000000000000000000000000000000000f193c9f3f1edcc2b9d7619f3eb72754d7458979d804e20574f7e0dffc34378e216bbafbc13e279c312b5be09e930390000000000000000000000000000000009805552fe2979b1ed49eebc77407114bc5aee0cb9091cb3fbebbf0ab909f79b68da3e12b4f5e486257ee7e261df00e30000000000000000000000000000000018aecc8e940beeec9a8955fbcd79fc7c333258f9b6bd70ab488d20411b296c61bdb3715f6f693bfdb058e33686ec25b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025c25b732b0bd6fc5d20fe3533b756e8a4302e05fe65470050559e741a942e32da8133af8e2d823044419e0b38779a10000000000000000000000000000000000d18c9704c8e26e6ee80cbe3f3aa2ebc282e21496f6d74f5b5a8de7bc53e08f1c9331f20cb3ed1b64fb55a6294fd8340000000000000000000000000000000002e3345d57d4335b81d44b88b437c350b12a20e3867e85a8547fca4d618b8cc35122d7e54b7e136503615cfb4d9ccec00000000000000000000000000000000001eb2b67575f30cdd60f052128e0fe44b17a9fa2579d9782bc541ccc552354ebc0f524db84276f59a109fb4b6335692d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d1eeac3986fddeaa9df8424bc7bd44c7c29acb3de60f467e6c812e9b7f14f99b707a4a198d3fc70ce3a39c5ef7509d000000000000000000000000000000000d428063f48d0e330c6477a5c327c1766a2d52ba4ba476f7b83443003495c3198e0487f335d6b79dc9636f576e89805d0000000000000000000000000000000001ff67e92da087fc1fbc722642227e2c1aed8aca10c9d8334971382aec431e85522cc76aace7989027041f38cd31e4ed000000000000000000000000000000000f3d1fdfe3a81da72b59924fd2c71d4007639cada1afd95fdd75e141e86e6bd1a334717538a57f237e744f853c175b281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa1513ef7c596d45ecead6af24b8fd3308ad308019de79aa5ae00e70bd0aabc4b8137110d31b8a6c18af843f7062ccf00000000000000000000000000000000168250e755b721750da8dc38e6b20e0f6092eee6d428e49052451973462057e1f31b6a5e4a7e0b3347132369a33f5d8900000000000000000000000000000000185701edcd71430466e0c4a7fd06dbd5abde9cc1678467bd8cf0f7ff5cb83f6afcbfbce74241db2c206222275534b1de000000000000000000000000000000000d5aeb387ac2f52a31f412b28d0e65994bfd71104a41e052061cf4073f890d2e81b11f20f9783d8c879ea0494ce9febc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042dd8764f7f1ddb50f7c8fedb839f416e91c1b4f59666bdeef2bd9cd0c9f6d602e98e368cb0e4d8a1217715eae946c30000000000000000000000000000000016e6ec2c26e447e8a5f9520daae8a74c10ca154902a7e3edcf01efc40927f897f84f28f37ec1ae646236f4ec60e377fa00000000000000000000000000000000027d8c0f382f8b4d99b659ab6aaae365f0a733a44a2f3676adf5bf28a546757b8b09e7724de5d7ec865307657101b1b100000000000000000000000000000000112dea8cf3872944a1fcb334bcc6f331b0c6de8db72e473ea9c9d914febbab6358fb3d7e3830827ef705a515c7f03be31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012ce5f7f54026ba1d41d155c9271a0953b25bbd3c6496ed744f6589bd120195c9e9de66973af3f92295c8d99b828072000000000000000000000000000000000d237e432fcf3fff29f6c52ee6096f57345934156013bae091b5674e99b79b5ea37bbcd6c1fa92830a99d39c2d3de188000000000000000000000000000000000099cddb0866b818a3a47391a97eed41e82f119778339e40a336acae9a96ee30cf4dd2848e61f2a72a3535b2118efe67000000000000000000000000000000000d6a97fd54a765f7d7ee5a0e5becf6dfd593ee1cfcb4dc35c6bd2d5a7567e738982fac529549659c820225623e7986241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018207ef47f49a884cd279b216dc439d39eefe4f0c202a25dc246e75ab46b8801eb1ef55d9de6b0dc956d2bf29ff8a89d0000000000000000000000000000000000682fb0db1af5cf1ae28f99e9f704916fa1a89eb9449c9e68b45c9319c55feb699baedb65d44aab493dae61323ace1e000000000000000000000000000000000ad490c4e21f552967797a79a77fec33772045c0bcc0dae7295d07bdd1a502ec7f1ec093f3b839ee083bce6d9be58abc0000000000000000000000000000000011fbf2bcdac191374cd2eb64866cb2864c36a48dd7d81dc30815e6d994f54237bcfe3d253d6badd73125352237089b2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89b43d6be6666ee0eb1bcc876429946c7f7a37025286475b7ebca27babd263c5c804314b436da846d27a3fab08c99f000000000000000000000000000000001613920fe70fb0a606bdb6f09eb80dea27ea78787b330100ac29ab93e5f830ed35e8e8b49e8438690cf6f8771e62f9af0000000000000000000000000000000010ac3245ec3b9f7e8efa9931bd727829447a5c9d86fc24adc8d159accfcf8344a0f3f026ef35af0bc45637278f9578ce0000000000000000000000000000000003b2ac3248566508a643b0ec64fa5d886dcde11ecf1e1b0f3a55f05bb84e042137aedf168675fc25fa0143a9d4a92fb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e84ef00a1b34974ae511b95bcf17845361312b2cd7e9c02323038a6f347d644d3753075af11312e77e8816540281700000000000000000000000000000000008f9ad141fca814ec974d4abd09f01846f1f4c99196934857f8eb49b9a8e0fcd281a9ecc6846cb2dbfd34bfb28cfa08b000000000000000000000000000000000cbb0894ae780c336aa88f479d73764fdcc4b73625e862b610439d627eff601a4ed8b5a8b53f4e2d786a9ca3f74da03d000000000000000000000000000000000b2285fae63c4a7860bd021bc5d6b32336b3629b5f635307c203ccac1f954615e6252c8c5dfdbb5846f6a5fe55d615be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019291c6f7a563074d7bebd65fb39d264de46e5c10cbeacbf409acb534aa2160e1a77f36c3c934fcab6e3e4b179b2b8450000000000000000000000000000000014b374ca1c40554dc70f78f36f838db9c6edb403c2500d8eee09eeb8f685ab565654fd1edce2020d533fbe8062cecdec0000000000000000000000000000000006a6bd2f06d3c54a33e08c659ee028419897243d826a90be227c53c00173de0459aafabde8dced73864cf104d4f668fb00000000000000000000000000000000119bdee636612c560c20208f5023fb6fac042f927ec3bf170d60582f05b27439b222872de2281f9a26e00c37248c3dec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000059944bf832302da5759bd3fbf7190031352df44963275e5b749b8e2a19b1a9cf56ce676a7c8495b1e8fc10daf731e700000000000000000000000000000000145ab4babd61ecd83ad9dd035b3195371dd6a09f7988886a6988d39b93ac74690f8d293c58cadfdf2e52f1a89f1e13e80000000000000000000000000000000000e9d3b2aed2112f91db906d6c33de7df37f4fba17ff2ffd0b7cdf24ccacc3e1b631085e64b6792ea4caeae44aeb8a49000000000000000000000000000000000bd91ea606403ce81e177db5ab9eb3304bd248697f71f6c545a15fef90a9612e447104f4a2becb76213b3f9a3a1537391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035200183eced81565c8223f52f7eb624ec3f9ec42fac8c084fa52082b439c32d725523f21095c85448fa4075e6264d1000000000000000000000000000000000f9f49db2cdddc9066d1efffb6c3b854668f73699846a99f200e8cb3d36424e706bf7da998d53b3ea25fd6bdb493ff280000000000000000000000000000000019303ea1c21a3d79a1c41d1bb192017d0d9186428095bd996e56bceff7385580095cf4d93be3fe11aa9d1695fe2d8e410000000000000000000000000000000011c972fd52755534001377c98055c13b59d7eca825cfe928829eb54cb27089ee5bc43d98e126e4dcd9901c9eb9a846811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cc09652fff38fe1b94ce9c22989e66aa990d58e54b74adb3b43258a3dd768eae9b0208967746e7b1fc81274d652ca700000000000000000000000000000000112d62b3918e000b487f1e419969dc8f6ff82c126a1e5fe85a9647c3ea2f7c7236ddfe084e4ed61ad417fb1931547b2c0000000000000000000000000000000014cb264217c66e9a53f4ff1d151956a4a98111bbb42bd1d07a528fc26bb8181ebfc51f67bc3a42739834a5319800873300000000000000000000000000000000157e69d3c1c7cd190354cd51ba11e4699f0db61185bc2aff603198c23ac82e6e9f5e5a9a337efa7d66d23df462c95d4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017259b78fa05fd691262b7eba64f90bc01d52189cf368948bdaed8419c679b31148ca3897ac92da3868bb46cbf364f33000000000000000000000000000000000c52df82928f0c1d1b6af11ced001758939b182e612a4efb8fd4748f4353ca2c8fdb818d4f6801f1e1b0372fd463efe00000000000000000000000000000000000acce64cd8bf0ce97d71a80c335cf6f1634d50c44a8489d282397021fe06a8ca8889fe775d909ee4d5062dd5f8e618b00000000000000000000000000000000059ae0973d9afbe900804dca9014c116e378be8d404bb956739af4fc542d55188e00abec42dedd8ca5fe0ad13bc71b461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c27e23a3745c3494256e04b1804fbc26ece509b8f615e8969d28d01225abcb480aea62bf24ffd2897562ffa158464b7000000000000000000000000000000001725c7e705b5fb1ef59a4236c6ce138914e1bd7e9db9448fc89f5a00dfd24c073922d3b1305da378b87213044f472f6b0000000000000000000000000000000007c7b4b5f5267ad22776151ad738d68707c79e43a8344d891599833d09a4f5b202910e49dbb4edca7cc3da966839ff46000000000000000000000000000000000977b438b93819b4390a8a3cc6c7ef0f4dfb2db1927c9045645683e3559241f3bb6ff4ff59f99652c07ed05318c4db1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163372d3c45f9e2eac9b265bf182d25cca7c46c236e9d91a4cc2db4d735b6cea5840a5623411e6dd7f09f5970a1dd6a40000000000000000000000000000000018433796811c2b9fab0c50c14538560a1828427d60fe422c37f3870a132e5e6a219b91fc769235d3576d246e7eb3817900000000000000000000000000000000077251b75cc7aba05269ec992c40f40b5bccc3cf04670e31b0c11441c6fe5e9f4953f3918b81a2a0efb3611a6e179d5a0000000000000000000000000000000008716216346f3159e5c85cf8078d9f3d29ef8e0990ee3fbb99b17f12a8d76a3ba0526d6eb1f247ab3fc7297e174a53931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007609f1a9a21bb51db41e339de97520003bafa842ec8720daeca8e87fd13deb62cbfc342113a773f7d236c747de99e9d000000000000000000000000000000000a394999aa00a495123b848bc041f1d8141d104b10ff3ce17428c8527d9425fe7f6b956e322db703ab81fd644195fae100000000000000000000000000000000101e1d860ad8429fb74d2e6096359be629016f35b6cfb06b82863648c74ee3b2de1044a41429730c6b6b5607a065c67f000000000000000000000000000000001670e95e6eaddcee88aa9f7ba4135f82ed1712732b0fcb926b940f78998933549d1fad909847d46724eabb8b606e4e5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d51b4fe70fae821aa68dfe507e23afdb2f6c5dfec5bf9dc93f1837f8861fa6b680ddf3a60cade2bfafd6c0513be156f0000000000000000000000000000000001963af7a863bfd4bc34b7ae8e8a401c23f8626b4ef4e73f645b161b0683cd8f8474d718595b2d98da50554ab67fa7680000000000000000000000000000000000e20c4620ba58590dcc0578b6e2e02b5310ba488303ee3fcdcb9d840cd9a7a09c366494ae9e1cb7febffa56cf18e78c000000000000000000000000000000000462f86a7341e0621ed993e7b14badf8aefd132915dbe99890be7d6f3f204135ee16c6ca90e629156770434e77ad1c8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cde12d75a6e6e62d8a08af6b2fccf448c19a525f5fc7848023affb0c9ed310303c24bf3cbe5c9de81a3134cd1ef031000000000000000000000000000000001386173a8e30a6e7b88474ae9064d9bdbb2c182940449d843858a80202ec9fd7fe558e463f789f226bb211490d181e030000000000000000000000000000000002fb942fcbac015449c0448ff02d562802bfcaf9681661caa78b662e34d44bcf5ab828a5c8b69f7c71ee4e3a073b58e700000000000000000000000000000000166935836a70d0397e751bec1190cfcdf2e80334f04a8db22879f4ac236ecdfcf26b5bd633905227be2f1da4a37b046a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005780ac6e2ce2fe88f13e9cd39e5a2206d450289f216460bf1e49c26ef55c5b85829924babc285e1ddca62935e569f340000000000000000000000000000000017d4335cdc8bf515147f9b856fa8e911c77807e1e94fbb41f7c8ad576eea5201a15e916d357535ce830b4e3b301bab0b000000000000000000000000000000000ec579b70f8c4309b65dedf0826deb04736e8195fa83a6a9623556881372815d0845cd0e6bc7b80915e6f7c76e790fee000000000000000000000000000000000e88e2887831e6cdd4181795a6259bcc91eb61a8cb81651c73c4c6a07eeb9233b960208cb482f9cd8e6803be6646f8a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009007c0b8c2429bb53212c6b84481831b2756ba4ffd6cde21aaf100bf0d682798671120d873d40407e8464d91aeafcb5000000000000000000000000000000000c8e1d8f27d15d989bb3bc8274bcf06747e17971ce8865af10bb5a0cfd2ecfc999133ef012469761369d9029dee795170000000000000000000000000000000002db7c39c99707064e2746248ba53ff6056a3372fe573e3da65298317297382af0bdf78e53f762082ade305e32846362000000000000000000000000000000000e0e7e19f352f348d83ac7cfa8e7ae514533f972850eeafe97ee7efa01f7d9d032289c4dc678ff1dcb9bab4e3ef775b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013def788f3c083c0143204af94457ca879a68ec67203bbe5c5e0d170fb506d061f9a412895fe6e191aee3f59b768e540000000000000000000000000000000001565e3884f0a538de3eff89df68db64555ea011361689b1219723e79a236596051fd788fed752226ed9d4dcff801ef84000000000000000000000000000000001040c8e0c3fa7d654b947b0279a2cf3a4cbb7c2317889496133585c0b7d7f0f15a3da197409925044d38e05de98bc9310000000000000000000000000000000013300a437ebc507312c0378363e79e2cf7c9c2dfa7ff3e4d1806adf31fc19c8525e5714808b525e2dcaca717a2f177f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000244c1febe43602487304751606d4e264e922e367d8387dbfb115304e067b1f5f66765c58eed6d9147e3169e6a647f2000000000000000000000000000000000074ea31af02a6aac1eb2b9d43fa35e92caac00d5ee2856ceabf24ecb69ba50bf8582b1b5e9a36a2ff0ad2e20010710c0000000000000000000000000000000003d12fc5cc498aece813ad8b7c9bdbac6683244f765186f39621bf96248d3e0ba8cb7c0164931653df1c101290a6652a000000000000000000000000000000000ebbe0b846c834608cf5c7b6b2da1616257d8cc551386766e43eaabf56b041419d595136e595e589d00ced3c073c2a5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027dfbbe2799b4d17a84b633df3056fbeee5d5254a1cf2740b6b246bbe3c7f7bd41b0ce7c5d4eead51b6f90a34ea628c000000000000000000000000000000000b8cfd51c527b7c68af7f8c2a013bf33ddf39eddd955c97c880539f16ea92e3194aee1fb2ea9da3522a257cb7aaa7a44000000000000000000000000000000000658bf2cd917aa308b881e39110a72a06eff60617eb91f7d864525762eeafde8653ad42ea2e6297820a3d974b20fd3a8000000000000000000000000000000000db6cfdc714a9d5f2d5fdc7715800273079dbe75715f939416472e1154e80c43d6e2bfbde2399453fbd682cd5f1a220a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffd2ebf6aac8247c18f1a9d111ef187156138dcac9bf7fe01110c19885f0af511ecd5ea261bd4af36c3417b0e0c846b000000000000000000000000000000000ec0f821c0c1a297f5ac974fc0cfedcce1dc154fc0d93be10e6bb3e75a8e638545161fc94d5de27cf063c6bad92f3a30000000000000000000000000000000000dc0c8b13f55e2192fb537d5f6c5da80cc0b935c54c03b02cf2fc493695dd6d87363c07fbcad0cded3b9a4e6b4e296bb000000000000000000000000000000000816213c92aa0e50df698eb435b2ec9d4adad4a4234a5ceca8c2acde7f5513abeea1c4ba2d3acd52d81a5a71b00d8d631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b156b96551f7c49c46f16eb065a1cc07ffdf82d41b0b0ab00b7fdf60748498c0bbf2e8d2558fe3e5414205f7929cd8000000000000000000000000000000000cede2a6e9e959fc87a98155c3065a3174a0f2af45f89f02c58eac5e5806e9a7c82586dae683a7bac52055b63c195bca00000000000000000000000000000000196ec658419b89a73d47eafc8efc018d91e8250b0b3b51eef9ddfe046fb244e6ed509af8afe7e4ec1f04ef0c30d6177d000000000000000000000000000000000126f9f054ab8f5728e4e055cb9bf5a1df678281e74ac9ebd83b9854f170759fb052c81b41f3cd1525b4a221661879b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001514cbe8e0c8959f8076f84aa05f49b80e1050583d946bbfb5c7cdb78c971fe1ef1ab1406ae8b7f8eb892d1e2df7f9f400000000000000000000000000000000098a22a53a99dc2d6c2582327f22cbed632cab7f6a8202d8f4fac48d6df66e70017cd0bb4aa83d817c05000dd6abdf5000000000000000000000000000000000180eedf78a27b9feb2c3aadec66b5287677829989d93af9e25f003b3c11d9002ad76bf8787d5bb37d629496f2040638b0000000000000000000000000000000010c8e1f57eb51ad18a42ca8f02e7ed1250e1515a122571caa5893dbc660bae2d2ce91f4c33e38061493aa6ef2eda94801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd89253b00beada2601f18e95dcf3554e9bd251fc2ff3effa4eb7e05ac50cb0c533f974c61cd4552d9213e6c04c5abb000000000000000000000000000000000a5094c7e506041a1980fdc800058fde643e07009e4a54f2040478158b0e18b3934d9b2c0dc38ca226395173df33f7b600000000000000000000000000000000179edd70799aa786533adf0d788181001f10f3ebbc08f72edb965b77b3adb1c6825cd8413d495efcc2beef03fbddd2c20000000000000000000000000000000011aee05037475887dfb29015355d3adb7487ea9244a920d8851a83654102c2df41264296dfc326ebe927a37ea2f4f44d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042bfbdbb5819cfeba687c3ecd5a729ca9eb471bf4f0ec949e1aa79d179056b53a3836d8245a2dc5455518fbe49b9301000000000000000000000000000000001131e13447835cd01c0f9fbe03653afe64d0177e3fe010dcb071f4c078e86e997fb761ac3c28fe9c0c51f90e62a1018700000000000000000000000000000000043625fadd868b79d5dbc93c29b66bed78d4fa2ee8590d3cab9c039935fcdaa6d1dc24bd5850bf3d0bf2b9d276ded3580000000000000000000000000000000007a0d010e5cb25e9baa577f2ce4cf588a7a5f794c490e389dc7691ad3ef9d36923a6a5e05faf9f8203d393d6f17570041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011313eb2c0368f64834c62ea4a21699025f0b75256a2197aab03846daaf627f0da0816bfe63e84233ffa0eb5717b2680000000000000000000000000000000001743845da7cf3043ef54d90f2f4e178eedac6c8f2ecaf717e6524cd93e29d0317252a2ff6c284afe0ac823fd96837b73000000000000000000000000000000000fb7ee15f22ee8de7fdc4359250c883bb9baec75f2b0ab56ea7ee67e46ab092cd285846c31be8171ee5f240abdf0fc0d0000000000000000000000000000000007ed200d16f2d0446e23bf4908c099c043e19e0a1a036608d0ec8bff652e33e7e15b208bcf7729a55360d324611a0bd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001677bc58593f530326550b484ae187024e2a087fc3be7c13a99cf6780c227435f5341db8f001f6df9386ed5c37a9153c0000000000000000000000000000000010f9af2a65b0b34902f6eb5c020f4029d24cc46961935e4fc83efce8789b59e90025bfd612e5a8930793f5d28fbf257d000000000000000000000000000000000abebcd8b26f10915f074bd253e052bdc3fb0865ee88745d32328292bbac013602ecb388f059c880d5a4789abc573496000000000000000000000000000000001102d15cb931a34e8eb016db0e46450133429502e343ae10de97b8a407c99d4d7beff207be58e928e6e742ca911adbaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ecf9a2d036c7f5c5f789bc99a13da40b6f2477afd666f2c9d1b27399f9983a4643f9330bb6e2e5b42813cfd82262a8b000000000000000000000000000000000e075550adb19de7f9edf0c80ce20598ec815b6f622516ab171aa69c697da5d8dea8137dd8d6af6e4f4448014f13ec5e000000000000000000000000000000001872ba58fe674545df41d435d3957b875e612b3b92410b3f30a3ad59de6b2d39ac1f99662c67c37484aa1bbf7e280984000000000000000000000000000000000172d9bd3c908d742d1afc5952fafcb020cdcbf41e2efd725a26a3eb1a40797a487a609a4cbaf6bb02939e4af2553e121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7e4ed9ce55921795e50504edf868c8afd9524cf13fa028e58f02565dd441b75c178321a7c1942fbe70ff3312d6543e000000000000000000000000000000000f1bba6ead692f7986db46196166ba9b9a616894be468cba3982b943ecfc72e4be3e53e3cefe40147c4276814e600ab80000000000000000000000000000000000398fdbe1b93cb02617029fd500c6ff3ba63b883dcdbaba4f0b143fb2cb035874dcd3a6f271b9e06df0d3c12e71123f00000000000000000000000000000000115d8367c5bc1a84af7f4a83d6241823b805d5d35740afab16d232130d7fe0a5dc49a92fe9fa360afca2f09d6eefbf381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006156bf218e8c2c50b927f9596dc17aa82bbf2b5ff85790a1e2fcbb422b61b08f3a976df160ff74623c30c6b88c65800000000000000000000000000000000001701fb001dd1f3335eba33ad5bb740b7ad917f0eabe8ce5d297491ed44391576dad6fac7bb18acd32692c8b92f8b99400000000000000000000000000000000116f035c44caca417117d00c77a558584a9464d1c426bf8d1118f8a3bb4c1b71db36547bfec7dfab188d479b8fc9f3e7000000000000000000000000000000000322591bb68f2409c483d34a1e55581c141f9d6c2032b2c1c72057a9d7ce36974141514029f99b245d32506653ed7e7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101b19b296daa4d12c0581ebeaa04b6dfe5fa3112e8709a7e2fe97242759efaf20e2e13556dc1af09c033f30b1c51253000000000000000000000000000000000794f9adb5ee6355123673c9226b12628517623db368773c1066e28876ffa1c15cdf643569e9e1d29c8c5aeb2f7e307200000000000000000000000000000000093a88cf490c92177c02478e05e340b888a1a257a76c95cb5b998e09c152f28af679405512887c0f7d1bf80297d0cd30000000000000000000000000000000000786a9148c62aaa8bccbb48f31332865dd03f2bb58ca61f116425f5ad935e45ed4074add241b62b659452838c231108b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee1b05dbeec7d3f5c8646f4fee56c58155a4faed7fa29bd0b36316912a1f70b4d6b15c3eeff607a8bdc9caffd800e9c00000000000000000000000000000000028a644639a1f95f696109bd9fd771b7a87b2057ddc5068150cb3048dd57b5ca4199924bbb779a5496a953b3617f5af1000000000000000000000000000000000b71ef7777733fc3f3dfedfee92eb1b883760a00cb22d47e2bcca623efbc229b5cbc443aed34684dc3530841548c3c05000000000000000000000000000000000d4d5f057680ff3c45ade2ac0729e85b433127899df7eebf4660e2864e30cb30ac6d0a9bf2eceec6f68a7a0128ac86d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016f8ac5504f9b44ca40c1c6af1b4cf9beab80d4e356e20234740ced20614490834d50b264e56594ede33e3b652ef9e50000000000000000000000000000000016c4a07044a62d85c37000c9f696e5bd7fe4376ad22216005fe7d9a8d8c9acdb40d13e36959e03a810f5f9e9cc386e400000000000000000000000000000000009fd2f411d1de7aaf889f01f4ee7d96c2b85d312d025d4c11ccea64ad951adb3e74f235e5d28c5e0b22a4c82ace74a9c0000000000000000000000000000000013069b22e7304768c4040e1a07b79a7517138d97b23c472cf2b1355c940495b931dce2ba62cc6a5d6b9cad6e8e05388e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bc23bd1bdf7d6cfcc5e2eedaae20a4e339cd05cdb131c736338b216765e405196ef09b349721609be9826131d44878000000000000000000000000000000000bf00cbba2e3b686ca4ea3a8fa417cee87fbc7d0de49486846987b6ed995ad49dc177776a95f1ff61340dd74630ed4400000000000000000000000000000000002f9d5215809f8bb74a21916c19aac86e653a7535c43800da58001a5f2a2f2b26e480e6b78ec647fbb51ab129832cd53000000000000000000000000000000000674999cf32314eddd2cf06cc4d646b30ec07cf062a417e4eb17a23fcaaf333e1cffc6a0126d452a854e28cf92b898051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017038fc18ba5ab6fe6e8d3e6d124c6ca9a1505203a9f5087491e8a25862db909f4658b0fdb2e786c7ef816b5bac45c7a00000000000000000000000000000000038e6ec25d840e7317a2883a30331cd1c3e0b2517eb0b26dcf2f001abb77c5a08f1205ed2277380868b22092e1de85fc0000000000000000000000000000000017ea8c69d4ce8e12a5ed137219c9d6e4c662a1d5747ca660414b34f8f810d84c68a08f8fb31e3a0e79a928f5320435cc0000000000000000000000000000000009768b057adf0efc9f74cc761e7d784d46eb0eb388e55e9825704c5e783c640c65f7599cb59febcabb278ba5a950fddb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d8a5bf87c36be002f5e62faee9a5cf1ff7edabefbdbddda85c82f236cae9b625920194b1b0a27d40b197e16baf1e47000000000000000000000000000000000b370a463ad25fb5812ff7a0ba468d8ddae1c38881cc2f88314df3d5b52dbb61df5db466a31dd26b75a6ef4f3c8c37be0000000000000000000000000000000006094bbc34bbd8a802f775f67ea19feffb2ae007ea7b976876b19575a917eb968c53c8d3bebdf999575eb363c1f229520000000000000000000000000000000010cbaf057b6e32b7faf7ef99c3403e8bbb65040f20f85552d0f38f0e6468a4fa72c314924465632aaabf9b50d8253a381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001996a1974dece1248b83b80a4233fe3c0188c9f687424a4b19ee807be1a24ccc6cf6cb3ed4476e043e4cec57eca5fb66000000000000000000000000000000001997d422dcfc1c375f7755828d2c841826c7627b726d1595fed32a0780365691b5457357a2617c48385279376a0202f20000000000000000000000000000000009854ef3dd4eceef5bc2955316eea0684c6827ace07583b789265d788c44dc7b9ab8673002e98bf766b67f964aed8b700000000000000000000000000000000002e03dc04be97478afe07f0b6d160a4b1a1ab4f339613a6468d92f0a1bb08c6c3f0d6ae5cc6bc213b37c995122b0a6131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123167916a2b5016bd9031b847d9393888f3be3a862c615f5144598e1be6051cec9c2061bbe590c0f0064704cc160665000000000000000000000000000000000bf74f7eb3decf172813caa3901bd5569159ad30e71085744cb29364098fa94ae3e1dab50bb86f741a62f9b006b9738b000000000000000000000000000000001317ede6ac4224a3fae94a13cfc4210d170a6653aa34459f63f1e4f4a61476d197e177403b604ac33b9cc2de93e63b5f0000000000000000000000000000000007d550e423ff88e849e8ccaee57441c25f481e00f124243f38f2d9fc675d1e8a18845c6319494d5aaa89b4110330736d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000078691635956ca100a47eeb0af5af3b1d0089b3922377eebde4a7d07401a326211505786d011b1f6ee308c286bb20ec000000000000000000000000000000000f7908d5db053e1b57242532c2af87db634beb9fba99631af7037844840fe2c39dd000e8fb18d0559700fddb395c2ae3000000000000000000000000000000000204a1e215e7c01c65ee576a08afe014b4e1204fd4d0e24cde2f561af0b542a788e483a8b2766bec5f6bb84158d9a5290000000000000000000000000000000001f67ed7aae81a9e7e948e4b65ad89e88f9a9a75d015d28cc516aafee6162b410f89d91276e6b58186828639fc2762c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7d078a6785dc1689ec0a5ae460508c87db47c11460b5a27677b598f87a35bf1253b37f53ab83cef0c13d6db4cdc9e000000000000000000000000000000000014cb275bc56ab6e2fe3b657998226e4e6e61351cd98978e5d1860be5d30174ed51b7cbfd849a4725fd0ee371f197fb10000000000000000000000000000000011844dcc9d66a0b018aa1bf0fc5ceacdc984d3c81c4127c29f84fe048b50b6e32d16c5c48892e6081952715f145e0a66000000000000000000000000000000000c590593ca7968d9420bc354e9833dbb856b9c4be2dd1eff8319b348dd716f92f02a00fdf0eda30d3e16548d8098bf7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbbea141557723d939844d8d389aaeea923f29572922ecab9df9a4d7aee8298f9052cc7aad8718d804add3674b0fbab00000000000000000000000000000000181323fa4a9cc093181cea0426599d10220f9fc8cf866d4afbfdb1102279ef3511e461890e88198169a7e80b8eef6e19000000000000000000000000000000001045f55e6cc206ff627aee735fcd30b7dcdcd6bca99033b4e5606c80e3cc21bd9cb59c7f3a5e6d6ffb72089f6cd10394000000000000000000000000000000000e657d8cd91f791a98e829024df07d0cec92cf2fa4ded59a77f7afded48d4fa18bc19e04388c7b8ac7c47bbefb1c24661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b66e8c0b0c1068e685663ac8a74fc48bfe98b53630e674516f368b4adcbd066e6b0a71fc67735f8f142a143b62b56e200000000000000000000000000000000127163e526f2c04a4eff66138512aaf06fd1c0d3b0ae6b2b5b0ee96375266257225eeeb4dd7cf13d8c55a49affd7d6510000000000000000000000000000000012c5ca350117c650073362abc9f574d53cb0b629d005d6473d1ce3e7dc2769906efb7c77f1269ffe640c714861fe7da800000000000000000000000000000000042bb4f741538d71567a2ed5658cbc575e24f4f2fae610631f76fbeaf4668583f8c757d474f69131357d9b44a9feb5201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000596f9a2717b501d0052ef7167cb14710a6ffc22ef66239d373a9f8655a42692866e7366c921a9164c876ab1cee68a4b000000000000000000000000000000000c29df6c0191a87fe13c50946dfee8cc5dd6c8168674acfebfdde4c5430fc6e17de9507bf8a878aab88f17f9bcd0c91c0000000000000000000000000000000008fdffb184d72438a4cd355fbb45d2a9d1f92c51ee18c8c4505d1503090382e0479eda005bd8709424ca0eb0afb6aada0000000000000000000000000000000018a4a6b4867bbbfed63544f4f2d7fe6e07dab1fdc8418dbd375b638d7e28f1b30882e57e97387aa6410f21d1083e89b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1d105c03ac0e964fe62a9af0d5e16767ce5bd2feebad246a4b0daa82895707e7795e961e4d7aa264854a263e24d0eb00000000000000000000000000000000154f26eff2b4a9de2308f1ae8fe28cd247e8137df08b5d2aefa2d9552d1c483fa7aae4b2db4950266ba2b3559f71125b0000000000000000000000000000000008f93ce2fbca8452abf1e97a4bc6b997bbf151ba831fe7385fcd7a1135737cf66fcc23688dbcfebcf69f0e02a8340ff80000000000000000000000000000000015eddb9e121ff3a4dd704f52a47957e1630026e832850e74a977bf53ead27affff9fbcfeaaa40fdbb469c0ce92cfc4cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161db7be7e529e00c94958acf7eeddcd5db94327114370302e630855182bc5f68c00a474423ed70ae8387a0870fdcfc40000000000000000000000000000000002122b6b8e70d47ef1b68e23194efc083f573064037069f9c4088accc24552146ee557536e362f52575e7b2193ce3a0a00000000000000000000000000000000064eb7251d50afdb5989e7aa76d35a84c2f9ad011cc44c9039fcd3bb3086943e847e1810a68f67400b664b7a00dbba9c0000000000000000000000000000000008e48c44a5c163547fa43bbc6a1761bfbdc6846ade7d8551228ff8725a56df2815f1222233939440d6f350ea7b866e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a698abf6d5e08149190a95ac357b5e00b94372ba3e41edaac00532b554d360aecae081a9cf9076073241d86a59458500000000000000000000000000000000024bf59ff07ce6e319346a136df739c603411a0f2c5676d3b100f5ec86266015856782e1e01982dfe5bb3cc623ae4b4f000000000000000000000000000000000df2a5a9022accb780490ce7c73633812c3221c59ac11f82e3aa994f701f77b82ee5812f7a252dff014608ec1c6fd5ff0000000000000000000000000000000019062145773f57a55bd622c1e77541331b744a986523936c0959ba2f90d15842acf0978924d136b929c59e17ba2f1c7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007401ea828b5fc36e7f50609b11bae9861142ac18c4ca0f7f11915391ff84b758ba028fad5c774e9fda0b22ff05040c20000000000000000000000000000000019e6920616c11d2874e224d9d14a65e06121308b59399d48f487bc8d3f3aa505b0a8afb3d039990405961f4cd8cf99ca000000000000000000000000000000000e56226158b3b388de0acd29ae0cb9708425d9047b6d0f1c8cbfdc3b26bac3cf11d30b02d3daa071c2657afa03b2bd7d000000000000000000000000000000000340e4fb653fdd0100ab142032a600f8ce62db208c739b0c021932a9376b91b4f9a3b3c11497415b696b2f22b397d55a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f4422c9c408eea5d315ce6df29de6b7df007490125648b5c1089e1d8eeb82b3b9ac058d71d36a387e472739de8e9ac00000000000000000000000000000000015b0186d8f17e9f2467695379ff10bf85601f4cdefd8d5d248597b42117ad5466a945e033a0ee0ed476df608e2416660000000000000000000000000000000003ae0a4d4f4a6ed15d7cbb7f97e13b56e9819928c264a959fe01fd9d00750c769d9ef0c52c09ffadd7ab2eaf55d9e29c0000000000000000000000000000000000d1058a812761217aa3de189881ed8347942451473eba79d1aab4e2a9db55123f5e33eb47aac6b057337925872c5cae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001444f08505a72a4b256683c9c2ab7c3bcc589626c2222d1d782511888df4c77d72fbaf267e7796d87097ca38e539d33a000000000000000000000000000000000b8cd5bd4b704586914f40d423f4173c1117e7b297a7060e610d1ebe0c5e1e4fd6f385aa726c4868b3b992b3fc7cb77d0000000000000000000000000000000011a701f2014d4dad656cef3410e54d1fbaacdc310374c84e86727fed21bd94b988357b24194555624d3fced3daa719fd00000000000000000000000000000000069d333979d29ece520448c9ead568c5446d78cc84b6fd2910823c58f2bb11f796f42fb2189ceaa20f1a16ca6e83aa781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169148efb919d35d84241377ccc023352a0b770697aa2b0f83a66ddb57c1729fea06aa72e16d372fc0d83ed75c9f1d37000000000000000000000000000000000334cdd605b44fa7367bfe5c93ac57ec5247841e7e696c96ac1377ed4b9683ff57360ea015014aea144d1514edb4f8200000000000000000000000000000000017f1363dbd8cecae0f690c1d9dda176307a1637b1f2df1521c0f0e3241b59ee1f55b99f9dabea17d29a845f0c2f1e6260000000000000000000000000000000019e4ea16ae986dc4d3a7fd2ac010e0c0918630b1351fe5e262d529382439be1a64e70241526ebaecdc87e796a9e062001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7abf3fae65765df0e2eb1d40f69a7f8d121f0df539f73b06553d72f9a4fba3f309f2400fab2dd6b59f81caff97f16b0000000000000000000000000000000019b5b7acc105206dc3d524ef370a206e12b6c6078d665d67dea8469e320e25ef269e2247be30e3375e7684189f160d290000000000000000000000000000000011f9a4962ac09651757023cd02f14db921f7b543490fa6f14986a305cb49e9742fb248f6129c2a69fa6c5a090bed27dd0000000000000000000000000000000003108ae6fce2efec5eacab28685328dd10f604afb9a8c55405b0b96c8281554ef77c581d9fd3cd37f4b8426b9551d1441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e713ad7da3a1bf9333fd9724fcc25ac118d183141bf20b11178e489e333f2cd407a6ac599ad9b3e17c3d551c9a308f0000000000000000000000000000000015f5d9aad0ce7b93eabdd99ea74c0d39faa75c9a8b69079348a024f7ba29a4565d13e5731a1912192bfd911c4928d97c000000000000000000000000000000000d1f06be6e153794147a6fd240c2186dbf29de2bdc10e843c73ccdb631806fbbf996200aa4124e6bb00f01ee54c07fda000000000000000000000000000000000fe4e889ba64e5d0b28e20c0f835c88898c8018d590cd2c9083a6eef2c44c72bd06ec000d8e12dda461e6642d03244591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199d59439fbefed56182f7c72f08a67c510e5483faa9372a27b6b709a2a143deb0aeb2934527c39883302eee4506671600000000000000000000000000000000025c38fa6880e79249f278293fbbae06f811ccbdfcedf1f4c5ac33fdbd185b8f14e17f64279c47d9c17eb02372d49b9b0000000000000000000000000000000000877683406bd00449bea64f3d7b0fbe47863693bf0dcd58645357e5a493a775f90c1bd7121adb48992d8c0b8a54711500000000000000000000000000000000016641a2f58e1b60e7a5af9c33811e2c6d7bf77332c72cd587e2bb5c2ba8ae5c3a629da7c20d8a7efeb7da3580c51d4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4ee5a9b7785bf824f2a867e45270b1c92b7515d67ca870cb09f51f3f91130ea5c1740e7edae7751aba755e21fbe22f0000000000000000000000000000000001eb233f7e8af97a5d2d956c678a343c76799e7ea0b9d4546bba675f6a1cb1f854a148f92e7816c7081983c4b9187825000000000000000000000000000000000e4e0005dda86fd5057c1ca922e742b1212bc20e561ceb02e70cd52d6ca97ffa1022e7df5781f0da2ab06a2b54ddaa9b0000000000000000000000000000000011187d5204e2487e84b854e058d56b6b2864d7e0a78e0f78db0442b61aaa5f9c5087278103c1bace2255cda048f036a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000167dfdba499597d14d17d2bf0b1c463f53d1b9549183ebf353f144932847fc55b538fa155693e7ac2afe94c2c3c025a0000000000000000000000000000000008c9b3fd35e0f8e77d837eb18cfd4082c1b5657a3f97f007c15812d85fd7656499304709a4aa2e3183806b85f52a76300000000000000000000000000000000007d6f70e1ce9ab6cbe48da75b18c5f159d9753eecd7afd3f61f709e02dd0cde863b1b5802484d1d60e646fee4d8e8365000000000000000000000000000000000ddc3359e379a407a56b530fef478fecfa764c94e70989fe2562f76fa2caba008c0d06647d87f4e4a34eeb7c52b54cd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb008d43d5df1834599820aecb3adbed20938be01b19d25f828055e231e322a3c8604f64a5ae6c3e93cfe26ad8f59cf0000000000000000000000000000000003bf33c4f3748a204d0b636a9452ef6d37448296b9b26713cd079a7b4fb88869334ad884a8f39b0668cf251ee3a2840e000000000000000000000000000000000a093cea2de68ab15b76c12e1ca701ae13db4c66b511ebd5a282c92f81e2f381f205a74af9b7b6ba0bcc009669b976dc0000000000000000000000000000000003c92b8037398c39fe9e8e6929a400b892bdf09a6616fba001105eb7ff7bfc382e6ef86413195647be774e66d1675ad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e4b145840c0ffa6ce587adfd9642789f715c167c2c894a4ef390f714d3bacebbcc371524d03787f84be4cb3e8cd32f00000000000000000000000000000000108d71dc01bf5f0d7c8575d11c295fde11703953207610c5bdf4df065a0dfe79cce16f788d72782930167217cb9c3db2000000000000000000000000000000000c8661755b04169f1716fa4c410930e5cdfb8fe2bedaa1dd1268e8e51e747712f9d9db9d57a405c599f334358940a6e500000000000000000000000000000000022e695541f6e113c5e771708cf5f9051964729ead98e2f50486cd9122fc2b388da566c983e10879a8bca3bf766e1f701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000ca7421aabdfbec158dbe9de40c0eee5c15eef0c0ba847e01c23d6b6816ac651284c3b2d1b573365dde217878f5c770000000000000000000000000000000007b8f0976bdf1663a08839e44ca947d04903c8dac7eb3e0fe223e7c310124831fa84bdb29521c057e3a909ca494c1d950000000000000000000000000000000001718cab76151071956512b1c85ed0d6babd3cc368e4c889d35b90e3f0d0d27bc90849b1ee56614dd0b0500b4b74e4c90000000000000000000000000000000002189f491c3ca8f9f167c8fed28d96acb331f8dd516686d69eb46b2f611bb2c36b6cdeabdd4ba0b743bd7a4968a95bd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f691aed2190e5abfab56b10db02d1c7d39d19e529b927ff410556ddb20f3321e3e8cb09a4dcd0f8f1de67b0dbb1c580000000000000000000000000000000011a7c1b4ca1b2f9b8ce69e90d1ddcfa16f325bcd11f4310ded935d3989771bcd397a22d7e927e0a4ad028fb4e05264a5000000000000000000000000000000001835b6cf50add5f250c03e7cdd2e17a2989022a57a9589adcc8f1a502ec70cba5ce7aa16b0d1ca4c71c9a209ed8f5330000000000000000000000000000000000b7ed12db13b99378ad61732579a00d63ccc305c8caf3766fa8de7b0f1fd08b4437c65aadb6fd4710c4db5ddf4f879fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bb8aa0b7f6e74b8b886e63574a1e8ad649e72bdd04685bbcf9ba5cd794f9cb27ffdc0e850996e4a56f03b0cb089d36000000000000000000000000000000000d791df192964ee957a0a2107f619bb350cb9187424068535b13053a8ecc6243a76dfcd89c9dffb64a8a1050670c5ff30000000000000000000000000000000004ddf84b683616043d4ed3cf45f2397c5d2716be4402fe47fae04418b0f7b6735fd3101cef4887e06c35884e1ad1e22e000000000000000000000000000000000ef37a06ea0e8059b4c87bb634e59aff4ae4c90f4f90ceb3956581519e8b339b01869763768655fddc66dec82b4dde281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091940c8fbaaab85ee618960bdf8cca22f9f0ebfdab2140c5246899271d794c01e830cf6e13b285767358bcdc54cad91000000000000000000000000000000000b070fc560a1b38d7b19c417d135635647c92593e14ff6bae7921c49e5bc6b58f158552722b55d79a2a37eb0e9cae703000000000000000000000000000000000842abc84325cd6a2e4a5cecacebf9afee586a0c5767d832f1608a70fd81a7bc875de0e3ba3652e883b64d417b1dce9c0000000000000000000000000000000016ee3c8e4f974c577e3498c916ed3fa67db4b38e4f4d7f085aa1d4b6f8ec28ea6f394e66b06206be546e90986199aa991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3744e80ca42a82a2f67f1e87a9e64dd7cb156abe1fdb8edbaa6ee352a9184677b3a432fe42eed9597200e800fb740b00000000000000000000000000000000141580dca3d93416e5d7a9c56a825c226a7d8b06149a0c9f2d7bb54c282acca9f216818b6876a8b6573c6e2fc42b238e0000000000000000000000000000000003b101cc769110e15c2e5462532437512d38cea9add3f02ae7865034f119d80a5b873d4954de57a6560dc477028e8b56000000000000000000000000000000000c50f90e4484559b89cd8d3f24458d6c4c28d26494a6b3e2a872f864719e255ae629f97a95ba39e0621f8d11820deeb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011772ce4221bbfd558fe842057d26e84339b684670c6304c8a00e178d2ee971ac0db2d6d00ab0e57b03f5afd01fdfe4800000000000000000000000000000000052e3e9b96ec1dad52c8cdeb06cf676c8a386943397ecbb5b9bf0cbf14bddd6f6643e61badcb34fe2d9190526e7e63ba0000000000000000000000000000000017c1a98aa4fd85ab9f2880766d7967330378602af4e99bfe7f0a472c8e5b64f1d1e10324816a63c21f54c7547500aab7000000000000000000000000000000001411eb75df52a00d653dc3ba4cea6879aa468a52d3d84f30244db61f36c7b8f285fb4acdfa62e19db7fa80db4b74078d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f86d6a5df59f0b81e0c067f49e0c4b933aa3704e73ee6a047f53d71cabb5f8059a1d391c8af47cebca3e7a671943fa000000000000000000000000000000000f6144cd8b8a0f761528b1805486a3f8b1796dc44040933c71da3bea8e7c49c08d5f8380548a72ae39538b72ad5f409a0000000000000000000000000000000000a775637b985d7453093b89bcd9791745cd353c026d55d6be9d752e37fd4166224687049920b4e95040602f428cea23000000000000000000000000000000000b35cf8c4cbf2ace949b4f6b8273b3d8957c7381dd7cbe7505ef6e5d4e12646390cb4e628758bc0e137387d00c749d1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003aeb3ad5c88daed98557e6b827c2ead81cd643d51247b776b6e7bbfe2d745089f0d2d97134e04050b21cd205b2336b5000000000000000000000000000000000dc8f567c0a0a4ef1a7b66ad3cb18216499e24deabd420d96a1d445f79ffd37f0d412fa194743eaef4abee0c2705bd230000000000000000000000000000000011a84591a654739b6ac11e63c66bfe768feaa2a48d251ea11ce229d4d18b56d651483e5c6816de68ba08e08e8aa7a91c00000000000000000000000000000000038b16716e8e21ebb570fddf7b42c140d23c6e9f2f4028d414f72af0b49c64d8f913f05969d6f9a37abad2f3e4eee5b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084e88f229205eb8c9f3e2020aaa37d8eb19c9fca80867395d72a78b9b5695c0a8fa07d956e118df2662bd06d686acb300000000000000000000000000000000091481e29e3df01219e2cc9e145f59b42ed517b31586a98f52e3599d25d99e648d876bc12b9322d82f40be0f4817796f000000000000000000000000000000000a24efca5e420e68dcde12c1f99925cc3cae831da86ea6b9894921c02cd8c1bebf657b4953102d07ed15c1aecb823b600000000000000000000000000000000002772f947b555b98ac1313eca35f4104436504156a4165c7a651d67a9528752da72ab34fe0140109d4f3e2cf3e9344531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092156d28b4b7f9e76ea486f725ada3d7cd234a2b29e28900dcabe2540d4159215201b504b6e0c84658373b940a01752000000000000000000000000000000000953fc5f4344ea035a1de62de1aafda2971d35a173e857d2a879df5735a9380d184f381b2f4a7f4f1d0290829d0ded6c000000000000000000000000000000000cbad1e52595c079294b168ad5fb5843361f74803f45281eb269253cc1995a72c450c11616cfd7ae1f1f3eee8f2999dd00000000000000000000000000000000034ab533f905c25b9564b9f8518d28acc0f3dc6f4ae13710841fbaede1995703472becbf993203b190798b044b5a35d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb2dd566af07f70409f5ed9342ab72699d80934324a202c8047ce2767ef9d73760322b503598aad157d2c749804576e0000000000000000000000000000000005e46bde0389840731f2dd19c56f5589a0e7bddade4316918ab9dbf47c9c7d56df36387194c65687a8c73bcfdaef740a0000000000000000000000000000000002e93b8e95cd264252407cc8d7a9f9a432b2850a6f5e261a86a3e6e1180d4147367a9b561d55b5bfdb6e3f2951f60b060000000000000000000000000000000012c0bed900b2160ce809e31bc4ad41f3c3c012adff07b6403d91237d3b3b4a126a2c21d56db02e44a3411409ccee4f321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031fdf2d52db432b390f7001de96b5028767ce7098032fd4980ca480461168379cbcefbf482cde54ec7a134bdfe3669c0000000000000000000000000000000012184ea06b1911757ef4c6c8fe756374016db70f70da2a39cbc02edc4a6ada034f177611671f13085c15e716261ed87900000000000000000000000000000000049407d3f03a2fd531e4df27f628f7a75cbee7d731a72fc3fb2af1466ae070e0794eb15cba79c6d62ce82b5b3998449c000000000000000000000000000000000a534bd3d848d5675306b97016409872bd65729e4f2091c1ed5561183b7ced144f55e61e341d81d8fc9555f1dc784e9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163c2bab8239f6ecad1e78801164c587a787fa2c9553d8572adadd9bceff86c5b2b5a52cc90c1c7a8a7aa99ad83a57110000000000000000000000000000000010fca397f41a8252de1c737358627c74a85c3a3090032fa7c7d4d3a045031bd1f4af58c8260bd9d64da9fcc86dfd5fff000000000000000000000000000000000a28170ee4277ae166ccb2fb0cd935b9b746025e19eb7ee640c454ae8694122bb22baf8645e302b8d6b20e5810f99fce0000000000000000000000000000000012e6891d623465229cdbe20bc680cd26193b020cde1e52b1f4467ce31e91ca9268906179290af97940106a78205f41b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5b9c2f304773af73719ed3f9605c7e2a0d4607985c090b4fed44147f22ea3d0e41b19bf42b50796f6b4c05512262d8000000000000000000000000000000000438b1726f06d701907646636cd311c9ed161270ac03be594c2165ccaccbde1cb2c586733e04fba7b27dfa45a7e06399000000000000000000000000000000000d3d74b40628fc547623a2eb4b9585eaaf3d4ab01dfaf5a894f06f9be9e6cda988fe9960a749d6d7446d2ea95a2602ef00000000000000000000000000000000171cab72de82faa190a8f3244549ac5a7540e3b510c8b3ef3b899b9e2191f01aa33b0d8af5e6b84b85f373c4d614e1e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dec8c78dbf2432224a94f7f75871da720084d90473baa95aac2f848bd67110103d21705400b685b551c60d58530a0b000000000000000000000000000000000e9761b36aac6781c3b903668c4cd13bded5af2cae8d951dbb4175b7de4b35409ee20e38bc136aff0feeeffd629873350000000000000000000000000000000011ee5ffc4cc7906fdef9efb2c8fb5695149c36dd0d8c2daa44c42fbade09db3044d4b1cfd62c4144c11a3e4a16072a95000000000000000000000000000000000c4eb5e6a09e4fb485ea04804fa1d62cf503aded33a0e54aab13f79b0a5b8151f25bd03bebf9046267fb3e809e2d9de71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f8b80688f04ac8b498a19a9ff1d3087887d7238b9f82edcf578f408888a7eb1f83c587048174f38069ed105e434d3d000000000000000000000000000000000f86c4654eb6c9e9156b9e573f6b4eeee5d2a24d929a439ad7aaadb72f6de7bdc6b339d03b5a5eb26e1384c318646d3a000000000000000000000000000000000fffb308caff3afb10d956ea31e4680a82ebc147e3ebbbdeb7ad4f6f502fa5ddf03fb47018b966b37bac6754892ea429000000000000000000000000000000000073b1f7330c6414059897e9a316afcb77d6bdff4e5c4c460e09f2a3d4bbea09c81ab4902429afc148c96996e13c51d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c9b65bdb6b282e84d040df38f0df859ea29963f0cafea770e96f48d57203a4f8f626d58e49fa8560a2cfaf0d139a850000000000000000000000000000000018177d3882f4dcb9364db6815a9029f22db7ae4494994ca047d4614c3c9bb217cae7942fae17478ab393b4a909ea4220000000000000000000000000000000000b5048748f40aa1c7b025b9315acba77d8177fe9a358db033d0d38ea27f3255f3a0f560262097246a361cab4626c00400000000000000000000000000000000002f0ca0b2536b02cf0aa1dc53285eb690fb5e1b29d166b7dfb6ff9dbdba460207a051d77a9df602c6afeb5389d436b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000940ec5a6666dc5f885aa3bf8eb285e7c2c8695acfeaf52c5a163d84b665be9e4fdcd4200859c8830c5bbd750ba9ed20000000000000000000000000000000008feec47df6be1f826a2a498c08af3b6abe88dd5de90c9971d62b618cd6df3d0f3aed80ed70f097c697cb9981d70a1f0000000000000000000000000000000000b83bb05ce07dd177a2e8781b964d24d45321a42dce5e388806610a9c2742cc57f4656ae91871d32b56143dd224ec2b8000000000000000000000000000000000da578dd312e865aa4ec90912332246da48d0a3a9c01b07726cb10459af6c7519389ac317e33cd672e2e73866e0207ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010da73562a40b166d7bc485e50e9485c145298120f7156b77fe42d4d118081c86af972c732775148066c55b4167c4d9b000000000000000000000000000000001331cbe4556103f9ebbde20afd9ede0fb4bfd8a13198d7459b3671cd32b68a9e848f899e3f084358868e79ecb166d54e000000000000000000000000000000000eb100445185dbcc81e5a23836b3210c2fa94dd433d9e018c9540942c2a8662dffd75a10dc182fbce54e5410449c642e000000000000000000000000000000000ec9712a33ecb529b6a16d1507c960f808b3b0df141862282056315c2485ef659c4a97c5ed8af3469bb023e9ac6015841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150de26ea0f5511e4715b0afee411061e64e547efe1aa9b4401db91d0869441cba1f8742878f8c3820574d2cfc22da51000000000000000000000000000000000971b6df1a2f025fd89343f3e678220ddfc8231884c7cc8b5df2a906c412a4a09fdbc97c66d2a1ef24ef0f1511067b5a0000000000000000000000000000000017ef55e0f0789f08f2eaaa2e71617e77df7754ae4a21a83d41ffb07109a4ab44d35d919a53038ee843b5813c91803976000000000000000000000000000000000ea85a8c74c55a5bfca9629752f1bf4772b48f3bff8e8efec5515b5d8e922e9b8639654a2af4352bac599c888a59b7b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b9f81fc55e94af896b5ab0ce8cca90a651fabd55a21721799513e2c34fc9ac491a5d847c1bf12a5f0a2930057ed1860000000000000000000000000000000013abefaf0c2929c6c27168231787035f9ce76bdddf80630926f4e755e80374043a7a7ad5ff44c38861996c026085392700000000000000000000000000000000000f72ef4938bd4701f8d387683eb0623e48b62879378fbfd6aad8e5746cdbb8a3338a5e1bca4f6e3727a9394062f25c000000000000000000000000000000001603d0e04770fa76924a3e7d160870fd541822d9f331697a25a27df4d5fb6220c6d2a459cc205de2d078c055628fdbe61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bd8867348015794ea44cb8953ca0f03e6e1366be7658a045dd00726e77f66ecbe9be004cbc31553c456f07d9cd80010000000000000000000000000000000005cf9ac85c32d9c7de5c9608f00e37784c1de818958ea2cb490c9faff1773691b25558e6679a06db02b2b04cba0030fa0000000000000000000000000000000017e3debad1a3a0d3213e2cae83772311301930ff279d8f6273a6a2072a82acf2e8543e0c1978b9e9d4915ec0b1d81882000000000000000000000000000000000761937005c8dd98780f769fa5d07612db581d1db7b7257b1abfcadc72a1f7a1577cfa6527835a3f68c5205aebf7027c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015da361bb523ece518e0df4c3b81c6d250e1aad8fc5517cd044925a4a656068e55015fff6588595202833a9938a5f5b5000000000000000000000000000000000e7c0cc6e112dd78b5ab418471eb472185ad9df04222b04fde09454222a3ee909d32551c886630fee1b1c96a33c06e26000000000000000000000000000000000945bd09e309cb8f11de66cea612eea8e924388f06050153f9d57b1d4942780fb2e610e0b3729b1199d55a3f9cb5ebb00000000000000000000000000000000018ae9bf5c59dbf687b347765a94789a4764b75ba4c8837e553aa77f7ea943ffe2d46566b29024fd07015abcca4facad41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7fa3c0cc4af753705d0ab71728e068370fe017449dbcf72bce54e00a2b8ed7fbb9876736a86f522a6dde40bbb626df00000000000000000000000000000000116a9fbdda1d9795e276f2b3fd7fdc302acdfaa1f25b6e53807bb8fb434469b140413f571b90b410102d09339fb6170000000000000000000000000000000000126de033c999e7da01310dc102af4ffa664b254be3038620b1dc6454527297a5d1067c97350b757d2651d48cd659aef100000000000000000000000000000000057460ec73aa03f4b3a7d23764510f8efbe156c88123166c2b2af08acc600343d344d3cdf692fa5c8f90dd380fad993c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eca02bb0b4009ce30c523a2f929c9d13a8b6bf2b0dc38a75944af5a646b99d131230f4e9475282b0c5dc8485dfeed10000000000000000000000000000000008cc789fd7f28111623ef1350d0e3d7c578bd1fb226d163ad79a623baec0136e82969c8ac0c1cb9dd3436e85b65d650b0000000000000000000000000000000019306443ff9b484afc5f0eb02a848daccbbfac3564a27c1eeb226897d12d49a1ffbd1c275fb15e57658b2e2fa1f5eb50000000000000000000000000000000000e9052d5cc62bbe264fb7a628d5aa761530bfc69b02955840233bd0ffa1550ebd22e81e06ffd97c2043fca37c38800ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018697d54dd19ff8efc61052448373ad96e1c3016c8e69c516d8ea0340c963d39c16f3d1ebc9b9b7c308e3a2cd28797a90000000000000000000000000000000009e37a8aa4c69ca7d3de7137eb67878b8a6a0c82a61025b45ea2993ecd8bf5c37c8c700d353a91eac4116f3ce7560703000000000000000000000000000000000946c6c8e0b5cb80a65254f0e653dc711fd0baa18e1a1fe7682a43f97fb8b6d80a52fccbb5c15e52bd46b3cade5e2d74000000000000000000000000000000000d054b0ec40acf9e605c1822415e1e5f6c10c8428312d951c266ed2c2804e0e4da985c45dc36fd542b1c3a15a60d947f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c2a641fa9b78e5bc887705f2e2cb02f37245f4fe95846cecde02d8d6511a78213b7232bcebab1454d1dc8333076a99000000000000000000000000000000000e6c897ea2ca9047224c0951ae48aac6f30168358ead33ff7efdca9181b794d36e499ff039c553a8796aeea087213c240000000000000000000000000000000012fa557346caf660f97d9e7719a1daa5061e28b3b86ca0e35accd7dba7ca1f2b1746936fe4c51158deb1f1193b0d7d6a0000000000000000000000000000000017a5ec25b331b697d82b43ca750f363fa7d9c8149856a730f4d4055c96e880b65106bcbf9e2a0eea4ba291752f2b17e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126d72e1958aa856cdb47f3264f8c252b212909b007199a1434dd4fc6614ac9ef676691e483e5500a97a315c5db754bc000000000000000000000000000000000f45331f74ce5a1f998dd825e7ec767d18deeb5ee0f0e5858625e1201252d6ba437989497ac832f8f91ec9f139bd3acb00000000000000000000000000000000051679243271e84152af1ef98952ab27763623c419eb66e39f7caf97042018b69b201954e81a5332a8b822fd39c11cdb00000000000000000000000000000000166bb7976f8305ac908b6ff37a1b6049de9657f573d12664f2fa3b50f2dc85f12b7e57c6f80cef1127ad59a155e1ba631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196e0bda2ce1bb046a3affbc5e6ad8d40e42117e1e0bb75c2c386fc4b3413d69cee50e2804f1f225daa6e527f20eecea000000000000000000000000000000000beafcdb3c675e06b9df910791bced1a866a11fca019c8e9339e6380289c249449dbc3bbb1670e2c4e27aee1629050f2000000000000000000000000000000000bb412259ff260c7fe0e79eda3fc64d1ed8c5dc94f47b6cb391ec8e138d82bd0c4f3fef8e3134d3f417bbaa6173404420000000000000000000000000000000018c8f8b4e94c1bfa527f7b3155c518a5a8534706b485def7cda06ef930c359ca6074ddea0f60fd7c83903a187ff36cac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010b3aa26397b4d778824f763d1e2894963e4d71190fee9a07054698d94d78450eed5a26d1719acad128fe4d72be3ba7000000000000000000000000000000000a50c2f13d358f620d31231cfe1cd685ee1d2f0876e85fc564eb8fd5543fbe79d883f169eb64303cd27cacff816d441c000000000000000000000000000000000ccd06265501e021a5a5633390ffa7b6c74e5483447effbe86f2bec06ecbcf3f01e8adf70328ff11e5e778551023e4b900000000000000000000000000000000176d55d2d3c689128c467e24a48828c1c457a482bbf1030d1f415f57088680a292a9509f008db74c333aa9d7fd811c7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5bf446fca039a6c06654ade4cd9a47540188626a8cb19995ace029fb5fed385d3a19eb58415dd5e6573008129c1e570000000000000000000000000000000004ad16ad06bf0b83ede4d6c6c93c406bc8f041aea31a931bec4c15524e9ef5b03216565090618f14f73fa63556582d62000000000000000000000000000000000d0e796ee8165ffee653a593d28303572f975f11ea96c314f7513b79c9f0d0dc2383f54ff92070b5642fcbe61c618c210000000000000000000000000000000003b627fe739426d01ee672d2af287f6e227c9bc312f166069d7097b3ea59c12be548c247c9c2a7141c681e7e4db254861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a97e79631fcd3a2eda627492c3629974979fa35c92108cd20d8ca194299e94d536621e05a4cafca52843e11fa7f7c55000000000000000000000000000000000b67e4a00422cd2f386372e1093eaf1e0c6ab61fcb866bc74e36ed47cd11135b7b0fda1669323948f010a4864e7a2804000000000000000000000000000000000cc8b392227f93591a7d5d4e20dc58b123986d235f25330f4c15ac72f38285c51cb3c05e8cbe18c000f5a30afd670a1400000000000000000000000000000000125e7b769bd524e06d8d4bc169d42ab5907acbc3964f82ad5fc46653d8843b3b9b6c78f98fc0ee2faf309f1db66a6a201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d26ac13ced53564543bd779c12ed59fd67c4ff04680e8c33ca350b26c55110f7e892d3ba5ac3b94a2ac69aab1a22070000000000000000000000000000000003ce5391468d3cd15a0112f2a85e3e695259fd621adedabcb31e886b276a8c1ea270f694c7fb743c5b897c3e3935b2f30000000000000000000000000000000008e2e8e27088aba2d302adb40e1dbf743491892b2a7d35d3e3fcacffe0a28f53426a071c67d9dea14619e25be07c4397000000000000000000000000000000000dcdeedc0f2dd3e7c751685cb36cf8bb0180b3680ecac5574c01f7f391f29c65f92061a9156e2fd436d00df6be2c12171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000373a92f7c50d6a1759eb0ad307a659d7b63a6fd62a7565c438c298e7aac19939a84d500402a0116b184f52e28102ef00000000000000000000000000000000019b69882700f174ef06bef64ca3c9a350e453af1055fc75c97f4d65872c2d74966cacaefdb83093c204112a03f270cb800000000000000000000000000000000104069b74e662c9cbc4fd31dd730904db523826816d6a90c872e3f4e85284a0fa0fb217d9f9557d9ed032a32d94b262d000000000000000000000000000000000974a4dcf5bef80dec5bbac6ea326d7fe1611c83f07247935b98033d901dcb54359cc8a54ee4c2b75728234d1e285a651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e9ec8cd073e00cb57852f86bec0fd237ce3800d1089677e7c222b15492e7657436157943b833ecaadfb4e2ac0b325c000000000000000000000000000000000ebe09b93ffa3883dd9b1dc1a2252d46bbfc760e2210dcc9305809ec4d3a631c4673fe73a0100b0df94c0153ed723d2d000000000000000000000000000000000cb36d51b2b3542d0e0abb586e3f648bff887bf3f167ae90663bc7b888c03739b87b12606cef5904b224f68dec6aedf300000000000000000000000000000000110514f7a63ec805e4b937683b367b5afc15581a221051892090eb0ecd33b58bd25540cf057fd5e54d939cdd9d51f53c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113f5ce01b869b9a2d6c4116d7d9e6802ae56e4cabd7e0541f7d7cb02bbd23e138ede176dd23b7652cafb323321a3d46000000000000000000000000000000001711be3d5d9ee00eb15d8de547ae85984f99fe28db895808c7df12f162f6dd2d49ef4287d7a95e328ba1931aa899635d00000000000000000000000000000000116555db0c03b92375f109c8632f4f32de6d75c485e116bdb7a9c6cb88bd743aa44bc570f8cea8a33457d1d467f8c5900000000000000000000000000000000013e83e6af5363b65d1a9c82693dfe3f12b071add3effd51767313bac84dfeef005227291418912bdf543e605421feb631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c4ec1f9ff2d1e0e3b66f54e026c3ad9850d97bbe9493bdfc66df26433344ee13ab99a6895e584f0805097b085a440e0000000000000000000000000000000005183f6c272feaef68d07a40084da61bb030ccc4fd1561777072e6805f81e7b426845a45b2b0d2ffea223f692dde6db800000000000000000000000000000000006347cb4d58be7b18f6415acec86bd873125c00fb1f3c9ad721a957a949cac96648fad4e3cc2431f436688faf4445e700000000000000000000000000000000097f1ea1e3c1f353ef757681d37cb0582adb5510359424242a4378ded03c753932564f9b8b094af629bd723dccf5ac031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c769bda6ab1dde0088ba6a98213caced1434fe403f0f15659f57badc90c22ee12924e0cbff3b81bc83d721bf258a84f000000000000000000000000000000000add028dfdb6748a61a9b210b257c8971c2426d894cfde0bdccf2493ae7109139ccbdb22f4490b710b4fa526b82d83e0000000000000000000000000000000000dd69b5cd7dceace2b44b18b1801f1af2f728ccd6a04c34863ac770496bd3c769b94d1a97ba31120c2704c2fb765917200000000000000000000000000000000070cd27fd2bab7357664fef90d8abc1834b373fdbac7ba88d2d23908cddfdc05fc971ffe81eb0de3c7931d2c1f0032f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd4131619dcd8977b9b7119124bd98735f9ed0a10161ae8990e2ef910da3643408505fdab947d396e63c8ff4791a9380000000000000000000000000000000004441ffc91cab39cb77baedac7656d8954a0887c441280d519363fad626d5ac039218af83d9152ba0335192c3b3c402e0000000000000000000000000000000019cb61cdcb0d4721d2642c27790cb1bff61d606651bf03461578b6101ecf1ccf9f816fd08d22cb780333270397a82990000000000000000000000000000000000e3944c093ffe8b3a063e9625ae99aac83e1bcdd500188525496f2ce0d572bcf138d9d4e53fbffa17cc869580d446f0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f184b25423d67d60240e51f36f30d44a6edafa6e2aadd0d64c7e408a69efdce29b438401c71a318d23b8f475e287d3b000000000000000000000000000000000c54588a5ac8156cf0a602afea61af59ff4d1129566626c30515e4aeb27ec62ec94c91b14df463d0fb2bd2c7974ab51500000000000000000000000000000000026b8192202435d1df1f7a08f21ee7da8c4364dbba08c6d2411960bc4c3d5c4d934f4f695ed49eaaed0de8bdd39c7df4000000000000000000000000000000001745af385c9faa4d56ed2eea7819b168a902e57079d3e75af09625f24deb03a6898e674b63dca1439c68a5bfa090278e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000327e054f3a9b7a34de5b79c3f4474a123888e963d5293be93acc433a915a45318cc7b0b06196feacffb7c329d0a6bfc000000000000000000000000000000000f425b2c22ed73646036b45b90fab7852e7dbed9b2934c0ee762f92b0fa26b24e2ee3cc78c10b472c71ca2ce45fb397e0000000000000000000000000000000006379217cd6376b7da437913bd788585c99e4d8e9b3e2de36647d46ce9a8e19291c8fe016bdb4a86fa53837a82de83f5000000000000000000000000000000000daefe609ca2f03290bf86471a120a952bb6a76e3a19c50a334fb754fa470c3f269179a66d8025f24ceabafe5b8205ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d54937a1465c1a1f6cdcc3c3424e074cb25b5b8d6ce979382cd5361cc5965c6c8375cb0f59ccccff7d4888d6a6a4f530000000000000000000000000000000017e6152e041d405eab7e7722cebdae7121f8ddb3f0336f67c8cbb37823d377d3d90a3c40615d4707afebbdff78f8f3a70000000000000000000000000000000008fea85099a644721792c55ac1ed6f91967e0b6b8e671930fe4e76fa4a99c5a935fba364650d805797892bd24ea50b6f000000000000000000000000000000000b67a95dd629b70a6b50c845fc72d1efc078fd973bcd0c9a90e1dc5fad6c1aed4c696c8c2dd900ee45377416aad7e15b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa3c17e8f1bf28d173b0401415093b216e3c0f915f102e1f6459e93837d1beb9510003564b6d6e94e8f1dd9275b51ad000000000000000000000000000000001106ce5694629e4e5cadde964513b211b5545099adee788a6bec3c9f647e0c08daa3c403e4f2c75da49e224438c6017600000000000000000000000000000000021a705f75ee9a4e77205e58219459562c555d62ebb6a28a51cc4b1ea8dd933e551f514d4e477c89ab3a7b7e33622ee60000000000000000000000000000000005eeb353ba43b1dd2b7d088f29e50138591b86346c18939b721f171a7f9a41c4957750f352ac7e0bf3f35668bec6c6fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192929f7ed8a0e7845fdc1b8c4a3c6eb8d1cc70a3134ceba27966be7c25c03b9c413963cfdf356afbb0d0284555c700100000000000000000000000000000000076ca0b158f3ae3923bc3360b7707c5575dd3e9a280301545d3a03b2037812bf58d40a5004b4aeaf27d2c9359cf45e45000000000000000000000000000000000bc6a5881954ece3fb95987c6f7ff60fa3e8fad078c2b7a808ede61aa9844f7fdd161d974edcf7c38d0a6d704d88dc9b0000000000000000000000000000000006ab9f6b230097467edb714632a0e48d331c1e6afaa503e18cc1919683f5885436ef97fc7ee84ab71bd44d114311858e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000165d84fe712cb94c9ba14eb23f925e229fafd759d25e7aad2f52ed54d3077981d9144d9641aeaa9a44e1ea8db0ff9f4000000000000000000000000000000000255c9772ab035d5d3ee8942d9b67b0e5c0e5a910775904ca18802ec11e8b1e7042db099240de5432b98a3a1a65f6629000000000000000000000000000000000ea9fe87af77a793811332d2745a4cfc21a089e9175286336717b303330710c27c5296e707a3623572025650e26aabbe0000000000000000000000000000000005b5cf552b9305f669189e66857a62d110b948f82c12e671893ce52d465e21594720c85c5feb215d3d1730d6aa54db421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9f0db7fd8fc530cd276b1e088e103661cd92590eb1941d1cc529af9ea092721ce3d77e9c23919d64df36c657e0cd9f000000000000000000000000000000000bd0fa7923ef37e2b8ab757f4fc02b0f03ad3bd911ebe2c783d26add27664d997b97526323bae10a509d2a0bc6535fa400000000000000000000000000000000198fb717c39b731638009a32fd38add77143805e837ffcf610b535b0583de03884e09e766c162faf2ddfc800b9c791b900000000000000000000000000000000114b4c2187370bd02168ad24b6af24c81254c7dbf27b177f9664f38cbf0c6cf40d675c186c2d34838e0410d47cc674d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021425276188fa1b56ee332b8653e29ae12ede33627fad4b11c0b7baec66c4ccc766b7d870adbe700b1b9d6ab06bfd130000000000000000000000000000000012c2d581b49c4eecee4e2bc3a89d89fc044c8270b4103e3da503721c971be4c63604fbcf2c4e4f67385b59d2a058c0cb000000000000000000000000000000000ee5044e6e406c64212d4c85aecd60db6dfaa5d9d87e6a4369441c08161cb9d130a56c1eb4fccb7b0165f2d6921613a60000000000000000000000000000000014d2aa6bc7ac017f5648a9c6d84ebbe60d4903ff78beb0d5cf38cfb86b8c7a20d39c56c3194e95e5f94b745cfed169cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a3890c341086df2f87f53061c1a175f6f712ece1a1d4f3e9e768842309ea10a3c71e2b68ef6c27ee02cfda6f7f33340000000000000000000000000000000019743449fc44aaced93e1ba066f77af00a1f3f764e1f501826f6f8dc6917214b9ab8a68629adbef3ea5f4afd3ce1edfe00000000000000000000000000000000136269fb7c6cebf84dd01d4f6cb0cf56e005b8d8b900c63020d0a2f357968cfa32d9b823b5f5de6e59eeb2f486ea4c400000000000000000000000000000000016d53562e5f0a7dae599c41df3daab457bf3dbb67350022ead1be23daf09283a49472c950026809560c09686433c31541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001976747f197c2e15b83adc7abade6d7187e911a8674a692bf3588e72e0a446c043f0050d57ca6e24a0f7a19e2c4b1d7f000000000000000000000000000000001919667dfb7babb095e40a42f09ce73d0c8d246eda076196aefcff76268f90bf3fd5b5e362c8375716acfdd1b82dab930000000000000000000000000000000001aff2e3f1acebca71afa78544ad0ec3a63aebe44672db04c857afa15f3e9a2c3b0742e2d406c3d34162d86eab0a7b86000000000000000000000000000000000c50d66141e319dbd611b1663a34f883f778b165f4da579ad9f9cf631cb370870fe8a9edc60a2d3af26eccaa7d10d77d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e15f6c0e14710eaa9d44a21350f25658f7e2f2e12264c6d7c4d079122884ea49eea89b9add556424638ddb2a1bdd0560000000000000000000000000000000010003ebe432571abdb309876926cf6146db05829387ec491149e25fda2c71a45e518477a5e448b4fc720789e0df64cce0000000000000000000000000000000007ce4015d8edfd07cd0b452d64d62a919f7ddac90fae662d64b0224e80bf4025c266a4223d4f98e547af19c36b458410000000000000000000000000000000000d03dbc43f133030a837f198e650f18eb8c20c356f8af680b38225c88bdf8f98a25da98d1ccac1f1d11ffaf131ce8dae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079d76a0933c00df908576f73c529e9061b4afb00ef6a60ebdf23c72824f610122240bbdc2d0de1bdcf38d6197d7ad7100000000000000000000000000000000000616c836b2a78f41c772c05499d29a549d395bd40e2d24f058c8bf9bce2f10e9643b1196f0735da1eb5989ff1884fb0000000000000000000000000000000009216db1fc57889c35bbd921d27ab606ac667d1e5d0cfdf625f5ec59fa0059111d294435f46694b7656c6b1f732de5e400000000000000000000000000000000184d5a9bffaec172d01e9b3dbbf1c8aa523193b2aa18994e35b54d59a3e9c9847d64d1c03a95d4437d6a21b980a4ba491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a7f9828141de108ba3adb7150a8cf3245dd75e503faba4d09fa9cd4df374478061eee436a13e64a8e9977ada53e28d0000000000000000000000000000000004efbaa96b16996db9838ebeffe831a6797b81712824530df24f79ea25b505fbcabe45994c3395481f822ada6d71c0f600000000000000000000000000000000189e7687248a102d4b6d81856a27f0a3badfd2304bcacb38d8001a7fcbbe90b5d8b19250ab307c4880af87de9c49167d000000000000000000000000000000000b679d584021f7d4ed51837b2d5107fff02a7bd852bd3ea69325728804ca362c332016b6d641175bbedfbe345c138f111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001e1dca7a05a4a76ecce5d48c66eea15232be0bea17c111fee1972e5a466b7003f3930669898de107687a5da6637923000000000000000000000000000000000aeaa77666b0b07dacb2d020378406d42274e2b2679c5fb8277633165b001cecd79f16dbb642f322982dc0a82706ba870000000000000000000000000000000002d8ea6580e039e9299327ad3525847da3bc95571d0038fdc41cf39cd9b4834357704e51f66ade07527d0ed8d2406b70000000000000000000000000000000000745c6d9dcb5c6709f3c678956b1e837308973bf6ab658a9e22ef82e0191cfdab536542035a41e6ce027be69975322b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae4575214289f7e25d872aa1bdc8ec68a2e3a891226eafefaaca65ff66823417cb9fb1d940b2683ac2ce1e92569528d000000000000000000000000000000001079f904cafdf79694880ff13eda57d6b1bc35a3b420a7f65fc377fc6adf6b61b44e919bd70cb7dd59cde9720779406b0000000000000000000000000000000012508f92554ad575f493728a6b71813a43ea2ae3ee0a1888afd9eeec7553d8cef7bebcd880a178724e2584aa0c9180c50000000000000000000000000000000018f4b6f2564aed7a9a8842a039fb3d3ea51c9a158be8bce308221e27841d8793a18e00d8dfe0630f4cfc9ff5cef763951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000011ad3252b8f513e1685847fbf70d6cd24812934c2bf36778676631735ad2663c0df2cae0a11716b4230846040add780000000000000000000000000000000018fa816185a8b2f46279805adaf67670ea286404b7eebcf1f67cc2f3dfb2a5f746ff4a24fe343d311d6c383e55b44630000000000000000000000000000000000d4acc195a7ec99b707300d7c1a2615692660e0ea2fc619544e4ee022d8fbffcfea13400fe79f91271121c50347de42a000000000000000000000000000000001115fc5429cb3cbf6adc2c0405a865a9d3ea43b9a2de331c22cabb90a68bd6a0d07026eff4b76f9165f945dcc31f894f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149d919957d288550f8485a7388bdda9fea3bf2d184babd40f37091f6a7c75e2fb8f976bc5c18c9b674aa8fbb035cddb00000000000000000000000000000000008c1a688011da56db1a1f4b88a70ec4a6f1f8e6926a4af7a83a8c0a852c89778bd8a2e6ee87d1f8187597a2e0b5811c000000000000000000000000000000000ffb978b9d2936b159688dfbcbb49f04033e0e4682646d3f4d9aee28b93fada76c7a9c5a68eed4d06c03fd4758e42c970000000000000000000000000000000006f409ba8ebe146ab8472157abfb8888dee0386922120ba93593fe316cc28fc4d88aea859baa20f39d499bdf44e676cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff23917b604fc34c1c704d708c6e86a15f702e2e867cd6092e8ea5f55282664687ba844c1f626860da9294a2b9ec4e300000000000000000000000000000000021eaa431f7de8ffe98f2c844d96f9e32b56da4f7bcd49778a222517b42fc64cbf231b02db851e74cfefd48cf8e98cc900000000000000000000000000000000120d7bb19660e13b544e0306a3977bb97287803a10599ee735e186f1eba2ba234c51e47bce279b0be30b23fca14ea870000000000000000000000000000000001961cd1f54b036de3b1c82adc0191174e232914cbb9841a872bd28515a409783366c64876e5ebe3237d39eae049fdd7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004172e98cd16572aa4f2456992a3673c6a9cc9205bee4b841f9db84f77eab11b6c4e0b0df92d95fc7e6fdaa88042d6e6000000000000000000000000000000001580fe0cb278d27f18c198d419ca66b3366e893e1ad3f473ee75be521c85bc6e657c2c3164c1cc79add257aa798b3911000000000000000000000000000000000e9c31620c99a6dfcf65f8cce427cb2aad8c500d7ebee93197bfed0b5b487b23d3af36766ddcfd010c49f80ce882fd480000000000000000000000000000000015428c05d02145a347a189ee7e0220b87ef2f00b93886745d41e58a1df055d927acd1d08f10b1985d1304135b862cbfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012902581e021c0e7b0146a289b35a379594b5506e769c4285a1b1daabdbf52722c5c7532a28e37e2b1e290feb58a866d0000000000000000000000000000000014d281316e2f4cd09423cd54dd62394bce7c91e313f1f0d91c6414de1aad79547532e8ff34d3d964a47f5f1dbbaa573c0000000000000000000000000000000015865130170cc3528a349836f6a4160ee4f868c1253638d4cba61734338a5daab4cf7178531a61b890ff60344c592eb500000000000000000000000000000000128ec1401cac058f19dd22d0436db7fbaa6bbdfb4b986da671ae82aff51c65a5dc2ab9789bf6334838413df4414439e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4dda0cd3c81cb10f50fdbf35c84ad2bfb5be5d45e27204b4e2f9d727a1b14080d0958430aaeb69f6c0bf9088bc820c00000000000000000000000000000000111c35a76597ba93de6708c49e2cf0b98602d3ae13c81d1fac0c5a8b1f4e9350d710585f68ce1d30f15bdd2126b20b8f000000000000000000000000000000000b4f05eba6908ed036156f69fb0efb5556ba90a9944e52781a8a4a01911bed0ef641d2e41443f33223c066be00b168c100000000000000000000000000000000006c6c97c53f8613abeb4136c5f3f38580e4c45494ae311ff6f1279e3c8881ce4e4bd3a735533b596c56fb7ce1ad1b3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbf050bee1f9a6762990de0296f3e779e82092e2341f30886e316520facce215b8cab9f0ea1eb5bfb99ba9f37b16d2d000000000000000000000000000000001725ddd8f5076e99fa06001e3a84ebe4522ffc36aa925a1af31c3f6933161ddf2cd43f63b185b5eb30fa0000f914502100000000000000000000000000000000176b8c74d77b443af759ab5a1e949c01de483c564fc8bdc36184d6796900c2c5d039744f17de8569df941f065165f0e8000000000000000000000000000000000dd6d733dda7cab83e27611941a7234ff8b68bd97f61b9437eec8a63fcaa4e48f3b484f4f60bac232e794bc9c8a6742d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a123f96417b3678a8a8c84952f6e98faa6615b041a633e7e7ca995cc52e749267c038047762c0fa7f54419ab590e8e0000000000000000000000000000000000807b8d1633d8cd1619d6dee02c08fc8f23fa4893830cfda32ec6b2f9367c18006b7d3d797c0a7385e70a454b1027e5f000000000000000000000000000000000dfa56c5d81fdaf2abf8f82512679858dcd8dd0ca0f142e847746e45a63495b4d33431892bd0e638a5be701ed043190d0000000000000000000000000000000005b2ef1fbebfa15051bf048f65b851e88ac94a5450b7b9a600eb7422a71ba5bd2f67bd727982f4e214ed128f5c4179c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005103ed736439271cbb7cb0372b455998c99b48915616ddbc9fa396e05dbb0dacbe27a2ddd2eadba3ca352dc40a765d7000000000000000000000000000000000d1de628cb79193e939d9a18f0e947f31ea00b5b2ac50dc1827ea41f6f134a59590d72e7cc43c6c17eda264287871bd8000000000000000000000000000000000adfae49d9ae730976b107a54b6d79bf37bd6d418d774a3898b615dfe6f8154ba9e1544f7eebc9fa4094bcdd7677c90000000000000000000000000000000000048ddcc907311c3130ea2cac650e8eb956959d52177f58d3ac96b294c27ed112906fe927291222295ba676e578e380cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000214cfe61508ab939b4a1f34fb795ce58380e4bca74d77b485444ab5b741d4395a78ed9b6b4c00284d6a212664c14e7e0000000000000000000000000000000015b1817974f3da7d3280dd96da5a0fe9a924cce513ebe4c84f80880d23629f1d3720661d4d2178665521163938a55901000000000000000000000000000000001325e02e5e3e57ffd0dfce2f26b70aaaddacce46c91ce6be1bede883166b0441302201e71d1f5a3758dc8f72627dc1ee0000000000000000000000000000000007cd7cf1b798c28e3b09882bef631bae76ce2a3b25e3d7d9b13e5cdfa8c6de4c8832e5524f59549f980a70c2ebf507771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab0f16219535e39fd396a73af90d105679a8c384ece811c0c8d79cdf4a13141a1517d2223ab64c61b154eb11ceade0f0000000000000000000000000000000018444410033fe9496a0d27c5d82d2769fad952166adcab12b2b026e9d2fa4b1fc363a2e745cc1826e3397822900507d5000000000000000000000000000000000bb0349a8c0b0f6169df3c7efa546bb71b494e95e184fe6855fa4fc2aab5db198cab92517df33e1ea0cc54936c35a11f0000000000000000000000000000000019cad998ee871e6db8995d9e4a848050efe3fe8193b616b4355d5f89f74529f0fe3d7bd8a894deef85252dc2390079861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071ecdc0b72d9a59b7f5c60b8d331780ce2010295e0f3a8069b75291cd9acfb6729e59736c17628d1f61ee893d1a34fe000000000000000000000000000000000e736b51b42e547b44a0d907fec6b4ff7101d3233a4f4c2190ad4d3cef61309b060cd236b0aa6f81cad80c4e987632f10000000000000000000000000000000005fabbb294c92e9657c998b2c785ab29e2b34e928a5db2b5ac637980d36b173da36841fa4b479e230f6fb64b26589af90000000000000000000000000000000002cabdb05b1db54c3e95d3d6bd5bec6a217af9a7989acd96da302da0bf5b954de69ade2da9edb600af9671a152409e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184e9307c980ee860ce798c01babb58c49a0cd4e7ad89f5c88d565be1c7799c2f3b5b5681238b8b89c675491b0a8c9e90000000000000000000000000000000010ad7f1e13b39087cad3051957f4f6e2b059f4efdbd233c90d4ed2ed042d26fa8ca7281df84cd3442717f5b855f60050000000000000000000000000000000000242d502a4242a1ec6679b24716e678b294264f54219f46360dac8aef8340c50cf25fe194b25d78d5d96eb8b8448e29c00000000000000000000000000000000005f183ef23df76c8cb4e94b0faeb01fbe1080ed10ff2ff12a446cab5dcc1822198bc5a2bea9de66b47d86f21d173f5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009edd9541676d4f8340ab0d57dfdb204b5c0f8c439576efeed3be8e546830ad92a450a97f86335a99b82c54265370260000000000000000000000000000000001762fa5eb1f01e2b72d0be14cfa8bf8faaffdd0fc8129c5e19c02efd8401fd24cf09c51bf0b6a186ad23d46874f0c4140000000000000000000000000000000016f68b1318fee9f749bc490ed7aa3f9910384cf9da77156b9130e41a6c2362e5be9fef7f9d46b2ea0a34a7383b075d6b000000000000000000000000000000000f4096aabd760dde416501117d62189a0936efb6701f47689d864a2e87b004fd24fa7e3eefc414dc06482108dcac9f171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cd03ba323011dc77b4d5ea0616a45e2b1271eadac932ba65bb40ec8caeb404d2e32cbf8ce0c9d6f6906d22e35c570900000000000000000000000000000000109e7ffaccc50db492d0308636f6530d2a8c67982fdde72cbc9a5beffa490a328b6da29ae41895a1f8c90d61c96d1b2d000000000000000000000000000000001102d27bf3ee092097087f1efb844f1c2c16578ac6745b8f80c2ef540df7956bc73857336fdd95fc40f9cd2d182064bb0000000000000000000000000000000017c3eff4919bf69811adfa2eb77d1902e860e0a50ab692f8cb59e13ec055732f3fdff100602135689c40f825cab748451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fe793c1c314fa38d501d26b54a7f515f4d2f3cccd153c23dd64ecc823d780d5e45716df4230de90b94f38ec2b6b47a0000000000000000000000000000000000208ea4ae3926138a0d53418d63f683de6ce9163bbcc1b17a0c2d3a61f9f57dbc43461c343422955bf5e447bac295ee00000000000000000000000000000000004f8b1257410d221a30880052a8c37a63686bb65f503fff02ec629c709e1c5e4989322ef0342ebda1426903b39e765800000000000000000000000000000000178b567544465e7142266a0d7e0c2d2e2876fe6509dbf18b84416d15c0f8e6d2817efd3dc8f10a71632f7324c1f66ec11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5fcb3c738f5b0191cf66200a7d4c29c54b3903165bfdeec78184cc3679dfe89e68c7ab0c50c0a53a94f88b4b68369800000000000000000000000000000000039ac1d419ccf9d3540a859e51c48decdd0ab7ea1a78f9a2c915ed019f15b4f6efba57da3dd4955b1cb61e2a5a6ee017000000000000000000000000000000000b94813c49d13e3cdd4f6f3d6ce58b8ca9f75746a8324f5e3a4e9161bc3482ad478a9f8cc33f1bc5c2ca51008500a536000000000000000000000000000000000f6079b9a35d6b9c4bd7061275bf97260eb4746c206fe8ae27632f54008aaa2d3b8957c646c2b95ddcd95684e04f58111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057c2a472a04e8d4bab0e8f610fbc3b55a918a7042c5cbecd6e137244a64da6a7cc88a3ea666e232dcff09be460b772c0000000000000000000000000000000007ca4091c90c729f5bee0b8aef643d2a0e96233f5c24a4ae9a46a40a7163a19a01f6dceda55ad2dc6be9603ca7d5e6cf000000000000000000000000000000000d0d6f5b7112d4ecfca98b5f248ae2e4241da7482d14f99d17cfbb0bb8e4091ced8aedb90db6321a6f073671ad5918d40000000000000000000000000000000011fbdd5bb2711ca0b0d7ce837edad45b03faa6a25b9d4bf4e2761279fff6f35e53a2df6ccca2dfa076f69b45fa36e47d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018278c188a10688cafe661fee5bf97d5446f7a4b90efd3ed1324f653f0b2c57b827b0a3ff9218b9e9e3dc3e1ebf95784000000000000000000000000000000001045e38ea40d3261e3a6dacd64810d140a0527b5804ac085e15352bbbddf4a763a2086d62c928c13168745bfb1ac4afb00000000000000000000000000000000193d1ba7fe4266179dfbcfd99e7f8fece3fee75ffa64e6c1bb5559dfeab16212167864ecb6e0ad8e33f815826400577300000000000000000000000000000000062bb1586b9b5fd4818d59778f87a57e6416ccf3744a9a2be59c6058642ddcb9179b5ffa1632b0c19e27d60da3c27ea51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116d1f9ff304f684167c011ba1fc0c68dad640e7d3fae81641403f572fe85274d71e9d77fe27c5e2c2dc92df9e180dc70000000000000000000000000000000012b61248cbfe9cf54d489a259e80c10d444ace10e0a3bae31ee67de990d41dde96c5f55187ce663f22ec1284a6510a300000000000000000000000000000000003293571e8aa2e05e18a4ed3de76a5f75c2a62f14918b18f2ae5c158cc1520756e080394c6c96a8b4ca5b75ac5173208000000000000000000000000000000000bee354716c71f4a9c2e4f0ed6ed56ed0553567ff2a92938d6f3f6e22ff1d2cd7097b6fe65911000859bc50d5e6593251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128c52265ffd0edd5253860d0691d71f95ba0101cc93ef8d86382e7461f3487242b139b31745f19270c6b2a1aa6d8a9d000000000000000000000000000000000f2eda86d5126e3914be6bcd8ca7b41311276e00f5a20740e3f0d11b82a331c841a79e3c60e2b42dbcd932778787556a00000000000000000000000000000000001d7d245194d622ec87a564095d7b9810981c6837e6cd1be1dfe4b01516bb400db3e7f59dfa001f1574750c80716bb300000000000000000000000000000000068809d96854ce40c835e58ad602b7f75be3299b5e064113e2098d292f6a79eb3d112c9d8ad6bff41b06b6d22bd230091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7dfb7a86ba605f5dd3819f0757ee9782fa04a9b5c82ee3dce99b89c5a522cca1486d8d5a49ae7940a622bc54388e00000000000000000000000000000000000fbeefa22d9ea62968cef3d4e8bfa5e81002bd509b209f4b4e10de82a75a995bb7a1cf4b152d3c235eebd323b9b13b22000000000000000000000000000000000ec1fb16b00e6cb3a6fcc1303769fa7f1d5c94b1e122b576daecdd5c484e6f880d18d074f77e7fd83f53d65e4f7abea00000000000000000000000000000000000bc7e58f9cf9ab293ba008c9eccff5ea2606c172bbcf40a058a1eadb012d69995ac23b9f7b0b2f4cb460b4c73ccf0b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e1c686bc90357fbc853a00e3cd3b0b03df94bc341ef9142da91696f6d46bd8a60589eb361ea068a8623e3ce0f17e96000000000000000000000000000000000acf45ea5a9f7a1cc7c30c11f80fe39d3e2eaccc4f9a2884365d6bb7a94d79786eee3a923788ee5497bc6645a25c54330000000000000000000000000000000018479ab8ff9787272d8b7d8e81175bef7911105fdb6f7903f8e5ceb57c2a487ce125b930251bc44b9a92cfcb082ab594000000000000000000000000000000000d6437faed48743a53caa2983010d0b04024d9c336242a6d2b9b2bdab712fd1b7dbc5f9fccf93a8839a95b500c1538971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dc679a3c1568af23c75e9d450b47e8e9527538c1539331435d85573181ce998b39e2cca7016c1106b6724e2d2a7b1e000000000000000000000000000000000a2d86622d54542689b9ee01fa4b5c6a8c75712e4f32cb56ba61774110b8ab0bf8b66568a51f945cf2d986e4f7f5e8ed0000000000000000000000000000000008e4211618e1b8acb0e9a48ee5723a745317a24a9ae966fc8a0d0899fd701d59843064c4d0fde980565150534e1fdc3d0000000000000000000000000000000015b1e209d57954ac5a2bf6bb256746bd9c3856378a8dcf2ada78c4b3c2ad21eca26ec1b55896f3b1e4f3385c2f3a9c111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a1cbaf9a335c5c4691117ace37384774d53788132b304eced94f31cc9e4a7a05c5e5fc716c7f065cd13f320b2f65c2000000000000000000000000000000001580904030bca5974f21c485d2418585162fe86b33e74206f95da76f1b3566ab5bbbf15710be0a39ad02f4ecf75766d700000000000000000000000000000000120d1b3931d547aebf3a709151a153f07528dd4f0f3a59719836b8de2322ec5fd8a12a0b38e39febecc06d60efb50948000000000000000000000000000000000401c148d0782abb859cb4c87533252b91d481f396d313bb7318c536052a2ecbba9e067473d85d7c29aca75e6e30a5dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001916d97a329bf5754a28c085af6a3a3b1bfcda48446a1654238a584311b726c097092b38f0c3bf97bc94ea278c5058fe000000000000000000000000000000000b9121ac96f6a4b0b2172b4c43a9aa5a69fd483e670a205c093f498447eb898266700952eaa7b6bd3f4ed7e295d078b000000000000000000000000000000000143de548429a6215331bf5345c460a6aac7cd9b0c05035dbc15453b13477509a03f6ce9883a6ccc72546a51435661eb3000000000000000000000000000000000dac265a7b14fd7114492c89fc525b66ff2bbdb232f1eb0608b6d1406f48db9738accb1dba02f5a7457e0a4e678e2b271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000299097df0f7f5394805b7962cf39bc30443fdd85b73d9b38048b6309c9d893cfa4edd94120b2b1b801fe538216dae2d00000000000000000000000000000000162bb0f2bcb5f2fa14f807e38f0d023ceb2e8dd6617d190a9e7fa9185d48b4beef29631d0a66860d7a68b7416be9129e00000000000000000000000000000000110edb24a268e01ddfc79abbbec24c646ee7b3d93383a75b837688fae579f91e0a7f3c5a0b7855716661347522e35b47000000000000000000000000000000000f5bd5692e6ceb572903fc47f8f4e01d43a2e6c72694fe7ced711900d4b00c6b603d4e49e3ae4e097f18b17d5f2c2ccf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e0453cc3a3c2274346b95bec30934312281306b99c3c054c20513fe31145cb4a5fe04661f2f5063da3bbe53f20894a0000000000000000000000000000000011fa917fe95f6ed0f912cf7aa46e91d7e901b03eaae42657244884ee96b847a0ace2fca43e9c2a3eb418f3292263133600000000000000000000000000000000186430abd0f849cabd821ca1a83a04c88a46795083de8b0ab75919e3f1efce1cbfd118a94c6213f2edc8237c94873632000000000000000000000000000000001541519d0ad580e1fe6375329e9843cfe3fc817833703bcc6ba53061e74e82db9900fa804b1e15ce51f6feb8de08b6c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033be273332f11dc925e221f92168cc4b162d9bd747e3f095036c81700f351f2c6575dfa742ab377ce2759e5c03cb63900000000000000000000000000000000133d4e54c040e7d406b92faa417e71d5867c77d1b0cbb802db3347cde0fb3558c212a843d40165ecbcec55c6a7d1c921000000000000000000000000000000000a045587b79d2b10ff8a1575abf2b0ecba81c9cee72c1ab2025ceaceecb178f47fb9da1d0c432a1bbbdcab7fe46f1fb000000000000000000000000000000000103b644cb11bf19a27a63dda30ad7b069450cc4afbfd8f42df201ce8e729208e286ce6bdfb89bc554e88f0261a5429c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157c33f53db31a060394a04e78a9242531fcf91d3a1a4a24052e873852f717f5e7cb318bd7485601d9a7829eb286f53e000000000000000000000000000000000a9dfb8956e78bb62a88b875a0503371423357b6dbe0754dc7273f2cbcf1500d48d3a2bb907cee8fc9cb05fbb5a230380000000000000000000000000000000018540ab1d16898717b59da2ae57a9627de25fcf3f31ba83ff8a110b3730331381d6515fef1d65022426fd36c35f782e50000000000000000000000000000000006bd1a503c954d9077dc4ac06bb902c141ce8d0f22788abef3d3b57420ab7b42080f7b9509ea66f374040244ffd720e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca5fa07f71e73d0f095f1c540fe4eacf6e3ebc84d0db37499919116255ec32bf7a8e0a68cb238be5b1b216376f35f1c000000000000000000000000000000000612c43fa29e8fb2c0804ef51dfc1263ccc22eeb92dc5dc89a25a96e22cf53aa1cacc66f9900c262115b95473b25883100000000000000000000000000000000030393cf4eb09d96962967e9a79b7cbd2ed077c14001360660e15f9ce2cf8f154acbbed3407dd8fb3216c9b650d1a3df000000000000000000000000000000000ce692802c6894c9c60cdfa1dbe617feee9ecbf65113393295be0fbcfb3ed43e329ad9cff3a87a07621f6b332f02f1431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003491599c9ea078d9627a85da1834b998d10cd06cd57770f5f05aa94dd6c3acf83bfbb4c1d9836bfa87d52d6285fe82600000000000000000000000000000000069a131c4804188c4abd6490a9e8986c4e27c639503307c8e145c15735903990a5a91caa362c5b3d75302b056df633650000000000000000000000000000000006ecac0df7694c696a1550b32eedffca51a344fca10a1a44776f56f43c940199e1680ed3beca99a004e12ce3ad64faac000000000000000000000000000000000d54e73285c45809d11ba8fe29ba21130cd12fc953e22aa91e5b0737c935b784039e54117ae436b086d15f286b0efe661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b583b6ce4ad20c73fc91cf45f0f7cabfa8a06e432bb98d2f05ebf7a0304f61f700512194683a1e939ca13a34faea94a00000000000000000000000000000000181aee787d82adf8f06a2a42b64a8ab5a1782ebfa41ba3128f65ae1363511cca79885a79f3ac428cbf77c62f330543d30000000000000000000000000000000001f50d9987c373eb4399f2ed68fedab85d582076bd268747076abe57217ee5fd74f719e1bd7ee5bc3b1d76cffb3e709c0000000000000000000000000000000012a72bb9fe4f2bb9159180b17e59ab44f94b079a675c6c493acde3c2ed97bee2c5f6af312e9a84ce21b2ca67cbbe1ffb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d920f35201837f2b70e8b26e5a86ffddeac1a386a118b71087f67f4a0a15c4f4c7d1fd5c136b91e572d318d734ef56000000000000000000000000000000000622ae91637a0316872f7b73b635c99fe87d43783aee14f617d96fa7e777fc4f4f1bbaeff9100779da2b2fbe2ec1118e00000000000000000000000000000000113c43164531b3dcd92365a7e4cd32eb8fc9809828a92f13214bf9532c8f01d57388d66abdd1d2291205026047a594ef000000000000000000000000000000000a2ddf1fe4557279c105aa397e126ff745dbe765b8607b8ed247d5a04d99cd714d345bcd54fdc025b34634a872eb76501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016453bc748429529d164dc126ff61ffa34665e8792d9abd3aa005eb505308bc10cecdd60253a289e88fc9dfa114af5f10000000000000000000000000000000012432249118862887de4b386d14e7ebf88e6dbb46c9cdf350ac8711bb3517a255b3c376e4c577b322519e24dc53541b700000000000000000000000000000000161ca3cc5946a54a08b3d2ffabd0d9d25e144fcfd043da5981aa105b993b254d52dcf646432d7fcb4da491f4a47f16be0000000000000000000000000000000006af4e6098ad590f4bf4e9cee74a0e24be6c8fdd60cf98fb7aad3fb244245062b40a67a63074c8780669badaf9b85c391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cae2561e04ea32b7bd0bb6a74814b06a33ba057d0f4a5b35f235d6c882ee8f640cde2682212d9eedb920dea3c89e2500000000000000000000000000000000083c2ac5f1aa3a62c5a6b0e5fb93b8c16b9565bfd86bb4882f33af7a1e6cb13b0474869dade71c2ea709a4df945d79500000000000000000000000000000000014239e6f5c7521819b4769b9c81305ff22db4f8da8275ad48eb4ad15a07bd9e85457f869f3cdba7791bbfaf6c0e95c2c0000000000000000000000000000000007399ccd6ee2cc6a70a10ecb9b2cfeb089d169c54086fc233b812a8bea34ed2dfcfb59e58a9a132f396520305dd1e62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008abf98161a1cd76726e248e77549386fdf2e314ee41299b8de9337e5f05c4590ce2420ba754b1aa16a06a17ed13749b00000000000000000000000000000000103ee9f075d71c115e05f7f6e5c5e06ea775534c6fa6a89a6c96c55aed1894921136ddb5f875d680c387e3453ebebc5100000000000000000000000000000000085aaeb0138668b1b965045a41d27319cd67830e47adc0038d7f6d82cfb0a2521c68fcbbbc14d4b2c5254e0a12c747010000000000000000000000000000000014526c7ec33f836a07a761a4da78d2ce89d9f54402be767ee34caf6a3e7be713e30e84931383032987dd91124a26b62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df8bc66cecc433f08031449139eb77d5d6067ebc927f2cb58dc793fc41c42e4971a7c57789ea282a3369489ca27cf990000000000000000000000000000000010e469d4e2fd2e0dfe4760dafa4c6f2d9eb4db9932175e9e3fdc4707c7fc085b020b8ae115462390d42a94b2dea48c4100000000000000000000000000000000061cc5a890e12bfe57c500670f42740e21080145d81672c3f2f13a90f8e0e9abc4d585204df6919b25bff9a57624e4d50000000000000000000000000000000012e7db8f5f679fe08fdaad3124625896a592fabf2e7269584754e9e9e8494fc071eea025489ffa92efad38e4ad70ec601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105545e59c4f35137d3b1b498a04b5ac54aec5a938527708a9925ab458ec1901636be021c29ca65daf3d703a84b2e00d0000000000000000000000000000000018a9280c169ea4483efafcb4052ec0c2f48ec2cbbeadd2714bba1e501033b77a579348a85be164d20538f1a478f32331000000000000000000000000000000000bbfeaceb179f3bd1c527549bd9f800c96c7938377ef7f95e5c3e02cc1a466a055c1d5debc75b4ff5060022f5ad4b5d100000000000000000000000000000000163f7822aff84027284112bc38a79f5e5f03f9944152255820165a8dd03575001a00471bf43710173460d3610fccfd361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5be8e013b443c2437af0dafa8f1e90d59ed8ada6f960acbf9077c549cbf4a01e2ccd500011c12c3116b91c8eb4420a00000000000000000000000000000000156a5199187951ae35717401b27daad21b0308f0c689e179fcdc933447d6810d4176774b2f4635c18608d1926521a28700000000000000000000000000000000165301703b4424392724e84579b74a97a7d0151c30bc0a03dd4542ce2e8761c74b329499bb80ad874fd9a2bfddd49a3700000000000000000000000000000000133d7108bf9023949952a328c17d70333ff10bb2fc3058ae1a2f8b53c28763a7973ca37b424081a81a4fd70ea5d604151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa91553438f837a96a1fce86fffad1741a68d65b74f98ef5e9a5ff50bfd1287955e52432c45d5a4d961dafecc9542430000000000000000000000000000000018abfbca49ddb0a759277951edf0ff40f9a7f4d92920afbd2f3aa091ed040bbe2bd875b125281c7f07b00a4593a949da0000000000000000000000000000000018400adf07e8464e6f82bdd636a911ced7598e4da6a5a6be191e980d85955c5b9313aefbe1e5819f562020b5ce32246c000000000000000000000000000000000933bee32d06a70ac1d22f217255d4f9170bd31e3f00112ff7a32a975c320eeb15f9a93584f2e2118fa17a4bd91c78831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061ea682ffd6209a854551f6ff2efecfca4326fc3100f1b906b584b6981cc34e1058983977213bc9c0065b7ecd1dcfb800000000000000000000000000000000134c05bbbe8ab83ae6983a380a13797aeee052cd10e04f629e5a01f3a151d12fb2e1a389fa2d54c246826f0a1ee4f80500000000000000000000000000000000190aa651cb1ce8d82b1bf1ba00a205da45092b83af683bb35add75baafae08124bd1516d2724094c76036597a55fb7ae000000000000000000000000000000001090e6f35febf7a783b0e4b2e2d20c9816224c940face656bef7843bcf320645ce34feae80a304f59b24ff2da4c2328f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f27f9bb136520ac0fc5ed0e1bfc83f312aa104c522e37dcbcb6b81d04018ca2dc8eb14bd881efd364041c76371c89100000000000000000000000000000000073e18b49f09627f4554c34f898cdbdd1f81eb405caf976be272e40fa79d90a0a69aed387ec1839168083de1923aac4c00000000000000000000000000000000095e2b74256fb640dcc076f3a68cfaadea7b44c5b456c4d1ba8fc8fb755a7de91f9ca99de8736eb3866f3edf1bcf898200000000000000000000000000000000065ef29196b54b6f74a6545c3b047b91e22f64b209bf7c147dbd42f54c24a4cd8d20b8e4340a48d52f6201758380cab41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052225f888d217b3f68f22f1f414967fc8a7f2b2a064055f4be39fc8f0ae36700d12afaf603d7861574315ce9ff6c8fc00000000000000000000000000000000154e32034d449891209a6e07e00f283ff04754d529010586b4395cf0c7a05e62f2d61156b5ce2549ad5068f4cbbac283000000000000000000000000000000001517ba9fbd9d0e821265e881bd11313519f9613a92cd631c6ce501e2a369109b22b2e0fe263d918e3e244f6cefc552ac0000000000000000000000000000000016b7e2e729dbe5947b5ee9153e36a5aa1cba17fd98f4c396eb84af40d95a0076851b1e7484352f4eb9a50c5339393c6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f5c93830b642d8701552dd48a1cd044d50ec327ba49ce86bd9a3a877051317727977bf713144b213097200cd2eb4310000000000000000000000000000000003c801800afb875de3c7c69a8a62f0da133bd80f7e77f68da71d4a0a5957604e8d9b56b8927d0450f6fb2c905f148d100000000000000000000000000000000002be299a0e4a96404b1d94a1ce7995fe70abfd9fb76f3d2e7e5291aacba20b3a158f6d6470ff34b530608fa019fbf0cc0000000000000000000000000000000009d6a0413987fd5653c47ea7d9a1b64057be59d53d3bb6f1ce9503f48a1fe3eefdce66827d48448ebac82be98b9977831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f89863343d5ab6e340b03300eb3d951d75e88b2f10ed0f5ad3f2ce7c428c8f241fe8dad65db1f8621d16148fcefdac00000000000000000000000000000000006efbd2522170d2da1b5f3ce1757cb0ca29f1d349360e62491f54230642247d9ed8b17f87574e36548d8dc7f8e90ed00000000000000000000000000000000007c163c12031f68ea603cac1c47248315a4bf888feee92ba6c69a09011789ec4985a62cf7cc0dabe582a1c4b1ae495830000000000000000000000000000000018b548add8363e0b6a99c6d40f08dacbc7d9e58b56699f0554faff1463669dc8660aa839fb5c2cb370f493bad6a31a791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ea1a249d41c107e8fc99c89cf1143da37b5d10c1ecd141f229dd4d0a4ec5a729fa72238c62480d9181790a73a12f1d0000000000000000000000000000000007e07fb727b8fa251c89ef8745391edbb78e867e1b304604943d832935a0803bf4e8c5120d012c986896b9d988974339000000000000000000000000000000000bd5b78773fd33062680d742dd3c92b541c41825075d88801fe91c67d392940abb6638bc045e59fc2f8c221602abb77000000000000000000000000000000000019f99fab2fb70b9924706fe5a4e44417d2debaad7d41cf3954e8392f75ebf4193c8db18a5a6e0cd492ec2a6f68354a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e8d229c6b22bbf787574ad39c87428ef40eea49fefda1eaa308140e03c310ce265ce7a138ac2f0343e9586ab88f5890000000000000000000000000000000003e8131900adefbbd7ac0b3749e1af4fa7654cbdb7caa737c402e99a74804bad0e1adc3ef8da76ee7a10e8045b8a51290000000000000000000000000000000015298dec35e7e652f808f7b5990f5fa3eb75a6a510109114403adcf698eabc590ae21dafad25fadb2617e03f513153240000000000000000000000000000000005d10ee7585acefde50d07662d79253e2179b9a1b1dadf41c1ca9b07415f0c08726c23762710d4af7e96d5afb34b48fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1e56f0f184a3436d5afd00aca3ab1df438843ac4f4be54489e629e3964a762466d0af711b0f7face917f90d5a93daf000000000000000000000000000000001144b021ab8e8048618bbb3eb17769de37203bc0e068e147319ab49e886d8f97e1bde16c62dedae35c1d46dd138e81b300000000000000000000000000000000191ee9b0e77313b177f5d00bbb9b265804f43441f0ab60f217c777771e3cafeac32abab451651bd68654d459e113712a0000000000000000000000000000000011996b92caf8eeca74ce7d347937f158748d7e556565fe8117c311d94b97c5b71cac6e20340cf10a2e19f9d26971774d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2fd4d20fa2bbe8a36f07b2e1896b783c071f0a16d52a6b6eb065b36ded6a7a7fef512d3a47d7bea4c092451b87ee98000000000000000000000000000000000a5e8d7bf84f4ba86b6fefd500f7587b7e500bfe693d600487755cbc0632d2d1b8ce418758433c53fbecd0167e5c62ed00000000000000000000000000000000017a5b73b813e94f5e6458b9d9bfcf758671d9af84a326951017c6c1f9a419c43fedeb79bd1e52ba01509a3ddb087c5a0000000000000000000000000000000011f5aa33bbbb2c2825fc78133fa5758e73e1f7dadcae362730f25d1c85b68908aeb715603638e8831c181ca0e96dd02f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abaf7a405f23cef690f52229ec51bc8c3a0ffab97167fa969a4d909549818d402a8f53fb304547a051fc3c7961c4c9d0000000000000000000000000000000015f2af9ff22ad3f23372184f7aebf644a0f0e8fe85bf850536f070dae1bc1d0dc2219b1d1279bf83e15d7843d1947fde0000000000000000000000000000000004d1ec46c5defab4a25f3d27af2d004fe5a7c2ae693d8e0892251d456f49c395c58d0f94c489402e5d2b99f8c9993326000000000000000000000000000000000e20f5646fc059fef433364fb948d84ceab0cd36b07ce397aa35ba71184618435b955fe3697a5937db471a5e01729fcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066ddbd4924b9304fc5e3649e5330220d824f9c9409d0f61190e47751616f4639d796cc1e51941e997ac8f0967cdd9060000000000000000000000000000000008f41bcee28dac19eb10feb91ee7a2b7c4f69e0e846c7fa0d74c8a193cd09e34fae0b21b7023a278cc2d13b06b16dc2c0000000000000000000000000000000013e966abe538a8f5fd03515608ff7a6fe78b0011090c8e68051aa6ed6bdf963a87aff3e6ca46a6d53eee6914b9a60a2e0000000000000000000000000000000013f92a8759497c5b6aac811bec7473fb5b884c14598d6a9e192db7843da569871aa7d299d749c58d2c983470870512761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033ee9277c9ca0aa5167fd2e0c5c31e035d639d5fcfee18e5511b5db577afb779655e1d5f50d61be281c914346ace674000000000000000000000000000000000d870f7bdffbdeb9c2fc1a457b82fb7df5c8cb04f0a3b97bf90aa451fd36df72f562197dc70e2b89d1c69649cd448d7d0000000000000000000000000000000000735c5eeeafc240dc2cb0adcee2eea2788264459d04d26b850f3acf33ff917246a0d2457e331f4a21d34d97875346400000000000000000000000000000000009d54785de42f34da35f3dd35d9bf7edfb8311a97a190d86ddfca28fcd55b06dd4e93d11ea9496c09621d596dbeab6231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000817029a26cf1106a8f7634563183e1e9b76475dfad7732f8c213f151a1272c47643f3c90de4fc887b91274a3386e2f0000000000000000000000000000000000cc140b5daaf20f2ef7d7a1f978f6ce4b1bc044fda9305873663e3da26453d15332de153ddcd5fee3371a6ab01acd9e2000000000000000000000000000000000cba31d153a5cecebcebba7283a565fe17ee8c0e13d89894e53038e7274353cfde1175ef5fffd5d8d5724094fb7e9370000000000000000000000000000000000e069d4cb4914bc268f5146306d0cac6fec65e97f0c9eee89d41e3485512ca715b2bc6145a13ee40169afeba22cc0d601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c59b7969ef96dbd086d1bfeea835faea99e34a2c80027a3c9944cbbf224807f2a5c72556df07cbfed55442571da7670000000000000000000000000000000010060fc940296ce66c3f0d21f5ae9a91e63a04cb6f50a94a3138bd3a2b3043d33d25035be8946c749db6612938930b41000000000000000000000000000000000e53b5b7ef78be9d98af99b9640ffd6198add5c553d8e3e236246b7cd635146346a69330514292ea18ff63e9b011d3960000000000000000000000000000000015ab50891d6a829aee6b05ff8354eaa9bde44f2937b7ec7a12943b590dfa878c3b02b8a9d3ecba0f9368212af6e2702a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004cb61ef4aa507107bc52c10dcc2f7e2002ed9ffa343a5814fd650d1be3e99474240c67661a6b8b02ea5ac93bec43f30000000000000000000000000000000010f1c31fce5228aefa8280585a550f129ff6af0d58e16041df670129191ceecd45b6ce772488fde181b38444697616010000000000000000000000000000000013e1254096067c28818e382addcc5e33d640b5ff8403ed4692f0493e9977a99faa5e5306accac2ce5cbdbea6804591220000000000000000000000000000000008698cb3edb1b4642c27f90de94751e6c7d83056abdf9fa4d9b8b682b645e76681df65ca8e4d46b04d3bbbec3bccf56a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001030489d08394cb93ce847531d64ac4e3b2dfe328691b7c891afe03270e08efaebe2559b51a2e4e06dba305c1f0fc738000000000000000000000000000000001863b4f06b4657c127b5e3d40403805e4376a8faa4052bdf84aff60423e92e85aaf3e0fbecac3a92c1799e0b5575b6b200000000000000000000000000000000097d5c89dd182c35b5bfab1ab68e35dafd1bc5a24b0b030100af01025fbd5c23538cf5b26c79aed7dd525f9707bef5660000000000000000000000000000000009639ede2635a34430b3f246d8bc141b2addd287923a2181885eb5adcab878a79a42012adefb804346b523ca3b4af1b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dc0050a638e4306c2995f69423e417b2e6302f26883ce16e7a1180b4acf8e137128a60210ea3d8e23e3e601bde930f0000000000000000000000000000000011d00f7521201a19be2d684bc83fe2fa713706c70efae0152bdcadad1863266e61f9281c2e85328b11617883dd8a8f8600000000000000000000000000000000006cc1c9c2b041ad84c03a3ff9c71b5e146104daf09f48cca5746a40f9700aa8d917cf5d93d528f8fc5e09b0f1be804e0000000000000000000000000000000003e33c96fd850cc43160693892bf1d9bd88b01556573830c995b793d197b0b15cfa2beb5b584f1e49d2c43219efb4b4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161e421667b2036f465fe7d95ee7eb34fd87be64e6401c6b3d55e79579a9194f9b73ddb11034efa4c3c32b343ce197d500000000000000000000000000000000040893621ac3b6c204eaa7f12242b331f5377400473bd7ca2abdda4a4b246f3123b9fd2daee859df036c6fea1bd1aa0b0000000000000000000000000000000012d6ed6f54597c5833cbb439f76c30f36debe8a96438ab4192d430728eb773819f70d33f92076d0d9582f95107f63bea0000000000000000000000000000000001572cc131514f004343235ea96f6fb889f91f1d1105cbdf9785e04d4306ba66f41464b6c2e68b422a8029a1a78f06071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118aad854fb455f167b3743d3e05dccd2b888ac6506fe5d95e60d3c148d48a9d71c6c04bc9c421b0ce65602da60c1b04000000000000000000000000000000001888bc5efb9322bfe8460dbf0800e3e8bd17c464562dde8098d845ae846e6db540880b67f764a6e523cd27f1f9be711a0000000000000000000000000000000009fa95cb1afe5cda866cd26694758b14ff9f04c0e0544c5adbaeb3fb37e6b3847b09a9eccb9cd8c2e90541da2b5d9ba70000000000000000000000000000000018935953ee935a9740ad860c9a7790f8cdd7333646fa55375880363bf29a443750a8efe8a38b0eda0a8b01acb6810c2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ff65e2e6b09e59c2369cd50ba857592f7bd6615618d4f1199917c95cc2149f30e6bc4e556f8c9ddaa04869b3c2d1a000000000000000000000000000000000182db4c6aff99dd216912d2a9a811ac6e62f0d3973c82647cc06fbf8518d608d49cce6a5c728ea76d17e70a2dd400e61000000000000000000000000000000000afe3cf47b02038bab6c396ab289d0593a2f810c2ee1ba1085abcf9852fbd165ed4c73dd1dec4ac0c44dc3d325b28b7a0000000000000000000000000000000006b296a5ddb1c0d7c4981fc5f44b413cb8308641d3eacdba441187ded4c615326c8ea9d857aea4198c1a84244b2bb5661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130600009fccf0d7904cff657e81c09edb95cd125689e212cee2b897c7b1e642f68384ef15a69fb555ed1d2f3c4341c300000000000000000000000000000000086f7b892266417012c34faec3d88c195fee19ad01824a5c679f5b718e530fe17710a7de7e76d7b2f5f0676f34b3081400000000000000000000000000000000116305d1ef69aa90c2213c7f2f948597ddabeeee23f4a9fa43adf64d93a57f722c969137419b02242824c52cc2b4ae07000000000000000000000000000000000c40d66794e4c4cbefcd74e80f84e42e8da48aca0237cbcca5f2d53791c0c6e72938443d3bd57d57472b9fa49d1383ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083c35754c26e767c81831bf730504e2a8e0a0a0b2c7ad50b225b3417b1036838d6fe00c7c23b55be8443fa25ff658d9000000000000000000000000000000000ca0a53c1e59d35853edc03a5833c334f7aba68927195a28c41f062a3e352090be4464b469bf9990f55e4e4ceeef65bb0000000000000000000000000000000005f90d7d3fd01fc46015f86b9ad8e4599e6480158290a1a97898b806e3aee8e2325b508d92678e5e17617befe25f40d8000000000000000000000000000000000c393f193867d66ce261fdf09b13899b819b75a730b76c37bf2b1f4bab189c90444ac1914ca87d1e88ec915ef2d7c1e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008428d3e2e74f0d2db252711c2db2690f52cb51b0ec8522930ae68897e51bfd98430de04b859d95f102b0d07cefb43e900000000000000000000000000000000034857c479858dfb85910aff173a1a5917d262e019115b584e7f8d6ae724ea312360a2eb92359576e5109ca4a40fffeb0000000000000000000000000000000003a1f726ca7ff13ea5eee04a6348a961f6989dacca1764b0b33d2ba21009053c254338b05a92dd6561fbe8e74b55c068000000000000000000000000000000000db0dfaa9140f86c4239ae9463ada5b2ed9dfd0ecfb50cf0a2db9ad1c182f1e2301f0147ca63ffce726625204c2d8d651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141705e857d13900b2b38964448761dd1b4655c9d965ae37115264d55cd407204dc04080bde5f615011608e42bc6a2b40000000000000000000000000000000011aec51c26f824f19f177b7b1b087493605c84741ae6dd95ad31af91de8779dd3df22c9b76616d02fd9a5c7402f987d60000000000000000000000000000000001381eedf77bb6318ec3c5c365cc9febb18ee0938c4b2d98d955b30b8da9d523a262cd4b48cccafb3618e21e44a08bab0000000000000000000000000000000004a9fd82a0d0f29a7fb50da605e662e78bac8e2602c280ca750d09d885bda853c9030ea24eb4012cfd75fade752b80321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000066121bf4edc50efdfb406a2d07b3c70d30de060bfe1a0b5f87328b9694cc2324cfc00fb9e315d7999b15c0aed5a0230000000000000000000000000000000000739a21b57db8c020909659edd56703e2d9b2362f001083dec6f3674816cecdb45d390506c1c7874c050df5c339489d00000000000000000000000000000000112e33366e41e331f01abd7c8c758f86185ceabb0fe73f44dd5ffaed298a774e43aad2ab3a37410e6afb33c55e3379e900000000000000000000000000000000186a697a23fe7cdb81c94d9b62849ba14a9c9651bbdb4f9cdc912700bc77def60072448a42411d593c24f37b73a4bdba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198ab71d32c3e803712f3b9dda32e3a40f5443248657862aa362c80b40b2e5b0b9777ef5dd2be7736249efa50f363c5c0000000000000000000000000000000012b81ac62b7688c68ed3049b75634c9188de0111ed36fde33966fcad5c64960113f39be75096b40b5abf994ff3965026000000000000000000000000000000000099b0ba997b5d85b14cb9a9e84d5f5d4875eaef80816130557f542756c47454d762bb2e127399d841e1e8dcd1dd0a7200000000000000000000000000000000058f24391bdeacfd762fcf69b87c757de18ee586fbee7be9c2c16f7e7d04555ae4a0305eb7542cf467d4e1d9348afa761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a8baa8f353630e7acbf6e6de8f7e4c84c00ee7b3ddd6400b3dcbd02125c9452177b5a135852ea98156b68a1d239e08000000000000000000000000000000000ffb411e97e94f621cb467cfda0de928fa29a28d481b14eaf5d37afb6505665299c935a4a2a057103f17caf627345974000000000000000000000000000000000619a7823378645f5be1064d99c44c9af2f0e1ec855ac20e7b40feaa77e3b507578a0b850fb41fd089e01aad172a9ab50000000000000000000000000000000013fbdeaf830296e45aaa64f31d1470c2cf8ba843cd33c32df6f17bcb38eb50995c1606d69fc0ebb59e25ebe8b298a0fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e73af91d7f28c3301387a3d2f653fb36b9288166b3cf814dfcc96625653ded1233de27acd4f0d32e56fc6bb1995b820000000000000000000000000000000018aa42d9453d8c1b20affcb76ad532dad412ba47998a8ebd2da4240995fba369a3ba8939e647ee151917884917f8f242000000000000000000000000000000001468624419912d192d7eef6cfdab1126f391bee55ade7f759f0cf47e78653b0dd875891ce694397c4b785d80495bea530000000000000000000000000000000016c652f8388a3297cb34509a80f54b5f3517123436596e90657fb44ee142d6fa9d1103df14594cb1bd942ddb73d3d1ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f1beedbc1ce681ffc6b56dbf29cbb95a2cd6305da295d9ca80937a0e5c4892ddbcca561c86884a5db2c7f33b0d544e000000000000000000000000000000000be20ba040103bf078690a0543a554728e972b01c970baaa884c17df674a067bba3e0a13098bc22b32eccda37706dd690000000000000000000000000000000018fc0656520989cc352273d046d6230fe8b22534210a2ca63fc2fdeee72f2c0b2f5ccee39452b37813bdcf3b729f74b10000000000000000000000000000000001df2338ff82a70e24f567a931eba8d2a27050e000b409aefb2305c68656356eefdcb0aaa2e4cfcff7c441b9393dcbfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097bbfbff47d4592595a6879edaab1053ff761449814fece45262699a33316a156cf70323720703fed6af04dd9bf4e0e000000000000000000000000000000000e46f5c5d14e009cb89270004d416923e19903837f84b77125cfddc248e1380da69c83cbdde894cf981dc4278df426b9000000000000000000000000000000000dbf70b7352a38e06478ec297d20def1fa1d888e225b0f73cca46dfce6c67dd321dbab00aa3567a3af00f5f171be72750000000000000000000000000000000014761fd503806ee5e525085006f0c46f039cc21e672782b30a401997dab6f0d2964b29741b47613d728363d1c710db491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ad709fd435bc4bad62400505f9e01acfba7acead4fffe78f44b2aa998b6f0a706cc0015d02a11a186170361b3a41c60000000000000000000000000000000010c9eb9e49c8151f0e976d5567d21c1d714fc27e549df12fe447be2d7bbaf396f5b018718cc176ff1ffb381212f9f0010000000000000000000000000000000003236caf1c2985e206ccc20e0656547e95721e2eaa9ec644d4ddd356edbb254bd9437f068c04b066ae55eb852b620ec10000000000000000000000000000000000f5c131bcfda82fb9ce68a935c3d4b4df045137d0cbc004912007facf36c341c15c3ccf5daaa8a26bcc81467f109e801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d2c6f593db751b9cef38abdb85ba9d35cfc06d8d703c7a05ea48864aac90239928bfa050059ea48cf388463c13d73500000000000000000000000000000000101dd3fe101b69063a94e2d029da625c7e7d2b3ac457b640919b9ce22c6897d3292cf12fe4650bd1a6ee354ebb22cf7c00000000000000000000000000000000138543ee48e66e39e0de15e16d01f9a36e879e4bf1f18b14d3edacc23d29f7a846ea761cc5dce2eb95a7c66af533294b0000000000000000000000000000000011dfbed076abc6eba808aa35e6591e3ceec4cc502eb0ea9b764883761b6a71542a505233b7fec4c58a5788b1db7b16661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136e675a00d7327abb7fdae7e4bea10d08d1189404959f870ccfd46c686e0517886bcf6050e915beda1f81687c4afefd000000000000000000000000000000000bf15c5cefbac681b0aabbd772f0f0d0a7c81315f2441e92c838efc14020b3b423da37d2a20b9f1d5ee379c695ffe11600000000000000000000000000000000161bbaea6288e916b2e08ec7d288571b02c3155d855a177f3642dbf691c3afc3798b2094bd6426d7a9e0582fd93ad000000000000000000000000000000000000eb95d8a0bdf8de65b47aedab665c7f52741d86857e419ba2d13e89456593b675a12927326556979d0b96f58394692e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003668aae4a4ebe846f30d254b9b31132607f87bc3cbf4c65764226cb040d356049a095c0dfd8a647b349f94ed855e2d300000000000000000000000000000000124c558b61ad61841b8bb90f2c52ab047e863c403fb573de0741c06bdcaa95faf42a95db3fd050868808445927fa712e000000000000000000000000000000000c58036b9f85fd8cf4f06f712a4fbfc223ca3bc9665095ecdeb4b15636038986bd66ad16556be3f61cc59ac5445f10dc00000000000000000000000000000000152116318c9a71fcd0d2cfd59954abe0f5287ab6e72c1d79024f7111667769c67956487c1c3175128cfc39c8b9aa138e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fb747b1ebbb8887c9810a92c29d4bdee0fdd92987b3455248e0d880bf38a82b1b5b4a08d908c2bac22d2f42a8eabbc000000000000000000000000000000000b2c71b0a24a57aa2babb047d4023c4650c75d61370988497d6a339d168fa6972777f21e3c6333c27e2759e2156610b2000000000000000000000000000000000502bc3acb91187fe1dc5eb4099b197acad6fb8855748ecfe9037a06e7f5ea5ee0a11cb90e1848ae826618734b3c14100000000000000000000000000000000002006721c959431a9cc1f0531c59f8cc0f6f765bcc84256e8b63d28584e9bc962c8fabbf6783a5bc11693767aa5fa86c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001344009f4da545c50bbe5d7a3491a74615f6610f717225860e7916699d847a2a49b4d40c4e4a789fb50b9b237840e00700000000000000000000000000000000156f08cbf940b03a82a3c939d184657a6672fbf72075c90273c0f1388abe0ca6f57ae03764d2e56880811143d5ce89150000000000000000000000000000000009e0a74a0866af8e2a4546a5f63f09d9eea8c2868298dbebb681ff19c3a07593cb9be0f5ff778b285167e4855b90ee9000000000000000000000000000000000147767e8094a9baa0b803bd6c65cbaf80be7750af063b507a51ab4d07befb03b8614b4b66b450e41bc2f8447ce20196e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165a03f5079da935d9890bc9ce1cf816ef7856793d6c7005cecd00e5b8190e8e87f50efae92fb5ddc1df570c4888fa79000000000000000000000000000000000b0dc849744767da681793dea031e37436bfe8a6ffc5fed2041c01d60353b8fa92080f007dc527cee59a9cba38dfac400000000000000000000000000000000018218715143377b8ad8cb93644ea665214e183113e51b0365029815ed89a360ff629f47d36ac99a51b7a188800ffb8860000000000000000000000000000000007e9869b2cba574f0fc71ddfe6b571a087f225da7b0d6c9bd7eae45d982ceab242e04e8c29d4fd3ef7a408f64ede73b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f1b094e46cce2b3d4e73782305e84366a58a96a0692b03cdccbc21f7ba2ea8f5aa3d0aa60a8b2fd304d4f78bb73f69000000000000000000000000000000000beab4bc37813cdd7ea18e2f13dbf43f44f39fb67f5323283f8add7e102c704cbc7bfb6da2f75b8fc0aa5dc5ebbd0cb8000000000000000000000000000000001795353decea43a6196c8edbe9b56e403a67ab926ef758dc696cd1d4804513e5018ef267d3667662c1e1b8dea3ba06cf000000000000000000000000000000000757a38fa8c04040cf35ed700b14db05fe39b7e4cbdda902cf96cabbbd28774a4b6c330c1f7f4caae77c2f32b3aaa7d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192afb9b6c2b8664038bee39a02411ba628db0177aead44a391adff4c4094c347548c300a5007792898be3c4bcd71a66000000000000000000000000000000000ff6189b269cdf73695607bcdab9d803701061aaea09271aaa8a95935dec7260465af7d795428cbe0769d78677cee3340000000000000000000000000000000019941ba431158354eb60360ae3818fb0c20d31b28bc3c5453f70673c8eceac4334d6bd89338e5925fb4351cbb8dee4070000000000000000000000000000000001d674da7c56b02b9eeca85497d5f92f9c35d353e88892f495e7c63ae711eaf8ee356033179ed19c5899e7a705ce65591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000472bdab72d4b529e9339857437078b362eb85ff345101ab98a60bb1abab672b9ab5b6399f13531f24f0d54f6d498db90000000000000000000000000000000017b7d6a7ebbd712ce804ed176e1e9dfa54e1dae7721b55b6b940827bcbd9918ca50f75c3b51dda8f0bb5b31b2321fa0d000000000000000000000000000000000713554582bc9a2f241082343b3b5f26d95976dea80fca76161dabfbf6a9595cd30ed946db46ceb1857cc33505e719aa000000000000000000000000000000000df0897acc9cff0806e795cb72a6f1b46771a913f7d4fe5a036f2c1041efa1f9de38c0b73fab38714fafe8443e79339d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f135d1b78400549463382d47e1a417e53e29f9c3d898a945f75628fc38160278139164191301bdbe6843ffc591cf520000000000000000000000000000000000008304493477102e0de7610d01ab7a8f2ce3c3e22dd72dcce3843c324dd71ca106a95ace5162f98009574ef8c61490400000000000000000000000000000000167a8f51050d0cec79ad0d576e5a233f8547b85fa30e0fcd6a3bce4f5b7bfd6186491424a8e17f0925e20f589ac0ac1d0000000000000000000000000000000010af43b4e75be6d2fe80c9253a526ec90e47d9035022e084f9065668c2b0f2755808b6870fe40db63fcb1ed576b22ea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112ee57f536e59371031c9bdb6f704f058cbf9a776c2aa83bda842794f9f75057456e17b54652781407753b734cfc2eb000000000000000000000000000000000f83454f319542ed9e70a38eb39dd4fdf80409ab005386c20807a9dc0ae1d71afcaa9705fba631dfff22c90ae550d58a00000000000000000000000000000000184797bfa9adca051f09d233de5a642809b0d5ba61c43d679b99d4c791ebbfdd03d0b3836e4a070fc510229afcc8ea2c00000000000000000000000000000000014a7b8cf630f70ebd3c78507a5aedcba397cf6b25a43007cf6bffce4e2eef38cddf11f6f0e33e4831b406d21a3d05321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b0b4409ffa83ba08277b02ee02e5495c16a5cd2baa4ec73392d3a3e79790b37d504f7aa2c27d409a2b32666a333706000000000000000000000000000000000a1c708f8968508e1eba0cb0b0cb8fbccb4fad0e3ef8bd25c5d2ba176ae455adedae06b0aeccd65bfcc50652446c2c460000000000000000000000000000000004ecb77bd0a209afd80d50b4404979a08266dd94d4562f1a7f91a09b8c25417b5b256f4048dc66d511316819e72db7e100000000000000000000000000000000142297ad4ccc7a1ed6b8d5baa3c565cb1b3e9c367181f6771d78156739f996bce6d5b1881569503dc60568c4f9ee06431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b3a24d6da9473513b83b64c967e9774b70c12d74497582e3f611be88e610e779feccbb69e2213dea2d08587da8a51100000000000000000000000000000000064401dad14899a0ae1410c728cf8631e18ddde99c18b3a0d93a556f679c48fe9f5c37ea70699d9cf8b6d5ea2f696cc800000000000000000000000000000000027b84f45827817ec903fc12e22d105a613e3b95f2221004a06d403ec4d0213951ccfa0859626965cd0b941101b7eeb8000000000000000000000000000000000d1934071870f6c33a6c1713bde7940f93d230fda6fe24af8b8ba080a49c4b2e3799caf8daf7416eb7469cb1454ff8111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b794e15ed55ab8bfde1d9f818cb23455ea22175fa1d91c90f30d57e2b2b72179d308cd37d04b4260038eee439579be500000000000000000000000000000000030218d9b27ff96eb37273775627ce5a267b2e691e978de829717ee7f7ad7ed1d39a24ab95277a7e1f767ebbc9643d13000000000000000000000000000000000d3dcbbb9afeca28465fc10b55bdd611ebb60dd6bdf98530268104e19468ad6f100f56e0473b4029c1b02a2bc6c8baec000000000000000000000000000000000addb637202cda397d7a1b8a989164a382134d4e11c6060881673a1658ad4c35a2f6e815fa361802a15d74fd65ebce061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122d13878822673f38b870c92b65f553a48b6a270be88280f391f44e117c1318f8c74fa6ada11a6b402fdd5d9aeb19e9000000000000000000000000000000000b9cc97ba5ef2d496a4a4a3251965aad39c15b98c8e44670163d40455c79df9e6fd6a2866424e720a3a76b0f005c78e00000000000000000000000000000000013a979abd9a12faed427d96004a4bb6b9f35c4413dd27d57a9434c99aab2f1ccd73579db31ccfb19ae93de7aa703f2ea0000000000000000000000000000000012b25025dc6597acb26b3c58f03a686bb46b8edf041cd6f5b3212cdc6c6f40363cf697af9f2183ccc6df1eac612e99fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001376e515e9c1ba13c091677194b5a24885061815fb10671cf5ad758c176586d16e707aa5107739312e54b69209dce36f00000000000000000000000000000000098fca25cbab13830f919053999e51e6dcd03231637f7ad2fa6352ab5672a7154983fce44f3c6550e62b41ce04ed223100000000000000000000000000000000074f435ef3bd15b9983860d94778028f1e8751e9905d63fe0710ef4fa54fe73274da25b3b5e6296b5742c877b4a5e5750000000000000000000000000000000005c3c1d908cc098b790a7c1d912bbea6869214ec64efbc5fc636de7d348717c2d9c63f04a5d45783b0e0d0b568ca848a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dec626101cb8d4c202e616c467a2909eda7b672c256fe7bd381b0d7ef3c6d9d618839d64ada04c11ed597c98c606b8f00000000000000000000000000000000030fe1fa71f97677e8929a1b6e5f171799100a8a6cdf1b08f4a9b9eb6ca47d46fd0a81db87deb74dda4ab97b6f305837000000000000000000000000000000000e2267760601c8b13846b61bb6264b43464460accc55485d748b4c0fe4c55ed8009197caf63397e4693d2c2b700b21b90000000000000000000000000000000007f46397aaa640f3b8a330c14547d9d0f0a6fb7403ac61fd0c746f2bc7fa2d023aad0dc03efac6d03716a384c7d0813d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012507f86b86cdab8bac48a872a201cd676c626da17e09fd6ef821609b7bad4877edb445a34e9f11161eb4e4f5771f72c000000000000000000000000000000000712cda4c7ea7f9a5c99d83671fee577c825c7d62e7672f4082842a8b0d04351aa3277fed610fd268cba12e4c06c1aef00000000000000000000000000000000103bc815706d9818daea0a01bb53829921efe16c0bed27a10ecb74bb40b4e01ddccea5b7c0419d6ab241c4de6aea09200000000000000000000000000000000008a1c10128ad7f895e1b0a7307bf3f0a491391be183c93be57011003746320ef547c3b5a4f44d0bfe320a37b60f026111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce4fe24aa2659152f311f4c1c877ba637a296da340a1e7a40a85cdffedfeb5ba3deb897a864dfca0a8d785650e3ae6e0000000000000000000000000000000012f3df9a2e9b7643a1d12ea2595efdb907b3b1308cac8aeee16c93e622512f37e58bfcb2fa03dafb73dce7137651895c0000000000000000000000000000000017f71159ad4785d2fafd9d17353a1e9ccf31c602c450dca8109d9d59e9ea8a6a754d6abe8f910b617a9ecc14e78bc1ce0000000000000000000000000000000006f20b68262a34735723b57e3df1755b85f39b186370151ade08b6e24ff43bb6e97d24eee2ddd957027f5b257a3b7f5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001549625a9dcd55b3189e6cb1e18031caba3a06382c10cef2ce9c21f6d1762933567477eb6c4eb2dabe0331916d0fe8c300000000000000000000000000000000112db81c221c95e6ab7ef9d6b125b253a8f17f6b5c7cc36df114e1dd0f1218d6c5d6bac9442d03a9c03535be0c2e3b44000000000000000000000000000000001314074c055f79ae0c5da8245aecd133bceb4e718dd25770f2aad68c55a48c5114469b290834890fd5813879d51f5fa500000000000000000000000000000000005f239211fc88218ecd7189df2af108288047edc6555d610b710ec809564de02eecc19cbc43302df3aa973ed01da5fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042d368752875de851ff461366661ebaa61b56f8a367cec34b3b4bf2c1c9b13445e2260ff1c1eea3c8b4b50fb971aa140000000000000000000000000000000019773c9aeb32fa93387e4eee945dafb76a0a4619a86ba9a3c6e918769a941b03b23ca58d3c675e95751d20a407d208230000000000000000000000000000000014b79e7818c49bdce31ec0204d82723196bbea81b7b3e2f4bb92fe6e6a79da6cae910e6d909fc0961a6928b9051eefbb000000000000000000000000000000000f870981d1cf2151fcc3b870f3df969a801bf641da0cdff58905e387ddeb3279b90834ca0a890268cdf9d575b98b1c4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f8a8e6919574aac5b3d568abb72a2112b058193c10ffd19117323062213f167db231563001400e889896628e2d7b7e000000000000000000000000000000001169392e2f93d071c831b7cf78bbc82e4a05f7b6e733c22329d06c4aba0769201d2e5378e009e966daf19151a9c9742900000000000000000000000000000000140092b33b73472b7a7f8e9617ab1439351152f78604300dcb8ebdc189bca5dcd6d7b244ece13a2c2af24a1647102c9b0000000000000000000000000000000008676cfe15a0007e6fbcc1d7d900f845747bc93a431fc895bbe23abb5076587f369253938c8348111abf6583ed9113ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198257ee0350232280aa5ff2c095a37faf2ce79bffdfa4cb505c6a522270c3b64d8d7970fe15137d0471f0e281a41de7000000000000000000000000000000000825553090d142c190260a92f972bfe37fe97738eb1bf49969fc947a47a15280d92e5d759fe96feca7990332155e31a80000000000000000000000000000000014470e046b7b29224379c653c0df643b947fffdb4079aefffcd88af2fda33679a9f82e28a897e19bf238cce98832d41900000000000000000000000000000000110073b9bb1050c745e42d92b10b861a9fcdbd2a9f171331f809b8c94163fce7626770245cbf859f038154d3f7b013b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000129a7c7dad0d394ade01926400c666e43f7c01df96c0ee01d1fc66877879565df4482c30f8495d58cf79c8f07ba7e5c000000000000000000000000000000000856c0804822d2336dfc3b8794f33ab11b2bcf45304be69f6abe7afa2e1184099bb27ca50e8ff5d2c6957881249c63640000000000000000000000000000000012783070ea327422376d199ddf5372a8e4ea40f8f1a2968e6ce738565fcdc258588ecbe8407ecea96c626fa5e2e070d500000000000000000000000000000000130e611e35810d447242b8da283e0e4de797d59d7dc6dfe9da6184ce0424c396a51717502b3cf05588ce1cc59e3d70a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ad9dea076235b8ac5be5612004fb2e549ca3003e95a8b5937d3a470c79c21d413568e1096769d445005fbe0d896399000000000000000000000000000000001033cf820bb8ef77630e4e300b563dd1a198b17ff974ce4758362d4911b6f9a5199bf50b3897dbd6b000501cc58909bd0000000000000000000000000000000003bbff8c98ed3f1e5a7f282f4b223cfca702fa9e263c9c88af307ced2877f27c420531858a9c92c96f17c65f27ea8f3d0000000000000000000000000000000007010ada05d1837b57869d68c83353bda1d4b32cf4bf75b18694d05a323ae9576ad93108bf6e37be89e2b247bdfd7a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b544326c5d44231bdf5940063e34ab14116801ff92593fff409cd1bc3b8310a3ecf008c038f9b8e1e94e9df5dfb05a000000000000000000000000000000000ab8c06d72af5b4d5899837c888312427d92652c421b9e1683f891693b300d7c0fb25deb752d3aaf3d1b15ea142b0da20000000000000000000000000000000003c6c02b0bfe20c87ba1157047a163604049b6756501bcfcfc715f33c013adf014a6d8df1a0a52780031c74d0fe82e5f0000000000000000000000000000000014ae3219aa97e6ea1cb4cae2d43075bb181e365a031014e53c42264afa811b4a828850c12f3286918950c9a10d1b1dde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000354afeb8f021cebd47c2906875806f30e61f47ce3ed481002fbbf38caef7f39bd1d7a3e79aae3afd3cfb3ba9a240e64000000000000000000000000000000000b0a1026dfb482622427ebe2fa83b71f14bd720ddc876d7cc71dd512817450f2de03c284c217d277157e0bfc1094b1a40000000000000000000000000000000015e526359d156859e6eae2045cc039c00f2f2b1f14b979ffef55d7797d2c06dcf3c375990bd9dbea0dad7b85086bd4f300000000000000000000000000000000154d3f9415c234003384ecf180221ae56e93e9c690f1eebed7ee063d5de241adbfb50c25febdb59b2c01528797223b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc80112ee014df71381465ff5f990dd7e03271657e3a1fbe22fea597e212159a74b950dc706af28068829c21a4de33f0000000000000000000000000000000016ffe6f2bf7c365e257d496b43248503a1dfd52c34d6f3c43c0a9d484aa51eda456937a40fcb5af0a3d22342432bfc8d000000000000000000000000000000000d355dfc048657dccf4b929d39073ee3f04a8e3837fd81a724794a15e036765723cbb640be7714a782b49782e2c5ee800000000000000000000000000000000007c4532d2d759792cd38ab9b15cac7af7b6417a0b0bc337e3606279883dafdc21e0446e0ceaf7e9ebc2c69e6eaaf38b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b63eed1b3bd84cd4336c7e1e8851566e4478728bb9614e07a350286e03290162b64626d4f8caa3ef879d10ef12198b000000000000000000000000000000001963fcab39e0d2355b372654a5dc94ed87ef709151eedfd1411fafc7efe956f7b86e61adb3792aa6d94542f67af7380200000000000000000000000000000000127661f03ba355e54ae1e47d98b006270b09a2d4b476d65a394cb2085df3f1c80a8d84a8d7a22234580a7b2d08c68f500000000000000000000000000000000002f4feb22a9ee2691e44cbe7993db835ad208ceb8529ae5dab9e2c4269b56fccf325fb3bf569e994c9692447743227d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081faee8ea8ba5e91f6cab8b1fc8ad30285881f1136e5d2fcf342f45cf8f3b88ed0ec7d17bbad67870e8a0ab0632dbdd0000000000000000000000000000000009cb1fe7ff226f260254c92c7445ac82864b1d8b3d68cbbe3f737ff3eb430f866ea477c86bac3cbcfdef376a5cb7a61b0000000000000000000000000000000001da64626e5f09f557d549c6fa18658c32e0ca5e3f9ba30c2a72d123dbd330c461e36b13d1981730555a4013e5ec9872000000000000000000000000000000001314255857ff6c86ca352ccbcfee3394948b5f7309490faa1fac5c2bf6fbb101b1aa52fb199c3624e011f51b1559fe5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089c63742e437c35c1e488d348f97a20093f198b24dc63c60e8208f0ab73707c10a50b978625194cfd96154e4155450c000000000000000000000000000000001950a8334833ae9cb665f9d712211361cdcdf3d6d7d5d1bff40491054a9aec3decb74aa2b8a6bb11cc23a26c885fd5100000000000000000000000000000000011c971ae8838eae20977ba58cc71ce35fcdf1ad5249d59fcf4bb0b2ce9c050546f9940b3be3bbcb10b37282aee55cb1a00000000000000000000000000000000070739f8dd0c9293ee70511fafd06b0b1ab6b779e8a486ee28a2fa7bb104524b36009beb83bfbaa791bfd615d28f41441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116ab95547ba5acafc6ca254f60391ab04e07c2e125f19da6421051bbb856336c077012eaf8cc03e4bda9b1826c5a5a10000000000000000000000000000000006121937ed728a1f86892a1e66ab589b0d0dab4d0ee53cdd24ff7635af48fb3dd16ebda2efad7982d0bf24cfd9777c8e000000000000000000000000000000000f1a522dc55ebe5297d5d8ba7c4f331134a88347e88dc6eeb7e1abc483b8d638a06bb6550949f87a5c36cdba12f545e80000000000000000000000000000000008e1f0126ae8a2c81b5ff881af612b08e1289bbe1c505a32baf050654d819c951b31c5272c6aeaf7d6b59ff657d2400d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f2cea33c7258b6a6c2b92fe4fb9d49c361f57474528b544b0b3386d499f8f04a4b8b9302497a3899a8054b96ea30e800000000000000000000000000000000013c1e885e8f8caa56658eb118917e4503d30ff6929a2a90818a8006136b4eacd51c8c5d149826f7f2a59f18ec0638270000000000000000000000000000000009563a36d6f545068ebc9e774740773b41f5847858681542d85e036766593e6994f4d83d5574bf54d9a90a945d0117af000000000000000000000000000000000a127553c8b9cece8c5da1dc5731c929928a2f3865e9b8129a864b94972683e2ae3115c2556b011e6b14f76eeac059011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ce4439a5a3e73b8062f1800f3bcaab8bc848a7f6c246a53c94cc3e8c858c2659aca97b27629c74d5ee021c703e0c04000000000000000000000000000000000798c9ce0c5fedc8e5d07bc57e2086dd7a676a6545d012d169c4adbe63ecf971ddec797433cb642651d1804bd3251a460000000000000000000000000000000012925519e680293ca5d1f71aacdfc17040b2fe3a0bc1915a0adfd08019d3d0da6282f3b00e5ccb06cf85170a2c16cb480000000000000000000000000000000007f7e7e47e383491531aaa75a53192aeb8af70eb66d350c192874e4f465fffd9cca75574565f229783252f906797c7bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012316d6d49caaea2882c24a8c78cf9a22d977ae12f6e0c4b2cf2a933c4a897c11db5efa96549a4acc72b3c5f063779d6000000000000000000000000000000000f414870002a26f28549e553a7add1ed4b79fa4c6663ad4c70e9de519428d4bf41fcca9ffa496eba537fe28fe15934850000000000000000000000000000000017c26fb4f0cb9a9d412c515138c4553987dae310868bcc7c25fbca30654f212bb3fd123a384555267295de5dd84d95b0000000000000000000000000000000000d3398a0fb0198ed55e03bd61b3f7301b1909cabb8fcaf7b404fa54774b381c23c5059b39af80752e8ddf7001f3496fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043ac5cb452da2695b6d08572e6738a8cfda5ddd184231d3286b4acc718de4ac2bb748c40d29becb036a623c93064d18000000000000000000000000000000000af3762625ad743c414178536423c15e996169f71122eaf690ce3990f73c42efcccbde7cc90a209dee9f8e99e338b21f0000000000000000000000000000000019742a8a34e1125671f22f1aebde90babe31bf26b1ea30e36b063d3e31fa6aa53e001c4b5dd0630d3461b273e0e592000000000000000000000000000000000016aa2313839ebe9f55dde430caa75faa2f6f51435fdefe0a531beee998cfd8198743b51da99a94de5213d3f0f7895bc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e0abdbdd5e64a72fbf326bfe327e265aca2d364844e843dd287e33773619067b8fff7278ea245eb14d53627f4300440000000000000000000000000000000012d3296a683f5a1538f7a06e5873bcd36d5d08414aa6c89e6c564eb6e3db1030b96ad9bb3fcc3948cacca8e652a5f7d6000000000000000000000000000000000c228610f01444ef881ea0fbc6d0f1205739fcdfac84e482edc4a1697948b1d93244d3eba901ce0ee7216f11543296490000000000000000000000000000000006990578246c1f863cae375cdecc2c41dfa2313490fa067596ccc17c169c1a7ab73b2b83b0d9a5b2fc63bd1842adfc471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000267823cd27b618ec291a456c297f7b91d5eceaeb97022461d5044125e8b82040526bbb5566b5fcd3c9afd756743b9a3000000000000000000000000000000001612be2213706a572d3d764fa06d02097086b2ad9b97a3c351bf8f06bf58a9198109036a43776d4ae49b33c1ff2f04a80000000000000000000000000000000009f15ab9963ba0292338358bceb43d5e58f14482cec904d5afddda501e1d2a7097d05ba14e6e2525c674caa58d48e19a0000000000000000000000000000000008cde8d2d376109aecea0a54383a6e8cd2aac7e5f97a5e0c5d8bf3b5aef888368523fddef2ab8b683c28c473c1b141a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be2a8c20f7e6129f754d6ced6937a491ae518b66c5240a135bb0716e09885cec8acf75117773f8c4e9c125d442dde5c000000000000000000000000000000001990455c88707b2800bf0269c15e78e0e03eec5aa283c6fa1c33cbced3cd6fc0894c3df8b7b0d1bdbdee26286d7fd25a000000000000000000000000000000000811d13d4565cca06de405060d6ea376b92657e9fecc34d751d5453d43af8dfaabce7dffb6a1105c85a19e468d3baba900000000000000000000000000000000012866d7eb581dd6bbec503da9631cc806988c5390e6c5ede4df734c161522425ef8a27cf8324c66fd95f83c8a18605a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f34c85fef6703c6eed85b0022cd1c28b46cefdae09c6ae72a5e0ef8cf3a1a896c6647e325138ff28cc83df999a2641c00000000000000000000000000000000070def530da20bf86e3544ddcdc5920dc01a5ccfecc284b1c7615c978fbf205302d294b8a026f11e8f543cdbf34fd9510000000000000000000000000000000019c765bc6acf3aa2578bc2b3a4a4f5aad4d63175bae3e420a843aed5c6d5ee00856d0b445207ef72f6e94ea11aaebab9000000000000000000000000000000000ca589249a7199676d285573f76a11f1c40fdc0d7e6ca0e5f90826240c50aafce26420efc382d43b8e5d4da2398f739b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e3993148f2064c37248e728bda7f952ed43d7ebb92f0b29c8a298f5d6e6bae46b569ac5f56a716e231f337819cbdcb0000000000000000000000000000000007304e4df5f33f8b3bdf7d396b39535339a8e62cc0fe431492d8bfef549b6e7e18b3b73865eeec09eb774c05a9848d670000000000000000000000000000000004bdfc6b979a2ccb35752715d371b985a5db897aec87facdb28013d587116b91b0a3dc0e63af12a9102134bee588e38d0000000000000000000000000000000004d930e1d20bcd2012bf9d772424fd831b54a18a2e49c2db1ba5afa02cf69f68e3c6c42eac23383647b843830819412d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000242fc169e84cb04d36a7e7f0647cc3303ebc9b4a4848d046c5260a1fa4de8e92c00f43f9f60cb31468b6fa0c0701e7a000000000000000000000000000000001667a670ddc17b2b7ee9777840918ca30e420302b80455d583509fb8a32d80512bd24190eddef23e8d1f3cfbe04c881b00000000000000000000000000000000174ebaf4ea24dbd6ecd32e86d517d856b66b42f5847326003034f0cb7988cb3641a69344a0d3c8f9e0fdc72b4c9975b600000000000000000000000000000000052d2a9fb05a5a45e9870baa27e05fd7a31e6760b5464f4b64612ac784f8a603dc06278abd9ec9a7b2d9e859c3196af31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ef5dddcdb430726be669f2e6a0badfa1ebc1145624b74ecc544f445774b7af0b2197578116c3cb7097aa0c3d8018a70000000000000000000000000000000005c8333caa2083ced238db58d344ce14046629ac2a683164cd7ec585a1f1d565541a0ff5a8975a85a23a4626fc6d4b9300000000000000000000000000000000067af59ddc23c700d05aee23f6f692af78f6c9d59a92bb58cc9cddb66411061a31f189000e6a66179149df44dd8e1fe200000000000000000000000000000000025b7ee79b9ad300a0944bbe0963460d43b95b8d7a300ba200154262a485839ec0f42a46d2d47210872846f812f5f8ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157e35ab210bd0eed8c13520e205de4673c1ccfdfa46388ce0e5aac2172d5adcf6f55f571ae78aa212ac278f10a5c2aa000000000000000000000000000000000f4e318a625c6ff74c0c95baef5e8f3214b87ac509558f89ed9d76364695e8bd7a1f6eea701af793e71038cc49042c780000000000000000000000000000000008b65e0b6fa3e54c6e204e5ef5696da3d7e62d98a108a6d92a39440329a6dc4f6fd0308cd08c1101ffe5e27526023ed6000000000000000000000000000000000f901478846e605a4cc3c34b83223a31f172b40e8d3dc6c33c5b114cdb75e19300c31ac8c0ae0fdd9f399375fa2996d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fb0b48c001ae1a5054a8284cac0673989eb10146c463c9cda9a58e36c6c36670e7479d13bb20200ee68b52b3eca73a000000000000000000000000000000001417c52dbf9378c549bd127bc113e64aa725b062e065b4abbe7ee0dc2e0ba766cd49a8d3564f9f46fc65f473ab5e85390000000000000000000000000000000002d96ea029f8cc461bc16c940a704b18f61b6abb83738d340dfd1ce90dfbcf78dcd9af4c084acc060d7a4f54a964b9ae0000000000000000000000000000000000ffcf296dcbbbc8ab3a907c344941beca1bc9f12a14843aeb5dba12210fb1afc83a12cb20779ff9c2706147a239f29f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010968e0ee59c1b362a24b741fa24e94f526315dcdeb34a118ba06a4cd82711b52fe43c9572703d036e262b55629f8626000000000000000000000000000000000f68f4bef24c33a3cf8bf67deb956aff0dfc163f23ae1f77d73d7db92ab0bd5871afd82c2fc855286df81290d6f0f502000000000000000000000000000000000e84300e64a874ec275c51065ff443a1d0c571b8cde6ea6b64860ab838a050106782454d87aeb70b526bfb3b2ffab5f500000000000000000000000000000000031f2ba1b9d67f219f7b3ca567ffe170b720018b8dc84a76f74a5b7474239d7ae2ce7d45e2ceee09282c9ecfa1bd6b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c24690ceafe25f82ffa628e29a050afa29656c128470a32cbde5f65211bbcfee20205b619a6eeeef4423d859d316008000000000000000000000000000000000f96c850ac8389f1a29ab55485294eea0276112760d4104bc88c7a11e3acca4a55366f55eb4f49585ba18fe9d8c8826c0000000000000000000000000000000017029ca22f428b264fa8c4465ffa11b7ace32019a530b993a964a6101c0fa19567b7efce1549cda5a865ad512c8b5221000000000000000000000000000000001421d2c88aa5cce47dc38ae8e38066a7c8d53f14fa635933059ca45cb7d898f620c69fe58ec2d35ca9736f3b363d1a041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f53a77c7ec5336021349ac04e27db1c514655111f7673fdef9e7f7882e5bb4859a9bf127d600504e5d8beeabce70800000000000000000000000000000000006a4dcad66bb727229b7ba7a40de1794f161df8a6c7181f80cf06b207d4b54174ca4a99b3028b0fd13c9a05f8c6e7b1d00000000000000000000000000000000146586fcd94aab0e00f8ab00a3775b08944cf949e5b80aa711278aa75a039ac8273879578f5be5d6ab37902d2b648276000000000000000000000000000000000b67a5497ea182c4bdc9813be7da5691d1833e91b680ac8e2d99111ab9907e58718b6527ae9e15b7f2e05db22c90cca71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001153783fafd87fe55dbd9734ef2971c49d6a5bf199e68d0bbeb7c2a482bc1d69d638e7e53f8877de2a17fe16e8cc44a00000000000000000000000000000000196cf7ca552109f9b83febcefb2e5c16d6595714056c3fe96bdc9b987268228373c92f54607ec7b73f6978a9ce65c8e40000000000000000000000000000000010aee1938c5f8feb5e50059b9e0fbe32949ad5378054d9f4e4d6ff3223fffdab7f0c744eba63ca5ddcb2716bef1ac91300000000000000000000000000000000138612ec55272e09b7f56c5335684a37caaa5dbbd5b72d4b6bb2487a2621eb779b207bfb662b000c1e1a561d67532b691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000329c1947188b8489824ea0f5c1378c18d2f070206f49855bbcb45e29ff36e1663d9aeb9bddddb0630c9edd43cc41cce00000000000000000000000000000000108c0e7e2cb636ee2b740fe2fcc10f2849dafb872149de4bcf53e98ba7c87fe8391125604c65d9ef5ee33e1dc91cada900000000000000000000000000000000012124fe2eed509f4786a2ce495349f5f03f97bdb58afc112df7f0e2f6ccb46f0739890d4365ff03ec0160548f1ca244000000000000000000000000000000001442e3707d740b9d92b75e70c875f452ce23db0dce240dfaa1cb874ed1ecab568b58343132b52928ede6c1c79e17d4801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015948d862549badd0e40eeb5ca5f51146e0234c02173cda657787093c720a4593970db877f877ecd5c542ac339a76930000000000000000000000000000000000a1449583f2d6f22918f4675158c7913b8b1c37ac2eb0af071a6105c39e96a89cf2681927d306d33641795939f11b78300000000000000000000000000000000009668789e4d6fedb2118cb0954f25680bf50765b17885fd9ecbb475b1490014e65f780df5ff6edde95b4db0ac67dc770000000000000000000000000000000013309b383281f20a4a00c324e13fadcfd5b073ea21636db221b454e8e36e35476e9d47204cffd5bb210b46c8590837a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2e72917e4d76b643814028db457a6bb26f6ba49e8bd5a92943e9a928d043b5e7ae83efe2ebcb214f57e3e2a45d558d000000000000000000000000000000000e15a41346a7e5ba538223d91ffe1930765e5779f14ffa74c545b755d827ecd47766664d968176a3fcc42cee399515a100000000000000000000000000000000131c324e7da3b1d1798a9948cdce2846100e093d23d24d4d430b268aa4dca4726194fccf5bd5ffcffb81b9b2ec19eb4f0000000000000000000000000000000010a30201e0cea6a71b17071081a92e51149841ab6b5410de881ac9d14082d6403e772acb91d9b780463556fbd4a0ef231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca9901b40bbd52c153a20561e7a59e4f155fed3a8efb808299879c495201da88a1cd62eac95f28a174df0545f5b1d500000000000000000000000000000000019ff86e033b9ce9131630c788254c5b8aa19edd640781211b5353d513f269e79065a411efd01bf88b23644fb459db0320000000000000000000000000000000018fd8e920ebbc8ec615274aafc5c12424cc62ca4672ff6cebfdfdea3704f7247a82b9575a9461bc9373ac38bc2686bd900000000000000000000000000000000095763c5e23fe263deae9df9cd30926eb10bd6a644feb3a59ca4d636586ddecbfa5c7a6e50092ae270069469737f33731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191f67fff1dffb867b63827ce6f06a51cba58e58a9645150dbe7000ed52b4dda922e6c5f25998e2b23e3d4ba2feb98ae000000000000000000000000000000000324e3d678b747ad15aed135d493662f774348caa40fb27222c758c99c1d088ae1a6b93a7229beccda308c1de4a9eb6c000000000000000000000000000000000e3cdd3505249f242b43649c77c27f8956846fccaedda21aa0f14bb335c21032563aa712d90ea2fd779e4c998b94b8a90000000000000000000000000000000009afcf38ed6916914ed4657d8f48f2d0aaceb1d0c697e6922865b7e6404c627af16175943139f2477cbdadc3276afc3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f595dd9e316be096971a6001084c1dbde3cf588eae80ceb5701f03a1469f3b09525d1ed4d849a335c2684546773bc030000000000000000000000000000000007843f62484bbafbd91bd933bd786b40bbe12078c72c9d9092c6a251646e4bdafb907edef6fe5b973e2d4b6a2aca649f000000000000000000000000000000000059d484d5bbd85869d1287dfa5655f89adeaa0d5607c573a32b71ba04808ae09ad117aa79763ceeb3d53c084af7e18200000000000000000000000000000000031a379a5fa709d08f1242d0645b0f1031318d7841121b2da4fc508e29b94bed0bdb792488cd4786017f5295a5e07fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001442e00a28a72d473cbe2b96ae2163b402a914bb1a91faf0739ea81c9a4d23924f1172f3b4be6bca27149bbbed73dfe90000000000000000000000000000000008600e6c370e296254d8986903cccabc27fd2828546b00e465a76cc5e77f8703fabff82b5489e88c02e62cb4b39479a500000000000000000000000000000000194c681a57a7fb54c0e8582a077cddfdd02dae579f67df50a569e27e415075f634dfc20b303618ab57f1d11e20feb93a00000000000000000000000000000000194d3df350e3f9487c82006d817c3a16a4d115e688d74aebe388ab40161142eaa6b3ae0e6c07b94f8ce216cbbfde16de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002814f72e642d4685ff1c6dd64a0d70e151a9e05dbc95e12d811347ba502fc0d90ab9cc9f7f1efe9c577b7abe32455eb0000000000000000000000000000000019b5ec11adb99977a43cb05981160ea8d1041f58bee93053f71730149762f5ed8abb5b43074c088c0c642f8d8b7a0c8f00000000000000000000000000000000022e208c8eb857b6b1dac105dbba0350ad79f117d3d6e9ca75ac758e8cf76b475c28c556c1e4d582c8ab23f526a9f3950000000000000000000000000000000002d7750fab5a52ca3ba2c11d3452044971da4d6faa188cb4731e29f83d48b5e7ede94c745e3ab1fff9b54c726018bf051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020e0d4b96689f0158f821cb605befa719b61c775c9a661de6e12b69113a50d53705d1ca9ed1f22a8226714e353433ce0000000000000000000000000000000007c0df3ebfe031b3608d7789bc4b6975e01e33b9b11effcc705f644266ebaeec5c92bc58fd9c1d0a282de7232d364e6c000000000000000000000000000000000f8db63c165fa90453e715a9648750d3748175a6e1d4ff9d4c105811b365cf9886f1b029e9300bc98089fe402b78004c000000000000000000000000000000000d60892d63f1ca7e5da3c7bc160b02104bb5d5ec69623838a2023b72578a63aaf1bb957610b18e9938cf751067ff39791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ead9d57626068c975272098b448e7fa5745ee3a2faa8bc183216efd7f8fa66e8c740b467452752e0f1a79899f41112000000000000000000000000000000000385aedacd1f2f59381abf8c9ab16bcc75d7c79619c1eb42ac8d2eae440f68257cb00be2204a6ffce537255bb2a8f942000000000000000000000000000000000c82dece8246753103a61b5b0b121108dc6e769a2bc04116ac832a7c29d5588495c267e1d222ce74cd178a77eaeecd520000000000000000000000000000000003984b273d4e408aea4ba03beae21741d5c2ad58258b317e8b7478835c06c0778d1317b226e007a704724e55a8f91aae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f7f16d32cfb19da9ebb5ae2b1f514127e9e9c654ff9d13874c21eaa905745d0bb5ade1818942aa5e04f5fb4a4f6c4d000000000000000000000000000000001788aa04aeea9c873a866844af2ed7f8120da6d4e1314aca6d0365bc277d6a077edbfe3665bd73f57402dd0ee88914cc000000000000000000000000000000000a2dab50f75ee3d5a966f34fe56c8b92678f82a3f511021d5e2dbe8a8acf2d00a8d0d6f7a2033d35ad2fd95412db91f5000000000000000000000000000000000e450139e665e2ce43c8c40a5177a01314a8a292348290712dbecd4024eae2c0c5c4456a90f1b375667b856da821938c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000887a101d3d660853ae6fa29cf457275c2abde75594011a4af48eece1b2ce4d5bdb514be848378f01a73529ca7bda26c0000000000000000000000000000000001a533d895a1a85b987617d82fbc7bf394db327010823ff0f46b0b29464f84e7075184a7602faa5fc67f08d199e3ba1700000000000000000000000000000000149bb4d5dc254c2e306668c1dbeed236453c639c6111b2fad74b091d71c4dd1540aca0ac627a9c36ffa2705cb680e1060000000000000000000000000000000001fe611266ce8487168d333f1b7a0a7f19a1f27b47223722b8fa82a5fb893570a064ba1f5f5cc3dbbdc1a3a3581add481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001144389b54016f1eec4bcf885419b761847e9fd0f7c9b2a51a9cdc9f5fb9a0f91deea363cc1f3e72a58030f13510a53100000000000000000000000000000000174626c2a9e57ff41d0d1f1c53318bc482ccbe5a20845a15e5d77fe297ba9dedad0e52fb8a8a18de1d2e266da8b6ca4e00000000000000000000000000000000127c41fbe226a80693089a7695a4ee15fd22137423942e8ac4493a7b9604c1e7b56e39c555703d79d71d7de65955e1c10000000000000000000000000000000019007acbcbf82ae868a40cb3f477679a72a29de03c7645b338114627d37d437b1bbff5edabb2a1a8278f5dbc4f78eb871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085d31562b95d636ab26951234926587929c227b9c16d789d1cf939ad1fccfb67b67af86466c43d95518e1245c7bdc9000000000000000000000000000000000062c5860a7efb9434b157d43e692ccac31211e0e0f03df1939977b80566023ee683f275f41043016ae4e2eb0995fc0510000000000000000000000000000000002c81a07054bde110e3ddaf74aa84d807ba273857d3945e394a0a8524f6f3bdd2e3e51db026e08fc3c6b7d84b48fd615000000000000000000000000000000000661700c906eec4773c7cd6cef267658be7f57c68ea2f44b30474d9f2e893db62c4f7ef3214b64a54e852a86ab0e36841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000489b397c308ad508ea1dab14f19f5c11ed38f76617173a1250362c5f41f9abb3d61727c417dc82f22c6b678b5202ea1000000000000000000000000000000000705601673c330a65a4b516c74141d118c43e7f8374351e3f22a6174de161a259dce88c42803caffedf5665beb8239da000000000000000000000000000000000f5543d20e1d06e44d94451bf8e47a274d82a2fffb6c4ebdcd0cb552a588e795930ce3df97dcf3211c2cf79f1bcb64c80000000000000000000000000000000018d5322817b6a780d0fc37e0e2db3085f725b7aa4e64d20b4f1b40feb940bac7401caae0c80f6221df9ae845aca0493b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc07ed168751006e9671613bc92a9adefebbe67936c0bb5e863fd177f284783077234bd26784d938f95b9cf4b7846db0000000000000000000000000000000008e7b5c1d9e23e2938660066a0f6eed6464b63757425f5c75d123990914c3f909a7cc52f4ed2091480cfa307b0888e3000000000000000000000000000000000134fda55c47b0815597f7f6c101a739d14e299269972ca88f0a0cdfccdd9167b8368a967ef834dbbc5626c41eacdfbe30000000000000000000000000000000005055e22f95145e63aec9f495651f2e360e1ff4d4baa6c7ba4986f336bd02494e65b2f90dcdb616adcb9ab55f862910b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c32b1f49f0573786182a7b3b581c05e55e25f635a216dea33e887158bedb1ee9c4a770aa46314e7ac7b16e6f075ab3000000000000000000000000000000000e5bbf443aac540ab66a86db25c1d05a6e5cb34fbf5cb347965f4d00b1282b87759dbd2955a937a9f67e92f252c35ca60000000000000000000000000000000012b0eb95ce6da766d99393d9f01e01c339022798ea994be45fcd32d8c96e59b14eea6a5a0d5fdf1c94175297fc050189000000000000000000000000000000000778c349d6b1e2ae0f9737821f3be215ba7168cfccc4a83511bccf5bc4f7ae1f2b95c3f9d382491b35a35113f0a8624b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016659d4a5b0d35cf40d35b1e1aaaf04dbf930408f3e054981beb976f0471d7a859e8ff3250877f1bee27e7e906aeb6ff00000000000000000000000000000000056593fcba8a5fdbcda31fa732b81930405b9e34bceee6f83162521761721922e5231724a687deaf2ab5e7ef6abb90c700000000000000000000000000000000189ec6018b5bfb2d5d09b7b307242fc029f34c60e30a4372ccc521524c4c18d5745edd4adc291c5f5ff8adf1d7c745ea0000000000000000000000000000000019228f66fa6bee5ebf1236462e141e4e1b08bbc07a188631c379a571cf5f3b086c7d7e174bcf93f3fc7eedd472c179e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c66addace5e99961bef8f026128719cbe2c58428cdd463898c82de33cf1cdd96fb83d790f2632d5f5e6e0f914debfca0000000000000000000000000000000013c348be0db111dd02dde7bca4e1702c52db76b376e466474b184cb68e91dae08e871c18dc09a793305e3538a30ca7190000000000000000000000000000000007cf33d4e36c92c130bb59fb5087afe5b83c404593dee3c2dd22df20524adaca37612c25eb2e256e2e2e1dcb118704e0000000000000000000000000000000000eb15a38483152dd3c3ec96d27ad8d07356a3f34fe128b34251aefaaf3e9523b14ebe0b6364800330b7a1996c02139dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e8946781d7f4d74b6ca034d57654b996b006660ceca6553313dc5d2b3eacafb9952415eb675089586d43b9adb752be00000000000000000000000000000000035893eca04bd3c5530f878df48482eab6191f67ff41062444379a32e7b68ea4cb60236a4e16ba4ac2b900e93f1591d70000000000000000000000000000000003987238cb5d2eca10dce7d2d70442199c4af82879b22742a4f70b68b47cc6317170804141efee75ca926d709061a794000000000000000000000000000000000fdf0d4de1417bae9e2cd2b14f90cf82d290cb9278e539273cd846698d8f2ef16efcaff9a0068d6fb4c707acbd19e7841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6b896705cd53a1bb031ca0ac7e3e82221460f33b1557f2449b77e60d28288aef47b81cb1be40dc2112d20651c9c83600000000000000000000000000000000018d336b112e486fc054aa67cd7bbd770d364d834ca1f1fab9ab63e3d2bfd964c53ecbbd2a8cda89779ec5dfe8d8cdae000000000000000000000000000000001104fd8a9a6878b2d0d22adfa6cf14c04bb784223b1aeeff2bc8eb280bce00bfd8c3658bd6305478c52c908b07a41d3b000000000000000000000000000000000b601b3d81a2661173202aad276e821adbba2f1746b465ad0531e017845745d2b3f1f972121b6a13dd607bcefdef44d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cbbeefaea065c55cd84a66de3243b63bbb88b3bcc95194106f42de49cc5774f314d7450c124d654179e771d81724fb000000000000000000000000000000000b0d7d72ee4782ce83064a533ac365edbc9c1214b6ca56a63a484ee35ddeed07f23f0d86f9ba7b9527421ed96961517400000000000000000000000000000000103847d5071512e338773f733430e274881fd2cbc48de91ef4abc3f6549c506acd8f059bfacf602dbd1b316a9d4464bf0000000000000000000000000000000003cc61f71aabfe1e2c135d9508d1d2b557566334f425d139f7a6d5ef556d06f60c566b40a07bf50ae095d8333ab0d5c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001661f515380234c0a59442d7c010ae3d1a1b1035cdbf2b7234153820cf9a92e3311268e51d5db16369a24363927147490000000000000000000000000000000009e8e735f51dc89e2bb06b2c2468dd53ecd58e8c2d0a5d3859a5f289277fd71e72e7f150bb3ef7ea55a42b5838a5cc17000000000000000000000000000000001030aff60617eb181f372b69ad3d1ea53a55bf4de8a1ccf6871bbc940c0e5ff7981ae1637aeaebcea5071e17c287ee0d00000000000000000000000000000000007c2d148dcd7fa902bb932c40ce6f1c92f88fbcb5e224d99f583ededb1805364e410699993039d38624d7aa1cf9a6331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db79512d8fd8fe4e7eff11b1ec883a40e740a4b08bf7ebebdc31c7cf21f62eea0b9ddb9320ee41b0c8a50a5d162d7750000000000000000000000000000000009962899d2cf55ff1072a150cd8065c1b5d37fe68e79ff4956a18ed1f55d48d48832c7c70cdd0ab481887a62c7a95e390000000000000000000000000000000003a7542b146cb58dd4eee5166f85c64fe0353fc3acfeab029cee0650a9ae292937220c083a3ce45564c8e5d5d4c730a20000000000000000000000000000000002251ce77b5c4b6e7c503fc0b1418be383bdb4002a68d1caff22ac1ff68c612ed722923c0c8f4ea6f8136fe2a64768ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000731ec3415f253a7bc0f86a9564f760eb7dbb11491b6e6690d230724cbb3046c75d29041c5e62f3942cb98d42750c90b0000000000000000000000000000000012ee823a7e4463f78e33599051cdfa85cff07e96009da46ef3989dbeca49ca125408ce8391245477b0cd5eb5d3c839d3000000000000000000000000000000000ab3c2c6f65656cedaa740eb99ee386cba7dc37f8ad63e4a9a9485591b6e49d8fbf3a5a3802a40408fd1c5ec41d3c98d000000000000000000000000000000000b2990209540ab2156920e52b6f93893377373c16acbe21677ddaca425334f6dcdfc614f533afec45d3767eaf0cd1f4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049646b7eccff3349dc143aada88a2fffb1fd84f8c2e80b87aa882d30789fa145c2573d4acb1735f5e70bf05949b30110000000000000000000000000000000005aeaf963ab3e5623b7de4854559e9778edef9a6f53e3493910bcb5dfbedc8a982bdf55b2b0dbd5a7f2131c2b1ff8eec0000000000000000000000000000000009727bff147cae9bc010b70710f1cb7d31ce8e55410c7ff2e650919ca2435d54d1eec8deeca4eb9cee68f2e4f0fb962c0000000000000000000000000000000007700b87a79f84d77b79f1c297b0decd16d012e45d976d50bbe39728ffba94a687f86a61f5eb79e2ea66fee3e8304f431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7b7b6045249f57034eef7aa38ac269d8494373ce19e3790fdd0f780343707c472191ec0b9401ddf21af84ae42cae1a000000000000000000000000000000000d47983a09d102d71fdbf9e02eeaf515973422f4c7ce6dcacbc25250ab1cd8baa5b6acbe863db83ac090dc84d68763640000000000000000000000000000000011c0cd9c08ba860ee12e7a247d6feec77d13658a3cb43ed0ab2eafb713160962e1c2c9aa83a10b11620ca505c936e0e00000000000000000000000000000000015c802a6ee6c88bcdf486514b2762df039a9b6b3d7c30d1cd26a5f7ed794d2c6b4a2ee46045ca90b00d21992bafe8d981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115ea66480d6a1baf6894dad0a7dcdea4a2e83232b2e14daadb6ad79bd8ccc4f9ff946a39f9c709f036349fb4036c5ea00000000000000000000000000000000017e21ff69229b1a0f0f91bbeaf72dfc81fd8577ce044072d355adda4bc041d76e4e140fd7dfeb9b97560b9859cfe65b000000000000000000000000000000001238a9360954c5fdaff8ab0041566be11edf76acc5226946024d41dedfefd0c524d51caeb53c296b3749fb0df7b64ffb00000000000000000000000000000000109b068db4330ef999bdfef98488f89e8ec038e5e6f536812b8f30a1896c292c6f18de97ab383ad7433b7dfac36404961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a639365357db31fdef35065c3b032e6417f15d7452e7514be10c39360d75344943e1440c2b54e8acf3c16ab11dadd50000000000000000000000000000000005041849f2d6ea6e3e440658bc07891045b5e9ef4987d44a375f955e30b3abfbac55eaa36ea81be8bfcb1cb98f3230d6000000000000000000000000000000000bc2624037db36737824be7805b7e8dc4cbbe495497a48645007afdf68192e8c617de259268d7babdba8ad5c25c8272400000000000000000000000000000000193db7076e86563fab664acfe31aa963dbdb30f07d252f22580c88a9261ba9ac2890d852949294e0cd6853b060685ee11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000396b5832a0978ea80d727857d243ae6424d61f0ae505bda880aadd22f0f1cdf6fbfaf19beeb16d3e1c62a35ff700b6c00000000000000000000000000000000056ce2ef08387c754c2dcd7919ec36e06cf2142392b2c8226af3a1f454a088e035fd4a37ad7b7b48a7372f85906416240000000000000000000000000000000016369dcca2839130df1551e596520e06a4bac33bd769509f45905c7f44ef76c9a3c0100110f5386017cfa2aec49deaa1000000000000000000000000000000000be654adc5e8ef82bb5ab25e8b1ff1fb2b564fd4b50c965fecc02c301e3e7aba58df1ef72c23d9e03dc639d973ef243a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151acbfa2c8783979960cf61e509641c8fd1836900310a10f0d691cc09030f6baea22f6f153a69b3b5aba1d0f1a93c8a0000000000000000000000000000000000894e002072999e0ca7ede8c726f4c75cc6b82a31bca1740540fffc0e17327f2e642e2135c9f89da8ff740d803fb6470000000000000000000000000000000012be8168df1aa225e871256383297e9cdff6127bfbe92a042fab85c17c5599398b1f53a1108108caf2dc73e930d3a22b0000000000000000000000000000000002a565209a5908151c30af8dcda0b5934d2db6fb37e483c11dd787fbd224192d8cd10b571cc928ee6d616aee8f8782a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d47d5c3369d1e62fcf47d71c811861a5b70345b2becc5787b3e3030abe72295626882e5c9754b95b76fbc213249810000000000000000000000000000000019763951a0f9ac885008cfab44f7825ced5847dd38ab656d6d89ff547b52a69698a577eda8cb610959be3b73775f0d5b00000000000000000000000000000000126d7bf11d1ad4c15f55fcdc340a5c0f2ff945aeb1bc783d6f4bbbf6603e5285630a7d0f34d990b4a6b07cf102b17b8500000000000000000000000000000000029b3e43c9054e0b1653e9fccd4d9a5d96b2e5a7b2504fad8ded8120ef5ba0569c4c79a1138a535f9a851aff6c2204d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157f47295f13df2d2627e6869b7cf056768b9426e8ccae7083bf2ca4a5a10b45b09f741637dab12a60c1de3a85ca0a2e0000000000000000000000000000000008782be2f156ebb382d305ab028ee9cc28976b8f9bb9e07ec91b975c7f0b39ce413b857a5741906892c26f8b4eb0423e0000000000000000000000000000000008c8d45ba88eee71a845c19dbcc97c9b261e9e13937579169fca22c1d9be48e413f7c9b4d38505316a868a027109958d000000000000000000000000000000000f24bcb062e33b2b898e9cfdbd20d7cb7177b868a69fa2ab829f310053bac913059171f56bbba2d4ad6216cc0cd81bef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084698bd604896a0cd2e0eebd4e382e167a6373de1253e546702bd000db04df8117f53abe1ae7344201eb3350bccfe570000000000000000000000000000000018bf63cb594d35e52efa26526fcd2ace057c8d3ff4b969678ebbad585d519532b0ea6b74e165aeb46a1b5867e39ca290000000000000000000000000000000000b2fa9c1340898f1c55c3b67328ee3b533e3f7a052f52a3bd4fc83bcaf12e15c7f216941daa312f653b0d35d86297ac1000000000000000000000000000000000dbc5748707d709d13c78a7b50d5ac5c842fdd8a63d07b9e3e86d0e2fe5ab4b643cabff581e0a54f6bc21eb3c5c98a041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102b7cc4aa54f08da7fdf99d027606114a1e6ca0776be7c3357de89c0c0aebfab12cf8767ed6e16760fc9d5dabb542230000000000000000000000000000000009ec268661082a56ce7149534dbf3027a0fe09e503183e96dc185acc93cfbdf407becf9e14e771d0bebe0dd5a42e733a000000000000000000000000000000000ad4e3af58aa2e2946ca41aedba984ba8d7f09cb667eba750e9052a3f57c62d93eb0392dffcb56f90b71e98d20163ee000000000000000000000000000000000038591cc8ae93647176a0ae5cc915ac98ebd1c9a442497168763217bff127bd12a55383a2458c1512599312187c0b5fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a6938f5c8440af210a5036b70aeb72b522a57fc800960ece6e501b84a6116239ba7bbf26c2eabbe447170f1e07127400000000000000000000000000000000149bee97d410f0c4b0d067fc66d83771758e31daacabb2d5ce812dcf2a9383a44693b86b1904cec13bd7b69b6fb1c90a00000000000000000000000000000000170b96e381c3c2f9c47ef9135541916795dc79d62b27489b0963f1da673a889e6d15ccfe8e04cf5bfb7ed10ac2b2fa8b0000000000000000000000000000000011fa0355ab6533c491c5fdb126ac9e0f8caaba2c0df9675b14e4d6f681894580dec59e00bca329df8db20f7efc7e19491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001254893cfa1222e898107687c9ea1d456d871933a486e72587a57afe42d4c7d643934a58e15b8dde13b181b4002431ee000000000000000000000000000000000f93889fcad428b2d587855e449ae811b6ebf78fac045304507d26c876514a6d5aa716f568606c3b0352e5c9d556cda4000000000000000000000000000000000c862a99c63cc4f730e364806a6caa7462d63376e6de3c9162e5765fc40456b2889ca3e530f3387b3e4c575099ae2ff1000000000000000000000000000000000ece604cd8c1cf5332695f93c06f8a3c0b9734ab3caed1f1f904e670605064b6c18d6c4e82da5e1378cf45f46214d2151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c47502c58488e45bae96614058688f60f75c93a3aadc2f2164183f16fc92bce8422217e99bff12f137905187fb37e73000000000000000000000000000000000818f48f961c2237d0500d09bc4ddd12e8989b277efc86b23fc418ea2e45de860e20d3bfea4fa36542d5dcc2fe81a26b000000000000000000000000000000000b59c3b766096df4e9aeb1aea7b6306c593b33a8fa69dfe6631a77715fb268e2d48f909e3ab0efc22a40b0def89a16a9000000000000000000000000000000000e3ff59260ef6120087cd3e6cbaece3a40f498be54e77ae8f90643e831fd521c861332d017b7150e3ce9b61b877794e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bcf01731aea813193f3f12e1fbaaccedb7c66ae7b589f168b7463e454e4af2c331bd4a3f4e429d0a2e5890190377730000000000000000000000000000000012f0d056d9879cefc792f0df1c1e28a6e41180eac7fc7d6406fd97149be577779bd37b6cacbc4721a37777b6e1187ee50000000000000000000000000000000004f34e4b494b21e9005d0911f85218b7fad7cf6cdb6809553e61bdaf920a54e68720534f9fc1196458f12d044fcdf6dc0000000000000000000000000000000002bc6ff2608d055860e191b3eb086692415d42a2aaac2c4fa6ddc20c9234eb81fcf2f96b22763de32641bce904eae8b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011120a58672595b8efe37faa92d7dd8c584ba7e35437e74d5a6055bf894978ee198345d7ab8aea8946d2c9a2f53a93a000000000000000000000000000000000175ddad501f60b4de06256295b581a94e3383df2a61994e5e95b87a38001efe0e20bdd74b5f206ef7e8686e4ecc98fbe0000000000000000000000000000000006e57d04f12204af70e29e72a78497c86242c852615656e090dbd11cf4f39aaa38d3b9fc022a7f74a64606700b9c585b0000000000000000000000000000000012a91cbce10734eda74784ab5eff42faa4a730a31e8710c8b0c0ba65856403a22ce556ee4d560c429e55ca2010b711da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e38434db2ae79b97486a521f10d89ade3c1e4122e403b4fd4f2bd6a8fa84d8480362b7463b3373ac336831a022d0b0000000000000000000000000000000001186d9310ef488484748ea7faf460cb04c951b041a2c3c9ac8c6f3293cea1d58780f82f9d7e579096afe7ed3293494ce0000000000000000000000000000000013bcb4243a8260e570bbfced687a1ceb858e7fc21313f186cb5480f12566870562c138843080bc063aa54694006291ec0000000000000000000000000000000006de05e8988cc16b3d367a341fc33f9ba2b7d900d45f09d23be924c3b18c0caac93b4a08086bffb94797f9172bd06dec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000420663488b35a491c7f50446e22a4da1371269d2da92715d0d5c6d2b4d93ba5d1c87410760790f1e21af7329e9ef06900000000000000000000000000000000139e3307f1e501bc20a2651effb35d68a015ba6114992a34a78072df2a4c6a04ab2d0d99bc7d613421ed944aba6f0fb7000000000000000000000000000000000faabb750ec4c63567307eebb95c60c81dd996cff14ee1ce3361948bbd404bf07983b564e6b7a46c1f5e95f912f521cd000000000000000000000000000000001272a4dce01b01a353fdd3a7d50e1bf8461e21b8860c8a0fe0b732db60c8843722dc5a895daafbd641893e749d9171d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c542021024ea92eb805168b2c4fa23c8d08eb5f7a498d4101766985f235d28231a35e753a9f173f0a200577338b935000000000000000000000000000000000caa5089b70dbe494ae28e68080f98c1deaa01a7167f72fa4adb4ddfc19396cca85a94a9c8fe46c85ede833b90657ed50000000000000000000000000000000014ae68c0f46636c233777459d18a686cf192722708e49077640ecfde8296ce5d816e599e272cebf3b0c71306f469e8380000000000000000000000000000000001054e3cb3910fa72eeca0c8bafcd72df30a0c70a2443bc90035d2e5ecd71ab1e04466b22b14b2518383373938136ca51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd9ca2adb79bde0d55e765febd705872570f46e9e544badb26b57e7be63fb261f25b678346203ceb0628fdc646233970000000000000000000000000000000018e0bda32d5d736522feec43d6f63c2e69a55a19d01eb7d192fccf7a9f90492fc8f1b06667576042e523d866630bcbe2000000000000000000000000000000000ea94b95b21f7fa3035aca5e5d5599ae5ed4a95888f69b551a4626f4ae712a7e3f2a5739e0f0087aba716f43826e38b00000000000000000000000000000000008a3964da6261688cce2137861fb084d5bdcaf3be5e41dd4121eac3ec3db8cec534e2d447a6eaa91f3b4eef8f1f2df521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a217e5b5edfd02f6f99a5f525416932f97cc808e6988d897d7ff1bdacdb034a3f6020873549e28925108da3932d05e500000000000000000000000000000000195c2f24022b05aa87eb8ec34c664af9bb27f79931b51ca690b8799070ae8a179b7de65e42a3811706a5467ed6dc800b00000000000000000000000000000000054fb9f5b95c2e685540b840c6ce5b143f80b755384eead683a5b05602e2f893c39410138af86fdc42267255fb55b0870000000000000000000000000000000008d30063022f4ce11e7349871a1fc8a82dc310fc96dc63f68f51f50be171c37e8efcd09c4e207e648746624038fd2d631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001219e002cf573ce860c209d5239a119275adef27766f8a80f71a174a4e3b8bc78c10c9f50f18b7ec05d20642c93bdf84000000000000000000000000000000000a731847d4ead262109a4b2da537f507c47cf8bd0d223f7961196a3768f14e17347d73cef5b095ca0cb3c9a297eadfa3000000000000000000000000000000000d862192b4ccc5f928b6b462b06e277aeadb9331a7b583c5a82c8dc9c0d4824eda570447ec1433c3b7c086455c3ed1970000000000000000000000000000000014a95b3999bb3cea421dc78d6f8d52c0322670dfa0e3d9f1d2477ff3918b94d86f7f7c5a5562a7b27c938dbc3a93b9bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004dc0cd7b46d37d091c30a0cbb48fd0e987560fa01bc0d8ffe33a425c5f0b4ce2e4be1ab954da8e005cbdf8735509560000000000000000000000000000000012aa8048d743daa19208a56224a8f833ba3bfe48d0ecbea51a7f8e577f13ca81e41fd8110108bf78b6e2f559721afe4f00000000000000000000000000000000041f51768940f4939808f6e3bdb703b9ef906dcfa6c3d8804ba315e1f979742f8876523fb34b4e39c3f43cc542b07b50000000000000000000000000000000001485722610e27dcd250d2888d86dbee47a3c19ffd00771899f497b85a75055d0f3e3fb55aba760874689d7f89dd24dd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001806068d9ce9371f8913b44cfa2eb0561c137d4e8fe75aa4f0724a82de02f6c4f3d4c56863f11d0ce9d897c6ec14c2150000000000000000000000000000000011891f4ceea81df9c4cd4c981bc8b9bede1308b814fdeb32a4cb46bb78c239999669cfc5277951ce8dc7b5e0e3015ba00000000000000000000000000000000014484c59785be3c0b3e2f39adb4bc58a3e050c88674c72ed8b70838c62e3f8fc069b71124cbd7325db5e2569d06aa163000000000000000000000000000000000b61153c4e58ea62a32ac0557c8aa3e1bc63acb30e62d48e1cfc2df2736fe65a3e9b77780a43081ebb987b35378073cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001596eb58fd2183ce3fbd12a453c2709e05ad578864bcf4319023a8d9130d1713f11d9d16d876cace8dcf85debd45b4c80000000000000000000000000000000019536767c164b10b490ded04d887e0f9abab3aa9e3ef41e943c6ae3c5cdcecc7c6f35a85bbc1c24c87bbce0917ecff9e0000000000000000000000000000000002d3561d12140f2a01ac12ed3266b4dfd91bdee8e4f2e5cf3244c46012ca778124ba966e0b5862309961396695f2ab8700000000000000000000000000000000049c4607dfe57d218c111c6a550ef05e6030dbc8f66a9bee77d2c2bacbe8795efdb8523f3d7efb277faac75086f329a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000034bf7bc3f17a83272eb2b78dcba1a1561371c0067c0906769e499d3f7163561e5871560329581bc633721fc82fcb9800000000000000000000000000000000198abc566c2b50647994cad427d64a6bbb03ecd6cce2ef503ec88159bcaf161346333099b58e7a8b174afa4aa33d9b20000000000000000000000000000000001561a63042f604486e1a8588a2aa1a021c0e971ff1ee39856a94a6d18fa0d9d1d0da19085bc5e0b1c7274ed2974091320000000000000000000000000000000010703d5ead1b741421abce2e23c090e2621c7c0fb8ccc2b1e7a20ce23af9f0bd93f89d4c8d6ad47945e3655610bc01421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ec67a203a192d981b8759b259425aff045fad249a769c0bec107745a199d31e1b4ba40d19c1208b1b532ae6d3b0cd80000000000000000000000000000000008334ed637b214f5f33c0359d6540405df12db5d707160d5bbf642256d94fc2301b6257619b8f8aca167757cfa4f24a10000000000000000000000000000000001fe8523ad82924a4143e12c03757ba53cb479a51ae427e79f91f0de469cd0fa8ce793505729706c6b4de49f43b3ccb8000000000000000000000000000000000abf6764c325e63b010f83c8de59fd3f0bc811b01ce43739015e3d352dac535f929b7ff0e6e2791f4590eadd10bbe04b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ed60136b65c5df608c4c5eb0e7f91ee80c0233642013e0e5302c4fe3298ecd821445cc60f9ba4e46701cea1b3981210000000000000000000000000000000011ea7eb246d65dcb87e53c9f42ef0b33a419a67a349b3c3fabc47bb4abb84ad9dc319ec262fff0dc8a724c028b7e3ca1000000000000000000000000000000000b909897a2e0f0099996b70854018deb89de6bd6f1df5dead6b678332735390ca6301cba1367e63f4d42cb3e6668945b000000000000000000000000000000000f5cfdc46bbfa817a776d799f22c8c4c9989b65b3b188d9040c765b31acabb988058f8285e667d3b6c8d69aff00a1e0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ea8cf19f171bffcb398a648ee7882827870759fc3c1c14743b5f16ddb43a99c58394d52f792b2942c3488c55f86aa9000000000000000000000000000000000a2b8ca69571212fe07b89f7eb60c0e8b1f14b78601ce03107fa23dc9d04ec5c80b2cd7643fcaa42d4951f072131a41000000000000000000000000000000000124054e8d823ef41517902422d316969faabb314371f88e099ada9dbbe53a1bdadc0def8eee2399cbd7a1e51993824fd0000000000000000000000000000000017e2c1c1912cbfa38ec772ee45673e9ddb00416ba62432c756528c9bef3868fe14ea5953508846d623dbfd74715841871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ba63691d45869210e4d5c88c4118656ba39b990a3e84d2d4f307a4505c22e877ac9fec6e798eb77a101b8418b24dcc000000000000000000000000000000000497173e0f3babc0301e1380bfaa9725b5965ff0544f64bd9e53efb47fc7d91dc55383d03b0b262525c725032a2e847800000000000000000000000000000000071559248baa95962c3b6ab834b1f785fcfcae2fad1323b4845b589cde98baefe28b5ff71ed99391549835f08afb5806000000000000000000000000000000000554bd633ce9c440e266760dec954d14074c4fd57899bfcd9007959252ecdda9ae63996eed30ecf3b4c24e8bee6d5e361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004227229e86f6f395462f00d6c1a7d380684d6f6d08e2a873573cda75b2b856164d86e675489ab70727475180b83ea6e000000000000000000000000000000000429e75169e9848674ce1cf7149c6f22a539152283c2bba38d1d9546162a1e5f1f0010636755a0b1e7e4cd012e0abdb700000000000000000000000000000000150733f4cedbd2fbd9649cce0fab4337f7855a8a73ecd406094505adda8107f234e7d36e1018cc67c1b4bc839d056a7e0000000000000000000000000000000013a2a21696c04cfa8bf099db8fc352417f54b289688023ac7e911f0c6a9ba21bd15d0dd39740b8143e44f9abc88188d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016885004c57809e7b29fd06fc2c207a9280bc522747cdbcee3cb94362eef81eac9e864ac8013cb5d5953bd1be19dfcf6000000000000000000000000000000000c6add91546fe4fa27f7a164baa2f8f3b4d93dcee48177f131ad83062da1cfc62673050bf486c5b1a47f01bd288b6b3d000000000000000000000000000000001978f26a82445aa10891d0fee103ae94e60bf1a72cd8029656eee28431235ffdd2dcb467d5f936d4e5a6a258cfa4cc94000000000000000000000000000000001822a2574af71405218269e841ac6a3e849da45ad9ce95a27e7933cceb32846fd945b157ada4b670d9cecdacad5cc70c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e0ab193a264c7199250d280aeb69f8d99b90538443a4174b0fab1359cd1353ab5060453345381344a3397a642b6cf5000000000000000000000000000000000e155af008ed3dafd0976f1f50d18aed8bfaa859a1f3b1804b07cb0986700f2b9e3703165b6482927d5b10803b32b5b700000000000000000000000000000000171af473540c901d42ce187611fc099c6296480807f9825335e0d243627161342ab96e02e670d4efe7cc9c476f0dd411000000000000000000000000000000000370e24d977a0d91a1a2395e504730a26d2fc69a37427e371df8a8e842f94ed355b1cb09bc5b1e7018fcbdf7113f70a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3cd5caf573b0b8435456b7db83968f1f86743cfdc2c20ce6c49862f87095c5c8e2a11608390cd6023c1f7171e2385e00000000000000000000000000000000126c0e6dde86e59546630c658859d64c39bea882dede4d2a24f12a0f227071e8457a16f901cbbbe57e01b33f0df7fc9f00000000000000000000000000000000164b399c2b8b049e694bc7077fae3d60449b59e917236430a4f26bbb5a409078f21f98c35de7c265b9cd18c608be760000000000000000000000000000000000184eff9698c49a589a1295e4e4d9b34ed4a8022cbe1e74c97c501519f906cda51b45ab5004091845399c3bb5788b420d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001282b4bade13ac9beb21c0ed9b0d3ea584902b3c21d4fa9dde516c805331971481bf981195983501a6ebd28fc042289b0000000000000000000000000000000001ebb2e77e0eb0143e6b8cf248f725c3bdba886241fd431dee11c038532291d8b1c4fd2e7afece625108d4f4fc5f3a840000000000000000000000000000000005715d058973e4ba63a5f6ce8fad6f9e5336dddcb585bf812f25e37328fc12523175ebaec670086a46ff43a34089d85600000000000000000000000000000000051193b285e46080024ba0299cfedb52708ef5a6034f063bb35d4a5d3049301e8ba47702b85fbfd60f7812e4fe1938651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf040ded64a384db949a456fbc85798e54fd850b1270c645bbddb6d31747a4a95d2d140a282e1047cbbd5f7e7024ad4000000000000000000000000000000000fb86c3885369ba3b7b138b085dcfd6b3a8bfe9e515a24e51fd98623419a9cc317e94255b7edde66fb5ba862b07eeab900000000000000000000000000000000003fc6c6a35063a35deb6db39c32251310dd7f3b4113832ca1511624df08fce6a1a0baa3d2d3abc7b925d36626e9893200000000000000000000000000000000167b67eba366380138b2631513d2a8c8c5f81fd8bec80fb944f70a5fa1de8450d6d8c69c726156a30d2871c487a3c13d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b43a4455af23d4190bc53d47f0639ad47162ab9f764632f9d665d173c304134c426fb1605b16ba1726e4bc937cab6e0000000000000000000000000000000004e74ae6145b4c3e04ad2616ee57fecb6edf31111d570ea8a0f006e041dbab4dbbad1d0bf5ad9f5325d5e7e8849276b6000000000000000000000000000000000992e978c1eef0d5e3b5ee5d183cd923a016098536d54b53dda5fa850a7aa8e8e1e0a60e64b4495486e4cae18c51bd1400000000000000000000000000000000169323a1ec687f6e734d77c5de493ee5b092ad5bb1c524610e48f9729ffc3fd35bec3944071c51828d8a4365108ac9b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047b15d5129aa3b51e8677e28d7f42a4c4d2a5d3d0921e174a6eb165a5d96765bc2f9f8e8c38bca79552848d2e9f738f000000000000000000000000000000000c340911aa5db25cc79b264caab3129697712f8136c2e723425223ee8456ffb08db08d694a36aa59fd223b5cc95cfee7000000000000000000000000000000000e82e27ab63d757a9b90347145e6bb7de950754bbbc915157f13156da4b9492fa860073ef15c1e28f6c7a0db4099038800000000000000000000000000000000151176932c72b7425a7c6e4d6f570a853bde1c8bdbbef40f18a743bb100b4a037439314b839be3b246f32fc8eba174f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cb0ea143ed1edeef1a4e2b46a95b92e693eee9165dfe0447009823b134a68af564684a1384d7b0620573001f9ba1150000000000000000000000000000000003ae2466b28224a89eda1a6b3bdcc9e891a321bcff23c204d9519f29f2fe5b3f5ddda5ef80fff7f23de6ceed5298ffae0000000000000000000000000000000015deaf4751dba2071431fbbd70474848b18872cd6f6d7158af0f067b4c4dd5babdac7ac68360ec4bf7d8e61353693aa700000000000000000000000000000000083f6a38fa522a9fafa406d49a5f0fe498c8a6a52d32fc19590bd78f8ca043ef112b72a1de3d15cdbdbaf6d88841e6fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009265979074f4f889c34e9c48010118004954a5a90d84064501ada8bde715bce4a625116b920d88a22df6b9ffd008a4d00000000000000000000000000000000045d98fb750ed9174977642f248c70aaac20da2d24bee02e4e90528fc5abe44689e26cee2343d90076dd4a8efd95f06f00000000000000000000000000000000070ed8a0064193d012d85ab3a63f32bb9953612ac1aff8b0ab533dd4fd12b93631359a28c50244bd31cd534364ba7ccd000000000000000000000000000000000b2d3c512f019ac2f14b3b656f739e1f5250a0f8149dd7ed58452477ea2c6e4c63918352b93c0d5bc998b782f132984c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018826051ee4040d30cdab952b102a527dfe311d98863e5fe585bcdd6931e522633dc536015e77f07b29c89ec9ce31130000000000000000000000000000000012a57554408570c3025d8d02a22c1a73009e2f86351812529e12f7d54f6b32dc50deb47b599b7c5d9c6c71dfa1fdbcc9000000000000000000000000000000000e2e64e5d507ea00756a121f988b58045dfed499384cb0d7e19011c43a230d9cfc0d920e12d1ed6970579676ca4905300000000000000000000000000000000009184eeb95f3a7c0d0cf10555231cf3bc09d3cab40fc603152d4fa4f00d7b533f486486d671293d7d290fcd601893add1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfd112957f6505f3108f08863888abf525f64118d7a421c98d8551a84f77f348e9171aa48dbc39b5b690fa5df9fb12d00000000000000000000000000000000093d89559bc88a157ce4667ef2da6784e6cd7bf19026914feb09c1bec2fc5d233187f07ec5fbda74f863c2feda8327840000000000000000000000000000000013b511ce2727c7bed5ede51ca520e389b3e23968f47b50264ab4fd9a9179c462c05a96fdfbb3532167e270020fae863e000000000000000000000000000000000d2e6506bfef756c04e9d3c4b9671103c76650bf011f3e9ad372c545dcf8736666763c93fa6e7e859ef116ecdee31fb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5e8897efb30169c85c346a8bf1c51be5ef283e353246744af4093847cf3cbc7433d91dc16c86c575129a0c928d3b170000000000000000000000000000000018cf36b7cb42ab433d55d788ffafdf038d19f318fb6df9c2f344e8c780256c6fe5f0ab07baca6b682be88d2f28af9abd000000000000000000000000000000000f3dc995c84dc8fb8cbe47d882d483c1f2fda52744b9714d0bdef3c861ac6d4067749150c1208dc3c9a3da6aec5c0f4b0000000000000000000000000000000004d735b846b627b9683f88f82d65a063ef7c7fea5a51942e47d6004d7b24c8f27715d6e1a66b62226f7c5b02c4449c451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e38664c56e20b34e08e5f8fc856282078cabbbe0a207193fa7eedbd5f37db403ce077767e45d85f9a1bbd6b14e4056400000000000000000000000000000000149d6686cdef272e5acd31c507ed46223977a41de9a9d4acd01dc4b68e2d743a9e5a8786eb920495974f9119ff7637b80000000000000000000000000000000003dab75dde3a9db93920d92ebbb7743e026887fe4807a42d4f55aabafc7ab7d2cba7d3e4c86405dcce8acf5e4280c1c5000000000000000000000000000000000b17b81ba6e9cc6684ea723790da5fe36786f2a541183b7aec2f1660f7f0475edf34425f0ae24d243a123aa87ddc0acc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ce789b7254f9f44fce5de2c166bffecea342150f66ff47472a2428d767756dc098c53018970fd18718b39352c98d1300000000000000000000000000000000117a853bdbdaa0304132440c4dabfb48a04e6100239df9c3c30c6d408cedb60f1c3875da9da472de1f7abceff52d7f040000000000000000000000000000000009cbfe9a411c3bd5a4d6cf7f2b1e392d65896bf4a98e4e6bd2e16dea7d7365f2f777639cbcfe01a41858bdc01540941e000000000000000000000000000000000269f187fb68af2dd9d2c89ee6b42ed1e8e52c01493b4f949d9c3e2478092da425e0a7f7ef3d8ab87511cda32aacfb0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b2a69e0f50382feb6a52bec5a619a52af2567a71dec7df9733dbc1563b9a752e7ea037f81da573e070e55a1b9f29c5000000000000000000000000000000000f2590761eb3bc0016d9706ca5951b70c5a0570494e7136e1b9d2ed5f4f852c1ee8c80263cedb8ee0c7d06e76479a2e600000000000000000000000000000000076281189c987570697535506aaa7f1637e5f4ce46ba9cc2ea5db0a902b508c7b13172bb5787d5476f11f8d7770f526800000000000000000000000000000000047ff3ec2b995c447ffc923087edb1591fa3c0ea93a632eadde47398fa0ea0a1d3774e99b5d159d8f82c0252f08093371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d79de5077cbb627c5a4bc6957ea5d00fb5a97ee91aef69d8d77e1b8ab105b099d98fc1024c1ad219de4316275c9e59700000000000000000000000000000000166f2820053055b369b667e5402b080e0cef6b5373302d03861ce02b9270530de1966c8ce87487027eb416fc82278bf0000000000000000000000000000000000aecabe7773b36a21d1de641d26e13788df5b395c61e94d6aa935ef3e10b70a75fbbacadca94c62f780c7ff62385c68a0000000000000000000000000000000003c01c8de89b70754cabfb6f00e29b62c4c5b1f7b9edd06f7990a7f9d032beca685a2b68844b3b399d74f483e9acb45b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc29de8e6307b77c2c08484e26adb64266acbc071f2f3a43faf7f4ed41ba2f954389a357b5abb49c7a9bdfcc95cce020000000000000000000000000000000004fee77a61817636917db7d8f03babdcff8d3d1e139d8874a1ad6c3995fc3d58969ec5c219d76bc4d8efc2146aca513800000000000000000000000000000000197a1304de74431d6771f9e38fbedebdaca6d8830a165ac289b012fde61418a8889524f4319a3d9e5e4c0223ecd063470000000000000000000000000000000017e6011a6d3cbdb9891a56fa7ea32ea2d89b49b1ae5739dba51dabc0035ebc90b7ecdec4c609fc0034b26f408252c5751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001429a08cb8fff05e88014c2729808667fd9d38bcf1b6f405d20c4471d58fcc68b1cea316d8c15c7d0aabd03d7c5dc675000000000000000000000000000000000831a636f98491333e71b86d86c75d2bd959c04df0d74c3d96fcedbf9c0a5139e88a229b20a8fe52fa2910cfbe68354e000000000000000000000000000000000b3f5aacced744b4f9a85b9a60977606a8ea5b6f20af32a5c9411fad6c7bc62ac4fd79c5b25c90e74479f21191ba4a730000000000000000000000000000000001641a095d25640359111cd47b62acd27318a13f519a62cc652bdca8fa5d45c50dbfeaf4846a9e55428886998cc895a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044ad2ada71dde708fc35e2a75d4c92ae61b3da6187fec5a51777c1cfebf1a00ef24ef5fe71678bc8c756d9e6098871c00000000000000000000000000000000036daa00011b813f90faa3a28e5f7473fd0d0a025caa3cc2eae3b07be9920bbe256080a0c2745e72278381391af67983000000000000000000000000000000000e7f2ee200363c3fd0849b80984e5418535c0156988ad4be3f682f01c33ba05c537371345569c23325c5544f95dcdff9000000000000000000000000000000000d50102e87276992e31aabb20431273357c2dabff73de366a353a0e42c0147c0d49ae12d706157aa40b9636bc467b90c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005ca3568c7e0d73e64ae72a9569236e9e9e7c7adc75e33ac56c1b11e3f8578c54ce180e4fa093b1f51576fafb309f7b000000000000000000000000000000000d5dc3d2b994e1da6541c68ece2d4711eaf94edeb19fb38b6a5cba383f58e9a064c482549fef4e373fd91ce778f38317000000000000000000000000000000000fc4d0c677cfee9213fb03d0fcc870412575cd73694b6d2b246b356692b55791e1381940a98ab6f8b160ec683334261c0000000000000000000000000000000002dfea3829e250bc04ec481859be8b5e608648488a2abad8545863b9e186afc852b6fa7a069cc4cb2c842c92ab4bcf4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001189ab183dc1e7652515190d1a536be552a50c41c468b1ef1a3bf03c2d1bb4b5604e44fc5c941d585437ee3b902405e3000000000000000000000000000000000f57fab0149dc21cca83403628f98967dd12b3ed6249c8571f92d61ff73fb613ec84f5264775155b0f2afe692fbf33650000000000000000000000000000000002bddf2be26219b8a80ec130ba3c54d9df1af8eea8f588746bcee0e0181a11dcacc27df2ff6c7832c8a2d2d0b1e398b2000000000000000000000000000000000d8b552a4c787605c0b3148c9f01458ca5e9f302ac33695ccfbc8282d81b4c733433c1d9f7a78fdd61b56707b7c26c0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f4e120eb96e7e5677b3d884791b78d2deff8291162c85d3ee270dc2947cc7c405502bc615f0e157b33aeadfa08811700000000000000000000000000000000041e2cbc8f15c126dc192997e7efcc056d96456c5f828d274fc9e054bc27e3887e33a092d48af4292c90d7d4f04e6e650000000000000000000000000000000006fd2957b52b4568898a6d52194d63e4833f78a97cea4daf25157d13f924704c668505ec09212f57dc44acd698951ddf0000000000000000000000000000000011a40b1780f38293f1f6ea97e84145b579e65da1abb8dea94bf1138c6b263b7574a751cf88ea52efd3419b93b08d2f561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102a40a6b52635eb364902e3493a6485ac2fd17688b0d3a62b101ce7b7e169c0018e41442f5d5fb6244a06dd052c5071000000000000000000000000000000000f21db1db74bd329ccead2e5d0a773ac478a4297af923e1b2567c4eb2c0ec9308717b711258dbe23b4505f834772cbd500000000000000000000000000000000106602979ffbfa5806033c3b15fe0fe49f81014f76fa5862b187bc3ac86a7e42b9163dec24a38d3002e9969d405f19af000000000000000000000000000000001656a6f5bd0801b25b06be7430a411749848de631e1896db3a9948ddd5e9474792516c9083e34e3a055af866564762131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e4477901b302d1e6ffd3279d1595c26ff5e6556c569323bffcc16d7e55b06377af946ed06ed40b783f828a02c60366000000000000000000000000000000000f173bfbcaae854e0f7cdca127cfee99cfc84b57b114006f7cc2a1604f8159586599a60ff807150bd9a9594e91a33c1d00000000000000000000000000000000107c48b722f39dc8431bab90442248ef84bacc0e67718f747adb083bfb8c40b9d4e38c13eaca7bca9846753193adf7ab000000000000000000000000000000000cd2418be5bbdaca2a1603a69e6350327f5292fa8a9e8302ee5660aae0aec1470b47f8af1ed5c7ee1706fc6067c882cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000168ffa983e03e3d4ddbc9fe80fb51be3f2db2d6819a1dfb2c96407c4be7df51f31a06c03be8af084c3264284b24829000000000000000000000000000000000170c5c3a90e560c3e5dbe3bd4e5eaca8c0cd46f0a19516b0cce13919ed1054467a697774a49ba359c47aa117b275635d000000000000000000000000000000001077a0e3866e662faef70dd1fa854ee5b12e92038e24dc55a24a2b3d893ec67a4f13b35a985408a881018477ef31c9930000000000000000000000000000000017d40135930c4782b10f269f5080b65fed4f12193010fce4a1c161c34bfce3142fbea24aa23fef48b2d908048ea3a76c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df8f3890285fee1d3121a786b933e0b35fce71756ba98d1594c1e5c9bbc51c72dc4c307eab7a84ee97acca1045cbdbf0000000000000000000000000000000004e98ea549df24b6a1adb6ad3a6f01af4236b0c271de9fe95e8b9e8ef21283b488f9754ac67a12fa975fd66d595721ec0000000000000000000000000000000019ffb12fa5d0852dcc474690e621c0822ebbe57f44cdd2c515c8e64c152a6240b24f7d698ae1ba59ae69b745ec0dde000000000000000000000000000000000019369898dc67801a5de8b70b190e5bb36625dc7dc480b2992264d361c1ca1ba5036f39df6e7d4a9a79272d14126308831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e096cff78a1ed89b7ce9a048affc5b9fe1cb26ff9c94798ec6436e4f1bcdefee7eec2d6ead17fe1e3e8bb5b4d7d900500000000000000000000000000000000194a60031bfa005e5e6e540163c27db047a01f3c84478ba220b7ddad67e51b50c45baa695c96bed44bd5da5787b199390000000000000000000000000000000001dcb09eb696098747e28a11739ebc77d2252aaa50ad1ad28eb96f6250f1d16f67b785949cfdc7a7cb22363126673abf0000000000000000000000000000000018a063c9107ea44628940784fda8f52d092b5711695a14b89e42ad090b9c751aaecba0868fe8332dfd77cf71625185061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a670b82f948e1d447c46b2a59759232d2639c32933a01586af0f85b7043b2aebd5da0e08427d6d7d7e3c3b2e5a37a4000000000000000000000000000000001883625bdb964a19b3e3e3e86821ac3a0a17a04cb3609c8087caab44d9320b552e643e53b33485ad829de8114614b2a800000000000000000000000000000000049cdcdd6f4bb89e86803d643d31101aeac5d7f4405e655eb5eb63cc4a3548f2c2b92261bd7a2fb1edd15f310c08f19500000000000000000000000000000000113cd3aece00114467c3e86bf099e56edada7e14442d864a18884bfbf2e5241ccd4c0567b78758b2a26ffbd978e855141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013399d0573f415e333518f342b3f5218d27faa6091caceee8dc06e4b375182d43b4f5cb0cb1603626d8244166b33f4970000000000000000000000000000000017825ef803a0a43c4f720fc29ca1e22d7116977adfda34ec7f6de95708b3b39695881422318e1fac75db7f23c6e98ff90000000000000000000000000000000017cac54453562899bcb5faa0ea866c2365c1e0a9afea9c0527b8a17a2efa654b40a1ffbdef7358d386a1e8793fad51ea000000000000000000000000000000000d129223d0a3b612fdfbea48fc88e3b8fd9b1c383f534a06404ef23ee22dd3ba931b9c1c3ca3f7e978b0ac7c8c9137901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5af8e8953836b3888803ca1819e4f949e74612f53f96ed0bc3763e77c6f192c67b383e4f0bd8f6867b40c15d1cd8d2000000000000000000000000000000000fbf6658c3bf26002730cdc0dc85371999bb3bb4e903de453f2f300d92b3003aaa0f843c5d39c7c4da28cd5b25bfbf98000000000000000000000000000000000dcf78ee8860f5dc01fe53ba4b60bada638902e67334dcc01088e8648e30355da5c8e1de2885831febfa48ffeca0893500000000000000000000000000000000049b7690ac7708e7f36f7ede214f53540e79dd586685eecee76e0150d45f9b103894d865dfdc9171e126e03208f983831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057b61a050bed803835d2af0031547096661be9f3a29b6f71dd2d5db9484d6f7321ffd82405d156727b0dc7f2cadabd6000000000000000000000000000000000d25a03e12c5b5e4a69f8f7000881cd48259f4e9cd77a38bb05973c3ca74a6adf2431a4fa8385c5ab5769e0df9fc48360000000000000000000000000000000000411057626036cf7abec0573906e8aeedca814486ab45b48802dd5f406594df2e38ac7a706a5702fe995bbe45581d2600000000000000000000000000000000037d4ad9f294eb2d55b99540aa71141e0e47bb62d68502703a19fb1291cd702911be385e60ebfad1a4fcdc1809237eb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076762c73c719700a43c451c0ea37a0d2e07859b7632d25ed9c219ac2f8cd573289ccab4362755d78557076978261c43000000000000000000000000000000000126f61c62029d40527ea8d06c29dce68e88531c888e626f863c5529aff5c4e95f011719581d7bf59554d6432bf67ff70000000000000000000000000000000019520e2daa94b8de7909686204d867fdd9b40d9b15d08cae1769489248d790ce6c986288ed2ef1a3469c8a570591842e00000000000000000000000000000000186b7cb63c012ad06cf575b810966f9cf8e88d0b9478315971d7e4700633977f9fa05a3bc926abc309ab8648d1aff8561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002e30edbd003a8b1f35e5b76562284d80b9274495e85f1b78ed8a591fc09bea8ecb015c0316f8821493fa6aaa5fece80000000000000000000000000000000018aa84b77df8c602f087afd32a6b1b4abbed927d57e5b69efb50dcb5229f5a91aeae8f0277f337e6ddfaca145ab9feeb0000000000000000000000000000000015ddaa1f86eb5c20a22a3390284a63f6e14584b22d202117d56155fc6bc1ac63dff60bf046c2af69dadab0df5d730db70000000000000000000000000000000004f2558c5bbb70263071cd5b998fe03c0b1c91d2dc74fa8c5211d2b7257578f99756fe1c425d49dfe0792adfe5280ec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ebac605ba794db968286e37279af75bc5b09af7a89463e9fe9382544e1002edcc3bd9b39f501a34fb7051e97fa3f50000000000000000000000000000000001dae26d6dc63e56aab94eeda509057fb70e74b1c541f17bf6958c2afbacf400c1b08408fa6d18f4a9f9d33046cd52ea000000000000000000000000000000001139178537e886e646778fd28b2857d2838e8dae68a0ab63686e34b358ebfaa880192cbd4a8e3a907bb928235e1b78d600000000000000000000000000000000058ec20699de411e7836dd8b285dc2194e643f9d5dac715c886c687c7e0629f849dd68d8176a2285f1a4e6afade67c931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7f21a14a48ab0ba4aee91c0625885d6b01460fc98b266be345eecfc3cdf1c34769a39f63f4668b01ed27ae507dad6c000000000000000000000000000000000853707f89785a2fd0f91cdb91a3a26eb945dbc1004c5a96739712ce5ac5dd718fd63de4b2cd1c41575210ad5e557649000000000000000000000000000000000a6b1a644e87bdfeedd7d5f5526470df74392c3e23e20b4fe9f22f3772aafda3b8185c36e5284b7cc25f257587a91bd7000000000000000000000000000000000c89bd84eb387935d59cce4171f00a590ca7007ee760d2581edbfce8e6ef8b2cd2acc22351254b0739b240e6126dbfdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069a0ec0378935cf3101ed6e52baec487477103a6fea80dcda112c3882b31feb45afe4c4d16f96b2e286b15493fa693d00000000000000000000000000000000171d6127a632cbdc8db25e389f60c50ced77989b8d6c116807bfaf7891d460cf287209f9f98ff6b28c118b053f88ea6700000000000000000000000000000000061a6eb11eb9c532b1b08933a61b9067957620b6a0d90e42c48d887509965dc0086b508f37b3bfe93993222cc2dad84600000000000000000000000000000000036638d40d00d948002019b937eb4936fee10601565d324b7b180b0e3ac404138f0d266eaef281be8335cb99ce201e581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001359248cd0bf470c91e2c6707801cb1c663c12204fb2539e04cb2cbc6ce5e119866827f9ec3d89cb7f42729a1bfa5aa40000000000000000000000000000000001e93b0c7438774fa8c7b5fb6ccd58d648247572a38a3b47e3e998efcb8ea1d5cf53bb8f15fc52822e7ebfd238d930a70000000000000000000000000000000011c18f3f677feb36217c1824d9e316c76ed1baf6c8ffd1f938f01b2127e08554851db4901563a5849bb3941b19c1c7d60000000000000000000000000000000008e470e844f51e60e6f744d4426755e4e97bb3639c79fcfd2fc3c60fc12f82e239e654287f6a0a7b7af4ea2b889be1211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aceff7d57bf85828f03febbfa81e512131b9d4ea6cd6a8b466826d3d143f0a8c0147d1c58a35290468cc7f31dc8d6b100000000000000000000000000000000151147df8066284c0165220ac8bbef374a91f36916aef8d2990c957fb34a65e685f4bff37be438d02349d5302c3c7f50000000000000000000000000000000000c5a9b5a3872ab252fdd2ed190f079741c2e3970c97661ff876eda3ad1fc6aafddf4502a7651e7618aa0121a957b49d10000000000000000000000000000000004433a3d4d5f2fc29c141858cedb63354fb863ed365b2c5a03dd96929d37c46f0959ff37463466067476e0f932c387cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb0c8ab6e2b98c5f9d34de3acd3c50c191e012f89796149d8a95d4ca7a9a118541995757e0e1a725d837a364233e09200000000000000000000000000000000181728354e822ac48c67b3e6db100645377ca7c92893e0b599dd350b81bc301aaddfac54e824089a4ed9792e6f0def3e000000000000000000000000000000000563af6098beb4815eeec530cf08f50342f066d08d268138d9cdf5307e284e5a6ddce6bcd0242e00570aca3f13e5a825000000000000000000000000000000000d263de0cab6f2865c75c6f00e878633d33baf30a0a8bd7b637ad786b6511a3bcaed6f86d1c4cc8c8bdf08d2ca9efe6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b098f261f7b36be73527f17037dfaca7d3d7d0654cd8eab5347e00b7a43732ce3063d3dd448d4909bc1c24f35293f240000000000000000000000000000000013ec0125601c2325c749281495841ac6ecc27f82f0bf84a907e3fe0559f425e1cf0b4e476723d6c12913706b0e10d40000000000000000000000000000000000115b837546fcf4eac8f35bb6c33ac3af2dacb6967b5f2b4062575646815d88df26a03b971f2ad20dfb10f18ddc0de36a000000000000000000000000000000000769941fa017e11bb61d304d445c4a6b5f9c012af2ebe84eaf5de7e7355f9c979ee945da67e56f4144cd80c2c5c4e2301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000267dba8e4e5d087d44270e623761c7d11c9d00488433a69233f171c9d8a95acd9d38b9a015b7d116ab76b2b7154d2b1000000000000000000000000000000000845f2b24916d1547ab0be03681307219f896cdb5b86fc1f0e53c5b99a8b92b3df5f7fff112fea21d1e8dd940a938899000000000000000000000000000000000bade5301578cf7c77a5c7e01dbf6a42c46b4f01c2d8f386d522b649c8fd03b046a15a19b1cc45df65313b91238a8f4f000000000000000000000000000000000686416d563d90b506192987a5108d094be3c9830172b4599368c4d15fb2f3302474c8db966bf39f43a0ae0a7afd9d311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddb0d375b76ed7a209c4256be34324730de9b4fe138659a04b4072ec8a39c61bf49b310638f32cb6e4a9a00ee3081b6000000000000000000000000000000000c9a88aea70c3f1de752923eb586923d100e229b032d95b64c64b64e0bb8bb5d66a8de7bce337e94654c99c2fe08fc61000000000000000000000000000000000b00d25fe797e0f0853d05f3f680c8e71ab0003405e23d67e700b26321a49715010e09a4e9969b2315df28420337e2ba00000000000000000000000000000000181869b308b8208570c245d211f54c63c8982a5a49bfd738586903009513becd10ed89270c82c2e382c8d7798940d4471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081ec49df044de2aaa613504cf465f72d4ddae77ab22be1ba9ed6836d52babf265628d20bd6131d4be51aa8bd66d0ca0000000000000000000000000000000001575f94dce5530c8948831ce62e9bdf11b5fe74e6b714dcde95614d2087116f505126b68e929c6b6616e625cc07571bb0000000000000000000000000000000013617d667d380884ea04b6709f9046245e7781bbf171f32cc0c533f87f66aafc5d68a7ebb97a26ed948482f7c42e73ed0000000000000000000000000000000000029eaa93844a3da0c1ba0a52d4707ad29175a678439bf3081739117daea7f933b0a4c531d66036c481a56600e3092c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689ec130c40431d438e491ae5a7bc87cee09becd88ef0e0648d8e8248cf4325c0dc982c6d0e20f7ce192a41762188bb000000000000000000000000000000000cc158f444af97625edf850a4c272d1c7b1d255030ba8b1239babe4e2c2671766ba6adbc8d062de205723ea7625c9ac900000000000000000000000000000000189ae15da3403ed35ce5d7ec407fd7e1247fb10155ec49ccb86c160e84212a6d47115e01c3ae10e72dba94d5f89f930b0000000000000000000000000000000000a3a7c128a2f520c53438ee70fe50783681072c95815027b919433c9a4b028e14236f6259bea12ece2b46e35fd002891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a4214f9de7c9843d047ff728093253cda06a23fda6720b690ab26845a8fe35c5d526be2670fdeb3e2e278fea80217a000000000000000000000000000000000e2ec56ef65c82af4b0eb1cc09248ac73538254b1a60035c7b7b2c845938e7edb4a5c71a44ce81c01d6f35d6dfd86af10000000000000000000000000000000014f0dfafaf14961eba9e3fe5e4d5783eaa364f11c0339a29f8fc7f94aac1ef219c61114390af6a58714deeb41d3b9b85000000000000000000000000000000000a6df933b1ddb9d120eb7df1a65f9b247e6f426f1f0a5f845b0c08ed437b2ee2c1a798997a9dc8da398fca488be78a241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000709868729d44af981a8d77b241f931904be222bf61d69d75eaa2777c75c14fa24b70849fe30ac607c699c5d2313e6b100000000000000000000000000000000131cc6bf14bd32e234c534b015566815159596bc88f8d4b9a4805912fcf2387757cfaa011be1f5ceaa6de447771d95880000000000000000000000000000000004748caf0b67721fe17c42266be0a00ac8b7236177228bacc2a74d7009cf15b5a713f98155783bda0d0ea8bb21b47b3600000000000000000000000000000000020af8f341527d18b52d39dd221858bfeeec5e33322a08d5b330aa19781ab2901fc6ee9475c6cf4b6d84ce72d51512211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144df9df4f9f3a274aa347e7a9162bdded981db496f48aaaad98ba54c3c793bb913ef27abf37a1846cb1dcfb2e276c1900000000000000000000000000000000140041f093bd58eba0438122b980da002d1e5e4d71450c00ba63228c14822daa702e4c3c412cb7b4bbd57c92ad3035000000000000000000000000000000000006324b67a55664f1c02361d0f01183397241c14b90c098c3d00bdf8c4b1ca2b26dd8257b565010cf72641628640d81e600000000000000000000000000000000183b82b62f50dee386bae75f5e24e13ed452347dc84240035b0b2221412db58e79ef2ba68ded05330993322bd57918071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f719bb31f5e1f79a45c12230d3518463c398d97218baae01ab6c7d3f140ed3d04cb7dab2870d811202562bc5a7783d5000000000000000000000000000000000f2fc77e2a11ec4f0a9ed54939cc74f1f8fcbaa9b73c371f58ab979d933570fbbb09a6721661ff2550a526492536bd0800000000000000000000000000000000003b6a4c08f902b8353a0bc93d001d44e626bb0e7720ffe83680352e4ce238129de015f83441a467116337b9166f3739000000000000000000000000000000000fcf44fb32c7f37ff02fe20e4bc20874eaabe24b721ab44c879411bca895562a8b6cc60d191c7226ddd8606442b726aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002724a829e7dafe58fa3f3932387d7c8b136d141d3c6ab18b385248f8e2fbbb91b0b52440606d26cd1b6842840b39a75000000000000000000000000000000000502c0cf101ec4b56c0e212f7783545f68f72b94aa9699de29a0c36568d9124b1ab30e9e4ddc672145048f32cd396a2400000000000000000000000000000000110c6f627595207e936fbde1ccd0588fa2fa66d47178afefe644d44c3840b5d3e661a8a1cd6be88eb49f9456f58c8fa00000000000000000000000000000000003dfa7c1b3070cdb3e31d9cf7e844ccc00cfe46a58ffcc2220d6416f71294d34885414af429c58cac0de9b26944404fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181afbce13ec8943c79ef2a915d4db5b5abc8be9daf6231f7c8a7f29a22f304c2148285292ca35fc2f2a85f52d542cfe000000000000000000000000000000001525bc110adf22f500d8ed319db2da50ba97e66238120b3a27516c384cd28725ca67586f0d6eda2e65509f6199b86daf0000000000000000000000000000000015d4652569125ab08bf224eaf841dbc3c6a41df4adf45c3c1419d7f6d030993dfaee344d2b5ff4c5ae597ea9e11306430000000000000000000000000000000003ee7c1e38456021733e8603befebd54b9fd7c7ed06a492c108fcefffd2da512da925ac6dbc59653e2b5a526ab47ad631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e7d1bb17560f275108c2b0933b2fbd5819a8e188127d2171483a4b830d005a950512481369e12615a407aa069fb38200000000000000000000000000000000056013cef223a6f176a39d753b35029d84b9be3e4888afb075ee3004b53c9d50c1397464f19e9c71622500dfa2dfef030000000000000000000000000000000015ffc4d1b37c21b7e8ce5bc2d0985b68fac891101253783a1584a736e35334afc76ac1dfa1042b2af29f70e8cdb2cce4000000000000000000000000000000000c69a89d0ad5d1a10c423ec320ef61f27173a7b3862f6ec5140b42551617723b59f22a1358ef4becfab338b31547295c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165494a48107c001dac8dac9a3dba18c1bb88cbe7c02da2ff26f190afb145af687c085899c8ce8255e147709c3e616f70000000000000000000000000000000016a7dd65362fb61f713d734b26afaab46fa9eb9641eacea27416c72f4fcf9cad7766a7ba7bab90f4b9c12c889f2347e00000000000000000000000000000000013344386e8265103057b30e0e033a9775c4d2199c7ca8def995f63e1bd5cb72fc6e7f4dad49b7e8989001ff2c94c9b64000000000000000000000000000000000e5939754646b3fa1756ed1fc052d2855752de4626c47343a15663f3c1ac984e34ff0859f71c3906874ea76770772a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a5e70e4faa0c58fb8cb8071682b83bf59b05e15beeb110c5f64e6fd92ae0a2396e951de4d7494ac9d22a9636c5c51000000000000000000000000000000000017b29cc701f229e76c2e950618486e43e7a49a1665069369f0bfd562b6bc84fd3eaa2fade85e8c7a49242ab0b8bf686000000000000000000000000000000000ff9d5b8e8e55abd68dc13864c4dadfac324bed8edb82a7f7044f4d002bcfc08818ca34f6fcb40d218119c8f3601bb6800000000000000000000000000000000192ddd284cd3cf707d54847d93ead2d95a64edb9903934a55a661b0496cb37a82ef3d745e23bb6800e847caab5a0c0111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673100540b2263bb43cfeef25f79203ff9813b53ac74271e511a208c138bf333f0274ec22c2de9e1d0c5b61388d492a0000000000000000000000000000000004952f3c7cb942a5cd603e9ae97fd449a5c89dbb9e4f10067009b525eecef339875d8483e470a6f88573a9501658417d000000000000000000000000000000000710cf44181450c7d921b2f7fcef0482664af80f5b25e1d4ff054723995cd8a5ec4e83e5b40c183f7d33c80898de3987000000000000000000000000000000000aa0a4fee37a5e56187da1a321f63a59006a8e79e8c96c0c8ccaa29a755c0af7e130310ad8adfee2f3af5babd32255b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dddbc1a2fe5116c220f22b1f66f4aaf84f914ed863b4f89e633fab3e40c307c031c30e4f12e7f103793c499c17808f0000000000000000000000000000000006f932bf8e5814a429be0e14d9b0ee1bdc86b76834f90023017ff05480356d7dd84c0ac8990cdb0af048318f3ef2e0af000000000000000000000000000000000285a67174a5e62716c9007d995d059bf3db978f30f682dc34fbaf35a948731cd88b1f04997e72910a2560df3e1d78a1000000000000000000000000000000000b57de678988fe43e30c1785c8795a2df8e6f49e7c2a3e934a914fc506f52d2992a33cc266647fd884d3a5c1a5fb025c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014338a8d8ff57255377f4b50fa8a268d53c48a134fc3d540b309c560a66652d321489fa97ad4c482b49471ceb7da60880000000000000000000000000000000003b04d2d1dd8b1f7fc216b81e2c20d1dd4f382357aed9b8a65335c39a404ff6a03748d8aab545ac8683debc705f951ad00000000000000000000000000000000128ab8aabe5a12de0ca9a725b8256703a3d5071a05a1ea235e1b51a5953deb6313bbb014521f3a0803c1d6956f23820d000000000000000000000000000000000eb24ccd6830c787321f6de698ab43a404f7a47c21cd502feecd80a1d711dad6336937d68baaec3aabe31cb69e1ae96a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099ba6f8a88fc0d6384dcc5c79091e4871f0afd07ea655cc9034ba800b324ad05cf206f17b1b34944c6af0e5e166c2890000000000000000000000000000000005ab857ad9430e00a14abb44cb43ed5654ba957a475752677f92bfe1edf18acd31460f3b63ce9518fa667cfb27ea51e6000000000000000000000000000000001175f99fd078c1b24f7952367cd0ca868dded4f7c961d12d950bf70b73fcabd625839d263c2227db1cb7b18ea20d7d290000000000000000000000000000000014dff1f530df08f4af9df5a6530428cc80c430c1a3624ddb084b84c3ec41b81b2c3e1a892d54f851eb7866b9dcac533b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c04c1aa0b9ace3c3b6bcf84e2c466e8c1874fcf483324c6808d2f3f2408da43806fbb56f0e66fcaaa4e4dde8f75aad000000000000000000000000000000000fdbb8ca07dbc7d444e6d9c3f89f6f2e9cfe33cea0b77d43537a1258bc5d63d6ec288205bcece21423d753031094b458000000000000000000000000000000001932e8729fa5bffae3f9f6bee7aa1170d57bf63abad55ca4dd0c541b59668f5b2760034ee0f99e1584126c621180640f0000000000000000000000000000000012cd141f78973fbfd0f270e8efe5aec7e5a096f219859c6cf883916d713e35d5b3f40f5cb5126654c9a6a6fc89ae93721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fa7e94a776ca6df651eaf65bff2a07580394e47c2ee2b3c6b2779efd4077be6132961647d2fa8ecba9e1d207dd29db000000000000000000000000000000000d61ff2a81a962213875bb45cf14260398c9a00c594745fe53943f7630bf1602a9ec03b11757f3042a37fcea8e9dbf8900000000000000000000000000000000126fb94bb500eb760f0ca93ecd665c63040d2b264d23573763f6c655db91736f15ebbaa63ecc0305471407fcf0115769000000000000000000000000000000001789e6c34798e7dc104a46c9ab162efce605d82549148d073cb510fcaec56fae4b8fde37329ea8f89d339151a80a34521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b4c8c06678d02fadc3ace20e692170b3676faa3d3ca0907a8c015479443b42367d4cb564cd15258de87e29ba4ecbe600000000000000000000000000000000057951498d606a20e2177f4632cf819afc45d03a6bf2e781c125cfe5007debbfb3400f4a61cdd748aa2e267ced3b9dae000000000000000000000000000000000e074b729f8ec07b627737238cf8620eaa41b42182b93c966dd377eb1eba593ca67885926fca46f2fa29408fa9e80d6f000000000000000000000000000000000079eb0f264a3d4be99eb1b3355115d5bba6bbf83cf77ea8da18e33923f47b3b2fb0897cbd4c884bf4c4428d7590e9cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001917bc809717f34992120edc423236e18bcc06b8d44aac3a0831d3222cc3d532301d8ecb5a4f40bbf485263383c64d300000000000000000000000000000000000eed9c45e8679807531dd7c3688a0d470b2c151e84ccddd40152805488b85aef14fac8adcea7a943cb1c415e87af160000000000000000000000000000000006c9efcff83966a07787c4cb80dadfdce96e2bf79cc4fedfe65e1c91122eda6d3c37e38047ab90d043538aaf8374e0c4000000000000000000000000000000000fc64012cf665e6c20f7a993831ec06ebf367b36b4a9c243f74366db52035bac90855e0600802a4b62e086bd74ec156f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116f5809bc9199b21990d092d1c5d195f58e7be168ad49c261ea38789038dc3123c4f93b055dcd74286c6011dc62a8c900000000000000000000000000000000053b4c190ab3c785a735259d04d23b33c321a5be985e29e90dedb01ac641c937db36f0a36d3ceb9e973a0902c8996b90000000000000000000000000000000000dfc0c99b1456bcbc63cfa571976e4181b99d13644a0a4ca01d75fb1e9b0476404c3bd5b3283d82d9d51fedfec35fd6800000000000000000000000000000000178bbac3bf05705d6265168c1fe8a0cd6dcbc93f126263f756f0e255aece8d474cb592a722697488cb894d124cfe84151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa2a2d4118f60b66d1726695735aaeae4ac5ae7366404a62f8ada825aa7b5e1db4cfd81669c92e2c0b284c3daa10b0f000000000000000000000000000000000f0a7181c463e30d1b35758f12dc71b99d8953e34eb934726381a72a98f8dcf3aa3adc57c4aba31f38b901911822c6190000000000000000000000000000000000a341e4af8f24ff69cb37f27a42222640a1a131b52fa83ed2863fcc2a99d02e678e60db0b63a90a750343431e0bdfae000000000000000000000000000000000f2a07b3ea760779691d43a58096458421dfd6f0eb7f150eb68953f7acf98177741c3f273fc3db86857e75f447c4cebb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d475c932cebb0b915bb9d7e0e8c13878186d832debcb7b7f28eb029060af2b5d5aa827bdb7f4d2750fd89d10fea258000000000000000000000000000000000520caf9f6a7cd2254645fdc9b6c7d4489f28078ab4bd40f36012366a079b68a3af995c66c7c6c05e9b4e0a08cc561f70000000000000000000000000000000019cca35e5c162005918693d02b3e45d6362ea66bb2b907a53e0a0d2979da7be7c8396015fdfc621966e3c9b8f37585910000000000000000000000000000000006025ca77a89f47b27c0af17120bcbbc53c1afff891949cf2485d1a897e4c8c8df49630bfa1bcac0fc77dc663d2c11911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010445e2b83040a3b948df09e5cf39c4804cb3a8b024d9916dbe143fe3ea80dd678a165b3d7e1d707ef85ffc3a1d7b4850000000000000000000000000000000000758b0ea67585b17bf96b0bae92d4893e1abf536cf3449c2cb1318b14d10e30db1e7e203b11790743eef00904511abe000000000000000000000000000000000c62948913b675d591aeebc758a01b17285e36a4cff1c76cf28c8f41998f7bc23e444bf874fcd5af6af75909685c750a00000000000000000000000000000000192b566e3412b2b552a4537f010d2cf46a80334c56e73c58a96f39b2733ec328c0307a1805328298790820f44a75a8bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019689cfe16d252a9c25f07970c30db5c8baf59bd74c6fcb892a4836add6dd8cecde4e6ffb57d238214e66a34035e82d40000000000000000000000000000000009cb3a73b936ad8524e2e47590ed54ce72311835d4efb2211285c4a5b5be5daa5cfad58d71a6708ecc0efda47eab29e60000000000000000000000000000000017beb9d2af62503cdb05aa98624c212780889b9d13440e699b60707f4d3178c6d01305205d5a42d23f5301f6241fdb8a0000000000000000000000000000000008e7411727c49f488502e6674e36bbba6859080a4456893d4f513521f55473a9abf353134bc089b2b7eb28692c70d5de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004957b5f6ca75a70b9fe42bb88df63a8d6bf2f01abc52f644a886cf5a08eeac7097f49222c613710058d48aaba158410000000000000000000000000000000009790581d267738075d7a7107479f2cffe447bf319e00a6285fd311323b364d5a97ae8bece2078cf7d0ea380a7e555970000000000000000000000000000000017d0a2c1800089f20c079143a9e3091f48f6f6870f2a58aced227e60d802e8e85b3440aeb2d1b4fd3d36b9c3b53392b40000000000000000000000000000000014f9159460e560eaee29b1c78da7058efe5e1457f7f0c03aa23537c23f648b1ee592693d7c3c87b02224bed6735a457a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177ed297174517dd6ea283733d18bd6c204f5ef00601424a87dd1d2cc24a3a33e50c167624865b6e7b4c4619320d1490000000000000000000000000000000000d3fb5c56bb3f713d61e955f5e5336869649af82d6a73ea9d9dd2bca1dbc89dcc226ad52634e815486fc1f6740e471ef0000000000000000000000000000000005a44c6276945b86ddca5bfc78cfaeee16e30f793fa24b877dd99dddea6dc1dcc1626f99c47aeae79725d81332f1140000000000000000000000000000000000160c0d2b670e9caeb75e1f85bc1245119534cba3160e73db34d412057275c3d728c25206b64a33b3c624ed38ac5e997b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0d4256916b7c7b5951c4cafb5e2511bb47e412bfe93ca3917ca6b2c6ff3118cef186d54c029b1215683a1a65b1ab4f0000000000000000000000000000000014c3b5b020b255883e9504ce92fe3194e90e4aaf3240226f2066f382096768b4121c73638baf143723e3221f26b2b861000000000000000000000000000000001792c5eefb76255cca680d20cf63983fc2449ebc0296241535ff5471cf095e6c29010e738a1102fd10c016aa0e188da40000000000000000000000000000000018786e5549b2aee0614bb9547b092d687b173aadd5d17231cb3d71aeca4f253bf8af1a00945604211e8a9e39250d53ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e9eaad650b55002dfc25e4156cedf321dad4524fb4bede2ca949656cd1023a6c0bcbdea861fdd582b22f6d894032d70000000000000000000000000000000019a8710846ea7e0c69e25c1d7744499537bfedb3a86c911482b4b340278cfdf0c0a51e58280477c8e0e016de615983cf00000000000000000000000000000000186e518aed5ea61cde29fca3fec2155c0af008572053a19c7487617ff344b071a79f633f89881644683570256ab932b4000000000000000000000000000000001405795c44d5c04d076e0120b7b61d297d1392ee5d73c1ef300073c86146e99c726c2dee3abd8f1bf1bcb9d8377f51d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abff40939849a038697f19932861d4a76cc10929bc661505f333e0190c2c20082a53c29494414c28b07762b2993593000000000000000000000000000000000060e7d4136ea2a93f5354e4332e338b94ea8afbeb713ad036f6907bd5a1c032ae8e6f7484dadc0cdc97a4d0f0bea539c000000000000000000000000000000000b9bcdeca3100689c0374e83bb95d7325eb55e61c755b5c2aa7540f1c63e9018d217234cc8437f30353b0d1b7fc44574000000000000000000000000000000000741b62a1cc4e2b4d8bcdd33df2b253845da922abad4b98f279553e60caa5dbee82b5129f10ffc7ff46c74a9759a13451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c62f015bac76db98830b024c7204d1e328293106086fa76418a1f31e0d4e6d53d7a357179de03994fac98ca6f5ee7800000000000000000000000000000000104086c4d3b6449ef507d49d81b1f35e0cedf3aefd7d4543ebc237b4d681bf36ed3735af8cd5ea3d1c9ee26b8a3c382b0000000000000000000000000000000012439681e2f8c76d75b84738bdde804fc779b6ebe2fa64beb28f3ce334b411dff35358839a7ab02c35367a08dc29ee0b00000000000000000000000000000000063a68dd66f63df2067b81f51b2b1b95bc378125f730ebe02456808d2d88446a6be630cf2515f195dc70d7ae029d2d4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abc17b721b7f2f6d3eb92c918904bc014e2de7ddaca1a7f97aae29d255f6e3f4fe48ca0f0ac040930f0e99cbd6e8e8c000000000000000000000000000000000e0054bd8defbadec7d7e0eb14710361322ee508dbcbd3b4d3c0819f14c80f4dbd61d47c41d0880ea0c8d87794169ce70000000000000000000000000000000015ce6029134cba549dcdd9f73d9de31ab8076e2335091e652519d01e3dd95ff498a784c925146a4393665cfbd18db63d00000000000000000000000000000000198e1e9e2f3c7d33890a6dd5b6db5b6c1ffe7b92dc471a537f26a08362f45efc487468d32e98339ae31f86e824f7b6ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007718137e88a2f8e000652482615281b996b77230148b54b4ed4c470053f995a24a1bc4b5faa3f06a3c153170c45d0a70000000000000000000000000000000005d92c689ffd08736f1f4d4f0d942d9e44fb2822270f80513c84640163aacf4fd3b1014faa135c0afd8d55b10dcebef30000000000000000000000000000000019bfead70a4e1d3cde4b64876da431680280d70c8451c4454b28260c2f3aca32ed533a060ddacb60284f34097022f46f000000000000000000000000000000000fa96e17d8be8a521b166f5fcac3289b2cbdd5498fb3add85103fceee1445d143d93c87f9ec9f5f6a390ce9a036cf5461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bf90a4bab9114ee3f2902c4cdea1f69d28e3ff32cc5bfc6e5418065293cbdedc0532c23a45ca27545e5a96ed7f0a6e000000000000000000000000000000000ce224ce4ccb2caecdc8fc9085b2717831d8252ebc045e50e3383645c5a114fa29c24bf01d5c3bc35f957f5b5ba82ea00000000000000000000000000000000016fe0c75a2a9209f603313b133aa355fb52f04ff8a01142d5a97109c9b1797d45769de74fe724897d8e05affc833d0ed0000000000000000000000000000000019d70711101fb25af1a54aad5ce24e386348d62ae0e61e11af69a7f36f815367c4f57e2335cf7b7166d4f3a8509517781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d842fda881df718865f8b9944f0d485d158f1f013e50851e79a67269839897be046488c8704b0ffd8c92393f856907000000000000000000000000000000000ef30cbae5512176bde58cf6d12429435fd3d3b2f469f74f99f73fb1142801c4c3b895ee6b7955614ab01bf34f125e510000000000000000000000000000000001a5a0a4fcc432f8a523e1153619a5342ff344bb9084a79eef88fef94ad4d7c63d3d0871a698d7d634a462cc3b99a0b0000000000000000000000000000000000cbef2c1e2610479d01969f75b1737316afa401ddf2267808563d2214fadeeae987ef2a496c945cfd43272b50c66cade1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7ae002070dff96ae3645c91b1814d82d96aa7b84ba54d7104154e3f6c190cd3f508ee0a5d53192cc70a0c0c08ab82900000000000000000000000000000000113300e634be6ca3679abe1425737026ac0d330f69471dc409b4eb0d586eed89acdc210363ddb211382df2bd8b27150b000000000000000000000000000000001059d8e200b5ac2fa789f0ad451c3b3146a8aae5a6e9a811e05c2542f1a01ebfcf47d7bb985cc0a693e2a949f369e28c00000000000000000000000000000000092015f406ead8e680c79c1bde27efd43761aee2e68617b3308ec947c292023b732a0e4719f531ec61a0071bc7e739f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003865f377e22b6cd97042f7051c4e1d555e41b559b4d3fadc0243982c82ee6cb1987d56413b25ca35df81b80d8f5bff4000000000000000000000000000000000106d883f74bff33c0b9c2e0d2ae5c4d5849256052a39aab503e096a88e4e8bfdb805c635fa77114f56a7c21929f889f0000000000000000000000000000000001713712649164bd47203f77ea1ca8cac9eff03e579d7c2b16bc4bf49348a0ab37a03649337ed08a573176b1c33a3013000000000000000000000000000000000e5eaf92ecd6781249c4914f71887e6d12e28621eaaee4e63f285e93a22f41e288deda63ca7e40305c7a8b9772dbc4361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b28f5ec052e263b10e818435f3e75fb962da023e544dcc3014ca0d537a62ea1df5e69165bb215ebf27b26f4a05b0670000000000000000000000000000000006ff601642fbd93b29041111202ee8c2c902c783148464615d3e9d676c900530d4b17514abda99a872c4060f164241d600000000000000000000000000000000094338d84cb8f6065c1114149310b107885570cb4fb12f5ce43d3528c4e0628b2d388a37b2f76f1fa3144aa90cd94164000000000000000000000000000000000d1b8cc47a954805bef610dff73d66a49445dc7567443c297b4ff1219b3013c9346ed2fb4dbf91117d2b205e48d0a0971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e6b29457d0f0322111fceb1fbf214c8a8edbac56bcd773e4132c0284922fb5ab60c719c93effebc431f2601001603d000000000000000000000000000000000fb178cdabb181bfd15d805fce2ff5a07c277dd51b082dcadf13fa69b465f4e15091e399f459d0063d5cdc415dcd390c0000000000000000000000000000000005322c49cef01a7137ac0f712c393df7229ff74f1021ef67fea734ba7a0bcaf27901ed269836d5a48384e2799d93a72600000000000000000000000000000000022244755cce1a4b1654f56e8bb9f573bdbbd78512ead3960587a3b5a0c50a9039683294263c3bd87c3fd88dd07ee5a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b0f165dcce1e88b9508bcd3a752fa8dc8a01e89f6cda2fd469df3454bb0b49105640303766232160c86e7a3124c2d600000000000000000000000000000000109e54d2e4c0144443b0ca391cca156f2df0f92051d85d6a62ddc611ee3ed7f1598d76e83e5dc322278ae78d9ae606da000000000000000000000000000000000c7cf2adf7873052faa09e2331fe7dc9af81c2062d7d35d9d9278496663bed239a84611cf7e28c6b7bb7958acc74098a000000000000000000000000000000000af03dfa488643cc3fce89bc9850cf96490535b7dc6aa64cb9698e311b7aaea295efd3093a7a6aad3807d0bcba3e4c011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000def3196603d1e047795a08c04c2f645a2c6a56e3bf5fd4ab51ec9e77f6cd6208d194c83b744437e85af5d586b4fbe7600000000000000000000000000000000096d92d089d4c82923d984acb8436a1b3775610fe88db70556e75955a259927ac5051402226b4ca67a121a2176ad5d510000000000000000000000000000000006fca4841d16bf033de4b74f73ece7f9dbebfb9764139826391e9302f1499c7b1566ac1dcfadc14be6879412406ccffc000000000000000000000000000000001753abddf4b24178e91f3ebf00491664e80b8c97c70a26e90419f3880b2f1afdffdd7546c6bf68c04bf83a16b192157c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000777fae0b6cd6f260560c65724985a042da7df7a6f132d27c6fe111c9290f8cecaf06f3624f426250b49b7e7fa89508500000000000000000000000000000000069b4e74cedf01869e6d633aedd210347918fc53f663ea3ef0e53a39d5da9feb616f02aa96016a3ba66b10318e57f4f2000000000000000000000000000000000d0366d217481ad7137df055349a8e9f2292dde0e30610fc19a57f480e6eead369e3cd4ef3896a3a559dbabf1ab766f60000000000000000000000000000000016ed4ca3f38f1435dfdca3d4e63053711660bf1088b6f4f2c3e595ab4d6d83541f0098637a1613fddbff12784ca45e2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7d68f815d6e9e670dd2b3f9e254d5385f3d36db42e0d8c9dc148c41e7564393330d5dd7bcdd099a64676ef2b178304000000000000000000000000000000000765abcedc72d48c62070dd2c2b81ccf0211ca302996ee77b84294d7491f15f005dccb03b994f79060b8392649f48b9e000000000000000000000000000000001862ab3ffcf336cce1498d82f7d72ebfdc28c6fc6af7f8787f5a71ce36170a243a6b6fc72b03c925ab0669a96dccb3360000000000000000000000000000000001a273b2752edfd56381a1b106fe1ed691e173633c3d463c211d474537ece36ca0900b933570d64d6113f2170ac3da971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189ddc1115f06063281e58e42713da114bcc7fef3ba4cc973881d0f350d3b4f95c3ea1492737b6fa0b47ed6a5dd79cc7000000000000000000000000000000000a5f0d7c0014c0a9adc1f9b2247260bc5813b64c0dd079e523034fe0bf137533757c3e8cd23243ca0c0df9e00cbff3e70000000000000000000000000000000017223b26c89a4d7bbfa44e197c2f54890cfc9bb9d1136a7690b8e9030df9432421dd9280e311d6a1470ec0c36f79ab060000000000000000000000000000000000484502cec0ad39ec237c83dfdb99651bc090b42b8a7edf1e15752a726901e3117d616456d313c3532dfd02bab2555e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cb3ca43220f0e79eca8ba899a19dcdf2aafd3f7b8728506773ca9c458f8e2e3c44c72ad5f815365d0b98a12ad95244000000000000000000000000000000001683608ff07d3f38dfd3f11cbd368d207139eaba6c5120e18a48bfea68b6a1e3a2c51c49dc148d30b11f69099689ad9e000000000000000000000000000000000426ec6debb43f340c5110f830bc46e2fcaa723ad2bea1d0db3d98414d46172af100cbe27d71e208674dfdd95470f817000000000000000000000000000000000978bc27dabf88d58426510ef4e5e6dece2fb22151df5a8af1ddfcb05a9abae773e94e9d9184881ea9199b43bd2f30941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066dcb061e83deb38b45233b2fc41417f44d3c7355ac318dcdb122b85df57e4e7d649115b62624b9da4b27c78b74c214000000000000000000000000000000001162d37e829ef40bba082dca59b0c3541a354a31de7f745a3b2e976ff5986ec26f4660f077ea9c7024c912e4616a1d0d0000000000000000000000000000000001ff168f874f3eb9350958a29dffe6a12cd5e262b79f742249ed5f514ceab20ebd1f3451270be153233d02926d93f3bf00000000000000000000000000000000056a0913ebb34ae39fc33691c98805dfe1931d9cad0ceb19dee33fe4a1e45e44863cdbac5d31eafbfe3363030c20f6bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078be24ae206e04e873c8957b9edc91a21b53429dd25e60af0f505c6b7ffb91db832dc283b5e256a080fe295fe41ab38000000000000000000000000000000000caf223a522a5b9b3bc19a4d714de1ab7abc1634db8894ec56654d98d1d5fb5c2c3cf90aa55e0ee550f47533b2aa3d5d0000000000000000000000000000000017151fc25c8f05d41eb4a5bac124ab137061ee13c29888ab2bf111ec468c7d4b02aa0c085d09cc6e45fcc786aec82d580000000000000000000000000000000014d8f39110411107f058cc31b6a3cac03a7d5bcce23e4264b0b6a1e5452ab5c3f5de123c5256b5757a0ec6d3a9bd1ca81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e73ab575a40b395c247fbd68b4b0d23163c3c30dc093be7aed74ea588d89361a785652d320c5536077d5a89ae4c7a0000000000000000000000000000000000db8c81c0fbdbe4e45548296e36fce418fa559e4fa82272a9e578ba671faed797ea46cc08e572428c95c62ed64cda67e0000000000000000000000000000000009643e46ba839f2d3004405f334eaaef1d2ad888a2456d63e56b5b9957128498d9eed6111062dde4b9fa6344c1748093000000000000000000000000000000000d2f6f7d6c67391b9300bf69f5af2558434fd03cd370fd654699d23702fbb3f33e6b1608c12747000160253ca8ecf5c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fd247e8e6ae9b4e782b5d84f191f8f5b3a59bde4a0b9aa5fdd22f6597db0dd14a58813dddc0bc5a38c85366ec7f7e200000000000000000000000000000000119c254b242ff185465fa6e081486478d7148789dd86b38e5f75721af9d6baaf6a2679214316b5ca410c60900e33599200000000000000000000000000000000049ac54643db917c4576f724392b86070230e3a081dd94ae70a71ff6ddffaab4b145941e3047e3b4214e92c3df6034020000000000000000000000000000000013498d131a1da8155aa7faed75b7d55b2b60d0b79b4c199de4da6b87b82b90844a5531758b047628c4cfae136bd1413b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005865fe0238422b1da4ff6ab487fe389a5eca786f44164c9ccbdd7bc04dc2d2f7b9ea65153218757091c6402508590570000000000000000000000000000000006ed2fb68e7348168004786796ad4989f6d1a3255fe2d25c4951909298d0fa27666fe21a9e34e23b0db09591dd63011c00000000000000000000000000000000107b541ae7945cc2658836755c7adb4259754cc3f6a0a067fa05d90805cd1be339e81ca122f645b5e87fc376c9a3a4950000000000000000000000000000000010d4b65e277ae18d05cb9c469b749748ec2bcbffd2d661cff9e2f571f43c13a9a342e896b78121206c74306a2b98f4d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fce34cc72d56590fa28777db8af7d3a627f5802825bfedbebf9a9d32bf6ae41551f9da2cb81d993cb4d49a79287d580000000000000000000000000000000019458052d819c1ff8d686d893681b7f8411093071c6b03e8619bab346519ae880ad8c8cf50ffd2061caec0598656c06b00000000000000000000000000000000119a1f8007847c0db8774b6d0f2aa5f4a9c12991858927641ec4e7386c387d302eaae74b99042212d2531b300aa78302000000000000000000000000000000000ffbcf865c52c616ebba4236221572d57de4c98add09eb069a41cd86bcffc3450563264927ea45b5aaac5e43765c91e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5bc66f4d00b0be456eca378b5d27b97ecd11ce0e54619e7401b041b22f31731491ef4f50073823f13476be03a1da1c00000000000000000000000000000000113d4d650dc4a031fdaf180f9b8740a99721190ebf417788cecf17872319f40d27ff04342b4992d7ac91c0275ed302dd0000000000000000000000000000000009b6dfb4f31e9f93d331bfee7cf56bdcdd3e6f36019bc5344b8089362edf3ea6dd124030d3cc378281a62cc7138ae51f0000000000000000000000000000000002845de987222a9bd6b69af5632a839e43c6da4ded2e11a4fa55a093bb87d698ad1c53ccd332ff6932aff2cbcde68efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000573d3c745c6f0d7d155e49301f1db01eb4c31d3650ac1bc4c061afcda1d32b2fa4250ef3f206667c13f31a9edf1c90f000000000000000000000000000000000787a1aa0058b38e56106aadc185531d3ac75aa5073b46a1ccfa3a37c000778de7bb5116681a5e2cdae7e71cc17733a20000000000000000000000000000000008b4223ac3ce99b30baab19d00a0faaf46a2ee9257556b54b88e77c202fa77dae0465e5d6b59ca6ac43b0078959c1bad0000000000000000000000000000000000cfef6f7ade50d0bdf917bffc23f59c1256275620349a26b7c4814ad745cbdcfb49372fe2fe7a3c5f8baae14b1397401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eca2ec40415418a0b00d7505d5d49ddfe6af6e1403eb8c8075f666f52479bb0991444f3c0a34daba899af7d599eff000000000000000000000000000000000029654062ddb405e9e0828282b5a939c5bd63358700dcd14d40d312fd0a24cb5addf656501dba301087846e462092bca000000000000000000000000000000001148dbc03051d355430ced38f855119d4781c219e011bf40b0e14eefe3e40d95bd3d3a4362171475a56bccd2822805210000000000000000000000000000000005fd9d7bba5b16749c324c33d846b1d923ada7902c5e66877f238e60fb18281e888b37218cd831ff288223ffa9eed4b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c868961f18f02faead4479c0a95ca9bc2d7fa9f038eedd645d0a69e41169e40e47c036a53746a697bcccc9433b3cfc0000000000000000000000000000000017dfbaf1c07e26411736267f0cc8dd0b10742a2fb388223c295b6f9ba34c02f15a08cc8a945a668c8abf9925f6797ee90000000000000000000000000000000006504aa29ea99589a7f70bd37a46ff658688d3ae23731a7959461e0ab8d34eba49964acfa4904208deea19c48e498f100000000000000000000000000000000003c6e943be26c1dc313a2d544ef9c5f77593125f44a42d8d1e41c8e53810f88708fbef275490be616502c8468041d4dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f646083fff4e3d6ba5cd860682f93031d3332b09bf561d8df2cba9bc6f58f866bdc87405689bac228234528ba2acf50000000000000000000000000000000001e0e095611503a7e916bf04cc85ca4461016e419f04ad6f8389a5c72f9b924ac54079c9f335b288c34eefb8686795de00000000000000000000000000000000019cee62be31a84b05d242b21a6772760b1e9ef2ea9bd3225f60b613a49958b86ec368549be4acbd07832adb7bf3bcb8000000000000000000000000000000000976113df5c659871ef972a42cc7e6963e0f4217667cd0a5d7e923adf8d0cc2eb7e8fba8f916f64558a9518c23f7e9b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009b62014432021ea5e304db73fe988ab90a5ec32ae7f13f79ee732edaba2c9fb22f9085019b2a3278024cde677041e7000000000000000000000000000000000a31fca503715ad271cbe652de608c8e9d5825ee7b04a40a1c708a438c2ed96d98dbeba1d2b1cd27859caded1fac9d0e000000000000000000000000000000000d0047285f64738e752642ade541a8332a5ea6f7dcaf6a3f6e0d4bc3ba8c5f185ddad68072885b79cbd294efc3efaa4e0000000000000000000000000000000010c6f24ce85bc819a3519d5f4f31457a40f110a0987137c7b479dc21b25b57ebef55ada63daa4f5589390b8c50c9ced81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2f35e28c64fb31502e504dd16867167e91bf796ed1fb7c219b26a380ea34daa08a2af7c1fd5f5240900b61e771b0dc0000000000000000000000000000000000b9ac468ba0421cd63f817e56bc75e5d939f3f0761e0eaa884041175a1400090a5fa6f60a9d091d35d8a9efda98232a000000000000000000000000000000000a834bf52722c059456a6a5e5c27617fd3f34e5549966224bfb1f0b103bdea0efd8db1657acc28ca79d3bf93b7017a6c0000000000000000000000000000000009864fa7f76f6ad5babf6b5c1e313e618a0c860efc2d880bcf63929308255e8e69da502e675b413a17109c1ce1a175bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001057362300cbf5c5cc9755fb6a0c8f82932dd4da6efcbbea52ad30edfe0082d731195843c575fdaeae786ba15dce3b7c000000000000000000000000000000000d27048d7a9c36602bc97d42df08e34d45b7ab097f1201857d788146d0cf7a759ec9d9c151da2e83561cd2efdb92372000000000000000000000000000000000198e29d9115d2b6b7fb59c05216d1f35eb0c1ab9d123fbe1688d883a32c84989151dac23753ce0b3002b5c2f3cb1e2f3000000000000000000000000000000000311bfa53cb8233ddbba8cf52bf7aa4785d9db6a19a3dd84c41b196dee13a5948aa80f04f876cd25c9b7d97b1bb249781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091fcfda6ee019a71cd4ee26b7552c0eab8a1f056702a80d23db19e9b10f5d8c68283c34732e5b356390387548dde44200000000000000000000000000000000020fbcd1c35b9cfe000f6ed8eef438f8d73d281bb4eae18e8c53bca70fed5782f588e0ce0815472168b613e83763ee8e000000000000000000000000000000000e57e3b4f558924ac1c93fe2c0eac2edbf53bbda1139ec2073af10337dbe5ca1c9aa6b3d0c6a276f1ee32d44dab890e50000000000000000000000000000000003005007d5837562b10432889327f8f5e1a69645b7f0ef737949fca0abf42a6f92ec463534a8f153f8a3f48d0e0542931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d61cee7f0e3703ce621ab56fe946e4069409673ec30d221534239b16daa9026ffc924ad3e1a8d875be4398f1bc164800000000000000000000000000000000009c5414bbfbc11fae7b74061db6b039612c77314efc0515e6f2a470604cb6268e27b6f6efa3d3c851d89734d2f8ab468000000000000000000000000000000000d898cd8286930f55c07d3ab481bcec5afde71b40f30ec83861bcaa5f00a28ba3dfa86f8efc4cb9c9d35481ffd160cf900000000000000000000000000000000059830dc41bfe09476863c6bf42fca0145a194845d959c28ffcef27f40d79851d774c6d445d54635c4b52136530609991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116bcc85f3de4a7bb502694425b0cc53702f0cc3f1ce8a89b3f21301c97e290bdd40f920c26f0f3d2b44c33f5b71067f00000000000000000000000000000000130ef144706bdd7de3f639621b4772d2748a5650ea95c9514a247e649a21978575b32d0c50ce1f997d16698bb500669f00000000000000000000000000000000127a6366cebff9a7b65cc902e3704d974d024c7b75d4954644d89981bd015c9ec749cb785c82d79f35ad8468cebf96a80000000000000000000000000000000019ae7097fc64cad02820dea663a58e6bff13ee4a4cb4389754f888614b7d2a5ff4b02a37eb428bf319d6873464d92a171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049b52beff42d57446d9bcc967fea2052eb55721e8d89a93d67fadbd79270ce9c5702045d3dc00271a07318d6bab7ec80000000000000000000000000000000006c3f4e4a229416276a72b7d8035c3ba6a5202774e392525fcd630d3eeb35258e7aa854979464497c024f2006fe5df8b000000000000000000000000000000000aa14f5945a7976b6cb68c1b3c5e29b983945e868befd4b055db43c1ab68215e9b10e38d5203363d7eaa82f260cfe61b000000000000000000000000000000000bcf2914427f76a26068582e6bca484b78fa6ac134673862cc4a51db214a3f50280a815812888bab63b7c0eac55552ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000677555797c0627a120f7c8e1948e0cd56e9d1a404fb59bd4e9ab6820f87d0c3a66e38d4146a95de0dc8ad6fb2cc5fb40000000000000000000000000000000018bfeca1c774a454d6387bbecd9eda3d479f978d7d61dd9f1930dea4479f597a126a25e30f7dc89d0f8920fa2aaf82a10000000000000000000000000000000010eca98132284c3df31b3092d813463bbacb2e4e94ff0b551a251a2341dffd75bf970ba19777bf58d464530c2c8e75b3000000000000000000000000000000001113b849206ce29b7977b9d733b745a8a94bf587fc88a1934554b9ac5dae09ff733612ff69b70e10ec1249fc5a98acc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133c811f9ac0fc8c2120de60cde48c467ca5e668198aab0d507e321cc1299ad783b87af798de9526ff43f6427f9c9772000000000000000000000000000000000e57e5feb6eef8463f99ddc6f9fdd0c8c95eb10a5159059eba4835d522ed1055458176527fea044a14bbafe72788154000000000000000000000000000000000086381552e3e5f747b0de26aa3ff606fdf470c8f3fb5bd2fe32a2c4676ae9bfb899f1be405f79e3f32c54d940dc50db10000000000000000000000000000000016736c2e328873c987a9d1a777b6b9025ce7ddb0297346388ea6283afe68b6f7118998404b5b002a25e03d9fabfe667b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bbdd418783584b0f5c75e68015c63a28626b7a6021feefa6c5dcad0f1188ed559245fec5d678f00e41b8e45938d74f0000000000000000000000000000000015853bc65e68363e78c2b7e75e0b826c9a01721ebda605a6bf292dc4c48cd484aae92881bfa7639c995975a59c92b8060000000000000000000000000000000010f1ce4a87c6a3622844769e6104545c45068e91e22ef0bda4510be21fc61bcb66ccd19e94ca8f01ba20da89ad75de9f0000000000000000000000000000000010acd9cba7fdcbe38e8f9bb07b71ef1c79a082d4d7d21aa49166e3bde0c8e4ff35d7dfd4c5144b333a7c9cbd431391181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc9bb5399e922540d7f00cb40df3e8f5194cff2c8ad86d6b6f5f356ee2b44bb213bb354ced372b4fefad42dbcc157e50000000000000000000000000000000005b86a1a5758146afbc52911c5cf7fffe3b0deadae6fbc830597be0431ffe190db7a6a7b13c17fae29ee01f1376c0353000000000000000000000000000000000df8d8af518013f1c39ec0c8dac2ca78334cc8b7d36ac57c892862a7d4cf41e232b7399ea275204f7575976ed5a236420000000000000000000000000000000003ecdb633151d2631e09e65c6e60531aa81b8217ac2eb9d4c9c02f3c1491623c840f9a9047695b55e0536167833c80861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167b2acdc1658ac4888d01105cc027ead3be1219360ad2f3051d5bcda6b0d40689143782099e69d421139925c5b626e5000000000000000000000000000000001869ebbd1a45a542c69448c25d66c996ac93db6448d3e5371d23794597853a0da438b4bb445ab6e25c66a4b12169ac8b0000000000000000000000000000000002ed09ed34be4571563e430588e0a06fe8b986913ff6e350156a629bddfc156e58a4c254b3ffefa479328ee461e5907100000000000000000000000000000000150f09fb1ebb0c4583a9bf5b0b94649e78a668fa3a0b484aaabbc046d72c8a5a8bef2528acbb02d0c6657a8d88e9b9d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128fac6c562713b37b25d65b39733d48cf26f9db6e04f86ae5259a9c4a81bc022347cc72d686eb28c07d7c699056e925000000000000000000000000000000000a4708673fc3b587d9c786d26c74052510f214f75ad4eaddb820ffd623b25c7cc65b0020bb7e2a963dab6def12439ff9000000000000000000000000000000000855f569da42b2c6368383dd5cf89471ad73b7e06320c51b5c2b60f4ea73454f22c1383c730b791428ad745ca539668f000000000000000000000000000000000c79e2f552fc22bdc70d056713d060b5ddf808cd430e0f6811aa1f7594fc73244656e39c0e41704262a33d45c773c7bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2c3b9e321c6792837de46f3cc80c2f0e40a6b53599954caa65aef3674406e47db224e56dbad8ed74c87965f2b179ed000000000000000000000000000000000940dc94e66fbaadd5cc173b41b267a540efdde17550798b5e00e3b1b5b1021f5d024aaf94b438a32fca94f62f64e5690000000000000000000000000000000011945c0cf903972bb1549e5cde5fca4b65433c6df78eed106e78ed13ff7bf7e91b2592bb132d6479b82a4a25dddac025000000000000000000000000000000000309bb2f3cf059ff552d26fe5b3d6af15ff9a6872440ffae64088e00cf8f6503a09c441ba626fb16c8ea0f8f27d03e2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053c7c7cc29789b497886771b7956959437f8f30b3096977fa0afaecfa7b920ee0e4f10029f1b7044931be331d56e84b000000000000000000000000000000000a65599eacea617f1ddfac947b928b9e638838145cd91587ef1aaf40779591ce9328adf76fe9af573e839ae9a8b78e0d000000000000000000000000000000000bfc7aeb636b07206067e415aa7be74190ad13a7db71c869fa2abf756f8b0671bec8c5581f70de87f277f60de44590220000000000000000000000000000000003f437da111e8a98e22847a849b718e1481d95f33e9c0301f7e9af0fb389a823fb2f020fec7169d332e02aaad89f5c811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000276d9568e9a453e5e912a2ef3d0e0393f44354b876ba00cb4fa5a4f3c78ab8674d36bd08c358b7e29e6bf1d060d55be0000000000000000000000000000000002cc809deb00924be412d03d09e3dbc23aca77456cb6a92465615eee65e13826d5536c16845467867b37c21c52724c9e00000000000000000000000000000000102a3569bb92f49f760a2a2084081067c693dfbb9598b4450d272e130643e2ca442637aaa27e536297abde363b484fa1000000000000000000000000000000000b81ba1fd771dba95e76fbad68abfd3eac31f2a361d85ca9eece02d2763c24a60791466d77853b1ccf5f17cd49e377bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ded75a6df70a72d41b99cda6fff97b7f40f2233700e7ad5fecf5460cfe6fd9447289848658345f029581b903fe91827000000000000000000000000000000000af19b9ce241193cdc1d229849ea8f52a98be4254e8aaf9cbb8e9233cced5f4bcb53c6d5e6867839e9fd630dbd85db4800000000000000000000000000000000032e13a3377f41c9544e99b68c31df0e4b3265c8e546040382f817584e97f0804a8f4819b2afa645907603d87d7426be0000000000000000000000000000000016a6b82210834d16ca9b75ffa17319f4b7abe9e27d670eb6b084de10184ad8f1cfb8247cda957e1cbd89927d2c6a11691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1f36063132cd14409372133296b82abb09c954e48c0436e65d3825fb1e97b21a447c416bd3ef5b30f1d5cd31ac271a00000000000000000000000000000000177953cbbbf705dbd469ba2fdb49d1116b12b9133ba8aacb58b6bf8c7a56f3fe552f7622a7b1337230d4740ffce0f82f000000000000000000000000000000001535da46034bc92cf6e8cff61e59014f531c1483e6fb2c5dd3c6b90898694ee005516fb05ecbf7eccac210a344c19259000000000000000000000000000000001761ac0ddb458dc3cac31b321c6746979ae08608f86e0e59b84c39c255635ae3ff4ff0a01e803702e954db2d85e8f51a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026cebde043b9adfc001abd772a5847ce72a5671261ccb809d638f1f54e59860364b15c1a0b363bf927636ed8381bf69000000000000000000000000000000000563f92b65660a1d62702738a85fae4ddbf92aa3fe2e3754e595650653a297b15b07b642b023a1676834fc8b2bb50f5d00000000000000000000000000000000048405bf169c9a765f0ae653cd57c8f2a928088f2a2ffa516b52075dfa1e5f3fb6f5c15bab6c45d8663ab6f5f6b37977000000000000000000000000000000000656c03c520a01b0632aae184f04bad70be7e7e12c4364c411db7af5f2e50faa65d36d0d49d3e9ab6c92df52fd5fe7521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f68b1c74be63488305cda0417131f23659927b276a3a8674ed03eafb2ad969e5e824f2bb8e50b5e2873075744d2be70000000000000000000000000000000011611f02d72abbb372660c79cbcd05c0271ad8a4eeb294d50946f08f1314266c772bf1a8fddf7547a01dd5eafc6ad76b000000000000000000000000000000000f5972127021fa24e5d7a819c6b457c171b3c538294b8f1c26cba6d75aa82c207a703ec097c9e9172a00c049feb0055d000000000000000000000000000000000eb3503f69471516387585a69fcc553ee4f367d67412da7f6ebd65e13f1de8cb782c540cd090b338e14a3b1ff1c2881d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011474a5ed1ccc1e1c554786bc61efbe7f24008d23a5b0bed5924a8df8e1f80b6202fa51e5fc08fe9bfb3e6d9d2db7e99000000000000000000000000000000000aaab2537c020f72e78ef34c253f7344a124998be9249121301bbb87dcee995659afd65b913749067fde70ed61266a690000000000000000000000000000000000c79f362a55ba6ae051eadcfbca2174e1d78f0c416ac1491542fddd3b32d20b5c6c28814c675b333fa0a3aa92268dfd0000000000000000000000000000000002cebce9fb34978cf0b5b69d0a41b3848bdb024eb0c263799894f31b2c84e7d3a75397172472ffddc0847d7af7f17feb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e9c29ab7719f842bd439233a6edb540c5e3bca29e9813050f6b51cbf49ecd4d606eb82073c488198c04e67bf72c3b20000000000000000000000000000000007cc2ab4c03a762ba1dfd25df2476ca9fee77c0a9c3069d6e9a061f2913908831f19eaa5a9731661a54073f5e35e960d0000000000000000000000000000000017928018662eae1825abd3c460d02c9abd8c2580fc24ad2e1eaa1db3448ad9a913f162fdee3e705643c9cc1649aa245b000000000000000000000000000000000031c2baad28c6c7311b7d1cd22e5c7f5674a9e857210ae6d7e764b3ff802f1a271653ec15871797eef46cce1c74295d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b88e9241776f5f8ec1989ba1da8592bc3e42c4c67bc15bf28cd51903b2ec74ccaa470a1dacafa8f1da908d2e62dff4f000000000000000000000000000000000ce3fd106496c3d4b9ab0327e695b30f6827afb45c75379206fe8ed8b81664440accdd37a76e0a7eae6a414f612ac8130000000000000000000000000000000018e066eb37ea89ae8baed435e9b07e268c66ae227ce0bfb720935140f76baddf9e08ee390956cd112a6d34d991044ade0000000000000000000000000000000015d3bae286dd8a166527584cd15826540fda53b40af71e4d559708b711d589a356b4ec46c183a244dc15fe4b90610c421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103d64c1685555300fde5d9961201e76c53cad947036149c003dab16d09cc2d9bfdf1f83a20f822bb694d1573b5abca100000000000000000000000000000000152660692870127e72359f6ca1d375d580ac3983febc904ae0ad0350ad31a82ad78f8e7d4a097992884b990ecba556b60000000000000000000000000000000004939c5cfc08f76578983ca59d14786244fe8748a3b47f068187667cd37f1f0e72abdf6741def6e1384c308df10916e900000000000000000000000000000000054d5e9ccf0bc635e1fb4570c67fe00cf571c901d59090b5f44f8eeb42f05f62aadbef5d10f66152f05017159c38676b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000318cfd3bfab1360eba1f07b898108bdb5685212efd1a10bbb1e30aa80a28caa9b7c8799c60f9e606ae016acc55c22a10000000000000000000000000000000008d7620147280eb8562ec97c6802bec3a075510e85e5b6dd2c30485e0ddb8bbaf1a3b6d013900c40c0ab9c5954f53eaf000000000000000000000000000000001150c79e35bc45d2ce7ef94c048d6aeed09d55a45b7e22c053e82f7be06f41d314cc5b9f66bed7de7f260f4ceaccde0e0000000000000000000000000000000010f4792df33198a61964a81759260ba9c6b80288b8e1b4c133604c9b71de4ddbab315c78bc3c7ee10b5b75f44dcdbd2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fc853672e07ab70fcfc7c7e0c40b349be68bcebcb3a41632791c9f04f1d74c125c62bdb414d77d56aea5683ce636a000000000000000000000000000000000034826e0493904fe118f444555f85a0baa08bd88488d700ee1d0750f4749ee3fbede4a45adba1884db7388c2ec2654860000000000000000000000000000000011e5941880e4c8b8b99c8bdbadf695fe181be75f1f01249ce501186487960ac8e49d35df9796b4220394b8fa72c90013000000000000000000000000000000000b4dab793a4a667d7af2022bc5e18fc8d8a7879b6857cd0d427973f147dcded42bedab845a708002b6f28a8352fe9cb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c9ab495e5fe7f2bd342fc2efd27490a455079801dcec626af30419975c37f1684f72b5acb41ef98aa56e6482fb270f00000000000000000000000000000000185b4b1668c0e0ed198d5d04b95a3d3a389c801e093e2c1b5727b0ef36f3b99a804926426d6ae1b791f9f06e88db58200000000000000000000000000000000002a399f8dedfb0851f1b6e2a4c23304b16cae8eac6b6b770c9f71a32a48300e209dd25011f2d94b748b95789dc91e3400000000000000000000000000000000000b78c49e9eaaae55372c80df92aca504b7391f10f9fec1dfb4ea63b35c15c09c4c1c4c0743173b55afd987e64413df61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c36d184d69756a2612eb7556537d558b332fe008c635299d2dd81618662803a3479d11eac43ac591c70bb5d4cb1137b0000000000000000000000000000000019243c0afb079774ea0248ffd86d43d68ab9e803358dd1fef446b0d7208e2cd2412289c546028ecdf7a5deaf56175d59000000000000000000000000000000000a500303a89da3795c41e7353b91f0f446ed0118cf96e0907c7022fb1af187e99d74fc83764bc8831f6a6a9281ce398f0000000000000000000000000000000014f08026c48f8485dea8ee48f78527a02a39aad64763e837b99832043941c8b3c0c962d12e5a545a0eb1316b938f16fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052c30760aca7fba6de13ee17ed14b41a2bb32423d4846e0bd19abf2d058589ba504d95ba96e0596a0be12414049e353000000000000000000000000000000000bd79ab008494216b3c71b1c614338f2dac580a4915d5afc2da53ea1d2dd2034e0791cf69a0c45aac015f62fadb4e7c000000000000000000000000000000000166f8a2add5a19b2b4024d9adc20043f259c92384324db829e09e7408a21f42ac9799a9c342629c6363f426902623974000000000000000000000000000000000c2746a502f50e7633dd983f4ff389b9ec25308b96561c97b480f95271974be5d27da266768fd771d2c784f93cb233591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a898e9bf6073147fb1e60102db677162003f1abd25edc5fa5dd6ab049254d4524f2d8b556d29fa3eca6435b05c979d80000000000000000000000000000000001f5ef70cf6a1d05e5aa5c8874def8738b0db2cb49db7c9af351ebfd204434331de56c6c6ef98de04d436fc5bf557fc200000000000000000000000000000000051dc3879cf41087d579bc0e8a7ea5e9064f5841ab44043afee45c0c4e3b32e11720f4aeca328ea39aecef743fe9b18d000000000000000000000000000000001383c1b6994087d9a0dcebfca28eba05350b71ba2425959bb064f868a782a36aa8a63e45a08503463553674b1c821cb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009412cceab3a86856160fa4bdeb1d58ff1820523e691070850dfe1b103954bb9693f3b3041176689c57f9750bcfdb140000000000000000000000000000000000faca7a963fc6683388a896c30e02d7cf1f240e535eabbc3097ed183c8dbda4a4a3a12dd85e4c3022523e2a380ada35b0000000000000000000000000000000006c4746f6ead0992092871bbda492de9cb83385090bafbd6b0fcabd2ae1ffce99ec57535a4dad5c7f2db8486409899f7000000000000000000000000000000001129304e49fcfbcadf136841f097aa993179013aadc959a2c591bf8a1e641317488464ebad805ac2562994e2712f1c9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f5c2f7fa387f1eb2a22fc25e84dbc78ecb4ef72827e3163a3a5a693e336ee722efaa857e114064b4f8a170f628441d00000000000000000000000000000000186b1670491a0ff4a1d9da4d22d35fb3924e47b2839b3c531ab862456e80e2e6854bbb232222f42de1cd85706762656a000000000000000000000000000000000f0851a5c8dffc773be9a02500650b8a7c3af338bd334b4acbeefc5e076d60290137c9328e132ad61e04ed561071407a000000000000000000000000000000000e64ea24961341d10a35700dd2e771ea7f727bd18c2c0211aa8e64df540d4482a3e5a6dc95b24bfd136b3e082523d8db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002c72b172c14d6ce9a4acb132a1263a2fd4c331596657542335bbb149193a8d6f66ca6c2f0eae3e7ed77388b204c669000000000000000000000000000000000cb8ced85fd739869e64a13d15a331172589698d6019963e5863e9500098e1459fd1f960142f5320403f50a43f35cb4d000000000000000000000000000000000e4130995bed7d1a94aee38154766f36cfea3ec89488d2e7cab0b3205dc999ade95e37d1ddba81e496eb298b9a2a1b0c00000000000000000000000000000000103548e88f56e2d285fe630000fba9f9b0b8c0eae22c307d6e4cf9af75f282556e4ee02bb50486990b9b43a0624d1ec81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000273eb86e28dbdd6b2423884bcf55c83487cbbbb853418392cb6656f4f440056f8bd4c5f3d53cc8ca217647f437645cd0000000000000000000000000000000015d85bca79db13c5b3b7a889bf50ed9477def0e17c316ec2d5dafc039df11ddadc98f109a02d4f71680f402ee24d576d0000000000000000000000000000000013ac7ec160094d25148263a22483e84d88a36651facd83f03b1aeeece8d0fd93c0f084f921175c1cc0bc1df19e9c12ba0000000000000000000000000000000016b110d12d8d4563e972bc0886fec621c2ad3544c508d58ad424f9b80eea596799eeaf7cc9fce77ca6e35c43ebe171561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd9fdb238ff03989b23a6783fc0b0de69de6b295141b98cebbf5f0fa2d316b3fb7698cdd1e6ad369dad4779ef1407c1000000000000000000000000000000000ff358ed45aaa6da0e2b43f850aacd4aa46a133c856289053d3c89134c6dab82f0398cac0df68bae717c4f4eed11751d0000000000000000000000000000000005509f7b37e168a8b03fc8830e9cde61e544b13e03b08d9fd0972ffd34cb07d98d53fee794382faec6ff58f3dfd86928000000000000000000000000000000000fcf3d4e7e1501387c4ad71e146c2cb03b30465fc3c5191ed4e829e37a948ff05dea484d969167a38fb63743ea7426d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bce9cc56a47d29396f85fcc71486b1737441f95319cfacde19d7fbc53f7a053bce166ec2a38b84fb6221a151543ef3000000000000000000000000000000000ecfcbba6fc001bf16c004b45b869334fae017a57f5f038359633b9c3524f6449b7476c171ab23514e995dc88f77e1f80000000000000000000000000000000016ae2f78dfb78b606eea0ecffe24e4c4f085b49f3f38e41a8d6697e6b8dd32ddafdf1d7eb9ac1755d7942396d6f5e5a40000000000000000000000000000000011223f7d0410f677dadc11718667557ef3cbb8604b0519835f6853b06aefa80be64330ccc3457b7fc3b257cfa8584b0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1a54fa926de77692d75a3cad9e71be514a3b2552c818ccf6c7fa2408afb6fb9014d2984beb460e9df5c7448d11f8d00000000000000000000000000000000014776766c096b363e1cd5e7128823a2ebe879dbd54face59eb5976ce84901fc5b9f2555a20944ae49c1240473717c17b0000000000000000000000000000000015a31c692b8f24d999ad4485fd1e6c49d1f4f3bb6dfc7f9eac3d20300bf697649a3eb5e3c8466f77096595b4d40b3e2d000000000000000000000000000000000c4a57c719b3262359bac95e3121ae0c651296c9bde0c91ccb6f734692cd0ffd46bbe64c37247a3b754a11f233af37451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dc66929e95cb6bb55df334357a7749e5860a0af7df982361c76cd6ee988c966b25a9fb1d8e2d3db9f3248a3496cdd90000000000000000000000000000000016337a847d4b22165257d5739c8d3737b846768f4b700bb9dea3a9921f824555f1133e1503c8f8ff361da013c011cb3c000000000000000000000000000000000701ca35573a82020128bda1f7f339c20a1d0f357dabec6c50394ef9e2ab05a1acf7a1e527cdae8ef7569ae389d7810e000000000000000000000000000000000bd4b9aaa17f6f93255cc93d118abd364a8dc9a1a9e94b794cd61d76dee9e977d622caa43442edfd2737e95a2c5f646d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001150376664173958be2ea5d309142561dedb2bddbd0aba954b6cbfd9db3759c0940bbc79352044706606d7c7a3d03ba3000000000000000000000000000000001636000a4b9423a751072c304051b1413434351556ad7e58b905f46fb0362861303abe34138370102497c16d186c5ccf00000000000000000000000000000000092752b76c60fb756feb4d98dcd5a776c68f8f8eff9962ad4d613007be0d4734fa5dff1154e25271287f7965435771fd0000000000000000000000000000000013637d02a5d90e2b160fef32b57d4aa271cfba5dd8ca373af7fcf3724fa49a7551790a5ee5bf54f5038ef5d75b01a24b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017051ed4d39e0abd5c3145554c90d0a4a478fbd9685572fde9d71be1a4f9815f4e62966f3f2358bba3d46d73d8ca54250000000000000000000000000000000010bcc4c0b57f90257fd3b62c0e79c93da0e5b17de9e4ad20a8c1661b182f7f838e460a34930115f264870e2e03322928000000000000000000000000000000001256736af16c9490b18c649ac67b5e1cce4d20fb5098aa9861d668cd502a69ac2424ded4146e2f08f048fdcf5da56a580000000000000000000000000000000004f81b24a6dd764ba19eca06df9b8fc8710a5821e31541d8c754acab7cc7ff01cdd66686b01ede62d2824d0c185623c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195ddb1687debed13e531a304727c3f30240e17a1aaca98e517191428c38f5e25a735833f582b6bbc9486b28195a3d82000000000000000000000000000000001092620786f7846ac2dc228269a948a4de3da3bfcff07798a6fa9377c4fd879c46d4519eb0bea59bd49e5d4eaf86a1f4000000000000000000000000000000000ce50660ce6d3fd708fb3ba997b1185276ab8b05fc7ad763d7661bc64f31f0b33308e12c7e8ad2fcae7d9fe24347e40f000000000000000000000000000000000615c39aa9d1454e9ca870d896c4ea74357df18c1c21be9ba6c0477a3b8716e2c8a0e31f460236b23f6f27539d1503fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001955e0c0f1896185ef15437d7198abc66ba02647a4ef4af586c2b7750d71de0d2d39fda884791b0c66a0275f93c26bea00000000000000000000000000000000180176eed7d517031ed3a30a0c58a108c3616e00f6c70d8e020377500b2c44dfb40a0ce049021db1440dec84845bd59800000000000000000000000000000000135299be63c3e74f91978b9bcebad6c2f35378e37528ccdf06b1bd1fbf93e8aba219b40332969d1fb46a77b24f05370300000000000000000000000000000000080ea37e8a2a4f73242d764380a6c9b79b26d936e81977e6e2600af076f7c231d08b5477e7861482a54ac1e64aece7161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133a8dddab8df4f14c06f5b28f117053b02f61ef8c9da1356e3a81f81320804db033e49bac94a5f1e037b4104db396390000000000000000000000000000000008352f81c73310c31e31cd5f267303e49bb1490c13a8b28e09c5bf3d72deee1f7d15f33a1df987c9202ad89e18c36a7500000000000000000000000000000000041d43f619edac2ea8a3a15b9915ac47e31a65a0fb5e62833aa5ec93086d8371c0f9a56c0d8afdb3403141f7735b8a780000000000000000000000000000000000a31e2b5840129cf2f2b7389ef4ba5f5f4c255e81486398a2cf52408f14f5556790fe11aa57a08836c15921baa0e56c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002edf086f489795507935e3b941f89775548b6e897f3544de7bd7c5c759aaa30cd4bf60c0922ddf3c352f9ecf3981e0500000000000000000000000000000000162aeee3f31988622e2f3302774a01a6cc1e8993a2cd3bf8b0684953603994db7367a7d5e5e4a2d1dc8cc476c75d6140000000000000000000000000000000000a9f0a63bb4129716047ee984daf1834ed7d9277739059db13c735a87fee6f8092e218bdbbb7c1a5a6ae1cdb9f448905000000000000000000000000000000000b496b2a1f6e4f031b7764f56b20aa7eb70e5bcddea7bc36ce59f2a9139ad1945b55b907986ce95ea8c7c4a98e8613a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009aaa77547265b05493ba1875a42cb8ca412fc010d9e706bc66343c15722e6e870ccf47f54d7d218fa4cdc06dcf2ce59000000000000000000000000000000000350878d2d873b3802f80594382e50f66eaba21f8559c61432acf6b24e3126c47a6d377fe39fc4cf89fca9aed09df7be0000000000000000000000000000000011292e077d168103f893090e53bd5abed36c8f81930f5580f8753f527d61a451b73fa142a57a1ea6da91693cdbb7ee4a000000000000000000000000000000000db0b51469338ce21f5a3dfa25e0761ca07f28236f9821dfb2283237c82a1c1bdd1be7ffa27124d00d31fb6812d78e6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000126403343c8dad4dd0d8e800aa59dc0aa60f4196a72f4aab76f07fa4c64ac48b448f12d01721a15ddbeb55257b2a74f0000000000000000000000000000000017d8b47e9033786fee0396e0a04bd3abbe4d014d8f9560502dd65c2c8420f1aacb821e011db7f20ef55f54f19aae6d6c000000000000000000000000000000001572acc3635d24bb78c24b436af8baf966eb167fff2a0be4b1d64b19a0fa881fe917b5caa6ec575db6a9f91281c7068400000000000000000000000000000000111f84b16cdf1c3781c26a3f8ef0b2e85963b1fb640862a7dcfc1aa46fe76560d5796533b60d6b9711bc240424b80e731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079c8c39f0d403bbd3f44dc94ae92328b345058020b7f33422a7861891cdcf11e6cd4e0c4c77b501fb36ae2440f4ba8c000000000000000000000000000000000985b745a089245da76f6d87aa6d3c9b629ffb0b43905b719e2703bfb00a27aebae3eac37741aaa195fa30e8567b065f00000000000000000000000000000000131d3e353448c195068b752abbf0f4f394e4a8762ed13eebd3183d898f44edc5f6f1306fe82b6cf4935d18474109aaa7000000000000000000000000000000000f8041783b4030af0a3d88b724b4e0276b24238201cbe9753355b10f3a11d53580eea092c52f60882ebe00126128200e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001037cd0e7d7b00136f2702285fc6f73088826d0603ecca0f3f1498ea5d20e1d6a62360c0300047f8436c442f7efe13b0000000000000000000000000000000007906085170bf3493bf0ff17414c76ba19569a10b258e4c7abf23604f8638dbf414f7a20e6d9ed0019ed09b41e8216920000000000000000000000000000000005bf679a8f619e79c7f50f39bb44fd1c02ac18fe4e59f8c1c86cb56619dedbfa5f2137e42328b033f721bfc0a58ff48c00000000000000000000000000000000179ef36a294ff15c4b8efa726e0f500169854bc5cf5ee44def42f6c53e76112604e6899b661718a3f6c9a2db0ba1c3df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d8cbaf19363b801e11efcd5576a7972f0093835ca51077705545eca482bd70e3a666def2ad867416d8a08fd93c655200000000000000000000000000000000079b32498cffa784e0731e39c94229b2eba2bad5606f4aa4b89ad8f813e710d3f51de851cb1a38cdd5f52dd162f82a6c00000000000000000000000000000000034b14c6339705c8fb1c5546bf4c6a10bca33a92eb75dfa70431e65e0a3a1546d6e443082b258241465496231619a93e000000000000000000000000000000000b8e72dbb405bb9b98b62256e41e771c7f2e04ff106ae140f37953a2f84e4b00e97dca8088ae37bd96f50d0f993fd8271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b87d23c37e95b6dfd26eadf7f19cebe18229a04668f32384dcc73b5b17ad67f6375b09f5f11ccde6dcfa2256b4ed75000000000000000000000000000000000f62dbed8bc5090f1244fe1ac509954a97e771e650699541df4887009806392b7e647138a465868fd4d6d8a1a18628f400000000000000000000000000000000103dbfd9571687b5af84aa444cbe4abb314b042c7043101cc78185af539455104ec0edc16bbe6b53abc2e3568b7dca5100000000000000000000000000000000080bc7f1510037f91b1d769f0cbb49a373b06818c56fe8c924242e36bf4766acb3938c496e7621a5d2e9a3767c8a0b9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3f13801accf8766c1f3c9d561c3c160c1877474bd26f67479b3e7f82439d9695ce9b6086c18aaa3e34f6173f51feec000000000000000000000000000000000465674bf53e64e5dfe8706e0601ee0a176ac8cf3b34ac91f59180d85d05c22bfa2c3bb7e46779ec8c0503b19f88b7db0000000000000000000000000000000004bfb27e4312d7e090a4ffc5cdc14531cbfb72ec491df77e7de0d9b6938598b8e66e9db94ff38507539cd510c4dd59c4000000000000000000000000000000000154be220943b8ee38326e749a4994c6182ca4f791b314b4cb3d4f4aafa6b5182ab03ae3e3569cde04002d2fa1be55f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ea38a022397ba85a538fb2947e8055fc42002f121d6391f3a0ba92b8359c805d57764a8230b2bc15f708af83c339da000000000000000000000000000000000b39783edd1f7b77a8265198115573ee4088a909827b48b35a8ada6e6f424d334cadd805b19e887af7b18c9350b63ae000000000000000000000000000000000019f581ee78caff7ac187c1a89cb4049323b3ad1239c8a62bd7ed6b4896e386a3789dc4a47a9edc01f31f1e55da44567000000000000000000000000000000000929f30d804ee39c217b45f8cb18de3752a6935fc894a3acc0261baac783f0f30e86e58dcf4a5284eef8d7ce2426b9df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007dbf0dcd22d0a03961397aa48c05c9b0e4d7ebf877d9fff28fbbd413439680a3c81802b987ae0509164f7777b66a5e20000000000000000000000000000000008349533421f0442a88daf60bab189c157aa17184cae1f1daae4d732efee8203c45f6bb27001e95ca8d583d74e5d65b70000000000000000000000000000000003025f5ce26d2d74c53a2ffc2b320041cbefc19d45349ff9878baa60d284e47bce97938172703fc8c644446a5ce004a2000000000000000000000000000000000ae27390faac2649aebe6a1818d7da58666db23398a044974c783cbc777abb8dbb06da01e735af6e12c70ea042d732991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b9c67380c949a0a24a75113b4e2c86ab60170fc23659caac0d0f0f8e1b4abfd5b0ee58b9e8fa6c20dbc23703b1581a0000000000000000000000000000000014dc1d46a84e86e64db2274d073f193b43430dc167eba1a92604178bb25609e181765ef6585e778fd7db1229f649ae3a000000000000000000000000000000000f75446b93a2f3c5bc49e9b7a1424262a1ff7a3e742786424ea05334a0e09ba4badb4d9bb93362bb374985e74fc77b6e000000000000000000000000000000000ce56eccc0d98b184dbb892d517fa0acd694bb91dbcae1798f24b0c49d58e40596a092317584d02a63a2bf1cbf4740401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bce5b221e27b2e3885c693a5b05cb508b317d704bd992e991e42001ac01ec94ae6b3322f77141013243b9f96d27e6300000000000000000000000000000000133520e5e823c6a61e7513b5df1338ead16bbf403a0b1b98754fcd1eb5b143b0b907be55f3bdc8e36ede2dd95c4fe12e0000000000000000000000000000000003fd7501e9b8fbd788a1ed9b786c1681b878917623ffc49c5f317b42947defa58e16ab6b95550c46b260fb46cd5621e00000000000000000000000000000000007f10ae4a3cd2fdc2b43c8e179301283329757971f2ec1fa2a54e1959175afde2aebd879cf182bb7060d379fb824af281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e1f9f7d0048c82ab84c9b89326f4fa8a6b853df1be9b851705592bfeaa44a1ca6955fe41a8f634ee6097abad5b805c00000000000000000000000000000000159974f70f6e3d670feccae339352803dcc84efce07940d06ce066e34c269539e8e99a508bc5021340fc897bb57ddb5500000000000000000000000000000000077f9ea71f064e76151ff58e0ebfb2fe809f222309b8e86bc7e14fa0284cdfc52b07a38122caa12715d0f1caff1d8b770000000000000000000000000000000015a5241481d9759e8e57a68713e07f2d756129bcb651416aed40ddbd8b9bf8a03f61b272f9f721bf54639ddeb61211dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012b50a5944a9a4b3344c5d4c59db746a2e5731f6f61127b314c6967a8a5d7539431fa82d2ef095335ec590955f07b080000000000000000000000000000000011d8fdf2892ad7ba64f81432364ab96e61b5b27463f467134d885f1490d4219658a287700bff256be0ca9618429ab84400000000000000000000000000000000028f7a22571cc0d04b7e276aa42dda4f67ea8e3a576dce366bb795eff22b38d36b5039c7575ab496eecf6e3c78ac74bb0000000000000000000000000000000006f6d7dce287fa364d19cfae2406cca3fac9e068540d6d2bbd95ea74c62c70ffaa35abc3113a90e79a35c785e49f9b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ab06fbf3d816cf6549a7e687b1956ceb1862318b0930a813bd81051976f193926fc4e5d1a2d0f1812ff13819fcc3dd000000000000000000000000000000000df92ec37a7c37079c89c82f0f1e33184e9871d9c039f249dd78e319b1abb024b9315f77220fe94c43c66cafd884267e0000000000000000000000000000000011d8787ca7aa8369b2decb423eb0f8d94dabe02a2c8cdde843cce85738454cdf22c79917095d0ee9d1ee6780fcf571760000000000000000000000000000000008808e276bd25cef7ffd91119165f261656a882673e47ab00cc01573250b0fda3ff1a9750842ecd2b6e7688cf95001771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019db9e29845dcd0ad33c9b1d0d3dc4abfc126873b637e1d8ab1d830cc9cb6978a303616107211272b996988329866d6100000000000000000000000000000000016e40e0d3c1e9ae56da9b877b03ea498864f2c7c8d5b9424bd29e09c4ad9530633774b83f7c6eb153b39101d4fa2eed000000000000000000000000000000000a54f39e77441ba4750a7f9a524a4368109f571b8535af89f6669531384d4e187d13f098641c1fc81d0db2c8d307303f0000000000000000000000000000000019cb93ee43cf626dc8d7d301e3ec84a41ad94f2c19906205b818ee7f2bf978428f62d23016403f33e0d6f88b979e39701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019297a4adc7ecfaa534f652a409e598370c46147e7074d0ae847d3b0d20f0455a0f76acff49f7c09ee2fe9b9bdd4b26500000000000000000000000000000000183b0698cde4efc6b43ddf50de20afed7c3c6f385261248cdd22c348cbea3a74d93d202535717fa0c65995ae2e7406ed000000000000000000000000000000000ebe942f591fc05f70d0af5c899ff13e3a9f2c8ba904d972353d85e2584dcd5ff93e7274dab1e0306d9be507d6a9bf420000000000000000000000000000000002fd3ae56e19b0fada08380bc3ccee76ef9960abadbca1c603f9e6e304c01be96b763d9684a9c43dcdb1c8dc244267251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175b1298f71958411a230be34e16fed58b5b17a0a6aac479d95e67cb3743b1b95b76f4676504702478e0f10ff3e5c0ff0000000000000000000000000000000018a55a478776c7b9fbd60bcfc88e45e8b7836d6458793f5bfcbcad2b8788ec8d3ac3a4542f573cb0449f49ddfc3cf83f00000000000000000000000000000000074b62425f79b4d8ac10bb9bad733ffeccf380f480f537fdf16dfabfa35cdeaec748e80f55a01ac4bab5aafaaaf713830000000000000000000000000000000004c0ef7dcdd20074d611ad06ff60061c1ad25287b4bd085642ea14bb3df8dab3fd2b6536c939b700e2af5057c75ee4c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f72e00cb4a5b217ce2b6294359fd979e0ef0918d36ea46471f193c7f4cc9fb86bd6ca1ced232f96d0940f6e00e32d200000000000000000000000000000000172506de01b301dc54980213329bb02ab14d4fb6c523130155b5ae5262767a919eee8165071a9795706a146556d74a3a00000000000000000000000000000000075878e455499f636715eb8543214f39c067873b3282e263c73877f11a4902c42357edf7563d8e9f69cc3336f697cc7c000000000000000000000000000000001821feef28dfb7507b23e29bffe9c53a1ea9abd99a63be06a7f41ef11ef8b848ad5bbf260bee74902b44d39cdc30a6d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049d5e2eec780221fb6a73e21195900ce1544782b7c7c2319ee479a70db21f71223e9556d79978b7a172f9a3b0fa18810000000000000000000000000000000008cc9886fafabf0f4b947fe416e0a4423a113a4f06cd6aa2931f4b51f92645c9710d7223e989a7311b3bfed917fea627000000000000000000000000000000000aa8d5cecbe99fda4813324c2e2803df05f00ce21183e10e46f4c5ac19e1e14f70a07bb9f2b55e37a9b9fd1b98fb5af700000000000000000000000000000000187dc3577bfbb50e1e6cf4e5410400469452230c41f17062c4d11421f885b8bc410954bee0e7aa1e39420799b89530841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130d38daa9f3b5a0ac75b18c12c51f80f1e49de3a019c91cb82b67523817cd2434fcb557603e372c7cb496b95e935c1f00000000000000000000000000000000082371af4aa99251a204d91748ecda513156f43dee192cc71083cdf73d7d54fddedcdbfbefdb2d66faa91e90bfb0f4d1000000000000000000000000000000000c7f8474821020b02fb36b4b035c4014575aa0899a8a258558aa410ea0f13cb59d404fed21e95f7f97047aa5faf358d70000000000000000000000000000000010e6c26ac6b4fdfb5fa3b9b443d4c70f8edf8b63d4d170853780b3b55a707d0c3ef9986607c4fcda90d7b36c4908c8a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c801768920ff74331d33930daa4aabb9040e99dccb5c22afd0b430a39942799f56c4205b07a1436f8575db5aa9a0160000000000000000000000000000000003efa318c88a612ef6919681d540a8139d1704f36218d256b01741cbe4a0aad5650f5bedb03baa2fb24f54455745da050000000000000000000000000000000007382864a35024f4b3ebf353b7d5903efade4be2da8f1f4a85b5899eca8007165c59e8d8847a1660e107503c9edd555c000000000000000000000000000000000eac240b773eea4ecc4ba7f4f8213216dd088f0766489d503e361b4d46cad3e1d52d1c28b4064c873d90dce1cecbab6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee1d1862c3ac2cd03b2ee00c67a8cfec3d668c04d4c75963189a6b27ac32d0d9f606fc153ad3db968f339f7c55632960000000000000000000000000000000004b882ef9badbe9eccfc771b001dab81435a347712ce32cdda52a1d042c606d7423d939cf13c3ab91f5e8f1eb12b858b00000000000000000000000000000000179c72deb6740d42be45aab0d7f606c930558cd83e58fc447d282674178f61c1a94f8f1902d5d11dcfe51f5b504b805c000000000000000000000000000000000ff7bf505a5febe052206aa81022c9799a03d3124fa83db4d8f16f521b760521bfe928dc3d4b510ff93211f5ec5d25b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000679f44cd736a3a44574120a3abeb11516bcd4c6957b3ad0ca16253bfa964b9a151a517a76689a71ce959bee7d7f5ee500000000000000000000000000000000040bb186740a9a6ae78927c839b5121f22c5d16b6708fa3a573b572e9214572e273fe6791dd4f75b918a3415cfb8f35a0000000000000000000000000000000013064b61afc225b673274c2a4a1df3cf89becc2688ed92e42ef9e5bfd7cc2b9a0609e59755a16433ba0c7894d5b83a9900000000000000000000000000000000063f98c43791be32b4c7a07885a6622716e521754a982227258b1cebf4ad7134861d504cfcd4ee42d05716b1d2ec5c141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d7524ee690a740a5f307238b2a720920bbed7929c2bd135aa25f38f4d73a161957e59fbd87da388bbcf5529ce960fe00000000000000000000000000000000060ec0e83dcb5c628ea715b6f549f37b58f1410897a466f650a9cd6295f3bc877db3a2f838311afc39cdc7582998ab040000000000000000000000000000000017b1128ef973b8bbf2b1b40d147cad2c433a6d180ed06d20df736fe5624d0d3db516b60537e31067860a187aaf7c2c3b00000000000000000000000000000000190988e4d55e5c407c394547cb3373609b3d959b8aad66e87a0d888dde1127c49db2784c5441a21116ce9207d396f6e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000276312a5b15800f53987193dc84dfb1d2ce5672e5328ae3fc39e1f460eab23d42499f991dbbf0cf6a1e9e39b3ebde5f000000000000000000000000000000000550195b6b7bbd24a776bb0e0c405dd01734e66ddab73bda74f33e1781d9c3a81cf4c114a091b1192cb5e8949716ed6f0000000000000000000000000000000009cd1f1bfccdf21f61c17ae7d5af891631ffd77ee09dec82c8e5664dc3fc81eb3788fb525dfc4ef43323a328186bf93f00000000000000000000000000000000147287aa781dea3ce6ba5db8b25025940da8a8cf9a58ae5fc0cf592d5055e0a6fd848de5d47abf890d79ae715b59ae711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101dd21251ce5222db7e686167b327a2f6ed2577d46304ccb975d36f547f30db8c0bb3e1905ac47c7c4855f6f77d35860000000000000000000000000000000016dfa1679a2678884f494c8c9deb60f8445a914c84c94a13ba4584ce590011014b9cd35a12c755175ea811fb9f21b50000000000000000000000000000000000192fe2061c167bef84d95c5fe254ea9e074071826eabee6542b3775ebe497fa7c01e0f2a2bc0042cca59533d213e19fa0000000000000000000000000000000018f929f25308da10b2d21ce7fbcabcff4610aef253fbb23c672daec107fa29a2ce82227ac130fad0be6fef8f58d0b8e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e6b71faf8a7db82c34d89ba0f223c3b518ff14559440f306cc341048cd4155cba42f234c47d0197a59d5750df8fa7f0000000000000000000000000000000012ada1890a934f812332ab2787718dfe9ad95ff5d2d6a15160dcb98a42459d59a622057b46c90eac9883284fca2b73920000000000000000000000000000000012dce874a3e81bdce42560d8cf588f29f0b0e80cb00974f616f467e63f0c2ae924b76a50c4ed5c60c1eaea8561563bdf0000000000000000000000000000000016ca998a066416aca071ec812b5dfce0ce4d50e116c3ddeee5701e006d5d465c541b1cc2cd591329f47aae69498cc9381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062363a22ca6261947a218a24ccad5eb75c011fc52a9c001016209f837958ee13cf0b51c58fc41b534a750f5892438600000000000000000000000000000000008ac2ab97a2594a35f6c05dcbc19513378b91d973953f9f1dbc62ff2259e071ae900939409cffd0c10c8eacfcd7061ea00000000000000000000000000000000041e2eebeb6b79654fe232d4ebbf6805d8b963d4bc7bfdbaa3c4f407828c0aa7ca0050c99086498fa689804c18eb482d0000000000000000000000000000000018d10f2adb5978e3b17644cc48c38ef671e82b7fde2509452701abe02e2086f7b8050529e70766de391dd286540ed4391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bfc68dc03cb8b80b19a2596fb49d682f38a166b907e13240dd6ac8d57b89ae7a390608949c221e771ccb0947a3a8d900000000000000000000000000000000128718b83ca9b9b20d06dd811ecf2bd3e33d3fb49b15006c5cee67ef6abf20b50ec315c990a2b28ef8d4e71490fcd506000000000000000000000000000000001718253f5faea86eb809ea9780cd75dbf2ceac93538c19afff8bcf9cadb3636e2e9bbacd6fba7940dae601ac9d16d543000000000000000000000000000000001090e127447cf3d84d863178b6b39e580aea4e1c7f214d02d3cbecb863145b6916f41bee779a0e383069c9c8d60065fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000549371d30d49bffc4021f3a926164aae90b87c58cd8579f6857fefef519c52736f7bd154475bdf6bc5378a33c1524b600000000000000000000000000000000017394a396578fcfd49fcbdfa362ff99705624ee067e25f551ad37e03605173556fba0fa0aa52d261df9fb483575f1e30000000000000000000000000000000012e2d0b76b73fe55810acc2b6f6128d672c8acd4fa3bd7377aa81e4f21d87d8103fcc6c965dc798e89291f42a643f837000000000000000000000000000000000599888c960b1c253910311fceb07c21e5cce03f68bccaab3cbeb043fff84d462e81de2f1f6bbc913d59f24f110b5df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177294a4e2144b42b011ec7f86ccee70684a5b41eccc86d640386d8bd09f55e27c349404395d6ad8331fc7ed1ee4e8b30000000000000000000000000000000016ca647a9a1ae4a29c0fc3bbc462c3c624915707f4b2b5149b52c96661dc34bea10e5040e25b176a22c677ad9940dfcc000000000000000000000000000000001249f0d55d94e8ed44baf565ba3c14209eaab9b4546b17c04f5b56643aca1ff6f5ea961619036047c08ac2e37a4f23f5000000000000000000000000000000000937c9fe540d74bdb5b0a73d984bf8863a122a22fd06d21534414330b673dd6a7e6ca02833f61e79161234c0032edd1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bab0da6a2235936692a0f62f4cfe20521fa94f5d11e52df052c4c8d869fb94d72a64fbb2b805f38af6e7d30236cf1d00000000000000000000000000000000153e914116d1b90a84831b1c53d7bca6b6029a1c58bb65275b552c3170de5f7a3b695e29be51b865e5b85ed8534ecaf8000000000000000000000000000000000eacbe9abce096c8f98a2df5098fc4ae3f9d885926077bc32b52c4b88e054d65306b7a8bacee545df0b6112b850b9fd4000000000000000000000000000000000a27949b36f57bcc14679b2a4dd52aec709c8431fec29de4435a9783976e8b22cc9a30863ac4fb6d0792c76c9dddea2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d2300c12bb6218dcba92f96402cda4bc3c039b8c63c546008632ca4106fcebfcf5d8824b745bda87b246d5f8ffeb1b0000000000000000000000000000000013780db322d7b6cce8f35fa17f16f59db5f44b91550d802cb36f7c0c88704f5810b948e3a7d529d4274b0e7f9e05b5280000000000000000000000000000000007034a0e82a33fc50439a6dd4fe5101869571bb6c9933f83d47573da714ee2a5887683bea688238ab1da9761c7a24a86000000000000000000000000000000000b60f798acb7595c3c6f66f254d198a2bbd0e2304e818718ac15cac0ae811c2c98189bb6c2d6f146347af83a34db76c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ac34afdbe2547d23c6c16a36e877c74fd9fdbc3990b70379f0a9a2a83a770fb2d54bf1126b80df92bdcf264a3679e30000000000000000000000000000000000bfe81abd2cc11486fdc7d455ad814fade8a95e0d9ae4a38cf487d2927e14ca84f6557e1857bf58c573bc6d0285d92500000000000000000000000000000000042e91d8c0cb8dd9562385cf707864786d1dc1c7b5568d1aac58a8709cb4b0f12d27807feed96b12381f246061b9d8350000000000000000000000000000000016cc27312cf0b40ddf2a0e32801c64076b3b82f0e7b13b8e623aac5fba108ecc6e48bc6c2b1af2334ae1e110a01015501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135fdff40e206b4172414d72e5e8a2b14365fcd69bd1727aa01a5c183810be819b86c0d80906b27c168021900c0d031600000000000000000000000000000000081fb85f2010e892d50cf843e65bff69a063016b24c9432fddef000f0423a153a17e1d2693c68815fe509bb82727ad77000000000000000000000000000000000e22f5ba0deb00d09bb53f29cc2f74000f28cdcb3808f02b24f393b530066328619b2de26c583babfff0f61e24e3f25800000000000000000000000000000000065ad005050ee95c321d012275ed4a643acc7f4008c2aa92967aa8613cc10807b72159851648e4d9e5404716dad6f1361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fe240eb31ae81e9cf1bd853d66932b2003ed93779286c7f2fad349b1cfd1209d902705fcc3653cec702603246f27ff000000000000000000000000000000000ab7809d6c1e5bc804d4f7c85f31a38de7824cc67ea24cfcfac032b38f724a03b626647b3d4862dcbf58d7de2891c29e00000000000000000000000000000000017727af51675aa339e73f44bfc470b547ddec2a093c41652ebe7afd3c3aaa679418056c44c2d25ed353774cff94569a0000000000000000000000000000000006dd33f65a2252293e3df728c405ed25b4d04e3cd3d699009f5fa81a73570811c82334a466ff1cb92cee8ae4ee9320e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010561cb107e8493fa542f341c9ca67f59f1e3d594cc21f95bb54c720159297e435b4e4b4976d706e28a2b6d1366a5c0c000000000000000000000000000000000a96209093914d1bede9cf3c71c948545f848acffe94c82885219dff5779307070ab5b99ecd899903546c3265f35a60b00000000000000000000000000000000001048989a0e6505ac0679f82f58fc56bd5c7c6ee24a6602093055abcf9deb45a49b0f607fd81506408152b4f2e691390000000000000000000000000000000018daff12269d6aa42ff9a273c61bc53dfc3b5e527e51f0d852e186e67f977d6a139d21b9604afe0545a2e29fcd6004711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006366a86469913eb09d73baf15c2a775be36773b9db2544f9e21fb92fbe11d93cedc4ea0bf480c3b1bd3335e193d974d00000000000000000000000000000000126126a48ad1aa83a743a2d87c1fdfbd62ba65d18b564fef9a58d2c1fa24e3de8e36f1fd06122e72ddc23d51f843704300000000000000000000000000000000011d326b1404e62207ea95efe2e99da412381499d26c4c878ecb278381d870ce87df614d21926988447f66ead84e959f000000000000000000000000000000001699bbfad9448ee94f7cda86d624a47db405efe28fab6bfd88c82a05d6b33941093af0b1f24b50fa33c355d9c294ac231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c3424afe8eb2df5b554bd8760c6e1a5c7b52c9c4e18142c1107bda305eafa2c1a7266799b8d585f6356810ef4dfc730000000000000000000000000000000013854be6fe7bd5a4819bbd8085d89b868e98d847c572f4ebcb4364afd55765dcb9038eec1969c302b5720d5fd64f512800000000000000000000000000000000004451ca2a146ce88bd007a5352cfb886f2c0d3c85963f4b9bc2e00db68c145c6b341ce5fa2c4e86dc846ed359f3c1da0000000000000000000000000000000000fbf20093dfa5ca56bee01884d75be9814a9b80ed5c1db73a64d1a80dd7b15854936a7bd15dfa0b1f7154068e5f906f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006434964546d700f66e7764334a5d51aa3f2bf0eb9355d957466792aa7bd493a856b4b4b6c81237eeef02e1ebc289e3800000000000000000000000000000000126921ca5e56ee4262fc5d9812e88e4173f7ec393945c67f0df3aa0b84b9e595dfa46f1bc851b46952f184180487d547000000000000000000000000000000000745520de7871d4f3e2cc8443e24170a4ad3696640076562397b6e65eafd235abfd2fcd9c40f799d4a1d8ffc797bf5f00000000000000000000000000000000000f3bb7e229452c2e96df937217e484932488c6903b5f409d2934b71a2422be034934c36bcf892cb648c0d4538a559d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108cff35edfc19996527bfe881fc7391f4d9dc10b2e5441eabbaa23cc48e9b4050217c74460c779ac7988e124a8c4622000000000000000000000000000000001813f0bd823de40e1a5a0d06b650c22055bf376c38014b85fdba4fdca5ca0578eed080f1d26599ad2abec32a5b176c1500000000000000000000000000000000004a732350bd6b265055bc1475c677f683fe388c972931daf046c43ac36b53b62842a4f685af7dcc2d0702b24db5dde7000000000000000000000000000000000c43328fa78310b94f125c6e1926be7387c181690d18d13d6dc93cf2bb995143cefef631e44bb50e5d6173f52483c7251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b36a7521c4e15d11c7c8bd3b10a74043e36aae4414b860588ff55da7de1df9b397ec40b8dbee7a10af57315b6b98a6600000000000000000000000000000000170e84e5f96eed4d8af494da7e2c8a4377454a6f79bb5df725a02b985aa8077fe34fa9007995f957d039a0d054be843000000000000000000000000000000000059c4c0992e519a159d00c4afbc20b9080bad7b770ad9cf8967b6e4e31d8d3d70615c9b073bd48d26991d4ca8c412e5f0000000000000000000000000000000012a1c6f0f93b3ccd56efaccc1047190c2161e86a9dc1f167c14c87562d8ca4340e4ffb2447724b33797b6233503801741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011313edcdd41e12877b8ae3be5d32bb251f16aeb545d24441e0310c9a9e82bc6fa29053c1f0a49e766301ffc511a6faa000000000000000000000000000000001024985dfde909917c1cbcd32c070b99e485a0695b9eaac558c5bb96a8b517cd3851a3458c8a7021a871132c33e26f3f00000000000000000000000000000000027bab13bfaf0076b436de3f071bbd27276a3cfba3b68d8d0f20eb34e6f16ce617cd09f06aa1cb4e8f3824b4c1adc1a500000000000000000000000000000000070901a56579cc144a2426ad7bda45055c9280cbf84b754262cd337f10a7d2abb635149b337e058b637928321ed32d8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9ea39cfcedb8bc4affb781c0789e0d323e61655e5be4d3fd1d5c3bfeafdd1075e400d9a476d5f7b01a8162f782e5e1000000000000000000000000000000000495ce7d909ed7a478eccaac7ff2bacc25c34b71921058920dd46caca34cff8d8e8caca979858d9db72953651975bc4a0000000000000000000000000000000017607b61852ba9d3ced5719df1a4324359cd251948d15091bb19ea443c9fb2fc3556bb3116fea1922d17c9f763c4c207000000000000000000000000000000000ec36466a3dbc41d20b06219aa2e13442e2249868337b707526c6d81e60c861e2c9a0f923c6793fec50ea24cff3479ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9b306ddf5e76b4af38833e1881aa1c1327be40b5df157e4c3d18334dedbb8a8a9c7840b3957a6fe0f4c85e7d5bb0da000000000000000000000000000000000accb5bb88a764d71c82baea2e08456959c8970bf60baebbc91162beb3ee876c58a68d6c0fbe2acb2c69eb55d1980cd000000000000000000000000000000000149f49e9c9b7d1d68e45a26cd7cf88bc93fcf90e156790630d1e3819a63f302073adf8531d1fc2a71710ed435205fe99000000000000000000000000000000000d38cc3e3853814d20b1ebb20d396b1b87992754e96af4a6cbbb0d7e9ddcb771b3a82a622a1f786c923c129e82d857861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c2996ae6122a98a9fc36425c0c22b6b00b82f9a8a6d86c28b000c4204c67c8e0c5e176193fba8e696e80efd993ddce000000000000000000000000000000000d3b18a731b8bb702ae279d5bc8ce5a20c4be033b502c115f683b2656c3de600ed94088cb77744850c4467aa98314f940000000000000000000000000000000011179b01fb1289efc28fdd7222a72966eb38c63bb4cb00c82a2fb523d341c3c7b0cd015d179a8c1dbf64163b34b7145c000000000000000000000000000000001034eab1f023c61c54b74a9ac7e7c50ecb4a6a889939da3eaf5cf5ad5f6ed33147918dd627caab152860436284f679301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b35738c36134d42a50c2de98cd85b8943987a5fe933de2c92f44805ca1a24ccffbc9e634ea6ad18ac676fbf938a2a7000000000000000000000000000000001538651d78ebc75bf6f48f5df8d7e44d91c4ca1e3b1babf29a7df3059df88188a5c555d963b03dd6bb3b4488cc488490000000000000000000000000000000000fda0a0ad3ed83d7886da108332c34c7099f59d06c9c63977aa41f092ac0a54c51d248bae2a8c7bdf72d683dd92687e4000000000000000000000000000000000a375ca1fb70fa49906cd14ee29a13881e3cd4edf070a1226dde07978d8f619bad96bb61c0fc9fc05c21af7884151f251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019da887951e85e073c7c46cbd86f9fbd821286d41cefdf8bfc376205d9c5fa5f9f936961fa6b7fbda51330408da5bc220000000000000000000000000000000001baf7646092529287a2ee35c5dd9112afccd5c35d4cd81ffd43542c6e828e48d56ad392551e8348fc53d39ffc51a5950000000000000000000000000000000012e987e09e6332e115b672f3b3c118f1f0148155e4ad9fe1aa31492c8a3ec5dfc0f55e448cd296e2486931730e8b0a3100000000000000000000000000000000029bb0c0bb59be221afc85c155cae3c97cefefb6f6d1a0d8c2b3e9b881672afb3618584c82d3c9d40e083739187e68ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a061fd60d00ef87feacc12cdf48fac79cf32ca64fc1fda9bba9b13eb67bd54bf66c86e7cabf3ec1105ccb8b92caf6a0000000000000000000000000000000008249d8e4d8105d4b81940acda2b0c096d4706fa6b1ef604dfc66eaac6a8f104ae7445931db027e18df9d67d2460b4a9000000000000000000000000000000000e66773227bff5fde682a98755290699e743850ac4091f8a3d9904d094e4c6fb60c89e0484c9d6376c5648086790084e00000000000000000000000000000000190b273712deddf0d85454deb4bd92494264c765ae2f10e359819db4ac9bb0ffee8797d7b7adff7d863050bc0d179be81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e08dbadb6ab4b9784aa805a8f73d55655a293f91bd454248dad05cff6ecdd6cf4dcceb1765e52933012a12cbdb7c3eb000000000000000000000000000000000c71d60bf2bb9fb12e570cd4ee6d57e39e2170bc47aa49338bfdb943486ad5298e59d2ff37c0bbe6fabd1bfd403e6c680000000000000000000000000000000010e10fd7cd3284446e8506d577e31401bb730be96418b97160cf994077408fed9c7332d2262909fcffe05e8a2035ea7b000000000000000000000000000000000eb03c999434173772a14d3639f0a4a4dfdb800d34b38e56a993bbdce4b8edc37f6c454be8e3f4adc8541a5872e4e9d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ce9d0227ba905b527b5901550ac3185ad80ea07847d357ef9b5261e52122f0b21ad41109054b8f530ee6508a366bb1000000000000000000000000000000000b983c40526952f3480da633d6a0a3228057a1804b14748066c8b2e1d848aabb62e44affcd35a7da0134a53722bb4cf90000000000000000000000000000000006eef96420d99b86b95e61e77334fd04a7bf5cd2d0712b0262cabd5d61e85552ccf3742d1af392ec0774cbd19705ef11000000000000000000000000000000000bb9f60235279c80e18976b40a10fa7cee7f40c4f26e88e6c518f23886a2a72f2ebfacd798b15e2794cfcfa2402f122b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ed80dfd93492bb81c380f2983a48c61033cdcd0c8e65d960d91c88e256ce5dccbc1d867b113a3974507e5d6601247e000000000000000000000000000000000608f9f60a74814aeb7badffad1a3282e8f4468d3cd016a54734733d395f661dfabf9772491736a3df371b51f1519622000000000000000000000000000000001470b48e11901d3b36a8fcae4155090f3ed66665a74a686105c7c9720dc8f8078130beb5e29789c97ecda31620b099e4000000000000000000000000000000000d7bfc7fb471a3068871e08cf8279512f25ecc052c68cae84e3b5609d84ac64c6c39dbd6c3df98b767da729a367cb4101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eec047b9d63a7b31a5bc7a16ef2ac626a7b1885fe1c6efd24eaa31beee23eb839296cc5ba74cdaa929ebf3d7cd81277000000000000000000000000000000001046a73424a7c9e533361ece7dc2fd0381eed96f6501dfb19025fd9f175f71a4d723d797f02a080c283bbbe1e3922f150000000000000000000000000000000014e451848cec6dd4b2ed6aa4a1976fefa34f382be497205347a521337fa813a6caea7519804bc24a0149c12f073babc60000000000000000000000000000000003e6ee5c2ba37f65de587e48f8b2a0e098ce36c87121896952c86d8db258330c97419c918e51815e60a90a8df3be781f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e17ad9aa80a485ab08b7e3a89bbd402a6b1c0c183759a6090b2c33ab52a79e0319d68f676cfbe9b5cd57c3c502fb8100000000000000000000000000000000092338ca37a12dcd7a2c7991c2e1ca7923508896a8205aa190e17dd1b08e9a87c2a14851ff0d13e47109aa2b5f009bc20000000000000000000000000000000007a463f9c09de4b3c91ddbffa4a337271b7a1bba6462544cf0b9e304570467b82eb5f086ddf24023c7bdb7dfe8c4fd0d0000000000000000000000000000000000732bf09cb2051b59f8cc9b3bb247543b95ba4b8d9ed7a4c6a4b89f03786387f4ab899b6f47eba340d13cf7d12f087d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006225682eb4ed0e52bed3e85a7960f722346a1efdf53733f4ca4cad1bf92c9e4880b90c705e7306617ad750f2d94939000000000000000000000000000000000d564cb26c440ecf1c73092ad5993199cd74a04f3ca50e5e51819c5562d58d5717ecb3e2b393346a47f70e787ed79472000000000000000000000000000000000efaed6ca12b94442ced852dd6325916b1789b1639559b820c5aab9e854dd47aa49b26318187d5d32ed65f00d4697e1b0000000000000000000000000000000019b73586a45cb579e3c1d9935fb5b63d5e8620054f4f4bff089904bd3537dabcf2885a2fb11fd22bf4f00721876828e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178823ed42745258a61944f28c33d4e2e620755561bc44d72f072e3fb933c43737d03eeaa06d901a5182bdb423436a0100000000000000000000000000000000073b0e9307b2a457eca228510164728a261d2ab189754d785c59ed95393560bfbba0d2d0dc8fec7e8ff682d20fd8e71e000000000000000000000000000000000d300ac575472c99f1690af3e52c22931769feebf4b50d99710660431b2a619f4a95926bb7b8e965edc590a24bfd4b5900000000000000000000000000000000028cd64aa95676a2def419a8fa639eb9a4f6361261ae323367c2af982fdb10036b5768b5101f7c501ecf875281d51d741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072f86f3c90234e4df352f3966e542e9e7577132cba049743f63ad4054b58e30a09e12489bef6cc485162ccd45e00aed0000000000000000000000000000000003edcf4a9db723a43a32b48c81f906cb3536370935e30a3ff46933310d80c8fdf3f1c5c175128f63bed5e3a8829c20ca0000000000000000000000000000000000e0cf2560e89853f0d2b0918c62c801d20845949058badb2d7e0028b19aa35dd020102d6b29f89a41989be41d6d890500000000000000000000000000000000022f3b233d23b1bbc21e703dcab3caeb18a19b009fe4a6989f3e13983ed8a454bbbc7f74d4145625a5b0e85cddedb1581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199ad3ea86dc2b02add5d20479049ea669c01ad172082e642014661e956916f08ff31670fe7464cb6a1f4e3ddb77ad94000000000000000000000000000000000ceeda74bf5d6aa1ea8f2e10d284120981cff618c632edd416cf60d2f67636ba93bc964958a12ee75ef24da9559fac350000000000000000000000000000000017b7060ebf3ded9cf1eb236ce0e2c880ba238aabc96e90e1dad35544272b699ff61856ad45860b8928d01a76ef21d55b0000000000000000000000000000000005b0315c2f3a18ac601accdd875d7e9c3ab759f86bfeedc7f184d0e9a38a21dd687049f98983590208c8527c8e4db8d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed593ae848e2bbd2542e72875c8f8a07aec2357b3123dfb71a70e2bc7bb42af8c54db20200a21cece183a02f2b834f40000000000000000000000000000000013e59423208b1454f01920da11eaf4c6a2a7431d7b15dffda0df76cbe868f43ef4b85b8ac6734e9b536c550a40bc886400000000000000000000000000000000179f713091a79a157231b9284c78070ededaa3ca1abb43f6e1d4182fce4e43a991404388f8b4d56bebe23164a164c4d600000000000000000000000000000000091e466f622aad04dd2261762588f67ee64a3d831a84983e810b58c97a049e0428ce062b812d0ae44bc9c88b989431a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e97be158a87113c7f12d9d063cae42dfda54dfa7c6f1647a870e16f2d8bd0309a1f160fd0f790dc2aead4b5282cf831000000000000000000000000000000000665ef19666b2642bda49fc596625dabe772706950120eabe0d8ae7d7c9086de55987f43e2f73d68ce599d2319d85696000000000000000000000000000000000bac6b0bb94b4eab0878d929623b772e82ed8d475303917fd8e694de3cc2ef6bcc733a8c7ca8a1b48d56da6bb00a936600000000000000000000000000000000101c51ae4d592116e7362a630abfd85d78f4d9ca105e722050782d6810b360a954b232df6ef830a78d5fa9cbd2a953b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fea13830b82b15eea4e4d5a7626002f57f24a4be86f23a2bcdd97ad47b77feb6f4534dfc067dce4693052e5336cf47e000000000000000000000000000000000983408c20b090d49c8b10abc85d068a217bd979ecf73f487c3f687aefa13bdba714e0b6a681540a78b4221b9c7a0666000000000000000000000000000000001021c0ec79afc0edf0eee0fed313ba553899ac601faffac0f1dd1a58bac4dd52017d181b4809bfe19f1c52cdbbb11951000000000000000000000000000000000d712fe8c0723b94b9cf67863569a7eae660fed08127f66d183e3e6fb5524db4e6a523620ab05bf87462b0795ded75cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018049f77560200cdafa9e36123d20bed8e1aca7157d97fd6c95a64cb02eb3f93e5bb41c1017534b7b1a78fc699758067000000000000000000000000000000001243c9c097da84b4bdd82daff0f63d480459f154199b900162d8fdddee11c8ea2ae31fa8a2dccbc0f7d1f6dd99a32d540000000000000000000000000000000010c9a183e439c55a30b2d830ee9f9b5af9b5b11703a3a43f630a195afab19d1ea3d81cdb99306f82a82bd7bcbf3cce5e000000000000000000000000000000001343e22d23306a18c266b9884458a260b6e9106c6ebadd39f2706d4aff343730fb375990ed78684722e7ea3bac069f671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163e24391ee67c2e668f18ca2c052d5ccb24ac3b427af592c12bed05d6ad929ae7767745dc99074eeeb8d63e020561e40000000000000000000000000000000010b5f5c330722ff6f4a3ba72fc7cb66c6d73f3da5f1ff144792555ec1dac509b1ce38c567cf8caea42de1e53b5b2168900000000000000000000000000000000160fe4c4dec8a24cf10c04572674132a929e95be253575440c38b107c7184199a1ddc835122a841635ffc2f2a20679d9000000000000000000000000000000000240cb3e0d8217788fef85e7e8a9319b7c70f5b164c580cb02a1a19a0f04ac02fb352d59c12ead81561c0380d34fd69a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cc624101b30437fbad665a7862ce3a046fa6a1ae2391d54a9a203f20287f939fdb1beb9788cb1fe8d396ce07df0f6e0000000000000000000000000000000002c5cdb6ea3f8be5630799eadb307304a68d24b054643b96b7caf0f0b3e393d6552b38acd6ed8f2eaafe92694397b743000000000000000000000000000000000c0b70e788eac5ce02c2435441ad189a027c8f25190bfc48fd90ad9f2e528e426431422a7b19b484cdf11e5ab3c15f570000000000000000000000000000000015162730efd8432b687b5dff860552c0c899824b2d14adf50b8a2df4854bfa362d3957590b0c088b23ea1fd01354890a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e85d8f9b8f1c734df3f774fe00357f6b8f459a33a72a9d56bb6eab1eaba156bfd620466e7d8b516e824958b6143612a000000000000000000000000000000000ee3389a3e6cd163f0c489b63e0d863195e247042fcb719377ae13655a65a908031418a7ae4733c46b7997d707a848e20000000000000000000000000000000008cdb756ea5a4711b46c4956027a8aad41fce620173a48869cdac139f18fd39ab6c387ee4ae819a1b0474100487d07c7000000000000000000000000000000000d2248c2b03b7532cdb85a3158eeab966216feadb091eab3d5b8f877bf7b6eae9b35d00a0afdaf11698c86a9d9b3335a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a725d9588491e79f44a2b34d1dca28d36987fe1b415a3d9f7be9d9a5fc2e1b21c096fb3444c0ff1e5421dd3be4c34a00000000000000000000000000000000084f69c3b49ded14de5e7143aaaff1fbe0e5b486b25d27cd19f3d70d87919daf0f426b0627efe414fc99492a6948b040000000000000000000000000000000001674cdde4b113fc1895f588a648545045ffdf123cf9130f462a18a1bdbc5ab8c5b1bca8c0ec642c398b2a4128439a6cc0000000000000000000000000000000012e73fe126a3d373b5536085c3714ca4f3761618b19df85d02b77ecb9acc8bc1110c321bf96e76025e689a0e300c90161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dcd0eaf26ec02eb73468f8677f388b1ab4b8f7a02b3a7f22c4e87e598070693dbbc62e5e8bdd425db0d1d45d2854ea000000000000000000000000000000000cf94bd98c67887ea70f724f39a1a8afcbea090558611b3f4003facb46aff731bb2f105f7ebb3836d415661be902aff800000000000000000000000000000000086e8d170aa5abb237dabe0a9076b788cf6e549c2e48139fdb53a8b0d204051414bf596f8a4de4f02453692db20e65170000000000000000000000000000000018f200e0609e513136e615fead1f6a0577e6414378b7d35054e1efa713bf579ae103abf43dbe1042643a2ab33e8d779e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000091a48c15a56ca911fb46e7345d85ee4fad8905218904a9aa858d635dcc6044984e932f43779a32daac5937f3750285000000000000000000000000000000000c0476b0f7d091b458b9a455e79d9515d5a128123da8a071d32e5243d784300940fe8359997419d78f835dfcc8e2f7370000000000000000000000000000000009a90c08d8c7096f444a1c39ad2534b15b4da71a048e51845ccedc1f5e2db8faa534afa4eac4f98fd9f7d68cef918a4b0000000000000000000000000000000011301b5780b577be096fa6ddf2faa5b6bf7dd9ea4540c0aa90e5fbcd0793c893330ef2f5be2522575445d2c117de56971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084ce2cb8d38ea2bd4eb48c217472998c614c4c527dcfd8eb5ac56424e8259f5e996053448f0f60ac55cbd915309c16f000000000000000000000000000000001374404961742a306c45eea63ca8437efde40f7bccead29b3475dc0d7824b5a07f03baf913a0b66570a76e7ad99e77d900000000000000000000000000000000014b244d86ffda34171b4760a21d1d24520dccf606b74b96061f56af48d79b7f2af0791f0006ff72a525bf7364dccf840000000000000000000000000000000016a8c96aabb813750d940d7da5f5c43e214d971e615f6dd9c6aee0cda7925fd93003f323ba1c30b60f2c854016878bf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003225c4f0f420334c2de4f782fdde19e3710151584d1d435f415559f5c3f320bff4fec8b600972ebba5084cb6bed09970000000000000000000000000000000010cadbeafae893a0f6bd09fe3fabea90c551977ee8494b21a4be3c945d7a84d4e438698b7d3f62afded7f4430e685eca000000000000000000000000000000001351aab4be82be8720b1ac0e6d87c88bd714732f5e98e999492f2bde419bc928a73ab4d8445d56d75f1c77f44cd0feac0000000000000000000000000000000000a0191315f15836aa46ee64f3c726ec953fa3604c2a2df121d5a1f6e56a03bd9ba0e9e4653c883b7ae3f0f91358a5261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be692ae928e281521ab9465f096e533a6b35a9e1436c5cb122c0a71574a03c7980b211b8e4627e1c3ab7a0314024add00000000000000000000000000000000106f396f6b3ac247c6cdc28c14f147de2b007c14ff4028ec2ff36e57e8c03547ec874a33ca569d29088452a3a70f90280000000000000000000000000000000019c58669d1355fbe838019f124e87d8d2adb051cdfd763d70c43a1d958736af0002a0be49997d21fdec7a19fda75b2ed0000000000000000000000000000000016d94d5968c790dc23c5f83a995d7d3e98763a4a05a99b0ceed7c19392932b8ceb729099ea37b94c6d3e671be10881841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8abe44fad75df26c87fe24d81c37f3ad9ae2296d44ceccc55578f1c840d862dbdf05617e35b96976fa18ad4e947cb60000000000000000000000000000000014401d2bbeae4169398f55bc8a68d89c25a179b32d43e33d790a1f57a2905bf76c24993f5c1d0bb8bc5e0da167c8ece70000000000000000000000000000000013cd2e983d82375856105ceff18d4f3d7c1f37a15c985f26bc4dfbd68fa9c17ccd4012b0eb6dd46867c8c11114217bac000000000000000000000000000000000d6d99cb4b90d4085fe9cf943aa24c064049d196b98bb13f4f78e48ea3b8e454eb58b4bf9148e9d2d0d3ed146e544d431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9351ac36ef705d824943a224e591665ad0c702a5a4f199e414b6e3b5c78e02afcaeb7e168a108e1e08a91e098bc0bf000000000000000000000000000000000ce8984f73998071f6e0e474c880ef422290a090d9718d1ea1ef26f199de2897d54eee65c68c1d07cf605f812b922f6f000000000000000000000000000000000ca78321f8d2e38a9699a653061f6e76a52b9f602780ece6ab9afc19f27cb24034c31fd4b9d4713a0bec252983d25a0200000000000000000000000000000000117c034af42983b7d24a4499e6b0d7b8ededdd1376a1abc951993bfa7f89d20a5157bb724f77489acbaadda17efcb5e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c740a9380661edfd62409a5c036f734a878e5cc122dee24ed03f277de70d8821f480995003fb361b4ea12c3e2f0ba00000000000000000000000000000000000276cf71f3adef5fa430b8dd2852384036e0474090a586aae38a66d7bcff663dd58a8cf6d341d2d2879b3680c17029b000000000000000000000000000000000a01d0d8a25a66fc3dbe3c4a11aa4c6ccecf5d3b594382836a6c26006a67b3b7488597267a65e1836cf9a89284744d23000000000000000000000000000000000a5ac2b43f92b0640174de668a35dc2f86be6237f40677f47c82821cbf55bf2a9b50498d5c2e7b70d5f2a2db1f8fc6841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeeed166d7b11e0c8b1c65092b40d16f8790d7860a9eee4c89f5d0a35f3238b5ebe1d4842662e755b848df09f3bcf730000000000000000000000000000000018ceabbb63ada9a230659ee9728b5f14cf8e857e934181e67bf040c42daf7de4affe5e41743cad6b5d3046ea8f03d25200000000000000000000000000000000049c863eb295b87e6619475e5b4632fc08f275f8f32a31cd97125fb565b8755f316c20677e145e0eec38520e02bf4eb2000000000000000000000000000000001897ba567dfde72cdf30ec183e909e04d808c8c23ebed817dbb4807d589a5ecc4dfd5f2fab486fa1a7767fc62e1e790e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076e4bd310f4dae8d66d4b53641269e5b379d34400ab954c0452fd194d4346005b1e0771c1c2471109f2eee6dc3c945000000000000000000000000000000000070cd80eb7d8c3ccec94c0f900a301dbf2d372dc8b602bdf3d4a0fa8618d701592852cd36a5dea20eeead5b4f712fee800000000000000000000000000000000156475dec4773a0418f669d40434b3f25eb9c2c96ffea2dd953bd8902a61f33d0d40a1a79b5de6c158b08e7461d027ea0000000000000000000000000000000007d998e9ffc4f02036d0ec51037063420fee16c579c30efd9161b38cac389148b50dca5d01d492b4dc4b9f6ae832d8ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7a326c00f3dab7a7db7858fabfb10420d369a7d30dbd73e5d69547641c93eb7153cb223f0963c851c3fd55d3eaa45000000000000000000000000000000000054cf6b8cc80016886573e09fbfb3fee0354f2ccd38f1ccf0d212c5379cb04dc4b3878f883316dcbc6552c1fb63360260000000000000000000000000000000011e635736a42174dc7516e0d04027094ff9cc4b93f0d03f44cc00beaf1147056c79b5e543f7e657754a1d8e0ed15dce500000000000000000000000000000000005423a00b8d5be1ffbfbb43669be726c95963d7a8a08683dfca1ec163f99e19b4a38e688094b8855a93be22200c52181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bd22069cd233033f8c1d3b2916470cc28bfb205373d8edbd708750f1757dd2788f54c86ba377ee48053977c71d99f20000000000000000000000000000000000d6a2074905e73acdee2a68962bcc4486a5582f3876698be10c2e5ec0a5f5fd098843481183343ef7475881ea51373b0000000000000000000000000000000008e86f0e94a8492e689adb757ed465d7682f57a8d72461a5109ef11a1d4936f294c5e9b4f5e56607b6345361a4c4c9770000000000000000000000000000000013581fde5f973292678d876c339dd5cbb6ce57521c2c4b2711f464354fe805c30a62568c7e3bacbcbef47cc67ef150791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114a17e8ad25e7406ee68a36be5102af45f26da1c124f14e4b371f43ebad8a9ff9edc7c4641c4281908751ed217684a90000000000000000000000000000000016501395e9c3adcdb4177be93dde731e2282c7ee8a2447878e671be11c91064e90fa445d548533a3dacde70b1004ddd00000000000000000000000000000000017a998652efe309ac621784d4a165ba2d0bcb907bb5074624f23f469f157b4918f004f4a34d246bb85cbc93401f2270c000000000000000000000000000000000b2e891ee80afbb636ea80a44e5e7a61bb5c7a295bf429e82b8aa98f7b994f9165effd787183db75ba950b0aa95639981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a659d7ea97bbb4443f9b7aedf2ea90628c280773585d76e9ccb934146a01fdaa7030ebe1169e66067dc0a55068bc7850000000000000000000000000000000004ab533e7a52e4f339cb17e52bec0fb7f329392805440333ef27bcc25b040ea37203d35fa7a1b43b8c056d3e3e913d740000000000000000000000000000000013e9e9d260b02bda35b626a96420a956e0757429396301cc1a40e3c50599f18aecce2076d50e9a3c6b75666a53d305fa00000000000000000000000000000000149e04d07d4775efd7f19b8a973c1c1956dc742bd65bce47f3bdb06e0b23ae7bb44e995b64139b72eb55f6ad2c4ee63e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe359021b94fc37795bda8c9f934ed1b6979833e2fc31fc3af7d21793d38a292f1fd1f476834e8263c698dae2eb4d530000000000000000000000000000000005a9caa42b02282f87174547ee49ef7207aac3df969049bf38e3f2d3de4ffefdc580003fc6a834ef4ac853212cfa458d00000000000000000000000000000000127c38a8128dc05401e44b950d1073fdfbcfd62c309554b60781ada7faed08548859364e13ae2611a8890c3fa4e4ff92000000000000000000000000000000000fd8dcc05bd1f9a9e0e6d886d7b7ea53df47ea44c61fc8a3f3b35095fe8d8e577966c672089f1faa46e0cf10017cca321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c90a6913b11501de10f3a49033c880e7c06230a0ee9fd7eb604c86464790228f4bfb5f7804377d25868f75b0a9d733f0000000000000000000000000000000003a4cc92f612b995cc7a0b414d6990e2f8147594c61b8bee7b2dcb20e50f0f98d60bd6b39aa4e7c47d7f59d18ba0d26d0000000000000000000000000000000013d269b30c504d8caa273b0d9877e4efaa87b95a72527ae960655c5833e6279bac03a3114c8f5b67cb7d7672b59a7a840000000000000000000000000000000009b3e68d04cdfd410eaaa29bdc4280292031431444da767ae9d4167c494fc464184d06330140b3a4a1579e16973a65ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c34dd384673fa91d37b444bec4c7d92379ac92bd98f64f9f7ad96f74c91ef190c5a9ec18802909a6fb77fdab582fde3000000000000000000000000000000000d42489679b07b93e23abb4dbe19c4a6b776d8d86c85a0d16ce039cf585c82d010081a4586884019b878ab9cb4b88f15000000000000000000000000000000001876216f281db581a351686d1b7c0c564b40811ee7f968e9bb0ea393d4cb610ec2fa24ef27db7425ca54f8614b55597000000000000000000000000000000000166292886c3728021695e28a18c48323e8afbd6c50f97ec22e89c2285adee2416d057394ee353ddb8de05f76d4678cb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011076613bffb6cf2b0bc8b22f9b47d379f6cf794877db267b0c489041172ba892ed2887fa4a935633720d15759c20dbd000000000000000000000000000000000d6608ffbdc80952c59255ab400b8d70b5e6ae325cb8c8d3a3130f219f24315de23d951923594bc8aabba23e81037da90000000000000000000000000000000010c8899827fd80778adce74f463a2f859315717492ed9fe9c28b5efbbc450e795d0ce4ee4255464d0575f7dfa66b23d5000000000000000000000000000000000b1132e2c43d4d7121b53765a83b86450b5141e32b1e0de8de4cd99772855f219e80f1960951798a45ec8e0a704b0d4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a8a6e776a2d079adea228435bed8883731046c1a503768a4e258ec554d960af0f3888f339d8ddd3d9c369e618488d80000000000000000000000000000000004119697ff4b5e5e80d0aeac8907147125fa58fa03da8bf9dfa15bde6a7f6dcd6d22bdab8fbd835704243938cece243500000000000000000000000000000000181d77bf29b0ca13bb0c63465c22e5767171fc1304c2e398e42ce08d736a770a562bf5bbc1b4c1d8bf38a16481ccdb5f0000000000000000000000000000000016522df4083d9fd61cb55268a193e298d6d4ff85e142408a2458f3ccfcaf6629f4f760a9dfa8614335e5f6a54d13e9a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e40b90704e1d011480ba4f23b55b10990806f3893f16f19b5af1b9ff912751fdb697a580ca3636556e5ff8b287ad2d700000000000000000000000000000000008e4cecf52f2173f13af160245d085069d176ccd0fde746536d22a3b6be4ce4600cb96abbe99f514720adf1b7f27c57000000000000000000000000000000000112096263a0f96e7cff6f4e591f81f83179bf31dd2530597d7e2a5672b743bc77a3073b5cb7e2ebbdf4a1d8c822306b0000000000000000000000000000000008564ec67c9e03dd82197dd53f97227a395e994adcbe78b8cc1ae60db7b516c1f655eb578a61af4be250ac80bc6cda991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012932453f18a7b9636ae94c301ff770ab9d4933ae76f685b1ba974fff080d0353fc7ba6f90baba1974d13c48dc1274e7000000000000000000000000000000000f1400c9fb9b5dd663c2ea0ceb9aebcdf8d278f9a6bfb0ca1bddb34c17bd48dbd9485507ab7216f6a8414dce275cc464000000000000000000000000000000000d4a1ac04a5e2e72ff0c02c4ed6e4f66bc3ae6a5575c3d5dcddb0c7bad3d98a6b6cbe65143f959c4c091b6d04da9431a0000000000000000000000000000000006bd749afd600587773530d214b79ae5229196ce71d86e052534f670bbed9ae3cfb5b61d181d70ef504c935d42d5af361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1c65af8305054ef717f1d97871a9fd706e827fcfcb238ac08be2fbc9fe1128e7460dab92bfd3a33a3978d7ac304b470000000000000000000000000000000001aea908dd74c101022c7e21c04af814bbe6f2114b3f790f761e359f1399677eda7ff1393b14a490ce91a0e6f4e8f35300000000000000000000000000000000163f1ff0b9163412551bc66618de7f8b2cfbea9bd3302ddb680566f93582b9514f17f8c38b75d53c5955b9229d0592be00000000000000000000000000000000101518c20316176ad6fd6b939d9b316b15c8c56cb7fbf833c5c1c4c4ba15ce2e4329f64e6c15b05ce1ca29889b5432cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001553d033b622a1f43074842b5a406beb7e19f4ed5ce7d8091b0e877ff89cf8cd8e021e82c197ede024f776c684dae62d0000000000000000000000000000000005f0ef9eebef4777792fc434b7376fdbfdce36db09093380b9f4c3ba674fcd85eb952ec7d5485178593a4104596594490000000000000000000000000000000013fb72b0e82b1e14ae41893b8c8394ddaf25e358943eaccb3ed912fd19e6f550abd6dce2541bb54b35b61c3a0efa4f9d0000000000000000000000000000000016035bc4c10f7212d1a4659d1d3f8e2696abf8f03def6c5207b8a0fb8dc82c9e543e65bd5692d66a4ff24d2544f32beb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8db00c8e27f6c9538dca2fb1ed120aed85d6c70f1534992fd69b19ec27a7f5f6574fbec880aea2c6076e2bf01a8bbd0000000000000000000000000000000008f1d3c1d87ca51f68b1101a155c1613bd60ec1aa2325f3f48bb39dd841eaccebed3ba053b389c027d8582a5801bdfde00000000000000000000000000000000169eec186bd18e5019125e8934d2621349de731a8e80c9224e1404f37daa81dc4097e10de3318f13cd6f8fa32aa4d2f4000000000000000000000000000000000d180b02b0fa06eae14ae2e629d57983a6be10c2b648773a1caab83c927d5dab637a8d0f7cf1ffd2d5a6baba3a131abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bf543c98b68020e26c5e8d03e81f33a6bdc8fca5b312383f4b055dd198066ae3eb15168b52bf3e4add4e6b0148253200000000000000000000000000000000112a6629a7814c8de9a89685c083f75306ea52ee7f00102f1fcf01065b21ad7c81918ba037af05703cc1bf47ba9c44550000000000000000000000000000000005ed770e9bbfbb323aab5ed5ac9b8d6cc38acbd613f2f2a7f516fe06136fb8cc6a3300a4f7636316886478c457567b8600000000000000000000000000000000090fc0325e97bf20ab51b6e45e77a99de929b7404920c337d811d04db43f829c0eeda9bdc1950fb2f5f8948fbe18b9cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003596c9296a8f7f6744836a05f7760a0ab6b4318874563e49e688d9c8219af0fb700657ad718123f697be3185ce2e6df0000000000000000000000000000000001031fbc80cea2eb8f5a1426f78851469f56630563c92c1386a198a4efae3f20fddf5724bf2ca43c505b885ff5ac4cf8000000000000000000000000000000000b2ecde10665dc9fa228acfb349c5844e937de601af24270ec9a03bba40fbb46d5369ee84d8b3d19471791f280fd614b00000000000000000000000000000000118c44871160322d1145312ca065430894a08da9ca527b2a874915fc7930f7be78060955cef47c1a56a21953d5526a331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b3af8dde9b5473c2de6c7ff8630c3a8dc102dd87ad1bfd75181df4f7a8081ec0259dd89a1ba2a4a757a4fd47b243130000000000000000000000000000000015096b7569d790136f95a58d85cca1b1f7cbc65587d45561abe417b3494e4477b773c0d98b36a4274c36c0b750d0b3fd000000000000000000000000000000000b29f95b84a4d18b31973a3b69fd956c873ebff362c6e0253149f98c4f4fdee9b42837a30830ebbebfb189be9eff6492000000000000000000000000000000000aae3ad137e91fecd02105995c393f88c95efc71f860120839a8eff3f47bbe2ff6a4a9f79feba374462c015bcf77ab0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004263c8d9ea0a330300cb4830ae76b8b7de2700bb5bde6b14491e9c47701960ff5d6c47064a09abc3309da278aa3183d000000000000000000000000000000000f1bf5c6bffe11a5fce0e59977edfa1c3dde1e0244a15e61b60b5afef379713cdc8dcd1118424703937f2dea490a65f2000000000000000000000000000000000cdd880536481144a2b32128659cedac2427cde5afea533a7f4307b1ce7ccb51831a8e8dbf24388de4896a9b0fad21ab0000000000000000000000000000000008c536eb64d2ab3a572c485e9592abcbea7e8d66f0da46cb216ed56f57711ab68c0cedbb24ff06315223ce95c88798b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001761a37754e58701c38caee53752502dfd1d21ae9593ddb8055ff2232573c3a8cec59d17a9f45a9c28a2437d50cfebe3000000000000000000000000000000000c1a8552a1f059672a1cf33a91815a84725db6008950d60de9c8348b3c40b6fefdcdb96a8b05b0e51df20ec59d95a31f0000000000000000000000000000000014398955c9c4c227ac2914eb88810dffa591357fcced5416daa7ae698712bb6d1fda60f93127874dfe4fc3ffdd703bb70000000000000000000000000000000007ed13ec9d402bf10277f2157fd0322f8e74844b9542c251a81d2f5e2b29d4ea00960707d3334923cb2fc375c4813a8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fc934973a609315413fdd01e5ba712bb388ad1b90653a77eee5785a873805d6ac17e787ee5c3d518ca6546bd4c1bd50000000000000000000000000000000003de2cce604421255271c12173256278c4205902ebc54053f6126f5b7db74a0280a1b937dc345689c40cd3e489e417dc0000000000000000000000000000000013b00489a1be8473d9f5de62a9a04678f21a985f6eb38474997b4cdfe022aea226679457c2b20660f63a297a91d9eb4000000000000000000000000000000000113336de707f7cbfca8c1584eefd11f589b450cb9ffc6a6170952a8a7c83c660105c0b754f6812bd54b25728000093ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043b6637277d95a91b09d7caaf198a1d12f174879eb949868a117650890be31976dabe4d94172a912df4e1f3bea5b2d0000000000000000000000000000000000b944ed882ded4afb80e38d4bc9198fd514db26a7a2961169b7345c355487ee6f43b834881fb76b1a15d5f110e45ff76000000000000000000000000000000001076a938b6e182483e262ea6460a6176580a7c85415e53eb9e94f8daef239728776dfbe4c9c8a95464c4eb08e0fa2013000000000000000000000000000000000471ed648662035cbcc685da843f14cbb5d4ec416265fbf289b694d11f8d265c49369e4179e4eaa85a235698ccccae2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094741febbf573f8c1abf410fa21015fb14ce5748c0cc9dee332b2cea95eb2c9dd815e24d7cacfa24bd1b81d72a9651e00000000000000000000000000000000066a66b8aa45a66aef71835aa6427ddf37b16eb65887a06864380d41e264df5c2518c11ae38c530b54184d223aa10e7a000000000000000000000000000000000a30edf74548a4a921e2e62c4bdde320f8cc795b4d749dccd832d2050deaeaf452a2b989a15faf212072b76a0bf786e1000000000000000000000000000000000c644125e1541c3eebc18df5b8d1139eb385d8945c6131329ed6167a200871f88c2dc15c7c5e21fba2f99f15d2e84e431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a58b10792e64bb58871cc738d0adf631a95bb6f006c1eeeb4b7905ed41bbda196ab24662b227e092c9988c5666bb9c0000000000000000000000000000000011fb6a56ba06a9c239b47101e6fa2d85360a55ceb0f6878d24afc2d45e63b367c176075f8a360e87f2b8a19f9d314d0d00000000000000000000000000000000036fba5dc42e68d18e9da3bb57e32eea835608e01d6e2c10becb328cc8423ee4126a5ec7bd1922e3e7e3dd5b70cec6d40000000000000000000000000000000000750f36d2ed2bfad5a9c99479b8e7d8d3113beb70f43b4c00bfe3b545643467a9770e461ab0f370f67512b877b73ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141fd961e4eaec72e6ffc8a6ec1c201533cbed22c71131e05a7af4eb862d749e33ee5b577f51e40ed066d8768b188fd9000000000000000000000000000000000ed253284e17c2860e309b17ac9297b33957d90b148aa181e9b56900ff5be90377f626cc94c85fb507b2ee30bd5210680000000000000000000000000000000008f09499000178f63a9897b78b50002d2977c1fec05aa63c8a38341bef8969eb01652f69f629c147d37a0c8984c69c17000000000000000000000000000000000527ff185fb07c3f50f8b56b5367e57300944830e4bde821e2a21acc81d44b39afd50d7dceab458e1b5a1930782c16841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015da155cd703fb6ba2237128e12445d218e3b8889a32ed0f806ea4dec2f9b5a91df6b87f6d798b6dad8ed1831e0436cf000000000000000000000000000000000e1cfbf18424dafcdddbd8d619fe04bf2a6970746413b443dbb7eae79275e06ae741fc8a5784931a63a15c2dcae43e9b0000000000000000000000000000000015f3beb0fd136cbb327d52efcd57aff1649a69655984b9228f46496dd72b0dc904a2d1622b67c8f646cf35f532e3c4700000000000000000000000000000000002831375e89e596f7fdf494b91af829bc2c5ff26a31685ca1c113886853aa4995d51da8899be70cd71ed5795c519c06e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025698a7d7adb1b7e214c9021ba8f1c988aac626bd62c8fafc55a446fbe24f22b3c3a346324c153e0768aee21fbd80b20000000000000000000000000000000001591c862a715f208f8759ca439b6ee477457b8dd679b6fa4fa4388c7c83d1ad4329434616ca97d330cea79bd5392f05000000000000000000000000000000000d783ef2c0e9c8a6c0220d2897d207192c46fa13a4f0a965eb1c2e6492ac264e036d975e7993f7e5d24666418c7d8f780000000000000000000000000000000011114f88ea27f2235d6f7025608c0fd2cd6e06284a5c91be92ae123391de35e28d1778ae2cc6a5a399ce9c5d5e5752891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006556405ad63aa3edf0520995023df56aa4ca5f89cb9f88a80df053d9fdcee2a7007d908b0fa54a838f9c1d95419c65a00000000000000000000000000000000106b8ada7fe9f96729ec1b5e597c964d4e410861ae1decd34121b7258b4e4b6eecf7cd57ef3c4256f7c1e5630d73e4e20000000000000000000000000000000003c7e760026812060587bde37f0ee36b1f98cb0dc673931da468b3f5490f0678a8aa3fb2daeac581e6ea4d12a750606400000000000000000000000000000000171666266002f3677e7210996c363f0173d62b633784a8745276a25f239888c89793c0678276b4ce863a3d4d3b9411811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091d5864bd824bb9d2557b68f9de3f031f719313fd8b9e53961e410f79e37290eac707fd7a5ee28ccdc4b83359e65c56000000000000000000000000000000000db6f8ed9bfe832899f6bf14b2ac4bca5ebbdc80218403312e72a4bc27c219b0021d831ce57bd2af58915950358fe2c70000000000000000000000000000000010bd2eb5b65cdb72900edeb058e5da09d9071130b68e442d523acdac27220fd5da011b9b7a572516d74d3fd43fdfc733000000000000000000000000000000001624fe0155ec985ea2e3def4263b9b97928620b63793e22b7498bf83218ecc3c6cf9803c447ffb8723c2ca0fbe9f53631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c683dec0c017398b8a33f67077ed8ba39099874a75cfef7b35171c329e4bacb0ea931264ef04f1b1b77e3a93e295ccc0000000000000000000000000000000010ef88938593a56d846065eedbf72185e67a8cde91f78c49ca1cc0dc8b036967442b6b56a22449911c7c4eedf52bbac00000000000000000000000000000000003cf7d6d1515f83c35d9fe1c75340bd05b5284c3f5dcd08de4a0df6480734f6b91d8859ebf506f4b390d5bc937d0062a000000000000000000000000000000000c17332e7f0b062f1b859ebd46a99b7164a6ee9eb2a0ac4610cd79772a0b7f50f4607c267a028ffd642016eec0ede8c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8cd5a74b0bf0ddeb256cf97f4505247e5b53199dc04be1f3020d0864beaf208c0a241388da9f15997a662dd4f60733000000000000000000000000000000001421d35626d2367b20a0c6553bb00aa59b8df8d6f41ef3c02d4310927fc9ebc37a32392cfd4b858f2d045fa5166915b70000000000000000000000000000000005fcf311b4aed4346027ecb663756651b322e2fbc08aacbedd19cd4d026cf0c1b9a186254df6d0474ec644ed524732ae000000000000000000000000000000000aa7377e3500a797bf5c58179e2cf31398a07dabea5ee995962fb7ee437e1d8c3240dca891446fe6e7ec36f1da957c821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c466ee9ca224efbeb025f1d69e9b2ce25c2ba096801ef3f51da07d982ead125702f0e11474fdb23c3be32ffd165a6320000000000000000000000000000000019ca6989fca100a5ab0cbcdbec95724f2ac002811cd3993ddb9dfba3cc1cad206e71b612cb0ce3be4a85a42633321322000000000000000000000000000000000ed5fb711a2acd6456ec2da9a4dd2f1542a8c0796ac0fce2e24380cac6cd8573dd79586167a55fb5bc0a2585cc1ea0a800000000000000000000000000000000158c20e4dc1eab22bf97e75d9af4a00bf759739b84824282a2fc4f5ef723510e0ae305e4783c2c6b3f1a658824c19dbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015fac153f91d15a5c8158aada69d56fe4fcda32fed73da6141c6eb54feacc96f4ac79deb711f4bb711eaecee2f70b1b0000000000000000000000000000000015c7c796d34ccfda01c014742d0372ab5d172e345c64fc0b9c5eefd3092797cd71596a91a10269698ccc5617dd64a66d000000000000000000000000000000001482f722d2c1cae7d7bf30419b939190d198f6a74e5e29de8236c5f116eeafa013646e328e13a22f98425cb5346cefb10000000000000000000000000000000019747f33ed0ef91f0090353f5da1e607f462391f91f179b89f0e4072cc9151099a78654787b426d3573c99b18a6226be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dc2cdcdee7ce704348b19f03d9719d25b01f7ae2ef06bdf5019f095022d724f6740d15863cc76f39fb3236005ec041000000000000000000000000000000000e5c695835e591cf4175252b87979ce87dbbdd71bf6f43104d40ce2eebae184e01d0f20011d674f9a1d5593007670f21000000000000000000000000000000000495db7a051e7a410f8f2422820caeb7ba0305321d1d3e4bcb0f28c9fade60c68e325d8ac8277f52d4eeba6f4bdbc459000000000000000000000000000000000135a21462d7a49a7c9cf7912b683b83ff99c9fb8204a88964deeb43174f7caccbd6adfe3986f0b1912ebfdf852d4e8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf1d665765d7b4a19ee70fffc5521554b428b1b3e76d3b64a4b8072d7800f7ce2f5ae589eb1fa77da63f3f8957c6092000000000000000000000000000000000cd4ae3ca4ecbb7451f942879504ce9b2197fe86c19d75e201f16080ae0e7fea09c3397eabb1256a095722ca94872b17000000000000000000000000000000001506138fb2e2c0c3b37eee21759c5e31f2a2ddcbf89a6389b09c14d0efbecf34b0ef1becbfcbb55ef5f987e8545f80e700000000000000000000000000000000087c6167568d2fd49b8901e0d8a487d776666199ce37a5a022076bf6c45f4ad7980d7144de3c6fdb8079b43d9d530e601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094a7138c5791a68a90c2d59366fa12794838eb83f82cf7acb0a7d2657cd55aa83e81b8342426d1e5f180b4176de79ce0000000000000000000000000000000003845ed19a6fe121f4b4c09d50232dad512a51dd0a496e7a2dd37d1c7a5b779c6539e5234fc6cc30bbe3a644127bdc4b00000000000000000000000000000000176b8926a5732adfa97cb3fdb7ab5d70264cbfefc79c1222752e847e5545d278ac466f1bfebf317abc6dce42bd616beb00000000000000000000000000000000048e64336bfbc1c0b004a7bb00f65180f7c7f213b565d1133b0b31e79262eef477cc97362a9b8046d05c7e81037a688c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010797e29a4900b5fe01f75ffe3f640e6484103c80e0b0f3aeaf1c4f79dbf86b154ca8f6d2331c13d8af2c13ca82d5792000000000000000000000000000000000699bee300f14f83c19ee47ea25b4c90cb1191a00120f476e582f3348dfbc78ed50625533117989f15b2f04d6ae9bcae0000000000000000000000000000000017291005915567d8c3d7389bf3986f0bb2428e3a03b6ad0c2b0a9335c3036a5023ad11fa1188078683f1c9ee93746020000000000000000000000000000000000663496a95a79c05fd18ac27a3138a3287f83213e1b76a26bfb194b491a172d7b87df955ccf14eb45a8e57221cf8ac4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cfc9bfd507e5cc70ba4fa6c9f68eda8ee3f7c0815c8cfff63fb7809087f112293e9b31f8327eff59016f718f68c4e00000000000000000000000000000000002d039735aa9e34261ce3ab102bebca08d157e6ee56126bb8fd1f62eabba1b6364bed9b0515857f49c769715115561390000000000000000000000000000000004946c5d0508945d3a31c4c67d2e1f3b963a05b468dadca126c7ed38255e1d4c69a0da8aaa40c0368581df4ec91316430000000000000000000000000000000017fcd079e55e6f9dbe0890e81f111b11a9e86693b2864a549b884e8d8c10803888943ae1efeb01347dcb392b04767c091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133f9519d4cfb9e6db6dd9b22a8dd8a566f49c1cc1d0278eec4abd178b44013145363dda08b71814520846feae4ee5b200000000000000000000000000000000014234e365fcfa6c4e8cabd3f4e54d8885b1558111cae3d360dda8f7c039a9300667b7c00443d7736b59c6b324c51c4c000000000000000000000000000000000250ae48806537ad044cbd829105d01bd0687c9991a4d585c2e25f1bda7e48eb05b6bb994f870905265634e2f798464e00000000000000000000000000000000070b9ec7eb94797cb4a02e9969d8c1ed222c0febb84ebfb8f164054b96483423fe828e21ebd59e2d4052f26c286bc0e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a8167c191c06a896706beacfa8f71b971f1f9f64d8e8555c720f5e8ea1460715e3c441372e60b93253a015aa7e5cae00000000000000000000000000000000056563cdd51061f617754b658fe2bb36e99453ac79b6b5a3ba6638a7458d721fc146316e8112ab5bd3f54b8281bfb5d1000000000000000000000000000000000b36a794b72050b997d60205fa7e0b1fb5f86278e4217263a82b5ed774f88ae6994c9cd0673c2fc10d7ad0481a1e99a4000000000000000000000000000000000961ce2970a0efff0f0b8689d0db831192526ab7b43263966f17d9b9e20f8e24af56939db3f5081255923f73621353691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122fad5a5f9b8e9e4121a83f5b5b6ab0ab1e7126a4e997be86e9214e786b22ba19a20bc3e54241df3f1a5a0cdc1af2f0000000000000000000000000000000000a6dea66e830b60826397a49b2a96b98adcaeffbf9285da9c813d46880cbd171d8a6799261b970d6a5480565b46f133d0000000000000000000000000000000012e15feb89478bd82e07911636e04a7cbc5b7cba58cfd55ab268274ddcd9d34151ae58962c30e93741d9a99d3bb28fb2000000000000000000000000000000000241e74ac6acbefbb94f23c2a488e59080b0003d9db02646199776a12d621b8678d725a094089134f20b0cca77818af81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e6d74a7a1616c42c6124c86eb2989c0269f440da7bec470c35e6669d422ae4eb6a7d0b2f1d8cc1632f3eee32498bad000000000000000000000000000000000dfe924c6b386852a8f80ec12db58740389d3ce23b269909485d588324e7d47cbefe051fe4c0f8a225d11b59ff148efe0000000000000000000000000000000007ac6ee8a33a17339860d3f07a63c3cddb72a29d983367c8a77a2011f62379d1de0fa0ed8c5771eb0215f629e7cea952000000000000000000000000000000000dd18723b7069beff825684a49023174865c36082a1ca749c8ba39341d3cf312a28ee0ee48368f5e96516345ec6132e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000388eb87d87878e4b9635865d05492a10c9cf6a23abb605c0aec50e0aeac819272c21277525d8cb8a27f5ff378ad38f00000000000000000000000000000000016cd0031b0c47a0e73d43e0cdb8c25c9225e6c67cad318b55136527285c00884827eab6d7b6753adf6ba61e00effc894000000000000000000000000000000000d85f9850151d07ba16feceb7f7a64585cc22202ae58d5d6637017e61804bf820f9e928b25a0bc1a4b202ddd6545a9dc0000000000000000000000000000000014f7ab9bd0eb8e7da04a8da89c731be6ce0882adcb2588a5880827d6b616e736c798c988c0f084d3ec6e6ffa4cdd22731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d33b656778ca2f10ab3770159671f297046dd1c75f75b3c456b464060d8dc61701a3e0198bd03d646654d5f11fcec10000000000000000000000000000000015eb4d601f16909ec3c3238a6ed4642f006fb61b84327bb16a51c2fbe10bd98ba5ed9e2b136c4d65b8909b10bd3404f0000000000000000000000000000000000d55bcfec98de5904faac277e189506e9dd4d569ee96df512d13f58cc2da9a08effe47be63507314b8d2e392cb7bf079000000000000000000000000000000001139582b42f59692e72dfac3c4fdfa34e95425f11d32609b6e3761922156b8bc493d00cd8c1078cbf127fc3d9463d4561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001265fb7bc6ae46529c3fc46add2a7c68d997b1227fd4106281174ed8e65622bfdd1d81ffd48f9f7112452748eaca37df000000000000000000000000000000000d1671659a49c4f4de7f5453c07577411d307c88fa64c5c5d9c81cca4c7c9f9c39752f39fa472607ce507b2c05c66a470000000000000000000000000000000017b87dda4b117d3609088eafa8172a3ff91ba3445a6df6115c0756adc27965020e0a605e3acba2fa2ac9dcb922a01745000000000000000000000000000000001044d4ad9f0d70ad50511356a0a17429320b3ed07c963766db84374a50c21f0b4607bf4a4870a0ecb100343308c817ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba377a51a85e0e666bffa9a43aacabf498505a460b287523ee29444dbb8d88b4f580cb685e7b6aec86dad08963168f6000000000000000000000000000000000635f9c31e4bae6b2f5407fb5d8ff45d395a051770d47f66f7ffd345b6899f2141557731852e43d505d2c1ccd9b6b776000000000000000000000000000000000263646a22761d58ca1fe0a85a021dc29c648826894e924c312ba92da45ee288304c353a2760b779dacac49e1cfed4380000000000000000000000000000000000bd5d3705bd40e93431ad76e63e4a2215d91e0c456cb8bfec5deac70a8153c01ff7e4ec88e0ddd28df7dc2b4f7f37ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001558820efcd210c4b87210500dbf928bd247ce9f402f3ccde9cbb561e7c8850f279c4c05fef06cd24ccd6f658715798200000000000000000000000000000000189eb6e2ddc6d8bad1615038a32682c9d4f0e46c1fd7e736ce83da55f1d7057f637f2dc94a5091e4416a642b5831cc9800000000000000000000000000000000173fa28171ce4c4327be6d359a83ed75e6903f3af8e73c89845c5848af9c0b0df4e7b0ce5413112c26f10654bfaeb42f000000000000000000000000000000001722a3d3a3b6e639d70850e0e1df37e4984f6309bde6097e80f3de752e98139415c54b8682f03df56cf043f27d70fd311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000835e86b09c7953c0631e6521d4eb3392f7044944534a7b2022ddb53ab9c7f5ed91ba311196348a3385b5cf503e44bfd00000000000000000000000000000000015c95f00c6908e2bba970b2e08f95b2a9bda9b738cc045f6cfa91c259ddc29d1dcfb4815080cb87595ff77cc27616a300000000000000000000000000000000130dcc0dfffca7fe40aa6a29dd73ac2a7762b5a351e52bcdf11bab5d84538b307bc7f2ddb6d09150d59ef88db8a06a8f0000000000000000000000000000000009d40bfde86b0f658e55ae724660b55076ffa73ce8c8ba19f41abb0c308cc07996552ed61318b737100bab5038fb5a711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c383ba6282e9cd17b676f2ed0e4cee0600b1ff848c156e12108d85de8187e749833bd52d79d247562b1d2647242ca9000000000000000000000000000000000d425a39acead53d8587eec2ffb1dc1e59e335a0449dde28f2a000e31a5ffe4b106512274bbc6a254813481e8b3199770000000000000000000000000000000008e9fcde4c67faa5d243f234f8bae794524fb03d5ccf660798ba764e9754d89f77698a51cc195c82725ac4b712f5a3940000000000000000000000000000000008938bb9d340ca0362f9659eb009286a82da813d5f303dfb3c98caaf6ecb56dd12da34a52b055ad0192d7411cfd0766a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e364372aaabcbbdd1db491bc5498563d2c618a6dd4b945e01269c0d5ac7d9f47cc9fab05dd89e964a32f313a959ab16000000000000000000000000000000000f53d623291a24a7b16b0fe662252823a3cd13f51d7e17737ff6051f126545fa8a9b15f259b171bc80a4c78d6d85f8a3000000000000000000000000000000000a835cd9b48c61a526b54e346a5ac9f18be8aa7b6102ec65b406802ff3e3aa311f18fab0eb94632e67e4d12baa58f29b00000000000000000000000000000000159c9ed69d46f49d0f6bd4af7e04c97fde0396b8bb01bcc2b675c646a7cde81bc5ba7c4e9f9b8aed2e2e03df1e32754a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000834bd07f5ca9adfb4e8a6940c655f53b1754c6c41cf33f13568d8df974a9ed496d2464819d073a5a8d1aea2034e46e000000000000000000000000000000001712e1c7fbcb92df74ffee1fc0e82ffed9d3a27f6c39d1f46415ae06af12e7e6dd1ead5f709615eb064d2ec4634ad922000000000000000000000000000000000f9d5ea43d714f231443a84e751dee453c0fe8b1def06b0657dd2b17acd8c6391a47437600557b790ab01dff96a839d7000000000000000000000000000000000353fa9e8c50f6277cb1b355db14bf424b0b88e90eb99edcde637228a6c98d6454b1efebddeb77b8647f87aebcb39a901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016151999451c18622a388a840ebc1b35e0c038f80d5119ecda1ce780983c999b14a115d101381bbc703171b3a473fb900000000000000000000000000000000014afde5a763a70668dfe631a68cb001369fdcfa1d484d2dab37404c9e587040da68b304e679fdbdb8a11f8be6215e5f80000000000000000000000000000000014acf3cf03328dcb4bc73bb40ca05f590bd1deab34d7173535bad07c501747d12a05f8063b1a38fa821d323011f3c78200000000000000000000000000000000087354b0e64839bf7602c2cc6505ef530b1acf7fca88b05e03486f9abc548f64dc79b21df28b3f6c6b308fc0c2adc8661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d2b23b040e35db312cb41d76ef57838956d32f459ce074559df425b7ae462f6bcbeda0b715e6ba0bc69283560f6944000000000000000000000000000000000736eed339e66933e7e083cdd4e48b3b931ef4d8afab0d601605536871435442ead4e824ea37a0f2113e50f98c3052a000000000000000000000000000000000130b83a227feb9765ec77ea6ae34d787017eb4f60849f60a78801d3d80b5e3f363e194094f748644b18d2ba12b27c68b0000000000000000000000000000000009c33360e70b2fc08a8ee4d5c5d56ce1078cd5549e90d7246e9462934648bd8b062db2c0be8e8cdab4d6db776b47961a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024b13eea5366357fa852bda231dd2d17c405fb405e903b3cd0d5538a6b829ac428f565193ebc77e1376f70ff03fc3df00000000000000000000000000000000147d549543c86fe83a7395b6fe5fb9b1c28561eb51f5b6212348183ea1743d6680d048cc881a0e76d605ba372a3e172e000000000000000000000000000000000434cf4cd629703fcd75c5269fd17d92d959acf10f20383849eef29da56947f2f2d6682d4283bcc8dd3412485ac60e320000000000000000000000000000000000683431fa5f360ae2a367cf8d9f39eb261a1e7c4617a4a43cae1cf4b3c1310d91450b26fdf4c5d6261cabdacbedcfef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010eeb920fe41ce4952c50bc400db650fcca7dcb8bb29ea14f1607b2c1fc604f6fa4d3efeb8d6cbc79231e0216a9d89620000000000000000000000000000000019b7dd44978f46bbf2a2380596fe3551d39f426131421d5f470a5b8ddfacaacc90fd824cc8bc2f8759ef6b6d783dc22100000000000000000000000000000000088de28f137d782a6647bc917e7b1b3e4f17d4ad7098f4beda3373814b0c3bcde6f588fec3bfd5276ccf5ba18bf10e9b0000000000000000000000000000000009829f39d63616a3c3875385b12b9f029cc7de41ded5d26cf7d5432be6c08c9b09f9c4f8464d35c2e9c4252ec0809ce61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d2e1f4a6eecdec53b63317b171dc485192988107c7e2aa9d3ef84f5ca7c3a4006646e9fca3b8b9ad451779a61031cb00000000000000000000000000000000164d567c6d6b8e3f8df6c252c918c124bb0bf36dc9c98fc1298128a909cb5de1827e5cd3dd62ebc42a9968f87bc8c6bc000000000000000000000000000000000c0dc7f3d9b7ae6724cd374b6716da9dc041ddc0b78324076f40e0f9c86a9a02b001c825c09da258b0a8175313b3a5b40000000000000000000000000000000012bced71cb57dd2f70907925a3ad6835900e0acb8b370b7297121641d5abeef473d6e0805a024b99c4e15bb321c0e5d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001539a337111d7f25dc8460aa6f2cb3b1f0b80433cd437bad0addcfc6f376be4736642dfbb8dd4411ffb80e30c4dbd43b000000000000000000000000000000000eaeec4f453cc0e3e814385c9d84fc41e5ab7567b89e9162df0078804ac570432cd8d7e00dbcf45e3f6f40cf7c8e556500000000000000000000000000000000036c6a34c42943a156831c350a8e289f319ca60fdb4208a048197a16d6da6a875356c8b5ac079e49ed0eb44692c2c6b30000000000000000000000000000000006ad0289b4a108d41dd864ee375ac17e513660e55ba0f10c3ee42ca311a9c7dfbbf0b14fbd771d454c56b7baba1bef8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ba8f35367eacdd681b5d24ba9cc39b8f2635975d87fb9899216c51c6445cd6f3d7e7109ea2fac0d0cd4c0767e2d30400000000000000000000000000000000084d88829dace9719d2667b84bd919ae2c5b14f845c38bed640e2fc91b114a568d67fee11e66649fd48760cd60dec3ea000000000000000000000000000000000c1ef628647e9c967eb409a965eed091f47dec4d6810d4fe4a15e3292e1098a8f621afa05e9d0e0a7b77e41944b8ab6b0000000000000000000000000000000006849a02accf1601750c21e11cbd6cfc7022134f19771efe49058000c6994406ac3325054b314b9d9897390c63fda2e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8ce4c439446732e3f13c81658f0dd0506ef6ab6232a5d539dacb75d6b01990efa681024af1bb50f91e2f2b57644488000000000000000000000000000000001401520246d9116f2c53f69258a3f6d3bb10b660e3325950cc451f6c125fc375378ff8a359ead4097829d4316f4b46d4000000000000000000000000000000000c4131f86ab7d4864d555b95af31163b5b5f48f03b4358b5ef37b24a957eec32d751a490e28d5679e62f6b4ffc9f52a1000000000000000000000000000000000abec50a41637d879f77091d8db1fa8e1f1ef03cd964c834277699b2c32041ddbd21343bf0c86b5720a2800ca6ee7d4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eadbb358edf3863827f7cdaa5c532819a8ad21066335a6f4fffb27588c483cf18ae754a72cb660b6189beffecacee30000000000000000000000000000000007348ac60a9b2d6b288f412134fab783aa15fefc0daa5702621852cfd15a70d9b2d3dec7c9d9598cf871dea1934750a200000000000000000000000000000000100483e1710958f1841f9f4b588850db0ed179fe442579bd20b36bd6de7e2a93818a77e0343f54da6159c55c3aee1ebd0000000000000000000000000000000016a4db9826d9acb35df1f9f59ae04434700acbc62f91a36486ece774d730b8ec0a8d8cc92cae2d050e8cdf68b576714b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000414ec2911d0f8af340d440f3084b90f03a7fa2ee8af36a3759bcdfe47dde74a6868c6141400200b4ca2d42e62588421000000000000000000000000000000000bd6d392c3871d0b23e69081cf347dba0ebe1403a95d221bfac57be00b0ea227b7c1e981d21b63cb67c756229f75d1190000000000000000000000000000000001a2cd89a5f3faee0b57464ef350d5de48e47a938c40ae0aa721dc503d064b4b7f7cd883457f7b86a34820137f1e4546000000000000000000000000000000000df9624b6676b1f5e869c38499816c92143f81dbb01194770e33b8a5ff027b20a33825df3465c575ed14108ca37a360c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001851a9ce9ccda98a388e8b0b057998be89a046b2f6d55a81fe0d47923eeffb249837f01d57679a70d55aa7a5920023b50000000000000000000000000000000014c6bae92d2d6866cd56c3402869acb0e15f888aa5fa76339c8587c136ee8ff7e0eeb5d02d8f97b7fee7fcce496e0fdd0000000000000000000000000000000000293a1d2dd11527df30161cbe1676bb714c31bef22c95282d0d3c29af4450fa581f6af53a2e2c586b964b103f344c9300000000000000000000000000000000179c341177a4fe720d610355c948b7989ef2f93d7214e25fecd270a79d46a352f783af34b20bf950ded31f06765d709a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8e5de0f35982c372c5656645f0def721b5e0ca79a66a6ed57624ecf42103184f6a746dd39c77d94b14abf6b3d8bf1200000000000000000000000000000000019cf04a281f19b9363d0120036f63957c4149595a21a16285dfc2e88938b41e945f2b565b0b249a250aef65cf28e99c00000000000000000000000000000000142bf0169d953d526735d32b4dcc1af7922b94bd388812a539a05c9621c80262e977a46b209110fc963d96d8be97a4460000000000000000000000000000000013b5624a26c5d7b67e79beaef451828c6dde67d11bec99dccbb04b2aee6db1a570a4b4495f344cb64f6bfe5394f5917a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001221dfd9cd5dc7d0b2e1fa532b77447cc405aef2d9a2332f2c515987247adf37f4d6b5db314114b65129c174231ca5e30000000000000000000000000000000011e7009f332391898993d631bbd5a0de29a4226a9555c80fd310c57a965e950578a3d5b7d79d78e40f7046aba94e310e0000000000000000000000000000000009411ab0fc172bc18bb0e6fc2328d351563934cf363878e3e67c9de7f580559109ed312bab68d7457ddb93957d9a10dc000000000000000000000000000000000009eed5fd804bef986f8c15589b0ac94634c7f5fb82641970a9582c7e30fc500726b0fc4a34bc46c2305660a8d5dd511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ed230d374796c86a5ac71fdb6317de85e35da963d242562c5e812b1eed0abc0819049c296bc1b38317e486c8aa7390000000000000000000000000000000013e22f39a8c2bbcf398043d54b1ea8f1106d137d179db281548ad1e0975f87d9c1d4b5b7ce1bc015d1f3c9f93b8b8747000000000000000000000000000000001498cccf4c6d8fc2007c18a7f63798b981fd986452af21f96c67bc453c459d36b49d554666285d1c1aee4bc8f73dfc370000000000000000000000000000000017b6fb9e4bbcdeedf579fe687a40f60ddb4cfe881509684eabf28ae933478f82af6109f2a4714a947eaec73b368645fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096461ba3aa19e21b5d2f6d9ee6bd3b2fb5c46917f47e896c751d2bdca571aa16f1ff9f03256c7e268fd73c79d2dfde30000000000000000000000000000000017e79facfef179527ed19f8fd21927a5db2b10fc3c34ad847420d59df6e4999ab24a2ccfe776707ea8a6ba38c807a6da00000000000000000000000000000000159f535a1b2a97410d361c5c3935bd85884fd9bee4355833e1777d24005480eb6563b4479aeb20f42cc461dbbd32a9d0000000000000000000000000000000000202ad2bad33895f5a046b4c13231cdbf7d26fdcf3cd754a512e7a0cf8209852e07443f62f6d70a01815d0f5026221a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090ca17c3a27aea9dd866f3a3f1c49eb98073b42933e2292ce6b74e165d61f71ba2b16a31985987eabd473856b7c1e550000000000000000000000000000000003cc688b3750779e99d9a7acb2692c0b330e6d1d43081dee9060cc85e9c1b1a70fd940d2e236987866f728262b4436b20000000000000000000000000000000002e140e1972fec8b1c975b2ef7dbfc19774630fb64a6b0304f181ea4c5e20c22245ea4b354ea70fc86032d1192e09cd90000000000000000000000000000000009173d4d59ce7fc35d9bf15840f3f56a735c5e0a87108b2ebe5be19d3b4aa690465cd59ef2661d0a3d7e88009c346be61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016307218569b19c148703af5f321698122baf03b59251e0cd0469bcf7a8a20d8b9e54a16d2dc1f4a2e2c2c6fca95ea780000000000000000000000000000000010d8ec69d5ea3897197bffbd494e13679b82fc48f5468e4ed42b4bdcc8d9e0870e84c70c1ef0a997175ecac162f99a54000000000000000000000000000000000abd8f45025a5342284a746e2d6ffc476902279f81a7eff67c161c9212a42f7598b5a213b46711d014f0635ae41caddd0000000000000000000000000000000004747ae66bbc88b9838af8be374a84d914548670cf28885a49fc9a1c8dee736023f8819b1a72c1fcf7bb9e175667038c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d65c68026fec5ba5456025f4c08b63669b486ed1761ed1dfdc40acec99490833109dff7b401ac0ef66b7ff67cd3466b0000000000000000000000000000000014764b47407d0dcd32169e0a1b83fc76c0773c8e511141de9344f64e8ac63f5eb48cd8b5c6c54fba4326791b512525320000000000000000000000000000000000cfcb716c322857a46d7a9d2467d4ef1f520f752b7f264abd4b0ee4e9606d255cd5493849ed3c9ebd6f8681255ce53d00000000000000000000000000000000010ea7f244f9c31c3988c8e8859938881de9380c0d773ae353207a7207fe5e11cf52dadfe79c96e5630e916de41a9da71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153d27abdf1dd3dee817d9262dd41e54134d8ec21c350fba833c3a9105b7695967e4d1bd5828a42a17a49baaaac7d947000000000000000000000000000000000b88ac63a84dfe3ec5d12bbdc2c91d6b095b2232fb071d81041462a08e6f82cc376fa10821e3df609bf5d26d708d78880000000000000000000000000000000018695c06ed0769453546cd1ab92af6e6cc500b0ad74b664bc378eae8f6ae533c4163316a14e98d084838274527a4e3a5000000000000000000000000000000000afa982eb924c3a70b47920210986d3ee3660e4c1765377055d7c9a087112e68023264f7b1bf2248a91a3c5b3468cdcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eca2992a6208112a2bd9af4f48b7b4b64f23a4745ccf6e22ab271b88e4d1a9f1dfae50703dc408f4a917a2685e53f70000000000000000000000000000000000c291bdba0e6aead00c842c522baf92fe3c53117618e8a7e3df9bf110619b5f01290d291cb309a651dcb49f65e470f000000000000000000000000000000000179b4eedccdbca1966b94bc7fb5da250656e92243f7c4d301be858733ea73f49516ae25d6f5257e60285865ff26c1ed4000000000000000000000000000000000f1e7a0cb3a9d8c5dfb5b96c6f01afbd2c7cc5542e88184d8e0f72a6c24916e91e4f8fe2690c9af8a9d82cf737f02c111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002431782eda44ad08e1b0eb24da6effddbe2488ec70bbc81c0e47fc384fab905070bea968fbc1a9fef69ee0163ff0f60000000000000000000000000000000018434211578bbc2be210c29cd3820b1b8f99e4ef9c39e8db8982e6783f1be62ea5d84c8ff98ab420386590b7b0497f080000000000000000000000000000000016b1f18bfc818ac6f8b42b8d725b4e3d108609b55827361734a1b178d567e5a91375118089d59f0096415b02f80fe6ca0000000000000000000000000000000015311675dd364849c0b15b3e68fe3ad222c381185a95be25233e9f72b089b271ba4450db5b5298e9ea9dce5b4f62ee951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001826b931f8f36dcd99855fdc37f2f76fdc3831484d9ff9d5a4dab19dd80a78f698ea26fb7816438757c7b43f85ac3df00000000000000000000000000000000001cec37a4c3a9cfd37d47199ffed888a4e08b8926cc81c521604a9102f45e5fb45fc696dd5d6c5ff8ed5feaaaaf25d610000000000000000000000000000000014b01fed71c43b1b2763ba6adfbfc77faa1d05d8f92f96b4d1d27513f106cd9308dc4a8d14ed63ca7f885a36c92aadb7000000000000000000000000000000000692cb1c34322d501e07cab7e9f65aa9b7ede69ab1cb51d3a46f3523ba11564b3d6510f42649903d98c6f4f640c1e87d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f63a21485c9b69c46dbe177e5d6aae9e0c0972450575f85cafa41d38b701308fcb4615231bf3670d2c65e5968931e7a000000000000000000000000000000000a2d2a9ecacbf2853dd9657417d1056c42b62904eebb1e2a91297fc73ffe22c09d5a6fe6951b7b3ac799fb779fb8c0d700000000000000000000000000000000170ef99f741779fab6443e58f54131631a337d1a51f50643f3bb67f79ed0c5d4f76ae52541f141e8eb7a12f1fc9a0e5300000000000000000000000000000000017ade664b2250785a250377d3a2d5867c32b8558d886a0391816f200bf90d3d43a69a02461af75f5bc823ebb63241411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000976091509c439fa6d0a28ef740be1d2a4adbf7adceecc68193884d3c0991f995bc4cd157ff8ba01fefc7fff9fd605e600000000000000000000000000000000195e4b6d8742b8ad41b226ecba866ca0e2e19f132d2421110256e71c8efecd08499928796bf0dfedba7e5a7b5b4ff8e8000000000000000000000000000000000b238a6569412720060d1044e4d22d61279b8bbb5dc7036577a1c7991a2ff18ca04c5522399890b22555ffdd4e3e9e94000000000000000000000000000000000278aee8ef24f25801baafbcf353f1ef8d0b6d78e5dc248791a27b050d207688ef9180512098c45ffa0e342e6971e5871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e2d0cd0111b5d5078c9194bdd84158c7022ebf87a3853b0ecdb9ad1d661a51d742b2371769f62f4ea8c0b622ec7f5f0000000000000000000000000000000004a4e735ce00444a58212ce7151bfb09af25a9d605f72e3945d7c1a39e06d7be45c65b4602e39708d1aee1c66280831000000000000000000000000000000000181ae1c4fc4bb2e998a3088f025c06d5f0bb1211d162d31bcd30018c3d12b05796458eaf46cea9c99014c40ba3dac6110000000000000000000000000000000019514645ef5c815bfd4900266363a04d76a8aa4846feff37c95425513bd07c413b290e45ef6768546c575ca58ee6a1c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159716deafd9486d82c1edd265e334d58daa3f715a89e0b138b2fb5be8273e0cd6af4573804267e3caf1730152b3f838000000000000000000000000000000000c5efd41e630583860e09e28a03aa294da83e21678fa1d66c126cc414d3e86126126c5814a1272152578e8227c66604c000000000000000000000000000000001003959fdc8b53df3e29f8c78e155aeb88fa1338e978fcdc11ed9c0a8c8058be73eb2de6091c8c2c071ea1583360c57400000000000000000000000000000000104ccb8e8cc1edd2aa4a7e856a3d655b3fe3a3cc29fe7ff6431f490dd783cb435bc04f2c0ccab28da7b6b0b9d988cbf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001212a2c67dde7ea1e34f8847d6c1ede1dcbfb09c9e4fbd60004aca8ad0e116e5a6ef114682a2c3eed89a1155d786746b00000000000000000000000000000000016a6fd89dfb33da0c3ad21f49b24f43622932d5554a51696182137cd2b4e75a182e99f26ab350b724e9fd5a97a145f10000000000000000000000000000000018ca96cd152882ac920b7b3373cbd5d58f956022e3bfe2b5fb943f663a5026c194f32fa0ba66493e92246435ecb27d9d00000000000000000000000000000000135e65ddc9ebcd7587408d79a460eb3a056797199ae736ee24c96ed1fe7af3c0b06181aed64683b2ca54e3585e63ea6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001146898701b384be18a69f8b8a5502872c07d2dbaf8b9875251ab4932ebeac48516896239dd26e697617628dc7f5ce9f0000000000000000000000000000000000c2e534f3ab1c183ce868f3a8f7f838ed8073873453334e81c66a3c88e25c9c152c1ccc557d7381c6d3ca227743217c0000000000000000000000000000000015c9bd39c476def60654722e7d66a1c67e5f709a79d4863a986932df324d3098baa81f7983a45ee3b9b243dbf5c7f012000000000000000000000000000000000391e16c496f3970d3e651bfba2de04c3ab8d2030832a96b4f9d3e6eb929f8391459ad0b731af382e92afc69c791dcd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149c62ca958b77caa3658cd486e350a153216c597a0e2df863f17207ef8023414e87ffedd9365813765f05fd88b0bad7000000000000000000000000000000000502514928161f0a28de23e929e8e5f2113fff4374ea6c6b48982e99a261f46da0d4619d8ed587b714ae84a06b2d4abc000000000000000000000000000000000978b5c010aee3ff492143936547fe42618ad525e95ae9ee8d045435db9b34f8e621cf78e0eb2b05c3ca7896ea8a3ae00000000000000000000000000000000016e2fc63f0066702f5b98441efe6d7177a3396222a35bea29d86296b7520f5fc20d221e2cbe5e4222bf564adaf3a22be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ccd685d94a5d4c35ffe3c9205651bed55c4257673bc4e34f1009bee5648cb2ec5fb468876eb4471c4b207adbb3b7de0000000000000000000000000000000009a47a6052acdbc4ae1ce4580bf65df6e62f3309ab7a5dbe3985c88798fa4cff026d698cda16f2b00a9b97e4d0be85d400000000000000000000000000000000016da47d5358e4faff56da4a4285ebb52c4645af82d90886312258eb5c5bbc65e59f8a4686affd0242688eade58324dc000000000000000000000000000000000a43a1e05a86d25657de4a5030a5dcd0093bcc0bc7f639790eca54583d0ae38508a37809a167e508f808d2eeb5c2cd8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cf3a001164694b023453a40db3985d13eff8efadd0dc1b6271c794361cb7835b481c9a65a01c1c400b43285d76644e00000000000000000000000000000000165f4933d313e30080651497bb851111f7f5026e19024988fd637ddab6b661820d65d94e8bc3e250ae517b3dc05b7251000000000000000000000000000000000c0dfdabee46f9b0e218ca45a1fec30b31f9eaff8ffc155fbb48fad1ce8aa5fe94628245117dcd8e4771a72c6c32e3120000000000000000000000000000000017bc7378f4fb0e5192da4d093d01dd520f2fbbdb8cd8e61ab153f1a69e57debd4b6503e136ea559d406b09069143c98b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f2a0e834d4c1edfd89a97226758e4835c6e4d5e1526463e796ec984740d82e9324875fbec8d3f3d6a7e08cf7a878f20000000000000000000000000000000015ebefda39a7113abc5b53488f00cd6c57b1dd388f1025b4e5661dcd22b62aed4d1fb3780fa4e18aeae548a616f4394f0000000000000000000000000000000016cfaea18431f548304b5f2898de0def2bf63c98731e66901b4f41e32f70a5b6c768673dca87441208daea27d0c227a7000000000000000000000000000000000cee61b31e2c3d9a6a8e2bdd24f9c63ab1316a1da37066b50a6d73245e9087b2e4f65f0da1d17164ec561b67b1b63fd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6c3b69da6de4452ca6d621dbbcf0f54c4684caeec15b382963a00e0a0ca1d34a17d23c02073a0dead7dc8bc0ea67b20000000000000000000000000000000003603466f5b593eb067330695b2bb6ee89ecf48a32e71f70f5e5b6ed9ef99a7af877f762f3171f7843d17ec3813368b700000000000000000000000000000000109d7a34b29f984d742bfeebce03f0b972270be7838ead74cc47e62c4c7ac28c4209c00b81c3a5eb2979f23041fb87d0000000000000000000000000000000000eb9b10f194316243529c3539ee89955635d7673db96c41b7972863c13798b27cff6d0774ec522a55f7e97f49d7eb0851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fe84a3486bf8e818643ff42802dfe934b4eb5930e3158dccd0bb46ae4ecdd31367fca882bfe7e63bcc0105c50e31230000000000000000000000000000000002a29dafe28c8b35ef7bd129195b9e9a1a5a7267729577c290e82f13949ad6a78cfc7065091c81025e3fc3c46c978d3a0000000000000000000000000000000001da15e767337f529479b0f29a4ea3bd8a28f1d0dda7ec2dcdac09bc3292c0e336e778226e2ccf0622f3fa60faa186c800000000000000000000000000000000168f2c2a00e33dc93dbbf746974df7d145ceb3928f58fb4b8f345401d972080e18dab0a8a0ed893910d37545c7761ac11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7d918787cbd36c05ba95bb13b742f3d8694d3accc072a0e7492d8dd13d4375f78c2f1506e86be64bd4814ce041e2390000000000000000000000000000000018842ebba79eaca0b724d072467a4c50827e2e57da5c5b632b82432deb82129789f01f912a192383a7c2513e9df0d9610000000000000000000000000000000015fa7b6924ead3bfe46446bbd55d4e8b8c154ff49742ef3db6e075c813f5900032eae95bc440e3d06f66dbdb65ef61ea0000000000000000000000000000000009691570ec96b20adf3719d0dfa4dfda5b41dba1f94d512f842799a518f39db46b0218cb3bc0a6bc26af3cea83ffe5211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b32fa61a5bb9f7ed055b8e6aad30b278d5404ff56d1b81026c7767f974f9d83face382b7b4f0368b8286e8e1ead8cb700000000000000000000000000000000071a73dd8f89250437b57e28c3e5af365bb363406c4a70a277b57242bc931ce6d2750339d7517f2a7b9b0796976395ea000000000000000000000000000000000d2bfbe18363c73ab189ce5abc02567442ab24f5ac6f8b76a1b5d8242e5d7417679ba1c65a1b1972db6bf8635d49abb10000000000000000000000000000000000c47ff062ddcc7401da07612ccb76bee27b83701b220e7d295b252074e9ae0b340296e8155c585c6e347a0784d3c0831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000237635eb8189d612dbefe663222be08e27d991a092a9e42db7c2dfbaa55370b4e68a7ec50cd7120f3980d991e485d4200000000000000000000000000000000109b548f41cb900f3660b63cede53454261e7b871c6724b23855fe475882991e7a52fea573cdb2859755d70eeb4b4fb800000000000000000000000000000000094ef53e1a5f745f5c3e23c7bf58600f52e0dbf41296874b43307b8244e3cf6fc4044d5659cfdff4f2fea888a65fa5c90000000000000000000000000000000015e3bc1422f4eec1fe741c6e9ba94f1f9d2d096bb27ef99910316d0c73f78441d473a32ff1d4920a58f6bc39c429d96a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005950540b7f5044c42c34690c88c99bd9705b58abd5dd5142e47ebabf28472452021cb7978a17409820843a2eddaeaec0000000000000000000000000000000008e8cf9c6fe1435a5fc320b3969edca84008aa45688a88c54a882e6ee2c63b6dbcb3af5bffd9bc451dfd6ab8e72106a70000000000000000000000000000000006770f7eeca9627507906a3bc548e21ff0858a4588b93cbfd40ea177fe55ae7354bab74c2a6671dd4de29e7fcb15cbbe00000000000000000000000000000000151cfa452a924f6e5d085bf573bd249ffb6de78844cc369ef6736d82017c455abb5237988b301d5d4b6c28ec6b97b44a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001555d33d3067d263ead52793e6b21662c9dbc0d57cfb4e7287a0715d010013bc14d9c66840774e100ffac3199e6492010000000000000000000000000000000009a80bab7066195381b196e6e84c722235e39c77ca3df5f758be7ca87259011f20ac2540c07dd587ee3d807bdd8d484c0000000000000000000000000000000000a64060b8c54824a49467473efddd469583ac5e31a8a0c95a4308fd9d1dbda21b6497b7d772a059cde2ceb5dc1573be0000000000000000000000000000000012fadce1e622e2a355451283cdd33d0774f17cc425cc1dfcd2e85fdfcabecf013c902597b9a387506dd52caf923c08e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b77fbc64ef78568a3de70bc0f5b8282b7b3fe2e0d6d4f06dec00e90e78d757edcf3286a4d47d6613c2080c8eb57c3400000000000000000000000000000000083d9a9ac10b128580a3af7aa704ff2dd42c698d38b4635137c8a7491738539d96724fc8c8cbbbe9c7ed0369f8bfaae40000000000000000000000000000000003eb249017248e1791ad9f887f34b447c2c25886dd3e7c3f2a052404877dbf3eaa3764412f4e5000a2b3d53b6d55a337000000000000000000000000000000000939ffda58c435d64123759c0e512444d05908a2834f2547f5278502032eb84f1d6047d67096c706769edb40f67e0a6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b630173e8d1a00499c6fb7740626e75bf5fdd1e91b875e21163cead3230e8ee9d53b13d53ea116d029767305807431c000000000000000000000000000000001320be7664b46285322d5f767e72a4a9da32463b58d9aca4118a5d738cc40dfd0feca21f6e9f308c8e0c8b61e8b482600000000000000000000000000000000011f5b5ae033d14a8ef8704d07fd409fcc89fd94fb46c50ff8c56d0ce6e35e3ccff78b447f9b7bba1cf075648631d197a000000000000000000000000000000000e2680c618adb8ffc751c5999f68b18eb78efec68573eb212557aca7edc891a2c47c0f96f8cf14149eb1f0c8c67061a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af258f212fa69a9dec8910015fb968440bc3a3681ea593e8ba16be58526177549ea62493430b22f1cf2e87dbb45ebdb000000000000000000000000000000000510bea33d26c2de27ab23b36803bd4840bd7c399d0ee4329193e6b9c192c109ebd9b37539dd1279e7498084e734573b0000000000000000000000000000000010dcf586845d62a20bf0e63bc8fa02846cff6aa2f2bcaf009823b46e907a428f2eb724290a81587af781c60c55abbcb8000000000000000000000000000000000088ff84e0c3b7ef6825f2527985689fd2f2a54961befc05a76ddaf4c7b8c601a6d0b40200145de06b9b50a6004bb5211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000441f28adce4619679e982d3f3e3041a2348131a5a54a93d9ac45d62802a862f5610ea21939a0d6df0d3e0253926436500000000000000000000000000000000160a14cf9f2e30d0655580c3d7e998adef7037d2ebbab02885f721637e797c74a53618c7d6d09233e3a80582e3e4572d000000000000000000000000000000001414b0fc8d37d5ca1a24b5e1e1fba58e154069d0ba8143b0b0e105dbf74a20b1bb9c6c95648646edf7cdd58ae507119b000000000000000000000000000000000f22084af73bbe1320971836eaf0e775467b70c55466a6f5cb2f20d9a35107036ba621d3ecae74fde937a2a810e600b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001466de960bf0b18f045bc56f8d6ee6f5e0e293a589dfd396329847a4ae09582b2597ad5bd514009883988766a97daee1000000000000000000000000000000000a31eab509a1fe1a624e6606e95fb54d3ccb8a317c321e616295ce910b854fb0aa4617dadd42c686efe0138848c91d4f00000000000000000000000000000000008a6eecc250f1d648b6d8f4aa9dc72d5ad0d08d69d85178a1b864d5d84b8e121a6bdec3567b9cfdca6bb93b5661bc440000000000000000000000000000000018bb1ec3de6f8f11bd897b9e015a7c3362c396af45fe52feb005f268acebc4019006250a469f01d62074dfe1457a6b281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001954ed78df89916120fc161ee805397543c67d31258ac58d666f56a6dce6e8b9a6ddcaf95121153cb5525901d85a8a23000000000000000000000000000000000baff6b95e1248e9e1aad9d9519683c1ae9a915dcbe270be5113599979539d5b36cad24782d9043ed605221a537ada18000000000000000000000000000000001642fb8c382e2b8bb8cb113b0fa3479b5ffb9806c0959865002501c39fb69e6574544a03f88b9754933cc97fc9307d280000000000000000000000000000000007e3a95e0f01d44cc452713c22d7e712afa190cc81eebe781944632a3e5eb2c2403c08b91dc2233ab96e2b6f02d30dad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000746613818fb69a7e9b30f2751f8f5d412ffdd5e04dfe14b6fb9547dc40d8a2a5fd90ace85b2c5e5f342e27e6544eda2000000000000000000000000000000001463f79461ab147e2427f886fc360542ae37d53883dace17dbe2493cb57148b3a820d68a9d2d1208268796ce2cd7a3400000000000000000000000000000000014d087ef9d735a798cf78829e5a64b1e5a86dc2f62baf6c8a5e696c196db36a51c602eeabc6a1588ddf5ce1c814e2f7600000000000000000000000000000000149cd177b7b2ca0964653d49e96f6f175c750ca4df30d0560ac6678a5d650083ea14b04b69c2eb7aacc9407fcd2e1c611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dce477f427baf54a2620489cbc45289f1df1e9132767c218fd19661de2cf02af74a35a9e66193d44bd395fb96c5f035000000000000000000000000000000000116a85c3ee84147afb19fd112ebcdeca8a6a5f4dd48d33c7cb431264c2a61c96a36605ebfc284a7158840605051717e0000000000000000000000000000000000e752aa973c7f7c46b763f4ca1b8390ff12f241449cd09a95d81bdd532f3d0cc894d51ee2e41d6e41b161d139e39b6f000000000000000000000000000000000e8db82b8019c534a439dc2f09369e74915bcab3b6ae7e9d49427f59d52102cf2b1db043ed11e9da30aaea67b41d56a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111830b6f009d5e92d2f19f9ee0b51b8d0c82e361046ef0a1ade136dd998ed6e5a0ab1794e22943fcc6a3af4b5074a730000000000000000000000000000000015a06d6ef2aa3780aed246e22365dc2903b4c30ab89c5610e408e64f0deffa66fc39242053c0492538ca023f1d006dbd0000000000000000000000000000000009729686416c78c85e492c922fd9c1b0a7e69009609119abb2dcfdb0877d5f750a84035ad5c04ffa918c6d6b6ff3b2720000000000000000000000000000000006f0502a80a83cc8d787cdc03b0b8891b7d24a693b9903cb08ce4007ce5b6ada13fde360a483da18fe9316d2d6e03faa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012da5a2f312c5c352f3ef7a9fb5015568cfaa56a2a3859d4067802839ec07201c24d9717550854bce3058537ce49742b0000000000000000000000000000000002f270471a3ae6f72647978c850d4f9c3cde09dee309fee2b653d18b5300243c620afe37325fad422ed2d3388294d8740000000000000000000000000000000019e2838c731b3a02bb0faa24dadb5d46ed5edc9a318c5aae8bbff763489db5a35ce78b9c0d6baa0ec8617be6e55bfb6b000000000000000000000000000000000fa8ce31762a18432e8d985e25737b124c8443209d8e0789f3f3238a9e825eda9d162457a017ac3037228a45279e84051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139ae67f3c4cc1bddbd70e180242f25f4637c1b109b671a667ea72f3e647406f8452d653d04890202bf4acb01786f88900000000000000000000000000000000078513b9f725201cea64ae5e2c6473ed35c61ac335429b1715c75c9cfef7171d894771f402254cfe84fc50ca36c386a000000000000000000000000000000000121a8b1efccbeecaaae7a499479298289c17fbdf1e2d89c0cc4837ad39d3839c7c9736822aea5740f6eca15e001cf56c000000000000000000000000000000000076f73c42dfd90d49803cfe2fb2678df7cf609430b2db58af00135c90b1abdc6307ddf4efffe5f5f416c08c0a7464751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000600a1682ecd3af6957c599969468bcc1a000f4cf98182645b6aecf256af4c5987375659a76db132607ffd77e4a5134e000000000000000000000000000000000aaab49b490286c29c818144ed6682fa4604fd952f09d134a4de74aeb126b76df32d02fe6a51b62b1acfa303ddf4f2e800000000000000000000000000000000101c4f705ef8014846fe56c3263882dc81d0fbcae85415c7b6ef0644ccfbed27b917030c75f8551f9a354a7299ec2f1f000000000000000000000000000000001241f7e85497fa33da4a6f0ea679551a03481bd31561cb243686c3c62bdc66c2d93b645a54d2d29244e306af1d6f007d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000226156e38cc42de1c0b9bafabd5896e6809c08724aec4d4bcf1db3d397ee539163096ce97286337c189c0a3d4d764320000000000000000000000000000000016c9fa7dda47cd916d8ee2ffff6414ac3b3820d36e7762e3eba836a1d1837c700d4cd4b18bdd56f237e6d5319c438c6b00000000000000000000000000000000107df5fc706e9cb9eab01616d30d001ab32112d1934afc255792f70bd1f341c2ed7fb1272ca62e9ed0efd54a5c6722b300000000000000000000000000000000190db68f1ea0a07e7d236969fb4405507b0dc53088736cde07b11452bddd26a6b3d4ed634632beac36fe5ca01e9bd16c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016aaf6c50b3a4807a9dd34b70c38283ec5021d8aa9420424a352d1578db742cc612b828e0a2a435ba6323c8dda0ee3260000000000000000000000000000000006df2db36b93c9d9c171388d1b09c41412c2099c259a857b93ce99b5350d51d82ba18c37d6064290c6e81beb7dbd82d200000000000000000000000000000000035f2182ff6edf2b95012f2ee57e1a28f167eaa4697a5d4928f1019fc6b4abc27fbc65515454f833beea1f07a8e3aca300000000000000000000000000000000062ac88083ed4ead633678f6dbea62bb89e386d4594a74586293d40d888f10335c306841e519c50032d4964f01fdf6f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020d2bb77c3b1203e201ce0a2b9b978d3426a1a825a2af0b3e340891e67b3684c8af47b819cfacc90313c595d9d442fc00000000000000000000000000000000022b242ef209d023014e83165f26838bac71e3eaf395d53801de21b1982af93bf250b2d61d9fe570eb0ba328c612242d000000000000000000000000000000000fa61bf491064282b3ece7fc40c3736c0e3e25553aacb0b5cdf277358ea7d251ffc2dfd432ff2bee5cebbf2b6c3bbc530000000000000000000000000000000002d29b91c99b60f6013e00ba867d943d5375c118070e109461ee2d0dc9e0a5f6bab9b9c2fada534955eb1c63face10691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010446443794bcff7795a3377b3af9b9411d6a7f3cb2568fd2db5a8a0ab931d6a1b217fc9838ace79d18e9c743bedef070000000000000000000000000000000004df7f86aaef2ade996ab857c8ff1b50e78b928451663d444fea75d41cce178dfa2067eed81450854215f2c004b2641100000000000000000000000000000000123e9ef5f5b3961e34d8a194da8f264b468ea89ea9beb305f33ac7f6ea0ceee1ca84656b315aabafaead635a8641ad43000000000000000000000000000000001753c10d98cfb625244e20866260080107fb6eb4e1a9d00ff5f610d5604723f5c69dbaf3057a99d72fa32b04232de89a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001292a864dfe5ad73fa4e057daceafa483dcee68289f1090ea86c4a64a242342067c71c9ff5816725bade360beb6d4273000000000000000000000000000000000a776b048b47e4277e12d896d580f04d964c2129d9fbcb17985eb1bb5cd097b3cbbaaeec0e5c835973a235bc507f282f0000000000000000000000000000000008b6367b731f2f4d8cb6a7c35562457f1ea9c9ed48aaaec963c39a4a0026eae1519beb4c83ffa7876577732f0418f264000000000000000000000000000000000e549976a666dd7c85e9503114de6e1a3c8329b8ad1d29e13249c813af438de2db006bef12cb34bc65e24a1e79bc82f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f725f0e0b443774734dfa3e2a2e6070b08f88580c1c1c5faf3b65a2fd6dcf8000908939c060b00cd5b821567194ae800000000000000000000000000000000194a7445389d64aa9d29d9e6cda19b2360442a1ca70c883288ac75fe22f5848737eb15929581544b21ce26aa3d876088000000000000000000000000000000000b6de53d5dda1699fb305578c86612fc71652783deed78ebbfd59a2f419b48598d26a9400673c68cce2991d137ff590b0000000000000000000000000000000012d5abc09dceb589932f15f7f756763f1d5047ccb7d5f86ce41aa13ea2c4b7a9357e6c4244afc1495965fe6d92b4e9f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c871727a46b0b7aec724b0c5a88f84a45795bdb4f22f8f67bff65a44e6c818ecd577288a2bf913c3b61674abbfc33f0000000000000000000000000000000005d5bcad18543933bc4c120f2da68bba81015b2237975b69ef6896a618f745be72d1145ab62908ace3011ed00beedc5c000000000000000000000000000000000f061c113d4d9cba6c4b402710c7fbc23e81b37dc6fc666196919dfdbcda511ae312b3751faf560e60ba606b90470b750000000000000000000000000000000013e96a9d6f9201a20d25bd4fa96eb0f78d6705cbc44fd8ec4e760043e44fb36f36285ba67f94ac4ffa3012080cfa64db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f93cb9617c245969955e2785019c292227038d8f8ab4ce4bd057766420ed88b8c6e08526472275ebe1d4677a912d7d000000000000000000000000000000000e16ac32762f466ac7cc1b0388654610ba1907a1152437de4806c8ea56a827dfb60c9e99a3f5893514bcc1c7d32304ed0000000000000000000000000000000014cb917d35ec93eceef9c5253091c55cc0fb08ec6393a8fdac1bf13aa8f2121ada05871725cbaf9f5b2da3c77b8999b60000000000000000000000000000000009e44894cd7cc95d33d36dba905b780170cdcd416221aec8bc46dfb2e62587a238787b9768c492e8a9e4a6eb4c439fbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007340a6fb5da118c1e7ca4a4ae1d03268acab0c703be69ecf6cedf37673f7726d7a1fc99ae11e9b2366bea7eca8f0f5e000000000000000000000000000000000ddb53eba1eac64a37b6902f67ecdb97020e3c2fae3ebad9c7c77248986a7b41581e9aeb18f7d9344f12d74662eda6e3000000000000000000000000000000000eb65453a34e6a1b29103e588243c89c424faf793764beef2f76adea8e9373d52734dc431bce6c46769a1258e697b7d10000000000000000000000000000000008f07de200c60859be4ab78263e72b6a326c3c92bf5d29660b050b3ab147ac64cfdc4e20559498b0487fb327c94f3ea41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c87312005457656a177d97575b4a4e7f5b7c1ed372bd66820b57193493b880cbfbf580f0af64e68186d93238df195c0000000000000000000000000000000019689872835fd016146686e6f104bd9aa40cc1f8a4f58809ce5ba2e142211bda39e89b0cf6edb76cb4ec498c1ed31d820000000000000000000000000000000000720ca78cf5394e60c28f86c28cd73779e1acd9c91d33d75768cf8b2e4d81c20bf86df5b996fa837ecf222a576d42c8000000000000000000000000000000001818e35c64c9bd6885295cf37e96a73b88f67ad793703491f3dcf5cda8a65db0494bc5b47c491536cc3bbbd3ad30bb4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001243248e664acf6d803966286cb3e13e5651315b509392b89cb511ab5702b8ee92696d9071b64221183804317456ae76000000000000000000000000000000000ea1031d4fdf7860ea01ed3dfff2a8d56c7a588862c22e9895d74ef770743ddd964f681c4a07d95f4a83ff06c4a148b700000000000000000000000000000000034049cf253306bd7d326d40db95adf5b97a5b45e25d27c7fc7478ce4e4d51a4e0080420f5c3b4540d774c259b837d5700000000000000000000000000000000178fa2d33ee61af3aaa5f79f29badabefecf07582dd61eb16e26d9e863e2d222cee9735f0e4cd70a017da649ad342e271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003420a3eaf6d6c088f3abaf983df3caa90bdc2a82170257341595af736dff55e5d071e7e4dd0251d7984ff7199d6dcbc000000000000000000000000000000000db7b8e9a17b49f8af699c1422344bf47d5855ea27e190384384b8e51d2b2151eb7f983bea785e529d1620d076af8c92000000000000000000000000000000000f3d784f5aae94783a5a47ba0ada086ebf722bf27b7eb3fccae56b2b0ce5136815d28463e42620383dad753e39b6b7db000000000000000000000000000000000e1b33e3d2a2720f114d3f3b2c6c73f4d4f222a58f2fdfcb000606d4e047ce636f1ad5f460a2283f6b674b7c2d5747c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b7668222e37387e21cdb6b3e0107846b7aa868f687227b7d9d6be27cb1efe57fdb0b719b5401e0d6d4e1a64442b354000000000000000000000000000000000ab894e8a47e8a15904e1760f59249329cdcb7f0f939720629f060b530e4998094a949a34c2316bf7758bc35622003270000000000000000000000000000000007046b0f7c092b0cda5891d405a64829152ef5ad41d4d5164a20bff5d176b1bcd9ac71b6b96ac7f3910dd4ccb134188e000000000000000000000000000000000698dcd91ee30501a9941993085f860e4e30f9cdfaf27ae42c904a923490ed5b845b14a342cf7fca58c841dd85ad92551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5e0bb49c375ef74222a26899dfadd8e257c2d25d7301a761778e50c629d9cd733470e78178b73ed66e3ac140656b5900000000000000000000000000000000172e59fe16d189e285a09264c39fcbc7d010195019c7ca639ab83982114ac8c54c3c3db4aafe067a791d33a5b3abb849000000000000000000000000000000000cfe5c92cdd431894cd0b9f79fce485e45e377ee549a6bcf4a9b54e776485b52a1e27931a423d1f4e9791d12a21023790000000000000000000000000000000006b728d48057937aba2c06b4a1e11962df778e0189bc89937bc0221b9603c24b50a570a02617fd3c61650aa5ba8a20f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001729ef90984984e54d57d18cdaf1bc20aa9a4649c25b171aa0b8ee6e82dacc4db41680ef522bfc6e1cb7cefaf4ea7e920000000000000000000000000000000015b89fa758178ba4f1bb19b00d25080055bd81e509260ec9abf09dba87537970d1fb96afcb4e8d98a0b3aa5d2b0d309500000000000000000000000000000000185fd81eca3bd34f4fe0f40ebbccef4b13926a5463976d09f219f44735cdccf3fdeafc220e2e6e89851dbec64137545b0000000000000000000000000000000009404a51e47648befc1f6eb8020ef5398b62da2686475082023af6b875622b54b1fc035855dd102e9d11e8b9333fb3891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f7695379d718fa1344007a23e4e2a7eeabb28bf7c968bfa47b3def88c8ba4b1b9c5af136adf18464f6f4ce93b1f51a000000000000000000000000000000000b3c7e3c69de69ca838c461efdf8e24624c8cf6df71ee4cebf7154d0bf91cc9226c0c91eac3ed7a8a55db0287176cbe0000000000000000000000000000000001116fecdb47df938bf45fd6dccf8c047257f2478865dcd484d74693f1f2afa11913b40c23708b77aad16377e00de3d1600000000000000000000000000000000013578c050db7ca7bfa84061f9621d885ec1f0b14af74892eda50523d9392eef2295b0b70df948b3d393310416713ea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f790f46b0b15e30a76d3a47dbb411756712a0261807e425a4beec395bd48dd17111591bbf6adb86df128c6b68d9d81a00000000000000000000000000000000008ba25aab1b09db4e9d6edce642e9f16ee4a6d9d42af02410cbf728efcdcfca769879cb5201b0b4e40eec2a67c0497a000000000000000000000000000000000a0816ff7c73cd383f1c2ff1ba5702c65d057a1fe7a8a9d049b42057f725c1ecee1418d2fe782fe04b89b0d6ca6bd22500000000000000000000000000000000141fd5d1a31a1827b84397adc3265abd00aee9a2059c3af2bf266f04aa166d28b332a957f5714965bc9b9902eab7303a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019457eb033efa116078c797dd924c056471e6073105b9eff7c6777e3e89eeb5a74e56fa7045b7b772ff3f9139bd9b5c0000000000000000000000000000000001474869e10aa64e32f534fa418d0d006e8ec57fa2bc31c06b5164accbaf389e2d1cac6cbfd41f51080de1b68a38d78540000000000000000000000000000000009ec92685445b1039531f29947af1f4a7d1ab30c1ed25d896ecc7aa23d0caac0c9bbcb95a7536522fbc142dd28548e2a00000000000000000000000000000000104fd0947bf8e74de3d5d626c7fd743a4d0b1b3ac5abdc546072d88e7daf31b8eed60287de7b595ee9b4b7c75121eadc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d893d521ead5cfa993f3ecd441d060b674fe4759fb393dc342b1db428964f71b0864f3682ae75cc696a8401a545c2100000000000000000000000000000000020e5d15f393d571d92b204f6d0dcc66c60e870685b058432e2d18d0968ef9df1f60b7b91c428d2fb03915218d50e2540000000000000000000000000000000006946e5db6a06b0a74f8df5ae252c978e98e5aceac355e41031737b4181e4e30ef51b619fb3209ee91ad089965a15d3c00000000000000000000000000000000023ff23f09d104c9407b0df7fc543b469464e9c09daa7632a6bef2ea7371801b00ac90874d5d8534da964b7d700cee5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001246150193c62c8d5bd2e35a0fc7c539b27fa1991f3f7309afff45548a2c862a51b8b917026f51e1ccec594e283cec1d00000000000000000000000000000000105bbcdaf24c0e3011428cfdf5511dc08edfda5e318e4148ed442ad069c68d195de02bce17bd1374d47c2bf89e39634a0000000000000000000000000000000015db5c23fb930f1adc6d76f14dfb54b0fa1e19ccb773aa0215251e4ca3f1b6a84c536ae6188924bda4b42531c4544d6b000000000000000000000000000000000c8d52c67dc1b86cdbaa3486385af0c43888c73a9a395a296ee95e2cc5ccb70cc73d5e9be07bd62fb0819025e173f4d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b9f0c580d7eb3cffed3afb22235c4c099504d272c5b9aca95d87c17121efcaae42333b0b0c107c17efe7ffee2a07500000000000000000000000000000000019286479995820bad141d275e2c73a14bacd4e5713d3c5e3146992a05636e5419c7c76c960428ae6cead53025a87e70f000000000000000000000000000000000d2faa2e1569f7e57eaa730b98af089f950acdeb36982b88d8f8a9b9ce10573457d4e2fe9ef5fef1db21927278bcf5230000000000000000000000000000000002b88eb2d55e8af15b7677e6fae3d16a20090a7f93b5998f8772cb351d7aa32966a11ed7929a872f8af7274603cdeb661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001276ad4fcda2f33e43f83bd4498a1ebece3981e8e0876189a4d911320f9697987207b44ce33df7653ca7a9949f1490fe00000000000000000000000000000000002509ce5b2c21e6d6f7656c6e4ba97c5fc55245494d3db4c2ec1737713817d32996150fb8afa32b3d0860162a5cda800000000000000000000000000000000013aee10bcdb8e316173ccc47c6f43181671d9df84c24474166496a09f65d3f7f9acf5e8e05bf9e4e79b747f25586d9080000000000000000000000000000000012a34c91c708d994fb0c20659c5bed3ee1293c11a138d86b1180ff23fcc5808b5883d6b9023b1be67e8d9309a2481c901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018029631bdd03f299fb60ad1fcc7c8d5384b3191d148ceeb1257ab745ee072ee5feb1822a72881faa64e606ca4d38d0d00000000000000000000000000000000143284c6f978c33a329c5b87f8dee7b76ba0b6040e58903684e973eb0c9e3a5645404feaf6dd97d85e56bd57d02c8c240000000000000000000000000000000007bd1c6081c6c472aa18549ea922ff46dcc6429361fc2ed1f67908584021bb4bb634d771a5647f87ae438255d43e9dfd0000000000000000000000000000000005317959b00fe5fbad4f4fa7c10a565049022e8c1b5e168681536156f1b03b96fc8b44df3fd97d56fbccdcc413766f271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174b8624208828c62f08f23a7ad6a59501b3e98e80e150e5cc2ee8752318d43fb3faf0bad522bc8aba70a04651df1e130000000000000000000000000000000014776d28af31e64d4038ed0319e64180cbf9b5190a62e3a43fe0607b5cb0717f1fa8cee8b4824d8bbe9a531592084a2f0000000000000000000000000000000015e87692d47baed1bb4326be47df36915e69c24deb68ca0357118a25a4d272f0cf58fa8bc73ae35ef6ed48f38e5bb153000000000000000000000000000000001427e8ae9c2f0619e700310f1e72d8f291c8b8c53e8c751b8f0ea3424650216908bd56d4a76d35d94524e2df5000dbdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f10bcc727a623b45d9c7f267d22a8ea999631339dfe53d9c3de32cda38d0d131579821fb08c742c2c0f80737aa6593000000000000000000000000000000000f7463f27129241ed2c32b55ef1c38d05e3f05a127a8ca6efed07cc4206393ad06f4bfcf173222ec66d944bd8f4b8f9b000000000000000000000000000000000f05be82493b1a2a0f1285e1b77850e839535533b88a8c6546c6233a0de2d4425876224fe7667562424129ceb393707400000000000000000000000000000000085a9c309021c17e08c15d9f2bb8098fbfdf5c4b3f3bf8a721adf9aba8eca00ca46950a287132bb4031d557effa4074e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fbd873e62a1242f96e1f5a45cba9457a9cdf3efc80b09a66eb716b245130103ac0b2ddf9751fe501d26c4da179ffbb000000000000000000000000000000000deeb3ab3344392d21ef61529627d7afcd3285db92d09bd5e1df7a3b0667255cca86f6be91f31ff67012c2a6b8e90aeb00000000000000000000000000000000155c6467efb899da51284b1e12aaadc37c20ef270c43f83a3f9a09bfb14a39b62b3444417827cabd7745298ce8097be400000000000000000000000000000000093f491139497f0019e795da164f0102625f49cf7aba1c5903e691418d7e2ad3f353169cb530af25feba698608caa0681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000064a572a868debd34835b63dab5826cb293d13a83e8f931c199a0764d14acb8b10e00be8a4a7869601467fc4d86c2480000000000000000000000000000000018337b37fcaa71d06b60c7dfdd4db785da6655190a97c4f09fadbcfbb45168f29efd6ca91a8d77776f57032ea7a97853000000000000000000000000000000000066edbd82d76c063b0a91f37fe737e9fdf4967d9db18f4abe707df654c9980f77eb090142693f604774b6e800dc1b6900000000000000000000000000000000181bd9170f327740e4da7189bda44da0fede263d9bf70264b95aca21c6c0dcdaf50cfd107a5555fee1a1ffd299fda25b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a9e35e9310d75d81bd47d86ad79b532aeeeea8d26f4dd803e74d7e4ec11baea8c70136e0245f801695b1ceb0c71dd5000000000000000000000000000000000578bed25b80cf68dc823acd017a30fe09f20bb7ee4340d9aebf9980e041df3886ebf85b1138a3496c0b4a4d7e21ddf90000000000000000000000000000000008814a11e702fe9af00c3b46c44fb00dd43104832724ddfdd012e07375d7a3e71a33a17ed609fe2df77a58c60af293850000000000000000000000000000000014a20167981a60d9d037c0975ad63e8f9dfd004f9a9d501ee892a9ee3cb2c80ca9f65f3fa850d777908e53c01d9cd5401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c11920161a56053346e1156cd06ad339f0f54706ad87d4513e797149322f14bcf56b28589ba1e8bf8e0cf5896a769b0000000000000000000000000000000010eb2aee9bfd8c54d48f4f9406c91233f7e7c4c52a0c64c2f1f828955cda0ce22b370667a5b535d569a51e755f5b5e00000000000000000000000000000000000f55424cd3f70a8bcf02e076f7f05a667205a29f5a88be5ee8659a8ee9ce4f0fa68739379dfc34cb70e7e11d8033728d00000000000000000000000000000000071cd00e983952802087d2697ee63aa0ea29972cea5341cab20013586399e7323d110802a291828c90b4b83a338135021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3564953e25d303df3edb5d3b7de4a1f29439e6b72c7cc487edd630b3beef300bfb01b8a2a7c46b2d87e5afde080a14000000000000000000000000000000001545c38231e77bceae49274c7b0f8090cb6ed196d641f79df2f9305ca1588aa2a7de88959560957c3b83cb33db5ebd720000000000000000000000000000000007f569eeea5df71f20809ae8294fa9a4b28541d564027d7b87565871fd78b6cd1cf2bbc04b7109272a57795fbb859dde0000000000000000000000000000000015647a3e0a32dd49deb073963728586ec7b8dc0ad79ba3f732400e3c39b38445e0b5879a9899acccecda11f7afbae8a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fcb5a2589cfb11a0a1ebf034b016a2f673fc965d068e12a2af726bd97fb2086dc37a33fc82524f556c4ad43aa903cf0000000000000000000000000000000009fd7b3f337e0a5d8232211756d55c4e78d0f73db4570319ae4c978792d0cda5c212a7ff1a733d4ef3cbe35f77142984000000000000000000000000000000000b124553ef8d3c83c60065f9146c93accbe59aaf4dea092ba72095a4a5c94c1db01a6a64d13d7e433755e553ac5258580000000000000000000000000000000008b349e371a6ba1268e2cea53c0c83f8fa13cf442f1056687afdd9e09ba2757be841c00f1a3c0fd6ac6572d8599b2fb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006dbfa8a278b219fac8e2a97d8be8508e4cd854d28e66a4383688abe8bc3727ea625af720ce454f31c70e159d301fe420000000000000000000000000000000002c36aed8126986c60b1401008ea598aaf9c5c8c92ef2b2b2cb516c059e91fbf66cb455251b0c09345f35eacf7c6add30000000000000000000000000000000018dc9bec0f78e2ed26960bdd3f0c7cbaa607254d8170312ef510701132e365ea0acbe9d3a922c269e5403e0dd10d06a900000000000000000000000000000000005340836d5d7061b4b4a1585e01884ffbede51118f9e9de9ec21983f870fa3c78c3bd861b8c433e876b1ac08cba94651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157e82195994a1d886043de55f0fe38db6529fea161dc749157f623a21fd377efe72912e8576e7c2d57b994bd52e75830000000000000000000000000000000002c940880e0fa4dc84ce09b3c3bf05f6b3315cbd253f97d66e7c95359b82525e70dc05cd1b490dbcaff16a901d2f13ee000000000000000000000000000000000a6a4083a2b40f734f347920937f58ad0b4958aa2712ed367df1c44131137f17ca1bc264ccc746edcff33320ff32fad80000000000000000000000000000000015920088371d552eed0efc9c0ac20881f9a2d41d5c19b225a29678e3041ff03fa22875bf840d59431f4d005f3532c3d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb7f1ffbde73e1e58c2f0706e489072728302ba3ec71f337f6db0bc9644eafa92251763504f72622c21cf80f5b54ef7000000000000000000000000000000000102f6f9a587c3974942ef5eed138df216d9e6198c3bbc51f7208f9f1da98eaf3231d5433a5141fbb2e0120d285c8c690000000000000000000000000000000014ff98db3780c67df0fa65e4743222f76e53568e17d0e43d0801804d1464d1e1dac4968fc2348a8532e282dc3679534a000000000000000000000000000000000a95ff99bbe17d799b3cd8737b88cd211eafb9f9de15fb4b2436cdc33ce9cef17e679bfbe9c0e1897c36850d81ab96c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090e255d48b8bd61525d457015c4ad33290e44f423ff30a1354609f39bf2905031a65e7028103e877b8da8080bc9aae90000000000000000000000000000000016f7758c642d6d0ce541bff39f8ff0e0c7538f870fe63bb121d154c17c48acf6a307bc7287412f5ebd352faec70c449b000000000000000000000000000000000b2ed3b4721ae409d60f273268f0c356bc1393670b4116eb25d16f5cdda960348b73d232977f2384e16dbf072174319800000000000000000000000000000000085367b487d6972109041177bbe49f17a2e2186463a1edf8e9006c13ad93afda64b6aaa63c0a4c116ab08f1708652d7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001456424c37c92b6777a1e00c487c808ad903f79513dae5cfbf1cdd824d1a2eea62ee8fc2da2c9fb18f7a022f45855e660000000000000000000000000000000000e4ce03ff33f8e05a9c01d472bfb7be6f6cb91fde45fc7fded22c53afd16bdaef7669425e74c1670d652f57ab4d1a0200000000000000000000000000000000059946d0b0e64448a93ebbf67298cc7340e85f95773ba4d425385eeb02834f9b456b648de22de9fb8da58d28ee73722a000000000000000000000000000000000ff09ac5240b3e99dbf8a39399a1868ccf7818af33f09c56a50387896ede2b7de959c63ab28e3a6f36da389938e585631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001275616a06d4315888a1bb987459c0f5419063d31ec1c45393fcd31380fc80d4b5932dc9f33b2b5ff3a04e78347fee0f0000000000000000000000000000000012fb1b304e77ba40d324935969bd8f8e294d8665e6cd73469a2d9cab7889cce98e812878baa1b4bead0e41c141e09ebf000000000000000000000000000000001838016e18d55180da13aef58e5e8b90a4f9a2e2ded1f78905b704a29fafb5c1ba236ee6e2d760bf936cf07448e3a2b8000000000000000000000000000000001542d204d553a6ca455f5e15484e58bafe5258710a7a005ff165b1b475d5a11c82bb9478a89466a65fbfe705c9e619b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021b2234c619bb27f62e480d4fced211584f115d6cc5dafaf6e8910c8e8a79035dba5fea01ce7a45413c99513c9682e60000000000000000000000000000000000d8989378e1657b66baca43d8cd93e54306d51cfde5a6de93ed506b6b9bb1258e8dd407f1ed9a9fe85d62da2b88533e00000000000000000000000000000000092b4133ccee71b20f7fe2b2de6c001ed2aad927298c0a4c6a1b4125a5db823eae137f8aa5cd854f222fdc8d5417f114000000000000000000000000000000000a82a008f166632a685443add00edb2a1f333c491764fab59cac13dda878c2d67f42fcb4c8a0c6b5040650159930a8b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cc69cccd75e170a4976c7294c40f99ee26a5cd92e9d4556377d00c08dee587237daed3fbdf9ae4444a4e55f4f8707700000000000000000000000000000000120b40cc8d0d370ce1f894e8276e223e98be9e604d0d23496895a615bbe6da1c1eaea53e4725f8a241278e4126b9290e0000000000000000000000000000000010e0af8399079f7eb3e3cee68be2b33256329558e19bc2870ebe6454958fb72121e3824897d6ba806a6d47598038dd44000000000000000000000000000000000b4797b811ff46f91202ec949b86ff25fa88de3ceeb3fee8a1e1e6e141ed0f1d95b1d34474d902e9fc3579546a27f7e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003beae7593bc02d5cb0557e56e2b5c973d5a2111b3447f8d03219d9730e8771c7bc4c981117287fea626f2762fece2f60000000000000000000000000000000002b835c09327bfcc970995392dc026f5b34cecaa02a5d9b352ab216c9576f623db15d6d231970da3cd9a1b9c79ccd08a000000000000000000000000000000000ffa66e9703bc4cd31b2255ab05d3f153193634602205d459c81683f4d28bc4594cc462a00379dd490f11c303b0e97a1000000000000000000000000000000000fe651094f4131410ccf9c4dea2c8da727ad9aa16fc1bff55547414a98ba99f532ff92571afd8e7cb4345ae031000bca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac06a0bfc3c89a103d077e18298a15393a9ac7d06dbc054ece5c2582b9322d6048fd6a11cf8dee6b492bc6e7cac010c000000000000000000000000000000000bed51ad1f2a3efaf8f35f9b5445201987861e77d44513a4ba61c741d4f4f262ac308b5089097817c56c3b697496c52f0000000000000000000000000000000014a0d55188fea736487f7bf71dce35a7ec1dc0bf2363de6643775db68cf8401ae656823ee10a888c09233253fc4727d4000000000000000000000000000000000dd97cdbdf8906b2eb44f50ba0d8d684ab56754cf7d856dc23e4dd2f0e791b32e00268c3049f2a574558c452a01ed3c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040eb1732f2f122f799a46188d72a8e7bb0a17c93cddf792c99f0db5ec707b46a5edafe54a9893d9f188350b7abc1d7b0000000000000000000000000000000002e86ea84379337869a671751a5c6a860a27f5a8418e5c401933acc151fb4a6208b8f7cf446ae7bd5d30c29c6868bdbd0000000000000000000000000000000005acde871aeaa00c7e7ca769b6ae095cb47177346e024fd2ac7e62ea0e44567242eb68e3bda423df33c3584fd59ae1f400000000000000000000000000000000137ae35eebeca7b534111feb1865343b468cc75c521b8bf12b841455bdb6711f9608112452623f5856d7ac1342724d201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000efa285efd6a028ea9859c7859e4d8d9b873f6d9638e226a4bbc7b77b5c282287182fb24228af36ea497436acdc71a68000000000000000000000000000000000f78674aafd1fbba816e496a3d2bf543069469fbd8f68e79d1aaad766ebe5150bcaef62a008e1dcdd02637c0905de30b0000000000000000000000000000000017c65210c093405cbfae8b839118c874d7a817fa029d3d7f7bed069db01511780224cfc5bc036a6c73794cb2d364d0fa00000000000000000000000000000000109ddd0f6f42d96abd9d21bccfdc3ae626c95d5dda347da3a0675f68b59cd0bdd7263a571a14ff8658eb60a07800ab721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a468461b04dd30a46758b497b87b3783f0970f258983107bbf76df37e274320e3bbfdb057485d367f7c1085b77d0755000000000000000000000000000000000f0bb22983c5edb6340b34409eab0a119ab730ec3af217c7812fa42f2392228a53d43d266f308d52c1354a9671510c640000000000000000000000000000000014abd8da46e68284d66e65760b531f73266e3036081c456226a8142f0ccd8cf7f2e53924bb596e7e8f9813e0d79f4caa0000000000000000000000000000000010e6ed2a8c023d292998adc162edb02e763f101d4938303fe6460a8cf1e5f3d91288f1ee7745580668a023be8fb0c7841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001771f86eee35691905b3c77b6c49827e260cd5ab39ddb6b16e16cfede00f050a99895b50fbd47c3d5e5ea7408902a5760000000000000000000000000000000010941ab2cb78691c8bca685bf4618dc3b07c68e937f6fc51d693c5bf0c2c49d19d3800332679fe6db6383e75884ac5b8000000000000000000000000000000001216abd3ceb3debb91a4293e67d46a087520f2db4e74929e44b00d5e74dc946f1bc86b8eedafb9c57f8531a18231ab5c0000000000000000000000000000000006d30188b4fbfc168806aab5eaa348f3c6aca17f40932d05b517b26550f7cc53d09021df44ab7f7ed01c1c48ecd5c6e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028ed057e2c1452a4e8d68bbbea39bee340ff617acb45d2a202a6bf49c55a455ee7932b63168512a0276587ce410a1120000000000000000000000000000000000e93f238e5375538208aafb42c7555f5d271d6ad62f0c4132dbad3531a33d40a9f663e5c365b687fef143c9aa2bf9e6000000000000000000000000000000000bae3df4a6652b898059fec2716f8b9a968c007baa9cd93a94573d7c8c38ea92059f489bab29cb694bf53be9bbc49b6600000000000000000000000000000000063bc330c9a01a770ded61be9cc38d5fd614e5f5075f2325cc6a7ea816e5fcb379fae2a7e5b6cb6b99277274730ae1d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f6d816e2086a9c04d415ff83fae52ee2693185596f11b9a625cac512a8cc6a262fe121e0300f707d7f7b2c4ce70258000000000000000000000000000000000559e7ad3de60b5c864f618d5a116a3cf179d4ccc5cce84abf41fc2c7f914b309a3f38cfe4567b99e0b3d766b9b3203f0000000000000000000000000000000000637feb00603156cef80402a44d127e10307ab8705ec283f942bd5525f6bcef890eabb376f644664f7512e0a10e2a9d000000000000000000000000000000000af575d2d87eeae3447630c6972e0a361f7d0584ce67deee0d86d52f1db2870b92bedb2389535bbe93019a21e4dbb82d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7bbe51498b5d3cddd5d15e4b4743e2e87349f1f6d42e757a929fbae25c11fe027ea68756cb073130152edfbbc99c3a00000000000000000000000000000000071e26257841318822a1c5227e5427b780f6dea649cb4670d410403b1a923291094f3bc7cee658f8e467d9fc994e74790000000000000000000000000000000001f5f87abfb00f0d0114310f15359b99141cdcd3e42a69d0f0e59fe70ef191ab54667f1b7a8249e75dae47096f8b7781000000000000000000000000000000000085adb61c88ae489dda0b4936b29118bf9a8c7610d1ab239c75c4c98a69ead8fd0fca2fb51b0a779d4fc83e2a6dac191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019122c98fd1b0004c280177eaa2c6a658ddf81bad31db4c1dc7b36eb62bb066009c4266b6a4365c76243a25623b3617300000000000000000000000000000000133cfe42bd773888dd4e6b7729266d7fc060acad5cda2abd65f31dbcfaeff72b3fcb2132174aad467c77b5377ca890740000000000000000000000000000000013e75ad2ac9d4107a8ceacddfaf6ec3275b1a6c39c3b8baad9f9c6f5d1aef2513dc2fe7e21df44c3d9ad5ed2b128891c0000000000000000000000000000000000adf6a14bd108bfd4908531e6ca0e738a3596c080041a7143d0746cd7fa018443f24c6f265ac7eeb3adbfd5d3ee0c981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fb29e7e495cff757afe9f9cb6d13d3631140de6a75b4c9aba42b9cfba4b2b8a8ae85a19a3113cd6123f5fe855fce5e000000000000000000000000000000000188596b9988acaf27ab8e45a63d8211893e4d88a9c9caaaba6cb37d48778cae5b770c0cb8f574c1b4a9f4930ab467e70000000000000000000000000000000006bbb521062980c2fecda6211e1b40da39b4fd5d7bbdd4a7794e1c9e09bfe0339fca0adaf1113b0b5b06b46842283b800000000000000000000000000000000000273498da932faf53410dbd2bef983e69161d417fc02c527fa75c44e1abfe7ecedcbb6143e9213c4576d694c66e429d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cf42fbe9ef85b47f0b7974945484e911e63596441731da09750a5f3483fbbdcb6e344f3e78615d7ed5484f3e33d5170000000000000000000000000000000004a4f03c4e9288530f148cfba12b8e646a45ac36e06beecfc27ce8b63674dacff9a9a1d4deb0c8624f440c5de28a71cb00000000000000000000000000000000071aa999afe3a0cfe48fde579e7ccb987f6a5577d0f4e63e91a2bd24b41d3831a5835ec0e2ec143da6502b98641b808d0000000000000000000000000000000007d7c553a045e42c6d8491fdaf838fc6ab4d0818faef3e5babe57b38503b9dfa67543e99d5a53c2800cc91e248a130c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d3182d845e0bba57863799f41861c92e11f0a6fe90fa57c210b35d5d520232a1ee098e4b68bcb5e3fb52872c261a78000000000000000000000000000000000a2db4d1ee3ccac7f3178f4a1cc4ce694a43449aa5f1d6a87e14ae3080301574407128ee385e3f8d4f9d922cf9a7a5db000000000000000000000000000000000fe4b2348cb7364c4565f5d7dc4d080aee93b5f9f2144d81aff6925ea5a2f5c66fe77202df692f32c0be9711951ffb0a0000000000000000000000000000000019db314b62e2b68b70b7563bf5ec4a329d352486c64d28218b5f9886963a9c523a0ce3b4baa2e88b8bfe29d9a656684c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3f70ac266626f2af4fc93e3db2b657d5b627f5d344320dfbfbe3f28a05176c5feb937a7e64fc447f799941b43cf3da000000000000000000000000000000001537583addd88d1c876b00a4f5f707cc272fb3d2bde72b244b061c1a4d689351af7d078606fc752680ac667424412ac9000000000000000000000000000000000a95097e5ae9cecd211349e1b478450756524a1a5e9e02681fbed713c6a2505cb789dbeadda38d692468200dd4039d6a0000000000000000000000000000000014c63db461ed28f80794648f302138dd5ca3db7e6d24e83f0e14b27a077afe9e5ddc6effc694091605f7aa128db93a3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c2cab9fde3bdaf9948cd8c9b374cfb627dffefdcfd52fd1df219eada149e7dd9ae2a287a095a519aac1b88fe1ac02a000000000000000000000000000000000a875a456f6c5a2985fc904e56cfdec30f7819fc0a65c863c033d8985aa41b2b74ebac6db2b7c0a59bcbf6f6be1c63820000000000000000000000000000000002dbf1ab764de8aeaa66bdf87b14c1339139346912b735065c8feb810565a9e5894cc5b546aed233671bbe81023d087600000000000000000000000000000000039d228aae06367d612418e3c092d1fdc261956902b6045d3eda215b8acecc96bdb20a5982e672fdc56291fa892601041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d9df9a45916d0e7eb0ad9d05e70c794259a686b84d4a9c0707e63d84a2a0cc6b4a69dbe8c63db70a3f844d88fb77f70000000000000000000000000000000000f4bf88fbdb4273783dc53295dba5eac21546c4d582ea563d888fab98965d06ddefb3e1c0163ec33112c17d50a305890000000000000000000000000000000016b14a3cbb66c7ef1c9278972566e5325169bc0171ab4991de7bcdaca63a6416cb0bb7c8b19a764b7ba3f7859439a9c4000000000000000000000000000000000a7bf2c21afa974fd6ed1378a9e4e9a56f1d97f6f24c0550beececa432e7565641cc7af4286c5d3c118d2700e48ccc141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002663656334d2e29608aa58aa80efce637af86551f55ce3408c6ca1477aa77f64bcfd1b6234916c2a0c2d38d95562fed0000000000000000000000000000000010598728d572aefe58558945aef6ff7948ed424ad2037cff6796bbfaa2d49078d61ed03dd4795b4b6a074fdd6ef7961d00000000000000000000000000000000060f14cc937b8a5acb514c181e64355aad6d70a314b4dfee6b10d327499e31bc331411fbb8a1e11d22ae5bc7b45c56db0000000000000000000000000000000014e148b8d179b63ec8dd1d382ffeb59a699211429f1735ecba9f1d18780f284e0e079e6afe0d1f449031ed3f3ca57f271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bcf6a46489f8b0287f31011ec48a12ed66bcdea7be8850f2138a8a4909fc3dcb2bf1598a7be40dc956ec1c6d30726a000000000000000000000000000000000af6f48196e6fb42209ee24bec47389c224c1dc1c87650549470397aa65a20224ebeabd1420171ab4008722b1dfe1c440000000000000000000000000000000016a95b38cec3244d6bf2d86a3fc2d19e5b6d26656625829d2407c6863a26d3a887f10d768384ee44356343cdd6433a2800000000000000000000000000000000038782043207ab8d39639aa267735da9400649acf4fc3cab4a507da1af5e1fe09b76f39a6b133139d6fae346551f61331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001927daac24920e2a9208b9fc7a87533e27681c12c1155d7ace0d78114d522cf8b3e59d991e1f721ad9eadfb13069a43e000000000000000000000000000000000a1965f8c800c6e32e4bedf295c0ac9f914f7e17eb30d3eb908bffdebade6975673617425104db8ae6037d39db54d9a90000000000000000000000000000000001353bb21e4e3518b08349ab35d1dd22c8695c19f442745be6cff44c04cd94059513954012caface5539cc20876d11120000000000000000000000000000000001537d259a51476dfbc80ac0bf0235b21f3fb3ea62a1b737f5ffe8b3c77c22ea06158213dfc309595da0627c6d5720aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fa9bf9b7e624d6b2cfe450bc2a1253e549ce40ce3f8ac7aef6a1a3a3d840d7f0e4a2ed34eafbd25c96b4cafd4f5c040000000000000000000000000000000000a45b09f2be6df22f20a454035a0ddb6b2a9302897b9c7761d0549a0917fa57cd298b60af8f55c0c5cf7e20ff4451f5000000000000000000000000000000001929e10d060820af285d4b799f959617907a649f326cf9d37d3e78a3c3c29fa718912ca9704aba511eacd6f2bf3dc2690000000000000000000000000000000008e017cdb8f4a4ce90464999d9f7b965a1d81cfc6e99258392bf3c6ab351cd9c44ca5aed99b120ad4a12ca4f39e6ed7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb53b30757e8c7eb901bd27444ef6231431c8d14087574b000cfaeaee9cf711454cda3964bd96b2e7daf04b4b151d800000000000000000000000000000000004f3fb8e3497361d5b4eaa113df7be3820bd75bcda08659612c9223998070d8ce740d040f0e955d172c88b64f424f9500000000000000000000000000000000018eddd36730558f29080e826f081770ac9673085e3458fe2be02d0c0276a9d930c9f005900f2e9c007e56d326fdcd68500000000000000000000000000000000145f47fca33f1e6accd255be7a2b7ecbaed811e6fe68870de808a37ac1f3723bf79387edac8f6cbdc1db29513e8b2bdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ea1e9af08df6b37bf2bb257652b7c5de1512d5cfeb8706776d4810e9267c22b8f30ea53bb8b6ffbbf1f57e1d74f45c000000000000000000000000000000001074b6a8f13c29c7d4db7e304756f1f028adbc7cac61d96de2fe24f14207ad581a8abbb3428dd2406b8f12c21f10022400000000000000000000000000000000012e0f514a3d56f07ec8bbbf9a97d1978020fbea1bc4585334460b38dd9f29ab995ee1c24e17721c3a483778eaf070c400000000000000000000000000000000183430201f6154bc626b5bc3153768d3505a76706059d530c0e6468d7d09ceead3a61b8e69f6a625f6f2c2ed2cb7592c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e208f7b22018fea3d6353653edd6e274e51e820419a9d504a98d0ba386140e9c597921725fb2ca52bdc5f18a63d74bc00000000000000000000000000000000043bf3bfba7b951932dea932d79776a8ca3df9a00d7456976c76fa6ce613e404e9df958d784a7e3472c1b59624744c8b0000000000000000000000000000000017b574cc6d5dc483528c7e5d5b60f47d3c7447f5ff1b79b98c9a53b02c60213d890f2ef109899a28a37ad8180dab1b5200000000000000000000000000000000091659c6bf098733e8b451ad25d80326db8bf7f25a0e3faeaa88b7c749ec89e3c700378abd761dcab9396f1e7e71cabe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec7c584293e71c57cb09f23190e05219d847bfd95867832d4c8ea616ccee129227fe1e1dddcf5fdc753dac736836bc50000000000000000000000000000000007d75110d8d6f1f8170cc4204191183a9760eb532c92b34cb17226632585ff8732d2be3302dff775edc5914fc9d8607100000000000000000000000000000000167ed8a5ba23e0cefa09830d2ee533923da9d773ff724e4c6cb22aaed6f76dddac3d1c5da8ac562e66363277665d9f2e00000000000000000000000000000000128933190d15c3d33e3069b790d3efb3bd53d0ace163b82cfb1d33789273af6eda14165d58d8b108240bfcb0449dc3fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001213e44cef05953f75df29b8c9a02617d8a662f6f5153b0838506c295a2e234491997acfa7c7f9cc5ec5e5275a7988490000000000000000000000000000000001ceef3a5dae59f2c5c575417418e4c23e94fd830b3acdc7feeab64cf2514a3e4acd610630ec2c9cbb42b67103a8a2f40000000000000000000000000000000012ba442af36566ded0a4f8df5b9da71769c4aae408c064c427f956469813d1199182dea2b2d52c95373f706784d00749000000000000000000000000000000001991105e87558ec8de90e70451e9b11e675a29efb3ca9839df5ea7db9ffc5a648f3f2959003423bf4c5beb00a045c1ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b3aab5ba6a9ebba028735229e95da5296605c9bddb262050edc50a9924d5d3f41778e50c4e2508c62e9ceba6664dc3000000000000000000000000000000000c5c6c298824358d46f27bab06e1743a5a2ad84e2cf7635f71987fce5c54e8e11d826dc5a04d8a429303d84c0974635a000000000000000000000000000000001603436735afc3bd443dce435c436f1c5e6af47ee49142b668f419552acad8ebf85ea07b32d4c9658e65aa4814b3d9b90000000000000000000000000000000014c5493d1b23df125028e41f6d3bd9fbf633ec81592d9d1d3c77f5dd798bf5f47d701953deaabb46beedb6e3dbdd645e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000207e7bb5ec1e7dadfd583fa6bd777dd7e640caea587572fae42c3ebe5dfa0e0b878d757e70d62c1ef3d41f202c3c2ee000000000000000000000000000000001344915329ac8134f3aed7804be9bf47d77626c6f3a046e92cc38f994b945d18cbbf41697dbeb5aceb7659ea3ed7ff5100000000000000000000000000000000185d4dd392e3a1b1b389683541c55843189832d2179279f4adc09a02575528491e485ce0c67d25db894f83af1b32da96000000000000000000000000000000001740929ad15676b7cd72a41ca786c65160bfd5d51aa9e41c08cd6a8fbce0babd6d7041923e5fba1aff1f421391cef04c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146ca59a1b0df35244c8c2b89eaee64977895bc41cfc888f03a6bc350c902924ee5a2ebbe98af0d7244294b66394ee6b00000000000000000000000000000000104f9cea6279617e236f25c3cd024fd9cb772cfed74b6a6aa3fae0560955b1e786bcf82d028bf158899386e1561f57200000000000000000000000000000000016e342276a72fa4d2c92bbddfc5cd9157d173b85cd998b65921949a1cea224312a6eb797d266943fc53812fc1beeff9f0000000000000000000000000000000007ebb7ffc650291a0c5a5693dffdee5bc847e18d12d9979abbba0625739953520111923c711dd62cf5c011d2f43f84a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018691be4655e3904a63d777dd7c77fd31af6f060ef68f72f3c7d151f5bf146ca08b8f0db6979808c0faaaade3bc4215f000000000000000000000000000000000ebdded275e66d5bd8c1dd81c228b1141ab26c2bf4d9a79ac3d952b98528c8a7332eb13f63f858b3a036e5f5439541a7000000000000000000000000000000000389ee6840d1e6d749ecf5d95bd3fde2ced323260d6a80577f53ade8231e2862a34c8010721f9f2c3d7d929c2ccf34670000000000000000000000000000000010173a5bd55bc401a0a1e3d3771c71cf0fc0ce2d0ccfcfd4a07e8ee28ea0672e0e215980e02525eb6cd19279ad5ea54c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b85eca3b187274008a101ee3566f7ff2cb5d3d0d1570641556fa0b41975e98446ca3a8a7e645d6066340cf6ce4d046000000000000000000000000000000000994935e97b2fdec7cdb02c624da3b3967363e248cfb1bcce3c78d66be3a6a5500afcb6902d4ecb53985e736b62a2dab00000000000000000000000000000000007474204dca97c20b33217cdb8e722d8edcc141aeb4b51f483dd38e4a87b4fc18a5468b536f043476045f82c50e291a00000000000000000000000000000000165b02c0640369897acac7c01555c0b53231b12cb804201ab1ead31035514050b8e72f23a23db3b13c817451da08e6c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003836ca3dcdca55164df53c624232f85711579bc9191a6ccc9637ab8fbedc0fbf7e4efdf71a99ea6ba84a6f0d7e9e0290000000000000000000000000000000013d5c830e29de1bf70a78a115ced284ea30e63c4b45e8f7c2e22ae39b8530db5d9b79b6456cf5664b55449c05f82cb850000000000000000000000000000000009dde75b93f423c9e2dd9094194346cd5af81b69c94381ebdb53a69c92ea5cca9910e7d5216b27de6c33028e536412d80000000000000000000000000000000003600e9cddd22fbbf592f0f8af8345558871736c7eb55240e1a9e5c9946911ada4174746e9fe933d5084bfbe285eb5741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003157427b57a3d8939225e4d9bde6f0b588fc5e617ce70cf44e70dabc8aa48572ceed5898dcf4b755ef5bc7ca1ac19eb0000000000000000000000000000000000f641ffe91f3b74fee1b3a6a78cc5dd513f9bf3418baebc2d22f6e50b8b9038eb320a167bb0c39de6e03433ab3338020000000000000000000000000000000010f3cf0b2b024a575e007f9386b3bac5b0cb67ecb7dcf46cd792b7651d62c989d6c8a8f337663874e1927948a09bf8f60000000000000000000000000000000014e07a0fcfb7ede380c31c662ac9c8b0b0cdc8327b974ba2fb82b09a38b553dc0128f042b41678b07b8ee1378c0e31161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001169f293b66d53a751e5076e1db96d0787d04af6ca872ae7cea0ecc002a9890a85b01f06a609d46d474b3413a17e4099000000000000000000000000000000000962a5b0e45a93e6e97ec3258bff8724b6bcc024746bddc4eca6963602203f9e8fe5ecf577e292fe67910bc9b21519eb000000000000000000000000000000000ce1ea1a7d995302136a9a3f60f64342ea69c7976ddde65ae603b9bdcc69e4f1df317aa863d14f435824b2da239ec0dc000000000000000000000000000000000bff09658b8512bbcfc77047220a63d9035357f907f7d73e0d27bb70f6ee423e086bbf8d44f16a1e198284065b8353c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012ab9938aec52913a167ab4a6aa660178a73aebf72f526a948a31102b425f7bb41212e8d4a87763ac8454a30fbeaf9b00000000000000000000000000000000012407d23128590e274bb206c929dc457c5cf99d26aa8fb5424fe17b7fa23a199ad98346ce7de1148efb4506bb266f860000000000000000000000000000000003477491b9b4512dc642cbc1d1a6b1ad3bad3156e387fa844ba9df9766d3a062ac38100f8099094474c4cd3b2e31af3a0000000000000000000000000000000014c1f3966da30cb1597277af41653ffa0283e8c9709ee5319780ad5e98f4627fd01712945102fc460bcc3759f76ae2b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce255d82ce850d116392702319478f701caff434ed6018504937815b0deb6884ca99a7845ef61ad9ec40f193f31fc72000000000000000000000000000000000c2f2bb0cbda8d1100f39e79f0f38fada2378bd5578285d5c35fe919f1c7cb114870d19d33695b25418bfae21a09e97100000000000000000000000000000000067e677ef5b8240074a5d356317afeb05ea0cf5d254264238455d9b98668fb7d5961e778df5e8be00b62ed352c6c9e7a000000000000000000000000000000000953f22e389c0a87d7d655508482d42a9c293bf3f3fe40bd0cdfbb21c0a34754e0f0c6bb66f9c5da6ed54483646adbb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1640339125bcb4eb91cde756347876cd74600d3ce825194f0b15b8d788e37304b0ab0c50efcea45f695225016f6237000000000000000000000000000000001642a08c000d113f45220777b5cb12501027e8a741d30725a7e61eaf1987d47c30c6bec3aecd094b1ca1e7841316e56f00000000000000000000000000000000102dbe78566e47b4c35f67d2ad04bcdf5622992f08092b27efe17ae5bd885503a205ad5ea3dadfd1cc3f1f2b4b17bf5a000000000000000000000000000000001533a6f9d99c4bec0fdc154dae9e3f5822421ca7dc3676995193ce5f9f89e72d1d27a86e3b9029b348a24d8f340ab9551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d7ee6960afcf9d04ff786e666cd869d766d609ed2ff1bd95281e9d731a00d535891cf69786e01e262382f929cd26de00000000000000000000000000000000164599e6263f8908b97becfe105f5864a51704feb01f36f51714c9a834f56042710ef62b0ac7660b3908af410e099f1a000000000000000000000000000000000ee2705c8c7515dc659bafaa07b54c022680769752c2108f4d8ff37888909abd77ecd86cf91329df0a6da4318ab191dd000000000000000000000000000000000e754081405b5e60111a14cb97a7f9831d48984f9740ee482c08d309ef4f00764e9a108d329e0f26f300c306e4514c181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb897ccd128d4ce233afbdcbeda15762cf6fb69ffa509f023d7b8b31865eaef79c38a80a4241168041442a69f9b402000000000000000000000000000000000172694f4a075a69f96eed7c2ad8e7cc133932b725be829d13fef1806b4efaaf2cd34dd201b952d575deddc043d19f84a000000000000000000000000000000000c339d111818e87df3c3bd7dfe935b7d65a77cad6862dc8766437219e45fac306584f8b4a5feca46c54cce17aeff88ec0000000000000000000000000000000019d71963edb7aeff6e7f0b071763cd27ed31399997f865d6e0bfc40e8e7c22491c97cfb428673f0da241aef4f0393b6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000906c00418c225184ff9e2c19d49d74a2246bbba3699badb4c65f8d08bec65a27d4ba1d64240143a1a8fbf260f0fa05f0000000000000000000000000000000011d66f22ce3acd52e43293ae777b03fbd8d557cef0107ad7b3d571fd77f22d887b4d5c36ab09b0ba2e4c3931427fe5a10000000000000000000000000000000000e2df417a8fc4da840da572a314a46e5b45040d32df1542d466a362eb381ad8929d4eaab2fac95bd73b6c7dbe937a380000000000000000000000000000000003d0232a689dbbdfb3b244c886ffa25fac07e993dbe4058b90fbe5aab220b5c80f3d4e52beb1d28d93f8f06c1110a2301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000365b01425aeda60b4862c75a7d75134543b4e05802c54dfe879381fc6d3363809ab1694e108f27cc658a14136880f570000000000000000000000000000000003c26a9350007404cde07a933176b6e2f6d8bbd81dcadbbe78fc3e1755b61c653258ca27e44fa5328d94893f0205ff670000000000000000000000000000000001b9d0629df9e893eafbc7dcd6626ecce949ba7a660bf2fda2b631f260ab983daa5efbdfd752e80b79578366f88a6a090000000000000000000000000000000012bf88495d371754d40f11e43d0911cfc5c09c6b7cd35b3a33b77777589b32873ad9aba3db8a65272cf753e87e40d72e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001044694288f61226320d910326427620d00c74bde63bfd48440099c5169667a139365b0d21f1944b9840f2b7379a4439000000000000000000000000000000000af35f28dd4db796209b67bbfb437ad0247703c1c16a4e0e61c14b167790137d4617ae0c0fda7593964acbf327305e790000000000000000000000000000000004a276b412f247821e6c78520edc15850aef049ff50cbfa47580c401b83130cea24f54e9d666aad3a3539e48aef7b3da000000000000000000000000000000000a5244c83e3dfb164fb5bf75009c4e024891944e2fb43110d7a4d1c00d808bfb9a751d1a4418b68456d02a43652cd4591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5cb14edfb45378af4d377c102a75fb31b66f98663f16f0b5825660f4da60aad2559c4532d0914634183d8ea711913c00000000000000000000000000000000005655dc62c085ce8ef4f1a26cc6c2e675b0556d3e16c067de805c8166cc291c95773dfe2abba7864c9883b6ac36e2160000000000000000000000000000000005c64df7724557b6d4c78e6895944b55e769aec01c45611b1013f0653a739a72ebfc550a843cf388bcb388f09b4f77bc000000000000000000000000000000000bed9bda1aab999f3886fbc83184e0c7b4d393aad27e97a6b4f746871c21e4f18b5afe3aeb7a59e1d227744570091c2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cde4067f09dd264460c862ca6951ccb6d6426471d4eaff297a4073c238a6faf02af758b8fd508d13cb96fd9709a937b0000000000000000000000000000000011f5e85a3d81fe7cf5780994bc5077d3359531a5d59390107bf02ec82ed5a599e200da6a28b0753f3dc47df3632185bb00000000000000000000000000000000009e5b8e5349754616b6cb34b31d3e1942f799beb137892c437b0c7f8be09daaa7448c26bb10ed432d3bce9c1878f90c00000000000000000000000000000000032c24fd4f6c4061335ecc468350f236f03dfa5cfffa3490065efdbca3669c98a3b92b938fa8749e474e01a8f030e4ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6b1d8a29050568fea5da7988174c2c62a055d99077fb3f891ae7a983241f7e9200d88672e329aca40782debd2f653a0000000000000000000000000000000005b565ca99fb98f322ff0e38dfc0854615b83065488ace0556059c02e278daf4d525ac16d5e03e6b9ebb6a46321099380000000000000000000000000000000019573fe4511d38edb85c53b0d13ba927ffb79f36239e1de9f6e2cfe162945c7802e800156b4538e353ff7d12256fe2fc000000000000000000000000000000001833895cdcbeece53b87813791c372aea281636f9513e95be98eadad003227e6ea28deb41dc7682ab751942cd961a9a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d226368c872b1efd2098b31b7a8b59ba0c7f28fa9759b0acc41fd1a5817714a240c444b2d28865dc98a93bc756ec07000000000000000000000000000000000e7c50673720b873d856e62e4bac71bfce8ca7da762e9698ebebc80f7d54d4f23d7eef148de34ceaecf61b187de7a26b0000000000000000000000000000000018da00c32b1549c028f308e48c26ab47f2cd4a83dac7cd0d2d929f97c721a9708af5bcc6051a357b484d881ecafccc130000000000000000000000000000000004cf897aaec32280235bfc64bca69f7d31849185227d28a2e3cd6e7672223489373edf082589ebdfd2bc2e5ee0c858ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a9e0696f9ded3be996d5d39add737fc4f07479dbf26444f5b0d74e1a1f1c0a3c249760c46de5a726b93e8a11181f7b0000000000000000000000000000000014df3a0ddf2486f36bb64ffc1db1565cf9d4fb91c74ff3b71be6b017e66620aa2a8a797225da1f8bb7e4c171bec6a69b000000000000000000000000000000001884f21c35e06834dc8607fda3ea84bc2862a22159e608b3e8510c8476efdfe9bde53f210a70327cb151abba9c3ee358000000000000000000000000000000000a3ba7235418478b2ef35b6360707538f1488d2baac6a66b53d52c70b46f1a8d071dd2c2718c520f9ddc73ce6ea3adca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f4b4e720a9b8afef57b1874a856b38505040c00de74effca5dce7684bf74a8f5ed32a6f20d7adb7f7dc7ea9ebf71cf000000000000000000000000000000001153633c94b822c13c2195d1c4378acaaf65dcbf0c92254b50ba59097ed05ec41ea3338f7d227c62ad9166e35e86302b000000000000000000000000000000000290837b545e5a05e9bcad16092c161c4b922936a2ddd4efda5b2120d8b382921f05ddc8034d997d4b1234f1da292ef600000000000000000000000000000000173d27b8a441272c97369713ef00e1e753584952c25be71e6cfda910b9377ac7cc647448e8291de2911b5f057d0f72d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a5533408466ec1dee4d6531266b7012c54ff39cb9d8a35e3d3e8c7ece654c6b29d1074654a21169e5a67d6050fee1800000000000000000000000000000000064b8de7b7ea2e5615c2f8971669bd3fa0283734633c6630c4595f614276a9123b6f1b00f8bc45628b5b7a759f62d7f700000000000000000000000000000000090bb1a3782e13e472ab4ef61fc5ffdfe6a20f404fbc615338660e6fb8242281c6982cdb0852395528d32581eedcfb10000000000000000000000000000000000f12c50168db7ec8a822e5908af746798b99c4ff9a5cadb3b849d8a367ff3b2620fd0c681d0bcc907edd0a88f104b5ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f21e6476d659f438868194917daf491ef2b09cb619fb88db44f65bed390c83a9131583572106e90850ea020a447e1f000000000000000000000000000000000c7f0b60f4f0410a40e7daf8ac7f0073a7a7a7412fa1dba907d55aa4fc1f44ef771667fff572dd49532d0905df2105de00000000000000000000000000000000016e23357b61ea66fab4866036fbd3ae07f7a3fc943ca6d294f93e9bb81e4cfc004dae04ec6126984fad59d7529ebf49000000000000000000000000000000000e817957fb0fadfdd00add4117f7a1f2702c4419cc63d41072ffa8bf44663a766019f9e5bf5b5f12e09a5de8114867631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002816815337a850c6a70425d12ec3390fe91941d1adfe5f9542a521e7beff090ec7bad56fed028e7016021432ccd1c80000000000000000000000000000000012cf06186331264b8451bcb870714ecdc10bd339bc6c3f6e2f48e6a09c59f505bd2c1f6b8997043fb0bb3dd3a4902d49000000000000000000000000000000000c70e2a07de67066be51c29397a0f496ae20a583d9c09f0d7090572cf6dbc565efa9b9cc0eee942c54ba0b9e02d5811e0000000000000000000000000000000017ffc76c6b38bb859b7fa6f84128e5625b00b4e39a87452edfdac73d0364cfbe5d8e58665d0f05686ae5eeb72f07f7d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b97a5cfdd2774b97fa71e22844dbd689d5c5dcc15afd85723b8f79d8a7fb3ad67d3ef0900afdd6cc54b3874e179632c000000000000000000000000000000000019b76d73e3ed60c2f718fe083f9e0a06f5d7d2484bda1008e143d350f8a913efca3a49fd62fb1862c71fb8335cb3cf0000000000000000000000000000000015590957f25caf26147396846514fb3948a168a72868d7bb93541a0863eec33d18635dfc630a459cde30f2786aa446c40000000000000000000000000000000008a19ed73912b02649e42778622d00f95b422c83dbc94b047bc9a9ea6e9a06b892c69fcf0848b7c585ecdaa36bc923841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104d483b82b2211d2924d8e59e54f0f33050d1380a2094d6be75f1f0bff4aa30998c9344b55c573ee7fdaf2d56e7106b000000000000000000000000000000000c743bdf0a67d1414b976ed9109892cc29509e92e87f285b204291c28ce384dc739d773b00a8b61d31e33f31eeca5d4e0000000000000000000000000000000001e3cbb7251dcd9e9eb0fb812f628f03f4cc4626d1b5c1e078fd02677a6509e60226cdabfd57025467706db6d62467140000000000000000000000000000000002d271102c8d3a60d71e1464e5f1edf93fd08a103727c2a358447383cbdc8beaa38c85ef3d0f8474a6edc852d8b754261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a56584f6bbcdbb4c0fd7d04f731d7198392273db59427e4f4002ef453205b56b909785a20407173910fa2a49fd7c0200000000000000000000000000000000173f5f4c45358f3fee629b9c0dc12418b2652603026f91030558fff1c1635ee8214c831032acd249d7b5b9f92d1f26a3000000000000000000000000000000000bffa7fb4ab1ebda1701e000c9507a3519000f432d2ce3a731f9acc3670f61af22e5bc1cce07be824564de6e5ffcda4b0000000000000000000000000000000012fc9a52b0fc78c505abb56db1a74ceda46bc8f4ac20a80ac90b93ea94a593233559d4489eb156360869258d1238224b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fde13120f9c0a7bc3f5b1aa1b291036830d770685f9f7798ec8228fec661e96a6db77b5a2638255f8954c18bf0d9a8000000000000000000000000000000000aad0fb28039b54c5799ee3c49b8425e3531d2f27fafbc1a66b7b85452d93113f95f983e3ac124e45c2978b12eb7f63b0000000000000000000000000000000014c89c9ecc4b713c409028fbdbb0fd393bd4fd4363a1b43ec43f2c658fb732cbf673d0377a7adb85f47970640855b787000000000000000000000000000000000270f8452abdc0cb63e5140b0d8570454694ce3c14bff3a0594952ae812bc17e850edf53a714a0ca39351f80f2be8e8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000204b73d4e7b585dcf5df25e8faf02d61f92c8547f9ed0fdd71785a4ceeac79c618e76298f0fe579daa7083f45041e4600000000000000000000000000000000195fdbcd815abca1171946fe4cae5feaf7aa205d129ad8c28f0c2c349b03e497397a726910e56f0f2540397bc4a345cd0000000000000000000000000000000015f95e50aeb525fb4926b81f391a3f05fd3e462a93da3eb8ae927c15466745e64c10d1fe5ac68064478697c026a6c4c6000000000000000000000000000000001032f80ff598999f7e2afb61d77d9fadbce053efbfc254e2ffc2ebbf8279aedb668a2007a8abc3a312872ef0f612392d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d609b1880e6c72c81921c49f7935b56640d8cf0701ff823ae996ddfcee0dfacc31edbf56175bd4e2081164bfe43662e000000000000000000000000000000000105553df601273442739d5f10800990c4ff2d7ad14417337a4ad3bc455a2b3fe3b6d3a6b95f0afa3044091dab88db8c00000000000000000000000000000000048cd7dbd9f125d6664ebbb1a0e0dbe141822a5af05187bb0245361606767206d514883084700554514c64eaa51d1e2000000000000000000000000000000000000e912efc427fe8fa469951ca4b5e4d5c9f9743ee28cae53454f0cfba5fcd3e922c748d5a0aa32eca8a96e6c50ae4b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ef1b20c17ea580119863acac8c8d639c5d60491a5bf7edee55676b64c172cd23ce3e4b0087d0c5d460ca13fc3ab200000000000000000000000000000000000958bf34c0106b9ca8b4f98a172515196a94deef9ab569923bef89de4abd35dba845bf7694c4bca6bc3a81248dc010d60000000000000000000000000000000001e0eabebfca330bb5c6a59304dd0d3b003dc7dab5b0104ee09c17a8d79f6f2a9836049fad26c0485d947177ef5eed44000000000000000000000000000000000d9e2193c921f83fc1931a33cabad22700bb716fad5021b0c902f0c71f84645fa0aa2d50cbd1919e765fe3d1bbaf532d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001387a26e4148f81484d3ca7a1be18d0bcf02a8f9d62e277d1f1b8a30b53bc17c10205bb05de743b5a67394ab4d47fa400000000000000000000000000000000008c388d3d3f7673d0356fd2cb043d1494f75959fc39aae1126c3a1c6472425298f3fce0da5d00c7974f6a9da4f94c025000000000000000000000000000000000ea3014f8811f30e51477d3f3c92e1b500657cb5a17a87b1dd103ebb9ccf8042d378e8f4e5acc53b9d9a3fe9c045d6ae0000000000000000000000000000000016e379123eeea3a088001a9e4d196104d2904a6c66939465ace7d815314ffdc35f18d57ebc32d008d6e15f41ab55b6791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000462219e466e1a11e80e9ed687cbd07aa1044eb6b821fb450860daa6ddc27c78254e1d58fa115fe0745157e07174521f00000000000000000000000000000000144e1e18501711daa4cf3abd6221822ff9c42028d2c4f2af34fbb78b99498aa487cb32e5786f0bc2f833203e5f9bbf36000000000000000000000000000000001759941ba0cc06439693e42c7c37d011529a05348580ba8dd58fbae1189ae742cc244242c3ff07a7786ab44a5f73f041000000000000000000000000000000000fc471997e7b0ffd50562f80a5027f397a3d2c62c03260f8691125b550c1b8b59d9b29efe79bca80a098fb8bf44590741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014773a4bea92eff773a345e1901454971477aa1c66652d98427c5c6799c1e57aca767f5808a5487db0b867fdedb74313000000000000000000000000000000001596c205b2f73ada312d62bfd465917c9f2dcc5dc8115368630539c250ff5a817ab960d9781479dae1bf4eced86383e20000000000000000000000000000000011b30afd0b167ad733e48eef7886a18b7352a54ddee7dac85f1782cea75f05a58869f9eecb8991ceb1412a3476afd15900000000000000000000000000000000104a3ee1afcd6989b8cc3371e7ee05fce19be23566eab83575b3be9d1bacdbbceeb659e324ae937bd9a5b60d99f907441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ea02e5933cbf95186a6ffff469432b17588510bbe6092ca4ac7aadf9493a46a7559f9bac9265c027cc65d9e5e834500000000000000000000000000000000004cb34cd2fdb5c37b68b5db8a346336932f3ab8d34399ec3078c76f21cf4970a380e55ae0afa9597f6ff6ed51078a3800000000000000000000000000000000004ff2fb6b7708cf225512e50a3ec283d0b9be811dba7662e4338f2569add56c1d3cf71e3b063e5fecbe0a78e93a6defc000000000000000000000000000000000b5286e9db99a258c49272676c80bedcd9bc119437d0049f9412a13a0cc3c300b8a9bacf82a7632f7948383a95f7137f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ef3ee375740801712747fa3a3c2428d0fd3220fe1dd5613a614145d45ee44244a9a33d6e50f65bd8da50fb4858ad75000000000000000000000000000000001611d8bc7f50ff2e43040569ad46d58655eab601c18c15bd47fcdc390b77c3252b43436d95d0c8dcf3b9188f5c74092b000000000000000000000000000000000b76d09f4852d8500b4bfcc735c0c3ed1a6b882bd70b1abdbfba870cfbbae87339091a6fc41e904f9a7c123eeea13fdf00000000000000000000000000000000140da05fc3b661b37ea4055586f26db16afe67dcf8c21d3cbc69deb290deae889ea9fc62dc7fe25ed4965e1cd32e16c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6609a5ad8e8198d14f3c4f4980206588f38ea32e0107c758d30cbd680eb0b035519ee386a00e9deb2783d221baef8b0000000000000000000000000000000014405950ec3539caa74e01ade48caea3c91aba07839fdfbb45fe7b04ed02274e51ae29f54a8b72bda66c9a6aa5101a84000000000000000000000000000000000f36661c3e23c1acb28f45098b3b2602b6e2ac0f5880bf5f3140e8ee2ea49a425a7039b65003593918b83d074a32ab7200000000000000000000000000000000064c3f493725dadef50f888578d2b021eddd5b2b5667d6967e568245988ff465399cb194c0a861519ada049863feda1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f77f9acae4420335aadd5f6881780de8f6a0c7a87f3c8476e49b519a6644636a37598502d6ebd5815eade8ad364968000000000000000000000000000000000ee29e559126c04b325549373926ffae1efbee969da8dcbb3d82bb90e6b01170f02f4d53558fd9035ca98cf4b3c0eb880000000000000000000000000000000002127f4fef39a86365b05c56c783e0597b0621f0ee979475e6156cd40ff44578c784059beaf5db74c6b9b9a2028252330000000000000000000000000000000003aa13aa6d02d04435f4ea1b759a8813a243f0325e1ba8b1895e603de553f9f43396c50bbc11f1c73dd8b8b8929c91801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044794895d7275725e59c5ae48db062931e8309dc069d5632adf6fdc8712d2f28d98ef93652ef0432dfba8f5781dfdd00000000000000000000000000000000006c650d984902c0efffd0cd45aa1d87d9c8b24eabe08f21ce4b2fc3cae714512bdd21098d5ec045c8deab145e89661f900000000000000000000000000000000144f9cfde1ac3cf15698eb8c5a4c334cb45d24d81ba7e3c8fc6ab4504f515f944a9ea9db0e0fcbc713324883558a9b34000000000000000000000000000000000486f15ab7f4969e5995b633a7554534a60ea246535b332945af452713f73f1b2dafdffc96910ac496215742fdcba2711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a9e86df2e099d35fd21d605fd8adf15a97f510e481a8aa61a8b446d98953f1b0f94084dc509305243af3b2ebce21ec00000000000000000000000000000000131d09c3f133d342548bccf841df423b77b748f5bd765140efab6257394a4a119e60593b5030ff1f7db5a38e056bd8580000000000000000000000000000000015f3e6a0378183fca3a20f583f11018adea1656ef89a6ff1ab3739d271fa4c8afc53c7a2bdcc4284c5ebceb651ae74fe00000000000000000000000000000000029fdb63b9c1e448285fa0befe229841ebca3763dee49b3155cef336f085ec010d3583414c754ca959ecb680fea859bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5df1f70ea2693c8e2867c8e55a4d0844956567cfecfa4b9067feca5dcca31ddad34b0020e58f5e8c93865b6b14d4d90000000000000000000000000000000017997fb7d9554c79f2a67ce2081224976e0f7e0dfd7597c8dd8384d7e8dbcadc28a27fcd8c311d22e4e05b7e4a0d9b68000000000000000000000000000000000b12ec93de3c107f858c4c32b090a34cc3161a70f6ae8f473544b9ec5be417d3e35e9d761427947a1df669959d74e55f0000000000000000000000000000000016fe78faef9fe5db3e14e564d6b56b09eabf55685e229af36854282bba6d157b4b928da2a5761a7f4a444038ebb8be5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4778ca7c44ad31ab4fb26153d31ad435c54368d96bba290a76265ab70786f125962f53b7bfd7d62d4aa7d7213c45320000000000000000000000000000000015a2f7c68e2431a64ed7c6bfe34d2299828dd7e96ffa635f236bd1e5a447b1d150864a2dc7208461b373d13628bc58cd0000000000000000000000000000000010e7ce0d5d700d83b5f9d6e7e233a5cbed5df706505cfe2256abb7023c0891476bc57976a6833e1a7ee8f086043008610000000000000000000000000000000004f79afccf204d148c09eeb30049cd45db70991689ac9932eb2c527fe45e6404b6787368a0a9eb39397cf6eb1b2e91371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d8c87278cab864d10abac16056e279c1d6fa44f115f47b2fcb9e82fca25611a1c6ded85fc2c021d7d960ea81b366e6000000000000000000000000000000000c3ea6748a194fa6cd6b7fb5c0ad8137293524c3214331ed51d1469dcabe0e4f8ee0049e7d1f7f7109647636ec221c0b0000000000000000000000000000000010f44de525b392becbd27c1e7993af943525b233268ab423752d480098c0daa8b3361a7d3878c36a5753c57d72c3c72800000000000000000000000000000000154a47409c7b4faa667e60c22f5b01524f335182f1b2a024537bba273a4322c7bc081da3e722f9a2f0c6b536f4ba2eac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078a98c9107c3e149e89e8046b2a37024edd9e29d46ee5fc06e174e20aaa4ee11ffaa5ba44b56a20cb33026a45bb62d30000000000000000000000000000000006c072be91c524f34bca7bb74a18c682f731e435a35916fbebdcfddfa080b4975026dbca44981fceeafb3439ce5d2559000000000000000000000000000000000ad09ee876ec33c20bb1e191cb14091dd09d6fac15a52b00f415737caecf8fcabdcd2e15337eee86e7321b5cd27c10290000000000000000000000000000000010adcd5b1cf5a794dc9fe4b8f3f14cef4230976247cff3f6f0eca97e0b375430ab5a6c07ceb84a9685563f300948f71f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6cd6056ff955b971f59d05f00f70fbb821fde269bff25cc4f116f8c3a9d5a524be2f194c7e50c4e695aad462e71ce80000000000000000000000000000000002e29fb207bce65d6f54ffdce6a71d2605043e7a3e3e142a72d88370f997b286a3d5825cc54796bde75fb215bb817a000000000000000000000000000000000001b98a04a09ff22546fa1f2abcf48a3f779b2e1b9b46d06e7e72e24946350841e3a1c1bd566dc29cdfe3e3f4444ed64f0000000000000000000000000000000014270a6e91dc58e236745b11f3ddeb2febcd49c75ce1de74347c137432a970dc3ac5f77a19acfbbb50512e69a721604d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037faf1f2070326c33f5640aac8bfcffaeca6bb8704e279f2f217e6974b5df2a30a35c4ee9582c0ef39fdb0ea8d791550000000000000000000000000000000012e46f36065d4079438b20521643d455fc4a9d151c3a95d273d5e5d46296c671a7d50d34c106d545c9809a26359d87d300000000000000000000000000000000133e4c45ebce459aa2784b1dc27c8a6b4861de225bc944cd93d98b63e7976a8ba89dfd9d2e38a253c2524f43d4c6f32d0000000000000000000000000000000013b9a83d3ca8b4a16a89f54aeb9f0beeff083d30cdd2947868077752ecb0a7cc38a74c0f8416a523febd3d03ad56381d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1ab6f87f7291af0ae9ca604ea4dc83a1b9e56d5c515ef5662d033cded5e89a4cf30edf2dced8db27d7266a9cd162ad000000000000000000000000000000000337616207d7383231e6bc0b5926bfe7cb3ead824106656db9ffe39795ae44cb53c0dc78f9ab9ec9706228dcc2b1147800000000000000000000000000000000122dbcc7299137220d9b6228383276b2279ab325690e33e041e415cfc18b6abca3515168df1a410a13fd3fd1897b947c000000000000000000000000000000000238f5634310defab25c59e05bb39d0e620d7c74c1a2b7e882717a1968a5c9aa87a5d9b8064bf1e8998a461bd248f4f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ea368e4b9e0a3a8c30a985ecf805fc3768e5733c1c388f39c81585326c7c81086286fa67540378c6d0756d2f4cfb330000000000000000000000000000000000f2f626f68b59eaabf9d05b31abf8c8674b980cc31f7f449cfd56f02d15c575fa75601c6e6df78d06010c20efa688fe000000000000000000000000000000000681985e33cf7017bcfba59ce57a3761cce04ee68d8ed853450c07daa20c303fbb9ed704384e2cdfd23e886a030f327300000000000000000000000000000000100a062480edb3bfe23433a8de8da3136a6d66b6fe2c746806708203b0ae552cbf5be8f4b042118a898afdf1211e32971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015cc32ea1bdfe2741059330b4de20c4a6aeb375fd602c7614535fdecc57a6902ef26fbac4650525045e3e7e0d78cc4ed0000000000000000000000000000000018c97fce161f1fc250b487979509ccdc7e63ef903d7acd6d556767cc2f0d69298f54f8505ca8ca977663f1bc641e1d37000000000000000000000000000000001032f2415560d8b51d32aa0d0de834bbdebe95b829ecc2f0dcba1235637c0502c044e5cc9dddc09d7be5709bec8bd57c0000000000000000000000000000000004fb62efd3944dfd4f1df6c732a96b185047aaba8bda6f5767edc6cd09fe188bb3fb562f1a37fee39a4d12d9e550eb2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000942365ce762f989fff5188bc91010f952dccf4307104db492a4100e46fd139c394b17d31e805a8374c5476a93e0adc7000000000000000000000000000000000fd364c7109f3576b654f4bddec8aaa9832438b139d58081817b77a925e173729012e3f1274977ac0b33d7bd04ff11f70000000000000000000000000000000006edcd909b473d99f49a50389e7549a2222b062905f5a435271d16e93cc0970167176ed7866f1d232441ce2ce40b1d75000000000000000000000000000000000ea589e1b3d06bdbbfd681799ca49680cdc6ae1169cb7f1370cf30f238c89be862e5cd1cd1ded1f2c9e759bc2e647d6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000145aff2d1569b04e42a7e44272bbb8e605f8cdcb155491b08f52a3cf22a4b7dba8dea9dbf3f88dbe88c3b3c17b8dac9000000000000000000000000000000000a08d25da1324ec8e8759595df36a7159ec2547ca18a5e430f6dc1104b44f351ab7f82e79d10e98e2a9ceccc007cd31e0000000000000000000000000000000019a6ee88832e0395c3c637512a00da0f0d4534fe60a1ea703dfd218fd9ba14e3d1bec2b04177df7afa62e2569f461c35000000000000000000000000000000000ac9773a528f704c156004ba3cb9770a1de86c44cd42e346bdd274a65a837de3a67c9450f01e28be1770b8a3b81530231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c5ad4977e509669a1baa2cfbdbdb0592edf7577f90bcf24e0f7011f424e9b2f219341f003082cbe1cab7c2e5c7fc5c00000000000000000000000000000000190c641daafb9c6e925341cbbe3e9e89576786e79960059d6ff2ce9d08e91737cdeb84874e83aa2fbf95eaeffc67337100000000000000000000000000000000159a56b80f0b584658076c1425febbfc03390bc8d97220425decc135a51f93f9c98e207d29d76bf120e7c871ac30f4dc0000000000000000000000000000000017a5a0b7a8b4e719a7cb0eaefe95ac9f7c72955f9ffe7e24131a6d633e087cf8c55c8b6a1fe2a6b23796d1e9361ee6591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bd89fd90118d60ea4bf4df35902ea8f930a39e787b01ba0a60b3f40591e52db36b4735cb5c694887e1f2020ade4dfb000000000000000000000000000000000d7580f67007b68109c8aca895045e58bb858055f5adb64e536bd0b975122e35cd62406be60adc3e619e7dc4632fa6d0000000000000000000000000000000000c9a637021f8508b02acc97733f2353528f8068927813eb2937aac6f39e56b38d7ffddec5147d18cbf4b52b20ed7ca8b0000000000000000000000000000000014a251a3aafe4a7fae33acebd223a24237d51f0d7e6c2e36b6993b91d4988a0ac6418a3b65b65cd2e5c356be21854a9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015558a948d169718e3a33b17c9cb380318d9af9c575d001d44523d442d5ba66be7a85fe66a73615af23c1ba9569c3ed60000000000000000000000000000000010a135b145def15c7dd0247af52d5b893e4f47463f0e7819d415ef06521075a565dc64902b3d5ed61981399820845034000000000000000000000000000000001873a08e7d041279d03e88dec0c700ba91187143ec7687ea1b66ffc84d0e75e2be608eefffbb47f74eaad37c50686aa700000000000000000000000000000000091839cf5b284a11da9d12bff9acc6a082f0503b3e04eda3ecd68a32b5df89f91f7e5373b86df5125c4385ad51263bc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8f4c64fb3f7f3c040cf1811a5cb01c4b04a33db798010f3e7dfa1a974e629308bf9fbb66f2bcfd4efbcfaae7568943000000000000000000000000000000000a82c3cdb469e66c44bfc6aa9efeb452082cb72c98430fb6d1bbefd3d9c64760aa2c38f453a75ce813228d760a345e0c00000000000000000000000000000000018efab4d919e1adeee5b5fcc8e89fd1b9ecbb49de50e80d60f70251d4a7da696c1c5e8c5de0d55b2887101bfcd88b240000000000000000000000000000000002d0ffa855389efdee28281a1e95fc805ef8dfe55dd54861e450a065885c49b7b6f69ebb7099bd9dabe96fd3f65493f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0e6156f0099845f81b3e16246bffa9514ac35edd802e9f39a6603f3cb1a2e6056d2a09ed2f2ebccb72371ae0726ae40000000000000000000000000000000008efde50a1e9c7bb4ea222aa69904e89c0995493ec17e4260f09b4663bf9dea0f5939a526bef1684506f836a115112a30000000000000000000000000000000001a24f67ae179255fcb9188fc5011f7cfa3e0010b5c483b524cac9cf5ced6e118ea4d91a9d2839f41099cb13358a118900000000000000000000000000000000090a800d9657928f63d9d1faecad7fb0e40377e56ae3f8c27c61a3d09fd1e9dc2c2b6cf423e0e0f88df6e992b3cbaedb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000702a2dda96def0e19b6c754e784c519b4f42972cb976bfcd973372f17e1fca6ecc0088fa5bd448bd55ba3ae530d2ff00000000000000000000000000000000004e08465aa570c5c4a6205021cb49f2ac325bef823eef8302be8ef884f62de7e68010416fb070bb3d4ed08132055b89c000000000000000000000000000000000f2ac59da7ad3336cbeda881d0e5f6b71db2ed0fda523d0d9eeffab8111e64eff04d21c66afe1fecc8adf6911aaeec1c0000000000000000000000000000000014252236ed41d358902a8e7ef2b3e2f15add33f59efd1b0c553c4b16c4dec0efc5aa34331009582c57fceaf4cd3b77901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad103e1f49b1a099ebf286650b65cc368ec423df1497e624fe5108e6115e4f7e7eae8089108bf019fd5a808fba2133b00000000000000000000000000000000039cb70034dbea094eb5bfd0a854360b378a3d333c55e3b9ab93335f4533ba2cc6dcee25a2eb90e61b1d3c54fe1c9c370000000000000000000000000000000013002ecc2c47cbc64e963d8fde3effff07450cc75322f64ab483074fa93e85e5aa2a17f0a2e85bcad8da09142b0921fb00000000000000000000000000000000074aad861044292daa97ad3f3cc4319c3db7d1eca9b66fbf5cde7e21117e026cbcaa94fb4ecdba15c45b7442f15e85a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ff622c75fda41e830d83e1f7c2c8d37967b8b2073341b856d17cdc25fed9aa4786f7295960212c5c2ca2945065ad72000000000000000000000000000000001580b7ed98c3b9e3dd0777caeaf42386f683efc9bb8088158c9c43fa4ccd178405307b67b9267c5f8305962a794816df0000000000000000000000000000000012f80580334017c86013329511527829b51311e5d52c46803ad126f62f8d548767b5dd29692b2593a0adac436becf4c60000000000000000000000000000000014144667f1a8c3e4eaae596afb725020992ef1eec41861699ec8d659d23701012610cd5591c98cad72927a3d96f429251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000001328dcbc880a0f6fa5d244ef89ad81f3c3905a0af36794800089f922e21b72ffe6b72e31f7ea58d1730e840181fbe00000000000000000000000000000000032a3c9f849533af17db9a05b229c8d3b142db58a8ce8ced3921366d27627733608126ba716270e1993b58cb3a1e596400000000000000000000000000000000045331d73f8bff93bc50cfc75302799e4a8898821e165f3de0b7936654beb9320c7ca4d5036a941b5f27ac185a8a234e0000000000000000000000000000000009a1f7b893dde9f0653f64d6a3bfe4a0f505c82a01eea7485a6bb07e39b42511c479a31e8237eeac3d766a3666dcdee91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df72c38326575a3dfd0c60abe795ff1f91f2d6e84440a16ef6c08eaea96fe445f68dde38fc9da4053e74f201f0063e2000000000000000000000000000000000dd12c1369cc16b00532cf89f17048ee560515a6fc29242e0f9ad16bf90e7ce799344f970f349d7b9c38d6153afcc9a60000000000000000000000000000000010d56040471c724e0111e1012f1c5e643d6829413e8937a7c8f77413df2511d2a4ca41bbd4e4beedda986c40b285e7e1000000000000000000000000000000000d724cf9958bb8036e3f91b09c660a2ac10b9c0a162c2989977d9ec7757d3bcc6b72691287c85b5b05a171e24bc8d61d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000168cf6afe08f62a48660c4bbda1b0e29a6b63c07d2cc86d66cd200dbcc0fdd3f69376296ed71338672a3f7a9262967800000000000000000000000000000000180c5db29ff0e366520db2a55a871e560981a850ce9effd61d544c7253c99a4b61b0cddd0faabc205ea6f205ad3bcd800000000000000000000000000000000018c2251a6903d33ceb0b12abecb7535515d5289b112443aea65f6bb96e303992f01b53a4db7961555163863cebd8c8bc00000000000000000000000000000000005fc705055c3bccf7056c9a64e6f3b9b656b7d58cac5c8a8bae389029ccae818de768c894da3ade62c83cee02ab771f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000765e1b6bea654dc67d999421710ac41965952f53ba835a589441841a6163e7d0ae41ac5406b591c6e5bac71b2f2423000000000000000000000000000000000146f33c010ada3ddeff9d87dbdaa0c4c3be52d0d7295a4da3205909168687d0948ccd1b5275b700f50753a2fd15241b00000000000000000000000000000000018ab48c636b46c8cd24191795679e83876d274fab1ddc3ceb6749fb4fd6c1b0b74998a98a34f03ad4eace16b4f2a231100000000000000000000000000000000193d73264418017fe9d23976533e9e4ec522ef71bf97f2659933f354b19bd08ff423e25a08c0af9a75af77f897a3edb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173d99f70ef55128675174a6d51fe24ac8ad83dd6bae15a9f391da65a4e5c9fe7ca4bac373a478e532739f21027aab6c000000000000000000000000000000000769c12f882e6e02cab80df2733415fe15b389bc0cbc6145013836b51026b236df8296e6da211eca019096131c98704b0000000000000000000000000000000014e7153561ac62442875caec537c4b16f06df2faa89ddfeb3994e0498ed673c4da24b3ca5066292fca1b9c9e1b1610c60000000000000000000000000000000001cc840b59b13af870042bb0ba7231f85b29a7bdc8d9368d5aa379005a7b2aa79cf481e54768c3bd9ab59fb93d0dffdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2f80834b33e2cd3f3c230d5a9e65fd674f29edfd8c0de3eac11dea59e8a9700585ebfcaac07d1ad59c4afda0a379a2000000000000000000000000000000000d6c27b820729a16a5050b1bc8a1d415f6f61da5c49e8ec83399ededdff4fe236ffedbf58b5a6ee7cda3a2d3977b939e00000000000000000000000000000000190fb3f8c608eec93abcbf1fe57b335919857d26521f30c105289a7a222490214f4147a4417aea594d912564c8e0db790000000000000000000000000000000016b8338eccde031e62fd0127d15ff0ea5f76c33ef2a49d87771228739e06e7de386a7e294bd77bb3b4f8c8a80e85ef5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052ddae4c6155a2cb711f864e53455aa551f92c76c25130658f6e6392fbb66dd548bedab448ea5bc197d7c781eb01ee90000000000000000000000000000000009237657cf177f84ba2fa09c2efc113d8146f2cee5890fb207daf667b640022decfb6fbfd98c0f6b2ae7248488004e5c00000000000000000000000000000000129704e8b35fc11aa753f3b2c2145fc1b150f87e16ad84fea400ede06149ee453e51c5394cadeda7beee63e04733fab700000000000000000000000000000000128d183c88817bd7297bcd58e33cf1da2e21dbcdbf3e0e7533334133431303ac6c4723e449ea889d1c043c8c99e56e091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8b24cfe2db01eb6a20327ac388d08e2d7bfd432097c9e3dcb697a3ff3a05d3ba1dc4e249391deb2eff3d0a08e1763600000000000000000000000000000000129b1c3b9ec9285f6916f279eb15513b87deb860b64ab138493453187d2f705559f840165e337f7e9b76d3361075246a0000000000000000000000000000000005763c17c5358c8fe56cf3a6350a6fe717545e3236f14ff2e2d9c202d8905317595b0e7e20b6ec17a7fcb1486f7f617300000000000000000000000000000000175a813782e259d77769d3f17cd9edafe10af907a8d940364a29e9d3b8b75ec3fe78fb07e9a2d77909326cd49e4ad1941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027f79d337b30bce1689db92d77b95fe68519c3299008faeb85235425c983b239789a690613b3a72bb74caaa5299ca1100000000000000000000000000000000173b4961226319cced64538536a0f0dec928b8a79b1f0e8a49f18d0cdcad68bdabfd452e30f96677fb5b2979b82dd8a500000000000000000000000000000000130833412eb66afaf6b445c8b367e6dad4ef1c2558c6c5f75f484371c464a260f860df4837b69d568d89068053d70f1500000000000000000000000000000000076fd9f1d0deeff4d3784c597d12668910dd7d94ea5156f3116390204a75a04f087f6ef5dd5a4ec0ba7270092527907e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e762c624f0ea97818c0bb83117d5df0afca15407a2641ded8561f00c7ab2e4e24cfe82457876aad20db7d3375254269000000000000000000000000000000000339a65bee3e72fea81701c3d0edfc75c38750e006614c4fd83895b10ac055ba5733ad7be8bd8a0811725a66ca12411a0000000000000000000000000000000012f92ce4b8c842fe0a4b22a3d950b1a1fb190ee09e771ed297369cf8b144198ef352c1d0e3f7e2390705ae1bfe18b2a70000000000000000000000000000000016f5607cdc02f9170619c0fb4e7ea1e24dd226ba67c41ae6cf7105785d18571bcf8fd601512fa824b247e6766af6325b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9fb4d154f2dd4fc40bb8cf0a64a36e6027b4ceef0f79516ee6dd5cd8144303ada1ff15f5e9b1603e2ddd6f94fee75500000000000000000000000000000000114dac33b2a522c7f8ddc9fd92925fd325b91a08f67e9d639cf616f517c66c4d1faeaa79cdb784f511ffd550d9dc81c4000000000000000000000000000000000bea9b7c4323d0b54b7101caeae2437f57b44e039c6b205fba391c00ece275fc609e4ab0213e88ee8f998649c6dfd5740000000000000000000000000000000010893701c4e486ccf3e3095d2f3f02a439611d4608a681652f2f4d8207b67c773e20b7805bc84e39f4faa480d8bdc2dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004273c66a22783fe880619708d228caa29ed4f3198690ec8ed3be4dc6b675f9ff47468c36df6d290c1456242d15231ec000000000000000000000000000000000358ef987e8d618b057948d354be0d95c8f140adec04e11d98200d66c500e57bbb527044fd415d6b0e6aea1380c620360000000000000000000000000000000009a290f91b985126e3419fd222e53f1bd23aa69ab9b81b9d957ac568d55a5c428bc981e216b7ecec357b6154f79848b90000000000000000000000000000000011d8f3f6aa71e9456a44244def7f0af9bf00e48f076a7163a4b15fda145e310078192ba8e1bfaa499e92f5bcc7b70a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ba6ba86b644bd96892caacce01841eed057ddf9f460eaebdce8f26fd50d31d9bac315303dd2aef7e3c905386ed6a9000000000000000000000000000000000043d9e7e32e4ac93f0903f0e7bf2e1c94a1dee22812a9d1aff62cae5fb665362ed4f3a7a775fd9ee3e2af252c617b18f00000000000000000000000000000000163e9d42c96fae30f013353e9d97e0b5786a90c8110e712341176504994176be149ae3e238141f7ee5e58b8bd269154e0000000000000000000000000000000001fff186044751ff136e0add91eaa4da0b2ca21e868b73607fbe0acba408596614a86c65e2e1f88b81ca8d8f9fb2289c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b966bc869f1e1c728cd89b7c99e79d19b7daa0856f4d9ae54fad6c7fcd0772b69a1d00d60c76303a21f46e900f5f770000000000000000000000000000000014cb15361ef896464d79f84b0b3520e94bbcc92927824b4d269c2bbd0af0ae1fa212cbce88ec54346393c4d423ba52b40000000000000000000000000000000007aa57716b7d95726c0b76e9b7bcf7e311da08fffbc81ee15b02f4bf08b3dd41d165115a259d34384d72fd75fe6524f800000000000000000000000000000000008ba06b5a787d2e8ad4c3f910a601a45f30b176e3618c0439c00a871b2bc14e1de0bcc2b72ed593dd69798bf0ab97d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ff17f78120f59943cd9b5007a1c607d787fbc08a3bcce5eca9a6e7336291e6b696a1efb6ce5193b7b7fd3f68fc43f000000000000000000000000000000000b799c1169fb6262224d7e953c3d710db495d88918fa5ca3ea106bd7cefc198f038df0e13db4aeeef4c4a6c6e8b7691c0000000000000000000000000000000012d458b19c9cd7ff654afdc4ea4d3e275271e579e3f083ed6fec04b92192ea19c1b55b921b34e20e1de9cc53a47951a800000000000000000000000000000000097e35ba7cf8b39ac42aa4c3632a0a0d6e8a8f057bc0fd4b11f71aca126ef7686f8f8a2c0241f67eea242e1a2771b1511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013eb7950960759e13626c7b5be87693bdb5eb05968bed9cdecfa1068cd7d3c97075ccf709ee8e9637c076d727747cd7a0000000000000000000000000000000012ad2c196a4f7fd2d4089484e785062e43839b0bc3e1d604d1630e4f95cfc9ac91bc750fea7f1735b4ff5d01fe6de12b00000000000000000000000000000000113e31c9d50cdc9f50b9b00e8793ac8a07d4b1a84dfd732c53933c43c0cf0b4506ba18037798aa47348d2f1ca24b08b7000000000000000000000000000000000cec9ee9492a05a533a2a35482454592436c4f7edc5695a88f0cda522e106f07f35e3bd72fe01647029b480b6d52ed4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001439a9fa5602ebdce91b248d2e1bb6d3f937e2d2249f5fe817301553bf36e4ff002d6d066cb63e24ab57ab920e600c59000000000000000000000000000000000da6eec4829a4b940710643495c17232d33bb7bdd767e1eee4915077ed0b831df1a3080da98baea829a6e377e9e0d9eb000000000000000000000000000000000c2a4d773e64c10431842145644ae2f63730555f11da19e1458f9a9ab2adf1c3f1a045d5aa997f8a89ec924a8278c27f0000000000000000000000000000000011ded0635e59e428d88629755a8ea11b8bd23e0b0c60182c73a4e8de4b7e50664399d88e228ead5528189448781166331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d620ec19ed67af168446e21d5dfcce68a5d1d0834a295357facce7e26f4455030993a700ef8cd5a91891b613a3bc38000000000000000000000000000000001630fa86ef31311af9802c43c0e0a873f75109d5b76dddfd2da074d5720b23094dbccbc470358eb192fb5d365bfa7a3c00000000000000000000000000000000032d6422d25d881dd94b629ce2fbb8b6c2ba6cd08d2f3da854f1955affde1eaa6e871a2ab489adb0b5ff978a7df6d3f500000000000000000000000000000000169b3e6864dea595ce86d97bfb9fcf26eb23093ba75aebda1930fc5e3e0cf2f641d27226eb5f994dbec8e47f8120e48a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ac9f1ef69025b67da31eafb81eed658f6472c2fceacd7cb5ac84b62fca6b04346e8341a02ce589d21e302a390d976c00000000000000000000000000000000175c5f9083b2d98038cf64df48e34222172c42646a57b9b538f02528950fe7260eea0502f6b04699feafe41d59893d6a000000000000000000000000000000000bc921434624de5334fd7f509977d4e8b6b69ba433a61cb20ebdb789a959748b30afde60e6bc6e740c0a9bf2352bf02e00000000000000000000000000000000002b757118fda743829e1d8fc328aa246d28be1b95f95452ddc146bae88660929a96ac6659984ad8d715dbcd6d6bf3481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3b2e15738504b69eff2a74eac44096ce50ca0998a550c3752db69289276feb136c27c7b1eb357f73ed6e4a14810361000000000000000000000000000000000629f1cc9c59201c332c38620a90236031fd803a1ad128d619e643e1d4d532a71eadf8ebaf5a4b45852876b561fef30c0000000000000000000000000000000017d094359487563883715eb07669854e4f025cbf47ec303f7303842c9f022b6ed7a037eb0d9bceac987621c08e8d4ce9000000000000000000000000000000000e1ace86b2e1063619d1282e00565e0d1412482070fd43f400e0a9fc042311b87b348a33ec925f878115b253e08bc4e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f40d0ebdfce6baf1024a669937170ad9e666660813dcd37ff6531d84f4151b6305dd084ff869988d99228fa1b60b410000000000000000000000000000000010b3ae2e95fbd78dee8c29da880747249eadd3334aa9472f08b31fcda74f8ba0678e7d8f44b30f0eea2c00d1f267d2a00000000000000000000000000000000015cdf4a52f79f6ef8aa5d61c4488b7314a71d252face9c87c93627c49e8a981a4b553feedf2240942632000b52a5b56400000000000000000000000000000000072e87ebd1b0d459651b6a3a0421304e5decca06aa8b4fa8e13a5f3bdd75b788014387a43b68388c0d2c34ba3f96d81e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a4b021f45c78564fa6303113aef811501c61c0624de6dacc963b42f8ffcbb53164ca4deb0e4063c9200e84736aa5c800000000000000000000000000000000173a9c582dda8f313e1f5c14f21a7f00320ec3c2b7558ed6d113ac89729071590b3ec982a79873e20caf3c6fcf565d700000000000000000000000000000000002047ea8f40ff057dfd05b17b67a350f325e78dcc4a0d19a405e64ce23c44a8e56841ca9f57e35b2f7e88771210b31440000000000000000000000000000000015b5688dffc2613c16bd1a11e3410f660d40272d682c2329a8d04956c01806d7eedb9138001a23edba6a738a21ad2fde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000100e0e2b1b4fc00721c1155022da0e3b394b0d8dcf6d8d29df8847704ec4dd9f6305ad7d2e1ab284c1074ae0e99461e00000000000000000000000000000000139a1bd565aa1f7013a5c0f08fab90bf3c157bf2b4bfdff3ad0de942fc4da05974b522be22478d4bc1b269444303f74e000000000000000000000000000000000e82ede5724d6b42a0b30ef3832c8519df8eccde633f7e2a91c3d25aed3e423752391b8f378d26e329f28f22fc0afe830000000000000000000000000000000006cf72bf453c494798b05ad401d1be0f1987681549869387dc85afcaf7a8e3f7bd4c9c9564e6087c8db68bcbf234d8b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acbbc26ff8082e6201281507ec817e1aa48fc3cd749245e4dbf9813ddde2082f2232fdaa4397ff995b5efd258361ebe0000000000000000000000000000000013c2592b2699e28b4a4a6a55c5077e4e927770937d0b585bf5bff3ff94fff892949a262fa60d19e7a08e11ee278ba49b000000000000000000000000000000000aefb08f71fcc8531b67b5623403305914f4a1242452543c05a67b4d805e04bc2b055ebad1006d2d84384794039d2c80000000000000000000000000000000000df5642c7ca23d3bf49d6978cf0689718bb73c020d503e7cb021db046d16ada87161feb46fd56542c8dde6b382baf3b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030aa5bfa6df9718620f17020a39f2f6ae0441b5682e11651070cfd91ca9426061b98daa3eff2dc8cdbb850829949fa800000000000000000000000000000000104d57eac1696ab955e852f2e092b3ed17471bb90bc093d2bfebb75c2704f6ea8c7979117568a18f25d5f88c3a7cebfd00000000000000000000000000000000099415ea067b342246afcfbc0555ca55b6c26e25af9ec43ec087e035fa8675b06eec4aba6161d6ddf145ab33f3089ebb000000000000000000000000000000001384ab642dc21526b26669b9c690741b98244d45e1ae5161255ff1ed444d50d5d4ea9b5fd9906c822cd646a05381b12e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086963227ebd8ae42e99eb67d87de72e9b8c8c4669cd9526bdd68670a76b4244f2827afc2d41a607dcffe880b466efdf00000000000000000000000000000000095650612c2197d7999241ed00ddae080c1627238d1884c339364931ea26b414e31c78a91bdecb1c7f797f61082748e40000000000000000000000000000000004c8900e47a670376abb302004481cd2cebbf5057115a63d03285afe62942f3c6cb2d165068cbe257895604bd0c107e8000000000000000000000000000000000c216aa20807ed1fc40c1d9a1792943154f77e87610416a26528af6a0571b2f5b61496504140d100ccd673d31dfa47121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a47f12407eb06e902e57c1b44b95f74e367e7f9332fe3f222350169d9874b422f97d51a01271b3b2e6ae250396b72b0000000000000000000000000000000006e429926d5253dbcb6dada8a418be7aa9c80c02b10b201e2d9fe9968c610cd833451f43029f62ca0b1885d7922871d90000000000000000000000000000000018f4170bdcdf38caf19e7d3c9cd2d78d1180ba945228672584eb75b7afdc5083c41aaf5861e876cba452c384bfbccd5d0000000000000000000000000000000002e58256b22339fafb9eee9050aacf7f3b34bd63dbff334844cdf48871f6b5d5650a0ab8d70c48640cf04b3b973e20d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124b19da6d8fb220f7e566499c192778e9b28cb2da5fe31ec2e569a03fcd7a1ba39deddf36d489655f7c69e10675e7ef0000000000000000000000000000000013650d54147ac7d016b4ee94de62e90469534d8f6a2bad6ebfd6e5d50247a7f184ad6a1af804cd43520d47e8c9d6d1780000000000000000000000000000000010d0cd79350974897876b17bcd2d6674636cf970ec3344677e381c72419fee418c15588fc37cd1063c5047a5ffbb5faf000000000000000000000000000000000f5fd55bdd7ea1b1c57702ed40cd6c63912ec6c0d13f954f41b5d8347e2a0befe2af9b900d48428b34ae9f5a038551981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001400738f1235b9302b86d2128aebfba46088b755cd7095f8e0feb6400a91360eaef54bf8e714be30d743d91803457e3f000000000000000000000000000000000644d3929cc9911c1e292336c0d43d771410d46c199e064bdee825381ea26219d2ee9696e50a291f94ff2752f5e6574d0000000000000000000000000000000004cfac7cba9dba084b0418b147cc7f0a6090ffb3619d6206121477dd8842f09dbfc48e14d5528d7f12bea9ebce41d9b4000000000000000000000000000000001025cd701a8a3dea5097c94c3924350b53c9c8af79b7ed9baaa928065a2833f860baa1a154b61b068e5d9e2840bda52f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084dfbe49f37db531979d235fcbce3b5ee534a654ae64b7c1616bf5ca282b59325bf7f69825a6831c3766b867757f12600000000000000000000000000000000174dc6e4fc2575701da91aaf5c3fff3ba476aa664d183cf57b2634000a82e05b075768a8a442a5cafdf95135c2cc936f0000000000000000000000000000000015574ae00f6dc32ae57f1db04e1ba50c82087cfb269349e98b0f8841f83a7bcacd3785954f8847bd88df0bab01de8444000000000000000000000000000000000cbf903479efb8ae9818a9b824daa117bf8c04c7922cbd7185b6f1456f425049a02f87abac7dddabcc0a183df781bdae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001039f728d8d83c9e8700063c169395bed6c7490d54dfabea1fbdb714dfead0ef5c86c8d8dcf8b06564ff3bcea2b803b50000000000000000000000000000000014a40ad99055d4c16e76d9922446d27be5761ccb547d22137db5ce8909004c3a39f797b0873a1a5637834ea0da52aac7000000000000000000000000000000001089b3a198f4f532514a35d74d69ef387fd54d8e8805f479b3425c840b256d40016f4972ccb3e1b650f6cbe7e17df05f000000000000000000000000000000000ff6b147cbc7407e1361e9e9f71c62d6b0d81a81be5be90aa6ac2d565fe07661fa73c8f0b604212f3c3a268c1f56c1b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f3ae1582692e3e33f2442991530517219f9b3ebf88fff03f81237553cc1509a4732155423dca88a6e63e9f036318b400000000000000000000000000000000000f80475ada3353f9f4beea3181004bfbd77033276fc97c73cea875cec86ce00c1c2956c5d45d548436226c4d0a48930000000000000000000000000000000000ced6435f355fe76d88f54401e4fb8f3992567b969177975597bb8f4f085b43dac6c4bf7b79b63d8bc617b1068655340000000000000000000000000000000010599298d7f952758f22e9c64f54b0c637c203b3fcafd205d08a408c20a8869612c7484c88d2843de8ede4c63abff98a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000deed304633e52f8174b8ae6f730f6751676a6e3f8e26ac8c114615f463eb2da71a9bac650ff188f16c1e9b61a2e0c900000000000000000000000000000000166b2764aa0c60dfc3d8d28d4a4fd2710608721be0074505f7c2f6061a48160812488f5918649d973888bcce4263f79000000000000000000000000000000000025811567302686b3d8304c35dca281ccde474b65acc50ab4c57be143cd60e73edd776395aae8ad7fb50d8d8f596ef1b0000000000000000000000000000000019b23e64059448e92ae75cd1dabbd569eb727a74f108552c06c1d64533d6f79b066a60fbfb1070eac8d9d095512d60791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148aa82244ac489a6d29cf7a5ed0a2099763db2d5b4c7324073e240271e9f9bf215a234ab16ab5cabffefebb36d8b3d10000000000000000000000000000000002dbac638f7cfc530c9d2bd1cdd3faf64f2c4a6cfb636ef69ea759aed9fd804f890e1d94a6507c1f330a760aa5fc37370000000000000000000000000000000015edbb563b6fb737e9f7eb0ab733b675ee622ea0ad3b27ad2088012434d01e00965c9d08d7d5e29b3e2312ce29d61c48000000000000000000000000000000000586c5fb0a680dcab6c924a7f1b77a4c4c5eecd7906ccc5766f0a9f874d19718cc8c84ec4349f4b2adeab311b259cfc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018536c11854b53a080f259976c390546547ebd0216c60f4b992c396297720047a64912403d86d2e7f89958b6a7e196b900000000000000000000000000000000019667de47937d95031897a3fc1b977d5d7194327c62a61181f28d5480a0cc5080be670590f1a3735a5e17e5bd1d9a8000000000000000000000000000000000006a522bb9af0557b0140812716059d749d47e8258254ef496dfff3d33c53ab448ecebf303ade65fed0747539cac0ba30000000000000000000000000000000010fe64b2d4243d5609af091dfea721fa7ac4a7a20e1d6a658ac48cf74fe071136f9245c76839c8324e57da741c40749b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023284f6bbb674448250470b05317d1d5464aa25d2618ebbfd2c94dfb4242bb24740dc09b088822d53e81fa0c3df684e0000000000000000000000000000000012d0f6105f450da62341fcdf77f85c8635ae876d892fb8b84107cb3e1345eb9e6d4443bb58936b40c3bdef769e6f8f74000000000000000000000000000000001469c571de6025bf61e8d26bf42f2381caf37213428671ca27b5c3418dcc4c07acecbb01ca2b62556c3e04d498d7c2d1000000000000000000000000000000000ffcdaf88a02d1c5e67418ceb2b6dc133d8c35aa080b84efa8ef68ffa330eb85f99f430cd5a06878ac7241c811a160c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eb0ab3b9f7c535d2cf14bbce867368b830f0832c62877c581ca80c46305e2f2a264279a33c6e0e311881a8d38300ab00000000000000000000000000000000069180f60e9c49d57f3ff7f25698c34842f8d1a08a3c1b3a9c44389091898983571c4100ce9fe30f69d616897ec280820000000000000000000000000000000018f9cfb80f0e064808bc7ab72b07ff4d4cfbac4c2a332a52dc0d8864b87b8b0b28d971b0b55c3e173ee2c34880eb6f620000000000000000000000000000000001d32e89bbb423b49835d05e1ef847e3f60ef7e9c102547ef0d5cf7e8ca3860d64f304a5e9a652e2b00a24cd3ffcf17a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084fa87381de3b4029a65a89d30748c6b36fdb5dcad5bf9f16a288a50b8ae8390725db0cd7b78fbfc18127cbb50053940000000000000000000000000000000005f29523e7ce25322e5c01696ee6a7b1b8c870e53dfc83918df6dc52d1d0890157c927257b111ecf41bee03bc90f1e9b0000000000000000000000000000000009a428030f019ee2907d46706e120be71ac4cde2f6bbf534bf8ff67d5e025f74f49055034e5e621cbb6fbdcc1024607600000000000000000000000000000000136934b9a77919605cc5cdf267d7ad3e17d3b98c411b824ff02a07f26c565630fc628895560030e9c69f0b174385fd7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e05e43fea0f6c7b589be17d2fd51e5d2e9e2c8119c391e3a65573dc4a29fa6fc4f134e6988f64ef97fc2ce01c09b040000000000000000000000000000000006da32b477fe9f75ca6c6aefd26e4a6c2adb2f179bd37c9f156380167842e85c86044ca21358363ef2fa4579c432ac94000000000000000000000000000000000a006191d9277dd93264ca4d3d7855f3298905e5c27c46983e91e339b890204d4b3e4bc7924da350dab83516902551d10000000000000000000000000000000007b203cb2e15248c5fbe2ce269c2e3027a5c03b07fa2cec6d2619ad9d9eda38d2e7d96de0ac5c7b9d3976001c5df20651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174a53f2ef50d98eceef87abb8ed231ccfbb065fde000854ec8ec55ed1d480ff4022446c06634fc9a7cb71eff99c4a86000000000000000000000000000000000a758cee0ec88392aaba77d7dd3b9c18df2f1da31b2daed006c3d79a196b86d5443388ab9ff3369e87e3ea7a3539fb0c000000000000000000000000000000000902fabb7c99dba8759f77accb5261282efa36bc101908e0f7d9569c7363d880c3b4ebccb93fb04cd6b271010cb524d0000000000000000000000000000000000b217b772f517d90805cb4e6037f2e82839fa9549da1859e85cf76ec8952fe98fa8a9d40e3fecfc7bb1846f1f8fa62a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001050cb16ce5ecbdf55d83ec6804945b882602035c3a621376267dd5ece77f083250c3de885ff65adb310e01db32a64380000000000000000000000000000000019da83f5fa1fd94077015622535295a6d4763c4f464ae5cffb3796cf99c3e0c115ec65d28890a3b68d0d62f7bb86452800000000000000000000000000000000102c31f1bd3638a26b7046fcd64919389572a6d2b290d03b0c028a0ab48f2ca5f30dbcf925ea90f68cadef85a239c8c70000000000000000000000000000000019a33801bf1c2977e1586a9ee9cdc74777436aaa069d241f365b13db0946078f5a70c846946488485eb1c19b022991ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049318e9ce756dfa02a47602fef0c5f69c3bad0c1825ecf52afa1c9001e2b60a4bb026fb465eec2b61c040d467890c6100000000000000000000000000000000147015d586e332fa678d2e6567e8814861eda9d25813108e54874c37441349413aee08839bf48dc8050b6ea7cc5b3464000000000000000000000000000000000c87b168ad95ec5981eead6a37d74e30ad575bb09aa3ac17b8bf0e5c6a11bea1b8d40f56f90d347046139c19110ec935000000000000000000000000000000000b8f20662e356ca8b3616dcf03a065a97a859b72936d472ed9f12431959b4fdd69d414b53879f86bcaac130eac8198ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001900021195089a4feee22cf8b539dcfba09ca48f828e77f5d905b3c2033404f2ed7b21509faee6ee6248683db7ac3c860000000000000000000000000000000010759a56269209a12894cad47c979c6b46282902cec89511f7adda7392c90bab9e191b5b6a8005f72854ae8e858f0ed400000000000000000000000000000000076bc78ec0a0c097ab589450c886f300a8edca200ffc84c03749b76b484131c620b5db35ec0195ac33edf304057b41bf000000000000000000000000000000000a92607c52d5c7d0ed24738f671d1c6b11e0590f64283df1e7db79ee40a9ea4ae2e38c3cf76225d0facbe93e5eaf8a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001851f0f6db1eab1b69dd7ced468aeccf2df239b455fa38e9313330e5281f18a20a8aa20ca1c5e5bc2f9866aec92a12000000000000000000000000000000000c1c251901260bab20360db5b0b8e050ac8fe5abf074a67c757002403416826c502a8775dfe851d2ba8cce472054337b00000000000000000000000000000000139740ed23b4d29802be95d6f302f54a2be8ab0aa3f183afce973fa9149b89f877a85246cde29676a6ae5ac1e0965c3400000000000000000000000000000000091664122a88acce381e1c405cfc18cc11f8c630bd4f438aecd02e9ddbb0ed85d38da050fa98e6adddc29a7c8c17344b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c65ccae34ff73b68373937aafa307355b32e3c3d0ad250fb062ae82f9cc13beaf298c6a71dd8d5599831fb38a8d315000000000000000000000000000000000aa6a6ed43fa75789d2fac1a0dcc92eac8b9ce5f49d4e2429038141a47144d37e0a8a20a232ab6ebb075e0bc17a26bec000000000000000000000000000000000bd00304bd516b3b64b3ca19235c55e1a4dc2f7d8ad2823992909271bc659fb276bb8c42ad2811a13dd3c37ceb37d88b0000000000000000000000000000000000642dc986bd879cc949e2229935f947a17ad848af0d52fb990504f745152e4e7bb11259ce4a8bdd419480db833424201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ba6a5d12a35ff05fff302c4abfa325db749075b30acdba4897092e9838e24003afd118800182b3a82b24695dd32e150000000000000000000000000000000013ce6eeac487f264fba1f26b6924734b816b88e120aad4a650c6033568e1da2eada3b07f097f7eb5f1433185fc68cc7f00000000000000000000000000000000175f9a6a026830306e7c9ab80dbb19bb0d0dc936141070e1bc165f0cebaa8bb35ddadd090ab8c0d85724eb83751578d60000000000000000000000000000000004ab1eabbbc1b88785770be143c478e059ddbb4a0be5c301449f7abdd358e8db0f1570bde2c37d25c33053a5cca5c49e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001393118b0664124d991ac7a98eca8888ee52cc90065b468838bba3371495ba4d5bbcf481d3d642c444bcf17fc8a69cc3000000000000000000000000000000000d3b5e12652096f1d9c6abd0475f9edc3e43998d31488eeba4f53c0d8b7261ee2adb0392168ea23ad8ecc8b4b607fcd70000000000000000000000000000000013b5209b79a78df0465415dec28ddecdc254f8c843199c62c23731a2f7e3f6b4f2f03a5e80565f74173131ac3cfe19270000000000000000000000000000000012947041c7c6f0b5cd83dbf442bab64e0c10cc33e0b53e9fade4354eff20da0b1c7f080fd8d50c429cc036eba2eafa281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009213afdc588d27053de6b0ab5df9ed62b313e1d05d6e5b0965d78f7cd8f665c3615ccd7a7759895a4402cca974a32fc0000000000000000000000000000000015c4262ad1b113cc6a65d022d480aba4f3201b519c296ccd5873a72bff4a9c4aaa8b6b1122486e15b1d9063e1379600b000000000000000000000000000000001832b25262ee5b8f100049b7e527f7adf82841f81709593211c3c2b73c20ea2627dd94c4af553d35a48f30416e7fb74a000000000000000000000000000000001776386a29b3457b0852f03e0c5abdf08c98a06809c7f7711038b8fb920f059d0211dcb7203177e37ea88b043d70f42c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000749414cbd262bbc05c87e61cf091ec90dae3c703e87b4040503f15cb0a0a9b5d208869cdf4a54baa9f737414717c350000000000000000000000000000000005485e5fe4329edff91541526ad98544953d58bd405b0d03a76aba85174b12910a77c2149f6479752e858bf566032a260000000000000000000000000000000014578447e6068e02f5d13120e72148785efae64bc1d52efaa8594dc0491a3b280ec9be9b06400047710cd7b88927b267000000000000000000000000000000001615ab016fdc2acb99eaa9872b4a896bc11009a66bc2c9cbe5cec0b187b2cc8a213731fbd33c6261d3b636a237e79efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000292589156be4715b87f0946d868034f2d33c22f3f615ed620faa031be47b86bcd1713c5c6330872390c1632b6c6317b000000000000000000000000000000000c35b7e6e42834831134e7cca1e9fff98c83f8dea9b21baea96d3aea623fe6b30c4edff140784fe9f1581aed28d7d2020000000000000000000000000000000017bbfa07a4746be906e692e09a3ab20629c1be8c07fd275ae37d717b4b4af1f25303cbfa3473588886a614aa04e3e6f600000000000000000000000000000000083f3b8815c245bfde07a139dfa4910743241741ea46876e0c8e0a7c55c394c112b76c71f401d0192afb63af49007f6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a8312c30f3a7f508cbc1cf6f00a6973873309a9cc1ea8cf682f637a73855ba7dc5c10908f306a5282764f66ecd3175000000000000000000000000000000000564c133be0d3be8698ab98a2dafb2b82ca43636a9876eff19fbca8e113e1990ccefc4492b6a6034ea2e2d6ff411e574000000000000000000000000000000000ca0f865c096920be147dc662619a2763817a474ddcad928638de4dbf121ede32f8c5b5d39475b18e8f924054b86a7e300000000000000000000000000000000043f0230d9352dd19767bc715b8d471dff8e4c4b355019321585add13f15e73bd5f7419abb924a300bda1f3f77c01df51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", "Expected": "0000000000000000000000000000000007ac96192f4225233b4b88f7cf2650464e10f3b8275304e790b72f006637051fdd82b98d791928342b00a57282e81f5a0000000000000000000000000000000007a341a771e2ef772134661c486268c3d354e8332655792b88d6bf7ec3cb8148974141d09b21a76a9af869d30bdc1b750000000000000000000000000000000004e01c938b6e64e5786b7e49b19d1f437d14ea9042b5b25e611789d1eb6c94db812976e75b9cfe635a7e9c8dffe8bdfb0000000000000000000000000000000008da0941af163a46252e9c6057497cd04637924f158f0507ccbff466ae810e2178eac76cb3ff8835804b88951cd44c0e", "Name": "g2msm-1024-jwasinger", - "Gas": 8017920, + "Gas": 12072960, "NoBenchmark": false } ] diff --git a/core/vm/testdata/precompiles/blsMapG1.json b/core/vm/testdata/precompiles/blsMapG1.json index 07903a3125..19112d1d14 100644 --- a/core/vm/testdata/precompiles/blsMapG1.json +++ b/core/vm/testdata/precompiles/blsMapG1.json @@ -698,5 +698,41 @@ "Name": "matter_fp_to_g1_99", "Gas": 5500, "NoBenchmark": false + }, + + { + "Input": "00000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f03", + "Name": "bls_g1map_", + "Expected": "00000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3", + "Gas": 5500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000147e1ed29f06e4c5079b9d14fc89d2820d32419b990c1c7bb7dbea2a36a045124b31ffbde7c99329c05c559af1c6cc82", + "Name": "bls_g1map_616263", + "Expected": "00000000000000000000000000000000009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d000000000000000000000000000000001532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c", + "Gas": 5500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000004090815ad598a06897dd89bcda860f25837d54e897298ce31e6947378134d3761dc59a572154963e8c954919ecfa82d", + "Name": "bls_g1map_6162636465663031", + "Expected": "000000000000000000000000000000001974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a0000000000000000000000000000000015f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a3", + "Gas": 5500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000008dccd088ca55b8bfbc96fb50bb25c592faa867a8bb78d4e94a8cc2c92306190244532e91feba2b7fed977e3c3bb5a1f", + "Name": "bls_g1map_713132385f717171", + "Expected": "000000000000000000000000000000000a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c000000000000000000000000000000001383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9", + "Gas": 5500, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000dd824886d2123a96447f6c56e3a3fa992fbfefdba17b6673f9f630ff19e4d326529db37e1c1be43f905bf9202e0278d", + "Name": "bls_g1map_613531325f616161", + "Expected": "000000000000000000000000000000000e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11000000000000000000000000000000000ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db", + "Gas": 5500, + "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 0b2ad89ece..5fd83f3437 100644 --- a/core/vm/testdata/precompiles/blsMapG2.json +++ b/core/vm/testdata/precompiles/blsMapG2.json @@ -3,700 +3,735 @@ "Input": "0000000000000000000000000000000014406e5bfb9209256a3820879a29ac2f62d6aca82324bf3ae2aa7d3c54792043bd8c791fccdb080c1a52dc68b8b69350000000000000000000000000000000000e885bb33996e12f07da69073e2c0cc880bc8eff26d2a724299eb12d54f4bcf26f4748bb020e80a7e3794a7b0e47a641", "Expected": "000000000000000000000000000000000d029393d3a13ff5b26fe52bd8953768946c5510f9441f1136f1e938957882db6adbd7504177ee49281ecccba596f2bf000000000000000000000000000000001993f668fb1ae603aefbb1323000033fcb3b65d8ed3bf09c84c61e27704b745f540299a1872cd697ae45a5afd780f1d600000000000000000000000000000000079cb41060ef7a128d286c9ef8638689a49ca19da8672ea5c47b6ba6dbde193ee835d3b87a76a689966037c07159c10d0000000000000000000000000000000017c688ae9a8b59a7069c27f2d58dd2196cb414f4fb89da8510518a1142ab19d158badd1c3bad03408fafb1669903cd6c", "Name": "matter_fp2_to_g2_0", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ba1b6d79150bdc368a14157ebfe8b5f691cf657a6bbe30e79b6654691136577d2ef1b36bfb232e3336e7e4c9352a8ed000000000000000000000000000000000f12847f7787f439575031bcdb1f03cfb79f942f3a9709306e4bd5afc73d3f78fd1c1fef913f503c8cbab58453fb7df2", "Expected": "000000000000000000000000000000000a2bca68ca23f3f03c678140d87465b5b336dbd50926d1219fcc0def162280765fe1093c117d52483d3d8cdc7ab76529000000000000000000000000000000000fe83e3a958d6038569da6132bfa19f0e3dae3bee0d8a60e7cc33e4d7084a9e8c32fe31ec6e617277e2e450699eba1f80000000000000000000000000000000005602683f0ef231cc0b7c8c695765d7933f4efa7503ed9f2aa3c774284eabcdd32fd287b6a3539c9749f2e15b58f5cd50000000000000000000000000000000000b4f17de0db6e9d081723b613b23864c1eeae91b7cbda40ecd24823022aee7fc4068adc41947b97e17009fad9d0d4de", "Name": "matter_fp2_to_g2_1", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001632336631a3c666159b6e5e1fb62ffa21488e571cffb7bc3d75d55a837f242e789a75f0f583ce2b3a969c64c2b46de200000000000000000000000000000000184f1db9ac0fdd6b5ac0307e203d0b4237a50554eb7af37bb1894d9769609c96c8437e9d6d3679ebd5f979eb04035799", "Expected": "00000000000000000000000000000000184af3f8a359dd35dddd3dfcc6f5b55ed327907ed573378289209569244e3c9c02bdf278eb567186f8b64de380c115360000000000000000000000000000000012f5ba8e520c4730ac1fb75dabbfdc0181855e5ba2968a8c0ba36a47ab86ac45d19aa3d55f15a601e120be1f75eefe240000000000000000000000000000000004e313db704b103c2c1e3a58f8e95a470e7199081eb086e9524583131714c4a3db551fd51a3f2314a19a658e7b1765380000000000000000000000000000000004040eab7416a1703b0d103120506f1de2b26b0f48c7a0ea63dca4d9ad1c478ae03b5d7bfd51f4cd6f8cea26212c4edf", "Name": "matter_fp2_to_g2_2", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000732f171d8f6e283dd40a0324dae42ef0209c4caa0bd8ce2b12b206b6a9704f2c6015c918c79f0625fa791051b05c55c000000000000000000000000000000001139e8d932fc0ab10d6d4f6874c757c545b15be27cdb88056ed7c690aa6d924226d83e66b3e2484b2fc3dcd14418ee60", "Expected": "0000000000000000000000000000000017fc341e495bf4ef5da4c159a28320aca97ca28fe3a0441242cf506b0f89bb52f5b5d8c6e038d229ffe67d00151912f00000000000000000000000000000000007666300b7be3d904ae3d19019f7be5cf5ba6161b969c1a78aff639a24387d8fdcc4d0e3cd81ba6f063ebf2d859370f20000000000000000000000000000000007cc705dbfb5c0418beb1cfbd864fa0631bd60eccfdb16b5d55b6ef3558e2ec87dac3b45294dcf04a064d6d1eba5a6eb00000000000000000000000000000000052cb9c982e6b05c1d2ab4eed1d8082f96426b55615ebc6a53bdc320ccad0aad044395ed641b3176b554f19e62d46b73", "Name": "matter_fp2_to_g2_3", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019a9630cce5181fd0ad80677ed5ad8cd8bce3f284cd529175902b78ad4915f0df56f0d8b37c87c9ddb23d0342005f1570000000000000000000000000000000002cdd00b7662569c9f74553a7d0585312a776c8638e54ad016f8d9d25df98651789470b12ce2626fb3ad1373744387ac", "Expected": "0000000000000000000000000000000015ad9155037e03898cb3b706f7105e39d413ff3a5abb65812b8d21d003cab8fbb607d3938ccd6a774bc8debfa30f42760000000000000000000000000000000019d6382bb2d78180a8998a0536d67412d00ec0ef65f4cbce01340b8d6e781c0ff790296f8cada28966b147c69e02f366000000000000000000000000000000001290c2c205b748069d0875a89ca74a3b05ad8218ed46a1570696932302983c090d96e17e0b828a666fdfc3b72cd348bc000000000000000000000000000000000114f2f7ffaa9f90b547e86c863a5d3585819a78b095848dfa39576a10874a905488687b73e613f3d426510f5d1d1ce1", "Name": "matter_fp2_to_g2_4", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e63c4d12a38837354bbcdf4f844e5dfe727ebe292016748007d162e74c1f849787767f7e77fc57a42783fe0b06c24c80000000000000000000000000000000008d879e4891a891f2e7d27eb95aef70d5b785b796620ec43dfbb6ae550b4effb9f24210dc20f401d54420445e21cfdd3", "Expected": "0000000000000000000000000000000012084a53cde353a46af17cd2fb02c477e47b874d8ff58025b5015837759032ff98013dc5bf01253bb964f035183c9071000000000000000000000000000000001659272ab7e3a070a5c7b25a5d3402f7371ed67e58cac8438df41c39c1acd95ac5886b030384bf537d7c4bb8ddb2c538000000000000000000000000000000000852ddcc37a09a0a8f62dfbd1ba5064c1f6afacc9a279a4d998bed643eec5a0d96d6bad95701a04f52c83e8f87f48d5d00000000000000000000000000000000097a399370875398028d42bde8cf4e9641730af7a2971e2f59c95938120603a239c65030ded4323c955f7fd24bebf31b", "Name": "matter_fp2_to_g2_5", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000028d6de947a3958af5b53578b0ceacc7ef89d36526d8f3b6fbe787af69fed2c85cad3001643b81c575a741c4566e617e00000000000000000000000000000000182b56202f0494bd8baf5c03969288a1288b8ed8e6c7f49ec9f7493ee3369eeb42fa8f5fb7b243fb2bcee6be244f02be", "Expected": "0000000000000000000000000000000006f8191123f1e8f6a05e4e663fa763c8a0ade5de3c7cd38ec1c82e1c85f123ab51fffcebd677afec8e9adecd8d11263d0000000000000000000000000000000004fcd825bc55d044eb70e0bdd5ea2ac58ec1487e903b431c57a640c756265a382581b8450fb15dc649cf22a8539088220000000000000000000000000000000015259f83d76490bb868bb88c2a2c3e07a326bd3e97fc2f552adf85722a360a443d720c328076e35224328e09494746e0000000000000000000000000000000000f76b0b960a1343b4267f5aff44901fd6796a778b1a87666b95b773edd0e7ffb6656d4f0cc3b9b38bc6c0ed20cfce153", "Name": "matter_fp2_to_g2_6", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016adb5935f32bafcccb81cf4d177dd8826013d85e11a4aad66e3aa596e1183aeb9d68eb8cf5b716a8a9445ea81b40d7a0000000000000000000000000000000018bee24b0c97af8aec210f15bbb6acbb76168dabe16e669d5558d8d32f00fdf5146471922fa98a28f238974d327996a3", "Expected": "0000000000000000000000000000000018bf5f93dbc2c37479b819f8edccd687c4d3c4dd04f8c73762fd89d0c003674e3b2ed749d23e775f925279b3112689f80000000000000000000000000000000008a033b197aa8ea2213dbd7ed478d98c25dc6e9f91b9924f3c14124da26a67bb196926e02da89b746f2a67b14ad226070000000000000000000000000000000006f7824bdc9c53212609512858278f79d9b094165ff178e3da8776e24311bebbd9deb29f366d4c7693a15c34df118403000000000000000000000000000000000edde25fc24b9ec58b3c317aa3ae48dd5fecdf6397ed9636ea042722d264db0b1a89a15a1e16e892755730ef52796527", "Name": "matter_fp2_to_g2_7", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000114285411713eafd395ee43bf1728f52d17ac512b9d0cddd38c904a9a3a1b30283a3918cd2cc3da6a7d6b4ff923cbb6e0000000000000000000000000000000018a067f91f94b2904c5bb6900f427ec4e93374b5079c84707feabeabde20b5e49801f1f3c7504dd27da94d5e754df4ad", "Expected": "0000000000000000000000000000000002d28025f4b798083aec3ca9a91a051ce27a374b115c944932026b4fe0dcf68b335d5e47212f800c241c2d42fd219635000000000000000000000000000000001742fb6ef8e9a5a7572b0d3fa4ae8ae56c9c6f4daa20d0b88212c40511c6f6b5ee98314a2d1cbe4bbbec907495a1ade8000000000000000000000000000000000d700a511a58c1b8f11153669cb21d88512dfdacbabe38e402431b4f7ba374b5f9a88614da2d56799d39324e9d19e27a000000000000000000000000000000000c6068bc7a43d614b8f1132b13e04f66d2fb5ac0c5bc8501b754a0bcf4f382db92b0994c4999e104c9d1111ef91d5edc", "Name": "matter_fp2_to_g2_8", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000dafa9fa843879038fd1566c319c24119989090c5fd34f6514e57f633d3709f0aa9954dfb289843a6990588e337b63e6000000000000000000000000000000001742a98dd7d3671c2c64aa71023a0040e936fd726c062d520626113bed471e53ff3e85737e5abf9ee8821bae53135f20", "Expected": "000000000000000000000000000000001350c68434a9b02392e60540a3985bae8daf9a170b30336ac73afae6f892c7ae8f5f1cadfb2780d6e5961ebf91cd69ee0000000000000000000000000000000000c20bd286fc1886b9b28dfa40d1a27395cf76a8b73946849ea0a7b5e12530de13c16acef8fe2a2c247ea65ca023eed70000000000000000000000000000000002d8ffd0235fb60fa573662034d46260e0c96396537b2a9d486dd03bdd13c5a1efd2d3cb9849ed11c4376b665f378226000000000000000000000000000000000d90ca1b73a6a9566832f9f19d8530a3b12f22bef853fc44088559b923ca108cebf4291e0d7de8f25c7429d455f5ae46", "Name": "matter_fp2_to_g2_9", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019cda532e5d94f3b193b3f286a038637a736c2b87b804efd4779359db5bd95320e06d6d28da3c229ae48ffc02303fab10000000000000000000000000000000018df89e4a545bfb825bcce2f4c25f2416a72e32633b3dead5205c8b7d69c78f119d0e940e5bde9ae1cf91574e5d6c175", "Expected": "0000000000000000000000000000000013f223602e8d12c3bb51cd393f6f59beb5c55fe80c3fc8fb0bc90eca533d9b7981563a30ebd727ab6cf0111fa2d3099d000000000000000000000000000000000962b0585c681894cb701f17ec06c0c240899db574c02d82d85ed4dabd4b8654c29b84c71d2921986fc2abc542a3ed9f0000000000000000000000000000000000f0e79245e645a6e3fb88b9103ede3e6ecdd7e45d61b5755d7a8d100d80719746af58bb23d3068cee7389b2acf17f8b0000000000000000000000000000000017fa0aac84c58283f34b9bf713cde98c175b38e92503c08205350822d778f3dd5bed8051e185c495831a628aa89335c7", "Name": "matter_fp2_to_g2_10", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008ad60829ff001404da40923806e496640a90c5c258a41ef5912f8a1a20eab84ce43b2b5aa4aa7dc4d8b281591d235020000000000000000000000000000000000f13dfef4b3b83aa7f9525eae9913e10502e77c03c55a7aa2de083dc5102c098b6f8e36cb5247b827e30fbcded9e2d3", "Expected": "000000000000000000000000000000001062c97c214b86518660c5e1c33a4e48923ae89ab7d8bc5c798e631de16fc1f104aa957d3e7915aee8551e24aaafc8e6000000000000000000000000000000000e42b785f17f25b87a0dc558a8d57b19d8f41767c3b4fd70c147e95443aff2d9a743003da41d578a2b56d7dc748cf59500000000000000000000000000000000111fd38cd2f5f681bb37f6239a5eea820ce3f01023c685f8e7e244fe9aa9dcbd18f0e50705faa5d8d66b28af9f371c630000000000000000000000000000000004726d3e452f6fcb180ce1d50bbee3a23f7949b635a058f12de1cf5abda19c042168feea53211dbed0bfca489a020930", "Name": "matter_fp2_to_g2_11", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010468e5421a72ec85b63f7f3070a949223105763868111424fd151c8365eb0307dbc9cbc92e5dfb296d06ddfb58d99000000000000000000000000000000000008149ce856d489050ea834452bc66f7f3478c2056969354dca8652f3d0a349e40fae0c4c57ff0f5e022aa93c61f8c844", "Expected": "000000000000000000000000000000001211bb8d3bf65b60efc7237ffecddb4e7e2f0dd36e2a704dfc9f4972897addff1a57182f8e0a0ac08c9af2c98eaa4c560000000000000000000000000000000007e9877280aad45a3b1453b6771ab509e4f53937cc6da73d3add50aff94869b27f49218fb479fe19a6176b9aadd36e35000000000000000000000000000000000ff915801695a281f6642751be77155a813847ae0237d77d2edf836aebac02b659b98d49842d4d10e82d9d146e63a3da000000000000000000000000000000000fae1c8c01a2dd94f17c660353d158ff6f3eed4e6375f1e414ade9d6fd040a48e3ff0d558c882e92e74bd6ef4ab06168", "Name": "matter_fp2_to_g2_12", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006295de7bfec61f06a56fe09afbb74be968329e88ba2e87afffe9ea9bf646ff5b4a03d6088e87644958ced95eceeea08000000000000000000000000000000001443e61dbf14b6c6ed99e1917ecfbe5a4a23ab9bdd3bb089fbba76d795d715d9d2e3c7d8db0b7a9434ad691b68bad3b2", "Expected": "000000000000000000000000000000000dd00d9f31cb5148048125668286c1790cb7294e740df978ac0bdaa6e1c4ba139a04f5770b194c9bcfb123d9b40b6acb00000000000000000000000000000000085d5f4cb831720fa13cef25464a1ba7af33abcc4079d2c5736a219ad9649ebb5dbb8687a2d3952390866587d7088f72000000000000000000000000000000000de377d773e40e1c76e218b969297d15f7819c525ce39aee5114e8405bd7361116682cf9d673574d415a7016b23b567d0000000000000000000000000000000018db26c2097f72b8788ef5aad2d7aa400627e224924afea1ac7c7a6b5cff4a55255e218572614519a536eaaf0f65533c", "Name": "matter_fp2_to_g2_13", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b14b12ecaa94f9656be54772be9b22a2495d4ff873b0bb971c27ab1d8b940c84cabcf921f6f75e93942c38cddeb87500000000000000000000000000000000019eca0daafbfdcd3b56be863dceb21e624b22c0d376fb92ba606456ce3825981713b88e40b7fd801e915f97d5c29ba75", "Expected": "000000000000000000000000000000001853b4c4e6fcdbed29c5d3aa4a9f6d447adc512f66a32fdef06c6ad316c42eb3ca47ffe6f21318ad610d0a68673d7bc300000000000000000000000000000000123d15c37fa8b1a95229e28500c9a767e6286b780138dcff2714bf1f8242f39bebb7d86e2811551914719ca90fb5615f000000000000000000000000000000000537498c2ec64b2ba58aa0a858b69990cac544d5cac29abdf6a42ae9c04061f83580b79c2a6104ebc55939d9a2bc5ae2000000000000000000000000000000000b348c19aad3b67c690512f372d995555ee38bffcdaf33bb827160d6929d2ce598523880f6136f11e1d6482a654cb016", "Name": "matter_fp2_to_g2_14", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000104a452343a4098e9bf07380a8e52050259da95f5fc88f31511a08090bda85f0a08d49cef95bd26c7181aa3eb0be122200000000000000000000000000000000012400aaec3d2f4a1a8cf3f28fd396133c3999c074a565c110354472ae29479b9b62ab67128521c2c6ec4869811ba760", "Expected": "000000000000000000000000000000000994e7b6ccafc996f672c42ab491105ffe1482e65aeb456de2213b531889773ad4d5e6ea1687d6a1f13e74878766f11e000000000000000000000000000000000b89030486a1d622c97970ee7da6189ac341b9cafbb4081463f579ab8b4b049c6e6c8b63157455770a79108424a14f24000000000000000000000000000000000ded43800a991f8c37282d803a39941d3bfbfbdc56dbf7500ef3d16750b27dcb1ad93f89714395fd3dffe318c1771375000000000000000000000000000000001994144b032e1f8c4d688754eef82cdba0018ac47030fcb77e8fd920e0b0336255d2cc8376c03e1074f91269cd2519d1", "Name": "matter_fp2_to_g2_15", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000093e04bfcbd77bc6bafeb77f02d0f794a20b155435ee3af1d667c025e7645d9387abe0ef281386339f461352da93fbe2000000000000000000000000000000000481ffec570d4e155ec10e0cc58effe7a5651795d604cfda6cdbf011676772fdce2c25227e7d5a1a26748d15b1668091", "Expected": "00000000000000000000000000000000195d99406baadc7d8740962cbbf4bc1f22b08eafb52f3cb3c588b6cb3cd89d16cb7b8d388563289f5b5ea466128525c80000000000000000000000000000000004809f70463633595dd763d658354df4f9b409911e1a0328fdaf486d76ffb410d7c6cfcc2d48fd6757d5c2a4834f81fd000000000000000000000000000000000654f8475562098a2cb27ce224674a383283cde35173e1c16b141998b641ac9ee663d766f045451a7f6d600973f0ec520000000000000000000000000000000013bac451a44982c7b1aaac7522dab598cb79b9a3dab77f4d5a4c1c97c154451499979af1f86ced8ce2099bccd400420d", "Name": "matter_fp2_to_g2_16", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013a3c5dd40f7d7fbba7563331917fe19a093d5d25ae7993200c39460e0c46d839e3958b672b4ed195300f398137faa18000000000000000000000000000000000255bc4d313fbd61a270dce8c851f1fa09e6ac5dff9b9e8dfc8a236a1d44548cb079023ee9b8f0f5756b39e44489c3f1", "Expected": "0000000000000000000000000000000016ea88d0bce32981f489438df1bc14e7ade7a45d449ee1ac1a041c1204460cf53ae5c0e111914d8af9e6b3b7fa394484000000000000000000000000000000000db571ca6a55bc8285421553a373048f7877ecb9683d52acf07d48e1026795993e4e7177490921bc6fe1e63d69c2de3c0000000000000000000000000000000011602919de1df6cc0dd36a59c84ebb8e209056534e336f5074c9ae5323f8a03b123dc6354cf85301d838b16518ab64390000000000000000000000000000000004407d30fbd632fd493055bd4d8cbed337767a2ac534411a3eabec570ba41d2ad28ef37512a7da3611ad60b6536b3f07", "Name": "matter_fp2_to_g2_17", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ab7b4dec955de92224b234c2d8bb2e3881806c2d36a9a21036e9412f0a8d3946027cbb65b5dd9c975e01b3f235b883f000000000000000000000000000000000ffbb55002d9e926b3d8e7d963ece82c14afaca8b4d8415df8f964a39db606ac99f9e442ff69f7ddbbc4ae563b836192", "Expected": "000000000000000000000000000000000c1e7b188697aa9a053f14e2d907f2c61a59e0b0c72f9cce30faf81dc714a50113500ca9bc3af6657a5d214f52c90616000000000000000000000000000000001544c35d712eaf79d8dd5a22fbab72f8a6843728898412a7f305b205f8a50e03c6c462b87b3ac165e9e6428e0a44a74a00000000000000000000000000000000029ebafd90a1a887669fd0ace762a66bca2bf0a216333b0ac97dedb6bff3dda2bca1e3d0ed5fa9081c2887fe6a8e24cf000000000000000000000000000000000e1a01ca93ed268e0291a937483f7f8e252c91f9bd8bde55271b0c97fcbbb9219009514217dd8bd7e0267f44e9927a93", "Name": "matter_fp2_to_g2_18", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000103469c08562f6f72152db58b48811b0098b68af8de00e652bd5a67246459664cc8c54e15705d702d51e3f1d8ff76a7700000000000000000000000000000000059b326dd567fb2f8a6ae87f41fb22b3edc25122138a5f6732edb48ed7fa1949eda6144297f54faf406d873a016a1510", "Expected": "0000000000000000000000000000000004e8ad9838e7e269cddf0ae5c8f0f57e7467e0b6f2b9e37e7c4bcae965e9582dc46c9c50aa01f5dc761bf2f1ad311eec0000000000000000000000000000000011b1438ccc668900914578c3ec6e1334d0823861c892608817498fe2e538deec73e0034a6e8ba9790f63fdd95af3714a0000000000000000000000000000000005b4c88196425d3ecd22bfc0cb1a95488493f85bb74f50315f0ffcdd57ad2de23c137cd6d2f6f6dca8af2e3f7bb0539c0000000000000000000000000000000017066344a0f345ecf6a2ba66c37ccbce26a3f551524f74636d4c4812bf5adfabffb0645b898b10c332e94e5f2ae2d1c2", "Name": "matter_fp2_to_g2_19", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bd594d2f5e1472f85bfd550df3eb948085781459eb3037fab34186ad9a0204a0767c8fba571af858a054dc231931b8000000000000000000000000000000000087b8398406c1e707fe87a16118e2448d6a5f4fd1d6c9d7174c4d8a4314fc7b2c21f04178533480976dd20e28b278ad5", "Expected": "0000000000000000000000000000000010d393bf893d589c578df58f4d0098ad3cd10d3a1d0f112f51b132a369e68c0284a6b70a5673383ae24a27a9043b16cf0000000000000000000000000000000003402afb77b187b45906d9cce348976ed88c758d75b9962a53352a6c3ee37751a9928097c0d68c6f8a315def4ca875200000000000000000000000000000000019b98631e53a3ffda3fb9165ef7236dad5c0c8d57c3315617cbd3ce77430bd89b9e1d88a019042cae0075594514a5e67000000000000000000000000000000001783bf1c9b0ec44c9191dab01ef5bda0cb2f533dbcd3aeac2b7c6720dbc8e3f770a215ec8ea2035129711ce4b448ba87", "Name": "matter_fp2_to_g2_20", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000673dface7041c3d7503ce4a50af946d344ad48327b515740b45276403d91bf1ef9deba79c8ffa0126be990b62bf3072000000000000000000000000000000000adb42b7eb0f6759a04da7b933bbc2b6aedde47da8571d6fa32268c606dbafcbc810844017eb6377493a12d76ca56c03", "Expected": "00000000000000000000000000000000086ac901098212acd091d9c4d42a1318c3b343480f1130d6e52128d61df9e19fb61ef1ff35de0ef60062cd99202910ff0000000000000000000000000000000019109b7292f1a420f09a56dce9694cb4944808a2ce9f1964cbb6ffd14a710c35abe81300090ffcd9e95f33e0de9f879a0000000000000000000000000000000012660c4e114a215390c6f6eabc4bd6e3d062ee28d0c87e24351c7d43195253cb7b5bcfed2b4abb2fdeb3ac04ee228997000000000000000000000000000000000e56d35a7e40a86ffd2088c81488265ecc4468d6cf02d563c91611cdf8b4333cf66ef50b993fe651b1792d2b242cff94", "Name": "matter_fp2_to_g2_21", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f554e52c4a6c5a94fd09c617f57e8f87af57e73ceaee8997fc62c8ddcb2f875ee805e6594a0fb72738abd3cd4748ddb000000000000000000000000000000001876dd03316ff007a2efb4c5f452d8418edacc2881b20e8340895f6fc768d14fd89bd9db3dcfb53fa98a1e96055fa83e", "Expected": "00000000000000000000000000000000071d3e796fb15d63c2d5cf68f59f11792b0b580b85c8839a02fad96664f14735ede2edfd5ba5b64045b366904f54ab600000000000000000000000000000000013fd1ea38d32772458622731b9e2d9d749f2b747443f7e47ef5e041531b56f86d1775d42a548b2bb201228f49ec9f46800000000000000000000000000000000099c2bd996c8c5ee37de971e8b75a0bdd4f69299778ee3d216973c9dbba97c7a93e40b209d390024bc4b5e82560a1a83000000000000000000000000000000000c4922ed9af845467440b78efa3a53ba904f29adf66e8ac437c8bb6624b5e5ba0772a5639b45fe167b1fb9283747c50f", "Name": "matter_fp2_to_g2_22", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e8b2369fc2c584d78d52037b109aecc87dea0eefc2da46948b5535ad19c9abdb31aee66739f4852a2d3c51f2e7f74e900000000000000000000000000000000168b2d3e4b67390cb8ba5e48a7a823db08edee7d8eff41b88cd653cec1fc0df7a55303d3c91e92a2dc8ebdb327b225fe", "Expected": "000000000000000000000000000000000e413d72fdc3db6fc79ef26ae8b37fe5c4356a80b3598513b5173b3406ffb54708b8794dae158060a1accbe956a39ff30000000000000000000000000000000019ba9dfa74fd241a55a3b47c9f37c6ebd1e8b51f46197881abb64b7f57c0e2d8f18edee35bb9da03702c0dc5cc8749f700000000000000000000000000000000183525156fbc80cc67d6cd15fd2ddf7fb0528656ec1d31b4c275ef101dbb635424abbff1154a3ee04346ac53148fb1f70000000000000000000000000000000011da0dcd666d01180902d8a7fd7d2fbb39f9c7587540451045956108a8579d7c116385a81627dad9d4cb8cfe68927b6d", "Name": "matter_fp2_to_g2_23", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016cf7b1a9ebafbd20c078948fc974bcca9b8069edc1ca5e8f364f8ca2a52e56e1a424ea6bcc4240f46dc7f262760bf480000000000000000000000000000000011a6a67d4501a8d9b3ab985be59ffc41e79c453bb5548299abff3b83ba9ff951025a68fe6a8ad3eef3c02d39fca8f909", "Expected": "000000000000000000000000000000001932acb1fd0708edf13c293007a035991bdfbfe0089b61c261258e8c5c10d82a5318b2af221b372f0f3f43c391421582000000000000000000000000000000000973650743f0ec8e2acca33f2ef230ee7a05635d14099cdce913ad8678458ec0dde5c5a941097af2ee0c8ffb937d09fd000000000000000000000000000000000bdaf319044101ee9aa27b3accd36a5ecaf8b80deda4548377ddeb97283537be3f7199ad3c190ed23cdb44abb8786a080000000000000000000000000000000006c448827e3fe4f274bfa55a66bc76c5b01e29ac6a8dbebd801855ba4e93bcbd03292ccf804f07f21481260c135b827b", "Name": "matter_fp2_to_g2_24", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010e53fe9fa94ca622cfa370129c1619b2426bd9d50f4b5eb8a3f681479128dbe92adde15477ad8a4463b08f1a02a62d50000000000000000000000000000000014d10a90709789b25369f0376f39b16860aee1ddc3a4340542abff0077a4af8da946cc29fb6afd9930b872ea98749be5", "Expected": "0000000000000000000000000000000004aee050b0ea07118d76f835218b77b39854f5ababc4e2a29d7c8cc7c18a69c30bb22437049a051d049c8a84f7868ad40000000000000000000000000000000003b1b809d5046054924c3814d26fd5fbdc59e03e5505813bab73bc212b0f5bc0d3fc34478311c5e1ac70fd16a01c52800000000000000000000000000000000002249a026af0b49f4659eca2c23dc790fb36a7b2996188828a17d5852003f1420f11699062932835cfe6543d454521e30000000000000000000000000000000008217aea2221f8748cd81cd37777605a95a63aba36a6ddad72c1e1ac57b24d79ff9d9c4ed71a6e3ac8a378129d5475ad", "Name": "matter_fp2_to_g2_25", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000194612afb777e39d0308a290bf823fe706487c3473412d1410dcb2c0016a70706e70e3a009c0bd61e755b1e4c65bcad0000000000000000000000000000000000ade016d06179faa8d44a9ee2542058bb81724d6af2954c0c09a897703d364ec25e62a3a917c5cecce5c96a7cfba924a", "Expected": "000000000000000000000000000000001274f676bcc05e54fa4b0cce234870ba97a0b1626543d6a9f09afebd5a752769000df404e4d434ebfd561f8335f36d0d0000000000000000000000000000000002877c9438fa319dd1a00f381834e8f3d3cdebf4e1f7690cb82559a2e978bedfd2455be020d0353aa56d435c0174b5b10000000000000000000000000000000009487cc9c7a09be901673cb1bd9a51f45e5d2ed30c90cbdd3e2b294c8f866f68da55533b78152e9ef6de30c345fde5b7000000000000000000000000000000000a3a8d4aabdb260203898655745cb695e6dc90c6e7bf0248784f8aa2340390fd5d8f1c6a98eb1990eb97c2a7f103e3fe", "Name": "matter_fp2_to_g2_26", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005aaeba19cb0baff9a8e46b901f15735a0c1f45116fe1f41c22fbe1aba22c0a7678bd4799db5cd9141f3112877e2c5f80000000000000000000000000000000003f54664746a5bc6f64021e2f18d8c175d96b1c8ce895809c0e6fcfbe896b3e8c1ac7f7556b9ef953371bb143bfbdafa", "Expected": "000000000000000000000000000000000ef415dfc1e47f39e9632ed21c9c2bfcc1959299710dcd7935a757e3756a42c8f6c627c720fd62f9c486a8e88a64c76d00000000000000000000000000000000088079108fe7d9ac93590c045be0d41396f3204d83793c4e862c5360ddb3268a63f704a9d14323943fc85874cdadaff1000000000000000000000000000000000cce908e8dbb7ec35820f2db5ae1174e0f675b21ae416fc89a7f242df3ee98764022744842999f65132229156d2627370000000000000000000000000000000011e0e2f8513d0a71b48599139a9a29c8eca090c5b02292baba58e07b1d3898fe158cdeb3bbe8edb4a805e695e896984a", "Name": "matter_fp2_to_g2_27", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010ca243fcabbdb219c5b30092d9d4595a4b8ad1cbed267229eb79a99aef9c5df03d8f24b71db77a5a76917c2fd960ffe00000000000000000000000000000000135d8d92f075c219f8012ce6aebc8e48443b2f33382479a4ca8db0a4f92041d5b6b1e5818b7a3de77a5d30be0e461d13", "Expected": "0000000000000000000000000000000007c6f133647745c312695439f1d8c251e941bad6e988cfe324ec7c959a9e0fb50618984429ff1841d4286922a26873170000000000000000000000000000000008edb220f77ed17fa1f4757a42ec66ad808c1acc25c4b9311be4c09703d547f648d9dd7c8109ffa89d01a35c69ec2685000000000000000000000000000000001595cc05b04f557ed569b19d64c09f4d82e6617437571fddd72a672d07ad94bfbaaed906b3a7e3db519159ec8d0a8c4400000000000000000000000000000000041157d4f40bfcef680af0143ccdd0c4bdd25e598a470dae844d887c398bc498edad715fd7383421fc78758cc9b00326", "Name": "matter_fp2_to_g2_28", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013e042ccfe0cbb7fa3b045a1fa1a86f199ae91721aaed488b96cc4f6de1899402f81842da2ab55c5bfa63f5b19ddce7300000000000000000000000000000000063cee89d1981f27a4f4d4f23c4d1229fd3333fc8f371ebd85c588e751307ccc75d71d151f7481ecba1ef0cffbfdea5b", "Expected": "000000000000000000000000000000000f983607a6d8a5c3b8a577cbd5d81ad2ae936e714199e3f4095cf280b8fd6d3699acf4d2ef251a571dd1ef4ba6d838bc00000000000000000000000000000000048c12f8b95f9537e56479b1bc43a121e4edfb6477fcb090a5ea60c5f4d01071776dd0264b0250902448f62800f4d2ea000000000000000000000000000000001644ba272d7003d0077991ccb4569638de0dcc48fd2e8e9a41cee1d2200aee1a849f2d620f60beeb06b08c31cd4eeacc0000000000000000000000000000000018892d773f7e48247215484ca0c8d996833c43a5291b0380c97607c86f4ab2784e692673a1da012ac4fec2713d156a49", "Name": "matter_fp2_to_g2_29", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e07265d2762e8e398c83efe1c43452d91b90b7a4271c09ff693c83745a6c01b73561ffe3da9300c8e7e1602dbaab0bc000000000000000000000000000000000375579c16a167fd9f9f61d5177705f157aa0df3451971029a9444432db119fb33b8c07de33fc822eab46ed4ae47cf82", "Expected": "000000000000000000000000000000000a06ea8e644d2d762520ad956d41ac2086a588450bc34f6d070b86fdfd73cd0734341a751d823935a009b7517770f86e00000000000000000000000000000000140ef0d6a0482537da7db8d775ac3c4a93b16c15fbe4602b5b1843ce757aada5f7776a74151d0bcf760f7284d4ffe56c000000000000000000000000000000000873c90f56a2b99da2f0a1528b8e376a5912f9cd81a159379ad70b7c10e6ebb7fea0a90d65543d968a34ebd539372e89000000000000000000000000000000000b05ff57079386e4e18e73cbff5f7b0efa329ef7355f083e8be258922203240dbb8926f7d11c22ab4c16d1df4bcbb600", "Name": "matter_fp2_to_g2_30", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aaa37576af2101d090139f562edc2a6e7169b0150af831d053a3a87a3a5518889a51871e02deb3ec154ccbe9dda46df00000000000000000000000000000000158edaeb58b99d9442d608bc8e6024365e9a81e0aa23bbbd466c9ccc8d29415352a153e1f852666505ef097122592ecb", "Expected": "000000000000000000000000000000000e9d6f9e83a2584f2cdacc4711085bd251e060f8c87ff7538ce474d663c6f23361c88971c9da589586e754ed69699c820000000000000000000000000000000003fa90cc1dd81b815704e15c0448bd0e8e8d0cd7ad51237a25d4b8a0f78f532b18ec30a108930b7407b7486aad9824de0000000000000000000000000000000000cb97bce1f75b1df5a4b52745014eb632d2d2230e52a9767e3dfd76754e98252ca81ce274b92a2947f6a65fedbaa3e400000000000000000000000000000000090edabb37f411fae1764792083c8c7412fb470833a9f7399fb312c58687d4afbdc622ecf9d74cdfa3ea87382adcdd5f", "Name": "matter_fp2_to_g2_31", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012bfaf34a8111a01d213f9a9fc90846335cda978b3df23de99cb7b764cf5db1a816f66adad1319aa7e25c0ab89e7de740000000000000000000000000000000000fed118654a128735fd39ffd3b381ad2d71479054b6bccc04dd58fbeed9b255ce2b925e2141a96a12edc3a19188d1f5", "Expected": "000000000000000000000000000000000cd234fcc729a4206233e46875a557027cb52c96322386b56d6e50d95dd9d23b6f8936ddc6f8475b1076a855c1ae23510000000000000000000000000000000010a774120f607bf9ad2d7bc498536cc9d35cefe384f88a2439a75f1a4f6a9e4b4253daff0d2c91b5915ee0e9a99b4582000000000000000000000000000000001496e7181495114abc0314f580c16038a04a8dab43b5564d518dba5f5e48112ce9daca4b16b6ad51c3af54ec9ce915d20000000000000000000000000000000002c61691a96a2120663c726d7fba3ed37524b58c92a024c15fccc659d1d2cdce077ba233a0d4419a6f237ee4e09abf52", "Name": "matter_fp2_to_g2_32", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b693fe53cbcd6f8d8c98900be1f9c85966cc644f0a900c70826c6573ee801ce7863a0b170ce0ef168fb1f0ea484b276000000000000000000000000000000000c6bd688fb883f3097f8b6fd6fd0bc5acef9341f21d62a0706fb3625a70459c45a5200ee36a3802d4bb4912030bfcfc7", "Expected": "00000000000000000000000000000000011cd454f16209b0b7040c744291f2df465ebc786946ce3cde77fe4d4bcc4b60a51573c45b8bb2d209da69107613764b0000000000000000000000000000000018a026f29fc2f81e82015ef8610b4396f2e3514ab1a213356953804d585c5cd6a3c5cffbf70d63d9dfca50129021f0e60000000000000000000000000000000015bdcc8c139e636b05ba7376c1ced4a183eb465df53b1996f4ddc8cbf42cdff4ae2bbc2d24831a8ec8b1134cff4444ee0000000000000000000000000000000017671fc3995babcd2c0a1d2a71c417fea84e29df67fa1096fe6d3ec77c45b64fb8da6ed08a57726ab314fb860899961d", "Name": "matter_fp2_to_g2_33", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ba7f82549ebfdc7f4959dc67cebde4720d76d5d4742af730d45d614133f0a7b0ae7b61ba5b914a997d9dde83b77b031000000000000000000000000000000000b4acd8c203ebd8e3ce12b10cc791b9a4183440309f24bbd60cb2991712c792ecac64d3f878cbe407fa8ca0d09548acb", "Expected": "00000000000000000000000000000000156d8823c37c81d8f03c0b2e61a2342aab6e6c9db36cadc9eb741e085de711e9fda08ca78f21753c4fdd8cec059b6c2800000000000000000000000000000000064d4fc2584c78f1e92f808d4457070b0470eb8de9d558885bba8b03efd8d8e195e4923d8e3382481a0ecee905371ae10000000000000000000000000000000008f1dc4d2ba12e7e3e1b0ef3855df4dbf29468bc99d5cb29fa3058a535af2ba038396bccaa238bba6d538498565c2809000000000000000000000000000000000fc9839b6ee876f7846b5086d487360b8faf133b6f5bd2dbc92a7fe2261b91b15aef8d90c227cd5f8ec05e32d807e022", "Name": "matter_fp2_to_g2_34", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000145f6f774d943a1bb753d5d4876b1a88a4021cb6a6607c0efb07eef2f90ba2a90a6e9dc94586de35f6047332553ce7b5000000000000000000000000000000000b892f1c8d001c8aeddf845c3845c51f2e06c3c77e543e9721d797951b6211a869da97325b569e0de35cf3beda853ac2", "Expected": "000000000000000000000000000000000d40f1c25dd57e36ed305276d4505cb250d2d9da0d5b954fe5e396b2c17a5399613243216586cedb19340e80f898873800000000000000000000000000000000063367c4a622fc925319fc6d119d8592f40f126ae05eed86ee5e4f6707b1d234c747e698c40f292dcb82ac5fe74ea80c00000000000000000000000000000000199ddbb5d4b6cd0fb9225a72c53f4596cf2597de63da56f4a9a18be8321a982de17367b0f3d794fa799657dd8ca10c5f000000000000000000000000000000000f1ed84e4fd958547d40cd2dbf16e2da4cb6d0d02763441067221890ae27ea1f689c26c900b695464ededf083667146d", "Name": "matter_fp2_to_g2_35", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001878e791993186ab76f785b2c6b0fe08588b048007c66fc00c695b55bd17b37bdba71f34ddf75ac441a0c2687711b2990000000000000000000000000000000016598f630f72a0e1f39678e1d0ec6530c4795d7565c5d026fea2389ec0ceb51b434b532466fbb1c92c1c958041283baf", "Expected": "000000000000000000000000000000000ee446310185ce76e31c13e4ca6c43166d971d9b9c539c7d0e8dd8ebbbdd9249922cb674bf6ad6840c203a5e208911fc00000000000000000000000000000000037344752896cff03bc39a9d09757a83c15fbd90f8bc1d8d58dca9b23bc00fa2b0f3f0bd7c9ed857d285825d40afde450000000000000000000000000000000003ef77f0220d1caa7538ecaef1ae2924ac1a180f11004034fc118aeac464fe1ce684b5fc90dae3370e3f79619889f3d7000000000000000000000000000000000fdfa434e7bedec071a1a333088d06299f55735f085a1e907a1c71c312bbb8d27ffa7de7ac69d421ebd675c4afd37594", "Name": "matter_fp2_to_g2_36", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000134725b4d43cb87d2e4d3c43ca98b8df257acfa612ccd61dc0aa1ca749f20bd42c38d933d39f8c3c1a14dd8fec43329200000000000000000000000000000000070ad61a7f5ff9f0b4e7483f5d56b0f315b5f6545b194565ebcf8f0b8d78519ec113af6d70550888be4d661a8403a036", "Expected": "0000000000000000000000000000000000ac465de3832452edcead434729be73be90785158617b5ec3ad53b12653e43721eda7de6742dc51d4d4bb58a291999f00000000000000000000000000000000147c39a5c162afa1f8eef400cfa1bdbe5436bc59d93973f50384022962f828ac934a4f88ab7c3d505b0bc3bb002f5efe00000000000000000000000000000000141bcdad53845a7eb2ec08189a55445059dad24ae5d39fedce869791aa28459f05a6cdf9575676cc6f3dd7d6faf077240000000000000000000000000000000010e9f539a9ced860661472f53147d0347927f065ec09bc32e00c5bc157b07f8b41b05aa4e0eedd1f73c7a287b2d0e5ab", "Name": "matter_fp2_to_g2_37", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000179bc843fecfe713f6e3ccdc8ca0f48759459b675c8b96f5403e1f6da92c2d60449638f564ce179373bce473669965d700000000000000000000000000000000082bd89b49aa62c94ecd4244b3077421569c71efccc62aed3d4bd492bdfe57c0d2cced568df5992a196a7b71bcbe5e3e", "Expected": "0000000000000000000000000000000016479eca30f48bfdaba4c8afca63ddbf59fe3367b2d3c17d15a5869dd2956fc67ebde964530926598cdcb62cfc993d32000000000000000000000000000000000650b4fd24ffbb953ccdb1b112799149d29e2377ee233b9ac97f4db432da63c98b8aad751f6060d04fe1f9262b75fca50000000000000000000000000000000004568dc0b9b430596f2fa59291ea6f923d552683ab9ab93000788145cd7c468c5576efd981c9ecee2ee0c16eca1ecdbe00000000000000000000000000000000154af1490463930d6b8261aa1d066eeda6d65b742cb53c65348e5cd766d86982a1489ad191d1b126233f193d24823b9c", "Name": "matter_fp2_to_g2_38", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fb118c86e974734fc434c3bcb783e4a7f9251d9fcfb9f4419529354c8a7a3d9f2215de2d1b9f0927b185c5b4db838b60000000000000000000000000000000004da0ce78f3068bebd0a59bc2e41e7ade737375f07d6c9ce962be022856c569a33e8bd6ae60c4bb1b53b3ffc2dcc2aee", "Expected": "0000000000000000000000000000000000df692ca763a74877352af3609c8cdbc184eb71bd35fd86334cb88543637b40b3adbb5802dcd7b88f4d722b566aba7700000000000000000000000000000000181495e709d1617f2d912f43487ad3920ac5f8e47395ec4b58bcf0b2d986c674a0c7838830a039bfb5bb59cd2fee2f5c000000000000000000000000000000000d20b482dd8aad583bd5d08ba9c61b3e954f022d48f9f4f62ddc9f5015ac71dab7d206b1d8b885d5e605519bd33d93a20000000000000000000000000000000010d3deccb9364ee386eb35c7117bab373a76d024627b8a031f96465d5f75b029fa992e29ad4a170c4473cd1df585429b", "Name": "matter_fp2_to_g2_39", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001f43b86ec24ad40552dc4874a632b4ff4663eeefe1a8c613a19a798a0ebe321a3d543e2df28277944a941b4586ac770000000000000000000000000000000000baaca6bc34feac790807b5eb5fd173c86c12803b76b50be59b2707df765bd10eb467effe34f8dc3e1e79df8a54fde38", "Expected": "000000000000000000000000000000000a007c914ed40c7f2719fc70def0d4752cbaa775cedae9365c5afb61a5e1a2854f9e1ce19af9fc85bfbfd2c33f5bf095000000000000000000000000000000000d85b0d173c25c2915fee429d2468a9eae01ba43c0f1a661f2ef83c1acd726865c00c40ccbc3aae306f93074e5e7858e000000000000000000000000000000000b3df302ec532c8100c121c9a3455392c713ec60de1f9572b040b0966f8ffb888e8cd768dcf6d63d4835a52d13a730c0000000000000000000000000000000001123c43dda8717d03fbc02fa53c4b1c9a931db6b274162cfb02ef5eec602bd8161dedc37c7f6217c8e82236f06e49e2e", "Name": "matter_fp2_to_g2_40", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005e4751707f3ea7bc7a74d80eff27a0d65cea0c3d2e793425e79cdb0c41e6ad0cfcdbb4de604637c41dbaf30a1e816e60000000000000000000000000000000008f69021794d93826f8207b96d49214b46dfb1778603634a9f5194e92481465702a8be1bc49a7bb57527fe6f963ae04d", "Expected": "0000000000000000000000000000000016d8d9b1b59a22fd830f88b9850576488f75672a87ccb766e52da77f187a8e66071130c7e71f86675f8379b2a8802c4b000000000000000000000000000000000aa4ca84aa23f01ec536ffa25c4b7a6c822f588bc75a4a72ed9237c0588ab892c8474a0f23afc7ff0dbc3b08f8e35b60000000000000000000000000000000001425e759e2537d9e5f0f356ff1d38128eff3a771fa661a839f7a8d0f548347438574ef7d592cd4273ef9b7269c9c5d7f0000000000000000000000000000000012cf1c67d1ce244ae22eec0bf4a400a0f356b9dd075d87a6e61941933872d7c0e42c1d238b2c1704d2cdb2df75169f39", "Name": "matter_fp2_to_g2_41", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000116988a869cf552b2440e16569d8b6e30c6b15430855c4d6bbf80683c5497291bac7999c1f8f08f494fcb4a989451c3b000000000000000000000000000000000e26058d72875fd3d852aa4139f71d35e1edb58242a4939da7986645117d027d20baf85770fc909d537524244da59ce7", "Expected": "0000000000000000000000000000000017f6e2743cb30fb93816d0dc802c24509315363c3652b0244e1395cb9200efb4d7b9fa7642e8d165d28a00740f1a83be000000000000000000000000000000001483644fffd3989ac98cea71843e87b8e446a3d497630419afe99b3f1729a831fa6a49bf763b0c410cfc5390ac4ac1db0000000000000000000000000000000018ad20ae5012266d771b2c86f891f498c2e90a7df19561be240319edc1fbfb316948fb3f8a6b0e3720676b076eb372e10000000000000000000000000000000012f404211899d8fc1221ab5b82db9042ad37e63348871e5ac6cdbddacda0a564888f89d22712069b6096b58c5935edd2", "Name": "matter_fp2_to_g2_42", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000078c6cf89561533810b583a88149586b29da5228ced10a75257b2587904217f63499d8b9ad2d536617247e12f8d1657d0000000000000000000000000000000005b016ede9d892fbd7aea4e8ed0f1eab70713557311481735a91308fabf76fe71e44a06dc23ea66ac5d831e982f401b1", "Expected": "000000000000000000000000000000000d4d78f992f12aefb0e3a6b18fbe2411108327a9befe4a822618fecca4def3169972b4f1fb254cc4656a676529d554ad00000000000000000000000000000000145ef33250240a5c9434d4b2cf2404d9e7cc51b55e482ebc6a8aed85caa21ed00623b3cb2d76ce2d96b2f346d395dfc40000000000000000000000000000000011af2ee2514c58078da335c0273cd18b98d1ac6f0e67890677403f71b0e06863fc72611c0cfba39ac894ae500edbdbae00000000000000000000000000000000186863e7c24cbeb45f7a66b5dddc9b57c7e22c5139aa6bdb82e77cd8182bb8d2fb7bddd7d3516b5422f92e08d02606b5", "Name": "matter_fp2_to_g2_43", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007160f36f0e5c4ccbcc7900c6504cd86fd6fd700bfa79af69841e4a6127eaad467ccc93c66baf7d767c3fdb1f31c527a00000000000000000000000000000000043fe62b0b9be76a375f3be0d6ec891d5bf5f2982cb2390125ff8d5db57b6b18c5616c526102e4f615963d601d13f122", "Expected": "0000000000000000000000000000000002af4a301e90c71eb375110e7fe23f8f05e2ede86b1a9b240e8d1d4d70e96f1dc3640fca7ebbcde9918deb91f3592de600000000000000000000000000000000058b5f36cfb6b0adb14b397dee4c3769c7446426eb5719aef4965cde2dcb70e6f2fa60101a5f03517c0040093453d092000000000000000000000000000000000f77b560469cd42c5cf3458ae13020c6678af3cddf9bc559372d12bc5d6b930795e1eb09f27cfdb8215f39fb2a11b30c0000000000000000000000000000000003308985946c742af7bd7d29abc2517ff1d225607b5f11fc66695cefabd8f25e294ebdb7339949d6bc4d98db19533966", "Name": "matter_fp2_to_g2_44", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b9590b1d0d292d9967d759060a551f4e8e4c1c0066a9a3c0be515085847fa26b77462e3bae9e2621f28e01f897df0be0000000000000000000000000000000006ee7c459bb4da96e87eb1d39bd7368de5f60104f85b7b4bcdd7761ce08d48babe1bf5e765282779803bfa972d0e668f", "Expected": "00000000000000000000000000000000093c936d57135b25900bd5dd55cd579aa8b85b9c1b5e8dac6196c4450b624734d9bfc3fda499cedf2e877d79f2da650b000000000000000000000000000000001832306d3ac1c1c61bdaa73c9b6e9c2ccb484c3baa1de6a217a2884c72b72618e864f75fcc2dfaca358181ecbd3347980000000000000000000000000000000002b2e5ff1ee02657fa88c7d6f23cd4c0465152a9daad8479b4b68c97930acb22e4e2eb0011ec4062b8ec46991a7cc630000000000000000000000000000000000712543547e9d24cc78d1c2e3fbe0b51222185f4c6e513256d1ee066ba50beee20321bfd60462e2587c375a0e9395715", "Name": "matter_fp2_to_g2_45", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000044612b42a2baa9d3e1d187b2a4e048773b4851bbd7d4025e0f7f61abee703b5a563397da4515c7379397dcde698228a00000000000000000000000000000000014cbff1000bc0f9b394b18e81124dc81f80e291e841dae6e96e0c86a6f618b9f6aa6103e0e7582e5136319a4dac92fb", "Expected": "000000000000000000000000000000000f52e2f8dff9a93b2985d5c2b8b980e4869af53ce55aa48bc1c9295e557e3b5ff78896e5e6342c2d535d18b11950bf390000000000000000000000000000000013d36cf2805d350c5b748e639d20e592deb4c5bcde99a94fb539dc56d48a862151b925314f21dce4c9130b32e44f54060000000000000000000000000000000017728f485d881b861f626c9de8b3df7d807b266de6cf8dfcba262f40a6248fb5e6506d11e88f460f0b5f1a1907ae5f3e000000000000000000000000000000000c0ab998f63f861c82106dc3ed5ea11a16e98139e8686f8442047a1cf9ac48c3d34b5129263767830144e9a13d4a1f44", "Name": "matter_fp2_to_g2_46", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013da827dd718d3736cfcec53f034d34bce253bc91f7cfd6cd2666819bdebbfc43a9363f82bf4b580a7739b5dda9c94360000000000000000000000000000000010e94039f37d218ad393e88a226dd324a37e8d5352dedf6d84fa2ed2cab2f874ccc5ce94599950f91b8dd6d6c8b84aba", "Expected": "0000000000000000000000000000000003463d887c4d0aaa21acaa308d77f2c7e13d10157efa9ec3fb1586a8db5ff1a9e807c91c86afc4df34c9fcf06e8561d700000000000000000000000000000000128a81efb9f30ed811ea3163c71b6a46ba2cbdbd3a9f93cb8d0f518747cc860431c6e93bdcdf36d00f83838965da4b50000000000000000000000000000000001777802b7c41111b38da3fd8092c280b4925827b2c1592f779a4ddca71f8268858855c413fd5c0057a652155261d75ba000000000000000000000000000000000c88b522d6dc2000cfbb7052e141ddfe15c6cd7fddc970edc4afc36fc59e7f8e31415706a8121e8e84348be0b50d0d88", "Name": "matter_fp2_to_g2_47", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000010416da7cfbed2768c77b80957053030d49d535b21a8a3297ab257dee0463c91b87a9e571b86bd874522149d9af0c2900000000000000000000000000000000197ef97f6d02a51b80e6f5629e88a3c60399bcc4a358ab103dac3a55a5877482558abed922585a1ce3228ffb507679b4", "Expected": "0000000000000000000000000000000014be96cfc0dbe09155ac8d8233b71ed584153e279b2b2be88471eb653aa4913fd2c33947547c61f7fd8bedbb552a8b1b00000000000000000000000000000000146b9a0011260e2646920894cf405bdebb101db12da7849b30868655fb5f972113cdf2fc322cc246d3dbd9f20b98fe2f00000000000000000000000000000000104bc20e104da5173dcff3e195f80960819a0d64e922bb484c2739c4b7c22535f7faeb1c85188aa853277740b389eac90000000000000000000000000000000019f5aec599f9ec286aefe48eedca3f929ac6c758c231182b92dc965d6ac1f3db53d93f57d733ca8425a5dde070b0dfa8", "Name": "matter_fp2_to_g2_48", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000025f1ac90f5b0748d57d8f7a928be875c5712801f70af0d057546228c1bf83d3a207884c0d66d0b5dbcaa736bfe0aa10000000000000000000000000000000017f66b472b36717ee0902d685c808bb5f190bbcb2c51d067f1cbec64669f10199a5868d7181dcec0498fcc71f5acaf79", "Expected": "0000000000000000000000000000000004ca0149527817b4df0f08acabd4e8c6329c0d1bd9f2e8211cbea25d69b84009ef158c770f948fd67e4609ccadc938680000000000000000000000000000000004101b351e2a9d34042291f38a289d8575872104bcf76f60bf888c60cca5101c34c247da30f7a8db4f0cf2f32abd302c00000000000000000000000000000000167e668de3207ddc60b8a5d5d246bf2f63ceae3bcbc4309e73eebf4d4234c2785bb13e4d5d8fff9c5f205e4fb942a2f6000000000000000000000000000000000491b965ed005065abdac53e3065781f2fd23f6159debc64f01c9f62073c651da33c05ed84617efcb5ffe08ce05e3b2c", "Name": "matter_fp2_to_g2_49", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f2dd27e3f0ab503a8752c0802ee14c655271e8cfbc734905b4331fb4e70cdfe291ff71053fbaf91680b1dd108f458f000000000000000000000000000000000c62014b7694a3e81370761e0adcc32430547a1bbe33746637e7762dc24f8d04b4bb955f17ca901659482c622d777642", "Expected": "000000000000000000000000000000001541320fb6f8a8c3c67278a7ad05ae7927d3555ad562bc8addb54c6693c51fb1c7355d2e74ff10f6bc3eb182d8f5b88b00000000000000000000000000000000172b65b110935b116ee683c8680ef0a660afdee43b9b8fce08ef3a70b352f8710c06b820348c338fb903a165cc5376da000000000000000000000000000000000df529b0e274e2e8993dd89ffef487aff23d31f502a19dd7d383de08fc77f1308a59ac5bf7cc899e81d377b2422187850000000000000000000000000000000010b40c9063d174b358637ab710d15c80d9230a1b3a056cfac4d583ad8c5b79c3d9bf22a1b0a4e0f629cd09ff7586f886", "Name": "matter_fp2_to_g2_50", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014d1491a45b4b0914a6cb2e4dc7de9d0962f5c175cd571057cae1e17d2c943954d119690ea14f5815f858d277a9ad828000000000000000000000000000000001650771e0f7b33d235f229b7d49a7a5a0f00f78e5f4abaa70f39ec452370198a8532b5873e41f17c449f9c565e6adea5", "Expected": "000000000000000000000000000000000978ff68d94d33703488298658cf2c1b6034d3d8d21c175d71a0545bc2f99eaaf131f061f3e4f55622668e686e691f53000000000000000000000000000000001124804b252f8187178435761897d00c43cf67b588ca69f97c20b0ffad3ed94acc2c0f85f900713dd6ee9f38e5ca94490000000000000000000000000000000010ca2a8ce71b9a096c132c4a060a17365475b6556d4fc6284266ae787e217b3ceaa3a32bdf751375eaf6ab49800132fd000000000000000000000000000000000a43b435b116d9480497f6b2e1bb377550cb1a7ad59e4214bffacd517afc6b7bf91112fe57b17a02a86876ea07361bca", "Name": "matter_fp2_to_g2_51", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aeb244909654b3e1df7cbeccf297223be57c2f514474edf0740dff48dcd5898b6e49eb65c787aa56ef79778249f4e07000000000000000000000000000000001007c89a66dab07f54313db8682f9e829baea229b030b4514d9c93686747207939c50a198e83ac2cf50315e02642a24f", "Expected": "000000000000000000000000000000000c3d87b1b78fab65cfc853304c682b39b6ec2b4ed005e9108f69daee5aecbd586c9818c37cdee865ba53eab9302320ce00000000000000000000000000000000062a7203cd2fd04a957cac8b6b6bb51e635ed7165c547ace10f93a32b7f37747a2e63d5767d966684409a6c748d4ee6c000000000000000000000000000000000526b44af8157dd68725aa8743684e020c1e385af7413c9dcebb320568663d18b6f29edea26f2628358852b794ffcc8e00000000000000000000000000000000098126f486ff55c21f64421e85b09a1b54f42d3499dc0e198db6f3bf7dd8476cad97c02b5b366e5ea20d8f83cc223f7c", "Name": "matter_fp2_to_g2_52", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000398d86b5206bae4ceef0bcc6335b1f6bf5d17863ef3a5e8463aaa69d9f73f8227263964659d4b770d6d9813f9399b9d00000000000000000000000000000000096bd18be1176e16a0d80e60f7d7ec9d3b6162f683440e3cde70082a73605da3783c8a058bf76d7e25056f5cd95c31ed", "Expected": "000000000000000000000000000000000f3e76e7d1cadfaad08d16457b02d89c40c157225eec7916d306faca8dbda008f41792888c647dff1acb4d4ba3b43c4900000000000000000000000000000000132bf730456e2afe745a58cdee689e37223292bf682d5b7dafa7df99e40d385559d0b3161bdda0bf5173c43ee46412dd00000000000000000000000000000000141b36ff6890e35db0054358bc0731b3aa0efac1a247a51daeff3515746456216975f44769174a4be41c109d35e4be33000000000000000000000000000000000ca401ee1addff8fe87b600e057ae34ba297886f92c5be8a8c00b360ada71831e31bc4ea1c309c7da31cb28d1011ecad", "Name": "matter_fp2_to_g2_53", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004ca5cb60c32edfa385baa911ccb7fd1f383824c22b945944b0f3f7011db8c123efd8fa70e4fe699d40c6716021f0151000000000000000000000000000000001339adb0dd8d83574c2008f0a7ed001b0808d2fb639b5e57e1d293884247d5c66c948ecc60caeea7bf440a3a44ed296d", "Expected": "0000000000000000000000000000000009d0af77517b654ad97de3ee1dbf69ec1eee901facd0f8c39b4af393d0e63957292a7529b461f7fa58909acad32ba3a2000000000000000000000000000000000fda17cd878ec0f8c294daec1bd1d56c63e875b002a81c9c41146dbb564bab6e4eae2717c9fd718af1ba816a1526e8fa0000000000000000000000000000000017563b7ff22b50b6d9e24b1e0d89ca5c72e68d4d3cc24cce36856191111d087c3dfb392070462dc7850ef5a1422931c600000000000000000000000000000000020001fcff638504055ba35230b360e6d3cb5777b959c194d6f9b038b58d3ead0b82b28bb215378abd85d357b85ea260", "Name": "matter_fp2_to_g2_54", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000089211892a61202b1ad3a85aab9f08f8d028f3e3deb16c1de4d62c1a403fa63c6dbbdf8cec37f0a9d6f346b1c7ee179d0000000000000000000000000000000012a9fc2070b326f4d7e64804b3a2e977f4bb36b6a4afcf27252af757d8535e8172a99dc909fad5a3ff8df23d6d6c5948", "Expected": "0000000000000000000000000000000000d51c77c2443f00d965c0d7ec9b5a8a8003c2a77b0ffce3e47bcb55420e8690a9c2ba9235b62a4b351d79d216a3aad40000000000000000000000000000000013cd46e3ee6cbb3bfb771ee30b5f5faf0a64a9efa1f8fc57024c83ad07a9b25e513f211ea604cfdf319dc42bf4c067d300000000000000000000000000000000009fbe1fffc67220067c948e0c80de23795e045fbe8031c9010eaa69356ffd8e5741cfe12731ec13aa236630f1b1dab4000000000000000000000000000000000e5ecdf808d10d47f041e4b078e79b32520ce9623b50059a3bd8b59daebf9103c31425659ecbaebfb2384d1c2f1b400d", "Name": "matter_fp2_to_g2_55", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b37365748fdb21fcb46f94edf86c586f17d0e042c4683e68c6cb83e7c0ed2c30ed260c15af2c9dce77bb705debfa7590000000000000000000000000000000010d7c02c6c1ba3cf6ac09a05dfe043905e1a7eb32b67f2e8a5dfe82eaca66ef46cce43aaadeff58ca85345dd0d3bf3cb", "Expected": "000000000000000000000000000000000f3e4d2559261829c0f4816f8b571170de1f74d75d74997cba56fdad42932db73504691f9e001f5b4604705a8c1a38e40000000000000000000000000000000018c72136bc7d3050ee693270668e706ebf70f990e447ecc6153a10625cccc9deaf5ae82d2a656b1376bf33b1c1fdc2c9000000000000000000000000000000001754f2725bfa76e92a74ad5b520ec2aa82a1f86e8623a054ebba489adfc9e71d1f14d4692ff9fdd8acc3d768b67e1b7000000000000000000000000000000000096f1373434a8822569cba0679dbd2abf619bd9a8c73e54e078688d4e2615d45431ac8cf3da5e15a83fe77d14b339e49", "Name": "matter_fp2_to_g2_56", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aeee59421c8ee65f8070b9d036e6bacb39dd2537d02960a3a57da4f0985cc7b27784d60fc1613f5a83c34d2250395c1000000000000000000000000000000001715ddcbaed0a05b38b1c820724405a713cc0215a4c497892f00746c0f9af28b440a3686178d9bfcd41944a224311306", "Expected": "0000000000000000000000000000000018d515b8c99f541c7dd448c3564c1909b84517b662d6a2d1176d3bf5e70abc0a2995c73ae3f1614bfed2f64229e173e80000000000000000000000000000000012126ab671420933cc4fa9206311200cc5241ca3eec54f5d97a426a72642bdde32a65c79735446779cd1744d112d544100000000000000000000000000000000190d836312ffb0d6bf493f4c942263922659abec46ac4de639efc311753148b445509f808c2fd813729b1bd96e0e663f0000000000000000000000000000000006494f9a451460ac658ec17710bef79d59b6e0fca049804c0954c5fc472bbef520f75d34408ccc62cf2da3deeb79acc2", "Name": "matter_fp2_to_g2_57", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ca4b3e1a8351057ba4a2ffaf0cdf1c3c0717ccfe26433f6c40e2cc29e32ed884f63d25979580fb555a5a86c9147bcb00000000000000000000000000000000010c1db593af38aa14ca9dd588f54b219ff1fc9edd25b3d16c595662ffa7939879244326b14d978e0dfdd25e37776964c", "Expected": "00000000000000000000000000000000173fa567aa952bfaa9a60b8232a185475cbb36761ebef49ea5fce900a06043d0e2c1b6024e40eadc9f4bf04b077201450000000000000000000000000000000010fdc32ff84f79fe39351cee1ed6b67dbcf2956020e2518d5bb5b367b61f86f1bce36f75516d9551d74cc3a567e6c2be0000000000000000000000000000000007abdff8a8967eccc4de6b4ce142173841c0e8399f5a67dcf0f7b5e5b4133391b44bf4d41d3ae3426839b19aa4c5d40c000000000000000000000000000000000c99f160062566418c09f10eb80f005f2c8c12825435f354f1d65bec0322e9b8ee968c009a84ba792a7ee7334b32bb3d", "Name": "matter_fp2_to_g2_58", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017cd94e7e672f0dba9a3c1db742d87cb18b9401e8311c4badc24f811a8f40c27942da6485807701c1a12da58076c756b0000000000000000000000000000000012f6de4ac9883e78f9d658cede4c70b44bac6b4c9734cbf24298ddf0df0cf54164aca245d8e313be4aca66ba3cab5d70", "Expected": "0000000000000000000000000000000019dc92f1da66d0855ebc8e7a2ddec623a2f843a97c7385364a631671be7ee3387a0f98940b5a51c8d9e23eb27e3133b00000000000000000000000000000000008493903c5c68b2847869b8c3b0fa9b8ba15bf1f11a40a29e6e82942e2910901044254cc8e8c3c3bf56e1f1b6dab7e86000000000000000000000000000000000bd3c1e302a191094059a6493e59a11ab05a49faf333f36f7680ec9b1043e59dfd7f0fabe9f334b97cd638dbb8bb664b00000000000000000000000000000000141c9b07ff33b6ab55b320dda6be54320082f0057c446236cf3d3a51e674c26a5241f2c702d9989adbae9045942eeab6", "Name": "matter_fp2_to_g2_59", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001b2843d9852feae3145b242cd0999877c07785bc72cc2626f388dca32edfb112bb90f9aefd6953eb15a0babe748573d000000000000000000000000000000000a69bfe809a67ee853cb96b5a7a72798748cda56936e5664d509001544539730f57a7541ecd2396c9225818b9dbfa3c6", "Expected": "000000000000000000000000000000000d0922466c358cfd756727e134b5e64d211244587e4eea036f0959e78570dce3ee264c703cc356cde20637c7560369340000000000000000000000000000000011a66d618f79fb662ac2b2d3b50750a5567e36d7092dfcc72d8f340c04df75ecc0ce4a01b410ea775dc548b8dc66c3d8000000000000000000000000000000000cc49cf4be5e2df6b43054092afa2d6acd66f5a43ef0667f6a2d660beb7fec70558ce02d7acbcd090df91fe833326718000000000000000000000000000000001270b0519db083f903a3dbe0b1b1bd5ce0b0059ea2c2c50335dd80b4bf154fc23a3de1ea753b0e279145254d8e5bd045", "Name": "matter_fp2_to_g2_60", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002479a989dbf27141bd9f467447218dfa6ef60781a7231f089d5f1f1d8dca2ce9606a75c09f63f37f9cc1ee61dceb32500000000000000000000000000000000037c2f1b96170f6847138232bac663e4940bca602717c877f58ff7f5259778246085d499ec6bbeaade18f738df333cc7", "Expected": "0000000000000000000000000000000007826398b4ec35ab58ba9fda5c15ada2a41d3854677172ef6a4a54087b64d0f73fc875ad62236eb7fdcbd94f14c8895b0000000000000000000000000000000016b14fa92de5f6e43988829ea2f851746efd6680b0ea1283264f803c8ffbe85a343bdd42225caefd1b94b8b311d2f4950000000000000000000000000000000018797093ff82bc10e6db60b1da50b9a60da01d67673e9bee8c7af2bfa2d57f409f7b06f53944938e5c73b049c2d3c6500000000000000000000000000000000000c66dcc3d30f35c21b8a9369c8f6de28af404e8b30d3c9a7f09c461b0272ba6d5a29e716012536dbeac1d9672af8427", "Name": "matter_fp2_to_g2_61", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e6fcc48312831b910e52aebbf19869b3b32f05db8310b68905bb244ab784df5732db2e72183de5d231d803d92aacff9000000000000000000000000000000000f61f9e52fe3afc2a6bf12e420cebf83bc55a449d6a167779e5b6ba3281c51d790a045643aa75f2516eaf6ae2a816ac4", "Expected": "00000000000000000000000000000000191aacce60a1a83f2c453fe196bbe5839a3a1178b147580435f7de8a2b0b4f65b3e280ac7a67570aba0fdbce6c11ad9700000000000000000000000000000000075ddd6b256f53a6ae6758a5158508540aa99b78ca069378f0ae3f5621ec24b9acff1f9b61d378334a63682a33fb0561000000000000000000000000000000000b06e11c9f858446fcc90c69d05cc26c33bafed0feda19adbd838c9c24bbf567b673110a1b248d0ee97fc682e561298e0000000000000000000000000000000018c75dc203493e12e1523af50f85ed648130ce5d3e9757f713850c867cc95c7acbb66c9733dc4f53d6a0e64bfaad5832", "Name": "matter_fp2_to_g2_62", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018efc6d366d79a09b7d56c81c17c2eec2ef7395fdb5991f41273329cdcf4537d342bddd83c3994a40d5c18f6afa054c600000000000000000000000000000000127021ce28627a9d6a492720f728acef3b38c12b951f70a932c7fc0ce3f5b6c80783351cec55d7d1bc4ab964bb4913b2", "Expected": "0000000000000000000000000000000012931f51430bea6e96f8ec456ce6b3c9e058b0bd3bbfbfe8b6e84fd6110c3bbbe0001018064e8981797f9c93713a0e4400000000000000000000000000000000196b6093dd2276098853ef2bfac84f0cad06b67a12484e98915dcc756310b818d8136954de1b602eb825ab29a143cf4b0000000000000000000000000000000008284beaa877b25374571dccb218c401cd905b351dd96700853f01920e409d11c4e440e90dc175cdf0fa807cb9d1e93a00000000000000000000000000000000063c6c238485c291fbb60bd2824154a9e23dea374292966d271ae94875391b7ceeee813e3fb9504223bb86f0ea3b6cb4", "Name": "matter_fp2_to_g2_63", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a0277228ab4e880c12f957a6fcdfe49e2155083f3f93d3f00c68622415cd1f5bae183b7df9e08328a8139392772cdc6000000000000000000000000000000000de0ab426e56029790a5ff72f34da97e11c028dc5d31e448c49ede004102804d2bcc36d509640247a4c8bfdf5104a781", "Expected": "0000000000000000000000000000000000f7bd0705cc4ea96ca38314cb85963044164b83a506ffeaea6e5eb8f7c4967cab1f1658f33b5435191427aaf9605bbb0000000000000000000000000000000007a93e2a5c118aff6ceaf2370ddad52a82854946ae595d384ee0b2b4935a574ba758736d84b0ae792f998ec6a707dfbe00000000000000000000000000000000090936add00fe5c7556610b28ecb4466ffc37b95b5cab43e072a585920b3cbe70faad01ef75d1dcb4f7d00d900bd99600000000000000000000000000000000006ae82539c68b7af3143e23229fe320924472c2b3e15a2e27e94cba674d30f083dce94706da094435c53285a43f89e56", "Name": "matter_fp2_to_g2_64", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000170b243c5aa49a0134bf3d6494cc1e55a1c6ebefc6117eca3b343a48ef0a2b077c443ec5b9201b198df015a38e66b7910000000000000000000000000000000019a8ac8a3be1d45318801bb0a654963b312540d24aafec46bb7661cebeec27b0b345275fd53c041d02b1ebfa27fc3854", "Expected": "00000000000000000000000000000000024c1b869fc13191b71d7159a07e869f1b13c11c73231b82e9bd0a7b4c32d7b376fb73d54f7231dd4974713179f235140000000000000000000000000000000012b9f95af661e8452aa5026302a7c28695307f75e9e4e32365caf378ed394fcecc831a3c47b443172188f4d18338fa75000000000000000000000000000000000f52675fb4d112d1d39ff953a253b22dfa0b73d972e756ea7fb673bf87aa992883c5baf32be6f50f880b03dcb740f06c0000000000000000000000000000000008b57726e17c873e12834dc291cff6bd95307f50e7b1d0caebd8c1eeb6eff4acc0520b135bc8e35a257133b7dc640db2", "Name": "matter_fp2_to_g2_65", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000fbbd5a10eeb2f358f2b167f1985d4084c4b12accb1520d780ef1c52f6fa80e97aaf190e7a7b241ef96fe8289fc0a9600000000000000000000000000000000155687114e7aa786ba27aeada830fc705aed069c4e3a07e88d7f33923319f416ff3caf6533cbb36e5bbb1b93a191bfd0", "Expected": "00000000000000000000000000000000061938df3365bf910884ccbd74d3cea7c30416bddc1a9b65e7723c15d89aa657da36a45fe10ed50bfa0c2769bb98aa2b0000000000000000000000000000000007b3981054255715826cf8f247210521ac681305aad3928b69804117fc143c5101383eab7017127c8452a79003a857d60000000000000000000000000000000004c745113480fd87212ed3ff30ba43c8716b32e62c1f0091bde53bd4a8fa8fe6bbcf0904144f4791ed1bf12dffa1f17a000000000000000000000000000000001237ba297c7f69e5e240846a12d86c8276a9a6ceb4af977edadc7ebfba3ad3f4ecc0b875da0ea578c83fc3b91f9f31a5", "Name": "matter_fp2_to_g2_66", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000115edef357ccc3432226d9bad796a42b1a278d9c8adfdddc5a0f8a36d32ea1787183877f8b7dfab71424cdd10b63441a0000000000000000000000000000000014b369ce61abe60d942346e049644b95a0fda96316446b2fe7ee427641af52fdd2a654bf125ff6c8c7f3dec98f6cbfb9", "Expected": "000000000000000000000000000000000a0cc3e328b4cfd01afe53dbf971ad78fc74d951050d76210e4c84438109622f0531747e762e185e3d7ecb9faa7c3255000000000000000000000000000000000622ad6092caa727d069b8921f4124d5996f3019705a908ef95d23092c5bb148873a22c227aa25ebee361d4184cc38a10000000000000000000000000000000002938d2ff50cffaab8c056c2844c50013f5bcdbb4f91b3f823836edabb39ba17ed1b8b5862301efad04bd2f5d5bf599b00000000000000000000000000000000072e96136afebbf8c06a37cf9b20c85ef8cb3f7f99d5c71b05a187c193711e5b76f52863c7ef080a1b64b2120ab2ed84", "Name": "matter_fp2_to_g2_67", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d22b7b36ac66b10adb4570f8e7521ed76de2df2a7b94b2d0b9ee4514cdff6fa7c74854d16e7e70f054a91df93c7ebaf0000000000000000000000000000000016867c9cba66dd9f1d0332d31c4e46f8e393eeeeb19af7e6e01effb29ad999b3086b599ee4b371de557d4fafd5da3794", "Expected": "00000000000000000000000000000000142ceeefa9fceb903b25d4dc68f6755833d7529752db0f125f7f65f2b7aeea8c90e599ac409576e82f7b9d6f83c43aa0000000000000000000000000000000001664acd89b482aed04ef40bd4d1ff9f39c80d7738771e2b3ca731af01aa230d865869cb05d83992e94ad99549fd0b8550000000000000000000000000000000013d6ace9b492c014d9a7504b5abe442e3bba13b1ada454aa53177990ec44f616e091f1382d36db87b7e794c11570a9bf00000000000000000000000000000000081b7a8a2906435f8a9242f573225ea62c5429e903bebda9fe9973a18ed2682185d72aaa6584b9848d1cc45ac907dd27", "Name": "matter_fp2_to_g2_68", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000db9258e1257e659e60bf8569ea90c8247a53a1d1eb958481623447a38d0f1f1686c3e40c8f15bd06cf5be9c02485452000000000000000000000000000000000517c87f3df032ff08d960f524939e66f7fa69b4168b0f2507baf7d7231a70dc5690a02d317b26f219365ac3255bee78", "Expected": "000000000000000000000000000000001182e4230f0c360c07913349f89f8436c01841c9615348a0d7057336c7483342024b0369ae52f39d4582f9885f552b5d000000000000000000000000000000000d15433ed130163a85f8ba87468c906aba88ef8610fcc1a8d6b3308cda29907acca351fd7fb19799184f1ad91c751b5e00000000000000000000000000000000111089005c4c5370863b0ea6b629197a865f978f71becb741f50f9b4e49b13162ca63c29aa26287faa9c923f57f4ad4c000000000000000000000000000000000dce405ed2a79ad433123105ad01a26ee85d1ba4e5f3b4e0339fea787058c06e9a6b10f5ec8f6eeb85b211e18b6ea076", "Name": "matter_fp2_to_g2_69", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000b6573c743989fc8613d4ea09c2e500ce965b50cf0c8975ff703116464082efff4b42828c8337809f6938d7cdd3f66e000000000000000000000000000000000896d316629c80ce6e5f240535863b9e064728665c0815f39b21675c236f6995e7dfff1e4aec9ad05861e2122469ea56", "Expected": "000000000000000000000000000000001694cb615d2994a903a13645ad44a63395320f286503902b6009e7c795dc8f024260e0c45bedd864edc9fcb9d1ca6bc1000000000000000000000000000000000f20538af015bd6d213f90fb1a1ebde4d9e2ab2defaf80d791a1f70af2ca7ea1598d43e9eef1cc982f468cf15d223c9d00000000000000000000000000000000046c62bec4c6876a67f5fe68107d677db8fa4d59ac0cb7afe6e706864c6e94744bedac6b34a68e8ebf89c231307b86d3000000000000000000000000000000001839f3b8a6dd8fe8028247670fe5b491bb43ea8fda53116dca87f97da96573a5e701a703fb5fa7bca457ef88a827e061", "Name": "matter_fp2_to_g2_70", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011fd2ccf6883b78fe19cfe7beded503cdbe1cd5dc9ee452aa6b329d2237c2529df6774334b132cfeaa616f20335f88680000000000000000000000000000000009eacceef036ec500e7676f54af703016fac93d69ed19c8943b64ffed2db498b19cd255a0a3437b568eade0f497c7b17", "Expected": "0000000000000000000000000000000009d8725eb8757828a94969ebf40545a62835686897d4504a66484a3078b2f15e39fe918d8dc01bc7560dcb005a7a0dbb000000000000000000000000000000000954a6cc9b2dedca1cf280f72fd0625184b8f83b78ee1ffcaf0f9178ce97900d759e4a74b914c3ddc32f84c3f4c3a8d60000000000000000000000000000000014121b83d2a06390ce7359e570e1593d5ff097cb0e44c38bc74171fbd8a8da0dfffcc2bcb95fb2d80a55933f696a86cb0000000000000000000000000000000016f71d24256de70618a02b0f016c6f31a21d2cc42855886ba30176584a028c2e12367be19b834bf41356cdab21223314", "Name": "matter_fp2_to_g2_71", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004a851380536054f6b69ef7581b57dfd753d1e6201069bd1218ae5766aada087b4b08f65d43b3ce0215640e8d34633310000000000000000000000000000000013579671b64f2d9a2c3ac2737cf95c2148acce3dcecb3db6d019730010c50d1c0504ba4ed42d93771ba296b0b07487d7", "Expected": "000000000000000000000000000000000cd47f0982904ccaf4f3cdaa37091a08e67a5f04af09033b864631300bb6c2aacbad105eca6ddf68a643976fb555d3d80000000000000000000000000000000012332ddb0e91f0ef9e085f21634c6d69576e60d3d24732a0c91a560906791f60f79d09ac0ebf448bd39f047b1dd428450000000000000000000000000000000000a756a869b3cbc5624f0e08019170beda35fd2642a79108b284a503942f8267b75868636302e5a12b4f1505331b15f9000000000000000000000000000000000f60724f6c8200edff41f3299ca003e9ea03b97b01a3e8c63763bdf67b9f7677331a7144915312458c40d041be97b3c8", "Name": "matter_fp2_to_g2_72", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000021dc1dedded9b0dd90afa9ab7fa8f9c33930fe4ae68185ea4cce9ed97ce4cc9ff93f96377b11f8d42b02e759a10b06200000000000000000000000000000000034c963fda3bb80043d6d7887661ad59b3c31c88c958b451a8e11684770c132205db6655ad7cbd604ecc3225b0c128b0", "Expected": "00000000000000000000000000000000095cd509e53f10b1ee18b2120e2d18f0905a202a992a9c62480beb6588275fc8b5b151e6abf17a12b6d9cd03a8b37a59000000000000000000000000000000001723bf1a3d79935eb4b39f7feaa1e05cd8f3e7a32e2c406625053d8d8fde33eefec231ee00adb00b0acac16a83dc77fb0000000000000000000000000000000004af528e886dad3f9fa7232605936bc22a6a22622828367791920ec9d31cdb2f290e37f5fc79efaeaf96c86b3f6e39220000000000000000000000000000000015bada14a84fdb09b77397cd2e27836f9f88854924af0cafc6f9125d32be848c8325a3eee1a26de8be8eb80b601f1ad5", "Name": "matter_fp2_to_g2_73", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003e8d1be04f8dbe5c7e1c7553cde8355ae16d26c819dea92fb543cbd9fe9e726359e1e4be0483a7720343f34c6a3fb9200000000000000000000000000000000062bc5fdae812802bdea09e4130c3d9bf80c7518138b116a4b6a302c155b97226a6ccc8a3ace18744e7adece08781f72", "Expected": "000000000000000000000000000000000d8f14042f36bb377655b63dbc37c50e0eb5775d4e4399972a6758cdfa9751cb4b733745ed1a47fe5f2cc434efc5af81000000000000000000000000000000001384016829d028f823e6d062898c042a461bca13ae4627c983d9b5c9e8b4ffff7eb25daa1c52b39e309b9c1e7e4f2e920000000000000000000000000000000004f7904d491a0c2018b1361a9cfec4fc829e607402859fd9b9ded60adcee51e9b522d302f9064130a4eed1327f49bb4f000000000000000000000000000000000ef4fe949fca569b31fc57ae7d0166ea53318c5712311076e052c2967144116f5490fdf56f26adf64aa01beb4f6cd214", "Name": "matter_fp2_to_g2_74", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000014b922157b19ed9debd9ae95cd9435f7980b8d4ea33fd29f99d5e7fb1a96f6d99ae13f7f86239c4bc286c3927d3522a000000000000000000000000000000000f6d4badf78d9115d93783a59ec9576fcfd87a2c29e1c506b6f7e313e71723811a36d64b37650fb6f7b460105a7e13f1", "Expected": "000000000000000000000000000000000f20b3a6505784681331208b573d3a241706692db71b5daf4e9c80adb1fa9bb87023d7ba7f9c65158653c735dee9dfdd000000000000000000000000000000000f7f357407ca6cc5c5fae4b84509d71b2f4de9af226cb4038b4820c0541d4999b7396608efd2f322a00a768129f9800400000000000000000000000000000000138dcc1b9d978adb5eee6356980cec5d18cfbfbf18cf6fd14f4119a563f473f5027af06342e84ea858223ed63d1a16af00000000000000000000000000000000012b63f0d2e8ea361d55aa617a99e066b5feef3af1930b83d2a48b527e0ef304ceadf7cba1415db80c54fdcbbcf66d14", "Name": "matter_fp2_to_g2_75", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005a54ee5e3dc05c38ade7a42c71baf5a1467938f97c0cdf0742441cd339f22542b1ca6cd215d385b3fd6ba74ec996a4d00000000000000000000000000000000051c6f0ce621e8e27e5017628690fb68f0fea27d67726a0a77b0caf9f524936e123ff096168ff2079b9990c07fa80354", "Expected": "0000000000000000000000000000000015ff2aa94f802d8f9c60ddcb43aee598239cf3ab7f90f8289a487b673f6065f8d9bc92bd4cd28df4a7b0d3bb78fad243000000000000000000000000000000000884b5d4ca3c8abea737cfca05878528890b6cee9bbac0bf027df5d4e0add431829caddf4c1e001818581ce08686eeed0000000000000000000000000000000019b91a7738fde9760240b335457955e963030848e85717858f22dc33ba5a4721156cfdd7341aa86d10d268e2fc9a1d26000000000000000000000000000000000af85e60161795906f3cf705f5e8cb8c15083a90836eac78445c6bc27ffbfc8c2df3009b436989b46b271dd8d1dbc282", "Name": "matter_fp2_to_g2_76", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000094e958d9b7dac39fa4f0143a333b2ccee09046cd23e6a1c0712470a3c2e61d2f8b85aeca37350f71d7ec75aea2b3b6b00000000000000000000000000000000080743cdb5e359e8b8ad3485d53ea286669ad66d841945296edf80dde77b20a158e2c1529dfc33a1fbecf177d75a0c69", "Expected": "0000000000000000000000000000000001bd1fe6a6c373cfdc2bfd488b0c942492b77d55b2560824edef3a91c711ee336bc1366690be40949d04edd39ad48a7500000000000000000000000000000000161476946a5687113c74a34284f49b0658e323fae57aba88b039eae584d6ef28adca669fb083a2fe8f0ef664eb5b957d0000000000000000000000000000000007aead870ae09a04cf9c9fa49d0888f7010782cdc5a0ade4c1340ff15d99cb39b7412d66d4147b95601fcf5a39c39bca00000000000000000000000000000000095cce83dbfec12973e27627bfb2d93fa9a027a2c2af4259a0879d6bda055d74559fc93fb3b4f6b0088f702af29a7643", "Name": "matter_fp2_to_g2_77", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000dec04526dbf7666d2c29db5de1ef0b3da85380a171d871a57ae3df364d2754fceabf9d4d2a3da1ecd94e377abc78430000000000000000000000000000000000d19875fe988ffbd0cf1e9bfefc7019579962ffa3a585ee232615e4a5fce0a07bce0537b203ea00010a90ec05d5b8de7", "Expected": "00000000000000000000000000000000133cdf684c3ff1cdaf07ff787b57a66c215eef06acc2aec4d726a086480e7b2a5dead2cb357d99e298df32d4c6f5029b0000000000000000000000000000000019cd65b830fb17880f40e104ed63a7d49b0fbad8eead7502f18f1b9f85f3f6ba6c275b8a242effc61a7a5d770a4fdaa700000000000000000000000000000000039aeacd163862e476b17a22c76042d7896a04f158489ae71afdd35d27106a3ec276baf5c08e3eed4b3f0a79c3c458d200000000000000000000000000000000125a9bd770c1fea2155a581211bd71d55eb1966645cc892a05d32cf1e4e5b23278ea2fb1336bba7f2c887debe4a93b52", "Name": "matter_fp2_to_g2_78", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000016dd03f0df71b183e42cc29c665f18d57637b65f05df85aed9a0f7b8aa37f7913f6606c10f24a7a8c570f485905583a00000000000000000000000000000000161e62d8be678a114fd4a99a6caeb9481f5eaef145571152fe8a6ed77a34c06a1b6ff66044102d19a94abcaaeb254e73", "Expected": "0000000000000000000000000000000007843268081f61ad2b3f6653336a99086381bb4da4c23b7d59b9c7827f2d4c196d136508c8a1f3d2f939e8c9799b95e10000000000000000000000000000000000e2c57ad95f762115d8230320810a4ea9978e26ca17decd6af4c112789608967a92fafe3fb3e79539d75d1c0bae97740000000000000000000000000000000010951c9839db9dd6ca5ef95bd1b1b9cf60bfd97cf88129fca23b24f19c9d5c71486dffb762e92f23d2a9e9d462556f620000000000000000000000000000000013d35c17b3763fc5db46ac8c44aef996f3f876c49f5278b7c97e844f23ac49f2d50b3af080322d30ead873af7b4257e1", "Name": "matter_fp2_to_g2_79", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000036efffcb0c6f42109bf9b8b7421e32fa3f855373345341e6000eccaca135ef3b2e1c0151bddbd46ae92185acb847d74000000000000000000000000000000000edbd7a40f3e688eaff5e29800159b8d799df07e81f65d59011e84329b4689a28a15ce11537fb560df705be26bf14b1e", "Expected": "0000000000000000000000000000000001aa1919a50b5bad62b839d672d5a11ad345fcc61f75eccc42990e113deb8a486423d1b27e7c81536d8a5799986b9408000000000000000000000000000000001879295d2f7bb3923ec61c063ee4f96d7d7cf7786259e2f4cbc3ccffe7e114af264b3527a5e06dcfad50ec1e2a9c1ae0000000000000000000000000000000001042632662e406c95f3fd44a6d956e526907147e7e6d4219c1c4b28a31e479974d00d4ad6e683f6a834d3d4a20830f4b000000000000000000000000000000000a29ea98ec25e7827bcb349ccdb2a57926809f3cce44d5ff6cd636460278c8103b0db78fa580e9edd4ecd0bdb21018ff", "Name": "matter_fp2_to_g2_80", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000974c7d17cbf91947ad435b30ad2b639671a43d67da6a4edc7f8bdc11fe817d4d42f687dd642a2be89c81bc36e8df592000000000000000000000000000000000efeeb85860877abdabae35672a77ca9d2cf0ed18ed209fb905b591a841c900ed06d2c32c56bed5f7efd469d369b05b8", "Expected": "000000000000000000000000000000000c67498c6751cc27d871b8711c4739398c501a5bfb688d7e1a73dc7db5c47c3e28b633078cb83745bf5b0d5d2dde3ce2000000000000000000000000000000000c205c03305422bd44082715b90e0a0ec178003d6f5e14a0d13bb0f2c38f2270816b884b4870b75db44ab080f88a35e2000000000000000000000000000000000257f378935772d326710ec6efeb22f8c9b6b549c8a4c0205b75740047d750d73da4e71aaa8ff33b9bd8ab7621b08e62000000000000000000000000000000000c386a15f09c849be9f449a59e1332a1e7f16a9394c8de198c01399a05b0f963921c4c57d49916407ae0d202af8da32a", "Name": "matter_fp2_to_g2_81", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015333364f4d0d173ef35e447fc189b9d65ef71b9fc4ecba25fb6c8c1bfe8467f26bb9c55ef10bb34125d714b94aa1df1000000000000000000000000000000000cbba9d8ac191032f03c0746f13108962130c9e2c01d47f01174a4c4d3daa7631268f7dcc08dfda317bd249fb6e73e8a", "Expected": "000000000000000000000000000000000864da537fd94a9ff1bdae733f01e145dc97a894733d0811cd67c2648ba61d0b187241f9ec69d8c011f514894a05a608000000000000000000000000000000000a53ea4ff9c0ff71541ee21127a33daff2b39e74301946a86e51dc7834717e7d8784cf92fa5845bc0613b6b869003f58000000000000000000000000000000000582f5a1fcef3067dfcdfabc6af33871114538abcb02fcad761cb496020c7b423fc52f0075916f160fbe03574df97ea4000000000000000000000000000000001244ede8ba0dc09aacdc5d9f886e59bf963a25885dbbe2c3d1f611bfae82debc556ec4c94f0606492c7b8c7bf976ec34", "Name": "matter_fp2_to_g2_82", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000781e980c167c982c2fc8d0baa3907bc5499eafca675ae20a10b25063c9088fd06f6769df505e5900bcaf99e266c052c00000000000000000000000000000000183c12798438ea92db75d5bf76cf29d320fab3653e4131989205f2817aebcb1b13f161864c084fd13a11459d7d5ccd92", "Expected": "0000000000000000000000000000000016c334aec0e19934665596f0ae37eb398f1d6f0d0c9f08189f1ccc219230395124a9da03858bdba13ec5366da54228af000000000000000000000000000000000b156ea34ae7b5c252dd90997f1c693773a463c26935a69bcc0599b95bde9e6aa31649c48b6ee4ec1f0a56b19273a5170000000000000000000000000000000014b2d69e02418844effcbc0d564b2721deae2872cd1f27f61d544fc0ebd5cadc77c6777ec944ef0500db181a5443618e0000000000000000000000000000000004f0d48a25c1eb81233f385af17ab6abf554e1285b669eeb5e884c64d5815fd5fa1350bb361997cf2e317f7c5e9cd19a", "Name": "matter_fp2_to_g2_83", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000879133a3c0e50c90abf1a6ac75bbeca1121c865ef39e9224ddb160eb725e0850a34aaf9014e42174966773e40e4c99a0000000000000000000000000000000004c66f8f5bd462cb27e9f5e1d93e322bd97582b9e81d07b2877103420262e4cfe6d0e3bc07f9f160701fd754793eae33", "Expected": "0000000000000000000000000000000003c0d6b721cee4e5fdc6a02095674a58075f81b1d28163f81d5b258c82634297009e6bfc8193969e23e196cf7a99ad6c0000000000000000000000000000000013229818411c8e55e50a63df6983150c1d5ead828711131d9c81841850ed76e4712954d3225eb6d7fffd3cb9924f7497000000000000000000000000000000000f42d6e4d5a28dbfda87c806cb0b1bbabb745e63e655c3c6be50411da4dcdc745ae50f71d56e88db8454d40375e325810000000000000000000000000000000000f663ab791b48f76d358e66e8cd8fa40848dff2bbec758ce1d7b3fe02d1f6b3f123cef644d4fd86d6a77b8155feae58", "Name": "matter_fp2_to_g2_84", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a7e855324ef471b8fefb31967cec84d57953407ba555b672fa59364b303030cb02b6c77933cc63fcd1b8c107b263554000000000000000000000000000000000b50c3f7cebdcf538820113acdb017fcd5d41a4fd679af8dfde7b0c330e3576ca79d09eedc724a93a3f5c90d141e7524", "Expected": "00000000000000000000000000000000197865f685e78a8842fa79ddc728d507e9f31b31666d1952a46f6422c97c83fba3087be70e3bb588260556014523f74000000000000000000000000000000000131f5d85ad3beaabd129d5a5675d90ea911ebd02cddb5ddc7a8be28c33061430d684d123d5c516785d21ebf756c99195000000000000000000000000000000000c7a14948f3aa29f845e5ca9877db9f0477af376eaeb45324c21e6f99e738aeec96b89af4df942bffbabbf50172d8e5b000000000000000000000000000000000ed4aea3cb585b0d36972f9ad6943172ca7375b44d1d6e80e0bf97a0b25d74deca4d35ce865c8747f1c7a2771a37c667", "Name": "matter_fp2_to_g2_85", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001706830efca18d3e75ea0f1ca8af23a816017ceeb045694cdbad6d3d9aa5a9ddb123f5097a226a217166de3a82038393000000000000000000000000000000000402132ac383a2fcb17fe73398273ef0c2f2d0d6edabc78f31080d3ecbf7c249ffeef28bb8b37a6ef2a7d726c070dc41", "Expected": "000000000000000000000000000000000a795c2affaaecab6cd2cfd6c8fab6e35cdd646e9cfa7b5e02400ef4abf839a69924ea80152eca7810a5041d1bf58ee800000000000000000000000000000000121426bb945d6f6b385c98a5247b7dadaebd3375dd8b2bff7aa77fddfbe603de89e77baf0e8f36a924c707c53d29a1450000000000000000000000000000000007a6fcb486634186f001c8b99874f0a07a37f1ff4b30599d2f570f1bb4ff290b816547f6ce8b3c1ed33e57630a1d57ab000000000000000000000000000000000fa65924a8f17414eb7dcc54f2a4134568484e91533dd21fd33cbcc37a920f2804516a64f1986e9d887ca189179d07c8", "Name": "matter_fp2_to_g2_86", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024beda2b950efcee233435f0c748e33aa928f54ff29d3db217d7e32b1aac5f4ed11705da4fb8fd38481382486e4aef7000000000000000000000000000000000c85283ad6e35a72d07b74775df1a4660113d50b51426451f454a575adf9cbf9d7be3f521649f6c367c4f4c74b67ff6b", "Expected": "00000000000000000000000000000000049d9ac43e31faa3d02f8255d207b82e4b27e8a9a61ba45fc4f9ad8048e5f89b58d25d98253aabe29334e0dc09d1cd6b000000000000000000000000000000001544f90a0baea38b48d89bcb337cf5a80faaa79334733b7e6126f55358a7e498aeb61419065b9434cab9d10fe8e7fd9f00000000000000000000000000000000139bdd668462a1b5d3ef1299d47aa91ed141ccbeba5b08a8ee31b023aa78c16514a97ba08abf5c8bb1abbd85b3fe87350000000000000000000000000000000005c7dbb8a22403a96aee634cfc67ee6f1069cd61a1e1831e8faa9d7e1aa5e4f7623f51f2e5b739f7fcf3b4ba77c82ff1", "Name": "matter_fp2_to_g2_87", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cb18f477abe58af92116101c3f52ad4f6074ed92a08c3adcc6660b555df9cff09dd8b34e032ed81e868a62bda50378d0000000000000000000000000000000013c4ab1558dc250c3b5d0f0fae3db62b8df969bb41e9ecc24c10e1e51cb399f1368bed7375a9b9ad9c7653c868eecfe3", "Expected": "000000000000000000000000000000000b8b8bf2b25c2386e5f3be4bdb387d8005cf055e68ab9a5606f17dbedc4fbd7a11314fd646d08bbd6e394485d4f56f5f00000000000000000000000000000000173a45d766682f82ec2d69aed1d80ede2477c276ddaa8fb97f5f4d0515b2c2e370c615cd81c1e361f95db855c9b1b6e200000000000000000000000000000000115868a9187a0465a9309054e865ef224ec3c88a5eafbcc25f9a912ee3b19084757a90b72a4038ba71b10f59fe2f93100000000000000000000000000000000006c5476eb8aa1a471d289af52c7d1df55f6bb1ad53d7eaba6bdc2a97fcb24ec480f9d8e12079d366f2213194c861f016", "Name": "matter_fp2_to_g2_88", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000188f650fdc51b970d16c0637ad5e97aade93c7f1398751439484ec6cc56613814908e51cfa7f68da9d980bb9dac47a400000000000000000000000000000000081834f86f1310135a2cb03265f37d9b7c9459bb149bc54b5a61319a7cde36c6a2a0fb49f8f1fb9d80f07b84f799119f", "Expected": "0000000000000000000000000000000016e8fea4d09831146fc35bcad28e441f2c02e4d17838e04dc7cf909b2133297a13f07ee927722f3d78e36721d6848e3400000000000000000000000000000000114dee8b3a47269e9ada05ee015a874d1cbdfff4acdf5310642f829efd08f78dd6110e1c7a514e7d76aff52046f4ed140000000000000000000000000000000017b9d23f7a865a3ca61197d841fd9195805a9e883d79dc7d36e82f504e6689ade0e84c70a5c5c516fac3e3c643942e160000000000000000000000000000000001ab82b2a0986dec3211507b8adca351829b0a13f25e281f98f54d9e0e32280ea4c638dcb74280eb747a0d9af43b6b74", "Name": "matter_fp2_to_g2_89", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006f66eb49f95f51ec90df86254580f0ae57862bdd8b5f2759ace63c5f14f8c5a762207f744bb82a8962f8c4fa410dfdb0000000000000000000000000000000004e02a80628c30ce336eab890fa37a227f77357a60be72cb87cc2b7442d2163d395fdc59350624ca1322bfe8619a2efd", "Expected": "0000000000000000000000000000000006bc2ae646a603a1f4524b445cdeb99914e4ed19cd0676d511764b828bfe126e81cad2cb566655f04de1a302c14d70bc00000000000000000000000000000000023bd509aabfa41385e90cd4b1cbbfa45d066c4defab56993aaa386dc5b7707b1a3a7d444b8bd295a30d0b8f4bdc572e0000000000000000000000000000000006f82e60e18cc958375cce6f465db461ff46ed9d15cfcc01a3aff455d54c77ebba5a654c2ec788b6ed8ac53c39defdd3000000000000000000000000000000000896fbe6492c4c297f8b6d60295a7f2565734d69eea67b2675211a203fec043f0d181b1348bea425a068b7bc12676ed0", "Name": "matter_fp2_to_g2_90", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001451bcd19495cea3a19393b77760f688fbf17b107dc131c88cbb503eee2a804e2978d6e8a4720d144083d28be73371d70000000000000000000000000000000017db715e8680a0e82e18b513f2c9c7ea136cefe8add71aac6baba146e3e33a498d025c7e0808ced306c915eb02900c61", "Expected": "0000000000000000000000000000000008604a06a198c3e11458de920176842221667d024f9c155892485a37ff56252be1dc629a6fd580fa41f5e598a23f3651000000000000000000000000000000000e008eed25eafeaa67f27e89e1f81b469724a4b00f08dc4ae672aa1587b19dc615330e3fce0fbd98d7526bc2c4afe69e0000000000000000000000000000000015bc1e4ea5ae2a7fde6d5e5c3e58f6ff5df5bcb125ab402f10edd09087bde39fa27dfcdce7d04fd18ce399729e155fae0000000000000000000000000000000006684e9be8bf9fa4badda842a1d8840f0820d9a797e482c64f4004a18cd63986f19abfc93f6bf068d38eb1e491cabbe6", "Name": "matter_fp2_to_g2_91", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013a6e129d4dd4aa93cff5489ee879763e2a2231939e609d2d72f07e630b37d09f3057a36fd5cdfc9c81675c996f8ba0f000000000000000000000000000000000e8d7ad082e8f9a718fc2ea712853ed9ab4e8b1a8ca9988f77c70fc759f1fe2d4bd73696e539f130be13b2862efbdf77", "Expected": "000000000000000000000000000000000f15c3d0b40735babb2e38a2471773faa16b2fa307c3a573ef4cfa5a5559574b2d26cf88b19dee204b77f6e11a1b927c000000000000000000000000000000000d224445f3d31d381bb29c4fdc8130174f5bcb957f451c92f4a652cc3d2b5df985017133a944849b5228a88f99bec771000000000000000000000000000000001338b48bc1fa229f251bcd4828654baec9d149f090b19596ad3b444eacc7bc583f97d9cfc40d5611fdcf89cc9a88e33b000000000000000000000000000000000c30dd2aa51f6577d57175edb3ccc1b324717bc195eb0073c1dff4e5b0d77cf5e41ec233527b3936994e86303f91b172", "Name": "matter_fp2_to_g2_92", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003379bc10acda5ed1014e2bba1e30cf83b72fe69259eb35476a031b8a898e0183bc32ee853a85fb3d738424208fc880900000000000000000000000000000000175a2e5a44ed62744fbbab9581ea7283470bff12436dfc414ad80b4070f895de3786022cbaed55bdbbc4f68db7460548", "Expected": "000000000000000000000000000000001735e1f2fe905839fd6534c95b95322f8cc86a4c482f1ad7691b9b9bb8f55015b4faaa1f243786aa33b5874817cd09c80000000000000000000000000000000013f1a27931ac513145f2601e009cf637ba4bdb18a7604f89534fa3ec8488f5b6eab9963c5d753fdd34cbe7d2f8eb8a5900000000000000000000000000000000092d8f800e7a4bf6f9a25ddd7f64fc403db53b1695ae59c15f229458f347a8e7c2ebc415af2d3849282b670c5cf6f8600000000000000000000000000000000019d22d694e559c55db63521e7b60a1a2342c3cce868d70951e5ed32ec0f5efaeab0e78b21359110f6e769776b745938a", "Name": "matter_fp2_to_g2_93", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b384a9db472c38a5d246da56059b7630f002b5f4663abce7c5f6e896222a1ca1ac02883a1ec95a4ef09bcfab7d0652a000000000000000000000000000000000de09ef45aafa56936e446e18ef9ff97ca8b81c295d35cf7b72416ebd80586d0fc479d86c23295ac54a23489af045ebc", "Expected": "000000000000000000000000000000000d7dc499e5213120b3ccc173c83d3c15dde9e13ef57238cad84889243b35c8e69eea2ac7ef7560051dcd7402b46b733e00000000000000000000000000000000063ad31c17eb17d39cb4b33e45a0b0e951becc11b685b10cb45cff268b6dca40b780f7e1532be91903372c413a11b5be00000000000000000000000000000000140da959456cbd34e041409350d6106ff65ce6dd2ac3149f04959b16eb83dd0456ca11e5990daf4a1e5c23d3f30a6c4b00000000000000000000000000000000195d07ab127d49baf89fcf5eea1f5e4cffea1a577a5c864c0e637fbdfa10182adc1d5d4ebb871949300193e45ae0fbdd", "Name": "matter_fp2_to_g2_94", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014df33e7d3ef2c339b958fee667097ccf146556261f7db4b0b0a3c29897b73a0ca249866cff1461488012bc16df43b0d00000000000000000000000000000000099dda253a43b8cfac580306267d9dfeb2c129ac1818fee43c6df5e582f5fa726ba73e1a2ef6a9e011a387c393529678", "Expected": "0000000000000000000000000000000013ec1ef25b303fe2f10a0bbe9bd77a4b2a055e176c2870c99e63b4baf2b313a835459263351dfbc25c22ea32946d8956000000000000000000000000000000000cb1c3292a2e0c9b1c1ff43cbf7595f39c00fd413b54782681fe75a6f5f231d13912f8d598dd8aaae8159de083dccd8e0000000000000000000000000000000005385f2d4bb6d94d67b2a3bacd3aae31da282707672252c0ab1a12fc85d8e9b9eb75454eb145937542099b860f9d6dce000000000000000000000000000000000e59506f7733a38a7e1da4ea5958de4755b52a9307ba2e5813131b33b86f0e401f97594d9674ff1667068a1ec3c9b145", "Name": "matter_fp2_to_g2_95", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011c89c8d7e83155a308b2e517a23f05a4a55353332292b44b0a891b6f730fd126bd0b97eb87f0fbdb6c82779791d022f000000000000000000000000000000000da6f02450955bf26e236ec63aaf80a018ac34fd8784bb24a22a1fc5e8bd686244a923009a10cb38b1422534d0997afd", "Expected": "000000000000000000000000000000000f4392a41fb3e58dea97b97fd22e2fe6436c3f9bbcd944585a76a5f1a8f98ea4ee21639208d765b6c3a7d08f8cd3f3f00000000000000000000000000000000002c3d62794996dbb881b665eece98926f41a42c21539125fda6070d9f69e29e0557c886b42e4bcd97b14134d6e9d1d710000000000000000000000000000000004b93f315822aa1be8250c2e736727d390ae3a862c4c7dda452817f70f01c73e6f344df1b0f05f03bd574edecc70902e000000000000000000000000000000000731403981fd6243d00c23d0a42a759016f7907548847743f18421f51b1e72cea92f0c5580328babd4ae3e15bc9c56de", "Name": "matter_fp2_to_g2_96", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015bb227b5c9ccfb8390edcd158b04a69a88a3b99a10ae90e548182751a16448df25493061afde2c9790a0e75e6f409a20000000000000000000000000000000001d7b609155bf3939192eee9642032e6fb10f57d53916674c60211a37b4a7662759899a9569e2dc730febd23f747a7a3", "Expected": "000000000000000000000000000000000b35c6294b70336217eb9334ff1f1bde9d892d109e947de7f4f5681b3830ed00ad1b89ccd7cbad88ce1586449140697d00000000000000000000000000000000032691e5f4597c06496e9e37907041ddcadd18ca8ce64a8b400b1e2e8d63acce5533231edb66b69807fa2dc026c1d2be000000000000000000000000000000000773ccd132cb215cd98aa17d7fc432e0577b08d8faaa35199000d46fdeeb954e8652566384fa0cc5bcd1724942f7075b00000000000000000000000000000000112e951db3694944fc82fb980547cd8b7f2e5ec6fd2051b6aff2573797bd6a28437848ea0627054af1960ad1de0981e5", "Name": "matter_fp2_to_g2_97", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000017599d71686e817cf58b78dd7586d5b359999b32b0dec2d67e33fb6388411418ecfaa2670a2cc9dce3dadaed0fb3364000000000000000000000000000000001773995b540be9ffbfd276a92c0494e4eae296d094f9f7eca975cf4f73ae05e92bd64ea71ac47bba534044f4072a6591", "Expected": "0000000000000000000000000000000018f2eace212eacabd44ff01d886543410ef72b4d27f8d25cb080dbe4b1d4b2b4e57e4dd40723d15789d9b5104b088d9b00000000000000000000000000000000098e9e9b302876ce85ba486609fd028f357314149ce8b530778e6de586ab057fe59648d8c8ae80fe619c4c605b90784a0000000000000000000000000000000016d20a8ca43d37518c8a0f47566ba61a7aade9ea2cdd4a0907ff0ed862c6b7c64815d50397eebec262a05c6010cfaa790000000000000000000000000000000005a70c2fce25acdc4a95fc2bdedb007d71f24b0b5714fa14910ef590215d25442e91a66b6bfea5f7777f0c6d202eff32", "Name": "matter_fp2_to_g2_98", - "Gas": 75000, + "Gas": 23800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f470603a402bc134db1b389fd187460f9eb2dd001a2e99f730af386508c62f0e911d831a2562da84bce11d39f2ff13f000000000000000000000000000000000d8c45f4ab20642d0cba9764126e0818b7d731a6ba29ed234d9d6309a5e8ddfbd85193f1fa8b7cfeed3d31b23b904ee9", "Expected": "0000000000000000000000000000000012e74d5a0c005a86ca148e9eff8e34a00bfa8b6e6aadf633d65cd09bb29917e0ceb0d5c9d9650c162d7fe4aa274526850000000000000000000000000000000005f09101a2088712619f9c096403b66855a12f9016c55aef6047372fba933f02d9d59db1a86df7be57978021e245782100000000000000000000000000000000136975b37fe400d1d217a2b496c1552b39be4e9e71dd7ad482f5f0836d271d02959fdb698dda3d0530587fb86e0db1dd0000000000000000000000000000000000bad0aabd9309e92e2dd752f4dd73be07c0de2c5ddd57916b9ffa065d7440d03d44e7c042075cda694414a9fb639bb7", "Name": "matter_fp2_to_g2_99", - "Gas": 75000, + "Gas": 23800, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c", + "Name": "bls_g2map_", + "Expected": "0000000000000000000000000000000000e7f4568a82b4b7dc1f14c6aaa055edf51502319c723c4dc2688c7fe5944c213f510328082396515734b6612c4e7bb700000000000000000000000000000000126b855e9e69b1f691f816e48ac6977664d24d99f8724868a184186469ddfd4617367e94527d4b74fc86413483afb35b000000000000000000000000000000000caead0fd7b6176c01436833c79d305c78be307da5f6af6c133c47311def6ff1e0babf57a0fb5539fce7ee12407b0a42000000000000000000000000000000001498aadcf7ae2b345243e281ae076df6de84455d766ab6fcdaad71fab60abb2e8b980a440043cd305db09d283c895e3d", + "Gas": 23800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000138879a9559e24cecee8697b8b4ad32cced053138ab913b99872772dc753a2967ed50aabc907937aefb2439ba06cc50c000000000000000000000000000000000a1ae7999ea9bab1dcc9ef8887a6cb6e8f1e22566015428d220b7eec90ffa70ad1f624018a9ad11e78d588bd3617f9f2", + "Name": "bls_g2map_616263", + "Expected": "00000000000000000000000000000000108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f000000000000000000000000000000000296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d00000000000000000000000000000000033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee65600000000000000000000000000000000153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f", + "Gas": 23800, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000018c16fe362b7dbdfa102e42bdfd3e2f4e6191d479437a59db4eb716986bf08ee1f42634db66bde97d6c16bbfd342b3b8000000000000000000000000000000000e37812ce1b146d998d5f92bdd5ada2a31bfd63dfe18311aa91637b5f279dd045763166aa1615e46a50d8d8f475f184e", + "Name": "bls_g2map_6162636465663031", + "Expected": "00000000000000000000000000000000038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3000000000000000000000000000000000da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b0000000000000000000000000000000019b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4000000000000000000000000000000000492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e", + "Gas": 23800, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000008d4a0997b9d52fecf99427abb721f0fa779479963315fe21c6445250de7183e3f63bfdf86570da8929489e421d4ee950000000000000000000000000000000016cb4ccad91ec95aab070f22043916cd6a59c4ca94097f7f510043d48515526dc8eaaea27e586f09151ae613688d5a89", + "Name": "bls_g2map_713132385f717171", + "Expected": "000000000000000000000000000000000c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f90000000000000000000000000000000012c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad0000000000000000000000000000000004e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a5690000000000000000000000000000000011c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd646", + "Gas": 23800, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000003f80ce4ff0ca2f576d797a3660e3f65b274285c054feccc3215c879e2c0589d376e83ede13f93c32f05da0f68fd6a1000000000000000000000000000000000006488a837c5413746d868d1efb7232724da10eca410b07d8b505b9363bdccf0a1fc0029bad07d65b15ccfe6dd25e20d", + "Name": "bls_g2map_613531325f616161", + "Expected": "000000000000000000000000000000000ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1000000000000000000000000000000001565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d00000000000000000000000000000000043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28000000000000000000000000000000000f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a561247", + "Gas": 23800, "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 f41d375943..b6e36dccba 100644 --- a/core/vm/testdata/precompiles/blsPairing.json +++ b/core/vm/testdata/precompiles/blsPairing.json @@ -3,700 +3,742 @@ "Input": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d2800000000000000000000000000000000122915c824a0857e2ee414a3dccb23ae691ae54329781315a0c75df1c04d6d7a50a030fc866f09d516020ef82324afae0000000000000000000000000000000009380275bbc8e5dcea7dc4dd7e0550ff2ac480905396eda55062650f8d251c96eb480673937cc6d9d6a44aaa56ca66dc000000000000000000000000000000000b21da7955969e61010c7a1abc1a6f0136961d1e3b20b1a7326ac738fef5c721479dfd948b52fdf2455e44813ecfd8920000000000000000000000000000000008f239ba329b3967fe48d718a36cfe5f62a7e42e0bf1c1ed714150a166bfbd6bcf6b3b58b975b9edea56d53f23a0e8490000000000000000000000000000000006e82f6da4520f85c5d27d8f329eccfa05944fd1096b20734c894966d12a9e2a9a9744529d7212d33883113a0cadb9090000000000000000000000000000000017d81038f7d60bee9110d9c0d6d1102fe2d998c957f28e31ec284cc04134df8e47e8f82ff3af2e60a6d9688a4563477c00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "bls_pairing_e(2*G1,3*G2)=e(6*G1,G2)", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d2800000000000000000000000000000000122915c824a0857e2ee414a3dccb23ae691ae54329781315a0c75df1c04d6d7a50a030fc866f09d516020ef82324afae0000000000000000000000000000000009380275bbc8e5dcea7dc4dd7e0550ff2ac480905396eda55062650f8d251c96eb480673937cc6d9d6a44aaa56ca66dc000000000000000000000000000000000b21da7955969e61010c7a1abc1a6f0136961d1e3b20b1a7326ac738fef5c721479dfd948b52fdf2455e44813ecfd8920000000000000000000000000000000008f239ba329b3967fe48d718a36cfe5f62a7e42e0bf1c1ed714150a166bfbd6bcf6b3b58b975b9edea56d53f23a0e8490000000000000000000000000000000010e7791fb972fe014159aa33a98622da3cdc98ff707965e536d8636b5fcc5ac7a91a8c46e59a00dca575af0f18fb13dc0000000000000000000000000000000016ba437edcc6551e30c10512367494bfb6b01cc6681e8a4c3cd2501832ab5c4abc40b4578b85cbaffbf0bcd70d67c6e200000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_pairing_e(2*G1,3*G2)=e(5*G1,G2)", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000fd75ebcc0a21649e3177bcce15426da0e4f25d6828fbf4038d4d7ed3bd4421de3ef61d70f794687b12b2d571971a550000000000000000000000000000000004523f5a3915fc57ee889cdb057e3e76109112d125217546ccfe26810c99b130d1b27820595ad61c7527dc5bbb132a9000000000000000000000000000000000186a1da343cacf1815b9c8b6c807f536249dbfdb59d77bf4920ad2198a0d83ada21f7c39de6f06a5599f22571cab288d000000000000000000000000000000000ba1ec44f95121bd622932b84bbb4b3d279f69c494ee44db68e3165c86b627ba5e397ee197313fb5b775972798997332000000000000000000000000000000000783e7493e9fb106fa0d085e7c03eb816468d12c65d9b77643ed07c02583d491f4db5db44e565d50d8ccaa9ad8f7f8e80000000000000000000000000000000010a6a5fd90cd5f4fb6545814f5df065b001074bb3f29f649dd2612815df3a19a320f7754dd3d458e48e7fb1b4953978f000000000000000000000000000000000345dd80ffef0eaec8920e39ebb7f5e9ae9c1d6179e9129b705923df7830c67f3690cbc48649d4079eadf5397339580c00000000000000000000000000000000083d3baf25e42f2845d8fa594dda2e0f40a4d670dda40f30da0aff0d81c87ac3d687fe84eca72f34c7c755a045668cf100000000000000000000000000000000129c4945fe62538d2806fff056adac24f3bba8e17e42d82122affe6ad2123d68784348a79755f194fde3b3d448924032000000000000000000000000000000000528590e82f409ea8ce953f0c59d15080185dc6e3219b69fcaa3a2c8fc9d0b9e0bc1e75ec6c52638e6eaa4584005b5380000000000000000000000000000000018dc3e893f74729d27dd44f45a5a4f433dcd09a3b485e9d1c2bd0eb5e0e4c9024d928ddc426fdecae931e89885ee4db4000000000000000000000000000000000d6ee02e1fc7e52a8e1ef17e753065882c6fcc14da61da7ffe955fe84a9d2af9ba57562c69db3088652931bf124b0d5300000000000000000000000000000000051f8a0b82a6d86202a61cbc3b0f3db7d19650b914587bde4715ccd372e1e40cab95517779d840416e1679c84a6db24e000000000000000000000000000000000b6a63ac48b7d7666ccfcf1e7de0097c5e6e1aacd03507d23fb975d8daec42857b3a471bf3fc471425b63864e045f4df00000000000000000000000000000000131747485cce9a5c32837a964b8c0689ff70cb4702c6520f2220ab95192d73ae9508c5b998ffb0be40520926846ce3f100000000000000000000000000000000101e147f8bd7682b47b3a6cc0c552c26ce90b9ce0daef21f7f634b3360483afa14a11e6745e7de01a35c65b396a1a12700000000000000000000000000000000090ca61ed16c4c1e80acfef736eea2db0d7425d9110cb53e6c4a2aa3f8a59ee6c60bdce8df5825011066d44bef84d29600000000000000000000000000000000028207394adcbf30250ac21a8f1db6283580bc5e39159930552e5edb25e6215c66b6450296edc80dbc3a2acd125dab160000000000000000000000000000000019bef05aaba1ea467fcbc9c420f5e3153c9d2b5f9bf2c7e2e7f6946f854043627b45b008607b9a9108bb96f3c1c089d3000000000000000000000000000000000adb3250ba142db6a748a85e4e401fa0490dd10f27068d161bd47cb562cc189b3194ab53a998e48a48c65e071bb541170000000000000000000000000000000016cfabbe60d1e55723a0ff72cf802f2d1cf13ed131e17729adc88522a657f320a336078a9399c8e61a3bbde3d52fd3640000000000000000000000000000000009aa9a3c2a6d49d286aa593c6ff644f1786fa9ae471bdb3fe70b150a9ed7584eaa886ac057c30005c3642f65ad5581cc0000000000000000000000000000000001d417894c0cce924955a795b188b27951f8438a5485404b921a42fa79dea03c10e29d0390df2f34d7be13f360a7fada00000000000000000000000000000000189b0b3a04e6c613899d51231dbf0cba6a8a8f507ebed99d24fba7ebac6c97a8859ffde88e6d95c1a9d6b4f0a8f3c417000000000000000000000000000000000d9e19b3f4c7c233a6112e5397309f9812a4f61f754f11dd3dcb8b07d55a7b1dfea65f19a1488a14fef9a414950835820000000000000000000000000000000009d0d1f706f1a85a98f3efaf5c35a41c9182afc129285cf2db3212f6ea0da586ca539bc66181f2ccb228485dd8aff0a70000000000000000000000000000000016cad7807d761f2c0c6ff11e786a9ed296442de8acc50f72a87139b9f1eb7c168e1c2f0b2a1ad7f9579e1e922d0eb309000000000000000000000000000000000d3577c713fcbc0648ca8fbdda0a0bf83c726a6205ee04d2d34cacff92b58725ca3c9766206e22d0791cb232fa8a9bc3000000000000000000000000000000000f5ea1957be1b9ca8956ba5f6b1c37ea72e2529f80d7a1c61df01afcc2df6f99ced81ac0052bd0e1e83f09d76ad8d33b000000000000000000000000000000000aabced4e2b9e4a473e72bf2b1cc0ce7ab13de533107df2205ed9e2bb50fa0217e6a13abcd12fce1bda1ccf84dac237a00000000000000000000000000000000073eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086000000000000000000000000000000001825bacd18f695351f843521ebeada20352c3c3965626f98bc4c68e6ff7c4eed38b48f328204bbb9cd461511d24ebfb3000000000000000000000000000000000029ea93c2f1eb48b195815571ea0148198ff1b19462618cab08d037646b592ecab5a66b4bc660ffd02d1b996ca377da000000000000000000000000000000000bb319a4550c981ee89e3c7e6dcc434283454847792807940f72fd2dbf3625b092e0a0c03e581fd9bd9cf74f95ccef15000000000000000000000000000000000abb072b8d9011e81c9f5b23ba86fdb6399c878aa4eadee45fb2486afe594dffc53be643598a23e5428894a36f5ac3ce0000000000000000000000000000000005d04aa0b644faae17d4c76a14aa680c69fdfc6b59fee3ef45641f566165fced60cbbda4ca096e132bb6f58ab4516686000000000000000000000000000000001098f178f84fc753a76bb63709e9be91eec3ff5f7f3a5f4836f34fe8a1a6d6c5578d8fd820573cef3a01e2bfef3eaf3a000000000000000000000000000000000ea923110b733b531006075f796cc9368f2477fe26020f465468efbb380ce1f8eebaf5c770f31d320f9bd378dc758436000000000000000000000000000000001065f2a2d29a997343765f239c99a018490eced40ac42fc93217dfe20d8b43ee2215f65166aff483b3dc042c5a43b196000000000000000000000000000000000766e4c66f4a442ff1f61a7a4d197d2b47dd226d0e7822a9b065108cfc643cd3f3d5ae59ed2ce4cde13fd9260bb5b7cc0000000000000000000000000000000012251cc6abbabeb7bbe1fdd63eaee10832a748fff24f7e3fdccaea87facb6e99f2e0407a38f27f90450a471b873104620000000000000000000000000000000011181e08c8fba91271adfee9d31681f8412ab7a3f754f7ba4709024c0ad2287e32dd455d71a296b4838072a8ab9d96f2000000000000000000000000000000001252a4ac3529f8b2b6e8189b95a60b8865f07f9a9b73f98d5df708511d3f68632c4c7d1e2b03e6b1d1e2c01839752ada0000000000000000000000000000000002a1bc189e36902d1a49b9965eca3cb818ab5c26dffca63ca9af032870f7bbc615ac65f21bed27bd77dd65f2e90f53580000000000000000000000000000000005a7445f55add1ed5c143424ceef3d594280e316c9441a8e68c3ad97377141d015bf878bdfcf0df9fbcd0529f4e8100800000000000000000000000000000000192b52ba08ed509fc84d5775a7182498fd1ff80941d673c53470c9c9f1192f9c0057d68a1dfee0c68fe5df3625cc43bf000000000000000000000000000000000d3fcaf2f727e0eb32c65da9b910dc681b948dda874d0db6f6ed3f063430fbf073385a9a14c2dd78568726124e2b3ea8000000000000000000000000000000001943ce22cdb2387bd5796950dc95d1ace4012ab9bb4afb46223760230c1709e075f1ae76d6b3f2e947ba6b16d458ccd1000000000000000000000000000000001271205227c7aa27f45f20b3ba380dfea8b51efae91fd32e552774c99e2a1237aa59c0c43f52aad99bba3783ea2f36a4000000000000000000000000000000001407ffc2c1a2fe3b00d1f91e1f4febcda31004f7c301075c9031c55dd3dfa8104b156a6a3b7017fccd27f81c2af222ef000000000000000000000000000000000a29e38da2d42fd4712052800c7c8dd6e94fd9f506e946068aaac799d60b94c2d7515769ffdd32ea95d3910330ec47de000000000000000000000000000000000c60dae92451206390e30b5daa7151d63624dee496753c87dd54eadc92dc9602081fae02a1a53bac97e984a571923a5d00000000000000000000000000000000085f4fda4c72328895f20c683cb49603a37ff2c43d62f66602506dad5b8d1daebfbac7a7db3f50ccf4dfff277deb105c0000000000000000000000000000000005674d005457e0fe1f0fd978d63996c5f3d29f9149ee4eb04c464742dd329ccaef5e5f6b896d986ddfc9f1b2a3aec13100000000000000000000000000000000071bc66d6e2d244afc4a5ce4da1dce3d0c22c303ba61310fdf57843bbd97763ef496833dfa99d14be084bb1a039bb2da0000000000000000000000000000000012c22e047b0af8e2f4bf3bd3633ef0f8264004ca8ea5677a468857a1762f815235a479e53f4ad4741ffda3fb855021c900000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "bls_pairing_10paircheckstrue", - "Gas": 495000, + "Gas": 363700, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000fd75ebcc0a21649e3177bcce15426da0e4f25d6828fbf4038d4d7ed3bd4421de3ef61d70f794687b12b2d571971a550000000000000000000000000000000004523f5a3915fc57ee889cdb057e3e76109112d125217546ccfe26810c99b130d1b27820595ad61c7527dc5bbb132a9000000000000000000000000000000000186a1da343cacf1815b9c8b6c807f536249dbfdb59d77bf4920ad2198a0d83ada21f7c39de6f06a5599f22571cab288d000000000000000000000000000000000ba1ec44f95121bd622932b84bbb4b3d279f69c494ee44db68e3165c86b627ba5e397ee197313fb5b775972798997332000000000000000000000000000000000783e7493e9fb106fa0d085e7c03eb816468d12c65d9b77643ed07c02583d491f4db5db44e565d50d8ccaa9ad8f7f8e80000000000000000000000000000000010a6a5fd90cd5f4fb6545814f5df065b001074bb3f29f649dd2612815df3a19a320f7754dd3d458e48e7fb1b4953978f000000000000000000000000000000000345dd80ffef0eaec8920e39ebb7f5e9ae9c1d6179e9129b705923df7830c67f3690cbc48649d4079eadf5397339580c00000000000000000000000000000000083d3baf25e42f2845d8fa594dda2e0f40a4d670dda40f30da0aff0d81c87ac3d687fe84eca72f34c7c755a045668cf100000000000000000000000000000000129c4945fe62538d2806fff056adac24f3bba8e17e42d82122affe6ad2123d68784348a79755f194fde3b3d448924032000000000000000000000000000000000528590e82f409ea8ce953f0c59d15080185dc6e3219b69fcaa3a2c8fc9d0b9e0bc1e75ec6c52638e6eaa4584005b5380000000000000000000000000000000018dc3e893f74729d27dd44f45a5a4f433dcd09a3b485e9d1c2bd0eb5e0e4c9024d928ddc426fdecae931e89885ee4db4000000000000000000000000000000000d6ee02e1fc7e52a8e1ef17e753065882c6fcc14da61da7ffe955fe84a9d2af9ba57562c69db3088652931bf124b0d5300000000000000000000000000000000051f8a0b82a6d86202a61cbc3b0f3db7d19650b914587bde4715ccd372e1e40cab95517779d840416e1679c84a6db24e000000000000000000000000000000000b6a63ac48b7d7666ccfcf1e7de0097c5e6e1aacd03507d23fb975d8daec42857b3a471bf3fc471425b63864e045f4df00000000000000000000000000000000131747485cce9a5c32837a964b8c0689ff70cb4702c6520f2220ab95192d73ae9508c5b998ffb0be40520926846ce3f100000000000000000000000000000000101e147f8bd7682b47b3a6cc0c552c26ce90b9ce0daef21f7f634b3360483afa14a11e6745e7de01a35c65b396a1a12700000000000000000000000000000000090ca61ed16c4c1e80acfef736eea2db0d7425d9110cb53e6c4a2aa3f8a59ee6c60bdce8df5825011066d44bef84d29600000000000000000000000000000000028207394adcbf30250ac21a8f1db6283580bc5e39159930552e5edb25e6215c66b6450296edc80dbc3a2acd125dab160000000000000000000000000000000019bef05aaba1ea467fcbc9c420f5e3153c9d2b5f9bf2c7e2e7f6946f854043627b45b008607b9a9108bb96f3c1c089d3000000000000000000000000000000000adb3250ba142db6a748a85e4e401fa0490dd10f27068d161bd47cb562cc189b3194ab53a998e48a48c65e071bb541170000000000000000000000000000000016cfabbe60d1e55723a0ff72cf802f2d1cf13ed131e17729adc88522a657f320a336078a9399c8e61a3bbde3d52fd3640000000000000000000000000000000009aa9a3c2a6d49d286aa593c6ff644f1786fa9ae471bdb3fe70b150a9ed7584eaa886ac057c30005c3642f65ad5581cc0000000000000000000000000000000001d417894c0cce924955a795b188b27951f8438a5485404b921a42fa79dea03c10e29d0390df2f34d7be13f360a7fada00000000000000000000000000000000189b0b3a04e6c613899d51231dbf0cba6a8a8f507ebed99d24fba7ebac6c97a8859ffde88e6d95c1a9d6b4f0a8f3c417000000000000000000000000000000000d9e19b3f4c7c233a6112e5397309f9812a4f61f754f11dd3dcb8b07d55a7b1dfea65f19a1488a14fef9a414950835820000000000000000000000000000000009d0d1f706f1a85a98f3efaf5c35a41c9182afc129285cf2db3212f6ea0da586ca539bc66181f2ccb228485dd8aff0a70000000000000000000000000000000016cad7807d761f2c0c6ff11e786a9ed296442de8acc50f72a87139b9f1eb7c168e1c2f0b2a1ad7f9579e1e922d0eb309000000000000000000000000000000000d3577c713fcbc0648ca8fbdda0a0bf83c726a6205ee04d2d34cacff92b58725ca3c9766206e22d0791cb232fa8a9bc3000000000000000000000000000000000f5ea1957be1b9ca8956ba5f6b1c37ea72e2529f80d7a1c61df01afcc2df6f99ced81ac0052bd0e1e83f09d76ad8d33b000000000000000000000000000000000aabced4e2b9e4a473e72bf2b1cc0ce7ab13de533107df2205ed9e2bb50fa0217e6a13abcd12fce1bda1ccf84dac237a00000000000000000000000000000000073eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086000000000000000000000000000000001825bacd18f695351f843521ebeada20352c3c3965626f98bc4c68e6ff7c4eed38b48f328204bbb9cd461511d24ebfb3000000000000000000000000000000000029ea93c2f1eb48b195815571ea0148198ff1b19462618cab08d037646b592ecab5a66b4bc660ffd02d1b996ca377da000000000000000000000000000000000bb319a4550c981ee89e3c7e6dcc434283454847792807940f72fd2dbf3625b092e0a0c03e581fd9bd9cf74f95ccef15000000000000000000000000000000000abb072b8d9011e81c9f5b23ba86fdb6399c878aa4eadee45fb2486afe594dffc53be643598a23e5428894a36f5ac3ce0000000000000000000000000000000005d04aa0b644faae17d4c76a14aa680c69fdfc6b59fee3ef45641f566165fced60cbbda4ca096e132bb6f58ab4516686000000000000000000000000000000001098f178f84fc753a76bb63709e9be91eec3ff5f7f3a5f4836f34fe8a1a6d6c5578d8fd820573cef3a01e2bfef3eaf3a000000000000000000000000000000000ea923110b733b531006075f796cc9368f2477fe26020f465468efbb380ce1f8eebaf5c770f31d320f9bd378dc758436000000000000000000000000000000001065f2a2d29a997343765f239c99a018490eced40ac42fc93217dfe20d8b43ee2215f65166aff483b3dc042c5a43b196000000000000000000000000000000000766e4c66f4a442ff1f61a7a4d197d2b47dd226d0e7822a9b065108cfc643cd3f3d5ae59ed2ce4cde13fd9260bb5b7cc0000000000000000000000000000000012251cc6abbabeb7bbe1fdd63eaee10832a748fff24f7e3fdccaea87facb6e99f2e0407a38f27f90450a471b873104620000000000000000000000000000000011181e08c8fba91271adfee9d31681f8412ab7a3f754f7ba4709024c0ad2287e32dd455d71a296b4838072a8ab9d96f2000000000000000000000000000000001252a4ac3529f8b2b6e8189b95a60b8865f07f9a9b73f98d5df708511d3f68632c4c7d1e2b03e6b1d1e2c01839752ada0000000000000000000000000000000002a1bc189e36902d1a49b9965eca3cb818ab5c26dffca63ca9af032870f7bbc615ac65f21bed27bd77dd65f2e90f53580000000000000000000000000000000005a7445f55add1ed5c143424ceef3d594280e316c9441a8e68c3ad97377141d015bf878bdfcf0df9fbcd0529f4e8100800000000000000000000000000000000192b52ba08ed509fc84d5775a7182498fd1ff80941d673c53470c9c9f1192f9c0057d68a1dfee0c68fe5df3625cc43bf000000000000000000000000000000000d3fcaf2f727e0eb32c65da9b910dc681b948dda874d0db6f6ed3f063430fbf073385a9a14c2dd78568726124e2b3ea8000000000000000000000000000000001943ce22cdb2387bd5796950dc95d1ace4012ab9bb4afb46223760230c1709e075f1ae76d6b3f2e947ba6b16d458ccd1000000000000000000000000000000001271205227c7aa27f45f20b3ba380dfea8b51efae91fd32e552774c99e2a1237aa59c0c43f52aad99bba3783ea2f36a4000000000000000000000000000000001407ffc2c1a2fe3b00d1f91e1f4febcda31004f7c301075c9031c55dd3dfa8104b156a6a3b7017fccd27f81c2af222ef000000000000000000000000000000000a29e38da2d42fd4712052800c7c8dd6e94fd9f506e946068aaac799d60b94c2d7515769ffdd32ea95d3910330ec47de000000000000000000000000000000000c60dae92451206390e30b5daa7151d63624dee496753c87dd54eadc92dc9602081fae02a1a53bac97e984a571923a5d00000000000000000000000000000000085f4fda4c72328895f20c683cb49603a37ff2c43d62f66602506dad5b8d1daebfbac7a7db3f50ccf4dfff277deb105c0000000000000000000000000000000005674d005457e0fe1f0fd978d63996c5f3d29f9149ee4eb04c464742dd329ccaef5e5f6b896d986ddfc9f1b2a3aec13100000000000000000000000000000000071bc66d6e2d244afc4a5ce4da1dce3d0c22c303ba61310fdf57843bbd97763ef496833dfa99d14be084bb1a039bb2da0000000000000000000000000000000012c22e047b0af8e2f4bf3bd3633ef0f8264004ca8ea5677a468857a1762f815235a479e53f4ad4741ffda3fb855021c900000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_pairing_10pairchecksfalse", - "Gas": 495000, + "Gas": 363700, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_0", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed200000000000000000000000000000000192fa5d8732ff9f38e0b1cf12eadfd2608f0c7a39aced7746837833ae253bb57ef9c0d98a4b69eeb2950901917e99d1e0000000000000000000000000000000009aeb10c372b5ef1010675c6a4762fda33636489c23b581c75220589afbc0cc46249f921eea02dd1b761e036ffdbae220000000000000000000000000000000002d225447600d49f932b9dd3ca1e6959697aa603e74d8666681a2dca8160c3857668ae074440366619eb8920256c4e4a00000000000000000000000000000000174882cdd3551e0ce6178861ff83e195fecbcffd53a67b6f10b4431e423e28a480327febe70276036f60bb9c99cf7633", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_1", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f000000000000000000000000000000000a69d6d9f79e19b38e6bf5a245dc820bddbdfe038d50932f76d0e4629d759f8ca6d573fcfc39256305daedf452f9fdf40000000000000000000000000000000015f5949369e58487afcecf8018775d1b0a73e913bf77e13d2e5a843bbbeba7d1978ca27ae8bfc87d30f567dd396b980e00000000000000000000000000000000182198bb38a0353b8db25389e56ab0d8679a1bda008a65dad77e4c95bc6804f6311eb16c761e1a5e2a5f87cfada49fa4000000000000000000000000000000000eb5483959e98c30e71db52615f63521378b156f142d46f3bb285b94aef39d80feacec335b797c5a68dc17ba89d43e0f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_2", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e4000000000000000000000000000000000286f09f931c07507ba4aafb7d43befe0b1d25b27ecc9199b19a9dc20bc7ec0329479ef224e00dece67ec0d61f1ca5ae0000000000000000000000000000000014e6ed154b5552be5c463b730b2134f83e0071dcdadfaa68e6c7c7f6e17dabb7daf06e409177bc4b38cfdb8248157618000000000000000000000000000000000f145e998dc6eb0c2b2be87db62949c7bfa63e8b01c8634248010fd623cfaec5d6c6c193331440957d333bf0c988b7b10000000000000000000000000000000002a1ab3eea343cfdea5779f64b3bddbf0769aded60e54a7507338f044310ba239430663394f110e560594d6042a99f1c", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_3", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d3000000000000000000000000000000000d1007ca90451229d3780d66d3aed7c9d8fc82e9d45549e8586600e38eb6763f3c466e2f6ba6ba1dafd8f00cc452dda20000000000000000000000000000000001d017d920a262b6d6597bab532f83270f41526409510e80278d1c3595ceabb9ceba8ae32b1817297ff78ea7a0d252e8000000000000000000000000000000000935b7a59d2e51bbb2f9b54ccb06ebee9d189fa82f0e97d10c8020badb3de7fe15731b5895faed8cad92ae76e2e1b649000000000000000000000000000000000792dadd48a20040ad43facedc109747411895180813349d41d0e5b389176bfb15895d41665be8d1afa80835ef818eca", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_4", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f9000000000000000000000000000000000095353ad699b89ac82ca7ef631775b2b3a6e3ed8dd320440cdb929baa428e63cb902a83857cc0e2621470544c69e84aa000000000000000000000000000000000892559ade1060b0eef2cbc1c74de62a7ff076a3621e5f0f159672a549f1201f2ffb3ac12c8b12cb86ae3e386c33e219000000000000000000000000000000000750df4632a7126ddb08658a4001f949b9764d9cc43a9393cc55d8fdbb15d4a1186dd87a6433d111888a7804540ad9fc0000000000000000000000000000000017554bd444665df044b91b0b2614017bbfcd7acc7f8c5a16cea2861235578ce2b27dcced9fba234999fa478cd3f6e42d", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_5", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1b00000000000000000000000000000000175dadb6ee656ec6aebf8d0e5edaee3f119c74e0ea64e374be9e8ab9fd3d085fceeedf4ed8de676ebe9065d83b0542ad0000000000000000000000000000000005cd6a875329c23e4918976cf997e93e403957acfc999f8159a630d21ab6f1762925c063784237262bedc82402ad81bb0000000000000000000000000000000003274bcb8db35e50164d136c2a98b5a6d2fb5f9767d0ee11c1358bf7ca5ed96d9122f8c1051ba3c658cc89777d03dfa5000000000000000000000000000000000380a240443dff85b6542f75db28b87c39e278cdb8d9627efbbc63b229e6ce783f6fb0114c8e91c2fd6ea71c95bb99a4", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_6", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442a000000000000000000000000000000000834cf1b4149d100c41b1bca0495e455002eb6596bddcb94ae48d0c65957e8b313372f8e0d6e57504664b266f38293150000000000000000000000000000000000de2875fbd14760bac4c2cc7d3f239177efe9f7f61f767be420d44f24c9fb863efd60dcd732986db8c5b72470617ea60000000000000000000000000000000000bc9535ebf11c2dcc8c7d3bcd09d7d14035635fccb5fddb7df29ce8855e79f99809781d6ffbbcb33d1227314609abee00000000000000000000000000000000039bbfb4d969d702255e3be7f255a97529a19687ce38cb70637c37894d4102591feef428b0afe8c9ef50310ae3b83091", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_7", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795000000000000000000000000000000000fc09c241899fa6e8cc3b31830e9c9f2777d2bc6758260c9f6af5fce56c9dc1a8daedb5bcb7d7669005ccf6bfacf71050000000000000000000000000000000018e95921a76bc37308e2f10afb36a812b622afe19c8db84465ab8b3293c7d371948ee0578dbb025eed7ed60686109aa0000000000000000000000000000000001558cdfbac6ea2c4c1f4b9a2e809b19e9f4ba47b78d2b18185ed8c97c2f9c2990beadc78b85c123b4c3c08d5c5b3bbef000000000000000000000000000000000ea4dfdd12b9a4b9a3172671a6eafed7508af296813ec5700b697d9239ae484bcf7ab630e5b6830d6d95675be5174bb2", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_8", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a1900000000000000000000000000000000000b36d8fb9bd156f618ab8049d41dfe0698218764c0abb10e12fae43c8810b8e2a5201364e2778f6f433b199bb8f9a6800000000000000000000000000000000000707eb15411b63722b4308c0ed4288320078d2463ae659ad4fb3f9ef8124f379df92d64e077403e50727388adb59ac00000000000000000000000000000000158e1249d5b91614924acb23899c6bae408697dec0982c10d0459746499f4e6739afb9d5129568106ed1a1caefeaa9640000000000000000000000000000000019e841562e4aa75321143f8ce1e5ec6158fa5cb8b98c839a486188260c18ee8a7600930f23aa39eac2eb520d6a0fba90", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_9", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac94300000000000000000000000000000000186a9661d6fb539e8687ac214301b2d7623caedd76f4055089befba6ef2c96263d810921ad7783d229f82783c9def424000000000000000000000000000000000447f3e20caa1f99fbaccab7bde2bd37fe77cea691ebf2b9499f95bbbb77afe72b7039eb0c05970b61360fcf8ade73730000000000000000000000000000000005e11f828eda86c10a1d7929def547ac06885da278afae59c5d95453caf0a2d8ed186fa7c6d0a7ab6e9142cfa4b338190000000000000000000000000000000003d954e61b6ab71042b19e804efccd4956b56662f27f70a9255cec0c464b86c0e83721ad3785dec62dd4a9dd3d6d5d53", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_10", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e0000000000000000000000000000000002b94534aa0ba923bda34cbe92b3cd7a3e263741b120240ff5bdb8b718f094d3867e3fcabeab4a7be39c8f8c4fdd10d900000000000000000000000000000000048711cf6a82534d64d072355cb8fe647808e7e8b2d9ac9ed52eb7fe121647a721dd1234c71ecd163d91701eb7331cac00000000000000000000000000000000141ef2e23a1ecc7ef2ed3ea915492e79cfffe60b5e0de8441e878bd0653843d79c724e3c5ebe2321361df99f8932ddc200000000000000000000000000000000085513b4009f29b3e00a91c2c4be418368560802ba4194cbd2f4fa3d72a55fcae547014434514a8b2a8fe3e0b28d2773", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_11", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276b0000000000000000000000000000000009143507a24313ee33401955fc46562c9b20c9917df3b40ccbd7ed43b1349d4551cfd98a4976d6fec5fc289460c8d89900000000000000000000000000000000060566b79df5cc975e669da8ca3a7fa91bf3f5c9fb871c3d62f4a3e79dbc341b89d38b588e5414bc385d5e3cbf3ab9310000000000000000000000000000000016bf40b8cc4c01a87aafae0c4439b623a51ba9a383756a550b69d627d6f45209f0d87e4f9be9edff35c986f7b9c49e3f000000000000000000000000000000001842d9172bce51a164fbdbdb108d0faae07e4642f21c80e40ac31e737657472ae3dfe552b65349629c210a068c4afc0e", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_12", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a5787681000000000000000000000000000000000ab19bbddd661e9db8fe4cb307ecebdc5e03efbb95c5b44716c7075bd60efcfc67de0bfd7c46ad989a613946c90a4c1000000000000000000000000000000000120800e7f344cda816299fa37f603ade06beb3b10907f5af896d6b4e42f7f865b756f14164db84411c56cb2ea81f60be000000000000000000000000000000000f688ddd257e66362af1437b6922d3397a7c3dd6dea6bca8ebd6375e75bf2de40bc287cbf3434388191e56b92949c83b0000000000000000000000000000000005252465784aff8c1c707da58b5808c69583bf852d68f96912bc53f8dae4536b09ccbbd25a49d9e744118992b92b6792", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_13", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f768000000000000000000000000000000000e3165efe00f69aee84ac56d2161f07c017abfaadeaad34f8c96799d68bae0e6f9b557bbf9137e7826f49f29c58d1ef9000000000000000000000000000000000de0dce7ea371ad60f21f2cb61cb582b5072408a7efc91edf05b36a1a3b58fd9e6cf808d75157eedccc8f1c93a8ae07d0000000000000000000000000000000016d911943d80427385ebac1d1b293914a9e4dd9db06c1d6a758192d63c8fc9368e02eae7fb0e3a7859408f215cfa76ca0000000000000000000000000000000007bfdc6afb8acec625e50ecbc08a5cdb7862b795866323679885ba5cba3fd51f181078e03fe35e96e6383c077eed1bf5", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_14", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931d000000000000000000000000000000000a68dccbe3452731f075580fe6102b8ee5265007ee19c56d95bcb096a3a6ac444f4145b980f41afcb0a865853b279bc600000000000000000000000000000000164767ea55a9038ac2dd254d8c8a4970dba93dacdf5416aecaa407914719cab165e7a32784b2c41652a86358737d831f000000000000000000000000000000000da9441fbc6578c85fdeca49082c9ebbf183de894d67c65158380ee56132d3cdb44b100d72b6d3b82688defb75d2aa390000000000000000000000000000000017d570e4f6e46550679d5d12c347414da207060f594620e2f8db66df8e0b06c912290b207a268e782d4b45db19a199db", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_15", - "Gas": 108000, + "Gas": 70300, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd8000000000000000000000000000000000118cd94e36ab177de95f52f180fdbdc584b8d30436eb882980306fa0625f07a1f7ad3b4c38a921c53d14aa9a6ba5b8d600000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_16", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000043c4ff154778330b4d5457b7811b551dbbf9701b402230411c527282fb5d2ba12cb445709718d5999e79fdd74c0a67000000000000000000000000000000000013a80ede40df002b72f6b33b1f0e3862d505efbe0721dce495d18920d542c98cdd2daf5164dbd1a2fee917ba943debe0000000000000000000000000000000001c2d8d353d5983f22a5313ddd58fdc0d9c994b2915dbc87a9b65b7b98ff00b62e140a27dc322d42b3ad190c1b3728dd0000000000000000000000000000000010412f3625947b38bb380a6ed059f1677b7a7afcb91517837c563dadd0e285b95740a200ddff6570d4d92bb636b625bb0000000000000000000000000000000015f4f9a480a57bd1b2388532ab045a1ba93d2f6589a3022c585fe06a1d611165c99d70be06251812405c9c37d6e9f7730000000000000000000000000000000001a78e6c5062a6634a56e9853ff5afacb2e7cf31fd0ea5f0d8c8ac6174c88133cf2f63450ec4590544c9a0e37daac1f900000000000000000000000000000000043c4ff154778330b4d5457b7811b551dbbf9701b402230411c527282fb5d2ba12cb445709718d5999e79fdd74c0a6700000000000000000000000000000000018c690fc5571f69793ec3c82915ac9513726ec891312f4f11dd3ba0ee95cc98b50d925099b0642e58a106e8456bbcbed0000000000000000000000000000000001c2d8d353d5983f22a5313ddd58fdc0d9c994b2915dbc87a9b65b7b98ff00b62e140a27dc322d42b3ad190c1b3728dd0000000000000000000000000000000010412f3625947b38bb380a6ed059f1677b7a7afcb91517837c563dadd0e285b95740a200ddff6570d4d92bb636b625bb0000000000000000000000000000000015f4f9a480a57bd1b2388532ab045a1ba93d2f6589a3022c585fe06a1d611165c99d70be06251812405c9c37d6e9f7730000000000000000000000000000000001a78e6c5062a6634a56e9853ff5afacb2e7cf31fd0ea5f0d8c8ac6174c88133cf2f63450ec4590544c9a0e37daac1f9", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_17", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009f9a78a70b9973c43182ba54bb6e363c6984d5f7920c1d347c5ff82e6093e73f4fb5e3cd985c9ddf9af936b16200e880000000000000000000000000000000008d7489c2d78f17b2b9b1d535f21588d8761b8fb323b08fa9af8a60f39b26e98af76aa883522f21e083c8a14c2e7edb6000000000000000000000000000000000818e567aea83eaf3142984bb736b443743659626c407987b604a30c79756081fa6ae6beeb2e6c652dbfe9cf62d44e3900000000000000000000000000000000193f0317305fde1046acda2c9491e376aa67244f68ef6495845d049e1293082af91f880be935d9d8ad0e25ad918caae200000000000000000000000000000000109224b8178be58ea4e4a194ca66bef9d14f6fc2c625d25feaa4f32e0f4d72d91024d96839bc96e6a624c5ad6221bd94000000000000000000000000000000000e42decf8a987efaeb4ede37236b637e61249bf6245679be7fd4d633e2d814ed4748b73890ad3c4fcbcfb4960cb67ae70000000000000000000000000000000009f9a78a70b9973c43182ba54bb6e363c6984d5f7920c1d347c5ff82e6093e73f4fb5e3cd985c9ddf9af936b16200e88000000000000000000000000000000001129c94e0c06f51f1f808a62e42a5449dd159289c14a09c4cc382c91bcfe878b6f3555767c310de1b1c275eb3d17bcf5000000000000000000000000000000000818e567aea83eaf3142984bb736b443743659626c407987b604a30c79756081fa6ae6beeb2e6c652dbfe9cf62d44e3900000000000000000000000000000000193f0317305fde1046acda2c9491e376aa67244f68ef6495845d049e1293082af91f880be935d9d8ad0e25ad918caae200000000000000000000000000000000109224b8178be58ea4e4a194ca66bef9d14f6fc2c625d25feaa4f32e0f4d72d91024d96839bc96e6a624c5ad6221bd94000000000000000000000000000000000e42decf8a987efaeb4ede37236b637e61249bf6245679be7fd4d633e2d814ed4748b73890ad3c4fcbcfb4960cb67ae7", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_18", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010fcfe8af8403a52400bf79e1bd0058f66b9cab583afe554aa1d82a3e794fffad5f0e19d385263b2dd9ef69d1154f10a000000000000000000000000000000000aba6a0b58b49f7c6c2802afd2a5ed1320bf062c7b93135f3c0ed7a1d7b1ee27b2b986cde732a60fa585ca6ab7cc154b000000000000000000000000000000000ca0d865f8c8ce0a476f7a6edb3ce4bd5e6c3a8d905d8fb5a10e66542f4325a9963c2f8d96f804f4d295f8993b5204df0000000000000000000000000000000005a966f6254f0ef4f93f082a97abe07db56f00c2ade047d2f0027edef6f00a0dfecaa24d50faa778fa29087302211f7e00000000000000000000000000000000121c51da366557c09af1bbd927521da88dfab3e2e9a95b6effb0a968795486f281f0c887e37f51837557b9e3808987130000000000000000000000000000000001a5524975400b1e88f3fff8dd34dadf5d75564cfc0026df31ee9c2c1d48b0f69a48e1e4a48cc4b7db61f023a79157800000000000000000000000000000000010fcfe8af8403a52400bf79e1bd0058f66b9cab583afe554aa1d82a3e794fffad5f0e19d385263b2dd9ef69d1154f10a000000000000000000000000000000000f46a7dee0cb471ddef3a50670a5bfc443b8455877f1ff602b21faff1eff07fc6bf27930ca2159f01479359548339560000000000000000000000000000000000ca0d865f8c8ce0a476f7a6edb3ce4bd5e6c3a8d905d8fb5a10e66542f4325a9963c2f8d96f804f4d295f8993b5204df0000000000000000000000000000000005a966f6254f0ef4f93f082a97abe07db56f00c2ade047d2f0027edef6f00a0dfecaa24d50faa778fa29087302211f7e00000000000000000000000000000000121c51da366557c09af1bbd927521da88dfab3e2e9a95b6effb0a968795486f281f0c887e37f51837557b9e3808987130000000000000000000000000000000001a5524975400b1e88f3fff8dd34dadf5d75564cfc0026df31ee9c2c1d48b0f69a48e1e4a48cc4b7db61f023a7915780", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_19", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013c5ebfb853f0c8741f12057b6b845c4cdbf72aecbeafc8f5b5978f186eead8685f2f3f125e536c465ade1a00f212b0900000000000000000000000000000000082543b58a13354d0cce5dc3fb1d91d1de6d5927290b2ff51e4e48f40cdf2d490730843b53a92865140153888d73d4af0000000000000000000000000000000002b51851ef3b44481d13f42e5111fa4fec04be0bf6acc7e59dec3a8c8113e5bb7b604c6dbdc5e8eddc2a1ffb81bc2baf0000000000000000000000000000000018ddb483ae75402852b7f285277ff7308ff78a3364cca8b0e0e1fa9182de275fd55c1e8ec3dbde180379c4280787ba8000000000000000000000000000000000170539890c89a4f91acd59efd413b5d1059f0c8fd8718e8f722e865dd106a4eb02e6fb0cd71b34ebc4b94375b52e4dd60000000000000000000000000000000001c2e9392f5d4b75efc5ff10fe97f37e2671cad7e4710765866e92aec99b0130e6ff1314502d069fb7b5f86bfce4300e0000000000000000000000000000000013c5ebfb853f0c8741f12057b6b845c4cdbf72aecbeafc8f5b5978f186eead8685f2f3f125e536c465ade1a00f212b090000000000000000000000000000000011dbce34af6cb14d3e4d49f2482e1b058609f25dca79e2ca48e289ace9d1c8db177b7bc35daad79aa5fdac77728bd5fc0000000000000000000000000000000002b51851ef3b44481d13f42e5111fa4fec04be0bf6acc7e59dec3a8c8113e5bb7b604c6dbdc5e8eddc2a1ffb81bc2baf0000000000000000000000000000000018ddb483ae75402852b7f285277ff7308ff78a3364cca8b0e0e1fa9182de275fd55c1e8ec3dbde180379c4280787ba8000000000000000000000000000000000170539890c89a4f91acd59efd413b5d1059f0c8fd8718e8f722e865dd106a4eb02e6fb0cd71b34ebc4b94375b52e4dd60000000000000000000000000000000001c2e9392f5d4b75efc5ff10fe97f37e2671cad7e4710765866e92aec99b0130e6ff1314502d069fb7b5f86bfce4300e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_20", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000053a12f6a1cb64272c34e042b7922fabe879275b837ba3b116adfe1eb2a6dc1c1fa6df40c779a7cdb8ed8689b8bc5ba800000000000000000000000000000000097ec91c728ae2d290489909bbee1a30048a7fa90bcfd96fe1d9297545867cbfee0939f20f1791329460a4fe1ac719290000000000000000000000000000000011bbc566a10eadf16009c1d2655cfae6adfb0f56f5e55b31dc000414be1b4cee9a0b9f7d9eab4c6829037c327914d5640000000000000000000000000000000009b28329096d8644dfcba6e92477eafff29f7477da4581ce76d1493f03034d7f5d3acaadbe42c76a83ca51db79d456d10000000000000000000000000000000019f75a303fdede5d97f3e521b03ef6b9d7c008d770b59ce3ac38900b340895e008342701ad1b41830b9c010936f4ff1700000000000000000000000000000000161aa1853edbb56fa3bd685c9c6b88e466dfa3c4f194f6774b4d9b1f30b016993bd0d65e8e9d6dea6caa196ff735bd6700000000000000000000000000000000053a12f6a1cb64272c34e042b7922fabe879275b837ba3b116adfe1eb2a6dc1c1fa6df40c779a7cdb8ed8689b8bc5ba800000000000000000000000000000000108248cdc6f503c7bad30eac875d92a75feccbdbe7b5394f8557a92bb12a796430a2c60ca23c6ecd259e5b01e53891820000000000000000000000000000000011bbc566a10eadf16009c1d2655cfae6adfb0f56f5e55b31dc000414be1b4cee9a0b9f7d9eab4c6829037c327914d5640000000000000000000000000000000009b28329096d8644dfcba6e92477eafff29f7477da4581ce76d1493f03034d7f5d3acaadbe42c76a83ca51db79d456d10000000000000000000000000000000019f75a303fdede5d97f3e521b03ef6b9d7c008d770b59ce3ac38900b340895e008342701ad1b41830b9c010936f4ff1700000000000000000000000000000000161aa1853edbb56fa3bd685c9c6b88e466dfa3c4f194f6774b4d9b1f30b016993bd0d65e8e9d6dea6caa196ff735bd67", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_21", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001354dd8a230fde7c983dcf06fa9ac075b3ab8f56cdd9f15bf870afce2ae6e7c65ba91a1df6255b6f640bb51d7fed302500000000000000000000000000000000130f139ca118869de846d1d938521647b7d27a95b127bbc53578c7b66d88d541adb525e7028a147bf332607bd760deac000000000000000000000000000000000ae7289aa9bf20c4a9c807f2b3ac32f0db24e9a0a360c92e5ce4f8253f0e3e7853f771597c8141d705062bef12d4fea80000000000000000000000000000000001d2f610d79110f93145faad2e34f3408316b1dc3a72852e811b324577d9037035e24af25002ddd100cd9283b70ddcad0000000000000000000000000000000012947315d5c0ec670619125eed0de3dd259a008baee4379b82accf2391e70a2bdad264cda04c3bc1b5394a62559fa0ef000000000000000000000000000000001239e687c4d3417c3c9b655035f8d8a649c255f9a8e6f03b785eed0d416a1cd6ef7c8b45563acb4616af24f64dbccac4000000000000000000000000000000001354dd8a230fde7c983dcf06fa9ac075b3ab8f56cdd9f15bf870afce2ae6e7c65ba91a1df6255b6f640bb51d7fed30250000000000000000000000000000000006f1fe4d98675ffc62d4d5dd0af9968faca4d0ef425d56fa31b80aea892820e270f6da17aec9eb83c6cc9f84289ecbff000000000000000000000000000000000ae7289aa9bf20c4a9c807f2b3ac32f0db24e9a0a360c92e5ce4f8253f0e3e7853f771597c8141d705062bef12d4fea80000000000000000000000000000000001d2f610d79110f93145faad2e34f3408316b1dc3a72852e811b324577d9037035e24af25002ddd100cd9283b70ddcad0000000000000000000000000000000012947315d5c0ec670619125eed0de3dd259a008baee4379b82accf2391e70a2bdad264cda04c3bc1b5394a62559fa0ef000000000000000000000000000000001239e687c4d3417c3c9b655035f8d8a649c255f9a8e6f03b785eed0d416a1cd6ef7c8b45563acb4616af24f64dbccac4", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_22", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f76a6dc6da31a399b93f4431bfabb3e48d86745eaa4b24d6337305006e3c7fc7bfcc85c85e2f3514cd389fec4e70580000000000000000000000000000000010e4280374c532ed0df44ac0bac82572f839afcfb8b696eea617d5bd1261288dfa90a7190200687d470992fb4827ff32000000000000000000000000000000001179ee329771b5913d07818e70f6ce5a58d74ea0b573eaa1bd3d97e45d3eeb27fcc7d37dba127af7a38354cb6ff48f7c000000000000000000000000000000000c898abe6eb76ef99f5143cfb8d840a918bcc9096ce25caa45d0bf5d20814cb01b024f1fd2cbecb6bef65d9456070dd90000000000000000000000000000000008e2a4fd746e86f90484f9b9b7b47b6afe5833762e515ccb276c554f00df88dd9aa0fb792c5f419dda0465cfed838e7c0000000000000000000000000000000012b5e6f7070c0045ade96f548ed6428c5030fa20c6f6f37a42fde9dbb5cd01def0fd8585bf8aeef913e7d42b9ef22efa0000000000000000000000000000000003f76a6dc6da31a399b93f4431bfabb3e48d86745eaa4b24d6337305006e3c7fc7bfcc85c85e2f3514cd389fec4e705800000000000000000000000000000000091ce9e6c4bab3ad3d275cf5888387646c3d9bb53ace7bd0c118fce3e44fcd96241b58e5af53978272f56d04b7d7ab79000000000000000000000000000000001179ee329771b5913d07818e70f6ce5a58d74ea0b573eaa1bd3d97e45d3eeb27fcc7d37dba127af7a38354cb6ff48f7c000000000000000000000000000000000c898abe6eb76ef99f5143cfb8d840a918bcc9096ce25caa45d0bf5d20814cb01b024f1fd2cbecb6bef65d9456070dd90000000000000000000000000000000008e2a4fd746e86f90484f9b9b7b47b6afe5833762e515ccb276c554f00df88dd9aa0fb792c5f419dda0465cfed838e7c0000000000000000000000000000000012b5e6f7070c0045ade96f548ed6428c5030fa20c6f6f37a42fde9dbb5cd01def0fd8585bf8aeef913e7d42b9ef22efa", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_23", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009439f061c7d5fada6e5431c77fd093222285c98449951f6a6c4c8f225b316144875bc764be5ca51c7895773a9f1a640000000000000000000000000000000000ebdef273e2288c784c061bef6a45cd49b0306ac1e9faab263c6ff73dea4627189c8f10a823253d86a8752769cc4f8f2000000000000000000000000000000000fe2e61bc8e9085d2b472a6791d4851762d6401fd3e7d3f3ba61620dc70b773f2102df1c9d6f1462144662fb2f15359700000000000000000000000000000000031f160cde626ca11f67613884a977fb5d3248d78ddbf23e50e52c3ba4090268c1f6cd8156fa41d848a482a0ca39eb04000000000000000000000000000000000eb61ba51124be7f3ee9be1488aa83cbd2333aa7e09ae67fef63c890534cb37ca7de3d16046b984e72db21e1f5c57a8a0000000000000000000000000000000006bf6f5d65aa7d19613141018ac8bf5d1e6fe494a9f30da215a2313a0241779006bce33a776aeedae5de5ea6ee5a9b9e0000000000000000000000000000000009439f061c7d5fada6e5431c77fd093222285c98449951f6a6c4c8f225b316144875bc764be5ca51c7895773a9f1a640000000000000000000000000000000000b4322c2fb5d5dd2c65b45f74ca75002c97444d8d4e5680d0369d32d180c93b294e30ef42f21ac274f77ad89633ab1b9000000000000000000000000000000000fe2e61bc8e9085d2b472a6791d4851762d6401fd3e7d3f3ba61620dc70b773f2102df1c9d6f1462144662fb2f15359700000000000000000000000000000000031f160cde626ca11f67613884a977fb5d3248d78ddbf23e50e52c3ba4090268c1f6cd8156fa41d848a482a0ca39eb04000000000000000000000000000000000eb61ba51124be7f3ee9be1488aa83cbd2333aa7e09ae67fef63c890534cb37ca7de3d16046b984e72db21e1f5c57a8a0000000000000000000000000000000006bf6f5d65aa7d19613141018ac8bf5d1e6fe494a9f30da215a2313a0241779006bce33a776aeedae5de5ea6ee5a9b9e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_24", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001478ee0ffebf22708a6ab88855081daba5ee2f279b5a2ee5f5f8aec8f97649c8d5634fec3f8b28ad60981e6f29a091b10000000000000000000000000000000011efaeec0b1a4057b1e0053263afe40158790229c5bfb08062c90a252f59eca36085ab35e4cbc70483d29880c5c2f8c200000000000000000000000000000000196044a5cdbc5300ee837dca745a44379070e9297697f5db28df4a37307cc740abed45cc778a3f4e3b8c9890ab6c3c70000000000000000000000000000000001176f5de6a3577ad67863bd3d9152ab9e8184964c6ac276e95946788f5a76394047580077c0971d874a40d510eb0443e00000000000000000000000000000000147dd55dff69213c5760e8d22b700dd7a9c7c33c434a3be95bd5281b97b464fb934a3dff7c23f3e59c5d8d26faa426bf0000000000000000000000000000000019efcf03ddb0934b0f0dba3569809d5b48b863d50d3be4973b504244414e1e1db56adff51d33265ce102b320c552781f000000000000000000000000000000001478ee0ffebf22708a6ab88855081daba5ee2f279b5a2ee5f5f8aec8f97649c8d5634fec3f8b28ad60981e6f29a091b100000000000000000000000000000000081162fe2e65a642993ba283df9bc8d60bfe495b2dc5623f0467c87bc7570980be2654c8cc8838fb362c677f3a3cb1e900000000000000000000000000000000196044a5cdbc5300ee837dca745a44379070e9297697f5db28df4a37307cc740abed45cc778a3f4e3b8c9890ab6c3c70000000000000000000000000000000001176f5de6a3577ad67863bd3d9152ab9e8184964c6ac276e95946788f5a76394047580077c0971d874a40d510eb0443e00000000000000000000000000000000147dd55dff69213c5760e8d22b700dd7a9c7c33c434a3be95bd5281b97b464fb934a3dff7c23f3e59c5d8d26faa426bf0000000000000000000000000000000019efcf03ddb0934b0f0dba3569809d5b48b863d50d3be4973b504244414e1e1db56adff51d33265ce102b320c552781f", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_25", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000150d43c64cb1dbb7b981f455e90b740918e2d63453ca17d8eeecb68e662d2581f8aa1aea5b095cd8fc2a941d6e2728390000000000000000000000000000000006dc2ccb10213d3f6c3f10856888cb2bf6f1c7fcb2a17d6e63596c29281682cafd4c72696ecd6af3cce31c440144ebd10000000000000000000000000000000005d8edbabf37a47a539d84393bb2747d0a35a52b80a7c99616c910479306e204e5db1f0fa3fe69f35af3164c7e5726b50000000000000000000000000000000005015082d6975649fbc172035da04f8aeb6d0dd88fdfac3fbd68ec925dc199413ed670488dc6588f9bd34c4ff527f149000000000000000000000000000000001312d53088ca58dfc325772b8dc0e1b20cebf7b2d5b6b4c560759987b44060bf4a59a68d1a5623bbb3cc5b0bc3986b810000000000000000000000000000000012110cd462c6fabf04f67d652639d19640c46f51aadd6c4f9a6dd7806cffb6192d95c198f4c8284151feaa2e2a0dbc1f00000000000000000000000000000000150d43c64cb1dbb7b981f455e90b740918e2d63453ca17d8eeecb68e662d2581f8aa1aea5b095cd8fc2a941d6e272839000000000000000000000000000000001324e51f295ea95adedc9730dac2e1ab6d85838840e3955103d76677ce9a7359215f8d954286950bed1be3bbfebabeda0000000000000000000000000000000005d8edbabf37a47a539d84393bb2747d0a35a52b80a7c99616c910479306e204e5db1f0fa3fe69f35af3164c7e5726b50000000000000000000000000000000005015082d6975649fbc172035da04f8aeb6d0dd88fdfac3fbd68ec925dc199413ed670488dc6588f9bd34c4ff527f149000000000000000000000000000000001312d53088ca58dfc325772b8dc0e1b20cebf7b2d5b6b4c560759987b44060bf4a59a68d1a5623bbb3cc5b0bc3986b810000000000000000000000000000000012110cd462c6fabf04f67d652639d19640c46f51aadd6c4f9a6dd7806cffb6192d95c198f4c8284151feaa2e2a0dbc1f", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_26", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f46bb86e827aa9c0c570d93f4d7d6986668c0099e4853927571199e1ce9e756d9db951f5b0325acafb2bf6e8fec2a1b0000000000000000000000000000000006d38cc6cc1a950a18e92e16287f201af4c014aba1a17929dd407d0440924ce5f08fad8fe0c50f7f733b285bf282acfc00000000000000000000000000000000117fd5016ddb779a6979d2bffe18032d9a5cdc5a6c7feeaa412381983d49ab894cb067f671163ccbe6225c3d85219db6000000000000000000000000000000000dcf01077dcce35c283bea662f4e4d16f871717eb78e630d9f95a200cc104fe67b0d69d95f6704d9812b46c92b1bc9de00000000000000000000000000000000121f212cd7251697ef6a7e3aa93eb0d7d0157cf1247d4411430c36c7277bf8acfccc4ed8590b5e8d0f760e0e4ed7e95a0000000000000000000000000000000007d22d78b486f575e01e21e1239cbedc4628ba7e01ecf4a3459bd78a9716e2969f26ea3f2449685f60397e1ab2aa7352000000000000000000000000000000000f46bb86e827aa9c0c570d93f4d7d6986668c0099e4853927571199e1ce9e756d9db951f5b0325acafb2bf6e8fec2a1b00000000000000000000000000000000132d85236d655190323279a01acc8cbc6fb736d951e3999589f0559cb61ea93e2e1c526ed08ef08046c3d7a40d7cfdaf00000000000000000000000000000000117fd5016ddb779a6979d2bffe18032d9a5cdc5a6c7feeaa412381983d49ab894cb067f671163ccbe6225c3d85219db6000000000000000000000000000000000dcf01077dcce35c283bea662f4e4d16f871717eb78e630d9f95a200cc104fe67b0d69d95f6704d9812b46c92b1bc9de00000000000000000000000000000000121f212cd7251697ef6a7e3aa93eb0d7d0157cf1247d4411430c36c7277bf8acfccc4ed8590b5e8d0f760e0e4ed7e95a0000000000000000000000000000000007d22d78b486f575e01e21e1239cbedc4628ba7e01ecf4a3459bd78a9716e2969f26ea3f2449685f60397e1ab2aa7352", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_27", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010cde0dbf4e18009c94ba648477624bbfb3732481d21663dd13cea914d6c54ec060557010ebe333d5e4b266e1563c631000000000000000000000000000000000fb24d3d4063fd054cd5b7288498f107114ff323226aca58d3336444fc79c010db15094ceda6eb99770c168d459f0da0000000000000000000000000000000000224cbea61c5136987d8dbc8deafa78ae002255c031bb54335bcf99e56a57768aa127506fca1761e8b835e67e88bb4dd0000000000000000000000000000000018cbf072b544df760c051d394ff68ad2dd5a8c731377fa2a5f61e61481ad5b42645704a2d083c7d45ed4774e5448141e000000000000000000000000000000000740b8b7d7bce78a51809713656c94cf98de72887676050f65f74c57cbe574278dd3634c44e057ea95babcc3d230e3c40000000000000000000000000000000006696058a191c7012a4ee7c973c2005ac51af02a85cbb60e3164809a583b4431dda2b59e1c9ceeb652b3ac7021d116a60000000000000000000000000000000010cde0dbf4e18009c94ba648477624bbfb3732481d21663dd13cea914d6c54ec060557010ebe333d5e4b266e1563c631000000000000000000000000000000000a4ec4acf91be994fe45f08dbeb2bbd053275861d11a486693fd6e5bfa3736134396f6b1c3ad146642f2e972ba609d0b000000000000000000000000000000000224cbea61c5136987d8dbc8deafa78ae002255c031bb54335bcf99e56a57768aa127506fca1761e8b835e67e88bb4dd0000000000000000000000000000000018cbf072b544df760c051d394ff68ad2dd5a8c731377fa2a5f61e61481ad5b42645704a2d083c7d45ed4774e5448141e000000000000000000000000000000000740b8b7d7bce78a51809713656c94cf98de72887676050f65f74c57cbe574278dd3634c44e057ea95babcc3d230e3c40000000000000000000000000000000006696058a191c7012a4ee7c973c2005ac51af02a85cbb60e3164809a583b4431dda2b59e1c9ceeb652b3ac7021d116a6", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_28", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008c0a4c543b7506e9718658902982b4ab7926cd90d4986eceb17b149d8f5122334903300ad419b90c2cb56dc6d2fe976000000000000000000000000000000000824e1631f054b666893784b1e7edb44b9a53596f718a6e5ba606dc1020cb6e269e9edf828de1768df0dd8ab8440e053000000000000000000000000000000001522e0a4ccd607f117fc6fc8f9abcd704e9850d96adb95d9bfaab210b76bfb2c5dc75163b922bd7a886541250bc1d8630000000000000000000000000000000018a6e4327d633108a292a51abed43e95230e951e4476dc385ceea9c72ed528bf3e06c42d10cefbd4aa75b134936e4747000000000000000000000000000000001198587188e793ad2ec2fa0fa1d0da9b61ed48444fe6722e523aeac270f17f73f56b1e726ab811bb54a6e42e506d70a20000000000000000000000000000000004bedd94182e0f16c71223ac3d68ab327d28ee0ccdcd2c2db07faf69e1babe3fbf3ba09c28b146eca7ab047b592947030000000000000000000000000000000008c0a4c543b7506e9718658902982b4ab7926cd90d4986eceb17b149d8f5122334903300ad419b90c2cb56dc6d2fe9760000000000000000000000000000000011dc30871a7a9b33e2882f6b24ccd192aad215edfc6c6bd9acd064dff4a43f41b4c212068875e896daf127547bbeca58000000000000000000000000000000001522e0a4ccd607f117fc6fc8f9abcd704e9850d96adb95d9bfaab210b76bfb2c5dc75163b922bd7a886541250bc1d8630000000000000000000000000000000018a6e4327d633108a292a51abed43e95230e951e4476dc385ceea9c72ed528bf3e06c42d10cefbd4aa75b134936e4747000000000000000000000000000000001198587188e793ad2ec2fa0fa1d0da9b61ed48444fe6722e523aeac270f17f73f56b1e726ab811bb54a6e42e506d70a20000000000000000000000000000000004bedd94182e0f16c71223ac3d68ab327d28ee0ccdcd2c2db07faf69e1babe3fbf3ba09c28b146eca7ab047b59294703", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_29", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000159d94fb0cf6f4e3e26bdeb536d1ee9c511a29d32944da43420e86c3b5818e0f482a7a8af72880d4825a50fee6bc8cd8000000000000000000000000000000000c2ffe6be05eccd9170b6c181966bb8c1c3ed10e763613112238cabb41370e2a5bb5fef967f4f8f2af944dbef09d265e00000000000000000000000000000000148b7dfc21521d79ff817c7a0305f1048851e283be13c07d5c04d28b571d48172838399ba539529e8d037ffd1f7295580000000000000000000000000000000003015abea326c15098f5205a8b2d3cd74d72dac59d60671ca6ef8c9c714ea61ffdacd46d1024b5b4f7e6b3b569fabaf20000000000000000000000000000000011f0c512fe7dc2dd8abdc1d22c2ecd2e7d1b84f8950ab90fc93bf54badf7bb9a9bad8c355d52a5efb110dca891e4cc3d0000000000000000000000000000000019774010814d1d94caf3ecda3ef4f5c5986e966eaf187c32a8a5a4a59452af0849690cf71338193f2d8435819160bcfb00000000000000000000000000000000159d94fb0cf6f4e3e26bdeb536d1ee9c511a29d32944da43420e86c3b5818e0f482a7a8af72880d4825a50fee6bc8cd8000000000000000000000000000000000dd1137e592119c134103b9e29e4f14b48387a767d4effae44f807e5b579e7f9c2f60105495f070d0a6ab2410f62844d00000000000000000000000000000000148b7dfc21521d79ff817c7a0305f1048851e283be13c07d5c04d28b571d48172838399ba539529e8d037ffd1f7295580000000000000000000000000000000003015abea326c15098f5205a8b2d3cd74d72dac59d60671ca6ef8c9c714ea61ffdacd46d1024b5b4f7e6b3b569fabaf20000000000000000000000000000000011f0c512fe7dc2dd8abdc1d22c2ecd2e7d1b84f8950ab90fc93bf54badf7bb9a9bad8c355d52a5efb110dca891e4cc3d0000000000000000000000000000000019774010814d1d94caf3ecda3ef4f5c5986e966eaf187c32a8a5a4a59452af0849690cf71338193f2d8435819160bcfb", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_30", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad6242000000000000000000000000000000000353d6521a17474856ad69582ce225f27d60f5a8319bea8cefded2c3f6b862d76fe633c77ed8ccdf99d2b10430253fc8000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c0533455013242330000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad62420000000000000000000000000000000016ad3b981f689f51f46e3e5e166986e4e71655dcc1e928327751ffdcfff8934caec5cc37327b3320202c4efbcfda6ae3000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c053345501324233", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_31", - "Gas": 151000, + "Gas": 102900, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff170000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000cbcd06a1c576af16d0d77ff8bcc3669a486d044cc7b85db03661a92f4c5c44a28d028521dfcfc292d8ecd05aed6ab940000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff170000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f00000000000000000000000000000000153ba4ab4fecc724c843b8f78db2db1943e91051b8cb9be2eb7e610a570f1f5925b7981334951b505cce1a3992ff05c9000000000000000000000000000000000c1e79925e9ebfd99e5d11489c56a994e0f855a759f0652cc9bb5151877cfea5c37896f56b949167b9cd2226f14333dd", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_32", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c8129292540000000000000000000000000000000013a3d49e58274c2b4a534b95b7071b6d2f42b17b887bf128627c0f8894c19d3d69c1a419373ca4bd1bb6d4efc78e1d3f000000000000000000000000000000001755d8a095e087ca66f8a118e0d2c7d5e4d8427dda8fe3049080f4aff12a8746f8c2679c310f4be0d94c5bef0414a7a600000000000000000000000000000000069c84c6419ed5c0441975ee8410065a56c65f07a4b545ff596b657dc4620c7405fd4d092b281e272773d2281a6359a8000000000000000000000000000000000e751ccbd475fe7eda1c62df626c1d37e8ae6853cc9b2109beef3e8c6f26d41a5e4e0a91bbc3371c7ab6ba780b5db41600000000000000000000000000000000184097644c9b44d543ebc0934825610590cc9f8b17ed08e9c06592bf85591d2702b18cf48a70b378926057e541eb8ac50000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c81292925400000000000000000000000000000000065d3d4be1589a6f00c85c208c44916a35349a096b09219704b4c31861ef58e6b4ea5be57a175b429e482b1038718d6c000000000000000000000000000000001755d8a095e087ca66f8a118e0d2c7d5e4d8427dda8fe3049080f4aff12a8746f8c2679c310f4be0d94c5bef0414a7a600000000000000000000000000000000069c84c6419ed5c0441975ee8410065a56c65f07a4b545ff596b657dc4620c7405fd4d092b281e272773d2281a6359a8000000000000000000000000000000000e751ccbd475fe7eda1c62df626c1d37e8ae6853cc9b2109beef3e8c6f26d41a5e4e0a91bbc3371c7ab6ba780b5db41600000000000000000000000000000000184097644c9b44d543ebc0934825610590cc9f8b17ed08e9c06592bf85591d2702b18cf48a70b378926057e541eb8ac50000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c8129292540000000000000000000000000000000013a3d49e58274c2b4a534b95b7071b6d2f42b17b887bf128627c0f8894c19d3d69c1a419373ca4bd1bb6d4efc78e1d3f000000000000000000000000000000001755d8a095e087ca66f8a118e0d2c7d5e4d8427dda8fe3049080f4aff12a8746f8c2679c310f4be0d94c5bef0414a7a600000000000000000000000000000000069c84c6419ed5c0441975ee8410065a56c65f07a4b545ff596b657dc4620c7405fd4d092b281e272773d2281a6359a8000000000000000000000000000000000b8bf51e6509e81b70ff44d6e0df8f9f7bc8e33126e9f1b5a8419414878a2209c05df56cf590c8e33f484587f4a1f6950000000000000000000000000000000001c07a85ece4a1c5072fe722fb264bd1d3aaabf9db9809d5a6cb3fe17157d8fd1bfa730a26e34c87279ea81abe141fe6", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_33", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda0000000000000000000000000000000014a461f829e0a76ba89f42eb57dffb4f5544df2008163bd0ea1af824f7ff910b27418a0e4f86cb8046dc1f3139cab9af000000000000000000000000000000000213e5d2d46523203ae07f36fdeb6c304fb86f552fb9adb566711c31262629efb0b1561585f85d2ac7be174682229bd8000000000000000000000000000000000b3336b5a4f7c0d16db9615e77bcdd55b7cb5b5c1591d835f34f5c1f1468e3cef954608667fb97a32e4595f43b845612000000000000000000000000000000001869606dde1688e5ae9f1c466c5897fce7794f3735234b5af1ad3617f0688529499bbdc9f0b911840a3d99fd9c49150d00000000000000000000000000000000001bfd33df4a6059608ada794e03d7456e78317145eb4d5677c00d482ac4cf470053d33583cf602feb67b6f972c9973900000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda00000000000000000000000000000000055caff20f9f3f2ea27c64caeb6bb1880f326c64eb6ed6ee7d15da7bfeb16518f76a75f061cd347f7322e0cec634f0fc000000000000000000000000000000000213e5d2d46523203ae07f36fdeb6c304fb86f552fb9adb566711c31262629efb0b1561585f85d2ac7be174682229bd8000000000000000000000000000000000b3336b5a4f7c0d16db9615e77bcdd55b7cb5b5c1591d835f34f5c1f1468e3cef954608667fb97a32e4595f43b845612000000000000000000000000000000001869606dde1688e5ae9f1c466c5897fce7794f3735234b5af1ad3617f0688529499bbdc9f0b911840a3d99fd9c49150d00000000000000000000000000000000001bfd33df4a6059608ada794e03d7456e78317145eb4d5677c00d482ac4cf470053d33583cf602feb67b6f972c9973900000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda0000000000000000000000000000000014a461f829e0a76ba89f42eb57dffb4f5544df2008163bd0ea1af824f7ff910b27418a0e4f86cb8046dc1f3139cab9af000000000000000000000000000000000213e5d2d46523203ae07f36fdeb6c304fb86f552fb9adb566711c31262629efb0b1561585f85d2ac7be174682229bd8000000000000000000000000000000000b3336b5a4f7c0d16db9615e77bcdd55b7cb5b5c1591d835f34f5c1f1468e3cef954608667fb97a32e4595f43b845612000000000000000000000000000000000197b17c5b695db49c7c8b6fd6f314da7cfdfc4dbe61c76475839c89064870fad5104234c09aee7bafc1660263b6959e0000000000000000000000000000000019e514b65a358640ea90cd3cf547d591f5ff1a13ad99c568ef70c558cbec26dd1e582cc92d849fcfce9749068d361372", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_34", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000016404bd07b6c6480af2d23301940e61817ee2e61fc625c100b31e1b324c369a583b61048dd57ab97b80b1fe6cd64c5c30000000000000000000000000000000004ac6e6077d4eddd0e23f30cfd64b7aa1525c85424224e70c15d7535e02aea7a312ef24ba2dcf70b926acb851da2530c0000000000000000000000000000000006ad07d3e8f45cedfb4279913bf0a29e37604810463d6020b4fa8c8c4977d69cffaa33e1149706f04eb237194dcafa520000000000000000000000000000000002c536dd2f05f4a7eaa33fd884262b22a2ab2a88e7b63cb08ebb67fc0f143da7d6b18dd394c424161f7cf703acdc82f50000000000000000000000000000000002d1d9ff74e20ea9b03c478784f57e7a58a21ca2b1e552319f33305f367f5ae4daf8138505f953db4f86c0ec1d96d5f0000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000003c0c619be1382199bee84862a0ac6bf4c891d22f722b6af5bfef0edd1ed8c7e9af5efb5d3fc546801f3e019329ae4e80000000000000000000000000000000004ac6e6077d4eddd0e23f30cfd64b7aa1525c85424224e70c15d7535e02aea7a312ef24ba2dcf70b926acb851da2530c0000000000000000000000000000000006ad07d3e8f45cedfb4279913bf0a29e37604810463d6020b4fa8c8c4977d69cffaa33e1149706f04eb237194dcafa520000000000000000000000000000000002c536dd2f05f4a7eaa33fd884262b22a2ab2a88e7b63cb08ebb67fc0f143da7d6b18dd394c424161f7cf703acdc82f50000000000000000000000000000000002d1d9ff74e20ea9b03c478784f57e7a58a21ca2b1e552319f33305f367f5ae4daf8138505f953db4f86c0ec1d96d5f0000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000016404bd07b6c6480af2d23301940e61817ee2e61fc625c100b31e1b324c369a583b61048dd57ab97b80b1fe6cd64c5c30000000000000000000000000000000004ac6e6077d4eddd0e23f30cfd64b7aa1525c85424224e70c15d7535e02aea7a312ef24ba2dcf70b926acb851da2530c0000000000000000000000000000000006ad07d3e8f45cedfb4279913bf0a29e37604810463d6020b4fa8c8c4977d69cffaa33e1149706f04eb237194dcafa5200000000000000000000000000000000173bdb0d0a79f1f2607867ddbf2581b4c1cc20fc0bced60ed8756aa4e79cb87c47fa722b1c8fdbe99a8208fc532327b600000000000000000000000000000000172f37eac49dd7f09adf602ebe562e5d0bd52ee2419fc08dc7fda241c0319b3f43b3ec79ab5aac246a783f13e268d4bb", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_35", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a0300000000000000000000000000000000053ee41f6a51c49b069f12de32e3e6b0b355cd2c3ba87a149c7de86136a5d9c5b7b59f2d1237964e548d1b62ec36c8db000000000000000000000000000000001913ce14bcd1d7bbb47f8efd92d7ffd155ed1990a1dbf1ee7d5e6d592a92bcbec6e865199362950afd6c8fc49b3e10a400000000000000000000000000000000020df729079e76cf06f84e3355e683e093dafad38c2ba92cf7a9faa0515f2f44d814f971046ea20116cc4b0014d7ec350000000000000000000000000000000018db123e05404eea8707f9356f417c3966312b9e41765a6fd8449879ddc4c9850c38434481b235a5bc35db1b8ee86d43000000000000000000000000000000000b4162715717e9065a3849a9294cfe39b351e57ab5a6790f3e725ad9fbf0e4b9d6a3554e872af9c37df33bb896dada5c0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a030000000000000000000000000000000014c22dcacf2e21ff447c94d81067c626b1217e58b7dc98aacab2ea3fc00b1c5e66f660d19f1c69b16571e49d13c8e1d0000000000000000000000000000000001913ce14bcd1d7bbb47f8efd92d7ffd155ed1990a1dbf1ee7d5e6d592a92bcbec6e865199362950afd6c8fc49b3e10a400000000000000000000000000000000020df729079e76cf06f84e3355e683e093dafad38c2ba92cf7a9faa0515f2f44d814f971046ea20116cc4b0014d7ec350000000000000000000000000000000018db123e05404eea8707f9356f417c3966312b9e41765a6fd8449879ddc4c9850c38434481b235a5bc35db1b8ee86d43000000000000000000000000000000000b4162715717e9065a3849a9294cfe39b351e57ab5a6790f3e725ad9fbf0e4b9d6a3554e872af9c37df33bb896dada5c0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a0300000000000000000000000000000000053ee41f6a51c49b069f12de32e3e6b0b355cd2c3ba87a149c7de86136a5d9c5b7b59f2d1237964e548d1b62ec36c8db000000000000000000000000000000001913ce14bcd1d7bbb47f8efd92d7ffd155ed1990a1dbf1ee7d5e6d592a92bcbec6e865199362950afd6c8fc49b3e10a400000000000000000000000000000000020df729079e76cf06f84e3355e683e093dafad38c2ba92cf7a9faa0515f2f44d814f971046ea20116cc4b0014d7ec35000000000000000000000000000000000125ffac343f97afc413ae80d40a309dfe461fe6b20eb84f8eec3a2718ec2c9f1273bcba2fa1ca59fdc924e471173d68000000000000000000000000000000000ebfaf78e267fd93f0e35e0d19feae9db125660a3dde99b028be77c6fac0116a4808aab02a29063c3c0bc4476924d04f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_36", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000009cd91a281b96a881b20946fda164a987243c052378fcd8fee3926b75576dfa1d29a0aaca4b653da4e61da82577218080000000000000000000000000000000008be924b49e05c45419e328340f1cbcdd3350bacf832a372417d8331c942df200493a3f7f2e46ad2cdaf3544cfd8cd8600000000000000000000000000000000028cd100457f4e930fc0f55996a6b588c5361816bb853d1f522806e5ec1c455eb200343476feeb07ca77e961fc2adc1f000000000000000000000000000000000f6adad0a3bab3610165be2fadb1b020f25488a0af3d418b7d7cf1165812e17aefcbc23308ebcd31d22ba4ca5773dd87000000000000000000000000000000001657ff792e3d89d5d35767bd0cc788411b0420665a5e0704f4d2399b9d9a5ad3c027ee030fdf495e5a6e2a4c69d0571200000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000010338047b7c67c122ffb13466935623ef2338b32bbf5452f78f7abe9a13a16824c11f5520c9dac256b9d257da88d92a30000000000000000000000000000000008be924b49e05c45419e328340f1cbcdd3350bacf832a372417d8331c942df200493a3f7f2e46ad2cdaf3544cfd8cd8600000000000000000000000000000000028cd100457f4e930fc0f55996a6b588c5361816bb853d1f522806e5ec1c455eb200343476feeb07ca77e961fc2adc1f000000000000000000000000000000000f6adad0a3bab3610165be2fadb1b020f25488a0af3d418b7d7cf1165812e17aefcbc23308ebcd31d22ba4ca5773dd87000000000000000000000000000000001657ff792e3d89d5d35767bd0cc788411b0420665a5e0704f4d2399b9d9a5ad3c027ee030fdf495e5a6e2a4c69d0571200000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000009cd91a281b96a881b20946fda164a987243c052378fcd8fee3926b75576dfa1d29a0aaca4b653da4e61da82577218080000000000000000000000000000000008be924b49e05c45419e328340f1cbcdd3350bacf832a372417d8331c942df200493a3f7f2e46ad2cdaf3544cfd8cd8600000000000000000000000000000000028cd100457f4e930fc0f55996a6b588c5361816bb853d1f522806e5ec1c455eb200343476feeb07ca77e961fc2adc1f000000000000000000000000000000000a96371995c5333949b5e9869599fcb67222c2e44447d133e9b3e18a9e9e14a92ee03dcba86832cde7d35b35a88bcd240000000000000000000000000000000003a912710b425cc477c43ff93684249649732b1e99270bba725e990559169b505e8411fba174b6a15f90d5b3962f5399", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_37", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000011bf87b12734a6360d3dda4b452deede34470fba8e62a68f79153cc288a8e7fed98c74af862883b9861d2195a58262e0000000000000000000000000000000000a5048d860b997a9fb352e58284ebbc026622d9be73de79b2807a0c9b431f41f379c255a2db0dd67413c18217cb21b7200000000000000000000000000000000045a701a3f46ca801c02a5419c836b2ab3d74ebd6f4fd1e7dddb1965b49c9a278f6e89950e7c35ebc6724569d34e364c0000000000000000000000000000000004cb55008ccb5b2b8ece69fac7283f5a9ef9e622e2a0e42bed5bdd77faa550882643afc1759b1a327c4f2277e13a3d4f000000000000000000000000000000001690dee40c6c824dc2588fc47dbf93f68ac250b9357e1112db72ded905ed7b101b5f877bdc42d56afb5b6202403a91c4000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000008418a39124b40643dddcd6afe1dbdf930303bca65226c2fee1b95de6e080e25451f8b4f2b2b7c4633e1de6a5a7d47cb000000000000000000000000000000000a5048d860b997a9fb352e58284ebbc026622d9be73de79b2807a0c9b431f41f379c255a2db0dd67413c18217cb21b7200000000000000000000000000000000045a701a3f46ca801c02a5419c836b2ab3d74ebd6f4fd1e7dddb1965b49c9a278f6e89950e7c35ebc6724569d34e364c0000000000000000000000000000000004cb55008ccb5b2b8ece69fac7283f5a9ef9e622e2a0e42bed5bdd77faa550882643afc1759b1a327c4f2277e13a3d4f000000000000000000000000000000001690dee40c6c824dc2588fc47dbf93f68ac250b9357e1112db72ded905ed7b101b5f877bdc42d56afb5b6202403a91c4000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000011bf87b12734a6360d3dda4b452deede34470fba8e62a68f79153cc288a8e7fed98c74af862883b9861d2195a58262e0000000000000000000000000000000000a5048d860b997a9fb352e58284ebbc026622d9be73de79b2807a0c9b431f41f379c255a2db0dd67413c18217cb21b7200000000000000000000000000000000045a701a3f46ca801c02a5419c836b2ab3d74ebd6f4fd1e7dddb1965b49c9a278f6e89950e7c35ebc6724569d34e364c000000000000000000000000000000001535bce9acb48b6ebc4d3dbb7c236d7cc57d656210e42e9379d4f528fc0ba59bf868503d3bb8e5cd3dafdd881ec56d5c00000000000000000000000000000000037033062d13644c88c317f1c58c18e0d9b4facbbe0701ac8bbdf3c7f0c37b14034c7882d5112a94bea39dfdbfc518e7", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_38", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000f26fdf1af1b8ad442ef4494627c815ca01ae84510944788b87f4aa2c8600ed310b9579318bc617a689b916bb7731dcb00000000000000000000000000000000153cec9690a6420a10e5a5a8ca46fd9d9f90e2a139886a07b375eeecce9083a5f5418e6baf64ef0f34176e432bc5343a000000000000000000000000000000000d87c1f37f83ae78a51af9c420e2584a64337d2d2dd8dc3b64f252c521901924e5eec1d9899594db5e64c93c7a01ef020000000000000000000000000000000017078538092ace26cc88b94360871fc9a6bb9992172158ef3a16467919955083accf8d55d48c7ec462a743dbbca7b448000000000000000000000000000000000289b703157a02fc1d687a5aa595495be8bbb3eb0d70554728255a44b7820e0ee82d984d5493c800f1d9d8ca0c9381dc0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000ada13f88a645bc6082c6321e0cf2b7ac45c633fe2f0cb36aeb187fe2e50e7510df2a86b98979e8551636e94488c8ce000000000000000000000000000000000153cec9690a6420a10e5a5a8ca46fd9d9f90e2a139886a07b375eeecce9083a5f5418e6baf64ef0f34176e432bc5343a000000000000000000000000000000000d87c1f37f83ae78a51af9c420e2584a64337d2d2dd8dc3b64f252c521901924e5eec1d9899594db5e64c93c7a01ef020000000000000000000000000000000017078538092ace26cc88b94360871fc9a6bb9992172158ef3a16467919955083accf8d55d48c7ec462a743dbbca7b448000000000000000000000000000000000289b703157a02fc1d687a5aa595495be8bbb3eb0d70554728255a44b7820e0ee82d984d5493c800f1d9d8ca0c9381dc0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000f26fdf1af1b8ad442ef4494627c815ca01ae84510944788b87f4aa2c8600ed310b9579318bc617a689b916bb7731dcb00000000000000000000000000000000153cec9690a6420a10e5a5a8ca46fd9d9f90e2a139886a07b375eeecce9083a5f5418e6baf64ef0f34176e432bc5343a000000000000000000000000000000000d87c1f37f83ae78a51af9c420e2584a64337d2d2dd8dc3b64f252c521901924e5eec1d9899594db5e64c93c7a01ef020000000000000000000000000000000002f98cb2305518737e92ee72e2c48d0dbdbbb1f2dc63b9d02d1a8c27dd1ba5a071dc72a8dcc7813b5757bc244357f6630000000000000000000000000000000017775ae72405e39e2db32d5b9db6637b7bbb9799e614bd783f0b785c3f2ee815367e67b15cc037fec8252735f36c28cf", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_39", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a370000000000000000000000000000000003d2c7fe67cada2213e842ac5ec0dec8ec205b762f2a9c05fa12fa120c80eba30676834f0560d11ce9939fe210ad6c6300000000000000000000000000000000057f975064a29ba6ad20d6e6d97a15bd314d6cd419948d974a16923d52b38b9203f95937a0a0493a693099e4fa17ea540000000000000000000000000000000014396ce4abfc32945a6b2b0eb4896a6b19a041d4eae320ba18507ec3828964e56719fffaa47e57ea4a2e3bd1a149b6b600000000000000000000000000000000048b3e4ba3e2d1e0dbf5955101cf038dc22e87b0855a57b631ef119d1bd19d56c38a1d72376284c8598e866b6dba37530000000000000000000000000000000007c0b98cda33be53cf4ef29d0500ff5e7a3c2df6f83dfc1c36211d7f9c696b77dfa6571169cf7935d2fb5a6463cceac6000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a3700000000000000000000000000000000162e49ebd1b50c7837336509e48ace0e7856f00ec45a76b96d1dd88eea300a8118357cafabf32ee2d06b601def523e4800000000000000000000000000000000057f975064a29ba6ad20d6e6d97a15bd314d6cd419948d974a16923d52b38b9203f95937a0a0493a693099e4fa17ea540000000000000000000000000000000014396ce4abfc32945a6b2b0eb4896a6b19a041d4eae320ba18507ec3828964e56719fffaa47e57ea4a2e3bd1a149b6b600000000000000000000000000000000048b3e4ba3e2d1e0dbf5955101cf038dc22e87b0855a57b631ef119d1bd19d56c38a1d72376284c8598e866b6dba37530000000000000000000000000000000007c0b98cda33be53cf4ef29d0500ff5e7a3c2df6f83dfc1c36211d7f9c696b77dfa6571169cf7935d2fb5a6463cceac6000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a370000000000000000000000000000000003d2c7fe67cada2213e842ac5ec0dec8ec205b762f2a9c05fa12fa120c80eba30676834f0560d11ce9939fe210ad6c6300000000000000000000000000000000057f975064a29ba6ad20d6e6d97a15bd314d6cd419948d974a16923d52b38b9203f95937a0a0493a693099e4fa17ea540000000000000000000000000000000014396ce4abfc32945a6b2b0eb4896a6b19a041d4eae320ba18507ec3828964e56719fffaa47e57ea4a2e3bd1a149b6b6000000000000000000000000000000001575d39e959d14b96f261265417ca949a248c3d46e2abb093541c103dadf58cd5b21e28c79f17b376070799492457358000000000000000000000000000000001240585d5f4c28467bccb5193e4aad78ea3b1d8dfb4716a3310fb5215a478aac3f05a8ed478486c9e703a59b9c32bfe5", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_40", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000b02ca2b0e6e0989ea917719b89caf1aa84b959e45b6238813bf02f40db95fbb3bf43d3017c3f9c57eab1be617f18032000000000000000000000000000000000b6069a2c375471d34029d2a776e56b86b0210c35d3eb530bf116205b70995e4929fc90349a7db057168dbe6c39857970000000000000000000000000000000014251a0a154731f73513b99d830f70b6fc4bcf05d11f52d2cbe9795ee8ffc5a5f717ad25770b8ecad6d0e9f8066e0cba000000000000000000000000000000001172684b21c4dfe02a55e13b57bbf105c954daec849d4c6df5276b02872c004fdf09d24f4eef366bc82eb72fe91bf70d000000000000000000000000000000001151aeb9441c5a8fabe80867b5c791420645241eae1400bbcc064d75bedd39de2ef585138fe9f65725efa1b1e5888d0300000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000efe47bf2b11dd10608a309c8aaefdbcbc2bb5e6adceef375371cface8f79668e2b7c2ce9990063a3b53e419e80e2a79000000000000000000000000000000000b6069a2c375471d34029d2a776e56b86b0210c35d3eb530bf116205b70995e4929fc90349a7db057168dbe6c39857970000000000000000000000000000000014251a0a154731f73513b99d830f70b6fc4bcf05d11f52d2cbe9795ee8ffc5a5f717ad25770b8ecad6d0e9f8066e0cba000000000000000000000000000000001172684b21c4dfe02a55e13b57bbf105c954daec849d4c6df5276b02872c004fdf09d24f4eef366bc82eb72fe91bf70d000000000000000000000000000000001151aeb9441c5a8fabe80867b5c791420645241eae1400bbcc064d75bedd39de2ef585138fe9f65725efa1b1e5888d0300000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000b02ca2b0e6e0989ea917719b89caf1aa84b959e45b6238813bf02f40db95fbb3bf43d3017c3f9c57eab1be617f18032000000000000000000000000000000000b6069a2c375471d34029d2a776e56b86b0210c35d3eb530bf116205b70995e4929fc90349a7db057168dbe6c39857970000000000000000000000000000000014251a0a154731f73513b99d830f70b6fc4bcf05d11f52d2cbe9795ee8ffc5a5f717ad25770b8ecad6d0e9f8066e0cba00000000000000000000000000000000088ea99f17bb06ba20c5c67aeb8fbbd19b2270986ee7c6517209679e6f84f5d43fa22daf6264c993f1d048d016e3b39e0000000000000000000000000000000008af6330f5638c0a9f339f4e8d841b955e322766457112039b2a852b37d3bc45efb67aeb216a09a8940f5e4e1a771da8", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_41", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c187229000000000000000000000000000000000096713619bf088bd9e12752cab83e9cdd58296ada8d338c86a749f00ba014087a3836ce10adaaf2e815f431235bff4f000000000000000000000000000000000161b70d0f384e589d8117938602f3d696f941c24e3c1ca5a9be090b670456c9df315d6fde52daed55c9d8335928a7a3c00000000000000000000000000000000186bb9e6f5ba70dd2c66a641d3b711844977939904c59946d4e9f49ac2d8c00890a43ccb20d4a62bfff63ce4a0a44e8e000000000000000000000000000000001995b9d697bded656236430e78726f0f6ef963db9a5a24d455c12db38aeab0f8629e5dc2d04920156f2a057d69613096000000000000000000000000000000001119b13caf82c18fadcb65c9c166914bfd822534bb9def3feae6c9e572c97c84e97fab3b345cf59358436a404075493d000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c1872290000000000000000000000000000000001099fe889d8f5ddcad09328997c7c3098ef4b4d74ab1d9f6fcbc33a03cafb59c7b28931da67950d1389fbcedca3fb5bb00000000000000000000000000000000161b70d0f384e589d8117938602f3d696f941c24e3c1ca5a9be090b670456c9df315d6fde52daed55c9d8335928a7a3c00000000000000000000000000000000186bb9e6f5ba70dd2c66a641d3b711844977939904c59946d4e9f49ac2d8c00890a43ccb20d4a62bfff63ce4a0a44e8e000000000000000000000000000000001995b9d697bded656236430e78726f0f6ef963db9a5a24d455c12db38aeab0f8629e5dc2d04920156f2a057d69613096000000000000000000000000000000001119b13caf82c18fadcb65c9c166914bfd822534bb9def3feae6c9e572c97c84e97fab3b345cf59358436a404075493d000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c187229000000000000000000000000000000000096713619bf088bd9e12752cab83e9cdd58296ada8d338c86a749f00ba014087a3836ce10adaaf2e815f431235bff4f000000000000000000000000000000000161b70d0f384e589d8117938602f3d696f941c24e3c1ca5a9be090b670456c9df315d6fde52daed55c9d8335928a7a3c00000000000000000000000000000000186bb9e6f5ba70dd2c66a641d3b711844977939904c59946d4e9f49ac2d8c00890a43ccb20d4a62bfff63ce4a0a44e8e00000000000000000000000000000000006b5813a1c1f934e8e564a7cad93dc7f57de7a9592aedeb116fa4ed6bc6452bbc0da23be10adfea4ad4fa82969e7a150000000000000000000000000000000008e760ad89fd250a9d5041ec81e51b8b66f5265037e7237f7c4a08bb83e7799f352c54c37cf70a6c61bb95bfbf8a616e", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_42", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a90000000000000000000000000000000002b03f02b45aa15b39e030c4b88c89a285dff5c4bbfe16f643f3f87d91db774f8ab7019285fda0b236ff7eec16496e5e0000000000000000000000000000000017d1ffcad218efd8b09c68eba34dbbc30b0a62ae250368ee37e5f6fd40479b8580563416afdbd92c0622c341331e20a30000000000000000000000000000000009f0eb3805ed78aa3952a0a437966258ed38cb72912756253a7a2f9113f0dd9a4e187062b0423e0587d93e904d88f50d0000000000000000000000000000000001bca57e985906695e14882f2aaeef75de5009e8717eb59962e978aa11e9d0a4d9a9e203df774cb1e993b1c6ecd6048c000000000000000000000000000000000695b11cc32740c91546eb7d554ca8b1f3afc942ad977345031be8b94b78b57a87ab049ca2d3676e039efccbf24d0c47000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a9000000000000000000000000000000001750d2e78525453f113b76f18abf2334de9755c03786fbc9233cda2364d57ed493f4fe6c2b565f4d82ff8113e9b63c4d0000000000000000000000000000000017d1ffcad218efd8b09c68eba34dbbc30b0a62ae250368ee37e5f6fd40479b8580563416afdbd92c0622c341331e20a30000000000000000000000000000000009f0eb3805ed78aa3952a0a437966258ed38cb72912756253a7a2f9113f0dd9a4e187062b0423e0587d93e904d88f50d0000000000000000000000000000000001bca57e985906695e14882f2aaeef75de5009e8717eb59962e978aa11e9d0a4d9a9e203df774cb1e993b1c6ecd6048c000000000000000000000000000000000695b11cc32740c91546eb7d554ca8b1f3afc942ad977345031be8b94b78b57a87ab049ca2d3676e039efccbf24d0c47000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a90000000000000000000000000000000002b03f02b45aa15b39e030c4b88c89a285dff5c4bbfe16f643f3f87d91db774f8ab7019285fda0b236ff7eec16496e5e0000000000000000000000000000000017d1ffcad218efd8b09c68eba34dbbc30b0a62ae250368ee37e5f6fd40479b8580563416afdbd92c0622c341331e20a30000000000000000000000000000000009f0eb3805ed78aa3952a0a437966258ed38cb72912756253a7a2f9113f0dd9a4e187062b0423e0587d93e904d88f50d0000000000000000000000000000000018446c6ba126e030ed071f87189cbd618627419c82065d26044759f6e4c7257f45021dfad1dcb34dd06b4e391329a61f00000000000000000000000000000000136b60cd7658a5d135d4bc38edff042570c7824245ed9f7a6414e9e7ab3840a99700fb620e809891b66003340db29e64", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_43", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb00000000000000000000000000000000185e8671e2ddb8e36380e39fe4eafefbac9769935603c28caac7d3f7f0f3e8ad14e925024b55aeb67d68b219875c9d79000000000000000000000000000000000546a0cb9d9f1ef9ec4a1e576fa0047557a56c0217baed8691c4085b88c84a0e12d44043aab8671393d02c4a764407ee00000000000000000000000000000000131884c1386980a181353548da9602db70ab495a661e76235c4b0a32b54acb0dfd8846e17bebd731e8041c4aebb8776600000000000000000000000000000000135b3db43511dbd8b3bd5a91880d6da1a2bd1383000e0d6f0a521bf88a5836a3b5f7cb9c0c02aa861a1c2d339f3c11f20000000000000000000000000000000000e1337271bd3302a1cab762161ccfbf2a18b7800e6efe58cf897d4adbfe4cb3bf14f4b59307fffc548179bda70c18bf000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb0000000000000000000000000000000001a28b7856a22db6e79ac4165e60addbb7dfe1f19d815032bc68fea905bd0d7709c2dafc65fe51493c964de678a30d32000000000000000000000000000000000546a0cb9d9f1ef9ec4a1e576fa0047557a56c0217baed8691c4085b88c84a0e12d44043aab8671393d02c4a764407ee00000000000000000000000000000000131884c1386980a181353548da9602db70ab495a661e76235c4b0a32b54acb0dfd8846e17bebd731e8041c4aebb8776600000000000000000000000000000000135b3db43511dbd8b3bd5a91880d6da1a2bd1383000e0d6f0a521bf88a5836a3b5f7cb9c0c02aa861a1c2d339f3c11f20000000000000000000000000000000000e1337271bd3302a1cab762161ccfbf2a18b7800e6efe58cf897d4adbfe4cb3bf14f4b59307fffc548179bda70c18bf000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb00000000000000000000000000000000185e8671e2ddb8e36380e39fe4eafefbac9769935603c28caac7d3f7f0f3e8ad14e925024b55aeb67d68b219875c9d79000000000000000000000000000000000546a0cb9d9f1ef9ec4a1e576fa0047557a56c0217baed8691c4085b88c84a0e12d44043aab8671393d02c4a764407ee00000000000000000000000000000000131884c1386980a181353548da9602db70ab495a661e76235c4b0a32b54acb0dfd8846e17bebd731e8041c4aebb877660000000000000000000000000000000006a5d436046e0ac1975e4d24bb3e3f35c1ba3801f37705505cdeb6a86c58bf8068b43462a55155799fe2d2cc60c398b900000000000000000000000000000000191fde77c7c2b397a950f0542d2edd183a5e9404e516146697a755561ab2a9705f970b491e4c0003657d864258f391ec", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_44", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e2700000000000000000000000000000000123f973ab6bd3c2e5b0512a0c77ea0ac3003fd891e1262137f9444cd07b927b564e618205ba09220320ea1aa4564e82000000000000000000000000000000000113dc3354146ca79eb103b31b61fe8bc6f33dcb9c59a7c39d989bd9411c1afce4239034f84e6b00a084be061c73e69c0000000000000000000000000000000000ae33bf68f24978c7ea9fc58d8d76047ec45d01fdbc880e6a5ba02a22a49a3a8253afe0678ecfa6013f4849da3401df70000000000000000000000000000000012c5b00376a1dd31378ec44f2dc8e321e17185d903cfc5c15345a01c33f2f151b21b938d31816550594a7a1e7216c5b00000000000000000000000000000000013d79f825c44775c68e90932d0496a5cae53f04a1edb19f8abeb5948a3dd325dfec4a8b6f58c7fbca9cf3c09b909d8b2000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e270000000000000000000000000000000007c17aaf82c2aa6bf01695157bcd0c2b34734dfbd572b0abe79c8dd3eef7ce6eb9c5e7de55b36ddf87f05e55ba9ac28b00000000000000000000000000000000113dc3354146ca79eb103b31b61fe8bc6f33dcb9c59a7c39d989bd9411c1afce4239034f84e6b00a084be061c73e69c0000000000000000000000000000000000ae33bf68f24978c7ea9fc58d8d76047ec45d01fdbc880e6a5ba02a22a49a3a8253afe0678ecfa6013f4849da3401df70000000000000000000000000000000012c5b00376a1dd31378ec44f2dc8e321e17185d903cfc5c15345a01c33f2f151b21b938d31816550594a7a1e7216c5b00000000000000000000000000000000013d79f825c44775c68e90932d0496a5cae53f04a1edb19f8abeb5948a3dd325dfec4a8b6f58c7fbca9cf3c09b909d8b2000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e2700000000000000000000000000000000123f973ab6bd3c2e5b0512a0c77ea0ac3003fd891e1262137f9444cd07b927b564e618205ba09220320ea1aa4564e82000000000000000000000000000000000113dc3354146ca79eb103b31b61fe8bc6f33dcb9c59a7c39d989bd9411c1afce4239034f84e6b00a084be061c73e69c0000000000000000000000000000000000ae33bf68f24978c7ea9fc58d8d76047ec45d01fdbc880e6a5ba02a22a49a3a8253afe0678ecfa6013f4849da3401df700000000000000000000000000000000073b61e6c2de0969138ce3671582c9b58305c5abefb54cfe13eb3284c2be04d26c906c717fd29aaf60b485e18de8e4fb0000000000000000000000000000000006297267dd3b6f3de2329e837302427ab6235b3ad4a9f8c6bb45795852d3c3c61fe75747bbc78043102fc3f646f5d1f9", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_45", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000002ec930fb58c898ede931384c5a5f9edd2f5c70b8c3794edb83a12f23be5400949f95e81c96c666c1a72dffb50b811580000000000000000000000000000000006ccaf6c08f831be9c99a97714f5257a985cc2a29b5f5c81bc8d794dd0d8d1a41eb5413bed654c0140dbacfd0dda9e1800000000000000000000000000000000144e9cf91580800dfaa47c98ff7d002a576be76d9e44ae1f8335a3f733e1162af0636372e143174d872c7ea89f4c743900000000000000000000000000000000101e143b838c8a3f5f80fb1412081091b875230f1e2f9cf374d4bcd595392f6daa9552dbb6d5834e27b1b3dafe061ed300000000000000000000000000000000072463400b3e875395a1cdd31d73d51396e34347cd86d9f6f43f42253b3cdb24b89ed7434b1522af95ba1ee2d29ed1bb000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000017147eda83f35d0b6c8894317da5b2e991818479674d7dd1aef6bfaebacbb61ad4b2a17ce7e799939f8c2004af4799530000000000000000000000000000000006ccaf6c08f831be9c99a97714f5257a985cc2a29b5f5c81bc8d794dd0d8d1a41eb5413bed654c0140dbacfd0dda9e1800000000000000000000000000000000144e9cf91580800dfaa47c98ff7d002a576be76d9e44ae1f8335a3f733e1162af0636372e143174d872c7ea89f4c743900000000000000000000000000000000101e143b838c8a3f5f80fb1412081091b875230f1e2f9cf374d4bcd595392f6daa9552dbb6d5834e27b1b3dafe061ed300000000000000000000000000000000072463400b3e875395a1cdd31d73d51396e34347cd86d9f6f43f42253b3cdb24b89ed7434b1522af95ba1ee2d29ed1bb000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000002ec930fb58c898ede931384c5a5f9edd2f5c70b8c3794edb83a12f23be5400949f95e81c96c666c1a72dffb50b811580000000000000000000000000000000006ccaf6c08f831be9c99a97714f5257a985cc2a29b5f5c81bc8d794dd0d8d1a41eb5413bed654c0140dbacfd0dda9e1800000000000000000000000000000000144e9cf91580800dfaa47c98ff7d002a576be76d9e44ae1f8335a3f733e1162af0636372e143174d872c7ea89f4c74390000000000000000000000000000000009e2fdaeb5f35c5aeb9aaca231439c45ac022875d55575cbf25c15cb6177c6b67416ad22fa7e7cb1924d4c2501f98bd80000000000000000000000000000000012dcaeaa2e415f46b579d9e325d7d7c3cd94083d25fe38c872f1907bbb741aff660d28bb663edd502444e11d2d60d8f0", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_46", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f100000000000000000000000000000000033f481fc62ab0a249561d180da39ff641a540c9c109cde41946a0e85d18c9d60b41dbcdec370c5c9f22a9ee9de00ccd000000000000000000000000000000001354146aa546754e10ada6e0fe98f04f5f3a3f8a8350d0295e02b8e9c80735b04c3061412e08ddb13c80ac36e5638e540000000000000000000000000000000012ab26513534b4dc1b71eec46b73199c4157ba9369e66fbe4d2d8f62237fc7c6fad31854ebd878f989b8c5cf35c7cfe0000000000000000000000000000000000eb731bc99cdadf7f2280385c7e17d72d34bcbdbdc725d5bc94e841036115e8cb95df08084221696f9be479821fbdd7400000000000000000000000000000000143ba7d3f66445249d9a81a6949f24ff40e7c4d270fa044a8b80200a4369b07806c5497a0ef9e9dbb87b9e63694623ee0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f10000000000000000000000000000000016c1c9ca735535f801c58a9e35a80ce122d20abb327b44db4dea31b899982c4e136a2430c51cf3a31adc5611621f9dde000000000000000000000000000000001354146aa546754e10ada6e0fe98f04f5f3a3f8a8350d0295e02b8e9c80735b04c3061412e08ddb13c80ac36e5638e540000000000000000000000000000000012ab26513534b4dc1b71eec46b73199c4157ba9369e66fbe4d2d8f62237fc7c6fad31854ebd878f989b8c5cf35c7cfe0000000000000000000000000000000000eb731bc99cdadf7f2280385c7e17d72d34bcbdbdc725d5bc94e841036115e8cb95df08084221696f9be479821fbdd7400000000000000000000000000000000143ba7d3f66445249d9a81a6949f24ff40e7c4d270fa044a8b80200a4369b07806c5497a0ef9e9dbb87b9e63694623ee0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f100000000000000000000000000000000033f481fc62ab0a249561d180da39ff641a540c9c109cde41946a0e85d18c9d60b41dbcdec370c5c9f22a9ee9de00ccd000000000000000000000000000000001354146aa546754e10ada6e0fe98f04f5f3a3f8a8350d0295e02b8e9c80735b04c3061412e08ddb13c80ac36e5638e540000000000000000000000000000000012ab26513534b4dc1b71eec46b73199c4157ba9369e66fbe4d2d8f62237fc7c6fad31854ebd878f989b8c5cf35c7cfe0000000000000000000000000000000000b49e02d9fb238a258f3a4307b6a2f64912b7fa91712b5639de24e90c09f9797654e0f7e2d31e968c040b867de03cd370000000000000000000000000000000005c56a16431ba175ad81260faeac87d8238f86b2828b0e74dbb0b296b34745ac17e6b684a25a16240183619c96b986bd", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_47", - "Gas": 194000, + "Gas": 135500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be10000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe90000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000068edef3169c58920509ed4e7069229bd8038a45d2ce5773451cc18b396d2838c9539ecb52298a27eebd714afacb907c0000000000000000000000000000000004c5346765a62f2d2e700aadccf747acb3322c250435ce2cf358c08f1e286427cabace052327c4b30135c8482c5c0eb90000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be100000000000000000000000000000000084486ebc81878331aab7d6f53ca3c773fda7b181b56a93e5ee0bfa189afbb7fd7a05c5bea35ec1054c0e1ddc2e2dac20000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000068edef3169c58920509ed4e7069229bd8038a45d2ce5773451cc18b396d2838c9539ecb52298a27eebd714afacb907c0000000000000000000000000000000004c5346765a62f2d2e700aadccf747acb3322c250435ce2cf358c08f1e286427cabace052327c4b30135c8482c5c0eb90000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be10000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe90000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000137232f722e38e084611ba67d2e28a3b8c73c13f20b6bb4c22141115bd43cdeb555861335f2a75d7cb418eb505341a2f00000000000000000000000000000000153bdd82d3d9b76d1cab9d087654652ab1451f5fef4f449273d81211d88891fc53f131f98e2c3b4cb8c937b7d3a39bf20000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be100000000000000000000000000000000084486ebc81878331aab7d6f53ca3c773fda7b181b56a93e5ee0bfa189afbb7fd7a05c5bea35ec1054c0e1ddc2e2dac20000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000137232f722e38e084611ba67d2e28a3b8c73c13f20b6bb4c22141115bd43cdeb555861335f2a75d7cb418eb505341a2f00000000000000000000000000000000153bdd82d3d9b76d1cab9d087654652ab1451f5fef4f449273d81211d88891fc53f131f98e2c3b4cb8c937b7d3a39bf2", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_48", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000fa57c1436615442bbb049d08ac46e501c07736cd239298752bb94d1904bd38cc687759987cadd99bd3c4d45ba07193a000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000f6fdc4e5dceb555c9eb4c912fedbfb3cb1b842345f73ded02cfaf8d397c4378809721094aa4a4113a368e0787effeb500000000000000000000000000000000143ac06258c579c11c05569669a2a10babc63ecc86f85c91791d8ea48af700a2067c5f13d2700b8d5cf59bcca8fbf7c600000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000a5b95d6031e92578f6b5de5b8873e87486fd818214be93814753dcf6665229758248a6529892265fcc2b2ba45f89171000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000f6fdc4e5dceb555c9eb4c912fedbfb3cb1b842345f73ded02cfaf8d397c4378809721094aa4a4113a368e0787effeb500000000000000000000000000000000143ac06258c579c11c05569669a2a10babc63ecc86f85c91791d8ea48af700a2067c5f13d2700b8d5cf59bcca8fbf7c600000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000fa57c1436615442bbb049d08ac46e501c07736cd239298752bb94d1904bd38cc687759987cadd99bd3c4d45ba07193a000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000a91359bdbb1314481305b25135ded23995bc761ad8dd4d264612313bd34b2ab9e14def566af5bee7fc871f8780fabf60000000000000000000000000000000005c65187e0ba6cd92f16511fd9a90bcbb8b10cb86c8cb62dee1343fc6bb9f582182fa0eadee3f4725d0964335703b2e500000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000a5b95d6031e92578f6b5de5b8873e87486fd818214be93814753dcf6665229758248a6529892265fcc2b2ba45f89171000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000a91359bdbb1314481305b25135ded23995bc761ad8dd4d264612313bd34b2ab9e14def566af5bee7fc871f8780fabf60000000000000000000000000000000005c65187e0ba6cd92f16511fd9a90bcbb8b10cb86c8cb62dee1343fc6bb9f582182fa0eadee3f4725d0964335703b2e5", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_49", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b600000000000000000000000000000000175bdd42583cbbf733242510c152380525aff7649273acef1ec20569804ffba7f029ca06878dbafde84540cece173822000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc500000000000000000000000000000000192f3e8ae2588f9223de77f5e872115f1edec96d6a0f403a47879410c2562e79853c9a706e423b83fbf3154234edb6f80000000000000000000000000000000015084258d58fd1a07bbdb2e90df5a56ae15a787037eff4fe55f660e45f04820c6fc8982303b5e82074cf0cdcbde61307000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b60000000000000000000000000000000002a534a7e1432aa317f782a581f974d23ec75420611165d0486ecd377660fa7c2e8235f829c64501d1b9bf3131e87289000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc500000000000000000000000000000000192f3e8ae2588f9223de77f5e872115f1edec96d6a0f403a47879410c2562e79853c9a706e423b83fbf3154234edb6f80000000000000000000000000000000015084258d58fd1a07bbdb2e90df5a56ae15a787037eff4fe55f660e45f04820c6fc8982303b5e82074cf0cdcbde61307000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b600000000000000000000000000000000175bdd42583cbbf733242510c152380525aff7649273acef1ec20569804ffba7f029ca06878dbafde84540cece173822000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc50000000000000000000000000000000000d1d35f57275708273d2fc05ad99b78459882178975d2851fa93e90345ac7aa996f658e4311c47bbe0beabdcb11f3b30000000000000000000000000000000004f8cf9163f014f9cf5df4cd3556076c831cd314bb951dc1113a71bc97ac7417aee367dbad9e17df452ff323421997a4000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b60000000000000000000000000000000002a534a7e1432aa317f782a581f974d23ec75420611165d0486ecd377660fa7c2e8235f829c64501d1b9bf3131e87289000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc50000000000000000000000000000000000d1d35f57275708273d2fc05ad99b78459882178975d2851fa93e90345ac7aa996f658e4311c47bbe0beabdcb11f3b30000000000000000000000000000000004f8cf9163f014f9cf5df4cd3556076c831cd314bb951dc1113a71bc97ac7417aee367dbad9e17df452ff323421997a4", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_50", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000cbf7a31e6fef4f4664bca4bc87ec7c0b12ced7224300aa4e1a6a7cbdedfcef07482b5d20fa607e3f03fdd6dd03fd10c000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f000000000000000000000000000000000477b55bd7fff14e0d1807bfc21edb9481be01c12abb1460d78b1aafe42953730167e32e694c2ddfb0d442e8cea57d460000000000000000000000000000000004b884c6ea36f189dbc3c0e9cf88f08baf5d868579998f63b752e61fcce3cf2c901bb9b51959d3597c4ef53cff41fc260000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000d4197b85280f1a5e4cfdd6a7acce516b34a5e12cf55081a858a2ad517d12733aa294a2ca1adf81bc9bf22922fbfd99f000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f000000000000000000000000000000000477b55bd7fff14e0d1807bfc21edb9481be01c12abb1460d78b1aafe42953730167e32e694c2ddfb0d442e8cea57d460000000000000000000000000000000004b884c6ea36f189dbc3c0e9cf88f08baf5d868579998f63b752e61fcce3cf2c901bb9b51959d3597c4ef53cff41fc260000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000cbf7a31e6fef4f4664bca4bc87ec7c0b12ced7224300aa4e1a6a7cbdedfcef07482b5d20fa607e3f03fdd6dd03fd10c000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f0000000000000000000000000000000015895c8e617ff54c3e039ff6812cd142e2b949c3c8c9fe5e8fa5b7f11287a2b11d441cd04807d220092abd17315a2d650000000000000000000000000000000015488d234f48f5106f57e6cc73c2bc4bb519c4ff79eb835bafddec8129cd26f78e90464997fa2ca63db00ac300bdae850000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000d4197b85280f1a5e4cfdd6a7acce516b34a5e12cf55081a858a2ad517d12733aa294a2ca1adf81bc9bf22922fbfd99f000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f0000000000000000000000000000000015895c8e617ff54c3e039ff6812cd142e2b949c3c8c9fe5e8fa5b7f11287a2b11d441cd04807d220092abd17315a2d650000000000000000000000000000000015488d234f48f5106f57e6cc73c2bc4bb519c4ff79eb835bafddec8129cd26f78e90464997fa2ca63db00ac300bdae85", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_51", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa0000000000000000000000000000000005aa892b0a056ff61706430f1daa3f0263dc01337eadabd8a7fd58152affd9aaa329e8c11ea98692134d9718cb4119bf00000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac800000000000000000000000000000000183b7b917aaaa94f0ea9959273ed4701102346be2a9d72531bd18fef908ecb0579a6ac10ed42a91f1147fc3a05b2e81900000000000000000000000000000000070983b1582a97d9797782e4f960a298aaa8ec509720495acdbf176d8ecb9ec9e041c2b5ed6b7dfb46fdeaae3fb341500000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa00000000000000000000000000000000145688bf2f7a76a4341564a725a16dd5009b4a5174d766e6bf337a8bcbb11c797b82173d92aa796da6b168e734be90ec00000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac800000000000000000000000000000000183b7b917aaaa94f0ea9959273ed4701102346be2a9d72531bd18fef908ecb0579a6ac10ed42a91f1147fc3a05b2e81900000000000000000000000000000000070983b1582a97d9797782e4f960a298aaa8ec509720495acdbf176d8ecb9ec9e041c2b5ed6b7dfb46fdeaae3fb341500000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa0000000000000000000000000000000005aa892b0a056ff61706430f1daa3f0263dc01337eadabd8a7fd58152affd9aaa329e8c11ea98692134d9718cb4119bf00000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac80000000000000000000000000000000001c59658bed53d4b3c721223cf5e65d6545404c6c8e7a06c4b5f42b166222b1ea50553edc41156e0a8b703c5fa4cc2920000000000000000000000000000000012f78e38e1554ec0d1a424d149eb0a3eb9ce5f345c64c9649971bb3367e5575a3e6a3d48c3e8820473011551c04c695b0000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa00000000000000000000000000000000145688bf2f7a76a4341564a725a16dd5009b4a5174d766e6bf337a8bcbb11c797b82173d92aa796da6b168e734be90ec00000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac80000000000000000000000000000000001c59658bed53d4b3c721223cf5e65d6545404c6c8e7a06c4b5f42b166222b1ea50553edc41156e0a8b703c5fa4cc2920000000000000000000000000000000012f78e38e1554ec0d1a424d149eb0a3eb9ce5f345c64c9649971bb3367e5575a3e6a3d48c3e8820473011551c04c695b", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_52", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a0300000000000000000000000000000000166ce33c0482b5957c6e746c16908ba579d6402b230bc977d3ff29ac2a4a800748d9c14608f2519e2ac4d1fe4daf29b2000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b0000000000000000000000000000000010f7bf9f6711ba723bb71a004a90109ee22be6643d56d410da18103ef44a1b3d50f10c4b94222c7f05fd3c28acbdc8ee00000000000000000000000000000000007af41f09e6d0adcb1935d6a93ea1f6156fa0157a63f265a3a7ceffe82f6635b8511e7e8f21e8f3be7a73513ff597b10000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a030000000000000000000000000000000003942eae34fd3104cead334a2cbb2131eaa10b59d07949479331a8f4cc66761cd5d23eb8a861ae618f3a2e01b25080f9000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b0000000000000000000000000000000010f7bf9f6711ba723bb71a004a90109ee22be6643d56d410da18103ef44a1b3d50f10c4b94222c7f05fd3c28acbdc8ee00000000000000000000000000000000007af41f09e6d0adcb1935d6a93ea1f6156fa0157a63f265a3a7ceffe82f6635b8511e7e8f21e8f3be7a73513ff597b10000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a0300000000000000000000000000000000166ce33c0482b5957c6e746c16908ba579d6402b230bc977d3ff29ac2a4a800748d9c14608f2519e2ac4d1fe4daf29b2000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b000000000000000000000000000000000909524ad26e2c280f648db5f8bb9c38824b6520b62e3eae8d18c2620266dae6cdbaf3b31d31d380b401c3d75341e1bd0000000000000000000000000000000019861dcb2f9915ec800271df9a0d0ae14f07ab6f79212059c38903a10e818fee665ae1802232170bfb848caec00a12fa0000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a030000000000000000000000000000000003942eae34fd3104cead334a2cbb2131eaa10b59d07949479331a8f4cc66761cd5d23eb8a861ae618f3a2e01b25080f9000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b000000000000000000000000000000000909524ad26e2c280f648db5f8bb9c38824b6520b62e3eae8d18c2620266dae6cdbaf3b31d31d380b401c3d75341e1bd0000000000000000000000000000000019861dcb2f9915ec800271df9a0d0ae14f07ab6f79212059c38903a10e818fee665ae1802232170bfb848caec00a12fa", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_53", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f6046300000000000000000000000000000000148b5454f9b9868aefd2accc3318ddabfe618c5026e8c04f8a6bce76cd88e350bebcd779f2021fe7ceda3e8b4d438a0b0000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a0000000000000000000000000000000003a6cc74cc398f38d535b4341faa37c968daf2009c3f05ace1f938b33bbe4002d81d18d30c2c856b21afe7a22b83c37a000000000000000000000000000000000452d1b2da6392f9df1bfd35e4575c565333703b2f83f56e0a88a0c8195968c5321296b07f6750584e23597304a5472e00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f60463000000000000000000000000000000000575bd953fc6600f5b48faea1032cf2b6615bf34cc9c526fdcc5042a292812d35fef2884bf51e017eb24c174b2bc20a00000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a0000000000000000000000000000000003a6cc74cc398f38d535b4341faa37c968daf2009c3f05ace1f938b33bbe4002d81d18d30c2c856b21afe7a22b83c37a000000000000000000000000000000000452d1b2da6392f9df1bfd35e4575c565333703b2f83f56e0a88a0c8195968c5321296b07f6750584e23597304a5472e00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f6046300000000000000000000000000000000148b5454f9b9868aefd2accc3318ddabfe618c5026e8c04f8a6bce76cd88e350bebcd779f2021fe7ceda3e8b4d438a0b0000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a00000000000000000000000000000000165a45756d46576175e5f38223a1750dfb9c598457460d12853799edbaf2b621468ee72ba5277a94984f185dd47be7310000000000000000000000000000000015ae40375f1c53a06bffaa805ef450811143db49c4011d515ca831d8dd578d5eec99694e31ecafa76bdba68cfb5a637d00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f60463000000000000000000000000000000000575bd953fc6600f5b48faea1032cf2b6615bf34cc9c526fdcc5042a292812d35fef2884bf51e017eb24c174b2bc20a00000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a00000000000000000000000000000000165a45756d46576175e5f38223a1750dfb9c598457460d12853799edbaf2b621468ee72ba5277a94984f185dd47be7310000000000000000000000000000000015ae40375f1c53a06bffaa805ef450811143db49c4011d515ca831d8dd578d5eec99694e31ecafa76bdba68cfb5a637d", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_54", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a00000000000000000000000000000000016d2c22eabd4a06a5ae67b890a25fbede7d0e96c625b80329b19be6aa861f44b6e85778130d0bdf69f2abd491ee9751a0000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf780000000000000000000000000000000007a9cf48dbe005c5c59b2c731cf4117e5fadc9cb2cd8f486f1ed58b2909092ee8f36d88b8f719db94715641b418ab4240000000000000000000000000000000004ba40d4766b91bf8da1cc2526f62791a1b5f6fc24ffc54b522dd30cde2d29a6a6f81e8429d518710843d43705f3b4e60000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a000000000000000000000000000000000032e4fbb8dab462ff0352c2d3925b0e97ca662189129928ccc1714364e4f01d8b026887d808342091ad442b6e11635910000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf780000000000000000000000000000000007a9cf48dbe005c5c59b2c731cf4117e5fadc9cb2cd8f486f1ed58b2909092ee8f36d88b8f719db94715641b418ab4240000000000000000000000000000000004ba40d4766b91bf8da1cc2526f62791a1b5f6fc24ffc54b522dd30cde2d29a6a6f81e8429d518710843d43705f3b4e60000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a00000000000000000000000000000000016d2c22eabd4a06a5ae67b890a25fbede7d0e96c625b80329b19be6aa861f44b6e85778130d0bdf69f2abd491ee9751a0000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf7800000000000000000000000000000000125742a15d9fe0d485807b4326579b5904c981b9c6ac1e38754379ee662063358f75277321e2624672e99be4be74f687000000000000000000000000000000001546d115c31454dabd79db911c558545c2c15488ce854d741502ff941883cc7d77b3e17a877ee78eb1bb2bc8fa0bf5c50000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a000000000000000000000000000000000032e4fbb8dab462ff0352c2d3925b0e97ca662189129928ccc1714364e4f01d8b026887d808342091ad442b6e11635910000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf7800000000000000000000000000000000125742a15d9fe0d485807b4326579b5904c981b9c6ac1e38754379ee662063358f75277321e2624672e99be4be74f687000000000000000000000000000000001546d115c31454dabd79db911c558545c2c15488ce854d741502ff941883cc7d77b3e17a877ee78eb1bb2bc8fa0bf5c5", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_55", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000f1afe9b199362f51cc84edb1d3cf2faf8e5bc0a734a646851ab83e213f73a3734114f255b611ec18db75694dcb0df910000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c7952820000000000000000000000000000000008ceb842a17953578013ceee519a28ef1b37f73e13564def5ffe08a64dc53aa680784e26138176c89269477ee003d16700000000000000000000000000000000159791b6f2c26ed611ca40bfbd2059c15cfec9d073a84254ad9b509ef786d62d17fdc67ab13092cf0b7b3482866f4c320000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000ae6134f1fec83a52e5358db260eb9dc6b918f7a803aae5715854ebee2b9bbecea9ab0d955f2e13e2c47a96b234ecb1a0000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c7952820000000000000000000000000000000008ceb842a17953578013ceee519a28ef1b37f73e13564def5ffe08a64dc53aa680784e26138176c89269477ee003d16700000000000000000000000000000000159791b6f2c26ed611ca40bfbd2059c15cfec9d073a84254ad9b509ef786d62d17fdc67ab13092cf0b7b3482866f4c320000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000f1afe9b199362f51cc84edb1d3cf2faf8e5bc0a734a646851ab83e213f73a3734114f255b611ec18db75694dcb0df910000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c79528200000000000000000000000000000000113259a798069342cb07d8c7f1b183e8493f5446e02ec4d00732c9faa8ebbb7d9e33b1d89dd289372795b8811ffbd944000000000000000000000000000000000469803346bd77c4395166f6862b5316077881b47fdcd06ab9958201ff2a1ff706ae398400236d30ae83cb7d79905e790000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000ae6134f1fec83a52e5358db260eb9dc6b918f7a803aae5715854ebee2b9bbecea9ab0d955f2e13e2c47a96b234ecb1a0000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c79528200000000000000000000000000000000113259a798069342cb07d8c7f1b183e8493f5446e02ec4d00732c9faa8ebbb7d9e33b1d89dd289372795b8811ffbd944000000000000000000000000000000000469803346bd77c4395166f6862b5316077881b47fdcd06ab9958201ff2a1ff706ae398400236d30ae83cb7d79905e79", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_56", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000019275491a51599736722295659dd5589f4e3f558e3d45137a66b4c8066c7514ae66ec35c862cd00bce809db528040c04000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf000000000000000000000000000000001272c63693873e1dabe2c2739310f627d3d9b5bcaa615402c3849ffd8dfe72b40fea4a068064655f2c8f46f074e6518d0000000000000000000000000000000000161a8e5e1de10938e5bce241ae73d76173022127822d744b23e656095c28f2f8d142ceb48b72a1dbc36b6143f8af95000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000000d9bd58946a4d26e3f97e5fe96e574d6f93562c0fb0c187c0c586208fe9a4d9383d3ca22b272ff3eb7e624ad7fb9ea7000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf000000000000000000000000000000001272c63693873e1dabe2c2739310f627d3d9b5bcaa615402c3849ffd8dfe72b40fea4a068064655f2c8f46f074e6518d0000000000000000000000000000000000161a8e5e1de10938e5bce241ae73d76173022127822d744b23e656095c28f2f8d142ceb48b72a1dbc36b6143f8af95000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000019275491a51599736722295659dd5589f4e3f558e3d45137a66b4c8066c7514ae66ec35c862cd00bce809db528040c04000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf00000000000000000000000000000000078e4bb3a5f8a87c9f38e542b03ab6af909d95c84923bebca3ac32a368b283700ec1b5f830ef9aa08d6fb90f8b19591e0000000000000000000000000000000019eaf75bdb6205911235ead4019d390003044963cc02e54b1c0cec4aed54cd3125dabd2ffcc88d5dde3b949ebc06fb16000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000000d9bd58946a4d26e3f97e5fe96e574d6f93562c0fb0c187c0c586208fe9a4d9383d3ca22b272ff3eb7e624ad7fb9ea7000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf00000000000000000000000000000000078e4bb3a5f8a87c9f38e542b03ab6af909d95c84923bebca3ac32a368b283700ec1b5f830ef9aa08d6fb90f8b19591e0000000000000000000000000000000019eaf75bdb6205911235ead4019d390003044963cc02e54b1c0cec4aed54cd3125dabd2ffcc88d5dde3b949ebc06fb16", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_57", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000a896c5a84cbd03e52ae77000eb0285f5704993664a744a89ff6b346efd2efec1a519b67229a3b87e1f80e6aa17e2946000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a220000000000000000000000000000000018a236ea02b1971d6e193a6eb92e1298956679d86864042fb6a0c36dd91c0e385944d779dedd0149fa8a1b3d6a07949d00000000000000000000000000000000048eac7d116b5a7906bce070e2b51ee7c4c493f1415abdb6fd2d35676036d3b741d14b7135419645a6906018e9d3f150000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000f77a58fb4b4165bf86d30b6349b84780d72b24e8eddce16c73a1f5a06de0638045a64978eb9c477d806f1955e818165000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a220000000000000000000000000000000018a236ea02b1971d6e193a6eb92e1298956679d86864042fb6a0c36dd91c0e385944d779dedd0149fa8a1b3d6a07949d00000000000000000000000000000000048eac7d116b5a7906bce070e2b51ee7c4c493f1415abdb6fd2d35676036d3b741d14b7135419645a6906018e9d3f150000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000a896c5a84cbd03e52ae77000eb0285f5704993664a744a89ff6b346efd2efec1a519b67229a3b87e1f80e6aa17e2946000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a2200000000000000000000000000000000015edb0036ce4f7cdd026d478a1d9a3ecf10d1ac8b210e8fb0900f331d94e7ebc5672884d276feb5bf74e4c295f8160e000000000000000000000000000000001572656d28148c21445ec74560968def9fb2b793b22a55086a039d39967a226cdcdab48d7c1269ba136e9fe7162bb95b000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000f77a58fb4b4165bf86d30b6349b84780d72b24e8eddce16c73a1f5a06de0638045a64978eb9c477d806f1955e818165000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a2200000000000000000000000000000000015edb0036ce4f7cdd026d478a1d9a3ecf10d1ac8b210e8fb0900f331d94e7ebc5672884d276feb5bf74e4c295f8160e000000000000000000000000000000001572656d28148c21445ec74560968def9fb2b793b22a55086a039d39967a226cdcdab48d7c1269ba136e9fe7162bb95b", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_58", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000001450bddfa14033ed8cdb94386715013ed9b2c4f9d65944e9d32c0b3545a085113e173e5afcfccb78878414a464d318400000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c95384000000000000000000000000000000000003c96c6f20d7ac31ee7ca77d11e8d25ea78cdf13e5f4d317752320e059e19196f14c15b5a18ca712f3a7cc6f09be6d4000000000000000000000000000000000ebd71f61fcddf1652675f577bbaeec26b892dd954965b057ffb431d6e37cc5425a2a42a0059482c2bd75adb2a120b0b000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000018bc060c3f6be35b724dee72bcda5cc376dc1f35561f7e70c9fe11eda256edd30aca8c19018433483186beb5b9b2792700000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c95384000000000000000000000000000000000003c96c6f20d7ac31ee7ca77d11e8d25ea78cdf13e5f4d317752320e059e19196f14c15b5a18ca712f3a7cc6f09be6d4000000000000000000000000000000000ebd71f61fcddf1652675f577bbaeec26b892dd954965b057ffb431d6e37cc5425a2a42a0059482c2bd75adb2a120b0b000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000001450bddfa14033ed8cdb94386715013ed9b2c4f9d65944e9d32c0b3545a085113e173e5afcfccb78878414a464d318400000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c9538400000000000000000000000000000000019c47b2347726bd72c33dd3e722d1fb179fe7d93b525c58defdea092f112dd0aaf973ea3573b358e8ac483390f63c3d7000000000000000000000000000000000b439ff419b20783f8b4485ec790be14f8ee1dab9eeeb7b9e7358f83887929cff9095bd4b0fab7d38e27a524d5ed9fa0000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000018bc060c3f6be35b724dee72bcda5cc376dc1f35561f7e70c9fe11eda256edd30aca8c19018433483186beb5b9b2792700000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c9538400000000000000000000000000000000019c47b2347726bd72c33dd3e722d1fb179fe7d93b525c58defdea092f112dd0aaf973ea3573b358e8ac483390f63c3d7000000000000000000000000000000000b439ff419b20783f8b4485ec790be14f8ee1dab9eeeb7b9e7358f83887929cff9095bd4b0fab7d38e27a524d5ed9fa0", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_59", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f35556500000000000000000000000000000000120935947070451885bf0c328bd83def193831ab9353844a01130074f16a1ff4d20df8459b5ad6a57d5f1959d37aae920000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e4000000000000000000000000000000000174ffb89d7715866562d9882acb81ce40758644ca3e0decd546c8f5c349b24fce88214956e7540fac36bcfc105cf34a0000000000000000000000000000000003e06c5f607ccf1e2991828034fcdf91106295e7174b4dca21926169451ee58e737d535af45073e2378206e03c81c421000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f3555650000000000000000000000000000000007f7dc55c90fa181c55c9b83b7736ee84b3f19d960318e75661dd22c0546d62f4c9e07b915f9295a3c9fe6a62c84fc190000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e4000000000000000000000000000000000174ffb89d7715866562d9882acb81ce40758644ca3e0decd546c8f5c349b24fce88214956e7540fac36bcfc105cf34a0000000000000000000000000000000003e06c5f607ccf1e2991828034fcdf91106295e7174b4dca21926169451ee58e737d535af45073e2378206e03c81c421000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f35556500000000000000000000000000000000120935947070451885bf0c328bd83def193831ab9353844a01130074f16a1ff4d20df8459b5ad6a57d5f1959d37aae920000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e400000000000000000000000000000000188c12319c08d113e5b8ce2e18802b092401c540294704d291ea09ab336743d45023deb55a6cabf00dc84303efa2b761000000000000000000000000000000001620a58ad903177c218a25360e4ecd465414b59ddc39c4f5459e7137b1921095ab2eaca3bd038c1d827cf91fc37de68a000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f3555650000000000000000000000000000000007f7dc55c90fa181c55c9b83b7736ee84b3f19d960318e75661dd22c0546d62f4c9e07b915f9295a3c9fe6a62c84fc190000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e400000000000000000000000000000000188c12319c08d113e5b8ce2e18802b092401c540294704d291ea09ab336743d45023deb55a6cabf00dc84303efa2b761000000000000000000000000000000001620a58ad903177c218a25360e4ecd465414b59ddc39c4f5459e7137b1921095ab2eaca3bd038c1d827cf91fc37de68a", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_60", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce00000000000000000000000000000000144f438d86d1d808d528ea60c5d343b427124af6e43d4d9652368ddc508daab32fd9c9425cba44fba72e3449e366b1700000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000b15d92f2301075ab0e3215aa72cf9b130bc8e1bcd9fa36375c4b9d7da430ae3e2b24f417336d8729f44542ee7f561d300000000000000000000000000000000197d90090501e8cdea28eb7963231f1a7b5f716cc3a086acb6e7626600d6544132cac943e8d5cefb5daf0a2f8d4006290000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce0000000000000000000000000000000005b1ce5cb2ae0e9175f2bd557d7869233d65008e0f47c52914fa44c4a6234b70eed236bc5499bb0412d0cbb61c98f93b0000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000b15d92f2301075ab0e3215aa72cf9b130bc8e1bcd9fa36375c4b9d7da430ae3e2b24f417336d8729f44542ee7f561d300000000000000000000000000000000197d90090501e8cdea28eb7963231f1a7b5f716cc3a086acb6e7626600d6544132cac943e8d5cefb5daf0a2f8d4006290000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce00000000000000000000000000000000144f438d86d1d808d528ea60c5d343b427124af6e43d4d9652368ddc508daab32fd9c9425cba44fba72e3449e366b1700000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000eeb38bb167edf3f9a38865b9c1eb32633babd6925e56f5bf16c18c91c6deb403bf9b0bd3e1d278d1abaabd1180a48d800000000000000000000000000000000008381e1347dfdcc60f2bc3ce0288dbce917da182fe48c12b049703af5daa1e2ebe136bac87e31045c4ff5d072bfa4820000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce0000000000000000000000000000000005b1ce5cb2ae0e9175f2bd557d7869233d65008e0f47c52914fa44c4a6234b70eed236bc5499bb0412d0cbb61c98f93b0000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000eeb38bb167edf3f9a38865b9c1eb32633babd6925e56f5bf16c18c91c6deb403bf9b0bd3e1d278d1abaabd1180a48d800000000000000000000000000000000008381e1347dfdcc60f2bc3ce0288dbce917da182fe48c12b049703af5daa1e2ebe136bac87e31045c4ff5d072bfa482", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_61", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ec0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d0000000000000000000000000000000007efcb9da7b7ff0f4a1d92489ad76c59158bcc42c5c7a93067772a6d9ef1d3b6df9360d0fc1214e7dec02aaaf7b118bf0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ec0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf23000000000000000000000000000000000143db2b6c68dfa02055ea2cbd11bee04a663c2d8fde6b0919355d755bbbc5a5e23021dfc7b6c1a76460020b4748da41a0000000000000000000000000000000008ef405cd76f7649b315d4afa02f9c40634ebbaf96390c7b3292e798ea4b646d36594b06d14a47ffa0adc2180d02c92e00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d0000000000000000000000000000000007efcb9da7b7ff0f4a1d92489ad76c59158bcc42c5c7a93067772a6d9ef1d3b6df9360d0fc1214e7dec02aaaf7b118bf0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf23000000000000000000000000000000000143db2b6c68dfa02055ea2cbd11bee04a663c2d8fde6b0919355d755bbbc5a5e23021dfc7b6c1a76460020b4748da41a0000000000000000000000000000000008ef405cd76f7649b315d4afa02f9c40634ebbaf96390c7b3292e798ea4b646d36594b06d14a47ffa0adc2180d02c92e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_62", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000b4e7355aea3488234552d3dddfa2d1ad3164056407770e6c54f764193c9dc044cb7f2b157a1c4153b2045867d6f99c5000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000000e7e532ee4b892af39f8a3db7a05cc77a6eb0b3d977c17076bac4a52d5ba003a0ac1f902a4257791a45370eb88426a70000000000000000000000000000000016a556050e4905fa74b5061e3874f05cc7a6c5b049bd3bb7c34adef5a77c393239a600542a4401c3e61978ee6515a30e0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000eb29e948adc9e1816c67a7865517fbc91610b2eb30da1d8a1e15c5f62e71a1fd1f40d4d59b23bea7edeba79829010e6000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000000e7e532ee4b892af39f8a3db7a05cc77a6eb0b3d977c17076bac4a52d5ba003a0ac1f902a4257791a45370eb88426a70000000000000000000000000000000016a556050e4905fa74b5061e3874f05cc7a6c5b049bd3bb7c34adef5a77c393239a600542a4401c3e61978ee6515a30e0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000b4e7355aea3488234552d3dddfa2d1ad3164056407770e6c54f764193c9dc044cb7f2b157a1c4153b2045867d6f99c5000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000019192cb74b345d6f577c1d788bab500fea089ad11a0d514ef0760dfbc95556207dffe06e8711a8869fb9c8f1477b840400000000000000000000000000000000035bbbe52b36e09fd666a1980ad6bc7a9cd085d4a9c7d707a3e5f3ab4f34bcf1e505ffaa870ffe3bd3e587119aea079d0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000eb29e948adc9e1816c67a7865517fbc91610b2eb30da1d8a1e15c5f62e71a1fd1f40d4d59b23bea7edeba79829010e6000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000019192cb74b345d6f577c1d788bab500fea089ad11a0d514ef0760dfbc95556207dffe06e8711a8869fb9c8f1477b840400000000000000000000000000000000035bbbe52b36e09fd666a1980ad6bc7a9cd085d4a9c7d707a3e5f3ab4f34bcf1e505ffaa870ffe3bd3e587119aea079d", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_63", - "Gas": 237000, + "Gas": 168100, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d2900000000000000000000000000000000179c34ba9578d5ff90272a2c7f756794670a047f79a53215da69937152bad0f86576945b12176d3e13cac38d26335c51000000000000000000000000000000000dcc715907e4e17824e24c1f513c09597965941e3ed0aaad6d0c59029b54fb039d716a998c9c418110bd49c5e365507f000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d0000000000000000000000000000000002f2e4467cdc15f1e57d75d6f5c172637df589590863bb437cc5166314e6362b7cd0d7499176b94529979849624cb432000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d2900000000000000000000000000000000179c34ba9578d5ff90272a2c7f756794670a047f79a53215da69937152bad0f86576945b12176d3e13cac38d26335c51000000000000000000000000000000000dcc715907e4e17824e24c1f513c09597965941e3ed0aaad6d0c59029b54fb039d716a998c9c418110bd49c5e365507f000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d29000000000000000000000000000000000264dd2fa407109abaf47d89c3d64542fd6d470579dfe0a98cc73f2fa3f6252bb9356ba39f3c92c1a6343c72d9cc4e5a000000000000000000000000000000000c34a091319b052226395b96f20fa37deb11b766b4b46811fa24799e5b5bfb20813a956524b7be7ea941b63a1c9a5a2c000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d0000000000000000000000000000000002f2e4467cdc15f1e57d75d6f5c172637df589590863bb437cc5166314e6362b7cd0d7499176b94529979849624cb432000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d29000000000000000000000000000000000264dd2fa407109abaf47d89c3d64542fd6d470579dfe0a98cc73f2fa3f6252bb9356ba39f3c92c1a6343c72d9cc4e5a000000000000000000000000000000000c34a091319b052226395b96f20fa37deb11b766b4b46811fa24799e5b5bfb20813a956524b7be7ea941b63a1c9a5a2c000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d2900000000000000000000000000000000179c34ba9578d5ff90272a2c7f756794670a047f79a53215da69937152bad0f86576945b12176d3e13cac38d26335c51000000000000000000000000000000000dcc715907e4e17824e24c1f513c09597965941e3ed0aaad6d0c59029b54fb039d716a998c9c418110bd49c5e365507f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_64", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c853000000000000000000000000000000001643567a0f22b90fefee96c8e2f5851623384c2c68bce9589cdf64c933d494a8d805edce2fd18a6db80f4819391dd1f9000000000000000000000000000000000e4e40ab1969bf9f00ee3b984947ae95bf7b9579bdaeeee926638f9566f8ab26debb4c8d4009535cb6422b2c2ab7282d000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000cab5ed8dc53e9c891df449bd199776adbfc193fc8d6bebf9716610fd4db6def608df059bf29fe43dbf1bf0aa52c1b7f0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c853000000000000000000000000000000001643567a0f22b90fefee96c8e2f5851623384c2c68bce9589cdf64c933d494a8d805edce2fd18a6db80f4819391dd1f9000000000000000000000000000000000e4e40ab1969bf9f00ee3b984947ae95bf7b9579bdaeeee926638f9566f8ab26debb4c8d4009535cb6422b2c2ab7282d000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c8530000000000000000000000000000000003bdbb702a5d2d8a5b2d10ed605627c1413eff588ac82966ca516dd7c2dc617b46a612308182759201efb7e6c6e1d8b2000000000000000000000000000000000bb2d13f201626fb4a2d6c1dfa03fe41a4fbb60b35d623d640cd430b8fb84afd3ff0b371714aaca303bcd4d3d548827e000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000cab5ed8dc53e9c891df449bd199776adbfc193fc8d6bebf9716610fd4db6def608df059bf29fe43dbf1bf0aa52c1b7f0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c8530000000000000000000000000000000003bdbb702a5d2d8a5b2d10ed605627c1413eff588ac82966ca516dd7c2dc617b46a612308182759201efb7e6c6e1d8b2000000000000000000000000000000000bb2d13f201626fb4a2d6c1dfa03fe41a4fbb60b35d623d640cd430b8fb84afd3ff0b371714aaca303bcd4d3d548827e000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c853000000000000000000000000000000001643567a0f22b90fefee96c8e2f5851623384c2c68bce9589cdf64c933d494a8d805edce2fd18a6db80f4819391dd1f9000000000000000000000000000000000e4e40ab1969bf9f00ee3b984947ae95bf7b9579bdaeeee926638f9566f8ab26debb4c8d4009535cb6422b2c2ab7282d", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_65", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f700000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000a27fe0a29c761ce29a731ead969b1db3ae9ef4c05493cc370a128d97ef956c55d9a500991b3e7bf9600383633778ebb000000000000000000000000000000000dbb997ef4970a472bfcf03e959acb90bb13671a3d27c91698975a407856505e93837f46afc965363f21c35a3d194ec0000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf1000000000000000000000000000000001528dcaae381eb764333992e28ed557034ba5413c5b64df40ef3150d2771e5d1cd8c211ca22075c7436e2582960ab3b400000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000a27fe0a29c761ce29a731ead969b1db3ae9ef4c05493cc370a128d97ef956c55d9a500991b3e7bf9600383633778ebb000000000000000000000000000000000dbb997ef4970a472bfcf03e959acb90bb13671a3d27c91698975a407856505e93837f46afc965363f21c35a3d194ec0000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f700000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000fd913e00fb884cc217475cb69e1fafc298d5c38ee3bd5fbf68fa9c777b79f5ec111aff51fa0184023fec7c9cc881bf0000000000000000000000000000000000c45786b44e8dc531f1eb777adb0e146a963e46ab65d49a8ce9978607e5aa5c58b2880b8018a9ac97add3ca5c2e65beb000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf1000000000000000000000000000000001528dcaae381eb764333992e28ed557034ba5413c5b64df40ef3150d2771e5d1cd8c211ca22075c7436e2582960ab3b400000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000fd913e00fb884cc217475cb69e1fafc298d5c38ee3bd5fbf68fa9c777b79f5ec111aff51fa0184023fec7c9cc881bf0000000000000000000000000000000000c45786b44e8dc531f1eb777adb0e146a963e46ab65d49a8ce9978607e5aa5c58b2880b8018a9ac97add3ca5c2e65beb000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f700000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000a27fe0a29c761ce29a731ead969b1db3ae9ef4c05493cc370a128d97ef956c55d9a500991b3e7bf9600383633778ebb000000000000000000000000000000000dbb997ef4970a472bfcf03e959acb90bb13671a3d27c91698975a407856505e93837f46afc965363f21c35a3d194ec0", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_66", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d200000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000eb3f5d24d1a4f520032534f6f81a6806c54df33cbd10c30203423aa4f33620b474cda321e924802b636daaeb34400470000000000000000000000000000000016f004f1dfbf140de042e4f57303928a576d9064f2da5b3ad392331f5c43327c7d2a6fd57456d5ef58b54a3e5ec275080000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c5100000000000000000000000000000000010ee94e9470765ac32b5648f1cd7d745a793dbd46dc95fa32db86929eec385e50cb35755120480be0956a2a342a46d900000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000eb3f5d24d1a4f520032534f6f81a6806c54df33cbd10c30203423aa4f33620b474cda321e924802b636daaeb34400470000000000000000000000000000000016f004f1dfbf140de042e4f57303928a576d9064f2da5b3ad392331f5c43327c7d2a6fd57456d5ef58b54a3e5ec275080000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d200000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000b4d1c17ec6597484ae95466d3ca0656f8226c5127b4068f46fcaef6a77d9418d75f25cc92c1b7fd03c825514cbbaa640000000000000000000000000000000003110cf859c0d28c6ad8c2c0d0481a4d0d09bb2000aab784939e9f819a6dc3a7a18190293cfd2a106149b5c1a13d35a30000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c5100000000000000000000000000000000010ee94e9470765ac32b5648f1cd7d745a793dbd46dc95fa32db86929eec385e50cb35755120480be0956a2a342a46d900000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000b4d1c17ec6597484ae95466d3ca0656f8226c5127b4068f46fcaef6a77d9418d75f25cc92c1b7fd03c825514cbbaa640000000000000000000000000000000003110cf859c0d28c6ad8c2c0d0481a4d0d09bb2000aab784939e9f819a6dc3a7a18190293cfd2a106149b5c1a13d35a30000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d200000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000eb3f5d24d1a4f520032534f6f81a6806c54df33cbd10c30203423aa4f33620b474cda321e924802b636daaeb34400470000000000000000000000000000000016f004f1dfbf140de042e4f57303928a576d9064f2da5b3ad392331f5c43327c7d2a6fd57456d5ef58b54a3e5ec27508", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_67", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531f0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d0000000000000000000000000000000002a36d5efd3381c35ff4f361cd813a96c3e5185141c5985073b45d1319c5f392442b7aa6a253b7eb22d1b5052812be00000000000000000000000000000000000f745dd17966b6befa7f740ea360241162505d6269226ffda90546863d0fff124d8fea13c763cfb69c2f8f12b81d431f0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab0000000000000000000000000000000004acd0ba7577ffe37bdeeaf5810b5a8a4a6b51c3c02bec4e0c6f0cfb4f12283120d283c12ecb7e4be7063fefb37a578c0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d0000000000000000000000000000000002a36d5efd3381c35ff4f361cd813a96c3e5185141c5985073b45d1319c5f392442b7aa6a253b7eb22d1b5052812be00000000000000000000000000000000000f745dd17966b6befa7f740ea360241162505d6269226ffda90546863d0fff124d8fea13c763cfb69c2f8f12b81d431f0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531f0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d00000000000000000000000000000000175da48b3c4c64d6eb26b45475ca7240a0923333b1bf7a6ef37c758ddceb0291da8085580f004814972d4afad7ececab000000000000000000000000000000000a8cb418c0192fdb509c33a79feb88c60226ee228a62a2c1be2b8c1ab9a0f711d11c15eae9f030491dcf70ed47e2678c0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab0000000000000000000000000000000004acd0ba7577ffe37bdeeaf5810b5a8a4a6b51c3c02bec4e0c6f0cfb4f12283120d283c12ecb7e4be7063fefb37a578c0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d00000000000000000000000000000000175da48b3c4c64d6eb26b45475ca7240a0923333b1bf7a6ef37c758ddceb0291da8085580f004814972d4afad7ececab000000000000000000000000000000000a8cb418c0192fdb509c33a79feb88c60226ee228a62a2c1be2b8c1ab9a0f711d11c15eae9f030491dcf70ed47e2678c0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531f0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d0000000000000000000000000000000002a36d5efd3381c35ff4f361cd813a96c3e5185141c5985073b45d1319c5f392442b7aa6a253b7eb22d1b5052812be00000000000000000000000000000000000f745dd17966b6befa7f740ea360241162505d6269226ffda90546863d0fff124d8fea13c763cfb69c2f8f12b81d431f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_68", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e7879000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000000397dbdcc3edf976e8c507f5e70299da8c7765772115bf8edf7dc9024050c2ed98746c2bf7dd4400ab1fb89af991e43f00000000000000000000000000000000139bd5f917f59e2cb6c41c59024c12cdaf95285f3947b80267f36e3bd2701f9548b561c49003fc5ddeee3fe7bc8f5b5b00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e20000000000000000000000000000000012ee6884c9d68bdabe8f4aa92aa613129993aad6a7aafffef1922c910cbd3f8b4ae8a810c59a0b9de0a79d4e5db13232000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000000397dbdcc3edf976e8c507f5e70299da8c7765772115bf8edf7dc9024050c2ed98746c2bf7dd4400ab1fb89af991e43f00000000000000000000000000000000139bd5f917f59e2cb6c41c59024c12cdaf95285f3947b80267f36e3bd2701f9548b561c49003fc5ddeee3fe7bc8f5b5b00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e7879000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000001669360d7591ed2362569fc05c4912fcd7ffe60dd26f533087b3099eb6603336863793d2b976bbff0edf4765066dc66c0000000000000000000000000000000006653bf1218a486d94578b5d40ff9a09b4e22325ba3d5abcff3d64652440d68ed5f69e3a215003a1db10c01843704f5000000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e20000000000000000000000000000000012ee6884c9d68bdabe8f4aa92aa613129993aad6a7aafffef1922c910cbd3f8b4ae8a810c59a0b9de0a79d4e5db13232000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000001669360d7591ed2362569fc05c4912fcd7ffe60dd26f533087b3099eb6603336863793d2b976bbff0edf4765066dc66c0000000000000000000000000000000006653bf1218a486d94578b5d40ff9a09b4e22325ba3d5abcff3d64652440d68ed5f69e3a215003a1db10c01843704f5000000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e7879000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000000397dbdcc3edf976e8c507f5e70299da8c7765772115bf8edf7dc9024050c2ed98746c2bf7dd4400ab1fb89af991e43f00000000000000000000000000000000139bd5f917f59e2cb6c41c59024c12cdaf95285f3947b80267f36e3bd2701f9548b561c49003fc5ddeee3fe7bc8f5b5b", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_69", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b00000000000000000000000000000000197ed996d62fc0628d8ea4adee487df31c794e05e7c327aaa140c6be0109031bb763c5f84bc35a0597dc61e93d23a9bf000000000000000000000000000000001056c1f3c6ae36be26430d142d34b0e807685c79935496414e004cb85900d85a18454bde9c0f2650f19db35eb3dd468d000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e5590000000000000000000000000000000006abf7ef1d5e3484992225b5a59791a68cc7e1e0f8aaf2415a9f759f2dff53f62aecf23e0443fdf37bb3775be9f5c981000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b00000000000000000000000000000000197ed996d62fc0628d8ea4adee487df31c794e05e7c327aaa140c6be0109031bb763c5f84bc35a0597dc61e93d23a9bf000000000000000000000000000000001056c1f3c6ae36be26430d142d34b0e807685c79935496414e004cb85900d85a18454bde9c0f2650f19db35eb3dd468d000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b000000000000000000000000000000000082385363502637bd8d030855032ee447fdfd7f0bc1eb14c5f00be2f5a7f30867483a066590a5fa22229e16c2dc00ec0000000000000000000000000000000009aa4ff672d1afdc24d89aa21616fbef5d0eef0b60307c7e193085e89db01dca0666b4201544d9aec8614ca14c22641e000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e5590000000000000000000000000000000006abf7ef1d5e3484992225b5a59791a68cc7e1e0f8aaf2415a9f759f2dff53f62aecf23e0443fdf37bb3775be9f5c981000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b000000000000000000000000000000000082385363502637bd8d030855032ee447fdfd7f0bc1eb14c5f00be2f5a7f30867483a066590a5fa22229e16c2dc00ec0000000000000000000000000000000009aa4ff672d1afdc24d89aa21616fbef5d0eef0b60307c7e193085e89db01dca0666b4201544d9aec8614ca14c22641e000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b00000000000000000000000000000000197ed996d62fc0628d8ea4adee487df31c794e05e7c327aaa140c6be0109031bb763c5f84bc35a0597dc61e93d23a9bf000000000000000000000000000000001056c1f3c6ae36be26430d142d34b0e807685c79935496414e004cb85900d85a18454bde9c0f2650f19db35eb3dd468d", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_70", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f50000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f0000000000000000000000000000000008789ffe0a8676c6a56742a30a48e5e65b88aafd71859d704fb9f69e5e274ccb6942bc51ad36c5671406052aacf19df9000000000000000000000000000000000c7607f4fc69a25aff00a54369f213c4587404644358da4abf26d151dfa4905ba9731dcfb12e2a3f2c551cacd0f4e47f0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf9250000000000000000000000000000000001b7a86c4142843a854dd0937bdbfd833a34fb15303d753e3f41eaf19f4fd9a6af785804d5ae2c3b99044cc13e6ca4b60000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f0000000000000000000000000000000008789ffe0a8676c6a56742a30a48e5e65b88aafd71859d704fb9f69e5e274ccb6942bc51ad36c5671406052aacf19df9000000000000000000000000000000000c7607f4fc69a25aff00a54369f213c4587404644358da4abf26d151dfa4905ba9731dcfb12e2a3f2c551cacd0f4e47f0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f50000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f00000000000000000000000000000000118871ec2ef96fd3a5b465133902c6f108eea08781ff754f1776dc029889a958b56943ad041d3a98a5f8fad5530e0cb2000000000000000000000000000000000d8b09f53d16443f4c1b0272d95999130c034720b02c3874a80a014f170c65c87538e22f0025d5c08da9e3532f0ac62c0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf9250000000000000000000000000000000001b7a86c4142843a854dd0937bdbfd833a34fb15303d753e3f41eaf19f4fd9a6af785804d5ae2c3b99044cc13e6ca4b60000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f00000000000000000000000000000000118871ec2ef96fd3a5b465133902c6f108eea08781ff754f1776dc029889a958b56943ad041d3a98a5f8fad5530e0cb2000000000000000000000000000000000d8b09f53d16443f4c1b0272d95999130c034720b02c3874a80a014f170c65c87538e22f0025d5c08da9e3532f0ac62c0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f50000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f0000000000000000000000000000000008789ffe0a8676c6a56742a30a48e5e65b88aafd71859d704fb9f69e5e274ccb6942bc51ad36c5671406052aacf19df9000000000000000000000000000000000c7607f4fc69a25aff00a54369f213c4587404644358da4abf26d151dfa4905ba9731dcfb12e2a3f2c551cacd0f4e47f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_71", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b2567300000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000b060965391bfd4afe3271c6ddb91eecb8c7a60451c469d63bb178b1361617000f589c33c35b5deda2f072c6edf2eb370000000000000000000000000000000011c8c988379cd2b82cb8ebd81c3e14d2c01c09dde5690b97623c0876c7554f52ccbaa33d17fb0f0cf331cc85749340cd000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000008151a15a13daeee49a82737118d488005fa7ed1869bc458f8af88e7341e0a48b5d8f129f6eb071fb07c11887f4d543800000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000b060965391bfd4afe3271c6ddb91eecb8c7a60451c469d63bb178b1361617000f589c33c35b5deda2f072c6edf2eb370000000000000000000000000000000011c8c988379cd2b82cb8ebd81c3e14d2c01c09dde5690b97623c0876c7554f52ccbaa33d17fb0f0cf331cc85749340cd000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b2567300000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000efb08850063e94f4ce935ef65928deaabafa580a1c0a8e92b7f59efc09adf240f5363caedf8a212170e8d39120cbf74000000000000000000000000000000000838486201e313e21e62bbde270d9804a45b41a70e1c072804f4ca2a2f5ba6d151f15cc19958f0f2c6cd337a8b6c69de000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000008151a15a13daeee49a82737118d488005fa7ed1869bc458f8af88e7341e0a48b5d8f129f6eb071fb07c11887f4d543800000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000efb08850063e94f4ce935ef65928deaabafa580a1c0a8e92b7f59efc09adf240f5363caedf8a212170e8d39120cbf74000000000000000000000000000000000838486201e313e21e62bbde270d9804a45b41a70e1c072804f4ca2a2f5ba6d151f15cc19958f0f2c6cd337a8b6c69de000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b2567300000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000b060965391bfd4afe3271c6ddb91eecb8c7a60451c469d63bb178b1361617000f589c33c35b5deda2f072c6edf2eb370000000000000000000000000000000011c8c988379cd2b82cb8ebd81c3e14d2c01c09dde5690b97623c0876c7554f52ccbaa33d17fb0f0cf331cc85749340cd", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_72", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc300000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000f05a111b41a54e0ca78c3a1fff3b80bee7c1505a06b9a4faf36a73b87121d2952cc4f4c4e0dcb6633cad12b0caffc620000000000000000000000000000000018daa0f9a2bb347517eee63463b9d6a5e850446e8a94d0986f2921bf81a9f7541e8fee9d7bbb6d9181021af945fce3e3000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a07060000000000000000000000000000000000876cf6553b21053e0d7a4449cd137fd946f2de0f7032f535f54914a8ae7da5afbe765bdfa3a0cdea0a50e1ed43bce800000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000f05a111b41a54e0ca78c3a1fff3b80bee7c1505a06b9a4faf36a73b87121d2952cc4f4c4e0dcb6633cad12b0caffc620000000000000000000000000000000018daa0f9a2bb347517eee63463b9d6a5e850446e8a94d0986f2921bf81a9f7541e8fee9d7bbb6d9181021af945fce3e3000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc300000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000afb70d8856591b980a2e4144357f4cb75fb367f5319786fb7fa2b656f9ed8facbdfb0b26346349986342ed4f34fae4900000000000000000000000000000000012670f096c4b225332cc181df91d6317c27071668f04226f807b0e17506fed0001c11613598926e38fce506ba02c6c8000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a07060000000000000000000000000000000000876cf6553b21053e0d7a4449cd137fd946f2de0f7032f535f54914a8ae7da5afbe765bdfa3a0cdea0a50e1ed43bce800000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000afb70d8856591b980a2e4144357f4cb75fb367f5319786fb7fa2b656f9ed8facbdfb0b26346349986342ed4f34fae4900000000000000000000000000000000012670f096c4b225332cc181df91d6317c27071668f04226f807b0e17506fed0001c11613598926e38fce506ba02c6c8000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc300000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000f05a111b41a54e0ca78c3a1fff3b80bee7c1505a06b9a4faf36a73b87121d2952cc4f4c4e0dcb6633cad12b0caffc620000000000000000000000000000000018daa0f9a2bb347517eee63463b9d6a5e850446e8a94d0986f2921bf81a9f7541e8fee9d7bbb6d9181021af945fce3e3", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_73", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a9035050000000000000000000000000000000017d9e9e2008501981068cb0403e73c270d99defd468cc9dc2d5bbc57750a4a58236f8f7a8df4f8b607095b6a80e7de49000000000000000000000000000000000ebddf4fc74f25be3c358b72a20d1c093f980adfc943b898266592f691e11413c60151a0085d6c9aec8c2d329abbac0d00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c2000000000000000000000000000000001093356407cff41779ce8f3d53dfe7a04edc8ce7192ddfeeb4329c38152cf1875d0df9ffeced95f1c7fae7d124649f21000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a9035050000000000000000000000000000000017d9e9e2008501981068cb0403e73c270d99defd468cc9dc2d5bbc57750a4a58236f8f7a8df4f8b607095b6a80e7de49000000000000000000000000000000000ebddf4fc74f25be3c358b72a20d1c093f980adfc943b898266592f691e11413c60151a0085d6c9aec8c2d329abbac0d00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a903505000000000000000000000000000000000227280838fae5023ab2dcb23f6470b056dd6c87acf848e339d5164981a6abcbfb3c7084235f0749b2f5a4957f17cc62000000000000000000000000000000000b43329a7230c0dc0ee61c43a13e90ce24df40a52a415a2740cb3faa64cfe21058aaae5ea8f69364cd72d2cd6543fe9e00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c2000000000000000000000000000000001093356407cff41779ce8f3d53dfe7a04edc8ce7192ddfeeb4329c38152cf1875d0df9ffeced95f1c7fae7d124649f21000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a903505000000000000000000000000000000000227280838fae5023ab2dcb23f6470b056dd6c87acf848e339d5164981a6abcbfb3c7084235f0749b2f5a4957f17cc62000000000000000000000000000000000b43329a7230c0dc0ee61c43a13e90ce24df40a52a415a2740cb3faa64cfe21058aaae5ea8f69364cd72d2cd6543fe9e00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a9035050000000000000000000000000000000017d9e9e2008501981068cb0403e73c270d99defd468cc9dc2d5bbc57750a4a58236f8f7a8df4f8b607095b6a80e7de49000000000000000000000000000000000ebddf4fc74f25be3c358b72a20d1c093f980adfc943b898266592f691e11413c60151a0085d6c9aec8c2d329abbac0d", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_74", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa300000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000001fdc4256cc997934a65c68ab9767b09c7aad14b5765dbeedb72ab2429231cb333ab9f9143414359376d76857e8972d9000000000000000000000000000000001362f417875259b47cfd9e4c5feda52b949dcbf5b8178318428fd3e70c384020e58f515b9a24af5597cfa037d42491c6000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e0000000000000000000000000000000007007c89288b69f16870dc857a02cd071db8178e578fd2b78fcd5edb5050dcded107a1c1c0071d45e4c4af364bc9400800000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000001fdc4256cc997934a65c68ab9767b09c7aad14b5765dbeedb72ab2429231cb333ab9f9143414359376d76857e8972d9000000000000000000000000000000001362f417875259b47cfd9e4c5feda52b949dcbf5b8178318428fd3e70c384020e58f515b9a24af5597cfa037d42491c6000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa300000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000018034dc4ccb64f0700b5e12b89d531cd9ccc7a399c1f36d08bbe277ccd8dd970eb00606d6e12bca68291897a817637d200000000000000000000000000000000069e1dd2b22d8ce5ce1e0969e35e07abcfd97f8f3b6d8fa724a0feb9ea78b603391caea3172f50aa222f5fc82bdb18e5000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e0000000000000000000000000000000007007c89288b69f16870dc857a02cd071db8178e578fd2b78fcd5edb5050dcded107a1c1c0071d45e4c4af364bc9400800000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000018034dc4ccb64f0700b5e12b89d531cd9ccc7a399c1f36d08bbe277ccd8dd970eb00606d6e12bca68291897a817637d200000000000000000000000000000000069e1dd2b22d8ce5ce1e0969e35e07abcfd97f8f3b6d8fa724a0feb9ea78b603391caea3172f50aa222f5fc82bdb18e5000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa300000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000001fdc4256cc997934a65c68ab9767b09c7aad14b5765dbeedb72ab2429231cb333ab9f9143414359376d76857e8972d9000000000000000000000000000000001362f417875259b47cfd9e4c5feda52b949dcbf5b8178318428fd3e70c384020e58f515b9a24af5597cfa037d42491c6", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_75", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c8000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000010fb029e35b3f6e156b8751415f180ee3960cd3bb6ba9b8e456715ec70b1ba1410b8bfb77998f744d3f462533b59e26c000000000000000000000000000000001472654d9aa210a41d74e3661e05a9eb6b292719b46aa65f94b6abd514bf05f679dae89d21008245d79a381b0d7f51be0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000a76ccda2ca736ce935b4b88e08bbf183f69e2b3f5a471662a5de571976e7d4264021db88b919c896bbbb8128732c3e3000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000010fb029e35b3f6e156b8751415f180ee3960cd3bb6ba9b8e456715ec70b1ba1410b8bfb77998f744d3f462533b59e26c000000000000000000000000000000001472654d9aa210a41d74e3661e05a9eb6b292719b46aa65f94b6abd514bf05f679dae89d21008245d79a381b0d7f51be0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c8000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000009060f4c03cbefb8f46332a22d5a2be92b167e493cca773121c9bcb485ff3c100df3404737bb08bae60a9dacc4a5c83f00000000000000000000000000000000058eac9c9eddd5f62da6c450254602ebf94e246b3f1a6c5fd27a26cbe1f1f02da4d1176190537db9e264c7e4f28058ed0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000a76ccda2ca736ce935b4b88e08bbf183f69e2b3f5a471662a5de571976e7d4264021db88b919c896bbbb8128732c3e3000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000009060f4c03cbefb8f46332a22d5a2be92b167e493cca773121c9bcb485ff3c100df3404737bb08bae60a9dacc4a5c83f00000000000000000000000000000000058eac9c9eddd5f62da6c450254602ebf94e246b3f1a6c5fd27a26cbe1f1f02da4d1176190537db9e264c7e4f28058ed0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c8000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000010fb029e35b3f6e156b8751415f180ee3960cd3bb6ba9b8e456715ec70b1ba1410b8bfb77998f744d3f462533b59e26c000000000000000000000000000000001472654d9aa210a41d74e3661e05a9eb6b292719b46aa65f94b6abd514bf05f679dae89d21008245d79a381b0d7f51be", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_76", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb21100000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d7000000000000000000000000000000000520cfc8c536a1d4e685c4eacbc2000d70abd72e1bf8ce3839d79f5cfa069ed31aafb15542f23b8d1af678bab05a2d410000000000000000000000000000000017cfffda12d21c98b79ac31c5bb696783afb7d69c2bedf0fb070cf7714959db14957a4763564b65b7ed214d7b48d399c000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c00000000000000000000000000000000124a601a06d5094945ec8528c5457ea3f8ca710137b6ad48ee7ad93db53c056059dbc8b02d9edf5e2786c575a0bff89a00000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d7000000000000000000000000000000000520cfc8c536a1d4e685c4eacbc2000d70abd72e1bf8ce3839d79f5cfa069ed31aafb15542f23b8d1af678bab05a2d410000000000000000000000000000000017cfffda12d21c98b79ac31c5bb696783afb7d69c2bedf0fb070cf7714959db14957a4763564b65b7ed214d7b48d399c000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb21100000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d70000000000000000000000000000000014e04221744944c56495e2cb7789acc9f3cb7456d78c44872d593343fcaa575103fc4ea96e61c4729f0887454fa57d6a000000000000000000000000000000000231121026adca019380e499e795165f297bce1b30c633afb6c00329e21b5872d5545b887bef49a43b2ceb284b72710f000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c00000000000000000000000000000000124a601a06d5094945ec8528c5457ea3f8ca710137b6ad48ee7ad93db53c056059dbc8b02d9edf5e2786c575a0bff89a00000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d70000000000000000000000000000000014e04221744944c56495e2cb7789acc9f3cb7456d78c44872d593343fcaa575103fc4ea96e61c4729f0887454fa57d6a000000000000000000000000000000000231121026adca019380e499e795165f297bce1b30c633afb6c00329e21b5872d5545b887bef49a43b2ceb284b72710f000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb21100000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d7000000000000000000000000000000000520cfc8c536a1d4e685c4eacbc2000d70abd72e1bf8ce3839d79f5cfa069ed31aafb15542f23b8d1af678bab05a2d410000000000000000000000000000000017cfffda12d21c98b79ac31c5bb696783afb7d69c2bedf0fb070cf7714959db14957a4763564b65b7ed214d7b48d399c", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_77", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a00000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000007f786ea1cc7cd69ae1061d6b914278dfc7ebe8a714aa8cd04323860314c3b4b36054169dd5c6c60e67bfa3902d216f50000000000000000000000000000000019675b09a4de34af3c6e79452b57b31b6d499200e996008a9e7d1c910ca0ad2a352dc39cb3fd7333182476095b7aeec3000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c04200000000000000000000000000000000001b8c085fd1f34fb273da7d651602b326fef7c357c2fb7845f4c17ce95152042af9e51e7d7699b50f3605bacab563a100000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000007f786ea1cc7cd69ae1061d6b914278dfc7ebe8a714aa8cd04323860314c3b4b36054169dd5c6c60e67bfa3902d216f50000000000000000000000000000000019675b09a4de34af3c6e79452b57b31b6d499200e996008a9e7d1c910ca0ad2a352dc39cb3fd7333182476095b7aeec3000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a00000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000012098b001cb819309d0b45df8a37854967f88cfa823a69f262fe9a40c564bad8e8a6be94d3f7939ed38305c6fd2d93b6000000000000000000000000000000000099b6e094a1b1eb0ead2e7117f3f9bbf72db98409ef1234c8b3b60fea1048f9e97e3c61fd568ccca1da89f6a484bbe8000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c04200000000000000000000000000000000001b8c085fd1f34fb273da7d651602b326fef7c357c2fb7845f4c17ce95152042af9e51e7d7699b50f3605bacab563a100000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000012098b001cb819309d0b45df8a37854967f88cfa823a69f262fe9a40c564bad8e8a6be94d3f7939ed38305c6fd2d93b6000000000000000000000000000000000099b6e094a1b1eb0ead2e7117f3f9bbf72db98409ef1234c8b3b60fea1048f9e97e3c61fd568ccca1da89f6a484bbe8000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a00000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000007f786ea1cc7cd69ae1061d6b914278dfc7ebe8a714aa8cd04323860314c3b4b36054169dd5c6c60e67bfa3902d216f50000000000000000000000000000000019675b09a4de34af3c6e79452b57b31b6d499200e996008a9e7d1c910ca0ad2a352dc39cb3fd7333182476095b7aeec3", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_78", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b0000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000fbe421858e4109c51de57b77da4f9c4c1f950099532d9e30e2f7a8b8b4fb9f708cde1a497050d0944e089978b15321e0000000000000000000000000000000019f48a0bf0f27df65ba766a65e831a0801a4ebcd1995a6002a803f88aead1503b7c39fde8ef5c4672020307241958a880000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000c8bd020743550a6d27f0052d0037547db204e3fd752abf6758d899a3793fd3cd50c3073df6258c20a2f8e4797cbab700000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000fbe421858e4109c51de57b77da4f9c4c1f950099532d9e30e2f7a8b8b4fb9f708cde1a497050d0944e089978b15321e0000000000000000000000000000000019f48a0bf0f27df65ba766a65e831a0801a4ebcd1995a6002a803f88aead1503b7c39fde8ef5c4672020307241958a880000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b0000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000a42cfd1e09bd5fdf93d4ffec5a6b312a27dfb7b5e5238dc590158156b613c2d15de1e5a1a4ef2f6751e766874ea788d00000000000000000000000000000000000c87de488d68a3ef74410fe4c892cf62d25fb7d9ef6cbf3cb093184803e12066e86020225e3b9899decf8dbe6a20230000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000c8bd020743550a6d27f0052d0037547db204e3fd752abf6758d899a3793fd3cd50c3073df6258c20a2f8e4797cbab700000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000a42cfd1e09bd5fdf93d4ffec5a6b312a27dfb7b5e5238dc590158156b613c2d15de1e5a1a4ef2f6751e766874ea788d00000000000000000000000000000000000c87de488d68a3ef74410fe4c892cf62d25fb7d9ef6cbf3cb093184803e12066e86020225e3b9899decf8dbe6a20230000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b0000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000fbe421858e4109c51de57b77da4f9c4c1f950099532d9e30e2f7a8b8b4fb9f708cde1a497050d0944e089978b15321e0000000000000000000000000000000019f48a0bf0f27df65ba766a65e831a0801a4ebcd1995a6002a803f88aead1503b7c39fde8ef5c4672020307241958a88", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_79", - "Gas": 280000, + "Gas": 200700, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff1480000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb00000000000000000000000000000000094a36d86483ac6f068017e4b978c7ea1ee58c429aad5994287f809c69fd5235532487d81f6a46ab827f2e0cb4c6df9e0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff1480000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa0000000000000000000000000000000007cdcfd000a86a408f39ef7cb0a4060dff8965956fbf6b939576a69674fcd5c735056da7988943506f8c35c2de8feaaf0000000000000000000000000000000003484fbf03d06907efbf3eff8b95789484254dc09e42208b7457619a31f795356a2cdfb24bb6e95c192b49a11c6fb9630000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb00000000000000000000000000000000094a36d86483ac6f068017e4b978c7ea1ee58c429aad5994287f809c69fd5235532487d81f6a46ab827f2e0cb4c6df9e0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa0000000000000000000000000000000007cdcfd000a86a408f39ef7cb0a4060dff8965956fbf6b939576a69674fcd5c735056da7988943506f8c35c2de8feaaf0000000000000000000000000000000003484fbf03d06907efbf3eff8b95789484254dc09e42208b7457619a31f795356a2cdfb24bb6e95c192b49a11c6fb9630000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff1480000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb00000000000000000000000000000000094a36d86483ac6f068017e4b978c7ea1ee58c429aad5994287f809c69fd5235532487d81f6a46ab827f2e0cb4c6df9e0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff1480000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa0000000000000000000000000000000007cdcfd000a86a408f39ef7cb0a4060dff8965956fbf6b939576a69674fcd5c735056da7988943506f8c35c2de8feaaf0000000000000000000000000000000003484fbf03d06907efbf3eff8b95789484254dc09e42208b7457619a31f795356a2cdfb24bb6e95c192b49a11c6fb9630000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb00000000000000000000000000000000094a36d86483ac6f068017e4b978c7ea1ee58c429aad5994287f809c69fd5235532487d81f6a46ab827f2e0cb4c6df9e0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa0000000000000000000000000000000007cdcfd000a86a408f39ef7cb0a4060dff8965956fbf6b939576a69674fcd5c735056da7988943506f8c35c2de8feaaf0000000000000000000000000000000003484fbf03d06907efbf3eff8b95789484254dc09e42208b7457619a31f795356a2cdfb24bb6e95c192b49a11c6fb963", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_80", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d5000000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000db912ff1f62be087194f6503b3b273b48bd0907afde777109522329e54cde1092afd48366af3f334c0df42ee98d8d5b00000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d5000000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b56000000000000000000000000000000000337fa3e53480c7865182ecbc7252aa6f9987685dbb814182447183d9da514732157ccffa4188d31eee96bc89c33f3f00000000000000000000000000000000004c5340a5240c4d6f1e095290ac5b6b5d121c5cadc6f30e5dd4855a9cf985e357b1a847cc060bd86aaef85ccf35ee41c00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000db912ff1f62be087194f6503b3b273b48bd0907afde777109522329e54cde1092afd48366af3f334c0df42ee98d8d5b00000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b56000000000000000000000000000000000337fa3e53480c7865182ecbc7252aa6f9987685dbb814182447183d9da514732157ccffa4188d31eee96bc89c33f3f00000000000000000000000000000000004c5340a5240c4d6f1e095290ac5b6b5d121c5cadc6f30e5dd4855a9cf985e357b1a847cc060bd86aaef85ccf35ee41c00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d5000000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000db912ff1f62be087194f6503b3b273b48bd0907afde777109522329e54cde1092afd48366af3f334c0df42ee98d8d5b00000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d5000000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b56000000000000000000000000000000000337fa3e53480c7865182ecbc7252aa6f9987685dbb814182447183d9da514732157ccffa4188d31eee96bc89c33f3f00000000000000000000000000000000004c5340a5240c4d6f1e095290ac5b6b5d121c5cadc6f30e5dd4855a9cf985e357b1a847cc060bd86aaef85ccf35ee41c00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000db912ff1f62be087194f6503b3b273b48bd0907afde777109522329e54cde1092afd48366af3f334c0df42ee98d8d5b00000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b56000000000000000000000000000000000337fa3e53480c7865182ecbc7252aa6f9987685dbb814182447183d9da514732157ccffa4188d31eee96bc89c33f3f00000000000000000000000000000000004c5340a5240c4d6f1e095290ac5b6b5d121c5cadc6f30e5dd4855a9cf985e357b1a847cc060bd86aaef85ccf35ee41c", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_81", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d800000000000000000000000000000000013d98eb6ddf8b68db36819b25d9a7b4a4ed2b1d2593dd6a6e79dc6adaaefd4d8d129d8d949c7421641374a5192b3fd5a00000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000f62f8cda209f1223a7695ed860de2c2b144bd6402ecd61838eded3f40d3df90fe10bd5d92245112e3ce822cb33f8d4b0000000000000000000000000000000018bb0bcf262b7f4583d1375ecce64bd6bb1fcc64fa4b6a93bd9ffbe870fe79df0f29baa92eb844e5c04d09c966e810dc00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d800000000000000000000000000000000013d98eb6ddf8b68db36819b25d9a7b4a4ed2b1d2593dd6a6e79dc6adaaefd4d8d129d8d949c7421641374a5192b3fd5a00000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000f62f8cda209f1223a7695ed860de2c2b144bd6402ecd61838eded3f40d3df90fe10bd5d92245112e3ce822cb33f8d4b0000000000000000000000000000000018bb0bcf262b7f4583d1375ecce64bd6bb1fcc64fa4b6a93bd9ffbe870fe79df0f29baa92eb844e5c04d09c966e810dc00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d800000000000000000000000000000000013d98eb6ddf8b68db36819b25d9a7b4a4ed2b1d2593dd6a6e79dc6adaaefd4d8d129d8d949c7421641374a5192b3fd5a00000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000f62f8cda209f1223a7695ed860de2c2b144bd6402ecd61838eded3f40d3df90fe10bd5d92245112e3ce822cb33f8d4b0000000000000000000000000000000018bb0bcf262b7f4583d1375ecce64bd6bb1fcc64fa4b6a93bd9ffbe870fe79df0f29baa92eb844e5c04d09c966e810dc00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d800000000000000000000000000000000013d98eb6ddf8b68db36819b25d9a7b4a4ed2b1d2593dd6a6e79dc6adaaefd4d8d129d8d949c7421641374a5192b3fd5a00000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000f62f8cda209f1223a7695ed860de2c2b144bd6402ecd61838eded3f40d3df90fe10bd5d92245112e3ce822cb33f8d4b0000000000000000000000000000000018bb0bcf262b7f4583d1375ecce64bd6bb1fcc64fa4b6a93bd9ffbe870fe79df0f29baa92eb844e5c04d09c966e810dc", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_82", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a800000000000000000000000000000000064be06bf988929a026a0ac78603eb822b9f6048ff829083cafc465aabb5e623509c8159ef889974c43634088195185a0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000b6a1b64528770227d79763e494d2d060d50a0530eacb8684147954b6ad194e0a0efd35ff457956b499f58f2177528ee00000000000000000000000000000000048431899516d3d0b8c327d80596e68cf41c94739c6e0fa7ef196332539f2aeeef71890a2db81b9a358e1b4f467a5b34000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a800000000000000000000000000000000064be06bf988929a026a0ac78603eb822b9f6048ff829083cafc465aabb5e623509c8159ef889974c43634088195185a0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000b6a1b64528770227d79763e494d2d060d50a0530eacb8684147954b6ad194e0a0efd35ff457956b499f58f2177528ee00000000000000000000000000000000048431899516d3d0b8c327d80596e68cf41c94739c6e0fa7ef196332539f2aeeef71890a2db81b9a358e1b4f467a5b34000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a800000000000000000000000000000000064be06bf988929a026a0ac78603eb822b9f6048ff829083cafc465aabb5e623509c8159ef889974c43634088195185a0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000b6a1b64528770227d79763e494d2d060d50a0530eacb8684147954b6ad194e0a0efd35ff457956b499f58f2177528ee00000000000000000000000000000000048431899516d3d0b8c327d80596e68cf41c94739c6e0fa7ef196332539f2aeeef71890a2db81b9a358e1b4f467a5b34000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a800000000000000000000000000000000064be06bf988929a026a0ac78603eb822b9f6048ff829083cafc465aabb5e623509c8159ef889974c43634088195185a0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000b6a1b64528770227d79763e494d2d060d50a0530eacb8684147954b6ad194e0a0efd35ff457956b499f58f2177528ee00000000000000000000000000000000048431899516d3d0b8c327d80596e68cf41c94739c6e0fa7ef196332539f2aeeef71890a2db81b9a358e1b4f467a5b34", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_83", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f60000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee410000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000f20033541ee3c68655e2c49f5e2fc8afd33255764267e55b3985790d6bb531db7171fa81caae98449ae3c6bb49225b50000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee410000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f60000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e000000000000000000000000000000000400e7e4eda0a9c13465af099ece14d8b30662fea5e222c6ab71b8fb44562dcc42c5255319741ea56b7cbaa2eab957c9000000000000000000000000000000000b04a27de02c7e71bbc51fcf3268b1eb734b754ae6e1c86ceb2ae0c7d0b40851e24dd497a93abf96168f7a705aeebc6a0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000f20033541ee3c68655e2c49f5e2fc8afd33255764267e55b3985790d6bb531db7171fa81caae98449ae3c6bb49225b50000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e000000000000000000000000000000000400e7e4eda0a9c13465af099ece14d8b30662fea5e222c6ab71b8fb44562dcc42c5255319741ea56b7cbaa2eab957c9000000000000000000000000000000000b04a27de02c7e71bbc51fcf3268b1eb734b754ae6e1c86ceb2ae0c7d0b40851e24dd497a93abf96168f7a705aeebc6a0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f60000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee410000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000f20033541ee3c68655e2c49f5e2fc8afd33255764267e55b3985790d6bb531db7171fa81caae98449ae3c6bb49225b50000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee410000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f60000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e000000000000000000000000000000000400e7e4eda0a9c13465af099ece14d8b30662fea5e222c6ab71b8fb44562dcc42c5255319741ea56b7cbaa2eab957c9000000000000000000000000000000000b04a27de02c7e71bbc51fcf3268b1eb734b754ae6e1c86ceb2ae0c7d0b40851e24dd497a93abf96168f7a705aeebc6a0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000f20033541ee3c68655e2c49f5e2fc8afd33255764267e55b3985790d6bb531db7171fa81caae98449ae3c6bb49225b50000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e000000000000000000000000000000000400e7e4eda0a9c13465af099ece14d8b30662fea5e222c6ab71b8fb44562dcc42c5255319741ea56b7cbaa2eab957c9000000000000000000000000000000000b04a27de02c7e71bbc51fcf3268b1eb734b754ae6e1c86ceb2ae0c7d0b40851e24dd497a93abf96168f7a705aeebc6a", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_84", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886200000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a6168542000000000000000000000000000000000352645e60bb10bc86d6c65a7b0d1dc290ff759c1c2e729a081d4b508b165b46b552ddbcd57a3546658a2aa53b8c224900000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886200000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a10000000000000000000000000000000005f8533875eac92050d86039e855238880b460eeed8c645abfa580b2789a478ddd98b5643be0a68cde274ac22b35b6ec000000000000000000000000000000000b94a5563380e67aa08e1baf868e36e8d3633c3d748cea822ad21f9d579aa1e774c41be88fdc58b61b2390c024fe466c00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a6168542000000000000000000000000000000000352645e60bb10bc86d6c65a7b0d1dc290ff759c1c2e729a081d4b508b165b46b552ddbcd57a3546658a2aa53b8c224900000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a10000000000000000000000000000000005f8533875eac92050d86039e855238880b460eeed8c645abfa580b2789a478ddd98b5643be0a68cde274ac22b35b6ec000000000000000000000000000000000b94a5563380e67aa08e1baf868e36e8d3633c3d748cea822ad21f9d579aa1e774c41be88fdc58b61b2390c024fe466c00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886200000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a6168542000000000000000000000000000000000352645e60bb10bc86d6c65a7b0d1dc290ff759c1c2e729a081d4b508b165b46b552ddbcd57a3546658a2aa53b8c224900000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886200000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a10000000000000000000000000000000005f8533875eac92050d86039e855238880b460eeed8c645abfa580b2789a478ddd98b5643be0a68cde274ac22b35b6ec000000000000000000000000000000000b94a5563380e67aa08e1baf868e36e8d3633c3d748cea822ad21f9d579aa1e774c41be88fdc58b61b2390c024fe466c00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a6168542000000000000000000000000000000000352645e60bb10bc86d6c65a7b0d1dc290ff759c1c2e729a081d4b508b165b46b552ddbcd57a3546658a2aa53b8c224900000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a10000000000000000000000000000000005f8533875eac92050d86039e855238880b460eeed8c645abfa580b2789a478ddd98b5643be0a68cde274ac22b35b6ec000000000000000000000000000000000b94a5563380e67aa08e1baf868e36e8d3633c3d748cea822ad21f9d579aa1e774c41be88fdc58b61b2390c024fe466c", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_85", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000000fc75b0eb2b6afed9d04e4c957ca64c2c595c1a00d295a23113cbb79f4e827b1ff0a40566039e32cd84024a9bd39fc3000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000001585d5f8db92696a596141237f5c78c524db68b482c469cca16c436c040d1d720387aafaa4282383c293d37eceb092d0000000000000000000000000000000013d1a7dfade2113a492ab236c090386e8d6d4ff5bf9ea02bfd80bd389d1b06fc72c00060d6fe3c74ac60775e1f45ae3f000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000000fc75b0eb2b6afed9d04e4c957ca64c2c595c1a00d295a23113cbb79f4e827b1ff0a40566039e32cd84024a9bd39fc3000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000001585d5f8db92696a596141237f5c78c524db68b482c469cca16c436c040d1d720387aafaa4282383c293d37eceb092d0000000000000000000000000000000013d1a7dfade2113a492ab236c090386e8d6d4ff5bf9ea02bfd80bd389d1b06fc72c00060d6fe3c74ac60775e1f45ae3f000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000000fc75b0eb2b6afed9d04e4c957ca64c2c595c1a00d295a23113cbb79f4e827b1ff0a40566039e32cd84024a9bd39fc3000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000001585d5f8db92696a596141237f5c78c524db68b482c469cca16c436c040d1d720387aafaa4282383c293d37eceb092d0000000000000000000000000000000013d1a7dfade2113a492ab236c090386e8d6d4ff5bf9ea02bfd80bd389d1b06fc72c00060d6fe3c74ac60775e1f45ae3f000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000000fc75b0eb2b6afed9d04e4c957ca64c2c595c1a00d295a23113cbb79f4e827b1ff0a40566039e32cd84024a9bd39fc3000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000001585d5f8db92696a596141237f5c78c524db68b482c469cca16c436c040d1d720387aafaa4282383c293d37eceb092d0000000000000000000000000000000013d1a7dfade2113a492ab236c090386e8d6d4ff5bf9ea02bfd80bd389d1b06fc72c00060d6fe3c74ac60775e1f45ae3f", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_86", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb10000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000010093a3820fda13babfc82cc313c6e20c503af71d2c1940cb5b2c879da00bb5d3bfb3aa17c3bab75b99fd74a8b742b52000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb10000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000c7f7169a5067d4a6cf6c21254ce79f8b7b4ed0d0144107900749f2e0ead7c7cfc25c156a0f4cba09cf51b9d03a51e3f00000000000000000000000000000000185b5357fa6340abc3ae41a686a623684e425c1a6f85865a8a8be52a24d5ca7f975b6604571a5f603667ced874cf2afa0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000010093a3820fda13babfc82cc313c6e20c503af71d2c1940cb5b2c879da00bb5d3bfb3aa17c3bab75b99fd74a8b742b52000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000c7f7169a5067d4a6cf6c21254ce79f8b7b4ed0d0144107900749f2e0ead7c7cfc25c156a0f4cba09cf51b9d03a51e3f00000000000000000000000000000000185b5357fa6340abc3ae41a686a623684e425c1a6f85865a8a8be52a24d5ca7f975b6604571a5f603667ced874cf2afa0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb10000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000010093a3820fda13babfc82cc313c6e20c503af71d2c1940cb5b2c879da00bb5d3bfb3aa17c3bab75b99fd74a8b742b52000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb10000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000c7f7169a5067d4a6cf6c21254ce79f8b7b4ed0d0144107900749f2e0ead7c7cfc25c156a0f4cba09cf51b9d03a51e3f00000000000000000000000000000000185b5357fa6340abc3ae41a686a623684e425c1a6f85865a8a8be52a24d5ca7f975b6604571a5f603667ced874cf2afa0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000010093a3820fda13babfc82cc313c6e20c503af71d2c1940cb5b2c879da00bb5d3bfb3aa17c3bab75b99fd74a8b742b52000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000c7f7169a5067d4a6cf6c21254ce79f8b7b4ed0d0144107900749f2e0ead7c7cfc25c156a0f4cba09cf51b9d03a51e3f00000000000000000000000000000000185b5357fa6340abc3ae41a686a623684e425c1a6f85865a8a8be52a24d5ca7f975b6604571a5f603667ced874cf2afa", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_87", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000059a7b662af14e0d3c7016cbafedd42173501fc97199c07114f47acdabd930332af4dea84202253b42b6d947b33de27c0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b272000000000000000000000000000000001949a50c589ec63db98d39491100e8e407345f9b3874f3a28e9b77d2fc28bf31ef976841c4276cb669dc4f3cca42fffd0000000000000000000000000000000001cd05bfae784b11f1c102a7b0268fc480d19cd7c65a3583f4624fc0bc8aa3c97a4c164b3803bc6ccc4e5d5d928110cf0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000059a7b662af14e0d3c7016cbafedd42173501fc97199c07114f47acdabd930332af4dea84202253b42b6d947b33de27c0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b272000000000000000000000000000000001949a50c589ec63db98d39491100e8e407345f9b3874f3a28e9b77d2fc28bf31ef976841c4276cb669dc4f3cca42fffd0000000000000000000000000000000001cd05bfae784b11f1c102a7b0268fc480d19cd7c65a3583f4624fc0bc8aa3c97a4c164b3803bc6ccc4e5d5d928110cf0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000059a7b662af14e0d3c7016cbafedd42173501fc97199c07114f47acdabd930332af4dea84202253b42b6d947b33de27c0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b272000000000000000000000000000000001949a50c589ec63db98d39491100e8e407345f9b3874f3a28e9b77d2fc28bf31ef976841c4276cb669dc4f3cca42fffd0000000000000000000000000000000001cd05bfae784b11f1c102a7b0268fc480d19cd7c65a3583f4624fc0bc8aa3c97a4c164b3803bc6ccc4e5d5d928110cf0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000059a7b662af14e0d3c7016cbafedd42173501fc97199c07114f47acdabd930332af4dea84202253b42b6d947b33de27c0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b272000000000000000000000000000000001949a50c589ec63db98d39491100e8e407345f9b3874f3a28e9b77d2fc28bf31ef976841c4276cb669dc4f3cca42fffd0000000000000000000000000000000001cd05bfae784b11f1c102a7b0268fc480d19cd7c65a3583f4624fc0bc8aa3c97a4c164b3803bc6ccc4e5d5d928110cf", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_88", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab400000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d00000000000000000000000000000000102ba7f9db164318194ab17f615ca8cc741dab773e8609023c58a722f1e4f209eb4bc3cff7a2b71c08bdd421068b9ff700000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab400000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c66400000000000000000000000000000000082961f3752eb7324800bc217514792b2111abe52df54973615737b8ec3a9f2db36dc1782d20782df8efae4bd7b8559600000000000000000000000000000000075729f6b9337b3f25da9d33cdbed7207a589a342cee61e8e99e030244b814accc93b26a0ca6d9ba08acf29511ef15be000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d00000000000000000000000000000000102ba7f9db164318194ab17f615ca8cc741dab773e8609023c58a722f1e4f209eb4bc3cff7a2b71c08bdd421068b9ff700000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c66400000000000000000000000000000000082961f3752eb7324800bc217514792b2111abe52df54973615737b8ec3a9f2db36dc1782d20782df8efae4bd7b8559600000000000000000000000000000000075729f6b9337b3f25da9d33cdbed7207a589a342cee61e8e99e030244b814accc93b26a0ca6d9ba08acf29511ef15be000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab400000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d00000000000000000000000000000000102ba7f9db164318194ab17f615ca8cc741dab773e8609023c58a722f1e4f209eb4bc3cff7a2b71c08bdd421068b9ff700000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab400000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c66400000000000000000000000000000000082961f3752eb7324800bc217514792b2111abe52df54973615737b8ec3a9f2db36dc1782d20782df8efae4bd7b8559600000000000000000000000000000000075729f6b9337b3f25da9d33cdbed7207a589a342cee61e8e99e030244b814accc93b26a0ca6d9ba08acf29511ef15be000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d00000000000000000000000000000000102ba7f9db164318194ab17f615ca8cc741dab773e8609023c58a722f1e4f209eb4bc3cff7a2b71c08bdd421068b9ff700000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c66400000000000000000000000000000000082961f3752eb7324800bc217514792b2111abe52df54973615737b8ec3a9f2db36dc1782d20782df8efae4bd7b8559600000000000000000000000000000000075729f6b9337b3f25da9d33cdbed7207a589a342cee61e8e99e030244b814accc93b26a0ca6d9ba08acf29511ef15be", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_89", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c50000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000b760253acb4c395332c1e3584f60d965a4b0b4f5274f457d05bdafb08546282829ae2c61e482a43136afa03ca0102e90000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c50000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca000000000000000000000000000000000144811cb59ebf7e5a380ca9c2b30dc987778224453ea65ab9fcc5ddd0a91a47aac13a459cf5ecc5bffc5f3c0502e8cc0000000000000000000000000000000007b4c5f3cf21e53b36ed096b1d0998c2be68f6977cbe3e12a63ec77c545316c556bce0a891a762b8af6a4304d0d911e60000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000b760253acb4c395332c1e3584f60d965a4b0b4f5274f457d05bdafb08546282829ae2c61e482a43136afa03ca0102e90000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca000000000000000000000000000000000144811cb59ebf7e5a380ca9c2b30dc987778224453ea65ab9fcc5ddd0a91a47aac13a459cf5ecc5bffc5f3c0502e8cc0000000000000000000000000000000007b4c5f3cf21e53b36ed096b1d0998c2be68f6977cbe3e12a63ec77c545316c556bce0a891a762b8af6a4304d0d911e60000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c50000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000b760253acb4c395332c1e3584f60d965a4b0b4f5274f457d05bdafb08546282829ae2c61e482a43136afa03ca0102e90000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c50000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca000000000000000000000000000000000144811cb59ebf7e5a380ca9c2b30dc987778224453ea65ab9fcc5ddd0a91a47aac13a459cf5ecc5bffc5f3c0502e8cc0000000000000000000000000000000007b4c5f3cf21e53b36ed096b1d0998c2be68f6977cbe3e12a63ec77c545316c556bce0a891a762b8af6a4304d0d911e60000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000b760253acb4c395332c1e3584f60d965a4b0b4f5274f457d05bdafb08546282829ae2c61e482a43136afa03ca0102e90000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca000000000000000000000000000000000144811cb59ebf7e5a380ca9c2b30dc987778224453ea65ab9fcc5ddd0a91a47aac13a459cf5ecc5bffc5f3c0502e8cc0000000000000000000000000000000007b4c5f3cf21e53b36ed096b1d0998c2be68f6977cbe3e12a63ec77c545316c556bce0a891a762b8af6a4304d0d911e6", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_90", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a600000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a470000000000000000000000000000000000cff9184748200fc11245bb213f9d00c3eef7f4698174e9e7a1ff6cf072a30d5f28173aed5fbbdf46b444282225790500000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a600000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca2000000000000000000000000000000000207d4a04d23b1cc880275ea6075f929ea097e464b208c94bf7cb545c76add5a557e5fe08ce4070c77be430e21b38e660000000000000000000000000000000017e907545d9a6a5733fd81aeea0dd92221328dc5b2e745b3102a28f9cbe013b548a061b1ffd55b18059e523a5908d7cd000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a470000000000000000000000000000000000cff9184748200fc11245bb213f9d00c3eef7f4698174e9e7a1ff6cf072a30d5f28173aed5fbbdf46b444282225790500000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca2000000000000000000000000000000000207d4a04d23b1cc880275ea6075f929ea097e464b208c94bf7cb545c76add5a557e5fe08ce4070c77be430e21b38e660000000000000000000000000000000017e907545d9a6a5733fd81aeea0dd92221328dc5b2e745b3102a28f9cbe013b548a061b1ffd55b18059e523a5908d7cd000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a600000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a470000000000000000000000000000000000cff9184748200fc11245bb213f9d00c3eef7f4698174e9e7a1ff6cf072a30d5f28173aed5fbbdf46b444282225790500000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a600000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca2000000000000000000000000000000000207d4a04d23b1cc880275ea6075f929ea097e464b208c94bf7cb545c76add5a557e5fe08ce4070c77be430e21b38e660000000000000000000000000000000017e907545d9a6a5733fd81aeea0dd92221328dc5b2e745b3102a28f9cbe013b548a061b1ffd55b18059e523a5908d7cd000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a470000000000000000000000000000000000cff9184748200fc11245bb213f9d00c3eef7f4698174e9e7a1ff6cf072a30d5f28173aed5fbbdf46b444282225790500000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca2000000000000000000000000000000000207d4a04d23b1cc880275ea6075f929ea097e464b208c94bf7cb545c76add5a557e5fe08ce4070c77be430e21b38e660000000000000000000000000000000017e907545d9a6a5733fd81aeea0dd92221328dc5b2e745b3102a28f9cbe013b548a061b1ffd55b18059e523a5908d7cd", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_91", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000012feb2cdef2060f089c32a68f91d4ac9e0a1461cbf4bd1bf8ed26782a700052ee2fb73af689490ba12233c8dd133158d00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c0130000000000000000000000000000000016b19dd160140ab5592e4e1f46ad0e3e413ceed148adfb0bf5b240a161b22b7dac5b45a389770a634bc8551f72dd12710000000000000000000000000000000009f439fffd4bbbf789bd0b5521a9dcea6e66282a167ce9b26d6543fba82101003d31f4a0ed3592f820d0a6d81c004954000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000012feb2cdef2060f089c32a68f91d4ac9e0a1461cbf4bd1bf8ed26782a700052ee2fb73af689490ba12233c8dd133158d00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c0130000000000000000000000000000000016b19dd160140ab5592e4e1f46ad0e3e413ceed148adfb0bf5b240a161b22b7dac5b45a389770a634bc8551f72dd12710000000000000000000000000000000009f439fffd4bbbf789bd0b5521a9dcea6e66282a167ce9b26d6543fba82101003d31f4a0ed3592f820d0a6d81c004954000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000012feb2cdef2060f089c32a68f91d4ac9e0a1461cbf4bd1bf8ed26782a700052ee2fb73af689490ba12233c8dd133158d00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c0130000000000000000000000000000000016b19dd160140ab5592e4e1f46ad0e3e413ceed148adfb0bf5b240a161b22b7dac5b45a389770a634bc8551f72dd12710000000000000000000000000000000009f439fffd4bbbf789bd0b5521a9dcea6e66282a167ce9b26d6543fba82101003d31f4a0ed3592f820d0a6d81c004954000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000012feb2cdef2060f089c32a68f91d4ac9e0a1461cbf4bd1bf8ed26782a700052ee2fb73af689490ba12233c8dd133158d00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c0130000000000000000000000000000000016b19dd160140ab5592e4e1f46ad0e3e413ceed148adfb0bf5b240a161b22b7dac5b45a389770a634bc8551f72dd12710000000000000000000000000000000009f439fffd4bbbf789bd0b5521a9dcea6e66282a167ce9b26d6543fba82101003d31f4a0ed3592f820d0a6d81c004954", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_92", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_93", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a7", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_94", - "Gas": 409000, + "Gas": 298500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_95", - "Gas": 409000, + "Gas": 298500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_pairing_e(G1,0)=e(0,G2)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 102900, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_pairing_non-degeneracy", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Gas": 70300, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a87002500000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "Name": "bls_pairing_bilinearity", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 135500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "Name": "bls_pairing_e(G1,-G2)=e(-G1,G2)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 102900, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4000000000000000000000000000000000bc2357c6782bbb6a078d9e171fc7a81f7bd8ca73eb485e76317359908bb09bd372fd362a637512a9d48019b383e54890000000000000000000000000000000004b8f49c3bac0247a09487049492b0ed99cf90c56263141daa35f011330d3ced3f3ad78d252c51a3bb42fc7d8f182594000000000000000000000000000000000982d17b17404ac198a0ff5f2dffa56a328d95ec4732d9cca9da420ec7cf716dc63d56d0f5179a8b1ec71fe0328fe88200000000000000000000000000000000147c92cb19e43943bb20c5360a6c4347411eb8ffb3d6f19cc428a8dc0cb3fd1eb3ad02b1c21e21c78f65a7691ee63de90000000000000000000000000000000016cae74dc6523e5273dbd2d9d25c53f1e2c453e6d9ba3f605021cfb514fa0bdf721b05f2200f32591d733e739fabf438000000000000000000000000000000001405df65fb71b738510b3a2fc31c33ef3d884ccc84efb1017341a368bf40727b7ad8cdc8e3fd6b0eb94102488c5cb77000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "Name": "bls_pairing_e(aG1,bG2)=e(abG1,G2)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 102900, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4000000000000000000000000000000000bc2357c6782bbb6a078d9e171fc7a81f7bd8ca73eb485e76317359908bb09bd372fd362a637512a9d48019b383e54890000000000000000000000000000000004b8f49c3bac0247a09487049492b0ed99cf90c56263141daa35f011330d3ced3f3ad78d252c51a3bb42fc7d8f182594000000000000000000000000000000000982d17b17404ac198a0ff5f2dffa56a328d95ec4732d9cca9da420ec7cf716dc63d56d0f5179a8b1ec71fe0328fe88200000000000000000000000000000000147c92cb19e43943bb20c5360a6c4347411eb8ffb3d6f19cc428a8dc0cb3fd1eb3ad02b1c21e21c78f65a7691ee63de90000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000114d1d6855d545a8aa7d76c8cf2e21f267816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca00000000000000000000000000000000166335679f3b3e2617b70c22c48e820e2c6a35149c4f96293035c1494a1ce4591f7a44bce94e9d76def50a71c9e7fa41000000000000000000000000000000000ef11c636091748476331159c8259c064da712ffec033c89299384b4c11b801893026726d992aacdc8e0a28db1a3ab82000000000000000000000000000000000fd8d4944030f480f44ce0d2d4fb67ff6264d30a0f3193cc218b062e5114cf9e4ce847489f7be94b0d4a9fc0c550fdc60000000000000000000000000000000000edba2c166be3d673ea77016163ae5cdf7b3c9bd480e733eb5c08a5f1c798793d339cb503005f5a9e586ea5aabf9695", + "Name": "bls_pairing_e(aG1,bG2)=e(G1,abG2)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 102900, "NoBenchmark": false } ] \ 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 7473d4d35c..7be235452f 100644 --- a/core/vm/testdata/precompiles/fail-blsG1Mul.json +++ b/core/vm/testdata/precompiles/fail-blsG1Mul.json @@ -5,28 +5,33 @@ "Name": "bls_g1mul_empty_input" }, { - "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007", + "Input": "00000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", "ExpectedError": "invalid input length", "Name": "bls_g1mul_short_input" }, { - "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007", + "Input": "000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", "ExpectedError": "invalid input length", "Name": "bls_g1mul_large_input" }, { - "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000108b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007", - "ExpectedError": "invalid field element top bytes", - "Name": "bls_g1mul_violate_top_bytes" - }, - { - "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007", + "Input": "0000000000000000000000000000000031f2e5916b17be2e71b10b4292f558e727dfd7d48af9cbc5087f0ce00dcca27c8b01e83eaace1aefb539f00adb2271660000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", "ExpectedError": "invalid fp.Element encoding", "Name": "bls_g1mul_invalid_field_element" }, { - "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", "ExpectedError": "invalid point: not on curve", "Name": "bls_g1mul_point_not_on_curve" + }, + { + "Input": "1000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_g1mul_violate_top_bytes" + }, + { + "Input": "000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a0000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "g1 point is not on correct subgroup", + "Name": "bls_g1mul_g1_not_in_correct_subgroup" } ] \ 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 24a46cc0d0..2f6c3cdd5b 100644 --- a/core/vm/testdata/precompiles/fail-blsG1MultiExp.json +++ b/core/vm/testdata/precompiles/fail-blsG1MultiExp.json @@ -28,5 +28,10 @@ "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", "ExpectedError": "invalid point: not on curve", "Name": "bls_g1multiexp_point_not_on_curve" + }, + { + "Input": "000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "g1 point is not on correct subgroup", + "Name": "bls_g1multiexp_g1_not_in_correct_subgroup" } ] \ 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 54a13c7f95..bf29dafe02 100644 --- a/core/vm/testdata/precompiles/fail-blsG2Mul.json +++ b/core/vm/testdata/precompiles/fail-blsG2Mul.json @@ -5,28 +5,33 @@ "Name": "bls_g2mul_empty_input" }, { - "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b828010000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007", + "Input": "000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", "ExpectedError": "invalid input length", "Name": "bls_g2mul_short_input" }, { - "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b8280100000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007", + "Input": "0000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", "ExpectedError": "invalid input length", "Name": "bls_g2mul_large_input" }, { - "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000010606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007", - "ExpectedError": "invalid field element top bytes", - "Name": "bls_g2mul_violate_top_bytes" - }, - { - "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007", + "Input": "000000000000000000000000000000001c4bb49d2a0ef12b7123acdd7110bd292b5bc659edc54dc21b81de057194c79b2a5803255959bbef8e7f56c8c12168630000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", "ExpectedError": "invalid fp.Element encoding", "Name": "bls_g2mul_invalid_field_element" }, { - "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb800000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", "ExpectedError": "invalid point: not on curve", "Name": "bls_g2mul_point_not_on_curve" + }, + { + "Input": "10000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_g2mul_violate_top_bytes" + }, + { + "Input": "00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b10000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "g2 point is not on correct subgroup", + "Name": "bls_g2mul_g2_not_in_correct_subgroup" } ] \ 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 1679f17b30..cf78ff07b2 100644 --- a/core/vm/testdata/precompiles/fail-blsG2MultiExp.json +++ b/core/vm/testdata/precompiles/fail-blsG2MultiExp.json @@ -28,5 +28,10 @@ "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", "ExpectedError": "invalid point: not on curve", "Name": "bls_g2multiexp_point_not_on_curve" + }, + { + "Input": "00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "g2 point is not on correct subgroup", + "Name": "bls_pairing_g2_not_in_correct_subgroup" } ] \ 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 8eacca4865..399f6b72dd 100644 --- a/core/vm/testdata/precompiles/fail-blsMapG1.json +++ b/core/vm/testdata/precompiles/fail-blsMapG1.json @@ -5,18 +5,23 @@ "Name": "bls_mapg1_empty_input" }, { - "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Input": "00000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f", "ExpectedError": "invalid input length", "Name": "bls_mapg1_short_input" }, { - "Input": "00000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Input": "0000000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f03", + "ExpectedError": "invalid input length", + "Name": "bls_mapg1_large_input" + }, + { + "Input": "1000000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f", "ExpectedError": "invalid field element top bytes", "Name": "bls_mapg1_top_bytes" }, { - "Input": "000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac", + "Input": "000000000000000000000000000000002f6d9c5465982c0421b61e74579709b3b5b91e57bdd4f6015742b4ff301abb7ef895b9cce00c33c7d48f8e5fa4ac09ae", "ExpectedError": "invalid fp.Element encoding", - "Name": "bls_mapg1_invalid_fq_element" + "Name": "bls_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 184d3ecbaa..9441f62bff 100644 --- a/core/vm/testdata/precompiles/fail-blsMapG2.json +++ b/core/vm/testdata/precompiles/fail-blsMapG2.json @@ -5,18 +5,23 @@ "Name": "bls_mapg2_empty_input" }, { - "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Input": "0000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b7", "ExpectedError": "invalid input length", "Name": "bls_mapg2_short_input" }, { - "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Input": "000000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c", + "ExpectedError": "invalid input length", + "Name": "bls_mapg2_long_input" + }, + { + "Input": "000000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b7", "ExpectedError": "invalid field element top bytes", "Name": "bls_mapg2_top_bytes" }, { - "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac", + "Input": "0000000000000000000000000000000021366f100476ce8d3be6cfc90d59fe13349e388ed12b6dd6dc31ccd267ff000e2c993a063ca66beced06f804d4b8e5af0000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c", "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 4314d7335d..69ec5082f6 100644 --- a/core/vm/testdata/precompiles/fail-blsPairing.json +++ b/core/vm/testdata/precompiles/fail-blsPairing.json @@ -4,6 +4,11 @@ "ExpectedError": "invalid input length", "Name": "bls_pairing_empty_input" }, + { + "Input": "00000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "invalid input length", + "Name": "bls_pairing_missing_data" + }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b8280100000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", "ExpectedError": "invalid input length", diff --git a/params/protocol_params.go b/params/protocol_params.go index 030083aa9a..f06346db84 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -152,14 +152,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 = 500 // Price for BLS12-381 elliptic curve G1 point addition + Bls12381G1AddGas uint64 = 375 // 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 + Bls12381G2AddGas uint64 = 600 // Price for BLS12-381 elliptic curve G2 point addition + Bls12381G2MulGas uint64 = 22500 // Price for BLS12-381 elliptic curve G2 point scalar multiplication + Bls12381PairingBaseGas uint64 = 37700 // Base gas price for BLS12-381 elliptic curve pairing check + Bls12381PairingPerPairGas uint64 = 32600 // 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 + Bls12381MapG2Gas uint64 = 23800 // Gas price for BLS12-381 mapping field element to G2 operation // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529 @@ -179,8 +179,11 @@ const ( HistoryServeWindow = 8192 // Number of blocks to serve historical block hashes for, EIP-2935. ) -// Bls12381MultiExpDiscountTable gas discount table for BLS12-381 G1 and G2 multi exponentiation operations -var Bls12381MultiExpDiscountTable = [128]uint64{1200, 888, 764, 641, 594, 547, 500, 453, 438, 423, 408, 394, 379, 364, 349, 334, 330, 326, 322, 318, 314, 310, 306, 302, 298, 294, 289, 285, 281, 277, 273, 269, 268, 266, 265, 263, 262, 260, 259, 257, 256, 254, 253, 251, 250, 248, 247, 245, 244, 242, 241, 239, 238, 236, 235, 233, 232, 231, 229, 228, 226, 225, 223, 222, 221, 220, 219, 219, 218, 217, 216, 216, 215, 214, 213, 213, 212, 211, 211, 210, 209, 208, 208, 207, 206, 205, 205, 204, 203, 202, 202, 201, 200, 199, 199, 198, 197, 196, 196, 195, 194, 193, 193, 192, 191, 191, 190, 189, 188, 188, 187, 186, 185, 185, 184, 183, 182, 182, 181, 180, 179, 179, 178, 177, 176, 176, 175, 174} +// Bls12381G1MultiExpDiscountTable is the gas discount table for BLS12-381 G1 multi exponentiation operation +var Bls12381G1MultiExpDiscountTable = [128]uint64{1000, 949, 848, 797, 764, 750, 738, 728, 719, 712, 705, 698, 692, 687, 682, 677, 673, 669, 665, 661, 658, 654, 651, 648, 645, 642, 640, 637, 635, 632, 630, 627, 625, 623, 621, 619, 617, 615, 613, 611, 609, 608, 606, 604, 603, 601, 599, 598, 596, 595, 593, 592, 591, 589, 588, 586, 585, 584, 582, 581, 580, 579, 577, 576, 575, 574, 573, 572, 570, 569, 568, 567, 566, 565, 564, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, 547, 546, 545, 544, 543, 542, 541, 540, 540, 539, 538, 537, 536, 536, 535, 534, 533, 532, 532, 531, 530, 529, 528, 528, 527, 526, 525, 525, 524, 523, 522, 522, 521, 520, 520, 519} + +// Bls12381G2MultiExpDiscountTable is the gas discount table for BLS12-381 G2 multi exponentiation operation +var Bls12381G2MultiExpDiscountTable = [128]uint64{1000, 1000, 923, 884, 855, 832, 812, 796, 782, 770, 759, 749, 740, 732, 724, 717, 711, 704, 699, 693, 688, 683, 679, 674, 670, 666, 663, 659, 655, 652, 649, 646, 643, 640, 637, 634, 632, 629, 627, 624, 622, 620, 618, 615, 613, 611, 609, 607, 606, 604, 602, 600, 598, 597, 595, 593, 592, 590, 589, 587, 586, 584, 583, 582, 580, 579, 578, 576, 575, 574, 573, 571, 570, 569, 568, 567, 566, 565, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 552, 551, 550, 549, 548, 547, 546, 545, 545, 544, 543, 542, 541, 541, 540, 539, 538, 537, 537, 536, 535, 535, 534, 533, 532, 532, 531, 530, 530, 529, 528, 528, 527, 526, 526, 525, 524, 524} // Difficulty parameters. var ( diff --git a/tests/fuzzers/bls12381/bls12381_fuzz.go b/tests/fuzzers/bls12381/bls12381_fuzz.go index a3e0e9f72b..9efc6f596f 100644 --- a/tests/fuzzers/bls12381/bls12381_fuzz.go +++ b/tests/fuzzers/bls12381/bls12381_fuzz.go @@ -225,56 +225,6 @@ func fuzzCrossG1MultiExp(data []byte) int { return 1 } -func fuzzCrossG1Mul(data []byte) int { - input := bytes.NewReader(data) - gp, blpAffine, err := getG1Points(input) - if err != nil { - return 0 - } - scalar, err := randomScalar(input, fp.Modulus()) - if err != nil { - return 0 - } - - blScalar := new(blst.Scalar).FromBEndian(common.LeftPadBytes(scalar.Bytes(), 32)) - - blp := new(blst.P1) - blp.FromAffine(blpAffine) - - resBl := blp.Mult(blScalar) - resGeth := (new(gnark.G1Affine)).ScalarMultiplication(gp, scalar) - - if !bytes.Equal(resGeth.Marshal(), resBl.Serialize()) { - panic("bytes(blst.G1) != bytes(geth.G1)") - } - return 1 -} - -func fuzzCrossG2Mul(data []byte) int { - input := bytes.NewReader(data) - gp, blpAffine, err := getG2Points(input) - if err != nil { - return 0 - } - scalar, err := randomScalar(input, fp.Modulus()) - if err != nil { - return 0 - } - - blScalar := new(blst.Scalar).FromBEndian(common.LeftPadBytes(scalar.Bytes(), 32)) - - blp := new(blst.P2) - blp.FromAffine(blpAffine) - - resBl := blp.Mult(blScalar) - resGeth := (new(gnark.G2Affine)).ScalarMultiplication(gp, scalar) - - if !bytes.Equal(resGeth.Marshal(), resBl.Serialize()) { - panic("bytes(blst.G1) != bytes(geth.G1)") - } - return 1 -} - func fuzzCrossG2MultiExp(data []byte) int { var ( input = bytes.NewReader(data) diff --git a/tests/fuzzers/bls12381/bls12381_test.go b/tests/fuzzers/bls12381/bls12381_test.go index d4e5e20e04..cb89d8a7a7 100644 --- a/tests/fuzzers/bls12381/bls12381_test.go +++ b/tests/fuzzers/bls12381/bls12381_test.go @@ -57,12 +57,6 @@ func FuzzG1Add(f *testing.F) { }) } -func FuzzCrossG1Mul(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzzCrossG1Mul(data) - }) -} - func FuzzG1MultiExp(f *testing.F) { f.Fuzz(func(t *testing.T, data []byte) { fuzz(blsG1MultiExp, data) @@ -75,12 +69,6 @@ func FuzzG2Add(f *testing.F) { }) } -func FuzzCrossG2Mul(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzzCrossG2Mul(data) - }) -} - func FuzzG2MultiExp(f *testing.F) { f.Fuzz(func(t *testing.T, data []byte) { fuzz(blsG2MultiExp, data) @@ -116,15 +104,3 @@ func FuzzG2SubgroupChecks(f *testing.F) { fuzzG2SubgroupChecks(data) }) } - -func FuzzG2Mul(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzz(blsG2Mul, data) - }) -} - -func FuzzG1Mul(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzz(blsG1Mul, data) - }) -} diff --git a/tests/fuzzers/bls12381/precompile_fuzzer.go b/tests/fuzzers/bls12381/precompile_fuzzer.go index 4df4db73d1..33b2ca7988 100644 --- a/tests/fuzzers/bls12381/precompile_fuzzer.go +++ b/tests/fuzzers/bls12381/precompile_fuzzer.go @@ -26,28 +26,22 @@ import ( const ( 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) + blsG1MultiExp = byte(12) + blsG2Add = byte(13) + blsG2MultiExp = byte(14) + blsPairing = byte(15) + blsMapG1 = byte(16) + blsMapG2 = byte(17) ) func checkInput(id byte, inputLen int) bool { switch id { case blsG1Add: return inputLen == 256 - case blsG1Mul: - return inputLen == 160 case blsG1MultiExp: return inputLen%160 == 0 case blsG2Add: return inputLen == 512 - case blsG2Mul: - return inputLen == 288 case blsG2MultiExp: return inputLen%288 == 0 case blsPairing: diff --git a/tests/fuzzers/bls12381/testdata/fuzz_g1_mul_seed_corpus.zip b/tests/fuzzers/bls12381/testdata/fuzz_g1_mul_seed_corpus.zip deleted file mode 100644 index 57f9d6696d8c3f73a31d8098ee337eebd7f39d26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37687 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 k`oqG#csO_!mjxc7| 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 x8L5EaMV6x>k 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 TaqXYT@b4mY)ukV;{^|b#ra#C& diff --git a/tests/state_test.go b/tests/state_test.go index 7b82b05e58..da4b8ef79d 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -54,6 +54,10 @@ func initMatcher(st *testMatcher) { // Uses 1GB RAM per tested fork st.skipLoad(`^stStaticCall/static_Call1MB`) + // Out-of-date EIP-2537 tests + // TODO (@s1na) reenable in the future + st.skipLoad(`^stEIP2537/`) + // Broken tests: // EOF is not part of cancun st.skipLoad(`^stEOF/`) From 75526bb8e01b189fc11b12e2bccebc09b2f8f687 Mon Sep 17 00:00:00 2001 From: zhen peng <505380967@qq.com> Date: Fri, 24 Jan 2025 23:16:02 +0800 Subject: [PATCH 069/940] p2p/nat: add stun protocol (#31064) This implements a basic mechanism to query the node's external IP using a STUN server. There is a built-in list of public STUN servers for convenience. The new detection mechanism must be selected explicitly using `--nat=stun` and is not enabled by default in Geth. Fixes #30881 --------- Co-authored-by: Felix Lange --- cmd/utils/flags.go | 2 +- go.mod | 5 ++ go.sum | 34 +++++++++ p2p/nat/nat.go | 7 +- p2p/nat/nat_test.go | 23 ++++++ p2p/nat/stun-list-update.sh | 5 ++ p2p/nat/stun-list.txt | 96 ++++++++++++++++++++++++ p2p/nat/stun.go | 144 ++++++++++++++++++++++++++++++++++++ p2p/nat/stun_test.go | 40 ++++++++++ 9 files changed, 354 insertions(+), 2 deletions(-) create mode 100755 p2p/nat/stun-list-update.sh create mode 100644 p2p/nat/stun-list.txt create mode 100644 p2p/nat/stun.go create mode 100644 p2p/nat/stun_test.go diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 8ef39e88de..f079df83b9 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -760,7 +760,7 @@ var ( } NATFlag = &cli.StringFlag{ Name: "nat", - Usage: "NAT port mapping mechanism (any|none|upnp|pmp|pmp:|extip:)", + Usage: "NAT port mapping mechanism (any|none|upnp|pmp|pmp:|extip:|stun:)", Value: "any", Category: flags.NetworkingCategory, } diff --git a/go.mod b/go.mod index cd1b989e7c..fc768460c7 100644 --- a/go.mod +++ b/go.mod @@ -51,6 +51,7 @@ require ( github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 + github.com/pion/stun/v2 v2.0.0 github.com/protolambda/bls12-381-util v0.1.0 github.com/protolambda/zrnt v0.32.2 github.com/protolambda/ztyp v0.2.2 @@ -126,6 +127,10 @@ require ( github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/pion/dtls/v2 v2.2.7 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/transport/v2 v2.2.1 // indirect + github.com/pion/transport/v3 v3.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.12.0 // indirect diff --git a/go.sum b/go.sum index 2e51046d82..82836a5d8c 100644 --- a/go.sum +++ b/go.sum @@ -423,6 +423,16 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQm github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -485,11 +495,17 @@ github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobt github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= @@ -528,6 +544,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -563,6 +581,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -601,6 +620,10 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -621,6 +644,7 @@ 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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -680,7 +704,9 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -689,6 +715,10 @@ golang.org/x/sys v0.29.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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= 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= @@ -698,6 +728,9 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -750,6 +783,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index f7fe8196c9..5f7af7424d 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -59,13 +59,16 @@ type Interface interface { // "upnp" uses the Universal Plug and Play protocol // "pmp" uses NAT-PMP with an auto-detected gateway address // "pmp:192.168.0.1" uses NAT-PMP with the given gateway address +// "stun" uses stun protocol with default stun server +// "stun:192.168.0.1:1234" uses stun protocol with stun server address 192.168.0.1:1234 func Parse(spec string) (Interface, error) { var ( before, after, found = strings.Cut(spec, ":") mech = strings.ToLower(before) ip net.IP ) - if found { + // stun is not a valid ip + if found && mech != "stun" { ip = net.ParseIP(after) if ip == nil { return nil, errors.New("invalid IP address") @@ -85,6 +88,8 @@ func Parse(spec string) (Interface, error) { return UPnP(), nil case "pmp", "natpmp", "nat-pmp": return PMP(ip), nil + case "stun": + return newSTUN(after) default: return nil, fmt.Errorf("unknown mechanism %q", before) } diff --git a/p2p/nat/nat_test.go b/p2p/nat/nat_test.go index 814e6d9e14..8dd5644fd6 100644 --- a/p2p/nat/nat_test.go +++ b/p2p/nat/nat_test.go @@ -18,8 +18,11 @@ package nat import ( "net" + "strings" "testing" "time" + + "github.com/stretchr/testify/assert" ) // This test checks that autodisc doesn't hang and returns @@ -61,3 +64,23 @@ func TestAutoDiscRace(t *testing.T) { } } } + +// stun should work well +func TestParseStun(t *testing.T) { + testcases := []struct { + natStr string + want *stun + }{ + {"stun", &stun{serverList: strings.Split(stunDefaultServers, "\n")}}, + {"stun:1.2.3.4:1234", &stun{serverList: []string{"1.2.3.4:1234"}}}, + } + + for _, tc := range testcases { + nat, err := Parse(tc.natStr) + if err != nil { + t.Errorf("should no err, but get %v", err) + } + stun := nat.(*stun) + assert.Equal(t, stun.serverList, tc.want.serverList) + } +} diff --git a/p2p/nat/stun-list-update.sh b/p2p/nat/stun-list-update.sh new file mode 100755 index 0000000000..901bfe4ba4 --- /dev/null +++ b/p2p/nat/stun-list-update.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +rm -f stun-list.txt +curl https://raw.githubusercontent.com/pradt2/always-online-stun/refs/heads/master/valid_ipv4s.txt | sort -n >> stun-list.txt +curl https://raw.githubusercontent.com/pradt2/always-online-stun/refs/heads/master/valid_ipv6s.txt | sort -n >> stun-list.txt diff --git a/p2p/nat/stun-list.txt b/p2p/nat/stun-list.txt new file mode 100644 index 0000000000..bc27f7e5a8 --- /dev/null +++ b/p2p/nat/stun-list.txt @@ -0,0 +1,96 @@ +3.132.228.249:3478 +3.78.237.53:3478 +5.161.52.174:3478 +5.161.57.75:3478 +18.185.125.152:3478 +20.93.239.167:3478 +23.21.199.62:3478 +23.21.92.55:3478 +24.204.48.11:3478 +31.184.236.23:3478 +34.195.177.19:3478 +34.197.205.39:3478 +34.206.168.53:3478 +34.74.124.204:3478 +35.158.233.7:3478 +35.177.202.92:3478 +35.180.81.93:3478 +44.230.252.214:3478 +45.15.102.34:3478 +49.12.125.53:3478 +51.255.31.35:3478 +51.68.112.203:3478 +51.68.45.75:3478 +51.83.15.212:3478 +51.83.201.84:3478 +52.24.174.49:3478 +52.26.251.34:3478 +52.47.70.236:3478 +52.52.70.85:3478 +54.197.117.0:3478 +62.72.83.10:3478 +66.228.54.23:3478 +69.20.59.115:3478 +79.140.42.88:3478 +80.155.54.123:3478 +80.156.214.187:3478 +81.3.27.44:3478 +81.82.206.117:3478 +81.83.12.46:3478 +85.197.87.182:3478 +87.253.140.133:3478 +88.198.151.128:3478 +88.218.220.40:3478 +88.99.67.241:3478 +90.145.158.66:3478 +91.212.41.85:3478 +92.205.106.161:3478 +94.140.180.141:3478 +94.23.17.185:3478 +95.216.145.84:3478 +95.216.78.222:3478 +129.153.212.128:3478 +136.243.59.79:3478 +137.74.112.113:3478 +143.198.60.79:3478 +147.182.188.245:3478 +157.161.10.32:3478 +159.69.191.124:3478 +159.69.191.124:443 +172.233.245.118:3478 +176.9.24.184:3478 +185.125.180.70:3478 +185.88.236.76:3478 +188.138.90.169:3478 +188.40.18.246:3478 +188.40.203.74:3478 +192.172.233.145:3478 +192.76.120.66:3478 +193.182.111.151:3478 +193.22.17.97:3478 +194.149.74.157:3478 +195.145.93.141:3478 +195.201.132.113:3478 +195.208.107.138:3478 +198.100.144.121:3478 +209.251.63.76:3478 +212.103.68.7:3478 +212.144.246.197:3478 +212.18.0.14:3478 +212.53.40.40:3478 +212.53.40.43:3478 +213.239.206.5:3478 +213.251.48.147:3478 +217.146.224.74:3478 +217.91.243.229:3478 +[2001:1538:1::224:74]:3478 +[2001:4060:1:1005::10:32]:3478 +[2001:4060:1:1005::10:32]:3478 +[2001:41d0:2:12b9::1]:3478 +[2001:678:b28::118]:3478 +[2600:1f16:8c5:101:80b:b58b:828:8df4]:3478 +[2a00:1169:11b:a6b0::]:3478 +[2a01:4f8:242:56ca::2]:3478 +[2a01:4f8:c17:8f74::1]:3478 +[2a01:4f8:c17:8f74::1]:443 +[2a03:8600::89]:3478 diff --git a/p2p/nat/stun.go b/p2p/nat/stun.go new file mode 100644 index 0000000000..36d54398b5 --- /dev/null +++ b/p2p/nat/stun.go @@ -0,0 +1,144 @@ +// Copyright 2025 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 nat + +import ( + _ "embed" + "errors" + "fmt" + "math/rand" + "net" + "strings" + "time" + + "github.com/ethereum/go-ethereum/log" + stunV2 "github.com/pion/stun/v2" +) + +//go:embed stun-list.txt +var stunDefaultServers string + +const requestLimit = 3 + +var errSTUNFailed = errors.New("STUN requests failed") + +type stun struct { + serverList []string +} + +func newSTUN(serverAddr string) (Interface, error) { + s := new(stun) + if serverAddr == "" { + s.serverList = strings.Split(stunDefaultServers, "\n") + } else { + _, err := net.ResolveUDPAddr("udp4", serverAddr) + if err != nil { + return nil, err + } + s.serverList = []string{serverAddr} + } + return s, nil +} + +func (s stun) String() string { + if len(s.serverList) == 1 { + return fmt.Sprintf("stun:%s", s.serverList[0]) + } + return "stun" +} + +func (s stun) MarshalText() ([]byte, error) { + return []byte(s.String()), nil +} + +func (stun) SupportsMapping() bool { + return false +} + +func (stun) AddMapping(protocol string, extport, intport int, name string, lifetime time.Duration) (uint16, error) { + return uint16(extport), nil +} + +func (stun) DeleteMapping(string, int, int) error { + return nil +} + +func (s *stun) ExternalIP() (net.IP, error) { + for _, server := range s.randomServers(requestLimit) { + ip, err := s.externalIP(server) + if err != nil { + log.Debug("STUN request failed", "server", server, "err", err) + continue + } + return ip, nil + } + return nil, errSTUNFailed +} + +func (s *stun) randomServers(n int) []string { + n = min(n, len(s.serverList)) + m := make(map[int]struct{}, n) + list := make([]string, 0, n) + for i := 0; i < len(s.serverList)*2 && len(list) < n; i++ { + index := rand.Intn(len(s.serverList)) + if _, alreadyHit := m[index]; alreadyHit { + continue + } + list = append(list, s.serverList[index]) + m[index] = struct{}{} + } + return list +} + +func (s *stun) externalIP(server string) (net.IP, error) { + _, _, err := net.SplitHostPort(server) + if err != nil { + server += fmt.Sprintf(":%d", stunV2.DefaultPort) + } + + log.Trace("Attempting STUN binding request", "server", server) + conn, err := stunV2.Dial("udp4", server) + if err != nil { + return nil, err + } + defer conn.Close() + + message, err := stunV2.Build(stunV2.TransactionID, stunV2.BindingRequest) + if err != nil { + return nil, err + } + + var responseError error + var mappedAddr stunV2.XORMappedAddress + err = conn.Do(message, func(event stunV2.Event) { + if event.Error != nil { + responseError = event.Error + return + } + if err := mappedAddr.GetFrom(event.Message); err != nil { + responseError = err + } + }) + if err != nil { + return nil, err + } + if responseError != nil { + return nil, responseError + } + log.Trace("STUN returned IP", "server", server, "ip", mappedAddr.IP) + return mappedAddr.IP, nil +} diff --git a/p2p/nat/stun_test.go b/p2p/nat/stun_test.go new file mode 100644 index 0000000000..b5f429986c --- /dev/null +++ b/p2p/nat/stun_test.go @@ -0,0 +1,40 @@ +// Copyright 2025 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 nat + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNatStun(t *testing.T) { + nat, err := newSTUN("") + assert.NoError(t, err) + _, err = nat.ExternalIP() + assert.NoError(t, err) +} + +func TestUnreachedNatServer(t *testing.T) { + stun := &stun{ + serverList: []string{"198.51.100.2:1234", "198.51.100.5"}, + } + _, err := stun.ExternalIP() + if err != errSTUNFailed { + t.Fatal("wrong error:", err) + } +} From f0e8a3e9c8a59ce3c97c2f474eee7a1e86544e8d Mon Sep 17 00:00:00 2001 From: Christina <156356273+cratiu222@users.noreply.github.com> Date: Sun, 26 Jan 2025 01:53:14 +0200 Subject: [PATCH 070/940] fix README.md (#31076) Hi I fixed 2 minor spelling issues. --------- Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45b80e86a6..fb82459d34 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ HTTP based JSON-RPC API options: * `--http.addr` HTTP-RPC server listening interface (default: `localhost`) * `--http.port` HTTP-RPC server listening port (default: `8545`) * `--http.api` API's offered over the HTTP-RPC interface (default: `eth,net,web3`) - * `--http.corsdomain` Comma separated list of domains from which to accept cross origin requests (browser enforced) + * `--http.corsdomain` Comma separated list of domains from which to accept cross-origin requests (browser enforced) * `--ws` Enable the WS-RPC server * `--ws.addr` WS-RPC server listening interface (default: `localhost`) * `--ws.port` WS-RPC server listening port (default: `8546`) From 9516e0f6b693794dee7191ecbb5cef6749d3eef3 Mon Sep 17 00:00:00 2001 From: Christina <156356273+cratiu222@users.noreply.github.com> Date: Tue, 28 Jan 2025 17:56:23 +0200 Subject: [PATCH 071/940] chore: fix various comments (#31082) --- core/vm/eof_validation_test.go | 2 +- tests/fuzzers/bls12381/bls12381_fuzz.go | 2 +- triedb/pathdb/database.go | 4 ++-- triedb/pathdb/difflayer.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/vm/eof_validation_test.go b/core/vm/eof_validation_test.go index afb856a32c..f7b0e78f26 100644 --- a/core/vm/eof_validation_test.go +++ b/core/vm/eof_validation_test.go @@ -363,7 +363,7 @@ func BenchmarkEOFValidation(b *testing.B) { } } -// BenchmarkEOFValidation tries to benchmark the code validation for the CALLF/RETF operation. +// BenchmarkEOFValidation2 tries to benchmark the code validation for the CALLF/RETF operation. // For this we set up code that calls into 1024 code sections which // - contain calls to some other code sections. // We can't have all code sections calling each other, otherwise we would exceed 48KB. diff --git a/tests/fuzzers/bls12381/bls12381_fuzz.go b/tests/fuzzers/bls12381/bls12381_fuzz.go index 9efc6f596f..5cb05b5660 100644 --- a/tests/fuzzers/bls12381/bls12381_fuzz.go +++ b/tests/fuzzers/bls12381/bls12381_fuzz.go @@ -346,7 +346,7 @@ func multiExpG1Gnark(gs []gnark.G1Affine, scalars []fr.Element) gnark.G1Affine { return res } -// multiExpG1Gnark is a naive implementation of G1 multi-exponentiation +// multiExpG2Gnark is a naive implementation of G2 multi-exponentiation func multiExpG2Gnark(gs []gnark.G2Affine, scalars []fr.Element) gnark.G2Affine { res := gnark.G2Affine{} for i := 0; i < len(gs); i++ { diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index b0d84eb879..d48850c102 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -471,8 +471,8 @@ func (db *Database) Recoverable(root common.Hash) bool { if id == nil { return false } - // Recoverable state must below the disk layer. The recoverable - // state only refers the state that is currently not available, + // Recoverable state must be below the disk layer. The recoverable + // state only refers to the state that is currently not available, // but can be restored by applying state history. dl := db.tree.bottom() if *id >= dl.stateID() { diff --git a/triedb/pathdb/difflayer.go b/triedb/pathdb/difflayer.go index c06026b6ca..2e1d83c74a 100644 --- a/triedb/pathdb/difflayer.go +++ b/triedb/pathdb/difflayer.go @@ -27,8 +27,8 @@ import ( // diffLayer represents a collection of modifications made to the in-memory tries // along with associated state changes after running a block on top. // -// The goal of a diff layer is to act as a journal, tracking recent modifications -// made to the state, that have not yet graduated into a semi-immutable state. +// The purpose of a diff layer is to serve as a journal, recording recent state modifications +// that have not yet been committed to a more stable or semi-permanent state. type diffLayer struct { // Immutables root common.Hash // Root hash to which this layer diff belongs to From 39638c81c56db2b2dfe6f51999ffd3029ee212cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 28 Jan 2025 19:55:41 +0200 Subject: [PATCH 072/940] all: nuke total difficulty (#30744) The total difficulty is the sum of all block difficulties from genesis to a certain block. This value was used in PoW for deciding which chain is heavier, and thus which chain to select. Since PoS has a different fork selection algorithm, all blocks since the merge have a difficulty of 0, and all total difficulties are the same for the past 2 years. Whilst the TDs are mostly useless nowadays, there was never really a reason to mess around removing them since they are so tiny. This reasoning changes when we go down the path of pruned chain history. In order to reconstruct any TD, we **must** retrieve all the headers from chain head to genesis and then iterate all the difficulties to compute the TD. In a world where we completely prune past chain segments (bodies, receipts, headers), it is not possible to reconstruct the TD at all. In a world where we still keep chain headers and prune only the rest, reconstructing it possible as long as we process (or download) the chain forward from genesis, but trying to snap sync the head first and backfill later hits the same issue, the TD becomes impossible to calculate until genesis is backfilled. All in all, the TD is a messy out-of-state, out-of-consensus computed field that is overall useless nowadays, but code relying on it forces the client into certain modes of operation and prevents other modes or other optimizations. This PR completely nukes out the TD from the node. It doesn't compute it, it doesn't operate on it, it's as if it didn't even exist. Caveats: - Whenever we have APIs that return TD (devp2p handshake, tracer, etc.) we return a TD of 0. - For era files, we recompute the TD during export time (fairly quick) to retain the format content. - It is not possible to "verify" the merge point (i.e. with TD gone, TTD is useless). Since we're not verifying PoW any more, just blindly trust it, not verifying but blindly trusting the many year old merge point seems just the same trust model. - Our tests still need to be able to generate pre and post merge blocks, so they need a new way to split the merge without TTD. The PR introduces a settable ttdBlock field on the consensus object which is used by tests as the block where originally the TTD happened. This is not needed for live nodes, we never want to generate old blocks. - One merge transition consensus test was disabled. With a non-operational TD, testing how the client reacts to TTD is useless, it cannot react. Questions: - Should we also drop total terminal difficulty from the genesis json? It's a number we cannot react on any more, so maybe it would be cleaner to get rid of even more concepts. --------- Co-authored-by: Gary Rong --- cmd/devp2p/internal/ethtest/chain.go | 6 +- cmd/devp2p/internal/ethtest/suite.go | 38 ------ cmd/utils/cmd.go | 12 +- consensus/beacon/consensus.go | 129 +++++++++--------- consensus/beacon/faker.go | 41 ------ consensus/consensus.go | 3 - core/bench_test.go | 1 - core/blockchain.go | 60 +++----- core/blockchain_reader.go | 7 - core/blockchain_test.go | 91 +++--------- core/chain_makers.go | 4 - core/chain_makers_test.go | 5 +- core/genesis.go | 1 - core/genesis_test.go | 9 +- core/headerchain.go | 37 +---- core/headerchain_test.go | 4 - core/rawdb/accessors_chain.go | 68 +-------- core/rawdb/accessors_chain_test.go | 40 +----- core/rawdb/ancient_scheme.go | 12 +- core/rawdb/chain_freezer.go | 8 -- core/rawdb/database.go | 2 +- core/rawdb/schema.go | 7 +- core/tracing/hooks.go | 1 - core/txindexer_test.go | 2 +- eth/api_backend.go | 7 - eth/catalyst/api.go | 34 +---- eth/catalyst/api_test.go | 91 +----------- eth/downloader/downloader.go | 4 - eth/downloader/downloader_test.go | 7 - eth/downloader/peer.go | 2 - eth/gasprice/gasprice_test.go | 6 +- eth/handler.go | 3 +- eth/handler_eth_test.go | 6 +- eth/protocols/eth/handler.go | 19 ++- eth/protocols/eth/handler_test.go | 13 +- eth/protocols/eth/handshake.go | 11 +- eth/protocols/eth/handshake_test.go | 12 +- eth/protocols/eth/peer.go | 24 ---- eth/tracers/api_test.go | 2 +- eth/tracers/internal/tracetest/supply_test.go | 5 +- ethstats/ethstats.go | 7 +- graphql/graphql_test.go | 5 +- internal/ethapi/api_test.go | 6 - internal/ethapi/transaction_args_test.go | 1 - tests/block_test.go | 3 + 45 files changed, 177 insertions(+), 679 deletions(-) delete mode 100644 consensus/beacon/faker.go diff --git a/cmd/devp2p/internal/ethtest/chain.go b/cmd/devp2p/internal/ethtest/chain.go index 222c66d4df..a90c53c432 100644 --- a/cmd/devp2p/internal/ethtest/chain.go +++ b/cmd/devp2p/internal/ethtest/chain.go @@ -143,11 +143,7 @@ func (c *Chain) ForkID() forkid.ID { // TD calculates the total difficulty of the chain at the // chain head. func (c *Chain) TD() *big.Int { - sum := new(big.Int) - for _, block := range c.blocks[:c.Len()] { - sum.Add(sum, block.Difficulty()) - } - return sum + return new(big.Int) } // GetBlock returns the block at the specified number. diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go index 5cb9fa0297..12dc5711ac 100644 --- a/cmd/devp2p/internal/ethtest/suite.go +++ b/cmd/devp2p/internal/ethtest/suite.go @@ -18,7 +18,6 @@ package ethtest import ( "crypto/rand" - "math/big" "reflect" "github.com/ethereum/go-ethereum/common" @@ -74,7 +73,6 @@ func (s *Suite) EthTests() []utesting.Test { {Name: "GetBlockBodies", Fn: s.TestGetBlockBodies}, // // malicious handshakes + status {Name: "MaliciousHandshake", Fn: s.TestMaliciousHandshake}, - {Name: "MaliciousStatus", Fn: s.TestMaliciousStatus}, // test transactions {Name: "LargeTxRequest", Fn: s.TestLargeTxRequest, Slow: true}, {Name: "Transaction", Fn: s.TestTransaction}, @@ -453,42 +451,6 @@ func (s *Suite) TestMaliciousHandshake(t *utesting.T) { } } -func (s *Suite) TestMaliciousStatus(t *utesting.T) { - t.Log(`This test sends a malicious eth Status message to the node and expects a disconnect.`) - - conn, err := s.dial() - if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - if err := conn.handshake(); err != nil { - t.Fatalf("handshake failed: %v", err) - } - // Create status with large total difficulty. - status := ð.StatusPacket{ - ProtocolVersion: uint32(conn.negotiatedProtoVersion), - NetworkID: s.chain.config.ChainID.Uint64(), - TD: new(big.Int).SetBytes(randBuf(2048)), - Head: s.chain.Head().Hash(), - Genesis: s.chain.GetBlock(0).Hash(), - ForkID: s.chain.ForkID(), - } - if err := conn.statusExchange(s.chain, status); err != nil { - t.Fatalf("status exchange failed: %v", err) - } - // Wait for disconnect. - code, _, err := conn.Read() - if err != nil { - t.Fatalf("error reading from connection: %v", err) - } - switch code { - case discMsg: - break - default: - t.Fatalf("expected disconnect, got: %d", code) - } -} - func (s *Suite) TestTransaction(t *utesting.T) { t.Log(`This test sends a valid transaction to the node and checks if the transaction gets propagated.`) diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 791b3d1d20..de5918a722 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -25,6 +25,7 @@ import ( "errors" "fmt" "io" + "math/big" "os" "os/signal" "path/filepath" @@ -422,6 +423,10 @@ func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64) er buf = bytes.NewBuffer(nil) checksums []string ) + td := new(big.Int) + for i := uint64(0); i < first; i++ { + td.Add(td, bc.GetHeaderByNumber(i).Difficulty) + } for i := first; i <= last; i += step { err := func() error { filename := filepath.Join(dir, era.Filename(network, int(i/step), common.Hash{})) @@ -444,11 +449,8 @@ func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64) er if receipts == nil { return fmt.Errorf("export failed on #%d: receipts not found", n) } - td := bc.GetTd(block.Hash(), block.NumberU64()) - if td == nil { - return fmt.Errorf("export failed on #%d: total difficulty not found", n) - } - if err := w.Add(block, receipts, td); err != nil { + td.Add(td, block.Difficulty()) + if err := w.Add(block, receipts, new(big.Int).Set(td)); err != nil { return err } } diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index cdacf354a5..20df6d0091 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -61,7 +61,8 @@ var ( // is only used for necessary consensus checks. The legacy consensus engine can be any // engine implements the consensus interface (except the beacon itself). type Beacon struct { - ethone consensus.Engine // Original consensus engine used in eth1, e.g. ethash or clique + ethone consensus.Engine // Original consensus engine used in eth1, e.g. ethash or clique + ttdblock *uint64 // Merge block-number for testchain generation without TTDs } // New creates a consensus engine with the given embedded eth1 engine. @@ -72,6 +73,18 @@ func New(ethone consensus.Engine) *Beacon { return &Beacon{ethone: ethone} } +// TestingTTDBlock is a replacement mechanism for TTD-based pre-/post-merge +// splitting. With chain history deletion, TD calculations become impossible. +// This is fine for progressing the live chain, but to be able to generate test +// chains, we do need a split point. This method supports setting an explicit +// block number to use as the splitter *for testing*, instead of having to keep +// the notion of TDs in the client just for testing. +// +// The block with supplied number is regarded as the last pre-merge block. +func (beacon *Beacon) TestingTTDBlock(number uint64) { + beacon.ttdblock = &number +} + // Author implements consensus.Engine, returning the verified author of the block. func (beacon *Beacon) Author(header *types.Header) (common.Address, error) { if !beacon.IsPoSHeader(header) { @@ -83,67 +96,55 @@ func (beacon *Beacon) Author(header *types.Header) (common.Address, error) { // VerifyHeader checks whether a header conforms to the consensus rules of the // stock Ethereum consensus engine. func (beacon *Beacon) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header) error { - reached, err := IsTTDReached(chain, header.ParentHash, header.Number.Uint64()-1) - if err != nil { - return err - } - if !reached { - return beacon.ethone.VerifyHeader(chain, header) - } - // Short circuit if the parent is not known + // During the live merge transition, the consensus engine used the terminal + // total difficulty to detect when PoW (PoA) switched to PoS. Maintaining the + // total difficulty values however require applying all the blocks from the + // genesis to build up the TD. This stops being a possibility if the tail of + // the chain is pruned already during sync. + // + // One heuristic that can be used to distinguish pre-merge and post-merge + // blocks is whether their *difficulty* is >0 or ==0 respectively. This of + // course would mean that we cannot prove anymore for a past chain that it + // truly transitioned at the correct TTD, but if we consider that ancient + // point in time finalized a long time ago, there should be no attempt from + // the consensus client to rewrite very old history. + // + // One thing that's probably not needed but which we can add to make this + // verification even stricter is to enforce that the chain can switch from + // >0 to ==0 TD only once by forbidding an ==0 to be followed by a >0. + + // Verify that we're not reverting to pre-merge from post-merge parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) if parent == nil { return consensus.ErrUnknownAncestor } - // Sanity checks passed, do a proper verification + if parent.Difficulty.Sign() == 0 && header.Difficulty.Sign() > 0 { + return consensus.ErrInvalidTerminalBlock + } + // Check >0 TDs with pre-merge, --0 TDs with post-merge rules + if header.Difficulty.Sign() > 0 { + return beacon.ethone.VerifyHeader(chain, header) + } return beacon.verifyHeader(chain, header, parent) } -// errOut constructs an error channel with prefilled errors inside. -func errOut(n int, err error) chan error { - errs := make(chan error, n) - for i := 0; i < n; i++ { - errs <- err - } - return errs -} - // splitHeaders splits the provided header batch into two parts according to -// the configured ttd. It requires the parent of header batch along with its -// td are stored correctly in chain. If ttd is not configured yet, all headers -// will be treated legacy PoW headers. +// the difficulty field. +// // Note, this function will not verify the header validity but just split them. -func (beacon *Beacon) splitHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) ([]*types.Header, []*types.Header, error) { - // TTD is not defined yet, all headers should be in legacy format. - ttd := chain.Config().TerminalTotalDifficulty - ptd := chain.GetTd(headers[0].ParentHash, headers[0].Number.Uint64()-1) - if ptd == nil { - return nil, nil, consensus.ErrUnknownAncestor - } - // The entire header batch already crosses the transition. - if ptd.Cmp(ttd) >= 0 { - return nil, headers, nil - } +func (beacon *Beacon) splitHeaders(headers []*types.Header) ([]*types.Header, []*types.Header) { var ( preHeaders = headers postHeaders []*types.Header - td = new(big.Int).Set(ptd) - tdPassed bool ) for i, header := range headers { - if tdPassed { + if header.Difficulty.Sign() == 0 { preHeaders = headers[:i] postHeaders = headers[i:] break } - td = td.Add(td, header.Difficulty) - if td.Cmp(ttd) >= 0 { - // This is the last PoW header, it still belongs to - // the preHeaders, so we cannot split+break yet. - tdPassed = true - } } - return preHeaders, postHeaders, nil + return preHeaders, postHeaders } // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers @@ -151,10 +152,7 @@ func (beacon *Beacon) splitHeaders(chain consensus.ChainHeaderReader, headers [] // a results channel to retrieve the async verifications. // VerifyHeaders expect the headers to be ordered and continuous. func (beacon *Beacon) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) (chan<- struct{}, <-chan error) { - preHeaders, postHeaders, err := beacon.splitHeaders(chain, headers) - if err != nil { - return make(chan struct{}), errOut(len(headers), err) - } + preHeaders, postHeaders := beacon.splitHeaders(headers) if len(postHeaders) == 0 { return beacon.ethone.VerifyHeaders(chain, headers) } @@ -334,12 +332,15 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [ // Prepare implements consensus.Engine, initializing the difficulty field of a // header to conform to the beacon protocol. The changes are done inline. func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { - // Transition isn't triggered yet, use the legacy rules for preparation. - reached, err := IsTTDReached(chain, header.ParentHash, header.Number.Uint64()-1) - if err != nil { - return err - } - if !reached { + // The beacon engine requires access to total difficulties to be able to + // seal pre-merge and post-merge blocks. With the transition to removing + // old blocks, TDs become unaccessible, thus making TTD based pre-/post- + // merge decisions impossible. + // + // We do not need to seal non-merge blocks anymore live, but we do need + // to be able to generate test chains, thus we're reverting to a testing- + // settable field to direct that. + if beacon.ttdblock != nil && *beacon.ttdblock >= header.Number.Uint64() { return beacon.ethone.Prepare(chain, header) } header.Difficulty = beaconDifficulty @@ -449,8 +450,15 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash { // the difficulty that a new block should have when created at time // given the parent block's time and difficulty. func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { - // Transition isn't triggered yet, use the legacy rules for calculation - if reached, _ := IsTTDReached(chain, parent.Hash(), parent.Number.Uint64()); !reached { + // The beacon engine requires access to total difficulties to be able to + // seal pre-merge and post-merge blocks. With the transition to removing + // old blocks, TDs become unaccessible, thus making TTD based pre-/post- + // merge decisions impossible. + // + // We do not need to seal non-merge blocks anymore live, but we do need + // to be able to generate test chains, thus we're reverting to a testing- + // settable field to direct that. + if beacon.ttdblock != nil && *beacon.ttdblock > parent.Number.Uint64() { return beacon.ethone.CalcDifficulty(chain, time, parent) } return beaconDifficulty @@ -491,14 +499,3 @@ func (beacon *Beacon) SetThreads(threads int) { th.SetThreads(threads) } } - -// IsTTDReached checks if the TotalTerminalDifficulty has been surpassed on the `parentHash` block. -// It depends on the parentHash already being stored in the database. -// If the parentHash is not stored in the database a UnknownAncestor error is returned. -func IsTTDReached(chain consensus.ChainHeaderReader, parentHash common.Hash, parentNumber uint64) (bool, error) { - td := chain.GetTd(parentHash, parentNumber) - if td == nil { - return false, consensus.ErrUnknownAncestor - } - return td.Cmp(chain.Config().TerminalTotalDifficulty) >= 0, nil -} diff --git a/consensus/beacon/faker.go b/consensus/beacon/faker.go deleted file mode 100644 index 981e345e3e..0000000000 --- a/consensus/beacon/faker.go +++ /dev/null @@ -1,41 +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 beacon - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/consensus" - "github.com/ethereum/go-ethereum/core/types" -) - -// NewFaker creates a fake consensus engine for testing. -// The fake engine simulates a merged network. -// It can not be used to test the merge transition. -// This type is needed since the fakeChainReader can not be used with -// a normal beacon consensus engine. -func NewFaker() consensus.Engine { - return new(faker) -} - -type faker struct { - Beacon -} - -func (f *faker) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { - return beaconDifficulty -} diff --git a/consensus/consensus.go b/consensus/consensus.go index ff76d31f55..c59b9a4744 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -45,9 +45,6 @@ type ChainHeaderReader interface { // GetHeaderByHash retrieves a block header from the database by its hash. GetHeaderByHash(hash common.Hash) *types.Header - - // GetTd retrieves the total difficulty from the database by hash and number. - GetTd(hash common.Hash, number uint64) *big.Int } // ChainReader defines a small collection of methods needed to access the local diff --git a/core/bench_test.go b/core/bench_test.go index d376830318..155fa6c3b5 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -285,7 +285,6 @@ func makeChainForBench(db ethdb.Database, genesis *Genesis, full bool, count uin rawdb.WriteHeader(db, header) rawdb.WriteCanonicalHash(db, hash, n) - rawdb.WriteTd(db, hash, n, big.NewInt(int64(n+1))) if n == 0 { rawdb.WriteChainConfig(db, hash, genesis.Config) diff --git a/core/blockchain.go b/core/blockchain.go index 6aac541ba0..ab88f4b68e 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -127,7 +127,10 @@ const ( // - Version 8 // The following incompatible database changes were added: // * New scheme for contract code in order to separate the codes and trie nodes - BlockChainVersion uint64 = 8 + // - Version 9 + // Total difficulty has been removed from both the key-value store and the + // ancient store, the td freezer table has been deprecated since that. + BlockChainVersion uint64 = 9 ) // CacheConfig contains the configuration values for the trie database @@ -543,21 +546,16 @@ func (bc *BlockChain) loadLastState() error { var ( currentSnapBlock = bc.CurrentSnapBlock() currentFinalBlock = bc.CurrentFinalBlock() - - headerTd = bc.GetTd(headHeader.Hash(), headHeader.Number.Uint64()) - blockTd = bc.GetTd(headBlock.Hash(), headBlock.NumberU64()) ) if headHeader.Hash() != headBlock.Hash() { - log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.Time), 0))) + log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "age", common.PrettyAge(time.Unix(int64(headHeader.Time), 0))) } - log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(headBlock.Time()), 0))) + log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "age", common.PrettyAge(time.Unix(int64(headBlock.Time()), 0))) if headBlock.Hash() != currentSnapBlock.Hash() { - snapTd := bc.GetTd(currentSnapBlock.Hash(), currentSnapBlock.Number.Uint64()) - log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "td", snapTd, "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.Time), 0))) + log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.Time), 0))) } if currentFinalBlock != nil { - finalTd := bc.GetTd(currentFinalBlock.Hash(), currentFinalBlock.Number.Uint64()) - log.Info("Loaded most recent local finalized block", "number", currentFinalBlock.Number, "hash", currentFinalBlock.Hash(), "td", finalTd, "age", common.PrettyAge(time.Unix(int64(currentFinalBlock.Time), 0))) + log.Info("Loaded most recent local finalized block", "number", currentFinalBlock.Number, "hash", currentFinalBlock.Hash(), "age", common.PrettyAge(time.Unix(int64(currentFinalBlock.Time), 0))) } if pivot := rawdb.ReadLastPivotNumber(bc.db); pivot != nil { log.Info("Loaded last snap-sync pivot marker", "number", *pivot) @@ -989,7 +987,6 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { // Prepare the genesis block and reinitialise the chain batch := bc.db.NewBatch() - rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()) rawdb.WriteBlock(batch, genesis) if err := batch.Write(); err != nil { log.Crit("Failed to write genesis block", "err", err) @@ -1262,8 +1259,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // Ensure genesis is in ancients. if first.NumberU64() == 1 { if frozen, _ := bc.db.Ancients(); frozen == 0 { - td := bc.genesisBlock.Difficulty() - writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []types.Receipts{nil}, td) + writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []types.Receipts{nil}) if err != nil { log.Error("Error writing genesis to ancients", "err", err) return 0, err @@ -1278,10 +1274,8 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ if !bc.HasHeader(last.Hash(), last.NumberU64()) { return 0, fmt.Errorf("containing header #%d [%x..] unknown", last.Number(), last.Hash().Bytes()[:4]) } - // Write all chain data to ancients. - td := bc.GetTd(first.Hash(), first.NumberU64()) - writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain, td) + writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain) if err != nil { log.Error("Error importing chain data to ancients", "err", err) return 0, err @@ -1421,12 +1415,11 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // writeBlockWithoutState writes only the block and its metadata to the database, // but does not write any state. This is used to construct competing side forks // up to the point where they exceed the canonical total difficulty. -func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (err error) { +func (bc *BlockChain) writeBlockWithoutState(block *types.Block) (err error) { if bc.insertStopped() { return errInsertionInterrupted } batch := bc.db.NewBatch() - rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td) rawdb.WriteBlock(batch, block) if err := batch.Write(); err != nil { log.Crit("Failed to write block into disk", "err", err) @@ -1450,20 +1443,14 @@ 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, statedb *state.StateDB) error { - // Calculate the total difficulty of the block - ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) - if ptd == nil { + if !bc.HasHeader(block.ParentHash(), block.NumberU64()-1) { return consensus.ErrUnknownAncestor } - // Make sure no inconsistent state is leaked during insertion - externTd := new(big.Int).Add(block.Difficulty(), ptd) - // Irrelevant of the canonical status, write the block itself to the database. // - // Note all the components of block(td, hash->number map, header, body, receipts) + // Note all the components of block(hash->number map, header, body, receipts) // should be written atomically. BlockBatch is used for containing all components. blockBatch := bc.db.NewBatch() - rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd) rawdb.WriteBlock(blockBatch, block) rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts) rawdb.WritePreimages(blockBatch, statedb.Preimages()) @@ -1757,7 +1744,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness 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(), }) @@ -1882,10 +1868,8 @@ type blockProcessingResult struct { // it writes the block and associated state to database. func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, start time.Time, setHead bool) (_ *blockProcessingResult, blockEndErr error) { 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(), }) @@ -1995,10 +1979,8 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s // 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, makeWitness bool) (*stateless.Witness, int, error) { - var ( - externTd *big.Int - current = bc.CurrentBlock() - ) + var current = bc.CurrentBlock() + // The first sidechain block error is already verified to be ErrPrunedAncestor. // Since we don't import them here, we expect ErrUnknownAncestor for the remaining // ones. Any other errors means that the block is invalid, and should not be written @@ -2010,11 +1992,6 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator, ma canonical := bc.GetBlockByNumber(number) if canonical != nil && canonical.Hash() == block.Hash() { // Not a sidechain block, this is a re-import of a canon block which has it's state pruned - - // Collect the TD of the block. Since we know it's a canon one, - // we can get it directly, and not (like further below) use - // the parent and then add the block on top - externTd = bc.GetTd(block.Hash(), block.NumberU64()) continue } if canonical != nil && canonical.Root() == block.Root() { @@ -2033,14 +2010,9 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator, ma return nil, it.index, errors.New("sidechain ghost-state attack") } } - if externTd == nil { - externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) - } - externTd = new(big.Int).Add(externTd, block.Difficulty()) - if !bc.HasBlock(block.Hash(), block.NumberU64()) { start := time.Now() - if err := bc.writeBlockWithoutState(block, externTd); err != nil { + if err := bc.writeBlockWithoutState(block); err != nil { return nil, it.index, err } log.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(), diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index cf72e98cb2..025b912ceb 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -18,7 +18,6 @@ package core import ( "errors" - "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" @@ -307,12 +306,6 @@ func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLoo return lookup, tx, nil } -// GetTd retrieves a block's total difficulty in the canonical chain from the -// database by hash and number, caching it if found. -func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { - return bc.hc.GetTd(hash, number) -} - // HasState checks if state trie is fully present in the database or not. func (bc *BlockChain) HasState(hash common.Hash) bool { _, err := bc.statedb.OpenTrie(hash) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 84f1b9740c..04dfa87b8b 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -88,7 +88,7 @@ func newGwei(n int64) *big.Int { } // Test fork of length N starting from block i -func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int), scheme string) { +func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, scheme string) { // Copy old chain up to #i into a new db genDb, _, blockchain2, err := newCanonical(ethash.NewFaker(), i, full, scheme) if err != nil { @@ -125,27 +125,15 @@ func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, compara } } // Sanity check that the forked chain can be imported into the original - var tdPre, tdPost *big.Int - if full { - cur := blockchain.CurrentBlock() - tdPre = blockchain.GetTd(cur.Hash(), cur.Number.Uint64()) if err := testBlockChainImport(blockChainB, blockchain); err != nil { t.Fatalf("failed to import forked block chain: %v", err) } - last := blockChainB[len(blockChainB)-1] - tdPost = blockchain.GetTd(last.Hash(), last.NumberU64()) } else { - cur := blockchain.CurrentHeader() - tdPre = blockchain.GetTd(cur.Hash(), cur.Number.Uint64()) if err := testHeaderChainImport(headerChainB, blockchain); err != nil { t.Fatalf("failed to import forked header chain: %v", err) } - last := headerChainB[len(headerChainB)-1] - tdPost = blockchain.GetTd(last.Hash(), last.Number.Uint64()) } - // Compare the total difficulties of the chains - comparator(tdPre, tdPost) } // testBlockChainImport tries to process a chain of blocks, writing them into @@ -179,7 +167,6 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { } blockchain.chainmu.MustLock() - rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTd(block.ParentHash(), block.NumberU64()-1))) rawdb.WriteBlock(blockchain.db, block) statedb.Commit(block.NumberU64(), false, false) blockchain.chainmu.Unlock() @@ -197,7 +184,6 @@ func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error } // Manually insert the header into the database, but don't reorganise (allows subsequent testing) blockchain.chainmu.MustLock() - rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTd(header.ParentHash, header.Number.Uint64()-1))) rawdb.WriteHeader(blockchain.db, header) blockchain.chainmu.Unlock() } @@ -294,17 +280,11 @@ func testExtendCanonical(t *testing.T, full bool, scheme string) { } defer processor.Stop() - // Define the difficulty comparator - better := func(td1, td2 *big.Int) { - if td2.Cmp(td1) <= 0 { - t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1) - } - } // Start fork from current height - testFork(t, processor, length, 1, full, better, scheme) - testFork(t, processor, length, 2, full, better, scheme) - testFork(t, processor, length, 5, full, better, scheme) - testFork(t, processor, length, 10, full, better, scheme) + testFork(t, processor, length, 1, full, scheme) + testFork(t, processor, length, 2, full, scheme) + testFork(t, processor, length, 5, full, scheme) + testFork(t, processor, length, 10, full, scheme) } // Tests that given a starting canonical chain of a given size, it can be extended @@ -353,19 +333,13 @@ func testShorterFork(t *testing.T, full bool, scheme string) { } defer processor.Stop() - // Define the difficulty comparator - worse := func(td1, td2 *big.Int) { - if td2.Cmp(td1) >= 0 { - t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1) - } - } // Sum of numbers must be less than `length` for this to be a shorter fork - testFork(t, processor, 0, 3, full, worse, scheme) - testFork(t, processor, 0, 7, full, worse, scheme) - testFork(t, processor, 1, 1, full, worse, scheme) - testFork(t, processor, 1, 7, full, worse, scheme) - testFork(t, processor, 5, 3, full, worse, scheme) - testFork(t, processor, 5, 4, full, worse, scheme) + testFork(t, processor, 0, 3, full, scheme) + testFork(t, processor, 0, 7, full, scheme) + testFork(t, processor, 1, 1, full, scheme) + testFork(t, processor, 1, 7, full, scheme) + testFork(t, processor, 5, 3, full, scheme) + testFork(t, processor, 5, 4, full, scheme) } // Tests that given a starting canonical chain of a given size, creating shorter @@ -476,19 +450,13 @@ func testEqualFork(t *testing.T, full bool, scheme string) { } defer processor.Stop() - // Define the difficulty comparator - equal := func(td1, td2 *big.Int) { - if td2.Cmp(td1) != 0 { - t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1) - } - } // Sum of numbers must be equal to `length` for this to be an equal fork - testFork(t, processor, 0, 10, full, equal, scheme) - testFork(t, processor, 1, 9, full, equal, scheme) - testFork(t, processor, 2, 8, full, equal, scheme) - testFork(t, processor, 5, 5, full, equal, scheme) - testFork(t, processor, 6, 4, full, equal, scheme) - testFork(t, processor, 9, 1, full, equal, scheme) + testFork(t, processor, 0, 10, full, scheme) + testFork(t, processor, 1, 9, full, scheme) + testFork(t, processor, 2, 8, full, scheme) + testFork(t, processor, 5, 5, full, scheme) + testFork(t, processor, 6, 4, full, scheme) + testFork(t, processor, 9, 1, full, scheme) } // Tests that given a starting canonical chain of a given size, creating equal @@ -647,19 +615,6 @@ func testReorg(t *testing.T, first, second []int64, td int64, full bool, scheme } } } - // Make sure the chain total difficulty is the correct one - want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td)) - if full { - cur := blockchain.CurrentBlock() - if have := blockchain.GetTd(cur.Hash(), cur.Number.Uint64()); have.Cmp(want) != 0 { - t.Errorf("total difficulty mismatch: have %v, want %v", have, want) - } - } else { - cur := blockchain.CurrentHeader() - if have := blockchain.GetTd(cur.Hash(), cur.Number.Uint64()); have.Cmp(want) != 0 { - t.Errorf("total difficulty mismatch: have %v, want %v", have, want) - } - } } // Tests chain insertions in the face of one entity containing an invalid nonce. @@ -809,12 +764,6 @@ func testFastVsFullChains(t *testing.T, scheme string) { for i := 0; i < len(blocks); i++ { num, hash, time := blocks[i].NumberU64(), blocks[i].Hash(), blocks[i].Time() - if ftd, atd := fast.GetTd(hash, num), archive.GetTd(hash, num); ftd.Cmp(atd) != 0 { - t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd) - } - if antd, artd := ancient.GetTd(hash, num), archive.GetTd(hash, num); antd.Cmp(artd) != 0 { - t.Errorf("block #%d [%x]: td mismatch: ancientdb %v, archivedb %v", num, hash, antd, artd) - } if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() { t.Errorf("block #%d [%x]: header mismatch: fastdb %v, archivedb %v", num, hash, fheader, aheader) } @@ -4038,7 +3987,7 @@ func TestEIP3651(t *testing.T) { var ( aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb") - engine = beacon.NewFaker() + engine = beacon.New(ethash.NewFaker()) // A sender who makes transactions, has some funds key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") @@ -4154,7 +4103,7 @@ func TestPragueRequests(t *testing.T) { addr1 = crypto.PubkeyToAddress(key1.PublicKey) config = *params.MergedTestChainConfig signer = types.LatestSigner(&config) - engine = beacon.NewFaker() + engine = beacon.New(ethash.NewFaker()) ) gspec := &Genesis{ Config: &config, @@ -4232,7 +4181,7 @@ func TestEIP7702(t *testing.T) { var ( config = *params.MergedTestChainConfig signer = types.LatestSigner(&config) - engine = beacon.NewFaker() + engine = beacon.New(ethash.NewFaker()) key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") addr1 = crypto.PubkeyToAddress(key1.PublicKey) diff --git a/core/chain_makers.go b/core/chain_makers.go index 5298874a40..d52554a307 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -726,7 +726,3 @@ func (cm *chainMaker) GetHeader(hash common.Hash, number uint64) *types.Header { func (cm *chainMaker) GetBlock(hash common.Hash, number uint64) *types.Block { return cm.blockByNumber(number) } - -func (cm *chainMaker) GetTd(hash common.Hash, number uint64) *big.Int { - return nil // not supported -} diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index f72e6285df..cb1087b4b3 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -80,8 +80,9 @@ func TestGeneratePOSChain(t *testing.T) { Code: common.Hex2Bytes("600154600354"), } genesis := gspec.MustCommit(gendb, triedb.NewDatabase(gendb, triedb.HashDefaults)) + engine := beacon.New(ethash.NewFaker()) - genchain, genreceipts := GenerateChain(gspec.Config, genesis, beacon.NewFaker(), gendb, 4, func(i int, gen *BlockGen) { + genchain, genreceipts := GenerateChain(gspec.Config, genesis, engine, gendb, 4, func(i int, gen *BlockGen) { gen.SetParentBeaconRoot(common.Hash{byte(i + 1)}) // Add value transfer tx. @@ -122,7 +123,7 @@ func TestGeneratePOSChain(t *testing.T) { }) // Import the chain. This runs all block validation rules. - blockchain, _ := NewBlockChain(db, nil, gspec, nil, beacon.NewFaker(), vm.Config{}, nil) + blockchain, _ := NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil) defer blockchain.Stop() if i, err := blockchain.InsertChain(genchain); err != nil { diff --git a/core/genesis.go b/core/genesis.go index 68d945e37e..b579e33c77 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -530,7 +530,6 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo } batch := db.NewBatch() rawdb.WriteGenesisStateSpec(batch, block.Hash(), blob) - rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), block.Difficulty()) rawdb.WriteBlock(batch, block) rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), nil) rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64()) diff --git a/core/genesis_test.go b/core/genesis_test.go index 964ef928c7..4e7662d14c 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -191,7 +191,7 @@ func TestGenesisHashes(t *testing.T) { } } -func TestGenesis_Commit(t *testing.T) { +func TestGenesisCommit(t *testing.T) { genesis := &Genesis{ BaseFee: big.NewInt(params.InitialBaseFee), Config: params.TestChainConfig, @@ -209,13 +209,6 @@ func TestGenesis_Commit(t *testing.T) { if genesisBlock.Difficulty().Cmp(params.GenesisDifficulty) != 0 { t.Errorf("assumption wrong: want: %d, got: %v", params.GenesisDifficulty, genesisBlock.Difficulty()) } - - // Expect the stored total difficulty to be the difficulty of the genesis block. - stored := rawdb.ReadTd(db, genesisBlock.Hash(), genesisBlock.NumberU64()) - - if stored.Cmp(genesisBlock.Difficulty()) != 0 { - t.Errorf("inequal difficulty; stored: %v, genesisBlock: %v", stored, genesisBlock.Difficulty()) - } } func TestReadWriteGenesisAlloc(t *testing.T) { diff --git a/core/headerchain.go b/core/headerchain.go index c587a83fa6..cb707a152f 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -19,7 +19,6 @@ package core import ( "errors" "fmt" - "math/big" "sync/atomic" "time" @@ -36,7 +35,6 @@ import ( const ( headerCacheLimit = 512 - tdCacheLimit = 1024 numberCacheLimit = 2048 ) @@ -65,8 +63,7 @@ type HeaderChain struct { 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 + numberCache *lru.Cache[common.Hash, uint64] // most recent block numbers procInterrupt func() bool engine consensus.Engine @@ -79,7 +76,6 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c config: config, chainDb: chainDb, headerCache: lru.NewCache[common.Hash, *types.Header](headerCacheLimit), - tdCache: lru.NewCache[common.Hash, *big.Int](tdCacheLimit), numberCache: lru.NewCache[common.Hash, uint64](numberCacheLimit), procInterrupt: procInterrupt, engine: engine, @@ -197,14 +193,12 @@ func (hc *HeaderChain) WriteHeaders(headers []*types.Header) (int, error) { if len(headers) == 0 { return 0, nil } - ptd := hc.GetTd(headers[0].ParentHash, headers[0].Number.Uint64()-1) - if ptd == nil { + if !hc.HasHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1) { return 0, consensus.ErrUnknownAncestor } var ( - newTD = new(big.Int).Set(ptd) // Total difficulty of inserted chain - inserted []rawdb.NumberHash // Ephemeral lookup of number/hash for the chain - parentKnown = true // Set to true to force hc.HasHeader check the first iteration + inserted []rawdb.NumberHash // Ephemeral lookup of number/hash for the chain + parentKnown = true // Set to true to force hc.HasHeader check the first iteration batch = hc.chainDb.NewBatch() ) for i, header := range headers { @@ -218,16 +212,11 @@ func (hc *HeaderChain) WriteHeaders(headers []*types.Header) (int, error) { hash = header.Hash() } number := header.Number.Uint64() - newTD.Add(newTD, header.Difficulty) // If the parent was not present, store it // If the header is already known, skip it, otherwise store alreadyKnown := parentKnown && hc.HasHeader(hash, number) if !alreadyKnown { - // Irrelevant of the canonical status, write the TD and header to the database. - rawdb.WriteTd(batch, hash, number, newTD) - hc.tdCache.Add(hash, new(big.Int).Set(newTD)) - rawdb.WriteHeader(batch, header) inserted = append(inserted, rawdb.NumberHash{Number: number, Hash: hash}) hc.headerCache.Add(hash, header) @@ -392,22 +381,6 @@ func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, ma return hash, number } -// GetTd retrieves a block's total difficulty in the canonical chain from the -// database by hash and number, caching it if found. -func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int { - // Short circuit if the td's already in the cache, retrieve otherwise - if cached, ok := hc.tdCache.Get(hash); ok { - return cached - } - td := rawdb.ReadTd(hc.chainDb, hash, number) - if td == nil { - return nil - } - // Cache the found body for next time and return - hc.tdCache.Add(hash, td) - return td -} - // GetHeader retrieves a block header from the database by hash and number, // caching it if found. func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header { @@ -620,7 +593,6 @@ func (hc *HeaderChain) setHead(headBlock uint64, headTime uint64, updateFn Updat delFn(batch, hash, num) } rawdb.DeleteHeader(batch, hash, num) - rawdb.DeleteTd(batch, hash, num) } rawdb.DeleteCanonicalHash(batch, num) } @@ -631,7 +603,6 @@ func (hc *HeaderChain) setHead(headBlock uint64, headTime uint64, updateFn Updat } // Clear out any stale content from the caches hc.headerCache.Purge() - hc.tdCache.Purge() hc.numberCache.Purge() } diff --git a/core/headerchain_test.go b/core/headerchain_test.go index 3228d82f0f..b51fb8f226 100644 --- a/core/headerchain_test.go +++ b/core/headerchain_test.go @@ -39,10 +39,6 @@ func verifyUnbrokenCanonchain(hc *HeaderChain) error { return fmt.Errorf("Canon hash chain broken, block %d got %x, expected %x", h.Number, canonHash[:8], exp[:8]) } - // Verify that we have the TD - if td := rawdb.ReadTd(hc.chainDb, canonHash, h.Number.Uint64()); td == nil { - return fmt.Errorf("Canon TD missing at block %d", h.Number) - } if h.Number.Uint64() == 0 { break } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index c4735c850c..a586046d5f 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -508,54 +508,6 @@ func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { } } -// ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding. -func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { - var data []byte - db.ReadAncients(func(reader ethdb.AncientReaderOp) error { - // Check if the data is in ancients - if isCanon(reader, number, hash) { - data, _ = reader.Ancient(ChainFreezerDifficultyTable, number) - return nil - } - // If not, try reading from leveldb - data, _ = db.Get(headerTDKey(number, hash)) - return nil - }) - return data -} - -// ReadTd retrieves a block's total difficulty corresponding to the hash. -func ReadTd(db ethdb.Reader, hash common.Hash, number uint64) *big.Int { - data := ReadTdRLP(db, hash, number) - if len(data) == 0 { - return nil - } - td := new(big.Int) - if err := rlp.DecodeBytes(data, td); err != nil { - log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err) - return nil - } - return td -} - -// WriteTd stores the total difficulty of a block into the database. -func WriteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64, td *big.Int) { - data, err := rlp.EncodeToBytes(td) - if err != nil { - log.Crit("Failed to RLP encode block total difficulty", "err", err) - } - if err := db.Put(headerTDKey(number, hash), data); err != nil { - log.Crit("Failed to store block total difficulty", "err", err) - } -} - -// DeleteTd removes all block total difficulty data associated with a hash. -func DeleteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - if err := db.Delete(headerTDKey(number, hash)); err != nil { - log.Crit("Failed to delete block total difficulty", "err", err) - } -} - // HasReceipts verifies the existence of all the transaction receipts belonging // to a block. func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool { @@ -741,11 +693,9 @@ func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { } // WriteAncientBlocks writes entire block data into ancient store and returns the total written size. -func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []types.Receipts, td *big.Int) (int64, error) { - var ( - tdSum = new(big.Int).Set(td) - stReceipts []*types.ReceiptForStorage - ) +func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []types.Receipts) (int64, error) { + var stReceipts []*types.ReceiptForStorage + return db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i, block := range blocks { // Convert receipts to storage format and sum up total difficulty. @@ -754,10 +704,7 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts stReceipts = append(stReceipts, (*types.ReceiptForStorage)(receipt)) } header := block.Header() - if i > 0 { - tdSum.Add(tdSum, header.Difficulty) - } - if err := writeAncientBlock(op, block, header, stReceipts, tdSum); err != nil { + if err := writeAncientBlock(op, block, header, stReceipts); err != nil { return err } } @@ -765,7 +712,7 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts }) } -func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts []*types.ReceiptForStorage, td *big.Int) error { +func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts []*types.ReceiptForStorage) error { num := block.NumberU64() if err := op.AppendRaw(ChainFreezerHashTable, num, block.Hash().Bytes()); err != nil { return fmt.Errorf("can't add block %d hash: %v", num, err) @@ -779,9 +726,6 @@ func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *type if err := op.Append(ChainFreezerReceiptTable, num, receipts); err != nil { return fmt.Errorf("can't append block %d receipts: %v", num, err) } - if err := op.Append(ChainFreezerDifficultyTable, num, td); err != nil { - return fmt.Errorf("can't append block %d total difficulty: %v", num, err) - } return nil } @@ -790,7 +734,6 @@ func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { DeleteReceipts(db, hash, number) DeleteHeader(db, hash, number) DeleteBody(db, hash, number) - DeleteTd(db, hash, number) } // DeleteBlockWithoutNumber removes all block data associated with a hash, except @@ -799,7 +742,6 @@ func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number DeleteReceipts(db, hash, number) deleteHeaderWithoutNumber(db, hash, number) DeleteBody(db, hash, number) - DeleteTd(db, hash, number) } const badBlockToKeep = 10 diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 0e986f66e0..5533c60ab9 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -258,29 +258,6 @@ func TestBadBlockStorage(t *testing.T) { } } -// Tests block total difficulty storage and retrieval operations. -func TestTdStorage(t *testing.T) { - db := NewMemoryDatabase() - - // Create a test TD to move around the database and make sure it's really new - hash, td := common.Hash{}, big.NewInt(314) - if entry := ReadTd(db, hash, 0); entry != nil { - t.Fatalf("Non existent TD returned: %v", entry) - } - // Write and verify the TD in the database - WriteTd(db, hash, 0, td) - if entry := ReadTd(db, hash, 0); entry == nil { - t.Fatalf("Stored TD not found") - } else if entry.Cmp(td) != 0 { - t.Fatalf("Retrieved TD mismatch: have %v, want %v", entry, td) - } - // Delete the TD and verify the execution - DeleteTd(db, hash, 0) - if entry := ReadTd(db, hash, 0); entry != nil { - t.Fatalf("Deleted TD returned: %v", entry) - } -} - // Tests that canonical numbers can be mapped to hashes and retrieved. func TestCanonicalMappingStorage(t *testing.T) { db := NewMemoryDatabase() @@ -460,12 +437,9 @@ func TestAncientStorage(t *testing.T) { if blob := ReadReceiptsRLP(db, hash, number); len(blob) > 0 { t.Fatalf("non existent receipts returned") } - if blob := ReadTdRLP(db, hash, number); len(blob) > 0 { - t.Fatalf("non existent td returned") - } // Write and verify the header in the database - WriteAncientBlocks(db, []*types.Block{block}, []types.Receipts{nil}, big.NewInt(100)) + WriteAncientBlocks(db, []*types.Block{block}, []types.Receipts{nil}) if blob := ReadHeaderRLP(db, hash, number); len(blob) == 0 { t.Fatalf("no header returned") @@ -476,9 +450,6 @@ func TestAncientStorage(t *testing.T) { if blob := ReadReceiptsRLP(db, hash, number); len(blob) == 0 { t.Fatalf("no receipts returned") } - if blob := ReadTdRLP(db, hash, number); len(blob) == 0 { - t.Fatalf("no td returned") - } // Use a fake hash for data retrieval, nothing should be returned. fakeHash := common.BytesToHash([]byte{0x01, 0x02, 0x03}) @@ -491,9 +462,6 @@ func TestAncientStorage(t *testing.T) { if blob := ReadReceiptsRLP(db, fakeHash, number); len(blob) != 0 { t.Fatalf("invalid receipts returned") } - if blob := ReadTdRLP(db, fakeHash, number); len(blob) != 0 { - t.Fatalf("invalid td returned") - } } func TestCanonicalHashIteration(t *testing.T) { @@ -518,7 +486,6 @@ func TestCanonicalHashIteration(t *testing.T) { // Fill database with testing data. for i := uint64(1); i <= 8; i++ { WriteCanonicalHash(db, common.Hash{}, i) - WriteTd(db, common.Hash{}, i, big.NewInt(10)) // Write some interferential data } for i, c := range cases { numbers, _ := ReadAllCanonicalHashes(db, c.from, c.to, c.limit) @@ -591,7 +558,6 @@ func BenchmarkWriteAncientBlocks(b *testing.B) { // The benchmark loop writes batches of blocks, but note that the total block count is // b.N. This means the resulting ns/op measurement is the time it takes to write a // single block and its associated data. - var td = big.NewInt(55) var totalSize int64 for i := 0; i < b.N; i += batchSize { length := batchSize @@ -601,7 +567,7 @@ func BenchmarkWriteAncientBlocks(b *testing.B) { blocks := allBlocks[i : i+length] receipts := batchReceipts[:length] - writeSize, err := WriteAncientBlocks(db, blocks, receipts, td) + writeSize, err := WriteAncientBlocks(db, blocks, receipts) if err != nil { b.Fatal(err) } @@ -900,7 +866,7 @@ func TestHeadersRLPStorage(t *testing.T) { } var receipts []types.Receipts = make([]types.Receipts, 100) // Write first half to ancients - WriteAncientBlocks(db, chain[:50], receipts[:50], big.NewInt(100)) + WriteAncientBlocks(db, chain[:50], receipts[:50]) // Write second half to db for i := 50; i < 100; i++ { WriteCanonicalHash(db, chain[i].Hash(), chain[i].NumberU64()) diff --git a/core/rawdb/ancient_scheme.go b/core/rawdb/ancient_scheme.go index 371fd384ad..54a3be391f 100644 --- a/core/rawdb/ancient_scheme.go +++ b/core/rawdb/ancient_scheme.go @@ -35,19 +35,15 @@ const ( // ChainFreezerReceiptTable indicates the name of the freezer receipts table. ChainFreezerReceiptTable = "receipts" - - // ChainFreezerDifficultyTable indicates the name of the freezer total difficulty table. - ChainFreezerDifficultyTable = "diffs" ) // chainFreezerNoSnappy configures whether compression is disabled for the ancient-tables. // Hashes and difficulties don't compress well. var chainFreezerNoSnappy = map[string]bool{ - ChainFreezerHeaderTable: false, - ChainFreezerHashTable: true, - ChainFreezerBodiesTable: false, - ChainFreezerReceiptTable: false, - ChainFreezerDifficultyTable: true, + ChainFreezerHeaderTable: false, + ChainFreezerHashTable: true, + ChainFreezerBodiesTable: false, + ChainFreezerReceiptTable: false, } const ( diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index 7a0b819b6f..0627aca34c 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -315,11 +315,6 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash if len(receipts) == 0 { return fmt.Errorf("block receipts missing, can't freeze block %d", number) } - td := ReadTdRLP(nfdb, hash, number) - if len(td) == 0 { - return fmt.Errorf("total difficulty missing, can't freeze block %d", number) - } - // Write to the batch. if err := op.AppendRaw(ChainFreezerHashTable, number, hash[:]); err != nil { return fmt.Errorf("can't write hash to Freezer: %v", err) @@ -333,9 +328,6 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash if err := op.AppendRaw(ChainFreezerReceiptTable, number, receipts); err != nil { return fmt.Errorf("can't write receipts to Freezer: %v", err) } - if err := op.AppendRaw(ChainFreezerDifficultyTable, number, td); err != nil { - return fmt.Errorf("can't write td to Freezer: %v", err) - } hashes = append(hashes, hash) } return nil diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 53418d1646..ae1e7c0bdc 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -500,7 +500,7 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { {"Key-Value store", "Headers", headers.Size(), headers.Count()}, {"Key-Value store", "Bodies", bodies.Size(), bodies.Count()}, {"Key-Value store", "Receipt lists", receipts.Size(), receipts.Count()}, - {"Key-Value store", "Difficulties", tds.Size(), tds.Count()}, + {"Key-Value store", "Difficulties (deprecated)", tds.Size(), tds.Count()}, {"Key-Value store", "Block number->hash", numHashPairings.Size(), numHashPairings.Count()}, {"Key-Value store", "Block hash->number", hashNumPairings.Size(), hashNumPairings.Count()}, {"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()}, diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 04b5d0d6d2..3d5d757a86 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -98,7 +98,7 @@ var ( // Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes). headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header - headerTDSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -> td + headerTDSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -> td (deprecated) headerHashSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash headerNumberPrefix = []byte("H") // headerNumberPrefix + hash -> num (uint64 big endian) @@ -174,11 +174,6 @@ func headerKey(number uint64, hash common.Hash) []byte { return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...) } -// headerTDKey = headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -func headerTDKey(number uint64, hash common.Hash) []byte { - return append(headerKey(number, hash), headerTDSuffix...) -} - // headerHashKey = headerPrefix + num (uint64 big endian) + headerHashSuffix func headerHashKey(number uint64) []byte { return append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...) diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 4343edfe86..da364444ed 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -63,7 +63,6 @@ type VMContext struct { // 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 } diff --git a/core/txindexer_test.go b/core/txindexer_test.go index 0a606ed8fa..246aec8b89 100644 --- a/core/txindexer_test.go +++ b/core/txindexer_test.go @@ -211,7 +211,7 @@ func TestTxIndexer(t *testing.T) { } for _, c := range cases { db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) - rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), big.NewInt(0)) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...)) // Index the initial blocks from ancient store indexer := &txIndexer{ diff --git a/eth/api_backend.go b/eth/api_backend.go index be2101c6ec..90439e8eab 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -242,13 +242,6 @@ func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash, number ui return rawdb.ReadLogs(b.eth.chainDb, hash, number), nil } -func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int { - if header := b.eth.blockchain.GetHeaderByHash(hash); header != nil { - return b.eth.blockchain.GetTd(hash, header.Number.Uint64()) - } - return nil -} - func (b *EthAPIBackend) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM { if vmConfig == nil { vmConfig = b.eth.blockchain.GetVMConfig() diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 37d962d070..7a9707dc15 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -361,21 +361,12 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl } // Block is known locally, just sanity check that the beacon client does not // attempt to push us back to before the merge. - if block.Difficulty().BitLen() > 0 || block.NumberU64() == 0 { - var ( - td = api.eth.BlockChain().GetTd(update.HeadBlockHash, block.NumberU64()) - ptd = api.eth.BlockChain().GetTd(block.ParentHash(), block.NumberU64()-1) - ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty - ) - if td == nil || (block.NumberU64() > 0 && ptd == nil) { - log.Error("TDs unavailable for TTD check", "number", block.NumberU64(), "hash", update.HeadBlockHash, "td", td, "parent", block.ParentHash(), "ptd", ptd) - return engine.STATUS_INVALID, errors.New("TDs unavailable for TDD check") + if block.Difficulty().BitLen() > 0 && block.NumberU64() > 0 { + ph := api.eth.BlockChain().GetHeader(block.ParentHash(), block.NumberU64()-1) + if ph == nil { + return engine.STATUS_INVALID, errors.New("parent unavailable for difficulty check") } - if td.Cmp(ttd) < 0 { - log.Error("Refusing beacon update to pre-merge", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) - return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil - } - if block.NumberU64() > 0 && ptd.Cmp(ttd) >= 0 { + if ph.Difficulty.Sign() == 0 && block.Difficulty().Sign() > 0 { log.Error("Parent block is already post-ttd", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil } @@ -901,21 +892,6 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe if parent == nil { return api.delayPayloadImport(block), nil } - // We have an existing parent, do some sanity checks to avoid the beacon client - // triggering too early - var ( - ptd = api.eth.BlockChain().GetTd(parent.Hash(), parent.NumberU64()) - ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty - gptd = api.eth.BlockChain().GetTd(parent.ParentHash(), parent.NumberU64()-1) - ) - if ptd.Cmp(ttd) < 0 { - log.Warn("Ignoring pre-merge payload", "number", params.Number, "hash", params.BlockHash, "td", ptd, "ttd", ttd) - return engine.INVALID_TERMINAL_BLOCK, nil - } - if parent.Difficulty().BitLen() > 0 && gptd != nil && gptd.Cmp(ttd) >= 0 { - log.Error("Ignoring pre-merge parent block", "number", params.Number, "hash", params.BlockHash, "td", ptd, "ttd", ttd) - return engine.INVALID_TERMINAL_BLOCK, nil - } if block.Time() <= parent.Time() { log.Warn("Invalid timestamp", "parent", block.Time(), "block", block.Time()) return api.invalid(errors.New("invalid timestamp"), parent.Header()), nil diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index e0a155f12b..4698827731 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -32,8 +32,7 @@ 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/consensus" - beaconConsensus "github.com/ethereum/go-ethereum/consensus/beacon" + "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/types" @@ -62,10 +61,11 @@ var ( func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) { config := *params.AllEthashProtocolChanges - engine := consensus.Engine(beaconConsensus.New(ethash.NewFaker())) + engine := beacon.New(ethash.NewFaker()) if merged { config.TerminalTotalDifficulty = common.Big0 - engine = beaconConsensus.NewFaker() + } else { + engine.TestingTTDBlock(uint64(n)) } genesis := &core.Genesis{ Config: &config, @@ -101,7 +101,6 @@ func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) { } config.TerminalTotalDifficulty = totalDifficulty } - return genesis, blocks } @@ -164,24 +163,6 @@ func TestEth2AssembleBlockWithAnotherBlocksTxs(t *testing.T) { } } -func TestSetHeadBeforeTotalDifficulty(t *testing.T) { - genesis, blocks := generateMergeChain(10, false) - n, ethservice := startEthService(t, genesis, blocks) - defer n.Close() - - api := NewConsensusAPI(ethservice) - fcState := engine.ForkchoiceStateV1{ - HeadBlockHash: blocks[5].Hash(), - SafeBlockHash: common.Hash{}, - FinalizedBlockHash: common.Hash{}, - } - if resp, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil { - t.Errorf("fork choice updated should not error: %v", err) - } else if resp.PayloadStatus.Status != engine.INVALID_TERMINAL_BLOCK.Status { - t.Errorf("fork choice updated before total terminal difficulty should be INVALID") - } -} - func TestEth2PrepareAndGetPayload(t *testing.T) { genesis, blocks := generateMergeChain(10, false) // We need to properly set the terminal total difficulty @@ -902,70 +883,6 @@ func TestInvalidBloom(t *testing.T) { } } -func TestNewPayloadOnInvalidTerminalBlock(t *testing.T) { - genesis, preMergeBlocks := generateMergeChain(100, false) - n, ethservice := startEthService(t, genesis, preMergeBlocks) - defer n.Close() - api := NewConsensusAPI(ethservice) - - // Test parent already post TTD in FCU - parent := preMergeBlocks[len(preMergeBlocks)-2] - fcState := engine.ForkchoiceStateV1{ - HeadBlockHash: parent.Hash(), - SafeBlockHash: common.Hash{}, - FinalizedBlockHash: common.Hash{}, - } - resp, err := api.ForkchoiceUpdatedV1(fcState, nil) - if err != nil { - t.Fatalf("error sending forkchoice, err=%v", err) - } - if resp.PayloadStatus != engine.INVALID_TERMINAL_BLOCK { - t.Fatalf("error sending invalid forkchoice, invalid status: %v", resp.PayloadStatus.Status) - } - - // Test parent already post TTD in NewPayload - args := &miner.BuildPayloadArgs{ - Parent: parent.Hash(), - Timestamp: parent.Time() + 1, - Random: crypto.Keccak256Hash([]byte{byte(1)}), - FeeRecipient: parent.Coinbase(), - } - payload, err := api.eth.Miner().BuildPayload(args, false) - if err != nil { - t.Fatalf("error preparing payload, err=%v", err) - } - data := *payload.Resolve().ExecutionPayload - // We need to recompute the blockhash, since the miner computes a wrong (correct) blockhash - txs, _ := decodeTransactions(data.Transactions) - header := &types.Header{ - ParentHash: data.ParentHash, - UncleHash: types.EmptyUncleHash, - Coinbase: data.FeeRecipient, - Root: data.StateRoot, - TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)), - ReceiptHash: data.ReceiptsRoot, - Bloom: types.BytesToBloom(data.LogsBloom), - Difficulty: common.Big0, - 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, - } - block := types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs}) - data.BlockHash = block.Hash() - // Send the new payload - resp2, err := api.NewPayloadV1(data) - if err != nil { - t.Fatalf("error sending NewPayload, err=%v", err) - } - if resp2 != engine.INVALID_TERMINAL_BLOCK { - t.Fatalf("error sending invalid forkchoice, invalid status: %v", resp.PayloadStatus.Status) - } -} - // TestSimultaneousNewBlock does several parallel inserts, both as // newPayLoad and forkchoiceUpdate. This is to test that the api behaves // well even of the caller is not being 'serial'. diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 8ac5d2eb31..3f3f9b7f0c 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -20,7 +20,6 @@ package downloader import ( "errors" "fmt" - "math/big" "sync" "sync/atomic" "time" @@ -164,9 +163,6 @@ type BlockChain interface { // CurrentHeader retrieves the head header from the local chain. CurrentHeader() *types.Header - // GetTd returns the total difficulty of a local block. - GetTd(common.Hash, uint64) *big.Int - // InsertHeaderChain inserts a batch of headers into the local chain. InsertHeaderChain([]*types.Header) (int, error) diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 47c89bf768..3a145b1958 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -126,13 +126,6 @@ type downloadTesterPeer struct { chain *core.BlockChain } -// Head constructs a function to retrieve a peer's current head hash -// and total difficulty. -func (dlp *downloadTesterPeer) Head() (common.Hash, *big.Int) { - head := dlp.chain.CurrentBlock() - return head.Hash(), dlp.chain.GetTd(head.Hash(), head.Number.Uint64()) -} - func unmarshalRlpHeaders(rlpdata []rlp.RawValue) []*types.Header { var headers = make([]*types.Header, len(rlpdata)) for i, data := range rlpdata { diff --git a/eth/downloader/peer.go b/eth/downloader/peer.go index 4c43af5270..0848e92a26 100644 --- a/eth/downloader/peer.go +++ b/eth/downloader/peer.go @@ -21,7 +21,6 @@ package downloader import ( "errors" - "math/big" "sync" "time" @@ -57,7 +56,6 @@ type peerConnection struct { // Peer encapsulates the methods required to synchronise with a remote full peer. type Peer interface { - Head() (common.Hash, *big.Int) RequestHeadersByHash(common.Hash, int, int, bool, chan *eth.Response) (*eth.Request, error) RequestHeadersByNumber(uint64, int, int, bool, chan *eth.Response) (*eth.Request, error) diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index fdba2e584b..185224d834 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -25,7 +25,6 @@ import ( "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" @@ -148,7 +147,10 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, cancunBlock *big.Int, pe config.LondonBlock = londonBlock config.ArrowGlacierBlock = londonBlock config.GrayGlacierBlock = londonBlock - var engine consensus.Engine = beacon.New(ethash.NewFaker()) + + engine := beacon.New(ethash.NewFaker()) + engine.TestingTTDBlock(testHead + 1) + td := params.GenesisDifficulty.Uint64() if cancunBlock != nil { diff --git a/eth/handler.go b/eth/handler.go index 9820118173..8893920497 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -253,10 +253,9 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { head = h.chain.CurrentHeader() hash = head.Hash() number = head.Number.Uint64() - td = h.chain.GetTd(hash, number) ) forkID := forkid.NewID(h.chain.Config(), genesis, number, head.Time) - if err := peer.Handshake(h.networkID, td, hash, genesis.Hash(), forkID, h.forkFilter); err != nil { + if err := peer.Handshake(h.networkID, hash, genesis.Hash(), forkID, h.forkFilter); err != nil { peer.Log().Debug("Ethereum handshake failed", "err", err) return err } diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index ce17345358..622880b097 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -260,9 +260,8 @@ func testRecvTransactions(t *testing.T, protocol uint) { var ( genesis = handler.chain.Genesis() head = handler.chain.CurrentBlock() - td = handler.chain.GetTd(head.Hash(), head.Number.Uint64()) ) - if err := src.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil { + if err := src.Handshake(1, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil { t.Fatalf("failed to run protocol handshake") } // Send the transaction to the sink and verify that it's added to the tx pool @@ -320,9 +319,8 @@ func testSendTransactions(t *testing.T, protocol uint) { var ( genesis = handler.chain.Genesis() head = handler.chain.CurrentBlock() - td = handler.chain.GetTd(head.Hash(), head.Number.Uint64()) ) - if err := sink.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil { + if err := sink.Handshake(1, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil { t.Fatalf("failed to run protocol handshake") } // After the handshake completes, the source handler should stream the sink diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index 28db93a209..d6cd83373b 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -18,7 +18,6 @@ package eth import ( "fmt" - "math/big" "time" "github.com/ethereum/go-ethereum/common" @@ -120,11 +119,10 @@ 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, 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 - Head common.Hash `json:"head"` // Hex hash of the host's best owned block + Network uint64 `json:"network"` // Ethereum network ID (1=Mainnet, Holesky=17000) + Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block + Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules + Head common.Hash `json:"head"` // Hex hash of the host's best owned block } // nodeInfo retrieves some `eth` protocol metadata about the running host node. @@ -133,11 +131,10 @@ func nodeInfo(chain *core.BlockChain, network uint64) *NodeInfo { hash := head.Hash() return &NodeInfo{ - Network: network, - Difficulty: chain.GetTd(hash, head.Number.Uint64()), - Genesis: chain.Genesis().Hash(), - Config: chain.Config(), - Head: hash, + Network: network, + Genesis: chain.Genesis().Hash(), + Config: chain.Config(), + Head: hash, } } diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index d0509f2f3d..5b35a2f935 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_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/beacon" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" @@ -71,12 +70,13 @@ func newTestBackend(blocks int) *testBackend { func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int, *core.BlockGen)) *testBackend { var ( // Create a database pre-initialize with a genesis block - db = rawdb.NewMemoryDatabase() - config = params.TestChainConfig - engine consensus.Engine = ethash.NewFaker() + db = rawdb.NewMemoryDatabase() + config = params.TestChainConfig + engine = beacon.New(ethash.NewFaker()) ) - - if shanghai { + if !shanghai { + engine.TestingTTDBlock(math.MaxUint64) + } else { config = ¶ms.ChainConfig{ ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), @@ -99,7 +99,6 @@ func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int, TerminalTotalDifficulty: big.NewInt(0), Ethash: new(params.EthashConfig), } - engine = beacon.NewFaker() } gspec := &core.Genesis{ diff --git a/eth/protocols/eth/handshake.go b/eth/protocols/eth/handshake.go index 68cf846925..0b6f110e3d 100644 --- a/eth/protocols/eth/handshake.go +++ b/eth/protocols/eth/handshake.go @@ -36,7 +36,7 @@ const ( // Handshake executes the eth protocol handshake, negotiating version number, // network IDs, difficulties, head and genesis blocks. -func (p *Peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter) error { +func (p *Peer) Handshake(network uint64, head common.Hash, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter) error { // Send out own handshake in a new thread errc := make(chan error, 2) @@ -46,7 +46,7 @@ func (p *Peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis errc <- p2p.Send(p.rw, StatusMsg, &StatusPacket{ ProtocolVersion: uint32(p.version), NetworkID: network, - TD: td, + TD: new(big.Int), // unknown for post-merge tail=pruned networks Head: head, Genesis: genesis, ForkID: forkID, @@ -69,13 +69,6 @@ func (p *Peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis return p2p.DiscReadTimeout } } - p.td, p.head = status.TD, status.Head - - // TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times - // larger, it will still fit within 100 bits - if tdlen := p.td.BitLen(); tdlen > 100 { - return fmt.Errorf("too large total difficulty: bitlen %d", tdlen) - } return nil } diff --git a/eth/protocols/eth/handshake_test.go b/eth/protocols/eth/handshake_test.go index b9fd13d863..1d1de3ec16 100644 --- a/eth/protocols/eth/handshake_test.go +++ b/eth/protocols/eth/handshake_test.go @@ -18,6 +18,7 @@ package eth import ( "errors" + "math/big" "testing" "github.com/ethereum/go-ethereum/common" @@ -39,7 +40,6 @@ func testHandshake(t *testing.T, protocol uint) { var ( genesis = backend.chain.Genesis() head = backend.chain.CurrentBlock() - td = backend.chain.GetTd(head.Hash(), head.Number.Uint64()) forkID = forkid.NewID(backend.chain.Config(), backend.chain.Genesis(), backend.chain.CurrentHeader().Number.Uint64(), backend.chain.CurrentHeader().Time) ) tests := []struct { @@ -52,19 +52,19 @@ func testHandshake(t *testing.T, protocol uint) { want: errNoStatusMsg, }, { - code: StatusMsg, data: StatusPacket{10, 1, td, head.Hash(), genesis.Hash(), forkID}, + code: StatusMsg, data: StatusPacket{10, 1, new(big.Int), head.Hash(), genesis.Hash(), forkID}, want: errProtocolVersionMismatch, }, { - code: StatusMsg, data: StatusPacket{uint32(protocol), 999, td, head.Hash(), genesis.Hash(), forkID}, + code: StatusMsg, data: StatusPacket{uint32(protocol), 999, new(big.Int), head.Hash(), genesis.Hash(), forkID}, want: errNetworkIDMismatch, }, { - code: StatusMsg, data: StatusPacket{uint32(protocol), 1, td, head.Hash(), common.Hash{3}, forkID}, + code: StatusMsg, data: StatusPacket{uint32(protocol), 1, new(big.Int), head.Hash(), common.Hash{3}, forkID}, want: errGenesisMismatch, }, { - code: StatusMsg, data: StatusPacket{uint32(protocol), 1, td, head.Hash(), genesis.Hash(), forkid.ID{Hash: [4]byte{0x00, 0x01, 0x02, 0x03}}}, + code: StatusMsg, data: StatusPacket{uint32(protocol), 1, new(big.Int), head.Hash(), genesis.Hash(), forkid.ID{Hash: [4]byte{0x00, 0x01, 0x02, 0x03}}}, want: errForkIDRejected, }, } @@ -80,7 +80,7 @@ func testHandshake(t *testing.T, protocol uint) { // Send the junk test with one peer, check the handshake failure go p2p.Send(app, test.code, test.data) - err := peer.Handshake(1, td, head.Hash(), genesis.Hash(), forkID, forkid.NewFilter(backend.chain)) + err := peer.Handshake(1, head.Hash(), genesis.Hash(), forkID, forkid.NewFilter(backend.chain)) if err == nil { t.Errorf("test %d: protocol returned nil error, want %q", i, test.want) } else if !errors.Is(err, test.want) { diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index f53782a053..31a35eb186 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -17,9 +17,7 @@ package eth import ( - "math/big" "math/rand" - "sync" mapset "github.com/deckarep/golang-set/v2" "github.com/ethereum/go-ethereum/common" @@ -50,9 +48,6 @@ type Peer struct { rw p2p.MsgReadWriter // Input/output streams for snap version uint // Protocol version negotiated - head common.Hash // Latest advertised head block hash - td *big.Int // Latest advertised head block total difficulty - txpool TxPool // Transaction pool used by the broadcasters for liveness checks knownTxs *knownCache // Set of transaction hashes known to be known by this peer txBroadcast chan []common.Hash // Channel used to queue transaction propagation requests @@ -63,7 +58,6 @@ type Peer struct { resDispatch chan *response // Dispatch channel to fulfil pending requests and untrack them term chan struct{} // Termination channel to stop the broadcasters - lock sync.RWMutex // Mutex protecting the internal fields } // NewPeer creates a wrapper for a network connection and negotiated protocol @@ -108,24 +102,6 @@ func (p *Peer) Version() uint { return p.version } -// Head retrieves the current head hash and total difficulty of the peer. -func (p *Peer) Head() (hash common.Hash, td *big.Int) { - p.lock.RLock() - defer p.lock.RUnlock() - - copy(hash[:], p.head[:]) - return hash, new(big.Int).Set(p.td) -} - -// SetHead updates the head hash and total difficulty of the peer. -func (p *Peer) SetHead(hash common.Hash, td *big.Int) { - p.lock.Lock() - defer p.lock.Unlock() - - copy(p.head[:], hash[:]) - p.td.Set(td) -} - // KnownTransaction returns whether peer is known to already have a transaction. func (p *Peer) KnownTransaction(hash common.Hash) bool { return p.knownTxs.Contains(hash) diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 13a7b0aaae..95e7739be0 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -1089,7 +1089,7 @@ func TestTraceChain(t *testing.T) { 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(), + engine: beacon.New(ethash.NewFaker()), chaindb: rawdb.NewMemoryDatabase(), } // Generate blocks for testing diff --git a/eth/tracers/internal/tracetest/supply_test.go b/eth/tracers/internal/tracetest/supply_test.go index 6f06b7c0d5..d918f5aca4 100644 --- a/eth/tracers/internal/tracetest/supply_test.go +++ b/eth/tracers/internal/tracetest/supply_test.go @@ -544,9 +544,8 @@ func TestSupplySelfdestructItselfAndRevert(t *testing.T) { } func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockGen)) ([]supplyInfo, *core.BlockChain, error) { - var ( - engine = beacon.New(ethash.NewFaker()) - ) + engine := beacon.New(ethash.NewFaker()) + engine.TestingTTDBlock(1) traceOutputPath := filepath.ToSlash(t.TempDir()) traceOutputFilename := path.Join(traceOutputPath, "supply.jsonl") diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index afed5332df..0090a7d4c1 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -65,7 +65,6 @@ type backend interface { SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription CurrentHeader() *types.Header HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) - GetTd(ctx context.Context, hash common.Hash) *big.Int Stats() (pending int, queued int) SyncProgress() ethereum.SyncProgress } @@ -628,7 +627,6 @@ func (s *Service) reportBlock(conn *connWrapper, header *types.Header) error { func (s *Service) assembleBlockStats(header *types.Header) *blockStats { // Gather the block infos from the local blockchain var ( - td *big.Int txs []txStats uncles []*types.Header ) @@ -644,8 +642,6 @@ func (s *Service) assembleBlockStats(header *types.Header) *blockStats { if block == nil { return nil } - td = fullBackend.GetTd(context.Background(), header.Hash()) - txs = make([]txStats, len(block.Transactions())) for i, tx := range block.Transactions() { txs[i].Hash = tx.Hash() @@ -656,7 +652,6 @@ func (s *Service) assembleBlockStats(header *types.Header) *blockStats { if header == nil { header = s.backend.CurrentHeader() } - td = s.backend.GetTd(context.Background(), header.Hash()) txs = []txStats{} } // Assemble and return the block stats @@ -671,7 +666,7 @@ func (s *Service) assembleBlockStats(header *types.Header) *blockStats { GasUsed: header.GasUsed, GasLimit: header.GasLimit, Diff: header.Difficulty.String(), - TotalDiff: td.String(), + TotalDiff: "0", // unknown post-merge with pruned chain tail Txs: txs, TxHash: header.TxHash, Root: header.Root, diff --git a/graphql/graphql_test.go b/graphql/graphql_test.go index 231170c273..3e6a042dbb 100644 --- a/graphql/graphql_test.go +++ b/graphql/graphql_test.go @@ -29,7 +29,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/consensus/ethash" "github.com/ethereum/go-ethereum/core" @@ -457,9 +456,8 @@ func newGQLService(t *testing.T, stack *node.Node, shanghai bool, gspec *core.Ge RPCGasCap: 1000000, StateScheme: rawdb.HashScheme, } - var engine consensus.Engine = ethash.NewFaker() + var engine = beacon.New(ethash.NewFaker()) if shanghai { - engine = beacon.NewFaker() gspec.Config.TerminalTotalDifficulty = common.Big0 // GenerateChain will increment timestamps by 10. // Shanghai upgrade at block 1. @@ -468,6 +466,7 @@ func newGQLService(t *testing.T, stack *node.Node, shanghai bool, gspec *core.Ge } else { // set an arbitrary large ttd as chains are required to be known to be merged gspec.Config.TerminalTotalDifficulty = big.NewInt(math.MaxInt64) + engine.TestingTTDBlock(math.MaxUint64) } ethBackend, err := eth.New(stack, ethConf) if err != nil { diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 0303a0a6ea..f00022e3de 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -565,12 +565,6 @@ func (b testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.R receipts := rawdb.ReadReceipts(b.db, hash, header.Number.Uint64(), header.Time, b.chain.Config()) return receipts, nil } -func (b testBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int { - if b.pending != nil && hash == b.pending.Hash() { - return nil - } - return big.NewInt(1) -} func (b testBackend) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockContext *vm.BlockContext) *vm.EVM { if vmConfig == nil { vmConfig = b.chain.GetVMConfig() diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index 7172fc883f..7355c2463c 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -369,7 +369,6 @@ func (b *backendMock) GetReceipts(ctx context.Context, hash common.Hash) (types. func (b *backendMock) GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error) { return nil, nil } -func (b *backendMock) GetTd(ctx context.Context, hash common.Hash) *big.Int { return nil } func (b *backendMock) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM { return nil } diff --git a/tests/block_test.go b/tests/block_test.go index 4bbd2571d7..15806b3eff 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -60,6 +60,9 @@ func TestBlockchain(t *testing.T) { bt.skipLoad(`.*bcFrontierToHomestead/blockChainFrontierWithLargerTDvsHomesteadBlockchain.json`) bt.skipLoad(`.*bcFrontierToHomestead/blockChainFrontierWithLargerTDvsHomesteadBlockchain2.json`) + // With chain history removal, TDs become unavailable, this transition tests based on TTD are unrunnable + bt.skipLoad(`.*bcArrowGlacierToParis/powToPosBlockRejection.json`) + bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { execBlockTest(t, bt, test) }) From 3fcbb6735e8cd7ca6508dcfeed130a0a86980ab5 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Tue, 28 Jan 2025 18:56:20 +0100 Subject: [PATCH 073/940] .github: add lint step (#31068) --- .github/workflows/go.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6406d2fa3d..d1d2579dff 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -8,6 +8,30 @@ on: workflow_dispatch: jobs: + lint: + name: Lint + runs-on: self-hosted + steps: + - uses: actions/checkout@v4 + + # Cache build tools to avoid downloading them each time + - uses: actions/cache@v4 + with: + path: build/cache + key: ${{ runner.os }}-build-tools-cache-${{ hashFiles('build/checksums.txt') }} + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.23.0 + cache: false + + - name: Run linters + run: | + go run build/ci.go lint + go run build/ci.go check_tidy + go run build/ci.go check_baddeps + build: runs-on: self-hosted steps: From 52766bedb9316cd6cddacbb282809e3bdfba143e Mon Sep 17 00:00:00 2001 From: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Date: Wed, 29 Jan 2025 14:31:25 +0100 Subject: [PATCH 074/940] core/{.,state,vm},miner,eth/tracers,tests: implement 7709 with a syscall flag (#31036) Same as #31015 but requires the contract to exist. Not compatible with any verkle testnet up to now. This adds a `isSytemCall` flag so that it is possible to detect when a system call is executed, so that the code execution and other locations are not added to the witness. --------- Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Co-authored-by: Ignacio Hagopian Co-authored-by: Felix Lange --- core/chain_makers.go | 23 +++++++++------- core/state/statedb_hooked.go | 4 +++ core/state_processor.go | 24 ++++++++++------ core/verkle_witness_test.go | 53 ++++++++++++++++++++---------------- core/vm/contract.go | 1 + core/vm/eips.go | 14 ++++++---- core/vm/evm.go | 9 ++++-- core/vm/gas_table.go | 4 +-- core/vm/interface.go | 3 ++ core/vm/interpreter.go | 2 +- core/vm/operations_verkle.go | 20 +++++++++++++- 11 files changed, 103 insertions(+), 54 deletions(-) diff --git a/core/chain_makers.go b/core/chain_makers.go index d52554a307..1f48f9d128 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -122,6 +122,11 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti if err != nil { panic(err) } + // 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 b.statedb.GetTrie().IsVerkle() { + b.statedb.AccessEvents().Merge(evm.AccessEvents) + } b.txs = append(b.txs, tx) b.receipts = append(b.receipts, receipt) if b.header.BlobGasUsed != nil { @@ -379,7 +384,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse misc.ApplyDAOHardFork(statedb) } - if config.IsPrague(b.header.Number, b.header.Time) { + if config.IsPrague(b.header.Number, b.header.Time) || config.IsVerkle(b.header.Number, b.header.Time) { // EIP-2935 blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) blockContext.Random = &common.Hash{} // enable post-merge instruction set @@ -487,13 +492,11 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine // Save pre state for proof generation // preState := statedb.Copy() - // Pre-execution system calls. - if config.IsPrague(b.header.Number, b.header.Time) { - // EIP-2935 - blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) - evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) - ProcessParentBlockHash(b.header.ParentHash, evm) - } + // EIP-2935 / 7709 + blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) + blockContext.Random = &common.Hash{} // enable post-merge instruction set + evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) + ProcessParentBlockHash(b.header.ParentHash, evm) // Execute any user modifications to the block. if gen != nil { @@ -561,7 +564,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine 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) { +func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (common.Hash, ethdb.Database, []*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { db := rawdb.NewMemoryDatabase() cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme) cacheConfig.SnapshotLimit = 0 @@ -572,7 +575,7 @@ func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n panic(err) } blocks, receipts, proofs, keyvals := GenerateVerkleChain(genesis.Config, genesisBlock, engine, db, triedb, n, gen) - return db, blocks, receipts, proofs, keyvals + return genesisBlock.Hash(), db, blocks, receipts, proofs, keyvals } func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 31bdd06b46..25d823cc87 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -157,6 +157,10 @@ func (s *hookedStateDB) Witness() *stateless.Witness { return s.inner.Witness() } +func (s *hookedStateDB) AccessEvents() *AccessEvents { + return s.inner.AccessEvents() +} + func (s *hookedStateDB) SubBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int { prev := s.inner.SubBalance(addr, amount, reason) if s.hooks.OnBalanceChange != nil && !amount.IsZero() { diff --git a/core/state_processor.go b/core/state_processor.go index 3eb83a673a..902ff582e8 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -85,7 +85,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg if beaconRoot := block.BeaconRoot(); beaconRoot != nil { ProcessBeaconBlockRoot(*beaconRoot, evm) } - if p.config.IsPrague(block.Number(), block.Time()) { + if p.config.IsPrague(block.Number(), block.Time()) || p.config.IsVerkle(block.Number(), block.Time()) { ProcessParentBlockHash(block.ParentHash(), evm) } @@ -155,6 +155,12 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, } *usedGas += result.UsedGas + // 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) + } + return MakeReceipt(evm, result, statedb, blockNumber, blockHash, tx, *usedGas, root), nil } @@ -181,12 +187,6 @@ func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, b 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.Bloom = types.CreateBloom(types.Receipts{receipt}) @@ -234,7 +234,7 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, evm *vm.EVM) { } // ProcessParentBlockHash stores the parent block hash in the history storage contract -// as per EIP-2935. +// as per EIP-2935/7709. func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) { if tracer := evm.Config.Tracer; tracer != nil { onSystemCallStart(tracer, evm.GetVMContext()) @@ -253,7 +253,13 @@ func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) { } evm.SetTxContext(NewEVMTxContext(msg)) evm.StateDB.AddAddressToAccessList(params.HistoryStorageAddress) - _, _, _ = evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) + _, _, err := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) + if err != nil { + panic(err) + } + if evm.StateDB.AccessEvents() != nil { + evm.StateDB.AccessEvents().Merge(evm.AccessEvents) + } evm.StateDB.Finalise(true) } diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go index 02e94963c4..763939735e 100644 --- a/core/verkle_witness_test.go +++ b/core/verkle_witness_test.go @@ -152,7 +152,7 @@ func TestProcessVerkle(t *testing.T) { txCost1*2 + txCost2, txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas, } - _, chain, _, proofs, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { + _, _, 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) @@ -219,7 +219,7 @@ func TestProcessParentBlockHash(t *testing.T) { // block 1 parent hash is 0x0100.... // block 2 parent hash is 0x0200.... // etc - checkBlockHashes := func(statedb *state.StateDB) { + checkBlockHashes := func(statedb *state.StateDB, isVerkle bool) { statedb.SetNonce(params.HistoryStorageAddress, 1) statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode) // Process n blocks, from 1 .. num @@ -227,20 +227,24 @@ func TestProcessParentBlockHash(t *testing.T) { for i := 1; i <= num; i++ { header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)} vmContext := NewEVMBlockContext(header, nil, new(common.Address)) - evm := vm.NewEVM(vmContext, statedb, params.MergedTestChainConfig, vm.Config{}) + chainConfig := params.MergedTestChainConfig + if isVerkle { + chainConfig = testVerkleChainConfig + } + evm := vm.NewEVM(vmContext, statedb, chainConfig, vm.Config{}) ProcessParentBlockHash(header.ParentHash, evm) } // Read block hashes for block 0 .. num-1 for i := 0; i < num; i++ { - have, want := getContractStoredBlockHash(statedb, uint64(i)), common.Hash{byte(i + 1)} + have, want := getContractStoredBlockHash(statedb, uint64(i), isVerkle), common.Hash{byte(i + 1)} if have != want { - t.Errorf("block %d, have parent hash %v, want %v", i, have, want) + t.Errorf("block %d, verkle=%v, have parent hash %v, want %v", i, isVerkle, have, want) } } } t.Run("MPT", func(t *testing.T) { statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) - checkBlockHashes(statedb) + checkBlockHashes(statedb, false) }) t.Run("Verkle", func(t *testing.T) { db := rawdb.NewMemoryDatabase() @@ -248,15 +252,18 @@ func TestProcessParentBlockHash(t *testing.T) { cacheConfig.SnapshotLimit = 0 triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil)) - checkBlockHashes(statedb) + checkBlockHashes(statedb, true) }) } // getContractStoredBlockHash is a utility method which reads the stored parent blockhash for block 'number' -func getContractStoredBlockHash(statedb *state.StateDB, number uint64) common.Hash { +func getContractStoredBlockHash(statedb *state.StateDB, number uint64, isVerkle bool) common.Hash { ringIndex := number % params.HistoryServeWindow var key common.Hash binary.BigEndian.PutUint64(key[24:], ringIndex) + if isVerkle { + return statedb.GetState(params.HistoryStorageAddress, key) + } return statedb.GetState(params.HistoryStorageAddress, key) } @@ -279,7 +286,7 @@ func TestProcessVerkleInvalidContractCreation(t *testing.T) { // // - The second block contains a single failing contract creation transaction, // that fails right off the bat. - _, chain, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { + genesisH, _, chain, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { gen.SetPoS() if i == 0 { @@ -364,8 +371,8 @@ func TestProcessVerkleInvalidContractCreation(t *testing.T) { if stemStateDiff.SuffixDiffs[0].NewValue == nil { t.Fatalf("nil new value in BLOCKHASH contract insert") } - if *stemStateDiff.SuffixDiffs[0].NewValue != chain[0].Hash() { - t.Fatalf("invalid BLOCKHASH value: %x != %x", *stemStateDiff.SuffixDiffs[0].NewValue, chain[0].Hash()) + if *stemStateDiff.SuffixDiffs[0].NewValue != genesisH { + t.Fatalf("invalid BLOCKHASH value: %x != %x", *stemStateDiff.SuffixDiffs[0].NewValue, genesisH) } } else { // For all other entries present in the witness, check that nothing beyond @@ -393,8 +400,8 @@ func TestProcessVerkleInvalidContractCreation(t *testing.T) { if stemStateDiff.SuffixDiffs[0].NewValue == nil { t.Fatalf("missing post state value for BLOCKHASH contract at block #2") } - if *stemStateDiff.SuffixDiffs[0].NewValue != common.HexToHash("0788c2c0f23aa07eb8bf76fe6c1ca9064a4821c1fd0af803913da488a58dba54") { - t.Fatalf("invalid post state value for BLOCKHASH contract at block #2: 0788c2c0f23aa07eb8bf76fe6c1ca9064a4821c1fd0af803913da488a58dba54 != %x", (*stemStateDiff.SuffixDiffs[0].NewValue)[:]) + if *stemStateDiff.SuffixDiffs[0].NewValue != chain[0].Hash() { + t.Fatalf("invalid post state value for BLOCKHASH contract at block #2: %x != %x", chain[0].Hash(), (*stemStateDiff.SuffixDiffs[0].NewValue)[:]) } } else if suffixDiff.Suffix > 4 { t.Fatalf("invalid suffix diff found for %x in block #2: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) @@ -440,7 +447,7 @@ func TestProcessVerkleContractWithEmptyCode(t *testing.T) { config.ChainID.SetUint64(69421) gspec := verkleTestGenesis(&config) - _, chain, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { + genesisH, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { gen.SetPoS() var tx types.Transaction // a transaction that does some PUSH1n but returns a 0-sized contract @@ -472,8 +479,8 @@ func TestProcessVerkleContractWithEmptyCode(t *testing.T) { if stemStateDiff.SuffixDiffs[0].NewValue == nil { t.Fatalf("nil new value in BLOCKHASH contract insert") } - if *stemStateDiff.SuffixDiffs[0].NewValue != chain[0].Hash() { - t.Fatalf("invalid BLOCKHASH value: %x != %x", *stemStateDiff.SuffixDiffs[0].NewValue, chain[0].Hash()) + if *stemStateDiff.SuffixDiffs[0].NewValue != genesisH { + t.Fatalf("invalid BLOCKHASH value: %x != %x", *stemStateDiff.SuffixDiffs[0].NewValue, genesisH) } } else { for _, suffixDiff := range stemStateDiff.SuffixDiffs { @@ -532,7 +539,7 @@ func TestProcessVerkleExtCodeHashOpcode(t *testing.T) { } extCodeHashContractAddr := crypto.CreateAddress(deployer, 1) - _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { + _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { gen.SetPoS() if i == 0 { @@ -605,7 +612,7 @@ func TestProcessVerkleBalanceOpcode(t *testing.T) { account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d") gspec = verkleTestGenesis(&config) ) - _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { + _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { gen.SetPoS() txData := slices.Concat( []byte{byte(vm.PUSH20)}, @@ -686,7 +693,7 @@ func TestProcessVerkleSelfDestructInSeparateTx(t *testing.T) { deployer := crypto.PubkeyToAddress(testKey.PublicKey) contract := crypto.CreateAddress(deployer, 0) - _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { + _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { gen.SetPoS() if i == 0 { @@ -794,7 +801,7 @@ func TestProcessVerkleSelfDestructInSameTx(t *testing.T) { deployer := crypto.PubkeyToAddress(testKey.PublicKey) contract := crypto.CreateAddress(deployer, 0) - _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { + _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { gen.SetPoS() tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, Value: big.NewInt(42), @@ -897,7 +904,7 @@ func TestProcessVerkleSelfDestructInSeparateTxWithSelfBeneficiary(t *testing.T) deployer := crypto.PubkeyToAddress(testKey.PublicKey) contract := crypto.CreateAddress(deployer, 0) - _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { + _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { gen.SetPoS() if i == 0 { // Create self-destruct contract, sending 42 wei. @@ -977,7 +984,7 @@ func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary(t *testing.T) { selfDestructContract := []byte{byte(vm.ADDRESS), byte(vm.SELFDESTRUCT)} - _, _, _, _, stateDiffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { + _, _, _, _, _, stateDiffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { gen.SetPoS() tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, Value: big.NewInt(42), @@ -1043,7 +1050,7 @@ func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiaryAndPrefundedAccount selfDestructContract := []byte{byte(vm.ADDRESS), byte(vm.SELFDESTRUCT)} - _, _, _, _, stateDiffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { + _, _, _, _, _, stateDiffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { gen.SetPoS() tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, Value: big.NewInt(42), diff --git a/core/vm/contract.go b/core/vm/contract.go index cfda75b27e..5670244e17 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -59,6 +59,7 @@ type Contract struct { // is the execution frame represented by this object a contract deployment IsDeployment bool + IsSystemCall bool Gas uint64 value *uint256.Int diff --git a/core/vm/eips.go b/core/vm/eips.go index a51a18dc60..ab58702428 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -345,10 +345,12 @@ func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC 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 + if !contract.IsSystemCall { + 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) @@ -367,7 +369,7 @@ func opPush1EIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext if *pc < codeLen { scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc]))) - if !scope.Contract.IsDeployment && *pc%31 == 0 { + if !scope.Contract.IsDeployment && !scope.Contract.IsSystemCall && *pc%31 == 0 { // touch next chunk if PUSH1 is at the boundary. if so, *pc has // advanced past this boundary. contractAddr := scope.Contract.Address() @@ -397,7 +399,7 @@ func makePushEIP4762(size uint64, pushByteSize int) executionFunc { )), ) - if !scope.Contract.IsDeployment { + if !scope.Contract.IsDeployment && !scope.Contract.IsSystemCall { 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) { diff --git a/core/vm/evm.go b/core/vm/evm.go index 1e52215b7e..3f9ae621a3 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -165,8 +165,12 @@ func (evm *EVM) Interpreter() *EVMInterpreter { return evm.interpreter } +func isSystemCall(caller ContractRef) bool { + return caller.Address() == params.SystemAddress +} + // Call executes the contract associated with the addr with the given input as -// parameters. It also handles any necessary value transfer required and takes +// parameters. It also handles any necessary value transfer required and takse // 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) { @@ -189,7 +193,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas p, isPrecompile := evm.precompile(addr) if !evm.StateDB.Exist(addr) { - if !isPrecompile && evm.chainRules.IsEIP4762 { + if !isPrecompile && evm.chainRules.IsEIP4762 && !isSystemCall(caller) { // add proof of absence to witness wgas := evm.AccessEvents.AddAccount(addr, false) if gas < wgas { @@ -220,6 +224,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // If the account has no code, we can abort here // The depth-check is already done, and precompiles handled above contract := NewContract(caller, AccountRef(addrCopy), value, gas) + contract.IsSystemCall = isSystemCall(caller) contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), code) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index f3a9808251..55855727b5 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -394,7 +394,7 @@ 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 evm.chainRules.IsEIP4762 && !contract.IsSystemCall { if transfersValue { gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address)) if overflow { @@ -428,7 +428,7 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { return 0, ErrGasUintOverflow } - if evm.chainRules.IsEIP4762 { + if evm.chainRules.IsEIP4762 && !contract.IsSystemCall { address := common.Address(stack.Back(1).Bytes20()) transfersValue := !stack.Back(2).IsZero() if transfersValue { diff --git a/core/vm/interface.go b/core/vm/interface.go index 011541dde3..3488526fc4 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -20,6 +20,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" @@ -98,6 +99,8 @@ type StateDB interface { Witness() *stateless.Witness + AccessEvents() *state.AccessEvents + // Finalise must be invoked at the end of a transaction Finalise(bool) } diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 996ed6e56a..e3237936a0 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -233,7 +233,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( logged, pcCopy, gasCopy = false, pc, contract.Gas } - if in.evm.chainRules.IsEIP4762 && !contract.IsDeployment { + if in.evm.chainRules.IsEIP4762 && !contract.IsDeployment && !contract.IsSystemCall { // if the PC ends up in a new "chunk" of verkleized code, charge the // associated costs. contractAddr := contract.Address() diff --git a/core/vm/operations_verkle.go b/core/vm/operations_verkle.go index 3492994778..751761a911 100644 --- a/core/vm/operations_verkle.go +++ b/core/vm/operations_verkle.go @@ -41,6 +41,9 @@ func gasSLoad4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memor } func gasBalance4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + if contract.IsSystemCall { + return 0, nil + } address := stack.peek().Bytes20() gas := evm.AccessEvents.BasicDataGas(address, false) if gas == 0 { @@ -54,6 +57,9 @@ func gasExtCodeSize4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, if _, isPrecompile := evm.precompile(address); isPrecompile { return 0, nil } + if contract.IsSystemCall { + return 0, nil + } gas := evm.AccessEvents.BasicDataGas(address, false) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 @@ -62,6 +68,9 @@ func gasExtCodeSize4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, } func gasExtCodeHash4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + if contract.IsSystemCall { + return 0, nil + } address := stack.peek().Bytes20() if _, isPrecompile := evm.precompile(address); isPrecompile { return 0, nil @@ -79,6 +88,9 @@ func makeCallVariantGasEIP4762(oldCalculator gasFunc) gasFunc { if err != nil { return 0, err } + if contract.IsSystemCall { + return gas, nil + } if _, isPrecompile := evm.precompile(contract.Address()); isPrecompile { return gas, nil } @@ -102,6 +114,9 @@ func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Mem if _, isPrecompile := evm.precompile(beneficiaryAddr); isPrecompile { return 0, nil } + if contract.IsSystemCall { + return 0, nil + } contractAddr := contract.Address() statelessGas := evm.AccessEvents.BasicDataGas(contractAddr, false) if contractAddr != beneficiaryAddr { @@ -131,7 +146,7 @@ func gasCodeCopyEip4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, uint64CodeOffset = gomath.MaxUint64 } _, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(contract.Code, uint64CodeOffset, length.Uint64()) - if !contract.IsDeployment { + if !contract.IsDeployment && !contract.IsSystemCall { gas += evm.AccessEvents.CodeChunksRangeGas(contract.Address(), copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) } return gas, nil @@ -143,6 +158,9 @@ func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memo if err != nil { return 0, err } + if contract.IsSystemCall { + return gas, nil + } addr := common.Address(stack.peek().Bytes20()) wgas := evm.AccessEvents.BasicDataGas(addr, false) if wgas == 0 { From 11e841e5992d6ffd5b59ed8219bce50bddbfdbb6 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 30 Jan 2025 10:58:44 +0100 Subject: [PATCH 075/940] build: bump test timeout (#31095) Travis often fails because the test times out. --- build/ci.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/ci.go b/build/ci.go index fd51b90d17..4a83fb9a88 100644 --- a/build/ci.go +++ b/build/ci.go @@ -298,8 +298,8 @@ 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=30m") + // CI needs a bit more time for the statetests (default 45m). + gotest.Args = append(gotest.Args, "-timeout=45m") // Enable CKZG backend in CI. gotest.Args = append(gotest.Args, "-tags=ckzg") From 7b96ec4dae8d4ddeffc761c7757c12e2d2b8bf74 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 30 Jan 2025 11:10:45 +0100 Subject: [PATCH 076/940] .travis.yml: change arch for Docker build to arm64 (#31096) This is an attempt to work around a gcc issue in the Docker build. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2ba3af9419..0353aa2e4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ jobs: - stage: build if: type = push os: linux - arch: amd64 + arch: arm64 dist: focal go: 1.23.x env: From d80da7c3b418d092a6a88c35a2bce341fdc23bb1 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 30 Jan 2025 11:21:23 +0100 Subject: [PATCH 077/940] Revert ".travis.yml: change arch for Docker build to arm64 (#31096)" This reverts commit 7b96ec4dae8d4ddeffc761c7757c12e2d2b8bf74. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0353aa2e4a..2ba3af9419 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ jobs: - stage: build if: type = push os: linux - arch: arm64 + arch: amd64 dist: focal go: 1.23.x env: From 7d0e197def6d50eebb8116e7f2b52f95a90c0aef Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 30 Jan 2025 14:06:50 +0100 Subject: [PATCH 078/940] build: retry PPA upload up to three times (#31099) --- build/ci.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/build/ci.go b/build/ci.go index 4a83fb9a88..de47e8e541 100644 --- a/build/ci.go +++ b/build/ci.go @@ -883,11 +883,17 @@ func ppaUpload(workdir, ppa, sshUser string, files []string) { os.WriteFile(idfile, sshkey, 0600) } } - // Upload + // Upload. This doesn't always work, so try up to three times. dest := sshUser + "@ppa.launchpad.net" - if err := build.UploadSFTP(idfile, dest, incomingDir, files); err != nil { - log.Fatal(err) + for i := 0; i < 3; i++ { + err := build.UploadSFTP(idfile, dest, incomingDir, files) + if err == nil { + return + } + log.Println("PPA upload failed:", err) + time.Sleep(5 * time.Second) } + log.Fatal("PPA upload failed all attempts.") } func getenvBase64(variable string) []byte { From fa9a2ff8687ec9efe57b4b9833d5590d20f8a83f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 30 Jan 2025 14:10:36 +0100 Subject: [PATCH 079/940] crypto: add IsOnCurve check (#31100) --- crypto/crypto.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crypto/crypto.go b/crypto/crypto.go index aaa5cc43a2..f9979aa4bb 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -178,6 +178,9 @@ func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) { if x == nil { return nil, errInvalidPubkey } + if !S256().IsOnCurve(x, y) { + return nil, errInvalidPubkey + } return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil } From b3833e5d980b7cca31988f41efdbb9ee7d7f4d15 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 30 Jan 2025 14:52:02 +0100 Subject: [PATCH 080/940] build: provide a flag to disable publishing in dockerx build (#31098) This changes the `-upload` flag to just toggle the upload. The remote image name is now configured using the `-hub` flag. --- .travis.yml | 2 +- build/ci.go | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ba3af9419..8953450e84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ jobs: before_install: - export DOCKER_CLI_EXPERIMENTAL=enabled script: - - go run build/ci.go dockerx -platform "linux/amd64,linux/arm64,linux/riscv64" -upload ethereum/client-go + - go run build/ci.go dockerx -platform "linux/amd64,linux/arm64,linux/riscv64" -hub ethereum/client-go -upload # This builder does the Linux Azure uploads - stage: build diff --git a/build/ci.go b/build/ci.go index de47e8e541..02a4d771f6 100644 --- a/build/ci.go +++ b/build/ci.go @@ -684,7 +684,8 @@ func maybeSkipArchive(env build.Environment) { func doDockerBuildx(cmdline []string) { var ( 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")`) + hubImage = flag.String("hub", "ethereum/client-go", `Where to upload the docker image`) + upload = flag.Bool("upload", false, `Whether to trigger upload`) ) flag.CommandLine.Parse(cmdline) @@ -719,25 +720,33 @@ func doDockerBuildx(cmdline []string) { tags = []string{"stable", fmt.Sprintf("release-%v", version.Family), "v" + version.Semantic} } // Need to create a mult-arch builder - build.MustRunCommand("docker", "buildx", "create", "--use", "--name", "multi-arch-builder", "--platform", *platform) + check := exec.Command("docker", "buildx", "inspect", "multi-arch-builder") + if check.Run() != nil { + 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)}, + {file: "Dockerfile", base: fmt.Sprintf("%s:", *hubImage)}, + {file: "Dockerfile.alltools", base: fmt.Sprintf("%s:alltools-", *hubImage)}, } { for _, tag := range tags { // latest, stable etc gethImage := fmt.Sprintf("%s%s", spec.base, tag) - build.MustRunCommand("docker", "buildx", "build", + cmd := exec.Command("docker", "buildx", "build", "--build-arg", "COMMIT="+env.Commit, "--build-arg", "VERSION="+version.WithMeta, "--build-arg", "BUILDNUM="+env.Buildnum, "--tag", gethImage, "--platform", *platform, - "--push", - "--file", spec.file, ".") + "--file", spec.file, + ) + if *upload { + cmd.Args = append(cmd.Args, "--push") + } + cmd.Args = append(cmd.Args, ".") + build.MustRun(cmd) } } } From 9bc8256a09d3e3b30371460f6d1195bbef60c71c Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 30 Jan 2025 15:00:50 +0100 Subject: [PATCH 081/940] version: begin v1.15.0 release cycle --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index 52dfa0281e..01bc97df51 100644 --- a/version/version.go +++ b/version/version.go @@ -18,7 +18,7 @@ package version const ( Major = 1 // Major version component of the current release - Minor = 14 // Minor version component of the current release - Patch = 13 // Patch version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 0 // Patch version component of the current release Meta = "unstable" // Version metadata to append to the version string ) From 9b9e7ccacffbc6f1db9c0a3b42bdba37109fea48 Mon Sep 17 00:00:00 2001 From: Ryan Tinianov Date: Thu, 30 Jan 2025 10:58:53 -0500 Subject: [PATCH 082/940] all: add build tags for wasip1 (#31090) --- cmd/utils/diskusage.go | 4 +-- crypto/kzg4844/kzg4844_ckzg_cgo.go | 2 +- crypto/kzg4844/kzg4844_ckzg_nocgo.go | 2 +- crypto/signature_cgo.go | 4 +-- crypto/signature_nocgo.go | 4 +-- ethdb/leveldb/leveldb.go | 4 +-- metrics/cpu_disabled.go | 4 +-- metrics/cpu_enabled.go | 4 +-- metrics/cputime_unix.go | 4 +-- rpc/ipc_wasip1.go | 38 ++++++++++++++++++++++++++++ 10 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 rpc/ipc_wasip1.go diff --git a/cmd/utils/diskusage.go b/cmd/utils/diskusage.go index 0e88f91944..8174236ab7 100644 --- a/cmd/utils/diskusage.go +++ b/cmd/utils/diskusage.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . -//go:build !windows && !openbsd -// +build !windows,!openbsd +//go:build !windows && !openbsd && !wasip1 +// +build !windows,!openbsd,!wasip1 package utils diff --git a/crypto/kzg4844/kzg4844_ckzg_cgo.go b/crypto/kzg4844/kzg4844_ckzg_cgo.go index 11bc451b58..dce592b444 100644 --- a/crypto/kzg4844/kzg4844_ckzg_cgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_cgo.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 . -//go:build ckzg && !nacl && !js && cgo && !gofuzz +//go:build ckzg && !nacl && !js && !wasip1 && cgo && !gofuzz package kzg4844 diff --git a/crypto/kzg4844/kzg4844_ckzg_nocgo.go b/crypto/kzg4844/kzg4844_ckzg_nocgo.go index 70a78e80d1..0662b2632f 100644 --- a/crypto/kzg4844/kzg4844_ckzg_nocgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_nocgo.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 . -//go:build !ckzg || nacl || js || !cgo || gofuzz +//go:build !ckzg || nacl || js || wasip1 || !cgo || gofuzz package kzg4844 diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go index 87289253c0..5c7810c14c 100644 --- a/crypto/signature_cgo.go +++ b/crypto/signature_cgo.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build !nacl && !js && cgo && !gofuzz -// +build !nacl,!js,cgo,!gofuzz +//go:build !nacl && !js && !wasip1 && cgo && !gofuzz +// +build !nacl,!js,!wasip1,cgo,!gofuzz package crypto diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 16a785a186..2d35b49403 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build nacl || js || !cgo || gofuzz -// +build nacl js !cgo gofuzz +//go:build nacl || js || wasip1 || !cgo || gofuzz +// +build nacl js wasip1 !cgo gofuzz package crypto diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index f18503c941..1d88ed460b 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build !js -// +build !js +//go:build !js && !wasip1 +// +build !js,!wasip1 // Package leveldb implements the key-value database layer based on LevelDB. package leveldb diff --git a/metrics/cpu_disabled.go b/metrics/cpu_disabled.go index 025d97aeb3..8404b0edd4 100644 --- a/metrics/cpu_disabled.go +++ b/metrics/cpu_disabled.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build ios || js -// +build ios js +//go:build ios || js || wasip1 +// +build ios js wasip1 package metrics diff --git a/metrics/cpu_enabled.go b/metrics/cpu_enabled.go index 2359028a21..838c32fad8 100644 --- a/metrics/cpu_enabled.go +++ b/metrics/cpu_enabled.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build !ios && !js -// +build !ios,!js +//go:build !ios && !js && !wasip1 +// +build !ios,!js,!wasip1 package metrics diff --git a/metrics/cputime_unix.go b/metrics/cputime_unix.go index ad4f812fd2..a44bf80876 100644 --- a/metrics/cputime_unix.go +++ b/metrics/cputime_unix.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build !windows && !js -// +build !windows,!js +//go:build !windows && !js && !wasip1 +// +build !windows,!js,!wasip1 package metrics diff --git a/rpc/ipc_wasip1.go b/rpc/ipc_wasip1.go new file mode 100644 index 0000000000..2608e29222 --- /dev/null +++ b/rpc/ipc_wasip1.go @@ -0,0 +1,38 @@ +// 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 . + +//go:build wasip1 +// +build wasip1 + +package rpc + +import ( + "context" + "errors" + "net" +) + +var errNotSupported = errors.New("rpc: not supported") + +// ipcListen will create a named pipe on the given endpoint. +func ipcListen(endpoint string) (net.Listener, error) { + return nil, errNotSupported +} + +// newIPCConnection will connect to a named pipe with the given endpoint as name. +func newIPCConnection(ctx context.Context, endpoint string) (net.Conn, error) { + return nil, errNotSupported +} From 0e1a19da76d1761fdb3db78112a9d0e3571d43a4 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 30 Jan 2025 17:07:45 +0100 Subject: [PATCH 083/940] core: implement eip-7623 floor data gas (#30946) This PR builds on #29040 and updates it to the new version of the spec. I filled the EEST tests and they pass. Link to spec: https://eips.ethereum.org/EIPS/eip-7623 --------- Co-authored-by: Marius van der Wijden Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> Co-authored-by: lightclient --- cmd/evm/internal/t8ntool/transaction.go | 26 ++++-- core/error.go | 4 + core/state_processor_test.go | 4 +- core/state_transition.go | 82 +++++++++++++------ core/tracing/hooks.go | 3 + core/txpool/validation.go | 10 +++ core/verkle_witness_test.go | 2 +- ...h_getBlockReceipts-block-with-blob-tx.json | 8 +- ...ockReceipts-block-with-dynamic-fee-tx.json | 8 +- .../eth_getBlockReceipts-tag-latest.json | 8 +- .../eth_getTransactionReceipt-blob-tx.json | 8 +- ...eipt-create-contract-with-access-list.json | 8 +- ...ansactionReceipt-dynamic-tx-with-logs.json | 8 +- params/protocol_params.go | 2 + 14 files changed, 125 insertions(+), 56 deletions(-) diff --git a/cmd/evm/internal/t8ntool/transaction.go b/cmd/evm/internal/t8ntool/transaction.go index d8650beca6..2bc4f73b60 100644 --- a/cmd/evm/internal/t8ntool/transaction.go +++ b/cmd/evm/internal/t8ntool/transaction.go @@ -133,15 +133,29 @@ func Transaction(ctx *cli.Context) error { r.Address = sender } // Check intrinsic gas - if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, - chainConfig.IsHomestead(new(big.Int)), chainConfig.IsIstanbul(new(big.Int)), chainConfig.IsShanghai(new(big.Int), 0)); err != nil { + rules := chainConfig.Rules(common.Big0, true, 0) + gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) + if err != nil { r.Error = err results = append(results, r) continue - } else { - r.IntrinsicGas = gas - if tx.Gas() < gas { - r.Error = fmt.Errorf("%w: have %d, want %d", core.ErrIntrinsicGas, tx.Gas(), gas) + } + r.IntrinsicGas = gas + if tx.Gas() < gas { + r.Error = fmt.Errorf("%w: have %d, want %d", core.ErrIntrinsicGas, tx.Gas(), gas) + results = append(results, r) + continue + } + // For Prague txs, validate the floor data gas. + if rules.IsPrague { + floorDataGas, err := core.FloorDataGas(tx.Data()) + if err != nil { + r.Error = err + results = append(results, r) + continue + } + if tx.Gas() < floorDataGas { + r.Error = fmt.Errorf("%w: have %d, want %d", core.ErrFloorDataGas, tx.Gas(), floorDataGas) results = append(results, r) continue } diff --git a/core/error.go b/core/error.go index 82f7ddcf5d..ce3bbb7888 100644 --- a/core/error.go +++ b/core/error.go @@ -80,6 +80,10 @@ var ( // than required to start the invocation. ErrIntrinsicGas = errors.New("intrinsic gas too low") + // ErrFloorDataGas is returned if the transaction is specified to use less gas + // than required for the data floor cost. + ErrFloorDataGas = errors.New("insufficient gas for floor data gas cost") + // ErrTxTypeNotSupported is returned if a transaction is not supported in the // current network configuration. ErrTxTypeNotSupported = types.ErrTxTypeNotSupported diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 2f841eb64a..750f3708dc 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -251,9 +251,9 @@ func TestStateProcessorErrors(t *testing.T) { }, { // ErrMaxInitCodeSizeExceeded txs: []*types.Transaction{ - mkDynamicCreationTx(0, 500000, common.Big0, big.NewInt(params.InitialBaseFee), tooBigInitCode[:]), + mkDynamicCreationTx(0, 520000, common.Big0, big.NewInt(params.InitialBaseFee), tooBigInitCode[:]), }, - want: "could not apply tx 0 [0xd491405f06c92d118dd3208376fcee18a57c54bc52063ee4a26b1cf296857c25]: max initcode size exceeded: code size 49153 limit 49152", + want: "could not apply tx 0 [0x3a30404d42d6ccc843d7c391fd0c87b9b9795a0c174261b46d2ac95ca17b81cd]: max initcode size exceeded: code size 49153 limit 49152", }, { // ErrIntrinsicGas: Not enough gas to cover init code txs: []*types.Transaction{ diff --git a/core/state_transition.go b/core/state_transition.go index b6203e6aae..e9c88eaedf 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -17,6 +17,7 @@ package core import ( + "bytes" "fmt" "math" "math/big" @@ -79,12 +80,9 @@ func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.Set // Bump the required gas by the amount of transactional data if dataLen > 0 { // Zero and non-zero bytes are priced differently - var nz uint64 - for _, byt := range data { - if byt != 0 { - nz++ - } - } + z := uint64(bytes.Count(data, []byte{0})) + nz := dataLen - z + // Make sure we don't exceed uint64 for all data combinations nonZeroGas := params.TxDataNonZeroGasFrontier if isEIP2028 { @@ -95,7 +93,6 @@ func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.Set } gas += nz * nonZeroGas - z := dataLen - nz if (math.MaxUint64-gas)/params.TxDataZeroGas < z { return 0, ErrGasUintOverflow } @@ -119,6 +116,21 @@ func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.Set return gas, nil } +// FloorDataGas computes the minimum gas required for a transaction based on its data tokens (EIP-7623). +func FloorDataGas(data []byte) (uint64, error) { + var ( + z = uint64(bytes.Count(data, []byte{0})) + nz = uint64(len(data)) - z + tokens = nz*params.TxTokenPerNonZeroByte + z + ) + // Check for overflow + if (math.MaxUint64-params.TxGas)/params.TxCostFloorPerToken < tokens { + return 0, ErrGasUintOverflow + } + // Minimum gas required for a transaction based on its data tokens (EIP-7623). + return params.TxGas + tokens*params.TxCostFloorPerToken, nil +} + // toWordSize returns the ceiled word size required for init code payment calculation. func toWordSize(size uint64) uint64 { if size > math.MaxUint64-31 { @@ -414,6 +426,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { sender = vm.AccountRef(msg.From) rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil, st.evm.Context.Time) contractCreation = msg.To == nil + floorDataGas uint64 ) // Check clauses 4-5, subtract intrinsic gas if everything is correct @@ -424,6 +437,16 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { if st.gasRemaining < gas { return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas) } + // Gas limit suffices for the floor data cost (EIP-7623) + if rules.IsPrague { + floorDataGas, err = FloorDataGas(msg.Data) + if err != nil { + return nil, err + } + if msg.GasLimit < floorDataGas { + return nil, fmt.Errorf("%w: have %d, want %d", ErrFloorDataGas, msg.GasLimit, floorDataGas) + } + } if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil { t.OnGasChange(st.gasRemaining, st.gasRemaining-gas, tracing.GasChangeTxIntrinsicGas) } @@ -487,14 +510,21 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value) } - var gasRefund uint64 - if !rules.IsLondon { - // Before EIP-3529: refunds were capped to gasUsed / 2 - gasRefund = st.refundGas(params.RefundQuotient) - } else { - // After EIP-3529: refunds are capped to gasUsed / 5 - gasRefund = st.refundGas(params.RefundQuotientEIP3529) + // Compute refund counter, capped to a refund quotient. + gasRefund := st.calcRefund() + st.gasRemaining += gasRefund + if rules.IsPrague { + // After EIP-7623: Data-heavy transactions pay the floor gas. + if st.gasUsed() < floorDataGas { + prev := st.gasRemaining + st.gasRemaining = st.initialGas - floorDataGas + if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil { + t.OnGasChange(prev, st.gasRemaining, tracing.GasChangeTxDataFloor) + } + } } + st.returnGas() + effectiveTip := msg.GasPrice if rules.IsLondon { effectiveTip = new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee) @@ -585,20 +615,28 @@ func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization) return nil } -func (st *stateTransition) refundGas(refundQuotient uint64) uint64 { - // Apply refund counter, capped to a refund quotient - refund := st.gasUsed() / refundQuotient +// calcRefund computes refund counter, capped to a refund quotient. +func (st *stateTransition) calcRefund() uint64 { + var refund uint64 + if !st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) { + // Before EIP-3529: refunds were capped to gasUsed / 2 + refund = st.gasUsed() / params.RefundQuotient + } else { + // After EIP-3529: refunds are capped to gasUsed / 5 + refund = st.gasUsed() / params.RefundQuotientEIP3529 + } 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) } + return refund +} - st.gasRemaining += refund - - // Return ETH for remaining gas, exchanged at the original rate. +// returnGas returns ETH for remaining gas, +// exchanged at the original rate. +func (st *stateTransition) returnGas() { remaining := uint256.NewInt(st.gasRemaining) remaining.Mul(remaining, uint256.MustFromBig(st.msg.GasPrice)) st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn) @@ -610,8 +648,6 @@ func (st *stateTransition) refundGas(refundQuotient uint64) uint64 { // Also return remaining gas to the block gas counter so it is // available for the next transaction. st.gp.AddGas(st.gasRemaining) - - return refund } // gasUsed returns the amount of gas used up by the state transition. diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index da364444ed..167bcb5c16 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -313,6 +313,9 @@ const ( GasChangeWitnessCodeChunk GasChangeReason = 17 // GasChangeWitnessContractCollisionCheck flags the event of adding to the witness when checking for contract address collision. GasChangeWitnessContractCollisionCheck GasChangeReason = 18 + // GasChangeTxDataFloor is the amount of extra gas the transaction has to pay to reach the minimum gas requirement for the + // transaction data. This change will always be a negative change. + GasChangeTxDataFloor GasChangeReason = 19 // 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. diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 412418dcc9..dec711b173 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -115,6 +115,16 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types if tx.Gas() < intrGas { return fmt.Errorf("%w: gas %v, minimum needed %v", core.ErrIntrinsicGas, tx.Gas(), intrGas) } + // Ensure the transaction can cover floor data gas. + if opts.Config.IsPrague(head.Number, head.Time) { + floorDataGas, err := core.FloorDataGas(tx.Data()) + if err != nil { + return err + } + if tx.Gas() < floorDataGas { + return fmt.Errorf("%w: gas %v, minimum needed %v", core.ErrFloorDataGas, tx.Gas(), floorDataGas) + } + } // Ensure the gasprice is high enough to cover the requirement of the calling pool if tx.GasTipCapIntCmp(opts.MinTip) < 0 { return fmt.Errorf("%w: gas tip cap %v, minimum needed %v", ErrUnderpriced, tx.GasTipCap(), opts.MinTip) diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go index 763939735e..500fb37156 100644 --- a/core/verkle_witness_test.go +++ b/core/verkle_witness_test.go @@ -147,7 +147,7 @@ func TestProcessVerkle(t *testing.T) { 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 */ + uint64(4844) /* execution costs */ blockGasUsagesExpected := []uint64{ txCost1*2 + txCost2, txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas, diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json index df2d9349fb..5853724cd6 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json @@ -2,19 +2,19 @@ { "blobGasPrice": "0x1", "blobGasUsed": "0x20000", - "blockHash": "0x17124e31fb075a301b1d7d4135683b0a09fe4e6d453c54e2e734d5ee00744a49", + "blockHash": "0x5f58514bcb3b216908f0aff6ced44666c3aa250df06093150ac850a7a7850f3c", "blockNumber": "0x6", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x1b09d63b", + "effectiveGasPrice": "0x1b0a08c4", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xb51ee3d2a89ba5d5623c73133c8d7a6ba9fb41194c17f4302c21b30994a1180f", + "transactionHash": "0x80348f994fb5f3b05bd2e5f58bbdc73485e449c028612a2c0680f9ac6ff70add", "transactionIndex": "0x0", "type": "0x3" } -] \ No newline at end of file +] diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json index b01400e605..602b25e21f 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json @@ -1,12 +1,12 @@ [ { - "blockHash": "0x102e50de30318ee99a03a09db74387e79cad3165bf6840cc84249806a2a302f3", + "blockHash": "0x47cd44027bb55856a175e36be0396bad221e52172529d9c1bf12bf5424a041ae", "blockNumber": "0x4", "contractAddress": null, - "cumulativeGasUsed": "0x538d", + "cumulativeGasUsed": "0x5564", "effectiveGasPrice": "0x2325c42f", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x538d", + "gasUsed": "0x5564", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x0", @@ -15,4 +15,4 @@ "transactionIndex": "0x0", "type": "0x2" } -] \ No newline at end of file +] diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json b/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json index df2d9349fb..5853724cd6 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json @@ -2,19 +2,19 @@ { "blobGasPrice": "0x1", "blobGasUsed": "0x20000", - "blockHash": "0x17124e31fb075a301b1d7d4135683b0a09fe4e6d453c54e2e734d5ee00744a49", + "blockHash": "0x5f58514bcb3b216908f0aff6ced44666c3aa250df06093150ac850a7a7850f3c", "blockNumber": "0x6", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x1b09d63b", + "effectiveGasPrice": "0x1b0a08c4", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xb51ee3d2a89ba5d5623c73133c8d7a6ba9fb41194c17f4302c21b30994a1180f", + "transactionHash": "0x80348f994fb5f3b05bd2e5f58bbdc73485e449c028612a2c0680f9ac6ff70add", "transactionIndex": "0x0", "type": "0x3" } -] \ No newline at end of file +] diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json b/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json index 8e0669d10a..386f1225e6 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json @@ -1,18 +1,18 @@ { "blobGasPrice": "0x1", "blobGasUsed": "0x20000", - "blockHash": "0x17124e31fb075a301b1d7d4135683b0a09fe4e6d453c54e2e734d5ee00744a49", + "blockHash": "0x5f58514bcb3b216908f0aff6ced44666c3aa250df06093150ac850a7a7850f3c", "blockNumber": "0x6", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x1b09d63b", + "effectiveGasPrice": "0x1b0a08c4", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xb51ee3d2a89ba5d5623c73133c8d7a6ba9fb41194c17f4302c21b30994a1180f", + "transactionHash": "0x80348f994fb5f3b05bd2e5f58bbdc73485e449c028612a2c0680f9ac6ff70add", "transactionIndex": "0x0", "type": "0x3" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json index 49c06aad62..0519ae1da4 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json @@ -1,16 +1,16 @@ { - "blockHash": "0x53bffe54375c0a31fe7bc0db7455db7d48278234c2400efa4d40d1c57cbe868d", + "blockHash": "0x5bff93f8f94ba7ee52bef1a80062b9fed22c6d1eebb2b0e87a4a003365a7bd66", "blockNumber": "0x5", "contractAddress": "0xfdaa97661a584d977b4d3abb5370766ff5b86a18", "cumulativeGasUsed": "0xe01c", - "effectiveGasPrice": "0x1ecb3fb4", + "effectiveGasPrice": "0x1ecb7942", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0xe01c", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": null, - "transactionHash": "0xb5a1148819cfdfff9bfe70035524fec940eb735d89b76960b97751d01ae2a9f2", + "transactionHash": "0x173dffc76966c72542560c376ce512a871e31b86988f9169bf021da0937640f9", "transactionIndex": "0x0", "type": "0x1" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json b/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json index 13bd7bd12c..4601273a51 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json @@ -1,11 +1,11 @@ { - "blockHash": "0x102e50de30318ee99a03a09db74387e79cad3165bf6840cc84249806a2a302f3", + "blockHash": "0x47cd44027bb55856a175e36be0396bad221e52172529d9c1bf12bf5424a041ae", "blockNumber": "0x4", "contractAddress": null, - "cumulativeGasUsed": "0x538d", + "cumulativeGasUsed": "0x5564", "effectiveGasPrice": "0x2325c42f", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x538d", + "gasUsed": "0x5564", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x0", @@ -13,4 +13,4 @@ "transactionHash": "0xdcde2574628c9d7dff22b9afa19f235959a924ceec65a9df903a517ae91f5c84", "transactionIndex": "0x0", "type": "0x2" -} \ No newline at end of file +} diff --git a/params/protocol_params.go b/params/protocol_params.go index f06346db84..a56eed5683 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -92,6 +92,8 @@ const ( TxDataNonZeroGasFrontier uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions. TxDataNonZeroGasEIP2028 uint64 = 16 // Per byte of non zero data attached to a transaction after EIP 2028 (part in Istanbul) + TxTokenPerNonZeroByte uint64 = 4 // Token cost per non-zero byte as specified by EIP-7623. + TxCostFloorPerToken uint64 = 10 // Cost floor per byte of data as specified by EIP-7623. TxAccessListAddressGas uint64 = 2400 // Per address specified in EIP 2930 access list TxAccessListStorageKeyGas uint64 = 1900 // Per storage key specified in EIP 2930 access list TxAuthTupleGas uint64 = 12500 // Per auth tuple code specified in EIP-7702 From a50cac5bbe1aeb6fdd74f02a83cea5a459bcab19 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 30 Jan 2025 17:08:42 +0100 Subject: [PATCH 084/940] core/vm: EXTCODE* return delegation designator for 7702 (#31089) Implements https://github.com/ethereum/EIPs/pull/9248 --- core/vm/eips.go | 59 ------------------------------------------------- 1 file changed, 59 deletions(-) diff --git a/core/vm/eips.go b/core/vm/eips.go index ab58702428..515999bd19 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -23,8 +23,6 @@ import ( "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" "github.com/holiman/uint256" ) @@ -709,65 +707,8 @@ func enableEOF(jt *JumpTable) { } } -// opExtCodeCopyEIP7702 implements the EIP-7702 variation of opExtCodeCopy. -func opExtCodeCopyEIP7702(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 - } - code := interpreter.evm.StateDB.GetCode(common.Address(a.Bytes20())) - if _, ok := types.ParseDelegation(code); ok { - code = types.DelegationPrefix[:2] - } - codeCopy := getData(code, uint64CodeOffset, length.Uint64()) - scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - - return nil, nil -} - -// opExtCodeSizeEIP7702 implements the EIP-7702 variation of opExtCodeSize. -func opExtCodeSizeEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - slot := scope.Stack.peek() - code := interpreter.evm.StateDB.GetCode(common.Address(slot.Bytes20())) - if _, ok := types.ParseDelegation(code); ok { - code = types.DelegationPrefix[:2] - } - slot.SetUint64(uint64(len(code))) - return nil, nil -} - -// opExtCodeHashEIP7702 implements the EIP-7702 variation of opExtCodeHash. -func opExtCodeHashEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - slot := scope.Stack.peek() - addr := common.Address(slot.Bytes20()) - if interpreter.evm.StateDB.Empty(addr) { - slot.Clear() - return nil, nil - } - code := interpreter.evm.StateDB.GetCode(addr) - if _, ok := types.ParseDelegation(code); ok { - // If the code is a delegation, return the prefix without version. - slot.SetBytes(crypto.Keccak256(types.DelegationPrefix[:2])) - } else { - // Otherwise, return normal code hash. - slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(addr).Bytes()) - } - return nil, nil -} - // enable7702 the EIP-7702 changes to support delegation designators. func enable7702(jt *JumpTable) { - jt[EXTCODECOPY].execute = opExtCodeCopyEIP7702 - jt[EXTCODESIZE].execute = opExtCodeSizeEIP7702 - jt[EXTCODEHASH].execute = opExtCodeHashEIP7702 - jt[CALL].dynamicGas = gasCallEIP7702 jt[CALLCODE].dynamicGas = gasCallCodeEIP7702 jt[STATICCALL].dynamicGas = gasStaticCallEIP7702 From 8daefeb890e827441914e69edf18c86d8c4398c7 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Fri, 31 Jan 2025 02:36:49 -0700 Subject: [PATCH 085/940] params: update system contract addresses for devnet-6 (#31102) Finalize Prague system contract addresses. Reference: * https://github.com/ethereum/EIPs/pull/9287 * https://github.com/ethereum/EIPs/pull/9288 * https://github.com/ethereum/EIPs/pull/9289 --- params/protocol_params.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/params/protocol_params.go b/params/protocol_params.go index a56eed5683..c9179634a5 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -205,14 +205,14 @@ var ( BeaconRootsCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500") // EIP-2935 - Serve historical block hashes from state - HistoryStorageAddress = common.HexToAddress("0x0F792be4B0c0cb4DAE440Ef133E90C0eCD48CCCC") + HistoryStorageAddress = common.HexToAddress("0x0000F90827F1C53a10cb7A02335B175320002935") HistoryStorageCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500") // EIP-7002 - Execution layer triggerable withdrawals - WithdrawalQueueAddress = common.HexToAddress("0x0c15F14308530b7CDB8460094BbB9cC28b9AaaAA") + WithdrawalQueueAddress = common.HexToAddress("0x00000961Ef480Eb55e80D19ad83579A64c007002") WithdrawalQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd") // EIP-7251 - Increase the MAX_EFFECTIVE_BALANCE - ConsolidationQueueAddress = common.HexToAddress("0x00431F263cE400f4455c2dCf564e53007Ca4bbBb") + ConsolidationQueueAddress = common.HexToAddress("0x0000BBdDc7CE488642fb579F8B00f3a590007251") ConsolidationQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd") ) From fc12dbe40bdb3fd77d0ea6049570b8c870421859 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 31 Jan 2025 18:34:22 +0100 Subject: [PATCH 086/940] eth/catalyst: fix validation of type 0 request (#31103) I caught this error on Hive. It was introduced by https://github.com/ethereum/go-ethereum/pull/31071 because after adding the equality check the request type 0 will be rejected. --- eth/catalyst/api.go | 6 ++--- eth/catalyst/api_test.go | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 7a9707dc15..e6f29c970b 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -1272,18 +1272,16 @@ func convertRequests(hex []hexutil.Bytes) [][]byte { // validateRequests checks that requests are ordered by their type and are not empty. func validateRequests(requests [][]byte) error { - var last byte - for _, req := range requests { + for i, req := range requests { // No empty requests. if len(req) < 2 { return fmt.Errorf("empty request: %v", req) } // Check that requests are ordered by their type. // Each type must appear only once. - if req[0] <= last { + if i > 0 && req[0] <= requests[i-1][0] { return fmt.Errorf("invalid request order: %v", req) } - last = req[0] } return nil } diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index 4698827731..407f0db3eb 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -1737,3 +1737,61 @@ func TestGetClientVersion(t *testing.T) { t.Fatalf("client info does match expected, got %s", info.String()) } } + +func TestValidateRequests(t *testing.T) { + tests := []struct { + name string + requests [][]byte + wantErr bool + }{ + { + name: "valid ascending", + requests: [][]byte{ + {0x00, 0xAA, 0xBB}, // type 0x00 + {0x01, 0xCC}, // type 0x01 + {0x02, 0xDD}, // type 0x02 + }, + wantErr: false, + }, + { + name: "empty request (too short)", + requests: [][]byte{ + {0x00}, // only 1 byte: type with no data + }, + wantErr: true, + }, + { + name: "duplicate type", + requests: [][]byte{ + {0x00, 0x11}, + {0x01, 0x22}, + {0x01, 0x33}, // duplicate type 0x01 + }, + wantErr: true, + }, + { + name: "out of order", + requests: [][]byte{ + {0x01, 0xAA}, // type 0x01 + {0x00, 0xBB}, // type 0x00 out of order (should be ascending) + }, + wantErr: true, + }, + { + name: "single request valid", + requests: [][]byte{ + {0x01, 0xAB}, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateRequests(tt.requests) + if (err != nil) != tt.wantErr { + t.Errorf("validateRequests(%v) error = %v, wantErr = %v", + tt.requests, err, tt.wantErr) + } + }) + } +} From 55a18616b1c4d2ffee498e07ddef23f49bddbb6d Mon Sep 17 00:00:00 2001 From: jwasinger Date: Mon, 3 Feb 2025 09:44:26 -0800 Subject: [PATCH 087/940] core/vm: simplify tracer hook invocation in interpreter loop (#31074) Removes duplicate code in the interpreter loop. --- core/vm/interpreter.go | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index e3237936a0..a0038d1aa8 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -258,9 +258,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( contract.Gas -= cost } + // All ops with a dynamic memory usage also has a dynamic gas cost. + var memorySize uint64 if operation.dynamicGas != nil { - // All ops with a dynamic memory usage also has a dynamic gas cost. - var memorySize uint64 // calculate the new memory size and expand the memory to fit // the operation // Memory check needs to be done prior to evaluating the dynamic gas portion, @@ -290,21 +290,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( } else { contract.Gas -= dynamicCost } + } - // Do tracing before memory expansion - if debug { - 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 { + // Do tracing before potential memory expansion + if debug { if in.evm.Config.Tracer.OnGasChange != nil { in.evm.Config.Tracer.OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode) } @@ -313,6 +302,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( logged = true } } + if memorySize > 0 { + mem.Resize(memorySize) + } // execute the operation res, err = operation.execute(&pc, in, callContext) From e26dd774a9c0f77f814673d64870d84da79cd549 Mon Sep 17 00:00:00 2001 From: kazak Date: Tue, 4 Feb 2025 08:09:06 +0200 Subject: [PATCH 088/940] tests/fuzzers/bls12381: fix error message in fuzzCrossG2Add (#31113) Fixes a typo in the error message within the `fuzzCrossG2Add` function. The panic message incorrectly references "G1 point addition mismatch" when it should be "G2 point addition mismatch," as the function deals with G2 points. This doesn't affect functionality but could cause confusion during debugging. I've updated the message to reflect the correct curve. --- tests/fuzzers/bls12381/bls12381_fuzz.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fuzzers/bls12381/bls12381_fuzz.go b/tests/fuzzers/bls12381/bls12381_fuzz.go index 5cb05b5660..a17c128b7f 100644 --- a/tests/fuzzers/bls12381/bls12381_fuzz.go +++ b/tests/fuzzers/bls12381/bls12381_fuzz.go @@ -168,7 +168,7 @@ func fuzzCrossG2Add(data []byte) int { bl3 := blst.P2AffinesAdd([]*blst.P2Affine{bl1, bl2}) if !(bytes.Equal(gp.Marshal(), bl3.Serialize())) { - panic("G1 point addition mismatch blst / geth ") + panic("G2 point addition mismatch blst / geth ") } return 1 From 0ad0966cecf0602bc554fd368d2a02ea762baf8c Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 4 Feb 2025 18:45:45 +0800 Subject: [PATCH 089/940] core/rawdb: introduce flush offset in freezer (#30392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a follow-up PR to #29792 to get rid of the data file sync. **This is a non-backward compatible change, which increments the database version from 8 to 9**. We introduce a flushOffset for each freezer table, which tracks the position of the most recently fsync’d item in the index file. When this offset moves forward, it indicates that all index entries below it, along with their corresponding data items, have been properly persisted to disk. The offset can also be moved backward when truncating from either the head or tail of the file. Previously, the data file required an explicit fsync after every mutation, which was highly inefficient. With the introduction of the flush offset, the synchronization strategy becomes more flexible, allowing the freezer to sync every 30 seconds instead. The data items above the flush offset are regarded volatile and callers must ensure they are recoverable after the unclean shutdown, or explicitly sync the freezer before any proceeding operations. --------- Co-authored-by: Felix Lange --- core/blockchain.go | 10 +- core/rawdb/accessors_chain_test.go | 3 +- core/rawdb/ancient_scheme.go | 1 + core/rawdb/freezer_batch.go | 10 +- core/rawdb/freezer_meta.go | 192 +++++++++++----- core/rawdb/freezer_meta_test.go | 88 ++++++- core/rawdb/freezer_table.go | 264 ++++++++++++++------- core/rawdb/freezer_table_test.go | 356 ++++++++++++++++++++--------- 8 files changed, 664 insertions(+), 260 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index ab88f4b68e..f097dc9781 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -113,23 +113,29 @@ const ( // * the `BlockNumber`, `TxHash`, `TxIndex`, `BlockHash` and `Index` fields of log are deleted // * the `Bloom` field of receipt is deleted // * the `BlockIndex` and `TxIndex` fields of txlookup are deleted + // // - Version 5 // The following incompatible database changes were added: // * the `TxHash`, `GasCost`, and `ContractAddress` fields are no longer stored for a receipt // * the `TxHash`, `GasCost`, and `ContractAddress` fields are computed by looking up the // receipts' corresponding block + // // - Version 6 // The following incompatible database changes were added: // * Transaction lookup information stores the corresponding block number instead of block hash + // // - Version 7 // The following incompatible database changes were added: // * Use freezer as the ancient database to maintain all ancient data + // // - Version 8 // The following incompatible database changes were added: // * New scheme for contract code in order to separate the codes and trie nodes + // // - Version 9 - // Total difficulty has been removed from both the key-value store and the - // ancient store, the td freezer table has been deprecated since that. + // The following incompatible database changes were added: + // * Total difficulty has been removed from both the key-value store and the ancient store. + // * The metadata structure of freezer is changed by adding 'flushOffset' BlockChainVersion uint64 = 9 ) diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 5533c60ab9..b9684f8e17 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -849,6 +849,7 @@ func TestHeadersRLPStorage(t *testing.T) { t.Fatalf("failed to create database with ancient backend") } defer db.Close() + // Create blocks var chain []*types.Block var pHash common.Hash @@ -864,7 +865,7 @@ func TestHeadersRLPStorage(t *testing.T) { chain = append(chain, block) pHash = block.Hash() } - var receipts []types.Receipts = make([]types.Receipts, 100) + receipts := make([]types.Receipts, 100) // Write first half to ancients WriteAncientBlocks(db, chain[:50], receipts[:50]) // Write second half to db diff --git a/core/rawdb/ancient_scheme.go b/core/rawdb/ancient_scheme.go index 54a3be391f..67bfa37ecc 100644 --- a/core/rawdb/ancient_scheme.go +++ b/core/rawdb/ancient_scheme.go @@ -58,6 +58,7 @@ const ( stateHistoryStorageData = "storage.data" ) +// stateFreezerNoSnappy configures whether compression is disabled for the state freezer. var stateFreezerNoSnappy = map[string]bool{ stateHistoryMeta: true, stateHistoryAccountIndex: false, diff --git a/core/rawdb/freezer_batch.go b/core/rawdb/freezer_batch.go index 013d0b9d13..801d30f73f 100644 --- a/core/rawdb/freezer_batch.go +++ b/core/rawdb/freezer_batch.go @@ -19,6 +19,7 @@ package rawdb import ( "fmt" "math" + "time" "github.com/ethereum/go-ethereum/rlp" "github.com/golang/snappy" @@ -188,9 +189,6 @@ func (batch *freezerTableBatch) commit() error { if err != nil { return err } - if err := batch.t.head.Sync(); err != nil { - return err - } dataSize := int64(len(batch.dataBuffer)) batch.dataBuffer = batch.dataBuffer[:0] @@ -208,6 +206,12 @@ func (batch *freezerTableBatch) commit() error { // Update metrics. batch.t.sizeGauge.Inc(dataSize + indexSize) batch.t.writeMeter.Mark(dataSize + indexSize) + + // Periodically sync the table, todo (rjl493456442) make it configurable? + if time.Since(batch.t.lastSync) > 30*time.Second { + batch.t.lastSync = time.Now() + return batch.t.Sync() + } return nil } diff --git a/core/rawdb/freezer_meta.go b/core/rawdb/freezer_meta.go index 9eef9df351..3cda9ae45c 100644 --- a/core/rawdb/freezer_meta.go +++ b/core/rawdb/freezer_meta.go @@ -17,93 +17,173 @@ package rawdb import ( + "errors" "io" + "math" "os" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" ) -const freezerVersion = 1 // The initial version tag of freezer table metadata +const ( + freezerTableV1 = 1 // Initial version of metadata struct + freezerTableV2 = 2 // Add field: 'flushOffset' + freezerVersion = freezerTableV2 // The current used version +) -// freezerTableMeta wraps all the metadata of the freezer table. +// freezerTableMeta is a collection of additional properties that describe the +// freezer table. These properties are designed with error resilience, allowing +// them to be automatically corrected after an error occurs without significantly +// impacting overall correctness. type freezerTableMeta struct { - // Version is the versioning descriptor of the freezer table. - Version uint16 + file *os.File // file handler of metadata + version uint16 // version descriptor of the freezer table - // VirtualTail indicates how many items have been marked as deleted. - // Its value is equal to the number of items removed from the table - // plus the number of items hidden in the table, so it should never - // be lower than the "actual tail". - VirtualTail uint64 + // virtualTail represents the number of items marked as deleted. It is + // calculated as the sum of items removed from the table and the items + // hidden within the table, and should never be less than the "actual + // tail". + // + // If lost due to a crash or other reasons, it will be reset to the number + // of items deleted from the table, causing the previously hidden items + // to become visible, which is an acceptable consequence. + virtualTail uint64 + + // flushOffset represents the offset in the index file up to which the index + // items along with the corresponding data items in data files has been flushed + // (fsync’d) to disk. Beyond this offset, data integrity is not guaranteed, + // the extra index items along with the associated data items should be removed + // during the startup. + // + // The principle is that all data items above the flush offset are considered + // volatile and should be recoverable if they are discarded after the unclean + // shutdown. If data integrity is required, manually force a sync of the + // freezer before proceeding with further operations (e.g. do freezer.Sync() + // first and then write data to key value store in some circumstances). + // + // The offset could be moved forward by applying sync operation, or be moved + // backward in cases of head/tail truncation, etc. + flushOffset int64 } -// newMetadata initializes the metadata object with the given virtual tail. -func newMetadata(tail uint64) *freezerTableMeta { +// decodeV1 attempts to decode the metadata structure in v1 format. If fails or +// the result is incompatible, nil is returned. +func decodeV1(file *os.File) *freezerTableMeta { + _, err := file.Seek(0, io.SeekStart) + if err != nil { + return nil + } + type obj struct { + Version uint16 + Tail uint64 + } + var o obj + if err := rlp.Decode(file, &o); err != nil { + return nil + } + if o.Version != freezerTableV1 { + return nil + } return &freezerTableMeta{ - Version: freezerVersion, - VirtualTail: tail, + file: file, + version: o.Version, + virtualTail: o.Tail, } } -// readMetadata reads the metadata of the freezer table from the -// given metadata file. -func readMetadata(file *os.File) (*freezerTableMeta, error) { +// decodeV2 attempts to decode the metadata structure in v2 format. If fails or +// the result is incompatible, nil is returned. +func decodeV2(file *os.File) *freezerTableMeta { _, err := file.Seek(0, io.SeekStart) if err != nil { - return nil, err + return nil } - var meta freezerTableMeta - if err := rlp.Decode(file, &meta); err != nil { - return nil, err + type obj struct { + Version uint16 + Tail uint64 + Offset uint64 + } + var o obj + if err := rlp.Decode(file, &o); err != nil { + return nil + } + if o.Version != freezerTableV2 { + return nil + } + if o.Offset > math.MaxInt64 { + log.Error("Invalid flushOffset %d in freezer metadata", o.Offset, "file", file.Name()) + return nil + } + return &freezerTableMeta{ + file: file, + version: freezerTableV2, + virtualTail: o.Tail, + flushOffset: int64(o.Offset), } - return &meta, nil } -// writeMetadata writes the metadata of the freezer table into the -// given metadata file. -func writeMetadata(file *os.File, meta *freezerTableMeta) error { - _, err := file.Seek(0, io.SeekStart) - if err != nil { - return err - } - return rlp.Encode(file, meta) -} - -// loadMetadata loads the metadata from the given metadata file. -// Initializes the metadata file with the given "actual tail" if -// it's empty. -func loadMetadata(file *os.File, tail uint64) (*freezerTableMeta, error) { +// newMetadata initializes the metadata object, either by loading it from the file +// or by constructing a new one from scratch. +func newMetadata(file *os.File) (*freezerTableMeta, error) { stat, err := file.Stat() if err != nil { return nil, err } - // Write the metadata with the given actual tail into metadata file - // if it's non-existent. There are two possible scenarios here: - // - the freezer table is empty - // - the freezer table is legacy - // In both cases, write the meta into the file with the actual tail - // as the virtual tail. if stat.Size() == 0 { - m := newMetadata(tail) - if err := writeMetadata(file, m); err != nil { + m := &freezerTableMeta{ + file: file, + version: freezerTableV2, + virtualTail: 0, + flushOffset: 0, + } + if err := m.write(true); err != nil { return nil, err } return m, nil } - m, err := readMetadata(file) - if err != nil { - return nil, err + if m := decodeV2(file); m != nil { + return m, nil } - // Update the virtual tail with the given actual tail if it's even - // lower than it. Theoretically it shouldn't happen at all, print - // a warning here. - if m.VirtualTail < tail { - log.Warn("Updated virtual tail", "have", m.VirtualTail, "now", tail) - m.VirtualTail = tail - if err := writeMetadata(file, m); err != nil { - return nil, err - } + if m := decodeV1(file); m != nil { + return m, nil // legacy metadata } - return m, nil + return nil, errors.New("failed to decode metadata") +} + +// setVirtualTail sets the virtual tail and flushes the metadata if sync is true. +func (m *freezerTableMeta) setVirtualTail(tail uint64, sync bool) error { + m.virtualTail = tail + return m.write(sync) +} + +// setFlushOffset sets the flush offset and flushes the metadata if sync is true. +func (m *freezerTableMeta) setFlushOffset(offset int64, sync bool) error { + m.flushOffset = offset + return m.write(sync) +} + +// write flushes the content of metadata into file and performs a fsync if required. +func (m *freezerTableMeta) write(sync bool) error { + type obj struct { + Version uint16 + Tail uint64 + Offset uint64 + } + var o obj + o.Version = freezerVersion // forcibly use the current version + o.Tail = m.virtualTail + o.Offset = uint64(m.flushOffset) + + _, err := m.file.Seek(0, io.SeekStart) + if err != nil { + return err + } + if err := rlp.Encode(m.file, &o); err != nil { + return err + } + if !sync { + return nil + } + return m.file.Sync() } diff --git a/core/rawdb/freezer_meta_test.go b/core/rawdb/freezer_meta_test.go index 409e811026..31f8c519c8 100644 --- a/core/rawdb/freezer_meta_test.go +++ b/core/rawdb/freezer_meta_test.go @@ -19,6 +19,8 @@ package rawdb import ( "os" "testing" + + "github.com/ethereum/go-ethereum/rlp" ) func TestReadWriteFreezerTableMeta(t *testing.T) { @@ -27,36 +29,98 @@ func TestReadWriteFreezerTableMeta(t *testing.T) { t.Fatalf("Failed to create file %v", err) } defer f.Close() - err = writeMetadata(f, newMetadata(100)) + + meta, err := newMetadata(f) if err != nil { - t.Fatalf("Failed to write metadata %v", err) + t.Fatalf("Failed to new metadata %v", err) } - meta, err := readMetadata(f) + meta.setVirtualTail(100, false) + + meta, err = newMetadata(f) if err != nil { - t.Fatalf("Failed to read metadata %v", err) + t.Fatalf("Failed to reload metadata %v", err) } - if meta.Version != freezerVersion { + if meta.version != freezerTableV2 { t.Fatalf("Unexpected version field") } - if meta.VirtualTail != uint64(100) { + if meta.virtualTail != uint64(100) { t.Fatalf("Unexpected virtual tail field") } } -func TestInitializeFreezerTableMeta(t *testing.T) { +func TestUpgradeMetadata(t *testing.T) { 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)) + + // Write legacy metadata into file + type obj struct { + Version uint16 + Tail uint64 + } + var o obj + o.Version = freezerTableV1 + o.Tail = 100 + + if err := rlp.Encode(f, &o); err != nil { + t.Fatalf("Failed to encode %v", err) + } + + // Reload the metadata, a silent upgrade is expected + meta, err := newMetadata(f) if err != nil { t.Fatalf("Failed to read metadata %v", err) } - if meta.Version != freezerVersion { - t.Fatalf("Unexpected version field") + if meta.version != freezerTableV1 { + t.Fatal("Unexpected version field") } - if meta.VirtualTail != uint64(100) { - t.Fatalf("Unexpected virtual tail field") + if meta.virtualTail != uint64(100) { + t.Fatal("Unexpected virtual tail field") + } + if meta.flushOffset != 0 { + t.Fatal("Unexpected flush offset field") + } + + meta.setFlushOffset(100, true) + + meta, err = newMetadata(f) + if err != nil { + t.Fatalf("Failed to read metadata %v", err) + } + if meta.version != freezerTableV2 { + t.Fatal("Unexpected version field") + } + if meta.virtualTail != uint64(100) { + t.Fatal("Unexpected virtual tail field") + } + if meta.flushOffset != 100 { + t.Fatal("Unexpected flush offset field") + } +} + +func TestInvalidMetadata(t *testing.T) { + f, err := os.CreateTemp(t.TempDir(), "*") + if err != nil { + t.Fatalf("Failed to create file %v", err) + } + defer f.Close() + + // Write invalid legacy metadata into file + type obj struct { + Version uint16 + Tail uint64 + } + var o obj + o.Version = freezerTableV2 // -> invalid version tag + o.Tail = 100 + + if err := rlp.Encode(f, &o); err != nil { + t.Fatalf("Failed to encode %v", err) + } + _, err = newMetadata(f) + if err == nil { + t.Fatal("Unexpected success") } } diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go index 38c47dc223..1ba8cf639f 100644 --- a/core/rawdb/freezer_table.go +++ b/core/rawdb/freezer_table.go @@ -108,11 +108,13 @@ type freezerTable struct { head *os.File // File descriptor for the data head of the table index *os.File // File descriptor for the indexEntry file of the table - meta *os.File // File descriptor for metadata of the table files map[uint32]*os.File // open files headId uint32 // number of the currently active head file tailId uint32 // number of the earliest file + metadata *freezerTableMeta // metadata of the table + lastSync time.Time // Timestamp when the last sync was performed + headBytes int64 // Number of bytes written to the head file readMeter *metrics.Meter // Meter for measuring the effective amount of data read writeMeter *metrics.Meter // Meter for measuring the effective amount of data written @@ -166,10 +168,17 @@ func newTable(path string, name string, readMeter, writeMeter *metrics.Meter, si return nil, err } } + // Load metadata from the file. The tag will be true if legacy metadata + // is detected. + metadata, err := newMetadata(meta) + if err != nil { + return nil, err + } // Create the table and repair any past inconsistency tab := &freezerTable{ index: index, - meta: meta, + metadata: metadata, + lastSync: time.Now(), files: make(map[uint32]*os.File), readMeter: readMeter, writeMeter: writeMeter, @@ -221,13 +230,11 @@ func (t *freezerTable) repair() error { return err } // New file can't trigger this path } - // Validate the index file as it might contain some garbage data after the - // power failures. if err := t.repairIndex(); err != nil { return err } // Retrieve the file sizes and prepare for truncation. Note the file size - // might be changed after index validation. + // might be changed after index repair. if stat, err = t.index.Stat(); err != nil { return err } @@ -253,12 +260,14 @@ func (t *freezerTable) repair() error { t.tailId = firstIndex.filenum t.itemOffset.Store(uint64(firstIndex.offset)) - // Load metadata from the file - meta, err := loadMetadata(t.meta, t.itemOffset.Load()) - if err != nil { - return err + // Adjust the number of hidden items if it is less than the number of items + // being removed. + if t.itemOffset.Load() > t.metadata.virtualTail { + if err := t.metadata.setVirtualTail(t.itemOffset.Load(), true); err != nil { + return err + } } - t.itemHidden.Store(meta.VirtualTail) + t.itemHidden.Store(t.metadata.virtualTail) // Read the last index, use the default value in case the freezer is empty if offsetsSize == indexEntrySize { @@ -267,12 +276,6 @@ func (t *freezerTable) repair() error { t.index.ReadAt(buffer, offsetsSize-indexEntrySize) lastIndex.unmarshalBinary(buffer) } - // Print an error log if the index is corrupted due to an incorrect - // last index item. While it is theoretically possible to have a zero offset - // by storing all zero-size items, it is highly unlikely to occur in practice. - if lastIndex.offset == 0 && offsetsSize/indexEntrySize > 1 { - log.Error("Corrupted index file detected", "lastOffset", lastIndex.offset, "indexes", offsetsSize/indexEntrySize) - } if t.readonly { t.head, err = t.openFile(lastIndex.filenum, openFreezerFileForReadOnly) } else { @@ -293,6 +296,7 @@ func (t *freezerTable) repair() error { return fmt.Errorf("freezer table(path: %s, name: %s, num: %d) is corrupted", t.path, t.name, lastIndex.filenum) } verbose = true + // Truncate the head file to the last offset pointer if contentExp < contentSize { t.logger.Warn("Truncating dangling head", "indexed", contentExp, "stored", contentSize) @@ -304,11 +308,23 @@ func (t *freezerTable) repair() error { // Truncate the index to point within the head file if contentExp > contentSize { t.logger.Warn("Truncating dangling indexes", "indexes", offsetsSize/indexEntrySize, "indexed", contentExp, "stored", contentSize) - if err := truncateFreezerFile(t.index, offsetsSize-indexEntrySize); err != nil { + + newOffset := offsetsSize - indexEntrySize + if err := truncateFreezerFile(t.index, newOffset); err != nil { return err } offsetsSize -= indexEntrySize + // If the index file is truncated beyond the flush offset, move the flush + // offset back to the new end of the file. A crash may occur before the + // offset is updated, leaving a dangling reference that points to a position + // outside the file. If so, the offset will be reset to the new end of the + // file during the next run. + if t.metadata.flushOffset > newOffset { + if err := t.metadata.setFlushOffset(newOffset, true); err != nil { + return err + } + } // Read the new head index, use the default value in case // the freezer is already empty. var newLastIndex indexEntry @@ -345,7 +361,7 @@ func (t *freezerTable) repair() error { if err := t.head.Sync(); err != nil { return err } - if err := t.meta.Sync(); err != nil { + if err := t.metadata.file.Sync(); err != nil { return err } } @@ -372,7 +388,65 @@ func (t *freezerTable) repair() error { return nil } -// repairIndex validates the integrity of the index file. According to the design, +func (t *freezerTable) repairIndex() error { + stat, err := t.index.Stat() + if err != nil { + return err + } + size := stat.Size() + + // Validate the items in the index file to ensure the data integrity. + // It's possible some garbage data is retained in the index file after + // the power failures and should be truncated first. + size, err = t.checkIndex(size) + if err != nil { + return err + } + // If legacy metadata is detected, attempt to recover the offset from the + // index file to avoid clearing the entire table. + if t.metadata.version == freezerTableV1 { + t.logger.Info("Recovering freezer flushOffset for legacy table", "offset", size) + return t.metadata.setFlushOffset(size, true) + } + + switch { + case size == indexEntrySize && t.metadata.flushOffset == 0: + // It's a new freezer table with no content. + // Move the flush offset to the end of the file. + return t.metadata.setFlushOffset(size, true) + + case size == t.metadata.flushOffset: + // flushOffset is aligned with the index file, all is well. + return nil + + case size > t.metadata.flushOffset: + // Extra index items have been detected beyond the flush offset. Since these + // entries correspond to data that has not been fully flushed to disk in the + // last run (because of unclean shutdown), their integrity cannot be guaranteed. + // To ensure consistency, these index items will be truncated, as there is no + // reliable way to validate or recover their associated data. + extraSize := size - t.metadata.flushOffset + if t.readonly { + return fmt.Errorf("index file(path: %s, name: %s) contains %d garbage data bytes", t.path, t.name, extraSize) + } + t.logger.Warn("Truncating freezer items after flushOffset", "size", extraSize) + return truncateFreezerFile(t.index, t.metadata.flushOffset) + + default: // size < flushOffset + // Flush offset refers to a position larger than index file. The only + // possible scenario for this is: a power failure or system crash has occurred after + // truncating the segment in index file from head or tail, but without updating + // the flush offset. In this case, automatically reset the flush offset with + // the file size which implies the entire index file is complete. + if t.readonly { + return nil // do nothing in read only mode + } + t.logger.Warn("Rewinding freezer flushOffset", "old", t.metadata.flushOffset, "new", size) + return t.metadata.setFlushOffset(size, true) + } +} + +// checkIndex validates the integrity of the index file. According to the design, // the initial entry in the file denotes the earliest data file along with the // count of deleted items. Following this, all subsequent entries in the file must // be in order. This function identifies any corrupted entries and truncates items @@ -392,18 +466,11 @@ func (t *freezerTable) repair() error { // leftover garbage or if all items in the table have zero size is impossible. // In such instances, the file will remain unchanged to prevent potential data // loss or misinterpretation. -func (t *freezerTable) repairIndex() error { - // Retrieve the file sizes and prepare for validation - stat, err := t.index.Stat() - if err != nil { - return err - } - size := stat.Size() - +func (t *freezerTable) checkIndex(size int64) (int64, error) { // Move the read cursor to the beginning of the file - _, err = t.index.Seek(0, io.SeekStart) + _, err := t.index.Seek(0, io.SeekStart) if err != nil { - return err + return 0, err } fr := bufio.NewReader(t.index) @@ -425,21 +492,21 @@ func (t *freezerTable) repairIndex() error { entry.unmarshalBinary(buff) return entry, nil } - truncate = func(offset int64) error { + truncate = func(offset int64) (int64, error) { if t.readonly { - return fmt.Errorf("index file is corrupted at %d, size: %d", offset, size) + return 0, fmt.Errorf("index file is corrupted at %d, size: %d", offset, size) } if err := truncateFreezerFile(t.index, offset); err != nil { - return err + return 0, err } log.Warn("Truncated index file", "offset", offset, "truncated", size-offset) - return nil + return offset, nil } ) for offset := int64(0); offset < size; offset += indexEntrySize { entry, err := read() if err != nil { - return err + return 0, err } if offset == 0 { head = entry @@ -468,10 +535,10 @@ func (t *freezerTable) repairIndex() error { // the seek operation anyway as a precaution. _, err = t.index.Seek(0, io.SeekEnd) if err != nil { - return err + return 0, err } log.Debug("Verified index file", "items", size/indexEntrySize, "elapsed", common.PrettyDuration(time.Since(start))) - return nil + return size, nil } // checkIndexItems validates the correctness of two consecutive index items based @@ -550,12 +617,23 @@ func (t *freezerTable) truncateHead(items uint64) error { // Truncate the index file first, the tail position is also considered // when calculating the new freezer table length. length := items - t.itemOffset.Load() - if err := truncateFreezerFile(t.index, int64(length+1)*indexEntrySize); err != nil { + newOffset := (length + 1) * indexEntrySize + if err := truncateFreezerFile(t.index, int64(newOffset)); err != nil { return err } if err := t.index.Sync(); err != nil { return err } + // If the index file is truncated beyond the flush offset, move the flush + // offset back to the new end of the file. A crash may occur before the + // offset is updated, leaving a dangling reference that points to a position + // outside the file. If so, the offset will be reset to the new end of the + // file during the next run. + if t.metadata.flushOffset > int64(newOffset) { + if err := t.metadata.setFlushOffset(int64(newOffset), true); err != nil { + return err + } + } // Calculate the new expected size of the data file and truncate it var expected indexEntry if length == 0 { @@ -652,7 +730,10 @@ func (t *freezerTable) truncateTail(items uint64) error { } // Update the virtual tail marker and hidden these entries in table. t.itemHidden.Store(items) - if err := writeMetadata(t.meta, newMetadata(items)); err != nil { + + // Update the virtual tail without fsync, otherwise it will significantly + // impact the overall performance. + if err := t.metadata.setVirtualTail(items, false); err != nil { return err } // Hidden items still fall in the current tail file, no data file @@ -664,6 +745,18 @@ func (t *freezerTable) truncateTail(items uint64) error { if t.tailId > newTailId { return fmt.Errorf("invalid index, tail-file %d, item-file %d", t.tailId, newTailId) } + // Sync the table before performing the index tail truncation. A crash may + // occur after truncating the index file without updating the flush offset, + // leaving a dangling offset that points to a position outside the file. + // The offset will be rewound to the end of file during the next run + // automatically and implicitly assumes all the items within the file are + // complete. + // + // Therefore, forcibly flush everything above the offset to ensure this + // assumption is satisfied! + if err := t.doSync(); err != nil { + return err + } // Count how many items can be deleted from the file. var ( newDeleted = items @@ -681,11 +774,6 @@ func (t *freezerTable) truncateTail(items uint64) error { } newDeleted = current } - // Commit the changes of metadata file first before manipulating - // the indexes file. - if err := t.meta.Sync(); err != nil { - return err - } // Close the index file before shorten it. if err := t.index.Close(); err != nil { return err @@ -716,6 +804,21 @@ func (t *freezerTable) truncateTail(items uint64) error { t.itemOffset.Store(newDeleted) t.releaseFilesBefore(t.tailId, true) + // Move the index flush offset backward due to the deletion of an index segment. + // A crash may occur before the offset is updated, leaving a dangling reference + // that points to a position outside the file. If so, the offset will be reset + // to the new end of the file during the next run. + // + // Note, both the index and head data file has been persisted before performing + // tail truncation and all the items in these files are regarded as complete. + shorten := indexEntrySize * int64(newDeleted-deleted) + if t.metadata.flushOffset <= shorten { + return fmt.Errorf("invalid index flush offset: %d, shorten: %d", t.metadata.flushOffset, shorten) + } else { + if err := t.metadata.setFlushOffset(t.metadata.flushOffset-shorten, true); err != nil { + return err + } + } // Retrieve the new size and update the total size counter newSize, err := t.sizeNolock() if err != nil { @@ -725,40 +828,30 @@ func (t *freezerTable) truncateTail(items uint64) error { return nil } -// Close closes all opened files. +// Close closes all opened files and finalizes the freezer table for use. +// This operation must be completed before shutdown to prevent the loss of +// recent writes. func (t *freezerTable) Close() error { t.lock.Lock() defer t.lock.Unlock() + if err := t.doSync(); err != nil { + return err + } var errs []error - doClose := func(f *os.File, sync bool, close bool) { - if sync && !t.readonly { - if err := f.Sync(); err != nil { - errs = append(errs, err) - } - } - if close { - if err := f.Close(); err != nil { - errs = append(errs, err) - } + doClose := func(f *os.File) { + if err := f.Close(); err != nil { + errs = append(errs, err) } } - // Trying to fsync a file opened in rdonly causes "Access denied" - // error on Windows. - doClose(t.index, true, true) - doClose(t.meta, true, true) - - // The preopened non-head data-files are all opened in readonly. - // The head is opened in rw-mode, so we sync it here - but since it's also - // part of t.files, it will be closed in the loop below. - doClose(t.head, true, false) // sync but do not close - + doClose(t.index) + doClose(t.metadata.file) for _, f := range t.files { - doClose(f, false, true) // close but do not sync + doClose(f) } t.index = nil - t.meta = nil t.head = nil + t.metadata.file = nil if errs != nil { return fmt.Errorf("%v", errs) @@ -917,7 +1010,7 @@ func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []i defer t.lock.RUnlock() // Ensure the table and the item are accessible - if t.index == nil || t.head == nil || t.meta == nil { + if t.index == nil || t.head == nil || t.metadata.file == nil { return nil, nil, errClosed } var ( @@ -1042,6 +1135,9 @@ func (t *freezerTable) advanceHead() error { t.lock.Lock() defer t.lock.Unlock() + if err := t.doSync(); err != nil { + return err + } // We open the next file in truncated mode -- if this file already // exists, we need to start over from scratch on it. nextID := t.headId + 1 @@ -1069,7 +1165,18 @@ func (t *freezerTable) advanceHead() error { func (t *freezerTable) Sync() error { t.lock.Lock() defer t.lock.Unlock() - if t.index == nil || t.head == nil || t.meta == nil { + + return t.doSync() +} + +// doSync is the internal version of Sync which assumes the lock is already held. +func (t *freezerTable) doSync() error { + // Trying to fsync a file opened in rdonly causes "Access denied" + // error on Windows. + if t.readonly { + return nil + } + if t.index == nil || t.head == nil || t.metadata.file == nil { return errClosed } var err error @@ -1078,10 +1185,18 @@ func (t *freezerTable) Sync() error { err = e } } - trackError(t.index.Sync()) - trackError(t.meta.Sync()) trackError(t.head.Sync()) + + // A crash may occur before the offset is updated, leaving the offset + // points to a old position. If so, the extra items above the offset + // will be truncated during the next run. + stat, err := t.index.Stat() + if err != nil { + return err + } + offset := stat.Size() + trackError(t.metadata.setFlushOffset(offset, true)) return err } @@ -1097,13 +1212,8 @@ func (t *freezerTable) dumpIndexString(start, stop int64) string { } func (t *freezerTable) dumpIndex(w io.Writer, start, stop int64) { - meta, err := readMetadata(t.meta) - if err != nil { - fmt.Fprintf(w, "Failed to decode freezer table %v\n", err) - return - } - fmt.Fprintf(w, "Version %d count %d, deleted %d, hidden %d\n", meta.Version, - t.items.Load(), t.itemOffset.Load(), t.itemHidden.Load()) + fmt.Fprintf(w, "Version %d count %d, deleted %d, hidden %d\n", + t.metadata.version, t.items.Load(), t.itemOffset.Load(), t.itemHidden.Load()) buf := make([]byte, indexEntrySize) diff --git a/core/rawdb/freezer_table_test.go b/core/rawdb/freezer_table_test.go index fd6e3cf199..9a72af6ccc 100644 --- a/core/rawdb/freezer_table_test.go +++ b/core/rawdb/freezer_table_test.go @@ -262,18 +262,6 @@ func TestSnappyDetection(t *testing.T) { f.Close() } - // Open without snappy - { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, false, false) - if err != nil { - t.Fatal(err) - } - if _, err = f.Retrieve(0); err == nil { - f.Close() - t.Fatalf("expected empty table") - } - } - // Open with snappy { f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) @@ -286,6 +274,18 @@ func TestSnappyDetection(t *testing.T) { t.Fatalf("expected no error, got %v", err) } } + + // Open without snappy + { + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, false, false) + if err != nil { + t.Fatal(err) + } + if _, err = f.Retrieve(0); err == nil { + f.Close() + t.Fatalf("expected empty table") + } + } } func assertFileSize(f string, size int64) error { @@ -521,93 +521,53 @@ func TestFreezerOffset(t *testing.T) { fname := fmt.Sprintf("offset-%d", rand.Uint64()) // Fill table - { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) - if err != nil { - t.Fatal(err) - } - - // Write 6 x 20 bytes, splitting out into three files - batch := f.newBatch() - require.NoError(t, batch.AppendRaw(0, getChunk(20, 0xFF))) - require.NoError(t, batch.AppendRaw(1, getChunk(20, 0xEE))) - - require.NoError(t, batch.AppendRaw(2, getChunk(20, 0xdd))) - require.NoError(t, batch.AppendRaw(3, getChunk(20, 0xcc))) - - require.NoError(t, batch.AppendRaw(4, getChunk(20, 0xbb))) - require.NoError(t, batch.AppendRaw(5, getChunk(20, 0xaa))) - require.NoError(t, batch.commit()) - - t.Log(f.dumpIndexString(0, 100)) - f.Close() + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + if err != nil { + t.Fatal(err) } + // Write 6 x 20 bytes, splitting out into three files + batch := f.newBatch() + require.NoError(t, batch.AppendRaw(0, getChunk(20, 0xFF))) + require.NoError(t, batch.AppendRaw(1, getChunk(20, 0xEE))) + + require.NoError(t, batch.AppendRaw(2, getChunk(20, 0xdd))) + require.NoError(t, batch.AppendRaw(3, getChunk(20, 0xcc))) + + require.NoError(t, batch.AppendRaw(4, getChunk(20, 0xbb))) + require.NoError(t, batch.AppendRaw(5, getChunk(20, 0xaa))) + require.NoError(t, batch.commit()) + + t.Log(f.dumpIndexString(0, 100)) + // Now crop it. - { - // delete files 0 and 1 - for i := 0; i < 2; i++ { - p := filepath.Join(os.TempDir(), fmt.Sprintf("%v.%04d.rdat", fname, i)) - if err := os.Remove(p); err != nil { - t.Fatal(err) - } - } - // Read the index file - p := filepath.Join(os.TempDir(), fmt.Sprintf("%v.ridx", fname)) - indexFile, err := os.OpenFile(p, os.O_RDWR, 0644) - if err != nil { - t.Fatal(err) - } - indexBuf := make([]byte, 7*indexEntrySize) - indexFile.Read(indexBuf) - - // Update the index file, so that we store - // [ file = 2, offset = 4 ] at index zero - - zeroIndex := indexEntry{ - filenum: uint32(2), // First file is 2 - offset: uint32(4), // We have removed four items - } - buf := zeroIndex.append(nil) - - // Overwrite index zero - copy(indexBuf, buf) - - // Remove the four next indices by overwriting - copy(indexBuf[indexEntrySize:], indexBuf[indexEntrySize*5:]) - indexFile.WriteAt(indexBuf, 0) - - // Need to truncate the moved index items - indexFile.Truncate(indexEntrySize * (1 + 2)) - indexFile.Close() - } + f.truncateTail(4) + f.Close() // Now open again - { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) - if err != nil { - t.Fatal(err) - } - defer f.Close() - t.Log(f.dumpIndexString(0, 100)) - - // It should allow writing item 6. - batch := f.newBatch() - require.NoError(t, batch.AppendRaw(6, getChunk(20, 0x99))) - require.NoError(t, batch.commit()) - - checkRetrieveError(t, f, map[uint64]error{ - 0: errOutOfBounds, - 1: errOutOfBounds, - 2: errOutOfBounds, - 3: errOutOfBounds, - }) - checkRetrieve(t, f, map[uint64][]byte{ - 4: getChunk(20, 0xbb), - 5: getChunk(20, 0xaa), - 6: getChunk(20, 0x99), - }) + f, err = newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + if err != nil { + t.Fatal(err) } + t.Log(f.dumpIndexString(0, 100)) + + // It should allow writing item 6. + batch = f.newBatch() + require.NoError(t, batch.AppendRaw(6, getChunk(20, 0x99))) + require.NoError(t, batch.commit()) + + checkRetrieveError(t, f, map[uint64]error{ + 0: errOutOfBounds, + 1: errOutOfBounds, + 2: errOutOfBounds, + 3: errOutOfBounds, + }) + checkRetrieve(t, f, map[uint64][]byte{ + 4: getChunk(20, 0xbb), + 5: getChunk(20, 0xaa), + 6: getChunk(20, 0x99), + }) + f.Close() // Edit the index again, with a much larger initial offset of 1M. { @@ -1369,45 +1329,63 @@ func TestRandom(t *testing.T) { } func TestIndexValidation(t *testing.T) { - const ( - items = 30 - dataSize = 10 - ) + const dataSize = 10 + garbage := indexEntry{ filenum: 100, offset: 200, } var cases = []struct { - offset int64 - data []byte - expItems int + write int + offset int64 + data []byte + expItems int + hasCorruption bool }{ // extend index file with zero bytes at the end { - offset: (items + 1) * indexEntrySize, + write: 5, + offset: (5 + 1) * indexEntrySize, data: make([]byte, indexEntrySize), - expItems: 30, + expItems: 5, + }, + // extend index file with unaligned zero bytes at the end + { + write: 5, + offset: (5 + 1) * indexEntrySize, + data: make([]byte, indexEntrySize*1.5), + expItems: 5, }, // write garbage in the first non-head item { + write: 5, offset: indexEntrySize, data: garbage.append(nil), expItems: 0, }, - // write garbage in the first non-head item + // write garbage in the middle { - offset: (items/2 + 1) * indexEntrySize, + write: 5, + offset: 3 * indexEntrySize, data: garbage.append(nil), - expItems: items / 2, + expItems: 2, + }, + // fulfill the first data file (but not yet advanced), the zero bytes + // at tail should be truncated. + { + write: 10, + offset: 11 * indexEntrySize, + data: garbage.append(nil), + expItems: 10, }, } for _, c := range cases { fn := fmt.Sprintf("t-%d", rand.Uint64()) - f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 100, true, false) + f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 10*dataSize, true, false) if err != nil { t.Fatal(err) } - writeChunks(t, f, items, dataSize) + writeChunks(t, f, c.write, dataSize) // write corrupted data f.index.WriteAt(c.data, c.offset) @@ -1421,10 +1399,10 @@ func TestIndexValidation(t *testing.T) { for i := 0; i < c.expItems; i++ { exp := getChunk(10, i) got, err := f.Retrieve(uint64(i)) - if err != nil { + if err != nil && !c.hasCorruption { t.Fatalf("Failed to read from table, %v", err) } - if !bytes.Equal(exp, got) { + if !bytes.Equal(exp, got) && !c.hasCorruption { t.Fatalf("Unexpected item data, want: %v, got: %v", exp, got) } } @@ -1433,3 +1411,163 @@ func TestIndexValidation(t *testing.T) { } } } + +// TestFlushOffsetTracking tests the flush offset tracking. The offset moving +// in the test is mostly triggered by the advanceHead (new data file) and +// heda/tail truncation. +func TestFlushOffsetTracking(t *testing.T) { + const ( + items = 35 + dataSize = 10 + fileSize = 100 + ) + fn := fmt.Sprintf("t-%d", rand.Uint64()) + f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, true, false) + if err != nil { + t.Fatal(err) + } + // Data files: + // F1(10 items) -> F2(10 items) -> F3(10 items) -> F4(5 items, non-full) + writeChunks(t, f, items, dataSize) + + var cases = []struct { + op func(*freezerTable) + offset int64 + }{ + { + // Data files: + // F1(10 items) -> F2(10 items) -> F3(10 items) -> F4(5 items, non-full) + func(f *freezerTable) {}, // no-op + 31 * indexEntrySize, + }, + { + // Write more items to fulfill the newest data file, but the file advance + // is not triggered. + + // Data files: + // F1(10 items) -> F2(10 items) -> F3(10 items) -> F4(10 items, full) + func(f *freezerTable) { + batch := f.newBatch() + for i := 0; i < 5; i++ { + batch.AppendRaw(items+uint64(i), make([]byte, dataSize)) + } + batch.commit() + }, + 31 * indexEntrySize, + }, + { + // Write more items to trigger the data file advance + + // Data files: + // F1(10 items) -> F2(10 items) -> F3(10 items) -> F4(10 items) -> F5(1 item) + func(f *freezerTable) { + batch := f.newBatch() + batch.AppendRaw(items+5, make([]byte, dataSize)) + batch.commit() + }, + 41 * indexEntrySize, + }, + { + // Head truncate + + // Data files: + // F1(10 items) -> F2(10 items) -> F3(10 items) -> F4(10 items) -> F5(0 item) + func(f *freezerTable) { + f.truncateHead(items + 5) + }, + 41 * indexEntrySize, + }, + { + // Tail truncate + + // Data files: + // F1(1 hidden, 9 visible) -> F2(10 items) -> F3(10 items) -> F4(10 items) -> F5(0 item) + func(f *freezerTable) { + f.truncateTail(1) + }, + 41 * indexEntrySize, + }, + { + // Tail truncate + + // Data files: + // F2(10 items) -> F3(10 items) -> F4(10 items) -> F5(0 item) + func(f *freezerTable) { + f.truncateTail(10) + }, + 31 * indexEntrySize, + }, + { + // Tail truncate + + // Data files: + // F4(10 items) -> F5(0 item) + func(f *freezerTable) { + f.truncateTail(30) + }, + 11 * indexEntrySize, + }, + { + // Head truncate + + // Data files: + // F4(9 items) + func(f *freezerTable) { + f.truncateHead(items + 4) + }, + 10 * indexEntrySize, + }, + } + for _, c := range cases { + c.op(f) + if f.metadata.flushOffset != c.offset { + t.Fatalf("Unexpected index flush offset, want: %d, got: %d", c.offset, f.metadata.flushOffset) + } + } +} + +func TestTailTruncationCrash(t *testing.T) { + const ( + items = 35 + dataSize = 10 + fileSize = 100 + ) + fn := fmt.Sprintf("t-%d", rand.Uint64()) + f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, true, false) + if err != nil { + t.Fatal(err) + } + // Data files: + // F1(10 items) -> F2(10 items) -> F3(10 items) -> F4(5 items, non-full) + writeChunks(t, f, items, dataSize) + + // The latest 5 items are not persisted yet + if f.metadata.flushOffset != 31*indexEntrySize { + t.Fatalf("Unexpected index flush offset, want: %d, got: %d", 31*indexEntrySize, f.metadata.flushOffset) + } + + f.truncateTail(5) + if f.metadata.flushOffset != 31*indexEntrySize { + t.Fatalf("Unexpected index flush offset, want: %d, got: %d", 31*indexEntrySize, f.metadata.flushOffset) + } + + // Truncate the first 10 items which results in the first data file + // being removed. The offset should be moved to 26*indexEntrySize. + f.truncateTail(10) + if f.metadata.flushOffset != 26*indexEntrySize { + t.Fatalf("Unexpected index flush offset, want: %d, got: %d", 26*indexEntrySize, f.metadata.flushOffset) + } + + // Write the offset back to 31*indexEntrySize to simulate a crash + // which occurs after truncating the index file without updating + // the offset + f.metadata.setFlushOffset(31*indexEntrySize, true) + + f, err = newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, true, false) + if err != nil { + t.Fatal(err) + } + if f.metadata.flushOffset != 26*indexEntrySize { + t.Fatalf("Unexpected index flush offset, want: %d, got: %d", 26*indexEntrySize, f.metadata.flushOffset) + } +} From 665c8512f388bd79053dce81b3920f65eb617289 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 4 Feb 2025 14:22:30 +0100 Subject: [PATCH 090/940] core: copy genesis before modifying (#31097) This PR fixes a data race in SetupGenesisWithOverride. --- core/genesis.go | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/core/genesis.go b/core/genesis.go index b579e33c77..d1ee1b6e92 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -75,6 +75,19 @@ type Genesis struct { BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844 } +// copy copies the genesis. +func (g *Genesis) copy() *Genesis { + if g != nil { + cpy := *g + if g.Config != nil { + conf := *g.Config + cpy.Config = &conf + } + return &cpy + } + return nil +} + func ReadGenesis(db ethdb.Database) (*Genesis, error) { var genesis Genesis stored := rawdb.ReadCanonicalHash(db, 0) @@ -248,21 +261,17 @@ type ChainOverrides struct { } // apply applies the chain overrides on the supplied chain config. -func (o *ChainOverrides) apply(cfg *params.ChainConfig) (*params.ChainConfig, error) { +func (o *ChainOverrides) apply(cfg *params.ChainConfig) error { if o == nil || cfg == nil { - return cfg, nil + return nil } - cpy := *cfg if o.OverrideCancun != nil { - cpy.CancunTime = o.OverrideCancun + cfg.CancunTime = o.OverrideCancun } if o.OverrideVerkle != nil { - cpy.VerkleTime = o.OverrideVerkle + cfg.VerkleTime = o.OverrideVerkle } - if err := cpy.CheckConfigForkOrder(); err != nil { - return nil, err - } - return &cpy, nil + return cfg.CheckConfigForkOrder() } // SetupGenesisBlock writes or updates the genesis block in db. @@ -281,6 +290,8 @@ func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Gene } func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { + // Copy the genesis, so we can operate on a copy. + genesis = genesis.copy() // Sanitize the supplied genesis, ensuring it has the associated chain // config attached. if genesis != nil && genesis.Config == nil { @@ -295,17 +306,15 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g } else { log.Info("Writing custom genesis block") } - chainCfg, err := overrides.apply(genesis.Config) - if err != nil { + if err := overrides.apply(genesis.Config); err != nil { return nil, common.Hash{}, nil, err } - genesis.Config = chainCfg block, err := genesis.Commit(db, triedb) if err != nil { return nil, common.Hash{}, nil, err } - return chainCfg, block.Hash(), nil, nil + return genesis.Config, block.Hash(), nil, nil } // Commit the genesis if the genesis block exists in the ancient database // but the key-value database is empty without initializing the genesis @@ -322,11 +331,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g } else { log.Info("Writing custom genesis block") } - chainCfg, err := overrides.apply(genesis.Config) - if err != nil { + if err := overrides.apply(genesis.Config); err != nil { return nil, common.Hash{}, nil, err } - genesis.Config = chainCfg if hash := genesis.ToBlock().Hash(); hash != ghash { return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} @@ -335,17 +342,15 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g if err != nil { return nil, common.Hash{}, nil, err } - return chainCfg, block.Hash(), nil, nil + return genesis.Config, block.Hash(), nil, nil } // The genesis block has already been committed previously. Verify that the // provided genesis with chain overrides matches the existing one, and update // the stored chain config if necessary. if genesis != nil { - chainCfg, err := overrides.apply(genesis.Config) - if err != nil { + if err := overrides.apply(genesis.Config); err != nil { return nil, common.Hash{}, nil, err } - genesis.Config = chainCfg if hash := genesis.ToBlock().Hash(); hash != ghash { return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} From eee868226a3d4504994fa176ea7c866b5d8f9d18 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 4 Feb 2025 15:29:51 +0100 Subject: [PATCH 091/940] params: start osaka fork (#31125) This PR defines the Osaka fork. An easy first step to start our work on the next hardfork (This is needed for EOF testing as well) --------- Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> --- core/genesis_test.go | 1 + core/vm/jump_table_export.go | 4 +++- eth/tracers/api.go | 4 ++++ params/config.go | 23 ++++++++++++++++++- params/forks/forks.go | 1 + tests/init.go | 44 ++++++++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 2 deletions(-) diff --git a/core/genesis_test.go b/core/genesis_test.go index 4e7662d14c..714dc4d6b3 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -272,6 +272,7 @@ func TestVerkleGenesisCommit(t *testing.T) { ShanghaiTime: &verkleTime, CancunTime: &verkleTime, PragueTime: &verkleTime, + OsakaTime: &verkleTime, VerkleTime: &verkleTime, TerminalTotalDifficulty: big.NewInt(0), EnableVerkleAtGenesis: true, diff --git a/core/vm/jump_table_export.go b/core/vm/jump_table_export.go index b74109da0a..b8fa6049bb 100644 --- a/core/vm/jump_table_export.go +++ b/core/vm/jump_table_export.go @@ -28,8 +28,10 @@ func LookupInstructionSet(rules params.Rules) (JumpTable, error) { switch { case rules.IsVerkle: return newCancunInstructionSet(), errors.New("verkle-fork not defined yet") + case rules.IsOsaka: + return newPragueInstructionSet(), errors.New("osaka-fork not defined yet") case rules.IsPrague: - return newCancunInstructionSet(), errors.New("prague-fork not defined yet") + return newPragueInstructionSet(), nil case rules.IsCancun: return newCancunInstructionSet(), nil case rules.IsShanghai: diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 22163030de..d13aee555f 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -1088,6 +1088,10 @@ func overrideConfig(original *params.ChainConfig, override *params.ChainConfig) copy.PragueTime = timestamp canon = false } + if timestamp := override.OsakaTime; timestamp != nil { + copy.OsakaTime = timestamp + canon = false + } if timestamp := override.VerkleTime; timestamp != nil { copy.VerkleTime = timestamp canon = false diff --git a/params/config.go b/params/config.go index f1e139608c..9269cb2310 100644 --- a/params/config.go +++ b/params/config.go @@ -133,6 +133,7 @@ var ( ShanghaiTime: nil, CancunTime: nil, PragueTime: nil, + OsakaTime: nil, VerkleTime: nil, Ethash: new(EthashConfig), Clique: nil, @@ -182,6 +183,7 @@ var ( ShanghaiTime: nil, CancunTime: nil, PragueTime: nil, + OsakaTime: nil, VerkleTime: nil, TerminalTotalDifficulty: big.NewInt(math.MaxInt64), Ethash: nil, @@ -211,6 +213,7 @@ var ( ShanghaiTime: nil, CancunTime: nil, PragueTime: nil, + OsakaTime: nil, VerkleTime: nil, TerminalTotalDifficulty: big.NewInt(math.MaxInt64), Ethash: new(EthashConfig), @@ -240,6 +243,7 @@ var ( ShanghaiTime: newUint64(0), CancunTime: newUint64(0), PragueTime: newUint64(0), + OsakaTime: nil, VerkleTime: nil, TerminalTotalDifficulty: big.NewInt(0), Ethash: new(EthashConfig), @@ -269,6 +273,7 @@ var ( ShanghaiTime: nil, CancunTime: nil, PragueTime: nil, + OsakaTime: nil, VerkleTime: nil, TerminalTotalDifficulty: big.NewInt(math.MaxInt64), Ethash: new(EthashConfig), @@ -318,6 +323,7 @@ type ChainConfig struct { ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) + OsakaTime *uint64 `json:"osakaTime,omitempty"` // Osaka switch time (nil = no fork, 0 = already on osaka) VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle) // TerminalTotalDifficulty is the amount of total difficulty reached by @@ -432,6 +438,9 @@ func (c *ChainConfig) Description() string { if c.PragueTime != nil { banner += fmt.Sprintf(" - Prague: @%-10v\n", *c.PragueTime) } + if c.OsakaTime != nil { + banner += fmt.Sprintf(" - Osaka: @%-10v\n", *c.OsakaTime) + } if c.VerkleTime != nil { banner += fmt.Sprintf(" - Verkle: @%-10v\n", *c.VerkleTime) } @@ -533,6 +542,11 @@ func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.PragueTime, time) } +// IsOsaka returns whether time is either equal to the Osaka fork time or greater. +func (c *ChainConfig) IsOsaka(num *big.Int, time uint64) bool { + return c.IsLondon(num) && isTimestampForked(c.OsakaTime, time) +} + // 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) @@ -611,6 +625,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "shanghaiTime", timestamp: c.ShanghaiTime}, {name: "cancunTime", timestamp: c.CancunTime, optional: true}, {name: "pragueTime", timestamp: c.PragueTime, optional: true}, + {name: "osakaTime", timestamp: c.OsakaTime, optional: true}, {name: "verkleTime", timestamp: c.VerkleTime, optional: true}, } { if lastFork.name != "" { @@ -715,6 +730,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp) { return newTimestampCompatError("Prague fork timestamp", c.PragueTime, newcfg.PragueTime) } + if isForkTimestampIncompatible(c.OsakaTime, newcfg.OsakaTime, headTimestamp) { + return newTimestampCompatError("Osaka fork timestamp", c.OsakaTime, newcfg.OsakaTime) + } if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) { return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime) } @@ -737,6 +755,8 @@ func (c *ChainConfig) LatestFork(time uint64) forks.Fork { london := c.LondonBlock switch { + case c.IsOsaka(london, time): + return forks.Osaka case c.IsPrague(london, time): return forks.Prague case c.IsCancun(london, time): @@ -888,7 +908,7 @@ type Rules struct { IsEIP2929, IsEIP4762 bool IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool - IsMerge, IsShanghai, IsCancun, IsPrague bool + IsMerge, IsShanghai, IsCancun, IsPrague, IsOsaka bool IsVerkle bool } @@ -918,6 +938,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsShanghai: isMerge && c.IsShanghai(num, timestamp), IsCancun: isMerge && c.IsCancun(num, timestamp), IsPrague: isMerge && c.IsPrague(num, timestamp), + IsOsaka: isMerge && c.IsOsaka(num, timestamp), IsVerkle: isVerkle, IsEIP4762: isVerkle, } diff --git a/params/forks/forks.go b/params/forks/forks.go index 4f50ff5aed..2d44e13b04 100644 --- a/params/forks/forks.go +++ b/params/forks/forks.go @@ -39,4 +39,5 @@ const ( Shanghai Cancun Prague + Osaka ) diff --git a/tests/init.go b/tests/init.go index 4bb83f9300..8429f38e44 100644 --- a/tests/init.go +++ b/tests/init.go @@ -396,6 +396,50 @@ var Forks = map[string]*params.ChainConfig{ PragueTime: u64(15_000), DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, }, + "Osaka": { + 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), + OsakaTime: u64(0), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + }, + "PragueToOsakaAtTime15k": { + 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), + OsakaTime: u64(15_000), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + }, } // AvailableForks returns the set of defined fork names From e6f3ce7b168b8f346de621a8f60d2fa57c2ebfb0 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Tue, 4 Feb 2025 07:43:18 -0700 Subject: [PATCH 092/940] params,core: add max and target value to chain config (#31002) Implements [EIP-7840](https://github.com/ethereum/EIPs/pull/9129) and [EIP-7691](https://github.com/ethereum/EIPs/blob/d96625a4dcbbe2572fa006f062bd02b4582eefd5/EIPS/eip-7691.md). --------- Co-authored-by: Marius van der Wijden Co-authored-by: Felix Lange --- cmd/devp2p/internal/ethtest/suite.go | 2 +- .../internal/ethtest/testdata/genesis.json | 11 +- cmd/evm/internal/t8ntool/execution.go | 22 ++- consensus/beacon/consensus.go | 2 +- consensus/misc/eip4844/eip4844.go | 110 +++++++++--- consensus/misc/eip4844/eip4844_test.go | 38 +++-- core/blockchain.go | 5 +- core/chain_makers.go | 18 +- core/chain_makers_test.go | 6 +- core/evm.go | 6 +- core/genesis_test.go | 5 + core/rawdb/accessors_chain.go | 2 +- core/state_processor_test.go | 27 +-- core/txpool/blobpool/blobpool.go | 22 +-- core/txpool/blobpool/blobpool_test.go | 158 +++++++++++++++++- core/txpool/blobpool/evictheap_test.go | 34 ++-- core/txpool/blobpool/limbo.go | 4 +- core/txpool/blobpool/priority_test.go | 6 +- core/txpool/blobpool/slotter.go | 4 +- core/txpool/blobpool/slotter_test.go | 2 +- core/txpool/validation.go | 6 +- core/verkle_witness_test.go | 8 +- core/vm/runtime/runtime_test.go | 4 + eth/api_backend.go | 2 +- eth/catalyst/api_test.go | 3 + eth/fetcher/tx_fetcher_test.go | 6 +- eth/gasprice/feehistory.go | 10 +- eth/gasprice/gasprice_test.go | 1 + eth/tracers/internal/tracetest/supply_test.go | 1 + .../testdata/call_tracer/blob_tx.json | 9 +- .../testdata/prestate_tracer/blob_tx.json | 13 +- .../testdata/prestate_tracer/setcode_tx.json | 14 +- eth/tracers/internal/tracetest/util.go | 6 +- eth/tracers/live/supply.go | 26 +-- ethclient/ethclient_test.go | 9 +- internal/ethapi/api.go | 5 + internal/ethapi/simulate.go | 8 +- internal/ethapi/transaction_args.go | 22 +-- internal/ethapi/transaction_args_test.go | 1 + miner/worker.go | 29 ++-- params/config.go | 96 ++++++++++- params/protocol_params.go | 4 - tests/init.go | 14 ++ tests/state_test.go | 2 +- tests/state_test_util.go | 34 +++- 45 files changed, 613 insertions(+), 204 deletions(-) diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go index 12dc5711ac..2f1731b60c 100644 --- a/cmd/devp2p/internal/ethtest/suite.go +++ b/cmd/devp2p/internal/ethtest/suite.go @@ -743,7 +743,7 @@ func (s *Suite) makeBlobTxs(count, blobs int, discriminator byte) (txs types.Tra GasTipCap: uint256.NewInt(1), GasFeeCap: uint256.MustFromBig(s.chain.Head().BaseFee()), Gas: 100000, - BlobFeeCap: uint256.MustFromBig(eip4844.CalcBlobFee(*s.chain.Head().ExcessBlobGas())), + BlobFeeCap: uint256.MustFromBig(eip4844.CalcBlobFee(s.chain.config, s.chain.Head().Header())), BlobHashes: makeSidecar(blobdata...).BlobHashes(), Sidecar: makeSidecar(blobdata...), } diff --git a/cmd/devp2p/internal/ethtest/testdata/genesis.json b/cmd/devp2p/internal/ethtest/testdata/genesis.json index 4cfebdcac1..ace2f78815 100644 --- a/cmd/devp2p/internal/ethtest/testdata/genesis.json +++ b/cmd/devp2p/internal/ethtest/testdata/genesis.json @@ -18,7 +18,14 @@ "shanghaiTime": 780, "cancunTime": 840, "terminalTotalDifficulty": 9454784, - "ethash": {} + "ethash": {}, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 3338477 + } + } }, "nonce": "0x0", "timestamp": "0x0", @@ -108,4 +115,4 @@ "baseFeePerGas": null, "excessBlobGas": null, "blobGasUsed": null -} \ No newline at end of file +} diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 9ff5a05290..9332f4901b 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -178,15 +178,28 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, var excessBlobGas uint64 if pre.Env.ExcessBlobGas != nil { excessBlobGas = *pre.Env.ExcessBlobGas - vmContext.BlobBaseFee = eip4844.CalcBlobFee(excessBlobGas) + header := &types.Header{ + Time: pre.Env.Timestamp, + ExcessBlobGas: pre.Env.ExcessBlobGas, + } + vmContext.BlobBaseFee = eip4844.CalcBlobFee(chainConfig, header) } else { // If it is not explicitly defined, but we have the parent values, we try // to calculate it ourselves. parentExcessBlobGas := pre.Env.ParentExcessBlobGas parentBlobGasUsed := pre.Env.ParentBlobGasUsed if parentExcessBlobGas != nil && parentBlobGasUsed != nil { - excessBlobGas = eip4844.CalcExcessBlobGas(*parentExcessBlobGas, *parentBlobGasUsed) - vmContext.BlobBaseFee = eip4844.CalcBlobFee(excessBlobGas) + parent := &types.Header{ + Time: pre.Env.ParentTimestamp, + ExcessBlobGas: pre.Env.ParentExcessBlobGas, + BlobGasUsed: pre.Env.ParentBlobGasUsed, + } + excessBlobGas = eip4844.CalcExcessBlobGas(chainConfig, parent) + header := &types.Header{ + Time: pre.Env.Timestamp, + ExcessBlobGas: &excessBlobGas, + } + vmContext.BlobBaseFee = eip4844.CalcBlobFee(chainConfig, header) } } // If DAO is supported/enabled, we need to handle it here. In geth 'proper', it's @@ -229,7 +242,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, txBlobGas := uint64(0) if tx.Type() == types.BlobTxType { txBlobGas = uint64(params.BlobTxBlobGasPerBlob * len(tx.BlobHashes())) - if used, max := blobGasUsed+txBlobGas, uint64(params.MaxBlobGasPerBlock); used > max { + max := eip4844.MaxBlobGasPerBlock(chainConfig, pre.Env.Timestamp) + if used := blobGasUsed + txBlobGas; used > max { err := fmt.Errorf("blob gas (%d) would exceed maximum allowance %d", used, max) log.Warn("rejected tx", "index", i, "err", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 20df6d0091..bdfddfff06 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -282,7 +282,7 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa if header.ParentBeaconRoot == nil { return errors.New("header is missing beaconRoot") } - if err := eip4844.VerifyEIP4844Header(parent, header); err != nil { + if err := eip4844.VerifyEIP4844Header(chain.Config(), parent, header); err != nil { return err } } diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index 2dad9a0cd3..1d76b21b30 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -23,17 +23,17 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/params/forks" ) var ( - minBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice) - blobGaspriceUpdateFraction = big.NewInt(params.BlobTxBlobGaspriceUpdateFraction) + minBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice) ) // VerifyEIP4844Header verifies the presence of the excessBlobGas field and that // if the current block contains no transactions, the excessBlobGas is updated // accordingly. -func VerifyEIP4844Header(parent, header *types.Header) error { +func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Header) error { // Verify the header is not malformed if header.ExcessBlobGas == nil { return errors.New("header is missing excessBlobGas") @@ -42,14 +42,26 @@ func VerifyEIP4844Header(parent, header *types.Header) error { return errors.New("header is missing blobGasUsed") } // Verify that the blob gas used remains within reasonable limits. - if *header.BlobGasUsed > params.MaxBlobGasPerBlock { - return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", *header.BlobGasUsed, params.MaxBlobGasPerBlock) + maxBlobGas := MaxBlobGasPerBlock(config, header.Time) + if *header.BlobGasUsed > maxBlobGas { + return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", *header.BlobGasUsed, maxBlobGas) } if *header.BlobGasUsed%params.BlobTxBlobGasPerBlob != 0 { return fmt.Errorf("blob gas used %d not a multiple of blob gas per blob %d", header.BlobGasUsed, params.BlobTxBlobGasPerBlob) } // Verify the excessBlobGas is correct based on the parent header + expectedExcessBlobGas := CalcExcessBlobGas(config, parent) + if *header.ExcessBlobGas != expectedExcessBlobGas { + return fmt.Errorf("invalid excessBlobGas: have %d, want %d", *header.ExcessBlobGas, expectedExcessBlobGas) + } + return nil +} + +// CalcExcessBlobGas calculates the excess blob gas after applying the set of +// blobs on top of the excess blob gas. +func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header) uint64 { var ( + targetGas = uint64(targetBlobsPerBlock(config, parent.Time)) * params.BlobTxBlobGasPerBlob parentExcessBlobGas uint64 parentBlobGasUsed uint64 ) @@ -57,27 +69,85 @@ func VerifyEIP4844Header(parent, header *types.Header) error { parentExcessBlobGas = *parent.ExcessBlobGas parentBlobGasUsed = *parent.BlobGasUsed } - expectedExcessBlobGas := CalcExcessBlobGas(parentExcessBlobGas, parentBlobGasUsed) - if *header.ExcessBlobGas != expectedExcessBlobGas { - return fmt.Errorf("invalid excessBlobGas: have %d, want %d, parent excessBlobGas %d, parent blobDataUsed %d", - *header.ExcessBlobGas, expectedExcessBlobGas, parentExcessBlobGas, parentBlobGasUsed) - } - return nil -} - -// CalcExcessBlobGas calculates the excess blob gas after applying the set of -// blobs on top of the excess blob gas. -func CalcExcessBlobGas(parentExcessBlobGas uint64, parentBlobGasUsed uint64) uint64 { excessBlobGas := parentExcessBlobGas + parentBlobGasUsed - if excessBlobGas < params.BlobTxTargetBlobGasPerBlock { + if excessBlobGas < targetGas { return 0 } - return excessBlobGas - params.BlobTxTargetBlobGasPerBlock + return excessBlobGas - targetGas } // CalcBlobFee calculates the blobfee from the header's excess blob gas field. -func CalcBlobFee(excessBlobGas uint64) *big.Int { - return fakeExponential(minBlobGasPrice, new(big.Int).SetUint64(excessBlobGas), blobGaspriceUpdateFraction) +func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int { + var frac uint64 + switch config.LatestFork(header.Time) { + case forks.Prague: + frac = config.BlobScheduleConfig.Prague.UpdateFraction + case forks.Cancun: + frac = config.BlobScheduleConfig.Cancun.UpdateFraction + default: + panic("calculating blob fee on unsupported fork") + } + return fakeExponential(minBlobGasPrice, new(big.Int).SetUint64(*header.ExcessBlobGas), new(big.Int).SetUint64(frac)) +} + +// MaxBlobsPerBlock returns the max blobs per block for a block at the given timestamp. +func MaxBlobsPerBlock(cfg *params.ChainConfig, time uint64) int { + if cfg.BlobScheduleConfig == nil { + return 0 + } + var ( + london = cfg.LondonBlock + s = cfg.BlobScheduleConfig + ) + switch { + case cfg.IsPrague(london, time) && s.Prague != nil: + return s.Prague.Max + case cfg.IsCancun(london, time) && s.Cancun != nil: + return s.Cancun.Max + default: + return 0 + } +} + +// MaxBlobsPerBlock returns the maximum blob gas that can be spent in a block at the given timestamp. +func MaxBlobGasPerBlock(cfg *params.ChainConfig, time uint64) uint64 { + return uint64(MaxBlobsPerBlock(cfg, time)) * params.BlobTxBlobGasPerBlob +} + +// LatestMaxBlobsPerBlock returns the latest max blobs per block defined by the +// configuration, regardless of the currently active fork. +func LatestMaxBlobsPerBlock(cfg *params.ChainConfig) int { + s := cfg.BlobScheduleConfig + if s == nil { + return 0 + } + switch { + case s.Prague != nil: + return s.Prague.Max + case s.Cancun != nil: + return s.Cancun.Max + default: + return 0 + } +} + +// targetBlobsPerBlock returns the target number of blobs in a block at the given timestamp. +func targetBlobsPerBlock(cfg *params.ChainConfig, time uint64) int { + if cfg.BlobScheduleConfig == nil { + return 0 + } + var ( + london = cfg.LondonBlock + s = cfg.BlobScheduleConfig + ) + switch { + case cfg.IsPrague(london, time) && s.Prague != nil: + return s.Prague.Target + case cfg.IsCancun(london, time) && s.Cancun != nil: + return s.Cancun.Target + default: + return 0 + } } // fakeExponential approximates factor * e ** (numerator / denominator) using diff --git a/consensus/misc/eip4844/eip4844_test.go b/consensus/misc/eip4844/eip4844_test.go index ec417380fc..839ea8df22 100644 --- a/consensus/misc/eip4844/eip4844_test.go +++ b/consensus/misc/eip4844/eip4844_test.go @@ -21,36 +21,48 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" ) func TestCalcExcessBlobGas(t *testing.T) { + var ( + config = params.MainnetChainConfig + targetBlobs = targetBlobsPerBlock(config, *config.CancunTime) + targetBlobGas = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob + ) var tests = []struct { excess uint64 - blobs uint64 + blobs int want uint64 }{ // The excess blob gas should not increase from zero if the used blob // slots are below - or equal - to the target. {0, 0, 0}, {0, 1, 0}, - {0, params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob, 0}, + {0, targetBlobs, 0}, // If the target blob gas is exceeded, the excessBlobGas should increase // by however much it was overshot - {0, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 1, params.BlobTxBlobGasPerBlob}, - {1, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 1, params.BlobTxBlobGasPerBlob + 1}, - {1, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 2, 2*params.BlobTxBlobGasPerBlob + 1}, + {0, targetBlobs + 1, params.BlobTxBlobGasPerBlob}, + {1, targetBlobs + 1, params.BlobTxBlobGasPerBlob + 1}, + {1, targetBlobs + 2, 2*params.BlobTxBlobGasPerBlob + 1}, // The excess blob gas should decrease by however much the target was // under-shot, capped at zero. - {params.BlobTxTargetBlobGasPerBlock, params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob, params.BlobTxTargetBlobGasPerBlock}, - {params.BlobTxTargetBlobGasPerBlock, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 1, params.BlobTxTargetBlobGasPerBlock - params.BlobTxBlobGasPerBlob}, - {params.BlobTxTargetBlobGasPerBlock, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 2, params.BlobTxTargetBlobGasPerBlock - (2 * params.BlobTxBlobGasPerBlob)}, - {params.BlobTxBlobGasPerBlob - 1, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 1, 0}, + {targetBlobGas, targetBlobs, targetBlobGas}, + {targetBlobGas, targetBlobs - 1, targetBlobGas - params.BlobTxBlobGasPerBlob}, + {targetBlobGas, targetBlobs - 2, targetBlobGas - (2 * params.BlobTxBlobGasPerBlob)}, + {params.BlobTxBlobGasPerBlob - 1, targetBlobs - 1, 0}, } for i, tt := range tests { - result := CalcExcessBlobGas(tt.excess, tt.blobs*params.BlobTxBlobGasPerBlob) + blobGasUsed := uint64(tt.blobs) * params.BlobTxBlobGasPerBlob + parent := &types.Header{ + Time: *config.CancunTime, + ExcessBlobGas: &tt.excess, + BlobGasUsed: &blobGasUsed, + } + result := CalcExcessBlobGas(config, parent) if result != tt.want { t.Errorf("test %d: excess blob gas mismatch: have %v, want %v", i, result, tt.want) } @@ -58,6 +70,8 @@ func TestCalcExcessBlobGas(t *testing.T) { } func TestCalcBlobFee(t *testing.T) { + zero := uint64(0) + tests := []struct { excessBlobGas uint64 blobfee int64 @@ -68,7 +82,9 @@ func TestCalcBlobFee(t *testing.T) { {10 * 1024 * 1024, 23}, } for i, tt := range tests { - have := CalcBlobFee(tt.excessBlobGas) + config := ¶ms.ChainConfig{LondonBlock: big.NewInt(0), CancunTime: &zero, BlobScheduleConfig: params.DefaultBlobSchedule} + header := &types.Header{ExcessBlobGas: &tt.excessBlobGas} + have := CalcBlobFee(config, header) if have.Int64() != tt.blobfee { t.Errorf("test %d: blobfee mismatch: have %v want %v", i, have, tt.blobfee) } diff --git a/core/blockchain.go b/core/blockchain.go index f097dc9781..b98c2d43aa 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2139,9 +2139,8 @@ func (bc *BlockChain) recoverAncestors(block *types.Block, makeWitness bool) (co // processing of a block. These logs are later announced as deleted or reborn. func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log { var blobGasPrice *big.Int - excessBlobGas := b.ExcessBlobGas() - if excessBlobGas != nil { - blobGasPrice = eip4844.CalcBlobFee(*excessBlobGas) + if b.ExcessBlobGas() != nil { + blobGasPrice = eip4844.CalcBlobFee(bc.chainConfig, b.Header()) } receipts := rawdb.ReadRawReceipts(bc.db, b.Hash(), b.NumberU64()) if err := receipts.DeriveFields(bc.chainConfig, b.Hash(), b.NumberU64(), b.Time(), b.BaseFee(), blobGasPrice, b.Transactions()); err != nil { diff --git a/core/chain_makers.go b/core/chain_makers.go index 1f48f9d128..19f433d7b0 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -143,7 +143,9 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti // instruction will panic during execution if it attempts to access a block number outside // of the range created by GenerateChain. func (b *BlockGen) AddTx(tx *types.Transaction) { - b.addTx(nil, vm.Config{}, tx) + // Wrap the chain config in an empty BlockChain object to satisfy ChainContext. + bc := &BlockChain{chainConfig: b.cm.config} + b.addTx(bc, vm.Config{}, tx) } // AddTxWithChain adds a transaction to the generated block. If no coinbase has @@ -445,7 +447,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse } var blobGasPrice *big.Int if block.ExcessBlobGas() != nil { - blobGasPrice = eip4844.CalcBlobFee(*block.ExcessBlobGas()) + blobGasPrice = eip4844.CalcBlobFee(cm.config, block.Header()) } if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, txs); err != nil { panic(err) @@ -548,7 +550,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine } var blobGasPrice *big.Int if block.ExcessBlobGas() != nil { - blobGasPrice = eip4844.CalcBlobFee(*block.ExcessBlobGas()) + blobGasPrice = eip4844.CalcBlobFee(cm.config, block.Header()) } if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, txs); err != nil { panic(err) @@ -598,15 +600,7 @@ func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engi } } if cm.config.IsCancun(header.Number, header.Time) { - var ( - parentExcessBlobGas uint64 - parentBlobGasUsed uint64 - ) - if parent.ExcessBlobGas() != nil { - parentExcessBlobGas = *parent.ExcessBlobGas() - parentBlobGasUsed = *parent.BlobGasUsed() - } - excessBlobGas := eip4844.CalcExcessBlobGas(parentExcessBlobGas, parentBlobGasUsed) + excessBlobGas := eip4844.CalcExcessBlobGas(cm.config, parent.Header()) header.ExcessBlobGas = &excessBlobGas header.BlobGasUsed = new(uint64) header.ParentBeaconRoot = new(common.Hash) diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index cb1087b4b3..d81a52e915 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -42,7 +42,7 @@ func TestGeneratePOSChain(t *testing.T) { aa = common.Address{0xaa} bb = common.Address{0xbb} funds = big.NewInt(0).Mul(big.NewInt(1337), big.NewInt(params.Ether)) - config = *params.AllEthashProtocolChanges + config = *params.MergedTestChainConfig gspec = &Genesis{ Config: &config, Alloc: types.GenesisAlloc{ @@ -57,10 +57,6 @@ func TestGeneratePOSChain(t *testing.T) { db = rawdb.NewMemoryDatabase() ) - config.TerminalTotalDifficulty = common.Big0 - config.ShanghaiTime = u64(0) - config.CancunTime = u64(0) - // init 0xaa with some storage elements storage := make(map[common.Hash]common.Hash) storage[common.Hash{0x00}] = common.Hash{0x00} diff --git a/core/evm.go b/core/evm.go index 5d3c454d7c..41b4e6ac58 100644 --- a/core/evm.go +++ b/core/evm.go @@ -25,6 +25,7 @@ import ( "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" "github.com/holiman/uint256" ) @@ -36,6 +37,9 @@ type ChainContext interface { // GetHeader returns the header corresponding to the hash/number argument pair. GetHeader(common.Hash, uint64) *types.Header + + // Config returns the chain's configuration. + Config() *params.ChainConfig } // NewEVMBlockContext creates a new context for use in the EVM. @@ -57,7 +61,7 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common baseFee = new(big.Int).Set(header.BaseFee) } if header.ExcessBlobGas != nil { - blobBaseFee = eip4844.CalcBlobFee(*header.ExcessBlobGas) + blobBaseFee = eip4844.CalcBlobFee(chain.Config(), header) } if header.Difficulty.Sign() == 0 { random = &header.MixDigest diff --git a/core/genesis_test.go b/core/genesis_test.go index 714dc4d6b3..3e120a9307 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -278,6 +278,11 @@ func TestVerkleGenesisCommit(t *testing.T) { EnableVerkleAtGenesis: true, Ethash: nil, Clique: nil, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Verkle: params.DefaultPragueBlobConfig, + }, } genesis := &Genesis{ diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index a586046d5f..1a2b31b360 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -587,7 +587,7 @@ func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64, // Compute effective blob gas price. var blobGasPrice *big.Int if header != nil && header.ExcessBlobGas != nil { - blobGasPrice = eip4844.CalcBlobFee(*header.ExcessBlobGas) + blobGasPrice = eip4844.CalcBlobFee(config, header) } if err := receipts.DeriveFields(config, hash, number, time, baseFee, blobGasPrice, body.Transactions); err != nil { log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 750f3708dc..7d62e90ad4 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -46,25 +46,7 @@ func u64(val uint64) *uint64 { return &val } // contain invalid transactions func TestStateProcessorErrors(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), - TerminalTotalDifficulty: big.NewInt(0), - ShanghaiTime: new(uint64), - CancunTime: new(uint64), - PragueTime: new(uint64), - } + config = params.MergedTestChainConfig signer = types.LatestSigner(config) key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") key2, _ = crypto.HexToECDSA("0202020202020202020202020202020202020202020202020202002020202020") @@ -425,12 +407,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr } header.Root = common.BytesToHash(hasher.Sum(nil)) if config.IsCancun(header.Number, header.Time) { - var pExcess, pUsed = uint64(0), uint64(0) - if parent.ExcessBlobGas() != nil { - pExcess = *parent.ExcessBlobGas() - pUsed = *parent.BlobGasUsed() - } - excess := eip4844.CalcExcessBlobGas(pExcess, pUsed) + excess := eip4844.CalcExcessBlobGas(config, parent.Header()) used := uint64(nBlobs * params.BlobTxBlobGasPerBlob) header.ExcessBlobGas = &excess header.BlobGasUsed = &used diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 4ab14bbcc0..78cf2c05af 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -51,11 +51,6 @@ const ( // transaction. There can be multiple of these embedded into a single tx. blobSize = params.BlobTxFieldElementsPerBlob * params.BlobTxBytesPerFieldElement - // maxBlobsPerTransaction is the maximum number of blobs a single transaction - // is allowed to contain. Whilst the spec states it's unlimited, the block - // data slots are protocol bound, which implicitly also limit this. - maxBlobsPerTransaction = params.MaxBlobGasPerBlock / params.BlobTxBlobGasPerBlob - // txAvgSize is an approximate byte size of a transaction metadata to avoid // tiny overflows causing all txs to move a shelf higher, wasting disk space. txAvgSize = 4 * 1024 @@ -223,6 +218,11 @@ func newBlobTxMeta(id uint64, size uint32, tx *types.Transaction) *blobTxMeta { // very relaxed ones can be included even if the fees go up, when the closer // ones could already be invalid. // +// - Because the maximum number of blobs allowed in a block can change per +// fork, the pool is designed to handle the maximum number of blobs allowed +// in the chain's latest defined fork -- even if it isn't active. This +// avoids needing to upgrade the database around the fork boundary. +// // When the pool eventually reaches saturation, some old transactions - that may // never execute - will need to be evicted in favor of newer ones. The eviction // strategy is quite complex: @@ -387,7 +387,8 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres fails = append(fails, id) } } - store, err := billy.Open(billy.Options{Path: queuedir, Repair: true}, newSlotter(), index) + slotter := newSlotter(eip4844.LatestMaxBlobsPerBlock(p.chain.Config())) + store, err := billy.Open(billy.Options{Path: queuedir, Repair: true}, slotter, index) if err != nil { return err } @@ -414,13 +415,13 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres blobfee = uint256.NewInt(params.BlobTxMinBlobGasprice) ) if p.head.ExcessBlobGas != nil { - blobfee = uint256.MustFromBig(eip4844.CalcBlobFee(*p.head.ExcessBlobGas)) + blobfee = uint256.MustFromBig(eip4844.CalcBlobFee(p.chain.Config(), p.head)) } p.evict = newPriceHeap(basefee, blobfee, p.index) // Pool initialized, attach the blob limbo to it to track blobs included // recently but not yet finalized - p.limbo, err = newLimbo(limbodir) + p.limbo, err = newLimbo(limbodir, eip4844.LatestMaxBlobsPerBlock(p.chain.Config())) if err != nil { p.Close() return err @@ -834,7 +835,7 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) { blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinBlobGasprice)) ) if newHead.ExcessBlobGas != nil { - blobfee = uint256.MustFromBig(eip4844.CalcBlobFee(*newHead.ExcessBlobGas)) + blobfee = uint256.MustFromBig(eip4844.CalcBlobFee(p.chain.Config(), newHead)) } p.evict.reinit(basefee, blobfee, false) @@ -1598,7 +1599,8 @@ func (p *BlobPool) updateStorageMetrics() { metrics.GetOrRegisterGauge(fmt.Sprintf(shelfSlotusedGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.FilledSlots)) metrics.GetOrRegisterGauge(fmt.Sprintf(shelfSlotgapsGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.GappedSlots)) - if shelf.SlotSize/blobSize > maxBlobsPerTransaction { + maxBlobs := eip4844.LatestMaxBlobsPerBlock(p.chain.Config()) + if shelf.SlotSize/blobSize > uint32(maxBlobs) { oversizedDataused += slotDataused oversizedDatagaps += slotDatagaps oversizedSlotused += shelf.FilledSlots diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 3d90ec4412..0187e8d9a0 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -51,8 +51,10 @@ var ( testBlobVHashes [][32]byte ) +const testMaxBlobsPerBlock = 6 + func init() { - for i := 0; i < 10; i++ { + for i := 0; i < 24; i++ { testBlob := &kzg4844.Blob{byte(i)} testBlobs = append(testBlobs, testBlob) @@ -121,7 +123,12 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { mid := new(big.Int).Add(lo, hi) mid.Div(mid, big.NewInt(2)) - if eip4844.CalcBlobFee(mid.Uint64()).Cmp(bc.blobfee.ToBig()) > 0 { + tmp := mid.Uint64() + if eip4844.CalcBlobFee(bc.Config(), &types.Header{ + Number: blockNumber, + Time: blockTime, + ExcessBlobGas: &tmp, + }).Cmp(bc.blobfee.ToBig()) > 0 { hi = mid } else { lo = mid @@ -194,10 +201,43 @@ func makeTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64, return types.MustSignNewTx(key, types.LatestSigner(params.MainnetChainConfig), blobtx) } +// makeMultiBlobTx is a utility method to construct a ramdom blob tx with +// certain number of blobs in its sidecar. +func makeMultiBlobTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64, blobCount int, key *ecdsa.PrivateKey) *types.Transaction { + var ( + blobs []kzg4844.Blob + blobHashes []common.Hash + commitments []kzg4844.Commitment + proofs []kzg4844.Proof + ) + for i := 0; i < blobCount; i++ { + blobs = append(blobs, *testBlobs[i]) + commitments = append(commitments, testBlobCommits[i]) + proofs = append(proofs, testBlobProofs[i]) + blobHashes = append(blobHashes, testBlobVHashes[i]) + } + blobtx := &types.BlobTx{ + ChainID: uint256.MustFromBig(params.MainnetChainConfig.ChainID), + Nonce: nonce, + GasTipCap: uint256.NewInt(gasTipCap), + GasFeeCap: uint256.NewInt(gasFeeCap), + Gas: 21000, + BlobFeeCap: uint256.NewInt(blobFeeCap), + BlobHashes: blobHashes, + Value: uint256.NewInt(100), + Sidecar: &types.BlobTxSidecar{ + Blobs: blobs, + Commitments: commitments, + Proofs: proofs, + }, + } + 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 makeUnsignedTxWithTestBlob(nonce, gasTipCap, gasFeeCap, blobFeeCap, rand.Intn(len(testBlobs))) + return makeUnsignedTxWithTestBlob(nonce, gasTipCap, gasFeeCap, blobFeeCap, rnd.Intn(len(testBlobs))) } // makeUnsignedTx is a utility method to construct a random blob transaction @@ -415,7 +455,7 @@ func TestOpenDrops(t *testing.T) { defer os.RemoveAll(storage) os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) - store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil) + store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) // Insert a malformed transaction to verify that decoding errors (or format // changes) are handled gracefully (case 1) @@ -738,7 +778,7 @@ func TestOpenIndex(t *testing.T) { defer os.RemoveAll(storage) os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) - store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil) + store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) // Insert a sequence of transactions with varying price points to check that // the cumulative minimum will be maintained. @@ -827,7 +867,7 @@ func TestOpenHeap(t *testing.T) { defer os.RemoveAll(storage) os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) - store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil) + store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) // Insert a few transactions from a few accounts. To remove randomness from // the heap initialization, use a deterministic account/tx/priority ordering. @@ -914,7 +954,7 @@ func TestOpenCap(t *testing.T) { defer os.RemoveAll(storage) os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) - store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil) + store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) // Insert a few transactions from a few accounts var ( @@ -992,6 +1032,108 @@ func TestOpenCap(t *testing.T) { } } +// TestChangingSlotterSize attempts to mimic a scenario where the max blob count +// of the pool is increased. This would happen during a client release where a +// new fork is added with a max blob count higher than the previous fork. We +// want to make sure transactions a persisted between those runs. +func TestChangingSlotterSize(t *testing.T) { + //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) + + // Create a temporary folder for the persistent backend + storage, _ := os.MkdirTemp("", "blobpool-") + defer os.RemoveAll(storage) + + os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) + store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(6), nil) + + // Create transactions from a few accounts. + var ( + key1, _ = crypto.GenerateKey() + key2, _ = crypto.GenerateKey() + key3, _ = crypto.GenerateKey() + + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + addr3 = crypto.PubkeyToAddress(key3.PublicKey) + + tx1 = makeMultiBlobTx(0, 1, 1000, 100, 6, key1) + tx2 = makeMultiBlobTx(0, 1, 800, 70, 6, key2) + tx3 = makeMultiBlobTx(0, 1, 800, 110, 24, key3) + + blob1, _ = rlp.EncodeToBytes(tx1) + blob2, _ = rlp.EncodeToBytes(tx2) + ) + + // Write the two safely sized txs to store. note: although the store is + // configured for a blob count of 6, it can also support around ~1mb of call + // data - all this to say that we aren't using the the absolute largest shelf + // available. + store.Put(blob1) + store.Put(blob2) + store.Close() + + // Mimic a blobpool with max blob count of 6 upgrading to a max blob count of 24. + for _, maxBlobs := range []int{6, 24} { + 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.Commit(0, true, false) + + // Make custom chain config where the max blob count changes based on the loop variable. + cancunTime := uint64(0) + config := ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + LondonBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + CancunTime: &cancunTime, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: ¶ms.BlobConfig{ + Target: maxBlobs / 2, + Max: maxBlobs, + UpdateFraction: params.DefaultCancunBlobConfig.UpdateFraction, + }, + }, + } + chain := &testBlockChain{ + config: config, + basefee: uint256.NewInt(1050), + blobfee: uint256.NewInt(105), + statedb: statedb, + } + pool := New(Config{Datadir: storage}, chain) + if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil { + t.Fatalf("failed to create blob pool: %v", err) + } + + // Try to add the big blob tx. In the initial iteration it should overflow + // the pool. On the subsequent iteration it should be accepted. + errs := pool.Add([]*types.Transaction{tx3}, false, true) + if _, ok := pool.index[addr3]; ok && maxBlobs == 6 { + t.Errorf("expected insert of oversized blob tx to fail: blobs=24, maxBlobs=%d, err=%v", maxBlobs, errs[0]) + } else if !ok && maxBlobs == 10 { + t.Errorf("expected insert of oversized blob tx to succeed: blobs=24, maxBlobs=%d, err=%v", maxBlobs, errs[0]) + } + + // Verify the regular two txs are always available. + if got := pool.Get(tx1.Hash()); got == nil { + t.Errorf("expected tx %s from %s in pool", tx1.Hash(), addr1) + } + if got := pool.Get(tx2.Hash()); got == nil { + t.Errorf("expected tx %s from %s in pool", tx2.Hash(), addr2) + } + + // Verify all the calculated pool internals. Interestingly, this is **not** + // a duplication of the above checks, this actually validates the verifier + // using the above already hard coded checks. + // + // Do not remove this, nor alter the above to be generic. + verifyPoolInternals(t, pool) + + pool.Close() + } +} + // Tests that adding transaction will correctly store it in the persistent store // and update all the indices. // @@ -1369,7 +1511,7 @@ func TestAdd(t *testing.T) { defer os.RemoveAll(storage) // late defer, still ok os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) - store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil) + store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) // Insert the seed transactions for the pool startup var ( diff --git a/core/txpool/blobpool/evictheap_test.go b/core/txpool/blobpool/evictheap_test.go index b03dd83d69..e392932401 100644 --- a/core/txpool/blobpool/evictheap_test.go +++ b/core/txpool/blobpool/evictheap_test.go @@ -26,7 +26,7 @@ import ( "github.com/holiman/uint256" ) -var rand = mrand.New(mrand.NewSource(1)) +var rnd = mrand.New(mrand.NewSource(1)) // verifyHeapInternals verifies that all accounts present in the index are also // present in the heap and internals are consistent across various indices. @@ -193,12 +193,12 @@ func benchmarkPriceHeapReinit(b *testing.B, datacap uint64) { index := make(map[common.Address][]*blobTxMeta) for i := 0; i < int(blobs); i++ { var addr common.Address - rand.Read(addr[:]) + rnd.Read(addr[:]) var ( - execTip = uint256.NewInt(rand.Uint64()) - execFee = uint256.NewInt(rand.Uint64()) - blobFee = uint256.NewInt(rand.Uint64()) + execTip = uint256.NewInt(rnd.Uint64()) + execFee = uint256.NewInt(rnd.Uint64()) + blobFee = uint256.NewInt(rnd.Uint64()) basefeeJumps = dynamicFeeJumps(execFee) blobfeeJumps = dynamicFeeJumps(blobFee) @@ -218,13 +218,13 @@ 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(rnd.Uint64()), uint256.NewInt(rnd.Uint64()), index) basefees := make([]*uint256.Int, b.N) blobfees := make([]*uint256.Int, b.N) for i := 0; i < b.N; i++ { - basefees[i] = uint256.NewInt(rand.Uint64()) - blobfees[i] = uint256.NewInt(rand.Uint64()) + basefees[i] = uint256.NewInt(rnd.Uint64()) + blobfees[i] = uint256.NewInt(rnd.Uint64()) } b.ResetTimer() b.ReportAllocs() @@ -269,12 +269,12 @@ func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) { index := make(map[common.Address][]*blobTxMeta) for i := 0; i < int(blobs); i++ { var addr common.Address - rand.Read(addr[:]) + rnd.Read(addr[:]) var ( - execTip = uint256.NewInt(rand.Uint64()) - execFee = uint256.NewInt(rand.Uint64()) - blobFee = uint256.NewInt(rand.Uint64()) + execTip = uint256.NewInt(rnd.Uint64()) + execFee = uint256.NewInt(rnd.Uint64()) + blobFee = uint256.NewInt(rnd.Uint64()) basefeeJumps = dynamicFeeJumps(execFee) blobfeeJumps = dynamicFeeJumps(blobFee) @@ -294,18 +294,18 @@ 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(rnd.Uint64()), uint256.NewInt(rnd.Uint64()), index) var ( addrs = make([]common.Address, b.N) metas = make([]*blobTxMeta, b.N) ) for i := 0; i < b.N; i++ { - rand.Read(addrs[i][:]) + rnd.Read(addrs[i][:]) var ( - execTip = uint256.NewInt(rand.Uint64()) - execFee = uint256.NewInt(rand.Uint64()) - blobFee = uint256.NewInt(rand.Uint64()) + execTip = uint256.NewInt(rnd.Uint64()) + execFee = uint256.NewInt(rnd.Uint64()) + blobFee = uint256.NewInt(rnd.Uint64()) basefeeJumps = dynamicFeeJumps(execFee) blobfeeJumps = dynamicFeeJumps(blobFee) diff --git a/core/txpool/blobpool/limbo.go b/core/txpool/blobpool/limbo.go index 32381a3936..d5992f2906 100644 --- a/core/txpool/blobpool/limbo.go +++ b/core/txpool/blobpool/limbo.go @@ -48,7 +48,7 @@ type limbo struct { } // newLimbo opens and indexes a set of limboed blob transactions. -func newLimbo(datadir string) (*limbo, error) { +func newLimbo(datadir string, maxBlobsPerTransaction int) (*limbo, error) { l := &limbo{ index: make(map[common.Hash]uint64), groups: make(map[uint64]map[uint64]common.Hash), @@ -60,7 +60,7 @@ func newLimbo(datadir string) (*limbo, error) { fails = append(fails, id) } } - store, err := billy.Open(billy.Options{Path: datadir, Repair: true}, newSlotter(), index) + store, err := billy.Open(billy.Options{Path: datadir, Repair: true}, newSlotter(maxBlobsPerTransaction), index) if err != nil { return nil, err } diff --git a/core/txpool/blobpool/priority_test.go b/core/txpool/blobpool/priority_test.go index cf0e0454a0..1eaee6d7df 100644 --- a/core/txpool/blobpool/priority_test.go +++ b/core/txpool/blobpool/priority_test.go @@ -52,7 +52,7 @@ func TestPriorityCalculation(t *testing.T) { func BenchmarkDynamicFeeJumpCalculation(b *testing.B) { fees := make([]*uint256.Int, b.N) for i := 0; i < b.N; i++ { - fees[i] = uint256.NewInt(rand.Uint64()) + fees[i] = uint256.NewInt(rnd.Uint64()) } b.ResetTimer() b.ReportAllocs() @@ -76,8 +76,8 @@ func BenchmarkPriorityCalculation(b *testing.B) { txBasefeeJumps := make([]float64, b.N) txBlobfeeJumps := make([]float64, b.N) for i := 0; i < b.N; i++ { - txBasefeeJumps[i] = dynamicFeeJumps(uint256.NewInt(rand.Uint64())) - txBlobfeeJumps[i] = dynamicFeeJumps(uint256.NewInt(rand.Uint64())) + txBasefeeJumps[i] = dynamicFeeJumps(uint256.NewInt(rnd.Uint64())) + txBlobfeeJumps[i] = dynamicFeeJumps(uint256.NewInt(rnd.Uint64())) } b.ResetTimer() b.ReportAllocs() diff --git a/core/txpool/blobpool/slotter.go b/core/txpool/blobpool/slotter.go index 35349c3445..84ccc0f27b 100644 --- a/core/txpool/blobpool/slotter.go +++ b/core/txpool/blobpool/slotter.go @@ -25,13 +25,13 @@ package blobpool // The slotter also creates a shelf for 0-blob transactions. Whilst those are not // allowed in the current protocol, having an empty shelf is not a relevant use // of resources, but it makes stress testing with junk transactions simpler. -func newSlotter() func() (uint32, bool) { +func newSlotter(maxBlobsPerTransaction int) func() (uint32, bool) { slotsize := uint32(txAvgSize) slotsize -= uint32(blobSize) // underflows, it's ok, will overflow back in the first return return func() (size uint32, done bool) { slotsize += blobSize - finished := slotsize > maxBlobsPerTransaction*blobSize+txMaxSize + finished := slotsize > uint32(maxBlobsPerTransaction)*blobSize+txMaxSize return slotsize, finished } diff --git a/core/txpool/blobpool/slotter_test.go b/core/txpool/blobpool/slotter_test.go index a7b43b4d22..8d46f47d2c 100644 --- a/core/txpool/blobpool/slotter_test.go +++ b/core/txpool/blobpool/slotter_test.go @@ -21,7 +21,7 @@ import "testing" // Tests that the slotter creates the expected database shelves. func TestNewSlotter(t *testing.T) { // Generate the database shelve sizes - slotter := newSlotter() + slotter := newSlotter(6) var shelves []uint32 for { diff --git a/core/txpool/validation.go b/core/txpool/validation.go index dec711b173..8cd13776a6 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -23,6 +23,7 @@ import ( "math/big" "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/state" "github.com/ethereum/go-ethereum/core/types" @@ -144,8 +145,9 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types if len(hashes) == 0 { return errors.New("blobless blob transaction") } - if len(hashes) > params.MaxBlobGasPerBlock/params.BlobTxBlobGasPerBlob { - return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), params.MaxBlobGasPerBlock/params.BlobTxBlobGasPerBlob) + maxBlobs := eip4844.MaxBlobsPerBlock(opts.Config, head.Time) + if len(hashes) > maxBlobs { + return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), maxBlobs) } // Ensure commitments, proofs and hashes are valid if err := validateBlobSidecar(hashes, sidecar); err != nil { diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go index 500fb37156..4e873eedff 100644 --- a/core/verkle_witness_test.go +++ b/core/verkle_witness_test.go @@ -58,6 +58,9 @@ var ( VerkleTime: u64(0), TerminalTotalDifficulty: common.Big0, EnableVerkleAtGenesis: true, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Verkle: params.DefaultPragueBlobConfig, + }, // TODO uncomment when proof generation is merged // ProofInBlocks: true, } @@ -79,6 +82,9 @@ var ( VerkleTime: u64(0), TerminalTotalDifficulty: common.Big0, EnableVerkleAtGenesis: true, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Verkle: params.DefaultPragueBlobConfig, + }, } ) @@ -226,11 +232,11 @@ func TestProcessParentBlockHash(t *testing.T) { var num = 2 for i := 1; i <= num; i++ { header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)} - vmContext := NewEVMBlockContext(header, nil, new(common.Address)) chainConfig := params.MergedTestChainConfig if isVerkle { chainConfig = testVerkleChainConfig } + vmContext := NewEVMBlockContext(header, nil, new(common.Address)) evm := vm.NewEVM(vmContext, statedb, chainConfig, vm.Config{}) ProcessParentBlockHash(header.ParentHash, evm) } diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 6074e9a096..44f5bc8273 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -314,6 +314,10 @@ func (d *dummyChain) GetHeader(h common.Hash, n uint64) *types.Header { return fakeHeader(n, parentHash) } +func (d *dummyChain) Config() *params.ChainConfig { + return nil +} + // TestBlockhash tests the blockhash operation. It's a bit special, since it internally // requires access to a chain reader. func TestBlockhash(t *testing.T) { diff --git a/eth/api_backend.go b/eth/api_backend.go index 90439e8eab..52ecd91789 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -356,7 +356,7 @@ func (b *EthAPIBackend) FeeHistory(ctx context.Context, blockCount uint64, lastB func (b *EthAPIBackend) BlobBaseFee(ctx context.Context) *big.Int { if excess := b.CurrentHeader().ExcessBlobGas; excess != nil { - return eip4844.CalcBlobFee(*excess) + return eip4844.CalcBlobFee(b.ChainConfig(), b.CurrentHeader()) } return nil } diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index 407f0db3eb..9840d9c6ad 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -1227,6 +1227,7 @@ func setupBodies(t *testing.T) (*node.Node, *eth.Ethereum, []*types.Block) { genesis.Config.ShanghaiTime = &time genesis.Config.CancunTime = &time genesis.Config.PragueTime = &time + genesis.Config.BlobScheduleConfig = params.DefaultBlobSchedule n, ethservice := startEthService(t, genesis, blocks) @@ -1543,6 +1544,7 @@ func TestParentBeaconBlockRoot(t *testing.T) { time := blocks[len(blocks)-1].Time() + 5 genesis.Config.ShanghaiTime = &time genesis.Config.CancunTime = &time + genesis.Config.BlobScheduleConfig = params.DefaultBlobSchedule n, ethservice := startEthService(t, genesis, blocks) defer n.Close() @@ -1625,6 +1627,7 @@ func TestWitnessCreationAndConsumption(t *testing.T) { timestamp := blocks[len(blocks)-2].Time() + 5 genesis.Config.ShanghaiTime = ×tamp genesis.Config.CancunTime = ×tamp + genesis.Config.BlobScheduleConfig = params.DefaultBlobSchedule n, ethservice := startEthService(t, genesis, blocks[:9]) defer n.Close() diff --git a/eth/fetcher/tx_fetcher_test.go b/eth/fetcher/tx_fetcher_test.go index f80b1d6096..52b3591086 100644 --- a/eth/fetcher/tx_fetcher_test.go +++ b/eth/fetcher/tx_fetcher_test.go @@ -1108,7 +1108,7 @@ func TestTransactionFetcherBandwidthLimiting(t *testing.T) { doTxNotify{peer: "C", hashes: []common.Hash{{0x07}, {0x08}}, types: []byte{types.BlobTxType, types.BlobTxType}, - sizes: []uint32{params.MaxBlobGasPerBlock, params.MaxBlobGasPerBlock}, + sizes: []uint32{params.BlobTxBlobGasPerBlob * 10, params.BlobTxBlobGasPerBlob * 10}, }, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), @@ -1125,8 +1125,8 @@ func TestTransactionFetcherBandwidthLimiting(t *testing.T) { {common.Hash{0x06}, types.LegacyTxType, maxTxRetrievalSize}, }, "C": { - {common.Hash{0x07}, types.BlobTxType, params.MaxBlobGasPerBlock}, - {common.Hash{0x08}, types.BlobTxType, params.MaxBlobGasPerBlock}, + {common.Hash{0x07}, types.BlobTxType, params.BlobTxBlobGasPerBlob * 10}, + {common.Hash{0x08}, types.BlobTxType, params.BlobTxBlobGasPerBlob * 10}, }, }, fetching: map[string][]common.Hash{ diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 1e625e21c0..697263f20b 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -31,7 +31,6 @@ import ( "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" ) @@ -97,8 +96,10 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { } // 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)) + bf.results.blobBaseFee = eip4844.CalcBlobFee(config, bf.header) + excess := eip4844.CalcExcessBlobGas(config, bf.header) + next := &types.Header{Number: bf.header.Number, Time: bf.header.Time, ExcessBlobGas: &excess} + bf.results.nextBlobBaseFee = eip4844.CalcBlobFee(config, next) } else { bf.results.blobBaseFee = new(big.Int) bf.results.nextBlobBaseFee = new(big.Int) @@ -106,7 +107,8 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { // 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 + maxBlobs := eip4844.MaxBlobsPerBlock(config, bf.header.Time) + bf.results.blobGasUsedRatio = float64(*blobGasUsed) / float64(maxBlobs) } if len(percentiles) == 0 { diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 185224d834..0a32c278cb 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -157,6 +157,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, cancunBlock *big.Int, pe ts := gspec.Timestamp + cancunBlock.Uint64()*10 // fixed 10 sec block time in blockgen config.ShanghaiTime = &ts config.CancunTime = &ts + config.BlobScheduleConfig = params.DefaultBlobSchedule signer = types.LatestSigner(gspec.Config) } diff --git a/eth/tracers/internal/tracetest/supply_test.go b/eth/tracers/internal/tracetest/supply_test.go index d918f5aca4..dc46b6d5ef 100644 --- a/eth/tracers/internal/tracetest/supply_test.go +++ b/eth/tracers/internal/tracetest/supply_test.go @@ -360,6 +360,7 @@ func TestSupplySelfdestruct(t *testing.T) { cancunTime := uint64(0) gspec.Config.ShanghaiTime = &cancunTime gspec.Config.CancunTime = &cancunTime + gspec.Config.BlobScheduleConfig = params.DefaultBlobSchedule postCancunOutput, postCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) if err != nil { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json b/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json index 05da3b42e1..f8e08532a4 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json @@ -41,7 +41,14 @@ "grayGlacierBlock": 0, "shanghaiTime": 0, "cancunTime": 0, - "terminalTotalDifficulty": 0 + "terminalTotalDifficulty": 0, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 3338477 + } + } } }, "context": { 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 f8adbabf63..9f452ca5bd 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/blob_tx.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/blob_tx.json @@ -41,7 +41,14 @@ "grayGlacierBlock": 0, "shanghaiTime": 0, "cancunTime": 0, - "terminalTotalDifficulty": 0 + "terminalTotalDifficulty": 0, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 3338477 + } + } } }, "context": { @@ -54,7 +61,9 @@ }, "input": "0x03f8b1820539806485174876e800825208940c2c51a0990aee1d73c1228de1586883415575088080c083020000f842a00100c9fbdf97f747e85847b4f3fff408f89c26842f77c882858bf2c89923849aa00138e3896f3c27f2389147507f8bcec52028b0efca6ee842ed83c9158873943880a0dbac3f97a532c9b00e6239b29036245a5bfbb96940b9d848634661abee98b945a03eec8525f261c2e79798f7b45a5d6ccaefa24576d53ba5023e919b86841c0675", "result": { - "0x0000000000000000000000000000000000000000": { "balance": "0x272e0528" }, + "0x0000000000000000000000000000000000000000": { + "balance": "0x272e0528" + }, "0x0c2c51a0990aee1d73c1228de158688341557508": { "balance": "0xde0b6b3a7640000" } diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json index b7d5ee1c54..043130a072 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json @@ -53,7 +53,19 @@ "shanghaiTime": 0, "cancunTime": 0, "pragueTime": 0, - "terminalTotalDifficulty": 0 + "terminalTotalDifficulty": 0, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 3338477 + }, + "prague": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 5007716 + } + } } }, "context": { diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go index abc2699498..e29144e04e 100644 --- a/eth/tracers/internal/tracetest/util.go +++ b/eth/tracers/internal/tracetest/util.go @@ -9,6 +9,7 @@ import ( "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/types" "github.com/ethereum/go-ethereum/core/vm" // Force-load native and js packages, to trigger registration @@ -53,8 +54,9 @@ func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext { } if genesis.ExcessBlobGas != nil && genesis.BlobGasUsed != nil { - excessBlobGas := eip4844.CalcExcessBlobGas(*genesis.ExcessBlobGas, *genesis.BlobGasUsed) - context.BlobBaseFee = eip4844.CalcBlobFee(excessBlobGas) + excess := eip4844.CalcExcessBlobGas(genesis.Config, genesis.ToBlock().Header()) + header := &types.Header{ExcessBlobGas: &excess, Number: genesis.Config.LondonBlock, Time: *genesis.Config.CancunTime} + context.BlobBaseFee = eip4844.CalcBlobFee(genesis.Config, header) } return context } diff --git a/eth/tracers/live/supply.go b/eth/tracers/live/supply.go index fa4e5b1904..bae7445cb4 100644 --- a/eth/tracers/live/supply.go +++ b/eth/tracers/live/supply.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "gopkg.in/natefinch/lumberjack.v2" ) @@ -83,6 +84,7 @@ type supplyTracer struct { delta supplyInfo txCallstack []supplyTxCallstack // Callstack for current transaction logger *lumberjack.Logger + chainConfig *params.ChainConfig } type supplyTracerConfig struct { @@ -112,14 +114,15 @@ func newSupplyTracer(cfg json.RawMessage) (*tracing.Hooks, error) { 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, + OnBlockchainInit: t.onBlockchainInit, + 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 } @@ -146,6 +149,10 @@ func (s *supplyTracer) resetDelta() { s.delta = newSupplyInfo() } +func (s *supplyTracer) onBlockchainInit(chainConfig *params.ChainConfig) { + s.chainConfig = chainConfig +} + func (s *supplyTracer) onBlockStart(ev tracing.BlockEvent) { s.resetDelta() @@ -161,8 +168,7 @@ func (s *supplyTracer) onBlockStart(ev tracing.BlockEvent) { // 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) + baseFee = eip4844.CalcBlobFee(s.chainConfig, ev.Block.Header()) burn = new(big.Int).Mul(new(big.Int).SetUint64(*blobGas), baseFee) ) s.delta.Burn.Blob = burn diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 4ad8a552d2..5fc7ed68f9 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "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/types" @@ -65,7 +66,7 @@ var ( ) var genesis = &core.Genesis{ - Config: params.AllEthashProtocolChanges, + Config: params.AllDevChainProtocolChanges, Alloc: types.GenesisAlloc{ testAddr: {Balance: testBalance}, revertContractAddr: {Code: revertCode}, @@ -136,7 +137,7 @@ func generateTestChain() []*types.Block { g.AddTx(testTx2) } } - _, blocks, _ := core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 2, generate) + _, blocks, _ := core.GenerateChainWithGenesis(genesis, beacon.New(ethash.NewFaker()), 2, generate) return append([]*types.Block{genesis.ToBlock()}, blocks...) } @@ -223,7 +224,7 @@ func testHeader(t *testing.T, chain []*types.Block, client *rpc.Client) { if got != nil && got.Number != nil && got.Number.Sign() == 0 { got.Number = big.NewInt(0) // hack to make DeepEqual work } - if !reflect.DeepEqual(got, tt.want) { + if got.Hash() != tt.want.Hash() { t.Fatalf("HeaderByNumber(%v) got = %v, want %v", tt.block, got, tt.want) } }) @@ -314,7 +315,7 @@ func testChainID(t *testing.T, client *rpc.Client) { if err != nil { t.Fatalf("unexpected error: %v", err) } - if id == nil || id.Cmp(params.AllEthashProtocolChanges.ChainID) != 0 { + if id == nil || id.Cmp(params.AllDevChainProtocolChanges.ChainID) != 0 { t.Fatalf("ChainID returned wrong number: %+v", id) } } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index d9cec560ea..c0b37c516b 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -624,6 +624,7 @@ func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rp type ChainContextBackend interface { Engine() consensus.Engine HeaderByNumber(context.Context, rpc.BlockNumber) (*types.Header, error) + ChainConfig() *params.ChainConfig } // ChainContext is an implementation of core.ChainContext. It's main use-case @@ -652,6 +653,10 @@ func (context *ChainContext) GetHeader(hash common.Hash, number uint64) *types.H return header } +func (context *ChainContext) Config() *params.ChainConfig { + return context.b.ChainConfig() +} + func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) if blockOverrides != nil { diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 130eaa9724..d364b80485 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -159,9 +159,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, 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) + excess = eip4844.CalcExcessBlobGas(sim.chainConfig, parent) } header.ExcessBlobGas = &excess } @@ -415,3 +413,7 @@ func (b *simBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) } return nil, errors.New("header not found") } + +func (b *simBackend) ChainConfig() *params.ChainConfig { + return b.b.ChainConfig() +} diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 175ac13a0f..7a7d63c535 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -37,10 +37,6 @@ import ( "github.com/holiman/uint256" ) -var ( - maxBlobsPerTransaction = params.MaxBlobGasPerBlock / params.BlobTxBlobGasPerBlob -) - // TransactionArgs represents the arguments to construct a new transaction // or a message call. type TransactionArgs struct { @@ -125,8 +121,9 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas if args.BlobHashes != nil && len(args.BlobHashes) == 0 { return errors.New(`need at least 1 blob for a blob transaction`) } - if args.BlobHashes != nil && len(args.BlobHashes) > maxBlobsPerTransaction { - return fmt.Errorf(`too many blobs in transaction (have=%d, max=%d)`, len(args.BlobHashes), maxBlobsPerTransaction) + maxBlobs := eip4844.MaxBlobsPerBlock(b.ChainConfig(), b.CurrentHeader().Time) + if args.BlobHashes != nil && len(args.BlobHashes) > maxBlobs { + return fmt.Errorf(`too many blobs in transaction (have=%d, max=%d)`, len(args.BlobHashes), maxBlobs) } // create check @@ -191,7 +188,9 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend, head if args.BlobFeeCap != nil && args.BlobFeeCap.ToInt().Sign() == 0 { return errors.New("maxFeePerBlobGas, if specified, must be non-zero") } - args.setCancunFeeDefaults(head) + if b.ChainConfig().IsCancun(head.Number, head.Time) { + args.setCancunFeeDefaults(b.ChainConfig(), head) + } // If both gasPrice and at least one of the EIP-1559 fee parameters are specified, error. if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") @@ -243,15 +242,10 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend, head } // setCancunFeeDefaults fills in reasonable default fee values for unspecified fields. -func (args *TransactionArgs) setCancunFeeDefaults(head *types.Header) { +func (args *TransactionArgs) setCancunFeeDefaults(config *params.ChainConfig, head *types.Header) { // Set maxFeePerBlobGas if it is missing. if args.BlobHashes != nil && args.BlobFeeCap == nil { - var excessBlobGas uint64 - if head.ExcessBlobGas != nil { - excessBlobGas = *head.ExcessBlobGas - } - // ExcessBlobGas must be set for a Cancun block. - blobBaseFee := eip4844.CalcBlobFee(excessBlobGas) + blobBaseFee := eip4844.CalcBlobFee(config, head) // Set the max fee to be 2 times larger than the previous block's blob base fee. // The additional slack allows the tx to not become invalidated if the base // fee is rising. diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index 7355c2463c..e017804861 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -279,6 +279,7 @@ func newBackendMock() *backendMock { BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(1000), CancunTime: &cancunTime, + BlobScheduleConfig: params.DefaultBlobSchedule, } return &backendMock{ current: &types.Header{ diff --git a/miner/worker.go b/miner/worker.go index b5aa080025..f8f4bae833 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -210,10 +210,7 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir if miner.chainConfig.IsCancun(header.Number, header.Time) { var excessBlobGas uint64 if miner.chainConfig.IsCancun(parent.Number, parent.Time) { - excessBlobGas = eip4844.CalcExcessBlobGas(*parent.ExcessBlobGas, *parent.BlobGasUsed) - } else { - // For the first post-fork block, both parent.data_gas_used and parent.excess_data_gas are evaluated as 0 - excessBlobGas = eip4844.CalcExcessBlobGas(0, 0) + excessBlobGas = eip4844.CalcExcessBlobGas(miner.chainConfig, parent) } header.BlobGasUsed = new(uint64) header.ExcessBlobGas = &excessBlobGas @@ -284,7 +281,8 @@ func (miner *Miner) commitBlobTransaction(env *environment, tx *types.Transactio // isn't really a better place right now. The blob gas limit is checked at block validation time // and not during execution. This means core.ApplyTransaction will not return an error if the // tx has too many blobs. So we have to explicitly check it here. - if (env.blobs+len(sc.Blobs))*params.BlobTxBlobGasPerBlob > params.MaxBlobGasPerBlock { + maxBlobs := eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time) + if env.blobs+len(sc.Blobs) > maxBlobs { return errors.New("max data blobs reached") } receipt, err := miner.applyTransaction(env, tx) @@ -333,7 +331,7 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran } // If we don't have enough blob space for any further blob transactions, // skip that list altogether - if !blobTxs.Empty() && env.blobs*params.BlobTxBlobGasPerBlob >= params.MaxBlobGasPerBlock { + if !blobTxs.Empty() && env.blobs >= eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time) { log.Trace("Not enough blob space for further blob transactions") blobTxs.Clear() // Fall though to pick up any plain txs @@ -367,11 +365,19 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran txs.Pop() continue } - if left := uint64(params.MaxBlobGasPerBlock - env.blobs*params.BlobTxBlobGasPerBlob); left < ltx.BlobGas { - log.Trace("Not enough blob gas left for transaction", "hash", ltx.Hash, "left", left, "needed", ltx.BlobGas) - txs.Pop() - continue + + // Most of the blob gas logic here is agnostic as to if the chain supports + // blobs or not, however the max check panics when called on a chain without + // a defined schedule, so we need to verify it's safe to call. + if miner.chainConfig.IsCancun(env.header.Number, env.header.Time) { + left := eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time) - env.blobs + if left < int(ltx.BlobGas/params.BlobTxBlobGasPerBlob) { + log.Trace("Not enough blob space left for transaction", "hash", ltx.Hash, "left", left, "needed", ltx.BlobGas/params.BlobTxBlobGasPerBlob) + txs.Pop() + continue + } } + // Transaction seems to fit, pull it up from the pool tx := ltx.Resolve() if tx == nil { @@ -379,6 +385,7 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran txs.Pop() continue } + // Error may be ignored here. The error has already been checked // during transaction acceptance in the transaction pool. from, _ := types.Sender(env.signer, tx) @@ -430,7 +437,7 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment) filter.BaseFee = uint256.MustFromBig(env.header.BaseFee) } if env.header.ExcessBlobGas != nil { - filter.BlobFee = uint256.MustFromBig(eip4844.CalcBlobFee(*env.header.ExcessBlobGas)) + filter.BlobFee = uint256.MustFromBig(eip4844.CalcBlobFee(miner.chainConfig, env.header)) } filter.OnlyPlainTxs, filter.OnlyBlobTxs = true, false pendingPlainTxs := miner.txpool.Pending(filter) diff --git a/params/config.go b/params/config.go index 9269cb2310..0dbe4c509a 100644 --- a/params/config.go +++ b/params/config.go @@ -17,6 +17,7 @@ package params import ( + "errors" "fmt" "math" "math/big" @@ -60,6 +61,9 @@ var ( CancunTime: newUint64(1710338135), DepositContractAddress: common.HexToAddress("0x00000000219ab540356cbb839cbe05303d7705fa"), Ethash: new(EthashConfig), + BlobScheduleConfig: &BlobScheduleConfig{ + Cancun: DefaultCancunBlobConfig, + }, } // HoleskyChainConfig contains the chain parameters to run a node on the Holesky test network. HoleskyChainConfig = &ChainConfig{ @@ -84,6 +88,9 @@ var ( ShanghaiTime: newUint64(1696000704), CancunTime: newUint64(1707305664), Ethash: new(EthashConfig), + BlobScheduleConfig: &BlobScheduleConfig{ + Cancun: DefaultCancunBlobConfig, + }, } // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. SepoliaChainConfig = &ChainConfig{ @@ -108,6 +115,9 @@ var ( ShanghaiTime: newUint64(1677557088), CancunTime: newUint64(1706655072), Ethash: new(EthashConfig), + BlobScheduleConfig: &BlobScheduleConfig{ + Cancun: DefaultCancunBlobConfig, + }, } // AllEthashProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Ethash consensus. @@ -158,6 +168,10 @@ var ( CancunTime: newUint64(0), TerminalTotalDifficulty: big.NewInt(0), PragueTime: newUint64(0), + BlobScheduleConfig: &BlobScheduleConfig{ + Cancun: DefaultCancunBlobConfig, + Prague: DefaultPragueBlobConfig, + }, } // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced @@ -248,6 +262,10 @@ var ( TerminalTotalDifficulty: big.NewInt(0), Ethash: new(EthashConfig), Clique: nil, + BlobScheduleConfig: &BlobScheduleConfig{ + Cancun: DefaultCancunBlobConfig, + Prague: DefaultPragueBlobConfig, + }, } // NonActivatedConfig defines the chain configuration without activating @@ -282,6 +300,26 @@ var ( TestRules = TestChainConfig.Rules(new(big.Int), false, 0) ) +var ( + // DefaultCancunBlobConfig is the default blob configuration for the Cancun fork. + DefaultCancunBlobConfig = &BlobConfig{ + Target: 3, + Max: 6, + UpdateFraction: 3338477, + } + // DefaultPragueBlobConfig is the default blob configuration for the Prague fork. + DefaultPragueBlobConfig = &BlobConfig{ + Target: 6, + Max: 9, + UpdateFraction: 5007716, + } + // DefaultBlobSchedule is the latest configured blob schedule for test chains. + DefaultBlobSchedule = &BlobScheduleConfig{ + Cancun: DefaultCancunBlobConfig, + Prague: DefaultPragueBlobConfig, + } +) + // NetworkNames are user friendly names to use in the chain spec banner. var NetworkNames = map[string]string{ MainnetChainConfig.ChainID.String(): "mainnet", @@ -346,8 +384,9 @@ type ChainConfig struct { EnableVerkleAtGenesis bool `json:"enableVerkleAtGenesis,omitempty"` // Various consensus engines - Ethash *EthashConfig `json:"ethash,omitempty"` - Clique *CliqueConfig `json:"clique,omitempty"` + Ethash *EthashConfig `json:"ethash,omitempty"` + Clique *CliqueConfig `json:"clique,omitempty"` + BlobScheduleConfig *BlobScheduleConfig `json:"blobSchedule,omitempty"` } // EthashConfig is the consensus engine configs for proof-of-work based sealing. @@ -447,6 +486,20 @@ func (c *ChainConfig) Description() string { return banner } +// BlobConfig specifies the target and max blobs per block for the associated fork. +type BlobConfig struct { + Target int `json:"target"` + Max int `json:"max"` + UpdateFraction uint64 `json:"baseFeeUpdateFraction"` +} + +// BlobScheduleConfig determines target and max number of blobs allow per fork. +type BlobScheduleConfig struct { + Cancun *BlobConfig `json:"cancun,omitempty"` + Prague *BlobConfig `json:"prague,omitempty"` + Verkle *BlobConfig `json:"verkle,omitempty"` +} + // IsHomestead returns whether num is either equal to the homestead block or greater. func (c *ChainConfig) IsHomestead(num *big.Int) bool { return isBlockForked(c.HomesteadBlock, num) @@ -662,6 +715,45 @@ func (c *ChainConfig) CheckConfigForkOrder() error { lastFork = cur } } + + // Check that all forks with blobs explicitly define the blob schedule configuration. + bsc := c.BlobScheduleConfig + if bsc == nil { + bsc = new(BlobScheduleConfig) + } + for _, cur := range []struct { + name string + timestamp *uint64 + config *BlobConfig + }{ + {name: "cancun", timestamp: c.CancunTime, config: bsc.Cancun}, + {name: "prague", timestamp: c.PragueTime, config: bsc.Prague}, + } { + if cur.config != nil { + if err := cur.config.validate(); err != nil { + return fmt.Errorf("invalid blob configuration for fork %s: %v", cur.name, err) + } + } + if cur.timestamp != nil { + // If the fork is configured, a blob schedule must be defined for it. + if cur.config == nil { + return fmt.Errorf("unsupported fork configuration: missing blob configuration entry for %v in schedule", cur.name) + } + } + } + return nil +} + +func (bc *BlobConfig) validate() error { + if bc.Max < 0 { + return errors.New("max < 0") + } + if bc.Target < 0 { + return errors.New("target < 0") + } + if bc.UpdateFraction == 0 { + return errors.New("update fraction must be defined and non-zero") + } return nil } diff --git a/params/protocol_params.go b/params/protocol_params.go index c9179634a5..6b06dadaef 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -172,12 +172,8 @@ const ( BlobTxFieldElementsPerBlob = 4096 // Number of field elements stored in a single data blob BlobTxBlobGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size) BlobTxMinBlobGasprice = 1 // Minimum gas price for data blobs - BlobTxBlobGaspriceUpdateFraction = 3338477 // Controls the maximum rate of change for blob gas price BlobTxPointEvaluationPrecompileGas = 50000 // Gas price for the point evaluation precompile. - 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. ) diff --git a/tests/init.go b/tests/init.go index 8429f38e44..ee8d354224 100644 --- a/tests/init.go +++ b/tests/init.go @@ -334,6 +334,9 @@ var Forks = map[string]*params.ChainConfig{ TerminalTotalDifficulty: big.NewInt(0), ShanghaiTime: u64(0), CancunTime: u64(0), + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + }, }, "ShanghaiToCancunAtTime15k": { ChainID: big.NewInt(1), @@ -353,6 +356,9 @@ var Forks = map[string]*params.ChainConfig{ TerminalTotalDifficulty: big.NewInt(0), ShanghaiTime: u64(0), CancunTime: u64(15_000), + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + }, }, "Prague": { ChainID: big.NewInt(1), @@ -374,6 +380,10 @@ var Forks = map[string]*params.ChainConfig{ CancunTime: u64(0), PragueTime: u64(0), DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + }, }, "CancunToPragueAtTime15k": { ChainID: big.NewInt(1), @@ -395,6 +405,10 @@ var Forks = map[string]*params.ChainConfig{ CancunTime: u64(0), PragueTime: u64(15_000), DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + }, }, "Osaka": { ChainID: big.NewInt(1), diff --git a/tests/state_test.go b/tests/state_test.go index da4b8ef79d..0c9553c075 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -303,7 +303,7 @@ func runBenchmark(b *testing.B, t *StateTest) { // Prepare the EVM. txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) + context := core.NewEVMBlockContext(block.Header(), &dummyChain{config: config}, &t.json.Env.Coinbase) context.GetHash = vmTestBlockHash context.BaseFee = baseFee evm := vm.NewEVM(context, state.StateDB, config, vmconfig) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index e658b62ebf..24caf41ed9 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.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/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" @@ -275,13 +276,14 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh return st, common.Hash{}, 0, err } - { // Blob transactions may be present after the Cancun fork. - // In production, - // - the header is verified against the max in eip4844.go:VerifyEIP4844Header - // - the block body is verified against the header in block_validator.go:ValidateBody - // Here, we just do this shortcut smaller fix, since state tests do not - // utilize those codepaths - if len(msg.BlobHashes)*params.BlobTxBlobGasPerBlob > params.MaxBlobGasPerBlock { + // Blob transactions may be present after the Cancun fork. + // In production, + // - the header is verified against the max in eip4844.go:VerifyEIP4844Header + // - the block body is verified against the header in block_validator.go:ValidateBody + // Here, we just do this shortcut smaller fix, since state tests do not + // utilize those codepaths. + if config.IsCancun(new(big.Int), block.Time()) { + if len(msg.BlobHashes) > eip4844.MaxBlobsPerBlock(config, block.Time()) { return st, common.Hash{}, 0, errors.New("blob gas exceeds maximum") } } @@ -299,7 +301,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh } // Prepare the EVM. - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) + context := core.NewEVMBlockContext(block.Header(), &dummyChain{config: config}, &t.json.Env.Coinbase) context.GetHash = vmTestBlockHash context.BaseFee = baseFee context.Random = nil @@ -312,8 +314,13 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh context.Difficulty = big.NewInt(0) } if config.IsCancun(new(big.Int), block.Time()) && t.json.Env.ExcessBlobGas != nil { - context.BlobBaseFee = eip4844.CalcBlobFee(*t.json.Env.ExcessBlobGas) + header := &types.Header{ + Time: block.Time(), + ExcessBlobGas: t.json.Env.ExcessBlobGas, + } + context.BlobBaseFee = eip4844.CalcBlobFee(config, header) } + evm := vm.NewEVM(context, st.StateDB, config, vmconfig) if tracer := vmconfig.Tracer; tracer != nil && tracer.OnTxStart != nil { @@ -543,3 +550,12 @@ func (st *StateTestState) Close() { st.Snapshots = nil } } + +// dummyChain implements the core.ChainContext interface. +type dummyChain struct { + config *params.ChainConfig +} + +func (d *dummyChain) Engine() consensus.Engine { return nil } +func (d *dummyChain) GetHeader(h common.Hash, n uint64) *types.Header { return nil } +func (d *dummyChain) Config() *params.ChainConfig { return d.config } From e332431cb28c6d374504fc5343fafaf3157a6aee Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 4 Feb 2025 17:16:26 +0100 Subject: [PATCH 093/940] core: assign default difficulty to zero for chain without ethash (#31067) I hit this case while trying something with the simulated backend. The EVM only enables instruction set forks after the merge when 'Random' is set. In the simulated backend, the random value will be set via the engine API for all blocks after genesis. But for the genesis block itself, the random value will not be assigned in the vm.BlockContext because the genesis has a non-zero difficulty. For my case, this meant that estimateGas did not work for the first transaction sent on the simulated chain, since the contract contained a PUSH0 instruction. This could also be fixed by explicitly configuring a zero difficulty in the simulated backend. However, I think that zero difficulty is a better default these days. --------- Co-authored-by: lightclient --- core/genesis.go | 8 ++++++-- core/genesis_test.go | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/core/genesis.go b/core/genesis.go index d1ee1b6e92..8f71f9ef1e 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -464,8 +464,12 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block { if g.GasLimit == 0 { head.GasLimit = params.GenesisGasLimit } - if g.Difficulty == nil && g.Mixhash == (common.Hash{}) { - head.Difficulty = params.GenesisDifficulty + if g.Difficulty == nil { + if g.Config != nil && g.Config.Ethash == nil { + head.Difficulty = big.NewInt(0) + } else if g.Mixhash == (common.Hash{}) { + head.Difficulty = params.GenesisDifficulty + } } if g.Config != nil && g.Config.IsLondon(common.Big0) { if g.BaseFee != nil { diff --git a/core/genesis_test.go b/core/genesis_test.go index 3e120a9307..ad75afcd9e 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -44,14 +44,14 @@ func testSetupGenesis(t *testing.T, scheme string) { var ( customghash = common.HexToHash("0x89c99d90b79719238d2645c7642f2c9295246e80775b38cfd162b696817fbd50") customg = Genesis{ - Config: ¶ms.ChainConfig{HomesteadBlock: big.NewInt(3)}, + Config: ¶ms.ChainConfig{HomesteadBlock: big.NewInt(3), Ethash: ¶ms.EthashConfig{}}, Alloc: types.GenesisAlloc{ {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, }, } oldcustomg = customg ) - oldcustomg.Config = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(2)} + oldcustomg.Config = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(2), Ethash: ¶ms.EthashConfig{}} tests := []struct { name string From 7c7b7f6ab1b3f56c527ce1fb39db3061a9ec0ac6 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Tue, 4 Feb 2025 17:23:01 +0100 Subject: [PATCH 094/940] core/txpool: remove locals-tracking from txpools (#30559) Replaces #29297, descendant from #27535 --------- This PR removes `locals` as a concept from transaction pools. Therefore, the pool now acts as very a good simulation/approximation of how our peers' pools behave. What this PR does instead, is implement a locals-tracker, which basically is a little thing which, from time to time, asks the pool "did you forget this transaction?". If it did, the tracker resubmits it. If the txpool _had_ forgotten it, chances are that the peers had also forgotten it. It will be propagated again. Doing this change means that we can simplify the pool internals, quite a lot. ### The semantics of `local` Historically, there has been two features, or usecases, that has been combined into the concept of `locals`. 1. "I want my local node to remember this transaction indefinitely, and resubmit to the network occasionally" 2. "I want this (valid) transaction included to be top-prio for my miner" This PR splits these features up, let's call it `1: local` and `2: prio`. The `prio` is not actually individual transaction, but rather a set of `address`es to prioritize. The attribute `local` means it will be tracked, and `prio` means it will be prioritized by miner. For `local`: anything transaction received via the RPC is marked as `local`, and tracked by the tracker. For `prio`: any transactions from this sender is included first, when building a block. The existing commandline-flag `--txpool.locals` sets the set of `prio` addresses. --------- Co-authored-by: Gary Rong --- core/txpool/blobpool/blobpool.go | 9 +- core/txpool/legacypool/legacypool.go | 385 +++--------- core/txpool/legacypool/legacypool_test.go | 575 +++--------------- core/txpool/legacypool/list.go | 63 +- core/txpool/{legacypool => locals}/journal.go | 2 +- core/txpool/locals/tx_tracker.go | 212 +++++++ core/txpool/subpool.go | 5 +- core/txpool/txpool.go | 21 +- eth/api_backend.go | 5 +- eth/backend.go | 20 +- eth/catalyst/api_test.go | 18 +- eth/catalyst/simulated_beacon_test.go | 52 +- eth/handler.go | 4 +- eth/handler_eth_test.go | 6 +- eth/handler_test.go | 2 +- miner/miner.go | 8 + miner/payload_building_test.go | 2 +- miner/worker.go | 31 +- 18 files changed, 493 insertions(+), 927 deletions(-) rename core/txpool/{legacypool => locals}/journal.go (99%) create mode 100644 core/txpool/locals/tx_tracker.go diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 78cf2c05af..51b8b67c61 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1269,7 +1269,7 @@ func (p *BlobPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844. // Add inserts a set of blob transactions into the pool if they pass validation (both // consensus validity and pool restrictions). -func (p *BlobPool) Add(txs []*types.Transaction, local bool, sync bool) []error { +func (p *BlobPool) Add(txs []*types.Transaction, sync bool) []error { var ( adds = make([]*types.Transaction, 0, len(txs)) errs = make([]error, len(txs)) @@ -1701,13 +1701,6 @@ func (p *BlobPool) ContentFrom(addr common.Address) ([]*types.Transaction, []*ty return []*types.Transaction{}, []*types.Transaction{} } -// Locals retrieves the accounts currently considered local by the pool. -// -// There is no notion of local accounts in the blob pool. -func (p *BlobPool) Locals() []common.Address { - return []common.Address{} -} - // Status returns the known status (unknown/pending/queued) of a transaction // identified by their hashes. func (p *BlobPool) Status(hash common.Hash) txpool.TxStatus { diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 3d780ad373..1440af5440 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -99,7 +99,6 @@ var ( pendingGauge = metrics.NewRegisteredGauge("txpool/pending", nil) queuedGauge = metrics.NewRegisteredGauge("txpool/queued", nil) - localGauge = metrics.NewRegisteredGauge("txpool/local", nil) slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil) reheapTimer = metrics.NewRegisteredTimer("txpool/reheap", nil) @@ -159,10 +158,6 @@ var DefaultConfig = Config{ // unreasonable or unworkable. func (config *Config) sanitize() Config { conf := *config - if conf.Rejournal < time.Second { - log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second) - conf.Rejournal = time.Second - } if conf.PriceLimit < 1 { log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultConfig.PriceLimit) conf.PriceLimit = DefaultConfig.PriceLimit @@ -214,9 +209,6 @@ type LegacyPool struct { currentState *state.StateDB // Current state in the blockchain head pendingNonces *noncer // Pending state tracking virtual nonces - locals *accountSet // Set of local transaction to exempt from eviction rules - journal *journal // Journal of local transaction to back up to disk - reserve txpool.AddressReserver // Address reserver to ensure exclusivity across subpools pending map[common.Address]*list // All currently processable transactions queue map[common.Address]*list // Queued but non-processable transactions @@ -262,16 +254,8 @@ func New(config Config, chain BlockChain) *LegacyPool { reorgShutdownCh: make(chan struct{}), initDoneCh: make(chan struct{}), } - pool.locals = newAccountSet(pool.signer) - for _, addr := range config.Locals { - log.Info("Setting new local account", "address", addr) - pool.locals.add(addr) - } pool.priced = newPricedList(pool.all) - if !config.NoLocals && config.Journal != "" { - pool.journal = newTxJournal(config.Journal) - } return pool } @@ -287,8 +271,7 @@ func (pool *LegacyPool) Filter(tx *types.Transaction) bool { } // Init sets the gas price needed to keep a transaction in the pool and the chain -// head to allow balance / nonce checks. The transaction journal will be loaded -// from disk and filtered based on the provided starting settings. The internal +// head to allow balance / nonce checks. The internal // goroutines will be spun up and the pool deemed operational afterwards. func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserve txpool.AddressReserver) error { // Set the address reserver to request exclusive access to pooled accounts @@ -311,20 +294,9 @@ func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserve txpool.A pool.currentState = statedb pool.pendingNonces = newNoncer(statedb) - // Start the reorg loop early, so it can handle requests generated during - // journal loading. pool.wg.Add(1) go pool.scheduleReorgLoop() - // If local transactions and journaling is enabled, load from disk - if pool.journal != nil { - if err := pool.journal.load(pool.addLocals); err != nil { - log.Warn("Failed to load transaction journal", "err", err) - } - if err := pool.journal.rotate(pool.local()); err != nil { - log.Warn("Failed to rotate transaction journal", "err", err) - } - } pool.wg.Add(1) go pool.loop() return nil @@ -340,13 +312,11 @@ func (pool *LegacyPool) loop() { prevPending, prevQueued, prevStales int // Start the stats reporting and transaction eviction tickers - report = time.NewTicker(statsReportInterval) - evict = time.NewTicker(evictionInterval) - journal = time.NewTicker(pool.config.Rejournal) + report = time.NewTicker(statsReportInterval) + evict = time.NewTicker(evictionInterval) ) defer report.Stop() defer evict.Stop() - defer journal.Stop() // Notify tests that the init phase is done close(pool.initDoneCh) @@ -372,11 +342,7 @@ func (pool *LegacyPool) loop() { case <-evict.C: pool.mu.Lock() for addr := range pool.queue { - // Skip local transactions from the eviction mechanism - if pool.locals.contains(addr) { - continue - } - // Any non-locals old enough should be removed + // Any old enough should be removed if time.Since(pool.beats[addr]) > pool.config.Lifetime { list := pool.queue[addr].Flatten() for _, tx := range list { @@ -386,16 +352,6 @@ func (pool *LegacyPool) loop() { } } pool.mu.Unlock() - - // Handle local transaction journal rotation - case <-journal.C: - if pool.journal != nil { - pool.mu.Lock() - if err := pool.journal.rotate(pool.local()); err != nil { - log.Warn("Failed to rotate local tx journal", "err", err) - } - pool.mu.Unlock() - } } } } @@ -406,9 +362,6 @@ func (pool *LegacyPool) Close() error { close(pool.reorgShutdownCh) pool.wg.Wait() - if pool.journal != nil { - pool.journal.close() - } log.Info("Transaction pool stopped") return nil } @@ -444,7 +397,7 @@ func (pool *LegacyPool) SetGasTip(tip *big.Int) { // If the min miner fee increased, remove transactions below the new threshold if newTip.Cmp(old) > 0 { // pool.priced is sorted by GasFeeCap, so we have to iterate through pool.all instead - drop := pool.all.RemotesBelowTip(tip) + drop := pool.all.TxsBelowTip(tip) for _, tx := range drop { pool.removeTx(tx.Hash(), false, true) } @@ -549,7 +502,7 @@ func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address] txs := list.Flatten() // If the miner requests tip enforcement, cap the lists now - if minTipBig != nil && !pool.locals.contains(addr) { + if minTipBig != nil { for i, tx := range txs { if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 { txs = txs[:i] @@ -577,35 +530,11 @@ func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address] return pending } -// Locals retrieves the accounts currently considered local by the pool. -func (pool *LegacyPool) Locals() []common.Address { - pool.mu.Lock() - defer pool.mu.Unlock() - - return pool.locals.flatten() -} - -// local retrieves all currently known local transactions, grouped by origin -// account and sorted by nonce. The returned transaction set is a copy and can be -// freely modified by calling code. -func (pool *LegacyPool) local() map[common.Address]types.Transactions { - txs := make(map[common.Address]types.Transactions) - for addr := range pool.locals.accounts { - if pending := pool.pending[addr]; pending != nil { - txs[addr] = append(txs[addr], pending.Flatten()...) - } - if queued := pool.queue[addr]; queued != nil { - txs[addr] = append(txs[addr], queued.Flatten()...) - } - } - return txs -} - // validateTxBasics checks whether a transaction is valid according to the consensus // rules, but does not check state-dependent validation such as sufficient balance. // This check is meant as an early check which only needs to be performed once, // and does not require the pool mutex to be held. -func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) error { +func (pool *LegacyPool) validateTxBasics(tx *types.Transaction) error { opts := &txpool.ValidationOptions{ Config: pool.chainconfig, Accept: 0 | @@ -615,9 +544,6 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro MaxSize: txMaxSize, MinTip: pool.gasTip.Load().ToBig(), } - if local { - opts.MinTip = new(big.Int) - } if err := txpool.ValidateTransaction(tx, pool.currentHead.Load(), pool.signer, opts); err != nil { return err } @@ -665,11 +591,7 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error { // add validates a transaction and inserts it into the non-executable queue for later // pending promotion and execution. If the transaction is a replacement for an already // pending or queued one, it overwrites the previous transaction if its price is higher. -// -// If a newly added transaction is marked as local, its sending account will be -// added to the allowlist, preventing any associated transaction from being dropped -// out of the pool due to pricing constraints. -func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, err error) { +func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) { // If the transaction is already known, discard it hash := tx.Hash() if pool.all.Get(hash) != nil { @@ -677,9 +599,6 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e knownTxMeter.Mark(1) return false, txpool.ErrAlreadyKnown } - // Make the local flag. If it's from local source or it's from the network but - // the sender is marked as local previously, treat it as the local transaction. - isLocal := local || pool.locals.containsTx(tx) // If the transaction fails basic validation, discard it if err := pool.validateTx(tx); err != nil { @@ -715,7 +634,7 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e // If the transaction pool is full, discard underpriced transactions if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue { // If the new transaction is underpriced, don't accept it - if !isLocal && pool.priced.Underpriced(tx) { + if pool.priced.Underpriced(tx) { log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) underpricedTxMeter.Mark(1) return false, txpool.ErrUnderpriced @@ -731,19 +650,18 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e } // New transaction is better than our worse ones, make room for it. - // If it's a local transaction, forcibly discard all available transactions. - // Otherwise if we can't make enough room for new one, abort the operation. - drop, success := pool.priced.Discard(pool.all.Slots()-int(pool.config.GlobalSlots+pool.config.GlobalQueue)+numSlots(tx), isLocal) + // If we can't make enough room for new one, abort the operation. + drop, success := pool.priced.Discard(pool.all.Slots() - int(pool.config.GlobalSlots+pool.config.GlobalQueue) + numSlots(tx)) // Special case, we still can't make the room for the new remote one. - if !isLocal && !success { + if !success { log.Trace("Discarding overflown transaction", "hash", hash) overflowedTxMeter.Mark(1) return false, ErrTxPoolOverflow } // If the new transaction is a future transaction it should never churn pending transactions - if !isLocal && pool.isGapped(from, tx) { + if pool.isGapped(from, tx) { var replacesPending bool for _, dropTx := range drop { dropSender, _ := types.Sender(pool.signer, dropTx) @@ -755,7 +673,7 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e // Add all transactions back to the priced queue if replacesPending { for _, dropTx := range drop { - pool.priced.Put(dropTx, false) + pool.priced.Put(dropTx) } log.Trace("Discarding future transaction replacing pending tx", "hash", hash) return false, txpool.ErrFutureReplacePending @@ -788,9 +706,8 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e pool.priced.Removed(1) pendingReplaceMeter.Mark(1) } - pool.all.Add(tx, isLocal) - pool.priced.Put(tx, isLocal) - pool.journalTx(from, tx) + pool.all.Add(tx) + pool.priced.Put(tx) pool.queueTxEvent(tx) log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) @@ -799,20 +716,10 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e return old != nil, nil } // New transaction isn't replacing a pending one, push into queue - replaced, err = pool.enqueueTx(hash, tx, isLocal, true) + replaced, err = pool.enqueueTx(hash, tx, true) if err != nil { return false, err } - // Mark local addresses and journal local transactions - if local && !pool.locals.contains(from) { - log.Info("Setting new local account", "address", from) - pool.locals.add(from) - pool.priced.Removed(pool.all.RemoteToLocals(pool.locals)) // Migrate the remotes if it's marked as local first time. - } - if isLocal { - localGauge.Inc(1) - } - pool.journalTx(from, tx) log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To()) return replaced, nil @@ -845,7 +752,7 @@ func (pool *LegacyPool) isGapped(from common.Address, tx *types.Transaction) boo // enqueueTx inserts a new transaction into the non-executable transaction queue. // // Note, this method assumes the pool lock is held! -func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, local bool, addAll bool) (bool, error) { +func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, addAll bool) (bool, error) { // Try to insert the transaction into the future queue from, _ := types.Sender(pool.signer, tx) // already validated if pool.queue[from] == nil { @@ -872,8 +779,8 @@ func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, local log.Error("Missing transaction in lookup set, please report the issue", "hash", hash) } if addAll { - pool.all.Add(tx, local) - pool.priced.Put(tx, local) + pool.all.Add(tx) + pool.priced.Put(tx) } // If we never record the heartbeat, do it right now. if _, exist := pool.beats[from]; !exist { @@ -882,18 +789,6 @@ func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, local return old != nil, nil } -// journalTx adds the specified transaction to the local disk journal if it is -// deemed to have been sent from a local account. -func (pool *LegacyPool) journalTx(from common.Address, tx *types.Transaction) { - // Only journal if it's enabled and the transaction is local - if pool.journal == nil || !pool.locals.contains(from) { - return - } - if err := pool.journal.insert(tx); err != nil { - log.Warn("Failed to journal local transaction", "err", err) - } -} - // promoteTx adds a transaction to the pending (processable) list of transactions // and returns whether it was inserted or an older was better. // @@ -930,28 +825,13 @@ func (pool *LegacyPool) promoteTx(addr common.Address, hash common.Hash, tx *typ return true } -// addLocals enqueues a batch of transactions into the pool if they are valid, marking the -// senders as local ones, ensuring they go around the local pricing constraints. -// -// This method is used to add transactions from the RPC API and performs synchronous pool -// reorganization and event propagation. -func (pool *LegacyPool) addLocals(txs []*types.Transaction) []error { - return pool.Add(txs, !pool.config.NoLocals, true) -} - -// addLocal enqueues a single local transaction into the pool if it is valid. This is -// a convenience wrapper around addLocals. -func (pool *LegacyPool) addLocal(tx *types.Transaction) error { - return pool.addLocals([]*types.Transaction{tx})[0] -} - -// addRemotes enqueues a batch of transactions into the pool if they are valid. If the -// senders are not among the locally tracked ones, full pricing constraints will apply. +// addRemotes enqueues a batch of transactions into the pool if they are valid. +// Full pricing constraints will apply. // // This method is used to add transactions from the p2p network and does not wait for pool // reorganization and internal event propagation. func (pool *LegacyPool) addRemotes(txs []*types.Transaction) []error { - return pool.Add(txs, false, false) + return pool.Add(txs, false) } // addRemote enqueues a single transaction into the pool if it is valid. This is a convenience @@ -962,23 +842,19 @@ func (pool *LegacyPool) addRemote(tx *types.Transaction) error { // addRemotesSync is like addRemotes, but waits for pool reorganization. Tests use this method. func (pool *LegacyPool) addRemotesSync(txs []*types.Transaction) []error { - return pool.Add(txs, false, true) + return pool.Add(txs, true) } // This is like addRemotes with a single transaction, but waits for pool reorganization. Tests use this method. func (pool *LegacyPool) addRemoteSync(tx *types.Transaction) error { - return pool.Add([]*types.Transaction{tx}, false, true)[0] + return pool.Add([]*types.Transaction{tx}, true)[0] } -// Add enqueues a batch of transactions into the pool if they are valid. Depending -// on the local flag, full pricing constraints will or will not be applied. +// Add enqueues a batch of transactions into the pool if they are valid. // // If sync is set, the method will block until all internal maintenance related // to the add is finished. Only use this during tests for determinism! -func (pool *LegacyPool) Add(txs []*types.Transaction, local, sync bool) []error { - // Do not treat as local if local transactions have been disabled - local = local && !pool.config.NoLocals - +func (pool *LegacyPool) Add(txs []*types.Transaction, sync bool) []error { // Filter out known ones without obtaining the pool lock or recovering signatures var ( errs = make([]error, len(txs)) @@ -994,7 +870,7 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, local, sync bool) []error // Exclude transactions with basic errors, e.g invalid signatures and // insufficient intrinsic gas as soon as possible and cache senders // in transactions before obtaining lock - if err := pool.validateTxBasics(tx, local); err != nil { + if err := pool.validateTxBasics(tx); err != nil { errs[i] = err log.Trace("Discarding invalid transaction", "hash", tx.Hash(), "err", err) invalidTxMeter.Mark(1) @@ -1009,7 +885,7 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, local, sync bool) []error // Process all the new transaction and merge any errors into the original slice pool.mu.Lock() - newErrs, dirtyAddrs := pool.addTxsLocked(news, local) + newErrs, dirtyAddrs := pool.addTxsLocked(news) pool.mu.Unlock() var nilSlot = 0 @@ -1030,11 +906,11 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, local, sync bool) []error // addTxsLocked attempts to queue a batch of transactions if they are valid. // The transaction pool lock must be held. -func (pool *LegacyPool) addTxsLocked(txs []*types.Transaction, local bool) ([]error, *accountSet) { +func (pool *LegacyPool) addTxsLocked(txs []*types.Transaction) ([]error, *accountSet) { dirty := newAccountSet(pool.signer) errs := make([]error, len(txs)) for i, tx := range txs { - replaced, err := pool.add(tx, local) + replaced, err := pool.add(tx) errs[i] = err if err == nil && !replaced { dirty.addTx(tx) @@ -1126,9 +1002,6 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo if outofbound { pool.priced.Removed(1) } - if pool.locals.contains(addr) { - localGauge.Dec(1) - } // Remove the transaction from the pending lists and reset the account nonce if pending := pool.pending[addr]; pending != nil { if removed, invalids := pending.Remove(tx); removed { @@ -1139,7 +1012,7 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo // Postpone any invalidated transactions for _, tx := range invalids { // Internal shuffle shouldn't touch the lookup set. - pool.enqueueTx(tx.Hash(), tx, false, false) + pool.enqueueTx(tx.Hash(), tx, false) } // Update the account nonce if needed pool.pendingNonces.setIfLower(addr, tx.Nonce()) @@ -1204,7 +1077,7 @@ func (pool *LegacyPool) scheduleReorgLoop() { launchNextRun bool reset *txpoolResetRequest dirtyAccounts *accountSet - queuedEvents = make(map[common.Address]*sortedMap) + queuedEvents = make(map[common.Address]*SortedMap) ) for { // Launch next background reorg if needed @@ -1217,7 +1090,7 @@ func (pool *LegacyPool) scheduleReorgLoop() { launchNextRun = false reset, dirtyAccounts = nil, nil - queuedEvents = make(map[common.Address]*sortedMap) + queuedEvents = make(map[common.Address]*SortedMap) } select { @@ -1246,7 +1119,7 @@ func (pool *LegacyPool) scheduleReorgLoop() { // request one later if they want the events sent. addr, _ := types.Sender(pool.signer, tx) if _, ok := queuedEvents[addr]; !ok { - queuedEvents[addr] = newSortedMap() + queuedEvents[addr] = NewSortedMap() } queuedEvents[addr].Put(tx) @@ -1265,7 +1138,7 @@ func (pool *LegacyPool) scheduleReorgLoop() { } // runReorg runs reset and promoteExecutables on behalf of scheduleReorgLoop. -func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirtyAccounts *accountSet, events map[common.Address]*sortedMap) { +func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirtyAccounts *accountSet, events map[common.Address]*SortedMap) { defer func(t0 time.Time) { reorgDurationTimer.Update(time.Since(t0)) }(time.Now()) @@ -1332,7 +1205,7 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest, for _, tx := range promoted { addr, _ := types.Sender(pool.signer, tx) if _, ok := events[addr]; !ok { - events[addr] = newSortedMap() + events[addr] = NewSortedMap() } events[addr].Put(tx) } @@ -1441,7 +1314,7 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) { // Inject any transactions discarded due to reorgs log.Debug("Reinjecting stale transactions", "count", len(reinject)) core.SenderCacher().Recover(pool.signer, reinject) - pool.addTxsLocked(reinject, false) + pool.addTxsLocked(reinject) } // promoteExecutables moves transactions that have become processable from the @@ -1486,22 +1359,17 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T queuedGauge.Dec(int64(len(readies))) // Drop all transactions over the allowed limit - var caps types.Transactions - if !pool.locals.contains(addr) { - caps = list.Cap(int(pool.config.AccountQueue)) - for _, tx := range caps { - hash := tx.Hash() - pool.all.Remove(hash) - log.Trace("Removed cap-exceeding queued transaction", "hash", hash) - } - queuedRateLimitMeter.Mark(int64(len(caps))) + var caps = list.Cap(int(pool.config.AccountQueue)) + for _, tx := range caps { + hash := tx.Hash() + pool.all.Remove(hash) + log.Trace("Removed cap-exceeding queued transaction", "hash", hash) } + queuedRateLimitMeter.Mark(int64(len(caps))) // Mark all the items dropped as removed pool.priced.Removed(len(forwards) + len(drops) + len(caps)) queuedGauge.Dec(int64(len(forwards) + len(drops) + len(caps))) - if pool.locals.contains(addr) { - localGauge.Dec(int64(len(forwards) + len(drops) + len(caps))) - } + // Delete the entire queue entry if it became empty. if list.Empty() { delete(pool.queue, addr) @@ -1531,14 +1399,14 @@ func (pool *LegacyPool) truncatePending() { spammers := prque.New[int64, common.Address](nil) for addr, list := range pool.pending { // Only evict transactions from high rollers - if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { + if uint64(list.Len()) > pool.config.AccountSlots { spammers.Push(addr, int64(list.Len())) } } // Gradually drop transactions from offenders offenders := []common.Address{} for pending > pool.config.GlobalSlots && !spammers.Empty() { - // Retrieve the next offender if not local address + // Retrieve the next offender offender, _ := spammers.Pop() offenders = append(offenders, offender) @@ -1564,9 +1432,7 @@ func (pool *LegacyPool) truncatePending() { } pool.priced.Removed(len(caps)) pendingGauge.Dec(int64(len(caps))) - if pool.locals.contains(offenders[i]) { - localGauge.Dec(int64(len(caps))) - } + pending-- } } @@ -1591,9 +1457,6 @@ func (pool *LegacyPool) truncatePending() { } pool.priced.Removed(len(caps)) pendingGauge.Dec(int64(len(caps))) - if pool.locals.contains(addr) { - localGauge.Dec(int64(len(caps))) - } pending-- } } @@ -1614,13 +1477,11 @@ func (pool *LegacyPool) truncateQueue() { // Sort all accounts with queued transactions by heartbeat addresses := make(addressesByHeartbeat, 0, len(pool.queue)) for addr := range pool.queue { - if !pool.locals.contains(addr) { // don't drop locals - addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) - } + addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) } sort.Sort(sort.Reverse(addresses)) - // Drop transactions until the total is below the limit or only locals remain + // Drop transactions until the total is below the limit for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; { addr := addresses[len(addresses)-1] list := pool.queue[addr.address] @@ -1680,12 +1541,10 @@ func (pool *LegacyPool) demoteUnexecutables() { log.Trace("Demoting pending transaction", "hash", hash) // Internal shuffle shouldn't touch the lookup set. - pool.enqueueTx(hash, tx, false, false) + pool.enqueueTx(hash, tx, false) } pendingGauge.Dec(int64(len(olds) + len(drops) + len(invalids))) - if pool.locals.contains(addr) { - localGauge.Dec(int64(len(olds) + len(drops) + len(invalids))) - } + // If there's a gap in front, alert (should never happen) and postpone all transactions if list.Len() > 0 && list.txs.Get(nonce) == nil { gapped := list.Cap(0) @@ -1694,7 +1553,7 @@ func (pool *LegacyPool) demoteUnexecutables() { log.Error("Demoting invalidated transaction", "hash", hash) // Internal shuffle shouldn't touch the lookup set. - pool.enqueueTx(hash, tx, false, false) + pool.enqueueTx(hash, tx, false) } pendingGauge.Dec(int64(len(gapped))) } @@ -1741,21 +1600,6 @@ func newAccountSet(signer types.Signer, addrs ...common.Address) *accountSet { return as } -// contains checks if a given address is contained within the set. -func (as *accountSet) contains(addr common.Address) bool { - _, exist := as.accounts[addr] - return exist -} - -// containsTx checks if the sender of a given tx is within the set. If the sender -// cannot be derived, this method returns false. -func (as *accountSet) containsTx(tx *types.Transaction) bool { - if addr, err := types.Sender(as.signer, tx); err == nil { - return as.contains(addr) - } - return false -} - // add inserts a new address into the set to track. func (as *accountSet) add(addr common.Address) { as.accounts[addr] = struct{}{} @@ -1793,43 +1637,29 @@ func (as *accountSet) merge(other *accountSet) { // internal mechanisms. The sole purpose of the type is to permit out-of-bound // peeking into the pool in LegacyPool.Get without having to acquire the widely scoped // LegacyPool.mu mutex. -// -// This lookup set combines the notion of "local transactions", which is useful -// to build upper-level structure. type lookup struct { - slots int - lock sync.RWMutex - locals map[common.Hash]*types.Transaction - remotes map[common.Hash]*types.Transaction + slots int + lock sync.RWMutex + txs map[common.Hash]*types.Transaction } // newLookup returns a new lookup structure. func newLookup() *lookup { return &lookup{ - locals: make(map[common.Hash]*types.Transaction), - remotes: make(map[common.Hash]*types.Transaction), + txs: make(map[common.Hash]*types.Transaction), } } // Range calls f on each key and value present in the map. The callback passed // should return the indicator whether the iteration needs to be continued. // Callers need to specify which set (or both) to be iterated. -func (t *lookup) Range(f func(hash common.Hash, tx *types.Transaction, local bool) bool, local bool, remote bool) { +func (t *lookup) Range(f func(hash common.Hash, tx *types.Transaction) bool) { t.lock.RLock() defer t.lock.RUnlock() - if local { - for key, value := range t.locals { - if !f(key, value, true) { - return - } - } - } - if remote { - for key, value := range t.remotes { - if !f(key, value, false) { - return - } + for key, value := range t.txs { + if !f(key, value) { + return } } } @@ -1839,26 +1669,7 @@ func (t *lookup) Get(hash common.Hash) *types.Transaction { t.lock.RLock() defer t.lock.RUnlock() - if tx := t.locals[hash]; tx != nil { - return tx - } - return t.remotes[hash] -} - -// GetLocal returns a transaction if it exists in the lookup, or nil if not found. -func (t *lookup) GetLocal(hash common.Hash) *types.Transaction { - t.lock.RLock() - defer t.lock.RUnlock() - - return t.locals[hash] -} - -// GetRemote returns a transaction if it exists in the lookup, or nil if not found. -func (t *lookup) GetRemote(hash common.Hash) *types.Transaction { - t.lock.RLock() - defer t.lock.RUnlock() - - return t.remotes[hash] + return t.txs[hash] } // Count returns the current number of transactions in the lookup. @@ -1866,23 +1677,7 @@ func (t *lookup) Count() int { t.lock.RLock() defer t.lock.RUnlock() - return len(t.locals) + len(t.remotes) -} - -// LocalCount returns the current number of local transactions in the lookup. -func (t *lookup) LocalCount() int { - t.lock.RLock() - defer t.lock.RUnlock() - - return len(t.locals) -} - -// RemoteCount returns the current number of remote transactions in the lookup. -func (t *lookup) RemoteCount() int { - t.lock.RLock() - defer t.lock.RUnlock() - - return len(t.remotes) + return len(t.txs) } // Slots returns the current number of slots used in the lookup. @@ -1894,18 +1689,14 @@ func (t *lookup) Slots() int { } // Add adds a transaction to the lookup. -func (t *lookup) Add(tx *types.Transaction, local bool) { +func (t *lookup) Add(tx *types.Transaction) { t.lock.Lock() defer t.lock.Unlock() t.slots += numSlots(tx) slotsGauge.Update(int64(t.slots)) - if local { - t.locals[tx.Hash()] = tx - } else { - t.remotes[tx.Hash()] = tx - } + t.txs[tx.Hash()] = tx } // Remove removes a transaction from the lookup. @@ -1913,10 +1704,7 @@ func (t *lookup) Remove(hash common.Hash) { t.lock.Lock() defer t.lock.Unlock() - tx, ok := t.locals[hash] - if !ok { - tx, ok = t.remotes[hash] - } + tx, ok := t.txs[hash] if !ok { log.Error("No transaction found to be deleted", "hash", hash) return @@ -1924,36 +1712,18 @@ func (t *lookup) Remove(hash common.Hash) { t.slots -= numSlots(tx) slotsGauge.Update(int64(t.slots)) - delete(t.locals, hash) - delete(t.remotes, hash) + delete(t.txs, hash) } -// RemoteToLocals migrates the transactions belongs to the given locals to locals -// set. The assumption is held the locals set is thread-safe to be used. -func (t *lookup) RemoteToLocals(locals *accountSet) int { - t.lock.Lock() - defer t.lock.Unlock() - - var migrated int - for hash, tx := range t.remotes { - if locals.containsTx(tx) { - t.locals[hash] = tx - delete(t.remotes, hash) - migrated += 1 - } - } - return migrated -} - -// RemotesBelowTip finds all remote transactions below the given tip threshold. -func (t *lookup) RemotesBelowTip(threshold *big.Int) types.Transactions { +// TxsBelowTip finds all remote transactions below the given tip threshold. +func (t *lookup) TxsBelowTip(threshold *big.Int) types.Transactions { found := make(types.Transactions, 0, 128) - t.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool { + t.Range(func(hash common.Hash, tx *types.Transaction) bool { if tx.GasTipCapIntCmp(threshold) < 0 { found = append(found, tx) } return true - }, false, true) // Only iterate remotes + }) return found } @@ -1982,24 +1752,13 @@ func (pool *LegacyPool) Clear() { // The transaction addition may attempt to reserve the sender addr which // can't happen until Clear releases the reservation lock. Clear cannot // acquire the subpool lock until the transaction addition is completed. - for _, tx := range pool.all.remotes { + for _, tx := range pool.all.txs { senderAddr, _ := types.Sender(pool.signer, tx) pool.reserve(senderAddr, false) } - for localSender := range pool.locals.accounts { - pool.reserve(localSender, false) - } - pool.all = newLookup() pool.priced = newPricedList(pool.all) pool.pending = make(map[common.Address]*list) pool.queue = make(map[common.Address]*list) pool.pendingNonces = newNoncer(pool.currentState) - - if !pool.config.NoLocals && pool.config.Journal != "" { - pool.journal = newTxJournal(pool.config.Journal) - if err := pool.journal.rotate(pool.local()); err != nil { - log.Warn("Failed to rotate transaction journal", "err", err) - } - } } diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index abbde8cae3..55699e93ee 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -23,7 +23,6 @@ import ( "fmt" "math/big" "math/rand" - "os" "sync" "sync/atomic" "testing" @@ -183,7 +182,7 @@ func validatePoolInternals(pool *LegacyPool) error { return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued) } pool.priced.Reheap() - priced, remote := pool.priced.urgent.Len()+pool.priced.floating.Len(), pool.all.RemoteCount() + priced, remote := pool.priced.urgent.Len()+pool.priced.floating.Len(), pool.all.Count() if priced != remote { return fmt.Errorf("total priced transaction count %d != %d", priced, remote) } @@ -350,9 +349,6 @@ func TestInvalidTransactions(t *testing.T) { if err, want := pool.addRemote(tx), txpool.ErrUnderpriced; !errors.Is(err, want) { t.Errorf("want %v have %v", want, err) } - if err := pool.addLocal(tx); err != nil { - t.Error("expected", nil, "got", err) - } } func TestQueue(t *testing.T) { @@ -366,7 +362,7 @@ func TestQueue(t *testing.T) { testAddBalance(pool, from, big.NewInt(1000)) <-pool.requestReset(nil, nil) - pool.enqueueTx(tx.Hash(), tx, false, true) + pool.enqueueTx(tx.Hash(), tx, true) <-pool.requestPromoteExecutables(newAccountSet(pool.signer, from)) if len(pool.pending) != 1 { t.Error("expected valid txs to be 1 is", len(pool.pending)) @@ -375,7 +371,7 @@ func TestQueue(t *testing.T) { tx = transaction(1, 100, key) from, _ = deriveSender(tx) testSetNonce(pool, from, 2) - pool.enqueueTx(tx.Hash(), tx, false, true) + pool.enqueueTx(tx.Hash(), tx, true) <-pool.requestPromoteExecutables(newAccountSet(pool.signer, from)) if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok { @@ -399,9 +395,9 @@ func TestQueue2(t *testing.T) { testAddBalance(pool, from, big.NewInt(1000)) pool.reset(nil, nil) - pool.enqueueTx(tx1.Hash(), tx1, false, true) - pool.enqueueTx(tx2.Hash(), tx2, false, true) - pool.enqueueTx(tx3.Hash(), tx3, false, true) + pool.enqueueTx(tx1.Hash(), tx1, true) + pool.enqueueTx(tx2.Hash(), tx2, true) + pool.enqueueTx(tx3.Hash(), tx3, true) pool.promoteExecutables([]common.Address{from}) if len(pool.pending) != 1 { @@ -476,14 +472,14 @@ func TestChainFork(t *testing.T) { resetState() tx := transaction(0, 100000, key) - if _, err := pool.add(tx, false); err != nil { + if _, err := pool.add(tx); err != nil { t.Error("didn't expect error", err) } pool.removeTx(tx.Hash(), true, true) // reset the pool's internal state resetState() - if _, err := pool.add(tx, false); err != nil { + if _, err := pool.add(tx); err != nil { t.Error("didn't expect error", err) } } @@ -510,10 +506,10 @@ func TestDoubleNonce(t *testing.T) { tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(1), nil), signer, key) // Add the first two transaction, ensure higher priced stays only - if replace, err := pool.add(tx1, false); err != nil || replace { + if replace, err := pool.add(tx1); err != nil || replace { t.Errorf("first transaction insert failed (%v) or reported replacement (%v)", err, replace) } - if replace, err := pool.add(tx2, false); err != nil || !replace { + if replace, err := pool.add(tx2); err != nil || !replace { t.Errorf("second transaction insert failed (%v) or not reported replacement (%v)", err, replace) } <-pool.requestPromoteExecutables(newAccountSet(signer, addr)) @@ -525,7 +521,7 @@ func TestDoubleNonce(t *testing.T) { } // Add the third transaction and ensure it's not saved (smaller price) - pool.add(tx3, false) + pool.add(tx3) <-pool.requestPromoteExecutables(newAccountSet(signer, addr)) if pool.pending[addr].Len() != 1 { t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) @@ -548,7 +544,7 @@ func TestMissingNonce(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) testAddBalance(pool, addr, big.NewInt(100000000000000)) tx := transaction(1, 100000, key) - if _, err := pool.add(tx, false); err != nil { + if _, err := pool.add(tx); err != nil { t.Error("didn't expect error", err) } if len(pool.pending) != 0 { @@ -607,21 +603,21 @@ func TestDropping(t *testing.T) { tx11 = transaction(11, 200, key) tx12 = transaction(12, 300, key) ) - pool.all.Add(tx0, false) - pool.priced.Put(tx0, false) + pool.all.Add(tx0) + pool.priced.Put(tx0) pool.promoteTx(account, tx0.Hash(), tx0) - pool.all.Add(tx1, false) - pool.priced.Put(tx1, false) + pool.all.Add(tx1) + pool.priced.Put(tx1) pool.promoteTx(account, tx1.Hash(), tx1) - pool.all.Add(tx2, false) - pool.priced.Put(tx2, false) + pool.all.Add(tx2) + pool.priced.Put(tx2) pool.promoteTx(account, tx2.Hash(), tx2) - pool.enqueueTx(tx10.Hash(), tx10, false, true) - pool.enqueueTx(tx11.Hash(), tx11, false, true) - pool.enqueueTx(tx12.Hash(), tx12, false, true) + pool.enqueueTx(tx10.Hash(), tx10, true) + pool.enqueueTx(tx11.Hash(), tx11, true) + pool.enqueueTx(tx12.Hash(), tx12, true) // Check that pre and post validations leave the pool as is if pool.pending[account].Len() != 3 { @@ -899,13 +895,6 @@ func TestQueueAccountLimiting(t *testing.T) { // This logic should not hold for local transactions, unless the local tracking // mechanism is disabled. func TestQueueGlobalLimiting(t *testing.T) { - testQueueGlobalLimiting(t, false) -} -func TestQueueGlobalLimitingNoLocals(t *testing.T) { - testQueueGlobalLimiting(t, true) -} - -func testQueueGlobalLimiting(t *testing.T, nolocals bool) { t.Parallel() // Create the pool to test the limit enforcement with @@ -913,7 +902,7 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) { blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig - config.NoLocals = nolocals + config.NoLocals = true config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible) pool := New(config, blockchain) @@ -926,7 +915,6 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) { keys[i], _ = crypto.GenerateKey() testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) } - local := keys[len(keys)-1] // Generate and queue a batch of transactions nonces := make(map[common.Address]uint64) @@ -952,51 +940,12 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) { if queued > int(config.GlobalQueue) { t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) } - // Generate a batch of transactions from the local account and import them - txs = txs[:0] - for i := uint64(0); i < 3*config.GlobalQueue; i++ { - txs = append(txs, transaction(i+1, 100000, local)) - } - pool.addLocals(txs) - - // If locals are disabled, the previous eviction algorithm should apply here too - if nolocals { - queued := 0 - for addr, list := range pool.queue { - if list.Len() > int(config.AccountQueue) { - t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) - } - queued += list.Len() - } - if queued > int(config.GlobalQueue) { - t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) - } - } else { - // Local exemptions are enabled, make sure the local account owned the queue - if len(pool.queue) != 1 { - t.Errorf("multiple accounts in queue: have %v, want %v", len(pool.queue), 1) - } - // Also ensure no local transactions are ever dropped, even if above global limits - if queued := pool.queue[crypto.PubkeyToAddress(local.PublicKey)].Len(); uint64(queued) != 3*config.GlobalQueue { - t.Fatalf("local account queued transaction count mismatch: have %v, want %v", queued, 3*config.GlobalQueue) - } - } } // Tests that if an account remains idle for a prolonged amount of time, any // non-executable transactions queued up are dropped to prevent wasting resources // on shuffling them around. -// -// This logic should not hold for local transactions, unless the local tracking -// mechanism is disabled. func TestQueueTimeLimiting(t *testing.T) { - testQueueTimeLimiting(t, false) -} -func TestQueueTimeLimitingNoLocals(t *testing.T) { - testQueueTimeLimiting(t, true) -} - -func testQueueTimeLimiting(t *testing.T, nolocals bool) { // Reduce the eviction interval to a testable amount defer func(old time.Duration) { evictionInterval = old }(evictionInterval) evictionInterval = time.Millisecond * 100 @@ -1007,23 +956,17 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { config := testTxPoolConfig config.Lifetime = time.Second - config.NoLocals = nolocals pool := New(config, blockchain) pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) defer pool.Close() - // Create two test accounts to ensure remotes expire but locals do not - local, _ := crypto.GenerateKey() + // Create a test account to ensure remotes expire remote, _ := crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) testAddBalance(pool, crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) - // Add the two transactions and ensure they both are queued up - if err := pool.addLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add local transaction: %v", err) - } + // Add the transaction and ensure it is queued up if err := pool.addRemote(pricedTransaction(1, 100000, big.NewInt(1), remote)); err != nil { t.Fatalf("failed to add remote transaction: %v", err) } @@ -1031,7 +974,7 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { if pending != 0 { t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) } - if queued != 2 { + if queued != 1 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) } if err := validatePoolInternals(pool); err != nil { @@ -1046,7 +989,7 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { if pending != 0 { t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) } - if queued != 2 { + if queued != 1 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) } if err := validatePoolInternals(pool); err != nil { @@ -1060,14 +1003,8 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { if pending != 0 { t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) } - if nolocals { - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - } else { - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } + if queued != 0 { + t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) @@ -1075,7 +1012,6 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { // remove current transactions and increase nonce to prepare for a reset and cleanup statedb.SetNonce(crypto.PubkeyToAddress(remote.PublicKey), 2) - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) <-pool.requestReset(nil, nil) // make sure queue, pending are cleared @@ -1091,18 +1027,12 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { } // Queue gapped transactions - if err := pool.addLocal(pricedTransaction(4, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } if err := pool.addRemoteSync(pricedTransaction(4, 100000, big.NewInt(1), remote)); err != nil { t.Fatalf("failed to add remote transaction: %v", err) } time.Sleep(5 * evictionInterval) // A half lifetime pass // Queue executable transactions, the life cycle should be restarted. - if err := pool.addLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), remote)); err != nil { t.Fatalf("failed to add remote transaction: %v", err) } @@ -1110,11 +1040,11 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { // All gapped transactions shouldn't be kicked out pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) + if pending != 1 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) + if queued != 1 { + t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) } if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) @@ -1123,17 +1053,11 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { // The whole life time pass after last promotion, kick out stale transactions time.Sleep(2 * config.Lifetime) pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) + if pending != 1 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) } - if nolocals { - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - } else { - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } + if queued != 0 { + t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) @@ -1363,8 +1287,6 @@ func TestPendingMinimumAllowance(t *testing.T) { // Tests that setting the transaction pool gas price to a higher value correctly // discards everything cheaper than that and moves any gapped transactions back // from the pending pool to the queue. -// -// Note, local transactions are never allowed to be dropped. func TestRepricing(t *testing.T) { t.Parallel() @@ -1382,7 +1304,7 @@ func TestRepricing(t *testing.T) { defer sub.Unsubscribe() // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 4) + keys := make([]*ecdsa.PrivateKey, 3) for i := 0; i < len(keys); i++ { keys[i], _ = crypto.GenerateKey() testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) @@ -1402,20 +1324,17 @@ func TestRepricing(t *testing.T) { txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) txs = append(txs, pricedTransaction(3, 100000, big.NewInt(2), keys[2])) - ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[3]) - // Import the batch and that both pending and queued transactions match up pool.addRemotesSync(txs) - pool.addLocal(ltx) pending, queued := pool.Stats() - if pending != 7 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7) + if pending != 6 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 6) } if queued != 3 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) } - if err := validateEvents(events, 7); err != nil { + if err := validateEvents(events, 6); err != nil { t.Fatalf("original event firing failed: %v", err) } if err := validatePoolInternals(pool); err != nil { @@ -1425,8 +1344,8 @@ func TestRepricing(t *testing.T) { pool.SetGasTip(big.NewInt(2)) pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) + if pending != 1 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) } if queued != 5 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5) @@ -1453,21 +1372,7 @@ func TestRepricing(t *testing.T) { if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } - // However we can add local underpriced transactions - tx := pricedTransaction(1, 100000, big.NewInt(1), keys[3]) - if err := pool.addLocal(tx); err != nil { - t.Fatalf("failed to add underpriced local transaction: %v", err) - } - if pending, _ = pool.Stats(); pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if err := validateEvents(events, 1); err != nil { - t.Fatalf("post-reprice local event firing failed: %v", err) - } - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // And we can fill gaps with properly priced transactions + // we can fill gaps with properly priced transactions if err := pool.addRemote(pricedTransaction(1, 100000, big.NewInt(2), keys[0])); err != nil { t.Fatalf("failed to add pending transaction: %v", err) } @@ -1504,29 +1409,16 @@ func TestMinGasPriceEnforced(t *testing.T) { tx := pricedTransaction(0, 100000, big.NewInt(2), key) pool.SetGasTip(big.NewInt(tx.GasPrice().Int64() + 1)) - if err := pool.addLocal(tx); !errors.Is(err, txpool.ErrUnderpriced) { - t.Fatalf("Min tip not enforced") - } - - if err := pool.Add([]*types.Transaction{tx}, true, false)[0]; !errors.Is(err, txpool.ErrUnderpriced) { + if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrUnderpriced) { t.Fatalf("Min tip not enforced") } tx = dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), key) pool.SetGasTip(big.NewInt(tx.GasTipCap().Int64() + 1)) - if err := pool.addLocal(tx); !errors.Is(err, txpool.ErrUnderpriced) { + if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrUnderpriced) { t.Fatalf("Min tip not enforced") } - - if err := pool.Add([]*types.Transaction{tx}, true, false)[0]; !errors.Is(err, txpool.ErrUnderpriced) { - t.Fatalf("Min tip not enforced") - } - // Make sure the tx is accepted if locals are enabled - pool.config.NoLocals = false - if err := pool.Add([]*types.Transaction{tx}, true, false)[0]; err != nil { - t.Fatalf("Min tip enforced with locals enabled, error: %v", err) - } } // Tests that setting the transaction pool gas price to a higher value correctly @@ -1567,20 +1459,17 @@ func TestRepricingDynamicFee(t *testing.T) { txs = append(txs, dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2])) txs = append(txs, dynamicFeeTx(3, 100000, big.NewInt(2), big.NewInt(2), keys[2])) - ltx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[3]) - // Import the batch and that both pending and queued transactions match up pool.addRemotesSync(txs) - pool.addLocal(ltx) pending, queued := pool.Stats() - if pending != 7 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7) + if pending != 6 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 6) } if queued != 3 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) } - if err := validateEvents(events, 7); err != nil { + if err := validateEvents(events, 6); err != nil { t.Fatalf("original event firing failed: %v", err) } if err := validatePoolInternals(pool); err != nil { @@ -1590,8 +1479,8 @@ func TestRepricingDynamicFee(t *testing.T) { pool.SetGasTip(big.NewInt(2)) pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) + if pending != 1 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) } if queued != 5 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5) @@ -1621,20 +1510,7 @@ func TestRepricingDynamicFee(t *testing.T) { if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } - // However we can add local underpriced transactions - tx = dynamicFeeTx(1, 100000, big.NewInt(1), big.NewInt(1), keys[3]) - if err := pool.addLocal(tx); err != nil { - t.Fatalf("failed to add underpriced local transaction: %v", err) - } - if pending, _ = pool.Stats(); pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if err := validateEvents(events, 1); err != nil { - t.Fatalf("post-reprice local event firing failed: %v", err) - } - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } + // And we can fill gaps with properly priced transactions tx = pricedTransaction(1, 100000, big.NewInt(2), keys[0]) if err := pool.addRemote(tx); err != nil { @@ -1656,77 +1532,6 @@ func TestRepricingDynamicFee(t *testing.T) { } } -// Tests that setting the transaction pool gas price to a higher value does not -// remove local transactions (legacy & dynamic fee). -func TestRepricingKeepsLocals(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - 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()) - defer pool.Close() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 3) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(100000*1000000)) - } - // Create transaction (both pending and queued) with a linearly growing gasprice - for i := uint64(0); i < 500; i++ { - // Add pending transaction. - pendingTx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2]) - if err := pool.addLocal(pendingTx); err != nil { - t.Fatal(err) - } - // Add queued transaction. - queuedTx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2]) - if err := pool.addLocal(queuedTx); err != nil { - t.Fatal(err) - } - - // Add pending dynamic fee transaction. - pendingTx = dynamicFeeTx(i, 100000, big.NewInt(int64(i)+1), big.NewInt(int64(i)), keys[1]) - if err := pool.addLocal(pendingTx); err != nil { - t.Fatal(err) - } - // Add queued dynamic fee transaction. - queuedTx = dynamicFeeTx(i+501, 100000, big.NewInt(int64(i)+1), big.NewInt(int64(i)), keys[1]) - if err := pool.addLocal(queuedTx); err != nil { - t.Fatal(err) - } - } - pending, queued := pool.Stats() - expPending, expQueued := 1000, 1000 - validate := func() { - pending, queued = pool.Stats() - if pending != expPending { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, expPending) - } - if queued != expQueued { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued) - } - - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - } - validate() - - // Reprice the pool and check that nothing is dropped - pool.SetGasTip(big.NewInt(2)) - validate() - - pool.SetGasTip(big.NewInt(2)) - pool.SetGasTip(big.NewInt(4)) - pool.SetGasTip(big.NewInt(8)) - pool.SetGasTip(big.NewInt(100)) - validate() -} - // Tests that when the pool reaches its global transaction limit, underpriced // transactions are gradually shifted out for more expensive ones and any gapped // pending transactions are moved into the queue. @@ -1756,21 +1561,18 @@ func TestUnderpricing(t *testing.T) { keys := make([]*ecdsa.PrivateKey, 5) for i := 0; i < len(keys); i++ { keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) + testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(10000000)) } // Generate and queue a batch of transactions, both pending and queued txs := types.Transactions{} - txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) - - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[1])) - - ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[2]) + txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) // pending + txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) // pending + txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[2])) // pending + txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[1])) // queued // Import the batch and that both pending and queued transactions match up - pool.addRemotes(txs) - pool.addLocal(ltx) + pool.addRemotesSync(txs) pending, queued := pool.Stats() if pending != 3 { @@ -1790,7 +1592,7 @@ func TestUnderpricing(t *testing.T) { t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced) } // Replace a future transaction with a future transaction - if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(2), keys[1])); err != nil { // +K1:1 => -K1:1 => Pend K0:0, K0:1, K2:0; Que K1:1 + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(5), keys[1])); err != nil { // +K1:1 => -K1:1 => Pend K0:0, K0:1, K2:0; Que K1:1 t.Fatalf("failed to add well priced transaction: %v", err) } // Ensure that adding high priced transactions drops cheap ones, but not own @@ -1800,48 +1602,26 @@ func TestUnderpricing(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(4), keys[1])); err != nil { // +K1:2 => -K0:0 => Pend K1:0, K2:0; Que K0:1 K1:2 t.Fatalf("failed to add well priced transaction: %v", err) } - if err := pool.addRemote(pricedTransaction(3, 100000, big.NewInt(5), keys[1])); err != nil { // +K1:3 => -K0:1 => Pend K1:0, K2:0; Que K1:2 K1:3 + if err := pool.addRemoteSync(pricedTransaction(3, 100000, big.NewInt(5), keys[1])); err != nil { // +K1:3 => -K0:1 => Pend K1:0, K2:0; Que K1:2 K1:3 t.Fatalf("failed to add well priced transaction: %v", err) } // Ensure that replacing a pending transaction with a future transaction fails - if err := pool.addRemote(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != txpool.ErrFutureReplacePending { + if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != txpool.ErrFutureReplacePending { t.Fatalf("adding future replace transaction error mismatch: have %v, want %v", err, txpool.ErrFutureReplacePending) } pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) + if pending != 4 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4) } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) + if queued != 0 { + t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } - if err := validateEvents(events, 2); err != nil { + if err := validateEvents(events, 4); err != nil { t.Fatalf("additional event firing failed: %v", err) } if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } - // Ensure that adding local transactions can push out even higher priced ones - ltx = pricedTransaction(1, 100000, big.NewInt(0), keys[2]) - if err := pool.addLocal(ltx); err != nil { - t.Fatalf("failed to append underpriced local transaction: %v", err) - } - ltx = pricedTransaction(0, 100000, big.NewInt(0), keys[3]) - if err := pool.addLocal(ltx); err != nil { - t.Fatalf("failed to add new underpriced local transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - if err := validateEvents(events, 2); err != nil { - t.Fatalf("local event firing failed: %v", err) - } - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } } // Tests that more expensive transactions push out cheap ones from the pool, but @@ -1915,8 +1695,6 @@ func TestStableUnderpricing(t *testing.T) { // Tests that when the pool reaches its global transaction limit, underpriced // transactions (legacy & dynamic fee) are gradually shifted out for more // expensive ones and any gapped pending transactions are moved into the queue. -// -// Note, local transactions are never allowed to be dropped. func TestUnderpricingDynamicFee(t *testing.T) { t.Parallel() @@ -1941,15 +1719,13 @@ func TestUnderpricingDynamicFee(t *testing.T) { // Generate and queue a batch of transactions, both pending and queued txs := types.Transactions{} - txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[0])) - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) - txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(2), big.NewInt(1), keys[1])) + txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[0])) // pending + txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) // pending + txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(2), big.NewInt(1), keys[1])) // queued + txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[2])) // pending - ltx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[2]) - - // Import the batch and that both pending and queued transactions match up - pool.addRemotes(txs) // Pend K0:0, K0:1; Que K1:1 - pool.addLocal(ltx) // +K2:0 => Pend K0:0, K0:1, K2:0; Que K1:1 + // Import the batch and check that both pending and queued transactions match up + pool.addRemotesSync(txs) // Pend K0:0, K0:1; Que K1:1 pending, queued := pool.Stats() if pending != 3 { @@ -1967,13 +1743,13 @@ func TestUnderpricingDynamicFee(t *testing.T) { // Ensure that adding an underpriced transaction fails tx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1]) - if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrUnderpriced) { // Pend K0:0, K0:1, K2:0; Que K1:1 + if err := pool.addRemoteSync(tx); !errors.Is(err, txpool.ErrUnderpriced) { // Pend K0:0, K0:1, K2:0; Que K1:1 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced) } // Ensure that adding high priced transactions drops cheap ones, but not own tx = pricedTransaction(0, 100000, big.NewInt(2), keys[1]) - if err := pool.addRemote(tx); err != nil { // +K1:0, -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que - + if err := pool.addRemoteSync(tx); err != nil { // +K1:0, -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que - t.Fatalf("failed to add well priced transaction: %v", err) } @@ -1986,40 +1762,18 @@ func TestUnderpricingDynamicFee(t *testing.T) { t.Fatalf("failed to add well priced transaction: %v", err) } pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) + if pending != 4 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4) } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) + if queued != 0 { + t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } - if err := validateEvents(events, 2); err != nil { + if err := validateEvents(events, 3); err != nil { t.Fatalf("additional event firing failed: %v", err) } if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } - // Ensure that adding local transactions can push out even higher priced ones - ltx = dynamicFeeTx(1, 100000, big.NewInt(0), big.NewInt(0), keys[2]) - if err := pool.addLocal(ltx); err != nil { - t.Fatalf("failed to append underpriced local transaction: %v", err) - } - ltx = dynamicFeeTx(0, 100000, big.NewInt(0), big.NewInt(0), keys[3]) - if err := pool.addLocal(ltx); err != nil { - t.Fatalf("failed to add new underpriced local transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - if err := validateEvents(events, 2); err != nil { - t.Fatalf("local event firing failed: %v", err) - } - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } } // Tests whether highest fee cap transaction is retained after a batch of high effective @@ -2039,7 +1793,7 @@ func TestDualHeapEviction(t *testing.T) { ) check := func(tx *types.Transaction, name string) { - if pool.all.GetRemote(tx.Hash()) == nil { + if pool.all.Get(tx.Hash()) == nil { t.Fatalf("highest %s transaction evicted from the pool", name) } } @@ -2336,122 +2090,6 @@ func TestReplacementDynamicFee(t *testing.T) { } } -// Tests that local transactions are journaled to disk, but remote transactions -// get discarded between restarts. -func TestJournaling(t *testing.T) { testJournaling(t, false) } -func TestJournalingNoLocals(t *testing.T) { testJournaling(t, true) } - -func testJournaling(t *testing.T, nolocals bool) { - t.Parallel() - - // Create a temporary file for the journal - file, err := os.CreateTemp("", "") - if err != nil { - t.Fatalf("failed to create temporary journal: %v", err) - } - journal := file.Name() - defer os.Remove(journal) - - // Clean up the temporary file, we only need the path for now - file.Close() - os.Remove(journal) - - // Create the original pool to inject transaction into the journal - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) - blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) - - config := testTxPoolConfig - config.NoLocals = nolocals - config.Journal = journal - config.Rejournal = time.Second - - pool := New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) - - // Create two test accounts to ensure remotes expire but locals do not - local, _ := crypto.GenerateKey() - remote, _ := crypto.GenerateKey() - - testAddBalance(pool, crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) - testAddBalance(pool, crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) - - // Add three local and a remote transactions and ensure they are queued up - if err := pool.addLocal(pricedTransaction(0, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add local transaction: %v", err) - } - if err := pool.addLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add local transaction: %v", err) - } - if err := pool.addLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add local transaction: %v", err) - } - if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), remote)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } - pending, queued := pool.Stats() - if pending != 4 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4) - } - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive - pool.Close() - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) - blockchain = newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) - - pool = New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) - - pending, queued = pool.Stats() - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if nolocals { - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) - } - } else { - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - } - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Bump the nonce temporarily and ensure the newly invalidated transaction is removed - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) - <-pool.requestReset(nil, nil) - time.Sleep(2 * config.Rejournal) - pool.Close() - - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) - blockchain = newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) - pool = New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) - - pending, queued = pool.Stats() - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) - } - if nolocals { - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - } else { - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - } - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - pool.Close() -} - // TestStatusCheck tests that the pool can correctly retrieve the // pending status of individual transactions. func TestStatusCheck(t *testing.T) { @@ -2566,7 +2204,7 @@ func benchmarkFuturePromotion(b *testing.B, size int) { for i := 0; i < size; i++ { tx := transaction(uint64(1+i), 100000, key) - pool.enqueueTx(tx.Hash(), tx, false, true) + pool.enqueueTx(tx.Hash(), tx, true) } // Benchmark the speed of pool validation b.ResetTimer() @@ -2576,15 +2214,11 @@ func benchmarkFuturePromotion(b *testing.B, size int) { } // Benchmarks the speed of batched transaction insertion. -func BenchmarkBatchInsert100(b *testing.B) { benchmarkBatchInsert(b, 100, false) } -func BenchmarkBatchInsert1000(b *testing.B) { benchmarkBatchInsert(b, 1000, false) } -func BenchmarkBatchInsert10000(b *testing.B) { benchmarkBatchInsert(b, 10000, false) } +func BenchmarkBatchInsert100(b *testing.B) { benchmarkBatchInsert(b, 100) } +func BenchmarkBatchInsert1000(b *testing.B) { benchmarkBatchInsert(b, 1000) } +func BenchmarkBatchInsert10000(b *testing.B) { benchmarkBatchInsert(b, 10000) } -func BenchmarkBatchLocalInsert100(b *testing.B) { benchmarkBatchInsert(b, 100, true) } -func BenchmarkBatchLocalInsert1000(b *testing.B) { benchmarkBatchInsert(b, 1000, true) } -func BenchmarkBatchLocalInsert10000(b *testing.B) { benchmarkBatchInsert(b, 10000, true) } - -func benchmarkBatchInsert(b *testing.B, size int, local bool) { +func benchmarkBatchInsert(b *testing.B, size int) { // Generate a batch of transactions to enqueue into the pool pool, key := setupPool() defer pool.Close() @@ -2602,46 +2236,7 @@ func benchmarkBatchInsert(b *testing.B, size int, local bool) { // Benchmark importing the transactions into the queue b.ResetTimer() for _, batch := range batches { - if local { - pool.addLocals(batch) - } else { - pool.addRemotes(batch) - } - } -} - -func BenchmarkInsertRemoteWithAllLocals(b *testing.B) { - // Allocate keys for testing - key, _ := crypto.GenerateKey() - account := crypto.PubkeyToAddress(key.PublicKey) - - remoteKey, _ := crypto.GenerateKey() - remoteAddr := crypto.PubkeyToAddress(remoteKey.PublicKey) - - locals := make([]*types.Transaction, 4096+1024) // Occupy all slots - for i := 0; i < len(locals); i++ { - locals[i] = transaction(uint64(i), 100000, key) - } - remotes := make([]*types.Transaction, 1000) - for i := 0; i < len(remotes); i++ { - remotes[i] = pricedTransaction(uint64(i), 100000, big.NewInt(2), remoteKey) // Higher gasprice - } - // Benchmark importing the transactions into the queue - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - pool, _ := setupPool() - testAddBalance(pool, account, big.NewInt(100000000)) - for _, local := range locals { - pool.addLocal(local) - } - b.StartTimer() - // Assign a high enough balance for testing - testAddBalance(pool, remoteAddr, big.NewInt(100000000)) - for i := 0; i < len(remotes); i++ { - pool.addRemotes([]*types.Transaction{remotes[i]}) - } - pool.Close() + pool.addRemotes(batch) } } diff --git a/core/txpool/legacypool/list.go b/core/txpool/legacypool/list.go index b749db44d4..736c28ec4a 100644 --- a/core/txpool/legacypool/list.go +++ b/core/txpool/legacypool/list.go @@ -52,31 +52,31 @@ func (h *nonceHeap) Pop() interface{} { return x } -// sortedMap is a nonce->transaction hash map with a heap based index to allow +// SortedMap is a nonce->transaction hash map with a heap based index to allow // iterating over the contents in a nonce-incrementing way. -type sortedMap struct { +type SortedMap struct { items map[uint64]*types.Transaction // Hash map storing the transaction data index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode) cache types.Transactions // Cache of the transactions already sorted cacheMu sync.Mutex // Mutex covering the cache } -// newSortedMap creates a new nonce-sorted transaction map. -func newSortedMap() *sortedMap { - return &sortedMap{ +// NewSortedMap creates a new nonce-sorted transaction map. +func NewSortedMap() *SortedMap { + return &SortedMap{ items: make(map[uint64]*types.Transaction), index: new(nonceHeap), } } // Get retrieves the current transactions associated with the given nonce. -func (m *sortedMap) Get(nonce uint64) *types.Transaction { +func (m *SortedMap) Get(nonce uint64) *types.Transaction { return m.items[nonce] } // Put inserts a new transaction into the map, also updating the map's nonce // index. If a transaction already exists with the same nonce, it's overwritten. -func (m *sortedMap) Put(tx *types.Transaction) { +func (m *SortedMap) Put(tx *types.Transaction) { nonce := tx.Nonce() if m.items[nonce] == nil { heap.Push(m.index, nonce) @@ -89,7 +89,7 @@ func (m *sortedMap) Put(tx *types.Transaction) { // Forward removes all transactions from the map with a nonce lower than the // provided threshold. Every removed transaction is returned for any post-removal // maintenance. -func (m *sortedMap) Forward(threshold uint64) types.Transactions { +func (m *SortedMap) Forward(threshold uint64) types.Transactions { var removed types.Transactions // Pop off heap items until the threshold is reached @@ -112,7 +112,7 @@ func (m *sortedMap) Forward(threshold uint64) types.Transactions { // Filter, as opposed to 'filter', re-initialises the heap after the operation is done. // If you want to do several consecutive filterings, it's therefore better to first // do a .filter(func1) followed by .Filter(func2) or reheap() -func (m *sortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions { +func (m *SortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions { removed := m.filter(filter) // If transactions were removed, the heap and cache are ruined if len(removed) > 0 { @@ -121,7 +121,7 @@ func (m *sortedMap) Filter(filter func(*types.Transaction) bool) types.Transacti return removed } -func (m *sortedMap) reheap() { +func (m *SortedMap) reheap() { *m.index = make([]uint64, 0, len(m.items)) for nonce := range m.items { *m.index = append(*m.index, nonce) @@ -134,7 +134,7 @@ func (m *sortedMap) reheap() { // filter is identical to Filter, but **does not** regenerate the heap. This method // should only be used if followed immediately by a call to Filter or reheap() -func (m *sortedMap) filter(filter func(*types.Transaction) bool) types.Transactions { +func (m *SortedMap) filter(filter func(*types.Transaction) bool) types.Transactions { var removed types.Transactions // Collect all the transactions to filter out @@ -154,7 +154,7 @@ func (m *sortedMap) filter(filter func(*types.Transaction) bool) types.Transacti // Cap places a hard limit on the number of items, returning all transactions // exceeding that limit. -func (m *sortedMap) Cap(threshold int) types.Transactions { +func (m *SortedMap) Cap(threshold int) types.Transactions { // Short circuit if the number of items is under the limit if len(m.items) <= threshold { return nil @@ -181,7 +181,7 @@ func (m *sortedMap) Cap(threshold int) types.Transactions { // Remove deletes a transaction from the maintained map, returning whether the // transaction was found. -func (m *sortedMap) Remove(nonce uint64) bool { +func (m *SortedMap) Remove(nonce uint64) bool { // Short circuit if no transaction is present _, ok := m.items[nonce] if !ok { @@ -209,7 +209,7 @@ func (m *sortedMap) Remove(nonce uint64) bool { // Note, all transactions with nonces lower than start will also be returned to // prevent getting into an invalid state. This is not something that should ever // happen but better to be self correcting than failing! -func (m *sortedMap) Ready(start uint64) types.Transactions { +func (m *SortedMap) Ready(start uint64) types.Transactions { // Short circuit if no transactions are available if m.index.Len() == 0 || (*m.index)[0] > start { return nil @@ -229,11 +229,11 @@ func (m *sortedMap) Ready(start uint64) types.Transactions { } // Len returns the length of the transaction map. -func (m *sortedMap) Len() int { +func (m *SortedMap) Len() int { return len(m.items) } -func (m *sortedMap) flatten() types.Transactions { +func (m *SortedMap) flatten() types.Transactions { m.cacheMu.Lock() defer m.cacheMu.Unlock() // If the sorting was not cached yet, create and cache it @@ -250,7 +250,7 @@ func (m *sortedMap) flatten() types.Transactions { // Flatten creates a nonce-sorted slice of transactions based on the loosely // sorted internal representation. The result of the sorting is cached in case // it's requested again before any modifications are made to the contents. -func (m *sortedMap) Flatten() types.Transactions { +func (m *SortedMap) Flatten() types.Transactions { cache := m.flatten() // Copy the cache to prevent accidental modification txs := make(types.Transactions, len(cache)) @@ -260,7 +260,7 @@ func (m *sortedMap) Flatten() types.Transactions { // LastElement returns the last element of a flattened list, thus, the // transaction with the highest nonce -func (m *sortedMap) LastElement() *types.Transaction { +func (m *SortedMap) LastElement() *types.Transaction { cache := m.flatten() return cache[len(cache)-1] } @@ -271,7 +271,7 @@ func (m *sortedMap) LastElement() *types.Transaction { // executable/future queue, with minor behavioral changes. type list struct { strict bool // Whether nonces are strictly continuous or not - txs *sortedMap // Heap indexed sorted hash map of the transactions + txs *SortedMap // Heap indexed sorted hash map of the transactions costcap *uint256.Int // Price of the highest costing transaction (reset only if exceeds balance) gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) @@ -283,7 +283,7 @@ type list struct { func newList(strict bool) *list { return &list{ strict: strict, - txs: newSortedMap(), + txs: NewSortedMap(), costcap: new(uint256.Int), totalcost: new(uint256.Int), } @@ -556,10 +556,7 @@ func newPricedList(all *lookup) *pricedList { } // Put inserts a new transaction into the heap. -func (l *pricedList) Put(tx *types.Transaction, local bool) { - if local { - return - } +func (l *pricedList) Put(tx *types.Transaction) { // Insert every new transaction to the urgent heap first; Discard will balance the heaps heap.Push(&l.urgent, tx) } @@ -593,7 +590,7 @@ func (l *pricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool { // Discard stale price points if found at the heap start for len(h.list) > 0 { head := h.list[0] - if l.all.GetRemote(head.Hash()) == nil { // Removed or migrated + if l.all.Get(head.Hash()) == nil { // Removed or migrated l.stales.Add(-1) heap.Pop(h) continue @@ -612,15 +609,13 @@ func (l *pricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool { // Discard finds a number of most underpriced transactions, removes them from the // priced list and returns them for further removal from the entire pool. // If noPending is set to true, we will only consider the floating list -// -// Note local transaction won't be considered for eviction. -func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) { +func (l *pricedList) Discard(slots int) (types.Transactions, bool) { drop := make(types.Transactions, 0, slots) // Remote underpriced transactions to drop for slots > 0 { if len(l.urgent.list)*floatingRatio > len(l.floating.list)*urgentRatio { // Discard stale transactions if found during cleanup tx := heap.Pop(&l.urgent).(*types.Transaction) - if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated + if l.all.Get(tx.Hash()) == nil { // Removed or migrated l.stales.Add(-1) continue } @@ -633,7 +628,7 @@ func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) { } // Discard stale transactions if found during cleanup tx := heap.Pop(&l.floating).(*types.Transaction) - if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated + if l.all.Get(tx.Hash()) == nil { // Removed or migrated l.stales.Add(-1) continue } @@ -643,7 +638,7 @@ func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) { } } // If we still can't make enough room for the new transaction - if slots > 0 && !force { + if slots > 0 { for _, tx := range drop { heap.Push(&l.urgent, tx) } @@ -658,11 +653,11 @@ func (l *pricedList) Reheap() { defer l.reheapMu.Unlock() start := time.Now() l.stales.Store(0) - l.urgent.list = make([]*types.Transaction, 0, l.all.RemoteCount()) - l.all.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool { + l.urgent.list = make([]*types.Transaction, 0, l.all.Count()) + l.all.Range(func(hash common.Hash, tx *types.Transaction) bool { l.urgent.list = append(l.urgent.list, tx) return true - }, false, true) // Only iterate remotes + }) heap.Init(&l.urgent) // balance out the two heaps by moving the worse half of transactions into the diff --git a/core/txpool/legacypool/journal.go b/core/txpool/locals/journal.go similarity index 99% rename from core/txpool/legacypool/journal.go rename to core/txpool/locals/journal.go index 899ed00bcc..46fd6de346 100644 --- a/core/txpool/legacypool/journal.go +++ b/core/txpool/locals/journal.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 legacypool +package locals import ( "errors" diff --git a/core/txpool/locals/tx_tracker.go b/core/txpool/locals/tx_tracker.go new file mode 100644 index 0000000000..a24fcb1f4e --- /dev/null +++ b/core/txpool/locals/tx_tracker.go @@ -0,0 +1,212 @@ +// 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 locals implements tracking for "local" transactions +package locals + +import ( + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "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/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" + "golang.org/x/exp/slices" +) + +var ( + recheckInterval = time.Minute + localGauge = metrics.GetOrRegisterGauge("txpool/local", nil) +) + +// TxTracker is a struct used to track priority transactions; it will check from +// time to time if the main pool has forgotten about any of the transaction +// it is tracking, and if so, submit it again. +// This is used to track 'locals'. +// This struct does not care about transaction validity, price-bumps or account limits, +// but optimistically accepts transactions. +type TxTracker struct { + all map[common.Hash]*types.Transaction // All tracked transactions + byAddr map[common.Address]*legacypool.SortedMap // Transactions by address + + journal *journal // Journal of local transaction to back up to disk + rejournal time.Duration // How often to rotate journal + pool *txpool.TxPool // The tx pool to interact with + signer types.Signer + + shutdownCh chan struct{} + mu sync.Mutex + wg sync.WaitGroup +} + +// New creates a new TxTracker +func New(journalPath string, journalTime time.Duration, chainConfig *params.ChainConfig, next *txpool.TxPool) *TxTracker { + pool := &TxTracker{ + all: make(map[common.Hash]*types.Transaction), + byAddr: make(map[common.Address]*legacypool.SortedMap), + signer: types.LatestSigner(chainConfig), + shutdownCh: make(chan struct{}), + pool: next, + } + if journalPath != "" { + pool.journal = newTxJournal(journalPath) + pool.rejournal = journalTime + } + return pool +} + +// Track adds a transaction to the tracked set. +// Note: blob-type transactions are ignored. +func (tracker *TxTracker) Track(tx *types.Transaction) { + tracker.TrackAll([]*types.Transaction{tx}) +} + +// TrackAll adds a list of transactions to the tracked set. +// Note: blob-type transactions are ignored. +func (tracker *TxTracker) TrackAll(txs []*types.Transaction) { + tracker.mu.Lock() + defer tracker.mu.Unlock() + + for _, tx := range txs { + if tx.Type() == types.BlobTxType { + continue + } + // If we're already tracking it, it's a no-op + if _, ok := tracker.all[tx.Hash()]; ok { + continue + } + addr, err := types.Sender(tracker.signer, tx) + if err != nil { // Ignore this tx + continue + } + tracker.all[tx.Hash()] = tx + if tracker.byAddr[addr] == nil { + tracker.byAddr[addr] = legacypool.NewSortedMap() + } + tracker.byAddr[addr].Put(tx) + + if tracker.journal != nil { + _ = tracker.journal.insert(tx) + } + } + localGauge.Update(int64(len(tracker.all))) +} + +// recheck checks and returns any transactions that needs to be resubmitted. +func (tracker *TxTracker) recheck(journalCheck bool) (resubmits []*types.Transaction, rejournal map[common.Address]types.Transactions) { + tracker.mu.Lock() + defer tracker.mu.Unlock() + + var ( + numStales = 0 + numOk = 0 + ) + for sender, txs := range tracker.byAddr { + // Wipe the stales + stales := txs.Forward(tracker.pool.Nonce(sender)) + for _, tx := range stales { + delete(tracker.all, tx.Hash()) + } + numStales += len(stales) + + // Check the non-stale + for _, tx := range txs.Flatten() { + if tracker.pool.Has(tx.Hash()) { + numOk++ + continue + } + resubmits = append(resubmits, tx) + } + } + + if journalCheck { // rejournal + rejournal = make(map[common.Address]types.Transactions) + for _, tx := range tracker.all { + addr, _ := types.Sender(tracker.signer, tx) + rejournal[addr] = append(rejournal[addr], tx) + } + // Sort them + for _, list := range rejournal { + // cmp(a, b) should return a negative number when a < b, + slices.SortFunc(list, func(a, b *types.Transaction) int { + return int(a.Nonce() - b.Nonce()) + }) + } + } + localGauge.Update(int64(len(tracker.all))) + log.Debug("Tx tracker status", "need-resubmit", len(resubmits), "stale", numStales, "ok", numOk) + return resubmits, rejournal +} + +// Start implements node.Lifecycle interface +// Start is called after all services have been constructed and the networking +// layer was also initialized to spawn any goroutines required by the service. +func (tracker *TxTracker) Start() error { + tracker.wg.Add(1) + go tracker.loop() + return nil +} + +// Stop implements node.Lifecycle interface +// Stop terminates all goroutines belonging to the service, blocking until they +// are all terminated. +func (tracker *TxTracker) Stop() error { + close(tracker.shutdownCh) + tracker.wg.Wait() + return nil +} + +func (tracker *TxTracker) loop() { + defer tracker.wg.Done() + + if tracker.journal != nil { + tracker.journal.load(func(transactions []*types.Transaction) []error { + tracker.TrackAll(transactions) + return nil + }) + defer tracker.journal.close() + } + var ( + lastJournal = time.Now() + timer = time.NewTimer(10 * time.Second) // Do initial check after 10 seconds, do rechecks more seldom. + ) + for { + select { + case <-tracker.shutdownCh: + return + case <-timer.C: + checkJournal := tracker.journal != nil && time.Since(lastJournal) > tracker.rejournal + resubmits, rejournal := tracker.recheck(checkJournal) + if len(resubmits) > 0 { + tracker.pool.Add(resubmits, false) + } + if checkJournal { + // Lock to prevent journal.rotate <-> journal.insert (via TrackAll) conflicts + tracker.mu.Lock() + lastJournal = time.Now() + if err := tracker.journal.rotate(rejournal); err != nil { + log.Warn("Transaction journal rotation failed", "err", err) + } + tracker.mu.Unlock() + } + timer.Reset(recheckInterval) + } + } +} diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 9ee0a69c0b..5ad0f5b0e0 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -132,7 +132,7 @@ type SubPool interface { // Add enqueues a batch of transactions into the pool if they are valid. Due // to the large transaction churn, add may postpone fully integrating the tx // to a later point to batch multiple ones together. - Add(txs []*types.Transaction, local bool, sync bool) []error + Add(txs []*types.Transaction, sync bool) []error // Pending retrieves all currently processable transactions, grouped by origin // account and sorted by nonce. @@ -162,9 +162,6 @@ type SubPool interface { // pending as well as queued transactions of this address, grouped by nonce. ContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) - // Locals retrieves the accounts currently considered local by the pool. - Locals() []common.Address - // Status returns the known status (unknown/pending/queued) of a transaction // identified by their hashes. Status(hash common.Hash) TxStatus diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 182706d63c..361dbe8b38 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -328,7 +328,7 @@ func (p *TxPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Pr // Add enqueues a batch of transactions into the pool if they are valid. Due // to the large transaction churn, add may postpone fully integrating the tx // to a later point to batch multiple ones together. -func (p *TxPool) Add(txs []*types.Transaction, local bool, sync bool) []error { +func (p *TxPool) Add(txs []*types.Transaction, sync bool) []error { // Split the input transactions between the subpools. It shouldn't really // happen that we receive merged batches, but better graceful than strange // errors. @@ -355,7 +355,7 @@ func (p *TxPool) Add(txs []*types.Transaction, local bool, sync bool) []error { // back the errors into the original sort order. errsets := make([][]error, len(p.subpools)) for i := 0; i < len(p.subpools); i++ { - errsets[i] = p.subpools[i].Add(txsets[i], local, sync) + errsets[i] = p.subpools[i].Add(txsets[i], sync) } errs := make([]error, len(txs)) for i, split := range splits { @@ -456,23 +456,6 @@ func (p *TxPool) ContentFrom(addr common.Address) ([]*types.Transaction, []*type return []*types.Transaction{}, []*types.Transaction{} } -// Locals retrieves the accounts currently considered local by the pool. -func (p *TxPool) Locals() []common.Address { - // Retrieve the locals from each subpool and deduplicate them - locals := make(map[common.Address]struct{}) - for _, subpool := range p.subpools { - for _, local := range subpool.Locals() { - locals[local] = struct{}{} - } - } - // Flatten and return the deduplicated local set - flat := make([]common.Address, 0, len(locals)) - for local := range locals { - flat = append(flat, local) - } - return flat -} - // Status returns the known status (unknown/pending/queued) of a transaction // identified by its hash. func (p *TxPool) Status(hash common.Hash) TxStatus { diff --git a/eth/api_backend.go b/eth/api_backend.go index 52ecd91789..66621190dd 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -272,7 +272,10 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri } func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { - return b.eth.txPool.Add([]*types.Transaction{signedTx}, true, false)[0] + if locals := b.eth.localTxTracker; locals != nil { + locals.Track(signedTx) + } + return b.eth.txPool.Add([]*types.Transaction{signedTx}, false)[0] } func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) { diff --git a/eth/backend.go b/eth/backend.go index a3aa0a7b9b..fea7e4e1fe 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -23,6 +23,7 @@ import ( "math/big" "runtime" "sync" + "time" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" @@ -35,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/core/txpool/legacypool" + "github.com/ethereum/go-ethereum/core/txpool/locals" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/downloader" @@ -67,9 +69,10 @@ type Config = ethconfig.Config // Ethereum implements the Ethereum full node service. type Ethereum struct { // core protocol objects - config *ethconfig.Config - txPool *txpool.TxPool - blockchain *core.BlockChain + config *ethconfig.Config + txPool *txpool.TxPool + localTxTracker *locals.TxTracker + blockchain *core.BlockChain handler *handler discmix *enode.FairMix @@ -237,6 +240,16 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } + + if !config.TxPool.NoLocals { + rejournal := config.TxPool.Rejournal + if rejournal < time.Second { + log.Warn("Sanitizing invalid txpool journal time", "provided", rejournal, "updated", time.Second) + rejournal = time.Second + } + eth.localTxTracker = locals.New(config.TxPool.Journal, rejournal, eth.blockchain.Config(), eth.txPool) + stack.RegisterLifecycle(eth.localTxTracker) + } // 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{ @@ -255,6 +268,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { eth.miner = miner.New(eth, config.Miner, eth.engine) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) + eth.miner.SetPrioAddresses(config.TxPool.Locals) eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil} if eth.APIBackend.allowUnprotectedTxs { diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index 9840d9c6ad..8fc3361192 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -115,7 +115,7 @@ func TestEth2AssembleBlock(t *testing.T) { if err != nil { t.Fatalf("error signing transaction, err=%v", err) } - ethservice.TxPool().Add([]*types.Transaction{tx}, true, true) + ethservice.TxPool().Add([]*types.Transaction{tx}, true) blockParams := engine.PayloadAttributes{ Timestamp: blocks[9].Time() + 5, } @@ -152,7 +152,7 @@ func TestEth2AssembleBlockWithAnotherBlocksTxs(t *testing.T) { // Put the 10th block's tx in the pool and produce a new block txs := blocks[9].Transactions() - api.eth.TxPool().Add(txs, false, true) + api.eth.TxPool().Add(txs, true) blockParams := engine.PayloadAttributes{ Timestamp: blocks[8].Time() + 5, } @@ -174,7 +174,7 @@ func TestEth2PrepareAndGetPayload(t *testing.T) { // Put the 10th block's tx in the pool and produce a new block txs := blocks[9].Transactions() - ethservice.TxPool().Add(txs, true, true) + ethservice.TxPool().Add(txs, true) blockParams := engine.PayloadAttributes{ Timestamp: blocks[8].Time() + 5, } @@ -294,7 +294,7 @@ func TestEth2NewBlock(t *testing.T) { statedb, _ := ethservice.BlockChain().StateAt(parent.Root()) nonce := statedb.GetNonce(testAddr) tx, _ := types.SignTx(types.NewContractCreation(nonce, new(big.Int), 1000000, big.NewInt(2*params.InitialBaseFee), logCode), types.LatestSigner(ethservice.BlockChain().Config()), testKey) - ethservice.TxPool().Add([]*types.Transaction{tx}, true, true) + ethservice.TxPool().Add([]*types.Transaction{tx}, true) execData, err := assembleWithTransactions(api, parent.Hash(), &engine.PayloadAttributes{ Timestamp: parent.Time() + 5, @@ -463,7 +463,7 @@ func TestFullAPI(t *testing.T) { statedb, _ := ethservice.BlockChain().StateAt(parent.Root) nonce := statedb.GetNonce(testAddr) tx, _ := types.SignTx(types.NewContractCreation(nonce, new(big.Int), 1000000, big.NewInt(2*params.InitialBaseFee), logCode), types.LatestSigner(ethservice.BlockChain().Config()), testKey) - ethservice.TxPool().Add([]*types.Transaction{tx}, true, false) + ethservice.TxPool().Add([]*types.Transaction{tx}, false) } setupBlocks(t, ethservice, 10, parent, callback, nil, nil) @@ -594,7 +594,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) { GasPrice: big.NewInt(2 * params.InitialBaseFee), Data: logCode, }) - ethservice.TxPool().Add([]*types.Transaction{tx}, false, true) + ethservice.TxPool().Add([]*types.Transaction{tx}, true) var ( params = engine.PayloadAttributes{ Timestamp: parent.Time + 1, @@ -1246,8 +1246,8 @@ func setupBodies(t *testing.T) (*node.Node, *eth.Ethereum, []*types.Block) { // Create tx to trigger deposit generator. tx2, _ = types.SignTx(types.NewTransaction(statedb.GetNonce(testAddr)+1, ethservice.APIBackend.ChainConfig().DepositContractAddress, new(big.Int), 500000, big.NewInt(2*params.InitialBaseFee), nil), types.LatestSigner(ethservice.BlockChain().Config()), testKey) ) - ethservice.TxPool().Add([]*types.Transaction{tx1}, false, false) - ethservice.TxPool().Add([]*types.Transaction{tx2}, false, false) + ethservice.TxPool().Add([]*types.Transaction{tx1}, false) + ethservice.TxPool().Add([]*types.Transaction{tx2}, false) } // Make some withdrawals to include. @@ -1637,7 +1637,7 @@ func TestWitnessCreationAndConsumption(t *testing.T) { // Put the 10th block's tx in the pool and produce a new block txs := blocks[9].Transactions() - ethservice.TxPool().Add(txs, true, true) + ethservice.TxPool().Add(txs, true) blockParams := engine.PayloadAttributes{ Timestamp: blocks[8].Time() + 5, Withdrawals: make([]*types.Withdrawal, 0), diff --git a/eth/catalyst/simulated_beacon_test.go b/eth/catalyst/simulated_beacon_test.go index 79d9ba738e..ea35482896 100644 --- a/eth/catalyst/simulated_beacon_test.go +++ b/eth/catalyst/simulated_beacon_test.go @@ -18,6 +18,7 @@ package catalyst import ( "context" + "fmt" "math/big" "testing" "time" @@ -143,9 +144,14 @@ func TestSimulatedBeaconSendWithdrawals(t *testing.T) { // Tests that zero-period dev mode can handle a lot of simultaneous // transactions/withdrawals func TestOnDemandSpam(t *testing.T) { + // This test is flaky, due to various causes, and the root cause is synchronicity. + // We have optimistic timeouts here and there in the simulated becaon and the worker. + // This test typically fails on 32-bit windows appveyor. + t.Skip("flaky test") var ( withdrawals []types.Withdrawal - txs = make(map[common.Hash]*types.Transaction) + txCount = 20000 + wxCount = 20 testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") testAddr = crypto.PubkeyToAddress(testKey.PublicKey) gasLimit uint64 = 10_000_000 @@ -160,7 +166,7 @@ func TestOnDemandSpam(t *testing.T) { defer sub.Unsubscribe() // generate some withdrawals - for i := 0; i < 20; i++ { + for i := 0; i < wxCount; i++ { withdrawals = append(withdrawals, types.Withdrawal{Index: uint64(i)}) if err := mock.withdrawals.add(&withdrawals[i]); err != nil { t.Fatal("addWithdrawal failed", err) @@ -168,37 +174,37 @@ func TestOnDemandSpam(t *testing.T) { } // 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) + go func() { + for i := 0; i < txCount; 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 { + panic(fmt.Sprintf("error signing transaction: %v", err)) + } + if err := eth.TxPool().Add([]*types.Transaction{tx}, false)[0]; err != nil { + panic(fmt.Sprintf("error adding txs to pool: %v", 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 + includedTxs int + includedWxs int + abort = time.NewTimer(10 * time.Second) ) + defer abort.Stop() for { select { case ev := <-chainHeadCh: block := eth.BlockChain().GetBlock(ev.Header.Hash(), ev.Header.Number.Uint64()) - for _, itx := range block.Transactions() { - includedTxs[itx.Hash()] = struct{}{} - } - for _, iwx := range block.Withdrawals() { - includedWxs = append(includedWxs, iwx.Index) - } + includedTxs += len(block.Transactions()) + includedWxs += len(block.Withdrawals()) // 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) { + if includedTxs == txCount && includedWxs == wxCount { 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)) + abort.Reset(10 * time.Second) + case <-abort.C: + t.Fatalf("timed out without including all withdrawals/txs: have txs %d, want %d, have wxs %d, want %d", + includedTxs, txCount, includedWxs, wxCount) } } } diff --git a/eth/handler.go b/eth/handler.go index 8893920497..6ac890902b 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -68,7 +68,7 @@ type txPool interface { Get(hash common.Hash) *types.Transaction // Add should add the given transactions to the pool. - Add(txs []*types.Transaction, local bool, sync bool) []error + Add(txs []*types.Transaction, sync bool) []error // Pending should return pending transactions. // The slice should be modifiable by the caller. @@ -189,7 +189,7 @@ func newHandler(config *handlerConfig) (*handler, error) { return p.RequestTxs(hashes) } addTxs := func(txs []*types.Transaction) []error { - return h.txpool.Add(txs, false, false) + return h.txpool.Add(txs, false) } h.txFetcher = fetcher.NewTxFetcher(h.txpool.Has, addTxs, fetchTx, h.removePeer) return h, nil diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index 622880b097..8d572ca966 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -299,8 +299,8 @@ func testSendTransactions(t *testing.T, protocol uint) { tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) insert[nonce] = tx } - go handler.txpool.Add(insert, false, false) // Need goroutine to not block on feed - time.Sleep(250 * time.Millisecond) // Wait until tx events get out of the system (can't use events, tx broadcaster races with peer join) + go handler.txpool.Add(insert, false) // Need goroutine to not block on feed + time.Sleep(250 * time.Millisecond) // Wait until tx events get out of the system (can't use events, tx broadcaster races with peer join) // Create a source handler to send messages through and a sink peer to receive them p2pSrc, p2pSink := p2p.MsgPipe() @@ -419,7 +419,7 @@ func testTransactionPropagation(t *testing.T, protocol uint) { tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) txs[nonce] = tx } - source.txpool.Add(txs, false, false) + source.txpool.Add(txs, false) // Iterate through all the sinks and ensure they all got the transactions for i := range sinks { diff --git a/eth/handler_test.go b/eth/handler_test.go index b63d3e8592..d5d46a3c65 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -80,7 +80,7 @@ func (p *testTxPool) Get(hash common.Hash) *types.Transaction { // Add appends a batch of transactions to the pool, and notifies any // listeners if the addition channel is non nil -func (p *testTxPool) Add(txs []*types.Transaction, local bool, sync bool) []error { +func (p *testTxPool) Add(txs []*types.Transaction, sync bool) []error { p.lock.Lock() defer p.lock.Unlock() diff --git a/miner/miner.go b/miner/miner.go index 9892c08ed6..595ef8081c 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -70,6 +70,7 @@ type Miner struct { chainConfig *params.ChainConfig engine consensus.Engine txpool *txpool.TxPool + prio []common.Address // A list of senders to prioritize chain *core.BlockChain pending *pending pendingMu sync.Mutex // Lock protects the pending block @@ -109,6 +110,13 @@ func (miner *Miner) SetExtra(extra []byte) error { return nil } +// SetPrioAddresses sets a list of addresses to prioritize for transaction inclusion. +func (miner *Miner) SetPrioAddresses(prio []common.Address) { + miner.confMu.Lock() + miner.prio = prio + miner.confMu.Unlock() +} + // SetGasCeil sets the gaslimit to strive for when mining blocks post 1559. // For pre-1559 blocks, it sets the ceiling. func (miner *Miner) SetGasCeil(ceil uint64) { diff --git a/miner/payload_building_test.go b/miner/payload_building_test.go index e5eb0297a1..307024c6bb 100644 --- a/miner/payload_building_test.go +++ b/miner/payload_building_test.go @@ -138,7 +138,7 @@ 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) + backend.txPool.Add(pendingTxs, true) w := New(backend, testConfig, engine) return w, backend } diff --git a/miner/worker.go b/miner/worker.go index f8f4bae833..16ac7de9a9 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -427,6 +427,7 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment) error { miner.confMu.RLock() tip := miner.config.GasPrice + prio := miner.prio miner.confMu.RUnlock() // Retrieve the pending transactions pre-filtered by the 1559/4844 dynamic fees @@ -446,31 +447,31 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment) pendingBlobTxs := miner.txpool.Pending(filter) // Split the pending transactions into locals and remotes. - localPlainTxs, remotePlainTxs := make(map[common.Address][]*txpool.LazyTransaction), pendingPlainTxs - localBlobTxs, remoteBlobTxs := make(map[common.Address][]*txpool.LazyTransaction), pendingBlobTxs + prioPlainTxs, normalPlainTxs := make(map[common.Address][]*txpool.LazyTransaction), pendingPlainTxs + prioBlobTxs, normalBlobTxs := make(map[common.Address][]*txpool.LazyTransaction), pendingBlobTxs - for _, account := range miner.txpool.Locals() { - if txs := remotePlainTxs[account]; len(txs) > 0 { - delete(remotePlainTxs, account) - localPlainTxs[account] = txs + for _, account := range prio { + if txs := normalPlainTxs[account]; len(txs) > 0 { + delete(normalPlainTxs, account) + prioPlainTxs[account] = txs } - if txs := remoteBlobTxs[account]; len(txs) > 0 { - delete(remoteBlobTxs, account) - localBlobTxs[account] = txs + if txs := normalBlobTxs[account]; len(txs) > 0 { + delete(normalBlobTxs, account) + prioBlobTxs[account] = txs } } // Fill the block with all available pending transactions. - if len(localPlainTxs) > 0 || len(localBlobTxs) > 0 { - plainTxs := newTransactionsByPriceAndNonce(env.signer, localPlainTxs, env.header.BaseFee) - blobTxs := newTransactionsByPriceAndNonce(env.signer, localBlobTxs, env.header.BaseFee) + if len(prioPlainTxs) > 0 || len(prioBlobTxs) > 0 { + plainTxs := newTransactionsByPriceAndNonce(env.signer, prioPlainTxs, env.header.BaseFee) + blobTxs := newTransactionsByPriceAndNonce(env.signer, prioBlobTxs, env.header.BaseFee) if err := miner.commitTransactions(env, plainTxs, blobTxs, interrupt); err != nil { return err } } - if len(remotePlainTxs) > 0 || len(remoteBlobTxs) > 0 { - plainTxs := newTransactionsByPriceAndNonce(env.signer, remotePlainTxs, env.header.BaseFee) - blobTxs := newTransactionsByPriceAndNonce(env.signer, remoteBlobTxs, env.header.BaseFee) + if len(normalPlainTxs) > 0 || len(normalBlobTxs) > 0 { + plainTxs := newTransactionsByPriceAndNonce(env.signer, normalPlainTxs, env.header.BaseFee) + blobTxs := newTransactionsByPriceAndNonce(env.signer, normalBlobTxs, env.header.BaseFee) if err := miner.commitTransactions(env, plainTxs, blobTxs, interrupt); err != nil { return err From 59d2eec9fc5177953eb7798b8fa5c9da5ebf95b5 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 4 Feb 2025 18:10:40 +0100 Subject: [PATCH 095/940] core/txpool/blobpool: fix incorrect arguments in test (#31127) Fixes the linter on master which was broken by https://github.com/ethereum/go-ethereum/pull/30559 --- core/txpool/blobpool/blobpool_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 0187e8d9a0..88d68eb307 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -1108,7 +1108,7 @@ func TestChangingSlotterSize(t *testing.T) { // Try to add the big blob tx. In the initial iteration it should overflow // the pool. On the subsequent iteration it should be accepted. - errs := pool.Add([]*types.Transaction{tx3}, false, true) + errs := pool.Add([]*types.Transaction{tx3}, true) if _, ok := pool.index[addr3]; ok && maxBlobs == 6 { t.Errorf("expected insert of oversized blob tx to fail: blobs=24, maxBlobs=%d, err=%v", maxBlobs, errs[0]) } else if !ok && maxBlobs == 10 { From c4ad459bd2d85137e26d91144f733bbb938de12d Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:43:18 -0700 Subject: [PATCH 096/940] consensus/misc/eip4844: use head's target blobs, not parent (#31101) A clarification was made to EIP-7691 stating that at the fork boundary it is required to use the target blob count associated with the head block, rather than the parent as implemented here. See for more: https://github.com/ethereum/EIPs/pull/9249 --- cmd/evm/internal/t8ntool/execution.go | 2 +- consensus/misc/eip4844/eip4844.go | 6 +++--- consensus/misc/eip4844/eip4844_test.go | 5 ++++- core/chain_makers.go | 2 +- core/state_processor_test.go | 2 +- eth/gasprice/feehistory.go | 2 +- eth/tracers/internal/tracetest/util.go | 5 +++-- internal/ethapi/simulate.go | 2 +- miner/worker.go | 2 +- 9 files changed, 16 insertions(+), 12 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 9332f4901b..1613521b0d 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -194,11 +194,11 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, ExcessBlobGas: pre.Env.ParentExcessBlobGas, BlobGasUsed: pre.Env.ParentBlobGasUsed, } - excessBlobGas = eip4844.CalcExcessBlobGas(chainConfig, parent) header := &types.Header{ Time: pre.Env.Timestamp, ExcessBlobGas: &excessBlobGas, } + excessBlobGas = eip4844.CalcExcessBlobGas(chainConfig, parent, header) vmContext.BlobBaseFee = eip4844.CalcBlobFee(chainConfig, header) } } diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index 1d76b21b30..148ea60274 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -50,7 +50,7 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade return fmt.Errorf("blob gas used %d not a multiple of blob gas per blob %d", header.BlobGasUsed, params.BlobTxBlobGasPerBlob) } // Verify the excessBlobGas is correct based on the parent header - expectedExcessBlobGas := CalcExcessBlobGas(config, parent) + expectedExcessBlobGas := CalcExcessBlobGas(config, parent, header) if *header.ExcessBlobGas != expectedExcessBlobGas { return fmt.Errorf("invalid excessBlobGas: have %d, want %d", *header.ExcessBlobGas, expectedExcessBlobGas) } @@ -59,9 +59,9 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade // CalcExcessBlobGas calculates the excess blob gas after applying the set of // blobs on top of the excess blob gas. -func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header) uint64 { +func CalcExcessBlobGas(config *params.ChainConfig, parent, header *types.Header) uint64 { var ( - targetGas = uint64(targetBlobsPerBlock(config, parent.Time)) * params.BlobTxBlobGasPerBlob + targetGas = uint64(targetBlobsPerBlock(config, header.Time)) * params.BlobTxBlobGasPerBlob parentExcessBlobGas uint64 parentBlobGasUsed uint64 ) diff --git a/consensus/misc/eip4844/eip4844_test.go b/consensus/misc/eip4844/eip4844_test.go index 839ea8df22..7d221aa96e 100644 --- a/consensus/misc/eip4844/eip4844_test.go +++ b/consensus/misc/eip4844/eip4844_test.go @@ -57,12 +57,15 @@ func TestCalcExcessBlobGas(t *testing.T) { } for i, tt := range tests { blobGasUsed := uint64(tt.blobs) * params.BlobTxBlobGasPerBlob + head := &types.Header{ + Time: *config.CancunTime, + } parent := &types.Header{ Time: *config.CancunTime, ExcessBlobGas: &tt.excess, BlobGasUsed: &blobGasUsed, } - result := CalcExcessBlobGas(config, parent) + result := CalcExcessBlobGas(config, parent, head) if result != tt.want { t.Errorf("test %d: excess blob gas mismatch: have %v, want %v", i, result, tt.want) } diff --git a/core/chain_makers.go b/core/chain_makers.go index 19f433d7b0..2ade70f175 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -600,7 +600,7 @@ func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engi } } if cm.config.IsCancun(header.Number, header.Time) { - excessBlobGas := eip4844.CalcExcessBlobGas(cm.config, parent.Header()) + excessBlobGas := eip4844.CalcExcessBlobGas(cm.config, parent.Header(), header) header.ExcessBlobGas = &excessBlobGas header.BlobGasUsed = new(uint64) header.ParentBeaconRoot = new(common.Hash) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 7d62e90ad4..b0258ae37b 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -407,7 +407,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr } header.Root = common.BytesToHash(hasher.Sum(nil)) if config.IsCancun(header.Number, header.Time) { - excess := eip4844.CalcExcessBlobGas(config, parent.Header()) + excess := eip4844.CalcExcessBlobGas(config, parent.Header(), header) used := uint64(nBlobs * params.BlobTxBlobGasPerBlob) header.ExcessBlobGas = &excess header.BlobGasUsed = &used diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 697263f20b..94fc5b35f9 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -97,7 +97,7 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { // Fill in blob base fee and next blob base fee. if excessBlobGas := bf.header.ExcessBlobGas; excessBlobGas != nil { bf.results.blobBaseFee = eip4844.CalcBlobFee(config, bf.header) - excess := eip4844.CalcExcessBlobGas(config, bf.header) + excess := eip4844.CalcExcessBlobGas(config, bf.header, bf.header) next := &types.Header{Number: bf.header.Number, Time: bf.header.Time, ExcessBlobGas: &excess} bf.results.nextBlobBaseFee = eip4844.CalcBlobFee(config, next) } else { diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go index e29144e04e..97896213b4 100644 --- a/eth/tracers/internal/tracetest/util.go +++ b/eth/tracers/internal/tracetest/util.go @@ -54,8 +54,9 @@ func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext { } if genesis.ExcessBlobGas != nil && genesis.BlobGasUsed != nil { - excess := eip4844.CalcExcessBlobGas(genesis.Config, genesis.ToBlock().Header()) - header := &types.Header{ExcessBlobGas: &excess, Number: genesis.Config.LondonBlock, Time: *genesis.Config.CancunTime} + header := &types.Header{Number: genesis.Config.LondonBlock, Time: *genesis.Config.CancunTime} + excess := eip4844.CalcExcessBlobGas(genesis.Config, header, genesis.ToBlock().Header()) + header.ExcessBlobGas = &excess context.BlobBaseFee = eip4844.CalcBlobFee(genesis.Config, header) } return context diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index d364b80485..0262f69c02 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -159,7 +159,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if sim.chainConfig.IsCancun(header.Number, header.Time) { var excess uint64 if sim.chainConfig.IsCancun(parent.Number, parent.Time) { - excess = eip4844.CalcExcessBlobGas(sim.chainConfig, parent) + excess = eip4844.CalcExcessBlobGas(sim.chainConfig, parent, header) } header.ExcessBlobGas = &excess } diff --git a/miner/worker.go b/miner/worker.go index 16ac7de9a9..6ec23ec624 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -210,7 +210,7 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir if miner.chainConfig.IsCancun(header.Number, header.Time) { var excessBlobGas uint64 if miner.chainConfig.IsCancun(parent.Number, parent.Time) { - excessBlobGas = eip4844.CalcExcessBlobGas(miner.chainConfig, parent) + excessBlobGas = eip4844.CalcExcessBlobGas(miner.chainConfig, parent, header) } header.BlobGasUsed = new(uint64) header.ExcessBlobGas = &excessBlobGas From ed1d46b3d31f250e5385a4b8b8f97293acf8adee Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 5 Feb 2025 10:35:03 +0100 Subject: [PATCH 097/940] consensus/misc/eip4844: more changes for blob gas calculation (#31128) This PR changes the signature of `CalcExcessBlobGas` to take in just the header timestamp instead of the whole object. It also adds a sanity check for the parent->child block order to `VerifyEIP4844Header`. --- cmd/evm/internal/t8ntool/execution.go | 2 +- consensus/misc/eip4844/eip4844.go | 9 ++++++--- consensus/misc/eip4844/eip4844_test.go | 8 ++------ core/chain_makers.go | 7 ++++--- core/state_processor_test.go | 2 +- eth/gasprice/feehistory.go | 2 +- eth/tracers/internal/tracetest/util.go | 2 +- internal/ethapi/simulate.go | 2 +- miner/worker.go | 2 +- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 1613521b0d..793b2d425b 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -198,7 +198,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, Time: pre.Env.Timestamp, ExcessBlobGas: &excessBlobGas, } - excessBlobGas = eip4844.CalcExcessBlobGas(chainConfig, parent, header) + excessBlobGas = eip4844.CalcExcessBlobGas(chainConfig, parent, header.Time) vmContext.BlobBaseFee = eip4844.CalcBlobFee(chainConfig, header) } } diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index 148ea60274..4a2754b55c 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -34,6 +34,9 @@ var ( // if the current block contains no transactions, the excessBlobGas is updated // accordingly. func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Header) error { + if header.Number.Uint64() != parent.Number.Uint64()+1 { + panic("bad header pair") + } // Verify the header is not malformed if header.ExcessBlobGas == nil { return errors.New("header is missing excessBlobGas") @@ -50,7 +53,7 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade return fmt.Errorf("blob gas used %d not a multiple of blob gas per blob %d", header.BlobGasUsed, params.BlobTxBlobGasPerBlob) } // Verify the excessBlobGas is correct based on the parent header - expectedExcessBlobGas := CalcExcessBlobGas(config, parent, header) + expectedExcessBlobGas := CalcExcessBlobGas(config, parent, header.Time) if *header.ExcessBlobGas != expectedExcessBlobGas { return fmt.Errorf("invalid excessBlobGas: have %d, want %d", *header.ExcessBlobGas, expectedExcessBlobGas) } @@ -59,9 +62,8 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade // CalcExcessBlobGas calculates the excess blob gas after applying the set of // blobs on top of the excess blob gas. -func CalcExcessBlobGas(config *params.ChainConfig, parent, header *types.Header) uint64 { +func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTimestamp uint64) uint64 { var ( - targetGas = uint64(targetBlobsPerBlock(config, header.Time)) * params.BlobTxBlobGasPerBlob parentExcessBlobGas uint64 parentBlobGasUsed uint64 ) @@ -70,6 +72,7 @@ func CalcExcessBlobGas(config *params.ChainConfig, parent, header *types.Header) parentBlobGasUsed = *parent.BlobGasUsed } excessBlobGas := parentExcessBlobGas + parentBlobGasUsed + targetGas := uint64(targetBlobsPerBlock(config, headTimestamp)) * params.BlobTxBlobGasPerBlob if excessBlobGas < targetGas { return 0 } diff --git a/consensus/misc/eip4844/eip4844_test.go b/consensus/misc/eip4844/eip4844_test.go index 7d221aa96e..f4e3cb3d9a 100644 --- a/consensus/misc/eip4844/eip4844_test.go +++ b/consensus/misc/eip4844/eip4844_test.go @@ -57,15 +57,11 @@ func TestCalcExcessBlobGas(t *testing.T) { } for i, tt := range tests { blobGasUsed := uint64(tt.blobs) * params.BlobTxBlobGasPerBlob - head := &types.Header{ - Time: *config.CancunTime, - } - parent := &types.Header{ - Time: *config.CancunTime, + header := &types.Header{ ExcessBlobGas: &tt.excess, BlobGasUsed: &blobGasUsed, } - result := CalcExcessBlobGas(config, parent, head) + result := CalcExcessBlobGas(config, header, *config.CancunTime) if result != tt.want { t.Errorf("test %d: excess blob gas mismatch: have %v, want %v", i, result, tt.want) } diff --git a/core/chain_makers.go b/core/chain_makers.go index 2ade70f175..8d09390b72 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -582,25 +582,26 @@ func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n 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 + parentHeader := parent.Header() header := &types.Header{ Root: state.IntermediateRoot(cm.config.IsEIP158(parent.Number())), ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), - Difficulty: engine.CalcDifficulty(cm, time, parent.Header()), + Difficulty: engine.CalcDifficulty(cm, time, parentHeader), GasLimit: parent.GasLimit(), Number: new(big.Int).Add(parent.Number(), common.Big1), Time: time, } if cm.config.IsLondon(header.Number) { - header.BaseFee = eip1559.CalcBaseFee(cm.config, parent.Header()) + header.BaseFee = eip1559.CalcBaseFee(cm.config, parentHeader) if !cm.config.IsLondon(parent.Number()) { parentGasLimit := parent.GasLimit() * cm.config.ElasticityMultiplier() header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) } } if cm.config.IsCancun(header.Number, header.Time) { - excessBlobGas := eip4844.CalcExcessBlobGas(cm.config, parent.Header(), header) + excessBlobGas := eip4844.CalcExcessBlobGas(cm.config, parentHeader, time) header.ExcessBlobGas = &excessBlobGas header.BlobGasUsed = new(uint64) header.ParentBeaconRoot = new(common.Hash) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index b0258ae37b..a6ca2781f8 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -407,7 +407,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr } header.Root = common.BytesToHash(hasher.Sum(nil)) if config.IsCancun(header.Number, header.Time) { - excess := eip4844.CalcExcessBlobGas(config, parent.Header(), header) + excess := eip4844.CalcExcessBlobGas(config, parent.Header(), header.Time) used := uint64(nBlobs * params.BlobTxBlobGasPerBlob) header.ExcessBlobGas = &excess header.BlobGasUsed = &used diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 94fc5b35f9..fe84950c50 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -97,7 +97,7 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { // Fill in blob base fee and next blob base fee. if excessBlobGas := bf.header.ExcessBlobGas; excessBlobGas != nil { bf.results.blobBaseFee = eip4844.CalcBlobFee(config, bf.header) - excess := eip4844.CalcExcessBlobGas(config, bf.header, bf.header) + excess := eip4844.CalcExcessBlobGas(config, bf.header, bf.header.Time) next := &types.Header{Number: bf.header.Number, Time: bf.header.Time, ExcessBlobGas: &excess} bf.results.nextBlobBaseFee = eip4844.CalcBlobFee(config, next) } else { diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go index 97896213b4..524a396d5c 100644 --- a/eth/tracers/internal/tracetest/util.go +++ b/eth/tracers/internal/tracetest/util.go @@ -55,7 +55,7 @@ func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext { if genesis.ExcessBlobGas != nil && genesis.BlobGasUsed != nil { header := &types.Header{Number: genesis.Config.LondonBlock, Time: *genesis.Config.CancunTime} - excess := eip4844.CalcExcessBlobGas(genesis.Config, header, genesis.ToBlock().Header()) + excess := eip4844.CalcExcessBlobGas(genesis.Config, header, genesis.Timestamp) header.ExcessBlobGas = &excess context.BlobBaseFee = eip4844.CalcBlobFee(genesis.Config, header) } diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 0262f69c02..c461b1f0a1 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -159,7 +159,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if sim.chainConfig.IsCancun(header.Number, header.Time) { var excess uint64 if sim.chainConfig.IsCancun(parent.Number, parent.Time) { - excess = eip4844.CalcExcessBlobGas(sim.chainConfig, parent, header) + excess = eip4844.CalcExcessBlobGas(sim.chainConfig, parent, header.Time) } header.ExcessBlobGas = &excess } diff --git a/miner/worker.go b/miner/worker.go index 6ec23ec624..2c54421196 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -210,7 +210,7 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir if miner.chainConfig.IsCancun(header.Number, header.Time) { var excessBlobGas uint64 if miner.chainConfig.IsCancun(parent.Number, parent.Time) { - excessBlobGas = eip4844.CalcExcessBlobGas(miner.chainConfig, parent, header) + excessBlobGas = eip4844.CalcExcessBlobGas(miner.chainConfig, parent, timestamp) } header.BlobGasUsed = new(uint64) header.ExcessBlobGas = &excessBlobGas From aaaf01d71232d1b7da5ab2ae9258f7fb9f22b1bf Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:58:25 +0100 Subject: [PATCH 098/940] core/tracing: state journal wrapper (#30441) Here we add some more changes for live tracing API v1.1: - Hook `OnSystemCallStartV2` was introduced with `VMContext` as parameter. - Hook `OnBlockHashRead` was introduced. - `GetCodeHash` was added to the state interface - The new `WrapWithJournal` construction helps with tracking EVM reverts in the tracer. --------- Co-authored-by: Felix Lange --- cmd/evm/internal/t8ntool/execution.go | 2 +- core/genesis.go | 4 +- core/state/statedb.go | 2 +- core/state/statedb_fuzz_test.go | 2 +- core/state/statedb_hooked.go | 11 +- core/state/statedb_hooked_test.go | 4 +- core/state/statedb_test.go | 6 +- core/state_transition.go | 4 +- core/tracing/CHANGELOG.md | 47 +++ .../gen_balance_change_reason_stringer.go | 5 +- core/tracing/hooks.go | 47 +++ core/tracing/journal.go | 237 +++++++++++++ core/tracing/journal_test.go | 335 ++++++++++++++++++ core/txpool/blobpool/blobpool_test.go | 8 +- core/txpool/legacypool/legacypool_test.go | 6 +- core/verkle_witness_test.go | 3 +- core/vm/evm.go | 4 +- core/vm/instructions.go | 3 + core/vm/interface.go | 2 +- core/vm/runtime/runtime_test.go | 2 +- eth/tracers/live/noop.go | 3 + internal/ethapi/override/override.go | 2 +- tests/state_test_util.go | 2 +- 23 files changed, 709 insertions(+), 32 deletions(-) create mode 100644 core/tracing/journal.go create mode 100644 core/tracing/journal_test.go diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 793b2d425b..16c8808360 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -419,7 +419,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB statedb, _ := state.New(types.EmptyRootHash, sdb) for addr, a := range accounts { statedb.SetCode(addr, a.Code) - statedb.SetNonce(addr, a.Nonce) + statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeGenesis) statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceIncreaseGenesisBalance) for k, v := range a.Storage { statedb.SetState(addr, k, v) diff --git a/core/genesis.go b/core/genesis.go index 8f71f9ef1e..8546f4e37e 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -154,7 +154,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance) } statedb.SetCode(addr, account.Code) - statedb.SetNonce(addr, account.Nonce) + statedb.SetNonce(addr, account.Nonce, tracing.NonceChangeGenesis) for key, value := range account.Storage { statedb.SetState(addr, key, value) } @@ -180,7 +180,7 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, e statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance) } statedb.SetCode(addr, account.Code) - statedb.SetNonce(addr, account.Nonce) + statedb.SetNonce(addr, account.Nonce, tracing.NonceChangeGenesis) for key, value := range account.Storage { statedb.SetState(addr, key, value) } diff --git a/core/state/statedb.go b/core/state/statedb.go index 0310ee6973..efafdc1aa2 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -432,7 +432,7 @@ func (s *StateDB) SetBalance(addr common.Address, amount *uint256.Int, reason tr } } -func (s *StateDB) SetNonce(addr common.Address, nonce uint64) { +func (s *StateDB) SetNonce(addr common.Address, nonce uint64, reason tracing.NonceChangeReason) { stateObject := s.getOrNewStateObject(addr) if stateObject != nil { stateObject.SetNonce(nonce) diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go index ed99cf687c..2923a2c224 100644 --- a/core/state/statedb_fuzz_test.go +++ b/core/state/statedb_fuzz_test.go @@ -69,7 +69,7 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction { name: "SetNonce", fn: func(a testAction, s *StateDB) { - s.SetNonce(addr, uint64(a.args[0])) + s.SetNonce(addr, uint64(a.args[0]), tracing.NonceChangeUnspecified) }, args: make([]int64, 1), }, diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 25d823cc87..a2fdfe9a21 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -179,10 +179,13 @@ func (s *hookedStateDB) AddBalance(addr common.Address, amount *uint256.Int, rea return prev } -func (s *hookedStateDB) SetNonce(address common.Address, nonce uint64) { - s.inner.SetNonce(address, nonce) - if s.hooks.OnNonceChange != nil { - s.hooks.OnNonceChange(address, nonce-1, nonce) +func (s *hookedStateDB) SetNonce(address common.Address, nonce uint64, reason tracing.NonceChangeReason) { + prev := s.inner.GetNonce(address) + s.inner.SetNonce(address, nonce, reason) + if s.hooks.OnNonceChangeV2 != nil { + s.hooks.OnNonceChangeV2(address, prev, nonce, reason) + } else if s.hooks.OnNonceChange != nil { + s.hooks.OnNonceChange(address, prev, nonce) } } diff --git a/core/state/statedb_hooked_test.go b/core/state/statedb_hooked_test.go index 874a275993..ce42e96409 100644 --- a/core/state/statedb_hooked_test.go +++ b/core/state/statedb_hooked_test.go @@ -85,7 +85,7 @@ func TestHooks(t *testing.T) { var wants = []string{ "0xaa00000000000000000000000000000000000000.balance: 0->100 (BalanceChangeUnspecified)", "0xaa00000000000000000000000000000000000000.balance: 100->50 (BalanceChangeTransfer)", - "0xaa00000000000000000000000000000000000000.nonce: 1336->1337", + "0xaa00000000000000000000000000000000000000.nonce: 0->1337", "0xaa00000000000000000000000000000000000000.code: (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) ->0x1325 (0xa12ae05590de0c93a00bc7ac773c2fdb621e44f814985e72194f921c0050f728)", "0xaa00000000000000000000000000000000000000.storage slot 0x0000000000000000000000000000000000000000000000000000000000000001: 0x0000000000000000000000000000000000000000000000000000000000000000 ->0x0000000000000000000000000000000000000000000000000000000000000011", "0xaa00000000000000000000000000000000000000.storage slot 0x0000000000000000000000000000000000000000000000000000000000000001: 0x0000000000000000000000000000000000000000000000000000000000000011 ->0x0000000000000000000000000000000000000000000000000000000000000022", @@ -113,7 +113,7 @@ func TestHooks(t *testing.T) { }) sdb.AddBalance(common.Address{0xaa}, uint256.NewInt(100), tracing.BalanceChangeUnspecified) sdb.SubBalance(common.Address{0xaa}, uint256.NewInt(50), tracing.BalanceChangeTransfer) - sdb.SetNonce(common.Address{0xaa}, 1337) + sdb.SetNonce(common.Address{0xaa}, 1337, tracing.NonceChangeGenesis) sdb.SetCode(common.Address{0xaa}, []byte{0x13, 37}) sdb.SetState(common.Address{0xaa}, common.HexToHash("0x01"), common.HexToHash("0x11")) sdb.SetState(common.Address{0xaa}, common.HexToHash("0x01"), common.HexToHash("0x22")) diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 67eb9cbdc6..e740c64faa 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -60,7 +60,7 @@ func TestUpdateLeaks(t *testing.T) { for i := byte(0); i < 255; i++ { addr := common.BytesToAddress([]byte{i}) state.AddBalance(addr, uint256.NewInt(uint64(11*i)), tracing.BalanceChangeUnspecified) - state.SetNonce(addr, uint64(42*i)) + state.SetNonce(addr, uint64(42*i), tracing.NonceChangeUnspecified) if i%2 == 0 { state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i})) } @@ -95,7 +95,7 @@ func TestIntermediateLeaks(t *testing.T) { modify := func(state *StateDB, addr common.Address, i, tweak byte) { state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak)), tracing.BalanceChangeUnspecified) - state.SetNonce(addr, uint64(42*i+tweak)) + state.SetNonce(addr, uint64(42*i+tweak), tracing.NonceChangeUnspecified) if i%2 == 0 { state.SetState(addr, common.Hash{i, i, i, 0}, common.Hash{}) state.SetState(addr, common.Hash{i, i, i, tweak}, common.Hash{i, i, i, i, tweak}) @@ -357,7 +357,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { { name: "SetNonce", fn: func(a testAction, s *StateDB) { - s.SetNonce(addr, uint64(a.args[0])) + s.SetNonce(addr, uint64(a.args[0]), tracing.NonceChangeUnspecified) }, args: make([]int64, 1), }, diff --git a/core/state_transition.go b/core/state_transition.go index e9c88eaedf..e7edd76ced 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -487,7 +487,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, value) } else { // Increment the nonce for the next transaction. - st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1) + st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1, tracing.NonceChangeEoACall) // Apply EIP-7702 authorizations. if msg.SetCodeAuthorizations != nil { @@ -602,7 +602,7 @@ func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization) } // Update nonce and account code. - st.state.SetNonce(authority, auth.Nonce+1) + st.state.SetNonce(authority, auth.Nonce+1, tracing.NonceChangeAuthorization) if auth.Address == (common.Address{}) { // Delegation to zero address means clear. st.state.SetCode(authority, nil) diff --git a/core/tracing/CHANGELOG.md b/core/tracing/CHANGELOG.md index 270e0a30bf..a14e123d99 100644 --- a/core/tracing/CHANGELOG.md +++ b/core/tracing/CHANGELOG.md @@ -4,6 +4,53 @@ All notable changes to the tracing interface will be documented in this file. ## [Unreleased] +The tracing interface has been extended with backwards-compatible changes to support more use-cases and simplify tracer code. The most notable change is a state journaling library which emits reverse events when a call is reverted. + +### Deprecated methods + +- `OnSystemCallStart()`: This hook is deprecated in favor of `OnSystemCallStartV2(vm *VMContext)`. +- `OnNonceChange(addr common.Address, prev, new uint64)`: This hook is deprecated in favor of `OnNonceChangeV2(addr common.Address, prev, new uint64, reason NonceChangeReason)`. + +### New methods + +- `OnBlockHashRead(blockNum uint64, hash common.Hash)`: This hook is called when a block hash is read by EVM. +- `OnSystemCallStartV2(vm *VMContext)`. This allows access to EVM context during system calls. It is a successor to `OnSystemCallStart`. +- `OnNonceChangeV2(addr common.Address, prev, new uint64, reason NonceChangeReason)`: This hook is called when a nonce change occurs. It is a successor to `OnNonceChange`. + +### New types + +- `NonceChangeReason` is a new type used to provide a reason for nonce changes. Notably it includes `NonceChangeRevert` which will be emitted by the state journaling library when a nonce change is due to a revert. + +### Modified types + +- `VMContext.StateDB` has been extended with `GetCodeHash(addr common.Address) common.Hash` method used to retrieve the code hash an account. +- `BalanceChangeReason` has been extended with the `BalanceChangeRevert` reason. More on that below. + +### State journaling + +Tracers receive state changes events from the node. The tracer was so far expected to keep track of modified accounts and slots and revert those changes when a call frame failed. Now a utility tracer wrapper is provided which will emit "reverse change" events when a call frame fails. To use this feature the hooks have to be wrapped prior to registering the tracer. The following example demonstrates how to use the state journaling library: + +```go +func init() { + tracers.LiveDirectory.Register("test", func (cfg json.RawMessage) (*tracing.Hooks, error) { + hooks, err := newTestTracer(cfg) + if err != nil { + return nil, err + } + return tracing.WrapWithJournal(hooks) + }) +} +``` + +The state changes that are covered by the journaling library are: + +- `OnBalanceChange`. Note that `OnBalanceChange` will carry the `BalanceChangeRevert` reason. +- `OnNonceChange`, `OnNonceChangeV2` +- `OnCodeChange` +- `OnStorageChange` + +## [v1.14.9](https://github.com/ethereum/go-ethereum/releases/tag/v1.14.9) + ### 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. diff --git a/core/tracing/gen_balance_change_reason_stringer.go b/core/tracing/gen_balance_change_reason_stringer.go index d3a515a12d..4f094efb4f 100644 --- a/core/tracing/gen_balance_change_reason_stringer.go +++ b/core/tracing/gen_balance_change_reason_stringer.go @@ -23,11 +23,12 @@ func _() { _ = x[BalanceIncreaseSelfdestruct-12] _ = x[BalanceDecreaseSelfdestruct-13] _ = x[BalanceDecreaseSelfdestructBurn-14] + _ = x[BalanceChangeRevert-15] } -const _BalanceChangeReason_name = "BalanceChangeUnspecifiedBalanceIncreaseRewardMineUncleBalanceIncreaseRewardMineBlockBalanceIncreaseWithdrawalBalanceIncreaseGenesisBalanceBalanceIncreaseRewardTransactionFeeBalanceDecreaseGasBuyBalanceIncreaseGasReturnBalanceIncreaseDaoContractBalanceDecreaseDaoAccountBalanceChangeTransferBalanceChangeTouchAccountBalanceIncreaseSelfdestructBalanceDecreaseSelfdestructBalanceDecreaseSelfdestructBurn" +const _BalanceChangeReason_name = "BalanceChangeUnspecifiedBalanceIncreaseRewardMineUncleBalanceIncreaseRewardMineBlockBalanceIncreaseWithdrawalBalanceIncreaseGenesisBalanceBalanceIncreaseRewardTransactionFeeBalanceDecreaseGasBuyBalanceIncreaseGasReturnBalanceIncreaseDaoContractBalanceDecreaseDaoAccountBalanceChangeTransferBalanceChangeTouchAccountBalanceIncreaseSelfdestructBalanceDecreaseSelfdestructBalanceDecreaseSelfdestructBurnBalanceChangeRevert" -var _BalanceChangeReason_index = [...]uint16{0, 24, 54, 84, 109, 138, 173, 194, 218, 244, 269, 290, 315, 342, 369, 400} +var _BalanceChangeReason_index = [...]uint16{0, 24, 54, 84, 109, 138, 173, 194, 218, 244, 269, 290, 315, 342, 369, 400, 419} func (i BalanceChangeReason) String() string { if i >= BalanceChangeReason(len(_BalanceChangeReason_index)-1) { diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 167bcb5c16..4002b57207 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -14,6 +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 tracing defines hooks for 'live tracing' of block processing and transaction +// execution. Here we define the low-level [Hooks] object that carries hooks which are +// invoked by the go-ethereum core at various points in the state transition. +// +// To create a tracer that can be invoked with Geth, you need to register it using +// [github.com/ethereum/go-ethereum/eth/tracers.LiveDirectory.Register]. +// +// See https://geth.ethereum.org/docs/developers/evm-tracing/live-tracing for a tutorial. package tracing import ( @@ -163,6 +171,9 @@ type ( // NonceChangeHook is called when the nonce of an account changes. NonceChangeHook = func(addr common.Address, prev, new uint64) + // NonceChangeHookV2 is called when the nonce of an account changes. + NonceChangeHookV2 = func(addr common.Address, prev, new uint64, reason NonceChangeReason) + // 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) @@ -171,6 +182,9 @@ type ( // LogHook is called when a log is emitted. LogHook = func(log *types.Log) + + // BlockHashReadHook is called when EVM reads the blockhash of a block. + BlockHashReadHook = func(blockNumber uint64, hash common.Hash) ) type Hooks struct { @@ -195,9 +209,12 @@ type Hooks struct { // State events OnBalanceChange BalanceChangeHook OnNonceChange NonceChangeHook + OnNonceChangeV2 NonceChangeHookV2 OnCodeChange CodeChangeHook OnStorageChange StorageChangeHook OnLog LogHook + // Block hash read + OnBlockHashRead BlockHashReadHook } // BalanceChangeReason is used to indicate the reason for a balance change, useful @@ -249,6 +266,10 @@ const ( // 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 + + // BalanceChangeRevert is emitted when the balance is reverted back to a previous value due to call failure. + // It is only emitted when the tracer has opted in to use the journaling wrapper (WrapWithJournal). + BalanceChangeRevert BalanceChangeReason = 15 ) // GasChangeReason is used to indicate the reason for a gas change, useful @@ -321,3 +342,29 @@ const ( // it will be "manually" tracked by a direct emit of the gas change event. GasChangeIgnored GasChangeReason = 0xFF ) + +// NonceChangeReason is used to indicate the reason for a nonce change. +type NonceChangeReason byte + +const ( + NonceChangeUnspecified NonceChangeReason = 0 + + // NonceChangeGenesis is the nonce allocated to accounts at genesis. + NonceChangeGenesis NonceChangeReason = 1 + + // NonceChangeEoACall is the nonce change due to an EoA call. + NonceChangeEoACall NonceChangeReason = 2 + + // NonceChangeContractCreator is the nonce change of an account creating a contract. + NonceChangeContractCreator NonceChangeReason = 3 + + // NonceChangeNewContract is the nonce change of a newly created contract. + NonceChangeNewContract NonceChangeReason = 4 + + // NonceChangeTransaction is the nonce change due to a EIP-7702 authorization. + NonceChangeAuthorization NonceChangeReason = 5 + + // NonceChangeRevert is emitted when the nonce is reverted back to a previous value due to call failure. + // It is only emitted when the tracer has opted in to use the journaling wrapper (WrapWithJournal). + NonceChangeRevert NonceChangeReason = 6 +) diff --git a/core/tracing/journal.go b/core/tracing/journal.go new file mode 100644 index 0000000000..8937d4c5ae --- /dev/null +++ b/core/tracing/journal.go @@ -0,0 +1,237 @@ +// Copyright 2025 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 ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// journal is a state change journal to be wrapped around a tracer. +// It will emit the state change hooks with reverse values when a call reverts. +type journal struct { + hooks *Hooks + entries []entry + revisions []int +} + +type entry interface { + revert(tracer *Hooks) +} + +// WrapWithJournal wraps the given tracer with a journaling layer. +func WrapWithJournal(hooks *Hooks) (*Hooks, error) { + if hooks == nil { + return nil, fmt.Errorf("wrapping nil tracer") + } + // No state change to journal, return the wrapped hooks as is + if hooks.OnBalanceChange == nil && hooks.OnNonceChange == nil && hooks.OnNonceChangeV2 == nil && hooks.OnCodeChange == nil && hooks.OnStorageChange == nil { + return hooks, nil + } + if hooks.OnNonceChange != nil && hooks.OnNonceChangeV2 != nil { + return nil, fmt.Errorf("cannot have both OnNonceChange and OnNonceChangeV2") + } + + // Create a new Hooks instance and copy all hooks + wrapped := *hooks + + // Create journal + j := &journal{hooks: hooks} + // Scope hooks need to be re-implemented. + wrapped.OnTxEnd = j.OnTxEnd + wrapped.OnEnter = j.OnEnter + wrapped.OnExit = j.OnExit + // Wrap state change hooks. + if hooks.OnBalanceChange != nil { + wrapped.OnBalanceChange = j.OnBalanceChange + } + if hooks.OnNonceChange != nil || hooks.OnNonceChangeV2 != nil { + // Regardless of which hook version is used in the tracer, + // the journal will want to capture the nonce change reason. + wrapped.OnNonceChangeV2 = j.OnNonceChangeV2 + // A precaution to ensure EVM doesn't call both hooks. + wrapped.OnNonceChange = nil + } + if hooks.OnCodeChange != nil { + wrapped.OnCodeChange = j.OnCodeChange + } + if hooks.OnStorageChange != nil { + wrapped.OnStorageChange = j.OnStorageChange + } + + return &wrapped, nil +} + +// 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.revisions = j.revisions[:0] +} + +// snapshot records a revision and stores it to the revision stack. +func (j *journal) snapshot() { + rev := len(j.entries) + j.revisions = append(j.revisions, rev) +} + +// revert reverts all state changes up to the last tracked revision. +func (j *journal) revert(hooks *Hooks) { + // Replay the journal entries above the last revision to undo changes, + // then remove the reverted changes from the journal. + rev := j.revisions[len(j.revisions)-1] + for i := len(j.entries) - 1; i >= rev; i-- { + j.entries[i].revert(hooks) + } + j.entries = j.entries[:rev] + j.popRevision() +} + +// popRevision removes an item from the revision stack. This basically forgets about +// the last call to snapshot() and moves to the one prior. +func (j *journal) popRevision() { + j.revisions = j.revisions[:len(j.revisions)-1] +} + +// OnTxEnd resets the journal since each transaction has its own EVM call stack. +func (j *journal) OnTxEnd(receipt *types.Receipt, err error) { + j.reset() + if j.hooks.OnTxEnd != nil { + j.hooks.OnTxEnd(receipt, err) + } +} + +// OnEnter is invoked for each EVM call frame and records a journal revision. +func (j *journal) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + j.snapshot() + if j.hooks.OnEnter != nil { + j.hooks.OnEnter(depth, typ, from, to, input, gas, value) + } +} + +// OnExit is invoked when an EVM call frame ends. +// If the call has reverted, all state changes made by that frame are undone. +// If the call did not revert, we forget about changes in that revision. +func (j *journal) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if reverted { + j.revert(j.hooks) + } else { + j.popRevision() + } + if j.hooks.OnExit != nil { + j.hooks.OnExit(depth, output, gasUsed, err, reverted) + } +} + +func (j *journal) OnBalanceChange(addr common.Address, prev, new *big.Int, reason BalanceChangeReason) { + j.entries = append(j.entries, balanceChange{addr: addr, prev: prev, new: new}) + if j.hooks.OnBalanceChange != nil { + j.hooks.OnBalanceChange(addr, prev, new, reason) + } +} + +func (j *journal) OnNonceChangeV2(addr common.Address, prev, new uint64, reason NonceChangeReason) { + // When a contract is created, the nonce of the creator is incremented. + // This change is not reverted when the creation fails. + if reason != NonceChangeContractCreator { + j.entries = append(j.entries, nonceChange{addr: addr, prev: prev, new: new}) + } + if j.hooks.OnNonceChangeV2 != nil { + j.hooks.OnNonceChangeV2(addr, prev, new, reason) + } else if j.hooks.OnNonceChange != nil { + j.hooks.OnNonceChange(addr, prev, new) + } +} + +func (j *journal) OnCodeChange(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte) { + j.entries = append(j.entries, codeChange{ + addr: addr, + prevCodeHash: prevCodeHash, + prevCode: prevCode, + newCodeHash: codeHash, + newCode: code, + }) + if j.hooks.OnCodeChange != nil { + j.hooks.OnCodeChange(addr, prevCodeHash, prevCode, codeHash, code) + } +} + +func (j *journal) OnStorageChange(addr common.Address, slot common.Hash, prev, new common.Hash) { + j.entries = append(j.entries, storageChange{addr: addr, slot: slot, prev: prev, new: new}) + if j.hooks.OnStorageChange != nil { + j.hooks.OnStorageChange(addr, slot, prev, new) + } +} + +type ( + balanceChange struct { + addr common.Address + prev *big.Int + new *big.Int + } + + nonceChange struct { + addr common.Address + prev uint64 + new uint64 + } + + codeChange struct { + addr common.Address + prevCodeHash common.Hash + prevCode []byte + newCodeHash common.Hash + newCode []byte + } + + storageChange struct { + addr common.Address + slot common.Hash + prev common.Hash + new common.Hash + } +) + +func (b balanceChange) revert(hooks *Hooks) { + if hooks.OnBalanceChange != nil { + hooks.OnBalanceChange(b.addr, b.new, b.prev, BalanceChangeRevert) + } +} + +func (n nonceChange) revert(hooks *Hooks) { + if hooks.OnNonceChangeV2 != nil { + hooks.OnNonceChangeV2(n.addr, n.new, n.prev, NonceChangeRevert) + } else if hooks.OnNonceChange != nil { + hooks.OnNonceChange(n.addr, n.new, n.prev) + } +} + +func (c codeChange) revert(hooks *Hooks) { + if hooks.OnCodeChange != nil { + hooks.OnCodeChange(c.addr, c.newCodeHash, c.newCode, c.prevCodeHash, c.prevCode) + } +} + +func (s storageChange) revert(hooks *Hooks) { + if hooks.OnStorageChange != nil { + hooks.OnStorageChange(s.addr, s.slot, s.new, s.prev) + } +} diff --git a/core/tracing/journal_test.go b/core/tracing/journal_test.go new file mode 100644 index 0000000000..d9616a2ce8 --- /dev/null +++ b/core/tracing/journal_test.go @@ -0,0 +1,335 @@ +// Copyright 2025 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 ( + "errors" + "math/big" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +type testTracer struct { + t *testing.T + bal *big.Int + nonce uint64 + code []byte + storage map[common.Hash]common.Hash +} + +func (t *testTracer) OnBalanceChange(addr common.Address, prev *big.Int, new *big.Int, reason BalanceChangeReason) { + t.t.Logf("OnBalanceChange(%v, %v -> %v, %v)", addr, prev, new, reason) + if t.bal != nil && t.bal.Cmp(prev) != 0 { + t.t.Errorf(" !! wrong prev balance (expected %v)", t.bal) + } + t.bal = new +} + +func (t *testTracer) OnNonceChange(addr common.Address, prev uint64, new uint64) { + t.t.Logf("OnNonceChange(%v, %v -> %v)", addr, prev, new) + t.nonce = new +} + +func (t *testTracer) OnNonceChangeV2(addr common.Address, prev uint64, new uint64, reason NonceChangeReason) { + t.t.Logf("OnNonceChangeV2(%v, %v -> %v, %v)", addr, prev, new, reason) + t.nonce = new +} + +func (t *testTracer) OnCodeChange(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte) { + t.t.Logf("OnCodeChange(%v, %v -> %v)", addr, prevCodeHash, codeHash) + t.code = code +} + +func (t *testTracer) OnStorageChange(addr common.Address, slot common.Hash, prev common.Hash, new common.Hash) { + t.t.Logf("OnStorageCodeChange(%v, %v, %v -> %v)", addr, slot, prev, new) + if t.storage == nil { + t.storage = make(map[common.Hash]common.Hash) + } + if new == (common.Hash{}) { + delete(t.storage, slot) + } else { + t.storage[slot] = new + } +} + +func TestJournalIntegration(t *testing.T) { + tr := &testTracer{t: t} + wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange, OnCodeChange: tr.OnCodeChange, OnStorageChange: tr.OnStorageChange}) + if err != nil { + t.Fatalf("failed to wrap test tracer: %v", err) + } + + addr := common.HexToAddress("0x1234") + { + wr.OnEnter(0, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnBalanceChange(addr, nil, big.NewInt(100), BalanceChangeUnspecified) + wr.OnCodeChange(addr, common.Hash{}, nil, common.Hash{}, []byte{1, 2, 3}) + wr.OnStorageChange(addr, common.Hash{1}, common.Hash{}, common.Hash{2}) + { + wr.OnEnter(1, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnNonceChangeV2(addr, 0, 1, NonceChangeUnspecified) + wr.OnBalanceChange(addr, big.NewInt(100), big.NewInt(200), BalanceChangeUnspecified) + wr.OnBalanceChange(addr, big.NewInt(200), big.NewInt(250), BalanceChangeUnspecified) + wr.OnStorageChange(addr, common.Hash{1}, common.Hash{2}, common.Hash{3}) + wr.OnStorageChange(addr, common.Hash{2}, common.Hash{}, common.Hash{4}) + wr.OnExit(1, nil, 100, errors.New("revert"), true) + } + wr.OnExit(0, nil, 150, nil, false) + } + + if tr.bal.Cmp(big.NewInt(100)) != 0 { + t.Fatalf("unexpected balance: %v", tr.bal) + } + if tr.nonce != 0 { + t.Fatalf("unexpected nonce: %v", tr.nonce) + } + if len(tr.code) != 3 { + t.Fatalf("unexpected code: %v", tr.code) + } + if len(tr.storage) != 1 { + t.Fatalf("unexpected storage len. want %d, have %d", 1, len(tr.storage)) + } + if tr.storage[common.Hash{1}] != (common.Hash{2}) { + t.Fatalf("unexpected storage. want %v, have %v", common.Hash{2}, tr.storage[common.Hash{1}]) + } +} + +func TestJournalTopRevert(t *testing.T) { + tr := &testTracer{t: t} + wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) + if err != nil { + t.Fatalf("failed to wrap test tracer: %v", err) + } + + addr := common.HexToAddress("0x1234") + { + wr.OnEnter(0, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnBalanceChange(addr, big.NewInt(0), big.NewInt(100), BalanceChangeUnspecified) + { + wr.OnEnter(1, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnNonceChangeV2(addr, 0, 1, NonceChangeUnspecified) + wr.OnBalanceChange(addr, big.NewInt(100), big.NewInt(200), BalanceChangeUnspecified) + wr.OnBalanceChange(addr, big.NewInt(200), big.NewInt(250), BalanceChangeUnspecified) + wr.OnExit(1, nil, 100, errors.New("revert"), true) + } + wr.OnExit(0, nil, 150, errors.New("revert"), true) + } + + if tr.bal.Cmp(big.NewInt(0)) != 0 { + t.Fatalf("unexpected balance: %v", tr.bal) + } + if tr.nonce != 0 { + t.Fatalf("unexpected nonce: %v", tr.nonce) + } +} + +// This test checks that changes in nested calls are reverted properly. +func TestJournalNestedCalls(t *testing.T) { + tr := &testTracer{t: t} + wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) + if err != nil { + t.Fatalf("failed to wrap test tracer: %v", err) + } + + addr := common.HexToAddress("0x1234") + { + wr.OnEnter(0, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnBalanceChange(addr, big.NewInt(0), big.NewInt(100), BalanceChangeUnspecified) + { + wr.OnEnter(1, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnBalanceChange(addr, big.NewInt(100), big.NewInt(200), BalanceChangeUnspecified) + { + wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnExit(2, nil, 100, nil, false) + } + { + wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnBalanceChange(addr, big.NewInt(200), big.NewInt(300), BalanceChangeUnspecified) + wr.OnExit(2, nil, 100, nil, false) + } + { + wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnExit(2, nil, 100, nil, false) + } + wr.OnBalanceChange(addr, big.NewInt(300), big.NewInt(400), BalanceChangeUnspecified) + { + wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnBalanceChange(addr, big.NewInt(400), big.NewInt(500), BalanceChangeUnspecified) + wr.OnExit(2, nil, 100, errors.New("revert"), true) + } + { + wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnExit(2, nil, 100, errors.New("revert"), true) + } + { + wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnBalanceChange(addr, big.NewInt(400), big.NewInt(600), BalanceChangeUnspecified) + wr.OnExit(2, nil, 100, nil, false) + } + wr.OnExit(1, nil, 100, errors.New("revert"), true) + } + wr.OnExit(0, nil, 150, nil, false) + } + + if tr.bal.Uint64() != 100 { + t.Fatalf("unexpected balance: %v", tr.bal) + } +} + +func TestNonceIncOnCreate(t *testing.T) { + const opCREATE = 0xf0 + + tr := &testTracer{t: t} + wr, err := WrapWithJournal(&Hooks{OnNonceChange: tr.OnNonceChange}) + if err != nil { + t.Fatalf("failed to wrap test tracer: %v", err) + } + + addr := common.HexToAddress("0x1234") + { + wr.OnEnter(0, opCREATE, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnNonceChangeV2(addr, 0, 1, NonceChangeContractCreator) + wr.OnExit(0, nil, 100, errors.New("revert"), true) + } + + if tr.nonce != 1 { + t.Fatalf("unexpected nonce: %v", tr.nonce) + } +} + +func TestOnNonceChangeV2(t *testing.T) { + tr := &testTracer{t: t} + wr, err := WrapWithJournal(&Hooks{OnNonceChangeV2: tr.OnNonceChangeV2}) + if err != nil { + t.Fatalf("failed to wrap test tracer: %v", err) + } + + addr := common.HexToAddress("0x1234") + { + wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnNonceChangeV2(addr, 0, 1, NonceChangeEoACall) + wr.OnExit(2, nil, 100, nil, true) + } + + if tr.nonce != 0 { + t.Fatalf("unexpected nonce: %v", tr.nonce) + } +} + +func TestAllHooksCalled(t *testing.T) { + tracer := newTracerAllHooks() + hooks := tracer.hooks() + + wrapped, err := WrapWithJournal(hooks) + if err != nil { + t.Fatalf("failed to wrap hooks with journal: %v", err) + } + + // Get the underlying value of the wrapped hooks + wrappedValue := reflect.ValueOf(wrapped).Elem() + wrappedType := wrappedValue.Type() + + // Iterate over all fields of the wrapped hooks + for i := 0; i < wrappedType.NumField(); i++ { + field := wrappedType.Field(i) + + // Skip fields that are not function types + if field.Type.Kind() != reflect.Func { + continue + } + // Skip non-hooks, i.e. Copy + if field.Name == "copy" { + continue + } + // Skip if field is not set + if wrappedValue.Field(i).IsNil() { + continue + } + + // Get the method + method := wrappedValue.Field(i) + + // Call the method with zero values + params := make([]reflect.Value, method.Type().NumIn()) + for j := 0; j < method.Type().NumIn(); j++ { + params[j] = reflect.Zero(method.Type().In(j)) + } + method.Call(params) + } + + // Check if all hooks were called + if tracer.numCalled() != tracer.hooksCount() { + t.Errorf("Not all hooks were called. Expected %d, got %d", tracer.hooksCount(), tracer.numCalled()) + } + + for hookName, called := range tracer.hooksCalled { + if !called { + t.Errorf("Hook %s was not called", hookName) + } + } +} + +type tracerAllHooks struct { + hooksCalled map[string]bool +} + +func newTracerAllHooks() *tracerAllHooks { + t := &tracerAllHooks{hooksCalled: make(map[string]bool)} + // Initialize all hooks to false. We will use this to + // get total count of hooks. + hooksType := reflect.TypeOf((*Hooks)(nil)).Elem() + for i := 0; i < hooksType.NumField(); i++ { + t.hooksCalled[hooksType.Field(i).Name] = false + } + delete(t.hooksCalled, "OnNonceChange") + return t +} + +func (t *tracerAllHooks) hooksCount() int { + return len(t.hooksCalled) +} + +func (t *tracerAllHooks) numCalled() int { + count := 0 + for _, called := range t.hooksCalled { + if called { + count++ + } + } + return count +} + +func (t *tracerAllHooks) hooks() *Hooks { + h := &Hooks{} + // Create a function for each hook that sets the + // corresponding hooksCalled field to true. + hooksValue := reflect.ValueOf(h).Elem() + for i := 0; i < hooksValue.NumField(); i++ { + field := hooksValue.Type().Field(i) + if field.Name == "OnNonceChange" { + continue + } + hookMethod := reflect.MakeFunc(field.Type, func(args []reflect.Value) []reflect.Value { + t.hooksCalled[field.Name] = true + return nil + }) + hooksValue.Field(i).Set(hookMethod) + } + return h +} diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 88d68eb307..f7c9e4844b 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -680,9 +680,9 @@ func TestOpenDrops(t *testing.T) { 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.SetNonce(crypto.PubkeyToAddress(filler.PublicKey), 3, tracing.NonceChangeUnspecified) statedb.AddBalance(crypto.PubkeyToAddress(overlapper.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) - statedb.SetNonce(crypto.PubkeyToAddress(overlapper.PublicKey), 2) + statedb.SetNonce(crypto.PubkeyToAddress(overlapper.PublicKey), 2, tracing.NonceChangeUnspecified) 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) @@ -1526,7 +1526,7 @@ func TestAdd(t *testing.T) { // Seed the state database with this account statedb.AddBalance(addrs[acc], new(uint256.Int).SetUint64(seed.balance), tracing.BalanceChangeUnspecified) - statedb.SetNonce(addrs[acc], seed.nonce) + statedb.SetNonce(addrs[acc], seed.nonce, tracing.NonceChangeUnspecified) // Sign the seed transactions and store them in the data store for _, tx := range seed.txs { @@ -1581,7 +1581,7 @@ func TestAdd(t *testing.T) { // 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) + chain.statedb.SetNonce(sender, tx.Nonce()+1, tracing.NonceChangeUnspecified) } pool.Reset(chain.CurrentBlock(), header) verifyPoolInternals(t, pool) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 55699e93ee..fdbcad3d4f 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -251,7 +251,7 @@ func (c *testChain) State() (*state.StateDB, error) { if *c.trigger { 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.SetNonce(c.address, 2, tracing.NonceChangeUnspecified) c.statedb.SetBalance(c.address, new(uint256.Int).SetUint64(params.Ether), tracing.BalanceChangeUnspecified) *c.trigger = false } @@ -312,7 +312,7 @@ func testAddBalance(pool *LegacyPool, addr common.Address, amount *big.Int) { func testSetNonce(pool *LegacyPool, addr common.Address, nonce uint64) { pool.mu.Lock() - pool.currentState.SetNonce(addr, nonce) + pool.currentState.SetNonce(addr, nonce, tracing.NonceChangeUnspecified) pool.mu.Unlock() } @@ -1011,7 +1011,7 @@ func TestQueueTimeLimiting(t *testing.T) { } // remove current transactions and increase nonce to prepare for a reset and cleanup - statedb.SetNonce(crypto.PubkeyToAddress(remote.PublicKey), 2) + statedb.SetNonce(crypto.PubkeyToAddress(remote.PublicKey), 2, tracing.NonceChangeUnspecified) <-pool.requestReset(nil, nil) // make sure queue, pending are cleared diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go index 4e873eedff..de2280ced1 100644 --- a/core/verkle_witness_test.go +++ b/core/verkle_witness_test.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/ethash" "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" @@ -226,7 +227,7 @@ func TestProcessParentBlockHash(t *testing.T) { // block 2 parent hash is 0x0200.... // etc checkBlockHashes := func(statedb *state.StateDB, isVerkle bool) { - statedb.SetNonce(params.HistoryStorageAddress, 1) + statedb.SetNonce(params.HistoryStorageAddress, 1, tracing.NonceChangeUnspecified) statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode) // Process n blocks, from 1 .. num var num = 2 diff --git a/core/vm/evm.go b/core/vm/evm.go index 3f9ae621a3..442441e9ae 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -439,7 +439,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if nonce+1 < nonce { return nil, common.Address{}, gas, ErrNonceUintOverflow } - evm.StateDB.SetNonce(caller.Address(), nonce+1) + evm.StateDB.SetNonce(caller.Address(), nonce+1, tracing.NonceChangeContractCreator) // Charge the contract creation init gas in verkle mode if evm.chainRules.IsEIP4762 { @@ -487,7 +487,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, evm.StateDB.CreateContract(address) if evm.chainRules.IsEIP158 { - evm.StateDB.SetNonce(address, 1) + evm.StateDB.SetNonce(address, 1, tracing.NonceChangeNewContract) } // Charge the contract creation init gas in verkle mode if evm.chainRules.IsEIP4762 { diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 9b9a31a855..c9eea33507 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -448,6 +448,9 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( if witness := interpreter.evm.StateDB.Witness(); witness != nil { witness.AddBlockHash(num64) } + if tracer := interpreter.evm.Config.Tracer; tracer != nil && tracer.OnBlockHashRead != nil { + tracer.OnBlockHashRead(num64, res) + } num.SetBytes(res[:]) } else { num.Clear() diff --git a/core/vm/interface.go b/core/vm/interface.go index 3488526fc4..0d7862a66e 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -39,7 +39,7 @@ type StateDB interface { GetBalance(common.Address) *uint256.Int GetNonce(common.Address) uint64 - SetNonce(common.Address, uint64) + SetNonce(common.Address, uint64, tracing.NonceChangeReason) GetCodeHash(common.Address) common.Hash GetCode(common.Address) []byte diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 44f5bc8273..bde230b6da 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -414,7 +414,7 @@ func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode eoa := common.HexToAddress("E0") { cfg.State.CreateAccount(eoa) - cfg.State.SetNonce(eoa, 100) + cfg.State.SetNonce(eoa, 100, tracing.NonceChangeUnspecified) } reverting := common.HexToAddress("EE") { diff --git a/eth/tracers/live/noop.go b/eth/tracers/live/noop.go index 46c5700d25..f3def85606 100644 --- a/eth/tracers/live/noop.go +++ b/eth/tracers/live/noop.go @@ -57,6 +57,7 @@ func newNoopTracer(_ json.RawMessage) (*tracing.Hooks, error) { OnCodeChange: t.OnCodeChange, OnStorageChange: t.OnStorageChange, OnLog: t.OnLog, + OnBlockHashRead: t.OnBlockHashRead, }, nil } @@ -108,5 +109,7 @@ func (t *noop) OnLog(l *types.Log) { } +func (t *noop) OnBlockHashRead(number uint64, hash common.Hash) {} + func (t *noop) OnGasChange(old, new uint64, reason tracing.GasChangeReason) { } diff --git a/internal/ethapi/override/override.go b/internal/ethapi/override/override.go index 70b6210275..f6a8a94ffd 100644 --- a/internal/ethapi/override/override.go +++ b/internal/ethapi/override/override.go @@ -86,7 +86,7 @@ func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles vm.Precompi } // Override account nonce. if account.Nonce != nil { - statedb.SetNonce(addr, uint64(*account.Nonce)) + statedb.SetNonce(addr, uint64(*account.Nonce), tracing.NonceChangeUnspecified) } // Override account(contract) code. if account.Code != nil { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 24caf41ed9..a22e470ad8 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -512,7 +512,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo statedb, _ := state.New(types.EmptyRootHash, sdb) for addr, a := range accounts { statedb.SetCode(addr, a.Code) - statedb.SetNonce(addr, a.Nonce) + statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeUnspecified) statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceChangeUnspecified) for k, v := range a.Storage { statedb.SetState(addr, k, v) From 5d97db8d03a3c55a6d1735543a2d41027333f37b Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 5 Feb 2025 23:01:17 +0100 Subject: [PATCH 099/940] all: update license comments and AUTHORS (#31133) --- .mailmap | 89 +++++- AUTHORS | 300 +++++++++++++++++- beacon/light/sync/head_sync.go | 2 +- beacon/params/networks.go | 2 +- cmd/abigen/namefilter.go | 16 + cmd/abigen/namefilter_test.go | 16 + cmd/blsync/main.go | 16 +- cmd/evm/eofparse.go | 2 +- cmd/evm/eofparse_test.go | 16 + cmd/geth/attach_test.go | 14 +- cmd/geth/logging_test.go | 4 +- cmd/geth/logtestcmd_active.go | 4 +- cmd/geth/logtestcmd_inactive.go | 4 +- core/rawdb/accessors_trie.go | 4 +- core/state/statedb_fuzz_test.go | 2 +- core/txindexer.go | 2 +- core/txindexer_test.go | 2 +- core/txpool/blobpool/lookup.go | 2 +- core/txpool/legacypool/legacypool2_test.go | 1 + core/txpool/txpool.go | 2 +- core/types/tx_blob_test.go | 16 + core/vm/eof_control_flow.go | 14 +- core/vm/eof_test.go | 2 +- core/vm/jump_table_test.go | 2 +- core/vm/memory_test.go | 16 + core/vm/program/program.go | 6 +- core/vm/program/program_test.go | 6 +- eth/tracers/dir.go | 2 +- .../internal/tracetest/flat_calltrace_test.go | 16 + eth/tracers/internal/tracetest/makeTest.js | 16 + .../internal/tracetest/prestate_test.go | 2 +- eth/tracers/internal/tracetest/supply_test.go | 2 +- eth/tracers/internal/tracetest/util.go | 16 + eth/tracers/internal/util.go | 2 +- eth/tracers/internal/util_test.go | 3 +- eth/tracers/native/call_flat.go | 2 +- eth/tracers/tracker_test.go | 2 +- ethclient/simulated/backend_test.go | 2 +- ethclient/simulated/rollback_test.go | 16 + ethdb/pebble/pebble_test.go | 2 +- graphql/internal/graphiql/build.go | 16 + internal/era/accumulator.go | 16 +- internal/era/builder.go | 16 +- internal/era/e2store/e2store.go | 16 +- internal/era/e2store/e2store_test.go | 16 +- internal/era/era.go | 16 +- internal/era/era_test.go | 16 +- internal/era/iterator.go | 16 +- miner/payload_building.go | 2 +- miner/payload_building_test.go | 2 +- miner/pending.go | 2 +- p2p/config.go | 1 + p2p/pipes/pipe.go | 2 +- rpc/client_opt_test.go | 16 + tests/fuzzers/difficulty/difficulty_test.go | 2 +- tests/fuzzers/rangeproof/rangeproof_test.go | 2 +- tests/fuzzers/txfetcher/txfetcher_test.go | 2 +- trie/trie_id.go | 2 +- trie/trienode/node.go | 2 +- trie/utils/verkle.go | 2 +- trie/utils/verkle_test.go | 4 +- trie/verkle.go | 2 +- trie/verkle_test.go | 2 +- triedb/pathdb/errors.go | 2 +- triedb/pathdb/execute.go | 2 +- triedb/pathdb/history.go | 4 +- triedb/pathdb/history_inspect.go | 2 +- triedb/pathdb/history_test.go | 4 +- triedb/pathdb/layertree.go | 4 +- triedb/pathdb/metrics.go | 4 +- triedb/pathdb/nodes.go | 2 +- triedb/pathdb/reader.go | 2 +- triedb/pathdb/states.go | 2 +- triedb/pathdb/states_test.go | 2 +- triedb/states.go | 4 +- version/version.go | 2 +- 76 files changed, 697 insertions(+), 157 deletions(-) diff --git a/.mailmap b/.mailmap index 312e51d854..92a9e07748 100644 --- a/.mailmap +++ b/.mailmap @@ -5,6 +5,9 @@ Aaron Kumavis Abel Nieto Abel Nieto +Adrian Sutton +Adrian Sutton + Afri Schoedon <58883403+q9f@users.noreply.github.com> Afri Schoedon <5chdn@users.noreply.github.com> <58883403+q9f@users.noreply.github.com> @@ -22,6 +25,9 @@ Alexey Akhunov Alon Muroch +Andrei Silviu Dragnea +Andrei Silviu Dragnea + Andrey Petrov Andrey Petrov @@ -51,11 +57,17 @@ Chris Ziogas Christoph Jentzsch +Daniel Liu +Daniel Liu <139250065@qq.com> + Diederik Loerakker Dimitry Khokhlov +Ha ĐANG + Domino Valdano +Domino Valdano Edgar Aroutiounian @@ -82,6 +94,9 @@ Gavin Wood Gregg Dourgarian +guangwu +guangwu + Guillaume Ballet Guillaume Ballet <3272758+gballet@users.noreply.github.com> @@ -95,13 +110,21 @@ Heiko Hees Henning Diedrich Henning Diedrich Drake Burroughs +henridf +henridf + Hwanjo Heo <34005989+hwanjo@users.noreply.github.com> +Ikko Eltociear Ashimine + Iskander (Alex) Sharipov Iskander (Alex) Sharipov Jae Kwon +James Prestwich +James Prestwich <10149425+prestwich@users.noreply.github.com> + Janoš Guljaš Janoš Guljaš Janos Guljas @@ -120,23 +143,38 @@ Jeffrey Wilcke Jens Agerberg +Jeremy Schlatter +Jeremy Schlatter + +John Chase <68833933+joohhnnn@users.noreply.github.com> + Joseph Chow Joseph Chow ethers - Joseph Goulden Justin Drake +Karl Bartel +Karl Bartel + Kenso Trabing Kenso Trabing +Liyi Guo <102356659+colinlyguo@users.noreply.github.com> + +lmittmann <3458786+lmittmann@users.noreply.github.com> +lmittmann <3458786+lmittmann@users.noreply.github.com> + Liang Ma Liang Ma Louis Holbrook Louis Holbrook +makcandrov +makcandrov <108467407+makcandrov@users.noreply.github.com> + Maran Hidskes Marian Oancea @@ -144,17 +182,33 @@ Marian Oancea Martin Becze Martin Becze +Martin Holst Swende + Martin Lundfall -Matt Garnett <14004106+lightclient@users.noreply.github.com> +Marius van der Wijden +Marius van der Wijden <115323661+vdwijden@users.noreply.github.com> + +Matt Garnett +Matt Garnett <14004106+lightclient@users.noreply.github.com> Matthew Halpern Matthew Halpern +meowsbits +meowsbits <45600330+meowsbits@users.noreply.github.com> + Michael Riabzev +Michael de Hoog +Michael de Hoog + Nchinda Nchinda +Nebojsa Urosevic + +nedifi <103940716+nedifi@users.noreply.github.com> + Nick Dodson Nick Johnson @@ -169,6 +223,9 @@ Olivier Hervieu Pascal Dierich Pascal Dierich +Paweł Bylica +Paweł Bylica + RJ Catalano RJ Catalano @@ -179,8 +236,22 @@ Rene Lubov <41963722+renaynay@users.noreply.github.com> Robert Zaremba Robert Zaremba +Roberto Bayardo +Roberto Bayardo + Roman Mandeleil +Sebastian Stammler +Sebastian Stammler + +Seungbae Yu +Seungbae Yu <72970043+dbadoy@users.noreply.github.com> + +Sina Mahmoodi <1591639+s1na@users.noreply.github.com> + +Steve Milk +Steve Milk <915337710@qq.com> + Sorin Neacsu Sorin Neacsu @@ -191,8 +262,14 @@ Taylor Gerring Thomas Bocek +tianyeyouyou +tianyeyouyou <150894831+tianyeyouyou@users.noreply.github.com> + Tim Cooijmans +ucwong +ucwong + Valentin Wüstholz Valentin Wüstholz @@ -221,6 +298,9 @@ Xudong Liu <33193253+r1cs@users.noreply.github.com> Yohann Léon +yzb <335357057@qq.com> +yzb <335357057@qq.com> + Zachinquarantine Zachinquarantine @@ -228,9 +308,4 @@ Ziyuan Zhong Zsolt Felföldi -meowsbits -meowsbits <45600330+meowsbits@users.noreply.github.com> - -nedifi <103940716+nedifi@users.noreply.github.com> - Максим Чусовлянов diff --git a/AUTHORS b/AUTHORS index 151c85016e..1ec240aeb6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,52 +1,81 @@ # This is the official list of go-ethereum authors for copyright purposes. +0xbeny <55846654+0xbeny@users.noreply.github.com> +0xbstn +0xe3b0c4 <110295932+0xe3b0c4@users.noreply.github.com> 6543 <6543@obermui.de> +6xiaowu9 <736518585@qq.com> a e r t h Aaron Buchwald +Aaron Chen +Aaron Kumavis +Aayush Rajasekaran Abel Nieto +Abirdcfly Adam Babik Adam Schmideg Aditya Aditya Arora +Adrian Sutton Adrià Cidre Afanasii Kurakin Afri Schoedon <5chdn@users.noreply.github.com> Agustin Armellini Fischer +Ahmet Avci Ahyun Airead Alan Chen Alejandro Isaza Aleksey Smyrnov Ales Katona +alex <152680487+bodhi-crypo@users.noreply.github.com> Alex Beregszaszi +Alex Gartner Alex Leverington Alex Mazalov +Alex Mylonas Alex Pozhilenkov Alex Prut <1648497+alexprut@users.noreply.github.com> +Alex Stokes Alex Wu +Alexander Mint Alexander van der Meij Alexander Yastrebov Alexandre Van de Sande Alexey Akhunov Alexey Shekhirin alexwang <39109351+dipingxian2@users.noreply.github.com> +Alfie John Ali Atiia <42751398+aliatiia@users.noreply.github.com> Ali Hajimirza +Alvaro Sevilla am2rican5 +Amin Talebi +AMIR <31338382+amiremohamadi@users.noreply.github.com> AmitBRD <60668103+AmitBRD@users.noreply.github.com> Anatole <62328077+a2br@users.noreply.github.com> +Andre Patta Andrea Franz +Andrei Kostakov Andrei Maiboroda +Andrei Silviu Dragnea +Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Andrey Petrov +Andryanau Kanstantsin ANOTHEL Antoine Rondelet Antoine Toulme Anton Evangelatov Antonio Salazar Cardozo +Antony Denyer +Anusha <63559942+anusha-ctrl@users.noreply.github.com> Arba Sasmoyo Armani Ferrante Armin Braun Aron Fischer +Arran Schlosberg <519948+ARR4N@users.noreply.github.com> +ArtificialPB +Artyom Aminov atsushi-ishibashi Austin Roberts ayeowch @@ -54,83 +83,135 @@ b00ris b1ackd0t bailantaotao baizhenxuan +Bala Murali Krishna Komatireddy Balaji Shetty Pachai <32358081+balajipachai@users.noreply.github.com> Balint Gabor baptiste-b-pegasys <85155432+baptiste-b-pegasys@users.noreply.github.com> Bas van Kervel Benjamin Brent +Benjamin Prosnitz benma Benoit Verkindt +Bin <49082129+songzhibin97@users.noreply.github.com> Binacs +bitcoin-lightning <153181187+AtomicInnovation321@users.noreply.github.com> +bk <5810624+bkellerman@users.noreply.github.com> bloonfield +bnovil Bo Bo Ye Bob Glickstein Boqin Qin +BorkBorked <107079055+BorkBorked@users.noreply.github.com> Brandon Harden +Brandon Liu Brent Brian Schroeder +Brion <4777457+cifer76@users.noreply.github.com> Bruno Škvorc +buddho +bugmaker9371 <167614621+bugmaker9371@users.noreply.github.com> C. Brown Caesar Chad +cam-schultz <78878559+cam-schultz@users.noreply.github.com> Casey Detrio +caseylove CDsigma +Cedrick Ceelog Ceyhun Onur chabashilah changhong +Charles Cooper Chase Wright +Chawin Aiemvaravutigul Chen Quan +chen4903 <108803001+chen4903@users.noreply.github.com> Cheng Li chenglin <910372762@qq.com> chenyufeng +Chirag Garg <38765776+DeVil2O@users.noreply.github.com> +chirag-bgh <76247491+chirag-bgh@users.noreply.github.com> Chris Pacia Chris Ziogas Christian Muehlhaeuser +Christina <156356273+cratiu222@users.noreply.github.com> Christoph Jentzsch +Christopher Harrison <31964100+chrischarlesharrison@users.noreply.github.com> chuwt +cocoyeal <150209682+cocoyeal@users.noreply.github.com> cong Connor Stein Corey Lin <514971757@qq.com> courtier cpusoft +crazeteam <164632007+crazeteam@users.noreply.github.com> Crispin Flowerday croath cui <523516579@qq.com> +cui fliter +cuinix <65650185+cuinix@users.noreply.github.com> +Curith +cygaar <97691933+cygaar@users.noreply.github.com> +Dan Cline <6798349+Rjected@users.noreply.github.com> Dan DeGreef Dan Kinsley +Dan Laine Dan Sosedoff +danceratopz Daniel A. Nagy +Daniel Fernandes <711733+daferna@users.noreply.github.com> +Daniel Katzan <108216499+dkatzan@users.noreply.github.com> +Daniel Knopik <107140945+dknopik@users.noreply.github.com> +Daniel Liu Daniel Perez Daniel Sloof +Danno Ferrin +Danyal Prout Darioush Jalali Darrel Herbst +Darren Kelly <107671032+darrenvechain@users.noreply.github.com> +dashangcun <907225865@qq.com> Dave Appleton Dave McGregor David Cai +David Dzhalaev <72649244+DavidRomanovizc@users.noreply.github.com> David Huie +David Murdoch <187813+davidmurdoch@users.noreply.github.com> +David Theodore <29786815+infosecual@users.noreply.github.com> +ddl +Dean Eigenmann <7621705+decanus@users.noreply.github.com> +Delweng Denver Derek Chiang Derek Gottfrid +deterclosed <164524498+deterclosed@users.noreply.github.com> +Devon Bear Di Peng Diederik Loerakker Diego Siqueira Diep Pham +Dimitris Apostolou dipingxian2 <39109351+dipingxian2@users.noreply.github.com> divergencetech <94644849+divergencetech@users.noreply.github.com> +dknopik <107140945+dknopik@users.noreply.github.com> dm4 Dmitrij Koniajev Dmitry Shulyak Dmitry Zenovich Domino Valdano +DongXi Huang <418498589@qq.com> Dragan Milic dragonvslinux <35779158+dragononcrypto@users.noreply.github.com> +Dylan Vassallo +easyfold <137396765+easyfold@users.noreply.github.com> Edgar Aroutiounian Eduard S Egon Elbre Elad Eli Elias Naur +Elias Rad <146735585+nnsW3@users.noreply.github.com> Elliot Shepherd Emil emile @@ -151,11 +232,13 @@ Evgeny Evgeny Danilenko <6655321@bk.ru> evgk Evolution404 <35091674+Evolution404@users.noreply.github.com> +Exca-DK <85954505+Exca-DK@users.noreply.github.com> EXEC Fabian Vogelsteller Fabio Barone Fabio Berger FaceHo +felipe Felipe Strozberg <48066928+FelStroz@users.noreply.github.com> Felix Lange Ferenc Szabo @@ -163,68 +246,102 @@ ferhat elmas Ferran Borreguero Fiisio Fire Man <55934298+basdevelop@users.noreply.github.com> +FletcherMan flowerofdream <775654398@qq.com> fomotrader <82184770+fomotrader@users.noreply.github.com> +Ford <153042616+guerrierindien@users.noreply.github.com> ForLina <471133417@qq.com> Frank Szendzielarz <33515470+FrankSzendzielarz@users.noreply.github.com> Frank Wang Franklin +Freeman Jiang Furkan KAMACI Fuyang Deng GagziW Gary Rong Gautam Botrel +Gealber Morales <48373523+Gealber@users.noreply.github.com> +George Ma <164313692+availhang@users.noreply.github.com> George Ornbo +georgehao +gitglorythegreat Giuseppe Bertone Greg Colvin Gregg Dourgarian Gregory Markou <16929357+GregTheGreek@users.noreply.github.com> +guangwu +Guido Vranken Guifel Guilherme Salgado Guillaume Ballet +Guillaume Michel Guillaume Nicolas GuiltyMorishita Guruprasad Kamath <48196632+gurukamath@users.noreply.github.com> Gus Gustav Simonsson +Gustavo Silva Gísli Kristjánsson Ha ĐANG HackyMiner -hadv +Halimao <1065621723@qq.com> Hanjiang Yu Hao Bryan Cheng Hao Duan +haoran <159284258+hr98w@users.noreply.github.com> +Haotian <51777534+tmelhao@users.noreply.github.com> HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Harry Dutton +Harry Kalodner haryu703 <34744512+haryu703@users.noreply.github.com> +hattizai Hendrik Hofstadt Henning Diedrich henopied <13500516+henopied@users.noreply.github.com> +henridf +Henry <101552941+henry-0@users.noreply.github.com> hero5512 holisticode Hongbin Mao Hsien-Tang Kao hsyodyssey <47173566+hsyodyssey@users.noreply.github.com> +Hteev Oli Husam Ibrahim <39692071+HusamIbrahim@users.noreply.github.com> Hwanjo Heo <34005989+hwanjo@users.noreply.github.com> hydai +hyhnet +hyunchel <3271191+hyunchel@users.noreply.github.com> Hyung-Kyu Hqueue Choi +Hyunsoo Shin (Lake) +hzysvilla Håvard Anda Estensen Ian Macalinao Ian Norden +Icarus Wu icodezjb -Ikko Ashimine +ids +Ignacio Hagopian +Ikko Eltociear Ashimine Ilan Gitter <8359193+gitteri@users.noreply.github.com> +imalasong <55082705+imalasong@users.noreply.github.com> ImanSharaf <78227895+ImanSharaf@users.noreply.github.com> +imulmat4 <117636097+imulmat4@users.noreply.github.com> +Inphi +int88 <106391185+int88@users.noreply.github.com> Isidoro Ghezzi Iskander (Alex) Sharipov +Ivan Aracki Ivan Bogatyy Ivan Daniluk Ivo Georgiev +j2gg0s jacksoom +jackyin <648588267@qq.com> Jae Kwon -James Prestwich <10149425+prestwich@users.noreply.github.com> +Jakub Freebit <49676311+jakub-freebit@users.noreply.github.com> +James Prestwich Jamie Pitts +Janko Simonovic Janoš Guljaš Jared Wasinger Jason Carver @@ -239,42 +356,63 @@ Jeff Wentworth Jeffery Robert Walsh Jeffrey Wilcke Jens Agerberg +Jens W <8270201+DragonDev1906@users.noreply.github.com> Jeremy McNevin Jeremy Schlatter Jerzy Lasyk Jesse Tane Jia Chenhui Jim McDonald +jin <35813306+lochjin@users.noreply.github.com> jk-jeongkyun <45347815+jeongkyun-oh@users.noreply.github.com> jkcomment +Joe Netti JoeGruffins <34998433+JoeGruffins@users.noreply.github.com> Joel Burget John C. Vernaleo +John Chase <68833933+joohhnnn@users.noreply.github.com> John Difool +John Hilliard +John Xu Johns Beharry +Jolly Zhao Jonas Jonathan Brown Jonathan Chappelow Jonathan Gimeno +Jonathan Otto JoranHonig Jordan Krage +Jorge Jorropo Joseph Chow +Joseph Cook <33655003+jmcook1186@users.noreply.github.com> Joshua Colvin Joshua Gutow jovijovi +jp-imx <109574657+jp-imx@users.noreply.github.com> jtakalai JU HYEONG PARK Julian Y Justin Clark-Casey +Justin Dhillon Justin Drake +Justin Traglia <95511699+jtraglia@users.noreply.github.com> Justus +KAI <35927054+ThreeAndTwo@users.noreply.github.com> +kaliubuntu0206 <139627505+kaliubuntu0206@users.noreply.github.com> +Karl Bartel +Karol Chojnowski Kawashima <91420903+sscodereth@users.noreply.github.com> +kazak ken10100147 Kenji Siu Kenso Trabing +Kero +kevaundray Kevin kevin.xu +Kiarash Hajian <133909368+kiarash8112@users.noreply.github.com> KibGzr kiel barry kilic @@ -282,8 +420,10 @@ kimmylin <30611210+kimmylin@users.noreply.github.com> Kitten King <53072918+kittenking@users.noreply.github.com> knarfeh Kobi Gurkan +Koichi Shiraishi komika Konrad Feldmeier +Kosuke Taniguchi <73885532+TaniguchiKosuke@users.noreply.github.com> Kris Shinn Kristofer Peterson Kumar Anirudha @@ -296,6 +436,8 @@ Lefteris Karapetsas Leif Jurvetson Leo Shklovskii LeoLiao +Leon <316032931@qq.com> +levisyin <150114626+levisyin@users.noreply.github.com> Lewis Marshall lhendre Li Dongwei @@ -305,36 +447,58 @@ libby kent libotony LieutenantRoger ligi +lilasxie +Lindlof Lio李欧 -lmittmann +Liyi Guo <102356659+colinlyguo@users.noreply.github.com> +llkhacquan <3724362+llkhacquan@users.noreply.github.com> +lmittmann <3458786+lmittmann@users.noreply.github.com> +lorenzo <31852651+lorenzo-dev1@users.noreply.github.com> Lorenzo Manacorda Louis Holbrook Luca Zeug +Lucas Lucas Hendren +Luozhu <70309026+LuozhuZhang@users.noreply.github.com> +lwh lzhfromustc <43191155+lzhfromustc@users.noreply.github.com> +Maciej Kulawik <10907694+magicxyyz@users.noreply.github.com> +Madhur Shrimal Magicking +makcandrov manlio +Manoj Kumar Maran Hidskes +Marcin Sobczak <77129288+marcindsobczak@users.noreply.github.com> +Marcus Baldassarre Marek Kotewicz Mariano Cortesi +Mario Vega +Marius G <90795310+bearpebble@users.noreply.github.com> +Marius Kjærstad Marius van der Wijden Mark Mark Rushakoff +Mark Tyneway mark.lin +markus <55011443+mdymalla@users.noreply.github.com> +Marquis Shanahan <29431502+9547@users.noreply.github.com> Martin Alex Philip Dawson Martin Holst Swende Martin Klepsch Martin Lundfall Martin Michlmayr Martin Redmond <21436+reds@users.noreply.github.com> +maskpp Mason Fischer Mateusz Morusiewicz <11313015+Ruteri@users.noreply.github.com> Mats Julian Olsen -Matt Garnett <14004106+lightclient@users.noreply.github.com> +Matt Garnett Matt K <1036969+mkrump@users.noreply.github.com> Matthew Di Ferrante Matthew Halpern Matthew Wampler-Doty +Matthieu Vachon Max Sistemich Maxim Zhiburt Maximilian Meister @@ -342,34 +506,55 @@ me020523 Melvin Junhee Woo meowsbits Micah Zoltu +Michael de Hoog Michael Forney Michael Riabzev Michael Ruminer michael1011 Miguel Mota Mike Burr +Mikel Cortes <45786396+cortze@users.noreply.github.com> Mikhail Mikheev +Mikhail Vazhnov +miles <66052478+miles-six@users.noreply.github.com> +Miles Chen milesvant +minh-bq <97180373+minh-bq@users.noreply.github.com> +Mio Miro Miya Chen +mmsqe +Mobin Mohanan <47410557+tr1sm0s1n@users.noreply.github.com> Mohanson +moomin <67548026+nothingmin@users.noreply.github.com> mr_franklin +Mskxn <118117161+Mskxn@users.noreply.github.com> Mudit Gupta Mymskmkt <1847234666@qq.com> Nalin Bhardwaj +nand2 +Nathan +Nathan Jo <162083209+qqqeck@users.noreply.github.com> Natsu Kagami +Naveen <116692862+naveen-imtb@users.noreply.github.com> Nchinda Nchinda -nebojsa94 +Nebojsa Urosevic necaremus nedifi <103940716+nedifi@users.noreply.github.com> needkane <604476380@qq.com> +Newt6611 <45097780+Newt6611@users.noreply.github.com> +Ng Wei Han <47109095+weiihann@users.noreply.github.com> Nguyen Kien Trung Nguyen Sy Thanh Son Nic Jansma +Nicholas Nick Dodson Nick Johnson +Nicola Cocchiaro <3538109+ncocchiaro@users.noreply.github.com> Nicolas Feignon +Nicolas Gotchac Nicolas Guillaume +Nikhil Suri Nikita Kozhemyakin Nikola Madjarevic Nilesh Trivedi @@ -379,32 +564,47 @@ njupt-moon <1015041018@njupt.edu.cn> nkbai noam-alchemy <76969113+noam-alchemy@users.noreply.github.com> nobody +noel <72006780+0x00Duke@users.noreply.github.com> Noman +norwnd <112318969+norwnd@users.noreply.github.com> nujabes403 Nye Liu +Obtuse7772 <117080049+Obtuse7772@users.noreply.github.com> Oleg Kovalov Oli Bye Oliver Tale-Yazdi Olivier Hervieu +openex Or Neeman +oseau Osoro Bironga Osuke +panicalways <113693386+panicalways@users.noreply.github.com> Pantelis Peslis +Parithosh Jayanthi +Park Changwan Pascal Dierich Patrick O'Grady Pau +Paul <41552663+molecula451@users.noreply.github.com> Paul Berg +Paul Lange Paul Litvak Paul-Armand Verhaegen Paulo L F Casaretto +Pawan Dhananjay Paweł Bylica Pedro Gomes Pedro Pombeiro +persmor <166146971+persmor@users.noreply.github.com> +Peter (bitfly) <1674920+peterbitfly@users.noreply.github.com> Peter Broadhurst peter cresswell Peter Pratscher Peter Simard +Peter Straus <153843855+krauspt@users.noreply.github.com> Petr Mikusek +phenix3443 Philip Schlump Pierre Neter Pierre R @@ -412,15 +612,24 @@ piersy PilkyuJung Piotr Dyraga ploui <64719999+ploui@users.noreply.github.com> +PolyMa <151764357+polymaer@users.noreply.github.com> Preston Van Loon Prince Sinha +psogv0308 +puhtaytow <18026645+puhtaytow@users.noreply.github.com> Péter Szilágyi +qcrao qd-ethan <31876119+qdgogogo@users.noreply.github.com> Qian Bin +qiuhaohao +Qt +Quentin McGaw Quest Henkart +Rachel Bousfield Rachel Franks Rafael Matias Raghav Sood +Rajaram Gaunker Ralph Caraveo Ramesh Nair rangzen @@ -430,45 +639,65 @@ rhaps107 Ricardo Catalinas Jiménez Ricardo Domingos Richard Hart +RichΛrd Rick RJ Catalano Rob Rob Mulholand Robert Zaremba +Roberto Bayardo Roc Yu +Roman Krasiuk Roman Mazalov <83914728+gopherxyz@users.noreply.github.com> Ross <9055337+Chadsr@users.noreply.github.com> +Rossen Krastev +Roy Crihfield Runchao Han +Ruohui Wang Russ Cox Ryan Schneider +Ryan Tinianov ryanc414 Rémy Roy S. Matthew English salanfe Sam <39165351+Xia-Sam@users.noreply.github.com> +Saman H. Pasha <51169592+saman-pasha@users.noreply.github.com> Sammy Libre <7374093+sammy007@users.noreply.github.com> Samuel Marks +Sanghee Choi <32831939+pengin7384@users.noreply.github.com> +SangIlMo <156392700+SangIlMo@users.noreply.github.com> sanskarkhare +SanYe Sarlor Sasuke1964 Satpal <28562234+SatpalSandhu61@users.noreply.github.com> Saulius Grigaitis Sean +seayyyy <163325936+seay404@users.noreply.github.com> +Sebastian Stammler Serhat Şevki Dinçer +Seungbae Yu +Seungmin Kim Shane Bammel shawn <36943337+lxex@users.noreply.github.com> shigeyuki azuchi Shihao Xia Shiming +Shiming Zhang Shintaro Kaneko shiqinfeng1 <150627601@qq.com> +Shivam Sandbhor +shivhg Shuai Qi Shude Li Shunsuke Watanabe +shuo silence Simon Jentzsch Sina Mahmoodi <1591639+s1na@users.noreply.github.com> sixdays +sjlee1125 <47561537+sjlee1125@users.noreply.github.com> SjonHortensius Slava Karpenko slumber1122 @@ -477,17 +706,29 @@ soc1c Sorin Neacsu Sparty Stein Dekker +Stephen Flynn +Stephen Guo Steve Gattuso +Steve Milk Steve Ruckdashel Steve Waldman Steven E. Harris Steven Roose stompesi stormpang +storyicon +strykerin +sudeep +SuiYuan <165623542+suiyuan1314@users.noreply.github.com> +Sungwoo Kim sunxiaojun2014 Suriyaa Sundararuban Sylvain Laurent +Szupingwang +tactical_retreat +Taeguk Kwon Taeik Lim +taiking tamirms Tangui Clairet Tatsuya Shimoda @@ -495,21 +736,35 @@ Taylor Gerring TColl <38299499+TColl@users.noreply.github.com> terasum tgyKomgo <52910426+tgyKomgo@users.noreply.github.com> +Thabokani <149070269+Thabokani@users.noreply.github.com> Thad Guidry +therainisme Thomas Bocek thomasmodeneis thumb8432 Ti Zhou tia-99 <67107070+tia-99@users.noreply.github.com> +tianyeyouyou +Tien Nguyen <116023870+htiennv@users.noreply.github.com> Tim Cooijmans +TinyFoxy Tobias Hildebrandt <79341166+tobias-hildebrandt@users.noreply.github.com> +tokikuch +Tom <45168162+tomdever@users.noreply.github.com> Tosh Camille +trillo +Tristan-Wilson <87238672+Tristan-Wilson@users.noreply.github.com> +trocher tsarpaul +TY <45994721+tylerK1294@users.noreply.github.com> Tyler Chambers <2775339+tylerchambers@users.noreply.github.com> +tylerni7 tzapu -ucwong +ucwong uji <49834542+uji@users.noreply.github.com> ult-bobonovski +Undefinedor +Ursulafe <152976968+Ursulafe@users.noreply.github.com> Valentin Trinqué Valentin Wüstholz Vedhavyas Singareddi @@ -528,39 +783,60 @@ Vitaly V Vivek Anand Vlad Bokov Vlad Gluhovsky +VM <112189277+sysvm@users.noreply.github.com> +vuittont60 <81072379+vuittont60@users.noreply.github.com> +wangjingcun +wangyifan Ward Bradt Water <44689567+codeoneline@users.noreply.github.com> wbt +Wei Tang weimumu <934657014@qq.com> Wenbiao Zheng Wenshao Zhong +Wihan de Beer Will Villanueva William Morriss William Setzer williambannas +willian.eth +winniehere +winterjihwan <113398351+winterjihwan@users.noreply.github.com> wuff1996 <33193253+wuff1996@users.noreply.github.com> Wuxiang Xiaobing Jiang +xiaodong <81516175+javaandfly@users.noreply.github.com> xiekeyang +xinbenlv xincaosu xinluyin <31590468+xinluyin@users.noreply.github.com> +xiyang <90125263+JBossBC@users.noreply.github.com> Xudong Liu <33193253+r1cs@users.noreply.github.com> xwjack yahtoo Yang Hau YaoZengzeng +ycyraum YH-Zhou +Yier <90763233+yierx@users.noreply.github.com> Yihau Chen +yihuang Yohann Léon Yoichi Hirai Yole <007yuyue@gmail.com> Yondon Fu +yong <33920876+yzhaoyu@users.noreply.github.com> YOSHIDA Masanori yoza +ysh0566 +yudrywet <166895665+yudrywet@users.noreply.github.com> +yujinpark +yukionfire yumiel yoomee1313 Yusup yutianwu ywzqwwt <39263032+ywzqwwt@users.noreply.github.com> +yzb <335357057@qq.com> zaccoding Zach Zachinquarantine @@ -568,24 +844,34 @@ zah Zahoor Mohamed Zak Cole zcheng9 +zeim839 <50573884+zeim839@users.noreply.github.com> zer0to0ne <36526113+zer0to0ne@users.noreply.github.com> zgfzgf <48779939+zgfzgf@users.noreply.github.com> Zhang Zhuo zhangsoledad <787953403@qq.com> zhaochonghe <41711151+zhaochonghe@users.noreply.github.com> +zhen peng <505380967@qq.com> Zhenguo Niu +Zheyuan He +Zhihao Lin <3955922+kkqy@users.noreply.github.com> zhiqiangxu <652732310@qq.com> Zhou Zhiyao Ziyuan Zhong Zoe Nolan +zoereco <158379334+zoereco@users.noreply.github.com> +Zoo +Zoro <40222601+BabyHalimao@users.noreply.github.com> Zou Guangxian Zsolt Felföldi Łukasz Kurowski Łukasz Zimnoch ΞTHΞЯSPHΞЯΞ <{viktor.tron,nagydani,zsfelfoldi}@gmail.com> Максим Чусовлянов +かげ <47621124+ronething-bot@users.noreply.github.com> +スパイク <1311798+spkjp@users.noreply.github.com> 大彬 沉风 +牛晓婕 <30611384+niuxiaojie81@users.noreply.github.com> 贺鹏飞 陈佳 유용환 <33824408+eric-yoo@users.noreply.github.com> diff --git a/beacon/light/sync/head_sync.go b/beacon/light/sync/head_sync.go index dd05d39588..5e41258053 100644 --- a/beacon/light/sync/head_sync.go +++ b/beacon/light/sync/head_sync.go @@ -1,4 +1,4 @@ -// Copyright 2023 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 diff --git a/beacon/params/networks.go b/beacon/params/networks.go index 5b00b27953..1204e0176f 100644 --- a/beacon/params/networks.go +++ b/beacon/params/networks.go @@ -1,4 +1,4 @@ -// Copyright 2016 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 diff --git a/cmd/abigen/namefilter.go b/cmd/abigen/namefilter.go index eea5c643c4..00945ef471 100644 --- a/cmd/abigen/namefilter.go +++ b/cmd/abigen/namefilter.go @@ -1,3 +1,19 @@ +// Copyright 2022 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 main import ( diff --git a/cmd/abigen/namefilter_test.go b/cmd/abigen/namefilter_test.go index ccee712018..254b3302e2 100644 --- a/cmd/abigen/namefilter_test.go +++ b/cmd/abigen/namefilter_test.go @@ -1,3 +1,19 @@ +// Copyright 2022 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 main import ( diff --git a/cmd/blsync/main.go b/cmd/blsync/main.go index d74e1496cd..57bc46c367 100644 --- a/cmd/blsync/main.go +++ b/cmd/blsync/main.go @@ -1,18 +1,18 @@ -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. +// Copyright 2024 The go-ethereum Authors +// This file is part of go-ethereum. // -// 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 +// 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. // -// The go-ethereum library is distributed in the hope that it will be useful, +// 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 Lesser General Public License for more details. +// GNU 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 . +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . package main diff --git a/cmd/evm/eofparse.go b/cmd/evm/eofparse.go index 92182a53b3..9710735576 100644 --- a/cmd/evm/eofparse.go +++ b/cmd/evm/eofparse.go @@ -1,4 +1,4 @@ -// Copyright 2023 The go-ethereum Authors +// Copyright 2024 The go-ethereum Authors // This file is part of go-ethereum. // // go-ethereum is free software: you can redistribute it and/or modify diff --git a/cmd/evm/eofparse_test.go b/cmd/evm/eofparse_test.go index cda4b38fc9..a9119916a5 100644 --- a/cmd/evm/eofparse_test.go +++ b/cmd/evm/eofparse_test.go @@ -1,3 +1,19 @@ +// Copyright 2024 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 main import ( diff --git a/cmd/geth/attach_test.go b/cmd/geth/attach_test.go index ceae3a122e..1df25359c5 100644 --- a/cmd/geth/attach_test.go +++ b/cmd/geth/attach_test.go @@ -1,18 +1,18 @@ // Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. +// This file is part of go-ethereum. // -// 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 +// 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. // -// The go-ethereum library is distributed in the hope that it will be useful, +// 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 Lesser General Public License for more details. +// GNU 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 . +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . package main diff --git a/cmd/geth/logging_test.go b/cmd/geth/logging_test.go index 4293a860ec..37fffecc30 100644 --- a/cmd/geth/logging_test.go +++ b/cmd/geth/logging_test.go @@ -1,5 +1,3 @@ -//go:build integrationtests - // Copyright 2023 The go-ethereum Authors // This file is part of go-ethereum. // @@ -16,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . +//go:build integrationtests + package main import ( diff --git a/cmd/geth/logtestcmd_active.go b/cmd/geth/logtestcmd_active.go index f2a2c5ded5..f9bbc3d4ec 100644 --- a/cmd/geth/logtestcmd_active.go +++ b/cmd/geth/logtestcmd_active.go @@ -1,5 +1,3 @@ -//go:build integrationtests - // Copyright 2023 The go-ethereum Authors // This file is part of go-ethereum. // @@ -16,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . +//go:build integrationtests + package main import ( diff --git a/cmd/geth/logtestcmd_inactive.go b/cmd/geth/logtestcmd_inactive.go index 691ab5bcd8..8dda1c47e4 100644 --- a/cmd/geth/logtestcmd_inactive.go +++ b/cmd/geth/logtestcmd_inactive.go @@ -1,5 +1,3 @@ -//go:build !integrationtests - // Copyright 2023 The go-ethereum Authors // This file is part of go-ethereum. // @@ -16,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . +//go:build !integrationtests + package main import "github.com/urfave/cli/v2" diff --git a/core/rawdb/accessors_trie.go b/core/rawdb/accessors_trie.go index bfe20767d9..8bd6b71eee 100644 --- a/core/rawdb/accessors_trie.go +++ b/core/rawdb/accessors_trie.go @@ -1,4 +1,4 @@ -// Copyright 2022 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 @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package rawdb diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go index 2923a2c224..7dada63d45 100644 --- a/core/state/statedb_fuzz_test.go +++ b/core/state/statedb_fuzz_test.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package state diff --git a/core/txindexer.go b/core/txindexer.go index b2f2188595..293124f681 100644 --- a/core/txindexer.go +++ b/core/txindexer.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package core diff --git a/core/txindexer_test.go b/core/txindexer_test.go index 246aec8b89..4425f0d9a5 100644 --- a/core/txindexer_test.go +++ b/core/txindexer_test.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package core diff --git a/core/txpool/blobpool/lookup.go b/core/txpool/blobpool/lookup.go index 2d8d0fd2bf..b5cf4d3799 100644 --- a/core/txpool/blobpool/lookup.go +++ b/core/txpool/blobpool/lookup.go @@ -1,4 +1,4 @@ -// Copyright 2022 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 diff --git a/core/txpool/legacypool/legacypool2_test.go b/core/txpool/legacypool/legacypool2_test.go index 8af9624994..d55e85d74f 100644 --- a/core/txpool/legacypool/legacypool2_test.go +++ b/core/txpool/legacypool/legacypool2_test.go @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . + package legacypool import ( diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 361dbe8b38..0ebf4c7e4b 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -1,4 +1,4 @@ -// Copyright 2023 The go-ethereum Authors +// Copyright 2014 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 diff --git a/core/types/tx_blob_test.go b/core/types/tx_blob_test.go index 6bd0f183b7..b9e6dcb0bb 100644 --- a/core/types/tx_blob_test.go +++ b/core/types/tx_blob_test.go @@ -1,3 +1,19 @@ +// 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 types import ( diff --git a/core/vm/eof_control_flow.go b/core/vm/eof_control_flow.go index 8230780773..c0a4459906 100644 --- a/core/vm/eof_control_flow.go +++ b/core/vm/eof_control_flow.go @@ -1,18 +1,18 @@ // Copyright 2024 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// 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 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser 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 . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package vm diff --git a/core/vm/eof_test.go b/core/vm/eof_test.go index 8106a29728..0a9cf638ce 100644 --- a/core/vm/eof_test.go +++ b/core/vm/eof_test.go @@ -1,4 +1,4 @@ -// Copyright 2022 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 diff --git a/core/vm/jump_table_test.go b/core/vm/jump_table_test.go index 02558035c0..a4f9759ed2 100644 --- a/core/vm/jump_table_test.go +++ b/core/vm/jump_table_test.go @@ -1,4 +1,4 @@ -// Copyright 2022 The go-ethereum Authors +// Copyright 2016 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 diff --git a/core/vm/memory_test.go b/core/vm/memory_test.go index ba36f8023c..41389b729a 100644 --- a/core/vm/memory_test.go +++ b/core/vm/memory_test.go @@ -1,3 +1,19 @@ +// 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 vm import ( diff --git a/core/vm/program/program.go b/core/vm/program/program.go index 3b00bbae6f..5b9cfdcc5f 100644 --- a/core/vm/program/program.go +++ b/core/vm/program/program.go @@ -1,18 +1,18 @@ // Copyright 2024 The go-ethereum Authors // This file is part of the go-ethereum library. // -// The library is free software: you can redistribute it and/or modify +// 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. // -// This library is distributed in the hope that it will be useful, +// 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 goevmlab library. If not, see . +// along with the go-ethereum library. If not, see . // package program is a utility to create EVM bytecode for testing, but _not_ for production. As such: // diff --git a/core/vm/program/program_test.go b/core/vm/program/program_test.go index 0b34210067..ceb7d8be64 100644 --- a/core/vm/program/program_test.go +++ b/core/vm/program/program_test.go @@ -1,18 +1,18 @@ // Copyright 2024 The go-ethereum Authors // This file is part of the go-ethereum library. // -// The library is free software: you can redistribute it and/or modify +// 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. // -// This library is distributed in the hope that it will be useful, +// 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 goevmlab library. If not, see . +// along with the go-ethereum library. If not, see . package program diff --git a/eth/tracers/dir.go b/eth/tracers/dir.go index 1cdfab5454..05c76bceb7 100644 --- a/eth/tracers/dir.go +++ b/eth/tracers/dir.go @@ -1,4 +1,4 @@ -// Copyright 2017 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 diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go index 553eaf1b57..4390a62b4b 100644 --- a/eth/tracers/internal/tracetest/flat_calltrace_test.go +++ b/eth/tracers/internal/tracetest/flat_calltrace_test.go @@ -1,3 +1,19 @@ +// 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 tracetest import ( diff --git a/eth/tracers/internal/tracetest/makeTest.js b/eth/tracers/internal/tracetest/makeTest.js index 7a50748930..826c91f639 100644 --- a/eth/tracers/internal/tracetest/makeTest.js +++ b/eth/tracers/internal/tracetest/makeTest.js @@ -1,3 +1,19 @@ +// 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 . + // 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. diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go index ad3d75d8de..680645970a 100644 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ b/eth/tracers/internal/tracetest/prestate_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 The go-ethereum Authors +// 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 diff --git a/eth/tracers/internal/tracetest/supply_test.go b/eth/tracers/internal/tracetest/supply_test.go index dc46b6d5ef..3d54ab1868 100644 --- a/eth/tracers/internal/tracetest/supply_test.go +++ b/eth/tracers/internal/tracetest/supply_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 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 diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go index 524a396d5c..85727e29ed 100644 --- a/eth/tracers/internal/tracetest/util.go +++ b/eth/tracers/internal/tracetest/util.go @@ -1,3 +1,19 @@ +// 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 tracetest import ( diff --git a/eth/tracers/internal/util.go b/eth/tracers/internal/util.go index cff6295566..88a9f5db44 100644 --- a/eth/tracers/internal/util.go +++ b/eth/tracers/internal/util.go @@ -1,4 +1,4 @@ -// Copyright 2023 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 diff --git a/eth/tracers/internal/util_test.go b/eth/tracers/internal/util_test.go index 6a467314cc..d6b51c4d86 100644 --- a/eth/tracers/internal/util_test.go +++ b/eth/tracers/internal/util_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 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 @@ -13,6 +13,7 @@ // // 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 ( diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index e56d011139..4e7fc31a9c 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -1,4 +1,4 @@ -// Copyright 2022 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 diff --git a/eth/tracers/tracker_test.go b/eth/tracers/tracker_test.go index 46f6ac8e51..447ab4e6b6 100644 --- a/eth/tracers/tracker_test.go +++ b/eth/tracers/tracker_test.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package tracers diff --git a/ethclient/simulated/backend_test.go b/ethclient/simulated/backend_test.go index 8efe93e243..5bf3c6be27 100644 --- a/ethclient/simulated/backend_test.go +++ b/ethclient/simulated/backend_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 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 diff --git a/ethclient/simulated/rollback_test.go b/ethclient/simulated/rollback_test.go index 8fc9f5bc86..57c59496d5 100644 --- a/ethclient/simulated/rollback_test.go +++ b/ethclient/simulated/rollback_test.go @@ -1,3 +1,19 @@ +// Copyright 2025 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 simulated import ( diff --git a/ethdb/pebble/pebble_test.go b/ethdb/pebble/pebble_test.go index 1d5611f211..3265491d4a 100644 --- a/ethdb/pebble/pebble_test.go +++ b/ethdb/pebble/pebble_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 The go-ethereum Authors +// Copyright 2019 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 diff --git a/graphql/internal/graphiql/build.go b/graphql/internal/graphiql/build.go index 0065c1112f..1daa406a88 100644 --- a/graphql/internal/graphiql/build.go +++ b/graphql/internal/graphiql/build.go @@ -1,3 +1,19 @@ +// 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 graphiql import ( diff --git a/internal/era/accumulator.go b/internal/era/accumulator.go index 2ece2755e1..cb383d8e63 100644 --- a/internal/era/accumulator.go +++ b/internal/era/accumulator.go @@ -1,18 +1,18 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of go-ethereum. +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. // -// 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 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser 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 . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package era diff --git a/internal/era/builder.go b/internal/era/builder.go index 33261555ba..975561564c 100644 --- a/internal/era/builder.go +++ b/internal/era/builder.go @@ -1,18 +1,18 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of go-ethereum. +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. // -// 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 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser 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 . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package era diff --git a/internal/era/e2store/e2store.go b/internal/era/e2store/e2store.go index 8e4d5dd24a..9832b72d48 100644 --- a/internal/era/e2store/e2store.go +++ b/internal/era/e2store/e2store.go @@ -1,18 +1,18 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of go-ethereum. +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. // -// 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 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser 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 . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package e2store diff --git a/internal/era/e2store/e2store_test.go b/internal/era/e2store/e2store_test.go index 353942f0bd..cdaefc484e 100644 --- a/internal/era/e2store/e2store_test.go +++ b/internal/era/e2store/e2store_test.go @@ -1,18 +1,18 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of go-ethereum. +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. // -// 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 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser 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 . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package e2store diff --git a/internal/era/era.go b/internal/era/era.go index 6ad7339b36..daf337963d 100644 --- a/internal/era/era.go +++ b/internal/era/era.go @@ -1,18 +1,18 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of go-ethereum. +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. // -// 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 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser 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 . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package era diff --git a/internal/era/era_test.go b/internal/era/era_test.go index d0f56b6f88..e0bebfa449 100644 --- a/internal/era/era_test.go +++ b/internal/era/era_test.go @@ -1,18 +1,18 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of go-ethereum. +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. // -// 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 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser 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 . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package era diff --git a/internal/era/iterator.go b/internal/era/iterator.go index f48aab46b4..3c4f82d850 100644 --- a/internal/era/iterator.go +++ b/internal/era/iterator.go @@ -1,18 +1,18 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of go-ethereum. +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. // -// 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 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser 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 . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package era diff --git a/miner/payload_building.go b/miner/payload_building.go index 3090de5d4b..6b010186bf 100644 --- a/miner/payload_building.go +++ b/miner/payload_building.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package miner diff --git a/miner/payload_building_test.go b/miner/payload_building_test.go index 307024c6bb..e0791921d6 100644 --- a/miner/payload_building_test.go +++ b/miner/payload_building_test.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package miner diff --git a/miner/pending.go b/miner/pending.go index bb91fe8969..9480f9cae8 100644 --- a/miner/pending.go +++ b/miner/pending.go @@ -1,4 +1,4 @@ -// Copyright 2024 The go-ethereum Authors +// Copyright 2016 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 diff --git a/p2p/config.go b/p2p/config.go index 14492a2e55..5ea62e12f5 100644 --- a/p2p/config.go +++ b/p2p/config.go @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . + package p2p import ( diff --git a/p2p/pipes/pipe.go b/p2p/pipes/pipe.go index cf1f3e2a80..a1423687bb 100644 --- a/p2p/pipes/pipe.go +++ b/p2p/pipes/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2024 The go-ethereum Authors +// 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 diff --git a/rpc/client_opt_test.go b/rpc/client_opt_test.go index d7cc2572a7..f62f689f6a 100644 --- a/rpc/client_opt_test.go +++ b/rpc/client_opt_test.go @@ -1,3 +1,19 @@ +// 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 rpc_test import ( diff --git a/tests/fuzzers/difficulty/difficulty_test.go b/tests/fuzzers/difficulty/difficulty_test.go index 49beedb486..c906089f8a 100644 --- a/tests/fuzzers/difficulty/difficulty_test.go +++ b/tests/fuzzers/difficulty/difficulty_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 The go-ethereum Authors +// 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 diff --git a/tests/fuzzers/rangeproof/rangeproof_test.go b/tests/fuzzers/rangeproof/rangeproof_test.go index bc7badc5b3..6b8d140e9c 100644 --- a/tests/fuzzers/rangeproof/rangeproof_test.go +++ b/tests/fuzzers/rangeproof/rangeproof_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 The go-ethereum Authors +// 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 diff --git a/tests/fuzzers/txfetcher/txfetcher_test.go b/tests/fuzzers/txfetcher/txfetcher_test.go index ac2e6b1c67..c6647f62d4 100644 --- a/tests/fuzzers/txfetcher/txfetcher_test.go +++ b/tests/fuzzers/txfetcher/txfetcher_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 The go-ethereum Authors +// 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 diff --git a/trie/trie_id.go b/trie/trie_id.go index 8ab490ca3b..7ac371b53e 100644 --- a/trie/trie_id.go +++ b/trie/trie_id.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package trie diff --git a/trie/trienode/node.go b/trie/trienode/node.go index 047a7a4bd8..b09ec66374 100644 --- a/trie/trienode/node.go +++ b/trie/trienode/node.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package trienode diff --git a/trie/utils/verkle.go b/trie/utils/verkle.go index 1d33f6c3e5..dea210c046 100644 --- a/trie/utils/verkle.go +++ b/trie/utils/verkle.go @@ -1,4 +1,4 @@ -// Copyright 2023 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 diff --git a/trie/utils/verkle_test.go b/trie/utils/verkle_test.go index dbec29685b..44c67ba03e 100644 --- a/trie/utils/verkle_test.go +++ b/trie/utils/verkle_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 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 @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package utils diff --git a/trie/verkle.go b/trie/verkle.go index 2e4d62cd10..015b8f6590 100644 --- a/trie/verkle.go +++ b/trie/verkle.go @@ -1,4 +1,4 @@ -// Copyright 2023 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 diff --git a/trie/verkle_test.go b/trie/verkle_test.go index 84eec2ed30..f31ab02df9 100644 --- a/trie/verkle_test.go +++ b/trie/verkle_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 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 diff --git a/triedb/pathdb/errors.go b/triedb/pathdb/errors.go index 498bc9ec81..49e9c3ca64 100644 --- a/triedb/pathdb/errors.go +++ b/triedb/pathdb/errors.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/execute.go b/triedb/pathdb/execute.go index 80cecb82e7..2400f280a3 100644 --- a/triedb/pathdb/execute.go +++ b/triedb/pathdb/execute.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index d8fb99ade4..6ba9aaf1bb 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -1,4 +1,4 @@ -// Copyright 2022 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 @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/history_inspect.go b/triedb/pathdb/history_inspect.go index 7dbe5959dc..9458e2478b 100644 --- a/triedb/pathdb/history_inspect.go +++ b/triedb/pathdb/history_inspect.go @@ -12,7 +12,7 @@ // 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 diff --git a/triedb/pathdb/history_test.go b/triedb/pathdb/history_test.go index 953f023530..2928d19d74 100644 --- a/triedb/pathdb/history_test.go +++ b/triedb/pathdb/history_test.go @@ -1,4 +1,4 @@ -// Copyright 2022 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 @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/layertree.go b/triedb/pathdb/layertree.go index 0bd086c2f3..85a5e470e7 100644 --- a/triedb/pathdb/layertree.go +++ b/triedb/pathdb/layertree.go @@ -1,4 +1,4 @@ -// Copyright 2022 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 @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/metrics.go b/triedb/pathdb/metrics.go index 1a2559e38b..45dad6f1ae 100644 --- a/triedb/pathdb/metrics.go +++ b/triedb/pathdb/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2022 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 @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/nodes.go b/triedb/pathdb/nodes.go index dee8c872ac..c56e38066b 100644 --- a/triedb/pathdb/nodes.go +++ b/triedb/pathdb/nodes.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/reader.go b/triedb/pathdb/reader.go index a404409035..30f75d1058 100644 --- a/triedb/pathdb/reader.go +++ b/triedb/pathdb/reader.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/states.go b/triedb/pathdb/states.go index 969782e3c4..873a7ba618 100644 --- a/triedb/pathdb/states.go +++ b/triedb/pathdb/states.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/pathdb/states_test.go b/triedb/pathdb/states_test.go index 30eb6ad6c8..4d181cc914 100644 --- a/triedb/pathdb/states_test.go +++ b/triedb/pathdb/states_test.go @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package pathdb diff --git a/triedb/states.go b/triedb/states.go index 9fabdb088d..c5aa7c64b4 100644 --- a/triedb/states.go +++ b/triedb/states.go @@ -1,4 +1,4 @@ -// Copyright 2023 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 @@ -12,7 +12,7 @@ // 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 +// along with the go-ethereum library. If not, see . package triedb diff --git a/version/version.go b/version/version.go index 01bc97df51..9153e0308a 100644 --- a/version/version.go +++ b/version/version.go @@ -1,4 +1,4 @@ -// Copyright 2016 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 From 9e33b29c740cce33b0b8747e8a772e7995cbd022 Mon Sep 17 00:00:00 2001 From: ericxtheodore Date: Thu, 6 Feb 2025 06:19:09 +0800 Subject: [PATCH 100/940] build: update to Go 1.23.6 (#31130) Co-authored-by: Felix Lange --- build/checksums.txt | 92 +++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index 7270492ec9..9a7101a3d5 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,56 +5,50 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/ ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz -# version:golang 1.23.5 +# version:golang 1.23.6 # https://go.dev/dl/ -a6f3f4bbd3e6bdd626f79b668f212fbb5649daf75084fb79b678a0ae4d97423b go1.23.5.src.tar.gz -8d8bc7d1b362dd91426da9352741db298ff73e3e0a3ccbe6f607f80ba17647a4 go1.23.5.aix-ppc64.tar.gz -d8b310b0b6bd6a630307579165cfac8a37571483c7d6804a10dd73bbefb0827f go1.23.5.darwin-amd64.tar.gz -d2b06bf0b8299e0187dfe2d8ad39bd3dd96a6d93fe4d1cfd42c7872452f4a0a2 go1.23.5.darwin-amd64.pkg -047bfce4fbd0da6426bd30cd19716b35a466b1c15a45525ce65b9824acb33285 go1.23.5.darwin-arm64.tar.gz -f819ed94939e08a5016b9a607ec84ebbde6cb3fe59750c59d97aa300c3fd02df go1.23.5.darwin-arm64.pkg -2dec52821e1f04a538d00b2cafe70fa506f2eea94a551bfe3ce1238f1bd4966f go1.23.5.dragonfly-amd64.tar.gz -7204e7bc62913b12f18c61afe0bc1a92fd192c0e45a54125978592296cb84e49 go1.23.5.freebsd-386.tar.gz -90a119995ebc3e36082874df5fa8fe6da194946679d01ae8bef33c87aab99391 go1.23.5.freebsd-amd64.tar.gz -255d26d873e41ff2fc278013bb2e5f25cf2ebe8d0ec84c07e3bb1436216020d3 go1.23.5.freebsd-arm.tar.gz -2785d9122654980b59ca38305a11b34f2a1e12d9f7eb41d52efc137c1fc29e61 go1.23.5.freebsd-arm64.tar.gz -8f66a94018ab666d56868f61c579aa81e549ac9700979ce6004445d315be2d37 go1.23.5.freebsd-riscv64.tar.gz -4b7a69928385ec512a4e77a547e24118adbb92301d2be36187ff0852ba9e6303 go1.23.5.illumos-amd64.tar.gz -6ecf6a41d0925358905fa2641db0e1c9037aa5b5bcd26ca6734caf50d9196417 go1.23.5.linux-386.tar.gz -cbcad4a6482107c7c7926df1608106c189417163428200ce357695cc7e01d091 go1.23.5.linux-amd64.tar.gz -47c84d332123883653b70da2db7dd57d2a865921ba4724efcdf56b5da7021db0 go1.23.5.linux-arm64.tar.gz -04e0b5cf5c216f0aa1bf8204d49312ad0845800ab0702dfe4357c0b1241027a3 go1.23.5.linux-armv6l.tar.gz -e1d14ac2207c78d52b76ba086da18a004c70aeb58cba72cd9bef0da7d1602786 go1.23.5.linux-loong64.tar.gz -d9e937f2fac4fc863850fb4cc31ae76d5495029a62858ef09c78604472d354c0 go1.23.5.linux-mips.tar.gz -59710d0782abafd47e40d1cf96aafa596bbdee09ac7c61062404604f49bd523e go1.23.5.linux-mips64.tar.gz -bc528cd836b4aa6701a42093ed390ef9929639a0e2818759887dc5539e517cab go1.23.5.linux-mips64le.tar.gz -a0404764ea1fd4a175dc5193622b15be6ed1ab59cbfa478f5ae24531bafb6cbd go1.23.5.linux-mipsle.tar.gz -db110284a0c91d4545273f210ca95b9f89f6e3ac90f39eb819033a6b96f25897 go1.23.5.linux-ppc64.tar.gz -db268bf5710b5b1b82ab38722ba6e4427d9e4942aed78c7d09195a9dff329613 go1.23.5.linux-ppc64le.tar.gz -d9da15778442464f32acfa777ac731fd4d47362b233b83a0932380cb6d2d5dc8 go1.23.5.linux-riscv64.tar.gz -14924b917d35311eb130e263f34931043d4f9dc65f20684301bf8f60a72edcdf go1.23.5.linux-s390x.tar.gz -7b8074102e7f039bd6473c44f58cb323c98dcda48df98ad1f78aaa2664769c8f go1.23.5.netbsd-386.tar.gz -1a466b9c8900e66664b15c07548ecb156e8274cf1028ac5da84134728e6dbbed go1.23.5.netbsd-amd64.tar.gz -901c9e72038926e37a4dbde8f03d1d81fcb9992850901a3da1da5a25ef93e65b go1.23.5.netbsd-arm.tar.gz -221f69a7c3a920e3666633ee0b4e5c810176982e74339ba4693226996dc636e4 go1.23.5.netbsd-arm64.tar.gz -42e46cbf73febb8e6ddf848765ce1c39573736383b132402cdc487eb6be3ad06 go1.23.5.openbsd-386.tar.gz -f49e81fce17aab21800fab7c4b10c97ab02f8a9c807fdf8641ccf2f87d69289f go1.23.5.openbsd-amd64.tar.gz -d8bd7269d4670a46e702b64822254a654824347c35923ef1c444d2e8687381ea go1.23.5.openbsd-arm.tar.gz -9cb259adff431d4d28b18e3348e26fe07ea10380675051dcfd740934b5e8b9f2 go1.23.5.openbsd-arm64.tar.gz -72a03223c98fcecfb06e57c3edd584f99fb7f6574a42f59348473f354be1f379 go1.23.5.openbsd-ppc64.tar.gz -c06432b859afb36657207382b7bac03f961b8fafc18176b501d239575a9ace64 go1.23.5.openbsd-riscv64.tar.gz -b1f9b12b269ab5cd4aa7ae3dd3075c2407c1ea8bb1211e6835261f98931201cc go1.23.5.plan9-386.tar.gz -45b4026a103e2f6cd436e2b7ad24b24a40dd22c9903519b98b45c535574fa01a go1.23.5.plan9-amd64.tar.gz -6e28e26f8c1e8620006490260aa5743198843aa0003c400cb65cbf5e743b21c7 go1.23.5.plan9-arm.tar.gz -0496c9969f208bd597f3e63fb27068ce1c7ed776618da1007fcc1c8be83ca413 go1.23.5.solaris-amd64.tar.gz -8441605a005ea74c28d8c02ca5f2708c17b4df7e91796148b9f8760caafb05c1 go1.23.5.windows-386.zip -39962346d8d0cb0cc8716489ee33b08d7a220c24a9e45423487876dd4acbdac6 go1.23.5.windows-386.msi -96d74945d7daeeb98a7978d0cf099321d7eb821b45f5c510373d545162d39c20 go1.23.5.windows-amd64.zip -03e11a988a18ad7e3f9038cef836330af72ba0a454a502cda7b7faee07a0dd8a go1.23.5.windows-amd64.msi -0005b31dcf9732c280a5cceb6aa1c5ab8284bc2541d0256c221256080acf2a09 go1.23.5.windows-arm.zip -a8442de35cbac230db8c4b20e363055671f2295dc4d6b2b2dfec66b89a3c4bce go1.23.5.windows-arm.msi -4f20c2d8a5a387c227e3ef48c5506b22906139d8afd8d66a78ef3de8dda1d1c3 go1.23.5.windows-arm64.zip -6f54fb46b669345c734936c521f7e0f55555e63ed6e11efbbaaed06f9514773c go1.23.5.windows-arm64.msi +039c5b04e65279daceee8a6f71e70bd05cf5b801782b6f77c6e19e2ed0511222 go1.23.6.src.tar.gz +adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c go1.23.6.aix-ppc64.tar.gz +782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0 go1.23.6.darwin-amd64.tar.gz +5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221 go1.23.6.darwin-arm64.tar.gz +d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb go1.23.6.dragonfly-amd64.tar.gz +d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7 go1.23.6.freebsd-386.tar.gz +ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6 go1.23.6.freebsd-amd64.tar.gz +b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6 go1.23.6.freebsd-arm.tar.gz +004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310 go1.23.6.freebsd-arm64.tar.gz +ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a go1.23.6.freebsd-riscv64.tar.gz +7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8 go1.23.6.illumos-amd64.tar.gz +e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba go1.23.6.linux-386.tar.gz +9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d go1.23.6.linux-amd64.tar.gz +561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202 go1.23.6.linux-arm64.tar.gz +27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74 go1.23.6.linux-armv6l.tar.gz +c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750 go1.23.6.linux-loong64.tar.gz +e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622 go1.23.6.linux-mips.tar.gz +7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f go1.23.6.linux-mips64.tar.gz +74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a go1.23.6.linux-mips64le.tar.gz +09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb go1.23.6.linux-mipsle.tar.gz +5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c go1.23.6.linux-ppc64.tar.gz +0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99 go1.23.6.linux-ppc64le.tar.gz +f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3 go1.23.6.linux-riscv64.tar.gz +321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e go1.23.6.linux-s390x.tar.gz +92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c go1.23.6.netbsd-386.tar.gz +86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c go1.23.6.netbsd-amd64.tar.gz +4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816 go1.23.6.netbsd-arm.tar.gz +53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9 go1.23.6.netbsd-arm64.tar.gz +6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9 go1.23.6.openbsd-386.tar.gz +f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae go1.23.6.openbsd-amd64.tar.gz +3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f go1.23.6.openbsd-arm.tar.gz +cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c go1.23.6.openbsd-arm64.tar.gz +64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602 go1.23.6.openbsd-ppc64.tar.gz +c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377 go1.23.6.openbsd-riscv64.tar.gz +10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01 go1.23.6.plan9-386.tar.gz +9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f go1.23.6.plan9-amd64.tar.gz +8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83 go1.23.6.plan9-arm.tar.gz +b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7 go1.23.6.solaris-amd64.tar.gz +96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8 go1.23.6.windows-386.zip +53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243 go1.23.6.windows-amd64.zip +22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218 go1.23.6.windows-arm.zip +a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41 go1.23.6.windows-arm64.zip # version:golangci 1.63.4 # https://github.com/golangci/golangci-lint/releases/ From 1847b5f63552edeff1c5bbf6a281527d1b119269 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:33:40 +0100 Subject: [PATCH 101/940] build: update EEST fixtures to prague devnet-6 (#31088) Co-authored-by: lightclient --- build/checksums.txt | 6 +- build/ci.go | 4 +- tests/init_test.go | 21 ++-- tests/transaction_test.go | 32 ++++++ tests/transaction_test_util.go | 173 +++++++++++++++++++-------------- 5 files changed, 148 insertions(+), 88 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index 9a7101a3d5..76f05e5b63 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -1,9 +1,9 @@ # This file contains sha256 checksums of optional build dependencies. -# version:spec-tests 2.1.0 +# version:spec-tests pectra-devnet-6@v1.0.0 # https://github.com/ethereum/execution-spec-tests/releases -# https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/ -ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz +# https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/fixtures_pectra-devnet-6.tar.gz +b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz # version:golang 1.23.6 # https://go.dev/dl/ diff --git a/build/ci.go b/build/ci.go index 02a4d771f6..6aa57f9cd5 100644 --- a/build/ci.go +++ b/build/ci.go @@ -338,8 +338,8 @@ func downloadSpecTestFixtures(csdb *build.ChecksumDB, cachedir string) string { log.Fatal(err) } ext := ".tar.gz" - base := "fixtures_develop" // TODO(MariusVanDerWijden) rename once the version becomes part of the filename - url := fmt.Sprintf("https://github.com/ethereum/execution-spec-tests/releases/download/v%s/%s%s", executionSpecTestsVersion, base, ext) + base := "fixtures_pectra-devnet-6" // TODO(s1na) rename once the version becomes part of the filename + url := fmt.Sprintf("https://github.com/ethereum/execution-spec-tests/releases/download/%s/%s%s", executionSpecTestsVersion, base, ext) archivePath := filepath.Join(cachedir, base+ext) if err := csdb.DownloadFile(url, archivePath); err != nil { log.Fatal(err) diff --git a/tests/init_test.go b/tests/init_test.go index effeec2b86..b933c9808c 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -34,16 +34,17 @@ import ( ) var ( - baseDir = filepath.Join(".", "testdata") - blockTestDir = filepath.Join(baseDir, "BlockchainTests") - stateTestDir = filepath.Join(baseDir, "GeneralStateTests") - legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests") - transactionTestDir = filepath.Join(baseDir, "TransactionTests") - rlpTestDir = filepath.Join(baseDir, "RLPTests") - difficultyTestDir = filepath.Join(baseDir, "BasicTests") - executionSpecBlockchainTestDir = filepath.Join(".", "spec-tests", "fixtures", "blockchain_tests") - executionSpecStateTestDir = filepath.Join(".", "spec-tests", "fixtures", "state_tests") - benchmarksDir = filepath.Join(".", "evm-benchmarks", "benchmarks") + baseDir = filepath.Join(".", "testdata") + blockTestDir = filepath.Join(baseDir, "BlockchainTests") + stateTestDir = filepath.Join(baseDir, "GeneralStateTests") + legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests") + transactionTestDir = filepath.Join(baseDir, "TransactionTests") + rlpTestDir = filepath.Join(baseDir, "RLPTests") + difficultyTestDir = filepath.Join(baseDir, "BasicTests") + executionSpecBlockchainTestDir = filepath.Join(".", "spec-tests", "fixtures", "blockchain_tests") + executionSpecStateTestDir = filepath.Join(".", "spec-tests", "fixtures", "state_tests") + executionSpecTransactionTestDir = filepath.Join(".", "spec-tests", "fixtures", "transaction_tests") + benchmarksDir = filepath.Join(".", "evm-benchmarks", "benchmarks") ) func readJSON(reader io.Reader, value interface{}) error { diff --git a/tests/transaction_test.go b/tests/transaction_test.go index 5179fc9afe..8147173905 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -19,6 +19,7 @@ package tests import ( "testing" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" ) @@ -42,6 +43,20 @@ func TestTransaction(t *testing.T) { // Geth accepts it, which is not a consensus issue since we use big.Int's // internally to calculate the cost txt.skipLoad("^ttValue/TransactionWithHighValueOverflow.json") + + // The size of a create tx's initcode is only checked during the state + // transition + txt.skipLoad("^ttEIP3860/DataTestInitCodeTooBig.json") + + // The following tests require the tx precheck to be performed + // TODO(s1na): expose stateTransition.precheck publicly to be able to run these tests + txt.skipLoad("^ttEIP1559/maxPriorityFeePerGass32BytesValue.json") + txt.skipLoad("^ttEIP1559/maxPriorityFeePerGasOverflow.json") + txt.skipLoad("^ttEIP1559/maxFeePerGas32BytesValue.json") + txt.skipLoad("^ttEIP1559/maxFeePerGasOverflow.json") + txt.skipLoad("^ttEIP1559/GasLimitPriceProductPlusOneOverflow.json") + txt.skipLoad("^ttEIP1559/GasLimitPriceProductOverflow.json") + txt.walk(t, transactionTestDir, func(t *testing.T, name string, test *TransactionTest) { cfg := params.MainnetChainConfig if err := txt.checkFailure(t, test.Run(cfg)); err != nil { @@ -49,3 +64,20 @@ func TestTransaction(t *testing.T) { } }) } + +func TestExecutionSpecTransaction(t *testing.T) { + if !common.FileExist(executionSpecStateTestDir) { + t.Skipf("directory %s does not exist", executionSpecStateTestDir) + } + st := new(testMatcher) + + // Emptiness of authorization list is only validated during the tx precheck + st.skipLoad("^prague/eip7702_set_code_tx/invalid_tx/empty_authorization_list.json") + + st.walk(t, executionSpecTransactionTestDir, func(t *testing.T, name string, test *TransactionTest) { + cfg := params.MainnetChainConfig + if err := st.checkFailure(t, test.Run(cfg)); err != nil { + t.Error(err) + } + }) +} diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 55b76df89c..3f91a82ec5 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -21,93 +21,120 @@ 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/types" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" ) // TransactionTest checks RLP decoding and sender derivation of transactions. type TransactionTest struct { Txbytes hexutil.Bytes `json:"txbytes"` - Result ttResult -} - -type ttResult struct { - Byzantium ttFork - Constantinople ttFork - Istanbul ttFork - EIP150 ttFork - EIP158 ttFork - Frontier ttFork - Homestead ttFork + Result map[string]*ttFork } type ttFork struct { - Sender common.UnprefixedAddress `json:"sender"` - Hash common.UnprefixedHash `json:"hash"` + Sender *common.UnprefixedAddress `json:"sender"` + Hash *common.UnprefixedHash `json:"hash"` + Exception *string `json:"exception"` + IntrinsicGas math.HexOrDecimal64 `json:"intrinsicGas"` } -func (tt *TransactionTest) Run(config *params.ChainConfig) error { - validateTx := func(rlpData hexutil.Bytes, signer types.Signer, isHomestead bool, isIstanbul bool) (*common.Address, *common.Hash, error) { - tx := new(types.Transaction) - if err := rlp.DecodeBytes(rlpData, tx); err != nil { - return nil, nil, err - } - sender, err := types.Sender(signer, tx) - if err != nil { - return nil, nil, err - } - // Intrinsic gas - requiredGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, isHomestead, isIstanbul, false) - if err != nil { - return nil, nil, err - } - if requiredGas > tx.Gas() { - return nil, nil, fmt.Errorf("insufficient gas ( %d < %d )", tx.Gas(), requiredGas) - } - h := tx.Hash() - return &sender, &h, nil +func (tt *TransactionTest) validate() error { + if tt.Txbytes == nil { + return fmt.Errorf("missing txbytes") } - - for _, testcase := range []struct { - name string - signer types.Signer - fork ttFork - isHomestead bool - isIstanbul bool - }{ - {"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.Txbytes, testcase.signer, testcase.isHomestead, testcase.isIstanbul) - - if testcase.fork.Sender == (common.UnprefixedAddress{}) { - if err == nil { - return fmt.Errorf("expected error, got none (address %v)[%v]", sender.String(), testcase.name) - } - continue - } - // Should resolve the right address - if err != nil { - return fmt.Errorf("got error, expected none: %v", err) - } - if sender == nil { - return fmt.Errorf("sender was nil, should be %x", common.Address(testcase.fork.Sender)) - } - if *sender != common.Address(testcase.fork.Sender) { - return fmt.Errorf("sender mismatch: got %x, want %x", sender, testcase.fork.Sender) - } - if txhash == nil { - return fmt.Errorf("txhash was nil, should be %x", common.Hash(testcase.fork.Hash)) - } - if *txhash != common.Hash(testcase.fork.Hash) { - return fmt.Errorf("hash mismatch: got %x, want %x", *txhash, testcase.fork.Hash) + for name, fork := range tt.Result { + if err := tt.validateFork(fork); err != nil { + return fmt.Errorf("invalid %s: %v", name, err) + } + } + return nil +} + +func (tt *TransactionTest) validateFork(fork *ttFork) error { + if fork == nil { + return nil + } + if fork.Hash == nil && fork.Exception == nil { + return fmt.Errorf("missing hash and exception") + } + if fork.Hash != nil && fork.Sender == nil { + return fmt.Errorf("missing sender") + } + return nil +} + +func (tt *TransactionTest) Run(config *params.ChainConfig) error { + if err := tt.validate(); err != nil { + return err + } + validateTx := func(rlpData hexutil.Bytes, signer types.Signer, isHomestead, isIstanbul, isShanghai bool) (sender common.Address, hash common.Hash, requiredGas uint64, err error) { + tx := new(types.Transaction) + if err = tx.UnmarshalBinary(rlpData); err != nil { + return + } + sender, err = types.Sender(signer, tx) + if err != nil { + return + } + // Intrinsic gas + requiredGas, err = core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, isHomestead, isIstanbul, isShanghai) + if err != nil { + return + } + if requiredGas > tx.Gas() { + return sender, hash, 0, fmt.Errorf("insufficient gas ( %d < %d )", tx.Gas(), requiredGas) + } + hash = tx.Hash() + return sender, hash, requiredGas, nil + } + for _, testcase := range []struct { + name string + signer types.Signer + fork *ttFork + isHomestead bool + isIstanbul bool + isShanghai bool + }{ + {"Frontier", types.FrontierSigner{}, tt.Result["Frontier"], false, false, false}, + {"Homestead", types.HomesteadSigner{}, tt.Result["Homestead"], true, false, false}, + {"EIP150", types.HomesteadSigner{}, tt.Result["EIP150"], true, false, false}, + {"EIP158", types.NewEIP155Signer(config.ChainID), tt.Result["EIP158"], true, false, false}, + {"Byzantium", types.NewEIP155Signer(config.ChainID), tt.Result["Byzantium"], true, false, false}, + {"Constantinople", types.NewEIP155Signer(config.ChainID), tt.Result["Constantinople"], true, false, false}, + {"Istanbul", types.NewEIP155Signer(config.ChainID), tt.Result["Istanbul"], true, true, false}, + {"Berlin", types.NewEIP2930Signer(config.ChainID), tt.Result["Berlin"], true, true, false}, + {"London", types.NewLondonSigner(config.ChainID), tt.Result["London"], true, true, false}, + {"Paris", types.NewLondonSigner(config.ChainID), tt.Result["Paris"], true, true, false}, + {"Shanghai", types.NewLondonSigner(config.ChainID), tt.Result["Shanghai"], true, true, true}, + {"Cancun", types.NewCancunSigner(config.ChainID), tt.Result["Cancun"], true, true, true}, + {"Prague", types.NewPragueSigner(config.ChainID), tt.Result["Prague"], true, true, true}, + } { + if testcase.fork == nil { + continue + } + sender, hash, gas, err := validateTx(tt.Txbytes, testcase.signer, testcase.isHomestead, testcase.isIstanbul, testcase.isShanghai) + if err != nil { + if testcase.fork.Hash != nil { + return fmt.Errorf("unexpected error: %v", err) + } + continue + } + if testcase.fork.Exception != nil { + return fmt.Errorf("expected error %v, got none (%v)", *testcase.fork.Exception, err) + } + if common.Hash(*testcase.fork.Hash) != hash { + return fmt.Errorf("hash mismatch: got %x, want %x", hash, common.Hash(*testcase.fork.Hash)) + } + if common.Address(*testcase.fork.Sender) != sender { + return fmt.Errorf("sender mismatch: got %x, want %x", sender, testcase.fork.Sender) + } + if hash != common.Hash(*testcase.fork.Hash) { + return fmt.Errorf("hash mismatch: got %x, want %x", hash, testcase.fork.Hash) + } + if uint64(testcase.fork.IntrinsicGas) != gas { + return fmt.Errorf("intrinsic gas mismatch: got %d, want %d", gas, uint64(testcase.fork.IntrinsicGas)) } } return nil From 756cca7c6f1324a5acf6d39d94033a6a5c7ce4c4 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 6 Feb 2025 15:05:41 +0100 Subject: [PATCH 102/940] version: release go-ethereum v1.15.0 --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 9153e0308a..b6dfc70b12 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 0 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 0 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From d74c47f8dbaf5af43c1a58e932a6849089d3fdf3 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 6 Feb 2025 15:06:46 +0100 Subject: [PATCH 103/940] version: begin v1.15.1 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index b6dfc70b12..f700f9e973 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 0 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 1 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From d11e9c0b517364ae3a372af48f0b34f754e1dbc0 Mon Sep 17 00:00:00 2001 From: Marcin Sobczak <77129288+marcindsobczak@users.noreply.github.com> Date: Fri, 7 Feb 2025 02:59:12 +0100 Subject: [PATCH 104/940] cmd/devp2p/internal/ethtest: remove TD from status validation (#31137) After recent changes in Geth (removing TD): https://github.com/ethereum/go-ethereum/commit/39638c81c56db2b2dfe6f51999ffd3029ee212cb#diff-d70a44d4b7a0e84fe9dcca25d368f626ae6c9bc0b8fe9690074ba92d298bcc0d Non-Geth clients are failing many devp2p tests with an error: `peering failed: status exchange failed: wrong TD in status: have 1 want 0` Right now only Geth is passing it - all other clients are affected by this change. I think there should be no validation of TD when checking `Status` message in hive tests. Now Geth has 0 (and hive tests requires 0) and all other clients have actual TD. And on real networks there is no validation of TD when peering --- cmd/devp2p/internal/ethtest/conn.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/devp2p/internal/ethtest/conn.go b/cmd/devp2p/internal/ethtest/conn.go index 757b137aa1..b555b14784 100644 --- a/cmd/devp2p/internal/ethtest/conn.go +++ b/cmd/devp2p/internal/ethtest/conn.go @@ -316,9 +316,6 @@ loop: return fmt.Errorf("wrong head block in status, want: %#x (block %d) have %#x", want, chain.blocks[chain.Len()-1].NumberU64(), have) } - if have, want := msg.TD.Cmp(chain.TD()), 0; have != want { - return fmt.Errorf("wrong TD in status: have %v want %v", have, want) - } if have, want := msg.ForkID, chain.ForkID(); !reflect.DeepEqual(have, want) { return fmt.Errorf("wrong fork ID in status: have %v, want %v", have, want) } From 4cda8f06ea688cc3e523ee1e35425393ecad807c Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Sat, 8 Feb 2025 05:26:15 -0700 Subject: [PATCH 105/940] params,core/forkid: enable prague on holesky and sepolia (#31139) Agreed to the following fork dates for Holesky and Sepolia on ACDC 150 Holesky slot: 3710976 (Mon, Feb 24 at 21:55:12 UTC) Sepolia slot: 7118848 (Wed, Mar 5 at 07:29:36 UTC) --- core/forkid/forkid_test.go | 12 ++++++++---- params/config.go | 4 ++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go index de589c0d44..bebc20ad9d 100644 --- a/core/forkid/forkid_test.go +++ b/core/forkid/forkid_test.go @@ -91,8 +91,10 @@ func TestCreation(t *testing.T) { {1735372, 1677557087, ID{Hash: checksumToBytes(0xb96cbd13), Next: 1677557088}}, // Last MergeNetsplit block {1735372, 1677557088, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 1706655072}}, // First Shanghai block {1735372, 1706655071, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 1706655072}}, // Last Shanghai block - {1735372, 1706655072, ID{Hash: checksumToBytes(0x88cf81d9), Next: 0}}, // First Cancun block - {1735372, 2706655072, ID{Hash: checksumToBytes(0x88cf81d9), Next: 0}}, // Future Cancun block + {1735372, 1706655072, ID{Hash: checksumToBytes(0x88cf81d9), Next: 1741159776}}, // First Cancun block + {1735372, 1741159775, ID{Hash: checksumToBytes(0x88cf81d9), Next: 1741159776}}, // Last Cancun block + {1735372, 1741159776, ID{Hash: checksumToBytes(0xed88b5fd), Next: 0}}, // First Prague block + {1735372, 2741159776, ID{Hash: checksumToBytes(0xed88b5fd), Next: 0}}, // Future Prague block }, }, // Holesky test cases @@ -104,8 +106,10 @@ func TestCreation(t *testing.T) { {123, 0, ID{Hash: checksumToBytes(0xc61a6098), Next: 1696000704}}, // First MergeNetsplit block {123, 1696000704, ID{Hash: checksumToBytes(0xfd4f016b), Next: 1707305664}}, // First Shanghai block {123, 1707305663, ID{Hash: checksumToBytes(0xfd4f016b), Next: 1707305664}}, // Last Shanghai block - {123, 1707305664, ID{Hash: checksumToBytes(0x9b192ad0), Next: 0}}, // First Cancun block - {123, 2707305664, ID{Hash: checksumToBytes(0x9b192ad0), Next: 0}}, // Future Cancun block + {123, 1707305664, ID{Hash: checksumToBytes(0x9b192ad0), Next: 1740434112}}, // First Cancun block + {123, 1740434111, ID{Hash: checksumToBytes(0x9b192ad0), Next: 1740434112}}, // Last Cancun block + {123, 1740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 0}}, // First Prague block + {123, 2740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 0}}, // Future Prague block }, }, } diff --git a/params/config.go b/params/config.go index 0dbe4c509a..cb12098bc9 100644 --- a/params/config.go +++ b/params/config.go @@ -87,9 +87,11 @@ var ( MergeNetsplitBlock: nil, ShanghaiTime: newUint64(1696000704), CancunTime: newUint64(1707305664), + PragueTime: newUint64(1740434112), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, + Prague: DefaultPragueBlobConfig, }, } // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. @@ -114,9 +116,11 @@ var ( MergeNetsplitBlock: big.NewInt(1735371), ShanghaiTime: newUint64(1677557088), CancunTime: newUint64(1706655072), + PragueTime: newUint64(1741159776), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, + Prague: DefaultPragueBlobConfig, }, } // AllEthashProtocolChanges contains every protocol change (EIPs) introduced From 9064038a86eead5f181d065a8ceb9ca2dc09fdbc Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 11 Feb 2025 13:44:25 +0100 Subject: [PATCH 106/940] consensus/beacon: remove TestingTTDBlock (#31153) This removes the method `TestingTTDBlock` introduced by #30744. It was added to make the beacon consensus engine aware of the merge block in tests without relying on the total difficulty. However, tracking the merge block this way is very annoying. We usually configure forks in the `ChainConfig`, but the method is on the consensus engine, which isn't always created in the same place. By sidestepping the `ChainConfig` we don't get the usual fork-order checking, so it's possible to enable the merge before the London fork, for example. This in turn can lead to very hard-to-debug outputs and validation errors. So here I'm changing the consensus engine to check the `MergeNetsplitBlock` instead. Alternatively, we assume a network is merged if it has a `TerminalTotalDifficulty` of zero, which is a very common configuration in tests. --- consensus/beacon/consensus.go | 39 +++++-------------- eth/catalyst/api_test.go | 5 ++- eth/gasprice/gasprice_test.go | 11 +++--- eth/protocols/eth/handler_test.go | 4 +- eth/tracers/internal/tracetest/supply_test.go | 3 -- graphql/graphql_test.go | 7 +--- 6 files changed, 21 insertions(+), 48 deletions(-) diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index bdfddfff06..d80d24e272 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -61,8 +61,7 @@ var ( // is only used for necessary consensus checks. The legacy consensus engine can be any // engine implements the consensus interface (except the beacon itself). type Beacon struct { - ethone consensus.Engine // Original consensus engine used in eth1, e.g. ethash or clique - ttdblock *uint64 // Merge block-number for testchain generation without TTDs + ethone consensus.Engine // Original consensus engine used in eth1, e.g. ethash or clique } // New creates a consensus engine with the given embedded eth1 engine. @@ -73,16 +72,12 @@ func New(ethone consensus.Engine) *Beacon { return &Beacon{ethone: ethone} } -// TestingTTDBlock is a replacement mechanism for TTD-based pre-/post-merge -// splitting. With chain history deletion, TD calculations become impossible. -// This is fine for progressing the live chain, but to be able to generate test -// chains, we do need a split point. This method supports setting an explicit -// block number to use as the splitter *for testing*, instead of having to keep -// the notion of TDs in the client just for testing. -// -// The block with supplied number is regarded as the last pre-merge block. -func (beacon *Beacon) TestingTTDBlock(number uint64) { - beacon.ttdblock = &number +// isPostMerge reports whether the given block number is assumed to be post-merge. +// Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or +// PoA chain for unit testing purposes. +func isPostMerge(config *params.ChainConfig, block uint64) bool { + mergedAtGenesis := config.TerminalTotalDifficulty != nil && config.TerminalTotalDifficulty.Sign() == 0 + return mergedAtGenesis || config.MergeNetsplitBlock != nil && block >= config.MergeNetsplitBlock.Uint64() } // Author implements consensus.Engine, returning the verified author of the block. @@ -332,15 +327,7 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [ // Prepare implements consensus.Engine, initializing the difficulty field of a // header to conform to the beacon protocol. The changes are done inline. func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { - // The beacon engine requires access to total difficulties to be able to - // seal pre-merge and post-merge blocks. With the transition to removing - // old blocks, TDs become unaccessible, thus making TTD based pre-/post- - // merge decisions impossible. - // - // We do not need to seal non-merge blocks anymore live, but we do need - // to be able to generate test chains, thus we're reverting to a testing- - // settable field to direct that. - if beacon.ttdblock != nil && *beacon.ttdblock >= header.Number.Uint64() { + if !isPostMerge(chain.Config(), header.Number.Uint64()) { return beacon.ethone.Prepare(chain, header) } header.Difficulty = beaconDifficulty @@ -450,15 +437,7 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash { // the difficulty that a new block should have when created at time // given the parent block's time and difficulty. func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { - // The beacon engine requires access to total difficulties to be able to - // seal pre-merge and post-merge blocks. With the transition to removing - // old blocks, TDs become unaccessible, thus making TTD based pre-/post- - // merge decisions impossible. - // - // We do not need to seal non-merge blocks anymore live, but we do need - // to be able to generate test chains, thus we're reverting to a testing- - // settable field to direct that. - if beacon.ttdblock != nil && *beacon.ttdblock > parent.Number.Uint64() { + if !isPostMerge(chain.Config(), parent.Number.Uint64()+1) { return beacon.ethone.CalcDifficulty(chain, time, parent) } return beaconDifficulty diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index 8fc3361192..e91e07d05d 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -64,9 +64,12 @@ func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) { engine := beacon.New(ethash.NewFaker()) if merged { config.TerminalTotalDifficulty = common.Big0 + config.MergeNetsplitBlock = common.Big0 } else { - engine.TestingTTDBlock(uint64(n)) + // When !merged, the tests expect the next block after the generated chain to be in PoS. + config.MergeNetsplitBlock = big.NewInt(int64(n + 1)) } + genesis := &core.Genesis{ Config: &config, Alloc: types.GenesisAlloc{ diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 0a32c278cb..8e6524446f 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -147,11 +147,11 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, cancunBlock *big.Int, pe config.LondonBlock = londonBlock config.ArrowGlacierBlock = londonBlock config.GrayGlacierBlock = londonBlock - + if cancunBlock != nil { + // Enable the merge with cancun fork. + config.MergeNetsplitBlock = cancunBlock + } engine := beacon.New(ethash.NewFaker()) - engine.TestingTTDBlock(testHead + 1) - - td := params.GenesisDifficulty.Uint64() if cancunBlock != nil { ts := gspec.Timestamp + cancunBlock.Uint64()*10 // fixed 10 sec block time in blockgen @@ -209,10 +209,9 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, cancunBlock *big.Int, pe b.AddTx(types.MustSignNewTx(key, signer, blobTx)) } } - td += b.Difficulty().Uint64() }) + // Construct testing chain - gspec.Config.TerminalTotalDifficulty = new(big.Int).SetUint64(td) chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec, nil, engine, vm.Config{}, nil) if err != nil { t.Fatalf("Failed to create local chain, %v", err) diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index 5b35a2f935..f92599dba7 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -74,9 +74,7 @@ func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int, config = params.TestChainConfig engine = beacon.New(ethash.NewFaker()) ) - if !shanghai { - engine.TestingTTDBlock(math.MaxUint64) - } else { + if shanghai { config = ¶ms.ChainConfig{ ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), diff --git a/eth/tracers/internal/tracetest/supply_test.go b/eth/tracers/internal/tracetest/supply_test.go index 3d54ab1868..57ba628b78 100644 --- a/eth/tracers/internal/tracetest/supply_test.go +++ b/eth/tracers/internal/tracetest/supply_test.go @@ -75,8 +75,6 @@ func TestSupplyOmittedFields(t *testing.T) { } ) - gspec.Config.TerminalTotalDifficulty = big.NewInt(0) - out, _, err := testSupplyTracer(t, gspec, func(b *core.BlockGen) { b.SetPoS() }) @@ -546,7 +544,6 @@ func TestSupplySelfdestructItselfAndRevert(t *testing.T) { func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockGen)) ([]supplyInfo, *core.BlockChain, error) { engine := beacon.New(ethash.NewFaker()) - engine.TestingTTDBlock(1) traceOutputPath := filepath.ToSlash(t.TempDir()) traceOutputFilename := path.Join(traceOutputPath, "supply.jsonl") diff --git a/graphql/graphql_test.go b/graphql/graphql_test.go index 3e6a042dbb..0f6ba10b90 100644 --- a/graphql/graphql_test.go +++ b/graphql/graphql_test.go @@ -21,7 +21,6 @@ import ( "encoding/json" "fmt" "io" - "math" "math/big" "net/http" "strings" @@ -459,15 +458,13 @@ func newGQLService(t *testing.T, stack *node.Node, shanghai bool, gspec *core.Ge var engine = beacon.New(ethash.NewFaker()) if shanghai { gspec.Config.TerminalTotalDifficulty = common.Big0 + gspec.Config.MergeNetsplitBlock = common.Big0 // GenerateChain will increment timestamps by 10. // Shanghai upgrade at block 1. shanghaiTime := uint64(5) gspec.Config.ShanghaiTime = &shanghaiTime - } else { - // set an arbitrary large ttd as chains are required to be known to be merged - gspec.Config.TerminalTotalDifficulty = big.NewInt(math.MaxInt64) - engine.TestingTTDBlock(math.MaxUint64) } + ethBackend, err := eth.New(stack, ethConf) if err != nil { t.Fatalf("could not create eth backend: %v", err) From d2ca7cf9f190d190495cd9f12b3b1f79f8513b8c Mon Sep 17 00:00:00 2001 From: Harry Ngo <17699212+huyngopt1994@users.noreply.github.com> Date: Tue, 11 Feb 2025 19:45:44 +0700 Subject: [PATCH 107/940] p2p/discover: remove unused parameter in revalidationList.get (#31155) --- p2p/discover/table_reval.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/p2p/discover/table_reval.go b/p2p/discover/table_reval.go index 2465fee906..1519313d19 100644 --- a/p2p/discover/table_reval.go +++ b/p2p/discover/table_reval.go @@ -79,7 +79,7 @@ func (tr *tableRevalidation) nodeEndpointChanged(tab *Table, n *tableNode) { 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 { + if n := list.get(&tab.rand, tr.activeReq); n != nil { tr.startRequest(tab, n) } // Update nextTime regardless if any requests were started because @@ -203,7 +203,7 @@ type revalidationList struct { } // 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 { +func (list *revalidationList) get(rand randomSource, exclude map[enode.ID]struct{}) *tableNode { if len(list.nodes) == 0 { return nil } From 22b935449499e37526b63bc56583a757fc6bf1b5 Mon Sep 17 00:00:00 2001 From: Chen Kai <281165273grape@gmail.com> Date: Tue, 11 Feb 2025 20:52:43 +0800 Subject: [PATCH 108/940] p2p/discover: make discv5 response timeout configurable (#31119) --- p2p/discover/common.go | 8 ++++++-- p2p/discover/v5_udp.go | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/p2p/discover/common.go b/p2p/discover/common.go index cabc5c7962..767cc23b92 100644 --- a/p2p/discover/common.go +++ b/p2p/discover/common.go @@ -49,8 +49,9 @@ type Config struct { // All remaining settings are optional. // Packet handling configuration: - NetRestrict *netutil.Netlist // list of allowed IP networks - Unhandled chan<- ReadPacket // unhandled packets are sent on this channel + NetRestrict *netutil.Netlist // list of allowed IP networks + Unhandled chan<- ReadPacket // unhandled packets are sent on this channel + V5RespTimeout time.Duration // timeout for v5 queries // Node table configuration: Bootnodes []*enode.Node // list of bootstrap nodes @@ -73,6 +74,9 @@ func (cfg Config) withDefaults() Config { if cfg.RefreshInterval == 0 { cfg.RefreshInterval = 30 * time.Minute } + if cfg.V5RespTimeout == 0 { + cfg.V5RespTimeout = 700 * time.Millisecond + } // Debug/test settings: if cfg.Log == nil { diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 4453d10695..48256ea4de 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -42,8 +42,6 @@ const ( lookupRequestLimit = 3 // max requests against a single node during lookup findnodeResultLimit = 16 // applies in FINDNODE handler totalNodesResponseLimit = 5 // applies in waitForNodes - - respTimeoutV5 = 700 * time.Millisecond ) // codecV5 is implemented by v5wire.Codec (and testCodec). @@ -71,6 +69,7 @@ type UDPv5 struct { log log.Logger clock mclock.Clock validSchemes enr.IdentityScheme + respTimeout time.Duration // misc buffers used during message handling logcontext []interface{} @@ -158,6 +157,7 @@ func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { log: cfg.Log, validSchemes: cfg.ValidSchemes, clock: cfg.Clock, + respTimeout: cfg.V5RespTimeout, // channels into dispatch packetInCh: make(chan ReadPacket, 1), readNextCh: make(chan struct{}, 1), @@ -576,7 +576,7 @@ func (t *UDPv5) startResponseTimeout(c *callV5) { timer mclock.Timer done = make(chan struct{}) ) - timer = t.clock.AfterFunc(respTimeoutV5, func() { + timer = t.clock.AfterFunc(t.respTimeout, func() { <-done select { case t.respTimeoutCh <- &callTimeout{c, timer}: From cdb66c89d6f8de3afd5e8d72bb5a0e3f46c27362 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Tue, 11 Feb 2025 06:15:04 -0700 Subject: [PATCH 109/940] core/txpool/legacypool: add support for SetCode transactions (#31073) The new SetCode transaction type introduces some additional complexity when handling the transaction pool. This complexity stems from two new account behaviors: 1. The balance and nonce of an account can change during regular transaction execution *when they have a deployed delegation*. 2. The nonce and code of an account can change without any EVM execution at all. This is the "set code" mechanism introduced by EIP-7702. The first issue has already been considered extensively during the design of ERC-4337, and we're relatively confident in the solution of simply limiting the number of in-flight pending transactions an account can have to one. This puts a reasonable bound on transaction cancellation. Normally to cancel, you would need to spend 21,000 gas. Now it's possible to cancel for around the cost of warming the account and sending value (`2,600+9,000=11,600`). So 50% cheaper. The second issue is more novel and needs further consideration. Since authorizations are not bound to a specific transaction, we cannot drop transactions with conflicting authorizations. Otherwise, it might be possible to cherry-pick authorizations from txs and front run them with different txs at much lower fee amounts, effectively DoSing the authority. Fortunately, conflicting authorizations do not affect the underlying validity of the transaction so we can just accept both. --------- Co-authored-by: Marius van der Wijden Co-authored-by: Felix Lange --- core/txpool/blobpool/blobpool_test.go | 6 +- core/txpool/errors.go | 9 + core/txpool/legacypool/legacypool.go | 89 +++++++- core/txpool/legacypool/legacypool_test.go | 234 +++++++++++++++++++++- core/txpool/validation.go | 32 ++- core/types/transaction.go | 15 ++ 6 files changed, 368 insertions(+), 17 deletions(-) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index f7c9e4844b..8589e5c01d 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -142,6 +142,7 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { GasLimit: gasLimit, BaseFee: baseFee, ExcessBlobGas: &excessBlobGas, + Difficulty: common.Big0, } } @@ -1565,8 +1566,9 @@ func TestAdd(t *testing.T) { 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 + Number: big.NewInt(int64(chain.CurrentBlock().Number.Uint64() + 1)), + Difficulty: common.Big0, + BaseFee: chain.CurrentBlock().BaseFee, // invalid, but nothing checks it, yolo } // Inject the fake block into the chain txs := make([]*types.Transaction, len(tt.block)) diff --git a/core/txpool/errors.go b/core/txpool/errors.go index 3a6a913976..32e49db87c 100644 --- a/core/txpool/errors.go +++ b/core/txpool/errors.go @@ -60,4 +60,13 @@ var ( // input transaction of non-blob type when a blob transaction from this sender // remains pending (and vice-versa). ErrAlreadyReserved = errors.New("address already reserved") + + // ErrAuthorityReserved is returned if a transaction has an authorization + // signed by an address which already has in-flight transactions known to the + // pool. + ErrAuthorityReserved = errors.New("authority already reserved") + + // ErrAuthorityNonce is returned if a transaction has an authorization with + // a nonce that is not currently valid for the authority. + ErrAuthorityNonceTooLow = errors.New("authority nonce too low") ) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 1440af5440..c7ff954a49 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -21,6 +21,7 @@ import ( "errors" "math" "math/big" + "slices" "sort" "sync" "sync/atomic" @@ -196,6 +197,20 @@ func (config *Config) sanitize() Config { // The pool separates processable transactions (which can be applied to the // current state) and future transactions. Transactions move between those // two states over time as they are received and processed. +// +// In addition to tracking transactions, the pool also tracks a set of pending SetCode +// authorizations (EIP7702). This helps minimize number of transactions that can be +// trivially churned in the pool. As a standard rule, any account with a deployed +// delegation or an in-flight authorization to deploy a delegation will only be allowed a +// single transaction slot instead of the standard number. This is due to the possibility +// of the account being sweeped by an unrelated account. +// +// Because SetCode transactions can have many authorizations included, we avoid explicitly +// checking their validity to save the state lookup. So long as the encompassing +// transaction is valid, the authorization will be accepted and tracked by the pool. In +// case the pool is tracking a pending / queued transaction from a specific account, it +// will reject new transactions with delegations from that account with standard in-flight +// transactions. type LegacyPool struct { config Config chainconfig *params.ChainConfig @@ -263,7 +278,7 @@ func New(config Config, chain BlockChain) *LegacyPool { // pool, specifically, whether it is a Legacy, AccessList or Dynamic transaction. func (pool *LegacyPool) Filter(tx *types.Transaction) bool { switch tx.Type() { - case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType: + case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, types.SetCodeTxType: return true default: return false @@ -540,7 +555,8 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction) error { Accept: 0 | 1<= 0 { + list = append(list[:i], list[i+1:]...) + } else { + log.Error("Authority with untracked tx", "addr", addr, "hash", hash) + } + if len(list) == 0 { + // If list is newly empty, delete it entirely. + delete(t.auths, addr) + continue + } + t.auths[addr] = list + } +} + // numSlots calculates the number of slots needed for a single transaction. func numSlots(tx *types.Transaction) int { return int((tx.Size() + txSlotSize - 1) / txSlotSize) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index fdbcad3d4f..da28e8a75b 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -34,6 +34,7 @@ import ( "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/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" @@ -79,8 +80,9 @@ func (bc *testBlockChain) Config() *params.ChainConfig { func (bc *testBlockChain) CurrentBlock() *types.Header { return &types.Header{ - Number: new(big.Int), - GasLimit: bc.gasLimit.Load(), + Number: new(big.Int), + Difficulty: common.Big0, + GasLimit: bc.gasLimit.Load(), } } @@ -128,6 +130,39 @@ func dynamicFeeTx(nonce uint64, gaslimit uint64, gasFee *big.Int, tip *big.Int, return tx } +type unsignedAuth struct { + nonce uint64 + key *ecdsa.PrivateKey +} + +func setCodeTx(nonce uint64, key *ecdsa.PrivateKey, unsigned []unsignedAuth) *types.Transaction { + return pricedSetCodeTx(nonce, 250000, uint256.NewInt(1000), uint256.NewInt(1), key, unsigned) +} + +func pricedSetCodeTx(nonce uint64, gaslimit uint64, gasFee, tip *uint256.Int, key *ecdsa.PrivateKey, unsigned []unsignedAuth) *types.Transaction { + var authList []types.SetCodeAuthorization + for _, u := range unsigned { + auth, _ := types.SignSetCode(u.key, types.SetCodeAuthorization{ + ChainID: *uint256.MustFromBig(params.TestChainConfig.ChainID), + Address: common.Address{0x42}, + Nonce: u.nonce, + }) + authList = append(authList, auth) + } + return types.MustSignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.SetCodeTx{ + ChainID: uint256.MustFromBig(params.TestChainConfig.ChainID), + Nonce: nonce, + GasTipCap: tip, + GasFeeCap: gasFee, + Gas: gaslimit, + To: common.Address{}, + Value: uint256.NewInt(100), + Data: nil, + AccessList: nil, + AuthList: authList, + }) +} + func makeAddressReserver() txpool.AddressReserver { var ( reserved = make(map[common.Address]struct{}) @@ -2163,6 +2198,201 @@ func TestSlotCount(t *testing.T) { } } +// TestSetCodeTransactions tests a few scenarios regarding the EIP-7702 +// SetCodeTx. +func TestSetCodeTransactions(t *testing.T) { + t.Parallel() + + // Create the pool to test the status retrievals with + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed)) + + pool := New(testTxPoolConfig, blockchain) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + defer pool.Close() + + // Create the test accounts + var ( + keyA, _ = crypto.GenerateKey() + keyB, _ = crypto.GenerateKey() + keyC, _ = crypto.GenerateKey() + addrA = crypto.PubkeyToAddress(keyA.PublicKey) + addrB = crypto.PubkeyToAddress(keyB.PublicKey) + addrC = crypto.PubkeyToAddress(keyC.PublicKey) + ) + testAddBalance(pool, addrA, big.NewInt(params.Ether)) + testAddBalance(pool, addrB, big.NewInt(params.Ether)) + testAddBalance(pool, addrC, big.NewInt(params.Ether)) + + for _, tt := range []struct { + name string + pending int + queued int + run func(string) + }{ + { + // Check that only one in-flight transaction is allowed for accounts + // with delegation set. Also verify the accepted transaction can be + // replaced by fee. + name: "only-one-in-flight", + pending: 1, + run: func(name string) { + aa := common.Address{0xaa, 0xaa} + statedb.SetCode(addrA, append(types.DelegationPrefix, aa.Bytes()...)) + statedb.SetCode(aa, []byte{byte(vm.ADDRESS), byte(vm.PUSH0), byte(vm.SSTORE)}) + // Send transactions. First is accepted, second is rejected. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyA)); err != nil { + t.Fatalf("%s: failed to add remote transaction: %v", name, err) + } + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err) + } + // Also check gapped transaction. + if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err) + } + // Replace by fee. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyA)); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } + }, + }, + { + name: "allow-setcode-tx-with-pending-authority-tx", + pending: 2, + run: func(name string) { + // Send two transactions where the first has no conflicting delegations and + // the second should be allowed despite conflicting with the authorities in 1). + if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + if err := pool.addRemoteSync(setCodeTx(0, keyB, []unsignedAuth{{1, keyC}})); err != nil { + t.Fatalf("%s: failed to add conflicting delegation: %v", name, err) + } + }, + }, + { + name: "allow-one-tx-from-pooled-delegation", + pending: 2, + run: func(name string) { + // Verify C cannot originate another transaction when it has a pooled delegation. + if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{0, keyC}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyC)); err != nil { + t.Fatalf("%s: failed to add with pending delegatio: %v", name, err) + } + // Also check gapped transaction is rejected. + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err) + } + }, + }, + { + name: "replace-by-fee-setcode-tx", + pending: 1, + run: func(name string) { + // 4. Fee bump the setcode tx send. + if err := pool.addRemoteSync(setCodeTx(0, keyB, []unsignedAuth{{1, keyC}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(2000), uint256.NewInt(2), keyB, []unsignedAuth{{0, keyC}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + }, + }, + { + name: "allow-tx-from-replaced-authority", + pending: 2, + run: func(name string) { + // Fee bump with a different auth list. Make sure that unlocks the authorities. + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyB}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(3000), uint256.NewInt(300), keyA, []unsignedAuth{{0, keyC}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + // Now send a regular tx from B. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyB)); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } + }, + }, + { + name: "allow-tx-from-replaced-self-sponsor-authority", + pending: 2, + run: func(name string) { + // + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyA}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(30), uint256.NewInt(30), keyA, []unsignedAuth{{0, keyB}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + // Now send a regular tx from keyA. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyA)); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } + // Make sure we can still send from keyB. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyB)); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } + }, + }, + { + name: "track-multiple-conflicting-delegations", + pending: 3, + run: func(name string) { + // Send two setcode txs both with C as an authority. + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyC}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(30), uint256.NewInt(30), keyB, []unsignedAuth{{0, keyC}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + // Replace the tx from A with a non-setcode tx. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyA)); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } + // Make sure we can only pool one tx from keyC since it is still a + // pending authority. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil { + t.Fatalf("%s: failed to added single pooled for account with pending delegation: %v", name, err) + } + if err, want := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyC)), txpool.ErrAccountLimitExceeded; !errors.Is(err, want) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err) + } + }, + }, + { + name: "reject-delegation-from-pending-account", + pending: 1, + run: func(name string) { + // Attempt to submit a delegation from an account with a pending tx. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + if err, want := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})), txpool.ErrAuthorityReserved; !errors.Is(err, want) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err) + } + }, + }, + } { + tt.run(tt.name) + pending, queued := pool.Stats() + if pending != tt.pending { + t.Fatalf("%s: pending transactions mismatched: have %d, want %d", tt.name, pending, tt.pending) + } + if queued != tt.queued { + t.Fatalf("%s: queued transactions mismatched: have %d, want %d", tt.name, queued, tt.queued) + } + if err := validatePoolInternals(pool); err != nil { + t.Fatalf("%s: pool internal state corrupted: %v", tt.name, err) + } + pool.Clear() + } +} + // Benchmarks the speed of validating the contents of the pending queue of the // transaction pool. func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) } diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 8cd13776a6..4d53c386b6 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -70,17 +70,21 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types return fmt.Errorf("%w: transaction size %v, limit %v", ErrOversizedData, tx.Size(), opts.MaxSize) } // Ensure only transactions that have been enabled are accepted - if !opts.Config.IsBerlin(head.Number) && tx.Type() != types.LegacyTxType { + rules := opts.Config.Rules(head.Number, head.Difficulty.Sign() == 0, head.Time) + if !rules.IsBerlin && tx.Type() != types.LegacyTxType { return fmt.Errorf("%w: type %d rejected, pool not yet in Berlin", core.ErrTxTypeNotSupported, tx.Type()) } - if !opts.Config.IsLondon(head.Number) && tx.Type() == types.DynamicFeeTxType { + if !rules.IsLondon && tx.Type() == types.DynamicFeeTxType { return fmt.Errorf("%w: type %d rejected, pool not yet in London", core.ErrTxTypeNotSupported, tx.Type()) } - if !opts.Config.IsCancun(head.Number, head.Time) && tx.Type() == types.BlobTxType { + if !rules.IsCancun && tx.Type() == types.BlobTxType { return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type()) } + if !rules.IsPrague && tx.Type() == types.SetCodeTxType { + return fmt.Errorf("%w: type %d rejected, pool not yet in Prague", core.ErrTxTypeNotSupported, tx.Type()) + } // Check whether the init code size has been exceeded - if opts.Config.IsShanghai(head.Number, head.Time) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { + if rules.IsShanghai && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize) } // Transactions can't be negative. This may never happen using RLP decoded @@ -109,7 +113,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types } // Ensure the transaction has more gas than the bare minimum needed to cover // the transaction metadata - intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, true, opts.Config.IsIstanbul(head.Number), opts.Config.IsShanghai(head.Number, head.Time)) + intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, true, rules.IsIstanbul, rules.IsShanghai) if err != nil { return err } @@ -154,6 +158,11 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types return err } } + if tx.Type() == types.SetCodeTxType { + if len(tx.SetCodeAuthorizations()) == 0 { + return fmt.Errorf("set code tx must have at least one authorization tuple") + } + } return nil } @@ -209,6 +218,11 @@ type ValidationOptionsWithState struct { // ExistingCost is a mandatory callback to retrieve an already pooled // transaction's cost with the given nonce to check for overdrafts. ExistingCost func(addr common.Address, nonce uint64) *big.Int + + // KnownConflicts is an optional callback which iterates over the list of + // addresses and returns all addresses known to the pool with in-flight + // transactions. + KnownConflicts func(sender common.Address, authorizers []common.Address) []common.Address } // ValidateTransactionWithState is a helper method to check whether a transaction @@ -262,6 +276,14 @@ func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, op if used, left := opts.UsedAndLeftSlots(from); left <= 0 { return fmt.Errorf("%w: pooled %d txs", ErrAccountLimitExceeded, used) } + + // Verify no authorizations will invalidate existing transactions known to + // the pool. + if opts.KnownConflicts != nil { + if conflicts := opts.KnownConflicts(from, tx.SetCodeAuthorities()); len(conflicts) > 0 { + return fmt.Errorf("%w: authorization conflicts with other known tx", ErrAuthorityReserved) + } + } } return nil } diff --git a/core/types/transaction.go b/core/types/transaction.go index 35dc1ea3f9..7df13e04bb 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -483,6 +483,21 @@ func (tx *Transaction) SetCodeAuthorizations() []SetCodeAuthorization { return setcodetx.AuthList } +// SetCodeAuthorities returns a list of each authorization's corresponding authority. +func (tx *Transaction) SetCodeAuthorities() []common.Address { + setcodetx, ok := tx.inner.(*SetCodeTx) + if !ok { + return nil + } + auths := make([]common.Address, 0, len(setcodetx.AuthList)) + for _, auth := range setcodetx.AuthList { + if addr, err := auth.Authority(); err == nil { + auths = append(auths, addr) + } + } + return auths +} + // 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. From da71839a270a353bac92e3108e4b74fb0eefec29 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:02:30 +0100 Subject: [PATCH 110/940] internal/ethapi: fix panic in debug methods (#31157) Fixes an error when the block is not found in debug methods. --- internal/ethapi/api.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index c0b37c516b..92249f7829 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1675,7 +1675,7 @@ func (api *DebugAPI) GetRawHeader(ctx context.Context, blockNrOrHash rpc.BlockNu hash = h } else { block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash) - if err != nil { + if block == nil || err != nil { return nil, err } hash = block.Hash() @@ -1694,7 +1694,7 @@ func (api *DebugAPI) GetRawBlock(ctx context.Context, blockNrOrHash rpc.BlockNum hash = h } else { block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash) - if err != nil { + if block == nil || err != nil { return nil, err } hash = block.Hash() @@ -1713,7 +1713,7 @@ func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.Block hash = h } else { block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash) - if err != nil { + if block == nil || err != nil { return nil, err } hash = block.Hash() From 58f65c60c29873f480f5a6f2718b1fe68a8da9bd Mon Sep 17 00:00:00 2001 From: jwasinger Date: Tue, 11 Feb 2025 17:55:00 -0800 Subject: [PATCH 111/940] trie: copy preimage store pointer in StateTrie.Copy (#31158) This fixes an error where executing `evm run --dump ...` omits preimages from the dump (because the statedb used for execution is a copy of another instance). --- cmd/evm/testdata/evmrun/3.out.1.txt | 3 ++- cmd/evm/testdata/evmrun/4.out.1.txt | 3 ++- trie/secure_trie.go | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cmd/evm/testdata/evmrun/3.out.1.txt b/cmd/evm/testdata/evmrun/3.out.1.txt index 44956f54f6..25dd8da5a1 100644 --- a/cmd/evm/testdata/evmrun/3.out.1.txt +++ b/cmd/evm/testdata/evmrun/3.out.1.txt @@ -1,12 +1,13 @@ { "root": "b444481d1367188172f8c6091e948aaa68bae763fd26d6b9e994306a66bf69f9", "accounts": { - "pre(0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142)": { + "0x0000000000000000000000007265636569766572": { "balance": "0", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0x3e48ef54b89079a075f3b8fc253c657a86b110a7aed3568c1517b10edf2c3eb6", "code": "0x6040", + "address": "0x0000000000000000000000007265636569766572", "key": "0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142" } } diff --git a/cmd/evm/testdata/evmrun/4.out.1.txt b/cmd/evm/testdata/evmrun/4.out.1.txt index 44956f54f6..25dd8da5a1 100644 --- a/cmd/evm/testdata/evmrun/4.out.1.txt +++ b/cmd/evm/testdata/evmrun/4.out.1.txt @@ -1,12 +1,13 @@ { "root": "b444481d1367188172f8c6091e948aaa68bae763fd26d6b9e994306a66bf69f9", "accounts": { - "pre(0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142)": { + "0x0000000000000000000000007265636569766572": { "balance": "0", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0x3e48ef54b89079a075f3b8fc253c657a86b110a7aed3568c1517b10edf2c3eb6", "code": "0x6040", + "address": "0x0000000000000000000000007265636569766572", "key": "0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142" } } diff --git a/trie/secure_trie.go b/trie/secure_trie.go index f53b10758f..45d5fd63e7 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -275,6 +275,7 @@ func (t *StateTrie) Copy() *StateTrie { trie: *t.trie.Copy(), db: t.db, secKeyCache: t.secKeyCache, + preimages: t.preimages, } } From 24ed0b506602cf18e92c2ec5b75173a68178748b Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Thu, 13 Feb 2025 09:45:27 +0100 Subject: [PATCH 112/940] go.mod: update blst to v0.3.14 (#31165) closes https://github.com/ethereum/go-ethereum/issues/31072 BLST released their newest version which includes a fix for go v.1.24: https://github.com/supranational/blst/releases/tag/v0.3.14 I went through all commits between 0.3.14 and 0.3.13 for a sanity check --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fc768460c7..cf9fda50c8 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/status-im/keycard-go v0.2.0 github.com/stretchr/testify v1.9.0 - github.com/supranational/blst v0.3.13 + github.com/supranational/blst v0.3.14 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/urfave/cli/v2 v2.25.7 go.uber.org/automaxprocs v1.5.2 diff --git a/go.sum b/go.sum index 82836a5d8c..9812cbbab5 100644 --- a/go.sum +++ b/go.sum @@ -508,8 +508,8 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl 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/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= -github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= +github.com/supranational/blst v0.3.14/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/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= From 8ec4a06b3f0686a3c181c5f88c899390ee80fb60 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 13 Feb 2025 13:05:05 +0100 Subject: [PATCH 113/940] core: sanity-check fork configuration in genesis (#31171) This is to prevent a crash on startup with a custom genesis configuration. With this change in place, upgrading a chain created by geth v1.14.x and below will now print an error instead of crashing: Fatal: Failed to register the Ethereum service: invalid chain configuration: missing entry for fork "cancun" in blobSchedule Arguably this is not great, and it should just auto-upgrade the config. We'll address this in a follow-up PR for geth v1.15.2 --- core/genesis.go | 5 +++++ params/config.go | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/genesis.go b/core/genesis.go index 8546f4e37e..4dd6c9ed24 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -364,6 +364,11 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g } newCfg := genesis.chainConfigOrDefault(ghash, storedCfg) + // Sanity-check the new configuration. + if err := newCfg.CheckConfigForkOrder(); err != nil { + return nil, common.Hash{}, nil, err + } + // TODO(rjl493456442) better to define the comparator of chain config // and short circuit if the chain config is not changed. compatErr := storedCfg.CheckCompatible(newCfg, head.Number.Uint64(), head.Time) diff --git a/params/config.go b/params/config.go index cb12098bc9..5a2e10a943 100644 --- a/params/config.go +++ b/params/config.go @@ -735,13 +735,13 @@ func (c *ChainConfig) CheckConfigForkOrder() error { } { if cur.config != nil { if err := cur.config.validate(); err != nil { - return fmt.Errorf("invalid blob configuration for fork %s: %v", cur.name, err) + return fmt.Errorf("invalid chain configuration in blobSchedule for fork %q: %v", cur.name, err) } } if cur.timestamp != nil { // If the fork is configured, a blob schedule must be defined for it. if cur.config == nil { - return fmt.Errorf("unsupported fork configuration: missing blob configuration entry for %v in schedule", cur.name) + return fmt.Errorf("invalid chain configuration: missing entry for fork %q in blobSchedule", cur.name) } } } From 913fee4be9e7b825bf6c6ff87918dde93a1be7ac Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 13 Feb 2025 21:48:03 +0800 Subject: [PATCH 114/940] core/rawdb: skip setting flushOffset in read-only mode (#31173) This PR addresses a flaw in the freezer table upgrade path. In v1.15.0, freezer table v2 was introduced, including an additional field (`flushOffset`) maintained in the metadata file. To ensure backward compatibility, an upgrade path was implemented for legacy freezer tables by setting `flushOffset` to the size of the index file. However, if the freezer table is opened in read-only mode, this file write operation is rejected, causing Geth to shut down entirely. Given that invalid items in the freezer index file can be detected and truncated, all items in freezer v0 index files are guaranteed to be complete. Therefore, when operating in read-only mode, it is safe to use the freezer data without performing an upgrade. --- core/rawdb/freezer_table.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go index 1ba8cf639f..e553df7029 100644 --- a/core/rawdb/freezer_table.go +++ b/core/rawdb/freezer_table.go @@ -405,6 +405,13 @@ func (t *freezerTable) repairIndex() error { // If legacy metadata is detected, attempt to recover the offset from the // index file to avoid clearing the entire table. if t.metadata.version == freezerTableV1 { + // Skip truncation if the legacy metadata is opened in read-only mode. + // Since all items in the legacy index file were forcibly synchronized, + // data integrity is guaranteed. Therefore, it's safe to leave any extra + // items untruncated in this special scenario. + if t.readonly { + return nil + } t.logger.Info("Recovering freezer flushOffset for legacy table", "offset", size) return t.metadata.setFlushOffset(size, true) } From b027a90ac06d6483a9ac8b5e961b3d6a92d59273 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 13 Feb 2025 16:21:36 +0100 Subject: [PATCH 115/940] version: release go-ethereum v1.15.1 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index f700f9e973..c97634d7a9 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 1 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 1 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From 77762820c9d1ec6cc33ab97ede61861772011756 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 13 Feb 2025 16:26:36 +0100 Subject: [PATCH 116/940] version: begin v1.15.2 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index c97634d7a9..374522e438 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 1 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 2 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From 68de26e34649e50c1f8f8a858a686c38274848b6 Mon Sep 17 00:00:00 2001 From: minh-bq Date: Fri, 14 Feb 2025 00:05:58 +0700 Subject: [PATCH 117/940] core/types: create block's bloom by merging receipts' bloom (#31129) Currently, when calculating block's bloom, we loop through all the receipt logs to calculate the hash value. However, normally, after going through applyTransaction, the receipt's bloom is already calculated based on the receipt log, so the block's bloom can be calculated by just ORing these receipt's blooms. ``` goos: darwin goarch: arm64 pkg: github.com/ethereum/go-ethereum/core/types cpu: Apple M1 Pro BenchmarkCreateBloom BenchmarkCreateBloom/small BenchmarkCreateBloom/small-10 810922 1481 ns/op 104 B/op 5 allocs/op BenchmarkCreateBloom/large BenchmarkCreateBloom/large-10 8173 143764 ns/op 9614 B/op 401 allocs/op BenchmarkCreateBloom/small-mergebloom BenchmarkCreateBloom/small-mergebloom-10 5178918 232.0 ns/op 0 B/op 0 allocs/op BenchmarkCreateBloom/large-mergebloom BenchmarkCreateBloom/large-mergebloom-10 54110 22207 ns/op 0 B/op 0 allocs/op ``` --------- Co-authored-by: Gary Rong Co-authored-by: Zsolt Felfoldi --- cmd/evm/internal/t8ntool/execution.go | 5 ++- core/block_validator.go | 6 ++- core/rawdb/accessors_chain_test.go | 8 ++-- core/state_processor.go | 2 +- core/types/block.go | 8 +++- core/types/bloom9.go | 45 +++++++++++---------- core/types/bloom9_test.go | 56 ++++++++++++++++++++++++--- core/types/receipt.go | 2 +- core/types/receipt_test.go | 12 +++--- eth/filters/filter_test.go | 2 +- 10 files changed, 102 insertions(+), 44 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 16c8808360..7de1eb6949 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -304,7 +304,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, // Set the receipt logs and create the bloom filter. receipt.Logs = statedb.GetLogs(tx.Hash(), vmContext.BlockNumber.Uint64(), blockHash) - receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) + receipt.Bloom = types.CreateBloom(receipt) + // These three are non-consensus fields: //receipt.BlockHash //receipt.BlockNumber @@ -376,7 +377,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, StateRoot: root, TxRoot: types.DeriveSha(includedTxs, trie.NewStackTrie(nil)), ReceiptRoot: types.DeriveSha(receipts, trie.NewStackTrie(nil)), - Bloom: types.CreateBloom(receipts), + Bloom: types.MergeBloom(receipts), LogsHash: rlpHash(statedb.Logs()), Receipts: receipts, Rejected: rejectedTxs, diff --git a/core/block_validator.go b/core/block_validator.go index 5885df9ee2..591e472bc1 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -129,7 +129,11 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD } // Validate the received block's bloom with the one derived from the generated receipts. // For valid blocks this should always validate to true. - rbloom := types.CreateBloom(res.Receipts) + // + // Receipts must go through MakeReceipt to calculate the receipt's bloom + // already. Merge the receipt's bloom together instead of recalculating + // everything. + rbloom := types.MergeBloom(res.Receipts) if rbloom != header.Bloom { return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom) } diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index b9684f8e17..efd16d5fa7 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -338,7 +338,7 @@ func TestBlockReceiptStorage(t *testing.T) { ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), GasUsed: 111111, } - receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1}) + receipt1.Bloom = types.CreateBloom(receipt1) receipt2 := &types.Receipt{ PostState: common.Hash{2}.Bytes(), @@ -351,7 +351,7 @@ func TestBlockReceiptStorage(t *testing.T) { ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), GasUsed: 222222, } - receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2}) + receipt2.Bloom = types.CreateBloom(receipt2) receipts := []*types.Receipt{receipt1, receipt2} // Check that no receipt entries are in a pristine database @@ -679,7 +679,7 @@ func TestReadLogs(t *testing.T) { ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), GasUsed: 111111, } - receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1}) + receipt1.Bloom = types.CreateBloom(receipt1) receipt2 := &types.Receipt{ PostState: common.Hash{2}.Bytes(), @@ -692,7 +692,7 @@ func TestReadLogs(t *testing.T) { ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), GasUsed: 222222, } - receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2}) + receipt2.Bloom = types.CreateBloom(receipt2) receipts := []*types.Receipt{receipt1, receipt2} hash := common.BytesToHash([]byte{0x03, 0x14}) diff --git a/core/state_processor.go b/core/state_processor.go index 902ff582e8..2c74f6f407 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -189,7 +189,7 @@ func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, b // Set the receipt logs and create the bloom filter. receipt.Logs = statedb.GetLogs(tx.Hash(), blockNumber.Uint64(), blockHash) - receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) + receipt.Bloom = types.CreateBloom(receipt) receipt.BlockHash = blockHash receipt.BlockNumber = blockNumber receipt.TransactionIndex = uint(statedb.TxIndex()) diff --git a/core/types/block.go b/core/types/block.go index c3db4d89e8..b284fb3b16 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -237,6 +237,9 @@ type extblock struct { // // The body elements and the receipts are used to recompute and overwrite the // relevant portions of the header. +// +// The receipt's bloom must already calculated for the block's bloom to be +// correctly calculated. func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher) *Block { if body == nil { body = &Body{} @@ -260,7 +263,10 @@ func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher b.header.ReceiptHash = EmptyReceiptsHash } else { b.header.ReceiptHash = DeriveSha(Receipts(receipts), hasher) - b.header.Bloom = CreateBloom(receipts) + // Receipts must go through MakeReceipt to calculate the receipt's bloom + // already. Merge the receipt's bloom together instead of recalculating + // everything. + b.header.Bloom = MergeBloom(receipts) } if len(uncles) == 0 { diff --git a/core/types/bloom9.go b/core/types/bloom9.go index a560a20724..962ba46d47 100644 --- a/core/types/bloom9.go +++ b/core/types/bloom9.go @@ -100,32 +100,35 @@ func (b *Bloom) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("Bloom", input, b[:]) } -// CreateBloom creates a bloom filter out of the give Receipts (+Logs) -func CreateBloom(receipts Receipts) Bloom { - buf := make([]byte, 6) - var bin Bloom - for _, receipt := range receipts { - for _, log := range receipt.Logs { - bin.add(log.Address.Bytes(), buf) - for _, b := range log.Topics { - bin.add(b[:], buf) - } - } - } - return bin -} - -// LogsBloom returns the bloom bytes for the given logs -func LogsBloom(logs []*Log) []byte { - buf := make([]byte, 6) - var bin Bloom - for _, log := range logs { +// CreateBloom creates a bloom filter out of the give Receipt (+Logs) +func CreateBloom(receipt *Receipt) Bloom { + var ( + bin Bloom + buf = make([]byte, 6) + ) + for _, log := range receipt.Logs { bin.add(log.Address.Bytes(), buf) for _, b := range log.Topics { bin.add(b[:], buf) } } - return bin[:] + return bin +} + +// MergeBloom merges the precomputed bloom filters in the Receipts without +// recalculating them. It assumes that each receipt’s Bloom field is already +// correctly populated. +func MergeBloom(receipts Receipts) Bloom { + var bin Bloom + for _, receipt := range receipts { + if len(receipt.Logs) != 0 { + bl := receipt.Bloom.Bytes() + for i := range bin { + bin[i] |= bl[i] + } + } + } + return bin } // Bloom9 returns the bloom filter for the given data diff --git a/core/types/bloom9_test.go b/core/types/bloom9_test.go index d3178d112e..07f6446a97 100644 --- a/core/types/bloom9_test.go +++ b/core/types/bloom9_test.go @@ -126,26 +126,70 @@ func BenchmarkCreateBloom(b *testing.B) { for i := 0; i < 200; i += 2 { copy(rLarge[i:], rSmall) } - b.Run("small", func(b *testing.B) { + b.Run("small-createbloom", func(b *testing.B) { b.ReportAllocs() - var bl Bloom for i := 0; i < b.N; i++ { - bl = CreateBloom(rSmall) + for _, receipt := range rSmall { + receipt.Bloom = CreateBloom(receipt) + } } b.StopTimer() + + bl := MergeBloom(rSmall) var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") got := crypto.Keccak256Hash(bl.Bytes()) if got != exp { b.Errorf("Got %x, exp %x", got, exp) } }) - b.Run("large", func(b *testing.B) { + b.Run("large-createbloom", func(b *testing.B) { b.ReportAllocs() - var bl Bloom for i := 0; i < b.N; i++ { - bl = CreateBloom(rLarge) + for _, receipt := range rLarge { + receipt.Bloom = CreateBloom(receipt) + } } b.StopTimer() + + bl := MergeBloom(rLarge) + var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") + got := crypto.Keccak256Hash(bl.Bytes()) + if got != exp { + b.Errorf("Got %x, exp %x", got, exp) + } + }) + b.Run("small-mergebloom", func(b *testing.B) { + for _, receipt := range rSmall { + receipt.Bloom = CreateBloom(receipt) + } + b.ReportAllocs() + b.ResetTimer() + + var bl Bloom + for i := 0; i < b.N; i++ { + bl = MergeBloom(rSmall) + } + b.StopTimer() + + var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") + got := crypto.Keccak256Hash(bl.Bytes()) + if got != exp { + b.Errorf("Got %x, exp %x", got, exp) + } + }) + b.Run("large-mergebloom", func(b *testing.B) { + for _, receipt := range rLarge { + receipt.Bloom = CreateBloom(receipt) + } + b.ReportAllocs() + b.ResetTimer() + + var bl Bloom + for i := 0; i < b.N; i++ { + bl = MergeBloom(rLarge) + } + b.StopTimer() + var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") got := crypto.Keccak256Hash(bl.Bytes()) if got != exp { diff --git a/core/types/receipt.go b/core/types/receipt.go index 47f16d950a..e52a0c6477 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -291,7 +291,7 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { } r.CumulativeGasUsed = stored.CumulativeGasUsed r.Logs = stored.Logs - r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) + r.Bloom = CreateBloom((*Receipt)(r)) return nil } diff --git a/core/types/receipt_test.go b/core/types/receipt_test.go index fc51eb11a5..78b43c7e49 100644 --- a/core/types/receipt_test.go +++ b/core/types/receipt_test.go @@ -394,7 +394,7 @@ func TestTypedReceiptEncodingDecoding(t *testing.T) { func TestReceiptMarshalBinary(t *testing.T) { // Legacy Receipt - legacyReceipt.Bloom = CreateBloom(Receipts{legacyReceipt}) + legacyReceipt.Bloom = CreateBloom(legacyReceipt) have, err := legacyReceipt.MarshalBinary() if err != nil { t.Fatalf("marshal binary error: %v", err) @@ -421,7 +421,7 @@ func TestReceiptMarshalBinary(t *testing.T) { // 2930 Receipt buf.Reset() - accessListReceipt.Bloom = CreateBloom(Receipts{accessListReceipt}) + accessListReceipt.Bloom = CreateBloom(accessListReceipt) have, err = accessListReceipt.MarshalBinary() if err != nil { t.Fatalf("marshal binary error: %v", err) @@ -439,7 +439,7 @@ func TestReceiptMarshalBinary(t *testing.T) { // 1559 Receipt buf.Reset() - eip1559Receipt.Bloom = CreateBloom(Receipts{eip1559Receipt}) + eip1559Receipt.Bloom = CreateBloom(eip1559Receipt) have, err = eip1559Receipt.MarshalBinary() if err != nil { t.Fatalf("marshal binary error: %v", err) @@ -463,7 +463,7 @@ func TestReceiptUnmarshalBinary(t *testing.T) { if err := gotLegacyReceipt.UnmarshalBinary(legacyBinary); err != nil { t.Fatalf("unmarshal binary error: %v", err) } - legacyReceipt.Bloom = CreateBloom(Receipts{legacyReceipt}) + legacyReceipt.Bloom = CreateBloom(legacyReceipt) if !reflect.DeepEqual(gotLegacyReceipt, legacyReceipt) { t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotLegacyReceipt, legacyReceipt) } @@ -474,7 +474,7 @@ func TestReceiptUnmarshalBinary(t *testing.T) { if err := gotAccessListReceipt.UnmarshalBinary(accessListBinary); err != nil { t.Fatalf("unmarshal binary error: %v", err) } - accessListReceipt.Bloom = CreateBloom(Receipts{accessListReceipt}) + accessListReceipt.Bloom = CreateBloom(accessListReceipt) if !reflect.DeepEqual(gotAccessListReceipt, accessListReceipt) { t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotAccessListReceipt, accessListReceipt) } @@ -485,7 +485,7 @@ func TestReceiptUnmarshalBinary(t *testing.T) { if err := got1559Receipt.UnmarshalBinary(eip1559RctBinary); err != nil { t.Fatalf("unmarshal binary error: %v", err) } - eip1559Receipt.Bloom = CreateBloom(Receipts{eip1559Receipt}) + eip1559Receipt.Bloom = CreateBloom(eip1559Receipt) if !reflect.DeepEqual(got1559Receipt, eip1559Receipt) { t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", got1559Receipt, eip1559Receipt) } diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 6a3057326d..e2790d91eb 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -42,7 +42,7 @@ func makeReceipt(addr common.Address) *types.Receipt { receipt.Logs = []*types.Log{ {Address: addr}, } - receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) + receipt.Bloom = types.CreateBloom(receipt) return receipt } From e5bc789185e74a776d122b95e490639068a6a612 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 17 Feb 2025 07:30:06 +0100 Subject: [PATCH 118/940] consensus/beacon: fix isPostMerge for mainnet (#31191) This fixes a regression introduced in #31153 where we didn't consider mainnet to be in PoS, causing #31190. The problem is, `params.MainnetChainConfig` does not have a defined `MergeNetsplitBlock`, so it isn't considered to be in PoS in `CalcDifficulty`. --- consensus/beacon/consensus.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index d80d24e272..cc9f44e460 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -75,9 +75,11 @@ func New(ethone consensus.Engine) *Beacon { // isPostMerge reports whether the given block number is assumed to be post-merge. // Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or // PoA chain for unit testing purposes. -func isPostMerge(config *params.ChainConfig, block uint64) bool { +func isPostMerge(config *params.ChainConfig, blockNum uint64, timestamp uint64) bool { mergedAtGenesis := config.TerminalTotalDifficulty != nil && config.TerminalTotalDifficulty.Sign() == 0 - return mergedAtGenesis || config.MergeNetsplitBlock != nil && block >= config.MergeNetsplitBlock.Uint64() + return mergedAtGenesis || + config.MergeNetsplitBlock != nil && blockNum >= config.MergeNetsplitBlock.Uint64() || + config.ShanghaiTime != nil && timestamp >= *config.ShanghaiTime } // Author implements consensus.Engine, returning the verified author of the block. @@ -327,7 +329,7 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [ // Prepare implements consensus.Engine, initializing the difficulty field of a // header to conform to the beacon protocol. The changes are done inline. func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { - if !isPostMerge(chain.Config(), header.Number.Uint64()) { + if !isPostMerge(chain.Config(), header.Number.Uint64(), header.Time) { return beacon.ethone.Prepare(chain, header) } header.Difficulty = beaconDifficulty @@ -437,7 +439,7 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash { // the difficulty that a new block should have when created at time // given the parent block's time and difficulty. func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { - if !isPostMerge(chain.Config(), parent.Number.Uint64()+1) { + if !isPostMerge(chain.Config(), parent.Number.Uint64()+1, time) { return beacon.ethone.CalcDifficulty(chain, time, parent) } return beaconDifficulty From c113e3b5b12619c80b962a3b6e895a14a13eaa75 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 17 Feb 2025 09:47:12 +0100 Subject: [PATCH 119/940] p2p: fix marshaling of NAT in TOML (#31192) This fixes an issue where a nat.Interface unmarshaled from the TOML config file could not be re-marshaled to TOML correctly. Fixes #31183 --- p2p/config.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/p2p/config.go b/p2p/config.go index 5ea62e12f5..68a9c0bb5f 100644 --- a/p2p/config.go +++ b/p2p/config.go @@ -18,6 +18,7 @@ package p2p import ( "crypto/ecdsa" + "encoding" "fmt" "github.com/ethereum/go-ethereum/common/mclock" @@ -135,6 +136,13 @@ type configNAT struct { nat.Interface } +func (w *configNAT) MarshalText() ([]byte, error) { + if tm, ok := w.Interface.(encoding.TextMarshaler); ok { + return tm.MarshalText() + } + return nil, fmt.Errorf("NAT specification %#v cannot be marshaled", w.Interface) +} + func (w *configNAT) UnmarshalText(input []byte) error { n, err := nat.Parse(string(input)) if err != nil { From d37a0b8cd0ad799dd696c25249987d89394a1409 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 17 Feb 2025 10:12:03 +0100 Subject: [PATCH 120/940] eth/protocols/eth: add discovery iterator to protocol (#31185) We somehow forgot to add this in #30302, so discv5 and DNS have actually been disabled since then. Fixes #31168 --- eth/protocols/eth/handler.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index d6cd83373b..a0848137fa 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -89,7 +89,7 @@ type TxPool interface { } // MakeProtocols constructs the P2P protocol definitions for `eth`. -func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2p.Protocol { +func MakeProtocols(backend Backend, network uint64, disc enode.Iterator) []p2p.Protocol { protocols := make([]p2p.Protocol, 0, len(ProtocolVersions)) for _, version := range ProtocolVersions { protocols = append(protocols, p2p.Protocol{ @@ -110,7 +110,8 @@ 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: disc, + Attributes: []enr.Entry{currentENREntry(backend.Chain())}, }) } return protocols From c8c62dafc78b0edadfa9406503cef2d957299f8b Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 17 Feb 2025 11:59:48 +0100 Subject: [PATCH 121/940] version: release go-ethereum v1.15.2 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 374522e438..9854aa1119 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 2 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 2 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From aec1964410648e1eda9e70685f27e846f2328c0f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 17 Feb 2025 12:01:20 +0100 Subject: [PATCH 122/940] version: begin v1.15.3 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 9854aa1119..f0fb3195b3 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 2 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 3 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From 3adfa1fbeb8b8711ca67221fff63d4d670fdf95b Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 18 Feb 2025 03:48:42 +0100 Subject: [PATCH 123/940] trie: do not expect ordering in stacktrie during fuzzing (#31170) This PR removes the assumption of the stacktrie and trie to have the same ordering. This was hit by the fuzzers on oss-fuzz --------- Co-authored-by: Gary Rong --- trie/stacktrie_fuzzer_test.go | 25 ++++++++++------------ trie/trie_test.go | 39 ++++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/trie/stacktrie_fuzzer_test.go b/trie/stacktrie_fuzzer_test.go index df487d16bf..7ff6ef0235 100644 --- a/trie/stacktrie_fuzzer_test.go +++ b/trie/stacktrie_fuzzer_test.go @@ -37,16 +37,13 @@ func FuzzStackTrie(f *testing.F) { } 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: crypto.NewKeccakState()} - dbA = newTestDatabase(rawdb.NewDatabase(spongeA), rawdb.HashScheme) - trieA = NewEmpty(dbA) - spongeB = &spongeDb{sponge: crypto.NewKeccakState()} - dbB = newTestDatabase(rawdb.NewDatabase(spongeB), rawdb.HashScheme) - trieB = NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(spongeB, common.Hash{}, path, hash, blob, dbB.Scheme()) + input = bytes.NewReader(data) + dbA = newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) + trieA = NewEmpty(dbA) + memDB = rawdb.NewMemoryDatabase() + trieB = NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { + rawdb.WriteTrieNode(memDB, common.Hash{}, path, hash, blob, rawdb.HashScheme) }) vals []*kv maxElements = 10000 @@ -55,13 +52,17 @@ func fuzz(data []byte, debugging bool) { ) // Fill the trie with elements for i := 0; input.Len() > 0 && i < maxElements; i++ { + // Build the key k := make([]byte, 32) input.Read(k) + + // Build the val var a uint16 binary.Read(input, binary.LittleEndian, &a) a = 1 + a%100 v := make([]byte, a) input.Read(v) + if input.Len() == 0 { // If it was exhausted while reading, the value may be all zeroes, // thus 'deletion' which is not supported on stacktrie @@ -73,6 +74,7 @@ func fuzz(data []byte, debugging bool) { } keys[string(k)] = struct{}{} vals = append(vals, &kv{k: k, v: v}) + trieA.MustUpdate(k, v) } if len(vals) == 0 { @@ -99,11 +101,6 @@ func fuzz(data []byte, debugging bool) { if rootA != rootB { panic(fmt.Sprintf("roots differ: (trie) %x != %x (stacktrie)", rootA, rootB)) } - sumA := spongeA.sponge.Sum(nil) - sumB := spongeB.sponge.Sum(nil) - if !bytes.Equal(sumA, sumB) { - panic(fmt.Sprintf("sequence differ: (trie) %x != %x (stacktrie)", sumA, sumB)) - } // Ensure all the nodes are persisted correctly var ( diff --git a/trie/trie_test.go b/trie/trie_test.go index 423ed30fe8..77234d9d9b 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -779,6 +779,7 @@ func TestCommitAfterHash(t *testing.T) { func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) { // Make the random benchmark deterministic random := rand.New(rand.NewSource(0)) + // Create a realistic account trie to hash addresses = make([][20]byte, size) for i := 0; i < len(addresses); i++ { @@ -795,13 +796,18 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) { ) // The big.Rand function is not deterministic with regards to 64 vs 32 bit systems, // and will consume different amount of data from the rand source. - //balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil)) + // balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil)) // Therefore, we instead just read via byte buffer numBytes := random.Uint32() % 33 // [0, 32] bytes balanceBytes := make([]byte, numBytes) random.Read(balanceBytes) balance := new(uint256.Int).SetBytes(balanceBytes) - data, _ := rlp.EncodeToBytes(&types.StateAccount{Nonce: nonce, Balance: balance, Root: root, CodeHash: code}) + data, _ := rlp.EncodeToBytes(&types.StateAccount{ + Nonce: nonce, + Balance: balance, + Root: root, + CodeHash: code, + }) accounts[i] = data } return addresses, accounts @@ -856,6 +862,7 @@ func (s *spongeDb) Flush() { s.sponge.Write([]byte(key)) s.sponge.Write([]byte(s.values[key])) } + fmt.Println(len(s.keys)) } // spongeBatch is a dummy batch which immediately writes to the underlying spongedb @@ -873,10 +880,12 @@ func (b *spongeBatch) Write() error { return nil } func (b *spongeBatch) Reset() {} func (b *spongeBatch) Replay(w ethdb.KeyValueWriter) error { return nil } -// TestCommitSequence tests that the trie.Commit operation writes the elements of the trie -// in the expected order. -// The test data was based on the 'master' code, and is basically random. It can be used -// to check whether changes to the trie modifies the write order or data in any way. +// TestCommitSequence tests that the trie.Commit operation writes the elements +// of the trie in the expected order. +// +// The test data was based on the 'master' code, and is basically random. +// It can be used to check whether changes to the trie modifies the write order +// or data in any way. func TestCommitSequence(t *testing.T) { for i, tc := range []struct { count int @@ -887,19 +896,23 @@ func TestCommitSequence(t *testing.T) { {2000, common.FromHex("4574cd8e6b17f3fe8ad89140d1d0bf4f1bd7a87a8ac3fb623b33550544c77635")}, } { addresses, accounts := makeAccounts(tc.count) + // This spongeDb is used to check the sequence of disk-db-writes s := &spongeDb{sponge: crypto.NewKeccakState()} db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) - trie := NewEmpty(db) + // Fill the trie with elements + trie := NewEmpty(db) for i := 0; i < tc.count; i++ { trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) } // Flush trie -> database root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) + // Flush memdb -> disk (sponge) db.Commit(root) + if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) { t.Errorf("test %d, disk write sequence wrong:\ngot %x exp %x\n", i, got, exp) } @@ -917,12 +930,13 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { {200, common.FromHex("dde92ca9812e068e6982d04b40846dc65a61a9fd4996fc0f55f2fde172a8e13c")}, {2000, common.FromHex("ab553a7f9aff82e3929c382908e30ef7dd17a332933e92ba3fe873fc661ef382")}, } { - prng := rand.New(rand.NewSource(int64(i))) // This spongeDb is used to check the sequence of disk-db-writes + prng := rand.New(rand.NewSource(int64(i))) s := &spongeDb{sponge: crypto.NewKeccakState()} db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) - trie := NewEmpty(db) + // Fill the trie with elements + trie := NewEmpty(db) for i := 0; i < tc.count; i++ { key := make([]byte, 32) var val []byte @@ -939,6 +953,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { // Flush trie -> database root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) + // Flush memdb -> disk (sponge) db.Commit(root) if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) { @@ -974,19 +989,22 @@ func TestCommitSequenceStackTrie(t *testing.T) { // For the stack trie, we need to do inserts in proper order key := make([]byte, 32) binary.BigEndian.PutUint64(key, uint64(i)) - var val []byte + // 50% short elements, 50% large elements + var val []byte if prng.Intn(2) == 0 { val = make([]byte, 1+prng.Intn(32)) } else { val = make([]byte, 1+prng.Intn(1024)) } prng.Read(val) + trie.Update(key, val) stTrie.Update(key, val) } // Flush trie -> database root, nodes := trie.Commit(false) + // Flush memdb -> disk (sponge) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) db.Commit(root) @@ -1045,6 +1063,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) { // Flush trie -> database root, nodes := trie.Commit(false) + // Flush memdb -> disk (sponge) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) db.Commit(root) From 68d477670c562747ba670523b14379506eecb112 Mon Sep 17 00:00:00 2001 From: piersy Date: Tue, 18 Feb 2025 05:50:19 +0000 Subject: [PATCH 124/940] utils: clarify description for history.state flag (#31164) --- cmd/utils/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f079df83b9..243b5d22f0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -262,7 +262,7 @@ var ( } StateHistoryFlag = &cli.Uint64Flag{ Name: "history.state", - Usage: "Number of recent blocks to retain state history for (default = 90,000 blocks, 0 = entire chain)", + Usage: "Number of recent blocks to retain state history for, only relevant in state.scheme=path (default = 90,000 blocks, 0 = entire chain)", Value: ethconfig.Defaults.StateHistory, Category: flags.StateCategory, } From 7332a1bc0ae14d25333d697a6a7a97b159928efb Mon Sep 17 00:00:00 2001 From: EdisonSR <61781882@qq.com> Date: Tue, 18 Feb 2025 18:15:36 +0800 Subject: [PATCH 125/940] ethclient: add comment describing block number tags (#30984) Adds a comment on how to use rpc.*BlockNumber and the explanation of the block number tags --------- Co-authored-by: Gary Rong --- ethclient/ethclient.go | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index f10626c01f..c761d4f8d3 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -85,11 +85,23 @@ func (ec *Client) BlockByHash(ctx context.Context, hash common.Hash) (*types.Blo return ec.getBlock(ctx, "eth_getBlockByHash", hash, true) } -// BlockByNumber returns a block from the current canonical chain. If number is nil, the -// latest known block is returned. +// BlockByNumber returns a block from the current canonical chain. +// If `number` is nil, the latest known block is returned. // -// Note that loading full blocks requires two requests. Use HeaderByNumber -// if you don't need all transactions or uncle headers. +// Use `HeaderByNumber` if you don't need full transaction data or uncle headers. +// +// Supported special block number tags: +// - `earliest` : The genesis (earliest) block +// - `latest` : The most recently included block +// - `safe` : The latest safe head block +// - `finalized` : The latest finalized block +// - `pending` : The pending block +// +// Example usage: +// +// ```go +// BlockByNumber(context.Background(), big.NewInt(int64(rpc.LatestBlockNumber))) +// ``` func (ec *Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { return ec.getBlock(ctx, "eth_getBlockByNumber", toBlockNumArg(number), true) } @@ -210,8 +222,21 @@ func (ec *Client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.He return head, err } -// HeaderByNumber returns a block header from the current canonical chain. If number is -// nil, the latest known header is returned. +// HeaderByNumber returns a block header from the current canonical chain. +// If `number` is nil, the latest known block header is returned. +// +// Supported special block number tags: +// - `earliest` : The genesis (earliest) block +// - `latest` : The most recently included block +// - `safe` : The latest safe head block +// - `finalized` : The latest finalized block +// - `pending` : The pending block +// +// Example usage: +// +// ```go +// HeaderByNumber(context.Background(), big.NewInt(int64(rpc.LatestBlockNumber))) +// ``` func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { var head *types.Header err := ec.c.CallContext(ctx, &head, "eth_getBlockByNumber", toBlockNumArg(number), false) From 32c6aa8a1a2595cbb89b05f93440d230841f8431 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 18 Feb 2025 21:53:33 +0800 Subject: [PATCH 126/940] core/vm: clean up EVM environmental structure (#31061) This PR does a few things including: - Remove `ContractRef` interface - Remove `vm.AccountRef` which implements `ContractRef` interface - Maintain the `jumpDests` struct in EVM for sharing between call frames - Simplify the delegateCall context initialization --- core/state_processor.go | 6 +- core/state_transition.go | 5 +- core/vm/contract.go | 86 +++++--------------- core/vm/eips.go | 8 +- core/vm/evm.go | 130 ++++++++++++++---------------- core/vm/gas_table_test.go | 4 +- core/vm/instructions.go | 12 +-- core/vm/instructions_test.go | 11 +-- core/vm/interface.go | 15 ---- core/vm/interpreter_test.go | 2 +- core/vm/runtime/runtime.go | 13 ++- eth/tracers/js/tracer_test.go | 19 +---- eth/tracers/logger/logger_test.go | 18 +---- tests/state_test.go | 5 +- 14 files changed, 109 insertions(+), 225 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index 2c74f6f407..4e365c6550 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -229,7 +229,7 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, evm *vm.EVM) { } evm.SetTxContext(NewEVMTxContext(msg)) evm.StateDB.AddAddressToAccessList(params.BeaconRootsAddress) - _, _, _ = evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) + _, _, _ = evm.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560) evm.StateDB.Finalise(true) } @@ -253,7 +253,7 @@ func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) { } evm.SetTxContext(NewEVMTxContext(msg)) evm.StateDB.AddAddressToAccessList(params.HistoryStorageAddress) - _, _, err := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) + _, _, err := evm.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560) if err != nil { panic(err) } @@ -292,7 +292,7 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte } evm.SetTxContext(NewEVMTxContext(msg)) evm.StateDB.AddAddressToAccessList(addr) - ret, _, _ := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) + ret, _, _ := evm.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560) evm.StateDB.Finalise(true) if len(ret) == 0 { return // skip empty output diff --git a/core/state_transition.go b/core/state_transition.go index e7edd76ced..0f9ee9eea5 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -423,7 +423,6 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { var ( msg = st.msg - sender = vm.AccountRef(msg.From) rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil, st.evm.Context.Time) contractCreation = msg.To == nil floorDataGas uint64 @@ -484,7 +483,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { vmerr error // vm errors do not effect consensus and are therefore not assigned to err ) if contractCreation { - ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, value) + ret, _, st.gasRemaining, vmerr = st.evm.Create(msg.From, msg.Data, st.gasRemaining, value) } else { // Increment the nonce for the next transaction. st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1, tracing.NonceChangeEoACall) @@ -507,7 +506,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { } // Execute the transaction's call. - ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value) + ret, st.gasRemaining, vmerr = st.evm.Call(msg.From, st.to(), msg.Data, st.gasRemaining, value) } // Compute refund counter, capped to a refund quotient. diff --git a/core/vm/contract.go b/core/vm/contract.go index 5670244e17..0eaa91d959 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -22,39 +22,20 @@ import ( "github.com/holiman/uint256" ) -// ContractRef is a reference to the contract's backing object -type ContractRef interface { - Address() common.Address -} - -// AccountRef implements ContractRef. -// -// Account references are used during EVM initialisation and -// its primary use is to fetch addresses. Removing this object -// proves difficult because of the cached jump destinations which -// are fetched from the parent contract (i.e. the caller), which -// is a ContractRef. -type AccountRef common.Address - -// Address casts AccountRef to an Address -func (ar AccountRef) Address() common.Address { return (common.Address)(ar) } - // Contract represents an ethereum contract in the state database. It contains // the contract code, calling arguments. Contract implements ContractRef type Contract struct { - // CallerAddress is the result of the caller which initialised this - // contract. However when the "call method" is delegated this value - // needs to be initialised to that of the caller's caller. - CallerAddress common.Address - caller ContractRef - self ContractRef + // caller is the result of the caller which initialised this + // contract. However, when the "call method" is delegated this + // value needs to be initialised to that of the caller's caller. + caller common.Address + address common.Address jumpdests map[common.Hash]bitvec // Aggregated result of JUMPDEST analysis. analysis bitvec // Locally cached result of JUMPDEST analysis Code []byte CodeHash common.Hash - CodeAddr *common.Address Input []byte // is the execution frame represented by this object a contract deployment @@ -66,23 +47,18 @@ type Contract struct { } // NewContract returns a new contract environment for the execution of EVM. -func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas uint64) *Contract { - c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object} - - if parent, ok := caller.(*Contract); ok { - // Reuse JUMPDEST analysis from parent context if available. - c.jumpdests = parent.jumpdests - } else { - c.jumpdests = make(map[common.Hash]bitvec) +func NewContract(caller common.Address, address common.Address, value *uint256.Int, gas uint64, jumpDests map[common.Hash]bitvec) *Contract { + // Initialize the jump analysis map if it's nil, mostly for tests + if jumpDests == nil { + jumpDests = make(map[common.Hash]bitvec) + } + return &Contract{ + caller: caller, + address: address, + jumpdests: jumpDests, + Gas: gas, + value: value, } - - // Gas should be a pointer so it can safely be reduced through the run - // This pointer will be off the state transition - c.Gas = gas - // ensures a value is set - c.value = value - - return c } func (c *Contract) validJumpdest(dest *uint256.Int) bool { @@ -132,18 +108,6 @@ func (c *Contract) isCode(udest uint64) bool { return c.analysis.codeSegment(udest) } -// AsDelegate sets the contract to be a delegate call and returns the current -// contract (for chaining calls) -func (c *Contract) AsDelegate() *Contract { - // NOTE: caller must, at all times be a contract. It should never happen - // that caller is something other than a Contract. - parent := c.caller.(*Contract) - c.CallerAddress = parent.CallerAddress - c.value = parent.value - - return c -} - // GetOp returns the n'th element in the contract's byte array func (c *Contract) GetOp(n uint64) OpCode { if n < uint64(len(c.Code)) { @@ -158,7 +122,7 @@ func (c *Contract) GetOp(n uint64) OpCode { // Caller will recursively call caller when the contract is a delegate // call, including that of caller's caller. func (c *Contract) Caller() common.Address { - return c.CallerAddress + return c.caller } // UseGas attempts the use gas and subtracts it and returns true on success @@ -186,7 +150,7 @@ func (c *Contract) RefundGas(gas uint64, logger *tracing.Hooks, reason tracing.G // Address returns the contracts address func (c *Contract) Address() common.Address { - return c.self.Address() + return c.address } // Value returns the contract's value (sent to it from it's caller) @@ -194,18 +158,8 @@ func (c *Contract) Value() *uint256.Int { return c.value } -// SetCallCode sets the code of the contract and address of the backing data -// object -func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) { +// SetCallCode sets the code of the contract, +func (c *Contract) SetCallCode(hash common.Hash, code []byte) { c.Code = code c.CodeHash = hash - c.CodeAddr = addr -} - -// SetCodeOptionalHash can be used to provide code, but it's optional to provide hash. -// In case hash is not provided, the jumpdest analysis will not be saved to the parent context -func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash *codeAndHash) { - c.Code = codeAndHash.code - c.CodeHash = codeAndHash.hash - c.CodeAddr = addr } diff --git a/core/vm/eips.go b/core/vm/eips.go index 515999bd19..6159eade7e 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -338,13 +338,9 @@ func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC } 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()) - if !contract.IsSystemCall { - statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) + if !scope.Contract.IsSystemCall { + statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(code)), false) if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { scope.Contract.Gas = 0 return nil, ErrOutOfGas diff --git a/core/vm/evm.go b/core/vm/evm.go index 442441e9ae..c28dcb2554 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -91,29 +91,40 @@ type EVM struct { // Context provides auxiliary blockchain related information Context BlockContext TxContext + // StateDB gives access to the underlying state StateDB StateDB - // Depth is the current call stack + + // depth is the current call stack depth int // chainConfig contains information about the current chain chainConfig *params.ChainConfig + // chain rules contains the chain rules for the current epoch chainRules params.Rules - // virtual machine configuration options used to initialise the - // evm. + + // virtual machine configuration options used to initialise the evm Config Config - // global (to this context) ethereum virtual machine - // used throughout the execution of the tx. + + // global (to this context) ethereum virtual machine used throughout + // the execution of the tx interpreter *EVMInterpreter + // abort is used to abort the EVM calling operations abort atomic.Bool + // callGasTemp holds the gas available for the current call. This is needed because the // 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 + + // jumpDests is the aggregated result of JUMPDEST analysis made through + // the life cycle of EVM. + jumpDests map[common.Hash]bitvec } // NewEVM constructs an EVM instance with the supplied block context, state @@ -127,6 +138,7 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon Config: config, chainConfig: chainConfig, chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time), + jumpDests: make(map[common.Hash]bitvec), } evm.precompiles = activePrecompiledContracts(evm.chainRules) evm.interpreter = NewEVMInterpreter(evm) @@ -165,18 +177,18 @@ func (evm *EVM) Interpreter() *EVMInterpreter { return evm.interpreter } -func isSystemCall(caller ContractRef) bool { - return caller.Address() == params.SystemAddress +func isSystemCall(caller common.Address) bool { + return caller == params.SystemAddress } // Call executes the contract associated with the addr with the given input as // parameters. It also handles any necessary value transfer required and takse // 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) { +func (evm *EVM) Call(caller common.Address, 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()) + evm.captureBegin(evm.depth, CALL, caller, addr, input, gas, value.ToBig()) defer func(startGas uint64) { evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) }(gas) @@ -186,7 +198,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas return nil, gas, ErrDepth } // Fail if we're trying to transfer more than the available balance - if !value.IsZero() && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { + if !value.IsZero() && !evm.Context.CanTransfer(evm.StateDB, caller, value) { return nil, gas, ErrInsufficientBalance } snapshot := evm.StateDB.Snapshot() @@ -209,23 +221,20 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas } evm.StateDB.CreateAccount(addr) } - evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value) + evm.Context.Transfer(evm.StateDB, caller, addr, value) if isPrecompile { 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.resolveCode(addr) if len(code) == 0 { ret, err = nil, nil // gas is unchanged } else { - addrCopy := addr - // If the account has no code, we can abort here - // The depth-check is already done, and precompiles handled above - contract := NewContract(caller, AccountRef(addrCopy), value, gas) + // The contract is a scoped environment for this execution context only. + contract := NewContract(caller, addr, value, gas, evm.jumpDests) contract.IsSystemCall = isSystemCall(caller) - contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), code) + contract.SetCallCode(evm.resolveCodeHash(addr), code) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } @@ -256,10 +265,10 @@ 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) { +func (evm *EVM) CallCode(caller common.Address, 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()) + evm.captureBegin(evm.depth, CALLCODE, caller, addr, input, gas, value.ToBig()) defer func(startGas uint64) { evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) }(gas) @@ -272,7 +281,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, // Note although it's noop to transfer X ether to caller itself. But // if caller doesn't have enough balance, it would be an error to allow // over-charging itself. So the check here is necessary. - if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { + if !evm.Context.CanTransfer(evm.StateDB, caller, value) { return nil, gas, ErrInsufficientBalance } var snapshot = evm.StateDB.Snapshot() @@ -281,11 +290,10 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, if p, isPrecompile := evm.precompile(addr); isPrecompile { 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) - contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy)) + contract := NewContract(caller, caller, value, gas, evm.jumpDests) + contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr)) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } @@ -295,7 +303,6 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution) } - gas = 0 } } @@ -307,14 +314,11 @@ 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) { +func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address, 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 { - // 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.captureBegin(evm.depth, DELEGATECALL, caller.Address(), addr, input, gas, parent.value.ToBig()) + evm.captureBegin(evm.depth, DELEGATECALL, caller, addr, input, gas, value.ToBig()) defer func(startGas uint64) { evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) }(gas) @@ -329,10 +333,11 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by if p, isPrecompile := evm.precompile(addr); isPrecompile { 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() - contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy)) + // + // Note: The value refers to the original value from the parent call. + contract := NewContract(originCaller, caller, value, gas, evm.jumpDests) + contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr)) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } @@ -352,10 +357,10 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by // as parameters while disallowing any modifications to the state during the call. // 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) { +func (evm *EVM) StaticCall(caller common.Address, 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) + evm.captureBegin(evm.depth, STATICCALL, caller, addr, input, gas, nil) defer func(startGas uint64) { evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) }(gas) @@ -380,14 +385,11 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte if p, isPrecompile := evm.precompile(addr); isPrecompile { 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' - // even if the actual execution ends on RunPrecompiled above. - 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(addrCopy), new(uint256.Int), gas) - contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy)) + contract := NewContract(caller, addr, new(uint256.Int), gas, evm.jumpDests) + contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr)) + // 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. @@ -407,22 +409,10 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte return ret, gas, err } -type codeAndHash struct { - code []byte - hash common.Hash -} - -func (c *codeAndHash) Hash() common.Hash { - if c.hash == (common.Hash{}) { - c.hash = crypto.Keccak256Hash(c.code) - } - return c.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) (ret []byte, createAddress common.Address, leftOverGas uint64, err error) { +func (evm *EVM) create(caller common.Address, code []byte, 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()) + evm.captureBegin(evm.depth, typ, caller, address, code, gas, value.ToBig()) defer func(startGas uint64) { evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) }(gas) @@ -432,14 +422,14 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if evm.depth > int(params.CallCreateDepth) { return nil, common.Address{}, gas, ErrDepth } - if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { + if !evm.Context.CanTransfer(evm.StateDB, caller, value) { return nil, common.Address{}, gas, ErrInsufficientBalance } - nonce := evm.StateDB.GetNonce(caller.Address()) + nonce := evm.StateDB.GetNonce(caller) if nonce+1 < nonce { return nil, common.Address{}, gas, ErrNonceUintOverflow } - evm.StateDB.SetNonce(caller.Address(), nonce+1, tracing.NonceChangeContractCreator) + evm.StateDB.SetNonce(caller, nonce+1, tracing.NonceChangeContractCreator) // Charge the contract creation init gas in verkle mode if evm.chainRules.IsEIP4762 { @@ -500,15 +490,18 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, } gas = gas - statelessGas } - evm.Context.Transfer(evm.StateDB, caller.Address(), address, value) + evm.Context.Transfer(evm.StateDB, caller, 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 := NewContract(caller, address, value, gas, evm.jumpDests) + + // Explicitly set the code to a null hash to prevent caching of jump analysis + // for the initialization code. + contract.SetCallCode(common.Hash{}, code) contract.IsDeployment = true - ret, err = evm.initNewContract(contract, address, value) + ret, err = evm.initNewContract(contract, address) if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) { evm.StateDB.RevertToSnapshot(snapshot) if err != ErrExecutionReverted { @@ -520,7 +513,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // 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) { +func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]byte, error) { ret, err := evm.interpreter.Run(contract, nil, false) if err != nil { return ret, err @@ -552,19 +545,18 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address, valu } // Create creates a new contract using code as deployment code. -func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) - return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE) +func (evm *EVM) Create(caller common.Address, code []byte, gas uint64, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { + contractAddr = crypto.CreateAddress(caller, evm.StateDB.GetNonce(caller)) + return evm.create(caller, code, gas, value, contractAddr, CREATE) } // Create2 creates a new contract using code as deployment code. // // The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:] // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. -func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - codeAndHash := &codeAndHash{code: code} - contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) - return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2) +func (evm *EVM) Create2(caller common.Address, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { + contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), crypto.Keccak256(code)) + return evm.create(caller, code, gas, endowment, contractAddr, CREATE2) } // resolveCode returns the code associated with the provided account. After diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index be86885261..cb6143c0b5 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -97,7 +97,7 @@ func TestEIP2200(t *testing.T) { } evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) - _, gas, err := evm.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(uint256.Int)) + _, gas, err := evm.Call(common.Address{}, address, nil, tt.gaspool, new(uint256.Int)) if !errors.Is(err, tt.failure) { t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure) } @@ -153,7 +153,7 @@ func TestCreateGas(t *testing.T) { evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, config) var startGas = uint64(testGas) - ret, gas, err := evm.Call(AccountRef(common.Address{}), address, nil, startGas, new(uint256.Int)) + ret, gas, err := evm.Call(common.Address{}, address, nil, startGas, new(uint256.Int)) if err != nil { return false } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index c9eea33507..1785ffc139 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -677,7 +677,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, tracing.GasChangeCallContractCreation) - res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, &value) + res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract.Address(), input, gas, &value) // Push item on the stack based on the returned error. If the ruleset is // homestead we must check for CodeStoreOutOfGasError (homestead only // rule) and treat as an error, if the ruleset is frontier we must @@ -718,7 +718,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] 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, + res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract.Address(), input, gas, &endowment, &salt) // Push item on the stack based on the returned error. if suberr != nil { @@ -755,7 +755,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt if !value.IsZero() { gas += params.CallStipend } - ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, &value) + ret, returnGas, err := interpreter.evm.Call(scope.Contract.Address(), toAddr, args, gas, &value) if err != nil { temp.Clear() @@ -789,7 +789,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ gas += params.CallStipend } - ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, &value) + ret, returnGas, err := interpreter.evm.CallCode(scope.Contract.Address(), toAddr, args, gas, &value) if err != nil { temp.Clear() } else { @@ -818,7 +818,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext // Get arguments from the memory. args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64()) - ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) + ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract.Caller(), scope.Contract.Address(), toAddr, args, gas, scope.Contract.value) if err != nil { temp.Clear() } else { @@ -847,7 +847,7 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) // Get arguments from the memory. args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64()) - ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas) + ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract.Address(), toAddr, args, gas) if err != nil { temp.Clear() } else { diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index 08f2b2bfea..0902d17c54 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -49,14 +49,6 @@ var alphabetSoup = "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffff var commonParams []*twoOperandParams var twoOpMethods map[string]executionFunc -type contractRef struct { - addr common.Address -} - -func (c contractRef) Address() common.Address { - return c.addr -} - func init() { // Params is a list of common edgecases that should be used for some common tests params := []string{ @@ -575,8 +567,7 @@ func TestOpTstore(t *testing.T) { mem = NewMemory() caller = common.Address{} to = common.Address{1} - contractRef = contractRef{caller} - contract = NewContract(contractRef, AccountRef(to), new(uint256.Int), 0) + contract = NewContract(caller, to, new(uint256.Int), 0, nil) scopeContext = ScopeContext{mem, stack, contract} value = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700") ) diff --git a/core/vm/interface.go b/core/vm/interface.go index 0d7862a66e..57f35cb249 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -17,8 +17,6 @@ package vm import ( - "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/stateless" @@ -104,16 +102,3 @@ type StateDB interface { // Finalise must be invoked at the end of a transaction Finalise(bool) } - -// CallContext provides a basic interface for the EVM calling conventions. The EVM -// depends on this context being implemented for doing subcalls and initialising new EVM contracts. -type CallContext interface { - // Call calls another contract. - Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) - // CallCode takes another contracts code and execute within our own context - CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) - // DelegateCall is same as CallCode except sender and value is propagated from parent to child scope - DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) - // Create creates a new contract - Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) -} diff --git a/core/vm/interpreter_test.go b/core/vm/interpreter_test.go index cacad8f813..0b93dd59e7 100644 --- a/core/vm/interpreter_test.go +++ b/core/vm/interpreter_test.go @@ -53,7 +53,7 @@ func TestLoopInterrupt(t *testing.T) { timeout := make(chan bool) go func(evm *EVM) { - _, _, err := evm.Call(AccountRef(common.Address{}), address, nil, math.MaxUint64, new(uint256.Int)) + _, _, err := evm.Call(common.Address{}, address, nil, math.MaxUint64, new(uint256.Int)) errChannel <- err }(evm) diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 2243e14b65..9d984291f2 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -128,7 +128,6 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { var ( address = common.BytesToAddress([]byte("contract")) 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 { @@ -143,7 +142,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { cfg.State.SetCode(address, code) // Call the code with the given configuration. ret, leftOverGas, err := vmenv.Call( - sender, + cfg.Origin, common.BytesToAddress([]byte("contract")), input, cfg.GasLimit, @@ -166,9 +165,8 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { 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) + vmenv = NewEnv(cfg) + 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) @@ -179,7 +177,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, nil, vm.ActivePrecompiles(rules), nil) // Call the code with the given configuration. code, address, leftOverGas, err := vmenv.Create( - sender, + cfg.Origin, input, cfg.GasLimit, uint256.MustFromBig(cfg.Value), @@ -200,7 +198,6 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er var ( vmenv = NewEnv(cfg) - sender = vm.AccountRef(cfg.Origin) statedb = cfg.State rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time) ) @@ -214,7 +211,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er // Call the code with the given configuration. ret, leftOverGas, err := vmenv.Call( - sender, + cfg.Origin, address, input, cfg.GasLimit, diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index faad1e7194..dbfc7308f7 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -33,19 +33,6 @@ import ( "github.com/holiman/uint256" ) -type account struct{} - -func (account) SubBalance(amount *big.Int) {} -func (account) AddBalance(amount *big.Int) {} -func (account) SetAddress(common.Address) {} -func (account) Value() *big.Int { return nil } -func (account) SetBalance(*uint256.Int) {} -func (account) SetNonce(uint64) {} -func (account) Balance() *uint256.Int { return nil } -func (account) Address() common.Address { return common.Address{} } -func (account) SetCode(common.Hash, []byte) {} -func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} - type dummyStatedb struct { state.StateDB } @@ -68,7 +55,7 @@ func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCo gasLimit uint64 = 31000 startGas uint64 = 10000 value = uint256.NewInt(0) - contract = vm.NewContract(account{}, account{}, value, startGas) + contract = vm.NewContract(common.Address{}, common.Address{}, value, startGas, nil) ) evm.SetTxContext(vmctx.txCtx) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} @@ -190,7 +177,7 @@ func TestHaltBetweenSteps(t *testing.T) { t.Fatal(err) } scope := &vm.ScopeContext{ - Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0), + Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), 0, nil), } evm := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, chainConfig, vm.Config{Tracer: tracer.Hooks}) evm.SetTxContext(vm.TxContext{GasPrice: big.NewInt(1)}) @@ -288,7 +275,7 @@ func TestEnterExit(t *testing.T) { t.Fatal(err) } scope := &vm.ScopeContext{ - Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0), + Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), 0, 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) diff --git a/eth/tracers/logger/logger_test.go b/eth/tracers/logger/logger_test.go index e7799dde35..b1e38bf627 100644 --- a/eth/tracers/logger/logger_test.go +++ b/eth/tracers/logger/logger_test.go @@ -29,22 +29,6 @@ import ( "github.com/holiman/uint256" ) -type dummyContractRef struct { - calledForEach bool -} - -func (dummyContractRef) Address() common.Address { return common.Address{} } -func (dummyContractRef) Value() *big.Int { return new(big.Int) } -func (dummyContractRef) SetCode(common.Hash, []byte) {} -func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) { - d.calledForEach = true -} -func (d *dummyContractRef) SubBalance(amount *big.Int) {} -func (d *dummyContractRef) AddBalance(amount *big.Int) {} -func (d *dummyContractRef) SetBalance(*big.Int) {} -func (d *dummyContractRef) SetNonce(uint64) {} -func (d *dummyContractRef) Balance() *big.Int { return new(big.Int) } - type dummyStatedb struct { state.StateDB } @@ -59,7 +43,7 @@ func TestStoreCapture(t *testing.T) { var ( logger = NewStructLogger(nil) evm = vm.NewEVM(vm.BlockContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: logger.Hooks()}) - contract = vm.NewContract(&dummyContractRef{}, &dummyContractRef{}, new(uint256.Int), 100000) + contract = vm.NewContract(common.Address{}, common.Address{}, new(uint256.Int), 100000, nil) ) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)} var index common.Hash diff --git a/tests/state_test.go b/tests/state_test.go index 0c9553c075..e7525118e2 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -310,8 +310,7 @@ func runBenchmark(b *testing.B, t *StateTest) { evm.SetTxContext(txContext) // Create "contract" for sender to cache code analysis. - sender := vm.NewContract(vm.AccountRef(msg.From), vm.AccountRef(msg.From), - nil, 0) + sender := vm.NewContract(msg.From, msg.From, nil, 0, nil) var ( gasUsed uint64 @@ -326,7 +325,7 @@ func runBenchmark(b *testing.B, t *StateTest) { start := time.Now() // Execute the message. - _, leftOverGas, err := evm.Call(sender, *msg.To, msg.Data, msg.GasLimit, uint256.MustFromBig(msg.Value)) + _, leftOverGas, err := evm.Call(sender.Address(), *msg.To, msg.Data, msg.GasLimit, uint256.MustFromBig(msg.Value)) if err != nil { b.Error(err) return From ef00a6e9a2bcb7b5737808d7e56a5c196009f918 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 18 Feb 2025 15:03:48 +0100 Subject: [PATCH 127/940] params: add osaka blob schedule (#31174) Prevents crashes when running execution spec tests for osaka --- consensus/misc/eip4844/eip4844.go | 8 ++++++++ core/genesis_test.go | 1 + params/config.go | 9 +++++++++ tests/init.go | 10 ++++++++++ 4 files changed, 28 insertions(+) diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index 4a2754b55c..32b34f4e53 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -83,6 +83,8 @@ func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTim func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int { var frac uint64 switch config.LatestFork(header.Time) { + case forks.Osaka: + frac = config.BlobScheduleConfig.Osaka.UpdateFraction case forks.Prague: frac = config.BlobScheduleConfig.Prague.UpdateFraction case forks.Cancun: @@ -103,6 +105,8 @@ func MaxBlobsPerBlock(cfg *params.ChainConfig, time uint64) int { s = cfg.BlobScheduleConfig ) switch { + case cfg.IsOsaka(london, time) && s.Osaka != nil: + return s.Osaka.Max case cfg.IsPrague(london, time) && s.Prague != nil: return s.Prague.Max case cfg.IsCancun(london, time) && s.Cancun != nil: @@ -125,6 +129,8 @@ func LatestMaxBlobsPerBlock(cfg *params.ChainConfig) int { return 0 } switch { + case s.Osaka != nil: + return s.Osaka.Max case s.Prague != nil: return s.Prague.Max case s.Cancun != nil: @@ -144,6 +150,8 @@ func targetBlobsPerBlock(cfg *params.ChainConfig, time uint64) int { s = cfg.BlobScheduleConfig ) switch { + case cfg.IsOsaka(london, time) && s.Osaka != nil: + return s.Osaka.Target case cfg.IsPrague(london, time) && s.Prague != nil: return s.Prague.Target case cfg.IsCancun(london, time) && s.Cancun != nil: diff --git a/core/genesis_test.go b/core/genesis_test.go index ad75afcd9e..86e5617ef8 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -281,6 +281,7 @@ func TestVerkleGenesisCommit(t *testing.T) { BlobScheduleConfig: ¶ms.BlobScheduleConfig{ Cancun: params.DefaultCancunBlobConfig, Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, Verkle: params.DefaultPragueBlobConfig, }, } diff --git a/params/config.go b/params/config.go index 5a2e10a943..523c987f01 100644 --- a/params/config.go +++ b/params/config.go @@ -317,10 +317,17 @@ var ( Max: 9, UpdateFraction: 5007716, } + // DefaultOsakaBlobConfig is the default blob configuration for the Osaka fork. + DefaultOsakaBlobConfig = &BlobConfig{ + Target: 6, + Max: 9, + UpdateFraction: 5007716, + } // DefaultBlobSchedule is the latest configured blob schedule for test chains. DefaultBlobSchedule = &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfig, + Osaka: DefaultOsakaBlobConfig, } ) @@ -501,6 +508,7 @@ type BlobConfig struct { type BlobScheduleConfig struct { Cancun *BlobConfig `json:"cancun,omitempty"` Prague *BlobConfig `json:"prague,omitempty"` + Osaka *BlobConfig `json:"osaka,omitempty"` Verkle *BlobConfig `json:"verkle,omitempty"` } @@ -732,6 +740,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { }{ {name: "cancun", timestamp: c.CancunTime, config: bsc.Cancun}, {name: "prague", timestamp: c.PragueTime, config: bsc.Prague}, + {name: "osaka", timestamp: c.OsakaTime, config: bsc.Osaka}, } { if cur.config != nil { if err := cur.config.validate(); err != nil { diff --git a/tests/init.go b/tests/init.go index ee8d354224..a8bc424fa2 100644 --- a/tests/init.go +++ b/tests/init.go @@ -431,6 +431,11 @@ var Forks = map[string]*params.ChainConfig{ PragueTime: u64(0), OsakaTime: u64(0), DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + }, }, "PragueToOsakaAtTime15k": { ChainID: big.NewInt(1), @@ -453,6 +458,11 @@ var Forks = map[string]*params.ChainConfig{ PragueTime: u64(0), OsakaTime: u64(15_000), DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + }, }, } From dab746b3efb24954a9d556e910a53fe527846bf4 Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Tue, 18 Feb 2025 15:08:43 -0500 Subject: [PATCH 128/940] eth/catalyst: support earlier forks in SimulatedBeacon (#31084) Co-authored-by: Marius van der Wijden --- eth/catalyst/simulated_beacon.go | 54 +++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/eth/catalyst/simulated_beacon.go b/eth/catalyst/simulated_beacon.go index a24ff52101..c71add93bc 100644 --- a/eth/catalyst/simulated_beacon.go +++ b/eth/catalyst/simulated_beacon.go @@ -33,6 +33,8 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/params/forks" "github.com/ethereum/go-ethereum/rpc" ) @@ -95,6 +97,16 @@ type SimulatedBeacon struct { lastBlockTime uint64 } +func payloadVersion(config *params.ChainConfig, time uint64) engine.PayloadVersion { + switch config.LatestFork(time) { + case forks.Prague, forks.Cancun: + return engine.PayloadV3 + case forks.Paris, forks.Shanghai: + return engine.PayloadV2 + } + panic("invalid fork, simulated beacon needs to be started post-merge") +} + // NewSimulatedBeacon constructs a new simulated beacon chain. func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) { block := eth.BlockChain().CurrentBlock() @@ -107,7 +119,8 @@ 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.ForkchoiceUpdatedV3(current, nil); err != nil { + version := payloadVersion(eth.BlockChain().Config(), block.Time) + if _, err := engineAPI.forkchoiceUpdated(current, nil, version, false); err != nil { return nil, err } } @@ -171,6 +184,8 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u return fmt.Errorf("failed to sync txpool: %w", err) } + version := payloadVersion(c.eth.BlockChain().Config(), timestamp) + var random [32]byte rand.Read(random[:]) fcResponse, err := c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, &engine.PayloadAttributes{ @@ -179,7 +194,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u Withdrawals: withdrawals, Random: random, BeaconRoot: &common.Hash{}, - }, engine.PayloadV3, false) + }, version, false) if err != nil { return err } @@ -204,28 +219,39 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u } } - // Independently calculate the blob hashes from sidecars. - blobHashes := make([]common.Hash, 0) - if envelope.BlobsBundle != nil { - hasher := sha256.New() - for _, commit := range envelope.BlobsBundle.Commitments { - var c kzg4844.Commitment - if len(commit) != len(c) { - return errors.New("invalid commitment length") + var ( + blobHashes []common.Hash + beaconRoot *common.Hash + requests [][]byte + ) + // Compute post-shanghai fields + if version > engine.PayloadV2 { + // Independently calculate the blob hashes from sidecars. + blobHashes = make([]common.Hash, 0) + if envelope.BlobsBundle != nil { + hasher := sha256.New() + for _, commit := range envelope.BlobsBundle.Commitments { + var c kzg4844.Commitment + if len(commit) != len(c) { + return errors.New("invalid commitment length") + } + copy(c[:], commit) + blobHashes = append(blobHashes, kzg4844.CalcBlobHashV1(hasher, &c)) } - copy(c[:], commit) - blobHashes = append(blobHashes, kzg4844.CalcBlobHashV1(hasher, &c)) } + beaconRoot = &common.Hash{} + requests = envelope.Requests } + // Mark the payload as canon - _, err = c.engineAPI.newPayload(*payload, blobHashes, &common.Hash{}, envelope.Requests, false) + _, err = c.engineAPI.newPayload(*payload, blobHashes, beaconRoot, requests, false) if err != nil { return err } c.setCurrentState(payload.BlockHash, finalizedHash) // Mark the block containing the payload as canonical - if _, err = c.engineAPI.ForkchoiceUpdatedV3(c.curForkchoiceState, nil); err != nil { + if _, err = c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, nil, version, false); err != nil { return err } c.lastBlockTime = payload.Timestamp From 07d7fe2b33c4356d95b045410afbd5bda4abda99 Mon Sep 17 00:00:00 2001 From: levisyin Date: Wed, 19 Feb 2025 18:21:22 +0800 Subject: [PATCH 129/940] build: upgrade -dlgo version to Go 1.24.0 (#31159) Co-authored-by: Felix Lange --- .github/workflows/go.yml | 4 +- .travis.yml | 14 ++-- Dockerfile | 2 +- Dockerfile.alltools | 2 +- build/checksums.txt | 173 ++++++++++++++++++++++----------------- go.mod | 2 +- 6 files changed, 112 insertions(+), 85 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index d1d2579dff..90449ef30d 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.0 + go-version: 1.24.0 cache: false - name: Run linters @@ -39,7 +39,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.0 + go-version: 1.24.0 cache: false - name: Run tests run: go test -short ./... diff --git a/.travis.yml b/.travis.yml index 8953450e84..5e8a493d03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ jobs: os: linux arch: amd64 dist: focal - go: 1.23.x + go: 1.24.x env: - docker services: @@ -33,7 +33,7 @@ jobs: os: linux dist: focal sudo: required - go: 1.23.x + go: 1.24.x env: - azure-linux git: @@ -85,7 +85,7 @@ jobs: os: linux arch: amd64 dist: focal - go: 1.23.x + go: 1.24.x script: - travis_wait 45 go run build/ci.go test $TEST_PACKAGES @@ -93,7 +93,7 @@ jobs: if: type = push os: linux dist: focal - go: 1.22.x + go: 1.23.x script: - travis_wait 45 go run build/ci.go test $TEST_PACKAGES @@ -102,7 +102,7 @@ jobs: if: type = cron || (type = push && tag ~= /^v[0-9]/) os: linux dist: focal - go: 1.23.x + go: 1.24.x env: - ubuntu-ppa git: @@ -118,7 +118,7 @@ jobs: if: type = cron os: linux dist: focal - go: 1.23.x + go: 1.24.x env: - azure-purge git: @@ -131,7 +131,7 @@ jobs: if: type = cron os: linux dist: focal - go: 1.23.x + go: 1.24.x env: - racetests script: diff --git a/Dockerfile b/Dockerfile index ff89e92f25..9b70e9e8a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ARG VERSION="" ARG BUILDNUM="" # Build Geth in a stock Go builder container -FROM golang:1.23-alpine AS builder +FROM golang:1.24-alpine AS builder RUN apk add --no-cache gcc musl-dev linux-headers git diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 44d5065af0..ac9303c678 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.23-alpine AS builder +FROM golang:1.24-alpine AS builder RUN apk add --no-cache gcc musl-dev linux-headers git diff --git a/build/checksums.txt b/build/checksums.txt index 76f05e5b63..1646cc6c45 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,82 +5,109 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/fixtures_pectra-devnet-6.tar.gz b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz -# version:golang 1.23.6 +# version:golang 1.24.0 # https://go.dev/dl/ -039c5b04e65279daceee8a6f71e70bd05cf5b801782b6f77c6e19e2ed0511222 go1.23.6.src.tar.gz -adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c go1.23.6.aix-ppc64.tar.gz -782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0 go1.23.6.darwin-amd64.tar.gz -5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221 go1.23.6.darwin-arm64.tar.gz -d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb go1.23.6.dragonfly-amd64.tar.gz -d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7 go1.23.6.freebsd-386.tar.gz -ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6 go1.23.6.freebsd-amd64.tar.gz -b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6 go1.23.6.freebsd-arm.tar.gz -004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310 go1.23.6.freebsd-arm64.tar.gz -ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a go1.23.6.freebsd-riscv64.tar.gz -7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8 go1.23.6.illumos-amd64.tar.gz -e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba go1.23.6.linux-386.tar.gz -9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d go1.23.6.linux-amd64.tar.gz -561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202 go1.23.6.linux-arm64.tar.gz -27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74 go1.23.6.linux-armv6l.tar.gz -c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750 go1.23.6.linux-loong64.tar.gz -e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622 go1.23.6.linux-mips.tar.gz -7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f go1.23.6.linux-mips64.tar.gz -74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a go1.23.6.linux-mips64le.tar.gz -09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb go1.23.6.linux-mipsle.tar.gz -5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c go1.23.6.linux-ppc64.tar.gz -0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99 go1.23.6.linux-ppc64le.tar.gz -f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3 go1.23.6.linux-riscv64.tar.gz -321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e go1.23.6.linux-s390x.tar.gz -92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c go1.23.6.netbsd-386.tar.gz -86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c go1.23.6.netbsd-amd64.tar.gz -4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816 go1.23.6.netbsd-arm.tar.gz -53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9 go1.23.6.netbsd-arm64.tar.gz -6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9 go1.23.6.openbsd-386.tar.gz -f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae go1.23.6.openbsd-amd64.tar.gz -3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f go1.23.6.openbsd-arm.tar.gz -cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c go1.23.6.openbsd-arm64.tar.gz -64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602 go1.23.6.openbsd-ppc64.tar.gz -c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377 go1.23.6.openbsd-riscv64.tar.gz -10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01 go1.23.6.plan9-386.tar.gz -9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f go1.23.6.plan9-amd64.tar.gz -8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83 go1.23.6.plan9-arm.tar.gz -b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7 go1.23.6.solaris-amd64.tar.gz -96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8 go1.23.6.windows-386.zip -53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243 go1.23.6.windows-amd64.zip -22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218 go1.23.6.windows-arm.zip -a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41 go1.23.6.windows-arm64.zip +d14120614acb29d12bcab72bd689f257eb4be9e0b6f88a8fb7e41ac65f8556e5 go1.24.0.src.tar.gz +5d04588154d5923bd8e26b76111806340ec55c41af1b05623ea744fcb3d6bc22 go1.24.0.aix-ppc64.tar.gz +7af054e5088b68c24b3d6e135e5ca8d91bbd5a05cb7f7f0187367b3e6e9e05ee go1.24.0.darwin-amd64.tar.gz +dee0ea64411a00b47ded586d5a8e30cfe3acf51564aa1bb24e039a6dca807a29 go1.24.0.darwin-amd64.pkg +fd9cfb5dd6c75a347cfc641a253f0db1cebaca16b0dd37965351c6184ba595e4 go1.24.0.darwin-arm64.tar.gz +b19eb6b7ae87f8371c3e7a84d129db67779a2883d2fffa6bb90412b0167df133 go1.24.0.darwin-arm64.pkg +d0dc34ad86aea746abe245994c68a9e1ad8f46ba8c4af901cd5861a4dd4c21df go1.24.0.dragonfly-amd64.tar.gz +4ee02b1f3812aff4da79c79464ee4038ca61ad74b3a9619850f30435f81c2536 go1.24.0.freebsd-386.tar.gz +838191001f9324da904dece35a586a3156d548687db87ac9461aa3d38fc88b09 go1.24.0.freebsd-amd64.tar.gz +ce6ad4e84a40a8a1d848b7e31b0cddfd1cee8f7959e7dc358a8fa8b5566ea718 go1.24.0.freebsd-arm.tar.gz +511f7b0cac4c4ed1066d324072ce223b906ad6b2a85f2e1c5d260eb7d08b5901 go1.24.0.freebsd-arm64.tar.gz +a1e4072630dc589a2975ef51317b52c7d8599bf6f389fc59033c01e0a0fa705a go1.24.0.freebsd-riscv64.tar.gz +7593e9dcee9f07c3df6d099f7d259f5734a6c0dccc5f28962f18e7f501c9bb21 go1.24.0.illumos-amd64.tar.gz +90521453a59c6ce20364d2dc7c38532949b033b602ba12d782caeb90af1b0624 go1.24.0.linux-386.tar.gz +dea9ca38a0b852a74e81c26134671af7c0fbe65d81b0dc1c5bfe22cf7d4c8858 go1.24.0.linux-amd64.tar.gz +c3fa6d16ffa261091a5617145553c71d21435ce547e44cc6dfb7470865527cc7 go1.24.0.linux-arm64.tar.gz +695dc54fa14cd3124fa6900d7b5ae39eeac23f7a4ecea81656070160fac2c54a go1.24.0.linux-armv6l.tar.gz +a201e4c9b7e6d29ed64c43296ed88e81a66f82f2093ce45b766d2c526941396f go1.24.0.linux-loong64.tar.gz +f3ac039aae78ad0bfb08106406c2e62eaf763dd82ebaf0ecd539adadd1d729a6 go1.24.0.linux-mips.tar.gz +f2e6456d45e024831b1da8d88b1bb6392cca9500c1b00841f525d76c9e9553e0 go1.24.0.linux-mips64.tar.gz +b847893ff119389c939adc2b8516b6500204b7cb49d5e19b25e1c2091d2c74c6 go1.24.0.linux-mips64le.tar.gz +bd4aed27d02746c237c3921e97029ac6b6fe687a67436b8f52ff1f698d330bd9 go1.24.0.linux-mipsle.tar.gz +007123c9b06c41729a4bb3f166f4df7196adf4e33c2d2ab0e7e990175f0ce1d4 go1.24.0.linux-ppc64.tar.gz +a871a43de7d26c91dd90cb6e0adacb214c9e35ee2188c617c91c08c017efe81a go1.24.0.linux-ppc64le.tar.gz +620dcf48c6297519aad6c81f8e344926dc0ab09a2a79f1e306964aece95a553d go1.24.0.linux-riscv64.tar.gz +544d78b077c6b54bf78958c4a8285abec2d21f668fb007261c77418cd2edbb46 go1.24.0.linux-s390x.tar.gz +8b143a7edefbaa2a0b0246c9df2df1bac9fbed909d8615a375c08da7744e697d go1.24.0.netbsd-386.tar.gz +67150a6dd7bdb9c4e88d77f46ee8c4dc99d5e71deca4912d8c2c85f7a16d0262 go1.24.0.netbsd-amd64.tar.gz +446b2539f11218fd6f6f6e3dd90b20ae55a06afe129885eeb3df51eb344eb0f6 go1.24.0.netbsd-arm.tar.gz +370115b6ff7d30b29431223de348eb11ab65e3c92627532d97fd55f63f94e7a8 go1.24.0.netbsd-arm64.tar.gz +cbda5f15f06ed9630f122a53542d9de13d149643633c74f1dcb45e79649b788a go1.24.0.openbsd-386.tar.gz +926f601d0e655ab1e8d7f357fd82542e5cf206c38c4e2f9fccf0706987d38836 go1.24.0.openbsd-amd64.tar.gz +8a54892f8c933c541fff144a825d0fdc41bae14b0832aab703cb75eb4cb64f2c go1.24.0.openbsd-arm.tar.gz +ef7fddcef0a22c7900c178b7687cf5aa25c2a9d46a3cc330b77a6de6e6c2396b go1.24.0.openbsd-arm64.tar.gz +b3b5e2e2b53489ded2c2c21900ddcbbdb7991632bb5b42f05f125d71675e0b76 go1.24.0.openbsd-ppc64.tar.gz +fbcb1dbf1269b4079dc4fd0b15f3274b9d635f1a7e319c3fc1a907b03280348e go1.24.0.openbsd-riscv64.tar.gz +33b4221e1c174a16e3f661deab6c60838ac4ae6cb869a4da1d1115773ceed88b go1.24.0.plan9-386.tar.gz +111a89014019cdbd69c2978de9b3e201f77e35183c8ab3606fba339d38f28549 go1.24.0.plan9-amd64.tar.gz +8da3d3997049f40ebe0cd336a9bb9e4bfa4832df3c90a32f07383371d6d74849 go1.24.0.plan9-arm.tar.gz +b6069da21dc95ccdbd047675b584e5480ffc3eba35f9e7c8b0e7b317aaf01e2c go1.24.0.solaris-amd64.tar.gz +b53c28a4c2863ec50ab4a1dbebe818ef6177f86773b6f43475d40a5d9aa4ec9e go1.24.0.windows-386.zip +f07677013cd7861c5e16067b0a82144c23c4bf72c139c762e142440f4c926f61 go1.24.0.windows-386.msi +96b7280979205813759ee6947be7e3bb497da85c482711116c00522e3bb41ff1 go1.24.0.windows-amd64.zip +4e78016d889431eb16aa0f87868cf52479b90059791c94a4ff45872d0573089e go1.24.0.windows-amd64.msi +53f73450fb66075d16be9f206e9177bd972b528168271918c4747903b5596c3d go1.24.0.windows-arm64.zip +4f9780158fb7996dcbcbc7c7ef208f880b5e8c1f2792ba3ede0c75050c1bc23a go1.24.0.windows-arm64.msi -# version:golangci 1.63.4 +# version:golangci 1.64.4 # https://github.com/golangci/golangci-lint/releases/ -# https://github.com/golangci/golangci-lint/releases/download/v1.63.4/ -878d017cc360e4fb19510d39852c8189852e3c48e7ce0337577df73507c97d68 golangci-lint-1.63.4-darwin-amd64.tar.gz -a2b630c2ac8466393f0ccbbede4462387b6c190697a70bc2298c6d2123f21bbf golangci-lint-1.63.4-darwin-arm64.tar.gz -8938b74aa92888e561a1c5a4c175110b92f84e7d24733703e6d9ebc39e9cd5f8 golangci-lint-1.63.4-freebsd-386.tar.gz -054903339d620df2e760b978920100986e3b03bcb058f669d520a71dac9c34ed golangci-lint-1.63.4-freebsd-amd64.tar.gz -a19d499f961a02608348e8b626537a88edfaab6e1b6534f1eff742b5d6d750e4 golangci-lint-1.63.4-freebsd-armv6.tar.gz -00d616f0fb275b780ce4d26604bdd7fdbfe6bc9c63acd5a0b31498e1f7511108 golangci-lint-1.63.4-freebsd-armv7.tar.gz -d453688e0eabded3c1a97ff5a2777bb0df5a18851efdaaaf6b472e3e5713c33e golangci-lint-1.63.4-illumos-amd64.tar.gz -6b1bec847fc9f347d53712d05606a49d55d0e3b5c1bacadfed2393f3503de0e9 golangci-lint-1.63.4-linux-386.tar.gz -01abb14a4df47b5ca585eff3c34b105023cba92ec34ff17212dbb83855581690 golangci-lint-1.63.4-linux-amd64.tar.gz -51f0c79d19a92353e0465fb30a4901a0644a975d34e6f399ad2eebc0160bbb24 golangci-lint-1.63.4-linux-arm64.tar.gz -8d0a43f41e8424fbae10f7aa2dc29999f98112817c6dba63d7dc76832940a673 golangci-lint-1.63.4-linux-armv6.tar.gz -1045a047b31e9302c9160c7b0f199f4ac1bd02a1b221a2d9521bd3507f0cf671 golangci-lint-1.63.4-linux-armv7.tar.gz -933fe10ab50ce3bb0806e15a4ae69fe20f0549abf91dea0161236000ca706e67 golangci-lint-1.63.4-linux-loong64.tar.gz -45798630cbad5642862766051199fa862ef3c33d569cab12f01cac4f68e2ddd5 golangci-lint-1.63.4-linux-mips64.tar.gz -86ae25335ddb24975d2c915c1af0c7fad70dce99d0b4614fa4bee392de714aa2 golangci-lint-1.63.4-linux-mips64le.tar.gz -33dabd11aaba4b602938da98bcf49aabab55019557e0115cdc3dbcc3009768fa golangci-lint-1.63.4-linux-ppc64le.tar.gz -4e7a81230a663bcdf30bba5689ce96040abc76994dbc2003dce32c8dca8c06f3 golangci-lint-1.63.4-linux-riscv64.tar.gz -21370b49c7c47f4d9b8f982c952f940b01e65710174c3b4dad7b6452d58f92ec golangci-lint-1.63.4-linux-s390x.tar.gz -255866a6464c7e11bb7edd8e6e6ad54f11e1f01b82ba9ca229698ac788cd9724 golangci-lint-1.63.4-netbsd-386.tar.gz -2798c040ac658bda97224f204795199c81ac97bb207b21c02b664aaed380d5d2 golangci-lint-1.63.4-netbsd-amd64.tar.gz -b910eecffd0064103837e7e1abe870deb8ade22331e6dffe319f430d49399c8e golangci-lint-1.63.4-netbsd-arm64.tar.gz -df2693ef37147b457c3e2089614537dd2ae2e18e53641e756a5b404f4c72d3fa golangci-lint-1.63.4-netbsd-armv6.tar.gz -a28a533366974bd7834c4516cd6075bff3419a508d1ed7aa63ae8182768b352e golangci-lint-1.63.4-netbsd-armv7.tar.gz -368932775fb5c620b324dabf018155f3365f5e33c5af5b26e9321db373f96eea golangci-lint-1.63.4-windows-386.zip -184d13c2b8f5441576bec2a0d8ba7b2d45445595cf796b879a73bcc98c39f8c1 golangci-lint-1.63.4-windows-amd64.zip -4fabf175d5b05ef0858ded49527948eebac50e9093814979fd84555a75fb80a6 golangci-lint-1.63.4-windows-arm64.zip -e92be3f3ff30d4a849fb4b9a4c8d56837dee45269cb405a3ecad52fa034c781b golangci-lint-1.63.4-windows-armv6.zip -c71d348653b8f7fbb109bb10c1a481722bc6b0b2b6e731b897f99ac869f7653e golangci-lint-1.63.4-windows-armv7.zip +# https://github.com/golangci/golangci-lint/releases/download/v1.64.4/ +f31ef6e20c62acc31eb7b851d611b4bd10256d1b1d8be38f0cceec300b5b60db golangci-lint-1.64.4-darwin-amd64.tar.gz +bb4a9ece7ef66ef49bd6de873f5f5ec801cf93dacf58efb360cc939b4fd37c47 golangci-lint-1.64.4-darwin-arm64.tar.gz +fd8f9046150356e36ad8af31f99219515d5e0ff6e8e9f4204182312447018fcf golangci-lint-1.64.4-freebsd-386.tar.gz +bbae940caa31cb1d2d8d26abd867666cd92746d2ddc63d6917d128c456d715ef golangci-lint-1.64.4-freebsd-amd64.tar.gz +86eb00cbdc5e277857a380d556d78a42b3edf8aae5991de8767dce7da337d73b golangci-lint-1.64.4-freebsd-armv6.tar.gz +c0f7d50f4fcd39ae8bda181c127b078a79d87c885ac472c4cce5b01134dde5bc golangci-lint-1.64.4-freebsd-armv7.tar.gz +31d264fa26a73a583425bc9b39c18de70a330e346fe800e80c277ddb5f8477b6 golangci-lint-1.64.4-illumos-amd64.tar.gz +3dccc18a6b1a0f2518196190ed56277b1480b381231605936eca6b862426b83c golangci-lint-1.64.4-linux-386.deb +b95f3e757c59ada75144bd086478ab63bcda83c2b2a935e60d8f39aff20fbcd2 golangci-lint-1.64.4-linux-386.rpm +8fa58af0022ae0487162c02d08075e2d869c9b5f8613a64b85fd769a2a2d2b93 golangci-lint-1.64.4-linux-386.tar.gz +fa80d2ad920fc74b85a0b93ad1671fd27c9c4d6f22e167cc4e1da758d72dd893 golangci-lint-1.64.4-linux-amd64.deb +8bf2e3c82504a893a12e84ecbc8071f787075d2fdc1ef946deda3d29aae1afad golangci-lint-1.64.4-linux-amd64.rpm +7de8f80a12cd3052610e6be21f08f2220805b1f3e43b3b6ec843f14a12140de2 golangci-lint-1.64.4-linux-amd64.tar.gz +ade222b9ae997a2875e44ed53ca5a129f24944b232132d0a5898f101381d3bfa golangci-lint-1.64.4-linux-arm64.deb +8f9f8617ed0d8b8f62c8dfe69877932c0d85f0d83a9ec3250b04777c7133ada1 golangci-lint-1.64.4-linux-arm64.rpm +debf1f73e71f1dd288957574eab4e7515b1b04c4ac2f127192181da8a42f0e8e golangci-lint-1.64.4-linux-arm64.tar.gz +3f616caa4a16738114ad29076a333c62bb0650fe4846b438c341d235f78ee5aa golangci-lint-1.64.4-linux-armv6.deb +6a7c9d7b7c57d7d440e1e3f133e18e4b5b703604d4ae7f7862fb9ea461887a8b golangci-lint-1.64.4-linux-armv6.rpm +d7b9e3c89af93d98c6b5a555ef48e25bee24f84d7825a29e343e9966404d5b4d golangci-lint-1.64.4-linux-armv6.tar.gz +18179ecf04ace3051450852424b31a4d26644a3912e759cd595e624eee0174bd golangci-lint-1.64.4-linux-armv7.deb +f669fce85d3edc3d557d1e64e2241d895f1ee676f79d139874bf76693cc447a2 golangci-lint-1.64.4-linux-armv7.rpm +9bbaa13b474ecb1560fb05aee0a8cab3e9cc327d41632bee8b553b766f2bf756 golangci-lint-1.64.4-linux-armv7.tar.gz +b5a2725adba2a1b04a5160ffa0730ba30b88c1ee99ecbc65dd7075a8d70f3730 golangci-lint-1.64.4-linux-loong64.deb +28ac00afb3f6407808fe7c15a6002e5fe6b3b461df3fe0223603542e6f9b974a golangci-lint-1.64.4-linux-loong64.rpm +121170309fed82cb64d6fae5020ef2b194e591a53156370c221a80121cc4aa08 golangci-lint-1.64.4-linux-loong64.tar.gz +aadfaab41380f53ada8f7ad4fa9af784bb882eaaa1e3939e048b3a5ea8f2c13f golangci-lint-1.64.4-linux-mips64.deb +6fecbff69086e316dd028050d3ebf82fc466c7f4dc0f6084307054621101c202 golangci-lint-1.64.4-linux-mips64.rpm +430c48034527af028dc608c115166f47b6b67c8cb83a317d9d44876b9753292a golangci-lint-1.64.4-linux-mips64.tar.gz +432126af2bbbd639dbbcc2c265337f104cc613a7b4c5a8fb5e49f182b428f077 golangci-lint-1.64.4-linux-mips64le.deb +cfa663eee0fae721510d6dc31e61db4be51b4e4244eb7de2b6a9bc6d475551e5 golangci-lint-1.64.4-linux-mips64le.rpm +2bacfac65182893c5ceb67b61d5b9d2b24da47726d84cb87d734a6e32f040148 golangci-lint-1.64.4-linux-mips64le.tar.gz +66d86e47d68420c03045eff0698e9acf9f82d97cd1f07d7e52837a6e544eceed golangci-lint-1.64.4-linux-ppc64le.deb +05466bd2d8e82f7245b838e29d0c90cdbaf67375b2b5bc980d8510d5edb206ad golangci-lint-1.64.4-linux-ppc64le.rpm +e013b6980f7140712af0aedc9a661265e1d3c6adc7e9d045734e3686a3601acc golangci-lint-1.64.4-linux-ppc64le.tar.gz +753980d2fb421d35292b71b51f9bb0552f18de2eb181ccf692ef79e086ad2304 golangci-lint-1.64.4-linux-riscv64.deb +73a33a883020298f8c652a4ace4f6888103d80d411fe3e9b77ce0a3b36ff7d3a golangci-lint-1.64.4-linux-riscv64.rpm +020efd09b894dc75012f43b1d4c58e69e5446ca3f79845b5e10a02588def3e1b golangci-lint-1.64.4-linux-riscv64.tar.gz +4d99a16bc9ff5cea5e4ae3568c6254390fbdad8f1d370c287744409112bceff9 golangci-lint-1.64.4-linux-s390x.deb +6e63374a9f95fc09f2bb9501059eb18b8107e08416722ba7b561ae385d80b33b golangci-lint-1.64.4-linux-s390x.rpm +62a6febb892b26eee84a32cc99d04afe90bf62d0970774b1bab75e36b66f53b4 golangci-lint-1.64.4-linux-s390x.tar.gz +5ba4d235f9abd60d2d280f9fe4228c6ddab11ae9fe48d253b7e477046675f1f6 golangci-lint-1.64.4-netbsd-386.tar.gz +061643bb4370a52010e5e76f88f5b5220e51058df50af86b45286263af92b321 golangci-lint-1.64.4-netbsd-amd64.tar.gz +12b2be6c35bcf7a36374e952c7efec7905a17fa3ebe6214924ba8721b766c4af golangci-lint-1.64.4-netbsd-arm64.tar.gz +553a71a677751dccee082ed8afe24cf58bef725f72aa02aedcc6758dd8f44125 golangci-lint-1.64.4-netbsd-armv6.tar.gz +74a5a5a7b8c8cd11dccdec303ee6592d904b09836782e6d658be359737f300ef golangci-lint-1.64.4-netbsd-armv7.tar.gz +b3ceea2187843f9ba6510303141a72465621e3f190a262c0b48707b9e983ea9a golangci-lint-1.64.4-source.tar.gz +fda4de312fcb0b4853b03bcdfb31ac631a68fa0b966f6aa010eb30d14427180b golangci-lint-1.64.4-windows-386.zip +8fc60bd809f86c6431ed8f3d1f25917538c0ebc93e670cfb199f25bbaa56e602 golangci-lint-1.64.4-windows-amd64.zip +b9058c9d2ae8d75048c6ad8885d11e5ac0a6c40be2af85bfa6605e48d69d3eb6 golangci-lint-1.64.4-windows-arm64.zip +809b0131adb1aa8b359becd13222df367b505bc2955bb3b1d2d0dd6f07347b13 golangci-lint-1.64.4-windows-armv6.zip +fc43f8c95d6bec8ba9a3557a0bb63cf9f504137ce6d24cfdc4c330d46f7779d2 golangci-lint-1.64.4-windows-armv7.zip # This is the builder on PPA that will build Go itself (inception-y), don't modify! # diff --git a/go.mod b/go.mod index cf9fda50c8..c9f4a4e4ba 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ethereum/go-ethereum -go 1.22.0 +go 1.23.0 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 From aac621987eda4fabf71f159e24560caf30d0e7de Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 19 Feb 2025 14:57:08 +0100 Subject: [PATCH 130/940] core/asm: delete assembler/disassembler (#31211) I maintain an improved version of the go-ethereum assembler at https://github.com/fjl/geas. We don't really use core/asm in our tests, and it has some bugs that prevent it from being useful, so I'm removing the package. --- core/asm/asm.go | 156 ----------------- core/asm/asm_test.go | 94 ---------- core/asm/compiler.go | 292 -------------------------------- core/asm/compiler_test.go | 79 --------- core/asm/lex_test.go | 93 ---------- core/asm/lexer.go | 275 ------------------------------ core/asm/tokentype_string.go | 31 ---- core/vm/runtime/runtime_test.go | 15 +- 8 files changed, 1 insertion(+), 1034 deletions(-) delete mode 100644 core/asm/asm.go delete mode 100644 core/asm/asm_test.go delete mode 100644 core/asm/compiler.go delete mode 100644 core/asm/compiler_test.go delete mode 100644 core/asm/lex_test.go delete mode 100644 core/asm/lexer.go delete mode 100644 core/asm/tokentype_string.go diff --git a/core/asm/asm.go b/core/asm/asm.go deleted file mode 100644 index f4b59f4471..0000000000 --- a/core/asm/asm.go +++ /dev/null @@ -1,156 +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 asm provides support for dealing with EVM assembly instructions (e.g., disassembling them). -package asm - -import ( - "encoding/hex" - "fmt" - - "github.com/ethereum/go-ethereum/core/vm" -) - -// Iterator for disassembled EVM instructions -type instructionIterator struct { - code []byte - pc uint64 - arg []byte - op vm.OpCode - error error - started bool - eofEnabled bool -} - -// NewInstructionIterator creates a new instruction iterator. -func NewInstructionIterator(code []byte) *instructionIterator { - it := new(instructionIterator) - it.code = code - return it -} - -// NewEOFInstructionIterator creates a new instruction iterator for EOF-code. -func NewEOFInstructionIterator(code []byte) *instructionIterator { - it := NewInstructionIterator(code) - it.eofEnabled = true - return it -} - -// Next returns true if there is a next instruction and moves on. -func (it *instructionIterator) Next() bool { - if it.error != nil || uint64(len(it.code)) <= it.pc { - // We previously reached an error or the end. - return false - } - - if it.started { - // Since the iteration has been already started we move to the next instruction. - if it.arg != nil { - it.pc += uint64(len(it.arg)) - } - it.pc++ - } else { - // We start the iteration from the first instruction. - it.started = true - } - - if uint64(len(it.code)) <= it.pc { - // We reached the end. - return false - } - it.op = vm.OpCode(it.code[it.pc]) - var a int - if !it.eofEnabled { // Legacy code - if it.op.IsPush() { - a = int(it.op) - int(vm.PUSH0) - } - } else { // EOF code - if it.op == vm.RJUMPV { - // RJUMPV is unique as it has a variable sized operand. The total size is - // determined by the count byte which immediately follows RJUMPV. - maxIndex := int(it.code[it.pc+1]) - a = (maxIndex+1)*2 + 1 - } else { - a = vm.Immediates(it.op) - } - } - if a > 0 { - u := it.pc + 1 + uint64(a) - if uint64(len(it.code)) <= it.pc || uint64(len(it.code)) < u { - it.error = fmt.Errorf("incomplete instruction at %v", it.pc) - return false - } - it.arg = it.code[it.pc+1 : u] - } else { - it.arg = nil - } - return true -} - -// Error returns any error that may have been encountered. -func (it *instructionIterator) Error() error { - return it.error -} - -// PC returns the PC of the current instruction. -func (it *instructionIterator) PC() uint64 { - return it.pc -} - -// Op returns the opcode of the current instruction. -func (it *instructionIterator) Op() vm.OpCode { - return it.op -} - -// Arg returns the argument of the current instruction. -func (it *instructionIterator) Arg() []byte { - return it.arg -} - -// PrintDisassembled pretty-print all disassembled EVM instructions to stdout. -func PrintDisassembled(code string) error { - script, err := hex.DecodeString(code) - if err != nil { - return err - } - it := NewInstructionIterator(script) - for it.Next() { - if it.Arg() != nil && 0 < len(it.Arg()) { - fmt.Printf("%05x: %v %#x\n", it.PC(), it.Op(), it.Arg()) - } else { - fmt.Printf("%05x: %v\n", it.PC(), it.Op()) - } - } - return it.Error() -} - -// Disassemble returns all disassembled EVM instructions in human-readable format. -func Disassemble(script []byte) ([]string, error) { - instrs := make([]string, 0) - - it := NewInstructionIterator(script) - for it.Next() { - if it.Arg() != nil && 0 < len(it.Arg()) { - instrs = append(instrs, fmt.Sprintf("%05x: %v %#x\n", it.PC(), it.Op(), it.Arg())) - } else { - instrs = append(instrs, fmt.Sprintf("%05x: %v\n", it.PC(), it.Op())) - } - } - if err := it.Error(); err != nil { - return nil, err - } - return instrs, nil -} diff --git a/core/asm/asm_test.go b/core/asm/asm_test.go deleted file mode 100644 index 50fe9e1225..0000000000 --- a/core/asm/asm_test.go +++ /dev/null @@ -1,94 +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 asm - -import ( - "encoding/hex" - "fmt" - "strings" - "testing" -) - -// Tests disassembling instructions -func TestInstructionIterator(t *testing.T) { - for i, tc := range []struct { - code string - legacyWant string - eofWant string - }{ - {"", "", ""}, // empty - {"6100", `err: incomplete instruction at 0`, `err: incomplete instruction at 0`}, - {"61000000", ` -00000: PUSH2 0x0000 -00003: STOP`, ` -00000: PUSH2 0x0000 -00003: STOP`}, - {"5F00", ` -00000: PUSH0 -00001: STOP`, ` -00000: PUSH0 -00001: STOP`}, - {"d1aabb00", `00000: DATALOADN -00001: opcode 0xaa not defined -00002: opcode 0xbb not defined -00003: STOP`, ` -00000: DATALOADN 0xaabb -00003: STOP`}, // DATALOADN(aabb),STOP - {"d1aa", ` -00000: DATALOADN -00001: opcode 0xaa not defined`, "err: incomplete instruction at 0\n"}, // DATALOADN(aa) invalid - {"e20211223344556600", ` -00000: RJUMPV -00001: MUL -00002: GT -00003: opcode 0x22 not defined -00004: CALLER -00005: DIFFICULTY -00006: SSTORE -err: incomplete instruction at 7`, ` -00000: RJUMPV 0x02112233445566 -00008: STOP`}, // RJUMPV( 6 bytes), STOP - - } { - var ( - code, _ = hex.DecodeString(tc.code) - legacy = strings.TrimSpace(disassembly(NewInstructionIterator(code))) - eof = strings.TrimSpace(disassembly(NewEOFInstructionIterator(code))) - ) - if want := strings.TrimSpace(tc.legacyWant); legacy != want { - t.Errorf("test %d: wrong (legacy) output. have:\n%q\nwant:\n%q\n", i, legacy, want) - } - if want := strings.TrimSpace(tc.eofWant); eof != want { - t.Errorf("test %d: wrong (eof) output. have:\n%q\nwant:\n%q\n", i, eof, want) - } - } -} - -func disassembly(it *instructionIterator) string { - var out = new(strings.Builder) - for it.Next() { - if it.Arg() != nil && 0 < len(it.Arg()) { - fmt.Fprintf(out, "%05x: %v %#x\n", it.PC(), it.Op(), it.Arg()) - } else { - fmt.Fprintf(out, "%05x: %v\n", it.PC(), it.Op()) - } - } - if err := it.Error(); err != nil { - fmt.Fprintf(out, "err: %v\n", err) - } - return out.String() -} diff --git a/core/asm/compiler.go b/core/asm/compiler.go deleted file mode 100644 index 02c589b2c1..0000000000 --- a/core/asm/compiler.go +++ /dev/null @@ -1,292 +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 asm - -import ( - "encoding/hex" - "errors" - "fmt" - "math/big" - "os" - "strings" - - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/vm" -) - -// Compiler contains information about the parsed source -// and holds the tokens for the program. -type Compiler struct { - tokens []token - out []byte - - labels map[string]int - - pc, pos int - - debug bool -} - -// NewCompiler returns a new allocated compiler. -func NewCompiler(debug bool) *Compiler { - return &Compiler{ - labels: make(map[string]int), - debug: debug, - } -} - -// Feed feeds tokens into ch and are interpreted by -// the compiler. -// -// feed is the first pass in the compile stage as it collects the used labels in the -// program and keeps a program counter which is used to determine the locations of the -// jump dests. The labels can than be used in the second stage to push labels and -// determine the right position. -func (c *Compiler) Feed(ch <-chan token) { - var prev token - for i := range ch { - switch i.typ { - case number: - num := math.MustParseBig256(i.text).Bytes() - if len(num) == 0 { - num = []byte{0} - } - c.pc += len(num) - case stringValue: - c.pc += len(i.text) - 2 - case element: - c.pc++ - case labelDef: - c.labels[i.text] = c.pc - c.pc++ - case label: - c.pc += 4 - if prev.typ == element && isJump(prev.text) { - c.pc++ - } - } - c.tokens = append(c.tokens, i) - prev = i - } - if c.debug { - fmt.Fprintln(os.Stderr, "found", len(c.labels), "labels") - } -} - -// Compile compiles the current tokens and returns a binary string that can be interpreted -// by the EVM and an error if it failed. -// -// compile is the second stage in the compile phase which compiles the tokens to EVM -// instructions. -func (c *Compiler) Compile() (string, []error) { - var errors []error - // continue looping over the tokens until - // the stack has been exhausted. - for c.pos < len(c.tokens) { - if err := c.compileLine(); err != nil { - errors = append(errors, err) - } - } - - // turn the binary to hex - h := hex.EncodeToString(c.out) - return h, errors -} - -// next returns the next token and increments the -// position. -func (c *Compiler) next() token { - token := c.tokens[c.pos] - c.pos++ - return token -} - -// compileLine compiles a single line instruction e.g. -// "push 1", "jump @label". -func (c *Compiler) compileLine() error { - n := c.next() - if n.typ != lineStart { - return compileErr(n, n.typ.String(), lineStart.String()) - } - - lvalue := c.next() - switch lvalue.typ { - case eof: - return nil - case element: - if err := c.compileElement(lvalue); err != nil { - return err - } - case labelDef: - c.compileLabel() - case lineEnd: - return nil - default: - return compileErr(lvalue, lvalue.text, fmt.Sprintf("%v or %v", labelDef, element)) - } - - if n := c.next(); n.typ != lineEnd { - return compileErr(n, n.text, lineEnd.String()) - } - - return nil -} - -// parseNumber compiles the number to bytes -func parseNumber(tok token) ([]byte, error) { - if tok.typ != number { - panic("parseNumber of non-number token") - } - num, ok := math.ParseBig256(tok.text) - if !ok { - return nil, errors.New("invalid number") - } - bytes := num.Bytes() - if len(bytes) == 0 { - bytes = []byte{0} - } - return bytes, nil -} - -// compileElement compiles the element (push & label or both) -// to a binary representation and may error if incorrect statements -// where fed. -func (c *Compiler) compileElement(element token) error { - switch { - case isJump(element.text): - return c.compileJump(element.text) - case isPush(element.text): - return c.compilePush() - default: - c.outputOpcode(toBinary(element.text)) - return nil - } -} - -func (c *Compiler) compileJump(jumpType string) error { - rvalue := c.next() - switch rvalue.typ { - case number: - numBytes, err := parseNumber(rvalue) - if err != nil { - return err - } - c.outputBytes(numBytes) - - case stringValue: - // strings are quoted, remove them. - str := rvalue.text[1 : len(rvalue.text)-2] - c.outputBytes([]byte(str)) - - case label: - c.outputOpcode(vm.PUSH4) - pos := big.NewInt(int64(c.labels[rvalue.text])).Bytes() - pos = append(make([]byte, 4-len(pos)), pos...) - c.outputBytes(pos) - - case lineEnd: - // push without argument is supported, it just takes the destination from the stack. - c.pos-- - - default: - return compileErr(rvalue, rvalue.text, "number, string or label") - } - // push the operation - c.outputOpcode(toBinary(jumpType)) - return nil -} - -func (c *Compiler) compilePush() error { - // handle pushes. pushes are read from left to right. - var value []byte - rvalue := c.next() - switch rvalue.typ { - case number: - value = math.MustParseBig256(rvalue.text).Bytes() - if len(value) == 0 { - value = []byte{0} - } - case stringValue: - value = []byte(rvalue.text[1 : len(rvalue.text)-1]) - case label: - value = big.NewInt(int64(c.labels[rvalue.text])).Bytes() - value = append(make([]byte, 4-len(value)), value...) - default: - return compileErr(rvalue, rvalue.text, "number, string or label") - } - if len(value) > 32 { - return fmt.Errorf("%d: string or number size > 32 bytes", rvalue.lineno+1) - } - c.outputOpcode(vm.OpCode(int(vm.PUSH1) - 1 + len(value))) - c.outputBytes(value) - return nil -} - -// compileLabel pushes a jumpdest to the binary slice. -func (c *Compiler) compileLabel() { - c.outputOpcode(vm.JUMPDEST) -} - -func (c *Compiler) outputOpcode(op vm.OpCode) { - if c.debug { - fmt.Printf("%d: %v\n", len(c.out), op) - } - c.out = append(c.out, byte(op)) -} - -// output pushes the value v to the binary stack. -func (c *Compiler) outputBytes(b []byte) { - if c.debug { - fmt.Printf("%d: %x\n", len(c.out), b) - } - c.out = append(c.out, b...) -} - -// isPush returns whether the string op is either any of -// push(N). -func isPush(op string) bool { - return strings.EqualFold(op, "PUSH") -} - -// isJump returns whether the string op is jump(i) -func isJump(op string) bool { - return strings.EqualFold(op, "JUMPI") || strings.EqualFold(op, "JUMP") -} - -// toBinary converts text to a vm.OpCode -func toBinary(text string) vm.OpCode { - return vm.StringToOp(strings.ToUpper(text)) -} - -type compileError struct { - got string - want string - - lineno int -} - -func (err compileError) Error() string { - return fmt.Sprintf("%d: syntax error: unexpected %v, expected %v", err.lineno, err.got, err.want) -} - -func compileErr(c token, got, want string) error { - return compileError{ - got: got, - want: want, - lineno: c.lineno + 1, - } -} diff --git a/core/asm/compiler_test.go b/core/asm/compiler_test.go deleted file mode 100644 index 3d64c96bc8..0000000000 --- a/core/asm/compiler_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2019 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 asm - -import ( - "testing" -) - -func TestCompiler(t *testing.T) { - tests := []struct { - input, output string - }{ - { - input: ` - GAS - label: - PUSH @label -`, - output: "5a5b6300000001", - }, - { - input: ` - PUSH @label - label: -`, - output: "63000000055b", - }, - { - input: ` - PUSH @label - JUMP - label: -`, - output: "6300000006565b", - }, - { - input: ` - JUMP @label - label: -`, - output: "6300000006565b", - }, - { - input: ` - JUMP @label -label: ;; comment - ADD ;; comment -`, - output: "6300000006565b01", - }, - } - for _, test := range tests { - ch := Lex([]byte(test.input), false) - c := NewCompiler(false) - c.Feed(ch) - output, err := c.Compile() - if len(err) != 0 { - t.Errorf("compile error: %v\ninput: %s", err, test.input) - continue - } - if output != test.output { - t.Errorf("incorrect output\ninput: %sgot: %s\nwant: %s\n", test.input, output, test.output) - } - } -} diff --git a/core/asm/lex_test.go b/core/asm/lex_test.go deleted file mode 100644 index 1e62d776d4..0000000000 --- a/core/asm/lex_test.go +++ /dev/null @@ -1,93 +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 asm - -import ( - "reflect" - "testing" -) - -func lexAll(src string) []token { - ch := Lex([]byte(src), false) - - var tokens []token - for i := range ch { - tokens = append(tokens, i) - } - return tokens -} - -func TestLexer(t *testing.T) { - tests := []struct { - input string - tokens []token - }{ - { - input: ";; this is a comment", - tokens: []token{{typ: lineStart}, {typ: eof}}, - }, - { - input: "0x12345678", - tokens: []token{{typ: lineStart}, {typ: number, text: "0x12345678"}, {typ: eof}}, - }, - { - input: "0x123ggg", - tokens: []token{{typ: lineStart}, {typ: number, text: "0x123"}, {typ: element, text: "ggg"}, {typ: eof}}, - }, - { - input: "12345678", - tokens: []token{{typ: lineStart}, {typ: number, text: "12345678"}, {typ: eof}}, - }, - { - input: "123abc", - tokens: []token{{typ: lineStart}, {typ: number, text: "123"}, {typ: element, text: "abc"}, {typ: eof}}, - }, - { - input: "0123abc", - tokens: []token{{typ: lineStart}, {typ: number, text: "0123"}, {typ: element, text: "abc"}, {typ: eof}}, - }, - { - input: "00123abc", - tokens: []token{{typ: lineStart}, {typ: number, text: "00123"}, {typ: element, text: "abc"}, {typ: eof}}, - }, - { - input: "@foo", - tokens: []token{{typ: lineStart}, {typ: label, text: "foo"}, {typ: eof}}, - }, - { - input: "@label123", - tokens: []token{{typ: lineStart}, {typ: label, text: "label123"}, {typ: eof}}, - }, - // Comment after label - { - input: "@label123 ;; comment", - tokens: []token{{typ: lineStart}, {typ: label, text: "label123"}, {typ: eof}}, - }, - // Comment after instruction - { - input: "push 3 ;; comment\nadd", - tokens: []token{{typ: lineStart}, {typ: element, text: "push"}, {typ: number, text: "3"}, {typ: lineEnd, text: "\n"}, {typ: lineStart, lineno: 1}, {typ: element, lineno: 1, text: "add"}, {typ: eof, lineno: 1}}, - }, - } - - for _, test := range tests { - tokens := lexAll(test.input) - if !reflect.DeepEqual(tokens, test.tokens) { - t.Errorf("input %q\ngot: %+v\nwant: %+v", test.input, tokens, test.tokens) - } - } -} diff --git a/core/asm/lexer.go b/core/asm/lexer.go deleted file mode 100644 index 630360b106..0000000000 --- a/core/asm/lexer.go +++ /dev/null @@ -1,275 +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 asm - -import ( - "fmt" - "os" - "strings" - "unicode" - "unicode/utf8" -) - -// stateFn is used through the lifetime of the -// lexer to parse the different values at the -// current state. -type stateFn func(*lexer) stateFn - -// token is emitted when the lexer has discovered -// a new parsable token. These are delivered over -// the tokens channels of the lexer -type token struct { - typ tokenType - lineno int - text string -} - -// tokenType are the different types the lexer -// is able to parse and return. -type tokenType int - -//go:generate go run golang.org/x/tools/cmd/stringer -type tokenType - -const ( - eof tokenType = iota // end of file - lineStart // emitted when a line starts - lineEnd // emitted when a line ends - invalidStatement // any invalid statement - element // any element during element parsing - label // label is emitted when a label is found - labelDef // label definition is emitted when a new label is found - number // number is emitted when a number is found - stringValue // stringValue is emitted when a string has been found -) - -const ( - decimalNumbers = "1234567890" // characters representing any decimal number - hexNumbers = decimalNumbers + "aAbBcCdDeEfF" // characters representing any hexadecimal - alpha = "abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ" // characters representing alphanumeric -) - -// lexer is the basic construct for parsing -// source code and turning them in to tokens. -// Tokens are interpreted by the compiler. -type lexer struct { - input string // input contains the source code of the program - - tokens chan token // tokens is used to deliver tokens to the listener - state stateFn // the current state function - - lineno int // current line number in the source file - start, pos, width int // positions for lexing and returning value - - debug bool // flag for triggering debug output -} - -// Lex lexes the program by name with the given source. It returns a -// channel on which the tokens are delivered. -func Lex(source []byte, debug bool) <-chan token { - ch := make(chan token) - l := &lexer{ - input: string(source), - tokens: ch, - state: lexLine, - debug: debug, - } - go func() { - l.emit(lineStart) - for l.state != nil { - l.state = l.state(l) - } - l.emit(eof) - close(l.tokens) - }() - - return ch -} - -// next returns the next rune in the program's source. -func (l *lexer) next() (rune rune) { - if l.pos >= len(l.input) { - l.width = 0 - return 0 - } - rune, l.width = utf8.DecodeRuneInString(l.input[l.pos:]) - l.pos += l.width - return rune -} - -// backup backsup the last parsed element (multi-character) -func (l *lexer) backup() { - l.pos -= l.width -} - -// peek returns the next rune but does not advance the seeker -func (l *lexer) peek() rune { - r := l.next() - l.backup() - return r -} - -// ignore advances the seeker and ignores the value -func (l *lexer) ignore() { - l.start = l.pos -} - -// 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 - } - - l.backup() - - return false -} - -// acceptRun will continue to advance the seeker until valid -// can no longer be met. -func (l *lexer) acceptRun(valid string) { - for strings.ContainsRune(valid, l.next()) { - } - l.backup() -} - -// acceptRunUntil is the inverse of acceptRun and will continue -// to advance the seeker until the rune has been found. -func (l *lexer) acceptRunUntil(until rune) bool { - // Continues running until a rune is found - for i := l.next(); !strings.ContainsRune(string(until), i); i = l.next() { - if i == 0 { - return false - } - } - - return true -} - -// blob returns the current value -func (l *lexer) blob() string { - return l.input[l.start:l.pos] -} - -// Emits a new token on to token channel for processing -func (l *lexer) emit(t tokenType) { - token := token{t, l.lineno, l.blob()} - - if l.debug { - fmt.Fprintf(os.Stderr, "%04d: (%-20v) %s\n", token.lineno, token.typ, token.text) - } - - l.tokens <- token - l.start = l.pos -} - -// lexLine is state function for lexing lines -func lexLine(l *lexer) stateFn { - for { - switch r := l.next(); { - case r == '\n': - l.emit(lineEnd) - l.ignore() - l.lineno++ - l.emit(lineStart) - case r == ';' && l.peek() == ';': - return lexComment - case isSpace(r): - l.ignore() - case isLetter(r) || r == '_': - return lexElement - case isNumber(r): - return lexNumber - case r == '@': - l.ignore() - return lexLabel - case r == '"': - return lexInsideString - default: - return nil - } - } -} - -// lexComment parses the current position until the end -// of the line and discards the text. -func lexComment(l *lexer) stateFn { - l.acceptRunUntil('\n') - l.backup() - l.ignore() - - return lexLine -} - -// lexLabel parses the current label, emits and returns -// the lex text state function to advance the parsing -// process. -func lexLabel(l *lexer) stateFn { - l.acceptRun(alpha + "_" + decimalNumbers) - - l.emit(label) - - return lexLine -} - -// lexInsideString lexes the inside of a string until -// the state function finds the closing quote. -// It returns the lex text state function. -func lexInsideString(l *lexer) stateFn { - if l.acceptRunUntil('"') { - l.emit(stringValue) - } - - return lexLine -} - -func lexNumber(l *lexer) stateFn { - acceptance := decimalNumbers - if l.accept("xX") { - acceptance = hexNumbers - } - l.acceptRun(acceptance) - - l.emit(number) - - return lexLine -} - -func lexElement(l *lexer) stateFn { - l.acceptRun(alpha + "_" + decimalNumbers) - - if l.peek() == ':' { - l.emit(labelDef) - - l.accept(":") - l.ignore() - } else { - l.emit(element) - } - return lexLine -} - -func isLetter(t rune) bool { - return unicode.IsLetter(t) -} - -func isSpace(t rune) bool { - return unicode.IsSpace(t) -} - -func isNumber(t rune) bool { - return unicode.IsNumber(t) -} diff --git a/core/asm/tokentype_string.go b/core/asm/tokentype_string.go deleted file mode 100644 index ade76aa360..0000000000 --- a/core/asm/tokentype_string.go +++ /dev/null @@ -1,31 +0,0 @@ -// Code generated by "stringer -type tokenType"; DO NOT EDIT. - -package asm - -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[eof-0] - _ = x[lineStart-1] - _ = x[lineEnd-2] - _ = x[invalidStatement-3] - _ = x[element-4] - _ = x[label-5] - _ = x[labelDef-6] - _ = x[number-7] - _ = x[stringValue-8] -} - -const _tokenType_name = "eoflineStartlineEndinvalidStatementelementlabellabelDefnumberstringValue" - -var _tokenType_index = [...]uint8{0, 3, 12, 19, 35, 42, 47, 55, 61, 72} - -func (i tokenType) String() string { - if i < 0 || i >= tokenType(len(_tokenType_index)-1) { - return "tokenType(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _tokenType_name[_tokenType_index[i]:_tokenType_index[i+1]] -} diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index bde230b6da..d75a5b0459 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -29,7 +29,6 @@ import ( "github.com/ethereum/go-ethereum/common" "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/state" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" @@ -508,21 +507,9 @@ func TestEip2929Cases(t *testing.T) { t.Skip("Test only useful for generating documentation") id := 1 prettyPrint := func(comment string, code []byte) { - instrs := make([]string, 0) - it := asm.NewInstructionIterator(code) - for it.Next() { - if it.Arg() != nil && 0 < len(it.Arg()) { - instrs = append(instrs, fmt.Sprintf("%v %#x", it.Op(), it.Arg())) - } else { - instrs = append(instrs, fmt.Sprintf("%v", it.Op())) - } - } - ops := strings.Join(instrs, ", ") fmt.Printf("### Case %d\n\n", id) id++ - fmt.Printf("%v\n\nBytecode: \n```\n%#x\n```\nOperations: \n```\n%v\n```\n\n", - comment, - code, ops) + fmt.Printf("%v\n\nBytecode: \n```\n%#x\n```\n", comment, code) Execute(code, nil, &Config{ EVMConfig: vm.Config{ Tracer: logger.NewMarkdownLogger(nil, os.Stdout).Hooks(), From 67cd4cd5a15990873d60200bffd85a8bf9abba8b Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 20 Feb 2025 10:27:13 +0100 Subject: [PATCH 131/940] .github: downgrade go for lint step (#31217) --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 90449ef30d..4da92f2431 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.24.0 + go-version: 1.23.0 cache: false - name: Run linters From c8781be76277e5ef8c8d6933aeb21ea6f34013bd Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Thu, 20 Feb 2025 13:11:48 +0100 Subject: [PATCH 132/940] core/txpool/legacypool: add setCodeTx reorg test (#31206) This PR adds a test that makes sure that a node can send multiple transactions again once a authorization is removed --- core/txpool/legacypool/legacypool_test.go | 63 +++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index da28e8a75b..7e35e0cc60 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -149,6 +149,10 @@ func pricedSetCodeTx(nonce uint64, gaslimit uint64, gasFee, tip *uint256.Int, ke }) authList = append(authList, auth) } + return pricedSetCodeTxWithAuth(nonce, gaslimit, gasFee, tip, key, authList) +} + +func pricedSetCodeTxWithAuth(nonce uint64, gaslimit uint64, gasFee, tip *uint256.Int, key *ecdsa.PrivateKey, authList []types.SetCodeAuthorization) *types.Transaction { return types.MustSignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.SetCodeTx{ ChainID: uint256.MustFromBig(params.TestChainConfig.ChainID), Nonce: nonce, @@ -2393,6 +2397,65 @@ func TestSetCodeTransactions(t *testing.T) { } } +func TestSetCodeTransactionsReorg(t *testing.T) { + t.Parallel() + + // Create the pool to test the status retrievals with + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed)) + + pool := New(testTxPoolConfig, blockchain) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + defer pool.Close() + + // Create the test accounts + var ( + keyA, _ = crypto.GenerateKey() + addrA = crypto.PubkeyToAddress(keyA.PublicKey) + ) + testAddBalance(pool, addrA, big.NewInt(params.Ether)) + // Send an authorization for 0x42 + var authList []types.SetCodeAuthorization + auth, _ := types.SignSetCode(keyA, types.SetCodeAuthorization{ + ChainID: *uint256.MustFromBig(params.TestChainConfig.ChainID), + Address: common.Address{0x42}, + Nonce: 0, + }) + authList = append(authList, auth) + if err := pool.addRemoteSync(pricedSetCodeTxWithAuth(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, authList)); err != nil { + t.Fatalf("failed to add with remote setcode transaction: %v", err) + } + // Simulate the chain moving + blockchain.statedb.SetNonce(addrA, 1, tracing.NonceChangeAuthorization) + blockchain.statedb.SetCode(addrA, types.AddressToDelegation(auth.Address)) + <-pool.requestReset(nil, nil) + // Set an authorization for 0x00 + auth, _ = types.SignSetCode(keyA, types.SetCodeAuthorization{ + ChainID: *uint256.MustFromBig(params.TestChainConfig.ChainID), + Address: common.Address{}, + Nonce: 0, + }) + authList = append(authList, auth) + if err := pool.addRemoteSync(pricedSetCodeTxWithAuth(1, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, authList)); err != nil { + t.Fatalf("failed to add with remote setcode transaction: %v", err) + } + // Try to add a transactions in + if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { + t.Fatalf("unexpected error %v, expecting %v", err, txpool.ErrAccountLimitExceeded) + } + // Simulate the chain moving + blockchain.statedb.SetNonce(addrA, 2, tracing.NonceChangeAuthorization) + blockchain.statedb.SetCode(addrA, nil) + <-pool.requestReset(nil, nil) + // Now send two transactions from addrA + if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); err != nil { + t.Fatalf("failed to added single transaction: %v", err) + } + if err := pool.addRemoteSync(pricedTransaction(3, 100000, big.NewInt(1000), keyA)); err != nil { + t.Fatalf("failed to added single transaction: %v", err) + } +} + // Benchmarks the speed of validating the contents of the pending queue of the // transaction pool. func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) } From b1f88ef9bd5d5eed77df05486ebf9c3e7c99a299 Mon Sep 17 00:00:00 2001 From: nethoxa <135072738+nethoxa@users.noreply.github.com> Date: Thu, 20 Feb 2025 14:30:55 +0100 Subject: [PATCH 133/940] internal/ethapi: handle prague system calls in eth_simulate (#31176) eth_simulate was not processing prague system calls for history contract and EL requests resulting in inaccurate stateRoot and requestsRoot fields in the block. --- internal/ethapi/simulate.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index c461b1f0a1..227fd0e8e5 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -194,6 +194,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if precompiles != nil { evm.SetPrecompiles(precompiles) } + if sim.chainConfig.IsPrague(header.Number, header.Time) || sim.chainConfig.IsVerkle(header.Number, header.Time) { + core.ProcessParentBlockHash(header.ParentHash, evm) + } + var allLogs []*types.Log for i, call := range block.Calls { if err := ctx.Err(); err != nil { return nil, nil, err @@ -234,9 +238,23 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, } } else { callRes.Status = hexutil.Uint64(types.ReceiptStatusSuccessful) + allLogs = append(allLogs, callRes.Logs...) } callResults[i] = callRes } + var requests [][]byte + // Process EIP-7685 requests + if sim.chainConfig.IsPrague(header.Number, header.Time) { + requests = [][]byte{} + // EIP-6110 + if err := core.ParseDepositLogs(&requests, allLogs, sim.chainConfig); err != nil { + return nil, nil, err + } + // EIP-7002 + core.ProcessWithdrawalQueue(&requests, evm) + // EIP-7251 + core.ProcessConsolidationQueue(&requests, evm) + } header.Root = sim.state.IntermediateRoot(true) header.GasUsed = gasUsed if sim.chainConfig.IsCancun(header.Number, header.Time) { @@ -246,6 +264,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if sim.chainConfig.IsShanghai(header.Number, header.Time) { withdrawals = make([]*types.Withdrawal, 0) } + if requests != nil { + reqHash := types.CalcRequestsHash(requests) + header.RequestsHash = &reqHash + } b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil)) repairLogs(callResults, b.Hash()) return b, callResults, nil From dcc0b3704d5f01a6e721c4f37ba068d3b41c64ec Mon Sep 17 00:00:00 2001 From: Delweng Date: Thu, 20 Feb 2025 22:04:35 +0800 Subject: [PATCH 134/940] eth/tracers: refactor block context in test runner (#29450) This commit contains a minor refactoring of the block context used within the test runners. --------- Signed-off-by: jsvisa --- .../internal/tracetest/calltrace_test.go | 7 ++----- .../internal/tracetest/flat_calltrace_test.go | 7 ++----- eth/tracers/internal/tracetest/makeTest.js | 17 ++++++++++----- .../internal/tracetest/prestate_test.go | 21 ++++++++----------- .../testdata/call_tracer/blob_tx.json | 2 -- .../testdata/prestate_tracer/blob_tx.json | 2 -- .../prestate_tracer/create_create.json | 2 -- eth/tracers/internal/tracetest/util.go | 14 +++++++++++-- 8 files changed, 37 insertions(+), 35 deletions(-) diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index 999ab211c0..b2486661e4 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -65,11 +65,8 @@ type callTrace struct { // callTracerTest defines a single test to check the call tracer against. type callTracerTest struct { - Genesis *core.Genesis `json:"genesis"` - Context *callContext `json:"context"` - Input string `json:"input"` - TracerConfig json.RawMessage `json:"tracerConfig"` - Result *callTrace `json:"result"` + tracerTestEnv + Result *callTrace `json:"result"` } // Iterates over all the input-output datasets in the tracer test harness and diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go index 4390a62b4b..d1fa44e9d8 100644 --- a/eth/tracers/internal/tracetest/flat_calltrace_test.go +++ b/eth/tracers/internal/tracetest/flat_calltrace_test.go @@ -77,11 +77,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"` - Input string `json:"input"` - TracerConfig json.RawMessage `json:"tracerConfig"` - Result []flatCallTrace `json:"result"` + tracerTestEnv + Result []flatCallTrace `json:"result"` } func flatCallTracerTestRunner(tracerName string, filename string, dirPath string, t testing.TB) error { diff --git a/eth/tracers/internal/tracetest/makeTest.js b/eth/tracers/internal/tracetest/makeTest.js index 826c91f639..cb41ebde0c 100644 --- a/eth/tracers/internal/tracetest/makeTest.js +++ b/eth/tracers/internal/tracetest/makeTest.js @@ -31,6 +31,9 @@ var makeTest = function(tx, traceConfig) { delete genesis.transactions; delete genesis.transactionsRoot; delete genesis.uncles; + delete genesis.withdrawals; + delete genesis.withdrawalsRoot; + delete genesis.baseFeePerGas; genesis.gasLimit = genesis.gasLimit.toString(); genesis.number = genesis.number.toString(); @@ -60,11 +63,15 @@ var makeTest = function(tx, traceConfig) { context.baseFeePerGas = block.baseFeePerGas.toString(); } - console.log(JSON.stringify({ + var data = { genesis: genesis, context: context, - input: eth.getRawTransaction(tx), - result: result, - tracerConfig: traceConfig.tracerConfig, - }, null, 2)); + input: eth.getRawTransaction(tx), + result: result, + }; + if (traceConfig && traceConfig.tracerConfig) { + data.tracerConfig = traceConfig.tracerConfig; + } + + console.log(JSON.stringify(data, null, 2)); } diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go index 680645970a..29c2834ba2 100644 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ b/eth/tracers/internal/tracetest/prestate_test.go @@ -43,28 +43,25 @@ type account struct { Storage map[common.Hash]common.Hash `json:"storage"` } -// testcase defines a single test to check the stateDiff tracer against. -type testcase struct { - Genesis *core.Genesis `json:"genesis"` - Context *callContext `json:"context"` - Input string `json:"input"` - TracerConfig json.RawMessage `json:"tracerConfig"` - Result interface{} `json:"result"` +// prestateTracerTest defines a single test to check the stateDiff tracer against. +type prestateTracerTest struct { + tracerTestEnv + Result interface{} `json:"result"` } func TestPrestateTracerLegacy(t *testing.T) { - testPrestateDiffTracer("prestateTracerLegacy", "prestate_tracer_legacy", t) + testPrestateTracer("prestateTracerLegacy", "prestate_tracer_legacy", t) } func TestPrestateTracer(t *testing.T) { - testPrestateDiffTracer("prestateTracer", "prestate_tracer", t) + testPrestateTracer("prestateTracer", "prestate_tracer", t) } func TestPrestateWithDiffModeTracer(t *testing.T) { - testPrestateDiffTracer("prestateTracer", "prestate_tracer_with_diff_mode", t) + testPrestateTracer("prestateTracer", "prestate_tracer_with_diff_mode", t) } -func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { +func testPrestateTracer(tracerName string, dirPath string, t *testing.T) { files, err := os.ReadDir(filepath.Join("testdata", dirPath)) if err != nil { t.Fatalf("failed to retrieve tracer test suite: %v", err) @@ -77,7 +74,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { t.Parallel() var ( - test = new(testcase) + test = new(prestateTracerTest) tx = new(types.Transaction) ) // Call tracer test found, read if from disk diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json b/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json index f8e08532a4..f59285cfba 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json @@ -14,8 +14,6 @@ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "stateRoot": "0x577f42ab21ccfd946511c57869ace0bdf7c217c36f02b7cd3459df0ed1cffc1a", "timestamp": "1709626771", - "withdrawals": [], - "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "alloc": { "0x0000000000000000000000000000000000000000": { "balance": "0x272e0528" 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 9f452ca5bd..50f3209735 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/blob_tx.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/blob_tx.json @@ -14,8 +14,6 @@ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "stateRoot": "0x577f42ab21ccfd946511c57869ace0bdf7c217c36f02b7cd3459df0ed1cffc1a", "timestamp": "1709626771", - "withdrawals": [], - "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "alloc": { "0x0000000000000000000000000000000000000000": { "balance": "0x272e0528" diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_create.json index 489a1ae6b5..dd4fca1ecc 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_create.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_create.json @@ -11,8 +11,6 @@ "number": "1", "stateRoot": "0xd2ebe0a7f3572ffe3e5b4c78147376d3fca767f236e4dd23f9151acfec7cb0d1", "timestamp": "1699617692", - "withdrawals": [], - "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "alloc": { "0x0000000000000000000000000000000000000000": { "balance": "0x5208" diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go index 85727e29ed..04fff12fe5 100644 --- a/eth/tracers/internal/tracetest/util.go +++ b/eth/tracers/internal/tracetest/util.go @@ -17,6 +17,7 @@ package tracetest import ( + "encoding/json" "math/big" "strings" "unicode" @@ -42,7 +43,8 @@ func camel(str string) string { return strings.Join(pieces, "") } -type callContext struct { +// traceContext defines a context used to construct the block context +type traceContext struct { Number math.HexOrDecimal64 `json:"number"` Difficulty *math.HexOrDecimal256 `json:"difficulty"` Time math.HexOrDecimal64 `json:"timestamp"` @@ -51,7 +53,7 @@ type callContext struct { BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` } -func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext { +func (c *traceContext) toBlockContext(genesis *core.Genesis) vm.BlockContext { context := vm.BlockContext{ CanTransfer: core.CanTransfer, Transfer: core.Transfer, @@ -77,3 +79,11 @@ func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext { } return context } + +// tracerTestEnv defines a tracer test required fields +type tracerTestEnv struct { + Genesis *core.Genesis `json:"genesis"` + Context *traceContext `json:"context"` + Input string `json:"input"` + TracerConfig json.RawMessage `json:"tracerConfig"` +} From 301a868d28bd0a177f06ce9e74f673894bd7101e Mon Sep 17 00:00:00 2001 From: Martin HS Date: Thu, 20 Feb 2025 18:46:25 +0100 Subject: [PATCH 135/940] oss-fuzz: remove deprecated targets (#31224) Fixes https://github.com/ethereum/go-ethereum/issues/31223 (sorry, I thought the fork fork would be created on my repo, not upstream, when I used the GH editor) --- oss-fuzz.sh | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/oss-fuzz.sh b/oss-fuzz.sh index 1f222c433b..4db245a781 100644 --- a/oss-fuzz.sh +++ b/oss-fuzz.sh @@ -160,14 +160,6 @@ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ FuzzG1Add fuzz_g1_add\ $repo/tests/fuzzers/bls12381/bls12381_test.go -compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ - FuzzCrossG1Mul fuzz_cross_g1_mul\ - $repo/tests/fuzzers/bls12381/bls12381_test.go - -compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ - FuzzG1Mul fuzz_g1_mul\ - $repo/tests/fuzzers/bls12381/bls12381_test.go - compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ FuzzG1MultiExp fuzz_g1_multiexp \ $repo/tests/fuzzers/bls12381/bls12381_test.go @@ -176,14 +168,6 @@ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ FuzzG2Add fuzz_g2_add \ $repo/tests/fuzzers/bls12381/bls12381_test.go -compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ - FuzzCrossG2Mul fuzz_cross_g2_mul\ - $repo/tests/fuzzers/bls12381/bls12381_test.go - -compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ - FuzzG2Mul fuzz_g2_mul\ - $repo/tests/fuzzers/bls12381/bls12381_test.go - compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ FuzzG2MultiExp fuzz_g2_multiexp \ $repo/tests/fuzzers/bls12381/bls12381_test.go From 2a81bbaa4f0988f947dfb1400c3cf707b9605ead Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 21 Feb 2025 03:42:54 +0100 Subject: [PATCH 136/940] p2p/nat: remove test with default servers (#31225) The test occasionally fails when network connectivity is bad or if it hits the wrong server. We usually don't add tests with external network dependency so I'm removing them. Fixes #31220 --- p2p/nat/stun_test.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/p2p/nat/stun_test.go b/p2p/nat/stun_test.go index b5f429986c..6bcaf45f9f 100644 --- a/p2p/nat/stun_test.go +++ b/p2p/nat/stun_test.go @@ -18,17 +18,8 @@ package nat import ( "testing" - - "github.com/stretchr/testify/assert" ) -func TestNatStun(t *testing.T) { - nat, err := newSTUN("") - assert.NoError(t, err) - _, err = nat.ExternalIP() - assert.NoError(t, err) -} - func TestUnreachedNatServer(t *testing.T) { stun := &stun{ serverList: []string{"198.51.100.2:1234", "198.51.100.5"}, From 53e8e1fdf2d41a93cd3355ccdad472cfea27289e Mon Sep 17 00:00:00 2001 From: rrhlrmrr <39875249+rrhlrmrr@users.noreply.github.com> Date: Fri, 21 Feb 2025 14:45:29 +0900 Subject: [PATCH 137/940] core/types: remove unneeded todo marker (#31179) --- core/types/transaction_marshalling.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index 1bbb97a3ec..f76d4b92e9 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -514,6 +514,5 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { // Now set the inner transaction. tx.setDecoded(inner, 0) - // TODO: check hash here? return nil } From 5552ada4861717af05a9d1925983b6e04552d5cd Mon Sep 17 00:00:00 2001 From: jwasinger Date: Fri, 21 Feb 2025 00:48:24 -0800 Subject: [PATCH 138/940] signer/core: fix encoding of `bytes` nested within array (#31049) Fixes an incorrect encoding of recursive bytes types. closes https://github.com/ethereum/go-ethereum/issues/30979 --- signer/core/apitypes/types.go | 11 +++++++- signer/core/signed_data_test.go | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go index b56931c1d1..b8b96bef92 100644 --- a/signer/core/apitypes/types.go +++ b/signer/core/apitypes/types.go @@ -501,7 +501,16 @@ func (typedData *TypedData) encodeArrayValue(encValue interface{}, encType strin for _, item := range arrayValue { if reflect.TypeOf(item).Kind() == reflect.Slice || reflect.TypeOf(item).Kind() == reflect.Array { - encodedData, err := typedData.encodeArrayValue(item, parsedType, depth+1) + var ( + encodedData hexutil.Bytes + err error + ) + if reflect.TypeOf(item).Elem().Kind() == reflect.Uint8 { + // the item type is bytes. encode the bytes array directly instead of recursing. + encodedData, err = typedData.EncodePrimitiveValue(parsedType, item, depth+1) + } else { + encodedData, err = typedData.encodeArrayValue(item, parsedType, depth+1) + } if err != nil { return nil, err } diff --git a/signer/core/signed_data_test.go b/signer/core/signed_data_test.go index d0637010ba..b6c080736c 100644 --- a/signer/core/signed_data_test.go +++ b/signer/core/signed_data_test.go @@ -1014,3 +1014,49 @@ func TestComplexTypedDataWithLowercaseReftype(t *testing.T) { t.Fatalf("Error, got %x, wanted %x", sighash, expSigHash) } } + +var recursiveBytesTypesStandard = apitypes.Types{ + "EIP712Domain": { + { + Name: "name", + Type: "string", + }, + { + Name: "version", + Type: "string", + }, + { + Name: "chainId", + Type: "uint256", + }, + { + Name: "verifyingContract", + Type: "address", + }, + }, + "Val": { + { + Name: "field", + Type: "bytes[][]", + }, + }, +} + +var recursiveBytesMessageStandard = map[string]interface{}{ + "field": [][][]byte{{{1}, {2}}, {{3}, {4}}}, +} + +var recursiveBytesTypedData = apitypes.TypedData{ + Types: recursiveBytesTypesStandard, + PrimaryType: "Val", + Domain: domainStandard, + Message: recursiveBytesMessageStandard, +} + +func TestEncodeDataRecursiveBytes(t *testing.T) { + typedData := recursiveBytesTypedData + _, err := typedData.EncodeData(typedData.PrimaryType, typedData.Message, 0) + if err != nil { + t.Fatalf("got err %v", err) + } +} From 8a14362bf7489fbfa22b6b261e336156f625bdbb Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 21 Feb 2025 09:52:55 +0100 Subject: [PATCH 139/940] internal/ethapi: fix prev hashes in eth_simulate (#31122) Shout-out to @Gabriel-Trintinalia for discovering this issue. The gist of it as follows: When processing a block, we should provide the parent block as well as the last 256 block hashes. Some of these parents data (specifically the hash) was incorrect because even though during the processing of the parent block we have updated the header, that header was not updating the TransactionsRoot and ReceiptsRoot fields (types.NewBlock makes a new copy of the header and changes it only on that instance). --------- Co-authored-by: lightclient --- internal/ethapi/api.go | 2 +- internal/ethapi/api_test.go | 96 +++++++++++++++++++++++++++++++++++++ internal/ethapi/simulate.go | 26 +++++++--- 3 files changed, 116 insertions(+), 8 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 92249f7829..f3975d35a0 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -775,7 +775,7 @@ func (api *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockN // // 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) { +func (api *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrOrHash *rpc.BlockNumberOrHash) ([]*simBlockResult, error) { if len(opts.BlockStateCalls) == 0 { return nil, &invalidParamsError{message: "empty input"} } else if len(opts.BlockStateCalls) > maxSimulateBlocks { diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index f00022e3de..d70cb90ec9 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -24,6 +24,7 @@ import ( "encoding/json" "errors" "fmt" + "math" "math/big" "os" "path/filepath" @@ -2309,6 +2310,101 @@ func TestSimulateV1(t *testing.T) { } } +func TestSimulateV1ChainLinkage(t *testing.T) { + var ( + acc = newTestAccount() + sender = acc.addr + contractAddr = common.Address{0xaa, 0xaa} + recipient = common.Address{0xbb, 0xbb} + gspec = &core.Genesis{ + Config: params.MergedTestChainConfig, + Alloc: types.GenesisAlloc{ + sender: {Balance: big.NewInt(params.Ether)}, + contractAddr: {Code: common.Hex2Bytes("5f35405f8114600f575f5260205ff35b5f80fd")}, + }, + } + signer = types.LatestSigner(params.MergedTestChainConfig) + ) + backend := newTestBackend(t, 1, gspec, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) { + tx := types.MustSignNewTx(acc.key, signer, &types.LegacyTx{ + Nonce: uint64(i), + GasPrice: b.BaseFee(), + Gas: params.TxGas, + To: &recipient, + Value: big.NewInt(500), + }) + b.AddTx(tx) + }) + + ctx := context.Background() + stateDB, baseHeader, err := backend.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)) + if err != nil { + t.Fatalf("failed to get state and header: %v", err) + } + + sim := &simulator{ + b: backend, + state: stateDB, + base: baseHeader, + chainConfig: backend.ChainConfig(), + gp: new(core.GasPool).AddGas(math.MaxUint64), + traceTransfers: false, + validate: false, + fullTx: false, + } + + var ( + call1 = TransactionArgs{ + From: &sender, + To: &recipient, + Value: (*hexutil.Big)(big.NewInt(1000)), + } + call2 = TransactionArgs{ + From: &sender, + To: &recipient, + Value: (*hexutil.Big)(big.NewInt(2000)), + } + call3a = TransactionArgs{ + From: &sender, + To: &contractAddr, + Input: uint256ToBytes(uint256.NewInt(baseHeader.Number.Uint64() + 1)), + Gas: newUint64(1000000), + } + call3b = TransactionArgs{ + From: &sender, + To: &contractAddr, + Input: uint256ToBytes(uint256.NewInt(baseHeader.Number.Uint64() + 2)), + Gas: newUint64(1000000), + } + blocks = []simBlock{ + {Calls: []TransactionArgs{call1}}, + {Calls: []TransactionArgs{call2}}, + {Calls: []TransactionArgs{call3a, call3b}}, + } + ) + + results, err := sim.execute(ctx, blocks) + if err != nil { + t.Fatalf("simulation execution failed: %v", err) + } + require.Equal(t, 3, len(results), "expected 3 simulated blocks") + + // Check linkages of simulated blocks: + // Verify that block2's parent hash equals block1's hash. + block1 := results[0].Block + block2 := results[1].Block + block3 := results[2].Block + require.Equal(t, block1.ParentHash(), baseHeader.Hash(), "parent hash of block1 should equal hash of base block") + require.Equal(t, block1.Hash(), block2.Header().ParentHash, "parent hash of block2 should equal hash of block1") + require.Equal(t, block2.Hash(), block3.Header().ParentHash, "parent hash of block3 should equal hash of block2") + + // In block3, two calls were executed to our contract. + // The first call in block3 should return the blockhash for block1 (i.e. block1.Hash()), + // whereas the second call should return the blockhash for block2 (i.e. block2.Hash()). + require.Equal(t, block1.Hash().Bytes(), []byte(results[2].Calls[0].ReturnValue), "returned blockhash for block1 does not match") + require.Equal(t, block2.Hash().Bytes(), []byte(results[2].Calls[1].ReturnValue), "returned blockhash for block2 does not match") +} + func TestSignTransaction(t *testing.T) { t.Parallel() // Initialize test accounts diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 227fd0e8e5..ac76372424 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -73,6 +73,20 @@ func (r *simCallResult) MarshalJSON() ([]byte, error) { return json.Marshal((*callResultAlias)(r)) } +// simBlockResult is the result of a simulated block. +type simBlockResult struct { + fullTx bool + chainConfig *params.ChainConfig + Block *types.Block + Calls []simCallResult +} + +func (r *simBlockResult) MarshalJSON() ([]byte, error) { + blockData := RPCMarshalBlock(r.Block, true, r.fullTx, r.chainConfig) + blockData["calls"] = r.Calls + return json.Marshal(blockData) +} + // simOpts are the inputs to eth_simulateV1. type simOpts struct { BlockStateCalls []simBlock @@ -95,7 +109,7 @@ type simulator struct { } // execute runs the simulation of a series of blocks. -func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[string]interface{}, error) { +func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]*simBlockResult, error) { if err := ctx.Err(); err != nil { return nil, err } @@ -123,7 +137,7 @@ func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[str return nil, err } var ( - results = make([]map[string]interface{}, len(blocks)) + results = make([]*simBlockResult, len(blocks)) parent = sim.base ) for bi, block := range blocks { @@ -131,11 +145,9 @@ func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[str if err != nil { return nil, err } - enc := RPCMarshalBlock(result, true, sim.fullTx, sim.chainConfig) - enc["calls"] = callResults - results[bi] = enc - - parent = headers[bi] + headers[bi] = result.Header() + results[bi] = &simBlockResult{fullTx: sim.fullTx, chainConfig: sim.chainConfig, Block: result, Calls: callResults} + parent = result.Header() } return results, nil } From cb9653d253be1ac2f04f10136655165bd8af2276 Mon Sep 17 00:00:00 2001 From: Maximilian Hubert <64627729+gap-editor@users.noreply.github.com> Date: Fri, 21 Feb 2025 11:45:02 +0100 Subject: [PATCH 140/940] cmd/clef: improve documentation in readme (#31218) Fixed broken or outdated links and improved documentation formatting to ensure consistency and correct references. --------- Co-authored-by: Sina M <1591639+s1na@users.noreply.github.com> --- cmd/clef/intapi_changelog.md | 2 +- signer/core/testdata/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/clef/intapi_changelog.md b/cmd/clef/intapi_changelog.md index eaeb2e6862..85d04f6d0e 100644 --- a/cmd/clef/intapi_changelog.md +++ b/cmd/clef/intapi_changelog.md @@ -94,7 +94,7 @@ type Account struct { > Notifications are not confirmable by definition, since they do not have a Response object to be returned. As such, the Client would not be aware of any errors (like e.g. "Invalid params","Internal error" ### 3.1.0 -* Add `ContentType` `string` to `SignDataRequest` to accommodate the latest EIP-191 and EIP-712 implementations. +* Add `ContentType` `string` to `SignDataRequest` to accommodate the latest [EIP-191](https://eips.ethereum.org/EIPS/eip-191) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) implementations. ### 3.0.0 diff --git a/signer/core/testdata/README.md b/signer/core/testdata/README.md index f425450a06..85aa70c04c 100644 --- a/signer/core/testdata/README.md +++ b/signer/core/testdata/README.md @@ -1,5 +1,5 @@ -### EIP 712 tests +### EIP-712 tests -These tests are json files which are converted into eip-712 typed data. +These tests are json files which are converted into [EIP-712](https://eips.ethereum.org/EIPS/eip-712) typed data. All files are expected to be proper json, and tests will fail if they are not. Files that begin with `expfail' are expected to not pass the hashstruct construction. From d103f179b917b06bba38331627674170ed24c2a5 Mon Sep 17 00:00:00 2001 From: levisyin Date: Fri, 21 Feb 2025 20:36:18 +0800 Subject: [PATCH 141/940] build: replace `tenv` linter with `usetesting` (#31172) --- .golangci.yml | 2 +- README.md | 2 +- cmd/clef/run_test.go | 8 +------- cmd/utils/history_test.go | 6 +----- core/txpool/blobpool/blobpool_test.go | 19 +++++++------------ crypto/crypto_test.go | 4 ++-- crypto/signify/signify_test.go | 16 ++++------------ internal/era/era_test.go | 3 ++- node/config_test.go | 3 +-- 9 files changed, 20 insertions(+), 43 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b63251055b..a702da524b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -25,7 +25,7 @@ linters: - gocheckcompilerdirectives - reassign - mirror - - tenv + - usetesting ### linters we tried and will not be using: ### # - structcheck # lots of false positives diff --git a/README.md b/README.md index fb82459d34..9ccfe933aa 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ archives are published at https://geth.ethereum.org/downloads/. 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.22 or later) and a C compiler. You can install +Building `geth` requires both a Go (version 1.23 or later) and a C compiler. You can install them using your favourite package manager. Once the dependencies are installed, run ```shell diff --git a/cmd/clef/run_test.go b/cmd/clef/run_test.go index 5fa6e02e14..d404457ba2 100644 --- a/cmd/clef/run_test.go +++ b/cmd/clef/run_test.go @@ -57,13 +57,7 @@ func TestMain(m *testing.M) { // This method creates a temporary keystore folder which will be removed after // the test exits. func runClef(t *testing.T, args ...string) *testproc { - ddir, err := os.MkdirTemp("", "cleftest-*") - if err != nil { - return nil - } - t.Cleanup(func() { - os.RemoveAll(ddir) - }) + ddir := t.TempDir() return runWithKeystore(t, ddir, args...) } diff --git a/cmd/utils/history_test.go b/cmd/utils/history_test.go index 07cf71234e..8654c454f9 100644 --- a/cmd/utils/history_test.go +++ b/cmd/utils/history_test.go @@ -87,11 +87,7 @@ func TestHistoryImportAndExport(t *testing.T) { } // Make temp directory for era files. - dir, err := os.MkdirTemp("", "history-export-test") - if err != nil { - t.Fatalf("error creating temp test directory: %v", err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() // Export history to temp directory. if err := ExportHistory(chain, dir, 0, count, step); err != nil { diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 8589e5c01d..d9137cb679 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -21,6 +21,7 @@ import ( "crypto/ecdsa" "crypto/sha256" "errors" + "fmt" "math" "math/big" "os" @@ -452,8 +453,7 @@ func TestOpenDrops(t *testing.T) { //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) // Create a temporary folder for the persistent backend - storage, _ := os.MkdirTemp("", "blobpool-") - defer os.RemoveAll(storage) + storage := t.TempDir() os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) @@ -775,8 +775,7 @@ func TestOpenIndex(t *testing.T) { //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) // Create a temporary folder for the persistent backend - storage, _ := os.MkdirTemp("", "blobpool-") - defer os.RemoveAll(storage) + storage := t.TempDir() os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) @@ -864,8 +863,7 @@ func TestOpenHeap(t *testing.T) { //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) // Create a temporary folder for the persistent backend - storage, _ := os.MkdirTemp("", "blobpool-") - defer os.RemoveAll(storage) + storage := t.TempDir() os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) @@ -951,8 +949,7 @@ func TestOpenCap(t *testing.T) { //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) // Create a temporary folder for the persistent backend - storage, _ := os.MkdirTemp("", "blobpool-") - defer os.RemoveAll(storage) + storage := t.TempDir() os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) @@ -1041,8 +1038,7 @@ func TestChangingSlotterSize(t *testing.T) { //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) // Create a temporary folder for the persistent backend - storage, _ := os.MkdirTemp("", "blobpool-") - defer os.RemoveAll(storage) + storage := t.TempDir() os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(6), nil) @@ -1508,8 +1504,7 @@ func TestAdd(t *testing.T) { } for i, tt := range tests { // Create a temporary folder for the persistent backend - storage, _ := os.MkdirTemp("", "blobpool-") - defer os.RemoveAll(storage) // late defer, still ok + storage := filepath.Join(t.TempDir(), fmt.Sprintf("test-%d", i)) os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index da123cf980..5b0c9c0533 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -181,7 +181,7 @@ func TestLoadECDSA(t *testing.T) { } for _, test := range tests { - f, err := os.CreateTemp("", "loadecdsa_test.*.txt") + f, err := os.CreateTemp(t.TempDir(), "loadecdsa_test.*.txt") if err != nil { t.Fatal(err) } @@ -202,7 +202,7 @@ func TestLoadECDSA(t *testing.T) { } func TestSaveECDSA(t *testing.T) { - f, err := os.CreateTemp("", "saveecdsa_test.*.txt") + f, err := os.CreateTemp(t.TempDir(), "saveecdsa_test.*.txt") if err != nil { t.Fatal(err) } diff --git a/crypto/signify/signify_test.go b/crypto/signify/signify_test.go index 9bac2c825f..ce41c1bd04 100644 --- a/crypto/signify/signify_test.go +++ b/crypto/signify/signify_test.go @@ -33,11 +33,10 @@ var ( ) func TestSignify(t *testing.T) { - tmpFile, err := os.CreateTemp("", "") + tmpFile, err := os.CreateTemp(t.TempDir(), "") if err != nil { t.Fatal(err) } - defer os.Remove(tmpFile.Name()) defer tmpFile.Close() data := make([]byte, 1024) @@ -52,7 +51,6 @@ func TestSignify(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(tmpFile.Name() + ".sig") // Verify the signature using a golang library sig, err := minisign.NewSignatureFromFile(tmpFile.Name() + ".sig") @@ -75,11 +73,10 @@ func TestSignify(t *testing.T) { } func TestSignifyTrustedCommentTooManyLines(t *testing.T) { - tmpFile, err := os.CreateTemp("", "") + tmpFile, err := os.CreateTemp(t.TempDir(), "") if err != nil { t.Fatal(err) } - defer os.Remove(tmpFile.Name()) defer tmpFile.Close() data := make([]byte, 1024) @@ -94,15 +91,13 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) { if err == nil || err.Error() == "" { t.Fatalf("should have errored on a multi-line trusted comment, got %v", err) } - defer os.Remove(tmpFile.Name() + ".sig") } func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) { - tmpFile, err := os.CreateTemp("", "") + tmpFile, err := os.CreateTemp(t.TempDir(), "") if err != nil { t.Fatal(err) } - defer os.Remove(tmpFile.Name()) defer tmpFile.Close() data := make([]byte, 1024) @@ -117,15 +112,13 @@ func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(tmpFile.Name() + ".sig") } func TestSignifyTrustedCommentEmpty(t *testing.T) { - tmpFile, err := os.CreateTemp("", "") + tmpFile, err := os.CreateTemp(t.TempDir(), "") if err != nil { t.Fatal(err) } - defer os.Remove(tmpFile.Name()) defer tmpFile.Close() data := make([]byte, 1024) @@ -140,5 +133,4 @@ func TestSignifyTrustedCommentEmpty(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(tmpFile.Name() + ".sig") } diff --git a/internal/era/era_test.go b/internal/era/era_test.go index e0bebfa449..72c3b385dd 100644 --- a/internal/era/era_test.go +++ b/internal/era/era_test.go @@ -37,7 +37,7 @@ func TestEra1Builder(t *testing.T) { t.Parallel() // Get temp directory. - f, err := os.CreateTemp("", "era1-test") + f, err := os.CreateTemp(t.TempDir(), "era1-test") if err != nil { t.Fatalf("error creating temp file: %v", err) } @@ -78,6 +78,7 @@ func TestEra1Builder(t *testing.T) { if err != nil { t.Fatalf("failed to open era: %v", err) } + defer e.Close() it, err := NewRawIterator(e) if err != nil { t.Fatalf("failed to make iterator: %s", err) diff --git a/node/config_test.go b/node/config_test.go index e8af8ddcd8..067796d665 100644 --- a/node/config_test.go +++ b/node/config_test.go @@ -53,13 +53,12 @@ func TestDatadirCreation(t *testing.T) { t.Fatalf("freshly created datadir not accessible: %v", err) } // Verify that an impossible datadir fails creation - file, err := os.CreateTemp("", "") + file, err := os.CreateTemp(t.TempDir(), "") if err != nil { t.Fatalf("failed to create temporary file: %v", err) } defer func() { file.Close() - os.Remove(file.Name()) }() dir = filepath.Join(file.Name(), "invalid/path") From 9e6f9246713be4401ab1bae41f0632379f208aec Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Sun, 23 Feb 2025 17:38:32 +0100 Subject: [PATCH 142/940] eth: report error from setupDiscovery at startup (#31233) I ran into this while trying to debug a discv5 thing. I tried to disable DNS discovery using `--discovery.dns=false`, which doesn't work. Annoyingly, geth started anyway and discarded the error silently. I eventually found my mistake, but it took way longer than it should have. Also including a small change to the error message for invalid DNS URLs here. The user actually needs to see the URL to make sense of the error. --- eth/backend.go | 4 +++- p2p/dnsdisc/client.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index fea7e4e1fe..f3a8bf3078 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -368,7 +368,9 @@ func (s *Ethereum) Protocols() []p2p.Protocol { // Start implements node.Lifecycle, starting all internal goroutines needed by the // Ethereum protocol implementation. func (s *Ethereum) Start() error { - s.setupDiscovery() + if err := s.setupDiscovery(); err != nil { + return err + } // Start the bloom bits servicing goroutines s.startBloomHandlers(params.BloomBitsBlocks) diff --git a/p2p/dnsdisc/client.go b/p2p/dnsdisc/client.go index 4f14d860e1..ac369ce07d 100644 --- a/p2p/dnsdisc/client.go +++ b/p2p/dnsdisc/client.go @@ -263,7 +263,7 @@ func (it *randomIterator) Next() bool { func (it *randomIterator) addTree(url string) error { le, err := parseLink(url) if err != nil { - return fmt.Errorf("invalid enrtree URL: %v", err) + return fmt.Errorf("invalid DNS discovery URL %q: %v", url, err) } it.lc.addLink("", le.str) return nil From a0e6381c48e95e42b70f7ac7018f690596de3fc6 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 24 Feb 2025 10:31:33 +0100 Subject: [PATCH 143/940] go.mod: update cloudflare-go (#31240) Updates cloudflare-go from v0.79.0 to v0.114.0 which also gets rid of a dependency to `github.com/hashicorp/go-retryablehttp` which had a security flaw. Diff: https://github.com/cloudflare/cloudflare-go/compare/v0.79.0...v0.114.0 I did a quick sanity check on the diff on all methods that we use and went through the release notes, there was nothing related to how we use it afaict --- go.mod | 16 +++++++--------- go.sum | 35 ++++++++++++++--------------------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index c9f4a4e4ba..f86973e0f6 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/aws/aws-sdk-go-v2/credentials v1.13.43 github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2 github.com/cespare/cp v0.1.0 - github.com/cloudflare/cloudflare-go v0.79.0 + github.com/cloudflare/cloudflare-go v0.114.0 github.com/cockroachdb/pebble v1.1.2 github.com/consensys/gnark-crypto v0.14.0 github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a @@ -58,17 +58,17 @@ require ( github.com/rs/cors v1.7.0 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/status-im/keycard-go v0.2.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/supranational/blst v0.3.14 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/urfave/cli/v2 v2.25.7 + github.com/urfave/cli/v2 v2.27.5 go.uber.org/automaxprocs v1.5.2 golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/sync v0.10.0 golang.org/x/sys v0.29.0 golang.org/x/text v0.21.0 - golang.org/x/time v0.5.0 + golang.org/x/time v0.9.0 golang.org/x/tools v0.29.0 google.golang.org/protobuf v1.34.2 gopkg.in/natefinch/lumberjack.v2 v2.2.1 @@ -98,20 +98,18 @@ require ( github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.22 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.4 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kilic/bls12-381 v0.1.0 // indirect @@ -142,7 +140,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.34.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 9812cbbab5..753ddbc9a5 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,8 @@ github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86c github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.79.0 h1:ErwCYDjFCYppDJlDJ/5WhsSmzegAUe2+K9qgFyQDg3M= -github.com/cloudflare/cloudflare-go v0.79.0/go.mod h1:gkHQf9xEubaQPEuerBuoinR9P8bf8a05Lq0X6WKy1Oc= +github.com/cloudflare/cloudflare-go v0.114.0 h1:ucoti4/7Exo0XQ+rzpn1H+IfVVe++zgiM+tyKtf0HUA= +github.com/cloudflare/cloudflare-go v0.114.0/go.mod h1:O7fYfFfA6wKqKFn2QIR9lhj7FDw6VQCGOY6hd2TBtd0= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 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= @@ -128,8 +128,8 @@ github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= @@ -206,8 +206,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -292,13 +292,6 @@ github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY4 github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= -github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= -github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= @@ -506,8 +499,8 @@ 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.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -516,13 +509,13 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= -github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= +github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -738,8 +731,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= From fbe00050707590f0fc4485c131a59af83f50342c Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 24 Feb 2025 12:23:25 +0100 Subject: [PATCH 144/940] crypto: add comment to FromECDSAPub (#31241) closes https://github.com/ethereum/go-ethereum/issues/26240 --- crypto/crypto.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crypto/crypto.go b/crypto/crypto.go index f9979aa4bb..13e9b134f0 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -184,6 +184,9 @@ func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) { return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil } +// FromECDSAPub converts a secp256k1 public key to bytes. +// Note: it does not use the curve from pub, instead it always +// encodes using secp256k1. func FromECDSAPub(pub *ecdsa.PublicKey) []byte { if pub == nil || pub.X == nil || pub.Y == nil { return nil From 9211a0e3ec778680916d52b6345f23bf262cfc0f Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 25 Feb 2025 05:17:21 +0800 Subject: [PATCH 145/940] core/txpool: move setcode tx validation into legacyPool (#31209) In this PR, several improvements have been made: Authorization-related validations have been moved to legacyPool. Previously, these checks were part of the standard validation procedure, which applies common validations across different pools. Since these checks are specific to SetCode transactions, relocating them to legacyPool is a more reasonable choice. Additionally, authorization conflict checks are now performed regardless of whether the transaction is a replacement or not. --------- Co-authored-by: lightclient --- core/txpool/errors.go | 13 ---- core/txpool/legacypool/legacypool.go | 84 +++++++++++++++-------- core/txpool/legacypool/legacypool_test.go | 24 +++---- core/txpool/validation.go | 19 ++--- 4 files changed, 71 insertions(+), 69 deletions(-) diff --git a/core/txpool/errors.go b/core/txpool/errors.go index 32e49db87c..c38644857e 100644 --- a/core/txpool/errors.go +++ b/core/txpool/errors.go @@ -51,22 +51,9 @@ var ( // making the transaction invalid, rather a DOS protection. ErrOversizedData = errors.New("oversized data") - // ErrFutureReplacePending is returned if a future transaction replaces a pending - // one. Future transactions should only be able to replace other future transactions. - ErrFutureReplacePending = errors.New("future transaction tries to replace pending") - // ErrAlreadyReserved is returned if the sender address has a pending transaction // in a different subpool. For example, this error is returned in response to any // input transaction of non-blob type when a blob transaction from this sender // remains pending (and vice-versa). ErrAlreadyReserved = errors.New("address already reserved") - - // ErrAuthorityReserved is returned if a transaction has an authorization - // signed by an address which already has in-flight transactions known to the - // pool. - ErrAuthorityReserved = errors.New("authority already reserved") - - // ErrAuthorityNonce is returned if a transaction has an authorization with - // a nonce that is not currently valid for the authority. - ErrAuthorityNonceTooLow = errors.New("authority nonce too low") ) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index c7ff954a49..4250283b03 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -61,6 +61,19 @@ var ( // ErrTxPoolOverflow is returned if the transaction pool is full and can't accept // another remote transaction. ErrTxPoolOverflow = errors.New("txpool is full") + + // ErrInflightTxLimitReached is returned when the maximum number of in-flight + // transactions is reached for specific accounts. + ErrInflightTxLimitReached = errors.New("in-flight transaction limit reached for delegated accounts") + + // ErrAuthorityReserved is returned if a transaction has an authorization + // signed by an address which already has in-flight transactions known to the + // pool. + ErrAuthorityReserved = errors.New("authority already reserved") + + // ErrFutureReplacePending is returned if a future transaction replaces a pending + // one. Future transactions should only be able to replace other future transactions. + ErrFutureReplacePending = errors.New("future transaction tries to replace pending") ) var ( @@ -572,22 +585,8 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error { opts := &txpool.ValidationOptionsWithState{ State: pool.currentState, - FirstNonceGap: nil, // Pool allows arbitrary arrival order, don't invalidate nonce gaps - UsedAndLeftSlots: func(addr common.Address) (int, int) { - var have int - if list := pool.pending[addr]; list != nil { - have += list.Len() - } - if list := pool.queue[addr]; list != nil { - have += list.Len() - } - if pool.currentState.GetCodeHash(addr) != types.EmptyCodeHash || len(pool.all.auths[addr]) != 0 { - // Allow at most one in-flight tx for delegated accounts or those with - // a pending authorization. - return have, max(0, 1-have) - } - return have, math.MaxInt - }, + FirstNonceGap: nil, // Pool allows arbitrary arrival order, don't invalidate nonce gaps + UsedAndLeftSlots: nil, // Pool has own mechanism to limit the number of transactions ExistingExpenditure: func(addr common.Address) *big.Int { if list := pool.pending[addr]; list != nil { return list.totalcost.ToBig() @@ -602,22 +601,49 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error { } return nil }, - KnownConflicts: func(from common.Address, auths []common.Address) []common.Address { - var conflicts []common.Address - // Authorities cannot conflict with any pending or queued transactions. - for _, addr := range auths { - if list := pool.pending[addr]; list != nil { - conflicts = append(conflicts, addr) - } else if list := pool.queue[addr]; list != nil { - conflicts = append(conflicts, addr) - } - } - return conflicts - }, } if err := txpool.ValidateTransactionWithState(tx, pool.signer, opts); err != nil { return err } + return pool.validateAuth(tx) +} + +// validateAuth verifies that the transaction complies with code authorization +// restrictions brought by SetCode transaction type. +func (pool *LegacyPool) validateAuth(tx *types.Transaction) error { + from, _ := types.Sender(pool.signer, tx) // validated + + // Allow at most one in-flight tx for delegated accounts or those with a + // pending authorization. + if pool.currentState.GetCodeHash(from) != types.EmptyCodeHash || len(pool.all.auths[from]) != 0 { + var ( + count int + exists bool + ) + pending := pool.pending[from] + if pending != nil { + count += pending.Len() + exists = pending.Contains(tx.Nonce()) + } + queue := pool.queue[from] + if queue != nil { + count += queue.Len() + exists = exists || queue.Contains(tx.Nonce()) + } + // Replace the existing in-flight transaction for delegated accounts + // are still supported + if count >= 1 && !exists { + return ErrInflightTxLimitReached + } + } + // Authorities cannot conflict with any pending or queued transactions. + if auths := tx.SetCodeAuthorities(); len(auths) > 0 { + for _, auth := range auths { + if pool.pending[auth] != nil || pool.queue[auth] != nil { + return ErrAuthorityReserved + } + } + } return nil } @@ -709,7 +735,7 @@ func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) { pool.priced.Put(dropTx) } log.Trace("Discarding future transaction replacing pending tx", "hash", hash) - return false, txpool.ErrFutureReplacePending + return false, ErrFutureReplacePending } } diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 7e35e0cc60..b2a068467f 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -1645,8 +1645,8 @@ func TestUnderpricing(t *testing.T) { t.Fatalf("failed to add well priced transaction: %v", err) } // Ensure that replacing a pending transaction with a future transaction fails - if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != txpool.ErrFutureReplacePending { - t.Fatalf("adding future replace transaction error mismatch: have %v, want %v", err, txpool.ErrFutureReplacePending) + if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != ErrFutureReplacePending { + t.Fatalf("adding future replace transaction error mismatch: have %v, want %v", err, ErrFutureReplacePending) } pending, queued = pool.Stats() if pending != 4 { @@ -2248,12 +2248,12 @@ func TestSetCodeTransactions(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyA)); err != nil { t.Fatalf("%s: failed to add remote transaction: %v", name, err) } - if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { - t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err) + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err) } // Also check gapped transaction. - if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { - t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err) + if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err) } // Replace by fee. if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyA)); err != nil { @@ -2287,8 +2287,8 @@ func TestSetCodeTransactions(t *testing.T) { t.Fatalf("%s: failed to add with pending delegatio: %v", name, err) } // Also check gapped transaction is rejected. - if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { - t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err) + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err) } }, }, @@ -2363,7 +2363,7 @@ func TestSetCodeTransactions(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil { t.Fatalf("%s: failed to added single pooled for account with pending delegation: %v", name, err) } - if err, want := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyC)), txpool.ErrAccountLimitExceeded; !errors.Is(err, want) { + if err, want := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyC)), ErrInflightTxLimitReached; !errors.Is(err, want) { t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err) } }, @@ -2376,7 +2376,7 @@ func TestSetCodeTransactions(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil { t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) } - if err, want := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})), txpool.ErrAuthorityReserved; !errors.Is(err, want) { + if err, want := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})), ErrAuthorityReserved; !errors.Is(err, want) { t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err) } }, @@ -2440,8 +2440,8 @@ func TestSetCodeTransactionsReorg(t *testing.T) { t.Fatalf("failed to add with remote setcode transaction: %v", err) } // Try to add a transactions in - if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { - t.Fatalf("unexpected error %v, expecting %v", err, txpool.ErrAccountLimitExceeded) + if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); !errors.Is(err, ErrInflightTxLimitReached) { + t.Fatalf("unexpected error %v, expecting %v", err, ErrInflightTxLimitReached) } // Simulate the chain moving blockchain.statedb.SetNonce(addrA, 2, tracing.NonceChangeAuthorization) diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 4d53c386b6..9565c77def 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -206,7 +206,7 @@ type ValidationOptionsWithState struct { // nonce gaps will be ignored and permitted. FirstNonceGap func(addr common.Address) uint64 - // UsedAndLeftSlots is a mandatory callback to retrieve the number of tx slots + // UsedAndLeftSlots is an optional callback to retrieve the number of tx slots // used and the number still permitted for an account. New transactions will // be rejected once the number of remaining slots reaches zero. UsedAndLeftSlots func(addr common.Address) (int, int) @@ -218,11 +218,6 @@ type ValidationOptionsWithState struct { // ExistingCost is a mandatory callback to retrieve an already pooled // transaction's cost with the given nonce to check for overdrafts. ExistingCost func(addr common.Address, nonce uint64) *big.Int - - // KnownConflicts is an optional callback which iterates over the list of - // addresses and returns all addresses known to the pool with in-flight - // transactions. - KnownConflicts func(sender common.Address, authorizers []common.Address) []common.Address } // ValidateTransactionWithState is a helper method to check whether a transaction @@ -273,15 +268,9 @@ func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, op // Transaction takes a new nonce value out of the pool. Ensure it doesn't // overflow the number of permitted transactions from a single account // (i.e. max cancellable via out-of-bound transaction). - if used, left := opts.UsedAndLeftSlots(from); left <= 0 { - return fmt.Errorf("%w: pooled %d txs", ErrAccountLimitExceeded, used) - } - - // Verify no authorizations will invalidate existing transactions known to - // the pool. - if opts.KnownConflicts != nil { - if conflicts := opts.KnownConflicts(from, tx.SetCodeAuthorities()); len(conflicts) > 0 { - return fmt.Errorf("%w: authorization conflicts with other known tx", ErrAuthorityReserved) + if opts.UsedAndLeftSlots != nil { + if used, left := opts.UsedAndLeftSlots(from); left <= 0 { + return fmt.Errorf("%w: pooled %d txs", ErrAccountLimitExceeded, used) } } } From 7d8aca95d28c4e8560a657fd1ff7852ad4eee72c Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 25 Feb 2025 00:42:00 +0100 Subject: [PATCH 146/940] params: add deposit contract addresses (#31247) We forgot to add the deposit contract address for holesky, causing deposits to not be flagged correctly --------- Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> --- params/config.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/params/config.go b/params/config.go index 523c987f01..593c70b139 100644 --- a/params/config.go +++ b/params/config.go @@ -88,6 +88,7 @@ var ( ShanghaiTime: newUint64(1696000704), CancunTime: newUint64(1707305664), PragueTime: newUint64(1740434112), + DepositContractAddress: common.HexToAddress("0x4242424242424242424242424242424242424242"), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, @@ -117,6 +118,7 @@ var ( ShanghaiTime: newUint64(1677557088), CancunTime: newUint64(1706655072), PragueTime: newUint64(1741159776), + DepositContractAddress: common.HexToAddress("0x7f02c3e3c98b133055b8b348b2ac625669ed295d"), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, From 7cbf934488b510206b8d0c9e1453fe9fad83692a Mon Sep 17 00:00:00 2001 From: Pierre Rousset Date: Fri, 21 Feb 2025 11:28:11 +0900 Subject: [PATCH 147/940] Fix flakey behavior in simulated backend Rollback --- core/txpool/txpool.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 0ebf4c7e4b..e09c920779 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -486,6 +486,7 @@ func (p *TxPool) Sync() error { // Clear removes all tracked txs from the subpools. func (p *TxPool) Clear() { + p.Sync() for _, subpool := range p.subpools { subpool.Clear() } From f6883431c28abeda55690976c2a8b59343df1e5a Mon Sep 17 00:00:00 2001 From: jwasinger Date: Tue, 25 Feb 2025 12:21:35 +0100 Subject: [PATCH 148/940] ethclient/simulated: add goroutine leak test (#31033) Adds a basic sanity test case to catch any go-routines leaked from instantiation/closing of a simulated backend. --- ethclient/simulated/backend_test.go | 19 +++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 3 files changed, 22 insertions(+) diff --git a/ethclient/simulated/backend_test.go b/ethclient/simulated/backend_test.go index 5bf3c6be27..fc78e84362 100644 --- a/ethclient/simulated/backend_test.go +++ b/ethclient/simulated/backend_test.go @@ -25,6 +25,8 @@ import ( "testing" "time" + "go.uber.org/goleak" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/holiman/uint256" @@ -350,3 +352,20 @@ func TestAdjustTimeAfterFork(t *testing.T) { t.Errorf("failed to build block on fork") } } + +func createAndCloseSimBackend() { + genesisData := types.GenesisAlloc{} + simulatedBackend := NewBackend(genesisData) + defer simulatedBackend.Close() +} + +// TestCheckSimBackendGoroutineLeak checks whether creation of a simulated backend leaks go-routines. Any long-lived go-routines +// spawned by global variables are not considered leaked. +func TestCheckSimBackendGoroutineLeak(t *testing.T) { + createAndCloseSimBackend() + ignoreCur := goleak.IgnoreCurrent() + // ignore this leveldb function: this go-routine is guaranteed to be terminated 1 second after closing db handle + ignoreLdb := goleak.IgnoreAnyFunction("github.com/syndtr/goleveldb/leveldb.(*DB).mpoolDrain") + createAndCloseSimBackend() + goleak.VerifyNone(t, ignoreCur, ignoreLdb) +} diff --git a/go.mod b/go.mod index f86973e0f6..e58d8fd828 100644 --- a/go.mod +++ b/go.mod @@ -63,6 +63,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/urfave/cli/v2 v2.27.5 go.uber.org/automaxprocs v1.5.2 + go.uber.org/goleak v1.3.0 golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/sync v0.10.0 diff --git a/go.sum b/go.sum index 753ddbc9a5..0dbd79cfaa 100644 --- a/go.sum +++ b/go.sum @@ -528,6 +528,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= From 756310fa43b8beab12b4fbe5fb663bc79285c8d2 Mon Sep 17 00:00:00 2001 From: Shude Li Date: Tue, 25 Feb 2025 20:40:57 +0800 Subject: [PATCH 149/940] eth/protocols/eth: fix loading "eth" ENR key in dial filter (#31251) This fixes an issue where dial candidates from discv5 would be ignored because the "eth" ENR entry was not loaded correctly. --- eth/protocols/eth/discovery.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eth/protocols/eth/discovery.go b/eth/protocols/eth/discovery.go index 075a85b69c..f43e6f864d 100644 --- a/eth/protocols/eth/discovery.go +++ b/eth/protocols/eth/discovery.go @@ -42,6 +42,7 @@ func StartENRUpdater(chain *core.BlockChain, ln *enode.LocalNode) { var newHead = make(chan core.ChainHeadEvent, 10) sub := chain.SubscribeChainHeadEvent(newHead) + ln.Set(currentENREntry(chain)) go func() { defer sub.Unsubscribe() for { @@ -71,7 +72,7 @@ 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 { + if err := n.Load(&entry); err != nil { return false } err := filter(entry.ForkID) From 612c9e0f4ae483f180ef96ace86effec6dc9bb0e Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 25 Feb 2025 16:18:34 +0100 Subject: [PATCH 150/940] version: release go-ethereum v1.15.3 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index f0fb3195b3..cf01564d71 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 3 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 3 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From f485e213b6f05d7136364bd3efba6f8c2990666d Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 25 Feb 2025 16:20:50 +0100 Subject: [PATCH 151/940] version: begin v1.15.4 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index cf01564d71..ddf151aa74 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 3 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 4 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From c7caca456460d4a08ca7c5044f8dbd0f0017289c Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Wed, 26 Feb 2025 18:49:02 +0800 Subject: [PATCH 152/940] build: filter out .git folder for go generate check (#31265) Fixes lint issue >>> /home/appveyor/.gvm/gos/go1.24.0/bin/go generate ./... ci.go:404: File changed: .git/index ci.go:407: One or more generated files were updated by running 'go generate ./...' exit status 1 --- build/ci.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/ci.go b/build/ci.go index 6aa57f9cd5..fbf739e476 100644 --- a/build/ci.go +++ b/build/ci.go @@ -380,7 +380,7 @@ func doCheckGenerate() { var hashes map[string][32]byte var err error - hashes, err = build.HashFolder(".", []string{"tests/testdata", "build/cache"}) + hashes, err = build.HashFolder(".", []string{"tests/testdata", "build/cache", ".git"}) if err != nil { log.Fatal("Error computing hashes", "err", err) } @@ -395,7 +395,7 @@ func doCheckGenerate() { build.MustRun(c) // Check if generate file hashes have changed - generated, err := build.HashFolder(".", []string{"tests/testdata", "build/cache"}) + generated, err := build.HashFolder(".", []string{"tests/testdata", "build/cache", ".git"}) if err != nil { log.Fatalf("Error re-computing hashes: %v", err) } From 2585776aabbd4ae9b00050403b42afb0cee968ec Mon Sep 17 00:00:00 2001 From: James Date: Thu, 27 Feb 2025 07:24:14 +1300 Subject: [PATCH 153/940] eth/gasprice: fix eth_feeHistory blobGasRatio (#31246) This change divides BlobGasUsed by MaxBlobGasPerBlock instead of MaxBlobsPerBlock. Dividing by MaxBlobsPerBlock meant the blobGasUsedRatio was an incorrect large number. This bug was introduced by a typo [here](https://github.com/ethereum/go-ethereum/commit/e6f3ce7b168b8f346de621a8f60d2fa57c2ebfb0#diff-3357b2399699d7cf954c543cbfb02ff442eb24491e55f5e813e3cc85829b3e8dR110) Fixes https://github.com/ethereum/go-ethereum/issues/31245 --- eth/gasprice/feehistory.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index fe84950c50..59830e9fe8 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -107,8 +107,8 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { // 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 { - maxBlobs := eip4844.MaxBlobsPerBlock(config, bf.header.Time) - bf.results.blobGasUsedRatio = float64(*blobGasUsed) / float64(maxBlobs) + maxBlobGas := eip4844.MaxBlobGasPerBlock(config, bf.header.Time) + bf.results.blobGasUsedRatio = float64(*blobGasUsed) / float64(maxBlobGas) } if len(percentiles) == 0 { From 939a804146ee347b81119b09533acbf640d48b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Thu, 27 Feb 2025 00:07:14 +0100 Subject: [PATCH 154/940] cmd/workload: RPC workload tests for filters and history (#31189) Co-authored-by: Felix Lange Co-authored-by: Sina Mahmoodi --- cmd/abigen/main.go | 2 +- cmd/utils/flags.go | 53 +-- cmd/workload/README.md | 29 ++ cmd/workload/filtertest.go | 216 ++++++++++ cmd/workload/filtertestgen.go | 382 ++++++++++++++++++ cmd/workload/filtertestperf.go | 137 +++++++ cmd/workload/historytest.go | 309 ++++++++++++++ cmd/workload/historytestgen.go | 147 +++++++ cmd/workload/main.go | 86 ++++ .../queries/filter_queries_mainnet.json | 1 + .../queries/filter_queries_sepolia.json | 1 + cmd/workload/queries/history_mainnet.json | 1 + cmd/workload/queries/history_sepolia.json | 1 + cmd/workload/testsuite.go | 145 +++++++ internal/flags/helpers.go | 42 ++ 15 files changed, 1504 insertions(+), 48 deletions(-) create mode 100644 cmd/workload/README.md create mode 100644 cmd/workload/filtertest.go create mode 100644 cmd/workload/filtertestgen.go create mode 100644 cmd/workload/filtertestperf.go create mode 100644 cmd/workload/historytest.go create mode 100644 cmd/workload/historytestgen.go create mode 100644 cmd/workload/main.go create mode 100644 cmd/workload/queries/filter_queries_mainnet.json create mode 100644 cmd/workload/queries/filter_queries_sepolia.json create mode 100644 cmd/workload/queries/history_mainnet.json create mode 100644 cmd/workload/queries/history_sepolia.json create mode 100644 cmd/workload/testsuite.go diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 8ee3130b5b..10343190c3 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -93,7 +93,7 @@ func init() { } func abigen(c *cli.Context) error { - utils.CheckExclusive(c, abiFlag, jsonFlag) // Only one source can be selected. + flags.CheckExclusive(c, abiFlag, jsonFlag) // Only one source can be selected. if c.String(pkgFlag.Name) == "" { utils.Fatalf("No destination package specified (--pkg)") diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 243b5d22f0..728ec2d667 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1197,7 +1197,7 @@ func setWS(ctx *cli.Context, cfg *node.Config) { // setIPC creates an IPC path configuration from the set command line flags, // returning an empty string if IPC was explicitly disabled, or the set path. func setIPC(ctx *cli.Context, cfg *node.Config) { - CheckExclusive(ctx, IPCDisabledFlag, IPCPathFlag) + flags.CheckExclusive(ctx, IPCDisabledFlag, IPCPathFlag) switch { case ctx.Bool(IPCDisabledFlag.Name): cfg.IPCPath = "" @@ -1295,8 +1295,8 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { cfg.NoDiscovery = true } - CheckExclusive(ctx, DiscoveryV4Flag, NoDiscoverFlag) - CheckExclusive(ctx, DiscoveryV5Flag, NoDiscoverFlag) + flags.CheckExclusive(ctx, DiscoveryV4Flag, NoDiscoverFlag) + flags.CheckExclusive(ctx, DiscoveryV5Flag, NoDiscoverFlag) cfg.DiscoveryV4 = ctx.Bool(DiscoveryV4Flag.Name) cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name) @@ -1528,52 +1528,11 @@ func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) { } } -// CheckExclusive verifies that only a single instance of the provided flags was -// set by the user. Each flag might optionally be followed by a string type to -// specialize it further. -func CheckExclusive(ctx *cli.Context, args ...interface{}) { - set := make([]string, 0, 1) - for i := 0; i < len(args); i++ { - // Make sure the next argument is a flag and skip if not set - flag, ok := args[i].(cli.Flag) - if !ok { - panic(fmt.Sprintf("invalid argument, not cli.Flag type: %T", args[i])) - } - // Check if next arg extends current and expand its name if so - name := flag.Names()[0] - - if i+1 < len(args) { - switch option := args[i+1].(type) { - case string: - // Extended flag check, make sure value set doesn't conflict with passed in option - if ctx.String(flag.Names()[0]) == option { - name += "=" + option - set = append(set, "--"+name) - } - // shift arguments and continue - i++ - continue - - case cli.Flag: - default: - panic(fmt.Sprintf("invalid argument, not cli.Flag or string extension: %T", args[i+1])) - } - } - // Mark the flag if it's set - if ctx.IsSet(flag.Names()[0]) { - set = append(set, "--"+name) - } - } - if len(set) > 1 { - Fatalf("Flags %v can't be used at the same time", strings.Join(set, ", ")) - } -} - // SetEthConfig applies eth-related command line flags to the config. func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { // Avoid conflicting network flags - CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag) - CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer + flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag) + flags.CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer // Set configurations from CLI flags setEtherbase(ctx, cfg) @@ -1841,7 +1800,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig { var config bparams.ClientConfig customConfig := ctx.IsSet(BeaconConfigFlag.Name) - CheckExclusive(ctx, MainnetFlag, SepoliaFlag, HoleskyFlag, BeaconConfigFlag) + flags.CheckExclusive(ctx, MainnetFlag, SepoliaFlag, HoleskyFlag, BeaconConfigFlag) switch { case ctx.Bool(MainnetFlag.Name): config.ChainConfig = *bparams.MainnetLightConfig diff --git a/cmd/workload/README.md b/cmd/workload/README.md new file mode 100644 index 0000000000..c85e58a041 --- /dev/null +++ b/cmd/workload/README.md @@ -0,0 +1,29 @@ +## Workload Testing Tool + +This tool performs RPC calls against a live node. It has tests for the Sepolia testnet and +Mainnet. Note the tests require a fully synced node. + +To run the tests against a Sepolia node, use: + +```shell +> ./workload test --sepolia http://host:8545 +``` + +To run a specific test, use the `--run` flag to filter the test cases. Filtering works +similar to the `go test` command. For example, to run only tests for `eth_getBlockByHash` +and `eth_getBlockByNumber`, use this command: + +``` +> ./workload test --sepolia --run History/getBlockBy http://host:8545 +``` + +### Regenerating tests + +There is a facility for updating the tests from the chain. This can also be used to +generate the tests for a new network. As an example, to recreate tests for mainnet, run +the following commands (in this directory) against a synced mainnet node: + +```shell +> go run . filtergen --queries queries/filter_queries_mainnet.json http://host:8545 +> go run . historygen --history-tests queries/history_mainnet.json http://host:8545 +``` diff --git a/cmd/workload/filtertest.go b/cmd/workload/filtertest.go new file mode 100644 index 0000000000..0e709ac0fe --- /dev/null +++ b/cmd/workload/filtertest.go @@ -0,0 +1,216 @@ +// Copyright 2025 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 main + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/utesting" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" +) + +type filterTestSuite struct { + cfg testConfig + queries [][]*filterQuery +} + +func newFilterTestSuite(cfg testConfig) *filterTestSuite { + s := &filterTestSuite{cfg: cfg} + if err := s.loadQueries(); err != nil { + exit(err) + } + return s +} + +func (s *filterTestSuite) allTests() []utesting.Test { + return []utesting.Test{ + {Name: "Filter/ShortRange", Fn: s.filterShortRange}, + {Name: "Filter/LongRange", Fn: s.filterLongRange, Slow: true}, + {Name: "Filter/FullRange", Fn: s.filterFullRange, Slow: true}, + } +} + +func (s *filterTestSuite) filterRange(t *utesting.T, test func(query *filterQuery) bool, do func(t *utesting.T, query *filterQuery)) { + var count, total int + for _, bucket := range s.queries { + for _, query := range bucket { + if test(query) { + total++ + } + } + } + if total == 0 { + t.Fatalf("No suitable queries available") + } + start := time.Now() + last := start + for _, bucket := range s.queries { + for _, query := range bucket { + if test(query) { + do(t, query) + count++ + if time.Since(last) > time.Second*5 { + t.Logf("Making filter query %d/%d (elapsed: %v)", count, total, time.Since(start)) + last = time.Now() + } + } + } + } + t.Logf("Made %d filter queries (elapsed: %v)", count, time.Since(start)) +} + +const filterRangeThreshold = 10000 + +// filterShortRange runs all short-range filter tests. +func (s *filterTestSuite) filterShortRange(t *utesting.T) { + s.filterRange(t, func(query *filterQuery) bool { + return query.ToBlock+1-query.FromBlock <= filterRangeThreshold + }, s.queryAndCheck) +} + +// filterShortRange runs all long-range filter tests. +func (s *filterTestSuite) filterLongRange(t *utesting.T) { + s.filterRange(t, func(query *filterQuery) bool { + return query.ToBlock+1-query.FromBlock > filterRangeThreshold + }, s.queryAndCheck) +} + +// filterFullRange runs all filter tests, extending their range from genesis up +// to the latest block. Note that results are only partially verified in this mode. +func (s *filterTestSuite) filterFullRange(t *utesting.T) { + finalized := mustGetFinalizedBlock(s.cfg.client) + s.filterRange(t, func(query *filterQuery) bool { + return query.ToBlock+1-query.FromBlock > finalized/2 + }, s.fullRangeQueryAndCheck) +} + +func (s *filterTestSuite) queryAndCheck(t *utesting.T, query *filterQuery) { + query.run(s.cfg.client) + if query.Err != nil { + t.Errorf("Filter query failed (fromBlock: %d toBlock: %d addresses: %v topics: %v error: %v)", query.FromBlock, query.ToBlock, query.Address, query.Topics, query.Err) + return + } + if *query.ResultHash != query.calculateHash() { + t.Fatalf("Filter query result mismatch (fromBlock: %d toBlock: %d addresses: %v topics: %v)", query.FromBlock, query.ToBlock, query.Address, query.Topics) + } +} + +func (s *filterTestSuite) fullRangeQueryAndCheck(t *utesting.T, query *filterQuery) { + frQuery := &filterQuery{ // create full range query + FromBlock: 0, + ToBlock: int64(rpc.LatestBlockNumber), + Address: query.Address, + Topics: query.Topics, + } + frQuery.run(s.cfg.client) + if frQuery.Err != nil { + t.Errorf("Full range filter query failed (addresses: %v topics: %v error: %v)", frQuery.Address, frQuery.Topics, frQuery.Err) + return + } + // filter out results outside the original query range + j := 0 + for _, log := range frQuery.results { + if int64(log.BlockNumber) >= query.FromBlock && int64(log.BlockNumber) <= query.ToBlock { + frQuery.results[j] = log + j++ + } + } + frQuery.results = frQuery.results[:j] + if *query.ResultHash != frQuery.calculateHash() { + t.Fatalf("Full range filter query result mismatch (fromBlock: %d toBlock: %d addresses: %v topics: %v)", query.FromBlock, query.ToBlock, query.Address, query.Topics) + } +} + +func (s *filterTestSuite) loadQueries() error { + file, err := s.cfg.fsys.Open(s.cfg.filterQueryFile) + if err != nil { + return fmt.Errorf("can't open filterQueryFile: %v", err) + } + defer file.Close() + + var queries [][]*filterQuery + if err := json.NewDecoder(file).Decode(&queries); err != nil { + return fmt.Errorf("invalid JSON in %s: %v", s.cfg.filterQueryFile, err) + } + var count int + for _, bucket := range queries { + count += len(bucket) + } + if count == 0 { + return fmt.Errorf("filterQueryFile %s is empty", s.cfg.filterQueryFile) + } + s.queries = queries + return nil +} + +// filterQuery is a single query for testing. +type filterQuery struct { + FromBlock int64 `json:"fromBlock"` + ToBlock int64 `json:"toBlock"` + Address []common.Address `json:"address"` + Topics [][]common.Hash `json:"topics"` + ResultHash *common.Hash `json:"resultHash,omitempty"` + results []types.Log + Err error `json:"error,omitempty"` +} + +func (fq *filterQuery) isWildcard() bool { + if len(fq.Address) != 0 { + return false + } + for _, topics := range fq.Topics { + if len(topics) != 0 { + return false + } + } + return true +} + +func (fq *filterQuery) calculateHash() common.Hash { + enc, err := rlp.EncodeToBytes(&fq.results) + if err != nil { + exit(fmt.Errorf("Error encoding logs: %v", err)) + } + return crypto.Keccak256Hash(enc) +} + +func (fq *filterQuery) run(client *client) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + logs, err := client.Eth.FilterLogs(ctx, ethereum.FilterQuery{ + FromBlock: big.NewInt(fq.FromBlock), + ToBlock: big.NewInt(fq.ToBlock), + Addresses: fq.Address, + Topics: fq.Topics, + }) + if err != nil { + fq.Err = err + fmt.Printf("Filter query failed: fromBlock: %d toBlock: %d addresses: %v topics: %v error: %v\n", + fq.FromBlock, fq.ToBlock, fq.Address, fq.Topics, err) + return + } + fq.results = logs +} diff --git a/cmd/workload/filtertestgen.go b/cmd/workload/filtertestgen.go new file mode 100644 index 0000000000..29aad9ddd9 --- /dev/null +++ b/cmd/workload/filtertestgen.go @@ -0,0 +1,382 @@ +// Copyright 2025 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 main + +import ( + "context" + "encoding/json" + "fmt" + "math" + "math/big" + "math/rand" + "os" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/rpc" + "github.com/urfave/cli/v2" +) + +var ( + filterGenerateCommand = &cli.Command{ + Name: "filtergen", + Usage: "Generates query set for log filter workload test", + ArgsUsage: "", + Action: filterGenCmd, + Flags: []cli.Flag{ + filterQueryFileFlag, + filterErrorFileFlag, + }, + } + filterQueryFileFlag = &cli.StringFlag{ + Name: "queries", + Usage: "JSON file containing filter test queries", + Value: "filter_queries.json", + Category: flags.TestingCategory, + } + filterErrorFileFlag = &cli.StringFlag{ + Name: "errors", + Usage: "JSON file containing failed filter queries", + Value: "filter_errors.json", + Category: flags.TestingCategory, + } +) + +// filterGenCmd is the main function of the filter tests generator. +func filterGenCmd(ctx *cli.Context) error { + f := newFilterTestGen(ctx) + lastWrite := time.Now() + for { + select { + case <-ctx.Done(): + return nil + default: + } + + f.updateFinalizedBlock() + query := f.newQuery() + query.run(f.client) + if query.Err != nil { + f.errors = append(f.errors, query) + continue + } + if len(query.results) > 0 && len(query.results) <= maxFilterResultSize { + for { + extQuery := f.extendRange(query) + if extQuery == nil { + break + } + extQuery.run(f.client) + if extQuery.Err == nil && len(extQuery.results) < len(query.results) { + extQuery.Err = fmt.Errorf("invalid result length; old range %d %d; old length %d; new range %d %d; new length %d; address %v; Topics %v", + query.FromBlock, query.ToBlock, len(query.results), + extQuery.FromBlock, extQuery.ToBlock, len(extQuery.results), + extQuery.Address, extQuery.Topics, + ) + } + if extQuery.Err != nil { + f.errors = append(f.errors, extQuery) + break + } + if len(extQuery.results) > maxFilterResultSize { + break + } + query = extQuery + } + f.storeQuery(query) + if time.Since(lastWrite) > time.Second*10 { + f.writeQueries() + f.writeErrors() + lastWrite = time.Now() + } + } + } +} + +// filterTestGen is the filter query test generator. +type filterTestGen struct { + client *client + queryFile string + errorFile string + + finalizedBlock int64 + queries [filterBuckets][]*filterQuery + errors []*filterQuery +} + +func newFilterTestGen(ctx *cli.Context) *filterTestGen { + return &filterTestGen{ + client: makeClient(ctx), + queryFile: ctx.String(filterQueryFileFlag.Name), + errorFile: ctx.String(filterErrorFileFlag.Name), + } +} + +func (s *filterTestGen) updateFinalizedBlock() { + s.finalizedBlock = mustGetFinalizedBlock(s.client) +} + +const ( + // Parameter of the random filter query generator. + maxFilterRange = 10000000 + maxFilterResultSize = 300 + filterBuckets = 10 + maxFilterBucketSize = 100 + filterSeedChance = 10 + filterMergeChance = 45 +) + +// storeQuery adds a filter query to the output file. +func (s *filterTestGen) storeQuery(query *filterQuery) { + query.ResultHash = new(common.Hash) + *query.ResultHash = query.calculateHash() + logRatio := math.Log(float64(len(query.results))*float64(s.finalizedBlock)/float64(query.ToBlock+1-query.FromBlock)) / math.Log(float64(s.finalizedBlock)*maxFilterResultSize) + bucket := int(math.Floor(logRatio * filterBuckets)) + if bucket >= filterBuckets { + bucket = filterBuckets - 1 + } + if len(s.queries[bucket]) < maxFilterBucketSize { + s.queries[bucket] = append(s.queries[bucket], query) + } else { + s.queries[bucket][rand.Intn(len(s.queries[bucket]))] = query + } + fmt.Print("Generated queries per bucket:") + for _, list := range s.queries { + fmt.Print(" ", len(list)) + } + fmt.Println() +} + +func (s *filterTestGen) extendRange(q *filterQuery) *filterQuery { + rangeLen := q.ToBlock + 1 - q.FromBlock + extLen := rand.Int63n(rangeLen) + 1 + if rangeLen+extLen > s.finalizedBlock { + return nil + } + extBefore := min(rand.Int63n(extLen+1), q.FromBlock) + extAfter := extLen - extBefore + if q.ToBlock+extAfter > s.finalizedBlock { + d := q.ToBlock + extAfter - s.finalizedBlock + extAfter -= d + if extBefore+d <= q.FromBlock { + extBefore += d + } else { + extBefore = q.FromBlock + } + } + return &filterQuery{ + FromBlock: q.FromBlock - extBefore, + ToBlock: q.ToBlock + extAfter, + Address: q.Address, + Topics: q.Topics, + } +} + +// newQuery generates a new filter query. +func (s *filterTestGen) newQuery() *filterQuery { + for { + t := rand.Intn(100) + if t < filterSeedChance { + return s.newSeedQuery() + } + if t < filterSeedChance+filterMergeChance { + if query := s.newMergedQuery(); query != nil { + return query + } + continue + } + if query := s.newNarrowedQuery(); query != nil { + return query + } + } +} + +// newSeedQuery creates a query that gets all logs in a random non-finalized block. +func (s *filterTestGen) newSeedQuery() *filterQuery { + block := rand.Int63n(s.finalizedBlock + 1) + return &filterQuery{ + FromBlock: block, + ToBlock: block, + } +} + +// newMergedQuery creates a new query by combining (with OR) the filter criteria +// of two existing queries (chosen at random). +func (s *filterTestGen) newMergedQuery() *filterQuery { + q1 := s.randomQuery() + q2 := s.randomQuery() + if q1 == nil || q2 == nil || q1 == q2 { + return nil + } + var ( + block int64 + topicCount int + ) + if rand.Intn(2) == 0 { + block = q1.FromBlock + rand.Int63n(q1.ToBlock+1-q1.FromBlock) + topicCount = len(q1.Topics) + } else { + block = q2.FromBlock + rand.Int63n(q2.ToBlock+1-q2.FromBlock) + topicCount = len(q2.Topics) + } + m := &filterQuery{ + FromBlock: block, + ToBlock: block, + Topics: make([][]common.Hash, topicCount), + } + for _, addr := range q1.Address { + if rand.Intn(2) == 0 { + m.Address = append(m.Address, addr) + } + } + for _, addr := range q2.Address { + if rand.Intn(2) == 0 { + m.Address = append(m.Address, addr) + } + } + for i := range m.Topics { + if len(q1.Topics) > i { + for _, topic := range q1.Topics[i] { + if rand.Intn(2) == 0 { + m.Topics[i] = append(m.Topics[i], topic) + } + } + } + if len(q2.Topics) > i { + for _, topic := range q2.Topics[i] { + if rand.Intn(2) == 0 { + m.Topics[i] = append(m.Topics[i], topic) + } + } + } + } + return m +} + +// newNarrowedQuery creates a new query by 'narrowing' an existing (randomly chosen) +// query. The new query is made more specific by analyzing the filter criteria and adding +// topics/addresses from the known result set. +func (s *filterTestGen) newNarrowedQuery() *filterQuery { + q := s.randomQuery() + if q == nil { + return nil + } + log := q.results[rand.Intn(len(q.results))] + var emptyCount int + if len(q.Address) == 0 { + emptyCount++ + } + for i := range log.Topics { + if len(q.Topics) <= i || len(q.Topics[i]) == 0 { + emptyCount++ + } + } + if emptyCount == 0 { + return nil + } + query := &filterQuery{ + FromBlock: q.FromBlock, + ToBlock: q.ToBlock, + Address: make([]common.Address, len(q.Address)), + Topics: make([][]common.Hash, len(q.Topics)), + } + copy(query.Address, q.Address) + for i, topics := range q.Topics { + if len(topics) > 0 { + query.Topics[i] = make([]common.Hash, len(topics)) + copy(query.Topics[i], topics) + } + } + pick := rand.Intn(emptyCount) + if len(query.Address) == 0 { + if pick == 0 { + query.Address = []common.Address{log.Address} + return query + } + pick-- + } + for i := range log.Topics { + if len(query.Topics) <= i || len(query.Topics[i]) == 0 { + if pick == 0 { + if len(query.Topics) <= i { + query.Topics = append(query.Topics, make([][]common.Hash, i+1-len(query.Topics))...) + } + query.Topics[i] = []common.Hash{log.Topics[i]} + return query + } + pick-- + } + } + panic("unreachable") +} + +// randomQuery returns a random query from the ones that were already generated. +func (s *filterTestGen) randomQuery() *filterQuery { + var bucket, bucketCount int + for _, list := range s.queries { + if len(list) > 0 { + bucketCount++ + } + } + if bucketCount == 0 { + return nil + } + pick := rand.Intn(bucketCount) + for i, list := range s.queries { + if len(list) > 0 { + if pick == 0 { + bucket = i + break + } + pick-- + } + } + return s.queries[bucket][rand.Intn(len(s.queries[bucket]))] +} + +// writeQueries serializes the generated queries to the output file. +func (s *filterTestGen) writeQueries() { + file, err := os.Create(s.queryFile) + if err != nil { + exit(fmt.Errorf("Error creating filter test query file %s: %v", s.queryFile, err)) + return + } + json.NewEncoder(file).Encode(&s.queries) + file.Close() +} + +// writeQueries serializes the generated errors to the error file. +func (s *filterTestGen) writeErrors() { + file, err := os.Create(s.errorFile) + if err != nil { + exit(fmt.Errorf("Error creating filter error file %s: %v", s.errorFile, err)) + return + } + defer file.Close() + json.NewEncoder(file).Encode(s.errors) +} + +func mustGetFinalizedBlock(client *client) int64 { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + header, err := client.Eth.HeaderByNumber(ctx, big.NewInt(int64(rpc.FinalizedBlockNumber))) + if err != nil { + exit(fmt.Errorf("could not fetch finalized header (error: %v)", err)) + } + return header.Number.Int64() +} diff --git a/cmd/workload/filtertestperf.go b/cmd/workload/filtertestperf.go new file mode 100644 index 0000000000..c1f2aff580 --- /dev/null +++ b/cmd/workload/filtertestperf.go @@ -0,0 +1,137 @@ +// Copyright 2025 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 main + +import ( + "fmt" + "math/rand" + "slices" + "sort" + "time" + + "github.com/urfave/cli/v2" +) + +var ( + filterPerfCommand = &cli.Command{ + Name: "filterperf", + Usage: "Runs log filter performance test against an RPC endpoint", + ArgsUsage: "", + Action: filterPerfCmd, + Flags: []cli.Flag{ + testSepoliaFlag, + testMainnetFlag, + filterQueryFileFlag, + filterErrorFileFlag, + }, + } +) + +const passCount = 1 + +func filterPerfCmd(ctx *cli.Context) error { + cfg := testConfigFromCLI(ctx) + f := newFilterTestSuite(cfg) + + type queryTest struct { + query *filterQuery + bucket, index int + runtime []time.Duration + medianTime time.Duration + } + var queries, processed []queryTest + for i, bucket := range f.queries[:] { + for j, query := range bucket { + queries = append(queries, queryTest{query: query, bucket: i, index: j}) + } + } + + // Run test queries. + var failed, mismatch int + for i := 1; i <= passCount; i++ { + fmt.Println("Performance test pass", i, "/", passCount) + for len(queries) > 0 { + pick := rand.Intn(len(queries)) + qt := queries[pick] + queries[pick] = queries[len(queries)-1] + queries = queries[:len(queries)-1] + start := time.Now() + qt.query.run(cfg.client) + qt.runtime = append(qt.runtime, time.Since(start)) + slices.Sort(qt.runtime) + qt.medianTime = qt.runtime[len(qt.runtime)/2] + if qt.query.Err != nil { + failed++ + continue + } + if rhash := qt.query.calculateHash(); *qt.query.ResultHash != rhash { + fmt.Printf("Filter query result mismatch: fromBlock: %d toBlock: %d addresses: %v topics: %v expected hash: %064x calculated hash: %064x\n", qt.query.FromBlock, qt.query.ToBlock, qt.query.Address, qt.query.Topics, *qt.query.ResultHash, rhash) + continue + } + processed = append(processed, qt) + if len(processed)%50 == 0 { + fmt.Println(" processed:", len(processed), "remaining", len(queries), "failed:", failed, "result mismatch:", mismatch) + } + } + queries, processed = processed, nil + } + + // Show results and stats. + fmt.Println("Performance test finished; processed:", len(queries), "failed:", failed, "result mismatch:", mismatch) + stats := make([]bucketStats, len(f.queries)) + var wildcardStats bucketStats + for _, qt := range queries { + bs := &stats[qt.bucket] + if qt.query.isWildcard() { + bs = &wildcardStats + } + bs.blocks += qt.query.ToBlock + 1 - qt.query.FromBlock + bs.count++ + bs.logs += len(qt.query.results) + bs.runtime += qt.medianTime + } + + fmt.Println() + for i := range stats { + stats[i].print(fmt.Sprintf("bucket #%d", i+1)) + } + wildcardStats.print("wild card queries") + fmt.Println() + sort.Slice(queries, func(i, j int) bool { + return queries[i].medianTime > queries[j].medianTime + }) + for i := 0; i < 10; i++ { + q := queries[i] + fmt.Printf("Most expensive query #%-2d median runtime: %13v max runtime: %13v result count: %4d fromBlock: %9d toBlock: %9d addresses: %v topics: %v\n", + i+1, q.medianTime, q.runtime[len(q.runtime)-1], len(q.query.results), q.query.FromBlock, q.query.ToBlock, q.query.Address, q.query.Topics) + } + return nil +} + +type bucketStats struct { + blocks int64 + count, logs int + runtime time.Duration +} + +func (st *bucketStats) print(name string) { + if st.count == 0 { + return + } + fmt.Printf("%-20s queries: %4d average block length: %12.2f average log count: %7.2f average runtime: %13v\n", + name, st.count, float64(st.blocks)/float64(st.count), float64(st.logs)/float64(st.count), st.runtime/time.Duration(st.count)) +} diff --git a/cmd/workload/historytest.go b/cmd/workload/historytest.go new file mode 100644 index 0000000000..a681510422 --- /dev/null +++ b/cmd/workload/historytest.go @@ -0,0 +1,309 @@ +// Copyright 2025 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 main + +import ( + "context" + "encoding/json" + "fmt" + + "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/internal/utesting" +) + +// historyTest is the content of a history test. +type historyTest struct { + BlockNumbers []uint64 `json:"blockNumbers"` + BlockHashes []common.Hash `json:"blockHashes"` + TxCounts []int `json:"txCounts"` + TxHashIndex []int `json:"txHashIndex"` + TxHashes []*common.Hash `json:"txHashes"` + ReceiptsHashes []common.Hash `json:"blockReceiptsHashes"` +} + +type historyTestSuite struct { + cfg testConfig + tests historyTest +} + +func newHistoryTestSuite(cfg testConfig) *historyTestSuite { + s := &historyTestSuite{cfg: cfg} + if err := s.loadTests(); err != nil { + exit(err) + } + return s +} + +func (s *historyTestSuite) loadTests() error { + file, err := s.cfg.fsys.Open(s.cfg.historyTestFile) + if err != nil { + return fmt.Errorf("can't open historyTestFile: %v", err) + } + defer file.Close() + if err := json.NewDecoder(file).Decode(&s.tests); err != nil { + return fmt.Errorf("invalid JSON in %s: %v", s.cfg.historyTestFile, err) + } + if len(s.tests.BlockNumbers) == 0 { + return fmt.Errorf("historyTestFile %s has no test data", s.cfg.historyTestFile) + } + return nil +} + +func (s *historyTestSuite) allTests() []utesting.Test { + return []utesting.Test{ + { + Name: "History/getBlockByHash", + Fn: s.testGetBlockByHash, + }, + { + Name: "History/getBlockByNumber", + Fn: s.testGetBlockByNumber, + }, + { + Name: "History/getBlockReceiptsByHash", + Fn: s.testGetBlockReceiptsByHash, + }, + { + Name: "History/getBlockReceiptsByNumber", + Fn: s.testGetBlockReceiptsByNumber, + }, + { + Name: "History/getBlockTransactionCountByHash", + Fn: s.testGetBlockTransactionCountByHash, + }, + { + Name: "History/getBlockTransactionCountByNumber", + Fn: s.testGetBlockTransactionCountByNumber, + }, + { + Name: "History/getTransactionByBlockHashAndIndex", + Fn: s.testGetTransactionByBlockHashAndIndex, + }, + { + Name: "History/getTransactionByBlockNumberAndIndex", + Fn: s.testGetTransactionByBlockNumberAndIndex, + }, + } +} + +func (s *historyTestSuite) testGetBlockByHash(t *utesting.T) { + ctx := context.Background() + + for i, num := range s.tests.BlockNumbers { + bhash := s.tests.BlockHashes[i] + b, err := s.cfg.client.getBlockByHash(ctx, bhash, false) + if err != nil { + t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + } + if b == nil { + t.Errorf("block %d (hash %v): not found", num, bhash) + continue + } + if b.Hash != bhash || uint64(b.Number) != num { + t.Errorf("block %d (hash %v): invalid number/hash", num, bhash) + } + } +} + +func (s *historyTestSuite) testGetBlockByNumber(t *utesting.T) { + ctx := context.Background() + + for i, num := range s.tests.BlockNumbers { + bhash := s.tests.BlockHashes[i] + b, err := s.cfg.client.getBlockByNumber(ctx, num, false) + if err != nil { + t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + } + if b == nil { + t.Errorf("block %d (hash %v): not found", num, bhash) + continue + } + if b.Hash != bhash || uint64(b.Number) != num { + t.Errorf("block %d (hash %v): invalid number/hash", num, bhash) + } + } +} + +func (s *historyTestSuite) testGetBlockTransactionCountByHash(t *utesting.T) { + ctx := context.Background() + + for i, num := range s.tests.BlockNumbers { + bhash := s.tests.BlockHashes[i] + count, err := s.cfg.client.getBlockTransactionCountByHash(ctx, bhash) + if err != nil { + t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + } + expectedCount := uint64(s.tests.TxCounts[i]) + if count != expectedCount { + t.Errorf("block %d (hash %v): wrong txcount %d, want %d", count, expectedCount) + } + } +} + +func (s *historyTestSuite) testGetBlockTransactionCountByNumber(t *utesting.T) { + ctx := context.Background() + + for i, num := range s.tests.BlockNumbers { + bhash := s.tests.BlockHashes[i] + count, err := s.cfg.client.getBlockTransactionCountByNumber(ctx, num) + if err != nil { + t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + } + expectedCount := uint64(s.tests.TxCounts[i]) + if count != expectedCount { + t.Errorf("block %d (hash %v): wrong txcount %d, want %d", count, expectedCount) + } + } +} + +func (s *historyTestSuite) testGetBlockReceiptsByHash(t *utesting.T) { + ctx := context.Background() + + for i, num := range s.tests.BlockNumbers { + bhash := s.tests.BlockHashes[i] + receipts, err := s.cfg.client.getBlockReceipts(ctx, bhash) + if err != nil { + t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + } + hash := calcReceiptsHash(receipts) + expectedHash := s.tests.ReceiptsHashes[i] + if hash != expectedHash { + t.Errorf("block %d (hash %v): wrong receipts hash %v, want %v", num, bhash, hash, expectedHash) + } + } +} + +func (s *historyTestSuite) testGetBlockReceiptsByNumber(t *utesting.T) { + ctx := context.Background() + + for i, num := range s.tests.BlockNumbers { + bhash := s.tests.BlockHashes[i] + receipts, err := s.cfg.client.getBlockReceipts(ctx, hexutil.Uint64(num)) + if err != nil { + t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + } + hash := calcReceiptsHash(receipts) + expectedHash := s.tests.ReceiptsHashes[i] + if hash != expectedHash { + t.Errorf("block %d (hash %v): wrong receipts hash %v, want %v", num, bhash, hash, expectedHash) + } + } +} + +func (s *historyTestSuite) testGetTransactionByBlockHashAndIndex(t *utesting.T) { + ctx := context.Background() + + for i, num := range s.tests.BlockNumbers { + bhash := s.tests.BlockHashes[i] + txIndex := s.tests.TxHashIndex[i] + expectedHash := s.tests.TxHashes[i] + if expectedHash == nil { + continue // no txs in block + } + + tx, err := s.cfg.client.getTransactionByBlockHashAndIndex(ctx, bhash, uint64(txIndex)) + if err != nil { + t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + } + if tx == nil { + t.Errorf("block %d (hash %v): txIndex %d not found", num, bhash, txIndex) + continue + } + if tx.Hash != *expectedHash || uint64(tx.TransactionIndex) != uint64(txIndex) { + t.Errorf("block %d (hash %v): txIndex %d has wrong txHash/Index", num, bhash, txIndex) + } + } +} + +func (s *historyTestSuite) testGetTransactionByBlockNumberAndIndex(t *utesting.T) { + ctx := context.Background() + + for i, num := range s.tests.BlockNumbers { + bhash := s.tests.BlockHashes[i] + txIndex := s.tests.TxHashIndex[i] + expectedHash := s.tests.TxHashes[i] + if expectedHash == nil { + continue // no txs in block + } + + tx, err := s.cfg.client.getTransactionByBlockNumberAndIndex(ctx, num, uint64(txIndex)) + if err != nil { + t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + } + if tx == nil { + t.Errorf("block %d (hash %v): txIndex %d not found", num, bhash, txIndex) + continue + } + if tx.Hash != *expectedHash || uint64(tx.TransactionIndex) != uint64(txIndex) { + t.Errorf("block %d (hash %v): txIndex %d has wrong txHash/Index", num, bhash, txIndex) + } + } +} + +type simpleBlock struct { + Number hexutil.Uint64 `json:"number"` + Hash common.Hash `json:"hash"` +} + +type simpleTransaction struct { + Hash common.Hash `json:"hash"` + TransactionIndex hexutil.Uint64 `json:"transactionIndex"` +} + +func (c *client) getBlockByHash(ctx context.Context, arg common.Hash, fullTx bool) (*simpleBlock, error) { + var r *simpleBlock + err := c.RPC.CallContext(ctx, &r, "eth_getBlockByHash", arg, fullTx) + return r, err +} + +func (c *client) getBlockByNumber(ctx context.Context, arg uint64, fullTx bool) (*simpleBlock, error) { + var r *simpleBlock + err := c.RPC.CallContext(ctx, &r, "eth_getBlockByNumber", hexutil.Uint64(arg), fullTx) + return r, err +} + +func (c *client) getTransactionByBlockHashAndIndex(ctx context.Context, block common.Hash, index uint64) (*simpleTransaction, error) { + var r *simpleTransaction + err := c.RPC.CallContext(ctx, &r, "eth_getTransactionByBlockHashAndIndex", block, hexutil.Uint64(index)) + return r, err +} + +func (c *client) getTransactionByBlockNumberAndIndex(ctx context.Context, block uint64, index uint64) (*simpleTransaction, error) { + var r *simpleTransaction + err := c.RPC.CallContext(ctx, &r, "eth_getTransactionByBlockNumberAndIndex", hexutil.Uint64(block), hexutil.Uint64(index)) + return r, err +} + +func (c *client) getBlockTransactionCountByHash(ctx context.Context, block common.Hash) (uint64, error) { + var r hexutil.Uint64 + err := c.RPC.CallContext(ctx, &r, "eth_getBlockTransactionCountByHash", block) + return uint64(r), err +} + +func (c *client) getBlockTransactionCountByNumber(ctx context.Context, block uint64) (uint64, error) { + var r hexutil.Uint64 + err := c.RPC.CallContext(ctx, &r, "eth_getBlockTransactionCountByNumber", hexutil.Uint64(block)) + return uint64(r), err +} + +func (c *client) getBlockReceipts(ctx context.Context, arg any) ([]*types.Receipt, error) { + var result []*types.Receipt + err := c.RPC.CallContext(ctx, &result, "eth_getBlockReceipts", arg) + return result, err +} diff --git a/cmd/workload/historytestgen.go b/cmd/workload/historytestgen.go new file mode 100644 index 0000000000..9d98bb28e6 --- /dev/null +++ b/cmd/workload/historytestgen.go @@ -0,0 +1,147 @@ +// Copyright 2025 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 main + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "os" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/rlp" + "github.com/urfave/cli/v2" +) + +var ( + historyGenerateCommand = &cli.Command{ + Name: "historygen", + Usage: "Generates history retrieval tests", + ArgsUsage: "", + Action: generateHistoryTests, + Flags: []cli.Flag{ + historyTestFileFlag, + historyTestEarliestFlag, + }, + } + + historyTestFileFlag = &cli.StringFlag{ + Name: "history-tests", + Usage: "JSON file containing filter test queries", + Value: "history_tests.json", + Category: flags.TestingCategory, + } + historyTestEarliestFlag = &cli.IntFlag{ + Name: "earliest", + Usage: "JSON file containing filter test queries", + Value: 0, + Category: flags.TestingCategory, + } +) + +const historyTestBlockCount = 2000 + +func generateHistoryTests(clictx *cli.Context) error { + var ( + client = makeClient(clictx) + earliest = uint64(clictx.Int(historyTestEarliestFlag.Name)) + outputFile = clictx.String(historyTestFileFlag.Name) + ctx = context.Background() + ) + + test := new(historyTest) + + // Create the block numbers. Here we choose 1k blocks between earliest and head. + latest, err := client.Eth.BlockNumber(ctx) + if err != nil { + exit(err) + } + if latest < historyTestBlockCount { + exit(fmt.Errorf("node seems not synced, latest block is %d", latest)) + } + test.BlockNumbers = make([]uint64, 0, historyTestBlockCount) + stride := (latest - earliest) / historyTestBlockCount + for b := earliest; b < latest; b += stride { + test.BlockNumbers = append(test.BlockNumbers, b) + } + + // Get blocks and assign block info into the test + fmt.Println("Fetching blocks") + blocks := make([]*types.Block, len(test.BlockNumbers)) + for i, blocknum := range test.BlockNumbers { + b, err := client.Eth.BlockByNumber(ctx, new(big.Int).SetUint64(blocknum)) + if err != nil { + exit(fmt.Errorf("error fetching block %d: %v", blocknum, err)) + } + blocks[i] = b + } + test.BlockHashes = make([]common.Hash, len(blocks)) + test.TxCounts = make([]int, len(blocks)) + for i, block := range blocks { + test.BlockHashes[i] = block.Hash() + test.TxCounts[i] = len(block.Transactions()) + } + + // Fill tx index. + test.TxHashIndex = make([]int, len(blocks)) + test.TxHashes = make([]*common.Hash, len(blocks)) + for i, block := range blocks { + txs := block.Transactions() + if len(txs) == 0 { + continue + } + index := len(txs) / 2 + txhash := txs[index].Hash() + test.TxHashIndex[i] = index + test.TxHashes[i] = &txhash + } + + // Get receipts. + fmt.Println("Fetching receipts") + test.ReceiptsHashes = make([]common.Hash, len(blocks)) + for i, blockHash := range test.BlockHashes { + receipts, err := client.getBlockReceipts(ctx, blockHash) + if err != nil { + exit(fmt.Errorf("error fetching block %v receipts: %v", blockHash, err)) + } + test.ReceiptsHashes[i] = calcReceiptsHash(receipts) + } + + // Write output file. + writeJSON(outputFile, test) + return nil +} + +func calcReceiptsHash(rcpt []*types.Receipt) common.Hash { + h := crypto.NewKeccakState() + rlp.Encode(h, rcpt) + return common.Hash(h.Sum(nil)) +} + +func writeJSON(fileName string, value any) { + file, err := os.Create(fileName) + if err != nil { + exit(fmt.Errorf("Error creating %s: %v", fileName, err)) + return + } + defer file.Close() + json.NewEncoder(file).Encode(value) +} diff --git a/cmd/workload/main.go b/cmd/workload/main.go new file mode 100644 index 0000000000..6ade426c16 --- /dev/null +++ b/cmd/workload/main.go @@ -0,0 +1,86 @@ +// Copyright 2025 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 main + +import ( + "fmt" + "os" + + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/internal/debug" + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/rpc" + "github.com/urfave/cli/v2" +) + +var app = flags.NewApp("go-ethereum workload test tool") + +func init() { + app.Flags = append(app.Flags, debug.Flags...) + app.Before = func(ctx *cli.Context) error { + flags.MigrateGlobalFlags(ctx) + return debug.Setup(ctx) + } + app.After = func(ctx *cli.Context) error { + debug.Exit() + return nil + } + app.CommandNotFound = func(ctx *cli.Context, cmd string) { + fmt.Fprintf(os.Stderr, "No such command: %s\n", cmd) + os.Exit(1) + } + + // Add subcommands. + app.Commands = []*cli.Command{ + runTestCommand, + historyGenerateCommand, + filterGenerateCommand, + filterPerfCommand, + } +} + +func main() { + exit(app.Run(os.Args)) +} + +type client struct { + Eth *ethclient.Client + RPC *rpc.Client +} + +func makeClient(ctx *cli.Context) *client { + if ctx.NArg() < 1 { + exit("missing RPC endpoint URL as command-line argument") + } + url := ctx.Args().First() + cl, err := rpc.Dial(url) + if err != nil { + exit(fmt.Errorf("Could not create RPC client at %s: %v", url, err)) + } + return &client{ + RPC: cl, + Eth: ethclient.NewClient(cl), + } +} + +func exit(err any) { + if err == nil { + os.Exit(0) + } + fmt.Fprintln(os.Stderr, err) + os.Exit(1) +} diff --git a/cmd/workload/queries/filter_queries_mainnet.json b/cmd/workload/queries/filter_queries_mainnet.json new file mode 100644 index 0000000000..3486885729 --- /dev/null +++ b/cmd/workload/queries/filter_queries_mainnet.json @@ -0,0 +1 @@ +[[{"fromBlock":0,"toBlock":20533811,"address":["0xa6794dec66df7d8b69752956df1b28ca93f77cd7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"]],"resultHash":"0xf3e78259332c6228e609b59b361024cafe5481304eb44eea49682c998afa7ff4"},{"fromBlock":3224543,"toBlock":21893937,"address":["0x761d38e5ddf6ccf6cf7c55759d5210750b5d60f3"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007b73644935b8e68019ac6356c40661e1bc315860"],["0x0000000000000000000000000ef7f9c5549165d204d8f440d1d84ea4f8c1dca4"]],"resultHash":"0xd064e462d2e964638bc8ee4fd6d87a764d55e0e9161a5b2b937a44d6fcc88fe3"},{"fromBlock":2248391,"toBlock":21894159,"address":["0xcd6bcca48069f8588780dfa274960f15685aee0e"],"topics":[null,["0x000000000000000000000000c384ac6ee27c39e2f278c220bdfa5baed626d9d3"],["0x000000000000000000000000cd6bcca48069f8588780dfa274960f15685aee0e"]],"resultHash":"0xb98df5d2fbe3931f0217701b7321db3b2af224c4950c5d03cc18d92c963f349d"},{"fromBlock":4017902,"toBlock":18202413,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000139ff314a62816d7d4d10c05c77b870169ecc7f0"]],"resultHash":"0x9dfca1a50f07ccf47a38cdd07df8367e1096a5ea1b70f45633e1a8a9db3c65d6"},{"fromBlock":1139493,"toBlock":21053654,"address":["0x5f98805a4e8be255a32880fdec7f6728c6568ba0"],"topics":[null,["0x000000000000000000000000c384ac6ee27c39e2f278c220bdfa5baed626d9d3"],["0x000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca"]],"resultHash":"0x1e54da0de45e85b9f25c891e0979a2243e3e51b2747d1cae25565519ceb21a34"},{"fromBlock":3451035,"toBlock":21893937,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x000000000000000000000000a3338b2b1a2cdfc448832ac1a511b628a24e7b77"]],"resultHash":"0x41bde228497f768920951f4c84f8997648fef7cd7dc89799d6abcf4a61f638e9"},{"fromBlock":671018,"toBlock":21894063,"address":["0xbcf935d206ca32929e1b887a07ed240f0d8ccd22"],"topics":[["0xce7dc747411ac40191c5335943fcc79d8c2d8c01ca5ae83d9fed160409fa6120"],["0x000000000000000000000000984026d27708ee0cac29fceb19400a7a5301e4df"]],"resultHash":"0x47748f41e60872acc3e6659c7e1405bc73d41aa36286e7211b4da8cc29141c97"},{"fromBlock":2767062,"toBlock":19649121,"address":[],"topics":[null,null,["0x000000000000000000000000bd554c3df133a850a2a8e65708f37ba5efe35cbd"]],"resultHash":"0xba1afb57e2103ca9f0e345c52e8e078ac7a9e572620813223efd3b0e8a3916a5"},{"fromBlock":1490593,"toBlock":21894191,"address":["0x172a9be5ea7f8602d6b9a97a914d23859053790a"],"topics":[["0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82"],["0x587d09fe5fa45354680537d38145a28b772971e0f293af3ee0c536fc919710fb"],["0x182b30867035c40c01114804fc90b9942f453de79d07993be1d614abfc37848c"]],"resultHash":"0xcd6d61bbe2f84b667484980ba5d4f07e90ba769d8c60373c19d10c2b87058272"},{"fromBlock":3199906,"toBlock":21894159,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x00000000000000000000000040e10218e0ab001b109d9f9ca96c8487c457e65f"]],"resultHash":"0x576f6817c2edb9891a88866339ca70e51e9a118b27bc46ee87decc0181599798"},{"fromBlock":3706091,"toBlock":21894191,"address":["0x54bcf4948e32a8706c286416e3ced37284f17fc9"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000755560f094b26e0e0a39a1dd7e47a3c4788830ec"]],"resultHash":"0xdd97c5982e0f2d107103ce0ef3254ccb3c1a69b5cd031b618b08ad12d29e9241"},{"fromBlock":3465199,"toBlock":21894191,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000693010a4d33112679ed95ffced9b47d778de52ba"]],"resultHash":"0x7f8e419c604abeebb32c74f7dbd24f401b148a4aa84a9cb1c7d06ef7b8c6b61f"},{"fromBlock":0,"toBlock":18866229,"address":["0xef68e7c694f40c8202821edf525de3782458639f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000cb049f3fada20d42fec84866bbd55246648e98a7"],["0x00000000000000000000000069ea6b31ef305d6b99bb2d4c9d99456fa108b02a"]],"resultHash":"0x34d50ab86df13d954ffba5f7840ee68ec06ceac641eddff5a73f3deae6227d5f"},{"fromBlock":4904975,"toBlock":21894159,"address":["0x7cc768b882be41ca03f9daccfc48b8bd6d25eb25"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xad8164b03737df9fe26e85aeaa8f52e34d862634cd3da65eb791f5beeddbffdd"},{"fromBlock":2961299,"toBlock":21253772,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000e80b1375ff7a498d5c28454fb60d79ad3434cfd2"]],"resultHash":"0x3e1b8eb8ed40a5b0e09e3b7737b02c8936cce6814ea973a642a9ec67ad2383eb"},{"fromBlock":1862102,"toBlock":21894159,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000002fbcf7714202a6996430436e67a4f11b17ed598a"]],"resultHash":"0x29c1edc31a7707c6dbeeb99685e6e6dcbbdeb69eed818f9e22ec58dd2b5b7139"},{"fromBlock":3224543,"toBlock":21893937,"address":["0x761d38e5ddf6ccf6cf7c55759d5210750b5d60f3"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000000ef7f9c5549165d204d8f440d1d84ea4f8c1dca4"]],"resultHash":"0xd064e462d2e964638bc8ee4fd6d87a764d55e0e9161a5b2b937a44d6fcc88fe3"},{"fromBlock":0,"toBlock":16729622,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000a666f70f6db2c204a19a2dd0272a96b8830387ed"]],"resultHash":"0x920c36b51d85a19ae89db401ea88821d20e89ff6596f2d03fa49ed02617323d9"},{"fromBlock":0,"toBlock":19855084,"address":["0x99ea4db9ee77acd40b119bd1dc4e33e1c070b80d"],"topics":[null,["0x0000000000000000000000000e590f8b856ecaf9acfd52ce03cd3cf1c525453f"],["0x0000000000000000000000003f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be"]],"resultHash":"0xe2f68f5f2ed2600f345f4e3ebbf41220784f3e471fe5338505fa36981d9086ee"},{"fromBlock":0,"toBlock":13467038,"address":["0x6531f133e6deebe7f2dce5a0441aa7ef330b4e53"],"topics":[null,null,["0x000000000000000000000000dea5585adcaafbe30e84ccd693214481c0daa4ee"]],"resultHash":"0x95f274fbc2ea9d7f4c96b809ba6cf8b3614e37814237005310f70f9aaac1cc44"},{"fromBlock":8566638,"toBlock":21754255,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a8ecaf8745c56d5935c232d2c5b83b9cd3de1f6a"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0xba23d0a7f5b565b4a5e5dc71595a83b193f8a8f2b53ba0fd6ae7421272f92092"},{"fromBlock":2660315,"toBlock":21893969,"address":["0xd1b3460f28681464d2b5cee4e71bb332c429ec1c"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45"],["0x000000000000000000000000e27f661ff53326f65cd6f89e5e789f3731e4001c"]],"resultHash":"0x67651677f9793a9aaca3518eac8ad47cf9a6acae30f9614df89545bfce345870"},{"fromBlock":421009,"toBlock":21894159,"address":["0x819f3450da6f110ba6ea52195b3beafa246062de"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000001111111254fb6c44bac0bed2854e76f90643097d"],["0x0000000000000000000000009620e9bc10597f68586fc61d38b86cd485191b70"]],"resultHash":"0xceba8cbdcb2206ae84fa0a86fb05dbbdcaaba3fe387627147c7e5ed3cfcec88f"},{"fromBlock":4828985,"toBlock":21894159,"address":["0x0652687e87a4b8b5370b05bc298ff00d205d9b5f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000007f46f400fadf8fe55a8b95e302175d8aea362337"]],"resultHash":"0x0f0b5af0d37251884abfdd2eb53112ef8ce5375144208fcebde60b0e7b1296c8"},{"fromBlock":4904975,"toBlock":21894159,"address":["0x7cc768b882be41ca03f9daccfc48b8bd6d25eb25"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xad8164b03737df9fe26e85aeaa8f52e34d862634cd3da65eb791f5beeddbffdd"},{"fromBlock":498010,"toBlock":21893810,"address":["0x777be1c6075c20184c4fd76344b7b0b7c858fe6b"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0x3da24d79906e2fc8145e02664af279d478f90c7bf930371e9d63f8b91ddc6d4b"},{"fromBlock":5620043,"toBlock":19365774,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x0000000000000000000000009b43c10b1cd9b18f8ba2f3e90025f51c4461262e"]],"resultHash":"0xf3242ab1d2f0356b6a31b6c42ee01ae4618a520b9d07fa0f983227c790ec4025"},{"fromBlock":3257732,"toBlock":21894063,"address":["0xb39304157227d684f28353fb7a016bd1c685da5f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000fe806c79275b249d87baa5dac4d21a594f240ad6"],["0x00000000000000000000000000000000000000000000000000000000000020a0"]],"resultHash":"0x3d87c080d653f5245823cfcd20a9ee759f48f450514e327c58223fd7ff65eef8"},{"fromBlock":3632042,"toBlock":20667694,"address":["0x7adb368141248d6c50b614aee3b6a9ef9f8c20bd"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000018c0ca3947e255881f94de50b3a906fc2759f7fe"],["0x00000000000000000000000018c0ca3947e255881f94de50b3a906fc2759f7fe"]],"resultHash":"0x50b2cf09e407a99bb098cc3f843e36bd3091beb7de66b95d00e840b8ff5a1daa"},{"fromBlock":1599354,"toBlock":21894159,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000046340b20830761efd32832a74d7169b29feb9758"],["0x0000000000000000000000002fbcf7714202a6996430436e67a4f11b17ed598a"]],"resultHash":"0x29c1edc31a7707c6dbeeb99685e6e6dcbbdeb69eed818f9e22ec58dd2b5b7139"},{"fromBlock":1211116,"toBlock":19491941,"address":["0xd77bcd9cf4212a41defbcd2e2ff0f50fea2be643"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000add9e07b04272f66c803f0e724f005a653e77040"],["0x0000000000000000000000003ce2a0101df6b034635f0bcec7a6cd9597768796"]],"resultHash":"0x1f4ed421c0a00145d68ee9b227e3ec707109cbad86dfdf2b942c4e3fe5a7d6d2"},{"fromBlock":498010,"toBlock":21893810,"address":["0x2f3c1a1c8d069b47cd756cbc22120ae82d61448e"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000005a47c638a0243a1f307e6a869f5140278da41921"],["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0x4efce609e4f2a7316d899d862a6ce4e7c923f0b4387fe4784a3bd9fb26de736a"},{"fromBlock":2416385,"toBlock":20517327,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000f3a71cc1be5ce833c471e3f25aa391f9cd56e1aa"],["0x0000000000000000000000001e6706370b007605347d2de24c2506152ca5a9d6"]],"resultHash":"0x694c173f7226a39786a148ca98fca04f8766a86cd71fa26d65299f69aa23eaff"},{"fromBlock":0,"toBlock":19274842,"address":["0x6531f133e6deebe7f2dce5a0441aa7ef330b4e53"],"topics":[null,["0x00000000000000000000000028a44f49b940b3875f882d08487d16295fb8bc09"],["0x000000000000000000000000dea5585adcaafbe30e84ccd693214481c0daa4ee"]],"resultHash":"0x95f274fbc2ea9d7f4c96b809ba6cf8b3614e37814237005310f70f9aaac1cc44"},{"fromBlock":3538090,"toBlock":21894191,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"],["0x0000000000000000000000000000000000000000000000000000000000000d5d"]],"resultHash":"0xf187387c8d5b4bf93705f26466651e78128cfe1e837dc362d976856d22e2a483"},{"fromBlock":287082,"toBlock":21894191,"address":["0x57fbb364041d860995ed610579d70727ac51e470"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"],["0x00000000000000000000000000000000000000000000000000000000000011eb"]],"resultHash":"0x05af91b100cbfdcf50d3a90f064557188605c58b383f0c1d9e523da99e510b03"},{"fromBlock":0,"toBlock":20539755,"address":["0xe65ee7c03bbb3c950cfd4895c24989afa233ef01"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000008ad4bfd99281f8a9e15f2668f701212050433a6a"],["0x000000000000000000000000f0073a6f7c86beb89c011a0f3e648dec980f16ec"]],"resultHash":"0x331c708ca4a7b826456ec0bb45426ab3649ca4236ef3671107664d56099d8d9f"},{"fromBlock":906415,"toBlock":21894127,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e9da256a28630efdc637bfd4c65f0887be1aeda8"],["0x0000000000000000000000008baf23f273edcf9cc3f51127e591f189115a2b8d"]],"resultHash":"0xade5ee4822e3d0dd9804ea249ccac7320daa51adc69d41af2ebdfbc20fddc390"},{"fromBlock":5620043,"toBlock":19365774,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000009b43c10b1cd9b18f8ba2f3e90025f51c4461262e"]],"resultHash":"0xf3242ab1d2f0356b6a31b6c42ee01ae4618a520b9d07fa0f983227c790ec4025"},{"fromBlock":0,"toBlock":21022866,"address":[],"topics":[["0xb51168059c83c860caf5b830c5d2e64c2172c6fb2fe9f25447d9838e18d93b60"],["0x00000000000000000000000000000000000000000000000000000004034e41c8"],["0x000000000000000000000000000000000000000000000000000000000000890c"]],"resultHash":"0xd5533c985ab1e771535a19b4728e758e5f2aff0c4a3305c1d5aa76898969544f"},{"fromBlock":7171052,"toBlock":21894191,"address":["0xce407cd7b95b39d3b4d53065e711e713dd5c5999"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000f3de3c0d654fda23dad170f0f320a92172509127"],["0x000000000000000000000000e14c3d81ee9d8684f8a4690dddb8139dece5d468"]],"resultHash":"0x152745971191f832343c99bb4ddd590117a30ea96101cdabdeb10349f1fe66f9"},{"fromBlock":3109653,"toBlock":21894031,"address":["0xb39304157227d684f28353fb7a016bd1c685da5f"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000ade336f3496452e5cb47a75649d14ca0823e7a11"],["0x0000000000000000000000000000000000000000000000000000000000001605"]],"resultHash":"0x359b612cd9fb37024b943193b42ffd7678172316ad789bdd87f469d035e60760"},{"fromBlock":3379313,"toBlock":21894159,"address":["0xa9ca155590671bbc01d7e1d95c0adec749e39cfc"],"topics":[["0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f"],null,["0x0000000000000000000000000000000000000000000000000000000000000043"]],"resultHash":"0x66e12d88814b935d5453d8cd5e9d59eed7c0453d8891ff4f0b5e47b639b87993"},{"fromBlock":738864,"toBlock":21893842,"address":["0x0a3aefdb58a03d7c30b2a063e1fd49c4cb5f8b60"],"topics":[null,["0x000000000000000000000000cdfaaa35d00f5b22cb8ff285c40e89b96d34adde"]],"resultHash":"0xb8c01edc4959040f50e685a3d785f80b1b0bd58d4a736f53b3972f7a200907fb"},{"fromBlock":0,"toBlock":20734392,"address":["0x7d3e7d41da367b4fdce7cbe06502b13294deb758"],"topics":[null,null,["0x000000000000000000000000c4af36f14bdb20d22ab27d8fbae5747aa166fbef"]],"resultHash":"0xbbfe86370c89fd29f9a0c742cf35da63a0809d4073684af9ea02c59a3c4163f9"},{"fromBlock":7828246,"toBlock":21329307,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[null,null,["0x0000000000000000000000003d5164cd6a0358cc1a7e98bdf3cabbd0f5ad92ba"]],"resultHash":"0x7a6967772e3e94d0a1c279da2a7aa22077b1dc7a21c449bb2ede85cbe14ef58e"},{"fromBlock":0,"toBlock":20330118,"address":[],"topics":[null,null,["0x000000000000000000000000cb22ebc93b4c58ffab85c28901585f186a1c604b"]],"resultHash":"0xad4c510ca89bd799f7396f01e6304a5808af0debe472cbb0f7ea98ebf270d0b6"},{"fromBlock":3810079,"toBlock":21894095,"address":[],"topics":[null,["0x000000000000000000000000833c907a80f892259ce75a880d714e6dd22509a3"],["0x000000000000000000000000399213292ad58cfd53517f4de23b853e5b5b60c8"]],"resultHash":"0xb7f67982419321110471a2a1fd12651e601885fb28b23a54b6e6ba60285b48c9"},{"fromBlock":6042343,"toBlock":21077039,"address":["0x94693c9e342f759272d6f7b481703df8e83b1818"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000004310aa2dd0f78635fa6409f4ef5a388f0458ab17"]],"resultHash":"0x78c8b6221b0d8a6ebba35124e89ccbb6dc3b01937fc4d84ac25187504b5f69f7"},{"fromBlock":622631,"toBlock":20195871,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000d2cf555449596b91150b1daec11682ec8b0ea8ca"]],"resultHash":"0x414f91848de83541f15e232ee0e071cd273df9f27ff3c4d3c4fafd0ed8ca285f"},{"fromBlock":0,"toBlock":19930598,"address":[],"topics":[null,["0x000000000000000000000000dd2a23c77372725018593b631241cafec8b78a06"]],"resultHash":"0x833319f0cb334002ad70d983534b274fb719abcbbcafa0afd811bef1e391413d"},{"fromBlock":3451035,"toBlock":21893937,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x000000000000000000000000a3338b2b1a2cdfc448832ac1a511b628a24e7b77"]],"resultHash":"0x41bde228497f768920951f4c84f8997648fef7cd7dc89799d6abcf4a61f638e9"},{"fromBlock":0,"toBlock":19438664,"address":["0x99ea4db9ee77acd40b119bd1dc4e33e1c070b80d"],"topics":[null,["0x0000000000000000000000000e590f8b856ecaf9acfd52ce03cd3cf1c525453f"]],"resultHash":"0xe2f68f5f2ed2600f345f4e3ebbf41220784f3e471fe5338505fa36981d9086ee"},{"fromBlock":2404893,"toBlock":21894159,"address":["0xe12af1218b4e9272e9628d7c7dc6354d137d024e"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000001ede2d0da4834df237b47b603b8e0c7a1bc2885a"]],"resultHash":"0x4853351d5aa917e8fe609d41d5f436b4b74cb37d7ae43b406167b56714d43dd4"},{"fromBlock":4716258,"toBlock":18636602,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000da478cdb499f3509d399fa3823a70ec40c7777e2"]],"resultHash":"0xe0a01952780a5dcc5c2c1a1512a7ca49db368b8b0f3efc1a35019b90911fdd9a"},{"fromBlock":3545156,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000000000000c2cf7648c169b25ef1c217864bfa38cc"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"],["0x000000000000000000000000ba11d00c5f74255f56a5e366f4f77f5a186d7f55"]],"resultHash":"0x9d54ba92b3a367f2c9cff8736229388b5f78141f35d0aea59e82576f1e656c4e"},{"fromBlock":1444933,"toBlock":21894063,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"],["0x00000000000000000000000000000000000000000000000000000000000011ec"]],"resultHash":"0x857867a9f4c926cb2af98810f7b5502a1cfbd8bf8a403eb9567a2e20b3526921"},{"fromBlock":2680494,"toBlock":21893873,"address":["0x1580eb65edb0b903e7b3624ca963219d0c5c565e"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000007af443393b95d2ee5ebdaab98dc2b0778a789e0f"],["0x000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3"]],"resultHash":"0x3254c9032fa38e8f54bc610b2eea0c47c04bad497e89c92afc108e5f75199cd1"},{"fromBlock":7807822,"toBlock":21470616,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x0000000000000000000000004cefd3a57ee8e1d6a3f564bb297254c51aeeb4ed"]],"resultHash":"0x96439488568de0496fb59522f750cf1fa4a1911648e45771daca8c13971f28d5"},{"fromBlock":0,"toBlock":16861090,"address":["0x6531f133e6deebe7f2dce5a0441aa7ef330b4e53"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000dea5585adcaafbe30e84ccd693214481c0daa4ee"]],"resultHash":"0x95f274fbc2ea9d7f4c96b809ba6cf8b3614e37814237005310f70f9aaac1cc44"},{"fromBlock":2048677,"toBlock":21894159,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000397ff1542f962076d0bfe58ea045ffa2d347aca0"]],"resultHash":"0xe1eeca04cfaaaeac8bf0a1b4680a47c09d3940f63e4fd61d69db922affdfff9c"},{"fromBlock":3109653,"toBlock":21894031,"address":["0xb39304157227d684f28353fb7a016bd1c685da5f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000ade336f3496452e5cb47a75649d14ca0823e7a11"],["0x0000000000000000000000000000000000000000000000000000000000001605"]],"resultHash":"0x359b612cd9fb37024b943193b42ffd7678172316ad789bdd87f469d035e60760"},{"fromBlock":2741398,"toBlock":21894063,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x0000000000000000000000007e9771d2ffcebfc97fd6e84927b964c787cfc698"]],"resultHash":"0xacfdcba31145ad71b6f1ca9e32e309f69c5cd48bb9b0f28691ae83267a9e1b68"},{"fromBlock":0,"toBlock":16729622,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000a666f70f6db2c204a19a2dd0272a96b8830387ed"]],"resultHash":"0x920c36b51d85a19ae89db401ea88821d20e89ff6596f2d03fa49ed02617323d9"},{"fromBlock":1302339,"toBlock":19803394,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000871a30f835e293304c153c2ea619316c02658e61"]],"resultHash":"0xdb1181afa524366ae5bd24ac234b5d9b79a5c5353a78ba60a758887bca3f202b"},{"fromBlock":1418458,"toBlock":21410675,"address":["0x6b3595068778dd592e39a122f4f5a5cf09c90fe2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000009420fdfcb670db7e97d2da5dd8b8f66b11309ab9"]],"resultHash":"0xb5a94e8dc48c525ddafafa303537b6340f7d0adb2a82723c7a814161c3bd26e3"},{"fromBlock":0,"toBlock":16628811,"address":["0xbcf935d206ca32929e1b887a07ed240f0d8ccd22"],"topics":[null,null,["0x00000000000000000000000018a65ae8a292df5f460c5dec1ca08850e66e02df"]],"resultHash":"0x58577c7f75523485356582c2830144c0e66838e80dd5c6d38f6c3119c192865e"},{"fromBlock":0,"toBlock":14447940,"address":["0xe65ee7c03bbb3c950cfd4895c24989afa233ef01"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000f0073a6f7c86beb89c011a0f3e648dec980f16ec"]],"resultHash":"0x331c708ca4a7b826456ec0bb45426ab3649ca4236ef3671107664d56099d8d9f"},{"fromBlock":0,"toBlock":21022866,"address":["0x79febf6b9f76853edbcbc913e6aae8232cfb9de9"],"topics":[["0xb51168059c83c860caf5b830c5d2e64c2172c6fb2fe9f25447d9838e18d93b60"],["0x00000000000000000000000000000000000000000000000000000004034e41c8"]],"resultHash":"0xd5533c985ab1e771535a19b4728e758e5f2aff0c4a3305c1d5aa76898969544f"},{"fromBlock":1123728,"toBlock":21894159,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000021a31ee1afc51d94c2efccaa2092ad1028285549"],["0x0000000000000000000000008f9f8721b1dfa254bf877172edc87389a89dd304"]],"resultHash":"0x93fdeba5de28f09205eb7d30a8f1ebdb2b6f6bc176eeb31e32e0f7ef7913d873"},{"fromBlock":1907920,"toBlock":21894159,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x00000000000000000000000040e10218e0ab001b109d9f9ca96c8487c457e65f"]],"resultHash":"0x576f6817c2edb9891a88866339ca70e51e9a118b27bc46ee87decc0181599798"},{"fromBlock":372054,"toBlock":21894191,"address":[],"topics":[null,null,["0x000000000000000000000000be70287dc323b6f2596147f7566596f183aaf767"]],"resultHash":"0x328357832df217f377f33e1cf943db52f51da5feda61b0ce5da3584696839c44"},{"fromBlock":0,"toBlock":16729622,"address":["0x701c244b988a513c945973defa05de933b23fe1d"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000a666f70f6db2c204a19a2dd0272a96b8830387ed"]],"resultHash":"0x920c36b51d85a19ae89db401ea88821d20e89ff6596f2d03fa49ed02617323d9"},{"fromBlock":1801832,"toBlock":21893873,"address":["0xb39304157227d684f28353fb7a016bd1c685da5f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000071042f6b3aaae4b7cceaa0abee9b151a0c109cc0"],["0x000000000000000000000000000000000000000000000000000000000000121a"]],"resultHash":"0x4bdb9baaed99ff24c10df0be65a901dd173fdb9f233e20301dea29d91d9f547d"},{"fromBlock":3199906,"toBlock":21894159,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x00000000000000000000000040e10218e0ab001b109d9f9ca96c8487c457e65f"]],"resultHash":"0x576f6817c2edb9891a88866339ca70e51e9a118b27bc46ee87decc0181599798"},{"fromBlock":3810079,"toBlock":21894095,"address":[],"topics":[null,null,["0x000000000000000000000000399213292ad58cfd53517f4de23b853e5b5b60c8"]],"resultHash":"0xb7f67982419321110471a2a1fd12651e601885fb28b23a54b6e6ba60285b48c9"},{"fromBlock":0,"toBlock":16999593,"address":["0xef68e7c694f40c8202821edf525de3782458639f"],"topics":[null,["0x000000000000000000000000cb049f3fada20d42fec84866bbd55246648e98a7"],["0x00000000000000000000000069ea6b31ef305d6b99bb2d4c9d99456fa108b02a"]],"resultHash":"0x34d50ab86df13d954ffba5f7840ee68ec06ceac641eddff5a73f3deae6227d5f"},{"fromBlock":3580144,"toBlock":21894095,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000c50c79ed8bc14643f344836170f3a6b2624d2a33"]],"resultHash":"0x0313656e7b513b060cfb8f496fb232ca37a29091095b65e48dc811012d95eb59"},{"fromBlock":0,"toBlock":19930598,"address":[],"topics":[["0x56b138798bd325f6cc79f626c4644aa2fd6703ecb0ab0fb168f883caed75bf32"],["0x000000000000000000000000dd2a23c77372725018593b631241cafec8b78a06"]],"resultHash":"0x833319f0cb334002ad70d983534b274fb719abcbbcafa0afd811bef1e391413d"},{"fromBlock":5620043,"toBlock":19365774,"address":["0x17890deb188f2de6c3e966e053da1c9a111ed4a5"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000009b43c10b1cd9b18f8ba2f3e90025f51c4461262e"]],"resultHash":"0xf3242ab1d2f0356b6a31b6c42ee01ae4618a520b9d07fa0f983227c790ec4025"},{"fromBlock":498010,"toBlock":21893810,"address":["0x2f3c1a1c8d069b47cd756cbc22120ae82d61448e"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000005a47c638a0243a1f307e6a869f5140278da41921"],["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0x4efce609e4f2a7316d899d862a6ce4e7c923f0b4387fe4784a3bd9fb26de736a"},{"fromBlock":3456602,"toBlock":21893842,"address":["0x77fba179c79de5b7653f68b5039af940ada60ce0"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000c384ac6ee27c39e2f278c220bdfa5baed626d9d3"],["0x00000000000000000000000011111112542d85b3ef69ae05771c2dccff4faa26"]],"resultHash":"0xd46a1ffef28d97ebeffd97b8191389658058ecbe161bbd47e08d852e0128bfcf"},{"fromBlock":4140627,"toBlock":21894191,"address":["0x13cc598e8a2257e7e87407b6e79c00f7692361fa"],"topics":[null,null,null,["0x000000000000000000000000000000000000000000000000000000000000120d"]],"resultHash":"0x1eb870085ea988166d33d2e00b0beb3173e8756f19bdac1a54c7944849160c60"},{"fromBlock":6867998,"toBlock":21894063,"address":["0x34d7d7aaf50ad4944b70b320acb24c95fa2def7c"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000ab48272303c177e18d63605cb78aeecf38aae93d"]],"resultHash":"0x95ff39ceac35a9c52e814322de10ac2b0d31c0704c8e2a444b6e6ba084e08ec4"},{"fromBlock":1083496,"toBlock":21894031,"address":["0x6a091a3406e0073c3cd6340122143009adac0eda"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000e70101ac5d6db9f867eb53bb80220b85af488c4f"]],"resultHash":"0x745d6e0f22d646ef637684106f46bd082d94db4324c44e9d641a2146b768abb0"},{"fromBlock":3451035,"toBlock":21893937,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x000000000000000000000000a3338b2b1a2cdfc448832ac1a511b628a24e7b77"]],"resultHash":"0x41bde228497f768920951f4c84f8997648fef7cd7dc89799d6abcf4a61f638e9"},{"fromBlock":3740924,"toBlock":20457747,"address":["0xe12af1218b4e9272e9628d7c7dc6354d137d024e"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000139ff314a62816d7d4d10c05c77b870169ecc7f0"]],"resultHash":"0x9dfca1a50f07ccf47a38cdd07df8367e1096a5ea1b70f45633e1a8a9db3c65d6"},{"fromBlock":906415,"toBlock":21894127,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000008baf23f273edcf9cc3f51127e591f189115a2b8d"]],"resultHash":"0xbbfe49a3c06c3021c24bb05e9d52f932cf480dff6145c504d7bd8e0b9c31d370"},{"fromBlock":498010,"toBlock":21893810,"address":["0x2f3c1a1c8d069b47cd756cbc22120ae82d61448e"],"topics":[null,["0x0000000000000000000000005a47c638a0243a1f307e6a869f5140278da41921"],["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0x4efce609e4f2a7316d899d862a6ce4e7c923f0b4387fe4784a3bd9fb26de736a"},{"fromBlock":5606654,"toBlock":21894095,"address":["0xae7ab96520de3a18e5e111b5eaab095312d7fe84"],"topics":[["0x9d9c909296d9c674451c0c24f02cb64981eb3b727f99865939192f880a755dcb"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000001341e0bf0ecd9d7df015c14a1fa33d2d4cc5ec1c"]],"resultHash":"0xed3fbe8e1157541bd8a0143c68d9ff31ffca40646983fb4b99a18a269b2d75d2"},{"fromBlock":293890,"toBlock":21894127,"address":["0x170217d48f8c9388f67ca2c65ef48e55a1352cc6"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0xe7c820dbb8ce25cd9a2d2c9e72be14ccbeedfcef7e37e831e940b95a8e90885b"},{"fromBlock":2334639,"toBlock":21894191,"address":[],"topics":[null,null,["0x0000000000000000000000001fcab39c506517d0cc2a12d49ebe5b98f415ed92"],["0x000000000000000000000000000000000000000000000000000000000000120d"]],"resultHash":"0x91205f17941cc3e0b4ba7b8690e197df0325321e15783e22279583dd783456b0"},{"fromBlock":3200760,"toBlock":19454437,"address":[],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000011bab7"],null],"resultHash":"0xe1fea93b1d7528c1503d031a2707af1c3a885c8447c904b1655fc18858541176"},{"fromBlock":3224543,"toBlock":21893937,"address":["0x761d38e5ddf6ccf6cf7c55759d5210750b5d60f3"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007b73644935b8e68019ac6356c40661e1bc315860"],["0x0000000000000000000000000ef7f9c5549165d204d8f440d1d84ea4f8c1dca4"]],"resultHash":"0xd064e462d2e964638bc8ee4fd6d87a764d55e0e9161a5b2b937a44d6fcc88fe3"},{"fromBlock":319309,"toBlock":21894063,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000046340b20830761efd32832a74d7169b29feb9758"],["0x0000000000000000000000003d5164cd6a0358cc1a7e98bdf3cabbd0f5ad92ba"]],"resultHash":"0x7a6967772e3e94d0a1c279da2a7aa22077b1dc7a21c449bb2ede85cbe14ef58e"},{"fromBlock":775754,"toBlock":21894159,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000ca05da65c7f83a30556ffffb035e58bada4d9ccf"],null,["0x000000000000000000000000000000000000000000000000000000000000263e"]],"resultHash":"0x5d5a0e928847050f90304dba3ea031233394fb9200180ad4c93926552fe09823"},{"fromBlock":287082,"toBlock":21894191,"address":["0x57fbb364041d860995ed610579d70727ac51e470"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"],["0x00000000000000000000000000000000000000000000000000000000000011eb"]],"resultHash":"0x05af91b100cbfdcf50d3a90f064557188605c58b383f0c1d9e523da99e510b03"},{"fromBlock":8556647,"toBlock":21894095,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000002fbcf7714202a6996430436e67a4f11b17ed598a"]],"resultHash":"0x29c1edc31a7707c6dbeeb99685e6e6dcbbdeb69eed818f9e22ec58dd2b5b7139"},{"fromBlock":4414787,"toBlock":21894031,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000213d374a227141834e64675ba9b6571a813a007a"]],"resultHash":"0x99ef87ca1c5de134684566fabf00d722eeade1494e45f40be5e6bb41f7f77a48"},{"fromBlock":904105,"toBlock":21894159,"address":["0xce407cd7b95b39d3b4d53065e711e713dd5c5999"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000f3de3c0d654fda23dad170f0f320a92172509127"],["0x000000000000000000000000e14c3d81ee9d8684f8a4690dddb8139dece5d468"]],"resultHash":"0x152745971191f832343c99bb4ddd590117a30ea96101cdabdeb10349f1fe66f9"}],[{"fromBlock":7486286,"toBlock":21418779,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null,["0x000000000000000000000000e137faa86acba1b35efccc22195bcd1707cc7176"]],"resultHash":"0xa5b400a951ac47b2cca28944e71ade85a78538095ef24292fb193032f30bb2ed"},{"fromBlock":7999897,"toBlock":21894191,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000005c57ac8dc5d8589dab9d422993ed3de8cc244151"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0xf9e68e76f28865140de9ac09af771d1bfb81fdc7864eb42dc29ae974b33c2fe5"},{"fromBlock":582435,"toBlock":21894159,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x752c774441aafb1bad7989a4956cf5ad05aaf9ee2950f75a42c51e6972011bb5"},{"fromBlock":498010,"toBlock":21893810,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"],["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0xb233781eb14a1512d29f99d35730b5afb56981ca4e77c6d44f75d1d74792f4ab"},{"fromBlock":377138,"toBlock":21894159,"address":["0xdff71165a646be71fcfbaa6206342faa503aed5d"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000755560f094b26e0e0a39a1dd7e47a3c4788830ec"]],"resultHash":"0x3e2bb28b01522a480a070771f1207e7fe672100d2afa578876384a6524a614a3"},{"fromBlock":498010,"toBlock":21893810,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0xc4ccb46ec96cae5adfbdc436ab2fe197adb88b88f09b440f8f1abeed011e46c1"},{"fromBlock":582435,"toBlock":21894159,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x752c774441aafb1bad7989a4956cf5ad05aaf9ee2950f75a42c51e6972011bb5"},{"fromBlock":719383,"toBlock":18717181,"address":[],"topics":[null,["0x000000000000000000000000fbb1b73c4f0bda4f67dca266ce6ef42f520fbb98"],["0x000000000000000000000000180148c00c8a3951f29baaea949f5dcbdceed7ae"]],"resultHash":"0x3bb3883be73827a6f278beca009de972a0b6d9533df1c04ea4816535b088b7a1"},{"fromBlock":2346116,"toBlock":21894127,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000009f817c535f01d0233ad003be4b6872204d4e374c"],["0x000000000000000000000000e49849f768e114bf06a4d715f6aca57c6cc0c35f"]],"resultHash":"0x3ea126ad3557ebf90124145fe8952c7d7dacfa6c3ee76a4dcb35502219f17e96"},{"fromBlock":757877,"toBlock":21894095,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0x6fb33727d5d9f1fcd986957b11f0a4c2a95bd35070af3ae868c64ca15a3b353b"},{"fromBlock":665080,"toBlock":21894159,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000000000000000a84d1a9b0063a910315c7ffa9cd248"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x8592daf1002c678ea61d3c4bf1b61565e1a1de1f1f5dd936003ee1b6f06e09d6"},{"fromBlock":1058578,"toBlock":21894127,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000000000000c2cf7648c169b25ef1c217864bfa38cc"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xa81fe6571947d1abc79e23b0927bac9058677f353a2a41b4ac9bdba0428d87cf"},{"fromBlock":2306836,"toBlock":21893842,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000000c4b632b389b09b0c6b546f5dbbb15bffad0961e"]],"resultHash":"0xffb3bdd75029ea4098f6a0de6fbb3ce19fe5381acb51b2bbe845c7af15d66d14"},{"fromBlock":1708350,"toBlock":19452274,"address":[],"topics":[null,["0x00000000000000000000000030aeb40fdd5165bed9e39c9b20557776329c0617"]],"resultHash":"0x4cd609a7ec7d0df36b9724850f7bb1f5a811c7e910603e67a4452c582e02c944"},{"fromBlock":779698,"toBlock":21893842,"address":[],"topics":[["0xa55c5f48fd29482ad55f4b59bf070cd1ac1a7132a31f7a136ebe8877ae37e1ff"],["0x000000000000000000000000c384ac6ee27c39e2f278c220bdfa5baed626d9d3"]],"resultHash":"0x613dfdefe3d0b316c44294f684ba20fcb92d1ca71e44a5270cdd1822c78890f3"},{"fromBlock":3778080,"toBlock":21894191,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000000000000c2cf7648c169b25ef1c217864bfa38cc"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x45402fdb57ea6cf2041718497f22b7eab9d97c6d8fb8b164b7175bc93ee15734"},{"fromBlock":0,"toBlock":20002094,"address":[],"topics":[null,null,["0x000000000000000000000000c4af36f14bdb20d22ab27d8fbae5747aa166fbef"]],"resultHash":"0xff78ca5991f7a203f28cf54ba9f74e9174db740cd34060d7c8ff2168d01e80b3"},{"fromBlock":8480619,"toBlock":21894159,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000009aef7c447f6bc8d010b22aff52d5b67785ed942c"]],"resultHash":"0x3229c8c2513fa6a3bf1ea76112b049bd5be3114b6ebedb5ffbac0b69055409f6"},{"fromBlock":873698,"toBlock":16384126,"address":["0xd77bcd9cf4212a41defbcd2e2ff0f50fea2be643"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000009d64dbe82a38b3e2a75bf44e4a91b2bfa8b86133"],["0x000000000000000000000000a8b3bf51e1bb5e227ec683e1bdf7f1f5110bfacc"]],"resultHash":"0xa80667ef9375b923773d663e85401df535ab608624e773fcc2e5d61c6bea77c9"},{"fromBlock":4993374,"toBlock":17708487,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000ade2edad8d2f3a5bd43d11948de9f55973f9ce07"]],"resultHash":"0xaec12a2645aa97caa72437efc1f368cfde740e267f4b96c1c3ef9c138a8aba91"},{"fromBlock":1770218,"toBlock":21894031,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000f207e674b23183b75b7dd59cd0a579f75a6d36d9"]],"resultHash":"0xd0e21e41daca0166dbb942c51eef7b76e0b98d3754d958bd94b743f9de60d7fa"},{"fromBlock":317883,"toBlock":21894127,"address":["0x7ad4780dfa1624ad1dca5d514c90ea7cf6eb37f9"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000008fe7d9643077b4ab2885cb2dad4236cc4784413f"],["0x0000000000000000000000008f19fff300a55dc8d2c5f321526b1647589cab58"]],"resultHash":"0x4e5d507dd096467034606fc747e037ea8716fbf9b760d8006389ed8b735ffc82"},{"fromBlock":779698,"toBlock":21893842,"address":["0x24179cd81c9e782a4096035f7ec97fb8b783e007"],"topics":[["0xa55c5f48fd29482ad55f4b59bf070cd1ac1a7132a31f7a136ebe8877ae37e1ff"],["0x000000000000000000000000c384ac6ee27c39e2f278c220bdfa5baed626d9d3"]],"resultHash":"0x613dfdefe3d0b316c44294f684ba20fcb92d1ca71e44a5270cdd1822c78890f3"},{"fromBlock":5837444,"toBlock":21893238,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000005dd6b9daa65838079c56f148a2daea8b6fe3ee6b"]],"resultHash":"0xcf9b313d36c9996f76ec25f1da8b2f03e5a79446c9e93d74f6397c5f82aebc5f"},{"fromBlock":1018734,"toBlock":21894191,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000000000000c2cf7648c169b25ef1c217864bfa38cc"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x4ca589d6231f064c8662886d3d797a9f111016f2b839a407871ec39f00a27d34"},{"fromBlock":0,"toBlock":18643412,"address":["0x6a091a3406e0073c3cd6340122143009adac0eda"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000755560f094b26e0e0a39a1dd7e47a3c4788830ec"]],"resultHash":"0x3e2ff1930e720e2ccade825ceb95022b99d524813c81bd3609c055d8597bd825"},{"fromBlock":498010,"toBlock":21893810,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0xc4ccb46ec96cae5adfbdc436ab2fe197adb88b88f09b440f8f1abeed011e46c1"},{"fromBlock":1375339,"toBlock":19288373,"address":[],"topics":[null,["0x00000000000000000000000070ebe06a95996b1a0adcbc104b6260f087005d64"]],"resultHash":"0x7c064d9c1b629735974686d55a8b82fba5cfa00af5e7385787da00894da412f9"},{"fromBlock":3522755,"toBlock":20703757,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x0000000000000000000000008d90113a1e286a5ab3e496fbd1853f265e5913c6"]],"resultHash":"0x924731ecaeaa5e4a568f41361a28db7e9cc86423a5858f82274d9d4781406953"},{"fromBlock":1055911,"toBlock":21894191,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x752c774441aafb1bad7989a4956cf5ad05aaf9ee2950f75a42c51e6972011bb5"},{"fromBlock":3246943,"toBlock":21894063,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000000eae044f00b0af300500f090ea00027097d03000"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599"]],"resultHash":"0xda5d61491acbe4063f22dd9836de638ff8a6cb9235f49d7d0eb65c4292a2b2c0"},{"fromBlock":3687824,"toBlock":21894191,"address":[],"topics":[null,["0x0000000000000000000000009f817c535f01d0233ad003be4b6872204d4e374c"],["0x000000000000000000000000e49849f768e114bf06a4d715f6aca57c6cc0c35f"]],"resultHash":"0x3ea126ad3557ebf90124145fe8952c7d7dacfa6c3ee76a4dcb35502219f17e96"},{"fromBlock":0,"toBlock":18643412,"address":["0x6a091a3406e0073c3cd6340122143009adac0eda"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000755560f094b26e0e0a39a1dd7e47a3c4788830ec"]],"resultHash":"0x3e2ff1930e720e2ccade825ceb95022b99d524813c81bd3609c055d8597bd825"},{"fromBlock":2291900,"toBlock":21894063,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000000000000000a84d1a9b0063a910315c7ffa9cd248"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x0402502a2cadff21607d273db245589c81a4a292374f2f018f0ab09f160fcb99"},{"fromBlock":2990473,"toBlock":21894191,"address":["0x48ab01de6f130a794c92c1fa260750e805e3a48a"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"]],"resultHash":"0xddc4c3add50a1d24e89edaa609b2984d3e74b552272f1d7e477678f717b05509"},{"fromBlock":2306836,"toBlock":21893842,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000ced92fa7f0797cbc851b48140ae218a0b0d41ce0"],["0x0000000000000000000000000c4b632b389b09b0c6b546f5dbbb15bffad0961e"]],"resultHash":"0x915580b8360c7df84f4ebc2e6171b64d1087fce792c640c67607d6594e405c0f"},{"fromBlock":1018734,"toBlock":21894191,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000000000000c2cf7648c169b25ef1c217864bfa38cc"],null,["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0xa00d6abe5fb30be437f037ad126714b0089c50af8d8232e0f6e23dfee30906c0"},{"fromBlock":3900190,"toBlock":21894159,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000000000000000a84d1a9b0063a910315c7ffa9cd248"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x8592daf1002c678ea61d3c4bf1b61565e1a1de1f1f5dd936003ee1b6f06e09d6"},{"fromBlock":1018734,"toBlock":21894191,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000000000000c2cf7648c169b25ef1c217864bfa38cc"],["0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x9e2fd8fe2084ce391d23074bab8d5c62c2c30d890f10cd567352f1e95dc3f660"},{"fromBlock":0,"toBlock":18643412,"address":["0x6a091a3406e0073c3cd6340122143009adac0eda"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000755560f094b26e0e0a39a1dd7e47a3c4788830ec"]],"resultHash":"0x3e2ff1930e720e2ccade825ceb95022b99d524813c81bd3609c055d8597bd825"},{"fromBlock":0,"toBlock":14447940,"address":[],"topics":[null,null,["0x000000000000000000000000f0073a6f7c86beb89c011a0f3e648dec980f16ec"]],"resultHash":"0x55a78fcf6ff6c8def7ab563511d0e35541369d8be9f2afb9a25faf0d9c84f9d3"},{"fromBlock":0,"toBlock":19467161,"address":[],"topics":[null,["0x2d71caede3523746c9bec44231534e5645f562180b5cfb76522cc731447b0371"]],"resultHash":"0x53fc19021225397776d671bbf46b22c4cadb52f38e32489fa9d9913b0b016546"},{"fromBlock":4811934,"toBlock":19243856,"address":["0x7818a7e2ab095a15dcb348c7dd6d1d88d7ceabfd"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000755560f094b26e0e0a39a1dd7e47a3c4788830ec"]],"resultHash":"0xbccf526ce3d1c8a0cd85657f716c68dcd413ded39eaa29c85269f712adab9394"},{"fromBlock":3860688,"toBlock":17071003,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000009c13b9c6bcc19ba14f309bf823304ad71c652211"]],"resultHash":"0x5449930c0f355976a0ef0bd57ebc7693edf49710b436ce33d6190a307e701361"},{"fromBlock":2832850,"toBlock":21132336,"address":["0xcffdded873554f362ac02f8fb1f02e5ada10516f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000001a1527a5127f721a4c9ff955c93f6faef2f6deb"]],"resultHash":"0xc305ca64b1593584ff364d2fcb57447e7f6e587a98bddf2058f17f512c7ba802"},{"fromBlock":0,"toBlock":20289029,"address":["0xd77bcd9cf4212a41defbcd2e2ff0f50fea2be643"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b3ab7423fede87c31e77163e3a90d20445eca0b3"],["0x00000000000000000000000062c50f2dfd68daef43b38acb22a32626fe5071c2"]],"resultHash":"0x18c42a6fdcfe73c384bbfd940c6cb4924f727edee85c2d1e5d2ab02aa4f3cbc8"},{"fromBlock":1770218,"toBlock":21894031,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000f207e674b23183b75b7dd59cd0a579f75a6d36d9"]],"resultHash":"0xd0e21e41daca0166dbb942c51eef7b76e0b98d3754d958bd94b743f9de60d7fa"},{"fromBlock":498010,"toBlock":21893810,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"],["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0xb233781eb14a1512d29f99d35730b5afb56981ca4e77c6d44f75d1d74792f4ab"},{"fromBlock":2076442,"toBlock":18707645,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000005c19b9abcfe6791ddb319cb909b20049a5076c53"],null],"resultHash":"0xd706ba50d02d39be5990069d9fa7e1a2ac783a8f21a6191fa0b83a6e00685fde"},{"fromBlock":1560895,"toBlock":21894095,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000045e2aa1483a1c02f1e7d07ff904bb1ded9350ab7"]],"resultHash":"0xb1ba5a4d19da809d9f365903a1e1c0f4751004abe670cdf33511eb374e644951"},{"fromBlock":2346116,"toBlock":21894127,"address":[],"topics":[null,["0x0000000000000000000000009f817c535f01d0233ad003be4b6872204d4e374c"],["0x000000000000000000000000e49849f768e114bf06a4d715f6aca57c6cc0c35f"]],"resultHash":"0x3ea126ad3557ebf90124145fe8952c7d7dacfa6c3ee76a4dcb35502219f17e96"},{"fromBlock":4505710,"toBlock":17219835,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000b94fb3cc45c11b3e1dffbc12490537a78306f1fe"]],"resultHash":"0x186f159071b0889db778ba273294d842c0c606c8517d8d58c85bd951f065a499"},{"fromBlock":3985702,"toBlock":21893842,"address":["0x767fe9edc9e0df98e07454847909b5e959d7ca0e"],"topics":[["0x769254a71d2f67d8ac6cb44f2803c0d05cfbcf9effadb6a984f10ff9de3df6c3"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000004d82a8afdf423681b60811943015c26d0c796ae9"],["0x0000000000000000000000006a091a3406e0073c3cd6340122143009adac0eda"]],"resultHash":"0xa8d522ca3a5c01ada33c3b7cd7dbdb5f0ac274f6a743f13156a2e78900e1ab55"},{"fromBlock":6550738,"toBlock":21893999,"address":["0x80d77b4ae7cd0d7a21fd3c1b2da25a4a06b63923"],"topics":[null,["0x000000000000000000000000bda13cbdadd055527ce95d82d39580a5cb412782"]],"resultHash":"0x13755de37725e0b2bdf8fe4e3b85beed3b1e9e9f152f52cf9c3898019120b1b3"},{"fromBlock":561656,"toBlock":20425331,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000030aeb40fdd5165bed9e39c9b20557776329c0617"]],"resultHash":"0x8a3550182f1e5f7e12327e4d01a584f502c6814aaae94b5c487c9308dfb70c74"},{"fromBlock":3262923,"toBlock":18342784,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000ade2edad8d2f3a5bd43d11948de9f55973f9ce07"]],"resultHash":"0xaec12a2645aa97caa72437efc1f368cfde740e267f4b96c1c3ef9c138a8aba91"},{"fromBlock":2306836,"toBlock":21893842,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null,["0x0000000000000000000000000c4b632b389b09b0c6b546f5dbbb15bffad0961e"]],"resultHash":"0xb34a8e5b2cee1218497c013cbedd2dc209148625c2f95723b6843e1e810022b1"},{"fromBlock":1708350,"toBlock":19452274,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000030aeb40fdd5165bed9e39c9b20557776329c0617"]],"resultHash":"0x4cd609a7ec7d0df36b9724850f7bb1f5a811c7e910603e67a4452c582e02c944"},{"fromBlock":8963773,"toBlock":21894191,"address":["0xf0ab9667469334bf7943406d766f4c48c05c6820"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45"],["0x000000000000000000000000c44c70fbfef750862fbcf73f5197a28bcaa11253"]],"resultHash":"0x43a1943da819df4a35110a267470fce49de100a869667b4d4e7af78caa57e220"},{"fromBlock":3226696,"toBlock":16587445,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000006637e824c12e1e9b4d0ba8bf0b12874e37192990"]],"resultHash":"0x5bc03006dfa8b7be0eb330ba9b224fb6ebe064424c43ec368a5e2d9a16048e2b"},{"fromBlock":1560895,"toBlock":21894095,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000045e2aa1483a1c02f1e7d07ff904bb1ded9350ab7"]],"resultHash":"0xb1ba5a4d19da809d9f365903a1e1c0f4751004abe670cdf33511eb374e644951"},{"fromBlock":1680976,"toBlock":20417273,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000030aeb40fdd5165bed9e39c9b20557776329c0617"],["0x0000000000000000000000006748f50f686bfbca6fe8ad62b22228b87f31ff2b"]],"resultHash":"0xf3fc5412340be8676ca9479b03e23ab67c67ab4cc7564fe2167e30f537ff5ec7"},{"fromBlock":0,"toBlock":19835735,"address":["0xdd9fd6b6f8f7ea932997992bbe67eabb3e316f3c"],"topics":[["0x590bbc0fc16915a85269a48f74783c39842b7ae9eceb7c295c95dbe8b3ec7331"],["0x0000000000000000000000000000000000000000000000000000000000000c9d"],["0x0000000000000000000000000000000000000000000000000000000000000001"],["0x00000000000000000000000000000000000000000000000000000000000074fe"]],"resultHash":"0x70404ee2c4a20b754b8260b4547c2c76d9ad602572b2b838f20504eb69b6cdbf"},{"fromBlock":5577609,"toBlock":21894191,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b89eb49bc337d2bfaee360ec63ad606b6788ceb2"],["0x000000000000000000000000e137faa86acba1b35efccc22195bcd1707cc7176"]],"resultHash":"0xa5b400a951ac47b2cca28944e71ade85a78538095ef24292fb193032f30bb2ed"},{"fromBlock":7174588,"toBlock":21893905,"address":["0x5c9921d0dcdd854525f89c62c3a0d8561e182cae"],"topics":[["0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"]],"resultHash":"0xb592363268cfee9c79d93f49e76ce8bd7ba48f63bdcb2e4f5a1cd136ebbef46a"},{"fromBlock":3246340,"toBlock":18546544,"address":[],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000ade2edad8d2f3a5bd43d11948de9f55973f9ce07"]],"resultHash":"0xaec12a2645aa97caa72437efc1f368cfde740e267f4b96c1c3ef9c138a8aba91"},{"fromBlock":3273221,"toBlock":21894127,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000000000000000a84d1a9b0063a910315c7ffa9cd248"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000ba11d00c5f74255f56a5e366f4f77f5a186d7f55"]],"resultHash":"0x33c64bcb9216d613ba200edbc725a5f5d953b52542e26fdd4840a30d203106a3"},{"fromBlock":1548048,"toBlock":21894127,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9"]],"resultHash":"0xf80e59faf84a78dd7e20bfc0be734578944d92bc73078df7006e5db61ded17de"},{"fromBlock":498010,"toBlock":21893810,"address":["0xb9f599ce614feb2e1bbe58f180f370d05b39344e"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"],["0x000000000000000000000000031946c8972121053e3fef32cf5ea15dba132fe7"]],"resultHash":"0xebd8535ef0eca9a057a676a16e86f469fb58d71f3e9851a9beb8931bf256ac7c"},{"fromBlock":2031541,"toBlock":17607165,"address":["0xecd20f0ebc3da5e514b4454e3dc396e7da18ca6a"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000848be39d1e89f413f31957f229406069900aa20b"]],"resultHash":"0x8f043387b3db1b73d89a05b3e95505f2b2e6d4a795bb394f8b40bf9f6d7907e6"},{"fromBlock":2306836,"toBlock":21893842,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ced92fa7f0797cbc851b48140ae218a0b0d41ce0"],["0x0000000000000000000000000c4b632b389b09b0c6b546f5dbbb15bffad0961e"]],"resultHash":"0x915580b8360c7df84f4ebc2e6171b64d1087fce792c640c67607d6594e405c0f"},{"fromBlock":3343185,"toBlock":20028240,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x0000000000000000000000001d8acbe644edc3e077a1d41b84b00dcc1387c000"]],"resultHash":"0xa00f90100ea8fdbc8803a6ac7692313951f0b3b5f9ddf1c90360e0f20042d064"},{"fromBlock":3985702,"toBlock":21893842,"address":["0x767fe9edc9e0df98e07454847909b5e959d7ca0e"],"topics":[["0x769254a71d2f67d8ac6cb44f2803c0d05cfbcf9effadb6a984f10ff9de3df6c3"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000004d82a8afdf423681b60811943015c26d0c796ae9"],["0x0000000000000000000000006a091a3406e0073c3cd6340122143009adac0eda"]],"resultHash":"0xa8d522ca3a5c01ada33c3b7cd7dbdb5f0ac274f6a743f13156a2e78900e1ab55"},{"fromBlock":779698,"toBlock":21893842,"address":["0x24179cd81c9e782a4096035f7ec97fb8b783e007"],"topics":[["0xa55c5f48fd29482ad55f4b59bf070cd1ac1a7132a31f7a136ebe8877ae37e1ff"],["0x000000000000000000000000c384ac6ee27c39e2f278c220bdfa5baed626d9d3"]],"resultHash":"0x613dfdefe3d0b316c44294f684ba20fcb92d1ca71e44a5270cdd1822c78890f3"},{"fromBlock":0,"toBlock":20686234,"address":["0x8597fa0773888107e2867d36dd87fe5bafeab328"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db"]],"resultHash":"0xb424a6afe2786c976fa9c8b6551dd05e14a8e371964b4106e1e14871f04d26e0"},{"fromBlock":5734655,"toBlock":21894063,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000f86b96bb30a5eccc5193d11a0e97bb6572f8962e"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x9a60e4a546c26d7c15556823a32a8cdfd7d41abcbcd452ca2276c5899cc58aff"},{"fromBlock":0,"toBlock":12375709,"address":[],"topics":[null,null,["0x00000000000000000000000039a5707a8c367f2a8a225daea6de53b55e8ec55b"]],"resultHash":"0x6bb32a558b3d468c807b2fe4fde0e15ce933871e247c0ff682f90fb8a3b2ab02"},{"fromBlock":1807231,"toBlock":21894159,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0x56bbbe6df981199c68f0378a770692c77b374cc316bc192ce0fa1000904ef634"},{"fromBlock":0,"toBlock":20289029,"address":["0xd77bcd9cf4212a41defbcd2e2ff0f50fea2be643"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000032f7ccc365a4ae5f6c3f81f63fb0dfa97a31248d"],["0x00000000000000000000000062c50f2dfd68daef43b38acb22a32626fe5071c2"]],"resultHash":"0x37046876814a9bd24d96233710e70e01d508ee123b5542b8cb867b4032a85d45"},{"fromBlock":8932336,"toBlock":21894159,"address":["0x654ca24793270d5183c69e77df8ccb25bb4cd9fe"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000004d32c8ff2facc771ec7efc70d6a8468bc30c26bf"]],"resultHash":"0x67b2b4602959092374ef113125aa1e0012ba92437c0a633b74be014dea4181be"},{"fromBlock":0,"toBlock":15955059,"address":[],"topics":[["0x590bbc0fc16915a85269a48f74783c39842b7ae9eceb7c295c95dbe8b3ec7331"],null,null,["0x0000000000000000000000000000000000000000000000000000000000005006"]],"resultHash":"0x2a14dc78bf21e6b6cd54b544b431e3ac5278b1fe3dfb18178b60e79982475b44"},{"fromBlock":5698656,"toBlock":21894095,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0xcadc80029938add1c4eaba777c879b894768d25f511b90951ccfe4bd28468799"},{"fromBlock":4179561,"toBlock":21894127,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x0000000000000000000000001d8acbe644edc3e077a1d41b84b00dcc1387c000"]],"resultHash":"0xa00f90100ea8fdbc8803a6ac7692313951f0b3b5f9ddf1c90360e0f20042d064"},{"fromBlock":0,"toBlock":20483228,"address":["0x907bcfa97fa02037a0a1228709e7756d41f212c5"],"topics":[["0x90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15"]],"resultHash":"0x5b4cb44fbb1ebc0499dc278f1f89ac3c2b32f06c47eb574ce39fda2df53b86be"},{"fromBlock":7486286,"toBlock":21418779,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b89eb49bc337d2bfaee360ec63ad606b6788ceb2"],["0x000000000000000000000000e137faa86acba1b35efccc22195bcd1707cc7176"]],"resultHash":"0xa5b400a951ac47b2cca28944e71ade85a78538095ef24292fb193032f30bb2ed"},{"fromBlock":7092747,"toBlock":21894063,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000c6cf51f57969129654c5014748e44e2a8f6ebd81"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599"]],"resultHash":"0x932c43c6e41c3105dc93f0cd52f2ca6b86f4ab21970455377551e0b8a63b8e99"},{"fromBlock":2799555,"toBlock":21894159,"address":[],"topics":[null,null,["0x00000000000000000000000085a23457a05c0f06f097ea0c0ae8da41a02f2bb7"]],"resultHash":"0x4f2763337cb3be0f8db42602e7915efec6fd7ab8cb3e5b7f76aa75dd58449f3a"},{"fromBlock":5022814,"toBlock":21893937,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000047294092daeafc531860a357346502fc3bc70f58"]],"resultHash":"0xe6dc4b56ac6e25fa69a9e04b2de7ac86078cca9f0aaa1e759220590f9bcacb3f"},{"fromBlock":555391,"toBlock":19178028,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x0000000000000000000000001d8acbe644edc3e077a1d41b84b00dcc1387c000"]],"resultHash":"0xa00f90100ea8fdbc8803a6ac7692313951f0b3b5f9ddf1c90360e0f20042d064"},{"fromBlock":5435433,"toBlock":19575687,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab41"]],"resultHash":"0x84bb7455f8784403829993af8d7a28e03ee2fdc40b30623f66834fa23f3f6182"},{"fromBlock":4033076,"toBlock":21894191,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000003cd751e6b0078be393132286c442345e5dc49699"],["0x000000000000000000000000b725c93b1757648615688961491cc18e70ab9193"]],"resultHash":"0xa134899b2c53eaeb81d7f130257a9ec884cfc3107c2311d88ef1472be67b784f"},{"fromBlock":0,"toBlock":20686234,"address":["0x8597fa0773888107e2867d36dd87fe5bafeab328"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db"]],"resultHash":"0xb424a6afe2786c976fa9c8b6551dd05e14a8e371964b4106e1e14871f04d26e0"},{"fromBlock":8256499,"toBlock":21894127,"address":[],"topics":[null,null,["0x000000000000000000000000e49849f768e114bf06a4d715f6aca57c6cc0c35f"]],"resultHash":"0xc43647114f9aea1be6433940c32c619daa19c40ad51eddf5fdb8431bea49bce8"},{"fromBlock":9841,"toBlock":21894191,"address":[],"topics":[null,null,["0x0000000000000000000000007da35b3cf8bb5c35036414f32efb2e75e21c016f"]],"resultHash":"0x4f34e5cf10775212d71aef9e357fd3d782bb5633c2c874b50eb21f1681681a63"},{"fromBlock":561656,"toBlock":20425331,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000030aeb40fdd5165bed9e39c9b20557776329c0617"],["0x0000000000000000000000006748f50f686bfbca6fe8ad62b22228b87f31ff2b"]],"resultHash":"0xf3fc5412340be8676ca9479b03e23ab67c67ab4cc7564fe2167e30f537ff5ec7"},{"fromBlock":7174588,"toBlock":21893905,"address":["0x5c9921d0dcdd854525f89c62c3a0d8561e182cae"],"topics":[["0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"]],"resultHash":"0xb592363268cfee9c79d93f49e76ce8bd7ba48f63bdcb2e4f5a1cd136ebbef46a"},{"fromBlock":1560895,"toBlock":21894095,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000045e2aa1483a1c02f1e7d07ff904bb1ded9350ab7"]],"resultHash":"0xb1ba5a4d19da809d9f365903a1e1c0f4751004abe670cdf33511eb374e644951"},{"fromBlock":779698,"toBlock":21893842,"address":["0x24179cd81c9e782a4096035f7ec97fb8b783e007"],"topics":[["0xa55c5f48fd29482ad55f4b59bf070cd1ac1a7132a31f7a136ebe8877ae37e1ff"],["0x000000000000000000000000c384ac6ee27c39e2f278c220bdfa5baed626d9d3"]],"resultHash":"0x613dfdefe3d0b316c44294f684ba20fcb92d1ca71e44a5270cdd1822c78890f3"},{"fromBlock":3262923,"toBlock":18342784,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"],["0x000000000000000000000000ade2edad8d2f3a5bd43d11948de9f55973f9ce07"]],"resultHash":"0xaec12a2645aa97caa72437efc1f368cfde740e267f4b96c1c3ef9c138a8aba91"},{"fromBlock":1708350,"toBlock":19452274,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000030aeb40fdd5165bed9e39c9b20557776329c0617"]],"resultHash":"0x4cd609a7ec7d0df36b9724850f7bb1f5a811c7e910603e67a4452c582e02c944"}],[{"fromBlock":858629,"toBlock":21098839,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000397ff1542f962076d0bfe58ea045ffa2d347aca0"]],"resultHash":"0x165ed93cf839ae1cd2a5c995ab7721a6d2bb998bf52b04bda8999cbc5c014182"},{"fromBlock":11746708,"toBlock":17218172,"address":[],"topics":[null,["0x000000000000000000000000c384ac6ee27c39e2f278c220bdfa5baed626d9d3"]],"resultHash":"0x3655e14a31a83bccdae575d92854bc0dd1aa24b3c42560ea353aaf25313d8635"},{"fromBlock":7477115,"toBlock":17759594,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000022f9dcf4647084d6c31b2765f6910cd85c178c18"]],"resultHash":"0xb9fc739b2867b3eb71cc82ea5d7963190a8aaede09165f5e04a7216b6d98b014"},{"fromBlock":13258007,"toBlock":18370344,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],null,["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x35a1f6e1f190d32c013fcea73c97dfd3a2164e96068b57e4b16e82c342f81b5b"},{"fromBlock":0,"toBlock":20289029,"address":["0xd77bcd9cf4212a41defbcd2e2ff0f50fea2be643"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000062c50f2dfd68daef43b38acb22a32626fe5071c2"]],"resultHash":"0xa065ee163e07ffc77dec98c4d514eb0599a0275ca309f24d3c21b1eb2fe2b1db"},{"fromBlock":1820980,"toBlock":21894127,"address":["0xc83ce8612164ef7a13d17ddea4271dd8e8eebe5d"],"topics":[["0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xc505667d1297ab606ef4e5ef6290f36a07d98eb260835f3b9166aecac6319c66"},{"fromBlock":3353941,"toBlock":21893842,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0x484fc9b5ce077f8f2cb6c020d48f0bced09216c0b1ac0da9e0001bbf9bca9c76"},{"fromBlock":5117595,"toBlock":21894159,"address":["0x84ca8bc7997272c7cfb4d0cd3d55cd942b3c9419"],"topics":[null,["0x000000000000000000000000a14afc841a2742cbd52587b705f00f322309580e"],["0x0000000000000000000000001111111254eeb25477b68fb85ed929f73a960582"]],"resultHash":"0x4ee6e708ec24b5f0f66f446ac212c3923094c22e547ebfc41ce66d1600579f59"},{"fromBlock":2963691,"toBlock":21893873,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0x484fc9b5ce077f8f2cb6c020d48f0bced09216c0b1ac0da9e0001bbf9bca9c76"},{"fromBlock":582435,"toBlock":21894159,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x6c3233107442d18416ade7b79fd533de21764e66f4ca25ce9ba3c0b6756e261c"},{"fromBlock":1857537,"toBlock":21893873,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000008fc6003daded7aeef374ec36030d7770fe41ca3b"]],"resultHash":"0x8e219ae45246dc29efda030f2cdde8e8b98abf6f47a9df3693d3c38c0d35b2bd"},{"fromBlock":5046656,"toBlock":21893873,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000ba11d00c5f74255f56a5e366f4f77f5a186d7f55"]],"resultHash":"0xd6be99adf427eda717d9faabeee61ae04949d8a7d47f6bf75707296ef57a0c26"},{"fromBlock":2159059,"toBlock":21893873,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":2046014,"toBlock":21894063,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[null,["0x000000000000000000000000f3a71cc1be5ce833c471e3f25aa391f9cd56e1aa"],["0x00000000000000000000000031d38869257c8af9023077d2316e42b948c74a17"]],"resultHash":"0xd98a051dddb5c2693d0a4f4ff67ab4a0e3fb5e11e0609dc798da410699526842"},{"fromBlock":5659008,"toBlock":20787948,"address":["0x5b272ce3e225b019a3fbd968206824b24c674344"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"]],"resultHash":"0x5150b1201282f07ec34a1874fd79f990b3efbb505b10396bb2b801c074a7496a"},{"fromBlock":1857537,"toBlock":21893873,"address":["0xec78bd3b23ac867fcc028f2db405a1d9a0a2f712"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000008fc6003daded7aeef374ec36030d7770fe41ca3b"]],"resultHash":"0x06ec627b839b58730cc13213218e71f5515b803518a7920d9a4c451dfd5b1e90"},{"fromBlock":0,"toBlock":16618657,"address":[],"topics":[null,["0x000000000000000000000000e85430a51bd131905219bb2460fb893f48236cef"],["0x00000000000000000000000049ab3df9ce5de1e321357e35f51fbde7e0e6a294"]],"resultHash":"0x9d26e74af44ab8f52fff14928929b8c28738590c60ab177073dabf77944a86fd"},{"fromBlock":7300018,"toBlock":21894063,"address":["0x8597fa0773888107e2867d36dd87fe5bafeab328"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db"]],"resultHash":"0xb424a6afe2786c976fa9c8b6551dd05e14a8e371964b4106e1e14871f04d26e0"},{"fromBlock":9258484,"toBlock":21596057,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000000000000c2cf7648c169b25ef1c217864bfa38cc"],null,["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xcd63004fb1b98175a09ef9fb68c62d0a77705530817dd329faaaecd889728175"},{"fromBlock":7643516,"toBlock":21869131,"address":["0xd9d27decffa31c061bf3ae0a92689ed02f973d5e"],"topics":[null,["0x0000000000000000000000004870525eae23fceb31df613d179ef6275e1b93a9"],["0x0000000000000000000000001b425529c9d7472603e2dcf125fd195f71dfb412"]],"resultHash":"0xb8d1170e45e6c0bf31964956c562019a40370922cbdcbeb3cd993a9d6eb5a26a"},{"fromBlock":4204051,"toBlock":21894159,"address":["0xd9d27decffa31c061bf3ae0a92689ed02f973d5e"],"topics":[null,["0x0000000000000000000000004870525eae23fceb31df613d179ef6275e1b93a9"],["0x0000000000000000000000001b425529c9d7472603e2dcf125fd195f71dfb412"]],"resultHash":"0xb8d1170e45e6c0bf31964956c562019a40370922cbdcbeb3cd993a9d6eb5a26a"},{"fromBlock":7174588,"toBlock":21893905,"address":["0x5c9921d0dcdd854525f89c62c3a0d8561e182cae"],"topics":[],"resultHash":"0x9fa1c6d661838ebe2ee3a996093a7105c8b6802c337905b3be990c66e8960654"},{"fromBlock":12516253,"toBlock":14846181,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x0000000000000000000000001592923d399fc2f6a7ee416e776d5158e6d13b25"]],"resultHash":"0xa9eb14873480c988ad3064d4672ec0c669fb3a4ba28ad8a2c266adaaf58273e4"},{"fromBlock":5377061,"toBlock":21894191,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":5860646,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":1548048,"toBlock":21894127,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x6c3233107442d18416ade7b79fd533de21764e66f4ca25ce9ba3c0b6756e261c"},{"fromBlock":2472500,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":5759874,"toBlock":21893969,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000c6cf51f57969129654c5014748e44e2a8f6ebd81"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x6053ffc37d74d5bb214410fda120b4cb4e2ddc9d8255477d62ec2c03646dfb88"},{"fromBlock":179021,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":12593555,"toBlock":14774164,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x0000000000000000000000001592923d399fc2f6a7ee416e776d5158e6d13b25"]],"resultHash":"0xa009cbb7c40ff16eefb49c0ea7a0348c5d969f8972602621296ff528184b1fa3"},{"fromBlock":3499853,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":5052437,"toBlock":21893905,"address":["0x2260fac5e5542a773aa44fbcfedf7c193bc2c599"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007835cb043e8d53a5b361d489956d6c30808349da"],["0x0000000000000000000000004585fe77225b41b697c938b018e2ac67ac5a20c0"]],"resultHash":"0x6247976a772901b29f48b3b63bb53ad636b5787a6c08bbde7acc64c4058d0f62"},{"fromBlock":2133143,"toBlock":21894191,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000930af7923b8b5f8d3461ad1999ceeb8a62884b19"]],"resultHash":"0x27b700ad73bb589322c65818d818ddf625087bb76b4bd9186da78a7f045f3a52"},{"fromBlock":6380717,"toBlock":20391181,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db"]],"resultHash":"0x858770148af52a5bc2057de44a63859986a9d6bc22b828301e5908237000df3d"},{"fromBlock":182183,"toBlock":21893905,"address":["0x1580eb65edb0b903e7b3624ca963219d0c5c565e"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3"]],"resultHash":"0xb4fb9017fcd461ef4167c9aa013c7f83f4ac7fde0db492c473fc9bbaa6fc7c3a"},{"fromBlock":6545879,"toBlock":19939849,"address":["0x8597fa0773888107e2867d36dd87fe5bafeab328"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db"]],"resultHash":"0xb424a6afe2786c976fa9c8b6551dd05e14a8e371964b4106e1e14871f04d26e0"},{"fromBlock":3224543,"toBlock":21893937,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000000ef7f9c5549165d204d8f440d1d84ea4f8c1dca4"]],"resultHash":"0x682af1b9d18d3f1eb76cda18cb59fb4247c84e6d96dbac3e70c5ba8590ed0782"},{"fromBlock":11837911,"toBlock":20537481,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x0000000000000000000000001592923d399fc2f6a7ee416e776d5158e6d13b25"]],"resultHash":"0x1ead1b3630ef89a7cbb6223ea2c7019e2d48c222472a4e2ed3b1ba855d3f3cf7"},{"fromBlock":894101,"toBlock":21894095,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007316f8dd242974f0fd7b16dbcc68920b96bc4db1"],["0x00000000000000000000000073a8a6f5d9762ea5f1de193ec19cdf476c7e86b1","0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0x30b08f22ebd2786d40db0ddb9a6d07004274c5ac4c5378f0ee0a5907e472d438"},{"fromBlock":5046705,"toBlock":20777213,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0xb6758c982200700783d68838ece59848e13a5b899e449a98851d12f6059c0ddc"},{"fromBlock":1211116,"toBlock":19491941,"address":["0xd77bcd9cf4212a41defbcd2e2ff0f50fea2be643"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000003ce2a0101df6b034635f0bcec7a6cd9597768796"]],"resultHash":"0xc85149c68026f8c90afb6eb16acc6465d7a8ecf9de9425a813fc22f1ec6f48a9"},{"fromBlock":0,"toBlock":19953000,"address":["0xd73be539d6b2076bab83ca6ba62dfe189abc6bbe"],"topics":[["0x0b95606a57983e48ae4c9631df8d2e17766c3017421531c1004a4882888ef274"],["0x000000000000000000000000000000000000000000000000000000000000a4b2"]],"resultHash":"0xe37c942941ca7d356a6f84958d872d105c852a08478d85d2819c5bc3de33e4c7"},{"fromBlock":2472500,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":0,"toBlock":21311753,"address":[],"topics":[null,["0x000000000000000000000000b647dd3226e2811d86990ea7766f5d851eb78b75"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0xf5ceffa06b492e7cdc91530c034069e00a69741f757b9fa828e363bfabe1a540"},{"fromBlock":2472500,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":2472500,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0xb6758c982200700783d68838ece59848e13a5b899e449a98851d12f6059c0ddc"},{"fromBlock":2472500,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":7643516,"toBlock":21869131,"address":["0xd9d27decffa31c061bf3ae0a92689ed02f973d5e"],"topics":[["0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"],["0x0000000000000000000000004870525eae23fceb31df613d179ef6275e1b93a9"],["0x0000000000000000000000001b425529c9d7472603e2dcf125fd195f71dfb412"]],"resultHash":"0xb8d1170e45e6c0bf31964956c562019a40370922cbdcbeb3cd993a9d6eb5a26a"},{"fromBlock":2680494,"toBlock":21893873,"address":["0x1580eb65edb0b903e7b3624ca963219d0c5c565e"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3"]],"resultHash":"0xb4fb9017fcd461ef4167c9aa013c7f83f4ac7fde0db492c473fc9bbaa6fc7c3a"},{"fromBlock":1336992,"toBlock":21894191,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000f3a71cc1be5ce833c471e3f25aa391f9cd56e1aa"],["0x00000000000000000000000031d38869257c8af9023077d2316e42b948c74a17"]],"resultHash":"0xd98a051dddb5c2693d0a4f4ff67ab4a0e3fb5e11e0609dc798da410699526842"},{"fromBlock":9775446,"toBlock":21893937,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x6c3233107442d18416ade7b79fd533de21764e66f4ca25ce9ba3c0b6756e261c"},{"fromBlock":7173828,"toBlock":20903756,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x0000000000000000000000004a137fd5e7a256ef08a7de531a17d0be0cc7b6b6"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x4a8fa44bf717ed1f6d2aa0e41a692696e8d70615f4fe7b829af045fe63da447b"},{"fromBlock":6557870,"toBlock":21893969,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000c6cf51f57969129654c5014748e44e2a8f6ebd81"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x6053ffc37d74d5bb214410fda120b4cb4e2ddc9d8255477d62ec2c03646dfb88"},{"fromBlock":8082667,"toBlock":21631503,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8","0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x0000000000000000000000005b6be21c4d1f2c1c5a3d6af3599f3bb0a785ae2f"]],"resultHash":"0x12349f34fbf81fc91e331c4514b35f955c6bb1aa6bb9dab782436977d5d9719a"},{"fromBlock":0,"toBlock":21385893,"address":["0xd73be539d6b2076bab83ca6ba62dfe189abc6bbe"],"topics":[["0x0b95606a57983e48ae4c9631df8d2e17766c3017421531c1004a4882888ef274"],["0x000000000000000000000000000000000000000000000000000000000000a4b2"]],"resultHash":"0xe37c942941ca7d356a6f84958d872d105c852a08478d85d2819c5bc3de33e4c7"},{"fromBlock":1300386,"toBlock":21894095,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xbf3454ca1c15ac8eb2d327f70e180f59d2d87c96cc0f4527339252092e03a2f3"},{"fromBlock":0,"toBlock":21281139,"address":[],"topics":[["0x0b95606a57983e48ae4c9631df8d2e17766c3017421531c1004a4882888ef274"],["0x000000000000000000000000000000000000000000000000000000000000a4b2"]],"resultHash":"0xe37c942941ca7d356a6f84958d872d105c852a08478d85d2819c5bc3de33e4c7"},{"fromBlock":7272863,"toBlock":21893969,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],null,["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0xcd02c26f900f02aaa4c64f843ebee92dc1a5ea20d889f7a6a77943d44ddcf98b"},{"fromBlock":9775446,"toBlock":21893937,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x752c774441aafb1bad7989a4956cf5ad05aaf9ee2950f75a42c51e6972011bb5"},{"fromBlock":1066914,"toBlock":16528429,"address":["0x5b272ce3e225b019a3fbd968206824b24c674344"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"]],"resultHash":"0x5150b1201282f07ec34a1874fd79f990b3efbb505b10396bb2b801c074a7496a"},{"fromBlock":9258998,"toBlock":21893969,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000000000000000a84d1a9b0063a910315c7ffa9cd248"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0x7afbcda9db33cb632a5cafa3d70a839f9925cd0219408baeabe2befd2acf0a98"},{"fromBlock":6597345,"toBlock":21893969,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba11d00c5f74255f56a5e366f4f77f5a186d7f55"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xacfccfac41d3f6a30b6fc92ba4444c483ef225b62bec7921a733e2f293dd9965"},{"fromBlock":5044153,"toBlock":21894127,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000aaf5110db6e744ff70fb339de037b990a20bdace"]],"resultHash":"0x5dc8a7c0b859b49a72a24bce1a0d0812feaac042017e726dabd2a0450c81edce"},{"fromBlock":2472500,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":13590571,"toBlock":20555719,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0xf66582f49ef22141ec895dd9dc7f7f4658da09e02c56db3fd9df448bc284af22"},{"fromBlock":0,"toBlock":16977620,"address":["0xcced5b8288086be8c38e23567e684c3740be4d48"],"topics":[["0x7d19c7776f05049226f581a23a4df896c65115763d8ec30490658efc4e8649cd"],["0x000000000000000000000000aa4adaa72dd05a84dbedb813c04eff90336d7c29"]],"resultHash":"0x495e9976c3e1db953581b9a2ef7763c42cdaae69aa61cfc6707afe7a248ddcbe"},{"fromBlock":113660,"toBlock":17433476,"address":["0x191557728e4d8caa4ac94f86af842148c0fa8f7e"],"topics":[null,["0x0000000000000000000000007aa96ef1261c21da7fdadb5613e356348cc088ca"]],"resultHash":"0xf4d58347fc060a177cbe50f490c6c81b37973fbae6ee1ea78ca64c2777b2223f"},{"fromBlock":1767302,"toBlock":21894191,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x6c3233107442d18416ade7b79fd533de21764e66f4ca25ce9ba3c0b6756e261c"},{"fromBlock":1505748,"toBlock":13182280,"address":[],"topics":[null,["0x000000000000000000000000cdf9c1fedad9f92c5c2e0c4c37aa15387eda11cd"]],"resultHash":"0xca8a34d6c5c24c318aec0855a6ea628cbac1339007eec15ce8a34c7b465d4f74"},{"fromBlock":1100280,"toBlock":17937411,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b1035d946d6548feca96341485d28eba463ad9cb"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"]],"resultHash":"0x140607d5e71d4b4fa5746d136dff83b43f5edff28bdd780f4b955f434fd4d38f"},{"fromBlock":2680494,"toBlock":21893873,"address":["0x1580eb65edb0b903e7b3624ca963219d0c5c565e"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3"]],"resultHash":"0xb4fb9017fcd461ef4167c9aa013c7f83f4ac7fde0db492c473fc9bbaa6fc7c3a"},{"fromBlock":6815398,"toBlock":21893999,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000ba11d00c5f74255f56a5e366f4f77f5a186d7f55"]],"resultHash":"0xd6be99adf427eda717d9faabeee61ae04949d8a7d47f6bf75707296ef57a0c26"},{"fromBlock":994757,"toBlock":18740247,"address":[],"topics":[null,null,["0x000000000000000000000000fba8763d939f30af181657c8722b57e9b5a58c50"]],"resultHash":"0x65c082202e8eeff57b250421c066ecc67981add3e287f312c441200c24f59727"},{"fromBlock":6550738,"toBlock":21893999,"address":[],"topics":[null,["0x000000000000000000000000bda13cbdadd055527ce95d82d39580a5cb412782"]],"resultHash":"0x7c82628b4c176ca32b5653f3b7f886572bcd6e6e4b6baa28c16ba71e833789c8"},{"fromBlock":6597345,"toBlock":21893969,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba11d00c5f74255f56a5e366f4f77f5a186d7f55"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xacfccfac41d3f6a30b6fc92ba4444c483ef225b62bec7921a733e2f293dd9965"},{"fromBlock":893718,"toBlock":17209388,"address":["0xd73be539d6b2076bab83ca6ba62dfe189abc6bbe"],"topics":[["0x0b95606a57983e48ae4c9631df8d2e17766c3017421531c1004a4882888ef274"],["0x000000000000000000000000000000000000000000000000000000000000a4b2"]],"resultHash":"0xe37c942941ca7d356a6f84958d872d105c852a08478d85d2819c5bc3de33e4c7"},{"fromBlock":0,"toBlock":20626416,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000009d7157deaa4af751701736576d7f5f03bd718a9f"]],"resultHash":"0xf5f2d1759f3b258008e908f2f25b457aa1f689b96e4c1871e4ecf781e324597c"},{"fromBlock":9775446,"toBlock":21893937,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x752c774441aafb1bad7989a4956cf5ad05aaf9ee2950f75a42c51e6972011bb5"},{"fromBlock":7429255,"toBlock":21894063,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000f7ac25089776c904db0e6c06502f9fc114e36863"],null],"resultHash":"0xb298bda8d09abf754c0f17ec503db379f2a25df3adcf00c1e5eae8c65b0cc818"},{"fromBlock":12107583,"toBlock":14999416,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x0000000000000000000000001592923d399fc2f6a7ee416e776d5158e6d13b25"]],"resultHash":"0x85e7f2024dcfe534a412883ee6029409a08aa7ec7895b53caae1c65df9b8cd8c"},{"fromBlock":3226696,"toBlock":16587445,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x0000000000000000000000006637e824c12e1e9b4d0ba8bf0b12874e37192990"]],"resultHash":"0x589159069c3dcc85df7d2ffc467e4269c3ef2c927d6f5c936118d778232ceb93"},{"fromBlock":3388912,"toBlock":21893999,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba11d00c5f74255f56a5e366f4f77f5a186d7f55"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xacfccfac41d3f6a30b6fc92ba4444c483ef225b62bec7921a733e2f293dd9965"},{"fromBlock":7643516,"toBlock":21869131,"address":["0xd9d27decffa31c061bf3ae0a92689ed02f973d5e"],"topics":[["0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"],["0x0000000000000000000000004870525eae23fceb31df613d179ef6275e1b93a9"],["0x0000000000000000000000001b425529c9d7472603e2dcf125fd195f71dfb412"]],"resultHash":"0xb8d1170e45e6c0bf31964956c562019a40370922cbdcbeb3cd993a9d6eb5a26a"},{"fromBlock":7745619,"toBlock":20558302,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000c6cf51f57969129654c5014748e44e2a8f6ebd81"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x6053ffc37d74d5bb214410fda120b4cb4e2ddc9d8255477d62ec2c03646dfb88"},{"fromBlock":0,"toBlock":19212688,"address":["0x7cc768b882be41ca03f9daccfc48b8bd6d25eb25"],"topics":[["0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"]],"resultHash":"0x0374b41686c1a6c2cdf211a015fad106c4ac04ef553487de12fb848c69c42ffd"},{"fromBlock":4588195,"toBlock":19768276,"address":["0xc730ef0f4973da9cc0ab8ab291890d3e77f58f79"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000000000000089341e263b85d84a0eea39f47c37a9d2"],["0x0000000000000000000000000000000089341e263b85d84a0eea39f47c37a9d2"]],"resultHash":"0xbf97904122c251d2b145143b47de395c2d98e5b545bff35945d53ec8eb50d780"},{"fromBlock":0,"toBlock":19248027,"address":["0xcffdded873554f362ac02f8fb1f02e5ada10516f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000004d246be90c2f36730bb853ad41d0a189061192d3"],["0x0000000000000000000000004d246be90c2f36730bb853ad41d0a189061192d3"]],"resultHash":"0x3e4fe7261ff83ec87adef5af34e82469e744eb77eed67f27dd4f6f30a557d65f"},{"fromBlock":317883,"toBlock":21894127,"address":["0x7ad4780dfa1624ad1dca5d514c90ea7cf6eb37f9"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000008fe7d9643077b4ab2885cb2dad4236cc4784413f"],null],"resultHash":"0x83abf0d1b90ed7557c2d0e44467ff7af7ce181b9ee79671011eb800343222195"},{"fromBlock":34595,"toBlock":16109879,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000037bd00aa1d2e98e48c0db302d35530212f388cd1"]],"resultHash":"0x639c713d9cea69fe6a1add8877510f3a1c5a4008799fae0b016be55c857f5764"},{"fromBlock":2472500,"toBlock":21893905,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":3940581,"toBlock":21823220,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45"],["0x000000000000000000000000cc164307e9642d2adea4ff102082ccdefe5e8282"]],"resultHash":"0xba000b48ac7a9814e2d8cee1d1fe682b96b4a08db53c72f1486e0285d05c290b"},{"fromBlock":5619876,"toBlock":21894127,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xbf3454ca1c15ac8eb2d327f70e180f59d2d87c96cc0f4527339252092e03a2f3"},{"fromBlock":4711049,"toBlock":19656623,"address":["0x795065dcc9f64b5614c407a6efdc400da6221fb0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000594fe7c3d4c52c0e9ab377bc6d8acd66adc8ea9d","0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000e12af1218b4e9272e9628d7c7dc6354d137d024e"]],"resultHash":"0x5338b3ee1b64a5df0e0f76216d6922e2eee34cb3a61e6392d4fc8c9160ea8506"},{"fromBlock":0,"toBlock":19248027,"address":["0xcffdded873554f362ac02f8fb1f02e5ada10516f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000004d246be90c2f36730bb853ad41d0a189061192d3"]],"resultHash":"0x3e4fe7261ff83ec87adef5af34e82469e744eb77eed67f27dd4f6f30a557d65f"},{"fromBlock":2076827,"toBlock":21894031,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x7aa8d86a67288e966d8e87864bfb57529ed927d39b0613c7d74f517261c9e3c7"},{"fromBlock":998893,"toBlock":21894159,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000e382ec905825ddbbff33321dd82ed588aef53a79"]],"resultHash":"0x08fbdb3df764c22af1dadb4b9af9da81cc0ab9fc516d2d9644de7aa187c41653"},{"fromBlock":120089,"toBlock":18033710,"address":[],"topics":[["0x0b95606a57983e48ae4c9631df8d2e17766c3017421531c1004a4882888ef274"],["0x000000000000000000000000000000000000000000000000000000000000a4b2"]],"resultHash":"0xe37c942941ca7d356a6f84958d872d105c852a08478d85d2819c5bc3de33e4c7"},{"fromBlock":0,"toBlock":19835735,"address":["0xdd9fd6b6f8f7ea932997992bbe67eabb3e316f3c"],"topics":[["0x590bbc0fc16915a85269a48f74783c39842b7ae9eceb7c295c95dbe8b3ec7331"],["0x0000000000000000000000000000000000000000000000000000000000000c9d"],["0x0000000000000000000000000000000000000000000000000000000000000001"]],"resultHash":"0x1f7a87c98be3c5b2d93aa4f3fa8dae2fdcfa3a9df916a68e4fdd9b53e56a5512"},{"fromBlock":5759874,"toBlock":21893969,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000c6cf51f57969129654c5014748e44e2a8f6ebd81"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x6053ffc37d74d5bb214410fda120b4cb4e2ddc9d8255477d62ec2c03646dfb88"},{"fromBlock":2275417,"toBlock":19872511,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"],["0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599"]],"resultHash":"0x6342bf689bc6db0f5a98fbb77c0dc42e58738444bb642f0ec1624bde0768f917"}],[{"fromBlock":11839013,"toBlock":14284317,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000036e2fcccc59e5747ff63a03ea2e5c0c2c14911e7"]],"resultHash":"0x6906b73f0b0f66a6c6f9fa7fc9a108faedc2427d1d9dfacef3256921b5fa0af7"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xacbec158aec75fe8ce89950fa1b95acb231026a12d2a7ea68c1b74c7138fbbb4"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xacbec158aec75fe8ce89950fa1b95acb231026a12d2a7ea68c1b74c7138fbbb4"},{"fromBlock":12504138,"toBlock":14210036,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x71379a2ca31e2cb4227a090bb0db3f57d47187886df730b3cb2b07abf923559a"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xacbec158aec75fe8ce89950fa1b95acb231026a12d2a7ea68c1b74c7138fbbb4"},{"fromBlock":15140544,"toBlock":17805709,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599"]],"resultHash":"0xf549a9667bea908e32dadbbb5b9ec49aa930070594a37196873197e45fed2450"},{"fromBlock":15048301,"toBlock":17978752,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000000000000c2cf7648c169b25ef1c217864bfa38cc"]],"resultHash":"0xcffc8bf85a0856832eef729a2b4064f63451707206d4431ead14125549123312"},{"fromBlock":11613954,"toBlock":14323073,"address":[],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0xa0fdaed4ec2f3460f99c0f96943b7eefd123102c6ef1fb833c41957f9dceb54e"},{"fromBlock":11416062,"toBlock":14469068,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x77c4c77fd2df40547a5fcbdeb0a5a2b2ec4b3244641e47ff6945149b7686dd70"},{"fromBlock":12301000,"toBlock":13791213,"address":["0x5b272ce3e225b019a3fbd968206824b24c674344"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"]],"resultHash":"0x994bc419722a4fb8b3d7ffeb02bc6d56744ecc0589261e46ad57051faa4ba016"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xacbec158aec75fe8ce89950fa1b95acb231026a12d2a7ea68c1b74c7138fbbb4"},{"fromBlock":12431122,"toBlock":13427755,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x7517cb2e4d59f8c24138583eb2b487618884ac89a5a2a1cd203ba76db4b6c0cf"},{"fromBlock":11613954,"toBlock":14323073,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0xbf9631c2f7c77cfcb0536102bba22ff5301b0193619280b949732289473d2a9d"},{"fromBlock":11416062,"toBlock":14469068,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x1aa629db11f2770d551eed52ccd8414f782683871c56e1beb46ed39b14dd50c7"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa29e57325f90b58600f81fe96db5dcf6de848e4fa5e18f4340900dc95c26f551"},{"fromBlock":12522337,"toBlock":13954331,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x9d027a0cebfb2cf001210a5397d9fabbe33d647872c3d174942d57adc09087dd"},{"fromBlock":12865129,"toBlock":19934618,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x52a31da088639b81b5353f339085ae96891f5eec27a24fce0ddd097adf7310a9"},{"fromBlock":11416062,"toBlock":14469068,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x1aa629db11f2770d551eed52ccd8414f782683871c56e1beb46ed39b14dd50c7"},{"fromBlock":12416519,"toBlock":13910111,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x4951c1a95d4132b8b2a950986d6b487247d95f6926bc751fe68b7fe0f4009d11"},{"fromBlock":12608049,"toBlock":13369158,"address":["0x7b504a15ef05f4eed1c07208c5815c49022a0c19"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000004a137fd5e7a256ef08a7de531a17d0be0cc7b6b6"]],"resultHash":"0x74e5a4ba9b5a9d9cacffbd1d0ed877d4c9e6a55d31b174ce1fe162fc8b31361c"},{"fromBlock":15409639,"toBlock":16351372,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"]],"resultHash":"0x41eab43c6bf42aac822fa2791dce48d967ee361dda18fcf4e9977ed3f6ec7a2c"},{"fromBlock":12461919,"toBlock":13392681,"address":["0xcb2286d9471cc185281c4f763d34a962ed212962"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xc637ee294c931f97f5a1bd5e5b195e6994c1684ebd75beb455e98a3271a8966a"},{"fromBlock":12922251,"toBlock":13636183,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"]],"resultHash":"0x13ad363e5347f188b8d47a104f856a7a6d9d27d1795f825cb6449d2c14d9e5ef"},{"fromBlock":12390674,"toBlock":14001099,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000b3c839dbde6b96d37c56ee4f9dad3390d49310aa"]],"resultHash":"0x0821c0976e7c53f210d0e7d0e195bbcf750ba0f3192080a5176e56ed303fbf33"},{"fromBlock":12476959,"toBlock":13885934,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x0ee14a2e6f4073ce495e1d4992b1060627f9933981d733968192d582352b8d77"},{"fromBlock":11416062,"toBlock":14469068,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x1aa629db11f2770d551eed52ccd8414f782683871c56e1beb46ed39b14dd50c7"},{"fromBlock":15140544,"toBlock":17805709,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599"]],"resultHash":"0xf549a9667bea908e32dadbbb5b9ec49aa930070594a37196873197e45fed2450"},{"fromBlock":12624557,"toBlock":13430093,"address":["0xcb2286d9471cc185281c4f763d34a962ed212962"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x25dc4526530aadb70644e7210930ce534f3e3dc0b842fd02e9e1e4c9299e24e7"},{"fromBlock":14418700,"toBlock":18236043,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"]],"resultHash":"0x0e33448a22cbd2c3dbd1141c8a363f41998abc90c7a6049e5be8b9fb13268e6a"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa29e57325f90b58600f81fe96db5dcf6de848e4fa5e18f4340900dc95c26f551"},{"fromBlock":14651521,"toBlock":17875529,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x8201aa3f00000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"]],"resultHash":"0x56ffd48746def7d6da4f018f6f84761687c5f75686cecb5ea28f6e035fd7b973"},{"fromBlock":15771134,"toBlock":16461475,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45"],["0x000000000000000000000000c44c70fbfef750862fbcf73f5197a28bcaa11253"]],"resultHash":"0x8ffa386dcecb233eeb2e5825f89e8efc61c44680123b3a41c5e77002c0236ef8"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x1ad156a080eb3202e61c0c78b506e53454ae1fd081b58342f2ee218539bed43b"},{"fromBlock":12544847,"toBlock":13476803,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x5f7c4671078041cb2112ace33792a39c94c8846fe9c8f3d1c5ca3de4fd75d82b"},{"fromBlock":13951704,"toBlock":17518225,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x8201aa3f00000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"]],"resultHash":"0xc4801ad2945a4f06e376cf53633fc86f74bbba63e5fabbdb48d06cdfac46e928"},{"fromBlock":10086946,"toBlock":12244571,"address":[],"topics":[null,["0x00000000000000000000000078b950c15e9deffd256075ce6c2698239a334541"]],"resultHash":"0xaa31abb65b849539fc258ecb6a563b24559573d861d0b518c36301b4e6c08519"},{"fromBlock":12506301,"toBlock":13514978,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x97baae9c34e26ade57314f1019d9822dfad3f3ba4731672cf027e86d775124aa"},{"fromBlock":12516899,"toBlock":13399954,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0","0x7b504a15ef05f4eed1c07208c5815c49022a0c19"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000e12af1218b4e9272e9628d7c7dc6354d137d024e"]],"resultHash":"0x30b9129de159cbb17d7f0f548d32318c6b9e62edd0a5430fb1aaa8ab327ec15b"},{"fromBlock":13032438,"toBlock":14926063,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000665fb69d812666794588a58f25b91a65b40f1bde"]],"resultHash":"0x20b189bf4f69788d8f2cca3b5603d417c70018fa36c1bc3a3e3f8e5f990a24e5"},{"fromBlock":14020248,"toBlock":17904165,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x8201aa3f00000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81"]],"resultHash":"0xfe48e1b28235bf2398cc081fa62a9bf7942c5aa60fa7181ff6aeb5b7e89c33e9"},{"fromBlock":12153933,"toBlock":13463385,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000064c29aac69d3122f6e5531ceca1b753f95350af4"],["0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"]],"resultHash":"0xf9ac647d4d143198204100084f6e5b99e6cf65f3fd66bb9edb3fba07a664ff09"},{"fromBlock":12202346,"toBlock":13711217,"address":["0x62f22a47e5d2f8b71cc44fd85863753618312f67"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x0000000000000000000000000652687e87a4b8b5370b05bc298ff00d205d9b5f"]],"resultHash":"0xd6e92f67244139b4bffd846c28810cb60a25b10420023f319203bfbb68c880a7"},{"fromBlock":12475336,"toBlock":13335919,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000aaf5110db6e744ff70fb339de037b990a20bdace"]],"resultHash":"0x932204b2a28773952d34195710ef28b7e1adb94de54b690f5762fa6a4872dfd7"},{"fromBlock":14539343,"toBlock":17375669,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0xfde2cdc3231fd4fefb0575021cee57332de9331e31e09034a877affe3ba6be8e"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa29e57325f90b58600f81fe96db5dcf6de848e4fa5e18f4340900dc95c26f551"},{"fromBlock":12699475,"toBlock":13411689,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db"]],"resultHash":"0x63b2fdd39a9f4e0ca43e5b7ce01f6b1d8982e2d63ac9c6453ed31886f10b2f84"},{"fromBlock":11296015,"toBlock":14101136,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[null,["0x000000000000000000000000f3a71cc1be5ce833c471e3f25aa391f9cd56e1aa"],null],"resultHash":"0xfbb9529dc92f4419cddcec6d28767428479ca8e61d368eb9c694e0a7338d10a3"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x357188f6d1d38581c197d16458ed5ec35ab6ad20182883cc516926fbece8f0f8"},{"fromBlock":14881287,"toBlock":18089474,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599"]],"resultHash":"0x817052d1f6a5fda24e083c9f14d1f3e3f75b9f3ed79b114b622a45c0aa222c5d"},{"fromBlock":15125183,"toBlock":16564131,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,["0x00000000000000000000000024902aa0cf0000a08c0ea0b003b0c0bf600000e0"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x30acc4118b57fc0ba3ea05eca6d5e51615b26b89acd2d4171e209e9f7633c088"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x1ad156a080eb3202e61c0c78b506e53454ae1fd081b58342f2ee218539bed43b"},{"fromBlock":12559679,"toBlock":13428937,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0","0x7b504a15ef05f4eed1c07208c5815c49022a0c19"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000e12af1218b4e9272e9628d7c7dc6354d137d024e"]],"resultHash":"0xeb64f87423c165e24297c2bc9497e00edaee140efa11f8a9e859ebe2a742caae"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa29e57325f90b58600f81fe96db5dcf6de848e4fa5e18f4340900dc95c26f551"},{"fromBlock":12540456,"toBlock":13448910,"address":["0x3fd4cf9303c4bc9e13772618828712c8eac7dd2f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x4d57fd13f22b2a29ef70dcdaf5697673fdd66f76e60647e5ebbbf2fbc492d1d7"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x357188f6d1d38581c197d16458ed5ec35ab6ad20182883cc516926fbece8f0f8"},{"fromBlock":11692350,"toBlock":15074655,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x0000000000000000000000001592923d399fc2f6a7ee416e776d5158e6d13b25"]],"resultHash":"0x612146a8f2f8b0b34f29d6ed0a350294a75a48d9800481a9d3ab6dfed15c1ba3"},{"fromBlock":11544128,"toBlock":14545282,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x6832d6096512941ced59e65aba3b40c613ff3478d908ccb456fffeda375510de"},{"fromBlock":14539343,"toBlock":17375669,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0xfde2cdc3231fd4fefb0575021cee57332de9331e31e09034a877affe3ba6be8e"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa29e57325f90b58600f81fe96db5dcf6de848e4fa5e18f4340900dc95c26f551"},{"fromBlock":11613954,"toBlock":14323073,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0xbf9631c2f7c77cfcb0536102bba22ff5301b0193619280b949732289473d2a9d"},{"fromBlock":15125183,"toBlock":16564131,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000024902aa0cf0000a08c0ea0b003b0c0bf600000e0"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x30acc4118b57fc0ba3ea05eca6d5e51615b26b89acd2d4171e209e9f7633c088"},{"fromBlock":11544128,"toBlock":14545282,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x08547c364309bf608994c574a7e3631c0b09c64c55875a3d0e2d8d3e39130378"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x357188f6d1d38581c197d16458ed5ec35ab6ad20182883cc516926fbece8f0f8"},{"fromBlock":11380001,"toBlock":14866061,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0xb6641c42de5d662e7bb143ffcff3a9c9836c36d30e4b55b3904da7b8004c32c5"},{"fromBlock":19238012,"toBlock":20653018,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09"],["0x000000000000000000000000f07c735011c311f55425bf8c534471a0410d85ad"]],"resultHash":"0xfbbfec7a73b7b483327f696001d8b3d8047be2319bd0597c31a3f5f249348728"},{"fromBlock":13330524,"toBlock":15982025,"address":["0xa9ca155590671bbc01d7e1d95c0adec749e39cfc"],"topics":[null,null,null,["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"]],"resultHash":"0x5e7ab29d61fe9781fc54ffe1a4d14f2f6f82bece06d379742a86f8729495607f"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x357188f6d1d38581c197d16458ed5ec35ab6ad20182883cc516926fbece8f0f8"},{"fromBlock":12670867,"toBlock":13440248,"address":["0xba38eca6dfdb92ec605c4281c3944fccd9dec898"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x6d81b020417d8ac7eb471ea2b7a31f654a99ca403fa90cd1ba87afb1586d0190"},{"fromBlock":15125183,"toBlock":16564131,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000024902aa0cf0000a08c0ea0b003b0c0bf600000e0"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x30acc4118b57fc0ba3ea05eca6d5e51615b26b89acd2d4171e209e9f7633c088"},{"fromBlock":12509850,"toBlock":13827509,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x88631e36611c620100217d84e615647cafdac505dc26c1b88412f425790dd0e1"},{"fromBlock":13803946,"toBlock":18039300,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x0ce0dbb6618b22c2fad02ba08ee798a446c4c0d8305817ee02534f9ba104cf83"},{"fromBlock":12539155,"toBlock":13733050,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x160c18c5fe9cb9cbf61ba59ba6d4e9d85961b3fc6492c9c40f15b877d66de830"},{"fromBlock":15099458,"toBlock":17831942,"address":[],"topics":[null,["0x00000000000000000000000093c329189b3f6fef306b98ee88dd0aa5ec1ec15e"]],"resultHash":"0xe5a173464ee39b50b00b57cf435ab5439d7d0ee8fbf9fe6ab6a4ce59e35b188c"},{"fromBlock":14237149,"toBlock":19268681,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x6d9e377636b3270f9b3bb45a4689c815367654ec217f04b63df3ab610013d7c6"},{"fromBlock":11501829,"toBlock":14467264,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x20bec368440da0e8cd2041800d61b7a7461b46697059a1daef8376d9893a4b72"},{"fromBlock":12719414,"toBlock":13495086,"address":["0x18d98d452072ac2eb7b74ce3db723374360539f1"],"topics":[["0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xaae505ecfb47fcd47fcbe78d0baeac0fc76d816809a8902396eb6e9f31b4bdf9"},{"fromBlock":12901053,"toBlock":13437194,"address":["0xd73be539d6b2076bab83ca6ba62dfe189abc6bbe","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000000652687e87a4b8b5370b05bc298ff00d205d9b5f"]],"resultHash":"0x66b335c56e33cc5f4b30a0670472d83e6414aeb292a93b67266161a30a28f9c9"},{"fromBlock":12532649,"toBlock":14240089,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xaa71cb2bb9c7bea535ff2cbd46212d8dd926e07b4551b46f7e05b6c33094d457"},{"fromBlock":15125183,"toBlock":16564131,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x00000000000000000000000024902aa0cf0000a08c0ea0b003b0c0bf600000e0"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x30acc4118b57fc0ba3ea05eca6d5e51615b26b89acd2d4171e209e9f7633c088"},{"fromBlock":11516074,"toBlock":15361176,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x1350793c356e20b4b62d3bb503264af1ff16f58d237ecb3194eb0317ed7149d6"},{"fromBlock":19130008,"toBlock":21513200,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09"],["0x000000000000000000000000f07c735011c311f55425bf8c534471a0410d85ad"]],"resultHash":"0x075da09437ffcbb104d92bd67b278a4a387771ce84ad81e961aa1e5041a89a17"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x1ad156a080eb3202e61c0c78b506e53454ae1fd081b58342f2ee218539bed43b"},{"fromBlock":11534372,"toBlock":15826161,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x0000000000000000000000001592923d399fc2f6a7ee416e776d5158e6d13b25"]],"resultHash":"0xc0cadc070e710e0778cb9598a57361e480bddcafb95e2c49a3cfd62b8de7536d"},{"fromBlock":13679707,"toBlock":14944982,"address":["0xa9ca155590671bbc01d7e1d95c0adec749e39cfc"],"topics":[["0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f"],null,null],"resultHash":"0x5c41998fe55464fe102d4ebd925729ddda4adc2a100f2efe81b9a20bacba6800"},{"fromBlock":15140544,"toBlock":17805709,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599"]],"resultHash":"0xf549a9667bea908e32dadbbb5b9ec49aa930070594a37196873197e45fed2450"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x357188f6d1d38581c197d16458ed5ec35ab6ad20182883cc516926fbece8f0f8"},{"fromBlock":11483430,"toBlock":14443237,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x707698a6608f9e42a6a7f2034e752711cb99f5bb3896028b4f99a954da2ba932"},{"fromBlock":13197619,"toBlock":17794010,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0xcc1b88a7e3ff32d43ed2851300897d3e7b4812ed4acb7de7bf647152cf6187e6"},{"fromBlock":11843564,"toBlock":15208469,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"],["0x0000000000000000000000001592923d399fc2f6a7ee416e776d5158e6d13b25"]],"resultHash":"0xad2933999f3ffd801d7e90366268eb076541cb0c193afb529cc3dee62fac015a"},{"fromBlock":12570985,"toBlock":13178834,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000a47bb4f34298052048c4d7319686e23064eb22d9"]],"resultHash":"0xbb41dfd3c16c1bd9439df14b6552d0e60a68c945cc77e8bd005b5180c415c21a"},{"fromBlock":19008524,"toBlock":21894159,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09"],["0x000000000000000000000000f07c735011c311f55425bf8c534471a0410d85ad"]],"resultHash":"0x3d3ff215b3c05beb76c44c57b57411cc2c6d2e9b4916bdb6b1ed7c58e118f155"},{"fromBlock":14539343,"toBlock":17375669,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000a1006d0051a35b0000f961a8000000009ea8d2db"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0xfde2cdc3231fd4fefb0575021cee57332de9331e31e09034a877affe3ba6be8e"},{"fromBlock":13447111,"toBlock":17632175,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x2e67479e797761a5e9c6a9e2a5c6ba7772e352f59f93acbea7a57e17d03759aa"},{"fromBlock":11613954,"toBlock":14323073,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166"]],"resultHash":"0x1ad156a080eb3202e61c0c78b506e53454ae1fd081b58342f2ee218539bed43b"},{"fromBlock":13447111,"toBlock":17632175,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca"],["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x2e67479e797761a5e9c6a9e2a5c6ba7772e352f59f93acbea7a57e17d03759aa"},{"fromBlock":10752826,"toBlock":17116195,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d1b430eb6f5de67cc2f2fccfa559b8db70d9d96d"]],"resultHash":"0x37c9f762a19a0faff3af5089f7b957c5d3b040de318ad50310f93be841e5f2a5"},{"fromBlock":5595291,"toBlock":7299424,"address":[],"topics":[null,["0x00000000000000000000000094d6faac6b98f58afd5da954e88c50d104381e58"]],"resultHash":"0x6ac7d17d2f8adbf0e04566a15f3f3ba51d04232137180ee027bb8bbbaf601fef"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xacbec158aec75fe8ce89950fa1b95acb231026a12d2a7ea68c1b74c7138fbbb4"},{"fromBlock":12561975,"toBlock":13425760,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa29e57325f90b58600f81fe96db5dcf6de848e4fa5e18f4340900dc95c26f551"},{"fromBlock":12439978,"toBlock":13665265,"address":["0xfffae206a0c17c4804f04af3880ff8a9dea39210"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x2d9b073f92783b63d78db520ed1831fb87e3afd6efbfa807a5fb7d64a23fe483"}],[{"fromBlock":13013858,"toBlock":13113462,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xc3262efd06edb3c32e7006c509bf816af37c7e8af1da86f41cccf5e86b2bf975"},{"fromBlock":3592098,"toBlock":3785535,"address":["0x3ec225d0cd929148a1473c546c06dd1ee9f558b1"],"topics":[["0xe4c14a344e557cc7c4b7e0d1f6dff174b9a6ad4e51273606bd0c0d4bd6339303"]],"resultHash":"0xfdfcba6693fbb40f42ac0ac5aea584684844891300d657b7d96f3dec59e18b91"},{"fromBlock":15676332,"toBlock":15821080,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"]],"resultHash":"0x1ace94825f78066527e8e1cb6c41eeee287ab3ddaa1ecac939ca7cef5545e522"},{"fromBlock":3242464,"toBlock":3512214,"address":[],"topics":[null,null,["0x0000000000000000000000004bbd29b9c1dc5dc624db6c76364a38ab2a3c5f65"]],"resultHash":"0x179b2e151e09aa1242c71b59acde0a68b90a9219cb4938a3aed54ca4fd0ce72a"},{"fromBlock":15629719,"toBlock":15833314,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0x50da69bb63aaacb497c6c115007dd47659ec0ef1e3738bc77014ca36694a1580"},{"fromBlock":12675039,"toBlock":13371963,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000269db91fc3c7fcc275c2e6f22e5552504512811c"]],"resultHash":"0x7285fff6c58a1893e70ef9661a9b92be6fd2b79ad4879fbfbf11e51cea0fe800"},{"fromBlock":7192208,"toBlock":7517625,"address":[],"topics":[null,null,["0x0000000000000000000000009c23d67aea7b95d80942e3836bcdf7e708a747c2"]],"resultHash":"0x113db6ba5f0394de52870e67cd9d07f3eb25d9cb4e293d2f19ddc791051fb934"},{"fromBlock":6890568,"toBlock":7178538,"address":[],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000000a4b2"]],"resultHash":"0x5e6b9434369162e27f85420ceb15759077e30bec806daabc04505e1fb36e11cd"},{"fromBlock":12966340,"toBlock":13150792,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x40bf567ea120d29ed4fbc1a4d6bc54397819963fa1ec15a71900046dc22c6b78"},{"fromBlock":7490288,"toBlock":7623726,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"]],"resultHash":"0x4531de3c9cfa11ef696bdc8648dd11b1cf4907cc1f73da2f36a50b4c6dd5baf3"},{"fromBlock":19998377,"toBlock":20084984,"address":[],"topics":[["0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987"],null,["0x0000000000000000000000006cc5f688a315f3dc28a7781717a9a798a59fda7b"]],"resultHash":"0xd46800a63f304bf6c80b818c1dcff0b0d6aaa7f002eea1e94138c6106e3d3de4"},{"fromBlock":14826852,"toBlock":14989903,"address":[],"topics":[null,["0x00000000000000000000000063945489ef54398f3ccc8cb44f2a93ba1ac91ab8"]],"resultHash":"0x6545bec98bb9256069559aaf286b79d08184fac2da57f214ab6e35e184c6347e"},{"fromBlock":15629719,"toBlock":15833314,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x9cb72c5b3db7ad0f3310dcb5f46cf3519a1bb1a225dd2df558c2dd75d6b4b078"},{"fromBlock":13018033,"toBlock":13096839,"address":["0x36e2fcccc59e5747ff63a03ea2e5c0c2c14911e7"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x9a1a33a4669b8951203f11d75bbd0000fb7265a027d4f39e34a3e019b66a2466"},{"fromBlock":13389791,"toBlock":13537791,"address":["0x938625591adb4e865b882377e2c965f9f9b85e34"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xb0afc68aba812a191d809b94676341f8eab963e79ef123ab7c479f86231c674a"},{"fromBlock":12949179,"toBlock":13127449,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x68cc14b1c3f79beafef4c6ac6422a5367b73fe20fe87131d4c9c0ebe934bb8a7"},{"fromBlock":15655918,"toBlock":16025322,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],["0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],null,["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xe687d7faae657c613f1ddb7c2a9c5f9c8e63894821fbb7a8941b6728867c2e2b"},{"fromBlock":16811448,"toBlock":16880089,"address":["0x172a9be5ea7f8602d6b9a97a914d23859053790a"],"topics":[["0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82"],["0x587d09fe5fa45354680537d38145a28b772971e0f293af3ee0c536fc919710fb"]],"resultHash":"0x90db29ce25bb5cfcd1d3ac860729b1a16500b888ab88f3eb79ffabba024d6a60"},{"fromBlock":18096540,"toBlock":18663712,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],null,["0x000000000000000000000000000000000000000000000000000000000000119f"]],"resultHash":"0x579247db10d064d044bdbf36056255933f10700f15901174f9ba570eaf128403"},{"fromBlock":2877473,"toBlock":2991041,"address":["0xdd98b423dc61a756e1070de151b1485425505954"],"topics":[["0xa5acb022726d980b249ddc212f4992ad87f28c093550232fcc48bd8af803f2d5"]],"resultHash":"0x060ff3b139b9a4aaf555f07f15fb27943a49499280dfe571702828ea44159cf4"},{"fromBlock":19938072,"toBlock":20091951,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000a14afc841a2742cbd52587b705f00f322309580e"]],"resultHash":"0x70099f0d0024b485b3df9a3667d1cd7e5c2aaa81f80c1a1fb6f221798abc104b"},{"fromBlock":16825828,"toBlock":16874876,"address":["0x172a9be5ea7f8602d6b9a97a914d23859053790a"],"topics":[null,["0x587d09fe5fa45354680537d38145a28b772971e0f293af3ee0c536fc919710fb"]],"resultHash":"0xf22145447f128689c1fa37a9ada540905e58efd40cf483206604705d6ac2ad53"},{"fromBlock":13205541,"toBlock":13568469,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"]],"resultHash":"0xe1131c3427fb66d385bad543d1d588a01f24fb243affbaac121f45c892438d0b"},{"fromBlock":13293223,"toBlock":13544555,"address":["0x938625591adb4e865b882377e2c965f9f9b85e34"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x9ef0eef12a2c2290c6d1a9d2ee54c9bfa3e6cc8041d605da65f69604537a2f90"},{"fromBlock":15658364,"toBlock":15857114,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,null,["0x000000000000000000000000408e41876cccdc0f92210600ef50372656052a38"]],"resultHash":"0x0a5347cee4d95203809de7458c4b5ca3ded2959c3a39a2d2f4c0d5f0a882678c"},{"fromBlock":12773372,"toBlock":13168769,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000c558f600b34a5f69dd2f0d06cb8a88d829b7420a"]],"resultHash":"0x41aeba15a2d24ecdce0429961e5d534fb653079d59d062d21e0358d90c2e26b2"},{"fromBlock":12973850,"toBlock":13117324,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[null,["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xec71446c6b56d292f471bb7b364333fcf1705b9398e6bd0577fbb58bcae4487e"},{"fromBlock":12973850,"toBlock":13117324,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"]],"resultHash":"0xec71446c6b56d292f471bb7b364333fcf1705b9398e6bd0577fbb58bcae4487e"},{"fromBlock":19455242,"toBlock":19553399,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"],["0x00000000000000000000000091204649a5c9ab2cadfc2089fd22ed0fbfe170ed"]],"resultHash":"0x6b772a513221b5ca62d7a7ee13fe077b8456d0b7eb49880a1ea912b39918b23e"},{"fromBlock":12912181,"toBlock":13133628,"address":["0x0652687e87a4b8b5370b05bc298ff00d205d9b5f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x3d00f162e30f7646ed4b39162e6b6e614cc5052703cdcd79fde3a1bef46cb82b"},{"fromBlock":20681638,"toBlock":20940363,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000004d32c8ff2facc771ec7efc70d6a8468bc30c26bf"]],"resultHash":"0x3cabc02900fa78bacfd06aead13e14e4abb976ecbbeeb3aff08c4690472d0b77"},{"fromBlock":16827035,"toBlock":16872886,"address":["0x172a9be5ea7f8602d6b9a97a914d23859053790a"],"topics":[["0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82"]],"resultHash":"0x758ab2ecf3a34e671536314beac5968f677c29e59f92230a74fcf41308c42de8"},{"fromBlock":15605613,"toBlock":15940652,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0xa906dc84e3eee39216d0de2ed0c1651a39885287433043064dc0d22577c647f5"},{"fromBlock":20681638,"toBlock":20940363,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000004d32c8ff2facc771ec7efc70d6a8468bc30c26bf"]],"resultHash":"0x3cabc02900fa78bacfd06aead13e14e4abb976ecbbeeb3aff08c4690472d0b77"},{"fromBlock":12586181,"toBlock":13192054,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d45afa3649e57a961c001b935ded1c79d81a9d23"]],"resultHash":"0x368749deff2b9056533cef64117d094fd49994165ed5718bfd19897625189e3e"},{"fromBlock":13000947,"toBlock":13088151,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x000000000000000000000000cc00b641305c639d9f2b3c34067c69679ee1dbef"]],"resultHash":"0x34d3292906682b46318c5093fc86b8101f9cac117fe27585b52430c5d9a53b74"},{"fromBlock":12964363,"toBlock":13152994,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x3d9ef32e9661d92456648a4d0114ebd88c5972db790b5e4cfbeacd5c808ab5b8"},{"fromBlock":11586188,"toBlock":11762313,"address":["0xc5fa164247d2f8d68804139457146efbde8370f6"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x264cb155e867786f4bfc963e689f7b0ecf322434c146072cdd995c3bf8fa49f5"},{"fromBlock":19938072,"toBlock":20091951,"address":[],"topics":[null,["0x000000000000000000000000a14afc841a2742cbd52587b705f00f322309580e"]],"resultHash":"0x70099f0d0024b485b3df9a3667d1cd7e5c2aaa81f80c1a1fb6f221798abc104b"},{"fromBlock":15044857,"toBlock":15312899,"address":[],"topics":[null,["0x000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8"],["0x000000000000000000000000acd4ec996aad815efe72a11944188c6db6c30176"]],"resultHash":"0x8bf07e8ea2642c43ddce728ba5956a2abc6c6dd2494729c14e7c4ed0493f6829"},{"fromBlock":14050024,"toBlock":14396266,"address":["0xa9ca155590671bbc01d7e1d95c0adec749e39cfc"],"topics":[null,null,null],"resultHash":"0xa36b883e8c1c247bcd58a2e4a59c1502033406c3709e00bd3737f0be1c79908f"},{"fromBlock":12965510,"toBlock":13125998,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x517127e38c31299fc1effb132b9b6d5e2f72ee8d6b5d7772c1c7293a87d21dc6"},{"fromBlock":12703765,"toBlock":13242375,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000e12af1218b4e9272e9628d7c7dc6354d137d024e"]],"resultHash":"0xef5d997667ef71e2f2ef6f9ed80bdb3b5f748336264c32532a5535d737aa4ca1"},{"fromBlock":12675039,"toBlock":13371963,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000269db91fc3c7fcc275c2e6f22e5552504512811c"]],"resultHash":"0x7285fff6c58a1893e70ef9661a9b92be6fd2b79ad4879fbfbf11e51cea0fe800"},{"fromBlock":15596730,"toBlock":15841600,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"]],"resultHash":"0x1d5e46b3f2cc10a43cc876950f64d76afdd91dd0bab4bf269f4d4967abdefe15"},{"fromBlock":15564631,"toBlock":15835055,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x97b337102d12ed4cd07c2d8284748792674619f0a58de6b26104569613d90795"},{"fromBlock":12988157,"toBlock":13081677,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000058dc5a51fe44589beb22e8ce67720b5bc5378009"]],"resultHash":"0x8018c937ff7881876a7048883d9ef90979213359892f86588b05ed0e42b255e0"},{"fromBlock":19815654,"toBlock":20144291,"address":["0x84ca8bc7997272c7cfb4d0cd3d55cd942b3c9419"],"topics":[null,["0x000000000000000000000000a14afc841a2742cbd52587b705f00f322309580e"]],"resultHash":"0xcb2af12f0cbdafc9ed0bff95d479559b4e47d1bf5f5c0fefb6b91b7268ffc322"},{"fromBlock":12867265,"toBlock":13203590,"address":["0x382c4a5147fd4090f7be3a9ff398f95638f5d39e"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x00000000000000000000000092f1ff14a80ea8c23028a40c74c05bb994ea0ee2"]],"resultHash":"0x1462001baeaa24756154df15d48c1400346df7c7162e4585927623087df29c8b"},{"fromBlock":2859119,"toBlock":3034125,"address":["0xd86c6f0bb961e83c1ea30e8ab9d5cc291952ec08"],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000058"]],"resultHash":"0xe777e2ec0b7d432248252e275e6fea7ce4d9a0243f1760869d0ee3969cbe659c"},{"fromBlock":12687449,"toBlock":13175995,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d45afa3649e57a961c001b935ded1c79d81a9d23"]],"resultHash":"0xf4c33a309beb45143ea0e343994947f874e0ffa9fa627990c8563fef929bba5d"},{"fromBlock":12679577,"toBlock":13184107,"address":[],"topics":[null,null,["0x0000000000000000000000004abcca8fcf84cb0aa1431c36740a213da7aa838c"]],"resultHash":"0xeea580ea214192680928dcf8a9b08b81cf8834a4a602463e09fae890ad04bbe7"},{"fromBlock":3197122,"toBlock":3572860,"address":["0xedbaf3c5100302dcdda53269322f3730b1f0416d"],"topics":[null,null,["0x0000000000000000000000004bbd29b9c1dc5dc624db6c76364a38ab2a3c5f65"]],"resultHash":"0xca122bee2eb91a266ecb9db66daaef6e15cc320102890e54478fbcdb690cf33c"},{"fromBlock":12927803,"toBlock":13177392,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000aaf5110db6e744ff70fb339de037b990a20bdace"]],"resultHash":"0xc44184392902f5a31f6a40c157cbfc51f814699e8a3c4193dc9b5563c61702d8"},{"fromBlock":12834996,"toBlock":12879291,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000fe7444f63e0010a7208529608eb173760629483b"]],"resultHash":"0xa5ea3613aad74e5ad37e170ff6b87adb2775b93a36fb6957974792d159a079e2"},{"fromBlock":20606236,"toBlock":21110666,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000f007476bb27430795138c511f18f821e8d1e5ee2"]],"resultHash":"0x2ab367e389cc0d37444e6abdb3d46ac9de7b54c64ed07dd3f2de9fdd53ba7b5b"},{"fromBlock":12927795,"toBlock":13232141,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000a47bb4f34298052048c4d7319686e23064eb22d9"]],"resultHash":"0xa32e7d9f4a24a3fc4d1cf22d78fc91f71cfba5a309bb65454da5a896d5431273"},{"fromBlock":15586016,"toBlock":15834006,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x073fe755551f7e62a4b5413998c66370e55024b82682ccfa46ae7687017e4d92"},{"fromBlock":12903065,"toBlock":13315124,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x00000000000000000000000080eac0b5954d861849824e21dba32c3b3b90ef96"]],"resultHash":"0x8932c0c239b1dc4e14cc4b1358a9bf99fbb63ddedb86d4574f2f02906a5345a8"},{"fromBlock":14403971,"toBlock":14633596,"address":["0x63b4f3e3fa4e438698ce330e365e831f7ccd1ef4"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]],"resultHash":"0xf6691709c661cd1291e335556c7557d88d03f69e1d9a485b52ffac7c1c1ee928"},{"fromBlock":20681638,"toBlock":20940363,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000004d32c8ff2facc771ec7efc70d6a8468bc30c26bf"]],"resultHash":"0x3cabc02900fa78bacfd06aead13e14e4abb976ecbbeeb3aff08c4690472d0b77"},{"fromBlock":12965114,"toBlock":13053499,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000005d2dd39191196d764c6fd33dc488caf13af482ac"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db","0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x5eab660e93e659679760acaebca360722713abc70da4e12d47284e3a09e877dc"},{"fromBlock":12966340,"toBlock":13150792,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"]],"resultHash":"0x40bf567ea120d29ed4fbc1a4d6bc54397819963fa1ec15a71900046dc22c6b78"},{"fromBlock":13358986,"toBlock":13564064,"address":["0x938625591adb4e865b882377e2c965f9f9b85e34"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x17535d588a530d8f7fd03684f3e6f29090f31d7b00311f569a106ae7112e91a4"},{"fromBlock":12936450,"toBlock":13220573,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e"],"topics":[["0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x9b56935c7a19659268eec06040332677fa5cc64229a2de3356b3a4731ccc1326"},{"fromBlock":12944620,"toBlock":13145113,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000a47bb4f34298052048c4d7319686e23064eb22d9"]],"resultHash":"0xe9f2b6cdc69cf8a7225d850fb041787f8e5756fb4cc452c323b6df3c4dcaac4c"},{"fromBlock":19938072,"toBlock":20091951,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000a14afc841a2742cbd52587b705f00f322309580e"]],"resultHash":"0x70099f0d0024b485b3df9a3667d1cd7e5c2aaa81f80c1a1fb6f221798abc104b"},{"fromBlock":15596730,"toBlock":15841600,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x88c595f6740afcc10e9f05da22aa9e6cf991b473f3da69c68a6bd2d60cc90579"},{"fromBlock":18276024,"toBlock":18455497,"address":[],"topics":[null,null,null,["0x000000000000000000000000000000000000000000000000000000000000120d"]],"resultHash":"0xe1d91587a9f84fc8b8d7d14cb12e4735159583e43136570704ceb04274ab9ab2"},{"fromBlock":14469463,"toBlock":14766966,"address":["0xe6f51e892046cb5b437e0033d990b527ea4367c8"],"topics":[null,null],"resultHash":"0xd8ad1547885e8a4c71e80a00e337cc6d58c59874b6527b913ac23aaeb5785526"},{"fromBlock":13004161,"toBlock":13078129,"address":["0x0e26a21013f2f8c0362cfae608b4e69a249d5efc"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x98a70e2a2b6f92df10ff562f70f7206d98266a2a41f91b4e2470df728e2febf0"},{"fromBlock":12687449,"toBlock":13175995,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[null,["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d45afa3649e57a961c001b935ded1c79d81a9d23"]],"resultHash":"0xf4c33a309beb45143ea0e343994947f874e0ffa9fa627990c8563fef929bba5d"},{"fromBlock":20021263,"toBlock":20064223,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000be8bc29765e11894f803906ee1055a344fdf2511"],["0x00000000000000000000000073a8a6f5d9762ea5f1de193ec19cdf476c7e86b1","0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0x6320f9a3b69f08455be3ec2b8eb3093b500e3f6827eb1d459cae3fc55c3726e8"},{"fromBlock":12939128,"toBlock":13144428,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000755560f094b26e0e0a39a1dd7e47a3c4788830ec"]],"resultHash":"0x9f7dde4a192ec76fb10b2cc87426bed87a0a92ad7bece1280a2aae602c5c3568"},{"fromBlock":20606236,"toBlock":21110666,"address":["0x356b8d89c1e1239cbbb9de4815c39a1474d5ba7d"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000f007476bb27430795138c511f18f821e8d1e5ee2"]],"resultHash":"0x2ab367e389cc0d37444e6abdb3d46ac9de7b54c64ed07dd3f2de9fdd53ba7b5b"},{"fromBlock":12989365,"toBlock":13110467,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[null,null,["0x0000000000000000000000008d06afd8e322d39ebaba6dd98f17a0ae81c875b8"]],"resultHash":"0x446493321bd81d28b7b9a5290b4247032414d856cc034d181b05fac04d68c1df"},{"fromBlock":16639846,"toBlock":16777984,"address":["0x819f3450da6f110ba6ea52195b3beafa246062de"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000001111111254fb6c44bac0bed2854e76f90643097d"]],"resultHash":"0x4712ec30762d4f2297d935c209b6cea67a93d6db9e5444ed925736b163dcde22"},{"fromBlock":12973850,"toBlock":13117324,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xec71446c6b56d292f471bb7b364333fcf1705b9398e6bd0577fbb58bcae4487e"},{"fromBlock":12741126,"toBlock":13145414,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[null,["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000737aad349312f36b43041737d648051a39f146e8"]],"resultHash":"0xd15b065f48375cfad97d719ebf53acf9d6860ebb498178b005e4e0ed0d3db791"},{"fromBlock":12941672,"toBlock":13096804,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d75ea151a61d06868e31f8988d28dfe5e9df57b4"]],"resultHash":"0x53fb6e5d0cb0f943b906d9b007ce9e0b2b7a2aef25a561d5076f24544fa92f0d"},{"fromBlock":12960594,"toBlock":13096642,"address":["0x795065dcc9f64b5614c407a6efdc400da6221fb0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000036e2fcccc59e5747ff63a03ea2e5c0c2c14911e7"]],"resultHash":"0x414a095ca51c774bc0234e3f5df457b21422535d70dad5083dd7d7a00d9b52df"},{"fromBlock":13389791,"toBlock":13537791,"address":["0x938625591adb4e865b882377e2c965f9f9b85e34"],"topics":[null,null,["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x19b965b7dc4d92e223a139466aa28843f5e9185d873d91f814eaf2d471aed9fe"},{"fromBlock":12908991,"toBlock":13094283,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x6fe8527a1928ae757b4c482b4639b8be53599afd91c402b6203ecfa382ffa060"},{"fromBlock":12973850,"toBlock":13117324,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xec71446c6b56d292f471bb7b364333fcf1705b9398e6bd0577fbb58bcae4487e"},{"fromBlock":12741126,"toBlock":13145414,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000737aad349312f36b43041737d648051a39f146e8"]],"resultHash":"0xd15b065f48375cfad97d719ebf53acf9d6860ebb498178b005e4e0ed0d3db791"},{"fromBlock":12903065,"toBlock":13315124,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x00000000000000000000000080eac0b5954d861849824e21dba32c3b3b90ef96"]],"resultHash":"0x8932c0c239b1dc4e14cc4b1358a9bf99fbb63ddedb86d4574f2f02906a5345a8"},{"fromBlock":14069853,"toBlock":14290125,"address":["0x2260fac5e5542a773aa44fbcfedf7c193bc2c599"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000004a137fd5e7a256ef08a7de531a17d0be0cc7b6b6"],["0x0000000000000000000000004585fe77225b41b697c938b018e2ac67ac5a20c0"]],"resultHash":"0x991b06079cfe3bf914dad7458001b0c76d5279cc3f363849b1d6222ca56f7a5d"},{"fromBlock":12973850,"toBlock":13117324,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000002f87b1fca1769bc3361700078e1985b2dc0f1142"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xec71446c6b56d292f471bb7b364333fcf1705b9398e6bd0577fbb58bcae4487e"},{"fromBlock":13015734,"toBlock":13591503,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000008534b5e068e1adb57cfe44554f4e65c914603f8a"]],"resultHash":"0x92aa70b5d1b8dbef91f03848c795265eca00be95b0716da155d162128b76b9d6"},{"fromBlock":12123204,"toBlock":12246035,"address":["0x7cc768b882be41ca03f9daccfc48b8bd6d25eb25"],"topics":[],"resultHash":"0xb8e617f3c3d8460fc92f1cca19681909f097847bb81233f0e874a5cb6d052569"},{"fromBlock":11611354,"toBlock":11704218,"address":["0xc40d16476380e4037e6b1a2594caf6a6cc8da967"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000006de2b77d89759c1275b99175494e29299f845cbc"]],"resultHash":"0x3ff37bb7bb743d7084f66621305470ecaca7189c5d48b23121578f320a32e8be"},{"fromBlock":12988157,"toBlock":13081677,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000058dc5a51fe44589beb22e8ce67720b5bc5378009"]],"resultHash":"0x8018c937ff7881876a7048883d9ef90979213359892f86588b05ed0e42b255e0"},{"fromBlock":14600142,"toBlock":15053424,"address":[],"topics":[null,["0x000000000000000000000000dc0d08c6bc98ecdf176941de7517018f613e8977"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xb1e677df65ee7770ead7064da3a55fcd7596f700bb1572da084ef1d3a174d9f0"},{"fromBlock":12977496,"toBlock":13066009,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000877d9c970b8b5501e95967fe845b7293f63e72f7"]],"resultHash":"0xc55ffc3ee5d9ef4f91fd3bfecc464f91feca8ff232b04cb7e72cc478afbce856"},{"fromBlock":6026548,"toBlock":6159932,"address":["0xdd9fd6b6f8f7ea932997992bbe67eabb3e316f3c"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000c9d"],null],"resultHash":"0xb01029650bbece654875b35f93370e833c6c80cd0bfcfbd66d55180c74287af3"},{"fromBlock":12964360,"toBlock":13051552,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8a1a865e4405281311c5bc0f90c240498472d3e"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db","0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x4fa0cdd9e5b59806f1b1df5842eeb648969efbb1275f33e9d28c3366fc05d1e8"},{"fromBlock":15571414,"toBlock":15893654,"address":["0x49ff149d649769033d43783e7456f626862cd160"],"topics":[null,null,["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x09a03d949ce9eb97222a827c27184d072825439c0d475b805989ae240d1c99a5"},{"fromBlock":12922929,"toBlock":13123768,"address":["0x8f9ef75cd6e610dd8acf8611c344573032fb9c3d"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xffd66882c51220b404536710d128f7fd6812c75ef8c212522d85b6c3fa181ddf"},{"fromBlock":6026548,"toBlock":6159932,"address":["0xdd9fd6b6f8f7ea932997992bbe67eabb3e316f3c"],"topics":[["0x590bbc0fc16915a85269a48f74783c39842b7ae9eceb7c295c95dbe8b3ec7331"],["0x0000000000000000000000000000000000000000000000000000000000000c9d"],null],"resultHash":"0xd940e6c45b744dba009307c4f7adfb00754e84bc1214c0b9c6f462e11a1ad494"},{"fromBlock":12872992,"toBlock":13223367,"address":["0x9a632cd9cb44f9383bf6f3117056c2455b30a6e0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff"],["0x000000000000000000000000e66b31678d6c16e9ebf358268a790b763c133750"]],"resultHash":"0x06612a12f530d4dc4d728cc9219fc4e27f80d3cfe49a8675ca226b64f689c4c5"}],[{"fromBlock":19121905,"toBlock":19156222,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b0aac1f129651e62cde6d1ae683c8a49f4d004d1"],["0x0000000000000000000000005c7bcd6e7de5423a257d81b442095a1a6ced35c5"]],"resultHash":"0xd0e87456d5ff56889e5069d23b5ceac692a24480e19facf43c1b0b972f84bd9b"},{"fromBlock":13029262,"toBlock":13061696,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x3e052c340e5836cacb1fe9c3ad374d4c1ecf2df3e16170237796e8a7111b29ee"},{"fromBlock":13036999,"toBlock":13044083,"address":["0x20e95253e54490d8d30ea41574b24f741ee70201"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0xda0488ddba3de247251589c1134bfa7b250ece47cae4fe19f5f397cd641869ed"},{"fromBlock":14186651,"toBlock":14198096,"address":["0x2260fac5e5542a773aa44fbcfedf7c193bc2c599"],"topics":[null,null,["0x0000000000000000000000004585fe77225b41b697c938b018e2ac67ac5a20c0"]],"resultHash":"0x903b83930040c7d56c97bae7619dadeb210624d31dc7b4bc070febb6c6f93f84"},{"fromBlock":13029262,"toBlock":13061696,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x5f900a7ca43e9a977d19f8207bf4e5ff6aab75ee457d89ed7d1a23bb4d2dcfbc"},{"fromBlock":19121905,"toBlock":19156222,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b0aac1f129651e62cde6d1ae683c8a49f4d004d1"]],"resultHash":"0xd0e87456d5ff56889e5069d23b5ceac692a24480e19facf43c1b0b972f84bd9b"},{"fromBlock":13028679,"toBlock":13059548,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x9ea193a41d45fbf094e442a47fae7b0187116ae93f98767104ca1854e68de3bf"},{"fromBlock":13028679,"toBlock":13059548,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x3493bedfb19b13a38dde7269fd52b96a985375eaf5b8fded4930e048143f5a92"},{"fromBlock":13028679,"toBlock":13059548,"address":["0xb5de0c3753b6e1b4dba616db82767f17513e6d4e"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x3493bedfb19b13a38dde7269fd52b96a985375eaf5b8fded4930e048143f5a92"},{"fromBlock":13031256,"toBlock":13054552,"address":["0x6fcc7db7acbc3e9dde3ee7d96cb61fc9c0ca17a7"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x45e175c2376de02eb7ba7c2001d23311e2ac49c5ceb3e53ff2c7bb00f5f40b06"},{"fromBlock":13009113,"toBlock":13073242,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000036e2fcccc59e5747ff63a03ea2e5c0c2c14911e7"]],"resultHash":"0xe53fa3fc30a4a5a0e3d2e5c9b70f432c49f395c79fe7edde49f9bcd9333ec44f"},{"fromBlock":13022581,"toBlock":13058593,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000000c365789dbbb94a29f8720dc465554c587e897db"]],"resultHash":"0xaaef421eaac897f367bf848077689a6be509ff8a46326c1de260bfe4a8f970c9"},{"fromBlock":11661635,"toBlock":11668358,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000006de2b77d89759c1275b99175494e29299f845cbc"]],"resultHash":"0x0d92bbe3abb7b8f3e6f2d565417088ad0705774569b8ee4678f1601d2c304154"},{"fromBlock":13028961,"toBlock":13061694,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e78388b4ce79068e89bf8aa7f218ef6b9ab0e9d0"]],"resultHash":"0x5fde0bf4fef34f4d78531c56974be71d1a6d291a689927bbecd1fd181da3c1f0"},{"fromBlock":13033534,"toBlock":13044454,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x8b16a4f116db806d970f2209ff35b77c142f361c15f579e64ca6116cfff09864"},{"fromBlock":13023879,"toBlock":13050945,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x942ecff5692339d92febc5d38274fea1cf284999d369ad9cef6235114cf9ff02"},{"fromBlock":20797153,"toBlock":20803970,"address":["0xae7ab96520de3a18e5e111b5eaab095312d7fe84"],"topics":[["0x9d9c909296d9c674451c0c24f02cb64981eb3b727f99865939192f880a755dcb"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0"]],"resultHash":"0xb85cc8673fc4a60d523541ed4defc762d3b6eb0048b474f9301e14748b77d096"},{"fromBlock":14215997,"toBlock":14245382,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000039f6a6c85d39d5abad8a398310c52e7c374f2ba3"]],"resultHash":"0xfbd3c2670eac930ad8603beed4d4943f15be27fe3fea0c3a282ada995e4cb178"},{"fromBlock":14218528,"toBlock":14273522,"address":["0xba12222222228d8ba445958a75a0704d566bf2c8"],"topics":[null,["0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014"],["0x000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d","0x00000000000000000000000043c7d0e58d8644c6d65d5d536bb6bd59bdac7ea3"],["0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]],"resultHash":"0x3d3ede56f08696bfbea7624559e462a17dc79faf3e62711dbf19a3138bd3487d"},{"fromBlock":20036412,"toBlock":20053415,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x000000000000000000000000b8f275fbf7a959f4bce59999a2ef122a099e81a8"],["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e"]],"resultHash":"0x02737356cea6de2a8580ca60346c5f6164b12038624872bd318a9d4f1b2acf46"},{"fromBlock":20032287,"toBlock":20050541,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x000000000000000000000000b8f275fbf7a959f4bce59999a2ef122a099e81a8"],["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e"]],"resultHash":"0x9408d31d60a4fb645bc00f0aa0b93772c767e98e3e3b4527755de51cc80f326c"},{"fromBlock":13015047,"toBlock":13056502,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[null,["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x06cb2cfd2b5b134d096c1279387ccf1c3a6f216947106d59f76e248dabed0f77"},{"fromBlock":15998174,"toBlock":16004186,"address":["0x94693c9e342f759272d6f7b481703df8e83b1818"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x40e0aded7640410a863f7048dd4aaf87fb3181c227c55ff04aef89ff4dc7e34e"},{"fromBlock":20036412,"toBlock":20053415,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8f275fbf7a959f4bce59999a2ef122a099e81a8"],["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e"]],"resultHash":"0x02737356cea6de2a8580ca60346c5f6164b12038624872bd318a9d4f1b2acf46"},{"fromBlock":5347095,"toBlock":5373390,"address":["0xcdaf9abed7c74b3c5abba6c168bab8fa8539c892"],"topics":[],"resultHash":"0x03a26a1f756112626f943d13ea9d50b043b2da3a17badf016608537beb92ff71"},{"fromBlock":13015047,"toBlock":13056502,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x06cb2cfd2b5b134d096c1279387ccf1c3a6f216947106d59f76e248dabed0f77"},{"fromBlock":13035729,"toBlock":13044465,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x00000000000000000000000034d7d7aaf50ad4944b70b320acb24c95fa2def7c"]],"resultHash":"0x51b699b4f24544ed72c1dba81edf55c6914a2cb7a7b35c6badc501d7e97be077"},{"fromBlock":13015841,"toBlock":13056651,"address":["0x877d9c970b8b5501e95967fe845b7293f63e72f7"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x5e83c35594977f86546933b5178026be47b8d1be5e8e0e53ab62be4ed55c10b0"},{"fromBlock":20037416,"toBlock":20052857,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8f275fbf7a959f4bce59999a2ef122a099e81a8"],["0x000000000000000000000000f621fb08bbe51af70e7e0f4ea63496894166ff7f"]],"resultHash":"0x2a6bf2cf03754a3e7c15e014097dce32574345d5a0b5c0311edbe04e4279e603"},{"fromBlock":13014827,"toBlock":13052515,"address":["0x0e26a21013f2f8c0362cfae608b4e69a249d5efc"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0x64fcab7747a7010a7f60a23f256d0e088f1fe178381bab81f5312bed49796efb"},{"fromBlock":10542443,"toBlock":10562098,"address":["0x8a91c9a16cd62693649d80afa85a09dbbdcb8508","0x398ec7346dcd622edc5ae82352f02be94c62d119"],"topics":[null,["0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x18fa1e53203f344096f9b03f4609014b913e18f8b544e84c186b8ce38de6fb9e"},{"fromBlock":14044736,"toBlock":14111521,"address":["0x328dfd0139e26cb0fef7b0742b49b0fe4325f821"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000f2f400c138f9fb900576263af0bc7fcde2b1b8a8"],null],"resultHash":"0x86a247cf2041acf5c45306f3d6ee99dab2d8ca1179a6eb97d35a1622ec78f777"},{"fromBlock":3778450,"toBlock":3826264,"address":[],"topics":[["0x7d19c7776f05049226f581a23a4df896c65115763d8ec30490658efc4e8649cd"]],"resultHash":"0xe14a8f781ceae515595fe0f1f9dbf04ed441bac50b670a64ff31fdd2b0d4a3c0"},{"fromBlock":14222848,"toBlock":14229178,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000881d40237659c251811cec9c364ef91dc08d300c"]],"resultHash":"0x977472abbba5ed462de0461b34c8478d0b70259c4058c35aa1e6246a35121207"},{"fromBlock":5326722,"toBlock":5373355,"address":["0xcdaf9abed7c74b3c5abba6c168bab8fa8539c892"],"topics":[["0xbfbb2c004ee5852a056aab3d9e02f42f824fb466821c4ebee60ef24939b8fb5c"]],"resultHash":"0x2e604941a4924d72eeae7b3913bed642ba88e3d442c1b5313c7de6e41b1931f0"},{"fromBlock":13028275,"toBlock":13039896,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8","0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x9b23b50ce20903f344f5e739bd942138c46f059b822219cac77ffa1fec27cdab"},{"fromBlock":13025470,"toBlock":13041929,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8","0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x1979c6978dda79035db83d1ddbc6db32c944596512b5b9854d598c761a702a12"},{"fromBlock":13031494,"toBlock":13046760,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000088ee5007c98a9677165d78dd2109ae4a3d04d0c"]],"resultHash":"0xe34b9ec1fa8b92c2c3ce39db0a865f378b4046ab945086f156222aa25b1faf63"},{"fromBlock":20155716,"toBlock":20164497,"address":["0x95d9a1a365f01ffce582fc1d6732bb5cbf502359"],"topics":[],"resultHash":"0xf3cd5c20dfedfa11d171ffad5afbdce1dd6e0efc86dd2a95e0faf28bf1757c5e"},{"fromBlock":13033469,"toBlock":13044614,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xdbe602ef0b9158659ed92ffeb65e41d3e7ea2ad02f3fd3476351b0816a546f98"},{"fromBlock":5326722,"toBlock":5373355,"address":["0xcdaf9abed7c74b3c5abba6c168bab8fa8539c892"],"topics":[["0xbfbb2c004ee5852a056aab3d9e02f42f824fb466821c4ebee60ef24939b8fb5c"]],"resultHash":"0x2e604941a4924d72eeae7b3913bed642ba88e3d442c1b5313c7de6e41b1931f0"},{"fromBlock":16827938,"toBlock":16874720,"address":["0xd9d27decffa31c061bf3ae0a92689ed02f973d5e"],"topics":[null,null,["0x0000000000000000000000001b425529c9d7472603e2dcf125fd195f71dfb412"]],"resultHash":"0xfc498ceb56bf4b8e5c9a633363f1666b9d124ce4a4bd8d7fcad82098f0787cc9"},{"fromBlock":14520453,"toBlock":14528688,"address":["0x2acae338d313be9505736fc262a1cc2f95832ede"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]],"resultHash":"0x52fa9a5c00c40770f74e2a3096a2ea8fa328ce0b301f347bca9770e315504507"},{"fromBlock":13020352,"toBlock":13057437,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000c558f600b34a5f69dd2f0d06cb8a88d829b7420a"]],"resultHash":"0x3c0046adae57d36fc2fde5743ab4a19f958406b8bb7e289272b09d064fcf7a0b"},{"fromBlock":5326722,"toBlock":5373355,"address":["0xcdaf9abed7c74b3c5abba6c168bab8fa8539c892"],"topics":[["0xbfbb2c004ee5852a056aab3d9e02f42f824fb466821c4ebee60ef24939b8fb5c"]],"resultHash":"0x2e604941a4924d72eeae7b3913bed642ba88e3d442c1b5313c7de6e41b1931f0"},{"fromBlock":13035729,"toBlock":13044465,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000034d7d7aaf50ad4944b70b320acb24c95fa2def7c"]],"resultHash":"0x4135bfc089556eb827cd99eb59d5d8d3ff273cd5d478b0bb214ebc69712cf1de"},{"fromBlock":12971230,"toBlock":12989649,"address":["0x5b272ce3e225b019a3fbd968206824b24c674344"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xdd3403d76de432cf133aaabf13e666d0ce00ea63b0b328096f65765795001889"},{"fromBlock":14222848,"toBlock":14229178,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null,["0x000000000000000000000000881d40237659c251811cec9c364ef91dc08d300c"]],"resultHash":"0x977472abbba5ed462de0461b34c8478d0b70259c4058c35aa1e6246a35121207"},{"fromBlock":13027015,"toBlock":13053541,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000018c0ca3947e255881f94de50b3a906fc2759f7fe"],["0x00000000000000000000000018c0ca3947e255881f94de50b3a906fc2759f7fe"]],"resultHash":"0x404085839e589fc1d95b993b6257ec1efcf0d48ed36d3c45f25e349bed478c3c"},{"fromBlock":13036980,"toBlock":13043285,"address":[],"topics":[["0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x08ede5f9ef7ec4e89c604d2e37a82f5b7792868acbd38ca84904f52a9ce438d0"},{"fromBlock":13026628,"toBlock":13048002,"address":[],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000058dc5a51fe44589beb22e8ce67720b5bc5378009"]],"resultHash":"0x82d85900117034d4bb135339a1890074e2d5b5998f686fb48646c07a781fa624"},{"fromBlock":20039359,"toBlock":20052699,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8f275fbf7a959f4bce59999a2ef122a099e81a8"],["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e"]],"resultHash":"0xcddebb593e1ea60a3d8b8fac5aca10835824b6ae01a30182e768521b24425dd2"},{"fromBlock":16827938,"toBlock":16874720,"address":["0xd9d27decffa31c061bf3ae0a92689ed02f973d5e"],"topics":[["0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"],null,["0x0000000000000000000000001b425529c9d7472603e2dcf125fd195f71dfb412"]],"resultHash":"0xfc498ceb56bf4b8e5c9a633363f1666b9d124ce4a4bd8d7fcad82098f0787cc9"},{"fromBlock":13052213,"toBlock":13067980,"address":["0x99b42f2b49c395d2a77d973f6009abb5d67da343"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xd476bbbe819ea35e60b3e27617146a2bdf467b5140106e03fb51093a27774579"},{"fromBlock":20037236,"toBlock":20048327,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8f275fbf7a959f4bce59999a2ef122a099e81a8"],["0x000000000000000000000000f621fb08bbe51af70e7e0f4ea63496894166ff7f"]],"resultHash":"0xfa3f4d877fc605e893e30b5206855cd579b4147ac213a01db39a3941508be542"},{"fromBlock":13014399,"toBlock":13049195,"address":["0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xcece652f92fc21ccadb5eb62afb20c01004cacc1b10ce52633817f7140d2a55d"},{"fromBlock":13033183,"toBlock":13042385,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x61fa2f4109615a2b7950b0346230b54165054f74656c6ddbfc2566f11ee9b970"},{"fromBlock":7464086,"toBlock":7480785,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff2"]],"resultHash":"0xcb67fece631a88a9fec2ff44802244d9962895dc3d3bc4168ba80bb5b155cfec"},{"fromBlock":13033370,"toBlock":13044044,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000034d7d7aaf50ad4944b70b320acb24c95fa2def7c"]],"resultHash":"0xb4459c61c2f6c8b84c0f057f06c1330c04015817af26b649b47aa3bc65fdf135"},{"fromBlock":13028923,"toBlock":13061943,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e78388b4ce79068e89bf8aa7f218ef6b9ab0e9d0"]],"resultHash":"0x65a2249ce337625e3a9435cc731aa68f0f773db17643f2b9bebfe5d7ac3215fc"},{"fromBlock":13048703,"toBlock":13056584,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0x3707ea7c55f9d17d2ce96f5cc598ff02d4be2fa0157639dfb923334c73b3e13a"},{"fromBlock":13004094,"toBlock":13067449,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000c3d03e4f041fd4cd388c549ee2a29a9e5075882f"]],"resultHash":"0x266dc8633baa44374a1e5191843c897df6d7e86c1cc529f7e40e154b27fcad5c"},{"fromBlock":12371909,"toBlock":12434428,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x000000000000000000000000c7a1cb6edc22e94f17c80eb5b959f2ad28511d4e"]],"resultHash":"0x9e2ff5d913fe4d8aebad11d6d863e49c667d78e6774d646cba3f15f55d6f1245"},{"fromBlock":13018352,"toBlock":13064803,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff"],["0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"]],"resultHash":"0x623e351f75a5a2a8afcf29cbfd24da2b777a95214cafefd23c616ef28c1839a8"},{"fromBlock":13048703,"toBlock":13056584,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0x3707ea7c55f9d17d2ce96f5cc598ff02d4be2fa0157639dfb923334c73b3e13a"},{"fromBlock":13035476,"toBlock":13046867,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x71f9559a2bc8fc8333ef06eab3f11a677f8ee27de1668761b0699b6ccacf4ac8"},{"fromBlock":3532918,"toBlock":3540688,"address":["0x4b9e0d224dabcc96191cace2d367a8d8b75c9c81"],"topics":[],"resultHash":"0x13a9c1fce7f326993a54bccc279fac9c6705af22554e3f432a57db9240582ece"},{"fromBlock":7587153,"toBlock":7616049,"address":["0x744d70fdbe2ba4cf95131626614a1763df805b9e"],"topics":[null,null,["0x000000000000000000000000650007a41dc5477a000de8fb3ae44617c7517e3c"]],"resultHash":"0x4de91b17739fa57497dccd7c91e3296114aa9d150e7ecb9cd1c6106c40f97642"},{"fromBlock":20027213,"toBlock":20053955,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"],["0x000000000000000000000000c64350c0eab6faed8f17cc2cdff0761c53fb4152"]],"resultHash":"0x96ebc6b52d2cf5fbd51e26af733f984556ff922529aca2ba5eac7fbb3d716302"},{"fromBlock":11657142,"toBlock":11667192,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xc16c851913f9c79a1bbd64e423f911d3d0cc5510145d6bab4a72a1b6b1159bab"},{"fromBlock":13029262,"toBlock":13061696,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x5f900a7ca43e9a977d19f8207bf4e5ff6aab75ee457d89ed7d1a23bb4d2dcfbc"},{"fromBlock":10549083,"toBlock":10560254,"address":["0x8a91c9a16cd62693649d80afa85a09dbbdcb8508","0x398ec7346dcd622edc5ae82352f02be94c62d119"],"topics":[null,["0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"]],"resultHash":"0x8d315d40221556933f0ad1c9b130df873914f3bebfc05fd7f68924e8c210ecdc"},{"fromBlock":11328274,"toBlock":11387318,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000004b6baeb330334a6b2d5ef08a834751c35c49080b"]],"resultHash":"0x6ce07937b0309f457af59fa13ffb8969a0ce84218b76d2c5aec98c878638f031"},{"fromBlock":9905767,"toBlock":9965462,"address":["0x5d3a536e4d6dbd6114cc1ead35777bab948e3643"],"topics":[null,["0x00000000000000000000000000000000001876eb1444c986fd502e618c587430"]],"resultHash":"0x81da576d67d2baa57ca71c82824ae09bd69890c5620fc99d7ff0c4ca755d3685"},{"fromBlock":13033569,"toBlock":13043965,"address":["0xff64cb7ba5717a10dabc4be3a41acd2c2f95ee22"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,null],"resultHash":"0xd46e8ffc28ecac01a5ca44c715ccd52a1e2eafb6bbc39c49bcd8ea11028d17ee"},{"fromBlock":20027213,"toBlock":20053955,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"],["0x000000000000000000000000c64350c0eab6faed8f17cc2cdff0761c53fb4152"]],"resultHash":"0x96ebc6b52d2cf5fbd51e26af733f984556ff922529aca2ba5eac7fbb3d716302"},{"fromBlock":13028275,"toBlock":13039896,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8","0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"]],"resultHash":"0x9b23b50ce20903f344f5e739bd942138c46f059b822219cac77ffa1fec27cdab"},{"fromBlock":14217193,"toBlock":14242118,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x00000000000000000000000039f6a6c85d39d5abad8a398310c52e7c374f2ba3"]],"resultHash":"0x11f0bbf82d64bb17ed52486f7cf90cd9d02867a6984495b2f5619da0ba519261"},{"fromBlock":15954548,"toBlock":15983163,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000006c6bc977e13df9b0de53b251522280bb72383700"]],"resultHash":"0x5be06318f789f63870a83a750dc97e53f288613162e3afda2967cd68ba9c794b"},{"fromBlock":15209584,"toBlock":15223289,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x000000000000000000000000ba8da9dcf11b50b03fd5284f164ef5cdef910705"],["0x0000000000000000000000000615dbba33fe61a31c7ed131bda6655ed76748b1"]],"resultHash":"0x99b1849681d401f3c4232daf9ad645fb96e1e0fc0a0cebf28c823cf28f7174e1"},{"fromBlock":19439984,"toBlock":19475816,"address":["0xce407cd7b95b39d3b4d53065e711e713dd5c5999"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x5705a4b41fa629e8477f03860c61655a227a2489cebfa03e813004d437bafeec"},{"fromBlock":15954548,"toBlock":15983163,"address":[],"topics":[null,null,["0x0000000000000000000000006c6bc977e13df9b0de53b251522280bb72383700"]],"resultHash":"0xb7de838d445858370ad0d522d79acceefcd8426d9a2ba7745605abb3425ff451"},{"fromBlock":3778450,"toBlock":3826264,"address":["0xcced5b8288086be8c38e23567e684c3740be4d48"],"topics":[["0x7d19c7776f05049226f581a23a4df896c65115763d8ec30490658efc4e8649cd"]],"resultHash":"0xe14a8f781ceae515595fe0f1f9dbf04ed441bac50b670a64ff31fdd2b0d4a3c0"},{"fromBlock":13024943,"toBlock":13053579,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000005767d9ef41dc40689678ffca0608878fb3de906"]],"resultHash":"0x85e73c7338f4f1fc200dd164cc90fbd9868650a88b82332087b31fa737125a8a"},{"fromBlock":13010408,"toBlock":13059222,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x2e56d03e1674bf2c73b5f72844ae516d349d636326c7f4c62769e0f9359f5e76"},{"fromBlock":12335867,"toBlock":12346225,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000737aad349312f36b43041737d648051a39f146e8"]],"resultHash":"0x1734e117d44f5bc3b1818cacad13e10a3e3174f371e7d21a76cf0be4063e5a95"},{"fromBlock":13064924,"toBlock":13085532,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x313be4e9cb39adc87382b2adf33f06b78c011960602820edc54d55153aed15e7"},{"fromBlock":19121905,"toBlock":19156222,"address":[],"topics":[null,["0x000000000000000000000000b0aac1f129651e62cde6d1ae683c8a49f4d004d1"]],"resultHash":"0x03f6c6efbd5ed1a5e04a12f5aa4e2fca32226c4b0263f617dd2482deced4ee58"},{"fromBlock":13026464,"toBlock":13048285,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000c3d03e4f041fd4cd388c549ee2a29a9e5075882f"]],"resultHash":"0xbe8d7280be606961d2f7f7d8e70ded4b9859dad6b2dc8c92b31126b8b565ba97"},{"fromBlock":13030038,"toBlock":13036558,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8","0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x7c57c99570c75a5490eba0ce4bea85d02332460ed5df13bf1bfd767b89b41599"},{"fromBlock":20035325,"toBlock":20052246,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8f275fbf7a959f4bce59999a2ef122a099e81a8"],["0x0000000000000000000000005523985926aa12ba58dc5ad00ddca99678d7227e"]],"resultHash":"0x7ac0a1a177bc3c602d05dfada0bb7b8df0273d7e593fd4b1aadecfc2726dbf3c"},{"fromBlock":16897006,"toBlock":16914204,"address":["0x26fc1f11e612366d3367fc0cbfff9e819da91c8d"],"topics":[null,null,["0x00000000000000000000000087dde3a3f4b629e389ce5894c9a1f34a7eec5648"]],"resultHash":"0xfbe8c2092a89c166bbab015b200771ecf19a0cf036f64d9ce5e4040687e78d86"},{"fromBlock":13028275,"toBlock":13039896,"address":["0x53aabccae8c1713a6a150d9981d2ee867d0720e8","0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x9b23b50ce20903f344f5e739bd942138c46f059b822219cac77ffa1fec27cdab"},{"fromBlock":11661450,"toBlock":11669818,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xc8830413b912b4c2037d97c84f9eae5595e2a43ccd93df5fede8b934a20f644b"},{"fromBlock":11378138,"toBlock":11397745,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000d6ad7a6750a7593e092a9b218d66c0a814a3436e"]],"resultHash":"0x1da62d1f0e52df0dad1cafc8267667849218b35b6670caa742d035de04a28183"},{"fromBlock":7554995,"toBlock":7591795,"address":["0x744d70fdbe2ba4cf95131626614a1763df805b9e"],"topics":[null,["0x000000000000000000000000ba826fec90cefdf6706858e5fbafcb27a290fbe0"]],"resultHash":"0x861687092d0a0e95396d6322979c32ac1200961341113e52fe40100cd68770b7"},{"fromBlock":12991241,"toBlock":13012816,"address":["0xcffdded873554f362ac02f8fb1f02e5ada10516f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0xa622968aa51af69414a036f23fc3ab2880eb98ae3dba121eb3dcd417c923965b"},{"fromBlock":13028961,"toBlock":13061694,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000e78388b4ce79068e89bf8aa7f218ef6b9ab0e9d0"]],"resultHash":"0x5fde0bf4fef34f4d78531c56974be71d1a6d291a689927bbecd1fd181da3c1f0"},{"fromBlock":3778450,"toBlock":3826264,"address":["0xcced5b8288086be8c38e23567e684c3740be4d48"],"topics":[["0x7d19c7776f05049226f581a23a4df896c65115763d8ec30490658efc4e8649cd"]],"resultHash":"0xe14a8f781ceae515595fe0f1f9dbf04ed441bac50b670a64ff31fdd2b0d4a3c0"},{"fromBlock":13028244,"toBlock":13074804,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0xdebb3a0e9c04728fa39f0c98a70b87281271049078cbc6ceca45c64f611d6f6c"}],[{"fromBlock":11661690,"toBlock":11666222,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000006de2b77d89759c1275b99175494e29299f845cbc"]],"resultHash":"0x991c03c2c4f97f7bf066c3a2142b3b26f1697c03ef7955bee817ec03dfbe8b66"},{"fromBlock":20042922,"toBlock":20043743,"address":[],"topics":[["0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987"],null],"resultHash":"0xe8f0160471733abb03a7cf03c9c105e73a4881e762818c15d368e797a0114fca"},{"fromBlock":7372892,"toBlock":7375732,"address":[],"topics":[["0x73b3810100000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xec1431e92dada7934f15777cb1547c7509d30eb1049090a9968e465e39e5a881"},{"fromBlock":11667745,"toBlock":11668836,"address":["0xceff51756c56ceffca006cd410b03ffc46dd3a58"],"topics":[null,null,null],"resultHash":"0xc6041688d5b238f5813d792df3f0cde783a3e5f9e545851070e467782b32a731"},{"fromBlock":13040114,"toBlock":13041525,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[null,["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x8f7c9147f0a600d561b309b0793382370ae0ecb19596763d9b08cf91195a3c99"},{"fromBlock":13617849,"toBlock":13621072,"address":null,"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"],null,null],"resultHash":"0x6c7dcbb29ef3092d3d0789a490228b949e0f2be119c68714b69570d426d4edc7"},{"fromBlock":7591162,"toBlock":7592971,"address":["0x744d70fdbe2ba4cf95131626614a1763df805b9e"],"topics":[null,null],"resultHash":"0x7d4ca88c025ac57f55978fd37f5ca19d447a2ba689097a06318d6b4fff38e319"},{"fromBlock":14228993,"toBlock":14229809,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000003cd751e6b0078be393132286c442345e5dc49699"]],"resultHash":"0xce827660f8eed0c9727b01d625f274cec1b567ca9d7dc120f3d14f3956f8a108"},{"fromBlock":7266572,"toBlock":7269149,"address":["0xb6ed7644c69416d67b522e20bc294a9a9b405b31"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x380ff6080e5ed06503bfca57146bd8835ab18382357da542413c7ea9a9da088b"},{"fromBlock":13046352,"toBlock":13047770,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x0000000000000000000000000cfbed8f2248d2735203f602be0cae5a3131ec68"],["0x000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564"]],"resultHash":"0xbcfc227805d7358a75cd9a8debcb52bc40923a6db8ab989ed842e3fe7fd4cd4a"},{"fromBlock":13038453,"toBlock":13041618,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0x01332413de3f5eaffc5bba8113f04054bb04d7bc1b42801042cb32639c2ea527"},{"fromBlock":13040114,"toBlock":13041525,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x393623ef0dae1b1890407eb4ca2bd36132a59feee70841810c7e9d493273c434"},{"fromBlock":13042228,"toBlock":13044862,"address":["0x34d7d7aaf50ad4944b70b320acb24c95fa2def7c"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x252bec1e3dbc830ae8d9139de25c33d6a589839757cc99a8c00cf21e6f361ab7"},{"fromBlock":13040655,"toBlock":13041404,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0x497493dbf544ec77374bf5913b459e80a0f9f290b0e77911e9783ed2d6884073"},{"fromBlock":12722630,"toBlock":12728216,"address":["0x811beed0119b4afce20d2583eb608c6f7af1954f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x4c3625ce76141008f441e0000e6a89303794a4945baf5558133e640174beeb67"},{"fromBlock":13040040,"toBlock":13040976,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x364e3c94637bef4e98efb3923dfcadadd49f761f9686ee933b1c44351e9a09a3"},{"fromBlock":13048068,"toBlock":13053370,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x00000000000000000000000034d7d7aaf50ad4944b70b320acb24c95fa2def7c"]],"resultHash":"0x4aefc4fabeabe25ee64e398d1b18b975cbaa84b901ee3213003a9bee33aca4db"},{"fromBlock":2680088,"toBlock":2681182,"address":["0xfa52274dd61e1643d2205169732f29114bc240b3"],"topics":[],"resultHash":"0x2449848305b1a215b4e96e8f7a71e2506330a6003f3604e7ffc057583c4805b5"},{"fromBlock":13036980,"toBlock":13043285,"address":[],"topics":[["0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa411430ec2a9f71749f27b4b0b93c9cedfa396ffce1c77436f04813b6a68a9ac"},{"fromBlock":13318181,"toBlock":13320011,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,null],"resultHash":"0x40e83cbdcbf3a5046761642090499c5f11c76025c15b3303f25b5790a5f58a51"},{"fromBlock":9487884,"toBlock":9492111,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x811beed0119b4afce20d2583eb608c6f7af1954f"],"topics":[null,["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],null],"resultHash":"0xc7c9cedaea1a7c70b773fc8e6a3c0ee2a85ed94240c82547c5f34aec1569bd66"},{"fromBlock":7267433,"toBlock":7269101,"address":["0xb6ed7644c69416d67b522e20bc294a9a9b405b31"],"topics":[],"resultHash":"0xef9f03688b4f82bb21cc639135398f7a7f097c773f86054deb1f1183fb38a404"},{"fromBlock":13058747,"toBlock":13060847,"address":["0x99b42f2b49c395d2a77d973f6009abb5d67da343"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xf9ee1f54dcc133bb8efebf8df16e4de1ab4f400444e3cc8219c23e2bd3fe60ad"},{"fromBlock":13039392,"toBlock":13041853,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000006a091a3406e0073c3cd6340122143009adac0eda"]],"resultHash":"0x24212a0582990625c5bcb020e674a778d2ddaa35f0fcb3f241a56c66e0c7ee96"},{"fromBlock":14228993,"toBlock":14229809,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000003cd751e6b0078be393132286c442345e5dc49699"]],"resultHash":"0xce827660f8eed0c9727b01d625f274cec1b567ca9d7dc120f3d14f3956f8a108"},{"fromBlock":7577672,"toBlock":7580116,"address":["0x06012c8cf97bead5deae237070f9587f8e7a266d","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x00000000000000000000000039755357759ce0d7f32dc8dc45414cca409ae24e"]],"resultHash":"0xeb1dc739a44a126cc8a8be785d0525a1d151428ac2120233f05570443bb26b87"},{"fromBlock":12723374,"toBlock":12728565,"address":[],"topics":[null,["0x000000000000000000000000397ff1542f962076d0bfe58ea045ffa2d347aca0"],["0x00000000000000000000000003747f06215b44e498831da019b27f53e483599f","0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x56871e5b5447936e8a196c96fb04bec3805600ba552fd2661c53a706fee59aa2"},{"fromBlock":844081,"toBlock":845396,"address":["0x7de5aba7de728950c92c57d08e20d4077161f12f"],"topics":[],"resultHash":"0x5c3aeaf116735e195abe0271da985a606a587bc7e267d39a341632bb3ed5c169"},{"fromBlock":2942021,"toBlock":2942983,"address":["0xcd111aa492a9c77a367c36e6d6af8e6f212e0c8e"],"topics":[],"resultHash":"0xdf109a923886810ed7c6badaad10de911a6cdb92e44b7e3e079a9171939de2c6"},{"fromBlock":13036698,"toBlock":13037908,"address":[],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x00000000000000000000000074de5d4fcbf63e00296fd95d33236b9794016631"]],"resultHash":"0x2dcaba4442d8d8803387da80f8a87e3dd6b81318a52e3e0171bdc6284144667b"},{"fromBlock":10295073,"toBlock":10295809,"address":["0xcffdded873554f362ac02f8fb1f02e5ada10516f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x5da87f7d4fba8d4df26d9db0986c4c5a894b9793a26ca5ffef8bb85a45c0212e"},{"fromBlock":12724070,"toBlock":12728697,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x811beed0119b4afce20d2583eb608c6f7af1954f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0xfbcdbc0aac9359cca21013785027febede9af33ad07c03db1e8a075e2d6c5d98"},{"fromBlock":12723065,"toBlock":12728002,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x811beed0119b4afce20d2583eb608c6f7af1954f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x10ce1b306b736fc42135bf7e0687832ea71bdd786f537957207c67b6a6f0ee04"},{"fromBlock":10553954,"toBlock":10556609,"address":["0x8a91c9a16cd62693649d80afa85a09dbbdcb8508","0x398ec7346dcd622edc5ae82352f02be94c62d119"],"topics":[["0xc12c57b1c73a2c3a2ea4613e9476abb3d8d146857aab7329e24243fb59710c82"]],"resultHash":"0x05f78aff9318467ea2ec94bcfe289589e245223dc24e65a2c400700b6fa1a024"},{"fromBlock":21431396,"toBlock":21433630,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c","0x7c5e9ea400000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff"]],"resultHash":"0x14ba15b3be74ad531665eb3b4a57890f4d4db36d56424e7ebe8558897c23e077"},{"fromBlock":13040514,"toBlock":13041613,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xb0717d254638bbf3941dfd98d92351c3d767e96b0cea887df180a2bb55390141"},{"fromBlock":13051070,"toBlock":13052839,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xd9dc04cea1465239158a63afa892e5dcab1fd63495665b2126584c7583a78df3"},{"fromBlock":7564842,"toBlock":7568039,"address":["0x744d70fdbe2ba4cf95131626614a1763df805b9e"],"topics":[],"resultHash":"0x81da9cd1d11671670d481920fb265b0b6ad30ead0bcefd522e0af296c36de423"},{"fromBlock":13038947,"toBlock":13042003,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000006a091a3406e0073c3cd6340122143009adac0eda"]],"resultHash":"0x346f45be72a78e920a136e19d7577df90de5f4bd93dac603be20dc458c536f63"},{"fromBlock":13039370,"toBlock":13044992,"address":["0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9"],"topics":[["0xa0a19463ee116110c9b282012d9b65cc5522dc38a9520340cbaf3142e550127f"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef"]],"resultHash":"0x67d0ccc61032507b4bda27ab16eaae1314f38ba403cbe2bc188ea60e56486df6"},{"fromBlock":13093264,"toBlock":13099553,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x000000000000000000000000ddf8390ced9fad414b1ca1dd4fe14f881c2cfa70"]],"resultHash":"0x70a1c28215e088844d7bc03cb67fe90fd7474a0062734a9832afbaaeafba42a6"},{"fromBlock":11661690,"toBlock":11666222,"address":[],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000006de2b77d89759c1275b99175494e29299f845cbc"]],"resultHash":"0x991c03c2c4f97f7bf066c3a2142b3b26f1697c03ef7955bee817ec03dfbe8b66"},{"fromBlock":13051070,"toBlock":13052839,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xd9dc04cea1465239158a63afa892e5dcab1fd63495665b2126584c7583a78df3"},{"fromBlock":11661779,"toBlock":11665556,"address":["0xc40d16476380e4037e6b1a2594caf6a6cc8da967"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0xce1cf241fa20b46da90effb92687039b5ccdaf979ae3e59f302e931acec77bc4"},{"fromBlock":14652255,"toBlock":14654590,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xdc77f56873c07503c790047025266df1004ee0f0ec072c5cc6f00c3ad8b6a27a"},{"fromBlock":9929051,"toBlock":9930286,"address":["0x5d3a536e4d6dbd6114cc1ead35777bab948e3643"],"topics":[["0x4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc04"]],"resultHash":"0x7ccf3e243ef267a9d298b304d57e7215619b412651068888ef2b0f3d0867a05e"},{"fromBlock":21462072,"toBlock":21467905,"address":[],"topics":[null,["0x0000000000000000000000004eefe02fce5b53ca33c7717bbd8ad3c9cb0609f1"]],"resultHash":"0xce98d0efe7c11e3caa3257774ad47cd2d58d2385db13ebceecfa8dd9f93760be"},{"fromBlock":11660487,"toBlock":11666787,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000006de2b77d89759c1275b99175494e29299f845cbc"]],"resultHash":"0x3a9c0b8b67dc9b3d267c5bc3ac7e5243c11654f01b1facd77bdce3b1922b3eb6"},{"fromBlock":13039798,"toBlock":13041279,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x5df0f5f21e9a40f35d8e72e659ae5f9399e9dcb02217364539b96f59665dd40f"},{"fromBlock":13039971,"toBlock":13041378,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x706d4c3d423e6cda788dd2804c477c9210f70fb5f17b484fcb608dc3cd1bdc49"},{"fromBlock":13038651,"toBlock":13040929,"address":["0x34d7d7aaf50ad4944b70b320acb24c95fa2def7c"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x2bc5d22e5b61f9f93445440c5fc2f3d17c2f7932425ebc4f80f343727570d4b3"},{"fromBlock":13039665,"toBlock":13041010,"address":["0x024cc95611d478dd367240e72c82662d9e390a6a"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x951901ac914bb471f33eb772f78ed0323c8236a57fd56332a93bc81352754a31"},{"fromBlock":13039437,"toBlock":13044684,"address":["0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9"],"topics":[null,["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef"]],"resultHash":"0x1c05ecdf175ded74f347fd9073e7202bc1896a905cb4383a0109e54b7b7fdf3c"},{"fromBlock":13039021,"toBlock":13043745,"address":["0x767fe9edc9e0df98e07454847909b5e959d7ca0e"],"topics":[["0x769254a71d2f67d8ac6cb44f2803c0d05cfbcf9effadb6a984f10ff9de3df6c3"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x7882332e1692da27a6deec69496a13a1eb6b170f67331d3e1a014220bf93d639"},{"fromBlock":13039056,"toBlock":13041565,"address":["0x811beed0119b4afce20d2583eb608c6f7af1954f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff"],["0x000000000000000000000000e66b31678d6c16e9ebf358268a790b763c133750"]],"resultHash":"0x41e93db5313da89327599eb2e29a6223f6304e6f5c2841e135f3a69eba24a92a"},{"fromBlock":15214027,"toBlock":15219162,"address":[],"topics":[null,null,["0x000000000000000000000000acd4ec996aad815efe72a11944188c6db6c30176"]],"resultHash":"0xd9dc3d5fca4944c27d5b93143997344c49d21dd05c101538ff40b102c21c770f"},{"fromBlock":10555157,"toBlock":10556358,"address":["0x8a91c9a16cd62693649d80afa85a09dbbdcb8508","0x398ec7346dcd622edc5ae82352f02be94c62d119"],"topics":[],"resultHash":"0x0cd7e538351233bf81a0cc11ccc387d9246bd8d178d0b36c2bedbc62210a8857"},{"fromBlock":2941680,"toBlock":2943301,"address":[],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000058"]],"resultHash":"0x27148dae376160eaa994fde7a25ed3935fda149d8117ca63e7b6fb642fcd2c81"},{"fromBlock":12724457,"toBlock":12727144,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x811beed0119b4afce20d2583eb608c6f7af1954f"],"topics":[null,["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0xf3f2e78ef22949e5179fd56adfead4f3dab190d50f05a59390359dddeba9ec43"},{"fromBlock":13038262,"toBlock":13043344,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000e12af1218b4e9272e9628d7c7dc6354d137d024e"]],"resultHash":"0x9423c0ed23ece3e0cfb738499b1b12e7cedaedf0e3c9dd7e7c3e54223d0e0a5c"},{"fromBlock":13036239,"toBlock":13038128,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000027239549dd40e1d60f5b80b0c4196923745b1fd2"]],"resultHash":"0xabfcc4cd1258206fe567646e9bb708c2c7acf0df9959b6cd4132b04e2a25cfad"},{"fromBlock":12722630,"toBlock":12728216,"address":["0x811beed0119b4afce20d2583eb608c6f7af1954f"],"topics":[null,["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x4c3625ce76141008f441e0000e6a89303794a4945baf5558133e640174beeb67"},{"fromBlock":20798827,"toBlock":20802879,"address":["0xae7ab96520de3a18e5e111b5eaab095312d7fe84"],"topics":[["0x9d9c909296d9c674451c0c24f02cb64981eb3b727f99865939192f880a755dcb"],["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x5186730411725013a4516f295891dc23448668f76cd0e60a69b97b269edcb3f8"},{"fromBlock":14898675,"toBlock":14899540,"address":null,"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0x22d7726010bd1dfcbae718440c5b65989a327104aaec44c4c7a1128e7b71a9da"},{"fromBlock":20042635,"toBlock":20043870,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000fbeedcfe378866dab6abbafd8b2986f5c1768737"]],"resultHash":"0x73a2d4de8f594b61a4b8aac7cd337c5cac815c041613138ab9d2d0d19eb42a5c"},{"fromBlock":3534392,"toBlock":3535921,"address":[],"topics":[["0xc7e416c5685d8971558840f05c5e63e02575b29997d8da6b9ba44dc10da6a370"]],"resultHash":"0x4761586aa5f2eaa54070a294d435f35ed5b9970098b5c63257090754d8424d0f"},{"fromBlock":13036585,"toBlock":13037963,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x00000000000000000000000074de5d4fcbf63e00296fd95d33236b9794016631"]],"resultHash":"0x57c84b64864223cbb9c14d8ba8f08324e626d770f0cd617c895106afc2bfbb70"},{"fromBlock":13039251,"toBlock":13042675,"address":["0x767fe9edc9e0df98e07454847909b5e959d7ca0e"],"topics":[null,["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xfba67e360c98dfb967bcfaa77bff5875a1cc7646e8ac375138b240df8ebef80b"},{"fromBlock":13036279,"toBlock":13043818,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000e12af1218b4e9272e9628d7c7dc6354d137d024e"]],"resultHash":"0x54390e0dfaca9e4bdcb42e8d0d1b9b89076ab6acc8f4be1b07d509e26eb478c3"},{"fromBlock":14227986,"toBlock":14230065,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xadd7e577c4a34d9a80e8367674e1e252d68fbef73effaee96f6c0d93e0914939"},{"fromBlock":13038603,"toBlock":13041823,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x0000000000000000000000006a091a3406e0073c3cd6340122143009adac0eda"]],"resultHash":"0x22d913e204de5979f8657bae357fa1cdbb3a963071a8ca8c54717b2ac4d895b3"},{"fromBlock":13031913,"toBlock":13033205,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0x228cb394791c1bda35b689cc6d6d3b8a26d82f9ec465b239e69c45e05bb18def"},{"fromBlock":12204902,"toBlock":12207298,"address":["0x37ac54dc7dd237eecfd0b61efdd57b15fe158be0"],"topics":[["0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"]],"resultHash":"0x766ed453fd17d6ebf9caf2c5a5feef6d1095071c278171f37d6b81bf4f453c56"},{"fromBlock":15842864,"toBlock":15848444,"address":[],"topics":[["0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9"]],"resultHash":"0x0dd2c18e45a552db99ad07ecd1bfe337d862567cbdfcf2a25955ce5802de180d"},{"fromBlock":13069964,"toBlock":13071228,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,null],"resultHash":"0x46797e22d82ef19f6bc8b48922bddb43c00090746bac4e5ad381d988b03224bb"},{"fromBlock":13216293,"toBlock":13217569,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xcd0d6949b39c7830296826a1b5c0972af6a98729144d9920bc8bc26b4fbe8aa0"},{"fromBlock":13046526,"toBlock":13047579,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x0000000000000000000000000cfbed8f2248d2735203f602be0cae5a3131ec68"]],"resultHash":"0x2790678b3e25cc78e1d028872149843bf75e30ff87f43de30a514fc072afffc8"},{"fromBlock":13040353,"toBlock":13041431,"address":["0x397ff1542f962076d0bfe58ea045ffa2d347aca0","0x7b504a15ef05f4eed1c07208c5815c49022a0c19"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xc50785a40596f0ede84630437f42b14ad38cfb4e709f4d457b0960e7d11b5a5c"},{"fromBlock":7654197,"toBlock":7655358,"address":[],"topics":[null,null,["0x000000000000000000000000cbc6a023eb975a1e2630223a7959988948e664f3"]],"resultHash":"0xc1ea8e577273ffa5458001fbead1ffac93823fcb7e1576ede5e10cea3d86154b"},{"fromBlock":10555345,"toBlock":10556439,"address":["0x398ec7346dcd622edc5ae82352f02be94c62d119"],"topics":[],"resultHash":"0x8d7cc5872ce1e3d1508c7abc1f8d59762ff1eb1d6ff0042255c0776d75aa217c"},{"fromBlock":14989083,"toBlock":14990778,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000001111111254fb6c44bac0bed2854e76f90643097d"],["0x00000000000000000000000074de5d4fcbf63e00296fd95d33236b9794016631"]],"resultHash":"0x06803c6bb685bf3c09faf07ff7fd79ac717a14ded328284fd3f03c8cb0484ce6"},{"fromBlock":3953800,"toBlock":3955192,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xcfaee5aaa72ac4e1696fba1eea2630389b0436f124de1850947bbccf92d8c2dc"},{"fromBlock":13037971,"toBlock":13044033,"address":["0xe12af1218b4e9272e9628d7c7dc6354d137d024e"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x6fbe087696e4ce4769fb3eb5a9c31e12b326ec249712584ef8f2fbcea182690b"},{"fromBlock":16714077,"toBlock":16715539,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000001111111254fb6c44bac0bed2854e76f90643097d"]],"resultHash":"0x2243900ab78eee08408829c4f61f0ee3d7e1c3a3700247f03718cde7d4ff90f7"},{"fromBlock":13034541,"toBlock":13040108,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0x53aabccae8c1713a6a150d9981d2ee867d0720e8"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0x5a16ecf4180b12c76605892ddbcbc3190b321fd0b10a3e689042e9ccaef64b85"},{"fromBlock":13039882,"toBlock":13040928,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xca9451ae9b9d76af6cf8a992e6ce439b14c2bfff6dab7f0f7eb9169f57aae5b8"},{"fromBlock":13039281,"toBlock":13041551,"address":["0x811beed0119b4afce20d2583eb608c6f7af1954f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff"],["0x000000000000000000000000e66b31678d6c16e9ebf358268a790b763c133750"]],"resultHash":"0x21f185c79b47a38e71feb0fb23daf8692d368687b9e921241b9408026627cdd3"},{"fromBlock":844081,"toBlock":845396,"address":["0x7de5aba7de728950c92c57d08e20d4077161f12f"],"topics":[["0xcc494284735b76f0235b8a507abc67ce930b369dac12b8a45e49510ccee0abe5"]],"resultHash":"0x1b9cc53446457661d61127ea84d9f73a0f7f7c84b55fdfddb4637f88ccfb5c9b"},{"fromBlock":13039376,"toBlock":13041129,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff"],["0x000000000000000000000000e66b31678d6c16e9ebf358268a790b763c133750"]],"resultHash":"0x800fe9edfbb8e77b189a6550090de250db3b21cff862d6032f7414e80935c54a"},{"fromBlock":3714914,"toBlock":3715553,"address":[],"topics":[["0x90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15"],["0x0000000000000000000000001e9939daaad6924ad004c2560e90804164900341"]],"resultHash":"0xd6b3b0a8c18b1f56fd8918f103750305b0ff719ceb1995e6ad24a054eaacbb54"},{"fromBlock":12878757,"toBlock":12879703,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xf027c053af2709b8d30bab1450986b6ea6d9cb7a133508a03454d3c8747121f7"},{"fromBlock":20798313,"toBlock":20801576,"address":["0xae7ab96520de3a18e5e111b5eaab095312d7fe84"],"topics":[["0x9d9c909296d9c674451c0c24f02cb64981eb3b727f99865939192f880a755dcb"],["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0xa04b6a3c00ac96ccae8faf1fa6e90e9cb3991ce3a8a720ca43d8c8f5b9e220da"},{"fromBlock":13038453,"toBlock":13041618,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0x01332413de3f5eaffc5bba8113f04054bb04d7bc1b42801042cb32639c2ea527"},{"fromBlock":7577672,"toBlock":7580116,"address":["0x06012c8cf97bead5deae237070f9587f8e7a266d","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000039755357759ce0d7f32dc8dc45414cca409ae24e"]],"resultHash":"0xeb1dc739a44a126cc8a8be785d0525a1d151428ac2120233f05570443bb26b87"},{"fromBlock":8754374,"toBlock":8756402,"address":[],"topics":[null,["0x000000000000000000000000fbb1b73c4f0bda4f67dca266ce6ef42f520fbb98"]],"resultHash":"0x6fa13d499317aaa09f9975eab6531079442dad6bf03bcf4c73d70d615fe314ad"},{"fromBlock":13038459,"toBlock":13041142,"address":["0x9cbfb60a09a9a33a10312da0f39977cbdb7fde23"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x08f636ed5aec543aee94aaafa124d7ade9176ee662d579974ad435760e7b973c"},{"fromBlock":13245760,"toBlock":13246585,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa6e5762044b187773ae36f515a157e8193f0fb9ddb9af8a544b4dd7333366dc8"},{"fromBlock":13039720,"toBlock":13041085,"address":["0x024cc95611d478dd367240e72c82662d9e390a6a"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x919e57e39f13885d118a06a2ab9745476b8614bb2fe1916b394a38813742b135"},{"fromBlock":13040142,"toBlock":13041044,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xb428e43351cd018b1e5333eaad975b7e7cf4fbc8ccb65f8a391e154ee8ed5b04"},{"fromBlock":13069964,"toBlock":13071228,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[null,null,null],"resultHash":"0x46797e22d82ef19f6bc8b48922bddb43c00090746bac4e5ad381d988b03224bb"}],[{"fromBlock":10206719,"toBlock":10206839,"address":["0xbcf935d206ca32929e1b887a07ed240f0d8ccd22"],"topics":[null,null,null],"resultHash":"0xd792b96604c4bc2484adb93bc948b781435815d0f0e65c28fe190a594d385c79"},{"fromBlock":3714936,"toBlock":3715405,"address":[],"topics":[["0x90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15"]],"resultHash":"0x459d70aaea32485b880f081e34ef6d0bb533de9e89b683deb48e303e056974e6"},{"fromBlock":7441446,"toBlock":7441498,"address":[],"topics":[["0xefaee3c90b37d63765790779d33d0b50dbd22a4eb719facd2a4863412441d2e0"]],"resultHash":"0xa627c74b2bb09bf6b0a57020fdd5763f9e301da254b49715e932280ee0da1e2f"},{"fromBlock":13039731,"toBlock":13039910,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x1f6c377498f7aef252b8bd49dd2e2990ab7d48bac1ad752872a03d2e69794889"},{"fromBlock":9853030,"toBlock":9853092,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]],"resultHash":"0x1a8f110aaa73d8cb5e4ebbdf6f64d6750d589a417efcee1504ea273a03e5d342"},{"fromBlock":20049731,"toBlock":20049854,"address":[],"topics":[null,["0x000000000000000000000000f3de3c0d654fda23dad170f0f320a92172509127"],null],"resultHash":"0x105d070d58b265afbef263834c0455789fc932ec1f40d674727a4effe574a0ff"},{"fromBlock":13040509,"toBlock":13040580,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x47f8d5ccb4ee50f957a2aca1bd72c6e40d85026d1c95914091a01f00bb36f8a1"},{"fromBlock":13040843,"toBlock":13040925,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xe2e1a70f9ee718986f3efbc8bd2822619e1deb559f4fa830354be920b643c232"},{"fromBlock":2774142,"toBlock":2774576,"address":[],"topics":[["0x23919512b2162ddc59b67a65e3b03c419d4105366f7d4a632f5d3c3bee9b1cff"]],"resultHash":"0x02dfa71a64417d69e00cfeb5a3344db53a40c892310d8d6a6d765bdee1f86070"},{"fromBlock":13037118,"toBlock":13037214,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x23a53724f262e66c52b9a6aef5dca73df9e12e89d1760ccec59c9178d9dd11f3"},{"fromBlock":8139167,"toBlock":8139324,"address":[],"topics":[["0x8940c4b8e215f8822c5c8f0056c12652c746cbc57eedbd2a440b175971d47a77"]],"resultHash":"0xd2c3502453e38496ab05500933d2ed830a993ced59497a43124759d401a9c4a4"},{"fromBlock":1940173,"toBlock":1940921,"address":["0xbb9bc244d798123fde783fcc1c72d3bb8c189413"],"topics":[],"resultHash":"0x54222846f6ca453034e8c7e7f5f6099c38160581ea65271ae7f795a524a997ee"},{"fromBlock":10097706,"toBlock":10098287,"address":["0x8a91c9a16cd62693649d80afa85a09dbbdcb8508"],"topics":[["0x35351404ba8a24ad4037a3df787e21ae5c0da5615468b58f6dec0925db0dea68"]],"resultHash":"0x03f1a8356137889542bfbdff532e098fbff6cbd905bf5ec32014f507d37d1a82"},{"fromBlock":20957125,"toBlock":20957177,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xc1e93c10a81bd5d5e51631125c26a626d1c62b470f77d342c2ac44b23239a3a7"},{"fromBlock":17601656,"toBlock":17601774,"address":["0xebd16e764ce252a6b1e07b062dcfb876e1b8a3f6"],"topics":[null,null,null],"resultHash":"0xad2c8cd311102613b6b2fb258ec6fb93479543122e1965409ca437a447ebfecb"},{"fromBlock":13046809,"toBlock":13047075,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x0000000000000000000000001a2a1c938ce3ec39b6d47113c7955baa9dd454f2"]],"resultHash":"0xa6bf6d643777510f77d856ffa92e243491eb270e0cd72c70d1653526eae44c7f"},{"fromBlock":12205584,"toBlock":12205774,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000011111112542d85b3ef69ae05771c2dccff4faa26"]],"resultHash":"0xa162f18cf766565087fd2e78fd88c2343579160ba221b1b3b01a9de7d0e5731d"},{"fromBlock":13040461,"toBlock":13040556,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x0000000000000000000000000cfbed8f2248d2735203f602be0cae5a3131ec68"]],"resultHash":"0xec8aee7724142d5c50fc9fb0cf17f38d02f4cfcf8132a7ab35ba29c610049de8"},{"fromBlock":7578677,"toBlock":7578799,"address":["0x06012c8cf97bead5deae237070f9587f8e7a266d","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[],"resultHash":"0x321db676e45cbdf1fce723fb7c4abde1079e65ce8c73f9e539052351c755463a"},{"fromBlock":13038716,"toBlock":13039195,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0xc229cc32913535694c0009703e1ec9d83868b283342142acd3d728ae65f6fc72"},{"fromBlock":12961841,"toBlock":12961984,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0x9bfa392f33b5757f195251927fe6290c0a98bdc19870b1963df919c27a5eaf69"},{"fromBlock":13040560,"toBlock":13040649,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xc22d893889d8670ccc1c1dfff4f3ced41914ca06b0f79929b2ef9f4237b98694"},{"fromBlock":10097959,"toBlock":10098035,"address":["0x8a91c9a16cd62693649d80afa85a09dbbdcb8508"],"topics":[["0xa0538452cc1d076ff5b8d3f28c9dc9694023cce753f22d03e2af7d86459d2437"]],"resultHash":"0x2af1d0bdb5e8d3c0640440872672d3626ff591d80f7d882211c3715faa7ad8a4"},{"fromBlock":3331403,"toBlock":3331487,"address":null,"topics":null,"resultHash":"0xc23046934996ef25e1ae025617faf5a2d418a43c716a88391c02dcea232a6b5d"},{"fromBlock":13040266,"toBlock":13040681,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x55d4f97da3ae29fda22b9edaf20bd9a43d64b0100c4f19248f563880e75ca948"},{"fromBlock":2774299,"toBlock":2774449,"address":null,"topics":null,"resultHash":"0x8564efb04942acf0a6001554a44dade9b0c2e81e7b474d97f457beaca42f0ade"},{"fromBlock":13040026,"toBlock":13040175,"address":["0x6b3595068778dd592e39a122f4f5a5cf09c90fe2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x117dadb8f36cc23a1fe49ebcfc254ef705c301d999b6730a1686e126c446052a"},{"fromBlock":13039818,"toBlock":13040056,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x7fa53f469ff9ff0ef7da04adcdb242a0a986e452027d868d21b649a0a6a5e953"},{"fromBlock":13040574,"toBlock":13040699,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x38d809aa5eddf595a4bb72c988a6c8253d9accba2784702a786ff287d53dbf8a"},{"fromBlock":20923038,"toBlock":20923190,"address":null,"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0xdf040499d10c091cfaae3e38273d1419afbc02a565bdcb708c52527fda3c95bb"},{"fromBlock":942370,"toBlock":942664,"address":["0x276c5c6ca8507ed7bac085fc9b9521f4f54b58d3"],"topics":[["0xea0f544916910bb1ff33390cbe54a3f5d36d298328578399311cde3c9a750686"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x57ec38081ed656e50b8cc881530ee38f19570bed575534458e390ab2c0156b55"},{"fromBlock":1960709,"toBlock":1960788,"address":null,"topics":null,"resultHash":"0x7da9eea290afceee604d5acaf177aed292ed636e66a9d31035e668f86487e680"},{"fromBlock":3427303,"toBlock":3427508,"address":[],"topics":[null,null,null,["0x54494d4500000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x2779a8d0073730e51744539439016db00ccaa62449da5c2da475c75e95ae120f"},{"fromBlock":2774159,"toBlock":2774577,"address":null,"topics":[["0x23919512b2162ddc59b67a65e3b03c419d4105366f7d4a632f5d3c3bee9b1cff"]],"resultHash":"0x8c1736360c858672b83cdbd65b2bb707c63ab98c8fa99e01a7a6b3565e22f51d"},{"fromBlock":12892097,"toBlock":12892437,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"]],"resultHash":"0xad2fd917b403093baca57b9f5ea7b4226d02f9ccad99372267ee800e3cff0330"},{"fromBlock":13039737,"toBlock":13039900,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378","0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x847f83dabf7c48e9c599ff5d21d5c305ad4c5d94bb250d874e810a05da2c5bbe"},{"fromBlock":13042309,"toBlock":13043035,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xef9571206a5bd691b61d99e34e1aa6d2cf98ee2bb72aa795497ab216a08a216d"},{"fromBlock":13476070,"toBlock":13476211,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0x610b17eee0cbcc519ae5d16488e93df779ab091945ec580d79344c437b53d69c"},{"fromBlock":16236568,"toBlock":16236726,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xa0ce0fc284eb64aa3ea49d08b1a7418fdd066321fdf49e69f2a7787bb3d52284"},{"fromBlock":13040233,"toBlock":13040770,"address":["0xe12af1218b4e9272e9628d7c7dc6354d137d024e"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xc0eef932fe7c5d3838897d39036555ab86408fed77ee2c8ae2ba52bd541e6fea"},{"fromBlock":13318886,"toBlock":13319225,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[null,null,null],"resultHash":"0x3e424ed897171ede702da60252e9d6646d5a4c89f0363bba173e5177c46c9a2d"},{"fromBlock":11662850,"toBlock":11663001,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0x767edb0eb817be3c2fecb927e607a2f0d86f3503cd10cdb86ef54912169bb92a"},{"fromBlock":10097706,"toBlock":10098287,"address":[],"topics":[["0x35351404ba8a24ad4037a3df787e21ae5c0da5615468b58f6dec0925db0dea68"]],"resultHash":"0x03f1a8356137889542bfbdff532e098fbff6cbd905bf5ec32014f507d37d1a82"},{"fromBlock":13040449,"toBlock":13040557,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x28169c7008c0339805b42c7da0b50a90cd483cc0f399a9674b94bbe111af0568"},{"fromBlock":1447756,"toBlock":1448151,"address":null,"topics":null,"resultHash":"0x781192e87e2b5d6df7d2951205ce02a382e8ad4e2a2247101bd055819cdbec64"},{"fromBlock":11392095,"toBlock":11392258,"address":["0xf5b0a3efb8e8e4c201e2a935f110eaaf3ffecb8d"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x09243490ea2d6a519a4d7002d2fead39840e64a79fe75926626e722e0e43068d"},{"fromBlock":13040504,"toBlock":13040576,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xa4745f253839f0a4fb6569a142e1929ac4b33da5328e3d40a38d7e89bbb021bf"},{"fromBlock":14883294,"toBlock":14883580,"address":["0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc"],"topics":[],"resultHash":"0xc0cdca0f063eb8a0e72d3aa02b83de0ef83ddd447fc536c8d3c51d4ec6cddbf1"},{"fromBlock":16714648,"toBlock":16714869,"address":[],"topics":[null,["0x0000000000000000000000001111111254fb6c44bac0bed2854e76f90643097d"]],"resultHash":"0x200533f43d156a414baef4ebe3b97946608baa96c22a0408e4f538f9527e0d29"},{"fromBlock":3534732,"toBlock":3534956,"address":[],"topics":[["0x78e4fc71ff7e525b3b4660a76336a2046232fd9bba9c65abb22fa3d07d6e7066"]],"resultHash":"0xb75ad826cb866124c423bc036435f78781193b814b15c4c9980095d3bca02eda"},{"fromBlock":11664073,"toBlock":11664711,"address":[],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x69a9e52f9951ce8c055b9c3e832d2cbdd11efd53ec7fd09817e2569cc9d5d7d8"},{"fromBlock":13024437,"toBlock":13024599,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x00000000000000000000000063945489ef54398f3ccc8cb44f2a93ba1ac91ab8"],null],"resultHash":"0x1fac348588933c195c32822c80d9408752fb4cbb6f0f52a7bde301c5f7bca2c1"},{"fromBlock":13040474,"toBlock":13040534,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x12eff26cb1ac6f324ce5bd99d6b03ae647587a201b8b61b8e987e983f9175e9a"},{"fromBlock":13039824,"toBlock":13039900,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xf507f6e5b10289e97b2125792f04e0edbf817644960c8620b7c8e53c6b390551"},{"fromBlock":13475874,"toBlock":13476331,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000594fe7c3d4c52c0e9ab377bc6d8acd66adc8ea9d","0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0x4db12e325e8a8e10358875876c94dd611ed1cf9262b89a1a6ec6d131435a43a5"},{"fromBlock":21463506,"toBlock":21463623,"address":[],"topics":[["0xed99827efb37016f2275f98c4bcf71c7551c75d59e9b450f79fa32e60be672c2"]],"resultHash":"0x0a39768360340110edc00269da50d5edb7cf00f38f303c270ef6bcfdc73fdd6e"},{"fromBlock":13040410,"toBlock":13040487,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x3a3491d504cdece799c5a6741c354088882401f25c502d59a11ba71f540da3dd"},{"fromBlock":10295449,"toBlock":10295573,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xe75f6d1fa2b0c0b65f8b55b98a57d16f6e664dfbef670ec669469cb84088f579"},{"fromBlock":5357744,"toBlock":5357823,"address":["0x4540fcf016bcb67290c3e14238702c64e6a51600"],"topics":[],"resultHash":"0x16dea750684eda1543d86e6cc562282433c7a1c37b5a7bd6752b79f50fa7a2a0"},{"fromBlock":7567899,"toBlock":7568409,"address":["0xd1ceeeeee83f8bcf3bedad437202b6154e9f5405"],"topics":[["0x5bdd2fc99022530157777690475b670d3872f32262eb1d47d9ba8000dad58f87"]],"resultHash":"0x9e6ed7f2aa537c3c09db147112de187de0d08eeb666ce7e25e74f677791e3432"},{"fromBlock":5573149,"toBlock":5573367,"address":[],"topics":[null,null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x4cfbff18374cbf9f37387fffb626643b45de897d75e5dd540ae5d4bd99d3808f"},{"fromBlock":12892139,"toBlock":12892574,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],["0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"]],"resultHash":"0xf46661478ccbe277be6d327fd58147561ae633d0859dc134a122904440b5d33e"},{"fromBlock":8408238,"toBlock":8408393,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[],"resultHash":"0x52aa70ba25e111f099abde1409f6da8bce82a943c5d27cc498de7fbb04e9f9eb"},{"fromBlock":13040609,"toBlock":13040681,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xfe9a46dbbd8e77330d03aed7249e7c95bc1bac3424cf68767a4a9b6f81ba7703"},{"fromBlock":5542264,"toBlock":5542392,"address":[],"topics":[["0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567"]],"resultHash":"0x48c6213aeca511bbee472f36e1cae81cf985646e4996e6f1d13d1179ffa4e1db"},{"fromBlock":12836700,"toBlock":12837002,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000a57bd00134b2850b2a1c55860c9e9ea100fdd6cf"],["0x000000000000000000000000fe7444f63e0010a7208529608eb173760629483b","0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x2b7b039b831f6070de1b7e6021f562d4ae9f61741de52f380ed4b20cca748cb0"},{"fromBlock":6051324,"toBlock":6051373,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x3c33999dec4d7c9d55a752fcf517ee9066bdb16e611bf3432e76753a3a8d2672"},{"fromBlock":13037443,"toBlock":13037578,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x0212abf4faf32bace62b149b654ab40455ef7bf2fadb930482d595729304769b"},{"fromBlock":13040275,"toBlock":13040401,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xd5dff86990ba5b5052de203fecd49e354057ee5be14acf115b5bda2faec5a8e8"},{"fromBlock":9929342,"toBlock":9929782,"address":["0x5d3a536e4d6dbd6114cc1ead35777bab948e3643"],"topics":[],"resultHash":"0x7fcca1fc83bad8eaf8e6f07ec3ab45b0451c1010da560dfa2ab36e68941ae614"},{"fromBlock":7445323,"toBlock":7445591,"address":["0xba3ed686cc32ffa8664628b1e96d8022e40543de"],"topics":[null,null,null,null],"resultHash":"0x64fb7ec10914129165c7deef69043c9c4379bcc3142614eb37111d5510135919"},{"fromBlock":13318908,"toBlock":13319153,"address":["0x514910771af9ca656af840dff83e8264ecf986ca"],"topics":[null,null,null],"resultHash":"0x2414b06a21edbc2258891d07e00846eb7b8bbdb4a5de8a813114b9b7bde2fec5"},{"fromBlock":13040375,"toBlock":13040756,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x7789eaf16b0625516e7d2cd0d51da805cea96d53e54d3fe3644730c37d028542"},{"fromBlock":18343780,"toBlock":18343981,"address":[],"topics":[null,null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x96417af1c8e8fbf698e8df8d9a1c63fc87baa4e71ab30d929e8b4620795ea79c"},{"fromBlock":12892182,"toBlock":12892378,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"]],"resultHash":"0xf50d43236307de2de4d79f1d788956ee5f85036c781f2eaac343f83321f2522e"},{"fromBlock":15671326,"toBlock":15671799,"address":["0x49ff149d649769033d43783e7456f626862cd160","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,null],"resultHash":"0x23dfde4309ccc2559111fa06b03b382bf0eb8b5fc3c3c8434ca8d53fdfea850f"},{"fromBlock":13040160,"toBlock":13040795,"address":["0x06da0fd433c1a5d7a4faa01111c044910a184553"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0x8806548ddacecfb5eadb00b76fa83530f0c0f77fde4db13dec34bdc842e54fdd"},{"fromBlock":13039818,"toBlock":13040019,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xd2f61c353fbf9de4bdb1a1ebd959910658a3d87b04866e46f73b7c3ef348576a"},{"fromBlock":20042968,"toBlock":20043723,"address":[],"topics":[null,null,["0x000000000000000000000000fbeedcfe378866dab6abbafd8b2986f5c1768737"]],"resultHash":"0x5ebcd58fcbc0e945cc4a9202657db70d62dfe735ef76782c680e233bd9190373"},{"fromBlock":11695575,"toBlock":11695866,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,["0x000000000000000000000000b8a5a55a34d92757f4d440e58927c9191fcb2166","0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852"]],"resultHash":"0xf2b0af884b69e1e6759703f1bf9f65680bf914d96fa78addd355c22f759048df"},{"fromBlock":13039715,"toBlock":13040581,"address":["0xfa52274dd61e1643d2205169732f29114bc240b3","0x877d9c970b8b5501e95967fe845b7293f63e72f7"],"topics":[null,null,null],"resultHash":"0xacb517414c25d227f929e1728269eca6d936d1f01d1da3120e33f36e2177b19e"},{"fromBlock":12891963,"toBlock":12892259,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,null,["0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"]],"resultHash":"0x2225ba09325a5e0ebb8f4b75bb5804c788ab299a8adfc6bce359b6f4ac9f8034"},{"fromBlock":13040520,"toBlock":13040613,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xb536d7f4cfa3be1b3bf1080877c84e278e667ca581cdb2862e6aa96af5449b77"},{"fromBlock":13050666,"toBlock":13050816,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0x12a4aa27e86c6f0765805e7e291c1814ca3efdfa9ab107651eca3037be929308"},{"fromBlock":13038832,"toBlock":13039205,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],null],"resultHash":"0x6b7ae5a21e1be59033c5e58c0d3aa6545b5811e6d3732b7312f6156d9edd782f"},{"fromBlock":18343729,"toBlock":18343946,"address":["0xc662c410c0ecf747543f5ba90660f6abebd9c8c4"],"topics":[["0x9592d37825c744e33fa80c469683bbd04d336241bb600b574758efd182abe26a"],null,null,null],"resultHash":"0x9305fe64df1cd4b7e89a991a69101d680c2ba6cf7e59c5e46990ac7d93b1d329"},{"fromBlock":13785421,"toBlock":13785495,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xa4f8c66a7e742a8ec5ba155f4b4f6556509266be514f2f795cf7dc6cd6d802bb"},{"fromBlock":13040602,"toBlock":13040673,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xf8821108b1703edf3125bd74c3b958fdc24c05d5b1353a0766665ad3e867f916"},{"fromBlock":942370,"toBlock":942664,"address":[],"topics":[["0xea0f544916910bb1ff33390cbe54a3f5d36d298328578399311cde3c9a750686"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x57ec38081ed656e50b8cc881530ee38f19570bed575534458e390ab2c0156b55"},{"fromBlock":1940441,"toBlock":1940609,"address":null,"topics":null,"resultHash":"0x2d724c4b8f3f7f93efd9ba5e32f0b4aa38b6cc19b98475c039b6ec2b8257b6e5"},{"fromBlock":10166417,"toBlock":10166497,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[],"resultHash":"0x2a43cb2d19bc3e9e37dc9b2ad609d76cf1887bfbc0d1ed2ad74ce5b675926b09"},{"fromBlock":3534751,"toBlock":3534921,"address":[],"topics":[["0x23919512b2162ddc59b67a65e3b03c419d4105366f7d4a632f5d3c3bee9b1cff"]],"resultHash":"0xc76ee4aa2e83e71f31d95ff8a893a156652da6e9bbbe9b3b7b4a331de7db1aa1"},{"fromBlock":12205543,"toBlock":12205964,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x00000000000000000000000011111112542d85b3ef69ae05771c2dccff4faa26"],["0x00000000000000000000000074de5d4fcbf63e00296fd95d33236b9794016631"]],"resultHash":"0x4eeefecafc207a9ae4007f44a3e1de74b3eb45590fc5f6f2fc87c68201494f18"},{"fromBlock":7566927,"toBlock":7567331,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[],"resultHash":"0xee3f8e540a0907cde3bf423fc9ed3bb40774e22b7da6c4a31e978f1094e236f9"},{"fromBlock":2111717,"toBlock":2111871,"address":null,"topics":null,"resultHash":"0x0d3962e49ba36ffff2dc34c74cbad1ecd8970f68501e1582853f2f8eec76ebc2"},{"fromBlock":13024437,"toBlock":13024599,"address":null,"topics":[null,["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x00000000000000000000000063945489ef54398f3ccc8cb44f2a93ba1ac91ab8"],null],"resultHash":"0x4895ee1adb27632ac084830aff16942b6272a54e91b04c92c2fec06b18505bd9"},{"fromBlock":20799049,"toBlock":20799403,"address":["0xae7ab96520de3a18e5e111b5eaab095312d7fe84"],"topics":[null,null,null],"resultHash":"0xa10430acaa753245e8fa441b2a863062bbe1a8610e7f79a24699ef3b18f0d228"},{"fromBlock":7567091,"toBlock":7567520,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[],"resultHash":"0x6316fafa6180b283db9b60c78ead580a86c62079ca3b7cd26199cc4a6ef3a757"},{"fromBlock":13047430,"toBlock":13047807,"address":[],"topics":[null,null,null,["0x000000000000000000000000bb0e17ef65f82ab018d8edd776e8dd940327b28b"]],"resultHash":"0x7d407aae4b85467cdffccb30f28dc191efad511bb6a8d2c92599270506650c6e"},{"fromBlock":13075394,"toBlock":13075670,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xf7f197956deebf17e8cad217e623578dcc8b10cb2b3189fa0d76efc5a977e7ac"}],[{"fromBlock":13040363,"toBlock":13040376,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null],"resultHash":"0x0c85940b815535c18e1f954d0671084785ae23c4b5346b5e2e2c952208321b66"},{"fromBlock":13041601,"toBlock":13041612,"address":null,"topics":[null,null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000024cc95611d478dd367240e72c82662d9e390a6a"]],"resultHash":"0xf08a34f7413b5403f3f9283cf2cef3e206685d3af3d32b38948e3e5ed4ca6d60"},{"fromBlock":13040474,"toBlock":13040534,"address":null,"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xbac98c1f7d46e515d3f1318ae16541319d01c01dcb06671046018c8c812e33ca"},{"fromBlock":13037013,"toBlock":13037027,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],null],"resultHash":"0x5dfd02e729509f8e1465f1cf29adea2a54e106ed4b746b331b11ca88233854ac"},{"fromBlock":3798448,"toBlock":3798472,"address":null,"topics":[],"resultHash":"0xc32fe14ac305fdba7ac39c90103b3b0fe052f9ee2b1517102ed333ccf9a1e83d"},{"fromBlock":13040553,"toBlock":13040593,"address":null,"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xf9cf42d7ac449de2b29e13c2cd4230f905bbd6259377a8baa5489fbfc4dca63e"},{"fromBlock":3715172,"toBlock":3715195,"address":null,"topics":null,"resultHash":"0x038255591685e988b35be479347a93590cbba04ad429e3c32a12075b707c3b32"},{"fromBlock":13040615,"toBlock":13040637,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x173f776c471a86f2099c94dd0281b34debad5d1ff7865b6ce685e7264cf3aa28"},{"fromBlock":13040671,"toBlock":13040671,"address":null,"topics":[null,null],"resultHash":"0x7e026b9febf1b7895e638f9b975c6a1cded538b70ee004c32db6b3af725ce571"},{"fromBlock":13039864,"toBlock":13039924,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x94be78bfa67aac8239cb81a4cac1d147b08b1ec35c35f5167f2637087c340682"},{"fromBlock":12985494,"toBlock":12985535,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xb4d015acca9ea24f72d30b5dcafb4e1fefec0e6b8e55bb0a58bdbf9b2d2df437"},{"fromBlock":13039495,"toBlock":13039513,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null,null],"resultHash":"0xd39763306410f4e11d1e249663e6c5af68f7dd31c8e319c58b5f0ed3c51f0604"},{"fromBlock":13039792,"toBlock":13039821,"address":null,"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x33f45e14c53bbfb40518a6be49a95338aee3e78aefb6fd813c3f7f1dcba32201"},{"fromBlock":16236608,"toBlock":16236626,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,null,null],"resultHash":"0xf5ddeacd96cc446aaee4968438e0540fd921c59512cba5c6215ba33245d6f225"},{"fromBlock":3534789,"toBlock":3534844,"address":null,"topics":null,"resultHash":"0xa51628828c1c31c6d55f3e372fd2e64e10140459c9423be91c96f9ace4e31501"},{"fromBlock":20264600,"toBlock":20264607,"address":null,"topics":[["0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1","0x908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378"]],"resultHash":"0x482cd7d5b8aae1b6f1147e0f5a66487a4363558978aae4c0999d1a6df07b8067"},{"fromBlock":13785435,"toBlock":13785449,"address":[],"topics":[null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x96deeba13e2b6bf5ab5e89465bd2c3ee56403ef6e023ee6062091ef9857cab3f"},{"fromBlock":14526515,"toBlock":14526521,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[],"resultHash":"0xae7561506bb13a36c80c30f7530ee2594d0543d410c28fd409db4ac1cd1c9a44"},{"fromBlock":12726345,"toBlock":12726409,"address":null,"topics":[null,null,["0x00000000000000000000000003747f06215b44e498831da019b27f53e483599f","0x00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9"]],"resultHash":"0x87dfc4e21373e54b9131f22de3098d089a3d02864e5075d355aa561d2435f3f9"},{"fromBlock":10780328,"toBlock":10780337,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0x702d35c5576cd01e947c784ffeda735f2665c41ac44988e8baedd16a81e5fbc5"},{"fromBlock":13040534,"toBlock":13040546,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x48fb253446873234f2febbf9bdeaa72d9d387f94"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x22da381c606d94c4d1a476c02d6e6ab46a2513d6b35bb1f7b3f0e90c27e5e5ea"},{"fromBlock":16703649,"toBlock":16703657,"address":["0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,null],"resultHash":"0x6ef95b6cc8796a12db32dfc03d726bc55892b9a3906ede4d125a9c71de2f1867"},{"fromBlock":13040479,"toBlock":13040518,"address":null,"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x000000000000000000000000b8f275fbf7a959f4bce59999a2ef122a099e81a8"]],"resultHash":"0x87c51a434dcfed54e47923e6c5a9a5fa1c7d6fc7a3bab80cb56f2db6bd290f0b"},{"fromBlock":13177262,"toBlock":13177283,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,null],"resultHash":"0x52f3111f584446ee31ce4a2b3bf910d9018912e6d202699f6d41a8b08114b265"},{"fromBlock":13041387,"toBlock":13041394,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0xa37511e6a15b20b4752306c822f4faccd92a41b06396a9e5ad60727f5d42d36c"},{"fromBlock":13039033,"toBlock":13039043,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,null],"resultHash":"0xecdb86eab5b5c0dd38d6ef2fa0fe8d43c1c3fe44044062ec26de3c8fbbddba3a"},{"fromBlock":13762907,"toBlock":13762921,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[],"resultHash":"0xcc51f221e5b8c9df7696537d901f038d9e115a764e65356452bd6f6e52635b7c"},{"fromBlock":17583491,"toBlock":17583507,"address":[],"topics":[null,null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x16751bc9438d4dee9e2b1d0fb845920588fa7d5e9e12f2176cb4dcae0de51318"},{"fromBlock":12450864,"toBlock":12450873,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null],"resultHash":"0xd53ab7019b18b1118abeb8610cd265b2c89f669108dbb50fd49ebe7dc9c72e64"},{"fromBlock":14226761,"toBlock":14226787,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null],"resultHash":"0xd0670fb0b1739fad33e881e92f626ee5c8ab41933261ac76399cad1b037a9673"},{"fromBlock":13040669,"toBlock":13040675,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,null],"resultHash":"0xfe2f6847e6b681859d4133ddd2702cc5619a551b8ca985e1ae7cd54c549d9a0d"},{"fromBlock":7445381,"toBlock":7445405,"address":null,"topics":[null,null,null,null],"resultHash":"0x3c17b3deab2a9d355313aabc5a3ce67c87f457d6228e7eed25834cbb7358e106"},{"fromBlock":13040597,"toBlock":13040660,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xe87aefe0efe9aadc728eda0acecc747cdd9985beb7926f77961d25ced0ad6724"},{"fromBlock":5321271,"toBlock":5321276,"address":null,"topics":[],"resultHash":"0x71d09c411d3adf41aa96d504560a9749e5e213e24bf1da3c19d42b114e474f5e"},{"fromBlock":13180336,"toBlock":13180342,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x8b370c9f57921998713ececea1f41b3104bf067b2e2f689dcabf34e01b2c7f19"},{"fromBlock":871805,"toBlock":871853,"address":null,"topics":null,"resultHash":"0x88f758217f922c95e5074a82c7fe5ddb73637960671f52212372b660c8157784"},{"fromBlock":4081699,"toBlock":4081718,"address":null,"topics":null,"resultHash":"0x0699b14587fcaa6db0c9222e052173e161c86dd542474467770f946e389b6acb"},{"fromBlock":15502349,"toBlock":15502381,"address":null,"topics":[null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x74060a2c21538a4ddc97213db1467020aee3eec87c58625d44103f922f72798e"},{"fromBlock":3427375,"toBlock":3427415,"address":null,"topics":[null,null,null],"resultHash":"0xec56d28b280c824f7a8129e96c845825ba326d627af27a219ae6271e6472c399"},{"fromBlock":3784903,"toBlock":3784926,"address":null,"topics":null,"resultHash":"0xce4b719469d10f94aa2fd7f517c51f08eac59b798d6f2702c2b9f1248a15daed"},{"fromBlock":14192957,"toBlock":14192986,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7","0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xad349b149ed6e7bd71290458e1b9faef30946d606529f64609b02ff21b14c200"},{"fromBlock":20042156,"toBlock":20042172,"address":null,"topics":[null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09"]],"resultHash":"0xe23be3f92d48e4fdb286debed4287195c40aee4427357df64ebf3597e3897b38"},{"fromBlock":13038588,"toBlock":13038602,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,null],"resultHash":"0x0720caa0f7e4ff680d53e4974dafc05f710a9c7c66eed832da56fc054e180189"},{"fromBlock":21463472,"toBlock":21463484,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0x153832d61008e412c5d3c022c292c2c482d7b320c3f3c9b2293670c1a9e2767e"},{"fromBlock":13040652,"toBlock":13040686,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],null],"resultHash":"0x2b298a950890da3d82e6e6ab39347a6936c64d80eab9b2d60003254ca96813ad"},{"fromBlock":5910525,"toBlock":5910545,"address":["0xe6bc60a00b81c7f3cbc8f4ef3b0a6805b6851753"],"topics":[],"resultHash":"0x6fe7e172924d7dca7f7b9539af9d3469b22cb1106e9473339e61ad150c2314ef"},{"fromBlock":18343803,"toBlock":18343812,"address":null,"topics":[null,null,null,null],"resultHash":"0x096ea25377feb3e327d62c267ef4a6c42b1ecc71ed2c6da875a3a38d6e67307e"},{"fromBlock":17361666,"toBlock":17361688,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null,null],"resultHash":"0xd00bf2dcfd984d8e97497e19a948e0a47db3a8f941e21d3795da8364ddb7d91c"},{"fromBlock":13040546,"toBlock":13040579,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0xd39736ff1c07c0fb3a1b169632ad77f108091afb82bd6d97aeafcb39bf85508a"},{"fromBlock":5910488,"toBlock":5910551,"address":["0xe6bc60a00b81c7f3cbc8f4ef3b0a6805b6851753"],"topics":[null,["0x00000000000000000000000024fb92c936a9429303dfae39b8824b931a009fe8"]],"resultHash":"0x15002a19f9b33c7d4b16bb1d047b46dde23fa3ffb29bb1d2b136317b63884e3a"},{"fromBlock":3451247,"toBlock":3451286,"address":null,"topics":null,"resultHash":"0x4af995ed498cfaa6c7e0be1e3e555155156d8c6042aac0d74e39a4f10993a6b2"},{"fromBlock":6327069,"toBlock":6327093,"address":["0x8e306b005773bee6ba6a6e8972bc79d766cc15c8"],"topics":[],"resultHash":"0xa65aeda8d396f01afe40432943208a1d8ab0153b1281adbc89be7360d70e9798"},{"fromBlock":13040662,"toBlock":13040692,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],null],"resultHash":"0x7dc7612d90babdef8ae4b9f56570451284ecb5d5e234a52daa4ef2d54c54966f"},{"fromBlock":13040602,"toBlock":13040675,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0xc3d03e4f041fd4cd388c549ee2a29a9e5075882f"],"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x514b100e61a4ec901b68687fdbc0ae97aa50a3457bf507add9da473bd1a9eda6"},{"fromBlock":4057595,"toBlock":4057608,"address":null,"topics":[],"resultHash":"0x9ad554d914f71f33421cf445d1f37c14b75c5433c3701c3e99f58bdf0da499f0"},{"fromBlock":11695738,"toBlock":11695747,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null],"resultHash":"0xbb6827a9fb918c8318df225099adb81443ed4e7e4953f0b485a6f5c7674f78df"},{"fromBlock":13042401,"toBlock":13042412,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,null,null],"resultHash":"0xc89ad796eeefbad79ed083c57c255e547cfc6790bcbe2813d806bfdbc38b44ca"},{"fromBlock":13047512,"toBlock":13047521,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null],"resultHash":"0x5cbce47a15ad1a1ca02d438651408495305de411180bd642648b21bee426a893"},{"fromBlock":13040680,"toBlock":13040727,"address":null,"topics":[null,["0x000000000000000000000000fa103c21ea2df71dfb92b0652f8b1d795e51cdef","0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0x87699c723756d44f4d901489113761c9f3d710d061534b5fbf6a193c16ac0eea"},{"fromBlock":13047763,"toBlock":13047812,"address":["0x1a2a1c938ce3ec39b6d47113c7955baa9dd454f2"],"topics":[null,null,null,null],"resultHash":"0x0db94629204a3ba1576df0c8f5b60fcdc338ecb0cf56ea239b83017df4cb3875"},{"fromBlock":15848281,"toBlock":15848293,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"]],"resultHash":"0x5e7ddb91085eaf2be41c4d5e8f6d07bcdf38e7479403de1cbc5acbdfb25f0409"},{"fromBlock":3798453,"toBlock":3798470,"address":null,"topics":null,"resultHash":"0xfdf2bf1c800dd96c7ba59d7e8de42317c2b66fb198f3aad86140201595b7b87c"},{"fromBlock":3798454,"toBlock":3798473,"address":null,"topics":[],"resultHash":"0xa196d1b1d8624afc987bc5d789b39e8c36e5b2a0ee7d5ff02668df365d5849d3"},{"fromBlock":20042946,"toBlock":20042958,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987"],null],"resultHash":"0xf7bab2c2cc41a4db4600547f11d1a0ecd2f3554f11282058f3ee2ac39ebb2797"},{"fromBlock":14229000,"toBlock":14229025,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0xca100fde8b07263afbcbd77ac86c3422efbeaf18d2a27d869106fa017c5981ca"},{"fromBlock":11902460,"toBlock":11902475,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x865bdbfce3a71aecda4a235a09e8524ae7f8c71b0b7ad1452cca751465560a26"},{"fromBlock":13137207,"toBlock":13137222,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,null,null],"resultHash":"0x0f1c36577dc10764604c86fda065e756218f3e4ab6917ef8af62c96d00cff409"},{"fromBlock":5039772,"toBlock":5039816,"address":["0xb8327f32127afe37a544c52b628653e222a93bad"],"topics":[],"resultHash":"0x7c4cfc3c1ec426f2c175d19a50f22762b7cacdc7de47291006fe3dc22aaf6fe8"},{"fromBlock":21431904,"toBlock":21431920,"address":null,"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],null],"resultHash":"0x8f1de6421fbe1848b2ec2224acae523d9793157ca558d0a67c76d8c5a4755eaa"},{"fromBlock":13040246,"toBlock":13040294,"address":null,"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],null],"resultHash":"0xe94e57570717c9bd1f33f51d1f25442a9b624a80006fa32377bf7e302dcba74b"},{"fromBlock":12205711,"toBlock":12205720,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"]],"resultHash":"0xb8bdd13b4fc12c72bff6078612c35efcc192e52cb843cbba85febae125a15645"},{"fromBlock":12607634,"toBlock":12607647,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[null,null,null],"resultHash":"0x8265c24926ece92ef855c721fd3a54b4a66c75b988ad096e151b769744b18a74"},{"fromBlock":13058884,"toBlock":13058955,"address":null,"topics":[null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f","0x00000000000000000000000092f1ff14a80ea8c23028a40c74c05bb994ea0ee2"]],"resultHash":"0xcfad58ebe19f88abd7582e84dfaa58e88b284404c92bc84c155a1e943c48b7dc"},{"fromBlock":14883445,"toBlock":14883446,"address":null,"topics":null,"resultHash":"0x5eebf3e7f3ffb139212e7f995705022306a085d53de66a51e63eaec61d8fb547"},{"fromBlock":10097989,"toBlock":10098004,"address":["0x8a91c9a16cd62693649d80afa85a09dbbdcb8508"],"topics":[],"resultHash":"0x7caf48a0605ea17071d0dae11abc5e1542896168fcbc28f0b42ee5d0cc025bf3"},{"fromBlock":14229362,"toBlock":14229371,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x39f0e754f66f970422c71db37d4e7a2765f0bf9f029a1ddc4b8814a150c9d8d8"},{"fromBlock":13042819,"toBlock":13042825,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,null],"resultHash":"0x433cc2971aafab67863137d585e9f900bb103ea7f8e119728af285e44dde900b"},{"fromBlock":13040634,"toBlock":13040665,"address":null,"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],null],"resultHash":"0xd2b4cd32f9449d0ec5438c69a44a2357d3f8b1145cbe7d7e5e417f92ba8e7bfc"},{"fromBlock":16986579,"toBlock":16986598,"address":["0x5b1085136a811e55b2bb2ca1ea456ba82126a376"],"topics":[],"resultHash":"0xc15e7b859d59bd13d8380bcc243b9e3a6d5ec647de8d94bac48ef34549852edd"},{"fromBlock":13040644,"toBlock":13040665,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"],null],"resultHash":"0xe1533cdaf6e12504b12f636d51ddef324d8c99d4804c9b9ddbabee3ea2ab6e89"},{"fromBlock":14526509,"toBlock":14526527,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[null,["0x00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45"]],"resultHash":"0x1cb3160aec8bba240c1b6af4e4970477e02e6c44543ff7f7d26d055eec981778"},{"fromBlock":3554829,"toBlock":3554842,"address":[],"topics":[["0x90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15"],["0x00000000000000000000000061c808d82a3ac53231750dadc13c777b59310bd9"]],"resultHash":"0xf6a0cde7fbd739f1764dea4872e3b007fdbe457bf8e78a3512b7e5eeb3773182"},{"fromBlock":7073378,"toBlock":7073387,"address":[],"topics":[null,["0x000000000000000000000000e85430a51bd131905219bb2460fb893f48236cef"]],"resultHash":"0xe0462a6f16982666246fb152f4e8d5c9d81b7ec46bfab613f5d2598ee51c1130"},{"fromBlock":13075441,"toBlock":13075485,"address":null,"topics":[null,null,["0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f"]],"resultHash":"0xa7d2a88a785757f792377f6f6d03a10fd20c3f995efa863e2fe6a018f3ec97cc"},{"fromBlock":13040614,"toBlock":13040630,"address":null,"topics":[null,["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x02b4327502aeb94ff702463328f0bacf50f445e18e06fa0e570dbddfd9f7ccc3"},{"fromBlock":3954664,"toBlock":3954674,"address":null,"topics":null,"resultHash":"0x1886b8f9a54ffca51ca560f3354433f04b45936275c00728271483acfad5fe90"},{"fromBlock":3534815,"toBlock":3534863,"address":null,"topics":[],"resultHash":"0x7c5066ac63ee9199d9623c266829ad8a84ff440beead7d21bb1db855b82a45eb"},{"fromBlock":16000075,"toBlock":16000102,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[],"resultHash":"0x9b29fa45c0f1b4d269b3ac19dd578c581964da81c7e8bb5e2d8a39faee489f45"},{"fromBlock":9706995,"toBlock":9707003,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[],"resultHash":"0xc8ffb4a53fc71a442395bb7e106598d4d7124463b7338e6830867fec532f6e70"},{"fromBlock":14653403,"toBlock":14653417,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"]],"resultHash":"0xa40221cf6e90ec690106e0e37986a8885231496cd9c07b57ca521e6e372b9b67"},{"fromBlock":14526516,"toBlock":14526521,"address":["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"],"topics":[],"resultHash":"0x2acdeb10ecc00acdbbfad1670556434fae16e444700a0c0a2311f646349aa0cf"},{"fromBlock":3798476,"toBlock":3798489,"address":null,"topics":[],"resultHash":"0x6941e0c609e169a8246fdba41da76e129841ef3c66255648b8f4bf63672e7f71"},{"fromBlock":11933759,"toBlock":11933800,"address":["0x62b9f8741bf53a6986a5411c0557c30f6f11f3af","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x9cbfb60a09a9a33a10312da0f39977cbdb7fde23"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b39459616226deab278e1b2bd230309a27f98139","0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],null],"resultHash":"0xf43d02433a55c175100589e4dcd0e6bb0abf94c72eacfb1f0f7bd56d99323066"},{"fromBlock":13040518,"toBlock":13040554,"address":null,"topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x0040691b9a3ed238f545b565514a9f17b56bc372cdd37b74577ca7a4e6410543"},{"fromBlock":19478184,"toBlock":19478192,"address":null,"topics":[null,["0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"],null],"resultHash":"0x244734a8355fb8625c60ca4ba7b96f6b3c500b90e7809e351802788cb70ca51d"},{"fromBlock":13037481,"toBlock":13037496,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"]],"resultHash":"0x4ca5f1663227b795cc7f7b8b82b48090e97d791f9ae1ed0d9b80abf6a2b3e024"},{"fromBlock":4057591,"toBlock":4057602,"address":null,"topics":[],"resultHash":"0x127510ac0a7a4fb4007ae4642187385040757c61b596925f9857e92b51b51a13"},{"fromBlock":5321269,"toBlock":5321277,"address":null,"topics":null,"resultHash":"0xfa1efd8188c42f3d3166d64f852334e43a61c1d3b9f306b1071267ae06b89efc"},{"fromBlock":14192957,"toBlock":14192993,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x0b697c79cfe172c0332a36e031041f436a8b4efe75a921b7809c68a676062e3c"},{"fromBlock":6849906,"toBlock":6849908,"address":null,"topics":null,"resultHash":"0x85a1d052c2acfd21d7e07e3aad22862e9ff77dc32f5583559c01d179c75ecd0d"}],[{"fromBlock":8051936,"toBlock":8051937,"address":null,"topics":[null],"resultHash":"0x9753425f53709b696f691db20a8be8c4f5d4d45040ba5fb4409fc3714b6260dd"},{"fromBlock":8051931,"toBlock":8051932,"address":null,"topics":[],"resultHash":"0x51e6477ec4928d5fca5dafc8beabe45a668e56b0d6af37513981c55720f52b9e"},{"fromBlock":8755456,"toBlock":8755457,"address":null,"topics":null,"resultHash":"0x4065049eb50f41ef1a9739431707b6505b83f487782debadd285df60294b5757"},{"fromBlock":9984803,"toBlock":9984803,"address":null,"topics":[],"resultHash":"0xd7bf03b75ce2dfc026cc66c02d8fe2c22a38415ee7d1ef837503ce75735a6717"},{"fromBlock":5357794,"toBlock":5357800,"address":null,"topics":[],"resultHash":"0x874ffa42a5681b70ed2975700612b2ab23bc31b198d1aa54c6c80318ed4d7acc"},{"fromBlock":6261430,"toBlock":6261431,"address":null,"topics":null,"resultHash":"0xa58a13ccc23766ee71631bf60e7ba4853dd68c92a8dbbb5e19d18883ed67fe69"},{"fromBlock":12205713,"toBlock":12205713,"address":null,"topics":[],"resultHash":"0x4f0c3710e46718b1d085aaa9b8f291a7a950d8e5cbc121df6aec2d1ed5f2278a"},{"fromBlock":15729905,"toBlock":15729906,"address":null,"topics":null,"resultHash":"0x35e53ed17942c5b42563f250d56d9627bbb99b91b043a051b8e817ba3e119dc7"},{"fromBlock":9632316,"toBlock":9632316,"address":null,"topics":null,"resultHash":"0xcac49d3a44404ac4a210768c820400022383bb2622544ef2ec2f0b5c0400b517"},{"fromBlock":5108707,"toBlock":5108710,"address":null,"topics":[null,null],"resultHash":"0x6d2a39d169ffb5830bfcad74fc0f02792fd4272b792a161a5739476bb61a4b66"},{"fromBlock":12205713,"toBlock":12205713,"address":null,"topics":[],"resultHash":"0x4f0c3710e46718b1d085aaa9b8f291a7a950d8e5cbc121df6aec2d1ed5f2278a"},{"fromBlock":14891535,"toBlock":14891535,"address":null,"topics":null,"resultHash":"0x0f4aea3fa540c1642f06a1bbc4019595043fbc28928e4ad84369d362e6dc4c0b"},{"fromBlock":14610199,"toBlock":14610199,"address":null,"topics":[null,null,null],"resultHash":"0xaa4c4354adf1b9d001cfe5959e2801751cf1d8ab7d657cc7b646df05da114817"},{"fromBlock":14125651,"toBlock":14125652,"address":null,"topics":null,"resultHash":"0xcbb82b4061f940ab9a8d4347b4837ec679340f0e112b4d0b8f07aea2afdb7c3d"},{"fromBlock":13041042,"toBlock":13041042,"address":null,"topics":[null,null],"resultHash":"0xa7613d3e4271423a873c2ab331a8bc863dba50e2adfff6a63511bd32787f0e84"},{"fromBlock":10475739,"toBlock":10475739,"address":null,"topics":null,"resultHash":"0x787da3276e8411d8382b830faa0a3cc604e2688c65c5474a7cd7e6c359d809b7"},{"fromBlock":14865839,"toBlock":14865840,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0xf63d66dba89cda4fd24f25db2aa384009dcb961f8a2b6fa136d0873e06c44d05"},{"fromBlock":10117726,"toBlock":10117727,"address":null,"topics":null,"resultHash":"0xd289d38ed73842aed26af0ca8ec5a118ea492f80cc08896a8523bbf398d45a1a"},{"fromBlock":7466201,"toBlock":7466203,"address":null,"topics":null,"resultHash":"0x1252f6f68863353d5d0fe3b0cc495c71b29124d3ff818c601c2601d9aa961b2b"},{"fromBlock":6073249,"toBlock":6073250,"address":null,"topics":null,"resultHash":"0x32297feec66dc9d2930ea3dec7ae487060ccd40072511c8b81f98a2c9da7fa6d"},{"fromBlock":14000155,"toBlock":14000155,"address":null,"topics":null,"resultHash":"0xd9fde4dec8fadc9698e883832c31558f33e47012b9889d23c1e782dcaa9ed509"},{"fromBlock":12976693,"toBlock":12976693,"address":null,"topics":[null,null],"resultHash":"0x29397c88ad5b397aba5f7b937079ae4a056827d9cbef3bb1e143528d3c7f45c7"},{"fromBlock":9870632,"toBlock":9870632,"address":null,"topics":null,"resultHash":"0x42fc326ec7089f4be6a4722f7fc838f159514ad3c81dcdd171881b7d4f1757d2"},{"fromBlock":17115803,"toBlock":17115803,"address":null,"topics":null,"resultHash":"0xace584e27fa6a079931d0c04dcfdfd0a46efc59283b794c93b4dddd4b21fc4bb"},{"fromBlock":14440278,"toBlock":14440283,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]],"resultHash":"0x4ea33e061f4ecdd23601f412f2ecef6933bb73a6f9ca572eef4a8de8b21ea325"},{"fromBlock":13041388,"toBlock":13041391,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null],"resultHash":"0x09f277fbca0bf70bf1282b96ad57db83c92ec5d38e12621e952b412a347c1448"},{"fromBlock":8755456,"toBlock":8755457,"address":null,"topics":[],"resultHash":"0x4065049eb50f41ef1a9739431707b6505b83f487782debadd285df60294b5757"},{"fromBlock":10956087,"toBlock":10956087,"address":null,"topics":null,"resultHash":"0x0fec5062bed616ca21bac660f9dae1455edfaf8ec35189d4cdbea13a8c8f4876"},{"fromBlock":14440281,"toBlock":14440284,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]],"resultHash":"0x3998592b753c60eaf6bca5307f369ae5f82eb24eb66a70ef834a7fd7142fb220"},{"fromBlock":7073381,"toBlock":7073382,"address":null,"topics":[],"resultHash":"0x047da2ebf97c1804cb1637bc32b8e6f8fb2646c60f4b4fa90080ad06b5978307"},{"fromBlock":20534257,"toBlock":20534257,"address":null,"topics":null,"resultHash":"0x18c8403db561cf765999371b2e1c302856b971c8c86ed23b0eddaf6c0707ea07"},{"fromBlock":12205713,"toBlock":12205713,"address":null,"topics":[],"resultHash":"0x4f0c3710e46718b1d085aaa9b8f291a7a950d8e5cbc121df6aec2d1ed5f2278a"},{"fromBlock":21467845,"toBlock":21467845,"address":null,"topics":null,"resultHash":"0x8c123e8ed4d360a8008455b994f7d9e965607d8896fcf6a707e63823c1ee8bd1"},{"fromBlock":10448364,"toBlock":10448365,"address":null,"topics":null,"resultHash":"0x2d250208dc2ffd44b2da87843a93ecd712a8a7d48117d78fd3ed84ae76301c58"},{"fromBlock":11977389,"toBlock":11977389,"address":null,"topics":null,"resultHash":"0xab1def45ee00251e752e849cc7258251066a5ba8b9bddf497d5c4a1cda2475d5"},{"fromBlock":10298764,"toBlock":10298765,"address":null,"topics":null,"resultHash":"0xe27f8f01b5c7c89cf120f18cbab02b9ebb08157694762294d6e2641af326d2ad"},{"fromBlock":5507052,"toBlock":5507055,"address":null,"topics":null,"resultHash":"0xfaecb393c494e8269a40605e075a17d8a817d4d2605e33c6a5ae80f5e1231333"},{"fromBlock":15845368,"toBlock":15845368,"address":null,"topics":null,"resultHash":"0xde95cb3bd96801400a838bfba5613b6d8a3fbe3a35782f0f78971dd918e5b43e"},{"fromBlock":8750142,"toBlock":8750142,"address":null,"topics":[null,null],"resultHash":"0xc2576c79cf8145ade5531ca6518f2ce54333ea3dec8b573d27c2fd81d5e132ce"},{"fromBlock":5039791,"toBlock":5039791,"address":null,"topics":null,"resultHash":"0xefbc929f93b03983d93f6de27f4d7a4b0da3b5b3f288f1cb4b2663196ad6c030"},{"fromBlock":12574970,"toBlock":12574970,"address":null,"topics":null,"resultHash":"0x776e9e868c5906b72cf1cebdb4eaa604d4c23db83eec7ba28ae6da8cf552d517"},{"fromBlock":5290013,"toBlock":5290013,"address":null,"topics":[],"resultHash":"0x24b169ae5d6425e749e312bb81bc5d609f4aab010eb0672fab7570c3479b5cf6"},{"fromBlock":6594645,"toBlock":6594646,"address":null,"topics":null,"resultHash":"0x3ec18e24709747cf29ae27dd05aa97a05fa86b073326991109b7a2fb370b6a48"},{"fromBlock":16430371,"toBlock":16430371,"address":null,"topics":null,"resultHash":"0x88b7c11ef5851d4d92b2783d00b4621968ec3c2e604d6cc036e4ce97a1e4a2dd"},{"fromBlock":8148296,"toBlock":8148298,"address":null,"topics":null,"resultHash":"0x91ec757d189b7611170553ffdbc4a31e6e8b5bc99393a11cdf773873d5d0d1ba"},{"fromBlock":5912147,"toBlock":5912148,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x28767a8ab268adaf8551f940f4a99e9c102b36d75f161ec45353f72df3da6d36"},{"fromBlock":8568129,"toBlock":8568134,"address":null,"topics":null,"resultHash":"0x91340874bf456ae66e5fe471703b8d97ced5bacc90553490fc8ade92acf462f6"},{"fromBlock":7073381,"toBlock":7073382,"address":null,"topics":[],"resultHash":"0x047da2ebf97c1804cb1637bc32b8e6f8fb2646c60f4b4fa90080ad06b5978307"},{"fromBlock":13785440,"toBlock":13785441,"address":null,"topics":null,"resultHash":"0xe3d109e6a1c642cab7ce89e3191d99387898604d76fa1fefd48b954878af6e01"},{"fromBlock":16465844,"toBlock":16465844,"address":null,"topics":null,"resultHash":"0xbfa68a6a779c57d2faa4bd11fafedd3b111145ecba23af0421f9fbf71c01ebfb"},{"fromBlock":6825405,"toBlock":6825406,"address":null,"topics":null,"resultHash":"0x5cf327789f42aa42d6811f86a69627673e327d6f02564a029ca50d26d13ef6a0"},{"fromBlock":6672946,"toBlock":6672947,"address":null,"topics":null,"resultHash":"0xf6a802c71d3d12b3de0fd3ae42203fe8a074caf2c541ee77f7761c9cfb920b84"},{"fromBlock":14559412,"toBlock":14559412,"address":null,"topics":[],"resultHash":"0x6e39afe11c1a36b4645f7092bd856a1c47fd26ae751fe5116ed0f2416d7ab3b4"},{"fromBlock":5304480,"toBlock":5304481,"address":null,"topics":[],"resultHash":"0x388790a0f1018778c1d8c5a8fd1c947c84da06e5692dd43a001c225b8f0c1a96"},{"fromBlock":8051932,"toBlock":8051933,"address":null,"topics":[],"resultHash":"0xe9312ae1d001320ea05848334917bcd4903f7ba04efcb09600b1e71c8514916b"},{"fromBlock":12702839,"toBlock":12702839,"address":null,"topics":[],"resultHash":"0x5f4f28e6cfddc0978c90a07fb20b75ed98d2d1dddb4d2cac091aa676e0d1dc38"},{"fromBlock":14509035,"toBlock":14509039,"address":null,"topics":[null,null,null,null],"resultHash":"0xed7af39049721af06945efebeffd45766a94a0aed11bdc4220b7760e7d7cf03b"},{"fromBlock":15729905,"toBlock":15729905,"address":null,"topics":[],"resultHash":"0x54af891df694b0dc265c905ad258cc9a434cef1ba79cdd9ff81bfca9ea24d426"},{"fromBlock":10537179,"toBlock":10537179,"address":null,"topics":null,"resultHash":"0x53f4ad8bdc5055119d21c57978e818ed94801fb338a5527d81fb45663170e2cd"},{"fromBlock":21464471,"toBlock":21464479,"address":["0xdac17f958d2ee523a2206206994597c13d831ec7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x8d6107f63a3698f71f24353622cf968852e478b74c421449555c966c9e09b120"},{"fromBlock":7073382,"toBlock":7073383,"address":null,"topics":null,"resultHash":"0x2ae3a44010d35a515b9e7a1d97bd7330b619329c460ab26a062dff5f87d96b82"},{"fromBlock":13047787,"toBlock":13047795,"address":null,"topics":[null,null,null,null],"resultHash":"0xf17aad2c3583494036d43609e2718e760a01062cdceeb1159ecbce9660ef80de"},{"fromBlock":9984803,"toBlock":9984803,"address":null,"topics":null,"resultHash":"0xd7bf03b75ce2dfc026cc66c02d8fe2c22a38415ee7d1ef837503ce75735a6717"},{"fromBlock":9157387,"toBlock":9157388,"address":null,"topics":[],"resultHash":"0xfbe3aac345b6479516984b349846b9f226bfc041590d80a1ef675e173a9dc586"},{"fromBlock":14526512,"toBlock":14526513,"address":null,"topics":[],"resultHash":"0xbd5ff6b4a72b9c74fafd25cc1ffbd7e8b37b6a46426dca129148bb220305a7d6"},{"fromBlock":17583500,"toBlock":17583500,"address":null,"topics":[],"resultHash":"0xf67f72eeb2888d3b7c0febc36aec0466f6522a8a354e2c9ac98f1a5796c5f47a"},{"fromBlock":20052976,"toBlock":20052983,"address":null,"topics":[null,["0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"],null],"resultHash":"0x4d14aa296546b1ccd1106cf88526df80e80d741bf348c3eec3c117aea54ac0c1"},{"fromBlock":7314304,"toBlock":7314305,"address":null,"topics":null,"resultHash":"0x42052c2967021cc5e8c8f746d97e7ea4a60eca2dd0e067b261180313f6dea5c5"},{"fromBlock":15729905,"toBlock":15729907,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x1598ab153f5da806aedcbf1ea505d712b95f54e6516b9e1e571689328d4e4b67"},{"fromBlock":7268103,"toBlock":7268104,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xb4eaa2c40a9dc9ccc53d65305e1d31398f69565e578b60cac2d8da1a8a54e014"},{"fromBlock":7453627,"toBlock":7453630,"address":null,"topics":null,"resultHash":"0xee2036cf643b7c8cd3131413e1eb02556ee180ea9d0493fb2a68e4c211af3493"},{"fromBlock":18178255,"toBlock":18178255,"address":null,"topics":null,"resultHash":"0x52937682f9d5ae4e234ba97a2a0bf438639ab5b5916e9964702cf740fa291363"},{"fromBlock":15373193,"toBlock":15373193,"address":null,"topics":null,"resultHash":"0x3ee396c19ddb10733e2d325eed00840173489a11462470f4bd5ab7c68ba89b0c"},{"fromBlock":11392189,"toBlock":11392189,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x8fccc6ddb867e3345a8f794a0a67f47dcbfc1606643b4d48b40765b0a8276dcd"},{"fromBlock":9523960,"toBlock":9523962,"address":null,"topics":null,"resultHash":"0x8ef63694085491efe0434e22e7ca0b1f7150dcc7bf2969850436b9cfd6f2fa1b"},{"fromBlock":14728967,"toBlock":14728967,"address":null,"topics":null,"resultHash":"0x23f62d332ef9bf2b648bf710f1efd12ad3eec86befdee64f1bdf862b7dae8e2e"},{"fromBlock":21709514,"toBlock":21709514,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x5e8d1be716f8cb538f25f22a994c7a927d4a64c70433ab9176f6095552181964"},{"fromBlock":12702839,"toBlock":12702839,"address":null,"topics":null,"resultHash":"0x5f4f28e6cfddc0978c90a07fb20b75ed98d2d1dddb4d2cac091aa676e0d1dc38"},{"fromBlock":20778343,"toBlock":20778343,"address":null,"topics":null,"resultHash":"0x58a6bf22fc64d9e8d93d9dc0e59033261415c079001dd7b18348cd3ba498e421"},{"fromBlock":15845368,"toBlock":15845368,"address":null,"topics":[],"resultHash":"0xde95cb3bd96801400a838bfba5613b6d8a3fbe3a35782f0f78971dd918e5b43e"},{"fromBlock":15840964,"toBlock":15840964,"address":null,"topics":[null,null,null],"resultHash":"0x9bccdb653a88ed119feb06b47c9a51555f05384ebdd3e4149a0d930ac55b7071"},{"fromBlock":14559412,"toBlock":14559412,"address":null,"topics":null,"resultHash":"0x6e39afe11c1a36b4645f7092bd856a1c47fd26ae751fe5116ed0f2416d7ab3b4"},{"fromBlock":18890411,"toBlock":18890414,"address":["0x86ecdc01c4a06a35e69659488c70546a06713ae4"],"topics":[null,null,null],"resultHash":"0xc94d915783355ff9fb4035a81e547a7fa475b88357a2183c606f204e0cca45a5"},{"fromBlock":14238413,"toBlock":14238415,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0xd46c0e31def1b92cad1b15e253cf78d8d811aa95b3c6185ce2d5c4a0a34a2173"},{"fromBlock":20799204,"toBlock":20799204,"address":null,"topics":[null,null,null],"resultHash":"0x76c44d4126a0695f117a869e9075bf1c8a41c5e040b6711294be1f5e54019c54"},{"fromBlock":14349534,"toBlock":14349534,"address":null,"topics":[null,null,null],"resultHash":"0x738743b021626c5336a923e29a80e5d8aab0f99d9f2cf32a9f58afa2e7a020d6"},{"fromBlock":13037490,"toBlock":13037493,"address":null,"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822","0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null],"resultHash":"0x055c2d086674abed5783ad5def47f470ad8a829457cfb1c9556cce6693bbd60a"},{"fromBlock":10661759,"toBlock":10661759,"address":null,"topics":null,"resultHash":"0xd3f5f3a5e28e099f677d661bd3eb52ca64f51d1c00da69ed0706849c205b7883"},{"fromBlock":5039790,"toBlock":5039791,"address":null,"topics":[],"resultHash":"0xa7704646e76483f000466cd030439a2e8b2e9c9fa39aa44fe85bea9e3f61eca7"},{"fromBlock":5290012,"toBlock":5290013,"address":null,"topics":null,"resultHash":"0xf1de99306efe4744146d2c40c5963b780bc5e871301cd60772c006060e78b360"},{"fromBlock":6814291,"toBlock":6814292,"address":null,"topics":[],"resultHash":"0xb9570e970afdd43ade72d2d42f80219fea37ae836b5da85162ad1d7e56547877"},{"fromBlock":13785467,"toBlock":13785468,"address":null,"topics":[null,null],"resultHash":"0x1cb41023a7db0338e770b5cad202888b10e8fad0027ed832d32ea21390b19318"},{"fromBlock":9687995,"toBlock":9687996,"address":null,"topics":[],"resultHash":"0xbcfa0e95029ac4d27509a19ab4bd724d55e813b70acd50f7b7337e2437ed10f1"},{"fromBlock":12205713,"toBlock":12205713,"address":null,"topics":[null],"resultHash":"0x4f0c3710e46718b1d085aaa9b8f291a7a950d8e5cbc121df6aec2d1ed5f2278a"},{"fromBlock":16986593,"toBlock":16986593,"address":null,"topics":null,"resultHash":"0x1936d87df56e1afb9cce9bba19ea2df1f8a86404bfb2feb61eb8b2f53f232719"},{"fromBlock":19238253,"toBlock":19238253,"address":null,"topics":null,"resultHash":"0x1132ab18e2c347e0190668455fb682b9950956fdfaaba243572e79ef0b2e990b"},{"fromBlock":12205713,"toBlock":12205714,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xee86e29f44ab3a9cd2a527deb5c4aca4676cda37cc0a5a5e14ede73cb6dda425"},{"fromBlock":9147389,"toBlock":9147390,"address":null,"topics":null,"resultHash":"0xc463513835c6ff58ee188b50682183bfbc6cc1b15818eb1570674da1f3047999"},{"fromBlock":13040442,"toBlock":13040443,"address":null,"topics":[null,null],"resultHash":"0xe9ff3039e1235ffca998b05895ed8eae8cb586c9931fd782c648532150769f3a"},{"fromBlock":8051931,"toBlock":8051932,"address":null,"topics":null,"resultHash":"0x51e6477ec4928d5fca5dafc8beabe45a668e56b0d6af37513981c55720f52b9e"}]] diff --git a/cmd/workload/queries/filter_queries_sepolia.json b/cmd/workload/queries/filter_queries_sepolia.json new file mode 100644 index 0000000000..e9d40387ae --- /dev/null +++ b/cmd/workload/queries/filter_queries_sepolia.json @@ -0,0 +1 @@ +[[{"fromBlock":329160,"toBlock":7369873,"address":["0x7451ee8eecf3b8534fa07b15b4b5cee4bcc88778"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"]],"resultHash":"0x25db53749138a4c37510a0805ae166c507f3acae2ab12a530deae7655f2823f8"},{"fromBlock":0,"toBlock":7713721,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],["0x00000000000000000000000000000000000000000000000000000000000016b0"],["0x000000000000000000000000f28e3d6e64cd5ae909177ea99ecac63755ca978f"]],"resultHash":"0x4b9354c69b4847cc33ddbf4d99b1e118c051371df0c9beb4f4cf26bd4d81e927"},{"fromBlock":0,"toBlock":7665156,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],["0x00000000000000000000000000000000000000000000000000000000000016fc"],["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0xce425b1bb2c807961ebf20a91f40e702d0d102352517458aad37e50151b2f3bc"},{"fromBlock":0,"toBlock":6875691,"address":["0xa777279ac63f977bddd294f33e3cdb182f900ac5"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000277b56a340"],["0x0000000000000000000000000000000000000000000000000000000000001410"]],"resultHash":"0x0e83f0594962b8562c38fefedeeca04e812fa96ba51bec788eede056b5a90afe"},{"fromBlock":2364138,"toBlock":6984783,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[null,["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000000000000000000000000000000000000000000346"]],"resultHash":"0x32724d34432774ced966156e39eddbf1a756d0494289f64f2099880e5832d896"},{"fromBlock":655698,"toBlock":7755800,"address":[],"topics":[["0xb9fa1caa1e1541788a4b5cd68270e6d375e3a28f4f94017af9351c5955d58fa7"],null,["0x00000000000000000000000000000000000000000000000000000000000017b0"],["0x000000000000000000000000093132745c59e283668783cfc75be29a9090bbdc"]],"resultHash":"0x4e5de76ee4910cb171491add2f62074ab851a7e395fb11adc4d8732c24718f55"},{"fromBlock":2797035,"toBlock":7755769,"address":[],"topics":[["0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0"],["0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x000000000000000000000000e3a73cf48dd65a92f03cbf2bf85fad1fab8b32bc"]],"resultHash":"0x600f6fca4007f0ba0892d80297a8dca7d7b65cfea8ea8f708b96b088127e8949"},{"fromBlock":658060,"toBlock":7082999,"address":[],"topics":[null,["0x0000000000000000000000001b89a43d543260fee7e0cad06a4b3b1beab20527"],["0x0000000000000000000000008f73f932d0310ec85731648bcbacf2de3b60bb0c"]],"resultHash":"0x74b50821877454def9388a8e4fb9496d91eb71ef4ce1b414bdf74f14ab4c3388"},{"fromBlock":1487735,"toBlock":7755769,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271","0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],["0x000000000000000000000000c98326d3c5afe5c76799bf97385321d52bf1927a"],["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x5fad9f825436f3041030a2df2b23c8f428ce44161d1a9d68399325f3233b02f1"},{"fromBlock":0,"toBlock":7714615,"address":["0x55679e247913942bdaf980a26c2e814203e8e012"],"topics":[null,["0xfd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x6affe85e9269f82072e76b72605c34b9b4b44a6d53a3869d157597158c22a52c"},{"fromBlock":191174,"toBlock":5649601,"address":["0x55679e247913942bdaf980a26c2e814203e8e012"],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5"]],"resultHash":"0x04169538996f1dbed7206b61b407a168d3b37172ddcc1d031caad97e68f975a6"},{"fromBlock":0,"toBlock":5559009,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],["0x000000000000000000000000000000000000000000000000000000000000145e"]],"resultHash":"0x6f727b53a1e78267db08f9a4a834c4c7aae17f44611773467f31500cb158bc2d"},{"fromBlock":0,"toBlock":6959720,"address":[],"topics":[null,["0x000000000000000000000000ec25efbe53018c4a7c3c5f959ad52a4c39fbd8ef"]],"resultHash":"0xfb26697132fb58e78ac7d7a28e110f32f50126f41757919424d4ee26345d5653"},{"fromBlock":429456,"toBlock":6285336,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000003fedafc30a6c9da74d22084d67d7e7fef2c1ea97"],["0x0000000000000000000000000000000000000000000000000000000000000364"]],"resultHash":"0xc5adbfc48e7dd40ec5812717607f720939c82c401b1ae2a9b592f05ad01b7ef9"},{"fromBlock":0,"toBlock":7246717,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x00000000000000000000000000000000000000000000000000000001636c28c0"],["0x000000000000000000000000000000000000000000000000000000000000165a"],["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0x81fdcd3e13ceebea3deaf279e9830b471b2952a98196bc9694d0e865f72cd37f"},{"fromBlock":697441,"toBlock":7210145,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000cf581dbfa198e4b31e7cb79a5c23f25e8282eac4"],["0x0000000000000000000000009ea18de905e654f9fb98498109c60edfe133c145"]],"resultHash":"0x13e2b48c3b7a885d9ca03421babff65d9fbd1b510d30915b45fa99233face744"},{"fromBlock":1006390,"toBlock":5566214,"address":["0x22c1317fe43132b22860e8b465548613d6151a9f"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000c48d2559dcac2c87de79c0bdc4aed3a3dbb54fff"],["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8"]],"resultHash":"0xcb9892fb7cd0f1c510951197e60e5272712ceaf1b52032a5a2d6191efe22842b"},{"fromBlock":0,"toBlock":6435215,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x000000000000000000000000000000000000000000000000000000000001ad4d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x683916e4f4bf0e6cda3a4c8a5d84722a312ae06daa8bf3eb2e2de6a7516bf6e5"},{"fromBlock":492944,"toBlock":7755769,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002afd"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xbb1f814b0ea567a45cdfe3a2577bc6048327608e7ee010fca9f28736c6d66544"},{"fromBlock":1106931,"toBlock":7755769,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000000000000000000000000000000000000000001fc"]],"resultHash":"0x6ee7afc9db91ce14c6af3222975cf81641b3045d1a90f51593b22b7001c350ef"},{"fromBlock":65384,"toBlock":7755800,"address":["0x666ca6fc75b44f3ff2d321c5947031141409b152"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000005db2"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xb914252b9263ebbd8d1a2e1cf3f0900f3640d988f744f6a01762ec65fb5118a6"},{"fromBlock":134126,"toBlock":7755769,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002ada"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x49e36f2defbc6bbda0f18c7969aa07ddd4461088b4ce1b567bd6457d85762195"},{"fromBlock":1153907,"toBlock":7755708,"address":["0x08394e7e653472694ecd4527656b2881e5701a14"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000062c2976bde177248e359eae3245cfaeba22a1bdf"],["0x000000000000000000000000321ce961084fcf3a56de4be2f2006707a0421aa4"]],"resultHash":"0x66bd6e704003650f5c1ecc139204182f1cd608f6485af126764fc2f3b8e9b284"},{"fromBlock":1477743,"toBlock":7755769,"address":["0x182ec567f33ac802e9e80c0a0bbe7610d5923e0e"],"topics":[null,["0x7fccf3cf41117a39dccbb957bda719d39cc8a68c8be4b55897b49be6e571feff"],null,["0x000000000000000000000000000000000000000000000000000000000017d39c"]],"resultHash":"0x9e54120991b987854b13772ddab24bcc1f25feb8b191580eb8dc1f8b4983b352"},{"fromBlock":658060,"toBlock":7082999,"address":["0x2df684c8f22f87200f1860ca0856d4410a07fcb9"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000001b89a43d543260fee7e0cad06a4b3b1beab20527"],["0x0000000000000000000000008f73f932d0310ec85731648bcbacf2de3b60bb0c"]],"resultHash":"0x23f5aff5f9675955263dfa5b8602a9d6bd8ca2408b136f177a393aa7c5ad2f42"},{"fromBlock":1466011,"toBlock":7501340,"address":["0xbd3cf0422ac029f46f12a3dcfb9bc0d90a7665d8"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x00000000000000000000000000000000000000000000000000000000000000fa"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xbc7a95ef941f5ff4d6c25bbe0adf62dd1288c10cbafcb086688ae34976080299"},{"fromBlock":1562615,"toBlock":7079448,"address":["0xd4eaf2a5da8c51a30c245ad71a0b93f39fa1ec53"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],["0x0000000000000000000000009b38debc05d4a2145c11e1effb6c6f7216178232"],["0x000000000000000000000000d1292d09173fc26cb82ddcc047d5d19f7369d56e"]],"resultHash":"0x326a032c461af6c1dc2028e152895bb2daee22cb05a252bf69094d89d0991352"},{"fromBlock":2002816,"toBlock":7755769,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],["0x29233435440149c2f178675f72d5fee66628ecb7950abbefcfeca71f773b72c4"]],"resultHash":"0x3f912f4880a1331f6ab24917aa7e664562c88ffdb3a73b4ea1b0ff4ee8eeb1ba"},{"fromBlock":191174,"toBlock":5649601,"address":["0x55679e247913942bdaf980a26c2e814203e8e012"],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x04169538996f1dbed7206b61b407a168d3b37172ddcc1d031caad97e68f975a6"},{"fromBlock":538836,"toBlock":6372228,"address":["0x2dec7530742c2c0039f8c466afffb6e39f171d8b"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,null,["0x0000000000000000000000000000000000000000000000000000000000000001"]],"resultHash":"0x0371b629b27c18371b9001118715517b74dc26135b45dd4403b2293b1f223790"},{"fromBlock":1466011,"toBlock":7501340,"address":["0x0a69d6b0671ef71bf69f8f33e426f3da46d4d8c5"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x00000000000000000000000000000000000000000000000000000000000000fa"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x94ca2b27f71399f8cfa36eb71869758237e9521a8bbbee507ed3a7908ab076bd"},{"fromBlock":270240,"toBlock":6693893,"address":[],"topics":[null,null,["0x00000000000000000000000000000000000000000000000000000000000d0b39"]],"resultHash":"0xa0f778ac764047894a84a885948a9eadd21d74c075c74b8550eac447728fba52"},{"fromBlock":413856,"toBlock":7410314,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000015e2d62c0"],null,["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0xf153c0c2a0b90ffff6b289a98cbee8bd13b00afb9de51dd1a956e745a8469b12"},{"fromBlock":678703,"toBlock":7755800,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002a76"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xadbd2bf9ef8a7d4a763bf963b1fe115a3edd130b85849cadd33c8cc10303ddbc"},{"fromBlock":473395,"toBlock":6071332,"address":["0x4b5011c89f3e727b71e113334e36ff70972a969f"],"topics":[["0x27333edb8bdcd40a0ae944fb121b5e2d62ea782683946654a0f5e607a908d578"],["0x0000000000000000000000007f2698714842f59e89f1eb8b1b70ccb053b5a176"],["0x0000000000000000000000003367dfa11e3148a07c2da773e1f65b155b0abe56"],["0x00050000381eb7d25d5a6d99b343042fe9e4e219ffa955b70000000000000c33"]],"resultHash":"0x793e4939f0b3fe62ba1bcb3fb67ab1708a29257a9d03a2a99380333700780d78"},{"fromBlock":319574,"toBlock":7658479,"address":[],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000002716b6c0"],["0x0000000000000000000000000000000000000000000000000000000000001459"]],"resultHash":"0x1d69427c35c9933579010801259ae1f445af26496a696676635898ec30650eeb"},{"fromBlock":730800,"toBlock":5387842,"address":["0xfbed2b7f3cde372a5aa7f92d53e6a9599e22ac5e"],"topics":[null,["0x00000000000000000000000084141972ee5ded3fd5c21f099007c4f64080ab76"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0xde173ea745f3972187ed784be19c7e4d28cd594a23035d3ea65b2867ad23ff1e"},{"fromBlock":2930524,"toBlock":7755769,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002b0a"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x92dd14d70aa964b592be3de4091ddb9f7a3a327ee163f1341866ac621e6777be"},{"fromBlock":501967,"toBlock":7114558,"address":["0xd4eaf2a5da8c51a30c245ad71a0b93f39fa1ec53"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],["0x00000000000000000000000035fbb60f453a9abf3b6aa27451a0b83f00256265"],["0x000000000000000000000000d1292d09173fc26cb82ddcc047d5d19f7369d56e"]],"resultHash":"0xfb9107e9b16acced8a14d0bf264b8d6fb8cc7799c49be7a85dd032064fa51358"},{"fromBlock":3072436,"toBlock":7755769,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],["0x2828326ef1e3d5c84d222f081bd23ce9481e732fe9eda1a704538461aadfe64c"],["0x000000000000000000000000000000000000000000000000000000000000358b"]],"resultHash":"0x0eb32d9e396f973734f56a1c0c8fd95d808ab55770b0a922e922ee64a5ee6ec1"},{"fromBlock":0,"toBlock":7189296,"address":["0x1f1df9f7fc939e71819f766978d8f900b816761b"],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000001cdb5"]],"resultHash":"0x110a53e1aab1bdf65ac54b616b1cd16acc783b7653246256ded91321d18399bf"},{"fromBlock":0,"toBlock":7659342,"address":["0xe3e87577bf7abfaca3b3ab37ee3521eca839506e"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000eb680d091cb442db16e35d00c6cdb2cb9dda3f05"],["0x00000000000000000000000072b9c3c2847e0c09776c071b2610dec9521c54d6"]],"resultHash":"0x6f0f0792ab4200e9c8ae8b1f01bd16e36272fd94897f7af66ec06078db991f25"},{"fromBlock":0,"toBlock":7184764,"address":[],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],["0x00000000000000000000000000000000000000000000000000000000000016ca"],["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0x23ebd5098b97d64283c723ea464e3fd7425d11ce2e4e2e31ea3ab7b2fb290f9f"},{"fromBlock":1962203,"toBlock":7755739,"address":[],"topics":[null,["0x4e10fea446dec52edeae544909c2ee6217bb8c7e8d66af35305e9f780cf241cd"],["0x0000000000000000000000000000000000000000000000000000000000008809"],["0x00000000000000000000000000000000000000000000000000000000003fc4b0"]],"resultHash":"0x60fddfd775ebae4594ff2ce5af3d47a95d1c87d02b0d0cf4150623c53651f159"},{"fromBlock":0,"toBlock":7331384,"address":[],"topics":[["0x2402307311a4d6604e4e7b4c8a15a7e1213edb39c16a31efa70afb06030d3165"],["0x000000000000000000000000000000000000000000000000000000000001ad8f"],null,["0x8c27175bb5d6a1656aab86592e5b96ec499f9a5235a8719208942b6aaa7814c2"]],"resultHash":"0xa7ec12665c16f1f2eadabba7427f11e7cb8dd9ce6f74230cb5050c4f51d14216"},{"fromBlock":0,"toBlock":7689788,"address":[],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000001cea2"],["0x000000000000000000000000c757f0742a5efa639de6ec9afbd899aaada5c4e1"]],"resultHash":"0x7b280fbbb2fed590f1b6263827dfc01471e4be27effd213b518c86bdf4b1fc09"},{"fromBlock":0,"toBlock":5559009,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],["0x000000000000000000000000000000000000000000000000000000000000145e"],["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xc354af61486916c6837ee9fc21db0c9b3c16661503369a137370eabe25170862"},{"fromBlock":1085910,"toBlock":7580612,"address":["0x8d171fcf12fcfcd88478834f5736ed058402344b"],"topics":[null,["0x00000000000000000000000000000000000000000000000000000000000000fa"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x25a5f27d7f45dd20cfb3a70b27e395269de115ad69592f886d0be4c8ac24c150"},{"fromBlock":0,"toBlock":6432433,"address":["0xfc6acfe4f69b41bf174230107e4b81b7b03bd91c"],"topics":[["0x51bbdc1d2a76e18752092da32318ce9d5ad268aae23f908efaf64aab614f8190"],["0x000000000000000000000000919663102b19fae17492a150bbf24a5196738441"]],"resultHash":"0x9607ffc2e2f85d617d30a8c67315223a912cddc2c60fd8f998d8387b8b885838"},{"fromBlock":1317354,"toBlock":7755769,"address":["0xbdd800ee3fe0300a4a1b702cbc8b836453eb3877"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000006b29975137d7de522bf6c4615051370c55820b3e"]],"resultHash":"0x7dcc1e578cae00d171c6360f07fa9bb7759b5669cb33ed06e46e16ae24b53ca1"},{"fromBlock":1172544,"toBlock":7755800,"address":["0x2a0f1c1ce263202f629bf41fa7caa3d5f8fd52c4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null,["0x000000000000000000000000000000000000000000000000000000000001f0e5"]],"resultHash":"0xc58ee10bc1f8140e2ba871d5e0ceba32cac63d723c651a26a709dfbc7b6132f4"},{"fromBlock":0,"toBlock":7029899,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000ed0bc1d60a1a58630dfab759150f9b35e2f8e6ac"],["0x0000000000000000000000000000000000000000000000000000000000000001"]],"resultHash":"0xbe1723ec4affbdd4b2c96e1ee3ef0894843690a29aad18fa511343c4cad1ecca"},{"fromBlock":1019467,"toBlock":7755769,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],["0x000000000000000000000000b97ee3b6579c019aacdea9f90a34c7ea40b1ecaf"],["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xc03be8ce200dfaba250abcfa2221621c72e7cd9a6581738e3195987a1185756d"},{"fromBlock":40844,"toBlock":7755769,"address":[],"topics":[null,["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000000000000000000000000000000000000000000c3"]],"resultHash":"0x3c07cf517f9c95ec6c9fac65c543239308e446c5cbce655ad3b3db067244ac7a"},{"fromBlock":2676270,"toBlock":7755800,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271","0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],["0x000000000000000000000000f641fab94463451256938d7c9312aa1c58567942"],["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xb1f96269005bbcca36f978b0480295be7d0bcb878f06fc65b76d06314da69025"},{"fromBlock":2027722,"toBlock":7755769,"address":["0x1cd40deb4196d219097499031922ff690f9ea813"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000093b714330996f3dec51c455e4ac85f3864274fae"]],"resultHash":"0xa02d3cd63ea10c0707545f43460fbbd45dbb601ca7a5bbad1fa7f45524a3f93f"},{"fromBlock":2411824,"toBlock":7755769,"address":[],"topics":[null,["0x29233435440149c2f178675f72d5fee66628ecb7950abbefcfeca71f773b72c4"]],"resultHash":"0x3f912f4880a1331f6ab24917aa7e664562c88ffdb3a73b4ea1b0ff4ee8eeb1ba"},{"fromBlock":1268701,"toBlock":7755769,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],["0x861d4dea01ea22e402526c43d4edb4b0a8ed655cd76997e8f0527bc298cd65f4"],["0x0000000000000000000000000000000000000000000000000000000000008809"],["0x00000000000000000000000000000000000000000000000000000000003fc4b0"]],"resultHash":"0xc0eb6e399462a641a7aae1d86de90fe6c3bfaf2b9c17e424990a993663e3af7f"},{"fromBlock":145539,"toBlock":7755769,"address":["0x80ba15dcd21e3260ddf573daaa59cccd442c2109"],"topics":[null,null,["0x00000000000000000000000000839a4f507e16d3d8c0ed04068a6f9557e79e3e"]],"resultHash":"0xed2a05b4039712dba8cdf482cc7256f046bd436377510943c0c7cf38a4949ac8"},{"fromBlock":2501102,"toBlock":7608761,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002af4"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xc18579dc53345f29150d3e87af0b8312b5210a3a3dc5a1c164d146626ac8e626"},{"fromBlock":1477743,"toBlock":7755769,"address":["0x182ec567f33ac802e9e80c0a0bbe7610d5923e0e"],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],["0x7fccf3cf41117a39dccbb957bda719d39cc8a68c8be4b55897b49be6e571feff"],null,["0x000000000000000000000000000000000000000000000000000000000017d39c"]],"resultHash":"0x9e54120991b987854b13772ddab24bcc1f25feb8b191580eb8dc1f8b4983b352"},{"fromBlock":0,"toBlock":7331384,"address":[],"topics":[["0x2402307311a4d6604e4e7b4c8a15a7e1213edb39c16a31efa70afb06030d3165"],["0x000000000000000000000000000000000000000000000000000000000001ad8f"],["0x434ab18e74443aedaf60deb40b86a46652a31f8e7946b89e38d87010a8c71dfa"]],"resultHash":"0xa7ec12665c16f1f2eadabba7427f11e7cb8dd9ce6f74230cb5050c4f51d14216"},{"fromBlock":0,"toBlock":6091590,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],["0x000000000000000000000000000000000000000000000000000000000000169f"],["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0x1206d4af9287217417eda7c7976c211afe9b752201992f34ab0fcdc2ad310e71"},{"fromBlock":779060,"toBlock":7755769,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000000000000000000000000000000000000000002f7"]],"resultHash":"0x3c6d85093272d0b7655dde7e5c1dafe0f3ed40b7d510e560d6d84f29e6ce37cc"},{"fromBlock":1522662,"toBlock":7755769,"address":[],"topics":[null,["0x10862ada1ca9077572160e37d2c6def4a83b17b544194b59eed77cbbe06730d3"]],"resultHash":"0x91c076089539179dd2089f91db29205af4a3fd19ea901095665a5c5180bc8090"},{"fromBlock":712373,"toBlock":7755769,"address":["0x22c1317fe43132b22860e8b465548613d6151a9f"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000b82d55450c18b9b28b3939c00b1dba5307c6e177"],["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8"]],"resultHash":"0xb398071d75a75a079e71825bff6aef3476e1ed19901d19d707591c333ef897a7"},{"fromBlock":1006390,"toBlock":5566214,"address":["0x22c1317fe43132b22860e8b465548613d6151a9f"],"topics":[null,["0x000000000000000000000000c48d2559dcac2c87de79c0bdc4aed3a3dbb54fff"],["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8"]],"resultHash":"0x61fe918b0c085d85ea1f228055266b1ad0286b0f212fa439b227df6c3ff86571"},{"fromBlock":0,"toBlock":7531627,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],["0x000000000000000000000000000000000000000000000000000000000000148e"],["0x00000000000000000000000038dc84830b92d171d7b4c129c813360d6ab8b54e"]],"resultHash":"0x44ee7ce0647093cbb1dab61d20d81f81de3e88a80d966b9fa5890d62a37ce101"},{"fromBlock":129898,"toBlock":7755739,"address":["0x71320dd08a45521c269ea7a37432973c7a57707f"],"topics":[["0x166e0f25af06322bfb9011ee3dd804ca0b93dc1276c71d8d605d661d22aa4172"],["0xbc3e8d090b1b642be9d033fd1403aa6d8ed3629fe9bc9036b19173cb76615d3a"],["0x0000000000000000000000000000000000000000000000000000000000028c60"],["0x000000000000000000000000ae23c1f73a8b1c138ab3aefb7b17fe53a26f0ba4"]],"resultHash":"0xabfa30a25a5dff5bb9ebde5123210fa78396c7ae9931d129932df08e73bb4bed"},{"fromBlock":0,"toBlock":7331384,"address":[],"topics":[["0x2402307311a4d6604e4e7b4c8a15a7e1213edb39c16a31efa70afb06030d3165"],["0x000000000000000000000000000000000000000000000000000000000001ad8f"]],"resultHash":"0xa7ec12665c16f1f2eadabba7427f11e7cb8dd9ce6f74230cb5050c4f51d14216"},{"fromBlock":469534,"toBlock":7755769,"address":["0xd86e1fedb7120369ff5175b74f4413cb74fcacdb"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002877"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x67875e05a1022def8a74be30bc54f97df541fa2d9549ba9f90d521e15fbeaf61"},{"fromBlock":1124482,"toBlock":7755739,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],["0x0000000000000000000000008e17d8f42bf281657e3b96f1637bce965fb45aae"],["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xa0d8b3a995e77ecfc95a97d4c8509f75fd87216d96c517131ff3f8900e343bdf"},{"fromBlock":0,"toBlock":7331384,"address":[],"topics":[["0x2402307311a4d6604e4e7b4c8a15a7e1213edb39c16a31efa70afb06030d3165"],["0x000000000000000000000000000000000000000000000000000000000001ad8f"],["0x434ab18e74443aedaf60deb40b86a46652a31f8e7946b89e38d87010a8c71dfa"]],"resultHash":"0xa7ec12665c16f1f2eadabba7427f11e7cb8dd9ce6f74230cb5050c4f51d14216"},{"fromBlock":0,"toBlock":6647562,"address":["0xda9d4f9b69ac6c22e444ed9af0cfc043b7a7f53f"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000b21d8d14e2ec2837fa187848109f806b9172b82b"],["0x000000000000000000000000e7ec1b0015eb2adeedb1b7f9f1ce82f9dad6df08"]],"resultHash":"0xe86144ddfbd406af4c1b8cc2ff35218be614bbc668f536e8e9f2e9e5cd34ac7a"},{"fromBlock":2027722,"toBlock":7755769,"address":["0x1cd40deb4196d219097499031922ff690f9ea813"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000093b714330996f3dec51c455e4ac85f3864274fae"]],"resultHash":"0xa02d3cd63ea10c0707545f43460fbbd45dbb601ca7a5bbad1fa7f45524a3f93f"},{"fromBlock":440737,"toBlock":7755739,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002a67"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x573c4eadf583b0d44a4d6efbfc7d11cb686c966567d74b636fa7c0643ca319b8"},{"fromBlock":1332316,"toBlock":7755769,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],["0x00000000000000000000000016ee14bcdc1b1f5bc13842aa1c005e72cf8046f0"],["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xf0e6d179cb320ff3073773424a2527335b2e2b090ddf2bbeb4ae4521f78a4f7d"},{"fromBlock":97914,"toBlock":6198290,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,["0x00000000000000000000000000000000000000000000000000000000000026f0"],["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xb22ca6d721e6efae3a08cd5f3cc8445ce2dad505f09887d2d610a96beb344878"},{"fromBlock":1779212,"toBlock":7755769,"address":["0xff34b3d4aee8ddcd6f9afffb6fe49bd371b8a357"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000c94b1bee63a3e101fe5f71c80f912b4f4b055925"],["0x0000000000000000000000006b29975137d7de522bf6c4615051370c55820b3e"]],"resultHash":"0xeade6da3b2d7a6dacbc0f1c1cda1fdf07194f8b3f51831a2fc71fa1a861ec248"},{"fromBlock":0,"toBlock":6963740,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],["0x0000000000000000000000000000000000000000000000000000000000001691"],["0x000000000000000000000000f28e3d6e64cd5ae909177ea99ecac63755ca978f"]],"resultHash":"0xd3ef8289c9a1952596e940a68f90099c7caea45b0b1d99e77151e65907182c40"},{"fromBlock":149843,"toBlock":7755739,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],["0x000000000000000000000000000000000000000000000000000000000000143a"],["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0x6077db27849bef200b3541993126367612b3c1e6ed9458f9c1a8c32281660a49"},{"fromBlock":1322151,"toBlock":7755769,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[null,["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000000000000000000000000000000000000000000238"]],"resultHash":"0x22a2495a4d5c903dd509ef936525f9c49399129d433f5e40e395803aeab179ce"},{"fromBlock":37570,"toBlock":7755739,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002b3c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x7277f377d26ae279ba35746e6bb51d6d78c74aefb495545c782a3a3297e83f51"},{"fromBlock":3425286,"toBlock":7503281,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000007046ba909536b39cf09850c551670456a689ade0"],["0x0000000000000000000000009ea18de905e654f9fb98498109c60edfe133c145"]],"resultHash":"0xfec37559bfdb750b326c11090c974e0ab17d81ac86c6d2632aaeb8e5b9f5a86b"},{"fromBlock":1577956,"toBlock":7755800,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000000000000000000000000000000000000000020c"]],"resultHash":"0xd7dbc2c173a5d7f078ad22aa7af6054a0ad8088bde45beb5681ae9042282249b"},{"fromBlock":0,"toBlock":6361726,"address":["0xb015188cb963080f9ecee1cfe591d4b5e75f162f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0xe976749493b17bc67904fd83d21972968d3f66ef29f6af3da6809b477abb53a2"},{"fromBlock":772075,"toBlock":5340530,"address":["0xbdbfd0f7593637c64624191008f46e0ce9e408f3"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x1dde06b3e0106b19be7b944b4ffbbd264541c3d249d4971bee3f8bfeefe2fe1a"},{"fromBlock":658060,"toBlock":7082999,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000001b89a43d543260fee7e0cad06a4b3b1beab20527"],["0x0000000000000000000000008f73f932d0310ec85731648bcbacf2de3b60bb0c"]],"resultHash":"0x643de3d3865f816e15b33f59fc08ac65c320f97841539305d12d140dc2baafe6"},{"fromBlock":0,"toBlock":7184764,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],["0x00000000000000000000000000000000000000000000000000000000000016ca"],["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0x23ebd5098b97d64283c723ea464e3fd7425d11ce2e4e2e31ea3ab7b2fb290f9f"},{"fromBlock":1268701,"toBlock":7755769,"address":["0x10434f7420dc32ad66132651d62b0b05490ab980"],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],null,["0x0000000000000000000000000000000000000000000000000000000000008809"],["0x00000000000000000000000000000000000000000000000000000000003fc4b0"]],"resultHash":"0xe1787b3c025de2b588fc661cf1fa4c1b030285de045f138d0dba37b863e632ce"},{"fromBlock":0,"toBlock":7469432,"address":["0xd86e1fedb7120369ff5175b74f4413cb74fcacdb"],"topics":[null,["0x000000000000000000000000000000000000000000000000000000002b10a031"],["0x000000000000000000000000000000000000000000000000000000000001ad5b"]],"resultHash":"0xe83c59505d21a5d612db76d0783d2eb6ac981542d914ecfbfb09e790e0eaf5ed"},{"fromBlock":2485608,"toBlock":7755769,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000000000000000000000000000000000000000000c4"]],"resultHash":"0x90c8ebb546a054508bfb54b6104e7a3b3ab67b8be244442c179a3eafd0add481"},{"fromBlock":1916125,"toBlock":7755769,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000000000000000000000000000000000000000000346"]],"resultHash":"0x32724d34432774ced966156e39eddbf1a756d0494289f64f2099880e5832d896"},{"fromBlock":974029,"toBlock":7755769,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002aa2"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x73c2bed0c7eb59190097192e9b4e138c5fa3b314f5409bb9baa2b4e718509c10"},{"fromBlock":1494097,"toBlock":7755769,"address":["0x4873528341d33ec918c7465f244491acb75bc95f"],"topics":[null,null,["0x0000000000000000000000005fe6d3ddf7c8bf6a36a86cbb9c2edc225a20a458"]],"resultHash":"0x6c029c73f8493170a23af4df2486fb925c7a960053623a48515daaca01d19dbf"},{"fromBlock":618159,"toBlock":7755800,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000097f75fb0350d562bf64b051c2a1937825609a2db"]],"resultHash":"0xe04dce7ecc2f73611f1ddb4822c562762c6b9f6f323adb5dbbb17869de9aa437"},{"fromBlock":0,"toBlock":6963740,"address":[],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],["0x0000000000000000000000000000000000000000000000000000000000001691"],["0x000000000000000000000000f28e3d6e64cd5ae909177ea99ecac63755ca978f"]],"resultHash":"0xd3ef8289c9a1952596e940a68f90099c7caea45b0b1d99e77151e65907182c40"},{"fromBlock":0,"toBlock":6002762,"address":[],"topics":[null,["0x00000000000000000000000000000000000000000000000000044471043de100"],["0x00000000000000000000000000000000000000000000000000000000000012dd"]],"resultHash":"0x260d28a179d7bf21c310e89a8597da7a7e02af5b7512fba5963ac4a4007ec9e0"},{"fromBlock":0,"toBlock":7184318,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],["0x00000000000000000000000000000000000000000000000000000000000016fd"],["0x00000000000000000000000038dc84830b92d171d7b4c129c813360d6ab8b54e"]],"resultHash":"0x2dfcf14420e2035042b6c26b3e010977fb6f061a2076e2ca273a5e23224d65d1"},{"fromBlock":1203535,"toBlock":5963354,"address":["0xe72c66da780842bd8815d7616dc1f7e5b6b104b9"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000006bc2445ae61f40ba1672afe4c75af5a9049011aa"],["0x00000000000000000000000072b9c3c2847e0c09776c071b2610dec9521c54d6"]],"resultHash":"0x64905200d66c93aff1f590335dcd93537a4aa7496bc052d13d17366c17d71677"}],[{"fromBlock":218186,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000093c4a726466183e43551973b5dcc9aa3e106f6cb"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x5c2b0fe71c1bc5590be1ccdb676f56ef408bc475596b4d9517b1a68312ffc5b7"},{"fromBlock":1817119,"toBlock":7755769,"address":[],"topics":[null,["0x000000000000000000000000ce4ebf96f01ca3a7c987d755ca2e87e86d6b169d"]],"resultHash":"0x323931c385c02cd8a3fee4c9b754cad333ed5cd9b9705a5faad024ea92f6a1d6"},{"fromBlock":0,"toBlock":5602481,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[null,["0x0000000000000000000000006e2c879382520c7b15927902eef1c0fbc1f8de91"],["0x00000000000000000000000027f0b7fa41a6e4617b4284138278f81281214cc1"]],"resultHash":"0xf5a706bd471646ca308163105515fe99218ef10d6e8e2c9de7e6b02999564103"},{"fromBlock":0,"toBlock":7067412,"address":["0xfbed2b7f3cde372a5aa7f92d53e6a9599e22ac5e"],"topics":[["0x91fb9d98b786c57d74c099ccd2beca1739e9f6a81fb49001ca465c4b7591bbe2"],["0x000000000000000000000000b0446f6b31376491690c6b4e2e2a24ed13486ea3"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x1c5864e06d9b74ca73c86ca99c40a91af014299deb156deb310c357c517a910e"},{"fromBlock":0,"toBlock":4746864,"address":[],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000001cea2"]],"resultHash":"0xcf8556b7df3ba469af191b2f7bbeb7d8b0a3516020eedcd4d66702d781556cc2"},{"fromBlock":0,"toBlock":6736853,"address":[],"topics":[null,null,["0x0000000000000000000000009883c1e85440aa4f8d1220bf7c544b13e13d0625"]],"resultHash":"0xb5fe5e688a6cc230dcfb25aff44faa52f2c035ef9d7950fba392a978071cb089"},{"fromBlock":35918,"toBlock":7755708,"address":["0xb31c077c99e0d61305fcd873a39f974d13bc773c"],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x1c07275dfc8a6121a64a504eabcc7c2fba30360ed3a5b78e9ce882fbe3a9cca9"},{"fromBlock":102389,"toBlock":6533396,"address":["0xb0446f6b31376491690c6b4e2e2a24ed13486ea3"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000fbed2b7f3cde372a5aa7f92d53e6a9599e22ac5e"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x2aa514d480e36fcbe0a7eb8043f4151870d25d9692281073c68ec1f803c572e8"},{"fromBlock":319574,"toBlock":7658479,"address":[],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,["0x0000000000000000000000000000000000000000000000000000000000001459"]],"resultHash":"0x210dd4ea001848a745ca5b84d72dee7c3894ba5c7e5905b9ea8236af8abb42c6"},{"fromBlock":2829143,"toBlock":7755739,"address":[],"topics":[null,["0xcf5384602957fef6c885e5319d928d8d970b930871c6ca008ef6b69cf0e7564f"]],"resultHash":"0x9330260210cb68ead1ec8aa8b3c0422d24d0dd16d0e59b75792bdb430337726a"},{"fromBlock":1501140,"toBlock":7755800,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[null,["0x000000000000000000000000e430f677a5e41db1e0a4b398af58a41c12fa27fe"],["0x0000000000000000000000009ea18de905e654f9fb98498109c60edfe133c145"]],"resultHash":"0x0c1c91612957b7f3927f0d3a263423be392967a10bc08dbfaafecbdfb38f62a6"},{"fromBlock":35918,"toBlock":7755708,"address":[],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x1c07275dfc8a6121a64a504eabcc7c2fba30360ed3a5b78e9ce882fbe3a9cca9"},{"fromBlock":0,"toBlock":7127855,"address":["0x3cb855c19fef72dfbe8d238e07ba49f7017ef85f"],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000000000000000000000000000000000000000000004"]],"resultHash":"0x0973b75419b145d45f243e430a161f4a60b6377f0de8485b777b020ca1047129"},{"fromBlock":2930719,"toBlock":7755769,"address":["0xf813d7a9dc058df8da69992ba978a2e76d6447ee"],"topics":[],"resultHash":"0x9074b64ce2cc9f2006c890c5c5676cf73ad421ac0ec786e81fd154b1935f60a7"},{"fromBlock":1222594,"toBlock":7755769,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000037648ceff8591473c09e5de49422a403bbf9756d"]],"resultHash":"0x1d4a343a932f79623a4b94fa1ae8960ec1024919010143d17176615c9a66a433"},{"fromBlock":1544694,"toBlock":7755769,"address":[],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x00000000000000000000000000000000000000000000000000000000000020bf"]],"resultHash":"0xbfba2e394642314af307282851d545daf89ed2c0ebaf0c5d1b3f9563dbe9effc"},{"fromBlock":729251,"toBlock":6467006,"address":["0x6ef88a8825753a0f66de42ac51e48956530372eb"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000004cd6c9069cd0e8d23e6560a9b9ea10e296dca86e"],["0x000000000000000000000000680b102a587a0ee4495b3013a708aa23b8c684e1"]],"resultHash":"0x304da208266de63accc272eb2ae2d720c1192770cedba21e5a64acc54053d0c2"},{"fromBlock":0,"toBlock":7089740,"address":["0x6375394335f34848b850114b66a49d6f47f2cda8"],"topics":[["0x2295930c498c7b1f60143439a63dd1d24bbb730f08ff6ed383b490ba2c1cafa4"],["0x000000000000000000000000000000000000000000000000000000000005f6e0"]],"resultHash":"0x159f8460372be2931e8d14431e716d7e34488b4c7a8fb397c5baebde6737f14f"},{"fromBlock":671105,"toBlock":7719053,"address":["0x22c1317fe43132b22860e8b465548613d6151a9f"],"topics":[null,["0x000000000000000000000000ebe7f58df983241023672cfd7fef1e166849e936"],["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8"]],"resultHash":"0x5185fa7f41d6dd38153c83216905a099903fa01cf9fc29c6fc39967e8d345d2b"},{"fromBlock":1815960,"toBlock":7755739,"address":[],"topics":[null,null,["0x00000000000000000000000000839a4f507e16d3d8c0ed04068a6f9557e79e3e"]],"resultHash":"0xfd78e5b32d8405b17763b1e0083409b54151d39c17e62fb7d36b9be34f0d9bf6"},{"fromBlock":619345,"toBlock":6465701,"address":["0x6375394335f34848b850114b66a49d6f47f2cda8"],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000005f6fe"]],"resultHash":"0xade939a407d2c0ea5291057a02e48a45d5e8bbfb2087a1574436a92b2f6c883a"},{"fromBlock":615694,"toBlock":7610170,"address":["0x11d82a3cf69d22a9af546f7f26af16d04f64e54e"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000026baac08cb753303de111e904e19baf91e6b5e4d"]],"resultHash":"0x54eb3c7e3ca68f58aab277813c09298ee338034127b5f8132e9e4ef5b0c8ba96"},{"fromBlock":0,"toBlock":7298572,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000024bdbd3f1beb74f48628476b69bc009113950d36"],null],"resultHash":"0x16107e89f35ae2a8bdccbf7918948fe843fdd82bed87d8f8ccb78db19ed35e52"},{"fromBlock":773167,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000f9488af53b849014168eb123f5fa774a8effcf60"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xdac70f6ede8c023b1bc496a1265f3d5bbee568607b25c3266605aac1fa0d8256"},{"fromBlock":290791,"toBlock":6998007,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000fbed2b7f3cde372a5aa7f92d53e6a9599e22ac5e"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x6c86afa1aa1610c179d4439582e3bd68a12784e183e509e65f143f2d9864dd6b"},{"fromBlock":1581505,"toBlock":7755800,"address":[],"topics":[["0xa1a0dabcc18e414e32ee23df17c071b7112131effdebabcb06191c9e1cc12f60"]],"resultHash":"0x1b905c4ae5cb2144abe53d4091343cad344ef5374ed2fb2d08a1af2be51fd814"},{"fromBlock":0,"toBlock":6559652,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000006e2c879382520c7b15927902eef1c0fbc1f8de91"],["0x00000000000000000000000027f0b7fa41a6e4617b4284138278f81281214cc1"]],"resultHash":"0xf5a706bd471646ca308163105515fe99218ef10d6e8e2c9de7e6b02999564103"},{"fromBlock":2818800,"toBlock":7755800,"address":["0xea58fca6849d79ead1f26608855c2d6407d54ce2"],"topics":[null,null,["0x000000000000000000000000813d308658d82f338c75e63ca5eac41dc76e717b"]],"resultHash":"0x450597e8a229b123b7c5f27124934d52f3c9f925b9f063b2c58f809be7d20fc0"},{"fromBlock":2655386,"toBlock":7755739,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000","0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"],null,["0x0000000000000000000000000000000000000000000000000000000000063c57"]],"resultHash":"0x1af401ab50a5ce62bf6e73620c43ee0350160bf7d2cec4cba1c0771e162c6cb6"},{"fromBlock":927975,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xfabeb6eee9d30787fdadf82a38cd59de6b1889367b29fd10563cdae8f88e1be8"},{"fromBlock":2132337,"toBlock":7755739,"address":["0xb31c077c99e0d61305fcd873a39f974d13bc773c"],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x196b99b963fabbc8bf8fc0b53aa4f5196c48509e7c877b9441b9b8ff36be0a19"},{"fromBlock":927975,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xfabeb6eee9d30787fdadf82a38cd59de6b1889367b29fd10563cdae8f88e1be8"},{"fromBlock":0,"toBlock":7246717,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x00000000000000000000000000000000000000000000000000000001636c28c0"],null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xf1b66b91ac19216bb81eb6345e23894d6b9779360f4f8471798be8f3aa62d068"},{"fromBlock":249911,"toBlock":6196974,"address":["0xa3c8ba0a9261ff47a146e6755afa430f0126ea34"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000006e2c879382520c7b15927902eef1c0fbc1f8de91"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x1673a124f214802aaa94ef67cc18b3165057ebf148008b0d604a706bb1cf8fc1"},{"fromBlock":1013045,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000081fd82b125b863c1ddb8aad1f313a16df0308b23"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xd6dfc06feceaaa8fc694e30c49b9d7e00f4be320f669018c041c26d79f4f2e77"},{"fromBlock":319032,"toBlock":7755739,"address":["0xb31c077c99e0d61305fcd873a39f974d13bc773c"],"topics":[null,["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x3dfbeb8b859cab25592cb88ba8e206f2d922972bdc7de15752ecc38600e83870"},{"fromBlock":0,"toBlock":6846660,"address":["0xaaea189325f03da321e1c590583daca15d4ef055"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000444f875c1754eb221032f8023dc03de2bc2098ff"]],"resultHash":"0xa0016a7b27f7dd55e3e0f68ac4d807ff15141b026b4415bf433a597774c23d23"},{"fromBlock":118341,"toBlock":7755739,"address":[],"topics":[["0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"]],"resultHash":"0x1ffe9f0d8b8bb414f1e8c7d3f0dc91cbaa806d05722050522ef254041fe562db"},{"fromBlock":767048,"toBlock":5904242,"address":[],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,["0x0000000000000000000000000000000000000000000000000000000000001318"],["0x000000000000000000000000f28e3d6e64cd5ae909177ea99ecac63755ca978f"]],"resultHash":"0x244ab27cf83cf231aefd594de219976de0cf2b3ab72b75918dbda11f208c3e8f"},{"fromBlock":0,"toBlock":5602481,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000006e2c879382520c7b15927902eef1c0fbc1f8de91"],["0x00000000000000000000000027f0b7fa41a6e4617b4284138278f81281214cc1"]],"resultHash":"0xf5a706bd471646ca308163105515fe99218ef10d6e8e2c9de7e6b02999564103"},{"fromBlock":2132337,"toBlock":7755739,"address":["0xb31c077c99e0d61305fcd873a39f974d13bc773c"],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x196b99b963fabbc8bf8fc0b53aa4f5196c48509e7c877b9441b9b8ff36be0a19"},{"fromBlock":755490,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000000446cfb718171eedb2bfae289c961fbed8df2555"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xb51986054b3c9f20e4d3565fdb38bded2148f59cb19473163f85cc6679d17ab5"},{"fromBlock":1575510,"toBlock":7755769,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000001b8e"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x4d539691373a7fe64c8f0c6f83ec75a7572c6c1c12ce15b99376fa6c1d4aa596"},{"fromBlock":466962,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000009c4e1984341f8e1149f8daed7f9f45af49bef010"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xd608e9f3cf7b312c962ac423f46c06bd7130abbc4d7150b99da4d6e5f73d38ae"},{"fromBlock":0,"toBlock":7189296,"address":[],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000001cdb5"]],"resultHash":"0x9e70ea924ba3ffed550596ccba84932273972dba01d8f78af0036caefb1e51bf"},{"fromBlock":0,"toBlock":7089740,"address":["0x6375394335f34848b850114b66a49d6f47f2cda8"],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000005f6e0"]],"resultHash":"0xa0a349e5400bd2564622c2316e2dcdfd4db86956c7cac695ba64543a5f692566"},{"fromBlock":586592,"toBlock":6225433,"address":["0xb0446f6b31376491690c6b4e2e2a24ed13486ea3"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000005b3f3266a9fcce9dfd996cd6f08d8513cb021062"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0xa992384b2342d6051204e8f0cf3e9abe0d3c6f355bb5115280a11fcf9625639f"},{"fromBlock":1948623,"toBlock":7755739,"address":["0x9072495afc2d59d857118ee59b4ef6cfc407d103"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000bde8fb9f69c9359f887f64a17f4a0edadbd9f668"],["0x00000000000000000000000092c7017c9dca00a8dfa55e918d7c0c647500c640"]],"resultHash":"0x7ffb9d7fb1352dbac68611e490ff4c742e36bdc66c439ae3d57f377593a75e5e"},{"fromBlock":756310,"toBlock":7755769,"address":[],"topics":[["0x35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"]],"resultHash":"0xfc36e2649fea727e0b3cc165611b6efc4075cf0747a44ae52b21763371262ff3"},{"fromBlock":118341,"toBlock":7755739,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"]],"resultHash":"0x1ffe9f0d8b8bb414f1e8c7d3f0dc91cbaa806d05722050522ef254041fe562db"},{"fromBlock":1689113,"toBlock":7755769,"address":[],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"]],"resultHash":"0x196b99b963fabbc8bf8fc0b53aa4f5196c48509e7c877b9441b9b8ff36be0a19"},{"fromBlock":491064,"toBlock":7022525,"address":["0xeb8ba4184fe5f76bc55055c85aafae9af372d28d"],"topics":[null,["0x000000000000000000000000fbed2b7f3cde372a5aa7f92d53e6a9599e22ac5e"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x3057b6fed8b19c69be28a5abf5ad4e58139732193ee957cc67b5d17f703f72aa"},{"fromBlock":564562,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xfabeb6eee9d30787fdadf82a38cd59de6b1889367b29fd10563cdae8f88e1be8"},{"fromBlock":2132337,"toBlock":7755739,"address":[],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x196b99b963fabbc8bf8fc0b53aa4f5196c48509e7c877b9441b9b8ff36be0a19"},{"fromBlock":319032,"toBlock":7755739,"address":["0xb31c077c99e0d61305fcd873a39f974d13bc773c"],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x196b99b963fabbc8bf8fc0b53aa4f5196c48509e7c877b9441b9b8ff36be0a19"},{"fromBlock":2252326,"toBlock":7755739,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000004b7d4ee7c2126dc2967e36f10fe4f7322812e34"]],"resultHash":"0x77874a27e346d61f4a84660b4cde4f4aa5f405cc64fe25d9a77bf29b87599e80"},{"fromBlock":2655613,"toBlock":7755739,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[null,["0x000000000000000000000000e430f677a5e41db1e0a4b398af58a41c12fa27fe"]],"resultHash":"0xb54fef8ca006042b7c6665f461a502d81f22efab1e73db824f5493b893a0d6ac"},{"fromBlock":1013045,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000081fd82b125b863c1ddb8aad1f313a16df0308b23"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xd6dfc06feceaaa8fc694e30c49b9d7e00f4be320f669018c041c26d79f4f2e77"},{"fromBlock":0,"toBlock":6499817,"address":["0x40001ecac527d825d8d73f50ceab01925676099b"],"topics":[null,["0x0000000000000000000000002c6ede8d0e0e41975d2a141a3d1fcd65c9affdff"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x9f31e2589ccb683e665fed930f0638521badca1726975752fcd821a189141b2a"},{"fromBlock":586380,"toBlock":7755708,"address":["0xe83ebf27702244dd5997526692f03415f741b98f"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x00000000000000000000000085fb57a0dcab5b8ed7b699b0803ed455ab6ea472"]],"resultHash":"0x2b8ce5904fb087cec112e7b3c4209675f393fe6bf3aa13fba9cdf903d18a10f4"},{"fromBlock":319574,"toBlock":7658479,"address":[],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,["0x0000000000000000000000000000000000000000000000000000000000001459"],["0x000000000000000000000000f28e3d6e64cd5ae909177ea99ecac63755ca978f"]],"resultHash":"0x13e16d3f7d4338abd755f2cee598a3f962be48c86eaefe9a1a5924eab508eb0c"},{"fromBlock":0,"toBlock":6625642,"address":[],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,["0x0000000000000000000000000000000000000000000000000000000000001410"],["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0x8f0307797c8f4511f30a732a843414c040850fd0ab915208fc761150db50e138"},{"fromBlock":491064,"toBlock":7022525,"address":["0xeb8ba4184fe5f76bc55055c85aafae9af372d28d"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000fbed2b7f3cde372a5aa7f92d53e6a9599e22ac5e"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x3057b6fed8b19c69be28a5abf5ad4e58139732193ee957cc67b5d17f703f72aa"},{"fromBlock":0,"toBlock":7687772,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x00000000000000000000000000000000000000000000000000000001502b9200"],null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xd7988b474adc8d0f7cd6eac64b6b988673d2ff6680147877aeceb71999de3700"},{"fromBlock":0,"toBlock":7214277,"address":[],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000014029"]],"resultHash":"0x08499c749883c61abe307a4650e85b0a88e9e4babaf6bb563f4969ef6a196f05"},{"fromBlock":2360290,"toBlock":7309771,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000026baac08cb753303de111e904e19baf91e6b5e4d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xb058404826bb3ad6d19edbc6bf62ad48a4b4f9f60796560406275970a3ad43d4"},{"fromBlock":0,"toBlock":5350924,"address":[],"topics":[null,null,null,["0x0000000000000000000000004eba5a3f148d354a06f2dca293792e9970dd0431"]],"resultHash":"0xee25f546e6f89beba4fc91dfc37ed3dc90517b7dcca6848878d46e876b6658aa"},{"fromBlock":491064,"toBlock":7022525,"address":["0xeb8ba4184fe5f76bc55055c85aafae9af372d28d"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000fbed2b7f3cde372a5aa7f92d53e6a9599e22ac5e"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x3057b6fed8b19c69be28a5abf5ad4e58139732193ee957cc67b5d17f703f72aa"},{"fromBlock":2223786,"toBlock":7755739,"address":["0xaa8e23fb1079ea71e0a56f48a2aa51851d8433d0"],"topics":[null,["0x00000000000000000000000084a1488afeb5cbec88d000f5c7d6114779e1e2e9"]],"resultHash":"0x02dcc447aab01af0d7c4cdfe864c946be5800cd1e2de5d88e49e45f5894834d1"},{"fromBlock":2132337,"toBlock":7755739,"address":[],"topics":[null,["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x3dfbeb8b859cab25592cb88ba8e206f2d922972bdc7de15752ecc38600e83870"},{"fromBlock":2829143,"toBlock":7755739,"address":["0x19fc4f304c1198c8ae1c23630a1611b27883693a"],"topics":[null,["0xcf5384602957fef6c885e5319d928d8d970b930871c6ca008ef6b69cf0e7564f"]],"resultHash":"0x9330260210cb68ead1ec8aa8b3c0422d24d0dd16d0e59b75792bdb430337726a"},{"fromBlock":991171,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xfabeb6eee9d30787fdadf82a38cd59de6b1889367b29fd10563cdae8f88e1be8"},{"fromBlock":249911,"toBlock":6196974,"address":["0xa3c8ba0a9261ff47a146e6755afa430f0126ea34"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x1673a124f214802aaa94ef67cc18b3165057ebf148008b0d604a706bb1cf8fc1"},{"fromBlock":0,"toBlock":6991621,"address":[],"topics":[null,null,null,["0x000000000000000000000000d28b3e460c660cb2ab0a4398aaf214fe822827a5"]],"resultHash":"0x2315e5403c48f5765c1529b5f11dafe9292210a890be7b71f4134603826dcd12"},{"fromBlock":218186,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000093c4a726466183e43551973b5dcc9aa3e106f6cb"]],"resultHash":"0x5c2b0fe71c1bc5590be1ccdb676f56ef408bc475596b4d9517b1a68312ffc5b7"},{"fromBlock":114273,"toBlock":7542814,"address":[],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000078865a27"]],"resultHash":"0xb9ec0f0d81693772fd26f7687dde9fb00a620907029059384b5aaeb371fa29a9"},{"fromBlock":0,"toBlock":7591891,"address":[],"topics":[null,null,null,["0x000000000000000000000000000000000000000000000000000000000000fa9e"]],"resultHash":"0xd426f1774c84c1e10ddcb847dfd52ba59aa14075dcdccb23efa58d1250ee3d5f"},{"fromBlock":2132337,"toBlock":7755739,"address":["0xb31c077c99e0d61305fcd873a39f974d13bc773c"],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x196b99b963fabbc8bf8fc0b53aa4f5196c48509e7c877b9441b9b8ff36be0a19"},{"fromBlock":35918,"toBlock":7755708,"address":["0xb31c077c99e0d61305fcd873a39f974d13bc773c"],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x1c07275dfc8a6121a64a504eabcc7c2fba30360ed3a5b78e9ce882fbe3a9cca9"},{"fromBlock":991171,"toBlock":7755708,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xfabeb6eee9d30787fdadf82a38cd59de6b1889367b29fd10563cdae8f88e1be8"},{"fromBlock":0,"toBlock":5602481,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000006e2c879382520c7b15927902eef1c0fbc1f8de91"],["0x00000000000000000000000027f0b7fa41a6e4617b4284138278f81281214cc1"]],"resultHash":"0xf5a706bd471646ca308163105515fe99218ef10d6e8e2c9de7e6b02999564103"},{"fromBlock":368360,"toBlock":7755769,"address":["0x7abf52a91d3d078960bafc9912fa1be248ef6dcf"],"topics":[["0xaeeb0cb16f299136e7e5467ea84217150fe83008833064528f360cde7b7b54c3"],["0x000000000000000000000000d23ce3b387eb7e80ca658457562c7198f7f83c40"]],"resultHash":"0xe6b4f020458ec2ffa72e703c15c7406f9b0bac67be6d12658f060232640ada21"},{"fromBlock":756310,"toBlock":7755769,"address":[],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"]],"resultHash":"0xb5497a6ece590089795d7cfa420df4a5f3ad890cb26ec4a31f2b421b454e9d34"},{"fromBlock":265477,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xfabeb6eee9d30787fdadf82a38cd59de6b1889367b29fd10563cdae8f88e1be8"},{"fromBlock":819093,"toBlock":7755739,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000000d6e94d085a597f316be1833649e05a45103e873"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x7b1b00c8fc4d2c6311ffa1f63d38a4b4411eca8dfd6eda9c126353d07bd8d7c7"},{"fromBlock":411526,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83","0xa06bc650f98c11fbe102bece34df529650a60de6"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000079240ea3dba4f6e58a77192c9c24dd57bc79304a"]],"resultHash":"0x4261b62aced3c3e413c8438f3c341bf1d9f04224c98b881b1fccaa6446ff62bc"},{"fromBlock":319032,"toBlock":7755739,"address":["0xb31c077c99e0d61305fcd873a39f974d13bc773c"],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x196b99b963fabbc8bf8fc0b53aa4f5196c48509e7c877b9441b9b8ff36be0a19"},{"fromBlock":2796902,"toBlock":7755800,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000001c59a21211362f2a5fea0d7879a2a7dcf88aae7c"]],"resultHash":"0xb9fea08ecf0dab96e5f7afd22b7eedee3feedfb9adf9f8de4a3ab55ead3f3e1c"},{"fromBlock":1815960,"toBlock":7755739,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000000839a4f507e16d3d8c0ed04068a6f9557e79e3e"]],"resultHash":"0xc7d89a12e7437b0823b28d756216b8e54e13fe83316142e175ef57632d0f0759"},{"fromBlock":2829143,"toBlock":7755739,"address":[],"topics":[["0x53bb90500b4bcd81f514e255a8d31018839272f80fc8c3d7f7f153e58c056568"],["0xcf5384602957fef6c885e5319d928d8d970b930871c6ca008ef6b69cf0e7564f"]],"resultHash":"0x9330260210cb68ead1ec8aa8b3c0422d24d0dd16d0e59b75792bdb430337726a"},{"fromBlock":118341,"toBlock":7755739,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"]],"resultHash":"0x1ffe9f0d8b8bb414f1e8c7d3f0dc91cbaa806d05722050522ef254041fe562db"},{"fromBlock":35918,"toBlock":7755708,"address":[],"topics":[["0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x1c07275dfc8a6121a64a504eabcc7c2fba30360ed3a5b78e9ce882fbe3a9cca9"},{"fromBlock":0,"toBlock":6432433,"address":[],"topics":[["0x51bbdc1d2a76e18752092da32318ce9d5ad268aae23f908efaf64aab614f8190"],["0x000000000000000000000000919663102b19fae17492a150bbf24a5196738441"]],"resultHash":"0x52169c89d8e3d1e71f69ea5f27543752f38b7c91db5d666a74971be1ec1c7c29"},{"fromBlock":700234,"toBlock":7755739,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xe41ae498b19bc37605d7b76851107908ff10f1fd3cf508b8c8ca186455428626"},{"fromBlock":539956,"toBlock":6303041,"address":["0x8eb074ddacc85832fda109ab3d93cc21914bee5f"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],["0x0000000000000000000000006e2c879382520c7b15927902eef1c0fbc1f8de91"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0xfdad440386874d4cbd78a88c8dab034f4508d18610ebbf29bc2248c365731726"},{"fromBlock":1494097,"toBlock":7755769,"address":[],"topics":[null,null,["0x0000000000000000000000005fe6d3ddf7c8bf6a36a86cbb9c2edc225a20a458"]],"resultHash":"0x3b50adb0b99b6f1f51197e44017490e53bf3563ada3a9534ec52d525733c8fb5"},{"fromBlock":981711,"toBlock":7741762,"address":[],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000002877"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xa2affcbbb5d5b5ff2f41233b9b354ab984a5c2483a3ea478f11ebf64a3b6ca01"},{"fromBlock":0,"toBlock":6559652,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[null,["0x0000000000000000000000006e2c879382520c7b15927902eef1c0fbc1f8de91"],["0x00000000000000000000000027f0b7fa41a6e4617b4284138278f81281214cc1"]],"resultHash":"0xf5a706bd471646ca308163105515fe99218ef10d6e8e2c9de7e6b02999564103"},{"fromBlock":0,"toBlock":5760683,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x00000000000000000000000027f0b7fa41a6e4617b4284138278f81281214cc1"]],"resultHash":"0xf5a706bd471646ca308163105515fe99218ef10d6e8e2c9de7e6b02999564103"},{"fromBlock":1088752,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x7012f930062bb41825d874ca35039ab8945dc3e536e109b4e7464fbb3317fd78"}],[{"fromBlock":960895,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":0,"toBlock":7184764,"address":[],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0xd14fe5cc8237c75bd416800cb1150c55f7371a015cc1470cd20d88cd3369c95f"},{"fromBlock":1696164,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1127343,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":0,"toBlock":7665156,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0xac6e0c2854e815f242460671ef73ecf8b6da189bd899782ae6bfcfc2526c0de9"},{"fromBlock":662475,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[null,["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xe66bcdc172b6a719f1e5b96fa280cbb33d981950167475d193474c458bf81949"},{"fromBlock":729251,"toBlock":6467006,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000004cd6c9069cd0e8d23e6560a9b9ea10e296dca86e"],null],"resultHash":"0xe9b5d3dc09bbe4587cce7e7ed72d2da6ed31fd13ba5d1ef5647c75825518912d"},{"fromBlock":565376,"toBlock":7692773,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":2060394,"toBlock":7755739,"address":["0x7abf52a91d3d078960bafc9912fa1be248ef6dcf"],"topics":[null,["0x000000000000000000000000d23ce3b387eb7e80ca658457562c7198f7f83c40"]],"resultHash":"0x0454105e91743a267887113a6a6a2bb3fa3289798d343a47fee337ceeea8032d"},{"fromBlock":0,"toBlock":6133952,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],null,["0x000000000000000000000000f28e3d6e64cd5ae909177ea99ecac63755ca978f"]],"resultHash":"0xbb114350fe45198706be9a1b7a61b11d6a6b86f1556b823afd38026f9172bb3f"},{"fromBlock":1067513,"toBlock":7444699,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0xac6e0c2854e815f242460671ef73ecf8b6da189bd899782ae6bfcfc2526c0de9"},{"fromBlock":0,"toBlock":7671140,"address":["0xb647735a3dcd086d5e7adc1c8f1f4733f5b46a5a"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x0000000000000000000000003d52b839a410fc977e73b98f36d1a40102e1ab79"]],"resultHash":"0x3cc6243513f8886631a5dd9fa63220df847ff03f850a1478866c4d1b5cc8001f"},{"fromBlock":263733,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1268701,"toBlock":7755769,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],null,["0x0000000000000000000000000000000000000000000000000000000000008809"],["0x00000000000000000000000000000000000000000000000000000000003fc4b0"]],"resultHash":"0x56b0e14277a624891e94b38c9cca4bd09ba522c5dc9c4ed83e1dd891aaa87dc2"},{"fromBlock":0,"toBlock":7276691,"address":["0xb647735a3dcd086d5e7adc1c8f1f4733f5b46a5a"],"topics":[],"resultHash":"0xba50a141bc33e6152c8cbb995d0558dd96c372b5df54eb37677234c9eea435ca"},{"fromBlock":729251,"toBlock":6467006,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000004cd6c9069cd0e8d23e6560a9b9ea10e296dca86e"],["0x000000000000000000000000680b102a587a0ee4495b3013a708aa23b8c684e1"]],"resultHash":"0x29d2ad54bee7ad71976cc75d24dafde9f222cab5470066b830a4d84c4717938c"},{"fromBlock":2601817,"toBlock":7755800,"address":["0xe2b378d9181046c84db1156b0f90cf3108e25e9d"],"topics":[null,null,null],"resultHash":"0x329df5d58922a08e0c3b725b9bd23947a442694295a1e15a8388db7e7487d3e4"},{"fromBlock":492162,"toBlock":5529852,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x00000000000000000000000038dc84830b92d171d7b4c129c813360d6ab8b54e"]],"resultHash":"0x461b31b4027f7b5e5fee16fad5841d0304bcfc96060a1b66f72364472a79229f"},{"fromBlock":448397,"toBlock":7755769,"address":["0x9c556a50fe68a15cda2591da6d451928b46ac8ed"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xcbe3cdb6970d3f3e0a8fb9b166a28fa59d9d3926a808b943ccc142f86b0c6c84"},{"fromBlock":446332,"toBlock":6953276,"address":["0x6ef88a8825753a0f66de42ac51e48956530372eb"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x0000000000000000000000004cd6c9069cd0e8d23e6560a9b9ea10e296dca86e"],null],"resultHash":"0x42a1f0b262c3278ee7499dc2669c93831e0ed027b2c2a10f596988afadd6c77b"},{"fromBlock":1127343,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xfabeb6eee9d30787fdadf82a38cd59de6b1889367b29fd10563cdae8f88e1be8"},{"fromBlock":2781431,"toBlock":7713400,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1780365,"toBlock":7755739,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"]],"resultHash":"0x5b7c44a6534eb053fe041808a63fad020ab4f7c224a14270307209f809a61ec0"},{"fromBlock":1696164,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":695016,"toBlock":6326832,"address":[],"topics":[null,null,["0x0000000000000000000000003a0cafcb6f2a8c3187879cd137c8aaaca74ccaca"]],"resultHash":"0x4eac0ff36c2181b94266b2c7d921de32b31cb780fff5965c63d04fc60ae7ae86"},{"fromBlock":416771,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":2905486,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1466011,"toBlock":7501340,"address":[],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x00000000000000000000000000000000000000000000000000000000000000fa"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x67a049e4e78a0bf3beaf1a4052682273a50972af7f401e29e8ec9cc0c58808e7"},{"fromBlock":544245,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1127343,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":661266,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":2747833,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":678685,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1127343,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":587408,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":0,"toBlock":5750538,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0xac6e0c2854e815f242460671ef73ecf8b6da189bd899782ae6bfcfc2526c0de9"},{"fromBlock":0,"toBlock":7111656,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000089097060177dbd38bb762ef6b94b349d4ce2c423"]],"resultHash":"0x874ea63221cb2940a952cad17eda293b19c8a58519f7dbc2f941cdddf005d694"},{"fromBlock":326616,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1127343,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":2781431,"toBlock":7713400,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":0,"toBlock":7026965,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xac6935f746fe30a2748502d5c2fd57e9bcbf502a5bf05d046f3e9fd45339d7f2"},{"fromBlock":926413,"toBlock":5043576,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xac6935f746fe30a2748502d5c2fd57e9bcbf502a5bf05d046f3e9fd45339d7f2"},{"fromBlock":367339,"toBlock":7755769,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],null],"resultHash":"0x58e5734303c746219710de04c9436843522532cfc9bcea94d5a64b609627f68a"},{"fromBlock":1715035,"toBlock":7445152,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83","0xa06bc650f98c11fbe102bece34df529650a60de6"],"topics":[null,["0x00000000000000000000000079240ea3dba4f6e58a77192c9c24dd57bc79304a"]],"resultHash":"0xfc3066bfa6eed6a35a9eb769c5b13859178b61bdc132e97325dc3575dc1381c8"},{"fromBlock":164489,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],null],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":1883646,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"]],"resultHash":"0xfabeb6eee9d30787fdadf82a38cd59de6b1889367b29fd10563cdae8f88e1be8"},{"fromBlock":996634,"toBlock":7755708,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"]],"resultHash":"0x58e5734303c746219710de04c9436843522532cfc9bcea94d5a64b609627f68a"},{"fromBlock":133116,"toBlock":4681344,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],null,["0x00000000000000000000000038dc84830b92d171d7b4c129c813360d6ab8b54e"]],"resultHash":"0x5a892f6b1e370b21038d792725af88a2db7531e78d31e2e585778a500d492317"},{"fromBlock":0,"toBlock":5522067,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xac6935f746fe30a2748502d5c2fd57e9bcbf502a5bf05d046f3e9fd45339d7f2"},{"fromBlock":0,"toBlock":7322615,"address":["0x8bda81d46a459f0cf67afc69e98d03b7e8bdb325"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x9844384cb2cd1f7041fa5c17ea0b4eca8015fbd83fb59b65b62a40402571be16"},{"fromBlock":2221602,"toBlock":7755769,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000db20ce3fea5b3e6522720dd9dce8bedc9d80cf79"],null],"resultHash":"0xf135ed1738a2bca0d1a84268b6ad95698286264a4055d0d9a65c22c894e8d45b"},{"fromBlock":606393,"toBlock":7755708,"address":[],"topics":[["0xdda5547a2857faf5056d2d09b4cf7d457608f1e1801ca7a1c774d61b6dcc7354"],null,null,["0x0000000000000000000000000a235b06c47bb3fdddfb76ca1a72c9d39b9f794d"]],"resultHash":"0x15ecc8ca1adb166f0241974361d1ce7587b67c44537a15125770eac3155c26d9"},{"fromBlock":414598,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":817880,"toBlock":7755708,"address":[],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":772075,"toBlock":5340530,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0xb95f5c877425205b1b4842dd732850f33a2aace893800e8ef89f6b93a0c38a25"},{"fromBlock":0,"toBlock":7181458,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],null,["0x00000000000000000000000038dc84830b92d171d7b4c129c813360d6ab8b54e"]],"resultHash":"0x5a892f6b1e370b21038d792725af88a2db7531e78d31e2e585778a500d492317"},{"fromBlock":17433,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xdfdaf6783751217b303dddf50c08324b98b2bcc5ad145dd0b6c34293a34c979b"},{"fromBlock":1950992,"toBlock":7755769,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xe41ae498b19bc37605d7b76851107908ff10f1fd3cf508b8c8ca186455428626"},{"fromBlock":0,"toBlock":5364118,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],null,["0x00000000000000000000000038dc84830b92d171d7b4c129c813360d6ab8b54e"]],"resultHash":"0x5a892f6b1e370b21038d792725af88a2db7531e78d31e2e585778a500d492317"},{"fromBlock":501931,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":2280658,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":17433,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xdfdaf6783751217b303dddf50c08324b98b2bcc5ad145dd0b6c34293a34c979b"},{"fromBlock":0,"toBlock":5794696,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"],null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xc8305d94705a3b588f2d7b448459900c8238cb2c43993e7dc55b72e38be685f9"},{"fromBlock":614227,"toBlock":7755769,"address":["0x7abf52a91d3d078960bafc9912fa1be248ef6dcf"],"topics":[null,["0x000000000000000000000000d23ce3b387eb7e80ca658457562c7198f7f83c40"]],"resultHash":"0x0454105e91743a267887113a6a6a2bb3fa3289798d343a47fee337ceeea8032d"},{"fromBlock":138020,"toBlock":7755800,"address":[],"topics":[null,null,["0x00000000000000000000000000000000000000000000000000000000000105c9"]],"resultHash":"0x5a9cb4e8e065dc30748c9d5254d8e54565eebc7b370b68922e5b13f5982cc0de"},{"fromBlock":3320334,"toBlock":7755739,"address":[],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":128029,"toBlock":7755739,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000e7c5196c14c953694599c32975ab3214eec6fe14"]],"resultHash":"0x15a662e554029239015dd014075768011f0dd43c6a3aa4959bb471168ad6153a"},{"fromBlock":164038,"toBlock":7755769,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1466011,"toBlock":7501340,"address":[],"topics":[null,["0x00000000000000000000000000000000000000000000000000000000000000fa"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x3a687a18bf9b48169e6185b5092d97713b08b514d1d003e0602b9720222ab56c"},{"fromBlock":662475,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xdfdaf6783751217b303dddf50c08324b98b2bcc5ad145dd0b6c34293a34c979b"},{"fromBlock":1993626,"toBlock":6861845,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"]],"resultHash":"0xf5b6e6e901d5457a49d487e6badce52aec57a32e563c94831426aa7b8019c82f"},{"fromBlock":1696164,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":0,"toBlock":7184318,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x00000000000000000000000038dc84830b92d171d7b4c129c813360d6ab8b54e"]],"resultHash":"0x461b31b4027f7b5e5fee16fad5841d0304bcfc96060a1b66f72364472a79229f"},{"fromBlock":20085,"toBlock":7755769,"address":[],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x0000000000000000000000000000000000000000000000000000000000000332"]],"resultHash":"0x3d67cfd4dc186efe23b6edfec0d492c0d26633bc3bee9d2f473e9db033335206"},{"fromBlock":662475,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0xdfdaf6783751217b303dddf50c08324b98b2bcc5ad145dd0b6c34293a34c979b"},{"fromBlock":832967,"toBlock":7755708,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1086373,"toBlock":7755739,"address":["0x135fabf0958a9dfb852953911fde610247cbcb20"],"topics":[["0xe5db67eb4a08037e976f0d7ed5cc52986dbf21d36f03bd33ed8cd2ddd793883c"]],"resultHash":"0xf84dfdb9f8a15fd80c17b2712d4fcb83b82636e0b1fd9fe86935d9958265139e"},{"fromBlock":1779995,"toBlock":7755739,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1942656,"toBlock":7755769,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":848368,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":817880,"toBlock":7755708,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":849302,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":606393,"toBlock":7755708,"address":[],"topics":[["0xdda5547a2857faf5056d2d09b4cf7d457608f1e1801ca7a1c774d61b6dcc7354"]],"resultHash":"0x15ecc8ca1adb166f0241974361d1ce7587b67c44537a15125770eac3155c26d9"},{"fromBlock":0,"toBlock":7276691,"address":["0xb647735a3dcd086d5e7adc1c8f1f4733f5b46a5a"],"topics":[null,null,["0x0000000000000000000000003d52b839a410fc977e73b98f36d1a40102e1ab79"]],"resultHash":"0x97c3c5a3076c3d397b0ff147366d44930ba7b3d7a157daf88bc393a027421ae1"},{"fromBlock":2042759,"toBlock":6241556,"address":["0xb0446f6b31376491690c6b4e2e2a24ed13486ea3"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0xd86ac73ba9d23d82cfff644cb1b1b8ec643b3c1057e1227a546a2c16320d5ed8"},{"fromBlock":550373,"toBlock":7755769,"address":["0x930fc4c47f34855bcad8bb4ea03b5c7c2a1d1120"],"topics":[["0xdda5547a2857faf5056d2d09b4cf7d457608f1e1801ca7a1c774d61b6dcc7354"],null,["0x7acb8ce1efb4b1ed3a0ccdba4b1a589601eb79e2605529404e8cf863e9ec84c0"],["0x0000000000000000000000000a235b06c47bb3fdddfb76ca1a72c9d39b9f794d"]],"resultHash":"0x92fc25426163ca5ba2f484b1cd4a542a133393b0ba41af3238dee9747718c9f0"},{"fromBlock":17855,"toBlock":7755769,"address":["0x135fabf0958a9dfb852953911fde610247cbcb20"],"topics":[["0xe5db67eb4a08037e976f0d7ed5cc52986dbf21d36f03bd33ed8cd2ddd793883c"]],"resultHash":"0xf84dfdb9f8a15fd80c17b2712d4fcb83b82636e0b1fd9fe86935d9958265139e"},{"fromBlock":833592,"toBlock":7755769,"address":["0x135fabf0958a9dfb852953911fde610247cbcb20"],"topics":[["0xe5db67eb4a08037e976f0d7ed5cc52986dbf21d36f03bd33ed8cd2ddd793883c"]],"resultHash":"0xf84dfdb9f8a15fd80c17b2712d4fcb83b82636e0b1fd9fe86935d9958265139e"},{"fromBlock":2988033,"toBlock":7755708,"address":null,"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],null],"resultHash":"0x9902e8bdcb3af765d6e417eb3805b7340be2b1cf6679b9d9c6a0746ae55214cf"},{"fromBlock":1780365,"toBlock":7755739,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":0,"toBlock":5391887,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"],null,["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0xac6e0c2854e815f242460671ef73ecf8b6da189bd899782ae6bfcfc2526c0de9"},{"fromBlock":250558,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"},{"fromBlock":1636471,"toBlock":5948881,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],null,["0x000000000000000000000000000000000000000000000000000000000000225a"]],"resultHash":"0x89814e2659b557f4214dce3af5de14ca686d16f50028b8754da8a3bbe8563541"},{"fromBlock":1293701,"toBlock":7755739,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83","0xa06bc650f98c11fbe102bece34df529650a60de6"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000f6b37bbad2b741cb163f629bbd7a5d4f9f19c879"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x01f2b378623819b70498f2f865b9deee9a768438bacb877a4cc5450dd360321c"},{"fromBlock":544245,"toBlock":7755708,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":249911,"toBlock":6196974,"address":[],"topics":[["0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x158476f75ce4fe845fe4ba0a135088e7551c28e9ef8126a6213881c8e8772f99"},{"fromBlock":2781431,"toBlock":7713400,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":4980899,"toBlock":7755800,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000001a3f"]],"resultHash":"0x8e843e01c110105c41c376c4778bc7f6dc4fbf9887152c0735ee4c9074082556"},{"fromBlock":496081,"toBlock":7755769,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x8548e56e79bdc81da6aa2a20817e7353b8ce42f2aae709172dffb7c986cfb484"},{"fromBlock":1791934,"toBlock":7512130,"address":[],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x49f183b418a2fecabc21aef3e9f064ccf60836af4529b0b759c1fba51db639ea"}],[{"fromBlock":5312537,"toBlock":5827968,"address":[],"topics":[null,["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"]],"resultHash":"0x512b774502b5f5482c5a4112ff7059dd068ecdb6ca925929d5ba30ad1da13e91"},{"fromBlock":2814160,"toBlock":3146808,"address":[],"topics":[null,null,["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x829bd5a72848481785e590b40c4d9942e43a3bca2a6839634febe0ad80e42668"},{"fromBlock":2602758,"toBlock":3639658,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x1ce24648687221d81dcdfd73b61d3d9765ba81ed7aa20b4ec48af402511df3b1"},{"fromBlock":6249387,"toBlock":7572741,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x82c07c8ba9db822f89888187aa77ebb6bc0f458603a1a0889f69d0b6ba2425e3"},{"fromBlock":1609490,"toBlock":4309586,"address":[],"topics":[null,["0x000000000000000000000000000000000000000000000000000000000000032a"]],"resultHash":"0x0236d29bfe35ef96c87b0f78fd12331ee4072ae7774c79a7e86ea2e8501bc3d4"},{"fromBlock":2609181,"toBlock":3180325,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000c98fa5773deac2ee02d51f5ae678bdb26608c499"]],"resultHash":"0x1ce24648687221d81dcdfd73b61d3d9765ba81ed7aa20b4ec48af402511df3b1"},{"fromBlock":7088312,"toBlock":7724095,"address":[],"topics":[null,["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":7007774,"toBlock":7753907,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[null,["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":7007774,"toBlock":7753907,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[null,["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6288866,"toBlock":7545898,"address":["0x33f60714bbd74d62b66d79213c348614de51901c"],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x57f6ae6de8922a24c471a9323c67b34c88a6eb3895aacca296e3823ba87bc83b"},{"fromBlock":7003590,"toBlock":7745276,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":7007774,"toBlock":7753907,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[null,["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[null,null,["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x79f2c3aec1cba39b6e975aa6df6e8e5b61e8f4d32f9e18ce51fece21b9f6c79e"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":7007774,"toBlock":7753907,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":5481907,"toBlock":7562617,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x540871ae7be1e484c15908a60ca094dd3c2463bfde440081fb5cd14c07221682"},{"fromBlock":6262795,"toBlock":7547523,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x09835d4f17eb08b7dc2ea514f5fdae1b87a50a5dac623c487c001bc465eb4aae"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[null,["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6961788,"toBlock":7736024,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":7088312,"toBlock":7724095,"address":[],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6777939,"toBlock":7156548,"address":[],"topics":[null,["0x00000000000000000000000084a1488afeb5cbec88d000f5c7d6114779e1e2e9"]],"resultHash":"0x67ec0ae2292cd5462991438f3380f66276d09f5d40c866d9d884c6187056d204"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":7045424,"toBlock":7734387,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":6997534,"toBlock":7755739,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":6271143,"toBlock":7547138,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x09835d4f17eb08b7dc2ea514f5fdae1b87a50a5dac623c487c001bc465eb4aae"},{"fromBlock":6271143,"toBlock":7547138,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x09835d4f17eb08b7dc2ea514f5fdae1b87a50a5dac623c487c001bc465eb4aae"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":4618359,"toBlock":7017022,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],null,["0x0000000000000000000000000000000000000000000000000000000000002c9f"]],"resultHash":"0xa437f498df73e39b6ad475a4341357f1d21ce1c65e05cd3caa38cb52fe0f126c"},{"fromBlock":6967215,"toBlock":7744682,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6591206,"toBlock":7240258,"address":[],"topics":[null,null,["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0xc369d523c9726cf2cd02a5a00526124cb42edc86c7673814f5383bc594e36a6f"},{"fromBlock":7088312,"toBlock":7724095,"address":[],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":6271143,"toBlock":7547138,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x09835d4f17eb08b7dc2ea514f5fdae1b87a50a5dac623c487c001bc465eb4aae"},{"fromBlock":2601170,"toBlock":3157422,"address":["0xf9b7e9bb840b7bbf7e0c42724f11121d4d1efc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0xe93646bf112af5886a5a39817c0448543a840a747093e1ac5c1f44069dfa4779"},{"fromBlock":7007774,"toBlock":7753907,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x095905c2b4f8d2cb2445457ab00acec6441f24d11c79c3ee56cc527e99eaedd2"},{"fromBlock":6288866,"toBlock":7545898,"address":[],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],null,["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x57f6ae6de8922a24c471a9323c67b34c88a6eb3895aacca296e3823ba87bc83b"},{"fromBlock":5317487,"toBlock":7571528,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x82c07c8ba9db822f89888187aa77ebb6bc0f458603a1a0889f69d0b6ba2425e3"},{"fromBlock":6262795,"toBlock":7547523,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x09835d4f17eb08b7dc2ea514f5fdae1b87a50a5dac623c487c001bc465eb4aae"},{"fromBlock":6070683,"toBlock":7152086,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000006b29975137d7de522bf6c4615051370c55820b3e"]],"resultHash":"0x1642a42cf8646d6f1d301101e75defd33f21b9c9721109e61d4c5079aea98b36"},{"fromBlock":5317487,"toBlock":7571528,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x82c07c8ba9db822f89888187aa77ebb6bc0f458603a1a0889f69d0b6ba2425e3"},{"fromBlock":7088312,"toBlock":7724095,"address":[],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6591206,"toBlock":7240258,"address":[],"topics":[null,["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x23f9cb1ebc0071c07cf0f485ac049db3f91f8b49119e0af5663ba6ed244a409e"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":7088312,"toBlock":7724095,"address":[],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6288866,"toBlock":7545898,"address":[],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x57f6ae6de8922a24c471a9323c67b34c88a6eb3895aacca296e3823ba87bc83b"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":5521951,"toBlock":6901427,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],null,["0x0000000000000000000000000000000000000000000000000000000000001c7a"]],"resultHash":"0x9614ae2f5edce85b27374af6642e18af382449905c196b2bca7912bf60de7c19"},{"fromBlock":6591206,"toBlock":7240258,"address":["0x33f60714bbd74d62b66d79213c348614de51901c"],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0xb7c86d62d535f921c13d4ba1282b10f2827d2b52c1826561cef8648b1d711946"},{"fromBlock":2388625,"toBlock":3265789,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null,["0x00000000000000000000000000000000000000000000000000000000000004af"]],"resultHash":"0x65e32f4345324c727c4f565b3e68bd3d19997b11fede56ab922e87a836a5a366"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":6216314,"toBlock":7559852,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x7d9469656704beea628f676ddc56f6bb9eb92f059225c324f486ce5fee9176e7"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":7088312,"toBlock":7724095,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x6623e6dc452e7da9bca7da555aa3b30caa6210d6928c1a4b06e2bcb6bbf797d5"},{"fromBlock":6111257,"toBlock":7579987,"address":["0x33f60714bbd74d62b66d79213c348614de51901c"],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x933650b8af15176adc5f8570984ba5b098ec1bd8165068c5bc4b88ef048efd54"},{"fromBlock":6278555,"toBlock":7543950,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":945904,"toBlock":3044662,"address":[],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000000000000000000000000000000000000000000004"]],"resultHash":"0xbcceed6fd4c7e7bf182819adf6e75f1edd9c34c233ccc639d368011524d0b971"},{"fromBlock":2568917,"toBlock":3421829,"address":[],"topics":[null,null,null,["0x00000000000000000000000000000000000000000000000000000000000004a3"]],"resultHash":"0x64d23dc06f41178ef5c3a56191aa38efcbaac2929577ce3415de12e55aaddcc2"},{"fromBlock":6288866,"toBlock":7545898,"address":[],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x57f6ae6de8922a24c471a9323c67b34c88a6eb3895aacca296e3823ba87bc83b"},{"fromBlock":5577293,"toBlock":7349259,"address":[],"topics":[["0x35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x1794cbd4b4830536584c5302ec4a01592d5951a0f2f16f12b5b9192612bd4777"},{"fromBlock":5628636,"toBlock":7587447,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0xf3d4c4a5f067bb0c2cd9ae744ef801f4d9b99001d81117c1757e6caf570513d8"},{"fromBlock":6591206,"toBlock":7240258,"address":[],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0xb7c86d62d535f921c13d4ba1282b10f2827d2b52c1826561cef8648b1d711946"},{"fromBlock":5657074,"toBlock":7553882,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x7797b365483656866c38871582f9365e387f0acad4852057e10cc062a2475813"},{"fromBlock":7244870,"toBlock":7755769,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000011"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x7539546c3abbda4ed315bdd6e72c6ef5b09782094689c70d3b580a528269541d"},{"fromBlock":7086805,"toBlock":7724757,"address":["0x9f78a25cd8a8211937ea2756aa66f57c836fd6b7"],"topics":[["0xda53325387d61a6b685c31632cef66c5f3e88c3a0f1c2730ef68fb2d039d3e9d"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17"]],"resultHash":"0x5ea69c3ebae57efe1d3ebfefc019182db58c3b08c37e73ef4e96b6ab666d5db9"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":6164416,"toBlock":7561065,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x540871ae7be1e484c15908a60ca094dd3c2463bfde440081fb5cd14c07221682"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":6233478,"toBlock":7560039,"address":[],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],null,["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x0ce07d46f5b30864edd1e6839bb483bc8ac27219c3066c0e5d4dc48690619aaf"},{"fromBlock":6150609,"toBlock":7492130,"address":[],"topics":[["0x35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0xe57283bc7deeac32d90cb7c49406d048ef82e70a2f900f0bd5f0028ed1db628a"},{"fromBlock":6350158,"toBlock":7475163,"address":["0x33f60714bbd74d62b66d79213c348614de51901c"],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x25c01158e8b91a7352afe51bb3f7866d5e2aa5cf8a470ae5b3966fa05fcffe99"},{"fromBlock":6288866,"toBlock":7545898,"address":["0x33f60714bbd74d62b66d79213c348614de51901c"],"topics":[["0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"],["0x0000000000000000000000004230c9e7171615d144251c1a0e6bf9d71c4ac54a"]],"resultHash":"0x57f6ae6de8922a24c471a9323c67b34c88a6eb3895aacca296e3823ba87bc83b"},{"fromBlock":6216314,"toBlock":7559852,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x7d9469656704beea628f676ddc56f6bb9eb92f059225c324f486ce5fee9176e7"},{"fromBlock":6262795,"toBlock":7547523,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x09835d4f17eb08b7dc2ea514f5fdae1b87a50a5dac623c487c001bc465eb4aae"},{"fromBlock":6252717,"toBlock":7580222,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0xe0342db5e4aff7a34a2cbf46dfd7e990cab796d207ec21699d062d91ce41e97b"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"},{"fromBlock":2360036,"toBlock":2536055,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[null,["0x0000000000000000000000006e2c879382520c7b15927902eef1c0fbc1f8de91"]],"resultHash":"0x13fc176aca1738f4944b4863defd65fedad077a486c108990f2c9f3408546073"},{"fromBlock":6216314,"toBlock":7559852,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x7d9469656704beea628f676ddc56f6bb9eb92f059225c324f486ce5fee9176e7"},{"fromBlock":5580431,"toBlock":7467968,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],null,["0x000000000000000000000000000000000000000000000000000000000000358b"]],"resultHash":"0xd505866110147d608b27a13dfc3131f96838347e029ae139b2bc772a59db761a"},{"fromBlock":3136083,"toBlock":4460931,"address":[],"topics":[null,null,["0x000000000000000000000000000000000000000000000000000000000000014e"]],"resultHash":"0xddfb3fb80ad18c70a042434be3bb7343ccc792e6d22b6de8f3d7b4d54d494af4"},{"fromBlock":5317487,"toBlock":7571528,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x82c07c8ba9db822f89888187aa77ebb6bc0f458603a1a0889f69d0b6ba2425e3"},{"fromBlock":6278555,"toBlock":7543950,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a"]],"resultHash":"0x3631b12dc0ea2718a4369c199d258baf83d8638cd2c3d21edf1086a1a4af159d"}],[{"fromBlock":5462278,"toBlock":5521715,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x9f627460e509ff66bc62825b46a8ef30cf3bee0cb32a4f94ab1803995b6b0c23"},{"fromBlock":5462278,"toBlock":5521715,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x9f627460e509ff66bc62825b46a8ef30cf3bee0cb32a4f94ab1803995b6b0c23"},{"fromBlock":5462278,"toBlock":5521715,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x9f627460e509ff66bc62825b46a8ef30cf3bee0cb32a4f94ab1803995b6b0c23"},{"fromBlock":7400338,"toBlock":7573531,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000010"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x32502b9fe1cd4cbc7831f54bead8899793bb64833946acfdd69e40e722ade2f5"},{"fromBlock":5460621,"toBlock":5523843,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xf7ad4dd50224b023340d9576dcfa18c9a2558702b00f190dada31d76037c5b6c"},{"fromBlock":5462278,"toBlock":5521715,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x9f627460e509ff66bc62825b46a8ef30cf3bee0cb32a4f94ab1803995b6b0c23"},{"fromBlock":2346203,"toBlock":2450447,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[],"resultHash":"0xaf3eb7a9b5aa96d848f2d32cfb6877119cd968097c3ce4f3869ef9447b9a8056"},{"fromBlock":5462278,"toBlock":5521715,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x9f627460e509ff66bc62825b46a8ef30cf3bee0cb32a4f94ab1803995b6b0c23"},{"fromBlock":2346203,"toBlock":2450447,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[["0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"]],"resultHash":"0x67578e8c26d27184f314c76b81139d12c37646a9a584a5574f501a61b04f542c"},{"fromBlock":4500308,"toBlock":4557601,"address":[],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x0000000000000000000000007217fbb1337462be420b271cd77f213a20354e33"]],"resultHash":"0x0c919b7ca9aaf46e00c122d30082dffe8b4e81ddd60992ea8f114b18a4ce7dd3"},{"fromBlock":4473769,"toBlock":4567107,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x0000000000000000000000007217fbb1337462be420b271cd77f213a20354e33"]],"resultHash":"0x7a2eb8f395900c085dffa299e81fb192361de91433ad992e88ae0606b92e3654"},{"fromBlock":4462978,"toBlock":4562463,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x0000000000000000000000007217fbb1337462be420b271cd77f213a20354e33"]],"resultHash":"0x3bd5572fe5858140811cb60736169c55d76ec65946d175dedcaafe8f62609874"},{"fromBlock":5462278,"toBlock":5521715,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x9f627460e509ff66bc62825b46a8ef30cf3bee0cb32a4f94ab1803995b6b0c23"},{"fromBlock":7401694,"toBlock":7531232,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000017"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xb0fb7baf653a07a22307629a52bf677342311704af815d443744da4d83e58243"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,null,["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":5462278,"toBlock":5521715,"address":["0x719e22e3d4b690e5d96ccb40619180b5427f14ae"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x9f627460e509ff66bc62825b46a8ef30cf3bee0cb32a4f94ab1803995b6b0c23"},{"fromBlock":7424911,"toBlock":7506285,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0x1d9f30260051d51d70339da239ea7b080021adcaabfa71c9b0ea339a20cf9a25"],["0x0000000000000000000000000000000000000000000000000000000000000015"]],"resultHash":"0xb932798e018fc44daa77b158ecc793b6b3088bdd8565c049044cc8608a394049"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":5402883,"toBlock":5563969,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xf0acf909b2f222d6665c5f38d5e1601db7ad49e18b3112733f38700a9109c63e"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":6234966,"toBlock":6286957,"address":[],"topics":[["0xbaa1d762384057169afd12b625998a5a7ed502c2e229acdbead30f3f6496399d"]],"resultHash":"0x9b16b111c2e538988e7e6e05aee62589bab50d1577ad8e14d50b24ab0f513501"},{"fromBlock":2852708,"toBlock":2904307,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0xcb594379bee7a4135be6e90141b4358269984f0c8b1bd13ee8c5335cfde0dba3"},{"fromBlock":5435576,"toBlock":5546944,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[null,["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x41944cb8bbb11b90fca664d28a289b0ab67a36d1131aac905100f71bf7351bdf"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":2852708,"toBlock":2904307,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0xcb594379bee7a4135be6e90141b4358269984f0c8b1bd13ee8c5335cfde0dba3"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":2407874,"toBlock":2543976,"address":["0x85edb7a0cbacf5bd641e0ff5d6270bef9c72bd6b"],"topics":[null,null,["0x000000000000000000000000855aa5fac685841c96f6d5ce103bf4a7122b016c"]],"resultHash":"0x632dd0a604e9b7e9df1f5e2c7b35c8cd9c443397bbb2c012e11645d699ec360b"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":2852708,"toBlock":2904307,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0xcb594379bee7a4135be6e90141b4358269984f0c8b1bd13ee8c5335cfde0dba3"},{"fromBlock":7400338,"toBlock":7573531,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000010"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x32502b9fe1cd4cbc7831f54bead8899793bb64833946acfdd69e40e722ade2f5"},{"fromBlock":7412101,"toBlock":7528561,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000017"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xb866a6a0e2e61faed988e0bd43c72660555c08b927c684f2c415d2b01ed7cc46"},{"fromBlock":7407413,"toBlock":7530398,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000017"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x3a467beb063319f3a6309852cf2df5ae6d6303879f4bea2a74a31e7895a38958"},{"fromBlock":4391681,"toBlock":4445784,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],null,["0x000000000000000000000000d1292d09173fc26cb82ddcc047d5d19f7369d56e"]],"resultHash":"0x99ac7ca7a080e32bb806e2778fae4c40458c9523cfbcc8d25a5fa230a2437413"},{"fromBlock":5441762,"toBlock":5552695,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xc2b1447ad80162863aa6a584140ab6fa56ba968b5d567dc3a3ce862edc94c9c2"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":2852708,"toBlock":2904307,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0xcb594379bee7a4135be6e90141b4358269984f0c8b1bd13ee8c5335cfde0dba3"},{"fromBlock":4458486,"toBlock":4559611,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x0000000000000000000000007217fbb1337462be420b271cd77f213a20354e33"]],"resultHash":"0xd97269108aadeec8bcd20720e1dd328892b321e0a88345361665425ca0f414d2"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":3385764,"toBlock":3457017,"address":[],"topics":[null,null,["0x00000000000000000000000026baac08cb753303de111e904e19baf91e6b5e4d"]],"resultHash":"0xeef5ce5159987dac87fbbc44717189b14e547be463018b77b715e10ab7b59e43"},{"fromBlock":3456545,"toBlock":3701349,"address":[],"topics":[null,null,null,["0x0000000000000000000000000000000000000000000000000000000000000364"]],"resultHash":"0xc85f1ef7e4e86e56112b84a0257ef39ff6d93efd65114cb3cfea4d0ab0f547f3"},{"fromBlock":2320120,"toBlock":2382408,"address":["0xe72c66da780842bd8815d7616dc1f7e5b6b104b9"],"topics":[null,null,["0x00000000000000000000000072b9c3c2847e0c09776c071b2610dec9521c54d6"]],"resultHash":"0x2afb01863b7152217e7854fa3b57ebe2bd51dbf11452b5ab2875e202a0575698"},{"fromBlock":4391681,"toBlock":4445784,"address":["0xd4eaf2a5da8c51a30c245ad71a0b93f39fa1ec53"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],null,["0x000000000000000000000000d1292d09173fc26cb82ddcc047d5d19f7369d56e"]],"resultHash":"0x99ac7ca7a080e32bb806e2778fae4c40458c9523cfbcc8d25a5fa230a2437413"},{"fromBlock":7398809,"toBlock":7485698,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0x1d9f30260051d51d70339da239ea7b080021adcaabfa71c9b0ea339a20cf9a25"],["0x0000000000000000000000000000000000000000000000000000000000000015"]],"resultHash":"0x1dde9a7da4c58f19024a86f7e007208b87e455fff29fcf95098fe465e7d45543"},{"fromBlock":2346203,"toBlock":2450447,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[["0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"]],"resultHash":"0x67578e8c26d27184f314c76b81139d12c37646a9a584a5574f501a61b04f542c"},{"fromBlock":7412101,"toBlock":7528561,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000017"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xb866a6a0e2e61faed988e0bd43c72660555c08b927c684f2c415d2b01ed7cc46"},{"fromBlock":4458569,"toBlock":4531620,"address":[],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x00000000000000000000000045da549856896a4f2ceb02d7512c8dc41a6f0a86"]],"resultHash":"0x795ffd862a08112e31f7e9e51575fd2d79f85360c7f85290eb2e87412f2aca7f"},{"fromBlock":7400338,"toBlock":7573531,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000010"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x32502b9fe1cd4cbc7831f54bead8899793bb64833946acfdd69e40e722ade2f5"},{"fromBlock":2375233,"toBlock":2526190,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999"],"topics":[],"resultHash":"0x75fa85e6a0860afd93385e1d5e30c61948a6fc6f047a9b8201a4be5242e44109"},{"fromBlock":4385662,"toBlock":4447501,"address":["0xd4eaf2a5da8c51a30c245ad71a0b93f39fa1ec53"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],null,["0x000000000000000000000000d1292d09173fc26cb82ddcc047d5d19f7369d56e"]],"resultHash":"0xa91eb9fed34f3f65996df6f1019cb9f134d521d370645bf5fa21fda6c1944bb0"},{"fromBlock":7405793,"toBlock":7485690,"address":["0xa06bc650f98c11fbe102bece34df529650a60de6"],"topics":[null,null,["0x00000000000000000000000089009d02e4da2eaa8c1553bc8ecc2fce27cc97cd"]],"resultHash":"0x7a2b37313beae18153b4362d3985ec9af77471c7808f89dd556a4dfe357a170f"},{"fromBlock":4500308,"toBlock":4557601,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x0000000000000000000000007217fbb1337462be420b271cd77f213a20354e33"]],"resultHash":"0x0c919b7ca9aaf46e00c122d30082dffe8b4e81ddd60992ea8f114b18a4ce7dd3"},{"fromBlock":6234966,"toBlock":6286957,"address":["0x9dcc53737fcb3e86a17cf435ca3c15390d4fc7ed"],"topics":[["0xbaa1d762384057169afd12b625998a5a7ed502c2e229acdbead30f3f6496399d"]],"resultHash":"0x9b16b111c2e538988e7e6e05aee62589bab50d1577ad8e14d50b24ab0f513501"},{"fromBlock":1871348,"toBlock":1968246,"address":["0x708d0ec21e1639fd70f4316474ad21a84c9540fc"],"topics":[["0x1b205f71b08271339a2b02ceaf7d8533d96f8cf7ddc94948c274c49565497f34"]],"resultHash":"0x7526ec0fc980f7a71a486e9e3a2f88f77df3793e64c71e3ca40cf7c40521a788"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":7412101,"toBlock":7528561,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000017"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xb866a6a0e2e61faed988e0bd43c72660555c08b927c684f2c415d2b01ed7cc46"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":7403222,"toBlock":7520095,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000015"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x6603c84b17286e4642b4d34df969732b8807e223dcd24adcab7865a25ac75101"},{"fromBlock":4481230,"toBlock":4566120,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x0000000000000000000000007217fbb1337462be420b271cd77f213a20354e33"]],"resultHash":"0x95b720070c44e878de527d3f6cd51be631f4bd866a05a06f438c1917174db077"},{"fromBlock":6556416,"toBlock":6791440,"address":[],"topics":[null,null,["0x000000000000000000000000f984be01f03d2866b2ef96ec95aa865304aacc8c"]],"resultHash":"0x165259c3a8ec7bf80d8e94d577c681d137f614ae431e13f28de9d8344e5e1753"},{"fromBlock":5402883,"toBlock":5563969,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xf0acf909b2f222d6665c5f38d5e1601db7ad49e18b3112733f38700a9109c63e"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":3281755,"toBlock":3357452,"address":["0x7afc4f6c9677d42f36ac11225ce612140a5bc968"],"topics":[],"resultHash":"0x83ef99164dfff81cc06a33b183516ee6b0d18f862f5d899506b103ec3f380be2"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":2852708,"toBlock":2904307,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0xcb594379bee7a4135be6e90141b4358269984f0c8b1bd13ee8c5335cfde0dba3"},{"fromBlock":6125361,"toBlock":6437424,"address":[],"topics":[["0x00d05ab44e279ac59e855cb75dc2ae23b200ad994797b6f1f028f96a46ecce02"],null,["0x00000000000000000000000000000000000000000000000000007ac8230b7000"]],"resultHash":"0xe1ed78400266a71f700832a1ea5dd3b8280e0badd986633cdb5c84f61a67f230"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":3375304,"toBlock":3504687,"address":["0x5c7a6cf20cbd3eef32e19b9cad4eca17c432a794"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0x5bd7b2cb2a274f35c85795cd6d80cd18f42dc5cf09ca9e01359600814e40c507"},{"fromBlock":3403868,"toBlock":3433558,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,null,["0x0000000000000000000000000000000000000000000000000000000000000001"]],"resultHash":"0xbe82c5b4dcea0770f02a448d4e85cdbf24c9b8ef636ba92039dc959c58a17e14"},{"fromBlock":7412101,"toBlock":7528561,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000017"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xb866a6a0e2e61faed988e0bd43c72660555c08b927c684f2c415d2b01ed7cc46"},{"fromBlock":7414222,"toBlock":7498447,"address":["0xa06bc650f98c11fbe102bece34df529650a60de6"],"topics":[null,["0x000000000000000000000000b224f94546e61638241211a3e6ebb75b6664fc42"]],"resultHash":"0xae8e2b5d653d7121de28245b6b83c35a322a43e18afd0737d042ad7a7d2e772b"},{"fromBlock":2861852,"toBlock":2908608,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"]],"resultHash":"0x79ccd42eb26f5919a1689cb2be2e3266ffb59e6d12071a04f8424e0a8110173c"},{"fromBlock":3282677,"toBlock":3602558,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000026baac08cb753303de111e904e19baf91e6b5e4d"]],"resultHash":"0x86dae19fc52506ccb98084c0ccb077e16af7e3ae04c5b45e2a4cb02d9bd3b0ae"},{"fromBlock":7412101,"toBlock":7528561,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000017"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xb866a6a0e2e61faed988e0bd43c72660555c08b927c684f2c415d2b01ed7cc46"},{"fromBlock":1862387,"toBlock":2013963,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null,["0x0000000000000000000000000000000000000000000000000000000000000001"]],"resultHash":"0x07db5401bd4dd3dc7b0d6f0464e5fd1daa64c46ee4c45557aee729decf928ae2"},{"fromBlock":5402883,"toBlock":5563969,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xf0acf909b2f222d6665c5f38d5e1601db7ad49e18b3112733f38700a9109c63e"},{"fromBlock":5482148,"toBlock":5538088,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[null,["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xa68b2e94fd56c4e7225825007873c721a6f66eeee4e1c171df9bee91a15f70c3"},{"fromBlock":4482416,"toBlock":4521277,"address":[],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x000000000000000000000000b1927224f07b070ae2e52fc03c8dab39f345ea89"]],"resultHash":"0xb177e29ed9be101f97c893f44db939742e8bcfa71cb56c6f4cb4dbabb8e54c29"},{"fromBlock":7418359,"toBlock":7527299,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0x1d9f30260051d51d70339da239ea7b080021adcaabfa71c9b0ea339a20cf9a25"],["0x0000000000000000000000000000000000000000000000000000000000000015"]],"resultHash":"0x0e728b804db3f558b14f2658caa2e738fd090b3fab6b2feb5e8d526e67498779"},{"fromBlock":6234966,"toBlock":6286957,"address":["0x9dcc53737fcb3e86a17cf435ca3c15390d4fc7ed"],"topics":[["0xbaa1d762384057169afd12b625998a5a7ed502c2e229acdbead30f3f6496399d"]],"resultHash":"0x9b16b111c2e538988e7e6e05aee62589bab50d1577ad8e14d50b24ab0f513501"},{"fromBlock":6191947,"toBlock":6247160,"address":[],"topics":[["0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"],null,["0x000000000000000000000000c7b98f0a54849b8ff5d45fd97988581da37d167f"]],"resultHash":"0x14c9276fcde8626957e6ebb0a6d19469ee02d10a13b47d55181ebdfd43384870"},{"fromBlock":7402844,"toBlock":7567043,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000013"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x83d06f80db07f05a16e09b843e20497ace2a69f81b3c008b92fc424750dd4e82"},{"fromBlock":7416848,"toBlock":7491327,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000010"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x6481428cd13cdc8947047174eae9b1ee45729b3bb108a50e9b2884ed842a0393"},{"fromBlock":7411206,"toBlock":7498874,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000015"]],"resultHash":"0x84cf9f2d57e97436df8ecd075eabe3384ef512541015fe036a5960bcb0de8d7c"},{"fromBlock":2853102,"toBlock":2903629,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"],["0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0x0398749d0d8ffa626f970d8ef589cc6295b227b728d80641b09ee9d269003f41"},{"fromBlock":2839477,"toBlock":2900104,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"]],"resultHash":"0xd1dfa2efdd8ac1b42eae75fa2566f47e9b22257e0f0a20be30668bf70de77a48"},{"fromBlock":7398298,"toBlock":7505084,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000017"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x56780f5f764fdf19693368b234645fa29f9576f0366dcd6b4863fe9fd61337fa"},{"fromBlock":7421806,"toBlock":7488067,"address":["0xa06bc650f98c11fbe102bece34df529650a60de6"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000089009d02e4da2eaa8c1553bc8ecc2fce27cc97cd"]],"resultHash":"0x1ddb944c089bf1de55c71e33b5d80a29770ef4b082998fbe1ae52d86649305b0"},{"fromBlock":7406849,"toBlock":7477439,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],null,["0x0000000000000000000000007bcc97d1f73b023734187299fc9ea0915294c050"]],"resultHash":"0xae31d89b587fef4fee5fb7df9142ee69e41df20f38ad5913b95dd207a43ab62f"},{"fromBlock":5483649,"toBlock":5535687,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[null,["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xa75498e7efe7d98df5217f5aff858e54c8c28c6c3ee1e1cc69b4a20baa5be810"},{"fromBlock":7411112,"toBlock":7501401,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000016"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x5d55946325b61453931e871b5950eb0cd634dc08856055b897bc0d3f6c2bfe30"},{"fromBlock":1882401,"toBlock":1955972,"address":["0x708d0ec21e1639fd70f4316474ad21a84c9540fc"],"topics":[["0x1b205f71b08271339a2b02ceaf7d8533d96f8cf7ddc94948c274c49565497f34"]],"resultHash":"0x79ffc1360277e46e806f511226de6b7cd5425c93ceeb0a56a93923b671ccc8de"},{"fromBlock":7406536,"toBlock":7524130,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000015"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x225e2c7281787c68343812c3a5ec66b47edacf6d474df1952093adc3bd77f765"},{"fromBlock":7401931,"toBlock":7638124,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000010"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x7a8d27e8293c5ee889ea70ca28b5b2e7d1a7683ca8a994ba6e4d1a77e2f0ebe3"},{"fromBlock":3283310,"toBlock":3527939,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000026baac08cb753303de111e904e19baf91e6b5e4d"]],"resultHash":"0x86dae19fc52506ccb98084c0ccb077e16af7e3ae04c5b45e2a4cb02d9bd3b0ae"},{"fromBlock":6837948,"toBlock":7000658,"address":["0x582cc5d9b509391232cd544cdf9da036e55833af"],"topics":[["0xd342ddf7a308dec111745b00315c14b7efb2bdae570a6856e088ed0c65a3576c"]],"resultHash":"0xc30f94d49fd2aa54f43e201b9ba3cd9d306b522618f79d75c3818b4f11a3895d"},{"fromBlock":2859845,"toBlock":2915517,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"]],"resultHash":"0x34c1e5422b2de68e1a1c46651c1afbecede628583b6a50a7f41f0c69ccd85d63"},{"fromBlock":7398779,"toBlock":7484931,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],["0x0000000000000000000000000000000000000000000000000000000000000018"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xb0fdacc23aa45519bd4f3f5de37c3618b16262b89d514dba11c988d3444cd7ed"},{"fromBlock":5429939,"toBlock":5565055,"address":["0x26b0fae932db549c4537fe1b563882583af9e0a5"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000ddc9ffbdb2b24f9e646b1a20fce1f6c78995043d"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xd6df9eafd9291851246cf19652c661cac086c302175ffc01b34facb85767b27f"},{"fromBlock":7393221,"toBlock":7490518,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000018"],["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xe85626a892641ba8f156d7eba18fac95daeb2addb093f48132306546d540d4c6"}],[{"fromBlock":7284472,"toBlock":7315296,"address":["0x666ca6fc75b44f3ff2d321c5947031141409b152"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null],"resultHash":"0x4671ebc2307b53d91681e1f5d59d31709fc81211873b74ab90230d270a3fe11d"},{"fromBlock":2871651,"toBlock":2881283,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"]],"resultHash":"0xeb0ea1a3b6e5f0f6dc79f89f9c9fd0e79d341049957244ba61e6b83e7761f89c"},{"fromBlock":6255572,"toBlock":6276265,"address":["0x26280ec2fa5e4987520e4c84d55b7320f1f3c4ce"],"topics":[["0xb4e1304f97b5093610f51b33ddab6622388422e2dac138b0d32f93dcfbd39edf"],["0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"]],"resultHash":"0xed70e01668fd02978926418e13e49dcc8c13cdd444e2b94ed9e7e617bd16dec6"},{"fromBlock":3411973,"toBlock":3430335,"address":["0xe20cf465a163c395e7dde1466cdd1abe695b4658"],"topics":[null,["0x0000000000000000000000000c4b9f731696bed1b0834f48a7f24e513dc3cfd7"],null],"resultHash":"0x3bb41f553effea092280722d2a49b212cb4ce266f09e4c4a342982f6cc9a3391"},{"fromBlock":5595503,"toBlock":5608828,"address":["0xfdfd239c9dd30445d0e080ecf055a5cc53456a72"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000009337117fe4fde0335a4f7cdbadca0862fe29f668"],["0x00000000000000000000000098cbc1530bfec21f8d10662d769608217364513a"]],"resultHash":"0xff493896d83be90aa3a65755f94a40ab79453e6ed2ddb349468b34995d529aad"},{"fromBlock":2866012,"toBlock":2898386,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xdd985a938683015da8e1f7a53524a49d38eb31154a6ce7c0b94fd739bb0aae1f"},{"fromBlock":6255580,"toBlock":6276252,"address":["0x26280ec2fa5e4987520e4c84d55b7320f1f3c4ce"],"topics":[["0xb4e1304f97b5093610f51b33ddab6622388422e2dac138b0d32f93dcfbd39edf"],["0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"]],"resultHash":"0xed70e01668fd02978926418e13e49dcc8c13cdd444e2b94ed9e7e617bd16dec6"},{"fromBlock":6320202,"toBlock":6340301,"address":[],"topics":[["0x00d05ab44e279ac59e855cb75dc2ae23b200ad994797b6f1f028f96a46ecce02"],null,["0x000000000000000000000000000000000000000000000000000cca2e51310000"]],"resultHash":"0x66e9c6089ae1a135d167eb47238fb4590c468cbbdc8a1d950f466609a4e12936"},{"fromBlock":5767601,"toBlock":5788560,"address":["0xf158908549032149090d59eb86b7b38bd5d15621"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x96e15a8f7598519f6822606610b2f20b212622372c06bd0acbfa628df6857169"},{"fromBlock":2867182,"toBlock":2884938,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"]],"resultHash":"0x3f8459a2730466cef857ed8736a945c2145774da0e563bcdff6ccba16247bb23"},{"fromBlock":6255580,"toBlock":6276252,"address":[],"topics":[null,["0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"]],"resultHash":"0xed70e01668fd02978926418e13e49dcc8c13cdd444e2b94ed9e7e617bd16dec6"},{"fromBlock":2871768,"toBlock":2881746,"address":["0x295c871e10bff8f810043a03a647b7fe9e2dd7ef"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"]],"resultHash":"0xb99a52556ae4af1a37e6ea57fae7543789accde93f72c3aeab1adcbe07fd7585"},{"fromBlock":2871651,"toBlock":2881283,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"]],"resultHash":"0x3ff7f127bfdad0831165c394e4ba67e4dd579d62f7830618b5da8d9f134b7c2e"},{"fromBlock":2545695,"toBlock":2558232,"address":["0x2d5a67ed56afe3f56ff035e3f269bd3b230b108a"],"topics":[],"resultHash":"0x975080c03432147244c5976c39e6b4ecd94dccfa5fa401aa6225f44e900dac0b"},{"fromBlock":4518982,"toBlock":4526318,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x00000000000000000000000083efd3ee9278cc7800e93e7f9a14607f5c331b3e"]],"resultHash":"0xe9efd4465a3ff5e9e857c79a111e7db36be45f7be6d8fcba198088f93ca822bf"},{"fromBlock":2871651,"toBlock":2881283,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"]],"resultHash":"0x3ff7f127bfdad0831165c394e4ba67e4dd579d62f7830618b5da8d9f134b7c2e"},{"fromBlock":2857034,"toBlock":2892294,"address":["0x295c871e10bff8f810043a03a647b7fe9e2dd7ef"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,null,["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0xfec538f56612c5f6a5e147cfaba3687daaca5a7f0d4c2ae623d61293e10d9696"},{"fromBlock":7060981,"toBlock":7080815,"address":[],"topics":[["0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0"],null,["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05","0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x96df148fc6fc0c177524ab68929b0f2a1124e5f8d727bb05cd9141329bb00f42"},{"fromBlock":2874369,"toBlock":2880544,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[],"resultHash":"0xa7037d915a722a03d3277c81d8097fbb7fcfbf2a32b4b7da41963a05611bf291"},{"fromBlock":2867182,"toBlock":2884938,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"]],"resultHash":"0x3f8459a2730466cef857ed8736a945c2145774da0e563bcdff6ccba16247bb23"},{"fromBlock":2545695,"toBlock":2558232,"address":["0x2d5a67ed56afe3f56ff035e3f269bd3b230b108a"],"topics":[["0x11cedc7f83a9a6f5228b8fcd3c3c0ae686a51e2e04ea46923e3491a32a4bbaa8"]],"resultHash":"0x975080c03432147244c5976c39e6b4ecd94dccfa5fa401aa6225f44e900dac0b"},{"fromBlock":2871532,"toBlock":2881494,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"]],"resultHash":"0x7913f167e2bd1437b78bb3107e649962917783da57469af8148341ef3f326778"},{"fromBlock":2871333,"toBlock":2883472,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"]],"resultHash":"0x826375c90b7dd722a1a4ab9d1117acd2fecc0f1ff67e2125ef3619d9796082d7"},{"fromBlock":2865895,"toBlock":2897932,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,null,["0x0000000000000000000000005b942fcd936702a00df9277bae624f8b6da9e2b3"]],"resultHash":"0x7422d194438522f7fd9cfa09746c3740cd2d5aaae0665ff777c4af0e89d9e55a"},{"fromBlock":7448059,"toBlock":7469066,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],null,["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x281c6d712ecdf865375a9be14eae7644e39bdcbebd4aa2ed020abf04d01f3445"},{"fromBlock":2864150,"toBlock":2891299,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0xe06d22f7ca749d47286067c59b2b15dbf03e9e03385d26bd4a826cf1ca208aa5"},{"fromBlock":7284472,"toBlock":7315296,"address":["0x666ca6fc75b44f3ff2d321c5947031141409b152"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x4671ebc2307b53d91681e1f5d59d31709fc81211873b74ab90230d270a3fe11d"},{"fromBlock":6255580,"toBlock":6276252,"address":["0x26280ec2fa5e4987520e4c84d55b7320f1f3c4ce"],"topics":[null,["0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"]],"resultHash":"0xed70e01668fd02978926418e13e49dcc8c13cdd444e2b94ed9e7e617bd16dec6"},{"fromBlock":2867182,"toBlock":2884938,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"]],"resultHash":"0x3f8459a2730466cef857ed8736a945c2145774da0e563bcdff6ccba16247bb23"},{"fromBlock":5772645,"toBlock":5786223,"address":["0x034b7ccf069fe523de04f765fc22356a099a9853"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x791ce784407488b8856f44112a7b356edda92788275a6a0e90a7edb0839ba758"},{"fromBlock":3421821,"toBlock":3426164,"address":["0x5c7a6cf20cbd3eef32e19b9cad4eca17c432a794"],"topics":[null,null,null],"resultHash":"0xaa3d8fec2a6908fda6d1f60055a1c0db2869003728d5f9df66f40444c5a95f0e"},{"fromBlock":7452142,"toBlock":7458903,"address":["0xa06bc650f98c11fbe102bece34df529650a60de6"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x2f9d039fc87f2fffa599117087b74b778af945d324b855a211d626f9191dcffc"},{"fromBlock":2866096,"toBlock":2885370,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"]],"resultHash":"0xbe42c404ae6281fa8cebd817284d41027820c8485f1bc9b86436501d0ddc35c9"},{"fromBlock":4515660,"toBlock":4528755,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[null,null,["0x000000000000000000000000db412c9598c41d72778744d8ee7d028214f00282"]],"resultHash":"0x84e0b361b020e60e45eb4ad1f8119871ecc517ca4b8d88929e50eeca7cc473c0"},{"fromBlock":7451293,"toBlock":7456945,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[],"resultHash":"0x15a76618dbff170841832845ae71d143d16be85fe299362ad56222dc8027fde6"},{"fromBlock":2871090,"toBlock":2884924,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"]],"resultHash":"0xbc933b216df1a3d91169dc5405171f3716c0995b7a260b3717ed4b964471bdf8"},{"fromBlock":2501204,"toBlock":2507597,"address":["0x13e9cc252d1ba1c6a25bf12597bf5dc608689e32"],"topics":[["0xdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae7"]],"resultHash":"0xbe1e24d4f2bef0f4c7a09a7f2a95d6bd50e31ca84d9d7287a8a592f7c1c12c45"},{"fromBlock":5015531,"toBlock":5040888,"address":[],"topics":[["0x435e19089f6ae5362a112155f011980907d2ff69b4c2bb894f8324260650ee6a"]],"resultHash":"0x74f2128b7c84cc2ee59bed973028edbeea259d07e8789b080cac700be9357dbc"},{"fromBlock":6320202,"toBlock":6340301,"address":["0x27f03f2422f0c3715bec8e43bf5bcd178ab406b4"],"topics":[["0x00d05ab44e279ac59e855cb75dc2ae23b200ad994797b6f1f028f96a46ecce02"],null,["0x000000000000000000000000000000000000000000000000000cca2e51310000"]],"resultHash":"0xa83cdf0b0fd2ea77e0097372e19d7c8f857c23351ad6d2a278afe5af24c2d34b"},{"fromBlock":4359240,"toBlock":4366818,"address":["0xb0910e7c7adec52ef3bae5db9d01fd967a22fb7b"],"topics":[],"resultHash":"0x18e60409276bd0e6742aa0dcc04d87735cd64e919c4dd851f34e7f3a14b90223"},{"fromBlock":2545695,"toBlock":2558232,"address":["0x2d5a67ed56afe3f56ff035e3f269bd3b230b108a"],"topics":[["0x11cedc7f83a9a6f5228b8fcd3c3c0ae686a51e2e04ea46923e3491a32a4bbaa8"]],"resultHash":"0x975080c03432147244c5976c39e6b4ecd94dccfa5fa401aa6225f44e900dac0b"},{"fromBlock":4519005,"toBlock":4526285,"address":[],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x00000000000000000000000083efd3ee9278cc7800e93e7f9a14607f5c331b3e"]],"resultHash":"0x1bbd2efde01bf9df0a341cb65496ce44d6f11dff5e4df9fb3e041d7bdcc8c026"},{"fromBlock":4428726,"toBlock":4436405,"address":["0x8737a1c3d55779d03b7a08188e97af87b4110946"],"topics":[["0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],["0x000000000000000000000000000000000000000000000000b8159170038f96fb"]],"resultHash":"0x4b6ae8bdde8dc5547be7bf147b17fc3019d4d03ca4d6f4a17346e25746f47808"},{"fromBlock":5409980,"toBlock":5414794,"address":["0x182ec567f33ac802e9e80c0a0bbe7610d5923e0e"],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"]],"resultHash":"0xe42cf4b3c6cf6ef35ea492559385ce9e928650a0ba1d24fcb62cb907c61f7db8"},{"fromBlock":4519005,"toBlock":4526285,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x00000000000000000000000083efd3ee9278cc7800e93e7f9a14607f5c331b3e"]],"resultHash":"0x1bbd2efde01bf9df0a341cb65496ce44d6f11dff5e4df9fb3e041d7bdcc8c026"},{"fromBlock":7448059,"toBlock":7469066,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],null,["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x281c6d712ecdf865375a9be14eae7644e39bdcbebd4aa2ed020abf04d01f3445"},{"fromBlock":7448059,"toBlock":7469066,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[null,null,["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x281c6d712ecdf865375a9be14eae7644e39bdcbebd4aa2ed020abf04d01f3445"},{"fromBlock":3317369,"toBlock":3329704,"address":[],"topics":[["0x27333edb8bdcd40a0ae944fb121b5e2d62ea782683946654a0f5e607a908d578"],null,["0x0000000000000000000000003367dfa11e3148a07c2da773e1f65b155b0abe56"]],"resultHash":"0xe8133c50deccf421e9ee03e7467ee28573fac1cd24f84216d01a02d23af47a68"},{"fromBlock":4417825,"toBlock":4437464,"address":["0xc86d830fd72e77673c5f58014c530f6242378bc7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000e0ffca70d862314ca067bb03813f52bd9225459"],["0x000000000000000000000000cd48b1739d2f1a72705320a9025d057262bc41de"]],"resultHash":"0xb204b27986191e7c8492a463e396154796f186283d65a8c795655641c876203a"},{"fromBlock":2706902,"toBlock":2722781,"address":[],"topics":[["0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"]],"resultHash":"0xbb445fc14615421c7ad21e3675551a39d6f06fd2bb0b578bb92364dbc6a1aca6"},{"fromBlock":5776890,"toBlock":5783469,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000b8714f0a601b432e37a1e78854492f8e4bd52f75"],null],"resultHash":"0xc0eba7960dca2bdffed2ee981f840e13f2707c7ef94b6b0b22a1d10341027ac3"},{"fromBlock":7452142,"toBlock":7458903,"address":["0xa06bc650f98c11fbe102bece34df529650a60de6"],"topics":[],"resultHash":"0x2b52a74e56d877bac69685dc4f5a203bff1b6506f3de4e51044edaed9ff77445"},{"fromBlock":2863083,"toBlock":2888077,"address":["0x295c871e10bff8f810043a03a647b7fe9e2dd7ef"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0x1303d3652e7e369d13a65e15e8669c3d70bfad431862c435d821a1f66490f079"},{"fromBlock":2867198,"toBlock":2886423,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"]],"resultHash":"0x72501d9c75ef392649698fa19e50d369c56f78864d2ae47543effe816a4a396b"},{"fromBlock":5015531,"toBlock":5040888,"address":["0xd098701586c4fdbbdf6081d2a85209c812c7d045"],"topics":[["0x435e19089f6ae5362a112155f011980907d2ff69b4c2bb894f8324260650ee6a"]],"resultHash":"0x74f2128b7c84cc2ee59bed973028edbeea259d07e8789b080cac700be9357dbc"},{"fromBlock":2545695,"toBlock":2558232,"address":["0x2d5a67ed56afe3f56ff035e3f269bd3b230b108a"],"topics":[["0x11cedc7f83a9a6f5228b8fcd3c3c0ae686a51e2e04ea46923e3491a32a4bbaa8"]],"resultHash":"0x975080c03432147244c5976c39e6b4ecd94dccfa5fa401aa6225f44e900dac0b"},{"fromBlock":4430318,"toBlock":4436731,"address":["0x8737a1c3d55779d03b7a08188e97af87b4110946"],"topics":[["0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],["0x000000000000000000000000000000000000000000000000b8159170038f96fb"]],"resultHash":"0x5c07c9eda4b9579fd357276bfb82823f564a37bb7d9cdf550f70027945b2dc2e"},{"fromBlock":3317037,"toBlock":3329804,"address":["0x4b5011c89f3e727b71e113334e36ff70972a969f"],"topics":[["0x27333edb8bdcd40a0ae944fb121b5e2d62ea782683946654a0f5e607a908d578"],["0x0000000000000000000000007f2698714842f59e89f1eb8b1b70ccb053b5a176"],["0x0000000000000000000000003367dfa11e3148a07c2da773e1f65b155b0abe56"]],"resultHash":"0x96a2bd130d8993f9c893511f0f83ebe3eaeb369a2f028ef5b552bf247604fa78"},{"fromBlock":2426609,"toBlock":2442439,"address":["0x85edb7a0cbacf5bd641e0ff5d6270bef9c72bd6b"],"topics":[],"resultHash":"0x1738195edc9f3fac0032c25682856c240658ccaeef8b80de6b6b12d2176607fd"},{"fromBlock":4519005,"toBlock":4526285,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x00000000000000000000000083efd3ee9278cc7800e93e7f9a14607f5c331b3e"]],"resultHash":"0x1bbd2efde01bf9df0a341cb65496ce44d6f11dff5e4df9fb3e041d7bdcc8c026"},{"fromBlock":5015531,"toBlock":5040888,"address":["0xd098701586c4fdbbdf6081d2a85209c812c7d045"],"topics":[["0x435e19089f6ae5362a112155f011980907d2ff69b4c2bb894f8324260650ee6a"]],"resultHash":"0x74f2128b7c84cc2ee59bed973028edbeea259d07e8789b080cac700be9357dbc"},{"fromBlock":5601641,"toBlock":5607811,"address":["0xfdfd239c9dd30445d0e080ecf055a5cc53456a72"],"topics":[],"resultHash":"0x863719269e9dc7c254a0fd25b1eebe8558f75ccc90aec0f681b2ec7638bb0791"},{"fromBlock":4359240,"toBlock":4366818,"address":["0xb0910e7c7adec52ef3bae5db9d01fd967a22fb7b"],"topics":[["0x5e1276d0e2c70e310694b5a7522e8710ee90fe71e646e8a1307024f214566a36"]],"resultHash":"0x18e60409276bd0e6742aa0dcc04d87735cd64e919c4dd851f34e7f3a14b90223"},{"fromBlock":7593516,"toBlock":7627518,"address":["0xbbd234155c2e2aa78fb4de2299db0b3b5b40600a"],"topics":[],"resultHash":"0x0ed08e047cebf302edc2751f3f2cb5a34abd98365c7d65ca9721f89622068740"},{"fromBlock":6255580,"toBlock":6276252,"address":["0x26280ec2fa5e4987520e4c84d55b7320f1f3c4ce"],"topics":[["0xb4e1304f97b5093610f51b33ddab6622388422e2dac138b0d32f93dcfbd39edf"],["0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"]],"resultHash":"0xed70e01668fd02978926418e13e49dcc8c13cdd444e2b94ed9e7e617bd16dec6"},{"fromBlock":2868071,"toBlock":2885866,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"]],"resultHash":"0xfd399afe985193cb10afa6abaddf7bb6a1750a1f5f427970d61f3dae620c7724"},{"fromBlock":2501204,"toBlock":2507597,"address":[],"topics":[["0xdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae7"]],"resultHash":"0xbe1e24d4f2bef0f4c7a09a7f2a95d6bd50e31ca84d9d7287a8a592f7c1c12c45"},{"fromBlock":2865928,"toBlock":2885459,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"]],"resultHash":"0x0cd06634724893c07bf18b8e8b7616db7fd3647a2e13fc4b63b3952f8bba47ac"},{"fromBlock":3416388,"toBlock":3442563,"address":["0x5c7a6cf20cbd3eef32e19b9cad4eca17c432a794"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],null,null],"resultHash":"0x7cff77806fd31155ecbb4cc274a430283c6757040a4048b395c16e9b46170f97"},{"fromBlock":7446867,"toBlock":7463757,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],null,["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x6cc35a7707ee763849a645c248668601468da4aed4439cf1a0e92a6e747a23ae"},{"fromBlock":5601641,"toBlock":5607811,"address":["0xfdfd239c9dd30445d0e080ecf055a5cc53456a72"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x863719269e9dc7c254a0fd25b1eebe8558f75ccc90aec0f681b2ec7638bb0791"},{"fromBlock":4515660,"toBlock":4528755,"address":[],"topics":[null,null,["0x000000000000000000000000db412c9598c41d72778744d8ee7d028214f00282"]],"resultHash":"0x245e024bf264627d14ba9577049f82ee61f355de9a718060b18285654d6917cb"},{"fromBlock":3317037,"toBlock":3329804,"address":[],"topics":[["0x27333edb8bdcd40a0ae944fb121b5e2d62ea782683946654a0f5e607a908d578"],["0x0000000000000000000000007f2698714842f59e89f1eb8b1b70ccb053b5a176"],["0x0000000000000000000000003367dfa11e3148a07c2da773e1f65b155b0abe56"]],"resultHash":"0x96a2bd130d8993f9c893511f0f83ebe3eaeb369a2f028ef5b552bf247604fa78"},{"fromBlock":2863218,"toBlock":2888686,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"]],"resultHash":"0x4ac3047fe503798f4b73b7c64f9da1845837f8617861c2e46e3ae6d3828bbda4"},{"fromBlock":7449076,"toBlock":7463225,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[null,null,["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xc9afa2e32c4f9dd400462c2f4dfcf4739181a3c96d6b94e02d523780efe232fc"},{"fromBlock":7447036,"toBlock":7459203,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"]],"resultHash":"0xba1ee847df60d1e71be77814f6e729714faf5b4e1c728344e77a5c981b72e209"},{"fromBlock":4856412,"toBlock":4857687,"address":[],"topics":[["0xb9fa1caa1e1541788a4b5cd68270e6d375e3a28f4f94017af9351c5955d58fa7"],null,["0x00000000000000000000000000000000000000000000000000000000000017b0"]],"resultHash":"0x88eedc10bfe45114515f6b2c843f728644744134fe180206e8e530fc20591094"},{"fromBlock":6255580,"toBlock":6276252,"address":["0x26280ec2fa5e4987520e4c84d55b7320f1f3c4ce"],"topics":[["0xb4e1304f97b5093610f51b33ddab6622388422e2dac138b0d32f93dcfbd39edf"],["0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"]],"resultHash":"0xed70e01668fd02978926418e13e49dcc8c13cdd444e2b94ed9e7e617bd16dec6"},{"fromBlock":7448059,"toBlock":7469066,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],null,["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x281c6d712ecdf865375a9be14eae7644e39bdcbebd4aa2ed020abf04d01f3445"},{"fromBlock":4417825,"toBlock":4437464,"address":["0xc86d830fd72e77673c5f58014c530f6242378bc7"],"topics":[null,["0x0000000000000000000000000e0ffca70d862314ca067bb03813f52bd9225459"],["0x000000000000000000000000cd48b1739d2f1a72705320a9025d057262bc41de"]],"resultHash":"0xb204b27986191e7c8492a463e396154796f186283d65a8c795655641c876203a"},{"fromBlock":7445147,"toBlock":7464578,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],null,["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0xed3b3841ea5b2491e5f82b221bf98f083257e9983f601ac390c617d0e8c0037f"},{"fromBlock":5597184,"toBlock":5608306,"address":["0xfdfd239c9dd30445d0e080ecf055a5cc53456a72"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000098cbc1530bfec21f8d10662d769608217364513a"]],"resultHash":"0xad08a6a11cfeb2d8150bc6a3385d12977d344fc3714e08643082ea429c0d1f8f"},{"fromBlock":2574122,"toBlock":2583701,"address":[],"topics":[null,["0x00000000000000000000000089a5f2c62213b18ee5f83b21cb1a323920c9b101"]],"resultHash":"0xaedc313ad31d6b984dc2f9e4d1feb64063c84f539fc3f6da90059f82592724af"},{"fromBlock":2860514,"toBlock":2889605,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"]],"resultHash":"0x5202007a2095bc5408ce1b279c54399838934b63cad0205ce0cff93d93a0a6ea"},{"fromBlock":2874186,"toBlock":2884030,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]],"resultHash":"0xdff7f0423c528b982f61468e0837e69364b48d9092ca83b883a14e9a23eba053"},{"fromBlock":3412532,"toBlock":3450477,"address":["0xfda9adbc51ca64d932621e7711caac40f98025d8"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],null,null,["0x0000000000000000000000008d37ac95786c542a0f2760a182a6936ba34d0b42"]],"resultHash":"0x5e15bf2eb0262388321d4a6c76a064df8685d51570efaa4d2831425051e88acd"},{"fromBlock":2873839,"toBlock":2882996,"address":null,"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x0000000000000000000000000000000000000000000000000000000154486d40"]],"resultHash":"0x1f9b060d3237805a634f7b5645fa44c56aeb4c8f7e3950c5e19530b09bfa6115"},{"fromBlock":7571103,"toBlock":7576927,"address":["0xfe17d34dc09666ea591825bb0a3f90167573eb6c"],"topics":[],"resultHash":"0xe52bde12042066d2e1a507cf89b3ba373ac2ed16cf1d3884a4a06c9a4b293c61"},{"fromBlock":5597870,"toBlock":5611067,"address":["0xfdfd239c9dd30445d0e080ecf055a5cc53456a72"],"topics":[null,null,["0x0000000000000000000000009337117fe4fde0335a4f7cdbadca0862fe29f668"]],"resultHash":"0x7b559e0db68fc9c73550f5d92a0fe334a4d28d9c023829396bc31c42fb390976"},{"fromBlock":5340753,"toBlock":5346010,"address":["0x63eaf4307d4ac2010d6abf2cce570ca11a5cf30f"],"topics":[["0x9866f8ddfe70bb512b2f2b28b49d4017c43f7ba775f1a20c61c13eea8cdac111"]],"resultHash":"0x9efe47324df7bf9a58672e7737d856be0cf31dae2af5b2252e39d669fd972d0d"},{"fromBlock":1903235,"toBlock":1915633,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xca317d26c2f3e87cf994633351760bd8f8f697bdde68d2d220351becb34faecc"},{"fromBlock":2870278,"toBlock":2885241,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"],["0x000000000000000000000000257a443076cab725287f3930fb024e15fa550fa2"]],"resultHash":"0xedb804a1d67b1f2f29c7d5db21d9a947bf39f7f83354d5472689bcdc26b8e433"},{"fromBlock":2866139,"toBlock":2892532,"address":["0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000d9c35bb2e27f4cbe1bedb8894414b94bda4232c0"]],"resultHash":"0xd8a88a59c02e00897ff59b04c5913a64c574d6115f661321f4a7e5a7b6f43087"},{"fromBlock":2868003,"toBlock":2885082,"address":["0x53eab61b720c4ed4bb886c681f4f69385e15f201"],"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c"],["0x000000000000000000000000000000000000000000000000000000038416f940"]],"resultHash":"0x9df5228b0616b1c72f537ea86ad76c1606c4114652f5692a78bfedcc224bb085"},{"fromBlock":5601603,"toBlock":5608203,"address":["0xfdfd239c9dd30445d0e080ecf055a5cc53456a72"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000009337117fe4fde0335a4f7cdbadca0862fe29f668"]],"resultHash":"0xf82a1b429f36a09f1f2d0e860ca789b669f832138a81dd8cad18ab58b6361ef8"},{"fromBlock":7448059,"toBlock":7469066,"address":["0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"],"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],null,["0x0000000000000000000000000325686a18aa829b9faaad70f22ea0830aa6076f"]],"resultHash":"0x281c6d712ecdf865375a9be14eae7644e39bdcbebd4aa2ed020abf04d01f3445"},{"fromBlock":5601641,"toBlock":5607811,"address":["0xfdfd239c9dd30445d0e080ecf055a5cc53456a72"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000009337117fe4fde0335a4f7cdbadca0862fe29f668"]],"resultHash":"0x863719269e9dc7c254a0fd25b1eebe8558f75ccc90aec0f681b2ec7638bb0791"},{"fromBlock":5597193,"toBlock":5612047,"address":["0xfdfd239c9dd30445d0e080ecf055a5cc53456a72"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000009337117fe4fde0335a4f7cdbadca0862fe29f668"],["0x0000000000000000000000009337117fe4fde0335a4f7cdbadca0862fe29f668"]],"resultHash":"0x2cfd3e39bc82692099446cf568590f5628b0eaec6f441acd976c6226fe9d8265"},{"fromBlock":6255580,"toBlock":6276252,"address":["0x26280ec2fa5e4987520e4c84d55b7320f1f3c4ce"],"topics":[["0xb4e1304f97b5093610f51b33ddab6622388422e2dac138b0d32f93dcfbd39edf"],["0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"]],"resultHash":"0xed70e01668fd02978926418e13e49dcc8c13cdd444e2b94ed9e7e617bd16dec6"},{"fromBlock":6255580,"toBlock":6276252,"address":["0x26280ec2fa5e4987520e4c84d55b7320f1f3c4ce"],"topics":[["0xb4e1304f97b5093610f51b33ddab6622388422e2dac138b0d32f93dcfbd39edf"],["0x00000000000000000000000081b9c651549b1af22b51b734bdcc968722dacba0"]],"resultHash":"0xed70e01668fd02978926418e13e49dcc8c13cdd444e2b94ed9e7e617bd16dec6"}],[{"fromBlock":7754096,"toBlock":7755210,"address":["0xc4545a0b4a87cbaff03a73f45c377c0b5f416e00"],"topics":[["0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0x36abdf19849b466fa552c51cce4baadaf7927da2b9ab1e89c1058eb24a7a3de2"},{"fromBlock":7754011,"toBlock":7755111,"address":["0xc4545a0b4a87cbaff03a73f45c377c0b5f416e00"],"topics":[null,["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0x8da1efa3210efcf4caa457632e2dd6ff6717ecb330bfff02dfc7e972de68aa86"},{"fromBlock":2817410,"toBlock":2819554,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000041e49d86fc1b767d6a02590fb8a8b6f3668a0018"],null],"resultHash":"0x31481fcb092850eb3361d4f71658921c4b03c50a9efa4109f37f45d1d2c37067"},{"fromBlock":2876716,"toBlock":2879641,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0x6d505007bdd75ff5ed6a8512c79b54285c40fd9b2c785a12daff60ab588e2652"},{"fromBlock":7754220,"toBlock":7755166,"address":["0xc4545a0b4a87cbaff03a73f45c377c0b5f416e00"],"topics":[["0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0x856c9ff69dc7e66c85ae9c6080e221fe26b81013db4c90fbe9c2d970701271d9"},{"fromBlock":6478713,"toBlock":6480825,"address":["0x04890fd959b09592c8c033e87e27ecb927c06e3d"],"topics":[["0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],["0x00000000000000000000000000000000000000000000000048810ec3e431431f"]],"resultHash":"0xf43d275796c59a3e6dab8b6b5e3f59cee439d1dd304a1ffb8e4389851c63ce37"},{"fromBlock":2876716,"toBlock":2879641,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"]],"resultHash":"0x6d505007bdd75ff5ed6a8512c79b54285c40fd9b2c785a12daff60ab588e2652"},{"fromBlock":3030982,"toBlock":3031855,"address":["0x26223f9c67871cfcea329975f7bc0c9cb8fbdb9b"],"topics":[],"resultHash":"0xf23f951a9972589e6cbb512191a7e063005c086d05b7cf9808e18ea72cfb7532"},{"fromBlock":4908248,"toBlock":4912449,"address":["0x9ef7d57a4ea30b9e37794e55b0c75f2a70275dcc"],"topics":[null,["0x000000000000000000000000000000000000000000000000b8159170038f96fb"]],"resultHash":"0xe5e6d20544dcc76f605e7906c2eb8598b0ca69684099fbd40bc563409c66a753"},{"fromBlock":5712018,"toBlock":5713058,"address":null,"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3"],null],"resultHash":"0x35d184a0325d0e13a4a4a1748678f4e267050d122b6169e286ec3cc37ab69eeb"},{"fromBlock":6262236,"toBlock":6262827,"address":[],"topics":[["0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"]],"resultHash":"0x99d876c62b58a2da7688af191ccfdaaee8166920caddc37a443986124dff23d9"},{"fromBlock":5598940,"toBlock":5599868,"address":[],"topics":[["0x2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631"],null],"resultHash":"0x338beff6f966a940f4de1883098183896e3b82b9ffc006a9d2fdaa529c39ab3a"},{"fromBlock":4810897,"toBlock":4813172,"address":[],"topics":[null,null,null,["0x000000000000000000000000000000000000000000000000000000000000000f"]],"resultHash":"0x26b61e7cccf37d9d79af1949dfc8bef9465f191a20f7b2cbe4304a3710f25b72"},{"fromBlock":4741288,"toBlock":4742021,"address":[],"topics":[["0x59200007defbdd8d2c9e53dd05f81091fe977b424f38f2562df9ee8725d58469"],["0x9d6bae620ed8be3a38c5ad6a74fe994e1c3cfe3bbdce71474ba8b08b11b4f3eb"]],"resultHash":"0x6b2cab37e7dcd02c1ac2831e3d42ab54d814c23e83f90fa32d9efea2d8ae5543"},{"fromBlock":1825517,"toBlock":1826178,"address":["0xd86e1fedb7120369ff5175b74f4413cb74fcacdb"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"]],"resultHash":"0x3c7acc280640fc0506346ae237db6858d5a985320fb59fffd75ee7bd2a7890bc"},{"fromBlock":5492930,"toBlock":5493453,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x0000000000000000000000009ea18de905e654f9fb98498109c60edfe133c145"]],"resultHash":"0x17a72519887f781af3f397b0eac5b56aef52200337b37ba75f55d909f6a3ec45"},{"fromBlock":3030535,"toBlock":3032420,"address":[],"topics":[null,null,["0x0000000000000000000000007fe27d970bc8afc3b11cc8d9737bfb66b1efd799"]],"resultHash":"0x0777274284f6bb66fd5a224652190653a8719320c8d996cdad281a2bb45015e8"},{"fromBlock":5653528,"toBlock":5654841,"address":["0xd4aa4138e66700ba20ceba075f48ffe9d31cb177"],"topics":[],"resultHash":"0xf242eac00ed361cdeadf09d3cb4f87dd2ad744de5b8299fba5ef149dceb5b316"},{"fromBlock":3510085,"toBlock":3510756,"address":[],"topics":[null,["0x0000000000000000000000000000000062241003302aca83b655e463ec85e05a"]],"resultHash":"0x7df9afa4a613c99b8a270133a8a37c913835103e5e5ffee048b6642c23024887"},{"fromBlock":5598945,"toBlock":5599726,"address":["0xe1978b1d689a4f8b1989ba1293b87f8ed0b1137e"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000773adcc4e914a4ce0c647d8d5bc583ee6da5528a"],["0x000000000000000000000000f9dc021985e9869227ff3e5fcccc9a0ef2ce7ebd"]],"resultHash":"0x4d2963358ccc80410af09f7500d7a6ee7883c97a3a5c96a4db87bbbefca80f53"},{"fromBlock":5492882,"toBlock":5493475,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x0000000000000000000000009ea18de905e654f9fb98498109c60edfe133c145"]],"resultHash":"0x4dddd89c2363c84b025c3cf0aa814ad0137eaee3cfc8fbcb10f7eaf0a3b70006"},{"fromBlock":4113477,"toBlock":4115169,"address":["0x66d20c6aa53e7f2b1bdb539f12bed20eaacda79f"],"topics":[],"resultHash":"0x2130cf35fc4267cf4909956f24de1911e4a9ea89f28b4fdf7eb0b83771d1afcf"},{"fromBlock":3030128,"toBlock":3031924,"address":["0x26223f9c67871cfcea329975f7bc0c9cb8fbdb9b"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000002fe022ffcf16b515a13077e53b0a19b3e3447855"]],"resultHash":"0x1c06b76ebde2c35e8efc64def6ddc0adbed0050e312bfc2c61c994e0e96b6c41"},{"fromBlock":2817410,"toBlock":2819554,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000041e49d86fc1b767d6a02590fb8a8b6f3668a0018"],null],"resultHash":"0x31481fcb092850eb3361d4f71658921c4b03c50a9efa4109f37f45d1d2c37067"},{"fromBlock":2876693,"toBlock":2879814,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0xc08d6f3a1c40699cd1f2cc30dc73be46c17ecae337a32faad17fc136b77f6307"},{"fromBlock":1528092,"toBlock":1531096,"address":[],"topics":[null,["0x1b549b7328c744f2b3b1dca394f6dcfbef53c46b82fad4ae76e09ba178eb550c"],["0x0000000000000000000000000000000000000000000000000000000000000001"]],"resultHash":"0x871aef3d4bb838dc9a93bbae3039dc1525177f79a3311b882b6ddc611023cb1c"},{"fromBlock":3422219,"toBlock":3427280,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000031f5b934a60f2c9b649a657e14f1a2b2e83f8ac7"],["0x0000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b"]],"resultHash":"0xe886625ca614b4e9adfe4d640054c83a2843ac24d35d896becd7076c1aa5f641"},{"fromBlock":1528363,"toBlock":1531081,"address":[],"topics":[null,["0x1b549b7328c744f2b3b1dca394f6dcfbef53c46b82fad4ae76e09ba178eb550c"]],"resultHash":"0xecfd08401852763293902798b8e5db97aaed856cbdd9e0b7965f37c9aae22025"},{"fromBlock":2876716,"toBlock":2879641,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0x6d505007bdd75ff5ed6a8512c79b54285c40fd9b2c785a12daff60ab588e2652"},{"fromBlock":7636632,"toBlock":7637531,"address":[],"topics":[["0x9c7519dcf6aef530f7209189ddd559038a69f8bb53f818b7fa76c67379aa6b2c"]],"resultHash":"0x028691d18e507259dcb8ffe65d9c191bfa16c74445726045156e67c750805815"},{"fromBlock":2875554,"toBlock":2880068,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0xf3165f923fa457fc62a5d73cf33be5845ef2d26092796431494565cde5152b3b"},{"fromBlock":7754220,"toBlock":7755166,"address":["0xc4545a0b4a87cbaff03a73f45c377c0b5f416e00"],"topics":[null,["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0x856c9ff69dc7e66c85ae9c6080e221fe26b81013db4c90fbe9c2d970701271d9"},{"fromBlock":7369867,"toBlock":7370761,"address":["0x83e40da6b06fb6fa86fb73e24b17ff959d05fab0"],"topics":[["0xc5d455e9addd7a804d8865ad7de39474f361eb662373c346d94f86246e259037"]],"resultHash":"0xc28929c604d342587030989dba8c81605585530255a6daf7fa8b6e7c5b09dc75"},{"fromBlock":5404711,"toBlock":5405796,"address":["0xd3e770e4ae02993fc292d79af165727f92eb0765"],"topics":[],"resultHash":"0x60cd0a722b3c81479c82749f24d42ba7a2262b2af15b9d0509ef71d33cfbeca8"},{"fromBlock":3421466,"toBlock":3425281,"address":["0xe20cf465a163c395e7dde1466cdd1abe695b4658"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,null],"resultHash":"0x797b6e81912ab51386daeac95dc1192c961e023f2dc51653fc3dde88c4a3419b"},{"fromBlock":2876326,"toBlock":2879062,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"]],"resultHash":"0x0a7648121e432ef9df2ed4aa93847eca942e213dd0f01924c259766c01021194"},{"fromBlock":6452241,"toBlock":6454183,"address":["0xd98b590ebe0a3ed8c144170ba4122d402182976f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x00000000000000000000000028e66deb112ef12f67c13f6a198540bb0fdfeb45"]],"resultHash":"0xd67e567da2d4fb60a107b20c7793a5788088adc15122d0eadad72680052d14aa"},{"fromBlock":3381316,"toBlock":3383654,"address":[],"topics":[null,["0x000000000000000000000000e6b3b50f621d3b625714e1ea0e0f4f2abe2a84ec"]],"resultHash":"0xfcae662ea96ae9e47860934a49aaf9862da4820842065eb44e98c96d6dc7f63e"},{"fromBlock":6965510,"toBlock":6966807,"address":[],"topics":[["0xd342ddf7a308dec111745b00315c14b7efb2bdae570a6856e088ed0c65a3576c"]],"resultHash":"0x17dcb43ddb060f96aa89d9f8b4e58d2cc8d884996f645f69f848ba20bdf576f4"},{"fromBlock":6693316,"toBlock":6695466,"address":[],"topics":[["0x2d9d115ef3e4a606d698913b1eae831a3cdfe20d9a83d48007b0526749c3d466"],["0x000000000000000000000000878ac6ab417f57251b3192d4c86a4d175fd4ca22"]],"resultHash":"0xe6b48b2074e406a856a241a65b7000eef50addb8c406e6938ad1b0ffc58979fa"},{"fromBlock":7754089,"toBlock":7755177,"address":["0xc4545a0b4a87cbaff03a73f45c377c0b5f416e00"],"topics":[null,["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0x956ee10d041782d9b2f7f134ca5ed071375a719c350fa6e404ffd39eb5e8728f"},{"fromBlock":3427167,"toBlock":3428459,"address":["0x9072495afc2d59d857118ee59b4ef6cfc407d103"],"topics":[null,["0x000000000000000000000000cd5b876728abbabc0515ef55e160c70b340c2705"]],"resultHash":"0x4bb75b87fa04dcc6141a7129090cbf6f9aec1afa01ca7936019bafa3479a6746"},{"fromBlock":5507318,"toBlock":5508308,"address":[],"topics":[null,["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xf891d59d92809541c53a742ccfb3d8ae4a0d15cb4bcd3c7f36d40440fc3e7ebc"},{"fromBlock":5492919,"toBlock":5493714,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x6b30f75cc259e51b40013e6037ddd081cb0e0764dc5cc0e5fb806868a12b504e"},{"fromBlock":5492919,"toBlock":5493714,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[null,["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x6b30f75cc259e51b40013e6037ddd081cb0e0764dc5cc0e5fb806868a12b504e"},{"fromBlock":5492865,"toBlock":5493609,"address":null,"topics":[null,["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],null],"resultHash":"0x7310d8ed477cbbdb59051cf4d29d0cd9c0b8ac1e46e8e743320bc2e188604969"},{"fromBlock":6425515,"toBlock":6426639,"address":["0x00c5c0b8e0f75ab862cbaaecfff499db555fbdd2"],"topics":[],"resultHash":"0x3e0462928a64b7c3565c21c75309c1fc7b7ff5b51b087e4953b844e4d6bd3b16"},{"fromBlock":2875089,"toBlock":2879558,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x000000000000000000000000428c4dc89b6bf908b82d77c9cbcea786ea8cc7d0"]],"resultHash":"0xcd39e89e3835d52f7af0be7a775f3599c84c96991401c4ccef91e618aae9a445"},{"fromBlock":7754209,"toBlock":7755190,"address":["0xc4545a0b4a87cbaff03a73f45c377c0b5f416e00"],"topics":[["0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0x2285a163c25091abbb665846e0e7a61792535da9db60a6c2f3273b460c5ea44a"},{"fromBlock":2876543,"toBlock":2880258,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0xd350a8a8b799a7436760976960d562a7f4331ddc1f4239509ec9dd6a92a4841f"},{"fromBlock":4432159,"toBlock":4432945,"address":[],"topics":[["0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"]],"resultHash":"0x342209be770e1f88a5582c9e002af6e797c1373945ad2003f7060811b70d514c"},{"fromBlock":2876716,"toBlock":2879641,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0x6d505007bdd75ff5ed6a8512c79b54285c40fd9b2c785a12daff60ab588e2652"},{"fromBlock":6261871,"toBlock":6262655,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271","0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],null,["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x8c14a966efa550a3cd28ea2414f3230a830eb079dce71469e401fe4fcaa4bff3"},{"fromBlock":2876989,"toBlock":2879713,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"]],"resultHash":"0x2526e3e20adfceccf596fe8f62d5a65b86240ae410d41b64acba8db4c33af57e"},{"fromBlock":6762364,"toBlock":6763235,"address":["0x56171b3242587bb5c2c19883434dc054db525e91"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000eee96830f08c6835b706cbee997d431a94b55332"]],"resultHash":"0xde5af1160c34ac4d8ef31da5fb873c06340f5b140968a7d8e747cea4ee7265ea"},{"fromBlock":2525459,"toBlock":2525915,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000207cb7aeb640fa6cee696269dee1a441d0425a3d"]],"resultHash":"0xf212af5fe2f5fb510cf9c9adef06e1286d5f7ea26eeeb886f363298cd518ab91"},{"fromBlock":2876716,"toBlock":2879641,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0x6d505007bdd75ff5ed6a8512c79b54285c40fd9b2c785a12daff60ab588e2652"},{"fromBlock":4908248,"toBlock":4912449,"address":["0x9ef7d57a4ea30b9e37794e55b0c75f2a70275dcc"],"topics":[["0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],["0x000000000000000000000000000000000000000000000000b8159170038f96fb"]],"resultHash":"0xe5e6d20544dcc76f605e7906c2eb8598b0ca69684099fbd40bc563409c66a753"},{"fromBlock":5507081,"toBlock":5508454,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xa7fd65e290742ea1189c96ad618e74a64db4f4757e65b636b714548c332640d0"},{"fromBlock":6221287,"toBlock":6223725,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"]],"resultHash":"0xdaf95d5b8b18fe96cc3974500eee048d84a374c534434a5c38e6eef97d4746a8"},{"fromBlock":1873308,"toBlock":1874122,"address":["0xf549af21578cfe2385ffd3488b3039fd9e52f006"],"topics":[["0xf6a97944f31ea060dfde0566e4167c1a1082551e64b60ecb14d599a9d023d451"]],"resultHash":"0xf68b71f9cd5b4a4d482d9bb0f55dd619732c1b903901a88e94473725538208cc"},{"fromBlock":3163030,"toBlock":3164381,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000a68d4c1e3de1b721ad1356bbf827d6bc8cef304f"],["0x000000000000000000000000ab4493b5ca548110a4d7a9c494bfe473367cd3c8"]],"resultHash":"0xc0f5059efb8aca9c72bf5a4c67be47f0d9394e963f607d19d59bb27a0454163c"},{"fromBlock":5493015,"toBlock":5493715,"address":null,"topics":[null,["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],null],"resultHash":"0xf6993c5dc9315ea1ec67939a66b127a030e3cc9059be6e2225d60ee7418e8fd6"},{"fromBlock":2875811,"toBlock":2879780,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0xed47adfc7fc637ec595040d4012087a4ac35535805eb6dd58287d28fffa4b68e"},{"fromBlock":6422381,"toBlock":6423781,"address":["0x5ac5b7fd4550902ba12df16175f7d0a6ef8b0549"],"topics":[],"resultHash":"0x212a0dca029578e7fd5a7b9d2d886c69e88f338acaac04add22f79aade98ac36"},{"fromBlock":6262154,"toBlock":6262844,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],null,["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xa13d466d1e237a9af3f4dddec1d9581acae9f69f18f98bc0ee0c3968b904b5c6"},{"fromBlock":3030611,"toBlock":3032656,"address":["0x7fe27d970bc8afc3b11cc8d9737bfb66b1efd799"],"topics":[],"resultHash":"0xfa53986c5c246c60170adfa114fcb4f398231c46f1e04c7f202567aada14a767"},{"fromBlock":2875808,"toBlock":2880072,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x000000000000000000000000428c4dc89b6bf908b82d77c9cbcea786ea8cc7d0"]],"resultHash":"0xbeed6c6249ad23674fd4611d02bf045a70e5ff1d6334d64380f25165db3cccb6"},{"fromBlock":5492919,"toBlock":5493714,"address":[],"topics":[null,["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x6b30f75cc259e51b40013e6037ddd081cb0e0764dc5cc0e5fb806868a12b504e"},{"fromBlock":3422219,"toBlock":3427280,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000031f5b934a60f2c9b649a657e14f1a2b2e83f8ac7"],null],"resultHash":"0xe886625ca614b4e9adfe4d640054c83a2843ac24d35d896becd7076c1aa5f641"},{"fromBlock":2525345,"toBlock":2526342,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000051bdc8bd6d9d4d37d0d33c3439ac3c5fb960671c"]],"resultHash":"0x6124f71654af879e946a4d4583b03559f146e2ceb09027df1a59c700abf4799a"},{"fromBlock":2876196,"toBlock":2879408,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[null,null,["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0xa9d88b176878ab1a1b0fa49a00a5826d3b48d9cd085bb7b0fc2b9a71fad3b327"},{"fromBlock":7369867,"toBlock":7370761,"address":[],"topics":[["0xc5d455e9addd7a804d8865ad7de39474f361eb662373c346d94f86246e259037"]],"resultHash":"0xc28929c604d342587030989dba8c81605585530255a6daf7fa8b6e7c5b09dc75"},{"fromBlock":2875808,"toBlock":2880072,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x000000000000000000000000428c4dc89b6bf908b82d77c9cbcea786ea8cc7d0"]],"resultHash":"0xbeed6c6249ad23674fd4611d02bf045a70e5ff1d6334d64380f25165db3cccb6"},{"fromBlock":5492857,"toBlock":5493587,"address":null,"topics":[null,["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x0051122210c97e0812ed11f27bf2b573c7736f5a4bdfe947d94e08f01c57bf97"},{"fromBlock":7754089,"toBlock":7755177,"address":["0xc4545a0b4a87cbaff03a73f45c377c0b5f416e00"],"topics":[null,["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0x956ee10d041782d9b2f7f134ca5ed071375a719c350fa6e404ffd39eb5e8728f"},{"fromBlock":7369867,"toBlock":7370761,"address":["0x83e40da6b06fb6fa86fb73e24b17ff959d05fab0"],"topics":[["0xc5d455e9addd7a804d8865ad7de39474f361eb662373c346d94f86246e259037"]],"resultHash":"0xc28929c604d342587030989dba8c81605585530255a6daf7fa8b6e7c5b09dc75"},{"fromBlock":2876318,"toBlock":2879230,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[null,["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x000000000000000000000000428c4dc89b6bf908b82d77c9cbcea786ea8cc7d0"]],"resultHash":"0xa361308f8d82b560e279cb90ee8b319488eca10417dbd66c92abb218a3495ab3"},{"fromBlock":2875619,"toBlock":2880156,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0x4ac70e54ceeb5f425482d3acbb2d35279a1ad514f5625bc3e0e72871353b6207"},{"fromBlock":6262154,"toBlock":6262844,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],null,["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"]],"resultHash":"0xa13d466d1e237a9af3f4dddec1d9581acae9f69f18f98bc0ee0c3968b904b5c6"},{"fromBlock":5342350,"toBlock":5345207,"address":["0x63eaf4307d4ac2010d6abf2cce570ca11a5cf30f"],"topics":[],"resultHash":"0x4068aa47a469144cdd32b3c71b4940469ef5432b4b680b232871755079098588"},{"fromBlock":2876295,"toBlock":2880243,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"],["0x0000000000000000000000001041d5b06b9f1e73a4d6ae4f4d2a3d5c9e0aa88e"]],"resultHash":"0xb364a14e519f6efb62895c410d795ebe633c7dec9460391ed4c9f7eea35408bb"},{"fromBlock":6221510,"toBlock":6223168,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[],"resultHash":"0x4200d26647709332d33cb4ce1f6bac9491e503e31f66c4d9e0fd43cda0fb8083"},{"fromBlock":2525345,"toBlock":2526342,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000051bdc8bd6d9d4d37d0d33c3439ac3c5fb960671c"],["0x000000000000000000000000207cb7aeb640fa6cee696269dee1a441d0425a3d"]],"resultHash":"0x6124f71654af879e946a4d4583b03559f146e2ceb09027df1a59c700abf4799a"},{"fromBlock":5598945,"toBlock":5599726,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x000000000000000000000000773adcc4e914a4ce0c647d8d5bc583ee6da5528a"],["0x000000000000000000000000f9dc021985e9869227ff3e5fcccc9a0ef2ce7ebd"]],"resultHash":"0x4d2963358ccc80410af09f7500d7a6ee7883c97a3a5c96a4db87bbbefca80f53"},{"fromBlock":6262154,"toBlock":6262844,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],null,["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xa13d466d1e237a9af3f4dddec1d9581acae9f69f18f98bc0ee0c3968b904b5c6"},{"fromBlock":5978864,"toBlock":5979542,"address":[],"topics":[null,null,["0x000000000000000000000000e4c60b750b851d88ff30ac492d809d911360584d"]],"resultHash":"0xf747c0cea288c577d7dba332ec0f6657d5f36c60007b76108c1e875a3628b190"},{"fromBlock":4063476,"toBlock":4066395,"address":["0xf651467aecd1a7905efb4cd35502f16880ee0c23"],"topics":[["0xf80dd09632f046e05472e1c239271a3b2ad3de73c27a1b03d0bb0329ba6716df"],null,null,["0x00000000000000000000000000000000000000000000000000000000658e0c00"]],"resultHash":"0x4853195aa4b792871cfa9bf13734bd8faf4909e6debbf8a65849a1416c0b01c6"},{"fromBlock":1528363,"toBlock":1531081,"address":null,"topics":null,"resultHash":"0xfd06c484c534671365952a6c1f93accad4162dd4cd8404fcb1153bd5d1709fb1"},{"fromBlock":6262154,"toBlock":6262844,"address":["0xb3f15a44f91a08a93a11c6fbf6a4933c623275fe"],"topics":[["0x8967dcaa00d8fcb9bb2b5beff4aaf8c020063512cf08fbe11fec37a1e3a150f2"],null,["0x0000000000000000000000001965cd0bf68db7d007613e79d8386d48b9061ea6"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xa13d466d1e237a9af3f4dddec1d9581acae9f69f18f98bc0ee0c3968b904b5c6"},{"fromBlock":7754089,"toBlock":7755177,"address":["0xc4545a0b4a87cbaff03a73f45c377c0b5f416e00"],"topics":[null,null,["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0x956ee10d041782d9b2f7f134ca5ed071375a719c350fa6e404ffd39eb5e8728f"},{"fromBlock":5507318,"toBlock":5508308,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[null,["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xf891d59d92809541c53a742ccfb3d8ae4a0d15cb4bcd3c7f36d40440fc3e7ebc"},{"fromBlock":2877134,"toBlock":2878871,"address":["0x779877a7b0d9e8603169ddbd7836e478b4624789"],"topics":[null,["0x000000000000000000000000177e068bc512ad99ec73db6feb7c731d9fea0cb3"]],"resultHash":"0x6722e252b25d644b95771d1aa219294a5cbdade1a5378dbf65d0449fabdb600b"},{"fromBlock":5492930,"toBlock":5493453,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]],"resultHash":"0x653a14a4b4c98231b378179a5aa1ad3d087920c44c396ad22a480d83b3dd708e"},{"fromBlock":5492919,"toBlock":5493714,"address":["0xfd57b4ddbf88a4e07ff4e34c487b99af2fe82a05"],"topics":[null,["0x00000000000000000000000038d1ef9619cd40cf5482c045660ae7c82ada062c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x6b30f75cc259e51b40013e6037ddd081cb0e0764dc5cc0e5fb806868a12b504e"},{"fromBlock":3322417,"toBlock":3323040,"address":["0xc3a11ef77e260e9bff04b6b2e0a4f1619436a9c2"],"topics":[["0x48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f"]],"resultHash":"0xcc97509e54083a9adb399fe300fc33f8f5814a80f7582098c2688cfbecef51c9"},{"fromBlock":5598859,"toBlock":5599379,"address":["0x38d1ef9619cd40cf5482c045660ae7c82ada062c"],"topics":[["0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7"],["0x00000000000000000000000081660dc846f0528a7ce003c1f7774d7c4135f344"]],"resultHash":"0x42d5eb89bd9ef03060199eca5034fd65e5fd27efd5a05ac507cd36514b79d077"},{"fromBlock":3030438,"toBlock":3031924,"address":["0x26223f9c67871cfcea329975f7bc0c9cb8fbdb9b"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xac01f4ab8ddf07d5b0fa276c8fcafd7c9d7682765b17cd78a9a2e21154f6b41f"},{"fromBlock":3422361,"toBlock":3425676,"address":["0xda9d4f9b69ac6c22e444ed9af0cfc043b7a7f53f"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000e7ec1b0015eb2adeedb1b7f9f1ce82f9dad6df08"]],"resultHash":"0xe41aedbbdd76c4f8b28f7a307e6acb693c7cf9aa6c7fed69e33b79e4f049aa97"},{"fromBlock":1908852,"toBlock":1913921,"address":null,"topics":null,"resultHash":"0xc2cbab221f0a74a24a5189a6b8916307bc451103aee2b5ad44273d41557edbdf"}],[{"fromBlock":3676092,"toBlock":3676222,"address":["0xb5e7041ca1b7024c77cedccb3da205a660643697","0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,null,["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8"]],"resultHash":"0x1fc40ce6939f1b2e27e6a91e3fc402fef2e73075c3a9aacb83a031025730673a"},{"fromBlock":7754446,"toBlock":7754755,"address":[],"topics":[null,["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"],["0x0000000000000000000000003a9d48ab9751398bbfa63ad67599bb04e4bdf98b"]],"resultHash":"0xae624936bd44883c1ffe7bb475a16f73ea113e035f08461d0fd766e13837a71d"},{"fromBlock":6479878,"toBlock":6479944,"address":[],"topics":[["0x1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac728859"]],"resultHash":"0x9d458a373d07027ef70f6ded810b3ac7cc9063227e466a96b6b539e4dfbfa5be"},{"fromBlock":5493294,"toBlock":5493367,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x9ad4ae5744b4eefab2e8634790156d16d592e92426079eedd72af3279a89c92b"},{"fromBlock":3792221,"toBlock":3792285,"address":["0x22c1317fe43132b22860e8b465548613d6151a9f"],"topics":[null,null,["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8"]],"resultHash":"0x7dbd3d260f9c5554b2923dc70627a18013f1eb83903186c0d3b2608751dc2a52"},{"fromBlock":4886507,"toBlock":4886732,"address":["0x236f697c518b7aec0bb227d8b7547b3c27ca29bc"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null],"resultHash":"0x4bd3cea91f08d6f4799c635196505b8001e57c5e6dc55588c682b194c1513c36"},{"fromBlock":3423903,"toBlock":3424314,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000004c00cb23d75530798593593401d977bfa04bd321"]],"resultHash":"0x21903735fb4c21a7e876907781eae922ce536fb7f6c3ce79ee787b7e4a70dcc7"},{"fromBlock":3423594,"toBlock":3423849,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[null,null,["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xf5c336f0d3cea3e86c9e3ca89118d52942ad4ccb77cfb3dbdff9d180fa093b15"},{"fromBlock":6453499,"toBlock":6453793,"address":["0xd98b590ebe0a3ed8c144170ba4122d402182976f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000708d8f13492900da663fd2421cbbef1419b2f185"]],"resultHash":"0xba7943cfae732f8ff908302f37f3ded7fa4d91eb2fd2961e2f3e4b10ac6a8706"},{"fromBlock":2319423,"toBlock":2319518,"address":null,"topics":null,"resultHash":"0x6db2bdebafdc4468b30b9f203f06a5f4d3a307b5feb0cea71d687fcecdc4bdd2"},{"fromBlock":3423718,"toBlock":3423997,"address":null,"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000044e1d00ef5ea916b66c3a4a57ec3786750d8968a","0x00000000000000000000000025aa96bf246423b96b69dcd300e34467edafcf67"]],"resultHash":"0x1a5d9097c515c6e3ec5cc47375ae01a8a6203943b474a8aa030a53c8d78f04c6"},{"fromBlock":2768915,"toBlock":2769104,"address":[],"topics":[["0x2ad3120f495e551d2c27d842512ed4f16e008ed3bf4df24aaf729a37080444a6"]],"resultHash":"0x4409eccb5d1be49dbba2d99ea9042a8c28877b085f719ab1d727134d79dc674f"},{"fromBlock":3423752,"toBlock":3424025,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000054ea27b8faea91b29f43793badb44066d77e2d17","0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000025aa96bf246423b96b69dcd300e34467edafcf67"]],"resultHash":"0x1a5d9097c515c6e3ec5cc47375ae01a8a6203943b474a8aa030a53c8d78f04c6"},{"fromBlock":2510213,"toBlock":2510333,"address":null,"topics":null,"resultHash":"0x4ecd528ea4a8484665703d0f6f77084efb50dd4941b8532f7dd335a23e58a6b9"},{"fromBlock":3586273,"toBlock":3586404,"address":["0xb5e7041ca1b7024c77cedccb3da205a660643697"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x958ed0086a302bc530c2d9e75095468aacdbbbbd6622f4e1f644a6948d8fd8bc"},{"fromBlock":2861232,"toBlock":2861287,"address":null,"topics":[null,null,null],"resultHash":"0x9e7660487fb78c641dd5ae28b1ec83aa5c9f2ee6fe9a8e0737ca911db8c29eb8"},{"fromBlock":3423749,"toBlock":3423991,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xc245ef6bfc7823613f1ec2e962255b06f02b7bedafe36b34304e7efd1900148e"},{"fromBlock":3423328,"toBlock":3423621,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xe4fc09d78d8fb34cfee6e01c7aaa3e509dfad16c3f4e1b264e11f3e86bb8e7f4"},{"fromBlock":1795452,"toBlock":1795565,"address":null,"topics":null,"resultHash":"0xe3a13ced5ae9df33489bd722f421917f77488cd405c3df257b843ee9ec2e76cc"},{"fromBlock":3423594,"toBlock":3423849,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xf5c336f0d3cea3e86c9e3ca89118d52942ad4ccb77cfb3dbdff9d180fa093b15"},{"fromBlock":6453503,"toBlock":6453593,"address":["0xd98b590ebe0a3ed8c144170ba4122d402182976f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xe5db67eb4a08037e976f0d7ed5cc52986dbf21d36f03bd33ed8cd2ddd793883c"],null],"resultHash":"0x2a9819a0e1c8afd3fe6e651d7d279321bbe663334f76bdd017cc489f3173a42e"},{"fromBlock":2320280,"toBlock":2320452,"address":null,"topics":null,"resultHash":"0x7017b79fb0b3580f0a301b9a6802335d5d763e99dcda983468ac42b9351aaa02"},{"fromBlock":3586285,"toBlock":3586388,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x8d18648b2a96d3fe290f24724c97693a7c1185910299b7d9b90e3fcb4a8b8f74"},{"fromBlock":3423749,"toBlock":3423991,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xc245ef6bfc7823613f1ec2e962255b06f02b7bedafe36b34304e7efd1900148e"},{"fromBlock":2903663,"toBlock":2903743,"address":null,"topics":[null,null,null],"resultHash":"0xf1a43edc1b0443676d59a8997b59a3842c3c497f9390f8a5c19acebc940cb2fe"},{"fromBlock":2112216,"toBlock":2112588,"address":null,"topics":[null,null],"resultHash":"0xe7e8c930ce6bee7923ffb6c42b81942ec242195f126ca63258af65e4c4f63edf"},{"fromBlock":3163640,"toBlock":3163832,"address":["0x5b9fedd37f0b92e7e282b19cebcf06f57b77c604"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x6e316bdfdc978b8666555edf12b3995777e2b2a6a156f024e53f90f327f1697c"},{"fromBlock":5289506,"toBlock":5289716,"address":["0x3f4b6664338f23d2397c953f2ab4ce8031663f80"],"topics":[null,null,["0x000000000000000000000000fa885f6579ae1cdc381e647fc306dcde4f976164"]],"resultHash":"0x38fad159a0c6318a8a0697622895552efac5063f55936625a5c725ebe536a872"},{"fromBlock":5704029,"toBlock":5704170,"address":["0x5f8403cfada2c58ae2adccbaaa983d48160e4b57"],"topics":[["0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a"],["0x0000000000000000000000004200000000000000000000000000000000000010"]],"resultHash":"0xd577f886182954eca5db0278df72aef8eab2684d64eda218570b3e8c52e51653"},{"fromBlock":5493294,"toBlock":5493374,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0xd9c6ed522a9564cde38764dea2642e0ec1150cfa890371cf69f970ebc8076a1e"},{"fromBlock":5493513,"toBlock":5493669,"address":[],"topics":[null,null,["0x0000000000000000000000007a4ee6f9f0ab037fe771fc36d39c1e19bcc0fdb5"]],"resultHash":"0x846c13936d229f2624caa97191f6b145a0eacd0625e304d21701c7a45bac661f"},{"fromBlock":2434304,"toBlock":2434385,"address":null,"topics":[],"resultHash":"0x1af9584bcecc66b35fff70e09a47f7ef6be55dff43d282204d94e19255b302b0"},{"fromBlock":5289506,"toBlock":5289716,"address":[],"topics":[null,null,["0x000000000000000000000000fa885f6579ae1cdc381e647fc306dcde4f976164"]],"resultHash":"0x38fad159a0c6318a8a0697622895552efac5063f55936625a5c725ebe536a872"},{"fromBlock":5978978,"toBlock":5979072,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null],"resultHash":"0x271474b370e2fefd72a1ca40052213b73e1119c34526d53b08efe05cdeb27417"},{"fromBlock":2768966,"toBlock":2769008,"address":null,"topics":[],"resultHash":"0xb0101f32669c5af6c548425281a41e3be8f85d01059b5ea2c9a2188ad0c24d6f"},{"fromBlock":5289495,"toBlock":5289691,"address":["0x3f4b6664338f23d2397c953f2ab4ce8031663f80","0x91b333a8485737f9b93327483030f48526fadc22"],"topics":[null,null,["0x000000000000000000000000fa885f6579ae1cdc381e647fc306dcde4f976164","0x000000000000000000000000788685c1fe1404b2473347dfb3242a124da99635"]],"resultHash":"0xb33d37186358d5cfd9ebd1494f7dafeb228cb2d8b59526c39b099f2b34b71589"},{"fromBlock":3765940,"toBlock":3766025,"address":[],"topics":[["0x47866f7dacd4a276245be6ed543cae03c9c17eb17e6980cee28e3dd168b7f9f3"]],"resultHash":"0x4538059a2713138e395eebe8e64de79683664552f695f5c8751f543b9464c86d"},{"fromBlock":3423456,"toBlock":3423649,"address":null,"topics":[null,null,["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8","0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0x345d86ea7de90287fc20d80512c17abd937cb538a5ee7b90e4b90dd280d22037"},{"fromBlock":6288012,"toBlock":6288384,"address":null,"topics":[["0x35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23"],null,null],"resultHash":"0x9314519ed14044a6ce62f67aceaa8082fffd462527bd88e49d0fcef90355a958"},{"fromBlock":5051245,"toBlock":5051419,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xfc9615e20872671b16e57132264d4c616a7459dd2c92c77f88e08b4f55268044"},{"fromBlock":5979005,"toBlock":5979055,"address":[],"topics":[null,["0x000000000000000000000000f89215880b3f56b92b7731e9c917d3737c441c4b"]],"resultHash":"0x6a68906308f8958718e555d47128a507caf5d34aec6ac04431043ec8ab463cc6"},{"fromBlock":1873466,"toBlock":1873708,"address":[],"topics":[["0xf6a97944f31ea060dfde0566e4167c1a1082551e64b60ecb14d599a9d023d451"]],"resultHash":"0x34b4264dcfd1ef78f5812bce3d3304e9756a4aa45b6ccc05818f9256b7e2e47e"},{"fromBlock":6222552,"toBlock":6222794,"address":["0x000000007f56768de3133034fa730a909003a165"],"topics":[],"resultHash":"0x4be31532852706748b29c9c4a242449a50de0b78237ce777f6b73aa20535479b"},{"fromBlock":6769631,"toBlock":6769685,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[null,null,["0x0000000000000000000000007abf52a91d3d078960bafc9912fa1be248ef6dcf"]],"resultHash":"0x8b5497a9faca1be8d310706ba05da4e16ce8a39e8670663c1244c5ed417edb2d"},{"fromBlock":2742001,"toBlock":2742061,"address":null,"topics":null,"resultHash":"0xccb0ab85d618184e5028c13f021ad836c4eb52c3b940820aa3c7699430a35e3b"},{"fromBlock":3423663,"toBlock":3423934,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67","0x00000000000000000000000004b7d4ee7c2126dc2967e36f10fe4f7322812e34"]],"resultHash":"0x527fe7f4d6800f6cbcb6a6b802955690a3810fce055e59bdeb316f7a4f6e9a2d"},{"fromBlock":4886524,"toBlock":4886638,"address":["0x236f697c518b7aec0bb227d8b7547b3c27ca29bc"],"topics":[null,null],"resultHash":"0xcbad350b752b3b3528636ba2346dc63d0e505756713481dd92b6ce4cb415c84d"},{"fromBlock":5654119,"toBlock":5654408,"address":null,"topics":[null,["0x000000000000000000000000d9d4b3ad7edb8f852ab75afa66c1456c46fef210"]],"resultHash":"0xdf2c6fca90d8abd33f990784149298111534354be64b60f5a4c2fd3761a336df"},{"fromBlock":4524747,"toBlock":4524858,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],null],"resultHash":"0x5dd702668c17059d057dac84a60fbc36ca1d65d6db542fb9207d45d0cb7f957f"},{"fromBlock":3628250,"toBlock":3628366,"address":[],"topics":[null,["0x000000000000000000000000d35bcf3da45426a9df5e58d2221bd79e6af0338d"]],"resultHash":"0xd644a2bc3031f5dc55696ef3beb4dcede40e19b2c58675c21c77e02ff4537843"},{"fromBlock":6769631,"toBlock":6769685,"address":[],"topics":[null,null,["0x0000000000000000000000007abf52a91d3d078960bafc9912fa1be248ef6dcf"]],"resultHash":"0x8b5497a9faca1be8d310706ba05da4e16ce8a39e8670663c1244c5ed417edb2d"},{"fromBlock":3423466,"toBlock":3423724,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xd582fdf7a87a93939e2068fe7e76689a498879efcb2906a1f9ff1d7e6a8ce3be"},{"fromBlock":2225544,"toBlock":2225631,"address":null,"topics":[],"resultHash":"0xf2603f467216189dfe2ae3890801b6b50a23b5207324ad91a6d2ff97e1fb21a9"},{"fromBlock":4115926,"toBlock":4116312,"address":null,"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],null,null],"resultHash":"0xb8072f33c5bfd51977fec0f5533e749815223ce7c20ca2be29cc36b1d350620f"},{"fromBlock":2358802,"toBlock":2358913,"address":null,"topics":[null,null],"resultHash":"0x578fc94222fb45859b03101af72f148e9a886c9ec00dccd9905c10921bb00ecb"},{"fromBlock":3163633,"toBlock":3163719,"address":["0xeee369870a52ea60cef0162a5b3aca1673f90999","0x5b9fedd37f0b92e7e282b19cebcf06f57b77c604"],"topics":[null,null,null],"resultHash":"0x9df98b9f86129933947c833cf116eb97be8473c3043f77f30701e7aef4d9cf36"},{"fromBlock":1767490,"toBlock":1767578,"address":null,"topics":null,"resultHash":"0x9a2cfdb9d425b3ee5c11c7ef633399928a8aa1df92a92b6ae30356f38fa54628"},{"fromBlock":4524746,"toBlock":4524828,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],null],"resultHash":"0xf7932d0f2ab7068c10169bcd77ff9d3510b172e06a8fbd4e3097a957f47cabcc"},{"fromBlock":5289506,"toBlock":5289716,"address":["0x3f4b6664338f23d2397c953f2ab4ce8031663f80"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000fa885f6579ae1cdc381e647fc306dcde4f976164"]],"resultHash":"0x38fad159a0c6318a8a0697622895552efac5063f55936625a5c725ebe536a872"},{"fromBlock":5405001,"toBlock":5405400,"address":[],"topics":[["0xab39b6198177d86fa26959fef9bca1102673c1ae25242930e42bc859b25b3790"]],"resultHash":"0xa607fd5175c6883be5af2dcc6813b6c50a6ed68455ef50269d2728955ce97539"},{"fromBlock":5289429,"toBlock":5289763,"address":["0x2de7b7364a37fbb35f946ca7175a1b596710b262"],"topics":[null,["0x0000000000000000000000000545c5fe980098c16fcd0ecb5e79753afa6d9af9"]],"resultHash":"0x16891f2bfc91b08af08cffe7c4c6346c19b29b2e236bf6765bf5da6e36d7d2d5"},{"fromBlock":6480660,"toBlock":6480864,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x5f091a9dc66316ef56f29b72d982a6f4e1ac0994b9320d7caf0a0dbe65d7434a"},{"fromBlock":3423328,"toBlock":3423621,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xe4fc09d78d8fb34cfee6e01c7aaa3e509dfad16c3f4e1b264e11f3e86bb8e7f4"},{"fromBlock":4886507,"toBlock":4886732,"address":["0x236f697c518b7aec0bb227d8b7547b3c27ca29bc"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x0000000000000000000000000bcb9ea12d0b02d846fb8bbb8763ec8efecb4c79"]],"resultHash":"0x9df1a813db58f913288a74349ce7a1f1d0058e90add5ca1591183e00318c1dcf"},{"fromBlock":5507705,"toBlock":5507851,"address":null,"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x4dd066db433f3fc5519136552bcdc42d69cb698d969f3aa4d211b759c061c015"},{"fromBlock":2290144,"toBlock":2290225,"address":null,"topics":null,"resultHash":"0xfe4ec31f3ae38c3b73c7e6c8fc1105dfe91de02cf3e275abde3c1bb0888f2495"},{"fromBlock":5493325,"toBlock":5493373,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0xe5bb267e0c5e285e7ec30eb9b08ea8009bd91df599dbd31e6ae2a5d82dd32105"},{"fromBlock":3427488,"toBlock":3427661,"address":["0x9072495afc2d59d857118ee59b4ef6cfc407d103"],"topics":[],"resultHash":"0xe90b168df929738d554647be2a57e2c0b2d64f85bbdf6fb491df8dd0f89d2e06"},{"fromBlock":3063178,"toBlock":3063189,"address":null,"topics":[["0xd1ec3a1216f08b6eff72e169ceb548b782db18a6614852618d86bb19f3f9b0d3","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0xfe7a257584a7c4a7509beb3b7642eba0b9608e231e855884fde00d4f0029e767"},{"fromBlock":5654097,"toBlock":5654471,"address":[],"topics":[null,["0x000000000000000000000000d9d4b3ad7edb8f852ab75afa66c1456c46fef210"]],"resultHash":"0x9d745397a79c89798beeb713dcef00c5c00e01bae084d16623955cf9dc0da103"},{"fromBlock":6453397,"toBlock":6453749,"address":["0xd98b590ebe0a3ed8c144170ba4122d402182976f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xe5db67eb4a08037e976f0d7ed5cc52986dbf21d36f03bd33ed8cd2ddd793883c"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000708d8f13492900da663fd2421cbbef1419b2f185"]],"resultHash":"0xf29cd3c3269af94d4c094cba3c151cebea1ee6a6b2c2bcc2b74e1a17fdee93d5"},{"fromBlock":2421882,"toBlock":2421959,"address":null,"topics":[],"resultHash":"0xa8c93c76948e54c3683d7e73ed734b3abc93371af194d9830925fe8481024bcd"},{"fromBlock":2768769,"toBlock":2769076,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xb1e3a1b46819155385694310ea4f465c5fd3db96c2af810043594cace05e1179"},{"fromBlock":1795337,"toBlock":1795655,"address":[],"topics":[["0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"]],"resultHash":"0x07496dc844fe21c63dd976a681a83d0120c3718c70254eaa30f05e33071c2d5d"},{"fromBlock":6762946,"toBlock":6763024,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x61a8b5e4fadc033572450b206dbd01233204c584426345d1acc9b571c1be8162"},{"fromBlock":2319450,"toBlock":2319538,"address":null,"topics":[],"resultHash":"0x69d8d1fee324e82873d7a12b922e2042de4abd8859978916acf365dbc1e60a73"},{"fromBlock":3381844,"toBlock":3382342,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000301daf80d468510939d4ded583b323dc29759186"]],"resultHash":"0x288826ec2d2fa8b131de3df1f56351c7a2861aa1bb14546b24ada00bbfd9c23b"},{"fromBlock":2685337,"toBlock":2685433,"address":[],"topics":[["0xdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae7"]],"resultHash":"0x33e8995a79e593563d3f80f5cc9c5d13808f1f631f3ffe0b0e7b88873ff119bb"},{"fromBlock":6872591,"toBlock":6872960,"address":["0xf2919afbf712071ddf73c22f0afe8011608e1e9c"],"topics":[["0x8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d546"],["0x0000000000000000000000009228665c0d8f9fc36843572be50b716b81e042ba"]],"resultHash":"0x9ec1dfac7c93cc356b22e2d766058b78f6996535ab0359e845f8c997ad16a544"},{"fromBlock":6456741,"toBlock":6457259,"address":[],"topics":[["0x5f971bd00bf3ffbca8a6d72cdd4fd92cfd4f62636161921d1e5a64f0b64ccb6d"]],"resultHash":"0x79489baf7868be6322aabfa2b17646ef4dcec832010ef4c9111ef3b51016abb0"},{"fromBlock":5420716,"toBlock":5420988,"address":["0x1c7d4b196cb0c7b01d743fbc6116a902379c7238"],"topics":[null,null,["0x0000000000000000000000006fac84fb0cdf5bcc40300dbd3b47d3d918eeee04"]],"resultHash":"0xb89cbd976c1b16a4d7ca15285db0c48b7a78480c400d7cb6313e681c7b21130e"},{"fromBlock":2818512,"toBlock":2818700,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x851effc5d685c784facee8752ef9f38ad01cdc76f94334589a37a3d0aac30cb2"},{"fromBlock":3423749,"toBlock":3423991,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xc245ef6bfc7823613f1ec2e962255b06f02b7bedafe36b34304e7efd1900148e"},{"fromBlock":6453522,"toBlock":6453679,"address":["0xd98b590ebe0a3ed8c144170ba4122d402182976f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xae9e1adc84c3bdf69d9ca9894608ab0b26a52cf37141a9623b8429ecec879e66"},{"fromBlock":1854913,"toBlock":1854993,"address":null,"topics":[],"resultHash":"0x1f9f0b4582633ccd39cfe3da40a3e3afd7ec98b70ba8555079b3ebee8eec2914"},{"fromBlock":5493346,"toBlock":5493420,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x3b8ab7d50fc6afcbe84d2a3a24a691c9120836904219bf824c25c3cafde98e45"},{"fromBlock":3423401,"toBlock":3423699,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8","0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0xe21a673f75a6b9af7e05fd33c2b7654bb7597725e5ca0f33711a81e7fd672426"},{"fromBlock":6456692,"toBlock":6457134,"address":[],"topics":[null,null,["0x0000000000000000000000004200000000000000000000000000000000000007"]],"resultHash":"0xf5f1425fb81e1ce6fed13d68967b279d4bb795d9356f054a82dbc17f521202a7"},{"fromBlock":5978973,"toBlock":5979048,"address":null,"topics":[["0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c","0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null],"resultHash":"0xd066c191c38d881001c7934774411445fde8c1958c4882e94a53098f22d675d7"},{"fromBlock":4524644,"toBlock":4525015,"address":["0x95ff8d3ce9dcb7455beb7845143bea84fe5c4f6f"],"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2"],["0x0000000000000000000000005c4220e10d0d835e9edf04061379ded26e845ba8"]],"resultHash":"0x66debf176104a8ad03f124bdd27607ff95ced007a3f5ff2d89bd4033f42a926b"},{"fromBlock":6453500,"toBlock":6453598,"address":["0xd98b590ebe0a3ed8c144170ba4122d402182976f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xe5db67eb4a08037e976f0d7ed5cc52986dbf21d36f03bd33ed8cd2ddd793883c"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x283cd33d622ca679f2b384940a406998f52cff5121f70ba98068bb41dc52acc6"},{"fromBlock":3423789,"toBlock":3424098,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757"],["0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0x78b7bccb6e71df1213b52f0a4e1e98f339f714b79ef95be1ea0ef41894f3e5cd"},{"fromBlock":1730079,"toBlock":1730168,"address":null,"topics":null,"resultHash":"0x13fad578a8cdb7e6da2256185141844212c30d7b10922aad89e0a4ad82192197"},{"fromBlock":5420816,"toBlock":5420940,"address":["0x1c7d4b196cb0c7b01d743fbc6116a902379c7238"],"topics":[null,null,null],"resultHash":"0x8aac8a3498acc51879c5e6ddbf9095ccf237d229d5ff73f51c215fa619f825ec"},{"fromBlock":6453433,"toBlock":6453732,"address":["0xd98b590ebe0a3ed8c144170ba4122d402182976f"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xe5db67eb4a08037e976f0d7ed5cc52986dbf21d36f03bd33ed8cd2ddd793883c"],null,["0x000000000000000000000000708d8f13492900da663fd2421cbbef1419b2f185"]],"resultHash":"0x5685ce5015d4d51331cee6fe0a3a95f86cc0d44f65ffb60493e971adb2287d72"},{"fromBlock":5493294,"toBlock":5493367,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x23a809ab1e40a2a6168d045320a95a751ac1c26972f66780e08306ce213b1144"},{"fromBlock":6456865,"toBlock":6456936,"address":[],"topics":[["0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972"]],"resultHash":"0xf1609789a30298b9b95080dc4935e591e7b3a185b2a843eb9d0c8619c847f032"},{"fromBlock":3765940,"toBlock":3766025,"address":["0x7d992599e1b8b4508ba6e2ba97893b4c36c23a28"],"topics":[["0x47866f7dacd4a276245be6ed543cae03c9c17eb17e6980cee28e3dd168b7f9f3"]],"resultHash":"0x4538059a2713138e395eebe8e64de79683664552f695f5c8751f543b9464c86d"},{"fromBlock":1873487,"toBlock":1873768,"address":["0xf549af21578cfe2385ffd3488b3039fd9e52f006"],"topics":[],"resultHash":"0xe4d05e93fd6626426e3f070891d068fedaca4918fe4ae92da04f63d7464cd24e"},{"fromBlock":6330387,"toBlock":6330689,"address":[],"topics":[["0x00d05ab44e279ac59e855cb75dc2ae23b200ad994797b6f1f028f96a46ecce02"],["0x00000000000000000000000026280ec2fa5e4987520e4c84d55b7320f1f3c4ce"],null],"resultHash":"0xaadb93d01ea561c20865eef8eb9151a2d317da298cb7df3392cbc33a09c537f9"}],[{"fromBlock":3031192,"toBlock":3031213,"address":null,"topics":[],"resultHash":"0xd36ddeb76f2f417146a5ecccdcbe8c411e339221f82787dbe7399568f1e6febf"},{"fromBlock":5493317,"toBlock":5493327,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0xb94308f05360a2e6f2d9554ea68d630bb8d536e38d639d2443837c8a1b201db4"},{"fromBlock":3393844,"toBlock":3393855,"address":null,"topics":[],"resultHash":"0xbbb6fac5b54a9316e61ab957f73f1c67921800522ba2cd1486ecabbf9f94c76b"},{"fromBlock":3031190,"toBlock":3031203,"address":null,"topics":[],"resultHash":"0x35c6ace8e7c59a4e77306a2f4999f4e99d201f83f29802ecd800d7bddb622225"},{"fromBlock":6339472,"toBlock":6339497,"address":null,"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"],null,null],"resultHash":"0x5e265c018fc7ae7559f3114c5edb74e201b91c1e9a9721113a118b2c6fc2119f"},{"fromBlock":2989372,"toBlock":2989414,"address":null,"topics":null,"resultHash":"0xa3507809e46a6b3ddae1200107d9ac778625bd419eb022f882e29f1ea2e864c7"},{"fromBlock":3323981,"toBlock":3323995,"address":null,"topics":[],"resultHash":"0xda9e518833b1c73b2c9a1b67465a6fe59f76ffdf90bc57e05ccde3bc2c26bb1d"},{"fromBlock":5493329,"toBlock":5493349,"address":null,"topics":[null,["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x5880d5baaf8dbff366de5b8b81e1822a737014a329110b8bb7245eac341a0e2f"},{"fromBlock":6373602,"toBlock":6373608,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x11bb0cf81b0549ca27ff0ac0939ba88b6bc8022a06ad7e8fa331a9e651a8fbbf"},{"fromBlock":5139565,"toBlock":5139590,"address":["0xf68f872f0dde0ec1ba8c28eed9d0674760aa8eb1"],"topics":[["0x838807fe70997cb429689dd35bc6ccb21720aa7d7daac8736b398060104fb0fa"]],"resultHash":"0x45b20509041ba441883718b2bc96cb8755b35e8fe42d7d4b64ef57d5bd0d7adc"},{"fromBlock":3427582,"toBlock":3427593,"address":null,"topics":null,"resultHash":"0x23264b009c5d7e1ffad3059727abd5cb789619b9eb57a784748b93f430eb6b9e"},{"fromBlock":5493326,"toBlock":5493338,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4","0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x11ced34ae0b5e1fd0332dd066fddd61d2919a466e08d689c9f86e89e564f0260"},{"fromBlock":5493314,"toBlock":5493323,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0xdd9025c89cd8cd2bf041f7ac887195a3d0412a16635fa4721b2984c2b4ba5a59"},{"fromBlock":2939170,"toBlock":2939184,"address":null,"topics":null,"resultHash":"0x2bedec7917a150100672e9ebafd77fb649565e339d2194867d891c56a957e60f"},{"fromBlock":5505412,"toBlock":5505423,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],null],"resultHash":"0x88f1fcb15c6a6933066e73c2dfafd3f7b066953f641c54cb4d70670d772eb1f5"},{"fromBlock":5493596,"toBlock":5493634,"address":[],"topics":[null,null,["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x342008a5dfc8e3addb399df7a053cdb67d29f5e794057c7633a4af74208fff5a"},{"fromBlock":5493302,"toBlock":5493312,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b6f4a8dccac0beab1062212f4665879d9937c83c","0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x5ef557ae98fe7bd3f804f0f160364f1d5390bfd5143edf90072c50a74081e56d"},{"fromBlock":2685362,"toBlock":2685410,"address":null,"topics":[],"resultHash":"0x980bd077508d4a95dc9ba6b58877a94d29a821101809a6f046341310f79042aa"},{"fromBlock":5493331,"toBlock":5493340,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x4f560094c3fbcc28232da5a2675552a05a2e9773e0f1861421e4d4495ad15641"},{"fromBlock":5493605,"toBlock":5493630,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x837684b68e3b2a2538435da4fdd43bc83217f972545eccf5e8093f9d8ae010ce"},{"fromBlock":5493347,"toBlock":5493354,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],null],"resultHash":"0x28c0132eefe3dfeb6d79ef524f7d3fd3fbbcd0b4e8ebfab94d6d019706d4e0c5"},{"fromBlock":6379517,"toBlock":6379524,"address":["0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"],"topics":[],"resultHash":"0xca2f2db7bf96efdd9fa08f780598048bff07e7a12423fbfcb6ddfc289e30971c"},{"fromBlock":4637932,"toBlock":4637935,"address":null,"topics":[null,null,null],"resultHash":"0x1fce5b6fd9066042d92f73f2f5c34c74452e089260b4c2aea52ea683174d59f7"},{"fromBlock":5493330,"toBlock":5493336,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0xd276ffc43d3fb16427421d5cc1d7f470f3a1676e146f5171cf4aed92fd313ab1"},{"fromBlock":6064256,"toBlock":6064264,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x40ed5672f93dde0622ebecf50982dd606642833ea51ff7786d2aba394ae35f2d"},{"fromBlock":3765971,"toBlock":3766004,"address":["0x6375394335f34848b850114b66a49d6f47f2cda8"],"topics":[["0x2295930c498c7b1f60143439a63dd1d24bbb730f08ff6ed383b490ba2c1cafa4"]],"resultHash":"0x0b9c8c346932a26a203ec354b870b79a5c5e0fdccecb75e0adad7f4b9684bfb5"},{"fromBlock":3111341,"toBlock":3111370,"address":null,"topics":null,"resultHash":"0x26e9148ef9602f6c47772f64f03eac91d488634ce1c2234c7faeafc9bbf1fc62"},{"fromBlock":3233799,"toBlock":3233808,"address":null,"topics":null,"resultHash":"0xd4e6ef290bb77f92019dd5c05d8b03d8b14dadbc83efeffb1cb2066a6c110742"},{"fromBlock":5493302,"toBlock":5493312,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000b6f4a8dccac0beab1062212f4665879d9937c83c","0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x5ef557ae98fe7bd3f804f0f160364f1d5390bfd5143edf90072c50a74081e56d"},{"fromBlock":5654269,"toBlock":5654302,"address":["0xf1d6d31b577a2e54f6909813bfefcd73b9341f1f"],"topics":[],"resultHash":"0x9f2e3a694c034841722599de72487ff15109109b8adcd0937d6fe7421d055ec7"},{"fromBlock":3024294,"toBlock":3024313,"address":null,"topics":null,"resultHash":"0x37c57273a3d3210babc60ae0cd7da6ee4dd18c3f9588fabf6c02687860981520"},{"fromBlock":4178736,"toBlock":4178738,"address":["0x39e12053803898211f21047d56017986e0f070c1"],"topics":[],"resultHash":"0x3e43e97106f97c72a610c60643827555fce4bc0e33c7b71ad8cf0a2303aa36fa"},{"fromBlock":4534035,"toBlock":4534051,"address":null,"topics":[["0xbb2d4a4c4a679d81940f242e401d2b2cc3383dbcb0ae798c14bd7905b1f6cae2","0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null],"resultHash":"0xa388d799ce609c0db3ef0e43f45510d0128c1747212218956ca1b0634ea313bf"},{"fromBlock":6596502,"toBlock":6596538,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x000000000000000000000000e6a568604b4a93f2b2a8fa0e13920d076c31a757","0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x33b9201ee7a212f4a752879dc366291cc7752dfd15aa88a7146264c80562c7a1"},{"fromBlock":3815100,"toBlock":3815122,"address":["0x6375394335f34848b850114b66a49d6f47f2cda8"],"topics":[],"resultHash":"0x8e2ce600397f5af05f0f798002646b9be85d60dda8eb9d61934e62557008c4e5"},{"fromBlock":5493307,"toBlock":5493323,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b6f4a8dccac0beab1062212f4665879d9937c83c"]],"resultHash":"0xfb998d99a181a60b261cf27353c47fca7cfd5e841919360f0068d0a6793d922e"},{"fromBlock":5493605,"toBlock":5493630,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x837684b68e3b2a2538435da4fdd43bc83217f972545eccf5e8093f9d8ae010ce"},{"fromBlock":2034342,"toBlock":2034364,"address":null,"topics":null,"resultHash":"0x4fb18033d4a0bbf5870f2158a351e7470be5950796eb9a67c1cb42bd2db102aa"},{"fromBlock":5550783,"toBlock":5550827,"address":null,"topics":[null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x4fa75b33bc49790dbc31ec843ea9aad04867a756e64b7e5ccdc7a173a9a2143c"},{"fromBlock":5493310,"toBlock":5493322,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b6f4a8dccac0beab1062212f4665879d9937c83c"]],"resultHash":"0x14ab4073f5be0f030393deb0d0bc83771ca91e3ccaa349819155f8757cb27706"},{"fromBlock":6269499,"toBlock":6269544,"address":[],"topics":[null,null,null,["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0xfc9cf595fb3b939d948fb1b0246c0a7d6e7a6190d428cbf37192f53c37758653"},{"fromBlock":3323979,"toBlock":3323992,"address":null,"topics":[],"resultHash":"0xa6cdd185775bb8eafa2c5a537a330bf6ba65e3fbeb547f711aa8584a43c21831"},{"fromBlock":6762951,"toBlock":6762990,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x443a4ee09e771954cb46ef380cd401477a7e2e61a079e9f84e82ffcf57dd77b4"},{"fromBlock":3031198,"toBlock":3031209,"address":null,"topics":null,"resultHash":"0x7d3d0eb41b2955b9d3867a14cd0d2a416ac08ad87594bd8b37e89fa3dcf296d0"},{"fromBlock":3586342,"toBlock":3586357,"address":null,"topics":null,"resultHash":"0xf6d4caba2d82acf0faf85beca1563374ba3a224aa63a4a90d83aa009b74a1c1c"},{"fromBlock":4515314,"toBlock":4515320,"address":null,"topics":[null,null],"resultHash":"0xc9b4763a679067ccbde7c239fb492e950efe447a5d0c954957e85c15c9975336"},{"fromBlock":6872886,"toBlock":6872928,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"]],"resultHash":"0x245b8131bb7190efc0dd72de0f5c429afb62a017a42d24efd8ee54bc576b5f2e"},{"fromBlock":5493341,"toBlock":5493354,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],null],"resultHash":"0xcad906a09fce6f97a5cf8e4e7e63d3037177fb548497ccc5e43e268087a77e35"},{"fromBlock":3815077,"toBlock":3815097,"address":["0x6375394335f34848b850114b66a49d6f47f2cda8"],"topics":[],"resultHash":"0x7aeacbe9393cba82f217ff13dcc2ebc62c088f6745b79354295c50e3030b1396"},{"fromBlock":3625839,"toBlock":3625847,"address":null,"topics":null,"resultHash":"0x926644cf1e9aa917d9aad888b9d92a8dd448f35122f67090de164301a9ffabfb"},{"fromBlock":5493331,"toBlock":5493340,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0x4f560094c3fbcc28232da5a2675552a05a2e9773e0f1861421e4d4495ad15641"},{"fromBlock":6680565,"toBlock":6680567,"address":["0x800ec0d65adb70f0b69b7db052c6bd89c2406ac4"],"topics":[null,null,null],"resultHash":"0xff5658503ee1fedc05d1d2e8ba2cf93d6fd17afb1f77acf7e7970315411243c9"},{"fromBlock":5493616,"toBlock":5493622,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[null,null,null],"resultHash":"0x100e14a4ad45a3d43fece09adbe8055d114838ad0c5e89587e888da2da14a01d"},{"fromBlock":5493293,"toBlock":5493314,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x0000000000000000000000000000000000000000000000000000000000000000"],null],"resultHash":"0x01a50b95d8e03e26ac4ba52e0b17590adb593ea91dfe3d1a13bfd4cfc6dddf35"},{"fromBlock":5493339,"toBlock":5493363,"address":["0x40001ecac527d825d8d73f50ceab01925676099b","0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[null,["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x92582f6b68f65f9c06d90292600b8b65399fc6c03744fa752435b50dec7de2c2"},{"fromBlock":5493331,"toBlock":5493357,"address":null,"topics":[null,["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x2f26cd5f0094a8805f350cfcedc5aa7340740d2187568033dc714af950498030"},{"fromBlock":2598719,"toBlock":2598757,"address":null,"topics":null,"resultHash":"0x3a0acb66a0b06141df598a78244b4e8e2f081bfac02109711ac8f32da7eea34f"},{"fromBlock":3323980,"toBlock":3323993,"address":null,"topics":null,"resultHash":"0x4c4a84cb751db0c3630e18d1f30b2aad7c204e9fb54010de32c0514d7611ee1f"},{"fromBlock":3382071,"toBlock":3382082,"address":null,"topics":[],"resultHash":"0x78f9d9d08ed9a3991add11bcfedb54869aa3f435641a6f792c6e8dc3935462f8"},{"fromBlock":5493306,"toBlock":5493333,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05","0x0000000000000000000000005b3f3266a9fcce9dfd996cd6f08d8513cb021062"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0xc0e01946f6ff0576963dfd62879a6a2d56e3c3618a80024057887e46860a222a"},{"fromBlock":5493303,"toBlock":5493316,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000b6f4a8dccac0beab1062212f4665879d9937c83c"]],"resultHash":"0x72836c9def3c2767c27d1da6836d08f4eefc1405e37b95be56a2500e3b0695f0"},{"fromBlock":3792248,"toBlock":3792284,"address":[],"topics":[null,null,["0x000000000000000000000000572af1afa5afcfc6fdf1eb2913aa4463037860e8"]],"resultHash":"0xb431ba440baa3b59ea1c59a1d240cfa18ac70519da584de0e6f509373c07f009"},{"fromBlock":3323984,"toBlock":3323991,"address":null,"topics":[],"resultHash":"0xf33f353e4d570634fd5eb13a68b89b8b618c18cca578c90e390d8efb20f786ec"},{"fromBlock":3031191,"toBlock":3031213,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x22388408f33994428f5c2654b0106389f94ba29c7297788ea1ede484c75d94b1"},{"fromBlock":5493342,"toBlock":5493348,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x32eb4a5a4d836f002b42e42ed882adae5044f70d9909e345910548da61327a5a"},{"fromBlock":5493310,"toBlock":5493330,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0xd4dce78e5596fe7f78b7ec121c56a023f41dc3b53c61130454843bb76fe8ad99"},{"fromBlock":5654229,"toBlock":5654250,"address":["0xf1d6d31b577a2e54f6909813bfefcd73b9341f1f"],"topics":[],"resultHash":"0xa320ac5e74496483f37cf0c4585d7be73d50308ba4308b70d1549d357b4344fa"},{"fromBlock":3957469,"toBlock":3957537,"address":null,"topics":[null,null,null,null],"resultHash":"0x945421a800835e7681cf29beea43c5dae6bdb302bd77057d9d18eb5435a4a1e0"},{"fromBlock":7376209,"toBlock":7376215,"address":[],"topics":[null,["0x0000000000000000000000000000000000000000000000000000000000002b74"]],"resultHash":"0x5d64b3e32a1a21403ee33c8cd4a4a3054b0290ee4a41158943af1d2f32cf7991"},{"fromBlock":3415430,"toBlock":3415451,"address":null,"topics":[null],"resultHash":"0xc2a666f730140d3ad0e219f1ab6b3cad0b0e46a781020208987a95b13731e21e"},{"fromBlock":3323980,"toBlock":3323993,"address":null,"topics":[],"resultHash":"0x4c4a84cb751db0c3630e18d1f30b2aad7c204e9fb54010de32c0514d7611ee1f"},{"fromBlock":5493282,"toBlock":5493339,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x0eb3848b06830ff718d7f37511de4e113067755ec3d6e826dec112b2cf253ac0"},{"fromBlock":5493330,"toBlock":5493345,"address":null,"topics":[null,null,["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0xcf8d2a4fc3238e85ce808adf99ce726b16dd0a365d60a4232692a952b79e93c1"},{"fromBlock":3814610,"toBlock":3814620,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x64369a70df6cf631cb3191630bb3c79917de4528e05cd243a62984496d15149c"},{"fromBlock":3445845,"toBlock":3445853,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x61d93f45d87fad47230c35af30f7309667b86d58034aeacf0f615a9649a7b4c8"},{"fromBlock":5493301,"toBlock":5493355,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05","0x0000000000000000000000005b3f3266a9fcce9dfd996cd6f08d8513cb021062"],["0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x3bbeefb89ca10686e5f3fd5024124e53c35f36ca92743ee7292b0f1f58b732ae"},{"fromBlock":5505409,"toBlock":5505427,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000b6f4a8dccac0beab1062212f4665879d9937c83c"]],"resultHash":"0x8977d4a7814d57ab342654f731a641fa0e4dae0fa4690e3c9c007c74c4cbf3e3"},{"fromBlock":3029501,"toBlock":3029534,"address":null,"topics":null,"resultHash":"0x1eb691e7a65ed03bf92f3b262b8d2e789bd5d4022d2dbfe6123c847752f89a3f"},{"fromBlock":7321450,"toBlock":7321480,"address":["0xea58fca6849d79ead1f26608855c2d6407d54ce2"],"topics":[],"resultHash":"0x102bb5ee57555f26557be81ad83f2ecee74a14c2be509f0352f60a99fefd39eb"},{"fromBlock":6222643,"toBlock":6222651,"address":[],"topics":[["0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"]],"resultHash":"0x47c10465fb7398387112a36bb992803dec8e5508a4fa68fbd7b04b366c327d67"},{"fromBlock":3765977,"toBlock":3765996,"address":["0x6375394335f34848b850114b66a49d6f47f2cda8"],"topics":[],"resultHash":"0x18ffb55c84ed84c9f7b5a05c666c5ef5d0f1838ea306c31292cbb1d052221f12"},{"fromBlock":5411960,"toBlock":5412029,"address":[],"topics":[["0xa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2"]],"resultHash":"0x5cdfbabb65fa946373787a22c67dc6a97929c3140c940b16072e068fe248e03d"},{"fromBlock":5493332,"toBlock":5493341,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"],null,["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0xd334b0ee8c494f9667978abf688c3cc583215131f2040d80149817ca7a7ab047"},{"fromBlock":5493312,"toBlock":5493322,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x6521f31c4b64bcf3de19e45743925c73ca398b5b691c4abee40cd39862b54909"},{"fromBlock":3423625,"toBlock":3423664,"address":["0x53844f9577c2334e541aec7df7174ece5df1fcf0"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x5420a3c09990469a4330a55fdce7e00e5fbc06666e220014f4db37d5c15092e6"},{"fromBlock":3480792,"toBlock":3480813,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0xf14caf0fe9be0fe65bb040d55bdc85a39acbb901fe82f605e2b7cda7b8e75fd4"},{"fromBlock":6262696,"toBlock":6262702,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0xcadd21bd5ac71bde6732cc4afa7a0891e270cee4a1ee7d86eec03161e8b7272b"},{"fromBlock":5493320,"toBlock":5493326,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"]],"resultHash":"0x6f6d68deae4494b3ffb4969e22e7965bf982a785de36fdff2e3d08b28da654a7"},{"fromBlock":6610820,"toBlock":6610824,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x00d05ab44e279ac59e855cb75dc2ae23b200ad994797b6f1f028f96a46ecce02"],null,null],"resultHash":"0x52c67010783d267bb01a96ecf4348ba18266ba3171f211adf2e5b101ff43cbc0"},{"fromBlock":2939169,"toBlock":2939192,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xc0ca92c9f1e3b5944d7b16db06e0cdba3157c040ea0a2817826ee1480a30e01c"},{"fromBlock":7370181,"toBlock":7370240,"address":["0x5500e5f864d07a7026d9abc7ad49e2364987ffbf"],"topics":[["0xcf8c667058d3773bf421bedb38a6938759b277329bac254c37f52f8b252548e2"]],"resultHash":"0xd5bd2f8de5f9fef3265a08ee2157bc495e4293f9d9be0c86215615098e62824a"},{"fromBlock":2768957,"toBlock":2769013,"address":null,"topics":null,"resultHash":"0x0063bd8c580193ac10e22d3358f495872a0ecc87541087009d68593f2e177320"},{"fromBlock":5493298,"toBlock":5493304,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0xe2477957a48e5c442d27ba7ab0674647de6a9d79eeab88965979f0e2169cc0d4"},{"fromBlock":5493314,"toBlock":5493323,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0xdd9025c89cd8cd2bf041f7ac887195a3d0412a16635fa4721b2984c2b4ba5a59"},{"fromBlock":3814619,"toBlock":3814636,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x652da9f1d878e182dd5d3ddf241d455d2de94664a708476d392dfea7e77a7c7a"},{"fromBlock":5599488,"toBlock":5599496,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x2c457e0c3c6bc80a75c6b3e2fe31fde6c9f8b805495ba031b21d592906dd0728"},{"fromBlock":5493341,"toBlock":5493354,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0xcad906a09fce6f97a5cf8e4e7e63d3037177fb548497ccc5e43e268087a77e35"},{"fromBlock":5493294,"toBlock":5493305,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,["0x000000000000000000000000b6f4a8dccac0beab1062212f4665879d9937c83c"]],"resultHash":"0xd58974c47e4d8b8f5672bf189144ed5f90fc93c124d9fde51626ee31b5a98b2a"},{"fromBlock":2989393,"toBlock":2989442,"address":null,"topics":[],"resultHash":"0x56a9b7f938a39a602fb6a7f7f83ea63553eb02cbce0a8da9b9a39bc55aeec7ae"},{"fromBlock":4574102,"toBlock":4574112,"address":["0x09547e68ce13fdecb5bf52fd17379fffa97cb797"],"topics":[],"resultHash":"0x5d5813acb1ef3de71c45d9fce4828ff81daa3852649b3bd7b6b869eb969e5b11"}],[{"fromBlock":6565905,"toBlock":6565906,"address":null,"topics":null,"resultHash":"0xaf76e893cb9ce0d861aacc543bc4d3766b1d8b62396e8a52da14d30c2ae972aa"},{"fromBlock":5242179,"toBlock":5242179,"address":null,"topics":null,"resultHash":"0xf4e66bea5f947f9cd2848e14eda0f260c75cfa729e3669956ed136d2b6ded5b1"},{"fromBlock":5654231,"toBlock":5654232,"address":null,"topics":[],"resultHash":"0x6517f9d2db7ac2dc33fe98ad35ce7e6cda037eb01483626bd9272c024a9e6a26"},{"fromBlock":4432894,"toBlock":4432895,"address":null,"topics":[null],"resultHash":"0x066879d2ba5c1a81b347a6630bf959ab6da137982a119d4d77cb3c6031080ba4"},{"fromBlock":4251794,"toBlock":4251800,"address":null,"topics":null,"resultHash":"0x92c8fd918cb78a06e121573358fa3b43e1728410cdf300e6caa574fb1de7440a"},{"fromBlock":5599361,"toBlock":5599363,"address":null,"topics":[null,null,null],"resultHash":"0x7534c20335ce21e0413d903e2d04caa5390e63c20eece7ca8f150167b2a5ac91"},{"fromBlock":6456884,"toBlock":6456885,"address":null,"topics":null,"resultHash":"0xb05d0123c35050017f7b44d1b533bb360c2227aa42c9dd6a7cbb6612738fef27"},{"fromBlock":3801924,"toBlock":3801928,"address":null,"topics":null,"resultHash":"0x713b9f4bd0e0b141472d951f76beb5393b268ee98230c0111763bceb5fbcaaf9"},{"fromBlock":7572250,"toBlock":7572253,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xc6aa420ff5d9e4c57a34d5d90e5819ac96ad4598001057063cabcbc18902b2ba"},{"fromBlock":2407656,"toBlock":2407659,"address":null,"topics":null,"resultHash":"0x727cfec79e61c0f79e9adbf01e05eb8e53a412688b6facbb1c86c5f9a44dee0f"},{"fromBlock":5034145,"toBlock":5034145,"address":null,"topics":[null],"resultHash":"0xd9b02b55f4445129c0d6572b2b2a68f3fbda8ad96f6ff3ecdf19299bed44e6e1"},{"fromBlock":6745063,"toBlock":6745064,"address":null,"topics":[null,null,null],"resultHash":"0x9690f9fc27dc66103468054b21bdf56d05a541303e67c33421ab1466d098f516"},{"fromBlock":4040372,"toBlock":4040373,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0xe613bd44a92e7a2339ed49a4a22b914e5ebc6f9c940f53729af41c250c5631cd"},{"fromBlock":6837588,"toBlock":6837588,"address":null,"topics":null,"resultHash":"0x0d84cdef0c770630787cb4d4da2ee619c5283372d5cfc30c8d3ad04b7fc4673f"},{"fromBlock":5493364,"toBlock":5493371,"address":["0xaee8e96bed6c5445658447fdee8edd12a1fd79b4"],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,["0x000000000000000000000000b6f4a8dccac0beab1062212f4665879d9937c83c","0x000000000000000000000000b31c077c99e0d61305fcd873a39f974d13bc773c"]],"resultHash":"0x5ccfe5b1ffdab03c32d580b2ee6ce0fd1a984e9e16f0a9e264ee8ffc07e5c87b"},{"fromBlock":5405140,"toBlock":5405142,"address":null,"topics":[],"resultHash":"0xe2a9e7f0a4e7bc9b3a03b74872427252370377ae830a6a33a14bbca5cc7f20d6"},{"fromBlock":5139583,"toBlock":5139583,"address":null,"topics":[],"resultHash":"0x42c4b1d2cea373114f509dfe5f7a3510bfc49b660712f93228591aba2dde000a"},{"fromBlock":7118886,"toBlock":7118887,"address":null,"topics":[null,null],"resultHash":"0x80daa9d128f3a724c21195ace784dea18bc9d40ca1666642129af707e15e6914"},{"fromBlock":6197749,"toBlock":6197749,"address":null,"topics":[],"resultHash":"0x3f5e8ec8cdd98b45f400793ac0314016aaa429e6b2107ca5224663fabad82fc8"},{"fromBlock":5139583,"toBlock":5139583,"address":null,"topics":[],"resultHash":"0x42c4b1d2cea373114f509dfe5f7a3510bfc49b660712f93228591aba2dde000a"},{"fromBlock":4040372,"toBlock":4040373,"address":["0x958b482c4e9479a600bfffddfe94d974951ca3c7"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]],"resultHash":"0x12ce9c8987085cecca97dfead91c5aece1b70a96dc54643955609da265916a7c"},{"fromBlock":6269386,"toBlock":6269386,"address":null,"topics":null,"resultHash":"0xf1036eef997cf51ecb1978006f73fa844c73122f7ecdfbd1115f824cb1e4e8e4"},{"fromBlock":7037380,"toBlock":7037381,"address":null,"topics":null,"resultHash":"0xd458f5a3cbb9466665d117f58c99e9512ffde0a90103af37bb0877aeac43e8a8"},{"fromBlock":3685673,"toBlock":3685674,"address":null,"topics":null,"resultHash":"0x1e23f4f8b470c7b3d4fe0f4aa14723e890c1649f1caa6892ec4183e76801aa69"},{"fromBlock":4554814,"toBlock":4554814,"address":null,"topics":[],"resultHash":"0xfa6b462843ab60dad05863af3a86e640cd90c845990cacfef836a722579aa2c3"},{"fromBlock":4257517,"toBlock":4257517,"address":null,"topics":null,"resultHash":"0x1068639788247dedb33968ed12137ed699a790af76b4b6cda5db9f80962ec5f8"},{"fromBlock":6291250,"toBlock":6291250,"address":null,"topics":null,"resultHash":"0x1fe751bfa3e8d81bfaa8c0acc793b685d3703db2a35f0e5ee955471bcd543556"},{"fromBlock":5493617,"toBlock":5493618,"address":null,"topics":[null,null,null],"resultHash":"0x1112009917007fdb935408783295b129a085732e58661623e7460d7967166a1e"},{"fromBlock":5654275,"toBlock":5654276,"address":null,"topics":[],"resultHash":"0x7d0f31a63e57ee6ab990107cdb64aa683592d58bba7eef1ffc3131e1a714e337"},{"fromBlock":6449052,"toBlock":6449053,"address":null,"topics":null,"resultHash":"0xc38a6c69d734cd9788afef915bafe6b6dbf9fe29c9e10e7d4fe555f429844b1d"},{"fromBlock":3711954,"toBlock":3711955,"address":null,"topics":[null,null],"resultHash":"0xbcafb9bdaef4e26e3c7218c35fd0257ca81e9d8bad760d1d180444da6cb8fefa"},{"fromBlock":4349153,"toBlock":4349153,"address":null,"topics":null,"resultHash":"0xf475b96e6656fe43f673ffd25feccb5fb162fab8d79b955a851327187eee5b75"},{"fromBlock":5360198,"toBlock":5360198,"address":null,"topics":null,"resultHash":"0xd53fee7fa1a4f0ada71be57fcf9098893db2a0e3ea187a63d0e5cc2e9074504e"},{"fromBlock":5779938,"toBlock":5779944,"address":[],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null,null],"resultHash":"0x65c1dec6584d9b772fbe2070fdc7345edd912069cf46b2550c305cae65bd5fd9"},{"fromBlock":5493617,"toBlock":5493618,"address":null,"topics":[null,null,null],"resultHash":"0x1112009917007fdb935408783295b129a085732e58661623e7460d7967166a1e"},{"fromBlock":5493298,"toBlock":5493300,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],null,null],"resultHash":"0x91f77fb657d475747e03a6a44c6219ddcf317f04a8bc29d20a7d7059cb71cf9b"},{"fromBlock":5493325,"toBlock":5493329,"address":[],"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4"]],"resultHash":"0xc0e1e36cd6258ffd011c45cd804536248494dc0e73f239898f06237a6366500d"},{"fromBlock":4584825,"toBlock":4584826,"address":null,"topics":[null,null,null],"resultHash":"0x5f1a9ebbb2c9f64eeda1553df9d3717c188dc91f2d99046638442e5379183c56"},{"fromBlock":5626614,"toBlock":5626615,"address":null,"topics":[null,null],"resultHash":"0x76fe5e0369d87226c31a57b6da2ec6bf2ea654185c12287a7486f035968d9de6"},{"fromBlock":4554814,"toBlock":4554814,"address":null,"topics":[],"resultHash":"0xfa6b462843ab60dad05863af3a86e640cd90c845990cacfef836a722579aa2c3"},{"fromBlock":5139515,"toBlock":5139516,"address":null,"topics":[null,null,null],"resultHash":"0x7985983304ce909a7b59120c03d64858b6d844f63a95f49d8230135d6837d58b"},{"fromBlock":6480761,"toBlock":6480763,"address":null,"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e"],null],"resultHash":"0xb8e9bf1dbb746c1072b8fc11a2cb8477056becb669e1c99ad0a7acfc1657bc08"},{"fromBlock":6769658,"toBlock":6769659,"address":null,"topics":null,"resultHash":"0xf5f2071f52ca26daa5396956de118ce6e8387f1528b4967e8fc75d029827cb2e"},{"fromBlock":5493325,"toBlock":5493327,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],null],"resultHash":"0x66cac069aae581cd319e9a1da5c759bdada66aed1ddd298757690cd700a7de60"},{"fromBlock":5493321,"toBlock":5493328,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0xe37d302cd4d8b94b8c8118eacac9b9846717bfd87220e954e9726e1e13aa3a81"},{"fromBlock":3323134,"toBlock":3323139,"address":null,"topics":[null,null,null],"resultHash":"0x22cc6efc06476d95c94ed208e2b28ab120e9f08af1cd4883f08ed1175d0d17d1"},{"fromBlock":7118886,"toBlock":7118888,"address":null,"topics":[null,null],"resultHash":"0x4b98b93f63a9b3f7e09797a39e0db77e23ea98037f7b9e3d5688aac9a3c569a5"},{"fromBlock":6884098,"toBlock":6884098,"address":null,"topics":null,"resultHash":"0xbd77cc5638889bcf6e26ca55d192270b7610a5519832069dbeb16c12b779d351"},{"fromBlock":6443316,"toBlock":6443317,"address":null,"topics":null,"resultHash":"0xf30e2313713d397591bc207e3351535129e1bbb9b41735ea76c2ba6f181bcc0a"},{"fromBlock":6569037,"toBlock":6569038,"address":null,"topics":[],"resultHash":"0x17030ad9a65abdc3fd4cc1cdcac568e62e3d63c4631e8a5f5030a78a09eec33a"},{"fromBlock":3660928,"toBlock":3660929,"address":null,"topics":[],"resultHash":"0x53520a227fd9c8c22d4b8911c68453708b30c9567da83f5e6e6be795b86e43bf"},{"fromBlock":4864076,"toBlock":4864078,"address":null,"topics":[],"resultHash":"0xea58d8d378952057be211f23df0b6f96ede9cae714eeef0c35126a4fb25cf45d"},{"fromBlock":7027513,"toBlock":7027513,"address":null,"topics":null,"resultHash":"0xb561f7dcf5e1d075fe4850ee4b907080b0f6714d3df137d7be222c3ae8f89575"},{"fromBlock":5979222,"toBlock":5979223,"address":null,"topics":null,"resultHash":"0x3e44433a2d3285cd899585eb54b1062f29c57a8403e79d081de2d5393a42d044"},{"fromBlock":4065028,"toBlock":4065029,"address":null,"topics":[],"resultHash":"0xe9c84b484160004dc794d61ac80dd4cb705c7a1d3b19142b6c9f5fddcb924d90"},{"fromBlock":7717495,"toBlock":7717495,"address":null,"topics":null,"resultHash":"0xf8ff48953fbc7fcdce27cd136e6659554a8f3f5331b2f2d3026e529383e2a6d3"},{"fromBlock":5493325,"toBlock":5493328,"address":["0x0305ea0a4b43a12e3d130448e9b4711932231e83"],"topics":[["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],null],"resultHash":"0x2734a9bfaf05e6f6be37ba94602d9c19a890ea12c8b965459d542dee388f23b5"},{"fromBlock":4574105,"toBlock":4574105,"address":null,"topics":null,"resultHash":"0xefa9b35a2c9b47525943d8fe99f856b9b1abfeee2c7b1b31a3c915b2fe75f005"},{"fromBlock":7572251,"toBlock":7572251,"address":null,"topics":[null],"resultHash":"0xd0d2123b2d33c47b334b8966028b999ee3c4c020ddfe9278c1a5a001f4ddd9cb"},{"fromBlock":6262696,"toBlock":6262696,"address":null,"topics":[null],"resultHash":"0x76931464d54a710c3a3f062a1c87e471c338dcfa6371d5d5d9bf7bbd3333239a"},{"fromBlock":6565905,"toBlock":6565906,"address":null,"topics":[],"resultHash":"0xaf76e893cb9ce0d861aacc543bc4d3766b1d8b62396e8a52da14d30c2ae972aa"},{"fromBlock":6205025,"toBlock":6205025,"address":null,"topics":[],"resultHash":"0x3f700dc32fc073b0559ce5e60f2ea24e1ae29013c8f4730aaa237fa27380f7c0"},{"fromBlock":6717558,"toBlock":6717561,"address":null,"topics":[null,null,null],"resultHash":"0xaacb2d01ee893d2560dc74c80ed7fe2bf3ae2f0d84980ea7d3b1ada22160efc7"},{"fromBlock":5493303,"toBlock":5493303,"address":null,"topics":[null,null,null],"resultHash":"0x42b1d4e0a9db338433d542f2f0929051d7d2230518df015af6b5bfce600be042"},{"fromBlock":6197749,"toBlock":6197749,"address":null,"topics":[],"resultHash":"0x3f5e8ec8cdd98b45f400793ac0314016aaa429e6b2107ca5224663fabad82fc8"},{"fromBlock":7616944,"toBlock":7616944,"address":null,"topics":null,"resultHash":"0x1b1b020e0c4523eb31378e7ad39cce1f631ee18d6666ff7d1093ecaf85efe953"},{"fromBlock":7580259,"toBlock":7580259,"address":null,"topics":[null,null],"resultHash":"0x5d0800e2b672a54de565351b3f17a374ec7617dec7f19314a12b02344144bc44"},{"fromBlock":3660929,"toBlock":3660930,"address":null,"topics":[],"resultHash":"0xeeb27b76a1e3e209f72948800327f0fae51b0f58958b8b8ef93ecba29265f6af"},{"fromBlock":5712350,"toBlock":5712351,"address":null,"topics":[null,null],"resultHash":"0xa8b147b8117ac09a555f158d147ff287c749be54954f82daa6d4ecf98d9c72c9"},{"fromBlock":6197749,"toBlock":6197749,"address":null,"topics":null,"resultHash":"0x3f5e8ec8cdd98b45f400793ac0314016aaa429e6b2107ca5224663fabad82fc8"},{"fromBlock":7370203,"toBlock":7370203,"address":null,"topics":[],"resultHash":"0xcc398610f7d47312132e785062dfad562d65ef2cc3700d9d24e10bbba0a737ba"},{"fromBlock":4584824,"toBlock":4584825,"address":null,"topics":[null,null,null],"resultHash":"0x7642c78ad6110d34a6c23e18b783ec80ef86b87fe556da33e9ca1c67ed7909ad"},{"fromBlock":6301968,"toBlock":6301968,"address":null,"topics":null,"resultHash":"0x146c59d9cf24837378452579154cd01004c0dab6970880a52349bcb9c6f89d19"},{"fromBlock":4341355,"toBlock":4341356,"address":null,"topics":null,"resultHash":"0x164219d00b3d20a89cb4d4d8d1ecd859191605665e3ccfe3d01f9b1f29ad8b63"},{"fromBlock":3903294,"toBlock":3903301,"address":null,"topics":[null,null,null],"resultHash":"0xde11c34087aad96fcb81d2ac23d42e2fd72d9f95c2282c7689ec74fe9759586e"},{"fromBlock":4811912,"toBlock":4811915,"address":null,"topics":[null,null],"resultHash":"0x063cf752dd50e421f82909fa47fe0ff93141d7fb38bb28e1d9a452ca90485765"},{"fromBlock":3510475,"toBlock":3510477,"address":null,"topics":[null,null],"resultHash":"0x64b8dbe61dc24b0efdb602504e8114ee91c4e78ed13dea93deb3547402c4d99a"},{"fromBlock":3660928,"toBlock":3660929,"address":null,"topics":[],"resultHash":"0x53520a227fd9c8c22d4b8911c68453708b30c9567da83f5e6e6be795b86e43bf"},{"fromBlock":6291406,"toBlock":6291406,"address":null,"topics":[],"resultHash":"0xbbb0336986caccf3fb9da71441f2c6a65ca254c3c6c9c7e877b3144de9edce0f"},{"fromBlock":7376212,"toBlock":7376212,"address":null,"topics":null,"resultHash":"0x8ec658d95d64ad6fd6f112d9e1ede080c75686d93ee6cab5ed331191073bfc80"},{"fromBlock":4347818,"toBlock":4347819,"address":null,"topics":null,"resultHash":"0xfe4dcf817b71cdee584c2b71cb2fd4dd3976583e2416f8a45cb88964065fbff2"},{"fromBlock":6222647,"toBlock":6222648,"address":null,"topics":[],"resultHash":"0x9268c68b4b85c2970a071fddd3c0223ffbf3bb9212ec8bb9a62e14894fa55416"},{"fromBlock":3465581,"toBlock":3465582,"address":null,"topics":null,"resultHash":"0x6ee80d97ad18f96d4c9319b33c3a9183a257ae69fa33121c4aa69c2c37e5d67a"},{"fromBlock":3757519,"toBlock":3757520,"address":null,"topics":null,"resultHash":"0x8fc77c06bbb1a80ee802733e3442f05efe8bb687b957a38c34932073754d123b"},{"fromBlock":7613871,"toBlock":7613873,"address":["0x6866b4923fc3fe89ac10b3ef0ab7e9ef5fc00dca"],"topics":[],"resultHash":"0x67ecc24faa016d9194ef4f74e1ab3b86ca0a53515e963234e279dde6004f87e0"},{"fromBlock":5654275,"toBlock":5654276,"address":null,"topics":[],"resultHash":"0x7d0f31a63e57ee6ab990107cdb64aa683592d58bba7eef1ffc3131e1a714e337"},{"fromBlock":5626614,"toBlock":5626615,"address":null,"topics":[null,null],"resultHash":"0x76fe5e0369d87226c31a57b6da2ec6bf2ea654185c12287a7486f035968d9de6"},{"fromBlock":6569037,"toBlock":6569038,"address":null,"topics":null,"resultHash":"0x17030ad9a65abdc3fd4cc1cdcac568e62e3d63c4631e8a5f5030a78a09eec33a"},{"fromBlock":6456958,"toBlock":6456959,"address":null,"topics":[null],"resultHash":"0xc7b2c0861416cd76d05ba982d2ac458dd333fdf0a71e069c9a0a2f3daa0be58c"},{"fromBlock":7370203,"toBlock":7370203,"address":null,"topics":[],"resultHash":"0xcc398610f7d47312132e785062dfad562d65ef2cc3700d9d24e10bbba0a737ba"},{"fromBlock":3660929,"toBlock":3660930,"address":null,"topics":null,"resultHash":"0xeeb27b76a1e3e209f72948800327f0fae51b0f58958b8b8ef93ecba29265f6af"},{"fromBlock":3628313,"toBlock":3628313,"address":null,"topics":null,"resultHash":"0x2428b225b8eab790e2af04f4c55bab2cdf9ea859e054ef0190c86492dc4e88be"},{"fromBlock":7572251,"toBlock":7572251,"address":null,"topics":[null],"resultHash":"0xd0d2123b2d33c47b334b8966028b999ee3c4c020ddfe9278c1a5a001f4ddd9cb"},{"fromBlock":5493324,"toBlock":5493330,"address":null,"topics":[["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"],["0x00000000000000000000000019c7680f666e51a6086c270e2aa2a517ae585d05"],["0x000000000000000000000000aee8e96bed6c5445658447fdee8edd12a1fd79b4","0x000000000000000000000000aabb8c0deb1270151b9b0776bbf9c890cd877e67"]],"resultHash":"0x6abb0ecbfeba3159b9f0a814a1ef9d99db2f48afbf20febf8edaf1e4e0752680"},{"fromBlock":3765989,"toBlock":3765990,"address":null,"topics":[],"resultHash":"0x50a0b7dd015eb4b34bc4a3182071c7b85442fe8bd5276e51d0bcdc0531420c4f"},{"fromBlock":6306764,"toBlock":6306764,"address":null,"topics":null,"resultHash":"0x3b10108fec0249fe6669e75d90ae9fe99511de1e54d36b4769a6d9bcdeabea77"},{"fromBlock":4341448,"toBlock":4341448,"address":null,"topics":null,"resultHash":"0x4478b7691f0e2950791ef90b6e326c57fdc3b15adfae9f9f2ffaabcaad42ea05"},{"fromBlock":5963332,"toBlock":5963333,"address":null,"topics":null,"resultHash":"0x3dac6cf693b06b72c6bae99d03194cf1c9e1294f71b4d7bcea17799dc565a522"},{"fromBlock":5654245,"toBlock":5654245,"address":null,"topics":[],"resultHash":"0xd04aa18b27effaca9d8ad1e479408117ef5961984e14e1f256771903ec7b45fd"},{"fromBlock":6425793,"toBlock":6425794,"address":null,"topics":null,"resultHash":"0x8eb1acbb576fd5c348ef3a84783996e2319adf028906a09c334067b13907cb2a"}]] diff --git a/cmd/workload/queries/history_mainnet.json b/cmd/workload/queries/history_mainnet.json new file mode 100644 index 0000000000..69382381d4 --- /dev/null +++ b/cmd/workload/queries/history_mainnet.json @@ -0,0 +1 @@ +{"blockNumbers":[0,10965,21930,32895,43860,54825,65790,76755,87720,98685,109650,120615,131580,142545,153510,164475,175440,186405,197370,208335,219300,230265,241230,252195,263160,274125,285090,296055,307020,317985,328950,339915,350880,361845,372810,383775,394740,405705,416670,427635,438600,449565,460530,471495,482460,493425,504390,515355,526320,537285,548250,559215,570180,581145,592110,603075,614040,625005,635970,646935,657900,668865,679830,690795,701760,712725,723690,734655,745620,756585,767550,778515,789480,800445,811410,822375,833340,844305,855270,866235,877200,888165,899130,910095,921060,932025,942990,953955,964920,975885,986850,997815,1008780,1019745,1030710,1041675,1052640,1063605,1074570,1085535,1096500,1107465,1118430,1129395,1140360,1151325,1162290,1173255,1184220,1195185,1206150,1217115,1228080,1239045,1250010,1260975,1271940,1282905,1293870,1304835,1315800,1326765,1337730,1348695,1359660,1370625,1381590,1392555,1403520,1414485,1425450,1436415,1447380,1458345,1469310,1480275,1491240,1502205,1513170,1524135,1535100,1546065,1557030,1567995,1578960,1589925,1600890,1611855,1622820,1633785,1644750,1655715,1666680,1677645,1688610,1699575,1710540,1721505,1732470,1743435,1754400,1765365,1776330,1787295,1798260,1809225,1820190,1831155,1842120,1853085,1864050,1875015,1885980,1896945,1907910,1918875,1929840,1940805,1951770,1962735,1973700,1984665,1995630,2006595,2017560,2028525,2039490,2050455,2061420,2072385,2083350,2094315,2105280,2116245,2127210,2138175,2149140,2160105,2171070,2182035,2193000,2203965,2214930,2225895,2236860,2247825,2258790,2269755,2280720,2291685,2302650,2313615,2324580,2335545,2346510,2357475,2368440,2379405,2390370,2401335,2412300,2423265,2434230,2445195,2456160,2467125,2478090,2489055,2500020,2510985,2521950,2532915,2543880,2554845,2565810,2576775,2587740,2598705,2609670,2620635,2631600,2642565,2653530,2664495,2675460,2686425,2697390,2708355,2719320,2730285,2741250,2752215,2763180,2774145,2785110,2796075,2807040,2818005,2828970,2839935,2850900,2861865,2872830,2883795,2894760,2905725,2916690,2927655,2938620,2949585,2960550,2971515,2982480,2993445,3004410,3015375,3026340,3037305,3048270,3059235,3070200,3081165,3092130,3103095,3114060,3125025,3135990,3146955,3157920,3168885,3179850,3190815,3201780,3212745,3223710,3234675,3245640,3256605,3267570,3278535,3289500,3300465,3311430,3322395,3333360,3344325,3355290,3366255,3377220,3388185,3399150,3410115,3421080,3432045,3443010,3453975,3464940,3475905,3486870,3497835,3508800,3519765,3530730,3541695,3552660,3563625,3574590,3585555,3596520,3607485,3618450,3629415,3640380,3651345,3662310,3673275,3684240,3695205,3706170,3717135,3728100,3739065,3750030,3760995,3771960,3782925,3793890,3804855,3815820,3826785,3837750,3848715,3859680,3870645,3881610,3892575,3903540,3914505,3925470,3936435,3947400,3958365,3969330,3980295,3991260,4002225,4013190,4024155,4035120,4046085,4057050,4068015,4078980,4089945,4100910,4111875,4122840,4133805,4144770,4155735,4166700,4177665,4188630,4199595,4210560,4221525,4232490,4243455,4254420,4265385,4276350,4287315,4298280,4309245,4320210,4331175,4342140,4353105,4364070,4375035,4386000,4396965,4407930,4418895,4429860,4440825,4451790,4462755,4473720,4484685,4495650,4506615,4517580,4528545,4539510,4550475,4561440,4572405,4583370,4594335,4605300,4616265,4627230,4638195,4649160,4660125,4671090,4682055,4693020,4703985,4714950,4725915,4736880,4747845,4758810,4769775,4780740,4791705,4802670,4813635,4824600,4835565,4846530,4857495,4868460,4879425,4890390,4901355,4912320,4923285,4934250,4945215,4956180,4967145,4978110,4989075,5000040,5011005,5021970,5032935,5043900,5054865,5065830,5076795,5087760,5098725,5109690,5120655,5131620,5142585,5153550,5164515,5175480,5186445,5197410,5208375,5219340,5230305,5241270,5252235,5263200,5274165,5285130,5296095,5307060,5318025,5328990,5339955,5350920,5361885,5372850,5383815,5394780,5405745,5416710,5427675,5438640,5449605,5460570,5471535,5482500,5493465,5504430,5515395,5526360,5537325,5548290,5559255,5570220,5581185,5592150,5603115,5614080,5625045,5636010,5646975,5657940,5668905,5679870,5690835,5701800,5712765,5723730,5734695,5745660,5756625,5767590,5778555,5789520,5800485,5811450,5822415,5833380,5844345,5855310,5866275,5877240,5888205,5899170,5910135,5921100,5932065,5943030,5953995,5964960,5975925,5986890,5997855,6008820,6019785,6030750,6041715,6052680,6063645,6074610,6085575,6096540,6107505,6118470,6129435,6140400,6151365,6162330,6173295,6184260,6195225,6206190,6217155,6228120,6239085,6250050,6261015,6271980,6282945,6293910,6304875,6315840,6326805,6337770,6348735,6359700,6370665,6381630,6392595,6403560,6414525,6425490,6436455,6447420,6458385,6469350,6480315,6491280,6502245,6513210,6524175,6535140,6546105,6557070,6568035,6579000,6589965,6600930,6611895,6622860,6633825,6644790,6655755,6666720,6677685,6688650,6699615,6710580,6721545,6732510,6743475,6754440,6765405,6776370,6787335,6798300,6809265,6820230,6831195,6842160,6853125,6864090,6875055,6886020,6896985,6907950,6918915,6929880,6940845,6951810,6962775,6973740,6984705,6995670,7006635,7017600,7028565,7039530,7050495,7061460,7072425,7083390,7094355,7105320,7116285,7127250,7138215,7149180,7160145,7171110,7182075,7193040,7204005,7214970,7225935,7236900,7247865,7258830,7269795,7280760,7291725,7302690,7313655,7324620,7335585,7346550,7357515,7368480,7379445,7390410,7401375,7412340,7423305,7434270,7445235,7456200,7467165,7478130,7489095,7500060,7511025,7521990,7532955,7543920,7554885,7565850,7576815,7587780,7598745,7609710,7620675,7631640,7642605,7653570,7664535,7675500,7686465,7697430,7708395,7719360,7730325,7741290,7752255,7763220,7774185,7785150,7796115,7807080,7818045,7829010,7839975,7850940,7861905,7872870,7883835,7894800,7905765,7916730,7927695,7938660,7949625,7960590,7971555,7982520,7993485,8004450,8015415,8026380,8037345,8048310,8059275,8070240,8081205,8092170,8103135,8114100,8125065,8136030,8146995,8157960,8168925,8179890,8190855,8201820,8212785,8223750,8234715,8245680,8256645,8267610,8278575,8289540,8300505,8311470,8322435,8333400,8344365,8355330,8366295,8377260,8388225,8399190,8410155,8421120,8432085,8443050,8454015,8464980,8475945,8486910,8497875,8508840,8519805,8530770,8541735,8552700,8563665,8574630,8585595,8596560,8607525,8618490,8629455,8640420,8651385,8662350,8673315,8684280,8695245,8706210,8717175,8728140,8739105,8750070,8761035,8772000,8782965,8793930,8804895,8815860,8826825,8837790,8848755,8859720,8870685,8881650,8892615,8903580,8914545,8925510,8936475,8947440,8958405,8969370,8980335,8991300,9002265,9013230,9024195,9035160,9046125,9057090,9068055,9079020,9089985,9100950,9111915,9122880,9133845,9144810,9155775,9166740,9177705,9188670,9199635,9210600,9221565,9232530,9243495,9254460,9265425,9276390,9287355,9298320,9309285,9320250,9331215,9342180,9353145,9364110,9375075,9386040,9397005,9407970,9418935,9429900,9440865,9451830,9462795,9473760,9484725,9495690,9506655,9517620,9528585,9539550,9550515,9561480,9572445,9583410,9594375,9605340,9616305,9627270,9638235,9649200,9660165,9671130,9682095,9693060,9704025,9714990,9725955,9736920,9747885,9758850,9769815,9780780,9791745,9802710,9813675,9824640,9835605,9846570,9857535,9868500,9879465,9890430,9901395,9912360,9923325,9934290,9945255,9956220,9967185,9978150,9989115,10000080,10011045,10022010,10032975,10043940,10054905,10065870,10076835,10087800,10098765,10109730,10120695,10131660,10142625,10153590,10164555,10175520,10186485,10197450,10208415,10219380,10230345,10241310,10252275,10263240,10274205,10285170,10296135,10307100,10318065,10329030,10339995,10350960,10361925,10372890,10383855,10394820,10405785,10416750,10427715,10438680,10449645,10460610,10471575,10482540,10493505,10504470,10515435,10526400,10537365,10548330,10559295,10570260,10581225,10592190,10603155,10614120,10625085,10636050,10647015,10657980,10668945,10679910,10690875,10701840,10712805,10723770,10734735,10745700,10756665,10767630,10778595,10789560,10800525,10811490,10822455,10833420,10844385,10855350,10866315,10877280,10888245,10899210,10910175,10921140,10932105,10943070,10954035,10965000,10975965,10986930,10997895,11008860,11019825,11030790,11041755,11052720,11063685,11074650,11085615,11096580,11107545,11118510,11129475,11140440,11151405,11162370,11173335,11184300,11195265,11206230,11217195,11228160,11239125,11250090,11261055,11272020,11282985,11293950,11304915,11315880,11326845,11337810,11348775,11359740,11370705,11381670,11392635,11403600,11414565,11425530,11436495,11447460,11458425,11469390,11480355,11491320,11502285,11513250,11524215,11535180,11546145,11557110,11568075,11579040,11590005,11600970,11611935,11622900,11633865,11644830,11655795,11666760,11677725,11688690,11699655,11710620,11721585,11732550,11743515,11754480,11765445,11776410,11787375,11798340,11809305,11820270,11831235,11842200,11853165,11864130,11875095,11886060,11897025,11907990,11918955,11929920,11940885,11951850,11962815,11973780,11984745,11995710,12006675,12017640,12028605,12039570,12050535,12061500,12072465,12083430,12094395,12105360,12116325,12127290,12138255,12149220,12160185,12171150,12182115,12193080,12204045,12215010,12225975,12236940,12247905,12258870,12269835,12280800,12291765,12302730,12313695,12324660,12335625,12346590,12357555,12368520,12379485,12390450,12401415,12412380,12423345,12434310,12445275,12456240,12467205,12478170,12489135,12500100,12511065,12522030,12532995,12543960,12554925,12565890,12576855,12587820,12598785,12609750,12620715,12631680,12642645,12653610,12664575,12675540,12686505,12697470,12708435,12719400,12730365,12741330,12752295,12763260,12774225,12785190,12796155,12807120,12818085,12829050,12840015,12850980,12861945,12872910,12883875,12894840,12905805,12916770,12927735,12938700,12949665,12960630,12971595,12982560,12993525,13004490,13015455,13026420,13037385,13048350,13059315,13070280,13081245,13092210,13103175,13114140,13125105,13136070,13147035,13158000,13168965,13179930,13190895,13201860,13212825,13223790,13234755,13245720,13256685,13267650,13278615,13289580,13300545,13311510,13322475,13333440,13344405,13355370,13366335,13377300,13388265,13399230,13410195,13421160,13432125,13443090,13454055,13465020,13475985,13486950,13497915,13508880,13519845,13530810,13541775,13552740,13563705,13574670,13585635,13596600,13607565,13618530,13629495,13640460,13651425,13662390,13673355,13684320,13695285,13706250,13717215,13728180,13739145,13750110,13761075,13772040,13783005,13793970,13804935,13815900,13826865,13837830,13848795,13859760,13870725,13881690,13892655,13903620,13914585,13925550,13936515,13947480,13958445,13969410,13980375,13991340,14002305,14013270,14024235,14035200,14046165,14057130,14068095,14079060,14090025,14100990,14111955,14122920,14133885,14144850,14155815,14166780,14177745,14188710,14199675,14210640,14221605,14232570,14243535,14254500,14265465,14276430,14287395,14298360,14309325,14320290,14331255,14342220,14353185,14364150,14375115,14386080,14397045,14408010,14418975,14429940,14440905,14451870,14462835,14473800,14484765,14495730,14506695,14517660,14528625,14539590,14550555,14561520,14572485,14583450,14594415,14605380,14616345,14627310,14638275,14649240,14660205,14671170,14682135,14693100,14704065,14715030,14725995,14736960,14747925,14758890,14769855,14780820,14791785,14802750,14813715,14824680,14835645,14846610,14857575,14868540,14879505,14890470,14901435,14912400,14923365,14934330,14945295,14956260,14967225,14978190,14989155,15000120,15011085,15022050,15033015,15043980,15054945,15065910,15076875,15087840,15098805,15109770,15120735,15131700,15142665,15153630,15164595,15175560,15186525,15197490,15208455,15219420,15230385,15241350,15252315,15263280,15274245,15285210,15296175,15307140,15318105,15329070,15340035,15351000,15361965,15372930,15383895,15394860,15405825,15416790,15427755,15438720,15449685,15460650,15471615,15482580,15493545,15504510,15515475,15526440,15537405,15548370,15559335,15570300,15581265,15592230,15603195,15614160,15625125,15636090,15647055,15658020,15668985,15679950,15690915,15701880,15712845,15723810,15734775,15745740,15756705,15767670,15778635,15789600,15800565,15811530,15822495,15833460,15844425,15855390,15866355,15877320,15888285,15899250,15910215,15921180,15932145,15943110,15954075,15965040,15976005,15986970,15997935,16008900,16019865,16030830,16041795,16052760,16063725,16074690,16085655,16096620,16107585,16118550,16129515,16140480,16151445,16162410,16173375,16184340,16195305,16206270,16217235,16228200,16239165,16250130,16261095,16272060,16283025,16293990,16304955,16315920,16326885,16337850,16348815,16359780,16370745,16381710,16392675,16403640,16414605,16425570,16436535,16447500,16458465,16469430,16480395,16491360,16502325,16513290,16524255,16535220,16546185,16557150,16568115,16579080,16590045,16601010,16611975,16622940,16633905,16644870,16655835,16666800,16677765,16688730,16699695,16710660,16721625,16732590,16743555,16754520,16765485,16776450,16787415,16798380,16809345,16820310,16831275,16842240,16853205,16864170,16875135,16886100,16897065,16908030,16918995,16929960,16940925,16951890,16962855,16973820,16984785,16995750,17006715,17017680,17028645,17039610,17050575,17061540,17072505,17083470,17094435,17105400,17116365,17127330,17138295,17149260,17160225,17171190,17182155,17193120,17204085,17215050,17226015,17236980,17247945,17258910,17269875,17280840,17291805,17302770,17313735,17324700,17335665,17346630,17357595,17368560,17379525,17390490,17401455,17412420,17423385,17434350,17445315,17456280,17467245,17478210,17489175,17500140,17511105,17522070,17533035,17544000,17554965,17565930,17576895,17587860,17598825,17609790,17620755,17631720,17642685,17653650,17664615,17675580,17686545,17697510,17708475,17719440,17730405,17741370,17752335,17763300,17774265,17785230,17796195,17807160,17818125,17829090,17840055,17851020,17861985,17872950,17883915,17894880,17905845,17916810,17927775,17938740,17949705,17960670,17971635,17982600,17993565,18004530,18015495,18026460,18037425,18048390,18059355,18070320,18081285,18092250,18103215,18114180,18125145,18136110,18147075,18158040,18169005,18179970,18190935,18201900,18212865,18223830,18234795,18245760,18256725,18267690,18278655,18289620,18300585,18311550,18322515,18333480,18344445,18355410,18366375,18377340,18388305,18399270,18410235,18421200,18432165,18443130,18454095,18465060,18476025,18486990,18497955,18508920,18519885,18530850,18541815,18552780,18563745,18574710,18585675,18596640,18607605,18618570,18629535,18640500,18651465,18662430,18673395,18684360,18695325,18706290,18717255,18728220,18739185,18750150,18761115,18772080,18783045,18794010,18804975,18815940,18826905,18837870,18848835,18859800,18870765,18881730,18892695,18903660,18914625,18925590,18936555,18947520,18958485,18969450,18980415,18991380,19002345,19013310,19024275,19035240,19046205,19057170,19068135,19079100,19090065,19101030,19111995,19122960,19133925,19144890,19155855,19166820,19177785,19188750,19199715,19210680,19221645,19232610,19243575,19254540,19265505,19276470,19287435,19298400,19309365,19320330,19331295,19342260,19353225,19364190,19375155,19386120,19397085,19408050,19419015,19429980,19440945,19451910,19462875,19473840,19484805,19495770,19506735,19517700,19528665,19539630,19550595,19561560,19572525,19583490,19594455,19605420,19616385,19627350,19638315,19649280,19660245,19671210,19682175,19693140,19704105,19715070,19726035,19737000,19747965,19758930,19769895,19780860,19791825,19802790,19813755,19824720,19835685,19846650,19857615,19868580,19879545,19890510,19901475,19912440,19923405,19934370,19945335,19956300,19967265,19978230,19989195,20000160,20011125,20022090,20033055,20044020,20054985,20065950,20076915,20087880,20098845,20109810,20120775,20131740,20142705,20153670,20164635,20175600,20186565,20197530,20208495,20219460,20230425,20241390,20252355,20263320,20274285,20285250,20296215,20307180,20318145,20329110,20340075,20351040,20362005,20372970,20383935,20394900,20405865,20416830,20427795,20438760,20449725,20460690,20471655,20482620,20493585,20504550,20515515,20526480,20537445,20548410,20559375,20570340,20581305,20592270,20603235,20614200,20625165,20636130,20647095,20658060,20669025,20679990,20690955,20701920,20712885,20723850,20734815,20745780,20756745,20767710,20778675,20789640,20800605,20811570,20822535,20833500,20844465,20855430,20866395,20877360,20888325,20899290,20910255,20921220,20932185,20943150,20954115,20965080,20976045,20987010,20997975,21008940,21019905,21030870,21041835,21052800,21063765,21074730,21085695,21096660,21107625,21118590,21129555,21140520,21151485,21162450,21173415,21184380,21195345,21206310,21217275,21228240,21239205,21250170,21261135,21272100,21283065,21294030,21304995,21315960,21326925,21337890,21348855,21359820,21370785,21381750,21392715,21403680,21414645,21425610,21436575,21447540,21458505,21469470,21480435,21491400,21502365,21513330,21524295,21535260,21546225,21557190,21568155,21579120,21590085,21601050,21612015,21622980,21633945,21644910,21655875,21666840,21677805,21688770,21699735,21710700,21721665,21732630,21743595,21754560,21765525,21776490,21787455,21798420,21809385,21820350,21831315,21842280,21853245,21864210,21875175,21886140,21897105,21908070,21919035,21930000],"blockHashes":["0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3","0x83227dbd864567a72712bf12f58b3998ddeeb77744978bde3bc0f21fc7dafbe8","0x912b473d9816d8228421b91311839c4f1b023bb33a17ba3fe7279f915821dd49","0x6492c40f133cac0bb7c1c179db9434c3a383d90fc644d71d1fd52e094d800189","0xde63303e6f9e8522325e1312087c12072131e7e0ae32027d6885a5f84b6bc09e","0xfa57aa0a4a2b4b5077f420bbb9f1abcfaaa3ee42293cea56ea4ad9df308c1be8","0xf0969986e0ceb402175d75f8f17736d00bfaa279d3f8625523ab992c6691bd25","0xc9000883d09d3ecd0651081925859aa6925ca69ca3f0dcca443a45d38b4df358","0xb418b7ac9ac7392678ca03b54bd85a7afb4425b26687037df9a7ab6dd93f49e1","0x3ad928b3040ba3922132a36396e33072432c8f92a94a538214daa6ba60432299","0xbd5683e1eba72c1eed4ad4fd6c3137e340bc4ccf1da6b3c90b541f46c0a8197a","0x8cdd42e577a738aa6d22fae1463fca7d94962eac7528c3fc05a90f062fcdc590","0xbf25fea185254ff380d564594caebcf59cbeb93971cf8c31b1b1d246c12ee2f6","0x29cb6b6e32a7f3dfb7d82ed5407caa422e01179b332c21c4758229df73c8bb4f","0xfb178ecad03f29112c8ec4a99dd4a67e2f5e79908314208fade693a332a63dc9","0x043fd7bda65dcef9641b03ecdabea5e8eb0e61d9bdcaf32a758d0429aedf8630","0x68fd4714849c5021a062b229938c2b150c2b49fb3ce81d3e767f80f931591204","0xc9edb3c95dcc7964d5b542531b49d6ab977ea30c341e14be52259d99e7411e59","0x4d9c798b06ba9d06214f2dc19f3ba3ffcaef246e4acb198254d9bd5a723d4d6d","0xf6aaf93f34d25bd3718fb15cfa15139327ab87f81c2a8734b89b1472ea1554c1","0xdc6ea9c81f393cb34aefa8331d26171edbab83f48c70e287aa99e4041b233428","0x7e29ccab38bd15ca29a039c2cec2cbad2fb0928d2bcc431f76a042d63af08b83","0x0fa327a1b017706660eeef94217f53d323d54b66f60588ecf72b552f9ea4cd00","0xe3b65d05f1e629c674dc365fc1b49d712f9c5c19c2775f5afcd3bfda1e47aa2e","0x268135ad8e2dd63029c19fcf936f3346a44611e46519ae96d61293d663dd1a43","0xbd916c150b51da5cecb78c66e6468a47ffb49fbe939eaba5dbb2c4da4255cb12","0x13f56d8c53a771fc715545bbbcb9e58730c7ad50dfa5d8da7031669a171c7bc0","0xb7e3b57306d24656bdf66c2024501c6b08d2cf58b32905c378a6bf5e30db64df","0x1ade7e40144179707c7498a5bd41325297b2aa5710990eae39b50547946bb6d0","0xd2d4436b871937515e59ae698e4681418e0ce01d1cabd761f083b9aa654032b2","0x180791cbe96fe7386d6236b2a5e05f4b7086399c60f69dd9488238492edeea7b","0x6bcf8493ca297e4b5aea4719f4dcece4cbdfe2dbfed6227b361321341123a55a","0x722c7b24714ff079d739d4ba27a1731af14868b740dd76fcee9699d33fedffb4","0xc1bd93e8499ddeb27343d4e58f528e6410e62e5afad312f01775a3a85e7bba16","0x69d6ee42d3619f622a891ac4cb11e192e434964a698d881c5b5905ee79663dbf","0x85e08bde473e82bab0b67f0e619bee658dda6bb49616361f691374fafc81665f","0x7d8e0cd575d7baaad167a471d388cddb9d67e158c271e3048e0edc297724bd9d","0x82120575dbb0eb1893b77aebd9e3bc65980289f55ad0da51ddb30409cdfaf0c8","0xb8793c62334bde8bbfed7e4740f0a9d4967d42b6cb73fdc934be3a681bf12ba9","0x5bb5347181e34a4e785cc96e49d195665dbfb7e9999ee13edcf1bea01be468e2","0x85913b756978796b5e155399d668aa3eea8adf03d08f83c57ade96185b7ecde8","0x00b9e835b7cba2149217cacfcc1ddcfb343a581edb2e76cccfd0b659838d4c4e","0xc4bdb43262f246d82d2ebe8efe7ce253e708ede04fb015d07c20fc386b15f2fe","0xd3fa41dc6a0b3d41e2aafb38c11398551233bb77f31eadc247db887fe7bc7f0b","0x556a5f3b95715d0fa104284c986de65a9315900e77badffbbf9e740ec11ca5af","0x06f43c7204475fedfa4af294c4f16840db56eb9a0d76213b6bafb17a869ffe62","0x33c34ed64bb543275df9e1c5d7b7d8d8ce83bb9e70414947ff605debcc20406a","0xf3481ab9554f22de8fb902b0f8359c2a82122d8c4b1da370f9e6e299b33f5c75","0x30629d6270b1edcaf146e4eb2709c93bfd4d75de400a87cf599e19df21142c47","0xe706da2e89b02b9c25913d2264a0a9953fb378ec8e8b88ff11f7d09c2096d147","0xfc73c67d849517cfa637c1e2cb7b4f8c9af9c9e0022d728c8e048af222d9511c","0x222f25a2a24a08fa9f9474aac4f2c246b9f62214d89e0b39887be3759c8c7fbd","0x3fc6a5a61122ac490d77401c1924ef772e54f3fdf9f6e5233961a8cdeb68ec73","0x6e36ae0d017277b596df8a6efa63e1c596e721275870b05ae233ceefe17cb06b","0x51d8f8fcb04156211a5722b9400a72f2bde549ec09344bba8e235ac8e39c0d1c","0x77df665df59be84200d419c1686c055aca862a510787ab7ad895dff568a69d09","0x3712fa5c426d99145e56f5e0bc14e80dc36e73c71f7e2817137792f7cbb66aab","0xe57e50d7ef79c3152b507b11d95fd95f20672ca4a7fb98941c06591e6a188226","0x48776e03c21e490a0863df8f6687bc03eaf4991d112a3c2f99b7d773f38db932","0x837da5eadea76e73e0565b868336b999be061f43bb8222d310f7b0f1db40daa6","0xbadfd3fb137fe24e2221afcc9f1b8cab773439095bc694f629e681d3411a1876","0xb6afe94e8984608356471a1e7aeadc3ff0439fa9f70393918c801fbc34d9095f","0xc3126aba584e4b8e924ca485f8770b86ecb00cc64a7efe04d6e6851cef77102a","0x168c237cf0fed96aa9ce8e39802186ac3f608a5635bf43f7e97b29196b46edca","0x09cee82e04dd2795214d62547a9ffbdb1b00377c8e46fe0aa30a93e4b95a92df","0x47ed031744d4b8247c75d4f5799fb627212687e545eacda624fbe731d1ded8c8","0xe153e1dac15f569458931e4f8d3bc27d489e0af4efe1354ff454f33b2e0726c0","0x4a1328ddf8af70154879a5271ec036b9f52591665ea7efd2a6eee51f9e3becf2","0x3cd36d88f2efcda6870815c446e1e047075718ae7a70e9d3e7ae83a050ff0d86","0x12cdf99e7fe3f247ef93fda55b8f8331d43b7bb545605c598dea71036ea4d4b0","0x458b839b6119fbab883a8ed578f7c4f522961cdf5d25f1a43cdf520417bdcde0","0x9c5613690e2b497365184f417fc97b3e894ab7d6d9fa00a9951bab4834da866e","0x52ba41373f816325421ebf2a2cc7eab29ae9f2a9ba49ac83195533a843424f6b","0x5bbab190cba0fcef4469aed605882b7cc3e9f5af5ffc5c210bdfeb3dbb7feb3b","0x9e132385f40f6cccf86c74dc577d0800339ecb341463f38da73695663f2a1986","0x79038d6072b4f466ad22e68a93cc6db9bbfdf181216bfa75ec82df3b77d5743c","0x2124b6bb1567225d552190a3e1275801556e611d5dec8826116cf74cc1945580","0x46cb726d5a768dc1433ac0a62b4a356257712daca1b8b0bce375a2c4aa845c05","0xf0b6ab3013139438c5a503362802e45d813beb5619d064357431172fa419bd25","0x2df10b2e03f83efe5eecb3ee00345bcea52617a047fbdff8aa7b5587b883e4a6","0x1146af18bac3dd9a3bfa8adc19e49efdb1cfa0f4ce4ceb761ec35ba627ef56e0","0xb48126f5d82a8ea3b6cc5bb5d793520d52fbc3f810bc98e121f6b0d35fc1b51b","0xae55ce5582a27c9c53d18142641d3e64370a6211937d55c63f83a99240039925","0xa5821da43931c54fe012bee97d60f0bb27a43e81a0e66b6f4efe79bd0e560d22","0x52d2140c0f18c228dc30341414711f8b6c15af4d83a89b3e6273653f15575c56","0xeb632a4ad8d66da8b5ee692154cc82d00e325657ead72561f862369edbab8cbf","0xfac2141f7bafe4d76e9b4e3c4278c91388ea5d3e535557c5d539649215d57b09","0xaee885368d0df8d68bd6bb0916989fdfdaeb93b948183120f05508cbbf480bec","0xcde1f3ecbd1734272afad1b46e14d6d5f4240f7a7eef48acf3c232a6dfd32ecc","0x300bcd91f539b7f2d7f2222eef0dd335eac3160b44f30465a8a477a30c6037e2","0x57b911f67ec4d327604004791bb8a744e6be26f2470998327411ce142a9bb01c","0x16b5d77aa5ecb080b517eadca9125eb5ff79c2ef0486065f1a704d27b555e7c7","0xff2895e24d8f92c12556a1c6e97a2e3030b78aa29fe961c169a2944c78d6a4af","0xc0f8e7ad94c2b6a3fb5cc5b911a4a10e7ef45a98b949ee57c1f016722ff40e30","0xbf6674c77d0d7d12d3db9b9be9d22889ce77e2428c07d522f70ec2445f81e1ec","0xe27dc8dc657bfa55491760e02e75bae8a8a514719c2a4a1d93a6856f4a5f8a7f","0xee94e39020eda225a49567a2777f4b2b6dbe28bebf2b76a113ca23d5bb89d269","0x0555e9df749b4facec7bf2bb1f604a1ebd38ba20a8ff0411b5003d6c3a7562af","0x79576e0dc239a55ec34eaf38b8c571b5d7d56fe56e95da87f97b971a2bf3e2f0","0xbd8c5319815e033c51b36a68637537f5f83bc936ca7410407b1b5bdaff4e54ec","0x2e46b6d0b96637364dbadb4ee1c753160b319aa9e8640033f0c29f9848a78721","0xb6c4c2e39554c8e86b571d4e39700743302344f959f110f462b50bc2661391f4","0x1dba1aa914a99bb85a7a38192f909141406cb497645401ec7f84b3fc8a3d11c6","0xa89c18f90e1c3dadfabfe476de8f7eb94e5bd19898899c0c20c2c1ce19170256","0x0b917d8fc0fc523339faf93308bfeec3b8dfd37d1973e9dc1e6d811359d2c531","0x5fb1051562258120d494c162e27bf7cf705275c3b80f168d41f82fed95a3dee1","0x87ea75561d3e445bacdd7e248775520e1a5d526e5687a3e744b74fc6fa5c6b17","0x07eadb70b4d6e61d753be6215791f30696e27a67c96bf032d7263acadc6f7572","0xc5d0dbdcc2b1c9b5e793adba639dd337594a5dd62ea4a271949f732af7275c20","0x51f769d1794d8219531a5085fef9b15a253e4473cfffd91c1987aa9f39398b93","0xa0f674d29fc635ff6abcd86afdbb576439168fa75487b370c353466cbeed58f4","0x25b8f440a7a2ff8181478ffdac1a4d132028d7583c337f39aa47e457d9b812eb","0x3c8212c7c446f4d2b1ff9ba18fa5eeaecff87cac1fa5ba558af72513916dba70","0x1a65dd7a0e93226af1c1f468f9efb3daf2fa97ccdcedaab1a2df3c3cce92b34b","0xe90e8ac799af6edb9d948d353e1446da7feda3f7ff7cb636a27cacaa0fceb7f0","0x62c2c39abbd38b6c2d95ef2bc840bfd7487f2183512d722d6e1fc51e8cd7dbbd","0x60ddf229a5a6fff0c54fc7d3d441b79aae445335e55fa9de960eabad22be0e0a","0xf4edb0eda566442fa39876ba9c38bb98b929a0496482771570d25aa2334057c4","0x6a2e6e8a9fbe25b0e997037dbcab9f2e73665c41219cbb79f94f1d9774bbe671","0xb10c87cdaa13717d853da2a2b7c81c9faedf76c7ade8021969af2022d5fcd553","0xfd236b9ea6cf8b61442e19617f7474f3ec9b0aad155962b576a601b0fa20e013","0x9a46c101d1cc7d2fabaacb3040ce36d9e89a18aa7b936334276f88e5e7c36ab8","0x33b792fccefaf085ca8a8be56681c03c43b5137e648ced4789ff0d062414dd86","0x9e20106f4f287dffbd5cdbdb5fd452631787d9585b4973800ee90e58a62ac468","0x973969d2f2efd0fa7b94443db1f759957135a23024cd610087b1342ac94a479b","0xbd61a037f3395c11eca3bdb8322170ba81121a34b1929a7867a8225340a115fc","0x5c9d7c534f55a292eb6d3b6d037f5046246de91863f1174c8154d7caa838cf8f","0xdbaeff64fdc13ac0a3b97891fcd8cf856582ee7aad02521eca9ec3ff5e99d571","0xfe1d23fca4e93790b1ad6895d014734918891fb42af1c036a686e22b1455d923","0x6426b6e733fab9a7a8e66ef31546ead0e800f2e94448f3e1c12ff407f6037fb1","0x5b34398025209dfc9d4bd2025c79c67e7a807f4a71903b203cc122d51d8e8cea","0x7e1cc05a2a563ffde15afbed5a721dfdd8ff09871d7e472cb09de7a569489964","0x724861998c9ec8c18b2c61b606699bf0f812e6dbc4c2d97f5c04f59e576e7a69","0x1728d61efce368b9218a1a7fa5e82209941be01a2b6170108b557fd427425e12","0x2603da7670328ad8304e9ab7b065e0e2b4e6eedce27683091affed393bb26460","0xf7a862865d0d7528b5e2bc986c5b6e2671c5d0795d1408ce9649c3325cc51a5a","0xda5a921c44bc4cf089251de5aea823f965a1271366399b4e3b4770222824c7a7","0x881364d25cf169514c6608c01edde62b30d92d13eb6a6c5dfbe06e89cdacd57d","0x2c0080ba2975091d249eff09f0b054d8d3766e3d40d40d821669460f9df03cf4","0xa5a002e5fddb8956c6fd9aee1c70dca55fdebb54fc829fefc51fc53748983971","0x8a906c231122259f088a120c0cd66740f3539c7594a600dbd4fb31a1acc63114","0xdceb94e51b29e7211d62e14cf5625e130d57e1ea5e42d41feef469af083e57ec","0x7d348b03a6968e531e4612294700dda7b1353bdec357bf29740f0875be8da4e7","0x9279e736b9ec93ca9f290eb50d3d917b33771f0c560289c6cae8fe4eccce3d42","0xe10e81647a94e5223e1ddd2a6be74d96cf1aca968f1b8437b5beb86439ef56d8","0xc73653624bf8dafa4922c2e643255ced2123ae2532fefbabcdc6dc353ffd5378","0xdadf72c4f0c0f2f2f493a64e7a87feb856c3415cb6e869f06f820b503c05f475","0x34bd5fab49358f11b78eb73911496d183446cc9422f8146192df773c5e4e9ea1","0x14d9e009ac1d503af77058746bfc5d906253e86a055dbbb0c21563f588c6b57b","0x8c0978139b4dc49a63ce498d11e20febe34b7f6be66acaa40443a914aa5788f2","0xaa64d0aaf444b1c88dfa37e2dfb6dc3746e023ff2bd3089fd6a1d573281c5dfd","0xa6f7219b93eb787d21eef4c89da27490a35af5746daefc3d69ad85969b731758","0xad383559053f0d0ed3cecb519e9d96f43acb11f9f59594a534c2488f6268389c","0x44cdda9af7b037739979706d8466d3ea0e06952a5d555ca6df672e9b3bb29e5d","0xa4ea8a9908cad0c5319d34de330ecb9a1ade4f4d9a6e84f5b1ec830675d40a12","0x38090cf903b7973cc7de69d6ec5ea6aa78212d1f52ab44bfd4873071b78175c0","0x2b75deaef097493a45df53a28b1adb66da18070549db4ebdba5562bd6aa9044d","0x3b9554a75fa804b95e4b3f913f483d9fca243814c906e6fabc9b28530482745f","0x75639c7f02d472a9d92f06ae0bf833b1b27028809deb258697d1421fcfef08c2","0x7b479911397a14112927904cdcaed23d139d254065b20e773a91a4612c4cf06b","0xe6c341c1edd3a6c069a19694ad212ede7dfb059666ad35db74f68f5cf16bb1b2","0x13646b69383ec42ccdcd0dac84cbe30761db29185464669e1c98294330946646","0x28f956eb62b84edb67ed1fde42391f8cc473a7e9d6db215a9081798d7009e44b","0x17c7e227b1dba102a4fd022085520abf9748f48e20885a308e7e82248d0f5c0b","0x11a413c0079d68b0555b2691f67a63d85749ed4f8d71f5b5d30a1cab6d665c27","0x82552ee44933e3061ef4ab9551dd9dc1ca79670bee3ecad81de931b42702e294","0xcf098070ad59c2d7a07605f9c1e7ffcd6d1b3c65db88813c17750fbe75fd2308","0xa2351a384cbb137618a102bbdefb8144b90a27d172a26b4f39dbcd8129b98b4d","0x9479a9129f4540e909b063f28280afb4972e5a6b856215ecdad5a821b01eab87","0xa0676bdbb7a1df8057b3cb70945ebbedb58a588fe8d9ac3bd58d18a9e172c858","0xa9a5790ee9ead7fc84c56bf1d2a3b24f603007d35f6f78791e817d38785b5ae5","0x71f90ec192e772da5ad3c0eadacb69f7e737ac203fd2e170d27e1262a6f53282","0xaeab8e7d7a7692c05ff0c6e3aa5bae1df0fa553bd630040e5e1034b7524d5f1c","0x56a00fa0b948c4528fb22e41c7b0dbac3aa8f474c9b797e7410eb302e695938e","0xc3bb281fb787a82690475c611ecf4a3503c60ba604b04411992da7240a2d961d","0x68a32cbf86581deb36936a435d6c047ecc57ed58c065626b6c5594aaeea297f4","0xe600d11a7c4c62a4acf0d063d9ce309165e74dc81dfc59265a410594b2a09412","0x00dd5480f9b45fa5b312188dbf73f022a59703fe1aec2fb57be231fb26590443","0x3c342204833d8a1fbc8385592408dcbaf7b01cf646241c9636c2d204dc66f85f","0x71e30a5480575eff3b970664c6281abcb5264a25eb93da7f08d3e5f1b7b54ee4","0x83d7787032384911f9e55cb21a92e0efa9a4259221afc94d8c8660de56024cad","0x78812c0daa38084400eac387779486fbbf4cfd0a94ca8e394badd346dfafdfd0","0xf05f0cbd5a11b2cb95c8eeb41b469687b27cb7c5a7f68470a0129a0cba9e701e","0x195c1772121056e51fc16f12c3ef948bf4dfd6bb86c83497736a146a1ad6cb28","0x607b635662c939c83990260d0832328c99b77aaf7c4425cbf20909e567a05191","0xaf674b5dc3954f2ea955e7f465814fe85874a8d6f6935663814259b3191e5cc2","0x9e56795506a9cf1fc6e539929c11e3e8c51d8acb21a6695c90a7f98883d3934d","0x24ccf5ef9c12526cac8f5dc046364dad886fe9472d75f81d2e3b8913f5a01583","0xc6a500693481ca6a7b3cb7f97dc7d0f7e2c3cdc6753d7384826ac8be6509a657","0x312c37cef94725798835d8489ff7de337a1c3ee75234c84db81a9e4b04aabc32","0xb2de5e1dd16bd809cdf9bcc1a13c49ddbeb1c0f4c713db66c899b52cc007acd3","0xf3dd4029ecd91edadb0b5a9587b0847adf0d983bd57a48fa90076759918ba955","0x923a9ebaa191c2987010830e8703d8687c2f7d824185d3ee75ea44f717654bd3","0x30bda956c80180b9eca21eca8d0dfd50ec6b714d7e13589dc7a4b1c6d4d46dd7","0x9976febcc7caab07c775a0263aa0c0a0e411b4276da8ea169e5e19a6b5c0504b","0xdea781ab4c4c013045a918b23e2ea13d53f6580ab0dfa89c65ab247c46b48ff2","0x2c5a833ade1fcaa3ac2b092845608b7768c24ef50d51225e140a9f39aa923676","0xed68beaa622e806f73c8e0bae394de3cf4f146a706f1bc565ff1b19730f2f948","0x2b4cb171185e85337bb0fcda2e87c85b771abae9167ebbe0332f3bad2e0a790b","0x1839cf8a6239894fa7e785bcc60eedceae4d9be517146c3f5b5f45ad2e92fecd","0x5966effdbc328d56bedc60c102be954cd31e5dcd5944c6dcce50851f3d6e87e6","0x2199afa30fb07e66c2985f81a3a28cf67bb34e3eae82fa40af6c728af85d6f01","0x7033ead211fddf0b0fb3b645d8d7c03da7194566f7b985ae3b9a9ebaea31b2ad","0x9bea12f37559706422d5f5771aec8452fce1506aa6532c094f494e9a0b8abcc7","0x22a350f5f0fd4e5c9ce4dd725c578ecbd5b46b41a9a38e7ecbe5fb0fb990cc33","0xb1137a931f8c193b0c13ff22e8e45777f6e8614eec22e3a26cd53a42e2e2926b","0x04c5faec727ef9157c0be846b43a5bd4b8daee34903c85d5a708491e36c5db0a","0x62d916a1599eec73e812876105423c5c384ddd928546a7f7619b2e8488639cce","0x9d711a7c38267beba116e900c181ae14942f33961e80460988c80886b8102b83","0x89af9d56da38a5257892a1f69b43fb5b6dea28089772110beef583ae57278498","0x77e4855b1e131213e22b6351d5ecd653e7810fb09930c0be6888c8c9149098e5","0xe2c3338344da9d10270f66b3af5bd229abc71472b4da4dda9db1a1d8e4a9f5ee","0x9801ae5f9cef229d6d9ff069053cc8e82f6fdd68acacfb64658f43f656ac853f","0x5baf8f28e17b18fe0154586f02f95b69f00dd5cd686678981a23ae5f0a01ea76","0x911dcf284a23959bd14215dac24d35528b3944f813fc8c45009edc3bc84abeb1","0x32b7dc827f105a5c59231123951d535434e85ef07a8bc510fee23daa6d7a0a7b","0xd248c07dbbb15fa93280b700b5686e0f18ac8126917b9b763c8dedd74669c38a","0xd46fbe14047e5d2970f0cb82e4a166eaeb596aabff0775057184353c1f0ea0b9","0x7bdd686dff839be0b1d182fa5d7bed784dae6f5f5240e15c9e1329f840663c3c","0x1400940fc7f8594b98ae7e32465d516e6fc841e05039f465efd8c285975b14ec","0x597dfbf5b087d7dbdc1f498324af6dd69dd2727940470bb62cc7187b661d16bb","0x047def5f2aabac221dc6664ada5554aa90954885059ae41780b0e23106756a51","0x9965fadffcdf930e99e7f5cd46c3f066d0ec7b059e74b3d41703599c31b05988","0xa8e5c27263590cb361a5fbf8f900659c9b52c8295a2e5c556aa9bdcbbfdeca8f","0xc97093c4a4d607ad067aedeed2c2c5076e9fb35641956ea3c22ad78a55881e04","0x0245c16b2298f908eb503dd9cb8d4f61239b0cbef96d0ff4edfa8c41a4b2b86c","0x7695cc1da5aa5871ebbbb087d3456ef8de1cd44dfa5a7ab9506dcc89aed74948","0xba9a431c8a0dff961ede934c802449f7bf305418e892a338d5bb47c657d4245a","0x7132c92c158e5e91763c6cccbddccbf68b9670bffb50c3ef72cede8f4df04db7","0xa3abde16365f73274ab68f70f2882d87f9d0f34cf0cd483d663195c1a4e60673","0xe974c234b082b1444c6f461469c72ea0f20dd8cbfe44a7a714a3bb805390b6bb","0x24e573679ea9a1a6ec9a845c470499ecbfee24c06294251bafa854e597cd96ae","0xd5b7954040215a9cd83d8366d7f151b8e5be27551b8f979e681177ae20f9db1b","0xb44da9a163a1ea399c3c4d226160713fb401590089f6eee333c9f6c85855c955","0xd3ad8eecc200708209172cb5ccd8c2646c8e56bc8aef5283a13c8a02d05e03f1","0x88f268d6ee0a99126d1db08fc8dd7935bf54728965358e670fb9faad12a0d787","0xa354c1fb13999fbe8154e11fb5493b0a5378b84f4729627ba15e6ec5250cc107","0xd75dd4971817e89b9d624d9b0e8714da81be3e9c1a546daa6fc08edd7e002d48","0x0a4fd233201b86400a12afb816f21d1f191fee5e3fbbf28e46bcf06caf120d9b","0x782e6faf21a703a226e8e90d03833beb829670c85fb242304c3f2478e4eb8635","0xa140ad315af0878cf688fec8e85440aad6897f59eacc4ab5bf268e5740599199","0x8314e159a2a4087d667b1a3c6aa17eefffe36fbfbd233d0aadcf2bc61f054e64","0xecdce41d5814fa27f0382563fe6dfec6c33d64843dcf5552bd6152dc95de40fa","0xbdc1cf5f1725e773cc0c9a5827437987e63d05bb580b6c2ed421f429ca54164d","0x7758ba74c52a4426c8f6cc17dcc74518bff9fcf8b033a82403c9581851d79e28","0x411a1a3715794123a64158f55e53d42f525a31bb71719bdcbf892481d7fdee61","0x6111cad188f9cce66f56dd3623eec0a8308939e6c704de07fa399af0816e27d4","0x3ecb4b37081c3dabfe50357e02df0d88311843d6b12b784e1e732c99887b7f77","0x49fb31411a2cdbb7de75ea2722d6778d3a1b52d32437a4fa4be4f45f131bfde3","0x89597fe8117452072e7465119cb44da30f1de56e5520c2949d9aa52c65076c62","0x7c92d3f307bad8138a57e3d467d742aad85ab8d728a9c832fddfc3da55dfcaba","0x0c63d0caaa6a13ea8e63922b03ee84fc8b136f3304527ec8ca89d1620f607ae9","0x45f03af717aceb3a70befeb1f3a30bd1e89ed5f56333ff7ee3dd89bbe9bfd279","0x546ff5eb3c5c9c37fb49cb1f58299617eefd9a34c1c04c04f47b871111e75146","0x7c3566321ab7574be40d8c3cd17ff1b4f3477fa7486ac501548bb8427a7db537","0x5b74c0a0287a553484de0e92e196e489c6e9db1273edc2f7e99e154edb0a32e6","0xfaf2141115bd1d9feaf27e23d994cdc94914fb5ef0fec2ba174c1938f955d1e6","0xa393dfabaedef822151c750bbcae6d3e47f4ebda55ffbc64a2b08506daba66f0","0x3fb2e18559060311f09210d173f6e2d5496a1e776c22f7016312d664fb3b23c8","0xf6443831a0a36b9fcd371bd9bab4cf3e315d1840eeab476ec3c3b18abf6ca997","0xb97c819069b2a2b4a577193964cc726ce911b9e3715d56c71f765617b4b1e697","0x22074ee5d24b79e8ddb040e177e6ae9caa699d5bede0ae34bbbabbfe16118b85","0x206a8a664c2d026e5301accac15cf1a12b623da1cd16dbccb0557152a076279d","0x00bfa5899131508850ed7c314a12620534b185a3416e3beb30dd462386ea5ca9","0xfed1ce53b924c5adee187da1ca3bb46762db7c5ed3c9f0caeae313b3280dc8d4","0x06aa46578dd9a997ccaba4d8a76da07ddbc90bacb9a9f53deaddbf2f374e15f6","0x50532f61e930a4c495888776a6dba1df330886daef0af7f5c568415f1fe792fa","0x06f271bc3298acba76e5526ce2cb229ba503256f90098dcee53cd25d83cf91df","0x3b3621f8af3fa89b959f02654ff76d9c4419011de6848ce856b228f85d5e4dd6","0xd37def227e4feb01c3bd08fefee0421a16f1913f81ed985291f931d32ccf803f","0x192a8f1855884ea577830d9514e094d16ea452220757acecb43780731786c850","0x09cbd0c86898c404a7b947678aeadeed1dbef3733fbab7e7b3fd7b0ea24ba9a5","0xf31e6a8e8c5fe051da89b328b1c6e6e505850bb327762d98012ee2625dcb94a4","0x1bfd5ca049b0565235c734e38ef65f7fc9c072b3ba18231a8bf6fee259665a92","0x4fb5c98b968ba936b7c7f2f190692ce652a0bbc50e3894d32df5a3ea0ab8f5cf","0x98e61bee9d4697ce9340bf97fedfe84133ff2c8bdf9f4664adfeb31a60456b6d","0x26490e7c5250b2f8ecdc243d3b6ba7020062cf02577c40c528db365af19e90cf","0x1c5bdb06c7deb61136edb737acd2a2c01240944914569fb0d9299bafdaa51b5d","0xe23e6fe7c803ca6f574f257e85db682274074532d7634d45c3b7a76dd85409a0","0x5a40e1be2cf0d2f7e5a79d75eef53eb7e02097037691b155924a790261eab4c2","0x62ffcf3704638302517265bc28678b98eb5a43fbb5655240d141a76b60b22c40","0xc350e8e54fb46631332e59c52c8b567ce41715089a19a4e18e8636b27ad6cf16","0xb4ff355e098ccd6b92018404680c00421805ba5aae69ae3111c9ac8513d7d141","0xd3fd9717676c57a15dd31d285c2506988f2f0fdb6c210a3e96cb99dc6f93b340","0xda3bf7f6f6465b9832a1d5a52e3dfff236e6a0f9f094286e392f57cc08544c6f","0x7b4b378b5841b85da84b759654642e865c546018a9877ad568a5ae2a382aebeb","0xd8bc6556a1607eeb449c28d675d066c3bdafe1a13f771c69f0a3996a98f65151","0x87324c3959bbf11f1133b6d4ed83f171a057661d56655606145249775dcea390","0xda5a2971ef30d0868664c1c236d11540b8d6147ae042eb6634e56ddc65589f9c","0xbb14b621c2dfc535073ceb7df7b6ddfe5effef3f2508e7d72448fabb9fb36b9d","0x3a9255925c30f192a5249cbf0b77962c877a8611a3c985b01a9e82d8b11155c1","0x50093dc67d915312075e981a145fbc90e888b0fa0e31c4de05d50b5d6e4d58ee","0xc199e4955bdfec5ad88ec1dc23e57a641e2e79f9b526e4ca9ea4e1db6aae8c9a","0xd0e612cd45c9d1ff1f17e1ec60bcb80a5e5421ac282cc1fcde5e040eebc6005d","0xc2003b5aa1553af3075b8cb666652a843edfc8ce8344fab9dec4c110dae6413e","0xf5e3f26ee4e580aeb26b15f7f79a2e810486559d4bc818cd7a4505220cc603cb","0xde498791cbd4d2de017639470a539c4f303b22b32a049b0ae9f68c208b8433da","0xfc26231fed384ad9a2176942964b844f294a67364c04cf12d9004b6967529b1c","0x63bf5ea366ca5fc0b94f680998ab1e6eed64c72759c3d81c0d7c57579d09ee43","0xf7489d1a76b54d32a30d67bad209dcf9be1c668fdcd941a26e34490458da6427","0x0e1441a43cc5cbd1704965f7da9153499021f4ac31b24ef5400665451f9ade98","0xab425493e09ad54783625d2c242b21ef291fff6dc04b80fe677e4ed678a5c97b","0xaa8b389bddb87bd90aa9ee8d8613d6aa080ca835f805f3c2fcc134e15e0b6459","0x6df1f1385e22b631884cfb0334b2d726ed6af03d2b0434a810fc858cae1edfac","0x2802e7043c213f9e52fd352c21bc95c9f71df1af2cce12d44196eacab73b4916","0xb454bb033151c2416ff5d0b112594ab4cfb989f17b0de6d9f7c7abe3f6488c08","0x0694fb5f2f35b0d299ac9affeb2c58c839092026b59db520089e831b71fea3e9","0x097302fb0461d2022ab721814ef81aeb295ca713c9be1b521e44c1cf3beb6c18","0x1028d69a4ed54546d839055574d21f9e7f3a4abb222714413dfd0e5332c244d3","0xa60d59de16f0b9e1127e392f449e59649a84ea4539c2e2bcad31781dd1cdeb42","0xdfd0f8151f56e12358540361bff09daff59ffe3998fe9fb1c5c421739a506758","0xbf47d7ec9d2e94c0dafbedac5768216e7a6baef911254604878cc8bb98a7cb2a","0x71b569676c1e992eaa1e568190f7a46ce14c26739b3db44fd3e28f437ac6c660","0xaaf5ad10bbe017415b6d891469a43e399a8d519b1bc2bf68a417e92e8503b65b","0x085a675a73e60894f47fe0a37e9b3be5d1de8aeb6c3762a961bf10bf02952ed1","0x434d5f4d6b2b56e52528a662128fcc49247baca488957915d611429ca4dd1dcf","0x74ca6fae5797f4fd893f7704e22e930b2baad45211b3234c412c828153cebe41","0x7695727b3f171685dd818f1f2d7df9bb660a9ee08dbb2b329661e3fa554e9cea","0x255cc59f46e93786aada36f50a2a5d5c1ef9bcc4e92bedc6a6bb882128b7059b","0xddf107252190cd976db16ac16f28a010f3d7825516bd9f784d2f65469ad0adbd","0x5f90b0221ea76019fc7cb0e3da908cca2a49e23b5215d2b47524de296de977ab","0x3a854968b5e463d80a2befa1f84b5b552539a50af0ecedb09f628469057a517d","0xf08c0c3fbe39d9a8f8695969f4e7e0230deba95f593b103242b5fb48c197b795","0xd3542dc29f6d59b2cc96359f4b21f6f309aedbcf301d7cc5796b7b12a0ad6845","0x3ca02ac518f396869612ab0682e29696154cd9ba2e07938017f9b1d70fedbbf0","0x40aadb0dd4057935f2fd421b84bf24d98c1acbfd61145f766719c87555c30baa","0x7d54ada0891b8f3ca3acda2803c03a02502161b9937f316c9bb00ff79e41ada7","0x31065264bc2d6fd26274958bb6b78734a4eddc85964d290fae9efe43bd981743","0x2600484ac76dce4ed83c1e1d5abdd747ebc96938ca9fcec54f90c87b4d15ed57","0xb2ea6db793987e1e8f3058fb87e4e193f9419cb82a5c981548761527c5774768","0x42e7e5fcaeba947b23ba485137f4dca89cf1ef67d5cbcfc32f38e5b04f46c025","0xd8c36ad17f50ed88cee1476c78e4c713003b92b102637249c2ae8d1fddb76c6d","0xeaf715e56bd835bb99731fdfec4342f09024ed9b7925ff01b2527919e90ce47a","0x87f2571fb27eea2bc19fd3f9e881f91d8fd06d35c40f6a636784776e2960a74e","0xe221c8dd99aadcbd7184cec9a459c42b927d73294b5c301dc9100e8255165dea","0x0aefedd9b6259846f2733e0436ef494366b657157406d92aa561ddfb0ed2683e","0x80d35f934cd0fb51f66245befe53b2681e30349f2cdf39a6683a659d847fe019","0xec4bb573ef2905a9e2d47e20c0f76784acce16a8566640874e25fc209df55e80","0x11f420a0e6a810a7928a90847aa7134e4d59e1865d7cbd0faaf713ea8a886232","0x289b96eb826c1668870f27be825d2dadf67de241dd05e8cbc16a0db40296acc9","0x7f794d611246c4d28ee70c42e54ca60d1539d9e2cab72f370b31e548b70ce275","0x7be21cc7187fd60aeee06313d0c768bbf86cb43080a548dd2c5c7e66cfd50697","0x5403f531d6737d55b7401508201f7036675cd78d98ecf858cc161ac9366336fe","0x199a05fcb9bd2c6c5791e7bdf551ac223dbab82520d172a6b4a9ae57030c63d5","0x54a8a35731a9c58bce2e6a7a017965ca35a2bdd49914c2f48d0edfdfab7ebaa6","0x1031c687bf115828c0690b5197ad3c3775f6d0401d225a82cf4c7a7b888e2cb0","0xa5fc4483dac9eb505e9d8679fe359f55cda384afa7cc77caa639e6b2765121be","0x17fa6d5b02bc65c1002d077b77a78b132531e3155ca4628032456d7fb7c201d1","0xde6c025cef09ed089fc9d6af346d892ea026ac2ec6f12dc8559880b58125426d","0xde16aee51311016b3e4c716bbf1bfd22eac59686ca946bc13fe023ba99680dca","0x391384addab56c4e13ce58a928b21f70a03c9476836fd17f069bc5bc6b0f108f","0x949034e950025f434cda3723fc0891b374eb38024c7c972bbb44266e73b2ca3b","0x07ada8ba16887dc33c93a3cea24480cdf3cbf0ff4f850659bc6db1f894d2e32e","0x432ddc6a11f3092d258a94f7a354c4aa97c56c8713fa83cc45e53eb0d276a861","0xc02bcd0499aeda0b67056d4c0b1e6b217e34c7ef41e583a47fb9c27483f42357","0x188d10dcf2b8394f03714c84eaf683d3aec6e33d3bb50a72460c9016e14cb6ee","0x91186c17dfa17dc4ef549b67f967a6c1fea0b9646367301f045140ec6290edcb","0xbdb63517bdda7e13c8a89be94b29605d9cd413d7d8bed9c8f2ab9ac9596118b1","0x971471f26b128e96788c323add0492bd2d35f09627b12067a64e9e87220d6f22","0xe0eb6d39b6866ade12073aed1dd5717412d4a7a72421fd9558ac125bb514f076","0xe121cd22817a4b7142ed1b311010a9f37a3eed2439755be918812aa4271a75e6","0xecbe4fb0702826726dd780088c2d2cb99a5bf2ae7a2324240d618c43fb8596a4","0x892489105daf6f8d5438040a913893102249cea0e6aaf3d46189217ff54f7e15","0x8c75bcfc93f304774e710204bee1e7cb239b7579625646bba41182af61a95352","0x0ae61fcccf2566e41f9144deec54ac8fa347e2d910874fcd5a3ba553eca6d02b","0xebf9b373c9df96a6fd65db1b54f6d649ebb63468d14f4fe3bbd6763cdb3cdcb2","0xaf57a6dfb03d040fc74a476b5a79fcd1c1e59ee4180e0aa63efaa628e869c6c8","0xe76e2a959949d12b41cca055745873d3aa96e15b44f815f1b7aeb5e67791fbd8","0x23d71a436bc0f685b2f68aa2b0a69e799aca8d518d7b8f18fce1fccb45b0669b","0xce230ed62816821e3143e085b1d2999ca9bafccd0f0fa9398396402cd5652011","0x00b2f50b78620976d0d79ee1bb948dd8f4d44a0232970f44e724aed7b630c003","0x5ccec19b843f9539fdf8fd504609f041243bd6f1e0a9809cba72307fc2081759","0x6d45231346f554e8872b885bb54aa759c1f5723206f85671c60a3fd836b93363","0xccda96da0cf56e32aad46e5f10f8b2fa7422111d37c282630c0e2d3da719ef5f","0xb5e218d4dd9ea2aeca21a5bb32865a450a8c882541905ae7766a0a999b63e2d2","0xb2e1149c37de1cd59f02a090b30a335519345cc755e64629cfbf22eb84241277","0x9497cf501d1f5aaaca743544f43707067630eed2b942fff75ec220ee70fd32bd","0xda188516d816b7e57b6fdcb91a54d40bb78eb3b99eefd73b878a22408410534d","0xc88b9088536ee65e7e04451bd1b756697abc111ba0f30cbb4f92b5efc6143b00","0x7c4a3ca02a97f8daf7e4d8bbc611bf30810781b1e06fc4cbd518247b77707f43","0x4318e5ae71d8fe08a1f57f722b9ddcade84bfa5cb6c6d27168cf0b71b0cd5a45","0xd6a1dac39dca9dfdfb79935437bb2a0b6b881d6a8c0a1a2d1b4f3daf3990934d","0x142d935fe914220241bed584d35cbf80b5d7a61255aee234ae4f008d83b51269","0x50830a66b1673f45f184d0b7537018f936a29ec7592c1dae5f015ff1b33438c9","0x57cf3a1047bd9f67fecec74c802e30ad896f8f50b2bc79ed76dc7e17a06b7362","0xfea9767971c2636891931f2b286ee72b65a8a5c593337f7a3573a493e04bfe87","0x26f4fc0fe324c8f46e7c135ffe1e252ddd204ea18395e916483126cfb7af27d7","0xba69dee211aa06d2aa7fada2e1ea776a8abb5857ec0a5382126432dafbd2184e","0x828fa48d4c85e85c3bd06639f48e4378dd4dcbbe20ab3541e44a63b537dc3215","0xe9ea827a7121c71bd24af44db7afa9cc931c2e0a9a3ea029d4997f3d6725bcc9","0x5c74b7097fc6c9d1c8bfac5b4f91790771fb89507115f9a05faf04fc149aca80","0x93db3e69900892b1bcfd61ca80a06dd7d40cc1b3996aabc046ed6b1399d59928","0xa500bb9c8c78d1d2b469a62137279eebde15ca8d9a72a53bf84deb9628cae418","0x3c9431a11c97cd5f151a17dd93d595d1b3a1e7cc60d0889a88bf7507d1ca9743","0xe3ea157fdd382cc9970f3b6fb6de5ed3834e652d0f481d40efcda9f14fd66746","0xa0d509d1725b27477217b5afbe5048e9b2d3c5051c839aebf6e2292f15686a46","0x9a3a2898092b02843b1393862b096d545caff3444cc6e3bea6615b096a2f51e2","0xd9bf38488ddde3cd6ddd8cfa56cd3de61e11bc88ea8a6f6fdc842f1a873ab531","0x37d152aa0a4b77ccdc78e7add46711cd89fb86b710dcadda0744386406518234","0x2c22a86748317d973322e52c1d800cf92cd4e7be31aa6e04f49e1a266d6c253c","0x954ec32c06d759a21c950a5a5703127ee1f7fcd5863682aab1e2b5f000798eb3","0x146806d5741f3a002a5fd23ae885640c4426352603b91a68143dddce01d5aeb1","0xed4852fbc6ecc07d4afcce4280fe7de208016a6f624452c22460e20a82276198","0x107b02dbaff7bdc58ad915570a3ae2735789e72be040e2c523d6b5ec895ec263","0xc7c2af6687140dae517e4955b1e3654f5469fcbfcd3aef611565260c0d453ee1","0xb655153d8ddaf5e38d981c428823c0ca76d6b8ce3b762e9076c589e15db04ed3","0x521cc7652943bbbc574aa01c7b02312377724fb2b8d8e3ba316beb3f5ff0caf3","0x240b9306df6ffa5382b9bbf628a0f5452a9171250be795088c57475584b3892d","0x150a57e8ab066dc635e7a59ddc6d7a817c41427263ca81ff8ef078a7cdf58791","0x1ac3fc240d4a143b1923feb7f9486b19208e4cf04bccd1130265c213cdf0b444","0xed5a9e1a5ca1c2a4cfb826ec6ffbb8913c1d23f9be1992c0c9a52df983603ea1","0xdac79b205cceccd94044df87b4548cf746df486df9b9f4e7a75b728701a2eaea","0x59c9671c22180d7a734d2d54a5eed1b8e98f96820f2a6e3c81fa481d9255eeb9","0xc6ff16c1a15667b4c1f7dec1cc06bacea2b3b13d129238ea9118a07c1b2da2aa","0x456bf5d002eda6820a8fad3cfc7d50f1c96c9c754a79e5f9272d01793d14842a","0x6122c2006b1d98297509bc639564350afd229c9112da7e62bc0a00b65210db0f","0x0103e96a89784063c99c92de692a1756a5e5ae7945f944d8bf324fef18f14689","0x2771c7738ecb451bafb1f43f21efd0dbd9a9ee4190f76a0068c84cadfad16efb","0x42a8359413462cb20c449311670f8fa07f636a52b1ed9177137e7eab262673b9","0x7d5f7cafec49afb91d905f6a48a97019bcdf96ec87db1af49fb63b1b62836f38","0xc3e63046dfdb8fff58e05b533a0a44a49232e0b732e3df3d90a8f20c3927afb1","0x5d9e9a8dbb099cc487509f22eba32e87c32a4e7e297d6de35f82a0bceecfee39","0xc9bd1abf8f92ed3a69f80963b5d73e489973e8359b23863d2f508caa63095b5b","0x47bb5da604724e2e96f7694c08a189b006a61066c9ff834fdb354ceac6386d80","0xb4cf34c8bb26fa4737c45670d3bef6bb3cfdb7338007002a23210f4704cb7f63","0xcf144f444e4c0bb0760886a655ca96427e5fe782249d3942dda45778d3d3f825","0x84f71c862fddc80db59d59320abb4dd457a8ae85bb0b0b3e9884dd694bfb86d6","0x4bbf4e79aac96ef0adeb34493420c71ef2aaa5d3846ffeb4a038b9c346fb8975","0xa8fa827f55cbd30db12f067b7d17424f21610008883499fef2fd0ef2b7ced959","0xe733bd868fb7bb6ae942996594403ad2919c645dda5aee2a556436cf9499d4ed","0x367f5d2a6dea72ab8ce47d89ccdd21c02402a2a54986487b611b5af967ef2b83","0xbfdee323cd60c2fc3f6527e879e00936327f3aaec960d0abd5565cc0ca29ad56","0xd37b824560c1cc43a05121ed59bb303563c6e4bc17415ae2a424eaf362cf6d6e","0xa886685c5bb57c41763ff6a26f2ff21c57db74ba1d95045384e17cad83382261","0x0ec914fa71edf31bb4863535f142ee980bd0110f0d4fd379102274a43863fcf7","0xc73aac426f8706908565824fedf656eb9a0288b41a56c29bc645f1038f9edee4","0x06de716e0d6d68dfaab92979fda144268369bcc0a718f1d76c7af2a1318200d4","0x6644005f27b0b746ac39ea56f777263063e67cbdfdb07ab5b8318f9ef8fb4aa6","0xb91d33c07f4da2b27d0df54c96df68033ceaa798f5b93966ad14fb04f4e68e13","0x06e6e001371c3e1b9e43d0996d0eddc7f3eca19f7d69591bd15b6227c6bddb80","0x85a5fbc1329872ef94241e896c9c95ba02481dd09510604c97d565a7a38e540e","0xf6c86404cae2e1c5015c3fffe5dc6f2842eb0041f4addda4e995ebda95486f05","0x62843d6c5892d7f2ef8aa3c6966722f0b475c5336fbe0c2f1a1278582db97941","0x70210b739bb31fa915886c2550522cdabc17e66f19564d6ee188c0b42c641d51","0xcd206f1e2c04f32f7fac59a68d35884cbec681de71a066d7abb476ffac967a1e","0x6b832bbac8d6dee7a0a48521d7103db790b7405057ee77a7d5555847f7257786","0xd363d11cbc193fa1a742b29f5b4238ce5725db8f87622023a6d7d104053a3764","0xf45c1703e121737cb7dc440a4dba4306a8311c12c2a8454ad934c409e7efefb2","0x50c19390bb1f9634481c36e84eb3c5ae23214f21bb081aee5d57c007e1543cac","0x4530e84f6389461c3152c36e6751b1a9cebf64220c2a35a5b47f4eaa527025be","0x5d81439c90aa5440cd9977d093acf34afc4f65966b78dd4aabb6db2fd544c7f6","0x28adb7d9bbfb6de8305e7ec46601316db9d194727b139ea692583e27cd48af66","0xc27a4a8383e0e9916f5a01c2b90288f5fbc18b12f7e2af0daa4903c7878ded41","0x5211bd7980e8f653d9d88e175c35fa4362b45a2fd66ec38e35006a4bc27e1350","0xae3182f3fbebe91933c5234733f6eee5adb369a95172aca524e3f85ba011b702","0xfc6ef9285c5befdd42aa08d9dc9153e2f2d54efc6d166e0e63a2a80ed389455d","0xee39f2b3a9ec2607a6e818524897deeb378daac28a072d24cf0b68f677001648","0xad7f79fb99573e838db0811c2cb57e902b11dd501987a4bcc96114276ec4fe05","0x29bbfcad364bdd3041df7a54c8224c334d0b9174b566daff73d1f17425a9db35","0x22a967cacabb4180dc980b548fe7b1dad105e2a8899600a51648b46c3b9b0ec8","0xc6385ae8ebd4a5c3e8e5762dcd29afaca25127d1464dfc03eff8047eb530f458","0xbee0e5de067bf21b7911b05de20e53fa5f6840efa4dc789d9c1b3ad3246603a1","0x64695d7b4505ac4b9ee4297d1e327bdd863a831d3f730abdbdc6744b6f7b2fc6","0x3e50ad93ac4ea02df9276bee70776a211ffe76797ac40a0926595c5d926a85dd","0xe8613efeaf62a6cbe572712fadff56926e3a93cc13ba16a6b90f264c92c078ab","0xbe7930fe61a14581787cf9a85d48debd61cba7ad63b534d0d4dc0596bae09be3","0x4c8d7e1c7ee5c37b8e4be7ad6c770a949605873ac62aaac73be18f0476c45168","0x076b2502375409eed617e5e14b23497d24eea69c81c02179b26d799fe234a292","0x80a22eb89c8c483cdee8d0d3759b7735fd5ad6e12498e540ba4b57c7b7eeb69a","0xf4eaa45f8fa9f84763b286353c4e77227f0f29b77d236c21696c05e0615e832f","0x3357b1d6d05955fe013e38f918bc889e9720370ce9d8742e2e184ae2da057a43","0x81586ef7b87feb7c6a3ad6688158f023e9561e3f66ade8b92970ea462b390bb0","0x95f25935d8ab621eb1e9d2648e28d72ac2821efa55d5c033feaaea6492894191","0xa1da7dcd0b030acff985c48ca82fbd64b57cb09656c0e0dc15b289fa8e93fe38","0x36f4d146fbed5819fa279716174bba013782c6d7d0126a370c9f876f22269d67","0xb07208b0b696004853ec2a5a94c8bc7dfff9d36d00ce7b85e4609edc4702716e","0xb4d0231cd5b278cfe42e38abd1ae12aea243f20e5cf3d054af1521816095b583","0x280b3b2c289be041b6a00b1424ec8588bc944a5aeb4d0366db63bcb5d53c74d9","0xf7d5b217214ab127666bee5370a99d4339b8805dd13bc8eaa9297883dbb54561","0xe8d086e9eaec4af921efe93fdeefc58b8c0be00ba359aeb3a3af0c00ec93dc57","0x517112d53ddb6cff69ff7255fcc9ff56a8ae29fb5dece8c270dfadc8e249676a","0xec28b16d60343e01924b0447e5d27cfaf8a1ebbe6280f081f034da4cae0ba398","0xc7e1cfbeb3281b64beeda6929fa60222a427c173815ec1dbd0cd5d0022894ec8","0x7f696710513ed74e65d00d0080a9e6c45b60d7c51f7c7a4beefd0861c925ebae","0x9107adf99fb7e020fd00cfa932cefeec88956a8d8c7bc48c9e5f847d543e8b55","0x1ab6d064270b1a2c47b8eeb3a8865772663f3f723a4fb1ee17e398ef9ae07c51","0x559e209956642b59ac3a4a967951cb81d8ab54f7f4f8e529918d76cbd5f3beff","0x1835d61d37cba5debcf6ea2c796a94056049ca145f2fc6f65afde249ce6866c7","0x303dd0416d391a574ba1124e73936c75589c523118b15f8f9fd8061083a89ec9","0x3c60f8a61fad184703cc4f8455a24959d44ba31f7b91da05f0703f65932721b2","0x792becd3b181d7b59ed94197f085213d651ca1794a4068aa0da1fad2db95d373","0x3614d358bb155b1f67d84a66a379d69367fa17cc0e955087d67a3c3b389584f4","0xd793e7f67d60df0a941be4bd1248ca094bf80d9c3a195e465528ff85edf02b1b","0x42bcb6e93a596a275cf3c385b06821e3213e21542691dc8a85f383eedcbf48d3","0x562193b84fdf04344b31c913fb117907c21ecf9e6513d19817aa51587842d2cb","0xe3bf1f56adbcea5d83e1d143ff45f752d92816b877033ab54671e9eecf98cbb0","0xd1607557a0d4790caf54667e2016039dea297d1f3c4bb857512b94803d090c52","0x9e1962489ab301a3093aef63b7f4ee53aa26534bedae9109ece71c278d67dc5e","0x3f341fe9c6618718455fc317d8b3c00dfa17b1c10ba5701df6a17d7671ef9361","0x22e3b76f1603ebc28c467b3908df9c5924bfa52df53de5ed352f230e0c71e8d1","0x5c64b9ba28673a70b00d6b25bdb686cd262083ba83f87f2b754ac89d74e9f523","0xd7878ee83ff04e4737e6a6dc62cd8b9860769b6ce97ed496500cfbe7bed63212","0xe28e82f9e23348d7213f931f36263421fe231c5af8aeeb34038d4d03bac34c8c","0x23973f3f91af25fe00cd2fa1e2952fef02bccfc4fcb4b2a37dea656fc84f936f","0x537d4bbd996c258c69f288f74a8a13b2f3a07aab9becf8c1f09b5ee94b7549de","0xc21a323f5500b4a9cc090cad01af0805180cd6c19997d1da9c5b4120ae5a5c2c","0x38d5b9a1bf7cfc24c693e7567777d7bceb9060dfb71635a7a323b8c2f1fbffaa","0xf3096e1fc40f405994b7af52576bd3f0be1fe5aed861d322e73cc18665bf9fe0","0x8d5c8d8b9ac29543b259338708dec1c40752a704d281301341f8c51daf226ad4","0xce3364f21eb6822785cb74a5a835c0aa8c601aef60aed177bc77aecab2d7ee3e","0x7c69977023bca0ea982777a09eaee0569cc6e8f9cdbed05762783c4010959ee8","0xcff3e6614777474909eda810e882b3bd88690839ee71b1b4f1aee152324dd040","0xf3d11e5b976e08e23501718b8111f0d06dac205103df4e807f4a7916dfadbaca","0xd24788a603d7a8ded7007344bd80a6d57959d96d6db8d8f82c4a3e8917971d5a","0x987574f8188e366190ffc885d9c0587670287a0e1200aa6911920fa6f4c430a8","0x51b17c163c48cd89d7312e6dbd84cec17f9b2e39936dbafba3020832fc3ebcfe","0xffae3e7ef61b6f08c58518c510153069780fb10cb8b979e15481af3aa63a2680","0x1f2ed3c01fed476ddf873ef196151ab70a5bd8e30bd273d7c45007320e2458e5","0x6fd4eb4c71abb49a844829b25870eff748182c4ef713771ff8a2f63bbf59767d","0x4de55e79c131d65d8eb0b78d05e2d609bc0144273effcfeabe4fafb212c9b785","0x2215302e2f864155caee3beb0d5b359ef0457f2d1a019a2786c017beebba1a17","0x2654f4020c6f782b4db6c50787b0e3df56f683d560db138355b5fb25df8c1de0","0xbd61b656b83eb33b40e61dce4d9fc3ec9e6cf88da199089ab4279c4e81be916a","0x5896ccc4e513c6d8a6592da00bcce49b9a7381d5635a901d333c281842ea9b87","0x392a9cb9f465f8cccc3ea355f8b9b20b0765f2b1a2b50634484e552c3ad31034","0xf679ef34189b63ddde9ae44fa16a228531554d6595e2fa0efca11a354434fae6","0xbd6f9f4525530cbbccc755f401ca17c450fc4537c615488728aaa2c01b681d38","0x948e76acb6563652c1874649feb225bd8bdb0875a8ae9a0ac571df00863a1008","0xe8154fcd25ab57bbbe75d7e377e97120bb141a1078ad652b83ddb3f9192c6aed","0xbff1ab99e382dd3d794b63076bac5823ee98dd6dd55c9774ab56687fefb97dac","0x7df8670d630b8145cca3ec8aa2cedba53ff18e99100b59a8ce30ab9f2c260843","0xa096436f49dc01728e7b1fff8e8f8b2552b001affc8ca57269e453076b25d526","0x44eba53319d07735ef7950d289ca608a5d0698c3df7ad1d579a42f099a56b41f","0x613cff66580eb9e4a266fbeb42d1573c1dac69d8eeaab03c3ec2f2c50122fe03","0x0664c3076336e950808f78e4046f734a31942dc831cdbe8cf0e85bd93f9b3250","0x468676e8051db28db14d50c042b2a50e09f627b0a3de57f0f1e86335c9709542","0xe7d49549db66ac92149bba0b99f73f5de35a1b90182347ad252013824913ca1d","0x7614dacde94957de97808892c5955dc1a694984eb2b0ad8beb5e95181d3e1a5d","0xf2da428ebee8389d9d1b6ea760ef6e97564d057489cf675f1e2fd84183bcf9a6","0x9a05d58752477dcc0fb20d185cf73c76e98d2979bafd8881be9d4bb205893f3d","0x128a1d8ec38c51fd17e740eea29fc3c32c8957983f3fde6b73a8df18fdf5cb7e","0x846078397e1f1f6ad4130f9e86a35eaf2788556f2068306fa9742f13fef9e7d9","0x3b75b926262ff70c6d6bc904d9ebc86867bc2d67ad3f4e55a88ac1cddf213e64","0xc4fbcf459bb03f05982afe317c7eeb8f837f71e43ab72db96b2d87f65cc8c5c1","0x2c35f0cf736a0e9e22eb28a1f6b7663518aca8f649701f878b21e1519a360d29","0xd0adf624bb6a3417c35ee3fa2e14b2f72c5ca55f87debead0171532fd320ed10","0xbc079b8ecd1003c8a4b74feaa019d889e102cc226de9f8677a6f5c5eb6b6ba53","0xba5cd9f14248487117e0cd8b13ae6c87cf62cec84d5dcbcee1044ab3c7451413","0x11ea8de7f0df3ce215d8afcb92107200ac0c85e1a04339b8396f590a49c12225","0x64a8b34aeadc5d8c8f9927b791323075b063e2edb5da3b142226f161ca7b1920","0x7298ee017f2939eecf06c9a951215be79140a6b6b94da0abc5f6af87645a9c3d","0xfc73423a808254291adbc17e846674775331815c2e5e670c3f163e87ab30d2e4","0x18e30c6f8b3d58691c6e2569b66439509dc48c5de363e8938c5c2237a9604a84","0xef9bfebd231de90b73f1e449b6936a67876a319186b07679298c11b6fd916eba","0xcb7b0ea686074c0b3b1ca134ab777fd21288f6e017e1242d86354731ba834465","0x9cb8f8573b0f000f9019162bb607d3854448acbe95a8b41713adc9e65f1f1fd2","0x7bff0c98ad5fde09157aa00640ee85eb4e12bf7a27c8ee1e0e8d5bee377f0e37","0x2fbb259ee5846e5e72feced587ad271e323589991a3734566c6fc389d7106914","0xd0f1dd1d15180dfe2d7c56c520b0cbd1022c5fd08a55e73e03dd815ae62a2bd0","0x98ca841aeeb0be1ae52fab3009383f4bd6b41534b7a270284a59d91711d9fbf8","0x23edb4128271bbe2a156b34b18d213443ec15e3d58078912182fc2f0c2814ca5","0x276a1896852f048dc04fe4adef00248714baa5c76bc5184a7cccae1e8ebcefab","0x039e593477e72c0ceb72c82b60e41d9f4c092a53f754abecd74b75a999ab3acb","0x915057a5a6f0cb631e42f7005f50995a3a23b88cddc953c215b91f4f844e23ed","0xe659c6fb97c0adc1e39de6cfbe33e620be4838d12b8907d7d187e122bb443697","0x75589abae7a1589f9970cd3d052387f1a2c9ab2bf501bca7fbdbd99938962d3a","0x6810707dea1167d62b2e4a470d730fe7b66594610e2c34596f7cec4a82af7b49","0xbd14e265e4f6fdb508e5d753b437e9d86f4300f46e9c6e6ca54f3806a823780f","0xb046e1193f0874eeaaffd4dea447fddb5c59f3ba7df946f43a842181473a1dad","0xa996f017d63abde03daf7a4e97fe714c184bb8abb393af337cea54be312ed8e6","0x7f61ee7d8e901fe8c199b403f8a0946a1b5f8f860ce071c76613abd85449cd13","0x8c6c88ee2d4f23525d3918064a248ffc470f920cd4327b4163d9cc968879bca6","0x0ded8f5001ae806e4f1dbbaf27a58d37f085e36e07fcef6b992697e675203116","0xe850d18ca6d73c07d05abfbead8a8b7db9e23fbb508f652e7ca839b13ab8fc13","0x7d5aba7259a2e20ffcc9da3ebc341ae49750fa9b14c1304df1bbac4a7819e172","0x8734748e1942675ca23881fd26bfd3a9a3734fdd3a7ed9ab6813ac1fb7f8b285","0xf1474e7e9015bf5ca97337255b377edd617cb3a430c36669299e1ae933da85d5","0x642acc9280ffe23c88655df7114160484301c1fdea15e482c15cb96a61c6da1d","0xabc4a64671789ba461e50e5e5bde7c58b54be2f0828598a707a4f87d51065df5","0xc19dff21563604a385c3128471b869ec91ee42dd476ea3afb59f74867df60f55","0x0c9a9eaf12686e9fb9a70ea31ed417281129536d7565516e4dbc1ffa133ce827","0xed5d56932afd24e9df1f3a2fef8187127833a41f0afc56ed8da4490a6753e657","0x33dd05c3acc9445a20d83a4318df4d63b599dd02da1e02562dd8b652e83b7b81","0x1899867333fe25d5d3c96814109e41f98acaf2e87f7f1f1748bb8efc74dd3847","0xa4f078429a943ca59d6ad79fa72a065c0372b113e35a211c6f21f4c4d1150f9b","0x6623263cfaa8a05afe70eacc3f53b90d23d2167e39795470b61098a31067cd7e","0x0eccd57c2221b18f5b461934b2666c92701b69554cdc9bc8dcad6bf5d84a0d40","0xed7762320d97474e3244db1641088ef990314dfc2645fe522db1043b0b881d9f","0xa3c44c2f8a1eb649e121779dc7af652334ba0e44851e61876c87b6c0d29f769e","0x9250026ddbca31e0c948c53709a5804fa8b4022c2cf726822ffb1500a027a1b6","0xcfbdcb8ffa52fc7254137d37937f48c992a8262f2419a3425e550b5cde9e01f6","0x32635da6f007f54b2d85a9d559f8f7689a50d3292841e137414d8b59ec7884a4","0x88e06f51eea23568dad305cf3eb8628bb87c700e83baab3a4a221ccdba37f040","0xc92415ffb613b383e7549a453bea4a7a32d45e4766f6095ebf39e6c6380d763c","0xf5620e96a63c1ab5c1d2ee87a74ba2a466bea86a7744687e12134d3b3f3b71ad","0xbd0621b5be68b1eb4709dbecf560ab81bf120c43db29e2741d367c73e28ea3dd","0xb98619fd81ed2de4b8464c044b195d53abaa993940201e225cefde50355a8f07","0x817e56d8632fea6d5183d3ac4133607189496d3758c28e47344bc67d2570c2d7","0xa0f393f07d9499df5e2785ae6f977bc84fccbff63ad5ca531614b6c71ab74d01","0xf0c670bdd022478bd5701db88d39db0d9d03de746b7c5806b20599eef5607858","0x298b8ca85cb5d11e340c58d6d5d89b4d126c3f2813d61e244fba255d694ed9c6","0x4d74ed6bd511c001e1229041f710cd82fa2266c72dc2f0ef581a7cdaca68c6e8","0x445ebed715aaa8513c10fe8a0e010e194ba98263f67d6a19ca265326c1a0bd75","0xfb669ccb09e45cecc4367eee0d1fcf6ae3f0389ea26c70e89d0788fa0d2f11ab","0x12f4adf3fe455cc7377d53d146a32bd31fe2f797b39811700e85b7ec57aa919f","0xbecfe298ced7cd45075d2a0a240b7f121eea659b09a194e8a0046b7bcc8de600","0x5d3a7cc62e429b359f4772a0097ba112ae9ef9cd467cafab38338114ae32ca98","0x147f939158855e1b26f022269d0943fcc3dec8151b2f060e4792b8bb13b3c802","0xf2081a44881661375f786f0f8080c5df2e342858728ac4508bf4f2eceefb1ec1","0xa04edd0ed5d16ce2bf8c3aac6675cec7cdc668949351261dbf9590e6c07d4b61","0x869fa3735692f5927631c94fcc3454c62f2c212ecff0d4b355dabd3f69ab56be","0x08db3ed18894b26e14bc8f1e52eb8ad031dcdd402010c52c4cb9f68c09433621","0xda9e5fd540dd1ad15237d72ef5be3155e0005effd540ddbc4363f16f53b90421","0xc9574e187f0e4e14f19932798203bec3069ce575b453ba7a82522a3700dc0498","0x0d6772d9e89d490d7c332e923578f3f7e0c972a4198cd3164b4ff01adff26fe2","0x544484c9490f8c2d3d4bc98c44344c5d819a2c8647a7657653bf51c8ce1eed69","0x755245294f71da632eacdc4b25298896c3893e90e5ddea7e82aa1f008185a938","0xc629b0771eadff9905762f68fb1eb729206ed784e9b0e4afa44c0fda2a9b663b","0x75fc3f62f1f02921c3729503092e2ddcab1dfc810e84f415ad507d54b73f24a3","0xc1f009360235d26f313e9c185d97d4ee496058a17bb8c9a2c1e3f100b49b8df4","0xa7246291452268f5ef5a88e2529537e787bff1304723a664bf97eb95b4e8b7c0","0xb808e40fd15ec98085a2d6a91718598246129cfd222b96ca9fded2026f709ea4","0x85d1bdff6603d1fc59be83cc09c30361a0bf5efd353661a8ed1a1a015490ab28","0x8a897b4b600c2f71e4e5918dd5dc9881a162f5e91a4008c10f6970a42d2479d0","0xa7ec27f444b0e49762d47f811dd4e4a388497aa902062abe5af451e3b8ce86cf","0x184f7cfdfd8b3b0cf7972af86afc6c29526756d03e600e1e9149dee10ba24309","0x0dbef8855a889c3a5235766d4711e1312715933f6bfc0854ba5848c7b0bcb9f4","0xb268c3ae6a06cc570949a3cc381c9ad175437cd642cc4d5616f97a7c8e019ead","0xae142a87e8a513035b898d5c8a6b5b19a36246666537f4a17526e1b2b5cfef79","0xbd1437082b26c8e1bb2ede2ca8415dda4de3255980bd53f1bea6e2a7d45a9e5c","0x369a185a5dc6a97e157884057f81e9627875c8d8e8520f1c254b8463f5dc10b1","0xac20d68051cb6463550716deb4da86e95ee6788d9a403988ce8cd8b1343b2040","0x2538ecfe29cbe6f0a24b761fcef80d01d59e09d57bc97b7eaf0fb7f18ef355f2","0x7c60e25358c428800feee75f24b1dad0966b975733b7a73ea1b0561221dea615","0x8ace7cdd9c328f89edc7bd820849e48dff8d17a4730c2bf041417ea50822938a","0x0e663eb4dff04d481e6d3a36963dea98e60a21d638e343c288bf811a0ccf03df","0x724c43cb2a2ed0d293105f642f76040d96e03d3ae47a363539e77c801eb4db1a","0x539982cc32b9014c035af99cc63060085b8e69556d36944e21ce74a74192afcc","0x0d6d380054e9221a24507703785a7519fd83141af8a65780d7f24e5998cd7371","0xd7450f620c19a58bde3660b015ce97e9d59d76635673518136ec46f2c9e4e562","0xeb6368570ea7ae67cb672467c389022cabb00ab798930ace8cde70428a325378","0xc1ad01b3cc126593d0f7b21a70371f8461b48185957ff7f0b8ac1ac0553cdb9f","0x14b00bfa1d97806a04eec5af08ae3c18c9a63459d6a58ea89fad3506077bc366","0xcc0efb7d16e0a30f95513f011ebf7a0f467b2edd5066100c92347e6da083ef9c","0x0b9b76207b6f654455c96a01f8d4c12590daadd2139ee28d323650dad757afcf","0x8f1351f2f9680d8032712a90edb67fde6d4ccfe5486d756b13c747e828577984","0xd9a841b08092ca4787c3b71fd88fab9ecc3ab6834b2d631969775ca405a3794a","0x260d4047923eb6c466fc669dec021b6d123b740fa0651ae83673ad858063acda","0xd7a660819621c35ab28d2628660241be0b630a1d7057abb744d3ff6582f8ac0b","0x657ae1f4d59964dad943546acd9171ad7dff6e22f94dfdc7338f36c8354d1779","0xdcb7a379150748ddc36692c3b52721356763a3642ae8d0e25a6528ce19a60133","0x509a82cd64fcaf33bec6eecf00a71f8fb537dd8f0000986806f6e9737c4a862f","0xf5b268f255e805fbec647121f08877f3f3da79aa51c0fab3b445e952e91f2b53","0xcd1c2a5fceb061abf1608eddd1d64c97ad8054b925163ba0737a9683c19c09b9","0xbc5a12e1cd7dcafb1a2ea4bfa91c73741a12067b079d2027d0af8a9adc99d8c8","0x7506775441ec1d32b47ff3b017169d16d22c81dababe83b5b5e5293e978ed4cb","0x99592af4cff5a327165ec342b59bbc0b4b09b20a82755682c07b9d25a2e2e863","0xcf7407543547fc6b8fd1240449011a37b7698e8ebddb619b6d282b7f679706dd","0x26a02d49626d47bf9a502ceb70144bdcdfc7ffd2575ac676dd1fd6c525eb32a8","0x7387c563aee679e8ce01649be5c134d6eb336188e813707df24dcceb3f4fc094","0x8299a8ae7e612c886b1357ca8dc9346b13e7e34a1c0c4d1027f6d1412649845d","0x48e672f719b4a0dcb7b5a64a99ed2366ee59bf18294325127dca429a8b5ddc76","0x1f7556f2000fd91fc041690e8eafc5d221f3ac560808b671b7b7c3c475d9191a","0xa62ab43d90ced19cc900aed7ab4b5be6d06bf20a06e7bcd46f92aa8b51e1774c","0x54e5e38cd38cad75858a166d14ec29302981a0359a2e8ee30606dfc84d500543","0x5e608556e50f476013799046c15babaeea5d9e2122d70202168b1a284ade6e49","0xd1cfd48fe7a47af45fca475d389fbae7fee7784ddaad81411148c1bd41624054","0x73f4259a322858359d8a3624f7223e99a47f9478a3933022b4191764a6feecce","0x67ad0efe621059c2b5ff8ba979600dcf843f4af6e78f7fcea982c5061e1c68be","0x0f791559eacd4eabf87624edbf538cd5884f95c365c0f3f9e70df10a60ae993b","0x9f8096202dcd5e04750ac785773caf91569bcf06338f674db7e809a78066e3e1","0x282a0e4c139edb69239eb8586f8b92a6d647e142d1fb25154d93c9f617cb8eda","0x6fc9054ffad75190a07a68f97865696d4e35a14d10ccd88f986879b7c093b843","0x70a7af26aab8ae31925e9cb33d4d1701ae2672ef1658082015ec91acc9148cfe","0xfdf7906d90e03096227e60730c39d7d42febc4951190cabede8eaa5128d632fd","0xb58e9393ff32720d34d29523b799eb84e42ce45c97ad6c80a0ed8973d720096a","0x04657e664fa9443a53e828f70ee1aa356cd2a395147d16d0edde37bc516a0257","0x3395788df6707036f7de1313fbf794a4576a93ace9cfbee7b25e73af73fe1fb1","0x131309c1ad35184f6e66ca0631ecc42d8bf946bfe0feb1acae5fcf4d19ce5771","0x5c94f2161b8a8664a49c210a4ef3f4d247785ac683e387fe80be0c6200e8d802","0x586392d0cb7fb0418dac07308e51f77d2587456269943585887a76bad7ee940b","0xd8bf219ce90f89b4c4553dcf65b3f6abd8ba312b51bb4d67423841d93844d302","0xfdd260d05bc8acad56d93255c7c170fd07495daed7f9a18242f15deaf2bd931e","0x31d95331dc4931dc8881780eb36fa818ab55ea51b2b71f5c2b4a5e105a35d668","0x7ff471bd4031fb900ba9a2052147dd07f88fcbfbf1e8c03e7180c3097eb6a004","0xb2bcbc59a7b01c7d1a338b2ba0c78a3f246280c2e2557a9ba60bf5dcad28449c","0x85763c6f40ecc5c084f84f0adb80304451aafdf9d360e4608750d546699dbcca","0xafdac5ea26356531c5dcc98fe2c8cfeb3fe661031cb48faf42a9d9eb42f389d6","0xc63626edd46a5726f45346e4877a9cd685665c009a1cf4a339ba78f027e40a78","0xfb2564aff91c948ef5d414dac82bcdd4d23f234ed2fc951347257c7fa12e3226","0xe44d918d863ef51710bc95c837dd651c1f536304e5761a6acef09e9c4c7ab151","0xc0cb6fc7cd4ff26a99dc8bbaedc753bdf608de98102d32949ebc1ceefaf8b016","0xed2f430e2b72d5759f9b9a8d958eda3719b967799ba5984a6b614adc02398b49","0x1979e50df2837155a0c27d8091f54cd44eb0903f12e4bbca317b019008dc0db6","0xc3b9553ad2f4903a2fc096c1b24b54c42d2b23c394fe79fcff30efef73dc9610","0xe28d8446f4633af7c4f667ce19503332d03919524b7adba9aecf267bc1ad1d00","0x0d5f7823f34d17d51f43429cece51d54276fc65c65410e23750dc5caed33df19","0xaf42aabfb1f00eb73d36e1eafcb56437b5aa76f5ebd35d9d2826a80785c1a113","0xdb50b07d86a0ac6c7acc8ba1567b634cecc6d4f51ac0963c841c24719f82b5ae","0xc3125b1616ff091d8424d7cf2e4f600720e57600846ffd52799f38ddec30b415","0x504223f7255b68837a3f19d97d9e613651d98e5a73247b6688ed1bf830ac794b","0xa6f32c54c0313bf807d5e0a1401028b1fbda07613f82668e8cf881722d22d3f0","0x3aa566a98fd56333c1594c49c0e200b26b109f99099de9f7c2dc8ed3c045e3fc","0xd4295c6d35aa2a17db44e34ae2f7aa597fc048a4bb32498d1070471fc64bec96","0xce1afb677c24a10fc608b70336fda07060b2f8a838e419d41ebf8dfda733233f","0xfc0dd7187c1e2f2b0d4d94ff1c17dd2a1917c308f6a9970bd011927db8999085","0xdda7d35d584c2435e91ccabae3995c631e2a5334ebf356720a5c972e79a22ad3","0x8e54021050300f8448ddbacde68e5d9d0b1afc949a7c71d6133ef35eda0503d7","0x55bd7a6c880efd2aa7c631ecfe9ec61ead2f47c815d3e028cf93ff4a38537110","0xb20edc98604c5bc0c29cee29341a78526d7949ffcc3c888d3a2205468adbcfab","0x4f5561cb3671cc781a58a88104923b5e80137ef76a5a69546256ca5788ed8598","0xe3872bb97f0516474170fef6d1ce4cd2d2fe599f5415f2de0770c9a3dec4091d","0x64597a8c934f7ab8e2ee6c8f98982edcb3487471d804ce83469cabd671a95de1","0x841dd174b0b584571b47e7dcd49babc5cc8263d37971c953ab72ec3c79432ea6","0xeabe1478b2465e36bab08f0085cf3738eab74058c422eeef98db07f79d8b93fd","0x014a189c699b30c01b8b81569e2d8acfba382546aca1ab7161d15b9176ebc9ef","0x260752527a2eb856bd4d3e0d538d888fd1b307458f84d99a73c9001a4d046d62","0x1da6b8e6df57f74165998b72756b2de098e55f7b049b8c5725365a23ca559b65","0xecb4d68c450ac1c26b94f1742666b676a02f6f322ce412d7a54c6eacab803326","0xbf6d555512c4134cdc36ad681b3f76e41cdf66d7d7cfbc94b0126c260fd1f58f","0x2e81fa5cdd8df1bbff0587ba469f332124e363302e61554f01127b00861b0fff","0x4ab8e88d695e0d9acb9b8c1a6eb1927b26c15f532724b4675dde918c5d56a308","0xb1425276d8c178f881f67146fd6088b7a86bc2c742a7ec45ac86d4416ef6f039","0x5eb44ca7943653a6cf3332a367db920ddf8be991f8b332ef864423ecbd23e40d","0x7b0e7136f34d50cf2caad9b7b52f0bc474267c01a04692ae50a7f2cbc54d519f","0xb2323f3468ab3167d59e10b2befc7d405e06a60c6d69bb270c1e034ffeb9e388","0x6b45b4c46a930376fbdb32cfa904aea82c4f6436f656d55d98d04ab2f0978084","0x95f25947dfc689033749f9ddf2c379dd84c1866260d0d65af1adc65213631e24","0x717f6ae7a9e986e402933e15c6c875c12c6f32ac0a23b05f1a040191ead87bb2","0xe6e8f9d8a8f53057494b80f30e0a0444a81240e51bd48b33834b00f88d58b354","0xd4117792813dd0411783d8678d6b1ebd737df06b267b43d6aca5b2f696dc360e","0xe43ec1abc5297479abccda565eec4b0e8efd9257f23fa76a7d24478b07bc0bd2","0x5d68d25e6d1880ceebeccbe193053a5895dc53f62de18a3478995b7523120d96","0x3b35a8ccc3bc98099a83d603e2edb3bab7dd0fe74c91024ac9de6aea84ef408c","0x28ae81141fb36280dcad4f91481239f8388dd8f3e28020cb7ea57f2774c0fa65","0x030a457d82b9d303983b0c7200b64ff973e8b5153fe8036a1a3b27956ac1c491","0xad8cb0cfce953f4d30414768c93a4c14d44cc8464905a6d3179ec231253fe2ca","0x5707b968671fe8b72d3b11a0229f328f1318ed51ab49afc5a7f4b56a85602149","0x9ea07b93abd0a73a584302af9da5f95263cec6c3a2e6990a2c3e3941f4613bda","0xc343f6d88b464672011233b050d7ff89ace42787f6a4f45e8daca9b2a547b710","0x8616c97bd54042c39b5b44aed4f5879ce17f440c5f46e78bf5023dce3c53c9bf","0x368ff7c5c2b2d85b5179d183fa69ca2f76c53b5009a440bbca9380cb6f1fa308","0xc791d6634cb7d033ce7ac02eae0a31d19683ec625a20f1629404f1e669912bb7","0xddb0086152951b4b7cdd5a2fb3a31de2b6bda33d94f41e12c580fbb2ffdd87d8","0x1b9b006a3f1e9a620ddb3297d0c0c943dfded3ca9ebc33514037e836a93c1d54","0xa9f0884af8790ed624a186a232c41392f51877bcc736a21d50aec16d243e42db","0xc4525af4404aa4e8a4f99794f394931214c2743c8c5b3bd577999664d4c95db3","0x1cb26fa057f3776ca1bf6b263c91af242c56cdef78a251ae9c53101293f569ca","0xe996dd6fbee1020ace4be2b064d81de1eebb75f12ded285f5140ff7263cb80ad","0x50ce9cf71e84b755086fcc6103617e97a5a2e01eb67a04d7eeebb911ef4ecab9","0xc5431c7f8e33f945fcbf646ff938a596e04e9060e4bbde1b2be020e23d6685e7","0x7d8773aa0c8de2caf2de449a854138615151f2fecd6cb09863d59d6f19905613","0x7a472882757b66f9a7b0dbe3d2223df851fc9a5b353a02c801c70f7245003616","0xbefa193ce6af03f4e4a0b792cacd7a5bf55e67bd3e8019c88f880445d32226b7","0x1e6237b1c6585e93c7ffdc82ddee63f433b45105d252b1588d147ab9b7908d21","0x68adbec613a26a78e7a2b2e3c98ca389bab8fda26b054232840f713649c3ea22","0xa860182e252da2d23a46f3471a71053a77b35084464af89e57c2320402e362e0","0x862288b41be23ff6ae9b804e33fe795bf1cf41837bb3fe58878355d5796afa77","0x597aa936ede8636f4fc185ba2cd31d4500d43e99ffd09b275b48ee4a677a6666","0xe5300425e726d70f3a3a6e1b86d2c7ca8f55e86b32188b0df7787f6a9532b59e","0xb91b180f32f49aa5889e2b82142c6bccd3a62878935eb8bea8f43dd3c1a3d201","0xb11f88e29d3e1b21abf88525f3846d37aa13e65f2467b82be57182859c2954b0","0x83e677d9cbc3bb311cb57bf2fb75e9be9e49c16ab1b6f31c404ed33f70f5c37a","0xb5f7b469bf41fa33de3891a55f544b0524be2031263f566b7ae27903e1ec2c2f","0x804b7737666a26cce01b985c408477636ff803e5a09103bd0593e4784c5fa52b","0xaa259e088c246edcafc1c24d404168f3d452ba928923decc93304eb06c2126b7","0xa2347475b545bcd8a90a200b50a415b4b25aea40268ecae10a86622a7a55f355","0x69a2d3dceabceee2e5ca8855ac58b4e74db666bae0ad9c37d4983e4c23e4a166","0x06b3c05df6ec4edb5dba119e5c2494a5a77590903d8e8f8f2f79747af76f92ba","0x643e111fe9037f74b42a5a4371e9cf62a27c3e5cb4ef251fb7e9296cbb931a93","0xf0b11be23623845e2af7d801b54f21edb51f143a15d716fda9a2467d571c03b9","0xe85b8e9d39403e2fe08f91763aa1baaf56066a2c3cab95ba9ef42b11fec5f651","0xcb89e00dcc55af5a3f1a2c4920d440462be457205ea0e3e6bd126f56ccb6d674","0xa915c6e1746d30ba02827e29577f8eb3239312065402c0f1958b873244b3e4a9","0x44bfb1efcd161cf37b9f87a79c8f930d8e305c58a1fbbd9c735c19b241a89c70","0x1a4ef586d0dd82b1bb605d2891b8b5f807da45e0d5a709fb20869936b6b4d4f1","0xcb84586b686f4714f1efc505c491cf2f64e12a9dcc3699c5a79d704fa3a869e2","0x34d80f87e433df46d7869d2d00b315dd5704138860482929afc82f2f9facea27","0x9c16c71ed251a64da0eef22718de1d0ff51a38a8e5d45f8b16eb97b1431f8633","0x7c761a750bf6fbb29e7bbd5dd0164cb2e0ff9278ed5c072f02918700a1fb8aa3","0xe442f280f6b839724b95aeff2264b74f3d33fc1c54a5d32bc2e672edf12725e5","0xa1b520b94b56dfcf9f2c0d59ade126d6764b33f2c17b6c25f5c6307792de78b6","0xbc94915d0ea4e232cea793e760084f5487ac2d30e7c6ab900332b2c027a8b571","0xb4d8fd923ee1cda742c7112237eeb7013e20ca0436099b88063a7fd4058f82f0","0x0df9dbc949b1e9f3644ee0f43f081542fff9872f2310fce9f6519ccd7afdfe58","0x1bc55176e21f9c41ce2254d44a6f4166163ee597a0bb1daf8936996312ee52fc","0xc80bf6404072a933e7642954c8b7a5d3b075cdbaef909fe6ec0fed29d9f9dbb7","0x7073aa7c0e249e3ad718aaf30e78e62936bf9d4266687576b6148fd0119274d8","0x9d483a1f4bc357ebe64eee99903494b9ceb759569c0db0e438c070d24cc67223","0x9322494b16fe77f9d6bb47cfee97308ce71035afc6685a93fcb03f868ec0a89a","0x3b12dcf838cf3ffa3d3532aaea29c4a3bfed46ab3599c2a0e0a52cf3930ad491","0x0c958bd20f0b20a082304a6bdee96e32d4f2105e2f67fd2beb02198cb5902f49","0xa889359b027a04818e286393fc202bb8c446da597a2a5df6959a6f4e74f186ab","0x210953c1b33f09470091f7d02b667467c3cd1b0f4c633985973a99c76a9d6f2f","0x16bb532f81776ea39a93bb2ebca580c5a823cdb843172bb819bae0046a4b95c8","0x85d8384af0ac3d1e3421dff7c7cb9c67505732741afe0a92fec4dd2300f193de","0x2f1ca0137532f20974517ce4c75705b6c22520993310a96c27c8b639f0442911","0x785f3b18a7b3194f5a380427325a0fbcdc6f3b89c368933a3b62055b7f84038d","0x41d5e77891fca74c8e7642234363c10f42e6bdff16795292755d124553e1a69a","0x353f8f094fa9d664c10d191ec25929ad3e8c05746346e9c11cd64f4353d855ad","0xaeb0f39aa5d8a20c83e081d4f28a38277519b47a04deea6ddeb1998aa9f2a9b4","0xaf19d602f5b205be142a26193c1a8e358321e08d2e268a47be154361a97cb5ea","0x0bf9f5381841bacc705a328f50f5e5612bcc26d01994c8d515b71941d7efb19f","0xf86974ca5b60d1ae75072f65a85e9d1be58a477382e80bfc392ed141f7a062bc","0x9278bed36d57ba579d9bc132073885bb88de029d7d948b511f805e1382468603","0x61f1bf8bfb11d20a06b46fba87a1390c09cbbf7f9f52f59baf8ea05eb5eecee0","0x117de9531d7bfb906fa7e6357a288832a3affed0725e22e014ee233d97d40835","0x4a246fe69541ed17d328bcd1bf55148d69deea0e8fbba8fb0152a4530f3a0fe4","0x4b3af292f551c9bf204132c15a7b1ad80e2f34ab62e46be6c04bfe713f5f8f9b","0xb5d3cf366da5a91f89bfec817977babb68ae4bfbc50ab2f2f767d9f74f702ce4","0xddcf7be0a4a70f02eee3da38dac1ba1597de8120f4c150e628c427c4b10c1a7a","0x399be75332275f2f9f6fa6c50da5bd95d108d706aa1cbb00a7d43731b7755cdb","0x8b28c3d012d98ffa4016b93132300cad4c080d9ac8629225be80ab53ee964c8f","0x9cc05dc0122ca9a597118b802f88e83fc6746ffc624b3b4f1bbd9841cd90f223","0x4f56672e89c781ee7ad65d328902d17042a164f2826eb123cecd578867475842","0x70651ed9c0c8d9eb7ed28b6770b119c18b10a385d2b7ae75a52b80e403fdb0f7","0x628f7b3ca546619e4600bc85f7f74413d7c6f7b95a4ee760fafe5b3538c1cb2c","0x6c07d9df4fceb17bb8edb2f28ead4cfb97ee3c6d6d4b592272091403aabefae6","0x0753e74284e5e0df6e617d741bfed40a44d37f3037fd1bcd424ddfe07a6b2972","0x0e3214fb1514707c38134a97c4b0fc538c828d7de673d0c1a69304f415ca673e","0xb4554aacabebe32ea9834c85320ed9bb4428ad59fc41d3ca070f3e3b30e5d1a8","0x77b7b6eddc8b988cad512f27a07c219d71a8bae0527d3ebf481aa3a7476e0297","0x7d84a222c07d6b1d2b9ec9cf2f15eb497b52d0014f4f5879447a98e402344a6d","0x38f775b574a7be37b21c34462ee0c19bdd2de26d6f5f928a114e929c97234451","0xa31a5d27bc18c31439b93acc6e8b38aa837cffaa95789ed3f9bd4555abccd4be","0x8cc5ed02048b472421f6adde050f5c66d4dcc0f59565418cc6f557811a66eb53","0xf703b18660e7ca79b2ba69c85fb2ad5f246bca8aa35cdabbf47216741dfeb4ef","0xf24cb8420aab5010e0efaa63cb366e950c0c96141d1fc4451cada3206f3c4658","0x4a7bafa6a9546f881fcef89beafaa6696037422a26504c952cacdb999ab0b056","0xf03048fe36382760417a8574ec5ed7ae490e289159e941e7b22254e4d3ed9c7c","0x829e325abb468342cc1eae1ee6beb2e439c9252b05b7a6774263df0110780f22","0xce75d1c240b0e42537f67cf013269388b9d66c3f4c16557cc3807118f4d0efc4","0xfe2df588419cff5ae80ec9112024021bb063396da146b6bd466ba5c9251271d1","0x5fb23a06aa939faa7193898a5ccf88a119d4340a2302b6aa3fddbf62e009bf50","0x3534e0c98605fd9fb39de012d4dfb737c44e5d9090b5d4ebe87e11696528e784","0xc4c914455ea08f37003476891bad2c69d5f63301014128f2d82df2b52e27fd99","0x797f4097673c2689f566d21eab7c32b00730247fdfb5c1e05fe181dfb17c3a30","0x58b63a5485645f712ab31e091a75b9c33d807da35e9ad2cbb8fd1e27bef78694","0xd53ee9ba0e782b431ef09da8f574136166db5ecd3b628c69bdbc7dc59d676d8f","0x2400aa2e3dc7801ea396b1616ffbc32ae772312d200475a5ccad99928cd4cafe","0x380b3e0344b4c97fd7028e8a4957d6b286fe19e41a8e7e499736ee9f9e75e337","0x23c1fee2ef41a92c4208a281158a8357311aa04279c4fcee1813922e18104ca5","0xfe9e84921be70af7a2cd39aa9eee50d46e52749f95f259a0b6682d279234152a","0xeb4890812b07f975346e506504c1903ab011db4e9eb5741522aadf44b2a4d07d","0x72eefe7902337741bed781ed074f8e6dd58ac29f8f316ff5fecb33bf4de4a067","0x112fd9f01d38e248768c141c1eeddecec2c53dfc7680fdc4b9cff7b569ded305","0x1ed5fa95e0def9284e7e81c9a589d96a89331a53901b256aded5195e1f7608f5","0xc3873ccef527d3ddcada7825dee04ba42c3a7ab794cadbb0189076dc199d74db","0x4150a55142a7466fb2518111a339aeffc1986b72753bf945fb55347704129b17","0xb21287f12c0045c781e6964d95e8f1b2dadbe0f79a9723528eccea9c26c2b171","0x6afc27f22cd4ceb88fd2a1e2064d9b66b68cff63b7e36b8d3f0ebab13d63d746","0x62b1926010281e7ade488d85688915b62cc69bd0df7d3b592b9cd7a91a2ca399","0xc3a3135ce8196975ca6e747b121be89e6ee5b7aeda2f49cfa09266c7348ebc11","0xd6ce6a60b7a3847010040ab856a235ecbcdf5ea23aa00d892dd45059cf084842","0x47eac1a1d48442105c54550258d958c3ebb0c391736a04fcb2ef4df1acd05af2","0x7713a66e39afdc98199082b835d4ce328863ad753e942156b7374f369e4d68b4","0x0678eb24e830bd2032f808a4520b3dbc60bc47cf3286a8b7b8568346f0794523","0x41f805ea0ecb85099f5baad16e11d699c059b4c0ef8d475dba5d7b36e0a1736d","0xaf447fa8d2ffe3b38b6bc2c0d28c7c6d2573fbc7dee65e994023738ac8596b4f","0xf3ee5158d63e6d15a8a224dd4f4243430987d93b235c3d65ec76c1cbac2ebdbf","0x35b4705d3161a9c6831bcdcf649a9b827da10981150a9c797731ccd116f512ff","0x4f90567d9b5b0c0becf3bcb2f3840ad12bd424ae2d013d46b832452c37f13d89","0x70ceb9087a3edd2ddfe8f288d16ef76a6b2825f4331ce4935cf45d2e5dfbc4e9","0x6974f30e74b09a16b9479d392da366d527c9e328185ef0c6db1c1c49257f61a8","0x4e3472569eb278ca423489cb350b1b607871039360d48a3e2233bb83ec49a7fe","0x1490ea1863d3cd139d71ca98c1edbc77aad814f2703fa199bd35293bb71ee561","0x0ddbe5e974706cc3e6e7ea60148cecf91d9dea563ce721601a601f5b9ea3be10","0x13ba6f13461d2a077b4a1117731aa6040b1e268d6bb1a1c7ad0c80205c0c2948","0xc16e00dcfe69a57af383d6fc43354827ff1c523f3c16256ad3a04765a97e7fc9","0x11e147af8ad7a7ba726e515c68ac3bcb468ec8e638820b3d8c25e139fdea202d","0xd1f6d31aaef6b5285383213da20b4c98b9e7eac4991cafcfb37f4b652e847e1d","0xa9df47539df2d0d13c71ec3bf014f6162f7a58c8e20db63cc3d352d8d938278c","0x418e02cc25e9b8f099109e32be4fbe964a9768c60b36d6d529315cf0ee522b2d","0x16c20db00dfcbfd0f1988bb39f467b88d42b8f3de8a7f0d6c2e94560082a2652","0x5cc756be4a5561d8be3aa5bfc2b2c9f0daca44d73699e1c9721894a004b477f5","0x52fb513763c085a9da65072b6c46efbe4a63839b06bf06eefa1e369025026304","0x649b5f91888b3a1be3389132a79016e16ed3cc67fdef262979c3ef8316a66e01","0xac6af63f8623a2ee87de819aeba8639e81da5fabaafe0cbb1944b54df8b6b11d","0xbf770ec7c198474333fc23e98c50a12a9474ca563c6049f9b9a15e760a10fadb","0x9be1fd57716c41f96912200c2c68475447d8066953c1185e69004863a9fcb0e7","0x0a8e6d23b4df238e1ad727711d04e028d7216dd211b0e16f2cb53fc68ca1d397","0x33d22370a51cc6feba7083bc390c7d874edf01e5cc276cf90a107b6b97c4ffbe","0xf4bbe4b3c32c89cbb0630cc69322f601524a1426741cf932ae03a4d6cc109228","0x4dc0817102ebcd5e06bb874b73f76637bb0f62c3c25dd0fd88221fca3856636a","0x857ee39c0e6eeb4264816bd780b471bfa495e08ec99ae60392c946b964b270fd","0xecd5a3cc05d79b5fe1f7146bb0ac74a2dd7ea92367fd3d9f421e31c40925c3b8","0x4b52381ccbfd01ddae49ac6c98d26b17468b5ce3344c35a3755d509ada78d3ba","0x60a5f1cc8fa71c311529ede775425bbbf2170e1747048ff049163a377cf69330","0xd44c7f93ad2b9944fd4c289c8f419e3108f8b997f54f36a66dc38e1bbab32e18","0xac9a7b384d922f9568a53d8b2a734b5323962a0bdce482d93859c97dcd713cc9","0x00bb458b8f9f902fe820dcc3ae71c6008139ed58aecd68f7dd4e8ff052745247","0x5d73b708d6fdc1cacb9b027611f74b6d798b94ed94f999dbfe4e68d56ab4886d","0xad8eb9caeb61ed2099490c03140e3ff12e02e2bdae6ff53107fbf311680af8eb","0xd9ab4e579111a2cdde246ed1bcd9a7e9e678da22076b58f2db4dc13effb07286","0x98f1523eeda352a5ff5b5651baf5db7e888142d0ae44fd665552c9120735d5fa","0x85e4b836b0e938b091b8f49825d8d4dedc829c9ea210b185dfa6da6c5636ffac","0x06a999ed887ec29133266070727e44542d505a641cae7bc6719873cddc4d45b0","0x7840883151cd1fe3503751657c77c4a9465f55bbe81b0e863352e68a28d651b6","0xbb4d0aea45d78f8978da3f2cd7739f57d2895130fce66fe57e0f53d99db078d3","0xf6301053f27aeeb2f1f19787f047848409badd1bb707271864cbb0164a6e3fce","0x6e1a97a2f825d49f1953d2c51c0a9f4d00ca3005b50ec50b840623f0440e0f5e","0xaed23034703884daa74723d3f449a2fdb1be8b55b3aa01a5405acca1976de23d","0x6aa3698d7081595c338b8e4f58a19334e6f10e531c90133dced29b16ccdd4d44","0x4fef9294ff61e2579e3e02bb6b28b69d7f86ed69dfc7a9cf3858e90dc263b2be","0xd2f3d16f94a2ee30d270bf62024ffd4dce16f07f48ddcf96c23257f9256b88eb","0xf132005ce781ab2ef5da9d2d2702b2314a5c300c6cf92316818f0617e15c14a1","0xa3a55a8480668c26bfa941aa96f70cd4c3b8b5432fa4fe783f2b04c4d1a26177","0xcc850830681c1a0a2c4edc17b78cfd11df5cedffb9bb9b1e049d27247a05edf6","0x854bc12788de601bd85640073f296178da68a9ef46de489715634b44313aa99f","0xcb53e4a739c7ee435b9cbefbc54cd0e5690f0409a69eb48d65ee051c1aef68af","0xdf8bb5effc74d0941bfbb6790cc6f15266e6e8e4b9acd80c43f5d288cffe1708","0x3e8f1449b93043a63e49c3b7ce4c78e2ba882d43de11f6aac6d5408e8ff4343a","0xf20dd366acb7c3fadb71895e45b03958d791b7278f86e9220d705b6dea23c7c8","0x3d2385f1aee6ad4169cc12ae1a6e5d1d837c8312dfe1e2c75f98cba83887031d","0xe7450ae2367a7d12ca13e4e27532a73921168ed3f701f45b429d467272e586e6","0x110cf442f749f057c61214cc97389cc49626200b4a97f4ab9ec17d8ac583511e","0xda3c587e1a4120ee9b3660ecaa98a44ac17ce0f28c51487bb5dc565f3be2b56d","0x37de68658a4a5baef2d0b4478d3da6b4512161b97e02cdc9eabe7b55ad7d8d24","0xf94579c122ce94d1783a2cac6ed37f92f15599459dfbfa6412640886dade1e9f","0x30bedb7d7b077048cceb025fa559df6c19042bab610e2a13840b78d9e867ae96","0x83214ebce6dd0845cc2665d79a36560b3d8776132de4fa7609537dbe8878e479","0xf7adb4ef8ed0622a7c6113aad53c51fae8406ded5bcb64618da89e1f7f7ac480","0x20f79e29c797c6e2ebd6cf0273d9bdb5e0c2f528078a260a3c071097c68cecaa","0xda80a5fac6c9e14df3d254bb898b068a7225c4a6f179a7a9050fe99ad384947d","0xcf600e1794e9c8a455e64634d4b05a2a51773d934da70313e2203cf930724cba","0xfcf36c5b07de359cd953ceb5d3cfd80b734b13783519211216be9369d86d239f","0xfe124caa3f9c3df8e5e94b5448bc7f0c135ba141baf8a9d4eac9eb523a597e22","0xa602852ef281609f3e31a931af8e5455ac9b35e45d6924cbc1d4090a4dd8daab","0x3522edeb45fe67089870b94b5c84debc487c1f23251013e36fbb7f87e02a404f","0x51c475233813b774a3f7b431e3846a44585ba911853d5cd44ee3484364fb76e1","0xbc36ff3120f21f34e9e34c65c76e57dd2cae9354fe6bde509f41b33c123ea2b3","0xb3718a5a3088d2ec9e4ff5ed6e8e4277c99185ea3ab7d06f42a90a33a05117bd","0x9590e94f3dcbb88e3a9247e140791246c52d7d59ab052aa84458215c9ec91673","0xc2b03e0be59e61ea347b0ac2e5746133264094506d74ea6ff9067c03a7afe0e4","0xba7cb5b9fd61300f49c92c7cf06df397d2ca1baefcdfe60cafaa8c4c1daf6a0d","0x2b342f0080c5dcfec436026dae9f4a7d47bbcd6f123989bf6d55b11a4c7a1d09","0xfbf3d12ab67626ebbbe91bd1c48438d003d7515b865078ebebaae381fc0ac335","0x455dc7c9e6cd716869313c7b9dd6ba91e5aa4392ac5e8a7ffe0a1744ada69d1f","0x1591ec8ab5b10aae35817e06b21436652a1fbc827e41bf94a4e46dbd3c8b52e8","0xfc3bee72a04a6dfe749c5436e5ef0f04804a80b91b0284a9196ffd91a5a9b7ff","0x4fc1e131794de5436133a4670babfdc9f19b4aff05c74829fdd1c7e91d8997bd","0x5b433508e77b12bf23694fc7b1b6c01fa2b742aca5e1b115d5f337532ab4a37e","0x65e261371ad58c12d23592ff2962099567760eea53755b7d57ac7063890e039d","0xaac5ae3786cdcfed66dd6844a45f9f66902aa9b1cb83718f2434d70cb5217a6f","0x4ef685d0192130a8924d4919b7631f824ea8a3d8d7a9a61051a7e501ed4fb94c","0xb726017a0a8d0c5dc0816e3edd5e21beb67a91ab3595ea0f3bd5e96861928718","0x13e840d9cf67c8d6e0d1b2523f981ab1e45702e05910bd011a283f3951902f56","0x359e2ed7061cccfec3e92e77daea181a3c3692bb7168f5bd1f835ef4e86026b1","0x970ec00d9f0e94dcd59d8bcae2c232a3ccacd1da8a2a353706fea35ff62e9421","0x3a3c6f174e69b60138d7246707f84c74847ba5d1fa50d2e097550114717089fb","0x9136a90ee609414f29d55cc5e4d387d6b962c9ddb8e4aa46f331ac11624ed590","0x197ca446530abf07f01993c6e3fd932d76d47e9831899f95b2a8b82fb7beae55","0xcd30a084aa82e106830f367c2c55d5f8e7f4621cd0405de87d41dda4bf5d4bf8","0xfaf105e8e19a4768ea91034db14f0894358ac368cf42013774f5489c9cc28fc0","0x9be9368b8573145c38cb062085285be21477b1332c377fc5fbf221a515c2d58b","0x98915ec655078f741a93d488ffdcbdfb5bd0193e39b9acdf8c3b6d53fb38b726","0xb692ba481b855e575414e232d88c2848bdff0e7dd6365e7353801d42eb223a8d","0x09b767b73bfe9ee44cdd837cf1e32741fca80118e7f32e155e4315e0123f1fe3","0x3173a0cca15b6072869134efe2fe3ca44c94656a0f59bfce220bfb33c660afcb","0xb4fefbc3bf6c77510fc3bb2886d1c0f1fea0d52fb703e3c8248bfb7c64de433a","0x01cca4296bb510a081c3930c4c8241b552cb7af805dfd836879a565a332863c8","0x89a88c13512d29d7bcf121c4d04c24a5ff2b7f79281efa81c9abf005d550ce20","0xc70aae38d30b4e4a95457a5b1e692c8747fa3f1312bc22d316892c141131780b","0x83cd5b2d0dc023b0bfb9e09ca8c732187ed8017356625791953faae6e228e3de","0x3e1912bacd4910abb9f67a16c2984fbe5da4719bcda0ed3f0352e44aaefa593e","0xdc67021da78ef54b0664289ad47426bdc21ed9d052284c662ddfdb1e76870a09","0xfcadf119f7daeceb83633dfe3b011bcf3f692336c8f0311420cd7cadbd1fdf91","0x548362e136856d3604bdaf2df483b8d356e25d0ad3f8cb818c7221dc916b0f29","0x1f584add6a90eb997396ed58f4e1619dd1f319c8bb32b339175514af0453a2a0","0x874e2d5792f0a7bd0fcb469690271c696ba713573aec52f6d00a8f6b697d7c74","0x8de8e8b9706af0a2d5f01d4fcd3fcd4b254bb26ecf68fe20aba755de496b58e9","0xec8c58ca899d1b8b0c92f4588796207dcc4202ea054be4695e4869d485577ebc","0x9705944ec73d9e5111c09c8a1e3a91269fc16269e0494d0dff528d341bb605e1","0x00c74bebf18654c80f393d279f4efea787a11995cb3bb6bb3e40ff5a9f2b0c83","0xab428f3d5d4e7e0fe906d1297f04df2eb42870ebe9d6616443a4ebc36bfaa56f","0xf8931fe3ad35d362d44a9619cd6f5b40cf1acf4f3d95d0d59d08604c89978236","0x9669a7765b60a8be8f23c200fb653287d75f5f9c06e8f4266f62ed1f9d109ea3","0x57f1c2fa3bcc3926d9430b4496d5824a679a6bd219d2a3901e98a0fa336880e4","0xb28cb0180d03cdd640123788d8cb7fa3d776cd13dc5a189d7076760920dbb430","0x4558cca8061edfc42697b356764d6bb850e8d68a68aa26c5fe29e8a283d46bf5","0x21a668d283bfa91484a3b14670d148f0f6a5ddf8da00c211245c7530570f38b6","0x4e5ac70afb4d7425e82aca20da209b743f3489032057d852b0e43d440b350c50","0x815006b4bfbb8d4f5687a6348592a2ae4899c35f87d4eb1ad1e7fe5c02441420","0xb394a2bf1c80b2d0403a601f002efad68d072db5836df5d2167a54c8d2d984cb","0x062e5a6cc429c85a4efb3a8e613d3ca8fef52911b166fac4e5a8908fd2180132","0xe7a292567f49ff2f51dfb43504c7766895329349cad57db9778d5229bbc93fd5","0xf82bd78c80be44fddd6555f0ee3e305f737d3bc22dc50fd4630c4b41a864ecc8","0xf2069d9e0b06a29ad8ca7f2c6ff835d2ddc27a73cb3c0c662c1fc333f0ceb2e0","0xf0248412af974aeaf4a74f2704e0b2b1896e8ba2dfe59e86cfcb504102985aef","0x2d8dff058d59e06df242e6adf0582f296444d823a6735712f75e9a900bf12484","0xf5c2c75184f0c9834d00927003d403a58a9c40a987cd11656b99564a343dc57b","0xcb6b279204dd88301c6068ee95ec787645a90a0de350e12a3aaea03c15c4273e","0x32b8ee98815c690382b0ad445468b7f370d0df4d3596bd87a1096c97fe0c0cff","0x345b8bfe579ce4349d1f461a54382917b1bc34334fdfda3d5412f8e41ad48fa7","0xb9bb8777694032e90aa47c9a68f96752e78920cf8cd5da0b7e409041947eb0f3","0xbd1f9c6dd49f5f6d2d919adc78872b5897e5ef9050b9578416cd310ce512ce8e","0x6a930d3c4db9ce36b0ff785db3b013e6a1eca94a4ceb556a943759fb8758384d","0x656b7a37f73d3d1c60b74fdd8d083fd47d149b579810e7665f734038777ccc34","0xa766219a3e37315b388ef0f9c7ecc0875cd2bca9c3023b5261bcc3d9cb1a74a3","0x5b02b772a3d91929b42bb12938bc5a1212fc7829e3be26bcf98d787888bb07c9","0x03df6952b2458126363f7f47cc48e4d9ca07c0d6594cae740a0654b820bd80a3","0xf7e23b8ed376488a88f50588b064d32b8ec7925c8af1bc4359f389072847f32e","0x0a1157256ec1cbb7029819c71249d081228790758be406f3f17578a64cdd479b","0x42a61229a34262b17f13dd76585c15d7a479ba88fd81afcac6e7d40eeb2a9a28","0x1fbfa1b7ceed7fe8f26c0f9d77c64f404aa2a15635c13aa829d2344e1f63839a","0x8c5918a0888ef5dea0f2f99c8a03ae2a83c10db214f80905367574be9e809332","0x9d82cdd20a7541e1d5198a484a86624d084eac7848b0099b711f74664b26436d","0x3dcffacf4c42269b67c7ac372c93712aeb281136a9f11b9592891a385f84db81","0xc544ac49fca06fd6dc8f176bc336dd55161855682cf73c28ec3f3f337670f860","0xb2f4dfe04eeb27d42886ae5df2efb6b77f5a70576ed5f7c426b96c378039e36e","0xc997c2bf6def4d2c0a213d875bb54845c57eb3d3618079299c57ac0bda778855","0x7e2bc446e3f3ef627f4f193fa1fd5f5e3ba83ff6e603825711713f76db342c3b","0x365c500c47f15c7d1040c827eeb3c0fccb54babfcb6672c853fa0899ee39c334","0x6871f4822cd60ff40997d66f167cd2fb498f866a80dd4a1ecca9eb2ceb063b31","0x4147b6a3d41cbadce25612ca4a2235c9bccfc809f3b07d8e4af32e84a2bf4759","0x7da190e708b9daeefdc17209d8db554edbd3b73274b818ff789ade9c02271b4b","0xa53906d4261adb1a4afcd602872b0d258ed1da9bf980658b0b20f3465f0b9936","0xc6890a2b8ae38b0413033bf53c5ac876a6a25cd740ae9927dd51c4cf294cc3c1","0xec90483187e8d3bfb07c4e49f6e5319a64ef138ca88eca45774e7da07a29a98e","0x69ef407dd3b71b874ca45d2bc8f5130dc92b8f8179272be4210b84c7635a570a","0x3e57925f7eef24ab0109e1a7ad596489ad92b06669e763047fc358de01141b9f","0x50395bffc859afd0037919dc4aae4d2b1804402cf8b8c4d774f7577002f70e98","0x513879e7e7467718614512c6f3d5d19a4706b03276d59ed4f36d3df297a3315a","0x3a73a3d579cb884916f59d3d206552eb99b03d2e5af2b006d583e1dec7687dff","0xcbec9abcfdb531e26c98bf42976317d7e638f2ec1c67c67170d39993f6d67827","0xda76784459c701c32fae0c50d748ee3fe92ff8f2a4cb421a45ceee31e4d5bed1","0x3bd755fc394d73295d2b822616388177737e6993f5a496e853e1262eee176917","0x514860bc1343626796a6c9d71f43daa722e730036871ba0c8d78e0fb9c7ee7a5","0x502fd7d1c377d14a91dc026fb65c7d4f088a136c476e856155241ab5b97c2b95","0x46a830e46dc875d7a9baf7cfaa940c0fffd4535e7c3be3bd49f0d0bd9e598bc6","0x690015b7e2b0d38aa1555051ed988a6f91d1efa571e38434c95f96d9aa852faf","0x90f96d53f012d40e33d736c5e948371acf476ca04997d49976f314d048d1318c","0xe8879cc9c5a105f957500515e80036d12c0fd09911f0472b91e21bc1e6dacaf2","0x79edb32f9cc6570821fc5d9f3f963f5bcc81371415751ce4186029c8504f5d0f","0x5d312f42d95b2b2a83cb023c106b99f7140d300723cfb32acae1ab1708992627","0xc449434805815ddaaa6cd75f93ef3cbeb0304f8187beb503c2cb35f19a860b51","0xd6b6e53f624cf04ddad6011c4219fa4bacc0b68e2351706f34bfc44107c44f45","0xf26735231a0ac1205720aa33480004c6f73a18fdb14889d3cc8b30adf600001e","0xbd90f2708063101e114bd204fc3ef47304fee1ec5817143579a41a721c562b03","0xc49a5abeedc587e9b2f7151e52cfe78ae059c28e123822da61862298e04cd346","0x424a387740b6495066e666059cb53ee1176bda277060c8c71b51977fd5fff3f1","0x45548473e65dc960f35aa1e5b7f3fa69f7da57d891430d096d755ef3d6392624","0x62e141c4985bb20a564b079f31184d8971bb7fbf9d77f22ccd0174d83fe5cb2c","0x9b76ae3ce0d40513cfd5ee9fda8fa84532bf0cc11bcda36944058b79c250835c","0x2e1da286c39328706282cb11b5eecdda2c47f2da79ad9a53d985d0ce1ec1b645","0xde27ce9073fcce37cfed86dd6e9fbc2fcd7279a7f86e67aa45c23348cc4bd999","0x54ceea78ee3e8888ed920757d079bf6136b053c77aed4df808e3cc521816b5c3","0xb39fa8db1e46919ba359846bb40bba0a79678d39168788e289572cddbefac91c","0x1d6e95bea7571b51156f55a819bf6eb298f46a4c44485ad49cad714cbf4a438a","0xcc02a4989a211d05263b89c99551f04621d975408aa7362b0a78e649b07b0ee6","0xca82918ecefd5c893f7ec77f1f55c7ad4e38b243d277d200602cd5cefafdcb53","0x3deb18568d53b87364e7d647d5b1d7ec057c2b9cb201e9ff86469bf82ca58abd","0x5ed9d2ae314d831403b34522a394972b51347b17fcfffc59e618c95cb7d34490","0xd79a74dc3d9535cef76cd4feae8f29e490b1f7b26d39126af503edbba8d9c724","0x011bf58187d194e346a6a45bcca5694b22e7d89ab00cac49d00f5e5916849402","0x72d969f094ea246c6e06f5b422166d0b84be7025485a056370251267dab5140f","0x997fe5e54843a8debd8245efb5f99f2cfccfe5ef3d9dba4610c182fd1c725cde","0xb6474a01ae843f149349c59133da76849d4fb8223b64f4301a890d957292272f","0x562657ff259f13d4592b9c2b2e011e30e30e84b405c0f10e1167fbd63bff027a","0x51a2148b5f2e3fd420dba7c10cbda0a94d2b20cf7ac3e1a3526d54fdbb2c3cd4","0x8a4fac1757ac781c2212d8bcd0cd6f43f8ef252ae17456ff28da31b7eb67967b","0x5f12a99ff281c28c2fc6abe5f881c952a3d614aa768168403e641890936434cc","0xd3dd9614106bd363e83f947054fdd92839c4ea21813c58c0ab2646eb98e98e6e","0xe3db645af52ca9f05d3ec3336baab0046323c643f34d2fdba7cc704ce5e560b4","0xe8b486370dbfbf244889fb5d52bc9a4f008504f85556cd95968f382486095777","0x02a5bfcf66d11044d515d4f94c5d3a350d42aca09896e864f187e00c4b7c7c15","0x36b0ad4efc857ea532f6004c37f114316cefca17f0032aecdefa5124298f497f","0x28fedf5730a9217a3f49da53194201932f477d4729f984d8a543133ea7f20d91","0x201727ccd59db1fb01e93d4da11b9b5f51b152e2b1b75b77c4be9f31e157460d","0x3ba3ff48da4f46b4ce280fcb496f0b7ab6d4539da1b26c58d3235f002fa3ff19","0x25fd50b136452c982d6e763d03774640379c100cf486d2505504dd268fe99d4f","0xf16785a82a16eff11556ab59ba0725776b78bf36d5104f18460727891d378c60","0x611d106d65b2e09ee17575347e5edc227ab9289e9b743db87cc98ebf97073e18","0xe7074e02efc4071584ca603cb9c3080937feb74d5af90db0e17c5648e9bf26f0","0xaca15ce779991960eb0f8754c332bc520e4c58bb93f25c85f1974aac09314803","0x4d79fa63f6009bed881f2fca6e96dcf4169454669453f934aa78088af8ebb06f","0x566cac6e0041ffccdf5df58eb5fa6ad6da8e1a7348b19aacf0f89abb9ec9ccac","0x5c1d2fc583553931715ea2f6c157a79ad3848c4ad6bfc38d5f00723bcd55c3f9","0xfa7df5f8f545c0c1e986198d63a4f0b3ec87ae82869f5c27e2f91c717f81f825","0xe229908d860d689605f3292a62d3b8e4ec8dd3a856d0da6a1fba2453ea217feb","0x29e40528da6afd837797cac58642cc7e7f5fa4706767599d6c044d7e0ec666d0","0xf61e87ebe53a26d4f54dd7bb602e06e2071e75bf3c42af4c2c5b5153e277527e","0xba360df45c2bef070b2cb57a88be08fdea40b5555c7b720983fd9e04613d612f","0x9ebc5734174e0cb59dcd535714feafeca729eb9df9ff0e32c3998b96b8b4f2f8","0x65a4f856e3b3ae68faa27aefaccb6d53b3f65243d5f3edcfafe4a63bd6e73a87","0x6796b85f8bb6cc1d442d3afb3187252db60b53e8b66f45820227bfc695047c1a","0x429f6b4d06f0f16e75764069d1bf700fa5d17c397104c2c834bf276a86324cb8","0xfcd1c3f528c230d40b818d83e1018dea0b9644ffbee3d465019e9639cb4e4062","0x602b39f67716d1d2cdb3487692386d9cf6482731be31079452af5764483b6397","0x7e3f8fdc468e4ba1d1fa9b3d27e0a27d5cf0aea575fb1f44960553de74758d8b","0xd9f5a29ab3084a9b86119370782231ad81d370d6ddd2731eba4129ada3de6075","0x3ef426be92a36cd9b5e619597b6a4f8aa9af70f207f692dbc6251ed019e0faad","0x5d2426c304fc4cb6dd1ea3fde29357e0e9c7d825705dd939bbc357709a300a6f","0x4f96e5df987cd14c636b36929703073175241655945590c60b595b4b6eea3cf7","0x0d584ef104838ec239eafa89953c7a1be92b136456471d8d704a256dde71d41a","0xa93a1a8f28f41352012cdc4f9ff4c70306adb925f005078166e337355eb256d9","0xc40406d104e0b96b98eaa0f3e0a8b8e61c009a7589c831d86b4ca75f13f213bf","0xa2f6929ce9b7d88277846db6517828c0a6ccb802524ff30af36d52cbaf75fb26","0x7336b6f21c273c4da62fe5e4b1939aed805c0b48f6d3e7965aa4cad96e651ccd","0x0155f6e29bc0b74b8b9f4a7dbf3a05b60c383f2381ff48a2e30d744c3d54a8c2","0xe667f96b63b817da8a3f4ffba2947b55da6e9c63e4c94ea38931d83670e16b5b","0x21df483d8dc4203f8201a7c9d1373c7a6eb7934fde3258a05c1704da7d835e21","0x3fc56f78ae533092a6729a0bfbffb7c60d83cc7fabe41b4668418e6d50767032","0x4b5885dda2537a7044d7e67fd9e3839026c30414ac5c060885dd6387c03aa852","0x486611ab1967911720ad6f06693ef280a86678370b53dba2b16878762e326689","0xd52ce654f3426998f5c8b55c443169d2afe3648d5c636bc67b4683e83a1a4f1d","0xd362d89524f1cbcd2c8b45c06ee27ccfc7e02d84592ee7f6f151fa6bf5064f73","0xda3cd28ddad867f9191365f4686eee4ca0729a265bb2cf3489ce27fd2ea42f5e","0x29abd8b5538f508208673ff1525cd988b68f7e257a1a1bd86b0987858bab09ca","0xf6c745cac32723683ef63436f93306ab389da41d7e845f6fcec319dba85eb601","0x8f75a0b33a168ade9a7ec109ad8ad3536a0996f038958ceeb310ab004fb01760","0xe39cb68bc34146951d2faa4fa13a61ed09a5e5d6dd8d652eb349111cd29e746b","0x3d26309acf915cc45916ecf51e7f8293c58ea89d7ea51af711e752b08fa252de","0xb913542a8c02ba36a2df88eaa0d7142c331b0e3f035ffd832e5ed4cd2434cb6c","0x264b418cddb4b00d7848683ef6d05f9dc76d93088f6636f55cdb727ed9b401fb","0x98f3ae2012ae2bbef852b40a75376bf41a94d32b433587e2f2236efad15a6d2d","0xdb57ac93fb6a71017d850727869dff11a639c74a274e9c571a708f4ebff34e26","0xef0799c2bf563094927e513fa1f7d23e82376665342b002c64119d7d7e5044d4","0x81fa62e9453e51b90682dd6814a6a1b733e4aa7a5f47683dbef105ebcef3356d","0x340531e85c0eebc710de8665ae8a44722cca1967ff4cbaf9ed564c567971e7a2","0x46110b27a9b764740f89f3e5809b28bbbb2068c53eb8e1a1c7da83715fb32cdf","0x63003cb1a4b4374d3ce0607a71e5ab35cce99924ea555617a633803ea50e5b7b","0x088d6f709589d0c1a1b6f36bd482008728343a58549a83364ca736e7e7978173","0x7a9b6d3e6151a2e657f30e9f6d0211d77e164359d883a18580a81808d143032a","0xe64ac1ff94885336ce7adf01e2f29e948036582b08e7f18565b0dcd94a612883","0x071f13ab3550f3422ca7db078bb288f24e8ddfca9cd9768416c6f22fc8a9c8d6","0x2afecec626d2321e510bf76d628dd95c94765268d535eadbee73301f9cfffd37","0xf9c4e050ab7eaeb3abedba9f326faec47e52131a7d8a1cecf90bebb204deab8e","0x8901b2d566310f5d9ddd7a7d707b3d8babcff81a1a4419543bbdaaf1e0b390c4","0xe7dcf74ed1bcc3f53db4bfdcfc227131e1a95aa12a9a26a3e4988d9967db6c9a","0x267de43bf567e6c998d67449607e04a00b2094f18f8e5f2891ec1ce47bda4875","0x3de804d79560dd3e4301cb656e0ae17ea304e68b696b821d616a1df098066c43","0xd16bc7a55138fdca29dab6fd9c2e5f7af07a5bdfaab2dfb4a576ef8d274eb006","0x5c6cca34d8f06c6ebbf3caa4e900170762b0458adbf19cdb122508adf3b7333e","0x55502c32c8c54602769ad934e11b9fa29f594d47de2d9efae8fbac06cba04dbb","0xaceebf050091df0fcdc6ef6d1ab1b6be7e58831a82ac3a27a51aa01f22314d9e","0x5d1f11c3c7a2e50107cb58c0c02bb15d2a88aa1272c0ec353c86959200ba40f9","0xc6e917d5c138026360a4cdc1b36d48b828e9d88942582c5d9dc8a93bdf77c2e9","0xf56478262b33fd61fe6ed0704247cc3018c7d726ec19c4c42fe57110e6f059ad","0x79fa042051373c8486ab362dbbb72a61f56b7706c8f41362a8670305b638c72a","0xcdf53446c05ba740bd66ba07a7c9b1a4ab714e0de4c95e519afb51ff3afd23ea","0x1a7c85cad11ec099cf4495e72f9c2a63d15a0c1b73ed293b048df48337b70711","0x547f62798f46d5e9fca984cfbe8a5549d738eb24f25a8f4b13424d4c17b079ad","0x2aeb90a432aed16e1c8c0a024adaf00d28cc819acffda0993fd2e6f9c76f1452","0xb3d8e90e9de6908ebcce515ee46b590bdc4ec66c7f77e0d28b4bd1c90e9119c1","0x28ffba821af6d47c8b8db9739431e6b97e29af2c2ecb583d31a26310fa26e53e","0xec18d5e338b832bf3ce47673f73c0763967a63215ed4baea179c0d8fcb6df4e4","0x83ecd7ffdfa041600ae6bdca3fd8630352e191feda46c6c106dcad267443f2fd","0xbe292d690e2038e1e5530d001739fc066307f6c683674036b125fc662b637e1f","0xfaef339ae7e808a42dbcb000133ae1111db4d36593561c5ac75528e01c0fc0b9","0x838f3e8103963d1c7383a32db3f61f6eafa3309cfe512cf8b8fed3f460c3db68","0xfc463207176c996efeeab0fafabd52fb141d8f426fa177b0e02210f1b0e61b99","0x2a363c476cc5f087154888ed37aa70c2781230bbce767702f9b32fc394bad0bc","0xcd7fb179eb3893e396e38c612ed605b8b2ed65188144f9b12ca085f99c373eff","0xcb8b7e347e46dec1ce7d8aa41d1e0a5568d32cb98acfef30e278008a02566e27","0xd8c98dc7bdb467e284d136e84e8d0af9a1d176a17825c9ef9ba4f2395747c1b9","0x49ac16ff441ad407aef14826d9958f30263175d98fa4f136fc62b722fbeb5aba","0xed5265726cfbdeecf6ebaa19d99b09798b0ba4d2cef2e38f2c09b5e7b5d53056","0x130ed86b0f863bb8196830e3f019f22cc680f25b90d05083a565363820824e13","0x6b4e6ab53fcd109b3eccb5a62b0e7bb94256f6bba66798202364c524e47f09db","0xa3af5d9d79114f01687c9b8d4c139ae2d47ae1cce71f123dbbb92836a4456324","0x84774fbf107ee10d2486d891a2e0d5fb1f10dd5683ca3a41a6fd94a51f437aac","0x9f189375bef4c7d205cc8f560e054d07e79bd8b823c7ff9a26c8aca4f91d734c","0x828c0178362a80f927d2b133d4ed5ea83c5cd7c326a2dc0cf03787ecf18231f3","0xa917888622bc9589534f319742439c0404d3dfa09e5faae24700f9beb634cfa6","0x2b1104f67c9aa3d03e2adb313567fd15a52303b7219b907f3d87b1aa99080fb4","0x2ab139c41c4fd7715ded3d18857c36d0b2cc63201c6ca464615e84a6160e4c4d","0xc07a4e93b26eb4a4e5a289781518211169a8534ad21e81700e611d8bfeee9fa6","0x8f0905c550c003f05a52c5b0fedd8a50db5f00bb0363cc4f8ecc4d4f233b857b","0x7f0b65cd3c04717b4d3080eb39eeffb0ec576a03f35907b521b08092e0f3411d","0x65e9a2b085dc9dc477a589b77fa03c0fbe7e462b0abcfb870e70d623544c388c","0x6f77c80b5d588150411c368741ab9e304926fbaf521defbe6eb8788ea65378ce","0x4a842217cd34b034fc688cbe3b79b0a8438b48569ee088cea42118c32d36595c","0x0779d818db2c338d0a045bbcb00438c6d440739d3ba07a5e645b4db4ac52aefa","0x3c5db30ed6dbb41292ea6bbb1c245fd1695017e1e329c6dded5d85eaf497ed92","0x53731953584cf84228fde312dd4f629ea6a161956a532a7b3d1e88d9b5886e97","0x1a36b483f95ca989411dc2a17761957c70097c98256e3bc241fea1b72d42ea68","0x8dbf48f9595c0aa5eaf00f65428a7607e6e481ebe0c4f4def82b1876ad91a2ce","0x72e636c4baeb0ebcf537568e69eb8d3911373cbe44371610dadb19d9c96397e8","0x145891cc43449c55fd97c6e7b4aa1a679d5f6147dbb762b60a3f37f812df6d77","0xbe6d63cbac7340e07901a4f03c0cdc59768a020efed335f815c78679c0878550","0x59c1a2858520ac90eca28177d75e788abec3364522967b2d83b072488f9e197a","0x5bf5cf72d5012f6dbf5002519975b246bd309076aad41750584f170dce36f3da","0x90fee0f80a80866b8f438ba269e66ba3fdd914d77c471a84cd70a6541d4cbdf3","0xdea80646ca7f29475e98081518e50a88ce20d784865e87bc275ba5ec24fb76a1","0x69fd34e2425c795a0ec5ec8b30c30d11b4f17da32412231ed362eb44737aeaae","0xfa73e4c8f688512cc0a1f4c2f821bf62cd9a2330f09b2a1699ca2864e8ab1d78","0x67806dee722636c0d81433b949085d144436c220c0bdfae5ac7a4a80a9cbf81a","0x1356803b983ffa7d57675a7da964b10c572d679321bfdd48b7e9f000c1756347","0xad82515db867218d1d03e0540b5f5abc238a6777e673194afaa67ee530f29046","0x83ffe5a4550fa8e551e6eb61ce6aa8de4ab411c27fea51fafe1142d5d142c727","0xc48e64030a03ce5adb1596eb9caf7a4c14c90d4f6e7b6ecd4c19a0b45567d5f0","0xeb39518090c21c5134a806e745df99c37f8b79566ac0b057d0a80a77f74cc0c6","0xf48d6b8c530895d96d71bb4f1c00119a102a0b84311f84e13409543d460931d3","0x70ce898e6b3a93987c494b4a5f61a0a0b42d2e857db087de2df41912e98cd79a","0x4500e50b3d67550959a3faeb0d3ff803d38698ddd73b2a104c5d8d86a58a70a5","0xd16131b8b37b4ae684ad27bf671e9f512f1416a3de9285c81c99dfd12287c922","0xc4f8b4b8815e1dd5a828eeec7b346dd36595727f39b39ff94c982efbb8a31879","0xc04c3565961a6fcba38d6d29004092fd4408e56e868aec552c0f2d82b57425c2","0x65237c56b1d568075a245bcfa78aca04c07d809f5b6dc953c34419227dd01437","0x59dc4887cf01a9cf7b6f5350d32000f2911594abe8336a0c47b2f1731ce33330","0xc3ffd5ff8cd6b5372ae07fe909686ec3ea7f5a335d917f8f3f629910a95dcbd2","0x889847e9c9dd73f5666bc9d75ac0520fcb1b044e8e0f6368306218f449e6428a","0x64db51310e97325443d13242d3d0f1a79b4e8fd0c7e5f4d007cc9c8d9db5f4ce","0x33ca7229fdb5a21a6838aa87866a259ee8201727e3809b758b6c8767b2e97d7c","0x35d789cefa779c48803c1f31c3234dfb2a411a28fcfe27754cb90de384e6e27e","0xb108cdc20f49fc4fd53a84a67283f7d49234ef20fe1707c90bf01016308f027c","0x2f6ff20902b607c2c7de23095c1378677852ad6b5f724bce96fb03d8e92c7433","0xcf19542c97d0c112d0b06c27bdddfd958afcc0b1ee29331df1bb480e9c0477c7","0xdda6ff8189a23f10ee44651dbf91c914fe2cdadbdb7875fc624ed91eab0672cf","0x2a8e550bf5a0cc32c84f26f25a0944e5fb3724a6d4dc23ea19c9545a1b8ba59b","0xb615154a514f927191bd87d6c61dde6d747910c1e31a445b6032db2576bd5f1c","0xfa680d2a1f854917f339d56c7c221b64fa179a9c8488eda1341c0e4c16f10c18","0x5001f95bdf6d2dc1d2e0f73458030c30b36393cac82b5812c37b726b4a2b0e77","0x58fbc48d27b0114a09c2e66531d48cae03fe029ed576b2b751402a4e1933e5e4","0xcce53281b3ad92c5926c2f36b39f764d632dd9aef8c3cfe6b949fb8251d91be1","0x71c09269ea98a111a67ba5d71fdef1f827a050c11977003f49c0721b519f706a","0xa87bece1f99c87a6ca1dab52bee0420b327ef993a65fe8ed6cf1482b23c4c4b5","0xdb25a765f57084ae6957e0bedb0c6e7390ae194377abbed7297b670f60c191c3","0x6d3c2e9314e1cf869e055671d9788f75407b92942f5721c39fc217c58cc77769","0xa67923fba0d9fd7548017567ead76a7f61ebf758262a0f69e3ce87427a068c9e","0x73e214694ef458289f0dc0a3115a1f869c07a858e87a09e9e7779a64f9ae692d","0xa14959a1de597873c6afa1e245b2478f6862dc3e599891f945fad8ba3e1c9d01","0xb2c0b0137344687290c6c21eee78c334408d774df65582212906bf8ddd0d2f99","0xc86300a80b0d46ff75a107b9f566acf8a9b502d1a2c322535dd428ddbab1a0b3","0x789f805630a1b4f23a239dd9d5e85aa845ec95b50a2717028e33b3a4df394c00","0xa7b541581715955dec1e688e3e11a59d6c312274f71bfa05e7e653b670687d50","0x11ff395b7e7d2537cbaed9b8f0a88d7caf3f7bd35f1098176b815601d3dadffb","0xfbef1666559041a854bb77a2131288bb601461abf9e4fc1f3cb7a31a250c7f40","0x6a59e2745e263a9f2ff507b7376cb491dc8e7e3094dbd43b8e45aae280b5bb82","0xcfc6a28d072827d0891b202a653735781f922be15710d19edb6679425b57609d","0x6b1964559a26f0bcd0f0b4d66dd1edcd989d590135954731ef85c06f59192952","0x93d7332a0938d12e0af412d0e166ef4297f3828047578c52877bc17dcaef7183","0x3777550b953f0034071fc90394d684a240db66e7010431f9d3ab44ec820c5742","0xd4e1bfd18839a3b26cb7db486242037376c270035b0f7de2895d3e114a0f3cca","0xf1088e65dd2bb858b2c67c14b33509152a25d17b5c291d0dd040c022483cf246","0x8cd1a3e8a249031d8c7dac0752cf81a2f146889296ab36e112d1585f8d2de397","0xb9f31c87fa45053ff9c1a19ca92e11db6fa592c74abdd6ab05008d11c09b619d","0xccec89c19e5653113cc318352e388f5f96e18137826d002ace31d0f389c03864","0x567eb91ffd65d0c65da99900341018ffa6394c134454367ec8ebc8ce2791dcfe","0xa9d91b764c66fa8145e36fd1ba258fcf698185fb2616af83ba967b9f74755171","0x32e58b1ef3ee8f3ed13be1641066f4ed018b763683e227c8112fb917f43137b0","0xbda592ac266de8988d065442fd7941a60ac110c75b924a1428f5fce4c00ac4a5","0x61dbb3a3d5513eb54d7bba0cb2c0f576719b40f78bdfe699933b9e4a0a515c62","0x1bceb3ca54beef22f78576eb0180f1cbd1b4efd5bca5ecdb694d992acbaa6bfd","0x62bedf575f83fbccdf22acf68bb281a2519013753a7fd6f12f29a9376e6fc77c","0x2d99ffd5f801048903945a32c20a6d9a56e414284fc75a392c5693a8970993d4","0x91a940f729f7ff4cb53453086c4886bbf71c012381d6f8e6bea0420936045c6e","0x071883e9a69bcfee26884a31a7538b4355f8555ba68e119d7888ecad57bab76b","0x3b1e43721c1bc891d3c256ea02d81f92d9a5ce0aa9bf015383e772849259cd92","0x64d7a5735ea3bd930d6199a247802599c51f9bd003fbe02364e6dd90577b0703","0x765987d7d78214b7cf9884ffce47f6840c25b191d6db131daa68cadbfe4dd3d2","0x7b9f1e7a79668ff97ec28f24ed58d632db496a4ca0a66c92fefd62f5b8e27df9","0x253026280380a7bbf04b76abbd87fb7873717e8a2351b3fcb69a688055501fbe","0xc6bc3f8c1dcab0a772a7b5dd624f9340fc873ad24266de9e61db5392da51642d","0x23ff24b24d593845f3c7871f5ab3ff7825ca5c0b7be6678e1bdd9ac68a4e4c95","0x581fb007e5cc81ac39b451ba968f2d7a7b9f61928fb2d2b6bd01a20fb58eea3e","0xead6b5337b03ac957446bd8a4cb4beea237883ded9d52fccbff42c036e37afbc","0x178a6f994bd3efb7e57b4e9a898fea5b392c3835342bbad4fddceb76477190ad","0xbef02acae652d895ccdb3f70573d7fe7645a7353fcb2c913be1d91ac9d7c79cc","0x350d2fd3b209aded263e8a8e42c259e2e38cfd0834f71c911df80156336079e6","0x8f62e6c9774292b046f190eda137e2d290f128c12b633223e41b5365b57ad86d","0xf6bbd1ab3fad49124394350c36b65072172d8d7ec0336dbaf5974bd5eec1a316","0x6dc823b92cc789d781d997995a9aab65c822b2ba86d503a0d2a4870c0bb0c2ed","0xe2c95523c89f75dd02c1ae0907021b3a3e08494e0933f9b450d34640e94f3275","0xd6538f19f68fbad0607e0d45b70e8a717a4ea152fd55d802755ec55fb2d0667f","0xddbe7735da2b25d56e4175514e82407fab7eacec6135621681e06b21cdf5ccf3","0x5789df09801eb49622ae08cd6ea3509047b5d3f7e15716bc4432782350b670c4","0xd84aee7d626aaf9bf907ab4e62a462cc67738a32481c8c0c40118f3fbe626ef9","0xc787160bef3e53c983c22f053227eabd1ef60e473d29c1ea17b09c30c05c7bdf","0xb830f458a8eb9628cd91943f92a07a8b80dc610302afbd5b4cb9042414cbcf1a","0x210b8deba5510e256aa2b630ee8243553a94be00cc8fba1e9f79efc1f4645d4e","0x5beab2ed504d73bf2d5b71959c4ff082b2d868eeaef39fe87413cad6bb21231a","0x748779af9adc9849a1647e0ea3cfcde3e50d3b87a0346213c67ea53c052dc7ae","0xa8ae2c818bf7c33c8b3301b43e66b9b8e6816e342855e83ee87e65e91eb7eeb2","0xa6017879ec1eae873774b97f93cfb854ada5ee7851d0f0bea08da62b5eb08aef","0xae77c0d0a35c76de0517c4c80c65d1dc4fa5d6da6d9ba526f30fef89ff738657","0x2820da7892afbc450cc9ab8296bb8710e4a7b46a47319deb7ec5dedc7ca0637c","0x9cd872dbd0fa893c40c6be1cc264bf28d37987972cced5071380b8bcce483672","0x89497a29383001390e0b33fae3af5ebf4aff790f9b5a683e3e4ffd4601e014b8","0x1b0c460144d02ef0819c425adf28bdabcbec6b504afdcf8cb10f85f01ba6c632","0x8a951ba096b330734e1f669a2c480ef1280ca1f9c455fefcae0e351aa72d7580","0x1ccc1c9443f947db02d9f0991731cbd9b6e9eafc47dcbbfd3bfad40193972bc2","0x67447ddef0ef5f7c6aef0a2969f761aaaaef1a4e708ed2f76dd0b6018d09d9a9","0x45704ce0959f8a8fd80d605deb7a740660a429968decb88d615a373ae3fa6b03","0xe1ba6d94b4dd33b66ec5469a5d39abf420bedd6aa14fa134f88b74c20e3e2e8a","0xa2c309991e93728c8ff156b93cf6a3cd11d536cbbb8d00d2699bcf30105ecf60","0x0c027d4d4a8a8d3f719e30865601d1554d804dfda464a5060b6172c5b09aa339","0x4aa7e6ba6e1e56d15904594d8433d8e66202530137e061ba11ac1ce6a16eb105","0x34e9f52de0c97c0feb43f12306bf5800274815599887d9d7f6b8305346da2010","0x9363428216fe1db1c534ebf6fba7cd17320501f757b4eb9553f5350006e5c9ca","0xd8820d8d81c0a6f8f3ca3e33e82b225521db55b667c88a286137e071ba5dcba1","0xbf73d4fd691fef9b240c0323784fd4dbf02bc7a781eb2ad1b4ef798452f3b60c","0x031f797a328a8b47179c85530669f0db20b5a1f490da581c87c7a8e8cd5a0cff","0x60d2316df090bbcafe3853679d16335b670eacc74e05da03be544eb203132d3b","0x3d5515245d87838225ab838f4fbdc2e072f02515b0e9f22e55f5ff9c8d885522","0xe60883b98113fa27247d1e1a934f3a9a80a629be627e5dc80bf750805ba84ef1","0x8c403c950b471aa9db696a52a8e8b0e8c4317439d25469e7e276d10767a45263","0x2af8bcf9533d1d63143d4a03dd2a550af70394f866fa13feb53baab127ef02b7","0xb3cea28afc9041d45faf1a2e311a60f8ac7e9960360d45f3611e8250797e13ab","0x7da9bb3b6d503655ce496d38ed957da087f77ddaffa30a82b5b33600b2d1dbab","0x332a5b869d7ed901cb13ad9a6d47a08452438486f8b077f91d132b51ae1c990b","0xae5134ea2e35459d5f1e0a1dad8eb1459cb1f2b0116f77b0c38761f35a6e3901","0xdebc492da4bdcab867dfdb2de0b6be57eaf0b7343743d2612557ef0b9ecc2517","0x4c990517cb2e28c21aee6be4f143a5799d907cfa6a0ddfede0a00d6650a2dbfe","0xbddaf6c61e0069fc9ab3f65ba2061952911fe88cf29cf55390fb0cbe82383b9b","0xbb7a9c2b23e4d2e0446cad49f591e53a890fc63925f9d31e3ff0bd3b6dbd6ea7","0x8dfdb7783f9c3adca688142762c4d20ac5d00f2430c701098a37170a6f768c09","0x519c46b67d573c9ebd2ad82666d96b6283f29018e9bb45c98798145042c50d66","0xa1ee1ba7a79517d6bcb660d33901acc696bacb064311691a58788c4a7a30b02d","0x896a2aa3273da6df6262f5bd10d93bc27780e9d3086f227615a74a54cbf5ff0a","0xf870ed6c6ba3e55600d9c558c0fcc7428f42ba5582998e5f98d63e682efcbb0f","0x13812ed42a9dd2f6f94db253a87c10c7e0d72197187c480b3a5fd0c150b69fb2","0x05979679e55e965df2a6ded02e8ffc47c461e883ce51fbac866d7fa580fb1d45","0xb20e2ff0ec44026efca65a8fd9eacd268780e22b101876a868fb8de4052963a4","0x8167b73ea287c2f379fc97e6cc2f88fbfdaef0061f1d7e593e69881e56302fbf","0x7952dbf232ff3c7846adba39c440c71e988fe10da1ceaf55f1062023270ba1b4","0xe9493a53b80edb27394ad06964d75e39cebb7b419409c7256cca2f5bf4057613","0x88954355698fdd0e0c194fef738f065b213ee8858468e473354f4967185252fb","0xf7c29e8f183c4fd49262d1de83cae2b1af44dce31c0c91aa926f2d4468e74516","0x1a21e5b5ae8ebd196b2528c134a14bdf0e3e07d7a27e862fe555d76dd1320170","0x7ab1af798eb056e0ac3c0c495a1d86b3e9b41ae948c9bc91faebddc43961aa1e","0xcf1ec0bc7fc926d2abae3a7ae3929c094d075c6b88a1c27bf34ed1ae2be4f8b7","0xbe7ce1d6144d57f5aff61c68968e5568d8c2d9613ee0d9723dafd3f18fa74c76","0x9e21d3e7c46526da1354d2fcd280c7b5e681f9a17ea5cada95bc378152243b69","0xa16aeb847b2bd20cc6354328dd51fb2177882226c345e1309c3b9da6ab5b0a93","0x379ce5a735c4a8fff46b93e776436a8ca798731506ccc2a6ce87bdab4a5fc887","0x89dfaa8918bc14a0bf3307dfaf5393155119cea911747181bd5967a90542c1e9","0x324bf76b9783ad3827d16caf4ed47eddab5c271c3705dfbd85e2b832ef9015c0","0xf57061a44950419d09efebb0d7e2e7927f31c427e2febe908e8706ecebd4f972","0x873eb2353031e2475280fc4f2ef52ac8dd5543b68d0df1a5b5f36fb043e2b7b2","0x05ab06191dd1da04ccba3fb4a249c95852e0de12bb9fb310142ce9e5d52f2f95","0xb61662275f7213c57c3153fa9e83978f7eec23ba7600404653fa1daa3e3eab54","0xe85ffa219c9e0fe480a71e9a4146b1d94b85669fdc378bc7945082a00fb310da","0xfaf540f10e41fe2a1dc728cb93b8127d3cda8ff8c82ada69c9e5c5a056fbaeb5","0xbb51fffeccbea502cb2c5e14ac5528003caf80abcfa73551278fa72f2b10f4bc","0xcf8931ea18933feb1f03ecb87751064287acc64b9ac36c1ea8802ee06ede2ecd","0xbd2e3466a16326b2c498574a7ab32389b2b9180bda1af09a0378e50d39dbd4a2","0x73269fc626604842aa281c7d0dbe7250af6c0566d569e40dccd44b1796eb2f45","0xfb3528f4333a5e8c64775a334e6885f5e7d437d77e951857da1398f0dda78614","0x2f0e326e13656df51ae616304d06bcbafc7fc577f384fcf742323dc12df5b2bc","0x956d0d90605ee0ab45056428d6cbf9a56682bfec02cee0c067e3fe2b050a325d","0x507a16d488c44b9e79bb21168676205d82a293968e17fb643005131b1f3e8a17","0x0c3b5cdf47e3dba56b903abf87a85ee5cd1fd55dcd8ae15820dfca1c0062da2c","0x10e11a0b43752684a4c4aec0a6476b8b689eae1e69ce227a0146b8f6ade93577","0xf94cb72a9ec712b74c1f5d639d95deec63c587e147243a98514c5691694aadb0","0x65c98bdb7af77e94690cee17a0d9c20085628a97d435aefb1489dcecba0fb252","0x19fc28a62e9c86e23210b9f274b7d65f46a25ece3e004f992521f470c3e6a195","0x7d8b2e2abf89884168c46fb061f0ddff3904928c0eb44d2ba04fd22a34b01250","0xe2fe0f6276f6dcfc552a0979bb7d115c7dea3865cfb92620f35d9268b75d9470","0x764843cbe47cab1da4a14dda8c141ea5284f0df68ea9a50d5e4f09801c6af362","0xe467ecab821453bc9c607dfce5cf4df2124f8398c677029b5b67805b5985f539","0x1bbe2711ba84553b32705737ad914072f7a13879435e55f7e8e44b8ac3ced245","0xd2ee712ebb5cbaa808037a46225f3dba11414ae62a8aecfe02f8b02f6e40d756","0xdf6253fbaa7e38111133eddce637d093bded99aef876992cbf75b3af66b6a0fa","0x4007f3ec0ea82ed04c534194d3ee5a58b360425beaa64d888c1cc984cc7671a5","0x79cfebdec1e1234e34c9d220d66544fab3bcd94a6c6663ad4d9e7bc25123dd07","0x24e184e5e842bf0b7da0a50b1312e1625554fa44ad47d1a829e335127472f152","0xe5919b97b5e3e977ec55790fa6c09abe2f5147d6e25e2ac89e1c42b7e02b32a9","0xfc9f97b870192f958fbec351309827dbea2c8008d1d2cfff48ef77051a52f2cc","0xbe597447dd724f41c9357ffce2ef24d5eac25b41931e9c24ab4a46178e2387f9","0x756ce67b6546843015a07af93f9038c19695bdad106e9f905f4a46b24a96b605","0xb0a409ef3d6a36c0501a4db90cb012fd84bf9724b8ddfbc998c540ae5e5d56fc","0x837e1f69d969ecf4d593498d57c97efbbf05091cf5c780b53b5e75f202ef1a90","0x0e2446385e566213716897def1c95c05b72a1b318369c455e93aa2488a5763e9","0xf96c74237d15e7f5457eab825d1d2d2d0413d290d875b20b5b06d6c7010dd111","0x795e8eb7d2eed09a3c17da867a009f71a227948fa17fc521bbdf7fb4a4bd3059","0xb42a407b7dcc2f5f62a3d6f39c8e92d07fade29b301055dea92426b6f7b1d278","0x14fc463824d22ec9bbf5566a26a98795dddb696e622bd54d347f8c91271d5e08","0xbc8409191b228f4ab99aa9b649b22643eff9d1f8beacd8e3455affc6638acece","0xb9b92a3046bfb34ccc86abb77003732c06a82bafe0e068699e8f19cc1fb5bf1c","0xceca300a06e1771e72050722f2bc4877baccb15781c8596e89e3fc373df50188","0x86e564d4c2e7399c5ea20831db122b7be3d2c995b3e635eee6ff4dced223f1a9","0xa09270bf6cfe649eb33806c05a843582e58557f2a74bea943f5ef59d4ba6b443","0x876485f06f9536f4bb4726c2d34f1d03375b01fba4750ac77d83c726dc2a8b4a","0xa20f8655694affc0d8d3b8357e8f4dacd726527bb54cca492ca629ffe0f2fa65","0x95bda2d34a4e78e0af09f5faed09f3aa0815f48d3688fb63a0e724243e6eb75f","0x88ad0e296549b7e0c91347ee667ce7001c2f6f6407cc6a8ea8b7fd95b78afa46","0xe9cbb20aa4fb5213f5cb0bf7149d87f74241a8e1404bef9b3f01ace96b042305","0xdac99242b62d79a4f9ab5cbe68abd4b7a12239e12602a032fd8cd650f73b0019","0xf7894c79680f6b66ee6c05fc4c5ecb7348a32d079a85f863960c6282226063bf","0xd35fd182fba38efbf47597ab6454e4c524695d8c85403731d666b7da87280b49","0x51365612ad793b85edb3787bd2078b821129fc376eb7fc9ba52796a076b8d7b3","0x4ecca59e5a4b6852a3f8a1856ac3a8f9b15f63c5f55a961ebedc232636398328","0x1bd98a37a9e81d38cf6bd8cefdae042f47548ff260b6747504d22cced876bd7b","0x9cd2a9d14c9c030058a4a46cc5583792cba49cc8f27da34f4b27a886822e393c","0x9db29993d0f0c0b2f6b66e81a5068b3d261644a062725e9fa7997925851611da","0x83f83175f2033dcb29c2959a73dac989f89701cc129449dcd70b3b30de478d5b","0xefeb8c7e3a557afe8fabb252eed9b4798ee27d620d1023c0342c79fb716be08f","0xeb506a4f20b6289099503fdb25a79335a5af6192ec6258ce208c83df2ca5cb90","0x1c43818b1fd7e4a30080af2efdf7111882c833aaf69fb0e5a50481dc45d0d7db","0x8b4b0a038e092bee67060e04085b072054cc2eafe3f0549c74fc44a596d7d766","0xba023a3edac28dff9edbf3c05b0ea3681074399337e261528ff4a07eddfa5a7f","0xecb2b32931b23ae4fd00acf43352c4902898364ba3116ef2b7b58aa89d57d575","0xd74b7a5e1e67c7c9a0c3640f3132990cb885d1e1010a4dc8d357ea16d86b1f69","0x6f588967cb066a112027fdf99abe64a08c765a3de7f0855bff3a88398c22e8cb","0x91af6ef7542c42a10c4738ce62efc16ab53af8cee4575a064798f72d44290394","0x78aa2bb11c0c93009061240edcb79de784a62b872e1cc9fef18993572e2bf567","0x438f97b60d22788a634373a0c9d9ae6f2ae60215ac8b0984443b76f590425f4c","0xeb8a67c447f05d66864fa994e2de4c669ec38b3e1735eb992dd35763b2eb88e1","0x7f9e9e0e3a1d7bc923bc84362a676ac05fdc453aa7488544650cab0df11fceb9","0xca2d7712491a9031ac79628d854ec7145dd180805ccb42e8a7082f89e0e5996d","0x1cc0d88c60eba473ed97d187d3619bb341f1ad5589d79bb40bcadb85ee229cc8","0x0a8ec1dbddb20c6e4828fa1febdfdede107b23e10d6ed0972ac90c190edf6772","0x52cba7f849a62342eff69eb6dd7c252706b4da248d7ef0d6a8767378bc8d3034","0x6af7fb965624ca22ef89c255b7e320e17dd1e0488a3426be4c75e303a4b9dd90","0xea9628b3ab8d44bd66fc00525dcdc45cb69cbf34ec978a43ff8c3c9024725bb5","0xc8171d1662ded2e95105ba5a2b3d1c75ff7e26c306e8a0de96f85041881441fd","0x3cfd9560130fe7748848daa3e1920b2eb428e5b5c695adfe8aab499aba1a66b4","0x965deb07a96aa2e622f7eb3d65116c12e079d9e0bad49a3a04a3bc5bb1d7806d","0x7ccfde23913f93678946d6d3954cabe0241e3e83db91a199cb388e5f261077f3","0x0c4d4357c788997621d10b571f884dac7bdb52c2dd941aaf9284066586088bc5","0xb5d13e56629682ad107fc4e24d6e40b7c20a89a900c198b802378915fe8069ef","0x376628d85486b6890083eee78f114ac006f8033adc7f67baf96f12024bc8a3c6","0x0ed6c88c78f06786285a4f733a7c038c16d508da19fe71de2fd7bd99aacaa556","0x2349a75e93c6145249d10367c74249f45e3f657cff26418269b142ef2373c397","0xe30bdf1719d077369cd9e467984144bca1d393b03530694333f7852ea8f0aac0","0xa0192fc60988089f640b2a225fa67c165cef4f5ac60cecdd45db4e887632528d","0x1647b89b49044c362445ad26b4c073a6065cfb73f30962601946d367cbaa4135","0xd4eb68cdfca2ce063cefbf7670b22151dec9689cc011906f2b79cf78324d9dae","0xa998bc517456f6e9542f343546051d4fba2fd38ffa0a7b04037e4a7a2f7546b8","0x55c199b417e5e3860bb2d2b0527a05bb81488c42ce0c672e466ee6bc8b84f54d","0xb2dd9e9cc5aa818dd884464189eca0b0e7a0050418d87ca3dc1fc1e4e387e9b1","0xfed5b4fb0bc9c0c88fa314030e4bd8a12afcc73318fc9e664bb35bdfd60750aa","0x14f36cc07a6c244f1fb40fc424b12ee7dbbfa14c5bff2050ccab468810f33d21","0x522ca550e57394f8112db4f8025c8751080eb432790f17d4a4047baa74b05eac","0x27a68403ed028b3ed4db565a5af12c7fa63fdc89a444370d4d889f1a383a6cc9","0x2bb805d1ab8c2a666cc4cd830768cc4900a5e12b7617c8ae6774721b5d015c56","0xd3397432f95a803a8ef184c38664efbe4fe1bd8618505c914226d7978fd48763","0x23c4349a09d5f02b413833b8f8995bcd4c0777e5b0e9ca06f26f8da5a8a0f401","0x18a95ffeec9bd4e1f809afa9deb5d570abdf0d4e34884eead7fbc4775da4df7c","0xcc33191605525e43cc1e9ed84de30dbf5d46c17781df9e1c293cfbe806d19fd0","0xa9a48ba11b17b5ed2227a4c96eb4262993dc524fbbaefb7992eb160bbc48cb44","0x9035c540fb71a54b71f2b62414b086a7a60c1b23a57141dd74909ea7a2bc877a","0x45cf5481f904d8ffb6ede2f54ee84ee7cb565018f43f4281efbee8ba3a0a1306","0x09aa924d0572df80d1b47926312b2831a7072ba7ad8783324a4c021d6b40cf0b","0xe87d23a082e670343ad05437bdd513152dba5cce4a60074935a82f7180adaf14","0x869d6dabb85896eeb66eec97ea4cc13f332666c1427e9d38d348ebe72a68d798","0xe6596cc2f6759336154174c98d9334582bea42a6963efc858d587eeb3884ca8f","0xb164f30707cdb17f361663521a7dbbb29f8b20ce750d797493fdbd436696efd5","0x5d62bba9c7df1e1e52f32dae5b4a1b47d2a9e02d09ee40c55dddde10737bedcc","0xdb692e4d6d8cde9536bf4879de3277dff30315201d50cbd9dea489bdff0fac99","0x11216c7b4a74895e10fe4bcefa8d96dc73459cbf2b766799984e9b717a5a6ea8","0x865445b642c80ad5fbff75787949563fa1a6524ff29b2e6268630246ac2f00b1","0xe56894e766303814d12926d153b01ae0139889f7ad986a41c0f32a01d686a5a0","0x004044f2e37d98e57dd144911496fc7118e779e0933bb84fbaf42eb81bff42c5","0xcaff262b575a093e3def18ccba98cd1c123d09dd2ed7a7d111297ed4e303a85b","0x882f5090d0552d52dedf3e1511539ab3f3fbe99dd7d2e2d776a844580fb9459e","0xe484edd26883b97a1ab4711c668a8340151a279bfdd5a59201bd1cb18b6354cc","0x1421b4b1bd342a79a1ba29868e702c730b5a84b5333f06737fa88654ec842299","0x0ed989e85e71f699e1e102904cf8e5c671e60126f74b6ee42b0ee1eace816c2d","0x6daa7340586e59b8d17a41e3eb8e99129a6b846755ce972d892b5ae1c085c0e9","0x982cad5a350d148fe0cf9c676c920367fc61fd841ea691deaa1306777af04ef6","0x65d4df7b767c3203648f38312605491cec431d3f9a4d414a4c0f6381dfe11cdd","0x7417745675da95ef5b6d90631d12cf74fa23cf833efdc2ed38a56dd311c3dd2c","0x199f3ff6fafc3714df2572ca7190d1e7b22ef496806c87d1e909e8825757d085","0x99630dea5ab130b669908ef222eef06145d92014921dce1ef6943238b261e14f","0x7f7eef5a6fd9712ed45c41a43d3fa2c327aaf4d3cb64abb3c9845a5aa66b03ac","0xdf3cafb4004b26ce42633b7040c66c6c3c4be8e71a493ffb57b87114d3876c46","0xa2bc14195d520afded9987d068e4295a2f09bdf5c64a3258b9bed2bcb4102f69","0x1880059d9eb1608f65c728632bd63bd02158256bdc1a3ab2c92769cc1eed476c","0xefa2278c826413c47c4f95fa946b2475a0454f066a2e759562304d3b90088e4c","0x841b6b7e9d9c4013bdff5c33d3756a5034924aa793cf3be25042f56e4e7da6f2","0x769e1757057da3feda909b5efcc7d5f87e4bfdfa2988b45a238c4de861443c5a","0xb6c1b5d3fb20f388e95d451b90669299c7e921b5ef6fbe1cd9942ae6ff7b73a0","0xbc1fbd99a1be9d13dd83c818f07ebcef6c66939c4f9fa891bf14021f22753d12","0x3ac471336d90df49c1dc1087d387efda472a12098f5d279175e60cd83a3934b5","0xda3ea07bb48bf22eae2b0f28eefafce4ed6a89874583fac7334b1df292c76818","0xaee72cad5e8ee3efbb044ca8ff509bc824ba4cebf8e99d544bc6b02f5dd94059","0xf099b1087645d9a279820ece3e1425286f9139b8474c28a70af78f513e78be84","0xdef30adb9ad7fd55c2f1db2252c3b80ebec64d8796d159db29d029310491f42a","0xe977db6124fd3848575e1b571e3fb93a2bb5aef911a198b8e171f97fa363aad7","0xb75aa5b6f4949dfed2c3afaef841ca5dcef4a5c236dea46edce1c7f21c101b24","0x1be1c983eb7245f41ace9392fad586980a0a5c3998cbd7fba9c09e54825562a6","0x58fe0752c08f69eaaaea270745e6553bb674aeacc522efe230feb46be2a1277f","0x321186b6bff809a7f1767ae0d8d35db56b054068310e799549d61f56c183c0f1","0x90a08fd77ab468eb6e448209a4c39ebe78a8f967b9bb2a9b6d7f1a2c8c2ca053","0xbff7c4d140a96ca22a427cc5dbe3c8568825c2fe47151078f7f652593f0df1bd","0x5b9bb30129abb4e98830ec8dd4d19f2e8e20b2637ba667713e6fbff4d747ab78","0x8598e0224a2a1ae1bf4801374d97b2776c8e9e7d0cfc2569499d49d7e25e0d0e","0xd8fa2a0b799edb6bf6179ced0eabfdecee90f57a008556a5d4407fbbcd24720a","0x0031e4af5bc3aecd96ad65cf44c44d5fd51783046a2e2ab4dc0b0a03df52fce9","0x85273d809184674bf41347e9d48efbc0e97580542f251e7d949bce702851e64f","0x7dded26be6fee4d59b410f861c4deeeb0cf20a78f0c5424585e90b4e675d3616","0xca11bcb7a25885bb523b4b064a19d3c9ccc91b88056a9de724b58640b9d2efd5","0xf7fa64aebca0bc211867b738970b7452de5106c64f79d6bed8fea82ee101b140","0xd0034d25827da2828d2cfc95b2b4eaacc4b266bac367a5095f5101a69c64d0f5","0xcf4094c65e96bc58bc7cfd969229eec78871c61e62cd23a01e898b6ba92711c9","0x2557ca7f4eb438482947b1ad606d0fe1b4878ddb9441762ada46108cf99156a0","0xcdec15756baccf8e5145f752894944fb47943d91678f7346071eff6f25573a38","0x17c6d297dbd3e2602b78b3f5b33c1d4fdde0d31bd2a8f61816c169122885a5f8","0x4892976ad273f170674c6ae83a50a9fb39dcd3a3635ffd74d137013bb0032132","0x7d3b8de532f4991f5ad73c654a4897d4cea4f4d721963bc8695f4013770f34a1","0x807186736861a81a84e1212700ebc8759da5c0c7d604938ce24ba4dff1d4eae0","0x11d87917e23dcbceff4ed682e85b2d8532c39763be3d623c990aa8f782959f99","0x253f11163f214e460b5078f10c4626622ef5b6030ddb4269d606883231d7565f","0x97da7441514850d2190773cdfc80e33feb313024c1ceca2f05954037a2b7e05f","0xc5759ee496188ed0a88b353bd1a49d84b275cd00aa5d3533616e74fb8839e909","0xe26c08785583d7c4ce5f9015b46cfcc7f2c389b99bab6a0eb0b64e748926ad58","0x346103fb6cd74e6538984d9da5f5d13f7eb55f5977cbb28c28276be8226de393","0x758ba03bb4fa4963e87c6a47e9ecadd2b3889722a79a5eb5531e4a5d91ad194a","0x76136f31a1a3a869805b17f4ff7f11295c9ac260acd8f90afa07c72528cf25bb","0xba0cbfebde385e79c771d3ac20b66b46fad270e985fd1e2a2835e25ddac352e3","0x4733f33179b96ab9f276df792bc0c6a0ca6ce192cb5a33731c332ae2f760f6c7","0x95e7bd4f8f9945dd0dcbe0c9082f02c8b158695f9e55a4ac6c535ad7bacd28db","0x5a7dd726a20c63ae75e07234117b660376dd28bb5f44a7066a6370704c719a5f","0xc48e97f8c561dad93272c7b1e9eaf4c28eee967cad0d13e3ae94aa903e3e4d15","0x512e7457df7fc118216794df2d538bc89810fa10c659fc9bd68bd6ef0d19d9af","0x8dc2a6ad61cf8acbddd1b9966177f9e1b410b9ef5b17a78483db46d1dc1a8169","0x466c036fe37d7d9e089c553e180c006f5703a19800a9929379b5b1414fbbf0d8","0x6c4b2e50192dc6a519b0eb6425e298edb3fb19ff1f1c0e42f47daed060b01c7b","0xb80c161e74a7594ecc0ebc67703e9bf5e22e269b158c19a7373ed6e86413faa3","0x0244e7fc95bc0ffe5a8256389417fc038aa325703a28a0e7aa7dafe28e699feb","0x2c4d346ac2aff5b00663c26fbed840888e728f142e6bce07efd1b627d4d81b8d","0x23ac3553193945e9dd2bd911b0554d03fc2d6adb6f508dfc6bb89685335fc5dc","0xdd6ac5cc051cf149b499ec304e4dee537dd48aee1c0403f1b82cee89196d6a15","0xa59af9fe91e03f8b26204e3a4a437c266eac4d69290b948402123d171b0a3404","0x2bf5a9323b44d5585a22416b1f6d480bb714b435229180d5404c2507e4adc087","0x01c4866c2789c9e7ede00b92990d2cfff0b310006a81a3ee91275fc98e40b504","0x81fe6fcfe24e76d3c761dff43e22a459096a86f8acc9d7a89beab4c43762465a","0x3b8498b8de1726832779c0f39b2bf6b93d9a1c9c8f20103d71c173b5083a813a","0xcd4fdf89d3bec78f28262fd6e4ca7b583403cf1d96eb20c9a570adb0b45f1aec","0x55da2ec0e63a30404257ac02d5d91e8a10a5263da98093900dc63bb25f9d9d2f","0x18d28cee25cfbe34d25aa90ebc55686b5529907e4d3a61197155c896df6dcb10","0xcd78fe82712af631329c062fb8f10a8db791a16f168aa11367cdec8aa4c8c870","0xb70c6a3c342500d3db0fff7a16d09f635d5c90ff61930f58e29c9a02b7943acb","0xa19d80bfb85ba6a5d2a02426784bb856f5b45173d1a44be710f2c046b09ae698","0x8a5e3347650e76c39865fd11fdaa6ea0412e250c36e7564a7c344c25681bedc3","0xe9c9edd2b03704e038775d79a7ca1670da1201bb078e6b4cccae10ed3b77fe05","0x975f08c28a5d302ae48b728b2f928458c1208f5569855d47c8ec79b0bbae11bc","0xac1ed4aa3ad7966eb86ebc578991abc0f48a39a1cddfc531745edf70ef9ce171","0x1c99ff1ba511cd5d5f736925fcfd8be7f9f302f0ff9732e6a03044a071b71837","0x771b3945602edc385bfdbedfc9152cde5b1987ba8316a36ac6ef0f25220b0c90","0x9bf15895c4573324ec244db136a73c827a6fa067412b4564b652f68dadfa3ce9","0x3d843f6922d72e04c3ba69f0557c5c1614e3104543ed98f28b3e3bdc4cf97042","0x08ceca0792d69f9fee8509c22f1bb4320856fa01bbb3c452c2f492551a552765","0xa3c86527054a450f8adfb175d20fe2988166bf488aaf37f88de01c41b50f1a54","0xafa22b96361df58d64f015a105afa80b30751c7eed32f515ad33c68124b3faa7","0x4936c7ba45c54924baa4abc2b333a17b1ad9ec74156a3df72e0306f73f778482","0x0ea21f8dd85218a3cfd63c39dbd6184458fe345304747d24bb904165836d962c","0x5f52e018002be82f5bab154bf27abfe0b864c8f2b1e76facf6890e23c77d036a","0xee5b2676cb5cb0c6e346786897b7068b601eeb997b98df3f02ec4ac0c840888a","0xcef8608c57a7b8652230df92dd386615ab70390650c070f6635cac75ae4d8a12","0xda0323330d96c1cdf2390881e7057bcbf50365fed440b27b4eda4b2baab8cd03","0xf792a33a77b9424ac5672568aa310f27932adfec0b73959bf530a206e3fda028","0x0140376b66764738eb29ab00844cfe26a08a5b99310ac87f6ecda09d0990fd2c","0xb8932c35ca4dde4b6bbe34898f90f55e2c6381b866879f0355f11a011086a29b","0xf25b29409f8c0a51cf34868699814ca63f1e89fb39bcbcf6771f6b82f74b5081","0xa49ef0c5a24a7f985a0e40b3dc31651fa3fefb04268b24437148b9e7663caeb1","0xd95a0b1d1abc74c19afe478da5daa3d81900492d7b6ce262cf1640c9331b2581","0xb7ff28289fdd1382f79aed1d71a0a8cc61622fbdbdbe6b5d895cde54a1eb3c6d","0xe4e2eeda3e3e8e894925e821946122a2ad193b9e565fc7d7a00beb97d238ff7d","0x62dc61e3ebf7d3dbb630069443c9b9eefe7cc055b7b3840f144a99c649f2f8db","0x5c9f78d6fdf1a93bbbd17e5f9b0d481dcf1299ee9a468f74da748b27e9e5de6e","0xbf1a495a97fb026b55f8b9cb9cc10c869194cf73a572703d0f9bc16e27bf9432","0xdfb603f8695073946afc98462f2f06283a5ef88195451fcb80c20b733f5127d6","0x71edbdead42dc42feef79ac1a83422b3575b22e34e7c1d24f7e213187de53b65","0x957124048ca5ed6973d8c6de4b85f95f924cf8642ce61d9c032ca982af3c58ed","0x7d0c9be43ce1c40300f86edcd4aee309bd2e956ba76a9746f869155fa60df76c","0x2e80ec8dc00f5dbd7b42555039b0a560ad1e90bcbef0dfb983ad5ffee98d7f57","0x6954b9298a02f7faca4660d9eabe6afe0817524efa30edc42edf5fc6b25ffc9f","0x234131182e3df2bdb32dbca22d9e1982d4c8724d76b0bbca4cf2866d096f60fa","0x0bfae40decb1f7add316f3fdaae216f171877becefd80ec36eeeb550e3f86b17","0x4cc0d272f3fc33548aac98a8b6b73463003ebc8bf4318504d138bf2f71631fb2","0x374bc2df592db33ebd858c5c26ebfbc0740654398d08b81c3602af70c41d0077","0x5db2933f474fd6402a3ddcc0284553fedde9a222572b3421beee4ffa73ff50fd","0x6ce5cd2ffe9299995e3d5164a4fb79c2db7f6f3e6fdbc9a942024ad1a1835a5c","0x00335bea52fa9ab89a3bb2a7e5eeb046147227dc2ec507c60b7cb0c4263fae1d","0x70cdadebbda66cb3e94211e47234f3ebce58dcc7bb5e99130cdb0ee5f88c2fab","0xbfa826291a43969091f755483cb5e3b6f860fd266f56b113e4658e1feea2399b","0xad18aff6677d3beafbaa89bbf524087fcc22c1a637a1e6ab7d7ada5af2ebf533","0x5601c81f93fcafb9a2e64715deb5ad0305521d6c943826ff66b5e21497b8dc2b","0xbcddb3b867a21f803c42552409251c3c4517a1ce00ca8f6dc746fdcd895f38e0","0x65d0cce86a02c0847bce8849bae04a275fbf81bb9ca4798c2274262f2fedb2e1","0x9d4621b76b7465d16865f8714915f00a6f658e694feffc23a9ad01082f2e1d36","0xababb9b74df8ebcf0264125b9482fed3e085dada62b18455be2d7171ec9c3ff6","0x72a639ee91f7cd25dab1c218b0d2edfbb76c804af3665441fd9ed5fd59a6637e","0x8e66f5490cef678c1cdb1a78e6672c406a78bef3f25d84df009472885dd6403f","0xb02cc911f4971cba433a26146cdca1e113e3484515d799f7014a73bb1455d909","0x1b2af0e62d8a1c1a8121c9bafa5e84a68f40dd80e8d17732e07acf69f26782ed","0x4586e08b278e9f51ba55ea1540ac632c3193bd21065f7d6b0b7c10141c3d6c98","0xfa8457c9d35edf6241ad5db2887f1498bbc4d92dfc1ab465b6a93ddfb3bbae19","0x96c164118e1033737219af619253df4825103820eb170a6c0bee6f3be554c80d","0x92f04e61c3b0a13c9a9e9e0d459321271109e8a0dbfabbfac7cec09bf35ea35c","0xd9380f970aba630d357bd333576bb11c81ba74ab9cb09bbf0a02a1128e211d01","0x47bf7db10238ee785cc4ec972ee006811e4a033523cce9bce41670e6b480c1fb","0x2d1476baf4b2d901924ad597a5e8e8b4ef5ad14398f71394c4c77c7051a056ea","0x1a02e82acc7c9d1d2ee7480119fc26734090dde3c83b2b3cd60c912289613c8d","0x8ba5694444aec97815f64b179a9b3bfe479b0a93c01e056ce460b1e66bc10d12","0xbd0b6276f887559895b17a22839f7f1c0e809601b3bb7d7ac82683c543d69d50","0xee21a8dafee63387ccd695cb70ab27336ebff66f2a17b1c7af9438c2619a9fb3","0x6899225cebb1f4419357b3ce993bd410ee8c923a23edc83448713ab89c78e7c3","0xd115bf5384070d754bf422444fd8bb40aef0781dab81c3733e49eef2efd6b6d6","0xb24fb68cb72c89ab72ee0dd06662f4a4ce37a09d18782bee87715106de084270","0x19de2dff8264118824dd98bf95967be5a73bce39c4fea78f9788a15d5df89f8d","0x6987de226e7ad342d0ddfa0f2c89288e1c5749fa02a8d3149a14a84af0b87718","0x53a661fd74e173836b34a17917d3a3db7c771ac3e4a28a24ca19891fcce42e04","0xf94b5ad20524b2679efa13ccf372be54d0aea4f9aabdeaa71ad8cb150d7084a1","0x208a3e9652e1efb3a0885f812b473ffc943df43c537a625d7da85089958d7938","0x31f7aef2c1953465e512acaa3c892487d9af5b589fdd77ed7c66c4a6179723a8","0x3a00948b04fb8246bf66acffcce1c7f723ab8b8247078e8b0cafc735a7ac62aa","0xce3a6b3f4e1ebd964fbdb8d08ba31059e7e2e26c1363bc2f8704e3f8406a6cd3","0xed56faf937213cb1c28abd284f98bffbdc9429c62c97cd829357fb443976fa0f","0x642d14de1a156b5c6a5725b69783dd386840dbb10543bbc6607f5bbe5a91f62b","0x84b9b4d733978b493971b0e770569eed23e152dff793b9fced993b2ee394ecac","0xad1501da23eaa2c034d349448d8a9688557c348ffd86253f7a48a8ac95abfe8c","0x2ee7f47f1dfa7fe6b90ce71966e9de87228bd601b0f62e82ee0f97b489629e85","0x01f59fb9df9cb75cf5d7b7940c812175cdb1951d8ab125d01ccee51f71f336c4","0x5bbf0e900c9a1d76b237b7439b0a50b6c9c3975f15ab763e961439605a504e9a","0xf2c9df30d0160c12c9363d969115b2d82633bf478640736278d81301e5f115c9","0x5cf660e105cf9c0c58825338f01569fb541c7d832b3c3e500dc51489e8fd4343","0x3de367df383db311d00050c840d96effaa8884c858990a73f69211a6bc174f95","0x3a6d9ac1f46dcbe468356dda48e24d83b3530f4eb87cc37dbb10de7535327673","0xe6f578a9989a524c06d5863b5a4cc37bdce01b2f2cfd8d000115b6f32f59ba28","0xdc3943d12c775c941d4cc6ab01776395c94fcde3864bf51e1eb0587b3a928138","0xee8a330f679946e72db4af38242f0a1b844c54ff73e05dbc52791da4fb68f785","0xfcdcd27910cb66e2d452113546467dae34c07fb4e1d2592735fc1137fcc1a118","0xf66083a48ae138a26fcde42be0b1d71048573b96c1f17cb81fc57a72be3279eb","0x81e353adba0c3205aa3132d1c0e35d5e2d29907bfe6807372fbf2336a4d724e8","0xc16f290cb14e3cd713a1169035759c49a3c41372e6055098e2bb087f646be7a3","0x32a4a90ece1b9d99cfe85b02d4382ea574e441b23fadb81f1a4ddbf87e27be4f","0x6488b08e8af4522d4ea02a54a6e068a04180e4e881ffdbdea60a9b356f9701d8","0xa4d2b148bc14d355605ce8344a93224f4073e737302ed02508b1c22e37906205","0xee4f60b75d2dccd5b73c2eeaa29f325490ff0e5785c7ba4a3eba834b88223944","0x07aced2183c003bdaa2cf885b18ddb041ad9d527f88415bca0290d4a83e74643","0x88cd8c0d8ef770d4ebed5ac6e4b40453e7be5b396e22426d2c4e3fd8c99c7b9e","0x50fca6a28396e0f68d56bf4c00aed4c419357c079f5d8b102583f5b622d262e8","0xd28a1c01cd001992fc81e44dde12ccecb3e2358027196e1d6cd055a01986e19f","0x8f9d4f34c71d4a0bb01d90247d6183825707fe84da3e58955759598bdee9eb69","0xff7ca5d4031adf9ee65d649ab98770a1358dac0cb4029884b9a85b77e298f203","0x29cc0f834e3991960802b47657d0b126e3838c965442060a99615728425ff1de","0xaa82dbf418ebaafe6e7bdb2e7757e6f36b401d73dd4f55e4b2f7e109d538ae00","0x840f68ed62af609324fa16fafadb3c79920954f4dc94d4ad30576a82b11bde68","0x6bdce520075f1a0650d2ee7aa69aad788f26b85dd771ee4993a4df19ec9cb7fa","0x74904646708d6c8954b905c6e845e2399b824b200f15cfa0f112a1bb0f3d70fd","0x407b3b758024ebf701d200c3bb37f7378dc509c3786810358212639f17ed429b","0xca4170444b1ea3ba0970e4ac20b8e230854e0d1606186279600436ea8b730535","0xc90dbfabae3b3cc87307d98e3bb220cd4555a73c4ef10bd77fa18658c8ddb4ab","0xf05593b82068b53a74d56c1308aef8599ff5b11264937a4aea975d60c18bacc3","0xfb784da94650511eb92bc01594a9e5ef3705565decf49d6b6188df63932dbfa9","0x48d3d40234997691cc69559ad97177561625635b5e52a7144391031a40a0e8f0","0x07cec773e11afe88bf5e9d88fa3b981239307afc75b285c3e5f3b4e8948cc26d","0xbcfedd8214881e293193a0c1bf2e123989ed8eed619f8aae9a203218bce87403","0xbffa2e1e84d8f68ce60fd52209a9543452007a256473f8f2248e2e204a92be52","0xf5caa4d2db6071477811712829ad13287d140e3bf4f2243f6e3430aa2c2b2fd1","0xc21d1602c403852dd43659d3124844a03d9fb9fb7903d57b7558ef34a596c996","0xa82d14a6b0fc98090e827ba4e39dc95bb9da21f2f0cec970c586e959d4a58d55","0x76baf9966ec61d5e15824419c05b40f5e4527aae69dcc50c295b600e2a53cec3","0x5fb403a24d67e5b1e486cee69ad989bc121a968772505f98a16c2b86f7679416","0x523b8b75972289f95263c7282d67135a38f320056bab14beae1da227899a144b","0x8f6e7e5c687ccfb5a236e7b5398381cfdf9ec54dc54be87f0187e20ff7772abf","0x2dd1f86d3019c17b05cce0aa39334365d73a51626ae4a6c9b5e1e864600540a0","0x89355145b37945d95d50620792cbb07ff4d8399871afee2c31228af9c6261b57","0x0049d0fccdafae89248edfd666c32189451ca147880b0c9edc6416faf9a87b06","0x2d2626e8cb868554e394dada3c1d27a2d18485f4e18a848a64f4532944129fbf","0x252bbdbdfd23c07dfefc9c842490e41d92b626c48bf378a1f03e8eb3e9de59cf","0x0b37856e1fbc18a5e9b92dfc4e483d0f2f67dae05c6bc05302478bf5b264b6ac","0x5aaff0f7de297995c7a79f623550985c261c0e7c4f9378a9dfec61de9900f51c","0xf8225635e5a1f9e7204a14c9c4181c0cff74867867df6ddbd29637e093dbbe80","0xa18671ef9feb1ba5b9170e5240986e3047714a90744595094472591375709d14","0xbdf54e1805280426e9284994c89edb59ee64dd7e6bdc07d53ec65f16619edcdb","0xc43525479e471c1e0694805db8d0e1446fdce2b7bef1f7bb834a71fe23db75ca","0xa92a5ff72d93cb8fa3c2f22db3177c00fc8c119f4bf16426c002af1d3d9f5ab8","0x321fc495b802e1a1b78b545c0361ae7fb1d8979b5a13f5ff2f28523167668a50","0x9e1f1d11c943969020b1230619b4787a3b10d334b4b698d2bc0b8b9ed0a78114","0x41f5668c5d29c5c04c5eba0e860c8b9090f1d69f71bd0c8682655b0d4c6a1056","0x3839e60515b56fcc8a803cdd505a2e93edc5ca88d210fc941e093d23f0f5c872","0x233f38042e6478330a63604db936a6820a39fe307f1fe1263b5dc152e1d6bdaf","0x2551efd399da526155ca271f700b692ee8b1d65931fa364ea51cc7d16ae5a345","0xdb51a3d4b23905f44133980994b0a601565d0cb24312da369bcc0013f02a528d","0x812ad46a000867e0a7e869f2a9f3377888eaa1bb343163977537fd1595ff3aa1","0xc322eb9ea2c19e71256407d27a9fd43ee6525e98f25566eea4b5e7e58793115a","0xf30d148088b45ef7fd1db1f5502c4a8a7c506a81afc64fc3202aae81f885946f","0x821fabf8ebefcd211e044630af153922823ffd8798fe0d5653da1494a2074806","0x49393e2d271759912f5d011540f574f5c0f5dbc53a28109678c7a44feffc35d2","0x424736ac8485eb0bbd5df5cba1a7d641f246e55ae1346a2468f7ba783fcee4a3","0xe57f12defb20f1c5ce45411e39bea82c8f7ac63489a5e0c7f973ed992c3247c4","0x8b1a16a68ca48fd959cba4c82d6b206a93cf93088b41eca4c48c65b9c70b8a3b","0xcfee1de9ebeeb0218f2ba72fda1ba4af2aa115038c0ae3fd209e479298581ec5","0xcb48734cbff3381126b80695f4e3433c3c84d50220df4beb0232051a8b9f1224","0xd118301c4a79721602a1b596929ebe2071e4776409b47457ecdcdd6cd93bf8a0","0xf5ebb62467daf005884b3c212a6f138cb631997f4f6b67250d7edd3ae1095c4d","0x5ab222eec5532126957a7828d415128b459fb782e761586ba97166fae4a858b0","0xa8f292e5fa7655ba1d4e378c170435c17a9a276f458771bf6c153c9ace360408","0x1073027222069208ff2d1dda67f549b7bba4d5680af9bb45004f96d7d31bddf5","0x5d3359b1583ad2ba3df287e052fab9c21d9b2db7a1b9be6c021e22271508c9f0","0x00563dc75940f0fa2efa515a6929f4233ab3ea7ff99824e36a236499bf720791","0x4250b22c81a12261e44cb1d70aed2cb031af3ef276f538e5ffe1adf334236493","0x47404945e6c8aaa9eb0b3bcb52cc09fe0176e4d1e6ce0486e221f2bdbfb3caee","0xc050ff87985f77dee83e521c8541ed13cdd8bd30f22decec20d09f307f8f945d","0x0c1549e32a26bcf378cf78fce47cbe366daa8c2381deeeb9589983fb65d3c4ca","0x00c1c0cf98ab3defa98a76c126f1a5bc229ad787ea5b998f0baf705581087c07","0xc23384837316bfff278ed9a4f47c8beb2fa235ab6391a1c96004a86c33d1c29c","0xd95e84983083ee04a3a04528b1e976c4f50a4bfd632bceec33caa531561896da","0xc6fd82b3f8d4cb7c2c7343d15ff3bd8924f68490340178e294bc55c711b43bf2","0x31edfe4aa8f5aab03dca2bbbe992b3ee6dc2a37b359d88bcb3cf9f675c9b8bbc","0x788fba61c3e0a45edadfeea93b0308586a9c3c5ca7f1e79a745772a12c33981d","0xdc7221cba9d95281b735705c676b78f0e450dac3ac03cf3ce7142666f1f36450","0xa2e706b0e6b1ac215d2f352c5b4e3045639b44fba59811b9055b1b213cd6a911","0x5a13256f55842f61e97d2699fe543dd4d7db3f4b385f3ebf4eee23dfc441fe69","0x67ff37748fe8bccbbc4880348065c5dc4c08ef26dfa724e94b90eae78b5fe943","0x32efc13739f41f4677697de14ff761b234d8d4cf2e7def453adfd7317a7c5f5a","0xab9bee6fb60dfa9ca6a9d88ccb252b1368588836fdfd52ea762197b3581ce0ba","0xccb8be6c03016115a1b60321c71b18c9b5b50e2e9bdae0f9d3c3d769072387ad","0x4c5eabd1bcc4ef385acd8ddbc973d0b11b0471dbaddffbff994a059f6449b3ae","0x5d88789a07a21b381a40b73019e5bde33ce77faf4b78ecd49ff5a7f798bce18e","0xba44f6904afe8a24872d258f058b7a5ae50de11895b167bae8699758e7390b82","0x6a85fac2a6581a060af8b4e775ed73216688e6c2b2b090dbc3d533e1aace9f17","0x39d985e332e41652eafcb0e9295f68b39a71aad7becdfb3728f8b2b71d19e8cb","0x7e6e166ee7111180a90cee3878612313b0e1e9c1597dfadd99f4c0f82bf0bf6c","0x4d683de66b7132f7e36d9d685a3361fe0b146c7a9b9a6e718d4426623c7702b0","0x2f9656f1324d4afe4c786f237b33468c33b0f1dbfb727db6cbff568860bd3be9","0xaca703608cc9e7b455577065f38e22b643f0b3e860393a028259ff296e8d6b7f","0x76cf098eca3cb9b07d9377cc0737a1953ec94848662907997560fe239210696a","0xc3f65535dfe59ff6ab535eaa457efa06f57e91064e8fb43b4d78e9fe71815f7c","0x1b8c7c8b5b79255ed1bc29db15023f1e8fd27de1475e1366c6acceca4beccc7e","0x163bfab5e56342aca8dc0f2eab88378b567bb039d26411b84aded63f7d98eb5c","0xffafce9906830cf4c12744b143563164e33a765169786f7681dfc273c6ad8373","0xd57f39452aab119685d3f77bc173c3381efab79bf6cb66b32e6ac090f45f607c","0x895ea41548f9fbe679df4898c1e1f2485fbfd4858da2be5c019d063d0ca4d423","0x8bfb507029a0cbe66c362478721b9afc5415504eb46330dcdf18454e89a8eab7","0x5ed3dbb85a59ca1ec43f63733f7097806031941413d0c132cee42140910426b7","0x38ec0d94221c415f9338fbfcb68a37fa05c237321d09b1f117ab104b8bd73222","0xb22b05f309298fd2dfaf9f6844ec41c787f94b7f9bb1b4e49e66ad385c59ea00","0x77aa31c08e980f60d51b9de41e96f0c8c7bc587ae38d6b59eba3ca05b7b0cec6","0x5e131d4e10f5b2c759e43764339cd3f8e11e48902d6d9bff7107f9fd254fc6f2","0xce3f2fbecd64425cd630a220b50e9b5d4b1c76bcee9fb31caca75d4438c18834","0x2f2883c89657ecdbda487a6139e8639b7522fc2d47ad02e7b8a871b5156366f0","0x05070c6c4df8f9af1fbbfb518ca0fcbe5db93ddf5e69206493908197e0dc8fa1","0x3e3de3d2e6e3bd46b3b3702d43a91377390b14e797ce7ec7a955abce67f28b33","0xe15471e7ddfea7af0d611f651d62a90702a90b33a4098de84b25b4bed1c9760f","0x5330317c144be565824cd5a5bbfffcf01f8d30842888333a7d0eda8599847868","0xa45ec351bc9b8bfd0d3df145bb3937b9388569e2bcd837ce883e0d4be9efdebd","0xff2d29660d3ed6361e73ce551eed264a62bdc827fd5377c97c8b956d481050a3","0x13c7035ac1feaa00bc33d96e0b652bb0fd83f17b79d8d973b079a71e10efe648","0x3399ad8b8d9e2144fb1e545ae858c20cdc43ef126c0044f88d5878606004866c","0xb24213aef5749d9d5840754e0822d861ae0f2f44090d6ec82d4a3e9c0f94e60e","0x4c5144a4262139217195bfef522675ea9c4df8384e662829220af12f8edba947","0x532e2519a1d10262fbcbc1da4bf27f94705f498c00df28c654ce81065fcfd033","0x01c1f7c83c99c3449397f2a44349fab9b01fba986199124cb0adaeff8dbaa8d7","0xcba56a74adca10553af7c2a643c802e01954d213e94e868047f58cd13d75f115","0xdeabd34cafe8c557767d256575ebe51087e43b22a01878288f007197a599045e","0x9fce1d7231e56c1d5ab619bb75d94fcc9b74f75185fa2d6fa9f8c8a734b1d876","0x626d5f8e8d37a3db33fef26915c576e238e41df9d53fb05de826c25df6e857fe","0x2a736c95c6564bf000b920ac7f7d37fafdb2174ada86ba7fe457c16e862b2987","0xfb0f2031556b3cef2a8b276492d311854fa3af847577986d4904e08642165fc2","0xe9e4c1a7b52585daecf6f7415c32cd9f3d6be0941503a860b93679b127d9f8ca","0x78dc670c76a89ad9d64b8ff50a43d74d874971fc670ebfa1478c71ebae2fc10c","0x64d33bf855a193bada26c94ac9fb6a03c9d179e713603f5ea30b04d05042b8d7","0xcca87dd627d92908cdd38d034d78e8f79799d0e71530ff51a014c08b0f521a49","0x250872b019eb9f373da5908857b1592a3fb13ab15b824ca192259c03a423e1a3","0x47f063e24a73c5c363c3431e72d08984b7bb6f032b7057836d62bf2bd1763488","0x4ae1153e19259e2e0b8bd60aea58f9c8f9976e6153f8bc1313f06b75316e28a2","0x0ec7004469eb00ba6aa9c485953084d49b0e0e033e10fca981974f1621ae9d08","0x0ffce367b000a6f44075da85d010c9318680005a102e109ccf4807bea78f7e71","0xf235a15c403f2125a79544b74d7297b95bc5c5723ffb9775589dfc7d4420c782","0x5e8f2260b37e93452ae950a3a79ee226c98856643ac7118cf19880b19e44ca48","0x96b76a92d4dce62a71994856dec173951174538d34a583ea8c63ecd7ec37d1cb","0xeae7cba4b64317ff2be0608dbc264bbe2f3fd7db5ecc9ead11603aaa3e4ec2a4","0x4a81212226915e0ef6d16698602c3e7dde98bd39b156c41c2157c3747293873f","0x2b23286f7b1d1b299830e8f047669a4c18e269a9fdb99aec92388175b2ccd27a","0x27a6ca6f0fb5ea06ba1fd60a651465b6e78d5e3a7c56e51fffc1200ac6ff4e08","0x9fb556cdb57a52ec73ac017264817a29e759489eebbfdcda705b292dd86fb2a1","0xcb1929a9a47a58ab276cd1ae5f57fe82235cd0ef0588c893f091f5804282230d","0xbc97930626f3f0c728c27a2494c7ff58458f0faf2498154aeb25b5da7aea4c28","0x133b04f3b19be5878eef8de954f4cf65c85af5fafdc2533dab0d683d8bc34601","0x7aa392f0a9e7c09d54aab0ca8d7f26c6c99d55e3e85feb0dbdb01142c90fc54c","0x9d7f6a69b3cc32bb8919585d34541d76c1bfe173afd147fa9f50a6a2f5c63f75","0x3d8376960bec55390206cfef66de2660349d79611bd8b59c39207c329ab66ea5","0x41b7ec65f4bdc77eb9b5a18dca6c2b5f87eca918d9b6f27aaa5c9e9c6e59e8ef","0x0eb55e098cf8b207dbb2539571101e3a5117dcae0ddd53080f35b5fb8e37d3a3","0xe5c5646b44d755b4dd52d1c4253aa0c5a06958cc3f4e02ea2c280a4879fb537d","0xc12807af52882c1358d822aca14228c0754039811c044f9e00419302274d1c8b","0x9e9b20cd1512f6d8d8bbb44b2505f80ff6ee17951ec8ceec06016f3b1c595c53","0x5b18544b2b42566e884bc294a7a4ba91ef2d9ef071b8c366eb08f6df98fd202a","0xb66153baa1d63d6eea19a431fabb9d7d1c0470cf0bf27c121478ec9ed15259c5","0x9a152d77d836329946a4c7e8a584d296f008571b23ad302d276b0722c7ec9880","0xb338fe60ad7a86f6e244d47bb21904e167254d1c23972286418a2a904749c0df","0x52e1f488bd73a471c37a1af9dbd12be64cf727d125dd4e91981588c88262b08b","0xae86cd1c983dd16bcf027ca1a2cedd03bf7ab0c715f33ce5b1e8ca73a065b8b2","0x37ddff1e7a90020b2ed08ecd73e0ad29a829cbab01a12a7efbb62d28b83f0a33","0xbe33e6100d1233e2d6b89c33c65526cdfea027d010264615b3a495090309761c","0xbe63f43c8fd898d2a5b8ebf88fdc38be04eabc99e04e455ef0cd06a7f67f9de9","0xcf536b96ffcde711a5506bd8e236935ad008ef0eae715c6d9ea00ead375ebfff","0x817028a2c348fc02b82565d6fcfeb1afce821214a1563210d06c117150b1ded7","0xc2f64e215d69cb24e674244a7fa877fef6cc0f390670335bd1255eb202c452e6","0x3178600cb3b9f1fb2c151bbf9fb71d6a3c993a063282f5917644b56c2f1cf195","0x26093f980b88c38fda1c759c7fb84ac14f5a863715e71ce5eed0fd80f4af758e","0xd6c53f08b58e0dab40b9eb608536b6c3f752ba1ebd3c621feeef2e277b1f92d8","0xea8efd539edec4a67c626fb5cedc3c5fcadd4f64c7818e671013b43275cca867","0x9941fec48c2983a7f3ba52f1aa24dbd23032761a23c6449288899a31734b2c76","0x55cb37c5614613d54eaff1651970b44cf9cfe79bb0ea881acc618d8bffe1e269","0xe2de020d5c7dbd54e5535b244a58416b58e2b7ec150a2d1b3240553e20821b93","0x0cd191362532cb937b75c340d30f42de632c09715a9ea3cd342db63961ec432d","0xd260265dc98c33937e475b9246e0d6efb8d8dc29ac49749703728e588870f742","0x51dcdc9408f51d695bb211796bdd8065d4da31d58a638d63ad055aea43d24391","0x8be7b98cbc6680372be9cf3324e5b078151d47135a54bea0edcde132d9fc060b","0xe2d5000030abd6c7f521ca9a9f3bff6644e6245cfc931a230ada90c8150bd46c","0x8a9fa1d59bbba9d82790bd5f626955ce567ab8ed7f7ee5ab3d87c6b9861cf8cb","0x5da10aba7f2a10049632441a9783275b024354384a56dda8a53e7bf0f9b3573d","0x23cb2d74ca4bf95a04705c1942f68163b7cd3a07091de726b82f42c46ee1db81","0x711a770eb7e227acc6d8192056a53d7efeff17301bd8befc1435a576a89e00f0","0x14c17e5d0f165ff904a0d478d757a458171b61ac058672a922cabaeaeb966488","0xc181a432d75a7e94f1dcacc06be336380715a7dd95424d573f1e85fdb0d47721","0x4ad61d9c653344600273501be9cab3a4f3400f39b556739bd7341b88e12dddc4","0x06da3c029a1b99fb6ca7f2d4f863a6e7a46adb5df85d403dfa5c474747a65197","0xc4252d612f23d9278b8d58465b179fc33592c9d33ea305c918146d71a6880ae1","0x495048a9473e25a9ba620ee9ca207420f5f4b1a3062454ca246dad02d504d070","0x201f5debb12fe92817cfac3189a6f74d4b0836bb8250f964e3606cf8e061d4be","0x9583a93f6c7387b7ad9cc145dcdb41dbeaea42fcf705b223c7454df0a3a7a146","0x4c197d4b296d9baa92102457ebe13af451e267226bfee983a0cd5dd11804fde6","0xd89692badfad96bfca593e3977faa557cb1a12d7d93cd7e3d1e95c9e7a907fd7","0xfb633e2c4228df769c30d80cc09aade34b504968ca50d4e968cd736991ae340b","0xfde53336ae40788c28c9dae447e5de2c22a31552a082a3fbfac2ecb3fd0b0afe","0x53cf7930380a7678aa2f0d561a6283d968290d05a309bb77f70891e0f791f7bb","0xb1eb4c4372badaf37f1874b055f46fe2a5417a78c0fde4a6dcf424768f0c4576","0xcdb5e7dceae096a36fc0959343bdf54a5aae9721f95fad68de837b9e82b7cbaa","0xca3452f0f818b070ba766d071f99fcb0e04254140f8ae91f8682216f6dcb01ab","0xbbdc330192449403bcd61cb7f7f1e5687675ff960b0ec23ad003d05498d097c3","0xe65c7021783548d99e412426ce8797b3941cb086b6dde77fe7874f248a51cbc8","0x4b8544c69103256b19066ac0ffc4f7aba37020bb96c01fd85c57eb8877dfeeba","0xed51a7e116bcb88060b901d00a8b67d2a4af86913ebd61e5ddeb4549ece6ade1","0x84bbc5d00c04fb8f16e5a5e059fba76aa3250c739ec6ddaa18f643c7a26abdb0","0x0a072908f6e2fc752375ad0d944324451bd09306b61cbb6c67090362d89dfc2a","0xa9cf5f8f1b628d98926a268e60e49f768927e777dafd7643f30264ae011405e9","0x51a6c004ec8f99238bdf0c436ce7c9fb4633e94800063f1268e8d6a46863e168","0x6a08d5eb606ec36c3101428eaccca62b65021b80905a4540046906467c939f18","0x4fde204dccf2ada6a902008e540b9b19c6c559196dd8902e961de60d864a7b0e","0x76ade02044b01534672c644ad1a5240281ad618864b848d37ca0fb800fd82546","0x2994c7617034391f65211bd99e8cfdec7c3265671ac9af04b6624707695b7a8b","0x4752a2721ff909a7e9b044d4d7fc564f95ad48f1ea1b3a01a4204a6a62ce34cc","0x75b9fe3c98cf4c30f7cb818ab527a08d0ffe452b0df241eaa5060bf703ed0d53","0x2e1ae711c35bc62f2c441ee64059f4e01208b6ef447d86cd0102e9f2d0c25aea","0x46f3b1a7491df2bcb0176b7cb2148b6159ec231e03c812c7ae90ee7ea98e6047","0xf4f6f9320ec234aa0cb4fba5c154fafb2b9bef3a9bde8e75ed5c7fb662156e79","0xa00c6fb89365b50248aae7ea0cad22d60c9a2b98bc988ae63e1569e2ed1e8fd8","0xf20afa097961a2a3be63cb88792e2a0dc3c450d587aa0507efa7e4a4849c0b08","0xdaf7eab64c8849796be2feacf4809b57cd5c14945f74a854f3e9d561384f0fac","0x722745ffb39b494cce9ee99d2c96eff7efc06a20aef2d9f8d422a217a6ee953b","0x6092ef74c19c276c4101f9913eb788565176e9724ba3e3d1761846682b200765","0xb28a93109f6929cbc13037cb56bb4dcca0e1db182db441d8c070285eee93e490","0xcb693a14c4c759681231d158c3f04c8a7351c1ed3d993aad4dbf0453f7e511f5","0xbb27fde6b11c1089dc31a4aeda73e07e465b72cb409bbfa52661dc8efafbd02f","0xcdc33e1baf1d7601a93a5b99ac3e89d51ec9b46e7dc5d48e567c5a35bc717166","0xd0e588ff41c26cc9af179e44a1d9bc50f70178e0dfdaf779019284ccd5f66b8f","0xcfa7e6c0aea0b046423c4b50769ea497e705332b094a0ba97d47bbe06ce7e3d7","0x400bbe5255ae5d193df4c8390c15480ed5db3b44705ba5a29d6393548c84ca0c","0xa4729ce3bd95d1f38d8ba80da811d1a42a0bb6ed70579f47db1223144066c603","0x1f252132af1cd4b19b7a3c5dde633920b4960831f526b65b4b07bc7bee84634b","0x5d6b964669632e57a66a4f474881579c3ce4d0ef7fefd05f10d89564aad22ee1","0x2876a43fa932de3607f848f10e893ab1b60d6b5f83baea7e9675974e91a99f26","0x50e4644e9f8de368692ffeaa0e3cf6442f40e62bd4f791eae61d0f08a272c3b7","0x63877fccc56a8d5abce4338417826707d26db76358f86c4f055e94ef38c28ae6","0x334860d8702eae7814881279b7d70eb9fe3a1ccf09f7602671560090a53b5abb","0x8b4fbffad18a8793069e3c22156e8b1ef60abbd3e5c58cfaae5fe6daf99b4b9e","0x10a3f8a7356e91e43171cc3567eb7319a76f9463e4bab4eee65d39ced1ac36d8","0xcac87ec886045c1f38eda82ef2c1d89dfd0f77f9becf74e07a4577654cbf022b","0x0b34bed875174b8badbc3c32ea96739d3ec8c5b402b3437a4e5c0722e11e64e9","0x66d1350d56ccbc45de3cf6f23b35ed6b84106c6b87952fcaf3f1f7510aec43da","0x7803eb3a01190a318b24fe265aa1f1f3f4a2a7f2e18185a237c11b8a5a88022b","0xb8633f1f52b76fa8c61da39e8db766cc848e2e119a9afb456803eef3a68b78af","0x19059f8df642ee02e99604f8718041ef5ef18ad2761e216e5d3e8235ddd3cb7e","0x0ccc9043942be8abc289705a171bb87e649983664b85810a49d7c521314082a1","0x4b05213f73787628c42f270b1e8c8943f60ec81325a69bb7e11e9599954c9891","0x1b6706e8d0632377ead4ae8bcf9be2d65944cc8a96a02185a7c1aa1e238fee0b","0x2725628f46ff79f680efa6ec1e3e1be850fc136933d71a4a78970e1ae50e2b2a","0x6d6a83f47b97d946fa0b793a051b886acc76e7d5d7ff9312dddfdf781f680ecc","0x16a0efbd33c6f0164cd6c9cd8e90a325cc43cc37712be7fc264417c409e52ab4","0x32592a25042f1e45f236e5eae7b5cc4a60f9892c96af486fdf1cb787dc1b1752","0xec83bd31a09a4ecf80a6725d01c4ee81f9320a6b4974aa43c7fad55f11587641","0x57bcab06f564430c67afd296a709a738897c3ca187fd7df9f1994e5b270d1d3b","0xff67f63ac0b09cd2739c96e5dff795e531e56362d598400be09289e48840e588","0x82b187ab4936ca4b10b358d5dd098848ca29d38b44b81d4b5bb39f407143c929","0x3313a81e1f97300203a64fd21a098792dc66e1ead6eb0038d9ce5d1550b2d49b","0x091a965c1fe8bfbccb8205485df94c1a805b70cbfd2c26858983554b3e49f0c8","0xd46149cb13e9694c5c9726a5d899109fadfd126b49cb7d3ba8798cb073d34bbd","0x3bdaa1bd12de393ab55eb13e27f14182a10aa1c73802ed8bdd3d009cefdffbdc","0x68369364513c8a71133953b33a39505084d9f01d446e85a80070f76be6f818d9","0xc829cff5a3b99039f9aa071461fd94961f9f91f0f13af602679086fb1105918d","0x21e71dde8bd6c3fe6c1017890954bbd495a980a0ea9f961b22e07619adab04d6","0x02c2cd7358ae1e8a2d6bcab393dd07bce8bb99c3e379a0a16e54af88b0cc7849","0x52f866c2acb440f9c21ccb8c1942979ccde781ced5f177e29792eed2eb1ff9ac","0xb5718132012450c7b69d2222850d9d712cb30827e96d5043e37d09ef1ae53fc7","0x5f956ec45ad18f565a27619038917b4309cbe088627ac6be1fe28e7a152cd536","0xf0a4f916cea55f76ff97c22452650a6767c8062945227d2b4ca79f88e4b83d82","0x2805f71c5095e51d98fa5f13303394f6cd24bc89cef189fefd71be1f31b97023","0x71e900d52c5c9a3e1884b916e9070744795bb6c44596f34b8ed31b32c3cfa4b7","0x5b9fbcd3978befc7df20298950829f93ad49ca9b2c3496f6616bf66b4b12cf66","0x266db59a14c82448063f519377cc83edaf0a762b45c6f916a08edf8ccc021661","0xd6185a553b3ec555996ee0bf8fd5abf57d6ff090bd5d742e0fc2b87d139c69f8","0xdbc31dc4a704d6613ad37d30f1b3504835bf821c770e71ce75b96e720683f264","0x20a591bc984f37cfd69c4526777fdff95aa73c6d3ceb15f1d9072e044451e365","0x7a7858621b03cd7cac7ff64816469fc58246b3e8834fd77101b1518365a7c935","0x755b7857fd6ce6de17b07d1d2c6a84225b62eb8fc8270e4b3f9645817cd0d0b4","0x839afeab0841e2a33b14848a949c0b10521d1d657ad3fd2a9857d16c90e91fab","0x85b1b4bf991b67b7094dd40303a511bdff3f200e71886c7274347bc9c5425520","0x182c070f883d21c4414652350858be42ee00de8a456541fce7b903eeb83ece2c","0xdb0666348278f2a0fd9291c9beeb1a93645ed0b23cf6eaddec4c102931224395","0xd2854a721c71a44a979e50007c550872075d9de3a8f80295b27192f353f5c18c","0x59de2de7662e06274adc2befc9039410f99b3208e09c2ed5d398ca3945c265bb","0x1d3f2c6817d46ae6b7605ea36f11d53b51920236ae49ed4f76f25141c4634c84","0x19e364d7133d3882cee45f1d7aff5bd1e1204a24aba972f2d7d136a48da28659","0xd709a623c599f366b8731143f0c7be3aac44988a02893e7ff7269fd675847559","0x99df0644485331007f19442f46d2845e199a87fa9bb3ee98bac8bb73da9e0200","0x688522eb588879b6ca133ab29b72469483cc3a29946e66a1b705a92f850b7dff","0x1e2ea13adca753465a53850c00067eb6b7448b5735c86b59eba4e4becc3802bc","0x13d78e0dbf5816824b950d6205a51fd478320fdf14483f6c96d45089eae0f87d","0x4ed4697c6453b1bb59d2f4675e21c59e1a95ae760c05c051eb3965a0b76fdd6b","0x79e4f785fcc14e40a49d60e17c680ab0eef8fc8baf33a96f5572370059b49c96","0x476f964caad763c8ebc9a0d0cee7a7ad17eea4d49d1577873ee6e245dd0fd563","0x8fe617cf2366d5fef8d2a0325687232728715950833a6ffa6bc5c9fe6f98586d","0xda1fb7c91174fe4622106d2efbc1e6b24e537dcba44d3cd94cfe8dec405da856","0xa7eea93c3def7751b529a3d41af6f4d9a37d63448d681f4e18a314def8dfc4ab","0xb6f445e41f76fe7f2448201502949cf2e42add1232ad83b82d7574071a63ade4","0x8ed1e8e529503337de1076b8b2008cd4b86fdd0e9905f4aae9968fcd76287536","0xd049338e6f42d0e67017c3558cd1a1a3ecb5b00d4f228fbace2ec96788f6469a","0x58e89b3bbedf7b64216bd2ad0408e0a36e11b1152558eff586eb9218ee416be3","0xa877c625bb74c733711d9cb2a9677ff4032df591e37b969629e8840dcc25cb60","0x4557ab90820ef75b5ac74e8de6ecfc69cfabbf3393af50fa1081492d0b0c2610","0x7a214e25fc3dddadcf0e07ace5908bfc4efc12d68fb324497cfd998bea444ecd","0xdeb0b4d58b21ed4fcf1a93915904aeb77fcbdb1ccf51904d7ba22b0c27ded143","0x5629ba4b1beafaa1e59e24681ac354e35f4bddb1638f39bf8679ba4b43a2062b","0xd947304fd152744c1a34f5687a1bdb0edc6dd88cf4cac69b9147cc70cb25591a","0x2c0debbf7878ca09a7a9c68347fb1be9143356106dbdae6dcc2ab63b343136da","0x6a26a67805d873b848f15e609e7bb10b78b2034398137d2e90a7474433737e4f","0x53fa8552628c69aa06ca0230c88a1e2872a6b2250d50e46efc09777b992055a1","0x0d5943de3b6d108aa6b731b0a66d6cd44b39c8ceae7658444e0f1ed3acb11e73","0x91fb0f2da95867de5d8cc815192076ded5ffa26a50cd1c719dd1aad887b865d3","0x4f5dc07f421e163f7c21b168bb6d9582ccd023f4a5795e2b0ed0196f76068dcc","0x95e930d6c525a8b551153e1e60eccc533f7602b10fcecfa6f0799d1105cbe957","0xbfebe1603fdd6ab825c51df99f2ffa7b0964ff3abbd8a49fee557fef7f1cedf0","0xd9038c67201c96f0cb8e7cc616b0ee3a24e56d1be51d90290fc34cf353cfd26b","0x4f6ad386e9a49af86a91c6e78adcd8a9779556d35c51c02c31fb13d496bbc391","0xfdda6e4cb24ac52e6ded7780ffaed0c06982a53e8cc2005306508a162bcd27de","0x42d3a08b3a780bf98945b0f4de90c53162bef61c0b31ff6f797433b6a436d772","0x6e4e0643cab8c1f41d5a02211b8a4158fcf800f1724e787ad2268a5ce11c11d7","0x45ecce5652a86fd45862cab4c2d28f2a68d3023765ec56b42b7d1f3eedea2198","0x97f1e237e20d8dc4c0857823b8ff813a5c5f8092391e982ffd64686ef838633a","0x431e2add2cb9e49ff0ea8facd6e1fae4dd116d56065047e24978deb0ef7efe59","0x0dd9d2a07f6ed4f23622c1b7b6683add5a394dfd13ee9e5ca35df33e11f82ee1","0x3d698da0e0dfe296dff80e309f80910d0cb59ed58acb6ca8db870428b1222e11","0x0e9c8444a4c866328f96ef2692085e63b75c76063874f40c2846eee04a54f0c9","0xc9e91775daab3973290e9a0ed93a24ddd5e6a328427dddcc550b8f664bed567d","0x70eabfab61439a635664a79b986cd7a18839adcc399d78998c240b8b3a7af555","0x08ddc39ee392d1965b67aa66e4afefa92030410b2d99612798ed902d60699bd2","0xca126ba044a2ffbde08e107cccf45ffc1b42c577098e4eec1fae5c4b1720aff2","0x80575a1ec38cef92312884196c06530fc41ce0575ecc7086e045c66b51ee0b9d","0x9d79677020d92ad0c14a9ae3e4c8774b38a5c1dc5218cc1f4f4dce3020b9a535","0x8103deab6705f2c7468dc908161f50dbb0b8110d0bac842421fbdea70a066822","0xeb89c381c2eca2baa3452ae9c8d47a2ccedc8dbe82c04f5036e25326693262e6","0x641a40cb0b9f049d527067a9d2038e596b7d6666062e0b35f4ec8a24b7d3481c","0x73e0d99d953b1f2073ebbf92398bfaedc7c458ee5e34a5ec9da6331f6f2af092","0x62d5978f35a63d4f132ba0a54192a305bf90cb03237fbad726e47927f0be20d3","0x48eaa28f1aec60d8c42d49f2e0f8980679f7680588f0c97a136d82dc9fa32fce","0x0a71dff9217981d16766f08aff7570dac7916d62e9dcf7af29dafef5ddb5fb4a","0x78ca168a65747f652e981a9e0ce4f97aa28ab6240f456cda04d3d0a48c52eff2","0xb1d6e739b290b878d63cf7a39ac6a44e465e108e1058360282b016a02bc05211","0x0c3eb583458e753c90517ca1ed596f89e085fe8793b918f323db5e5fc6ab05c8","0x67db4c79c6f9cf3ad90f3bb53c031035842153b7a1cdde1b4cebd11cb77e36bd","0x3da95a4db6f5d7b62f954cf098784ef85dc8ae6cbc16f0b953c0543c5804c439","0x8409f29bef6bb18b0aaf447451336aed1474c51a27b49712299f622fd0d1ccb4","0x009cafb33459411f38a6f0b54714af64a64cee790eac4dd2ede908a44afc873e","0x07cee3a30af2611bb099823e66bc9004368d2937a01153b4935709b54c6999ee","0xdcc4bfd58329d545cb1bd58574560cf846e9987719d432d5df1af6614f631658","0x11a4bf619738c7500537c51ebf4f64401b7a6bc236e009b41d5a79cf34bb0d77","0x922bc8f982efa2fd5ec1c9b0ed7e4ed653eacd4fb2eb153755af92408ee67d16","0x0e2189d893f7698bb4d3ac223779f0842599e1b6b5801be555425980353adb4f","0xe3729b123ff15eedbff2609726a1b6cc9e3626b2761fae59f798a26d7b766fca","0x689f2bc144a585a5b9905f8001073fd5abff91bf983577cf4a657c91a82f6a45","0x3f8dc47613f1296000f78acf982f3f957f923d94375deb1a73cf71678d56667e","0x12352a0e1beb94113c79d525704e036ade6304beaeb1212644f89c34b16d7236","0x58c921e4713d2e889177979d2581626d9097373520f198918f7034bda90f920e","0xec976d990f9e1ac9ba709cab35ef619d1ab82a17024d85d64d388bf90b413e20","0x0f823c7352d99b40f4253e4075c991b77d5e9cc1d58427ece66b07bfbd0742a5","0x34395cbe01622d83fa89f2fd84ba5b06426fbcac995538a56a2f0cb83614a6b8","0x47d4da98d44e67d3629f5de0ef89afaac05d1ccbadec327269944dfbc1b232bc","0x9a10d5c0322eba22df99c82547cfe584778fd47e1a2a6a71ef7b050dcf2b42e6","0xaa1ed4a7ec430a8d73ad636d97c5d271b2557932a714a7001599d9a8f8f27010","0x8231888f27e65775be79119bcb1de5480e0475ce352b9c867514bf536467d263","0xe0901ba43a6259d1010ded14076d686ab0a3811dfa2994163c7604be20020e85","0x890754a7a664850a9fcd185953f99ae7707ccc66e0fadb8eb8c115824c27a354","0xd23daff203f3132a98a83a77e96365d0c59110ae8761ff3e486706b21e006fc4","0xc97032e622feb241cc01e4740ab777387d6877d58124debd8c4a5d92d757e4a1","0xd461a8d5c1714e993b0a67014315fc22f7b38f273ec86b0fc9b78d0ec659c1ef","0xdc1bb5b3603a63a2d5f288f72b0a48e248835f1e13cde0865e15e6b5fcf8d5de","0x5a2a3a125387958bff090e4bd16393a1683cf169db17eff8b8761c17358bafe0","0x28134cf6679d83c33877f9243fe990cdbb62ee4c887023862db74787c4fc55d7","0x3cc71c0bb2373b8506eb659ef456dcc824513db236f468d23643d9c46ee3e25a","0x378040d0ef6ed1c452a3dc9fc32e903a891baf2655de212c2a1153aef74571c6","0xc5c746dfe7be18566fe74937e197c517b6cf373d1f1b1603b1d2b2cdc5f78a55","0xe080da92b79727d39bf6accfd2a96dc60719ad361a35b516e8ad0aadae5b30e5","0xf33488efc39ad37677013f9dea6422afc7b53e17db5271db5f1f8ad13e4f6c97","0x6b1698017d56a8e7224112cb5fc4269b59f4207872787b50649ce65e199fed53","0x23f97bd0caf28b45572fe964850fc700eabb4583dd6b4a2ed1927df91ab5187e","0xac4caf5ec9c60cd70cf7403eb6c153fd53a43b43c2a5705d5c61e80ca248d34a","0x4e64073f026ce5734026eea4ad92b9de19a0d516c77ec480100caaeb9f7da155","0x518a97d8b45551abf464a7619f5294d8454008cd05cc59c7b58333b01ab07d15","0xa78f6b3696ccd4d4138df10e97b9e1616f449bf0322ac92730af607966c11fd8","0x503cd7224b069151d632b8abcd0545b6683a981477eea994357dd87008f49cb9","0x48facf692f330888fc45d8952959855d9b0b2d489195e63fce9e5df4a6f9afda","0x5370c5cf87715fe6840095e43a8973431549be3158479485993d0f777d5fe7fb"],"txCounts":[0,0,0,0,0,3,0,0,0,2,0,0,149,2,0,0,1,2,0,0,0,2,0,1,0,0,0,0,1,0,1,0,2,0,0,0,1,2,0,4,0,2,0,2,1,3,0,0,2,1,1,6,0,0,0,0,3,0,1,0,0,1,1,0,8,0,0,3,0,2,3,13,3,1,2,0,14,1,1,1,0,2,2,0,0,2,0,1,2,1,1,1,2,11,4,2,0,0,9,3,1,2,3,0,4,0,2,0,0,2,1,0,1,3,4,5,5,17,4,1,0,1,0,1,14,1,0,2,1,0,8,26,1,6,10,15,1,2,1,1,5,38,0,2,1,7,5,2,2,7,13,2,88,3,15,13,222,3,0,14,25,0,3,6,0,1,1,2,6,0,3,1,2,0,1,6,1,2,3,2,7,0,0,0,0,0,6,0,1,0,1,8,0,0,2,33,2,9,1,0,1,1,0,8,0,7,9,5,1,1,0,0,0,4,0,1,0,0,7,0,0,34,0,13,0,0,1,1,14,6,0,0,0,4,0,0,0,2,1,3,13,13,27,0,0,10,3,0,4,8,4,11,0,35,35,1,5,5,34,0,8,28,1,29,6,6,0,0,10,8,6,5,15,0,3,1,1,2,2,0,0,12,0,0,3,14,38,4,0,0,127,34,0,12,16,1,0,1,0,2,11,0,0,1,1,0,2,0,0,23,0,0,61,43,9,77,0,1,2,24,5,0,0,0,0,2,21,17,3,1,12,0,23,39,26,11,3,1,25,32,2,0,14,2,0,58,40,10,65,97,5,45,21,88,66,5,35,201,40,6,4,108,3,32,94,80,22,46,75,152,69,81,289,60,54,88,82,70,89,41,110,1,180,4,82,36,145,47,262,7,111,77,41,232,162,0,43,164,43,0,14,97,45,2,55,21,43,40,18,29,171,125,55,168,82,66,120,93,11,40,84,52,124,56,56,2,138,105,134,99,136,205,146,121,219,217,187,121,67,120,290,214,205,144,179,277,234,231,114,156,156,366,266,314,259,289,264,236,9,40,66,145,136,334,378,73,170,88,34,127,100,112,196,59,109,26,303,89,40,56,58,85,188,13,107,65,164,21,224,77,57,380,80,14,219,143,94,89,94,124,197,63,11,173,51,122,148,180,101,113,166,94,107,125,51,144,147,85,121,127,155,82,176,130,164,185,307,250,47,22,150,125,213,133,136,131,114,44,128,111,44,139,200,92,21,116,205,118,281,119,156,136,44,130,288,83,59,66,59,67,141,76,75,144,24,63,123,155,44,119,63,157,23,74,53,70,0,10,49,129,137,58,304,54,104,74,95,94,41,242,28,76,5,17,11,125,18,31,137,111,86,168,14,16,20,153,75,185,112,159,166,48,11,108,57,84,30,49,72,141,10,49,79,99,15,48,16,71,151,114,29,89,5,105,3,175,34,130,149,154,25,5,140,7,110,61,170,85,80,172,100,98,166,0,74,76,99,41,58,0,132,187,152,165,113,45,149,142,2,96,110,44,44,59,98,6,91,126,64,147,18,11,28,205,129,0,83,51,20,50,63,57,35,77,160,31,63,64,0,24,121,129,70,21,99,106,36,74,168,101,129,229,198,0,211,134,44,40,178,211,51,49,108,99,205,224,205,119,69,232,62,51,194,0,103,91,147,38,237,103,92,108,123,193,43,131,190,32,29,155,166,20,128,103,11,93,78,138,12,204,0,193,76,30,38,68,184,108,22,208,53,34,0,141,55,58,190,61,0,121,188,49,0,45,184,136,103,171,51,117,324,262,13,111,215,45,38,108,71,11,26,246,58,81,38,57,108,67,12,46,109,73,7,88,121,113,63,10,20,210,237,218,251,184,217,9,60,46,170,115,84,130,23,105,0,184,141,104,147,109,14,84,208,32,90,167,85,99,281,11,55,18,98,65,22,72,26,118,251,97,123,71,113,145,83,118,0,146,89,152,43,197,9,134,56,34,124,125,72,215,52,47,125,143,58,157,131,220,170,126,193,99,40,61,148,63,0,138,49,186,68,32,137,43,175,124,96,131,157,130,142,112,97,159,179,209,171,177,100,214,0,80,117,161,163,51,167,96,103,208,116,277,194,151,31,118,191,172,107,123,54,0,254,191,66,349,168,285,80,158,544,176,171,210,149,136,246,201,169,213,161,149,277,246,171,184,172,118,188,191,213,139,136,172,49,0,403,261,194,255,220,197,314,135,154,187,92,112,178,234,167,255,286,137,271,156,186,128,175,109,217,212,122,151,210,240,137,123,265,132,188,182,134,105,157,165,159,167,97,0,101,179,208,157,138,98,233,178,85,162,136,194,213,259,0,111,290,143,127,224,131,207,162,282,338,126,421,125,145,222,147,121,182,208,194,193,178,214,205,242,145,243,235,90,105,51,146,207,243,136,130,218,218,230,175,279,164,146,172,206,304,179,183,228,245,107,238,199,229,132,99,145,123,155,165,286,151,122,196,180,354,152,164,244,171,120,167,204,156,220,134,243,267,251,30,283,186,213,147,273,191,213,234,209,202,357,259,616,230,288,283,229,219,293,127,261,417,122,141,169,90,249,245,216,165,208,290,155,135,155,198,236,140,364,188,168,119,319,205,154,139,203,160,175,142,314,221,0,205,246,190,0,150,188,149,182,188,119,148,189,141,173,139,336,295,79,114,85,44,327,327,89,242,97,69,128,55,7,47,133,45,57,131,44,504,55,178,12,13,6,609,132,249,57,324,60,22,57,343,294,484,280,453,339,238,320,39,41,429,329,43,273,168,89,23,200,255,222,5,159,23,271,425,343,101,153,311,122,171,412,215,35,64,208,17,357,221,175,345,230,523,407,690,102,232,419,233,167,129,62,284,299,152,356,39,444,247,34,8,173,283,223,125,46,209,116,167,129,180,404,90,130,420,347,49,141,33,123,335,37,13,117,378,15,78,23,77,112,111,199,90,205,190,690,561,373,425,63,356,235,98,214,308,209,316,325,219,303,82,16,429,40,125,179,113,137,151,91,94,120,0,273,241,196,113,530,225,196,58,230,129,39,0,305,75,281,215,223,62,192,178,196,85,0,65,339,139,91,307,41,286,330,338,14,178,154,293,129,334,25,279,163,323,159,252,373,249,344,123,11,48,344,193,54,298,103,169,8,172,87,75,123,142,5,363,267,0,9,170,127,218,1130,182,91,47,374,188,167,61,414,31,274,165,124,57,175,192,163,139,200,31,243,138,14,5,144,244,136,114,183,195,135,446,20,196,20,197,181,171,179,150,114,197,163,140,206,159,210,97,158,95,164,85,27,83,96,239,131,238,222,124,120,143,183,147,31,167,107,70,209,124,150,410,79,147,150,114,116,116,145,128,94,53,154,125,157,115,153,129,590,104,174,115,115,107,99,123,108,159,115,155,232,119,158,151,174,22,190,93,173,135,178,95,163,208,127,138,197,131,87,156,99,144,142,126,180,196,154,103,168,159,132,204,190,131,248,194,175,150,181,154,120,137,46,161,731,163,156,151,107,118,129,72,149,93,138,95,112,144,163,131,166,146,127,153,131,177,134,106,112,142,148,104,161,133,135,126,116,183,142,156,78,107,110,124,144,123,90,116,114,119,111,166,142,124,129,107,112,78,218,105,140,318,176,110,123,200,120,156,141,137,160,150,107,112,162,155,163,118,121,184,139,139,110,135,129,190,115,125,227,128,129,166,152,159,121,96,82,144,122,298,126,139,586,100,117,136,171,137,93,87,154,379,117,134,131,90,150,90,171,152,84,140,189,118,103,146,126,205,157,298,168,111,152,290,134,97,214,128,130,144,151,128,128,151,137,182,147,115,171,73,113,158,127,140,335,138,158,128,228,143,133,221,179,187,122,109,106,156,131,134,122,134,106,124,162,137,0,148,178,86,131,127,159,270,98,186,143,113,123,265,158,10,25,183,129,256,145,187,104,128,84,80,81,92,305,140,184,157,172,149,67,219,112,225,108,230,116,132,250,163,175,117,72,328,190,390,143,179,213,156,273,128,200,99,134,268,155,192,147,264,210,99,119,252,236,101,308,150,42,111,158,67,151,128,180,27,126,140,142,250,159,144,235,164,127,173,63,159,97,197,59,62,147,143,153,129,184,111,123,106,163,99,199,191,202,192,215,123,111,196,200,227,149,140,132,246,143,102,67,140,141,131,212,137,138,128,154,194,229,141,135,89,187,109,126,125,119,119,128,380,199,276,151,205,145,240,103,96,161,202,243,312,98,14,123,165,154,109,153,187,167,120,130,145,241,156,233,119,130,144,131,133,160,101,52,270,195,206,172,175,124,165,148,212,152,107,160,69,110,140,124,109,186,137,138,161,237,143,150,123,154,135,205,213,233,145,232,115,107,316,94,105,117,169,161,290,139,84,231,192,194,123,246,183,149,157,144,146,156,251,180,135,243,177,268,188,257,107,130,185,235,81,148,357,287,127,213,39,175,158,124,151,200,174,375,194,545,189,208,124,74,159,195,319,287,219,323,159,64,168],"txHashIndex":[0,0,0,0,0,1,0,0,0,1,0,0,74,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,2,0,1,0,1,0,1,0,0,1,0,0,3,0,0,0,0,1,0,0,0,0,0,0,0,4,0,0,1,0,1,1,6,1,0,1,0,7,0,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,5,2,1,0,0,4,1,0,1,1,0,2,0,1,0,0,1,0,0,0,1,2,2,2,8,2,0,0,0,0,0,7,0,0,1,0,0,4,13,0,3,5,7,0,1,0,0,2,19,0,1,0,3,2,1,1,3,6,1,44,1,7,6,111,1,0,7,12,0,1,3,0,0,0,1,3,0,1,0,1,0,0,3,0,1,1,1,3,0,0,0,0,0,3,0,0,0,0,4,0,0,1,16,1,4,0,0,0,0,0,4,0,3,4,2,0,0,0,0,0,2,0,0,0,0,3,0,0,17,0,6,0,0,0,0,7,3,0,0,0,2,0,0,0,1,0,1,6,6,13,0,0,5,1,0,2,4,2,5,0,17,17,0,2,2,17,0,4,14,0,14,3,3,0,0,5,4,3,2,7,0,1,0,0,1,1,0,0,6,0,0,1,7,19,2,0,0,63,17,0,6,8,0,0,0,0,1,5,0,0,0,0,0,1,0,0,11,0,0,30,21,4,38,0,0,1,12,2,0,0,0,0,1,10,8,1,0,6,0,11,19,13,5,1,0,12,16,1,0,7,1,0,29,20,5,32,48,2,22,10,44,33,2,17,100,20,3,2,54,1,16,47,40,11,23,37,76,34,40,144,30,27,44,41,35,44,20,55,0,90,2,41,18,72,23,131,3,55,38,20,116,81,0,21,82,21,0,7,48,22,1,27,10,21,20,9,14,85,62,27,84,41,33,60,46,5,20,42,26,62,28,28,1,69,52,67,49,68,102,73,60,109,108,93,60,33,60,145,107,102,72,89,138,117,115,57,78,78,183,133,157,129,144,132,118,4,20,33,72,68,167,189,36,85,44,17,63,50,56,98,29,54,13,151,44,20,28,29,42,94,6,53,32,82,10,112,38,28,190,40,7,109,71,47,44,47,62,98,31,5,86,25,61,74,90,50,56,83,47,53,62,25,72,73,42,60,63,77,41,88,65,82,92,153,125,23,11,75,62,106,66,68,65,57,22,64,55,22,69,100,46,10,58,102,59,140,59,78,68,22,65,144,41,29,33,29,33,70,38,37,72,12,31,61,77,22,59,31,78,11,37,26,35,0,5,24,64,68,29,152,27,52,37,47,47,20,121,14,38,2,8,5,62,9,15,68,55,43,84,7,8,10,76,37,92,56,79,83,24,5,54,28,42,15,24,36,70,5,24,39,49,7,24,8,35,75,57,14,44,2,52,1,87,17,65,74,77,12,2,70,3,55,30,85,42,40,86,50,49,83,0,37,38,49,20,29,0,66,93,76,82,56,22,74,71,1,48,55,22,22,29,49,3,45,63,32,73,9,5,14,102,64,0,41,25,10,25,31,28,17,38,80,15,31,32,0,12,60,64,35,10,49,53,18,37,84,50,64,114,99,0,105,67,22,20,89,105,25,24,54,49,102,112,102,59,34,116,31,25,97,0,51,45,73,19,118,51,46,54,61,96,21,65,95,16,14,77,83,10,64,51,5,46,39,69,6,102,0,96,38,15,19,34,92,54,11,104,26,17,0,70,27,29,95,30,0,60,94,24,0,22,92,68,51,85,25,58,162,131,6,55,107,22,19,54,35,5,13,123,29,40,19,28,54,33,6,23,54,36,3,44,60,56,31,5,10,105,118,109,125,92,108,4,30,23,85,57,42,65,11,52,0,92,70,52,73,54,7,42,104,16,45,83,42,49,140,5,27,9,49,32,11,36,13,59,125,48,61,35,56,72,41,59,0,73,44,76,21,98,4,67,28,17,62,62,36,107,26,23,62,71,29,78,65,110,85,63,96,49,20,30,74,31,0,69,24,93,34,16,68,21,87,62,48,65,78,65,71,56,48,79,89,104,85,88,50,107,0,40,58,80,81,25,83,48,51,104,58,138,97,75,15,59,95,86,53,61,27,0,127,95,33,174,84,142,40,79,272,88,85,105,74,68,123,100,84,106,80,74,138,123,85,92,86,59,94,95,106,69,68,86,24,0,201,130,97,127,110,98,157,67,77,93,46,56,89,117,83,127,143,68,135,78,93,64,87,54,108,106,61,75,105,120,68,61,132,66,94,91,67,52,78,82,79,83,48,0,50,89,104,78,69,49,116,89,42,81,68,97,106,129,0,55,145,71,63,112,65,103,81,141,169,63,210,62,72,111,73,60,91,104,97,96,89,107,102,121,72,121,117,45,52,25,73,103,121,68,65,109,109,115,87,139,82,73,86,103,152,89,91,114,122,53,119,99,114,66,49,72,61,77,82,143,75,61,98,90,177,76,82,122,85,60,83,102,78,110,67,121,133,125,15,141,93,106,73,136,95,106,117,104,101,178,129,308,115,144,141,114,109,146,63,130,208,61,70,84,45,124,122,108,82,104,145,77,67,77,99,118,70,182,94,84,59,159,102,77,69,101,80,87,71,157,110,0,102,123,95,0,75,94,74,91,94,59,74,94,70,86,69,168,147,39,57,42,22,163,163,44,121,48,34,64,27,3,23,66,22,28,65,22,252,27,89,6,6,3,304,66,124,28,162,30,11,28,171,147,242,140,226,169,119,160,19,20,214,164,21,136,84,44,11,100,127,111,2,79,11,135,212,171,50,76,155,61,85,206,107,17,32,104,8,178,110,87,172,115,261,203,345,51,116,209,116,83,64,31,142,149,76,178,19,222,123,17,4,86,141,111,62,23,104,58,83,64,90,202,45,65,210,173,24,70,16,61,167,18,6,58,189,7,39,11,38,56,55,99,45,102,95,345,280,186,212,31,178,117,49,107,154,104,158,162,109,151,41,8,214,20,62,89,56,68,75,45,47,60,0,136,120,98,56,265,112,98,29,115,64,19,0,152,37,140,107,111,31,96,89,98,42,0,32,169,69,45,153,20,143,165,169,7,89,77,146,64,167,12,139,81,161,79,126,186,124,172,61,5,24,172,96,27,149,51,84,4,86,43,37,61,71,2,181,133,0,4,85,63,109,565,91,45,23,187,94,83,30,207,15,137,82,62,28,87,96,81,69,100,15,121,69,7,2,72,122,68,57,91,97,67,223,10,98,10,98,90,85,89,75,57,98,81,70,103,79,105,48,79,47,82,42,13,41,48,119,65,119,111,62,60,71,91,73,15,83,53,35,104,62,75,205,39,73,75,57,58,58,72,64,47,26,77,62,78,57,76,64,295,52,87,57,57,53,49,61,54,79,57,77,116,59,79,75,87,11,95,46,86,67,89,47,81,104,63,69,98,65,43,78,49,72,71,63,90,98,77,51,84,79,66,102,95,65,124,97,87,75,90,77,60,68,23,80,365,81,78,75,53,59,64,36,74,46,69,47,56,72,81,65,83,73,63,76,65,88,67,53,56,71,74,52,80,66,67,63,58,91,71,78,39,53,55,62,72,61,45,58,57,59,55,83,71,62,64,53,56,39,109,52,70,159,88,55,61,100,60,78,70,68,80,75,53,56,81,77,81,59,60,92,69,69,55,67,64,95,57,62,113,64,64,83,76,79,60,48,41,72,61,149,63,69,293,50,58,68,85,68,46,43,77,189,58,67,65,45,75,45,85,76,42,70,94,59,51,73,63,102,78,149,84,55,76,145,67,48,107,64,65,72,75,64,64,75,68,91,73,57,85,36,56,79,63,70,167,69,79,64,114,71,66,110,89,93,61,54,53,78,65,67,61,67,53,62,81,68,0,74,89,43,65,63,79,135,49,93,71,56,61,132,79,5,12,91,64,128,72,93,52,64,42,40,40,46,152,70,92,78,86,74,33,109,56,112,54,115,58,66,125,81,87,58,36,164,95,195,71,89,106,78,136,64,100,49,67,134,77,96,73,132,105,49,59,126,118,50,154,75,21,55,79,33,75,64,90,13,63,70,71,125,79,72,117,82,63,86,31,79,48,98,29,31,73,71,76,64,92,55,61,53,81,49,99,95,101,96,107,61,55,98,100,113,74,70,66,123,71,51,33,70,70,65,106,68,69,64,77,97,114,70,67,44,93,54,63,62,59,59,64,190,99,138,75,102,72,120,51,48,80,101,121,156,49,7,61,82,77,54,76,93,83,60,65,72,120,78,116,59,65,72,65,66,80,50,26,135,97,103,86,87,62,82,74,106,76,53,80,34,55,70,62,54,93,68,69,80,118,71,75,61,77,67,102,106,116,72,116,57,53,158,47,52,58,84,80,145,69,42,115,96,97,61,123,91,74,78,72,73,78,125,90,67,121,88,134,94,128,53,65,92,117,40,74,178,143,63,106,19,87,79,62,75,100,87,187,97,272,94,104,62,37,79,97,159,143,109,161,79,32,84],"txHashes":[null,null,null,null,null,"0x1d31a775de39f8d41fcced175436fc2653a51ada160934f1d6b428d0b6febfb2",null,null,null,"0xfd5f813f7970fdbcb6306bb5522c4ee651b1be1f0c93387206282c5453cad018",null,null,"0xee0d26305131e14ad22faed44e7aea060c8f09278413ab2a926ac9484a004d60","0xffc847a3fd6a475bfecfe0b970f9ac39b2bcf684eb6fcdae4b593a505831b2c3",null,null,"0x42db9dd2959c89c42ca8c5bcbfa79b6d5cc9546b1af87f128e04831e7ea32e03","0x3d93beb4d7dac02b2bbdd8fbd248cb42ebabc02b7a6e70df538ffd34127a6711",null,null,null,"0xd3557edd4843c4a2f9ad2971938299acb2ebcdd0080c4af5803664606f8227bb",null,"0x977158b15a9488235c36ab8a5739ae98fa06ce4e5b836726b7d44294d0f01b0c",null,null,null,null,"0x90d41c6122aad7f46cb4b020f3fe7a2a8a00a2a9212bb8a010214c2f4e45d5f3",null,"0xdfe39c078869c77643402615f0e39f4808d27e137414b7adbc6acd887b4e28f7",null,"0x3cd359d0e28df61715e873e9df25fe5e17f251d7218c473e596dd8ab16a51f0b",null,null,null,"0xb3aa4f61efaf31946900171f6178ac1754c177e85861cec16db35f8b82867a35","0x00c6c5da425bfe7bca6bebf85a273915ac4498ca1eebd13b519a3424086750b6",null,"0xa89e3df60e00f5718f676eac0fee128fa0d49cd96afa95f8868c66199d98d895",null,"0x60b13bb3d58df3c36c899c52188b818005a7e35b06921ab185d87eaad3860cd9",null,"0xcd7c4d1843988495f43dc42c816fb636e974880a07c4e5381ab4a502ab66cabc","0xf9b5710e6a251308225b96ed44c25c38cb36b9d6a447d94ae6cc51d9b620e182","0x13cd7ee6b8d713195ea387578214636ceb6a0d0ce98af37f4d8f4ddd14d5ba23",null,null,"0x8ad68a639ca9f5ef499b01a75b16c9f29ab08e15216e06cb4310fe1edf38ecc0","0x879f628ef2b99a312e0d22fb1f425185369831e29ea6c93311c0f91554b99cd4","0x1141605daf14dd1f667d06f30e8e7de7a1ea127c7c547147a90306bd13a64612","0xa50dab9efe599713d66bc4e064946030b426faf429ff96abccfe37bb8072aff6",null,null,null,null,"0xd67afe14005bdc791584a9c46d7f45dbdc77074c1451bb4814e2a470871aae71",null,"0xd33f785902abb5e163406102d889b9966ecfb531cff8e91b9874887a35043762",null,null,"0x299ebcd04af9ea6a26f198449addcdc821e9365d184d533539359c4ef8dcfe17","0x89473a7b99cbc33c7c3722de4c0efb0db621e1066a94b7abfd293ed2e21c7ac6",null,"0xe1b254d579e7808e2be225ba372e604ad30e1bf0d35a18f70a20f64a348a8fa5",null,null,"0x263ad9e43f696f2f0f02213b67d8a9d13b436d10986642acd3e70b2e7911f00b",null,"0xdfd06faf8c30ffbb776b6c13d1b564c58714a17b32e3bf1436d680b562da5990","0xd4bba08715de662b51398355b261ad9c2a2bf27f7c0cf496d195023bb733915c","0x8ac786c11fd9c1e1f278736cda0ae293a567bc773939e47b30e4b792b45d90a3","0xc3504f7bcd91c822a547f0f5290b3bfdf4bf64009e1cf8ed68605c445a2ab459","0x2cedea1e46efe8c43af1788c38f3eeae34bca049d7041a0703893985adfddd23","0x230f8bed1dfa7937825fa06cb990a638f37ac2c9c8d23363757d0d0804702ab7",null,"0x1d372e867e1ab43cdcf5182c37e5f230b2c881f4e10f435d55c31bffcaf87670","0xad4929f0e5500060fab13626ae951410631f17ddbbc93e3ddff24118f2925363","0x69fcd4b3da729fa7062bbfe31da7dc26a3cf835027107c7235cacdfe0aeb15ac","0x0c15f8fe75c299648e064c31f539abf062c4292c52d326ad3a7a0b851a7a63a4",null,"0xdb9b652b504dcda6379e000a89bd9a07995a89bb02670e3e082db514708624fb","0x2f4884509a78661b4d941841f8b6437dd7a206b82316cd0ed18040d0fa446f76",null,null,"0xb5cffb03506700cabe0b7cfb3cc104a49fb191e2c72d216c5935321cc57f7e1f",null,"0x31cd016f481382b26893cc4a24bfe539130cbf68681e898323ca06006add6093","0xbff1e7b607cb8329e6188184435308077c6b1dd2ede960a621207b6c878d3f03","0xf29aa081e6f8149297bad0a481c819bc61e9f2cb5bb3b37792119f4170aaf36c","0x0bbf06e96766028b6ba408557fc550df3b96d339948af9c1a6df75ae45a0907c","0xfa887e6b16f950c30cbddd38cf0c622cd73a9aa35032bbf54109530057e254fb","0xfabd14d1b72948b5717ae5c3c3abd2dd87ba8a1b62db02717572d392903d9548","0xa61eda06227ea40603e2f74deff248655aadcd7c389c7c015db84c5004993358","0x04fc73c10c0c371c67b19fde48c4dd319cbad2edf21ed7e903321cd33235b8e9","0xfd337a0593eea93533ca91f35c91655b3d608eda57726a62c4588a8e7476c007",null,null,"0x8ee6f92f4cc9356b16b76056937850364179e77540b13327ab3cdf8fcedab45e","0xe4395d036b55cd3240d9bc03dc4cc314468fb08b54f749af1f34a9dee4fb4d8a","0x5b9666ca98edd2856f282715f5b7a7400bedeffed2c559bbef2261814be4d05d","0x1d1ebf618d534cd5fe21d116e31f6b088091bf574fe9a1b0d56f51bb4fa62f6d","0xdb02b932e50977059a3e2db246e2509ee3f6dc2d8571b974f868328edb4d6a2e",null,"0x9cb3cad337ac20bf23337e0fc821fc49211e2803741ce9ad1fda85c8fd7ab467",null,"0x248f3285551b6c0762bc381fa23d2adb0aa1fd95f223daff6e925d24b00786fb",null,null,"0x17bff3701fa1f034421f18416e85bbb1d86265176593d564477bdada88418235","0x454000226995f3f5e006c31d09457289b6e960e23e5db675988ac4033acca768",null,"0xe174313bcc4b113c942aad621b6f32c9aabcfae162d09e81cea9f3f80d30d990","0x085da1c3469c23b8e7544a1dff09dd1508b0156e2ae33c15312403497f1b64b3","0xa1dd8d3686d52945925ae3a3660955eddfa4685559faf458841c08d824e5f78f","0x9eb736bf6178af06813574b1a567836da0f1ae9ce28e38b19721db748172c3a5","0xfcadc6baa441d6108ef0bf2c1d0ef88f802b5563ddaf709d08991f3d3dc8fa5a","0xe10c28e3f71d20c8e224d40485af318e48c8c0ee1ab91bb3469a7724a4c2dd33","0xad531d143cabef1f2d079df5db0e426913ec03095db4bcddd20096b07f9a41d4","0x2f1f23e59938e188ddc8020c8f08d1f199493e1d902e898b6bc91fe8eb8300b8",null,"0x74bf297c63494d4ee6d4cecc283979b6fec5677f41cc1b785431a41e5d26d00e",null,"0xec2afac638a420b687318ab3a5027ea06b6485134ab4ac703bb28f3e3555ad6a","0xf62433c20daa7de71ff7bbe6f801a0c6169929c35bd10f1d425fb393ce5ed084","0x8c3920eaafc9d545f93052dabce91e4cacd6b0d458e1f7895c33b1dd484c7dd9",null,"0xc36ad06641a1651dbc2055a1b5406669675ff7b2abf214edf40b1f1a9216b2cd","0x8b6a1ef14dfa426a15d53c7775f7affd780c619e635fa5c7b6db29e6c1f14585",null,"0x82041b1409841232270ce72b73ed98c86369d421296c033dea3f5937934169ed","0x6d875a8fdcdbd8fc82a517ebba5f69366154ce6ae5bbaf2b60023cf826208d17","0x451195e063eb2dc73ddf780a8554cc001842548d6ffb3a07a20d17b87a6094f9","0x692ff0a3e582226987ceab98c309df7a7dbf835b8278949595a17f631765e2a0","0x44340b4934d71303568f6c5bdbb6fbab7366fa7109f649268b617e2a9203df38","0xb94558691f861cf4128cc612cae1de4edb93f1a0ec9df228f81f946baa6e6467","0xae430f9e4316d1af98810f64c4a9a90bdfa4b0b11c40ca0cae09e1d8f2a7ed09","0x6c427a2fc60a6a9d1ec71f3c039e18461810faaefbfcaf03d62f6046c2d85bd4","0x4ec624ddfebe75d983ace8626978cde7a9fc402596d8f5723de67af27791a5ee","0xd2a1dcb420820776a886512563aa44bea602dd3f43c588c2955ad1f205cb621c","0x8c046d4b0aecdc3ea33ac694ba2ab810a9a582421640274a607dbb2e484c8d42","0x83253494c3756aac94bc07e1b7aa0fd1c0e9db94ff35dd6de7b927999679f8c2",null,"0x2f397eeb49edd1fb5130f574d64ba405a9361c34f2918df4273b50c2cc56f38c","0x126c0827ddd2eb88a1c6b119f671e6c50b0352bfb4f49d4af60471051c950046","0x248c53b2043a20b241035788fa6de4eb7f592a2bd59fef62070a19cf7e485565","0x09ca05a074ffff1a4b13f2b22b1314f02961a20d1f69ea9000f80eba08aeb068","0x150d8bdd8f8b7ab928aadda15544454d879cc71b8e7104c956357d256efa1766","0x47bf049bc17acda40c6e387d536ef248213a508e353867a4687bc3dec7989dac","0x03fd84502c5a92a54bc6cd2c66ad799b241597ce17cbbeda871c33418d3ae9d6","0x8f3cac2966814879004f69b79427bfad14f81993cc4b7d8816e31a19c4d08ccf","0xe7170305e8c59182f5db85e7b76597c284fd78718bf78fce0faf6c6aba72bb24","0x6edd1b9aece2ee8b4ec83dbdc8ed02173b2ced54d080259953a7091b6fb026d2","0xb81fb49de4a40741789f584c827e191a76d357436b989cabd067981ed97571dc","0x8ebaee1f0ea1e7d793623628192c4269a73666178c4522b07c28ebc5fee9b974","0xfe8aae7cc2a9e294833f18c4eaa30d6c38c79d7e187d954e4a7df9ddeca4680a","0xb277c845616203e3875920ecd2847fab245e6301bdd7c0c58a24fc52cd6ba8d4","0x8f0865b2e18db8106b5cad222eef727233ada7bf820373ded6ac68dc655ee253",null,"0xac1a744b5f4dc5cb824e1c0ef2c0aa0481e8f17a4936882d333882d71ae8ff04","0xf157147e23da9117899841d6561a4a22fd50b0c4f7f0f21075a80452aa262c09",null,"0x6ac04f38bce293f2acbd7e536cf6c54e12d032124334c67bc905f643ce606638","0xb25035a132f6d50fdbc8cdba0d28089a55a555497954980800a7281595a7a48a",null,"0xea36ac1f4cd25afb9e90d27775a7e616fbb43e7ba8b836d580fb93f54ba5ed35","0xdf91fbc4103bc9d6a9413b6516b6a7a53d04327f5fe46c419293931d8965c74a","0x002abe52612d371b2e427f678a1c183882433715c8a9fa0e7a7d196c4631728d","0x85b5740fcb04ee4c74304bb0bf2789f04d37490920acc2b868c582015bddac62",null,"0xf5ecc907a5eeb03fec03110aa309520848c8c28006f9e92fa0fe249acb83a410","0x6df17f5096f220784a562b695a2e5b72aadbd5efbe0f9b31b29dd241a39a0763","0xeec68bafb42f1ce5939a591a6e78e187860ecafef6e95ee5461dadfea72d8f83",null,"0x90bfe805c09678c419343de22e4b58f5be27248e955fdd0a8cf229c988a79040","0xfe1a489f42805bfb19f915b04642db56f9b184778df204e871aa8d6088303a9f","0x4948de61bd6c1fa91f10e51e404c21e0b70e81a0e453fc63427dfd12ae4242c5","0x526c0574c969f6c7b2029de60244af4b2b0fe352aa29e351f7c8ce5339d68c16","0x9f95254aec6c8937e80ec12340905b4e732aa6e742c59fb28af3be8767534566","0xdedd96cf30fce50df2a17e0775da8e05891d017678595ba0c7846c0402f5fd4a","0xd8399a252d6afdf441003a8329602b7a52c2c0212b7603215d27a56c1993f7ac",null,null,null,null,null,"0xe21204ae6880c8b96f1c2d06557453267ec62d09e9825c9dbedc0f75dc9c7c75",null,"0x6c0a9da4f64351da953aafe72468156605b6a33306a0bca5b73982ba8f32ad6a",null,"0x3699fc89374ef5beb279b937a834e2abae95c9dbbfaa5c60a9ed4ef65e7120e0","0x7e33338b2e1879bbe0090b0ab4089508dac99f7cc5493079ae2735f471666a6c",null,null,"0x55c0baafa87614255dae6fa0432c866528a4d5a7b8e66f99b9be903f56b29ed9","0x71c53ec5f11f1f4c3a1702c27d7986bd1dd3657dcc2dca3624197a37486f1b13","0x49a5d3dcbf75cd2a2a6a165a16420643e079fe47d77b26846acf3c34c788d3c5","0x8c1d7fea963bf513575f9990a078b79a6389a4f81b1e179282702f41ffe5a657","0x5279ab400ac9dbd7351fa36646fe983455d928054aa944bd532edd28b616d501",null,"0x2a5e265342797ebfae89e7b0f9d0aea59926319c9e0e6a1c61513339677d6839","0xbaece21ed2071f7285276f0a1c887bf69795f377817ff9e563c1c1ab15f88778",null,"0x14ac8ecf9cf6390f3bc463ca57cb6a16beb86d14d98db7f21a1cf5b5b5891594",null,"0x381bd15fb72a079c1df8dd4885b974d18a4db592723258fa78cde2b344d48c39","0x10a5f7cb3aaa4e46ec985edffe9210d1411b7b27064d230fff92acca15a6382b","0x073acd9a0c0bf9e3770ef5c14bc563b84e18377824b94e587d765432dd986d88","0xd1a67e38f0ebacf8901fa585f2c27bf6f0c0626556af4fcd6df3179966c9e5dc","0xea7008ca8d603882b3bd3ea12d1c3b4f4f5682ac7293af1539a90a1df41b1d92",null,null,null,"0xd5b6619a20df4698b17c5d542e0b67b6a1201d47f3d662f459496005446f4d99",null,"0x676dd1f33a5d53bbfb3de6fe78b8b8d74c2b09cbbb216a2304317d234b6cdde5",null,null,"0x7005564492c6796e928e2a02dd7285e9dfb6e25e090d5aa5b9f38d73bf781841",null,null,"0x760cd2b6139447fbafd9b056ae5fe5219f093b0d88e952428bdd61479adcbd87",null,"0xdc123671b1f66e388f9be81b7390e11621216159d09da4d08d9b5dc80c69090e",null,null,"0x6e13c6d6d2e52b7f3700f1bc731529f171e7f5bc0430b916899f60cb4b4beb4b","0xa21f9d0bc25bbb7c9c5dd3b284abef952902b49fb36db9b17591191b3853d687","0xda0a41b211c91db0deafc8034285ed392dd3648822380254aea6ef08ad547080","0x867161e3c9200f8e51d706b3522d884e8f054108af442d77dbc0b9df6eeb0270",null,null,null,"0x142b3d4b385463f690fb5c206e95d1061a281914bbf7fd0c3e6691cb9902bd91",null,null,null,"0x5147fd79aa40d970d0b0978c378220b100373f336ca0b0f682bb2a0952c13302","0xec257c4a5a5913c58b6b255936972084d6debe03f76aef702fd7d733181851a0","0xd2a8456234e79f4412afbe6c44caf64f87456c41552b47bd4de366f195be7d36","0x312a4f1dc3295bc9285edf57e28efe899035e60b955bd2635c2048f80c387449","0x8cecb9d427d0bb850c447fb7582e9cb6f2c9b475801ae0b364811d656ca9d486","0xe6b3f2f1d8543a13a4ab733dad7f1a9bbef1239f9bfd3daf61c406d86561cb02",null,null,"0x7e5200926a25c97f033e1d6113673b6fc3f47b949ae5c9e7040add94cb47cfdb","0x840b4f823276d566df59cdc45d355e75b2a799e372f8d1b44ca0548666dbc837",null,"0xa8f6380b5492cc6d67f2e0dbb563663be7541a79c5d52fef6d3b2ea720fac334","0xda562be1671bf38cc7b80c25107621d55af8787b4ee66743aeb7ed0f5404c7bd","0x78895d3f5f9e7828da29ca06175ee242f864da6248593b7638e6fad095ed82d9","0xe744daeb8b5f4a766b1e3be1de64288175012af5b27f7a354021db6336a6d7ea",null,"0xe8659b63075ef381d904ce7cf933fb7e2b6a4e10e52d59cee265e8d90f2b0b82","0xa7dc397655741c06ed1804a88938558ff2f55703589aa16931626389c7df8de9","0xeedf79c08c03bd8ef447c32623f76add2ea14be033f393d5573c275eb1cdd817","0xf86e0a7064c42ee173309da4d0b4c7af4a755256c5b7412a1f458b5675619b93","0xe68acab741ec77bda63a38f8a2177cfa07aa00313fb1848ffb3a412e168f261d","0xf2250323be07b28ef239222d31d6b801c833b7d4ec96b763c871c3e916964e90",null,"0xeac76834b9e49ae9cad9b399064ef2c74ef02ab61492daeb5c3f9d9640ec7b4f","0x374e9e4abfc3271ab64be8b42928280fa221aa78256096a98be7ff3bf7a5eb77","0xc0725c7dfa5b445c4dfffabc786632a8622073f71c64669abd7c27ae2d619dc1","0x6efec79ac4a135fc4608fd99285bb9a2747005087a403ba6bea26c18e2293372","0x906e05ab98dcc3f4c85920643f5551e3b5e09a3f344c9e4b2487a54e08e5cf2d","0xb68e31b0d6b06aec100ba53a2788e0c100b03df7578054dcb85408b397b1c3f3",null,null,"0xaedb066a7f6fdcfa5f35048dd4fd4852e85e8654fdcfbbb6e4adee1e4aca7ab9","0x668b1dc99b39410716a0faa7f5d58b6f1d97b48a6b9cd1382602451a123703f0","0x0fc3f83601b8b49afa50a6e1d372d46f51e11fbf6bcb056bfb48350d0e120ab3","0xcf9c5c6f808e1fe5d3128046c8a48bc9796d58d5c5c47b6caaa9e7efb790f795","0x623b2137f346f35bd1c33d6b2f1c18d57e6633d032fadc32ce76734afb26b6b0",null,"0x50c2c16a65828fbc2d51d0fd0c55a0c6c40f923e3bc46009a18ca651d0aeaa8d","0x0a49386be882c4ff6684975a7849b7f1be10cb2c45085c71eab6bf205428428d","0xed77fe54967a9b2f95f90fdf444eb5652e84e27731936ef52b072119f16fb535","0x9c2f17c616419ae978f6bdc992aeb081a4181b383f81bce279b93ad8f6257520","0xd87c500ef632d07f3d557664135be14be5982ec00d23854c58f164bc66211bb9",null,null,"0x9e88bb170341b31fbfb307ee05caa7efe6bf10c065e99e2292e44ba46fe42489",null,null,"0x8834ff7ef111d8ceccd3b62a90ac6f4cf95442f4473fe133b8de76b6e63d13b3","0xc48c659cf87fa466ff3576d65eb65a0b6e9e8b0de0837e626276cf7e7e8d9440","0xb54be7bbebf12c0861c5637f76138fa6e6d247535464f5d2135a4b8fc8bcaa76","0x3e584cd29e423f2fdda22845db9558b67c802658343cafbba98404b3c31ec9ec",null,null,"0x5d2238bd7b2ca13d1ad5d3a0a2e63e2aa7da3da93add884606633dfb2f7c3a8a","0x147bf570294cb43dce66958d0529a7778f3038d037eb7f31e33a63bcb10487d8",null,"0x4ab8b2494fa4d83991c0929616639ac55c1933219b6366be972de2c7c6ddf079","0xa17e7a1ce21f07fa41517a234fb5beae34aca9e52e91a7949991c3b8dc713132","0x64995e4e03374dd433f6e64ff56882643f015be03ec9ceab56b014508ffb8021",null,"0xa0b2f59758cd745fb4162541b8327f502e2dc76a29fadeda1cff3eccf4c57c72",null,"0x67983abdac96ca026503816dfbf8a5304177cb566b3e6c78e4d53f72bc61dda0","0x9b82b5d66af4b9a2aed0449ac425d8bdf3a6f8aaadfa84c57878c9100bb73c44",null,null,"0xe21d2ca7b9c334ee0f44deb4a6f3cefb64afaa470fc3bebbdfe79308d2efd65b","0x97b27ce49151428fcc5ec0bd9a398c3e72ef80958e58c6d47ee1f37426a3d31e",null,"0xc6c2d10a454d5037dc55180c24e0d1346f71ea24ce4631b7d0c60fdcd6645938",null,null,"0x901ccb93e9d7b76e5c721e1e543c1d12ec90d36a1f9bd5aa72fb62bd434579c2",null,null,"0xd616e4ca7d8fde74893b05fe5a98377f114718baa65b43e8464973f94558df8f","0xf70e27d0b5e0741d6c6c586e277b4bbea7565febf3df3b426aa888700fb7cfea","0xa5119845a088407425d7012772ece073a32b4dd115c4ee14c50bd1126cbc7a23","0xbc95822ec2432d53d1df6a9afc2c71b66c8f6ec3125af0b1e66fe56ae69f5986",null,"0x4424b625b41249d2199de89ed1585cbd6fa6f73872f1b4a97e1becb320a871b6","0x69ad3e176bb53697339963e6520f9c26b802002b7fa2f2b720701d006e4d072a","0x3b9c9d2a0882d4cd2848082662eb2b11e95124720029fd599a9952ed68eee47e","0x679b68a52a5ef003d934a1a79fbb4a8465d4c48be3a99f225e88034e97f44804",null,null,null,null,"0x8e1ed7db31e561ff3d599032209f0824df1d7d8531234c0cffa6bc254ebf3732","0xde158b41f827fb85b164d9fdab87c80b3020cd8a72c113dba39211cd2cbd43fc","0xc7165e8e505116294db667abf4882e9b081a963bddaa8e2bb8917bd251273daa","0x57807af6556e1ee6b4f45ca82478a5dd816ee567c42a1551f3825b01d4be9451","0xe221ab752de76260771c67a0d07f8f710efed29267377e05528ddac5eab2a7ba","0xd8d9ca068fec6015a70908cf97501757feef557239cabdf83bff6e0f88a28332",null,"0x1daa8acc6024bc3baa2df7797b1589dc6ff2d5fde2d8ca7a33ea29055ca6cad9","0x7eeb3b6b01923d95bbe3ceccfde66bd2837a1dce0f00776218911ed3fb1c32dd","0xc08c0da9248a53b1618e17ee421ed1a993fcb749f958f1d903cc202fae63be6a","0x01964bbc69991b031ea3fa4b72fd6fc18c70c0c089be277355bd6ce32c9a9e22","0x0e0b87c952fcc7e20b2523acb75faa5bdae5b20487b68f7eb338ee10c13abd19","0x8b1c13ab9e948ff7d13d26ab07f1b713148f4137d789606af6482cabd59face9","0x22d3242d5db9704f4ed85a5be4975f528a1d431970ddd472187d5657874508d8","0x7a1fb580118330b353b74b2dfbbbe7ac6c0134a21bf7670c743cbe1a367c0b19","0xe1514e856a9e93d413c1e69c521903548b422b7e218a8570225de8717497a81a",null,"0x474e59a5c5b8c04cc7faf0446b318705433b767e73e3a2cdc9dccb77cbc0afb7","0x72b4bd1c6f9bad26fe676a7fd1990847a290c24b1a7d52685799d79643d128f1",null,"0xffd9cfe1da7af617f83da875074f1e02e13bd93fcd9fd821899907b8c247a192","0x771daf4af4099f922564e09765dcfb7dd1bc2108c7c6d3126a4acde4befbb3f7","0x6709e236dae287c5db549a3d748ee7f40713ebcc7b4f252a27aaa284330f1e4f","0x38931440beadfe8e3704c6ef13cdf943866d2a24b12b0667159962a76f19e30a","0x6ddcacb41cae49fc10c5cf65e30b705fb1bacd262ccbb6dd224bf813b9c58965","0xb8131f3c14f937bbb891821c58f56cacefbc4ae4d90473ad4d2ccdab70d62b47","0x5967874ab04dd0ea22dce40d1bc0ac061f5c1f209ef166efa46868bad959ec5d","0xfefafa3ce5970621b87ae8a0d9263c94ffbd6e763eb2c7104ea1fea62587c7e7","0x497c19000cf5d0cd6da7a65865113d887e27a8ec9438186b9c147ba7d2a12f8a","0x0e65dd7fc53e1f857c5b4a962efaabe8b684b22176887f3ab2670aa5cf35371b","0xaef1655b3866c2ea6fd34be151606ba7e147a4b639b650e993e8fc19d5c34679","0x0c21366ab54f81b3d3c1df180937105893d8f48c61afd403c0eb6305880be0e8","0x7e042164dd38bc49f0d6b935f6f0cb5611921e7c13280bb12e106a9542cb5a52","0xfda8c5db3f4bd2eef563c02aa3173430d69463fc7c77798358897e1f95bba406","0x88925f251322fd3506bec69e7669018b1100a46436bbea922905f9e0aa3d91b5","0xcf530fbf7f2ea5738ec9260a60d008203d63fbecfcc2cfbe289b9a18732dc5ec","0x8539fb098d723ae10494efb18d1ad9a4a0e440481da19f39ba5d41e257597e0e","0x6c3c0608a8ded6f81d76c9fe7ffe123db06fc1f35de3719861e52b25f9281a34","0x943fd88d631873ebcc124c41fda8fa506189c99e0873178361421f13ebf1d499","0x88c4f4bca1a0e76d8b33976851cc8160f68709e71adc94cf7dd4ac1c52bb4e7d","0x016ab87e15513d70284463ddcb5db944a7f19d7abe173d53c8cc204ca48654e8","0x977b498e71878a10cd8c49de5c150b000d8be4f94ee0ad73854b4febc1d6cc94","0x021957efde5d8af9dfc3b434a4b993d67086507352371914fa7444d8342b1453","0x4bf40149bfa3ae7b5e43b089f1d6adb265151994c96d02d349f221da897ac442","0xd0c93532c761f80a32ed821eb6ddab521749999907f9a54a45cae295c1495088","0xdbf32967edf5ecdc8aaa7efb4c507e8590cc6053bf3ec658228fca5c24bff034","0x72bfd1b785cc9d377cf5215fc9db8870e8000d3c0040062298f7b38add669148","0xd834080a85f66ba69e294593c5d840f78af189147dae5b46a239b7d2810fdced","0xa74a6d8145f7b4308bd0cc42198dc32ff339214888a16da11cf229a97edf63ce","0xefa459ab7f825716d71e042e34ad3dae2b0c172b0ce2858524ec2f3db92629e7","0x4d30557703781d402ff9e458fb402d2e14c633fc3a3feb0ea2e648a77e27d6c3","0xdaf5ccd36f366b3e78f866a2fc3387a742ab4ab24184104f41297e34878b06dc","0x8c52ed7f4f89c4761592611238cb571c6ff4603bd2a173f60255b30ad49bf0c9","0xbfdc8e2b4bc14d2d3668392c0db464c3d11e77f601c95705e5be4428db0fcaa8","0x5429015b4a0af1e7b8a4855b395b47af68316730489bee2611c5b5aaddef4f74","0x8ad8a497de132f064070b6ac124aa6eec1c5bf0bc7b6fabd0b7705a5dcd96b92","0xae048bbc9ddb0e2c3ff2f1808389a915d486729082f9a6aa020698bdaa2c3f4b","0xc0aa41b74c23ecd2bca3abe0849f08374760b00999967a21c8457540fd6b3e0a","0x49aa5acc8c53480d0455d88664adb0a8756a5004c3e4efe2ad9cd439c9d49664","0x6f55adaed78cbc6e9d65206201bbf282e553f9bee998ebc6cfc768c5ab58b58f","0xda48f37fef66d97dbf522c8fd58957e025e67d067b68240fe6394e59cb9ceb0b","0x256ba4d812a5de16b632cb2b7535bf995adcdd9aaacd7b7b8060d56eeffb809f","0x8a22c29cc3e8c6b0b552036fcb2956dd4e744eebfaaf3a3fae8abb954747e542","0xcf18f7e7be61b55a12d4de1b92dc55f3519abe05682b8452a17c7ee47cebca89","0x90ec2554fb3739584255009e16767433848586b72aca2262cb4ebb1bc02c7ff3","0x40a74e438da839f9f7dd9c95eccb1f3fe7e4d5024f0665c533a23c348a5e9aa7","0x8efe12b8ff55f7cff4a6840d469c09ac5ed52e3ced2ce48f437b58e6b4e33bd3","0x57a4459a3b040764f781f2d886f8c46bfa3dac774bcea00c223ba9e5e202c665","0xbb3e1905a7b54b0535875457a4ddc0e1a483c2936d30bdc3eb9d8ac4527f50d5","0xa93e8d99107317984bbd40004b1e4f6778e54be2ba7b19ba8e7b882358d60f4c",null,"0xc2e42649041c9d7ee76bb9da6035ed307da84f445a8ea77de6e018e7adafb9c5","0xd22987fa476a04fce4de726478f1bbc454f7d4de82eab0247bc20bfcc6490c55","0x49a9ac49cd60beb0b5d9c58637581b22476301e64b58dd2e74e042928114de64",null,"0x11909a0e386cd3a7034fa577ff67b8add57c990005b2779660c9f32ed9d4957f","0xfcc33a27059bfc39154b7fe8575d85d1dda7e47b47b7c52b8ee17e64af178a3f","0xd3efc997dfc0cb7819aaa4c6f055beca14c818643bcc85d8993998cd47b21e75","0xe83202d73675e418d10f97a68ef58c277b88be409dad9a948d37bdca0d001874","0x1f16df15b16704f45910e81b61d2e611039927981607663108e802ea684e60cf","0x4c0931ec9da4d260f78f1d278fb25d0510c137c37b0e07ff9a912c6e3dd1e231","0x7159f5f015cde1e6e566b9b736593537aadc07e8537eda8144d677bc04ed8bf6","0xa5bcbe6f1b84a4f95687053ce8afb89db66816ec5dd62d4c308c16f807b0d0cb","0x741af8418ef8cfe3d9c9b1c26925bc69a32746fd9aea147281f1a274fc820bb0","0x77c126ca9a5ba21972967480b0973420487cfe74fdb4c02447be7f1a94449880","0x044214ce8c0cada80ab5a6152b000a0ec85de3cf551cf482ead6063db8700bbd","0xafe7d8ff88eca91d9974de7130a5770ac0b149233e1f9f13f935c1728c496b59","0x8d55a87d1ce61dab1631539424ea625915f0ae67073cc0b7cfb6712bf5617cb2","0x3084228ba3803d1111bf7dd15010d80d149c0bc402480c6775d13643773e48db","0xfd252aa59f4d6d4c06f3e740638fe4daad976b25e6632060c100069adc922b70","0xf7da43de308b6396f2798a8d7da0ee81867e8407f2e0ca73166a6360c12ffbfd","0x3d92e397a5415413c4286f2a9d6bb0d92ef39f64b82f2dd15187574450914423","0x08ab56e18a7c194c30d88a48ddf2ea8e956a47c00ac4c703bf335adf3aa6f014","0x7f1066e95b1b3be9c4828ecb3430cff48850f5c9507a22023aeed6a3f3c377f1","0x986c5234b64859ed4585a188bc2b9bccc7a3076b017863e67989948547336553","0xc7e206ac2b9ee78b95dc7b79abae23513bb78601df933a690eaa8158987fd4f2","0x0f877f13a6924208f758a12e97e252862e88532d31d23f359d1ddcb3268a79d1","0x02d3ae088d5d805317d7ca184ea215a154623ea4834638d147a232b3a9e9c3eb","0xe4633a4391fc67a1b90c656284ef848b0bcc8736437bc2cb9c3fe5f768d5a794","0x1916e79e38738c79bd2a8e52784a924d7682f6f6338af87311cf209c82343169","0xa2f62128d15217c50a75b96ac6929db4ae22a9d2afb4f730d8b0b8f1521a0048","0x56f47f508ca44fe4b1dddc08f5673fb7506cd095b3169ed3ddf27e6eb64ccacc","0x9b72905764f4a5cab981e8eba67636fed0012f57b7dd68ad4e1855730e79eea5","0xdf1cffcce8a97e5e3e90c61ea1757ef3abf26143e070f35c5bd8ec9fdac3e2ed","0x198162f89e3ab60b8fe3baac7065bbb36cf585a62009579908df7985a1e36b1c","0x0012b2f4ecdf37d95486cbf37fb95442b1380a86a83d9cbe90c7e02f99bf9ad7","0xf8f526cd5c9350879605b3d1cbdef333fa826c1d2c0d709f934f112eb9faa48b","0x2f22767efffa0e277d81c4d39b49ec6b58306820474a5069c88696149060f406","0x5bc08a4b3bebd85328040e0c598ae027f0b9ff5e2c401c3671af5bbf4943b71a","0x6d88370c25f125987dc13252191ff7cea0926b2a1cb90b46d71d75c78643f638","0x277a3e1d786ff2c1629bec54c3ce325a653352899d7764616582d8b56eb04fb9","0x99c50d6e104d87e78f39b212d71d630b0495e9adc7acd0b1be4916e42f98f807","0xecea40670259b5a11c5f38982afbe4ea5663a2fbf2dc27acd5c077149fb20aab","0x119875b9040cab0d55d0e45bf656694d18339d8972bea28b80e7fea0c8a9bb0e","0xb2b1d4d2adbd3bd00852a836675069eb69ee54ab613f0094c367339cd918aad1","0xd47b50889930011aef80e2f0c3e1d8094570d31cbfa09a729b1c88fe326826bb","0x0c109494c446a22f217a19fbbe49beb095ee6ffb7b2d9e205aa900765e02e4a2","0x2926d34338c342cb3e38bda70cb33cf5223a70583945985582d61dcd217921d0","0xb043ad551a78a1c770447c1f1545a90623d3b6c870d76e67b52fabec069094b9","0xa276ca11d1c249301bf24dcf575199b7f6da5667eca7e503886e5a07e82adb3a","0x6e1e2585f76d12cd3d25d249e8b10acd76fcff3479e796b96a75c4c1cbcc1413","0xaea7d9cc34d77f97f456d87338eb172d79cb5f3b630a804bc0b3274a86461610","0x3e16e36ea95d0327ea54adbdd7688bee53909d076822edf40a5ab23c706ae6fa","0x4dbdb928f584ff1a7a7c2dcb8976c6c9892c5f5dcd4d026a5810d778751e21c4","0xb1e67f71a14a37d7d082a268171608f1d710563afd971f50e21db79493c71c16","0x7717e3c1cbc813e00fc042d5454996b3a85c43136ee187cb63b45e565060e23f","0xb673199118f2fde7a11991b7d01b9b3e8d2bf8b2c0adc76c5a7f000a3e13023c","0x8be038d32403894ca48311e22e16032976f03649429a38c8a4dbd30bb27627fd","0x8e23794d9dfb8a9c0deedadb7eb32c98f7b421de56190fa1c481098d07409587","0x09a03472292fc7024e929e990a81e3f20c56b7a636728eeebe7c117126b64a68","0x87953f5297b411415dc1fba616de978577a3936011b9f2c800e280bdb962b976","0x102962e469f82c48c6e35956a517790476a8fc3f3f78aeef5b270de236c2f973","0xf98e6b09a21178ab2be29d73fa0677fbfad9f827ca90248f2a2a2e89eaac839f","0x8781e46ce41b0a5092ced4814569e11aa01b12920768db489c7b64b3bfe55b8c","0x08f27efc239f14ac20ef09d57a54f592a95bda9d31da8af8bab61b32a60e5d7d","0xa87a41227f90499da781dc6d892158da7d81eaa71c089aeb82cd69676b445635","0x8f4a9521588126bdd52657753e7e9baf70520ed130ac2a4da3d65874028bebfa","0x820e6c179b71937d93d3b6b3b93b95f519f0066768676c4e4bfb2eda063d4785","0x6402974194da5c83adda46d6d7038bc7898815dff5e704452f23cbf82c35b074","0xe2c4b92c5a317fe305c34300fc81061136bb0db276192d1e31dd88eebec35c23","0x30c21081bc59bd3602762056f6d031326ec8eaf5d5837861a4fb64252e58365b","0x70d3508f27d2a0efb7fef01eea40906107bda6c3039a7419ccd1668c4271a535","0xc7ac3cda2a064b7af84c2850e94513b3957c6e7098573ae4e7e73869df69fea4","0x2432022f1e2d78dc54addc836f8dace1c0201bb796d535a962218539e630a2aa","0xc5fce5be621171f516554789c0cb6a99d969611d7d139092e0a53df77e46617b","0x092714b27c35f722a6f0538609053c2c7936f0b4fd5f8bdba0457a4750423660","0xa5c33003bab34aed08e2e345eb114a5c7900e41450a4a2d00920acab487d314d","0x639d0a473d87e5c1c592a3cd5693a1838d415cb733e9c0d593859012f6206588","0x106a8898a50080a83a3a8aea97317be214cb36683e2e6afbc2524f2a13c7ca94","0x400bbe96ba459631a694439aabf4080e7aa5a939a5a6e330bb1c85264fdc21c5","0xb13aa7c20f218849c4469b2bd6704750fdd8807db0e23d0ae9502ab3e7b0f295","0x1543cee509f6b15f9ccc5e2ec995051627e0af5524c5bcc72becd934db448398","0x0e84ad7cb391f23326fe808976b5070a16eeacaa3b640b272642227a7046da3c","0xfd593f7b0930954dc22f018afddc81a37e4eaffb061a38db0d3359342a9d2b54","0xecbe9e8cd294dc8fcee3e23dff5cd053431026625b8d00b4dbb2d81d4fa3cec7","0xf55acef3730a062b250673d2c4a09b528dafc8e15fc23a5d8396412d31dc20e1","0x32b3de61307b71b54301143075fa0193004a83efacb06cf29634ca8ffc4e437e","0xcf5e4015adeaeb65434c00d8e45d18850a8136f84478b621977b96c7d76cee96","0x2f8f0b930f67fcd8255aaabe2c51cd5d9c6d6cd7703920099163fdc1ca5d0e55","0xc95c6ebb18df23ec963bf792884084375b13e679d91f04d1cd5c031a360db78d","0x6c2e44f1d05769d5d079e5398c27a3e67b9c170da291a0637c5a4dd2c1bfefac","0x57935ecb138b0c1f9fc897e469b87ef578813b21410f9fefb394a751e2788942","0x81f94dd69361817a99c13fb077ab24c11c1927ade76efd54029925c5ca5f8216","0xeb388244021687cb2ae146a6bfd678dd44588f1261558a5c20926bf7897e9437","0x0a32591ae255b01f06f826c0bc0a6506821a26a367e94bb4c0e49c27b359f1c6","0xeb645dc3f34c0a516877709d0ce68a00339c2c58ebe0a4289bc8909a56689d2d","0x6b25453d0a296a2630f478f5b841f43f4c2b9939a65b3940874d886874aaa0cc","0x54b0acc6cd6f1645623f1327ce3ec5acdb14ba42779f198ce8e1e34d52cfed9c","0xc387b36a94c2501641e9f4313be05d92853ba09865114c681bd19d240fe508e4","0x81b2e416d93d5c1776ee7dee2412d72e78be92917dd0ff948750050c03978aea","0x84e31e565d3a28c8358778beea0e57770db81bae072f9ce2322d020f7acc1460","0x8b74e7e9fef12948c0b5b908979ee52f0e044dabbabd620afa320ec4cda5f89f","0x02be5c770d7c135a526485934ccf76d69627738bc29cb2b2e5a3d8bbcce6a5c5","0xd24ceb80b6f6b3aec4dc1165319240fa5631388da73aa552e494c5af1ea7f1b6","0x51e99ff5cdb359aa15f6e2988e3d6a41a17d5f460aac798c3c84adeb9d918437","0x779faf349d174f6800f1e8f7fbe4ded1e0f7a5d5367aa020f524028bd51c40d5","0xd9d9c74a49bcc38b848da1031b8c78a6e3a22d7fa8aa9a5f25aa306cc45cad57","0x578f0e56c43dca483cac915a43a00f24f66db0ace0a01f5188de32bcb13aa7b5","0xd362123bb1c8404551455485616377b5a1847bacd84ce11237a7c5c3618dfebc","0x7a3e6a0fea2a4ced14164e74c0eb1c642b59f0c1293de0da5ce8ba931c2bfb9d","0x5d63a9ab1f7f93587440f9c6c3448579c930779b95a94d5e8eec2a12a9953daf","0x8477bccce9b2878c1b8208bd45024665a3934b90c773cab9304432050e07490f","0x83ac7a9048e9f4895fcbe36e475fa1446c444a222958da2f9f515005cc6afc4a","0xf48f8eb4cb153a0f8d6ac20c4c4ec1b0fc948252a06df3ec9fe4df2ef3b76d9a","0xa152619ad5cdbcd2ea3738b373741b375f0504ca92784f3158b43670149af79c","0x219b846c1a4319bd0d000e7e2c6b1accd4e0adae1429c2767dc9c07b7c1f46d9","0xdb14bbac216f95e38f225f0c8044ea36293612cc0a5759c255200eed46f5061b","0xfc2d8d4331fdf72e6d1aadcb506692553cf5c45a1a55190cf6e084053808bfe6","0xd1d0347aa34d6a05173515dcfcc7376af947fe0c23459a96f39991089b4df462","0x88e5b34f4e3829700c7ab8f806385f09ec9c0bdd327bd70f7ce9b62800bcf0fe","0x2ab60dba70f289538e522592fe504a46d11d0a458b2c92bc19401070d0bf0717","0x8ca68a021c15b5c6ea944d53909338a83e293a854b6a18b22ab99a74052d9b01","0x385075638e58b55afc2117daf51b500aa5d71c46da78d6c33d7ed6d5c817fb17","0x3c8ace89188b7f5423cfc434c6ee3336e325cdfeb6c6117f5180fc3be0858091","0xaf2371fdcc3ec6b7337f88afc3c0b130bfcfbdcf02e2c48fdfc2e04530f36a75","0x84b79a115d35fd7cd28026ea26757eb4f6841decdf31c3a9263c6f3e984cbe49","0x2ab9db0df624b1cde97c36866f8eb9fdd37fb9c0e072678d82334a67c146d11b","0x69993f832331eb6f5b05930c79fa700a8fc55bb6e06cd91705fd6d245ef08ef4","0x8ced49f1814602e2ae6b91f519e97950354ddec52ae654a9e536930f3949f14d","0x21d78e83fa85e698dbf8207fe6ddab4a67fab0232c4fb7faf8f274ff37fb6e8b","0x6f6f5381924c10b6b4c8e9fe9f39cff1c70faa7332d4b360485f584f0fad503b","0x398a056409bdf43faf32b4d58663d64c6e8b6383e55f5776f476ea5591b365dd","0x1f7c3b494fab52f6124ba88d67cacc991f46db6c3879962588b74231ef91c8ac","0x7379558c79e5331a3a3e1e7e9e5446313146e2f8eccf16ce1913c3073c95b0ab","0xbb9369bbb3cfc7407abbb3bcda2a3c520513340409ed6060fcc622ac4b16c571","0x47f803b2e04634a6085492a70f74593d05da07503d69cae8b8ad9da9ad4d90ee","0x4b70a5603b46e5d3aa58b5abdfbb35b8b7deb96dfd30257d6486b0d26ab9f3b8","0x35ecf80cdaa68940df70b9d19c941cff334fafa50b7520f59e4f74428a5963b0","0x145b1da471f5f3548184dfdd999c9a4c7d462a3a07d932a16aed7516bc2dad95","0xe7229a9c550ed71aacfbccdcb3bb23b7f1c8535c27797c750df4f4834263ddc2","0x9980b741f4163fe1b214d0ca5fd4c2fdffb07e9453afbefb83fdff6e37b327ae","0xe5bf1e41a7fe87d3a3380ca09c90e30968bebaccb240bf71382d7356be7f6e70","0xddf8bc1e9da6c9f089d66f9236ba047e64cfcae142cf6fa7d3dbb5998f2119f8","0x07b9b0cf8a5662e86d76eafc5eebfcc2a3e1181391111020eb4379204ea4a18d","0x5aa754d2f04817b2fbf5d3991607ad52499bac4c01fa339f540160bea44db110","0x5ef595d5c10a874c8282c9842b6795af4e13e35699ae3cc1dce9544eb46f4d31","0xa8603130bcb184f08dab93ba2788dfd01c30d2bdf40d743ecf697d330d8efcda","0x331c09e4c46c1a5e0a4b00f0dd4e6032534ed955e514f757dda437a874fb6cc6","0x8e572e6224a1b2ecbc9f551bf4a4c7df60d40b634b78cc7a5cdfa11f8131a43d","0x7d1c3d6369c4af9d2d0d0a4353daa305a4298998bb7b8c0423c59287b787c091","0x9d60895cb6a68836ddc72f6706bdf728c2065880af130824578fd89a5df16a2b","0x7432918a3ef097adb4c8423c3b946d7da82c4fd4beea232ae520d5cbe26104b8","0x8fbc230534e835beccf62289484d98cc2d23db4a1f5bbabee8d7dc9ffb639c16","0x909852635f0670197a07a439af530eea22647565ef70b4ea0b9e79cea52e0f5f","0xd21bcb7df4118167f571df4a313d781da7697f321fe617f16ef315d841dccbfd","0x13538dc0345aff003256ea2cee96d9c6704deb369c733cdebad469224eaf7fcb","0x3a406db9092f67fec0bac7b14774ba1c6fcb9a482d3b79603f5fb71d78ca4669","0xecc70a9e7180a6b4dcc2bb9fd52cf6a44417df20ed60d7a9c29cceb715921398","0x6389f3d5cb8aee2775dab706404727b3aa2f8412532246ff286a0feea906dad9","0x34039e8dd4f36ee4f7db297291e9348bb76ff117c751a9fb2de1891f01a71a04","0x2540386d72438b4607bce204cc77b9c58194c5f3ee1245a4c4a1232c7642a068","0xb64e2f54c1c9317c6b4d052be4695ce84eea6fdfd46c0c14370a8c5039356f9f","0x0f85c546b0c82621ea9bdd1992ef0f1f188d0d3ccc0403fcc9d5e6d92acaf5da","0x956d40a6e06af05fd9391e0dba48c2f2fe38d66617b1e25a074abf5f2b81944c","0x77909b653a9b732dba6c5554ba3278a234581fe3de5e482e1fb2863737ad77ed","0x07a625658554a487c78095f9f6cfbf8d3434c12f2c6e52f426976aaa5abba018","0x5a4054dd9fa2dfb9fba3c5c91161d39524a213427cbac2a3eeb479154013a385","0xc66c238c6645cf09000b459958fdc0a6bfdcfa892339da6e6730dc67807e57a2","0xe96f0c0b9cf9fda13f17aa09395502e68a0ef68119f622c4470f1dc04f8ebe5f","0xc17b8c15c3fce3784c6050f6df31c59ac49ce5d41347bea6261a7c38d863f15a","0x4cd5de1dc253042da7d66a96174db5e309fcd89f82953379c75055cdef906d90","0xe922970e14660a3f03f59ba92c776f6cd1d3e0bd576c466d8685d0cb940f4021","0x1c590670b60ce83da23d34aa2ee935bffc9ba18cd345640a1d3efbb178f52e14","0xa4a7e9edfb5f61df160cb16a5a00bd8af2967ee72a1114d141ee456bd039889d","0xd3ac5dfb11d9805203581963a67a6b2e96a3a8bbf8e75fa0722eedc010854319","0x24bb6a5d53e769481e3d613d0538f785b955835f4d3abfed2a411d4ab8086f46","0x603ad22b75f0a59bae623e67756b39c9d6c3e4ec6af50fa400b127113d06fcc5","0x37591b105f0df9d3b5320722a3d69df092b9808a7709e946bb03584dea24ddfa","0x4c9b205e656471404554be277135e1e85b1933d43119382db68d6efd37d2ae42","0x29eecb03e9345e1e7ac37c242a65afc8cfedda2aaaec0a11c686f454cd54684c","0xf62d1ab941f4d3be02ca89b348c69547c1ad5c010f1a6399ce843e337acee310",null,"0xbe1e5ab040f9ee2721202aa6ea84139e156ffa0ea0d4e813bfb824a726fc4a7e","0x414ba751854f75b39cd9f23471a2e2ce898e041678bd7f4cd202a69fce42c98f","0x7234948f2f819dd7d9965dc2e3404f6429338e366ee72c0184c47471ba96a5cc","0x911dfd0edf57cdd72e2edec5b25c58db00918a1e7df41cfab1d058b5b8af364e","0x6dd41722bb58804f60684ab3a43ae5acd28d0f780a0023b13c8bf67179e21bb3","0xbfbdb9155c645636824023af9c69f5c5f01fcb5375c91116031a7111c01551b1","0xeb2ad0d182dfc72c4093a9238ded71101bc00c57d8c665e00d26940f33882208","0xd7218439b10dc76b92fd75d6b03f50f4dcbfe9796a58bc2c131caeb6699d44e9","0xc04c1198a96da53b1b3d050f4277825801d27198cdc3a67cad3a360204eb78f6","0x3ed9de8080649c3d7588c7b4d83ea3e3ee08fdc334e8b2e0b252c0ca18f5b1b3","0x7fec943e2205ce0f510b0f63ad618d3ddf23bb17642486f9638255bab5baa99c","0x565eea027e1d2b2d74a3b760e2056bee1f5191b8e4551645cc913a97f4a6a892","0x446c2d4ee027204848479c46b0053b82fe84142fa9fe256edeb5ac710a143ffb","0x03181b30d66d60889bd2326083162fdac0077924aaa6a788ee43fed6efbe3d4b","0xb4c1e714509fca00c9ae17308057da5875819a6b4ff43683e637eac7a66ac43e","0xaf6cf75266f9be45deb2fcc43fb31dc44572b9fcd20856b74b8e208032b73f4c","0xdf623682de9570dbe8c078916b95a132e211a496bd20f68e0a32f71e1ec64b9b","0x667953d0c2f8c93354f6df823d5a9f4ad9ef939753ecf769f998b0a4cee06cc2","0x628979bc6a23d614c154aa0988185bf90f6fdfd1ad2ce4434cf5d1f0e18d9c4d","0xaabe26a5f1977751a30508f314bf8335738ed5bcff578cc2710939d473699b58","0x87205940639d0238d995b52e689d2f45754dfc625ef0470db94c8b8926e7fc85","0x097dd9659e2f25caab009052f52d00caa3380362a70aee10c6b513323b581f2d","0xc65a6d394b627ea66d7482671d730926cebe5047c80ef0bdb7099e38e9e0ca1e","0xf6f4d5aa00e49bd362f16dffb0acf23c80ebbd3ca54371be61d0a6f1de4c157e","0xb39663b0f8c3b9e866e130100d67183488fe3f4860e14fb0b7a42370b77ccdac","0xefde8f45c791f84b76867ca41bf9ff7bae292ad7190ececd6cb8740e9e20183f","0x88f75ff535dbc7c885bf73eb5cafd7a182cd5f403908c03de1cc374b7dab6f6d","0x03fd36ada049cdf544b8fbdd002827b1e6718d5996056978d3122af7d1a42996","0x6b5a9e06ec2f752955de4c1d1ce2a3829bfb731193387ee27a7508e004c5ada7","0xfa9bb533dd70ee1c3eef519bf39ee5bd9b64949381b01334f5110b0b9bc118ed","0xdf3d44d84feaeada6989516071971eeead21c937561cba1ce6fe4b9a62842ade","0xc3a7e2c67a9737c7adc99d5b99419ac5b5322764658e91dae205e89aff1be073","0xfd2427877e3a06ddaa5afc4aba33f9b59dfbcc63cd26a36de9d4789d6e0d9424","0x03016d30184550ec8b0907598be3a6a300393a2e060c9b7da5c7e27e04b01bf3","0x8d1ace72c7aa55d0770f90fc09b3954c6728600eacc0f49bcb465369a6ece118","0xb4d7cbab8411b92ec6e730e8c9d390ccc3454593a42fbca132dd1ea905cbc902","0x28150c4efe743dc8252be156d7142d806532fc73d0907ba9869e6a82cd213922","0x926db2660a9c0190509a403ea0f939ebccc2700a6ed278062350cff107e6f29e","0x9b844c56cbafdcdb23d1a37f2afa368400c2b0c4ebfd8249551c3100d8a4c5ad","0x80bda8593a26345282bbaf0ad69819e968165768ff51a180b94e1d3dce5c567d","0x3502634004f2d98fc14c063a2859ec795456fb53e2681809f99dc8d977bde5da","0x2be9a1c46964a953e9f086ad3cfa4c2dd80d9962677b98e89a34c83492d2fe97","0x1b8ab07c6ecfa80f954c69cb7fcceb66fbba74f4477b0247ecba2c27f9c072df","0x827391e27edcd3b2f0494ab3ba3543ac09de63d532d9a03c1f49274688900f05","0x472f7ec2af8ef93ad07a2c2d58ab9c9dc044aab9a379555a9d8a8ddfd77e8a8a","0x6e70fa8fc12117f5877cf5753632cb78b51c781a0da9f7930ea55cfd23b5ab94","0x59203931dcf4685c008e9dbb5374ab6866d360ca7c715036a5f1254580313354","0x21f983e4807a9eb409f65295cc07219454f7d3cdc197d3503ba991ffb876e92c","0xe351f5b98ee83d82e0c9715c0e7e97d04b528418dfcd9b7613dc2bc01bdf3f80","0x4d19bf2c828beb8420669a8738342f998860dd8a5516feeee58c1ccf43142d9f","0xcf645518c9ba3e381f827aabbf19be84640650575a3051f92ae0991f9273840e","0x42602cdc51408a4452f1166c3883791b5dcf4b6cb1ea13bbbdf9ea2050214d4f","0xa54fb92fe5a13124067cbe39804160308e23effcdeeb3a469cbeeb3fbc695496","0x639053a4703510cbb3282cebd822180679478845d516b0a4fe0103b98e77d49e","0xad0a248e009a3a371568911a3a6c67963ae533e092316bae27ae901e5c26bff7","0xff4452806107fc768a74dbc9a09b1961e9e5baf3c6fb61e7d81aab190cc58c92","0x3493d439d5a0ba00b64e69be6d391388b386e02f5c2e40267c37d066ba7867ad","0x218f37cf36aa8300be4f01b761f6d9cc34cca9b18268a369f3394d5d7f5e7428","0x72d64ebcecd31225e6ad7468840431f8e851327d19c59cd0a795e0cb084ef653","0x9783121862e99c8bb7c8b36b3f1da791bc73b0f5021038ccffe6ae823bcaf2d6","0x2326364030e4c4c8a292ce5350870986dff2341cbb47c0cf306ea6f200f6d4e4","0x01676cc9fbe015a8960971640a6a895433f610beb5faa43445fc78cd20c7a436","0x59e8ba83d4db4d2a0cee2a153b7c680fb1b7930c901c744be6a3738a08de0ba5","0xadff449cafa75885da9b2205998885068af0f9100082129a81874db28af9c193","0x43a5ee52b490e0e0a694e7b249eeab45b5e22010b47f590304458170e84f4ed5","0x62f9625af86b6af21dcd3bb1138a036ce313b6b9885f39d711e3eaf7659535eb","0xd5bec35ff5050fe1908920eeed2dd6d1dd27e0120bd6581e2624bf48959b3723","0x985fbc2ae11f530458bf41fbc1b9d1bf7540e78adacc6fd8e29bf9c3407c01b4","0xb56294b35db7f99c756b9f8a3addba3920aea96298303055a76ca0ad1711aca5","0x16d153c58ee76f3233f82e4a6ad9d54b8121a9467f39edba6f32c206b892de02","0xedd87c37a3ff5e3c67f4c470b465bf21fa97cfd71141d0692a26b28e1dd629b5","0x0c07ac57a07a9e2a4fcdd3b5f05651ffea18be744cc1b0bde151b10dd942bf59","0x371dc54a466b244dfde22ee15bba42e10e7aa468c430f4a3d21c6057b621a251","0x3efebee705217275aaddbd742d8efeb6e5eec7be9edc4f7ddbc97623ef136778","0x1b31d2cea219574422a918416d9e7de52b8110eec030918cddc773b459ff1787","0xde7940dd9936de25949be93ec72a3736f3e5de888922a065edb3e90d533b1920",null,"0x03bfe68819748cbd44d8173938610df7be50a9119555a65f981937c721dff99c","0x14d00f7a794affb6754298d22b1d48a9f36d290e10c8a50fbb70ce5c34aa6951","0xb8054c7f35a296e2915cd7596d4fc80d88bfe6a04fda0ba86f19de2a35438b1d","0x97abf5459b4ac14e312cbb7cb1a640231afe95498f74913bf7e16d251437f6d8","0xab1d9ef4685befdc424531194ad4550caee778726fc6492a9809a4899ffb8f1f",null,"0x6b85b771e867bb73b74e57cf34297598429250f73bb5d6f1de10eb4ca87f7c69","0xfe08254553c0db15f70603c27e584f85e9c1fbdc71816d5ff74485f38dad8a7b","0x354f6aee856f9292c2596446b2808fc7d1f90c99c0152fe5fd5d65b0d1c1b79d","0xce1ef08cf159a11496c33b4b907934e6c04185ed0c6ad25faa77b6d07de399ce","0xc83a4955e74d11f93e1061c34632737c7a164d274a35dcf2dfe7b01abae17e90","0xfca0eb619367ffd2fb5f95f1ec054487982f01c1f60c7916aefaa62d7bf496f5","0x250a4ffb9eb2098607bbaf88335619ebc5b0932f8e698ddfc8dd1a7625ebccf8","0x1d39019e9afea87fcb64e9c13bee6d752044433767ea8a0ee6ee250878e83790","0x46c4253bfd3214ef012f754d0170ee9fe08f4c7cd12be98384ba20aa534a0b24","0x835ac93be4cd6b7011026a0164366a90df12bca79ee837e0f6a58eec7ea26b3d","0x6cc68e67b18f36b2265ff96dbb020e4b5b461ef88e580e9d5ee53eb318477e55","0xf50b661f422fcf482b61d06aa6c28221a8dd43af3d7037b6169000241db28dce","0xa2240d60dd31deec46496683b3524b62b322ad5dc6c649ac6f003410f231a0e3","0xa8baebd8f1e579919c9931c3e3eb2113a40797ce4f8f75f04e71a2abfbfa0887","0x6be8c919562ef75555ad1f097edce7d80a5b3e8ea0f7946d85ee57fa3c782900","0xfae82097054f5d1f275436f01c046bf5113fb72d71a59ec4e544d7894daa3c58","0xe21bb792fb6bc5a69da614084b2be8d3a65f3c1c0e18ab8a1d840f4796a5313d","0x4eff7edf2dec63142a63cc92b7fe0dce2243eac7d7f67581751d87f21ae8fbdf","0x3836875c6743f70d7329916902e8aea8ed73136dd9a1a91ea7d0a0a48620d648","0x27d2e0844c1fbb3c664783c47a051b5d95583f096efafe064db5ccb0063aca99","0xe8465f7235140677acb0f47e707b7ea9ac64804e4b1bef1f90a01cf72e392854","0x5f4ccf121ea24c333c25aaae80936790fd9992c7aac948cff0a10b74b15ec133","0x6cb01bba558dd89f1076642a0c6ca37ae2a7eda078c2d638e2040427e4062fd1","0x67205aa576549aaaddd7f156efed15fc6c8240d7b01b0f28ef69ab2895aa20eb","0x61bb8f7381586d6b2ae0bcf46d707cd0b92c57e68ebb4fc2488dfa780a8e2c66",null,"0xd159c22b1bb0d67f8649dd9b184e47c6771cfc6fa4a89b4bb0f498463f41f185","0x5313cec32a9e552bf79cdd747264f989dcb5e3bc6d13a709d847ebd4853dd733","0x7f3705cc025cc3559118d66df65a815eb422d425556b3eb2c30a9c6ba6eb568a","0x1c16f4d08b487d3b8b903f23cc340b738d2d4b03f226118c9ef637c6a8e1f668","0x48084bb093b66b7ff1de22c52fdcf2e77f87b6d141b5abb4489bced9a9ced002","0xd43bb84b5c891195591f9b7e2d7a2e8754d8ed1ce562c22cd8786847ae044f2d","0x5283cff9a6c2e3eb3e972eb0b6772536224ee3e90f630be673b275a37606a89b","0x2d25cda19d1642639ce32e96d67daf2729f73d60cb7c0fa3534853c0f6050dfa","0xa64f79b2e6d2be58358d3fda2d4f78d15e657f0eaf34c26509446424187a03e0","0xfe60375d7d6cebfbf6593da64663aed478dfaa0a919777c8b1f943fa66eb648d","0xac4fddf8f34c0c8b0faca7742c1e7788608b34d7a60c7540964a8032fe5eeedd","0x33166a9a1e9268a916250af7fc96750c392577c1ced1d2ac53e66bfd87c33eb4",null,"0x2c6f940debb1e29c3ef22f76ac7e414139a82465e25361d1796448e0f9924f60","0x422afcbfb1da325e33d268601ecc61fa378bdbf6a856c2f1f4e2d94519642b0c","0xc61c5ffc9121efa23a031b60169af11397b051d961d30823f369ecf1d23c3587","0x5b4fa68c31afb86121052f35c91458c92da4a8368acf6a42812beb1fb85882af","0xca07db9cb8142ac8f925bcef21b006befd167ef6f77e5d0f45df9412c88f63f7","0xbf327bd93af84beb4afaa69a5bb492ad6c65c1a43baa8e50be8d611412ce7302","0x900e5609c07287a341e4d018e91edc5417f8d633e235002109e772647cc117be","0x494c329efc112c7893f32fc9ebbba8c51a6d8930c276fee0ec17001310d2494a","0xa845b8c74322a27ca6c4def53300be2029abe550ee9a5097f9085081bb7dd0b7","0x4bbfd12953a15aa51ea51d412e19a2d41f8ab176b0b15e7bc1bbdf5d6985de7a","0x99e5c4763451b21757f678ec4fc1900fbc5396ba12727c99dbcf2a0e9322dcb5","0xae18e25d5b6c27ffdb3fb5844389543e66f011378b62846ce036ab78dd1b29a0","0x2ed6b52f5664209dbf5a6ecebd313a071f398c0fbc2615fe2fd6531ccf93fadc","0x34364eed2639c59b14c4e816b46b48eca06b721cb25f01b514c4480ebf86f007",null,"0x413db3920fa57bc1cbe6bb4da960d29259a08dc2beef7eecff32996303221b5f","0x01cbd7174e8ad1e911c7c4e596cb543ca37bc838599daae1efb94f98e11e40d8","0x84c83d63120e6fcd77a850f435153e54bdd9713cb331eb7994168819f242d9da","0x3afea25396a3e6f35e438201a48464c5cc01b13fa1c9ca5c032e11ec7c0b07f4","0xf4f2b2939a306fd9cd7da18dc2594722c677780d4827921a67ca98e4dcfa881f","0x1e655181dbce7c0ec33d730a4c70bde7d2ec606847b133ede1326f8ddde8509f","0xa314d083db5e48f6f64a14e56980b5ef08e8e4864005324747f5be9ec5552db0","0xc5e8351826e8f6155a4d0c77b84aac2b5e4039f5e1b5713c36ca4aa84c07d456","0xc1a7bb380d1baef6680f6e9b2e3adf9acff73ac19f894c97d29e1bfb4e9459f2","0xc9ec72549f8d31d67cf6e0ea33fa826f2e0f2215408dc188478e3a289a3510ce","0xb03974e7a62432e107443438125fc2e5e01879c69a8ee028bb10599615049e3b","0x30d5115d90ec29583f31cfb09a92b92d893aa03fde06fdae3da7acc87459b295","0xb98d7e2527bf13dd316c3cf926c8d09ea590995251692bc61190e1afc1249e19","0xfd6fa47162575f3e4466ddc6d01fdeb2c8cbf46d2661e9b0d2d7bd8cbc3c2b25","0x4f29930fccc77dcc7f4a991421fb93611c82ee723aa3996a4ee37347c34d5533","0x241e81ca7ce6eff8dc80e09352ad4489ff9ac315caaa95d7260c9dcb7acb0c1a","0xfe75405729c94747a7858f3665ea52ed1c87f212c44c407312c0a8880f4e5622","0x3a542120f4bb0c57b1bdc3cb79ee651c488b1a660916996f426e1512549f4475","0xd7e4a72e4383b154d35a9ca7a34cea82a89654e6401b41ded25ff788ea1158e2",null,"0xde8ceed9c02d3535670b3bded8b47c37a39ec3a560b46daecd5237d37ee22a09","0x1d52d3a15e2f1a37b42f5955b8890d55d1d027c0885abbde97a5c222d30439ba","0x7ea5cc7e4b390a8252a7ea8dc7e54d58b10efd9622d4046662ea8b01323aa91b","0xa060563d5521d0a38baf6e74a1201e6076583fb7bae543379848ad4b89f82af5","0xf8d8ab9e4f6c4f46052b8a26dcf33c32615aaae0ff1ba4cbf73e19601df0a20d","0xc50c2b1339bc7e61757cc36165c56992c599af6412d4097220e66a2078174822","0x2ab15e20939512ac54c26cf6ddf86599e401cb5154ac4658ce78bb34dce61274","0x6dba169a794f2ca931fe77055905e820d0d9d5099f1bca836dbf34f24d9060ff","0x76124ff40304a8464511123402e3ea209a63d399685e86a299294f306304b02b","0x5b669c8170b044a5a7f53819ad63901f8762dbde4ded611a7925a707e8263096","0x04ca247aca19a75ce7862cd299a0fa1321dad5ddd7a8ec8167a8a33c86fbeb55","0xb78516fa91f482d115cedd3836b968d7332b93f8386508d939a6bd1d4aee3063","0xb1f686efb429b22efc1f22fa2a23a160c7d5a33c324ba02ff7a6d975ccc5479f","0xcb0861d6656e5669b5408401b56b31d6abf483b401f5c267d57b70229abb87f9","0x164e2118856e9d571a5fef7255ef17a2163136dd0bf311fa70b2e7f65cf8df26","0x57fabceaac8172efc34a2f5de3de2735c7ab0ae3a8ed8b98ed76a3742f653666","0x1d20c74f8841ed11ceec1c661e1f2cf29597c205ee7cd3b3b1772f23cb33b0d7","0x6230be17049db01747987d61e4178864ef0a4c015af2fd332075d717462a5a95","0x09ae49e3710cebcc4c1db006e8d51affe7404a074d777c0c015de3b131b4f3fa","0x0d15dabb63a109be75a6c094f994e1da1a526530be4beeeea50aa6977b29752d","0x745633b938c81cabc51e08a8814b99449f0a2828a071444e7cbf5bfa5cb3bacc","0xcb34fb67e8dfb0dc8ace05086a2418ff75638166f6d4386def2d040336424a5e","0x72679084ccc07f3187735e7a5985635243cd0eecdb677623395945f4b3fe6e6e","0x4456be4fea962a999129c979b7856baa42bd6e30b47b54c8b8e662a27a130c36","0x52cba683dfdbac88e20577aba07d4529fa030f4e59272fff633abd19e01f7feb","0x2fa2127a0dc3278b529524e57dc958611a19f98d16c0eb051344347b8598b90a",null,"0xb7bfa8f22e0a5944b8b6156a7ad8a925771208b990a8db2bda2258cb727d1a5a","0x26bdef95218113d5db8919364ef34dfd182838525fc6624ba431e35c735d7717","0xa1bae82eca9d92ce79830568c1af7b35955c97e915c466e31af142f568056a53","0xcda5678f66a5696f9a1e8347c35d6a0313d8af7ec4e1a97978956c970cd9d0af","0x8e978382a9f39f034dae4f909be12e25b7076271f31af850dfea9c36c07241de","0x3e9291ccf67e4425443629f5d24aa93162723f98762ace228616e2c098c1ea57","0xbdad472a30dcc8a475ecd242bbf6d23a632ce4cce706e3aab619a206be415218","0x3e1377070b7cda69bdd6c3e729958f9e0257ac1bfb72654f5a57f76165f236d3","0xeac0dbac71ca21f9744fe2f5147016b0e2d5d6e269d83ef09a02ff7f726e94d3","0xb150236da3b578165532d960eb4d7327d7d0a6a4c6c85a1d8f9d4b0ba2145bc7","0x651875674a922c7498bc31b847b363f47d4c28da339bfe0481fe27567d4556f7",null,"0x8dcc26a1b1a4660b72c114763ae3b32822e206f136f67b2ca40861c3a03ec6db","0xd3da05260f847161cf9bd98c0526d4c92e2fb69eaefbdd98fb5b562e5a6bf29a","0xd2a48e47ef5beb7b607cadba52d799d21945198e490bf26c268b9b89726afa79","0xff57b39233ea9ce839de000ba40f9591b3b61af8cb107e1d3a7cd59ad9775ad8","0xf4f7226bc78a502128a530c63b4c9adeb92444a8351ed79422adb1ad2446a840",null,"0x1c9c237f275b2fc6f7bfd813a0e077959cf01461fa0470c3e30a9ee9978b6bd3","0x6fbeee5ee6a86af4569a0be7fd69f989479aa6afdd1d38a44a1500c317c28e45","0x280c82e767e50f0e4665bfbd776afed93aedc27901e8ec38fede61d8e0e67f87",null,"0x0766f7dc8c77d78dfd462aad56430a9990f6b111d1ca8fa9b1b6a0bba6dad53c","0x9cdd91d1bdf9773642fa30be6c71a61ffb94070c5d98748aafdf102726a73893","0x08fa58e84c8ead64a5ebe3ae4fea13277378ef4c07eae5ad0b3e416ce76eeb97","0x34a2bfd05bfa44114226a4027c75bf0da12255a6b6a559e9a28ae9aa374f02cd","0x4f6956111b3abfb6eaf81bf680b95a49a7803b3c8bb53a8f3ac3ced0df77152a","0x59f87a6d55be8ccfa9b4135d58ebe50807d14f1df8f9226fc2ba30067a8b886e","0xfd7b7da9d0e58cd2b432a55d0d682e0dcf634b37530b8d433e07b30167c47ccd","0x73a62dfc0dfdf4607db93fdf8ee673436ff7bb8434ebd1e9ffae2f950bb79a9b","0xbff58e2da1c4eaedfef2e35768fd6e37061724ee3165cce4f37405bb4c7dfc53","0xae61879ce8bb2e0f3101fdba791b24902524bf804363be9524fda8973336923e","0x8d2d361a86b063e40486b159b88e5eef2658cbaf266611c34064997477f1103a","0x5ab59fbf65acb290594a128b802b6de1e8e17992d3d94e74ef23eb5e756ced24","0xf7cdc69edceb33bab5c7ce79792adaa0532df97cffa1e62846fc855de337afe3","0x5094a647bdaed880d96f4f6841082ec6f3e345708b0efe107ca0e7508abecb10","0x9c553abf386cf222604ef5b14d1a3ff61fac7009380e8d008b03643e8231a046","0x5d1009a65da54ff98ecf083494ab9e30313577359d4337531aa2402acd85481b","0x3c108acc7fdec6445ccc6f8d74c3844d3c684648962809a73e701587c0880750","0x1f37460ee9fca543871aba3ddf1c142c97983b6663b4d7c16f6c4490a7c16f45","0x0fe589732204d3a0aaa5be5830ba660f12df48a6707895e3ff202b4c18b61af5","0x8e72f54970a43129ead1eae70cd23f2a1fe34558400a5c50a28e4e828b790043","0x3362d697733917ef52e969ea97a8662a11cf83e9adedb5cf1a176675ecf32f9b","0xfde573768101e749cc5a77751d0041952c924a72186879bbea942280c7409640","0x7fbc00d6586b7e139f8673ce7b49552cce7e1fdac38e74b899055c76ba9c3a00","0x0c8b87c1b7b81fb82f489d10967fde9dbde4615b08b309894d369c96a8e59fa1","0x7ff3b7ca0dae607fcab0290cec9c5ce4e11acae7504a876aff620afd167820ce","0xd2aeed0f8a60b44f86bd1ffc876464c006c92f0489cd68a23f076eb39e856520","0x1b95e638fe146233b2ad7e4093f591d88351d7fe8d554dd69783d3b15e99b868","0xbd71b3fba9aafbf216386d5ea67bba838990d949c4dad9c324ed7e45c3026df8","0xc5235859f1c8b0c980a1030300325493fd10ccab6e9c9c87ec972cb854b155a4","0x890a6467e557b854c306b452bb1ebbcbd9323f2d57ddfd34972c52fde2a37208","0x4874d9d4110017db6a13055bc210fe1c1846f42d316b6b5098ab2f9badbabd31","0x2218163389386e0b8606b563cc479fcba4a1e5b865006cd5d2b3d50e0a62146c","0x74f1862f08ae91de2cb75f8a7c4abd50652c9c82470bf7d6954916de9b9074d9","0x3d9d9468c340c61e5e5fc35cd01a5295b79759eab09ec1522ebc463c70bbc83a","0xa37a594e434e8b482cf83213451807df6c562819d48e5848400e32711f11caf8","0xaa735c5e8781521b498c6285cb83400aa51053981824b92e8bd1d036dd3a3323","0x4729f4e03dffc0da252009a59e5713f4467c6767abfdb2ad6311542f21ff1a10","0xe82176b5062a2a166f78d6e637ee99090387fecd7933bfcfa4a485c3c39276b6","0xc358b11adf6b6eda5c4bbeaafe45919754c2fd15c2ef143ecbdedd3bca65b18e","0xa059a822fe533e55b00bb2312e420e958c8008a22e15347ee3561e5cf56b7585","0x8c817d1fae938e9fa7f7dc663ff4e935c86dad118e7116d7c784bd10d4f30a03","0x06f385a3e7ddea62c47f0ee602ce00545fa7c8f9b40c01e4ca037e29b665edb2","0x153c196344e4dced1e8a7cb0d37163615e34abbb6580448e1e5a24b506f2cbe2","0x2ddee9eed8c27a9e6cd00027f178d94dba21c1c7b6f7e5b7b948f44a425fe34b","0x1345c14c0ca019a4422663b7907a19f74fe3d213243d7c3d0bf6088878788ffc","0x132e4cc72575cee44a04cce771b9b6046e7df58b1e3080b4017fed995ce44bd7","0x436a8892c21ecb602a17a38572d5e432f935b6adf5fe3fc93f3e14e323424997","0x565a60cddc2e1faa3b74577c0c0d15b301611094e0cdfed36825e64b1dabef53","0x75144ec04b97e51feab1b21db777ee66112ce72ff3b4ba986f18aa9992236922","0x2c3529e7a8ff6052212253004b8c332523527e3759ad6fe7598c2c62d00edbb9","0x10e3f883b874d31ab86c6182b9167ee711c19552ebcda1b246e82ffe4086bf0c",null,"0x84c4fd14b97dafa78bf718576346907dd762ac89ffa0bbdb06ef7227ff955f6d","0x5a05575fdcafb87b5a3b5bee4969153e0c511f75f050e1688b805253e2c0243a","0x462af4a2c89a2dd66f6aefe5f14251533dc47b575186a24a3268700246ec33f3","0x49a74ca7a09146d9e3686e3d95acad349e46a26ff8dec1b7f7f4154acf444f8d","0x142cb8b658a444ab0402a29efb55b2465f8194b59f980de42be947d12eb6ba52","0x0811e8266319f56135d018d435ae9d1113172df32fb2f4b00a3556740ebd3e7d","0x58ed5fa5a07799f3fcb154768675cf00cf75da4a7d293aa46ba007f577f0b1a5","0x2681ab7b897b25393026467c50aee092398eadfe0422228c64b5809b91943a1b","0xd340cbaee88a153a147858661feeedad672a7a5ceee49a9410dcbc77d62b1c8f","0x82ea467615390f0d18a1851a3b03536fc504460b9772004b1746c714ef461a5f","0xe74687b412ec0800916876313b213d5cf9a4177a59caa978d405570ecfec7b90","0x960d190faa4e050a99f09db155a001444c8c7217dee670d2f5709c6108a5c04c","0x0ba4b89fcc2be39a9c196c20c7bd4e41c2664071f4306e783cf9301be886b067","0x8a49d5db50fc52ad857c58866cbdbfbfea2815b7e2ef04f15a71b4a07c706d06","0x230cb804d0f0e335ccb7ffb565bd75e80c1b77976a414bbeb63d76e4d7c4344b","0xd4fbc8ebd990857ce8dde921cd72615a44e61626abb9899e9b220d81255a1152","0xa4c658788356f2ad9a80e57407d0c2760ad7ce70f4bba6760c8ae3da9ef7523d","0xbfe7e170c06ffabadd8c9ecd906f036b1665636f9f2998cdd124344a96c8373f","0xb5968631c394b3ae8bd445ebaaa8622486c2f29d3f802ec7e9c6fe1a1e40060c","0x3f593a0d036b9ab437108928958ee5a208cb74350bb7f0afcab69fdbf5c6eb83","0xd26f4f1a42d2a89e96b3ff9932c3a43ce578281db3fc56f6c8fd8c947cf5f959","0x20c05519efe322716778a75798b63c73b5794ebc7c8178d61f466396c8b30e60","0x428402239bdf37bc91ef04440a02714f81ffda9fb3083c1e4992bc7a0d5a86cd","0x5655bc4260704aaeed27ad0697703e77c140566096596989c99afe8f6d2f082a","0x417f96c159576435e919c62189b20fdb8f7e204d570fcd8d3366aaf4919df069","0xc8cfbbdcf2b4e6a845dfe0f4298631864fca687eaabe5fb833d21c74a1d0e6fb","0x92b9db626ffca9cfdc6434e412edeaa97194bfe3baae9fbe3a95700c82e5f675","0x84dc04090335c5b48def13161c015c3b132a47e77983bcb1f9d2692cb8892abb","0xef7bb20fa1a3defab5a983eb259c93941807fdb67d7c06b21e30ad5857422571","0x3a5fd143cac1d30bdbd345e9dfdc51781337ac588ffe779894cdf5ec8d754316","0x26b702fadf41cc8cebb7f0b425e835c967f608fa12f90fc7f225e53bd5232a92",null,"0x4f34ef5d25f07e0fa9f69afd599fbd14ad023d5ddc1018aac85b46a2a1d6da8b","0x0dc867fdf6dde72471c06dea1c867d5f28f94ad58d213855a3da654b589ab63d","0xa381082facf40b059358aa83d291f32a7f3118192abc119438aa9c5f61dc71c5","0xccc8b417d7e087686bb26050d14874df08687030db12b64578fc215c0dce4385","0xfb6e9126e04301b92534de421ae536c77ff7f07f2bb730a629bc1bc1da9128a4","0x66db17f85565ce8a229a40ecb1f71695a584884bde9ef02295625c4c1426c271","0xab0ad2702da2bc587a59c9693249534f6dba1b7ebc65e76016ab76d824b318b8","0xfa6ca120ae3ae49fb71548e6e41f09f16a3440a0f165082fdd37e33262552b65","0x5e25bf5822f109427326783af5b9558afe6fc3dffd20d3b58c3044179240d71a","0xd0e98620254544a752d0955a8e00b71022081e2d964fb8b7f4a426bcf782a32c","0xcadc2f32098571786de42b412ff1141979a93973f363d531940d5cd959879532","0x8a1bdc66c90d21720c2c156a225340748f0e74eeeeabb9a0a531d57cf4d740ec","0x302139986937550b64ff2b6143d6aa93cd4aecd46c606617de334ee7b58f8693","0x42ea054168980640dd2f35c8900938d76c89d73e8a31a80d77af20683e0d1311","0x371320f779d20f5b2b08dfbb7f1191476ff6efe5246a36940ae3d8ce0e596247","0xa2c963823533831258526a40ac30eb671690ca685643da48bcd37e663a20b17f","0x19012a97f690c7bd5fa7f640c722c54b01ad656e146f71bd5726b88abd5dc2ec","0x76a99b80a1c42e9254fc2b5bf65029006455def295346cdd8cf9959471ea6f53","0xb5f75adb990f0209d81a85e6966fff7bc154293a3400ad1b3b665d9ff42d8c1e","0x914938d18b5e1a5f407020bd1033dd00f434d69ae1d003f075d5ccb9548a2cae","0x801e749d2ef6d8a0d18dea2a312747b0f3c200b453573208044ac94be5915511","0x5d7b6bea8a6e85dd146dc533f2427bac30f4fac032fdc4f8c9af71f7f0c05395","0x54abf5b3609b0b25217db96bf7c2493b1b41430fbb755149354252a75831bf5f","0x1b0e0ca894b531b935c772969ebcdaef47457e3d946d87e39ea3d9a268cb1118","0x5a98c13816325198a5ff7744304e514d3b8e988c28d1f97668c93fef53b07de1","0x504f8ec725ea6b82ec37a52dc47622aed54b6689fb6036d2f879f5d10cf860e7","0x76ae9bd1ef3a66593351b0949e6c9bea4640bc27f574164f8e9a64262d334868","0x177f957f46fa50a820e30dd907e71194880d7ffc6731df3fa607f0f211ccb77f","0x41fba9f4ff12d152d84f8470cd1a470fa5d2b6788fc3c1a4780b934bddb724a2",null,"0xb3d8053a52e0d137533fe14042b9c3ea7349533787e972ce61266860968ad930","0x59acc74a1a5e91cb5f0f0371fb5798d33a8e9763ddcd6acf6f2c9c5feb3b7a0e","0xb422db692da50c55fbae0c56c8a21c8987b69d90ef5bff9e78aa9ce273e34fae","0xdf85bdf292fbffcbb2cc14c963b1481910bc51b0420b19153583fb24f8dce5cb","0xcb21aec50513585239d29a69cebc0ee02936155946a95867e7f8b4a6112df251","0x0e6bfb6aba4d8cbd3cca1baa5295481315b2df632ed49dddf252b7df179e64eb","0x97865eb5613c29a24fb1609ea8c792ce7c53cc7320f86c7d755a9fca679e9b77","0x0991044732397e9906faa7b07e16543f06fbab8cee3225b1c468566b1f595c13","0x2f6cb64b74e6e3b5e357a6861040b0769727feaa5743a110bfcbc662b3147505","0x03495b6c3203d7a5e7104e965271a4d0b4cef4cb3391763e825c7ccd3978617d","0x62b91ff7e832742bab963c7ce5e555cf05a110a15a29fed189cb8585ce95607f","0xaaabf5a0bf5ede019cc82c3587a2bb94e002e484ec61f4eacebd335ab0483293","0xffe6a8d194a899183fedc291da73a6ab3a4bb3becc1950909b2a035704522642","0x5bf9e432bb3d1a3ed0d7007b8788d7af22ed57b96d27cb0f1740b1540e41e6db","0x7f8051e74db33806de2e972993a0965dc406309986a15ac698e8349d8830ca7f","0xe9d3a929f6f51786571fae61245c60ef6c4487a5814eae3bb7a2a1e5f03e00a8","0x422f98f30b4d08c7417f80a9375c1f8579fbcad270cb43e0e7068373549faf6a","0x487051dec8a10ec378a9d3cb023f2b496183e3fe12629ec276aef07f4bb2c689","0x1ea3e0f19e55c1b0d564496945552e3c5cd087fa929676b7f6c9cb199eb888e8","0x0c0e1cf14e210b3164e2b5cabb41a54ab2cced5cbb05307bf46af130ef6f6c8d","0x67a42674d4a87aed897e8a54e117baef7ae3c78d55ca2a23760696a5ecc7b69b","0xadd334b326f87acba8a5043fa4c076c42ba4b39b90ab8b805bcaf41dbfb95946","0x11d825f6622b4edeea109783e2b2a9a98cb9d3eb9f01c36e90e35b73a5a0000f",null,"0x3c11f1ec45454385c251b284efcfa185afa5d1b57bfdbeeb4c1c55a4956204b7","0x95dd9169067afc1c294a8c10cef803ecbc793710de5b8d1b41e93274196c5fd0","0xa694e4290e59dd0fa8c2aa534158f459339280bf2ed05a6dd76a037ecdc2e442","0x8199c4147c3fc317747cb324e15984d799de66341b9061f0c7c3b1eb89584b44","0xf4929e4500a68dde049091dcf40532b6db16f9d51d4796d7d3356035f07b5310","0xb2d38ae7444740dabd48a09152c359b5254e67b6c3904924b8b5536b66fada8b","0x16c9847443d4da8a8df5f213ab1dc329acd418a99cf8825f41f9014555b5b5c4","0xf099e4dab5a47ae45bdc18b64f29700460b55c18d7ba33589b412b684c9167e2","0x66ba3c71e9cc492b0ebd268c25bd333b7eeee62e2e8d4858ae92b2c4c76649cf","0x8db5ad3e59ed8a015785bc669c0365e3ee90b17d2ee0bb2ad7bc7ea6baff2a0f","0xcff5ea7715bd2534991f0050e6e2336d939ae67631d2bc0a67e8e08fe5380573","0x6193f87c919040f299c749a3fe2afb5028c8c75315963381c7d50ea4638827a9","0x3b3e12567ae941caeac22afaf0f026962e6996f7df71e1aaa44cdb7e9df95244","0x8eb05b8a3b70a55eeaa0a3033ff897264f078e207d5c2b1901b687a77b718acf","0x5073a314dcacc582012f3492201fd20115137c43f481050c902b6d8251241c79","0xc7d3b9d9d4153ed8a3a5440f78c8c8276b49df7ac40b60ea6689a98c3869aca7","0xbe10fa60df4af66135f34cd6697d8c728be8bcaf42db1448d1860ea9e0b72e26","0x8c485af5ed9e1705e7ab42b0af5d3d8f6214c371b250d43700af1604b25226c7","0x50b13ab71b233c055bb8cc923b95e71f7e5ca215822cf0dd14809dd8e8a05d8b","0x335a920b02447bb1f2c4ffdfd76fca791045f7bfa0f8c8cdd967ee0310c0bb43",null,"0x8299559714b02942a8f100a3e042712620cea00dfde1b9dfdcea8fb107a14442","0xcf2e29d6ffc0ecb1ce009c6cae2e7c7063b7f962a6e47457c3b0508bf5eda6f9","0x936761e96e96da21d056ff892eb237f416a21dbe415c5934c2eebd2ee0efc5d4","0xea7d4f4431d64d3cb5b35b30dff1d677058ca229647fcef8c5fa778f8c6bbc7e","0xf6e0e3422eb09ee83a7c7ec9aad30c66bb269411de3763ef6568e1afbff4c9fe","0x7457d52da7a64ebcaa5fc7c5682e11b15b7fcb7a1e38d97143e978306b393017","0x8e1235f300fd40b6215a92363173a75ab4e2f0099a138f433c6e398dd7dfd7de","0x89b8c02046d9a62d0999061a82cee266e457970f6c287984f5c7fb0868f69843","0xed11f7e24ce60c6521199482f5bc5bc7e66acee4be38aada1df84e953d9f5b71","0xb2f0c3eec0df0d554b3db479038301cde1c69ef03e3238571c23f116ef391e18","0xe2db6cc87f2ff28fe046c49f809d71bc34384349b3861a65cdbf464c80f57c97","0x6d49d748bf030c7e68f2abf19d3d88ee8bab72878a68e87c08cd5031aec071ea","0x6d818e44096a85b9e2dbef96aba0fa298351ffcf220e0ed199291c435ca5bfe6","0x768b62aa73376fb68e83fe91388e6523eeb9180f3a9820d225ad3b28befcbe38","0x66ccb957166ceb38ec4a8e3b2cdb9d16e2048f5cfc9838f72e9826cea13d5b28","0x62e8e4bd8a3adcbd3d80816bd327d53d06b172538fdb2b406364c16438ed7bee","0x5b590297a3dd5bcd2e7c7bf7bfd6bf39fcb491f0573d1389bfd1bac36f19deee","0xf22065c1b2468ccd49113bed13051d44a101dc04134dc4a8d0e11dc472da1a20","0xcf4dc205c3a19c129609fa3e7616f4dba05c5804738dc728322bed02cfdd9ade","0xa54337e1a3914ebb69166c70f566f510da6e94bb70ee9eaf42b0e4ac615d86f0","0x3fd22f062217b624e2a6f423070761683639d3a0c500c09c6928fba7d265f226","0x376cb1cbdaba90923d31bb85a65a288ed5fba9442db9a8a031d5871e3cf95b8c","0x6258ea54b64a2493c8c7947fe8ed3ca41273dc3dc2acd5549e8ead5f584a7718","0x4cb7b4b0bc9f66c7ce4feac8a479d1e9a8ec78f1819a559f493817f4a1000290","0x46ac49035a6db22be1eeca06f8b2f503f2683d6cf664ba0dcf269516a3f93b6d","0x5c2843b81f3a0d9c0157a6a8762b08c55ce7d200aa117a28c1b2b04d81434a89","0xb21e4618af987b8f17a7a7f2536f96f9a9aee39bce5c9264b9ed8ae07e8d65e4","0xfddb5d5acc03089f0c2385767a54b92ed83987458ac58bbe0dcdd8ace94e99bf","0x32e8f8212cafdedbf206678d85da9dcede4c146b6bd80a12b09491600642c744","0xdfcd54084e2d7ed0c85c8445e0946627c793fc1ad39a508bf241a519cf902e92","0x6f42eb5315075ab763ed0b19c507344d8b34071b00c7a69100c6cca4097b4f66","0xa704014f84ce83d5fb70381fd82896011afb18b109a00398f3fd32166f3775a7","0x27e1686bcbb31dc5c444e9a2ab27a3b806d66710c57489edea9bacb70e9f7664",null,"0x3c210a6df4b242b6d4422c48ea9eb252480a96dddd14717450f18341c7b67819","0xd61a5cc3411e0bf8c3d8462d3fc4186c451097195019769937ce3bfb79b5523c","0xda8b937e4c4dd0de883ee1e763e93d5912c3ffe1de6e4264bf5a4bb682964e99","0x10a80d3c02f43ac49b3de30613efde4d8307e0b0370a651c4fd1c1a2d7d8c813","0x308141c003800f768e7e00fde35bdace5dababaa1d555639fcdd417f34fd9684","0xb7659f42e30ec78bbf79d3a6443d30396a9ac79b7ecd085b08a09c4fc5b46a9a","0xf33dfed03c1eec54869a7185a3a56a8095d6f5b2e3f156d97a3adc0f1f88bb4c","0x868e79ef8a9610b587aad2b313f32a6582cf0fcfa9a68a2fd1e389a4913e9fae","0x0206b0e0671bf0999f754b6f26896d8deac7e3c3d94b19903fb7e0d1c1ca0d2a","0x726f2feef628a672758fda2ba595590bf1c8ab07d914fc76fd1c6d3a646caefa","0x75e38ca57f02f0ee1936f9e4f8bf05ecdf8e6de549d210ec19f8f5885330d2be","0x1e84ec1a67660d0e9472d41b4bb7b552d68519a0237f56281e0a17c6302ddf80","0xa2e4fc4186741f0d7b33a8e90929c22ee49db15e013f1344d1be174d4a183189","0xf21b8c5af080b5733073708fa197173664d57dbd1937a3265e6aa5ba53f4c19c","0x3dd4aae7a8843d67653d9aa611e4a7a749c88a78cfbcc05ad3ef3a1f0bc4eca7","0x39eeb6185cf36814b0028d8382b0dc615524a96b349c06bb8732dad6d1d0ab51","0x5e42311684b43e44b0c6317dfb4cf3e4cc37dd34e1032a5c26688c948ed3c8b6","0xae1e0df778a7df20277f8e23cdbe81d36d39c14b1917ca76b9358e0d3dab9a84","0xaeddb6ce6e12e605c405d22115ce8026f17ca92ac696f37fe4292830d3ce44d0","0xab7ab44af99e3eea080240da0ac83345f0da12f5f274c81f33b86300faf8c45b","0x3bd61e3761efa9aaa36bb51d3c109de657a3c514de3264103bd16b2282ca844a","0xc48a36e891140c550f248fc32d7ce288c0f28ca9362a673a7ef82553f141358a","0x912d0fe78451d35f652bb9c92b73968156159118223f0d992b4c565356d0f3ae","0xf269460127158a75f4bf4e21653b166041fd93dd9b3a11c0898736a3fe31628b","0x430364cc0feb5138d51aff67ef6e273c8afe1bf51ef9b5d11cb5ccc30d0d318c","0x11fd7c4738e099797b1f1bceb68f2e541a92fc473cf973018e5591223180d883","0xd616a94aa3edaaa85f39e9723d848db8f7ad0c5714db1c0606bf8744b9a2e095","0x30b8a81b3efffef3961ee37d318a7581aa17c215158604160233c4ea4747f94d","0x1246d11c9989d560724609676c336cc565807f108dcaf0d680961f07ac33b269","0x1a7e1f32b32442d1f0246d1cfcd938d47fd34e06611b6eb8ba1c5cc4adcaec36","0xee8309a89e99eecac3107c859a74bb1938b6812122976b36df55f75daa8335d0","0x21cbd3c803291155e7990d79dc92f6043cad8b6477713699bb27a93018c45873","0xa74078d0f325d867ef5571ea06227b109b974214983c76186f53ac602b5eaec1","0x26a79edc3043e8667d329d1b5d69475e16d1331736f3d3bd3e8c721db23cd89b","0xc46e396316855423b0c1c3012ca674e057232af0861c937ad0f25e747a606041","0xe197f9b56a4e25473f8f939cd2fd6bde12d1e4204caf4261d2f1fe0e65571e04","0x215a72960ebdd93b3a12f2698da0acb09779f2032bc0d636ef8d7a602b47630d","0x842f21aeebc3acb528680f325381469df3ca41a1180d47fad7287700be466417","0xa263ac0084e85a7cae92a50aaab4d1403ae98a8e54f4fa4c72274523208d91f1","0x0da36be2383d5e79e6ed2e71f221281db401924f22e6a92e92c8a3860a990b1d","0x47c0371c3d1cdd78ca130fc62b717baf63a8067f7e109998f4a5661d09ba6c36","0xf1fadb0d3c7ab9a9d35628392a39e8272b70cff9a0418cbfd10c6de434afc04e","0xaa9d0915a78e87ab796fd64f2050c8c49d3b852112daf56c2e53eb613bc881d4",null,"0x51092136cea8544fc41ad092da09d5657f593db54823b53cc05eb1179093efe3","0xf4a523abba0de93af668351218946d95ce6f4e7bd47f11a9c368ae668878b513","0xeef44b27d0b16ae15b017362b586d3374eca951125d9dc40f48318e13afc9e90","0xdcc9a648b156e9e49258e22f819de5c36c8854ac62fcc30d202769d00881fcdb","0xbedf7766b7b52a4090725164494aaf849fb2e0444c333735e18dd6df5a82c1bd","0xd96c135e258ab5ca8865915472c03b5952b689db210ccbdf4276403ad9ddc316","0xc7f30c6e138ae0375834fe895957d6fb41761c3be35f6d67a98543b0465ad36c","0xbda967a8fe766dcb8a5aef43d67af55bac03a94a6199fc6489c04901e068c9c7","0x9fc66cfe70e32a77f2f556e69c246b6a735c44f0b57e028030d0b6b1c831d6d1","0xa7f1b2ffc77ae6494fede0938cd558c8afb2df3842c31549ff083c78dc889c90","0x75aeb1228c8685d70196d9e0d9b856c74ff388e2f3e281ff262e6c3e99d653ea","0x6f8207f82c03f960c5563dab2c684c621716a223e7899e9f5ba72baf7b99accb","0x1c1ca4c4e65cd8a0e30b8f55405c419451282f33fc2a5fc29b6f52cea5e7e8f0","0x9370a00bc8bab543d1f9ac696ffc0f09388e1d9174daa909b6d13ef08008ede8",null,"0x9e0dced70fe3568cf6c1ad849936f3aa0c4c4a611471742c0a1c0068907534c9","0xbaec8ad8c46aac60c6eb6edd5bbda98c9c789b2da672a0449900c1393c7aa7b2","0x9c3ef625acca321b0639d7f7b6ada86cd09cc88a397f4701df42d416d9daf4a2","0xd83f76d21855267bed0e27974248dee4453152ad140be05a8cc54ae4a1e0d3ae","0xc2063a0902dba0ea6f49cce232210923c1296999adcd7fb4ff71d3f6d06f00c5","0x2db5f5e95f1f18b7e0803b6cc5ed129fb39e2124fac5716cbc48cb614560f3df","0x300f49e996034bac00fcd799561e606c1b26ba6a5425aea5222460780c60cf23","0xc3dad50cf6ab5fba9457436c5208c394ce82b0caab7ca02ded0ebf745bbdc79b","0x0f489862543ab93dec59599fafb18dc0c77511ea7afe55f0b31a568a163dfdbd","0xde7d5f60ff85cadba23b9b050d4a841080b99df5e94e45f5a642f874d575ef09","0x8a443dba3e40edc96875b9c65cb9a38d2ea18dc473e2f4cd7e2d4fed668c2fe0","0x11bd8187a960fe4998c1dbeb1f5cb90a46f3f842038fc7f16492f371128544bb","0xf7e714659566dc93fc388473dc6c48d60d06748e94cbf0cd67973564db6a8c1e","0x3b89854c7c8b054f9fe9cb19fc0e3f0d01aedd4f82c16a6054ec4fb2a9df7189","0xa4a61f30903515c8b2b6e28c77ad8ac6e560a9abb2004a8b459a02374cdaba2c","0xaa2796f92fa8ba27a124e5917496fdc3d8713f14d8316dcbb783906afba2cf69","0x33f3829d60b64e5cda05bfb69909a887fe775d62a1a441fd6d7472061737ed08","0xa7c7dae58340b9c3379e5f242b50baeba71ab90336c6caf758e7316b46ef96de","0x0f5745bf9d03c188ae1b20cab263e793e91c59004e712a70f6f8092cb1c9d332","0x6e2a28eae78f09d5d4370fab592551871348598e2bbf3a152d97c1db441ad6b9","0x27504ec57797d7ea3b914c034513d17158405031aebd0487341dd5d30cdd869e","0x9b189e2eaf4e4d7315f1bed86c3772bcbfa4ffada7d00d0e52aa7cb99cf2b77e","0x2bbaa9d12f4fdae9e7a37599e1c37f6d38bb121cf9a0c0e0c2546c6c9bf9552e","0x97db65bc056240d707b7c420fa6577b364a9a04b2025e0328e8c8167506f5521","0xce73c73d7fc46ccc367f0c87dfea27b16035437c6a7ad4d603d7f8070e530f0e","0x15af7be6a17fcd4e31b0de4c3a346e0e1f20b59599465a3136a1f478bd176c94","0x2e633dd07736f79947330d6c004f551be6005761bec3634c3186b9867a6c7a17","0x5fb7044795004f14c4fc4bd2816b763f6cd9a8a5d811d7ca5cbebff91ba12d37","0xf3655f886163fcadb096c9d7de74138e69b2e2b25c588b54af3d75ea6bfbbac7","0xc4cdf9b3f01c3ae594b8fc630b2690225b7474c632f76629e2d7ad5448993a15","0xe7885b9635ab84a34f399649988ef64a9466091deb40d5d99af921e8e9842173","0x8da184d460f92306850e229358bf3f7574370645cf68715bf64ddf9be12563d0","0x6d8c74f2ec0aab24260658991965b0451683dd87514b094c30d72bd8886ed283","0xe3a1a9201a2c5bb5aa1b3f5b9bb6bc28c9b795755f9b6191292f381144b4b515","0xb57887827409268ce7bc3df94114c2ab4d13be46d0af8f40d0ac5b9ab5e8dceb","0x0f991f6decea4fc9057dfe3a9a5fbf5eb7f1c68827566c2d4b303791d1d1184d","0xa78e0065a1f6a47771ea790486867f082149a2fc4241c152ad3dbcd24d616d8d","0x5ba88af139590f8514404ba30afccc61304ded5f6978dc35e932b778084691a3","0xf154c4af97dcee50b5ab45f47626ff266e36f6316fd779ebdc12ae4be4c74e29","0x97f9d0c72c1f98d988db050d51ffc26a27a951929f934651577285d444987745","0xd6ac5a8c6dbc44241be39ce6f1e4b5dcd5296b1d26e1572201a91f997f4966c5","0x06ab9664e5955843715d1a0e1e9f5ea5703b5e89fae00c11e4982ba20d41cc65","0x3fd503d5f9028c97ed7b11472f68f3ab6a9ae21b184717c208a0ecb0a8a8e23d","0x5a228af81a57545833cf0cd7b7772e77b627fced4c1f21571c082c15825a7f87","0xcdf944f8aa759c49bf09e2bf70ceed3a51a60eeba0a9d3f658c4154a28dead91","0x6369e274dec9ed795c4f858329e4d5cb66bc196c5cd681e47702d5cfa680a7b6","0xb7d0800f851e904b423a2ef87692d6b0f3d6f2ee6114337e3505e4789d17ef2d","0x114cc514f7a4630c20dccd4be867827f04a1b2455f38a28d470cda00209711a1","0x66e5ca1912f2a2fdf7e8c5da4fbd5bea4b5e258dd8ebe7fa6dbcfc1af794b830","0x1b807a22af1c2b8373c455482680538abf9c1172798d3bc1ce74fac4e707b9cc","0x2e90e1fa7880a69ac6fd5e72be2becfc5d9db412d75fde7ba621b76f6b8b321f","0x55e1480fb7250f8cf2ac887fa32a204387670a34afba0981ab41da106a84f2c9","0x826cefee8cb4b6abbbbad8b3a18f9a4b23402bd131f0ee7cc7e279a07e94f76a","0xb616ed5121b8c03c331ec663b9c403fbc85825d44bdf4f46b766417df0450431","0xd0e08a76c59b03301d87e534cdbabb457130cd64b1a1f6f4d98c130f8fa2a08d","0xf835e27794ac7a9d703cd343c2397fa0f73ab8ca7764f0e07d7ab531d5dd1921","0xb59e98b49990a78eebcbe85f533f15f1ae8dcb3844cbaf98a114aabefee7364f","0x37f70467dcb1e530537a3f9835e663658ee97d2f3c1b30c00de1c00c33dea370","0x705e2f1c6fe01f582ed7d110a2fb1796e87c8d6f00971e891fb52fca786227cf","0x9a301c048105bda72ec9a3e95b39c61283ec12dcb616398bb12b9915206459e2","0xefd6253591eb5289176cf00ecd161c858cb3eedb95431e01316b1c3ad880b9cf","0xf640960d685086acc059b0590919a6d91d8213a1321bcb038f5f33fb2251930d","0x3821578e42b620beaccd700fff3dcaebcf6e0ab187bd50af71681764a3cbcd86","0x7780edde7790f0a512ec0e9209beb7241b3cb1900221758da138bf3cb97f7f46","0x22a2905c076aa245f1d0488fe439ed7a76b7f08912a7195fa6709e3fba4f4a0b","0x2d914ed01a078d9da8d9e47f7670fe2910e295167a381cd1c919247fde6cb2f0","0x84cd032706049d042f062b6701f4c595c4ef5263373197fe6071d680b710910a","0x1884538b238c7b7b274cc3d7789de9115592369169579ad8ecf539abf25001af","0xb63fabc59426dce89b83671fdc89404af5e92f321512c533c979d78131acadbd","0x813bbd8e299af11f5f794e363edde0a294d00ca92690bc6cf36f568a6c37397b","0x16425a183c07fd032fd54da4269bbabae5bd417e1bdc03488c09ffabfcf8f619","0xf843f6779b10e0a3527b1e073f93d199a0e139bfa3eb211a468611c507bd0983","0x51a52f37c93222d6a811336fcee16f6a155581941349805f33f0756ccc2cd62b","0xcb73dd93bc01427d4a5677b059742aa175fbb3a8f01664410da49b52154807ac","0xcd46793ba2bb7c04fa9380a75118bfd2de6714da866590f77c33e19f893ab7ea","0x1a28fea0a84bc1c8015b85bfe3e06b2f6734ea08f92bd43911d93592ea287146","0x5c79d4475c7709c625b4fc1a0876347c89a9f3027472407f20263d3d6f2cf6c5","0xb7ceff076639f3ce4ec9da08e263a5ed4cd047e7fb805ae926d35ebf079f9636","0x51d781ecffb05e0ddb0cffa03ea7d0cb37ec05c3bbbb426b9db6b2970749bb57","0x103d6a8164369524f7a5cfcf8628e45c1e885985da1269333b665192734d54b7","0xbc694365fce384d0c826183a9025990c2a6561ea85da2f291b215b1f382c84f6","0x91fcbd82f7830863f4cc7c992f7bd76dfb4f5a0667f889c1e486962b75c98c49","0xb407e2e6e493617cb8bb18c109865b26c88add21547ae38d3624fc34fb3e382f","0x2ca07f6f08cc9cda40d67b685749f039ef3cdd4c6d61020889ed937c7018cc16","0x25897784c53887f90065da2fcbfa2931df73bac4cedaed7683984cd1c2424510","0x5ad0ecbaf15a69a94bbe036520b84cec4d4875e2ff271ea4bba27fc883941f9c","0xbd0c85566e3d0343397bced8be0e47ead3be74a5a3d4f8280e712603b0262e10","0x8b3197e9e812850e851856343526e96c4c3d902faebae11261fdb33914f239d3","0xa5a73f97a2dce83a51a421117d2d2390fc9b07faef0739f34ce60d1758662b98","0x9570c4f21cfe9043c3edee312499b24c68007b7048e3b40b477340266273089a","0x1809ca0a814e33fbba0276b3b7352ea817336acec2b2a0c252a57cc61b0f527b","0x6a568b9a685c0c4ea173117682d1d0a989fa88425ebc66353aff96faa4d110f0","0x5f36fc23b6879656ec4a5e3b5475795779478b4e34dbab799adcc0690a28d95d","0x19fed4ab8ef0a994fbb43f185ccd9ad3da5c17116bd69311e473c4ff7d53d00c","0xd810dfdccc3766a9119eef5c1149a9d446d9e82bc648918026f5250684e965bf","0x3c450f222c850f1c5236a7df4a969d05a7fc1e38132cea915004453c4e6be5c9","0xc923ff8b0e0a25e377124a37125e59ad3ad1fdebed661525f834e8425292b23d","0xf1cf567527910e6cfb18747a5742ba7218eb79a10da979a4dbaa1d969e866b42","0xd7a0ac5f8cc8182d7b91cec1390a49bca089c24f0090533b5b71295435585bb2","0x3564987ef4828b5a5757d181e6a3fdf58b541d0d74e449d4ba691319ad0ca578","0x94888fffbbeccac6f486800fa5ceca33f08a3ad8e6822d9506cd6e2457678480","0xb2ebe31e546eaae1be1aaf30fe6928044c2077e0221508b1f5af42c5353d4562","0x8f7a3f5d584b904f5e1a63182055129d9bf0b1d15b8f3ab207d9f0b43db912a3","0x9923540940bdf662281e34f41c6f7e19bb140e0f7d81bba3ec7d4b2cd5e39fd7","0xe3fa484db4417fd822d566cb59ef4676c595537ef8898072432933ce75c3fd81","0x1c69e15e65d2be4902b1264d034f5b6541bfd0fce86509e7c1f63e2e9705dff6","0xef248900f5c837256b8b2d0a174cc84ea57c57c466314e5e2a1f064fc2131d81","0xf6db1f2d3dd9f4c7393c038a26432aeffa99051b2a2a50d0f1e60994b62353aa","0x2fac1c5385835fbd43c264dd7f08f1e9c92a3a95c34b20a22d0bd1bfe53d2dcc","0xb17401d6d6e7621ee897f86ecfd8197066df8dab25fb08503c0276d64aa41c24","0x70e21135bcf57d5fcc861253357c0759428a3f0749b976e75603e3828374f25b","0xe6dabd8d56f72b53d93ca69d0ef1d0dd1e25f788f972384a051be04142cafd39","0x7384fdc90610ce92427b32166a9ca35347f3ba8ffded15f09857a3e3bb48f923","0xa2ecee0d67eae9a7bb5a8a067bbe9d7a2c95f27740fe390d3c4f96905806861a","0xcd96e6660b2d74d42e0e9838ed7d3b2d9169f83b66070e3aa12acc955f6281ec","0x762d8b29e82f4d8dd3a5963b2c8a5f59c91c668a54c41a2c8a95d9cdc8fee3c9","0x63a5f8926e5fb3871d42178fb08bb905fc1957cb94282f4591aa60e3fde82eb2","0x9414bde958ea4eeb5991be9ef52e9b84babfb42d97a6e3f483cfcf3d407f6697","0x4cba9052222d2638b6f7685d6f35105d55d23afbbf78798da99f960a15cc20fb","0xeade952c3eee0de252c04ae1c40f0f13b21a6de0fce99e6ffc670575c3ef4ba9","0x20e1097b386bb98679fd5f8a24787d2f3a89aeaf0124c06894b12eddfec04a9c","0x69cf154a650beb8f0f86d9b3e4b946311f6ec0818d143836f5ff87e791d519bf","0x1fb0d47590ed0929b7f9405912fde58b7fa70c4243f5286bc8cdbb6eb9a38f73","0x1a6375eb194150390fc3b143b7f74006760000c8e37672bcf9c97d1295b01b75","0x3c4e2436886692c1eb0bca44b42bc63bb08794d55ba5df934e80778ff3e3008d","0xd37ae401a92aebcaeee20f398b99357d5507777fc77ddbbb069dab6c1e3729df","0x3872e8b24f02052c4323af65df99d4ad0891c38f7dba70f775ad83ef5dd7a345","0x9c2018ceb2e9cec7795d47cd9a7243e22e1807c0089cdc0f241df5ad378420ef","0xa927061946a52f4518407a5c2d6274f9ca05f7ca71f3aec29662816ef6b47233","0xb7fc8a91259f0e482c20cb5b19d5792dc1eac84939e371a2b31ff80d03aff450","0xad28f8640f0b43fa57bee18c0076118b74f5d5b4e9dddc2fcbf97186f93f1e4a","0xa65cf0db5bcd83f9331646b28c747d4eb2ee4de492dbc3b5d57630c440739a2f",null,"0xc097fa6a91a0d5620993c189b6e05d55044d8df62033539f6b616fe5288e14c9","0xd10d1f66688dbd46c5d132227faf19225077c7bc916777d21030e33e22aa43ed","0xbc50ec1d9b57568211603d4441dcadc9a0fd6cdc327848d8a4394a58712219cd",null,"0x76283ebd3a01eed4c36bacb9c9f91afb38477e21d546b27d725e3e10e4b9d386","0x7502bdcbcff9be6de06534fb407b5d4cee2dcac295605a58fee0996433290e47","0xd1488603f6acd808caefbd311cb087913650adfe6deff304315860d93a3d3517","0xa8f758c4758810a70b004aa3a6003ff46aa270c91f2b43a708ca07c05cb7ffcd","0xc392796e9e943e5f5c15c040e657b98372f7143236a28ab61360da91cc05562a","0x53268807a54fa5e4db39d6dad59d7fe7e79267ff90a250ca5eb7b26082b3cb66","0x5fd069dc00bf0f5275ed6248df25cf11233e9f26727c4da76a8a1401f65d1164","0x57ac7ea962952d08096248726ddcfcabeb29c1dec4d736e111f1972a2a6c59d2","0xd359523536e633367f51f7aa50c1aed4dbfa73c8e2ba240442bc159c0ac2b6f3","0xbdb5982a7bb0c929272326fc4737558aab09ab7a42d5387f6dc79cbddd128988","0x851ba2b08344bf22da27b640467eff3cf15dbe98c5f416a3badb010ab74e04eb","0x5fadddb238d631e56f31c9ed8e178a24feb869540e678654df27b6dced48980e","0x5211064e73946b322ff7624a1f1f4995291ad0836573957dd725e49f2be8ba26","0xcc2bdff69af03bd7544a7f47684b501f2a1557f3c7a9c562dc77c83d4eebe915","0xe0849be981a66ae2fd89d4a1c300cd32e88cf84953b2950df3a34d2341811576","0xf9ba063bad19d9b2f58c16267c15fc2b3e6faca1f19676611ab3128147af15aa","0x584bf9ecfc3c5b087340739eb7441c8b229872a5e88014f46940f8af36690dd3","0x2cfd3ccabf4252829c008c0ead4b7e374a85a1627401fec4537e72f06bcda849","0xf79a3e319e26e58f663ad3d08e82e93e3350f56757883c4c010fa63e054e8918","0x4c2f3397a13eb9a9340f3adc034fec0813447c75a9c179d483ae1f60b5b7b700","0x89e14e70c712a4f924b75ce2bd01df9e6767dfc4a9c1363472e0ed87ffea5abb","0xb17ecc7b7959ae0470fa0a9cf5a913740e59ec0a9c3ae1225ad831c736619441","0x3404633110cc56939ce338206ca3b79898e26892b345c45e1a37300f40278fda","0xb88dfb268c929e063751c1f3dfbcd0850fbbb7312ba31f3d058952645b9ecec6","0xd99ac6c31b7b014bfca7181bd4b77e5e8a87c6110bb65c14187e08b2aa4f66c4","0xea9d7b2db5cc76fe5379c34606ba43ce2c68c69a15702cea1369827898d9405b","0xfbd0fe864e8f17acea40552b5596996e45ab75dade63dd37cde6987769a2871b","0xcaefa3185aa23e6abab29a88d0d226b423c2360e06bb19464e9a73f64f8adcae","0xab3fc2ac340851b049ee7465abca094a3968f2ae87c82a3105e7142ece8f5e06","0xa88de29ede66354d91b83d863fe97710b3ca60ee2dd2e8441193b95d11a8cecf","0x4d0ba188f6924bd5f1136b74b07a5bd15b8b0a0ea2ee79d3c782fe60d177c7ef","0x1d0fce694ae7037b121ca5057f5e9b04a2761b45227051929a7fe17196dce895","0xb5d2fb40ff41a82b276926ca7570553dee7517d6c3f8ded6bff38de9e1332cb7","0xddc9f4b402c8241d70699c3c5fa0e6c19d40536b3b46964dad085d7f07c4bde0","0x9c179f3b2d30e024d4d230c8f71e46084f550010b389237fe0614e3d029fa4af","0xe316960291a055ce1abb7eae785cd8ee12ccf2379b58177867cc18ecdeacd512","0xc1f226a5759a8bf5e19ceba5b2e832e0ca5177e7ee556486c12d4e30d5942a17","0xc35d25db32ba77058d61d399e9079df73c4d952f5256c95c9bf729d5688a53b3","0x72e28ea3a159d47e56fcdc5bcead888e8e92e5e62324afbfb2580773513484e0","0x4732468ea8330387d2eff55d498ae90a8f0a327df87777b358ecb38a4d8ade08","0x187c8607c5dac08a52412b5dabd81a6a487cdc99786722cfb83a8aeaf4448885","0xd7871591d1e02c147d30bd0b59aaef94337d82702835b4ea1c5eb9da93cfbd65","0x086490d73bd512bf6bee791e31f1bb80af2f3067c6b6d8b0d5f96a72f172b15d","0xb1bb91ff967beda555ec1f305054aa943700ab9fa390105a04ad2b085c96827a","0xed98b30ffc274cea030506cbca76ddd93748f06a5ef7d2230fab5273f824cb68","0x12d387b3f174d03055089cc128f0c768038d33271e5e5d0fb6698be80fc6b25e","0x6197e51bc3ec0c2a406094c028c6def9340270128d6b9bfe070f75af9912d9f3","0x074a9d37c93de42e903ba545811a783b222036cc2b8338453fb472ba933001b6","0x8a72d0070f590863f60196e1b67bde7099b797af97ebcbdf03e3dd6cac7b1c11","0xcedaceb4ed807e0dfd371f2d78b30f517e8371c2551a211aa64a93253a9946f9","0xe20e4eb62a71a248853797db111d7e6f839382ca4391984772827fa0223ac470","0xfe029cb6f23042379f99131384ce10f59a2910107a02afcc08e5637872943645","0x29284b4ee85edc711121dbafbe96b5b172a54b5947ea2733d4bbaa34fe9e1bb3","0x8123bfd3e2e1e77d518f8a529a757d38d6c989f22eb65fd8e9c91fffcfca4f34","0x656af3e6715648a5df2f1a458cd0a66709504c45c0925820341d06492f8b7fef","0xf2148ba10547cb54053ca44d29e57d69a9b73cb7e714c648132104cad5859feb","0x6ad2b0edea40f62fcfafd34d55b4e1588b45cbb4d1731321007cbc50ad181ffc","0x2b8866d64ed94a8a7f84e92ae7291ca5a43cd2a418e3cf693ee05a6bb1a7b9e6","0xa5390b17dbd09056c8034f4adca9fb1bec4ba179acf304a4156a130213b23d03","0x36bc8ca98e0da70ec698f4589be015aa5ed5b620ccdafcd4123675388651b1d0","0x65e2b702cb54340c5d1dccdc9c0afaeb9294c9c9021bd0a449fcfd773c5e7a88","0x4ddb0d1fa29782f5ebca621e81572d750442596dcb9587c298cabbf40234a255","0x8085f968a83a1bebded14e91cdc738e3195bd42ee21b6f15904105319395470b","0x16d385f4fd6aed085e81c1d4f6c2de2484da33f20a9e504a4e4c4af3166cf746","0x511caadf9888921cbfd9ad3087bc04259554afc0850ef132f2ea0a91de6d9bc0","0x42133c7ef34b15a42b8dccc2a9a0fc0c48cd858abcdff756357b33e1b5c43c87","0x37ad26adb004199f84aa36e96c0aca5a47d896becded789f589fa705e1fabaae","0x7ee8c8b0366e6be090d821497d40829a9cd4db4cdeebedad3f101f1ea76a0eca","0x85d8a65dad40a19fe806106478ad42a746601ce26f2484b796640660e188018d","0x2bdbc2e1fc305e6924207aed02d9aeeab783685d435f5b1cc77b4bc8833ea4fe","0x8c3cfdbe9d99bc57f436d67279288d69b996cf718f7511d76398a94b4ea48b79","0xfb33afd3c64b72b684349acc0468db7fdcf12308237e5f965d17bee946afc74a","0xf382e159ccb877ac8392f3493cd0a4c9dc6c37ecb06617d168988d691ec9e877","0xfe745b648ee851fdafc49679227d1d70e9329fcf57bcbf7ec7b4e25745d7ed07","0x82fb83495f60c2c1f5f28133b75d00ea3c186921ba756240b26941fce4a631e3","0x5d247bc24e2b7420dfc675130e7ee4690e4b28b235e56d6b1d938d6e69610e8a","0xfc9b7be7a62eb90f1da4b8e048785abcfec5e48cfd97e8d63d3c1452f95330be","0x7c8de2aea6c9f2741d89183152c3ad4720ec8c503ddf0149f2fca5d816a4cc02","0x81501c272b8a17a42fabc1e75b28c2e994d01234bcb97736e415ef2bc0079386","0x614611369254f6aba0781e6e47455daf3aa328d3fd71f7cc069f58a20ae2e99f","0x8d8a2334bc29d3339ce579c2cc46377c768241013792832dadc7e2241d7ea00c","0xdf68a42aa9dcc32135b976f05f2ea2bc5f4c75219fb4a54c7ddfdb75606d5b20","0xe9ad19bc50c19ae3c3917ab034571dd459f790a601025b9c3b099ae20ef4fdb3","0x3b6365ee1489737fff15fa15cac9b19f9aeb95262dde34f140d1ffaa4158ff23","0x168e4c1f773d41f3016459fcf366e44a7bfa367addca8e5997b1afc94717a945","0xc99b6d7147504739bb352b3d5e2e1fb0f20d975edcbbe29d8e8570453641e86c","0xf12c0d48c28c0447557ea16e1c2c586dcb38482377dca9c138d37e5ab5649314","0x2c56fbde68b6fcf73317d9ed14ba77ebb7b061125ec049e20f06d55d35cf2a25","0xcd4113f753261e86c7007711c4febff9c23740778c4c05d7dfe5bb47eae23164","0x73163073ad4a88557f66342533451221379e00c990d9074e4ea580d48228a74e","0x6822715eb037d4528b58e48ca1d00b903d46ac6c860ab201ee2c8b9572019971","0x27adbe8c0ed7f5d4d8ce0a6e89668676d4a5de3a000ec6e019bcd238947e93f6","0x9796c94d4e00eb6766c8b4da363ca88365528c1ea43c2302b3fa067d86c94b7d","0x0acf5c8c8979e71570feb834276303a551b5e81c92ac2b6de333abdff6000665","0x88893535f26087277149cb72ef8790fd8afa30a7d87add6c03383857cfce6324","0x7ff7dc7fc34d0e0c9362b1aebf82d7bf0348acba30205854b04d1f518e635eec","0x5fab7f9ef619f82270b9a1b196f2fac43a65b78b2012a43c22e042d0a363ca46","0xc9c6d45ee617c7c088e7e25d27b9bdddadf2d6c306f6b29d709dae2853895dfa","0x5d2022d9fe04b166b18c5b0856d12ba8a957d035e5c642857e0b853c3c9dee7c","0xe0b21ae2856d4ea56d9e3109ff9e5cff5a8dc3717c5c884d0efc0622de3f3c1f","0xc452438975d8693f324c8aad10ec5cefd49f5cb03d88a3c8d50766438035d4a2","0xb2a6aa13a54f33e0e78bf65b04e2ed75881255e724843cd20f82e95a0afc9d68","0x3201c28e9585c360fea5122424d0460e71dfe70ecbddde2b11147f620c84866e","0xefc2542d8fd3a5a008f9d796b04ad82c792beb7e34ece797c6a4f1f20139a1dc","0x4a0a61c7aa793d3155c16e57a62873442a85738fd994e2c0cf891b16c25f5c0e","0x49e7789c2224d38375164c003c374894b01046db14b0570b15ba410aec372435","0xf57a95a2afa751cf26c498b57353189c3bc63be77d96883b76b1a27434c404d3","0xc3ba0e3cfc4946e06995f0f826d8f63fc931502173f534e637854204d296b99a","0xaeffa3f864cd6d11979e1150f55be23071b70576f5f51e0e3fad8fcf57f368ea","0xed379c6e5310d543dacae886f36a94f0588a2b0ba7428e7c8e3b8deb0e95f88d","0xe55f43a4d21e6235cffc6e6468874272080fa2811b46f9a4221d122f7702232a","0x49b6ffe102cc6e5bccdced2bc692f0183eedc55a6ea32677706243a72f99a986","0x104f8d1c863bf9fed21854f671c34f751bcfc9cf283bdc11641ac49838e88627","0x94cd8e0a40acf64051448bd67d6d023ac05e824100c5dde0ee467c5b71ff344e","0x65fba77a902fe54d21728c45cf0fee963483e8a424c47637a689ee8f0da50505","0xc6adde3f304fe916ae33a80d81d17ae3ef62f34c592933b4830a4dfcc75aa98b","0x4799139a0b66b9ec93dbbaabc0dbd45e3135ba5849aae09a05a48e7e7d0a6e6b","0xb8563d3b7d3268770d0603c9b46bdfd5a9fef0b720b8d5b5642efc55ec6748b6","0x3e86ee548b9aa989552e64bd27ac50b1ba2e62de75f989b63222809a032b3ea0","0xed64c7c64a7cbd53a32369e64be81a3e9c231a95ca53a9ef7b7e3e9eb43c4457","0xa506791501a06c0359cdeba7b4b26c2981fd4dbcf20e74909e80e481ccb46e3b","0xba24c0b7b604d55ec4f4175c727740f12fd8d07bc5b555179c1022ff685fe4b2","0x4a7053d4fd0ce2ef3d58a4336f66f5081aa3345c0ebfc3846ed0223b5afbdc80","0x6aa8d817c45a15ee1694a9c82a29c0e94d5dec88eaa1a78966098648ea5db050","0x701b71262edf99df83e99f97d2d5d17560cf38ed6fcbecf609c15f43fb9dcac1","0x1f829cc31cd51b169f80a502cf80bd72943cd076f28a80169d77f5c772daf781","0xa59fd161121547451a371c06a7b2892eda4763cb125699e2be03d8284fd5d311","0x4276d5049a9e724a5a9d7a774993bf6bcd808809717ff276a8414e405ef9b7d5","0xdfc1357fcd46561988a90dee494c1bc3dc1dbc826561246a849a31d2ecf5dcab","0xb6f1eea4b929fabf9af34980ef3cf5e6f56d5f01b910be043b79b6b4d8b10dcc","0x5df854edd49ab66596159dfb216087b76c957f9e846018b26699009c92637e12","0x4f9bb7a7f2ecc62aa86c36849b7698b63d514acbda3b6eff8d17d060203abe2b","0x5032c8e7ecdbeeb84832144eb1c57dcfcff3efb7585404960d4c9d54061d437f","0x0c479fa5d6b172b5de061439b5f2316b02596aea7499666b9bb7f2f1678857de","0x6c7ed8d852b3f3ce172b4150fa3ef56341c9cc004f10a75f3de3e46b699c6241","0xc9794547c200f29d39009009fd255e5e50c3781dc634e30dbcdfaa34e0e5dd97","0x3010837b4b0824c40b013d4244da914d7e6079e7c8e80c02dcadd9c38088f20d","0x6541483dbb89a45d37e20fddf23f1cae9042c7ea72b556f7bce695f75c4d58ee","0x7db50e81ebb10ea4f2298000979e2931121dc3a34d2210e4005cef9cefcf99a9","0xa17aad4b5aba365e422f0805b6c3ae86552546e372f7883d15a60a22dea561b0","0xbc006b49a39c74bd563cd8047ac9ece1616304c0e778f67ecdc561e2463e463a","0xf2ef5050498b621dd8eed09fa9dfa3409e547e9bfbcf3da9f61ac547b86589e2","0xf423eae08a48ac44fc407ca477c2f0d683b8295917c8ee3b4f6a865879c34ab3","0x9381a5ead4674595521f74670057448f8f71f69bc679edbaf8c8b84723e2e2c4","0x58f272fa4f108bb23436bb96d6c57f7b651aa55bc8a5e497c0021b35d652e039","0x883f7abd77c510fc53b70df540355d9d3b9fb8d42ef83ca0ed598e3e92587b5c","0xe2c717c32c53eed1157f98d7eb78496d504f3694429e47972a609922768dda3c","0xb6fcbf374d3e1e4716e4014f677e6d9d2887cc6bbc314c513759d5f612e5a062","0xcb418a8cbbb5850a82b77a41ed3fbaec0b7958dc51ffdced4fc0b2a3f9d36903","0xaf11bf453830ec2f4d4b9ce95c8de1dbec56651e4d8bd06b6bdff8bf7afcad7f","0x9a960a951d7de606379d7b3121c568e0e25176af9901156870b432d5786d6ad7","0x29f4fe443cbc349912bbf4fb71b5eee276210385ec524fa5cb0c39e1cd7f32c6","0x5aecb8e5cad125c42fd9869af9ac45ee87a687590bd242dafe3de4ca55aae7d8","0xe43c59bdc68c30c0e5b220980165714a39f4afd992af4da13ad1e788d0451619","0xa70ada9c876dbc18a3e6cc424a4a992b2ebba8a89f7dc07515e495dd443a7abe","0xf4b07e8019e0768af9c7a37bbba65283f993751d34aa46c767188e948a8eedc9","0xc9ba7eee45f280c2f98ed79ec01a60228e44628f7300304e55855c14a2741a83","0xbf037843f7873592ba4a03cc3f5ff6894712b97e146bba9c7f53e7d1f55de29e","0xcb331e5cb641c17c6f7a4be8de84cbcefdb2527ef2b8c0bbe31b5f2893222968","0xa4f33d33715e84a8399fe1aed8b5fdf93a4401ca401ced6642e898f6933bf4ac","0x884076f8feb95dcace1c6a547740029ba922d56539e7ebe948c202a3b055eca8","0x245f84c543cc3bae2ccd2d47ead550eff4ee0860eaf929727e54301fac068e82","0xe40e4eb13b362bdbb2fdd63e04552e441cf1fd9126516b3c80b79acd3499b1f7","0x921585e4021b9d2bb2a78f6c80fc11224cf8c81abc759c5f5924211cfc554122","0x701680948b5c7b77e1a289aa2bb3d8ac989cb903b583e9b2b06acf91a337f157","0x0509dcac589d122dda61f167ff152041701165f15603d5fb398cb2b8fb119b10","0xb1145e0c93271937ff81df90e72df0d29c705028fd1d0de626d3a62893c38481","0xe4346545f6034fad30c080df75665827310323a01202f6374bd55b5268da2460",null,"0x548b775e6c38af91c1a159fd8422bd73bafde16f544fc2a615fec3930c961407","0x70680cab123f9dd191300b3d1596615219dcf0a5045f994617e0156f9c89fd6a","0x1de4b14b8dd3e39c3a7298af0a5b2db0086198e4d22a824cad5445b3d4870490","0x07e1eb8674c463a4245ed4237d7ac48c48bd34caefedf5382dac77a24f83e474","0x6d45e885bc5f6848ab36725753da1f40e7d2eb44737d4100ebbe3b7f4d2f31c2","0xccbb7d8e506810d907e3be4f8ad1c59809c37dd796bb0db39c1cf272e48e0971","0xc9d58fe9090a82514b9ef8d27a1d68ba9fc296fe0c8c6802fa3b47398722eeab","0xa4c3cb5e1b285144117240a3c628338aeddb82adee71939cd934059037304146","0xaf1826409d146e0c2ff7f12764e53cbd46e052de5c275c1552ea52cbae8a9e04","0x998067780b5381dac504aceaf219fc97cfee2f8f852d0ce722a01650557ac756","0x0e87ae6d9eb79d99dd43b88a37bcf392b5bdccda685934da851a3eaad4f8599b",null,"0xeaff18747ed22db39aff89f407f03bb8edf287c1c5b3810bb3dd2363632dc45f","0xbdfdd9d635b7f753f1aa5c2ab11a17f4d9577434d7977c031af32f562bf2cb6d","0xe6bc8e3a15484699342d6fdefe09c135bfacb6712cff48dd3fcd39fa03923351","0x607462288eba8c8980c666848237a3a2ce06b5f1e54294454a3354e17255cf0f","0x1f7df0398965971a179c12eeb69e813caf67e6cb15b4c7d37e5328fcd61d3794","0x0e19536c06aeb5810ca6eb17fdd1dd964053ae3c8560a6df3bad51c5492ba7da","0x617ed6aaecc83cf463e5bd55f81fdfd24db5e96ceff448981edeb4b1cb978998","0xd2115b4eabfefee36b26e0a792509ba3ab963b6364131f036e5cfdb25e245bc6","0x07631ab418c6f3b100f75179fd6233c9d18d2f256b390f0150c5c9f92b924dca","0x9cd2127c8a4f214d10f7192bc9294730b54055ce9f1c84fcf14960fef369f9f7",null,"0xda78fa37f2aaf34f2ca15604f0531c64157dc4ca5e7e59788a530f0bb97e2e53","0x5d3adadb457af59c2f8ac7694e47c61a41e2e70eded89cd196cffce9422e9566","0xb08cc0a4f1457d08fc2f3a552d89bce8cc122e5332490d25b2c9865f1a1e83f6","0x1ca49388ff2a626f4d0e964b0e557d720c313d2f76ebbde52e07671e8ba1b72d","0xae4cb1f04dde625fa206b06d1137d36cfcbdd86a21dc55bdbf8de5352621beef","0xb8d8a04220ae928c5db09fd6c308b1bd8d2078ccbd41f9471598703dd597ce6a","0x3f4b520f77e30a35f0ee1d762e1a2a5dcc79a3ac281ec7896bb3ec608fcc8e7e","0xb32f981c4bb0e3dfc110a9022b9f9ddf3002c2ce884c4dc66015846cdfcd0ecf","0xed036ca3d47d7a2428dd10be615af637f75dc19fed464d241dcf48266e2f7bac","0x3928e059a66902df3f11bb181645e97ff4d203137bb48baf794abb2e30df893a","0x4f6bd29a11ecdcd294e3bb79b9b91fdafc575a55fea941e45e36464f3ea67c2f","0x084deecddad3b6b099444dfd101158408d8a22db41ca1a6e954c0b25248391b6","0xb599b39ee62f4e606d8a7a467195a864707e007817ca5bd7d700480456e7f46d","0x2b2dc3aee6d6acf4ce76f13163e7252971fa53ff3a196aee511414ed1315a8bf","0x49ab1b1ed8f347ed5e13e534cac748e3b4c629650a7f1f41a734a55ff9aae10e","0x31561c725b2ccc03e303e97edbfeba6d619680830f5e772242ddaefebf9fd70b","0xddbe7faca53dbd7d3f6e4b160fa8de357349a9df89a88917f69da60434941e38","0xd48e90c006fda105e5b538e4020a160af10d70af093001091bda8fcaad0cabb5","0xd85a85b268e520d597c9229e46fadfec7b52c07b895db152c4fc9d0e6da6219e","0x53a315a67c73e9f770aa350fa3c10d44bca10cb51da9d337336a61948890b5fd","0x41ee0d8fa2601544407136beba45f02351aa957ea995326196d6f301b57a85ad","0x044090e2f958b1f9782769112c541768c42c70bc46dd8a60c5ded096ba7fc013","0x503a46a91ae68adda3f0eec5b337ac457406b82e2628085b656fc01034c4bc11","0x52fa9d65ec740eea67d261d36ee96a7f41a87432ecf95f6d94c361bbabf78009","0x51c43395b7a8adf452ead14b38c9a93547ada8bb9dc71cede93b136b83e52673","0xdd13b9c1f57cd91d74c2cd572dee182078bef1929b934fa041ced8a35fd13a79","0x0fb719d13a82a1dd87651a92da6d10d5d94d03989a7b6fe4415453ad8b9b7100","0xff88caabcb12e4fc6b0e7537f818a9bee2ac73a5499a0da654b559a23f25e395","0x9891b451132509e0875cb034d3add83db6d49bcbe77d458fc41146a6f26f2d43","0x2f03127bc3b7636993e7fdaab3854e367a8b2a88a8bb4039c0a9c2f0dc948267","0xb22f72923a3a1c1af3c1f99e88c2886ab1f8ae17df2aed983802b0f961436d13","0x795a15385baad0bce422bf8bf2c750e2d511e3df7625daad75418cdb8254183a","0x239953fc2764c57a6c1ee6e6362d32effbd69cdafbd0ebadf0db6a516eeb53d0","0xd2159280b2cf6603a15872998c7699a336398c41e14fe1e8c7e7692f5a476b51","0x3fbca1b1bb7a0983851ac8ddd69edb42a4902838bfe1c688b60b1ef06a052292","0xad8874199fa56214f36c1f4f52fbfe5bef0a5052a3e9fe6d75488842e80cc2e3","0x041516548e778df61dbb318b50f7ebc64a336e7a980ad105a8c74e84229f85d0","0x756febffab6116ff4f0c9ce6d9aaf35aaf8dd08d540dfc962f2fc256ab2e43aa","0xd2fd510cf43598b8af50eae65f48373e45e685c245727a50f6a72b1d9f9b1a49","0x210406fad09adb81f63ed54a08e3d12d5d56741d6fabda89b7a603ad322e4db8","0x579cea7259be20bd39a058de90990265cb82ff54591c9acd5d022a308f8a16a7","0x8fde97978def9ec804bc4304d26e73d7e536f2adc7adc984570ae8403bcf2935",null,"0xa26bef1f69fc9cd1d6e9a525d65f8515c1df28cceb7afac3770198e1fce06242","0xf675fea4bb3d72dfa0b1910e4991c45b63ca20b05076cc1174ba879dd832a6a0","0xae8d675637b1309615ff1b06d19d5510355232d4bb9b22cdd78f16cafd29efd0","0x1473ee011bd8bdd9a545026dfbd133dcd3a99eb717efe8344b73bf1d54884b35","0x0d505c32c8f4b39cdb05ecef99c3c970717d35e681a774887bb370f832d89640","0x95d5b8b02227684040011fcb8eed8750bffb5b1aaeea9893bfeb16440a79b8ec","0xe5e9ba71a32ccac3b737e716ace0d400a400eb8957f0bc20e17ed1d19f0172fd","0xdb1e3469b3c40f10ba181bdbd803537362bf3cab1598a69065ab805b5230eeff","0xb310db964d55b411cc157b41b7efa42d46d312723ecbafaa7bcb37fdd7f83857","0x2b47ec01f4a58e887d7c66fdcf671e1b90f03a958dcc481ac7fa0966264df7ed","0x8e0bf24d65c9d978bdd7ad3c57430d1d22dfb5dae85b404d8d282ab156e930e6","0xe498cc6f2a2eb9a52624d34fc6b4f95029a21ef99b0b24aed4c48b1d1c0d72be","0x862d96467bb33c26ea5abf376713ca070325b663f307d7a2f679bd37d32f70af","0x59477032501639d8e045e71b3890487412ac2e50c54d39fb39efca04e58d4024","0xcef6c2cfc5cef36987c51a60f0957d6c8f729dc3b30dcaf3c4a27b4454b97427","0xe17402b1a4112ebeac8fa8083636373af6bda330d74475fc6a024f023d1156c3","0xe60f31b9f393b2da50032565abc4eaf21296fe9b8bbc05e20058dd0dc8443738","0x7dda2897eb785e5f81d699fe52d807b7220f905bba9c085d260cad450dfaf2c0","0x6c856b48be9ce5816f95fb1f8a44493a633a0e4afca70db7c3d144992cf7791f","0xb43136740c40e0e0b8b8d2ed825dd3601c9894272ddd88d0348c500bcaf21cba","0xc42b98888856d9441ae469fbdf738938d53e1b0d6adc6f5b5fbba22aac181d71","0xfa807585e8a3e9db3e8db2bb195be3fe8264867736139fce9df22bf614306b39","0xa3f37bde0c70012c042ac479d308d693091d41a32eca668e56e04e828560338c","0xe8066348363715eec128ec591ec0f267371ba5502b057ba1054a1fd908cef9ae","0xd6a28a527c0ff41d63313d05de7739bf34d11c0ef34c58753558f5998fc4b514","0x295fb7431a009e10f790292ba51e48add75ce8cd019e6ef8a3fd37ac5f7d6a93","0x7ad6fa318b21ceacbd64ed86b794bd9723b539c9cff5745420be4420b4abc39a","0x6cbdec15fd5c946ed5e902b0ea33746e3020179cad308cf1a17f5555b1979617","0xe5fce39412179bb6af19bf77acc4ff866f5b9f8c485f0d219a0e2e355cafc38b","0x9fd076e140dd3faa1cf17798fb597a35e014b2b48aeefc60eb3407332cf2102f","0xfec9afc530f39cdacc7a82915e66df17740e6db068000ce50cdcaedb95dcd1d9","0x2ec904c3a92982efa64176961491143a1620293759dc2edb6bdece5b84db6c64","0xbac5115c9c2cab8f681e5cf986c05fd5c86d4751a03d87b8d3acdc476b5e3004","0x808ee214f59d808e2098307ad5ba07742b94c6dcfff87fb1809c8cb8bfdcc805","0x8d4d9c81f5b7e27ff23a67b39165b88df09e84b4f63dde1d51cb751861177528","0xd4d660497be9afafe0be31474565a971aeb767a8a57d1ee67d8ed5e20533c548","0x6748b9631b5e822779b9c189658d070768c795d1ae07535c2eb8b30ff737b65e","0x5bba8eb1c9252605026154bf2c6a364cce05f800b2391062d1e0886c95b61063","0xb600a1f4ab31ee6acdc1246b806fb74f0aa2f7a30a1aca3690c62f478ec9904d","0x550228a8714a8e4fa13c2ffec6bdc262c1de18a3fd29e99abf1673d0146d504f","0x36342f9f9297fa149d8a8ef35aa81954e7829b64c8269e2a5f7a57773016b17a","0x1324b642ef0f0f85142b4a919e4936ca7aa8f9c9bae3cf810545bdc0aaf3efb3","0x0f7723176a1506970693f2946bca0a0cbc91c55a3bee8b1d367bff08fdc88cab","0x4d13c5e208a40e6d368b554ea862c9d4f0e0f420f003a315908873648a1968cf","0xa25b7ac6281d73eb8fc3d4a13eb15eec3c9c82ca081abf767acfebdf13d79754","0xed1c4c69cfa483bdc7cdc33f38ee22cbcdda47e3a5c7485ac2f0b89653690553","0x6be194dc3d5aa19a6355e71a2bf96ffde72336f6f0c03c9238981632320dc597","0x87416c1b224f3207da9ae2091dda7e8bbeba5d912fe2f8dea8b3405b666389f1","0x4f705c5cc70016f24b4398e5c5d55dc1baeece8b2751c055ddb65649f9b3b9f0","0x08133189440930e3638c279726b7c8949b7720ac1f614522a159c5e5eaa0de25","0x7ad6cf83c45abdfa4d031fa211dca189c3ea94f7c40ce0f7d1c8055196649662","0x3fa8a0eccd57ad5c0867f45705f1f0f6245e5bad9f8a6d3015ab2540905602cb","0xa30518daa29193f2be9ff543cc6ec97010facdec0380c3714cc05ce335c966a3","0x3643c11b13b4a4179efedd0443055f4cc1e52a14c6af6bcdf1fecfa38caae223","0x19cbe8c826c3d362901e79f6b7c6f5373bb88dd614c031c065d4ff2c7072ac3b","0x0797e5d1d78be0bf903b8c54208d3178c7ca4af1429213b89c61ae47aa1b3194","0x6b1972be0ea324e583dc1df8297aff8ca71a30a0f9981a4f429cc89e23095364","0x59bccc690eaae8ef08a3ec3e64cc7b2561539c210dba689de78897471a72cc60","0x48e4307a2c76d9b13d839d75edc7119ef0cef0db1fde439e9f36415a78b7ce3f","0x85946bca5996707ba5f1d5b2b3b7f7d50cdf442adc4b2f7314370761cbb5afb3","0x3221d3e116f6a2e92b64ea7aed7cc0236939c877773b946712083d8f545d51a3","0xb34715fb15ac8ea2e408ada7c7c6d915e5f27b33de8450400a1903f02c88dbd6","0x1e6623d45cfa7b8dd67ecc0e91925549664b6ba9178c9630aa327c31a853374f","0xce3315d2d974fb565ea01db5f1106dc0a1f7cb15e9e7c2f8ffea937a15c807cf","0x9818f8c75232572837c44e8277335d35a337a8f281c574b942e906513a2ebb89","0x0fcb554ae14cc7502b99c725b40b0b18530bfb7efc186b17e2e14966cfd4978b","0x0a533770e4ee642b6fae235fc862e6e29fe99b3345653d9be8422c569c3c9d17","0xd33e2837434de5404dfa95db47f276591075bf3642b657518cdf3b0d49b00bdc","0xaa06566acbc1c42a307644291cbeb737371f9119c46b3e0e26bd75fe32cbd88c","0xe08e20de88c5cc8a92a5156a03c07815972b105e61f61daab5374a2c98aba722","0xd44f6b769afd912155fe3df405e11b0f11dbb918fb542ab71330694970be0ad4","0x35d85de5865099329af244a3acf15ba3b1b1559d810f5d0e3878693a1a492ea9","0xdb8189466b8af7ff91c7b28832188d87b9651fe3425d820e5ae2e165309662cb","0x663f3025a306f2e246f290e1d427394d85520d75bf0e6f29ed70b0a50be98b2c","0xe09396f9c46cc40b5977b55d779a8d28c7fcff9e56ba9c31393b684f264d5d95","0x12fc4960e057524ad2706a7fece48abec524a6451240b478ea6d1cc10eb49ce1","0x6edab61a8cd527e7196d5528710e17caef59a6ec406cc528f0c2f97ce207388c","0x636df4e1b7d8af6c38e66a20082915cf0ae3e723cd7aae942c45cc04a4c63828","0x0296eb00b74ddd0ebfafe5027c8c7f1b38360f4ae20a763741fe1af74638eb7f","0xc4a061d8c9d3262baf6d2a7ae8d8fa15236bd7afc7feef3afeccf27d50f90688","0x2f7ac28976eb6420a95ec39117b0371bc50b6c6fbb8b1761ad00c06cb1ec9ee3","0xa1e913de4e349638e220811a173c5b45c83661dbdc6624476fc2eb611afdf659","0xaf667d959ee7d4523cb7cf441bff99c3171b71df9b979f78323eefa6a235ffe8","0x235baabfea001604a0b1a26c26dfffdd1eaa830343d5366f7589c855f074e93e","0xea82ddb47de68eb56d3d8e805f3db0db8713231fe435d491a06f15297e36cf5a","0xf40eff14de79535461df56b0f9dfb320d7929778194614494cc55d7cebff7f29","0xd7eb66dd495cfc7024a3899750683fe6321d56179a26d91fd54b27b2b446a1bf","0xb4f8a26a65dc21a6d88ab1d2d2783dd716506dc6ce0de83f7aac18ce92b4ae01","0xaed9c8812e5366d2c477d11e3f63fd548a8174cb73e127c0c9a3341ea08eeced","0x4baab3638bdfc6928413a658ed0557c498519592111f02bb96b51097e7cd0869","0x519fd2843770ce9c114f38cbaad079045851385270c4d9039cdd67027482c71c","0xa7e08905c7d4c5941ab0efd21323dcd829ba61c8f74917574104c9eb0513dbad","0x55be25d087dbbd316814dea3766ef7f1b44e746f5e5454568db626e52fb472b2","0xa1251a51bac6bbbdbdb5a269d35a6226efa0186fbd37b3f12b37c0dc47becedb","0x29ce6d1a66c90b21bb07d5ec4edf75708f6b935014c22b6b388eb796f195390a","0xd2edc03b6d08a77b6c874be2fe68b101890a34fcbeb506266d4a453e77ded5f1","0x78cc38d1be6320f7529c7d870e10c16c314518ea1229f8470b340a8977022d2d","0x44583681231d17c7ad9a6fd4bee9e3680c89d6137088d87b29d37d67c6ce2624","0x2bbe761bc7e808e103ee3daf88d0172c2927cd1467bdebbcf52731873ef851c4","0x9e4f26b12fab56ca3e4fe74723db3e1bae21b86bf5cd7253cb1877170ea3b66b","0x2f010ce3d59e27ed9a5f40727ff433f20324317dc110e06c2ab2bc02c55e1a22","0xf5cad3fb08ae05769b8e3c251a3edf1079ea65000a665e74e6244ea4dfcb5093","0xbeb3b943c69fbd826394636c7a37334e6b81e0693b5c6a0db893aea87fca2cb6","0xf3c05d6cfcdcb27fc54e8eb8edf72999f6437316e88504a03fb3a256013be0d8","0x3f9c3d50fef538e5c0c473faf2eb17ddefd7782eb3d74db0adc8f0c438ccc0a6","0x595275a03e93d8b1be5b3a38b9881274e598dca5760100c7d9ad9e7a18d20f25","0xcbb8d82697806899c5edb1c8eaa9c3be364c7a91800857a811775a6abffb2092","0x181ee53074daab12b2594678c1495b426ed72dd78c7735fd97182782ce1a57ce","0x252bda51409d2473d37bd5c454f0cbd1fa17b187c804dac365dabf8fa06d10eb","0x974cff69672a484249e5916208d66e72367b9393b66a8afe3e2fbb2b5773bc17","0xd0fd60b496479c0b28d1433b9fca1de0a7fa7ca65984b96798021a6f844716de","0xc599d01652dff363502ccfbab9066d51dcec3b3fc5402aab01cc27f8d0ce3931","0xb4ed2c71322ce6b20fb0b11b670ddbf3ba8ba9994915f498b4efb5425a159b3f","0x7448e1d60a622f411c7f70087bf272985ec32a4ced960f7dbf95cc682e9dc3f2","0xa6c122788995e4a2e03c97aab3883a820232b0e80ea716998f3973264106e476","0x499c77600b77684709255b46179557da4c59dd4611ec00599ac21f05031f7607","0x56545d6b3aa1ad95cedaab3efc0dde82b3e87c4db5a351fa7fe6970f8ed64d50","0x0ad151662eb47bec396942c5e1da532d720a2e078b273a8a88b9d87841e0d2b9","0x1f2d3288bdf40131c58c6aa657fced18cd5449657a79ac546882390d411c25e8","0x1f8c715a8566c80ef21d4bafc4416c320b62ed88b513663af1d7eb25585a30c6","0x04b8f1a823b31c6cbec1b92c036061a09ae23cb655bacfe7a9a0df55f6b0b70e","0xa34008b10beabbcc1b66f45f613c114287426f1ef9b66965419427877b8b53b1","0xea122c8cc8eb120c2d5a863c5045338c697ebf05d8d3c4caf1384eefa2a82393","0xae0d4d31395e67985d269bd8e2b58a103ca63b1f315b7bfa04954f12c175a936","0xe4f47833cc02ac05c89f6aab583646d7e8cd952c568eedff42f0d9a5c110be79","0xa07daf56546d5c66945d6dc41916bf391ef84d5049da26af461a5105fe0cc7c4","0x9af4bba21d3e47fe8d3cf1480bd3760f5fb442d01195e47e0039c637e3d1f8be","0x4a93bb0c8fd2ebe9d5a0936da123aac7d813192823de20004159363870c14ebf","0x28956cbd139905595c279fe21f73cb4c03b840ba9c55a49d546d2e69980bd51b","0x7895d6a36e0139b8fa0794d9e86cf6bcdf99a1968bc26462e674bfb7c64fce8f","0x8b4d6d0a02e5c2bb771b688f8d7b041ae69bd69b5a9c36a15d54866a83fc88cc","0xf6e660dfcb18573fb3bd4e6bcf899179fb4002347fd771bd329bb774a3eb3b35","0x692b91d84ad72e4f5d7c76f96517f4904e7c4a70439565363a9abc59abd82645","0xb55fc09625eac0052b8e60fe9576c5d5e9a5b8ae2a82185509d1f290fb59540f","0x4656844be6b83554f267938d9226ac2c190c1e53dbdce1e9eff6031f07610218","0xf36022d80c036e3bfb210214b24610a3c56c743f1357d3e786cfcc07102d2bdd","0x3405e618ccd6632ce51d4786b066256dec3d04d0343f05955ed5ac17c3a1f518","0x5bd4ac3e1da24d873697bba29877c50bf575ec2227530ef42f16a25747a2da2b","0x15e9cc147a1fd4afa2fbbcf48bcd1cf072a1a50302f92e32707350552d4402a8","0x35141f2410346da3ca0151bcf3d5e95c4adf2f3bf8ea3f490a5723164506afcd","0xe4a400778b873fccaabbd6d79c2ff6d19375b220cd71ee99f59ac85377014070","0x30fe7770ed32d0626b7a7ec6e3f8650194e23d963b261052d5c05c4ff3a8f695","0x1a1ecf02b3d5481935649511cd68bb3d54e3df926831968a4b51ea1cd04ca1f2","0x5bdb3f0e8387e95d649d9e7be217922fe350a40acc57c14f36890db11626d61e","0xe0d1f0f6f6f334d4f849383a11ee8d3a34e4cf6305b4b69baeaeaa16acd5be59","0x983f4158864e1fb60cbb0dcad52c9d286d5b120da586e94076e7518943d43c33","0xca55793dea6fc6b4517ba45171edfacd89b05b7cc998c99cc8723de22ae3311e","0xcda01de18d87a7f8bec50c09f25d54aad015bfaae965ea3421213784d730a0bd","0x3a3d5d6350871e365271c20db63f83181d0e4865721e8a6b83f60768de74d494","0xca49131f9d98eae926ddef50e509ea830f35ff62da8bb81269c880650a8c1434","0xc4223c8156cd4c539ce10ef2dbb0608945901eacba30e8e3f54516f6c647cb03","0xe06d2d821d15f991b0fee3de88a9b7c2ac2d138d3596fc13c734e6766f95dac1","0x796670da62868728ba8a089c0ec30413e49c999dbbcf8b6718f9b71bba67ddd8","0x20a4fff92b113c6b03652cb20d695537b618d3066106e5a98f1736ae64172ef6","0x9968128a6d7eaa75807b7098b8a78dc7d7855d7d1720d49dcd00c14be9fd747c","0x3e7dd2b032b8276d870a297a4afd6e1ebe5bfa59537d327d54e245e4d6d37e42","0x1948b6c91bebc99f768a99eef0f36cf73a47a6d8bc985592895187abc3c96f34","0x0ad23c2034c281e092060e5ea60d8e33227d69458fd5fd5bb5d1561fbc448be7","0x23b30515adb9e579147e4b565448c0e7f0da95a81565517f51a617b6ae267003","0xa308270f3ca534892a4c652c26a0b5a729da44a1d7bce7504ae31c5806fd9ef4","0x5ebbf471e9c325e3b26cc93b5207a869d9cf4cb62fc87fe600b218035e6be770","0x4ad13de8e30bef83e9baacc44b19a4fb7eafb4d67e66c6d14b4d44d15d56cf65","0x2af217c3aad3df7f9cf121cc7c950bed0c49a00f46cd52989a0b4a34def4dfa8","0x676bedee2f043e057c5aa18f98f9d7f70cfc0944c0e275a6b8027b1dcc0a445f","0x5f49434ce00acaf7d98a900ab5a7dab53d449400b26568d75081faaab3e2aad4","0x4e6354ea4f71409c2d35d7c58f68079c9cb4dad8994707479c5cd6834df31d8e","0xaface5cddfb8976525e5ba4de8f4fa6312fb58b0fd3749a789d99a00afe17f18","0xada38225ea7ad1b22e9cd7bd07988fc8bbe87c3a3e5b92607854ae40496c8b8e","0x53bb7eaf065e2cbe330d8b89b2be1de436b6b9edfef293c4407a903a3fc59cfb","0xff6e5007ace4a475c4c1cc913438b202743a6d541b00bc3f02ecb178870b71cd","0x9296f6eb357c7b8c8f465f2bf14ca0c0574f838015875a987e517fe524a3af51","0x112d9c11169cf5d82487ad124a46252c66152a9d872d90672d8afd96d010f9f3","0x91d86818e8a1294d3e5dce87b35dcd50cc2ea3279fc677718c53c05a56edc421","0x7f8876ecea245a2975c1ed0822bc505d6d9921328ffe0d2c702123e28bf28e28","0x7b3829745c80349440ebc4cad5023e0aa0453bd979e8d674d07700e09bbf2927","0x84842f4a6391036f49e01409128d298e60b26cdaf92a75fb020df83356d71a19","0x7b94768da25042412acae1280cfbf2652877038ce5dc9a1cdb40bed1f3e68360","0x8ccf49aeb36b49fffb0b38934c919a4e2ed8ccf1bcebcbc66375d71641452be2","0x4d7c5019a2ae6c3fba7a4d09f50f8d6599ee376ff0be124c84d6c70fb053f0e8","0x95aa4f247f4efeb4e0530cc91758a7f65ea039787308bd526fad8c6456424845","0x90fadf47edae0b74a6815a1ca0613048783afdb0031fbac24c4884a70fdc5f0b","0x6d4d39ab338ecf34cce027a457837a28d486c2ac3b863c6c9ac61a430dbe36d4","0x71f290f012c43a8f9659ecc9c15eacf66e1203ee744c5c870d091ee74d57f4ab","0x25224e73a62ee59f4c0f4706de2d7ef3d47bca1b8b4a61f1549c60cce8947849","0xc59177f191969e728d292d9f337b90f1b23db748a538cb79141bb67b2494425a","0x8ab6d3d314ed3ec58ff5658b7d1e9af94d50126c0c03981143e35e37e6210577","0x1b8b2a074ae2c84357dea772a5c8600fa26661d260922a4c916123a3655e7950","0x11ed6ec6883bd1fa665e88cd52c1fbec2f1c0b9c2988e8f2c7ce83d79ee24a56","0xa6ae78324cc6553b878b91ff88bdd0302b8e5a102f44b688fc99ce495f110520","0xf2dc64d694677d32e1f1c7b0f24e3479d634ffa0e1e3112c9d6e9a96547a9e7c","0xb5118ca7951985ed591b2507229bd82a92c30d8d1a2e953ddb9f8b3bc9a998f1","0x4d145fd77d0072c9c3cb8fc7b49076ab36ee9e1203fa7e3e7fbcb9d3a90c2526","0x0eff332932ae434fadefc52f7617b4f725356df1b59b31337379cddd75aafb25","0x3b2ada2d42ab5ad141b2af0a3449f40ccaa0f0c15473bc40fcfeeeb775caba8e","0x82bc2b03a31a446438973aab21951348c40b4bf537457e88556dd7e6cfa40b61","0xe264491b32c11e52f69c08deedeeb12843f1890af2e1820ae24801f363aa7cec","0xb30d8a4ac278eb38fe61d7ec55bf29a1c4b84c91516b959400f8ba9d13379ac8","0xaa1472c8eb82f69fb4bec04c31d5b878a1ca52281c4ad9ba0bbedeec7302e027","0x363efc59897aeb29f3329a25bb30f896dfb42dd8d42a63e149a86610d5f5d620","0x44d27552583da0e3423b10799b4a572dc769c98bed24d21a5d33a521f49b8254","0xe026ae501ecf684eee1487d58e69c41fae5467f40345f6b778c938f6e0c9ce3d","0xed8971dc219759008dfe268577db3ec4aa21bb6fab419c12b9ad6d9776ee9d5d","0xc5153a5ee3ff5ee22275887ad7218580de1a193243d821b85166bbf981bb8887","0x538fcdac5ee56137d8ecd49d6772e07d941834d18e817d48d25fbffba5b9eaed","0x40b7c20706b496ce728313fb0037d01c82e175aea361aeebb51edc3cfc247e8d","0x55335e13adb9ea098ad551782b0e75d03a246d29c47d0c9c22c86b67787d5297","0x6add885bf84ef8c8099d4ffc32a3edc9c16a6454b72fbb4a432d523c5e2c5756","0xee48e07e275f12a6ae6a1ee8e3781faea1a197c69fc5f1ede45c6852445fc219","0xfa93da79d2f54509cd2e9a5c18ef48f78f7aa544b61695bfb09d2518240651e2","0xcdcaea5889dbe88713ea614759264222c001ec390fd2cf8e7adf753eab429bb6","0x051438e011220ddef814a035df65de71d415e9e949acb19f4e74b1235597576f","0x2df80eb232d4f24bb256f7f0f61ef5a72af409ae41de00fedfe8aa81917a3c75","0x13bf71e6d65c05c94f1d58f39c9718d27384d96ffdc66cbbc46ee3f14a85b95f","0x2dbb891a27b14088c6595d9fdf489fe2b0d99d268f58084cf04609ee21e0588e","0x619c57f000b6f0e5ed8767d05a1073c92faf28c4eef782378439260af8a655ec","0xd930257ee7ed2bf51f35d126889a695807388dc2bee4cbf7cd5e1c62da4c85ca","0xadd9d0551b16a21893fbd2bd75c3d41bb548de58f8f726be586da77b712f09ad","0x9edb0c59b9424121d754331d0c8f8dce26c82b3493044002d908feb5d0130903","0x59f7fa25bdd205ec1aa28fe152f95dc6c8d2ba14cb7308c6527d7d110baa48d9","0x554f4ceab3755d5ae3716abd40ba4004084703adbad9531fdb01ba2db366c018","0xa6e2034b846b0649a94f5e677dc1a497598cdca6264d244fa0cf56e4b9753e75","0x7030e5cb45dba12de44f50fb5f77b31ec82bd9f1d2fe453aa553d54e86b8812f","0xe4778c6610ffe6772d8532ea7d75761be7630845c11c0239461f8e6c2a7d4267","0x76d9c7ff6768b345728c2e844dc0765e6ceda6fc66001751cf88f4135be5cccb","0xe5394b8db2fa3502afdaebde5eb76e185ee555beb577159dc7095696e0cc6292","0x8c9d22925d2c72668ba6687345a861c87c20775b2d119fd53a0dc9defe1ee247","0x9433fac859d44a80f4251a225673988e69cafd4826c905c36f3fb2de6a608bd5","0xa20a8afa175a1737f8de03099e69f4378de49c19bf999e528111793e12cb8825","0xbda4095bafa7a06fe8c81d7ad1cbe52d0b54f0aa7c67cece50bf1a3fbd333c07","0x894a623a9b9da38b8f5f1f1189df089736154c622dbba93ce7cb64b37480612a","0xb2a5d574d6d34d0cdd5635ee7ca01e04bb5e07b8d17769ff4dd34cd683b16245","0xc9cdcac1c5664ead5f67699a2fa4a461eff52d478f46350bb11b874e8e7c807b","0x01842e9ae306398bcdf5234cdb7c1116ccf8f41944803ae7b0167b226a52ee10","0xf6e6732e75522b2e4d9ee5f21559db2c4f75cb4bd36126812514bcc349cf3be7","0xcf45e9a182e651fd7c739bb73e86a6414a52c372bc0edd26dcd322f5e1b5bd21","0xf51b2ba4940beab2ba90991cf8e4ef0a565342a8f0eae61775d6ae5e5c4c3283","0x88948eb8dd4ad67c960da29430849c4ce19c92f587120d5217063ab58b7de14e","0xc246eb3d1a9baef5084093e9553352a6d46f7de3baf437b5628c5a36b0e5335d","0x144105ff072d5c81ff6e31658e8ed932d11ee0ba762e83598cc5bff915e50a30","0xe92804dfd8c3b63759b93de79cc414884dd617d5bd9dddf774952c956c3b466c","0xeda6eae478f9210eae91d03d812dc53de793f993ca2ed537bf6620fa4f2b7fdc","0x56b3337100d19a0e212a4b97c69b19bec7e9559dd8c075cce6429dc39d14af72","0x6ac8d9a80c9d978926024f60d8ba9538f3ac967d22f6dc1802c8175ff59e36ee","0xadba8639073476bfe9ff035b38db0941fb687a9ea71b2307f95604a808bdac7e","0x7511ac63a9554cebe9aad384e860b16c0828615e9410d8ec0c672c5510ff416d","0x834cd4ac3a62462513d6d8dc4cfb23d3b19302667ce824d7609fc43310746d2d","0xb986be1e9065892dcac4e8303dc77b90de3d17d1d972e3d1307075fdc39ab017","0xe39b5bc786ff4d5e5065757b00e45a8d8870f646aef151c79869ecc6c79fedf7","0x08b6f733dcd6628933377edeba78e0d50bda913801bc8dac799d5bf92fc1a161","0x15e4fc5ab0a061866980a5bf9cd49a8ffc1a4ab9be9fb87887819bb5b0971373","0x1f8b081d2f474a1835676fdb901897c533ceace6ddd0d62162a6abd2f4350f87","0xc45113d76810c8f8823f7c771ba97d4d9ba8276592c3849be3ae88fc21ef32d0","0x105c2dc2a5e173148ad1dfb35c877a0c5722ef3d31d56f6cd1c677e993e84a64","0x9ed049608081f28824501ad66f5756880fa31cb10710c1fdc0f016ab456bdacb","0x99abca238c9ac5e1e39a227d1e683db17b7a3a93711f2f99c6269356d605d040","0x45b0d55f94c157d8f32bf6ef81177e2c96a730ce423eb5263ed95bacfb52813c","0xa75f6cf93d5e21cbe65ca3b35a148e010a24eecbadfcbb262ff3d7adef691995","0x60471e22a4412277d71b0160403e0ca05a103d07d7137e877fb1336f2e193c8a","0x42f05bbe37a39cc48ff62931580040d6c89fdce27cdbf034d20d05d39c447585","0xe17ac2a3b8ced1124a9a4c4aa057c549efb2e7a54b905a9cc8bcac24dfc43fde","0x84a692f06d0684ef48e66e83eff3c8bd10a836e5bc94a1328540575030d966d4","0xb8b2d53393e7146e940357761e97be2b242c0fb2c683259c6dcf745082cd55b0","0x684b0143a5254004d9059f79d9f7c050707fb1078c3921e5e96417110621deb6","0x56f8eac37acf2e21ef72f340d1c710c98a15fb00b045e3174ec2879c009b6dd8","0x2e83f13e8a961c0a14270ec761cde4cc6f285d732864bf20779355e05d9a5481","0x4a88aa0013df52144cb0ab92d9bc98153b1fc943d85b9c149fe46b996a68c692","0xa59535641f4086acd4067a22311e264e25900d5e159df56c995fe06cec33049b","0xe529366c1bb9770bd882efd2cac89134da3fabd0a19186b50c50f35e82dd6861","0xb1b137b4c39b768d39506d32892b2315965db25bb3526e3fa1b7266ef51b46d3","0xb1bc4bac9e493cb50d88e32a7a7daff94332e07d73a9e5892bcb3de838831673","0x85df23e3dab3f4a0c8a2c7e0af662036821eff3e1764e1f9910c14789bd1dc4e","0xa6e62279da387962edb93c44f38c2e1e89171494b1cac465a101af3c47e6dbd4","0x6c2a10b33569e67b0ed695bee2eb39aea96105fc3f152a0d30289d25b3ed75f0","0xdea3c2fa5868fc1aaecb76798e9448d403c895c40db9cfe49ab699fee7e3cd4f","0xebc244fb4a5efb1938e7b882b019ee54624d0deffb42a4057bd31d4f763f8bda","0xe6f1265961016a1a9cfcf0d4284c20bf85b88382261ffa956cee68feacf7c48c","0x2ba4b260d48c32ae498c84549a1bb90c0c53bb1290ff484dee250284eda55f46","0xf143e54372bbe815c1b627460e3c9f4f350be6cc2e8053961552d5c986597b7f","0xf02c5b46757389d684017a4053ea46588ceaad9f62c3b98920f624d5299f98b2","0x9bafd2f08045e9c9081dd79212437d0b566ba50b92a00561b3826c3fdf91e63f","0xecbc870c7d6baa6e6f0f8edac2bb9460832683a7362e24dfc49fe898e077d993","0x0b2f5140c6d6fa90d6bd41d770afc5b0be9c3449b5cd65f7029210eeea32b2f5","0x7ffe85da0b00b4b943a3ce628227aae0b6e5da5a4f06ad6d0f3699a23aaa5028","0xfb449e2b64e625c9e9740949aabc6b460a982645eea0fca27917696b25e9efca","0x66bcefffe97503a49c8c5a4e9361f4b2f7b8f8847a5602e411cfde179260d0b8","0xa8ac3713f360dad23affb1343f549c461803bb8b6c7df344e7bf4dbe3ce33cc3","0x1bc132c7f521750c30b480b7f2c05c314024adcdc4de87bb0e86693da5490331","0x8c4c4437bc6be48c7eeaa71554f2536b71936e0eb5ab25bf26617dbc8fd7edf5","0xb52843974876b3fbaebe96aa3485a33c0f485628b4ee68bf205a58078cc18061","0x67a5e17daaa87b484e82694ea508ff04cc9dcafa253c80dba7133b67986ee021","0x0538ec67b9c688952ecbc46357ff8d091e380e7aa05cd1d0d56cb6acf6c051b9","0x2dd3df69c8f3455a5330ca6c523da42bbdffdb12c2b9fabe813630732642b1b4","0xa36618444cd68f7350aec7f5a25969fdd082f4c7b831e603c3b2140613473e48","0x043fd055dcb3144399334ecf05761b69d5235c9a4b2af7ccd02c52ad35df8a87","0x4a71052fd147cdf9facf7479583ec614fc97c5cd7db0de293367389f7c378dc1","0x01d64f0a8690f1a20c50b5f185bb0a3281342ac00c878fb1236aeca694ac7b19","0x5eab60cfdae22833b88238f2f21ce7c87ae0e10581517ea97eb2054198ad6746","0x6e8b63a3d99065ed1dcb19b49d9ea5353d366aa1ddde403244968694439a2a78","0x0b56043d25264cb7b4510315badc70fa3b2fdbc1837a374ecf38d986cc7f7818","0x77e271686cef96693f7f442cc221980d031218f4ac3406229faf039e47ed3a5d","0x8f3ac77e6e60f2154ce95c6bbca697107bb0ec6f0114232d7674f25aa2e07bb7","0x464dd9efe9521622522459ca8d38325b7b6178ab6b784566f284e5f0c05bc818","0xe675da2566cd2661912c059acd072f63ec1485a60ed1df9cdc2d40ab02caf83e","0x9fcf81948ea04f10744de10c38a9d65d4cf1341cbb8b91018bbebbe78ad2e884","0x83e34df468d56018bba36090b3e2761dfa164ea0459359468e304c24d762456e","0xe93880511a9c8841fd2e689b003898986c10c6d3a91b092db2d2a8592552e4d6","0x5cd260cbee3a58c0a7e6d95b03cf6cbf1ecc68d5b4ece788e614865b4a1b4f21","0x1c416fa01d4ba43b85b23cf642b5f4c1bd1715ffc75962d629608399c556b216","0xb94f158da574b3f60665ca08f2eb8cfe834097750f5a2ce19867966f8ef333a5","0xdb5952934833e17efac50339788b4b35ad0563d73ff671b5b33fc2c11b8204c0","0x20a8b74b8a517de62eaa6edee1b2eea429ed8c21dbdf245069c23850d315bf25","0xa072ec6934087b9f3a53eeecdd0c9951e6199b74d779bf35c05cf3bfcb3252eb","0xbbdeca4903b6ab13e733c3a61152b10bff1c6c26325d9810a6ddaaef71ec9512","0x84142e0f127ef0f2601fbff8d43af96ac33201aa689360c42e984f8fbd504890","0xdeaff8dfcf67900df2f3f7b844b9c92ad39c0208fdc4f71d15e727675724464b","0x2eb4c0f0293437c8f48007ad40f42273de36d454e00d3112e12d5aba8353d064","0x3a046a6d0747bfa282975fea37befc2fc82e9678ec929302dfc354eb774b424f","0x5c6949eb6d08e9b0ec7addb64cef0136328f5bc8f08e6d5dc63127d62494a6ee","0xb11bddeebe95d378d0f823b9c219f5c24c33caaf670a9ebc957bf79954f97c8d","0x512edcf64021367946b7b497ee61a10d6bd5509a428252805346bbe654ce1201",null,"0x2bcb1dac0049e6f7c1c3b985d2fda58e76086235535e42a639285b50f991c2d8","0x8d2d208c47a0dc7426ba314f5ac09858bead0a4406f73195b42a742534351ca9","0xfabc32e0588d42c64e84e0b53ea0c1d15873e8fc9288edc7a4d14a27481c47e7","0xfff00475e1b49df876dd137c36d4f4aca56226cf34f82eace008fdef4d6c0123","0xa124e9d8d12fc5c0aa6c79961b37e60f3b510b1d46bdc6da200086b3ddf0bcb4","0x35ff11cfbc63c50634c37303ccbd5ab9852b95b8973508a89a3008ae15b4230c","0x647527342f2b65b95fc33497452cb7320c2a6701a0d509ac609075ddbb1684eb","0x447698529fbf5d025e32aaa4c8591e0654429a9f638b693afc217cf714894e5c","0xde4853a740fb55620fd199b47c837aef1cd511fbad84e88307384547a7d66169","0x5bb0c96174a3b55c28f8170d643d7f47bc5fa4c5c1a934eb20c0975f20baeeb8","0x108c08ddf885f58b4e94e09219bdc478ef844f12804daf07bf7741954c0b1973","0xec578775389c0ab3a89739085991fcbb37317d93f47e86d3433c2b7bbbab2f90","0x1ecaefbdf299f2bb13d485d81e5d79fe93d2955d090b02414e2aea5b7f07966b","0x74a66fc11e5c48b7aef5bd02d3dcab6dfebbca8ddac5270c7d10d9ef04db8ac2","0xb8c5fca2c3d1438356b6c9ad15b461c62c37ef7304f421a87751a9bc4b0657ad","0x0037f0f50841db4d5c591ca45a030cb79004185c2c22e700be045efd3743dda5","0x6993466a80c874c66ad9c90a76af4dbfe49558afa5a3f8a6d33f93393cb360a3","0x95da333d378ed9d6ca707254e3b4f6ddab253338dc34b342593c4e093547acdb","0x7a1e9e4619f524c213316b5e94361939c04ae63b687dd3f265c2006ac7dc72c3","0x71a96755e23c87e46f447ea1b93913fc2d6f8c0db860a293dce3dce5730b03e5","0x47fe36d223e88c158f323c96d65588af74be8aa99b820429f7caeabf9b604bee","0x1e715926775e057716b9acd673bed0a0c6af775ed88793400e3ca373768448f9","0x28d00c98973d994238130798867ca704e7f0c7cf5842e4912e10fcd3ecb2b7d6","0x6d13049bf0d0040e656d414b6e4667fb22b99ad98b744f577c2f77a20728307e","0x47cae99fdf51c07d0e19cff6b7b256280c35539757e10598c41580d99abb4ee4","0x8003ab677fe642c49130161ec2ae3af6efe142bad15734f2213884e125f3c7e7","0x330e474a9bcefeb6a211d78d444b046418fef1c89c2ca57c71442cb84849a6c0","0xe5dbc4c14a7d3381c9cef56605d169570ea032fc84fbe9fe3981f8201e63384f","0xc45eda02f6e3965268a1eebe24ea2314c46f340d791b9e70082c1d1c6d8afd21","0x8e225f5832e0a10f646c45229bc7e875d81bc1653e9d95498691e78564d23888","0x57a2f03f2d3b52ac23c37045d15bd78907d8bfa9ea3d42844fd4d7b28da56986","0x2b8280598b3d96e92a861125e650cc725d5e4ff2b48859c8dba22fcc93c83f0a","0xf46ac71e3104c3462549d9477b31c59cde632e288eef6de05996c2a364a8d020","0xe7edd7e1dcc87da655236c1ee9ff3c2e5fc69512416aa5d2acd5a68da334778d","0xfb1c3bdacfaf5394d1850b3759c87c6e9203f5ac8bf5dcaf8ce3778c4011a5d2","0x5485cffd80c6a762248ce355e3929a9b1c94973627f46fb8112f95368594c2f8","0xa2fe5427708fc22703ea81c3550b55b5a27534db4fb9f02bb029b9f7d50712c4","0x5861ee465d4bb44653454b8c578ca5098b81b200d88e0119a2ebddad01533262","0xc84b243ccce7f1cc84d18dd0a7d7f85975d7061f2fe91107691d7d7a2c680317","0x0c0ea9f7f0de1b85439953dd4206f841d74590905f105baba71911f136cb402d","0x8d75c533f8d4db14c8a6dcac8dd60b9a98aed03e26691fd1fb9e2fc3c3ba9690","0x1805d2f45a0aea97624bc88f1c8c031cf47bba677e0f6546a01e86d7f3d0f27b","0x1cfca5e5d2f85ee32c8dcaf9d4bf2568171d42d51f2ea508d0c74abf00affd20","0xd8d73eab42c75c86f731f4dad63d3e273af3208353b507fa6827238def364868","0x507c5683753f13b3e5a162376c209ab9b95a77d765cb623c2223cbf26dbb41a8","0xa3558980e2740d554c8c3c106515743259eb2b20416b0b573235e7059d360c7d","0x094cab84102dc294750749359d757cbefc020c94f46e6b58a3e447b3e5463861","0x4a4d25cf1216b4e7c44c8bdd421c4ea60db071a601f49c9a6f50804620139e33","0xf7b344c4e653acb060502990eb036725c8fe5dd4695a08c235577e31e549d365","0xa8b01d6a5865a472215abe47654b8f5bc79279de7dd358a12ee7302e3c030aad","0xde74059780236d70349c60d740b5e379cce944210139f8ea207f63b925f374d0","0xc338085ae3e56746aa2fd1775217d6a61ce03cdca0755ac9c7236132d80e0f2b","0x2577a72238110062555e9675db608deb1ccece299c2b494580317818491c9d52","0xe72a70155ca550ea5731fbc44a7470a86bd3aeb02742a89165fc009134015998","0x9c7166133e4218fbb0680fe0e85a6d1456ef12063e22c4cc718cd5d56bc69267","0xc24f00b34888632895913dae7e5ce0bfc404418abbec908223513a789c3ace0e","0xd908f7c39d0a704911406a51dfa9f10d995857cc7acd244205998cc27187f407","0xa073ddaa10bc1dac0e743686f209a6cea79a3f31eef0906b768cb9be375b683b","0x43ddb22beb4ad7998bdbe76757ce192e5611262d79305530da23b4f007b99181","0x5a1bb100cbb3f63cdbc1ab07f1812b6359bb65ef829f4cf7fc1e382fff19a133","0x5b22ec697601555d0110416750905431ec2c26080320c8d5f4896d9dab6fd546","0xc2404bfa71ce902525264a5f5a1df30e2a95c4950a0a6428a25fa4d3f5da431d","0x49a6cffa2638f22c8ad533ee349baa7e46b9f0b4bd7b712a6fa5ee3c37af0014","0x80c800ec7aff60aa09d04e28d14b2a526f04c3e3fe74e8967bd2889841f3c78d","0x845a7227e2dc00af7100eea450e8d7308c1a40fbf8d99d6096ea57e558c4dc63","0x3eac891f5ec9a67ca561674909a2df20951b9162236920c99d1cbc3510141f49","0xdc64a145629e00aa85c25d0fa4b6d3b6bf14248c47fae2e88330cf89e6fe0d90","0xa1c589c03d124ef3acaee29b4f9dd3dbbe69882e5d9269e6ee1629316da4ca1f","0x59e3360615f64e1d8c53ef5a1f140898f806d11327f00c14559cfcde947763f4","0xbf472eb8830cf405d0f56f066af380136054a4d2288af767e36175cbc23d1885","0x45d376181ab75e69753c0435cf33d43840946ead20be091554efd51c4fc09da1","0xcdc43ff20013a51c3e25c226896b344a431fc9491bc03e59b15be510bc5040ce","0x174e761747a67f017f6a44b9344b2a1efe259a27bd311e3c84c9baa6847f3199","0x575c38d498f1b5f81ab443774c492aff99d3af565aa9b2543260c34c2768d643","0x4e46557ede1ef04c533250419d52ae0b553800fb5ff7abab1ebd8364aef692a8","0x7ac2c41c765f0980ebe2b98b2bdd9817e95b685c25f074e746d33ddb0c57354e","0xd652d1c03bc6faedf042dd066169281940a89e759f002da4a93d9ed30b07032a","0x17b25876aa1a953c9df3974cea3d38b6975cbc01a124337ddd310f64ee1807df","0x3d036a6b1b0bfda9a1d75c2fa0bf8294c4a7a1c043af19dbc6a5a50db1dcf089","0xaf39012c8653e1a6adf979fb8f00f9195b1ee110e6914027548c8e63bcaa9731","0x62107d55df0ab2328ef2142acba8b8b5ff09310e71e8a7491c3706e090d4fec4","0x94eb484ece809e5bd474c3f6c10b323643c860d8851dfbc96982587afd03b0fc","0x3521b5e08185937bed30d87cf6679b6d16eb0019c5ba702d7590abc7aa73a839","0x76dddf7924254ec3287a43e6da1f6eab442adf1690e870c5e5ed126d5c3824c7","0x7d82d487d43b0a201077af754d8daede5159a40560e7a2d415010925f621d492","0x025c1b1fc3b8515145dbf6cf55081e753f0a0c600164684a9e85d4bb75a4a0e0","0x7e2aca5987f7c24ad618dfda81acde722f627ac8fcc198c585a314dc1ab586e3","0x9fba9f82e8cbdb182f958cd7f83d02bcf1c01977556b2f2a4c50aa500ae079d4","0x26237c2621408d01ead5a0be569e567a7562bc495c4ac26d79067b363a34936f","0x73d0f3491ee9673a3dec24ca34b620046fd10f6343f95d3c4751ae05dfa342e9","0x9e0d9b8db1902a7b96441b159e10962a0764ee35ff18a35e4bf1cc3a51b31063","0xe5bdcf42b0556e696f2068f79a9510ab221eebeb891799131580cebb1f03dfd9","0xa17cc5a0332aa76756e5191385eebf66d9bde71324a33c9daddd3744056c7364","0x53ed10c829fc77687ce39588be41b08a14b26277bd82a54cdf2feb0be32c6044","0xbd250c3a009001b173beefc6d1f63df359701bc788e9da68188dae835a39c191","0xc73e525c654db4782b61e1e81e17d0e8f1a82b6ed0586642ff7e9ec0cf441756","0xe8a6467c7e847d23b1b91fcf593e5d00d17a06dc08c26dab51449cc7c3870c28","0x62ee5af7174721f0aa452f3f54e97db420e8787c68096243e1058298008a03e9","0x9b52418dbe957d03ed9426ceabbc843c95e3a12a6b4a05c87a1b96380331ae3a","0xc5a4c55225dbea3d49386f0c6533d378e72a7869e3a5664ac4a282e49be9318a","0x0b36ffd90d50bc7a839bad4a086121394f56ed023acdc656472f5505c3c522bf","0x2598788d60db78387c206289dc2ce4e893ebc09b890db9084f3e411dd196c9bb","0x87e42d942934b9472c10ae34324c0e496f5b07fafbfbef0c3fd2724feb54eaea","0xea405a1f92ec35c01d2e994a4ad18439025b362ac8913c7022a2720c0abc200e","0x47ddbc96a2db686a9dc44f089df45fea261bbfa9e6fced594a34d5b1da441dcb","0x85f1c453f79c79702cc8977941139ae888a484336261d1a4e777581707bbe1a6","0x87e6c80bc425b77b436d8a252bedca4566f9c8f218579ca8df95e3b71d0a2342","0x0348009b4fbce90cba9fd937aefd73ef9a14f415bf01d348f0a75dd2e3efd471","0x5e94e01ae27e9d7e01ad4d735b07d2e101d269c0c2f86c653f8b0db2248f4290","0x11437f14bc0f61ac30cdccdb53bdf87cd81c5a49e0e267c41d10e769e92768cd","0x7191471b5057857674330ac3a6f6285c1b2bea73ccc0b56deec0714c1a29d7de","0xcd93157b1edf998ee8cd64084d26b5682b791afbed6e8e4459a6c56f0219c22e","0xe24917a2347e168ecd5aaee1c3ce82ae30d0fdcf89688966752e5efbf24d0922","0x921c9cff68ad8d73d895aa7c7bb1788e774a5892af1ab828cd8a98dcf5faa24c","0xce451941f97ee55c458800d1cd9b8fa1b3dd28749bcadcaad96fc1645d05bbe8","0xd43d389a6466399f4416002fdd67ebfcd491fea50abb060ff2f788429c102064","0xf80e9c448d875234ad974fcbbac40dd0f1202c46bc4f9a9d4a2ff2360c55e4c6","0xca848915da408944310d75dc17126b0098ec168cde00d874cf09378813c6c450","0x86b29e35d6e7c22755cc94f79335ee0d3db2a5c5527bd44b88aee006c7737bf0","0x6eca3663d59159aaa3bbdf69f71f8477f95a8e22681fec32ab7c175a72716e18","0xf744e305ff6ce10fc0fe150c4fde2cc67adf256ad1a0571a9cc8604a54b9bc62","0xf768dd4eca3f80539e3125d9f33c3225fb49d5e1e7bd67e26f40764def2ab60f","0x6be5aaa12c13b2599487d9df6cb2a2be003270596b36960e2845c19b7de752ae","0x159f6811001e644ab3f1b52a45769b092ec23b23e5c112e20082d564399a43a6","0xb3367024cb135ab988b5e7c58932c45d94e1df8705c4b518fdd58c2baa7332dc","0x896310658db5c4a7f8ee8ef72c8e2f751d8efb8b5894cdd3ae66237f9e845bad","0x05ad0040f9813b865719ac10f78a050aec33de0e662be8e6c370bfa46cd7cdac","0xa62ab26ed680ede0acfde85049ea7f05866b96780e1a4865683bfd466f9573ca","0x91c5f843aa1648185779880c7e6b71dfb034716286ed5acfa597343a8429f0e3","0x41dd21e99de807090edabfc37d73724b9dfb0d203143f0bc954d1a9b983bb394","0xf452b6d8928d7f56fa4ceeff724f4bed574d0ae1a6d199fdbea625ec2a3def07","0xdecdb93ad9ae939cc6d4b384b7b41519c23032f2f28ee2ddc45dc9a88b281e16","0x46e825f742d7c34300b33ef2f332d7f54f418d295a6d03e081728d3c502ba5a9","0xc01a6f098a88877e38ac850331653148cd986e06f67add5fdbbda4e106a6c5cb","0x0c69a1b4b3c2b2dabef7cc47b7eebfbc1f06848d9b9cff8cc90ff40e2a238e6f","0xaa26fe4d51559953293c73aeb41b7abed65922f20a595e6579a0a99adc630bc5","0xd36a27f3154216ce1007ea11a70b942fc9414c41b5a04f3341da59f188e0d42e","0x0d4657f3745d9c4d1e8ed11c33e48e4c3edcb6ad03db51714125388a94823888","0x2ac7ae5d3ded1624aa4334349b4e938f8c2e6069b31e8972589415a016752969","0x389375472455bd67110a1a96ae945b0ed3ca0e1a6e851dbf07db29f100f24c8d","0x6c3b9d791921fddf0dd71b0b42c84a4070ef65a00b2e9b93f185ac1d1bcf9600","0x61935fb16d1bb8c9c2ed136d6b7a52f8d117d078d18a43202e9c5588383a4f9f","0xdd7e593eaf3081945e037c243f1d82617832e7dcefead16fce97d63c4577b485","0xce1c9d2c60add0abd8c48a11055b5bfcb540ba6223222ff0f9bce3e37cb7e7c6","0x8a6d98d5a5d80a001aefd4933189ab9debf112eab39e6508283e6d91f6fe4d87","0x4d3188d98e2a27b6789effafab9a645c97c095e027dbe9f05bd82fbda0a76d18","0x85c1f7bb11f4e175374f9fdd8b7fe1cc3c38ac628047dd8065c32b76657584d7","0x861820d41d01a4765ff21bd837257390654e31a24140ab700c8db2e2374982d4","0x9e1181c95eed5198e437fc909d7c022506141fe3f8fd6fffe24550503ade02d2","0x1099b4d854252fec5b476a8584d82a02882ab93f6035fa0687127aaf717d4caf","0x3c098242a07cc9dee1c21ce0725b2e4a7dbc19c919716a8ad8aff2dadf9152d4","0xc5784412dfbbae99d85e1140f3eb87f06fa9a054553c538dfb87dc0d7670bd5b","0x2a54ed7e51367282316f66a7009e19c8cf0b0599d05df86c7c157daf15ea4109","0x5379f6173ed27034a1f0a1968c8f506d753ca7c24cf52ced4a3d39a02101bb40","0x1f813d6e60c7060d87ae9662e1c925afb3ad5d9a66705f955ccacdaffd3d6e61","0xe703f6f5949ef85ce155ecf50baa625de57313edaa8c9c8fe6b8a339142c5c20","0xac26d24611b406b65c66a84322498bb31e3956d7877243cf2efb45d417ea107d","0x9e87bdcb4d9c62453f9b7cb7379373c57b5b5fa147cb9be7ef06330096ddff11","0x96f975477ea0b052740a1eb1621fad911806a86a6f5c796b19aa107dfcfb366e","0x837bff3c4d242cbf1dd06e34e391fab21b459a0110b2b325e9698eec7fa6ca37","0x82f21406fbf872c76b4c9020ef2b3f1cd627cb9bb6536d8a85851ffe05e67780","0x41281a88c9033844362660118a8b1154dba01bdd1db6d91419ff09a8af8e7c62","0xad30e62c06904a8e96dc91db0c336cd64d95569ea8df012a21e7238d3e1004b7","0x6ace0e9b517fb0d74ce7a67068dec53351bd94025ed110c11aaf6bd6836f6b28","0x4a68029f8d5577136b53f1cb84af25401e6ea618352b6dc6638e1f7d872f017a","0xe1678e974b3622e24dc18c079b3dfb2e9f71f54fbf50e03c13f90fd3e3f2454a","0xf6a8c0e20646e98f2007bda73bd281357cb3e64b4422fe7c5ae0f0528eefe201","0x41ed971a64f06be1fec58fbdf6ad62052a7a21d196e380f781b71b35acdd395b","0xd309f236a7455fa26628de1a3ade0dd99a91aace36587cc0adcf18db8e85d97d","0xd1df80699298f439f226dee4f75359cdd031d4ed502ac0e662e227623abecfe6","0xac48526d2fba3ff5fa2191cf4faa2d99e47f66f3099c09c35c333430b3fede1f","0x41d62cd543f9297a93ba75d93e44db6aeb9efac842d035471435e54dc0eb1574","0x954573f9f0b33ce6855e090448f2835c6fde0aef9607f75ea346648e1d73e47d","0x704513f32910865e6367a581911827d609ab66dee6c92b9ca19de1f71baeede8","0x08ed021d3e243852c53dbf8489dad9c8b8164723a51523fd0ce25071b95b62be","0x78faac74e0347b99c7df83b049666b40d8511245d2d8df0ac41bf8945a0e0f8c","0xfad580dbd0f4f92cdaa2db6a6a863df69cfefe0b03abceee71d7ac9833239dfc","0xec34d2a27f6f45515177aa774f138278e9cb32b43440f0da27d6a66841e7dea9","0x39f4627640648ac6dd97245677699a0fe39da02375a0c5543ba2da6f7a0729a5","0xe09e222c2a1a1c2c0a0c8f53f57f0131f532d73dfc19bc8abca6855544d8c669","0xd6dab4fd69002f08ce66575a23790665c63dac065bfafc4b0644f397a38b3b9d","0x9d463191ac44b6ef1c0bc25204a5a000f6ec0f7e033ab5daed0c0dd5415d76a0","0x0d1dbc1862ba33f42cdc461a14655bed5ba717d6ede7e118a1e6b0089a2ab6ba","0x18015d87c3f9ff44b0329dd7448c9a03332da7636efa9db02189993194528f1d","0x844183dc961c678c3ba5692690e3b64e3acc552ab6844999d4b06dc595d11c7a","0xaa43081414fe097dc31837fbb20d7479a952544e9e83b950aeb0bf4b498b3328","0xc7e1074ff74519def16453ea53ec17600cddea4c120112314e02561635099119","0x7c1fd53ecc712b5de74f444a72689197f4b705588a4ba6e37d522a69c2d19f90","0x028c4ec9e7e048c3d498d295d06d3c3ef3b4561e575f8e1cb169d1691235599a","0x734ff75dca8db518e0bf8ae62b6dcf44ebba040172a066770835a3c7a16706cf","0xf46657e121cda26519bab098637c53b9fccfe5d425376f1eb90a2d2317aaf6fd","0xeee47ead5596f85e18099b30b9723a647489df7ad5649e695266e7e1a57330ae","0x79881d3b1063e2fb58b1eae7cb1b6715cea27d8f226363a2536da6e9831cfd8b","0x12c4f60766447675ea0f9dcd85ce4aaa0e32feb50cbc984cf00297822e9ddb47","0x0e5ed5adcc08ce30bb3c5058bf43eadd2c107e91102fde8a730db20e7972c2ec","0x32251160045351fa8e814223a07519a818c59fd6bccd34b8d8ba840b1206c9c2","0xec38c5d1b479144db68818cb94f6371c87883c0da199b3ed024c09e8f450c6ca","0x8bda80a6bde84f361dc6501158aa8ec8cf879314c4a0b5483b04636c0aac5862","0xd2f79b0e2c0b4d4010b1f01c6100a223e96d6dbbd42269c151d253106b926710","0xfb7adcc7a99dc683ef8404d7241657c1a25f4aac5b574a83a6113bb2c2e40558","0x5f5a4c4357c533ab8c75c2e84a9ca8dfcff9eaf8b1a6fb252e85f4dcb487e261","0xd191a54b2eb1ca68a58d55ec6cb002f759fc288737ff4721b0cadcd83125917a","0xa8f3416ce91d65b945568e642063f2791399ca17ce93f46c25157a22c6d9cbdb","0x808cc3f142b9964207a88826f2f23a989c34e01e785573b436977fa0de23d8cd","0xe9dfc4c2fd81906fe3ade76c36f0bdd6bc907ad6ec65fa454f8e992333dd1852","0x2bf732ae27fc927a36647c8505fd0696f9f58f41de1db2693f7f7c9781e1530a","0x526159798a6641441d87fdd08eaa3b81ebc53a443f33d60bd4e7029fb9f0c8ae","0x222a1d86b1fec98a62a2ee1421fceebf312cbb53766df9018701d8841a39aec9","0x776e199ffe9c16255ef69c6c5d350fecb21238f41d600836951a2c24f9c7f99d","0xe6a758c7acf353348e156370ab001a621ab8bb107f8757b812bed7527b7b708d","0x21eeaba4cbe2ffc140247b0a822c6df02a0bb6f60fa46007c9291a9170c56b1b","0xbf312a7a9f7262169dc7d3e92e9489616f13bbe22d41fa7b6dc5a2a3a82cfe7c","0x36277f6939844e3fcad79c2d45f6d048df23ff19e7eb6fc990e39ff7fa5653a3","0x9614f16c84f8cc629655497f4825b81d6bc3d0e5e445e73c8aa39cf15eae6743","0x026e67171fd870ab613efd3d1883b914149a2678e6bd9e4f1924a866202d8770","0x4326431aaa11075ce07ef90313b655e54ae44b90577ad34721c40cdb9d98b4df","0xb235c73ec058b0dfc7af10dc4785aa4640b49c7514e14bd279a08481b77e4a3d","0x81aa0a1304fa7c710f58bce2c0ec53120c9579584cec60c43f2d738794689be2","0xc29ca8e9febaef4a758090eacd1e922210bf731cfaa47ff05385c4d5f30a9ae5","0xfb8da604916346c9a37553e55500d06dd830c8e8c9d7521506dff7a08dacce8b","0x8f6faa6777eb5414cea0e32bd35bef01e03e4a89321c9b62b1aa2fd32dc8ddcb","0x1e326560a2e244ed1e8c5c76d9db22cf6233dfc0b2c6452ba4642cade131d86f","0x2ed7f9b1fb9fe1825487c6044029ad7c5aab95b6bf91fd8ebfb4cc2d1c9f2c62","0x80974baa9e8c5a70374c08384b0ab13c3cc5d313d2f60c035e8a66f16f9ddb16","0x462493b5e99e5a391dc936b216bd2ab2a353c3cbbfe82d3b56ada075bb4368d4","0x8ab4a785bd70707dcc8c42ac1a0285d457b5d61da19ebbce65197355d28660c0","0xfc01a97c66b3a9c5a9d333a1a46a19034d8c235b933ce3d189e8760a686c370a","0xbeccff40c301b3d07760712393df9a1359432c699a020535c3c122b5737e9698","0xf77756acd58701b4d2e0732110c4ce2e4917831009a561d3e2980d4dd8336078","0xd98b303406b3648a383725472ced57115305b9552bbd1e70d14f68f6b33ebaab","0xa2bc36fbb643c51cdbfe0152bee3d7eecf668caf46683fa21dd07759a1c3c0ca","0x5b9d639175473bf3966a2b1a4b5b78ad239e347821a0186e24a9328d8df5c225","0x6fb444c54f19afc28ce1f8e1e5af3f3cffc3d472e52c78b63ead9eb71241dbd4","0x7a67e7c5f3c153b94a9404813dc3f9d9879c6d9c6df41743e9acfda786d1fdbd","0xc8188aed0d329a4ec1e4ff8b5edbd6d54de4453f03349f4551cf1d013b4a29cf","0xa78445bbf86810a7c0e5622eb18849efcdd6f8f0c05db7c4db8d1040be01747f","0x31bc5fa16ad95f32fd51744802aad75aaf004a5989a54dd9b09508284d3e6a80","0x0b3eae30533ef3d7f567fafb394ac66133df4423ee5dca71c2c99f8de58d76cb","0x7991298bf451e42c7f5d7275d8107a68878869774f2cf3f1c4fbae4c568c220a","0x26f6a154defec005b882dbfa78211035d2f0ba7d62ff3d121f1f6a3f3d639939","0xbd2000943537698faf5e243eacd74212ff5acde55024289002fcb8c954d560a8","0xf3e0356b0b68761859bbc1d5eefac130a3b4a2e002e2cfb4f21be52d62506964","0x9d0700a6782f080a23245eb533c69b673efa95701a5b025729e9e56e1c8e3b48","0x3bd622584c5c945cb67edf403578a52f3ca3df329cb8a561f914a77f5936c3d8","0x6f87d2dead4c8e3a4018c605b7123d133689b7c454e2b864309d49382f4c7a33","0xc4e75de596fbcb22d28e16fb547ea741338ae1ef44085a5b742d28361282103a","0x87046fe264a1587caa3b706f9931e0fcc7a685a2c8410c3416e6bddb1726ec35","0x178d8b82f40bf08e78b01a42ee9bfc607278628a8a82fdfda240d86f08fafab7","0x14e62a0ccc9588be4152ba5ccbd355a67477d77dd9fb6c5ac5c5b317084f9abb","0xc540835528cdf58d5a44c63e33c7e1e6cefadd6f39cc892eda44da31bdc84426","0xa31e93e3205ee2a450e2f5829441bdecd91a45f5bd6c2a27c81e35a66157ac25","0x81320b13ea19ca902827d8b55891f7e0368f52de724e9bd9ae240785673cd9bf","0x49f7baf15effa6c2355182c1644ae0a7887b957dd5ebe08dd3556bd3051a02e8","0x21543fbe53921ed9faeb49818ff8a388d7931864c4b066babc4fa9e749a8ecee","0x20e14db79d546400bcbcfb4320d02a02b7d4840613785a858c17b447a53b3a88","0x7cc92cacabe2c1dae7b9b8e7ae1cd29bfe3f92f5485d5ee8a0742a91770b41f8","0xf1437b7f7809bc2cfa1ce3fb8eb8f2f9b8e4539af0a07010af1cfe021693e542","0x16e99cbdb6d89f9fafb26011b4ee5b415897204cc5d721c425c1614eef108df4","0xf9e9ce1f28d47fb692fdd07121aee150b353cb2aadc6e71baa0ea93d6c839c26","0x6db57ad98e5ad3a9a748c063d46ef89cd791d00b80bab1ff8013b2b791b98554","0xbd834b6c9ecd45872ee36dcb1c14ec86816739c8595ac1a01eb18982854a7620","0x29e3d3cf900a550c5f4ed3d9eb24eea9dcc6951dc83c0d0c79a37c79e5fc6fc9","0x20aec6bc2ac2fc666113b3ff25e12156dc40cc83d3c1424171d95b465ec758de","0xd9cd661fe0de26c64d832cdb41199ca4edc01fc9c4f359e02bb43ab42d0659f5","0xc5e85ed4b1af7aa4c64ebf66e9b362e7025517b66f012f4a366fb616b894ebcf","0x2fb8e762526a638b9e4ead2583b99c2790bd1197495a60a56696be444a22e823","0x1119b6db828c003051a4fba99b28adfc0073e82484fa1f81ded87d1f90929b35","0xd2b010cc5ad43184a5bb37d692ab3d28dc643cd558a7dcccd63a3c42e3d65cd5","0xd71c348a655651013873e8c1efa1516317094dcad24dc0ddc98d6503f43ede01","0x618851c3d51b199f6ebd29c7ea07570e0ed3ba9899e714c1f85a548349ff537f","0x9add1abe342d3f0d468020ae4b7bfbbc8e204a8d730bc16ea711d3b8afbf30df","0x0cdcec1c7558f1be30d09e69c47465411f60c9b998c87bbd968a138b9b60b958","0x0230cf6fe46021ae2984dc883136209358ed898a07731a04711045b8c61297d3"],"blockReceiptsHashes":["0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb7a8b41873decb21c12b636229187b289cef4e30d61bf9117fbd23ef4928652c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0754c161f5610e38042f317761b6ef9da5d2df33d1038dba06aad7e827d91c1e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xae4bca935757ac898b51973cffb912d1c05e6beacdbcb13b3849f3206d18b393","0x64378f2a848a060aefe81e7dda01fd82d0e2cae5da5b7b3ca841274043c7dbe3","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xe1859226b64c84d5905a7a80c86f2e5966771f48ed98f7ed1348825d76c3a4b3","0xc123a2ac05a62f40258793b2d82f185d2670ef59e55e76b595363b25f9fca060","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x56ba98f07a4e996ca2b367a6515470049becd547590341cf23bf3241fdacecd3","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1949405d087973075bf20af12c19a9f4109b502b37fb2906d44f8c8f060667e0","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x30fc60b148a15a3ca57c371ca8254cbe4882b89ac882efcd2e66829c2a777301","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa362596a676512794b4489b78ac314a9f617dbe2927478713f85b3d5b442b877","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xcacb29c2024170b5a390b43c63dfb996a0e4ce6b59d519b5d6cca4b6b67e10bf","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf50f1ce200c5f1f5cfed15128d3280ea8a88ef6b068391964e7c6eb44b0b95c0","0xd3260ad6ab5b0aeb7f8ddf38e74638a1f6032da8ff2653dca23faa976a18855b","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x9b82c10a110352afeba39ac7e49d9ca62138c82ba0b87da7783fb6d7703748f2","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x70d4411252838bb09a0071a4b2dd47a2d5877c66590d75d9c663d6b1fc8be531","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xce398a799b8328202a8cd9d1ebf4074c3790654f1216bd3fe99ed42a38d6c72f","0x3cc1f5c8bb6530d63ffa77a50a904b4fe82bed71f3a2a6526efb0e8df41a9dae","0x685d0794f3d1b9f6f22c59a974d86cfd65f01ebda3c9bbac6f652cf7ac494b26","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcaec0a747bf0b9c4bad05ca24220c469c5d9473b5f98dcda9b5db9c370463f","0xea88b895e5af5d3b82a19a1684347e32365c220c154870dcab7229ad80b44322","0x2f45ac1781eec5818f28166862a46d9935158643af04bdd82408d442082546b3","0x0764ab562fd8af790540c84a970ba29080e09c04a5800ff6192762636b8d69ee","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xd1a9fabb56221b691860d0f770c4931c5c55f435c45edcda56494e45d941bed2","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0d60b8a1573cedb005f85b79631f838ae9c0653251cbd45b7583751a05e9a697","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x72f71136e23136c1fa1f9a440bb91f5b30b5cab3cf8f308bca807b3c185c1eb6","0xc27aea76b5814ed132cc58e4634afd51eef8318761ae94c78af7fadcc440c9b8","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x4e648a342b676f8c46375daf30eee1941115efa64f6b9ebaf70b7e792c09683e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6ce6607583c26cacbe077ff74df36d4a959f2b3b8e89a071532905c9f2b54ae9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xe30632ba24e74fdd9a5841db14330a81c785976af1fcb6fe5fd1d5f99c2c3aa6","0x1cb7ad496aa0e671c7d593068acc63116f271d9192218746791cb9b7b1b129b1","0x34604bcb9b5cac425654e078057395ee8ceea80102a7b7b24d3d43c8a37f1811","0xda219a53f6c62094bbe1c47fde21e1d75fd57ab75fafd8f8cd5c4d33f395ff29","0x37ef612248d8552c87d1389e5208fe5eb5d2991361668e0f035dc678eac6d8bd","0x8acafbecaf42496ada336e789100031e4505af0dad0032c5dd89226bdb5ebb15","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xded7f76a5ebcac1a1863eea11f1c7229be71301481f64edc91c57bb051d126d8","0x55afe68f17828a552dfc6159b8d1d60248b62294dbd6eb14bda03faffae323d6","0x81c3f9593457d442a77004f30f66b67c781ef3b7f5f516c72a96124dca5a3834","0xc3e2b52b08908a3da6679964f42a0acca9909ecf48bb503c39f3603e022fbb63","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x15fc47431c297565bdd18c7d3efaf6e82a5483c814f6cfb9ff4910ea8abdd7a6","0xf42970d21227ef4e12a5bdc9d6ce9fe20ab305632acc0832f1b61758409ce29c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6949739a78a4c354a8ea10084d21c1b369034c810d08949537517114f749fac4","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xca3e015b42a8502272ac15e778e5cb563875e4af15c4db13d4cf5c98b3227058","0x83cc291e240220943d3c8e80cf45d41cd28339ec0eba29bcad123e119bde8f13","0x310a95e1df94a86ced3580cc7529bee3b3746b30499b102a1bc6e3979caf7bef","0x39bf73ac949d703301817a45cf82aba9efbb116adb83ac695ed5425b64448912","0xa5c740318a8648412ea04fcb87d49fad4fc5159c86efb0ded02bf9a22ffc0783","0xbee113d2d6c8f9b24eb82044ac9348dc6f7640dd9a3459c5cf5b31323783b77e","0x925f322b59a477bf8819fb6382ded0cafcf7257f1366e3aed39773b586d7d37f","0x9d2962a6ec4b0bb6f2d1b26fdcc77506cefb6101cebf8f67003cef16b1cc920c","0x9460cffb5cf0206b026763a06fd23ba00f7b3ae3739e9bade8e4513280b64d7c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x65c5987e3b5fd8ce1afb61c45346f9996f71967de4af3f3086500f0a066d314a","0x1b91ab9d18f2c401640fa178855ca8fb97a868f56e15e3e2d2965ffdc65a487c","0xdd9a2cc715c94705b3c3e1c1ca368025023658f91935e44524ab16379614382b","0x18d28d773f7899920342d7bbba169c295eb1d27c805674629067fed04697bc6d","0x0a0c3ded28e9c441547045c881252a935ed60fdff9b72d0b46629f56d1748617","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x5ceed970a573ad47b1453a1263ddea44b432d068721d1d60ac4fdd5ae9377742","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x48642a5bb412c27bc80ef736d43268da73415c47dcf02e1080898b7e8c2bcea8","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x17a49a3897d5c1c6c7a50b951abdd1cddab83b77b33a176a365fdd724d8ba3f0","0x16aa7ff562bc69b2a13c95ec000c98dfec2cbeb66a63220ef84c8df48348dfaf","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x436b51ea4c875be7f093ddfa808eea1d1bebfb31979f8a86e4c6f5aa63dec7c4","0x1bef6198b145c84569a37891376b35f9f22c50ad413f9215d4b4df0783b7e5d0","0x18165bcae2c819b24d95ca9c4023703b25a718ceb487972ae864a39560eba478","0x4d5cb325142482a376a59b16c68951fe646391490b0db818668dcd7972e4b9d5","0x2eadce6c19449a59bda5dd5b525de79a8adab1ded3578a74aad72751cc8bdda1","0xca202729c83cb50058a227620663c497b05f33b96b73ea66033b7ccc617e53da","0x942a1814a61f8a0043a883fa1cdb53c50e2d8e9876d30a8f1e28d75689087f4c","0xc7a4e531ca68b574da29dc3b68a92cf645882791ed937ae3bbe4066644786929","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xdce7852295385d8f15af3803f68a943cfca15aece2da9a066533ccba1ca64c40","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1f77e249f269fa5e74e9db3d60bb065bdb1f863a85598037d6401a11b39546b9","0x14cfef5b80a73ee05faf6fd554f15ff5b0e13f93725530b6e4d1b720e69d64e3","0xba00384f54d9fec0b9fe7c915fdd088cd926984d03e5532340c1506cdbaf885c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x85e086a2ce0de231064e07b0218ed34228d040417af6f2b581a9607ea3f084f3","0xf1fe8703647b50b5b178944e9a8de1ff41c689f5ee41de6b0679bbed7cd7ff32","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x87e249982ed980fadf9035f5cd56cdef0b66ba03692981e48e6b6b43af47e799","0xe41cb623ecf13fc8d4049dcbe4247e35ddb9b55cd0665415e0d218cb59d067f7","0x54611e6faa683d6251fe19df4be75db2e22676e7f92c06088d955c2fc4962397","0x8ec205f51bc7fc1daee158ba8a373688de3e20c84316ee8f65a5dc96fe4db1e2","0x63d0959d120b87ae20de76a0beb996b9e4944d4db55d1de9d2102f37224f3492","0x3e7717a743b9e7459d059015c9a44364279ab592578f97277cac5ef87e22ad64","0x372839e0d5fad9ff606476047895c9450a160167ef4da744434aa4369aa6f6e2","0x661cc81d88c8bb5893270bdce152bb67d5d03d601556eb6e92d2e26c80ecffc8","0x94b26dee612ce051c5753d180478036c8caa811bc5c5277e07f34b33f78c99a3","0xd5423fd02f20ac5bcbaf77b548c2cd95fcf4ced49ec042d3a270db5ae73f8766","0x222eaba3e01cbbb4b23b43ad6bea242e5f814ac8ea3cd46f83198c6de585ffe8","0x58e92e4f1c391b39270d72d095b4ab496d212e0b04e3f336f63eec2ae5e746f3","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x9747db5ef62b3e281f8f27a747f288eb0d7d17fbfd7f32de575036fb7099b22a","0xd470a4f07b1c7b81dbdfdcb0b3e8ee90f7c1587447832c8eb856ccba54fe18a5","0x4d7e00f9a305113e5bd81c724bd775cb6bf06768a4e322d2be20c99585e08ff0","0x704fed54a7a36b3f0e794a349692d40b275e2f6df0c8add9cf79bad0859bd04e","0x0e070e7c90d693135d6d6e2d26ee6dfde9e632dd7ae417d266931f915a30760d","0x119703e1e6b003819445eded53e6b4f9daf217938651f74265db28a33cd4e646","0x552ad7861620b80fcafd6e88598d004f4f429d4c325b889ca9732804f2892b43","0x68d5bafc3ec4b3cd8d8935164ddfd0de47c3c21db6490e0b99be875bcb6851af","0xdfe586f690b67036e6acf803dfb7879571d07b6fb685c8d9635c87a959c9f521","0x1372f7e3308672f58b666e23f3aa6b50bef8bc37d2fd1fab429c2ba2763c3ae7","0xf204b2d223dbacf94442165296767cc7e739ee144098547cf4cb022127bf29d6","0xa584b8484f4312f38d092b2c2334259adbcb984e1041cc29a8c6967fc289d22a","0xad3209274e88c93689cc38b383b2b4e82a9d376b004f34f2ee84ee8a2e411cba","0x0524ae1c3b0863b7215410d2289bb7af3c662ac706b5cd77e57f5810c1997588","0x97c25f90441f2d4a85109c3ba483bb2790a4e10e5fd6711cf57aa9c26faa1395","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x32e2cc88e68cbcde6082af246aa7fd3b7d46e72f537305c0961e0834f48994c2","0xba11d0ac91b57424f10cd2108762198f07fec3afa31723bba9a9a146211be751","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x9f16856b752f4c30784767a050e7ea6a7400c28f451f8e08142c66ddf65bbd98","0xe19d1ac0260380b5217517c8a51346dbb6bf478c7a76759da271fad5e031b259","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xc052f82a0665ab4bf337d309ef2bbdfe3b8be582c96d4f0a856e0ba779efb488","0xf32a6269dacaebfd833894c662248c32f8cf80a79b597a7f12a511ea174ce746","0xb6e1be0d5c8ee78a3eefce5c6026465b9c5c337d38d9cbdc05923a5028848aa4","0x2b1100a3131ed5202be95f1338c2a5faaf2debf973da8d8d03af28cae5caead5","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x3dd8ffb7a1693becc752acb23e9357341d153ff786bde107c15f573ebefa1a49","0xa82f506d59417e28e2f6c0ae2f00f6fffcd3aa2495ce826476b21352e65b196b","0x55c87b45f3713a97a1b92a770a7165a1bc1032dba2ddadfeb5b03d4af1ca5b04","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xc5a452640baa9e577b895d54d134c839016d985bcc05e2f9af265b9c5a57b660","0xdafb0147977a0bf74f0e2f6923b77968b6086eb0f357dbfb146e1e695c93faa5","0xf69b56ef15e631ec5240e392ed593740489d27aa484055e99ca6f04bbeebd109","0xf71b28bead43d7038652e5423bcf407630525825a38ffd4a90abe8df7ca38161","0xb8a6f7acf225856d310b8909e216934fabb351069c3408f41f36c90aecdf8c33","0x43937e92769f2844f44f90d9c620c4deac1def67adc63bfd392b217ceb9d2963","0x5e3340d91b86e23b96d6ebdc8eaf4bac1ddef0063b4144b3ee95a178f5c3422c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1361c2780c7332f47575f2b7e17a75b6a4a457b5dd0037697f9a77302dcf28cb","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x407a76f8dee680796819905b0903dfc194cc54018b08d9d69a16badb75007b03","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x84096a473b9ebbb12eb2a948067ebedfd38acedb9c0d1d7b4c075def06022aa6","0x3350ef83c663e7d0d1a8bde920ab20bc4033e6076ffd0f0590fa046ccdfd5114","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0073e17dbdeb7800b3adce11a20a5e621b2587834f21825f8e767064d8a60cba","0xcc2739feed47689bef55f99f5d875646cd4019ecc2248be6af0dfaba3710b521","0xe53fc0f5396673fd13db83c30dd4e89a57809c7438315f3b85eac9ef19ea4cf7","0xf8379788e7aa54c1b83ea9aab542c8b8710fc64bc896b7adc8d7628b6c29ae9f","0x90de5dd44fb09fc4eacd94b4bb7b0703bd09f2d3d5b4ee007fe8e7edde011232","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xe733b43b297ea19157b0ae11652a6827930fc532c9b6959aa8d6f9cd55934c24","0x5e38fe38a82814ea40ee81ff30eecb2ad01bd5d83e606c7ae418656099382b65","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb03cff9da6c3c2d21db3e92cbf24ecff56978dad93e1787b77b484555690f09e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6a71bf942f5acbd4f07c1a82e495498a9093db97148805ef53880eac521859ba","0xc3888eac0f4254e19098d3c8a7c1926b2257954bc7deae2e86f62fd46f2e5b15","0xa834c2c28f7ee201d58091b81614a1043fae7a14519c2d557d72347f48f03cd9","0x3c390f3c3dec7c3700287ed5d786592af360089e402fabd222afdd0b4f6715e8","0x6c6623d1c29d18b34bcd7cff66508eb226195a3ccaa7066abb14f911dc8c4a53","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xe3b1ee5332d06cc94d11c89180c6da5740aa0d930d360bd5dabaf06759ee90e5","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xbf6c0becddb5791373529b5d8c64d53eb0821c6c6d289d98effe5fbbbd383efe","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x692837a62017bab1c0cbc3870ef3d165cfbd0db5070f5aeef285f14a5edde050","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf5aa91853707bbced036bb1ae44ab6a14b68d184215c1a8cae4b13029e516fdd","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xbbaace2d19ec01e6a2ee01040a81ff410168fa5746a99c0b3d7c53473168315a","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x595284403a0a124b62131b369e9197392064323cb122e41445e9912297d0f84d","0xb3040790c5a64ccb0b30ce475db6fc30703d865fec7d182277ff9799cee5d3e0","0x59f227fa1f864194d129d580226e911a6ed7c857d8d6949f2358272fb3bc4e17","0x03fed081e2f599f328c91658dcacf894106be5d0aa2ed5486c7a316dc5bf3508","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x9b785dd253949f38b71c0d1c277ee6dd2e5e2c702bedbb132ff6adfe5aaef3ac","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x49dc12a1233cec6a94b729a47db86301422d4553e0ca53d730bd07b4f1b7236e","0x506d1a388c61a5cd13061a9a8cda3438373a4056a88e36e1ad6365e71553aa6f","0x971f92618c91510108b88c7b2cfe7a6178941b058d2cefec2d2402d9351c3e19","0x10c6ed40cb2394e11dbb70f3d78fc2b157b629ca33be43078e7767ff83cb3feb","0x9a2d6a57ef096648ba2910df920809a380b02b9fa1c3f188f2cae05c07b5108e","0x7e120e7aa940582dbdc7896dc08cbbbfc244b59cad14c58a5cc1bee43dd81246","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x992b7cf009be9bed5a0810721f0b5bdd084b085fc70e0618d0759cdd8a30e192","0x529ec5508e1e1730f8b0ad57388ea63586afc1f3f3f60f1e491957b7c56d5dd5","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x3e86c665482c602a5754bf950da23248da8d74400d8ecde12e686c3a8473f049","0xa3f2fa22ec5d6a2c72a048c9a9f6a34a72d41d9ae7c822fb36adbd86081e241c","0xfc576bbeeee567ce31be3cf0bba160f9dbfeacbf4cc335338e1d9eea864108a1","0xc2a546b67ea5348f8cd8b3b9fda4a32da7590c90efb2d27af277ef9db5dbef8d","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x92fcb4ae950cc9bd1f447a50023efbc967763352adeea3592479a67df141b957","0x3d7ec7294b72ccce185e6647b9ff41453ee66a82d445cf0207c1018c9a1b26a2","0xf8e745ce8af43b900eae09802e4e03586c53c675fbcc28f84fe9681397fd84a4","0x4567ac1f50747e0861e08f3c64dd7ec7af5f322f666f8ec7b0b6572e8a991e79","0x2194a721d8c13df64765b60e51e9206f0172659c8a54edf4868ac7765641e5a6","0xd5a6942862fbd92322b921b7c4cc68ab06fc7a7e4a5b9faddda7edfb2b12391f","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xaf883413b9d534a0ef089deb5f3075661c720d06e622b4f9fe735a27e1c9f882","0xa3f270b9e9c3a3649396959be004b2a562cf9aa19ca3194dfc1c7ec4698ca3eb","0x36d8ee452c8b85c6e3dc4fae6cf14315f8d5edf5af07474a8d0efb4a083a9e5e","0xed9b54f3283f9d39b96f4d7fb969051a93983d9daa436c47c2286b6325744dbe","0xd8ca487872d16922added2e58196d72b00b4cf454a74d056f5b0c36f51cc884e","0xeeed1b53d6e552579967751cf271da5edfc282422159c675030115229abb7a25","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x713aac332b98304403b9534e2604792e923a1923cb9955e4c244f9bff0348660","0xd7bcf8667c477bc082d45d5755cfbb6c03dd1707de553d55ee67d43cc386d8a1","0x112c6e92b4f1e83b2529a61958eb670bd151f12591033019528544554f989fd4","0xef8b2897aa5b112086bfe66642b50e3ed043cb480b73c98506e35c2299275679","0x6b1c07b61c91f8f90c684d72dfa77221ab7b71adfd4839c675c07367fe76ac8c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xaf38c67afdf0fb371a2e7885b47640e4a06afb02f2a2f9dbdbbacf9f3fcb365b","0xd206d0c116f3a9404c255e8a9d95096c2a5ad67d9f2bd281a5f6c1823dba21b6","0x439e41602bfd14d020ed77fce979d7af3ea9f36dc657e5810a45485c9a26f48f","0x10f8881823a1f24f05331f6980dc90b26e7f16bf5b6dad6cc78dc584b8b37ade","0x22fd9c625c18985cf711538e688f9fdf48e7341de0315c7275e15b9b4f6e9f45","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb1bbcae204204e6663beb17888a00b158af38ce7fc25721190e97a53d7d2fade","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xcf42fdd5be42a25f1858327ed7dc037690cd5886caacb1b50d0e8e085e731bf1","0x068a8df40e5617dcb8bdc7f3c2b05c4cf934e915585787cb6ca9deb246de894c","0xe3bfa15f3f43d899c399cf34956a331d6bb2c72861625d8d5e1cc7144905325e","0xe7dc1d5f19ee24876df9fffa721ea349ddc72053729a3e6c8907b2ef212bd507","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6a59f5e344a293a4f93f0c5819de486bedd685e85684c9155e545d09d5d8479d","0xff18be09310626c091e192506bb567cda4ade108fb0d526cdde336d11112204d","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xe5ad394504a0c04e3a1b393f90b0c4ceca301b881eb3ce72fefe21f31b2396a7","0x56648b2e3c1698aa00e66ec6cc9bd21bb1f7fd7e640e9f1eded405322563e769","0x46c6b7c26109a214838a5a5c374d2dd4db955db6c940c4a4feeca7e8abdad00d","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf6b8ec5b6f97520dd9e5f365209276b0c824e300eef0a9fb09576eb74c7adf7a","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x540d4fce381957373368716201f13a71006e7a624a555e84aeb7828b79391722","0xcb991f3ed26951a2e202fa77450cd8dc13567c55c00a88293171b0af0f9aa8a3","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x86ac66b7ff279338937e5424a2c1a508c87f004956cbb4be62e4961ed9a9a0a1","0x24c5698fc51aa54ea1705ec803f59fd02200970faad1a68ad1f37663d7d91f93","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xe092b37712c8d32352baaff028b6726d5360b74ccb80d441edd4d3b5ae8e669c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x134bfe4847e658c98ec7542e6f9c21a333266bf11b9ee8ba4c5756cb85346ebd","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x097cf76e9ca984639dda484d9abb2dfdca67469f47b1fde71212cc93be7ce5bf","0xb383c864798c063b9f7bc6f63f44a0a9bf34313c807684cecf86915c5ca9d12f","0x676b51720af195571c5af827e1e6505a8cdda7f7fe3014da6fe5710e49821968","0x1ef2df87bd6b8e748cca0e94a57cae61691dfa9730d2b8930a8ae8a4ac85ad2e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x2b989ed6faaa233d363fca55b6b2ec3faf247f37a018ca01575be17ee6985b1b","0xd7cfd5639b686a7047df395c95274a1e84b2c36326b30f1446552f32a1d7238a","0x4f611e4199d69ba1d126300fd4cf749b16762f8b4cf26493d7267cdcffde2407","0x4cc8317396cd055886f568588534d499be254bdf210b0ae4c6d8fa90be625b20","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x59521eddd1f1f7f683ae460ff654309146aca927a2013c4fccaffadfe0666d0f","0x6d334c2231685358a4d1439ab145dd0d28c13849fe92d2a1c2f720d1ed254da8","0x941689e8fbb27d5c145de0a5c2ba9806358e388a201fd75815d247ba98666ff1","0x661dfc176a046653b19af40ff0d5175861f0fc5a190b78244773cab6198efdd5","0xf5dc4fd9e509ac14380b0ed7e753348c87be29d3093754365536dfe1e4415735","0x78dc67012f34cd3e88335dbf1a03c6bf535ab0d9a72158f66510da1d2c7af1db","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf05bcd9c0b38e9dc6682846b44e8d283d60998b70762a360aa296d07f2f8ba1b","0x261f3bf76b65deb1d6d397193b0b58461d230f978085cec68608315cd9f1e082","0xe822b00f36641d1ea2f57819f304603666bbaaf30307b3f59faf1e76ce5c3cc1","0x0e6695735d022fefd32ffbf258a57ebd04c28c8ec0686fc3f834c756aeaf3c40","0x7286db868d80c4744158bb051cc03b3d757c16ed7ff76205c3febfa8859c99ae","0x0417e6cb111ece97c9d884f04b50d4db838d446c4aaafa162f586d2978289b7b","0x35c7e017a4768da1d29b85b584b87748f1798e36f63baf5b48d986629db3a8ab","0xc2f6718e407784c27b29660d9dc22db47136b1b61ee11682586a9d043ca50d12","0xbf4708f207a53a287876bfaec10337d12ff63b08b89dd4417887a42f5a673e11","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1081014daaeda22b4c8ee62edc6ddbcdeac5415a5ef930399ac1a9040f540396","0x860aaaf22f1d6044d97df3bab08fc3cd8771ba1f32a35bcb4b3314708bc1c9cd","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf339681f7360f99fee70253dd11c32dedf2786735d1687edf403f808f3b2313a","0x41cde1b9bb5b60bf21edf244069440227512bf1051d41b43beba380026684502","0x4774f9d9b4f79de312682638f5603dce69250fc6680fedcef489c4872307bf95","0x57e46e9066ce24db49f239dab006372dafd112dd3ccbc6bf80163a15bb9be2cd","0x7e1d21834e514a458699adf5ecab78291f71f889147c1320aeb80cb2092b8267","0xbe89dc4ec33249e90cadc27074400bb808353ba8c3174943647978600d2ca834","0x12bbc74109e856bcf2e580c8a5f7782a203cfe3b65ec2e4e5cb6fe9ede238da8","0x55835db46d146006e3393ad7546f9ecec5cd90bb7aeb6b90d845f4f3bfd1c17e","0x36aa76614547a5978bc1ca9657617a44bced319e709058d7aa3f65f24b1fe997","0xac115b82b923e000bab83698ffd50db62d8eee81d2ade80e49bcca9697c7eac7","0xaeb54d6ffbf458b2fb6738c3babc0c7c115ab7a54e8744b729612b25a55154e1","0xc35f303e6d1fd5581b5dabbb5abb86dae6baff7deb01ccecb5c06acf8d982b5e","0x231d0bcbb67db55b02aadbd5ff1692862314467a167b8ddcf66cc27990238aa0","0x3db0bd82891e64bae4ccb213fedeeaa9235362e3b2cb07406a5a420588845b89","0xde4727648f91fbed86dd9116f963ac71b220ee778cc78d8f184560bdd2764906","0xed88bced1b97a950e2fff26dac1d46c98a28b275460832efab74261524f8c5f3","0xb5fbee41f487d8d37d6e8512694e1dec93e28d70c6dcee4a323d401886bcce2a","0x67c786afb31e22c800823fe265b4d3585d012cd81ec2457813b91646d1124ccd","0x76a4bf696f9c1ce686c4d5f964a74855e6d626426330ddb6b8898315cc67f468","0xe15bf509b951deadd2c5bcf3ff0b04151195dfd413c1144e95e80c38210fefba","0xdbdd620b29124519c8542852dcfd51f75cad82e5d9321815be088735155342ec","0xe7343d6fa4217cfa7dd84c4aea52ed64c726a0ab1920e32bf0b40215b7b38fd1","0x82c5f6aac1660b72beff1983bea7aaa9fc42a52d4cc250465003d72b7c1dca66","0x1a7887a454e2589964fcec2a356f176d6326e1f7ba25985708b5c380c27f2c65","0xdc30460b5d0781114f1f141bc175f16a7d69419083e6c4dcc584714f46bf1a08","0xfc5ed4cf71f45d03374a65df9773a648fabd591d27f4c838c0e66fbb74bb9472","0xb5ed2228a7855926ca8c6d8b8ee873bbc3429d08d9b3cf5f31014002c3a22d45","0xc7f80f33a17994fa14c8eb4c1cfac3ed1c943dad618ee1a99f756501bbd02a12","0xbc892060cbc3f9175c1ba57dc46d562625ae271d3ec0d78e4f77fadedcf0db06","0x322855b7edcfc578215c9b5744de7bc0796c17becbefce5a9d242f6649e35a96","0x6f2f7fce4760c5ff2bdd5c146863d1948dd36031ad54640e659f543134241ab3","0x319f48b4282fdeca4d948c9c3eaadf7db2fdac42a863d403cd08a748e955bdb8","0x4f3c463c760bde9eb64c9baf0b2f797e4226a78b8442746941c9f585562ed490","0xb5337f0769411e66598b32bcbde33d0a13775558148c6f0f6a32837e5ff8e85b","0xc779ce56319af070c957ca47502f94b9dacaa4f519266bd81eec60906b50d260","0xdca4c5d95ca826b345491779df9e1355a83e1cc8419aeb487058cf7a17c6d8be","0xfc4a44b247e499380a1485522b907685b9fd34a9048978daf47519f25982985f","0x6ccc035ae78026fc8a79f793d2fb7cbad04dfadcebb2bf50a7920052d6d2cb04","0x830f5806b26d1b9fc6684bd12fac6fe016e5a140c84f0c6dddd219ab36d6fc2a","0x63ef129454ece654d2e2464f9f0844be69fa01fbf5322a10a65a9185f6e2ce9c","0x06aaf4ebed5b2f1bf5baafd7312b1402a1033f79ec7ac8ddb2e6b5a95e255627","0x7258244288c335639b2fce2ce2eea9e9a959b37eae4b839f06ff0ddd2f4d266b","0x267aadd11529a9335f4579adc6060473f96f3f5bd3265ec37dc2405b8ad6d7f3","0x0956c7d9c3cb7b108ee8a87a832f197601623d6ea4d1ec379787523cf178c0ca","0x5a184b7f46537b70f7a90286c7feb7db286c85a2d1dbb0602835a557c2fbb56b","0x0022126f8ec1aa3dc334e80ce3d0a39ac7f13ce6771ef604c6226e9cb7875b7d","0x38581fda1fa2fa4d386ba87155a296c525570db98a17c4e1ea4d439b45bc447d","0x301f5e8e95827ad8338a8dd768e4e072bd8fcd64f797839646af04e784a4fa78","0xaba5e81f9327aac67a3a2b850770fbceeeb2d319a58bc97c53d163b702bd7ddc","0xe469ae7b0a8bf4ef668158598b338e7a41456dde223e3898b8a9f45fc297f023","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf37674bd8b6bb7e0ef80d8bb064f89c57915ae50cc6a0e300555c2992e725db7","0x6c67695d769eb80fd6c508b8eabac922044093fccdec8aeffd2e8a0ecd4facbb","0x33510ee8c5644fed5b2af89ce068aac899e3e177166434bed9d72f98a7e64ba5","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x3618332d45265977f42bccb8cf912b57ac1bfdd1743b4451176d0d93081b98b2","0x546036a205ab50269c857ec690643b70c805a2ae5d75c96467eba372d6696025","0x056076864c5475b0384db87f9e5dfc424e1ff8f2a143defad526d73217de3352","0x7ebd0e6d382c99664eaa1f8d3a0530abb438a9176e1dae5862f05c4ee8d12702","0x05f9e2a0f28ecf6565162847e37e94e256bce4a20f6893db971a63ef4b56345d","0x77f0961145f3c23601dcf50fb156db6b5b444413944e82f37805462cc9de3f85","0xc4607c176771b7cbcb86bca4dbf4790b2e3883cd326b7fa3ab7160b1a3d487c7","0xdfc8d97ad0aa980895ddb053ec683fc0b89efe944003785d92e75aba4b9fae65","0x66c5153da55477c74b849efb70d1443720a9d554f9d3c307767714474754fb5f","0x3bddaeb454dbe2723d2f911b25e7bc981f7f4891a20169594028e29bb64d947b","0xb4327acac6bdcab6f894aaf3a56e8df00fcd0f55572eb2ee943b281f9aa7c5fe","0xa7493c16dc2bc9e04a652cc7307b7c49e94fc6d61324d68e03512d68369559bd","0xa2be1d44228623cd2a35f5b5d433ccff8d8d9bca9026d01780c6ea38ee15ef4a","0xbafb4bf6d7aec28a96818aca5d8e00bded42e523c818a05d27a6ca49dff86a97","0xe8851b34e88a3360a9fe9769572d0459fdf6600a1d8ba4eb329d2a64d72c7f04","0x97d70e8460a07ced3ac0d84e760a972725a049e4b33d67df2733f43ba6871188","0x399641a7078ba850d4775075487c593051cb5e8d70a0a023fb7022f13064316f","0xd5dd67392257c91843e3dca2ec11c51f25e219d84d51b8f5e82de4e2f38c9a52","0x3dcafe701b9579258c0bbbc4a34fc5df441aa5da24d522c2a0cb64d7b2906345","0x0965018552010afae284564cddc7685101a07c00ffd7184bcc3aa84888e91399","0x0dbcef964031167c71010bf4fcd7cac53533d44d9935a0deb4343fa0cc868aa9","0xd87d8ffca2e514fcd3d3eca4fae4a075c3cda1ff544ef3dbe7fe25cafbf1fbb1","0x51a0a9cd874f4f71d5049ba1770f72bc1f4eb0f745b745a3bb81845e056b1825","0xf236f255ddcc1d3becb640da80fdc15dbbddf30dff6392f28249c1100d6a5c43","0x839b0557628305805792f4c3d773e2430a78a1e443eb9f079bcee58c85087b2e","0x74dcf9a342c31c39b4588c2defe9130a250c667c3ac8d96f4625cd5a1c67000b","0x3206d989152b63cd3adde25c56f0fb419ebdf4fe416c92d777d3dc5f02853729","0x166d3e8a89b1dc5bb797f801b2a29ef3c91bdc5dcf05a0d78f7167534cc7bd7d","0x8344328ff94f5f761ea26e44357327eef0e426795144c289a3c87c15f8dc57b5","0xfab35c867a470ea969a6772cb13c14cf800f487e51f086b7aaa39ce2f0797c09","0xf3217905a73d8a4224be4808cbf6077818a021199daf61e02b299bd576c19766","0x5eb740ecab5e073f7a34e7f1379adf015ee8d62f48cd7d2210d5f69e5de1bc08","0xbd3d82a75fed5ee656dabb9089b7d8d60a754fefc5e149be5c16d5fed3163828","0x161dcbc86c5271f935917bfcb0a2c43a0bc4e0e76e75a77050365e1186758973","0xcce7c1dbe004ddc86355377fe21cb9ab0af999a9f619e7e324a85c02f73117dd","0xbcf889e206d621d2bd543769c841b0271e2fd396113fd31b6141cbd79390ac1f","0x7ea3d8ef03421acfb63fc492694ff2209edd44adc3b262c5fc27a26de684cb87","0xeb4205b0da049270c647a97075b864ba84541305735c4f26fd2c0f7baddc3b2a","0x40b28f1ca0768bc189a3af479c70ff4a405f384535454fcc41491bab3ae15b16","0xa67a666d203f5e55f44782cde2ad3f19a5095066dc9bbf5d11d6b5f6f842254d","0x48fe9b8b6441e9ec2d1a16192f126a11df12d7b634a99d06f9423facc5aa57d6","0x05161e61ef15fd673b58a90d08d13146c855fd1ebe138b437fd52d571c26ebb4","0x9337d48c4e902fee2de295d6cb0e2c726dbc7509a752366c5452547d865cb2f6","0xe3b0574fbf7e94594e88902435d0d331d2fea856c862130d8c4ea34cb047b299","0x2e74e23745d26fabbad5bc837f0c5451464d90d9c9b35ccdbf887d5543998042","0x10165334e56e257df026f1f25c2670871f30e5daf4e2d55c8148b9b1e28fe6dc","0x0967649d70b271caef1cad80365556291a612a0122b44edd0389a0036d870021","0x9e83ef263ce9de94e5888725194ba0f3727777fe8d36de6829fb48ee43168bcd","0x9e29e3901ff5ac205d753a58087cea7d25c58f39579cf0376bd304278d57b6f4","0x32532377fecdfaeaa09e1e314b3aab0b4d3564baaccc5cfef9d8e84dfb434d56","0xa81622ebc5fb9c236c180de445b2e9f03f47d3196b47fd517a69488c161c15a3","0xae67ec90cb374472bedcadb5911bd80ae1f4d0d220c65a92a082fb1b9fa73cae","0xd6cc7cc2b881b0590b1e0c9ac73f54a8f70e552666cd548f00c61a003b7bbc8c","0xb19cabc316bef6fcb10c1e8c882a0f0b603f8751f839aee46956f18a45f664da","0x7fa5c2d5d4f317f79ac97206d1e42eabc96622062bc96d5fa03e93e0268bb873","0xe3b53938494222ee8b2b9938e73a35ee79e603d8932b3910113b5747e06a9e56","0x96e7757521cd3fbea19ba4dc2afc67b2362bdb678d212cdad086cdc7331c948a","0x5aa021b60bdd1c85246f9608afc014f0a80fafa5601cb803f9c235f4c0d79231","0x264d23bd17fcc551f6d0d26d77834bde243f1d1b11d54ad43bd95d82585b5691","0x2a444da1b0dcc0fc4cd7f677d5e1778732d3a0dbad791dabbd556bdbba2e563b","0x3f9bfe3468f7dbd456bdd7dc02fd455766a26a01f09aa4845732c0c0e1d7472e","0xc873d28298bd995862a7b073976b9ab684fcb7f1cb30c97c33d4a8172028bd7b","0xdaea27163de310ab1522d32e0b9e8cbd7678537d0ef64c4141db703846ab24ac","0xaa41fcb6b482f7501ba0db786c3686e20448c195744abb93db6ac5fc884e5a54","0xcc2194b30e946db37440464b6ddd823b99f2c6271c83e900978fbb47b3172f31","0xc0422ac4398b74810ea04a8fbe6cae4df3d6b785d137f873a1ff9618012cff4b","0x3807dfe786bfe789beeec5c9ff571c74dd43aa7c992e5c37bf2af21e83c756b0","0xc7213749ce6fac4b08dfbaf8c82912defc952d8e2feb7fb288fad99639b0535c","0xc32e3340fad46f6439dedc8f8033889ceddeae4c088a49ac155af84e9aa198c3","0xce2287a0467ec92bdac8588c3738233fd5acf858a78dfee27dc07a41937a5e94","0x01c0a7ae259026b1828a41f6f7ed0b61195fdde85bb23779b6eb940a760dbcd3","0x9cae979755d9011768a663ef01a886fa6a1a85c77d0cc0217f6344508916bdef","0x03b18229076e2d6ea4869f35a5a773fef216928f403988476a2a4921bace491f","0x2fd47e2ed89839bf45e3dc4aedb83e2e07efa7ee611c0d5ac69b4c0f73e8457b","0x635e499335c8527b036437caa36dd0fb4c40a99993ed170820d2fffc41fb7e4c","0xd0b1c5b92779ae0a22921697d1f850b004b2b89fdf3fa43b3de8c5c572aa21b1","0x2b701ac13e0f952e5923185fae43f49dcc817865aa0034f9b8e4fae6c417bdf0","0x411ae32799117c0119adc3af394bcc20f97bbf6fe8ef5a55e0ce2b3ed60c656e","0xac5765fef59770936e20dc4edc549a75bdc37cc4d6bb89a0e2366f23448a9ff4","0x3fb0e1dc86dca0688e331f4802b227cf3c45ad2082ff759c514af04a7598540e","0xa664b1329e7410222a705f0abb297d207049dc8c78d472a619b356e42539c4d8","0x37fa5596e7853adc469f57346107e4517569f014318ae8de3b2df3789a18d59f","0x6dbccb8c132c105439fcdfaa1d11959f0e8e444127375e2809d637fffb14e3da","0x15abf5b895819d7485f5f676b2ac88aaa6cba63a4506f5278933ff906160e204","0x3f77beef111a5fadb8ce20a8832f28a5b503e56338d182341b4c0335179974ae","0x4b4e0e7b928421b27213be6c16e6d6dfa4b189a5bf823aabf2637e589bf1671d","0x1ab348df1b64ea6ac6e05229a0735936d6231664ddb456a47268bf86a6133f38","0x879019a2c037cc102b8f96c003f2960006d94be639bbec75783e7ab68e7d185e","0x300faaa1553da3e6ba2899c8e0378375f82545ea3deff9ed08f1168a6f60465c","0xcc8f1caf0e5f09a9dffb7302245a452fa2b90feb0f3b877fe7d11be918aec7e5","0x8d821fdfc47e14bdc9558e563d03fbcd0503abd0fcac97ad59ee864b15fa39b0","0x82f1a87216f8f064cf7ef956e6dc02399a5a6638e3aaa174a2b71c924affb39e","0x53d3dc1e279b07af27b1abf74bace7e13a8403daa58a2200e8efaf893dbfc5b8","0x27e98c8a1dffb22e61a674a0acc57a7eaa66339eb4e6ef9f50f0bd6e2a947e0e","0xda6732068f3867b392927ece242ada2aad44c953b5ca8e0e2b9f844bc1fab38f","0x8079c507c389bd5d6b20c84083d4393918daf1312561c9d3f7aef3d54eca9ca2","0x31a3cb9ab0a7cbe709fcc7f916c729349b43fe499ca349141dd09648d978c941","0xd03203f902855890f4f81d44399724c20123a1c3596fa9ef8b0cc31fcae2bd3d","0xb7a84ecadee30239769776d1d1d20cb90f49b57d87536deba18ae2a23d7e1461","0x5b960ab8a0c464c15bdae244916cc570dd8535780ca1a8f6a25abc4c1e5a07e6","0x1d4addc1e0b40a46081bf775450d254857589e534430b76c1f66924edcec5292","0xcf239ee191a3297b477df5f2f58f8a922078b73c638290854baeedf4019f90ab","0xb8c2c6ee0357cddc33cb19d93f432a0308737956ae2ad495f5dbcba814fc7cf9","0xb441c5c38ae4cbf63412aefb7d6b43c2503889497950087ddf3366995bd9e776","0x8cad12904d4df7db783b0d2c81fe3cffbc3378787b678fdde57153f8d48aa600","0x54ea1f74bd7c8d504a81e31867b1ee829199399935f4c8589f701445ac7314cb","0x44110820bac7d94d3d8f602541d897f0772c55d1705ccbfa2654a8e6bf6d011c","0x4c96d310e057b0ca453c4d1d300a0c796419fa6499fc0307d2a60ab9430915e2","0x36b157775c3d5af600adad5e2a09c7c6af13a1bc10d54d506c3450168620a178","0x4e9b336d96d99a77aeaa0aa23676bac4b856ce7d164bc4e50f1f28e880329a07","0xf5cf6b25cad38539dedd1b47ae860498853e7fc48f160e900c62e7f41aa38c56","0x58e2a4bd0cdcac5d888733f4dc7096b02ab99e4c1de1bc8e8e2dba5ad2c9e0f2","0x30ecf52578cba99721473b3ef4b300a588e6ce1692fc619eaf0ca41538082976","0x64be7f007bb113c3e6638ffd1d1f997b56e4e6fe66997398010e71bc45798531","0x1fb0ea7223d2cbdc2cfc7c6c3548f0aab49d40b0cbd1fe9b1d72c4652a7e9fd5","0x7b07aac49f3990f03e41a8e8ea2de96cba65f247a7a88ddc9b534e46fdb0e01a","0x2fd331fa589a2da6254521c03d710c393a81335fdcf4259e3c7fce69ac20dcfc","0x02dd616eba198faa2cd6633213a0008689fa833053db3c1e620c92d2b704fd5a","0x27ab64d0e6eb12a53d5c5a7ac0a01d2ea3fe2713c01e30969be2d96dd9408200","0x1e174d7a81356dc4a37febf5d7f4241624a4d47d551c8fc619d7d33d7b2f5199","0x4d6ca5e8919f83571c44ab2cd3f1e4daaa1c8f936ddefad0fb4a1c5108a1486e","0xef48048a7284173ee12d8d58c5fa0e7c27d96bdc3a02c4f9064beff61d342b26","0xee8ab10fa4cd1052fd58047abf6c6f99f0529355b1f4efa988c0056f6064db27","0x129ada99544b1b374ae4efc5fd5b4e87c517225db04096690aeb48131c90e8b2","0xdb7930ed8442666dee366c9252c45e3c826c94d1b622fad548d6673d6079707c","0x6ec0afce47cd7881c879f7a0401470f10a922d9568e92259d223a6992237a863","0x5366a1d24a78922483b0316c0ab708f4774d707831a03b15b49c1c258f7db6dc","0x6b444cf0066112a59a682dc1535f7267160ed92d75210b3b789f2edf62418138","0x0fb989e0a12d4f125a2f94f1adc653025ab9a3124588fc8b1e2cef256d0fd6ec","0x09d2b70d872f8919fae6e580b6cddea9bc1d320bf6a2ba013e6c846783d32fa9","0xeaa3e4b36401b820703f1540fcfd40409efcf4c1478c6fbfedc733697742f9e0","0xa7625adbce0f315c015c44e3e0a03197cad0e5217457327cb847fb22791b02ce","0x3dc693734a6d311b2d4ca880b08dd774b33ac4fd23bfbe2dfefab6dffd642313","0x430c491191fec63ca1ebcf31d18d8c921959cc56588731ec66a2842e3b41ca93","0x97d3b49af96ab900a4675806f627454203f9bfb3de611d9ef38a762a7208a4da","0x7a41a10ed26ac93fc1f1294dd1bab78d7d764e3d6d2adcef256485523f1cbae8","0x5b993b1e659f7551531af68299a1e084a448335cdc46c6d9db3845c9b7a2bcdb","0x21b66030fd6ffd0c06ccd58eb055330f23eeb0bea2eeb50a4c5ccb735e66b4d9","0x43f497bd6407ca4ecc5e661b6d871b7f7f4c2ea8c518031159a1fbca87759192","0x73f99b9896ca632123cccf869b49a6ce5c002d26a2443b86fd501648ecca620f","0xb615acdb450725500fc94f42abf9692e9a969365cf34c135e3738c39f98acaad","0xa0a75a1d11f971c0cd9ba7306472191cd1198d15cdaa735e7aa8d8e73d989240","0x0beda423b6a5894539068837cce23b9f6a69273cd2b4551cfacc2dfd6c3742ee","0x9bf515aa436e39f0bf8654f825220636612146ffbbe2f89db954d357d20338c3","0x1a3383f388b6ae80902738a8a405ef8990d0a4a3402d7a4bdf0f52db084c7dce","0x2e6ce617e59fae2494beef70287f3f0a7f7079cb50493a0867437cead6223e73","0xcf9dea513dd2d1d6cf7073163a5d93fb6ce50a888b63e875d6ea7cbeee6d4bee","0x834bfb469d2b1c7f4d16a3f1508454e740b183d8b2c13a6e1cb38a08a6dacd31","0x883d682728aa36b35e5d461119abd83eae7f60dc68707a773e0d06e50a6d1d79","0x0476198ee97f4812770ae3d3412612c1a0c173a8f50292365641dd983eac242d","0x4ab91c80f6773a4c9e580d4b26192feca9423684d2153b503876e7f010199aa8","0x96aac3afa17154fda353f140d069ef66ffe253fc185144a567864acf076a3007","0xf15098248383c7006e0310817a4cbca1248d1dc673665c66faea6f922238a338","0x06bf21bf6b31091e7fcb431761d9b1fa49cac2206324655bbfaba15642daff0f","0x2e94a08e2b0ee51c0581ec048733bde849a7b1940d3cea8027c2ef170e660757","0x0770110f0b8b21a479abe3da53f442bd90a791c07317cecc13859eec9a099884","0x51232d4cc24d11989e566d02d1f1c4b8580cc3195d765974cad50a4164df61fb","0x9ed1336053809f4d48b442fc109be21133171673d3da6ef262e94f47190e68d4","0x2a668ed6cb89712c5f207c5e7e0d8b527a0a443585105872a7670cc193ca3b77","0x05ec9d25222966738decb79bfb0776993c11e38f0b1acac0e33adeb21d807d49","0x2569a905e769d09e8a1725213168569001a0409cfc692e1c0a292c1f28c360a7","0x32b31f5735c5a41a4cc54bbda92ffd1d73d0f4e427a9554a9d2bd16c17ab8ed1","0xc792382c57d34dc3897fddf52e3e5a7d5135a51e7650dc9c2627f58b70715ab3","0x87e7bdd9e5d2b891ccd997de84341d374f4046b353667d5bf597d0cf2814e84e","0xf61d55071cb63922fc947977b03a72916ebe5ba5ef20b4e918be2ada2de4d00c","0xa8aa58d40ec8c015e955d8423bc000f76a04fb8bb352d8e80841147eb1d85f46","0xd8dc61c820c30ccd855292da616e7cf4860b5ffab840ef4f43115bcc1761245a","0x17d9b9e64f28cbaefe1a9a2c80e1e44c24556e3cf67cc5d6784bdc570cb82863","0x9a2adfc7715d28751712186567b4bf82c3f599f95ab24686a59272192ad72afd","0x40724765c40cd7053b0dc2fbbb6916b0969bae5b7e8f826a694886f45d55d387","0x8df3a8dda430a844d8676688107e73bfda9c5d2af7a118d292e1f163e75b9dfe","0x97cc43b56ef44217f4208510ec8fcdacfa2a50becf9c9c488039b644b22d5eaa","0xdac109477a27863b6fdc250689e47803949272290256a53b88af659b513e17d4","0x92e3e9cc6da630220228c309bb75673c25901c67f3acd13ed340f19b52b15875","0xacd71cbe36c541e49d640bf4807ad4dbb7cbc34ef6b3d5eedc8a90873579c14c","0x9f6cf37c960d59aa8779bb7acdd0b0665d4ad8d5963c64bdb020d8cfe67b905e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x39e4d07715a3ba427ca0041b35c4d44c6f9fba2ff99011f67e23751493102523","0xedfd773b889b82d1cc53116f07649efbc61cbcf68ef82556821be6558a573861","0xfffe6f92583ef21c756370e7cd2126e6e226ce7728f30f585e1c171e42e827b4","0xea8c886d074af11dd5f915e9262db27bec57c5060286c672e1111211e6e30892","0xa027c08f74ad968c6d001f095243e40622a62c4453b96f8bec4d76d1717618b6","0x351d2cf4a13fc6c3e0112a2d842e8b723841c1cf2ac7ac6a5afe129cad3969fb","0x8fd86e17508aab4541a8a9b83dbca8be9d1ab2006cb18be71fb22f34628a4239","0xcbdbecd7d9040da068629f27ddc71fcb0b932dea191dd209ece8ac9e638089e6","0x6ffdf2139c5ca454249bc15acfa488db44464f5482c7603264c6eea03dbc608f","0x41d7f1b09e2f6f9d260e5e94cc565bda988ead0eaf48062c1d34f611f9295fdf","0x7e62cb58165b7cfd26f1ad086e8e585f0d4383a0b75c5f2f3036686a6f51f36c","0xc394b2bc8888fe802f260e3bf1f237380f95d75a9df920294ab136be30390712","0xc0d44e527bd77451706484ef82c944b67b2a2f518688c35c3cdd56e5447b6f4c","0xcab402323bb078bb5a05f88afc8882053c31c0f973af87158e1d0680b254e9bd","0xb61989ae5a3f7cc31b91c840833a0b92c9bead28ceb830f594146f08d20e34c7","0xad0af96a100218e9703f7de4b5b8452304fedcaa9390903d106125a1772195be","0x183b7323dbc5b687ee6c72bfd81dcf0d3fcdc0bce42c9b00f63c15daf315fa05","0x87089b383425a0927d17736a6efe675505e54fd18fe558c92bef09fd5f6c1750","0xa63e57ced4badca232f86798e21556002ac075a4667c93f35f54f1f70a6614d9","0x7d39bb73e2d7e59257bccb34bc2940fc3155e1cb2775ccbed5c1d7d9d1100f31","0x0a72cc44353cd071f6d3a838adb98365597fb90654128e548679ecfd526028ca","0x65b755c5e9d6969fa2be17f2bffb034405a848e79260b1a7d39bc47971571102","0x62774cdbd424a47eb7a5f6544798d7262815c45c99775f0489ebdca121b7b622","0x4266bd66745ff2f942d226f9a90419a1d5fc5fd3acf9612dd09d92ce586b7f6f","0xdceb6e37ab5fbd4465bc34c24aaa5ff5e076fb69f8a626635d9b57e2477bd855","0x13112ff0f170aeca866d2cd31da20779d0a894ecf975051709d7bcf7609cbb83","0x43de270681a03742d96f37e1ef86cb7726acd57700fc94d102409c86d1380b85","0x9b4a698211958c6ba01bb9cb256643de742162914cb71c5741d4a87d7ef41c76","0x86afdd8916463ac766e746e26c125faa56f1118f4225d6d88c759f968266d960","0xa191f95f0afaf9dc5b8cf76325b2de5d5a2a7fb561caa097c675f8dc3b69833c","0x38f4f86597a58ae7e0f9a9c92c0b9f399092637ab5afd1801ffa14f1132ccfd1","0xbcb763601a8bc4e30262d86cda205746c0b61126ca64188b9a16091f0ef6b088","0x4d2ea500efe67c9880dcd4f8b4da0ce93c8d4ea10055e20a3d8af6da57143edf","0xca51e70744a9be1d62a71157faaf4b080a9e568f55d87499994cf694a7cf1e63","0xe66c3a163521e7be56ff27823e34b853126bdb60d67794e2d64ee4b52885bdd5","0xcf384f8c7f3f2d8356a170ebe003d992e56b52a0adcc7bf2841111f954c12692","0x607453b4776d2643bf4b84cf0203065157fab36b236da467bccc032a1b597130","0x883e5a9b276174039ca8014ca00fa800836925ae6e02e4b04fc7bd1ae647af23","0x2c938f7506f90af30c05a8311ffbaf02764e69fa6f12a04260153773dd25baae","0x721f3e49e33e54feeebe9074fd77cde0c928d712742cba07500f99cf995cc772","0x892aaf71faefaa0008d78c119f094f83e5dbe3a9877d861a0f597bbd1e655347","0x491b1c2192c211c32405c96a040193b247eee54fa916e551161f1877e201faa2","0x10310fa59208c11b8d0e13f04620f7562865b7b99c8dae8a3c93f554ada1b24d","0x349594ac151d2ba78a31cfcc1918d8014df45efcbe0e7bb3b3cfb495d9b361f3","0xf06d9c6dc33e9c6412d2da614f437effcd6922a48746685913c093c739ba9ff8","0xb6669f2fd3998814174c7583a3e45833e9daa6b68b81c7104e24b5d5f230f65d","0x543e8782091ec11308942b2939c9dfe4f5549ecb450723893d330df184f076ed","0xcabef69aa721dd78157b32733ad65fbfacff2011dd44fdcccd7a5e040a10ea48","0x1f0b5e40e7805e6952c4001574466ff3b2f3ab0576818a91ba32933abd58bc48","0x948bab0924e81514c4e95fdb9c3690db6ecb3dda5a038d01963b015666ff52e4","0xcd013597ceee9f4631c98c95190c78c5b8203e00530d337e0c6ca4265b9f9b0b","0x5cfe1aa3ec77173f232519f10e58ae6beeb784fe658c088bcb7881a64dcba919","0xff45e783888847a37ceede49facc22a91d54042c4f39ce8d0cfb21d83101944e","0xde1552c6c8aa54ca94cb3af19affbf34fb08041ea616c3cb38a7b85361f7b300","0x69e3d0534c277cb8614364297caef991c7e14dff014f80cd94dc79aa1849df08","0x16342a11f7a07c74be61d7c4e5ac4913f1eaaef1ca238f98bf5a1f45615b3610","0xbb7710289b1e6ac6356038f722f95d4da3692cab70636739074c609c50ed0ded","0xe6a13548bc1990390266625b029d31c26260b9bf75936091ef413e5e6ff38334","0xc01842b59ffd202e1d441c6d5f7a3e57f1ee774b00f7fa850fc044b7008b0a1d","0x852c33e658fe395d6e4e0f4b1eb3ea0a66f0882f0e124ce0a7c853c1b8cda304","0xcd673f16079eb7c3482bdae10a35493fb127dabe0b44450692ae586227472848","0x6846956433f4795a8451a2ed78a7e4235b922dad80fe2cb34a3aaa2346212908","0xf3597205b8d72c5faba80dd2a9e0f337595f446a3abfe4abc3db261dd0c7fa65","0x4cb661f257e8955a70f4404c80a57d27beeb86445f069055eafcdfbce5def207","0xa27245be555ec948d23177c7ae112bb109d220185154b1444f9beee970e21f02","0xf5b251ecbad0c643842f1734c80bf82427358c3ca72b1dcd7106afc565096fa6","0x300bb4f252f3865ac9baaa672555299d761b7c229ebb2b112e274aa295168c28","0xc7a8f06dcc4f46d8972b6faee3ca4144f9aa4984fb0ec599a9ffc37313830cc2","0xa3137c37e5bdfe7b1b7a7fea02c84943425e41ebbb6066d096e3008deabb3440","0x5b3f4d51dd2ec83f250f5806fbea8737bfe541546b054f07c587ced2914e4635","0x24ca81e5d7ecc92e84e1cd371198bbd54222f811b7e601a708dcdb0bd4ed3155","0x9bda4be5224b46a086f18da9e609f2b1a4a785f0868082a341e252c151a628a2","0x09f05ff7b012d22368a373ac0d1d337273f24308f3dd90a65b188cf94753906c","0xf9df5bfb4528bc999596b865237bd0c17edbe30844ebe1f470126633490bd237","0x42cb85f52ea20c289ff863fae08fc9f8dfdc84e7063e1a792b2b3d0ed30f3a7c","0x7212cbe1be54b47f15c44556b025c81dffe6d8a0813849218b7d23275733b658","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x3be9c6ef2ba0f5e8c7d53dd2776ec8743bada3b416343b31b61b2ee5001c7b21","0xfa0cfe242977e7c9bc89697aec7d9f155e4b93c29420ac2a0b4e9ec66b2052ee","0xb8de69c251edf009b2350fdc4deb8d0efe6abd757160997b69b0474f231f018b","0x15b2513f2ab0c0992f259a0fc7a1d094b59d367c59de1bed291368e3b81bb066","0x41b19abfb0884386e7d758d5f85e47ee1e5cb69b935066cfa110d11393740122","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0d33475bcc4256d8ddeeccfe5f6f2d82480a3013644dcd26275551cbcf845bb5","0xfe2a0f9e1d00a9cee69c65bde6d2b150892f768f6002645ca7a07605845958ac","0xf182a47adeb12198d509266372fc8c30d87cdef7342064620ab07a3196135a2f","0x38cf534de9ffb9e5ac691dbe3fa8b8b0fe2012654bbc714236d3e635327612b7","0xa1fe2e7f0cfc8918c0709038ac9e069155519c688e8f81e12abd24dace8f1fc5","0xbbdf5a3a3ec666159424f70ea9570e943955a5a7c8edc50fc2cef7ec9d71c95a","0x5a9b72ec74bc297cbbbfadb733ab3303ace273ba0243bd19db9dbe05047fb561","0x8d559c10c33563185cf4c0fde0575103b3b9234459339bc245da2dcdbdcebc50","0x44629d9a1557652afdee997044a6d3888aca23702527ead15aadeb9b054542d3","0x86c3a541692af49ea64f8f9e1274d365cfb82a33298abe4f5b29b800e454134d","0x61a017fd3d1b40f0b9fca3e6f41809f816dcf86da52cef939ac5587f60a58991","0x111fb78063b2096e68400ed8cd47d02b573c9f39eacce5000574f23444acc6e9","0x8bf8f0456b97f9907b680985c4a17c2cc12579e9f70c9f085cb17a1459857d71","0x6f850c14575b5384a874cdc9cd73a619c8c41f57642e9d22bf9982b36aaee88d","0x31ef035edebecc89025129ad56ef8c6fafa562d66a380ebecaa9365e6cd8e502","0x762e52ecaa819a1135ddb20bff7511efd09737bb69d902eca77d95f235ba4953","0x6288c12db90d1eae8205805db372d0fa93dcdaa8900c59c0f1e6ebccceb045dd","0xe50a368f055d4cdff425c8a7b22c1bcae944457b9c6e801b5307db0f016244c1","0x54945a907423aa5b792dca09e58053ffd0ee933b3ea70db28d8afc73c698cc6f","0x603b48ab2ff97927bb9f299c2e1b10db7f73dcca770c2d2d02c377b2ca31f409","0x788fed99245ea640fcc719cd56ee197751a2eeb42fed926f9e413aee078bc5c2","0x2f58a16b307d2615bf0dc46182bf926b26bb27f55d936ee486e980ebb37a5e92","0x76c716b125f99c086745bfdea4343df2be1335ff7e3d267f3886ef4e7aba8776","0x943fa05ab3f04ae58aa1d0340c55b61cb2a63cc76c3860acefec2b45dbd501ca","0x5844f1b9d6619b111699b210bbf18c74b6f13e6a1638a5fb40f2a1c7f435d657","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x2dfe917f42477274a33eb236fb8d805d504770b1448da3c06ac8568069ba72b6","0x4c96abc83ecfd88349a84ff33a9cf5966672e5bac9e27496876f89b81f65da00","0xd87e096f1861cbe58a484bad767abb4f1b8a47c71d84f137b36ea59e7fad81e6","0x307730b5a8e41727efc892024eb21bfe426afcb2d07f3e58c5ebc46367b9b2f7","0xf30dc4ba0028b27459886a519d0148d2ffa9f7214c8668639bc270b5f16f7d71","0xb429dbd71e910389ab38f6e8b668a1b3145b0892d8ecd4039d29d9422b61ce73","0x62ed4196cb09026101ca8ac469b54055c041446ce3ff7ef7dd8839a130a3aed6","0xadfb47b673552b33235e9ae282d1be14fb21ef3241b488efc9a844a2de2d6881","0xd4d5b715ef2d129b1dad105dcc0e8287e491a395293cef76e4323c8738b2ce9e","0xc5b91ce7bf7d26d36e3afbee5b5376e8c71d6349e9ccdd726b7be828c3d0a40e","0x5c2a7a43735e7b69e20e084210a386a8376e7ba1b28d29cfaf6426df201129f4","0x44816ecd9352d79a0d3c30d1ed806ca715b01d65b94bc7883524befc1c2c0b5b","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x82e9f6c647f69d3e36594674dae5e8f2c4f9173d3b85b8b008973d1bddc173f7","0xee0e790cb14f679cc384a23ea8f7cef6dfafa012836546c8a6d5699f66544b45","0xe8c6ce249b8172eab43d356574290ac10e334c118329e520ca10953af491d171","0x5bc92e47224cf915e7f16da7f08d1fd10bff33187c0b99bcf84df923de701a04","0xc9d9e972472f93f7d4a2ab0509c1cf309f404ba9af42256c757bb2dc00aed125","0xfd08d39bb51e19aebf3a938d40f228fd4409e3d0bf53892e3d6bc44d0b5816d3","0x7a38e4c291d64e01adc9a0ac65f1bf99dd73778ad2db7115c9fa11b6d27819fe","0x65edd017dbcd738acbac68f91ca885e983ee9a41493042ce92418586b3396537","0x943e3806388de248b437737aff2aeed966e837334441dc25945fe9ed5ac8fa1b","0xb26434fdf7a41977c84fcf73504bad121fa326e7e1ed39752331b7ba7290932c","0xf25c54087d20b41df47e5c735ef3b6b42ed283b1140b81538a7e00bf5014e9eb","0xeeb08371f1a64327237ce689f2217c676cf3804d40d360d38b9ef83d5cdc09ed","0x69c1bab6a49bdb9c993c484275aaf5740793291b65c065090dc805da653a53c8","0x7b8a110ad56836188b91acb44ea6e3caf55c8ea7ed47548d6d1841bdfe895919","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x52d7411accb58152440ae5903a578ce79ecb13512857ab7d582c1abbd3eb95b1","0x4ea22b03a4e925344930eb2a57a747c8f5b1935ea0ce05f6dd5e0f51dd1b8df3","0x00ed1629c16e4c05e655fed317cf6bdd487d7f0166018551df35bc1d2ee03ff7","0xd2558fd8ee323a84501af28bb33d289d526228839bccbd9ee2450ba0205ee559","0x0996e918a195cea48df2462af0e2958235e557356002c908b1f6bf6acf61ef53","0x64e02fc93f340a3658dddda3f351f0e5b2fb25f625f767cd0d3689797c20cab9","0x504bf55d2bdd322fc419659b1cefc79e43d0ee4c4e74ee51e547ec9667887c2e","0x5cc051d1e4606ebe4c8ae338c14278febe4ccde31696b368a958be4eae880dfa","0xadb6a5a6ef50a8020b4f669eb0c91a5c5a5922ab65067bf7b45db95227ecc93c","0x0e2d7adcfd7ee1a8bd96f20ca27c3c725b2ea68568bd5a814602d78bb9c123b3","0x43496c06a9636f3ef2d90f242c60cac2a2b8d985214e07088d68ea142b4d9a00","0x65f1477efa95a959796b2d68e0c3ce81921041badfc6c9b10e62c23e5045cd88","0xcfd09986b68972324960537bd2a1a3171b1e5c95f6a12159f0992f9e478db532","0xfbdac415d53eb2e95b411c078a07bd4a98b53f5d84b2e61a70c071f94eb2be7d","0xc44a217ca0f96a9f057aa040a84896a0192c252ed55107242a71870b0d879283","0x38762f19842a0d120399a85ea49fdc796c4f1f82c3522ecc0984e0e555af1216","0xe121f0e829d90cdc633d100bb1fd715fce66876771fd4d5e4317a49b1aaf4d2b","0x6e8ff43593e45567238e5f09f0b991ab9ea71167e251e9cc8b14323f21cfe036","0xf40c165e2e097e320b84ef5405c79bb493f1e5ee969056b99abb72cdf41b647a","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xce7f1ce2bb48d5afd79f5951a7c388a52f5b4954991d76f445ab04be59fbf71b","0x73321f026b8c99325c45d4d7a7d099cfe375f21790483ce40bf40d5ab31be504","0xe66ceeff1efc2975d4c75237b174b0e468db4175a554b3186bf252924cec14fb","0x47b13f17c9557b88305fbabbe95a3f2cf3e767eaa7665231fff1cc440e671c52","0xe5f2fc4605dacffd6e678680fceecdc4ec9a779f16538d86cb11e64f0667a796","0x6095151f977f6c18bbd04e1bc49cde600ab964ef25f4aa671fbb754199bb8b6c","0x5d2d6a0caa77a16f10bcbca938226175237260a743f735023fede5ca368ebf4b","0xa47fe8c3e7e2c199b210939cc9e905611f2efe1e0c9a6a22007b86fcd2098a82","0x8bd3eb786f3c354d9eccb71e9ac87c959a258d879afc093b6932446a4db5a409","0x26d566008562b7e16ffc67f3c8cc724e5e6fd018fb9b932b24e34aaacb706a4d","0xc74adbf23de0e6a39991124f97a1b72420b9dd6f561073307c3a06217d32e38c","0xf3ae8cebf66077a4ef1e85e89f2b728934857feb71cca5cbd9e80c301575b06e","0x573c850dbbb847717fc2394eb47de5d18a1c2cf24e6ff392dcb6f6ae0e5143d6","0x800f37886c0c441ff079e55a09b26468f120161a0390508071b66ae51ffc5e74","0xcdb57ca6b064c7834ef3460f112bae935728ee6cd602ca04c96913a61be62013","0xc589c9500148705ab35ce3c21fdc8cefd39ddb0ba6a40b51c165ec9fb344663e","0xf0dc28f1cdce967920589845862331db279e1106bf8a0f1c619343bf35e48e1c","0x349a65a905c08aea1fb976de88166d43dfea4567ab20a9e2eff1af62f81bc603","0xd377f7146ee6ed55bec820c13a5c34bbe40e4594e619340d31d381c139bb622e","0xd43aaf516b522358147ab5b1779894875b690d6fdbb39eda330605580f8b8074","0xfe50b6ccf3f7c07f9f1c2f8caac862268085c23b0bef08c84b043b061e07853b","0x5fa6398a37353c8afbd71613cc0cb3ed4ac94435d566cff847a03ee91000096a","0xb2b18299c6c5d1e06b1f217742a7f623cefe8e84d36e5c3c6d535cfc9bf261f9","0xfc512d500df71db33b1e93c6f83169ab8e1a00e8e57825f8b8e950b784274346","0x692f6302f4c499ef22650571a350a356baea15f4aa25f26c0739be5bdb38f505","0x8cda67f78d2753d19dc7d2de72227c1c2a907df67670b36bf213592743e2b164","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xe7a8cb8c1ef6a658d34e090a614a212bf6061e298abad2a592f0e339fc832f4a","0x367445f8f2cd6375ddfa38134e186fca2df3d12e1b7ac11584e5dce4d815c88f","0xb1dc5df435c3e478ca4b2fc3b722ceb09bba808f79732b1c68258847f5e43b85","0x1943eb144a64a34bcaf1ee6ff1556079ffcbeb2b073c7c7dabb98e56491ee6f5","0x9f5464192ad4300ba8108ce13a56818bbf9505ee88e3a5657bdff049529c724d","0xe5cf189553084176b30b9e654ed4606df0bd480a198354e17384392a69ba7105","0xad8c7b446a9d8a2011b791d627a7e117bf8dc4f36192ea7f988789f9a598ecad","0x3de1be0e8351a492b2fbb3f0b1df634bd72383a8ef1e7f3248c23b60c573859b","0x1ee0987e0da8eb6db7c5cdc357b3d22c8bee48fc878dff98f38af731817be9a9","0x7ac880364eda2a247e297a917b81e710d893bce344d89425a0442cc9024a2ee1","0xb83fd07823aaabc4fbf89aff0ccfaf6297781dd0f08ab804886b579dac9ac952","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x080a849f15de656290f6a953b87a0b585dd14604bb54924b56061b7f6f326ae9","0xd6e7af92e64cc5a5394d9f0f39306b6a58c2023295cbc2ae6bc67648670aff8a","0xfd45c4ad573acdef07827e9e96d2579f0222f1a676fe8b6efcb44866de7e8854","0x45e2d9697811ece0fd0e820e72eca2808a1b0c109ccfbcb05800301159e8ef0c","0xb41e4b72b5e3d2f7dd5c6cfe5315238ade147ce3861174cfea14127562c01352","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xfee2b4291e98df5662de115ebc569fa3fc4f09dd23cae5e3a8ef806b9f235e5d","0x34a338a960555940279ee77cda42324f5df0570b27bdcdab5e4a068a6e53cd80","0x06ea52b57d240097ebec0a87ec6f3956a8c29ce3c9a6ff5cf1d9cd80af0f4718","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x635e12c6b0c13792ce57d8cbff8642e4dac78e1d6512fc4d2ea4c7ddb5f6c43c","0xf6ddde991248c3f5a4fcb27e36551cadda0b4c927a8c7f705d92de8a8899e90d","0x6a379fd8911aec42120fab9343bda18041ca0ead9f1e7e99c85c96d964d16681","0x952761b7888de6457b5314d0d8eb4e812c408ead46a0a39a07c34f1d041aa44e","0x4f49cd6cea57ecd78a2ddc8a017fcd32193920a6f6ae966684cbb72d58fae4a9","0xf0911693049af2ae4e6fe8a9a8149f24ceb84f978c83121a12b0aba3c0b2a6e2","0x1e58b50d324c61f2bca813635874f1ccb06c210161a5f6f6472386ba72ef8aee","0x7dc067f307973f18a09cf1215111075760938765cbae30fcbce79b063a8af01b","0x960dbba0917f5f9c5db0de580498e4e06b4d6481801213b47f7a854ea96d8a52","0xaba982c68d53e6d4c26f4334b347110bd9e8ce6cd43ebfe967108c0cdc07d0ef","0x352a337fc76f5e93b346acee9bfa6325806bc3e1a680be7a7f6754a20a3bb590","0x3c0767d8a0472639f5acd3199070e47c16fd76ef39b40f40f07cadac1864b5de","0x2bd8b784e8d5fcb83a14c156a2abd1a3f6552b183fd7e75daca131488c956ba0","0x475718051a644600e5de00b80730badedca46f2bf05bea36b03966e03142ca6b","0xdc4f2a48da0fdc8b3d5dbdec7a5f6e2310fb52c410f3be135584ee4b1c9d80cd","0x41f7424d734cc4c4972a23117367230a443a8d999d054c9e4eb1b9b491130e6c","0xcd2ef8451a68c2c1b036c3d19fb009ae0f90f7d9fdf99e2d18e80bc1bc8cf764","0xd05aa09a7a90e8ed959ae688760a6990dea1e7143d3f5d80eec9eef0bc603253","0x77c83998a7cf76709391e8a7a0fd46d8b206ec44e08391ab6132f673664066cb","0x2f5dd9ddb5e2320de20540b55141c7a9e8ece6753110e4b7da2d310e616fa25e","0x7a1b5ac811c27a39c958884926ed50f4407be56171186f0324fe5fda7a59be10","0xd36f3016489804b7b5940f06161323e4f032610de5e93cc578518b695b76eea7","0x1113e8e29770393632cf2cc7057217c6e2c9733c4ec4d6559a48f0ec714cea97","0x9e2a07e5c7f0764d38d9fe195301ff723f6a8fa8d9840b4cd99a43f69dde528d","0x2957e4f46028ecca442f6c29969c45c04813e107e684c5620a6a4b4e7dd444d2","0x72f77ec02f5689b05f9fe45616942509f8ef67f31d3d7a7414217c239ed7c13b","0x966b8dde40fcde6c1d3c05cd3bab64c093feb71f25b03ea56a1435a0d012fe81","0x8056c2bb5a539c8837b6b4acb4de07ef2ecd138fcaafc170615a68bf86773c0d","0xd42299356fced3450d4710f1000b3267a9be477666e4b8980747e1826163f5f9","0x24d3aa7dac2e6bfc24142e588c60cb961dac2fe271f09418860fd666ac322184","0x535c1dc0fe958b6cae3ea5d2d827c3419b7a169b5e0258f9e9f23e00ca0bcf39","0xda2f88487e385f5a67deef58aad0ddc91eaee8db2164f29966503e4801e8e313","0xcd3fb65f075791d26a4f30f2d65693d9a6060bf580eb7ca703bc78ea68419f80","0x929a69836972eade84ed15f5c56294f7cb81ff1a0e3006ba966806eb30d99e78","0x3d80d76a2a3295aae5b77119d45ccdef1d2d1a0d7b1e77b796a51b51fad4b28a","0xcdca7d06565b2d76ac31dd6ff8ea45440a1931a8252655d73807f2ec2e7181ff","0xd8fed9cd7618cf662586ef3473850db91ee6f73d7fba73a9f2db946481573575","0xf076b57c9bcfc6f2d65fc6902d6f8bc43e277684b7c9af9aac4ec673b5ca947c","0x954e14ae042dfbea39e3ee9c05c1e547d7e57c50cf19c47d603fff78307c25db","0xcad937da71a40a4a6988f30a382ef9caef6f0d009247df2d6360fd68f13f3088","0x2eb347a8b6f00b086b4d6412b9162599dae0f3eef94edc8ebdbd0c71a7ae03ea","0x7aee04b9a2ab0a519b7030bd92b89053a9c9475af0348a227e95c5aee17387f5","0x93486c1d21c8752c8505793eef0bbc30aa653a7b4da02441b8b2e9dd617f939f","0x852c2f9b67836e4f1e315e88cf34476670fdb57a66d80c31acf4d0ba17db3a5e","0x7c995111b81d33d0a7b96f9994f156e6492ada410d7fd35d45bf7969eaea3ff3","0x870ca4c1647e47f942d4b8c2490403e7b09ad2ae7401e63af7e05b48a2a65dbd","0xb0c12e7cccaefe46f019085eee1c33586ded721e2f5181fc68c2ef6ee20ba14a","0x7a07f3383378d57428bb75fe5f99bc1cea9d80e9b0cf58e7f30d726b6c9fc0c3","0xc208f7da00bf12ff87b3c289e3e4e6b44502b86a277d6194665236114b8a6495","0xe4cac4cf8861f9e96b45978c4f82fb434c54ae3c1cb77731a373a0fd3e06cc4f","0x62b3ffc84af57ec4f4f6c25bbef61a458298736a7f8391b977f76719edb8d466","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1b21ffb27f29df3e79330b24a3bb5505d325b2f8cc97123ac7237a7f93df5ac8","0x1a4f7d1f54f18e1445b30781f74c68ff44470103bf2103889c03176cb802f253","0x40e7bff3d6a5963f594751ad4baae59e53f336961a28b3c2b2ef1ce8e477256b","0x9788258580a0438add39052e133d1f2a2f29a107ebb1bb5ba98fd3ae3a31662c","0xe1726c544b3e24567c19c629808c59ab996e2cdfac0683d906201b678c8731bf","0xdeeda443e806dde1427dbbc2a1eaedcf7833640d593a7813dba897c0bed3218f","0x8bd545caaebdd14c868e86b4cd9da550625fa2b508677ad340f237fd4b4b9f37","0x2cde3dd8e6d8fe7a461e2cbdd091de6997b1951824d68fda0b37af5c17655a9b","0x966f0cf324f0319f8d8c9943d504e43d83346b956167ed758aa7911fc27ccb01","0xe9e30f0465a091880e8637c95a2f9247078e1eeb06bb97e3b398c5a2b81151f7","0x359f10e62cb80fdf888b7dd8434ea8139d2acd08c6a3999a012b2e2728253ace","0x2e75729fb89b6634c67ee47c8798fccac243d24fb3586daa3ec03da8711474bb","0x7b85f774689fffef7951c813d82fc0a60491e0ecf2ebdbeb006daf006c0878bd","0x6137a71ca9cf15429ad8b42a5283109739e973d1e3988102b69c7767a575810d","0x57f42ff00e4f30c4f6e9c1aa551b8666ad0e57518b32fdabbfa678e1ec69bd53","0x0bde2c19e9997d8131596a9c782f8d94173a416f8a849a10499fc657feaa9535","0x96befdee42fc8d070d45cdad76b08299577b35080673e69308c7e9b0f4ed30fc","0x0cce374d02d374b1cd2c0a13da1447ecaca441b74717d2f0728a57385aeb2641","0x9429d477c6e829cc6b5dcc750d7d88c41ac32f3edb7d7af0182729c83596c542","0x1453ccc64220074ae2a4cfc91e22f8a1a8cacc2d5549d9e3633eefbb96d92e3d","0x58c0012c7cd1d2ad9d5dae43596b502e913dabda2ffefd127b587527105e0922","0x1ca2e5080c79d796b32c8e8b37222533dc90843bde8f64a3ba8ced86359b4f69","0x7fe3689d136e3cd639d0151f0d04ffa8505801170bae5cb0d51d7cbaa520d5fa","0x3a0497866a2b51f67f062c841c351211040b0a0d5573c128a2b965c247c029ff","0x928ed2baa33e408379280b0d9eab521cb303b7d3e019b94b29511ba1797c1ca4","0x4a6f3c7f479f508e9aa853ecdbc55395285d767a8df87711050de04df6669cf9","0x8f15c8f8e962043f1d9611b4c56426b4d547801072291c52baf8f6b58d6be95e","0xcbd8907013eb6568679b57d445142e68ff16abfe9a861756b2582580c913a3a2","0x8361ef274c18a6cc96246da0ba09122a36dea6fd4391a15b41efd9065767abce","0x4d38526132f6b9d5407599f8a22da90757b427d5c1fa73deab5206bd45105bb0","0x129080e20cd250fe1154125bd05299eef3c5d916da068311eed6517816e84ccb","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x49908c1ab4efc1d9bf32370663616e73b0c980824467bb7e042a3f8f2eaf44ae","0x90bb402d1f8121ec6c6437c6f618efb541389a89e86c40fb43e555ce35883ec1","0xdd558d12d4d7ef83a88196de5a736086dec7c15ac87cb0806704633b18e109bf","0x68f682b124835958d774d54650632f469325523538375e8c8e305a2509715523","0x015dbf0f7cc4929cff7a8fa5197a9b72f197d9993c2b3fef7d842d277c28a172","0x8461f88b02c01a17eff35044880bb6aada7ca89dc07d2091844b348ea9593e15","0x30ce3494f37f872379c283f9ea684a3b1f10cc33cdd6e0e7ca9bedcd557ec1b2","0x48292e38e73cb40679913ea029ea5735a352067c17ff03e2359b22baa3f46d1d","0xab9c634415f0afb9a8f5ccc85138c1748cc2ddef0922934aa8f49fd487dcb473","0xf03fad8896593572eec6bf1367d790f34dcca0ecd1a3040062e0c941dfacf5c9","0x1af0bcb5c46a2db9c9b4d50ebfc500d516d0c8b9966f18fb2ff24623aae05a63","0xc6162db3b736a8c3381c1fd223efc050100fa7cff68b252f3afada256dfe9996","0x607ca5ca1ef8032d9a9ae0cfb5071b19c9a793a4478e742cf7c5619e51443724","0x0593d4a32cec5a2d163a142a48ad464ef05de429594ce43bd114048dc3fbf990","0x45b085ca22d7f223c6af4c489369c739e5ca78dbc458a855bbe537aba20e33e6","0xadf6772ea699c30129122cd32fe57bff1951bb67a96423cef0bac6e9bf374d62","0x16eb0ae8db39c797bb8dc2fee13787984a6f11ee23bf0b6cd5b0475c0cdca4e2","0x00ecf504f68f0d7ca592dfdf6a8f109ae348ff9796f958647ea028c0009e6c40","0x971691ba78ff55f606591867da064c8ac68d826a06184a2c5bd28f98be5c962d","0x2b7ebdbec66bcca09ca4a3c04d52fa6fc754bac46c638520bab670398cd1991e","0x12877552f97feb0991d772739cd7cb979c863cb13650cb397e9abc93244ecc38","0xca9e74806272937259a5f60b3c94c0927ab84e8c08e1488fcaef68ba22d80614","0xbe4e6a05a2f7fcd002e72194cd7039603515a72e99f9d2a49858fc0aad5602dc","0x5af782ac461e8c47921f7688f26242fb7a808081d7b7d0c1e1bbdfb5a7e4d687","0x64ed5dd935fdd7b7ee08c46c733a5d1977a378ea32d69f382f3bd94486585b4c","0x05fd0b7f31113dee31e3d78a3e17030622215bd77faf7d48d752623aa3c5bc26","0x102f44e211e399d63da6d954eab167e4b0bda165e6d27e55a42a657ea7189222","0xea6e1408f40161deff5411c01be5a5b9a3a2b67b894a8bc438b77d5abcf6df9f","0x3777b8432f8d8b8167c4060bae9ac36948de3949c7d231f5bdc5c71be2e19bc3","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xd375baaf5462d63f32903294dd16db378c5b00884f84fee2bb727ebefcd2e489","0x3f24bd57c93314beb7f87ab7830a055cb67ee80a13031d2b2b63a695f99f8ba0","0xc650924136f009826de8a127bc9ec467f63f0b28b60d130b262e54a187e61249","0x353ddb18a74d52a951c75fbb8d1b4a90c16c8b266a7bf61b4dbc7670a7beb516","0x35ff848d0cd3f28f5b6244e5fa0560e98a72d82d93594b13ae92cc15f3b2ca96","0x9f5978406ae269c6a6fb36de9fbd905014985b35e5f16f7bbf9cf0589e5fd945","0x59e39dc33f57ebbc169589abdc982a3181f85688209a618fa691f97143462f25","0xacc589be5f1bbf8983c4a4d86238a34ba3af5c082ac4292ae15e3da4a10ac6dd","0x4f6fff7c142cdd3dde8a1f58dd936c7e52c3f978bc986cc4bae22013cbef7eaa","0xf6419a6c67c75afada7b892e3416aecf34a38a74d396781f743494d92f7bfbef","0xaabf6cfcda3e18a3b78882369efeed228dfb382fe9373d0077071a7228a437bd","0x10750893e5a3b4ca6c0911b475d4fc43b60905b413f4ba1c5fd387345f6b71ef","0x3966f68c6ad23d9a30caa415784165635c292b415b935c1362fa0a29e1456b89","0x5cf556270bce6a9123e46aaa1f72ce6c1f856dd4ea90aa76c0c8971b6a64f1f4","0x939cfa69c059a6ca406eea7eac34777004b3c60e5b95ae14d541f6ad93b7bc62","0xe8b842c33f05fc44b4126874e9f67702be2d148af464d9e50ebe04295b5b3d3a","0x502eadfe84a5fa3a229bb55883fa9ced870a8dfd3ee098b4de678528acb50ea1","0x6512d50a70a48b96137f184651648aa46ae4b672c520fd575e8dcaff70950622","0xe66de027b9473e32e12b319ca684fb9d1ca35345ca08ba00a9e001ce7a1a2c7e","0x392b5b131cb7892966f9a7a4b73752cc9463f5ab8861e9b34928690ceb67f1a5","0x117e1c5b7e8bf3adeb985084abfc72d3aeaf6926a84c0bd481e5d227809a3704","0x1a425d4f61ee707f073c31cf935ad7e0c555942ddf0b76ec2f754881838ef853","0x46dd7886279cb3082a219de54e8ca8988cfd55bb86c9491180255c8644463bbb","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0b580160ac7e98383d60bb0740a4c077a4cf05e7b37ef0d6ad7ec477048f8b8d","0xceb62e021959ffa8ac2aa7ab4027785254354ea262e3cb9fd66b5cd2c6bdb801","0x5a912589b7f5fe446f957e8cc65144556c23127ea55cd9eaad9c25029662ca37","0x1c20789ba7b3de06ad6051f4dbf81e68e7928db0b412f6c1fd757338735b8463","0x5322c58dc9639876efc01bdcd82f4a8835df46b576235e138737b5f8469bbeda","0x63832a5a1bce698179159b705328a0e4bb826d12a725cc46f3e4ca06aa7a737d","0x4ff4f0e1d01fceba67c4e7d55593e24886944b579867b8846dcb02c2ae69c1c4","0xaab5e551b9e4409b2f602a64d2a85b54ecc0c8e2ce84e676a06489d26aab391c","0x7a6dab5ebfca90a88be46af57c072bb1d9e6568fb994a51fd2daf16413d69fda","0x440090627bebf8f5a1ac3930b45ad813e47bdcd699c241e73d5f50f6d6541563","0x6c8340e1f519d67ae0e6dc7b77ef5ddfd222c62a5213b15dde2ef588ec238f68","0x43026c676964ae8351889479a4ad33a981703b2d3585dd55450a5ffea24f215d","0xd8e55574a86233fcf662316f352edcc2af630bd17342241b23ee49c888207b81","0x32fc7f4158a7afc721f228b5714f07d261f682e51dcedd5411e7ddd461c9a7db","0x4366fd11902e155069e5f22d0751e92d1442ffa5f49d1864c23400a985bc636c","0xaf2634b469ef3b4be6fa5fbb7bb7f6334cea8c3675ad0b1353072c673e01500f","0xa7c750510f26d8fea2f046dd31afc7d1c60309d1af971233ff0bd45a83fc3654","0x1ab0723880e898eeaefe7f65ffa5d86c1006d18d45db35a33a0b8d1206710a8b","0x3c49dea527815beb8c133830f38b381ef03bc9a353a6b7fcaa8d75a2b1645786","0x7ef0ce900a9c5953ff2b1181ab84cdc837cd97fdc2d419af04512b32748c05cc","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa16f56b99e0a947cc0ee5a7bfd335a2bd665db0f4207bc4d7be10aba8ec73c04","0x61162d4cec12e30aa508a59bd73ec1a9191bd9443404527d2711ab1d627f52d7","0xba7c2e0ba0b0f6db7c70a9f8b1681f55a40190a4d4d06b73b2ddcffc451d8ea6","0x41ae198fe67ae68d989c93e43d4cade265488ba6a24fb675f68cfbfb7cd41492","0xd5c8a0f13e97ec4fe85781ac8b89286275caea1268fc43cec586730cc3caf89b","0x4fba08f4b3c6bce8d90e4b9d9677eb924437352acb29a8289d7588d1390e7508","0x68c4b0b50f067137e570bb154c9a857829e97a2793f11190a3a28cdde52be7f8","0x95f142a2642b31cd6d315a75ff34720bd140b6e5b70ea84f5b0e2138871dea96","0xba219175c6367f7ec8ca7b8d248648ae00b329d051bb28e144d98f97a49b2e36","0xb213e13d820f917eeb53792facfc84f038abfdb744446c1afdce8dbca8687615","0x605ba33df1ba9c3aea5bc72daeb049ddd1c4930b3310c55f68d567988cb05081","0x220524c832b9294ea905351a957e4282aa06dd746134e93701d52dcda94ad051","0xfe1ad339d09e726aedffaf0821759f838d531bf9d45a090b9849054c1ed881dc","0xd7562062dce86dbc821a0de0282a8e1a65e881c4fe91ce42142b39ff0cc93741","0x337012abb9bb691d614700c4c2b556fc0e582738f414a9d576f2850e7be5d68b","0xd92017ff8a268e0c72b2ff3f97d507a1c453720e528ea9ad4c5d9718ef479d4c","0x7e04402807523d5d5334a5d41e140f490cf57c082ad0b9bb55b14f307ae3ebab","0x4e4176106bae3b1a23bcd36da638e0f49f0fb8f3210f448be7aec6b374df4aed","0x95d7e7ec6d13f30a8bc0f7779edf54bbc31d61d6da9493bdd12d9027e58bfe23","0xaca9d422403eb337982854d273b4769c1fa415d1fd84f61d2a0b143cb7d8ed03","0x7c932c3ae7d760c36ec3010fce9f22d26c9381fac1d625efa1694f4bf222ee19","0x6ce2ed89a4c5b352b3a58c92b5f876014dbe58620551f98c00fe32fd5bd7fc03","0x1f140f39fa39b28a05217c8d749a7656a777da362818855ee61ded87907b0966","0x4078028e8dba0d5e205a02ea3e02d71945bf0412ecbb59dfa547be3dfef72a7b","0xe1bd869ba0fdd467bb68b99030a3605652801376e8e55eeb78a6e18284706c78","0xdf3480941a0128c91229893c14a0aa4e54b3bb41307d63456613b6e3cd4b7944","0xd4e78266fa5e3a5026e5004c23558b35e004d6da1d580ad4c0da9c3fe4e167a1","0x6dbae8e06ea1a1c9dcd0bbe7647ed99e63c4067612fc277744493e7f077338d1","0xc1e82cacd33327715e794c779b6ab79a70d8b58f824ed6732d7fd3b2418d01c5","0x692ec9d1418b258fd553d7b7623c40681602b4c81d147678858565d5145903e3","0xb874fd21a2ceb92598cf6d4e70b61dce20d73eb1c83d6951c75fcf3043283bd2","0xc3481252f344b7fffd6a90f44280f7db90c13cd7655355101eeb5dfab3f4fa2c","0x514601a4722f396e849497641b2d737d163ed57384ad229654e2363aec09ce98","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x2a721e145740e27d809da7c74f7d7777d0646f8823685130b6e5e3f88c4098da","0xda8c082c8bad2b4245852d2f73c5eca8bf9b6b5c1b98e9d51491b89a0bf1b31b","0x1d19155f5ba509e6f17e949341e5e07b33c73aceb5c96f2b1eafaff08137f827","0xcd6e9ac65ae2a6c098686a0568708d502549f6256f3d87d3e3321003fabeaee4","0x11fdcb2823b5320ece6a80f37a5c2a0f7986aa534748dccbabdb572f3aee695d","0x14d912c47cd3c87dc0846a20e19c908bbaac93deb4e744d5477f0366cbd200f3","0xbdcfafb1713d81430abf171b24151c42048da09803d0ebc0eb83adda840e7252","0x4fdbb31d6c497aec37e01da72187b90d9cbcada6f3f93a73e32b45a74f59e2f8","0xfbc8829e8bbe0816b8467748bfc9d5b4c31875f2627f1695d90b68ee49dd05d4","0xe5000309aae1aeecc2b3a7131275e6777477b209e44e8b9055b8e1dba327f4cb","0x70c535b47fef277831b459aedd25ed9112bc121aa0ab7e71713e19b6216350ef","0xbf73691204246b43d34db6e15fbab9d2daf7b9bb96568659a02abd767e5e0bb8","0x7e7d73b93f9c0d556a5d4575cba25be94178d25af002a9dc6a6c8e2ccf680759","0x8c045456146f5c66a3e1a31aff99a992df48d3ddff2b5723803c53d3fc6480bc","0xa6502af0372466864dd29aabe22d0a61d5d4afa6be582ed92aa5cb55f04d3eb0","0xa3dc817af97d3f14fd82e91be2dff57fcbfc65a5f3ab669a2cbd4360d500d743","0x63fb4d0f5c59b3eeead2c17f5c19d4f0803a55e9bba45c07613059b112814cc5","0x3f377babd9fdf9e7e59988eca2ba0d71b4c116c5182eeefa1e9a96659f95485d","0x7fa37de74604146c00404cac050464cbc5f921ea1dd5a6151528d0cb59ba3413","0xe27467f1d7b05f6fb33de6c6a1850f128f3036666d2b3f926566c32090b54c38","0xd9b644df984b7af9b24abaf18a5b2cd5075cca26687a0a243228a532449a9bc1","0x2f2fc270ab8c21d9f7aa01ce462638f331e8d7ce3ffc491af952a9d21a81e189","0xbdb4e600e4a3ff0e5f05140bac10c3fbd82920ee26e056fa5bfc2a2a5f5d2cf7","0xf8bcd43d8f8af468f01ebb7dcdf1c3f2a13975e8f0d02b9a5f9a75711db0d6bf","0x9df0f63089239f0ca17edeeeb75b4d421c7a951711112c8918977d5c786099b4","0xa56bb962d28f545f24f0cb1921b778f14f7b4e0150a182493f375ceb8e8f78ff","0x2f14dc8a4bd513fdfdfcc016bc9cdd1909076c942aeaab7aca9f44bcfe43810e","0x261ee3167dd7d55e3df273fd9ed93f3a315af7f8d58ff826a1e11c1b933c2a1a","0x13bfccc1859ae6543e3ad74384656b192159f7a914f5ed48ddb6aeffe848ca32","0x8610dde8c5ad4ba7c5b48baee604908c3b83807b8bf21e500cdb3e6a150693ea","0x3a00e53744d3353ae86017f6aded0833cb178156f16b6a925c6d751875995074","0x753458bd0f0e325a2c09e787a4521d0ff0a40c8350d677ed79e1399ee9e6e1a5","0x4653b23816bbce1e7cbd5cdb1aad36efdc75f97108c49af4f47f68dfa7a7e2be","0x6bfc73a48f9b0b372e56e38c6367e99578afbee2f36772444ba9b6a59a5e9feb","0xeba384bcdef2736212ce62d836caf24d5f40808d2cc4c1f9afbd2f5c026bdf71","0xa72b6379456435d76ebcf4a6f3d1902242303d976fd0ee02026fd13efcf58bb3","0x5f84bac3be0352127d76273ecb28e9b27b2baf1d1fdffd9995b4305c0c1177af","0x70f3c412e2d0c59ec3ce17b8dab0cdd5978a70c21992f0a47f32e3cec950cd02","0x7a47be4cc5b26e127bbef99386192396080f6b9cf1822e3ac3d5f1efc37c13ef","0x7e475aadbed64e097590b2afeba516f4aa624aa7ad78dff5f17d604531a32d16","0x36030ef05362f7f34ac9cc09235c925de60fb46065aad0ffaf2479a31de21aae","0xe302f5c19a5e666cfa6b5a73f240a6e210f4651f7cdba715ee6b60da75641c62","0xf204c7ffa5d2605206b2cb13a9eea13a864304e5726f4203e205e151f85612c8","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xaaed617aebccc70ae5b8bb1deb43893c407306ef768edff092a0daac698ffe1f","0x2dd37f28eb91878dbbc80e7beaa37610b615b07693f8444bc6d131dd0c4586df","0x1e7f5f485643294371895130984bb816ffbaa4756b6366aceebc684a08028e48","0xaa8c4ece551c896e667fdac3b10b28044308c583ed22689dd55425677d35ec5f","0x2a5c553fb92792be44b33398f18f65311eaffa856591017596225635e7c02597","0xf59da15b81492e56b8444ec9011c96d5158b9509cdd8cdedb46eb53820349512","0x801900f1f666cff20b3b5e342a2dc882cafc2f75c5b7290c2f3ec1355e783c2e","0x5a8625db19496c9366266641b2800483ca395027810bd9ff0f7b92a2830e8abf","0xb38047bce3a9cf77ff4185f82885b326159d065e68cef43fcbc071c7badd47d0","0xee59b7b8e0c60e7344e7dbbefbfcc7ea3734ab50eda7d3493d6ec023aedd5d07","0xd131d141def16b32be4dfa48df1db07831ab534230b6d4461ebdd123d739645f","0xa0b5e92b4224e86243b666efabeff2c10ce65fc0a6509a534c84d854842b2a2e","0x7c72a5089281ef9bf0556d7b27f5e195a18b137d3d93f727b337a0cff23a02ac","0xaea5757bd5e65d7a5f3cfefd4271c9ec099c39a81219d7fd6531e29cab2d0742","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x19b7701294ff85c98de01a1c0f300ddabb7d9d9b6ef511b879d3ca377b5bfdbf","0xffd21df69e6ccdbcd90aa7cd3325330bf2f94374cbce2c0e7a7566b872ce1966","0xe69b6372ebe586ac7d3854ca170315e62a814d8442bbf8b38c62d1b85d57a560","0xf6b73793ec619943deab6740f807042b2446dda2eadb6865fdf1e948038338f3","0x05f7ac284977be65abdd8e9240e6dfce863c7b59e2a09ff2d79dae68ca52dac8","0xfa6518d10872bddcf48c1ee4596c7f89ed1005e74d7d473f88039504e558cffa","0x7dc351a327c44a10370ddad241aacc4953f8279bbeaed9cc1cf6f8d85dfefca8","0x469e2b45bf3832fc74d77ad90f93a4f37ca28bb3b4279f0b2e327568075f9027","0xcad72d6265fd4ede118ad35a2b09a92bf03c73a90a05824de058d09a301acae3","0x599f8166fff81d4cfea501b46d0ebc659c0c670c370fd8742af9aa6ff45b9139","0xca21d232821cc2b81656cfe10156445bb85b6f6430911578887e65f261d5c3e8","0x0f0c4e277e3dc551363edcb3191c6ceb6f4e89857fbd9f56944b604d8a5d6ce8","0x98981689b3d7f1d1320f8db51ac8f7eb01726cffb4c5f0c8f035095ef04a9754","0x8e4b1637eca5253eecfd3b103ae7155d478fa1b043372c3dbcb62d97d0aa5827","0x9265149b4782bc96ae75e3e73ba026496049df2c712c6f55b78ea6cc4d87181e","0xbf4a3b419a4aa2863cb1f7031761748ae6c985d4e7885e716e76eec6c2f74869","0x11488b178cb08c054ada345b0970b21d378dbf28e3701a55a895c1e73c518ae0","0xf62e03aeec4417c1fea3b1f068d97bac420bb1ac110beeb16a74d9928cbc036e","0x631193699f5da6fb7b14276a87c7b34d287be661e0dcde28427b57d1ffc23607","0xe35c505cc3ebec38685edf24c39cf3ed9cc5d2e65965b1e44dd0529cd2f13bb9","0x98b107fd91450cc0ecffd79b7ea97197501ab4455a7c8ec08a1585db528480c7","0x3438ad0b5785a39b8da1c267b736432527dffc9b842346bb52ecf499c5fab451","0xf23e2c738e6db87544d71e5d9dd796afa40f4cbbdc3b53b60040def089a09bf0","0xb65c366f1801b8489af4215720235db59e75f2815cab0f9094151ade70c4da9c","0x94ad5f63edbd7d3b2f50c5702bbf6081053ecc2db95a4c080ce3d2286104e37c","0x605b3d4ff9a7ad82e7f66c7dd187d0983b375f3c446571022c4be135bc247ff7","0x3d3298558282f4e6ce6bde28efe89b4e48bfdafdca524c39aa47a2ee1ae71df9","0xb65fcc8f80e0f61128cab51d5397705c5b98d6d8e9593c118af764b65bd526e1","0x3f19520e06ee4b1ffb7a7683a1d21d8b9d0f2f6b7e843230a4f568b98eb57d88","0x91cf4d10dcbb4aa0e27e69633980760561f98b92119b628b86c9b829ffe9f56c","0xd81c9326671f2e4b2f54c09ddc5a3258e4f8777be097cdfdd9588d0c5fa502fd","0xae507ee8b03ea3b3b0c68ec0018654442f3b641e7d524cf364c1a70eb32ab59b","0x70c976a88fc09b44212898c123ab9c7467119a705b1e0a85d0d0b5157db07be0","0x27e8884c36f358c0b3fef3a838243a0e540eab636cf6d1845da3e794a8520881","0x90a67576182ae352fa4e46da090b9bff4d02e2ca69b7d2ebb6afd43fbc472f31","0x205d215752948cd0b34aa30d5eb81fbdd62440d86fb62532d3f3738318215dc0","0xd7b474d3662ee61273a3b6bbc76dd1bdfecc3c05e951139d07c0d5612d839bc0","0x6608011708ec76f7b1b0df13e122711cc5599b6baf8533d1873979f091ed7e9c","0x1a2f5ffca387484a03f3855485c6522acb9988abe9a6c7010b8b6f292e578ab1","0x57f38a919ab167d0de0e4b5d76be3857306e91f2760976fb1fcafbc47b2629a1","0xe260e7a2a02959b931fc467bc2bd32051c23e9ec4d03d239c003828b7accca32","0xaf394b4f650e9d3a285d5986173effdbec03adc436a7ff6a5b83ba88c3493c9d","0x1ca85e7770ff781c8a078f48d3e1ffe5b55d6d529701e22c57bdc87c80466268","0x86ff9e90381e142b09bc5d8d6dd10a0704d16c6906a6c18c77157077a419d6c3","0xb68c058935762e9ff1f437dcd782f68e0cb4702e8d949090d3997721dbe32deb","0x47bc1c6bfbd46897950e8946852df22b37b1c85909b6f3549437868a87d44b89","0x4dbc074fc57c396811f3308929f1d44bdd0cdbbc38d5e001e84513a1b40019e7","0xce4c4d108b68ab5d8341c8f0e98882fe437428d8e71a74622ea37f968add8862","0x6d363280632c9b4cf34d1d7f181fb515ea4d5b9b299c1236766056b935c9c7ef","0x0db272ce0a0ea46971754cd77c36b52fe4f31c837462dd4fb6077dda52a3f9fe","0x84f9087054c19eac6da2e94e9b1beb3cb88b0b1fa58334097c6f1faa6d4505e9","0x1f5f3e15159a98ad7f1594bff9b59a2da4f57d11dde127679a8b0f9132c8b380","0x990936c0899c956b4b829656b24c56ac76dc6f9c773e70bf73acbbcaf539d563","0xd40a555d86eca8ad82daa965afe34ed125f9353be36ad6bbdb723b9d69e66aac","0x571cf6fea91954029aea836a1a3e4b563d292fe34d58ebb7371068e5b53b9a30","0x0a4534ec8038d56f0c77084fd13d998e0e84199fade858946e546655e7887644","0xa9d9fbd4f02bbbba829e50e807d2d3bf400ccd989b1b67bd79f6e5d282dbfda6","0x48cdc2882dffaa2b651f7dfac2646c17cf99a348124f60b61e8e572a342600b7","0xd7203ad04f96f9f5229b39effb99984dcccb8045f03f9a1fe56ebb4ca70a87a5","0x85a3dd5cd6ba0b92c5c65a3c06cd7629b5067bc44508d1828dc7e1ff567ee7a6","0x8ed7bb5ab80e356b012c736e945a62b2fc21b4ed3605899900f45c52495ee6af","0x7c07bbf940d2152e6ac9237a2cd06d5092897545961ef543a02164bb405ec536","0xb3264228f3482866e05767fd2cf94a7eed7b6f024434796972e6942995fc6783","0xa772f749dceaf6e7ae18b0608400b62d15db37d030345da319af43d4faeb499b","0x8f60d39eeac57c4f89723ae16a8eee6b062a02495c0977e70789add038e9c074","0x180eb8306e39512caed5d84c4f50eeb959ffb47893e733a258a4ac312dbcdbf7","0x7b0008851eb3f79672419cff4f1182526269691d58a0db366f38d97d9ee61a31","0x741545b2c81346ce94b5de8c50718d6bc9ca454b1a4a44e33282b0ad2e561868","0x546e544c85fc125408f9af802284e19458f66fe2dc84529784b10e3d929cf399","0xacbcf1b85dad0d8a1681f36d10753deea5d623aab6a8c726e3a22bef138dc07b","0x329b8ae4f10b82ae0f022c293f7b6adb6fa1f0afae81469d2b6c2f9210a1f640","0x1d5142b05fab574c9c41b46f2550f3611bca57e4505677863774097ec99d1324","0xb9e5a61b6300e806708ee1697fa19ad18f474146f8ae8fc44c1ac5e344e08880","0x4e6cff77d2313061fde5ee48eac129f8221923318365ac508e64f34f8212d892","0x599b074dce8f29514c6d624523f7d265c2ec444cf002ab9331d5ae348cf98298","0xb58b0d67619b7fda3417bddf65f6ebd531e7ecdbbe9745013c19a2ccc434653e","0x9edc1a9701dba368045609d957e30520d71297f30c038be3fdc38356c4ef6df9","0x001d14026cc055b0adc7193bd63c1ab2856cde6a288baf58cb1f53abe9730911","0x86eef1defdd753a93025651edb8ab1a1b2d53639825e27cfffb48298bd687082","0x4c3ee837a900ac0892e651b8c161e8999159450d66846075ddfadf7127986043","0x077bb34206e7ea5d0da627771d9033500ec52ee9738ab234b73268ac93c3cecb","0x50546562d4cc1af436da33a9e004a27515c89e2ec8f22d994e7c3fc64f84ff87","0x5103e25f5d173de1ab9b7a0040cf16f3ec175e5b17a170c17b823bd0796bb303","0xb0770b589864f8f46394ed7b274ac79c82affa754bba2270dc490519983e9c9a","0x1f6c22dc8853a923bbc33911c810cba4324bd153f266be1c7235109d265f0cdf","0x76263b1ade9130f5730f93f16832973028e9c0d4ddec54f23e41472199b57821","0x204795ed4e93c4258e3014bc7e9ae179de0b36a26ce7b47ff0e43fede12ec504","0x657b47e3ca098a557717f7359a4704ce78a7c90c6a8d5ca792550748f619228a","0x2ffe84df86f8e33726530f9066f1f4299ca9ff2bf55f436113b7b37da789597f","0x9afbf12c114d2a171b7c139bd008b53319cd218c841a84c852c29837d2c2f271","0x40a88e9b83a25242e85ff45f56e55e43903d43cfcea9e2b839f13a6c29ed1295","0xbad22d75f6e2dec3377cc58fbe8e7dc369dde9182b909b399ebee9c2340723f9","0x96409a6618697aa91ea47b941316881ddf1bdfb66ddf553fde4faac601a5cebf","0xc5a4f9c4e110da7ee6cc101c85acaaa02c651254aff73f5e725fccdc5d4ca359","0x01ae24e0cda191175ba1053826b26e3c538ab57a3190be66407f3d54a1d69025","0xfaff9e538ecf06f171e8e3e7cd843d2ed7dec8f58808ab74d6ea5d0d00f8f5d8","0x1b3e5bf56d1fb976e2710e3f349aa9373633b9faa87e4934a6c43454b5b23b2a","0x68291e6f87524bdc4965cdb4f279a83d710088d3d0de432d25f1b44602998911","0x671524fa76db082fd99ecf0beb7a3288425be0e798e74b0eba5839c1c6d810a4","0x046d739aceb152476d1d8e108b238ad3e1786f66f11c29e263b5b4276a55a6a0","0x5c88c65f496f7f721492e64b623263d06a7baf2acd4b18dac4a6e5f12924ebfd","0x7296dc7022ceae57a3a3b0a9ea0ef3b11469ecd245ce9f29e7e0a3a0ff3853ad","0x68652a45e520077d5536f9a71604e63982746be23a11a42fdbd1cf0cc5f46e3e","0x7d88dbe60f7174f0428b5677268bbd77f87bb8cef739fa02b12b6c5747779ef1","0x47096fc51448b41f2106156d02e66ecf22fa8199a94698a1149f50cbcfc63a67","0xaa6a99c08b33d1628acf93e3d21017d798a5f1da4487d067f398cdae91ea11e7","0xf8360e4fba67fc813a8a483f53b15cb2564a91cb6233a8894961eebde4ed049c","0xd599864911a86771515ee7cf74daa8159c0aba3c9ae6e6237fa866ffe41f02d3","0x64554ba5ed2f21917334fcff42f6c660258f728a9ba5d350159bb6773675c51d","0xad035ca8c60908b47a7c7a55975d4dc98c4c6e57ffa41e4cbfab7977dee49b4d","0x5ef394b9eeb8309db873134a8a8c0cdd8de830fac0c4bd1279f6ebe3fd66e9fc","0x82b13839cdd3b942ddb5992a57345068f326c84e1675aaf3ce87af0fad6dcef4","0xc151ea1f678e96df6018688f0c0251ebcd082d45acb0b6c8bc13bd184532fcd5","0xecefc907e4557ea9a6c3340014db3cd212f81cf1452cbdba0b373182809cd6f5","0x26528c01967703eef8d1704093a8ea86ffb202c4385b8dea0e88cca17f728d3d","0x55c1e6b82acba841889e7dfa8fdbe5bdaa542e8019aec951fe4d0f8319315c9a","0x58b10960cafb14f072fd95ee550f4e490c22e9e813badd416ee5d719fba2bdb0","0x95b5129726dc04b1e8f6d6a057cc63a9d3382266d6279184d3d7a8dd6d391a95","0x06ca9d601971754637f73d10169797636e77e059918e6a7de32f8440ffbf344b","0xea51b4e8d24bd464eb403bfd504cd1b097649154233ee632c0b69fecffd8e95c","0xca2c15cd5f9c8fd2363b9903df5f8613662ac31105e354d32705bd61313b738f","0x7864bd24662b191a72a50cd9979186c4475207e5558ae9bb5192d529a5834e8c","0xd3b3309251caac58b9d4fc947def5f436d58008dcf1ce5f10fd2ac83e69a0d0e","0xa49206ae1754b2f6c24772b0ffd385889b48e87628dc8ea045ea7c4f579fb5b1","0xd5552f5218220df15630de993811f262829ab1b183e9126d83c5109ede23c5bd","0x85a8d0e5630293155af4181cb26fe25ec7c5e246fa4f86111c27e45537f424c4","0x7a5c8f490d5b4388abb933c6c74926a80eda1d098095b1690fb4ba41ddbecbc5","0x3c5f409de2fb052b40fac4c9ae230875e88912d4608f9e826541417fabde2797","0xef33a2119d9ec2a73f9cde0215d36398e35f3ec05d9c66ed477a46895381abae","0x7a1ee08fab58ef9f46c8807558c409e9bf414a7f95da81c965ffe5036adece04","0x76e8065a6fcc4ea4ee8d36d221bdff0aecba992bc65f6206dfb49ee73b8d4b54","0x4ae401a680c12eb5bfc3c6461b3f58be8ea4037217602713c0c79772692fc9e9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x2e2c42eccead653fdd607f8ef2ae694da0e63c87f5a655f66953f08a63760ba0","0x87325f1d165c49c56760894a8a889cb5b3c10d3fcd6e0135ab41e2587002e45b","0xd363af114a43cbe7bb2f16f2a900cc01d8dff0d922d17fba9040c8eebb6b792c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xd502968da6a2c8d5f7df7acef2edf643a03a72b8ce19efc65a02a2db11abfdd1","0x99650da1dc7ddce021b909cc93461a68da461ce5bf4787fc0fe088fae95e1996","0xfceb383b98d3d320380755a981b8718a728954e23384cada0e6a168ca8efbbaf","0x7ba1df973e0bb57793b0d15f1c212ff34e12509ec9537b9a24d143e65bb36e23","0x07573bfe4c221d12b8d6c8ba26a7c78c3cabe9025ec423e957cadb2cf7f688a6","0xda3e68327aa2d1e4296fae3a05973f18ece3e453d0443575d5251cddb871b9ab","0xd005f6d5da1071d62d1dec652a757b6024e6f1c48553833367aeb8e9ff5bdc7f","0x5407f1e88ecff2490343b449edc2425773474251034c2d362aed1b7cdd8121f3","0xfbbc989b2d1f17c0fdeadd1842aa1a238c5624cdc1a527b8ea640b345135c2a8","0x15dbd0440e37cafcb6767c8998036ede9a60010582f0b8adbd0e02eb6f6cef98","0x08e74158d34a196635da6145c20b52b3fc0040191602d0bd17cecc450be22384","0xf48b5862ed4d33f67bd2b1ff3f47e565f1c4721fb62522e7daee52b09fca2fd5","0x25b779e64206279c86f6847bb324be225e0ea736577e99f647587fbb273000ab","0x710620297396a1d65ab36b2250a29c082e385a2a435c4c7da279aebcf3e534ac","0xace0b20de07d091e838c5ae6f7ecd0822add2384c402d5c346dbf278fdd212ae","0x8ecb8c2ed191d9e5a4a12944227366cd136795adc10c7743fbe1f2906ad4306e","0xb368a0c6f0b62f7c89584687bbbafc5799f32efc984b8b9805e93d97aad75b6c","0x5cc33ac74b27b41cb1681bf7a774c0921ee92c0f101e967079a6b879cfc775c1","0x44a6a46b5f6fb160916063914494699f8d1e2594d9907ee13aa97e8c1801a514","0x11eb8e008c375bd7cff2284b6a3a1b765cad86ae7c671db2b047d7575d249468","0xdfe14d157d66529824ade6b09b040951a708e106261b28cbe5b2d93cd12c1969","0x03d685a4f9ba6ba5b94bd158c719fb0fee1e0d370d68ca6caa6a151738625820","0x3115cc7903b910248fd3a25e857270abd47bf4e999ef25eec653af6ba2e201ea","0x946dbd95352c43c39675ccac0a02ee4622c8247915bb8df64c0cd934b9108147","0xefb656c39e008ad45c11bd364d7c3ffc555c0b775fd6d9db789918625d136435","0x820f4a2493b1d02f82ebe17c836c36f98355ca13e775e277b43c5982a7b508da","0x999ce987e88cea25958507f8e81ee2f252a21e75aa1843869ad3e66c806bfe19","0xa7684eeacdf665a94477b1eddc58e8915b98f53c75aa6fbbfbda0feca7209e35","0x2fcc84cb645219974005f3a7ff851c15b414a72c298c112483ed963d767c5852","0x53f3640f7aa5113d5c1683d81afe4d5f67f3a7b1656fe40f95d5355a632f555c","0x0f349e5af82ddb761848f59d277caf59964e716a5c9a277606414fe6670c2a15","0x5f18b3e8155961d5f027790cd92d758aa048392a735e199853a61c055c7e0148","0x1797378d21f30ab8f1d0d5f02bd0af694195733ab9d99ef60aa996562026a457","0x6787f4f18c766433112b7454edef427030dadc4e6d2378f581670c662c3b9f69","0x1ec5a2eb4e717f08aa2ee2bbc789b1928c36ad1e374df758575f4eda2a74ca54","0xdf590ecf74084bc78e0c8198711ff751a6fe14ca5e22069d74c1e35de89dcc99","0x02994da36ca85e0a2b5de4eebe1f9ac748f5a6f3a3a826e75c1243a1536cead1","0xabaf9d19e385c6f58aecf36bfcb4d402752f792cace10b5fe7d341c320dd2fbb","0x8d5d57a63dea4a6c0b28d41a8b8e8458ee7c794a2d0c7d41e3e3c062696a14c6","0x57ae83a5cd07d7cb028ed49f0af4b1c37178d42a8d24e7ec3722445a4756178f","0x7d394632145726694940f98f61187db36b9ce37be98faf0b99c26c44487fee0d","0x4bdb471249c02de6759504690cccd91626772eefb752bd252f2bc66f2d67d814","0x7195b1fa4494a77ef2739366ee08251213ab728fe5aaba0abfb365689a3a306e","0x621cbd0c441166bf4858c3232ed4400336218c88a936dd248806218cb9e7586e","0xf0f827b3b226cbd472bba592256e74427b20f997b359d34c40450d070b027bb1","0xdc870ceb8a357ad3be1534161d03ff9eb342c87ab812b2e0ea9fa982f4095c5f","0x8804ae0b41dc5a7b9dfda28da9dae0fa4dca401387053c3b9b3a57f50556c5c7","0x098f1b0f159797a4e1813cb6e810ce1f47896cd0c3b47dea9856c77a2084ca64","0x78d68fd40b04d78c7746b328f18c742fc1faaec169752c9a07fad2a8cd8f42bc","0x8af5dd5821f77de755ec1c2854e1a9bacb1ba5115868e0c244c4b7461d2d55ee","0xafcccf2019651e08bffeae9eb2df111c5484a3c3cb147764ec232397a07efe3b","0xa0bafffb3f839defb9006a1c96750d6ee55bb5be41af54fcb16d3b016336e952","0x74362c9612ed6e43d815adc178ad2c2c16e0da8998728f31f774a79782e6892d","0x5c27f74b8a41599a318df3fc6f3f695589c6ebcc05cd347fc0c8344dc23d4d38","0xd3520e73893b1ac38da20c48c159df54958345f9f78823557eec485eb3d31a4a","0x41b066e5107a561653ba2250bfb7cf2c207f1f705cc07782a22c54edc1b445e5","0xa3e6eb18f85778ff22a5e11336e00dd830195a85abca10046c4ad14f742c7dbd","0xfd6af6bad616a6c0156954be5dd034a170b3aff612dc0bb1fb73c394d498510d","0x02db06dc85612d6d463b7a661bcc9b53ce5856d3bb6d0c24d8169c0a55aa1f0a","0x79dac0272345cda80e128c81b9b3275b07e057243326f15f1b58f98c5cf8367e","0x85aa5edbfe2d785c0e8b7a9311c0b8142748cba5028c7925bb75889785562ffc","0xac28dc5bc833f665adb7afaaca000de9a310118fd9d77d21bb0b651e9dcd4b7f","0x8f5dbfa1132e1a60d87f92150ceb79b0e3e731f35e84cf0d761e4c8bb41db79e","0xd96094576797c3663d850c5a1158f53a653c46ce3c7ae01d238c8870af8d57bc","0x5ff2dacd355f9ffb7852bf05985a9876ea86a7afea30ff47fc84c04f1758ec2e","0x49e4d3386c594dc15a6e0043629706b05e4e09f11406d09f2804753c378ccc17","0x35a0f73a2b8690bf5d313640ba09c29e70f1177809c95e5c2435ba277ca70a9e","0x6e1f623ce83157133d26cd9ec6d2f2e18304d5638e98f7e267e0a2f77d3e7b31","0xdc3bfef5c4136de046ed22821c51d0100d04c69198042404edbf8a677470849c","0xf84447182e13da2e6d492b8a3f875f4b2f197550ae012c943fd25358f269cf26","0x0536db535501b47a14bd9ef6c39b437e2092fe54113b96bfc0463580d41ac030","0xdd8a527b5ba1ef234f7aff32d0f3fe25fca7a2eac8f376d2e2925feebc1c2648","0x6711289e0c195c0b1faba71bbe9224ae7c843acee3592bda5d22cfe7f456cdf9","0x314b55605b0ebc019bc5892f0aee1e528b70ad97fd6318d2d39fb201185b87fb","0x97dd043dca630574d7c504fd325cd06dea3809faea0852a4d63ebc81f452f488","0x31756a1330fa146f925d3548a6898141fafbbd3b173cd1843661fa4d25b1e6bf","0x9bd97a077b61a384410ce34b78c919506f09de71ae538f5a272a6a787277c46e","0x02133c34052c90f2ba8bc5cbad3631f794e615d5373d5ba60147dcf2e381dd70","0xdcacd01ca9297d71ad2a9ce6afc87ee26b6728aaf26172d0aaccb3a4b690a8d8","0x1c6b0debe38c80c853e3e24bfbe9c67898aacc81a8d1c362af99b7a6881cf58a","0xd90b72ca9d6fea6a562c9ee303264da9dd9e8cf977f14e0fb80a4a649a342ba5","0xd57bf70d420d621c132ed0a4c8f9a82a80b6aa7ad471e287f6c70897071d67b9","0x18731f231feb8edd5643a3cc7e8921827dbe5d1e91829598bf9d9ba31f976d9e","0xa7cf974c5b1a466edd281f4ad7b38310b316f99f0acd8b2cee3a96e534f5a419","0x6a081d88c38f2f7ef86337fc1e3a6321ddffda3b0c751b234b39f938b51596f0","0x2f1b44b0e8973cb17dde63c43e93f9700f8ebe8adbe1d731b0683ce44ed64dae","0x4c1596f0f9f877a8fd0b58e05ed70daf8faba061b88612da09fdfda51cdafb36","0x9cd48328685fd9a9e11ea75fc0a2ee1cf0cdabef0c02c068788225883f9dfb0f","0x83467143009f060295eaa98d83f6df0c0a1f1e30a69e1d6c24ded8b7efe251cc","0x17f818d947590ae83b035df93dc830575144a16c0e2cdecc252b01fbb9876d17","0x437d9a2d177e5533e02b4ec74c93cbd9d265f7b2655bc39ead25f6779a4bd3bf","0x1974ee99970a99a724bd2dab0f4ef428bfea2fd391f38b83943d5c3d43d46423","0x7a14b3db1aa5353ff3025ab05fcdde6d30921341ca9870875602f597693ceca7","0x559d698653cd8cfcae76c151e752a7d7fb060ef0457b2d3e7566bb2821bf5cce","0xd65b739136862e7c8e1345a20f991b1b68a8b3e9ce3ee97fde3b5ce482c84c30","0x92ee1dea9bcfb811b3edd517ba3f15ba3ec676f7e222494f0f94746bc67196fd","0x87e58ddbcb31920900291ec2d34a854a87cfd7c4fb692e0faed08427846bc62e","0x7a091e5673d923df1f9cbf5bd1a0d6ba965eb5791c531622d3408614af2c321e","0x600139324f3dee665878d6fae61c0b7766e49789cc4c51278da4d5a0bccb4fbf","0xdfcc55afeaeeacbd39b04c1c3b7270c9027a702ce97a95ad8a5f017a7b5823db","0xe62b3367ddaedbb6d2fe3fd41bc1df388f0353bdcf1ff7bc85099a3ebe1cd2fd","0x8e0f7cd103c8d2cbb9f7bfb93acb40a6e1bc649731fe9122969f3a36126cdf7a","0x98520cc21bf4a12fe3176fdf615cee07187bdd565030e71066193262877a31b4","0xab7a3e63692faec1f238a6e292d2ceceaeaf0532ccab51da0ea8b2686e5f0376","0x09aca83259d133cb474a9d3f5f474dbf3374ec450f969bfd280d801d8b6f51c8","0x2005d0e3e80d326f59b2800c89626c924cb58df1c4145ea8886251d572e75e87","0x7946e6bf1a65ba0b5ff3d6a848cdac235f5d8aa21ce5a6e7c31b31de470f1a23","0x36ba850cb5546aa7dc5c340584bcdb2c4b2e60ce357efda6c7b8aa2be104a133","0x86d0e1b14392a384f6389ace0e48f97a51baa14e2ea2b0724cb5c4a887380929","0x0f614b5160d16370c62b64f76069267a76e840e8401ec4b88c87e5e5b3d20f27","0xef945951f3b9caa7d77d842180fb409f6ab479b63054e756ea8e3c15929eee6d","0xb2a2dedbf9e9f882bfe44e99a84f3413560dde3839151f9b69fe6b09b99b46af","0x26c63f29322a7c1595e099b85c9736680b874cf9c934b6d42e2cbfbbb0ff99c1","0xfe434c7facb6060f14a2a716bce722e89e10dc319384d6184084b628a3baa11f","0x09acf6b7f073018904f34c2086ff3b139bb8cd7a0e086a6ca9ab9f3daec1c7e8","0x365aad9c52ce316fb91888073a47228de95be3b3c2b298009db9b0ec41ccee0f","0x794028d2f054b93f12ca4e747897eaa29c32451da922fcae8cf535892be490aa","0x9a9f28c4635c9fffcf598b536ae8ea5278746d38f389774a3f5f7909e0f0ed6b","0x87e1dfe6eb1a2cc5b1870894b687069fd03a5d120d9cc7e86d5792adf06f8852","0x17d6d8b60ea4ff830f18f9e185039bdbe6bfedd40599b5b824763c7f0b4f1f6f","0xad2a1ba83dfcbb3e2f01cfea221e3fe2a4fcb51e775d20cc8ea1aa00768cf634","0xb0f89f1f4f6d744e518d9be884ff75403ab133c88fae30216f7fefed33db2e39","0x16ebca101ec95f258b9580d682be29b5cd7945809a33ce15391514ae70e4d785","0x235499d2dd5d78ee272f51ed068b8a1e4c27e8d0a734a72b8615a2f6b84850b2","0xe7855d26300cb083bcb17c817781299611f795126bb0355152193cab61acf12d","0x2e177aa1bc50af95c6b4163ac88e51a2a1a031d4d45fe1e3542e822abefb0b4d","0x6814b282e03fb90b9bdd71681bd3bb17463f95d6af25ce77d165495584b6f1fb","0xe23d23ddcaf6c2e10b1c90d61e12d652442f4264684e7824db014179753b17ad","0xf3ff6951f14cafcac2eba1a84319068134a8d4bca11fe8aec13ee65d8f597f9c","0x3c7e964d32b2fdcacec28c47479ea873ddf034ea2d38bbac430b673f1d65e394","0x44730e74c5d47b0e7b23e0b995991a792850acc8b123b9399234f2fb46454a69","0xdc3db41d434ec3b84354d291f0638ad45a4531456913011dc94734194bd3bca9","0x787977b130ce38cb7f7374d06c5d2d2fb423866a98fb13b93613e3eb6e1c8fe6","0xc18391e3ea46d1091afb1741433ce91848a3f87c4db8efe57f70f3c0d465863c","0x942f2889ac61d43dfe650af9b3805949b75265f0eb6698d7e9f4be3ee0211f26","0x75b3899fa43894dac7b5a2d0d1f4d8386435c940aaddfaea646a6c4fb2da2ce7","0x6873724c8a6ec643a6350b1dccf4bd98cca018d36b8454f3293bff5436b71dc8","0x4764ec04302577e52092e456686e54ea613fdd4c6fc36688163edfb7b6f01e10","0xbe9cf03763582b017c0a5fdc8a38201f8a8d8fc4b3d873fdd8c6cf7876232fb2","0x3bf5135f5426f3f10410253ece7288aae8bd0bbb3d911ae30536f860e5f0d877","0x669a7dfda24ed9fecf9520bf4bad869fbbfa5fb437e7d3e82310801a66102458","0xba5876f2f5b9579293ff91ed2e11afb34c4324b068c4e072626280f263e1386b","0x8ee5bfbb1741f58ddfd0dedd34be75e95d39dc0bbf3f0484e76dffd63d4b8276","0xa06a84a39614349462c80602c6b0e397ce27191b64a32709acdd8ab90ccfa185","0x0e653e516a81cf43ba4a1c15da3468b8bbf4b0c5e49498dbbf4c2e76f2e6c65c","0xe7ac8dd7ee15c6179834593fa95791cdbf28284d2eabe6514ee0fe86eb8226a2","0xf4cdf27876144d80314d692ed659cc79bc579f5767be7b2713b13b0a1de6a76d","0x71d9fb55930c021d913926fa5eda52b8e886bdafdd94c61aaa8168d624dd7482","0x7039fdd58a9227a047447fbc86f04b786bb5087a3e3fd498981135fdad14d0ff","0x2cc8a69de5d9312e72287dfe5d4dc7715ee2deb45fceb9db436153b6d2f3f9f9","0x86e89634efb77ed0c30e0fd0dd212d6a9666645ed6899e6f7604357d0d07e309","0x6f7817a98345ab0b3064933fe6bfe5dbf890088c3b8d578725c27d5eba4ae99a","0x48ef9adb30ca176ba9be47123d47beb4af3b411f41f789c7a011189bdc070b6b","0x6e139174c4ca3fb6c830e27f907c3985bbf66c0c789ba852575c4b13bad3a0b2","0x07554a43beae8c824a9945a9f63d43e02a0253044a8f7e19c011c49df37c72c9","0xe036b0bd7d54464a54b2da6345251738906fb62f73a9a571ecf426f4cd8c429e","0x625e500bb89257ecfbaa99ca5b2119d2ea8aa422350486ea26c6ee0e57807cb0","0x03c3e0b9eb58793818b6f0194d50346fb0715be86e1e21882de30f7fda67ffa0","0x5d8bbbc977fa00c38e123e932e594f29055008ee76f82dc3847782b38747653d","0x4eb1978684af5af515b402352e4dd3066b72fb8003515f34c6de13f69cff2884","0x2eacf95091e97bd7d7960646ca68d378bbf323ac23284e6fcfa5ddd1c78c4f43","0xa1b856a3beffa790f4915bc4b2586462658cc587bc81393b92967b0362820755","0xcce1a255f73998607ab9491b2ec7826b0d0cef958830316a113f38cca17993ad","0xcbb205a3f5d969d21d19081de2f7aa731e53a4175d2bc4f0e6e3a65f47916ee7","0x34c1044b5be125aa4c37f33ee5e61fefcc70955290e3dc140c1962d6422c7bca","0x95b787300a045481c32ba18734ad6cb7b942c2d59c40805f80a1cdd7a5cb43f7","0x1246e933e60cb31d6a7164bd269c590eb4c4dbd0a75aea834cad0c717a307d20","0xcdde1aafdd422127999507522040df4023eb59a4c9fc23d7cfcf1016584210cb","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x40db4f375ace854ebe54eaf170aff037c77614242193a18110da3c51737a4f69","0xbf32d74e89cc9141f7fac4271da021a773177055549881d5313121e31ea6c756","0x745db716f6d9adda8d8cfde44802bfcddebe797b45269a2cb58aa2494395178d","0xd61f991153b06ce2e77283462b772690f6f3d4b67d6eaa1c743c9423a08154b6","0x1ea8a3c559ef45ff4601959e1db02b0202ecba2679bc1bb620bf54b3570ff4d0","0x5e24ccf502bdd2fd521aa9870213896d4ed37ffc7a051b0909bf4cc7c9df5659","0xf46cfaa19960f1b77e78502b95ad75f10552442f831c167a7f4b1ee4c7073577","0x25e09ceff98be49d040cd5d1e6c180267f28a5598e7206809189383cde3a301c","0xedc9130dbc95523655259ee1d59619d6ecb23097da0de05bbd7de71c98d5f6a4","0xc52efb08b800cf6be56d9e5c4f2fee44c70d12f2f1518e4fa8b10c1e637777a4","0x55d4e90a01c0d23e4b93c191e64c5e12f80f76d1497250b86165a8e40f0418e7","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xc45479349b51241d85d5f92064c5a7f86ab665523867e0764a01049c5be57539","0x2d358ed97d5d7967078eeb90db2bab69ad2b992aefec1f68a149b2d06bf129e5","0x791f55cb287708c53b5ae5e0d4fdc4cc6649683c5daf05da3a43422d535b966b","0x7de4dcebaa9cb109b42dec24a53a55667cd93200c8c61e0ebd34e4c2867d9258","0x3760149edd7a8b51a67400f422db7cc214905532b812db8f0f94ce58ca68b902","0x39171fc56d2445101400d1fbed2332dca3c2cc2009887d25e1d96a08851f95fa","0xeeff7b03557aa5e269e1fd3ba6f1c33138b1c4045c01058d79c8e8e539394fb0","0x67380975bef8d53cfa1216451c591861cec73ca376d80cc1cfefe489c5a065a8","0x14faed502caadebb00c5e3ef6786e816d00c6a62b3e594e1226ca11b5c260377","0x92a61ca0e28d4c6e9ed0783014554972f6373448fe5df17c4e6b05197048b9d4","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x322d975849cb3493e711756cbff6c5040cc203434cd3eb8d5bf73e85ee989e04","0x6c054f3449cb6df8c3a43f33bc1ca7721e9ae483f8c621c81c7f2aa5982fc444","0xe8f5c5bc9a454459d7676b81cbd54cf93ca68a1ae85c082fae1f2779fdd0e019","0x65af2f5ce7da4772fc86387e07b1f4e7709b30411811307e8815eedb41b4e13a","0x45b1e466f32ee4eb8b4f6c9937a717f85ecd201e8d9b78996ca41a7eb31a559e","0xa0f9a6a93a32a477ecf585302f866d4d77ad5e2e3fbe33f2a976df2334437dab","0x12436c4a525f95cd1c9dc54019cf5791bdf88d2c94642a40ffe7c7eeb1ae011f","0x9a57c618673af8f7be3769cae217159ce885e689a4219efcf3d03b28118386d4","0x0beb6a91d12a92cc8e11444e8a71a0f318ab19912b5cd5efdf86e5fc932e93ad","0x07c9978d480f8f488e8ed0e62cf8531abc59dae639a281ecc4198342423bc882","0x8b927d8cac1b2708196ab94f13f2cc99f787b0f50671e5bf14d141029dc15256","0x58bf5903f71a0042af5ad02888fac84a313221d99926fe0fc78f54c77fec078c","0xd81102ddac5c6066862b986379f4651cc640b760a7e0beb901e138306cdc1ba7","0xfdb6ccd49352a32a5143fb1ef24243fbc282214333c9bb85d4f169002cd5df6a","0x182a7060a54b13faf9817752f15ebf5868e3d1e01281c71e2e42397a984324f7","0x50265ee271bc2da562277a9b535425f320877f8f1cfba05c39a1c83fdfe19b44","0x9b3983d8c718566f0efffbbe0efb61ea07bd7582d65632afebfd5fb3fa2fb6e7","0xb6ed8050accdabf950f9ec54b8adb59088210f7d336a560a0c64ea15e19f5c20","0xf2889d9261efe280142fad9dda311ba7f5fa4e75d7c9b00dcee3056ba9a8a8ff","0x10e001dac625a62b06be1e504605a5cf60afb7b9756799b011800cdef9d768f3","0x21f960eb7d3be120bdb642fb51757d1c31317273d54adf6b7621bc045bf1641f","0x3344c4d9efb98aaded9d30f5e8ad8f8f3af141cf0d62d47347660dc9f270dc6b","0x059378d127d9b9041ce178b1a1119ff42a8dd5f1b1add4c1d3b32e9146524faf","0xfd5263934afe074420f7ecbacd2e59b8b82afbecec9ae0c129a09f8923363c9d","0xae0926f078b13d3de7a68ede832e173f97e904dd6f18ce69667074ad1840937c","0x615d7e7b7267ac4f98929afc7a86d399fe0985e34e22812cc9a26e27471ddb3c","0x9d17cf1c1673d622a221dd70724139f9adac910eb192839fe734678122191fc0","0x75f2016536bfb7e185d6d486f5f376835cb6de18716d966dc4a8e824912cb848","0x547c7eda216b9c95b639a86567164fcc7e8bd9169273c2c703a10f3ab2974f18","0x92f15a41c5a1d6af7aa089735793558e80328687c5c2dcc419f53c7ef2fd30b6","0x25bc29f20c0ed7819d494f22dc8f78f42d6559f5aed76112adc30cceba6a5a23","0x4e510c46758ab6c5cd842e8c961ecdd47d2fc4c72ca71677cef184e1f95b6271","0xad369135dfbcf20c638505bae5df6ea0c20de8f18b5154195aeba51a1d9fbb9c","0x71fb616c9d080e3178b58ddf93cd997081e9389943812cb1e9101e51e81f6ca3","0x38bb45147c34aabc5b9f53b0db32d4272ec654d318051a100357f666a1594d8a","0xba38507c96ab6c6fcfe9a4b8911e94409b492eec113025d7b99cc90d4238f8c7","0x20cf0a3b334dcfe979017aca076537847534e6949a6bc61f11ef1acf4e607172","0x505c78bc85b4b835e27532e3625bdfa8d6708a04bf7213d4cfa4de5caf3229d2","0x68d63535b10d06cf5136a7d71e517875152e8ccd27965787a1c59f6c50ebbec5","0xfc4c944127871e21c06715bf3689292118c8ac461d2d55f8fed10d9fac6ef5dd","0xbe033f1883edd5850366a254d34a8d17fa44ccfc5f7a56ea42eedf7a869d38d0","0x91dfec2f6c6de5a1b2f3a441cf90b24c5d1c7c187fa0364834db93afef395703","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x019aaf2332ab053c4a86d066b6fb1ee5a8dc5346a0d65fadac3eb3f8647f1ac7","0x65bb3d762b698a441452e035d8c4cd4181f40cd0e07f3cba53c2fd48d530b588","0x2f78fca2d6b9054bb2dedf8880f1321817055af5818519b5e33d3fff99309e1e","0xbe04cac03173a37d0dce34980009a76165921764b86d528f6ba6ca95d16a3710","0x70a795ebeebeb4565240112012caec564c8eb387b9976f1894ab83de9fd996a0","0xd7fce8c2245f3a1894661635244bb1850abb2e378cc5ea7ee16494487296d395","0x08d6c6069d66455f1f5881a78f47a240fbfc898144c6ecd418a689dda5d258b9","0x326e1752141ec291c9f5f90fb9f85cea1f041a7e3f58526e9dc729ba2c65c83c","0xb78fd7a64b889488fe5015dbcc7d68465d917f3b7309308adc3f18a9acb49d69","0x11070df09d0e2568022320ac64c7f502e6ee9740697cbeb061027f57560e99bf","0xca65676545822d8ffe80ec284bfc3692aced8ed47bcab2bbe36e827f712c078f","0xda748b3beb34e83c2e1d218ad958c23c68fbeb18f1223a1213f591836230e211","0x594f15627213dedc496cd3ef1a1c9cbb1699959abd902376cb80e63304cb384c","0xd785ec11d482c65c60af299a4ac4ad29361a004686bd83f0fade24e11fd05b87","0x69911928c48bf5c592a0f9cbe5549460ca0946eaf673e2ae995b8ea963a77aec","0x8c71b78bf00fa11e8e0b8cb6a1e2b35230a20585da862c7a10f7c7d81a5e7132","0x78c8373a652d2a01f6e2f1318e305667149fa4a2d95928c43f9ab182391d503f","0x58d4f22ef27e09b0bc94d9356647aaaeaed30411214b0b2b3791c852670b10f3","0xcf6584aa116f6231c3ee48e814bedb08d4f180ada6a1cac172672c988fdc11ca","0x982c2d3acfa1bf01b41c4ef63821a640e2069e5786ce09f229f3f625c16e412a","0x5b2a3a3ac2494017fc5ffe0cd05ea790a9ae02a5a927eef7966a13bee3c0ffb7","0x1db2d4e92c400d02314e34d3ab999597d9c928c83972fb20579a55b46b6eb5ef","0x5186d0d06e33c83da1be241bdd9cca8961aed0f287c3a3a1c7ce0f572f34c3a9","0x9aead265ac7dbb68e80f664c5d6ca1c7ba44b42476d4d5cd55772ef32554aa65","0xb514eb5c61a058bc778d7dc9fa7f1ffb3387e957b4fdf5f055c867affa2fcaa9","0xe5f38c76dc94144ff3fe9c0c4e56e4c05a7eba6e578114077d2487f292dcf1c7","0x916a9d4dcbfbfaa48ff094220cebb45f6191d9b6764b3b34f86f5521fdc3511e","0x452c7f2be2d3f2c890aee15a62698b442b250657a66b32c09bcf148500ff9659","0xbcb82576a37024353af2788b7accd001c55c72f6df164dc827bfddb2eedfc2ab","0x3bb4523f676f0f0a80e34f9230482ef269bf1e237b6376d6390f7921f7c66082","0xad01d07a7a580ba24bf5d71b59970f02b8557a978a89b6ae1b9254471b4c10cf","0xfda0e61ba2e63e18fbc95a03557dae966fb4e251d82490029dce54b6b78a1bae","0x6d1ac618c8da6519ef2810ef6156035e207a4571dc95efcef2e647449988cd96","0xc8a9bd5da0b4116081b5654b809dbf6a4c8fbc427f73f8048ec587d54a5f79b2","0x3907d61fc43b86eaff3b920f6a014c962381c1b74a9840ded5358ea649a47502","0x595947c94969516fadf0a5ac05ec02da60bfb48efad246754908e95456843642","0x970b429cc431b247336d983d712634557ef57a73fdcf4ca646804c5db3be4054","0x4edf44079a86c8eb8b55f0fa714a8175567523a3c4a9e1dc0dc63d8ca65f2fa0","0x286c8af38613a3402c542322b3d8b05116c6925f812a85213d2e5ffbc78c3a88","0x603767351187c4ff840e0594562257dba3da0e48a6a75bf42c07ad43191e9078","0x66c9cedab50b2d0400d3039ef025e10918fe344ad1ef9a54e0b180a81eb380a0","0x2ba80b55339ddb7ff9fa5c7134a9bb03046e0ac43e86822c86a0421af9322ec8","0x312d080648a66ca2b6428455b9cc72a472bd1c21fd227647b3297d2af1eb97aa","0x0786c97cc534f669cdc3d60d13088fc874cfb24b48f81cad0dcbf790b36eff28","0x3c351f641dce3c743d6f05b6a8bc99d390f88f1ea1fd06ef3cd34453deb6c0bd","0x13901712a6c1e6f1b6037345d604ef24f4a35fea0c899e53b2d0477dc5d2ffac","0xc714f894a62478171d2b932ff29b6eaaf002671230c8ca413b0ed7881f67a127","0x8e2a270502b7f59f627e038b173da665a4bdc6fc8f577a98b8ea07f4c0f9a2e3","0x20b6d420cfac9bfb8038b07fa36fe304b5a10795834af6823c640d9bfed31131","0xfdc7959f892ca4c99955b4740956441ef16fe69f431c71dd885b1e2cf9e74132","0xe68064c79213becf647a8f2b9f4a5aa949f69c6266ba9a444b8a9f489ce86b15","0xcbf8ce43887f8478961821a107117c6bf2a7fc3b1f64c55965a3fd211cd84947","0x12c69b142eb84896eafb8ec41008bf8f811b3e0e870297a5d3f13a587d626076","0x2ab416582dabb34b31313bf14673a0475747ced0fb73a53dd22f3a713f4f5677","0xcd13c4c8e35e5c6538c43a83fc96e5166fc61b622f8c788552ac7b2f2df2b40a","0x55dd854a7ae55897e43787d99ef67c4e28457131e5c41a4a46e5f17bb71c05f5","0x084e023e5761ceea07de9cd279f5413e6ec88b83588ba6773301e8f3d4691fb9","0x42b3b89cc84c393f688edb6d9dba51be10e8bf534296f2601c204930fec4e70f","0xc740aa02d35d00a052a2571d1ebecce0ae7f2f1073a40c2b9f64e9a0da0d7185","0x879b18ca645dc8eb1e6bb7531e07d6f83bb2dcbf73db31a09293de2541f524e7","0x5b4fe188914ba6c2259960739fff5ca019a2725a378783a6795f17dc5a6bf154","0x16c2b6ceb71c93d091ce998b28f666d584b30d9eee4f3bb76fa706d313e3e790","0xd9715034b125a21627de2edf1feac77c495a0a53f684d515db289625401aec3b","0x1798f4ce1ccf2e324fc41a611660246750c508c83b808c0d48624f9e18ed708f","0xae8b1c4daea27bf9499c9cd3ce4ac10267602223e0d9b1625dff34bfcd0612ca","0xf9b45d2891125942508faa2ce81d9b1c5072e578a354536c878170b967b20342","0x43555b852cb38551262f268ad1f2036632ff28058fed2350e9347c96fcc09d86","0x31e4911da8d59afb70023d2d06871dd58f4f4f07c9bd583ad141b15e4757e075","0xa216ec2b06d9263a69ebe27cce275a2e14444b4de308a255e8a91edaa9f2fd34","0x4e1bbe1fe87d8d66091fa49703c588da64e9d55d21d04c696bb07897de4ec45e","0x5b8224b5b79fb95d339c914ec4f4105c4b557d840113e25220c1d2dda0ba1ed8","0x2e83bd0f1017b6fa80c0d3d1bada61c7bdde1dc974d12c8194cf3a4dc514b188","0x9dd90584b7e667e686ad6f1c175f589784128a507173e66ed195ea8f999f150f","0x99d086d09fe28b5d24368a00d05ac296ecd9daaf6a6f2f5e1956d1eada2eefd6","0x3e9f681c5badc46242dd11f593cc73cdd94c6dfb5df8fb148862d3fa0d7a3e2b","0xf79a94ce2b0992f8a4664a8cd169a65cc6950252a96f3389d90c682fc2d48914","0xb3d1c8a9eb253145720256ab1e0e8c28d81607fc1f4e0216b70ffe594754b46e","0x66ebf087bcdd58d3a7133c30c63df6a87d8dfc979d9fec79ad1842a270e8f2fd","0x1b3cbfc4c03e873f34d4f66def97fc52a1f871bee18cf7e43a1f0a7d5c850cb7","0x22fb01c07737411998314db1f4f3e1772ebc3d873a8d3dec6358a9ac58ed14dc","0xe86b1980117baef47516c21d6c1c5b33ece5041831738fdf6bc81a1872d4a557","0xa5fd232b6f42ce7c9963c47367aebe53a25a24acb741d8dd261f798fc48d09e4","0x5c3cbf000f7e06534bcc69ad66a398ef6f37361d5c096a77774d8b37904d7aca","0x4dd591aa04fd057df8283913409b7a668b046a819ce2faaa52d706bd31b2595b","0x2cb29a77ddfcf21a86cf8edf7d3838ccfb858b1ca18ff8d59b7a900d0a20ba24","0xcba2eaf80de66d5f09093ce6832d9ad541c4b2b4923a7ed6634872d507348d1d","0x88bb804009a54beabe06ac393980febcec6cbad725236b5209fb7601308924f6","0x9a09a69e96686c6febbb37feb2b43893eb610d36a1181923a47ef4052fae9892","0x1ee74a0468e6e1919f91c46ed0fd43310b139b8c7fd9f79e270ec236e27b21bd","0xabc034c5cf8f3fee817e900dae6e0612b3bdc9191509ec60408d8c88309bfb6a","0xe8a6717710a510cc62a31a78b4324200d6efa0dce9b5a42d540bfe3b0d860403","0x13cfb3169fea8e1d674aa63cb2015bbf2a82c427eb80f206cb43accdcad881e4","0x1573d9c8b90e03a40fa4520f459cde4cb97a268b54fa100dfbc7684bd82552bd","0x832d9049e5fd9b70ab3f64c3515c40829700d5c7cbd7309d3d484631d7120dc9","0x6b726aa356bb3dbdb9ea3502e4b882be333b895bb7d719231e7752285287d96f","0xa86a125316bb5b501f39f061db4e8eaeeb880b6e3c7e65f948aefca578cddc6f","0xb3b58f1344b3db2790678f6d3d44158a20347d28a658d19eee8639348718ad65","0x065345d4405fc25fdac3492392fee7588bce08b7c98d8ba644113b0970e6311f","0xb8d3fdc8c445ba5e908713b6e8049d1dd78f13b72a01530b3954e2f544835345","0xdca3f6453ab99724d21b1e76e046a1c47d288bf540ae317e8e1b0424880a492b","0x1cfbfd3fb52406d1b801892d82ab6113cef8575774d5b3cba43e9b31baa52317","0x48e0f7b1c51ee8b288ebc3eea7abf2fc5b8bf5ebeb7d23dd9e97bccadfe4b831","0x485f391366c4246ac44009b43bf131c016ec840e24639283798a420818602c29","0x68f8914c825ae354a239e36549dd80ad8cdb901d8f06014039461dfad4dc5d7a","0x86bb5d58cb1900a8dc04a375c929c105c822aa20a32e6bde7e4c93b7221e14fb","0x9ae536240c8aab43d1bd3ca24cd1e4e20a4f9318835e5df4927f78006e3abd73","0xcaa9a9fcbd250497bc6b0cf984b96a67643fe3ce476e6cfedcb43b452c3e543f","0x61812b050a1223e3cbaecbd0f091e5919fda15fd2b31cfdf93fce4ccbf5cbcbb","0x1f7cae5088522796ea8ebd7015976a47a3bb4a1d3cc5f0e2c1cbf0950a1236cc","0xf2e1e91aca4b173d3ea7c80eb6f22a0a34d5c4dcdfc8e2de53ac789b0ad384f7","0x4cc7f9b9785c08c5d02c95ddf198133b4556b6ee058cd7b5f357429649060e7b","0xab5ae0ad4baeb9486e79c35ec443bf271c24bbfb69ddda9400c2f0c3a8e6d74e","0x8eeb92afbf68e801de2bd0a4cdb21f6de5b9217a6cc5584ccad9a77ec9ed3112","0x383fcd80944b7d2316f25f8221484c7c9f2fd3431a13de9efa9273902a03c8ce","0x85fc7517c9d6193baea48bfd0981ae925d17f8c41aa4dc2e0ff0e9a04867dd32","0x4ddf3f430cd31fbe03e5a9d917bd4deeeb31eea53c3e8d85d862af179a250e3f","0xd6240920f499f7cc9705091221f997bd72e4c547c7d6faa9dd21f77f1bd6b4fb","0x93db5e6f8227f1dbff81e3de7d2240167706371274f0a42c5d06a7eb7266a333","0xa76e70993cdf8cf3b231ba8c63ed8fb680003bda0351e1a0f23d3f54f9beaa6d","0xbb4a3f97d104f5361924618fa2faee081443e43f203f844f9fa0cb912bd6c438","0xb8424e98abc144bfebee4648832775843401e4907f491c580c462df6115f5858","0x3213c9a64f65f508cbb2eda44980f96189b1800d541fff8269f2fa6f3f277705","0x5c594d872e6752127e0d5a8f09865369ea7febaa0d6ea5cd5ca98e0355b1c194","0x81a5cc6a1b47b178ca6d6efbdd63a20f142d2c0a919e68a3637b7d2f278362af","0x15273afb496b8959b315a53d7e285565b1a182ed202c8982fd3cea835d70757d","0x5316d610ad08c7669cbf15e66694a3bf1f6ef0aa83b871886c29abdac81980e4","0xf4cebbcf4ab4c16c621da246259c59d346a53feca8cc2b41734e926cfd1823a1","0xf4ba9799a011fe3fb6edccce442d8e58852feb82d2d8a3d507a8ea93a042baad","0x750d7122c1386d36df92bb1ec56128a5d33f5ec23db1279dd211298d8393a2d4","0xa96724a4d18ac7dbf551ce9755b8a7610c9ae3f537acec4d22e007c009b3bdaf","0x4b6e56517bdb83224f07b4cf9d4636f5c0e255e8b55ac9e2697183a6d9e5acfa","0x1bb4d8bf22b8f369779d705c79ed21774827c7dd852b7f08c7449f5f32a03d6e","0x12a742a9f743a2d791f6c7de1329dfb1de686540da8221416313d933422ba483","0x454d07e975e692e6632c97f9a2d7cf3a1348c5f390e8f1b474871f60483ce388","0x5d983a89ea47b7dd6defe7fc28498e444e836f9336648af2f04df67113b643c4","0x58a572c7f37887b5b6c0f1f9b3cd0045ac5a26995c5d8f304a3cd7fb7c631d56","0xa51544527b694126b8e349e526327cda6a565c7f95fa3991bd1f5e89a0a1f455","0xf2b8dde8029bc54d3b6b247356f6f69fd80486d5ef5eb1aa004b46e29c4398dc","0xdd0f89a4d917f5df509c0754f2c722e5e752ff35961cbcbffcb16c13d24cd176","0x8c5aefe2fa1efe244eb19ccc71099450d20adf129bc0bf67cf701f99ff746a7b","0x3f3fabededd2dd4b32bdf82782a1549828b1a5fd74e78882828333482e022fc0","0xa51de6f614c3b2ebb83d5ff6787721fc4d51447bab4ceb9dbe1608e7706caa7e","0x62d9d2f028593ae003e97e0f7237b7ba3e3d6f49fee8186d7ca85e2e9f1041e7","0x163cfa244aefcb728fdac595978e0a683f14b3a5b250c5246d433afda34af6ab","0x1809ca182ef2b641c2b3a81457a47e8fce99c616495d34093b10d563fa8c74a6","0x266523cfc8d93b52b2bef448ecbf2b2c586fe19f602408fe7582333a1443cd31","0xb77596b93d9d8c1e7ef14d68252a1be142d3b2fdd13a1b80330f4b9dd1bea798","0x8cf41a71509444418c0879c7ccc71037640f16b7914d8ee314f409db0b9965e6","0x67e0c11b94634a265f13922cde8f7ce0598e4921668c4636c672adcacd3f7eef","0x8e40f1273235268b7e1581e35a48e2578e5abc4bc9cf4cf6ff704e0344e2d5d7","0x0656d6d79ea8f442a83db22e6c41d15fa4f1f164aca2b6bba49cbb13d82a1305","0xdc6c53985604eedad2e53d34916eb56bc19db691d64f6b4297e1944c812878d1","0x6dd04116a9b10d657f5c786fd0e20d067a227decb45cffa9eab6d90884964eb8","0xd1cbfdebe3de2281345fbe6bdab9636a98ddbd2208145a269e1599fec5efef00","0x421012375fdc5555f4bb95828598bbc1d05d7fa87d01a57a7947b9b3e6cd71b8","0xb031fc8d0a3e086452a1dfd3a40c13423921e2fe498ec33e04f2489287570825","0x163f6210e5e1f21c2b943ec30fa52fef6643a89fcd68fec3a974cbadc55ec81d","0x00f5e51dab7ed6a704c254fafce56b79f648273e9fff46ca7728ce18d5c741af","0x6dd1855698c8572bafbc8c0339120dbf5915c165c885246b9aaf3cdbb98b3f02","0xd76183357045fb0c3eba32e5a08f345c77b5ec5717ff8e1e0d1933859082d9f1","0x0bd949fbac9f561f582a4c18a69dc74ad2cc4e65034c5877dbc96fe0294adf5b","0xd87296ffa2e015718f4fc9949241dda73d9155bb26635c36693e220304324f19","0xa76571842cb2adbc361aba977d859acad99db99fd618b8e6fe8edbcdafd2e212","0xbc12fffa1733493d62f0fd494dfba821ca584ca5594fc84f400d6eefd412697c","0x5af8aa7caee71d5e1e5e4f094f420841c0bb010582b289e353202c4bab6a2d44","0xe7be34d6cc33fc98ef23f5700c86caae01c81455e8797dd7695a53efc182be85","0x3732da06074303aa88f79ec85964fe440b4af8bcfc373bea30aa157eb1d6f746","0x9d12e9c5469a938127da3b6d6e00150a3420414cb2cfe0bae5475b48be7c0611","0x099cf0a7b4c6400fc8910672c44ff86d9a087081c5300b50ec72b146ba37d423","0x7b40a7c1f336c30b2ce0b56c8fcda78a34f068b47f5beca42c2c65b4bb9f8fce","0xdc2929a52c4a223f67cb93a2751947e84440d4bb4ff30407e25e66092b68b212","0x2b8a315f7b6725aed2e805171eb8a0cc9a10c8d2db6d6ba227c6e762ef835018","0x4f892d90911d81e5b1ec53708227ffaf377c64ecf5b01b905614349f077cc1b6","0xd3d61de8d6523c56efee4f3282d0afd945ea8564e45c274f111096a8f8b92a97","0xe6aa97f6a53115011e5f7868d067824e8f2eb3572209216812353937e97d82ea","0x0ea8b0e903703e45b3385ea40ebb27d7b7ce2ffda5dd35004b26ec6c88969ea2","0x5fee484892bf8e71773df37c018006fff9cef0f9f03aaf4382c35d832bc9a5bf","0xe3118e2fa7d6781c4d6c41e1fc9c01642cb4d4de349d95b94d07b9e322994d71","0x6c1a9a9aec3cee17cde5cc6cff68814a1a51fa1783ac184813f0b3576980c46d","0xd03a713e5b4d1769dc127b7a8179cf7252b603d6969bc2d2222cc2553073c818","0x03444d070b534dfd8cf7036b3c324aa09345e6703f3b4f723e4f1606b1514422","0xdfa992d1cee420f4c27af2f07a7c4cfd7e7696406c552e99723debb923c8e51b","0xcbded9de3915c38f23629c43cbaabf5193a0d2ba367380df0971e5889c3999e1","0xe095da928c32f9d79ec0f412b329edfe0162c2d9a27c911a1f27407d75baf305","0xdedcf3f1abe226f4fe5f26ec55523867ac604f7959c2d3de95d4a7ca73a88414","0x6f9b562c9a7a180090cd700b430f32f2d2b80652222e91dfa946e7c7314cce22","0x567bb572241d6d2d253f6ece8bfd46c3fc14a14c2eb58506b283f719d810228f","0x5506ec6a224cbe73467da2409a79521f40b2d1163aa291cb0214b29151c11e09","0x1ba18b28db450577ae68617bc769494db7dcb1a1e437a0c65b4ec6f8a280720f","0x35e9bd71dea7ec19af58ea90fbc674f0d113a67b7dbe8a46f7fadb8ef6925af5","0x20da585f550c546b5e10454ea9b468acaf0f204e4f14a5eb50ae9920b9168b3c","0xcb2b3d9d2e2f5ea4ce080f76f27be884713f1acee3a08ca197fee8cbcc264295","0x96c0e341b402cd74b560cc784b209c9dc59336604b0c05743e062498ee9185bc","0x88ef9b3d84ec8f45f950c0aed3a3bd536283f8f5e24dd87bd56b0165c076be3d","0x779eb3e7eb966f3fcb4eeea7c9f9111c4f5193b13339c0554f1b47c3a2648077","0x0cbfb9029d8fd902a1bb0567dc43213fa19ee968fbbd908ff5f670bd900183d6","0x09a42688ff1bc24dff8452c1f1486731c5f16631c03a4d5a6a2a3efef1a0fa26","0xed4d08ba33371a275b56ca7c8af3e09fa06ef7a9fd2f4f5e8a83d069985bf547","0xd7e2809760b0ced40e4835d9598e12a3a8117fad87d0cec213fcbe9fec9c5c6a","0xb71aa937e1271a097ae1d1b9a646c35cb6259a934587012632501d7c842df1c4","0x4b9472d0103e2373aeeffe3e939e064c1c46606cc832fd51c933f99f6537f90a","0x109e15e2d5bf360b5d18babb01ff91f817d770f9c97c2850cb415d8bc454f39d","0x03ead5eb373dfad7f5066f111ac750725e5d203429fc1988cc24c351ff76b06f","0xaa4729276263fac3b54c72ca8c3763f1659c5a6ecc60c87987e4c0e0516562f0","0x4a939dccd6388fcb0760dca06ee4e16f1972d4d49306abfe40446df1e49d9600","0x71e790fc8e329393a3773491d6168b6b1d7d2952bfe86e40f0c0e3e8047850b3","0x87af972c683e3fd487b8e4e196cc52b532124e75bb806384a934a1f67afd58db","0x0d76c561ea53f7a8e978781eaa5d98f62ddd33839491f2d88e73a35eab93d6b8","0x9fd4e95687a38cf8bd698530d4afb7b213648033c2d5fc7a27a97200a9001030","0x7cc5dbde2f20967ae3f4b94271d1eae0ba2cda1e91572b0b0f3c19e8dc8ae85d","0x6f4fd0e0e75cf783540a236e79afab0febf1e2c51e687a91b1e7eba00d5ae1b2","0x85381d0d6cf619a3df83f45336d0a288a3b1640a026793a7f5b5c8e0387c7a23","0x07630ae26834530d38756be88a9dd9a3535da843971f2a665c67c1b4cb9a4e1e","0x96dcb6e0fa16808871aa29ff7e52d30dd7ee0b0a08394fca32a13307c6d886ab","0x6df474daf136643699cdc6f506c749b70e4fea13630f239540490c122fe688c3","0xe98adc92c94f068fb529c5b83cbf3fe655c346f230b4632fd19c8f51eab4520f","0xe9337adcd8862d2227807d8bd062192f63e559dd95f3a6bd16de1cfb2d28c087","0x5e915a426084d070b802f66966ea1847a6b2d3d9efc61d15754c801824ba46b6","0x846b8744830465245857c9208af283e8c9bf97897977be884ff3e9e9988d7d7a","0xe284600619908ec409654e6132d55160fce1454b3e8c55a5893395db5e2e51f4","0x7f05ba28fa54b63ebe3b5e7acb4b3118d2a03ece4a02bbaf615c7eb559b3156a","0x52945e29a22345304bbfb3d8668ba93b9c534bbeb5b786bff002ba9de853a9ec","0x31da7e0e398f7c95f9274f041802f5a513ffcd237eba8ca8f541da64567ca6d2","0xe273c92535aab73f082ef07d493f90aed8e9624265faea582f17d73068cffa1b","0xa1b666b55d37aeee450f31f12f69faa52bfc3f83b5452dbd6e84947f20a0a063","0x560fced33725acbbe0a7d2d526e79dfb81a0a9c1c70ea5d055388f8ccde74890","0x1d9bc2293b97beef937ab31708959937e6d922baa33aeda67753e6de0c94fdb3","0x08bd6fffba51f8c6f76539595a660e0355c991fcc3072dc57f4f6d88fa3a3d33","0xbe556188873ecb66f458389e7bb7447dafc1ec40809f62cf048113ba418b60c7","0x5dd32c52024e4eabc5c46f09e76b8108346e5c298c112c7c791f734af1c89567","0x6e1e44db708b03f810f44de3f9644f366ffb02ed7906ed11049133ba9f492e8c","0x277c9bb5d963dbd1bb7ecdb24f40c256c1da083e1ff2435331f0f78213d220ce","0x3a205b2664301d8cd5d29fec11c7def10a34e5810d7a4fa77fe24e0eb7520ad0","0xe0675899b23624184bc6a754fed13e37599a47ec58529212f7c31111f4719d6f","0x2bf4253727b90cf2fc41af5cbd81bc02c86e905ddfb7efedd94027ddeeffec23","0x678d06c4b6f743687543b1041424738400eb039ffbf6a2c1dfcc00f1c309f359","0x9214adcc9359cd1fe52cc23fd8a8c67b7d5e2e098953c0e4191a1e7cec6b7563","0xbfdc89c0d9823b26c565d079dc8323b91a04998b1b740dbeb66e7f87e962b747","0xe495e77e2757365b995c3109693c40f510285728a3c7383882fe22d0c791bcfe","0x5fd1c9de2458afab6e9a127575ea5c940656ef33ecd426d1749a77f20d60f06e","0x7fbb43ff380003db1e09a97e137946302144ae09cd6541788c0cc87dd451e77e","0x3450b547a32ce4f8de2af4313f14d719d25a02075f42e26f0b92ee987bf100cc","0x6445b7c44fd00ab514ab05256d76e40f425e620774c476a8b272b60591f70c15","0x72613266dfb48d93cddbd137036d0bfb2012c3b1dedf1dfd801421c513e43105","0x7fa259463730ad702b64470dddcd69f9fd4bc3f9ecb4722a571a8bd2ef33dc8a","0x8115e765dd97fbee2e3e620e47753a95329be837dff338d03eda0a0349754803","0x60c9b0fdb8443f32d66a1eb8616865c95ce2524a98ff3e992233e0694623dcfe","0xc26e03ac61a8adfe52edef250450cfd1bbfc915c812de7a2ade7df4c51745416","0xf8fc8b5e510558f66794430944ef0d91658293aa63a97db1028e40333d0fbb22","0xec1791190d758abceedb8ec0c9c1b01ce38af57f77a07858a12b3245524e0b49","0x0a46b6cf7903a842c8b1610cde3f8321326cc433730e62d444de9c86d50fd0fe","0x9b3eb38d14cb3586d703049c8d5412b3b14411f8cee2965e48eee1c42fafd40a","0x2e3cc4a6648557aa2f95b15043c493530680f9444250fc8f6f3599d0f5f3f0be","0xea8ae0fc210a15ed64f46a35fa8b1556b76d09ec8f6d47ecfedca2f4ba6c907c","0x12fe9cf56bce887d2b6772e84aa422b1132bb655a59f06b3e2e40d5e20fcee89","0xab424e4f1e30fd5bf0e72253b22643942a13323336de9657af216f805362ce61","0x3ae8b9ede728261bc571e69d6c2c6b5a054d2702297cfb2f74c7958cec6c0bdc","0x838b4888060e36cb685cae32460f9a4d8b7e409a5bb893a291eb7dc3140dcb4e","0x6469b6e4790807edc5dd30541178cb9dbd61e21cf347fae396415c738246ec08","0xa3cea6465fcbcf8c4d2d52d049c01cebd16394034623a92647778216eccd2eb4","0x904f6dc8bc8c0800f77eb4c37762f905af93635d289ee0bb4f4f729cd11c0869","0xd5c16a13e3bbbf73d2d14745382a724fd9d7d56de117373055cf4bb0c3057c97","0x44a98e88786984c42c72b9492969327c67eba0a1406f9f5f764d4d3b221ffec3","0x4d0ca05b66a2e761aa85cbf7b21a789419f4e7e8a883e9ea8c7b49e03feba10b","0x3106a5580af05f9692315631b5436e2da0aedb2275a2be243557da308ae8f83b","0x954078b876e987233426e530fb7ad69aa9fd0fc02eec7b37764ecd56f938512f","0x045b9278d110a8b13bf13bffc6dacd9e3af08a07013222ac6c1febcf7d433e6e","0xf54d3a846e71e2811a2d75a63e2c99aac64dd2811cbdee04e3ab450604edd8cf","0x8fc2a5ad38c00b8a962cf7a2e17c1746cbd0bd97e0200182cc610960dfcf833f","0x9cf567b6c4bf1ae871ae0ec53e575bd62a7d60ba9970f2611cce6724a008bcbb","0xcd933afcbee4a9d5664b29577d8c9aa36f336f1b2e3683a757d0d4155cc4b55f","0xa6218af882961c5ea878b28bf2a034abb238b9144a1702f7e70c1cfa4d57fccd","0x40c4386d9999336e9b0b40400bd61b0f38ac681b4d72582af2037067d5419170","0x279b8f48adb0407dba92b12c2367ef3c72018c4ef3969b712139d70837655df9","0x1a9193431c64a989d9f707d33348ca0411fabaa270f45171ebe7bb80f8b3bc5f","0xd4d5cca39c760b9c7d5f375c3f33e73ae9c2c882d096e5d53d5378b051f2ac5b","0x4e797ffc1750e27a7fdda718bd02bf4a1b331f00e27f980508a5587486b580e4","0xfb26b2586797257db25c3ce75e95d74c994526e87e76bde330b0d8388b3d34ee","0xaca89094506473a40dac2f78b2da67d3cb6c12e11c5af1d7e040bfb834fa0c44","0x5bd97f29ebaf82b0ef965c289df51b29895626a47e69c954c3951fa759827a8e","0x037bf417887de2ea360a46bc7e8b31283b4758f6dadc768e6470831c6470ac43","0x1c95e7a721c532bc6c68aac86e35a0f30a102b079d7a8a18c273ff6b0bf6ddae","0x8ae011e7dd49c700fe1c9ff26848d9a65c74dd3dfe34dba0a37a957c60c63781","0xb2a0f9de786ea5da63c8a765d5c052a783aacd355044009e32f5df46236529a2","0x4a68062cfd6c26612a48fa96fe23e70b63b5fbedd7135664e595209dea45cc66","0xb73015448d4bde327e1d8cc01967acc4932c2d8efd71c6c823159ffab2b1819b","0x6ac02791f5590ab24321f20b32bd13c02ff13f21d843eec969873705d5983756","0xe0c7932c796483e35b20692617292fed1b4c5072bcd59b08e14df9411d88670f","0x451af5d30a1776ea43c5a8143c48205ab655aea5f0070d01edf3f9994a172419","0x0a918bf6e35aeb874245b42dd0528046c9638f20cb16c1f6bef03d0e4b50da7d","0x8adba58b9a83430a16f0ff56417ef6212bb7ab2bd5df73cbbcec46b591e7164a","0xe19503d31af286c679ed039b4bf63224f443b1e7aea58826aafcf78716119cd5","0xdd67f66abf9c78d07fd330e49ce52d27ceed9edf9ea329c1881693a0643a1337","0x23275bafedb4bd5d9542583773f00ae92d524f8dde496deb67207b9889710508","0x3f4eeb9960a538fb16a20c3f85338e4bee39871c474a25460b06422529af3a3a","0x37379cdac3d421da277f90e349a14935c37fd94eec7c38913aa7cadba635c527","0xb4e288a769860ba6fb1df1b5b769255aaec08430e9df2f2b82321b9dd9f68274","0x7127b4a6d81948b371d2144d365acf43440f7c5c303edcd00d7f1bcc4425d83f","0xa9564ccd010e8d4f6e3880f781d2bb77442f7d36e1d43d5f837dbb67e44ad75c","0x1c6a2067b57afeb51a4aab7bb294ad04ac988b47eb8674f67a0d9cd82e115b24","0xb8927e82150fd4836f593ebb27a6ad7b5ed2768134f23407031843febad1b3db","0x3466353f8ea1274dbec3607e058f4e6d3d20a017200eab4ed978651fa9ec5e9a","0x09adcacaacd75dcd20a1a187cdee4a4732fb3ccd8b633769341bcc0495c33d94","0x945355008a6b82eb2cc3798e6d922d7a7a18ddd601aea8e33d94cc0e6f0bcfa3","0xef7127b5d50420a9ff7d656067d615088a029a51b5ebe6a18e156fd1b928e830","0x35604e11ad486ced1c7784f13632a44b0e171fc75c3f813305abee466c78b93a","0xac0f4b25818aad74f331f1bf0ae00cf1c0fe1c93f38fbc23de7b7922f7d7ba37","0x69ade472e67bead8f74e205ae01d02d269de037e6b365a5156ecb43ab87564f0","0xa6b21381debf7a46bd60a3280138ab4618bd17e69991d6477db48f52c1d66c75","0x3cce4b9145d89cc2b82567681335cf603b3b568fc76f8c7d742aae9bdb59f098","0xb7210c3fb287201149b4aa58d8793dec28f09ccdeab3b3e96a3e7dcc488fa845","0xea8a02aef49a7982dc44aafd40ec7b4a339213127d0cb0636ecb29f0cb92c68d","0xfc5ab210cb528e7f19a3f70cf94ce39bc7b3da63bb63f05870b24c4e2ce981b6","0x76d327d8aec7d5d4acacd64b752356944367a9b9ffeff3a83f9cc9b8d05acc0e","0x5338f6c1d4717ffb8f1adf01f76cf4603fa3c12d9fe40e5ee50b6fb103293279","0x3a5c47e51a9b132eb81be6a6767a7446f2dee25e1b73e35f0f64a9b24cb9c249","0x554c618c062c7f7a1e548eacedae787316f62726a36db229474d161a33d945c1","0xaa0d5f064ad33e008aae37937f182ea56cda37f17699c6131e69ed2f8150c550","0x5067636b9acdd04bda39cf5edf0d4d4de14696fadd64845e71b663f9f5029756","0x12a68c66679edfc0e3b447311866877191253a92e4d1df8ab8016a4317fc2573","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0ebab3fa9caf754ca34a11069483677a133e3f9e9dbc8f37f7b96b639215a86c","0xfd3e6b6d84b621ad5a7c198a12abdd6d35619a22a6f46a0c5ce2ccd789c5615c","0xae21bc03162fd579deca3d23174e0e1a486dcde12164718471b2ae2e8e278cc4","0x6a20210af62a5762ea5bd32371a07a4ba440dd68e16dc17fb4b0f11a93eb5a0e","0x6324b2187b4f9c8aed48becba4265356c7f42703c3264e8b5f4a656d9a46c575","0x41dd75dcc4d45bdecfcbe298e6ae4e209a9c4f110da4a1abe67b316f79b02e19","0x06fdcf2db4b66c6c0e705d1e45ab8fb87456e96b2fedef0c16bb5422f5865ebd","0x0caa50818e4ba5222f71c7e1ec26bf8ef1fb804df203d91b7acff5a9a9bf8da8","0x69c6cfb99b885885410072d4b823a1c14847f2a5bce193946638ff9589e38027","0x1efc3d0b7a3a00cefe9d9a6edbdd16716ecf671a797e031df954d102fa33e475","0x1813df347507c6b7db2b6073736cfb16777caa8102d531d671618508d284b6ac","0x79e42d65cbda09e52d65197a6a3981cb65e77d049603a7eea190325aa7339304","0xcb481838351a2499ea0fa02059dba477013e77a80dacd966a1a456418bb049d7","0xbdb866cf7788a71a41c631f7fcb29457235c704cf506572aee00dbc98ae5b71e","0x31f1b85887eb2ecea458d5f793ab0877c70fc2900180ba86a2de21b8fcdd64e8","0xc0a18f7d20e157783f25b662e3461c4e10b0c4c5f23bf0dcac44d60e5b46f6e7","0xefbdab89274702e92196d3acbce99c7ed4f3afdddcca36e729a92a5c8c34fac9","0x926d13cd874db886b6e17a5a50ba9b7b52ab3b94e83be497b1a1818926635ee6","0xdb9ff3f1d38a29234cb5c285187365748136a14222a565e4f015897d5ea10576","0x874ce6eec5bb1afd92a1ce73ab39bbe9b57c80088b0726aff3bb7c4d83b5d98f","0x45bc05ebf59df1b405c593f4bf1a9369b1af4cd08b96366d860373b9118432de","0x2730a5b3a2e98e9f780d72050607ff1ee6175ab571c9a4a09ba0509ba863caf8","0xe7fe67a40d64460598407724226070d001f6e89460488feecb8ccf2a4ade8d4d","0x5150a0e4024dc8e9db68b971e7dae2276cd92a2fd6f3774d0c461d220760a8ea","0xc1206dd9d135024784c201ad1ee43c92e97306bf3c4cb2e494fa5c3070517bcb","0xd823f0883a1326d8b69dbefd35cd2cff4c5bfbc904bf591c94307e2544cdcef8","0x441c862454dcd3c791163a840d681fcfda61d9be37410b271f542075238fddaf","0x8d13b9f3da69215128231f08ab86f83f242550360a2bb1ed307bace57b6be50b","0x8661bc880e17f636eefc8ae2e10513e53a48e9812e8e0042a9385b9fe2143b0b","0x7efbe9e817f87a7b696292b2717b69b4a7383a308bf0a329a1c512effaf5405c","0x15ef021f136fa3484b0622960d83c922d1f936e17b6b4af111056165ff4d0b59","0x9e657fb5d28778d14bf0f1ad76a1bf0bf49a69f88d610693e2975c864551dee5","0x48247096b4f0161de943dbd85310b95f06bf1c97209a7ae2fb55c63ebcf28874","0x2c4fd23d0ed41e772a5249a1a3687831df50fa875e226097c3d281431adff04a","0xcc0fde14f3c1fbef3297859afc8e68726550a116b3b090d1d7b37160df592512","0x32e84941f25dd7af390fd0700534289675fbc492a32a626eaa2de47f251d1225","0x522bf7e1797d86cb1eb80b81509b9a63e23597fe080bc4aa0fff529998330299","0xf12b12523bcd49042abc53010ccf9346fdf3be20977bc44cb6dba618499ef748","0x893e6498eb52c869594df1cce89e955e49dc5e73a4a9e6f9d98818541778ba61","0x8b7d7a75b214d1ab1d508b77bd4eb9ff53f38e6c2f040040d49fcccabcb4ed84","0xfcbadad530e530fd6718308b0c301cd2ccc33e03504387ea2d39d9cbccf87e21","0x46275a040b45dd03b4bd9c8793c6abd8ee3928803f14f92d4e3f4f27eca2b340","0x516f19811155bd8b5ea78944f393d0dd8b1adf0f1590d1424c82ee1249f29818","0xd2edc7e07bdb6594fecf66aecd32c321eb6c5f7130fdd28032d8e8ec193cf7b6","0x038f0b57441772c6fd16e69cd9bac08d3e1d133bd8eccb725eaa88f136bcec98","0xa1f46e698d039a096d39a200a64d4843d91aca45857fe37042436c0bb7e7d1be","0x217985e443c685431fa8e0d5a187f3e5764305d50d52cc99424c187b8dba5199","0x97dbb21f685a28f294f987843a1685f92ef50fc70d739402785eec8ca10d87cf","0x6679573fbcf116d328337f4d9caf6377f466756e2374957b268227d282017fb5","0x026ada0ab6de333c3178904aaded6ae75c1750e4a748444b97407b450ebb0c31","0xecced645c7e330ab5c90d0a3b952e81b371e321c81acb8fbdf0d1b01da55977c","0xdbedc2f4c83591d8ee4d6be3b183cc955de68d93b2d97a692ebaf11fce1c358c","0x9630be5618bac33a3e79470dd9026afc34392e4250d11726dff670fd85e71df1","0x6adbbc57b2a78b93372a77eeaa56908bf0cd7181f0557d832aab3a5abff0ef90","0x5219701047b645d734d2143096eacf95ef28fe35572f95bea2386ec6cd05a40f","0x2fd2987bc2a52443e0a583a93eeb6898ac835979c627aace93520d30f324b2a5","0xbde7be8712ad7e14c69f81ea2eaf2c325ae3bf0fbf6707bea53ddf7383ce443d","0x63155ae112159a937c997660bf11a495b17b165c897c5367044ff904e4f6b6a4","0x67d92db7237938fc835bdaabba982095a4fd93c0c0f49781f2f9cc49a8850267","0xed78ae48272421ddadcc82232da16f3facecee7fed830db1b726710175ca9e8b","0xe65d5be696cf6cb56c64fc07aa7cacf1901aa4f3426ad6596de5562c1603988d","0x907a120592af2ac34e2ac1c72cf1f06161fc4a620fba65fe69144ed6996dd347","0x826178de76ffe4dc39c04287bb88bcd4d82d8cf300c76d76498b0e199443d127","0x22fff777354cdbddae22e27e9eb7b00496090d765727b753fe5b638b834a2339","0xff9153bfd019a11dad8e3dd5e7fbdf23480734028f56e5dd4f40b6a07f5e0bbb","0x61b9d980e71964752c0f84a8305a99dd18ec6fcc28885563ee3d87c7b57fce9a","0x5d4f953771ebf85cc2db14ff51b2a1477a06a1a2b0ffe3797c87e70d67c6e937","0x30086fb8d375088c80fc219c4e8a5b6fa0b7e2718d119d2e5736254eb625d0d8","0x49524f3f369b46c5e01928fff91a5a84367792e6e8a59b2a3819e55274d4dfe4","0x1d62d9c594c61bb567eb9c4d6227e0677d71aff94b671af4812eb2be0a73f3d1","0x1dac3c18c242a1cd60b3c89a32673b95290f8b6328f184475abbdf4b6f9db59b","0xa113b4f66cbfbda00ef4fb85c358304bbb2492ed79d0335e8081111f1f124984","0x0523c3ff37eece967cb89eaf9d320a02e72812d60cefe544b7bd2c4d5bc9b076","0x4fc28edde733479eb395df4003c2be4406419015c37574932a2e3239f66e6b08","0x1a4bbade71ace795f32ff1c36398c6ed8f3b559b705d1298b85863ee39420e80","0x621dedebe93a1e821c0575ffb60c0c3352bffa4ae1ab9e9f4b1186ea00be1ce0","0xee0858e479b33e7a65ffe1cfdf1174ba148a5fe5f7445b61e8701dfba6f29535","0xab893b43a44335510ba7201fb76b581e64ce6267508d0ef9a807216c98f8b2d5","0x43e6477d812ae6112d3e3f7f6ad3792cd5855f14913c539d7711bbaf52534f6e","0xa88a344c6a69266b56936a664cc95618584c52c32ca85c340e43859c59c133b0","0x2549ad82a8022ee1f145a6022a87b39202d921dfe235fd8edb7833f146d0de1f","0xc58342b8425c9e8ab13112e41647296e9b5a8fbbb530712ee394901210bd6119","0xbc47be4c05ee205248c6a95bef044be3ce30f082b44ebd973c22fc26adc1b53a","0x7340311f4760c119d73b5367dadbbdb99e457dccf8be4d869ff168943cc04014","0xf15c0675ebb9dd8eaf2c287294adaf47eeb05812c3e889f588084a764b23d7d9","0x54bd870df26fe986c756a9473eb85f5ca74407e3669621ebda59d0869e1be419","0x47ac7dec3f3d4a84974afd0f78e40915489cf036909a16a55f593fecc1f70d82","0x75186e75976e4e80674d4d45d959451041b23cd2f16d9c37e674b852d417d4f1","0x33f7f652084137b51256f9f091126df122c965803ce97bdfe0c2e0a3c404f393","0x9fd6d92eb4197b24dc5085658fdba94b23a1d6240d9cbabb2700490d5e587f17","0x1173afdbd256fe0396cb58568083b6bb76e132beb86693826d49cd924ba548a4","0x5d78a82df6a4d7e9e8f869f9069e88fc2c7162630dd751451ac20923f53670d6","0xe1289e3ed882008bfbe629c99ef4e87a0594f2a221525a4b332037ab29f2f502","0xccca76b275abc6a34d8a50371d8fc020c90c4d61816c81f2da9e1c3c669125fc","0x9095c83528a081c794b3de2795e25cbe0cc65e5064c93e065be3ebe9fcbe0fe9","0x6c9167c2a06fd708014d6ee177d8b011c3b14d63d452e76a25b6c6274c2d4c2f","0x98a84b96f90ecd92b8745c8605aaa4ef86478d1ba8e7d6f866dad1a72103c408","0xe29402ac7316b94bb4e2d6b831c8eed1030a260788648fc69ca0e489d8586852","0x17fa82a84f7df8e8c96e0cf9081668de9891b2b61156f1e9240d15fcb5cebbe5","0xeb999a6226f9355ed4559cf6ea25afff38b369c3e8bcfd99a0ff650d3701e599","0x7ed84bc4085139e5962483f4997ed5f8c6529f061f1c407a0bc928a363948164","0xca44491932176de008ebac2db54455015390c019704fd5c436bf2063e52b5045","0x88c3591b88c6c2e339a0c67c4db7a6e49556b79bac77d348c8c6ceeb254787ac","0x3239549a511c1196c09a1db1b0e3122fdaec828d87ea6b92858c2084b160db75","0xd77f4af3e98e05691eb66e4b4c3409c979c71eadcb17846c809fa53d03153571","0x289520f35c47d931d3fc54290eaad20ada7289b026bda1eb5b581652ce2e384a","0x09a565a976ea5c6d00b83662fc82435f55614999aacc5280b05f367aaae60dc8","0x8918ecec0902addd2e7555ffc89a7a98c2ea667c3232186d6a649d1bfe12ccb7","0xb671c1a016a926f1da02ef5462fb893f81b69242fd96516e89ecf1b653caef41","0x5c002cec8ee88755ec0d4fb44dce974d507243230804e0e9319d96ce2fb650d5","0x3986dfede11e3b5475ce543e67e0b3c28a6bfef75daf7ede3a6130c8fee37d07","0xd6074ccacc89b20a43bb37e86a4237f85a9912b844fc3f55d5a97dbadd464fe7","0xdf7115287ac8af491c99ebd513f1f54548fb0cea2643a6104acfd8bc3ed5cc7b","0xee52ef344c18a4ee3a2d5761d0dcc2340e2a949eb03baa241f55387f09435748","0xbc3ae81be6bbb31b7de5feedc136a0080b880a562875db5b2cc098ffd86ae683","0x2e937f79e8241040811a88c63875a476f402fb461cfb8b795c89c0ca74351973","0x6fa05484e53e674da54ff6736cc3056ec36606cedd9ad6cebd7a854f91dbacb4","0x102b65dc7ee9806f0a5159a38cd64c3bdea4cb633a8887cd183e7a4b350f7279","0xd49dae1b21ae37d06d482e1630e1f80ab72676919e772aa137c757e93bf42ee4","0xf799ff20def83ab97b5bfa3766ccf05cb36797f22bea4d60f24d4d845f61cdcf","0xb348828e6ce3bdfba409104f31d4548067019fe6ca932a7ca0ceae1d54878f6b","0xc5114f7251a785a4b20bcb5b1a34df6d581ef4ef2d1a63adf7cce237797a0883","0xad77415aca4681ef143b652c07dbaf4544e180effb7865a2064b8e9071845b9d","0xe1aeefec2c6d7dc4112cd71eb8723062f6408b83b96c4e32c863c484446b1d6f","0xea75fc0e6f056f8396f2bbe43a39d7a2aa9aa4c6683b03f9821b43204eb6da38","0xd3393baee58501e894283a5ae4d235282f16d4ed4fa69162da70a09e933d6af7","0x5e795e4c3c6965e637159b47ad39104af3056c960da7a87ff239d7e564f2858f","0xbcd83d89de9f6c4568ac72e271ec30e26dab1b1728389e1a608467d5d38e1463","0x9eb5f8aedf04a4f9c4264ae677f736b75e02e86b85c0872a8df5588c398dc1f2","0x3419f749361729bd6694908331e7e6a03637828ac65dae0ef9438c3ac9c2ed98","0x35e4f63963fa34e76738d307db8093d02b38ddc63b7ad0c515d3f005785444d0","0x98cd55db85a77e2415d4a22e7bdc54ad6f1841234b83ffc1b99bc4cfb5f35c17","0xa49bac313b11e33371789ce473ac7bca5826197fa4fb45c7dc64c7f2d518758b","0xfe92eb02d0b7a90d3b112b5c1a65bf76dba297c89033405bef9eec2db5e46cc0","0x4616c98ce98e5454b00b4e117aca06e74c6bca209cf4b3acd676b0a20ff23ee9","0x4de94d40aacc25478d73d716d69a80e67b077816f482abfb5ded9374c4e7021e","0x1de59cd2dd81527da4ec7adf9388d2fd3eb2c20c410342ed06fc3e5bd6b39e88","0x86d1b31502bcecc4c051ab1cd6a56e6fde457e36aac04edcd4bc9fbb8e52fa06","0xb6794eff6244b4ce40ef157529e418ae4dd60af2bafee910be32ad1452ea451e","0xd840648423f1b38daf97f477ece0de1791f8bcd935163fb6d11de2907633ba63","0xb2efd44da134c7fff51988cafe5f1e47719f48a0a2879a287eb54956e6e6c6b7","0x6097d26e842588c732c0b41734131d6dfb22294cbbfd5d058b7b0ae6bf69fbe2","0xdcf1a4c2bf89fbffe49d769e5d15f4d42588625b4b70930a3771217477f2382b","0xb8eaa7607b3f000da9131ff685b07bc71c365611e6e5ff2bc604b76ccd6b0dd7","0x65894b2a5bf92b01a2cb8f66f53b4b16906d8761fd0558e48d415e4eca14b4c9","0x418cca8895784ffe994ed1ea13838d83a19ad372763d65cd91617f633d371cb0","0x3f6c7e34aeaa5b77c8c002453eb7cf35783f1ede137d94834e241aba61bd8d08","0xf3899c5f2abc27b89066b391ab5ad02d8f093276da9bb36fd4f32c0b0f936857","0x7d7639998906404a31abecb601c4dae839cfceb47cb01bc98f913b8809e97d10","0xefca25804218c7ddfc3aaa52cef60e46cebd162a3b2d36152dd75a1b45b92a1a","0xb38aa179500d6f06e1d8bbdd505366459e35c21b3e5f5cf009b0c5349b3dfcb7","0xe37243c921eb07d02cadc418a8d631434438cf181b70333aaa9218e25f39584a","0x36a5c8559314b9d737230b3627938162d3b0f0ca649dff12b40bc1d18eef9941","0x9a8e4bb6a938129173e16f93ab75506d09b255a9e9b2d1dacde3948ad5c6107c","0x3f162560ca16d7a6a8f6731cf4aae82f41f36536956c3ff13b1ebb84371e097f","0x0cdd9e224c5fdeed83672f4148791439a94c35fb3a7719d0085cd5ff72d0b34b","0xd21d5fda2ad57cc96d13f19aa2d8fa49d32f38954996550616f6ac49155fbfb9","0x1da5c215cc86ce98e62684f92619d83ab6932425a502b3342d21f8e9e8b9e1ff","0x24d30ae661fa8f96f7413fe81dae84a7dbc7cef095874d6878a7d9a11a75f995","0xb92ffd8b340d2ffb009be8cc0a0a474f03c5bb569e97e173f64e4fcc695b926d","0x802c04474f2636e0a98b28dd13ea68004e3e65c0be2174faa10a415bd46d20e9","0x9d0c0ccd1c63ce9b8b55cfdbbf6c188ff66f71b8856a0e9f87e724ba1a3a5c50","0xc9e96dcaf5f23c627ac7b21ae329475736eac917a19d2cc63a91d03b8216aeb9","0x5f4198b367414bb080318d1d72b8084fa7900bf69856f68e2d41d5e60ccc1ace","0x3dccf57cc8ff20f7429e358bc9650029fe3be7ad6a7b877c8108d587cc7a65de","0xe8c95f65bc2950b3d1fc150326a5dc0807049c5a13d82f43a8a1ed532cb6964b","0x3165f7fba25e9608530eaa0de9fb7c7b310c6cd2e039ed2c1093aff4debe7a9d","0x0eea7e4a3be71b1e7d4adf7acbc628798de6b29d819cfcfcf1285546f78b574b","0xd31b91822f42bcc536e1a05b57bd531ae3f362d9072fa7e60175483488ad2be9","0x5456bf8a138557ed15c5e757ea79fe234a449cf1c1cd4e783d5e64257580148e","0xb11ebf57a9a8d1469228dd49133e9d730e4f4ec94af61fd609475bdb2cf0f385","0x8034c4810df18c184da64081f70b8c9f32df6edb332c30fded54ba08305709a0","0xe8ea046f5d98de82e1eb1bf10eeb337220a7963356b72f80c759cbc3cbae9ec7","0xa084a28740d1772d1aebd3084e95259512c1074e357ba80bf1724ceba70dd5b4","0xdb9ee6dc3160ecf29ef10e7468398cdfb381f2717d9736c060f074f51ee9afac","0x083ba7449aadaf3742e48dab01f9ae75028481c48cb3989541c3181f0d0c8ced","0x889a0ac2aecb3ff4fa3fceb5bf69b771d08814ade9e0f65154cac2b5aa619a0e","0x4384082f19e227ee879db5cf7dd69309ae25200779f800c6e02cdf7f14a51721","0xea703ead5d8d8c48688b75f0aaf4d32f95a08f3d3b06bbd3f6d689b173777e1c","0x3e3f37f943dd26f9f8af209b0157837a0eccd129e0b97d9d9273ac84e8512543","0xb0c2d0229002ccab30a033f0de4e1eba9247c7f51ade1356039835b390132dc1","0x16e9b4aa46b7239e0d3ee87c7ff28d8ffc7443e5478267f8ab7713f4bf6ac2b1","0x0c78adf8603f99eda1de4b35979d5f43798202880e1d4855b4a4cf55694e54fe","0x95eb40c604cce770d2b6d555b1e6c9b74e2b4a95b417bce29be5dc076fd6e997","0x6615bc11e36667f47164fdb4a631c606c025822324d070c99eec52295b6e10da","0x3f2e764cab495c3ce8b20e92deb6506b209274b331ef29a7b4af043a56109a48","0xb6dc48ea5fc198c84752c74bafd92db8ac3786b233161cd9be7061e3a4cb17a8","0xd0cf78d73d68a842e22a421b24145dac2e1c6ab1b6d3227e083dfc05d35fa872","0x4ae6cda25d262480658051a6226fd97b2d4d58a9e1186c558da814534f8d41c8","0x0ada8890995ce40da5dc3dacd0f1de348d06969a92896d7a951f03229bb6d7df","0x39decff4f532487c3326a124d6737ad76e373ee3e37257af395bff799af35add","0xe60b92f1a25a5e07f5d1fa773b5bcd4b0412652a4ab3a2519a64ddde31784987","0x2a305fa54826094013d777001c4761881ad4112f540f8959005cc8191eb793bc","0xf25d60d1ef516e18c31c288bfc7aca903ddfc6edab6f1123377d4e34ed0782b3","0xe777ea8440c9a60b5ce3556be8cda26963337191b91b846b2e4893ec7a5bf1ff","0x21f53eb2ae942d42b920513239e28511257130462813514ce56e42798d7539cb","0xe9c8d8da908c4edc540cc4c7940aa615e83b8b40f06cac2d37eeaa18d62c0f37","0xd0d4d5f56f200ec662943557b8fe6409da62799a50a4d68f95569f02aa5faf59","0xaac26bd407fc2b56d855afee83187aebdfe1deee0ade440803842e8c3052e432","0x7c614fcc7ec732a90353407659eeb13df766a92e8976b3036a9d864b4d92b126","0x76e7d0fb21fab3d4458f348c215abb7ef7049bc84d6f26ad557954571edaae9a","0xfcdb3a5c42f3247158caa81e5861f30bf169ab8289c3baefe5b8dab2ea545e5a","0xf213ba8cb47f9be8d18debc8b15e600d40785cc3ae81b7ba4539c0a4346dc6c4","0x322f395a2b47ccc094d1f0dc2521f09d31ce0544ea470b5a7ac8df65495ac3da","0xf6cc35a294a1b300159a88f7251ea97f28b94ff4cf625beb85b6bc2a4921d2b9","0x1894df21c97b6c77b319bc276b8c03ffbdd16432bb17a17170b8853df9fd0004","0xbdb6e4ca9c7fa40fe7a2efd9d737bd8cf9012b0f7dd4f7297db52a0d3bc05333","0xbc0a51da1c9e1bb2b6454a7af0ca8a2dc4627a806880d19333b243169e409f55","0xb9c18ea5166a0446e88ee04a5adb011cf85f0673199f81217e053747b2981da4","0x525798ec2fc9e62461cb85ac0f3012f33419a5c44b5e450fd9df366014d2bd5d","0xdbd5114edbaf2855ee94b2b5d8d440bd3bbbde82aa55b3baef3f9f28b7f025e7","0x569537c67868f3a3ffe95d304ba255cab3c667713fba21f5447591e8bc392611","0xa8dea14bbbf5005e51c332378263ec133859f1ad7b16fec00963f1ac5b1a527d","0x28583a386b43376c288f234997ba65277e86aa907cb1264144340676692dbb8d","0x0168e1b4ed0e88367b7fb3f96a302cc3c885ac12d18bab4123df9f124bbd3f6a","0x266803bd9fde92d08780378fb4bf767db850933e69295c2b66d1abc2e388a6a1","0x97b6ef288f152f3966966fb056473bbb5e1560e70b51bd336dc6d2124c4e298c","0xb88c38814ced588223402a85e9bce3bd25f1142a90d55d51831ff507cb8ec200","0x5eb27bf798e7a83da1a839e1517c71d35ddec075f16513b0e44d8131557166ae","0x6e42599a4f38fd0503870fbaf5378a6408188bcfbdb0538ab7b854d00e038a63","0xfcc572479981c262575f5e93d149398f4a30dd6d634b60f52006092ca322dae2","0x45f2acb59cba76c87fa112de958319b4cf739f42ab3ca5d3b9ff3ffdecdee3f5","0x73b76b06500578b3b969660b407a2f2dbe8f08067e3f09a91e2a7602b0818bd7","0x18b1be172e8cdd0448ce24329a0491a82313da5f7d069d4b5053f93b8928105a","0x72fdc38f7c3477548ea6f42afaee27400714a812a3571b07904264c3ce459d47","0xb236d39d36982beb08d0241dd052a9616cb95c22d5da787bf239109ba1676683","0xb4645a7b14200a267f23095bd453d6924378dc5df5fb3d0a6ad45de2a42ded17","0xc488d6f42f0ddc36a69af842672faf2be23b053ad3b580588995950f3a637829","0x182258555e4a8ad5c5fc3df3f9cf3fdb371adaea4af67cfaddba82356c8bf593","0xebfb2911e92c769638a2e58fde949c4e788c7cac8b9f16ba718df73b92a26318","0xe0191ef6f2a8d6ea81d6017f43ace34ebe4929760214f5122202b451bfda0f49","0x18a1522e467a0069120644a5c592695ba98c65ff139bbdf4e454db9a39793ae5","0xe1d2c447eaa41fca424f810b3bf8172773e1e13ce025a7b5b8aa2257e4031ec1","0x156706b2eb3fb2a08663ef05bd4894027960887e903a05ad321cdc66815bf6aa","0x289b711f9e64061f8321f70eebfb35e433b86327ac1fc75e2fc4099a5564cb32","0xb4c206e1b045055d5c840ee20a32914ca8b4765e843e6f7e44ebf07af5f344d7","0x437ebe7fefa45065137b1c73475430bc44b0d17d34428c101e8af200d51c1502","0xbd462190c8e814520efc2be38171ddfeaaa63ba6888e639423ac5c483caf0265","0x6c0b22711e9574f3349ab05d1c24a46d3b9c646f29d7cd386580fb014673b1a2","0x27ba165e9a5ee63cbcee254b33818e8bf50dade62ab01a19da024d80409a3f63","0xc55dc291bab50d6b060d0dc47872b12802c7fc9cf2a1b44a703237b071b38fd4","0xbc6aa369eb8c3d5c1a9cb802eed01d7934161095d4ae5f47d3da09f90d40f82c","0x03f1db8c5a713e4c72cc02bd73d93d799ad643e9c79d2615120e4ed821b1a1be","0x430c25d5d71ce628ea7fc09be3d2229db2baa9ec504ecb8c60b770f5f797703c","0xe9dc0f169551910bac9a4dde8dbc226f06b947f58eb35820069f0c1b8ff84c9f","0x3ee19c732b9d2b5fe7b9797b8651dfe19f70eb366346ac7d0167518866a980e3","0xe359c3a9fb1bbf5cdf221c4b3f07ea1ad3eeb407660940a34268aebae29e4f24","0xf8382abf91c8bc23fb27a929d08bff6aeff001aae58b062488cad5984d52d3d8","0xd2ea9116729935a4d3a55afe7308c804e0ee742e538657c189397ea0745c95fa","0x00f597323c668529ae4ba6f05a5899e3e419c943c87ab315107be95f166cc71b","0x4361cdebb3cc58f58d7b96a0df207ab8413bed1f484d05122b42939068b50805","0xda1d9486f368ac7a32c2b45b3a8e99241b9d76e76d62b4efb4d7d9711597ebdf","0x6e2d862010b81d26884a38a6343c9d04d0ed5c8751d2a333a18ddf9fd8deb282","0x7e7043e2c7b147bb9b81849e7d926c625be1ff61f78aa7142295627e817b2132","0x344950db3d11bef646e9f7ea0f0a2a38ae1776f00ebee748199dcb8055d8b2f6","0x66fda39e4207c43ac2f49c1b75b9278171c6fae1ef2f68717aa916898f371123","0x897aaf76286e8e77831537466f346950ebbcdfa6a41bc4f67e7c0db324f519ed","0xc6195bd2ef4c97b8e9aac11eb795b5b407da52da93a0d69ea48fcc1bc5ed57cc","0xa05970b103532874357cad3d0e7752b54be79ac28a62c3b8380e9abfd7f8734c","0x8653a1863ec56056f629b0444b580757b854797d80345225ef97448b47f2b3c0","0xaf2023f94823452108a9579d09027a0f88652895c9599990be4c00d20175a406","0x0e40e813219451fa9de8509be8ca8802fee6483624ae4ca20703e70a3abef6d7","0xf706032373d519621654e5d9171ac7cf3d40c5da2541c8d475a12307f8c5720a","0x97cd59aa046b42712ef1b16db8eb055b1aa2841d9d06498b9f5e9831cdc5aa45","0xcf4a61d34a1d19b936f336d251abe02e6bb5a7d9c89108839bc4ff1b9713dea8","0x2dd851cf467a5f4c0cf32eee0398933cd8c5a048e5c3f96af5073b7a216d06f6","0x6e10e843284bc5e07bc8b75cf2904cba84c2ec8e2a7baa9cb425ea74ebac5b46","0xcd8ef4f11a5648f0084b29bfbb5a2cc8448e8d019a9929f2b7bff0a8cf30d854","0xa7d7592c4a6755a62f3a5e6b1a8c06714ef7ea98f77c5de8664541b51f6638b4","0xe22f6dc9ae3e93b6ec448147497b22e30157f64b8d40386eb1d1ae10fd64aad2","0x22802f854169e0b0ce6e99a333fc45d8c4a58d1c1225d0e4001c681997314a7a","0x72d1ca69bb5d63a7d4f650464d4c0cb97b174a335c301b3489970f6ccaf7fced","0x6f4e21bd36d54f424d347b7c4cf29b1be37306aa195b08f5f652b21e57ee078e"]} diff --git a/cmd/workload/queries/history_sepolia.json b/cmd/workload/queries/history_sepolia.json new file mode 100644 index 0000000000..cd2182b5d7 --- /dev/null +++ b/cmd/workload/queries/history_sepolia.json @@ -0,0 +1 @@ +{"blockNumbers":[0,3891,7782,11673,15564,19455,23346,27237,31128,35019,38910,42801,46692,50583,54474,58365,62256,66147,70038,73929,77820,81711,85602,89493,93384,97275,101166,105057,108948,112839,116730,120621,124512,128403,132294,136185,140076,143967,147858,151749,155640,159531,163422,167313,171204,175095,178986,182877,186768,190659,194550,198441,202332,206223,210114,214005,217896,221787,225678,229569,233460,237351,241242,245133,249024,252915,256806,260697,264588,268479,272370,276261,280152,284043,287934,291825,295716,299607,303498,307389,311280,315171,319062,322953,326844,330735,334626,338517,342408,346299,350190,354081,357972,361863,365754,369645,373536,377427,381318,385209,389100,392991,396882,400773,404664,408555,412446,416337,420228,424119,428010,431901,435792,439683,443574,447465,451356,455247,459138,463029,466920,470811,474702,478593,482484,486375,490266,494157,498048,501939,505830,509721,513612,517503,521394,525285,529176,533067,536958,540849,544740,548631,552522,556413,560304,564195,568086,571977,575868,579759,583650,587541,591432,595323,599214,603105,606996,610887,614778,618669,622560,626451,630342,634233,638124,642015,645906,649797,653688,657579,661470,665361,669252,673143,677034,680925,684816,688707,692598,696489,700380,704271,708162,712053,715944,719835,723726,727617,731508,735399,739290,743181,747072,750963,754854,758745,762636,766527,770418,774309,778200,782091,785982,789873,793764,797655,801546,805437,809328,813219,817110,821001,824892,828783,832674,836565,840456,844347,848238,852129,856020,859911,863802,867693,871584,875475,879366,883257,887148,891039,894930,898821,902712,906603,910494,914385,918276,922167,926058,929949,933840,937731,941622,945513,949404,953295,957186,961077,964968,968859,972750,976641,980532,984423,988314,992205,996096,999987,1003878,1007769,1011660,1015551,1019442,1023333,1027224,1031115,1035006,1038897,1042788,1046679,1050570,1054461,1058352,1062243,1066134,1070025,1073916,1077807,1081698,1085589,1089480,1093371,1097262,1101153,1105044,1108935,1112826,1116717,1120608,1124499,1128390,1132281,1136172,1140063,1143954,1147845,1151736,1155627,1159518,1163409,1167300,1171191,1175082,1178973,1182864,1186755,1190646,1194537,1198428,1202319,1206210,1210101,1213992,1217883,1221774,1225665,1229556,1233447,1237338,1241229,1245120,1249011,1252902,1256793,1260684,1264575,1268466,1272357,1276248,1280139,1284030,1287921,1291812,1295703,1299594,1303485,1307376,1311267,1315158,1319049,1322940,1326831,1330722,1334613,1338504,1342395,1346286,1350177,1354068,1357959,1361850,1365741,1369632,1373523,1377414,1381305,1385196,1389087,1392978,1396869,1400760,1404651,1408542,1412433,1416324,1420215,1424106,1427997,1431888,1435779,1439670,1443561,1447452,1451343,1455234,1459125,1463016,1466907,1470798,1474689,1478580,1482471,1486362,1490253,1494144,1498035,1501926,1505817,1509708,1513599,1517490,1521381,1525272,1529163,1533054,1536945,1540836,1544727,1548618,1552509,1556400,1560291,1564182,1568073,1571964,1575855,1579746,1583637,1587528,1591419,1595310,1599201,1603092,1606983,1610874,1614765,1618656,1622547,1626438,1630329,1634220,1638111,1642002,1645893,1649784,1653675,1657566,1661457,1665348,1669239,1673130,1677021,1680912,1684803,1688694,1692585,1696476,1700367,1704258,1708149,1712040,1715931,1719822,1723713,1727604,1731495,1735386,1739277,1743168,1747059,1750950,1754841,1758732,1762623,1766514,1770405,1774296,1778187,1782078,1785969,1789860,1793751,1797642,1801533,1805424,1809315,1813206,1817097,1820988,1824879,1828770,1832661,1836552,1840443,1844334,1848225,1852116,1856007,1859898,1863789,1867680,1871571,1875462,1879353,1883244,1887135,1891026,1894917,1898808,1902699,1906590,1910481,1914372,1918263,1922154,1926045,1929936,1933827,1937718,1941609,1945500,1949391,1953282,1957173,1961064,1964955,1968846,1972737,1976628,1980519,1984410,1988301,1992192,1996083,1999974,2003865,2007756,2011647,2015538,2019429,2023320,2027211,2031102,2034993,2038884,2042775,2046666,2050557,2054448,2058339,2062230,2066121,2070012,2073903,2077794,2081685,2085576,2089467,2093358,2097249,2101140,2105031,2108922,2112813,2116704,2120595,2124486,2128377,2132268,2136159,2140050,2143941,2147832,2151723,2155614,2159505,2163396,2167287,2171178,2175069,2178960,2182851,2186742,2190633,2194524,2198415,2202306,2206197,2210088,2213979,2217870,2221761,2225652,2229543,2233434,2237325,2241216,2245107,2248998,2252889,2256780,2260671,2264562,2268453,2272344,2276235,2280126,2284017,2287908,2291799,2295690,2299581,2303472,2307363,2311254,2315145,2319036,2322927,2326818,2330709,2334600,2338491,2342382,2346273,2350164,2354055,2357946,2361837,2365728,2369619,2373510,2377401,2381292,2385183,2389074,2392965,2396856,2400747,2404638,2408529,2412420,2416311,2420202,2424093,2427984,2431875,2435766,2439657,2443548,2447439,2451330,2455221,2459112,2463003,2466894,2470785,2474676,2478567,2482458,2486349,2490240,2494131,2498022,2501913,2505804,2509695,2513586,2517477,2521368,2525259,2529150,2533041,2536932,2540823,2544714,2548605,2552496,2556387,2560278,2564169,2568060,2571951,2575842,2579733,2583624,2587515,2591406,2595297,2599188,2603079,2606970,2610861,2614752,2618643,2622534,2626425,2630316,2634207,2638098,2641989,2645880,2649771,2653662,2657553,2661444,2665335,2669226,2673117,2677008,2680899,2684790,2688681,2692572,2696463,2700354,2704245,2708136,2712027,2715918,2719809,2723700,2727591,2731482,2735373,2739264,2743155,2747046,2750937,2754828,2758719,2762610,2766501,2770392,2774283,2778174,2782065,2785956,2789847,2793738,2797629,2801520,2805411,2809302,2813193,2817084,2820975,2824866,2828757,2832648,2836539,2840430,2844321,2848212,2852103,2855994,2859885,2863776,2867667,2871558,2875449,2879340,2883231,2887122,2891013,2894904,2898795,2902686,2906577,2910468,2914359,2918250,2922141,2926032,2929923,2933814,2937705,2941596,2945487,2949378,2953269,2957160,2961051,2964942,2968833,2972724,2976615,2980506,2984397,2988288,2992179,2996070,2999961,3003852,3007743,3011634,3015525,3019416,3023307,3027198,3031089,3034980,3038871,3042762,3046653,3050544,3054435,3058326,3062217,3066108,3069999,3073890,3077781,3081672,3085563,3089454,3093345,3097236,3101127,3105018,3108909,3112800,3116691,3120582,3124473,3128364,3132255,3136146,3140037,3143928,3147819,3151710,3155601,3159492,3163383,3167274,3171165,3175056,3178947,3182838,3186729,3190620,3194511,3198402,3202293,3206184,3210075,3213966,3217857,3221748,3225639,3229530,3233421,3237312,3241203,3245094,3248985,3252876,3256767,3260658,3264549,3268440,3272331,3276222,3280113,3284004,3287895,3291786,3295677,3299568,3303459,3307350,3311241,3315132,3319023,3322914,3326805,3330696,3334587,3338478,3342369,3346260,3350151,3354042,3357933,3361824,3365715,3369606,3373497,3377388,3381279,3385170,3389061,3392952,3396843,3400734,3404625,3408516,3412407,3416298,3420189,3424080,3427971,3431862,3435753,3439644,3443535,3447426,3451317,3455208,3459099,3462990,3466881,3470772,3474663,3478554,3482445,3486336,3490227,3494118,3498009,3501900,3505791,3509682,3513573,3517464,3521355,3525246,3529137,3533028,3536919,3540810,3544701,3548592,3552483,3556374,3560265,3564156,3568047,3571938,3575829,3579720,3583611,3587502,3591393,3595284,3599175,3603066,3606957,3610848,3614739,3618630,3622521,3626412,3630303,3634194,3638085,3641976,3645867,3649758,3653649,3657540,3661431,3665322,3669213,3673104,3676995,3680886,3684777,3688668,3692559,3696450,3700341,3704232,3708123,3712014,3715905,3719796,3723687,3727578,3731469,3735360,3739251,3743142,3747033,3750924,3754815,3758706,3762597,3766488,3770379,3774270,3778161,3782052,3785943,3789834,3793725,3797616,3801507,3805398,3809289,3813180,3817071,3820962,3824853,3828744,3832635,3836526,3840417,3844308,3848199,3852090,3855981,3859872,3863763,3867654,3871545,3875436,3879327,3883218,3887109,3891000,3894891,3898782,3902673,3906564,3910455,3914346,3918237,3922128,3926019,3929910,3933801,3937692,3941583,3945474,3949365,3953256,3957147,3961038,3964929,3968820,3972711,3976602,3980493,3984384,3988275,3992166,3996057,3999948,4003839,4007730,4011621,4015512,4019403,4023294,4027185,4031076,4034967,4038858,4042749,4046640,4050531,4054422,4058313,4062204,4066095,4069986,4073877,4077768,4081659,4085550,4089441,4093332,4097223,4101114,4105005,4108896,4112787,4116678,4120569,4124460,4128351,4132242,4136133,4140024,4143915,4147806,4151697,4155588,4159479,4163370,4167261,4171152,4175043,4178934,4182825,4186716,4190607,4194498,4198389,4202280,4206171,4210062,4213953,4217844,4221735,4225626,4229517,4233408,4237299,4241190,4245081,4248972,4252863,4256754,4260645,4264536,4268427,4272318,4276209,4280100,4283991,4287882,4291773,4295664,4299555,4303446,4307337,4311228,4315119,4319010,4322901,4326792,4330683,4334574,4338465,4342356,4346247,4350138,4354029,4357920,4361811,4365702,4369593,4373484,4377375,4381266,4385157,4389048,4392939,4396830,4400721,4404612,4408503,4412394,4416285,4420176,4424067,4427958,4431849,4435740,4439631,4443522,4447413,4451304,4455195,4459086,4462977,4466868,4470759,4474650,4478541,4482432,4486323,4490214,4494105,4497996,4501887,4505778,4509669,4513560,4517451,4521342,4525233,4529124,4533015,4536906,4540797,4544688,4548579,4552470,4556361,4560252,4564143,4568034,4571925,4575816,4579707,4583598,4587489,4591380,4595271,4599162,4603053,4606944,4610835,4614726,4618617,4622508,4626399,4630290,4634181,4638072,4641963,4645854,4649745,4653636,4657527,4661418,4665309,4669200,4673091,4676982,4680873,4684764,4688655,4692546,4696437,4700328,4704219,4708110,4712001,4715892,4719783,4723674,4727565,4731456,4735347,4739238,4743129,4747020,4750911,4754802,4758693,4762584,4766475,4770366,4774257,4778148,4782039,4785930,4789821,4793712,4797603,4801494,4805385,4809276,4813167,4817058,4820949,4824840,4828731,4832622,4836513,4840404,4844295,4848186,4852077,4855968,4859859,4863750,4867641,4871532,4875423,4879314,4883205,4887096,4890987,4894878,4898769,4902660,4906551,4910442,4914333,4918224,4922115,4926006,4929897,4933788,4937679,4941570,4945461,4949352,4953243,4957134,4961025,4964916,4968807,4972698,4976589,4980480,4984371,4988262,4992153,4996044,4999935,5003826,5007717,5011608,5015499,5019390,5023281,5027172,5031063,5034954,5038845,5042736,5046627,5050518,5054409,5058300,5062191,5066082,5069973,5073864,5077755,5081646,5085537,5089428,5093319,5097210,5101101,5104992,5108883,5112774,5116665,5120556,5124447,5128338,5132229,5136120,5140011,5143902,5147793,5151684,5155575,5159466,5163357,5167248,5171139,5175030,5178921,5182812,5186703,5190594,5194485,5198376,5202267,5206158,5210049,5213940,5217831,5221722,5225613,5229504,5233395,5237286,5241177,5245068,5248959,5252850,5256741,5260632,5264523,5268414,5272305,5276196,5280087,5283978,5287869,5291760,5295651,5299542,5303433,5307324,5311215,5315106,5318997,5322888,5326779,5330670,5334561,5338452,5342343,5346234,5350125,5354016,5357907,5361798,5365689,5369580,5373471,5377362,5381253,5385144,5389035,5392926,5396817,5400708,5404599,5408490,5412381,5416272,5420163,5424054,5427945,5431836,5435727,5439618,5443509,5447400,5451291,5455182,5459073,5462964,5466855,5470746,5474637,5478528,5482419,5486310,5490201,5494092,5497983,5501874,5505765,5509656,5513547,5517438,5521329,5525220,5529111,5533002,5536893,5540784,5544675,5548566,5552457,5556348,5560239,5564130,5568021,5571912,5575803,5579694,5583585,5587476,5591367,5595258,5599149,5603040,5606931,5610822,5614713,5618604,5622495,5626386,5630277,5634168,5638059,5641950,5645841,5649732,5653623,5657514,5661405,5665296,5669187,5673078,5676969,5680860,5684751,5688642,5692533,5696424,5700315,5704206,5708097,5711988,5715879,5719770,5723661,5727552,5731443,5735334,5739225,5743116,5747007,5750898,5754789,5758680,5762571,5766462,5770353,5774244,5778135,5782026,5785917,5789808,5793699,5797590,5801481,5805372,5809263,5813154,5817045,5820936,5824827,5828718,5832609,5836500,5840391,5844282,5848173,5852064,5855955,5859846,5863737,5867628,5871519,5875410,5879301,5883192,5887083,5890974,5894865,5898756,5902647,5906538,5910429,5914320,5918211,5922102,5925993,5929884,5933775,5937666,5941557,5945448,5949339,5953230,5957121,5961012,5964903,5968794,5972685,5976576,5980467,5984358,5988249,5992140,5996031,5999922,6003813,6007704,6011595,6015486,6019377,6023268,6027159,6031050,6034941,6038832,6042723,6046614,6050505,6054396,6058287,6062178,6066069,6069960,6073851,6077742,6081633,6085524,6089415,6093306,6097197,6101088,6104979,6108870,6112761,6116652,6120543,6124434,6128325,6132216,6136107,6139998,6143889,6147780,6151671,6155562,6159453,6163344,6167235,6171126,6175017,6178908,6182799,6186690,6190581,6194472,6198363,6202254,6206145,6210036,6213927,6217818,6221709,6225600,6229491,6233382,6237273,6241164,6245055,6248946,6252837,6256728,6260619,6264510,6268401,6272292,6276183,6280074,6283965,6287856,6291747,6295638,6299529,6303420,6307311,6311202,6315093,6318984,6322875,6326766,6330657,6334548,6338439,6342330,6346221,6350112,6354003,6357894,6361785,6365676,6369567,6373458,6377349,6381240,6385131,6389022,6392913,6396804,6400695,6404586,6408477,6412368,6416259,6420150,6424041,6427932,6431823,6435714,6439605,6443496,6447387,6451278,6455169,6459060,6462951,6466842,6470733,6474624,6478515,6482406,6486297,6490188,6494079,6497970,6501861,6505752,6509643,6513534,6517425,6521316,6525207,6529098,6532989,6536880,6540771,6544662,6548553,6552444,6556335,6560226,6564117,6568008,6571899,6575790,6579681,6583572,6587463,6591354,6595245,6599136,6603027,6606918,6610809,6614700,6618591,6622482,6626373,6630264,6634155,6638046,6641937,6645828,6649719,6653610,6657501,6661392,6665283,6669174,6673065,6676956,6680847,6684738,6688629,6692520,6696411,6700302,6704193,6708084,6711975,6715866,6719757,6723648,6727539,6731430,6735321,6739212,6743103,6746994,6750885,6754776,6758667,6762558,6766449,6770340,6774231,6778122,6782013,6785904,6789795,6793686,6797577,6801468,6805359,6809250,6813141,6817032,6820923,6824814,6828705,6832596,6836487,6840378,6844269,6848160,6852051,6855942,6859833,6863724,6867615,6871506,6875397,6879288,6883179,6887070,6890961,6894852,6898743,6902634,6906525,6910416,6914307,6918198,6922089,6925980,6929871,6933762,6937653,6941544,6945435,6949326,6953217,6957108,6960999,6964890,6968781,6972672,6976563,6980454,6984345,6988236,6992127,6996018,6999909,7003800,7007691,7011582,7015473,7019364,7023255,7027146,7031037,7034928,7038819,7042710,7046601,7050492,7054383,7058274,7062165,7066056,7069947,7073838,7077729,7081620,7085511,7089402,7093293,7097184,7101075,7104966,7108857,7112748,7116639,7120530,7124421,7128312,7132203,7136094,7139985,7143876,7147767,7151658,7155549,7159440,7163331,7167222,7171113,7175004,7178895,7182786,7186677,7190568,7194459,7198350,7202241,7206132,7210023,7213914,7217805,7221696,7225587,7229478,7233369,7237260,7241151,7245042,7248933,7252824,7256715,7260606,7264497,7268388,7272279,7276170,7280061,7283952,7287843,7291734,7295625,7299516,7303407,7307298,7311189,7315080,7318971,7322862,7326753,7330644,7334535,7338426,7342317,7346208,7350099,7353990,7357881,7361772,7365663,7369554,7373445,7377336,7381227,7385118,7389009,7392900,7396791,7400682,7404573,7408464,7412355,7416246,7420137,7424028,7427919,7431810,7435701,7439592,7443483,7447374,7451265,7455156,7459047,7462938,7466829,7470720,7474611,7478502,7482393,7486284,7490175,7494066,7497957,7501848,7505739,7509630,7513521,7517412,7521303,7525194,7529085,7532976,7536867,7540758,7544649,7548540,7552431,7556322,7560213,7564104,7567995,7571886,7575777,7579668,7583559,7587450,7591341,7595232,7599123,7603014,7606905,7610796,7614687,7618578,7622469,7626360,7630251,7634142,7638033,7641924,7645815,7649706,7653597,7657488,7661379,7665270,7669161,7673052,7676943,7680834,7684725,7688616,7692507,7696398,7700289,7704180,7708071,7711962,7715853,7719744,7723635,7727526,7731417,7735308,7739199,7743090,7746981,7750872,7754763,7758654,7762545,7766436,7770327,7774218,7778109,7782000],"blockHashes":["0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9","0x6a5e5dd0c78e0a5f1e7dac39c11bd6c7e3ca6bccb2498aa27a8b41c9228a8dad","0x56e8d2e17c6e23f0a4a0675d7553623dd40f9a1de4fb6a7cbceb8252e8bc0fb6","0x2d382397412eadbbbf39f7886bdb6e5da994ead4e149d5c05b6eb23ab7c5e751","0xaf5759e9bc2f63dd342e1996c603cf9c76c43bd34aa524c0c7674cda469893a0","0xe92c7a3ec123cc5b82ebafcb81cdfd5d626ec84643d6a51ee9a8d158de5f9818","0x73af17bae45c632fc8caabb1b22cd8ee4c849f9838634ff933b9ead1b1501102","0x9e23c2b94f844681194af7025bad29f4e3430017c851556c4da8002fb22ccc14","0x1bfbde79a1b433b2da971ca4acf3ccd48a1f6320676df628f2be26cf42245670","0x13eef2769e1306c8b5ed55118888e43090a2796d181c1a724d777e45465a9539","0xe056293ff26cc6d9786cb2fbbb939b7f622e80d6c68561a4ffdaf725500b5282","0xb5cea9ced2a6a8e77d0f5d2b83350709b4c15a2f4aa9f96a689e6335b4057bf4","0x5d97ae64d3ab2b79c6a644c730060d37680b99bd6e0b9a6877cacd512430f3d1","0xe8d655116a06920f346b90141cf5c87b7adfcd0ef3ed3210f670450299221bef","0xe7c355f7dbfb2f5b488f451d64c73300dac6ada83679b84516cd0ff469358163","0xbde250922bb26abfd64386f0a07b26e358f062addfa372dee24db61e2c811683","0x26ff48db3e388e2f415eb07f62397c1931c8f9da69bfedca74309ab88feaa497","0x9045a2d05676e015b3b9ce80e15e039683b1d8f7cf488aab82239e4fdfa9ebdc","0xde7fe668300229b05e2f92b02ac6df08659dd11327e8b1fb0d583b172e08c328","0xb5840dd7603f2dd85481ddf2d7f425b41a66bb74e08770749dae3bbbfdc5267b","0xbb7d85fe04f101c85a4e41a1127be5297d7cff1de0e7dda6a08ae863f007039e","0xd38800a1eccead6b9e310353811a21db0b7a67cfd413234521ecbdc9fe16a795","0x517f4eb0e3bcc5f14509ee5558fb660b2f656189f3891161448d5a954baa9934","0x55415e34a9d3b2db48dede7aab36d2d0fd2c31d2df5f819b63ae1910dd853ec6","0x0e0dbe1f90c7491c3e2eb879c3e9fa45d316dfec0f95d8ffcdfe9fb78a146c15","0xe2066616bbac04eb54453e820b4f211a7816e0aa36ef2a1569a01a2dc307caa6","0x0ddf0475bf16edca3ae84f4a834f494a07564d9ac1b03d4390c5050f11866888","0xfa41fc223ac8391fdb8cc256beb5be2d60b379d47fcc0aa4e326fb0b8a68b2bd","0x806ebc642c35fd389ed352337c7a835fb833c4d73d6885d4cbf4cfa6b098c19d","0xdbbe5d201f91e4b8ef7224d7379809d1ab97ec6084eb9acd37ecb4b77d342e59","0x17e7a7c82f3725f85f6d135b5f018a4a1329db4dcd5c65446b25825492e6255c","0x79ee935a172fddcf92b5479aa56f5de7daeae2fa6de6d2288e2ed4d7d5754ee8","0x4dfe6ad112a51fae4c63a21d51cca1e03f323b8ddd780ea420acd203dd556c78","0x4a7be2ff8078bc5a718e2670c1d3868192858580bf7066bc109967ac23a4fd65","0x1752155050371d1c024c336f0d7e3a9c57b0908f61cf24f96961ee3804344d14","0x886ec8ff26260a27e89d3d1b7b3a476aef3f546c34ec70aa2d861257d210d074","0xde0ff170dbd6aaf5952940c1dc5c9647e62ebb6467027891499bbbf0d7060219","0x76b4f5a9183f454b969f3b1f70ba94ff941525b518037ce856df338ae7665590","0xe549cb2c97c4313ab8e890914c3d39eb7cc1f13176b89dc3627d24ea68269205","0xe3e1ac6b827df008979a2fc7f3a1d58e3855167f167968a8f55d26ec9d319d6e","0x71d490ce01fb6770912c6f7da92389444bd47324e65d7eaeb905abfaa085ede9","0xdf2ff5c50b2e8d97ee294dd62f5962bf77792e05492f5c63be5c8f10c887bbbf","0x0b8afe11e930782860eb7338b9cebbddcb4173c37ca08a404cac63b0987827eb","0xa6b64078e93bedd8f3f46d94806211b01a084f21af4a19ed5567fac9595e4e57","0x65296e86d5bf3dc314197abb08e35c78d632cc496215fc4a9c43f2b057a5a536","0x120dca2ede53ffcae454c00aaad1cbe81ec7700e4811fae7dd5cfd4b39968b7c","0x8db730bae43afcd4fe93c27c999d3080f0ae82a5393e6c7d0b12a7968f8e0e56","0x69757d54a02e1ff2dd7c529c61d5768e70c649d1b9b610429ddd6f568f7cd3da","0xdbe1dc11bb3696803603348a6f134ec8a8011a58631bd8b8fcfce33b9ab17b5f","0x5a6520c2d86fe5f27c8c53c0492ab1cc6a23f5fe994585c0edb79c7dd59bec8f","0x9a2c404e659a916b900404b248d775dbc778fee16887fe3a528907edfb9addf9","0x1fb56ca23210109f99795c10ed0864c2e74fee53523e46b9700e9d39123ff244","0x9ba63b539669ee596d34289040e8d6b7bddad437faf031af580266d03d89044b","0x11cd367646ff57c2e1c9093b8d9ffc37062746db0a1a753b1646235da94ed41c","0x32bf3478839397768b5c3a2544afe66f532292cba4a68faccb542b4199fdb746","0x7cd1a84e64f4bc0914c9beeb7aee4b4a0b971b835569b5d0020c96a00e3e8700","0x79def0ca19bd78eae862cc933ba1bd50340d9e1ce57cb42b4d8ad24f5983ca0d","0x873f0effd9354d5b315aafa061f3803ec084b3d636d7f1bae5ffe93d97febcc1","0x4b0baef9790b52886567893c955ddae33fd4902bd4c74014e894e199f1fe7f49","0x034944e08cfb684d571a01ebba0f0c74377aa41e547082d328785d5ff7867057","0xda330e5d73a73f49ca60f7b1976ca33586471d361c9224b863dbff0d4e01b3f7","0xc91a1850203aeb85cde0541294280dfefaf0934872a6261194883464ce92e235","0x8ad9dc186f616ffce7a40fbf839946dc90c77c06cdf00729c1ec6e3576ba165a","0x4c42d58fef7e3d1362637c18ef1f788863f75da743ead992b1fa985b327cc17d","0x4bd935f1659d1a567232c5d57549ac46b2a906a236aadb440c5136883aa19f5c","0x00c22ba65d79f9a397edb65fbab417dc6c9500ce4df4140b5bcd67ae7732f0dc","0x238900afc196efe78f5d8729a021d3dd848f5279a65feeaf880503588c0b8b42","0x1970f3dadb7a2fac21e6299668ab50fe32900229cffe785e086dd3bb0b7a294b","0x140797a5d35c4c88a92135124284f2614afed550959d849da16a1bd268bc993c","0x1f60f3d4162b854a3f143b45960ffb6aaf72433840f6a8ccadc3e7f3abee72b8","0x20e63d2b8e6aa4cd017e4341906d8152bbde189edcafd2c73f42c15aab21335f","0xbd7ee5796e49360eea060c3b264d044655de534e52a2c215b76d92ebe868692c","0xb48518ec7e94aa1001de8e0c7c2ff2da6cee21eed2812dd2b04a549119721d42","0xe18a937341267e60008b5b11f3aa3c5dc083bdc9eab4eb397ee02c4b0644b849","0x425844a7df04f298dff19cb8184d382e5c2f9250b035b027cc8bca7e4ecf96d2","0xf3445ebbec41a2bc88fb830b3b45dfe2f9516459c215e570a151cfa0083c6ddd","0xddb06c193b7c9212fccbe2113217177a4ac5195a913786966e60725c8174cd3b","0x4f89efb55de40b6eed5a09cb9aa3c32dbc9048137554519258daa2ccb2821265","0x5f6ed1f259409eef13e9477ee4e3156b996129d91bfa3b3827d2532af9153a1b","0x6da7034676cee23c94650c031b919009d19b9bfaaca5fd59fc3f6c6a3a1a2ab7","0x4001e2d09200e0a017d3f5258894a76a4e00744602a149febfd6cf46a93d54e7","0x9f507eafee4feaa2684335eb11d77e3383560fc6f04d2363799197bf8a4a0957","0x58808a22cf58c18ace2a29f9057ed023f269d9b0a05a9f575b03d54afc4d00d0","0x9bf4104e502b6a9ca5c561bf77a2a214d5a13971c223adc4ceae4bed99336289","0x5707d846dd1b368e9c6ea0e9238f7a8a8559d128461a1769e3da71bc7427b247","0xeeb857fb70beb5cb37903b48e2b278c94542318f37a27d0e3311b32aa2e47025","0x6b7ffb29c96c75672a46428b64cee8c12d12a82c721ec0f59f989bec8f6e0533","0x883745edc53a273e2f164918651c88ae6d799a344c5cdff6af9e1dacfa66e43a","0xd7d55627e46030db89f6a8a2203e3f493a992937ebc8be7afcabd5867530311b","0xb92b2a5b6515ed3e26b916fa52d145f226148ec78a0cc5f9a756627c37d20172","0x993aaaea3962f0c249b8530f119844f88fe06d7bc2fbebaffb964af1643a803f","0xbc42f890ece3b81c84a810f546f558e5a450fa94da6b8daf1bd560695e6c88b5","0x71f14bf26b7153c15e447a43c5c8ef6932c73fa17f6a78085f02a9424e8d61f8","0x436d24afe666f58f4c8735b5d3812bb07e9a539edf2566ff9f444d9390d88372","0x8f4785e042a380cdc51181aa2c7646a07df15810b7c292708afcab9992a3abf7","0x4473a556b89cb6bbaab52bb19a53ab1704e5a641327d3e10f532a514f66c74dd","0xbddb2c0b98976e0b70113b98f086a50b043eacc2f2fa3da76335940110f1cdf0","0x79a2e78c2dbb5575c6044d709c4b8cc81131949e9c8c3b37f8d4e6ded4870844","0x3c9647cdaa30be4983b881ac4f4f326fc50d3164ac0f22e13bb710501e709afb","0xdcf9325fd02b68742924fef19aa3b2cd9b53e1c038448be9821e42e84453e093","0x3b6fa6c322d02c6e0d9d0bdebfb9fccc03449140c0d22bbbc51d63e4b7d5ac39","0xc4d359148d43b8ac64d9c21cd3a63d33437a32f28440345eaaaa53143e265b1c","0x367b480f4fc578f00c7810b2f1848cc7deab299eead79ad07d6dc720c2e98057","0x3bd80bb33eb73858696a9c4086f2382a82f197decaeb4f1a693a15cc274dd308","0x648aeb6426dd26b7f89c442c12a7617bc06719e682f64d463bc6b3a1a92d5a42","0xbc2505545baae5bf12c4858364372418ec47f39163536dd3389911f17a25f636","0x91ecf357ac1fc4ef104fbb53b9cb601a285b9848154b41bb4433d3bcfd611b2f","0x5c0a6ee68beb9fa0120017bcb6b39fd6285bf72b527f0f44443ee5d530525d3c","0x826b735fc8526f1d4fc187e5d0571b317281350df721cd3d796a1b2351702453","0x1211a5ff02d633b0c28db49b099e992cd0c76542d4591bb99e30a4cc3c56493b","0x7c0bcaaa05a216247bd475511f02910f537c1e257042c055b387d5faa587089d","0x8927c2bade536ec9b22fe3773e105f3b402d693223b14a00ad8223c381546cdb","0x53b0185bd9421a9dee71c47c809097fb81f6cf3dd9132d60a435f294c1db8c3e","0xf14875d8237cbe37a097e7cd619acd03c5e8cf87c06195f477f39d5cde5200f5","0x67e0c2d744571c503f82dd5f2ed9684c2a1f54bf810185e48852be4a4c6d314e","0xbbeba71a8127da480a1fa1871d19187e9fbfc1ed9758c02378cd76cb471f5f98","0x700520299639ad6c9484bb8e1ae39076e7211ab7903786a920f83ac67db527ce","0x8ba1f231d3616ce01704a204ead270c230da7bec8d2b7ae2ce5e02a45c617943","0x7b889f5761abbb56967474d10272c8c9793f938db63f9a9f2a9bb6738fb3e2ee","0x2750001a703c2e723ca0209aa84cebf1c6cc0dbd79a2f40be2a6c6c32cacae07","0x8f2509d14761459510cf516c08917f73c9ed944ad40069abc514944d344b096e","0x764287b8c7baec1868c8765be5d440b03cf99fed0219a037665d7e8dbf1537a8","0xc75096fb3413bbb962dd8edb9ef3118cf7e0f3a6f4747032e5b834f6ec1cc804","0x0aff4f2d4999d363863725f02d75d7545096bd694acf87299e1a77bc74a31239","0x59b659f0c7901782893280b6ba2aca4b636ba085481727d055c1340852dd313b","0x7e13927f4f3bc91384507aca45c6d09a8eca93a9f7182e9a0df01cb7398cfd58","0x8d5a1b4d786b27c24435ca650fdaba2ed5599d3b75b7008ec233d68d3a3a29fc","0xcb440c940d5062e0a296df840624e477d51dccf7676015960e3e18426c103324","0x40dc376bfd55dd54f19084d7e47b3c6123ec3a7b3e4ef9f85d0269c0474af630","0xd2a7072e8f4e39e446541c8aa3db3ced9c234bb8e3de7d9d8d57703370d40e3a","0x02d46155b1c8aeeede3b81ff8352e2a7fc72361b99cc9d30c986f65dc116c08a","0x5f227cb0a932cb1dd055619d1f4b6a943365a5c3c8bd13ebc6ff85b4e3f31c92","0x201d9c9482deace6516cb4a618044c4c81267e64ff0067e66dd3389382b00b3e","0xc2567edd06689fb8459c6fe70ca17cc5705edf866332fa9a05fba3846e0fa664","0x1001d5f65797eebf149925a4e2c6f98cf6372336275671e52f35650de165e0f2","0x6241be737c66770c9257007122dbebd22dc6e71fc91a905672370c8eb6bf8218","0x8ca68babf6dd415ecdf3b7c29b0cd4795d8fa921889712104b241e529bf2b70b","0x8a0b0a5b165e08cdff4b70c681ccdcbcda689eadc7917f5c28d43403437d0808","0x94ea6dbcf12a8aa351a18919810be4b589c812d845c3ef88b825b089e926d194","0xdef5d2c7ad5bfad8ceab130f96f4ab99d8f10da43e70e58e3fa16a93999c1103","0x23e4692a52f6520c981882e362424387c38834ddcc85111fb7389dc3679991f7","0xd6eabf3c58c9e07795a21779877a04e04d395358b3e3a8f3da4eec999a2ad554","0x8e16075267e12f477ecc0fbc1828be6ae5052734fe60ad26db32f3a52e58851f","0x56e91d613dfa7d4837faf609abb5fd2b1fc9a3caf2379fdb2feb4f359979c704","0xda196fc68db2440a157f346118181f887ae9c2ea5bbcda37102b5ca6cb712e59","0x0d3aa7257661ee45f790b752768ccf369bcb6f56a8daa4a2240be71c8b1f1b46","0x1d2935a309c72210fb057b9c3aeedfdafbce50fe3517fc16d88dba2632d53090","0xba36ea1abb70ad25d79956b63c7fb6ea2262a7ae4a0ce91cc26f775178bea0bb","0x7cea26d63f6be94e5f49bf1a0248ead0ebe6a772b4796afd997907721eb62b56","0x4df90f989db438656b79fdfbaa1a380fae096fb0da1e19f60a9843ea746737bb","0xa89c0a9cfc64d042544fa0dcba1f3c58a17df49f9124dfcc636b32ea470b1392","0x9d1696103f950e32f0f9aff2058ccdde0abcc6c8fc5abac4377ceab8d5d48f31","0xd858aaeac8af4d8e7ca50ece585f0c7c36ee6eaca6d3d844f80675e77331bcde","0x667a185eca6cd05471c0e41f9e74677c79be094f59c5e343b9877cf71bb77747","0x6df33b838e2c61b52e401e92c54e82602b26cc08abc1cccc7caaea884e15782d","0x6bbcfec4ee86743e11dfdfe93c90e2a3445fcebfbef81af6f84c455f680da2b7","0x619471d7f269123819a2f15bb4d89a184317ccd8e52173c67c6bce6929f5f9ea","0xac1fbd1bb252f851cc43647712730426243ffc0bd81844eb87751adc86af098d","0x16968efa489ef6bdd4c62d7dfa680c0999b888f44488ecb51fa25a84c02bb20e","0xc4929583a1919fa270e237172c552f593c100950a91401b8ffca7bbc33f9eabb","0xd2cecb07be9cb55b0978f6a9a7c1bc440bb69fb4240907a321326080c2471cad","0x6d248460ce1e99f1bda08fbcaf6d8e9ceb51d9556b4a61a93680e9545e24a877","0x60d3e56e6b4c8db208e6d4990e0c5fd56a73145a2afb8e4ed51ab5bc61d4ac0e","0x966c7c86066323cce2c6bf9be449d5c5b9fe1af9512b79fa52acaaad945b49e0","0x01124d20810818bb36514536e8ab46f26ac0ef7484986bf140be2fc3ca7055e0","0x11439b846ae8ad895c0a950a178a0a79ed32dd1e524273c4483373f72b248545","0x6848cc3689f522e1ec2f51f2eed00c1eab423ff99f8d7f0a217c2124a4b41c1f","0x3975f76ae8ef48de1d881d85411b15ec94ae6a7be53841f87d40a676cff67fd1","0xe42019efcdb940f7aa01fcc5ccefe9f95daf8f1b25babf07047c391f489fc695","0x5704786a9faf3832c08878b0a8a3dd55bde755c6a5fb9eb1460cad4bcb5aa6ac","0x028cba061b9bf842853b450e754d21caebf9099a877484ac56c944d34c31b1de","0x20d4311f7c91241c80a9e1fd44cb447087847d82560b72390538d40e4f1e8286","0xd1ac6c8e490b5cdcd552fc38362fb6536770a8eee63bb3b64bcddda963061bc7","0x8add5c34f3206da12c0b69e68b62b87baa4410fb146c13feb47caaa24ac9d45a","0x126ce8533624a4c5632aa3ef5daeb23c86a3d0fd0e644450499f9cf0db3c02b2","0x979bbde0ab37d1125e950f3a7ccde72805006927a7a394b51d1e68df8c2fb95e","0xbb46ebb76c7b0e5df80d41bf3ae2237107c879eb1cd0f2d0bc3a0f251f5a051f","0xd3c8a1f1bb55d5ca1c590f2824ec697f6f18700e1fc5df92ba98184013955767","0x013734d7d1f2291980b25b7ea1fa65e7ed036bada40b83cd5ce0faecacb6fb78","0x2640965949027e9546851a57910c7b062e21c57dcccd0465828a29fdb6658051","0xe06f963cb2f60b88fe4f9e417b7b93099792eae1fae00762959d475e114dcb33","0x7684acd1fa4de858ef1ab6107506123bfc81d35acc41a68ddf4deb2916495483","0x3a51e4f26072ac7630346e6c9fdde9480ea22ceb7fe32fd8803805ad4236ea73","0xb371b7535b5b51472d39ce08fcd1b7ca8c8f73915161faf4d132603eae889afd","0x3f0286711c4f86af6087e4f3005b31e43e459630a67d5500617efc8e2cb7767f","0x14cc8911a76345e22df3444955627ce0682b38897d62c5a4f1c5cd20c2da4099","0x776495a7e611ceb3dd4425e4751183f9bc6b2bed664e4fae82dce26e6ed464f4","0x3e0b2d9b08d8d098d9993061d9645c9940e79c73165226db0b8ae37aef96a77e","0xc0e34cadaf37effb86a31b097ec58f0e62c57edfe593ece974257eb30b0ef594","0x58d55b01ac9f32a4ef8d530b143b72e25894676788f6e12e8d50e772201f6c6e","0x665fb686582662b1437806e17398651927d7e008d6ca728e9f1ac6c0e54bc1cc","0xa2d32660a1d172d4cbdbd28ba539d8fb463dac8894fc953d1cee08be4a2f9fc5","0xa5e6014af0736129b032be53044e078cc566ada92f62c00c28d0154ac02cc552","0x0c70c064ab050b12a18b04a5cfc2d94dc24d283e88326726886dfe7e435b1a02","0xfac573c3856ff1eb798dc148cfb36cf8fcb560a56850007177560492e91ffe0f","0x6c830d778e5951a583ed9374cebad4122b46029dd5df5320347af44b1bf78675","0xff67d0f68da263f41e4cec55016a78075a8aa9f438e9229095a8e63935459911","0x112d770a2f52b6a5ea0d6f875bde92b9218a4cf4eb9dc4f8be96bb3db678bf9b","0xa19da52388df6fe762d3699a899babdbeddb0e9106679e0c8b4daf321619fcdd","0xebcf1da883f09b9a1569fe1fc9f66e7c3cfed1c96ae4841e4ed2a6c54fa27f4d","0xfdf0e44a5506a9c3c065f7691679ef090853b5da505c5afec3b060b89f8b7fca","0x5ad9824e85d11dc53d087b56580610d5754141899cb0d0285ecc88b749ea44c1","0x8192bf4bbf25981301e6068a113ed11b122228ddc9369c0d3cc54464fc83a104","0xc425c7ab1b4a6d29172897b6b77b05b90d69dee77cb2819f263bcaca6442b81d","0xcf7e560cb9597662b752aeac49f06570205beb6c0a2f33f96a4ba38bf3c7eef6","0x948018c536775723818936d02f806e236fd1b9dd6f13160bb812c15d7ef6191b","0x362c21c45d3d73b2330accb92716ab361f5052232dc4e4c7902350f0230f53de","0x560f31d04b81e8b690aaba7849f389da8662c762ef525e8dcd1f87f9989941db","0x30f5139cf627c85b895cf4f93d3fcd76c63c98819aa94fdce90b5e850f8574c6","0xed965260eb46c04a7cf45aaadeab9212d43ec595d206ecc8d6117789f2c72152","0x12ada731b4f45feed524de0b57b3549f420c01d033ba1efefdcec8109e897f5f","0x50140e58f3cb4353f99108a6a68cd2f98a744e0538af0e12803858bc4c919b4d","0x1c387e8c849699b1484c09218ca9208e54c1a1a225e4e6db789dc4bc3d97c1b0","0x6bc1cb0215bf4342d46f1e4409f6ac6ce1334d7084ef514c3f1b8d8e8870da1a","0xda6760f3429a4b014a1248508cc9c04d6bb0c73a6834f050ca0ea0df4a8666ec","0x67d83477d84148802a5cbb4e87d032250a19bf2c8af0c6c72ba2e74dacc11880","0x3ceaa55b8d99cadbcb6992d541d97ec96ed36f7037b31b47a2acb8fb9e7c5f62","0x71363238cf161171e5bed3c2be1ba915846864d058fbcb1d51f009ddcf4b473e","0x8c42cae018cbb1fd78c41a9d7df36df7260d8ce495e6bc649e210b20deca4d0d","0x0119aa1a3dfaa73d0d81b264633b5690505c83c144faa10a75673c45b60d9011","0xcd895ac194dc7e2ac2317648d049fee9042efcd9d805ffd03a430c3cdd7cadb2","0x7016e1b54afc7561d5ba579ae8590dbed7e5dbd059a88bf4d925fd91e2dd5e85","0x0d29d86c167fa921040270c53002404d6222c324a441002ffa3b0ef67ca82087","0xb2ecd182535a35364c23468391afb5695e6a7cbb048c8a3f535d70d661351c68","0x5a39d70df6ac72425309a0849e36b1b60d41cf64952625d69578196ff16673fe","0x77aebc75680ce3c2a1d105680e649acef6ddb29263e3893ccb9b9b07f4c185c2","0x10cb29027f689b2f7d009ad800aa42cbe54a15afabc43634e4b31fc97a6d5ef0","0x14333ff8f7b749c3a56a4f1ff4057409058a15894b4196b4e16e05c8827ee07a","0x9ad686d1b6a51c45adb8e91b6de0128425d1714d50f54227cbede89c197ee098","0x50400138df624e9fdf460d8745e4a47da8e0d2bafce3f4d674d535f07509d7aa","0x66c7abad9226c1936fb7fdfacef6e0e7d12f5d3e12353c34c0ecac02f3bc2e31","0xbb3de8bc462a7b453cb665a80a976367009b2b6a30ed924b82c8a7dff5529456","0x662dd5fe975d1a226b092579a6673cc3d5f248a3e9df3714469243e29da2053e","0x718f8e5ce1730af7a51d1176ba0182e6268339aa0724fd4035e9cf899db516a6","0x676460da6a84bd9066cd770d8afbfcb663d589bb54dc74d68c8cead0426fc17b","0x9fbbc356f7e50476445a7a4121832d4f174616a4cd4f11a5249e87540aaef0d5","0x2f14b6ffab8a03a65ecb5aa00a4a1994f15a2bc1e70830228a0aa67415ca3f17","0x388d7215b91bbb87f979cf76114fc208ff347b338560684432d7cdfae2e09ed0","0x5b13f1477c8c83b9eb6e5fca863688008c75355419925109a4849a24362b8651","0x5afae975204396c5e5319314fce5056c2d1640f8ebd196e12773c6ab30c3a40e","0x031fdcae1d54f0e883aaec0d25a220e4bfd692d6e2ccb975c96001d795e5dcca","0x369fd1c543604b9e7dae3774966e9cdb2baf1b4b834605d02ed07ca3b514eb62","0x2c0e8bc0d8307ec65292f3af2623bf62cd18fb9f046fdae54c6e06f7516a373f","0x5914fdb106390b8134ebd279d4205c8e08868a7a19ff1cf672587249eaea80c6","0xfbe06627531d8a31d0163d3c8bac149dad55c2e1da1f342116e4be71d67d4156","0x487f8979d2d8a8cf14036af3ef3924acd75a0386436393e0f5f71fee40654f90","0x63b0a2af4cb46d416330a9712f816eba4b480b0965b4cc515976ddfacf065af3","0x3d4ac834247cdfbe607893c34c098adef5238ae4634ae0186f3386f60b0a1395","0x65a82cbc554002f71c3830e8af743197b9d3d9412ee1902cbf08ca3fd7ab266f","0xc4306c37cf5b270b00dd9deaae838780cd6ccfc984f6b2bcc5740dbfb1cc5d44","0x3eee8423992c1c334c67e81b2850f3698a93d0538294470d7b67af8d53a761a7","0xb8f367bb3d2283aad86f2364565c14595a5d768b99c7fdd992859b0e85a67008","0x98ba5f1d192bc92520f0c6b218003bf4519820463ada6f20b38c61188145cbef","0x3dbac0f5bda32179d87a490a63ed7b7407656d8fd76d97db02a7b187c4e99448","0x5565531485dbeb1e02fa6199e127b3ea25deacb55e9ca3fdaaa3f5926d33a96c","0x2a655cee69fd20ec4b2238f78ef44b0e223fa42c312892f8f0b0a01b917a300b","0xb374500ea46262e780f82b9c2fdedc6058890a1ee07c1b53005ca67ce58857ed","0x4864b213d5ec68dbdd34df6e4f8342d773e2edc3f2db569fa49b21bf6a542019","0x349934858aeffdcf52d4b62641da96e4ab33faeb3012bc877b80ad98b3984c05","0xba30c29028a946f97d01f14216f0d61b6e103d0fb57daecdd353fc1724d4f4e4","0x6caae42b54779cec6142f8dcdbd99a76bcc373b9bebd1a80c121458fc152c6d0","0xbcd832da509ada11f251cc954691af4bbf8bdc3484d9af4a71b46989849c93d3","0x6685db5539fb45047061ffcdc98395a65418f4a04dd86dd4a3d3a195336ed116","0x8a032aa7a0214937ab90392578b82f5b1979cac064ea0c2b129cfa93e841299a","0x824d3563e197b827691282034ea30692c4ae68ed27b0af4e3ff0f81cc99f66c7","0xdeeb01313f472dc9430eb878a01c658ac17a7222978058ff5d2a8f1fa4c4e8c9","0xee5b331f34fbc42eafa6255e76650311a37786fa8eea7359b3141632de37da41","0x04a732c9ef1f19ba18a63cebb130c51132067a15c10c43531e32045584b08eac","0x2b40549f6b010dcc785297ec32354bfefc8843b802ee5e7f766c77055d78d301","0xbbd5198048a6d7dd2bb281524361c60ab5e91614c4b78ef803c8d01463827d1d","0x2b23015dff3d6164ca20307079e5afe8e8115d3744b9b9fd9d01cf47d49401e8","0x428bff92019d2090f6fd82fb5a3e26bc65dcd82e14fb823cf89fc217b1f0f9ff","0xec5d90f74e5a1c79cdf91de11a0ed1ebacfdb1bdc832f91bd9d57f2d5622bc83","0x32ab1acc631a488c8219cabb479e6898b74e942006d3099a78bcd34933923822","0xf8b978f013abe6fb8ab72f46206f085b97e1613a49cf36ac0ef8a256365578d3","0x5fb61bc623b4aa5761158a3d3194e6f1b7a7fe4fdb595c2235f44ebf7a7c691f","0x305cca1f22c1bbc6a81823174b82b97a44fd9a840e55b9ce1a870c917bf45bda","0x6bfda2b7051c92f0878a4e7ffe8ce19e5f81bbb1070b5c58fdd4cd6b206294a5","0xd6c82fba897300d87974014f9ad9b9daf01c1531f15888cdab955c8ec8c92440","0x425b9b77ef4d2a34ca3cdd1e061e5c3b7c5dc2a4bc2f8a44172760aa725b46fd","0xdd13d663c9fee2c7d42e495a2eb8bc295cc2fd1fe7aaf110a1a54c8c0e5b9165","0x7a5a256f0147e5a985eedab0eebd11523b97510e34c27c9064a57b75cae64c79","0x79a7ddc60ef73ca0dc49969393fca667d259c286f5a12aa229130f249c5fe27d","0xcebab0d740566931e78ce66f045191ce86c0aec4f75125fb934d50ea88c3dca4","0xd1f189d6e29f8c599a407524741cbbaa72c6bdd89d9c1c9c5c321d4a39ea624b","0x79c99d217344979ff2757834b3818131bf4d159876f3cf5ed6994bea2f3ca682","0x951ea4f2ded810f3b9d32d8b51cf0e72cd4fcfd007bd029031f0c47e33330b25","0xdf4f04409bb79c52452cb0b829e56cb91d7934340aa029cf25bcb76285a60cd5","0x2596613b981dccb0f4544838793f38b1bfb1adc4966e49fcc308a2d07175de9c","0xab2a9b0d3bdd9778a512f88acf2ca7f550a06f7010bd4584bf01f53415a8d9e9","0x6d65b196a9d028597d257067dc7073c5d2e66aa52f329575810d063e2701e64f","0x812ca21085b182163965ddb94687f9255d5cebadfe3009eea220e8ce02206ebc","0x9b4e59097f83642d8a0a483b25282fb3089b9e4fb378cdac2d145316dceb3769","0xa35d4c8b68f4afc0c68ffaecd45a27d5a04bd6db3e8c9903fac1286f9bbb24ac","0x4eaac2ab90144f0973ec5dbc69443e875e5de90b17425429f9cc691251f477c1","0x5d3bcf54be5de80cffa5ebb0bb319f4d42e9328f37d1f9a1ab1aebb388ee096d","0x5d35eecb0ed80abdb81c0c880b87c2edb4d3b5f00d4cb76dba233451fcbd8c85","0x64bf1730fa0ae37dd892e80d14f6376b5709fdcf35733c3d987beaad43a7190f","0x12b6cf8558b1847df7fd64b52c3943bb62c702b79d057dde34c95e0ceda70065","0x9170b26d855231713538f63e5a3c834773c8d4dbc3cc5c3885bc82919a95bca4","0x398a2b81c68c04707a558ef91245a83c3639fe578081af9ee207070d8366d0c0","0x4f90d8056cc11d5128600f6ffaa5a75973b7dbbfa4eeb69e3828631bd11af6be","0x1a2b330431aaefbe450778c1f3103db6f29cee79312e79493ab25ea836c9d356","0x3840bfd2481ba197177b71282d04f50cfc406835dcbc2accafceab28e9e42589","0xadcbd62c045edd69662c4b70f87c7b9a8f3b0eb982fd222851f3ea4bb9f10e07","0x72ebfb13fcc6314151942d6455a784f34ddaab13b81923885e2931c2e545c146","0xde324c0646e90a379f92ab723d1f04583be64ca0445d806329f4dd2f148fc1ac","0x83796345347b1bd1f9e46f5987ddaaa19ade23a1f0f7871d2ef0780dc7115962","0x3b2669869e0286be42a93e899308aefc855d122cf68741b4370fdfc7128078ec","0x1bab72a71911a86a746cdd053908a597b62e4292aa641876344699e3410752d1","0xf7b41b54da3c6dc76a0fbff19a6fde5fedc91f2bd33571a66899ddaa08f66bb6","0xe199992deffd70e1f906bb3deef6614ce3e073c4682b1bebe2ee67c9a57d4212","0xd8ebb990249e481cdf86fe9a0634f92c845959557a02734e6b6ef3bd8473bdc7","0x724e307f1aec4b9d72297f92321fc6828d884e2fbdab0220f6198822cffb7c0f","0x693329a6bd6400529a439aab86fc1a92f78e532d167796e8d12b39f24717f778","0x6e7405c6edb25cefed7f58998f29a2a3db6d9ff5acd5b26da7c2b54657cd2840","0x45917e2591474001460cce5b9a64b2fdfcaabf85563d6147e589fcc8a8182d71","0x03164c47f3691469d75d63a9c467b590b88d319c76f261f66eea076901eccba8","0x4bb98eaff8d338fe6cf84e08e03a769109a9e487d576890a2a90431529310aea","0x81c7b6de2aa44c5dffeb4d877cb335289e7ad8d90ef66d62987e8118df2641b8","0xd6090c9912181b1bed171730bba424404663b0f28e52502c7d07ecce920939dd","0x73afd4f8ad15f38ed9e7ebbf2628fd655c7f7115b5f54ba54ca1b7ad4092a393","0x65cbda1229cf69403eb62fd596ea814a8f908f55eebf269da63c67b6b06c95c1","0x64bcf0de8490c3124d032f7112504b58a412bca5bb264d97f81727a9be2e8821","0xc4fb5c12879893a76db17ae700e3ecf0ac261588702c6cbb3741e0c9b4e25814","0xecdba627f3bca182424f81a1c777a5af58d8353477d17bd5ba023df2f72b28fa","0xafc639dab8d41e74b0d9d5551ae5ff5197a1182a823b945a3494126d7ace7a9b","0x426e1d330c4791575f857b284e9e3a42b65660f0b69d3fd0c6355d09f4a622d5","0x87d28e6caae6b1ca02cbbf6bb3a1e57f554e3f6366185cc8fbb67bf5af61b399","0xeb9687a33ad8a0cced4bfdcaf962361a279fb77a764a2f95e2b640b52bb606fb","0x4c14806c0e25b282fcb9b228caafe4f69bc3125b5f5bb60d00cbe925e8cebd49","0x896136cf939c164c9f3112ceba37958dd32eff27c6dd1b2340f271c640cb2889","0xd3588fcbd30c3e1c428a31309aacaeb9ffae38ce2d3414fb41e50f33b00546ac","0xe04f1d4ffeadaa0c73b3e39e0a71ab7b85b2cb3e2596a525b13480333221e0ea","0x3144311751c9d4e995cb65a188354a200115f42fc86cc751de4a718cfd513562","0xc23fac7c5393376321b040b431ab6f67e560e8c2dc1115571848ca8a0772fd4b","0xf83f90dd30a333486eb30f0d0728ee4e1916e6a0413de0d2a3084391afd41ffe","0x5e78cccb340abdd2b0e5cf3841d20c58b8d60348d52b74a848fb88aa4e910da7","0x67bbb6151d2da8494cd93268a44772ac0a76172c94a21010796cab9a3f353352","0xefbb43cd011be9be1ee95c3a0eccee25fc3b758788b4730816d4ca5b6994e400","0xa36983fbffb6a6ba0e8f4f4650bfc0f4cda0569573fe7205e22c4a1419211b57","0xca28e768daf91e5db7ad0403c301212632af2ea40f4321a967ab9e7014f7ec8c","0xdc1911374f25381c83a037187fd1561240079bc1812694c7647865fab09edc3c","0x1c0cdceaa79e80728314bf631aaf2f9bce2ccd0e1e49af4fc94eb17828f3124e","0xfbaf2a771552199dc09b6e1cbb84c7d1833e07519f43a5b5af03636b38fd6daf","0x290c6589520dcecac8ba4a14dbc5db1fd417cac3bf40cca6afe77dd3a2dc1779","0x4ceb5c36f2614ca691dc9e68d9c62af410b842bfa80abc3caaa7ed088c895fc1","0x91d75195c299297794ec0e18417ce10b6c023a62ffb591655c739f5f349653b3","0x45ef88ccb488f23579a2b6b47a6428f4a393931670e80a55d9de6f34f0dd570c","0x3261e5f0b3d19edd8e9339312625b46bd2b21e767eeadacd971bd52678f1e6be","0x1e85bab561329ac239276537f9a2455936936ee1f2c7ddc843dcdc992dcceb9c","0x51d246c8139dfa442db2c4ccb12b7f4497c8ef8dcc2cc4e770e4ad70d5a4cd5f","0x6b1d33313a4136a89e7d9a48b886eb7b90f075dbfd68f0c93eccb951204fe7a9","0x9241997fac28a96ce8cdd5abef33c2fe8d6890b66529505f34fd2a6b2c763c3e","0x3a714fe5540716ba798468841e83be3080ec070b88031a4c717905a832f27c4e","0x4f3e27551f3507b1fa9db9ae4c5bb222149c226b5ff406c8eed3fa3f109cd555","0xc0fbac7afb11c099c42b40a53ec977c615af0426d0d454dc5c3e444f82bb6e0f","0x31fe3d608dccc0f005e575769f8050c4eaeae7477618053afbb78fc5630f4615","0xbfef673d6ac39978c5a3d9a7af4aa03ab1a7cc411314f77586845138f310bdce","0xd898a4b761480be69a89140605fdf73c5b91b3d4e61443ed46af3640182ac048","0xf0cd3224893b6856872334ba490ffcbd2b9796dcc214a568368c5800ce7cdad6","0xe253de057c0a8b9d2c753870676b33a4dff557b64d1ca581ef39f42b7221a8e5","0xb4830617cb5b2a846926017ac5a3444f75e69726d09f956f9c07c4d877461a98","0xe9bdce69f6a9fc0b19fee170831e5b36846a888495796b7b12c39666a80d080d","0x01b30d6ec5fa429a22e5d5f91727edbe51dd27d4846415e92ca0e29c6da9aaa6","0x2c0216c4bef33843190d82b8b82b43105e9bd1497c2c427179dc3886932cbf36","0xb837db84407cda7f4d6767461ea89ad4825d130cf592a54ed46b60e95c1e380b","0xee693532dd3f0a82d82f3cfd85acd74dba89a924d08c5a58639af0682a08921b","0xc6c5d717df097aea180ba824c46a8ea293bf7255f25d0ca663a35571dc67ec8a","0xc1b11360994bdea61c5c581a4dd3941a949cc58f661dad3d6e02b7a18a531f96","0x762b7f1724c5891c18a6853a27a3af9664e06885687c5b510c7562e5af41d4b0","0xf44da8eef7d30883d16c6aaf14e918cfbcd16ebc8fe0e47da7353887b5eb7e0f","0x93f95d594f97eb6a11f363ab5bd32bfe49a84a519e26fa8618659b0747da9b71","0x0aa409c8a70cd0bce3f37320a1b9983cf0af18e2c982996b0a66c35dfd2b6b08","0x1ed43bbaead24cd522bd4c0e05e1e14d04efe9ce4cdabefd8eba705638855f67","0x31f8aa44ad8b3b4e493709c0a85c3c85cca9a149a7a47762272be63e16ad7a61","0xdd9d0dae82f7e0871f23e27ea193c143c778fd0208266e10d04df23dff438df0","0x14b703cab02942512dcc376d907487fdccc667e661d14b5b2054998c9cc58e30","0x93601fea07bb6e98cc2aab5d47f34310dc8cfbbcccb61aaab8e6b29c5f774669","0x848ea26492df7e6284e2c588876cf424b93d9f5f566d0c55e399263d0dfc32e5","0x1af5beb9f8cc089107b767dced72667322fb603cb3d07d5558c1928a83733042","0x67b86b3a6d38b62b70fd0e1f6939fc13eae82f9d6cdf22272b5821d6983d9038","0x5c18d158000ba7ea8e48b5db5415437f14c4e9f1c48cf977e1592ed8742d3d63","0x3a67f3b64e16076c6d8e1177d24e4cec5ea90dd1478b5b0bebfa23a80f3caad6","0x7e350a333c954a3f793f78e3745a78b8d7a59f8ebddba769106dcf6654c9bb4b","0x1880211d1ea9ed32f557ad7906a2dad0be1842650a22ae8837b2ee0cd7f8bae9","0x913faf6cd341ef052e7a0a93058e0f0b572336226bcc266375ecce34182a7df4","0x9b20b9902904d2759210dcf5acbdf881bea9122066ffb0c0354e4c4d43d0061c","0x4de8380642a126a45e32ed06aef5f6cf29bc14922170ac5f03d0692f5bc8f631","0x5e0eddcbd95d939dbf5e49048481ce33ee93a2883778eba4cd00b6ab9b819d9e","0x0f28be79a4728ee05053d7de1144580eb772b012d7ab1821e6f3b570d4ec9535","0xe22352fb1b746132a5c39b6ecc01071eba287a5287e8ef2ce34591f99beabdef","0xe33dc9c58ed1431bebc658666463cea74365f3275f9fbe4ff51224901ae8a4d6","0x32588057ca0ba7100d56f3a08dfd0f3a9be78aed30c56e2c370575fe4aba46b0","0xd1b6160e4c7e1314dfa027121bd665710b6bc362d952779a4c2d77029da0985d","0x1dbd0d3a6f98e0425cb205b4aed2eec23b7ed3fa9fddd180adf0fd9d385a46b8","0x228c4995cf49701b9d4af4c18835d28f98aa3b8dac0bbea839d4965de972018f","0x0ab8d41a3e665e429624e963f4fa8ba0c03225f1bafd5a7a5a9b0fbcc179ea35","0xe1a34a0ee6970ed610d705b9fad300e9a73ac2017ba7d9412daff38bed590fb5","0x2b8285912a3dc4a8bdedec980a2a601c81eec4974e983f4e7512acc865cd8fe0","0x40ab4967736fe2f6f22c1a0f39cb7f413f83e9aa8080b3f5c6633310aeb3e8dc","0xe4038c568d80ba1cb9bb66dfffc05cac50b67149454e9ccf6d622bf3fb35cad1","0x534654910e663c9b010f768a5cea9c52f28c69be4b52597fc6188d9ee9ad5f44","0x012e32643f23c20c20f7356efb3856f6193e0f6e4fe8fec54df3f069649d2f3d","0x88277661a7195186b27494c9b7a0ce8de659fe5ca626c2486d30a5623e8cb2fa","0x1773e5239ab2bb02a8d80abd7250a82e7578ae0f183136159a84a774c7e5a397","0xb0f84c374ff513077f723e903a8c14ac0b2d101e10ac974e55e3dc444afb2e75","0x7265ae6b329e7ffffbb916954f624f7d3f3f22935bd08a4e818215da37bc4ef7","0xb7518a204a715520cb1b170d084e07906b58a9669bcdf8e52266b3952f788f06","0x7ccb01ff0749d990e12591a67d89395271e8c92464009b4bf66a2247f5945e83","0x92e42e3192f11a57643f56e2015651be05c7bed62fd02dd223a7a2f895d9325b","0xc18142d48b9370d0ee63d52f467acf167d14bde1a9a7edb706a9382c284f0c1c","0x9d00181ad7bd3d8b3d205e88e26a27802f6101cad456cdbaab6fd068d2590f40","0x391364b01aa87969f813c814503e355ee9010a4a7ad7e2deae7034a4f15028e1","0x945914a561b7dd53941099a96640f2e95127d29dd66a15190811a4ceba7803c2","0x3f8b20f86ec83c128cffa235bc35a0a4cd2aa8f3cfd3f486aa299da4ab756a8b","0x09c7e4266757fb0a82c22d63487ddcb936a63dbaafbe09824af9455e79ae373b","0x2ce86e7f13b59d572fa4d005138c34b0d9ab64ae731bd395b73193a74098566e","0x70546dcfd93172f621661f33607e230c7af4b1cafa306c640133f6b397e6ebfb","0x88d872b8a0039ef776a3ad839d4e36eef6f344394168c116916a31407a338b22","0x343f2b9e6eb1785910ef5d1991524c6e3f228eacb8a49960e13c406e78a61cca","0xcd6cf5da08b1b016dc14365ce59096afd8e49f0cc64478be7934f4a1dc7c0956","0xfbe05c2b05ee00ef7d11a74d7f153c24acf75faaa54ac64f93e432ace4d38c23","0x2a3e67901236fd57b990f2f876f6b33262dd4e77f83dcc05dbadc0ffa68ffd54","0xba31966f845491d51d3df4f685af22c7cfbf5725023b3870f3dcd9aaa3dd8707","0xe5099bd9f536f668756f770d20bd05f0182e4e19c1c9b561869754fca97cd277","0x1fa85cdcfbef02bb2457036d867419bd24299aaec719d022f65628acc0c7572e","0x6d286da0fb81627d8e5a34178a504497b3fc716a7599f9ecaf49cf921b3f1b92","0x64e77dec6a6ad44beebeed0fde054ce42566b562c137d615ebfdc24f38d5d27c","0xd0d62bb8dced36fa2fd85357e424da48d1b7b8c9ad8bb758f933218b1f7d2ba9","0xf01d46f6f9ef12587243aca92bc59ce04bd6532c318e83fcd32ac9a1da56f077","0xd004e6b412785450d3878b9fe17fdbf758192bebd45395a845397c0b3deb2763","0xaf04872a74f75eb28a42e6248eb1338e6ddb6aef8f550106c55a604fd29e7ed2","0xe5a2013b81ceccf2dac52d7f3a5d9b278609ee9852ca350f9866f580607bfe6e","0x7f08f54c36c3c8a73b8c0511b206c9cca5ebb99c2c27285e537fb22d53f9a0e6","0x04faadf65372f3cac9ae9fd8b4f25735a3028b272d51accd36b46db716124605","0x7155fded10d57c0d03be868ecd2a95135e613967c391a279bf2dfdf44ee83b2e","0xceac0864cb6199b451a7a81c17ee12348acbe19b92f80dd3161d6058eca890f2","0xfb65a17a2925cd88203b49e125d51f99d833a1aad0257de087be9dd84b0f8991","0x2b290eec7d5e81f09df32f3d834ae7fb0ce634c336c1fd82f2a50bd373d6f108","0x5cb5c8a1d132a180b8c7fd2c13f1ca20129b9eda7996bc6f83c14feb34ca82d7","0x36c50531109bea5ea5ff182850404f99a67554278da13e6dbc1067f559c71690","0xe4c3344a1aa39741418e22a4da0e972938fc20d83bec39068350adf3a512e93b","0xbbb33f926f23fcb6bf0f1f5d3b61ef38a245e25703e3fa6200a0f450598eaeda","0xf5a87fb645947dcc44a82437a54aa9653106b22a425c7ddb0742a86f3f2de344","0x64003a32f326ec25afaa947e9a07e71d456405ac1803a6f0ff624f7a055700d7","0x3ff2a2e3b6b4f76d12f1fef6f1d4f2fa0d66890e195112861e48a3547761177a","0x830caee0cb6fbe4492a5175caa95053b6e96c5ee2b79082df396d986736ad88c","0xf6d2599d2d7ab38885a4c34f51f0a85c5035844b562a6b72dc4b268946d0405f","0x732d01147dae3b590a5016d8345e70af8c8806f6a02cf0a5ffc4bfc9da2d3371","0xb02828a9bf8f535181439484e927ea28dd635ba6e14d6cbb11c2a578d4bc4860","0xbedf90ce1fca0952a35d13a029e9fc2ae41ac66556a9894ad4414ba64272a640","0x493c56bab9f7808f000ec0931b3e1331f095f8d0cde5ea5fdb9db4701d54a807","0xac23a8ede0acfb044a34bbd839315413145e5ecd3f3c21b68faa05a6bfafa2a9","0xca287c64eb9659aa21e760e659a60ff03406b28584fe843f097c991821ad67a3","0x8603bc20cbdc6fba4b8447949e66b8677ad51b1d6a3938b11a81fce212f5de2f","0x452b281aa082a786d75203a24b02cbc07a3d24c8f024ad699cf5d6462630fa57","0x4e250e3a78c4f73ed30e903a594aa042ef144b9a86dca256933b49328aec5d16","0x42a3006c19a60a6c7e19690a218dcf010d76a4bcede99f46b6a6d4d553cbd127","0xc720579d19c209db1b0d2e2ca2e7b3b7e29a66d33e18dc9dd0075eb2960529fe","0x3612371fc7110b7c2af3a32bcbb940544d5e4a64a964da74711d0335e946b5e2","0xd9abd66e121ca28c91d77ca55d2b3ac622540b7a21fc759dc143791a36978315","0x4259837a86d33c3142b644a6688dda4baf34d40d08efb543ebd53f00e55e6b88","0x934c1e1961010583cfdd39d836c37d0364196955c4a519ddd0f5c0c3208c831b","0x069b724d1ca254f45afd23934fdcd49d91be9c831bb1ee53268dc82f617f521f","0x6a35d944b0f6ba11c0cb03307c3f5b868a851996321de2d255a4ea54dda30a0a","0x22d5f8f0164aae4fffae159391fd5363942cefe40e3fbb7819ce22b13e3c4411","0x7033c02f270045dbb4344230a7acbce91a6277de314582e3bc3b1d43450a9b77","0x446a114212576cb151ac23a352fb647055a30c249a73f0e996340e109508d290","0xdc7fba6830f7398424f3ec0d069e6a68680e242bd9463e77e49c712f8f7effca","0xcbe0f272727a3beb466fd85606f4220c30a306fe0c658d53d67fa0b2481c8ecb","0x0a976c7e706f49be6ccc4ad1ea1c5263e3a3b3c4c52cd0140604915afc28d698","0x9ca899c143847c4919e22b3c3e5fcac46a96282404d2f9b53f2d50170d288877","0x66f1284fdd42de777c321eac9248564dda90b5a11c4fec608f7e028b89b70534","0xf79a37bc3605d7a38f46235e98007ade4c93c2d0ee4f9553b0e43e44f5c56473","0x20cb57f2c1cef9cd5be89a8c1d4ce613e898822aa0920bf5ca8288feaca84476","0x68b1d6c519011ffb40487455e7b417fdf075ce6443f3fb32b40487a025c32797","0xd4195d22ddb59554662cb43cbb85e522cefb039a0cfd5228019e42973c337a3a","0x4eb0e246b256572b5a4cee6134b97ef7cc268a278cb5f2641903f583df5f9837","0x68d7e23f1d8d167627862c361bc37e49f4990e936b6c4c1c884d69e511aecd81","0xbfbdd65025b500e8536b21c9d086d523084e6141011143ac79787022c74e6b25","0xaab9f4a485405a3ac4989687d92a0e07ea155b4b6e2a0f5783b0515a4ceceb89","0x9b935101f1bc9189bd0832d7d6d7bc8d220d13c891559264fa0300fbf4671540","0x0b4b1490017575c051356b1af9595bd55204fdd436467e995d490d1efa9af0de","0x3f96c24fb6d1752302cd812125fd73329874d18db15da837cda11e6944b325f3","0x7a03363cd86c306f6b650a00598a01bf350344305b81c17894f4c0388782200a","0xa2164a927c1b13d4c8036a82760d72751310af261875a8fff8e9476edec984d9","0x2c02e97b1cea0b910c07b4956243d5bcf54b52e0523313b5c7efbbc52fee26df","0xd1736801dc2c5dbd1200d8a68298bb53593f54f5299e45630dddf1c66e039104","0xb5badc31d9870393ffd4b97d748a0dbf78616e5dad55a188aafe04349964084a","0x7fa73be18dda5cb9f91db888d7753c0c9bc77f2cac2b8ce3fbf15bc2bfb76a61","0xbae30caad0bc3dfcac91d6ca9e3e7cee4790d9cf92d3cbe8d2cec4605caa2eb9","0xe03e901c32500fd4c829e890f60e82f2b6d40a44db7328f645eaedb1c3ea0ae7","0x8225ecd96fce1dd5accc0ede3b23d967926d33567d4c330db81e63295b439045","0x359bc008698521374345bbf51b9568ad1fd8cd50353409af51ba488b83292d20","0xd63626e5cb17fdca709133295fb92cfc30607431e8013f4b278fde959e293142","0x74c79bbbe1812fccfc0bd494ec65b19f777d2b2eb6f2c5c7f74cf90436be7d22","0x63e6cab6fcdbbdbcaef555b734da22e1e5e0d690a253bb9fd8723f12d84515fa","0xc025cc768c9a938ddd0f9abfca97e6bd046ae0648bdd97b52bb9471caafdfb8a","0xec84fc074f8df011ab566743d20358d033a579208acd63b9488b639eeb569d40","0x4bb6e1c090591979eec5ea2a1675171fc6b1ca31a27e36f55fd01ba93cae1641","0xbdcb929d8ece3c768b2ee506e733a25f23523f023d2bf753115d39e77688a5d5","0x00451214c93f11d0e6a0438fc9fdfacd56209ce7da19080aa9963b8a1cf8b081","0x2027c65c78b3aff09c35d7a118b07da8d6638d5a52498b40d37cb1bd994f46d2","0x233a78f482b1fc2954e06f37b045f073d4adf1ce6b81dc3e58bcd5fc5d9e7c71","0x162744e6ac92d36bac8ef4aab59cf96358cdf0f10d87478ec75e437e89c4f637","0x90c09ca9bc0db733dbd323d81636eeee506819f3d087a8ec7123f926d04ede87","0x4287addd1274f6be8e9d70ad3e57a23ae34e6f54f66571e0d39dcc1cc6db3336","0xa1e10359285ca8b468b9eaa40ed270b3437524e20bf21a145e68e7b2298017aa","0x13f7dc5b8ad7aea997ac0fcf542527f7949fb84c6630ccbfb4ad8a67202b1f3f","0x9e9597e2a51e18329b7850fd045fe1408b5346520ed77d8f6cf47b21fabe6d96","0x5d70da731375bdd1505f6cdac4df00368810d136117eb2570013e1cf2443d34a","0xe573f147f40f176a76cc922523c3f24662bf36f12767967426d435aebf043a39","0xb1149eda867aa293637fae3b0b8139e5092a7fbb1a6d24f0f44809c770fe72bf","0xe4097d7cf06deb6887e227e610afdfb016049a235593d7df6fb637b2eb3bcaf7","0x3c615cc9246be083c9228fae5063b728a215a9d85864fcc7f07385e7835a95e6","0xa278f9410e2b5fb9608f2359ed13053bfc7e2ced555cfe11776d1b6931dd1695","0x471fc146d2c670caaab91b7b1665731f45ec58bc9352bbba34e7a7983e34d459","0x4bf0e9d8bd15c48c6a542bc170ac28f28038afa57752b5cd012cd28de5f3334c","0x8cf8260af653efa2c98f5c0f935015e5a715fcb32143d306f6d2fbd2f507b46e","0x5884d65b0c43db9bcf3d530e987b03ba9c68d58317abae2b33ade04b2c2a6625","0x5beef99bb0924c4e892ab23bc8ef337415944b5b571439cd7bf1118721c42675","0xe2cc286c5b69b4b6497b4eb90e204ee921532ed82e1963d75a3a9756f2fd5c73","0x58cee24ea79de5f1bb917b3503660b0489357378e8584cd2a5e04bc0c29b7e8a","0x2c082892e308753588ceb4375fc12fb54b09e6e04e07f701c1fc91d336e5ae1c","0xcaaf04ca04eb06717898096c8baf1648aef7ba4d678ee6b32bad363a83fb19de","0x94aad413afbcdbbf57ff6f073e966c9e5b58b8b9ff247c20fc8216fa385b7b9a","0xf2d39daf851a1d0a79d2cbf227784211cce51f659f49e492e1697ef0d7074af4","0x4e282720c634ffcd7b56da0f8a54e4c33cffaeeb19baef787a006d71e369ea90","0x25bb92949de23132e854d298ed56033447ce3522bdc834a145361a1026007bfa","0x53648f4fb4fad6b048fd159d3f2643dae7d262b5224ce36b37086a88f2e7460a","0x2fd1ce784f112d45913205ba66510a2c39f7c8c11b48baa6efca7e2e54bf2ee4","0xbbd63dd567c0c89a43b49945fa6093ee7181b3c761b10aad6c3996d82ca6da5d","0xe116745f7c20ac1fed91b113e859fafb10ab9d4f02bd958dcd2543fec7a554f7","0x2947be7cf85b03517daa1ae20e8683b3c64c4a48bad8ca5b56c362a8a4a07b50","0x9ae7d491d62e835826a1b2f9cf938fbb70abf7e45dfecf0f849812b9347c92da","0x127863f69837a6ad0b542211f7ad938536a229232c176f0e49b7c2f01aba5fa5","0x69df2076170ab86228464fb719b464ace318fad5f68630e2e0d6cba3f733b3ca","0xf26aee559b7c2fc5027c4875e60eef91abbf80200fb18de4652701be31106211","0xf24a1e568f9b2077364ca88ac2788a844397b982b3c93cc2e1965caa95099a7b","0x2af363b3f4bea09119b42c7e0e93f4778da65a1a946e97ff7890019a0a8f80da","0x39d814da6f76aa7b44e2511357a0349c8dab3f4d5bb2b1c6db51ce4746958a43","0xb536e76078a9754a00737c46f388a0dc3459e34a928617832888b49e65dc7259","0xa72a685ba9a653431b6b2ee883a9d114f1107f000d01956d45cf81877592470b","0x6c959ebaf649c7e030fdc22717103fdba0cbdbfcc15af975de8a97615e7f2764","0x95c218be1bc88d314189d0f387498091e75cf67b351a9fab1173cd6d3c725dfd","0x6b1d6671e0be263a78e3f485d1dd17a30625623152371f322bf09aa6295ac21d","0xe13d7ca0047c806848e2153cc06466aae42b3bd94fba7fdf52dfb1571247a76a","0x63e724e121f35825a3532cf620e0aaa311e1d26bc8464f2e94438bf329b853fc","0x2d9436dd2d9b86613ae87abed29852f82f8e3f1261e6ad73e9f0c5eb8c04aed8","0xee48a90c694023dd758b37822c001cc6cee7712381f554f4e6d41ca03dc8ce73","0x0017401ba37434e4f6e39ddd2bc7fe8f664fc815514721e8e4665bce7bf24d19","0x88e7d1d3fba32691d12596cab3dea635371f7fcb7b7bd357c12a62c1c46dec12","0xe36d54aec1356300ca653f89457cdf79c08a9f8ca1cc58714f89a00b8131b7bd","0x2cd05e5f468e7b31fe8bdadb793fe3ff5c25c12227a43cff6e765af2c9b0e889","0xbd1f39ca368fa47c3b8fac65249e4cec2da5fdd391a6fb025d145c93fe7d9f59","0xbc113e0e1562e5add24d28ddefe1021c21f5f047221148849c89e8406ce7253d","0x2ed764fc49446b961d5f6d5da681ddc635c2ec0640353ed0bf88e1fbde8f7b8e","0xe51b91dc0d5ff17a36a14fb505c4ca7dd078ddfa616b124e4f5033c0902987db","0xd2021f3c67ee22ec148af728e62d12d8f3e833b480b38e2f731a7e7c08090f8a","0x46cafffa0c4fc127da1c6a132d010ccb36cc2586e755d2ecfac91e0688fea12b","0x2fa78aee361a93c223e12dbe3c57bdc24ab0969bcfdda654290ded3504118e2e","0x08ea6880d7e3b859a719d5c3966d8691189e257212ff17eaef624631a4b8e087","0x3c4752af1a5eaee495f830d7d40a57367b24988d61e920b76d64666280d9e7d2","0x75fd73684dd6f2afc49c2628d99a434a7ef8d982222799f764aa27680f94e7f4","0xb1fb8ce0895b3a9e46f49f8c6caf229625a430fd5ab7f1c48541688aea5e6efc","0xe56299e62ad7c6fb5e37284d2a29186f761ef64caf5a1b69093b52a3d2417ad0","0xefc63266b5a58192a90ab2b5c69baa99159ad5fee7033834cf90dac365b4a4fe","0x4b747b43399001781907b655c5800562591155a435857bbc4c2f6186f3f52002","0x58268028fadc53b60a10760dd847396ed9ad23aece53180e746df97477275b6a","0x0f3e2f46a163f00f169098d5b5b6b7e56374ee5df3088f4421fddc01cd528492","0x5dbd028788186ddc00d76fe68286b02418b2b791ee89b1fa32afe850766018a1","0x9f7c9c5f886612b9e0e2cfbd9f5003dbd6107876b65ead39a88a68a0e4e99eb1","0x6badac63c38be0da93e4d8040bf6ef83a406b7d8927526f4fa49a28dc6849556","0x079126a5fb75208fc264fe9823b009c784853b50270b4ab0b168d77e8c80554b","0x5a9ee8081c88cd75d662cb68bfe0cd5dcd50c7302ef6a9394700fee240510445","0x370e0976f862fd8a0fdb50aab4928dbca11782b29d55439580b5d5b92d608403","0xd49a5ed13b7d165c1cf4a3b3c59a90be7481045cb12760d4476156efdbb9329e","0xb018c416e095acf0c0a5b22f84003034402e2ff5c4198ef2cac638bd2fd975c9","0x49ef2bbe98f782d069438ae85f1a32da12c513ae3e24e2c0c117400ac1056438","0x6ef65ae36749a0c164b44bddc6a47fd7cb5041821b29a00b66acf8428da162fb","0x3eff008adf1013c391940c2cd42c606405c71c2bebacfc42ee7229da930f0082","0xeb9d0fea8720d6f8da2b7d84550441531e28d33195e106e4dfb6bf212def1e3d","0xd83c1c9aac6c81fb3b7a68e3aa89f537826f9daab828fb78646eec50d7c2e04b","0x049f0469d10b71b5990e1b8fc725acabd481c6c47b1a63c6b9849fcf6327a163","0x1d92741bf530cdc67d6daa9505cc9c6b618b7736cd7b8fa88aad6be05a5f3bf7","0x510332170b28137e7023fcb96c7d1592f73b6189858109764340f4ed3ea08a5d","0xf7092af93b4f0345d4b4e160ea8464a5241e99d1bb57be3195fb586d4fc7dbde","0x18e37b4595f6772e422d2c0658cdae5325a1d8221feb0ecb42ea9495131f3079","0xda85931c2337bc40b62b1964757b13abdbcad01765becaaee00ac180edd37222","0x7f517dc2e0cf520c3f08964436acedaa7976ea50733a352584b368a79d6914cd","0xe2b2df9db3c3379d145cf0cc8c589ea99d21909360dba161440440b9d83e8372","0x4f7557bc9765ca4d4192d240579f1f46a3a6e69a1f267fde041763c04354937c","0xd4b44ada44046b287b43db27c531dc5f62230889ce8c111c67ee27c98bb030ce","0x0bcda1f63542c486637ffdc45aa44ee248892621c155648fc84252b847fe7ef5","0xc6aa8cec743230fa452d86dc61829cb7999d1cbc6aff5019e9a764a80bd534af","0x70d648713237daf25c23781c9071f77b96e3a9d415cef0666d33f796ba75451e","0x0fce2ce2259b052b4974e84fc595e44e19fe0bcc586fc85e38d580fa39351219","0x1d0b8ebd01e95bd25f5fd09d6ada06dedc6b248f450991a613c536468860458a","0x1f201fb9b22d587e2b22f9778ed74c3b8fbd5d36382ca3cac8b39ff3ab9513f8","0x74249df47f1e30832c6038ae7b7be164c6910e04f5f15494fa50974d05bc51d3","0x4c7ede00793fee0b198f82914cc35941f1170e18144fed399dbce4226bb47f73","0x3a45ec5919b57a54ab513d429595d8c85550af16fc16aa11f4217ee5a51c0c26","0x63db625761e6a0b1da55322ffafc5adef071ec6bd6fbcde5479cf0d0acd5253a","0x3c3893d3dcbe99b984a36cbdb20ff2c2834643118e267738288396f7d8d90b28","0x5afc064cbadc8342a401c46b779e7bd3d5cfc6aea62b4ca9be4206f7fd9cd955","0x63b9ddaa34941ac2c692630b59191f8a1e2bd0924b5ebe9791c63dda5772a98a","0xe0f372363ad7fc8f596dda52357e20e5b3d98e02213dc977b7d3e88de1cc1577","0xeda8edc48edbf6f0ae5d3d21082772f21de7f36435a1b44541e4acca21960182","0xc138ebe55482de20cf836cc88e273f2bba3c2ad2fa005943aeb3861f2b8c99ad","0x6de15bc88473e3add803b80dee9f0844de247c0de7c1665104bf7dbcabf051c9","0x3fc61f0cfb106daa59de1c63fc1c64064a58e20394f3cf1c0431df79d21c0a8e","0xef9cc83fd22fb7837c563f4e46d9164314f35b0d31d9c520caa072f8d25bec9a","0x9fb86da96701ff837bc6fb3ca16e8301ddf81201794707b096ca69e97b8b6404","0xeef0078a7057cbfbb7a339f74a3749185eb6599d48a214f058eb9677f3a29c5f","0x2c4eb83f65f89f3364f160b1dc5115b5177850247ec7a6fd67a96f1203f189b0","0x93418d3ad89d7b333a9fb5640b270c7c414b84bdbb0347d99cf5c003306b12be","0xe332ca1c9a0e5b860b9832c223d470860dfb202a662b35f3ee394f8514c48652","0x79146f6e60379f3669a67147b217725f6cedbf80a94e3f511191ed35e8069969","0x2ee053465cde04dfb6d883ab0adaa0a1fbc0b02050cf0725b2101030f779ba39","0x69ff7667795e2b0c2ff04c0befe926a7bc02463f9e0122dd19b2160e6e40393f","0x63fee6bb55a91ed04b766bbf3331b6448d16e8ce073e6b4d2b18124397fdf22b","0x951aa88e9d5ef0fdf1682b7ddf9019904a5df91a24333f55ec606c329269e435","0x28a56a315231bb54de2c2da88c8ada6faa881b349a7915e81d199a7fe681c743","0x732da4de6ae0947701a9a74323a32992b02c0c398b38909acf56f59e3770a854","0xeb0d54299cb98bbf8723d2c143390bad6b83d1dd8b8d372fbb62879471d97882","0xbaced1c9304e21f5a9c779305b1ef3743ed98bee0149e0b041d13b91482885c9","0x7fa5d36ce1178086965d54305f5e6556fc119755455a4309c7fea47cb65a8d26","0xb5aae17f9eb36afd7317652ccecb6c2db22b42ea2edfc8b2f6dc3de0327c2a64","0x97c75da1e65178657bfd27d63ad90b37b98025ff171e95d0e01fefa8d9f48397","0xdef0556fabb32aa12cd2629a75baaf2495ade9fea19c8165e71cc71b8735b69d","0x250b4e6a7279d34b48955cb93cdcc0ae7c4a6a5fa52b8bc582df18975cb32585","0x51e850605157bb29eb01f2d7c4fdff450fac616e8a3f31127dcdd9eeff2c64a9","0xb1e50f7562fe87405a446873ea5e09daa2ec70551f7900daab75d7c6a40757ff","0x2c6cb1024dde17286a47f0c794aac199af6506fa46fa5306608672f4f19e2598","0x75052aa41fddef843104fc83cd91c48a406c93c1bbb4ab63ef127f508c25a25c","0xe20ac27d9a21c220e33413666cb9ff7aed2e877b008b19946af215f9d54cc6d2","0xf09a92548067c958b3e595e83ced61003de40ad02fa236087e9fc27687a68dac","0x0d2f15430e7c8abb445aab9e2e2aafd9df8b8e7e80920fde33f6670d4389ae8a","0x01d252ba724eb113906715cc4a3a1d55420a78778b88dcbc2af7a6957fa0d04b","0x0c1986f8e1cec8981a39a58154e523b035cb63d2da1ab4356d8162c9fca6537c","0xd37ad83fc49b0d95bd52143249996a170fa691c8f73c3338339ead0e1d763649","0xfdc3646a5cb5a6004dce783f0922d1e22c15f09602bc04be69eab5144372e9b6","0x956e79177cfed7d1b337029fb37a9eddddd2baa7cd1f1f9d0b89ea9b98130868","0x9b980005e8b5f02b54e65b8b9687118b10a8f74ca60d4f566a06d3f3b8878545","0x10778cd7b9fa15de79f083d05274cf1a7e15a899da0a5f8ba0b42cb0666e2c36","0x4c2bdbd066a7988d686ad6f1f8b94496c62b31f191f6faf5287104f602bdb9cf","0xd97b3071a0b29280cd443bba2b45a1763309d6f17a7981a5bc21d4a499f62818","0xede14672ab6f18ee04bfb639efa8327b6cd9e85edc96df6734b2a40b31054fd2","0xb120e2026dae0e5834ed0e63b4ce12ace5604bdc83c0dfa76f64ebe12744a052","0x6dc919108eb3eb9d3d2abdb8353cdfa3a34700dccddba3a6f4858a5b0d9fdc58","0xd759e9471b4ae35e361587aaab8b0aa00570d31575320b45be0df432f43e7133","0xe8fd51629d754b55925a753442fde46b3f24796764c206ac40ca9a97fa02d628","0xa4a9d70f6b702f96e7f50c99e34088782411543dd768a328cb42da7d39d22370","0xc97a4168cb621d4717a90d5d5e03dff4787519bb8ced2d5591d010a53c860e95","0x1c9ea1407efb9bf1c493973d3833509d654ceacafda16d5c072f234730432cc0","0x77c5f2ea47f5bc5705220dfde6279089a787d48ff1ae166b5a9752f51bf6cf8c","0xcf1b525521f3729ccbe2afd9fbda06b236c79369ab86808c12be1fbfe83f4883","0xa584f0acf0d863be9378b098ace6d4e3e78570ada56b4c5b3afa5289f88f762a","0x02b0f472d93aad23b3ed9d2a9af1fea23f976aa1502ca63c9f309d4ac0aeed8d","0xe96122dad349bfd1b3cdcb4860b29df519380cf4bf7f32fbd3eed7e9b609f8e3","0x90f8a0a6508e135767b12a938f0adfaf4be1f4014c2e42b9e5898379248ce8eb","0x1139ea7cc8f7bfcafff98e414ca7e536bb16ac6a2f8554a547b71e8f2b3cf8ef","0xbac1fcc889741610b9a719afb3cf3c65796df484c3875b389e7428dcb17b1fad","0x79798e7bc658f6cd5c8a32ca5fae33e002731eaa3dcf51ec15b88c0d66707ead","0xa22e820ecdecc0ce8f6cc2a0b888931e8d96b6ab0b6b8b4620804a89713ee255","0xdbb214c9af845a2c4b8aa04b00700c082da32c8e210391be4051331151c6dca6","0x6ca73b16528a8057967576c86c3d0c802d12b6af4b178893a6e2a237601ac49a","0x52cfeaaf8fdd717ca56f0d2475e1fca772be9b1031c8b8e43441b870ee0ed40f","0xcb8011eaa3c2c7d2283393196fa4e5d2d58682f0d89d969809194533c08252e7","0xdfffaf60b30860ca74bd3e1c409b25bb0928d0416766b2523af4516d276f0813","0x2af0d3f564a1bab1f39854dd1eff38ea5616b54bb1dc8385e731f244690b7340","0xdd4b5126aa424925564b95c63db17c2d02063b1c275ce93da96c9cd0322bb3a3","0x35233e7352c7fc6c91a4f36f82c11580296d5a918b214f20e89cc5aac7496882","0x3b7c359969b7f5f63c7116856d0873360f3f61e1dc0e04c5727d404112e03cb4","0xb0aaa0347644a4d483cef0c4fa5c0ab423092e3377b24514139cbaa5334c1413","0x82a483e38611213f0ec33fe9def471e54774ff630bdee102d98b3ad57cc13184","0x063dc6203307941a68dffec4dc5eeeb0f7a585158d8cee679829dca904d00651","0x7239a164757f898e863e7dce99cb01104b9a0bc4d825cefc693163ae6d00d1c6","0x2d734be2c4f66ffce196117b5114a7f9ba62f09511960654b665e8a3f1a2a5b2","0xd8f113964f1d70cd9e5b6e22163e14077c14421f14147ecb27038130ae4e2b7b","0xaa003af34982c0ce45bec3d0a4442ffc36bd483a2aec14dc14e51ad96167e883","0x6a38de8d7c5fce92e855dab3fbedad094b7f12be289696f4eec53aabfda15611","0x26f6922dbfdb2f426a0d1db0d9f4eaaaf1ff6e33dfd6bdb8c050262692c6b543","0x7995f55d174931e6e28df828ebb3c66987501e6eb5a707dd45ebe51da00718fb","0x8ad86e3c6c475f8aa50412bbd3d8a0f7fd09b7e741eaf9a262d6819b3d233e3f","0xb105d0e9b82a4cacd7b8b2400a675264b37940b7285e12aa4e6e9f0e57b76f0c","0x18015b9b8d6d877b1a7745e0e438faab97a1dade908a46367e9fb5e9d08404d5","0x29a3f3cecfbda4af6fd373c755f1622d10c8cf7516a56a6736d716084874c7df","0x084fdb18c58c3102ea0a964fa68c81164de04e350bec7e35ef204f78378655e3","0x22281ebc6f119413ab70556c037d7c546db6499894661d40d1ebe1ab59212cd6","0x656e2c54858ae1115a8944a732ed3ab0fe3ead2371c4a738a4e034e1208c7b4b","0xb0b04f854e42cf8e2a87f85fda3a25c00981b6f132ec49b74620c3deefbb87df","0xada021d761235a86b7dccef58110759cecf3d2fd553e542dc89005ed4bcf73fe","0xfdc9ec3c6b436a99c37f42533603576476f4cef8e6a2811e6d1d4df098f590ac","0x76737a0da4f50f65f5aaad9c94bbb2b623c1f935a45403f5f920fe5afb51d4d8","0x0ef7c2f14128e9f986ad9a6af3ea7bf1921798ed61af880458a1fe2b928fd83f","0x1903b1c1a6681d115a0a1c19558eb8a24f26697ad65970c2deff7964402af266","0x2a35c1b915928d548599d0f870db575ac110c9886a0aa763e04e740fae21594f","0x19838757330dcc6f31f8484ab196fc8ddbaa2068898b5951e7224e1b33dbdcec","0x78cc57c88b8f09c226e9ab4da76f2559b0a439d905f14f87401b2021aa0b24b2","0xc21d3e15e4a6ea79892ab7013d1d3b3fabc999a78e209ee03bb214b9706cf333","0x1f83b23d0898345fa8e48e371eb80b4dce3a50aed5cce7726fbd91b6ddc4d45e","0x61b8a6ba7f64d45a6ef2aa7a492b87a1e048cdc20817fb80652eed289a016480","0x4c0035da2e48306e5303fed26167a45279055c32efdb087460682f93dc9eb106","0xfcb3b0dffc60c082e09e22e67b80172292e5f47825d918c926904afd7e36d278","0xa7891aa7a73ff77135c0c2e6f0afae11d4c14897ae44c5235ff7730b42427512","0x159eaa1676c3c5f1a490d1e5792ab56790bd6c9cd4e05b223a10532712e5d602","0xdd6e689db4d4d8f4b125e50470ae37d60a3fa15a05111dba7445e7b93c413ea5","0xa165b30f550ffa41c62f05005bf70f6bdfdeb2f38fd43d1284d50a9cb42c82af","0x6c34b2b6b4d4f623508d163ad59d3e136bf57104e61a99708036c321b10d53d6","0x0a762f30b618431b994fdd9d163cf51fde570fdab6db6bc09014a345b225f90c","0x75c60abb18aa55e576f04e05e55875d5b147548a89652895c81426b4b7805826","0x190f7c7ec4f1acd8379213fe35208b88eccb168b34f4fb772bd6afe5a9b2ccba","0xa63738066ea51b0ff7d1eaa477828460b34746aaea22ff0f4d8726dc92fa777d","0xf0fdbe91b3f18c3dd8f3f1e2739589dfb6b637232e3b8f54467c9e54c5ff942b","0x08504d975844e943cb45900d468c9f20759030c787a01175185961936970aee2","0x1cc8e2621bba6e794110e9223d0a7cbb6b4c2211a0d7cb3a2df2d6058bcd2580","0x2168dcdcc7532714efb197a6c5686eaa017164d2833d8b334c8ec102590f660a","0x72318a967fcdc58cbcc5ad39a150c5999b0faa10e29461de9f0f49991cc6c373","0x2b8e8bd1cf3bf9f6e5a4cea607b0863c1f788a4ebfcb036c60b822fd3d3df0fd","0x4c6cc8f0c75a85f128382394494dec4bc252f8a5f5057f26a82f7302af7233f3","0x3f43ddb7398a7513aa05fa4a7178c1b6135daa2e05f49e025b2ca046724c4885","0x00bd68df6d4efa0cefcbeb6e8bc6ff973cd4b3030a16adc2667429d9ddfcde2f","0x6bbe524f29734dcd09e707338bc3c619c2644bb8b7119f967eca9107493d3839","0xff7660a27c80e7f53a6032ef5def475226a22197f20fa5572ebf548334385226","0x3153ab6ab05c8fea69a9a4d0f39badbbcf21108401840f28499ae4552b5c94e3","0xb8d270316c9f2ebfb1a2cd82b757f36abc6a3aebd55e4f0f43a7dba0ba5c3275","0xa0a2b57ae58c06ffb890fa851eb86579c50913473ad1f7085eb70d70aa94ca16","0x734d91ac86c52b1acced3c7101e67fa9c993c73752001d7270350a904e1564dc","0xbabf882c1bae98571b4a59df4daab29e9684003883afefbb89916a142056a24b","0x53bdf51765a7ee0d4e9f6dd2f154f8ff7b277495a002c9326779261c229c51a4","0xb30485ed9876102daf14e8aeaa48be0800adff7529a4c831f637f82ff99bde78","0x7e3bb45575fb0cf551fb47b26b130caa306cea0759678589f9482baca1dfcd50","0x9c6a2cf16fc8aae8b2d1b1e26bc6df2ad0377637cc3a6fece722a0631608cda0","0x5c16347e026125c78da3352074c9ba716c99f0960b1e6bf1ef3336e3e1eab089","0x01fc4e846a2ea3dbcadc98cbee4a65cb657a1d5b42aaff2b008b6095554ebecf","0xf549ed084b74512ea33a2ee9bb40bd1be5f4fc7211a9e0b92dde908e2a10f861","0xca7dc7f7b7944acc92db9ed8c1aa8587967f4e68ab7902035d97adca08c04e25","0x0d5bd7f65bcd950d124f3a6419cea3eb1180649df99a27936302c6ed5a8dbb3e","0x4375b27d0bb2a42ca8bf80e790db6803d327e911713072ded6395d680d528c00","0x4c4e951036358b27d06bcf1634a14be7f2b1ddfee3175c4034d22b4ed46d1050","0x4b3c449b89d084ecbed968c713711167af88f0395525ed3274d91951ce640fab","0x83c0fd8e1cf6477002fd8761ef17bc16f2490fe9aacac6428a81870ace9cd814","0x0398257c3dcb3f33c9dfa71fd94ff654737c993473ad8bc63e7de1eb43759c94","0x2c1c57ceadabb4fb79ab7909d71fb9919b1c6d34828b573bb207a19630248855","0xa8697e690112d8e147b6aa6f109024af1e348ff892c53cfbe76c5973f20a1f29","0x1e14b2f96e4e163284f773d7c74efde4c976552b77a0cc34ac4ce6ed0da7292b","0x084e403f6fdf4af24b7f541fec7dd6ee81be42c1c6ec3eb48ad9a4b048d4b54d","0x406b0ab09bb5dde5efa47aaedce4cbe2799432910da560827f3b53b5a5c819a6","0xd64cba5b9df3a13eddfb3b7b331dc4fc6738337e738466a6d0183accbc29ba9e","0x1fdb1a983800cc3bd5000e55436c430f4e53c3c6df9493226093159b87465074","0x934be4035c4cd2dd1ec160ee1bd46f23f84ba83bd0225d196afe79972ed76a43","0x64851734fd4c83256b057620936a34a5692cddab5c1f4bffafab7db070980f7a","0xf9fb986faed59f99ec09e792e413f179a6226872a2c3f3515542858b6d92c2d8","0x91252e0652484a4ec7f24db110ff0d7b7d3f501ef260a2751e386825d8de081a","0x0eeb79e146cac12218851d0f430fc840ee7e621d3eaddb21816e5b1290d552d1","0x2181ad1630e24d6e112ca1f551d0b8466985787590e9b814bc644a17e8a4f513","0xe0edfb61fc69e12f6561502ebeb3dc9b123f3f0a96cf129d4f0acb87a681381f","0x8ccd0bf0fac9088940b3210832eddd4e8b9dbc004ed15a0b42a546d1812f732a","0x2c0ba4d88bc073a656ba41142b51d69d691f975502a09f77d899928fb6880eec","0x68020ab38f07fc82e721f24a1623cfeffeb28bf7a629080d7de5b335720706fa","0xdb3134fbb98ff8e3e2a8401a241921ef6cbd4451184a4d94219e95d7e14ff96f","0x416e9a7c4366deca19cc0c928055c77d69c3205ccc1b406d86906b840dfd7457","0xf718181adfc39e06aa12c2c31804ab209840903a66afb0312add16390ad6e8f0","0x1defa2a94b40a1ad3ba60732b5ea76eac225e2101126f22eb23b30b8ae0352cd","0x2e4997febcb8388022fef93fbb481dfd2202242db741e4a1a47677b25bcdff39","0xd45b5aa687677f1d7a05986e9b706623c254bc1a1b7f1fa29bc877a300f6009d","0xff7d1f6cbc751fbc7af9aa8673b434b8401ffbdc6618ec95a0e0f5529ccbbe2c","0x3aff858cdb1057a91456d96b5d49125f9adba97d369dd5046a3489246bf68e42","0x74b95372ab8fb4a6e04e5d0f1186ebacbd528b791891b52fba5f6c75875977ef","0xb4ebb4ddb73064c59a9036c78df4c45e8ad7ed9458a119c0c10b6c700fc1329e","0x9ed700bf4aa36102b3e27066c5884cf96a6e29396008e2be028b7dd2486461cb","0x89d937bd80ca6ed953a875a7a01c4705c009e0bc8484cf999262f796e3d6d4f1","0x4e1c5011895ee668b9d13fd5682e75a7f147f983dd4323ae6e189f45f89ee839","0xc5dc1c71ce2cb79b37fdc36d2f46f2847a91242c6f130ae5e2d00d77acdef222","0xc261aa7f75f907add3b911780ff525d7cb65ca134271e2f2f3d8b48873d71dc1","0xb2825bf17d175fe89fa6611a49f3efb15f1cd8b8ef6573038bc8fe81728d1b09","0xbe5321a6b8f7ae05687bf2a6514a348fe797b2ac338eb88bb614f70b2ff26f9e","0x788ed7357b787f5796cc9910b8815611de22d1e95672f85cc69ba274ac39d451","0xf68f747835c6822909c3ae382b4129d97c921c2109a5b7330039ca0be3933ed3","0x9124afbbb2c908153dd709dd1e1c5b714e8c04b3bbf56d6bbc956dcf65a55cd5","0xf448e23cf7c6b1998329e09951cfc39fc77bc100ca268a7499427e4478ae6fab","0x9fa1e13cd4417ebafbec36538be79982b68b56eaa7e01c61e672083a749f0bbf","0x0b6a6d132e366eb64bfd4cd37ad52f729ced3de8680915a7dbc745aa4d266e56","0x294de5eb3ccb1b67c97f6cf7f6cf5d919ac4085c82d1e80b51c3a9fa2104af91","0x6b52a6ba051ef4ff9d614a4de8ebdb2cfe0d7a0163788de362bda8cc4dad4c18","0x8ce4d047160ff6cb9ec56e2ef3b0180e586dba3f5dcfec8001b4553ba76a8267","0x9ebb4b60b800d0b8416e4f46cc3300f9dd20fa74087183c1b7bb32f90783cb25","0x31de6e043e548d6a16dfbb3f7a7fe733268ffb9182991bf5dc37cf2223039ccd","0xb50b804bcb5d89148f08b17bb285b23c8e536b07b47f83a850f5a4bf26054113","0x10d75072f90bebcb84d5f4916730a5dba7ad80755e60a14b10ec1335f4ba60a9","0x340383ad4b746a6eb49ee7d643af6338f2711b43e1e74da18005e40b094a4a52","0x73505eb064140b1f12f59cd7af9a7badea65c2f799fe6854f1421317f4aa7e32","0x608bfec246043d0495da3d93be56566d00943c15669c8b6c0dfb269b143ef4bd","0x7922684b3a9037f486ef1856e794e220bd033efc15714005034792bad16b7843","0x2a55bdd87fdf42b27077efc1292405fcfa4337a9a0bab568a64094bc7d53bf14","0x594d4be60a490b283b823eb0fceded5696998a497b660dd03d692b375e96a7fc","0xd0e6acf76d158bfc4538889c2d89c6e52370c02dc1586dfe90df4233a2d7c592","0xf3f01227cf57cf2cc3c351f5dafa896b2ede4242f7563c6d8a4b9325c8e5fc5e","0x74d7e72074b3cc0a84d7d37b914ec20038255cd534ff636438c3e3f7a1740f04","0x479f3b24b1095a3e404e2a23af86eae7b7d8457b3a74b1f3a20f72b897b2940b","0x55852c63cf878869a8216d4f6a10bf71196e73e9a1e8ce8d6d191f0713b8f9d8","0x4cd7ce3379db00e614cda226dc7c07d819682fbd850f208f4e54960a6ac6df7a","0x3ac937f6cdfb6a002d0db49f8c9bca3b61fc343e9486744ddde534db678cd7d3","0x0be195af00182a7165eb802d54e137fde8aa58cb692271893f2d213b24e9aaa5","0x0831c732b97cfc5436d5d7e3a4c7e329d559c8af513517821f328fe08e85e522","0xc95ae109f5c0a9803f7b593fbea2ce580866b66a5ea91687e6b286599e2433bc","0xee2edbca136ae20a311688bbaa6a292affe7f027d37950d3628d75721aec889c","0x1f004b1486e72f55befa8ad6132de7930162a40d7239f1c644c8d22c1a9522d2","0x312c3797955310514b42419d02e464826a9bff899e2b2c7e42ef516409a7faba","0x6ca294b1b0b6e69f513bc5d5ee206cb72b87678141a70e3054b4dd96d97726c2","0x6b6cb6658c5f63edc9ee2a65b5a3cdd7d6d8a4d6aa00818bcf0e69479cb9a3d1","0xa3b4f3c9cbba969b13019559eb8d2d72f1ec73c08c721c4b569909c4eea3dba8","0xfa2cfcb95149c775afb4385a97d91a46276c622c3dc011cbfd9f01b449a9390d","0xa659360dc8407505d6e1b1a85407637512ba8230f1ae78072c0e53978430723e","0x8d544aa9dc77536424000ffed24ef68c8ffdb53c6b9e140c68e5270a92317b2c","0xb2e72cf2302b8c1530d3395cfb605e38a3f0a73bb45d5657e6df59685895b4e4","0x8e8032465d06c2d000185b7823de114af2cbede01910d19d86a41eacf2186a66","0xc1ab2bfb57611e9faf5bc0725c47f1d940538789753ab3cd390979295889009a","0xc6ebf673a8fc9bfd910f5c9b60c305a733f3f998793c4cd20bcd274136c5ea4a","0x8dceda30bc65a31cc1e44ec24b49fcffe08c488f7aba0c4eb768d1ee8d18ff6b","0x486715b6c4abc6991beb479e5fecd6d98618393c156ff1c4494d85af59923404","0x79e73d6a708ab95178e3b02ebc7e36a2b6a337c6ac2eea6d6c2b221e5dc7eb0c","0x360f363d8aa383c55190d7a73060256f8b1d17f722e3d9416000dc9010ae4eb5","0x8d9e7d4f0c67dfde3eff2fa01fa58d353567c623d1d6701ed252d63102f4adcb","0x8a46f55524090e9de8ce3abb1b27215dcd99466e8077ac1a9f74fa8dde832f8a","0xa4842af16b6d7fab5e61602dc708031b2eda15f31864501ce002c049b0b0fc5c","0xe218fbbe46f1cf15df111a3aecac40e5d3a84514fe111e3438d5526616490049","0x1889f4b312550d80c156d692cae704896b2738aaf16784e292ebcbe7c188aabd","0x8bbb3807a6f171e4847ea231e8f272eea7b6a566e148aaf5ce63e80dc167bacb","0x721487762665c5fbd35a13ff50b8f5139ee17d5002660fe1e075534183b13605","0x7b40c4e415815fb767eabf94b5a4b99cbff1965b9bcc5a8914de167c030aaa19","0x767230f3711fe414e639f52fafc73dea7f2694f676e72079cdc06ef470408061","0xeccc70cd752e84e04e7e5896b14b5af0875d7cb4d8492201d6d04c97a1070ec6","0xad6dbe9eab296f75442bb6a08ad7cb7a5481eea7902133ddabbf1edc488601df","0xe9c4f9569e6326fdeaaf40b179ba04e0b803b0698ef5ef0b9047c3f10d38a554","0x19b619ffedb098a00497940db49135ffe40be9eff1f347f391e583f930604711","0xf73da4bb5c5b5891d976e0b735ceb99b6298f2120fb68bbd5aafbdff74e0f906","0xd5acf175723aacbeae4cfb2be68f52fa1e35ce4470ac2ff027db1b6109800b16","0x18fcc42740d98328d5b511eead04038c4f423adf5cb052c95cf568f67b44cbef","0xc7bd4014074caabea47abee676d53cdf8d4b8cc72aa7cf2e24c3d6750e0dae15","0x0226f52030950d925e14c5a78d038e1a43117f5569cf6e681073fa150e42119e","0xf2800a7d5a39dc3570161e6efe6118a850461b46a771e222560506814fea2374","0x577e74825f71489e183c233545c6ee66c8f92eda00f1d0133165832fe63778f6","0x4fef97a8ab9a54f062478884c185599e0c764915c7133ba2f7aa9cf274b79fbd","0x51d867fcd378e23cdd4f693de4ab5c4c9db6ae5a72755e0a1e4713426ce41cde","0x2a131d181c2d6ef75e7033e68ed6f55b632543e3c6de88eb7f11bd25e46c168e","0x38fb045e50f89895db282a06126a31c8149369977adbd11f702d7d763f69ae78","0xf063ef21eec5e18cbe157e18939e981abf6dcf174b3e6d05bb1a526cc83d3379","0x108be562aaa97f0af74357aa1e72441322f997bf712fee4076edb0155bf8450a","0xee1126aad91d1cde28e943ae94cc963836d8c6c24395cfea30aaeb1550b7a03a","0xeff0e0ffee66315070bb22735e436a71c18f33fb320255a6eade58e28209e315","0x0fedf52565e3d2fd705858bfd45c2054d8fa5dc053151368b4f3908dfc27a8f0","0x6f1c64515b9a9aedfb525413c27edba4ea72f0a6893fbfb864d23bbf3d0ad949","0x653c34afc1d2e33b84e95f111a9909edf3087a9c56337c81c03162809383409c","0xfc86e77e7305e2fcecc5b36a0ba48b228fc7d240c78abdcf762147517e1475c6","0x24d8b9f552971a30cfd9590f84aba4dc59bee52fa3c9117ef492dee084ec6553","0x3f1272a78b62b5d9b4088fc59ba75ccce1aecb4bb03048fa266d645026165eb2","0x98a06fe45073aca1d458d142c5c795dc4f8d267fdc05e5a5109685b08102bd5c","0xfd292fafe278d626f632c20bff12981e391acc395efa1ba9a6782f90d1c274d0","0xa067d93613300762b2ff3d8c05f74475c74af4fce4de4ae37c6ccad10f12b5be","0x7cb6bae786eb3bfa1f7b6707e490332a989d859354932c4bf47506158e7901cd","0xd79864bb276712a8004300952fcbc037bfbbd707319966ad6ee1bda9e41aa8f7","0x3431c186d4c2cbf159bbb76fe9d2c0be95e13e3b318edef2d6456d9e54df01c8","0x097519a1e2559076578706d53d383f145198569135563d48c1b9b2d453a6dc0a","0xd1315f563d420377b84aa1b63c1fffc2c80e10621f075b9fba5d43de142a2d57","0x663dd76aa3a221a1aa22f757b5a48ef8b1fa79d951da8df930b8f1616b345084","0x0fbf279635dd7fdd3b7afd7063782efeafdc924ddf5af6c02873bab44c342396","0xa9401349d9a8e647b0dc4efc98486cc7629cefa85657f3c1e8d7162b1275a76a","0x1da5bc9ba6fbdd1dee87e8cbafd1767eef2595ab574bca4bbda8875420621658","0x1a1bd0e5a0066e07ac215df9718684ccb042f6faa84a592d09f043e42074fc17","0x22bdf0e03a6be9117a6a5c128f044a0439826da7dfad0bd2fa30579f20b84436","0x6d946f1298d2380da305bdf82e2e0c8bcc2f7ee053ee31b0c75484281992a21c","0xb030845e621ab70cbcffea849de336c34e11f7d3cf91131e53b9c88acd0f72e6","0x15273d47d274313b29b1cd2a05c77ba3a353e716a70766b584a323ea0f05bb82","0xd076da1d3762456c294d8a1682dd8f548e20b3760a8d4a0a0079fbfefe1d2d78","0x4250dd4c6e54e7434661b7e3557149644dfd6c16e802435a72cb24b20db04c5b","0x25a35332e51b2721054372ac15bc2d06f51092e82ae507d29d05bdc2c86c72d1","0xfb47d88ebbb8a621b4f1c99fb86b0b7d7af021ce4df29bdbda943935ef9a7571","0xf756af738b81b3eaae179136f63a0e1ec092b034c7b13005fb9ed1cc3eb0ef33","0xf6cf24af0e5cb6ff10e7f8d124b614f8cd4c232b54d3cc5765ab161376f50838","0x10d898a3be0b808a16052e26f9d3119a62f61020916890064db0e9a7551b3c16","0x23097524f9cd53b15cc6f331282f1c644cd107f06ee1c4841b3cc6856802773a","0xe632d0c6b699258d2cb84daac87486b6fe39cecb8fc26be47541d51bf09ef8b0","0xd8bf24215757e21808428b2c42ab94c9622194713e63025ceba7d003590d43bf","0x3ed20fba40550f5979ba353216539b7066166e0ce1bed7b23bfe568bb6322434","0xd5c16fba2f79be17339eb1d948c914e384e646b72b990628470155ed6d77ec98","0x6fc8aeada55b4b0f703f4df7a7c7e32199bbd34cba341d1a605cefce3166fab6","0xa1fd8e0353bbd3891f68180702429c571ce22281457bdaf2ec29a8af3bd70a0c","0x5d2e473898c98937f3e96956dc725befa99216ea15a78db32b0d9de21c934114","0x58f4ebbe13a1b147ddd751dd1a113dd6e746a9623e3ff635d4fd5a2af07e5143","0x63e623df1a273530e99210b29d50b52880de77e2db1d58893dd645cd64812b44","0x03a74871989d4e32f73eb109b6488067d9cc66f163738494f0ad78927d9f24d9","0xd27f8dc4ea624ede3668a7f68c04bab496733b3eacbfa792d245ae48334a25f9","0xda6115e2e3bc89c804458a90bee0b25917760aa57b46320343e2f69935ec53c6","0x445e015f04e38227da6d2a11382fc6b6ad50f35ce60cb5eaa85164aec3086986","0x35436f42c257950d3eb16aaeaa85ff97db1efb2878de9d2752a8729d6995ee33","0x5c9b213ed635ac84a15394c5ae8845b21f219e1f2822cf1d0c38c14875aa56b5","0x13a838c712f29c0e4e64b815b0357dac1c454469cf2aef060a63b3ca3c57d296","0xd212a6f65abc21e2827d727a5746d99cde017ff8f617f2583bbaae0894ebc6ca","0x80724b0ad8fd86d331d9a459275baf9fc92da49782aa6121b0065b2f654b9d76","0x4f03f998e9d35263bba40061da9c9f7443b48acbcc66e51e8bddac8539e1d741","0x62aeca33a3ab303d7666b5ab871ddb08c4f391eb2e694e15b011d1581f3c8b99","0xbbf0280eb7e05b9e22651a222d56bf40751a98ba961403491ceae084e1363fe3","0x58e36619b39a91077dd21b44e1f465cbc584fbc9ce1fcbd53cb07b25e8992f84","0xb48bc1130f931d526ab71d891fed4f92b283cc2b2b964284e1fd4e7005d4d7e8","0xa93a5a49a11d4f3f57339df3bd420903d7c4227f4bf555c6a5bfdf2a4edaa820","0xf0c6874d2aa9ff0744b802c3ab16e5ac8a243211b4550973bd779fec277c39f3","0x7906d532696b44cbef5d9dc0856785ffb04da20fb48866533acf74e05f77117b","0x5af534b5429b15fc5b10a4f4ca308a53ccf757e064c459e77db081303e2e054e","0x7b65d24fb22abd32deb4b1842d2aff90a12ffcaa1b6f2c79169ebb84d5c56117","0x0817803686fbf12cc2d6c2a908e561e919ffa25953350ce7c93ea66aa0d90179","0xe45997c446f3c70476c1de89cfda9c2342b76a992ca37ffc85f4c6887993b798","0xa7b5b27b3e981e4b096c348db49f81058ae992e92681b4bd56e1f487d02c9c25","0xe5ec169c5a165f63a67651ac4cda3729043445637853cbc87211311626cfe2df","0xb50eda759092ffea8381b05ce45171ba02b6ef42b1f965320b3c3ab0d7047285","0x253c530f0210910821439e7cbca2ec87fa743b20c80f50e8340531615a303963","0x553f2bcc4083e2bc4308136802022c3e08c9fd1b4d6d3aea19cea01ead8fbb38","0x75c0224d3e1bf3716cddd398e7ae9c19d0645566bbbcafefbd68d581d9398ec7","0xcad09fb9f9e337db88429be43654a58556ac6bab6b5c3ebc5708b01e42e59f1f","0x27b7e29071affdfb7f682d9f753ea70a5452183ed1d14cb2fcbc458e7079418b","0x8fcad45f834699d8a9bb11007874f5b878ea22e95f4623b6924d0d7d34243e8b","0xa3c0a849a96cfdd57eec34717600488715a81d0b5942b2ec7307a6a9a29ef20c","0x5128fae84a5b400b3d824a1cdaaaecc48c42280366b9220f62fd032956db61a7","0x19f6b4878e5ebeedaeb53fe4d05a63699553dcaa01e426c72f6f42a70eef0ca5","0xe1d31b22e3c62112115187f801d8080ef5f371b764b7eacc1e04a12061a186fc","0xb2e8f53a4ba6ab743954276e346e3701c4a3e2c334a29cfdfe7b0ea183067b96","0xdf40d82201aa77affb3e31ba95687bf19ba2a08db3adb1836b7d7b77d4b7ff30","0x8fb65428ee1b46f90aae0c3955c115b8cd7637b224c4a8c2d9bbff8329360080","0xf70f59bf0525451a7e3904cb897155aaaf77e69a5590f192837c0badba6a5c7a","0x960ec0f1a8a5fd8c9949ce8e86eb90be443c244aba086bb3b68756e79822d1b3","0x93a9ecb6f07b2c71c28fbe617cb72f23975b75ebfe5c0f6e61c3050a097fb1bc","0x2239e09ade09a90249440818e4f8f619920d390110331bcaa3e9bd5d8e515169","0x55715cd6c9648d8a8cca00bf95fb092d5e4d3d31a781e06c7abf1ccd116443a5","0x68ec0d9d198c8d83483c2a03d9824036f1d2d04e8d570690120f03428b01c42e","0x03abe96da447dd4aac88df7d591cb5cf8c61fd606412285e38ba54cde5977c35","0xd7da79aef804523fd26079396db9cff418ff944a269e57cbf28a6b02fa41e582","0x07e4873470173895f6e93e5894e41c5ea39a132401ee7d7c8417a7718427b039","0x82797ac756a1596ff47b9167abaef9cd0d915527445ef03492a2004c42828a88","0xeb9eaa5bc79504d45f7a6ed4f46e0f18219ea058b3ec9788e5d3d6eb1d856e1f","0xfb482f334a3237784b13494187e2c89b129e7b83ccd49af984221dcab513ec20","0xf831d307c339cc98f963224704754ffc8bd3c959e813f764a9f749d84aad67c7","0xd96f8cc6d0f1c62da3c47cec1306dd7147d7687e5bc36b57ce5c07a0fda9b0c6","0xc2f7fdd220f8adf170f29685dae241c0553cfc035a608f1ecbf0ce5e8abd807f","0x2b6b034b38659958b1f5f6d9044b689b42b8f34c7dd3a856abc678906c8339fa","0x63eb8303df35d5a4871095337c8f4a78b2e905940c5b32b848bc7dc5108298ce","0x2fa21e9d501d4c9b69f70e0fb74ce3bf8642ee900959da57ac95cd511697a511","0x749317ac69654af22471b631a1fa4ecb5885c86c6e0acb7f2e99df48a32a58b7","0xed7d5ead79be764de2044c0380853ce898954565738a3f470fa00396afd4a213","0xee0b39e8ab0a9b989f87a6491ce0bdd4c46313f332880b27bb8f60d761c62968","0x33b4c97fda937523ee6c680719aa6b42b4048b6716f6901651c2ac97a8a1d945","0xd0a52b0722174ca863b86329c9665a42db7f9e1b34c938b71f8dc4bd9d5b6eeb","0x1fa43408568ae53d8bcb329b7ed9baec11c01eb3290e290667169ba880083d0e","0xda69f9a7eaa3667001349923dc68bf7b530d272981dc63aabf14c75e46b1e7e8","0x52a314df2195ce1e49abbb7030e75015bfedfb5e7033eff1e33de72c1fd1e60d","0x8d8bd7eabf988edcc41498f5e1f54f746af257063ee866adfeffa599208324f8","0x1a3c4fc36033cff0a94632b2f9577e8465c91956825c22458d72e1b6e85512b2","0xd1fc048491e9416b06af8a5a3a208480f8b40ad41ffbc61aa32f6bc59c34550a","0x9e49ca80315582bdf927b8543814f69c74a11d6c00aeabd68db6225b7dc6992f","0xa9a43ff8dbb9b5a1d4b4e00f795a89c09b2c5a8e45bd00dfd40de22749451389","0x5192784e147adef99afcd0356746c764454b3572da111997aab15295a85cdf9a","0x1c17dce0872ff0ccfa2a2f4a9fb2f759e80ee9d5bb6dedd5d558fd51836fc229","0xbec8a18035297c3367d5af08f9f2c189069a4caac939d45cd3a622dcd40facee","0xe155949df941a2f795664ca7499cd3f72f02c5227439b66f084006ea3b3fc254","0x68d522a0ded47afde56de3382f15a077f845190cfa21998d3360c4593acd0ac0","0xee521ef0f5d09a88c3e39c89c470df1a10d17f0ff49b830aaf01fcc303f754e8","0xa22c58bd77c31f975ac27e4e2c12938983c1252bcb3848015673ebdb8db571a9","0xbf5120aec25360c4f57e94d98f606eeceaaa1969cf157475959f649981b2f8c3","0x564071515286fe3c8f6f690d41718a3a90083aa843d795e6084f7e03eb9fabad","0xe9264c3db80d1fd6e0d4d9e66b5b0115516edcdb2677cc0b009045a33f0e1c8e","0x8838bb5950c95c755deda6be602bc26c2421683975c629596ae58f5117fe6c3a","0x1f50ab49904ed93cb59265141d7eb39b589fb18a677f3c0688d42e9fd566a0e8","0x734fd6c898634e1caa9b679921d626421141804c23596973c96d8fd45a6fb3e1","0xa85eab60fc50ca4d1f2c3351d866932bd091de66652f45fe931a7145a79176cb","0x21a76fe05f4c66b2b205f9479c3ba85d8795789cc18b9f1b46b6f71178b58c3e","0x51babf3871e6fe6f1cdbbf1a78173c36d7b374ea2ce29803b28058dd5b5c99b1","0x600783ea929ef09fd57d2f3e12d6a51891d1ae20e3895e12ccd35cb271b470a1","0xdfff2a34e49d00d849f9c6def0e0a42816d18b8bddb12c5f8c2bffc5ce926262","0xd071e7acefc6b22ef40950b6aeb2842d7e8495dca672d7623a58a889daf52c68","0xf03cbc1ab47630842e032211efb5356c0bf988cdaf5f3e731dc56250cc24b459","0x8693434b59a2cb11acd3a09c355f5b101b25ee36b802140d62c3899a5513688d","0x9dc5bf1d3c076c46c9f66d60d01f6cee6a7a57c89dcc51a7200b96bc67fd0570","0xf9eca09b7c4213728d379ff8de18f496872ca73247b48964ee8e8e3275ee59ce","0x7ca5b9a5999e216e70f5ed60c530a4399f625eb10c105d85926ba41dc2f3a348","0x6f074df753a5dc51c5bb718075141c717acad10f7bac15c2fac33094f0f7db02","0x7056eafbe76a47f13cd687f818654fce70f804fdb81767c1b4a0751e2bd3c10e","0xb87e1fd47647336c88e79d0f22f81c4fff9c34b7fb40396eb2ada1692e6b1597","0xc48a001c0c6f86884493c7ed7e12726b05ff8d9d97109b7b8d1bc42bb9919fd0","0x3e9225175fdc69356b94fbb7ce77458e3dcab25538ddd540ad9f76b35bce4f54","0xba13c9da8ddd65d5f1a60ff5e6cde3ee46549a9256fd06f7cd2924e38cacd984","0xe407b7329bf511976163a5995166d3aaa4cd88a3b3902c46f1721690a5c0cb06","0x3e1506e58cd241b1aa920036af6db10d7e85195d53ccd733d38f9f813e1cac7e","0x4b5507bd36ee6a3dc7f1dff18c4e3c014b29a9dc60a9cc3f69748d66c3795f6e","0xa4f59869905df716d2ab70dba9e38df3985a33ef009a5a01ccad44dc9bee04f9","0x117a597a5868d40b819b935348ee0b02ba22e2a5617ea0beb86f4831b143d3d9","0x610cc907b7ca0567e891dde0cdd58f443bd775b56939ced609f1ca5098130036","0x8e4a57475ad01ed09ddd0477d20f5bb0de961584472fb7138d032e5d6ef6c86c","0x6ad9bff0d0bd77bec8feca96ec37dbfe7994cc20ee7efbb4bbb2a2f3f166fdbd","0x06325edb15564585a95039dfc6eab1effc752e67731564b8de03f0b3c492051c","0x12e977b7636bc3d0fb72d523370da5242fbae2596295b65ed2a4a783682e93eb","0xa2dc0f0f81cd7e764979110a340d24791c6224e791075b6afa1397714f999226","0xa024d0d35d27f3cf1a7a8bf31f603c8b9b6dd315f3b1c6723c576d00cb5a701a","0x81a6eb8926efcdeb1ab69cd151ea2217b18e6a5215c209aabb49716a807d1723","0x8a4c0b49953d87b1a1a2abb29ae21f735faa88134060f70cf303962d7719d54e","0x2528f8fbc83b13e9e7b70777a655ee387edd37ce791f59fcd403cb9b515f3d2b","0x45ebd5db8b31e7613e96923dc0a817a83f6671dddb697843aed14e448fa1ff78","0xd2527955424f26aab7e180c9ac468e10d96ef0a0977f06bdc1a12bf298370ee3","0xe4895a2223f4d677769ad0df3a17e5c84eebcb9d7bc16919aed480396ea68921","0x3eaa424270aaa01e48cbbf3d812a334a417fc3eb636616e11bc305d78d79cf0c","0xcb3e116ee44e18c87cf6cdf6788f69a1fa3a644d41c952e6c3e512e1ca2eb40f","0x508eb88b6ba8d79500dc5a215eb810fc49e494987de98c45a02dbad7c78e9d7c","0x769c9b8d53013c232f3e038fa5d961fee96c025b103f3ce3151a75bda49b0be0","0x038c4ae6a9e132b9e71347f69b2e92542ac8107af629ed2addecf25d4a44f873","0x0306acbbe53b2e9c00d3f671f7c7fd25ff563451d4c1e4a422c9566a2afdb268","0x621be262f1886267626974ec255211b0b6089f32c6d64d002031fa7dd947dbad","0x4415436affdc7b1c7db31150c55aaa5a86050f89e54233a051fcde362cf5b790","0x39824b7c1f28a9a4803535258fddac7ae6473a5a3e14439e4a2a06994ccbf31b","0xefcee2b0d0b45d9a3dd9781dfc237e51340d7c316af396adbf1ab5af494c4b7e","0x6d750089807c0fa6167dbe5bd07aef8677b5cf8898946e7b9b0b17e3273a8366","0xaa97cfca995f39cd1cdc4debbfa2cb8a5e04be54dc1a6774db5e8414e3b348fa","0x5bd54ce643481dd1118cc4b2654f9f1b7a2d7c8f693d97655e841031eb755b92","0xe075db3a454fd741267b12f98f11b0c2a73e9ca1b059801d25ee770ea9de97e9","0xc3b2c076cb2fbd9b15c049b1b564f42805acc3096187c5cb6bb3ec59885c253e","0xe5cf970ee188bc9957291be5cdbadba478f09a72f1c92c88c73d7b6e35b4867b","0x4ce69bdaf48ce7415f644b919369c41531b0aedb64de534232d185ffe16072a4","0x776a3cc2d1fd55997e53982cb20786722bdbac65b8c6e398b5c69fa515cf16e8","0x49a179542d18b676a5c039957dd5ae64b650728e30d8ea9f5a976af0670a18c3","0x1f4f4dfbb2e0255ed431cc8c1c579299a03e0e068956bb56023efb66465da158","0x3b57316fc17a8e8e256082d278ef87b03b23ccdfd3d230fd9eceedadb334f1d8","0xd4363790d98a1427b4cd95e85b252460316ed6e43f982c741512ff75d886e6b7","0xf0531cccb97efbf896964870e4b4c6a179d8a8d3e3fb0621cb18096f5251c4e7","0xebb28dd64df33a1711037e3af38c527f20ddc3c4072724403b908b65b4d2c76a","0x551c02dd1693394332c71926d2b0d0db2bcf382c1f442c6c4ee3f14cc4160c04","0x42d6cd660ffd127393c8eb49d958ae8dbeec657bef0446c139e19c0763311bf7","0x214093dff49d8efb0b7230353c2ab7c42771026716f1e69ce58b1f9f5b231c2b","0xccb9adb574412fea123beffb7ecdc1e5eff248dca3eac984b17c665368a35156","0x442aa11112466d9f1f5770f43fffffbd1496ef99dbc0595593c4e590c0ab09df","0xc8157849081c8de724e196554224776e52bd5779712739f43ffec2f492e8ba9e","0xb27a4474c95ac7b8e18faba3d9647da7f77dad741448dfb63f9d7a198758ddfa","0x6d0b4d26e479a57126af462a515cd43814780ea0a7ad58238289bf0f127253cd","0xd38d296c837866b99b5ce674cfa5fc17ec64312ff6d420a34fd5702eb6e4caa1","0x4ee07ad5c0181dbdde5bdee74d92f79961775e98a3212e242d639d07321a2df1","0x89bd85d7217324899278ab361afeb290c5cfcaa2bc2184b4221ac80fa7cb31e2","0x0a6a66138beade958f4a74dd2c923bc891b07721b2ec2d9673ac5cf55e509a89","0x9640e0821a6c8a473ce1f39905520879bbab7757f607cb0f8263af3f8eee8940","0x37b56eb61ab3d94497e527ff989cd708ae207ecfe9eeeea4e1bf15c42c19b7a0","0x2dc46e60e4579718414f7ed433b90530f2d236be89751dd6fa1ad7327073ecb4","0x776d8a910aceef3650c31270b34422e46af353a5c46001e898554d9a7d0466bf","0x50985502ebc181ac56761177befe8fb86f766ae949e6c7b0aaa6f37f3c02b414","0x11c0220e1b105ab816ede16c1c6f995071595b033dcc07ed8d812d483db0be5b","0x1f33b4417e3ad0e4b14b770a9ff95c4a774d1b6efc2156392023231a19cfe090","0x5ecee947526192e74ed64868da1de271b1b5b8803257d33b063a67cd6aba5194","0x4364a8653163ed438e3c3a446d0e8f68b84dfe4d12a3633c4894179cf5e41057","0x912c6bcd96671d3fb8e3d150dfd7e254d12c22375a00ec31eac96689ee549803","0x9fecde94b71131e0e736423bc0016d78e48b6c42accf61b848c283a17e5f9df8","0x1a9593cdf483bfc216fb6589e0908dffc00e0c42eabc8ab79d6a4145f2805e18","0x2c73eeaffc35a5f0db903f8a2c84cd066de3ce7b3404e178b52fce2dee6b7a57","0x57ff8d8b16ff11a39c2afb0ef2eb9e4914c465be0aaf7cf7a3011f6a29f6e7f2","0xd36dd85e1c0650a7eb8564229f3f99cf258bd7ea01b2afa97482f7747d46ab67","0xca97380afe562ba9af8bc450d9e05975add6d8d8b4537703bc8474ef6404c9d2","0x150d15792b1e229ba133a655e4d1e7b2f08245f520fa2e875d606e35116c4cb3","0xdcd0e686f0444535c84acb701b57aa5ca10dcb6f3ecf96bfb807e4ec0dc85ed3","0x243c84a96d982fb77042d8181f3b2b9efdcc71d23b0c3ddb5296f2cd80424b32","0x490745af81e68c65649d5b8ce25d11d0b818ff95db3637357b587be61e909b5e","0x796c5eed16335affb2423d17b88eaa4ef35290bb3ea9c42d57c0f71a86ad301d","0x5edd5c168cda981901c5fc5cf46763885d4d8d0399e0dfb15187f176622190ed","0x858425df36dc0e98a0b51dc3f8152453cce87f6ed4a63dfcf731612dc924f9ac","0x3c003ee6b303f9cb95aa4ff0a922e7a5d6121bdd32c6156f22a62b80a3a389a9","0x340320063459ac297512d4d1a37611fc1beaab03092edbc4202382c9beb47d3d","0x11e9be865c27a54014e97d85f3adc6bf49e09a99c8b12d80032b18397954dde6","0x82ccb5c6f6738f5cc58d2dda51cce417fc71ddd50d2dc9853610af27c4dc250b","0xb96b838df813d30eba8d1cef072e2d0726c93aa08a26f4379019507ecc4ad344","0xcc8c6928f44864293e946e4ffe3011409550097fe8f4c77bb0dbc8246bbd1cfe","0xc1ae7947a0c0005201cafbb82aa20b047d1ed5c0e593c601b7709e06c3f025b6","0xbe4ac43a7b87ccbb1006cb6278add51c4ec60133be7e3c677ce80dab214c2e2a","0xcb86db88b728d0280c6a78a5e005847415411008a428de7519d21142e9a91472","0x0d2b8e73bc6ff4ec6b7dca3ff81a52e6b3381110d13f47f6b4c511e9a221a8b1","0x41a48d473956f18726b48808c6f194dbef926012f815c453ec24a00244232457","0x9702680ee768ce63f3f8ab9910c63fcac3c237152842be823952ad7b16abf25a","0x718534c0e257aec8f2b075728fe41c4ca07820ba4b2cde87f1754bce5bc88825","0x9c3b29b2f2f88381c82c001d258b36dba2deacfd8060c531881744b25b856430","0x75bda6e4b3289d5ebde800ecd6210a661ff639df0988effdbf5e7aa25d4ec5be","0x369e9cd8cf5cf938d54fbf23e209139af25a259ed042cc8786bf4ddb89f23134","0x7ec7d409061c195a4f63c0b2e4998b3a46ae31264de7087eafd95e7e59366c23","0x4749a4d88746c5bd8a9654c8d0d686f309d5e6a032b31793132b42933a3cf448","0x668d842aefb6a3e9c77863ca859403399b7c2802ce559612d12db45fb490f8e3","0x884633c660c8af38165c5d449409d9ebee4475af13f7307843948535cf29bc9d","0x3cca534ea8f514165bc5853560b976273810d7daaa9cb1b96b6b43e2e79ed831","0x2b69b90460708297b80500b1b438da1db0c67bf4e4ca6092667034f62a81c459","0x73be22546c35f080770952a24ab540a455e97f0bdc16e10e889af9e5fdcf8688","0x21bc587d4f6e79f5c3ac15e4e06dbdb2578d3a855eb44a75245ef8503e54e3a8","0x4b72e3875be7b3e49734d635843ee3db28ac14c3e318fe01e829f32cc7fdc4fd","0xf52c0efffbac17717f0ce44d8afc5c81a75a18e67177827b4c9fefbac6b2ebc4","0xd3c8d12ddfcc7e4ef24f0fbaf9eea6adcd61d6270d7040a9ec4b13551ae765a0","0x635dd41935fce7d897450ec654793cdb2dd4a4f5c5d6c5e1391f8e97374d2665","0xf21195508176baaecb64a1b00d6342f254d6728c1cc2fe96273a756527d19197","0xc350ceac31c179d0e7ad3cf6adccb982dbb293e2fbdd94dafb85986bf0ff6caa","0x53ec4995dfc3c9ef865ec94b8c27f76d992e1e9851bfec5b48d0f90048f49179","0x4911c6606eb907f602e3546fd4f2ecbfdd4c65061098c6b8f007662a51fa24e4","0xe6102c90b5280c6d9df33114044bfc73ed32f51cd0b503f693509f9b205f76e2","0xff1c9161ba35daeaecf61cf4f5d1d5687c920c9e439b736adc71126d581ce181","0x1a3c7353b4ba3d79cc38dadced45b7e25df87f13499d18d5e1b29e4fc24b57dd","0x5d1df20f18bd0cec6b1c5944ab8f97a2ee5feccafbd2b9cdbf1caa45989a92ac","0xf9eea45b844f1020df6a884b44e623bcf72d512508c98cd12e2ef74d3516c0bb","0x93f704bcccbb9ba751408bcc8faeb083fd314b361b10ea0d6a9d307b7d0f39ef","0xd5691144905cdc8be0613dc03d99e89ffccc95de38607e5a5730cf64ad887dab","0x998b0efaf83d530480bc2f8486d06e49f4dd012bcfec2b14716bc8a2ab1108b0","0xae8c2e7b3bc51289c663afad884e6f6daca7cdcf99363bd0a09bbdf91f589d41","0x0418597080d1dfe5388465716304d1719fcb66dd9a63d3c2ae2d1c4a10b5ba2f","0xd627c4df9eb149f532e10c5f78fab4fde60618ae05f3a694d25389dc1db2bccb","0x9cc72dbf246616ec49df86bc82eae8b2214047a06138c91a9996bf9910b77e17","0xf46c684c040e80cf7564d8939d07937c1aa9abcf24d716b15077f910210347ac","0x62258a54de744bd892574121c17744d4f3b137c24687ae9a15819fe7c67acba3","0x71ed55cbcc39f8c10ed588c7f9a121cd484033a666efbe807288331a50f5699f","0x332b1e9529f32d413e230287d383a6ff00cea350a91baf248ad17dd7836a3eda","0x812934d4ede62c8472f675bc823db10d99bbebed7a1eed07faa519093f0f448b","0x86eae7c39e6d2e0b68dcbcc84a347b5dd75a34df2ff6a77f61ed35e313ce2101","0x0b7f6244b34fe19b7d042a3b1687cf68b3bbcbf7432a403d3f406c71ef03471b","0x14b934b4b652fca90078731a8680ed4e19e39e0687c4d8bef6379593d0fbf548","0x7794d9ea601178f32e704836b27c47262d071b3ec8e1f9c93eaea97e7c30ca03","0xb8c7f8110c79cd68e9123cf85fa8b394e082a03a6db4e7d2afd23ec8748c19a3","0x063fae9fe4fad23c9c6aadca32c12d39782b965fbe04bd95f4adae1b4765d01a","0x2a34281365a5574e41673ea33eb69c4203f82d12ea756d1a6281d1b62065356d","0x9609d126b065ae8d0a8361badcebf87ee1c3f451f2d9d8439ca6c5cda8ba2966","0x9f4eb5a6a433a1012e7e3e04f5267a4122a9cd457dcf81b6997f95370c465d86","0xccbe8a44e214c38085bc2fde4db6c91868b87547a1414b84b7885944324ec680","0xbc1c1f1145e262f113a58289b435ab30011c914ab890cb9bbd7b1113f7505d7a","0x23cace3a44637f1ed058daaba6ec3218606e52e268753cf9c318722a83a56bf1","0xe911c5d92346b2706f4d2c1c29fa42e2bd98bca889a85ec9143fb3e2fff29910","0x46138c0eb5885b798f9f7416c3ffec97a490ee48f308f8e548faff58827568d2","0xe72e3d34b1518d08da6467ecb6b9c9ffb4a0361912f4ed48a9a77ce35ab167d1","0xb6e86a592a081c97deab4a302e381195a7a94d44173d4387cecec10549e55336","0xa13ef24a63767412769453589601e58684ec37f3b8baf7c79931be757274d3c2","0x8bd61a94a537e9019174cd698977c184b9c4536c6991f30af6e2c10579e5b4be","0xd4bf2f56891e51908d400f95783214e8e5878cf7785d67a2840fa45f65914c64","0x45f46203b7d59dbc1e481d0ec070fb29cbae137c4e86421dced9cb1cfd1e3dea","0xaec73d95b30e3e7b1ff02f932fb8bd09bb4b74349f8977d703e178fb46fea8d2","0x8a277802c77066f8dc136d6630a1764a83580eb87868d40cadfa19d4863226d3","0x3cafb07d0cc5efc631d9be97f52745898379d03e1bd772c24401817825659071","0x27ea6cd603c1dd54e69170519b8ca8d5fcec3bc26fa5e8f103ef8552eef05696","0x231d9706ddbfdc149682425d5c47cbbb58c0473ee7317b3e899f171b686ae0d0","0x79e21ca6088ffddfa4138aae88f6c9d9ea9297e1dbb07d1fd1da615beda7686b","0xda19e931ba050a4b08f7bbb481ecc6f61fbc4de04b24e4f77e79f985477f4d18","0x2ca6a8b7c75db418098dcdff052a5b18bf2f1599714cafa29c5279792f8d8342","0xba2b5a45e44bacf3186e88baa07340d28dc9fde3d3d710a77e5904745c74c168","0x85f80c109b068dba30eb2a15bcaac103853f23ef6b65c7f623e08881558850bd","0xcfb8517726df78bf3a006257808324106db3aa46a269ab333ce6b38facfd221a","0xe940722be83899f393a6318b4a4a7c2c07b029b94ab50a16a3b444616296ce1b","0x59432f8a69c2df45d151af7d3269cf38df1e889f07c9926dd1643f1e945eb5e5","0x214edfeb8287e90b474a0fdfaed3af40213bb43da202b384b47d5bdc179c3e08","0x795f32940c5b55df29cd88e3919367c9585a83afa910fc40966d24e0cc47a22f","0x5102fb91905203317f040ee360ab2fb544c8c3e85a4cec980d1e3cba7614971a","0xfede991a4cd60cb5e46aab57ae86dbdec4ffbe9abcebb50c6074c5f1ee515878","0x2912cc4ea24f531983fdca42a02e54e8be806a346e1fdb382bd42458f367fa7d","0x59cfbf594898b5d548d2f94afeb35b2324b63b1247460640abd0e87f2b4bd6df","0xf2c077bfa08bcb5af2b2bf7d1997a80e326f227e4b0a2dffd91bf83e5c2cb398","0x0af36ae99dcfdfdd7d155755872775f67c2e1db29aa4e9ab0a165fb4433a5274","0xc0fc42747029236c000ff350a2155b619d43af6fee894e0294b419d729e9bffd","0x9c64fa2cbd6e4a433368bb84d020f5c48c995a7a7537035ffed644ea9b74c6cd","0x1e8de86a722c4e8255ce284fa851d4e843e4615702e0a32a30ae532a64147e4b","0x3ca1dcaa115534a4bdec23af46cafb5d7411648b274a14ecef41925c5728b3ca","0xc09e9f28205be5e5edfb5cdbe80ecc82edcf400c43ac9337605edd6fa5239d03","0xd7c9c8e53d6c5f0e1cafa1d5710ba9beb364559950ca6f23fc7c098d9d63b9f6","0x726480d0b9850c9763bcdbbf71993c30fcead707f8ce1cc40defefaaf314cc64","0x614c6d967839da737832367bb1c1035c152a971f14beb0a66a90d2e4f4ed201e","0x7a21def7921d2fb4f652a084248aa6a2383dea2184c577f1d9238d1fb78e94dd","0x92e466f6967dea9dcfa547e0cc98fe939a91d37353fb681d7f47111586273ccb","0x2cfb79e32b4aaca157f6dc480abb96d985e3c1e95b96b2a756aa89dca554431e","0x4c43278272932c202fbbf8e071cb49dd52a859d6be4c3f889ca5038aee62bf55","0x5a42462bb646064284fe6cf0f135233d7620f7db63081beb0744b37a06e4a372","0xe4adee5c472c7fd7f7d38edc2c2fe5938afa031d8e0b9ccf8c8543959a267674","0xfe74d7694f71a88cb3f63334d7be16ac78d68c0c6a155db9a8bb8fd521ed954c","0xd7699105cfa055cd9b54d27f5480126c8f8559807df8d941a008cad4fc2c8c31","0x03f8985d23b6bf5cebc265eb1272246f3479a6fbe46097ad3e35fcf23c58af86","0x6ffbf6bf4903f80a57ac34fe63f5db17bec6869b37e5a32b6acce782bf8693c4","0x4f49a9996b80ca8fb79702d9280be4770ca31861527e84472c2f8026803c7a47","0xaee03b03492e671deaf91b088f764d4ed1b6dfc4a48d2f6f134a7f761115dc5d","0x4d2e2bc06b144219241e46a68b819b5ece0cc40df50dcec0779b9287547d6fb0","0x3eb26a9fdd91d44f1a7096b90064d1cad3d869d65baa2f7c9db97c887c0be1ad","0x0a4c4971341057803e5da25f66c7f7ee885a71a2a790fa258be896c00a5b49f4","0x6f8ca64d8a2e60d253f82b00f99eed678016098414ce1f014d02324eec5d0481","0xb34a5d0cb4c8440ee94af010959ce075e5241e96d5204de73dade481a2d43cd3","0xece534c7987e175d5d727aa1d5ead60d797122cb33e7e20bdf76b255a282bbc6","0xec9858dd72d243cf7c797ec5fe14f0c2afa3ec8473a54a4a22901b54f38d5dab","0xdd283ca9478a9364d81a4712f7c6023e84f3eafa1cc06aed7fdfbf1f375d4396","0x64b63f42d3ca1348149cb1bcc6ff2f6f48c76ad5b3a70d3f577e67d6f9f9309f","0x877b925e747a60d56d8ef333efa5c69c1b6f3e5669adf1c899cb25dbfc78dc8e","0xb3e6b21fe48640f8e5ae4bb27d526a530b1d6be74ae40666ef5818b59e124308","0x7e7ae3ec301b6fa6d6e896b4f826f4652fbe344bf88aea371fbc9002c2c05056","0xd910261b85849ae7bdf7ca1b7bb28b4212115e37f9af4828c98c7e39bdb9fdaa","0xc7573a030fcca9c49470a29198c77a2011d3a903474a4922e59ec27f4e8aa500","0x0f8e8f52e682204dc518605307fd9f5bacb43ecd81ebd433d8b1c9a6685a43e5","0x55bf6f895be015d53945f26fb2c5efa5726a1a65f2d188acf117a24ed5adaf0c","0x06f7bc2f8051648ddf78497cd86b336b92ebbfabc6ba972d13b95258c294496f","0x793f218f30950493924b21c80dad85d164d60b22a7646006ebd754272dbb7ab9","0x2b94cb64f38b6a210cd79e99f738bb53f28367d9e667d7c2ef69eee09403e4cb","0x3cc22caf7d8b18481e1ae4582aa64a37f5ad64d96187f25f11cc233e63cda150","0xe130115cbfbb50e3c7ad2014fbe89932918824189a1e0f199669daac6f121f19","0xeb31a7fcb70b09493e95369d2204bc25e72d23200f9b0f02e43db3e0641d19c8","0x133c3196736cb099621d1e5c40d9f92dd1d1e3a47843b6171d4cc04c86829ba7","0x6fad3a3889d8a2603b8435cdbb40b5c8f67c4abb04972206f579b84dd8482bd7","0xd934101caa2cff7aad315bf5595f7c921542ce2f612243b307b769b96bd05d7b","0x5bb8b802a6deaf658306e0619f3fa95f242fc952f5bab963c97b58bb9580f16f","0xd8a1d0615c5eacd3284b20805211118b7d4034079bbb8b7c894bc9a1dae6894d","0xbd78757d526c677c1e54b181228654072379da6861c90f2e65937dfd3ddc3980","0xce7df53fa1fafbce4d9171690881a679907295bc778fa81738fe4bab4f66f046","0x0af2985e0812129e2bba16c28d4b5fc6dde3ceca1a58354bc53ffd4c4cf9429b","0x9c5b41e9b548ec6a49cabd67339afd81d672c4afd66c7508c0ff32c5e299359d","0x4444dec0eeb90bf5fdd94e4907f45ae68f786741950b210a6f878055b3cd490f","0xe19ea34bbde0fb2f93b1cb0045111adc76159deb4ea9bf1275fcd88d8ebf06c0","0xfc1ca6dca980e4958746fa7939c8443f5f8f21a76c3d35f22c910f8161431041","0xac72a22bb9e14ce1b1b4b334d45e844c5cb8d792c31383c2e31867c8d6991780","0xa73b8667899df0d80b3ac0b3d8fe68b43b5ba0aad9c9225c1c5de6ddef11df12","0x30bfade008f6b4de11440ffde43feb803df55282114a3692615d439b6641620a","0x19bf04db83467f3a64dd8186446c6f0722caf6e9c9ff6afed217632b9b3aed64","0x076641281dadbc8c0768c768f3feb93019d8b2a0fafec5047a5968cc4edfa159","0x89cdb9210b274fbbb2d7b741ed90fe40ae58e63a1ce6a4fa6169cb15ea1e7dfe","0xaf045f616f86729fce7a2c34d1f7fe73225411bb7400c8b0e5fba526e3d5cb4e","0xbfdb0353608ba4153fa1b1653b3fb1445f8bbd6422ea7a99f904ddd32c9b1cc7","0x3aac8cd56d596b0ca335ed9ed7a7fa04d7c121871db12618c5af3b2555e8526e","0xb4f44ee84b82d0337845d7a5d11a381ec9277500850614364ca3acfbfa358343","0x36f0def5ece9c817c5a125894227f1f87ddcd6c075c84463e010c2766cb6a03f","0x30aea76b76de68b241052a1303dd013074f4d46a53bac0563b0ed5f2f588ebcb","0xcf79b4b4f1bb3a17468a9f6eb9759bc490208467cd478b90d763c3060d83c8b3","0x95eb0ed42ad1b68ee9a6864b59284c05692b6d00506b80665ebd263905d12ead","0xd07efc5c0fd133ea1dd377be604164a1a5a6fa868b4d234d61581fb8eb579644","0x01c3429dbadc616ea98209b93a90786378105820246e56b0edba1fa3bf0edf28","0x741301fb915ff4bb26a2b85cb435aaac9a77023ac75cfe395b327f69a48a8f00","0xb8491f4ffbef407e8a836f2ff7a9db9dff5df5c8687cd968acb7164f94b2a64a","0x7e998ac5ae2a8cd88c8708e2e20f061a1b1bd3eb9b301a7494383d4b379fd8fc","0xcbcfe54debfe301a1b898864de3fbc44b96a56a4c639c449406d858cb06bb56c","0xfbbadd96b2fbc1275b7e316667a0a16854c803d41eb0ef89d6b86047b1468e72","0x035cbec590660c2aa6fa813fb8a7e68c8ef656d12c7155b7076d4160b53b99fc","0x0bcd106a24956d21c1591a26f3a90ec37f270afa412b5c1c882d98a780d86cc8","0xf7474c2219e0c5d54bdb828ffaa285bbfc779bbf3fc6d98da3bd9ec7e985deb8","0xbb918d75a120958d98c20e5b3a561a79edcbe64319cc30935d8ff69c1382fa70","0x6c46b65f88cba732b3b1863d560fc42b2daa4b0c8c35556472a27e52a25c2d54","0x49bd0e85b9cef873d50e62e10de03d4138fd425db32e55d17c1c4c0c79871c3c","0x27e05501152a8a98ee33ecdc7f342bafe8325424b7e7e065c88e08e9995c9365","0x0ed5062fb9b83f37e6ec9e370895fb0753f3c17e4ace08430c6b5e1a224ae9b6","0x947ce3f5e8645ab6144c6b04772a265f432a9b35b6e743b293e620fa3663ee9d","0x4097cc087fe194066400f2238106b4e5fe76103184c42b56eb6cb3cdf7dd5e95","0x73464e77a4f24df930e851df3d828ffa41aa5aa71a079ee3379fc803983e0825","0x22e92f9816374967bd53c0e3a732dbfea1098670926df4c9930641cd024b8e9a","0xf1d137505e6b923935135afc173e3d23aa5d7ad1386981a3fcd6b8bd65abd682","0x4cc947fceaf2206f3e353f93710e0325646fcdfbb1fce18ffb6dc11fd4226d08","0xa2831f9a921a66cb8d0d583f6b31ef7b9cc836b0a555246f9b91ae4c2e913d48","0x3a7a1e9e7bbe34bc7c138b718486c75822091d4a93bb71fb4342cb033961dfae","0x6d01238abb0b75d074ec72596208f0ff73a8546395fca91ebbbcd948734022f6","0xbb6cc516a6c43ccbfc434c07c24ca349904fc716397d65b117bdfb40e6d93dc3","0x3023970f347efeb893a1cd68464e09da304bf5702e8854978574098c7cd7fd72","0x9f4994c58c9e19b2e3feaf121b7bc6ea065ad3f66c5fd8ab86b4776f15ede525","0x87eccef7167fd2da8aa956e86f6fbd1e755be8334a47258847360ccb1aba1692","0x9c8d77ceb6eb3ce8a98c080fe06049bb117be95b1a65995736dee0ca17f6a32f","0x8d1b5c900e10ea92a6cdf211917a32e6b083f287cecf42739c3a4245a28e68f9","0xd40976ee053bc864f60e99ebd5f69f943177d115c0fce5b7a66671dd3dbc45b1","0x575eda10cc8b6426fdff71f16f86ada707b356282f167f560f50131c8a605695","0xe753dc176fcb4b236a94ae565a645233d1e30ce30f72fc54a40100c50809dd80","0xd3677f3b0c323f6937bfbb4f36e7cfe908a1e2e91dc4d95b6956fbde115e41c7","0x70ba6df851e9d5debc146293de0896cc4066c2939bae748c64f8f08aba04756c","0xdf10d44d4950477e40888bc470aae59e31848cfa9730fdb9216e0b8448f57d26","0xcf0a3ec5ab28b130282a3d55cc1e6163c256f7f8c7c4adf95106c5dec657bb58","0xa783f0deade8c4570c969b5023307ec6c9310b22abcdef3371f64a905a57d4ba","0x2041e6a458c2f805ac2190ebd187b376e9aca3cb70a16a01a76144bc1d1d752d","0x7d2e5b07c7d14cee0199ad938c0c0de8c71d2d48a692f2e180457c5fa21885d5","0x8420156c84aac3ecf51af03864b77015bb634e8e2b18b0f7e36a8bb765aba57d","0x42570a1a033ff0d1ab05c5951099bc2d8960b4124aaa448cd5c0f5e0ef883df1","0x8f4eba60d2014efc0485d2cf3f53b1816f57e0f7dcfd36a186212c70e1e84f94","0xd6fd936cd61f9db350262bb17c43bc6e04864ff5a65f3f8ad37a395d7b2e07ec","0xba391eebad41f6b5b9b261b21a25e87262fe80c4bd7123dbb2ce193a6790e88f","0x838006b3da890d00a279f7e5492f2092d0b1a6066b0caf51bd16a3af0a59077f","0x1e63840cab9f66c81a292aaa5587b57c3e29d20478333a7ebd22e40d848cbc6b","0x99fe8853d2ca4de5ee26ec72a40b335f94020ac2705f36b7c8d0a2447b657f4e","0x592000c4bdb50961f106fbd0de3abfdf3c2c50de70a5d6935acf970c9d808125","0x844b10c97c57e9004eb930886d7f4e856e8d70864a0fc725310a0dba46152d28","0x8693a533f98e32f55d4177299980fe56de9d4bf33062df3f47d8dda049993699","0x8d30bae931552ce82af666d8ccfe235ad0939dc4418d37394bf9afdd1a2da64a","0x2bd46e9aea7d27e03ef06eb34ed367588489f7d8586426b99cffb65e6b15eb81","0xea90d5e8c888649dbfcdabaa9c7af15b10fdd42c518d8a4c8068336f3989ab85","0x32463231176253c2e90d9a95245a638fe0794c282ffa4f1772875d67d54a0864","0xeed0af8bd3a6e5bad3d1d93aac0382592aad1496544e66c6ff1e7a85e1fb04ea","0xa93b4de10dd10bf30ca6bf19d74ea0d28615be16db646075ccfb691291e4ff76","0x9a11792f8618e3ea9be6b6532646c2b0fdd57f43ef21bab085d966585e6047fb","0x250ec792130fdd7fb7e0da04badc2688e4209e795a9a5be767df327e35b6ba00","0x056c99b1c97e224edea94979dd089d4a8081d4f823dd5062625ed7b1948826e9","0x3365ebd1efcea478e04ab6ab36f9a65695c4e4ddcd0c0a2556be7767fdcdf39c","0x998550e30a3300c7c17e97a34ee390e456cb883cdaf3c72e0eace5f52c3bfee3","0x12290422cec24330a31af961856fb8238c27a39e5d69c66b9baa6d44807dc023","0x0bafd953abd0b9d2be0ac141d06eed2604213f579dcabec80b877aefb5cb65c6","0x69273b35dcd1a591ea554f4a85f64610556f72c503617331badcda062d0400ae","0x0e4c0b0b1a3e304caca08bc7317762eeb82e5f17aa4dba6ff25c57a1319e8093","0x7f1e85ab58b6b89de26752fd94bb1f408ad7a3780f7615983ed9915a2cbdc23a","0x1dba8ba1c7f8383648aad985fd16da624e084c87b1ff8b99b7d5b1e943f41277","0xab37171a354c802978d777090d8ec933cb2c329965f9c201322a0365a7654e15","0x6b1b354fd45b9e93eaada21543f1fed6543ef07b07abf9020458a4e5db9ae14c","0x333c6d7cc679ab3cefbf033141991b3979b9e536ea7a9c30e5aa6d267c94426f","0x65cefe96081d1d3dcc771c60986dd1b8d874c25c5a96c48f8bf9378937e90690","0x9717ae0f1316082688e02a44dc41b52c9d00c5e6d2ce7d98cc57974659026210","0xc380c16e4ce49c9008e2f39619b683517ec81e2727a285057ae8cbc3559a7500","0xfea418c6abe35e70b7fee46cd52fa30734ac35576a7f37c67150e9fad743592d","0x58006003b437a3f6ad3a60bb52216e284ff4c5c77aa70a091a4665a069488390","0x3bd158fe1af6105962a956f76a0441d80b44b63596cba59a0a7147eb7edb3300","0x18953da788a6607764e8ff52b071c32a942256181689c16f7c6ec9cf17bedbe0","0x1fa6c5a883d750217a167cf1ab8fa84531c9284e66cee1d4429072457a8ccf71","0xf5b523f0554d179a93f8908fb944ebfef432e2bba0295dcdcd138cd07e33a426","0x14af1e46080b5a47d17a685f0965927ee8c13df3d8668395b533a6b5a9a0390f","0xd3098778bbb5069ac27928e321375392d97f1773cfee739aa093b4fcaebb29bf","0xf716a8394eb43b50e9def3fbaba8eeff510ba5bb72e06ddd7f233bc54b08daa5","0xee58add918e32a0cb0f5187aa24a0eafc72fea2a757155b8a05e18767fde6db0","0x405c9557051ea7912ada3ca08aa4a59a9a7623ffdcacb487749ae23284c2cbde","0x6ff6235095378c826a4ce70258b1d74f09df20987a5798d84b3fa06def926563","0xea685a126153833c88b7fcd78f425ee29b6e0e546149e50ef7d05c72d9d04a95","0x66c4d247d101ea3d49598f37e6f5d47e927fbd6fd50b2add107f6e21ae49a119","0xc0e780120e698a8e27393be9b1c360a50556236c250ba09c3b31665df6abe88e","0xbd1dc02c4c799a7aea89867d88b69412d66a4484fe178dc16e3fd90c68fd3294","0xb4c3c2fb699f60828b0dd6d3ca91d9cd65ec2398268824a4074720debe3caca4","0x92084c055834a7f9f09af784f1df456a917e85210b96b5fce2afb34e14c1f701","0x3490f6f435f9ac8ab2cb27d7bb7f0544a1d8b72819bd2358ee242455b54dcc88","0x7fd1e714d5ceadb00551841b228505cfecbdaedb0f130310a16d9273792eb9ee","0x1c68549adf9f4b2578b0cfa962e95c63244bcde78d10037f1adfc2d665d87a24","0xecd4764faca92522a8b70b28f9472e968215d65d638d0d21cc8ca456f9bb72f3","0xfeff41ac99d0242f3da62dc3e68744b0df83ad8da08173027d53a125366b842c","0x55d653fd6f8c65c4fd726ba36e687552fa8b2addd751022f96616efbb3437699","0x64b13d45fd4d452b29f2959d3d43c048d44c7085da1afdd6df0dc106244fb3ad","0x03dd4b0314f5c6f35da0df4b4bfb62bca6f202be3ee56cfc526c9c7e13aa20d5","0xe10c98785d368c0272776a63e8cace0908bbbe1f67c53961d93cfb7b03fd4456","0x377b5df49195db50c62c9a285b8560c89791d763c5acf30aa047494d3590eb58","0x55bc6f180e3d56e30ed37c582c50e64fee7e4368dd2b09103ae67df3bab1ebec","0x9fcaa55220f11b5a3f465c6574e44fb2e255a0322a62295b15c4c3b7349cfd8b","0xc7536cf9ff667f0da0c98bc24e2f5c9c2cb9ec1ba74dc85f7a724059338c30b5","0xd18a9f2ef3fa0c0b995376bda9965b6810f1ccdda51f4705230c330bc85c3d13","0xf93317de6f1c3aff210c7ea7817ed8ee220117c908b439a81ecea119ec6f49d7","0x405707142bfc88492f81483eb64affff21c6fb545ab62c71599886d10bce0d4e","0x21fdba7986344c07b2074fc3ab76a0bd3bf8581b15d77488ceac5cf5f8f34950","0x0f971c54e23e7d0cbe9b9791bb1b1eee3773084fc6e2daf1fe1b9d2a27d62f56","0x0e20234277899e8f6a338a812d99f1a46dfed9cbf2d8f9813bbd5e7d7820c0b0","0xf6ad62dfdd26d4bf3cc337d58e8f3e58e3c717528118561567ea9f6ce481de5e","0xb7845d048bfda10d313fe0f22da66bc0d4ff12286f6bf543525b12c3b258eb32","0x10ad9c4afc4a711c5625dc7dfc7e9bb2754d2484bc6645873c35a67707de2586","0x4413da1f1719d81029a746a339380eb03f43c529f69094554ae6d5aa12129940","0x99f5b5ef38f23f8d159d602b635f11c7a5d3515cb9395945aee695bcc9b1c5d8","0x80e1390f5d2904a8c2306723117984a00652cfdb60984404dc5b25463f91d593","0xe43eac4ecf74a2886822db50e973e2db720f0ad7cf681bfeae314b47ceb23236","0x2ababe47d12217ea4fe80659c4d4b866e7980d4c061b2cbc2482926764d0ef31","0x1db381b43fc25d4f3b759276c0db7d4080b2c339c28d4a31790958e43754b61a","0xeeada2cb14f6f88a3f61ae11c363fa1fadbabcec9c6af732d2775c2c0561dd6d","0x42cc7d72a08e76182ec97075098e8ea3c197e274bd286b3d174127a47872b7b7","0x6ff4423613dc373cfc0243bb37b6ba523ca44c9b32c94427994ccd2d8585d032","0x13f208a6df9bad7bd469c0bc5bcaa80fe9fc30566440d2babba0dd739a41e095","0x6bad27cabc9ebb35de4670505ac452ee7d1dcc3a1007387c1e10934b61b19d39","0x85ad3be922702ca859952261b2288f1d30512026e3133a4128a0909318cbd05a","0xeb11a6ec5947c9a4e46e0d178daf43c609295f30ad95ccfebe3b8f9224166536","0xbf725f90cb5f5dacc8e4a09eccf3d32f156cc8c050f440ac8b9c67ff5249188a","0xf306f6f541207f3f04a677a3ad3ee9f618d7d94e8c839376c74141a54d6b2b5f","0x69f6167967d8f599dba68067ff99a36b8809f6ccd4f0bcf9c7172ce4757a8c3a","0x532b77a431321056f44e027fa077a4e9a3858ced0c2942eaf28a182cfd7d8ae9","0x8fe7f22c99f97d6c12fa3d671879b812bfd3ccc9f0dfa52d02707ba53e15e487","0x2083141cb48e31c7969877add33f64c0d25765bc28cf5d5419eacf44d6432cee","0xf3e39ae597282c8ee36723e518b56267b81f601365e0869a3f14c5e6c8390e2c","0x356bce26f4dff62d738ad5b839bb4bfdf7cd56c7fc619fa93edddbcc0ccc7dde","0x8c58729c143be8e61f88f85b15bc8a6ab6f67eb1e9300e60c2badd883dfffabb","0x74d0adeb2b0987d9d34e298172b953c37eb6c31bc2e6eb0957e9cc1a0c30f7f1","0x6d0bc9644a0d0ae0cbbf6fd984f80e1575baa06bcc919a97bdf24ae20011b6b0","0x58023cd9d59adf5955512e608e4472c54e68ec6773ed2014a857e7cfe57cde37","0xcef7d3bbff7b82e730adb002b077308232ed508e9cbca1102beb26a8e0f63ba8","0x83b85c48a5b455e98ff4b70c2cdcba7750748fe9fc70f7fb283e1bd4736291c3","0x93dfb52963ad8a5df07daad7d5c9b8c9e9fbd6d240fa84df2804492fc0b441bc","0x4a0203da7bbf8cde458ba3bd8a0f9a30499ce39a1698ab79f7c23529b4356e5a","0x3c74eb2a4169c061acaf9b98d5ed8702f75da9f07114bd2d15eec81e651c1052","0x375cd56188807db8376943463724d559eaf2533cd4e8f2c9056698d91520b5e8","0x935707fbccaa73ff310f1b9897ce91c0ed7a9a33e7b89b3a2fa5bda5c64ef68c","0x4dac6a66248767131ddf6087af544add8a28f4272288ba15cbb0e1b87b97036a","0xbd5b7042dd2910d0d7c59c39534c23b00cdb2e5ef459a53897029ae4dcd01871","0x9671198981cc4f19420cb6a8faf432f2abdb78665bf914a209d413958c990b89","0x13da342988e7397b41636a4de5601792567a68638fcdf98c078b82f11fccd830","0x2b524d41f8cf3e8fe76dc91d000c13d9c58a0e131650fc51bd45114034187b06","0xd5b0deff2fcc040bab2f7e07fa24475e894ce38fe92ceb8bfc5b27db9fabc8d4","0x01498db3d8e69c1b72d1b21323caca06dd890341e6cd0451c378e2dc3d43a90e","0x63783b6ff3f0d4517dbcbd9d1a2ac54452e7f81d56c4f72138a3dd8f4d28a38a","0xfcc300872b2ddd967dd3780b632afe2ac3731dddc7a932e412391bb25fcba209","0x3026dd7974936859da2bd409e2fe659b8c7f99cf1276e9dcf5fac29c96bddd98","0x978bade55f7bb733b862b1ec9c2dbd96da018db1d317c646dfe771f54eb77c90","0x758175da3d08057c5ca7bb4ea9c333beda11f8b31c75bbbf0ce24f1aecb11f5d","0x48bcfe25b4145ab42be1c6a3983db29d09a569037a2bcac786c2f0271983fb67","0xc59b5345f90ec3b24cb5cdea969bf27ccabef6fc839b776a7cf1aef5157ffb2e","0x6c76cd87d97174f7b6c7a567eff75d74a92582b393c9a236f68de783d56cf54e","0x71cc21e84781a6ecf366d7d55121cb3ad7400580dd04283f496f78c3f13380a5","0x53b0e91777040fdfc71b39461d9523cd788959179f06e5a7b6f02d3a4f2a7f94","0x77f24bf5ecef8e05c36ee557ef559e8944867da0b255bb627b5bbb95342c683f","0x853a52782856127f5ebfb8ca1ce5bc8a7a3a5f43afaf3be22623641ef64af82e","0x03b45b3176f6740714037df6ca6fb6a8f39d6f805c6420a15a3e5d66abef1871","0x9eb3160d33cac300a964e324cb703bbcc81c024799e6708a59eedeb02b630cb5","0xce4790cd8dd098a5f368a938b93d3e7dfb929bca9a1f4a126c5d890fd20918ed","0xfce172131f1498e45891d6c02b5c40116090366ec4dfc48a8cde03b1f0585a1f","0x8c5584a6ad336031e742bc3cf38487748d333202d0ec8206af67d6e54facc027","0x0b25f6adb12cfb5e5b55199631f41ad8b8357dee6e6e346b0456545abb7ba3f6","0xc1ecc95d1202dfcc3e92e42baee443792fe3f1c35670473cd769b8182d0a6c20","0x7a00850794b4540da9feb4f8841f7ed7b946abc2ffe84698afd78fc13b7316ed","0x54b56e808b3b4c70b1018b985391d5a0673b19116935e27f7c88b0653610c92f","0xf729d73b37f5f52c870a2b28c5bbd3f3406d5404cca3711d6d1d6ee87ec9585d","0xa41a5f06541aaf2191b6464d8c7c0699726b05f5efe2e548ac889007424f7cb7","0x915b8c46bc0f38e0174a3b37785d1ee611b199816791107e70aa077efd239036","0x9e1c5143c9e57824b0ab942047bfb464425cebf4dc46c3e85da97ee82e32bc98","0x767b5cebf84008616e72eb71959d4fd9dce0e6b9f037b433578436ad73192e73","0x78c865c0f0e429776a1f0000585721e9d0e597b9fb0ddc0b0d5d2723dcc0b3b6","0x6974fcb1b8d8854b3547c047f4cba482dec74841ea511488672e95515968aa2f","0xd86c149c6239dd0d13134b17c1ac38fd945ab4dd9d8a93e46c210fa99429369a","0x799d3e42e518fa01f3a6547243d374ab7decd7c9a7dff9a18adf5494da044fa3","0x9d24fa061317f353601d5aafdaf5b0b98d4a7b102a838acb353cee5e649f5136","0xa39ffcc6f5ac1e4959e4d9f1164f25290996302b702282ad921e5adbd6623ef7","0x661838ecd840176ae35f14af8840577ae2abe389c50dd310498e0a7a90b4572b","0x6ae31aa75ca40c45380d9abd90ee8135c79fa2cc6574b95977797e92ff40b35c","0xf9ab8a45cd37ab4efa78c954232fbb9cd26286ed18018d04e1ed62ae1a6ced74","0x8f3f805ff2e573b0ce8b0220c33beb71b77c888fde00850d458ab69c6f4db67a","0x1025f47ebd2d1203c9f260c11a347cea637aed2a1fc6391d24f5d731b6fcce5e","0xed65690807d7f5fe11f340301e6f6362a0574586aa98604da0fab16fa8c980af","0x9debe3ddf4979f24ad5b81ab3268ecfb95e1ada8a1919b43743ffe4150fd73f0","0x68b506db0943d5aed4e2104ea3601da195ba3ce53b723da6fdda01d2e6d5ee1d","0x088f8087c8bdfe263d3f0327d6980a63e81e5b86dc1ba5d982f780d7326f8f78","0x8832b7fbb86fd128d9783b2eaed1414769e637426434245c3a751007839cba7e","0x2f17cdd13470d45d568ba9d87a64022c925b94f025e426891d8152ba43456ede","0xe021b75013707e422efff024d9c08726cbd4667c625133d69f40a613c981938a","0xb6bf7c5ede3af77edc09337f5153f082acfcf2c551e07822fe5a0675bd1af7f2","0x33aceb7505a0860e58a2a94dce591b17c0d599231be979936cb542980dbdd5c0","0xf6d7e70102790ae64223e5ae55d0f28fdee4c47e5023ff52a92143b6cbf7b0f1","0x9bd55674dcef2e9f0f1fee294a63aac1a99956a6557c8c8290880004b35a0463","0x82781a87fc1f270b61e94ef5bf7f6c0c514ed6d741b0d2c052f2868955f4564d","0xd3299ad5e8aad1feb222869c9df235d260b03281ee00e240656221d390e6a4e9","0x0fe35d2bc0274a89bee81ced0d35421e2113795a6803ab166afce9ecba10fce9","0x84e901d04b8746c688030e4c2c4b06fa239bd2bbd6ddf056dd03a7f131e5bb4a","0xa38d3793a74853792b560ec276aba89fab2f15f6798105445826789c84209277","0x7381fdc2c49af07ef9d9523d7ffa244ba14e8c32af7a3c679cd4e3a1862f2d5c","0x38049d6c52bd326628543eb4758f15478412ebe3956da7dae474ca06de63f72e","0xdfaf46eac5eeea128c4630ada92678184e00517aad8a786a55b6771b4250668b","0x606489ed6643ab1b64ddcb56fcccf0a3f4735fbb3d5211bf3f716f8085565232","0xd41758e6efdcbdf4fdb8e932b5480f8ef71dec7b9676a2add250471ed8a56a8b","0x322f9fe6d4abd7d52090efbbc454e7c3b316a438e0170ab19a30fb6fcbaae154","0xd8647e16c185c5cce5c0c60cbb92947ef82f2cd0212cd4a9a75a637922d76bf3","0xb1ef3d37ee7620ee5061f3b0ee354b5117405e4279155c5dbee65724aa4fe3c6","0xa77368ef021dcbbcd6b4006eed8b0d0fbe85a93421210bf46db9f4a60bf8de37","0xbac6b8cc57cc77f06fe65245b01eea2be0e3c5dfc0576d1806731f4301a2b6b6","0x91f139c095730f37fee3397551b1ff89f2643eb13aef32140a36e321ca16716a","0x099ac88ee3160859c2cacbbfca11f2db146d7b371c1820cf524cacdabb7132d4","0xf4586fc57a258ddc6a058d08b8d46c2672a0d01856f906acd87f7249f2431602","0xecc35a372f3aebeb1320262d911adf0b9a2b3336d3a471da373d13b8adb958e5","0xf473e5a53c426c05f154ee1aa6f33b252117e4c070a8894e6cd9affb99b49c4f","0x95dd7fa5a4412870513ce854ba0107a72a8f16d71527762c01c78eefb2c050c2","0x36b4a6fd91a17d621dd15e2ce0c71d9297f438529fb1f10f08f8a7f77b36598f","0xab2cf03df11690b869fbd5877d356057f046e72e675076b4e6aba48cc581f65a","0x85af6caf8bdfa5933f53ac450d3cc4c1985445a6cc7580a64c2e8c0b536d05c3","0xac6e377ee794df0bb55e6090e5d9340dee2be43b8c00a3072f78d9b8407059a0","0x3d9093404e7922807e0d1af7082fa7233585f01a6e1de27d890a04aa9c9e22b7","0xde531c6845a0874e9a21ae8fa0a628d2d7466fbc744815891b596e346d020e15","0x1cc1018c83b4f0084ac204e5c7d80b32336711812449996bf0794463fc644d32","0x130db35599737ac291505531e8f0930b570fd2023f28fda5d3600224e584c998","0x6ee194e08657d878380b036b1d31a40007cdafc057d4f1421df213f65fdb405d","0x26401ba4320c684847817dbe77e2e96ae1183cd80daa47c76fb32a0229d78ee2","0x580504d6cc84cbccd94dc21f0da53be5ed54fade8104d8d8ad477eac56ab30be","0xc94af78beceb32fcb6ce6fc0c1e135e5a9dad8ba098be00ccd557a08bf869666","0xe836dbc2efc8197c81411ee9466853e2bbc2255c456b582417d9d3e036400825","0xd10c7a46411e56a6df6bcfa23d9ae26fab2f9222b512b22add72a3eaab666121","0x36b0c785cc27d0ab9747d00939ac21c64fbd73dc81e5f834607d25aa05efceb5","0x1992aeb5232ac7a4a29ab7b44fc6e8fdc4fa5f660bbc338326b52ff96098231b","0x4d7dbf7410e8f07079f0621de528f3ce318a726d0c1412cbb71218238c51f1e9","0xf7b7de33dfd6cdfb647e13492c61e1c45cb42b7597821816f2e2ce81c02992d5","0x345a4db46e00db42163d3cd1bb6ad89147ad2630d23e270b2941e7e2d66befb8","0x8d81b3d9a75727df1ee48a6dfc4050355d5d8a340ac1cdafd964d306619240e8","0xf379cae5f27dbb36559377ee82ccea56b51a4f78e8f926cbd8b93afd1d8de31d","0xcc594b3c1993cfd54a732e7d3357dc94bf16d659bb801bf51dd803c8e5fab0dd","0x43276d6d7e3c0a2b7a1e420447fafb56899d4da57dedfaf3530fb89fecdb1c41","0x7cceb4e9878f89b31842293a4b9f42134e3755d26cff8db75f86ba578d5c714c","0xb40fb1b58db242cc704cda7e96f328df334437c378e321599ad2e02401ed4b24","0x42247ae24490ddf719f73865b318aa90e674564a463f0e91e5548447afc836d8","0xb76205c02e8e500b05792d067c6f0f975852c11134553a934553e7459e4c0603","0xe3a39a2da73255e6c5d49733a4ceb9a2b06292f142b5e70e7842e737eb827b8e","0x12de050c68c69bce7fa61e286ff29b81e7f4f1625fd250b30a24fac8ef6ef74e","0x3a4e1356d68facff2cbb0cc9125e0ed7cca0c547a1c0a687c3a59a2779c4861b","0x556afa2960b0d7058d8974570a405d56feff09811c8ad3e12e0c04fece076044","0xb281fd2e4abd64b0efc47bfd6d83a728c5123a31556bb604216dd91a6738158c","0x69fccfae2ea7da00cd820ae6f9e0b33611be16c0b3c6df4472dacb0bbade0bc3","0x9a1c36a86b2c41945e438773f9aa89ef5a6a209611a066f539cc84d636a23d42","0x1ed29569d1355a2c2f27e72ac58923270cb52f7e95a85eabd2289407762dc5ac","0x38874817fc27c9097063db96756a768d25bdebc4e6b7053eeb2765c01a2b9a0a","0x476dc302c0a19cf7af25ebdf7fae3b24dbbf916be825f9a13eb2302ce395298e","0xb26a54bc4e2855a411f30925b871426109b73c83a695137a01293013a060d4e6","0x6da20568896f483087095fbe15ac519a64304c81d30ce9af091c99ae246e157c","0x7d173f4bcd7512c6ebb2db68dee26f5d45039d5d256ebc22edc14d52110513f6","0x5a1fc69e56ecd48d90db569463e34996d3dc1d8f84d274f6e88fdfd7fd49663d","0x32e8b3e59cc9d3c0220d12e23290002091c8473ff924dcf6e48d50f43476d93a","0x1c07ddf9c14ea8a55039d8ec935fc6615de897c7fb7663a2d2cd4054fb83c7d3","0x455a5c2f4e25acb254b02bc50faea27fe55d54b3c33b57ce4b42b70eaf8ff8ea","0xc3271a6d195de6823f52ba8538b9e299ba99ad4c7b9e57eaf75ebb83fcc966a6","0x0474d35e4a970a99b991a2b967bd9ebbd6b41d5460d6dab9284ab6a45a9cba49","0xae1249ebb39c2417808681a3233ef46b610f11a6710a1afd649fc50f5afa3ea1","0x8f3fe9250b68c695f7c4782fc1513f22ef9597e8485bc8bd08166c839b3b8653","0x7c9a3f909565bf171b6de126b2098eb4bec42dd80b05ecfa5a439a5eb01e76fb","0x3c1fd41c8bacfaebe8ec1b778750849ab58d01d9f0a3b86b394a308384c638cf","0x42ab2662da4d36782f1ac11c2b57753e678ed2e2f8780c57f754ffa8ac06165d","0x2ec8a5e91c0a439afeb4c743c9bc6f52a70fcd5def0d05e60674e397179592c1","0x777d0c7b2267d5872c10454b27defe2668e216acd09b61cb9af5b5d016d0c2a1","0xed8a0394e59eea365c3e6282086e375a4173dfc7e394d453dee49cf56694cdb7","0x74b7b47a9ca1ad222d54c83cd997ba4f6d24d54a3e6384e8358644810537280c","0xc89323b59d9acf7a14dac08de4168cd875ccf23936a713b15de1a20bd19c276e","0x1fe086c212a547045b4cb13508e207269b7db3c0f0bdd79f928487923ac67d24","0x9e245f8522e309b022f2243ccce6661dc2ea021a20dd09525efbd1b0c1faa9fa","0x89b945bded8d0b708696bfd267f4ed75357577f2edf1eccf36052035703b6ba5","0xc3df6dbae87404695c9e62f890ccd25558182d6ab29748590e5fccd9a91f9f24","0x3d1aeb687d237c8656ae5038ae847bcdce29edc876ce4d0d7639fd6b50cdf2ea","0xe5f75cdd047efb22f166a1d3795eba4743719b266460f298e8a1120b90f3f9fc","0xa142282a0ba16aeb1e40176c752d0bf24b7f106a28082e8b325cc4767a892067","0xced3db91cfe5dab0639141e61bd87d4cb30d35b0a8f279f1e2b87c59693f7952","0xc27d6bd120f7a5050c73b281e958150115b78565f9577e58a7e389b75514a05b","0x92cf6b3b8b397ee56bcc787b0e7fcd27187ac7491834a68cfe714c83c598607a","0x4bfceba96e9f10872faedf26b3fcb8f8697dc71889e7af187b3ce732d911032f","0x2644b5d9e2c40c289d7142a6ba8bc9ef2a2ddb0b7d1b78629de61a83069ea622","0xd1adf6248bd688ef24dd31d553e3ae697ff29039dbab447bb61facd91997ec83","0x1c5688df0becbc051f2f56a01be1e3186c5c239413cd06247168c86e959d567c","0x4fb1952b4e2f7cefc9445c151e53b6dc1951fd628fe11b8e42beea2d726281d8","0x1714d07d7deb94468a76bc1142bc83fd966f7a3c7daacfcb391e44a8e9a50ea0","0x1200fde73fcf4913dcfb7be3b2ab6b35069da12b2b4d31337702271738f2dcfb","0x49c3238beb601934cde90145f3862c03f5036afe4b472ca1a5f9a9af605c5599","0x6379117844218ffacf054cdd9a0c101d0ff8e6302b5e07b7719358bca274a70d","0x0a13e4183bf2b25ff35ca3769fedfcc96361bdf630ee4ecd34bcb85f323e49d2","0xde69d715cb9444b1a94d814f652b36e0a80388f885e8a073a6f04620e32fa1e0","0x28d88645bbb8ee043e725fe68315811e88939320b43edc8fd63d7e48ce6cb48a","0x9ccee68199add3b525b505c092914b4866e979a44ada841d74a9265ad96123d7","0xe6e37f33778002023ab47a82206d73c33cc71128a76738b241fdf4207bb7d23d","0x05ac8705e6c7609013406c22db8d34c9dfd8ae51c0b39fa3e9f347d356077bcc","0xffd0c1fa852b4b57b104357dbc121f148ae88f23b92bdfb6f69ed2a186e1b770","0x4588ea9a25532a1d495f40a564246f706779021940fe5645907a48907e4dd70d","0xfcac120a3d6ec8b36a082f9b800d20129ea4c5bac516d2ba476cfefd3ee53a67","0x526b73eab095e2700844b5e18bfa4ff0c175a9a7d6a56806df557e5c398e8d91","0x3d1e0534535781547e0c6bea95f65b3b6b265bc9fc0e266d2809739fae6a9320","0x9400aa520b66d4c0d0eef3e8379efdd2832fa5ef3995d14842ee803ae6d52779","0x296c0606d21f1b1a294f2e6a5b516b7a0b8fc8d927e6327644961307bb03b95a","0x57ba0614ac611d4f63fcf18ef8fd263c1e6c7270e05c0cbe94a3e64ddd55a047","0xab12d3c4deda38fce175fa02ddd30262fa324dcf00ae81122ed40077d2774b5e","0x6e2b25959a77510247238e9cafc84b86ca9c47f821b03288c252793a1eaf6c8e","0x1253ddf8bbe4b80bf27e87c7ba9175c5bb03e7a0bd45b36c8c60d5b85edc6958","0x1d9efb9cac84747ba8edd382a54229ce0619b9737fab47e4b10d99e2e8cf334a","0x52ff9a0a4942058cccd8274f36c57a06fc03be80a98df46102ef00e7a31e0482","0x823f3a5cc8e703735aa9160c6a3640a7e49728c17c1422f66500a4d3c7af2c36","0x3b629e4d582f7223c0078ad40ac2fee05978bcd7ff3161aae9b714e33461e1d9","0xb6afbdc1d111acda09b2a1acc9627bca40b7e7d2e72cbc85d6bad442ae7a7dd5","0x48e2f4ace9f502e8160879814505761093ef45fc4c9958a5e51d333d1ef705b1","0xaeecb1b565159c5a232a530d176fc948f88cb41a9c327c4743072d750274bcd0","0x8ad9b661cc07c154ee201a4773a66bc9a7e04a301fc8b6ee1a4c1506810a9179","0x0fb2d26c3f2716b5c26ceac9b54e82bfb95b65772b5c9b5d39afd9eb02f7e6b5","0xe176d97372d0f74659b68e81ae95d986438ea5e93fe83e7d4853863311d72b4f","0xcb4058ecdc177755eb8e4683ace833fdd5d14857e92b7594c03b6f04deacaa56","0x4c5d21376855b97975b6f460ea6c2a5beae75d10e94be196df51faeac23b93c3","0x51a4d744c779204f8fde32b378660e0272d08bd57e5274362d3eed6bad4fc288","0x0ea8ecb85351c3f0447accda4466864e06d0b7cb9c137bb9dca593a3b4e5ae16","0x3009d81f68777df38c79328cb69f9e06c973b74f74febeb04f4b847908bd9888","0xfd3499a2c682b001811113cc7efd5eb6895f210d5df30270fb8d89d7221a641a","0xe462164532c9852917c0efd37e1a16b3ada03d23955ef569ab24cc428f269e0e","0x031528c841ac4b3d4c6e0af1830cd50c3419462276b19b695e826a445dd9ed32","0x3dccd82d2648e31368107e9305f43baee68e337edf4bbe592f8e7b61e1a2ff0f","0x30ac526092c7c17a4fc0b8ca2cd0d810d0f99137848ecdb66817f0207d926c44","0xf37d0e48522f881bc44bf3490ec29ae9d603eb9db24fbf02922ec41f780dcf89","0xbfbd47b135e4117422987e02d2c0f31a63877daaccedefa46fde99776f7459e6","0x4b56a66d32df282217d268019e0e2efabb6ae2023da379c666eab7760a842d1c","0x81ab47d205e286cf236b3524600950a6a61e3f2528ead524db689575dd63406f","0x6cb3b485eb526099b5d685bce56763d3c553c2b645be90701b17cb680fad25f4","0xa3e7649f6d28afcc47226babf1ac247200047593b3593750fcac8aa4710422c1","0x406a96c3c37df742c8b08a47f033b3f0cc483f6b781f4b41e457f912cdd6ac09","0xce5da6331514c5b9a1af4a7c894b6843569ae8024c1ab665be4ab246469d3176","0x6383be4fe6998c374a304e05dddce9949497e8fdb6728907d19dc1048d4adf9a","0x6df1d542b9852f82e92bf5533e72a3978b15be68c4d817f0ccaf27bf711585a5","0x7a01e98ee5c28487438ced66a671e8901636ca7f7e20e36edb79094807d20839","0xf8469b24ed726941e4639f2eef1a527f70e76774d13f2dcf1b07050993a7dbb8","0x9f2a3a65b4411097f7274fca3c8c9df3aabd2473a8bfe153a670dfb0e511dbf7","0x28da49c2d291616b567731b491aafd96a39c9cac706d1075eb37ec6dde86debf","0x89013b83b566e811ab2897926d2487902e1666dd04a7f48a1d2907195ddb8dcd","0xeb3eece4726082afd8663845e9203ef08a6b1d2d5c8c8536094ce8533d547293","0xc448c22f39d252ec50a58d745f86c15e2d009823856bd5e526aafe9104252e6f","0xf0afc65666f4597f5aa9143e29c7ccc0232bc784ae97bb70bce046739cb3c8bb","0xe32ffdcf7e1a538fe01755ce9dfab23a7b10d51cee7b2aed2975da206c2ce6d5","0x664552afc59b12366b20e7e992740f1d8d99677d9847524f1803bc7c93d81a1a","0xf7c240b1f68767b95086d69ff08ab7f29f11074def4fb845cd27c409f3075c42","0x9310eb21aaaef8830b90bf5490353cf111f97c6957a2228d9f2c68bcac79f579","0x03a73c6e02d68576a85bcf16db5ce80268a6120b2d15b6dbda10897f12477676","0xfe7f33dcf45149b3640b9d98c98eb2bfcfbffd2052fb0bb1bdbde23fc5bcb958","0x0c3d03b8b0fac2a487e56d20726f69ce84e3c3c211bdb3abda75e23c08c6909e","0x9f3bb68760132d6d6361bc333d9a974e22b7563ec21bbff94c4434be64170f15","0xe2e44d87f0669605fa9cede143268930bdf459d071a48ab00a4b09c675008d96","0x1b6cbeff4e7b6dd86ff2c124c83adc4a0ae28bd454d1843da486a455a77c361f","0xd26b9ea7906cc84497091d3a87a5bcfb6a42bfd12ec2950c06d8a550e03478b9","0x7a46bff5b25f955a3e830323d8d297948201ca41062ab5bcd5c822c5f844202d","0x1463d7402d8669c91d4b6b19e234fcd8f364a983c2e72cbd56d51ac12532ee90","0xeba59753a5f6fbedd3d8fe53ddb56bccd3e50d1ace67b87f71ce26b0a307a274","0xff80ae41e1ff8c4fb0831511f2b397e23811dbe39077f69117df4559e1773bec","0x089dd94660f18589d72a3d3e359d2c434c2981618448300e752e0d0c33f8cc8e","0x27a012950997e4bbb52bc30164095510a74356eb48a88c307a1fc16e1f2fce23","0x925b2b866e0641f3e8ae832b9c5dd4e426e416272a9147081eec6f18d5fc2593","0xaa33062e72d0207fc20fc372ad53e133e383e2955d3fee971f9cd5fb00f6c100","0xd27ab536231bcd369468748ff19d9dd446a7cf054cfca87d1fa03e315eda4b4e","0x9a16e545c02242f757d89345aff654045db7d5606ca9c379cfd577efce8948d7","0x7f7e334a29c9b919e0b83d83bcc486664488e75f156be518f467ad28d34101a2","0xe89d6693c63c4d692a3db0562126823c7f0a6af628691b6d3d5c4856cfcd042e","0x910f8d0f4a0b0e015799beebf17330c3e4e7465024b0070a20a3a0bff48b84a7","0xda7ea11e6a8ac8604acef3545f5434928210ee28cfb0feb4bca857f515458099","0xf85a861308d45f77f6d9c1c07c79e165a42cc066266a403714b8866a85feb17e","0xee830b21dedac570136450382bfd64c2ed5814c3b311ec65506c8da8ec30e12a","0xc87542b60970fa53e61cfffc3c52a2da70f160d1de8d78e9b5b7d863145a9cbd","0xf98efbb810af0b7aa419d0e8d8ecf0d79e3d1171d96d36d7c95a9074bb34a62f","0x5fd357ad40297480564148adf753a20388cdbb7c900c06696deec1b244055e06","0x2dcaac98165aa32992f0b42bd1fa2db4f7b923eb45d48b5be193c17bdfcc2b2c","0x790799a62c54124ff455bf7cdad6a777c35e205b16daf7093db0f0aebe51c9db","0x90a8fa19b3209cd6153b0edc3427ddd1e6291bc2ea6e0614c53cc752281f9629","0xafb38ac8e37797e8074795a26a43c64171e3a7dd3394dd7293c44e584e43d34f","0x27c1765dc7ddcccd653f127512ab4693593c6ccff1b8d367c6f8c2a0e4fa3686","0x9672be2b61eaa9db04c0e277055cd536699242d59a0a3822ac17b8940e424087","0xd9a5325ff091c3d55b79491ca43cd5ce976a2403e619646a4c11893459dc278c","0x8a9b2a6496b0e157b2b702b8647926b1d5e9915d19efd0513691d44b12567ac7","0x33530cdef6feaf386843cf707b0cdf001beae7d597ad342992e6c0755b92e495","0x04b9d19219dbb6ffd1334253615164dabf723491931e60b73eb2f16f2d3a0ec0","0xcc16c9dead0f723f756b687693abd7486b3e00a0b5f77cc1febadf9b098d2455","0x406c0fa0e16ffdd4f072442ba597b0fc455a4a79098f50365403a264edd11fde","0x75a4a90d9667ab1e9dcc9713bcf4015309d0e7c49844501700d2814b4442a938","0x1b1972182d6f98888ba38c1749c36fd4449ded453b079aa9a180a95ebc811cab","0x2ee1e420b917778780ac423652d7778ce6f3f5f93c8a9df8bbeb34cb9fdc886a","0x34b440e9cc22cb85a4270722088184325d6604166005071db24aa401e555e6fe","0x6de7a07a463de1a554ba0ab10ebf8946017e474a8b6a1c34033be092cb866dfa","0x1acfba75e9215bd4eb092ce418451929353ac8e66e52931c7f67ec0e94c1e456","0x2d20cdf3db5de0884deee20657b5018e489b19264b3b1d7aa46c932b737d2ccf","0xdcfef6615d289060939a141836c696a74526c1534d5aed7ca20b2efb27ce03ed","0x6dd3b4a8be51c48e50fbda14bea53594485eaf43779c4656f4b658cce2ebb2ca","0x72b2f51e2fda36f22ce81329f2522a3bf212db3b82890ce9b29279932056269c","0x9a6ae30879a69190aaef3af5b55d06d2087960c4def4055e73728837a3322998","0x42c0f10436a52055f1ee3a62e3f2e1cd5bf20f94d96648f98a21f29eb71fd06c","0xb28ba8f3b8dde16de4a893bf7dbf21d158fc292f3decc8feb66d567e5c23c77f","0xcea85cafd3be2d9fc428814faebe2001424f88c74a6c82b657cc4d4118bec9a5","0x2420d41f1e3e2c3a05310ffb4a8dfed6999c14a37889c28e6f49fd642b36531e","0xd81f42f8ff7983d95302f49d7e5275ade2ac3c42678e3391d99734efcecfd414","0x3193913198b07d2e583bef1eb21e225d8f5b08cd7b68b420f836a285f991391a","0x0ba1f132f7d457c923a7525ef50b69d9b2eba072001753ad1ee9bbb46f888e1a","0x1213f62435d39c9cac8ce5ea09987d60ab5cc442982eb551cb99ac9c87fe6937","0x2974aa6e364e6a56eac624447a01520a6c57e7ae8faeb7cfaf4312db0f2b445c","0x1293f9465b9abcc0f271b03c628f74bbcd2086aca528da19d68d7f49c42a8042","0x6828e8cbbc587ef00bc0608aab553e091acc93bb988ac27301047cfa68df6f16","0xc7d3372a890c4062d12dd4201514c3dceaa1c31be2e2254635d6a0bfcf3a6239","0x1ee94dd70da2d33769919177a3b670cbbf9a9265117c7fb5e1d1bfc2f329b125","0x8a8b491462a5db7f51b8558edd6aa7e651e872f3558ec4d1d3e6a2fef5fcd12b","0x2cc6ec35e6812a7475c1209ac2ffa2481e2d6f9c76abf06a6edac48748833ed4","0xf66b553360b40e3c841c02ab640f638ca9420afeb804f88b77855b1c7807b67d","0x10e2bfe6e7b22ad5c3feb71369da9a63d23350ca40e62ad3d654da11b36cd333","0x3092ac4897b5772b7da96114b4a74099fe926ce79d4d3d32605c570eecb58ea3","0xebe7cac903a3c4a6b2de47417dfba3e24ba1c0a735f6f926e4a57717d573872e","0xc5d8f8038e757eabd67cc360344d62dc20964c91d1ca5ee19bfb0fd1dc80d950","0x87c7b2b095389b66534eecb8c5eff1185e99d77d9445fdc9ac61a35c89bc5240","0x181b5f49eeb92d46cc06f66119f17bb7ff93ba30b6258b0dc64d72acff3e30d0","0x3ca8b0b5334682f088351ec554602ad40dc927eb80daddfab47828ee879af4cb","0x9834dca4de9a4cb203f6e3f464390c4ff81066396f5540d9042fa638a6d64c19","0x1fb5b0e56d20d6759fde48caa54bfe7282085460b254bc1c02719c4b5a517f71","0x08abc20a3c15ab60843e341b49361dbc7257ed8993a030191690a79dafc94202","0xe6d26373bc326091c4a394c9136661ecd46248c7bbfea24caa744aee2c2e6c0d","0x1273d0a600f49f01ea4bf9b499e2f774a097cdc4cb40a0130b1e5c86d586e9f9","0x7c67bb26d7db96729f9fd99e28705ac764d513d209d7708f1543391e2692989f","0xd95273bb3b44c590bc15897c6c8e6950651e3ac45d7cf96a2abc693630993bb9","0x8b5cccbe910791a389eadcad244da77008252e7aa4c8ffab1e9823f0caaf17ef","0xbb6dac441257db59282bd1222fe6f28bdc9c37d7733488eef5b111d1e9f81366","0x4facc9f81175074cb909d426c446a4e193dcc8f1c8891da32691ec20da92ebb5","0x8fe2ec6c3e47d89012e8fe93db45382da7fe3da51f2c01cdbddcef49bcc99484","0x702ea427bf2a52466a35bff977282315347d6b8f75a5b22884866873e103753f","0x84334c65385f01d3bbd605c919dabdfa047184883c5e71ed4cfef3639c3e6e58","0xe29a368f45eb43291f7a07fbe477e41f5b3f0417f5e2f289c4f51c4b6ca40e80","0xc74a179ffe3ca693c63508eba6eaeb4bfa401276c2511e41ac7b675358eede10","0xbe62956f6394f0be139d785f5bf6ff65dd4bddcfe064c35aa308245692103cc1","0x29ff4adc9f17346477c0306e5523e0014243aab5a73271d2b21bf4b953cd0c04","0x669af691f0a8bf2297529a967ad283e8335db1b6c2ed1654257c4babed85bccb","0xff52ca6bfec54d78a72219707cb90c5567ad379db7a681299c7e5d9e32813bc0","0x188d1925d0b1cf1f1ae0d4833cb95763e2cbeac7231f390c29f485aa7972f18b","0x131ee433cf51b6bd07ae25e6ab5a439816f784a7e22b4d9be558404f1db3148e","0xc1e5388599366156a6321920dc0240fe1017cea1a0eab5068b9a203650dbbdb0","0xfa79e3b5d9129e1fe240e33e27eb609f66cb37bd5076812995058d16b89bc55a","0x3249b20fa66e4acebad781b626bda0c986fa3cee0286a3e79ee538262a5ad1b9","0xee4062cfa099df64e89d38c06a1672d54b389b46fb7f1f9626e46eb864af08ae","0x8e8930783b776af44aad02c46e2de070038ca27163e040275c3c9520f035da26","0x7c84405b2a587a8ecba53da0be2432326140f908acd843a3ca63160273385252","0xacaa25054376343804fbe26410fcde47d6b17fd66d1fb3df9385d4d61e73dbb3","0xe46e476231118e643adfae18922b96c2f65357c840ec4837d10a871ece74245f","0x20377a7c6c60c0ce4ce145eee1af51696409583dc72265a5c544d5b93983ee5d","0xf850b5f13847675fa876ed61e919da028953f2603897698dc4e536e5b9ddb22e","0x0f82cfecfc04ab77f98a56ae2e2563cc085002267f36cbd5a50bd0d2c7ab353f","0xeb0a91114e52f9df441880325446eb4eeba034056aff85b9f2054edf3e641557","0x8de79566bde73ad2f26cd222289ec384e035a60321508c408b82fac7c1ffc9f8","0xde4ab1fc762f7fa0aded553dec2c38b84d2a7e6912cc57dfbfda7160f720d778","0x459135d3fc53663e2db17ec2d57841ebf868f769d69fc80b51fa62c976c18510","0x2e54f50b7c05a004be24748e737e5c49cb95252f3e2755b1db3622a25f5398d7","0x010826c9c3cfc8cf42206e714cc7fde20d7e83433110a9963a73f90102e48f6b","0xdff2f458d72d2ceef757e1a05b1dc20f4915a7fb38e96d21120564a46d44ccda","0x23b1966018e2f972303031b1b8d4ab1f80a9e122e8d757e9de6b487cccceca20","0x5ceefda51b6453e9ea2ac2141944232c8274b8812d551f79b92ea4bdc37aacd6","0xabc7adec9cc1ddf245a008fc8d5275d8306dd3247d596d7d83b3bac673aa1754","0x6f3a5183d9df7f7e67c83975b58a39d448e2c6fc7e7815aeb13e76280a48e560","0x24eb93ee8846a2e8538652306543ba03c6c53c58294b4e76d388b528ee1048c0","0xb09e34005ab7a41eff3a2a705608ec60a5d59cb985d4971feac284eea4aa816f","0x86d7552548fb7bb17a4d1d68e70d538a71092750cc42030ddcac3135258861c1","0xca047974f81202b99449e6f093b0fb6f74217bbf53c07981f5636bfdd7f958a5","0xecf50a7d2f834d47423083096698899e6798c3e95e3ab90a337ea3297f1959c1","0x204f284ce3b9514cfd6b22cecf788c9d5d8abd521739b0db71f70820e9001d1f","0x7c97be5dc908082df1a2377ac2ec16fdae1cdb43e2cf4a753e55d6fa17287119","0xbf928389b9b96e859c15d1303a3d29569d0f0df0e8f2aaaef59b2b28a0b4c37c","0xbbd10f236833b662e64f13694a3bee73ed09d61a7858590600921c0dba41d134","0xa11d1190dc40631edccd482864785e03fb65283bb039aeb9f6b6a8eed33c5a0c","0xadf511e597709f06728f93b51b1725ec9a17aa19418f031cac1e5cbbb8a7c976","0x21b28c98851a163b9fd7cca053911393e2cf7596d2d24757a34f3f824e0abb88","0xdebf4d7259adac256c0c40398743030ea43034be9ef2eb9978538015401d18ae","0x8f8e90bf8479b98c8f020ff8487029d28c91380b82699ef52c5a45e5ac1169c4","0xab108d817f4f3e69ac12edaf3382b3329f45ac02de9a7c4fc28a7023c322eb48","0x789e8105e992d10f8ce27dacae4cb3bf38479a92d43d268dc00304b0539882a3","0x37ecbcf49c71509a8304209621eb17b227b7aec55acfc987ae1f94f92ebe5758","0x33669d494340d6dce2e2f642005f14d4be39846a5769bc137f97bb68368a06b5","0x2cd2f7ecbbc37338bfafcb2088accd4fc055bea2d224822714d64354a4f9844d","0x4f77b84a1be890c717212d4990c39a13f8dae5b3276aab4a5d77c782c113ac65","0x3d5d0615687af7822a53116254dc90f4f462c6f672da09dde35f8b68ec53072a","0x947fe68719a48ff3c505905cc6665be654059c7e17369797d763f27babef47f2","0x599714596cd1c71bc738def808f52ae926315c15e48587cd12a9f1351ebc1a5b","0x33aa33ccdc0f7915970b99ac3394dc019c1690c17cba2418f13afa0dbe05ad37","0xff368a09419b5f8fe0a08e41c3282bb960fb8b8be6d7d6fe2ce16dd01691c3a1","0xc50b43e56ed5761dd2b6523b92b3eb87e2559892a64b615b0691502a6183dbf3","0xafdf467ea59bce46668433d1c21b23a51fba5b377a56ebeacf278775ecbcbc12","0xaedb352ef9b1b200494f02515b21b28d28b52dd6161491786eda563eec84f248","0xccc18dc1027b76a55b34feebc5a7f145c15f9755cb1d195a50dc191e69d52589","0x7dfb037df5cb4de4a4b7061cc71290465c0a833c9c08826e769fb52ff68f3542","0xa10d3b86c75e8826aa3cbf92e3c3562b08caa0a845eefcc941936862ba3c39f4","0xd1cf1fa89d2c40f5f6b9305a70a0ebe85cd203a195544b6b59aa7919f420cc19","0x4175a78e2972bd8762855db3644ec4348d2596e34b8d61f8cf9a96deaeb5d6e5","0xf4a3c05f4aa438ece315d90600ec1294ba59149573fcd3dd1511e646eb48d7c9","0x883c48a8149ecf8b0610fae214ad0c27613cd3fbd2cde826839d14a0e0a9abba","0x465077316b0054dd4382b1f0bb67b0865538da46a76823c0e34e161f00a1671d","0x08c3d94a6fdabd6c23f7a7809b8b47b9620ff4aeed5fafcda6262b5b01a1a1fb","0x94f87602745036002f88c5ba3be374fdf9382b38b523dfd813b680d41d76bbae","0xfa5c12b7013f866ebb72c79871f865f591c4262f7c54df70fe3d11d771f94862","0x7ca22fbca019edb8e85685eedaa9d331c9f045212b722ce60ec465275b7234ba","0x43403c007bb63dee6794e282dc3820cdb08c80e6bedfbf435260529e8b2b8117","0xb524becd722aca3fc44f4744f70fe17922171f5c695b9c13fc2b6431e4495c9a","0x24ca1b8ff08dfc8de94b003d30ad883c41236b889f15763111261637e2683e96","0xe2deb153ff982ae2d475a0860b5aa53145e36ee70675c104ef258f979618063f","0x3acea87f69db03a6ec4cc1b7280ccccdf18e335a603a7187547f831bf8102e4c","0x52d04559c7adc88cb89104cc8ded6aa7ac5098fba35f657eb5808fa859a0e639","0xc701bfdb148e688d07fa0edc4d5dfa0799bcee275f2d101dcb847a0f1e4a65fe","0x0382acb0ab1ec6fb3d2af5facf37be6534697642a90e3cb841684a5576ed4fb6","0x4b08251ddf77353610cb3a444774d0fcbffc540fa1e5138c9c8dec78aed6de4e","0xf807389f43fe4c582fb2fac24a8a1f33fba5deecefabb2bd3d8530091460e211","0x1a93db1f9b7b3601bd7d144a599dc25efd4b9fe6a60285a19fffdc93f0c91529","0xdf1c72c17c94641924854539840dce9bca463ed71b43bccaa892155576ddfbca","0x85f8f64b3df40f03955455f9082a511f4eb023fe7f9aa1aca8d1f2596bb2ddfe","0x470f0e07ee8d20c604f45f19d00288f3b83de16347add50ee098c0127d520843","0xdb923a438ab979024a232a769cbfc2fa4e5af48d3a8b50c621fb403d593c42a2","0xaa2cd37b719718e2d3cacd24949401381daca678917c6965e0a72ffa9f330052","0xa889d65e2f3f9a2324e7b68e8911319582d4836ad96bf5f87080131670cfaa8c","0xc5172d51d2a95ddb05de956b0ae2912eecdf77c195d581663266e501c394c474","0x401e24cc8fb19439190b620e25acd14042a0769a5a0f12d185063268abfbb277","0x96fe7de10ac0444b6d8917f54968c9cc1c49a1f4f646de9524d4aced59c07d38","0xd9a39a0a7b059ef9c5e08d4086a5d4f75321e0a02c4988f0b2066f014a854648","0x0c5674f282037b230120acd821d7255c3826dabaf5f19eb9ed93a90eefe6ae93","0x286e9ef69cc3895299efa6b7dfa2dc14c46c3022951f17faed6b479b987fa1dc","0x58494bbe205924c40223574435b09df7250015533cb2b8a0c9641c5c421856a2","0xbb98e02e61fe27ef43bc332ddf5e3379e3dadc4a1e9307bd415cf0341fef5d2a","0xcd1718d906b2bc05e2278f5567c4d0a90c72b63cbf32abc2c76e81ab471790ea","0xe22ff990846200072cc2cc538c78a72cf4934c4df39893b9bd372664d18cee7b","0xacb9f0c5f9fe2ac63e70c7357641fe26b1bf587fe88d17113b9759e1579c74c0","0x02310aabf48126e3a962c174ccc1e7e4bf4222cd8b73f002bea058914d364f9e","0x217402d0624b653500da8fa80f97ae7512b54198c53785542881416044fd1c9f","0x0973c5c99b5fd025f76981ce4004344e1ebfb3ea544d7eb291a35e66e4a206ea","0x42ba876cf902c108e5cd37ee418117683e4436bb584aa980be0190bfcf994374","0x66bd4a3904e4eaa11d51ecd1bdcb64bcc6c3620e311b9cc672ca57568fe4d030","0xb1ea799b2e3161901eb96c48af185b834259cec521128c31b828410fdc2c2af3","0xfb865b77b1d3857f98d188c3cd31db4c2c5a0073bca6c012a6ef95d56504b761","0x6c5bcd4d416b8c336baf1d82dfc89f0da7f2f6ab53a91505e446d6cc4ace6f10","0xb4ee766706587f3383838249619e1bbb4f95d9538af4a32fc0533620f07373c3","0x5efdfa61ce15c92ea06c6e758f78c32756f3e6f14639de7a0522f2d5fc64db1b","0xeca081d7a1d61db462e4dbd2c7a17255fe85252a3bbb73fdc006bb6d09443136","0x63cae914c833d15d1f44102fa0bfa2e55c20fe071e889de4256a755f9311ca60","0x96c4f245476f38242841c257c32e7c29a50b67219d63bbf550e6e9188a66ac2c","0x23d3293b2a39f073bb0e54c6a04b3d673776ca3c175ece4280c727c103d5e180","0xad4e55298eb748f865099dbb32d2c5e80e582c52515f44432dd7705c7d404b93","0x49aed8a79f730a9ef19f9fcfb265f45261955f43f1648b1f5a80822f511331e3","0xd9097fad564ce5c91f298fecacb4e6bda2b9895baafb42b83535069d66376b1b","0x5292e73e93c18487b724481421d927d88b3172cd1bb3fb44e9c8ac44a4a88aa7","0x754983bda64c40cf90a507ec20e20ac26e7d1a5e80a28e6d672d15e6b8fc0577","0x74a799fab01266689e84425766a7a098108f7f49ff5153e17058ec84416f87dd","0xa7ae7cee086d2eda097401ce97d355bb08de439e2f4cad69ad3c56953244fa89","0xa662762e3ebc5e0ad8f94de1378de2097b696417ea5cffaca797afe995ce089b","0x0e1e8f6d5dd687ab809c8d07117709b04f1f7ddcc90ef3bd059faecc890a4c9e","0xf4cb654af9c8d13a850d20c2485f8233f7377738fea3e81dc25255f33abcad45","0xd6414b5fc0170deaa6b4f4862ea1781e5f1eeca3a3aca43849ae7f892325eddb","0xa0481e3e26aadbc13db2b748953d4fcd545505960c67a1a2fd824ed2d79a6a3a","0xc466ec6dd74bd62f02a9925e245c5d7e7307210eeb5c103a2ca524baa1e0b665","0x84740f90f13c687a5d03796ae630b2d6bea5d58d29ed20268f5adf3e26d3ba9c","0x1b60513e1e54f3024e41a75825ac4a56777cdec60b8a5551f3339c5c1fec6154","0xf0e4476b287b225883eb2c89c7a470ab0eda9e64cc0b891ce4338d12f7368086","0x747ae3e9c128ba24ff31af96a143c461e27f7e7a0202b59ad9bb787dfea42c7c","0x58f5d44695cadcf541970663ca87d97f5e8aa94f7c49bb9e3260df499c61c9fe","0xc887c5c3cf55239233d88757841ba4a2d74d664e0ba253f8cdb0f9cae4b476ae","0xa6813bdf8fb3278da19710c5002b0496c5f9ac494d8518e53fab942e61ba7138","0xd1057a31ec3ee3f46e045241d5c3d409b21f9f37a403f5e909ac4e8fc5ae9de8","0xfc2e83068fe8f6dfa407aa4f4b2ff418f44c8577817f67dfb951cd3d9b47b037","0x9be0fe66fcd93866f8fdf2c25087ef5f35717f5606018cb02cc18a483000a4eb","0x0b06e078dc3f1565bcdd6f2d1d00ac3ecf55a56282c5fcd84433c42b54156f23","0xd4fa0e4ca6a63b9df96b940d54ecb80d09d3751af14b4b9b9624af02f6a5cdbd","0xcdecdc0dd7368f2efe2a325bf2fe4e566eaa1b8c07d9c18b69460a08172c5103","0x851b51d20e9181d528256feca0bd48955010638a7f478ad814a8cedd61371b47","0x679f356835f1915772600f689767221af1d69759f924b1d3c5d4413990545b6e","0x2d3c643d0cc0de950fabfbfebe695c6602e60cf6674fb9ceaaf5c30c89c2eefe","0x0f7b2c7203209862d31d3ad8fd7495b5fa3f6dbc68ff2919eaf78d6cdba87ded","0x314de33d4d920870b2d2196bbedeb6ad93552183912b1de38da084196fff39f1","0x31409a8271c94d29223f98ed13d2a2321a07973044bf4cdc01f8bb914a02476e","0xf73732d05351714a043e98ef23d8352df5d85e96b0acd6edab17d056ebe4be81","0x52d72dac8cde031dbc6dd9e3fb229a859903de62d273b0756bdee9246077c000","0x0761905c49e3f6e11490108da264423e61d5390db5f1a933c56ebe9d5b4e5065","0x4ba3c6194748f22aaefc9e59aee2329ccc3d90aae8e80413e574022e9b6181c7","0x5161e9772d51e5b7d388123557929223804291605260716b9c1d16b4eef5ab2c","0xaeb62858e12998b05625855f0eaa2391c3e738ea09abf8b036eaf360bd2bcdf7","0xf407bf7d695701ff44289ea1f75697984ca914d670987e373826a09c00107029","0xcdffe69d844deb681727bc2f3f4d1eb97ca6110aa56fd7d2e7aa60c8da06a80d","0x2d23f672c1a5f52cb102fc6a7be4a87968dda0e6cf4ce52cf4fe28017978292f","0x60f2f3fa68b11c832ddfba502cea08382e0ce82eaa59b612306b81d7acfea094","0x4389b179d0f60c19021b50ad52cd3d356733a27ae10e509d3a4d9fea3b66e7b9","0x3be3b394d5b12c4e3cf6224c137622f35eb6d47f3818bbe47dd5b5c342c883d3","0xfb49ffcd2e550c72c82ecd8a9f53d1807c13bf333663edb83f3fea14738ea956","0x2cbb88cf60b7748308e91091f1bcda2f4923af1388f1ea2fcf78decb0522a68f","0x80855e412bad43a3546a1452ce3819281d0b8f9d841313113d5654a1f9eae258","0xbe46056acab1cb589481f4d41b50a8dcb82e41ccfdece0fb3e4abd8e88db24ec","0xf70d43514b106ce6c9951a4df2e9fa7403f6a7097ede9c7340c6a1bb1ff69d38","0x3ae961ab4c8364018ddf3dbec6d1905e535817da0011ea50a8b82647b41b3c37","0x3d380e354b647bca2175fdc67120052fc3a0116a3350c205d9f8c8079691882e","0x2f0ed669d2635fbf8544fbab025124c515c8e08fad4a59e595d323bd3cd14f73","0xbb057c917c996b283bd9d023b16b57ece75a03277a5fd1dff64652c58844251b","0x7256b85117520e97912554841973cb9454a1ea94fbb2ae5c2b6e2279d8885c3c","0xc8752d5025a1697bc1cead4f886b0af330ce092897abc863c9f53879d5acd6c3","0x74646e8a3cfd4d8a53843fa533c796fead770af07792a79d5396db316474b6d0","0x13cb62e761d56079440fedba8c9d3f6daff6837f8c449f1718260358126b0cc5","0x494f50311d1486b534335c81fbe75169733523ef363b279fe35dca4214013e57","0xee8144e0322f1a1b2d793868de7c816dff73476982fe58a5f25ea45672b50667","0xdbda3a7234881b5fa34006813969f093e0dca1c96da56cae66e216475bf0c917","0x28cbee8d8ad625ccae689e6108686dbff58ec6cee5d05cb667f0a552ee630ca0","0xdeff18cfbb3d16a4e4cdd6c3b016bfc23bf9318f7d99a4017d3ae7a977d4cb67","0x39bf5832ae11c28af999948b6f14a6bf6b6475b37de0c276628f2f12f27e06c1","0x9a9de4412c206cf72b201e1494aabd3a11c1bc8293c2ba34175ae6fb25108ddf","0xfcbf322cf431042243d53460ec625a05e61dcb30845d67517516b3368302256d","0x6a012da687045355db009136193f96dc8e9863f65e29a5577a3d438193ce13af","0x2b42d0ccb5079c7a79c81a5f09c879356d3423c03ad294f1672c30f2a5f30b65","0x85216097701c3e9a2cfcd1742b31ab5934b6e911568187f68d5134a1b0a8360a","0x4fec77ccb6b6639c207901613ddb784a479583200baf54a307715a9edd45ca44","0x6673e187392a9f2163918cb6cd338107c51f8fd05e45852790c023cc38089a65","0x3b4b8b45062f31a8c3ab64f5dac9468c0949d1ee5b67c7a45a89af071f84ef10","0xb8a0b4c2e4e8b4379c916fbf00ac283eb385ceaf5442d74f821b466abf146f58","0x5a9c62a6aa940e242d84841dc57eb59d5f2988fc9278326aaae33dfa7653fb9b","0x1e78ea2b98127d00a0920a028d3a11298ef9d6a82536befd84b72c5e3428b70f","0x56e43d1a8871f80f8a22f283f94d5e2f6154079ddcbe71014597361e1698545d","0x4271657f32739bca342ff23a4c347150a5e61f127ca44b30b04738715af67d39","0x67d1da46e80f4a5973edbbb03a6aa4f4adf3897ee5c58f4138f576eea12e0a03","0x138fcd5c2e9217816aedbb4fb7dc0742c089974095f69e483a9b44d26c731373","0xc12fcb10293e372639e01007b6863b1dc3207c7b1c22687bd4134fa871666380","0xabbb84017205275b09972d2ba2eb417aa1cf2b8d9ccb6cc54d623d8f0f6e52c7","0x48492aafba9eb5c0ede5f599ce95c6dc901c975dd0162a08359cf856475f5d2f","0xe3202eca552d2e34c763b2ca3e48103eaf7797f8ac396b413733fde2d8ea8de5","0x898f46f6eda6c55b09feb6e1c3011d0fe5c802da6814df73f652b0bb0637b9a3","0xce30b442ff866b890d76082e1233902b3ace2d15c36585726212818db87d738c","0x678633c731a28ce5c49a3d2c81004012a2316261a01af5cbcd961f5f33b91c71","0x94f90744f9a01a16b2c2237a3da403ded52baa0b926282d2af0dc13627c51972","0xa05c67e4f7ad31ccc7cfe341cc54102874fca40717c11da0f26fe3ce19345702","0x890b3be6ab227ef66fe16c92fda880421e1c90933ce168a73c6edd80953bf488","0x6082e3646d09e3988cebfb01262ffb6803dc22f147f7e68ef4784abacfee514d","0xd628611be8da1668efc534f7388654622e136b3910b8c42229dbe130a1468ea1","0xfe1e0810d4ef73499b2ea12ca403b688d68e22a108b67e3b5d1cc8233a957068","0x1ad13ee5a8553740aa1bcf450434c66f21be26cb6c0071c60a2b29aa9b9bd672","0x56e5d8f7c8d814f75afc3ae55c8beddc360f7245f2cb5ac8d13f82465ed306c9","0x0a61af1aeb4111e3cf5fb285d3a91b4b8aff8dabf10435e43e9ea78b1aab4867","0x32c521768d596793a2dc7ebba5a1b89a11969b724aba2abe2bc263c26f20b761","0xc715bfa83e8820d9a5a4872e83850133ee7a8102d35c5616825377af099a9047","0x0e635710e64e837b2a0172e0bac698797cc2dbda5a659602f84574a86643aa67","0x9099412b510d20c66e447d6936beab74d60190a956eac474d376a9a356d683b7","0xa1f4c335aa74873e759b4111d63f40cc1e044d781583955b20d6f58c1fb2cb15","0xcfb7c805e53892eec620c4b00ae2fb47adcd386f77668ce20397d639def05cf6","0x92e10fed99e008020411dfc70f638fbcfea7711e5443a19365bfd8548f8bb857","0x659d48718593bfd1be3378bbf90d88ebad363cb20d8ac9f5bbc9f06cf33db1a3","0x9b20fca8603c15a5f15cebae0c3101a2bb0793b9e435941c2c3a917ac2f80073","0xd6afe8addeffe865f326ad7f38e7c53a65da25e0caf96ae0a888f4ba1c836457","0x36125cc945e0ebca21528b9b2f64f86df3773f6a1340ae3bfba3e806cd7aa8d8","0xd10d92e6e3060a3d9c7def74bbc403fcad253f597b10328eb1587a1a52e20592","0x2bac13f3c2fd28805f65dacf2cf4a141534f1477df6b00176568dd64c2d047a3","0xc0ad350615b89032e64a1c6ba2fac16bab5a34e269d6cc5e6f860fff39c762b4","0xca0ff21f9e8eb40fb3b7668639819b9221d27b59f351209920f5eabc3775262c","0x6c3e7ac65571b3bc221a701f641c2606460bbbd12d7e6e996801281fc03d416d","0x7a204c8f60359ce7dd486e8cfff13d1af7bdb75c9499945823a7e2b42933374e","0xb448d458daddddbd9209f229296add8e1abaf8ff2844c223c50f93826d359e0c","0xed9f352441cf0f1df5a5eccb2de92957c45244b9807a50b7f59ffbfae3f57857","0xc55051be25f883f7a593fb04b096f36f128a8533a12ad822bb04eecaa42e81b4","0x581ef4f7617f49fa2ed3b1d686dc31dd7068b8fa90dc916728a86feed528b10e","0x9c66036a83d1b3f72564869fd9d37ffa98ee35ce8938784c6028694ac9955390","0xc715c77ef31c4d26203d45862381b8c1d461e7f399cc6e58f2829744812e7ef4","0xb35be8f3c654845684a6740f388e11a3ca8740575f0b0ded1deb4cd40e173fbd","0x826da7a3d367de621f24a885932699a18d889f3f8ae276c4e14f63c71de4d14d","0x018622ad20f2e898efcb5f335b51f5c3334c29bd148f750484f060d63a38f0b4","0xb02831f8002fb4b25742b858774487449e51f9faff5af3a1c2097311600aa173","0x0d734fdb6e78ad04c4bcda1753c0c00e500286f4605a9913419fed3a656e438f","0x0e11f81dc12fc297e096494207f67e41caf98e5d8a5d1c20328dcf7cf29d749c","0xc1ca4281c7f20abad2e85f8fdf53fa602dbf9a8544642dcd5c0a348481fe5f05","0x9c97a8ca6deeb61570c92aa1fe3587f2773308ae2727241751a05bd3d349297b","0x653322977520301c33716af2bff63acf49e4155b0ccd624d2e598c34cc9eea1a","0x2d541b538a6ee4eb40fb90aa173fe9e27cfb3b4e6aec289fa7073001d8254dd9","0x9a01187a42ae0048e38b27723c0217287e9a688dd83701f2a96ccf66513dc69a","0xc362fa5e34a8cd9b4f5cbd981ef6a56ea5f7feb3cbc183b8e895967b6ec4c670","0x49c9f669ad2e67a7b609573c9cd3ff710a504096ef1fbad93172f3b6fdc22b8b","0x185dbc9bbd685d5ba334f5edeeb9b7fb76b3b510b995c286b4259f21afe0bdeb","0xe76a44a94cb0047d879b40311ae0f84a9f15878ae42300eaedfa7e807cb04fab","0x315a995c0069ee864b27e022ff6e94d664b7dcd38ebf163f1e4a8db8cb1964c9","0xfb03b2a0ff60e0c9eb4672db87ecf63457ff2df085b7084c4503ef893bdffc52","0xe88e460bb73611c88cb25aab8c4c536a0a32b060f5996433b9441df957a31daf","0xd44fdf0c7c8f333667fe45b9c8364a928445d20d7460bb2cc7e13ccf995afc73","0x2638f8b964c12f901c8e264db991d2e174994c2c3856a8b3ffe61d98b9ec22e1","0x37d40729dab6b28b909919d29df78c7717f690498d525cee90c29950d9ddf203","0xbfd8ffbe0996374b99a4018e8cdb66836758be4c1d1cf8945e070a1348df3590","0x333f331d20458bb4de31cc6dac71e87abda05fcb7c8c7f8ced209d6874f8729f","0x996088094f1328935246a670469aac99c415c8da81a461c7aadbbe5aae5faafc","0x3d8ff831aa1b5db3d58735d9374699c7e817ca3206ee574f3873e661cff480ed","0x646cf4247fe07b8009dc00a0761469e70c88de530ae190df708be2267ecd5cb0","0x606d8f8c6570ed1a1a79f85492e5b929d0052b03cd225d3be9836b5aae9058f4","0x148825b15722383076cbfa9fe92fd7c918b7b4fc6efec2f6333c34b5ff84fe15","0xb18238d6979bf5b21d5d7f7dff198a36573d7762a0be985b8395b99dd9e3d4c7","0x893cfc4e0d46f851ba213a95744c9e75fac53431b283efa34dc435ff728b2128","0x73534b292b2a67022eab8810316b48aaac18606c5e015c70ecd967bf7814f09d","0x59952c508327c6dda5e4cdf0acf86bee12faaa07659b3ff7eb9f400abda9bf16","0xaf80e279a4162d13ab52be4562c77bafc74b2cb02f18d499c8875f850ab33647","0x4b82373934127f794d22089eecf72032308fcd4cfcccfc674b5672ce593ada35","0x25609dc0e0fed6fc0644d6564743fcc5c8e3ee25406a707ed06379de9d4c2d89","0xa8b9f7342acee54e9faf37d5a42d7b2c88f25b9b251af8da7d04e76bcfa7578f","0xf2e8f4ffe51d08c96579bffd7b5867384dd6722ecbf944ee28710696bcb65721","0x131a8cae697e843eba360413c219c52071efb6bd0f7c4633367ee569a46bcd47","0x50e0e39b362d119fad04e1d59e9f96821e7055714434d3963438f5c7ae49e00a","0x776d742615aeb3806e4f5c0de3eb42245f2d66e5cc94fe58d55e2a53121c4080","0x2f64de440451fde3c58a95ac7d81524b6b57fbbfcb06e894ef953aa4b5cc0fef","0xcbd62a717f0a54152c235fd17d76b36cf6beff692d4cb1fb69b702bde465d7fe","0x701c8c5b66c25dee3cdccbc5bc432cd58ec5b531aa2184a1612305a94d5cc594","0x8c673ead936180d041a435074d92cb4fa3d58277a5fe48580cb60b50a090fd79","0x2b26a8edc6a8c49ceef6d1c39d1cfbb130b67bd9483fd17b80b863fe19b1e513","0x53a2e522e3a1f19a119b980709abf4fc702aeaae952ac6cb5acbd368ad44cd31","0xd70e277e85e081d2930aac49c6c1acf9ccf19c53eed11b82bad7412690c2cf72","0xa2e7053a230ca84bca570b95e3aa83fd7d9f173daeccc7a322abd12efa04a49d","0xad36e643c72d44f5068803af84013f48cc935b0b90aa283084a1854ad2de92b7","0x663675352659e9468f568fea22c4c20ead718dc512331735fc1c158382c55a6d","0xf4946042228c0737ae23ba31af5fe63b2f5a93a5d5dd56b858016d5268769465","0x8a1ac910d4ac04f6b6d9b3182c4803fd05669d55b97ff84791cb75e8d00660e0","0x22bc2d4115fecc11dc48e8db107c10261f93dc08d714405632c95fb81fe6f6a7","0xbeb169076fad8293bc8cdcb2cb584bd3278eb8e7da5f7e5d26990477d4e500d3","0xec6475d881c8e54becef0e1bd00c9043cdb9941a70cc144a109a7b9a919d1606","0x2301cb2f9910b65db9a99f16a8388a162588e8095bc5557aed2b3ddf5997c0f7","0x3600814a838ca1efca237db2f1a8b98dc12ccae523abab466a8bef675491fea8","0xac2941c0efdab04f96ffbcf905a6e586562922bd73c24d8b28a4a5a19767d582","0xc09fd58c76cd7fe945f98615ca7943b811ff7ce6181a827dfa8e77d0d48c12a2","0x700a0897b8e8530c571f0f8030e45048fb919799f91ee495e0f73f6769a965b9","0x219279d4db87be2ad59abc8d7ad73004f7c2486bc609594200413e9d4afca72e","0xa42f744a8d89c693604382aa7fa6b17530b664114ab4fd4112540308c6f684ee","0x89936cfe9ff4264d43f652c063d595d591f3680814638a6894431e968a7fba7a","0x6aa6757493b4d2f67598203d5fc190c49ce6eb87fd8b0b790aec186ae2e4b4e2","0xed11fe6e613f818dfbc22ef842401e77a457c86346396b8e6500576ea7458eb1","0x1ab8d507a234753850e05e1268ba9aec3c97e57341c7bfe568111c2fd3afbea0","0x8bf1970cb910a8e6a101fd88646077f6196a1bda1fc97749bc3c9c826f4885b6","0xc3e86cd688bd44c301070d47588dbdfbc1b83ef5a076deef5ba9f45089774d35","0xa9bc560144cca238199ee017f88958b1138194d526ad3695d8d834277c6722f5","0xfe6fdeeac0b7ad54a53cad6a988731cbe2ab211bbf49821d35264e2fc62deea5","0x6acc02b6ada5aa700813c6f839bcaa1ca78a2d088ea11193e3cd7496536ff9c6","0x15dabf513c277be5ceb144f52be97a938a028ba81c7e72229660b332750b8f61","0x4a9c022b22f78b700506d1af98e5a23f68bcd5b2ee107f62db135aa43516f1c1","0xcab783ed96e59694f2f5adf48666920bb4c6eb5cd6e26033b8f1ef7a2c3c1beb","0x27ca4825cc4f981f4730126a5f3ec4b064da429d46d32421bc8565016e05f95e","0x51df75988d8f66af149f44858b74a96a7d4b7ce1918372f94baf078a60524931","0x050ecaef8bf3ecb4cd6a6d34bdd95d0eec6bf879baa52e035430020bba208f04","0xf19fc017685d00952bac857dd0620757edff00db988dc35872304ee647b07904","0x570a917ef2735730c3a6e1781df7146009ff767f50fb2497f548b374cb2918b7","0x2aff718875d54e9f6172b2a784019bed8b00ccb02ec2b671b80af2f637ebe5b1","0xf32d037ac265f5fc3009020daef3d55ce45acdb110e89545cd85392c1b943a2c","0xe64bea4f5fc7272dbe9754629d4662f35ce544c118ab1072c3dcd576c2bb107d","0x61b8847acf442e452c889e764439ac64f37dab16fe52fd8f63b1d41fbef95057","0x99c1b2b08cc7cb88c132f06e2b601d720dabdef449d97c3f237f756cf3e4cd3e","0xe8584243d7e7872d172ad43c12769d124463889b271699d9d98ebf68cb07d7c5","0x8e3e3478c49e3ed0552e90f986f01f5b659ece694bccc8260f91a99adf503adb","0xbf9d498abee0fbb45e4ab9c9ef5b3c5bde705e5cd7010b31ab72a3b33bc26d1e","0x04b0a149e33dd90fac0b1e9d29c0f7e70d3c09a8492742a8b33a8d063b021553","0x16e4bb8856b434b5e50dfe2b699300c9c0d30d3ef40650e32a137e0c280b10e4","0x3ec93e37503d9b9abd4814913d3809dab9e7d914a627866b0c1972f400a580fb","0x1e4c5b750baa30962895b061d19c6c63f3bdb7d0dbc131947a4448c187141291","0x38ac11498194eedcf397aba10f1b7a6e4f79048108c079b3698b284348f931e9","0x72337de21b4cabae7a45c5559b2dbcba1530a775d4e6c70c5d7dc3ae360ccbbe","0x3f30ffb0c94bfb674a3c0f0761f119a7704d72efb07675b296e268fa673f2ea3","0x3d7bdde6d6fe785b9b19d506990cdb8348e88961df40e8095ebeaff01546acb1","0x503cfc268a3ed066951373e45d401ae4f73ac118ae5738746dc03d0b4571e09a","0x2001d5e00a5c78d105ba9e789c7cdaa2e3dfaac9740d7de6a1f8573f3e7cc035","0xfa32b559de18952af9465e623d3d0e670bdcdfcd8c34702b538ed9230615f723","0xf8879266ed024a03179296509f759755fe0df2bba825da328f2119749c4df364","0x057d2ada9b033c70100a5e897ca0ba69ca4e1049dd662529596443b52238afba","0xa6036d1299731bb4a97f1fd2ab9eb6b37f8094e10b0958eb591b3371253a5f49","0x04b977a5df0b1adfcf7e04d5ca69d0bebc19b812b17dc6c1b2b6cddf3d446ca9","0x52caf50de89f4455683abb159e3a2256285fe7f7f49a8dd74f5ee02b915eab67","0x3810f9bce373afa85167bb661721cf3263bff423443bf78f8639714a93c9e159","0xbe250e1647de6e85878627d423aea18f0c9bec678c58c88e2e87cce8ca265289"],"txCounts":[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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,6,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,11,0,1,0,1,0,2,0,0,0,0,0,0,0,0,2,1,0,1,0,0,1,2,1,10,10,5,1,0,0,6,6,0,6,0,6,0,1,9,3,0,0,5,0,0,0,0,0,0,0,1,0,0,3,1,0,1,0,3,4,0,0,0,0,3,0,13,3,0,0,3,6,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,0,0,3,1,1,2,0,1,7,2,9,0,0,0,3,0,2,3,2,0,1,1,2,3,1,0,12,2,9,9,5,3,12,12,6,6,0,6,19,17,11,18,0,0,7,0,0,3,4,12,0,5,8,6,2,0,0,2,3,13,3,4,6,2,12,2,2,8,3,6,14,5,12,9,3,0,1,1,5,6,1,4,0,4,1,1,2,0,0,4,1,4,5,1,9,3,9,3,0,1,11,10,1,0,0,0,0,2,1,1,0,0,0,1,6,5,6,0,3,1,1,13,6,7,6,4,7,4,3,2,31,2,0,2,5,0,6,39,0,0,0,0,0,0,2,0,0,0,1,4,2,3,6,29,7,2,3,1,0,5,0,1,0,0,0,0,13,0,0,1,0,1,15,6,1,1,2,0,0,5,3,1,0,0,1,0,1,1,0,2,4,0,1,0,1,0,6,0,1,0,2,4,4,2,1,1,4,0,0,0,6,1,1,1,5,1,0,4,2,3,2,2,1,2,7,1,3,2,5,4,6,2,0,3,4,2,0,1,3,3,4,9,0,1,2,2,2,0,5,1,9,1,2,6,4,4,0,0,0,2,0,3,4,0,1,9,1,3,1,0,20,4,9,1,1,4,2,1,1,0,1,1,0,0,0,16,0,0,0,3,1,0,0,1,1,1,3,0,0,0,0,5,5,3,4,4,2,3,7,3,4,5,0,2,1,0,1,0,3,5,1,1,4,2,2,2,4,3,0,3,3,0,5,0,3,0,3,3,5,0,1,2,0,0,0,2,1,7,22,3,0,5,1,1,3,0,0,0,3,1,2,7,1,4,2,0,1,0,2,0,4,4,7,5,4,5,3,5,2,5,6,2,2,3,8,6,8,14,4,2,7,4,1,4,10,8,9,1,7,12,74,0,2,3,3,1,0,9,4,11,9,8,4,3,7,9,9,9,15,10,20,11,22,15,34,58,28,28,4,49,8,19,68,91,56,22,424,25,106,36,30,15,29,34,15,29,22,24,35,13,21,34,12,37,20,64,39,22,26,13,41,21,25,17,19,15,8,24,10,40,22,33,21,24,29,19,21,12,13,21,33,25,14,17,17,21,12,16,23,18,15,18,19,0,15,26,41,25,43,42,47,21,0,32,15,39,41,66,32,69,83,62,39,28,12,39,16,31,73,13,27,19,38,70,36,72,40,28,98,10,22,17,67,13,23,113,17,29,17,16,23,30,30,22,22,17,43,72,42,82,0,97,133,62,88,33,118,72,113,87,298,109,127,30,39,55,72,94,44,54,75,0,54,52,113,87,65,98,37,49,42,54,79,61,45,42,102,81,96,59,44,70,43,0,71,94,35,101,112,30,40,29,30,80,101,25,64,39,26,55,62,68,32,64,90,44,43,52,65,27,47,0,26,101,0,51,55,43,65,45,25,60,46,40,48,28,59,65,49,45,25,102,35,71,40,42,97,58,0,0,49,51,59,76,55,56,59,68,81,44,0,0,71,89,66,89,144,218,0,52,43,84,36,53,41,82,47,31,0,69,91,64,64,103,34,61,97,58,43,52,89,31,80,31,30,138,239,57,10,361,53,60,0,56,79,91,0,40,21,86,115,72,25,59,64,67,83,115,59,37,91,55,43,164,37,76,47,70,28,28,0,68,71,133,68,63,78,61,86,38,34,72,68,41,79,38,79,90,66,62,50,74,36,141,40,0,85,38,79,34,33,58,62,0,77,84,50,53,38,49,92,58,67,102,74,53,173,115,77,0,91,27,53,52,36,103,207,112,163,36,69,50,63,18,59,59,57,0,64,77,87,116,32,94,79,43,66,49,30,75,77,61,78,48,54,92,44,261,116,52,107,83,84,88,73,46,50,101,145,83,102,72,190,57,70,109,95,63,104,62,57,37,88,73,80,67,66,44,68,23,61,27,54,39,71,68,195,126,129,69,48,41,80,64,71,62,50,68,80,155,117,110,58,92,118,162,127,91,114,106,74,109,114,92,144,122,111,91,117,107,122,90,88,130,89,83,111,81,79,79,108,76,87,102,51,126,169,91,129,89,83,110,120,127,88,154,122,69,77,70,67,361,166,67,60,92,114,78,99,233,105,73,79,41,121,185,130,244,107,75,45,66,148,119,81,117,95,108,83,129,188,111,0,82,108,134,152,303,116,131,161,146,104,134,63,103,84,109,139,147,109,101,92,120,124,254,54,114,115,141,98,94,110,158,134,252,88,61,57,79,171,118,66,118,117,52,180,0,88,58,61,46,73,105,100,84,70,72,119,76,91,55,113,53,141,137,100,80,117,82,133,96,116,103,83,21,116,77,173,66,89,111,81,152,88,123,160,74,107,55,82,132,261,99,113,125,63,131,84,86,74,103,91,78,72,71,83,81,132,160,58,50,39,59,82,116,83,62,68,88,90,92,56,89,45,60,53,113,139,133,88,109,100,95,87,29,93,13,101,0,68,73,49,98,168,80,69,146,89,95,122,87,175,82,125,82,67,90,107,160,78,138,151,100,110,89,4,63,212,84,85,127,97,77,22,86,79,79,108,164,112,97,84,96,28,176,136,104,125,96,0,0,105,81,140,143,66,108,80,95,120,64,145,118,156,71,111,81,177,190,104,92,77,102,106,60,127,123,116,66,94,117,159,56,196,149,94,132,131,107,88,58,90,55,116,70,101,95,70,108,111,52,80,81,109,69,78,64,83,91,112,96,98,70,91,111,82,155,90,104,139,114,144,104,72,73,104,176,66,48,87,79,108,101,115,88,114,55,85,93,92,145,39,68,123,86,156,52,123,118,143,88,388,91,76,104,85,57,86,75,75,61,78,117,87,105,58,98,56,84,118,58,109,94,84,79,73,80,119,80,81,88,128,197,60,72,73,51,76,66,98,72,79,81,91,96,105,164,55,38,86,95,104,70,77,77,66,70,150,74,109,160,72,114,61,34,125,67,80,47,48,104,155,52,71,131,57,108,58,107,86,224,122,157,72,151,61,316,107,111,17,126,128,117,130,130,155,79,125,74,445,341,82,81,163,72,73,123,119,179,54,66,51,94,108,68,69,45,84,76,47,46,61,70,57,51,59,53,20,51,88,107,106,82,68,79,54,200,149,51,76,69,42,93,81,93,82,56,58,67,59,66,90,75,68,93,65,89,54,72,65,73,88,112,77,44,146,47,78,53,63,154,45,81,88,72,70,64,89,68,191,66,67,78,70,88,83,59,86,92,44,66,51,72,117,63,61,73,96,68,122,73,620,155,744,236,36,107,338,587,190,550,397,620,273,492,228,264,236,214,525,284,107,221,230,318,327,179,255,431,66,81,95,92,72,125,116,100,72,159,138,73,101,286,111,113,108,92,118,104,1056,160,149,92,111,65,144,117,67,82,76,90,173,70,90,82,88,97,118,151,96,163,134,62,62,65,72,82,93,64,91,122,220,153,56,171,98,165,86,210,120,112,119,96,126,85,109,58,214,224,241,111,132,161,84,123,91,109,82,177,180,151,179,154,166,145,159,19,114,107,168,50,69,119,119,158,213,145,98,120,73,108,71,89,111,221,152,164,14,140,127,120,71,112,85,111,133,116,93,70,131,138,137,160,73,113,68,109,120,179,149,184,171,217,139,109,158,99,156,224,328,132,104,195],"txHashIndex":[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,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,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,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,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,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,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,0,3,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,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,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,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,5,5,2,0,0,0,3,3,0,3,0,3,0,0,4,1,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,2,0,0,0,0,1,0,6,1,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,3,1,4,0,0,0,1,0,1,1,1,0,0,0,1,1,0,0,6,1,4,4,2,1,6,6,3,3,0,3,9,8,5,9,0,0,3,0,0,1,2,6,0,2,4,3,1,0,0,1,1,6,1,2,3,1,6,1,1,4,1,3,7,2,6,4,1,0,0,0,2,3,0,2,0,2,0,0,1,0,0,2,0,2,2,0,4,1,4,1,0,0,5,5,0,0,0,0,0,1,0,0,0,0,0,0,3,2,3,0,1,0,0,6,3,3,3,2,3,2,1,1,15,1,0,1,2,0,3,19,0,0,0,0,0,0,1,0,0,0,0,2,1,1,3,14,3,1,1,0,0,2,0,0,0,0,0,0,6,0,0,0,0,0,7,3,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,3,0,0,0,1,2,2,1,0,0,2,0,0,0,3,0,0,0,2,0,0,2,1,1,1,1,0,1,3,0,1,1,2,2,3,1,0,1,2,1,0,0,1,1,2,4,0,0,1,1,1,0,2,0,4,0,1,3,2,2,0,0,0,1,0,1,2,0,0,4,0,1,0,0,10,2,4,0,0,2,1,0,0,0,0,0,0,0,0,8,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,2,2,1,2,2,1,1,3,1,2,2,0,1,0,0,0,0,1,2,0,0,2,1,1,1,2,1,0,1,1,0,2,0,1,0,1,1,2,0,0,1,0,0,0,1,0,3,11,1,0,2,0,0,1,0,0,0,1,0,1,3,0,2,1,0,0,0,1,0,2,2,3,2,2,2,1,2,1,2,3,1,1,1,4,3,4,7,2,1,3,2,0,2,5,4,4,0,3,6,37,0,1,1,1,0,0,4,2,5,4,4,2,1,3,4,4,4,7,5,10,5,11,7,17,29,14,14,2,24,4,9,34,45,28,11,212,12,53,18,15,7,14,17,7,14,11,12,17,6,10,17,6,18,10,32,19,11,13,6,20,10,12,8,9,7,4,12,5,20,11,16,10,12,14,9,10,6,6,10,16,12,7,8,8,10,6,8,11,9,7,9,9,0,7,13,20,12,21,21,23,10,0,16,7,19,20,33,16,34,41,31,19,14,6,19,8,15,36,6,13,9,19,35,18,36,20,14,49,5,11,8,33,6,11,56,8,14,8,8,11,15,15,11,11,8,21,36,21,41,0,48,66,31,44,16,59,36,56,43,149,54,63,15,19,27,36,47,22,27,37,0,27,26,56,43,32,49,18,24,21,27,39,30,22,21,51,40,48,29,22,35,21,0,35,47,17,50,56,15,20,14,15,40,50,12,32,19,13,27,31,34,16,32,45,22,21,26,32,13,23,0,13,50,0,25,27,21,32,22,12,30,23,20,24,14,29,32,24,22,12,51,17,35,20,21,48,29,0,0,24,25,29,38,27,28,29,34,40,22,0,0,35,44,33,44,72,109,0,26,21,42,18,26,20,41,23,15,0,34,45,32,32,51,17,30,48,29,21,26,44,15,40,15,15,69,119,28,5,180,26,30,0,28,39,45,0,20,10,43,57,36,12,29,32,33,41,57,29,18,45,27,21,82,18,38,23,35,14,14,0,34,35,66,34,31,39,30,43,19,17,36,34,20,39,19,39,45,33,31,25,37,18,70,20,0,42,19,39,17,16,29,31,0,38,42,25,26,19,24,46,29,33,51,37,26,86,57,38,0,45,13,26,26,18,51,103,56,81,18,34,25,31,9,29,29,28,0,32,38,43,58,16,47,39,21,33,24,15,37,38,30,39,24,27,46,22,130,58,26,53,41,42,44,36,23,25,50,72,41,51,36,95,28,35,54,47,31,52,31,28,18,44,36,40,33,33,22,34,11,30,13,27,19,35,34,97,63,64,34,24,20,40,32,35,31,25,34,40,77,58,55,29,46,59,81,63,45,57,53,37,54,57,46,72,61,55,45,58,53,61,45,44,65,44,41,55,40,39,39,54,38,43,51,25,63,84,45,64,44,41,55,60,63,44,77,61,34,38,35,33,180,83,33,30,46,57,39,49,116,52,36,39,20,60,92,65,122,53,37,22,33,74,59,40,58,47,54,41,64,94,55,0,41,54,67,76,151,58,65,80,73,52,67,31,51,42,54,69,73,54,50,46,60,62,127,27,57,57,70,49,47,55,79,67,126,44,30,28,39,85,59,33,59,58,26,90,0,44,29,30,23,36,52,50,42,35,36,59,38,45,27,56,26,70,68,50,40,58,41,66,48,58,51,41,10,58,38,86,33,44,55,40,76,44,61,80,37,53,27,41,66,130,49,56,62,31,65,42,43,37,51,45,39,36,35,41,40,66,80,29,25,19,29,41,58,41,31,34,44,45,46,28,44,22,30,26,56,69,66,44,54,50,47,43,14,46,6,50,0,34,36,24,49,84,40,34,73,44,47,61,43,87,41,62,41,33,45,53,80,39,69,75,50,55,44,2,31,106,42,42,63,48,38,11,43,39,39,54,82,56,48,42,48,14,88,68,52,62,48,0,0,52,40,70,71,33,54,40,47,60,32,72,59,78,35,55,40,88,95,52,46,38,51,53,30,63,61,58,33,47,58,79,28,98,74,47,66,65,53,44,29,45,27,58,35,50,47,35,54,55,26,40,40,54,34,39,32,41,45,56,48,49,35,45,55,41,77,45,52,69,57,72,52,36,36,52,88,33,24,43,39,54,50,57,44,57,27,42,46,46,72,19,34,61,43,78,26,61,59,71,44,194,45,38,52,42,28,43,37,37,30,39,58,43,52,29,49,28,42,59,29,54,47,42,39,36,40,59,40,40,44,64,98,30,36,36,25,38,33,49,36,39,40,45,48,52,82,27,19,43,47,52,35,38,38,33,35,75,37,54,80,36,57,30,17,62,33,40,23,24,52,77,26,35,65,28,54,29,53,43,112,61,78,36,75,30,158,53,55,8,63,64,58,65,65,77,39,62,37,222,170,41,40,81,36,36,61,59,89,27,33,25,47,54,34,34,22,42,38,23,23,30,35,28,25,29,26,10,25,44,53,53,41,34,39,27,100,74,25,38,34,21,46,40,46,41,28,29,33,29,33,45,37,34,46,32,44,27,36,32,36,44,56,38,22,73,23,39,26,31,77,22,40,44,36,35,32,44,34,95,33,33,39,35,44,41,29,43,46,22,33,25,36,58,31,30,36,48,34,61,36,310,77,372,118,18,53,169,293,95,275,198,310,136,246,114,132,118,107,262,142,53,110,115,159,163,89,127,215,33,40,47,46,36,62,58,50,36,79,69,36,50,143,55,56,54,46,59,52,528,80,74,46,55,32,72,58,33,41,38,45,86,35,45,41,44,48,59,75,48,81,67,31,31,32,36,41,46,32,45,61,110,76,28,85,49,82,43,105,60,56,59,48,63,42,54,29,107,112,120,55,66,80,42,61,45,54,41,88,90,75,89,77,83,72,79,9,57,53,84,25,34,59,59,79,106,72,49,60,36,54,35,44,55,110,76,82,7,70,63,60,35,56,42,55,66,58,46,35,65,69,68,80,36,56,34,54,60,89,74,92,85,108,69,54,79,49,78,112,164,66,52,97],"txHashes":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"0xde30b088bb933554adca87ae9e7032e2ab7eaab1f591de4a12ee936c5939dad9",null,null,null,null,null,"0x2744b7d749cd94335ae5106e3ee2c987763443cfeca9a84b93abf1f4cc655cdd",null,null,null,"0x02938762fc30145268efb733110cc787d741471cca8ee5e8355fee853ef62d46",null,null,null,"0xc2f22dec73e3ef74ea82981e14a1ad09480fc0bc094ee5e9f9fdabb28e7d35ff",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"0x6f4032b030ecd98df08861345f19ad2c705f2c53229b36481621e57f70107a63",null,"0x2cc1d9190206f5b87d9f12d8d2ed05bcdbfe13dc7ffa3a0360f0a625f93d4ef8",null,null,null,"0x2fb86402249c84baa19141af3e059f2642fea96c7d91bc895dc318e0c7870d56",null,"0x3fe61b03b2a16a833c8cc69bd69eefd8ab68088235276eaf27926c1d6db3be4c",null,"0x008436ced114d691a47f10c7f5edcbbc455bfc29d348e689a3352c2a032f3e09",null,"0xbf98a5e0b303dfd4d26d095cb19e37f94844a1ae675dae9cbdc9f332e13eb955",null,"0xcb036a26b51bdde7b6e957afdcddcee7d3991d2719cb155b66b31a4068911997",null,null,null,null,null,null,null,null,"0xa672cb0b8c3c91d900441910f38b70418ed8e7a70f9feeb4f505fd407cef1de0","0x06ce359ce232aa3897d4277eacf8a4babb5876c7ab4fa83e056bfcb47b1829d0",null,"0x2425809eff2760946ed1e85a780be25cadd0eb9d17a80329144b47614155f8ee",null,null,"0xdb7b4bf24984b8908fe136ddb9ff0bcaf70409033bf5df439e4d11e9c1fe305f","0x5e1a222ddc918a84ddba43b4c0238c4eeca552b0b96abf9290a9451eda620d55","0x96d6b9d2e299d633854434bdd3d0e56c6b709a68531a99e73238e853ce63cbc6","0x23a3e7069a6a72decdd6976b6523c1a823dfc0397e8a2aa4e85a573f2be5de62","0x71ec4f8c69350eedcd10fa089b58a03e884e2445530d2f380c78f03ab9ef6d00","0x9fcbd97ddc6700b3358eda94e442641f19aac67bdb4a32de0bc4f6f03129372d","0xf4639b3fb48c71f96ea5df820651b41d6f06559c660e39fffc8de0ea98775064",null,null,"0xb8531cdec0cb8da6f11230a210dedacb9013a3cf04329a95365745f7dc56ddf1","0xbdcbeed389f6ef6561a668315cf374ee3da56ce2ac4d55e95a8f6339fc8c0171",null,"0x6c31f583dcfb358e66fb3a5118cc0fbf7ac0ca0b1e0a5780962ab4bd889cbad6",null,"0x0c52362dfbd7059e3b93078b9ed363ec20cdecb41be22f392c699217bd0ee5c0",null,"0x171ab39099645d285bcd9f920d9844bffac18e0a963383342cd2b48f51d5bc54","0xf7ba684f6a3a92ac7a1bf58723dc57f7118c65090986df78c880bc45d0e3b63a","0xf6e8eaf6e7d9072b5c9f36fee5b2d1624f193ae2b00c73888bb413db523f5c79",null,null,"0xb0c1aa925ad9d3af99b51fc09d52ac9458ad1903f38291c561154c801bc7148d",null,null,null,null,null,null,null,"0xd3c79d05824ba0927f458688c1b405d012e62f29392d0ae5cc9416b78a40e08e",null,null,"0x2a6e1bd3d516e507ed22fb50af74c9dfbc85a6cd94087cd90ef934c00f5476a9","0x0087d345c8d19af0f9b4e696b2c435a9284d5454f828630eea365d0ce60ff21a",null,"0x597fba081f985b806fa98600940e1174776464408b05b6b06a79e5e00d16c663",null,"0x0587eb1a0e935d7fe0f2b640944e102bb98cf9ddd84f557b67a094f23bb31b28","0x3b3377e166ef24616657b6a543bcaf740729b488627fa7dacfb594d74c0c8b45",null,null,null,null,"0x59262c7c5a8c956d8346d8f71445b59b74f09c6650d27c6d83567b7dae3d3f01",null,"0x55d88fa43d80997937110f5b011195e2f79456480b2f2c4f66b98aa2826e61b0","0x462b8494e24b689af5d90e2d656d2a5e26caac1af58220ee5afa758e23fe841d",null,null,"0x1f9941cd97133342a1e89dc52700fd35c8c9820610c57ef2c354f80f5bcfc8d5","0x90ddfebd08e5b0a12b56f643247fd2a6805fb63725b270d2a5c58dd3f2c891f6","0xe13938aeda0c029f83472b1297148653868ab40f0b29ef4763994d37f1da3844",null,null,null,"0x8c9cf938453de5b3579a281bbf4d94bd7595fc88a75d9506e95b7be0aaaee698",null,"0xe93cf4923a552ea75b5333a046889d49f498c53ae7e255829d4de0a4b86b43a8",null,null,null,null,null,null,null,null,"0x52e6553306efe2cf031d703bdc6bfb7dbfdafd39f785619578da1a3eb1281ce8",null,null,null,"0x8140a0c5d28da90315d5bdbae5525acde32c8806850edc21357f2253c8f0b762","0xe30e54cd3bd99874bd16ed300960831bf22d95aa882c22e9aa82b9b50c801631","0x508fe0dad4524ad719402fbbbad3bd6c592cc683a95b329b0f3397cae718f8eb","0x739db8837907972fbdbd5b7b333650c9821ad8e6761bc94e56121b10bb309b94",null,"0xef47541570bcae2508a4121083ceb8ff5d903c49a69d6e2f7b8131c5ed065eb9","0x3635f4310c91d4fdbbfc96d7042bbad7f9d50c13d01caa2d37ff4927a7873631","0xef389a0ab2be054fb56a2747e57742b14995cd94153ec8203bafaa13baa013a7","0x75d7a4122136d8e18e36406ca5141e07f0220bbcd403e9af4523084992a6bf82",null,null,null,"0x8ff645c4b1e101f9f30a2f1e858563db0ea881a834b13e9965081fe7a245c33b",null,"0xfee45f2ca767d52c46d82768c08b1a4412723147623a84de1f64f98a54c726a6","0x054893f6061bcb44485267390f8e847b7380ad6a17f17583ee5171fbd873c430","0x9b1ef1a1c9bf53cd83f227948a1892222f3d41100709d56416991c79d7f2a0ea",null,"0x8444d8bd1d66bd77f50e8275d60855ea28fb9111f14c39bf81a8a73ec5c06c34","0x170a8712f7d1ae1f24dd768f712ef641f9324540fa10d633484f673f4a9bea4d","0xa28e80a7168eec7be08f764f513a97adf845ed9fe3ee975573f8369ae7d267f1","0xfdc4e0acacb3b0e837dca7ffa618ee71f7f8df3a45c62399be48c276827a78a8","0xf50e91f202fb1843f2ea683a03356509f00186e05c083d1f3a5f82b34415a53e",null,"0x7f64b9b76e90e20889c19e728349828fd47004648052c347e30196ec4b50375b","0xe6fa4f93b2b13152d4c8e28bead558fbd853063f74a9ccfb7490cd004dcfa3ab","0x494cec7a70b910374710b569c51fa7fd63bd6022b43151e75da3bc92de488477","0xfe76b210f1af756df5ab89f42dd910f08cacc479b7f96e07c870c3cf9ed52ce2","0x1409ee8abf37b286c26381da32669e1ed02be0ea9dd9c9c27dd1f8ed74c54952","0xf25b0da11c6abb1bf486d0fa91ba01b6adedff65c95909c667de5846a7bad607","0xd03204eb11247e3e03bcdc6d783be8ac575e75329d516924b0363baf7077cb69","0x227cbd66dfd15314480e7db1fe1fdc8c3726da92afb1505aa1b43b71b48751af","0x109a260146baa4b69e3297d61faae0e10f3d3d2a579803ae87de19ebabe48211","0x5c8241a60f61d143541ad8cfa7550baea70d8d0989a9ccd959ca302cfd5dbc04",null,"0xd96ebc2317fcd274519a79e70485881443b067f2741e23d2822ff0d7b19537f0","0x5191140f66e7ce8f13edf89fc3f176cd0472d63364d628f4b7891be781fc0e5c","0x9d858eb89920ca369057b3ff03adb413840690d7b84c97dbae416b75a733e376","0xbe2973240bf13cd339900f0c7cc75a77f099cd25170706050ec81aa404f05a95","0x2556cf1ee66167e68c5af508786eea1a8abb68bdfca98d7a282ffd0df86c5a1b",null,null,"0x10e9456497768c65b02528623ec181d4feb3f5a0695af0e5c68f537b6b4f5262",null,null,"0x84dd00831d8284bd6359b2f2730a2029a736a88e93b28d973eb4bcf1e518091f","0x23f6dde1cb4ff7c5a5f8465c1f5419da027d39409e2da2690fa2a71390f59051","0x4d81a95117133eb50d62d155bfc68ac808605b044e39f633c4ffcc6e2f70bd97",null,"0x373a6bd1c821df070299f65816cc10a0a8dca3b8547e93cca48a31a1e72f7a2b","0x0161e703f56cfea22643ec2582faa5f6e68a637c8bb22164bbdbabcd34608159","0x36d8ecac5323ff0e1db3a8104d98517e886a977fb5dc4ac21cb81a8fe8bb3b50","0xf6e7ebcf59f58d9c985af385f33ece1b37fc4147029f7ab8b08829e7ac873f07",null,null,"0x171c0962dc8d4291e357e996b9efd31ca469aba5242c60025d623c55c286847f","0x538c9bbe4d4f77bcad9a17287112416584f20b187d43c676e57f967db52bec24","0x6c494d06b9f0c94cea3e9fe8a015c423beb4d18b0078cba5fc1d5805114721b1","0xf5a057fdbaa5a6d935d1a112a43d8f66714d74740d832fa0f7237104d363fbc0","0x4d18a9a634b2243e54f60cf0a9e82f0d3d51878bcb6834b6a7a14e5ed0594639","0x02b65390d7f2dc15a25173f6a50f5078005046660c0243fb3a00e05f724cca55","0x0b1f2e5f3e7f61baa4c20e110fff220da54b86def498cc925b0dfb4e0d776cab","0x44dc3249edb33307a7f3a88beb231995d46cb48331fd496304a21fc170f8c73d","0xc637815c7c97b99dfc19d807d8b77767cedbf2d1069c63343b0169241c314749","0x4d610e1eaf7d5f6d27e3381a14753fdcfb2d9946439067779dc131ef4a0d3e7b","0x701250b9b452384487d56921e2ef6f1233f73701e66ac25c813ad4dae37fb11e","0xa802e0674386639daa90c578d195aee4a271296ad95b86874b7a15b059161b40","0xa02d974de7daa132e58a5d30b40d8031bea1354082a898973728b659747f37e4","0x64b8b3c3b7f51ee24e176f87a5a82404e2e0d2c3c2a4c9416636508768f5661f","0x304fd83d58ebdf17db6f185c65d55ccc11b9079b2dafcff712d8eb7f4b16631b","0xa50dba9aa6e0932c833cf8065c90733a96a190c96dfef869a3612c7ebfcd37dc","0x91114c35f69c00bc075b43ea1643e757fddb6b367352fd4f374b842c7d7cbe86","0x496a61cfeee0de4d50c4be7bcbca4f7aa68d5acc1b523ac13bcc7a530095e5c9",null,"0xaa888ff7d54619794e9d9c5c9761d0d1040d10cb338d70eb1c781be8e8667c2b","0x0baa82b94e163f097789cc54509564f535ab5b1ba77dbff27000d6fc5681789b","0x6925aca058984946a5b2e2e8c4b7f9d68197f67c0b41d1098987cf9a83cf3dac","0xacbfeb29a2067ba50127e90fcb3b8c75b1ec4859ae3ac984d2513d064148976d","0xf6e8406dfd41d1f2415a60bb0c9d6e721e894edd507cced6f33fea80c7a4a156","0x3165a1468d346e3bdb8b5042b18dd3afc5359c956ba1ed1b6544447506e8a420",null,"0x9c895914daac05854c3628215ede6db1c0a2208c8d7990a718990361d44748c0","0xf81be0427adf4725d061c989f8795cb21d7cbfd5c46971805049a706b0d763c2","0x1dd3b2c261cce1d877c996cadffc49deb4131ef06dc93457b23792fab64ca6c6","0xbc48db3876ad3643b3c39f9383be13a1327380f4ea915e360353bae3c1f6d674",null,null,"0x17cada85a47e93d3def82b73c0d0b96ce008e54a5e9960914b2c51dbf134b45f","0x03e7a0544d81f31ba07401a29ed125e883044e45f57f0b84672e16c186f658c6","0x706a8a6eb6b35b33c770b57b2415258872ef330fc2b402c1e082cce7a63a6b33","0x06e91c18fe7223d9fe284ac37093b64e03631aa5f2becc3b30950b12000a71b9","0x31a0df7d8737f184640065aa002038153d7c7ec976764cc5b3cd8aa84977ee92","0x1886ffa60e269e804dbf7194c5d1c65411899d71e65f2fb7f416d2390eb7522b","0xcaec4da2a7967a97667f553e48df7925a155078623797ef963a73c0eddf8de1c","0xa353ad81576f8f7fbcb216214b0841099c15260ed8522c957b42e829d9fa09a6","0xdc337d24e58736172629e765fcc70d1ced4eed13e4c610788ab9646f73a46c60",null,"0x847206c92cfd7f1e24b02beec83214414e887a4e7b3dc471763243b0b047ef60","0x9a0d10b6900c18195344a448f1c337689e05638ae874c0f32fa9c72b14983d15","0x054dffc129a9cadd292bcfec3d16cefe24c6d5737fabb6106ce09c41006a8a99","0xf75220a27d9d072ab3463ec9c04961e6f183f080722dcf040accfcc4f211ae9b",null,null,null,null,"0x4dbde3684648cbdd9ade6cd91e42d4396d11f625fd39da14f4c3221609d127bd","0x254aadd82b64313309133bf23f6f5ecfae8c0db5d902aad2a26f04d3e979f862","0x9b707d63cdec358a293ceba39c0cca9eec359f2e2ea8a6a538efd6a1d83529a3",null,null,null,"0x9f8e0510e4d61341be6ff95db677d2034acd27ff40de4dd246c30d724b9513a5","0x9a74059a2bfc5969e3bedcd4f108440b99426ec12256bd1ae35d7a2a09838a70","0xa337bde20e26034c4b63e0d8893de4a7751dacce34ae0c475f5b2849c1d186b8","0x64c70ec8a01a6a1cfcff7dd02a5c794bae6d9741ca20a00d6e028982c5ba7ee9",null,"0x2142478ef53a919536f849163f8e3bb7c1efdecc105b42337507e1ddba5d54be","0x441696ee1f40763bc25239427fd9b31123aa9ac9d7aca995f8a2c9868131de36","0x9a5a9fb4ad399dbc7eef0558e73f2aa6f2ba0b74449e174d15e6e428dbb09532","0xdb9e6b1a7fff449dd37b37037dd2731edc85370c8df40c85fcfc09687fc80f55","0xc474d7732436c703b178081eae3a807bcde9025336f6cc2663a3c6cc4fae319b","0xa73485da13ca6436a91c0f1df4fd104b4a2077f3e5a68ae33854b97cb6f9ac3e","0x5912b67aa6ca6518a1a5fcae1e0852cb4800e46160fb35815fae58e415ee3a3e","0xd9562cda6c29976bde4e047506e243002c883319e109ccba2e9422763142f08a","0x7cd345046ce15a9c6e4937fd3306db5b88efc89fce7c3602d07cdb73dde8cf3b","0x8ddd7bde87d54d0e3e231bcaeed4072a0a984f7f689d2b6314fde370f7328081","0xed8e7117d84593f71313caf32c7c46849ac148946d23a9b612b202f3e81b8a47","0x1dde42476b6872737c8ce60ac445950306b5b81692b953c580917980cece64e7","0xebef5e882daf03f6b287e836237448a040d4c781236555ccc7909d8dc2d49c9a","0x64a3756faa824a7f2746bad1a5324aef4b7bdef1cf0baf45bff98bfd5443a0c8",null,"0xe13fb729a6c143151f58fe8bb2ae02313f0ecdd0f3c81d134e07f41b74b91b12","0xe492159b8005914f011618106d85d9deab9cd45a485dfb1211d64b61a0d1caa5",null,"0x8521732bc712e5a88bd1bd92d7dc7bd4649d2032445be123284ab280b8928976","0x4b6f4d246a4c48ce1bb7d82b15cf0c5020abdbb983e5c373360261fd70d93bb4",null,null,null,null,null,null,"0xdb4106bc4a68ab6e7ea7ad9c92dc94c52e4ca3328f5d3722dd1e9cff190e3de8",null,null,null,"0x9217a53b6d0696b9ed25e238128b260bb352750ab5fb35c6c47403757883ec1f","0x457a289047a69e07c0162b9cc8e3b32ef40c0ba0d6befa26a2b72b655b91d472","0x094c58bfad42beaec4a48463658d1bea42269411bac6309dc814f09e28520916","0xf96902637afd3307be7ef0ff70217e40ee75d3fad0685efe4052aef616c28d2d","0xd3aa73dbe913dbeac644c4ff333869763f33de05ee703d5decf9a7d196247db5","0x9282904493d747c8a5dc621d8199770c291f6e97817e229ec422e9c52ec017df","0xc54888a7c09fe4341325248c2bb6a34ddd8d4e474831c57b775312d9b291ee61","0x8c869b8cb0ffbaee48508cbedefb4ac16b14326f335e4f6d5047158fa19997ce","0x74fd2520eb62f557a02c0350c7f1f7d2ceb55c8faa24357fa6475f200e8024c9","0xe7cf01e3c4341ab8ca44210a227896d75c39b02da51af1d7b3b83d7c32ab3741",null,"0xab605d17676390223dd0447d97e94a787f22bfd4ebece3e91a44f5f5c8f2b35f",null,"0xc7517b359c05fbbf5654afbde387d2c6c260c7c8e5b33db086526a63480e090a",null,null,null,null,"0x6b023ca7480d4dec24050eef4452848e15a4eea6d5f5c4ecc515cdc75c96441d",null,null,"0xda1bca10186c1846789002167b6c5146bf17cd3e4901312cd2bd55b0e0df5eb2",null,"0xbd7e25b33e59e5efcc699955d261a4bcb703164513323b1527c42dcaa7d382d8","0x4d8242a7d1a9c2e4ddbafb2696d60f9ab828026dfe1d575bb24130e631d1bfaa","0x574a61d45a1a971f70f6491ffe567942531c232e588bb299c716ddf8f58badf0","0x19af7319af9cfdf485cadbebe696f1b682c82b10211462efdb8b14a416db0b28","0x019e207054521c0f7045f73452b57b90f13cb7001b65901072f13f6dbc6f6233","0x0a10a2947954e8fb1c8e4446456edc9360ac16e7d85a5774aab69ce842332279",null,null,"0xdb43cf6a04f93a06f729bf550123333ff0336b6b7c51141fffcb3520856e3247","0xc14a4675c75a0b05b3bd9ea34955c8dcdc25e52a19366ac3d18356114ac95226","0xba7bf34b5ba5a0a7cef54743143297085a028cbd9baa577b1bc8b02851e1fc9a",null,null,"0x49fe177cd7bdc4f7247424cbbe133133bd5c8c7f3cfc4f271bf173911f56c967",null,"0xa6d714ea692d485629cd16e53304abf77697f595505f6d4fb19d3d3f8b195a1c","0xca8d776e8bf30a5b2e897969bebd37ea405111e3f66df533eb77f689f5daae33",null,"0x9c17a80d8fc612b9426994fa58ad906595ceb462e02ef3e7986f42b097ab30c3","0x32104e6da4c2335f2c46035329e5ddb4d40f9d264243719c9dfe17257e45ce9a",null,"0xce0d541a0b7ed12946e0e7e86c3673a38e75484cde19b98754f1486b46271483",null,"0x3694caecebf33a16d67856573ca26c71decb72147dcd9457cad0e3bcbb36f045",null,"0xe81acb77d9d0748d672011c3d3e5376daaae55d0cd508ffe15e36bcd209db37e",null,"0x5010f07d7de6070b641710551658ba3296eb75c0ff0f164e844787cdfccfb43f",null,"0xab9a96ccb298bfce2471ec7a6d22702819bc78e3aaeafc3bfceeb199d520410c","0x688c48574f9aaee8ad96bef40b111db85e73c8c18e535dae2af986a25d64bda1","0x964b1613d93fc9cb086a1164101ac7500a6d07b502aea38284d28446764820a6","0xda1dac6d723c82b218926d0e8b07b62b310c074a9ef22022f70597fb4d5b521a","0x8056c9c87dae46697833b108aea6d4d529e015bd83de3e6bce8cee19a17e1b13","0x1162ebc60024bfb21988a60145c353ccb7bbc6c5b8d996f168b2a2f58a02c495","0x9233e1189cf0c2f8a39c9ac93e7e6f6a2bc8d2388c422c7fdbbb5510977406f9",null,null,null,"0xb244898654a270e23dd438ea55cf70aeca31ec9f44a4b9b592e80ef89370db53","0x66c385cae0926e53da6751fd5eda6b0d9d969673a5cfa13ff7ba9d790cdb7992","0x499a8103ea331550db0f28325a3c866fe88da65f52ab190e655036a027429885","0xf5cb0e35d7448869766cd989d072291b94498952da7749d4fcbd497327f812bf","0xe557c4db40aca5b9ee5422c8fc4cc2961b090935983ec79fd82b6a44afd41619","0x4b323866a37d67f821026966a701664219b6a1085e9e435a5cc281aa9924fb82",null,"0x0f00a58bb956135e617e315eae857866b982010bca4ddf4316dc782a7acccbb0","0xeb96232a88a255a9970227928153ce12c91671dc94739722eac87686366f17ba","0x6e2c8a7807ba62eec2b500d4ba718c581e13e67e0565e67d0d6ed3473edeae0c","0x4e8f1a2d85f00034dd1decdb0c7dadfac9d7c71b53d7ca1209d3d313805a01bc","0x9c456c913823ffa8203ba357a3254fb2dc1d870c7763f26bedc9b303f5515428","0xb7cadd1a00d3789a03e630befe8c494eabc551913c05c324e00e80f9b024e930","0xe2235d7f0319d531e3291966837050fa5df178b0fe6f299cf172e721b1f67354","0x6c2c94316c16a29928ed092ca9e1d3410e52a33d2377e4a05ead9a44ec1bfccd","0x1e23ba0d0a73a3568b5aadb26b71559b80057a51acef2a0e2338c5cf90b32525","0x4563eadaf3cf2e2c7d307071d2b86457f5af51a5c5e05d154994e688d9bd7d1c","0x18254ab55940444ec6693839f630e36a659f86749ee44c623c533914675e4d74","0x014e4d0f3dd2d3a59cbffa449bdfd2b582d63d787fb16c52037fa267ed9169c4","0x151dcb478ee6ec58fe7210cef066ccb993eb55def36ab947f86910975d5acaff","0x412179fbea1783bf0f92a559d738d3fb1e048e4ca5138354a25bd5d35df7b989","0x60f6b0f07a344c3391adf92845a5a7aba4e3dc9c6acf223d2df082bbb68d47af",null,"0x37ef3a63406a137d47b71b884082570e24fa2c93af2c4d5acc1b34d10ab87a60","0xf7f4e404737ce30fdb8b6973df989a3966a6381acedfbb3d0506ff893ae28848","0x6124f4f5f8f2aff8fcdb7d4cf411149ad99d4a8de967062d16a8545fd4abcf6e",null,"0x040d9be34aba041bc7df7a7261e97bd71a97791c5797a8012b4b5eaa93725bf9","0xfb36453d10085c9d432aebb97353ace1cc859f905f183d68530efa82586246c2","0xeb1961761e492f601e3d351e05515ebe544035c5cdd4409fe2855893835dfe59","0xa0f08bb0ba81864961ed1c5f2aff8c632602a9c3544d938aab6423637eeba9d0","0x55a9e8ae636be21da9ce6f4274d09847dde4f0faf1242a36d0c1cfaa35a3035e",null,"0x7eb7f099c56156033c0ce6b955a2e3a3734b5578f582041cceb7b0c8a7d31049","0xc44d4123928dd97b0d9765a264a214cb0376d6b6571b80453e1dd2a6feb770ea","0xa2a44c4ed6769216714f0b0a8b7af96c7131f1468a4230b924743c90cd05a406","0xc0ba7a6adc3a9705d5738ecf01da70dd695aeb8d3270c02024b6266387afdcb9",null,"0xf63a892a9932555a1a8820db7eff5c3fe96853e6c354cdb39ff61f18e4537d82","0xdadadef4768aeab6f653cfe3cf0710268495d8bd00aef4ecbcafa1c0b0c96041","0x91a47c44cfe9b46207403775ee80846b273eb1c481073d35766a32728f71b4c2","0xe7e64473d8f2570d1496dd2778f65dc295277e3db8ee4b19850e1bae5e7e8c0c","0xd1d8cfc5ba26b4250e656808831943cc0d79ecef85200a6ff09c4dc84ddcaed0","0x1ae56bfa8956e676932fe1ea14d0a8e0303efe39ca8558fe8f63a16b1955dff0","0x1e7c44f70ad9e2184e7e65f6d5ba89b8c719d14294283590ee8a2cad3d8565b4","0x624615f6959c9257490052c08657281acb47adf360f71fea8dcb5ebbf911ecfa",null,null,null,"0xeff43442e1eb16ba2626df06ff3348ecadcb2e93b0d005ba7f16b29cfc938b4a",null,"0x6f3c7669c46aedf92609c0f99fbea65bb60bbd1f033873a8552f037083c7b920","0xcf1378508157d75f54164dc1e15fdaf17098f094bd01ebccef3b5aa47394f308",null,"0x91b79e8258f8d6ecc7f1e64460b55c800dcd7352ddf9f3b84187b0a7ff1b77fe","0xd070b0e936be9066bba1b44b69ade361061415dea226809818c419eaac5fbdda","0x34d91758ce79f0426aa993b9a54957c6e5dd2828522898d53f54ff6b2182a1f8","0x253624fc9fc6207c93d4f635239ed7994633c9f3659a97f87d07b4624e84ee54","0xef0095e4adc906479f63b6bc562029f458b1845b92fe8b9f03d04baa1a93bca1",null,"0x4cf2eb6cbd4cae7bca612529c037f7787cc1ba0800617c1b288c98b9ca5783b0","0xb3a81c50632efb01f8633dd55657c1ba9bd50a60a84166ef31651b721a79a440","0x60e25134f227564cecb9269db84bde49cd2712b98bfdec2caea0bcee1ac3e362","0x820c828f531168a0cef1d97a9dbd6e87ea57e05d3c8781ec83e499341b34bde0","0x5eace2300df4a24bb72457040407447b9fd5abe67cdf47e77a758c8a05fb008d","0xb85867b3f6928dafc3d873278b8c19233d703a699a4b3c873ba92f56e1825721","0x39c7b24a0d085c3b48a7e0f0343937994046d16600e4d52683ba8bf8db4aef12","0x54d5111d85f7477e948d4177c6ff753ff3ed640e7780deb9dacd5f3abf606675","0x291721dd749eedd9aa69a89c2492b62404812eea4ab06f073fff0df4335bec03",null,"0xfb4483a698b84182bb1e9c5d0782022b77e643f1dc2401b9513e06d7fd5f8faa","0x4c005e7a1f2a46438e91d2db2a9b750c7ed634f98963286be7818015390cf763",null,null,null,"0xb0a0fb1516d491041da859d0480090e39060bbb6237833563b464073414f221a",null,null,null,"0x1ff270f3a6d9294ecf766141869d1e3358e5a1a2901d1bbb9c2d58540a3d9a26","0xeba787ffa66659048ea768d8aac3eb2cf0ab2446236b2a9c090b4ee85eb4ebbb",null,null,"0x9a151ba3f56744ec2626c60249202be66bbc31b2f1c0ff011e207a8185f86735","0x3d70a765ced16526ca2e0f874335331eb41d47b4c31bfc6b9f3befa995cbb78c","0x649fda0c51c110d6ba18b70ddb964c67c4a9a315d20089f0d2a157239d60837e","0x814c12ebe1b6f699402c669758cb995559882477926acde672bee7b65820f73f",null,null,null,null,"0x3c4b0360bb7e748250d450294dddfe58bf5366c4f2adaab051df20716fd2c054","0xb7e46865e80efb7ecaa20c4cae275738c9a53ca47b361c569ce3c85b0f2694ea","0x72f6d4a4a7ff7c992b549d2969a893f0dde74901978e77dd0b14e9b6c834ee03","0x0977f0d58fd83a07f7eeba5317582c64a59e59fde3112984e5b3400efa0c1c8c","0xec2f3a6b9b85550ed6cd179f280ac56d7e9198a3c1f29729577b71b0bbb49e4f","0x6e86eb97359194666b6dc3b5659e07c2890f9e62d5e168601e2817bf900840ea","0x0ce8449def205652b0baa846f0774e9024175de7156ab422a79796f9cec1728e","0xb0e4616ad1cf8ca988e6c8bb48e0c2eba6a71c9568d10c260076fe6caf194bc2","0xa98fd7f138b0c8c46cafa540d6d74d2aa7c9252c0628f23d172f5d4540c59f13","0x96ceff4f4057cba74a271cae2e6a4a6b8781dfb520aed30bb67319d746fcca4e","0x962225c34798db9ba1c6985bc609ff00b5e3fe824db8ed5dee5bfd4315044023",null,"0x729f262a234f3ff602d12ad470f783ccb63fc68532f2e7daf02464aa678d94d9","0x2a3f53239ebe27671b12a2f096c216faeae16fa394f6f993400c7ab500aed380",null,"0x2378fe3909cd90c9f17bb1f6fe684c620493da9887e7d71c3135ef704ef3821d",null,"0x09097a04570bd0d1fd6b3eaa232bbb8f1db9b6ffda307240e3d579cdaa11e13f","0xcbbf142749d181d339044d887269ad382c5bfc1c042d211bd1c49d7be3fab0c7","0x9e4de377ad1c63e2d02fbc0c7647083b5c658093a9b9ff22313979ec00fcb208","0x2ce0ec47a916905e2f73288c24fdd86b922ff15d090b36651cf5acc1497cd3b1","0xe7cf05e564ea3c8a8ea14d880cdd8b95c813257fc7269a29a4463fc2a1b7fbca","0x5f0f60c98a01e884cb8d2444508f308a273e33cafb8b6594f9bba4d2a3011120","0x7a1609582255c4df05df1f488a7b584e8263918b0d896310da55989dfe06a2e8","0x4fe416754ee082d1345e68fabcbc8cbe83afaa11bf5c509b28343a01d005c0fe","0x8a7c0eee55fd06f93e2abd0acc1e802af89812f518545ef08c22a7ef49cb3c31","0x9e49974650b80c4e3d6bbf1d9e7ce11b21d22f922e268bfce5d54dc960abfce6",null,"0x68de7038c4744908de9fb8e3abbee44dfcdffec4d71e37742c4cebb9e5a50cf2","0x7e8b31238bbe985ab81299e9acc3de6b2dca8c8b0b193c840334079b745044be",null,"0xcc1cbef3f0aae74ea105a80903d8742a20cd1733d59d1f5a62557335f7709327",null,"0x303c70a7576435ea2de70bbb52b97c3133f2f8a4e89d7cc8eaf7905d61dfaafc",null,"0x4bc46658d8ebef91a919f2e7bca7a621d83c49750e7430871558f88da39e5008","0x42d9f169c9e9572e970531992dc1fbd42000db261f06de3ccfc4fae745914ea9","0xe0fd7244e3293b6f5454ca1c8ded526017e05b65a19c3d97598ec034bd2afb77",null,"0xda1ab76009d188441b11a1a340f45212799aa81c531b48be9cf25a6995943490","0xcb954ef0e5ff97edf04cdb202f1034b283aedcd02520fef33539ea2ee2089590",null,null,null,"0xfb9c42d151c26f7af62e548ef313c126f06fb827f93fc32893a5183afca0e98e","0x27e0258ebdbed7a0f40a93efcc057e40c2b6f41f55ebb1a231d46fab21ffc7a3","0x2458b4f4a82b41dfd42daa2bda8f5e2de6549fa43dde01a31381bc9388d0880d","0xcb4f9f31daef1c1dd619c76f0ce80589f0fc4948b3299be4112d7de86d5d12aa","0xe6b58d17ce68ab6bf95a3b5ac128c2c8d985441acfbe6aa6a9fccb6503124335",null,"0x31ec7161ab719c601719a0161997fe479fe88f956f558ee446b18bc3129653e8","0x48c27e7317669aca5cef01d843e4383fe5c3a06ff5b560f92f6787b8c43f3010","0x6376d105e3660230e7e491aa4e1cdc479e8ab2094da7d60502fd99361a520e64","0x7ce89d9acaad1aaf05a4e56aa858fb5a074e9bdaba862b72d6758e1f6ff3ee12",null,null,null,"0x6f7ba6dc551e259bffc0923b738c17a76101725f26a60597cf751ae3bbe70719","0x6144c3cf453e5e67da8ee99228f715f36d7ea4912c7f6c3a0500a442ccc5b2b0","0xc4a0cd06d94b8e2e7eb92768eb9556d6178e50f7acf22fb7103eed54ebfe5252","0xb191720c6295ad39a4c6606e76d36e4e8af37a06e9640dc4c382c85a6c7ad6dc","0x663e7821e19eb5a211824a12fe611655564ddfa8f342278b4ad52ce7164eff30","0x1db95b3d3d1a1c41ddef33fca3d88327ba53258e75f48ec347967cd1dd761095","0xa68447433d33a493356797a44688e6dbfe6b4c58d9861fb7491ddf30a210d5dc",null,"0x6099a9dce48a3a06cbf39e31d21e9298428010675de5fef9e8630d01627e7b65",null,"0x4487ba8798d61355620158d607bab04a760e4a493dd5f977dc6efaa622a398ce",null,"0x4f59e43a4f083504fb7eb20dd3df68b2d5ccbb1b57ef63e4be14d1e7465b2ff3","0xb046bbdfc30f348fc1781cbf5729693b5e222c1fe37c582051515be618b7bd4c","0xd38e2e6a65142c7a25be2bdc021b3faf1268f08f466eb945ccf60e6b380bd40b","0x25e0a61f65788a05bc36e22c53b66f65c981af7ced60ede5ee495da5191bed23","0xaaa6d2bf132304e43d0a5f6c486cf3845889a274f50580a9d8d2e3e3cf053576","0x66c85dfe605a9de32fb1019a832e21b1364cc9271ccc6f8f98e1398a35a4cab4","0xe6b9a780deb26ef1138eae025e64089f829ef615c3481c04075e0a33ac482e2e","0xa6612085a306778017fc408230e12e1624889edb2b829f93f73547b88a8f7495","0x59c8af07038ccb3a137ea337b3e26f697a5541530376f4b79463a4c957254f04","0x97dfb0642f6828c88f5d983af399551dc0623f5d9aa694cbeb7650c925a28a2f","0xac519ea7952d5b497624473251fbb49c448c5d66f78520269765c1c5752fe292","0xac68b8907ec03a000b9f9255709347a1ee00a1680c2594a2d31411467f52a35c","0xaee7f2f195f49b22aff9c1dc92550a18c92da95960d6f88af90af6a8eec46f77","0x7f2e94ce7081829aa36769a9af173510ae15d086b73e01507b45c460470944d5","0xf44e552c7f37bbf682a2b202a1ca61d3fc80874104bd83069d228e3a92976610","0x4fdb3c6ecf9146cfd6f9977cbc179c19d5e56152f7f02c08ac010a34a859c265","0x692886b41fa4df1a5cd833ed5b5cde8a64edf5a796883545e25da6c7136997e7","0x20db6b507c6dde03ff3897f72320f3f38104a40027b451a1d569dfb4f04b25af","0x43ab962ad34cf63e81c8d267170af9c6774c62ff705f5b5b58a6811f93a09420","0xa330bf5738a2cb6d591237721bff1eac25d57b9a89f5dbb73c4f70f13ed80c10","0x8238952f8e59142a46ff4c676808b876309737349a7f3f0fc474f8a54779e8f1","0xf60425b1d24f335f1a39548a0052bca903276f3307e57bf55aa1d55af2d20546","0xa243c657acc6ca34dfaeda8838005a70a25174735ef6c45397d83857b4c76eb9","0x48c18db85574364572717d438d632ac1fc65e468d79d92bc58fecf85cb4b46bd","0x0e099cab3e4231d66b4988e911be8ecf4fb4ba75454e27d5683ee97083e10fb5","0x636697106ef1a5141556ff3c545753a1c1f137419d971a263ceae4c67ac6acbf","0xb38c98c2be7d4f9aa2e75f041934872adcd7038248f0a1ec46e5ea68d1e7314c","0x0f7877a68de05895bf34a4d735276ba87354dd01e565371aa72326d65aa1286d","0xa4d61df0e2d7758f343c15d38dc6633644a059665c607f34f3ac4ec7f21cfc80","0x1dbd162445ba3b56d4eb3aa6758a5dbb85312ae8fd8103113180cb3c2d607859","0x68ea17058cacd47c6e65495cefe7b05d820d856e74a3e80f59f88aa5394f45af",null,"0xc3820d941bd60be6582ee77359e93c2530dac2930d5193e74bdd1b81c6a56136","0x310b8491b867af02f50ccc6f0a8fb1030fb52ae8546a4ec89812407e34847043","0x7079c33589254a2ecff2c6f4dc76365ea610bde2d7cedc0e3906db7f330a525b","0xb193ae4d633f69714d73cf3fdbd3d5b15cad4bf2d339ad2a523ee09198231e6b",null,"0x4c98cf06a5e06d4e90dbba7a1416460a6b78ffb85cfe2bda89aaee8938db6d75","0x773781ce5ccd7845e400f9fa25c0e4464755f89df5b89973b420f104f285d041","0xa8e83c129f9efb299e54bfd9f1596a486510aa6a33e3dbc2dc2f8b1e67c473b2","0x46df3e8a07ad931b1499a40eba7594bff7694183c59d35354515b867ce65e97f","0x250fb20a8dcc1c52250618aa8d800308f6bab1a350ac3bfd19740113051737be","0xcad829de1a34c168c4da77e3301712a07440ea7580312ef1aa63c2cd0e395e58","0x699c39acf8f65515d9122d2ba8c6a03ae7bd42fc181d1370cb62d79dc96c7e8f","0x3b42919e56227f055772089e44cfe02447a68e92ed65e0b508d577986b8b7534","0x4a57509e44daa51208e64d518e72d37bf0f53b81d613c5dd5ff87f3752ade40d","0xe79dd2066d7de9ed5140ed0c5dab07243bd1d654693aa764f79ecbb2a9e4733b","0x5fa5d4172eedff4b73f7604690570cc138b3cf8e4a5ede449861a71924f48997","0x88b5d050ff99b60885fec3c5f4c557a1e07d4d97aac5b6bac221696a2122faa2","0x072831e79cac9a3b4b603cdf3f710cef708da77c59ade9f4ecc196f3e6da9715","0xf419f0222504488683f5bad1d364c5e5820417feff109bc81d3a846d3383f939","0x18a2001b293d79f86999d0261e609c4493a0e3996df06cad1159b2060150b7e0","0xd629104cdf516cc0f5725bb173a43e5c7d65210aa19f6bee7bc42fbe5f8afc1f","0x2389d632955be6d504abb9273fa0ab4ec35abc8001ff622b7429ea7731e25e20","0x1075d837bcfb58c4bc2454ee0ccfb4e5021471718fc83569dee5edfb6bc981ef","0x16e2da9d8e0fe69cd05bc14c72daf75a1523204015bb96c4e034977a6c95057c","0x1401c066bece2c4bce521b7e3f2089085de896a2c73788b8b6749ac14eb4e00d","0x1830426c0df4ca947e92c948bd255517cf3b85ac0a6632bc0a8c54a6b3547339","0x8202702916bc83fc98e75cbbfc869461e5d7771a3f49cc93deda0117057c6842","0x72cac20002149151b07edf881763800c3b5a7499e435286b7e1ccc58c310d930","0x977cf1b7aeeea9271c83e02b1bb588b61cb5ef3eddd01630fe513c5c25350295","0x3fe3e636de4158d370eb951ff2b2e3876cfeeffca19723ed908d0a2f3c237b77","0xb6abccd81828a3e641a61c2af422840659b76a0cef7cd1441514bd3ea9ad55d1","0x67304deb7c248f3f410894fe8ff1f316fb8d728e062ab9c56b7e50c774bc630a","0xab5a5e609c7fcbc6c2cc672919b18cc307ad79f10afa8848aeb5c0acdafe06be","0xfa94470bd62df1f22ab3a7e4016eea2e0ef4bc909f837041889223f6f352c080","0x87f1bb2750adefb8b786524191c0c624f67b5ec682262ce0eabc506459c8fceb","0x09185a3419ff3ed7bb1fcf6c588acb4c2f104e811a6616a118271793722bf073","0x818db5bd75c3655b81c1062a2e3527f4fa334ef10238a95253d4eb43bcf53099","0x998793c128533f40f7ec8be8019cc2828d81cabb8f66e7a9b99bbad6a6468d1f","0x6a5eb8ff8aecdefdb4709c6865c6ec00671400443bd6fa2810aa305dceae616c","0x043977a5487fbec6b52265f7e1e16fdae420c670a6259465d8dc41046e4935f7","0x9343f48aa047a9c34087bf519e2990902badfdd07b6eb2a16f64c4b07c325ed0","0xbb982725c495dceee9eb67874798f1cf66c55042d98a102754c937526ec490a8","0x619c3b65cffb29623813d1b6c8d50c581c970204a9e2e5b2f33bcaf256d8c95b","0xe5842e2935fedb28a21d87142b0e009f7211a3185f84d3d7f22d1d69f2063220","0xe4d7b0326e7a80cff294215d88992ec1cb8d56c7bfd860c89dd7350bd3f75b31","0xaca360c3bdd3b6d5645d3833ea920256e5ab5d26b791e05da2628674cfffba93","0x6e67a931aac0e6913dc68d1cd8bbd42a3562b013bffe0fb38758ffaca35aac6a","0x871c7a6cf39de7d0277a1ee6cd7a4ba47c6a7c80fa5e3622dd27cae97023e8d2","0x4a6a07f1ac52dbc59abb187c176ebf903304ceef134994cb30cc01bbb5cd79a4","0xb238399e06f481533b80564c9453b1bf8cbf6d1d93cf0d93d8194c9ff859013e","0x00787e48ed21f5d78a34c4951835e186e69bb16960128b0ba433e518db1971f5","0xe5584f36d6f42d5c54af28361a188536fa9a509cd34d355e88dfffcd3dc40a8e","0x489e073b989e88af79329092ea552595242628458f2a172d81dbf5b0bbadad3e","0x52dfe0df5135a9770d5043120d2410a20324737b5d0ac0e2c76a199fedce2e40","0xbde2ec34dbff0265b16b476e11effd92dab93d83dcbe54094885b9c8e4de36a2","0x8cdeb7828cef67883273796c1f161f89786aab14a5499619d2aa34e73313b28c","0x4b3654781ee10fa097e458eac5cc915ad849e74242e46570fbbd6f09585fd111","0xc8b1718a769e76c8dfd78bfdbe5c9c2450e2bd131a498afed3570467bcae90fb","0xc1aa7058bf87f661431eca0495c0775ebab737d18f9b136ad3a49ee46cb8c1da","0x675a9c9eac390e570167c7e8c0075fabdb5aced287d075b6613e1ec51c8fd9b1","0xfd6e8c1ef61beb57ed7871585ac3fe0923eca2046b32c3c92d82ef0552196a21","0x4f45d136f672a977735a5d483389f916eef77c01d089fa40a6e7077b42b93946","0xb9843cd5c44a69ce43dd47b367a29314b12a66109f9ba6325e44702a5cca08e4","0x5daf92eeb81631971e66cef64abc7592123f4590b0baeb30aaf1ba51890758aa","0x6627d30ae836b6f1729e57408eac01bfdd3585fca6fb1ba258ad02e5ebf8ed05","0x772f44b0d49291e3cf4bec5c2f4ba1b626ed40d7f6baccb346c642957809a0bd","0xf3754c8b2ca6824930dbb3a287f2bd89a11c160bc12b3a66d2b9eee6e0b7b63a","0xe83e861d738a966da8a1b2ae14698b492d563cb4bd9875da2a85e74bcd13b02f","0xb94bce8aa18f1d7bdb41e4064ee48e3a20203b9ab130c464540d39cb9bc5d29a","0x450dc8bcc87ee2de761fbc5c7e0b98ed645a5ce06a06ea5314c8e63d3ae4f7e6","0x7fa374369cf81a99c35e7315f749c8eaf4d4f0471c5835c9952d79dcc3c253b5","0x24f1c6bab535df80c4dc2e0ec0bf5d1c0e09f8a1a665a3ad33b8e6c8c348a766","0x3ad2b2cc43d13e0376bd93ce56bc1c33f217c79306dd8f4605a058729c7590a4","0xdf76c111be88cb9abb5bed32a7b9db413cdfc678f357c1860d9e160fd91ba977","0x682d8edf15ac49e185b0187cf2118407ca32b50ba8eaa5b2b796165d819937ba","0x8854f133f7ddb56c860118771a0e3de458457ea5c59ee429c126c34e391d0695","0xeb9dcd2cf95c4a745ce26e86aab68572d0c49d1172cd628ffa24fa4ee745df4f","0x50a382171eeba8291937e71ab808cbae206d68f392fdb421b4a02f8ca396d95f","0x9dbdbd4553dbf606e9133897b5fe873b70787725d25e3f7691a15bcfb0847ab9","0xdda3fa8a710a9b2791baf3ce0a9b7398f6aca490f0dbbe71403a1eb8c473e1a7","0x978ffec54e22cbf42a9ca9bc9674ebd70cd6453d1463a4ae5eb3e3e19043aea1","0x817e54ceb5000b6d5530a0c85992b400efca11392ff760962f8081c786c79352","0x8c411955a057644a548ef56e5956c201ec3a0dc8f7858b5917050c88b3097ae5","0xefc70ef3acad4fc1ade1df8ac59a21fea16c083843af3f72ecc0d132a2a1c096","0xf23d5d05183aadd88fd2302d3524f27d5807512e94d37544548b7539070b4115","0x4a78fa2661900a281f94bc878d5d80e2c423ddfb57f63d20bfe3ad35938e2dbf","0x0c7208cf618dacedbeeb2ffab90d60f387b3b9654b57f7523481d7995cdaf638","0x4647afb9c38bf78703f14752c759685ee15f3e038d8f9b2d3c9e96317f32233c","0xccc370490adc9cb8677d827f5fd24070af0b2b99ad91f1a833a75431873ec057","0x2fe0d037e9e08409f59bc88fff133162ae02e257a2880c3c9b957cc6df0f8c0a","0x0b9ba34ec37bc97ce9d2716fc6cf8f95ba8a9d2421eb065caa927d1e5c8932df",null,"0x87c850d3d28c770fbe82666897470a71626a257b2199a8d455790b1c353f0bfb","0x374ad7cb99a410d9b7f5bfa170789dde666c1956448f1ac99905f3424f80a446","0xa9f4f52fcc40989f12101829877d804726ebe40ce356e2aaf3efd9663a4359fd","0x9b732d9517444edff0a10e8c101b6dc7c339d582fadbb2ad9eb1504dbacb2bae","0x0f6d833339c5c1b2facc85709b351a5161395366b178f12e06eef81184655ba9","0x5aa37a08971964454521a0ffd0aa1fd1f140fa85f084f14cd2e6a968fc225f6a","0xfa6cfab0b5961609aa7af32646f13c7622eec9615da24062f5926887dc7be591","0x583441b52cf1d266464a03d927a5d8dc0411fa0b8a6ee821309b41e26ee21b00",null,"0x319d9b2d9b8ebe61297e5f4dbef0c4e24a055b01f52d1f4a99487c8d2b9e3bc0","0x7322a6bb1822f17a6883f693d819af51f4a9a48d9a9c236a18c105a3a9308e1a","0xc34dda095e6c57b1d658f98c04cb8502d35f2fd1a179ce3035380199743ec884","0x4669e39916dc47000aac2c5dff31a8fb1c8c0d804c4311cfc12c2017e16944bd","0x6984e34551823e14d027288a5a8b6f69357009fb5a717102aa80766a506462e4","0x6ec1edb45b0fbfa01aabf9f9289f106c21b734d1ad01d548e2c4dfab6c638d22","0xee28294d127018ce77fa209a00d4535348ec2963ee601bdb4cf677fca5fdbdea","0xf8045c1c169cf0042367250c8fc255098b6fb30ef25be109c7a9df7514da236d","0xc8338bf68bab4913b563732d6120af3d94e1d734d3885ae79613bda698fe0732","0x0de6e6183ecdd5c4d05da3e68c7c89f916b6a32e8a2c873600d117a6a285c482","0xbd644bffcac4f2fc9f87ebbb67572747bb27bb0a70ab9ab353230fee78bfc54c","0x830993a39c5e1d215a7a4e4f8005ad04f09a2ef13088639cfdb138a17c4cf524","0xb99ce89c7c88be0fa87412c013fbfb4209af467e584443f65dcbadb19485ef0e","0x29fda7ec43173e20eff53c6d55c8e286a42e9af1048a1946396f326b53289d38","0xff43be7da2f852fbf4b82c59bdb88edd65be78a398d3c3c99b5b2e8a2e85fc89","0x5782921dc4de76d7f9259121c2a7e5caeb30c5ca1c813d54e98936d4b041034d","0xc9ec2f8cb9f6c699f83058133d4ab016d2e916f2487f0aee827515f63d5eff74","0xfd20e9c56a0058f5254beb1d04e7d3c4412d63848e148437b3f971b653ac0785","0x3e0df92dee2b3f23a2ad011eeeae6cd73fbdcfaaecd4e9a4e1cbbcf648e74093","0xcdcc3c7213ed787c961b1f561acaf110c7a033d872e56eee606b0322aa624b4d","0xfd53ec6c3dd87ee75f4307f416e5eea071a8c39e5ea01fcf5d8f1b657a7d696d","0x5d2bf072c6f360c833cff6cea3311ffb2e1ff829413debbfa4fcfda5e9f7536a","0x81b7ea314805b108618534b7e704356588931c36fdcff40ed1f5b66ffe960e9e","0xd9416b5154f2c4d60a30a2fe282b2df899e0e25410245148df2687404e751d02","0xcaa45ae2a28f68dac36e2a8f564e3509abd12956e5842c9802eff41ca45860e3","0xf6cb34fa23538148c6f6c669338197935ddddd7b134169239ff9ef51017b7d80","0xa4f7208c5af3983fdb201f5f140e4773820b68c0cc4bfb06f16d977e36a7ebb2","0x5b8c0c5f6b4f619ef23799b6663cad67898dbb47bf85054cd37daf36c1a62350","0xfa91b22f00e251a3c1489e06fb781f59e49c21305e67dbae6ff5fd08518f0cd3","0x1d926bf79e34ccc7d1aa37732b1e0247f7d0ae53c99efaa57cd674514eb12b64","0xe8843a7546d2288e25857651f159cfc9a9a47c85b906012efa7611ba33b22402","0xacfd5ac00ea13f33978e3f60bbf2e8feb8268342fa5f751aed942dbaf5d086c2","0x9f8ddae8be5961f0a671eb6e86b868db183f8042bb8e42672d41c054d4e578c6","0x7c34b26b1db3d8bf925f143e7d6df7e117c65526c2130be8ea832b696ca9e0ee","0x2ddfca0e845e43b53188fcbc1012e98b8e1e06b0e3fb280f741789df0aa33084","0xbdfa436d7f7dcb837364c32ec57dcb2f3881039e06ee67e6ddd3b34dda6a3b3f","0x1b60e7680f67d7a6a37906d28ae588538e24a04b85571f50109bf1fdd8a659c2","0xd25773b3d1adc262406ec2b81b9c1b8688491ce1e667170b475cde5f442d9b17","0x44559d390064193a07cb6318a0727b20a93b7d772553b92be173b9cfd18c5af6","0xac83381b0b8185a2ba16dd9d44a442972f0f438f76cb071cf609632d3c0babdc","0x1d82598f3dead699dcae287bc008a1bba44f63b9802715f6d4f2b1938578cddf","0x85acf4ac53141b4c376df93a862ab2760b652597ea02f0317b4dc7cd14fa8236","0xa8f10e98c0ee7a4c4a5b9a2d5b90774e186a4faee03b36439e8566f8cb9f0084","0xda315bb8fbe6ce7502083e55168c273ffc9b1be23cfe67c1967bc42e851cea8e","0xb7a2160f183e04d589e52f1d82004142c69c156bcb3c6ec20ab80c90abf8f7d5","0x63fe304160bf2ec14eb99e86f427485fc842ce1f15364193f84c69c59a79baea","0x37a9cc635558cbc13f17a2368063c2a637daf702b2308dc7a8ac382438c35704",null,"0x39bbf2a079bf52ed77ea01daca7f2847af3c5bf454f004e05a5725eb8c5794f4","0x2d05b08f92939f62e5348ea38cb25ea5eb3705e735dd4024ed4a53a749fd9ac6","0x51fa16154514a1d6dff64df83f8b8eb09ab79025a5b94e63286a521231373f83","0xd98dddc7d59cb4d79d64135d7cebd863f506098c6bb3f3907a2f8c0b988531cd","0x0957181b0806681c4a8e4c2906098c9135d140fd4cef9092918f627c382363c3","0x309c76598105ea3511f3e2ba56eb32ea5016b4fa3f0b792e5dc61335cc06d7dc","0x5a8e537e7c466f364fda9b2adcf5eded4e2d4ec8e0bfdb0c2c37e6239c1c5b3d","0xbfdb89396d434ccf3793b362be9bdf503169ee922480d0c3b9ac9261af2b0b16","0x375808efd31d03800d30049bffb698bd30a1a1ed8845af5fadefd8b7c8027603","0xc8d022ee90309892e9aad7a3a7afd1e5b30cbc47c7444486ad9789fcd3060f13","0x71e8cce4d4d83469bd3beb8e670cc491cbed231ebc8e770eaa2426270d1a79c9","0xe9705cae2aeca465dd2207cf405bedf05131dec5c3619b36034a2fd7c6687c20","0xd0e9f05d04b1e4d4ad9e8aeda184836e3eb1372bff3c46d535b6bcb6cc0179ba","0x23ba830f34af6351056158c0d50bf6136cdd777a18da2e390a01b611ef19bb17","0x58a0dc2af071a81846b2105f663fbbf7d0947cf215d548eb706d4184a101f84c","0x2e89077f74bfdd8c3f0f322c68c9fab05c698d68a61bb7b41803e5b49a9520c7","0x5f8d8b80edaa5eab014dad2ceb6fe3d6cfa938ca4dda40f4131bea3d15848328","0xfa82e56016fa73aa864f07cb2746185e62fc686cecfe51c589b6358016d1db67","0x76bdef2e4ead9ead5c19670bbaea47a1e2d1662defde350ed0e5ff054248263a","0x2db8b45d47456930976a716d0f179c0549995b29bcdf0ce37ee3913b2e8beb61",null,"0x21831b4289aed1e9796c38cd3b65a741fa7a268cd21ef646811ca161192903d2","0xc896da627235d7e857680e3e3f671c883728e34daf92686881afaecc7add1b96","0xac27a75d780a5645a17a65128fedcb3ce1f63f03b7781b49122f0d7de71973e1","0xd046220a49343834b866c1628cf45db2130d88a46079ca64cdf725ade7ed5ef9","0x5672054a012c9a3d6fbd3456d3b7644b81a7991d881951a262961ce22e021004","0x6328ac102568e7939fe35989dabfc79bd20da6720616c6b0581577b36375d286","0x76ded901f8c4ee7620866d224d808cdfd56fdbb182c3b09f23e83b94030ed9b5","0x6d8b29e9cd09acf1ee6ab039113f16d940ee99997ee7ec4caa7d2347d1282cdf","0x3d1a31c1dff4b35ae92c6c5c28fda4a73d3549aac63ab99031134dbd6c36bc28","0x1ecf03701b080922fa71904453231083a40d5730f77fbae0f5ee97860f2c1c0e","0x9456078f708366e627120b7ffcd1579efa1c834a4ed59c6f1eba552f1aa4e125","0x4c6c836bbf6652ad48185c3b625b944d8469b0890f16ca93b57fcea12f6bb0f7","0x4aa09d18e6038614a710c3942b081147d6b9294927fedda0f3079ed87e677e13","0x95a976b5f97b6634ab6e87ce2bdf27e1a64a50973954f33a373cff939df1fcca","0x50470c8ab4b599342cafec378dd641c30a8c30f8f89d9032e7f3fa3d80c5ea90","0x306671d8acfb10452f2235cb84d5ffd087d228f5837769b68a22998d8a14c2e8","0xf071e559d20e316eb85a4d1e553f5bc34728aa1755c90876c0ab9f9716640725","0xc1bee7301b2e291c3d4007f7e079d497e1ee555ef796138d25ff949fa88d8d13","0xd0b115426b2fa9bfef0d6ff6b9e423a3c86898df2eb3b63ef79ccab4da9ef21d","0xa2c9dc8fa3a2531eb0d49d6b6e4ad436e721e2d3d9dedd828bd33dcdd337b39b","0xf63c3054746e7bf41ad668683c950d9f64475b646792f4e0ae7f5b201e592a23",null,"0xfd8b5bebc26417d6946c50a825d7bee705f4b9182c76d008b4892624f2618931","0xbea1012d55ebca8954c582c3899da94240f319035667d234a6877a2efa342ad4","0xdaf142bf009450b1f01dab8fe1efad1a51b32d3300cc75012fdb666715991835","0xde774ef3cfb4f0c21ea3377814dc0c658d91ac8d71c10408a67b66bfcfb185d0","0x4a912de108999b6d25d510488ceb4a80c223fa84a11e38403fe238e79c4ad08f","0x376bc6e2d18b827d57ecdaf089f4c0a88b11da9e25f458a9afb7943cbd7a7d2d","0x329acd9d020d2d16e2e9c21543146c5f329decd6a0631b37c9f38883714c60cb","0xf73a23a59f7ce8a4d5afc891c95a18fdba23e2bbfa5685094675c20e2149396b","0x4ebd1948759f0086038da448fa357f58dc77355d2a75d6ca9a8d322bd74763f2","0xf57ae96a7de83a826232addb9c3621d9156b417d12cf313d3b193010adb691a7","0x00935d1b0adc6dc0b613db6086b9af3b400797439817cc6bf05290ecc6b10a44","0x9aa904c64eebfcaff48ab2524c49cb146eb470dc6e6bcc95eb223d6448674608","0xf6fa20ff61ea6c5e6cf193af384fe8c965f556123cf0f64bbcd259859909d14b","0x3105bda1bbee140dfa64f88527450b0d2b8540ed3f2b26cda5790efaf1c2a721","0xe960bee52419503b0941468cc29403038ced7dc7a6c2f9a4a6475282ab2945e4","0xdaa24049fdb96e87b2bd35f0956f22a6b42285d79f459a439747e549107eb4c7","0x7d917056d0b79833f8b6576a4d55959300642cf0590439ae9b2e33064e422649","0x246bf80729716c02185a85a6b4f30c381e708e99eb4935d9a52e82146f4e0676","0xd50e72d305be9ee3e383e2bd2730b56f0f5d6506633475983159ee0f0f98f888","0x9c179260fe1ca7e19dcb9119efba20968aa554f32089037b109181cad7b7d64e","0x6feebf2f2b242beaa4f47576f3399596cfa6c23511846b123ba0517cd6589cb6","0xfcf2d237d1595bfbbc369c9900fefbcc6a8c36825d1bdda1a5095ecafbc36e8b","0xfa8d7a522153ad7294a86182640ab0029c7dde96043bdb7ce3f7275f86be33ad","0x4bc07c946472451b29205e292c8e91c6bcf2bb0956f6a1ff222febaf79248e07","0x1d5c96ca7e1dd8b2616c00c8b70b38dd68cacb42a76aed650f9227c40e4ddad7","0x2e31afa75bb00ae9117b14206943938e1ff4d716c7293dcc61a08f4f5b606ac4","0x4d99279ade93a491c53545f939b7864470f53906379c77c0f1b629d73a095f93",null,"0x3c6455ba9cbc2ae89e5e72ee85126890bbc79a478c474cdd75cf54930530de00","0x41175ba519ba46f499350b0cd5ac1c81bf5294d76bd7bc8c1fb23760ea9311a1",null,"0xca190a1c706c3b81a31a681a598ea1436f7748efdcbd36732478eee07534cb42","0xa39445ca3864b1c433a8bbdc3e78c3be5803fc1e7b103a942bdeb0dde50e934b","0x4ec90b17b539d7fbb463b43dec9cee3906fdc7e0acbcf1d31fdeee6f6d8c145e","0x2a2ccd6e08e180ef4f847f0f549ab60e17ebeb2585a7f298d1110d2577b43e39","0xefd90d374af1a4d69f0379ef959e4102487de02b6e20849ea22d21d35bdeafe3","0xc9f35e85a79cfbf559fa6152d0a4eead53f63a77b09bc7293861a00b00b87c7a","0xb8fd9f4d7f6a0a0af8f3a776632457e787dfbb6977223a015aaf2910522a4274","0xdb15613493f16dd4d1d47332d9c5c48c72c85ee56f71ce37e244a96bc592ee32","0xbc7eec584f1e66310c7c58ef1afcd9bca54ea8ed5853735c124f61c8f8e9bdf3","0xf765c83e6c4b4d4b403245798722bf65ff521032caae36bc478d71c004819f8b","0x8d16bd42b99c253a8172842d0fa602bd1c684b183bd646b7320b57f3907e114b","0x73fa56f4e3d00411f4d213c7076dfe9f9c16df36347a4adb7501090567abbe5d","0x7e49a6510729d47580f9b58409e6d23e19019a87c6986d7ab70bd583c8555207","0x583f718f371b55c9541bc8cc9b940c74b1d601460c1d5fd0bfae5d6179805dbd","0x892eb60931300b8c72b8952f1b3eb6f0b00be7e198c7e00b36b97b065fda8616","0x156f79fa63dba6ce94c2be32df27b416da9c204f8abc8407031956cffa1a75fe","0x7612281c80c6113f3cdf0067183845580b46474b01d3d98d8b0e54f088641735","0x0716cd1d603b127a61c36ec37e1bcc4a51633fe6fb011e2aa7a215bd5dac0704","0x602be61aca7ba52d7b57a13226580185bfb4597997dba8e15295c71dae78458e","0xdbc0a68a6640c26189af61f6dd2fd732d9c491c14728920b6334cfade6972c6e","0x4047bfe66a7f415d8828fed479c690b681ef2daf01f0bf19e7e68bb64e0709f8","0xe780fd37918dccac825dd0f0b1a33e5837ba70492bab094275dccac585c6c98a","0x0fad8d9a1d095b5b098f21751c46d37b1f3dde4a8864bf7cd5430728bf26757f",null,null,"0x0c427a497737be9c875007a75a1d77bbe776e78e5ca92e02d35bff2739d9937c","0xad65cf154c4fe73b8d4090f71b8e3d5b297536af74baea24f67a5719a8e31f52","0xdd93c50e94c444b311aa1c63c725afcc78bb27f9171f0957e212cfe7cc34bc00","0x0dcf138404620b9bb403721e266544c05088c0166b30a108af0351632ed164ab","0xc9eb95ee8f4daaee42d5d8f4097873e94cd2d4887589b7e60db2468159a5f995","0xce072962cde8359aac0a3c3196b84b8d493572a01fd201ce18b0c0cba4002b9b","0x074252e946f5fa3cbe2f4a2f6c71ab818acf839f490de11e2ae1d449da926f63","0x8b467aff31ac0fa6b61ecc31681040e4898161b17dff32a10f01d16f011d4079","0xf5e3c370bf9640780999960a64c153b43a4a1b7af9677fd9cc7f5117a8e24461","0x5a1ea2e53aa9adcc42796ec38c70b8a94b47ab697dbc3860e60db62231f47f27",null,null,"0x1ddf24b69d1e239dc2c7799b5aad1d4c3231fb10f54809a3c743041aad91fc6e","0xbbef88cb983455e96dc87625796edd6e2ca1a926c16fdf0977c01c7a46701f7c","0xfcbc45d9f2349bda5d8b7a757bb5bbf4e075e8f4173945e89e1d489019e37deb","0x5d89e6389676f055ecb74f875ea42d4d320122b54e0bc4659163e49110cd249c","0xad7b0fc50cc801a78db0749dafa2141c6248a1e4d3bb621c09078c700393c3a2","0xfd99fb3f26fba1450ce4aea87c2bca0322519fd2cefed346efb34fe4de2ee40f",null,"0x7c25b6404eb69c08dfe36911d33630b56866b688ad75f39c3a65f1dc1b1ee186","0x30dca4815ab9d1d600c5aca103e573ea602d2a8bd98aea263ee53d9374b48b7e","0xad7ab111704c9f21ec1087d2c289b556f5d1d8e05cc4d2d2af05fdc483d40aab","0x3d858c3ed815d0058903489a16c4fecde37fb266c7fd024fa7deff7a5b7b1d01","0x170019c24a30f19edb5ee7a64f4e7238c829cbb179f5a950a7113b0d4807b794","0xcc24816d170d05344539c16d5e1f93ea66bf6e3a3b5f2b985c48130df69df026","0x829a88ff0bb3eaf951753e162eba024d6e4a616563502c378b2f77a107bda141","0xedf8b6d86ece4005ed8eb8fca92b72cfbe15a59fd9982b2323b8d099d508790f","0x6a3616784af3ed8f45761712037567ace53fc628d16f3e8b32758263d4ce1d41",null,"0x67efd85c55af1108819a1bcbc933605e3b1ee35bf6e38644ace82834106d66ef","0x6f366885f84614230d05f665211b53cffb97299b487b926866ae3f8c796ba604","0xb8b1b409711ef231dc9b42d44ac1490d80f16c368601dbac18f1ce96a3dce6d2","0x082967a2f7b276f001ef9ac5d18c4186c066337bee0bb5850f187a516bbe95b2","0x9ec52d590113c88e0f3fccd75194eb04e642aaa2a781a99fcb6a93eb3c8e2bc1","0xd50b9d5d142af9d3287cbc5e3337f95493927cb1bea212390b8ce50174c4c6f2","0x3d587a05c07d4fe84f40fb221e97e973fa95714a04ae163b64cda90109c4e1fc","0x528f84a881c2bf69987b75f53e391d8974a868fb62a517935566750f04de473d","0xc298497c64273afe59e26e8e1133e89d3c5efe00aa19fa0d69f50bfc39cc76ce","0xce3bb375527bc23ac7bb3f395d93f7cb161b9caa6d595f6a8fd6a7d09db09256","0x00e79d375252b9688613265a1e790ab721d2f9354ab5b60bbf161feb8172109e","0xe0f9f91fa0aeccc5a8edc2a0d4e3b4821d03ac94c82025bc2c23f2b0fd6be3ea","0xc1049d138d651fdc3cb510fe4f6e68bbbbdf6d58955a22b880fd2f79b36cd3bf","0x3c665d4a38624a153c4a8dfdb906041b37d83371347a01bdad38317695d75fc7","0xb21f0077074050a4b54db5dce2e32be824b39c922f59bf5316b54c160fd0498e","0xc564fdfbe1e6652f21f544e5eb59a335a518ea7106edd3a745d61d4994f370cc","0x2918f3cfe35d0727d8432c50bc1a06dbc0ccf91043252da44dfb78a2c7dc7f81","0x845b228a29935fe3b314ee87fb27b1a7566da1d6a54a5970b6a68c77ddab3d51","0x1ecff2093e04c70929d6007e2c85179e61c57e7904f651daf13d11646adfd85c","0x35b3cd36d03bb133e896abce0a3f2f5cabfcf0e79579c7eff98327c0dd4ca222","0xc7d2fc42fd524d48a45f72fe96a138a6e9369ac74ad97ecfa0f43144d481127a","0xe5c374b27b8f94a8f87005f77f003d81404c489a96edc56925ca8eff4b4bb85d","0x7b0abde3e2280e0b0991730b69c9490b19d66dd07900fc2d51fbcdbb7ab80115",null,"0xf0f35246c2f80e09bbf434709f2ef9d2862e75f2c969f354d137bc56654756ac","0xb9567bca7062b8c2d0d61a35e4d17fcab2b22859f1ec3260acbee164b8b7b802","0x35a7fc6a6489d9cbe7d9d0cbbd53277a8040c707f0d800e44d8eb6bf56ffbd82",null,"0x1280a8ff23c2951d1cb084c81592562ee55240aca88f14cf5b1cffd017dc354f","0xee79ee300d0592d9e7be67cb773e5653e39ac028dadfbc1d665fba29ca70e7f1","0x8b83e7243025749f3ff20bec08bb1630df5659547b6a25ddce183dfe6afa702a","0xb937fb7c0de6f9c3f9c0f14151beb69758db79dfbc7d6a428cb06f3f46cc0405","0x47d004173f431f62d401711724080b8d1859230f163ed4df5544080dd804e7eb","0x4ec619fa05edcbb9499c5b5816dc710d1469d1670ecb29f76e0e0b09f654f4d4","0xa1d31778c15195a58c0429e001502f73d461ad37d63aae4114f433acf5fe8749","0x6cad139ed3de836e32f4fd02d866ab4d1126b872e00eeebaf2cd403a2156f3f2","0x6cbd6ef2b211b7ca1d0e420dfbcd56fc30701ddb831b9b2abc9692f7092b4fce","0xf7ca8c16ef76587e6d501a92d1da1d5c2773072540dc9047f0f35664541621d6","0xa14a605be1db136e13c378d666ab8fe02754fde38fa36feeade0c838d30b76d9","0xca75ce32c6ae096793ba6cc0be2e1aa08201a289f8d6aea838816ef89dc68c5a","0x9f85e81303d92515f69282c144331c568dce1aced0197cf71c20bb5c38a2e98d","0x19cde5cf264bc73b4d104002725acc89507bbf235df6bd6a1a21e40f316f10b0","0xf16c7d7cc3850aeec75e2c2b200f75ea78d558db5ce80aa9e609fe2b198e2920","0xc7c2651aed3d770382c5eed1dc50689f9a6ff0a81d54e5664750bac70554748b","0x147f7ffca10e30552bf1cd5bc61cf14cf7cf0202fef0ef02d017000b40bb8c2f","0x79c5d55685060ae9c4e930126e53e5c36768e0f5df093d7c6a5651c30abdd46a","0xf9b72a3ca3f5d1c79f9c7cf70eaed56fc3aa8312c77cceede8f5eb2bc50be679","0x9105203f200e896ecc0ae2a42ed4273a02bd08c7ce216709bdd3b32a213652bc","0xe44476103300d2c91fec579a5680a932b5912140d907ee2074b6fecdf5f04b47","0x103b9a22eb5efd8e08153bffd750b8e5f218100524709620cc6a90c5f954a9a3","0x990b162f160e47010b4d33fb3f53e0f4cfff2bfe9612b2ace8c4bf553d99b9e1",null,"0x5e0f91e972f58026248fc95d7d846c74994d93ae81245d412ce23f721f1f30dd","0xa6d5447f394e8427173e60f1af3902a5a9e80846200c1f776a3a3efc8efe5323","0x4180922a3845752dab68baa5ea802e9d162912c07b73a322e8458c12aff1d98e","0x90fa99752d65cebaf6092d76ff74ebf7f06fbf3666e0387a9b56819d80d6faaa","0xd5dba2432ef10bd9d21fcb04c5c92e893ab941672ad2bc5cb6d613a0b1e5a959","0x66f89a941936ca20415f07ec9ce22f8fef1f469c37a39bbba480d6016b330a82","0xa587a5bc8dc02ba468a6e0d4e7719fab19e35f1d6173d0906988eb062b082dee","0xe6a1e6a6cee9d0accb16d7d762edf45ee2eed72ae7dda9ca5ddc202f234daa08","0xdc84777bf6fa76ae4c981569494b289e44dca6ef43dac7c2acf14dbb0dca2d43","0x6451a4292fef53a96165e9bf35f024ba49fcc5ee90aea287f7648b98b76be965","0x2a3c033896c1e2a6026a97c80e7b0df5bb003bb11a622bc1be225085e554747d","0x488775b72fab86f1c84a1c234f74fe46578a33a26aed7c86950050c1155fcf26","0x33ecc85630dc1f691e2efb05afad8793aec2dd923a0c1b34e9761d8dc4ad2214","0x182572de2cd7690b1483dcbd3dc8c0361830c47d7a349277d9e9a701b39c2ced","0x4bc38c3e5c5a612c28bad482e72a8256ea828155da7d5e64aa5ba3a78a8e2824","0x63843693962d19bc13c37c50fbc7c1f690efc03115504a7c86dfa0be6600d80a","0x8dd112d733f08ddf0d14bce8f1ea70abdae85be2b67230df3c1b33fe48d4af67","0xd7d21e0b9a9696a36113665937c472f87a7ba42376f3431163bd17572f0272a3","0x5a5d6d7f91f3670fde98efec184e018b2f4c1af0649272d7460a17f1276b3045","0x95cccf2532a2c7bc23f5adf71416467d0978eb4d7e12b9d835fcd6f5e92aecac","0xe5d935a86d855ca98be40ba95fb941ad17cab26c5c8fbd72ee21e96cd2961baf","0x9db49b5dcb833762d1365eada5a5f1ddce59914b234371edb709fef6390a7507","0x50f790bf738c83a2faca4cefc24b5272ee4cc56122f1bf963eb411c735764a5d","0x9ff16c4c6024481745e5e7cb457bbe538351ec798f6ce999310a74e581551f42",null,"0x51293b81a2234d18d24de90c0640f4c6b9c538dd64729f8fce5e58955287911a","0x92176d7471ae7354e82e2864dbef817806d99eba20bd9c6e9570f5145d1d97c7","0xbe19cc2f3d364e9bd40cc35387d38799f6b45c01e799871db5ea097861109f8b","0xda72c6d9c566b60e9ff32bf1b7b32de34954c7f506dbcee643f08c83b58c60b1","0x1548fb59cee34a37c0b6b5b5bc4835b71a7da4f3c623a05501505fc969d6f866","0x74c030da5147eda7ff96e6d71e623fe008e9c058a0e001381a92fb8123269751","0x0a25b8b2c66dc6823ebf35f5c0be47a68b6811cdf8a5fe53450e7b5cbd2d768d",null,"0x2b51e94d15969895f893df9d99b7a4dd01009484feebebccb19f1c969adc937b","0x540a3360342e692e45a9ff879c1c587bb5ad4ea7979eaa5fdc6be439c4b0323b","0x2c6d4e2774649912551a6a70e50bfa33fb43632f2697ae03c6ca25dc31cc50a8","0x2c25237b81a618e3c1d1314eb9d84f2e879cb86d0b5116a44b356f2c2f226058","0x28594eca2414ef4c25d780e2d3199525150f7cb2cf8377087372facdde0fb380","0x5ecc2769ee72eed78c2fc5f5e72bad2afce23abbd07b39f63c8788f4877a70ac","0x0dc997f26663d48c1ef8f85cf1f6b96f83e31731a4074fe2a23a854051fab7f1","0xba8de3d2d07c54e27fba3565d87c02830fe685743ea7c362c30f829a8ad7ca97","0xa4b68e2150f9eb130a59e857d0760a74b49cc3d450b7b1cb90906e013e94e2a0","0x8aa5385d7d89e60c972ba291be7578d2d927432f0364ff937b32b150144327ac","0x591f5cf2eb1f6b1ec685211330a33b48e3c05c241418b3085e06a0c9767e0ffb","0x515e0941ad82a64e03e28bb9746e3487334d0d7b24fd94b29ea3874189e319d3","0xde1fb7823b07bb1ec2cb1d3fbe6582a754c65ea6e6fee5b10a23cdfa26be4fd5","0xefc36e59ea79bfa0e772a2fa6feeb12a82fe7a68fa86a8f07cf77060fa9639af","0x6c6e916f0eaa6731e5eb97ab031e15584ac401a74c0d647d7ceb6388ce3b2f2a",null,"0xf6facb5cd1d56dc783da6481001a2870a6b2b925dd1d6a5be87531a4459307bc","0x542e2e938d193daa9f00f609c2c2ad9c054913739188e500ac2e2bbce1061bd0","0xfb1980cf2e27f7704592ca8a0dc0c84037f44968ebc8c55e84efd7115fd772c3","0x52d351c93d94360e5ae7e16c969107c4d33103b43dc47e36efb07476737e8c26","0x9040b40795a28318394d9b3da03fbc1e51d9cd2c7154424740d6db75b3be3a29","0x13e66989f5fc4112ed24a95c6bfbeaa74c5f5173325636f5e699dd69834800f2","0x9b584e668c294227d713a8f45b5ab0513f0e3c419bd1c72a9bda0ef93aa6c520","0x048df354cd2c33d0a0b5f397dc1b28d6e4ca74edd7201eca8d1461c17ca60758","0x9be81f3e4154b016e3f01d889e98b0816c9510a6d8e52bb212986bdf72ddc4ed","0xdbcb352fe71eb2d6fe9e8e7d0b61217fa26a8568e807cdd7d8df962a5847cf9e","0xf4ec39a3e60c1e74b0769c0ce47540c8b0db68bbba177bfb26255996726f03cf","0xd012badf100af2923cb65183797851a9439feff51f6d1bb70a969205bf1eb5d0","0x6ed09693f6261ff64e5af8b8b0d1db682eb151ed1e3cf1821b0322543ab33a00","0xafc8fb2f9391bdf204a1cd69df5befbeafbf8301095f9a11e1e7e8840d918735","0x9857ef7fb4bb87e23080573e7da8effa9e6e6abc94f67f796c984ad46e4e5e5c","0xe779cfcfb52f7b55643a30bad460cfb3499edeeeab764169e340e9e640980b68","0x13bb07d041d3c99fea7aa58cbaac9916a50411946b54efdac2e1bf24e0503407",null,"0x96f5e6f9167c8cf4565c372a380e44b72c18fd65566cad2cb16c76b626bf686d","0x23fbe9aed25170782d3b098377ca9137bfa4d9e4e40006e13dfee3fe1d8689ac","0x7faf5505a27390a15a590f5a4fabebfd0b077241decf12ce0b345ca95bdfe3dd","0x044fb5486b14370a627903dc65950f585df40bd435e6c27276c5fcdb19846a08","0xd464c4c7119a6cb1fcc7e779e91d35d4a0542defca5cff8a658d6d9d0ece3aba","0xcdd1b244f0c23142d9e926033a3b0a9b9c6d459de64fe386a307ce94ef069064","0xb7368ce0075dea013a94ef4598fadc5c587301b0ec224a26a90ee82acd00e98b","0x26f4fa9808af45c8cbd93e752554d70d385717f8771d16a7d90444d67d9a0c9b","0x1bc2f64f6677913312cb9fecc81b0d2a305fb637c2d24ace74c053d7946c72fd","0x44b8fec3e1250ca79c06c40275843e8be479e01f1876afa96251ee7f8496dd3d","0x63f18b6d847c84a60fd1ac5842f39ab4768d089cb4c9d8e7e1ccb0b01b1e8438","0xc9c97711751ad1af8c7c65f0fb6ef2fd29cedcc3387d5163ea50d9cedbc6fe07","0xdf539a85d7d2de1c36fc1be3d6d2de986dd6b5b43e062bcbe575d71c8ee523f5","0x3c55036175471d2bd2df7d30c94a12797868ea4a5adc353ccc6cf8046622de06","0xc3becbfeacc4a3563587e6f5cac363aec39248026ef6d0bee84acb8938462729","0x4b5c00e59d6324304184ebd0526b8ebebc86777db78f4682a6ec662ad933a5f4","0x4f3a313bca1ccfc95bf07eedd564bb4de0f8df983123ee22bb8e76bb73d34d3f","0xf71cac822a8fcc0417a085254285eaec51f99fe9435ed256513005d7904919a5","0xe00b4cb20f37de54c45d2e8a4658a58f4b50bbb9bb1d547b33678e32cf81f8bf","0x86f794e1620e72752cfaec2e0a5ef2dd0f745e890409c62c5396a7b7b3fe8176","0xdd67c467efe6ac9b91c32d449d8a46330d9279517403c367a173e61d494570af","0x98af4a89b39c2a0ec71ab8b05d022384336b291bab692028df90fb32ac0ff7c2","0x932ba74c83f983fb6efbc5f34adfa96d0092e16c66121983e8ac3877ca716e92","0x650a9a21025f7cb9e4db088e3ec296debaa2f7311e16f814096db6b7c269c507","0x5443339adb7fa1bf8ca12c19533ac81483cdcac7e4280379cd7761884abace2e","0x0e028eaa0c716b695d6a34c229d03776d0fa2cc973f504b4f863ea914a851a5f","0x455ae79fb298b2476e58f74fc9e15ef677d82a7a01fa482b717479629b591829","0x7e394b667287040b9f99323cd01849d319c6a45bd39a19931e3bef0790a58507","0x608080bbadd361f3e097c7032591c64546b4e68a192e87956290cbd2abf5a2e0","0xbca829c61776848fcae9cc82da0613b9cb727582d55bb8730e9d79ffc37215c3","0x48d48ff5116a7358691341d748e2ef97c7d3e6a1a91bf3cc25ed07f64c39082f","0xeee791db0fda75f3ae5361e0ed73c2616c58f46aad26a279c86cf96943826932","0xd051a04493b8fa82cabd5a8bb927eb5e07ea87d8e39f8617d7b619d514cd62b4","0xad6ab2304ab2a0cc9e15895bf414d71f4c58a4c48b5f5caf071f0e5b72a8ec60","0x8be8b99d89e162e4920ccda137f18db720aa175c40015f5bc02aeae0fdb23ed5","0x758126e05215f9740433a7af695b619d675c51371142356fa32cd9b7f043660a","0x98b8644490481a65d7385ba706b61bf9aa5b9cc9d6f8576432fffcf0d18b15fc","0xb7ed85c36314963dde1aba3639c4de88e82d0ecf980788d1cc860d80cabbc9e0","0x5544c64752e9711806868c356b71b406cde150a8245e9e0e8399c35a2f1940f4","0x6902115a37fd3720921feb5a7da6abc33479948dc4d3f6655476f6a001dcf2a5","0xcc81bcf1164e6dcd36fea8beb8cbf066cadfd679319f88a85b78f76c02ceace1","0xd8d0b9fee8e77a2ef484824506838a9ca5dcb567fd7f19cc113efc1fbb6a7ae5","0xa90c4ce676a54722dce854ee8e06c5060657facd57576aa861583e10085573d5","0x15b6b9f4ef85da5792e59d03e75e045c1ab4c875d0dfb9dceac9d99b8daf0d45","0x75b22877e4830f4684ae080f789d5ddf114c8592ae29a1c4fc793efa2fc02976","0x27eb02826f5637a28fc8a1f2a37da11fc1335fc1946bb65b6667f026e353b24b","0xce2f1188d4982a6e5bd6332c3bd398c7068d5e2dba96add17b832542a759b544","0xf3289e3d7490c3755d4e8b187b50aed1359de26b208ca0541189d9c909f051bd","0x683638f2e06827a6858bf88ffc3ee1c2327803fecbe8715d8e316f21b08cadcb","0x0308145e52686419c224ff1788ca63ff562bd47125bc20e7c64558889e809720","0x23990d9d3e1dbc87b2f056c6250f19964eac49518622861eac91874b9b758e28","0x1959b41044d71eeedadc44cc259659284f2a8bf02f02861bc309607f52af5891","0x5a5d58a566755090f8619bfbdc776a2e140bb641a32fa4f29d1368c129eadc93","0xde463542576ff641fe973cdb4bcfb6c4aa86cbacd7f81b1c9eb2c9115bd54227","0x38463b79d3a7736104ffe2a50c62a2138d69d4ae0c4cc653edfbadd0cebb0b1b","0x35cf565b2292a4093ae89693e6605989cd1e611e1ea99598b3b1de6a0ac26825","0x2eafe5ce70a216dfdb6718df1c4f6646d291b6d784862815bb686c5372c0a07c","0xb87ca20f6f0286f72905e5e1a8f21c82f17c357e2397b099bb77a9f659c76fba","0xc8233bff15632243fd5e6f749af9ab3574c26d41026164a1242b7d41a7106967","0x10e5c008e888df758a10c5da1be9745c94ec9e0d414a7b410af886390cb6c394","0x69e367445c207ff983dad98ca39988d177edcaaf92d9c597b2c9f2076fa81927","0x374fee10440cefd0a690eed68f4e870f070b9509c7eb16edcd3bd74de8f44c03","0x389ec984b119bb5d1c2554424b07bffde2f617819b83696ab90be6f2aa3b14d1","0x4fb7eb48bf2119b00caad607b2ee2a0a851eb215be955ab77d92e8ac7109ebb7","0xd96a5c7bbb45862ee9422ab030626abdb17e57bc70339cbd48f5a14654a2fc3b","0xe64e66554c130ab194d0adf053f29dfb681faf6e92ada1698990d41be94fdbb8","0xc7cd59f09abc257dead0a39d2e750115124b93c5050c334fb48abd1512850759","0xd568d88136805f5602c7b20fc31d43f1b5fbc7b9dae5431887aec68a693f0bff","0x0b0f825bfdd1198365cc68012fae3b92cd5044d9b7bc5f66acd1e961fa48b980","0x504327e518f3cf75af73f0d0b12623d681ed40a83c7c678e435414e7237e3aa3","0xfefa75057400151df3bfeb55e8c4b66de780cfad1e012a4bcb0a93a54db7d64f","0x21d6e581658f7664fe0920517af65db871e280706817c0eb6ccf90d531137bca","0xcd0f42e9120309482aa226773dff1d1d09c6649555e1976ce5e47dd990a83430","0xcef0863e36bedb25fd6ef47261c827c302871ba3b108713188cfd31d28b02932","0xf849c7af2fed525b47f3416adf34223bd35709723367f911d3bb3d88455b5293","0xc3b6baa95f33871e3f3183f8343c536d9cd5e21ff8968a13407d2ba51d98aeba","0x2d5362f03404c17087848a99e717ec41f9888e4345edcfcf4fa8b460eef80454","0xa52c5efcb5fb9d023e7af2debdc34475d13e7e6522d5a7ca7a3a3e54a396cfd7","0x9be717d9487bea8c45c88d4146e011cbec021f1be4fff4cbbd2fcd182e477c8a","0xfde3d2ce46e1827e8df0177993bbed4a637212c51def1c8564fb03f3e27b4a6a","0x9625686c1be75318ef71e1e6be83167a0c3d5b188c12ab865c7519254a7f72b6","0xb25e8179c285ef91f2942f69e3c6db18179ad14ba702418433b5479bad7c43d9","0xfee26fd364fb99172b53eb6c2ca89c2ccb3675ebccd84909be920f80c2e47bc6","0xa696433b088df2313d53ef3d20caf7e4dba0fbf4837ebfb1645218eee6427256","0xd8c4c1e4672dacc10b17670d4b2c14efaad249a748b6ab14c1e3e2819c8c3a37","0x2553ca494bf4f257516a5600e5f008b807d0e49089658560a32ddd59003b7322","0xa6530df2c111b13619020685004ac43892384f0a77276c31fcca45c1530ae247","0x20fe4fdfcf85b86a5b26bbe6a7cd48fd542c95340105455c5a390b6ea7159c97","0xfd8c5c467ff9f0fc916d7c377907152fd6a2b9b8b5ceb5b1679cc9b8d0348604","0xfcc38d8f48d713cd29fac77ed84922f390b706db99f255951b10fe6f33a732b3","0x67270a2f2505d756e71d0977f93e44cb1f111ecc8eea37461461b9fabcb27a1f","0x23dec5cac45adde98fb8f11f1e19320b5ecca82691cd7fb0568be3b525ac3df5","0xa054ee1763403f519facdcfd0077f4831ffaf269b944cfb7e0fc02f33ffcce4b","0x24477a9d27f179fd26fdef6c69f3cdcba8bd5d745b479546ede515610d21ee26","0xf87f272ed958aa781f58c28b0064f7a035506fed632c5a96328660cc3465cdd0","0xce2b72732c9aa49c0758663ae7892ba7ea9b84111a6014ca8255c9d5152005f3","0x7f496a310514db2adaacc25f4c086cc03802e9ed6f287919eb392e66da35b546","0xf5a2b4312beaa09ba3b4c285bf6d6893f280620d4f614de106131154de05ab7a","0x73b912a2b9da433f18a96548ba207b83e1f3513a291a2cfe40879a102f876682","0xf6061d3830f036758534f2dde632a46151b1012e4e7aa63d9f415dfcff5a0268","0x79a80589ae3bcf5603bde39a4bddecbb490827afe04fac301314289a8ea902c1","0x8c2d3f1468b8e6f1d1d5abb965d9ac02cdbce6032f875dc89b8e4670fa157227","0x46394c9b2b1da88740db457eb1349f4a46be2ecb421a4dfccf37a9d1b43c355e","0x4e9252af4a22562df61c326870094e3d594e13759b0625b2def2e2aacb51f65e","0x5a88c96900aa77d9324f27dc5d50e3823785ffaf4a24ba389e76f41b09ce3f42","0x6bc932d2895776e99d2934005fd7de70cab294de4f920c22c759522cb0227df1","0x351eed0639e433ba5e653f493d53088e0b5f8cbc5cccb033c3d5e45bfaec60f5","0x429f983e9ec0b07b890a0f71145a9639b0187e74c4f388631208bafd2e178e6e","0xb046006e3eb70a5bcb5489e936346bd98d5bc1e1cbd9789defba01df77b82512","0xfe13da4271856db0a369d88fe908cbb44dcc851a51772b5f0fffe6f50d91befb","0xa99188badbd1bc0631fe63342e1f2d646b031eb84f83909d2d61518fde7c0904","0x7098182b3ee9dda03baf235674126427e6d12c915b3a8a028b188dd76bd3bfae","0xc68834a05f61caa0acb0dfdad0fcb410253477ac356e475ddd829f3017ccb21a","0x42efcde4f910f14896871d407a27668c1809116ed7434788579675f971c55eaf","0xa63afa58e88935fd38b213f60c6988f14d95cc41f3eeb0722823287d7ddbe330","0xfd0e3af67e38c4970699ee0d19dea29d18df9e3a59989fcfa03930a3909cb15f","0xdcb652fe731edc3a58ecb6e07c09be96885d7effedef6bbf28611366f2d6de82","0x20835c5e3d3780c2db4f48f5f1f56a3143495657e8e05d69ed80c93b52a7cc04","0xaa4b5eba13376aa772207b47435f5d17cc17ab1ff896cb0471895dd34f71aba2","0x6bb53641fcc3aeba1127db6e46e4835e72e83bcd7317c20e87e5a5e4cd6e0edf","0xd6a34183d179d5a05e5e988841717a388e7e13c96b977805c9af833b86813b8c","0x139d91f69979b162975afb21fbc141b30d4cddbc13fa2f400681bd6dafd0abcd","0xadd71ecfa8d73b807ec7f8b0a4ee8bea717cc7677d24661b0b7e8bf11de346ae","0xb0127e12edd401e9aaebd5f95931540cac19482108ce7c8164adf5a63d7453b3","0xadf0422437c54894a1a96a941685e40950b53fc68a5101c399f97a55899ffb99","0x2829a184b0da5c5b4ea1233c4d46ff6ce683f61adccf7b1a3018e3fc719ab6a0","0x891ff30060f68ab8eacaa52c87217bc51a5317a565d3d2696913f4a30d9d5f0c","0x5001c9f3658265e3a09147112bc4d49af1c31d552dad51146b5622f55408a66a","0x5aefbb7102dcc84715ecb92de7bc22202828bab1354d3a97596d9ee287c9136e","0xe05bc64a17ed2de7ad03f855d9c0dd9092bb60d52b089fe83beb7b22b6c511d1","0x1afc489f57b3b0b00c3be7e995791495e4d703c3a722b39c151caeaf9cb4e0c1","0x5f2b33e4a770155a5b15e877cf8c56d06d4d16192dcf09e403e92f64bf65304b","0x9c18829d583cc4219d8d90eb025b4fd4f5dce3eff41c7cf5f75a4962ab4983d4","0xd6bbee63b055b931fa3decced80d4ecbd595d692cec89a0bdf22058e1295c841","0x330cb35600f7622cb0fa664b9f3cf2ce76d32f7a20a589df7c4ede78ecfd3935","0x6c6928e84ca7db26789e4bb79bd396dc4eb8079f339b724fdaebaa082ef05a87","0xcf8619340a1abbd728aae1f9244bd1ac6d8cccb2a5f8e6d46e655c3b2186d724","0x7c536ba7eb4ade6ac25ac8a5d4f9e5db285205c58e21cd74c91f9d713c744bbb","0xe9946d4d54eb9aa84bcdc59f7613fd25b37d937590711cc0d4c7f04a5fd0df23","0xfd3f2f1030667a51f977ef8abb32bf2dad7aa5ee38fd9ed537a5a68de1ecac24","0x63fd4995b6eac808a629c108c3e339ced24d8d39e065882807a8918d61326a2c","0x74ffeb1f3439f3be0a0301188c1c7f42c53dcd73deff668b96f168a13033002f","0x721e8e30e16c4359b009c8a32cb1959bea7791b9bf499065b84ef2f4de30d256","0xdafa44a07f563fb926e9f6db5d9570b69d445b002826e229d03aa35b8efe65fe","0x5988d195af836ae7e52cbe624596b53c189cdc86cd6672f3bf3abb88de6f96ab","0xd0fbeca2ebc7572ba2d9902925ac59383c22337076666432dbb5d48723f10acb","0x7aaa816f4726a2b5fc0360e8c7ce28a7418ff77c74f453f2474d9a68b87d4a08","0x13d9d8ef8e3d6bb4b1e4884f97825baf645121b3fc56bc16453eef9f87d16cfe","0x967db698e478dd038e91ec3e581d77afa0b19864cc9d32589c5ce23d9d97df8c","0x12aa0ec5d482b3a63e778e5e37f4ac436fb6849027f7f307f9e86427b22700a1","0x6218cad91f65bb48697ab82bf3e5147e4e18beb278012abf9096acd65c2bc723","0x8ef3aeb0f03c36ee7300f22c22242f72bb539ef25778a5f7fe9fdf654950d7b5","0xae083ef33a17cab6ddd245051f5aa4fe18361b10ac0ae65b0a991e949714f505","0x767bf6b23cbe9214eca3caea28b2b857bf7f74e6cd0ce70ffbf92a0f3a067ab2",null,"0x4768ce56ebc897a60ac559eba1f868fdb7737941ed53a589a6953206b6480dd8","0x58ad5784fce55502dea701a564506c5e530a666679f7d12c4ad2a4a07b453626","0x995f4593b98956c478d88eb727bfed5e39ab61afa2f198ac525b954d9caef8b5","0x2059606cb2790503cafe49cafe3e2ee237313eba10a85a67bc4ac279e2630c7a","0xb43114d95c8e2c8f17101187f4322a54931886341da1c072518e35372c562985","0x52f6189f1e7f1438187a6e98f56a7080c5484682c6a192bf442533ffd9237c02","0xaa685a68605906d3d50cd67ddc24c8d7137d495d71c03fb3c1aecb7182dcb98d","0x54534accd524e807a14b9c8d0f916758da05a758ef68693fd360d221d0d0f883","0xfdb7c14ce1b6fb880f267c7b17e3360bd482ab2d3e3c6f762e99ec3aa34a3236","0x23acead0044846ee0b009f31e6b31899d8783bde0cce2d444b44d4aeea798958","0x6d9a5d528b351519b9a0355f19461567d3fb981ed6824a39daeac23100703a86","0xb897ce8b8581867d0d9dd4a9fbe15c2ac044dd8cad1af805edc436df1beb5532","0x3c58be5ec31cce77df1c9ddefa8e716b46e3ef1ee51531732da8bcba62e95052","0xf9832de22612b4ee7387b6cfe3dab927a8a87d28f38d5690bc7ef0b9b1a25f07","0xb8576b1a6921e16554b1bcf74c8d138fdcb3f79c36507b1b38a3514b8cf5c462","0x5dec4ef1913aa0435f774f526dcd4e37d33192e245073e5983d04b10a55cd129","0xc1accbd3cbac4b6cfe41ce60656bc4f598d8814b8632ffb610b14b3d2cb15087","0xb418a3e848b27ad3f6454ac03d0333966417404b7049c696a623d830aa3d9abf","0xc342033434882860e92a03ef351900a6d6a84f8f685a8d2d2b3a3637f48389d4","0xef61cdecb0c0b9d3980648398e0d590317b1ce0f6967515f4d7f0d2aef8190e2","0xcff4a7ea805d522b0d20cfdd973ac002d27fd2e3393378f4ec645afdd613a7e0","0x48d7a42b12b2464765fb1efce293d774102e713e3a303d0abc8726da80efc907","0xaf80d1bff6ae3409eb3228ae98a5a9f517cf03e198c514214aecb127ecf71bec","0x8ffbad511d1d89ce2b3c5d3bb94fe212dca57ac0cca4e8876fc131c43153f165","0x1c56b5e25b7a80d67b46f0f7990861033b28f3e807a08073fee6499986e97874","0x2fa05274a81ecd478b41bb233f879881613080c94e48a71c41d55217d976a36c","0x316cb665be07f32ffa31b938a65d9d8191be041747b3f01440104f65e8dbf2e6","0x623569b9f4dccf8ae3d565ff651d2505f73139fc5dcf2b24566e5f1285c7d728","0xa67ccc2b9c189820f222cce7168f8b797c1713938fb0383359a27d679e390c04","0x0f7eacd1cb24060f20623858c8cc5d44c6015c4446a39ef0b42d20f2502ca054","0x40d0e80f41bbd09acb9a8edc2b4b5f965f7c4e4083a55e680966c0c842c88aa5","0xa97fb99ea3847bcfd9d5509ee5ea22d30a206d6ebd9946ac8c94f6fac6935253","0x9dc045255fcd4fbfe845993bbc9a485aa692d87cdc38214304936f11a8a5b045","0x9637cbbb3a0108d3c29f4068ae5771b38c2169b09255e71c29b6f70814c67bab","0x5f64c5fe5b6223b1bfafbeb5573d03ca3bd979d360f230890c910c033227f8dc","0x287c6f31fa83d3c06b620510d864da2f0a2f4f3097caa95968e0ecb5a9389287","0xc268fdbfefb634ccf21f96e546fd3fa0c10190f8fb6b36506c2e385ec175f121","0x3ffea9084a6d6b82999db323d0e9a897ea4e0e7e4da0a4fa655710e5fe8e9783","0x017cbbc1db840435ba48d0f96c18dc96d55e154fa7b1275e787cdd99a383ba4a","0x90ff269de775f82fe1b450b1ff480e9f72ffb64f40769b06bf85fe26790f4a06","0xafc31a2f4889d70a5baac302d6241509fd10ccde3c1ef086ced98f265353560d","0x592649261464185dac1670503f28fdf110251b96219df4f028099a549df95821","0x00422d953cafcdb0bcc78d8dc9c11f77e84e2372d5f67b0db2c8fd327fead349","0xea9de18a278618ee844e4674332cf5dda2eadde9af811832b12213c138b26500",null,"0xc7b09f87de76d5c086cd98636be82772bb2428fec01233a4b68a63fff610d91f","0xfb8327a1d23d56ca27f87f999a2eb838c97e930c57529a19abad37fdb041bb27","0xf8e5b6f992bcf88a32889b002170f8ba35085c0d08e3854dd8b2729508d00295","0x6942d48882b20d08fcf3a04f3c95e2809baa1daec03a4a36b878cf037847ec48","0xd1e087e81f1d11e1c60e455d2fc128c1e8462bf423f14b0d5a85379eef1f91c0","0x6e9599631305d346ff889dcfb50c487494451e77517991f79dc10fa6fea54077","0xb11758823877f3fc26721b21d7fab2e8bf3796ea3383089231484aeef4b70b24","0xc6be87feac451cae609798b8b48171ebb26308223ce3239cfcf0013fedb60324","0xfb70b141d1bc32021fc4cd1a73bc2ce19d88c4d0db406fda558176a4f85a3bda","0x718ec68a3d0de12e7402364b8b4d521dc83cb69724c65826ead442ecbbbb4d7e","0x2a03dc2f2ff713c3d91bb8ad57ff9c4c2e9bd10edd41dd999fcb52e6dae70f9d","0x34637f8b30b5cfe8a4f6fc112811a7c48f3fa4f250674af4cc15b4bc0ae7ce1b","0x20b0b75d84f491cc673ee024781562eac32802524f1dbf366172f930c02d018a","0xfc5577bccbac851f677ecf9d4a0cc3c7af59a4095a92265dd07c246a8115e8cd","0x76be43b76732bc46ea8ef5d37123ddf2af59cad3249cd2d54c043a2bbf6213ae","0xfb18efc5fe0812ea61c4c5aac59710e0ff9b03b2321fcc703cfb12076b0b97ff","0x44987a3be75fd078b839849aab9d147576073f5d6cd21686ece3ba61d597508d","0xc94a11cd6cee13176d8f8a93189d32d9abc7a641d42ec244f6e9c78573e3f055","0x257a60ec4e4fa8cdbde6fe3d12678a1368d790d726a666a004d325b70f9f0929","0x5fe6947769ac37f79e9598a5d5a320525fc6899be60ce332fb2e111d0a3a89ee","0x4d35c701abae2b05dfa90516ea152b5ec7f4bae852af456a063c04164afdeeef","0x9496f40042cc8a1fe78979e777444f053e8ff98d0036f0caa0d6b30db925ebc5","0x3c399219f1f0c2d03ad730ecf6ddf7a307bfa0e0e34b3089634b6479d5a44d35","0x0c21e30916bc5e28513f69fc8b195c5f4cea8928abc85bd7528fac78bbd7f5e7","0xdc69234fc2ca9cc19cfa1ca926a2553639d5b002ba22e69585a2034075cdfe6d","0x035cfc4fc308b88620f43e8a9c2d51706e07e5ab875b591ed7c8c7aa6970c17e","0x9eab839dbad87b442284f2daaa162b62e10ea3ae695c720b060b298fc86f0604","0x3d8dd2d72e4565529f50f76c34697c5185700e62a403bbd0c88ec53589066ebb","0xc934e0841ece9956083e02a01cd029ebe0378199fdf2de4b3a784fb55b29d490","0x93d69e11d49a6ce6f6f07607a5190df78be08e996e6540168f80b3aa4a16029f","0xa57a11b051e4a07723055d60248aae689ee4abb0275cc7d0396c236384af95df","0x696e7e00d0abd44f0793c67394a46dadb19c7a2bbed1d4387e95e3c1d06682be","0xb2106c0cd991a4b91378691fa5b629402cdc2ba426d75afde7c4b034d4a1c467","0x14193b5f1949ce45b539fc94c9e235a844cbdadfea55df95084afc132d236684","0xd4db2605659c54789c05e920088c000b0e48cf549061e3e69d3bef1f114f34e2","0xab5dc5a90c718181b0a49ef0e24992ba944333cd115acc721e1f3988795a0cf1","0x5c227146b5152f82a800a927fd6d8df32ac0b490d6a33a6456688d9b7a5f599e","0x1ee8ae9a2d807e8073bdb1bbe38b65ca59d55bf613cd56e6a313e282f9dcbd31","0x9be0498d45043e6a40e1bb61a35e1365457d25b79ca73295a0e8c0e33f1f6231","0x82c1e1086b873f446c6333a8c6dd80a367e45defe53469bd77aff957d5f0833f","0x9126363981f06596273f77e3d4a1177005a63656560bc3f8591c8ea75f155580","0x1d9ddfc0eb5ae6a13ca2563cce57c1f3d7343eef4b610d869537a9192d87f95d","0x7cdce92887cb773346786af162ad1c8413cd3b20cc348644d06fa894a9e3bf27","0x56c235715d1c64aede8edbcaa9c3c6cce2a837833a20752a9f083b7e20459687","0x9633fd3ad0097740c09a6f73f937aded7225edb18358019b5d08edfb9a22febe","0x5fd837ecb677031a72ddd97a35539c20c24083436687f05fc94af60f9df95509","0x8b4f1772af124860d7c4816008aa6521d9d1682601ecaa7ac51dedf5f03a9efb","0x8349525e423c211a4dda752fc9600a265e6b4f8536701756f35fec16af4d3026","0x96250f70a9471a8144cc10b891d8043dc45bf558a35a0acca4a432e245e87cee","0x11983d872c5142922415715444f00ad9e430b422f32ec0c5f061d5e98873989b","0x11e658d5877ed0bf0561942e7b5cfa0a725e28cc16cfde63ac656cf0444d5389","0x442f4fd85115e4e0b60b516ec5f545242fbfd29c06d2b469c4c102ed48006226","0x5558f25d5dddd214258614de09035d50e7840e6214fd69b651f04b825a8121b9","0x5a7638ee527ca8a067493861600d7ab0b6a7beb74da6de680351dedb9b5da30a","0x9444b4e8ac878952b55455fb656e9ebe1808a704e86efd90e9560364177a1457","0x441a0ff78bf3a6f4ffd7a2c7fdfbc3da8d1f4d299b6e29da8173f7636d77b19e","0x3615262afaa7b70abd50c2bf70320c29a51f9a26e7a62eae8c408df6f7fdb8a2","0x3c68401814014d88f10d3964993e7cd25e51e756abb188a706a86aee62c26aef","0xe997c8e032bb46a481836131d6697ab144535ae4ab66c724ff18382c339ce54b","0x3b6da3db5a63dbd8bfe3a37b3187d78a2266a0b6b1c412db828a2b6318fa0c57","0x49ecc44263d03344dcc12eee483ac9f668d5cb06684bd0e7af4b3636480cf959","0xb29c2b7266f5bf5722a7bb2027d9d329d27faa719291182301620e7ab3410760","0xa710567783a5448939c8b434aff4284b20a4de603422ea6a908df201604b6283","0xe8d92eb6afec5b301a34bacec6b7ab571fb475010fb016f28a66bed17a95a034","0x8174c5100d940fcd2746948a32232b94cb63f70591ae5c34047b6e820afa0968","0x0bcbdc253bdec8fada32e0980dbde8654b306584294c7b26771f8e31aa072187","0x35a49c13868e0cf40eb512cf5c5b456691ba745f9c9b9dafc6eed1b4a6faacac","0x8986da8942286048bef75f6a2782bc233f4d5ea7d0c74a04fb3bf692c0cdc2d0","0x4886b3783237ee597bccb6ed42dfc3418645be5111384c940830a25c1b8e9e02","0xe31daef0f6e7e11506978e9f24bb7df2dffaaca0e98c55ad5bfb8bbf545907dd","0x248a4452a23ba3c3dc2e936511ecb02c746a741a33a04dcae8b8fc7e04653178","0x0ca74f37ff4e09f060289928f8ab9598637edecdffa7a69222cd19e944dff761","0xd1ca2b6e0cb2bd8f0f60eb0cd93e9f37b31db9bd79f82c4d32549d5ad3809968","0x39237d7be8cffef0c6ae7b1b38715b463775a83e9f2c8229c26e8e12f31bcd0d","0x123de0f5163bfcf4008b334dcefcce7893fa0fea3d14a46393828b145d2e112e","0x0d91aad009e52064be17f11365d6df09d7734fb740e1961564b61c54206f9433","0xe517d34ea4d4b4720978bd837f69091a319f3b7c3d616979afe386b3358d0f22","0x895f1d374dbd8a7777e18bd8b0408c2a09b109b9b13121854af301ccae1e603f","0x8e114cf9812502ecebe235e4afc1d921765c892605463391ba3fc9aea481c846","0x3a066ecb2d72a36711eaa2747ebed38ed222dcef7941fab62093e2b10c949905","0x34b7902489cd42c0376b723baf09db54cbf35843dee5360bc718f89e4556d6d9","0x7312a8dc6fe60a5a9a77540435b7c317ada95a6c09a87b3cd210525345d99001","0xf9b1798f8a445a4975bbad2a6c656f263c435f042fe9df1baad46044fe26fd85","0x3ca1686f31837be5b385d91bcdc709cb938968f45083f06f06301cfa0482813b","0x98c87886af2d2e861c3b35035bb6f00d071b5f802562a7697ace4173abe471f0","0x9e3d21ac6f6cdb65df03accf9f77024561c76cd54f6b8634f883865c62f0da62","0x7b37a5549d756131452c7901c8fdeb108035098a6f8503e554270370e87f3168","0x9adc30161e0af934262fc10ba0fa5609f01398a58943054f471df1c8a4cb3a82","0x1d15d897679e0d947e14cd3b9a25c0e8a61483fe7517382bcbb29c184a8cc4e5","0x43c523b0cf693d3e4cdab850bf70c92eef8671585c659bf640f3bab7734eb372","0x54377ad4b24a15360296ff5de98d4c46cc8202e5f6e3faabafdb57482b8afa44",null,"0x2db5da774717fce631d84ea572c0823a4be25821d878a9cc7b330aafe7ebc803","0x39d27bc8ef793023b3ce65aaeb25ae92220e84eca0c33b76c7287b4ae1c26623","0xac20989329223d4189d9dab890c1d438c9253ac8aebcf05eb27970aa763a5cc4","0x6629c7b613f10725450459a1562f33f47fdb5d43161264c03a7bfb30c7b6e257","0xaa4d337df5784ecfd976cff097f98c261bc89357fb9a9b30fc78a233c7ad4c66","0xa1771e82aedc25668b198c5edc6cfa3e78e20cf482e1c96e4358e0460556ad1f","0x87b43610d4c28fed0eeda889a467f1777bdc7fd5d9df120114bb013ceabfc441","0xe4383e46a6e1baf00eae95d0f61bf95462fe8e1dab21b0ba1ba3eb9ebf4d2b7a","0x193a8998e90bb6f337bfb191bd36a058361bf6571bf864b026aa43cad5301707","0x8bb5ff5822676eab50a914e7a036c1199011908dd27d7ab9c3799c97c748b74a","0x59786b20d1715ce671c8ba1068039ef0c1edc6905295f807ab0a81f34e49c4b4","0x616bfbb30566facab29afbabf449fa6e3ca09c1935de8b623e4320f6884eadda","0x30e51e8ffad82232ffeb4809a2d5f3b2657b29759647c441dbf648d8d323a9b5","0x313c809ef832ce7f2a3664345b45782f394e33ea461ce51c979a7c17a62a3e59","0xef2ec93ca714a23f91b108e7449166ecea7618ee832daf2fd32e2c1b6808e0aa","0x8ae9d3c7d2f0fc3113ae2379f121eda2200c22cbb0e4d16fc22193117cfe1439","0x22554eb649460f0fceb3589863b09d9fc012ebd5fd91e29e63677efa891727c6","0x36eebcd544fda9b2974e5089209f00778dad967e6f84cb282aba280bdc1d70e9","0x5b277103f731b5ca6f4716fd46b600c1c761f05837b58220d0946faa4d8c0eb1","0xe5ab91882408efaee83889e54c6b9efa9cf9ef588078e012e72e0515bbb9e41a","0x6ff360c9034eb9e8b0ff1034fe7d3f33a89153df8011197e48804422798dbaf7","0x085d0dfe016f707fcb23cb3dd4f7f61a887effa62525fb84eb7e2c47b11c32c2","0xa0cb2941bbf3596250e18741b2493c3bd4d139701aa44e2b5827263ea523a87d","0x28f303cae0a783e8666bb66c14ab13e09cdde1ab439d9ecdecdad12b66d99104","0x78b78fde565ea4be27c70efc411f7fe63065047024978c9c5fc5102e5cb44eb6","0xc3acc08764f553787e6b527f954455fd7ac24d89b6e52f39ebb1b874cd9b5021","0x8d5ba23e36fb4e626dcbead63d4a630adb2e1fa2def1c9594cfcea3fe51b51b5","0xa4de7902265fe85fe5df1bb729b7b4727f05e6c36b788a77f6d97dd6f61f0e43","0x9807a77c8705c5c57380a36e8b175497b30b8f63e72634ade948f23aa02967e3","0x36b70ff8147f3349f6e617d6c96771b115f94b460359ddb96677b5d1faec9cd2","0x77e353e2ffe6fea1dabbb02f76daeb3cea9f32a829a057602cc4647a51e5674d","0xe6147e9e15590817d48aec29da77a1386c65f226b218c019e767b1bd3b41ab37","0x50795a4341f5dee89896b2456bf16d13bddd933aabd2640520513736d36860d9","0x54d7087c0867b316163454e391880332d27f320566f6ff1e3059b61a2d981911","0x50df441e583b0baa8ea31b3f909a043641544b69f01de9309cc75b23716ee8d2","0x387ba7121ae3a3bc433c94f549e71112620cd2b5a2980d615e7e1f4bd0ce9300","0x72b072155e9900706d9a16c00f48857abcf3cf0bab275e0a93a4eefe9772011e","0xbb209f5da66fada437aefd46dabb93b2e82f25998292ffb804ee83eff92eaecc","0x25cdcc6df7072c7a69400c9a771a5309d0e5a82975f83dd8ab0c44bd742166d7","0xc286ec92d67876c6db3431cc8bfd1d3ad14334eb4486832410f349d410015c01","0xa550ca9a3e2873fba33a63ebae5bf735c3de48a34ea44880fc90cf22dfe23a1f","0xdb55cb875e3efcca0c255f75575d7eb8a1c314c9e6958d78321fb37baecbb5a9","0xec2846c8121d763ee5cdcaa7ce48ef4f2a29e541ea2cc6e935fcd5a6956bf5b3","0x2c460302196bb0cef00cd3d41b54e2cd5e514afc3575c922beeda2c3a996fac6","0x9793dff2717024c74ef2e6313f84587407a5ca668de185ba6fadae96449e691a","0x4abc3b276d96a08be0e06c6d115b8a081cf2a3983d1d3115396372b01fad1ed2","0x9f4b0b33ff50cc3cf453a15643201247837d5a45aa4ac076ff20abc13e61d8de","0x352c4949f7ee5052e33d62615fd9434ca83dff30696dc8103fa9e5fdad1901d1","0x63f15771997fa23665ee86c09b72f37ebbfa3f60aaa3c2a20323e8375aa557a2","0xef9994f577efe99a37718417f12bdd4d4b30f84de36e6729cca3ab140a665cca",null,null,"0x70d1bbd4513bba520f76ef2ba19c98ff5200a48de586c5e9ef06d1d1f79f5d90","0xddbf948ffa3842f2bd1795046f160d762b54eeda8f6732f76027572c32d046cf","0x705ffdf8112987ff93cf85f77703021e4b9d38d1cf75e76b3811896570debecc","0xcc36f86c1c1611218e1027bd130feac9800ebbfef0960d94dc0fbd256ed944f3","0x73cddd49bac97138c5b65053173ee79e94e32ed1a0cc88a1fc567218f8c7bf36","0x3aa25139612158bc8ec37cf77c2da53fef007070097b3f19ec3b9797090223a7","0x7a2d4319362b8f933870dacae993c26ccd1309c3e80b9af0d84a8b0975d6c2ff","0xbad0616a4d2b21c9808be765b79e373f84d302f4d9de111e87604772c01d278b","0xc20025cc32dc7495855fd3c9ff07f972b39e0e4f2cfd8b88e08a442d6ecbead7","0xb85907ca692c8bd66ee327c886ca7c1b3568fc70af726da51cf92d4c68cd5def","0x490efc6dc0f0ea800f79e1d226f60964be8335429d57be98b2451f745a7b301a","0xb1790ebe47879f016b9807641d7fb9d75171f9b1800145bf3b0136d9aa5ebd4a","0x720e768358b89f358bdfdc765c0aea13a7990dba73200d2e2aeac8fe34346d64","0x1dfdf9fb78b48017c3208fa6b1b2e953ab72209d624d66d4fda31891e3afb870","0xe216d43437184385262514591af42b6cd9694c4ae3db3b2856f7040156654027","0x9d551b438ac1ed40adddd09243edee699bb989e2b19236f4d2c0d6aaae70cbb4","0x3682e47c45c7c70a02959e2e23f92df821bbb5ef124dd061252f12418df520fc","0x2cb06c29686f16feeceebe89d79764e95bb03233bde18bcc55a392e43fa7c14f","0xae535c3de5548894f0c25a9937da1321cbe37d3b7a1c1169121bf236ac9a1b80","0x8db663fa57e69fdee0ca75e4c4d7571ffe1fe3b5de4330cff5abc425881df1b9","0x09ff335acc21c16977299a26cb9323da5be2bd6221ae1da9bbaeae6677585624","0x212e50e33d5245e5957c6e8c59b2f9e5df7e8257c31ec4299de4a237a50d0b10","0x06b4daf77caf7ebbee6e03a9fc57d919ac0973afb372c6ebcc356b17a656baea","0x7e7e7fd69588e39fd0003745049028b84616fb10f6b63abbbdbf81711c916516","0x121b98664fe2e0c1736407754cf55a6254108f9467ce40a86511910e8e289e06","0x3f5a75d023bead3ff0d39d54ec849507175e0692b64d1d3ed08ef33aef66c0ef","0xe8fc6bdb218f04a2cac14b882ce07b6a6330cc306059855bf6700d258f0b5ea2","0xf6f1fef8789745f0da9eecea4fb24adf1a685598f7c1d6f77a1eed00b1711b17","0xd09e4178d708013ed1c41e3febe8ad909103692ab26801e303ed154f4038fd68","0x702b6184de800c9f42ac974bb0478257e403c6d7a0183affce458b0672b76254","0x9288df5f2fb7bb432cfb3b126963f056b82cb0df42dd5bcb923978769bf425a3","0x6df0069b192f04cf818862bef82e2b80ee361963cbce89cdd7d996a7ac7e54dd","0x15abe9113309e2a219760a42eb25ddb9e81897b543fe15af0ec63c07ce8c13f0","0xb69b511a894f354395e491b5ab7bb1bf27a1e7c797c47d9fda3ecfefda18cdf0","0xbaa43375375ca2ea83615a1f1dffc8b9ac143ec48f4a777d61874de15287be2a","0x76bca5f2a6c3467fea7d710f72ef44e235bf31a4271da26388ebde59d035b533","0xd3b0521b76eb29fcfa2f0c34c4bec5ed8dd2d77a33bba084939755a22540d84b","0x7f41b313b0d9462f50768d18f3246c29e74532e0c74ee3833dba83e09aa8aafe","0xaad3d1afbde782f68a8ace29e902c4ff904fc034f1a41d33c21848fcd6746506","0xbbb7c1083dd8321db067f1fb677e0d5c2c7e1d68a52ada450204e88dd860bea3","0x45be7759964963ff81874cdc1145a678a265026adc7d14ac71afa2b6bb7c0bb6","0x1cd964d4a822241e4af5813687fa0de8e08d92127436c8b5c0e134ce063ffeeb","0x8f6e69e1175accaafe3aed4415b90858fcf65cb4957561bfe0d454ead8e0e7b4","0x83aea6c068777a5a66f27b878ae81232fd29236ec183a3d39e0519c36985c3ad","0x741f380f709de5b2314a0f1640e51fbdea29d1f1d7b83654b8ead13be4c4c95d","0xa861682dba921821cd18fe320ffafe26259d3de6427ef0392fd27204fb37b22f","0xd7b5fb94f751ae5b8d158b3986be40125b7e17faa0bd8c0bf907967e4106d64f","0x7b4b875ea0553f38a87a5400d71d0a5c3879e127c5ee1d051825f997c73f713c","0x3efae9076cd605d8f20e1a21a7c828b7147084b4f9938db069979f176917765f","0xf6dfe12cacab58c23177b7ca21dc89ee703ea016ae7145d7ce405fa102cca087","0x89e8fec9ce757a4b226433ac1cccad63edc12e466321f12721fa30a93f96881f","0x167a1d77f4623a5077d9eff4a4b75ed77b6428cbe5020a41c483ea82deb49ee4","0x7d948f25241091604b5a0ae398f6cfd4d821d27a884863ffb929831745ca06cb","0x1c0e1446b11969855dae51d8c1348d938c5218128466547f904f5077d5fc723f","0xc3029fd167e859ffdf74835681c6fa2f8b3af9011356f3b2d5974855f540100e","0x6e282321b57b8c6cc44e36c5b0c4b08c83211ac6c0814c698de48cdebb74b65b","0x92082098e3a62ad777c9188c087afa338c0c9de03a8ec67968f090be6a1b9457","0xb3a586e1ed21859189c70c4a2c8ce91908987d693e64a725bbdaa4a07cd0ea66","0x5af9a7689701995d233565c567c064f26fb4bbb2c4ab283cdfede42225d108c7","0xc0a67e164b70c69e941a111dc3f353e8bad7b257e07631e2b9147c33c1cf5f7b","0x488f27300b910f3b7fd54be6c8d52c2aa92282d77208103e54b1bebecc25ee82","0xd548862ba8d9a98d098e1bb9cb8db91b7a6687dab21c8d0c541eb749db8cc211","0xe222125196e405032b11aa957fd414c17e4d3f218be228f6fb69661aeefec9f8","0xe7c8d157a3b7ccb356e1c9817c0bd7919f9035d2f5955f92f879b8f259de65c3","0x2de230322d0ab40d82b48ba9feeca634d0871c9ee3382718d8955a2511031759","0x0b1e66c388322ea11711a978f38851609cba7e202e17b1e74fce343404c51dde","0xba5a522b5577a3ea466b0dc6b85f86c6846ac6e90fb2ad92fd7f273b04053d79","0x9417fb866eb2d67862fb0993088a7cab46f85e548881f2c2b660adc6054760dc","0x0ee32290bf81c1062ef98c6deb516a31d9f1955461a6cf69b548a45ee00c1943","0xfa83bb2300d8dc8b5b38bc96c3f3871c6dd2f6b714babf725ae45cd7f88036a1","0x1d08b888e3b5ec492b8dba10bbbad17c7cd44b6b78d1a248c19428fc373a3755","0x8c5be81af463b13e0f39df8cc0d7953e2bf8c129d6f7a594414601ec7b3f51dd","0x546a770aea4b3520f342cfa643eabc8e581185c8d2edb2cc472d973af9d1f56b","0xb47ff8681b36bbe9f2bcb0ebffac631680b2305d4b117f7507b9e4b63d3e9ea6","0x2f127df8dfaabcbe5e2944c0069a57ddf114b8685ec2e6457558e0e9e1ebea7b","0xd6969e9b14d1426403c7a846acf3029b3e0da75ebcebfd238f6ce98e55503262","0x8b8dff5d70cf120fe68f6f760303d6d9a4b5d128f7ce0c07eb31cebd696cc64c","0xc6cbf2fce2b6b976763a93e68c00cfe4847cef8359ff5178663844282b1af51a","0x2c7cb12ef5e852a027120bf4003876aea8c86bd1480ea505869a84a718a3ea52","0x35a183720357f2d91daa1e104a247ef70a2ef02cd50c3b802a0b3798a6ce6fb8","0xe7419f4ff8fe1071cb52b0b3f4a743f09cf4e41b9652d4547d485d11f1b8f57a","0xbbbd3ab490e0d2af9080d18b94d0de0e3b2eb66082f720b7c76c3e463aed3366","0x883b15bb7f4544f96823c4d1f6fe23d4baec493826ce2579cec6523bb910c34b","0x511c5a985d7e80e4d8cb24fa3277005d39f51db1b0ce869419c9e439a17cce31","0x3364355266f1233f92223279391c081428c04493b11eeff40637db2b0d1c52d7","0x9d91bc26b932bd1620b6255d3223cfcc5517b1e35c3b160a016872cb6a4ad0c1","0x50cb47633857706fc5544aa1a6c9f254051d747a4794d458539bf52ffdba4479","0x1eb1912cfffdb7fb0483c5afb1957a29e2f7006a93889b236f3d4cafcdb89f8c","0x3d3dd458bb904f430373bc008c2d77757718815f1c12739c0daca449bc8f7e17","0x1720b151061b204e064300b4b8e6e6536964a22999dd589432d1070e6024eaaf","0xb27efcce3dad630cc868da86c06d5af7769c48c08c9d6b9ff1598c98bf089c3c","0x96a834a53ec3dd824e29324ab39b4c0331d08ffde104eab1f7b224304ad52bc3","0x373c796e4da261f94dc60d97e7cb988a89516a1bcf7c92f996f27e4fc7a960a6","0xa36fed1f0ef01315379655bc584e722464b190bb970092b02920bc974a453911","0xf152fb2220e894018e274c20453e97e69e55e709285b7e6f432448bf0974f4ec","0x1483b47a4f52daf3fe5a2ab26845014373a7fdafe0f36d1a2bbf4640cf90238f","0x061054e890bb5480e35033921eb7286f7e31450da46d3a64f15cfe28ddc81923","0x91425a360206160312d8ff0d0b448d563e5639edf2cd15050f5527034bcb9822","0x7650bdbc8880dac33961041b91fa70b1a70627759a26fb2e13b5662454f5f2ab","0x4fa245ca94373ba7c9a042d94a62d2ab7eb07ec826e6f275d088e0b1c1ca1e2f","0x45540266cd191b9f1b4bdd44ffa9d1e02b5ece2919c9324f7213645cff8fb389","0x24a3d62da0e4a4736c62a3bd2c3ccf7b3cf56135f5c2a5f6192c4fde3cbb8f60","0x010a1047047cc029bfd502ac762733e6abaa7d5277e9d46a4193b1e6ede52200","0x0935fef2471ca9618b2a46ea676aef00b5135d17a400c41014eeebb7f55f8311","0x566fcb8da2d9af0af7553ac76c55a80aeb06c0823245a2008fe014be05b8afc0","0x4df7c8e95fb4f3de44dbf05d3f1f508ccdee80d8131525b414b10716549f6ea9","0xab3067c0c7f26dfc59363fbc7d31d2bc2fa13f6928cbe071f5387e3ae25b8fa5","0x49deef65ad34a890b2bc87c07a00435886e9e8d6d873dd633fef96a90cc0f24e","0xa90f1732e93ffba058f32f93d91d6e194857290e6625cd9155e95d318128e2b6","0x7d86ce6374176c14d13db5d9db13df85d057584ca0ad5f0de8ac9c39325d69a4","0x0c78ace4a43259a8c068bdda396f436aa74d134075a84c2ed1664cc4c08ee860","0xf146e970b89fde617257be622988f302688338f6144312b37a88699c73b59696","0x59ce95347081579239553638774076f3e30518d64b7b39f4e333dc10bfac9b2a","0xdba1c0f6d3a1c6ff6be2ee85572c5072b7a3cb024e958fda78da97caa7955baf","0x4edcc4d09d5bace441f7e5df0e94443c15041079c64c3f812ad2be903c967c59","0x652438a13a774504ba794ea7c837529e887dec1839c5b6ec1a87f059871f77e9","0x76147e1421a182e24f2ee2e39f89048543b736fbb6426a562f845a2529bd9b2f","0xd8f49d017361b5bfed8fd697baca9775c357b87488aaa65c8288bb7aa811a86f","0x4b2794488ab8e3eab5625694de928c9a1c23f6e3e6390b30ec68d57bdbb0e1e1","0x042069ac66d4e8a1c48e3befbf4ae1214e57832dc6496f7dfce9b6f6234f3875","0x7e827c96538b3728e3bff6481613a2f9b262babe1dc3badde204e58566b16fd0","0x58e2e925f3cad546f20c933019e9a3d30f3abb4aecedbb3664649f4194818ddd","0x5c2dc7c2109696756439d84a9d3f856b61ecb3e6e3b9cff95e336a92ab151e4c","0x0bbbb3553d6cf3404275e3794b1b385a1700f723b81e0589ea39969b5dd4e147","0xcfee61b9e62cfebd9ba41a547fb75c18f191d1ba5e8cd405156a8ab37bc58a66","0xc56abe21a8cf7b7f5819402bcc5889c306ab06b7a6528bb2a9c5fc6ca13d12af","0x50ac8bed9b2668b8bf080a2f803f33bc933c106412bfff5746d6e8d22c3110e8","0x04a576696f7dae825c93ac7ca044707b1817762235c17a8de5f6447ff80944a4","0x6459849602be946f4944f6e81fdd9d115900cb611bcab75f9f57e4018e452d91","0xd45d47bb384121b715182479e38ed960aebb78ec4d08d1e0790954e4cec4d61a","0x173c1a4bcbc7a0191f991f1bfd3d1be9e79b6d77867da37e4f1332f4e3975f4d","0x62adaa77141fbd495f8b2d461ce8c495358e5dc2b2d3ddc1c6f5438ed1c21f05","0xa354ea877d2ff0d5bed98b941498f7ee573f7fbe2155a3e761eb95bd3b90ee43","0x683d9a7ddc8524646681b625f315e066bbb68c2e38e9199ad6cb80585e008afc","0x82627e8e2c729ffa506d07c7a4240e3b3aab829951b7d79424bbcfb6217bf9a0","0xb2fdea09d2cb0f2e49bbec8b969c847149384926c270b82d1756a4a40bee0c8a","0xfda7819412938dbfa53302095fd6ea2df783ae01c584644a02baa6a30f744f86","0x78784d468d7b34d630da5055eacb2ba625a9587cbc21b528c4ca2bf3cc6634c4","0x9e706cee3510f33b5d5d583516e66b0164cedf53576b86783d3da401fb5a0b9d","0xc7c776f4df8f3f55fdd9a2c06c26e8c9d81d4a0c4c8471e4517a1932bd4a356e","0xa9ab8a55a445d4e4bc0d2327ec1eee4d1f4ec60e435c1c52ec59851a1c6175a9","0x5ff583252f0f553d11b6743fa374b5aa3c60bba2336c49c80c90585174482fde","0xab1707de7e1596c6ad847deecb7f041ef32ea062964f8724e65fedb110bdfaba","0x0a1e7be99bacfa9b65439bf6b881f89d9d700b7cfe1128dd35b69cefcbaf49ee","0x0cde78ac306bdde24f44fcc306e538ecc5922b6502d1ec2255eec13f282ec78e","0x145135145782195f3f1c6566de57552574c6212a3fc5013c5ddaf342f7586f47","0x0214e02087cc7fb3d93beebc87cf0cd1551149a7324f2e3778e4b4d1d63193d5","0x0c9c2710f894dbfb2f70c7fcef01a999fb7fdb6389d0f078dea16e567272f77d","0x92c5bee41786edeaadb3a1073966d4599a0e1743f37687217c960541cc32db2d","0xde93a7be1f496add4302f06f307f97479f0f12b6a69dc9a65ea2e9d838f53e50","0x6156e3b040c4c176f157170e4dcbfcabe630435a156e03cca54f558a14da5ff1","0x4300e3af24908b07be440028b42d6745680814159a6069cf32b0e7e9cae84ae1","0x799e881a53f85058efc37beaa2948b050a15c1b8a7f38e1bbc36c55e843b5744","0x25ae35c03826b4673549bbdf17633f1cd27d88d078c0d9fff5bdc2043823776d","0xd93c1c52acd857462848b95d8a0dbc36730f701a4fc8c6bf373cbc1f04b55d47","0xf200a477822fdbf20d87c1acb63c79424f4e6a1d930230297eec493bacd39607","0xcbd10e6c21170c26d44408298c80ccd45a9d36357dcb35a9707a73e8aae546df","0xf091ff79aab87f1dab1df460e75e0de45c3c77c8e0d83694f14a073e39e9c766","0x8d33fd12f9eacfe240eecfb1e636626ed25806acc5b2f7e6298482a0785defbf","0x33a1795429a7256a298fcf0ba7671fd8a1330e73b26ef87f2769a5c3c8d21da7","0xaf0d0691a67887cebe29a665ccb8fb54e327638990bcdf9c668089b8d537d906","0xed2b5044b57ab02955860e06a36f8dc350fcc244acd0086caa75b5758d6e0e0f","0xaaa16cbed18184378479d4183308390c1dbe9a2b07c93012a4440b766e01d375","0x77c0141a246d6ea20f6f6664ee6862610470d8c4801850c6881b81a90ceeaa1f","0x3c287ec4f09446adccf4099377dc2205e96ed8df5fd9e9e4168d5b9c43bef44d","0x5fb4b506815b8d782ca136780752aa43d48e0d5911111f7d058e137a1bf58eff","0xd8ca227b2c0f37ae285e6ecaec98b5edc5c192d6513c8e5439af9e334479ceaf","0x6f25e9941f699d44590e62d5e7b52e280c63464ea8983917cf76285bf6aaace1","0x9c48083dd5b084aa524a9fb1e951f9178be3d1d1c463fafbe5f28a8bccd563f3","0xb4683f6346db70287c689f611f919ab94e0db8b2f0c78d334c2a36e0880b074c","0x46b13f1e3b39fb4de55927ded03683800d03f74289e6622ec7fa8af96f839dc1","0xa050952cae44de8284ee19e9e945dec75e7a84f17bb56757ef148ec261adcc4b","0xd72e775965569e8c5c42064bc14ced4d502d83d50df65c8367d23603f3f4812f","0x3f3f14132c9cdb7c3415c2ca5547284123a20014ffa0f197b448e7e2cb81fdf3","0x4955fb2a02ea0c9fb63dee346baf4e09c67255f26ef31e3ce6d325203f735606","0x56e7821e6598748b8f24f866662b4bd11e7b4a6c5fe1f18314fd50ca77f75b70","0x1d0f2e949afdf930101c3e6344ebbc25d76ac28128a6937790cafe8b4e7aab47","0x69be4787446d2a6346ed3eaf49af4272368b32e593f147551253699c38478125","0x59ac82939a6915b3d35575008e01a8a73473a8c67debf8fca762be3ca23b3488","0x4b6c1290b575d40f249563d04cceef271b57bdb2e0f04344a411adcb719c8a83","0xf642acbfe5a62ffffcddb6092d08c081fe848d4da947e4ec34773a6f128563a9","0xb02100556faf37261ff2ac6c587daf94975f459ef3ff56284c664a924e67985f","0xc9dba13714d57caf0f09202ed9f6d44d79e8a4e7fc507b7870a7985e88276430","0x058c05a5a40342ba13b4d76891459be70ae863369a9293de60e2c4c502804628","0xd3d130caedfaf6f2dafef53174c2899cb543d3e213e35101ec142dd449ae674e","0x1fb8faae308a34874c57394e0baa893cdef203f82100fc0ded2b54046ad735a0","0x409719ef93807ecbe54704f418590baf2f80b7db363a7f4b33af54694c622023","0x9278bd49448bd6b4082986fd545529040f2c92928b363b003e3a9d61c551e614","0x065c3623d9c9e9f7a53464f83a43ca25e6072ac6bed28113b2944d9ce3b699ee","0x5402de2a31357131cd9608e9560fafd2498a0df08906eefae9c29e126559ebd5","0xc5c531b7d816f0b21a59aae3822e52156c37368cd8314e40328ffa94e42e6cf4","0x5a30dcccc2008a06acd4156d5b09fc9447b06f180da05c2bcd00b8ad143db8fb","0xe7aca709e5bd6a89652ddbb5696e36bae31b76e821c8f48e8875d5cdddad2143","0xa80a330dc65441cbee3b993f3ca0e57df9ea71ec7f284a2a8d5214f71baf6632","0x1515203e08cbf64760a6e3fdcb52308a333f4a10e5730c39a8c38fbbe826afe5","0x8e9d34b64c4ef0fa44c8d707363f685cb5d6975d42d61d50e9dc5eec08984bce","0x14ae854a07fe6e55ab254f6762d2b60f1bbd77f98ae32524eebc40ba946398d6","0xad1022f89cd8eacf8dd28f73b3c33f418cd876d1270b36b02ff8b078522c74d0","0x465dc0cbb323af9cc161c2f135082ee3fa6cc4b8f798d4ebbf2dd5c403f73788","0x2fb866b2bb94d693caa04d315c458792326c4324d8dd4a91447af1ed713f5c38","0xb23aa254fb14881d70258c843b6af26eb761498ee78dcd9ac551433d1032d34d","0x98879e8944b2487e850e0f10ecaab48301a7d064fc962a49009d9d33e9c5f860","0xc24c14a7da043727efcc10edb9dbfe56d6b6fa8909513af8dd3622eba06452fb","0x6ed6fddb8bbe70668cb9aa4a61b97ae8ab44fd9148892e6af387f18485683545","0xf6787bd10a31a70bd175b64ba58a40c7dd555e202496feb1aa3a0c4f5e2967e4","0xa555173b55eb557074bf21ef91026354d807d27940922cc859af9eaa9e56158e","0xdf38a8d6c879919160e21a3dd7e15527956e019b32f092f84357126bf2c15d7b","0xbfca11965a1480c465e6c6d88de54f56e0ba8d219454a6a5a4eeeba14a09ac81","0x703a87c78bb3159d59afe17bab4c2f9bb02d5d9ca99defa016c9d3e86a444b87","0x044a085699115894c9a434a29572c03f03b08ccfdb321c557e7b18c4bd6ce90d","0x5c19763dc9cda4049fc02de25ed2df7df1c35dc44f46c20ae6fd52e6551aace0","0x7f9174a6f787c02d84405f8c6fccc931fc1463876e4a2bb01d1323279f58f41d","0x45b93371e1d941d729b836cde29ba23ccf5571074d296fb36d174359a19c38fd","0xec57dc03713396709a95a2b7fe8d6c97461ff33789f5062927974fc42033a2c5","0x81d11ba8c02795130a349ac8a1fe61350daff49e11b443f162d09c9d06233dbf","0x83fc974f06884155166c61ad3e65eb03c2af9dfbbbd8b77e312fb1116158aa71","0xe5f3ea6bb87bb303bfa4b0895c11693ebe7eeb3aa418012621c2512512ae5f9b","0x5f9b3c2ceb63ff0de6b08834be2fe303ab06d50afd21f9e46c593716c2c75d69","0x2ee1d526647aaab1b163aa1f8c26d58fadf2b8181d6ab6fbfd5ed7e797f4cdad","0xc16604b4d9f9673f28f66321b4277b606f1473a67a1714df51e6291326563a6d","0xdea52a8562f5382dbc2dfc2e123fe04d6b6f93c264d419a32fdfe1bc3528bab1","0xcce98c3ab8484ae39a2d85b0f4f3ba8f9305cbd8ec3b247dd5c583bf3dbffff4","0x3b794fe216f2425230b759334430037593be9ca319a10daff00ad7cf02c08ca6","0x36f0a1d63edbd09932f376bd46516b4ad55d7e2cecfbadf4293358c7a0ba83e5","0xf4bf272fbfe85cee8a43b1ea1c30ca7a47a3cbb019025da449f4da9bf6d8c096","0x0474bfb60d16a62126c64f30812dc34c01ae8056e6cbb22a59eb2790cdbe9ec5","0x92e103597375c06504015e4497c0c741c1332044d3a31b7b520ae6e6b88645ff","0xcc12408aa9104371a7fbffce9318b66469d3eca4a25caff5d25fd6a6071b14c4","0x98cde37601aae4ceeaa2f51d2f26fe8458539acc391f3b236de20d5ac4452f15","0x4e92bb19dd0163ab64d5587f4805c916ffd4aa7626c794b689308b5c24dae7b6","0xf29106a9b7ee8658df6c6ce2aa517aa8a5d08a8dd7d95e411f0cea8083f5d6ef","0xe86e059f7083a1a281a3cc677419fc00dcbafb3f0676ccd0b8be426793ecd78e","0x44b99bd7f17bd76aecfc09f1da92cc6992764d8f917bacde6623654d24892fc0","0xd814e46d88169575562d7948efb40bbe3823cf3a83b8f7d04564170d46a9412e","0xc76fc21558838ee3a3dfceeba8857ebb0a40aa991b85ef622a2a2f3a407453e4","0x04ac5a3d4a68ccd33ab30c171c59faa22446d95e20dfa91e3e7d941472bf5e77","0x91d49f81e119361efb07b6ed4b75ed6292c33f656cecaece3f5b176d56448c7f","0x53d77b29f6b32eddfbeb00fe7bf70f2cb6cc9795b2c80327b4f86a5495c6f0c3","0xa06f08146b232729d3eeb13ba1a4719428d412a68051d48ecd3764bfd6efadd0","0x8cc34e86d30d35b8c07282bf791739bb1d7060bdf42e0aa84ce59fba873c463f","0xa0849ddc14410d7728e5fb5d65b23f94919729d34ae013dcd6ff0828022c4dff","0x9293272f55c0fd4bb30a49a0f9e8f73fbe3976a5b5571f138348322e17b6ddea","0x17e26ad3861a61c45cd963f99e14ce5fbc35f92d6887c57cb3cd48154d15c586","0x23ff30613cbb36dae4a8ae1d0f228ad17d3cf2359205bf5dbb25da2ef1c13fcc","0xfa0e12b6858bf19250acce9ab80045e04a0b56457e2487ca6dfb5bc7bf1843b9","0xec7194c0b446629d4a15f097ce2e9d935594e146440d155cc54ad31926022c40","0xd79a2688a8e15518be19daa0e06a42c386b7873422d47f1c4dc713b11635c845","0xae24aed06f9394f2a6e5a33e295e50df332257db4b1d2d623fc00e2416df4524","0x411ff670f9fef7b98a879494e50c4fd9d79e7cece7050ac406aab8bbb92cf62e","0xfb0a4c570cc2346a790bbd19da38ef1ca0f3e68e5cd86c7d7858037642401ff6","0xe1f2dfcffd13014d8460234fd6260ab5cb3c24e1647f11961e1b2d41493f82b6","0xe332ade004ad216cda39c4d0b52db5f020007d47aa4b0f13e5450a8e2fa98f4a","0x6c597bdab0e3650ed3fc9fadc0be46d1c08b5c993016d2c24dd2c19dba8eb1df","0x336b0e64bf70ce74d268b1be38d2036cba167cee374a01e7082734eb3a56c941","0x0d87261081e1e2ab733d8e692fd53aba987a0ed8306f9c84335755c6b901a9f0","0x0798f160bf9bcce4aad7595f987dc10bdc06262b1a1c1ed4fcefe56dc1cc5bcd","0x2929d4fd06d033cdf5b899565dd986b9860dc8013097e36249d4b41d2b053f74","0x7c99c0d6a71300fadf8aa59d7aec487745bb2738a716fc898f28651fdc03aae4","0x9838950d1507f01a5f0cee1f9864a2f3ad1d30b6c83b528a29bd37ee9a2b1916","0xf00fb6fcf4c2c8cabf34314af6c067ecba655c21afc64de2c664651c579933d1","0x9341bd7e3507b45f340fde48545be5556943000693acaf364b4d78ea53a15e56","0x10d79241a42095244724667572bd070676a9eab2fc653826944ec327d67397d2","0xc515e236b4d489e38065f941f3bd618a74f0f9ba0a2d6617fc9eb311901f6530","0x8bc990908d3727d0581c3aec81a07df241cb9cf501aa22408b0284178e5e272a","0xb41833b332e82a279f4d3ba1152b8e2a8f751fde909e6bfb9ec08d05146d5d98","0xb5dfcace304c7154996f42d2832d9df4430f22c270d7c7e750269ecb62776117","0x96021d71eccd5c9f4c7f6a59f22a4c46866ce98dc760a5167fc9b822d84f64e8","0x5275ce82c8addd098224b324dfec76f6d201e9c6fba25d6456a5ee06f7ab9c76","0x8a05f3dca3c6e7a174f9dc605b85e1ccc4bd3ca0eadc3213a97651975322fa05","0x29ebfdd7748442ec5e4a2c528b418af4c19ae1c90acb8b8e5befaee70b1c2942","0x3e0922d9b3032cc732a73ec5b8f495adde91d72916914f44995fe876b45a305b","0x3180b23aedeed703fc9a727395693970660933fbc6157699631694a648c34015","0x9e545d6070bdec0624d917406a33ff5a8c00cebcbb6cb9316cf684bc8b4c6727","0xf04c0860f4dcfec963058806e49e889cc542c66d9e9a72e8ab7a2483118ee946","0x46d27fbc22ff0695b275fc68c7e5783045f82dd392e73ccac8cb2810c67cc311","0xf91d29e75157af67e2e8b0a6598b771f91bd753df74120859ed8bc32dc4a5ed4","0x0e23f517e33064e6d5ba68c8ef0008715dbe59a45f18fc92ef0ff54f8f907256","0xfe5099f73f57c96a013773a4300fede30f9ca199e251c30910d3ea3c95fc5a31","0xbe0e666f0f94632947a2225e9ab78c54cc26fdd0915902d285a2a95ee83f315d","0x66e70871ec78c98683b62b799c410f6e3186b5aa500bf91839ca7458601a689e","0x34a20d0005534183cc4063be2fa79f182041d03ebce64b6b6cf9c34efc3777ec","0xcbdca9dda4f868d79f76e5543683f1b1295f0fc92db6f9b8af263bddeb5ed830","0xaf01ba0bedb927fc99c36c444822e58ff9fa6c8aab5350389e812324c3e2c583","0x69a4978bbc0ef842f0684efcc0919cd8ab4340cba18aa1a584ed66bbe6d97364","0xf76ba2b448ccc305ad23b8ea2848a1f012b1cbce5684591fef3017530a1a9d6e","0xb8a7e07f81bf41c492872175ec7e8d2ac39898531c96ea5266aac5f1a55f1869","0xf3dfac355ec404b9345df6a56b3c12fc83c3f22c9bd9327261f230575d48105e","0xf5706fee7ad7d0e31feedc8b123143dae6189b5e785ec3e66f31017466ad7c02","0x74b66cd9379ff4887eead3247623294a4b004aec9c11669fd97e287f773d6abf","0xaae435b0557a07b5a74c29b26ee8b59367f90fe89793b2c1fc86ca39129afc20","0x65f72de0717aed3b7644f0dee4f804d6b32f91834ce3d31119ffae6d8ed2a2b2","0x37ac16d4ef4ee195b4d1b16f49b4e62aba702a5b3880e3f6aeb999584876c722","0x7598b58ec15f784e1a6ead80c99663d4d2e6ec84804b46c266e7711af796bc32","0xc9179cde1f511d1d462873e69c7e30f7ef9898d9059df318302d800f03d413e1","0x08bb387ca126572d9ac0671b539b53a0ea1ca18063973271ececd5f57ad3bc2f","0x05de6e04575f55066fe34b22408b3d08595014af4bc46750f0304b35c32cba65","0x5904fb6926c9ac6b5ceb3fcfa5c6129c1285b4dbc01d4d539d9d1d6d1fe3065d","0x5d7cbee416c2825db5b9d21a2a571e51f618cb8136ec9e75e30f5496162bde0d","0x97cc45e873f399453e5e42c830f2ec2872d4821f70f44dc3616372d5115a9cbc","0x3b7f55a86190cb959f64947af9c42531fd8ab70db47a3c15a2d0664305abc40b","0xb2624435157712e6a38b8a2a53739765febb804f43306199bb674936f677401f","0x415a33f004d132dace1703602c446180166cd292fed5fe6f67ce308cc0123ed4","0xf7fe7a3d8ea48386d4b86b1f35b80b762b7361cdbf31396b2273e8279c47f1e1","0x7354d900121382ea496f1eb14e68d67103140ed90e42695777263904e636a828","0x6118092657923aeb9bf25050a385eb6f9cef7e3472df16e4c6478a6675e68922","0x1c64aaa0783205998c7d700f40c6216ec94836a304cf6edbcc4564b6693d7f40","0x64b72054fe44bfb5d2b6bb7e17bb87de63e0a4fc6baf82f01bc8eb9edfd85863","0xf12ce92f970def1408f8222f0edbd8bee86602ca4c154b48619c453010d61780","0x0208a39233a42724245e598a0f2603bdbf96a256d4794a6a6e93cd30e20a62f6","0xf6753da29aaa26720e63663b029745d3b443bb163746a4b936fff6e9b26a38e8","0xb5c914b2eddd03d72ba723ff381e56097edde1d8023a7df782fcabaca7d10e3a","0x206db29b4c7c96ca2ddf01d627b15606311ca3f16f4d0fcb3e168d4f85a34a56","0x753a32261a6f3388da2b7390040760bbc20e26efcf9b9db9756e175b019e1f86","0x253e9d2178a5a918a6056406063f39907b2ca730a18643e4888424ac70adb151","0x7e33bbf487b1174913b31c8d99c86bf1401087bcb400b20d782c8046324d26a5","0x92ca163d1cda1975aa95d44443a65927cf29237adc9ab5b66ce58dca30841c19","0xc817d132460b565b93e84ce2fd8b278add1f8f7234f3a367e79cfd88c6c74e59","0x2171a7e20b9ecddab50d6c8087f7b9c4c55509e3a5af10a9ee997133d08f79b9","0xc721a5ae469b0f61abf492225482a7c869c847b636f02046928d5d0c4626054f","0x300951118acd97d907b3cacf92a8c04f8b891716e3b825ee31bf3b0849ff5583","0x01b8c25c488e2c82f68668861af0373a02a06e691b3c5085cc293fb45f8327f3","0x60f19d278eb9b9c64058c7716814a96bdbe2b68c32b40dbcae8184b59a909962","0xd4b386ae8f4467ec67e43e93c181752ad314c30923cc0bc4caf39a22ccea0cb2","0x73f5f721b4effd50ed25504fc3c31a4531f92c808fb104b930fa9e5f0920c3d1","0x81d686ce50803d2edc066c33b3db26e0292df122c188ed3b7bd663c8df7571a0","0x55fea9c7358b66956b12b0238b7cb0499732e9d27df5a99cd18c8fdaf4182e3d","0x211ae933afba764f717c1ec53450b6db819c0a0e3c5b594bd460020047288952","0xf74c89901c10d21bedbaccfbdd735d3043fdbd160d4a7735a46c8cb12d18e4d6","0xa33362a8457369bef4c9c73f58873e4a8f4c1bcfe25ad2b479fa733b1c25f87d","0xcb81947205530ab6bdbbb86b21e9636adc1f76cff18cb2ac0f514b3ec99c483c","0xf5f9b361cd259c05fee818a3252242d0ff166332ef3f366286059a968c11bd97","0xff41b29870e3b070e0ab6fca0d3aeebe12836cc3df6c21618361c4c551d98338","0x1bc8291fc756846e8ace19e2220f76295659402ee9d34b1aa497e3a0e84bee58","0xa99ff49ab3637c633e5155a28cfc3c4234301ac891a29f9a79b4159167be68e9","0x09d5fe74f69306f051ba473486d107462ad7494a6c58a74fbf89cfa3dd45b839","0x29a11d0695b397f4c4a8cdcff3a0ff785397543a51742bf518d8ba3c20d83a8b","0xc9b3da580da360415b89a5b1140b8615d27a9d601aae8fa97278c521cf3abeba","0x581a2f6eae00447c2b6afa8b38c0256f8dc7b95be3f7f25ee6d6d0e69b516e0a","0x67ac015a54e461efc170780c5ed8d5e998c2657ff39598f628ffba471f288d6d","0xfc3ca636ee7974bc4c0a50d8e606dace2270f681a59ab71fbf9d1a16027b859b","0x5131199b01ddd908f06b964ada2e91ca8b7aaa7519d07dabbcc7efcbe4641392","0xb92f6a58cf42009cc05c92b1c2a4d04dc385fb0f106d56a9532ae2356fb9b6a0","0xf208050a3d495f303d13770e6adc6ea00642479ebb2504ddb98206ffa703d249","0xccf69961599a47138576f10e71b9d10477064b02a3091c585444c45be3680444","0x6789311f0ff37b64f6015558c1abb50b1411ea618a896db3f4275a7a267dbeaf","0x26bc2970482d270965f5d622c3974c0e4ecc61bc39d30d8339f34a99fae9f25b","0xc9e8ced121321f590937e8ebdc62f5af6d70265766b650441efde07c42789332","0x83119e387c365b7cedf7a972ba5775da008e63468d2ba63fba8a88d40342fd81","0xf631051da889aa0a28c8c8ab57ba194cd28319df80cd1e0f15d333bd3e8f894c","0x801fc4db58612f37b58aad909adb3d14135674302bd8e64a958214256f80ce87","0x2548f18d7e2c38c1bf130b4095f2a570e51cffe20494392d98dcce69f39560a0","0xe1fe163fab3d659b4ac445441418cc696cbd12397118374d26a45909e08e483a","0xca7a20faa0ac98db112080a638c2deaa40c4d26190d1277d44ff9c2ec5f71f97","0xee8120aeae60ea22dc8701f681ac2b09aaac27db2d06a7d86dff19862d2e5588","0x83ccabc17dc0a6e5d2d526ac33571085b846c63e7675166dcec3de52bd8e21f5","0x8190eb24de3f4a9fc2931efec7b82e96c7e7c4587a415ee021e7219e2dbc5ab2","0x33a78d59979fd3ab142f442ae317aaabf0ba363c2c8ff3be53c79b54ab6c4b2b","0x59ae6a315a1ce47f4d721135c0f7e9da0f977704a6d52f56009a10eb73c67213","0x10535d51751d685c1a05a4baf0875470d643ef3b24291b7058221270fe4c6d65","0x0a06d149544e17bab43427b92ba65c0779cad7e85e48619f3952f06311ad229f","0xf6e57092a3ccff78b9c9c5b2a66c3a4cecd2192fe968699cecc7df96eafa572c","0xc7a54c48307265fb3c4f5013d80148f5987d2703e73e2818b352e03eaca12e0b","0x866c3857006c36787820e633f95c05ab71cd107f908cff0cf3a0e096a3c6cfd0","0xe817301f2bc27f783d39f844b35d6c057bf4fe81b81fb447e302abcb4fe6d137","0x65ff4096f1840f96e447003b7b0bdb0d29504f9d08b3d1521dac29dfdccc764a","0x3a61a8e10f19fe9e4ee776bb780b5ef1b3284ec94c385003e885fd701299d787","0x61faeccb79a4011f6ee03fe5172a13d938eb768f5063683a0c83ef4e6eb0d432","0x4ac91d33e87560e3306308ce60eb056169cf15feb4b3608875fdcf8c1918802b","0x43cb4e41c399888930ae02cbcff21da21fff7e78670d1695c5badb49e51f0998","0xcaf6b2705f6f734226a4800c95b2ee8cea45d254b5534ea6f71ecb4d132e5de5","0x1396aef9e46402d6c6b895e37cf2e19a9952e5856bdc16448c7485e466072a23","0x0b678d3b986cc2a55a561d8b9423bd074894cf79a6f430d497d686a9e1ccc84b","0x835a480ad3c3fe81ba07208f42b5f8088f6a41cff8ba8d2fffac81cf3b21b12d","0x1b77696a93cea4f28588ae634260503ca3fa2be48dd6fc799d8bcda981745442","0xd6d9aadd366d3dace61688e9f4c18324178cfeab3ec91e39f3ad9bc9e22de496","0xfab4c5294749eb6f9077562bcd227a7c15fdaafd864b7fe533b620578992975c","0x7c86f60d754c07045ce69255e7e5ba837a4f5ab6bd82436212f9d671336fdd5c","0xe470f9784aebd58e7a11e97261e7e2739a42cc4e4b5e4b8df439af8532787418","0xd6e7fbe9d0ef56c07f31dab93ca6cc200dd94d6032cef3c4d0738f7b90eb6946","0x4ccfcf663e6ccd29886a48e7d69f1d76a568f217d29db63d663d95fc26c4e25f","0x75232d29db1f0ab581e5f5301ead18dd66f2f65f6127cb1abdee1650616d36fc","0x4da0b74266ed2c9b4500ad8e8d599333fcf73b5e11965dcf093ff05c191e558c","0xbe174b1261d0c6417abfad30a2b21546140614993bb6c901b179cf416511798b","0x3fef7d268eb000ea3078f4d9c7aac52988d22743e6a69659904583d296a5b227","0xfa1523805a24a080314cd65c2c200f229e970906a89c2cb9521e0dc424ab80ec","0x7c44decbcc10c5c676120f4bc03851b218e2204427b9965d9eed83e04d294e53","0x668233bd19ae3ffc034b79969158a791a89eb36620ecece6ae0ef740dc7bfe4b","0x45454e400aeffe713119ebf200ab8566e207986a2dba2b8a0d18b1a55de80158","0xfd945f870b9d055dd041463ad28d65c6716d3a041ef5a4593381a52ad235c83b","0x6bf988917e64f2f75dcf5d1c8ef9b4d88d27bdce7e0e49801feaf363303c6475","0x6797385ba0f5b0c6aeeff1c1467a426c207181662e38e7924ed74290d8f81880","0x115906a61cc63611008cd1af2d995ccab3c8fe5f9156240a29ffcc5ad4d7aaf8","0xf2b355108c3a2fedac5fce8014ef6a39b76fb1a0e35a30ba739577e45d5f74d8","0xffce9bca605a772caa286e78e65ccdd0ace57f338a914eeebf2c7567749ddcf2","0x045b394e61e5f241128c0514f6102ecfbf6d0cc6c29fa7eb3e549605a7eeffc4","0xd9f654e3499108bb10e0a2f86438f079c1dfbc12b7c48792961c9f5e9ff2b2de","0xe154c6e6aa0078cc434d3f3c05ebf407302f98a1f1bc510cf2bd2e7ca9056dce","0x8161fafe6ad06ec5835f0106ca6f79698b8f80075d082d12c301f68a36ab0948","0xe9863c730cb74b9c8738dd83bac34435b13f4ee2a9a4134783f68f40d8b9db6e","0x348afdab22a85b92cea0032ac6bb67ec43cb2474ebf96d3d8dc3f739291200fe","0x0ab7fb3b628d054c7db92ea60575d9eb574c258c2e2eaebe95b9af53e81413b5","0x57838d0d2831938401e70438bfac64f3721f8666d88eda5899b0e95e4ebb1e0d","0xf32d0d694d188130e9535b375db9dfbe244beb13b934f32fd6f2d5a5539290db","0x384dbc363c68e127aa70fa2288bd0f9b0e2915f13362f289751d3580945971e2","0xe500ec7ac9c41b4777e6edfea82594d8dc965e5fca77bb3654f8153340cd008f","0x43adda7e5b8a80ff13448dee3c6dc722ce921fe291df2523c6586ef889ff65f2","0x1e94a10f0a83e0317c69f81fa74c4c8b46cc7009f5501e36c3d2ad10099f343d","0x3868b32d610e5970bebc04280ffe49dac75ec4aa86f2a9b5d958950fe2f57146","0x6a4aebd382ce16712d1351094343f60e7242671cc513f5b609ecec8208f691a1","0x64c0362fcdf18ec038a89187af939989e12215922d711346e624f9c9f5ab230d","0x46dd8effdf91f0213c693170005b93212d3d6287366241eff8fa90ebd60b7c56","0xd1ac3ad8300aaeb5ab095f74e7796fbf0dba29b53e629443f8bf03424b956b7c","0xbe13e72d44e7865237b891dc2a5aef9908365d0516e8a3b7dab8e35b0a288dea","0x3181f994fb810129ae77c454f8fb2ae40f01c017ba657fddcd3b983bcb80f9f3","0x4dddfc70ad4a284ea93113be878fd34e13cce9316b86be06c2d4569e13a229d3","0x81757990b00a0a27ed7ce562b5fb6a5e3f85867ab1ba4d97e24bd78baecf9eb7","0x383a41690d61c7ca56d009330c937e5574ea83f93e7382c7416ca7e299403cbe","0x8d107251607a83e0001c10c1e9d8f0bef6911abba2ff8e63a34845d92db0497f","0x12ff7a1060a9615e4a586af0d35bbce49d5bbce2991fc3fe11ccccb4378cc22b","0xa060ec7bced6f20b33131683aa6420488f2efd2d75c0247b1232004a939dcf52","0x9e374e5ecca8aa0ae8ac2249cd8bef4c74fbad8eb0efcda9f2dd63d5f73563f5","0xcc741a0c36b2f84127d9c97ed2f93c9eeebfafed539d025e59f95b0e42fc1d7a","0xd263b817cad28923fd3678d9e0394890320b8fefbf2a84273d7d7753c6c2d719","0x72fe7cb27bc6104e4d087be842ba2eba7d08e0a562cfc2500e62e2a3cc019d45","0x3880783ca59fc48b5080b34038bafb757142368d63b889e7828721f4754645da","0xfce52cc70771e79f29cf5b9d0129dbe4318536015fe29fd910e87000b8f3bda9","0x1c1b2b3d76cb1db11be5830e9d78545f4183c9997d9f40dc40965bec97e0f24f","0xf01d0d84cf0e72cbf00650877a1f571ba97a063d7dd3628435a2820ea47b6eb7","0x02e93182eb972b7bddda9a455b37eb568f14c3d2d5374cd02d6705825c3992a5","0x88a33ed34d8f6443933eadf25cc3e2ead02f13faf0c6c81954e90e46287c75c8","0xa4affb7045bd7b0944e6f3c41166933391b0752aced1990553c4aececff1ad07","0x87690d79f53d64681ebbd3425242c5a5ee61a3c36093c646d23ae8200673997d","0x361e0d5d657eb276952b2f402d7b0caec2094dd3eef998332b67e7815f78f1ba","0x05cf9b25acd50ae3a753e00118ef9e3d4c9077c552175505a4b9d571d07f1495","0x9286f380ba28a52b491d247b79458be53c4cd5316c3654786d6e8f1eef1a0e61","0x50dbeb0ed30e6531c8a3de3fd4626a5a6e96e36061ea6752c149572cf57c4bd0","0x7f4c024240694f08c6bbf57e3d6eb563d3706453922560e03c1d528da90d96fe","0xf27ebc593f3c599dc1e39a818e277cf1eb034fe26b4be063f65589e34ee45d4d","0x1afca2ff03d0de723c2428a1c6452e759c15b4f0555f24d869b2d7b47058c95c","0xc0c78286aa657ee33ae477921a5040a8993c444fc3607e1d3afca055a17b9153","0xa14d3d9831d0c4749174178e14089d8756fb4a5d128b61a87824a4dac2050eaf","0x66adaaa5598b854c366df7cbd4c26d6d365bb9194c2d97340227eb6ef9f9a004","0xb6e2b7017446f46c6857467cbed2cb546cb7117241e3d392bcf3304281df16cb","0x64ee9124645d7e8fb7094f373496a7bb70844968ec60cdaddec52ec751c5b5f1","0x13b8273ea984b2740c53837ae8a1a6a6c0c9fee39cf56fb0e6dd2fec21b572d7","0xed79dd808e19b0d535b951fb2c244523d54d91928a78299acb83dbdd454c47b2","0xd1dc64cdbf1af9a0dccd554f6e3e01fca9537d4f683faa053b7af9c8314a165f","0xf8c5854bb4699a535ddfaefda2fdd450a427a58322e0a838b2cce5789eb48218","0x92d733cff2fcc5f6f0427ddf5aee11911c7bf6e1e3edeb3835293324e4e308d4","0xf9acc5457f341206a1a52bf6810359f5e0fe288aff94950a860ce48fb1b084e7","0xb6e4f7fce7f539fec0bcc2ef8af7be895a39e0fedb372a16d571581a39a803e6","0x579563ff17af75359fdf836f44a8eb21698dd3ab5324dcdd9d2cff0ed68815d8","0x99ebb96f1b15786ff0d3a615c31e0c1d63134516e2206bcbfb76846d72ec2bbe","0xeafaa87dec5fb5f3602e4462e232844b1e82bb1496f654c8efad0c5ac994bf81","0xc4cb880a2bd4127b5108d4738aedaacf7b2651d4316f664643072e45daed5518","0xc860a669e4c0285d2081a359bbe54f2fd17f68348fb230fa660abe25b93b5542","0xfa1c8080f6e9898f4122ec2aeb3570d5415205666871f96046a0617f0420f71d","0xe0872bbb130ce5ff9fca691fac97b4d67d9e10e06e3664669fae518c5fc523dd","0xb30b0763eb61c360b0ebce6aad52fc9966f1ae89481436d9db4786d79d723eb0","0xfc5e16bfa08370398880153523ff01aae080c9b73398ce06ae1154613707b2a4","0xed02d5492e51998f458b14f98050ae0aa966112ae4293efd8cba2bf75b0ad25f","0x2861d64adf30ed36d7baed4335d92e6ae7a0e923eef5ec47bd3899ca87d6564e","0xe6e7cc5c7929144011ed45f989e5dbb48aae189b1ae007cd0aa357c65192b570","0xa313b96e484941605302463c2e9c05e709f5f1aeb4a1c019a389b2a0bc8930fb","0x6bb0f167d28831a27f440501792261805cd050383901484ece1d6f7461d88cf1","0x0c20f73b5f2bf73f84a89c3e1a2ab48b52f085726f80e9f8ce649a8f3e606665","0x278a3b8e6ee885ab3170b4f89e2d48d3080a13bc2cb0a3515622d5e46e7c0ccf","0x5b6e7c71e4f765fd7cf7a47c6894aeb600f8ae86d99943e709c845b72be40ebd","0x23466c1f88a53024413267da8d2fb38ae08734401e50063f77262f2ef31cdef3","0x1bd7d951255807f12eb3d1f423c2b62dc2fa68a4754336a05cc93ffdec292b94","0xa0428386c54709bbe2a740a2f0410a2f84acddb2f28ff3527ab6f885f105a15f","0x62de190a839b3bf9b67dfa82da165435e6e582737ce39f5b395b33337f0ba22c"],"blockReceiptsHashes":["0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x3a60d4c47fe84c103e8c03e82cb8daa375a9d8b408df380eed6c913d0425bf37","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x5ef7078ba514851776eb062038d33dc7554acdc4c49fb723494f9e5fabddf688","0x5ef7078ba514851776eb062038d33dc7554acdc4c49fb723494f9e5fabddf688","0x32fa90fbd8644f750b350ccd5708cbab86028c6b79a004c1a2d2b834f6bb30ef","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0xf72f9afe4a9d8964289a6472717676702485512b2b35e3c8e6b40d681f876522","0xb29f5ea88828469b67d003b12f5989f954e0bbd4e6b0e03fadd93f56b033781d","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x32fa90fbd8644f750b350ccd5708cbab86028c6b79a004c1a2d2b834f6bb30ef","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb29f5ea88828469b67d003b12f5989f954e0bbd4e6b0e03fadd93f56b033781d","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb29f5ea88828469b67d003b12f5989f954e0bbd4e6b0e03fadd93f56b033781d","0x4205e0fd4869dd39d3d73be63c9253a91985e24b2939b54f14629029cb58dadb","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xeb0e9ce8951acd071c7ff12745149fb00be00ccc12d7a902f147c6179ce15e9f","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0e3078921751119cc2807f4ad98d17e8b9007e5fa56460ab086151ed093c6213","0x4d2eeabbad4aa4cb8ed10bbbdfb3cedb576c49c98cd1cc002a0873e359bafedb","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x4f38d6d71c4f08d87ea69950ec1bcbc2a10dc5466eff502041f570943ab3fcd0","0x0198c1117fe1378af5702733e0e57b9a1fcfad1b4cdc27d8dcfe3acb08271cd6","0x87f6ca65ad7fa9af7b8faf20c7ae850222c51abfa4d47dd5d07e74d8e94de11e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x4b5281177096f4af59405e05c79feb4d0376a6afc5ce1dca49f3e7b877e31975","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1bd1865529966aa4432082c43725cc60967cdf941d2668f5c79aff1c0ef41ccc","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb29f5ea88828469b67d003b12f5989f954e0bbd4e6b0e03fadd93f56b033781d","0xfd889595b243e5042dd27ad4cb68d6bcec6fb0d466adba455c29c431e92bff28","0x5cf9fcd32057bf18e1276afca626ccce9e1aa381af30eb495b53147dcdd684a3","0xfca5002b5730ba3db8b0d5e94469cce9751bb53d634f48b352a249c8402b79da","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa32dee43dfea50ab854a3603823beaaf6e166d47656fc08326356e29d289fcbc","0x6955772dc11114a5ad3c6fd398b882945e6b8e62474fa37d00d7f9f90b830412","0x14a531ff466036fc51a51185d64c975ea68189b105835d1782362f9d0994b07e","0x37bafd16031757a64182bb45d928cdccd6c342c41c3bca011147c463ca5e57af","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xbb9243a393e6eed5eae367e5a21a62144afbe5c85866759d97e2509d609758d6","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x55f965959f0e4adbfd0df29c8af092d0240bf5833fc1106c817637fab014b6bb","0xb987b0264aa7ac8f3aa4c2f14fb00a92ba2fa23e1c31d3d79544a57410b5ac16","0xa4e71c7ad60b9a64cc67be6c05ef2566705d60d3e17b3fb7f2e8d31725a10ada","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x59411fd128af01a4e0f15a9dbfbb4089ccfddb659f849966d1f47992b41cc0f6","0x64f51b9defa3a01a76933ad33a0e44f9a8620c05d205c7abe48b5f539df7493d","0x29fa7a2446ec695bc13fc9ce3c3ae4fe2b52cd484cdb9316fec3c44e0cdb83a4","0x442599b6b168d7f4565abb288531ca66668421db122fc60ae0dde6d612473cd8","0x06a8bbff6cdf6e6625988c3c0c2061dc6367e16a57c60b968197af4221032911","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xbded0862b6248c785cb813213ec630972854a39af56a9de0681288e7b2efbc38","0xc4fdaf8ce7dace69945efe7f76d7f6bfcc987a3938c38214352c7b7ee5b11284","0xaf1b4ef9c0f88e1c6061936a1aff73612dccbfae923cff7cde404e9232c12a98","0x1d2b09768292c03a91194015cd17db981db21a05901d9c28c41e45bf13d30d0a","0xf3659f017e1d89471e681429d7986a11c7b82b2dd64928161fab7defc1a60bdc","0xbf356dda60cb31015f199aa603bf1741bf22cd162cfead4549c5834c621a87f9","0x3e5d8f7fec6127592803a94c2ac53b8aeb2e6f4dffbccac97982acbea3c34696","0xbeac4a6d90e62adb930fc045e0348b364d717bd6cc16ecc94fe0ac2ea14f3b16","0x4363b5c68bc300d5374c457f4c203bdf09a49e00f495157b3d80e19d54f0db80","0xf6a4623dafa4280ea62ea58d5de87a30cfaf090e62bcb5fad95ffe679eaf0fab","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xdc9dc4591ca77989e16d887ff1838bfafb164a54dd4495eb7d8fc21e716e5358","0x0cb5be4fd2a1d140eaea3d033046aef772fd2822a9ca27883d0326de554b0a6a","0xfe21e3f4eacda8b96e617ad45a3259c95f4f5da008227ebd039a85ec9ad26bbc","0xb459d617d54b53a86ca7aa677fd096b9b408f975cae22378f8df67473b66ea4a","0xa9a630dff6ea46f8b6b13e8fba0f6402443e950b7536678cdf0a70f4c1833969","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb7e05f98282d031b4f9d595901ad26e2946f267a7d4208df532075edc3fdc73f","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf75f6aa4851384fc4044b2811b2b838a4e4d1d5ded10aa91d5d3217904ee8f8f","0x678f3736de21f2ae5a1788283e8066da5c432d51bb0955ddfde84ad727cd3eac","0xccd33ffa8e6b723e6222323f1a753471721c6b702e29498499ee5a993df51248","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x20e72f0aede089f0f58d7f2733abeeabb1db27bcf060c35fee2ee8627c303a11","0x4f1bba2c727b209fde15851480049297fa52416021b0e3b133aee96bb829cc1a","0x9c3a97b4744a3553ac601634499df378e0757feb878739b4b8d68aed12c9db52","0xf36220f5c942a175e2afa4e22901ef71e855a906442a082478b7a74b7e1bf01d","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xc2483789d987caf235d9c5c8124e5c188dc03881f45ae511872b424e4adc3117","0x46ba3d0a99565de583631f379263ad6cc4859398b71690a1367d22a73763897d","0x33d783b529dfead2b74a6b9ff9ae4d321e275f7ab432dce937780317a07f7ed1","0x326ce3be53b9183043d5608a9d8a153feeaf25747e9d462f95d8b46e6c560b27","0x2eaf4b19833b6a2ed3f7b7ba285e4a6ed0e4ae9c6754618ae09c0e4893bfc42a","0x1d77d27d119e1c5701888b4f237dd31be40ec65583f9637ac2a5903fe3e76f3a","0x76765e323500485fac3db2b4b925b642e0a316d80550a16546e3e46d1733e0ae","0xf4bd9605ba1a043b9c17d3ddd20712384debb5e80cd2148817dd7fcce66458dc","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0xd421269f0d1ce5fd5468e2144d74057f381d42218e2a09d80e660010d0cbf39d","0x2ad5b1d47a7e097c6817fba76d6a498441f460e2a82e8c26410d2f84013e1a79","0x0d6cb49597bdc7037f1e4911132fd8c160c32255328b19b94739baaaeee1aecb","0x49ff2278573cc4fabe4d82f80f716076b1488079c06c48f93c16d5ee2c43071b","0x4d1b7e3206b63a6711e6bd1bc70738c28244810503df28f9749cd6aaa73576e0","0xabfb2a82f76e6fe92290f9368eb6e5feb577cd5be5d3c0961dffa9575da01c5b","0xd4bb63c1bfa6cc539d795d804054678c0565b8ab0f2192b0fda61990ff1782c7","0xe9a62ba5256cd3fadd24866b51bcd3027b6f55446827d3f9d90572f7318112df","0xb29f5ea88828469b67d003b12f5989f954e0bbd4e6b0e03fadd93f56b033781d","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xfb65d7ca739cc057e47de58a508569b10607bce1cffc11a9e63a16dc18b3a425","0xf4c5dabc51fc5dd32398811d0d78a59e87142e348a61bd31e8409950778788f9","0x113f8420d496586e12dcb55f230c4bb1596154d8967708e1f49b669e30a735b9","0xb37d06f44666461ddf8ada257e4666db754441a6313899f85e8031f7320e992d","0x159945cbc03d2f9ce01ac5c5ece6019dd08d6e613dc4bd99d60c4835673fb8e0","0x9d0aff717863e587d1a65fa33da7fa61233accc19c1f8b59ba85df8066cdf1fa","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x2411f3869b9062bfa1a85d32347fcf37f75de7c75c9b05f6632fc2c4bbae21d6","0xe39b4d20f8185a8a9fb0150be378531e350f1496d6ae2680623867912d446dd4","0x2b414e186583470fb502070c1d40f7cc9b59aac326eb854c0c162e189ab00bbf","0x33699b50de3e02071ceeb0dbf5af154bed299295fc3153efec88eeb26ef78069","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x2e063e081b3bc6e465e5a59ae0b73dc1f44c6a5f9c9dbcfca0fd07052a5fcef1","0xa49351377460ecb5575279548021b973cbdad8ea26f874d8a208772a0a67099f","0xeffba0cb0a4a2b3cb83d1d1949c449b6e45049edf6991445382cef718d64b39d","0x4cacf0457a19f9ba0eb65745b6c49cf7e843e32901fdc4a912c293f90ce4b4e2","0x65bd4a823842596f7fd6c29b18129def99df4a504d8b171895ee6b17f644b6d0","0x0ce60c34d07324c56bbe3774feb6d4ca263401a718363887f61f5e39ec7d6dd8","0x9740335e00fb3c5235d685f93b90c6b857e6f3f8613fe13ade8bc17e43d60c25","0x3c8b289c77afdb7e471be9ba46d5e9ee0d8e8e8e681f6673d3272118bd82e2e1","0xef9047dfa0701cf93cb13ed1d21e32ece4fa64983aa4136573391ffce4c755df","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb826fd7036e9a3a0167990b59cda5c5c3835d36d27d89decdd02277186dcc2a4","0x40b33833707e98ec1dc2ee256dfb9bc071203ad775920cdc3b2a4201e82c2e5e","0x7f9f8076452623430c22ec4e61929bbc574cbec7f0489d665f5af434a3b8d12c","0x14313a5bf0cb1403a84ce02a45765ac15bc717436fd3f250e95bec9e7b7b483f","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x4bbcec817d50768c8e60679f988e878542fe48b95dba620b04cd7db2ac0b9154","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x32fa90fbd8644f750b350ccd5708cbab86028c6b79a004c1a2d2b834f6bb30ef","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb29f5ea88828469b67d003b12f5989f954e0bbd4e6b0e03fadd93f56b033781d","0x97a2e3f57874835ae0b2a71cb16454c914da1bff00f2b9c4bb8277002611a4b4","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x9de88cead7e1f7066a7c0281471db2c8a724f1e8cf9e2d4f7d7977a5e08be3aa","0x8c3cb7be14853ab903d49f37ca19a55db2ceee0457d688cb5436e4711bdaaeab","0xf421a5e59255ba9dbd15e1431484c5f4e2735bf6f6e631d46edaaeab9a67f947","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x4205e0fd4869dd39d3d73be63c9253a91985e24b2939b54f14629029cb58dadb","0xecc45abfffd95439753951ffe98a50a87d4ed8a1e3f0107e6daa695f00c4c151","0x4205e0fd4869dd39d3d73be63c9253a91985e24b2939b54f14629029cb58dadb","0xb29f5ea88828469b67d003b12f5989f954e0bbd4e6b0e03fadd93f56b033781d","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0x23fc4848729a8b9afef9409b93c42654aa664195d435dedb0b89be8a1e22ea19","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0x32fa90fbd8644f750b350ccd5708cbab86028c6b79a004c1a2d2b834f6bb30ef","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6985220d515221ec5850c7dfc333808bf40c0602de286077c88b07456899f951","0x73952818e1734c33e1b3e171b0d280f89335abe31de7daea8da0b6d08f6d569d","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6c22eff81db28a478a15f2120237c0ea96afea42287aff4557b616937f1b023e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xbf000d0d0af21213edd5c2ffa167e5d9ad3620aca1685a8f7f1a3a8ef36e91d1","0xe448128860bddc51af98019ea3ef105ded78069b6ca76d4a43679326867815b9","0x1ebece4390ce30971127ed9d25d072cb3497f6506bace8ccb986bd024a403e6f","0xb29f5ea88828469b67d003b12f5989f954e0bbd4e6b0e03fadd93f56b033781d","0x974bc01b4cea5d53126847b4ff9009537b100eda6934a27965992307867395d9","0x104713feaa934b9891d26797e47d76bfcd9bc17ab2a572ee97d7123443edab7f","0x452883379244b17284c705e7533e939d74ef56be7d90e374bb23c20342b7c4d2","0xe5a92af3d6115e9a9c683649f650ba79fc676ce26f23a3c2203de8d98b8dc607","0x4a1461e4ef5496203b04b9baa13ef0c5438ad2f3dd455d93e4c1bbeab0855f61","0xac1b6f29254cf5e37655ba7afda28a9af20744c777b4fab088ef0067d1471cbf","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb9e740f6af0de2a027cff17bd434648a3eaa23e86a0eff3e25392889291ba4d4","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa36da8f7581285c555eb1072549cd0cb31434799d9523d02a5e89e363afdca64","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x7de898fef0c537c9f0b9e61f82079d7639e9b9108547005accfb953aa77b9d82","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa6687a2c5496438892d490d8bae2841058cba3b0110fd831f05b6329b9cf4441","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0x1ad0152b6c6fb42a4975c4a780ec6a1237a7b13c31722b31e6d1a78020650ef2","0xf35d67bb412524157a31fa3821f7614de0c755da01bd8bb8a958626af1f75995","0x0b4c5cda4122d62c052ed6cf99be121422e64134821d1148f86dbd9dbb0681eb","0x94d02c46fb1ac00054ba46bffa3d11a5c343e538ce08be7ba4300d695bb37a90","0x1a275cb543c299803ea76dd18e616a54f8d665df1c36a3d48e6e377c104cca81","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x7765b7eabcb7f58ad00f9bacb48d18d59ff87f1e7fa37eec6058225c1710d464","0x04e38da345ad67b7fdd0ca4c53763d11ba0b1da5a53fad512ebd289dd1df4959","0xb15cdb271378c65df82add92c5361927b9edd9141487e0154afe9132dea74890","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x46afba54dc42513606e8a808e8c3ebb3e0cd7b31f970dd522a5415dc49f3e3d8","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x774863409459107792d9daeba7a647c1cec10bdb7653b6c1cb98ada7cb071b2d","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf2adb1f56a09f96923e14a4c13a918b5dcd87f5f5a0f8396c9e71d266c446ef8","0x285edc7a23d2f07888c8629856358643a51ed1b471a0d445eb52fa0b7921d25d","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x3f144555a1633c267b40bde69d88a29181899640eb2958a0420f9a663c0d850f","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb486d3f692fd3859100f77329de385fe4127cb9c1bef587428d1983aacce0d2e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x7361b3fd5b0fe3b2e04c3aaaf167a2160e5af399999863c09639a9f923d7f9cd","0x0a1e4d898d91b45cf1381c2bc54e015839a4952732f89867a57c4db94adf27b8","0xfa63f4dc85291cd1afc10e46e1588693aef1b7e66686fa06860452936a8c3e31","0x414ba264b8bc0be2a8c689059d3e2e062a4f4fe1dd4931e034b05c440d6846b5","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0x146ae426b0bd7ae90fa07baf7fc349bd3be46f93c1d531f97cc4ee7e4ab8bd5c","0x392d145e652442aac34846761c285db6c44ff2908cb2077e15dd38e7098b1fec","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xfb757af993a4d2f9390237aba8c0e17b406e7f7566919baf2588d3e5316e3aee","0x85595137bec1b940a5e12030866d6544a37fa18ed13a1858ae62b14d119aab6a","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0xc8fdf0398961569199ed0f1e393e84454ffefa9ba6854e6d15e770f6fff0cc90","0x9f337c9b4b7fd8d867759aacff616c3a9a68bbc585ceabbb871520f9dfce31e4","0x60459ec04d1eb8a0cbb4a43be569e80f5478e090eb337cd5d97f0116d445a0e8","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0f341332f860a9e16fe7ff0c5a6d4b1e66ef14afc15845b7334cc9f00c618232","0x4d386cc464357f951aa65859a834c377e7af6b9afe4264994acc140bb2597da1","0xacf6f6dfcdc2d68158d5c7aaa88630dff5f2c1f29a6b18f5ac3d448d1b8b3b3a","0x415bf742955397be45f4272ba53b4f92910d9cab38d6291f4f37befba00f039d","0xe0eba8622f5414cb6a326bcbe6ca1ef5f23f25658ca2912c4cec02dbfc9b972c","0xb1ba06d01d8bd47772aa92569183a48245f67c31ac1aea49c1498675153d6e9f","0x9c8d9670096aaff2bef9beeb7f3747b43749f0858abbf9a0123a500eed7a1174","0x3e40a09766c973d66757f3fec2be6fb9953d71a90ea70b74ed8150b3a8e4594e","0xe9f10d298fd82c9782e012e54e28e20fe3806a5a493fc6f30419df379950d6c1","0xbdfb8c9b2901536025755e0071f0fda04abe9720de9f8e8f316480abcbfe9ba4","0xaf2ba086db6253cc0f850668448a1061e1ea8701d29f7ea1dc97f95142fe8399","0xa8175f477f4b674328f2aa84edf9f5e68da844bfca0e632301c6abb722ce9fcf","0xcef5039a1d81220b17110c1ba60ab9b2e538b99c9e91b9a451a1d1edf6e2fd20","0x54d50f001d84c4cdb4044714e8718e8b3ef8778f955c5bfa37a443f21aca33df","0xee1062068c3ecc41b345692d779a7de7deff61af45d8d0d0659dddca530a215a","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x467bfa0e27234426d7c17d48d09531911745abc5b524d0a89cd6e1b65e7e03ee","0x83c98afe4ae212f511c56c57f0d3847d1b7e2bc2587eb6d3115361f9d04ef405","0x137d48a1f12d21c3451eb707449d03dd157637e6bb63aa1d98fdb39eb699d5e5","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x64d2661a53bb86eda71efa55bf0b886157d10e281f086e456db58ca62e4debc9","0x028140595c3768b9284258912603b00c237a4b9abe56e5f7acd1864be5aead5d","0xd280beb2da2fa4773c921c465eaf3525fefaf2e2aa86ae175c8c76d2084eed67","0x6d531de46e824ee51023b426f9d1e9fe10d162862b248924c9999604480c09f0","0x38889eda7940604085faf9769f68fe6fb21f045960e3524ad3524b7d7f0c23cb","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x28e5ad2d04d59a9348d7d64a4114c828c0c78d304d650abda86648581c7f5b82","0x513e8a8cbcf97b18c3304060b4206f6000b4bc6d9c1d302bca3435394b1fd15d","0x47bb5bdb11c3d9e4f210ccd684211010babdc37cdd27b2dd17bccddde67e98da","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0c809478254db470374384dca23e338fc7768cf4d13aa4e47b37b2bc002d0e1e","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0x81fba72b4eebb60725432cd16e8dfba21562b8e1053fb9f99673441b06365b2f","0xba7929400b30faaa8eaaedb26f81dba5ae093f6727884fe6fba86b8ab7d35636","0xbafb138c79db208afbf9813dac16084497147c8935bc3626e60a1e1dae2cf56a","0xf54c84d21073c2455b6805590c28a95f104dde2cd0376a712ee1ff6f47e4f38c","0x8ec34953d7a3b48a6c613a9a75a2486c07c086fb67226cc1654e41d95cf7508f","0x0bb05deba75234ad173d461bbe32888c4a133cb44992d2ea45c198a72bdc5aa5","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x62119aee424443b393c12ee412df20e761dc93cb1735024180239081bdc2f5d9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xfadc670ef7e5ab4d617ea2c71461145433f08ee561f08a4c0c2264c795c00ca6","0x8236fc7dc0f11b7db2188b1f24363a406b4fb39dbadc6f80047f8eb541bac307","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xba1f12cecc7244c49c1f9fffafb3f4bd2b6489117add695f5dcfff69c878c67e","0xe88242d08fac35dadf194b442d334102f720bfc7f42c8a1867e1b5f8b66c8a68","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1ca362ee511e531718657f5102750e7c631f83c423d30801a6cf307385485333","0xbd1e84f9c51d66b18266dbb292d388a319681277b4f87da0ff659cc3d1c69d9c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xae327c68dc5a04fb2bdde8118c9c874bd0001d5396a200fd02c8deddfa9c515f","0x84a0c46e9f1557ced825a7599a6370f0fbee36504ca11b83942c3b62bdb83d55","0x60a0cbcb2d5ae79f01fc8dbed757d26123f4e69f630c6a27da6067895e8ad282","0xae2b9d9c2a838d6704839992934257401ea5328b1be656e69ad66c40e770937c","0x5bb847828bf9b0d79f2d630d73b7ceadf11a0ea6bbc75607deed2b8ab55e91f3","0xa1dea7dd034ac395e0e7fc68771d0907d162555ea9e0f64b93bf12c0728231f3","0xd4e48b114b059e3492234c05cf02a74e60690ceabec63cdfcef8b1549eef6bde","0x33efdde4136a648f8a47be2b97bb1e3c45cd59687887767b5ea3c99c38b8ae8c","0x43559ee1cf6ab898ccd0c71a83f0ce0def53dd8a6e9c08e7f544775ce5c4cadb","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x2256c40576208cee49dcc15613ae4677fca07fb78086ed6a4a948f1e97f8ea61","0xdb7350b373fbc9bfcd021e41b0136d9e7d6039bf9be1b6b2f7c78c70b6c989ae","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6c594a6bf00247ac4d90e09ada99749dac76ab0a77e98bc2aa8e2300fa0e1aab","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0924fb6c2de10ad7e129df3c018c23eb8505fb3143df11f7fd3b9a5d6773a882","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x4fc8b18d9850b250628cb0d93c6307c52b2dabd101f315d5eb89de2ff3941916","0xd675081035c2b7a83d1e1d2a697f2a19e9cd5d2b7affa1f3e5c66863a75fa809","0xd8e1b2bba94ae45568d5c32598bcb103c764595772eb246a11de7949adca6e8f","0x78d92359b46b5f7690fdf0d7321d85e59fd114d029360337d6372d30c619bda2","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb848ad1fd8e0d4fd42b0110343a7ae8b726d4ee93522f43f8d9c2b5dc29b82d7","0x84c97f5cfcceff4039ffed5069aa7a6a33ec1cf87f47a5cd220c5d3aba82899b","0x9bfbf6e9fbe80d13176933c29d2591ccfeaa7b05f6c391af6c784c324d313267","0x6342bc3ac0a69345aec6d2d413a4cad2a5f3d78aa15dc1b379391be8bd66b2bd","0x776489fe3fb20a901bf9e8d495979d974b4242faaeddb907ba4c542fa02d6207","0x511ee093ccac68324b2127659909f40d55912226b135150ddfed0223ffdf6e6b","0x1cf3158fcc2281e77a952823d6266d2fb2fd60baf65b680ec9fef90758c9fed2","0xe764071dccdc79103765fd79e4a0be33774b456e2e3cffa52245b53e8457b2d8","0x033d9db99c95854529f75954b2c6a18e5d15fb6f92a47da1e70743968eeac704","0x930d499ee0446b7fdc20aac9351b19372981dbc32fe04a47df4e7052cec1e451","0x40993ba5a81c4c837ff10bcea4b95babe24ec1a1babf642d112d8d756453a835","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf98440c1de2c06f94afbe6118afa5cc73630b90cae4aebf481c0ea0d775d4e1f","0xed290663d9d96e2d927a1821d86afb5fd38794cce001c2d873ec139671b04210","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa2047cd96a9359c05d8abf109922bfc63abddefe599d5d5f1ff133b044878970","0xd81e538f983be26d9c1007f64951479538f1a62e50a86b964fcb645dd8ba8053","0x7b6d6a4bd1c867a2e8f45f8e711d530768399feccca1abdd955b33ec4229f226","0x81546113f5aa69fa84e4424bd092fb5fe4f093b7be8183ce57a7a5014d036223","0x31fd0d038a6d31a0c3657d33428074e8b6713f5c56c51cc150ef115463a4c7ba","0x5416abd2815f42a0af51dca684d9315e05e8dd6c1349d8c51176d3d41fdfadd9","0x51c1bfbdd709e475e0b8e9645e19ca8324f88a5f94626afd0e1c4b37ac95a6ac","0xaa859a3910b882454bfb2a1841aa94a7b0d3e44e496cba8c8d2db5f0a5cfece9","0x10612bf696a4f603811aea341ba0a142191d1a31d48dda0d59bb4cbcddf4244e","0xd370d65bca9a9d62d958bc85cdf455a13aad9fd7ddd7cde8b0991d719784f8c9","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x784821b1c17816490aa29b1a8e025fab2835fd16e0931e65313c7290260d3392","0x2e33a0ca5d9eec4c9dd47b9ef77cdf6fd37d720e592462b0aac2fbc78286d5a5","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x56ae68b59fe099d7502fd2f09624194151078dcd0ff70401a3efc2f64c1e8d8c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x2b3a364dd7a684edab17299efc0d7fa828db43b93cbdbc3e5f576d7ac9e75675","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x4f1fb9e5a183f508cecea2fe02a9b22f7fa0d478172fd6468887cb7ee10e325a","0x37599d3239a28e2d5d325a37f3e98787758301eaf437be6facd808f5d2b04dac","0x0028c95b248e12d02a6261f968d12e6acea47e168b12a28ee32cd8f773068c52","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0xe48af58167f3f81ee6722c96790214805173218e4c6c9cefd860361267d96a04","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6d9165a83c7fb47e10a9a6920fae3c83c3007660d69b5f702c068c5cdfbac81b","0xfc8af0623b105a9a6f669a539b3a029bf429f27c9e3d55782d00b111046eae73","0xbe670472da0a1403c4e7742316967b6e259ccf69da9cd18fb10f888afc80b8e2","0xc617054d178a60665d58cae07630dad93b7c1f2d44c783d142a5275ed5022505","0xee50702e59f121083125217eacac44645ca2414dd38c44e4dcfdfe525205ec93","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb5a1185b44f1e59d2f8620f148c2b3643ac57889aa5f32ebd66279978b9e7027","0xbba5f9305fbe6787c6e1987070c3d436cf7960de9d2ef2ded0f1551af1442081","0x97f0b87df2328daf6df4c72fbecc74c053e306fab22cbfc403a3235b402ce53e","0x3ca58a9a221a52debc9cc1af9570df17148c84f328e04741706e00ee2ff8a908","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x451d6be17dd4c65be89b2078a82970911219ff679cd55a513e0429bc864d2eab","0xa3b9e233babdbe73880c39269fe84f535defc73940109d087a351aa960de843f","0x856cd1fd9a24a52ec5633142d7989abe5a1a1b5617db16fc8c6006f9b7b7d8ec","0xe3d38d3a19c6d9b58564b1800eed8d77424ffd2abb3fc70ad85fb8c9a0b00a86","0x26756e1a58e5cb6eafea2d218d9f4ef5db0cf2ea0381ae24582aca3fb76a8f83","0xdf8fa6269de18a16b96e5cdb91261b51a8d14bfc4faa4565cbe0ae5a85a400b1","0x60d5574b3ebffa80b79a9b48acbaf39ea2d51c3d0afee7857afc52147ffad355","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x402fa5f8e536195b208ac6d5ce0b3210126d17ab8a960584e9d59c4ce91bf90c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x095f8a395e1d62dbbc8d787c4a14543c408470ebe8bfb317321369d638a74baf","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x6334175f1443dec31ed0d899c8ac7c445ec6ed95670b3f0c0bd0c92a2144d651","0xcc7b344cd3214c5bb87b4ba3e8b34cf2fd30e68123d349d107e77a4cecad5fa7","0x0187f61951d5043610c573872ce0a8796f7144823398e6216a192a6a551be9ba","0x1f0fc2a876b9b156127472558956c1e990611294f619bdb7ff0f35312abd19cd","0x96bf1fe74baf7fe00f5b966498f67f6898805214638b9c82360e56bcff0a6589","0xc1c2f15a36e22ce5e3a9f491485b85966e69d4bbf29b0f1502caff13fef1ebf8","0x2d3bdfd05df910b4b61fdefb1cc560c6bcbe907664a13001535427832dd39696","0x32fa90fbd8644f750b350ccd5708cbab86028c6b79a004c1a2d2b834f6bb30ef","0x2e85982253fb08990d06494cd5220c86115a333230b9264de5df347d5ff5bbf0","0x5e0342d78191741472141968bb0c1c20e5b540341641103df8f8066d70126e3c","0x5f6be7547aefde617f81bf2a59d94c2d5412e51ad23d61d224a6f1feec0c67d5","0xb67f7affd145f82940c202e53708ce7d7942e4d67c92f0608dc3eb60db73f838","0x1663019ebadffca4feff035c217a00fd7e2c5078db1002bc1b74802fee89f391","0x0709670ba11c61612fc55ec3d27cbcdc46e1dfeda4a839a27d45b977561a7845","0x54d34a2a1e0530a065f1825fc048a6bcb6859e1e167da1e681b91da6ec9d1863","0xaba82cad36907bbb28f2df5fa9a45f59119b78e4c72de05a05e64cca87b9069b","0x43e6de6e044992633e1f9b80880008858b6f4e974d0102b41561ee3ede5cac3f","0xded4540c08efd814d7690a60cd692606063b6fa388892fefad60fda9addb4c5a","0x9222dd63c07557cae10a0d726594954cc447ce53b3c647578df287450469fa86","0x1fe3eab03bc0e2bd6a36e2d827881b8c4867c63a01bd08a446cd064d645becc7","0x0b69a75b6230a80e4356e3ee682905617b37e421f155238efd545f62af5df4aa","0xe74d4a6fd33065cb847febf730c5b8956feaa0ceea5d429af75e31ec1e5e4ca6","0xa0de21b90b7a8ac722a08edf51bf3b53908750e1ad09d0a2362cc6f18ddb9d83","0x4aa3e56a632a9db36bad99b87949af1e953ed45d4bbd3f0564992ba97ce1b973","0x07ddb73177940a8243ba9f8a830a05afc88cf44887665a2cabf183f4a2b28f08","0x50467c61bb1fe73b2bfed2834bb532846f9e1d06dcca868fd2f37e01589f22ee","0x29cba98674d391bc2bbfdb112d8356dd49ba3c712888858eb0b0c60391df9bd3","0xa3c308c9c1242687d33db3d7f39e278ed7db898bfec802305c778c73b3f575ad","0xc3d85296d916cd4fe8422049df424e46180524614fe852a4acd7c6f7c0b7fe25","0x8ce8e1792efcbc3318696c5ebaa8c69b924558784c5febbc77542658c9557132","0xd89fac6bacfc611ea2083f183042a8e8161573d18a4f1e571a84a8434faabba0","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x72faf8660f304e96744c647dd353cb57de5df9af5ac69a2eaa8b1f1635700232","0x47eb8d4b25fa6f9bb50553a10d2702f96fb855a0d2d1ecb177fbb511ff4fd6b0","0xed7a43b6b48b9bf7092ac131d8ccc7452acae8381a73e83d426fecf42d1dae44","0xc525d1e083727eb941b230bd414983ac531efeb059a06a90c05baa53691c7f07","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xaa2a696f0e685bc8cdea25601516236b983a364a99772539da5f8d0544dddc90","0xc71893c2e738ed1249e616128d51eb04da14268675b29418695e39c2bb63c4b0","0x0b35e5d3fc402e1d5822eb9a3f490536e8c0afd4b1226de04a77c6cb5f56ddfc","0x1b771782bddbe268527a38eca98a0538e9539754200275b4137b6ea209478914","0x947a82b710d98db4dbdc74ef7f0d197f83870d8211c982b46758d984f7890090","0xd4edb99e43ce929a35b721e120d9b32a132b1585112b7af79e442990d21baeee","0x0c5bacbedb7494db16f5bafc0b5879a209a3778c2f89b9659ed05980dd494ae0","0x4a8d89a0e54821a84d1be1433cf5a91a6a041791d50f03f2287e91fd4e88f276","0x3cab9d331d55b27ec639dc0c4e769ffc17a9bc7fe5ebb61e856c97d0ad75c60b","0xb045a7a5f813b818bf2ed1d1f39dc6672dd1cf1d869e4f483230b40ebf269587","0xed430395997feabee4092f58f6f21f1512e523a9ce9829247fc8988c57ef58b6","0x1d0ff72f4fab8100428857841bddc9d2376048b9e88a5eaee802aac355d9840c","0x92689bfed877e08bbb9dc2ea77a37fd068a7ef3948549f0a524baabaaed9f441","0x21d346023d7247062316a5ba112e1528a4c38cea10843097d8f07fb5763a176c","0x83d7c8759fe9aafae9b91ef83da3c78c137fb027ac41fd93471049e3d4f9d359","0xf9ddaadae7b87fcd1587c5e7cc2179c35a0a0c9f8a77463ebe9d7335e01213fc","0x0ee6af248f1df26484336b3e34535d336ce43286d8b57fb78a124ed5e664793d","0xca91cef9e67101477d95ab08d899e7b590ec46c2e9fa85ce2afe7deb81a664d0","0xac34b34d69baf4488a7cb3492aa7ba6fbd0ee331277124949ae0580e7bf1abe7","0x4eb9da69d645d45710a9cfc28991d09722938648aaf1a06bb43ed3d909f6042b","0x1035462193fb7f9ce06f42080b86c9b3c53efc53a94381fcf50b666a3350f728","0x09dd6d8f9650eae579757e57bb9b06803819ef9c3292020de5c0be6f4cb8dd07","0x8c7415896ad247c2a2955bd99ac3b5be169e251d9a32ed44850f7ff4340c77d1","0x9322cbe4d2ef0f6c2dc4546e7f00ee15a5e075db9c86ad29d7e30d943ad3e099","0x334700837da1c5bbad7cbac535a0f506042e3b1d9f7adcd5ba784c7beb20f3a6","0x81d8978b6863f96735ff01f0d988ed773cae3d49bfc6200b6cee0641061e801a","0x9dbb6a0cfa98ace94c7adf51219dd63c367928c93bfe8111d2b321fd54b429ef","0x0ecb6f2d84a8638c3b1b0fc37b83a6e552f80f92137bd036d3edaae2502a56c9","0xd58c0b603c103ac4eab5e02fcf952f9b8ca3246da417f41aca90b894f6180a97","0x15515451b9bb8f7c3896c5f517e2874fa9c1d3022e22266862e340d50cf218da","0xff269d349d0461588ea762822923ba20e13717aa3037743c63ac1d500fa31cf8","0x607acefcffb0c2b48ea1ea2b73c0d289e3016dc6766fbdf0c8ee0d46944a1537","0xb30d8b2be1c6c2e9bc015c36a7823b23f08706e0ff9f573354d893d74a9354eb","0x4ca9f1864aff3528a2b8e6e74efbc827371cd64d9832dbc88e63e75c095f8cf5","0xbaf41053fcf37e9c534638409b8a81e34ffbc13e89d04fd109b4f1528abd4eec","0x2b1943550a5af9ee2d9c64da6eb6de2fbb95aeccdc7ee973202ee75565eda366","0x9406d19e5d9c212c951353f187098bef00cb01df377e8646809a073393e23842","0xbd515db9ddf564006f53a2f6a4eb5948372010280109373b6f141c93a335aa8d","0x176dd039bdf4ff8f2fb95f1f8b663c18807f3c3a5e1d8cdb5e117e74a6001ba4","0x4a5eede5f3721eb7b04b944eec2d0a4ad7c73b124d09871984957d22b153c5fa","0x2e1dd8fbfe468543a57a94ab28b42a9c2e62d9c837e1c310f961bba81bf4a36a","0xcf70f206b8b308844aa49f41a0c67e20d72976c15f437c5f70d4fbec0b0d1a8d","0x86a72338f807ae7ff111c65964a8f6a9de953bff89d6468d888390f43a7a24eb","0xf3bd7b7406ecdd6fb6e5717a4e9a79cfc9f88acdd527afbd89097f4f4b85dd2f","0x8aea347d41e73d736ea2a7fa65f20da14082196ff86262f4410f96ad4eaddead","0x00a5df94e7493e9bbf0857a2e68fa7ed1066c1fbeeb6685c692c263b45d8e075","0xa63ec2a2244ea5da4dfc7e68331669c053ddaa82711afac98a3712a2b551e936","0xbda0baf8be5b4ceaee8036eed84fd86e1916ab617a3363e3c5c6c5fded2367bb","0x8592ca95afd92484f0087c943821931148ac4a8f3a51f9d06de78c48dc58770f","0xf8d7938de0036d9ad45f760276c365b39a16581378b2894fa70eddb41ae2d43e","0xa61fb4294c44dacf37d11e8c4917ecae83c7e25e4dee7631cd097527eee46bcd","0x566f2f317934080275b7271c53c8df434e9a3fce111ba059791b654c58cc2f2f","0xf8b99d16fcd8e663ce6f2546bea847e46914b765c04e0a1c1b22a2a3a466608a","0x1504183d9f4e21a95b19bb12343591a13e5a91372acb0fa9e6f0b5fcbdc1541d","0xeb637470e324a72d8fa1b8ba4057b013a8f781509b509a4097821b7511136a93","0xf39c31c3f1a322a963b8fdc17734ff390dbc4c64b86e2621d0a43fe2664d517d","0x70945814762579ad40ddead0224dfaf193f802a44c637345958f351c37d1c485","0x9559988e698fe5c7e90738ac2e22f5bcfcc99bb204534bd0a5d8066a18afb77e","0x697fd68a21ab3cfa339310e65bec503d2b1ae3d93a4d26925d8455302328499c","0xf6a89c7e64062e34e9a8cfbb5b852db78216844fe48b1da098ae62b6684875cf","0x6340cfb3562efcafa1a33eb567b47505813e1d6fd29265c2fb2a60038f6ebc85","0xd92689f7b5557821b376ca4610a5badec02cc1c4f45e596de50ad9783eea65fe","0xd4e7576420f771f812a731886343f947865b147daa2db28b7492dd1fd4f09a9b","0x40266cf54a89922316a684bf1e48e94bf60f58e29ffe272a035a0e877b456a1e","0x2a070fcd79a2ad603062558173cc75f7c07e4ce771a215c75c4881e3ece6b00d","0xc40688fce31318e25de572cf7946310420fc8c33d483f86ef9b694b755bfd9ab","0x8d5f95f68fa8b45367c43222be8d0621609dcea57b9e91a3668db9a34f95b8a0","0xd659eb18488ef3802423dab9ad30a999a34d8a397d0232dc16ed42ab81829882","0xf917bf65d362627abe06c4d9996d11a81b78e35187faf8ce540ad41f1fb6a025","0xec0577d726edecb2af09b451b563f011db447ccceaf95b597f3b29c7cf63b886","0x9a0c224c31d754ab41d58df51e3c27060c8e1f8f1d41474fb2e04f796dbc9045","0x10cfafcc64dc9ebbc4871d9c65dc6a74aa7c7c61fa129816e6f9b3913d083531","0xdb5e1507fb8413fdcedc4bf47c8e44572e68ef227b99eeb931bfffe28f76b33c","0xebd93015d2d769b85ab4de94f514df3bd6ea3b0b60ad6f15e612548ccd188d76","0x659778595b2a19abff3525f7f1d89367322dfe11cd0e9c58ade2333379a306e0","0x7b06bf879029303a3fd6926fcbe81558242f0d4b91394fbc14a60566adecbb90","0xa0e9b5c4dfdcb71013a1af8d9ad34b081c39b78953620481ac9c560c98009822","0x3ad408a1491e26e7eab61eab465f55049ec5419d0d868239c509d2d084faa900","0xff8a6bc1524e18de9335efcf9b4a7a013fbbf5033d0e834c61805c712642d1ab","0x8adccc3ce9c0df85ee0eed8d4b1e425864207cf40efce016cd5e0c70e8d890b3","0xc1ec345f7110287584ddc1877ddfba1d918d1ff4f32a0ed182425a03bfc61c41","0x1efb485383b93beb1621eb14a00b4a2b264555226ec83950d55389d9f4bd5c51","0x8af29cfcb80a88c9db51dde67dabfb7f4bef29641c21c1421f57508a0c19a860","0xa9036301b035452599b0ea2579d85f6cd037405b25cb2ca2633e21e781563ec6","0x425e72d6f4961c9e16b27bdf15e3a735f5963429ac41f6ba083f976f2b70965c","0x1385fad870bcb6633d3fb32c439f7a2540a1468bf43c33cc7b19e45c8351262c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xfe41fedfd7416e5fc0e123217088ae06384fd9bed0d20addb9c87e528c7de9a2","0x93dfc747634b3a7ccfa337b5e5951b0f8a21612c68e95c6dee6d70562bbda972","0x0a49cb8cfbd47e3b771929e710c279373f817e2175423eb5c0758c07f8cc8f04","0x0efab3e77519f75bae9334e8e3c4817e93fe8de8845dc46d90c1b4715f4233aa","0xb65be225879a43056bb1f6e5c799f057dc3ca771932b738c70ec4e14bdcfd6d0","0x9137f81551604b53e6308db5fb7bce1516040a11108d04acf98cfa9b3904c4e9","0xc5a479b591d801b0084df3c5bbfa93a888c2f64288ffc5e229f9c2304c803fd3","0xa01b91b2ac630b712ef51caba6c4759aa70a4e7c50ffa18be0b18e5419b6446e","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x13f01c1bd2436d5e3a159b778fba33ac7b5f959d8081f82eaac4536354731477","0x7e3444386045c9d3751a4329852a896d2ea90c5ead24da2b4ead242cdd89a3c1","0x0dfd219a4e13f4b05e55751367906ca9315e80f9408021f70685ffa9bd8f0c70","0xe1f1223d608f889c467f6a259d8065a3f39ab79fa4739c4124d6f25247c5d904","0x1152e8c21d5ece341bf89addebaa2f7c3a4577e766678d9c778fdc96213512d2","0x60c48faa19b14b0e8bd55aaf60ce660d7de3ce7a14f0abaca99fc4d19c744008","0xafad493694aeed148fedce4c634958cb43a6f595a9b924492b416dd360e7b057","0x17e3aaf767eaabd0841afd0c3090b6505c9a16ed0091b05650637a8818f05b0b","0xbd7c36be09cee1a021f1825ec08ba380639e2233c28ead9ab999e7d7811d325c","0x41c077959fd11ed4eae437d7c0ebc0780d8d1115a3add575a5be35b133be5ce5","0x7cb14abf8ec1d5a53e681dd6d978d1e5cfc2bbf2402ef627a4e986fff0ce91ef","0x9efbc64f8e2ffd2b17f97f15791ff04a7c56a229a4bac8240302ec38bb2e6923","0xefc5a74e1f34fc039664a7e362a800f02ae5e260cc5ba5472e4b23983696d309","0x576fda07e94d7e103ef13bbce93789a0cb283178bde3f0f14861a3c3c16e2700","0xce34413a2762a859cbf8af7498756d0e0c52b23f1d2fa03abdfe22d282b56c91","0x01f5ab15463a4694b03fe54e28588e0be9cbf5b5ca14d245c783bd5b2b6c9758","0xdaa463cc8e2da2f2ab5a2c1ee8ffdfb291952d7db52132d02442b7dc746bb5c0","0x8fde72a3ed52a2f170ba0570a85c953f372d5454c8f441b5ade7a3a19e0412b3","0x1004a55f9eae0e25337ca19ab2983ebebaaf20e19aaecb30eb5b466c3d6e3c9c","0x40802a49f961420286f127d21c021f3ff5d6fed6efb955fa991115353a25fd2b","0xa3bb444bdf30775ae7acbd26cf3f5edce88311a547e899cb073fbb3cb0be807f","0x3b04e90b9512099e348b486f9b52312a6742422ccb696af3cd123b36c2f30a0d","0xa253340c6c6a853a63d85148f40fc79242df8f051ad53cd118dfafbdbbacbee1","0x5bda9fd76669f49fd7fe878503627336ca4b76e02dcb9b2ef7675b8dfdb8a05c","0xb9f3c95b5e75d8cfb38afee6bb1ab2df62aaa9d0cb89b18be5ce4ba9439a0922","0x35177c264532127395ee72af306a7b1026732d201c46c9b4c9671409e16a4c72","0x8cced1e6c82a8c3a9472b911332a2c17b198cc3a064ee37c8dcbd9be1e311079","0x219370a3d37b4b1e634f5a687b90335871277eaeb322cbed73d5d359d7c206c7","0xae2cec360d3ab0d55062bb1993fb702c75edd99776e1917d7b2fa7681b50585a","0x635fb9e04f5bc0d7aad08c5267974fc132fdaccbc4a2d3f07361ea800662bab8","0xabc27da99592a5fe0226c6e3bcf08431d19642b7ae4281ae1e62953d08be8a5f","0x718712d96080d4cb98ef4725c2e3e064462ea7bd1952c9ec00d0f930ccc986f9","0x75c9a19003264571db0c695d696e6c8e18bac6dba01cfb544864d0b306458d8f","0xc7b619b099e5e41a41474c779c8d84883be029f7ad0afa2afb7566190b5f11c4","0x66ab905a431e117b3f720e4582af27cc3e4201111bb71d9791d344fcb35b626d","0x3aff0be63473499519fcb87d8a1ca4e4b45dec35a4bbe5476f37befbb53c6d3e","0xa598177492151ab044c1f47884dc0f40fe0f43de52b1fc77cbf5996138ba681a","0x8ea4f1932e97cb8f9f6483ef522b658caa39be8d468076c78b96237173f8de31","0xfa3533ab1c401cadf384ced1586acd582ca219f6c01a97ade245a9f79a54d8e7","0x4f97be9efe24cf7c54a976fb50065c5fe9565c9d60ac436850c7f0470ea603fb","0x154c61100db3817bd8b896a3289752a0698617b3775fecf419a48596cee3c14d","0x2bac90c3edc58808b379f9efa007e2fc56bb251decfb1647574a76a279def824","0x9a51d8ef5cb3ca25faad34c5826ea18663aaee8ea4c784553465f02e93742a2d","0xa34f0761e2d50d6619cfcdf7c682967ee27a0ac6f1bfc86ddb53560bfa6aea5b","0x5973dd8e8e906cf2d82d3dcf9a1e39c68a596822e23ee64e3bdb2c9762f39334","0x65799340ab4e1f6894b58d90b777a0841a294cdb2ec1ffe945ad37cfc8083b6a","0xc08a27d4f680bb0a8ed9864ad9b82b686acd2d96ec8e796f982288cff9a583db","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xffea42b163c9781fcf6b84aca7ad60591e3b7be06ca7a3247cf9b8764f6364a3","0x20c7b098f08de581af52374ba37b7678770d507113eb7ef8ad51b09a73c925fa","0xf4fad7392d0e15ad1ea77bfcd12cb2db636483bbff23e335d81cf1e9b8cb213b","0xe2334c8b677409c70fda60ffea1de56e0e3e3a7d34931c70e3b65090a158db33","0xce5aae54827589e9dcd13ddc638fb907ff9a24f98531da52c10e675ac2a368f7","0xdde53730c225a15c968595e90160d247c85ca738881f09a0f88f8cc9a6323ad6","0x365717faf952bb9c855ccbeff6547e6ce65c7ec885c0faa4d9e02f455dc85585","0x523f438b9c943e7eb24f3887152b84ceca197294fb497446fae4b926e8c9c315","0xe4bec56c32009a9cc124954316d48ba5650f43c89a115e047023291847480af5","0x9dc9fb9be0fbe5740fe4e58417463ea980be7ba98fb7c5a9b7868714e3a22818","0xa40ec930f14811e32be6cfca3e917b158325d79f3075e099f0690d6d965f9752","0xaacc366655609e6fc4e5cf4a39ee2c3566c9ce4074d970626f63920d32baea6e","0xb2473605091c64adbeaed1684ece6978a9c5db336640918c0c8bbfae430677f0","0x84b9711bfbb83c959f926656d9c034ca9ddbf2b7606aa7a47832aa566270fc42","0x8c966921be17b51c98182c22972d4e12403ce2b4b703a94fddbe02f7562cdbce","0x61cca6acf429b31e58cb015a88a7dac95655512aedf661f4a6ef8d190c0e847f","0x2ca79b477a9a7eb3fdc70501a333c6e99acdecf9a7887eeb866faca4c868cfb9","0x4808d109308340523d27f827f4daeb9489fed4840412f309a31aaae6081e0688","0x99d626269907d05e79fe1c3d7357b15c8a3b13c9b75588528415d24fbc8d3b98","0x2cfdb8ef164423a83cecc61b9e788e663613eaca9d8b29f2693b8718c49a5172","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x9cc0d0a69981951144b1299ea46791764b67a9140bd2032f6ba42d0e494931ce","0x67ca3a4e875ac1fd80d87f0a6dcc431c8183a166fec75199933ff6eebc831937","0xecf52574a33c717da0d8ebf3cf545f4dc0e28ec03581dcd1329141ea1f98515a","0x8d48fb976e984bc41ecc71b054af5a39f4bb3ce148482c59fd7e47fe0e69cb7d","0xb3b6c35eac3b4d9a981d525881ca0e93108f533d9415ac1cd30e43781aece8dd","0x9615f66c6c4b7b89a91b9ccd617c43e657b62ffc153ed9306e13921c782954b9","0x83135bc1b2f25afff2196ac12deb9631e4a53861bfa172733933b6aef9b3b510","0x11eb998ac32d1ccf5f98c329c48d62697a2b285ab415ee9cb63e2292dff52d35","0x3266fd05373d77c2de50e63629025632338e1b288f62e61329e1ea4b6e43251d","0x1dc5055fbae045b43e86df13c95871b77f394df8bd89f4e51dac49d24c15b4ed","0x638d973eb3a293487238eb36fee337530f6248a47344dd9e929816c93292ea2f","0x2301c86b9269267e302ea67d33d5663df01606b5a6883eed75648aaf525d07c7","0xedc4cf47c658cb5c1fc79cc728febd452fa2a439498fa361e59f1e53970edbc6","0x45559f26be88942181a852f25e5a207edf22d6366816e334089f0eeabe63dfb2","0xfba6e136b58795e1a0b2b8992bfacd8bfdd659cab5a0220185b381659e743564","0xda9d41d21b51d7b80489c928baf3c5a7213df59126403cc48ba4f26aa26e616a","0x3e2ad63c202d66e95cef17e48b8fbb0cd8b787e338af6c7292fce79e96f5f486","0xca5630d00b1dfb5def41c46c996c76e6e8de6999ea346e310837beff324db854","0x174df64465a54d1f0d4fcac77363be82bde56fd7b3da6a63b243b91af13efec3","0xd577308671a8aa209a926718237815573f235186e4413ccb41ce79e6f655a1eb","0xc90c8d37efd4c6e02caae122afcbb7bc45686ffa7d71456568ed38b26be582ae","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xd01df4f0b1e57d24e30f5b322c242dc9e25b6c59c3ab70037ad10bf9f0e2388a","0x8dae1c66a58e867e14add94f0f72afcf3e0aa2b14bb9552feb4538e6f766126d","0xdf006aa753f8a8415f49b6ae49d5311eb35da4f32209591b59726bc0edfbc971","0x638e13aee489fe54bde8c1059d68ac99749424937a30c9b26184321fb6d58df2","0x4c651cacac789c76bff78ec354db7e95b50d44e86b8b353e4c66c633bb708636","0x0a7822f1f76732e6a2c115bbe7b0eedb7f107951ca6193c9fffdbfddbbf2a3dd","0xbf6df6b1d50e14ab54e5235df517a5277f6f5c7f76d29463dbd3406eab2451b0","0x50aee9255c969693c9e448d3db8132edf7523575d00fdc24edd8a0f21c0931a3","0x04f9642125308d0d36a98e9eefeac2fe86a99748a74a5346d03cd31e495ffd59","0x462622fbedf61de09135a009b7eef79661a4362f0c71080c2f0b0518f05615f9","0x2eb559576fb3b3f9fd345925b69c4c5e11c3dedcacf37ceb0b340503432f596c","0x02578a98c0e15459b67454f5583c270a8f1e2ab6d5fc7ef9d6d32cf92958cf49","0xe0634620926a2e5d886fc442a7162760c8a048e98c7ab5b928d06f04589fa19c","0x8ec6f0b9fdd37ff9ae1b91a8640593862f05927e921b52923701c2166ad1dd7f","0xa89f2911d9edda4bb8c2fb531c0f0b8bf3d4f18f26e5355be297a81b736d5d2b","0x9a90e29717496d51cdf6969fd9bd9856147a8a061012dc528918a9bdf805f565","0xb4c7a844341d41448d3565db666b29bef7c353896204908c447486313d7e292e","0x2b145e3e2942b6ed45c378dc8570584e83fbecfa7293b69e3d81ebf88d418d71","0xd28b387b5baa36ad298ef5e2c8fb541e736309b1063dfa9c28778cc16a0f525f","0xf9675c833cfb270dab6431d879bcdc7886e9c2a54fcc15e16aa0cc720d2811b2","0x0b5f0c2d50ec1cb20bd8a0ab7ced7186375dc29f032fda5f4b8a16bc5126eb49","0x068ae4b0456648fc008cb36a3543f98b1449c477f3dda9c96ba58f27c70984e3","0xd4ceb76507865be62da0c3fcb0ec00eff8791f20e6bcd38165ce32cd5366dea7","0x071c1a81c261494b92b717bfb5fe9326aa3509ad69007f68d81d96c3495ac97c","0xf4ca21ebd4d3a29e9ac6a9b177723932e73c20539b228f6a11760ab14d9738f8","0x00be10cafe036276369d489d2527ebd801f55e779eac3952631ec0437abbc17d","0x6a1098d7b00d048cbed32ed68279136e6cc293a98d619e3c72da23f6ad0d0297","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xb51219bf29e01105d4dfc7bdd6f47eacb05eecce9a3d7d0c3c95abca5d0622ce","0xe353e0826192b4420726457649f7d91e330ef06ceebcb1b02488a452e8b01390","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1cae9d97ce10e83bb4da678744fc311912184206d2105be992d865fc2240a532","0xc8a9a74f7ae93f8e836b19336ca0ebcc67d242e25ddb84f17a9f389ce0a54839","0x5ed1cc47437a551dd4eeb68061f1035e2700f6d4474a8f1b9bcf6d63d5f79fa1","0xbc89557560bce1e1e3efecff5175fa7855146cf2bef942a929519b39fb40386b","0xc88506ab1b6838ed2bf5f24fbdf456c6012776cff9d1fa753803f4ecc47816b3","0x853d42019d0b0ef00df08874290ccefea0734702387761bb962fd27588a72bf8","0xddc8147cb0a7287af00846443da4564b0e3c7695bde9d084b31fe4dbcd5b0264","0x39846c873c850f9fae770c0ef34f49751555fb642490dd98c45fd11474a8c974","0x7af858ea7e83736bb5c3c243d8670fbdb4d8028dbc3891004e9a7923c4f53dff","0xb84d7162a9973000735eaf910896d5a1d83e3db4bb7e88017cd9dadac2b2a9fb","0x68d9410ba59eb69fdef5d6f352dfca3c8ecdcbeaf3431f58f24632866140f8cc","0x3bddcae1723a8a1a76858f078ebc13a183ed0a7d3ccb726e3b7b49791ff765a4","0xcde9c00864c0fd80b5d6d384f3d2308b2d06f0ad5438df26b8a89965326888cd","0x2cc6280d6a788bb630c0df2cc0fb82163a497089d56398fb1d9b36fe1ae5c735","0x44b09fb10343e3efa46147fbc21224a6263ed22dea81c2de3e39d3eb7bcc78de","0x28441dd932325f1d50d21c25f2e3171bd909fd911f197423fc6b0f797fc8d4a4","0x9bcb13c8052e2954e0463926fe0ff4701877c86e8fecf41ef9859ca864d0fec0","0xa63e825bea13d03e97315b49e6a2678713d0d207d34606d6974e9671d4cbc3f3","0x597fa398e99b236cdd224dcf0b6536a7dc25d06a6498f7d3066b4e41628a21ed","0x4016ac038b1d7be4688bb61bbf54c37007c009a95ea4b3330562f106167278ca","0x1ae029e0c72911da886bf0214e37faa29bdb651351d7c9096b91054883695c34","0x59382b04fa9a4aa18cdc3b182b0cd858e36eb9bf296112a2aabe322556017ba5","0xf9314f00f3360ac91c4d6b9b0c83a8781d769a60c02e2195a3d6976187e64ef3","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x0e2ca134974a0dc8d86ca0267710293e329982bbf6babb142f07eefb06ac6a58","0x28498ef2d5644f72534f868cec1d1ea749a0a8df56542f7ba63b2c76e2a1eff5","0xbf73876d88835dc9cc73cb4b1ce445497d9279c0bf4c7ff35c9a404672502072","0x90d4231210c9b24be9093f25ef03cc675693e12b6ba5fae71534e35e39d3cd71","0xe972b7aebccb0ae7a938ddbeec3e227ab9d534f74ebaa543e10cfebc90f54b89","0x46a1787c9797261d1022b6c5ad2f98ce49602b121a237bf01a87d28118475c9f","0xf845b1e0ba618fd788f7017e85fb4fa29b2128ccb3bd85c5ba8605739c1d78c0","0x52423b91b6883cc8dbd4cf5c04f9eab15f1b142e086285c2b1057a58d3edece2","0x22487256d95e25ed03c78263814abff2a4d0f537f96ed6c54bc328433561d43f","0xbbe6bbbf9083aba2e283498435463f8e5d7a73a41a1239ffe50f0ad6bc17a934","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x7ee88d9a9fa653fb98a054e226f725da763206541130b8f51559bcce17a3acfb","0xe0fee7215e8c43f4c25ce84dc6d2eb9d0dec63e131f3f9e06adc3a9fddfba7ea","0xb166b62dbee0a168f8aa8ca6b20a935794e3e9e4ab91858d488cdbf220dda187","0xeb98ab6e9dcf49d9fb8c2e3ef140d2cdeae2b369131d30aa638b89650937fda0","0x0bdd44039305a7bb2ca0c97f4a2f5993baa2ee8a4121321d9f7941a725d1b611","0x3a03f9ff5b5835bc7bbfaa5b84d7c62f87368ada775f3c7724f6e23d403bb93c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x864f069c0fa0b86c2bbe0a4af7534aaa139c3df0a2ef32acbb8ccbb195cf5921","0xaa13c48b26126b719d227c9d1c8ba683d43b048a5d57a4e589bd2205cecc5c1c","0xc7ee065e67712e270ce7652969df0e5bb568657e2803c4a1debb1757f3f39706","0xad6b579548d34db048fbf80c4fdcd3c3487a1831f99807180ba8913c9e8bdd5e","0x0cf7c3bf20b68e057172fbb7d79cbe61024de3b5b10a3b2385118dfaa4f093f0","0x00609a63da8441178ad301a45ad5758001324e0c95a5c3a3caf3279def4835fa","0xc4daa5d2ec7eb1410339f21579baf3c06838cae23ea52704b53c32f0b922393e","0xef34588bcd2d1cb61ebe78ab263944899e41b53442479b079624fd828ba40363","0x9a709f675495045497973fb0045369920bb27c0ef6b32b37a85938b86ba7ca3c","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x748ad644ca2ed362e30f550cb91413ba07c566d2afd9a7ba683a6622b24a7f7c","0x63665819cc6c418365f04f7206f09458bb481025d190d77a37c010df00df1845","0xd2c134e5e9d5baeea73c9b1d20f32019a49ecb287a2a294c9e5ad53596a3bd3f","0x6b8248e715c2aea6fa291d0798e71017d100d90ff64acb9a5d74273a45b78ef2","0x1ba00c15c2c4211f532d6b157239cbdbd480ca699cab62ed0390d813b3c57f58","0x17b442ecfefa6ed81790e8aee3b0066a23fb0b725e1f33b28b5b4ad05709ae96","0xc39b0c395a1d1a45ef0adb8838e7ae5b3b98863fe36d46dc44f70575e8d43c67","0x9134cb6aebc62731ef6b5a56537c4b859580590bdc2360ec404114c218cc1570","0xe3e429e9a2fcaf69b58b95cec3e8d10365208dba30e2fa2e2118819e09bdbc9d","0x7dfd95acef5a91fc2163aafb84f1fc6be934c534b67a66a8af35483870486af2","0xc80660e7e6299286701b50511efbd14068c12a8d1f96881882d704dc92c51059","0xc30a457d012e51e02a01440e4948643d551348aa8c53745275653cd65580f9f0","0xbaf44e7c294cc5c43a30d4e21346dc2e0ee59e3e8f702987e952e8af3292d854","0x3fa188d7a6c35f6f1a4953ce0a39c9fb0f34981d425f104e97729a4694409f30","0x3c140aeb967c1affcd6a1763b9ce020f1d5c32adbefe681b3dcb5d50250091c5","0xbf930cd3cb36d715854fbe7f8d1b4348dae0f409c0a78f5e77e2b490f1031914","0x342e90ab9db6647b2a65a877bcdc5db3c5104d4bf7d68e3e778816151085c17f","0x3815c551210c05f4b4021e52d075e0f7be040c7e3f085723e091b165545abaf6","0x596cf2d485215a4b8d20aef01645afd35a5c65b5a54332f965ceccd453f58b79","0x849ca83a3fb9b4dc9ced612e681092086fb44c26581091a9d56e2fe860b92a7d","0x2d9f8ab1aee01cc81ead786261747ff48bfda35b1970e872e285f44a6be6ba07","0xbe79aeaa1ac2ec9b14f887100535600a40c55c92e717c5fd1b6e1f0d6402bd31","0x897bd12f2ab7a998da2788a1640d7558636ae92f1ec537a17f62a7a3d1cffaa3","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x7af60b0b2333a37aea60474e9f9cac3d47e1552c631ce7ba25b4d0ca19da6880","0x0c2085dc89308c3c0f742ec8355a3c701ab1bf4f17f658d076bc7261ef4cdab9","0x339d54d9083e512073596f6cea09166dc4c67eeb2fc4f08f405fb2d854b728f2","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x3bc0b2ec3ed0ea53a5260defe3918f2aa0576bd81597773e61beff7c325f3585","0x04535ccea69a31b85f86c784be2c3d90d830748f96b07446e271ac4af3fc49f2","0x9e35ec500c19834c0aa038efc48dc3a51c1818ecc5ecfe405bea197c8efed2ec","0xd4ccf215177b0b2804b8c48e08fdd91bcf97fcab82e2247c58234ec216458228","0x84c4bd06c457542d845c42f991046e8e00d6e4b9599a918aaa43525f3961df4d","0x9246c6eed34678a5ed81eafcf1975ee83c8184bfdc3dc837e02add987c2dfc1e","0x09ad8ec4196dd466ead179b5588d900e4fb14e1ca5d86760a7a213d5f0f5939d","0x6bb7461ab78e30c782b52d675b6d9994143f7084093e572dc82aad1d1bf225f8","0x2be9bcd9e5dce123c8d52f09dc63c5ffca69ea25797908652ee5711ce6f87b7e","0xa279a9fa86a058406fc88a59aa26c88eae3ea77f530a329f53cd0167072f9b25","0x59214e735b62e8c02466854d07de7f580e4a7cc1dba25301b90b937ad975b8c7","0x0e4f5d8f2bfc8bf459e2012232b2bd44595609dda8efad609b1c273515173dba","0xbaefea9a6252eff2a7c7149eeed929b1786abc47cdee367cbff9aa1a10b7a947","0x3f8863226063bdc38be1c251b3046ddade13e9f68793f181d80a73e6436eb765","0xfb33516a14a5dd26b75935776ca63583e99ff80e91a64658892654e9116a1826","0x235851c38ded9162ae6f61d98075c9648ca29306c0ab9cf85c553c2a7c92381c","0x5e0c3f3dd9ca01c1fdcca5a6509e14f44c0f94353ed9dcfa7c98d68a05a98a14","0xe0c50e513bcde99ccb272efee254c7337c609acf68b50a3626a5073c159ef7b3","0x259d5dd24f45227d751e3bb627e95a27a8598fd731c91266fcedb8a3e05f8825","0x034b6e4925090942f9b2a6ccfbe7b8c21afa171aa3861261d74f7f243a621c32","0x0491686aa0fdc4243b172b1ca479e00e3a776dd9b2788e0e92db238029802e0a","0x029eec68977a08531a2e941c3fdef8d64757c1a2c28f34ae36601449b4fa09c9","0x945ddfaa5bf6d8b550f1003dc09c383405c5bca982fa597f80da1ba0142d8aab","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x5fe0aa5b5a08b6223a608a6ab025168d4eef13d00bdd759ca2965ddcef9ea752","0xb55230432e0686b6ca2b652c3bdec1a991627b4d21eae5f29eefc8c3d75b7eff","0xc4e64457cf1df5423e9a67e686542efb87ba2e2a71de850c538b0d4f7a9195d6","0xaf69f78286225bda7049222b89edcc8d50f16cef946113f4d5c9a151272b2de0","0xbab3a69c57bdbf46ccf89ef8a18cb439b39a94e607e3de0541a2bc266971b258","0x56d2f1dd1b7df6a9809b89488c62094e1d19966109726010601de2ac049696e2","0xc66cd90d77bbbf1ea601d7d07b904013a44f9b4ce4b2ce432855baae7f42a91f","0x2c8b626f84ec4c1888fc08ba385f6df363cd507e34dde2d31e5d9a842a10da7c","0xb3f20b70da0b2fb713cb3fa9fd1863f6f25074004e53439c01aa9f16d0288342","0x9774a3eaee3d080c0a5208c61ca8e5cad172d05dee32c261c77f6c8675fadae6","0x4fde600e51e4c156eab6e79db53b1357ccd1d7408c4e71c283146fe8a90688ef","0x4836755231d2d42a9d274a4874092aeb4fe0228cce0e171da9a4a9f05941d680","0xd342e2a55a8be38ef0ec658550776e4c3d046b5925eb6d6bae47f04e5c3dec0e","0x96000f03aab163aa1ce294c7fa347ad469452b2519dff9c13c9134f6fbb4eaac","0xfe679e4540b6c1b0bc82ef5ff79c5cf82c2ff82b9f1b9713e01a4cbd1132ea44","0x1abb51fa313383b59fadb64a378649eac5f269efb6f0bab0d30fff8c2b3467c7","0x3e559fe794120c28865b66f79d020838c216af9843f3c1e336acd01d00facf40","0x0fbcf7a9304a33f9be55245badf03a3ce4fec149ccc1ec72aaf8f3b323a4a527","0x9a01a0f90456bd29337e297a9b5bea3d2c55d12875059509b58168bb09d16f4a","0xf0d58001c216569953b173af6229c4c0497f58eeb786e0b0c505058d40c0bfb1","0x431c6e402be2244b6e07ba3b5d50286138806900d882fa3f774f39564b1d3128","0x640463519b23b9529d6f13c5dc07b757ba30da53ace7a486cdd7d4baef2541be","0x2740c2054819c0dd540bc4209c369967a729eb0df20c241c49fbbb5cbe18cd46","0x629ba085f5ed80515a29aa4276a0a297032d3c96a88ae5e15b343538291a0cc4","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xf6501ccaf0fedfad6f93ad05557a6a402ef153c0d9d25395240175955b5ef195","0xc5eda0aafbc0ef758f001b17301bf64912593ba33e661a86762275fd2fc66e9e","0xd044eac034fe10890567684d00160977086bf3e941f331a092780eaac0718722","0x3a08a073f4f0eeb8abce5a1deeaa21ec8fbb89836019b334da75e34bf45b0974","0xe26b51f87eb7890328580ea8f04e36e5afb0f3f6be80f2fc900918d8f5087291","0x1e9114faaab461f4fa6a7879de39e86d3c76cecb53845f77fcbcf5aa4603ada4","0x13fa839d04da36cbf4d9ead820674db9401842635a20da6a36b64efdc207d456","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x4c88d8b70c9dcd07778b9a6eb5d101194ede3d4cc0cf1f72e89b8e510c7c745d","0x580d95cb49b984194dc5b5a3e4d47d5d20a47e568e05c91cc8a5db864753bec5","0xee2a8ccb8780f1a362d31a1e1053267fb65a02391f0fc50e958800141a6e5366","0x611c32375be273b3289f5313418e1f6e1871fdf619a91338868eaa057d98acfe","0x8d992ae2b6a1acb098efdba17385d817a6b2c566bfb144e502c253b9d3d97881","0x1f850c9ccb9a11d1cb3bd8706d7519baa5688a9ec6dc98ea06580be6d792e826","0x52af15e98d3f5ae0c0355cd45e88428de6f306dd092e428d8b258be413c4a4d0","0x9d12134e705c3d8bbd7a9437c8b8a869e17c6bd691fe79df69baef54d0a83660","0xe2ab568f1c9bc502395f43ba2abd3fb8bec82e3f9f232dd13d90d313c27155ad","0xdbcbf22ca53d69023d1c357b0cd7706c9d1274de6e5ee28a7ff4f529a8a9abd9","0x5c017fec8cbfd33d8c81065301ddd56f138c5633e1d3d55fc676522aff2ea288","0xc3db595d6f579a3f20d4e3281dd21323ed29090d0a1904f9267085217cf9a738","0xee9a1906b41e9e4624fb4865cdf90c9592350cae7b6891e684c9195626580990","0xce6c4ea789ca59066998c5d435b5217f866f0b50ea3a7c3a7bebbcd130eb4f46","0x93533b286c785710826bd7f91359039f8ebc33bdec044cfed754fc76945e7473","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xd12e78be62b27c4713ff60371819835d78641da3791039337cb2bc2060b3ff7e","0x9a3b3ff2a672b722bc24988b9f2dda64426d3279710d754af44c176e77be8d5d","0x5b7e0249f9caf1afb327a925921aa6e073de21a0f8f52ed3a631017037d39405","0xf7773a291feef285bfaa27d11edda3454bfe51fb1e058ff3a5f19eec81c196c4","0xc5003265ace4bfaa688cf295db18a066b119f158b7213484c7c743ca0dd9c48e","0x1970fe7c31b3f56351bbfcf0fcaeed509bb3b025165a93c9c5e796be35c3bd8c","0x962daf77542f7065d810d86db33f88cd3e95c084bd357275c54cecde4f3bdb7f","0x389128484670c338861947712a74acbf8b06bec718924adc4ff50eb6a5ebb6df","0x47c477afe2f2951653f32bef5aa9f617e13185e1ef90ee8012490538759f2a26","0xf3bc3eb393a3556133e411638008742a3fbfab39f8d5b7a18ee42e93453ffd30","0x89c69ea134c4a0d921cd634f1080b31c9bc7e0fa4b35afc0368a1b9d1293ddff","0x2e2873afeacc1b707fb62e319f94b8b76a701b18a580850c2d301aa4c7e95b3c","0x8281fd546b829e8ee8e60d7fc48133af6d673d09a7f6ffbd7157de219d0709ac","0xa40977f8eb3ad4d02d52493a6f836b72e2664d3571e164a16ea41d08c752dc28","0x2349d7af386e8b9783d56e413e153a67cd7bcb7b1c1e118e3893cf2b7ef149e1","0x2c2901753ceefd31d10f700dae0a27008616cbcb2a0fcd0d123505db1418e0ca","0xe29de3efdd5e51c749be4d62030f27a0e7dd791452d35cd27b2e136da07847bd","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xc2daae48251384e3b3f0d14dabdad05f485a09551006acc5b2b2aeb7fbfc0eb5","0x4abdbd9cc68b4e2e8e8d9bcf04dcd90fc01e1c715d67f2f385bcb6d6d6b45e55","0x66709b3c7f7e1c09558c2fc1cbe27b060dc7ecb68858bfc0041a7b22851a11b9","0x3356622526cd52e3af973322fcdbdb0eba637dc095b3e209017934e7c1c3d815","0xa05ae077eba4c1c8db61ed78fb6bae192eda29aabc2cb8093fa75f8c3ada2654","0x3caf8e1d2c09a8986778add0170c00936f30ff490254dca83906a1d0fd76810e","0xcb8064dcaeac44baae9f70ef659b318fcd3e9d4bc02cab0794fbe3914de0bd16","0x6d6ed59349bb4714d8de7860949febd8c352ca21763d2b6e56f03e3deba305c0","0x3f586fc6b7ba0253ea8ee634d63d13cdcb939915dc3e1c0ed4e717ddec843900","0x162d4a24fca0a6305536e30eb7239dab220a2de9f98368c1111413df13ddf608","0x2943a929cee6d374ba9c0e73fad56fc4d8cd6f36eb890e3c949dbe34067e7616","0x5936a74167c5ab7bcd00b14146d6420e853e208a3e0517552094182a772f812a","0x9b6a2e29b5a7abfaa0b1115e42dcb38ad7c16310100fc7507e4dd84ec57b4888","0x10cf768e7d84f9fb0e0f0b02c0077b7d4db40e6fc913bf9773660e9a7cf04c88","0x61d8e38bb8616640d4ec1071fd92cdccba8ef3d7db091d454a52c9b34a3434fe","0xebbc5ae325f1cfe92033efe587a240d826331190a29242bfb8ba496ff7fcd90e","0xfb05bb1ba8ac3e19d0e468aee4148fe2c45b1a889e2c7ab3e0ba8d9865b3a3b8","0x8b24734d93f18850cd7be7993b4c154317254da061cd3d8d521e241315560055","0x83699072acaa244beefaa0730b80103a35856cea0e1a064c7abb83847b626d90","0x33aed3626b1aa2c16a5996a0785c7583bed61730ff54243bb790aa85d87356d4","0x7e6696b73a2869b1d1796a3bbea5cba9c32d66d6030e3f8bc99615dedad94d65","0x89d4fca3cf2b534eaf3ad27f0e32f7afc312b91243537063a7b5accab3183d65","0x4804d2391ab8d2d51e0f080972c30e5eb416ec79053d753fb50e9653e051dd33","0xb16142beab8a230ab89b477490c4e24d6d65122815f9e08304d33a16f4083881","0x58c4b178f335db43059a93f3b4d2828099bdd8827f41d46477ae2ade9176dae8","0x81cbb252dd5ef6ded0ca36485071721eb2c30a6dc5e3f928a4befa9b844148b3","0xb4057a955a04b9f46fdcdf0a5b8f52a8f70c9b488ce3650a646155a73b847fb9","0x743f2f27321388078e992dd57e71bf13f1f068a024f657094a728171e82f28ba","0x0a38080a3419fa3b61c2e9596d8b43469e43164ffdb6e0cdd576105151615440","0x1ae9be1a489e99eb3026c1875534f436d20c7d9fcf2c72c75d711abdeb7693da","0x286d284351d4ec5b1f56d1405c0f2bad1f31832acf69c5176d3d80d3fccc7989","0x0a5da5aeab09246d7f2f5609039656ac8441a38d81db326f086b62a4405f10bb","0x46203ae8b3ba20022405566f84897e9d2f5254bc27b753d2cee64cd37def637d","0x83a7a5d881b0c96d9416f6a075c8656ec0a464cb068990361be56f1d74c839d0","0x69e1dc5ce230f9b2c9963b5a12759d6456aed7a3ca74129c8c1e4e435c4a36e2","0x0a847eba3f74ae0558707821fdbb066fefa77fa2dbb88f00354e1b8497eac0fc","0x923d78c7f1f2ec6eae66f2d5c8e956e4c129a6f652eed112038b232bac4b8d22","0x16f9284110b500db4435f432ec69a8deacb7d1c49cfbdb7b9f8fce38d6081356","0x43d551c0cb9976c54f45d8c29d645a38431bc8bb9cf854268cfb832e1a5b7c50","0x124cb81126e6335d4465b07a8283a6587bc0a554e2083b7f379ec08161c8cd1b","0xf032c2a4bac41ad098a6e9178f1268b88dd452ce2d41a619dadd92c2f9a3835b","0x7030a2b96d0f7fc9e17351bb8dd0f3ec117756e935c3a836ab049e580755eb39","0x2ea22426583f29bb0dd0ee65b431f4cd924f64057202fe853e3bcb73437e5f94","0x7f71d5e1b0d942f08e94798f90e8f6d2c7a30399744057cb2fdb3ab9b0f37dcb","0x37c20802e8eb7e569156da4345806015f2171f7ba424f116de89f5ec41bd480a","0x159dcdc3106b251298e541e29b9c2805f7bb1a82dfce72d16838c82c29708c5f","0xdf2df6eff4819db1e62931ecc9484d415f7c7041436f76467d52f1e7700d53be","0x226c94a2e0028caf7446dc6c095157595c441f4f9617c8a89c4f9e2beecdd69c","0x12468e22ebb76c4e482273327f50937a500ec5372db8651a01e0b2b8717f3bf8","0x30e13ab5b6a9f59e6c24645d7c91d38fa12803ca2f2b541b858a7f1f89cf76f7","0xb15c1bfb3724c119b40a0b7916d0dc0d2ee8f10ab958018c1b3280d8fe23036c","0xe0b003f8dac706281fc34fe59fec0934b8156b02815ca4ea25e87eab231b104f","0xbcfe6def46fd7e56554808449bf05a173c7d55e85d4c8136990db2e613841c35","0x1cac8370de2e68557bd5dc47e21c501946969403439edb897669392b97b243a5","0xb3d524a7f519cc1f0b7dbc41e1f7f7a1f38bb541da52e7d0825e1d7158e38ea4","0x16b5b328b84bcd69ad4a8feefae60f8ded7f7be9d4a36695dc033f89c936035a","0x865ca070d9b1104b3673b3b1514a424cf7a417a200d155eb5170e0c6a1515bbc","0x09debc693e216e816423bd496217503b3c57f5fda766b3d371781816f60b0f50","0x7c6b86726658329e97c03691abb1ae6eed180279b1a8d0fdb3cfc985fa81083d","0x4b111622a100d3148106688255e7a308c897255ff873e30f277ff71123f804e9","0xca69daec66e69381fcee933e06344989f098830211931077ef466ae0134e7ea8","0xd23114e7a9f6f6a2e10461b5d79adc55a07661d0f5708615780bf00a62c92809","0xa560304f00b16400bae46d4fb5deff46d48b65fd231fc05c9505553a5dbd542c","0x3c0cb73c969507dd7a7a57425abcc46db3feef73c96565726f404c24b53b8321","0x54f7db1d0e6119eb05701ea25a6e719197b8ec83ce122d3e730e1c1149b1a92e","0xc2692ba50325625b3f4667b47c66da5b1f35a839ab595b6e58947d2a95bd9aea","0x2dac9f8a4d6a730939f052d57c1c087917a085c9278af9ad6ab20657b7e31391","0x9152e102de4d5e0eb885f6a56d0070b2acffac99dee560aaf741f6411e933003","0x9c8ef9d2ea193718ae9aab63324bbd157ea694029a046c6a65d187c9752b0751","0xbe36c8514b3440238c9bb5629917bb01115afb81973efbb0539f5683d3fa4991","0xcff39e9b2d3464cc999d1c1b93ca1b04334014bf2206fd1841091a87d06fba7e","0x47c6040878f57b8ebc242eac67d1dd0c02e800b3b9a1ea86848bad67a8598769","0x2ca0947fb8ce1d082dd810a6e9111f4cbf5ee75b33d049a3e9bdd79bd6e9d1bc","0x69300477c4d9f37dbf319c076e5a8deaff98445e59019bbd22eb30f01379e222","0xad5fd1f0723b437473f0039c13f57df8a076fc8651060d669766646d0644c7f0","0xfb4f014b130318eb1004f6688d9ed11163a7b7a8b863896ea40e939fdbac29af","0xe4b48ec418bbc578a6484cbe4f09c1c9a8857cd9110defb8646d33e191df0bee","0x95e9ddb707dd5ea353d313d13aaf20dabe5914861c093b0003655ddb812c5134","0x77c41d28a2f76631b6be0da3bb362f7c77bed0787ef257356843b04cb793635d","0x2bcf0c05f8006d02215bd5af146ac755272de2a0766a85628a9e58505c3988f9","0x347a3a2ae8394c05ff2b733172afaefa6ea413c0decd544ee98ca01f5f9b6edf","0x6bfd808f126b15143db3493f5c99d8cb38288e0d268e6d5ab014c0d9df07fc66","0xb3285b8af7b2cfb604cca9b8681ffbf10524bfe0955f00409394872d9272ff00","0x48cc1fbc0b2e90ed12f637c78bd5ce1bc032f5aa3f3c0fd2c7477b5b9e2489f6","0x8ebed850c2f69dc1e83b322aba44bd84201b164f27c301aad9db5110f3161205","0xb97b90cf0d348de9b94eb607e172d6f7ea691d1558a2762962ff811024eb6bcf","0x4f6f199641d46a724ae27ba8ddf931d1153fe0be7dc8021d4ad63decabc2a9fa","0xcc054234f564935cc83b608fdaedb268d32707891e4b39b479d3c8d0fdaa56f5","0x3120581bdcfb3f4ae8cc133c9e92e792f42ee6cb949c448bb37d313ee2703e64","0x68e88de4ea7f6f15ab71538a762f0888e73fdeca52939699bb88554dfdae930b","0x54ede0c1a640a08b464945b43f366ca6f3dd3166d80deaecf2f2a6355d9de11c","0x66c5cb562822d3d99f37542304046ec04ff8298d27cfa92e18eba327adc4d821","0x85c0b690f1dedbb0eed754668a1c2f66120d305198e89e1f8dea768cebeaa2be","0x8c6746662aa0073b612477e030747858e73814630632b86133781c109a6768d9","0xf7dd8aa13fc41a666694249833d9b348312dc21763539904141348e74f473578","0x47175e1dbd13d56ceee81671104f517a6e5a3f950887b09fd0471aeaf92982c9","0x59773942f9a1effe59f267c60a2acc9df42c06ebfadfd4d0b26397769f2c93d6","0x9ae1e3c5ea689ebb100971c3e881c00c3fc88edf5a812ebcb06958de2a47d382","0x4abcc2fa3490d4c4d172a8c0c131f35bea754137a2e0e765e7e64f6073e54a96","0xc20b77980d6b85f16d7908a3e159ba42a64c86150045cf12f0a12d644589d728","0x22bc81e9a131b411ef94c593494937552d412ba72821e32b00936297f7df1134","0x80292d454aa391be33a82a36e6798480bfd9de4f583632b89483718f6a0c9a9b","0xa3eec11ec18012c1668f830dd645238430ccc881d752edc0e5343e5597731cdc","0xa82effbba1f9116dc4c78e4b7659c22c0bc715f3eea7611c46cd76d9ac368e39","0x8d8ce01a06e90d55694f788ecaf7d717c8bf8f90dc2394d46365abfbbd4ded3c","0xcd895333cc738ca4a5308c4692ea0dee3c30e13a6562849666ac86833197ca13","0xa7e11058250b01e8018bf2ed414c25a5b527a7040607f02c5e5ea1cb769391fd","0x9ba2429e19494103b2f5a1a8b83275b7019c953b66a73df0f232ff4d50bd54e6","0xad571bd32382b00d203491c2abc5869f1d480c537d63b8ee3f880852dab02c56","0x433a3d8c033c2ec8209e7c7cdb6b2b989ed45c3087ce9bea4a9112e000072388","0x8adebea35ab312596909c4a6fa0f8da9042b90c2a144db12daa5c87988583c85","0x10279a98b304badbed19eee10289fbf851dd25f9ed4b11ba510987b8b492fa41","0x90050f2f08cc39bbb1d02b1860b01d100e5ddad5cd7685729fee164d9ea5a9fb","0x3d53c9940d372e2311c0f228e08658db4405195cdc5e1bff31bc41b9b32f74fb","0xe1dee870eb1a9ca10d7d74ce448a4aad5d9ab7232de8a73a397d0d3b0d55f4ee","0x24e2194c4aa206f4cac6a69a425c6e92d47bea52094928888db1903898fb73cd","0x09f188dc3f46e06afde98f0bd8521040e006f8c91603dd63ea0e7d083e66f95e","0xf2a8ab9d571024d8ca8eb0c69452dbe954d9390d9479ce2410b9d259510bb79c","0x3e515ba0cb795113b99c56ee217fc886b6bb662f3bdb475cb26367e92137b99d","0x736edd7dadd5a85c3964b970d7283ae6fc14682f502e4bbefd43e3422184b493","0x5570f808ccd05cfb896679e4522520ee64b425adb30cd59471f5561b21bd715e","0x845ff32ac3821836a69b49b58e955e1d293944a6d5b0564ef453173e4ee1908a","0xddcd911a768ca4ab43f2e1f35bab04c17c33cfaaf46a24ad9edcff324af2efbe","0x75b996cd62e81ba0ebc78f077fb0402b6e5c4a9b8898449eed624ed58d8d269b","0xb05d4cdaf858ffca32156b25b624bc005113de710f06be93d8bc07c8406f395a","0x9b1b1a490f5028245bf8dfb245c03741ac92fe60c217ec91be8ea51e5a13ee08","0x328dfa27dc2693c266f4858716e513f7911caf7a8d144903c0bccf8799d20083","0x08acfd284804e3995016f5ec45ec548aa5da74c920ba530f2a5aee10a2272114","0x5208f5938bb46ef6277b6ac0a01cd51d7e5f6a98baffe025a675201add710bbe","0x7c04629888d5d78aceb956705b44087c800efdc17e8b94fc13afb32040191f6d","0x297834110cdd382fd9cd4d45459e2abedbc74a7672485cbb9220cff43e8beaa9","0x8d965b53386b7ae5a877faed813128aab718a95753aa4c74847b287c56411f69","0xaa372a7c27815fc1e60b84b59e9ec6507ac83a7451a7eb82589e5dc3c2383c87","0x08698eb62954ab41630ee3f94e4aef1e5155e406a2d36654defc499f8a465523","0x71459805e2ee30a5c45475e3c8b80ad86e87712abfe95477d23780b7885da8ff","0x5f5b5294f306fbb646a4f07b1eedb9063d7ca7a809b10ad02f290d4c6f5193c1","0x84c5ddfc74911468cc564a414d2edb30e8db08ee237b76d431d3d3ad9f09cf4c","0x2322678d634041cbab6e20139a985adb8314eb8af5bcb7ae7b1ad390eb57e5c0","0xdee5a698b875f8aba9e5f56ba449e26566b53bb73bbfd4677a43a19f30688e29","0xa24b749b5a27c6efc57053b7ac414bbd89e091415ce184332c95664c7f3cb2b3","0xb1d8d6b147b6aaa777e3de542367176156707895a8adc905440e9c6b6b7a944c","0x75d43b59699423d5a5adab1ba35c6225db803afe779d95a393ab16739a782f09","0x03117e787a4e0571e425705fcb7776e460a42e36a47881d5d28041cc454123df","0x98d75d0ed3702c7c0541866efe68f4c8b6a74900ae566f5cdf34e704c4bcc14e","0x3a7961c9cc7ea9ebadfedf7dd7c683002ac90f5b020b6204f9bfc6e74d541fc3","0x7a60c13c13773938ef1b4a1b83fea70a94d730f44ee56f7d0829dca5f46ef2de","0x1368c1fcb745c02d3c35083b2b9fe2d3ea9ab69e7632113a80165bc9bc961333","0x8f959546435bf38c80a0f2ac63e96356ae4c793561bcfa460e8e3fc35c5b41d8","0x2b65bb02d687782859dc9b17fe9861bde378f8b55cb00ade09d5f47ff8f442ae","0xaf14bdd99eb1331517982005909962aa47a3eeda30a3a4cb9188eded64bf22ff","0xae6475993b8b369e8566309d4279a0dfd7dc57e808d8ad9d671e2910012a25ca","0x7d272602088fe64d6538507b3e8b0d215667ed2e33a1761432a4b6b2f2ed8f6f","0xd4566e338d968cc880795049f45ea7cb988e50011e53cf69b0b9404da3a3c07c","0x050520508eec710bfb21be32e2eb1ba4c9a2ec5fd5883bbf5929a9abe9edc4d1","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xdd40c571dfadcec31c5097525c51bf8e7affa9c7ca8ac83030d41fe3a00d98da","0x6b4f878c6747eb63b7df28f43f5f043ebe43e13f56d93a0253ac6c8cb29a3483","0xb057d35ec1c47c0c6a59d08c7212198adafd67a1f6778b7019949d5faccac392","0x2b2a79a99253e8f559f4c46529d766e9a9dad4f927273c2afd1a3577e63309d2","0x0fd6d4b0e37d3426a8737e9487f5adeb3507915cbf58651a00c3f1cb86a866c0","0x567c48bbfc089d00768a6251ab1928331c0329b6ceaea54613780b2dd875ed28","0x4d0fd663e8b293da1c11c3365cab42c14c1fc71b7ce68e1a8518f7ace97b60ef","0xcf6128c0f6ef13c334d6f669e6a7f07f6197d745855043518029401d0a0d6606","0xa0b82e91af9cf3587e25c95f26b81aa8d7b55354374df1f9d2c43ef51d916155","0xee1efae95825ccfb8ce375229dfc5d94f1594bbc69de552e6eab57c409f275fa","0xa0b50351953115e434446be81c72b0c8de2e0c5a0ab014cd7d21ba69459422de","0xa613a51d815f10d74c4c6b2584e6926aa15b324cd818b5cdf5bd2e84ceb76bf4","0xfa4a8ab97e266875845367b1755f875d102a80c65f7dc8a346f8e0eef673dfcb","0x9fa72a38e313512378ecc6b4380c7d0373ff0d31d2142553bd6cef6eb8cbfc65","0x2e64a74b8ed42a201285f0869b8e9fcac34e4d1b7d9029690a98d9ee1ebc4ae6","0x5515bc07e468484103a87e6b1230a815c30bb69c25a1095a5d31d956e672590a","0x7c57553b0cae3963f9347435f1743e74e4e7b95e766f385c7160836e7c0ba8a7","0x1a335a8592b72f0a779f9dd14d7e77be9b8139b2d0782b4b8838d2b26534dc1d","0x170fa9eaef8ec9f09f108220492b0ed4dad5caea7b9a40098ea409bdeeac9ec7","0x38a226647e025d03d7f061784628d7c0bfd2bb19940609b7acae3e467e92a1a0","0xb322c789bc20dc0d79a695a9c987dfdfc3d603f75a628eec8895a2911010d113","0x9855f4297ec96c9385584c87715c7b0788b968a75a6a2684d48d83d1186f9de8","0x95548674c0b1e7a1d367f8ca21ef952a2905757f3313f5b781a57e76fb7aa184","0x92d977d0a9b6a9de16dc55371623eaea887e8a9cdb5e82b988214af852006f9a","0x217880d898c6ed5ce85c8359b77e426d6547c07135b232e5023e36ecae68cfdf","0x57d6771b6098129284ec5cf2eabd2645a6a2bba41e1c4131863134ef91022860","0x0513d460342b3ad68e016bc90d3250eadb4554d59c6cb2a5c9de7013ab69d582","0x9dc1dd78455ff6f4feb58781b842380669673d54715a13d0bf033293afadfb0f","0x754f5db63a2676ae1178e2fa81832df1885966ce4ce32739598be135cdd8aa6e","0x42349be7896548a874c7a39d55ab2184a2697a43886982500320618f8957a494","0xf5fdacb67e7fc07f878f7f94129502d1b1ff8fd258616805f155f3baee7ec267","0x0bd31038ef48291895d7332376300311624c273795997ee5428ad2b6e23bb79d","0x3a9550abb8659e35a843e36f8cb4b5787f1b4f837d4a7c4214219ff56cb4776e","0xe5f2f4d7ef915bb2aecc0cec10dde414a68b62a78824871a9c30240cbf7e20e2","0x4eb808762c19342cd92c229e6177091757fd7a6cb319bae82d176d03097a09be","0x17bce92618c714f8a47ea7f55213f24ca210eab82d0497fae558d28248299cca","0x3bdfc1dfde7741a0431cd188a7a9a9b855a1974b0e36384a1e949261666d94ee","0x408744359769ae6d4ca9580b959e43ef1e7bea33bbed5f39afd2ba6ae2a506c1","0xecde7914cbc9da89f1c8e0e614efeec75a5afd5b4a783a88580d1d4a2d768906","0x098c8b7bdfb651b416fe4cb19f4f1a30a57e00f83addda09850b7b212d9a4ef6","0xd0947c8d394a6027ed55220e32453b489ab0c39df14a43fc10b8968387d521ac","0xb2f14fcfe00fbee69dddb55d9d7c03aff7bee20ad0c4888ed320aadf21dd3e44","0x0f93fb68e4a4d35029c2e6e37e8fbaf0fcf7abde224b7fc389f65504b99f67c7","0x22c13a36b93394ece7661a1f75ca51e60c6816e05694bd4a4e6323e6a1db1c05","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xa82f8f6c958193d7289ca0c3250ae50a25d878f38631027e7c10e2804faae1c9","0xb6d95983488b9bdca7d72c530c85014667a781dedc42896c5cd748e22bb3bf2d","0x5b148b6a7dbda11ade8127e0dd5c018f6d96d22db378997bbc2bc6da244eb632","0xae7c2aa4fa74df0312437ae2e14b451c39e9c5fb19bcdc686e10a918ab10a831","0x3a5c88255bbb208d5e2f1bb75e933b63b4155445b4b68f1fb0a87b5f8ff8b2ee","0xf39be90df1380d738deef2f36616d604c23f4e665ca34a36593604b3ea23a08a","0x7da98b47b8f6a7ee012df836f61fcb1cee9264735aacf93a74a39c3f3e3d6021","0x9561c901e046dc2696f2511d0034be0b32c032284ab8fdee47cfddcfa6931454","0xea4d2c57e6b4c09ad5099b64fbf2d477cec37d2cb367d1626c7485325762ce81","0x768dda7da806ad37eaebee7b7c0134572aa2ce7103406a9a71f48de759284faf","0xbc1bfc80aa92d8f5edba8c44643ffe975868edbf40e2a692544f02c59559b18f","0x8fc7d3e0d4adf17cf9fcd566bbfe2821ba1490bc63142bfbf21b038fda562532","0xf7fd882955773e18f1ecb9a233c3237fdad1cea120eabe90b4f68ab03ef54af8","0xe14b5626f8ee15503a39f5096ef038ca2e0dde282ae82b9956d297fc3dfd79cc","0xd0b5f3dc60d761239a7cf49f68b6e33147cea58aad9ccb75b0bf70df4aa541fd","0x4137fe1caa71a1f553b7ea3e8a22e70a5bb93f1975f8bd0a0aae45ad00ee180f","0x9d65a5651319e1eda4e5ddf733557de6c2ec58db45994c49ec06d3933c717107","0xba6e3603dd280e0b99aad923d51cc928ba359a90ba9c1199313c3179726e5a9b","0x5cf7871cf0a13f284122eb79fc41452f05ad5e25f684f0011a1a83c32e1b0220","0xa4fe0282760e3e25e07fab81fbc453b63203e7505e4a38be415a54ae6e291964","0xe0f824531222f00708a5b9b081fe2f0a03df88281d7f65491632afd1e8b9e663","0x52d677dc199536cd2b4fddc9475e31a5464c6e23b3f2feb7c89373737cff3e90","0x88bd5df64cb37a9573ec9ffae600ccaf15fcc0fca6cd41c7828409a6851edb97","0xc6021566f5d3e8e769aeaa4e57bee3c87361639d738906669a751d6ec33ca981","0xad2ee8dca7d08bb06534008a93e02d1c5829d2c45d0a87341ae602ab515d1ba3","0xc2e148834ebbc2e5bfdbc049a826c2543d555e82ebba54d1d9ce364db2c0ad50","0xe6870b3aa61c98a3905ddafde7836f3a081d8adbcef837337c217e29e496ce8b","0x444ced68cd327f2eee01863b53c22ce1deaa8e8046db6956e5147291ee01171f","0x4875c6dcce08945f91dfc6b53916142c4c82f97160d298d56f26512428a02b81","0xab846ed785bff95b1a60d91187db61a88f0cbaf38338e1d98f1d4eb49ce7decc","0xe0bc0f406ce4d3a8db74930aee3abd81b81c456a861678c12f91e86be534cbda","0xaf79f765a2df3a75c262b8077c71eb4e600aba68f05428b3c633afe9fe5d55b9","0x4f5ed337600c29ae79efe049cd573c4de6341ba5cd685de386d39c590bba2239","0xe9796fd29db503c276aafb1211fb5da02e8a4f463e2c5c9900a4d88c382fd25b","0x7fdec04292b8a90a2a37ee58d1dbb0f09c822cccb87684bff17a2c6ea3db33b3","0xf73676f7bb4b088802290d52b635f16bacb5f7cb5c1eb3149fb8b062f2d68c05","0x6817d1954bbdcc485d09c8eca0686f68998df42da77b70e2b9dc28e1a8c595c1","0xa9ca3e05f5eb5bf3a5f1c5eed49510e86dc7f050463bf1b2db296a12622c119a","0x56d46472a23f33614aa8f6729385f3b4daf3fd70b6fb4b846b69e09d759a4f10","0x48077f71d3bf3eb989b2106987821a1c5f40a75e52ab1035da73ca095acfc7f8","0xa0f0dc8491364fa9a58873467255618c42aa0331e9088b52f7728238dcba3870","0xc12701148047b3edf57019d256e11858df76c5fb8d140f896b363ef94decf25b","0xdc17e1610ec216c8d266aeaf79e8be1d4ff543d41765c1f625241df279b14c94","0xa9166a2770cfa407b3401ea9808efd6edeaea6086bdbe46a0edb0db6ecd2a078","0x3025796c698b9bb886a802b544e118b883cb2f8140384cd157be6cea36f5aef3","0x560409ea037b031339e207a81a18f6787242a06b0c1147e7ca279689575b8eb0","0x38c9d0cbd98260d24ef9617bc570aceb503e812c4502732ecc5c311fe76e1cbc","0xb171fb27055b360175936b8d912fb7c47590543c521ea48ce374fd09cd21ba09","0x1cb548c1cad662b7ffa4ceb5ad1624598c24024ad22aca124a26c1d49e927369","0x2478f0065de69cd3e9ffd85833911bb84af60a20fc45f13cc603c09e6f77c21a","0x9fc5a9d7b7031914bf5c7d5b7c991ff7122ca72434eae78e66fd921a2c5bffbf","0xf3d8fdb79b927dd80d7bc58c015124a4a6d0a99198dc421469d83518de2c30c1","0x3653c61b8bdb29e0d0be0e3065f93877f0bb87073c5e8cfe3f66adcf4c68cbeb","0xd5a7742ba7ef81b70fe72e0f4e06004a86c8f8a3216b3991d61a4348fe2f0f22","0xd86e0f446e30dcd0cbcb35c47ff6ba8868fb0929aaaf730045158e52bea794b5","0xb93b8670c12b0e1bb171f22b28944418139df741c7ca8aabefbab564e43a7094","0x23018b2c1c6b3e676945675cd40a7db1962808d5df14af4fad36aab94138df50","0x691352a6856a3998a82ebe458a5d82b0d881983c0958432dd05a7676f35a3cba","0x58fa49d7b6222b59b4d8ce027ddde590af3d3a10ee8ec246b9137dc9e71f7332","0x174c0134e2d9a6afd7df7d2847e498e206f9438ca87147f813d36642728bf26f","0xea9eb5f9496c31c20e07dce6f81df20d463c138e4f151875bc9d438cd2054d6c","0xac72cf1d93a2cc5821a3174ccc14e82c6e6360c5acfbc67d8399bdafe6a99f4d","0x29c440a2d867d3412700ad5f7816604b5125072acc0f9811692b2fb349316de2","0x318d618b1210c4375fe75da93685f47f68baf0c4622217d79bda1df3f28fce5a","0x3415f2bd5932c2912793ed384ceb149246b1823fecdafba873f63d3d65e89a14","0xaae959db0b48e24776c0f059541723bf43bc620d970eb82f491b8c90c1c56d0a","0x80515004d7baea180abe9c214f981b9f0b99ec9dd7613e056e221291f7cec8f7","0x9d2a178ff8aeb382f67e15884aef97ae9aee21883d969c5647961bb5002c2394","0x29c64cc697ab17a3be4f1a721fc820d999d789072f9e6f0c81d787cfcee6eafc","0x77a1bda974d155f0f745330722a692342175241fe363ad23e20d774bef24174c","0xcfcd0ce0138db27843ef0a476080f464e71950dca6ec7bb74b92bb44d2b61af7","0xef4fa22b5a26f8f88d6266e463fc2e7f04293f64a111236d368ef5e0aa3fe488","0x44ac2f7b702f8941f6755cd5cd070aca5f2b9469c09114759759acc82062a745","0x88763860a5d78f5ba44023cdc436c5f640ad6d7ae051b19be96de423caf1cc85","0x732ffcf83708e8d4f3e68516a2730b004dfdf709f50a7aedfc417fa6b622bf27","0x5125b09318af74e008cbaa969b65e4d91a45f8f99dae9dacf8b684f84bc0a5f5","0xa482ad00921dff839fa1d4945c887ece41d25f004647b31d12b1a28574c1ff96","0xf8968edf99e5c3234191d67f0dd2cdd250ab4d3bec89d76d8e852c9e4cd271cb","0xb76e48858d5b763c02fa746dd3017b91cb52b59c4e525680aec0bb3ef7698512","0xdcbae81f0dea0be60fa28f6538254b1134a40b45e88b80dab37a279f53ca7217","0x7aba8f25440bae48b613f26acbf2cdc5e390d7a9958dca1c176a73d0c11d2c52","0x055fa17f95736571c07a74dd97f7b064102dc388dfd3582739c9d8de3b782482","0xdd2dad518be25ac60eb7c1dcccca7c0dd9407ea0af1325ebab767189f51b368b","0x96a5a577fbd8c282e1ae315aefe76c7eb22417ad036be163e3104085d8262b06","0x525599cf3f44efc9c530aea87a0eae04d0799ee00ff1c956f992a1d6e77597bf","0x29ebe8e1f6706f778c775962996ec927400fa5bb7ab0deb539485858f7a1ac10","0xb5d6ed0773871d096f4062e1c16ab9ade153a2b3312252b5fb6732c9652d28f7","0xba56ea085c5d7413b8fa616c5daa7894b160dfccf22e654c0ab1ccaed9cdff8d","0xeb37975d5924edd9c172bb29864caee1bd005e14132bd2e38193605bd28f7959","0x35b917e18551683da4b81c3c468e438b2a4e32320ab89ce85909861e0bfdbfad","0xad85ad4416e73ca654c426fe7e78a816fdfb5dca45ebaee8bf09e3c15f2b3839","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0xe16f31047334bd421de4ceb69e8e04282568827831614ccf9093c6b33fea8ee9","0x224ba3466dd657c02935333e7108fc002501af2b3a5a99a8acfc8c6e365fc186","0x5ef8582350e5016a695f6af4b1a5ee777bae557f1316a6f6b6fa3bcd70799a65","0xbce2db293de435d067f81fd1c263ee4868c2b2d0fe4669b6ca9bb3c437b49f0a","0xc373b31a2364380088d53662e03fe3f983ff2df9ad8dadb6c7491bddb6f05efd","0x9f501386e3a58265b504428aeee5c34018f86d6c55b8b846c5b54d8b0de24c38","0x5912bbd81e3eb490991e4f502108e76b64c2b658c860004027ad21dfea414aa7","0x54ad539dcf38bba01cbf00ffc2215f03ca24d40ad35e770f31662a08d3931142","0x87f2a7849aa8c7e3872749bb84cac043bfc80b43cba9fdf029fb9924383ae4e5","0x0104827d606e197b34ec441b7a9e6d8a39f97a1d210d2fff87e03a3db7500e95","0xa55aa0a938a010fa0cc3964cf00c208e2173f07fc63aad95cabeb726b5dcbf22","0x051ef00ecfcea3ce4e2f6e7443a2bb5d359926d553c66b58c1494bb2ba0f5f08","0xaa5df3e6e6997c7045d89f4e73fbba6b775aa58daaafdf7bdab1295525622db8","0xb6247e8f54fd74d4cf3061e3bb8fe010681d2f9a85fef3c284d68538e15e5d73","0x13f0aed9d610ee3bea7fa76043518b1538cae2fddcaae73d6a82cd3d0a2bb426","0x183a97e3895aba92027c6e8d1fba6ab8c11e4f78a9c59035879f155ee562d7f2","0xb46e7085e732c1fe4fd92baf980576002bb15cb9ea15c5d8cecfb3dbde7996ca","0x0234b29e1af0cae195751b2cd7b7b6176e403e021dc60167e21a4139b71e68bf","0x6d529bdb2d3c017fb3bc8e50804b57bf8ecd30aa3606fa58e90343c188cbba44","0xc9858404a04cd4161d5c58253992343aa413ee754558d3892f6c4b650a35334a","0x2b11944dd827bbee3b422c2a1c40c1e275b288e389188cef9c0b16a551f343b6","0xd636865649eb339e2eed9b413d3a75513d85ac24e7707f8b791b79ad6ecfd1f2","0xcb377e9e8a45cb159b8e3c36c37190df7a5721a2aa95e78eea10544a0909f958","0xd8842720651231728ce242b24da4d8187da8aadd079b315fe83994bb2bf0baaf","0x8cd9fcffa6505e69d04d6a20c9ef31316cad1bb8a66ae9ade7b9f0377ead2827","0x79b49900b45d2a3a402b767ece9a9443d313969673b46a778ef0fe9567247db6","0x4ada0230b5508a6169d396d7423d41d53fd6c07a253bb90d46320b6c6857296e","0x65feac569d89c741b6029aeba10ddb8f7f84dd574c0f745d6d33491de01e0a35","0x10d6e4c5010ac0940ac68355cc040e5e6134a8211719727096dffc6e46f05119","0x72bd073aac46639593424bd0b1dc7657f05f0330657706d8418e6286cecbe1d3","0x5c6deae95ab8a455642ca0814ad85a8bc6deb8f7ce15a549f009187b58a042d0","0x88cdfc07933f8b95791bbb4b90a06cb20f3c83c95ac2b53828001f46a436a1c8","0x5de673640df477305cac15d04bd75fce477b9250bd20a0925e4b435d104230cb","0xc634b705eccf47bfba0e72064d2594fbe3330db7cc0604a3496fe640b8ff5e22","0x8d62427706415845e763fa60cc9ae5836b38b080e7a3e54df0a43adee7b75106","0x39ee8b066d9369d19d875ea9898d434a7c534aad31178b0c2b9fabf5478312b0","0xa65c2552c891df00378ada9847250cd3e86d6be9fe8b017c8d40202f23e90cee","0xc8a89681552cace4788a8710026365eef7e733436bfc1cfde9bf693e84684190","0x5e45bd331855e36b7b503b2d3dd41cc54ce4276ede331b5c56509cb76418879c","0x027414f042f1bb32f6cd2b64c0cafc1bdf00fe0cac49d30ba12ca1a0038e7828","0x0f4fd8b92e6acd89bf51e0120cc93116edbe3fc5c3e69235c043f1b7bd791127","0xc2bad1eeb08f1d7b7555fef22838437c0434155d33563a30ebcab9b05e61f6d6","0x0e5bbc48e38893556b783a37f701947fe2a8b76c80b93f3482702165110a4367","0x1e0ebabec898c053365608a3cda324ca1273d965bf14bde6fa83a05b648b938b","0xce5490084c1fc9f2a7f68c261ca1477b6162dc730387b05bc6743447b9e558bc","0xd0cca87e47d22000e7703fea9361f423ea00f7aad9db469f24a89615497372b6","0x7c606d8e30e1c9dbc872ab2c1ac0f592482b7d47fcfe3b16a33a9fbf12101b65","0x3a475e87511b97028f68843b5469e9ccaf0cf2a722dee9604da068baea923a41","0xf3b4a1ba80cf06a2db72ad64d52573ae33bec1e1bb3fefeac08f536e669995b3","0xb8e6d03fab4fc0b2f01f0c38278a76b2809769b23e11cd736fbcce7558322052","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","0x40e2a23ad4e713184d92eec79926870473ab9647f69472b2abab4f4369b5ce65","0xf9b849834c8c3e5354f48ffa9fd72ed17963324dd28a5beac6dbd50dacf6a221","0x6647b59a4855bba01e2c1ee68cb5085c23b5ea5ad743eee0f371e2fbef26a4d0","0x589e270be40a2bf15fe2d454be4ae696edde1a1ebf4baa02b9c5d4cf97edffc0","0x099febc4c4e46c27879cedb03dc3f15f94a8b43da842e6029373d47e1a648606","0x7f963677048b3c328f06fdc56df4798c2cf96259b59f9d3ddac1cc1ee721357e","0x2c5dfedec06e936400f0640c661874fb6bad9119d021f75e7dbeb47bfeb3a7a8","0x2b104c84f406c73e7665b8fef04e21df2517fcea6802da75a47b245dea8abf0e","0x2cd71b707180cdce2811ceaa0aef420c1232df3f53b8983afeb1c906b561de9d","0x3ee467575ad2ddb0a7a8412958167785682494c53320dfac4d03441b042d4a45","0xc331502c1f16b6c835b6ff60f7f25d3ede877355acb9fb0db2893bef0f87bfd9","0xb7c111e2baec5e330480b6dcdbbfded1eab489b7b478c627607f96f5cc816d17","0xe7831238690b2d6585ebf083ad1b1653ac5300680e6e66346054a3bf8705e321","0x49b9696e7cf24eabcd013b3630a2cc26c69b55dbafcaa2438f2a5b3e8708821b","0x2c4acf90d7aeb9d7a8f8adbff5d9bccf80350c82bf1e5461f20364f2535f7020","0xa79fd047831f097f565fc04c31ef3e8737b75531e76a64e8dfa6e0364a676ed0","0xcec2b1aa69187520f5414347624f799554b796fc1907dbc43be0bde319110040","0x44794bb6a1256c80d535e8fecceeeb28f39eca91ad10b9aa085d0225f24f4ab6","0x9d47aac9ba7225f99e2a742ce6c293a1639292fb162246f341a206b05846bd0c","0xa6a736c8d0afb387bbfc8b3c8a4f7c4c7a5ad12d3553dcd8ec08f7c45f033039","0x7f3dc6cbb209360000e4cb5ea0af9ace288bbb54b58960af334dec60f6d2ff8b","0xa3686b5f0142b5a6bc36944c1501926cafe7bc4efe41ec332129e266fc993a50","0x00765047cc33f89e2ee6cbc3551b05dc88bc9e087f453d3ff93b309e2f586012","0x402f7c445c4d0e657c9cfa7a89ce1a6ddbf5428624400eba44c1babf70666e71","0x5a34bf9cddcd329002e958192c07604c3334755cb911f1067271a5c57e33d29f","0xa48e547ee4b912740ae1a2072dd668800cc12f45f61097333f0b9f7f77fc6e67","0x3a8e45428e383c76a2804ee3918f90e584bd2de90bc6ba0599fffcabc8e214ae","0x50408fd6a81aea9c5ed379fb14c6aa864d1d8b02a9be06607dd8e7944dbbb6e5","0x50f3b1fc72eb5da58b21760d89b68dbb6999d5688b2a743e62b4cfe2d239973f","0x1654d21aecad6fa136004a790892849cb59b009cf848987e3ea2cbe992d9cae3","0xa195c2e549b3e0d8dc7be9b7043464114874121a3b4198144d5b49893e2b847b","0xf073e4bcb3b28c5cb363c11bc3bae11dec5b3c1fff6e28513d0f8c03e6f6d4ec","0xdc8d8983c9180d8f561d6556cb4c03d16f791e2a2f627259c01c7f119ed731cc","0x1833f1363df995cf5bfddf55680c095504eb23f0067c7f214d146eb6a0b5d38e","0x2f0bb47b1cf4055a796baa68681e4ca55cc6c568cc6d8f7fe0faf913df775612","0x360cc4533829265910b0c07c39d4799b4d9c5ab68e3f4d31b0ea564ecf01ed58","0xef96d0787ea610e933a3453c7f3135b75437e9a2d14dd7e7d9a98e6a19e01831","0x75a7855588e219608b3c165e48cd8070a9d34f825fa29e6749af573e9eac64cb","0xd5256d1209aa84c2144d7df6372a946b968abdb3cf648d1926eb715368c74151","0x29cb65b70b3b5d1a1c6f0d181cfc144e690854ad5ba8bf295f21df167e826317","0xae4c3e058446dec8e1917cd94505cda71b5fc6246a925cfb3cb65045d77e0335","0xdfee6825c80fc8973c99e12d125b2632aaf64d1bc56fdda386af3521db9328d4","0x932f4b549adc4a39d5c8fc4a31df0a17e774aecf4286e8369929f42e60be4bb9","0x0aca6c5ad88ccfee16321bd51587e608fbedb6680d31dbcc1a01412d22f406a4","0xb6e12dcf6fbd9c2e0f1e21375b10c056906e29b3c1938856008876ef4b3d1fe2","0xa3e9e37471f71943d42affa441f647e424aa29038397d1018aad1a0911b26f86","0xafcce9564dafdf67e0e04f74395c49cfb702e061deb8e61ccc8b16932e6b24ca","0x155f452ddac58a5545e6d5e5b25c4382dbd0a55b3ed362056899dfe97ef22bd8","0x8fe1565357dbe3c12c3a9749267d9e40b862e4160891f927d46c9794f0d0be6e","0xf8490908a73c1fc342454a0a81fabaf3092f451600777262b2aa13926e72da05","0x8fc69adc2a52e6daf4159a98de8396f973ab9942cae107a8104ddeaec0f1e39c","0xc0c22d729c527e24137b77d48641e31849aedda5d87136a89010b98d2cd819e4","0xfad04b5e768fec60ccf0e6da69c9fef82358ebee2a2e7a8b16006cf5fa7e3da6","0xf066cc60c85644be4efe7778e7c7a8cd0fd629bf4349297793f5e0e7be8104eb","0xe20ed5d92f1ea5e83ba57c7b0128f6b81e8ea85c0a83214789c1ada22f5fa411","0x38fecc956fbc758dacebfd4703748172a0327961f96245850cac33a853421983","0x546216addb06a763743e245b2cf1ff42ad8196107edc51130bdab29c38cff0c6","0x684c10125db6783e7206c528d7ecd2dbbca5b7894b49c96c4570f7bb20f0e66c","0x198137865c1a17e737754e9a4dfa937de15bdefc900052b2619c91d04c6d7cc5","0x42a0dbc46f17f32e3b0245f1062dc95353a04b0a8ccc3830357f1da84b7919e9","0x8250779721f476f6d4036bd5507d30e624d21fabb17903bda297e84a1f599296","0x778b5462e591722b2774efc954a2fa1fa9312d87b78efa803c845e0324060759","0x9af6f768cb2345c202fcd65cd65823ff2eb190b748cc7933f2175098d832ef75","0x2cb601d26231d4fb7f68460e7596530bf6201106820f0dab4b81328e8a7a3849","0x2a1c1c5c32c000620d335b7e0b2dcb7a17b66b62f33191672def32af305a0a02","0x1f83f05556cfddd4cb6a2010bd5984e86c9262fd441790485b6d6602299c30c8","0x98b767c6f93e4e024ed57cac0f886f9d070da3e2e60817266520cd4a7a443563","0x8856ffae995150cbe278e4efc2c2845dddba0ea52f3417cb64f6ab204275124d","0x3285707930977475811401b21e2b266101440c22464e0378a55eb68ba632e638","0x637711fdbd12992ef674fe5ebd85a5dd85bbaa0c13dd655fa3a37d0676bbfee0","0xdf51433a7167d61b19b17565b4a659c8f542ad21ce0e38aed91a4d7c73dfa87a","0xbbf49948bb413d1efffa8fd05793b52697c6f6dd12380b4876119d01a4b4d90a","0x7fc5b732a968f5c0999e8abbabe1209aeeb6154aca22693d7608709087d54ee3","0xb4d21630151012a3dc9c3f531ddc1f00f51b886d3bcf8d3075d46d7b69177131","0xb800ea9cd255f888c1ad24ef164592129232c18adfd8316e35748a8d08fecd07","0x958c5c91d99a27246d1bdc773bee631c8f01f789a683a6bf107646abd0914029","0x04558d02c8f022ef2d6ae5f931f3ed01c3c106a1abc21ba5288cf79af199da7d","0x8f94d0293057d9135f69d55c75edfc1c5e3640f15178332acb25d31017470e02","0x832cbeaa9a46d710dbf8911e2daa1fbe7046dd5bdb8c28256d3868a47b5dcb67","0x5053a2f953afc7a322ce5a33b8026f4dfd2e7c5cf326d0969ccd5ef39c6ab412","0xe8a4f4c829059e99945cffceb6a9da3d5fd2828a3bd661c9a395e92d7066230d","0xc4c45051f182fb9ba2b345c301ccd341c79fbe8836e7103660d3e9ed5d8718fd","0xcda03d1a4fa84063d0b2c7ad643bbc020a8244a29a5ee572b04854292728f02d","0x7d9255d9ceacf7c7aca01869b07cb0974a628324038f861d5883d10369a33163","0xfed549d7d56e68cdc7d4edea483cc7c576e1daa86595d4eabff089249bf95844","0x3cdd58b6c41f289bb0c9e4b1932215e7e94ad490b5061e9d77b0f3eac38f8608","0x2bac1629a1f132b85633afff341ead96f7aca9a6d411de565d2e249bdbaa2c06","0x1aa3f5ae77c717dd3beb7d2fca5b0e6462c92a982508d8ed56d92f4c29270264","0x52c8dfa7473ede25c3813da8543a4777f543a053ccacfe24faf232726d6fe879","0xa6177868019f0a6fe37d37332cfaea05175ef3c59f1cffeb11bd106c758347c9","0x80018315eef32f867f52c95d228d1bf087977b81c666d1040d1796eb26655fa5","0x8babef9bba2e091f9351e15902a4a808d9e8413000a51495a9a073d7ccbba288","0xf88d274bb1e3c6b082a889591e4ecf87bdaf8dd4e837c53a19380ddb72ea70e7","0xa6868d24c93d5ca206dcfd517a22f2e40666deb0664f239ed89d4129e2770b05","0x781f8765d1745366290e1b94bf2c614bc06b363ba20cd2162f5f5af734f7ec4d","0x27c1a7ece0fdfddd6e0234f0277acf7747eef40d6918c7cfecfe8796dffa53dd","0xc40fba65744b78a02402bee1ae5dd4abbb4c479a84e754278cd7842f91f5cf3f","0x5df41c911768ed40455eb3ff3d2d4cc59e2d0b0d8866c88b1b7ed6cd30f73ca5","0xb08ed1a6de4362a4262dd134e96c19c801539c52565b6a73cd709edeb30ed0ac","0xd8b6a525c318d938392c5f41215cd2a9a47d385c2aea3f499de839ff26ff0101","0xfc92928104c6e2d81c8e1d9a8ab9bf33e74a893cc4a17464b4c7e40c3351e0b0","0xba426a9a5ce6cf404efbdc872a21ed3464640620ac8f5a4c32ce5c28cd72e9ea","0x3b0406885950d44e058a84455a53dc695f553746058db85de58b258e4a57a330","0x79e3f6e89314a47509a56461276e50ee944730ca14a3ddfc75623213eb138704","0x58223aa15414313950dbbf5455c056140f650f32b7aed23bb9ff461cf16cdfec","0x2be1559663f835dce564eed3d3026c20a2277b816ce466aaa5fa30e6fa9c5eb0","0x73521b8febea49b4b7560c7ece8ecda72f2fe0b849200b4d92ff034967b1da50","0xcc92e603b4ddb4d62b2af44fbfb7cd3b5d8a4818fc3d2c78fe5b61e58aa36999","0x05d590c1774d036d46a61a16bd02de46398c763f627d554200bce6458618eb2f","0x1f7487b4d0f113f2736a02b9003fe5583836c90fa7ea7ee76cec7e1a74978e54","0x47ffffed3d71e4fc09fa0c65d0d5391ac670a258e03d4d33a19564f44360fdac","0x848bd635f3d587da452233b7562b2dd6b826c0f0ef96874afd53a05be071e0f5","0xcf6d2b35573ce20691d60dd9cd00a1c80fe92a019f987eaa3b96c5df661b7e57","0xb2508a34b91eabfee8df2a894b2e9e37bf16818d530db9afb6e5043603c93342","0x50d129c6973ec79bd6ca326b59fe25c32e9948fc00eb81d6265c6a62328f0fc3","0x56f9591e5dde0013c0e63221aada50cf39fd0da67cbe28a36d596bd75458bc41","0x4dd628dafa5d34c4800fa8774a6fcfe58d2e4f1101d78460de5c57d65c6fa055","0x00d20bc57a97e0ed9c06da5bc22c76c7bd444a70a50f1370305e11750524979f","0x9f76d457c0b2c67a585bda7dd88f002e65a5153d733d59a76ad5423fff3d8909","0x4eae4ed06acf5810d2ae4400a613c39f88edd28f3fabeab388bd749a9ffffbc9","0x2c20abe1eaf4aeb34f198b54a84b799d492c9b26e5089dab7035eae2390af348","0xf3d2b5f6321f296457ecdad4bdc136c06c6f8cee636a027753e5a0d0aa508918","0x2254a6bd7bd74211bcf86a8c1c8ba1840cf32ddabad0b62aa3dedfdf18ced00f","0x0d64a6403d050cf944ced12f5a7aeccf9d6df304d4b7d7bd52af9a5c934d4499","0x37fa1302a2ab8c9805c3e34490c91ae469f487c3b198b535d3cef035395e61fb","0xb7ae12915c746f0808b773309e11096e539052978609e2d66fcc7e27a25f4a78","0x0a42072b341a582177298f018f1504c768486e06fb370e5b40c9cab772a6f1f5","0x203b28cd9a3d422a6eda9844728e51c81402145e620aa680aa11a3f85d9373a0","0xaecc28ee49a084e13b635fc2df3aa5c74081dcbf4a9be73596c980b639223734","0xe65da3059aa14ed1bafdb9d407eb4943e739f227984c77016c75421d1fa653ee","0x01c3b1838f36d2b08688ad45fdc8457736b9f287e76959c2893205f5fa84e47c","0xf58bceae272662442a9576e37cef33914341c250b97214035e486a8410066879","0xc3b7573045764dd8a5e6d9fc3112fc24019c529a6ed16ef2ac0bac10ec166e6b","0xd8eb6bfda8636f360da51d72e967a0452e64ac84c84695fde1d8a3606139e85c","0x8ddc955c089c95073afa63666d03609b572d2da3351aba6d22c6e080e9a77dbd","0x9d60a7d6132c49a46184b8272642ca51b9034284b3559e35e8885c2b48bac1fd","0xa6ad8d67717b6fb9e8da3fabcc024ff58177a60286095291f8b470572911de55","0xf91bed837404a9950ee43ca3dcd3742dc7008a5b006aea3cb5f17bcb7c0bb71f","0x70b984dd91ce3e1809b32be49229671c8d9447876bd838d3c8d7e47aa50232c6","0xd9df080079fc0b1eaea5c2a0616943e6fe72c1ea1ac0ec4b82e5b5c3a51fc192","0xfb49e158a617025dbcaaa7d4a0204148369f7cd0310cb155ec8f3e2878564e2c","0x955737eef711f5137e8b6189e640f15a30c34765f83787e2ffe48fdcb160824b","0xc0fd76c85e63728d98ff0c9c5d68ddb847068f973fb1f49e589b7b6f0f3b21af","0xafa018cb41326ff985405a86080e02c146e4f5b821d724db45c857ec0647c9b1","0x5aa5376ea4b7daa8055d1f2aa24765d12b5ea47d5df770d4d87b7e7e7051d2ca","0x8745115d75466bfbc1b4a6bb72d21bd0af4f90bc0b1a60bc32637702685ed8a0","0xc763b44cc8bf6ba2e6734c33f775a367584e5718bf95ae23b7dbe2c3e151f62d","0x9c7d4aaf5766955b3556c9319161b70f574fb896d38ef10041046902f3498523","0x0754930c5cdd227454a8576645af8ba56c78b9aaa29b9b35c6ad40dfc017672a","0xafab88997edb717977d19b6aa8a015a9272eaff1aae0e22c71241e7adc4d61a4","0xc41bc46dcbb258df45ea3b56343c67d7e6dc34d30aa518c954a725be288287b6","0x71974d95a7b4730baa6eeaf9c0208bb4f47c2c2884444b2d8478bac399e5b99f","0xd800ec704b1906a716a4eaee857583ad611f3af93bed6b80d031d59003291f6e","0xff0a97c17d8c97e368f3c6f9d69f255e565ee6487f1a44228fc2dd95068d52c7","0x9566b57bb02dc0790e9d6c38dbb7e288e09f82f75944c0acd8dac33ceacb10d2","0x2383edd984ff70c65b9cb187c9a3123218c5208b37a04e22dc1bbf6a041563ae","0xba6ce8b580ba6c53174573f936d6c24df97c654629f36e4b8029b957fc7855f6","0x39da91aa8f8a87d0a69394a10adffd258336646d1508f6732444d8f01baec7ce","0x8841ff8c79345854eaca21449b2a15e11657a6d90441e1a40ba39376135f4d75","0x5d7bb4852b4e1be7f1a04bffeb60033384ac73e04226b93c4adb079c7d9c9539","0xb45f1972dce352d5f0bf5b6828ef34fffa37520937f75fdc5cd3396c288e645d","0x395a33c68d098f09dad54aa1ab76611fa0854df332e79f8c63027cff9b4c1c6f","0x55b633be450c8c766fbdfab04f9debcdb68b63eaf770f933d32a6af44a519a95","0x1aa693c7a30ef3fa45b324edda8643ead5f8e8ad4ebf85f682616211f4866544","0x2655c31be6c66ac423a022b89f2de921b78c3c92a85ce24c460124288b51a19e","0x0e65e3fbaa858a2a772827ef4d1a8af0c38981ee2b8879cdf0a8277f80fd8d97","0xfdad0719051d3220b46c368790cff88fe21f49f2c7faefe561f3a06f189bbe9e","0x9c119bdfca36b4ea0ae3a05c5ba71d2102509395b1ce9c728a41fb64b5e2db68","0xa371ad6a57ae8c7f8ac46d722de3cff62020c3aa7203e54677d7cad04319d6c0","0xb2ae9a1a5c6e30e418f7ce3b3f253012ad3209f4e51b55db1cb47ab87dd1a0d7","0x3c7200638fd3d49506ca8fe823cdc2ee19743a8dc603c3516cedabc4170d9948","0x2d81b75ed86bf4f9f79bb566507514d1b2ec82fe37db510bdbdca03e8b6eb2c2","0x68f30288af7788a57b59e97ad6f8d03758e716e19eee73915ed92fc8ab1f07ed","0xb5e807ba64dd2fff7f5396430e5eb0d84d99f07f003e3c4b7117b350db5472e4","0xc4f593a4e6e679df31016da0c4f6b4e15f5536fa917fc10899bdfcce2c45b135","0x17b7be228cf9228b6da178bdcae95e158de17fbea2ffb85f651b452f37cd9036","0x515aeedd01e912a45b60070b9c0c4fc337488585bc1867503510a37db23ff6d5","0x33e4b3600c6ea976bc393f1edbb1be5b0ad8a11ac00c103f7eab36ee06a1514d","0xc1eab047d010883f76e2151e4fde936ba889df9a75a42c7bfb7c3e8440707fb5","0x2a239e48dda5794c2171ad5724c95cf07caaf1cac66c7cdd92754d79a3eec1be","0xbb6a058959d4f09b2728e7b58a83c393a6ea4bb5a16ae058dff64d144ed11d33","0xbcc55ae5431886a930e92958d2a242002647f0bc8f8412026441252bd8c6938b","0x621e7320de30bc72834e72d90a7f2282480e5067e13798a15b3f663fc5a49ad0","0x7d9c251c854c520058b49a874de2d9d52b8f95306ec828ff96c31dfc2f5d6b5c","0x920bc1943f4b94a00870f381569dd328e8b8f83f14dd97111cd9837886ae81cb","0x726bdec411fdc41e858b0956f224af45833feb8f9ce040f68734b768d6b01e8f","0xf5272e3d9c68885c1f51579ec867980759b5e4d3203ee747f2fecc2b95dd1cb6","0x9c924144014336a43ea64ad55913283a1b1b02c90f52be7aa528621963db643f","0x19c9e6dd698c04bc4d30197eaa4945ac1248aeba298aaa853aa1db55bcdb9d74","0x38d1aaa7ff493d057ff37bff8072b9929df45fb233461f34d08c6d7d41b03f2f","0xa4e3d1ca0461c84d2d8c8bff65d96c241d24b050f815859d91933ba56a7bd0a2","0x0148d9ca04dc1cebbac205379de33b01a96d84654040a27d5142c08f6dbf914c","0xfc0365683be62985b15470734b32ee459056675220634aac42bfa2f49cb7e4dc","0x1717ceb88df80d1d1bf9d715a1fbe47e06f4ab71da40db5e40000ab16e34f5e5","0xa249a20a0b375ea159b1d11c2bd53805d302a4d161350fa6e5825e27c1dfe1f6","0x661ca0d33feb485e90df25811dc24735c48b89857d08244530feba0c3875d821","0x365d7be036032ae7340c6ace6b3ca6c59aa72107e3146a7a6058aa9bd48d5f47","0x9783e6f208bb77190fce9f8086f07401ff1871b7e9f74b660b8cfe696f3dc40f","0xc6eb8dc8573e0c9fdc264b6b53eaaebe1d837a34c4e0fea87cdd54799480edb2","0xd45419ec1643e683ba41c269285cc107928376ab0893c314b993e670be9e89d1","0xb7ae2b1c5e8c3112f614a75a468c984adddaf05b00d5d1a077873b05709ae564","0x0ea37d0d653a954922c8b503d37b8411ea34aeada7e1c2924d129a30cebfaf7e","0xccca8fd93b35f5dfb75ce92c542861a9723cbf2401c7c68670a8735d36f697af","0x94a3ee635eca49f3c2ee3a74a04402924b7de0b17ff68d129e13d027578c10e3","0xde5a028aed34c5f39a5093af018c168233b55843c60f9b091243517a59a667df","0xfe9c679b9bf6e2d88cddad63f370e2388edf0ffad0f6276e0a20ba1c5c949c1e","0x5f6abf1147312140d460e94e00ca80a1a7513d3a6f400ccc1d40306d5ce46854","0x1b9216aba9e3f1a0332babd80c55e3e2f97669ee6e1c9d4c2f3343fc35de0913","0x8d0a5f6aedca916f2e110ddd7aa21e9230c1de47e49b16e59ec81a88dbd39126","0xabd9268628f02790e916b393570c5465d8961032c8fe399b647810419c59a80e","0x75e24f1bcaa0c6cbf53aeab172202dd42f2b2e4feb273af675c7220a384a1533","0x8ec13efc82e8353b063e5ae3c9a20edfe9f7d6c51e53c497a4582973c453c826","0xb9d98119f8a8c818393db4016b95e8d04ab6a745f33b94b99adce21dd0b5bf64","0x2c390f682947e8946635a1a0a993999a3828bd36ad73fb203aefd67e60d3e9aa","0x73fb52b6d5cbb5735a00919830a3e93a270eb8b28f59c26e3af56fe6237ad9b9","0xd3e888efbfb0dc910faee7daa9f17a24f0ac669fdeb94be737dfd0bfb12842b7","0x85664ac17435eac08dd55d7ce8916f72a0143b20f160330a81883725c6530769","0x7102c9cc716bf56312f1d46b0a9443f8ae0319de0cdc86b2c7ff06449429b907","0x56b47016eee0fd6cfeff5eca394abb7cb8d3cdec96026f87197356cf35f99feb","0xc5aac096f79648cd291f8b76b6b01dd4b7c5e8e7f079f755eedccc8cf06e32fc","0x4e6c392fe9c57f4bd433288811a2a69f24d3a69d9c16bc806020198caaf5fdfa","0x80e09558a6fce9bb2b50903a7dc6beb1a2c33a4ca1ace340976a19a508affa54","0x61f2db0c31de925bced566f8c393a4bc5b2a3cf804e9264dd146167b5545ae8f","0x842645ce0f6d1601ab8646c5a46b9b4369031fbc384da361a2d3698f6f3b4a02","0xa9482bfb8e714feecd506a107f45c09a74e8a521316d043c53e7bd45c1fef604","0xe28540adb069e3da6cc09a1913d9f21868ffaaabdef9f4e359d430caf89e692d","0xc3af623db94eddebd9f8508888f6c46e50f236df0730ac2fd484d8a9fb9c5e14","0xd00ef8ed6aa7aa328755ba307e759fed8232ff4729a6778d01eb4e2699b388eb","0x097e6486896336fc5a645a2e5874e7c2dc14270994d0c2b8d13c6beda52a2f95","0x78c67ea30a041293d527978d993c069f0e6aafbf6964e60eff6c8fa3077ff74d","0xd637df3fa059a8fe7f40ca67df5a559458489c15229581a017970c7f51546ae6","0xe306f85b9c1b121211cba68ef37e108cb63840449522fe2dfcd9101708a81936","0x3bb783fefd0c9ebebf6e4e39d948d8b48cc9dc23d1029b9f10969f0b702b6a28","0x29896937474611ee88d64bdff0e960897d2d635cfefc280512939c36e1965f68","0xcd2716a05d5222147b99fd1f215b63dddf7a7bcef7c54f1dbcb72f058c0b8f60","0x4fa5e4c1abba6575ae0ffb79372eca95f2eba06ce336140fc5b17ee18bb4e37a","0x30cd4177c685d01e29a9ac9bb375eda09b97314bb1978e29ab2c93788b34df05","0xa7f2b3165eea24d953a890aed065a52052afe0d67bf3a494316789a3fa08f0d8","0x6928433b6430635deec733bac0d330b1fa9e57f3a44290bf061296b7eed0d44e","0xaf7f0c5f6f1a80295cf63d915629a48d6072d142bbdd0198827cd147bf88dbb0","0x18b97662ff2fc142aa16f715937c271df6f6cb479a416c596efcc677875fdfef","0x878216fc585d68a4e815a66a753d4a0bcc2bfcbcd11c68a9a7c63acfe860a621","0xf82342521afb9758654503348af979e3fe6d6751a30f053b7f652c04994df00c","0x8c8e8cc663abf90015a9dd592b1918ec208ec6e7aa383be49e3315c78cb476c2","0xad30adbffaee3194232ea94d448f43bb354e6344dd2b29735acad20766418a2e","0x7ec1444303c179fcc2e1d9729954c4ba4063298a282f370fee4cb0d6bc807b19","0xe39c8f1b6c9cd39997db47e1e3121d65275d5ed965e134a4f030eaf6af846e6d","0x935ea1b4ccd21c413ed3ee5925c1f9a4f8bb94e266b8df2fa9b19911f1b531a3","0x7118c5159a8dcb8b1c43da32d4886a16c8c90313f6c1d4dea3073f5184b16b44","0xc7a65479d7c1b0701e1b3bd53939ba1f5b60af42d043c984123976bdcfa3c911","0x5fffa1a3ab8cb252bb3f45ba8740a19e4702fd93c87ed2d6e4001f3bf77a6aec","0xb26906eee1ce487b3d140ecbf768e6cce4d30396dd37cb79183442aecb656b94","0x573cc07660ef4c743ee741582f68720ee39af334bf41951f3d31850332fea977","0x97873357bbd3649eefe0dba687392334e2bf667b842be1261b62eb7276d09ec4","0xea3607e6dbba69537d4b50f8844f0e7c12ccb579740911b81fbf79aede17dea9","0x6cf3d0141aa99ad2b3c097d3e6216d71ce548cf1752567125e01411f54bb0844","0xa38421c6744fddfcbbebb8ed9cd38c34e1067eae0029609829d6424f982b0b1c","0x165d64cc3867c358d88cc9592a515b5226559a6b473324640985e59a0b6a4794","0xc12b323a05adeadb4510adad12fcf350c5370b0d2eea22b8b1780740219eda7f","0xa324b57f5c71230e0128a9c68cbed883dfda0637fc93eb58c54b6ffc714579cd","0x89f30ff7c6eb73deab9f41a612e37820edf1ea5ff326c07ffd216060e2186e2c","0x2d8f50edc52efa2846977f11ca965e54f8b7e471c0eb975d229b6ccce3461072","0x4d0436b15b63f76115bae2c7addf541e40661636d2803d52d63311f2b29cfa50","0xe67d0554951bf27c1aba6531b240170c34d12f1d3d7f33b48fa411c510c836eb","0x54a80278b8dc3db3651dd663d1579e2aec097fa93701b33ce7a7bc3e06885aa3","0x67218dddd3a46a9a19437e756fbf9b14f5869e02021fe4ec0605d07288937c98","0x5500632f0d4d04af6fb94493f8da5ccc9d5409a282ce12ac77838e288de0cac4","0x3b82d1ad73aded55861b637ea9fd1f0998999cdfce315c5b60c9b2cf4c49734a","0xaf3cb49b05aa7ee778f7f1aea8c62a5027125a01c986301e3210ef5add28f78e","0xa19baf29a3910652d52974aebc9eedf940076aa9aa66d410f4a76020e203dc5e","0xca335a86be1bfa7a0550022b0603f2f9445af7106ee70fa299088685fad00ae8","0xcbc40ca95e910f191e615c3c4791d8e42902c54763825b9cef999bac0e8a3e0b","0x6fb107a4978a3ce7a9e8565dbd780a74554f065cf7a2f46e99725f07706758a7","0x2a51df163574e60d882c05394250ef9f60963daf394ce0c37367937630a1bc16","0x25d45477dc0a653743144bdc113dc109dd05581db656e23c8575e5e6147ef5fc","0x5dbabe11ae67a32ad0e34823611375db17afa80fd4b295ec39a9a8008a35b248","0xc8e65480363fc3c4cb888484e225bb209fa7ce239909573755093e9c1556432c","0x71cea686dd01b3cb2339913ed451bd76dd835c6204c15636ab812bc33f6ca5e1","0xf9c1027caa7837f5f804d7642a47584a98f2160c5d6a2b246203bdd8d73b690c","0xb85536ec1873887890489130ce261d963b3fb19be805a0dc2a0b94e299347b13","0x39532307208686f090cfcd950ae0e47951033305da6ac1197df4d09048aedaf1","0xfe94bf8cd5fd67da3cb0ce7bf3d44e4f756eefc2145684aeb88b9c9830295f06","0x1777d2958eaa5ea1b6504d5399cf041f2b668d6f49a6422413862c43fc1f861c","0xb80025ad759df4a6beee0f4b4bebff15c6930a70c4c7bde7111adea33d0d9229","0xbbf1cc9b26ac6b012024541896fd7225ac31882c338331df5bd8d3bbda4929c0","0xde74a4133b556115009d16aefbf28c74294e3dc983c19e537cd109360ed18bc4","0x9943d3f09da7ecddcc487399dc2e88c68f391c5d4c0a7d70f44cb459eeec7732","0x7324714a964226b69e925c0d7c5ef131b5ae7781cb247008f291958172cb5aad","0x334220aa64c4c484962826df74b0a6a9ef3ee2d06235b97a62aa59d35e513b3f","0x0de6a71940101cabb29841e511b2c4976e1db7cb3408ee0f4ec1de8886dc2c33","0xea37c32900303558f718d5e40b5aae58b0e5e414ef2b7d7edc068112fc03f024","0x46ce7c8853e28c287ed1b39c615ecefe84eed4e4303b1ee0bd6b2213b0b123c3","0x36e94731d421c1a89dcf3236cd95932ac0e90a5facd4604340d4cd4df802d689","0x3f2e6c22a3221b69e6d383c8359eaba0a133c1388557b12c39a51d1a3d6e77f1","0x336d21df6cbba4ccb3c00774e8cc9df59339b96c5e765683b55e4909348c2d21","0x4c0cd42b134d8a0303e134a079ac333e370ddc602ec14428c890be3f39224505","0xdad2b34d6bd22b09ddf6f42e2d032c38413d70cef263eed28e4a6dcedbd0c5f9","0x895d6214ab5b383307045dfaf9b5dd761deb5a8f6a169160e86281b4cc883388","0x1b7873c0381eb9ba8cbf5b8786303694835cb3c9db784365c28cca90c285f0fd","0x71246ca5c291fb79bfa22c58ffdbeef659ae10431a9f7bb60a1e3df127aba29e","0xe9e837aa563502a8197e370feacfb345c5bad29023a0c43aead8ccbaa9775c44","0xfeb3b5d9aa4de4924d9c5da29612f02decfe21749e29c3f7f485b8afecc7dc12","0xe780e7d46ac1ceae19b9c38f18033a524ab04bc901d0e20d8188961c42ba354f","0x0a6a37937eec75a47b057860eba3ce828d1e1ec1ad57970b44c0fa0eedb49528","0xaa67e93c2c3e23612d5e0cfbcb079ee9bece0cdaf4f4c1414d0691d6f5c74d50","0xd12ee4c6ab53fadcf3ed97e1a7234b5b7cc6206be9273fa54c6957b57cf1f250","0xf3a84b01900caff5ba90d88b12662c90c035c80352c5bc62e76ceed6498324a1","0x08d0bca7086f9c26dc08cf76a2cab83f32300188cdebf60b087c86dabb75265f","0x2e55651579feb3bc915bf992dbe41e78ff3fb53a5b239d1912815c57b2243f0b","0x8c92ae7b4b1d74602df0dd8f1f8449b012c8afd8b7009047b04eefc7ac3dc618","0xd85958dbb82eb7a910731060e591beeb3b89322d783c60201dfdf788fed28132","0x32e219787c0357edf07967359b06c630777a8187e458795e590726b289aa9e1f","0x0932335ff3be287d07a9c175626dd9633fb0151b6fcbffde6cdb5c6ae9018132","0x6189d95b8221bd7498ac30d36d8064579075c664922135065260d63522b89254","0x77aa6632d2ee969968766553fcdf309ac342299163504c686bc8c86cc597290d","0xfd055313975340f9fd3ccf91fc7b11d86b9daf2d5615850242a2a82360a82897","0xeac446902e5b34298cdb75fe15f6014265836defa6133a03be7e4623663418b8","0x2ecc3e5eb101d26e7e1c916daf47b5bef9366bd30d67ca12850c12a5db16f0cc","0xffd3970b9e81171bd95f6921cc30e58268f0d5d61dfc551063ee4ef5f83edb8f","0x278e957a0999add07dac9bf876bb6d66938d0865501da4a9edf5a402b8b8df71","0xa1790121759242c8adc0d63b662dda07d15634f579417905c165e3d9aa31555f","0x83596f8849d6b6801863699926be27193ff1f21f5f8088a7708370f9a85b6010","0x3fb43edb9aa0483917bda82496a719a362a349980803627c087601d219f71cda","0x79e4935ae2843a9c4a3dd6219ff2252e2aa9a7b7735600dfb8a15bd03c0e7aaf","0x29caf1f44b856bc79de3a7d02cb075fa3b62b3ffdf2ceb228bb5c6d79609fb04","0xfa860a7f944779b48f953b4df6c0071eef71eb95402657ec2fb95cba289283ae","0x2debc26fc71d0c3e3bfff878c90064ebea1f44fbd1b0770152b8dd37b20c64e0","0x3c82986df01577a8c74b3c6d27564a8c6fba671437140ce8ccbb3d950b80e4cb","0xfbe8a2fab4963e6e737d42a37c1840684aa751a7d834f3e31ad7249046948a56","0x0183438f9b368d23486b492c3ae5f466f422eff106fc672a33d3af5d9657c857","0x9f0406d0eed28b2dc275c45ba07b8720d686b3ebbe6eabb7e5d2c3be39362502","0xf32fab0385373435d48d2c9df5a4470ff7b0029a0bae45ca039772862536bee5","0x0d304ea72c3df7344f9db7750729828f90cfceb05ac1362a99cf0e7fe7da3314","0xec273ddc09ff4c7c8d4394c7205ad712eb507a041a48137e50dcb5f069fd9f22","0x29c0482398c15f77d8992ed12279422bc41bf7f6b1b6748a73f685582f4d8c61","0xc2e7048eb87b758ff4378cda45af57861824d424b3235c1dc68755cc2612b0ae","0xf833fe225eca27066ecb9276543845193f786166a8ed9e9d8b98094bfc0cd27b","0x6b23c1d2f949b9bbfbc0692a2b526ef55c6b326b1291c6c1b95e99a0de12104f","0x925d0ddea0e6683e853e358ba1e948e9951db3eeb56168da76f5a0d7c18c1d44","0x78450836f2171c1cbb38cfc844bbc282ce8a4dc2e1348cda061b0cff68aeb416","0x6723813427354705f00fc11b9f7d3c583ae910ab23f3b9d0fa0b4f5c33773506","0x83dae1b66240659554a0e35d0da3d5a4c2f5af3faadb3b232182591a9aa1cc51","0xaebf55732b7fba9f2a9a7963125faf09f846f800ef796736e1426717d91e683f","0x41db2836828a985d915a16d8fdef2c92b8287a64efd815f2cc67643e26066101","0xfe1390db186e7abcf73b59ee1f06478ed309600e32547b2d6e4d0d1bdfc555b2","0xb22c860df7e2660a7223b440a451d56494a0e60074b88a563b832cf0b9921e48","0x9b66cdf1918eb57d412456ddb66097dc60253c9514597fb14e6b1ae2d64c958a","0x98d43ae5aae7385b25a3148250f30936be6607f78e0ea60f5b98656b14cfe9ed","0xa7bd9a2b030d405299ffc22372d557b11847037d99a9dc6aaec166d7af00c925","0x1202f3a3eaf7e10ce22f2ab95dfc64ca76460e933a6c0dcc0b73a222e8555ca3","0x4fb5889a30b3bf3228d63301ec472749d2b30a110edf8e833d1b7fac5a24c643","0x0db4b9c1d3b348311dfdd5b3660541b19a0ca3252d8a9c5d9b8d7622be616b4e","0x61169043a00be8ba948849027975091a71ded7fc93799e399d3d09466dae8a23","0x0dc5267f43067f3693c1e0a9c8462d1867026a9f40146d96a4d5579f3b634871","0xcd15d2c39f5b75d7a7efeb8aa30171899a6c560de43b10e0669e2bc28f462df2","0x581528aa17202094088fd6b28449c62b452bee83d924bf293226077eddc73199","0x17473546b0dbcda328660b10baef998276fb5274ad260f3e02253ba430a62f00","0x22f6bfc47206f532b214973f4808fb591df841bd30c3c24f86d6e4cbc9f12a9c","0x36c7af9b915fcbd574ed91e2fc627b33f78d60ff982b18e74c8737dfc2c3ff32","0x4ec5865a90200122c1c6299bb4975faca8f01a90533b3b1a2f037979638ce265","0xb2779a0fb84b87ab0173001a63a52231aa63e4d9c350b6f42c2510d8dc1337e9","0x4aefaec87f8dba01a017aa81280cc57a22e0a73e67625000eecc9c4b4b10d350","0xd35e627f8760a8fef78dd7255a1d7848a530daa4da05da70321cf4de9545c1d3","0xba0f33af763711d1a90028c33e4007d70342e2f98fbf2267c627ffcb1b09dea6","0xabcec94f3126a856cc1b1853ea551e3f5633cf00d33a711d15acb4619114cee9","0xfef5875bd12cd61043ee8d480e6075bb94d892a15e813155dd87ceeee20ee22b","0xafb19d84c5fe8185d67977554599c0c60ad4ca4ab7fe1b11578116e0d39885aa","0x6977de67b1cfd628e97646d66724646450bce5de3bef94d653c641662c728762","0x0eb63f4ee2126114530d9fcf2426636f89821f1bf179eb88c89e58f2cf739212","0xa66a45b277e38eab314bead2e56c0af773ccaeafc228969c16a04ee36321d924","0x54cca1662669d40c81c8df72fb0d8ad0d121112428e99325daacd69448c9870d","0xa909e789bae066068d62f53b9a67579fe4a260a2caf6a4bfff79f0d42484d930","0x06f975c1abe6fda098bfcf9220f5b6133f41dbc5464bf47df628dc77622de3f4","0x2cd8070b262763f886715177a0b3c904da8509d28e629632b2f3997e87276313","0x777b956d9ca0f1ff2b8560f100a528a4b275d2a371e8b0406fd3376f42adbe52","0x909299d313ce7d45adc26dac85f8886775c9cd6120137697ef34f50feee4a3b5","0x3200f7873fee4aeee582f429c43c238c0a5b24b225f523df96b79e99bc87f8d7","0x5cb1072e9baf169a504b29655f73c1d8d6cd51b988143bb171fb2469b561fece","0x6f9ec5eb8ed96e1ec8707b6fbf3879ff7bb8ab3800fe68d0de7d15bff8a482a7","0xe9d28b9356dff9d321d41fd3f98abeb65f0cf9d1b66b0d6dcde438ab7630e01f","0x810d66bb76b217f44a40f2fd59d8b0d27a250c26d32a1a277a678ab0e4f46487","0x0ab76fb685091db501750603922ada915b39b8acf4208ba3e88618ab50627bf0","0xcaadcd7e13eae697afffc7470142cf74c3eb5dd076e7eeb0a9c5d72548f4ffe0","0x521b789dae079dd90c4d7612b1d33fc7d4406f55d7a5c39d6b9529c6d759d99b","0xd5a05f12806d3e6a2cad62989ce32bdf0a95b249e6841b51e1c6d4e8901e943c","0x9e3d46e6c07cbe5d5a5a30b5266662368caed7ad3bbf6e56504b113fe0997cfb","0xca00c39335ed81430e93c59aba05d82629b06c8d245b3d7118827a896bc844d6","0x22078f053cdde84bd61bb49204efe2f6e633e9bef6c8ef99e618ac2a8e896105","0x7bcd656031d3caf1c0c7b425b6b809d0833428b8e23cd5b361f902954d848a8f","0x4ecee87c3511aeee4114d83b3b8423cf2dcd0d13f1969e96a0d92af5b41c38d3","0xfb7b84f230a772fa2f3e7076a9f48eeba5ad05dd98c8be7cf8dd7daf9104b314","0xabb59d981bc7fd2998cfa76ab2628efc8d417621cf32442863c62d8b5a81d50b","0xed6b9b695859c3991239067576f5d6a5befc8806e11ae089b713fc9bf2ea9dcb","0xcc955c4a7d563ac02f20290a9469fd2ceaf262ec68bfc8186b28f492df390af9","0x38daeb306fd9538758bebe3a096b535b705440d1ec56946d48b055cdba644060","0xfdf3dba57fee47ebde0606484ad55eb6b3c01ef81373f652ee8973e50cf10b42","0xa6ee4176ada9964f8fde83caa2c63b616bc9aa75dbb65732afdcbdaa32142ff9","0x00124e92b9bca541d1bc7aa49a6817f4309036e17be8d9cccbede9cce0ce1a94","0x74e3aca2d8a268827f3bb689b67b5ef6a0ae47f0314710b36f61eb391f2f5fd8","0x2a82a1fc43b3b68725b89cf5da4a0d2ebe75c619caf5d5d84b3959604ae63d4b","0x8df966bb185922c38bb1ae7b315e086d0add17860158495c49ba4bee39249a7f","0x0bdcd94a2ae80d770df1ae7def002a0ea9600c2674f9bd8c6f6fc0f28b403337","0xc3b763bb432bd3f9c0a5435736c3495f37a94f9c741857b4727b212015f388e0","0xd126630ed852f5e992ae6c5f2c1b76ae5eaa78b95c3a9f4ef5acc4e1a33c6c4d","0x7bbaaf49d7468159a17fcfa90dfeafbdfdd16997d83ee5fee753be54cfd5204c","0x1c6c114eea356fc42a6652e1c3371490d7114afeee4c0e6fcfa2c1ba8d3f3d72","0xdbf5d459db62a79ca29acdddb5fda453232f37e32ae24d9be8f6ed9e2ed23022","0x324b7365bacac084d2d6ab08276135e6bd3d77c15e6e7e64f74a533c72d98d01","0xc486d371a555f29e75bc0586960650b4eb4345dc96ea4d2edf4388a250abb590","0x33eebbe09761d0adddfe2422bd228fea072a36fd4ef4ad8d02d054ad5bde66ac","0xc49b07182157737bbf9fd915e6c0cf5fa8c791c818e226e8b48b4287dbeb8d5c","0x68c6a569375aea72cb45175f49be28679b193a269e539e3b4882288181599209","0xd2d80a7ab00870c22ef23264bf9c98c1e07a9bdfda680edecdd9903313dd39d7","0x4834ad2b63f7f82e73c0ca7b7633176cb1e7bea5a33599e5893dfc6baa2c9a08","0x0ae745c5bfa9f2cb49c7bae5e78f6338680e6ad8c54636fe90074ec2feb3b7c7","0x343075f46bf58e09be84a833c0efd5c94bf30d3a05aaba2d4c5aa68667540bc0","0x485a5f402781e3fbff51bd5d4f7e454831a2a781e24b7a7921492cf6738a5131","0x3f53d3a29232e70f563ba648c625e2cd5397280ebf0797e5cdc6acdeeeb62f78","0x58348ad9c83bcf9a6b146238b234eda145f8e295cf260d878b45fd406c4100c4","0x3abf7165d69a5d949d28ff1f0fe47636df7ae3c8f6f372dd863fd7fd0d68489a","0xee63b1f64713a2b7d2bde2d9f82d23e6913efb7e5eabedb0e4822c7322c2c0b5","0x6f63c32a3119af84ebee998dd40184df58405d8fc08ad61303a154d13778962d","0x1c44e98f008805ed1b35185d91080f79fc5d660045918fd478b652c4bd3b106d","0x0efdb2c38a513204d7b5832de618ebdca40e666ef6e6cb8952be20b8e525c187","0xe722b2a04794b88a583d2640bd67ff53893f059211743c3f926f31a603fd5324","0x7648385c131ce44135c86efad17329dd47cef6bec149c03dac366359c78f56aa","0xf3df795e3dc4e7c3dc83eec35c6160a969ceaaf5dd305731fc1660721ca1f45a","0x9b6ed541210630c9147c0921c6fe3841d3191caf42120cb9a1ec0afca7e03d25","0x48b6e76b0b838a98a9733b31aec01b94137a446fd78de75ec5cea9d56eb70b42","0x3ab1a3a836708886053069e725977d553136671f81d76b5c42acb0931ccb2280","0x7c2980aae96ecf82296edbe41bec10bc65a07bb28c74a6b3b25312043a3c3b65","0xdef249cadca268c30bc31f5330c74f271c37c3d0aae5529e5417c895abee3650","0xdf1cd6401bf0ad311e5becaf65c8bf094b29891d2ca1318cf87182a157e2575b","0x02f7fbd8f868a2407e8ae444f44d7b48753901b58d22770076a1ab7ec6bd5ce3","0xf47398d75f44af98002c1c6b9728ca601a72c7ae4fc040ab33a602b2dd73b323","0x6d868059a6c401baa6e505e2be09b6a67633c43a40028280ea670a6b65ce42c4","0xf1b0e6ee98515af11ae47be035acd820fa2f5eb13b2c01db163f637824c380c6","0x3998361394aaa101587e186d969975a31e2f614b9cfe35cf47cfc3472e4473a5","0x22fc8ae8825988b1760c944be5037486a5e16fab73aa5bb6b3def203e66c4592","0xd78c420007efb06486f1757ef18d5031fc15d0ba345e87632ae22c098884d2cd","0x540315e42cf0094ee66747f5b5841ebce93d34077ce50136c222ef370ffc027c","0xf325d7d8a1983523649b09a2b0689794066f781b10d07395259515b7d40f2dd1","0x0154f80a9d3d9eef37fb68da34e320f9d1b2bf5bac6c302b20dab6f11906b8a2","0x895a6bc6dc13ff335c4715309b78a42b0b0e1c7b6066c0ce526f9d2b5a84545d","0xd035823ac2128aaa628cbce3f68d65b69f4f95e776df27640054f6c65a715de5","0xe9317780986a3acc49fbbba57c0c56834f3ebc5f109182fd37b6cc083b15b25e","0x5ab96281057a7ae65b91f7a22e637d2f854bcae4f92cee2c9b18941348d3dd16","0xce72fee9b37434ea7900cacc74786580067edf131cd7a579dff246213ccd6bbd","0x95f1da6a097707031e922f5d6d9d7b2402f1ab60c97e9d5f918c27f7e531801e","0xb3a6220ad33d63f84085eb5275ebea3c7d18017b02d8f93b9b32041300a99abd","0xf6eee56dd73e63917a6f8374ecc4a0cab828d94f729701580c6f0c5db9d26f83","0xbf776633355811d4a8228b9ab40c2e52fff83c6c4c2a26b9273a98f5c81c3fa8","0x2d1b67a40f9f5f8c6b970f1faadc4d9492b5e86b8951e7119ba1ab4059144706","0x90fc859032bd5a248eefc0b250510863fa1d1fb2f585dfc8c2c618ae32096867","0x4caf443a9cd7549199d645325687c2981ea005865df5b07f76afcfb0fe936a79","0x80dc84da5603df4f83912e8dc86071da9b255f9797a912c5e0a5679f894321fe","0x464125e8bf0d383d37f2a52157e9cba9e902f40f0c69f584bddd3ad4a4535876","0xd9b9a3c2c1963e1144dbba0036a80de2d8d668f5f11ffb888da1ec0cbbfe3bb8","0xf372a2bcc3d6b684eb4ecb77800e467d7ab8d77a3d839d1b245dc8925b5045d8","0x61305ed5ad02d114519ba48786e1371e39236a54288e0fc6a30e284fbf49aa44","0xf03bba853af13c6d3b29fc59aca4711f4ac2af792095e904ea118b7dbafca9c8","0xb5299512ce88aa17bd8043a3f9ff344fa9dee79968f4c88b5c05da50a8fb7c62","0x52ece6748ef43a9a849241919cb648decb913be19ab7e6ddb612b6e034aa796f","0x20d7bd5dade8f0b6a248c337a398421f5deab2693cec73cab58a35d8f4d166b3","0x90d85bac070ec7a932fc3dc0582bdc9abe406a9bf7f83117869feaa2909a3fb5","0xc7e9bf5800f46439a36ce3b38b0c6189f0a0353d7a1939368dfb141e2c429669","0xeaf20452be64a379c527a54a8d56114137b7c95a24725aef0ccf90c8b8720a31","0xf434c5f0fd080e7a119df6fcb5f822a0e8e4d65a3a86dbe41747af1aebed8c11","0xe0aa2192fa41980296b947de91ff945d3eb445d5331f6642718acddaebe83538","0x923ba01d85601fd1df4a49539806387482551abd591bb9f69e876e73ef91a653","0xb714976b7454a9e9dd32f831efdcc8cc1af557e0dcbc89672e0a0e109cff748a","0x0665a61b3da153f1c9d8658bf246ce242d07372226030ff06eba0d8f27272083"]} diff --git a/cmd/workload/testsuite.go b/cmd/workload/testsuite.go new file mode 100644 index 0000000000..3e3ea1d001 --- /dev/null +++ b/cmd/workload/testsuite.go @@ -0,0 +1,145 @@ +// 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 main + +import ( + "embed" + "io/fs" + "os" + "slices" + + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/internal/utesting" + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" +) + +//go:embed queries +var builtinTestFiles embed.FS + +var ( + runTestCommand = &cli.Command{ + Name: "test", + Usage: "Runs workload tests against an RPC endpoint", + ArgsUsage: "", + Action: runTestCmd, + Flags: []cli.Flag{ + testPatternFlag, + testTAPFlag, + testSlowFlag, + testSepoliaFlag, + testMainnetFlag, + filterQueryFileFlag, + historyTestFileFlag, + }, + } + testPatternFlag = &cli.StringFlag{ + Name: "run", + Usage: "Pattern of test suite(s) to run", + Category: flags.TestingCategory, + } + testTAPFlag = &cli.BoolFlag{ + Name: "tap", + Usage: "Output test results in TAP format", + Category: flags.TestingCategory, + } + testSlowFlag = &cli.BoolFlag{ + Name: "slow", + Usage: "Enable slow tests", + Value: false, + Category: flags.TestingCategory, + } + testSepoliaFlag = &cli.BoolFlag{ + Name: "sepolia", + Usage: "Use test cases for sepolia network", + Category: flags.TestingCategory, + } + testMainnetFlag = &cli.BoolFlag{ + Name: "mainnet", + Usage: "Use test cases for mainnet network", + Category: flags.TestingCategory, + } +) + +// testConfig holds the parameters for testing. +type testConfig struct { + client *client + fsys fs.FS + filterQueryFile string + historyTestFile string +} + +func testConfigFromCLI(ctx *cli.Context) (cfg testConfig) { + flags.CheckExclusive(ctx, testMainnetFlag, testSepoliaFlag) + if (ctx.IsSet(testMainnetFlag.Name) || ctx.IsSet(testSepoliaFlag.Name)) && ctx.IsSet(filterQueryFileFlag.Name) { + exit(filterQueryFileFlag.Name + " cannot be used with " + testMainnetFlag.Name + " or " + testSepoliaFlag.Name) + } + + // configure ethclient + cfg.client = makeClient(ctx) + + // configure test files + switch { + case ctx.Bool(testMainnetFlag.Name): + cfg.fsys = builtinTestFiles + cfg.filterQueryFile = "queries/filter_queries_mainnet.json" + cfg.historyTestFile = "queries/history_mainnet.json" + case ctx.Bool(testSepoliaFlag.Name): + cfg.fsys = builtinTestFiles + cfg.filterQueryFile = "queries/filter_queries_sepolia.json" + cfg.historyTestFile = "queries/history_sepolia.json" + default: + cfg.fsys = os.DirFS(".") + cfg.filterQueryFile = ctx.String(filterQueryFileFlag.Name) + cfg.historyTestFile = ctx.String(historyTestFileFlag.Name) + } + return cfg +} + +func runTestCmd(ctx *cli.Context) error { + cfg := testConfigFromCLI(ctx) + filterSuite := newFilterTestSuite(cfg) + historySuite := newHistoryTestSuite(cfg) + + // Filter test cases. + tests := filterSuite.allTests() + tests = append(tests, historySuite.allTests()...) + if ctx.IsSet(testPatternFlag.Name) { + tests = utesting.MatchTests(tests, ctx.String(testPatternFlag.Name)) + } + if !ctx.Bool(testSlowFlag.Name) { + tests = slices.DeleteFunc(tests, func(test utesting.Test) bool { + return test.Slow + }) + } + + // Disable logging unless explicitly enabled. + if !ctx.IsSet("verbosity") && !ctx.IsSet("vmodule") { + log.SetDefault(log.NewLogger(log.DiscardHandler())) + } + + // Run the tests. + var run = utesting.RunTests + if ctx.Bool(testTAPFlag.Name) { + run = utesting.RunTAP + } + results := run(tests, os.Stdout) + if utesting.CountFailures(results) > 0 { + os.Exit(1) + } + return nil +} diff --git a/internal/flags/helpers.go b/internal/flags/helpers.go index 170b67b310..fc84ae85da 100644 --- a/internal/flags/helpers.go +++ b/internal/flags/helpers.go @@ -295,3 +295,45 @@ func CheckEnvVars(ctx *cli.Context, flags []cli.Flag, prefix string) { } } } + +// CheckExclusive verifies that only a single instance of the provided flags was +// set by the user. Each flag might optionally be followed by a string type to +// specialize it further. +func CheckExclusive(ctx *cli.Context, args ...any) { + set := make([]string, 0, 1) + for i := 0; i < len(args); i++ { + // Make sure the next argument is a flag and skip if not set + flag, ok := args[i].(cli.Flag) + if !ok { + panic(fmt.Sprintf("invalid argument, not cli.Flag type: %T", args[i])) + } + // Check if next arg extends current and expand its name if so + name := flag.Names()[0] + + if i+1 < len(args) { + switch option := args[i+1].(type) { + case string: + // Extended flag check, make sure value set doesn't conflict with passed in option + if ctx.String(flag.Names()[0]) == option { + name += "=" + option + set = append(set, "--"+name) + } + // shift arguments and continue + i++ + continue + + case cli.Flag: + default: + panic(fmt.Sprintf("invalid argument, not cli.Flag or string extension: %T", args[i+1])) + } + } + // Mark the flag if it's set + if ctx.IsSet(flag.Names()[0]) { + set = append(set, "--"+name) + } + } + if len(set) > 1 { + fmt.Fprintf(os.Stderr, "Flags %v can't be used at the same time", strings.Join(set, ", ")) + os.Exit(1) + } +} From 1d2043e806cb70905619e0b11e5d4a5d73388000 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Thu, 27 Feb 2025 00:40:35 -0700 Subject: [PATCH 155/940] eth/gasprice: sanity check ratio values (#31270) Follow on to #31246. Adds a sanity check in the test to make sure the ratio value never goes over 1. Would have avoided the issue in #31245. --- eth/gasprice/feehistory_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eth/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go index 241b91b810..d220027e69 100644 --- a/eth/gasprice/feehistory_test.go +++ b/eth/gasprice/feehistory_test.go @@ -84,9 +84,19 @@ 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)) } + for _, ratio := range ratio { + if ratio > 1 { + t.Fatalf("Test case %d: gasUsedRatio greater than 1, got %f", i, ratio) + } + } if len(blobRatio) != c.expCount { t.Fatalf("Test case %d: blobGasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(blobRatio)) } + for _, ratio := range blobRatio { + if ratio > 1 { + t.Fatalf("Test case %d: blobGasUsedRatio greater than 1, got %f", i, ratio) + } + } if len(blobBaseFee) != len(baseFee) { t.Fatalf("Test case %d: blobBaseFee array length mismatch, want %d, got %d", i, len(baseFee), len(blobBaseFee)) } From fc4dd183e9327af9b5443fdea0bfbf68f041826e Mon Sep 17 00:00:00 2001 From: buddho Date: Thu, 27 Feb 2025 17:08:33 +0800 Subject: [PATCH 156/940] core/txpool: fix error logs flood caused by removeAuthorities (#31249) when remove an non-SetCodeTxType transaction, error logs flood ``` t=2025-02-25T03:11:06+0000 lvl=error msg="Authority with untracked tx" addr=0xD5bf9221fCB1C31Cd1EE477a60c148d40dD63DC1 hash=0x626fdf205a5b1619deb2f9e51fed567353f80acbd522265b455daa0821c571d9 ``` in this PR, only try to removeAuthorities for txs with SetCodeTxType in addition, the performance of removeAuthorities improved a lot, because no need range all `t.auths` now. --------- Co-authored-by: lightclient --- core/txpool/legacypool/legacypool.go | 7 ++-- core/txpool/legacypool/legacypool_test.go | 44 +++++++++++++++++++++++ core/types/transaction.go | 12 +++++-- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 4250283b03..0fda56986e 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1765,12 +1765,12 @@ func (t *lookup) Remove(hash common.Hash) { t.lock.Lock() defer t.lock.Unlock() - t.removeAuthorities(hash) tx, ok := t.txs[hash] if !ok { log.Error("No transaction found to be deleted", "hash", hash) return } + t.removeAuthorities(tx) t.slots -= numSlots(tx) slotsGauge.Update(int64(t.slots)) @@ -1808,8 +1808,9 @@ func (t *lookup) addAuthorities(tx *types.Transaction) { // removeAuthorities stops tracking the supplied tx in relation to its // authorities. -func (t *lookup) removeAuthorities(hash common.Hash) { - for addr := range t.auths { +func (t *lookup) removeAuthorities(tx *types.Transaction) { + hash := tx.Hash() + for _, addr := range tx.SetCodeAuthorities() { list := t.auths[addr] // Remove tx from tracker. if i := slices.Index(list, hash); i >= 0 { diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index b2a068467f..ef887041ad 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -23,6 +23,7 @@ import ( "fmt" "math/big" "math/rand" + "slices" "sync" "sync/atomic" "testing" @@ -238,6 +239,23 @@ func validatePoolInternals(pool *LegacyPool) error { return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1) } } + // Ensure all auths in pool are tracked + for _, tx := range pool.all.txs { + for _, addr := range tx.SetCodeAuthorities() { + list := pool.all.auths[addr] + if i := slices.Index(list, tx.Hash()); i < 0 { + return fmt.Errorf("authority not tracked: addr %s, tx %s", addr, tx.Hash()) + } + } + } + // Ensure all auths in pool have an associated tx. + for addr, hashes := range pool.all.auths { + for _, hash := range hashes { + if _, ok := pool.all.txs[hash]; !ok { + return fmt.Errorf("dangling authority, missing originating tx: addr %s, hash %s", addr, hash.Hex()) + } + } + } return nil } @@ -2381,6 +2399,32 @@ func TestSetCodeTransactions(t *testing.T) { } }, }, + { + name: "remove-hash-from-authority-tracker", + pending: 10, + run: func(name string) { + var keys []*ecdsa.PrivateKey + for i := 0; i < 30; i++ { + key, _ := crypto.GenerateKey() + keys = append(keys, key) + addr := crypto.PubkeyToAddress(key.PublicKey) + testAddBalance(pool, addr, big.NewInt(params.Ether)) + } + // Create a transactions with 3 unique auths so the lookup's auth map is + // filled with addresses. + for i := 0; i < 30; i += 3 { + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keys[i], []unsignedAuth{{0, keys[i]}, {0, keys[i+1]}, {0, keys[i+2]}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + } + // Replace one of the transactions with a normal transaction so that the + // original hash is removed from the tracker. The hash should be + // associated with 3 different authorities. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keys[0])); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } + }, + }, } { tt.run(tt.name) pending, queued := pool.Stats() diff --git a/core/types/transaction.go b/core/types/transaction.go index 7df13e04bb..4e48248b4a 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -483,15 +483,23 @@ func (tx *Transaction) SetCodeAuthorizations() []SetCodeAuthorization { return setcodetx.AuthList } -// SetCodeAuthorities returns a list of each authorization's corresponding authority. +// SetCodeAuthorities returns a list of unique authorities from the +// authorization list. func (tx *Transaction) SetCodeAuthorities() []common.Address { setcodetx, ok := tx.inner.(*SetCodeTx) if !ok { return nil } - auths := make([]common.Address, 0, len(setcodetx.AuthList)) + var ( + marks = make(map[common.Address]bool) + auths = make([]common.Address, 0, len(setcodetx.AuthList)) + ) for _, auth := range setcodetx.AuthList { if addr, err := auth.Authority(); err == nil { + if marks[addr] { + continue + } + marks[addr] = true auths = append(auths, addr) } } From fa16d497bcf45719edf9e4e7a1823449f6562ea8 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 27 Feb 2025 12:07:36 +0100 Subject: [PATCH 157/940] build: update PPA Go bootstrap version to 1.23 (#31282) This is for fixing the PPA build, which has been failing since the update to Go 1.24. In Go 1.24, the required Go version for bootstrapping was updated to 1.22. In general, they are following through with always depending on the Go version two releases ago for bootstrapping. Since we still support Ubuntu Xenial (16.04) until its EOL date of 04/2026, and Xenial only has golang 1.10 as a package, we now need to build Go a total of four times to get the most recent version. I'm adding a step for Go 1.23 here. This should last us until Go 1.25, which should be out around 04/2026, and we can hopefully drop the first bootstrapping step at that time. --- build/checksums.txt | 8 ++++++-- build/ci.go | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index 1646cc6c45..c8b742e443 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -114,14 +114,18 @@ fc43f8c95d6bec8ba9a3557a0bb63cf9f504137ce6d24cfdc4c330d46f7779d2 golangci-lint- # 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. # -# version:ppa-builder-1 1.19.6 +# version:ppa-builder-1.19 1.19.6 # https://go.dev/dl/ d7f0013f82e6d7f862cc6cb5c8cdb48eef5f2e239b35baa97e2f1a7466043767 go1.19.6.src.tar.gz -# version:ppa-builder-2 1.21.9 +# version:ppa-builder-1.21 1.21.9 # https://go.dev/dl/ 58f0c5ced45a0012bce2ff7a9df03e128abcc8818ebabe5027bb92bafe20e421 go1.21.9.src.tar.gz +# version:ppa-builder-1.23 1.23.6 +# https://go.dev/dl/ +039c5b04e65279daceee8a6f71e70bd05cf5b801782b6f77c6e19e2ed0511222 go1.23.6.src.tar.gz + # version:protoc 27.1 # https://github.com/protocolbuffers/protobuf/releases/ # https://github.com/protocolbuffers/protobuf/releases/download/v27.1/ diff --git a/build/ci.go b/build/ci.go index fbf739e476..6203af98ba 100644 --- a/build/ci.go +++ b/build/ci.go @@ -843,7 +843,7 @@ func downloadGoBootstrapSources(cachedir string) []string { csdb := build.MustLoadChecksums("build/checksums.txt") var bundles []string - for _, booter := range []string{"ppa-builder-1", "ppa-builder-2"} { + for _, booter := range []string{"ppa-builder-1.19", "ppa-builder-1.21", "ppa-builder-1.23"} { gobootVersion, err := build.Version(csdb, booter) if err != nil { log.Fatal(err) From f005d95b55a3cc1d3c017ec19e949e842aaf0c33 Mon Sep 17 00:00:00 2001 From: Shude Li Date: Thu, 27 Feb 2025 22:52:00 +0800 Subject: [PATCH 158/940] build: simplify go mod tidy check (#31266) This changes the go mod tidy check to use the go mod tidy -diff command, removing the custom diffing for go.mod. The check for go.mod/go.sum is now performed in the check_generate action. Also included is a change where check_generate and check_baddeps will now run on the GitHub Actions lint step. --------- Co-authored-by: Felix Lange --- .github/workflows/go.yml | 2 +- appveyor.yml | 1 - build/ci.go | 28 +++++++--------------------- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4da92f2431..78410aab10 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -29,7 +29,7 @@ jobs: - name: Run linters run: | go run build/ci.go lint - go run build/ci.go check_tidy + go run build/ci.go check_generate go run build/ci.go check_baddeps build: diff --git a/appveyor.yml b/appveyor.yml index 1543211edc..ae1c74c18e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,7 +24,6 @@ for: - image: Ubuntu build_script: - go run build/ci.go lint - - go run build/ci.go check_tidy - go run build/ci.go check_generate - go run build/ci.go check_baddeps - go run build/ci.go install -dlgo diff --git a/build/ci.go b/build/ci.go index 6203af98ba..b2ff829d3f 100644 --- a/build/ci.go +++ b/build/ci.go @@ -25,8 +25,7 @@ Usage: go run build/ci.go Available commands are: lint -- runs certain pre-selected linters - check_tidy -- verifies that everything is 'go mod tidy'-ed - check_generate -- verifies that everything is 'go generate'-ed + check_generate -- verifies that 'go generate' and 'go mod tidy' do not produce changes check_baddeps -- verifies that certain dependencies are avoided install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables @@ -155,8 +154,6 @@ func main() { doTest(os.Args[2:]) case "lint": doLint(os.Args[2:]) - case "check_tidy": - doCheckTidy() case "check_generate": doCheckGenerate() case "check_baddeps": @@ -352,22 +349,6 @@ func downloadSpecTestFixtures(csdb *build.ChecksumDB, cachedir string) string { // doCheckTidy assets that the Go modules files are tidied already. func doCheckTidy() { - targets := []string{"go.mod", "go.sum"} - - hashes, err := build.HashFiles(targets) - if err != nil { - log.Fatalf("failed to hash go.mod/go.sum: %v", err) - } - build.MustRun(new(build.GoToolchain).Go("mod", "tidy")) - - tidied, err := build.HashFiles(targets) - if err != nil { - log.Fatalf("failed to rehash go.mod/go.sum: %v", err) - } - if updates := build.DiffHashes(hashes, tidied); len(updates) > 0 { - log.Fatalf("files changed on running 'go mod tidy': %v", updates) - } - fmt.Println("No untidy module files detected.") } // doCheckGenerate ensures that re-generating generated files does not cause @@ -375,6 +356,7 @@ func doCheckTidy() { func doCheckGenerate() { var ( cachedir = flag.String("cachedir", "./build/cache", "directory for caching binaries.") + tc = new(build.GoToolchain) ) // Compute the origin hashes of all the files var hashes map[string][32]byte @@ -389,7 +371,7 @@ func doCheckGenerate() { protocPath = downloadProtoc(*cachedir) protocGenGoPath = downloadProtocGenGo(*cachedir) ) - c := new(build.GoToolchain).Go("generate", "./...") + 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) @@ -407,6 +389,10 @@ func doCheckGenerate() { log.Fatal("One or more generated files were updated by running 'go generate ./...'") } fmt.Println("No stale files detected.") + + // Run go mod tidy check. + build.MustRun(tc.Go("mod", "tidy", "-diff")) + fmt.Println("No untidy module files detected.") } // doCheckBadDeps verifies whether certain unintended dependencies between some From 767c202e4779536f4d9d862080304f20d9514371 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Thu, 27 Feb 2025 15:53:52 +0100 Subject: [PATCH 159/940] all: drop x/exp direct dependency (#30558) This is a not-particularly-important "cleanliness" PR. It removes the last remnants of the `x/exp` package, where we used the `maps.Keys` function. The original returned the keys in a slice, but when it became 'native' the signature changed to return an iterator, so the new idiom is `slices.Collect(maps.Keys(theMap))`, unless of course the raw iterator can be used instead. In some cases, where we previously collect into slice and then sort, we can now instead do `slices.SortXX` on the iterator instead, making the code a bit more concise. This PR might be _slighly_ less optimal, because the original `x/exp` implementation allocated the slice at the correct size off the bat, which I suppose the new code won't. Putting it up for discussion. --------- Co-authored-by: Felix Lange --- cmd/devp2p/internal/ethtest/chain.go | 6 +++--- cmd/evm/blockrunner.go | 5 ++--- core/state/snapshot/difflayer.go | 8 +++----- core/txpool/blobpool/evictheap.go | 5 ++--- core/txpool/legacypool/legacypool.go | 4 ++-- core/txpool/locals/tx_tracker.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- p2p/netutil/net.go | 6 ++---- triedb/pathdb/history.go | 10 +++------- triedb/pathdb/states.go | 8 +++----- 11 files changed, 24 insertions(+), 36 deletions(-) diff --git a/cmd/devp2p/internal/ethtest/chain.go b/cmd/devp2p/internal/ethtest/chain.go index a90c53c432..689667a56b 100644 --- a/cmd/devp2p/internal/ethtest/chain.go +++ b/cmd/devp2p/internal/ethtest/chain.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "io" + "maps" "math/big" "os" "path/filepath" @@ -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/maps" ) // Chain is a lightweight blockchain-like store which can read a hivechain @@ -162,8 +162,8 @@ func (c *Chain) RootAt(height int) common.Hash { // GetSender returns the address associated with account at the index in the // pre-funded accounts list. func (c *Chain) GetSender(idx int) (common.Address, uint64) { - accounts := maps.Keys(c.senders) - slices.SortFunc(accounts, common.Address.Cmp) + accounts := slices.SortedFunc(maps.Keys(c.senders), common.Address.Cmp) + addr := accounts[idx] return addr, c.senders[addr].Nonce } diff --git a/cmd/evm/blockrunner.go b/cmd/evm/blockrunner.go index 9a04807b33..31d1ba5ba1 100644 --- a/cmd/evm/blockrunner.go +++ b/cmd/evm/blockrunner.go @@ -20,6 +20,7 @@ import ( "encoding/json" "errors" "fmt" + "maps" "os" "regexp" "slices" @@ -28,7 +29,6 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/tests" "github.com/urfave/cli/v2" - "golang.org/x/exp/maps" ) var blockTestCommand = &cli.Command{ @@ -80,8 +80,7 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) { tracer := tracerFromFlags(ctx) // Pull out keys to sort and ensure tests are run in order. - keys := maps.Keys(tests) - slices.Sort(keys) + keys := slices.Sorted(maps.Keys(tests)) // Run all the tests. var results []testResult diff --git a/core/state/snapshot/difflayer.go b/core/state/snapshot/difflayer.go index dce4f79a11..28957051d4 100644 --- a/core/state/snapshot/difflayer.go +++ b/core/state/snapshot/difflayer.go @@ -19,6 +19,7 @@ package snapshot import ( "encoding/binary" "fmt" + "maps" "math" "math/rand" "slices" @@ -30,7 +31,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/maps" ) var ( @@ -431,8 +431,7 @@ func (dl *diffLayer) AccountList() []common.Hash { dl.lock.Lock() defer dl.lock.Unlock() - dl.accountList = maps.Keys(dl.accountData) - slices.SortFunc(dl.accountList, common.Hash.Cmp) + dl.accountList = slices.SortedFunc(maps.Keys(dl.accountData), common.Hash.Cmp) dl.memory += uint64(len(dl.accountList) * common.HashLength) return dl.accountList } @@ -464,8 +463,7 @@ func (dl *diffLayer) StorageList(accountHash common.Hash) []common.Hash { dl.lock.Lock() defer dl.lock.Unlock() - storageList := maps.Keys(dl.storageData[accountHash]) - slices.SortFunc(storageList, common.Hash.Cmp) + storageList := slices.SortedFunc(maps.Keys(dl.storageData[accountHash]), common.Hash.Cmp) dl.storageList[accountHash] = storageList dl.memory += uint64(len(dl.storageList)*common.HashLength + common.HashLength) return storageList diff --git a/core/txpool/blobpool/evictheap.go b/core/txpool/blobpool/evictheap.go index 5e285e6c53..722a71bc9b 100644 --- a/core/txpool/blobpool/evictheap.go +++ b/core/txpool/blobpool/evictheap.go @@ -18,12 +18,12 @@ package blobpool import ( "container/heap" + "maps" "math" "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 @@ -54,8 +54,7 @@ func newPriceHeap(basefee *uint256.Int, blobfee *uint256.Int, index map[common.A // 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. - heap.addrs = maps.Keys(index) - slices.SortFunc(heap.addrs, common.Address.Cmp) + heap.addrs = slices.SortedFunc(maps.Keys(index), common.Address.Cmp) for i, addr := range heap.addrs { heap.index[addr] = i } diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 0fda56986e..fb10060496 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -19,6 +19,7 @@ package legacypool import ( "errors" + "maps" "math" "math/big" "slices" @@ -40,7 +41,6 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" - "golang.org/x/exp/maps" ) const ( @@ -1674,7 +1674,7 @@ 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 { - as.cache = maps.Keys(as.accounts) + as.cache = slices.Collect(maps.Keys(as.accounts)) } return as.cache } diff --git a/core/txpool/locals/tx_tracker.go b/core/txpool/locals/tx_tracker.go index a24fcb1f4e..0113646669 100644 --- a/core/txpool/locals/tx_tracker.go +++ b/core/txpool/locals/tx_tracker.go @@ -18,6 +18,7 @@ package locals import ( + "slices" "sync" "time" @@ -28,7 +29,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" - "golang.org/x/exp/slices" ) var ( diff --git a/go.mod b/go.mod index e58d8fd828..ba26f2150e 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,6 @@ require ( go.uber.org/automaxprocs v1.5.2 go.uber.org/goleak v1.3.0 golang.org/x/crypto v0.32.0 - golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/sync v0.10.0 golang.org/x/sys v0.29.0 golang.org/x/text v0.21.0 @@ -142,6 +141,7 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.34.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 0dbd79cfaa..1e4efeb697 100644 --- a/go.sum +++ b/go.sum @@ -553,8 +553,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/p2p/netutil/net.go b/p2p/netutil/net.go index 7d8da88670..696c331859 100644 --- a/p2p/netutil/net.go +++ b/p2p/netutil/net.go @@ -21,12 +21,11 @@ import ( "bytes" "errors" "fmt" + "maps" "net" "net/netip" "slices" "strings" - - "golang.org/x/exp/maps" ) var special4, special6 Netlist @@ -324,8 +323,7 @@ func (s *DistinctNetSet) key(ip netip.Addr) netip.Prefix { // String implements fmt.Stringer func (s DistinctNetSet) String() string { - keys := maps.Keys(s.members) - slices.SortFunc(keys, func(a, b netip.Prefix) int { + keys := slices.SortedFunc(maps.Keys(s.members), func(a, b netip.Prefix) int { return strings.Compare(a.String(), b.String()) }) diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index 6ba9aaf1bb..c063e45371 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -21,6 +21,7 @@ import ( "encoding/binary" "errors" "fmt" + "maps" "slices" "time" @@ -29,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" - "golang.org/x/exp/maps" ) // State history records the state changes involved in executing a block. The @@ -250,15 +250,11 @@ type history struct { // newHistory constructs the state history object with provided state change set. func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *history { var ( - accountList = maps.Keys(accounts) + accountList = slices.SortedFunc(maps.Keys(accounts), common.Address.Cmp) storageList = make(map[common.Address][]common.Hash) ) - slices.SortFunc(accountList, common.Address.Cmp) - for addr, slots := range storages { - slist := maps.Keys(slots) - slices.SortFunc(slist, common.Hash.Cmp) - storageList[addr] = slist + storageList[addr] = slices.SortedFunc(maps.Keys(slots), common.Hash.Cmp) } version := historyVersion if !rawStorageKey { diff --git a/triedb/pathdb/states.go b/triedb/pathdb/states.go index 873a7ba618..0a83b2f2cc 100644 --- a/triedb/pathdb/states.go +++ b/triedb/pathdb/states.go @@ -19,6 +19,7 @@ package pathdb import ( "fmt" "io" + "maps" "slices" "sync" @@ -27,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/exp/maps" ) // counter helps in tracking items and their corresponding sizes. @@ -174,8 +174,7 @@ func (s *stateSet) accountList() []common.Hash { s.listLock.Lock() defer s.listLock.Unlock() - list = maps.Keys(s.accountData) - slices.SortFunc(list, common.Hash.Cmp) + list = slices.SortedFunc(maps.Keys(s.accountData), common.Hash.Cmp) s.accountListSorted = list return list } @@ -205,8 +204,7 @@ func (s *stateSet) storageList(accountHash common.Hash) []common.Hash { s.listLock.Lock() defer s.listLock.Unlock() - list := maps.Keys(s.storageData[accountHash]) - slices.SortFunc(list, common.Hash.Cmp) + list := slices.SortedFunc(maps.Keys(s.storageData[accountHash]), common.Hash.Cmp) s.storageListSorted[accountHash] = list return list } From 6c286beb39f61c9457c19deb0aa90bb172d80505 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 27 Feb 2025 17:52:22 +0100 Subject: [PATCH 160/940] build/deb: add step for new Go bootstrap to debian rules (#31283) Next attempt at fixing the build on launchpad.net --- build/deb/ethereum/deb.rules | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/deb/ethereum/deb.rules b/build/deb/ethereum/deb.rules index 3287e15ff0..5905ad50a7 100644 --- a/build/deb/ethereum/deb.rules +++ b/build/deb/ethereum/deb.rules @@ -21,7 +21,8 @@ override_dh_auto_build: # requirements opposed to older versions of Go. (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) + (mv .goboot-3 ../ && cd ../.goboot-3/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot-2 ./make.bash) + (mv .go ../ && cd ../.go/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot-3 ./make.bash) # We can't download external go modules within Launchpad, so we're shipping the # entire dependency source cache with go-ethereum. From e1e326e069e4238dd624557a00c24a485fc1fd8d Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Fri, 28 Feb 2025 06:53:56 -0500 Subject: [PATCH 161/940] core/tracing: stringer for gas and nonce change reasons (#31234) --- core/state/statedb_hooked_test.go | 4 +- .../gen_balance_change_reason_stringer.go | 6 +-- .../tracing/gen_gas_change_reason_stringer.go | 52 +++++++++++++++++++ .../gen_nonce_change_reason_stringer.go | 29 +++++++++++ core/tracing/hooks.go | 6 ++- 5 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 core/tracing/gen_gas_change_reason_stringer.go create mode 100644 core/tracing/gen_nonce_change_reason_stringer.go diff --git a/core/state/statedb_hooked_test.go b/core/state/statedb_hooked_test.go index ce42e96409..f319b0e63c 100644 --- a/core/state/statedb_hooked_test.go +++ b/core/state/statedb_hooked_test.go @@ -83,8 +83,8 @@ func TestHooks(t *testing.T) { inner.SetTxContext(common.Hash{0x11}, 100) // For the log var result []string var wants = []string{ - "0xaa00000000000000000000000000000000000000.balance: 0->100 (BalanceChangeUnspecified)", - "0xaa00000000000000000000000000000000000000.balance: 100->50 (BalanceChangeTransfer)", + "0xaa00000000000000000000000000000000000000.balance: 0->100 (Unspecified)", + "0xaa00000000000000000000000000000000000000.balance: 100->50 (Transfer)", "0xaa00000000000000000000000000000000000000.nonce: 0->1337", "0xaa00000000000000000000000000000000000000.code: (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) ->0x1325 (0xa12ae05590de0c93a00bc7ac773c2fdb621e44f814985e72194f921c0050f728)", "0xaa00000000000000000000000000000000000000.storage slot 0x0000000000000000000000000000000000000000000000000000000000000001: 0x0000000000000000000000000000000000000000000000000000000000000000 ->0x0000000000000000000000000000000000000000000000000000000000000011", diff --git a/core/tracing/gen_balance_change_reason_stringer.go b/core/tracing/gen_balance_change_reason_stringer.go index 4f094efb4f..250b521193 100644 --- a/core/tracing/gen_balance_change_reason_stringer.go +++ b/core/tracing/gen_balance_change_reason_stringer.go @@ -1,4 +1,4 @@ -// Code generated by "stringer -type=BalanceChangeReason -output gen_balance_change_reason_stringer.go"; DO NOT EDIT. +// Code generated by "stringer -type=BalanceChangeReason -trimprefix=BalanceChange -output gen_balance_change_reason_stringer.go"; DO NOT EDIT. package tracing @@ -26,9 +26,9 @@ func _() { _ = x[BalanceChangeRevert-15] } -const _BalanceChangeReason_name = "BalanceChangeUnspecifiedBalanceIncreaseRewardMineUncleBalanceIncreaseRewardMineBlockBalanceIncreaseWithdrawalBalanceIncreaseGenesisBalanceBalanceIncreaseRewardTransactionFeeBalanceDecreaseGasBuyBalanceIncreaseGasReturnBalanceIncreaseDaoContractBalanceDecreaseDaoAccountBalanceChangeTransferBalanceChangeTouchAccountBalanceIncreaseSelfdestructBalanceDecreaseSelfdestructBalanceDecreaseSelfdestructBurnBalanceChangeRevert" +const _BalanceChangeReason_name = "UnspecifiedBalanceIncreaseRewardMineUncleBalanceIncreaseRewardMineBlockBalanceIncreaseWithdrawalBalanceIncreaseGenesisBalanceBalanceIncreaseRewardTransactionFeeBalanceDecreaseGasBuyBalanceIncreaseGasReturnBalanceIncreaseDaoContractBalanceDecreaseDaoAccountTransferTouchAccountBalanceIncreaseSelfdestructBalanceDecreaseSelfdestructBalanceDecreaseSelfdestructBurnRevert" -var _BalanceChangeReason_index = [...]uint16{0, 24, 54, 84, 109, 138, 173, 194, 218, 244, 269, 290, 315, 342, 369, 400, 419} +var _BalanceChangeReason_index = [...]uint16{0, 11, 41, 71, 96, 125, 160, 181, 205, 231, 256, 264, 276, 303, 330, 361, 367} func (i BalanceChangeReason) String() string { if i >= BalanceChangeReason(len(_BalanceChangeReason_index)-1) { diff --git a/core/tracing/gen_gas_change_reason_stringer.go b/core/tracing/gen_gas_change_reason_stringer.go new file mode 100644 index 0000000000..e64be781a6 --- /dev/null +++ b/core/tracing/gen_gas_change_reason_stringer.go @@ -0,0 +1,52 @@ +// Code generated by "stringer -type=GasChangeReason -trimprefix=GasChange -output gen_gas_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[GasChangeUnspecified-0] + _ = x[GasChangeTxInitialBalance-1] + _ = x[GasChangeTxIntrinsicGas-2] + _ = x[GasChangeTxRefunds-3] + _ = x[GasChangeTxLeftOverReturned-4] + _ = x[GasChangeCallInitialBalance-5] + _ = x[GasChangeCallLeftOverReturned-6] + _ = x[GasChangeCallLeftOverRefunded-7] + _ = x[GasChangeCallContractCreation-8] + _ = x[GasChangeCallContractCreation2-9] + _ = x[GasChangeCallCodeStorage-10] + _ = x[GasChangeCallOpCode-11] + _ = x[GasChangeCallPrecompiledContract-12] + _ = x[GasChangeCallStorageColdAccess-13] + _ = x[GasChangeCallFailedExecution-14] + _ = x[GasChangeWitnessContractInit-15] + _ = x[GasChangeWitnessContractCreation-16] + _ = x[GasChangeWitnessCodeChunk-17] + _ = x[GasChangeWitnessContractCollisionCheck-18] + _ = x[GasChangeTxDataFloor-19] + _ = x[GasChangeIgnored-255] +} + +const ( + _GasChangeReason_name_0 = "UnspecifiedTxInitialBalanceTxIntrinsicGasTxRefundsTxLeftOverReturnedCallInitialBalanceCallLeftOverReturnedCallLeftOverRefundedCallContractCreationCallContractCreation2CallCodeStorageCallOpCodeCallPrecompiledContractCallStorageColdAccessCallFailedExecutionWitnessContractInitWitnessContractCreationWitnessCodeChunkWitnessContractCollisionCheckTxDataFloor" + _GasChangeReason_name_1 = "Ignored" +) + +var ( + _GasChangeReason_index_0 = [...]uint16{0, 11, 27, 41, 50, 68, 86, 106, 126, 146, 167, 182, 192, 215, 236, 255, 274, 297, 313, 342, 353} +) + +func (i GasChangeReason) String() string { + switch { + case i <= 19: + return _GasChangeReason_name_0[_GasChangeReason_index_0[i]:_GasChangeReason_index_0[i+1]] + case i == 255: + return _GasChangeReason_name_1 + default: + return "GasChangeReason(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/core/tracing/gen_nonce_change_reason_stringer.go b/core/tracing/gen_nonce_change_reason_stringer.go new file mode 100644 index 0000000000..f775c1f3a6 --- /dev/null +++ b/core/tracing/gen_nonce_change_reason_stringer.go @@ -0,0 +1,29 @@ +// Code generated by "stringer -type=NonceChangeReason -trimprefix NonceChange -output gen_nonce_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[NonceChangeUnspecified-0] + _ = x[NonceChangeGenesis-1] + _ = x[NonceChangeEoACall-2] + _ = x[NonceChangeContractCreator-3] + _ = x[NonceChangeNewContract-4] + _ = x[NonceChangeAuthorization-5] + _ = x[NonceChangeRevert-6] +} + +const _NonceChangeReason_name = "UnspecifiedGenesisEoACallContractCreatorNewContractAuthorizationRevert" + +var _NonceChangeReason_index = [...]uint8{0, 11, 18, 25, 40, 51, 64, 70} + +func (i NonceChangeReason) String() string { + if i >= NonceChangeReason(len(_NonceChangeReason_index)-1) { + return "NonceChangeReason(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _NonceChangeReason_name[_NonceChangeReason_index[i]:_NonceChangeReason_index[i+1]] +} diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 4002b57207..0485f7a3eb 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -221,7 +221,7 @@ type Hooks struct { // 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 +//go:generate go run golang.org/x/tools/cmd/stringer -type=BalanceChangeReason -trimprefix=BalanceChange -output gen_balance_change_reason_stringer.go const ( BalanceChangeUnspecified BalanceChangeReason = 0 @@ -282,6 +282,8 @@ const ( // once per transaction, while those that start with `GasChangeCall` are emitted on a call basis. type GasChangeReason byte +//go:generate go run golang.org/x/tools/cmd/stringer -type=GasChangeReason -trimprefix=GasChange -output gen_gas_change_reason_stringer.go + const ( GasChangeUnspecified GasChangeReason = 0 @@ -346,6 +348,8 @@ const ( // NonceChangeReason is used to indicate the reason for a nonce change. type NonceChangeReason byte +//go:generate go run golang.org/x/tools/cmd/stringer -type=NonceChangeReason -trimprefix NonceChange -output gen_nonce_change_reason_stringer.go + const ( NonceChangeUnspecified NonceChangeReason = 0 From 4038c59845795a6b6b6a1ae834667b74ebae0aa4 Mon Sep 17 00:00:00 2001 From: Darioush Jalali Date: Fri, 28 Feb 2025 04:07:21 -0800 Subject: [PATCH 162/940] eth: remove EventMux accessors (#30017) Hi, it seems these methods in the `backend.go` and `api_backend.go` files are not used that expose the eventMux, but that is not needed. --- eth/api_backend.go | 4 ---- eth/backend.go | 1 - 2 files changed, 5 deletions(-) diff --git a/eth/api_backend.go b/eth/api_backend.go index 66621190dd..853c786775 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -368,10 +368,6 @@ func (b *EthAPIBackend) ChainDb() ethdb.Database { return b.eth.ChainDb() } -func (b *EthAPIBackend) EventMux() *event.TypeMux { - return b.eth.EventMux() -} - func (b *EthAPIBackend) AccountManager() *accounts.Manager { return b.eth.AccountManager() } diff --git a/eth/backend.go b/eth/backend.go index f3a8bf3078..4c0fd9e68b 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -345,7 +345,6 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } func (s *Ethereum) TxPool() *txpool.TxPool { return s.txPool } -func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) Engine() consensus.Engine { return s.engine } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } func (s *Ethereum) IsListening() bool { return true } // Always listening From ebc3232b49c10b249286016301842119b02e7878 Mon Sep 17 00:00:00 2001 From: Kuwon Sebastian Na Date: Sat, 1 Mar 2025 21:58:57 +0900 Subject: [PATCH 163/940] eth: do not add failed tx to localTxTracker (#31202) In transaction-sending APIs such as `eth_sendRawTransaction`, a submitted transaction failing the configured txpool validation rules (i.e. fee too low) would cause an error to be returned, even though the transaction was successfully added into the locals tracker. Once added there, the transaction may even be included into the chain at a later time, when fee market conditions change. This change improves on this by performing the validation in the locals tracker, basically skipping some of the validation rules for local transactions. We still try to add the tx to the main pool immediately, but an error will only be returned for transactions which are fundamentally invalid. --------- Co-authored-by: Gary Rong --- core/txpool/blobpool/blobpool.go | 19 ++++++++++++------- core/txpool/legacypool/legacypool.go | 11 ++++------- core/txpool/locals/tx_tracker.go | 26 ++++++++++++++++++++++---- core/txpool/subpool.go | 6 ++++++ core/txpool/txpool.go | 11 +++++++++++ eth/api_backend.go | 16 +++++++++++++--- 6 files changed, 68 insertions(+), 21 deletions(-) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 51b8b67c61..7ad95612bf 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1085,19 +1085,24 @@ func (p *BlobPool) SetGasTip(tip *big.Int) { p.updateStorageMetrics() } -// validateTx checks whether a transaction is valid according to the consensus -// rules and adheres to some heuristic limits of the local node (price and size). -func (p *BlobPool) validateTx(tx *types.Transaction) error { - // Ensure the transaction adheres to basic pool filters (type, size, tip) and - // consensus rules - baseOpts := &txpool.ValidationOptions{ +// ValidateTxBasics checks whether a transaction is valid according to the consensus +// rules, but does not check state-dependent validation such as sufficient balance. +// This check is meant as an early check which only needs to be performed once, +// and does not require the pool mutex to be held. +func (p *BlobPool) ValidateTxBasics(tx *types.Transaction) error { + opts := &txpool.ValidationOptions{ Config: p.chain.Config(), Accept: 1 << types.BlobTxType, MaxSize: txMaxSize, MinTip: p.gasTip.ToBig(), } + return txpool.ValidateTransaction(tx, p.head, p.signer, opts) +} - if err := p.txValidationFn(tx, p.head, p.signer, baseOpts); err != nil { +// validateTx checks whether a transaction is valid according to the consensus +// rules and adheres to some heuristic limits of the local node (price and size). +func (p *BlobPool) validateTx(tx *types.Transaction) error { + if err := p.ValidateTxBasics(tx); err != nil { return err } // Ensure the transaction adheres to the stateful pool filters (nonce, balance) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index fb10060496..1cc6856663 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -558,11 +558,11 @@ func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address] return pending } -// validateTxBasics checks whether a transaction is valid according to the consensus +// ValidateTxBasics checks whether a transaction is valid according to the consensus // rules, but does not check state-dependent validation such as sufficient balance. // This check is meant as an early check which only needs to be performed once, // and does not require the pool mutex to be held. -func (pool *LegacyPool) validateTxBasics(tx *types.Transaction) error { +func (pool *LegacyPool) ValidateTxBasics(tx *types.Transaction) error { opts := &txpool.ValidationOptions{ Config: pool.chainconfig, Accept: 0 | @@ -573,10 +573,7 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction) error { MaxSize: txMaxSize, MinTip: pool.gasTip.Load().ToBig(), } - if err := txpool.ValidateTransaction(tx, pool.currentHead.Load(), pool.signer, opts); err != nil { - return err - } - return nil + return txpool.ValidateTransaction(tx, pool.currentHead.Load(), pool.signer, opts) } // validateTx checks whether a transaction is valid according to the consensus @@ -929,7 +926,7 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, sync bool) []error { // Exclude transactions with basic errors, e.g invalid signatures and // insufficient intrinsic gas as soon as possible and cache senders // in transactions before obtaining lock - if err := pool.validateTxBasics(tx); err != nil { + if err := pool.ValidateTxBasics(tx); err != nil { errs[i] = err log.Trace("Discarding invalid transaction", "hash", tx.Hash(), "err", err) invalidTxMeter.Mark(1) diff --git a/core/txpool/locals/tx_tracker.go b/core/txpool/locals/tx_tracker.go index 0113646669..eccdcf422a 100644 --- a/core/txpool/locals/tx_tracker.go +++ b/core/txpool/locals/tx_tracker.go @@ -74,28 +74,45 @@ func New(journalPath string, journalTime time.Duration, chainConfig *params.Chai // Track adds a transaction to the tracked set. // Note: blob-type transactions are ignored. -func (tracker *TxTracker) Track(tx *types.Transaction) { - tracker.TrackAll([]*types.Transaction{tx}) +func (tracker *TxTracker) Track(tx *types.Transaction) error { + return tracker.TrackAll([]*types.Transaction{tx})[0] } // TrackAll adds a list of transactions to the tracked set. // Note: blob-type transactions are ignored. -func (tracker *TxTracker) TrackAll(txs []*types.Transaction) { +func (tracker *TxTracker) TrackAll(txs []*types.Transaction) []error { tracker.mu.Lock() defer tracker.mu.Unlock() + var errors []error for _, tx := range txs { if tx.Type() == types.BlobTxType { + errors = append(errors, nil) + continue + } + // Ignore the transactions which are failed for fundamental + // validation such as invalid parameters. + if err := tracker.pool.ValidateTxBasics(tx); err != nil { + log.Debug("Invalid transaction submitted", "hash", tx.Hash(), "err", err) + errors = append(errors, err) continue } // If we're already tracking it, it's a no-op if _, ok := tracker.all[tx.Hash()]; ok { + errors = append(errors, nil) continue } + // Theoretically, checking the error here is unnecessary since sender recovery + // is already part of basic validation. However, retrieving the sender address + // from the transaction cache is effectively a no-op if it was previously verified. + // Therefore, the error is still checked just in case. addr, err := types.Sender(tracker.signer, tx) - if err != nil { // Ignore this tx + if err != nil { + errors = append(errors, err) continue } + errors = append(errors, nil) + tracker.all[tx.Hash()] = tx if tracker.byAddr[addr] == nil { tracker.byAddr[addr] = legacypool.NewSortedMap() @@ -107,6 +124,7 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) { } } localGauge.Update(int64(len(tracker.all))) + return errors } // recheck checks and returns any transactions that needs to be resubmitted. diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 5ad0f5b0e0..242af02136 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -129,6 +129,12 @@ type SubPool interface { // retrieve blobs from the pools directly instead of the network. GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) + // ValidateTxBasics checks whether a transaction is valid according to the consensus + // rules, but does not check state-dependent validation such as sufficient balance. + // This check is meant as a static check which can be performed without holding the + // pool mutex. + ValidateTxBasics(tx *types.Transaction) error + // Add enqueues a batch of transactions into the pool if they are valid. Due // to the large transaction churn, add may postpone fully integrating the tx // to a later point to batch multiple ones together. diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 0ebf4c7e4b..55812415f9 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -325,6 +325,17 @@ func (p *TxPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Pr return nil, nil } +// ValidateTxBasics checks whether a transaction is valid according to the consensus +// rules, but does not check state-dependent validation such as sufficient balance. +func (p *TxPool) ValidateTxBasics(tx *types.Transaction) error { + for _, subpool := range p.subpools { + if subpool.Filter(tx) { + return subpool.ValidateTxBasics(tx) + } + } + return fmt.Errorf("%w: received type %d", core.ErrTxTypeNotSupported, tx.Type()) +} + // Add enqueues a batch of transactions into the pool if they are valid. Due // to the large transaction churn, add may postpone fully integrating the tx // to a later point to batch multiple ones together. diff --git a/eth/api_backend.go b/eth/api_backend.go index 853c786775..75b039dbe1 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -272,10 +272,20 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri } func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { - if locals := b.eth.localTxTracker; locals != nil { - locals.Track(signedTx) + locals := b.eth.localTxTracker + if locals != nil { + if err := locals.Track(signedTx); err != nil { + return err + } } - return b.eth.txPool.Add([]*types.Transaction{signedTx}, false)[0] + // No error will be returned to user if the transaction fails stateful + // validation (e.g., no available slot), as the locally submitted transactions + // may be resubmitted later via the local tracker. + err := b.eth.txPool.Add([]*types.Transaction{signedTx}, false)[0] + if err != nil && locals == nil { + return err + } + return nil } func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) { From d2bbde2f2d6b02152c2d102e0639eae8ce89f319 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Sat, 1 Mar 2025 14:10:38 +0100 Subject: [PATCH 164/940] eth: check blob transaction validity on the peer goroutine when received (#31219) This ensures that if we receive a blob transaction announcement where we cannot link the tx to the sidecar commitments, we will drop the sending peer. This check is added in the protocol handler for the PooledTransactions message. Tests for this have also been added in the cross-client "eth" protocol test suite. --------- Co-authored-by: Felix Lange --- cmd/devp2p/internal/ethtest/conn.go | 5 + cmd/devp2p/internal/ethtest/suite.go | 197 +++++++++++++++++++++++++++ core/txpool/validation.go | 14 +- core/types/tx_blob.go | 17 +++ eth/handler_eth.go | 13 ++ 5 files changed, 234 insertions(+), 12 deletions(-) diff --git a/cmd/devp2p/internal/ethtest/conn.go b/cmd/devp2p/internal/ethtest/conn.go index b555b14784..a7bc70cbf5 100644 --- a/cmd/devp2p/internal/ethtest/conn.go +++ b/cmd/devp2p/internal/ethtest/conn.go @@ -130,11 +130,16 @@ func (c *Conn) Write(proto Proto, code uint64, msg any) error { return err } +var errDisc error = fmt.Errorf("disconnect") + // ReadEth reads an Eth sub-protocol wire message. func (c *Conn) ReadEth() (any, error) { c.SetReadDeadline(time.Now().Add(timeout)) for { code, data, _, err := c.Conn.Read() + if code == discMsg { + return nil, errDisc + } if err != nil { return nil, err } diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go index 2f1731b60c..8ebbe2a05d 100644 --- a/cmd/devp2p/internal/ethtest/suite.go +++ b/cmd/devp2p/internal/ethtest/suite.go @@ -17,8 +17,12 @@ package ethtest import ( + "context" "crypto/rand" + "fmt" "reflect" + "sync" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" @@ -79,6 +83,8 @@ func (s *Suite) EthTests() []utesting.Test { {Name: "InvalidTxs", Fn: s.TestInvalidTxs}, {Name: "NewPooledTxs", Fn: s.TestNewPooledTxs}, {Name: "BlobViolations", Fn: s.TestBlobViolations}, + {Name: "TestBlobTxWithoutSidecar", Fn: s.TestBlobTxWithoutSidecar}, + {Name: "TestBlobTxWithMismatchedSidecar", Fn: s.TestBlobTxWithMismatchedSidecar}, } } @@ -825,3 +831,194 @@ func (s *Suite) TestBlobViolations(t *utesting.T) { conn.Close() } } + +// mangleSidecar returns a copy of the given blob transaction where the sidecar +// data has been modified to produce a different commitment hash. +func mangleSidecar(tx *types.Transaction) *types.Transaction { + sidecar := tx.BlobTxSidecar() + copy := types.BlobTxSidecar{ + Blobs: append([]kzg4844.Blob{}, sidecar.Blobs...), + Commitments: append([]kzg4844.Commitment{}, sidecar.Commitments...), + Proofs: append([]kzg4844.Proof{}, sidecar.Proofs...), + } + // zero the first commitment to alter the sidecar hash + copy.Commitments[0] = kzg4844.Commitment{} + return tx.WithBlobTxSidecar(©) +} + +func (s *Suite) TestBlobTxWithoutSidecar(t *utesting.T) { + t.Log(`This test checks that a blob transaction first advertised/transmitted without blobs will result in the sending peer being disconnected, and the full transaction should be successfully retrieved from another peer.`) + tx := s.makeBlobTxs(1, 2, 42)[0] + badTx := tx.WithoutBlobTxSidecar() + s.testBadBlobTx(t, tx, badTx) +} + +func (s *Suite) TestBlobTxWithMismatchedSidecar(t *utesting.T) { + t.Log(`This test checks that a blob transaction first advertised/transmitted without blobs, whose commitment don't correspond to the blob_versioned_hashes in the transaction, will result in the sending peer being disconnected, and the full transaction should be successfully retrieved from another peer.`) + tx := s.makeBlobTxs(1, 2, 43)[0] + badTx := mangleSidecar(tx) + s.testBadBlobTx(t, tx, badTx) +} + +// readUntil reads eth protocol messages until a message of the target type is +// received. It returns an error if there is a disconnect, or if the context +// is cancelled before a message of the desired type can be read. +func readUntil[T any](ctx context.Context, conn *Conn) (*T, error) { + for { + select { + case <-ctx.Done(): + return nil, context.Canceled + default: + } + received, err := conn.ReadEth() + if err != nil { + if err == errDisc { + return nil, errDisc + } + continue + } + + switch res := received.(type) { + case *T: + return res, nil + } + } +} + +// readUntilDisconnect reads eth protocol messages until the peer disconnects. +// It returns whether the peer disconnects in the next 100ms. +func readUntilDisconnect(conn *Conn) (disconnected bool) { + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + _, err := readUntil[struct{}](ctx, conn) + return err == errDisc +} + +func (s *Suite) testBadBlobTx(t *utesting.T, tx *types.Transaction, badTx *types.Transaction) { + stage1, stage2, stage3 := new(sync.WaitGroup), new(sync.WaitGroup), new(sync.WaitGroup) + stage1.Add(1) + stage2.Add(1) + stage3.Add(1) + + errc := make(chan error) + + badPeer := func() { + // announce the correct hash from the bad peer. + // when the transaction is first requested before transmitting it from the bad peer, + // trigger step 2: connection and announcement by good peers + + conn, err := s.dial() + if err != nil { + errc <- fmt.Errorf("dial fail: %v", err) + return + } + defer conn.Close() + + if err := conn.peer(s.chain, nil); err != nil { + errc <- fmt.Errorf("bad peer: peering failed: %v", err) + return + } + + ann := eth.NewPooledTransactionHashesPacket{ + Types: []byte{types.BlobTxType}, + Sizes: []uint32{uint32(badTx.Size())}, + Hashes: []common.Hash{badTx.Hash()}, + } + + if err := conn.Write(ethProto, eth.NewPooledTransactionHashesMsg, ann); err != nil { + errc <- fmt.Errorf("sending announcement failed: %v", err) + return + } + + req, err := readUntil[eth.GetPooledTransactionsPacket](context.Background(), conn) + if err != nil { + errc <- fmt.Errorf("failed to read GetPooledTransactions message: %v", err) + return + } + + stage1.Done() + stage2.Wait() + + // the good peer is connected, and has announced the tx. + // proceed to send the incorrect one from the bad peer. + + resp := eth.PooledTransactionsPacket{RequestId: req.RequestId, PooledTransactionsResponse: eth.PooledTransactionsResponse(types.Transactions{badTx})} + if err := conn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil { + errc <- fmt.Errorf("writing pooled tx response failed: %v", err) + return + } + if !readUntilDisconnect(conn) { + errc <- fmt.Errorf("expected bad peer to be disconnected") + return + } + stage3.Done() + } + + goodPeer := func() { + stage1.Wait() + + conn, err := s.dial() + if err != nil { + errc <- fmt.Errorf("dial fail: %v", err) + return + } + defer conn.Close() + + if err := conn.peer(s.chain, nil); err != nil { + errc <- fmt.Errorf("peering failed: %v", err) + return + } + + ann := eth.NewPooledTransactionHashesPacket{ + Types: []byte{types.BlobTxType}, + Sizes: []uint32{uint32(tx.Size())}, + Hashes: []common.Hash{tx.Hash()}, + } + + if err := conn.Write(ethProto, eth.NewPooledTransactionHashesMsg, ann); err != nil { + errc <- fmt.Errorf("sending announcement failed: %v", err) + return + } + + // wait until the bad peer has transmitted the incorrect transaction + stage2.Done() + stage3.Wait() + + // the bad peer has transmitted the bad tx, and been disconnected. + // transmit the same tx but with correct sidecar from the good peer. + + var req *eth.GetPooledTransactionsPacket + req, err = readUntil[eth.GetPooledTransactionsPacket](context.Background(), conn) + if err != nil { + errc <- fmt.Errorf("reading pooled tx request failed: %v", err) + return + } + + if req.GetPooledTransactionsRequest[0] != tx.Hash() { + errc <- fmt.Errorf("requested unknown tx hash") + return + } + + resp := eth.PooledTransactionsPacket{RequestId: req.RequestId, PooledTransactionsResponse: eth.PooledTransactionsResponse(types.Transactions{tx})} + if err := conn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil { + errc <- fmt.Errorf("writing pooled tx response failed: %v", err) + return + } + if readUntilDisconnect(conn) { + errc <- fmt.Errorf("unexpected disconnect") + return + } + close(errc) + } + + if err := s.engine.sendForkchoiceUpdated(); err != nil { + t.Fatalf("send fcu failed: %v", err) + } + + go goodPeer() + go badPeer() + err := <-errc + if err != nil { + t.Fatalf("%v", err) + } +} diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 9565c77def..8747724247 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -17,7 +17,6 @@ package txpool import ( - "crypto/sha256" "errors" "fmt" "math/big" @@ -170,20 +169,11 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobTxSidecar) err if len(sidecar.Blobs) != len(hashes) { return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sidecar.Blobs), len(hashes)) } - if len(sidecar.Commitments) != len(hashes) { - return fmt.Errorf("invalid number of %d blob commitments compared to %d blob hashes", len(sidecar.Commitments), len(hashes)) - } if len(sidecar.Proofs) != len(hashes) { return fmt.Errorf("invalid number of %d blob proofs compared to %d blob hashes", len(sidecar.Proofs), len(hashes)) } - // Blob quantities match up, validate that the provers match with the - // transaction hash before getting to the cryptography - hasher := sha256.New() - for i, vhash := range hashes { - computed := kzg4844.CalcBlobHashV1(hasher, &sidecar.Commitments[i]) - if vhash != computed { - return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, computed, vhash) - } + if err := sidecar.ValidateBlobCommitmentHashes(hashes); err != nil { + return err } // Blob commitments match with the hashes in the transaction, verify the // blobs themselves via KZG diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go index 88251ab957..32401db101 100644 --- a/core/types/tx_blob.go +++ b/core/types/tx_blob.go @@ -19,6 +19,7 @@ package types import ( "bytes" "crypto/sha256" + "fmt" "math/big" "github.com/ethereum/go-ethereum/common" @@ -85,6 +86,22 @@ func (sc *BlobTxSidecar) encodedSize() uint64 { return rlp.ListSize(blobs) + rlp.ListSize(commitments) + rlp.ListSize(proofs) } +// ValidateBlobCommitmentHashes checks whether the given hashes correspond to the +// commitments in the sidecar +func (sc *BlobTxSidecar) ValidateBlobCommitmentHashes(hashes []common.Hash) error { + if len(sc.Commitments) != len(hashes) { + return fmt.Errorf("invalid number of %d blob commitments compared to %d blob hashes", len(sc.Commitments), len(hashes)) + } + hasher := sha256.New() + for i, vhash := range hashes { + computed := kzg4844.CalcBlobHashV1(hasher, &sc.Commitments[i]) + if vhash != computed { + return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, computed, vhash) + } + } + return nil +} + // blobTxWithBlobs is used for encoding of transactions when blobs are present. type blobTxWithBlobs struct { BlobTx *BlobTx diff --git a/eth/handler_eth.go b/eth/handler_eth.go index b2cd52a221..11742b14ad 100644 --- a/eth/handler_eth.go +++ b/eth/handler_eth.go @@ -69,6 +69,19 @@ func (h *ethHandler) Handle(peer *eth.Peer, packet eth.Packet) error { return h.txFetcher.Enqueue(peer.ID(), *packet, false) case *eth.PooledTransactionsResponse: + // If we receive any blob transactions missing sidecars, or with + // sidecars that don't correspond to the versioned hashes reported + // in the header, disconnect from the sending peer. + for _, tx := range *packet { + if tx.Type() == types.BlobTxType { + if tx.BlobTxSidecar() == nil { + return errors.New("received sidecar-less blob transaction") + } + if err := tx.BlobTxSidecar().ValidateBlobCommitmentHashes(tx.BlobHashes()); err != nil { + return err + } + } + } return h.txFetcher.Enqueue(peer.ID(), *packet, true) default: From 31c972febfacd093179b900ad9bd95bab456ee66 Mon Sep 17 00:00:00 2001 From: Shude Li Date: Sat, 1 Mar 2025 21:11:51 +0800 Subject: [PATCH 165/940] ethclient: add BlobBaseFee method (#31290) --- ethclient/ethclient.go | 9 +++++++++ ethclient/ethclient_test.go | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index c761d4f8d3..3d6a28eabf 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -598,6 +598,15 @@ func (ec *Client) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { return (*big.Int)(&hex), nil } +// BlobBaseFee retrieves the current blob base fee. +func (ec *Client) BlobBaseFee(ctx context.Context) (*big.Int, error) { + var hex hexutil.Big + if err := ec.c.CallContext(ctx, &hex, "eth_blobBaseFee"); err != nil { + return nil, err + } + return (*big.Int)(&hex), nil +} + type feeHistoryResultMarshaling struct { OldestBlock *hexutil.Big `json:"oldestBlock"` Reward [][]*hexutil.Big `json:"reward,omitempty"` diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 5fc7ed68f9..787cad3f96 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -404,6 +404,15 @@ func testStatusFunctions(t *testing.T, client *rpc.Client) { t.Fatalf("unexpected gas tip cap: %v", gasTipCap) } + // BlobBaseFee + blobBaseFee, err := ec.BlobBaseFee(context.Background()) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if blobBaseFee.Cmp(big.NewInt(1)) != 0 { + t.Fatalf("unexpected blob base fee: %v", blobBaseFee) + } + // FeeHistory history, err := ec.FeeHistory(context.Background(), 1, big.NewInt(2), []float64{95, 99}) if err != nil { From 8ccca244f1aa435387947839c12cbc2cf6803fa1 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Sat, 1 Mar 2025 21:37:47 +0100 Subject: [PATCH 166/940] version: release go-ethereum v1.15.4 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index ddf151aa74..c151a5e962 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 4 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 4 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From ebff2f42c0fbb4ebee43b0e73e39b658305a8a9b Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Sat, 1 Mar 2025 21:40:14 +0100 Subject: [PATCH 167/940] version: begin v1.15.5 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index c151a5e962..c222ccb3df 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 4 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 5 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From 7405dc5c4b51a950abf72cd1c31368891cd5c9b3 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Tue, 4 Mar 2025 09:30:03 +0100 Subject: [PATCH 168/940] eth/tracers: fix omitempty for memory and storage (#31289) This fixes a regression in the opcode tracer API where we would log empty memory and storage fields. --- eth/tracers/logger/logger.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 596ee97146..02ff8146fb 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -177,14 +177,14 @@ func (s *StructLog) toLegacyJSON() json.RawMessage { if len(s.ReturnData) > 0 { msg.ReturnData = hexutil.Bytes(s.ReturnData).String() } - if s.Memory != nil { + if len(s.Memory) > 0 { memory := make([]string, 0, (len(s.Memory)+31)/32) for i := 0; i+32 <= len(s.Memory); i += 32 { memory = append(memory, fmt.Sprintf("%x", s.Memory[i:i+32])) } msg.Memory = &memory } - if s.Storage != nil { + if len(s.Storage) > 0 { storage := make(map[string]string) for i, storageValue := range s.Storage { storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) From 658c607e131335831adc82f17a58f666889a8778 Mon Sep 17 00:00:00 2001 From: levisyin Date: Wed, 5 Mar 2025 18:02:18 +0800 Subject: [PATCH 169/940] build: upgrade to Go 1.24.1 and golangci-lint 1.64.4 (#31313) - upgrade -dlgo version to Go 1.24.1 - upgrade golangci-lint version to 1.64.6 --- build/checksums.txt | 200 ++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index c8b742e443..06e44ea2b0 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,109 +5,109 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/fixtures_pectra-devnet-6.tar.gz b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz -# version:golang 1.24.0 +# version:golang 1.24.1 # https://go.dev/dl/ -d14120614acb29d12bcab72bd689f257eb4be9e0b6f88a8fb7e41ac65f8556e5 go1.24.0.src.tar.gz -5d04588154d5923bd8e26b76111806340ec55c41af1b05623ea744fcb3d6bc22 go1.24.0.aix-ppc64.tar.gz -7af054e5088b68c24b3d6e135e5ca8d91bbd5a05cb7f7f0187367b3e6e9e05ee go1.24.0.darwin-amd64.tar.gz -dee0ea64411a00b47ded586d5a8e30cfe3acf51564aa1bb24e039a6dca807a29 go1.24.0.darwin-amd64.pkg -fd9cfb5dd6c75a347cfc641a253f0db1cebaca16b0dd37965351c6184ba595e4 go1.24.0.darwin-arm64.tar.gz -b19eb6b7ae87f8371c3e7a84d129db67779a2883d2fffa6bb90412b0167df133 go1.24.0.darwin-arm64.pkg -d0dc34ad86aea746abe245994c68a9e1ad8f46ba8c4af901cd5861a4dd4c21df go1.24.0.dragonfly-amd64.tar.gz -4ee02b1f3812aff4da79c79464ee4038ca61ad74b3a9619850f30435f81c2536 go1.24.0.freebsd-386.tar.gz -838191001f9324da904dece35a586a3156d548687db87ac9461aa3d38fc88b09 go1.24.0.freebsd-amd64.tar.gz -ce6ad4e84a40a8a1d848b7e31b0cddfd1cee8f7959e7dc358a8fa8b5566ea718 go1.24.0.freebsd-arm.tar.gz -511f7b0cac4c4ed1066d324072ce223b906ad6b2a85f2e1c5d260eb7d08b5901 go1.24.0.freebsd-arm64.tar.gz -a1e4072630dc589a2975ef51317b52c7d8599bf6f389fc59033c01e0a0fa705a go1.24.0.freebsd-riscv64.tar.gz -7593e9dcee9f07c3df6d099f7d259f5734a6c0dccc5f28962f18e7f501c9bb21 go1.24.0.illumos-amd64.tar.gz -90521453a59c6ce20364d2dc7c38532949b033b602ba12d782caeb90af1b0624 go1.24.0.linux-386.tar.gz -dea9ca38a0b852a74e81c26134671af7c0fbe65d81b0dc1c5bfe22cf7d4c8858 go1.24.0.linux-amd64.tar.gz -c3fa6d16ffa261091a5617145553c71d21435ce547e44cc6dfb7470865527cc7 go1.24.0.linux-arm64.tar.gz -695dc54fa14cd3124fa6900d7b5ae39eeac23f7a4ecea81656070160fac2c54a go1.24.0.linux-armv6l.tar.gz -a201e4c9b7e6d29ed64c43296ed88e81a66f82f2093ce45b766d2c526941396f go1.24.0.linux-loong64.tar.gz -f3ac039aae78ad0bfb08106406c2e62eaf763dd82ebaf0ecd539adadd1d729a6 go1.24.0.linux-mips.tar.gz -f2e6456d45e024831b1da8d88b1bb6392cca9500c1b00841f525d76c9e9553e0 go1.24.0.linux-mips64.tar.gz -b847893ff119389c939adc2b8516b6500204b7cb49d5e19b25e1c2091d2c74c6 go1.24.0.linux-mips64le.tar.gz -bd4aed27d02746c237c3921e97029ac6b6fe687a67436b8f52ff1f698d330bd9 go1.24.0.linux-mipsle.tar.gz -007123c9b06c41729a4bb3f166f4df7196adf4e33c2d2ab0e7e990175f0ce1d4 go1.24.0.linux-ppc64.tar.gz -a871a43de7d26c91dd90cb6e0adacb214c9e35ee2188c617c91c08c017efe81a go1.24.0.linux-ppc64le.tar.gz -620dcf48c6297519aad6c81f8e344926dc0ab09a2a79f1e306964aece95a553d go1.24.0.linux-riscv64.tar.gz -544d78b077c6b54bf78958c4a8285abec2d21f668fb007261c77418cd2edbb46 go1.24.0.linux-s390x.tar.gz -8b143a7edefbaa2a0b0246c9df2df1bac9fbed909d8615a375c08da7744e697d go1.24.0.netbsd-386.tar.gz -67150a6dd7bdb9c4e88d77f46ee8c4dc99d5e71deca4912d8c2c85f7a16d0262 go1.24.0.netbsd-amd64.tar.gz -446b2539f11218fd6f6f6e3dd90b20ae55a06afe129885eeb3df51eb344eb0f6 go1.24.0.netbsd-arm.tar.gz -370115b6ff7d30b29431223de348eb11ab65e3c92627532d97fd55f63f94e7a8 go1.24.0.netbsd-arm64.tar.gz -cbda5f15f06ed9630f122a53542d9de13d149643633c74f1dcb45e79649b788a go1.24.0.openbsd-386.tar.gz -926f601d0e655ab1e8d7f357fd82542e5cf206c38c4e2f9fccf0706987d38836 go1.24.0.openbsd-amd64.tar.gz -8a54892f8c933c541fff144a825d0fdc41bae14b0832aab703cb75eb4cb64f2c go1.24.0.openbsd-arm.tar.gz -ef7fddcef0a22c7900c178b7687cf5aa25c2a9d46a3cc330b77a6de6e6c2396b go1.24.0.openbsd-arm64.tar.gz -b3b5e2e2b53489ded2c2c21900ddcbbdb7991632bb5b42f05f125d71675e0b76 go1.24.0.openbsd-ppc64.tar.gz -fbcb1dbf1269b4079dc4fd0b15f3274b9d635f1a7e319c3fc1a907b03280348e go1.24.0.openbsd-riscv64.tar.gz -33b4221e1c174a16e3f661deab6c60838ac4ae6cb869a4da1d1115773ceed88b go1.24.0.plan9-386.tar.gz -111a89014019cdbd69c2978de9b3e201f77e35183c8ab3606fba339d38f28549 go1.24.0.plan9-amd64.tar.gz -8da3d3997049f40ebe0cd336a9bb9e4bfa4832df3c90a32f07383371d6d74849 go1.24.0.plan9-arm.tar.gz -b6069da21dc95ccdbd047675b584e5480ffc3eba35f9e7c8b0e7b317aaf01e2c go1.24.0.solaris-amd64.tar.gz -b53c28a4c2863ec50ab4a1dbebe818ef6177f86773b6f43475d40a5d9aa4ec9e go1.24.0.windows-386.zip -f07677013cd7861c5e16067b0a82144c23c4bf72c139c762e142440f4c926f61 go1.24.0.windows-386.msi -96b7280979205813759ee6947be7e3bb497da85c482711116c00522e3bb41ff1 go1.24.0.windows-amd64.zip -4e78016d889431eb16aa0f87868cf52479b90059791c94a4ff45872d0573089e go1.24.0.windows-amd64.msi -53f73450fb66075d16be9f206e9177bd972b528168271918c4747903b5596c3d go1.24.0.windows-arm64.zip -4f9780158fb7996dcbcbc7c7ef208f880b5e8c1f2792ba3ede0c75050c1bc23a go1.24.0.windows-arm64.msi +8244ebf46c65607db10222b5806aeb31c1fcf8979c1b6b12f60c677e9a3c0656 go1.24.1.src.tar.gz +8d627dc163a4bffa2b1887112ad6194af175dce108d606ed1714a089fb806033 go1.24.1.aix-ppc64.tar.gz +addbfce2056744962e2d7436313ab93486660cf7a2e066d171b9d6f2da7c7abe go1.24.1.darwin-amd64.tar.gz +58d529334561cff11087cd4ab18fe0b46d8d5aad88f45c02b9645f847e014512 go1.24.1.darwin-amd64.pkg +295581b5619acc92f5106e5bcb05c51869337eb19742fdfa6c8346c18e78ff88 go1.24.1.darwin-arm64.tar.gz +78b0fc8ddc344eb499f1a952c687cb84cbd28ba2b739cfa0d4eb042f07e44e82 go1.24.1.darwin-arm64.pkg +e70053f56f7eb93806d80cbd5726f78509a0a467602f7bea0e2c4ee8ed7c3968 go1.24.1.dragonfly-amd64.tar.gz +3595e2674ed8fe72e604ca59c964d3e5277aafb08475c2b1aaca2d2fd69c24fc go1.24.1.freebsd-386.tar.gz +47d7de8bb64d5c3ee7b6723aa62d5ecb11e3568ef2249bbe1d4bbd432d37c00c go1.24.1.freebsd-amd64.tar.gz +04eec3bcfaa14c1370cdf98e8307fac7e4853496c3045afb9c3124a29cbca205 go1.24.1.freebsd-arm.tar.gz +51aa70146e40cfdc20927424083dc86e6223f85dc08089913a1651973b55665b go1.24.1.freebsd-arm64.tar.gz +3c131d8e3fc285a1340f87813153e24226d3ddbd6e54f3facbd6e4c46a84655e go1.24.1.freebsd-riscv64.tar.gz +201d09da737ba39d5367f87d4e8b31edaeeb3dc9b9c407cb8cfb40f90c5a727a go1.24.1.illumos-amd64.tar.gz +8c530ecedbc17e42ce10177bea07ccc96a3e77c792ea1ea72173a9675d16ffa5 go1.24.1.linux-386.tar.gz +cb2396bae64183cdccf81a9a6df0aea3bce9511fc21469fb89a0c00470088073 go1.24.1.linux-amd64.tar.gz +8df5750ffc0281017fb6070fba450f5d22b600a02081dceef47966ffaf36a3af go1.24.1.linux-arm64.tar.gz +6d95f8d7884bfe2364644c837f080f2b585903d0b771eb5b06044e226a4f120a go1.24.1.linux-armv6l.tar.gz +19304a4a56e46d04604547d2d83235dc4f9b192c79832560ce337d26cc7b835a go1.24.1.linux-loong64.tar.gz +6347be77fa5359c12a5308c8ab87147c1fc4717b0c216493d1706c3b9fcde22d go1.24.1.linux-mips.tar.gz +1647df415f7030b82d4105670192aa7e8910e18563bb0d505192d72800cc2d21 go1.24.1.linux-mips64.tar.gz +762da594e4ec0f9cf6defae6ef971f5f7901203ee6a2d979e317adec96657317 go1.24.1.linux-mips64le.tar.gz +9d8133c7b23a557399fab870b5cf464079c2b623a43b214a7567cf11c254a444 go1.24.1.linux-mipsle.tar.gz +132f10999abbaccbada47fa85462db30c423955913b14d6c692de25f4636c766 go1.24.1.linux-ppc64.tar.gz +0fb522efcefabae6e37e69bdc444094e75bfe824ea6d4cc3cbc70c7ae1b16858 go1.24.1.linux-ppc64le.tar.gz +eaef4323d5467ff97fb1979c8491764060dade19f02f3275a9313f9a0da3b9c0 go1.24.1.linux-riscv64.tar.gz +6c05e14d8f11094cb56a1c50f390b6b658bed8a7cbd8d1a57e926581b7eabfce go1.24.1.linux-s390x.tar.gz +5dbb287d343ea00d58a70b11629f32ee716dc50a6875c459ea2018df0f294cd8 go1.24.1.netbsd-386.tar.gz +617aa3faee50ce84c343db0888e9a210c310a7203666b4ed620f31030c9fb32f go1.24.1.netbsd-amd64.tar.gz +59a928b7080c4a6ac985946274b7c65ce1cecc0b468ecd992d17b7c12fab9296 go1.24.1.netbsd-arm.tar.gz +28daa8d0feb4aef2af60cefa3305bb9314de7e8a05cbca41ac548964cdfe89b7 go1.24.1.netbsd-arm64.tar.gz +b7382b2f5d99813aeac14db482faa3bfbd47a68880b607fa2a7e669e26bab9cd go1.24.1.openbsd-386.tar.gz +2513b6537c45deead5e641c7ce7502913e7d5e6f0b21c52542fb11f81578690f go1.24.1.openbsd-amd64.tar.gz +853c1917d4fc7b144c55a02842aa48542d5cc798dde8db96dc0fdbc263200e04 go1.24.1.openbsd-arm.tar.gz +6bc207b91e6f6ae3347fb54616a8fb2f5c11983713846a4cef111ff3f4f94d14 go1.24.1.openbsd-arm64.tar.gz +4279260e2f2b94ee94e81470d13db7367f4393b061fee60985528fa0fa430df4 go1.24.1.openbsd-ppc64.tar.gz +6fc4023a0a339ee0778522364a127d94c78e62122288d47d820dba703f81dc07 go1.24.1.openbsd-riscv64.tar.gz +b5eb9fafd77146e7e1f748acfd95559580ecc8d2f15abf432a20f58c929c7cd2 go1.24.1.plan9-386.tar.gz +24dcad6361b141fc8cced15b092351e12a99d2e58d7013204a3013c50daf9fdd go1.24.1.plan9-amd64.tar.gz +a026ac3b55aa1e6fdc2aaab30207a117eafbe965ed81d3aa0676409f280ddc37 go1.24.1.plan9-arm.tar.gz +8e4f6a77388dc6e5aa481efd5abdb3b9f5c9463bb82f4db074494e04e5c84992 go1.24.1.solaris-amd64.tar.gz +b799f4ab264eef12a014c759383ed934056608c483e0f73e34ea6caf9f1df5f9 go1.24.1.windows-386.zip +db128981033ac82a64688a123f631e61297b6b8f52ca913145e57caa8ce94cc3 go1.24.1.windows-386.msi +95666b551453209a2b8869d29d177285ff9573af10f085d961d7ae5440f645ce go1.24.1.windows-amd64.zip +5968e7adcf26e68a54f1cd41ad561275a670a8e2ca5263bc375b524638557dfb go1.24.1.windows-amd64.msi +e28c4e6d0b913955765b46157ab88ae59bb636acaa12d7bec959aa6900f1cebd go1.24.1.windows-arm64.zip +6d352c1f154a102a5b90c480cc64bab205ccf2681e34e78a3a4d3f1ddfbc81e4 go1.24.1.windows-arm64.msi -# version:golangci 1.64.4 +# version:golangci 1.64.6 # https://github.com/golangci/golangci-lint/releases/ -# https://github.com/golangci/golangci-lint/releases/download/v1.64.4/ -f31ef6e20c62acc31eb7b851d611b4bd10256d1b1d8be38f0cceec300b5b60db golangci-lint-1.64.4-darwin-amd64.tar.gz -bb4a9ece7ef66ef49bd6de873f5f5ec801cf93dacf58efb360cc939b4fd37c47 golangci-lint-1.64.4-darwin-arm64.tar.gz -fd8f9046150356e36ad8af31f99219515d5e0ff6e8e9f4204182312447018fcf golangci-lint-1.64.4-freebsd-386.tar.gz -bbae940caa31cb1d2d8d26abd867666cd92746d2ddc63d6917d128c456d715ef golangci-lint-1.64.4-freebsd-amd64.tar.gz -86eb00cbdc5e277857a380d556d78a42b3edf8aae5991de8767dce7da337d73b golangci-lint-1.64.4-freebsd-armv6.tar.gz -c0f7d50f4fcd39ae8bda181c127b078a79d87c885ac472c4cce5b01134dde5bc golangci-lint-1.64.4-freebsd-armv7.tar.gz -31d264fa26a73a583425bc9b39c18de70a330e346fe800e80c277ddb5f8477b6 golangci-lint-1.64.4-illumos-amd64.tar.gz -3dccc18a6b1a0f2518196190ed56277b1480b381231605936eca6b862426b83c golangci-lint-1.64.4-linux-386.deb -b95f3e757c59ada75144bd086478ab63bcda83c2b2a935e60d8f39aff20fbcd2 golangci-lint-1.64.4-linux-386.rpm -8fa58af0022ae0487162c02d08075e2d869c9b5f8613a64b85fd769a2a2d2b93 golangci-lint-1.64.4-linux-386.tar.gz -fa80d2ad920fc74b85a0b93ad1671fd27c9c4d6f22e167cc4e1da758d72dd893 golangci-lint-1.64.4-linux-amd64.deb -8bf2e3c82504a893a12e84ecbc8071f787075d2fdc1ef946deda3d29aae1afad golangci-lint-1.64.4-linux-amd64.rpm -7de8f80a12cd3052610e6be21f08f2220805b1f3e43b3b6ec843f14a12140de2 golangci-lint-1.64.4-linux-amd64.tar.gz -ade222b9ae997a2875e44ed53ca5a129f24944b232132d0a5898f101381d3bfa golangci-lint-1.64.4-linux-arm64.deb -8f9f8617ed0d8b8f62c8dfe69877932c0d85f0d83a9ec3250b04777c7133ada1 golangci-lint-1.64.4-linux-arm64.rpm -debf1f73e71f1dd288957574eab4e7515b1b04c4ac2f127192181da8a42f0e8e golangci-lint-1.64.4-linux-arm64.tar.gz -3f616caa4a16738114ad29076a333c62bb0650fe4846b438c341d235f78ee5aa golangci-lint-1.64.4-linux-armv6.deb -6a7c9d7b7c57d7d440e1e3f133e18e4b5b703604d4ae7f7862fb9ea461887a8b golangci-lint-1.64.4-linux-armv6.rpm -d7b9e3c89af93d98c6b5a555ef48e25bee24f84d7825a29e343e9966404d5b4d golangci-lint-1.64.4-linux-armv6.tar.gz -18179ecf04ace3051450852424b31a4d26644a3912e759cd595e624eee0174bd golangci-lint-1.64.4-linux-armv7.deb -f669fce85d3edc3d557d1e64e2241d895f1ee676f79d139874bf76693cc447a2 golangci-lint-1.64.4-linux-armv7.rpm -9bbaa13b474ecb1560fb05aee0a8cab3e9cc327d41632bee8b553b766f2bf756 golangci-lint-1.64.4-linux-armv7.tar.gz -b5a2725adba2a1b04a5160ffa0730ba30b88c1ee99ecbc65dd7075a8d70f3730 golangci-lint-1.64.4-linux-loong64.deb -28ac00afb3f6407808fe7c15a6002e5fe6b3b461df3fe0223603542e6f9b974a golangci-lint-1.64.4-linux-loong64.rpm -121170309fed82cb64d6fae5020ef2b194e591a53156370c221a80121cc4aa08 golangci-lint-1.64.4-linux-loong64.tar.gz -aadfaab41380f53ada8f7ad4fa9af784bb882eaaa1e3939e048b3a5ea8f2c13f golangci-lint-1.64.4-linux-mips64.deb -6fecbff69086e316dd028050d3ebf82fc466c7f4dc0f6084307054621101c202 golangci-lint-1.64.4-linux-mips64.rpm -430c48034527af028dc608c115166f47b6b67c8cb83a317d9d44876b9753292a golangci-lint-1.64.4-linux-mips64.tar.gz -432126af2bbbd639dbbcc2c265337f104cc613a7b4c5a8fb5e49f182b428f077 golangci-lint-1.64.4-linux-mips64le.deb -cfa663eee0fae721510d6dc31e61db4be51b4e4244eb7de2b6a9bc6d475551e5 golangci-lint-1.64.4-linux-mips64le.rpm -2bacfac65182893c5ceb67b61d5b9d2b24da47726d84cb87d734a6e32f040148 golangci-lint-1.64.4-linux-mips64le.tar.gz -66d86e47d68420c03045eff0698e9acf9f82d97cd1f07d7e52837a6e544eceed golangci-lint-1.64.4-linux-ppc64le.deb -05466bd2d8e82f7245b838e29d0c90cdbaf67375b2b5bc980d8510d5edb206ad golangci-lint-1.64.4-linux-ppc64le.rpm -e013b6980f7140712af0aedc9a661265e1d3c6adc7e9d045734e3686a3601acc golangci-lint-1.64.4-linux-ppc64le.tar.gz -753980d2fb421d35292b71b51f9bb0552f18de2eb181ccf692ef79e086ad2304 golangci-lint-1.64.4-linux-riscv64.deb -73a33a883020298f8c652a4ace4f6888103d80d411fe3e9b77ce0a3b36ff7d3a golangci-lint-1.64.4-linux-riscv64.rpm -020efd09b894dc75012f43b1d4c58e69e5446ca3f79845b5e10a02588def3e1b golangci-lint-1.64.4-linux-riscv64.tar.gz -4d99a16bc9ff5cea5e4ae3568c6254390fbdad8f1d370c287744409112bceff9 golangci-lint-1.64.4-linux-s390x.deb -6e63374a9f95fc09f2bb9501059eb18b8107e08416722ba7b561ae385d80b33b golangci-lint-1.64.4-linux-s390x.rpm -62a6febb892b26eee84a32cc99d04afe90bf62d0970774b1bab75e36b66f53b4 golangci-lint-1.64.4-linux-s390x.tar.gz -5ba4d235f9abd60d2d280f9fe4228c6ddab11ae9fe48d253b7e477046675f1f6 golangci-lint-1.64.4-netbsd-386.tar.gz -061643bb4370a52010e5e76f88f5b5220e51058df50af86b45286263af92b321 golangci-lint-1.64.4-netbsd-amd64.tar.gz -12b2be6c35bcf7a36374e952c7efec7905a17fa3ebe6214924ba8721b766c4af golangci-lint-1.64.4-netbsd-arm64.tar.gz -553a71a677751dccee082ed8afe24cf58bef725f72aa02aedcc6758dd8f44125 golangci-lint-1.64.4-netbsd-armv6.tar.gz -74a5a5a7b8c8cd11dccdec303ee6592d904b09836782e6d658be359737f300ef golangci-lint-1.64.4-netbsd-armv7.tar.gz -b3ceea2187843f9ba6510303141a72465621e3f190a262c0b48707b9e983ea9a golangci-lint-1.64.4-source.tar.gz -fda4de312fcb0b4853b03bcdfb31ac631a68fa0b966f6aa010eb30d14427180b golangci-lint-1.64.4-windows-386.zip -8fc60bd809f86c6431ed8f3d1f25917538c0ebc93e670cfb199f25bbaa56e602 golangci-lint-1.64.4-windows-amd64.zip -b9058c9d2ae8d75048c6ad8885d11e5ac0a6c40be2af85bfa6605e48d69d3eb6 golangci-lint-1.64.4-windows-arm64.zip -809b0131adb1aa8b359becd13222df367b505bc2955bb3b1d2d0dd6f07347b13 golangci-lint-1.64.4-windows-armv6.zip -fc43f8c95d6bec8ba9a3557a0bb63cf9f504137ce6d24cfdc4c330d46f7779d2 golangci-lint-1.64.4-windows-armv7.zip +# https://github.com/golangci/golangci-lint/releases/download/v1.64.6/ +08f9459e7125fed2612abd71596e04d172695921aff82120d1c1e5e9b6fff2a3 golangci-lint-1.64.6-darwin-amd64.tar.gz +8c10d0c7c3935b8c2269d628b6a06a8f48d8fb4cc31af02fe4ce0cd18b0704c1 golangci-lint-1.64.6-darwin-arm64.tar.gz +c07fcabb55deb8d2c4d390025568e76162d7f91b1d14bd2311be45d8d440a624 golangci-lint-1.64.6-freebsd-386.tar.gz +8ed1ef1102e1a42983ffcaae8e06de6a540334c3a69e205c610b8a7c92d469cd golangci-lint-1.64.6-freebsd-amd64.tar.gz +8f8dda66d1b4a85cc8a1daf1b69af6559c3eb0a41dd8033148a9ad85cfc0e1d9 golangci-lint-1.64.6-freebsd-armv6.tar.gz +59e8ca1fa254661b2a55e96515b14a10cd02221d443054deac5b28c3c3e12d6b golangci-lint-1.64.6-freebsd-armv7.tar.gz +e3d323d5f132e9b7593141bfe1d19c8460e65a55cea1008ec96945fed563f981 golangci-lint-1.64.6-illumos-amd64.tar.gz +5ce910f2a864c5fbeb32a30cbd506e1b2ef215f7a0f422cd5be6370b13db6f03 golangci-lint-1.64.6-linux-386.deb +2caab682a26b9a5fb94ba24e3a7e1404fa9eab2c12e36ae1c5548d80a1be190c golangci-lint-1.64.6-linux-386.rpm +2d82d0a4716e6d9b70c95103054855cb4b5f20f7bbdee42297f0189955bd14b6 golangci-lint-1.64.6-linux-386.tar.gz +9cd82503e9841abcaa57663fc899587fe90363c26d86a793a98d3080fd25e907 golangci-lint-1.64.6-linux-amd64.deb +981aaca5e5202d4fbb162ec7080490eb67ef5d32add5fb62fb02210597acc9da golangci-lint-1.64.6-linux-amd64.rpm +71e290acbacb7b3ba4f68f0540fb74dc180c4336ac8a6f3bdcd7fcc48b15148d golangci-lint-1.64.6-linux-amd64.tar.gz +718016bb06c1f598a8d23c7964e2643de621dbe5808688cb38857eb0bb773c84 golangci-lint-1.64.6-linux-arm64.deb +ddc0e7b4b10b47cf894aea157e89e3674bbb60f8f5c480110c21c49cc2c1634d golangci-lint-1.64.6-linux-arm64.rpm +99a7ff13dec7a8781a68408b6ecb8a1c5e82786cba3189eaa91d5cdcc24362ce golangci-lint-1.64.6-linux-arm64.tar.gz +90e360f89c244394912b8709fb83a900b6d56cf19141df2afaf9e902ef3057b1 golangci-lint-1.64.6-linux-armv6.deb +46546ff7c98d873ffcdbee06b39dc1024fc08db4fbf1f6309360a44cf976b5c2 golangci-lint-1.64.6-linux-armv6.rpm +e45c1a42868aca0b0ee54d14fb89da216f3b4409367cd7bce3b5f36788b4fc92 golangci-lint-1.64.6-linux-armv6.tar.gz +3cf6ddbbbf358db3de4b64a24f9683bbe2da3f003cfdee86cb610124b57abafb golangci-lint-1.64.6-linux-armv7.deb +508b6712710da10f11aab9ea5e63af415c932dfe7fff718e649d3100b838f797 golangci-lint-1.64.6-linux-armv7.rpm +da9a8bbee86b4dfee73fbc17e0856ec84c5b04919eb09bf3dd5904c39ce41753 golangci-lint-1.64.6-linux-armv7.tar.gz +ad496a58284e1e9c8ac6f993fec429dcd96c85a8c4715dbb6530a5af0dae7fbd golangci-lint-1.64.6-linux-loong64.deb +3bd70fa737b224750254dce616d9a188570e49b894b0cdb2fd04155e2c061350 golangci-lint-1.64.6-linux-loong64.rpm +a535af973499729f2215a84303eb0de61399057aad6901ddea1b4f73f68d5f2c golangci-lint-1.64.6-linux-loong64.tar.gz +6ad2a1cd37ca30303a488abfca2de52aff57519901c6d8d2608656fe9fb05292 golangci-lint-1.64.6-linux-mips64.deb +5f18369f0ca010a02c267352ebe6e3e0514c6debff49899c9e5520906c0da287 golangci-lint-1.64.6-linux-mips64.rpm +3449d6c13307b91b0e8817f8911c07c3412cdb6931b8d101e42db3e9762e91ad golangci-lint-1.64.6-linux-mips64.tar.gz +d4712a348f65dcaf9f6c58f1cfd6d0984d54a902873dca5e76f0d686f5c59499 golangci-lint-1.64.6-linux-mips64le.deb +57cea4538894558cb8c956d6b69c5509e4304546abe4a467478fc9ada0c736d6 golangci-lint-1.64.6-linux-mips64le.rpm +bc030977d44535b2152fddb2732f056d193c043992fe638ddecea21a40ef09fe golangci-lint-1.64.6-linux-mips64le.tar.gz +1ceb4e492efa527d246c61798c581f49113756fab8c39bb3eefdb1fa97041f92 golangci-lint-1.64.6-linux-ppc64le.deb +454e1c2b3583a8644e0c33a970fb4ce35b8f11848e1a770d9095d99d159ad0ab golangci-lint-1.64.6-linux-ppc64le.rpm +fddf30d35923eb6c7bb57520d8645768f802bf86c4cbf5a3a13049efb9e71b82 golangci-lint-1.64.6-linux-ppc64le.tar.gz +bd75f0dd6f65bee5821c433803b28f3c427ef3582764c3d0e7f7fae1c9d468b6 golangci-lint-1.64.6-linux-riscv64.deb +58457207c225cbd5340c8dcb75d9a44aa890d604e28464115a3a9762febaed04 golangci-lint-1.64.6-linux-riscv64.rpm +82639518a613a6705b7e2de5b28c278e875d782a5c97e9c1b2ac10b4ecd7852f golangci-lint-1.64.6-linux-riscv64.tar.gz +131d69204f8ced200b1437731e987cc886edac30dc87e6e1dcbd4f833d351713 golangci-lint-1.64.6-linux-s390x.deb +ca6caf28ca7a1df7cff720f8fd6ac4b8f2eac10c8cbfe7d2eade70876aded570 golangci-lint-1.64.6-linux-s390x.rpm +ed966d28a6512bc2b1120029a9f78ed77f2015e330b589a731d67d59be30b0b1 golangci-lint-1.64.6-linux-s390x.tar.gz +b181132b41943fc77ace7f9f5523085d12d3613f27774a0e35e17dd5e65ba589 golangci-lint-1.64.6-netbsd-386.tar.gz +f7b81c426006e3c699dc8665797a462aecba8c2cd23ac4971472e55184d95bc9 golangci-lint-1.64.6-netbsd-amd64.tar.gz +663d6fb4c3bef57b8aacdb1b1a4634075e55d294ed170724b443374860897ca6 golangci-lint-1.64.6-netbsd-arm64.tar.gz +8c7a76ee822568cc19352bbb9b2b0863dc5e185eb07782adbbaf648afd02ebcd golangci-lint-1.64.6-netbsd-armv6.tar.gz +0ce26d56ce78e516529e087118ba3f1bcd71d311b4c5b2bde6ec24a6e8966d85 golangci-lint-1.64.6-netbsd-armv7.tar.gz +135d5d998168683f46e4fab308cef5aa3c282025b7de6b258f976aadfb820db7 golangci-lint-1.64.6-source.tar.gz +ccdb0cc249531a205304a76308cfa7cda830083d083d557884416a2461148263 golangci-lint-1.64.6-windows-386.zip +2d88f282e08e1853c70bc7c914b5f58beaa6509903d56098aeb9bc3df30ea9d5 golangci-lint-1.64.6-windows-amd64.zip +6a3c6e7afc6916392679d7d6b95ac239827644e3e50ec4e8ca6ab1e4e6db65fe golangci-lint-1.64.6-windows-arm64.zip +9c9c1ef9687651566987f93e76252f7526c386901d7d8aeee044ca88115da4b1 golangci-lint-1.64.6-windows-armv6.zip +4f0df114155791799dfde8cd8cb6307fecfb17fed70b44205486ec925e2f39cf golangci-lint-1.64.6-windows-armv7.zip # This is the builder on PPA that will build Go itself (inception-y), don't modify! # From cd78b65cdaa9e00866962e38685c4f93ac9e8444 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 5 Mar 2025 11:04:24 +0100 Subject: [PATCH 170/940] core: match on deposit contract log topic (#31317) This resolves a situation on the Sepolia testnet, which has a different deposit contract. The contract on that network emits two kinds of logs, instead of only deposit events like the deposit contract on mainnet. So we need to skip events with mismatched topics. --- core/state_processor.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/state_processor.go b/core/state_processor.go index 4e365c6550..9241d091ad 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -305,12 +305,14 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte *requests = append(*requests, requestsData) } +var depositTopic = common.HexToHash("0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5") + // ParseDepositLogs extracts the EIP-6110 deposit values from logs emitted by // BeaconDepositContract. func ParseDepositLogs(requests *[][]byte, logs []*types.Log, config *params.ChainConfig) error { deposits := make([]byte, 1) // note: first byte is 0x00 (== deposit request type) for _, log := range logs { - if log.Address == config.DepositContractAddress { + if log.Address == config.DepositContractAddress && len(log.Topics) > 0 && log.Topics[0] == depositTopic { request, err := types.DepositLogToRequest(log.Data) if err != nil { return fmt.Errorf("unable to parse deposit data: %v", err) From 4263936a0402e2b175a366091ed3cb54133bc6a8 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 5 Mar 2025 11:55:17 +0100 Subject: [PATCH 171/940] version: release v1.15.5 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index c222ccb3df..334b5da9e4 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 5 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 5 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From 2645b4e0bf8e8ca294922116ddb30cdbd5952af5 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 5 Mar 2025 11:57:18 +0100 Subject: [PATCH 172/940] version: begin v1.15.6 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 334b5da9e4..586bb870d1 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 5 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 6 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From d219e9b005358f96d85f4eb66e1418c605b2bb0f Mon Sep 17 00:00:00 2001 From: Halimao <1065621723@qq.com> Date: Wed, 5 Mar 2025 19:51:53 +0800 Subject: [PATCH 173/940] build: fix execution-spec-tests sanitycheck URL (#31314) --- build/checksums.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/checksums.txt b/build/checksums.txt index 06e44ea2b0..5ccb85bba6 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -2,7 +2,7 @@ # version:spec-tests pectra-devnet-6@v1.0.0 # https://github.com/ethereum/execution-spec-tests/releases -# https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/fixtures_pectra-devnet-6.tar.gz +# https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/ b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz # version:golang 1.24.1 From 9aba6895b939c49896902f60fe58cc32a569efdd Mon Sep 17 00:00:00 2001 From: Delweng Date: Fri, 7 Mar 2025 18:23:19 +0800 Subject: [PATCH 174/940] core/rawdb,state: add preimage miss metric (#31295) 1. The metric of preimage/hits are always the same as preimage/total, prefer to replace the hits with miss instead. 2. For the state/read/accounts metric, follow the same naming of others, change into singuar. --- core/rawdb/accessors_state.go | 6 +++++- core/rawdb/schema.go | 5 +++-- core/state/metrics.go | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go index 9ce58e7d27..adc77fae83 100644 --- a/core/rawdb/accessors_state.go +++ b/core/rawdb/accessors_state.go @@ -27,6 +27,11 @@ import ( // ReadPreimage retrieves a single preimage of the provided hash. func ReadPreimage(db ethdb.KeyValueReader, hash common.Hash) []byte { data, _ := db.Get(preimageKey(hash)) + if len(data) == 0 { + preimageMissCounter.Inc(1) + } else { + preimageHitsCounter.Inc(1) + } return data } @@ -38,7 +43,6 @@ func WritePreimages(db ethdb.KeyValueWriter, preimages map[common.Hash][]byte) { } } preimageCounter.Inc(int64(len(preimages))) - preimageHitCounter.Inc(int64(len(preimages))) } // ReadCode retrieves the contract code of the provided code hash. diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 3d5d757a86..5480c7a72c 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -145,8 +145,9 @@ var ( FixedCommitteeRootKey = []byte("fixedRoot-") // bigEndian64(syncPeriod) -> committee root hash SyncCommitteeKey = []byte("committee-") // bigEndian64(syncPeriod) -> serialized committee - preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) - preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) + preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) + preimageHitsCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) + preimageMissCounter = metrics.NewRegisteredCounter("db/preimage/miss", nil) ) // LegacyTxLookupEntry is the legacy TxLookupEntry definition with some unnecessary diff --git a/core/state/metrics.go b/core/state/metrics.go index fb45bc4b84..dd4b2e9838 100644 --- a/core/state/metrics.go +++ b/core/state/metrics.go @@ -19,7 +19,7 @@ package state import "github.com/ethereum/go-ethereum/metrics" var ( - accountReadMeters = metrics.NewRegisteredMeter("state/read/accounts", nil) + accountReadMeters = metrics.NewRegisteredMeter("state/read/account", nil) storageReadMeters = metrics.NewRegisteredMeter("state/read/storage", nil) accountUpdatedMeter = metrics.NewRegisteredMeter("state/update/account", nil) storageUpdatedMeter = metrics.NewRegisteredMeter("state/update/storage", nil) From 4cdd7c86314e5f5a98fa68e928deaa99c026f40d Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:10:16 +0100 Subject: [PATCH 175/940] cmd,eth,les: replace Cancun override flag with Prague (#31341) It's that time of the cycle, should have this ready to go for mainnet Prague release. --- cmd/geth/chaincmd.go | 8 ++++---- cmd/geth/config.go | 6 +++--- cmd/geth/main.go | 2 +- cmd/utils/flags.go | 6 +++--- core/genesis.go | 6 +++--- eth/backend.go | 4 ++-- eth/ethconfig/config.go | 4 ++-- eth/ethconfig/gen_config.go | 10 +++++----- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index bbadb1cc19..eb0dda0952 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -50,7 +50,7 @@ var ( ArgsUsage: "", Flags: slices.Concat([]cli.Flag{ utils.CachePreimagesFlag, - utils.OverrideCancun, + utils.OverridePrague, utils.OverrideVerkle, }, utils.DatabaseFlags), Description: ` @@ -212,9 +212,9 @@ func initGenesis(ctx *cli.Context) error { defer stack.Close() var overrides core.ChainOverrides - if ctx.IsSet(utils.OverrideCancun.Name) { - v := ctx.Uint64(utils.OverrideCancun.Name) - overrides.OverrideCancun = &v + if ctx.IsSet(utils.OverridePrague.Name) { + v := ctx.Uint64(utils.OverridePrague.Name) + overrides.OverridePrague = &v } if ctx.IsSet(utils.OverrideVerkle.Name) { v := ctx.Uint64(utils.OverrideVerkle.Name) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index ecee2bfd80..71ab0b6968 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -183,9 +183,9 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { // makeFullNode loads geth configuration and creates the Ethereum backend. func makeFullNode(ctx *cli.Context) *node.Node { stack, cfg := makeConfigNode(ctx) - if ctx.IsSet(utils.OverrideCancun.Name) { - v := ctx.Uint64(utils.OverrideCancun.Name) - cfg.Eth.OverrideCancun = &v + if ctx.IsSet(utils.OverridePrague.Name) { + v := ctx.Uint64(utils.OverridePrague.Name) + cfg.Eth.OverridePrague = &v } if ctx.IsSet(utils.OverrideVerkle.Name) { v := ctx.Uint64(utils.OverrideVerkle.Name) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 9d9256862b..fda6edb78d 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -62,7 +62,7 @@ var ( utils.NoUSBFlag, // deprecated utils.USBFlag, utils.SmartCardDaemonPathFlag, - utils.OverrideCancun, + utils.OverridePrague, utils.OverrideVerkle, utils.EnablePersonal, // deprecated utils.TxPoolLocalsFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 728ec2d667..1394f9060e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -233,9 +233,9 @@ var ( Value: 2048, Category: flags.EthCategory, } - OverrideCancun = &cli.Uint64Flag{ - Name: "override.cancun", - Usage: "Manually specify the Cancun fork timestamp, overriding the bundled setting", + OverridePrague = &cli.Uint64Flag{ + Name: "override.prague", + Usage: "Manually specify the Prague fork timestamp, overriding the bundled setting", Category: flags.EthCategory, } OverrideVerkle = &cli.Uint64Flag{ diff --git a/core/genesis.go b/core/genesis.go index 4dd6c9ed24..639556ad90 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -256,7 +256,7 @@ func (e *GenesisMismatchError) Error() string { // ChainOverrides contains the changes to chain config. type ChainOverrides struct { - OverrideCancun *uint64 + OverridePrague *uint64 OverrideVerkle *uint64 } @@ -265,8 +265,8 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error { if o == nil || cfg == nil { return nil } - if o.OverrideCancun != nil { - cfg.CancunTime = o.OverrideCancun + if o.OverridePrague != nil { + cfg.PragueTime = o.OverridePrague } if o.OverrideVerkle != nil { cfg.VerkleTime = o.OverrideVerkle diff --git a/eth/backend.go b/eth/backend.go index 4c0fd9e68b..8fbbc20a47 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -214,8 +214,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } // Override the chain config with provided settings. var overrides core.ChainOverrides - if config.OverrideCancun != nil { - overrides.OverrideCancun = config.OverrideCancun + if config.OverridePrague != nil { + overrides.OverridePrague = config.OverridePrague } if config.OverrideVerkle != nil { overrides.OverrideVerkle = config.OverrideVerkle diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 6b75ab816f..0bf9ce3579 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -148,8 +148,8 @@ type Config struct { // send-transaction variants. The unit is ether. RPCTxFeeCap float64 - // OverrideCancun (TODO: remove after the fork) - OverrideCancun *uint64 `toml:",omitempty"` + // OverridePrague (TODO: remove after the fork) + OverridePrague *uint64 `toml:",omitempty"` // OverrideVerkle (TODO: remove after the fork) OverrideVerkle *uint64 `toml:",omitempty"` diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 8e954eaefb..11c0c06372 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -48,7 +48,7 @@ func (c Config) MarshalTOML() (interface{}, error) { RPCGasCap uint64 RPCEVMTimeout time.Duration RPCTxFeeCap float64 - OverrideCancun *uint64 `toml:",omitempty"` + OverridePrague *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"` } var enc Config @@ -84,7 +84,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.RPCGasCap = c.RPCGasCap enc.RPCEVMTimeout = c.RPCEVMTimeout enc.RPCTxFeeCap = c.RPCTxFeeCap - enc.OverrideCancun = c.OverrideCancun + enc.OverridePrague = c.OverridePrague enc.OverrideVerkle = c.OverrideVerkle return &enc, nil } @@ -124,7 +124,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { RPCGasCap *uint64 RPCEVMTimeout *time.Duration RPCTxFeeCap *float64 - OverrideCancun *uint64 `toml:",omitempty"` + OverridePrague *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"` } var dec Config @@ -227,8 +227,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.RPCTxFeeCap != nil { c.RPCTxFeeCap = *dec.RPCTxFeeCap } - if dec.OverrideCancun != nil { - c.OverrideCancun = dec.OverrideCancun + if dec.OverridePrague != nil { + c.OverridePrague = dec.OverridePrague } if dec.OverrideVerkle != nil { c.OverrideVerkle = dec.OverrideVerkle From 49ef375033cf84a1c1f0cabb8b7354ed59c0adce Mon Sep 17 00:00:00 2001 From: Austin Larson <78000745+alarso16@users.noreply.github.com> Date: Tue, 11 Mar 2025 11:00:50 -0400 Subject: [PATCH 176/940] core/txpool: demote error log to warn (#31332) This error log in `legacypool.go` isn't necessary, since even though the behavior is unexpected, it is handled correctly. A discussion on issue #22301 concluded that this should instead be a warning log. --- core/txpool/legacypool/legacypool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 1cc6856663..8c09d48695 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1604,7 +1604,7 @@ func (pool *LegacyPool) demoteUnexecutables() { gapped := list.Cap(0) for _, tx := range gapped { hash := tx.Hash() - log.Error("Demoting invalidated transaction", "hash", hash) + log.Warn("Demoting invalidated transaction", "hash", hash) // Internal shuffle shouldn't touch the lookup set. pool.enqueueTx(hash, tx, false) From 71f9f1e684affbd0ab87f21202d247786c9ce371 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 11 Mar 2025 16:15:07 +0100 Subject: [PATCH 177/940] core: prefund pectra precompiles in developer genesis (#31342) Prefund the precompile addresses for the new precompiles in the developer genesis block. --- core/genesis.go | 26 +++++++++++++++++--------- miner/worker.go | 1 + 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/core/genesis.go b/core/genesis.go index 639556ad90..9bd8c4f8b9 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -636,15 +636,23 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis { BaseFee: big.NewInt(params.InitialBaseFee), 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 - common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD - common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity - common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp - common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd - 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 + common.BytesToAddress([]byte{0x01}): {Balance: big.NewInt(1)}, // ECRecover + common.BytesToAddress([]byte{0x02}): {Balance: big.NewInt(1)}, // SHA256 + common.BytesToAddress([]byte{0x03}): {Balance: big.NewInt(1)}, // RIPEMD + common.BytesToAddress([]byte{0x04}): {Balance: big.NewInt(1)}, // Identity + common.BytesToAddress([]byte{0x05}): {Balance: big.NewInt(1)}, // ModExp + common.BytesToAddress([]byte{0x06}): {Balance: big.NewInt(1)}, // ECAdd + common.BytesToAddress([]byte{0x07}): {Balance: big.NewInt(1)}, // ECScalarMul + common.BytesToAddress([]byte{0x08}): {Balance: big.NewInt(1)}, // ECPairing + common.BytesToAddress([]byte{0x09}): {Balance: big.NewInt(1)}, // BLAKE2b + common.BytesToAddress([]byte{0x0a}): {Balance: big.NewInt(1)}, // KZGPointEval + common.BytesToAddress([]byte{0x0b}): {Balance: big.NewInt(1)}, // BLSG1Add + common.BytesToAddress([]byte{0x0c}): {Balance: big.NewInt(1)}, // BLSG1MultiExp + common.BytesToAddress([]byte{0x0d}): {Balance: big.NewInt(1)}, // BLSG2Add + common.BytesToAddress([]byte{0x0e}): {Balance: big.NewInt(1)}, // BLSG2MultiExp + common.BytesToAddress([]byte{0x0f}): {Balance: big.NewInt(1)}, // BLSG1Pairing + common.BytesToAddress([]byte{0x10}): {Balance: big.NewInt(1)}, // BLSG1MapG1 + common.BytesToAddress([]byte{0x11}): {Balance: big.NewInt(1)}, // BLSG2MapG2 // Pre-deploy system contracts params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0}, params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0}, diff --git a/miner/worker.go b/miner/worker.go index 2c54421196..8fb42e31bc 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -486,6 +486,7 @@ func totalFees(block *types.Block, receipts []*types.Receipt) *big.Int { for i, tx := range block.Transactions() { minerFee, _ := tx.EffectiveGasTip(block.BaseFee()) feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), minerFee)) + // TODO (MariusVanDerWijden) add blob fees } return feesWei } From e442c4d50cb41f3fbc4e1a550a6b7ff6c29526f2 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 11 Mar 2025 17:17:47 +0100 Subject: [PATCH 178/940] beacon/types, beacon/blsync: update for electra (#31243) This updates the blsync base types for the Electra fork. I've been testing, and it doesn't seem to make blsync fully work on Electra. But I'd still like to get this in to make some progress. --------- Co-authored-by: Zsolt Felfoldi --- beacon/blsync/block_sync.go | 7 +- beacon/blsync/engineclient.go | 7 +- beacon/light/api/light_api.go | 14 +- beacon/light/test_helpers.go | 8 +- beacon/params/networks.go | 6 +- beacon/params/params.go | 52 ++- beacon/types/beacon_block.go | 63 +++- beacon/types/beacon_block_test.go | 21 ++ beacon/types/exec_header.go | 8 +- beacon/types/exec_payload.go | 7 +- beacon/types/light_sync.go | 18 +- .../block_electra_consolidations.json | 194 +++++++++++ .../testdata/block_electra_deposits.json | 305 ++++++++++++++++++ .../testdata/block_electra_withdrawals.json | 232 +++++++++++++ go.mod | 2 +- go.sum | 4 +- 16 files changed, 899 insertions(+), 49 deletions(-) create mode 100644 beacon/types/testdata/block_electra_consolidations.json create mode 100644 beacon/types/testdata/block_electra_deposits.json create mode 100644 beacon/types/testdata/block_electra_withdrawals.json diff --git a/beacon/blsync/block_sync.go b/beacon/blsync/block_sync.go index ff689a922f..a6252a55f1 100755 --- a/beacon/blsync/block_sync.go +++ b/beacon/blsync/block_sync.go @@ -156,8 +156,9 @@ func (s *beaconBlockSync) updateEventFeed() { return } s.chainHeadFeed.Send(types.ChainHeadEvent{ - BeaconHead: optimistic.Attested.Header, - Block: execBlock, - Finalized: finalizedHash, + BeaconHead: optimistic.Attested.Header, + Block: execBlock, + ExecRequests: headBlock.ExecutionRequestsList(), + Finalized: finalizedHash, }) } diff --git a/beacon/blsync/engineclient.go b/beacon/blsync/engineclient.go index c6569fdbde..77bee83f5b 100644 --- a/beacon/blsync/engineclient.go +++ b/beacon/blsync/engineclient.go @@ -100,6 +100,11 @@ func (ec *engineClient) callNewPayload(fork string, event types.ChainHeadEvent) params = []any{execData} ) switch fork { + case "electra": + method = "engine_newPayloadV4" + parentBeaconRoot := event.BeaconHead.ParentRoot + blobHashes := collectBlobHashes(event.Block) + params = append(params, blobHashes, parentBeaconRoot, event.ExecRequests) case "deneb": method = "engine_newPayloadV3" parentBeaconRoot := event.BeaconHead.ParentRoot @@ -135,7 +140,7 @@ func (ec *engineClient) callForkchoiceUpdated(fork string, event types.ChainHead var method string switch fork { - case "deneb": + case "deneb", "electra": method = "engine_forkchoiceUpdatedV3" case "capella": method = "engine_forkchoiceUpdatedV2" diff --git a/beacon/light/api/light_api.go b/beacon/light/api/light_api.go index 91f66c08be..f9a5aae153 100755 --- a/beacon/light/api/light_api.go +++ b/beacon/light/api/light_api.go @@ -43,7 +43,6 @@ var ( ) type CommitteeUpdate struct { - Version string Update types.LightClientUpdate NextSyncCommittee types.SerializedSyncCommittee } @@ -81,9 +80,9 @@ func (u *CommitteeUpdate) UnmarshalJSON(input []byte) error { if err := json.Unmarshal(input, &dec); err != nil { return err } - u.Version = dec.Version u.NextSyncCommittee = dec.Data.NextSyncCommittee u.Update = types.LightClientUpdate{ + Version: dec.Version, AttestedHeader: types.SignedHeader{ Header: dec.Data.Header.Beacon, Signature: dec.Data.SyncAggregate, @@ -206,7 +205,7 @@ func (api *BeaconLightApi) GetOptimisticUpdate() (types.OptimisticUpdate, error) func decodeOptimisticUpdate(enc []byte) (types.OptimisticUpdate, error) { var data struct { - Version string + Version string `json:"version"` Data struct { Attested jsonHeaderWithExecProof `json:"attested_header"` Aggregate types.SyncAggregate `json:"sync_aggregate"` @@ -259,7 +258,7 @@ func (api *BeaconLightApi) GetFinalityUpdate() (types.FinalityUpdate, error) { func decodeFinalityUpdate(enc []byte) (types.FinalityUpdate, error) { var data struct { - Version string + Version string `json:"version"` Data struct { Attested jsonHeaderWithExecProof `json:"attested_header"` Finalized jsonHeaderWithExecProof `json:"finalized_header"` @@ -289,6 +288,7 @@ func decodeFinalityUpdate(enc []byte) (types.FinalityUpdate, error) { } return types.FinalityUpdate{ + Version: data.Version, Attested: types.HeaderWithExecProof{ Header: data.Data.Attested.Beacon, PayloadHeader: attestedExecHeader, @@ -355,7 +355,8 @@ func (api *BeaconLightApi) GetCheckpointData(checkpointHash common.Hash) (*types // See data structure definition here: // https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientbootstrap type bootstrapData struct { - Data struct { + Version string `json:"version"` + Data struct { Header jsonBeaconHeader `json:"header"` Committee *types.SerializedSyncCommittee `json:"current_sync_committee"` CommitteeBranch merkle.Values `json:"current_sync_committee_branch"` @@ -374,6 +375,7 @@ func (api *BeaconLightApi) GetCheckpointData(checkpointHash common.Hash) (*types return nil, fmt.Errorf("invalid checkpoint block header, have %v want %v", header.Hash(), checkpointHash) } checkpoint := &types.BootstrapData{ + Version: data.Version, Header: header, CommitteeBranch: data.Data.CommitteeBranch, CommitteeRoot: data.Data.Committee.Root(), @@ -395,7 +397,7 @@ func (api *BeaconLightApi) GetBeaconBlock(blockRoot common.Hash) (*types.BeaconB } var beaconBlockMessage struct { - Version string + Version string `json:"version"` Data struct { Message json.RawMessage `json:"message"` } diff --git a/beacon/light/test_helpers.go b/beacon/light/test_helpers.go index 7bd19ca0ad..50e554b3d7 100644 --- a/beacon/light/test_helpers.go +++ b/beacon/light/test_helpers.go @@ -39,10 +39,10 @@ func GenerateTestUpdate(config *params.ChainConfig, period uint64, committee, ne var attestedHeader types.Header if finalizedHeader { update.FinalizedHeader = new(types.Header) - *update.FinalizedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+100, params.StateIndexNextSyncCommittee, merkle.Value(update.NextSyncCommitteeRoot)) - attestedHeader, update.FinalityBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexFinalBlock, merkle.Value(update.FinalizedHeader.Hash())) + *update.FinalizedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+100, params.StateIndexNextSyncCommittee(""), merkle.Value(update.NextSyncCommitteeRoot)) + attestedHeader, update.FinalityBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexFinalBlock(""), merkle.Value(update.FinalizedHeader.Hash())) } else { - attestedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+2000, params.StateIndexNextSyncCommittee, merkle.Value(update.NextSyncCommitteeRoot)) + attestedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+2000, params.StateIndexNextSyncCommittee(""), merkle.Value(update.NextSyncCommitteeRoot)) } update.AttestedHeader = GenerateTestSignedHeader(attestedHeader, config, committee, attestedHeader.Slot+1, signerCount) return update @@ -63,7 +63,7 @@ func GenerateTestSignedHeader(header types.Header, config *params.ChainConfig, c } func GenerateTestCheckpoint(period uint64, committee *types.SerializedSyncCommittee) *types.BootstrapData { - header, branch := makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexSyncCommittee, merkle.Value(committee.Root())) + header, branch := makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexSyncCommittee(""), merkle.Value(committee.Root())) return &types.BootstrapData{ Header: header, Committee: committee, diff --git a/beacon/params/networks.go b/beacon/params/networks.go index 1204e0176f..eda225e0fe 100644 --- a/beacon/params/networks.go +++ b/beacon/params/networks.go @@ -41,7 +41,8 @@ var ( AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}). AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}). AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}). - AddFork("DENEB", 132608, []byte{144, 0, 0, 115}) + AddFork("DENEB", 132608, []byte{144, 0, 0, 115}). + AddFork("ELECTRA", 222464, []byte{144, 0, 0, 116}) HoleskyLightConfig = (&ChainConfig{ GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"), @@ -52,5 +53,6 @@ var ( AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}). AddFork("BELLATRIX", 0, []byte{3, 1, 112, 0}). AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}). - AddFork("DENEB", 29696, []byte{5, 1, 112, 0}) + AddFork("DENEB", 29696, []byte{5, 1, 112, 0}). + AddFork("ELECTRA", 115968, []byte{6, 1, 112, 0}) ) diff --git a/beacon/params/params.go b/beacon/params/params.go index e4e0d00934..c6600cee5f 100644 --- a/beacon/params/params.go +++ b/beacon/params/params.go @@ -29,18 +29,46 @@ const ( ) const ( - StateIndexGenesisTime = 32 - StateIndexGenesisValidators = 33 - StateIndexForkVersion = 141 - StateIndexLatestHeader = 36 - StateIndexBlockRoots = 37 - StateIndexStateRoots = 38 - StateIndexHistoricRoots = 39 - StateIndexFinalBlock = 105 - StateIndexSyncCommittee = 54 - StateIndexNextSyncCommittee = 55 - StateIndexExecPayload = 56 - StateIndexExecHead = 908 + StateIndexGenesisTime = 32 + StateIndexGenesisValidators = 33 + StateIndexForkVersion = 141 + StateIndexLatestHeader = 36 + StateIndexBlockRoots = 37 + StateIndexStateRoots = 38 + StateIndexHistoricRoots = 39 + StateIndexFinalBlockOld = 105 + StateIndexFinalBlockElectra = 169 + StateIndexSyncCommitteeOld = 54 + StateIndexSyncCommitteeElectra = 86 + StateIndexNextSyncCommitteeOld = 55 + StateIndexNextSyncCommitteeElectra = 87 + StateIndexExecPayload = 56 + StateIndexExecHead = 908 BodyIndexExecPayload = 25 ) + +func StateIndexFinalBlock(forkName string) uint64 { + switch forkName { + case "bellatrix", "capella", "deneb": + return StateIndexFinalBlockOld + default: + return StateIndexFinalBlockElectra + } +} +func StateIndexSyncCommittee(forkName string) uint64 { + switch forkName { + case "bellatrix", "capella", "deneb": + return StateIndexSyncCommitteeOld + default: + return StateIndexSyncCommitteeElectra + } +} +func StateIndexNextSyncCommittee(forkName string) uint64 { + switch forkName { + case "bellatrix", "capella", "deneb": + return StateIndexNextSyncCommitteeOld + default: + return StateIndexNextSyncCommitteeElectra + } +} diff --git a/beacon/types/beacon_block.go b/beacon/types/beacon_block.go index e4cd1340e5..a2e31d5abf 100644 --- a/beacon/types/beacon_block.go +++ b/beacon/types/beacon_block.go @@ -17,16 +17,21 @@ package types import ( + "bytes" "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/codec" "github.com/protolambda/ztyp/tree" + + // beacon forks + "github.com/protolambda/zrnt/eth2/beacon/capella" + "github.com/protolambda/zrnt/eth2/beacon/deneb" + "github.com/protolambda/zrnt/eth2/beacon/electra" ) type blockObject interface { @@ -43,10 +48,12 @@ type BeaconBlock struct { 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) + case "deneb": + obj = new(deneb.BeaconBlock) + case "electra": + obj = new(electra.BeaconBlock) default: return nil, fmt.Errorf("unsupported fork: %s", forkName) } @@ -63,6 +70,8 @@ func NewBeaconBlock(obj blockObject) *BeaconBlock { return &BeaconBlock{obj} case *deneb.BeaconBlock: return &BeaconBlock{obj} + case *electra.BeaconBlock: + return &BeaconBlock{obj} default: panic(fmt.Errorf("unsupported block type %T", obj)) } @@ -75,6 +84,8 @@ func (b *BeaconBlock) Slot() uint64 { return uint64(obj.Slot) case *deneb.BeaconBlock: return uint64(obj.Slot) + case *electra.BeaconBlock: + return uint64(obj.Slot) default: panic(fmt.Errorf("unsupported block type %T", b.blockObj)) } @@ -84,9 +95,12 @@ func (b *BeaconBlock) Slot() uint64 { func (b *BeaconBlock) ExecutionPayload() (*types.Block, error) { switch obj := b.blockObj.(type) { case *capella.BeaconBlock: - return convertPayload(&obj.Body.ExecutionPayload, &obj.ParentRoot) + return convertPayload(&obj.Body.ExecutionPayload, &obj.ParentRoot, nil) case *deneb.BeaconBlock: - return convertPayload(&obj.Body.ExecutionPayload, &obj.ParentRoot) + return convertPayload(&obj.Body.ExecutionPayload, &obj.ParentRoot, nil) + case *electra.BeaconBlock: + requests := b.ExecutionRequestsList() + return convertPayload(&obj.Body.ExecutionPayload, &obj.ParentRoot, requests) default: panic(fmt.Errorf("unsupported block type %T", b.blockObj)) } @@ -99,6 +113,8 @@ func (b *BeaconBlock) Header() Header { return headerFromZRNT(obj.Header(configs.Mainnet)) case *deneb.BeaconBlock: return headerFromZRNT(obj.Header(configs.Mainnet)) + case *electra.BeaconBlock: + return headerFromZRNT(obj.Header(configs.Mainnet)) default: panic(fmt.Errorf("unsupported block type %T", b.blockObj)) } @@ -108,3 +124,38 @@ func (b *BeaconBlock) Header() Header { func (b *BeaconBlock) Root() common.Hash { return common.Hash(b.blockObj.HashTreeRoot(configs.Mainnet, tree.GetHashFn())) } + +// ExecutionRequestsList returns the execution layer requests of the block. +func (b *BeaconBlock) ExecutionRequestsList() [][]byte { + switch obj := b.blockObj.(type) { + case *capella.BeaconBlock, *deneb.BeaconBlock: + return nil + case *electra.BeaconBlock: + r := obj.Body.ExecutionRequests + return marshalRequests(configs.Mainnet, + &r.Deposits, + &r.Withdrawals, + &r.Consolidations, + ) + default: + panic(fmt.Errorf("unsupported block type %T", b.blockObj)) + } +} + +func marshalRequests(spec *zrntcommon.Spec, items ...zrntcommon.SpecObj) (list [][]byte) { + var buf bytes.Buffer + list = [][]byte{} + for typ, data := range items { + buf.Reset() + buf.WriteByte(byte(typ)) + w := codec.NewEncodingWriter(&buf) + if err := data.Serialize(spec, w); err != nil { + panic(err) + } + if buf.Len() == 1 { + continue // skip empty requests + } + list = append(list, bytes.Clone(buf.Bytes())) + } + return list +} diff --git a/beacon/types/beacon_block_test.go b/beacon/types/beacon_block_test.go index d5920e805a..05aeeaaa16 100644 --- a/beacon/types/beacon_block_test.go +++ b/beacon/types/beacon_block_test.go @@ -33,6 +33,27 @@ func TestBlockFromJSON(t *testing.T) { wantBlockHash common.Hash } tests := []blocktest{ + { + file: "block_electra_withdrawals.json", + version: "electra", + wantSlot: 151850, + wantBlockNumber: 141654, + wantBlockHash: common.HexToHash("0xf6730485a38be5ada3e110990a2c7adaabd2e8d4a49782134f1a8bfbc246a5d7"), + }, + { + file: "block_electra_deposits.json", + version: "electra", + wantSlot: 151016, + wantBlockNumber: 140858, + wantBlockHash: common.HexToHash("0x1f2637170986346c7993d5adbadbebbf4c9ed89c6a4d2dff653db99c8c168076"), + }, + { + file: "block_electra_consolidations.json", + version: "electra", + wantSlot: 151717, + wantBlockNumber: 141529, + wantBlockHash: common.HexToHash("0xc8807f7a1f96b0a073ff27065776dd21eff6b7e64079c60bffd33f690efbb330"), + }, { file: "block_deneb.json", version: "deneb", diff --git a/beacon/types/exec_header.go b/beacon/types/exec_header.go index b5f90bae25..ae79b00841 100644 --- a/beacon/types/exec_header.go +++ b/beacon/types/exec_header.go @@ -22,10 +22,12 @@ import ( "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" + + // beacon chain forks + "github.com/protolambda/zrnt/eth2/beacon/capella" + "github.com/protolambda/zrnt/eth2/beacon/deneb" ) type headerObject interface { @@ -43,7 +45,7 @@ func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, er switch forkName { case "capella": obj = new(capella.ExecutionPayloadHeader) - case "deneb": + case "deneb", "electra": // note: the payload type was not changed in electra obj = new(deneb.ExecutionPayloadHeader) default: return nil, fmt.Errorf("unsupported fork: %s", forkName) diff --git a/beacon/types/exec_payload.go b/beacon/types/exec_payload.go index b159687dfc..7b81f2fbfc 100644 --- a/beacon/types/exec_payload.go +++ b/beacon/types/exec_payload.go @@ -34,7 +34,7 @@ type payloadType interface { } // convertPayload converts a beacon chain execution payload to types.Block. -func convertPayload[T payloadType](payload T, parentRoot *zrntcommon.Root) (*types.Block, error) { +func convertPayload[T payloadType](payload T, parentRoot *zrntcommon.Root, requests [][]byte) (*types.Block, error) { var ( header types.Header transactions []*types.Transaction @@ -62,7 +62,10 @@ func convertPayload[T payloadType](payload T, parentRoot *zrntcommon.Root) (*typ default: panic("unsupported block type") } - + if requests != nil { + reqHash := types.CalcRequestsHash(requests) + header.RequestsHash = &reqHash + } 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) diff --git a/beacon/types/light_sync.go b/beacon/types/light_sync.go index 3e9b13d0e2..128ee77f1b 100644 --- a/beacon/types/light_sync.go +++ b/beacon/types/light_sync.go @@ -36,6 +36,7 @@ type HeadInfo struct { // together with a proof through a beacon header and corresponding state. // Note: BootstrapData is fetched from a server based on a known checkpoint hash. type BootstrapData struct { + Version string Header Header CommitteeRoot common.Hash Committee *SerializedSyncCommittee `rlp:"-"` @@ -47,7 +48,7 @@ func (c *BootstrapData) Validate() error { if c.CommitteeRoot != c.Committee.Root() { return errors.New("wrong committee root") } - return merkle.VerifyProof(c.Header.StateRoot, params.StateIndexSyncCommittee, c.CommitteeBranch, merkle.Value(c.CommitteeRoot)) + return merkle.VerifyProof(c.Header.StateRoot, params.StateIndexSyncCommittee(c.Version), c.CommitteeBranch, merkle.Value(c.CommitteeRoot)) } // LightClientUpdate is a proof of the next sync committee root based on a header @@ -59,6 +60,7 @@ func (c *BootstrapData) Validate() error { // See data structure definition here: // https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientupdate type LightClientUpdate struct { + Version string AttestedHeader SignedHeader // Arbitrary header out of the period signed by the sync committee NextSyncCommitteeRoot common.Hash // Sync committee of the next period advertised in the current one NextSyncCommitteeBranch merkle.Values // Proof for the next period's sync committee @@ -79,11 +81,11 @@ func (update *LightClientUpdate) Validate() error { if update.FinalizedHeader.SyncPeriod() != period { return errors.New("finalized header is from different period") } - if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexFinalBlock, update.FinalityBranch, merkle.Value(update.FinalizedHeader.Hash())); err != nil { + if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexFinalBlock(update.Version), update.FinalityBranch, merkle.Value(update.FinalizedHeader.Hash())); err != nil { return fmt.Errorf("invalid finalized header proof: %w", err) } } - if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexNextSyncCommittee, update.NextSyncCommitteeBranch, merkle.Value(update.NextSyncCommitteeRoot)); err != nil { + if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexNextSyncCommittee(update.Version), update.NextSyncCommitteeBranch, merkle.Value(update.NextSyncCommitteeRoot)); err != nil { return fmt.Errorf("invalid next sync committee proof: %w", err) } return nil @@ -194,6 +196,7 @@ func (u *OptimisticUpdate) Validate() error { // See data structure definition here: // https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientfinalityupdate type FinalityUpdate struct { + Version string Attested, Finalized HeaderWithExecProof FinalityBranch merkle.Values // Sync committee BLS signature aggregate @@ -223,14 +226,15 @@ func (u *FinalityUpdate) Validate() error { if err := u.Finalized.Validate(); err != nil { return err } - return merkle.VerifyProof(u.Attested.StateRoot, params.StateIndexFinalBlock, u.FinalityBranch, merkle.Value(u.Finalized.Hash())) + return merkle.VerifyProof(u.Attested.StateRoot, params.StateIndexFinalBlock(u.Version), 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 + BeaconHead Header + Block *ctypes.Block + ExecRequests [][]byte // execution layer requests (added in Electra) + Finalized common.Hash // latest finalized block hash } diff --git a/beacon/types/testdata/block_electra_consolidations.json b/beacon/types/testdata/block_electra_consolidations.json new file mode 100644 index 0000000000..421b554224 --- /dev/null +++ b/beacon/types/testdata/block_electra_consolidations.json @@ -0,0 +1,194 @@ +{ + "slot": "151717", + "proposer_index": "20165", + "parent_root": "0x0b968237e4cd877e1b5f146da849d5a228cba9b9020c10095cdf177ff0cbdca9", + "state_root": "0xc99af23f66c2b3c964b5301f314ffae1add20b1d88b3a9d8a95c72110b06b2fd", + "body": { + "randao_reveal": "0x81126bf1b4491dd0906c2d82615b34b8d3f779096bcf0a5f0ddda2a6da2b6c1858d3359a0b70cf66af69fc649bf6683e0520b3b14edcde3d6bd75b394d0812c5fd232350e6e3b5e9e6b262219c788ca2e74fa15a1e02e034b091d6c694aaeccd", + "eth1_data": { + "deposit_root": "0x8654042dec994aa6fc1a36fd0f4ebb2a49d1b27ada9460b045e2ea2a15718cc2", + "deposit_count": "10010", + "block_hash": "0xb358182abdc706e4a7ca709816043ebb23f3d93e943ca0becdfb9202abecd2d3" + }, + "graffiti": "0x6c69676874686f7573652d676574682d33000000000000000000000000000000", + "proposer_slashings": [], + "attester_slashings": [], + "attestations": [ + { + "aggregation_bits": "0xfefffffffffff7ffbfefffdff7ff77ffffffffffdfe7ffffffffbfffffff7fbfffeffffffffffffffffffffffffffffffbffffffffffeffffeffffffffffeffffffbfffbfffffffffffffffffebfffffffff7ffffffdffffffffffffffffffffffffbfff7fffffffffffffffffffffefffffffffff7ffffffffeffffffffffffff7fffeffffffdfffffffff7ff7fffff7bffffffffbfffffffffffffdfff7ffffffffeffffffffffffffffffffdffffbffffffffffffff7ff6fffffffffffffffffffffffffffffefffff7fffefffeffffdffbffffff3fffdfdfbfffffffffffffffffdffdfffffffffffffffffffffff7ffffffffeffd7ffffffffffffffffffbff7ffeffffffffffbfffdfffffffffffffffffffff7fff0f", + "data": { + "slot": "151716", + "index": "0", + "beacon_block_root": "0x0b968237e4cd877e1b5f146da849d5a228cba9b9020c10095cdf177ff0cbdca9", + "source": { + "epoch": "4740", + "root": "0x75198e06e7a0fe301a524212e6376d2222e421fb3cfd1ef0dcb637bf6d20deac" + }, + "target": { + "epoch": "4741", + "root": "0x8bb6fe4f7ea104312914c88ac84534e4da2ff8207790060f4ba903aaf231678e" + } + }, + "signature": "0x9138d56149037ae150d8c544c8b609a250fe5e3d66cb36e5d2dd618a642dd79bfa45ec1da014f24872410ddf9ecba28907bec2ea0e5581694871746fbeba9c4e5a553725b03feba05272a11a327b02bae60da8144d333eb019568cf64eb8a43d", + "committee_bits": "0xffff010000000000" + }, + { + "aggregation_bits": "0xbdfffffffdffffffffffffffffffefffffffffffffffffffffffbffffffffffffffffffffffffffbffffdfffffffbfffffffffffffffffff7efffffffffffffffffffdffffffffff7ffffff3fffffffffffffbfdffff7ff7ffffffffffffffff7fffdffffffffffffdfffffffffffffffbffffffffffffffffbfffffffffdfffffffffffffffffffffffffffeffeffffffffffefffffffffffffffffffffdfdffefffffffffffffdfffffffffffffffffeffefffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffefffffffdfffffffffffdffffffffffbffffffffffffffeffffffffffd9ffffdfffffffffffffffffffffffffbfffdfffffffffffffffffffffffffdfffffff07", + "data": { + "slot": "151715", + "index": "0", + "beacon_block_root": "0x3fe0c30d4be1a2e83c5109a35fd811fe20f783952199e0d10b485985510edafa", + "source": { + "epoch": "4740", + "root": "0x75198e06e7a0fe301a524212e6376d2222e421fb3cfd1ef0dcb637bf6d20deac" + }, + "target": { + "epoch": "4741", + "root": "0x8bb6fe4f7ea104312914c88ac84534e4da2ff8207790060f4ba903aaf231678e" + } + }, + "signature": "0xb1653ef5666f3ec1ef9ba39036cc6a361b96b3b82ae9ccd6aa7c83c63e358843c054de6022915421360c04ab343b4cee104f2d5d357454f0ca5d86bc24f2524520f27621624c3e78b0e0915a59cd3ba583eb380dbf984265ffe720eef9201b04", + "committee_bits": "0xffff010000000000" + } + ], + "deposits": [], + "voluntary_exits": [], + "sync_aggregate": { + "sync_committee_bits": "0xf7f7fffffffbff6ffffffbfffffffdffffffeff7ffdf7fffffffffffffffffffffffffffffffffffffffffffef777dffffffff7ffeffffebffbf9ffffbffffff", + "sync_committee_signature": "0x99a90d385ef2a1c8d7c8d96bdfc9aa03065532f4415709efbade179de42a8b1c9b736a5d08377c3f9d3a9c220dcd95c61986ba9cc0b735b2c23ac6b8128fc5851e4057c7c469b94ae25c2d0c560793b12021dfb29d34d78e085b8cb8a952f4ba" + }, + "execution_payload": { + "parent_hash": "0xdeab769383aabae234218751c24b5c286c54b7e8545308767217c48ee8a66a03", + "fee_recipient": "0xb9e79d19f651a941757b35830232e7efc77e1c79", + "state_root": "0xb1a9669102c2f7d49af01c4831923cb6f030c6a98b334ecb4d307b6c0c7698a7", + "receipts_root": "0xcd85cea85d138342fef326c1c73eb4fc4479f1fc567e7687c5757c39b5a20c34", + "logs_bloom": "0x00200000000000000000000080000000000000000000100000000000200000000000000000800000000080000000000000000000000010000000000000000000000020000000010001800408000000200000040000000000000000000000000000000000000000000000000000000008000000000000000000000810000040000000000000000000008000000000000000000000000000080000004410000000800000000000000000000000000000000000000001000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000000000000000010200000000000000000000000000000000000000000000", + "prev_randao": "0x1e00579f0d5b1861c9e0978a213dc67e0fc4296458f392e378d06b4b85b4a8c3", + "block_number": "141529", + "gas_limit": "30000000", + "gas_used": "207715", + "timestamp": "1740424464", + "extra_data": "0xf09f90bce29aa1f09fa496", + "base_fee_per_gas": "7", + "block_hash": "0xc8807f7a1f96b0a073ff27065776dd21eff6b7e64079c60bffd33f690efbb330", + "transactions": [ + "0x02f9017b8501a588771083013b2285012a05f2008512a05f2000830249f094d27d57804f09a93989e290cf12cb872c39ad2ad280b901040cc7326300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000005693ed58622afdb000000000000000000000000b3db4f6329df01ac317a70200f6614e1cd0db6f7000000000000000000000000fc7360b3b28cf4204268a8354dbec60720d155d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000d0ada425f6835193b8507d7de3a77ec1bd6c5377000000000000000000000000c8ae6c2d3f6695e41b5cb149beae76600f4ac97dc080a0ee5a62cc99129e5aad3d6b2de4f169dbcfc3b17878bfa9e944879f2899f5d16ba013bc53a251af668e24bfd2157c52a7168e5cbc235cd3615b6f5f733e0bdfc5c2", + "0x02f8d18501a5887710038459682f008459682f0e8301395c940000bbddc7ce488642fb579f8b00f3a59000725101b860aa01b02b16b7a56850cc9b7e1275e8d49e16fc12bd30b4bdf2ef68b5543822b2466101cb541b8815b5ca1721120e4f9da3dc91086418a5680fe3037dba62dda3de79dd22bb41036719c3771f140b419586ae7d9bdf3b10d88850909d4556b19bc001a07ce67cc0fe3ce5e16083414de6c422bbb8d61e2f345b25fc60c8bf58af8a52d3a024b28ae0bae9e75bb588466a4a0ec84d27b4df8127dc58a50cf80b2edc5add54", + "0x02f8708501a58877108219a7800782520894f97e180c050e5ab072211ad2c213eb5aee4df13487025494cb85b9c880c080a08a3568a5f66c85d336f3b98586760753bf3960dc22b5a7edb7551fed54637727a033e49b70c561443b3cccc06e8656e4ac23820f1911800473776d92c0a6014f1b" + ], + "withdrawals": [ + { + "index": "491304", + "validator_index": "71416", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491305", + "validator_index": "71417", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491306", + "validator_index": "71418", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491307", + "validator_index": "71419", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491308", + "validator_index": "71420", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491309", + "validator_index": "71421", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491310", + "validator_index": "71422", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "59212" + }, + { + "index": "491311", + "validator_index": "71423", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491312", + "validator_index": "71424", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "59263" + }, + { + "index": "491313", + "validator_index": "71425", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491314", + "validator_index": "71426", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491315", + "validator_index": "71427", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491316", + "validator_index": "71428", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491317", + "validator_index": "71429", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491318", + "validator_index": "71430", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + }, + { + "index": "491319", + "validator_index": "71431", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "67541" + } + ], + "blob_gas_used": "0", + "excess_blob_gas": "69468160" + }, + "bls_to_execution_changes": [], + "blob_kzg_commitments": [], + "execution_requests": { + "deposits": [], + "withdrawals": [], + "consolidations": [ + { + "source_address": "0xb57a360b34e22c598a9b0da37c5b9a7825da4db6", + "source_pubkey": "0xaa01b02b16b7a56850cc9b7e1275e8d49e16fc12bd30b4bdf2ef68b5543822b2466101cb541b8815b5ca1721120e4f9d", + "target_pubkey": "0xa3dc91086418a5680fe3037dba62dda3de79dd22bb41036719c3771f140b419586ae7d9bdf3b10d88850909d4556b19b" + } + ] + } + } +} diff --git a/beacon/types/testdata/block_electra_deposits.json b/beacon/types/testdata/block_electra_deposits.json new file mode 100644 index 0000000000..46dd0a44bb --- /dev/null +++ b/beacon/types/testdata/block_electra_deposits.json @@ -0,0 +1,305 @@ +{ + "slot": "151016", + "proposer_index": "27017", + "parent_root": "0x2f135d2fe887c6012e78b25b8adecc33bc268c8057e444422f9fbdbb02730a30", + "state_root": "0x62a65efc3b24c02a29c4fdab5edf076329024a05dfc944b35f920a38d07b24ac", + "body": { + "randao_reveal": "0xb765dc7a976fb26b7cf8df404055cbab5e7665dfc1106ed4373709840d99312fb5f782a44c25294cece2f55e0cde6d1515504693574ddfb9bbcfb47c21763efed46b91cb47cefb5a14c78dd53f491d51e40b36eaf26e23e1edc49875e8c734cc", + "eth1_data": { + "deposit_root": "0x8654042dec994aa6fc1a36fd0f4ebb2a49d1b27ada9460b045e2ea2a15718cc2", + "deposit_count": "10010", + "block_hash": "0x28f59400e7becd79cfe3b14f36dd58fc27826849247dbfd1e4d09448806f8955" + }, + "graffiti": "0x6c69676874686f7573652d6e65746865726d696e642d33000000000000000000", + "proposer_slashings": [], + "attester_slashings": [], + "attestations": [ + { + "aggregation_bits": "0xff7bffdffbffffffffffffefffffffdfffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffff7ff7efffffffffffdfffffffffefffbf7fffffffffffffffdfffffeffffff7ffff7efffffffbfffdffffdfffffffffffbffffbffffffffffffffefffbfefffffffffffffffffffffeffbfffffffffff7fff7bffbfffffffffffffffff7fffffdfffffffffffb7fffffffffffffffffbffffffffffdf7fffffffefbeffffffeffffffff7fffffdfb5dff7fffffffdffefffffffd7ffffeffeffffffffffdfffffffffffffffff5fff7ffffffffffbffffdf7ff77ffff9fffffffffffffffffffff7fcfcffffffffffff7ffffffff7ffffffdffffffffffffffefffffffdfbfffffffffafbfbf7fffdff0f", + "data": { + "slot": "151015", + "index": "0", + "beacon_block_root": "0x2f135d2fe887c6012e78b25b8adecc33bc268c8057e444422f9fbdbb02730a30", + "source": { + "epoch": "4718", + "root": "0x6567f31ab5ccc3a0b0cd5d27abf183ed36704f817d09cb9dbe183da83cf07bf2" + }, + "target": { + "epoch": "4719", + "root": "0x49ce68a9103d485d81d74d0c744a3fde20657c4cb81fb13b12cee75a2a29804f" + } + }, + "signature": "0xb7ad39b499b0e5b8a22849b068c98a08fe611d45a2f43e30fa449e657436e685e9e2a9bfae3a3128baf939f4394c0f2717835b0756e3177cb38d58775618ff6607fb68f362d60b9f865daff0ac239da49690e8fe439aa0dc27e2d4196beac98a", + "committee_bits": "0xffff010000000000" + }, + { + "aggregation_bits": "0x0108000000201040400000000000000208", + "data": { + "slot": "151015", + "index": "0", + "beacon_block_root": "0x2f135d2fe887c6012e78b25b8adecc33bc268c8057e444422f9fbdbb02730a30", + "source": { + "epoch": "4718", + "root": "0x6567f31ab5ccc3a0b0cd5d27abf183ed36704f817d09cb9dbe183da83cf07bf2" + }, + "target": { + "epoch": "4719", + "root": "0x49ce68a9103d485d81d74d0c744a3fde20657c4cb81fb13b12cee75a2a29804f" + } + }, + "signature": "0x833659ce0cf0ea303c1df6d0754f5303392789c91498635bcd339f0056c496e770072f025eb962793105137c424d80af05a6ebe8d6e7f9de48121fbc362b91d1644f23ce3728ddfab680ff2c064fc73a049389116a56409ae35d675b37c59e92", + "committee_bits": "0x4000000000000000" + } + ], + "deposits": [], + "voluntary_exits": [], + "sync_aggregate": { + "sync_committee_bits": "0xf7f7fffffffbff6ffffffbfffffffdffffffeff7ffdf7ffffeffffffffffffffffffffffffffffffffffffffef777dffffffff7ffeffffebffbf9ffffbffffff", + "sync_committee_signature": "0xa7be0f119fee5d9f9409d508b2291e1d8d81d3b9edd64d7a68d12f9b1a84bd50230618e4db78ef6e7f1e2f3e6aa56e2807985b25d52750a56b9d1b087ae3bca80c3a0b091e52c3797d82778acdf877e42b8fb18598d9fc56e9e469ebdd5c15e1" + }, + "execution_payload": { + "parent_hash": "0x52ad968c44fe260e5bb67b63c3ede2ade269a23641d27fcceba237065784c89e", + "fee_recipient": "0xf97e180c050e5ab072211ad2c213eb5aee4df134", + "state_root": "0x34ecb1a20d718e06f69e4ec6b6ad86c75603149a207480b03a077d0231668805", + "receipts_root": "0xd2da2f149a53d2c26982187652ecdf1114ae5301359c0ee6752c2b78dd97ea02", + "logs_bloom": "0x10200000000000000000000080000000000000000000100000000000200000000000000000800000000080000000000000000000000010000000000000000000000020000000010001800408000000200000000000000000000004000000000000000000000000000000000000000008000000000000000000000810000040000000000000000000008000000000000000000000000000080000004010400000800000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000000000000000010200000000000000000008000000000000000000000000", + "prev_randao": "0xb45479ddbad8fc0733b7762aed1a5b5861712b29bc20c2c0e34dc5e6722e82c9", + "block_number": "140858", + "gas_limit": "30029295", + "gas_used": "2383293", + "timestamp": "1740416052", + "extra_data": "0x4e65746865726d696e64", + "base_fee_per_gas": "7", + "block_hash": "0x1f2637170986346c7993d5adbadbebbf4c9ed89c6a4d2dff653db99c8c168076", + "transactions": [ + "0x03f901198501a5887710821dd184773594008477359407830186a0946e8d9c2108be0894bd30c8525c71d1bbcb31912e80b8808b177fd73255e0d6bd6e8a142b0572ba8f34d66075cf829e3fab19009fb1a8a5d057276080527fd8fff3f3f4d3b02314aa185d801e8d378d88992aa540c8b093c1e4264b68777c60a0527f69df553e04f0a6a7435a5650668958d47f9d4187d2ff2e72a91d8d9f74928c8c60c0527f8d8f0c90c68115c209dcec644ae93d4d05c0830f4240e1a001359c559c4114b7919abca725d032f48ab4519d2857567795ca4f49345e65a280a091007fbb893a18315106cbcb53bf044d6a5c0ea7098e0b6198727c3983ebc628a06c9abb0a1ded37b6305a5711831f03fce5e467a70dbc9c0c724ebd18b200a202", + "0x03f901198501a5887710821ae084773594008477359407830186a0949ae53a8e1ac8eeab1feece735b3d840634e30c4980b8807fb45278a2777c8ecd11eb2c2052276fd12c86bdb2373aa59d293c6b0ae1e8df076051527f8c9bb0742b467c164d5aad3087f92355c3f8cd0c291ca87b086e86fffa73780e6071527f8b11001c065ced40db4a5b2c43de47fde7a3b22f8919b39acd8d0b309df8a40a6091527fa49bf4a805c16f59556bec2665b647e02cee4fc0830f4240e1a0019da1702b651bd92e079ca2e801671cf22f3d3b6c097a185275dca50784123f80a039e483afa3751d7d758f2273fb19ac2143e5ce225eec49244f0aa358dc9fcb13a02e4a552312d68db400acc3898835e0aa32f46b8ef786ad6e2fbb0d933c51c551", + "0x03f901198501a5887710821dd284773594008477359407830186a0943c9f26a8f3c71bd76665e89a50f5f70d9953901e80b880605c60fe5360ce60ff53606f61010053604b6101015360fc6101025360396101035360e36101045360b36101055360926101065360e061010753601461010853605261010953607361010a53609561010b5360c861010c53608a61010d5360d261010e5360bd61010f5360ff61011053603461011153603761011253609e6101c0830f4240e1a001f8b21450b076ae1037e2e42f8a6899f01f793a2bee9f59e00ee520af66d56a80a0e97e75f469a7478d725c078e7d5b6979018753556850a61cfcd01cd2c87f02c8a024a8247013e502c09f4d7981f912995c44978f9680c261829bb3f0ec86627ea6", + "0x03f901198501a588771082398384773594008477359407830186a09401abea29659e5e97c95107f20bb753cd3e09bbbb80b880600060335dc61f7ffede24c98d6f2e886373c1dd99c824ad17b93cd6cca65a8856cd72972eea737960665260b3608653601a60875360f660885360ab6089536024608a536043608b536001608c536038608d537f15db390ca3613b231b40c801210901ec898c67f53aa7864f903944c3e3568817601b527f23a5a30cb6c97aa2c0830f4240e1a001c543c4e8d14cbdfb690f66b63b8b4c4fbd3963b1a555c6ab3ae43b08367b7880a065b7869dd9655457013e3e88c7866205124bec055f51b41e1fa92acce78b994aa07b83ebb8f12ba28df90ebd3eda8858204f2ff0eccb7ad8be10fafcb249bb3fdc", + "0x03f901198501a5887710821ae184773594008477359407830186a0946a5e2c588bb18c17cdadb44f82d22a895da0d62480b8806000632a674ca35d600060f15d60e249603c49604d496097497f8474c6950d31f88091bd7bed171350e494e797be9c933f1288dabacbbb84810e60c1527f84f66da36ef2af9007aa316630acc16ee30260d66c55ec449fdf03fb20860c8660e1527fba2768ed15416619a048e1b79c81583af46d1f3ff8141279fd98cb2326e0c0830f4240e1a0018ddeb1837db4291ad48990f90ac5bca82d10b9d3d73eebf1aa5c314cf91abd01a010004635691cfef330e4bb27701074e719e65c037e4182be65becc5e1945522ca02cb00278eb15a555f9ce56dcdf783135e8aa6c852816497d389190e63ae304e6", + "0x03f901198501a5887710821dd384773594008477359407830186a094000f3df6d732807ef1319fb7b8bb8522d0beac0280b8807f9a8968ca7a94768406d68b36a066e74dcadc49bc3605fdb95370ae9040470a4860eb527f0d8c1c38ee4b5dbf2b28f10ecc705f9cd2a9a36cfeff6c433efb8bd7c99626e061010b527fbbc1026522b0e497dc9722fc477fb7344969fbb16d66e31cc6e03de9a23178e361012b527f63ed37d8ac0e69b5609744b3ada8384a1dc0830f4240e1a0014cd492e6c4d129d4d3b22182ea5a5a632f3320aebbb6251d0ad724a747391a80a0c07736c5db2bc49a29ac00df7b32abf94978bcea15e65423b5cdd7d35df126dfa06b3f8c10978fc3e1cd60753975ed21762bf99a59fb29cd8e0a970321ee72ba9d", + "0x03f901198501a588771082398484773594008477359407830186a094dc547f9b829e446d70566195aecc6a5977e5860a80b880600060335dc61f7ffede24c98d6f2e886373c1dd99c824ad17b93cd6cca65a8856cd72972eea737960665260b3608653601a60875360f660885360ab6089536024608a536043608b536001608c536038608d537f15db390ca3613b231b40c801210901ec898c67f53aa7864f903944c3e3568817601b527f23a5a30cb6c97aa2c0830f4240e1a00150e9783b2dae0fabae7243e90ddc1dbab17e6a0934ba2434aac62f27cdb2d001a0ad1f8b4409159784a76bc7abe3a89003139274ff8215bfb50da2ffaa8b312cc8a032aa53063bbae96713f93714c830c536949c843cc09a3dde8cb2ebdfcfe5d613", + "0x03f901198501a588771082398584773594008477359407830186a0947a40026a3b9a41754a95eec8c92c6b99886f440c80b880600060335dc61f7ffede24c98d6f2e886373c1dd99c824ad17b93cd6cca65a8856cd72972eea737960665260b3608653601a60875360f660885360ab6089536024608a536043608b536001608c536038608d537f15db390ca3613b231b40c801210901ec898c67f53aa7864f903944c3e3568817601b527f23a5a30cb6c97aa2c0830f4240e1a001bae560947db14e3ed438ca8504783d40c9047191f49933b1d5e1ec8208583a80a0237ae7f13f17c0f994513c83636e1ac7e4d7c722221b51778352dfab41864310a036cba8ec5a2d31e6342f6afc914e3ba9dbfad0db22d29cb74e46e170ae2b09a9", + "0x03f901198501a58877108236ff84773594008477359407830186a094000f3df6d732807ef1319fb7b8bb8522d0beac0280b8807fc51dcb985e3563ad803460f85ed4746c57bf060d8e2259116646a0002c898fb360ea52606561010a5360a761010b53600561010c53604861010d53600761010e5360a661010f5360986101105360a96101115360b06101125360dc6101135360e6610114536071610115536060610116536091610117536084610118536041c0830f4240e1a00118b3d58c9a58f76bb27cff8ee97664f8b88ea8ec955abc1463805d2b96428d01a00eb390be8ce5900249b939af5bf2ca243ed1902ea6b1bc3bf372f8028b95861fa048dadfa661c274595edc2cf2797b9ec4dc873cd6a75d7329293f873c4335438a", + "0x02f9017b8501a58877108301391785012a05f2008512a05f2000830249f094d27d57804f09a93989e290cf12cb872c39ad2ad280b901040cc7326300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000ee86442fcd06c0000000000000000000000000000b3db4f6329df01ac317a70200f6614e1cd0db6f7000000000000000000000000fc7360b3b28cf4204268a8354dbec60720d155d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c8ae6c2d3f6695e41b5cb149beae76600f4ac97d000000000000000000000000d0ada425f6835193b8507d7de3a77ec1bd6c5377c080a0bb753e1df11f4e15f7b1f44c04d738b30e0849b804bb786f7fba10edc3d7668ca05d7151817aca075c8d7bf9ba2b74e9294d28de1c4b8d3e5b138669e89324885c", + "0xf873836181cc847735940782520894fcb6e353ad4f79245c7cb704abcffe2f4868424188058d15e1762800008085034b10ee43a031323a053c2013914ed32e251907c3311e4218561cdd8c25eaf8672355e66720a046900db9b5826610a5208c61a6e0c9f64178a76caefd64037db69b997295bf5c", + "0xf873836181cd8477359407825208940d3de4256d6322683fdea9ee23765ccbfcb83da488058d15e1762800008085034b10ee44a0cde1811bcf855221edb3b337e6bdd6bf26b11c9387768fba8597daff950ad5cca07867720bce30276937c2d806024791f158a64862ec35a036ff1dbb01d16be959", + "0xf873836181ce8477359407825208946021752d8d9b2f221d4fea4349dea34ddbcfce5088058d15e1762800008085034b10ee43a0f833125f6025471a4f351c2777d5841a23e4f6002c51161855004820fb91eaafa01722b78eba514ac450c0459568b4dc9521bb797a7c601c5c8825cd5e006f71a7", + "0xf873836181cf84773594078252089461e296d527edc89e831cf593ec341f16197eeafb88058d15e1762800008085034b10ee44a0151e6c4bedcf29fafb9ef50f81f7e573d75ba42e00c46e91b9761de3e13cdc37a047bc54be6c3493ceb0949a3324ee1cb93c8058c9db71fbfb5c16ffdb472c0fed", + "0xf873836181d0847735940782520894cf7317ee7a3b497ecf634b94bff60ff91b92574788058d15e1762800008085034b10ee44a0c6e018c4eb28bab20355104705e0570a371c157dc592e503713bcce730953d76a0279412202acdd26ab9d03c2edb129aa974fc39c86a0ecbef410c0a69d27789d9", + "0xf873836181d18477359407825208947e7b519df31f77ced83eea1b16aedb6dcb0f0b2488058d15e1762800008085034b10ee44a08fe9e5cd6238d8e3e21ab280bca46ce43c23620b1f81b386265efbcbdb106385a018945e95e62a6148cbf35649e1e2ec4835491b4e4b6216e316c4932c96220ecb", + "0xf873836181d284773594078252089488a075e0fb1c9309a200a8bf0a88b214bf7ceb8d88058d15e1762800008085034b10ee43a090b175e1335dc2c4450dd3a0543e19e2635aebea5675c94eac1cce52c7ce3d64a021aab7cccb861a1c30d876526a4ef0b7e217d784fc89cbd02e8c6d63ad35b0ba", + "0xf873836181d3847735940782520894c8d7cfb58f3ac02568e6505bf3fb5eb6f080703988058d15e1762800008085034b10ee43a06d530baafa0a899792978df61bf5adc6028be85be12f55c687e44f1740dc22ffa06d4196c744ecfed500c4ad0fa17947c12238227155acea265edb7c7461571259", + "0xf873836181d4847735940782520894e0132e8d7b1b766e0ade5543d6c6c0b2d5a2f01d88058d15e1762800008085034b10ee43a007e42562bf3a9a058fb1803d7c423ea0d7113fc98788be2a6b4d982210066139a02a24a9efb9f88cc53ad464b62601af3e54fedd8305e1b98670bfc8dab223c596", + "0xf873836181d5847735940782520894eb674c0411db79654afdc1e131f3b6e734baee6c88058d15e1762800008085034b10ee44a0e197786db41e4d21914f319e669aa504f1e821d2cd17b39a396b1b85b5348025a00b1efe1355fcb919642f14f7609893afe70017eaa999d531e6f77fbdc5d28029", + "0xf873836181d6847735940782520894dc07c60993cf689438b8c85f86b0ed938dca77ea88058d15e1762800008085034b10ee43a0f00a06c5148f52c55b2f65668a757c9d0011e7924032b88c771e3934e0bab6a4a0480e37e4cd116cedecd7de44cdb91c698ad896abbd3b08e2651773dea497e8e6", + "0xf873836181d7847735940782520894110ddc93db59ed31a03518510221ec2f35d28f2f88058d15e1762800008085034b10ee43a047c9b1fb51b626b40cb2707269a8ad6a7391c467864e4423efa3b4ede8bf6d3ea028314d010ef79d04027fec9c0efb0bbad7ef386e110bc8e07797e78f484cb51d", + "0xf873836181d8847735940782520894b599a876aaac824cfce21bdf15627c9fd8634c3088058d15e1762800008085034b10ee43a0630d66f57eae656309cdcf02dbf20db3bf960c77fa0c66b72de13b7852b0c8d7a00541603caf792d410387983650ec5799d9eaac5761296b3ad09f26fbe40fe251", + "0xf873836181d9847735940782520894d36e5540dd71acbd6416d60252c4d7c34a3c824588058d15e1762800008085034b10ee43a0dd6a775844cc76e89ab1b2bd43d266b3b1b6e34a8d129cc1c1f7ce28c44b2439a01ab09f383573d80274ed64053a079902796c2e6e4cc19abf0271d37e2db4a0d0", + "0xf873836181da8477359407825208943adeca35af56206a74987a8fe13c669365c770cf88058d15e1762800008085034b10ee43a0a8f36c6870413fdea217d52c0b6bb3d6b55a837e7907ad2a3979da577f9f1763a0646ed9c93233cae748988a3a33debd3411706a2a88c3349d2702da1b5a728cea", + "0xf873836181db847735940782520894d77b95acd12f7b4b5692b55717b7bbca1165195488058d15e1762800008085034b10ee43a052069ecf399b7323e46892858d2d99668d7554b581245656d97768972f533683a009824b000ffa65ec5acc5210674b12ec2b92f45214e2af2c541a9da825baa9f6", + "0xf873836181dc847735940782520894f388bf5766b5ed5d4e1cbf15772e677dbfa80b0088058d15e1762800008085034b10ee44a0532fcb541538ee4041bd97e09c0f86fde22760d4d3e3922b48d2fec22c41503fa00aab5d1fc4438ea787d42f08508c82cc8c9940583217eaf25e9cd12e53241b4b", + "0xf873836181dd84773594078252089435d4996296e58560e6ef47787d51b55f1e2bd92a88058d15e1762800008085034b10ee43a01c2172f632447d91029c0bb197b6f29c6f16be40ddbc45637132aae1734dfbf2a06c7e9868cb7e95d72edd545e173887a45d405e3597da99067985d8e7343ba224", + "0xf873836181de847735940782520894a4c3b77b898e53d6095f11c53a1ce272cff9af3188058d15e1762800008085034b10ee43a02ba7caf4ef662c4a459f11d2ff90c970c8b4d5ab27e201b8f80e12d763a46f57a02e1f114037a153d9ad303e5633753785bd7c73c5cb0b9f3bb8159312eb0692a4", + "0xf873836181df8477359407825208946e84f6113fc1919714f0266705813fb81a17181f88058d15e1762800008085034b10ee44a07ac801acd1375d7bc7d5a7e54553be58976519169de1e2e14186494087a0b4baa043a9a4311283cbcbca29255de9e3bf1e688d73a0e4e20ff8d8b5a2e16b6e630c", + "0xf873836181e0847735940782520894e9ae1a806004e1452baae0493920815aadd8479888058d15e1762800008085034b10ee43a02fb8319f5613dbf37419d177b132306a7c55b2d72d04522d6eceab27ddba4f82a03f1b125a7c93ff5e6c278df26ebf8411fd9317112424a26dabc5a23557712272", + "0xf873836181e1847735940782520894fe1905d8ebd20e037274eef441283c811ea82c1688058d15e1762800008085034b10ee43a0224ee510dbb1e0ef70a7a016bd1512039fcf3af0af9a34b9b1cc2ee90a002339a02b7a11a1ff4a20c1253069e4b899ef0aa2f2702c3c4460d478f92a9a43e00b67", + "0xf873836181e28477359407825208946adece88e477f53a143a4c29d97940df2ec768e088058d15e1762800008085034b10ee43a08590ee9e8715492a2e5c1390f4e389143c410e1d416f5202994b516f51e7eafba03159c4853aeaf69bf1c44c4e6cc8e449bc7d42eba79384cd8b133659d38159e5", + "0xf873836181e38477359407825208940d34d140a7376892c4593fcea3ae26f5d6f202d788058d15e1762800008085034b10ee43a01a115564422f4e9fe3d1e51202e25ad90705509c2b827423bd9a766d67e6c6d1a00fbc0b850c9835c6a75a4baef78f29458f592ca83447dbe1c5f14c38724a86d0", + "0xf873836181e4847735940782520894d1c7fa75b9bc55d041fcdf215f3e3a351c9f9edc88058d15e1762800008085034b10ee44a0f1bcf05bfdd6d0d2a4345f86c2875dd7bfa685745427754fd3b524a69664114ea0674e3c62d1e0b5ac4d79cbc972ea51e2183201f879e17b9061671107089fcdda", + "0xf873836181e5847735940782520894418ebe350a8c6387bf5e42f3502742af8e0781f188058d15e1762800008085034b10ee44a02b5935a36f3240d235d2574f6a0d97f432aa4443da752e1101479a9392b124d3a0674f43bb33455d22e08224c584a2f206cb6ac4a86aa312f8d63b75f99fef5764", + "0xf873836181e684773594078252089484914d2770c711d27888c775c547b1d933b48c4788058d15e1762800008085034b10ee44a0c94d55923ef4bd2e4c0a83f31e36dc49f2ef84bda5a4dba429795ffe33bb6574a04101d4d64e212019cdeb93c8e2ec7488405c2f716acb64e5ab70ca4689c4a370", + "0xf873836181e78477359407825208948f51e560b85edf2e653c689c4e9fac02ce0556b888058d15e1762800008085034b10ee43a081e8fb2724b676b50ed6a9dd02a3dfdbeb1cd715cbe485cfa98a204c5a7a35dea04d7f13607047239a65d798a199a66460d89f3334a79f49587fbb58ad499e1a1b", + "0xf873836181e8847735940782520894ee2503205c24dc66346e356f13f333fb8782d35888058d15e1762800008085034b10ee44a098b33a8231bf024845d5bf52add950edc4b1c53f23b03b8b5439ffcbfa034522a03dced7a7342c7d2eb201d8225009a41527dd98f7a6475a8a65660feb4c68d6d6", + "0xf873836181e9847735940782520894096ba6c59bd667a0fea9a356bcc988e4d9f2d8eb88058d15e1762800008085034b10ee44a0c3a8d920e1f80f5139f70822ca6c899edf0bc17c8fb3c7f3a1318ddea7d62c7aa054e14fb1325f2a23214fc6ba3abf11ea547e01a1d95a3e490c3b1f9af277ec90", + "0xf873836181ea847735940782520894da0adce4f1dc7debe7b2b52e8fe9ace6c7ea9c6688058d15e1762800008085034b10ee43a0755d9805b1d15d1392d860e86df05834fd94a61d18c22956907ac7c1bc982892a063de885856b515242c33c31f9cee81d23aee55fd632b88d86fcdb3f8566af3ef", + "0xf873836181eb847735940782520894af7d412aeab7525c0541dc3aa6c1085cfb8c909988058d15e1762800008085034b10ee44a0b91c06dd7e4010c5d7b3f66285f4c139e22480773fb053409950ffe5bce7b720a0397f1b6ef9424dd5e30b07c110fa5b009cf86bfe92a98e994427d595dd9586fe", + "0xf873836181ec8477359407825208943cf8c0d567261eaf4ac0872d33a9f48af361769f88058d15e1762800008085034b10ee44a0828618325c9586073c8199d866e9001a7b9ae129a29cc60cb43aca355175b13ea07f885bfcc7b096b6c47e0122bef7f0295712f0810a78ab4f0b53112561d2c84a", + "0xf873836181ed8477359407825208944779242587ba9e828999249eadd82984430f484388058d15e1762800008085034b10ee44a0dd150d77fe8d9073a20510992f5eb8c70380327f5483064a6f42fb547465ccb3a04cb3406733b1e7318315255edccbad06adf0e6a3fe13f01389c5c95245cc8150", + "0xf873836181ee847735940782520894ea531cfe2de357ecff3855b88dbd07f60b03cdca88058d15e1762800008085034b10ee43a08c72279cb318e4dacdfaf265959cd7f31002a1521113bc7e65851ab8ac2aed06a008340ab82a4a61f91d3e5f4594629b6a422fe11e8d6b39b2a145eabf15f3bbf8", + "0xf873836181ef847735940782520894d00b5f53ea2a66ad33c3fee304bb22857dfb8a8788058d15e1762800008085034b10ee44a0ebb567f7d111eb54667984476e3a271c99220942e20e96f713ef9b4ae5728404a040bae6c5b88e58b0e02d1218df7ae41d9b3b99d2180eddf8ba770976852de483", + "0xf873836181f08477359407825208947ead29f6616f78f21a951c9686dd257be7b8efe488058d15e1762800008085034b10ee43a0f749f26b7f700cb7bfbbb6e37206553e64ae70307f33cb60455bee1da135d4a6a072467439050b5a0d411d90c92fe6fb17676189d3fa8a0ad27ec4dbcdc03c14cb", + "0xf873836181f1847735940782520894d503c13ee55c1ea128357d4018ec58d0d5e5c3db88058d15e1762800008085034b10ee44a0adbe9e31e5a740ee0b52a69b0cc85a718c799309df72991bc856c364f9b85f28a051a55333b441a7255a63e0fe6918aff4b6269576ef99763190c784624f8f7e45", + "0xf873836181f28477359407825208944ac670d8760faf780468638ef80034876ed8918d88058d15e1762800008085034b10ee43a0636ee52b3e021114085c7413cbaab77013b432fd41cbf0a88dbd8d145e8a1125a02d15ffe159ec762142907b2e8b5e04b804361a399b23ff335ee4b996f7ee0a81", + "0xf873836181f384773594078252089424ffb8c97ce443f8d3265ba3316defcfc07c659c88058d15e1762800008085034b10ee44a03c4c9d42c3a76c275f8f167cc846e62a16e2d4f54418b0303f64f0a1f2122fcda034d0cd15b9d14b118eb7a2e5bf9a464043e5b1935e740ca557fd05b47328b092", + "0xf873836181f48477359407825208940c5cafc547ab98c9ceaa1c07fdd6bf7820aeb95488058d15e1762800008085034b10ee44a064728de799b66a56f3f634bca37944e0027ab9be12419d2e976bacfe295c5854a03a4b830c50b7c1cf39511b592ac20634bb54e6afb795dddbfc6c322bf6ac85fb", + "0xf873836181f5847735940782520894db8d964741c53e55df9c2d4e9414c6c96482874e88058d15e1762800008085034b10ee44a0d56eac7a793978c4a8356bf94024e3fe292d9f61f594c3bc847a49c4c94df56fa059b143fedac3f768e936b63291180c1fe34415d27888e1b90326d28b4567fd53", + "0xf873836181f6847735940782520894ba85bb35ae6ff7a34745993fcf92b9afd34124f188058d15e1762800008085034b10ee44a0b368c25c6edfe52749b1377664c2886a5c09f89d12c63078ba635dad22ae3ec7a004d02d8cec691a288092fd337f4a9c18eb4d15493cd512cb963a3be9cd9c0b04", + "0xf873836181f784773594078252089458871015f5a2d3948264f7c16ad194c80ffd531d88058d15e1762800008085034b10ee44a0c6ecc87a4c18d2476757ca03080992de68e24b16826e35d0a26b6d137a4b6be8a065defc8e1b910d228675e323898baf81d24633cf57549021e64678e4e41bb78c", + "0xf873836181f88477359407825208942a90af45df70b0031f218cc122598ddf3e10469f88058d15e1762800008085034b10ee43a010c9e461dbdac507e73c5c2092f83c780fd91de482b1db746544dca8adbabb9da05f1c695251e7fcb4fa0a655f5d64845e597fb3f2a948326dda2e7a87fa74ea50", + "0xf873836181f9847735940782520894761bbaaea6ceb265f5262c3b559adc2ad3ed2f0988058d15e1762800008085034b10ee44a01e238f26c7ed2a54504a1ff05ab2cdffd5306c80281f61e3a93f950b2c965014a00739c6e4e75c3c312636bef62ff6fb8a1c0d0c71dd34f117e19bc58fd9353e1d", + "0xf873836181fa847735940782520894dfe86f51c5e603f1420d1f0ab366bd3bfe23d2a788058d15e1762800008085034b10ee43a06994565ae218ce6ce28078aa4924a01207584026a892fd82b4bc8c187d8bf1c2a02b44cbe2120bbf57c777b2321e2b54e3d8015a6484e109bf761e07e38b22c9d9", + "0xf873836181fb847735940782520894d616547158b05ab5079106dc0336d72763a7287188058d15e1762800008085034b10ee43a01559edc6eb87baba522ba21cd45da85f76be8adceeca311a378035d723efa31da063253dd048dbe7e7c7285a5b1b23dfce7655e060c5b9523f56c6de6b7fa30ec0", + "0xf873836181fc847735940782520894dc68cd278cb7f5f666ce7b0a3a214a8540ed4dfa88058d15e1762800008085034b10ee43a067f63eb982417af7de349aa9cf07889ed0d7423407995926b8044fe7525154eaa00417db33f88ae9c142950ef84ae18f47445fa7c26b6a482df6ffb5e13ca89cad", + "0xf873836181fd84773594078252089411f8107da05b6905e8cc0227ca3b0c6eb764fac088058d15e1762800008085034b10ee43a06594ca7cfdb0ee036f1735bbd3f2971be1da00edefc122a0214807828a7ead31a075a11a79283bd39456153246494d408c61f18f27022c4bb888b5742e1c66e3ef", + "0xf873836181fe84773594078252089404da906545679850a7ee0ef6836e183031bedc8888058d15e1762800008085034b10ee43a062c55b09cc71c0c3e34bb97dc8e3d9e9918929f0c9490309090bc430bf6eb722a05f733500640bd0f6e61952424a3d9bd5dfde0ba3cda5be598489f0859df6c919", + "0xf873836181ff8477359407825208948bdc25c43c010fd3db6281fcd8f7a0bed18838e388058d15e1762800008085034b10ee43a02518ed9188048e9a9666de8a3983dd208c2e582a18720a2605baaaffdb2ef4aaa0510893d599ed7e303b7027e9c9453a8f25409735ae782faad9fb3afefe4e458a", + "0xf87383618200847735940782520894af16f746b8a834a383fd0597d941fee52b7791eb88058d15e1762800008085034b10ee43a0d8b4839aed9b334066a24ef5295f456fba1d0fc6d783b7d18012cdb2c18861e2a07a74bd5a40d360c32bceb00be00d3e6e608f39b04a13ecc3ed4672900f5c54b3", + "0xf873836182018477359407825208940c5c736600f8ea58ccb89aa72e3f3634651fd55188058d15e1762800008085034b10ee44a033c53fbdc9c86cf60777c5d2bd192f57d36628c672a7ca61352effbe7fa781f4a01943da2502b48ee6b3b936769270da655c8d955c9a390e0c186ee5d3646d1d27", + "0xf873836182028477359407825208946f475e0f0e9eda58556fddc04de9b1a9b6a4cfb488058d15e1762800008085034b10ee43a00a00563e58ee9203cba306e432af000938b1e2e2daebbb7d06210c0b3cdac601a05d0f1492b63df3df5ac1310fccbdc3e0863d8c3c7231186df265d32abe00f87f", + "0xf873836182038477359407825208949b2e76498a695c4dc7d0890069cffa84a9581d2488058d15e1762800008085034b10ee44a0cb83570f01c24cdef394144b462fd9b7753337794a84fbb89c68e40038491487a03cb5dbc916553e4534921cc0c0d7e9d3c12afc7bb345ecf88e030c8d6f275a1c", + "0xf87383618204847735940782520894e2d2b2069f4a54fcc171223ff0c17adbd743c28588058d15e1762800008085034b10ee43a01e6d349911a4261a944c289ec6594cb1d6414fbc96240ea5d0a134cb75cf5ff2a042dcc7cfe31d1260bc5093627e0fbace0f87812d37cfbcffe7beff500dfff385", + "0xf87383618205847735940782520894386bd49f04322544f3c7178fa5ae1a24b947b45488058d15e1762800008085034b10ee44a06e76a8890665419b746548fd24bf999efa9eda82b509a2a13dff3c8d8774d239a00c54e75e6280c2368a3cc742f1c6c6d4853cdff6aa71afb3b59939283a70ba70", + "0xf8738361820684773594078252089400af839c3fc067fafc2e0a205858d6957f0dd18d88058d15e1762800008085034b10ee44a06e90bb215dedf42450c3529ecacc852df6fa5c4d76b04b673d2dee5162f77afda061c0f17a6fb4eaafd5c1792bd780e256ae93b8197eba1f739d3483b6018b34c8", + "0xf87383618207847735940782520894ebb6d32a650afa9221b55a11c6a6de52b6f07cd788058d15e1762800008085034b10ee44a0bb5b7a794279609699dcfef3544af96e2f36e1a080d9df5ae2f0d065d897e7f6a020b02a03622daf550239dbffa1d81c3637dfcc4267f19ec86deccf77005c7b3c", + "0xf87383618208847735940782520894011d26a3a9adc9203c8943a6a77aa8657af5242088058d15e1762800008085034b10ee43a0033c85b6bc49bc1122163ed03061ffd5a580e70621a77877108c975f6280374da03a2ebd53fa8a5b2c0676e05e87ce8ae0f64f2a1304c1c01fb0a353ca084123f6", + "0xf873836182098477359407825208949c85bc61a89fb5abd957e6c819c653fc1aa0d11b88058d15e1762800008085034b10ee44a02c511d53e802a2653fe1284802c56362ce7f36936030da8f2afabc9369812b8fa02ca196683edf5a07038d65d12d23b607d331558f8e8bbe1bb3638b3f87ed1e5d", + "0xf8738361820a847735940782520894bd8e8435b7897d87cf7cedb5cf8c5dd865dbf72088058d15e1762800008085034b10ee44a0dc65a971d20e6b631f9ce091c891068600846b80a519b897dc90d85cf493b67ea075b4159b6bb958d789c05bfbdab2f58bffe006f1bc6481f5e5fbd0c0de87e0ab", + "0xf8738361820b847735940782520894adebee2e3ff041078b62380d001c6e51b4f1559888058d15e1762800008085034b10ee44a0dc5c31ab6d48576b337145ca3480f20403342d4632db7e3c58a5c2a3722aad36a0088bee3e8da14156e74abd4b830ce7dadd9aa5acc682b0a5f441e2c579930dd5", + "0xf8738361820c84773594078252089471e94c459c9f05085fc0d34b5f21e648e05dc6b388058d15e1762800008085034b10ee44a0cc7dd758523571aa417ca7e92ce18fa344eb09ae4030cbe67a20749a5f25cfa6a079260f268e88f5349a96d339a543c81800ddac65ded5bf66ff69bb8d2cf6ac8a", + "0xf8738361820d8477359407825208947c1fe317db82c9298b87c56c3194178271b621e188058d15e1762800008085034b10ee43a03670f304b0cfec63bbb48f6adea22daabf97cb5066464b66dc8b0c5062547c94a046ff008a93f3ce2964b77be87730cd5e4fe706832955148580869189edd18d1e", + "0xf8738361820e847735940782520894e069d1c9abf5127bdc3a164fb93b96bfa9f74ce088058d15e1762800008085034b10ee43a0118c5332b8e96e0938c49205cd48c34651dac16e06b177fe9ccb3c4a5714a818a0335ee8a457a31e10f6ece6faa85587e2527e69e7287f9cbfcbe977033091d5cb", + "0xf8738361820f847735940782520894b9bbddd1eb6ef8fb1bdc6a853d5ad7486a9487dd88058d15e1762800008085034b10ee44a0fd2a39184707e76817b5132d4f680f58b814ae07053bff5444341964029676bfa03a96b5d6be262592e72f19bc64ca930f1e76a6655d89ac3640aa927ea066f679", + "0xf87383618210847735940782520894a804387cdaf986d45831e8074efb2115af053f7a88058d15e1762800008085034b10ee44a03809b662c3a9d240d7b7f9e2cb4fb8d50b1e421b4548180704aedea809b2218ea063c9d8136461e93058f75ae91000d4e6f0cf21ff74d5c91c340209c1d04f0bff", + "0xf87383618211847735940782520894f23501d784a041fc911b4c86c2bfb1f63ec170ea88058d15e1762800008085034b10ee44a02af9b021ce8467c713e9ba2dd9a948cdc1d67dd04117868b6897831a4c9b2448a06bb0aa527519e251ec40b747f25dc7c7c2ed689022ac4dd80c4a40c37efa06b3", + "0xf873836182128477359407825208943928be2a7058088313c0fb3294014e88a3c5ed4a88058d15e1762800008085034b10ee44a098ea195f842b013d76e62b19cb989e3d853ca5b84602bad0b777ecdfebc2f0dba0540fdd9b2a2ddcb4a634bf63186c80987bcb9c19d0025ca0cbefba565e4afbbb", + "0xf87383618213847735940782520894196aa07204141478459c14106ef5e5282efe995788058d15e1762800008085034b10ee43a0b817d9e63a606c505074d41ce01c53612ba083cd4b39adaff884c869d539fd6ca06dd3bd03aefe17446e3354dcf4864a712e4ac2e4c59701a41a4f7ffbc937adcd", + "0xf87383618214847735940782520894763cbf89560e2da270000822abda9584db693fa388058d15e1762800008085034b10ee43a09b856c0c79b5f977db2d9c26992f9e2a113e86dfde2fa684ae4a28a45fdf7dd3a078ac54eacbdc28a7b98176c5c79becb1ebee800186c48b664a643ae760cf0318", + "0xf873836182158477359407825208947feaea0ff70ffc9eec2104f57f7136aff4dea68088058d15e1762800008085034b10ee43a0a5d30ceced18dbf6684a5ce409f654f359ad2d6105ca8cfb6c66d0ad18fa840ca06a3f64c8d043f06d2b0d26fde83f003aeb24904226fea3712af38e2c7c805a96", + "0xf87383618216847735940782520894e5466aacd9dd6d3bb35060a1ccc76a438de88ca188058d15e1762800008085034b10ee44a0b2646589ce46644bddfb0bbe5f5dfe9700a82accbc4ef29997094913c1ad85a1a01b65a1ac0f935af862b93dd79559b685d2c6afdf93795e70fc3cf174f95a7d9f", + "0xf87383618217847735940782520894f670980415cfe8c4f8d10645ecf974c9a2fea00e88058d15e1762800008085034b10ee43a06f2d0bca0b319a77accb02cf01e2edf5fff3f5cb38fc99d25a2d19642027e359a05223e3bce8700a92b7770fe92d7c50527505230cea7a5ab05e90c5a7959e0cc1", + "0xf87383618218847735940782520894a29115bce7829ffdd989b7cf1bdd1eac06a2cb3688058d15e1762800008085034b10ee44a09377c8d9a2e30c4c08b6d81fb5b645b6c4938d4047858668cbb6ddd3d67b2433a079e9b9182f4c0c6291a470f6dde8846b0aa729676224081d29940f0c319c54a0", + "0xf873836182198477359407825208948f528aa67dc1846c893465fa1c8c26556bc5fe1988058d15e1762800008085034b10ee43a00e35ce7ac258b4230bbc01045e9b5e1789543dbd324e975504c0c60e9cb5cbcfa057879da45fe069aa050ff7734b6e59b5e127db0f1921b973885ff3ef6aebe3db", + "0xf8738361821a8477359407825208944dc4ec6ac43c8c45777292db987203c0248e17b788058d15e1762800008085034b10ee43a03b63fd365340ceebecdb997d2b4bb41b336683c02eb1139cb1791d286ee13246a003ea3888ed23e1f986d8d3b9d560281d3484dd2fe974c25f7216c90568208b45", + "0xf8738361821b8477359407825208940d2f39f251cb547cba567a31e5e9f93c19dffa8588058d15e1762800008085034b10ee44a050f14998905eb10dc8e53395da51b21b0eefde3bc103b615d6f97d7b44f26e36a008ae2d148621eefa13ef0e3fb6ce1d259c62c8e057180ed49d761fab9d312b93", + "0xf8738361821c8477359407825208949eb31fb94ce5111e2a04cb9d156b513887ccbd0088058d15e1762800008085034b10ee44a07e88781530f943cd64ca63c2b7133bf8ed704356622be4b54f08751b54bf1d2ba00fa89ce3cc8f773cc83a72b7d58327740c41c95679e7003522c489ab9f66f88f", + "0xf8738361821d84773594078252089404b88ef83f8c41b1465d360a1e82f07ae190892a88058d15e1762800008085034b10ee43a096a28917edd16daee0707b0459a228fb5e006a5b9714a5d9cdac681a6960836ca02bce226c902887909a8bba3ad618153e90ff2d93e3825a42b72181bd18154d87", + "0xf8738361821e847735940782520894af23e04b04fbe15630eadd32a6f27a5a65ea554a88058d15e1762800008085034b10ee44a01dd4f73c1317ed5bd565999aa5fc130e388378ccd9f9641ed6a213d357d7bb7ea03e94fdad16c029234002c3ee24d382fae242f60bb58340c2a45488e57ad1bcb1", + "0xf8738361821f847735940782520894746cdff371e3f1e905b3ac52280078bac2dec7dd88058d15e1762800008085034b10ee43a02a4b086a715feb49bb892f026c3995f4235ced4da4a500bd3c960af2c3853ecfa03c14793e2606d25e7b5469a04bca55f50af24abe997afa154ef276ebfc7a6e6c", + "0xf87383618220847735940782520894c33e5155bdbf1a0a7ceb1b80f8586c5cda5c378188058d15e1762800008085034b10ee44a0b23359e18485b91d7599425b986ebb19cee52960533f993c24998636ec169a82a028d4cd7d4bc768fe29a6a3f32065b0a59188239808fbe5bb39e90ccd8eb43989", + "0xf87383618221847735940782520894e7fdef5f5219068f3d0f88a7445005574c66279888058d15e1762800008085034b10ee43a0101fbd3be6b8fc9c5a7f5c8f3c9fec2abcedbac8ab3c7247df2c98e6b968af38a019c11ee7058d8a6eeceb2e8cb45492f442eaaaa7fff37cc7fdd9d17e92e3bfaa", + "0xf87383618222847735940782520894f0a81a63c5e09b0bd08e027de48058e377d3732d88058d15e1762800008085034b10ee44a0f0e999e581df579e31fae928c52a7df96a1524d38f2e41bf4893ae7c4a083a48a022e1d07f18385e6d2f9fce94a25d042f4dee7eabb2df53d9ef694ba27869bb29", + "0xf873836182238477359407825208949878ab34dc3b4a63c80fdb733491472c11d59a5688058d15e1762800008085034b10ee44a0d719bfbbfbdbdab38420d454322ccf418defe93e5d81dffc354e0324d4ebd5dda05859b730b918a46f7e58bc0858aee845eeb07e64a6be8df0357a18b519b3c00b", + "0xf87383618224847735940782520894912859bebae3086ac7a062dee5d68aa8ed2d71ec88058d15e1762800008085034b10ee43a0a73cddf5a57016d0cf7e7f91e0e6e419f1a3e6485159868817ff0383fee03b4ba02a0cbafef77b725e6e3adf60c14463316b2d6780536e29d411044bf9d4a0518f", + "0xf873836182258477359407825208945a0b737ed85049410e5ea61f444d07d5c8c0359f88058d15e1762800008085034b10ee44a06cea82c78f91a7e463a6493ae9aed4039cb220686ed4b650c89e4160835d1a30a062d3191502b312090301ea3dd63b6b29f4e64622639a6e080d4a15a1b2b22ae0", + "0xf87383618226847735940782520894305a5dfd46e6128abce28c03b3ad971f4e4915ff88058d15e1762800008085034b10ee44a06ee9ca5a35966737addbde05c3702020db87737e2f3fe6f783023e69ef49c84da067ac4e87f6f02258d33cc1507006ed81501d1398428016f0b99eac2bd23f54d2", + "0x02f9021e8501a5887710808477359407847735940782dfad9442424242424242424242424242424242424242428901bc16d674ec800000b901a422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200eabd7137c45a0f283d7839ca69f6bbcee6adc41416bc9e01c31e8ca86b767390000000000000000000000000000000000000000000000000000000000000030a3dc91086418a5680fe3037dba62dda3de79dd22bb41036719c3771f140b419586ae7d9bdf3b10d88850909d4556b19b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020010000000000000000000000bf3da697ab02552a5da95f267075cbe495d1ecb30000000000000000000000000000000000000000000000000000000000000060896bccd536b4a30c4c3ce5877544574c624dff09f100abcb2df38df7c797069aed3213f1320fe77e4cf89907fb23fe4601a9008fdbac478412f8d6a5eb4c53b12c3848c29ced5ded2a7e3fbeb1e1dc4f58a563d761f7ea80c06088126e0dd9eac001a0ccca64755c8eae02419698251ccdc9e3691d2caaf5a104cf9542383c1a548d2da00ac0d62ff682d5edf5746aa633e34a5e8e789ec3eccdbd63b8d12fb80862d80c" + ], + "withdrawals": [ + { + "index": "481571", + "validator_index": "71016", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481572", + "validator_index": "71017", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481573", + "validator_index": "71018", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481574", + "validator_index": "71019", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481575", + "validator_index": "71020", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481576", + "validator_index": "71021", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481577", + "validator_index": "71022", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481578", + "validator_index": "71023", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481579", + "validator_index": "71024", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481580", + "validator_index": "71025", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481581", + "validator_index": "71026", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481582", + "validator_index": "71027", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481583", + "validator_index": "71028", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481584", + "validator_index": "71029", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481585", + "validator_index": "71030", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + }, + { + "index": "481586", + "validator_index": "71031", + "address": "0x7bf8bca0ccd13d04fd466539989efe2adcb0ca7e", + "amount": "34197" + } + ], + "blob_gas_used": "1179648", + "excess_blob_gas": "67895296" + }, + "bls_to_execution_changes": [], + "blob_kzg_commitments": [ + "0x92549576706cd5a855ea6a82537d1c7190c8d7d439f4dcbcf4b9b2bd34c4712d14f4ed041644bca5659e1826570e58b8", + "0xac58961e240bb13fd49d4cd60ace53bf3b6205ab7aee98987f3e589680fbe9d3febf3991150dd2ce0a785b9c7ceb42e2", + "0x83945613f3af6994e24c48b02a39a7c0e9c98f168c0c12ce3bf1d5bc267236ed6770c9c8a1fd7d7a9152066ccfa7147e", + "0x9334f6af7b93b7c1ee1cbac56bd38e9d9d6e50dd110bcee546333ec3ba0702c4aabe16b332ebc657967c66e9789a3a69", + "0xa43089b05e5987070bdbc3b8742bb30d7c34ea0e81518dc26ccb3f3a97c23df6d96f2cf1000ff985b494cc04743c5e2a", + "0xb45aefd32b12b74523a1082102de20e6965b31fb493228a12247e85165346087be8e54f435a60e9c96c1af716d4477c9", + "0x93c5be3093d114302d2dbd86f132c925d7de78bf977c0fd47e0e2c2dff528af381989fe0e50dc82e48d7f5c34d02f6ed", + "0x8a6a84e0ad21a30bacb75e8d0d5c3cf9fa89bb4d72a3cb4462a771cc533227aee35a21030258bb6b5869bebb3075be69", + "0xb54c1dd86ee3f132994ed666988cbdfd9a2b775697ce3e17139850cfe6ab2a5f250a1e2e9103fbe241582eca35d26b25" + ], + "execution_requests": { + "deposits": [ + { + "pubkey": "0xa3dc91086418a5680fe3037dba62dda3de79dd22bb41036719c3771f140b419586ae7d9bdf3b10d88850909d4556b19b", + "withdrawal_credentials": "0x010000000000000000000000bf3da697ab02552a5da95f267075cbe495d1ecb3", + "amount": "32000000000", + "signature": "0x896bccd536b4a30c4c3ce5877544574c624dff09f100abcb2df38df7c797069aed3213f1320fe77e4cf89907fb23fe4601a9008fdbac478412f8d6a5eb4c53b12c3848c29ced5ded2a7e3fbeb1e1dc4f58a563d761f7ea80c06088126e0dd9ea", + "index": "10011" + } + ], + "withdrawals": [], + "consolidations": [] + } + } +} diff --git a/beacon/types/testdata/block_electra_withdrawals.json b/beacon/types/testdata/block_electra_withdrawals.json new file mode 100644 index 0000000000..68c67b6803 --- /dev/null +++ b/beacon/types/testdata/block_electra_withdrawals.json @@ -0,0 +1,232 @@ +{ + "slot": "151850", + "proposer_index": "38060", + "parent_root": "0xcedd94fbf2ebaf371384911b85bb3073eadcca25eeb4ab29d14acd95cd88bcfb", + "state_root": "0x611fa0d96bedd90a2474b2e67f93f5a5edf82af93443079b58658c6739207a30", + "body": { + "randao_reveal": "0xa69041c990d2c6cab84d979be3c9db5081026874c8e37750c4274a355a7acf06f7fbc88857db3c20c84309f61026b20917a99fc826123ae930dba33dc92ced07ebdd57b45b1760fa08309c67fef843ee33ffef518e2ce9cb3c41da9e65d6f6f6", + "eth1_data": { + "deposit_root": "0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e", + "deposit_count": "0", + "block_hash": "0x1b60b6c9500355aa0ff7e1654482fea15eee29f2d52a25aeae859df953c0f7d4" + }, + "graffiti": "0x74656b752d676574682d3420544b656466343463616147456230323761393061", + "proposer_slashings": [], + "attester_slashings": [], + "attestations": [ + { + "aggregation_bits": "0xfffffffffffffffff7fefeffffffffffffffffffffff7fffffffffffffffffffbffffffffffffbfffffbf7ffbfffffbdfff7ffdfffffffffffffffbff3fefffffffff7fffffdfbfafffffffffffffffffffffffdffffffffffdff7ffffffffffffffffffffdffffdffffffffffffdfffffffffbf7ffffffffffdfffffffffffffffeffffffeffffffffbfefffffefefdffffffffeff7fffffffd7ffbfffffffffffdfffffffdffdbfffffdfdfefffffffffffffffffffff7d9ffffffffdffffffeffffffffeffffffffaf3ffffffffffffff7bfffff7ffffffeffffdffdfffffffffffffffffffffdffffeffefffffffffffbfffffffffffffffd7ffbffffeffdffffbfffffffffffdfffffffefbfffffffffbfffdfdff7f0f", + "data": { + "slot": "151849", + "index": "0", + "beacon_block_root": "0xcedd94fbf2ebaf371384911b85bb3073eadcca25eeb4ab29d14acd95cd88bcfb", + "source": { + "epoch": "4744", + "root": "0x810ed886bb9706fc2df193e2272e3a864eae69b43ca5797789f865b562cc3456" + }, + "target": { + "epoch": "4745", + "root": "0x9a8e0a72cf9f99379750c1c8b403c6daed6138c4577610e36d4b405f4f7e307b" + } + }, + "signature": "0xaffbe8cdd9c06cb23046969189e66e3c825ac6d0d7170334d9a5d8e7797d47069dbf96f391a86f0eb4b1c6d2eca55b34123567907c3342b4bbe31e520a0e0be813d5986f2d679a2b1f9ee0072bdbde35bf56affc060fd33556733e57103ca4bd", + "committee_bits": "0xffff010000000000" + }, + { + "aggregation_bits": "0x00000000002000000000000000100000000000800000000000000000000000000001", + "data": { + "slot": "151849", + "index": "0", + "beacon_block_root": "0x2bafda2b58819919eb49363290dfc50050f3f57cd6a0112ab4b5d4a42ba7c821", + "source": { + "epoch": "4744", + "root": "0x810ed886bb9706fc2df193e2272e3a864eae69b43ca5797789f865b562cc3456" + }, + "target": { + "epoch": "4745", + "root": "0x9a8e0a72cf9f99379750c1c8b403c6daed6138c4577610e36d4b405f4f7e307b" + } + }, + "signature": "0xa56ae375f437178909c0bf4ea632b94dff322f63bf383c816693c6f9841fb24fa7de3440fbc749cfc0c0d55e341c466b0f019dc77758dae97362c23ce1f8f71d8aab12f7491874d2d7c3e197037f313c840646da75c40577ebc0cdd239524f1a", + "committee_bits": "0x8010000000000000" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000400000000000000000000000000000001000000000000000000000000000040000010", + "data": { + "slot": "151848", + "index": "0", + "beacon_block_root": "0x85f3e44f8ea07968ddbca17eafd5b6ae402560a120ce96ae8ab9f06fe9bc2deb", + "source": { + "epoch": "4744", + "root": "0x810ed886bb9706fc2df193e2272e3a864eae69b43ca5797789f865b562cc3456" + }, + "target": { + "epoch": "4745", + "root": "0x9a8e0a72cf9f99379750c1c8b403c6daed6138c4577610e36d4b405f4f7e307b" + } + }, + "signature": "0x93c1542a02328cda2a26b7a2bdf02480fc244608c232d8239a6519ab5899588b531cc383f1a6462e37167ab6b85eead40296ceda75a9da55805bffd8631642b2197cc3c2684070b68f2543ad406ff992a9f9a3f852f9a4cce664400f4a0850da", + "committee_bits": "0xd000000000000000" + } + ], + "deposits": [], + "voluntary_exits": [], + "sync_aggregate": { + "sync_committee_bits": "0xf7f7fffffffbff6ffffffbfffffffdffffffeff7ffdf7ffffeffffffffffffffffffffffffffffffffffffffef777dffffffff7ffeffffebffbf9ffffbffffff", + "sync_committee_signature": "0x86b38c811f1415024af4bdc7b60bbea76e938f326595aa7238ca047bf336ff74707e9da3052d3d376766901b2d097fd5140de9bd4a9c0a5fbd4f12e0ac6ae472d8493a87e6e9bd69590d39ef6f142f7b2990938cd56e54e48bd9a9a55e1a40a1" + }, + "execution_payload": { + "parent_hash": "0xef54f75df413929ddfa60638b93feab47a0ad57e7585069308dc3b31beb42e05", + "fee_recipient": "0xf97e180c050e5Ab072211Ad2C213Eb5AEE4DF134", + "state_root": "0xa694a1983a7427b1ee0524a1619573db4e8f48368d13dde2a1103142e1e77cbb", + "receipts_root": "0x72a0eed2e520b8f791fc8dcafa8a94c3e411cba82097af3fb0287d3698c7bf0a", + "logs_bloom": "0x00200000008000000000000080000040000000000000100000000000200000000000000000800000000080000000000000000000000010000000000000000000000020000000010001800408000000220000000000000000000000000000000000000000000000000000000000000008000000000000000000000810000040000000000000000000008000000000000000000000000000080000004010000000800000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000000000000000010200000000000000000000000000000000000000000000", + "prev_randao": "0xbad3a8687ee866a509e9b22c4bd16d16ac2fc5a134fe8ce3477552604e5870c6", + "block_number": "141654", + "gas_limit": "30000000", + "gas_used": "2716694", + "timestamp": "1740426060", + "extra_data": "0xd883010f01846765746888676f312e32332e36856c696e7578", + "base_fee_per_gas": "7", + "block_hash": "0xf6730485a38be5ada3e110990a2c7adaabd2e8d4a49782134f1a8bfbc246a5d7", + "transactions": [ + "0x02f9017b8501a588771083013b8485012a05f2008512a05f2000830249f094d27d57804f09a93989e290cf12cb872c39ad2ad280b901040cc7326300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000056e915d8da78e50000000000000000000000000b3db4f6329df01ac317a70200f6614e1cd0db6f7000000000000000000000000fc7360b3b28cf4204268a8354dbec60720d155d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000d0ada425f6835193b8507d7de3a77ec1bd6c5377000000000000000000000000c8ae6c2d3f6695e41b5cb149beae76600f4ac97dc080a0212407d77d016985f42a043805a755a10b29c905c7e104c4c0f4bc00f0128ab0a0153258c0796acf19214c28c4554d82022c0f5b14c324068acc895d6e365a43fc", + "0xf873836202478477359407825208946177843db3138ae69679a54b95cf345ed759450d88058d15e1762800008085034b10ee44a0797cebc48b0b84885aae6d7be2e45bb148b09f6a58c7bc35f6d4b0ed4218d4c1a0671bebb2c27f37350c18bc626f7096e22233e8243828efb5831d8de85e230f15", + "0xf87383620248847735940782520894687704db07e902e9a8b3754031d168d46e3d586e88058d15e1762800008085034b10ee43a003a4493dbfa34810445419bea223d56ef71737f28a1c821a46862b173c3a06e8a01fe9f6643b5054a85e45ae0413118dc1c0de71ead60704241fa40ed8ecb432b9", + "0xf8738362024984773594078252089415e6a5a2e131dd5467fa1ff3acd104f45ee5940b88058d15e1762800008085034b10ee44a0c8c7a7b76c6525400c1ce5d7dba14548060d36d2bc4bd846a7a7425217d66957a025449e02d5bcf26d422dfbf41bae2de5e8468d7399043c12da8bbb7f5fb02eed", + "0xf8738362024a84773594078252089480c4c7125967139acaa931ee984a9db4100e0f3b88058d15e1762800008085034b10ee43a01ff07f88e3ef809a7326f7912323ddbed12184b573230d4f269969a48602a5aca052831c32b936474c7e200297135e951b8948130a61f0064ef5bce0fd8ff421f2", + "0xf8738362024b847735940782520894d08a63244fcd28b0aec5075052cdce31ba04fead88058d15e1762800008085034b10ee44a01fd39c5fc58bff2729959025ef99dda0614160f06289efc56e6ccb0b67bf209aa002ec26712f5595db24e57dbef108c3f4e8b1863d71dc0a6746d944c10353f209", + "0xf8738362024c8477359407825208940b06ef8be65fcda88f2dbae5813480f997ee8e3588058d15e1762800008085034b10ee44a0095291ad41e987063ba52692f06dbb29612393dcb40ae89ee3571e660c65db81a07a59182d51c5d07fcd8fc48adf3667a50d9b39185619c52938c741303603609e", + "0xf8738362024d8477359407825208941cb96c5809da5977f99f69c11ee58bae5711c5f188058d15e1762800008085034b10ee44a065c2371b3cded7aee9ffbd9383f86970b06b191d93b1485991f3d25686d86c38a0067905277c21e7402e8af63e6ae6b577d9c669db4a78f61c887cb7bd4c8b117a", + "0xf8738362024e8477359407825208942aa48ee899410a6d97c01b0bb0eeaf1771cc435b88058d15e1762800008085034b10ee43a099694c115ac14278bbc982204081457ec7b12404a86010dfc6877b87a3571bffa0117d6a284e25bda56b7fa75d26ac4429c38659a8f339280f1b7df051fcea84ee", + "0xf8738362024f84773594078252089407b9d920dd8e8d83dc1125c94fc0b3cdcdf602fb88058d15e1762800008085034b10ee43a0b7068fc0a17b7f6dbef5a97f10202748f9f45be2d47a54658d0c4d7da0f0d653a03362d98c11472ab5dad42e39de5175cf756d9fe022a8d0628f5d6da7b5b7525c", + "0xf87383620250847735940782520894fcb6e353ad4f79245c7cb704abcffe2f4868424188058d15e1762800008085034b10ee43a0ed028a4990f492396d8e86f9b0b58f934a8ee54938cbed8f83d68c29752f0bc3a062ce81c4edca14179ec5ce4d046e5d612c23d59f6744599bfd6ec71deb4ce2cf", + "0xf873836202518477359407825208940d3de4256d6322683fdea9ee23765ccbfcb83da488058d15e1762800008085034b10ee44a026d858e4cee789dfedcce3d7f52c8b1e5553a59c41894652dad1fec3f2dfe7f6a04935cb6ee45e295ecbd0d8ece2860f6697786d439c1f8e066e8ceca802bc705b", + "0xf873836202528477359407825208946021752d8d9b2f221d4fea4349dea34ddbcfce5088058d15e1762800008085034b10ee43a0d68f1b33afc775f5ee8e35d72a2abfa5966f6fc6f24cbc74498cc49163554898a02c8fbf6de58c657a47db2deb478659bcc31d92ab1697b336169010d3d937409d", + "0xf8738362025384773594078252089461e296d527edc89e831cf593ec341f16197eeafb88058d15e1762800008085034b10ee44a0cbf42d8ee53861132879567876c2d3d4361a2bde5a8a03d673e8a9e02e2f2198a0315ae79bef63a5105373ab4bc82f4d981674ddf22f555a414394252de873bc7a", + "0xf87383620254847735940782520894cf7317ee7a3b497ecf634b94bff60ff91b92574788058d15e1762800008085034b10ee44a033f4bfc7c5f798824317332a8e1cbc5dc6c3008aa09cb66dd090aa3c2a5cca1da013d43f1901fe898eab79bf8491a7eeb84373a187ec4d181ff1d2e5815cdce8f7", + "0xf873836202558477359407825208947e7b519df31f77ced83eea1b16aedb6dcb0f0b2488058d15e1762800008085034b10ee43a0268a7ead7124d86048cc864fc1ae417c5bc72d569c506a08bfd95abd1a3869eea02ca3d7363cb6f6507d81f070784cb74edb060228c93f740815fe96aa7d884574", + "0xf8738362025684773594078252089488a075e0fb1c9309a200a8bf0a88b214bf7ceb8d88058d15e1762800008085034b10ee43a064a8c228105a6a32632607e256ebb266a1b4ee37fd624ffc1f1ba939cef76066a0221b7fdbf2e6eba0742990b2b6d715f813599ec7ff01cd839901424230e5b0eb", + "0xf87283620257847735940782520894c8d7cfb58f3ac02568e6505bf3fb5eb6f080703988058d15e1762800008085034b10ee449f9df05b5989b41018aae438d7cf6eaab197ac212e434f3c4d97b08a2490b802a02732feacef45e05a73bbf32caf062f0d84bc2daaef88a9527b1ffbcb44a17a21", + "0xf87383620258847735940782520894e0132e8d7b1b766e0ade5543d6c6c0b2d5a2f01d88058d15e1762800008085034b10ee43a029a831ae211d616087569490c670fe44a681465a30144626e9787ea7174d0e01a05fc1c4037e8b7ffc15ced7750833ec8771f1b4d65d1e68381c68cf9523e44c98", + "0xf87383620259847735940782520894eb674c0411db79654afdc1e131f3b6e734baee6c88058d15e1762800008085034b10ee44a01064ff856cbb0bfbcc61383cae3aed541f6fe1e011e86bb842efd25e88429539a046a0b8db35289c2285d917ec68ca78cc2ee7492d8ef7c1e11e63b64d8530c121", + "0xf8738362025a847735940782520894dc07c60993cf689438b8c85f86b0ed938dca77ea88058d15e1762800008085034b10ee44a06f9e81bd4cdb2847e729b1ef1a331a663fc7531ed74a09e59ad02920db531f2da058e52df9092b08b45e4a9b961f431af4dfbb0bd86a48cc162c3e2f0d56d5658a", + "0xf8738362025b847735940782520894110ddc93db59ed31a03518510221ec2f35d28f2f88058d15e1762800008085034b10ee43a02eade5940ccc8290dc553ef3027d086985b03a19cd97928e258c3f4f7b1523aca0549d6ef116c9932490e49144b0287b6bbb702584a17576291241ac15ffc94bb5", + "0xf8738362025c847735940782520894b599a876aaac824cfce21bdf15627c9fd8634c3088058d15e1762800008085034b10ee44a03cd476a5d252e0b18d8d0809f26fe3871b62091cfb43d08dabd0c5874dce3590a063b5231c6c7190ac4e87985d997d46ef4c8bf3177953272fd1d0df9de95a506c", + "0xf8738362025d847735940782520894d36e5540dd71acbd6416d60252c4d7c34a3c824588058d15e1762800008085034b10ee44a07d9bd59a5a4480d84722885e29cd6d33f1cf04a98dcd8e3dcf7321f0fbcbdd74a0354eadbc5e2cac079487f00d57f5fccbcea7936010a7509e6712f8ce39806dbd", + "0xf8738362025e8477359407825208943adeca35af56206a74987a8fe13c669365c770cf88058d15e1762800008085034b10ee43a0a7df3bd9baf87afa5894782cf23385baebd8128d2ff7a1a971234ecf3e6ac7dfa03c811122700ebe14becfa56791483c58a1810dcb7cdd7b3ac3e2ff0b0e1e042c", + "0xf8738362025f847735940782520894d77b95acd12f7b4b5692b55717b7bbca1165195488058d15e1762800008085034b10ee43a0d1b54826d1311a0903886ef61521910679cdaa3cfa70f14b672ea803a955c15fa05e881bdf984a03ba04042f26b46c82cb55662cb3eb23c40618e17cfe1e91d80a", + "0xf87383620260847735940782520894f388bf5766b5ed5d4e1cbf15772e677dbfa80b0088058d15e1762800008085034b10ee43a0ab360b7a78ca54508f199cce95ea4c443482716205c32237b2be1dcfd1cb011aa02fc48513039fd6fa6bd608c9dfbb1965d2e15e70ab6cd67b781ba486bab2d093", + "0xf8738362026184773594078252089435d4996296e58560e6ef47787d51b55f1e2bd92a88058d15e1762800008085034b10ee43a0621eee5a891fdd819305e26ee2a6152e752381b29f7e2af5597bca6ed0f9c441a0747cdd3922479fd516c01172d6562a238576486d0fa084b9f3e603f304b4edea", + "0xf87383620262847735940782520894a4c3b77b898e53d6095f11c53a1ce272cff9af3188058d15e1762800008085034b10ee43a0a73f452201074e6cb8fb75a74da059a7e0928fed9ded27dd17bc4cfd93a22443a0674b3c5006a65687aa6802133fd29c77e68cef8a315175f677e9b6b0dbab56b6", + "0xf873836202638477359407825208946e84f6113fc1919714f0266705813fb81a17181f88058d15e1762800008085034b10ee44a0f054fd8871770486554e18096985f02ee95c032b9be137a8e0026f619b55d2c1a02a4855957e29e3d20223cc41194d0be22f7ef7cf436df2783754147bff8a5c04", + "0xf87383620264847735940782520894e9ae1a806004e1452baae0493920815aadd8479888058d15e1762800008085034b10ee43a0b475580a478780d91e262e2b1697d1faa216effee65d00d2b6357acb47b1ac54a015abc88732edd4be13376b6f910c5b5c6c1929210bf25f384a49fcb48aeb069f", + "0xf87383620265847735940782520894fe1905d8ebd20e037274eef441283c811ea82c1688058d15e1762800008085034b10ee43a089466e0fb9624d16c977ac2d64276e4700c47ef9ff4c8cfce8c801109e8b0b77a05c6b093850d7e34da5d445e203900087275573e83681eda656e3638ec3661547", + "0xf873836202668477359407825208946adece88e477f53a143a4c29d97940df2ec768e088058d15e1762800008085034b10ee44a071f1a5b69f6c8ae0393c4390adb7a3271f99af0c01524e277690ea199dcc2da1a03e887397647eea176bb4d7f7743a0f812a1223da3b465134e4f7b47a267379ef", + "0xf873836202678477359407825208940d34d140a7376892c4593fcea3ae26f5d6f202d788058d15e1762800008085034b10ee43a044af0ef032fe68acae258743e7a913b65bb1bcecd04e3ca23ff4b1c35f8ea248a0180e9622e1cbc136d45607eed1371a21adec0f1e76c9f60ce48de13798462ba4", + "0xf87383620268847735940782520894d1c7fa75b9bc55d041fcdf215f3e3a351c9f9edc88058d15e1762800008085034b10ee44a08b91903cf64c5ea1ef70728d84f3d6c3460e9b0373e39e25e5601a859578388fa059180173244f606fb86eb64187a39db3e6eea697b8eb725d44a348523e1a48c3", + "0xf87383620269847735940782520894418ebe350a8c6387bf5e42f3502742af8e0781f188058d15e1762800008085034b10ee44a084bd185a547656a0e4d8cc84cb47b77509f857bd5de7d6c56182c143665bb7b5a068b10a9e4d24f54d7af772976d4c9806828af12e763207efa4c47e1352590719", + "0xf8738362026a84773594078252089484914d2770c711d27888c775c547b1d933b48c4788058d15e1762800008085034b10ee43a0dd2129a3c3b56301435d67d5da0e8b4e5eaff46e6d30f49608c5b5d50c5e9dfba037b1663d9a8a20bf14f205817728934e3c6f0ec10642c2d24b54e46c0e3160b5", + "0xf8738362026b8477359407825208948f51e560b85edf2e653c689c4e9fac02ce0556b888058d15e1762800008085034b10ee43a009ca07e74aa8d418f7888718ed9014b539c60efb053116aa8e02b0cfc9930e7da05eb1a866237575f7f7de2051f622a8e45192cf7ef57c143eeffac1a54dda4082", + "0xf8738362026c847735940782520894ee2503205c24dc66346e356f13f333fb8782d35888058d15e1762800008085034b10ee43a0f02a886b4bd63232f0c1247c969d3d80c4881b5ea9fc1419564e38dd67f1831aa067f136cfa69edd0fced8be030956974d94a08e3ddbdaf29129e65ebb719dbdb9", + "0xf8728362026d847735940782520894096ba6c59bd667a0fea9a356bcc988e4d9f2d8eb88058d15e1762800008085034b10ee43a0a6b9529f9e732c69e23688f6c5644dd7a73162e427eb9356a1dcf1759a6fee3b9fc127e4986c286784fde59cad6c3f1efd1c7f6d4f7e5088f5c7a74d386b0949", + "0xf8738362026e847735940782520894da0adce4f1dc7debe7b2b52e8fe9ace6c7ea9c6688058d15e1762800008085034b10ee44a0734e8f035d7479da4857ce0e09202d497d831594ec24ff722106c8c7608963fea00a1f8a360c43f0b5fd58a71a2c2c5afe895aa5a15320b052baf1b44434cfe6ac", + "0xf8738362026f847735940782520894af7d412aeab7525c0541dc3aa6c1085cfb8c909988058d15e1762800008085034b10ee43a099e288225e6dbbdc77753aa08f3efbb9f0b96d7def768d9854e855fe01610cd8a034f2d3aae0864b7afd5e691f33bc2d28083110f0111112936da8f45d98319630", + "0xf873836202708477359407825208943cf8c0d567261eaf4ac0872d33a9f48af361769f88058d15e1762800008085034b10ee44a00f20fba4abb6ee417a1f0bdbf776b0d5dbaabc81ecaaba9c58f45360208e33c7a05dde3f3f6b92919e408a0aa72937c33523734a0a2cca772fa2147273d7be1c3b", + "0xf873836202718477359407825208944779242587ba9e828999249eadd82984430f484388058d15e1762800008085034b10ee43a09b5e17f912c9fb7f803b43c2c1397b01b8ab205ff682a4423f0a8214a2e79197a0521997071cda90e04ca276220e6f7dcff723c5d27224528fa3601ef3a2221494", + "0xf87383620272847735940782520894ea531cfe2de357ecff3855b88dbd07f60b03cdca88058d15e1762800008085034b10ee43a0022fc439ceef6778c85bcb9b86eca5cbfa6ac349baa54887159c8585af0e6ecba01080d90e6b555cccd88b693af79881d7f17247b01b3ca62c281c7ddf200ecc79", + "0xf87383620273847735940782520894d00b5f53ea2a66ad33c3fee304bb22857dfb8a8788058d15e1762800008085034b10ee43a042e9e53473b2553d37080c3a8836b183ec8f3b41f47e9bbec02e3aebb7dcdfe1a070bafb99da6e92cf4090bff7eca3c3c8044cb46a9f05f544a0b56a521255d324", + "0xf873836202748477359407825208947ead29f6616f78f21a951c9686dd257be7b8efe488058d15e1762800008085034b10ee43a0a04cae14d43584a0fed384fc6d981238e3cd2302a7fbdbc5245192068abed008a05aef32306b51b2320199e8f3f11280bae5f677b99907b6244ba892d1d441ec12", + "0xf87383620275847735940782520894d503c13ee55c1ea128357d4018ec58d0d5e5c3db88058d15e1762800008085034b10ee43a0e280df73654670e3cf5ae5aeee1e1931e98cf29ff874ce7d32790f8233d5b287a01892f9b5e6902f7dde4411566c1ed3c499703b0801a0c4b1a9dc1b023d6443a8", + "0xf873836202768477359407825208944ac670d8760faf780468638ef80034876ed8918d88058d15e1762800008085034b10ee43a0514dcddc1910947d09fa8a6c0e6f6cf7d05fb4d5bf158bda354d2e6c6348d581a0047981492e9b9eff0ea70bacfaecba069aa2b2c5269c8469cac42d9b11d19383", + "0xf8738362027784773594078252089424ffb8c97ce443f8d3265ba3316defcfc07c659c88058d15e1762800008085034b10ee44a07fc741180d071dead819a84ba1be1f2eeb518caf707ceadeaad03ea9edecc80aa060eccb7fc130827b061d57c5fb3e168a30dccc1fd4ba6b69df65cf82f78a6bba", + "0xf873836202788477359407825208940c5cafc547ab98c9ceaa1c07fdd6bf7820aeb95488058d15e1762800008085034b10ee44a0787e06914cf15a0d5c805c92ee953eba7efc3f9ba09ca62d0ed2f3b6167ffa60a014fa025423178902bb480a1823bd9cd17a55f7c2fedac8a42f81b834c4f5b547", + "0xf87383620279847735940782520894db8d964741c53e55df9c2d4e9414c6c96482874e88058d15e1762800008085034b10ee43a0ee3e494f464ab6384f2a856e3e4a82b581b60dff1494c5d31d8ffac33133c4dda00fe28dc8352736880aeb0df3b34c846d9e48e056f0ee34115866abd2e4cb9cc9", + "0xf8738362027a847735940782520894ba85bb35ae6ff7a34745993fcf92b9afd34124f188058d15e1762800008085034b10ee44a0697c551925faba103e19343af9b1373c15a915c94c2c2b2248754707ba6753efa0195134d1de635393b68258bbc3a6130da2f6f28e3a21f53cf7c0d309e8604a91", + "0xf8738362027b84773594078252089458871015f5a2d3948264f7c16ad194c80ffd531d88058d15e1762800008085034b10ee44a065fd5136b42302cd12e08ce81d4bbbac0bedb774eb07df3ec89e10d1bd0e3eb3a053ef3a9a4b6b0fc0afc2aa8f0fd6eeeb0f8d79df5010395e68401b34a9c1b932", + "0xf8738362027c8477359407825208942a90af45df70b0031f218cc122598ddf3e10469f88058d15e1762800008085034b10ee44a0b8318c8dc899f7a1c0c57fbe9199901c927788d51460a971328870dd05516748a02811349e21979f97393c1c0707f508bcc9edf7e8932a2058c62fc503c6e298f9", + "0xf8738362027d847735940782520894761bbaaea6ceb265f5262c3b559adc2ad3ed2f0988058d15e1762800008085034b10ee43a0ee810426bf67a8873cc6dc0f41887bc6dcaff093a620b980db51343e80b828a6a05fdaf2729c1dee2029a5bc9174920d1bd16a253e2a20ab69fb4cce9a22bbcb44", + "0xf8738362027e847735940782520894dfe86f51c5e603f1420d1f0ab366bd3bfe23d2a788058d15e1762800008085034b10ee43a053c6702a09db8bfbc3560bc380816ed7c119a95700fc9cc7cb44c631637876aba02bddd96beafe8592027d38a9596efed58b08361c863a905fabf4dac4b6fc22da", + "0xf8738362027f847735940782520894d616547158b05ab5079106dc0336d72763a7287188058d15e1762800008085034b10ee44a05fce463f3ede6e6ea82f59b0e2f1356aa6cc9e4a2092186ff4eeac6144f3d70ea05870f706fea0bb3e813e3ecdacdaa82ad6234cf8cc051d15b0aa5fc041943aff", + "0xf87383620280847735940782520894dc68cd278cb7f5f666ce7b0a3a214a8540ed4dfa88058d15e1762800008085034b10ee43a0e376459fbce80ca4941fdeb313efbe587a7567cf3a34c477df38b7409b043e69a03ba4f66d19838df4276344d1c44253d83789e1c77ee8a40d4c8c447789723386", + "0xf8738362028184773594078252089411f8107da05b6905e8cc0227ca3b0c6eb764fac088058d15e1762800008085034b10ee44a03bcb59ba309b004c55ba3df3eec064e22fcfb5a57c8e5ca0ff146bda02774a75a07ed6d73ad8a0daa1f1c98430ad5e5fbdb4748554c8ffa0233638077e79deac03", + "0xf8738362028284773594078252089404da906545679850a7ee0ef6836e183031bedc8888058d15e1762800008085034b10ee43a0094da8f36bc9c6ebb5f92ed23a48067f0efc5307094da7c5890a942f654748c2a05883676b2416160acf153351fc86c771a56bf4251aa134897a73cea3c3f4f7b2", + "0xf873836202838477359407825208948bdc25c43c010fd3db6281fcd8f7a0bed18838e388058d15e1762800008085034b10ee44a0dac96e3d17998ae7886f80455c92444fc078f832b424e31c7c4d1cc1c09d5d2ba07104abf0bbd8433c357d0ae0d9ddfaa3e7d8dea15644912d51931b448bbfdada", + "0xf87383620284847735940782520894af16f746b8a834a383fd0597d941fee52b7791eb88058d15e1762800008085034b10ee44a0294814d951013410c28b152df0361a6bdf245cc987ab30a7304251188641d609a05a530ee23d27f69768191325ffe65582ece63791bf09fe197f504fa57bfd5146", + "0xf873836202858477359407825208940c5c736600f8ea58ccb89aa72e3f3634651fd55188058d15e1762800008085034b10ee44a0c1e93262c0f669d8dcafbe0b69d6fa444595b9991e0ab2d643ca82c32bb95779a07890187282502da60706b81047b42099ec2fcf12f967cada17ea595b8d2d50bf", + "0xf873836202868477359407825208946f475e0f0e9eda58556fddc04de9b1a9b6a4cfb488058d15e1762800008085034b10ee43a02954b5ef28644f34235fa8a78138f8a20f451ee904bbcb557ee0d6a57aadebbda01e380d4925b3eeafe722cffec0811d4b546f2962dab2415247a609d017aa6830", + "0xf873836202878477359407825208949b2e76498a695c4dc7d0890069cffa84a9581d2488058d15e1762800008085034b10ee43a0c4c1ad80c72b77662bdc60e5d9d2f8a7d4f7d5e591f7d36bf75792603c350a48a075948e3ef779497e000693a717ebd926dc2f1040a9fe108067b827470250cb5f", + "0xf87383620288847735940782520894e2d2b2069f4a54fcc171223ff0c17adbd743c28588058d15e1762800008085034b10ee44a0c081205b252b273039c2e97df9831d3f3660a5d9c6432de2d9005d24bc1c949fa015a60d2b5a33cbc1d41626d844ab093695cffb1d445a7059bc30a0ee70130bba", + "0xf87383620289847735940782520894386bd49f04322544f3c7178fa5ae1a24b947b45488058d15e1762800008085034b10ee44a02a76823c284c6d383ce1605f433ee24e9d25755d9914355e7ec0a2e747a31aaca023bfe68b343ec5da856c221a08e42325e2fd465cafa52872885e471e87a26783", + "0xf8738362028a84773594078252089400af839c3fc067fafc2e0a205858d6957f0dd18d88058d15e1762800008085034b10ee43a02dd6ac183d86166f2d48f9e5798998beb2492203130dc29a8ccd60d682c68241a060f45d781a16584462adde0ca311cdd99a0c46c8e96c772e10dec6e21958ca64", + "0xf8738362028b847735940782520894ebb6d32a650afa9221b55a11c6a6de52b6f07cd788058d15e1762800008085034b10ee44a0d7d9588987d423ddf1180b35560d0cc8c350c4eddf3b4f04d491bd952d1ee939a07b95e674b777c204738e34c332a4c96e067d1fd530ca4e17196c9c8a2a84428b", + "0xf8738362028c847735940782520894011d26a3a9adc9203c8943a6a77aa8657af5242088058d15e1762800008085034b10ee44a0780c40f1a71ed2631a01df292f842ee8a8dc98d1b80d0685d92ac22dfc2fffe2a051a4e8f7bae167c3124d47938c54639fff25e9b159507881f6b9d891eb50d805", + "0xf8738362028d8477359407825208949c85bc61a89fb5abd957e6c819c653fc1aa0d11b88058d15e1762800008085034b10ee43a0f041d0b9537468ebf005b0fad79296b1b74e63af050e13f31999737130346deba02d50794faca4b4e1515287ae2690e4d7b7855f29a56a6d644f8c828b6d30a997", + "0xf8728362028e847735940782520894bd8e8435b7897d87cf7cedb5cf8c5dd865dbf72088058d15e1762800008085034b10ee439fcc0821fc19eab1c1e6e15d7447aed84f079a3d178cbc9e865e6009a58b558ea006d296a4d03301ff9663336813b95368dd3553f88d2635ec7559416445f214b4", + "0xf8738362028f847735940782520894adebee2e3ff041078b62380d001c6e51b4f1559888058d15e1762800008085034b10ee44a0e67f178fbd1a91014a87c50bf50898474c1fd80cc782aa05cc2d7efc427d5c13a045ddd298df67dfac72dab9b255066e81b4a1a7988e61b6c3b0318b788733e0fd", + "0xf8738362029084773594078252089471e94c459c9f05085fc0d34b5f21e648e05dc6b388058d15e1762800008085034b10ee44a0f16ec0330912b815ea3ad0d955766eebe92031c7a2d64bf786b7f55bb4f63798a03d03f718b4de0f491a08315e6fac7fe9ee98098ceb3d27ec4128da1f4b4f8153", + "0xf873836202918477359407825208947c1fe317db82c9298b87c56c3194178271b621e188058d15e1762800008085034b10ee43a089edd1266f626652a65dddd34bcecd33cf0975ad6664cec15b706910d41d23b0a055f7752a91aa4759e5c84a4bb2180ac78810ef99246e52e8974fea996efaf8d4", + "0xf87383620292847735940782520894e069d1c9abf5127bdc3a164fb93b96bfa9f74ce088058d15e1762800008085034b10ee43a00a809e015ed5159d60be66d8b65efa57f72be941e9928d889c6be888096896e6a0724239814c01e730b19dd093cee6384864964e59d34d84cf1e9a8116a11a7155", + "0xf87383620293847735940782520894b9bbddd1eb6ef8fb1bdc6a853d5ad7486a9487dd88058d15e1762800008085034b10ee44a08717c8d1194e516264fb1ea3cb78b73f5dd507d17823eff675c97bf304a90b2da05a96d1bfd29677fa4e97fd37bc4e4962a9ab6f99fcf1c74bf4749a97adaf0e3c", + "0xf87383620294847735940782520894a804387cdaf986d45831e8074efb2115af053f7a88058d15e1762800008085034b10ee44a00d92c86dad2165ddae28c5081638c3eea7a54bf7c15f75d2e3a0d52af40d3c97a043c833c190d2e78ce01fa96a331e475fc41f7b51622bf4f081e4831de49ba07e", + "0xf87383620295847735940782520894f23501d784a041fc911b4c86c2bfb1f63ec170ea88058d15e1762800008085034b10ee43a05d27e028f1ef0555f022f214e222a33266971b98098643ba84578f70598781f0a0548bd8b2ba26f7f4b96bea6187981f5af5c36cbe0c57558d6144eb7590668a70", + "0xf873836202968477359407825208943928be2a7058088313c0fb3294014e88a3c5ed4a88058d15e1762800008085034b10ee44a092c573d072e4fbd59fbe85d740fb99b1cc94a97c0896020b1eb4c50a0c1194b2a07edd4babced9ec70bb660fefae771aaf3244341da1e3123b42e6885a933c3d2d", + "0xf87383620297847735940782520894196aa07204141478459c14106ef5e5282efe995788058d15e1762800008085034b10ee43a08d6b3fa7173e77e69d0c9a851396dd8b457d32e15a916082002f367acc0605bea06c7319e1eabe15b1887633080dac1be3e3611861e2ead80487a0858b24f2f9ee", + "0xf87383620298847735940782520894763cbf89560e2da270000822abda9584db693fa388058d15e1762800008085034b10ee44a06a92950880b902296ea1c6d8ade6011d7249107a520c4935dee51dd59de41389a04701288ac10e1ede1468e197258e7b38a5157ed96cffdde2c99314fc9e64e260", + "0xf873836202998477359407825208947feaea0ff70ffc9eec2104f57f7136aff4dea68088058d15e1762800008085034b10ee44a04d90fec69d1b3ffa4e21a81a12bde21223baf92be9c972ec983454d8271870a0a0159b7c2b5238c515755b3f7812afbb5d4726a957a9c9767c3d4c044f83274185", + "0xf8738362029a847735940782520894e5466aacd9dd6d3bb35060a1ccc76a438de88ca188058d15e1762800008085034b10ee43a0837538d8e417194bed46f36eeba282fecbbb58bcbefc6f7e018c42a73ae81345a038b1d65f0d27ade5bf1d263fb67c758e76d1ef797cca936f3412e355074fb994", + "0xf8738362029b847735940782520894f670980415cfe8c4f8d10645ecf974c9a2fea00e88058d15e1762800008085034b10ee43a0ac3f8bba9b19c4d9a3a0d03ed515f81da94b6ac72284b4d8a27c4922aae659c0a078c566cccfde53296c238d408e0ab3dd4a07df1199c12b673be05e45195bbc4e", + "0xf8738362029c847735940782520894a29115bce7829ffdd989b7cf1bdd1eac06a2cb3688058d15e1762800008085034b10ee44a01edd6db1f63d1c384edf6bfc0c3253fb8bdf175c913b62fc5d0c76dd2c7bd411a004a5ceb0c53728dbefccd21e5342f25e90fc4e3de69661a96a2b6e8eabe99580", + "0xf8738362029d8477359407825208948f528aa67dc1846c893465fa1c8c26556bc5fe1988058d15e1762800008085034b10ee44a0b8eaa2b524d2970d341996da7babffdaf92160c755e9b4ba6e453e800a93c5fea05b0bf41c26aefc1fa29539c34d32f42174fe27846ef4ea8427f9f64414ab2994", + "0xf8738362029e8477359407825208944dc4ec6ac43c8c45777292db987203c0248e17b788058d15e1762800008085034b10ee43a061f4bd7053ee4bcc8d1a3edf748d9d3a585134c1fa61129951a094d5069705a6a03e45012ff902405e6c78e0e7d8be2abbc079b8c79af32022f3f6ded85a023a22", + "0xf8738362029f8477359407825208940d2f39f251cb547cba567a31e5e9f93c19dffa8588058d15e1762800008085034b10ee44a0bcc76559b8384c5f31678d1efe17f1c7c9267ee4e50c688421fe269a18ff8ab5a07ededd086d4f210c05ac901c987a1b30106cd76e7cef0a6723bb1dc1b20ccd30", + "0xf873836202a08477359407825208949eb31fb94ce5111e2a04cb9d156b513887ccbd0088058d15e1762800008085034b10ee44a0deb981e565672e01dcc8cd6514c459fd3936380d87f7fadb2660f7c350ac2e51a014849dcb352073dc9663c0a289710145efd7428cbe0c88213611432761ad93b9", + "0xf873836202a184773594078252089404b88ef83f8c41b1465d360a1e82f07ae190892a88058d15e1762800008085034b10ee44a07e3e84ca883d7d8d4e51f36454609b4e6b313a98ea8d226d47682612ae87f812a052687dd82b4f62e8449f7c0034b950e82c78aab8a5518592ba5b652c72b36017", + "0xf873836202a2847735940782520894af23e04b04fbe15630eadd32a6f27a5a65ea554a88058d15e1762800008085034b10ee43a0b90c86c8c6d5254ebdb8b82640ab629ccd6eb9acebfcf53b931949872d9aa6d9a02cbee4611a01bc2d694b3a3b86070ef762b497fbb2b9a9c3bca6b8c0112f97d4", + "0xf873836202a3847735940782520894746cdff371e3f1e905b3ac52280078bac2dec7dd88058d15e1762800008085034b10ee44a0751ea5aa4636525bec891fd848390f6e032587d1bbda675c0e393e410844a1d6a032fdeac6961819450d3059c61f97b60f5cd50e27a18c392539719af3f194f53f", + "0xf873836202a4847735940782520894c33e5155bdbf1a0a7ceb1b80f8586c5cda5c378188058d15e1762800008085034b10ee43a02fb25f3cb803a573ca57d7782a90267f5e2e92fd018f01fd7c5152beb3e2e179a0732710f218d2b8fa87143dd9c10e239aa7269da3dd08ed081cdef99fc28f2561", + "0xf873836202a5847735940782520894e7fdef5f5219068f3d0f88a7445005574c66279888058d15e1762800008085034b10ee43a0f06655172c1d09a30c06930a24caadcd736beba5b63aa137ef0701e57820bceaa01821754fd8180b0ff357c500232f2008e703d2ac6b6fe0a14c202a1c039bdcc7", + "0xf873836202a6847735940782520894f0a81a63c5e09b0bd08e027de48058e377d3732d88058d15e1762800008085034b10ee43a0443ce407a5a49665e5b7847293b62446a2bf6d5885309b75c72c93cc715f8202a05151017b926df1bcfff2c3309e4771f2310b5ed0ded4503e6c4e57d78cc2b380", + "0xf873836202a78477359407825208949878ab34dc3b4a63c80fdb733491472c11d59a5688058d15e1762800008085034b10ee43a084ae376d4ecb7d0e23df6dd426999005f05fbcfffb8e1916d13e53f492fa058ca03b42dfaf1fcff5912e20d3bc9d0e26f61ca37a0c2647a62d20e443db23ebf400", + "0xf873836202a8847735940782520894912859bebae3086ac7a062dee5d68aa8ed2d71ec88058d15e1762800008085034b10ee44a0e9172415691d94476adc2c2fb0b5d68285ce83ab024dc53166f870decec3a4eba07e5f2f8a52145948789e57e3311da5edcbf563307ff0987342424f4e23055673", + "0xf873836202a98477359407825208945a0b737ed85049410e5ea61f444d07d5c8c0359f88058d15e1762800008085034b10ee43a0db10a0538cfe66a2152e6ed531eb5be016ec5f1cead127b91b8f123e54efd8e3a046c6477c90bae429b65e594b254a396bfddfdc15e1e3cec9ffa26a46a4884ccf", + "0xf873836202aa847735940782520894305a5dfd46e6128abce28c03b3ad971f4e4915ff88058d15e1762800008085034b10ee43a074cf4ff900d6170b4266deced030c14cb92d9872837e9cbae3b768c3f561d1c8a0252ba383431d7108ac2402bc6f8f807177496bd9997643994a9c33dfeda303b4", + "0x03f901198501a58877108216c784773594008477359407830186a094dba34be211bf539e27107cbe7e6893770280aec580b880297fb846f12a980aebe1d5b1187b2e6660f3e68f457379b59395a0411b9859c25842606f527f16e565e886e3afcd0ede18e04e3c827adf9e5c54db37870db32c31a18813d44c608f5260b660af53605b60b053605760b153603060b25360f060b35360e760b453600060425d600060c95d600060895d600060e95d7f25818248c0830f4240e1a001b7f74a7d5bae21aaf16e7b2d2ca7f47c800636b2a3f8b519aabb4b3541708801a0faebdfbd5a7832abed65c7fe25ffdb498b0c19c70cd53a1ec53e3de6c25ca0eaa03690227cf2f99e38b48a44f739fd63b00482017bee063657b418d85e68cd2094", + "0x03f901198501a5887710823ba784773594008477359407830186a09409fc772d0857550724b07b850a4323f39112aaaa80b8800a7f9b44ddad8f17bce75dceb28c1eafa80fbfaf4e0d793fc9fc42489c913ffec7906023527f0d1debc2884eec1a57d882e7085ae952d5d76b3e168370cc9af6294ccb55a7ca604352606460635360d96064536042606553603a60665360f1606753609160685360cb606953600c606a536055606b536043606c53603b606d53c0830f4240e1a00159f296fad44019f3cfa307df01412afa1643a67ccafae96c83d43b6758ffe080a04b6af5cfdca885787b508751e15ebeddc4ae4f5e88035002a72fe720ed9c1808a07781ed6c6f1778c74f692c9b966d1c27185045042cf386eab20543852afd7d9f", + "0x03f901198501a5887710823ba884773594008477359407830186a094000000000000000000000000000000000000000080b8801660f660ce53604b60cf53601260d053600b63df83d68853600263df83d68953604f63df83d68a53601b63df83d68b5360b263df83d68c53601363df83d68d5360f663df83d68e537f93ad362c9daf922157be015981847c3d63de3a139a88e7824d2c62693233acba60e4527fb97203d3cc1f05cb5b3a18ba38b93d6eae2675c0830f4240e1a00125c14e94773c0f2504208d25925d0def274e4cd05be154b64484cd55068b9401a01f25239f9cf530e73210788333c06832ede4d25811fbd5288f1c6ec09626a848a0142054f5501636d093d1f8fd9a18991a035ff8272ccc4b732e618929c5ae60a1", + "0x03f901198501a5887710823ba984773594008477359407830186a094000000000000000000000000000000000000000080b8807f1c1e1707ec5a3c08643377106467f9d8cf7343cddde951134184de69c4a0ab5f60cd527f496d383985b30e2192e37082533c4040429f17d2d8066cbbb0df4ce5f1bcc72760ed527f934a6a5a54f24b814ed3df79092d3215e14b5fe7c1ae730e377b17777e7d3afc61010d527f324e451356f8780882a2abd81a56fa0ad656c0830f4240e1a0017fde88c70f2ed440c9dbdcee3973e4d7b85d3a65a7d3db7289a2a16db2f00480a0064a83db9cfa03f6af8b2e48c5b383d57f3de72c1a556bdb89f84ac5a33ef294a07a99426dd140e3f729bf681e9493c93b9f5466afab8bd43b08d44b83121e2c66", + "0x03f901198501a5887710823baa84773594008477359407830186a0947a40026a3b9a41754a95eec8c92c6b99886f440c80b8806000603d5d6000605e5d7f2a4466d55bb88fa289d012628a52864aca1c1e1707ec5a3c08643377106467f9606d527fd8cf7343cddde951134184de69c4a0ab5f496d383985b30e2192e37082533c40608d527f40429f17d2d8066cbbb0df4ce5f1bcc727934a6a5a54f24b814ed3df79092d3260ad527f15e14b5fe7c1ae730ec0830f4240e1a00122ad5c899f52d21eba94a21044753587639cf91301db410de58f73d740feef01a02d622199b408f02048f237a3cee8de1cbe7c79de5fe0342f1a6cba7d9d5c53cea012cae1d118329a17eb3cef8d2a24ce1a96afdb6ef7c0fd58f11041f9ebb458a6", + "0x03f901198501a5887710823bab84773594008477359407830186a09401abea29659e5e97c95107f20bb753cd3e09bbbb80b8807f1fcc4bfabba1d810c2e9750fe5f9f3c70adf76d7a54bdf886617f1a099584d2860d8527f410b6d3e2670b1d7b668f22f9b6d1e5bb1b4d12d4bc198e2b642cd9eef1ebf4e60f8527f753d66f7de6d60873b96cac74055a2c05f1822dd662fe1e18b5962e191d8cc88610118527ffd19563f4930341b9ae50f37f40c3519b4a8c0830f4240e1a001ff78fe5af972c7cce1be875aba37ff8b7367ab34a0879d0fde2873c1c34e3301a013580cd6864dabb7ae62de736772696075a507b26d352eecea97581662b11762a03a47f80d8b09c0ed5686c0082aeaa569bd7200bb6cd4a89507c391da4aae8882", + "0x03f901198501a5887710823bac84773594008477359407830186a09401abea29659e5e97c95107f20bb753cd3e09bbbb80b8807febcd375a4548f911bbf94fb20a71723f2bcdf90b1893dede0d86ea0086c94f4663ded9bec5527fa75fc1bbd45e9a2357080a88f65a12c678ad697d56a558ddc54d4bb74c6c6d2663ded9bee5527f75eaa5150042917e755fc935fc3a8af87bf91944c7e3f00eebbf3a6574e80f4663ded9bf05527f27014ac42049105c03fbc0830f4240e1a001466f18955590485e681c566fab7923ffc11c44febd37dfa460e4ae57b2bcc301a08ac71347df4693d6fd98be1cfbdc5b7cc1ddc75f2512d1b85df24c9e1c754563a02145852bc429244eb4311fa25b529d4245e0a1b79581e829e251f92edaaf209a", + "0x03f9013b8501a5887710823bad84773594008477359407830186a09409fc772d0857550724b07b850a4323f39112aaaa80b8807f9e664ccecd377f7cccdc8eacb44927d06ad21fa62b767c61a984a997b503e76a6021527f9884bb7e3c5262eabd6dc6f0daaf38581cc4e7387f25237ef70b3765d9f7f69d6041527f263c0b0f9697916d24f51e6443f9ddc9c00ee8795c6563b153305d4e889ff9336061527f3a7664aab6aa9ff375049c342739cf230af714c0830f4240f842a001148d696bf857b798a51d3cf76e1f30c0ff18dbdb67b4e4651ceb9a81bfe319a0014516a223e4dd099c56e3320d0f6b50e061e00a6548964a52ac15bba57028ed01a05077e103e2aabb0f6f8712c96fdee81a4a4b8b53404286535eb188b02be775dda021063c5abd0394b12c6935dd209bdc413472f558539469806e5baffeea1d00ef", + "0x02f8a98501a5887710078459682f008459682f0e830137a19400000961ef480eb55e80d19ad83579a64c00700201b83882586e0c10f84614733e5752428cbbe809e3699d9a3bc5bc604e81169e6a59304352237e39c8e6644acae5f595f1a8640000000001312d00c001a01d67ab7c6569f238adca00963a31b5bd856960affb9d738ceb78085800ba29e1a0495ad28ef784fb388e2145af0778bfc08386cb0695d1c0ca1022fabff8ccd9a9" + ], + "withdrawals": [], + "blob_gas_used": "1179648", + "excess_blob_gas": "68812800" + }, + "bls_to_execution_changes": [], + "blob_kzg_commitments": [ + "0x82b6012a3307f01e0ec06ce5768f093c75b731e81aa16f08afe60e2e457e2f4370f13ea15baac9c10ad8956cb1599f47", + "0xa758a4d6c5dd35ec363c80f21dbee519db19aa0f69c1318b70dc01738555b97f7607793d072946019e4050b8b8e5105b", + "0xa49b025f2a1c657f4c07df7cb04d430aeafacdc1cf9afaf841cdcb019ba3f61d6151241fcda0b2851f9d5adcd2a67bdb", + "0xb909fcb4f35d2bdb684643f0dc3fbaae73024b7d2e771656cc0117fe34143aa29d882454285d340dbb1c6dcd1cff2d0c", + "0xb9c826af3dbc163bddc7bcd0230b87f57193bf567ee7fa35fc17f970dfe620dee074c61776fb37fc19958996e5cf585f", + "0x8ef3c784f8070d96f4a834640b6d76e589508ac121177a323f49b3a1073b9592d23464487a31a36974c8e571d8573d46", + "0xa8ddab3b3301512e74e7d83b472af200f35d4b8a4df6ea783363035e2250a90ba473f31ea382c4c275e9c37621098dd0", + "0xa33e2ae43573502a30c5f98a9a33c8a6879333f96d24fdff686544fd01b99130114d741e076ff873fb649fe44ab5e81d", + "0x8f01d73cad9ce715598a653f48e9b9003abf2d2084890fc722c1eab65a4678146e81618b84d227652513723f4088cda3" + ], + "execution_requests": { + "deposits": [], + "withdrawals": [ + { + "source_address": "0x4b6C4667921A132eE6eD26a2DE7654adaE481E4d", + "validator_pubkey": "0x82586e0c10f84614733e5752428cbbe809e3699d9a3bc5bc604e81169e6a59304352237e39c8e6644acae5f595f1a864", + "amount": "20000000" + } + ], + "consolidations": [] + } + } +} diff --git a/go.mod b/go.mod index ba26f2150e..9c0c447f3d 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 github.com/pion/stun/v2 v2.0.0 github.com/protolambda/bls12-381-util v0.1.0 - github.com/protolambda/zrnt v0.32.2 + github.com/protolambda/zrnt v0.34.1 github.com/protolambda/ztyp v0.2.2 github.com/rs/cors v1.7.0 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible diff --git a/go.sum b/go.sum index 1e4efeb697..42abfe4d30 100644 --- a/go.sum +++ b/go.sum @@ -462,8 +462,8 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 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/zrnt v0.34.1 h1:qW55rnhZJDnOb3TwFiFRJZi3yTXFrJdGOFQM7vCwYGg= +github.com/protolambda/zrnt v0.34.1/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/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h1:cSo6/vk8YpvkLbk9v3FO97cakNmUoxwi2KMP8hd5WIw= From ca530362ca083e335c50a0c84fb6b81c4ce3b7ab Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 12 Mar 2025 05:30:02 +0800 Subject: [PATCH 179/940] ethdb: no need to check the metric nilness (#31353) The metric always has a value, no need to check for the nil. Seems this code was first introduced here https://github.com/ethereum/go-ethereum/blob/054412e33528e53f6deae940c870217b614707b9/metrics/meter.go#L45-L48 As the `nilMeter` was removed, so this check seems is useless. Signed-off-by: jsvisa --- ethdb/leveldb/leveldb.go | 32 ++++++++------------------------ ethdb/pebble/pebble.go | 33 +++++++++------------------------ 2 files changed, 17 insertions(+), 48 deletions(-) diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index 1d88ed460b..7f47523b82 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -368,29 +368,17 @@ func (db *Database) meter(refresh time.Duration, namespace string) { compactions[i%2][2] = stats.LevelRead.Sum() compactions[i%2][3] = stats.LevelWrite.Sum() // Update all the requested meters - if db.diskSizeGauge != nil { - db.diskSizeGauge.Update(compactions[i%2][0]) - } - if db.compTimeMeter != nil { - db.compTimeMeter.Mark(compactions[i%2][1] - compactions[(i-1)%2][1]) - } - if db.compReadMeter != nil { - db.compReadMeter.Mark(compactions[i%2][2] - compactions[(i-1)%2][2]) - } - if db.compWriteMeter != nil { - db.compWriteMeter.Mark(compactions[i%2][3] - compactions[(i-1)%2][3]) - } + db.diskSizeGauge.Update(compactions[i%2][0]) + db.compTimeMeter.Mark(compactions[i%2][1] - compactions[(i-1)%2][1]) + db.compReadMeter.Mark(compactions[i%2][2] - compactions[(i-1)%2][2]) + db.compWriteMeter.Mark(compactions[i%2][3] - compactions[(i-1)%2][3]) var ( delayN = int64(stats.WriteDelayCount) duration = stats.WriteDelayDuration paused = stats.WritePaused ) - if db.writeDelayNMeter != nil { - db.writeDelayNMeter.Mark(delayN - delaystats[0]) - } - if db.writeDelayMeter != nil { - db.writeDelayMeter.Mark(duration.Nanoseconds() - delaystats[1]) - } + db.writeDelayNMeter.Mark(delayN - delaystats[0]) + db.writeDelayMeter.Mark(duration.Nanoseconds() - delaystats[1]) // If a warning that db is performing compaction has been displayed, any subsequent // warnings will be withheld for one minute not to overwhelm the user. if paused && delayN-delaystats[0] == 0 && duration.Nanoseconds()-delaystats[1] == 0 && @@ -404,12 +392,8 @@ func (db *Database) meter(refresh time.Duration, namespace string) { nRead = int64(stats.IORead) nWrite = int64(stats.IOWrite) ) - if db.diskReadMeter != nil { - db.diskReadMeter.Mark(nRead - iostats[0]) - } - if db.diskWriteMeter != nil { - db.diskWriteMeter.Mark(nWrite - iostats[1]) - } + db.diskReadMeter.Mark(nRead - iostats[0]) + db.diskWriteMeter.Mark(nWrite - iostats[1]) iostats[0], iostats[1] = nRead, nWrite db.memCompGauge.Update(int64(stats.MemComp)) diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index 8d6fcd2d51..b87ecb2595 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -465,12 +465,8 @@ func (d *Database) meter(refresh time.Duration, namespace string) { compReads[i%2] = compRead nWrites[i%2] = nWrite - if d.writeDelayNMeter != nil { - d.writeDelayNMeter.Mark(writeDelayCounts[i%2] - writeDelayCounts[(i-1)%2]) - } - if d.writeDelayMeter != nil { - d.writeDelayMeter.Mark(writeDelayTimes[i%2] - writeDelayTimes[(i-1)%2]) - } + d.writeDelayNMeter.Mark(writeDelayCounts[i%2] - writeDelayCounts[(i-1)%2]) + d.writeDelayMeter.Mark(writeDelayTimes[i%2] - writeDelayTimes[(i-1)%2]) // Print a warning log if writing has been stalled for a while. The log will // be printed per minute to avoid overwhelming users. if d.writeStalled.Load() && writeDelayCounts[i%2] == writeDelayCounts[(i-1)%2] && @@ -478,24 +474,13 @@ func (d *Database) meter(refresh time.Duration, namespace string) { d.log.Warn("Database compacting, degraded performance") lastWriteStallReport = time.Now() } - if d.compTimeMeter != nil { - d.compTimeMeter.Mark(compTimes[i%2] - compTimes[(i-1)%2]) - } - if d.compReadMeter != nil { - d.compReadMeter.Mark(compReads[i%2] - compReads[(i-1)%2]) - } - if d.compWriteMeter != nil { - d.compWriteMeter.Mark(compWrites[i%2] - compWrites[(i-1)%2]) - } - if d.diskSizeGauge != nil { - d.diskSizeGauge.Update(int64(stats.DiskSpaceUsage())) - } - if d.diskReadMeter != nil { - d.diskReadMeter.Mark(0) // pebble doesn't track non-compaction reads - } - if d.diskWriteMeter != nil { - d.diskWriteMeter.Mark(nWrites[i%2] - nWrites[(i-1)%2]) - } + d.compTimeMeter.Mark(compTimes[i%2] - compTimes[(i-1)%2]) + d.compReadMeter.Mark(compReads[i%2] - compReads[(i-1)%2]) + d.compWriteMeter.Mark(compWrites[i%2] - compWrites[(i-1)%2]) + d.diskSizeGauge.Update(int64(stats.DiskSpaceUsage())) + d.diskReadMeter.Mark(0) // pebble doesn't track non-compaction reads + d.diskWriteMeter.Mark(nWrites[i%2] - nWrites[(i-1)%2]) + // See https://github.com/cockroachdb/pebble/pull/1628#pullrequestreview-1026664054 manuallyAllocated := stats.BlockCache.Size + int64(stats.MemTable.Size) + int64(stats.MemTable.ZombieSize) d.manualMemAllocGauge.Update(manuallyAllocated) From eb879a76cf7f67526543afaecb7e3e6c48372ac4 Mon Sep 17 00:00:00 2001 From: buddho Date: Wed, 12 Mar 2025 05:30:45 +0800 Subject: [PATCH 180/940] go.mod: update crypto to remove dependency warning (#31334) --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 9c0c447f3d..eac0d7a7fd 100644 --- a/go.mod +++ b/go.mod @@ -64,10 +64,10 @@ require ( github.com/urfave/cli/v2 v2.27.5 go.uber.org/automaxprocs v1.5.2 go.uber.org/goleak v1.3.0 - golang.org/x/crypto v0.32.0 - golang.org/x/sync v0.10.0 - golang.org/x/sys v0.29.0 - golang.org/x/text v0.21.0 + golang.org/x/crypto v0.35.0 + golang.org/x/sync v0.11.0 + golang.org/x/sys v0.30.0 + golang.org/x/text v0.22.0 golang.org/x/time v0.9.0 golang.org/x/tools v0.29.0 google.golang.org/protobuf v1.34.2 diff --git a/go.sum b/go.sum index 42abfe4d30..4537d194d0 100644 --- a/go.sum +++ b/go.sum @@ -541,8 +541,8 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= 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= @@ -640,8 +640,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ 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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -705,8 +705,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.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= @@ -726,8 +726,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 915d9d9de5c54bac566f7a418dc994d49689f19e Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 12 Mar 2025 19:20:40 +0800 Subject: [PATCH 181/940] cmd: ctrl-c to halt the whole import process (#31360) When I press Ctrl-C during the import of multiple files, the import process will still attempt to import the subsequent files. However, in normal circumstances, users would expect the import to stop immediately upon pressing Ctrl-C. And because the current file was not finished importing, subsequent import tasks often fail due to an `unknown ancestor` error. --------- Signed-off-by: jsvisa Co-authored-by: Felix Lange --- cmd/geth/chaincmd.go | 12 ++++++++---- cmd/utils/cmd.go | 5 ++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index eb0dda0952..c30927d9ff 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -103,11 +103,12 @@ if one is set. Otherwise it prints the genesis from the datadir.`, utils.StateHistoryFlag, }, utils.DatabaseFlags), Description: ` -The import command imports blocks from an RLP-encoded form. The form can be one file -with several RLP-encoded blocks, or several files can be used. +The import command allows the import of blocks from an RLP-encoded format. This format can be a single file +containing multiple RLP-encoded blocks, or multiple files can be given. -If only one file is used, import error will result in failure. If several files are used, -processing will proceed even if an individual RLP-file import failure occurs.`, +If only one file is used, an import error will result in the entire import process failing. If +multiple files are processed, the import process will continue even if an individual RLP file fails +to import successfully.`, } exportCommand = &cli.Command{ Action: exportChain, @@ -319,6 +320,9 @@ func importChain(ctx *cli.Context) error { if err := utils.ImportChain(chain, arg); err != nil { importErr = err log.Error("Import error", "file", arg, "err", err) + if err == utils.ErrImportInterrupted { + break + } } } } diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index de5918a722..33c93c2cc6 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -55,6 +55,9 @@ const ( importBatchSize = 2500 ) +// ErrImportInterrupted is returned when the user interrupts the import process. +var ErrImportInterrupted = errors.New("interrupted") + // Fatalf formats a message to standard error and exits the program. // The message is also printed to standard output if standard error // is redirected to a different file. @@ -191,7 +194,7 @@ func ImportChain(chain *core.BlockChain, fn string) error { for batch := 0; ; batch++ { // Load a batch of RLP blocks. if checkInterrupt() { - return errors.New("interrupted") + return ErrImportInterrupted } i := 0 for ; i < importBatchSize; i++ { From 5606cbc710ffcf327740e4db54776eb8a3c1a2fc Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 12 Mar 2025 12:21:50 +0100 Subject: [PATCH 182/940] crypto/secp256k1: update libsecp256k1 (#31242) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the libsecp256k1 dependency to commit: c0d9480fbbf8eccbd4be23ed27f6f2af6f3b211e PR: ``` BenchmarkSign-24 57756 21214 ns/op 164 B/op 3 allocs/op BenchmarkRecover-24 37156 33044 ns/op 80 B/op 1 allocs/op BenchmarkEcrecoverSignature-24 36889 32935 ns/op 80 B/op 1 allocs/op BenchmarkVerifySignature-24 41163 29207 ns/op 0 B/op 0 allocs/op BenchmarkDecompressPubkey-24 318624 4062 ns/op 304 B/op 6 allocs/op ``` Master: ``` BenchmarkSign-24 34509 35330 ns/op 164 B/op 3 allocs/op BenchmarkRecover-24 25418 47725 ns/op 80 B/op 1 allocs/op BenchmarkEcrecoverSignature-24 25735 47591 ns/op 80 B/op 1 allocs/op BenchmarkVerifySignature-24 29108 41097 ns/op 0 B/op 0 allocs/op BenchmarkDecompressPubkey-24 294747 4143 ns/op 304 B/op 6 allocs/op ``` Performance seems to be improved significantly: ``` Sign-24 34.86µ ± 3% 21.66µ ± 2% -37.86% (p=0.000 n=10) Recover-24 46.14µ ± 3% 33.24µ ± 2% -27.95% (p=0.000 n=10) ``` --- crypto/secp256k1/ext.h | 4 +- crypto/secp256k1/libsecp256k1/.cirrus.yml | 101 + crypto/secp256k1/libsecp256k1/.gitattributes | 2 + .../install-homebrew-valgrind/action.yml | 33 + .../actions/run-in-docker-action/action.yml | 54 + .../libsecp256k1/.github/workflows/ci.yml | 890 + crypto/secp256k1/libsecp256k1/.gitignore | 42 +- crypto/secp256k1/libsecp256k1/.travis.yml | 69 - crypto/secp256k1/libsecp256k1/CHANGELOG.md | 177 + crypto/secp256k1/libsecp256k1/CMakeLists.txt | 405 + .../secp256k1/libsecp256k1/CMakePresets.json | 19 + crypto/secp256k1/libsecp256k1/CONTRIBUTING.md | 109 + crypto/secp256k1/libsecp256k1/Makefile.am | 283 +- crypto/secp256k1/libsecp256k1/README.md | 158 +- crypto/secp256k1/libsecp256k1/SECURITY.md | 15 + crypto/secp256k1/libsecp256k1/TODO | 3 - .../build-aux/m4/ax_jni_include_dir.m4 | 140 - .../build-aux/m4/ax_prog_cc_for_build.m4 | 125 - .../libsecp256k1/build-aux/m4/bitcoin_secp.m4 | 134 +- crypto/secp256k1/libsecp256k1/ci/ci.sh | 149 + .../libsecp256k1/ci/linux-debian.Dockerfile | 79 + .../cmake/CheckArm32Assembly.cmake | 6 + .../cmake/CheckMemorySanitizer.cmake | 18 + .../cmake/CheckStringOptionValue.cmake | 10 + .../cmake/CheckX86_64Assembly.cmake | 14 + .../libsecp256k1/cmake/FindValgrind.cmake | 41 + .../cmake/GeneratePkgConfigFile.cmake | 8 + .../libsecp256k1/cmake/TryAppendCFlags.cmake | 24 + .../cmake/arm-linux-gnueabihf.toolchain.cmake | 3 + .../libsecp256k1/cmake/config.cmake.in | 5 + .../libsecp256k1/cmake/source_arm32.s | 9 + .../cmake/x86_64-w64-mingw32.toolchain.cmake | 3 + crypto/secp256k1/libsecp256k1/configure.ac | 752 +- .../libsecp256k1/contrib/lax_der_parsing.c | 22 +- .../libsecp256k1/contrib/lax_der_parsing.h | 30 +- .../contrib/lax_der_privatekey_parsing.c | 13 +- .../contrib/lax_der_privatekey_parsing.h | 29 +- crypto/secp256k1/libsecp256k1/doc/ellswift.md | 483 + crypto/secp256k1/libsecp256k1/doc/musig.md | 54 + .../libsecp256k1/doc/release-process.md | 94 + .../doc/safegcd_implementation.md | 819 + .../libsecp256k1/examples/CMakeLists.txt | 31 + .../libsecp256k1/examples/EXAMPLES_COPYING | 121 + crypto/secp256k1/libsecp256k1/examples/ecdh.c | 121 + .../secp256k1/libsecp256k1/examples/ecdsa.c | 138 + .../libsecp256k1/examples/ellswift.c | 122 + .../libsecp256k1/examples/examples_util.h | 108 + .../secp256k1/libsecp256k1/examples/musig.c | 261 + .../secp256k1/libsecp256k1/examples/schnorr.c | 154 + .../libsecp256k1/include/secp256k1.h | 724 +- .../libsecp256k1/include/secp256k1_ecdh.h | 68 +- .../libsecp256k1/include/secp256k1_ellswift.h | 200 + .../include/secp256k1_extrakeys.h | 250 + .../libsecp256k1/include/secp256k1_musig.h | 588 + .../include/secp256k1_preallocated.h | 134 + .../libsecp256k1/include/secp256k1_recovery.h | 85 +- .../include/secp256k1_schnorrsig.h | 190 + .../secp256k1/libsecp256k1/libsecp256k1.pc.in | 1 - crypto/secp256k1/libsecp256k1/obj/.gitignore | 0 .../sage/gen_exhaustive_groups.sage | 156 + .../sage/gen_split_lambda_constants.sage | 114 + .../libsecp256k1/sage/group_prover.sage | 89 +- ....sage => prove_group_implementations.sage} | 163 +- .../libsecp256k1/sage/secp256k1_params.sage | 39 + .../libsecp256k1/sage/weierstrass_prover.sage | 45 +- .../secp256k1/libsecp256k1/src/CMakeLists.txt | 176 + .../libsecp256k1/src/asm/field_10x26_arm.s | 19 +- .../secp256k1/libsecp256k1/src/assumptions.h | 87 + .../secp256k1/libsecp256k1/src/basic-config.h | 32 - crypto/secp256k1/libsecp256k1/src/bench.c | 280 + crypto/secp256k1/libsecp256k1/src/bench.h | 194 +- .../secp256k1/libsecp256k1/src/bench_ecmult.c | 368 + .../libsecp256k1/src/bench_internal.c | 555 +- .../libsecp256k1/src/bench_schnorr_verify.c | 73 - .../secp256k1/libsecp256k1/src/bench_sign.c | 56 - .../secp256k1/libsecp256k1/src/bench_verify.c | 112 - crypto/secp256k1/libsecp256k1/src/checkmem.h | 102 + .../secp256k1/libsecp256k1/src/ctime_tests.c | 267 + crypto/secp256k1/libsecp256k1/src/ecdsa.h | 18 +- .../secp256k1/libsecp256k1/src/ecdsa_impl.h | 149 +- crypto/secp256k1/libsecp256k1/src/eckey.h | 20 +- .../secp256k1/libsecp256k1/src/eckey_impl.h | 55 +- crypto/secp256k1/libsecp256k1/src/ecmult.h | 74 +- .../libsecp256k1/src/ecmult_compute_table.h | 16 + .../src/ecmult_compute_table_impl.h | 49 + .../secp256k1/libsecp256k1/src/ecmult_const.h | 39 +- .../libsecp256k1/src/ecmult_const_impl.h | 568 +- .../secp256k1/libsecp256k1/src/ecmult_gen.h | 156 +- .../src/ecmult_gen_compute_table.h | 14 + .../src/ecmult_gen_compute_table_impl.h | 108 + .../libsecp256k1/src/ecmult_gen_impl.h | 445 +- .../secp256k1/libsecp256k1/src/ecmult_impl.h | 995 +- crypto/secp256k1/libsecp256k1/src/field.h | 386 +- .../secp256k1/libsecp256k1/src/field_10x26.h | 48 +- .../libsecp256k1/src/field_10x26_impl.h | 474 +- .../secp256k1/libsecp256k1/src/field_5x52.h | 53 +- .../libsecp256k1/src/field_5x52_asm_impl.h | 502 - .../libsecp256k1/src/field_5x52_impl.h | 463 +- .../libsecp256k1/src/field_5x52_int128_impl.h | 299 +- .../secp256k1/libsecp256k1/src/field_impl.h | 536 +- .../secp256k1/libsecp256k1/src/gen_context.c | 74 - crypto/secp256k1/libsecp256k1/src/group.h | 152 +- .../secp256k1/libsecp256k1/src/group_impl.h | 872 +- crypto/secp256k1/libsecp256k1/src/hash.h | 49 +- crypto/secp256k1/libsecp256k1/src/hash_impl.h | 160 +- crypto/secp256k1/libsecp256k1/src/hsort.h | 33 + .../secp256k1/libsecp256k1/src/hsort_impl.h | 125 + crypto/secp256k1/libsecp256k1/src/int128.h | 90 + .../secp256k1/libsecp256k1/src/int128_impl.h | 18 + .../libsecp256k1/src/int128_native.h | 19 + .../libsecp256k1/src/int128_native_impl.h | 94 + .../libsecp256k1/src/int128_struct.h | 14 + .../libsecp256k1/src/int128_struct_impl.h | 205 + .../src/java/org/bitcoin/NativeSecp256k1.java | 446 - .../java/org/bitcoin/NativeSecp256k1Test.java | 226 - .../java/org/bitcoin/NativeSecp256k1Util.java | 45 - .../java/org/bitcoin/Secp256k1Context.java | 51 - .../src/java/org_bitcoin_NativeSecp256k1.c | 377 - .../src/java/org_bitcoin_NativeSecp256k1.h | 119 - .../src/java/org_bitcoin_Secp256k1Context.c | 15 - .../src/java/org_bitcoin_Secp256k1Context.h | 22 - crypto/secp256k1/libsecp256k1/src/modinv32.h | 43 + .../libsecp256k1/src/modinv32_impl.h | 725 + crypto/secp256k1/libsecp256k1/src/modinv64.h | 47 + .../libsecp256k1/src/modinv64_impl.h | 780 + .../src/modules/ecdh/Makefile.am.include | 6 +- .../ecdh/bench_impl.h} | 47 +- .../libsecp256k1/src/modules/ecdh/main_impl.h | 94 +- .../src/modules/ecdh/tests_impl.h | 143 +- .../src/modules/ellswift/Makefile.am.include | 5 + .../src/modules/ellswift/bench_impl.h | 106 + .../src/modules/ellswift/main_impl.h | 592 + .../modules/ellswift/tests_exhaustive_impl.h | 39 + .../src/modules/ellswift/tests_impl.h | 436 + .../src/modules/extrakeys/Makefile.am.include | 4 + .../src/modules/extrakeys/main_impl.h | 285 + .../modules/extrakeys/tests_exhaustive_impl.h | 68 + .../src/modules/extrakeys/tests_impl.h | 483 + .../src/modules/musig/Makefile.am.include | 8 + .../libsecp256k1/src/modules/musig/keyagg.h | 32 + .../src/modules/musig/keyagg_impl.h | 291 + .../src/modules/musig/main_impl.h | 12 + .../libsecp256k1/src/modules/musig/session.h | 24 + .../src/modules/musig/session_impl.h | 816 + .../src/modules/musig/tests_impl.h | 1143 ++ .../libsecp256k1/src/modules/musig/vectors.h | 346 + .../src/modules/recovery/Makefile.am.include | 7 +- .../recovery/bench_impl.h} | 42 +- .../src/modules/recovery/main_impl.h | 82 +- .../modules/recovery/tests_exhaustive_impl.h | 148 + .../src/modules/recovery/tests_impl.h | 287 +- .../modules/schnorrsig/Makefile.am.include | 5 + .../src/modules/schnorrsig/bench_impl.h | 104 + .../src/modules/schnorrsig/main_impl.h | 271 + .../schnorrsig/tests_exhaustive_impl.h | 214 + .../src/modules/schnorrsig/tests_impl.h | 982 + crypto/secp256k1/libsecp256k1/src/num.h | 74 - crypto/secp256k1/libsecp256k1/src/num_gmp.h | 20 - .../secp256k1/libsecp256k1/src/num_gmp_impl.h | 288 - crypto/secp256k1/libsecp256k1/src/num_impl.h | 24 - .../libsecp256k1/src/precompute_ecmult.c | 91 + .../libsecp256k1/src/precompute_ecmult_gen.c | 101 + .../libsecp256k1/src/precomputed_ecmult.c | 16456 ++++++++++++++++ .../libsecp256k1/src/precomputed_ecmult.h | 38 + .../libsecp256k1/src/precomputed_ecmult_gen.c | 1779 ++ .../libsecp256k1/src/precomputed_ecmult_gen.h | 26 + crypto/secp256k1/libsecp256k1/src/scalar.h | 83 +- .../secp256k1/libsecp256k1/src/scalar_4x64.h | 16 +- .../libsecp256k1/src/scalar_4x64_impl.h | 663 +- .../secp256k1/libsecp256k1/src/scalar_8x32.h | 16 +- .../libsecp256k1/src/scalar_8x32_impl.h | 427 +- .../secp256k1/libsecp256k1/src/scalar_impl.h | 565 +- .../secp256k1/libsecp256k1/src/scalar_low.h | 25 +- .../libsecp256k1/src/scalar_low_impl.h | 166 +- crypto/secp256k1/libsecp256k1/src/scratch.h | 44 + .../secp256k1/libsecp256k1/src/scratch_impl.h | 99 + crypto/secp256k1/libsecp256k1/src/secp256k1.c | 648 +- crypto/secp256k1/libsecp256k1/src/selftest.h | 32 + crypto/secp256k1/libsecp256k1/src/testrand.h | 46 +- .../libsecp256k1/src/testrand_impl.h | 217 +- crypto/secp256k1/libsecp256k1/src/tests.c | 6788 +++++-- .../libsecp256k1/src/tests_exhaustive.c | 528 +- crypto/secp256k1/libsecp256k1/src/testutil.h | 148 + crypto/secp256k1/libsecp256k1/src/util.h | 400 +- .../src/wycheproof/WYCHEPROOF_COPYING | 212 + .../ecdsa_secp256k1_sha256_bitcoin_test.h | 1564 ++ .../ecdsa_secp256k1_sha256_bitcoin_test.json | 6360 ++++++ .../secp256k1/libsecp256k1/tools/check-abi.sh | 74 + .../tools/test_vectors_musig2_generate.py | 656 + .../tools/tests_wycheproof_generate.py | 115 + crypto/secp256k1/secp256.go | 15 +- 191 files changed, 57984 insertions(+), 9861 deletions(-) create mode 100644 crypto/secp256k1/libsecp256k1/.cirrus.yml create mode 100644 crypto/secp256k1/libsecp256k1/.gitattributes create mode 100644 crypto/secp256k1/libsecp256k1/.github/actions/install-homebrew-valgrind/action.yml create mode 100644 crypto/secp256k1/libsecp256k1/.github/actions/run-in-docker-action/action.yml create mode 100644 crypto/secp256k1/libsecp256k1/.github/workflows/ci.yml delete mode 100644 crypto/secp256k1/libsecp256k1/.travis.yml create mode 100644 crypto/secp256k1/libsecp256k1/CHANGELOG.md create mode 100644 crypto/secp256k1/libsecp256k1/CMakeLists.txt create mode 100644 crypto/secp256k1/libsecp256k1/CMakePresets.json create mode 100644 crypto/secp256k1/libsecp256k1/CONTRIBUTING.md create mode 100644 crypto/secp256k1/libsecp256k1/SECURITY.md delete mode 100644 crypto/secp256k1/libsecp256k1/TODO delete mode 100644 crypto/secp256k1/libsecp256k1/build-aux/m4/ax_jni_include_dir.m4 delete mode 100644 crypto/secp256k1/libsecp256k1/build-aux/m4/ax_prog_cc_for_build.m4 create mode 100755 crypto/secp256k1/libsecp256k1/ci/ci.sh create mode 100644 crypto/secp256k1/libsecp256k1/ci/linux-debian.Dockerfile create mode 100644 crypto/secp256k1/libsecp256k1/cmake/CheckArm32Assembly.cmake create mode 100644 crypto/secp256k1/libsecp256k1/cmake/CheckMemorySanitizer.cmake create mode 100644 crypto/secp256k1/libsecp256k1/cmake/CheckStringOptionValue.cmake create mode 100644 crypto/secp256k1/libsecp256k1/cmake/CheckX86_64Assembly.cmake create mode 100644 crypto/secp256k1/libsecp256k1/cmake/FindValgrind.cmake create mode 100644 crypto/secp256k1/libsecp256k1/cmake/GeneratePkgConfigFile.cmake create mode 100644 crypto/secp256k1/libsecp256k1/cmake/TryAppendCFlags.cmake create mode 100644 crypto/secp256k1/libsecp256k1/cmake/arm-linux-gnueabihf.toolchain.cmake create mode 100644 crypto/secp256k1/libsecp256k1/cmake/config.cmake.in create mode 100644 crypto/secp256k1/libsecp256k1/cmake/source_arm32.s create mode 100644 crypto/secp256k1/libsecp256k1/cmake/x86_64-w64-mingw32.toolchain.cmake create mode 100644 crypto/secp256k1/libsecp256k1/doc/ellswift.md create mode 100644 crypto/secp256k1/libsecp256k1/doc/musig.md create mode 100644 crypto/secp256k1/libsecp256k1/doc/release-process.md create mode 100644 crypto/secp256k1/libsecp256k1/doc/safegcd_implementation.md create mode 100644 crypto/secp256k1/libsecp256k1/examples/CMakeLists.txt create mode 100644 crypto/secp256k1/libsecp256k1/examples/EXAMPLES_COPYING create mode 100644 crypto/secp256k1/libsecp256k1/examples/ecdh.c create mode 100644 crypto/secp256k1/libsecp256k1/examples/ecdsa.c create mode 100644 crypto/secp256k1/libsecp256k1/examples/ellswift.c create mode 100644 crypto/secp256k1/libsecp256k1/examples/examples_util.h create mode 100644 crypto/secp256k1/libsecp256k1/examples/musig.c create mode 100644 crypto/secp256k1/libsecp256k1/examples/schnorr.c create mode 100644 crypto/secp256k1/libsecp256k1/include/secp256k1_ellswift.h create mode 100644 crypto/secp256k1/libsecp256k1/include/secp256k1_extrakeys.h create mode 100644 crypto/secp256k1/libsecp256k1/include/secp256k1_musig.h create mode 100644 crypto/secp256k1/libsecp256k1/include/secp256k1_preallocated.h create mode 100644 crypto/secp256k1/libsecp256k1/include/secp256k1_schnorrsig.h delete mode 100644 crypto/secp256k1/libsecp256k1/obj/.gitignore create mode 100644 crypto/secp256k1/libsecp256k1/sage/gen_exhaustive_groups.sage create mode 100644 crypto/secp256k1/libsecp256k1/sage/gen_split_lambda_constants.sage rename crypto/secp256k1/libsecp256k1/sage/{secp256k1.sage => prove_group_implementations.sage} (72%) create mode 100644 crypto/secp256k1/libsecp256k1/sage/secp256k1_params.sage create mode 100644 crypto/secp256k1/libsecp256k1/src/CMakeLists.txt create mode 100644 crypto/secp256k1/libsecp256k1/src/assumptions.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/basic-config.h create mode 100644 crypto/secp256k1/libsecp256k1/src/bench.c create mode 100644 crypto/secp256k1/libsecp256k1/src/bench_ecmult.c delete mode 100644 crypto/secp256k1/libsecp256k1/src/bench_schnorr_verify.c delete mode 100644 crypto/secp256k1/libsecp256k1/src/bench_sign.c delete mode 100644 crypto/secp256k1/libsecp256k1/src/bench_verify.c create mode 100644 crypto/secp256k1/libsecp256k1/src/checkmem.h create mode 100644 crypto/secp256k1/libsecp256k1/src/ctime_tests.c create mode 100644 crypto/secp256k1/libsecp256k1/src/ecmult_compute_table.h create mode 100644 crypto/secp256k1/libsecp256k1/src/ecmult_compute_table_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/ecmult_gen_compute_table.h create mode 100644 crypto/secp256k1/libsecp256k1/src/ecmult_gen_compute_table_impl.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/field_5x52_asm_impl.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/gen_context.c create mode 100644 crypto/secp256k1/libsecp256k1/src/hsort.h create mode 100644 crypto/secp256k1/libsecp256k1/src/hsort_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/int128.h create mode 100644 crypto/secp256k1/libsecp256k1/src/int128_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/int128_native.h create mode 100644 crypto/secp256k1/libsecp256k1/src/int128_native_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/int128_struct.h create mode 100644 crypto/secp256k1/libsecp256k1/src/int128_struct_impl.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1.java delete mode 100644 crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java delete mode 100644 crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java delete mode 100644 crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/Secp256k1Context.java delete mode 100644 crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_NativeSecp256k1.c delete mode 100644 crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_NativeSecp256k1.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_Secp256k1Context.c delete mode 100644 crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_Secp256k1Context.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modinv32.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modinv32_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modinv64.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modinv64_impl.h rename crypto/secp256k1/libsecp256k1/src/{bench_ecdh.c => modules/ecdh/bench_impl.h} (54%) create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/ellswift/Makefile.am.include create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/ellswift/bench_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/ellswift/main_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/ellswift/tests_exhaustive_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/ellswift/tests_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/extrakeys/Makefile.am.include create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/extrakeys/main_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/extrakeys/tests_exhaustive_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/extrakeys/tests_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/musig/Makefile.am.include create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/musig/main_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/musig/session.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/musig/session_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/musig/tests_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/musig/vectors.h rename crypto/secp256k1/libsecp256k1/src/{bench_recover.c => modules/recovery/bench_impl.h} (58%) mode change 100755 => 100644 crypto/secp256k1/libsecp256k1/src/modules/recovery/main_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_exhaustive_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/Makefile.am.include create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/bench_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/main_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/tests_impl.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/num.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/num_gmp.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/num_gmp_impl.h delete mode 100644 crypto/secp256k1/libsecp256k1/src/num_impl.h create mode 100644 crypto/secp256k1/libsecp256k1/src/precompute_ecmult.c create mode 100644 crypto/secp256k1/libsecp256k1/src/precompute_ecmult_gen.c create mode 100644 crypto/secp256k1/libsecp256k1/src/precomputed_ecmult.c create mode 100644 crypto/secp256k1/libsecp256k1/src/precomputed_ecmult.h create mode 100644 crypto/secp256k1/libsecp256k1/src/precomputed_ecmult_gen.c create mode 100644 crypto/secp256k1/libsecp256k1/src/precomputed_ecmult_gen.h create mode 100644 crypto/secp256k1/libsecp256k1/src/scratch.h create mode 100644 crypto/secp256k1/libsecp256k1/src/scratch_impl.h mode change 100755 => 100644 crypto/secp256k1/libsecp256k1/src/secp256k1.c create mode 100644 crypto/secp256k1/libsecp256k1/src/selftest.h create mode 100644 crypto/secp256k1/libsecp256k1/src/testutil.h create mode 100644 crypto/secp256k1/libsecp256k1/src/wycheproof/WYCHEPROOF_COPYING create mode 100644 crypto/secp256k1/libsecp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h create mode 100644 crypto/secp256k1/libsecp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json create mode 100755 crypto/secp256k1/libsecp256k1/tools/check-abi.sh create mode 100755 crypto/secp256k1/libsecp256k1/tools/test_vectors_musig2_generate.py create mode 100755 crypto/secp256k1/libsecp256k1/tools/tests_wycheproof_generate.py diff --git a/crypto/secp256k1/ext.h b/crypto/secp256k1/ext.h index e422fe4b49..1c485e2603 100644 --- a/crypto/secp256k1/ext.h +++ b/crypto/secp256k1/ext.h @@ -109,8 +109,8 @@ int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, unsigned char *point, ARG_CHECK(scalar != NULL); (void)ctx; - secp256k1_fe_set_b32(&feX, point); - secp256k1_fe_set_b32(&feY, point+32); + secp256k1_fe_set_b32_limit(&feX, point); + secp256k1_fe_set_b32_limit(&feY, point+32); secp256k1_ge_set_xy(&ge, &feX, &feY); secp256k1_scalar_set_b32(&s, scalar, &overflow); if (overflow || secp256k1_scalar_is_zero(&s)) { diff --git a/crypto/secp256k1/libsecp256k1/.cirrus.yml b/crypto/secp256k1/libsecp256k1/.cirrus.yml new file mode 100644 index 0000000000..81a4f04328 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/.cirrus.yml @@ -0,0 +1,101 @@ +env: + ### cirrus config + CIRRUS_CLONE_DEPTH: 1 + ### compiler options + HOST: + WRAPPER_CMD: + # Specific warnings can be disabled with -Wno-error=foo. + # -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual. + WERROR_CFLAGS: -Werror -pedantic-errors + MAKEFLAGS: -j4 + BUILD: check + ### secp256k1 config + ECMULTWINDOW: 15 + ECMULTGENKB: 22 + ASM: no + WIDEMUL: auto + WITH_VALGRIND: yes + EXTRAFLAGS: + ### secp256k1 modules + EXPERIMENTAL: no + ECDH: no + RECOVERY: no + EXTRAKEYS: no + SCHNORRSIG: no + MUSIG: no + ELLSWIFT: no + ### test options + SECP256K1_TEST_ITERS: 64 + BENCH: yes + SECP256K1_BENCH_ITERS: 2 + CTIMETESTS: yes + # Compile and run the tests + EXAMPLES: yes + +cat_logs_snippet: &CAT_LOGS + always: + cat_tests_log_script: + - cat tests.log || true + cat_noverify_tests_log_script: + - cat noverify_tests.log || true + cat_exhaustive_tests_log_script: + - cat exhaustive_tests.log || true + cat_ctime_tests_log_script: + - cat ctime_tests.log || true + cat_bench_log_script: + - cat bench.log || true + cat_config_log_script: + - cat config.log || true + cat_test_env_script: + - cat test_env.log || true + cat_ci_env_script: + - env + +linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER + env_script: + - env | tee /tmp/env + build_script: + - DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm" + - docker image prune --force # Cleanup stale layers + test_script: + - docker run --rm --mount "type=bind,src=./,dst=/ci_secp256k1" --env-file /tmp/env --replace --name "ci_secp256k1_arm" "ci_secp256k1_arm" bash -c "cd /ci_secp256k1/ && ./ci/ci.sh" + +task: + name: "ARM64: Linux (Debian stable)" + persistent_worker: + labels: + type: arm64 + env: + ECDH: yes + RECOVERY: yes + EXTRAKEYS: yes + SCHNORRSIG: yes + MUSIG: yes + ELLSWIFT: yes + matrix: + # Currently only gcc-snapshot, the other compilers are tested on GHA with QEMU + - env: { CC: 'gcc-snapshot' } + << : *LINUX_ARM64_CONTAINER + << : *CAT_LOGS + +task: + name: "ARM64: Linux (Debian stable), Valgrind" + persistent_worker: + labels: + type: arm64 + env: + ECDH: yes + RECOVERY: yes + EXTRAKEYS: yes + SCHNORRSIG: yes + MUSIG: yes + ELLSWIFT: yes + WRAPPER_CMD: 'valgrind --error-exitcode=42' + SECP256K1_TEST_ITERS: 2 + matrix: + - env: { CC: 'gcc' } + - env: { CC: 'clang' } + - env: { CC: 'gcc-snapshot' } + - env: { CC: 'clang-snapshot' } + << : *LINUX_ARM64_CONTAINER + << : *CAT_LOGS diff --git a/crypto/secp256k1/libsecp256k1/.gitattributes b/crypto/secp256k1/libsecp256k1/.gitattributes new file mode 100644 index 0000000000..30efb2244f --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/.gitattributes @@ -0,0 +1,2 @@ +src/precomputed_ecmult.c linguist-generated +src/precomputed_ecmult_gen.c linguist-generated diff --git a/crypto/secp256k1/libsecp256k1/.github/actions/install-homebrew-valgrind/action.yml b/crypto/secp256k1/libsecp256k1/.github/actions/install-homebrew-valgrind/action.yml new file mode 100644 index 0000000000..ce10eb2686 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/.github/actions/install-homebrew-valgrind/action.yml @@ -0,0 +1,33 @@ +name: "Install Valgrind" +description: "Install Homebrew's Valgrind package and cache it." +runs: + using: "composite" + steps: + - run: | + brew tap LouisBrunner/valgrind + brew fetch --HEAD LouisBrunner/valgrind/valgrind + echo "CI_HOMEBREW_CELLAR_VALGRIND=$(brew --cellar valgrind)" >> "$GITHUB_ENV" + shell: bash + + - run: | + sw_vers > valgrind_fingerprint + brew --version >> valgrind_fingerprint + git -C "$(brew --cache)/valgrind--git" rev-parse HEAD >> valgrind_fingerprint + cat valgrind_fingerprint + shell: bash + + - uses: actions/cache@v4 + id: cache + with: + path: ${{ env.CI_HOMEBREW_CELLAR_VALGRIND }} + key: ${{ github.job }}-valgrind-${{ hashFiles('valgrind_fingerprint') }} + + - if: steps.cache.outputs.cache-hit != 'true' + run: | + brew install --HEAD LouisBrunner/valgrind/valgrind + shell: bash + + - if: steps.cache.outputs.cache-hit == 'true' + run: | + brew link valgrind + shell: bash diff --git a/crypto/secp256k1/libsecp256k1/.github/actions/run-in-docker-action/action.yml b/crypto/secp256k1/libsecp256k1/.github/actions/run-in-docker-action/action.yml new file mode 100644 index 0000000000..74933686a0 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/.github/actions/run-in-docker-action/action.yml @@ -0,0 +1,54 @@ +name: 'Run in Docker with environment' +description: 'Run a command in a Docker container, while passing explicitly set environment variables into the container.' +inputs: + dockerfile: + description: 'A Dockerfile that defines an image' + required: true + tag: + description: 'A tag of an image' + required: true + command: + description: 'A command to run in a container' + required: false + default: ./ci/ci.sh +runs: + using: "composite" + steps: + - uses: docker/setup-buildx-action@v3 + + - uses: docker/build-push-action@v5 + id: main_builder + continue-on-error: true + with: + context: . + file: ${{ inputs.dockerfile }} + tags: ${{ inputs.tag }} + load: true + cache-from: type=gha + + - uses: docker/build-push-action@v5 + id: retry_builder + if: steps.main_builder.outcome == 'failure' + with: + context: . + file: ${{ inputs.dockerfile }} + tags: ${{ inputs.tag }} + load: true + cache-from: type=gha + + - # Workaround for https://github.com/google/sanitizers/issues/1614 . + # The underlying issue has been fixed in clang 18.1.3. + run: sudo sysctl -w vm.mmap_rnd_bits=28 + shell: bash + + - # Tell Docker to pass environment variables in `env` into the container. + run: > + docker run \ + $(echo '${{ toJSON(env) }}' | jq -r 'keys[] | "--env \(.) "') \ + --volume ${{ github.workspace }}:${{ github.workspace }} \ + --workdir ${{ github.workspace }} \ + ${{ inputs.tag }} bash -c " + git config --global --add safe.directory ${{ github.workspace }} + ${{ inputs.command }} + " + shell: bash diff --git a/crypto/secp256k1/libsecp256k1/.github/workflows/ci.yml b/crypto/secp256k1/libsecp256k1/.github/workflows/ci.yml new file mode 100644 index 0000000000..54b2fab1c4 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/.github/workflows/ci.yml @@ -0,0 +1,890 @@ +name: CI +on: + pull_request: + push: + branches: + - '**' + tags-ignore: + - '**' + +concurrency: + group: ${{ github.event_name != 'pull_request' && github.run_id || github.ref }} + cancel-in-progress: true + +env: + ### compiler options + HOST: + WRAPPER_CMD: + # Specific warnings can be disabled with -Wno-error=foo. + # -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual. + WERROR_CFLAGS: '-Werror -pedantic-errors' + MAKEFLAGS: '-j4' + BUILD: 'check' + ### secp256k1 config + ECMULTWINDOW: 15 + ECMULTGENKB: 86 + ASM: 'no' + WIDEMUL: 'auto' + WITH_VALGRIND: 'yes' + EXTRAFLAGS: + ### secp256k1 modules + EXPERIMENTAL: 'no' + ECDH: 'no' + RECOVERY: 'no' + EXTRAKEYS: 'no' + SCHNORRSIG: 'no' + MUSIG: 'no' + ELLSWIFT: 'no' + ### test options + SECP256K1_TEST_ITERS: 64 + BENCH: 'yes' + SECP256K1_BENCH_ITERS: 2 + CTIMETESTS: 'yes' + # Compile and run the examples. + EXAMPLES: 'yes' + +jobs: + docker_cache: + name: "Build Docker image" + runs-on: ubuntu-latest + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + # See: https://github.com/moby/buildkit/issues/3969. + driver-opts: | + network=host + + - name: Build container + uses: docker/build-push-action@v5 + with: + file: ./ci/linux-debian.Dockerfile + tags: linux-debian-image + cache-from: type=gha + cache-to: type=gha,mode=min + + linux_debian: + name: "x86_64: Linux (Debian stable)" + runs-on: ubuntu-latest + needs: docker_cache + + strategy: + fail-fast: false + matrix: + configuration: + - env_vars: { WIDEMUL: 'int64', RECOVERY: 'yes' } + - env_vars: { WIDEMUL: 'int64', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' } + - env_vars: { WIDEMUL: 'int128' } + - env_vars: { WIDEMUL: 'int128_struct', ELLSWIFT: 'yes' } + - env_vars: { WIDEMUL: 'int128', RECOVERY: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' } + - env_vars: { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes' } + - env_vars: { WIDEMUL: 'int128', ASM: 'x86_64', ELLSWIFT: 'yes' } + - env_vars: { RECOVERY: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes' } + - env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', CPPFLAGS: '-DVERIFY' } + - env_vars: { BUILD: 'distcheck', WITH_VALGRIND: 'no', CTIMETESTS: 'no', BENCH: 'no' } + - env_vars: { CPPFLAGS: '-DDETERMINISTIC' } + - env_vars: { CFLAGS: '-O0', CTIMETESTS: 'no' } + - env_vars: { CFLAGS: '-O1', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' } + - env_vars: { ECMULTGENKB: 2, ECMULTWINDOW: 2 } + - env_vars: { ECMULTGENKB: 86, ECMULTWINDOW: 4 } + cc: + - 'gcc' + - 'clang' + - 'gcc-snapshot' + - 'clang-snapshot' + + env: + CC: ${{ matrix.cc }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + env: ${{ matrix.configuration.env_vars }} + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + i686_debian: + name: "i686: Linux (Debian stable)" + runs-on: ubuntu-latest + needs: docker_cache + + strategy: + fail-fast: false + matrix: + cc: + - 'i686-linux-gnu-gcc' + - 'clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include' + + env: + HOST: 'i686-linux-gnu' + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CC: ${{ matrix.cc }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + s390x_debian: + name: "s390x (big-endian): Linux (Debian stable, QEMU)" + runs-on: ubuntu-latest + needs: docker_cache + + env: + WRAPPER_CMD: 'qemu-s390x' + SECP256K1_TEST_ITERS: 16 + HOST: 's390x-linux-gnu' + WITH_VALGRIND: 'no' + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CTIMETESTS: 'no' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + arm32_debian: + name: "ARM32: Linux (Debian stable, QEMU)" + runs-on: ubuntu-latest + needs: docker_cache + + strategy: + fail-fast: false + matrix: + configuration: + - env_vars: {} + - env_vars: { EXPERIMENTAL: 'yes', ASM: 'arm32' } + + env: + WRAPPER_CMD: 'qemu-arm' + SECP256K1_TEST_ITERS: 16 + HOST: 'arm-linux-gnueabihf' + WITH_VALGRIND: 'no' + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CTIMETESTS: 'no' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + env: ${{ matrix.configuration.env_vars }} + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + arm64_debian: + name: "ARM64: Linux (Debian stable, QEMU)" + runs-on: ubuntu-latest + needs: docker_cache + + env: + WRAPPER_CMD: 'qemu-aarch64' + SECP256K1_TEST_ITERS: 16 + HOST: 'aarch64-linux-gnu' + WITH_VALGRIND: 'no' + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CTIMETESTS: 'no' + + strategy: + fail-fast: false + matrix: + configuration: + - env_vars: { } # gcc + - env_vars: # clang + CC: 'clang --target=aarch64-linux-gnu' + - env_vars: # clang-snapshot + CC: 'clang-snapshot --target=aarch64-linux-gnu' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + env: ${{ matrix.configuration.env_vars }} + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + ppc64le_debian: + name: "ppc64le: Linux (Debian stable, QEMU)" + runs-on: ubuntu-latest + needs: docker_cache + + env: + WRAPPER_CMD: 'qemu-ppc64le' + SECP256K1_TEST_ITERS: 16 + HOST: 'powerpc64le-linux-gnu' + WITH_VALGRIND: 'no' + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CTIMETESTS: 'no' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + valgrind_debian: + name: "Valgrind (memcheck)" + runs-on: ubuntu-latest + needs: docker_cache + + strategy: + fail-fast: false + matrix: + configuration: + - env_vars: { CC: 'clang', ASM: 'auto' } + - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' } + - env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + + env: + # The `--error-exitcode` is required to make the test fail if valgrind found errors, + # otherwise it will return 0 (https://www.valgrind.org/docs/manual/manual-core.html). + WRAPPER_CMD: 'valgrind --error-exitcode=42' + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CTIMETESTS: 'no' + SECP256K1_TEST_ITERS: 2 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + env: ${{ matrix.configuration.env_vars }} + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + sanitizers_debian: + name: "UBSan, ASan, LSan" + runs-on: ubuntu-latest + needs: docker_cache + + strategy: + fail-fast: false + matrix: + configuration: + - env_vars: { CC: 'clang', ASM: 'auto' } + - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' } + - env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + + env: + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CTIMETESTS: 'no' + CFLAGS: '-fsanitize=undefined,address -g' + UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1' + ASAN_OPTIONS: 'strict_string_checks=1:detect_stack_use_after_return=1:detect_leaks=1' + LSAN_OPTIONS: 'use_unaligned=1' + SECP256K1_TEST_ITERS: 32 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + env: ${{ matrix.configuration.env_vars }} + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + msan_debian: + name: "MSan" + runs-on: ubuntu-latest + needs: docker_cache + + strategy: + fail-fast: false + matrix: + configuration: + - env_vars: + CTIMETESTS: 'yes' + CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g' + - env_vars: + ECMULTGENKB: 2 + ECMULTWINDOW: 2 + CTIMETESTS: 'yes' + CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g -O3' + - env_vars: + # -fsanitize-memory-param-retval is clang's default, but our build system disables it + # when ctime_tests when enabled. + CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -fsanitize-memory-param-retval -g' + CTIMETESTS: 'no' + + env: + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CC: 'clang' + SECP256K1_TEST_ITERS: 32 + ASM: 'no' + WITH_VALGRIND: 'no' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + env: ${{ matrix.configuration.env_vars }} + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + mingw_debian: + name: ${{ matrix.configuration.job_name }} + runs-on: ubuntu-latest + needs: docker_cache + + env: + WRAPPER_CMD: 'wine' + WITH_VALGRIND: 'no' + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + CTIMETESTS: 'no' + + strategy: + fail-fast: false + matrix: + configuration: + - job_name: 'x86_64 (mingw32-w64): Windows (Debian stable, Wine)' + env_vars: + HOST: 'x86_64-w64-mingw32' + - job_name: 'i686 (mingw32-w64): Windows (Debian stable, Wine)' + env_vars: + HOST: 'i686-w64-mingw32' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + env: ${{ matrix.configuration.env_vars }} + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + x86_64-macos-native: + name: "x86_64: macOS Ventura, Valgrind" + # See: https://github.com/actions/runner-images#available-images. + runs-on: macos-13 + + env: + CC: 'clang' + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + strategy: + fail-fast: false + matrix: + env_vars: + - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128_struct', ECMULTGENKB: 2, ECMULTWINDOW: 4 } + - { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', CC: 'gcc' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' } + - BUILD: 'distcheck' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Homebrew packages + run: | + brew install --quiet automake libtool gcc + ln -s $(brew --prefix gcc)/bin/gcc-?? /usr/local/bin/gcc + + - name: Install and cache Valgrind + uses: ./.github/actions/install-homebrew-valgrind + + - name: CI script + env: ${{ matrix.env_vars }} + run: ./ci/ci.sh + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + arm64-macos-native: + name: "ARM64: macOS Sonoma" + # See: https://github.com/actions/runner-images#available-images. + runs-on: macos-14 + + env: + CC: 'clang' + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + WITH_VALGRIND: 'no' + CTIMETESTS: 'no' + + strategy: + fail-fast: false + matrix: + env_vars: + - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128_struct', ECMULTGENPRECISION: 2, ECMULTWINDOW: 4 } + - { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', CC: 'gcc' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', CPPFLAGS: '-DVERIFY' } + - BUILD: 'distcheck' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Homebrew packages + run: | + brew install --quiet automake libtool gcc + ln -s $(brew --prefix gcc)/bin/gcc-?? /usr/local/bin/gcc + + - name: CI script + env: ${{ matrix.env_vars }} + run: ./ci/ci.sh + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + win64-native: + name: ${{ matrix.configuration.job_name }} + # See: https://github.com/actions/runner-images#available-images. + runs-on: windows-2022 + + strategy: + fail-fast: false + matrix: + configuration: + - job_name: 'x64 (MSVC): Windows (VS 2022, shared)' + cmake_options: '-A x64 -DBUILD_SHARED_LIBS=ON' + - job_name: 'x64 (MSVC): Windows (VS 2022, static)' + cmake_options: '-A x64 -DBUILD_SHARED_LIBS=OFF' + - job_name: 'x64 (MSVC): Windows (VS 2022, int128_struct)' + cmake_options: '-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct' + - job_name: 'x64 (MSVC): Windows (VS 2022, int128_struct with __(u)mulh)' + cmake_options: '-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct' + cpp_flags: '/DSECP256K1_MSVC_MULH_TEST_OVERRIDE' + - job_name: 'x86 (MSVC): Windows (VS 2022)' + cmake_options: '-A Win32' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Generate buildsystem + run: cmake -E env CFLAGS="/WX ${{ matrix.configuration.cpp_flags }}" cmake -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON ${{ matrix.configuration.cmake_options }} + + - name: Build + run: cmake --build build --config RelWithDebInfo -- /p:UseMultiToolTask=true /maxCpuCount + + - name: Binaries info + # Use the bash shell included with Git for Windows. + shell: bash + run: | + cd build/bin/RelWithDebInfo && file *tests.exe bench*.exe libsecp256k1-*.dll || true + + - name: Check + run: | + ctest -C RelWithDebInfo --test-dir build -j ([int]$env:NUMBER_OF_PROCESSORS + 1) + build\bin\RelWithDebInfo\bench_ecmult.exe + build\bin\RelWithDebInfo\bench_internal.exe + build\bin\RelWithDebInfo\bench.exe + + win64-native-headers: + name: "x64 (MSVC): C++ (public headers)" + # See: https://github.com/actions/runner-images#available-images. + runs-on: windows-2022 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Add cl.exe to PATH + uses: ilammy/msvc-dev-cmd@v1 + + - name: C++ (public headers) + run: | + cl.exe -c -WX -TP include/*.h + + cxx_fpermissive_debian: + name: "C++ -fpermissive (entire project)" + runs-on: ubuntu-latest + needs: docker_cache + + env: + CC: 'g++' + CFLAGS: '-fpermissive -g' + CPPFLAGS: '-DSECP256K1_CPLUSPLUS_TEST_OVERRIDE' + WERROR_CFLAGS: + ECDH: 'yes' + RECOVERY: 'yes' + EXTRAKEYS: 'yes' + SCHNORRSIG: 'yes' + MUSIG: 'yes' + ELLSWIFT: 'yes' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + + cxx_headers_debian: + name: "C++ (public headers)" + runs-on: ubuntu-latest + needs: docker_cache + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + uses: ./.github/actions/run-in-docker-action + with: + dockerfile: ./ci/linux-debian.Dockerfile + tag: linux-debian-image + command: | + g++ -Werror include/*.h + clang -Werror -x c++-header include/*.h + + sage: + name: "SageMath prover" + runs-on: ubuntu-latest + container: + image: sagemath/sagemath:latest + options: --user root + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: CI script + run: | + cd sage + sage prove_group_implementations.sage + + release: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - run: ./autogen.sh && ./configure --enable-dev-mode && make distcheck + + - name: Check installation with Autotools + env: + CI_INSTALL: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/install + run: | + ./autogen.sh && ./configure --prefix=${{ env.CI_INSTALL }} && make clean && make install && ls -RlAh ${{ env.CI_INSTALL }} + gcc -o ecdsa examples/ecdsa.c $(PKG_CONFIG_PATH=${{ env.CI_INSTALL }}/lib/pkgconfig pkg-config --cflags --libs libsecp256k1) -Wl,-rpath,"${{ env.CI_INSTALL }}/lib" && ./ecdsa + + - name: Check installation with CMake + env: + CI_BUILD: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/build + CI_INSTALL: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/install + run: | + cmake -B ${{ env.CI_BUILD }} -DCMAKE_INSTALL_PREFIX=${{ env.CI_INSTALL }} && cmake --build ${{ env.CI_BUILD }} && cmake --install ${{ env.CI_BUILD }} && ls -RlAh ${{ env.CI_INSTALL }} + gcc -o ecdsa examples/ecdsa.c -I ${{ env.CI_INSTALL }}/include -L ${{ env.CI_INSTALL }}/lib*/ -l secp256k1 -Wl,-rpath,"${{ env.CI_INSTALL }}/lib",-rpath,"${{ env.CI_INSTALL }}/lib64" && ./ecdsa diff --git a/crypto/secp256k1/libsecp256k1/.gitignore b/crypto/secp256k1/libsecp256k1/.gitignore index 87fea161ba..bffba8cb2c 100644 --- a/crypto/secp256k1/libsecp256k1/.gitignore +++ b/crypto/secp256k1/libsecp256k1/.gitignore @@ -1,17 +1,24 @@ -bench_inv -bench_ecdh -bench_sign -bench_verify -bench_schnorr_verify -bench_recover +bench +bench_ecmult bench_internal +noverify_tests tests exhaustive_tests -gen_context +precompute_ecmult_gen +precompute_ecmult +ctime_tests +ecdh_example +ecdsa_example +schnorr_example +ellswift_example +musig_example *.exe *.so *.a -!.gitignore +*.csv +*.log +*.trs +*.sage.py Makefile configure @@ -21,6 +28,7 @@ aclocal.m4 autom4te.cache/ config.log config.status +conftest* *.tar.gz *.la libtool @@ -29,9 +37,15 @@ libtool *.lo *.o *~ -src/libsecp256k1-config.h -src/libsecp256k1-config.h.in -src/ecmult_static_context.h + +coverage/ +coverage.html +coverage.*.html +*.gcda +*.gcno +*.gcov + +build-aux/ar-lib build-aux/config.guess build-aux/config.sub build-aux/depcomp @@ -45,5 +59,9 @@ build-aux/m4/ltversion.m4 build-aux/missing build-aux/compile build-aux/test-driver -src/stamp-h1 libsecp256k1.pc + +### CMake +/CMakeUserPresets.json +# Default CMake build directory. +/build diff --git a/crypto/secp256k1/libsecp256k1/.travis.yml b/crypto/secp256k1/libsecp256k1/.travis.yml deleted file mode 100644 index 2439529242..0000000000 --- a/crypto/secp256k1/libsecp256k1/.travis.yml +++ /dev/null @@ -1,69 +0,0 @@ -language: c -sudo: false -addons: - apt: - packages: libgmp-dev -compiler: - - clang - - gcc -cache: - directories: - - src/java/guava/ -env: - global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no - - GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar - matrix: - - SCALAR=32bit RECOVERY=yes - - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes - - SCALAR=64bit - - FIELD=64bit RECOVERY=yes - - FIELD=64bit ENDOMORPHISM=yes - - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes - - FIELD=64bit ASM=x86_64 - - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - - FIELD=32bit ENDOMORPHISM=yes - - BIGNUM=no - - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes - - BIGNUM=no STATICPRECOMPUTATION=no - - BUILD=distcheck - - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC - - EXTRAFLAGS=CFLAGS=-O0 - - BUILD=check-java ECDH=yes EXPERIMENTAL=yes -matrix: - fast_finish: true - include: - - compiler: clang - env: HOST=i686-linux-gnu ENDOMORPHISM=yes - addons: - apt: - packages: - - gcc-multilib - - libgmp-dev:i386 - - compiler: clang - env: HOST=i686-linux-gnu - addons: - apt: - packages: - - gcc-multilib - - compiler: gcc - env: HOST=i686-linux-gnu ENDOMORPHISM=yes - addons: - apt: - packages: - - gcc-multilib - - compiler: gcc - env: HOST=i686-linux-gnu - addons: - apt: - packages: - - gcc-multilib - - libgmp-dev:i386 -before_install: mkdir -p `dirname $GUAVA_JAR` -install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi -before_script: ./autogen.sh -script: - - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi - - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi - - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD -os: linux diff --git a/crypto/secp256k1/libsecp256k1/CHANGELOG.md b/crypto/secp256k1/libsecp256k1/CHANGELOG.md new file mode 100644 index 0000000000..05222e5ed0 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/CHANGELOG.md @@ -0,0 +1,177 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.6.0] - 2024-11-04 + +#### Added + - New module `musig` implements the MuSig2 multisignature scheme according to the [BIP 327 specification](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). See: + - Header file `include/secp256k1_musig.h` which defines the new API. + - Document `doc/musig.md` for further notes on API usage. + - Usage example `examples/musig.c`. + - New CMake variable `SECP256K1_APPEND_LDFLAGS` for appending linker flags to the build command. + +#### Changed + - API functions now use a significantly more robust method to clear secrets from the stack before returning. However, secret clearing remains a best-effort security measure and cannot guarantee complete removal. + - Any type `secp256k1_foo` can now be forward-declared using `typedef struct secp256k1_foo secp256k1_foo;` (or also `struct secp256k1_foo;` in C++). + - Organized CMake build artifacts into dedicated directories (`bin/` for executables, `lib/` for libraries) to improve build output structure and Windows shared library compatibility. + +#### Removed + - Removed the `secp256k1_scratch_space` struct and its associated functions `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` because the scratch space was unused in the API. + +#### ABI Compatibility +The symbols `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` were removed. +Otherwise, the library maintains backward compatibility with versions 0.3.x through 0.5.x. + +## [0.5.1] - 2024-08-01 + +#### Added + - Added usage example for an ElligatorSwift key exchange. + +#### Changed + - The default size of the precomputed table for signing was changed from 22 KiB to 86 KiB. The size can be changed with the configure option `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake). + - "auto" is no longer an accepted value for the `--with-ecmult-window` and `--with-ecmult-gen-kb` configure options (this also applies to `SECP256K1_ECMULT_WINDOW_SIZE` and `SECP256K1_ECMULT_GEN_KB` in CMake). To achieve the same configuration as previously provided by the "auto" value, omit setting the configure option explicitly. + +#### Fixed + - Fixed compilation when the extrakeys module is disabled. + +#### ABI Compatibility +The ABI is backward compatible with versions 0.5.0, 0.4.x and 0.3.x. + +## [0.5.0] - 2024-05-06 + +#### Added + - New function `secp256k1_ec_pubkey_sort` that sorts public keys using lexicographic (of compressed serialization) order. + +#### Changed + - The implementation of the point multiplication algorithm used for signing and public key generation was changed, resulting in improved performance for those operations. + - The related configure option `--ecmult-gen-precision` was replaced with `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake). + - This changes the supported precomputed table sizes for these operations. The new supported sizes are 2 KiB, 22 KiB, or 86 KiB (while the old supported sizes were 32 KiB, 64 KiB, or 512 KiB). + +#### ABI Compatibility +The ABI is backward compatible with versions 0.4.x and 0.3.x. + +## [0.4.1] - 2023-12-21 + +#### Changed + - The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one. + - Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is enabled (`--with-asm=x86_64` in GNU Autotools, `-DSECP256K1_ASM=x86_64` in CMake), which is the default on x86_64. Benchmarks with GCC 10.5.0 show a 10% speedup for `secp256k1_ecdsa_verify` and `secp256k1_schnorrsig_verify`. + +#### ABI Compatibility +The ABI is backward compatible with versions 0.4.0 and 0.3.x. + +## [0.4.0] - 2023-09-04 + +#### Added + - New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them. + ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See: + - Header file `include/secp256k1_ellswift.h` which defines the new API. + - Document `doc/ellswift.md` which explains the mathematical background of the scheme. + - The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based. + - We now test the library with unreleased development snapshots of GCC and Clang. This gives us an early chance to catch miscompilations and constant-time issues introduced by the compiler (such as those that led to the previous two releases). + +#### Fixed + - Fixed symbol visibility in Windows DLL builds, where three internal library symbols were wrongly exported. + +#### Changed + - When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`. + +#### ABI Compatibility +This release is backward compatible with the ABI of 0.3.0, 0.3.1, and 0.3.2. Symbol visibility is now believed to be handled properly on supported platforms and is now considered to be part of the ABI. Please report any improperly exported symbols as a bug. + +## [0.3.2] - 2023-05-13 +We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`. + +#### Security + - Module `ecdh`: Fix "constant-timeness" issue with GCC 13.1 (and potentially future versions of GCC) that could leave applications using libsecp256k1's ECDH module vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow during ECDH computations when libsecp256k1 is compiled with GCC 13.1. + +#### Fixed + - Fixed an old bug that permitted compilers to potentially output bad assembly code on x86_64. In theory, it could lead to a crash or a read of unrelated memory, but this has never been observed on any compilers so far. + +#### Changed + - Various improvements and changes to CMake builds. CMake builds remain experimental. + - Made API versioning consistent with GNU Autotools builds. + - Switched to `BUILD_SHARED_LIBS` variable for controlling whether to build a static or a shared library. + - Added `SECP256K1_INSTALL` variable for the controlling whether to install the build artefacts. + - Renamed asm build option `arm` to `arm32`. Use `--with-asm=arm32` instead of `--with-asm=arm` (GNU Autotools), and `-DSECP256K1_ASM=arm32` instead of `-DSECP256K1_ASM=arm` (CMake). + +#### ABI Compatibility +The ABI is compatible with versions 0.3.0 and 0.3.1. + +## [0.3.1] - 2023-04-10 +We strongly recommend updating to 0.3.1 if you use or plan to use Clang >=14 to compile libsecp256k1, e.g., Xcode >=14 on macOS has Clang >=14. When in doubt, check the Clang version using `clang -v`. + +#### Security + - Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14. + +#### Added + - Added tests against [Project Wycheproof's](https://github.com/google/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases. + +#### Changed + - Increased minimum required CMake version to 3.13. CMake builds remain experimental. + +#### ABI Compatibility +The ABI is compatible with version 0.3.0. + +## [0.3.0] - 2023-03-08 + +#### Added + - Added experimental support for CMake builds. Traditional GNU Autotools builds (`./configure` and `make`) remain fully supported. + - Usage examples: Added a recommended method for securely clearing sensitive data, e.g., secret keys, from memory. + - Tests: Added a new test binary `noverify_tests`. This binary runs the tests without some additional checks present in the ordinary `tests` binary and is thereby closer to production binaries. The `noverify_tests` binary is automatically run as part of the `make check` target. + +#### Fixed + - Fixed declarations of API variables for MSVC (`__declspec(dllimport)`). This fixes MSVC builds of programs which link against a libsecp256k1 DLL dynamically and use API variables (and not only API functions). Unfortunately, the MSVC linker now will emit warning `LNK4217` when trying to link against libsecp256k1 statically. Pass `/ignore:4217` to the linker to suppress this warning. + +#### Changed + - Forbade cloning or destroying `secp256k1_context_static`. Create a new context instead of cloning the static context. (If this change breaks your code, your code is probably wrong.) + - Forbade randomizing (copies of) `secp256k1_context_static`. Randomizing a copy of `secp256k1_context_static` did not have any effect and did not provide defense-in-depth protection against side-channel attacks. Create a new context if you want to benefit from randomization. + +#### Removed + - Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags). + +#### ABI Compatibility +Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions. + +## [0.2.0] - 2022-12-12 + +#### Added + - Added usage examples for common use cases in a new `examples/` directory. + - Added `secp256k1_selftest`, to be used in conjunction with `secp256k1_context_static`. + - Added support for 128-bit wide multiplication on MSVC for x86_64 and arm64, giving roughly a 20% speedup on those platforms. + +#### Changed + - Enabled modules `schnorrsig`, `extrakeys` and `ecdh` by default in `./configure`. + - The `secp256k1_nonce_function_rfc6979` nonce function, used by default by `secp256k1_ecdsa_sign`, now reduces the message hash modulo the group order to match the specification. This only affects improper use of ECDSA signing API. + +#### Deprecated + - Deprecated context flags `SECP256K1_CONTEXT_VERIFY` and `SECP256K1_CONTEXT_SIGN`. Use `SECP256K1_CONTEXT_NONE` instead. + - Renamed `secp256k1_context_no_precomp` to `secp256k1_context_static`. + - Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`. + +#### ABI Compatibility +Since this is the first release, we do not compare application binary interfaces. +However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version. + +## [0.1.0] - 2013-03-05 to 2021-12-25 + +This version was in fact never released. +The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6). +Therefore, this version number does not uniquely identify a set of source files. + +[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.6.0...HEAD +[0.6.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.1...v0.6.0 +[0.5.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.0...v0.5.1 +[0.5.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...v0.5.0 +[0.4.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...v0.4.1 +[0.4.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...v0.4.0 +[0.3.2]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...v0.3.2 +[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1 +[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0 +[0.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0 +[0.1.0]: https://github.com/bitcoin-core/secp256k1/commit/423b6d19d373f1224fd671a982584d7e7900bc93 diff --git a/crypto/secp256k1/libsecp256k1/CMakeLists.txt b/crypto/secp256k1/libsecp256k1/CMakeLists.txt new file mode 100644 index 0000000000..aba6e51259 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/CMakeLists.txt @@ -0,0 +1,405 @@ +cmake_minimum_required(VERSION 3.16) + +#============================= +# Project / Package metadata +#============================= +project(libsecp256k1 + # The package (a.k.a. release) version is based on semantic versioning 2.0.0 of + # the API. All changes in experimental modules are treated as + # backwards-compatible and therefore at most increase the minor version. + VERSION 0.6.1 + DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1." + HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1" + LANGUAGES C +) +enable_testing() +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +if(CMAKE_VERSION VERSION_LESS 3.21) + # Emulates CMake 3.21+ behavior. + if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(PROJECT_IS_TOP_LEVEL ON) + set(${PROJECT_NAME}_IS_TOP_LEVEL ON) + else() + set(PROJECT_IS_TOP_LEVEL OFF) + set(${PROJECT_NAME}_IS_TOP_LEVEL OFF) + endif() +endif() + +# The library version is based on libtool versioning of the ABI. The set of +# rules for updating the version can be found here: +# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html +# All changes in experimental modules are treated as if they don't affect the +# interface and therefore only increase the revision. +set(${PROJECT_NAME}_LIB_VERSION_CURRENT 5) +set(${PROJECT_NAME}_LIB_VERSION_REVISION 1) +set(${PROJECT_NAME}_LIB_VERSION_AGE 0) + +#============================= +# Language setup +#============================= +set(CMAKE_C_STANDARD 90) +set(CMAKE_C_EXTENSIONS OFF) + +#============================= +# Configurable options +#============================= +option(BUILD_SHARED_LIBS "Build shared libraries." ON) +option(SECP256K1_DISABLE_SHARED "Disable shared library. Overrides BUILD_SHARED_LIBS." OFF) +if(SECP256K1_DISABLE_SHARED) + set(BUILD_SHARED_LIBS OFF) +endif() + +option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL}) + +## Modules + +# We declare all options before processing them, to make sure we can express +# dependencies while processing. +option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON) +option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF) +option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON) +option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON) +option(SECP256K1_ENABLE_MODULE_MUSIG "Enable musig module." ON) +option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON) + +# Processing must be done in a topological sorting of the dependency graph +# (dependent module first). +if(SECP256K1_ENABLE_MODULE_ELLSWIFT) + add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1) +endif() + +if(SECP256K1_ENABLE_MODULE_MUSIG) + if(DEFINED SECP256K1_ENABLE_MODULE_SCHNORRSIG AND NOT SECP256K1_ENABLE_MODULE_SCHNORRSIG) + message(FATAL_ERROR "Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.") + endif() + set(SECP256K1_ENABLE_MODULE_SCHNORRSIG ON) + add_compile_definitions(ENABLE_MODULE_MUSIG=1) +endif() + +if(SECP256K1_ENABLE_MODULE_SCHNORRSIG) + if(DEFINED SECP256K1_ENABLE_MODULE_EXTRAKEYS AND NOT SECP256K1_ENABLE_MODULE_EXTRAKEYS) + message(FATAL_ERROR "Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.") + endif() + set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON) + add_compile_definitions(ENABLE_MODULE_SCHNORRSIG=1) +endif() + +if(SECP256K1_ENABLE_MODULE_EXTRAKEYS) + add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1) +endif() + +if(SECP256K1_ENABLE_MODULE_RECOVERY) + add_compile_definitions(ENABLE_MODULE_RECOVERY=1) +endif() + +if(SECP256K1_ENABLE_MODULE_ECDH) + add_compile_definitions(ENABLE_MODULE_ECDH=1) +endif() + +option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF) +if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS) + add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1) +endif() + +set(SECP256K1_ECMULT_WINDOW_SIZE 15 CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. The default value is a reasonable setting for desktop machines (currently 15). [default=15]") +set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24) +include(CheckStringOptionValue) +check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE) +add_compile_definitions(ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE}) + +set(SECP256K1_ECMULT_GEN_KB 86 CACHE STRING "The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms). Larger values result in possibly better signing or key generation performance at the cost of a larger table. Valid choices are 2, 22, 86. The default value is a reasonable setting for desktop machines (currently 86). [default=86]") +set_property(CACHE SECP256K1_ECMULT_GEN_KB PROPERTY STRINGS 2 22 86) +check_string_option_value(SECP256K1_ECMULT_GEN_KB) +if(SECP256K1_ECMULT_GEN_KB EQUAL 2) + add_compile_definitions(COMB_BLOCKS=2) + add_compile_definitions(COMB_TEETH=5) +elseif(SECP256K1_ECMULT_GEN_KB EQUAL 22) + add_compile_definitions(COMB_BLOCKS=11) + add_compile_definitions(COMB_TEETH=6) +elseif(SECP256K1_ECMULT_GEN_KB EQUAL 86) + add_compile_definitions(COMB_BLOCKS=43) + add_compile_definitions(COMB_TEETH=6) +endif() + +set(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY "OFF" CACHE STRING "Test-only override of the (autodetected by the C code) \"widemul\" setting. Legal values are: \"OFF\", \"int128_struct\", \"int128\" or \"int64\". [default=OFF]") +set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64") +check_string_option_value(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) +if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) + string(TOUPPER "${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}" widemul_upper_value) + add_compile_definitions(USE_FORCE_WIDEMUL_${widemul_upper_value}=1) +endif() +mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) + +set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]") +set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm32") +check_string_option_value(SECP256K1_ASM) +if(SECP256K1_ASM STREQUAL "arm32") + enable_language(ASM) + include(CheckArm32Assembly) + check_arm32_assembly() + if(HAVE_ARM32_ASM) + add_compile_definitions(USE_EXTERNAL_ASM=1) + else() + message(FATAL_ERROR "ARM32 assembly requested but not available.") + endif() +elseif(SECP256K1_ASM) + include(CheckX86_64Assembly) + check_x86_64_assembly() + if(HAVE_X86_64_ASM) + set(SECP256K1_ASM "x86_64") + add_compile_definitions(USE_ASM_X86_64=1) + elseif(SECP256K1_ASM STREQUAL "AUTO") + set(SECP256K1_ASM "OFF") + else() + message(FATAL_ERROR "x86_64 assembly requested but not available.") + endif() +endif() + +option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF) +if(NOT SECP256K1_EXPERIMENTAL) + if(SECP256K1_ASM STREQUAL "arm32") + message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.") + endif() +endif() + +set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]") +set_property(CACHE SECP256K1_VALGRIND PROPERTY STRINGS "AUTO" "OFF" "ON") +check_string_option_value(SECP256K1_VALGRIND) +if(SECP256K1_VALGRIND) + find_package(Valgrind MODULE) + if(Valgrind_FOUND) + set(SECP256K1_VALGRIND ON) + include_directories(${Valgrind_INCLUDE_DIR}) + add_compile_definitions(VALGRIND) + elseif(SECP256K1_VALGRIND STREQUAL "AUTO") + set(SECP256K1_VALGRIND OFF) + else() + message(FATAL_ERROR "Valgrind support requested but valgrind/memcheck.h header not available.") + endif() +endif() + +option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON) +option(SECP256K1_BUILD_TESTS "Build tests." ON) +option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON) +option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND}) +option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF) + +# Redefine configuration flags. +# We leave assertions on, because they are only used in the examples, and we want them always on there. +if(MSVC) + string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") + string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") +else() + string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") + string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") + # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.) + string(REGEX REPLACE "-O3( |$)" "-O2\\1" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") +endif() + +# Define custom "Coverage" build type. +set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING + "Flags used by the C compiler during \"Coverage\" builds." + FORCE +) +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING + "Flags used for linking binaries during \"Coverage\" builds." + FORCE +) +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING + "Flags used by the shared libraries linker during \"Coverage\" builds." + FORCE +) +mark_as_advanced( + CMAKE_C_FLAGS_COVERAGE + CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE +) + +if(PROJECT_IS_TOP_LEVEL) + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + set(default_build_type "RelWithDebInfo") + if(is_multi_config) + set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING + "Supported configuration types." + FORCE + ) + else() + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY + STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" + ) + if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Setting build type to \"${default_build_type}\" as none was specified") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING + "Choose the type of build." + FORCE + ) + endif() + endif() +endif() + +include(TryAppendCFlags) +if(MSVC) + # Keep the following commands ordered lexicographically. + try_append_c_flags(/W3) # Production quality warning level. + try_append_c_flags(/wd4146) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned". + try_append_c_flags(/wd4244) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data". + try_append_c_flags(/wd4267) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data". + # Eliminate deprecation warnings for the older, less secure functions. + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +else() + # Keep the following commands ordered lexicographically. + try_append_c_flags(-pedantic) + try_append_c_flags(-Wall) # GCC >= 2.95 and probably many other compilers. + try_append_c_flags(-Wcast-align) # GCC >= 2.95. + try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0. + try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only. + try_append_c_flags(-Wextra) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions. + try_append_c_flags(-Wnested-externs) + try_append_c_flags(-Wno-long-long) # GCC >= 3.0, -Wlong-long is implied by -pedantic. + try_append_c_flags(-Wno-overlength-strings) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic. + try_append_c_flags(-Wno-unused-function) # GCC >= 3.0, -Wunused-function is implied by -Wall. + try_append_c_flags(-Wreserved-identifier) # Clang >= 13.0 only. + try_append_c_flags(-Wshadow) + try_append_c_flags(-Wstrict-prototypes) + try_append_c_flags(-Wundef) +endif() + +set(CMAKE_C_VISIBILITY_PRESET hidden) + +set(print_msan_notice) +if(SECP256K1_BUILD_CTIME_TESTS) + include(CheckMemorySanitizer) + check_memory_sanitizer(msan_enabled) + if(msan_enabled) + try_append_c_flags(-fno-sanitize-memory-param-retval) + set(print_msan_notice YES) + endif() + unset(msan_enabled) +endif() + +set(SECP256K1_APPEND_CFLAGS "" CACHE STRING "Compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.") +if(SECP256K1_APPEND_CFLAGS) + # Appending to this low-level rule variable is the only way to + # guarantee that the flags appear at the end of the command line. + string(APPEND CMAKE_C_COMPILE_OBJECT " ${SECP256K1_APPEND_CFLAGS}") +endif() + +set(SECP256K1_APPEND_LDFLAGS "" CACHE STRING "Linker flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.") +if(SECP256K1_APPEND_LDFLAGS) + # Appending to this low-level rule variable is the only way to + # guarantee that the flags appear at the end of the command line. + string(APPEND CMAKE_C_CREATE_SHARED_LIBRARY " ${SECP256K1_APPEND_LDFLAGS}") + string(APPEND CMAKE_C_LINK_EXECUTABLE " ${SECP256K1_APPEND_LDFLAGS}") +endif() + +if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +endif() +if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) +endif() +if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) +endif() +add_subdirectory(src) +if(SECP256K1_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +message("\n") +message("secp256k1 configure summary") +message("===========================") +message("Build artifacts:") +if(BUILD_SHARED_LIBS) + set(library_type "Shared") +else() + set(library_type "Static") +endif() + +message(" library type ........................ ${library_type}") +message("Optional modules:") +message(" ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}") +message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}") +message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}") +message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}") +message(" musig ............................... ${SECP256K1_ENABLE_MODULE_MUSIG}") +message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}") +message("Parameters:") +message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}") +message(" ecmult gen table size ............... ${SECP256K1_ECMULT_GEN_KB} KiB") +message("Optional features:") +message(" assembly ............................ ${SECP256K1_ASM}") +message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}") +if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) + message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}") +endif() +message("Optional binaries:") +message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}") +message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}") +set(tests_status "${SECP256K1_BUILD_TESTS}") +if(CMAKE_BUILD_TYPE STREQUAL "Coverage") + set(tests_status OFF) +endif() +message(" tests ............................... ${tests_status}") +message(" exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}") +message(" ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}") +message(" examples ............................ ${SECP256K1_BUILD_EXAMPLES}") +message("") +if(CMAKE_CROSSCOMPILING) + set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") +else() + set(cross_status "FALSE") +endif() +message("Cross compiling ....................... ${cross_status}") +message("Valgrind .............................. ${SECP256K1_VALGRIND}") +get_directory_property(definitions COMPILE_DEFINITIONS) +string(REPLACE ";" " " definitions "${definitions}") +message("Preprocessor defined macros ........... ${definitions}") +message("C compiler ............................ ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}, ${CMAKE_C_COMPILER}") +message("CFLAGS ................................ ${CMAKE_C_FLAGS}") +get_directory_property(compile_options COMPILE_OPTIONS) +string(REPLACE ";" " " compile_options "${compile_options}") +message("Compile options ....................... " ${compile_options}) +if(NOT is_multi_config) + message("Build type:") + message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}") + string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type) + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}") + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}") + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}") +else() + message("Supported configurations .............. ${CMAKE_CONFIGURATION_TYPES}") + message("RelWithDebInfo configuration:") + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}") + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}") + message("Debug configuration:") + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}") + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") +endif() +if(SECP256K1_APPEND_CFLAGS) + message("SECP256K1_APPEND_CFLAGS ............... ${SECP256K1_APPEND_CFLAGS}") +endif() +if(SECP256K1_APPEND_LDFLAGS) + message("SECP256K1_APPEND_LDFLAGS .............. ${SECP256K1_APPEND_LDFLAGS}") +endif() +message("") +if(print_msan_notice) + message( + "Note:\n" + " MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to compile options\n" + " to avoid false positives in ctime_tests. Pass -DSECP256K1_BUILD_CTIME_TESTS=OFF to avoid this.\n" + ) +endif() +if(SECP256K1_EXPERIMENTAL) + message( + " ******\n" + " WARNING: experimental build\n" + " Experimental features do not have stable APIs or properties, and may not be safe for production use.\n" + " ******\n" + ) +endif() diff --git a/crypto/secp256k1/libsecp256k1/CMakePresets.json b/crypto/secp256k1/libsecp256k1/CMakePresets.json new file mode 100644 index 0000000000..b35cd80579 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/CMakePresets.json @@ -0,0 +1,19 @@ +{ + "cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0}, + "version": 3, + "configurePresets": [ + { + "name": "dev-mode", + "displayName": "Development mode (intended only for developers of the library)", + "cacheVariables": { + "SECP256K1_EXPERIMENTAL": "ON", + "SECP256K1_ENABLE_MODULE_RECOVERY": "ON", + "SECP256K1_BUILD_EXAMPLES": "ON" + }, + "warnings": { + "dev": true, + "uninitialized": true + } + } + ] +} diff --git a/crypto/secp256k1/libsecp256k1/CONTRIBUTING.md b/crypto/secp256k1/libsecp256k1/CONTRIBUTING.md new file mode 100644 index 0000000000..80890fb706 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/CONTRIBUTING.md @@ -0,0 +1,109 @@ +# Contributing to libsecp256k1 + +## Scope + +libsecp256k1 is a library for elliptic curve cryptography on the curve secp256k1, not a general-purpose cryptography library. +The library primarily serves the needs of the Bitcoin Core project but provides additional functionality for the benefit of the wider Bitcoin ecosystem. + +## Adding new functionality or modules + +The libsecp256k1 project welcomes contributions in the form of new functionality or modules, provided they are within the project's scope. + +It is the responsibility of the contributors to convince the maintainers that the proposed functionality is within the project's scope, high-quality and maintainable. +Contributors are recommended to provide the following in addition to the new code: + +* **Specification:** + A specification can help significantly in reviewing the new code as it provides documentation and context. + It may justify various design decisions, give a motivation and outline security goals. + If the specification contains pseudocode, a reference implementation or test vectors, these can be used to compare with the proposed libsecp256k1 code. +* **Security Arguments:** + In addition to a defining the security goals, it should be argued that the new functionality meets these goals. + Depending on the nature of the new functionality, a wide range of security arguments are acceptable, ranging from being "obviously secure" to rigorous proofs of security. +* **Relevance Arguments:** + The relevance of the new functionality for the Bitcoin ecosystem should be argued by outlining clear use cases. + +These are not the only factors taken into account when considering to add new functionality. +The proposed new libsecp256k1 code must be of high quality, including API documentation and tests, as well as featuring a misuse-resistant API design. + +We recommend reaching out to other contributors (see [Communication Channels](#communication-channels)) and get feedback before implementing new functionality. + +## Communication channels + +Most communication about libsecp256k1 occurs on the GitHub repository: in issues, pull request or on the discussion board. + +Additionally, there is an IRC channel dedicated to libsecp256k1, with biweekly meetings (see channel topic). +The channel is `#secp256k1` on Libera Chat. +The easiest way to participate on IRC is with the web client, [web.libera.chat](https://web.libera.chat/#secp256k1). +Chat history logs can be found at https://gnusha.org/secp256k1/. + +## Contributor workflow & peer review + +The Contributor Workflow & Peer Review in libsecp256k1 are similar to Bitcoin Core's workflow and review processes described in its [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md). + +### Coding conventions + +In addition, libsecp256k1 tries to maintain the following coding conventions: + +* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations. +* The tests should cover all lines and branches of the library (see [Test coverage](#coverage)). +* Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)). +* Local variables containing secret data should be cleared explicitly to try to delete secrets from memory. +* Use `secp256k1_memcmp_var` instead of `memcmp` (see [#823](https://github.com/bitcoin-core/secp256k1/issues/823)). +* As a rule of thumb, the default values for configuration options should target standard desktop machines and align with Bitcoin Core's defaults, and the tests should mostly exercise the default configuration (see [#1549](https://github.com/bitcoin-core/secp256k1/issues/1549#issuecomment-2200559257)). + +#### Style conventions + +* Commits should be atomic and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures. +* New code should adhere to the style of existing, in particular surrounding, code. Other than that, we do not enforce strict rules for code formatting. +* The code conforms to C89. Most notably, that means that only `/* ... */` comments are allowed (no `//` line comments). Moreover, any declarations in a `{ ... }` block (e.g., a function) must appear at the beginning of the block before any statements. When you would like to declare a variable in the middle of a block, you can open a new block: + ```C + void secp256k_foo(void) { + unsigned int x; /* declaration */ + int y = 2*x; /* declaration */ + x = 17; /* statement */ + { + int a, b; /* declaration */ + a = x + y; /* statement */ + secp256k_bar(x, &b); /* statement */ + } + } + ``` +* Use `unsigned int` instead of just `unsigned`. +* Use `void *ptr` instead of `void* ptr`. +* Arguments of the publicly-facing API must have a specific order defined in [include/secp256k1.h](include/secp256k1.h). +* User-facing comment lines in headers should be limited to 80 chars if possible. +* All identifiers in file scope should start with `secp256k1_`. +* Avoid trailing whitespace. +* Use the constants `EXIT_SUCCESS`/`EXIT_FAILURE` (defined in `stdlib.h`) to indicate program execution status for examples and other binaries. + +### Tests + +#### Coverage + +This library aims to have full coverage of reachable lines and branches. + +To create a test coverage report, configure with `--enable-coverage` (use of GCC is necessary): + + $ ./configure --enable-coverage + +Run the tests: + + $ make check + +To create a report, `gcovr` is recommended, as it includes branch coverage reporting: + + $ gcovr --exclude 'src/bench*' --print-summary + +To create a HTML report with coloured and annotated source code: + + $ mkdir -p coverage + $ gcovr --exclude 'src/bench*' --html --html-details -o coverage/coverage.html + +#### Exhaustive tests + +There are tests of several functions in which a small group replaces secp256k1. +These tests are *exhaustive* since they provide all elements and scalars of the small group as input arguments (see [src/tests_exhaustive.c](src/tests_exhaustive.c)). + +### Benchmarks + +See `src/bench*.c` for examples of benchmarks. diff --git a/crypto/secp256k1/libsecp256k1/Makefile.am b/crypto/secp256k1/libsecp256k1/Makefile.am index c071fbe275..a95b4809d4 100644 --- a/crypto/secp256k1/libsecp256k1/Makefile.am +++ b/crypto/secp256k1/libsecp256k1/Makefile.am @@ -1,13 +1,12 @@ ACLOCAL_AMFLAGS = -I build-aux/m4 +# AM_CFLAGS will be automatically prepended to CFLAGS by Automake when compiling some foo +# which does not have an explicit foo_CFLAGS variable set. +AM_CFLAGS = $(SECP_CFLAGS) + lib_LTLIBRARIES = libsecp256k1.la -if USE_JNI -JNI_LIB = libsecp256k1_jni.la -noinst_LTLIBRARIES = $(JNI_LIB) -else -JNI_LIB = -endif include_HEADERS = include/secp256k1.h +include_HEADERS += include/secp256k1_preallocated.h noinst_HEADERS = noinst_HEADERS += src/scalar.h noinst_HEADERS += src/scalar_4x64.h @@ -19,29 +18,44 @@ noinst_HEADERS += src/scalar_8x32_impl.h noinst_HEADERS += src/scalar_low_impl.h noinst_HEADERS += src/group.h noinst_HEADERS += src/group_impl.h -noinst_HEADERS += src/num_gmp.h -noinst_HEADERS += src/num_gmp_impl.h noinst_HEADERS += src/ecdsa.h noinst_HEADERS += src/ecdsa_impl.h noinst_HEADERS += src/eckey.h noinst_HEADERS += src/eckey_impl.h noinst_HEADERS += src/ecmult.h noinst_HEADERS += src/ecmult_impl.h +noinst_HEADERS += src/ecmult_compute_table.h +noinst_HEADERS += src/ecmult_compute_table_impl.h noinst_HEADERS += src/ecmult_const.h noinst_HEADERS += src/ecmult_const_impl.h noinst_HEADERS += src/ecmult_gen.h noinst_HEADERS += src/ecmult_gen_impl.h -noinst_HEADERS += src/num.h -noinst_HEADERS += src/num_impl.h +noinst_HEADERS += src/ecmult_gen_compute_table.h +noinst_HEADERS += src/ecmult_gen_compute_table_impl.h noinst_HEADERS += src/field_10x26.h noinst_HEADERS += src/field_10x26_impl.h noinst_HEADERS += src/field_5x52.h noinst_HEADERS += src/field_5x52_impl.h noinst_HEADERS += src/field_5x52_int128_impl.h -noinst_HEADERS += src/field_5x52_asm_impl.h -noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h -noinst_HEADERS += src/java/org_bitcoin_Secp256k1Context.h +noinst_HEADERS += src/modinv32.h +noinst_HEADERS += src/modinv32_impl.h +noinst_HEADERS += src/modinv64.h +noinst_HEADERS += src/modinv64_impl.h +noinst_HEADERS += src/precomputed_ecmult.h +noinst_HEADERS += src/precomputed_ecmult_gen.h +noinst_HEADERS += src/assumptions.h +noinst_HEADERS += src/checkmem.h +noinst_HEADERS += src/testutil.h noinst_HEADERS += src/util.h +noinst_HEADERS += src/int128.h +noinst_HEADERS += src/int128_impl.h +noinst_HEADERS += src/int128_native.h +noinst_HEADERS += src/int128_native_impl.h +noinst_HEADERS += src/int128_struct.h +noinst_HEADERS += src/int128_struct_impl.h +noinst_HEADERS += src/scratch.h +noinst_HEADERS += src/scratch_impl.h +noinst_HEADERS += src/selftest.h noinst_HEADERS += src/testrand.h noinst_HEADERS += src/testrand_impl.h noinst_HEADERS += src/hash.h @@ -49,17 +63,28 @@ noinst_HEADERS += src/hash_impl.h noinst_HEADERS += src/field.h noinst_HEADERS += src/field_impl.h noinst_HEADERS += src/bench.h +noinst_HEADERS += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h +noinst_HEADERS += src/hsort.h +noinst_HEADERS += src/hsort_impl.h noinst_HEADERS += contrib/lax_der_parsing.h noinst_HEADERS += contrib/lax_der_parsing.c noinst_HEADERS += contrib/lax_der_privatekey_parsing.h noinst_HEADERS += contrib/lax_der_privatekey_parsing.c +noinst_HEADERS += examples/examples_util.h + +PRECOMPUTED_LIB = libsecp256k1_precomputed.la +noinst_LTLIBRARIES = $(PRECOMPUTED_LIB) +libsecp256k1_precomputed_la_SOURCES = src/precomputed_ecmult.c src/precomputed_ecmult_gen.c +# We need `-I$(top_srcdir)/src` in VPATH builds if libsecp256k1_precomputed_la_SOURCES have been recreated in the build tree. +# This helps users and packagers who insist on recreating the precomputed files (e.g., Gentoo). +libsecp256k1_precomputed_la_CPPFLAGS = -I$(top_srcdir)/src $(SECP_CONFIG_DEFINES) if USE_EXTERNAL_ASM COMMON_LIB = libsecp256k1_common.la -noinst_LTLIBRARIES = $(COMMON_LIB) else COMMON_LIB = endif +noinst_LTLIBRARIES += $(COMMON_LIB) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libsecp256k1.pc @@ -71,102 +96,186 @@ endif endif libsecp256k1_la_SOURCES = src/secp256k1.c -libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB) - -libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c -libsecp256k1_jni_la_CPPFLAGS = -DSECP256K1_BUILD $(JNI_INCLUDES) +libsecp256k1_la_CPPFLAGS = $(SECP_CONFIG_DEFINES) +libsecp256k1_la_LIBADD = $(COMMON_LIB) $(PRECOMPUTED_LIB) +libsecp256k1_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_CURRENT):$(LIB_VERSION_REVISION):$(LIB_VERSION_AGE) noinst_PROGRAMS = if USE_BENCHMARK -noinst_PROGRAMS += bench_verify bench_sign bench_internal -bench_verify_SOURCES = src/bench_verify.c -bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) -bench_sign_SOURCES = src/bench_sign.c -bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) +noinst_PROGRAMS += bench bench_internal bench_ecmult +bench_SOURCES = src/bench.c +bench_LDADD = libsecp256k1.la +bench_CPPFLAGS = $(SECP_CONFIG_DEFINES) bench_internal_SOURCES = src/bench_internal.c -bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB) -bench_internal_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES) +bench_internal_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB) +bench_internal_CPPFLAGS = $(SECP_CONFIG_DEFINES) +bench_ecmult_SOURCES = src/bench_ecmult.c +bench_ecmult_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB) +bench_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES) endif TESTS = if USE_TESTS -noinst_PROGRAMS += tests -tests_SOURCES = src/tests.c -tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) +TESTS += noverify_tests +noinst_PROGRAMS += noverify_tests +noverify_tests_SOURCES = src/tests.c +noverify_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES) +noverify_tests_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB) +noverify_tests_LDFLAGS = -static if !ENABLE_COVERAGE -tests_CPPFLAGS += -DVERIFY -endif -tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) -tests_LDFLAGS = -static TESTS += tests +noinst_PROGRAMS += tests +tests_SOURCES = $(noverify_tests_SOURCES) +tests_CPPFLAGS = $(noverify_tests_CPPFLAGS) -DVERIFY +tests_LDADD = $(noverify_tests_LDADD) +tests_LDFLAGS = $(noverify_tests_LDFLAGS) +endif +endif + +if USE_CTIME_TESTS +noinst_PROGRAMS += ctime_tests +ctime_tests_SOURCES = src/ctime_tests.c +ctime_tests_LDADD = libsecp256k1.la +ctime_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES) endif if USE_EXHAUSTIVE_TESTS noinst_PROGRAMS += exhaustive_tests exhaustive_tests_SOURCES = src/tests_exhaustive.c -exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src $(SECP_INCLUDES) +exhaustive_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES) if !ENABLE_COVERAGE exhaustive_tests_CPPFLAGS += -DVERIFY endif -exhaustive_tests_LDADD = $(SECP_LIBS) +# Note: do not include $(PRECOMPUTED_LIB) in exhaustive_tests (it uses runtime-generated tables). +exhaustive_tests_LDADD = $(COMMON_LIB) exhaustive_tests_LDFLAGS = -static TESTS += exhaustive_tests endif -JAVAROOT=src/java -JAVAORG=org/bitcoin -JAVA_GUAVA=$(srcdir)/$(JAVAROOT)/guava/guava-18.0.jar -CLASSPATH_ENV=CLASSPATH=$(JAVA_GUAVA) -JAVA_FILES= \ - $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1.java \ - $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Test.java \ - $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Util.java \ - $(JAVAROOT)/$(JAVAORG)/Secp256k1Context.java - -if USE_JNI - -$(JAVA_GUAVA): - @echo Guava is missing. Fetch it via: \ - wget https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar -O $(@) - @false - -.stamp-java: $(JAVA_FILES) - @echo Compiling $^ - $(AM_V_at)$(CLASSPATH_ENV) javac $^ - @touch $@ - -if USE_TESTS - -check-java: libsecp256k1.la $(JAVA_GUAVA) .stamp-java - $(AM_V_at)java -Djava.library.path="./:./src:./src/.libs:.libs/" -cp "$(JAVA_GUAVA):$(JAVAROOT)" $(JAVAORG)/NativeSecp256k1Test - +if USE_EXAMPLES +noinst_PROGRAMS += ecdsa_example +ecdsa_example_SOURCES = examples/ecdsa.c +ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC +ecdsa_example_LDADD = libsecp256k1.la +ecdsa_example_LDFLAGS = -static +if BUILD_WINDOWS +ecdsa_example_LDFLAGS += -lbcrypt +endif +TESTS += ecdsa_example +if ENABLE_MODULE_ECDH +noinst_PROGRAMS += ecdh_example +ecdh_example_SOURCES = examples/ecdh.c +ecdh_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC +ecdh_example_LDADD = libsecp256k1.la +ecdh_example_LDFLAGS = -static +if BUILD_WINDOWS +ecdh_example_LDFLAGS += -lbcrypt +endif +TESTS += ecdh_example +endif +if ENABLE_MODULE_SCHNORRSIG +noinst_PROGRAMS += schnorr_example +schnorr_example_SOURCES = examples/schnorr.c +schnorr_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC +schnorr_example_LDADD = libsecp256k1.la +schnorr_example_LDFLAGS = -static +if BUILD_WINDOWS +schnorr_example_LDFLAGS += -lbcrypt +endif +TESTS += schnorr_example +endif +if ENABLE_MODULE_ELLSWIFT +noinst_PROGRAMS += ellswift_example +ellswift_example_SOURCES = examples/ellswift.c +ellswift_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC +ellswift_example_LDADD = libsecp256k1.la +ellswift_example_LDFLAGS = -static +if BUILD_WINDOWS +ellswift_example_LDFLAGS += -lbcrypt +endif +TESTS += ellswift_example +endif +if ENABLE_MODULE_MUSIG +noinst_PROGRAMS += musig_example +musig_example_SOURCES = examples/musig.c +musig_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC +musig_example_LDADD = libsecp256k1.la +musig_example_LDFLAGS = -static +if BUILD_WINDOWS +musig_example_LDFLAGS += -lbcrypt +endif +TESTS += musig_example endif endif -if USE_ECMULT_STATIC_PRECOMPUTATION -CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) -CFLAGS_FOR_BUILD += -Wall -Wextra -Wno-unused-function +### Precomputed tables +EXTRA_PROGRAMS = precompute_ecmult precompute_ecmult_gen +CLEANFILES = $(EXTRA_PROGRAMS) -gen_context_OBJECTS = gen_context.o -gen_context_BIN = gen_context$(BUILD_EXEEXT) -gen_%.o: src/gen_%.c - $(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@ +precompute_ecmult_SOURCES = src/precompute_ecmult.c +precompute_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY +precompute_ecmult_LDADD = $(COMMON_LIB) -$(gen_context_BIN): $(gen_context_OBJECTS) - $(CC_FOR_BUILD) $^ -o $@ +precompute_ecmult_gen_SOURCES = src/precompute_ecmult_gen.c +precompute_ecmult_gen_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY +precompute_ecmult_gen_LDADD = $(COMMON_LIB) -$(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h -$(tests_OBJECTS): src/ecmult_static_context.h -$(bench_internal_OBJECTS): src/ecmult_static_context.h +# See Automake manual, Section "Errors with distclean". +# We don't list any dependencies for the prebuilt files here because +# otherwise make's decision whether to rebuild them (even in the first +# build by a normal user) depends on mtimes, and thus is very fragile. +# This means that rebuilds of the prebuilt files always need to be +# forced by deleting them. +src/precomputed_ecmult.c: + $(MAKE) $(AM_MAKEFLAGS) precompute_ecmult$(EXEEXT) + ./precompute_ecmult$(EXEEXT) +src/precomputed_ecmult_gen.c: + $(MAKE) $(AM_MAKEFLAGS) precompute_ecmult_gen$(EXEEXT) + ./precompute_ecmult_gen$(EXEEXT) -src/ecmult_static_context.h: $(gen_context_BIN) - ./$(gen_context_BIN) +PRECOMP = src/precomputed_ecmult_gen.c src/precomputed_ecmult.c +precomp: $(PRECOMP) -CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h $(JAVAROOT)/$(JAVAORG)/*.class .stamp-java -endif +# Ensure the prebuilt files will be build first (only if they don't exist, +# e.g., after `make maintainer-clean`). +BUILT_SOURCES = $(PRECOMP) -EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h $(JAVA_FILES) +.PHONY: clean-precomp +clean-precomp: + rm -f $(PRECOMP) +maintainer-clean-local: clean-precomp + +### Pregenerated test vectors +### (see the comments in the previous section for detailed rationale) +TESTVECTORS = src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h + +src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h: + mkdir -p $(@D) + python3 $(top_srcdir)/tools/tests_wycheproof_generate.py $(top_srcdir)/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json > $@ + +testvectors: $(TESTVECTORS) + +BUILT_SOURCES += $(TESTVECTORS) + +.PHONY: clean-testvectors +clean-testvectors: + rm -f $(TESTVECTORS) +maintainer-clean-local: clean-testvectors + +### Additional files to distribute +EXTRA_DIST = autogen.sh CHANGELOG.md SECURITY.md +EXTRA_DIST += doc/release-process.md doc/safegcd_implementation.md +EXTRA_DIST += doc/ellswift.md doc/musig.md +EXTRA_DIST += examples/EXAMPLES_COPYING +EXTRA_DIST += sage/gen_exhaustive_groups.sage +EXTRA_DIST += sage/gen_split_lambda_constants.sage +EXTRA_DIST += sage/group_prover.sage +EXTRA_DIST += sage/prove_group_implementations.sage +EXTRA_DIST += sage/secp256k1_params.sage +EXTRA_DIST += sage/weierstrass_prover.sage +EXTRA_DIST += src/wycheproof/WYCHEPROOF_COPYING +EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json +EXTRA_DIST += tools/tests_wycheproof_generate.py if ENABLE_MODULE_ECDH include src/modules/ecdh/Makefile.am.include @@ -175,3 +284,19 @@ endif if ENABLE_MODULE_RECOVERY include src/modules/recovery/Makefile.am.include endif + +if ENABLE_MODULE_EXTRAKEYS +include src/modules/extrakeys/Makefile.am.include +endif + +if ENABLE_MODULE_SCHNORRSIG +include src/modules/schnorrsig/Makefile.am.include +endif + +if ENABLE_MODULE_MUSIG +include src/modules/musig/Makefile.am.include +endif + +if ENABLE_MODULE_ELLSWIFT +include src/modules/ellswift/Makefile.am.include +endif diff --git a/crypto/secp256k1/libsecp256k1/README.md b/crypto/secp256k1/libsecp256k1/README.md index 8cd344ea81..f7a59b2b96 100644 --- a/crypto/secp256k1/libsecp256k1/README.md +++ b/crypto/secp256k1/libsecp256k1/README.md @@ -1,19 +1,27 @@ libsecp256k1 ============ -[![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1) +![Dependencies: None](https://img.shields.io/badge/dependencies-none-success) +[![irc.libera.chat #secp256k1](https://img.shields.io/badge/irc.libera.chat-%23secp256k1-success)](https://web.libera.chat/#secp256k1) -Optimized C library for EC operations on curve secp256k1. +High-performance high-assurance C library for digital signatures and other cryptographic primitives on the secp256k1 elliptic curve. -This library is a work in progress and is being used to research best practices. Use at your own risk. +This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose. Features: * secp256k1 ECDSA signing/verification and key generation. -* Adding/multiplying private/public keys. -* Serialization/parsing of private keys, public keys, signatures. -* Constant time, constant memory access signing and pubkey generation. -* Derandomized DSA (via RFC6979 or with a caller provided function.) +* Additive and multiplicative tweaking of secret/public keys. +* Serialization/parsing of secret keys, public keys, signatures. +* Constant time, constant memory access signing and public key generation. +* Derandomized ECDSA (via RFC6979 or with a caller provided function.) * Very efficient implementation. +* Suitable for embedded systems. +* No runtime dependencies. +* Optional module for public key recovery. +* Optional module for ECDH key exchange. +* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). +* Optional module for ElligatorSwift key exchange according to [BIP-324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki). +* Optional module for MuSig2 Schnorr multi-signatures according to [BIP-327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). Implementation details ---------------------- @@ -23,16 +31,18 @@ Implementation details * Extensive testing infrastructure. * Structured to facilitate review and analysis. * Intended to be portable to any system with a C89 compiler and uint64_t support. + * No use of floating types. * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") * Field operations * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). - * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys). - * Using 10 26-bit limbs. - * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman). + * Using 5 52-bit limbs + * Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan). + * This is an experimental feature that has not received enough scrutiny to satisfy the standard of quality of this library but is made available for testing and review by the community. * Scalar operations * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. * Using 4 64-bit limbs (relying on __int128 support in the compiler). * Using 8 32-bit limbs. +* Modular inverses (both field elements and scalars) based on [safegcd](https://gcd.cr.yp.to/index.html) with some modifications, and a variable-time variant (by Peter Dettman). * Group operations * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). * Use addition between points in Jacobian and affine coordinates where possible. @@ -42,20 +52,126 @@ Implementation details * Use wNAF notation for point multiplicands. * Use a much larger window for multiples of G, using precomputed multiples. * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. - * Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. + * Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. * Point multiplication for signing * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. - * Access the table with branch-free conditional moves so memory access is uniform. - * No data-dependent branches - * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally. + * Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains) + * Access the table with branch-free conditional moves so memory access is uniform. + * No data-dependent branches + * Optional runtime blinding which attempts to frustrate differential power analysis. + * The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally. -Build steps +Obtaining and verifying +----------------------- + +The git tag for each release (e.g. `v0.6.0`) is GPG-signed by one of the maintainers. +For a fully verified build of this project, it is recommended to obtain this repository +via git, obtain the GPG keys of the signing maintainer(s), and then verify the release +tag's signature using git. + +This can be done with the following steps: + +1. Obtain the GPG keys listed in [SECURITY.md](./SECURITY.md). +2. If possible, cross-reference these key IDs with another source controlled by its owner (e.g. + social media, personal website). This is to mitigate the unlikely case that incorrect + content is being presented by this repository. +3. Clone the repository: + ``` + git clone https://github.com/bitcoin-core/secp256k1 + ``` +4. Check out the latest release tag, e.g. + ``` + git checkout v0.6.0 + ``` +5. Use git to verify the GPG signature: + ``` + % git tag -v v0.6.0 | grep -C 3 'Good signature' + + gpg: Signature made Mon 04 Nov 2024 12:14:44 PM EST + gpg: using RSA key 4BBB845A6F5A65A69DFAEC234861DBF262123605 + gpg: Good signature from "Jonas Nick " [unknown] + gpg: aka "Jonas Nick " [unknown] + gpg: WARNING: This key is not certified with a trusted signature! + gpg: There is no indication that the signature belongs to the owner. + Primary key fingerprint: 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366 + Subkey fingerprint: 4BBB 845A 6F5A 65A6 9DFA EC23 4861 DBF2 6212 3605 + ``` + +Building with Autotools +----------------------- + + $ ./autogen.sh # Generate a ./configure script + $ ./configure # Generate a build system + $ make # Run the actual build process + $ make check # Run the test suite + $ sudo make install # Install the library into the system (optional) + +To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags. + +Building with CMake (experimental) +---------------------------------- + +To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree. + +### Building on POSIX systems + + $ cmake -B build # Generate a build system in subdirectory "build" + $ cmake --build build # Run the actual build process + $ ctest --test-dir build # Run the test suite + $ sudo cmake --install build # Install the library into the system (optional) + +To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake -B build -LH` or `ccmake -B build` to see the full list of available flags. + +### Cross compiling + +To alleviate issues with cross compiling, preconfigured toolchain files are available in the `cmake` directory. +For example, to cross compile for Windows: + + $ cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/x86_64-w64-mingw32.toolchain.cmake + +To cross compile for Android with [NDK](https://developer.android.com/ndk/guides/cmake) (using NDK's toolchain file, and assuming the `ANDROID_NDK_ROOT` environment variable has been set): + + $ cmake -B build -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28 + +### Building on Windows + +To build on Windows with Visual Studio, a proper [generator](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) must be specified for a new build tree. + +The following example assumes using of Visual Studio 2022 and CMake v3.21+. + +In "Developer Command Prompt for VS 2022": + + >cmake -G "Visual Studio 17 2022" -A x64 -B build + >cmake --build build --config RelWithDebInfo + +Usage examples ----------- +Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`. + * [ECDSA example](examples/ecdsa.c) + * [Schnorr signatures example](examples/schnorr.c) + * [Deriving a shared secret (ECDH) example](examples/ecdh.c) + * [ElligatorSwift key exchange example](examples/ellswift.c) -libsecp256k1 is built using autotools: +To compile the Schnorr signature and ECDH examples, you also need to configure with `--enable-module-schnorrsig` and `--enable-module-ecdh`. - $ ./autogen.sh - $ ./configure - $ make - $ ./tests - $ sudo make install # optional +Benchmark +------------ +If configured with `--enable-benchmark` (which is the default), binaries for benchmarking the libsecp256k1 functions will be present in the root directory after the build. + +To print the benchmark result to the command line: + + $ ./bench_name + +To create a CSV file for the benchmark result : + + $ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv + +Reporting a vulnerability +------------ + +See [SECURITY.md](SECURITY.md) + +Contributing to libsecp256k1 +------------ + +See [CONTRIBUTING.md](CONTRIBUTING.md) diff --git a/crypto/secp256k1/libsecp256k1/SECURITY.md b/crypto/secp256k1/libsecp256k1/SECURITY.md new file mode 100644 index 0000000000..b515cc1c8e --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +## Reporting a Vulnerability + +To report security issues send an email to secp256k1-security@bitcoincore.org (not for support). + +The following keys may be used to communicate sensitive information to developers: + +| Name | Fingerprint | +|------|-------------| +| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 | +| Jonas Nick | 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366 | +| Tim Ruffing | 09E0 3F87 1092 E40E 106E 902B 33BC 86AB 80FF 5516 | + +You can import a key by running the following command with that individual’s fingerprint: `gpg --keyserver hkps://keys.openpgp.org --recv-keys ""` Ensure that you put quotes around fingerprints containing spaces. diff --git a/crypto/secp256k1/libsecp256k1/TODO b/crypto/secp256k1/libsecp256k1/TODO deleted file mode 100644 index a300e1c5eb..0000000000 --- a/crypto/secp256k1/libsecp256k1/TODO +++ /dev/null @@ -1,3 +0,0 @@ -* Unit tests for fieldelem/groupelem, including ones intended to - trigger fieldelem's boundary cases. -* Complete constant-time operations for signing/keygen diff --git a/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_jni_include_dir.m4 b/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_jni_include_dir.m4 deleted file mode 100644 index 1fc3627614..0000000000 --- a/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_jni_include_dir.m4 +++ /dev/null @@ -1,140 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_JNI_INCLUDE_DIR -# -# DESCRIPTION -# -# AX_JNI_INCLUDE_DIR finds include directories needed for compiling -# programs using the JNI interface. -# -# JNI include directories are usually in the Java distribution. This is -# deduced from the value of $JAVA_HOME, $JAVAC, or the path to "javac", in -# that order. When this macro completes, a list of directories is left in -# the variable JNI_INCLUDE_DIRS. -# -# Example usage follows: -# -# AX_JNI_INCLUDE_DIR -# -# for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS -# do -# CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" -# done -# -# If you want to force a specific compiler: -# -# - at the configure.in level, set JAVAC=yourcompiler before calling -# AX_JNI_INCLUDE_DIR -# -# - at the configure level, setenv JAVAC -# -# Note: This macro can work with the autoconf M4 macros for Java programs. -# This particular macro is not part of the original set of macros. -# -# LICENSE -# -# Copyright (c) 2008 Don Anderson -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 10 - -AU_ALIAS([AC_JNI_INCLUDE_DIR], [AX_JNI_INCLUDE_DIR]) -AC_DEFUN([AX_JNI_INCLUDE_DIR],[ - -JNI_INCLUDE_DIRS="" - -if test "x$JAVA_HOME" != x; then - _JTOPDIR="$JAVA_HOME" -else - if test "x$JAVAC" = x; then - JAVAC=javac - fi - AC_PATH_PROG([_ACJNI_JAVAC], [$JAVAC], [no]) - if test "x$_ACJNI_JAVAC" = xno; then - AC_MSG_WARN([cannot find JDK; try setting \$JAVAC or \$JAVA_HOME]) - fi - _ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC") - _JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'` -fi - -case "$host_os" in - darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` - _JINC="$_JTOPDIR/Headers";; - *) _JINC="$_JTOPDIR/include";; -esac -_AS_ECHO_LOG([_JTOPDIR=$_JTOPDIR]) -_AS_ECHO_LOG([_JINC=$_JINC]) - -# On Mac OS X 10.6.4, jni.h is a symlink: -# /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/jni.h -# -> ../../CurrentJDK/Headers/jni.h. - -AC_CACHE_CHECK(jni headers, ac_cv_jni_header_path, -[ -if test -f "$_JINC/jni.h"; then - ac_cv_jni_header_path="$_JINC" - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" -else - _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` - if test -f "$_JTOPDIR/include/jni.h"; then - ac_cv_jni_header_path="$_JTOPDIR/include" - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" - else - ac_cv_jni_header_path=none - fi -fi -]) - - - -# get the likely subdirectories for system specific java includes -case "$host_os" in -bsdi*) _JNI_INC_SUBDIRS="bsdos";; -darwin*) _JNI_INC_SUBDIRS="darwin";; -freebsd*) _JNI_INC_SUBDIRS="freebsd";; -linux*) _JNI_INC_SUBDIRS="linux genunix";; -osf*) _JNI_INC_SUBDIRS="alpha";; -solaris*) _JNI_INC_SUBDIRS="solaris";; -mingw*) _JNI_INC_SUBDIRS="win32";; -cygwin*) _JNI_INC_SUBDIRS="win32";; -*) _JNI_INC_SUBDIRS="genunix";; -esac - -if test "x$ac_cv_jni_header_path" != "xnone"; then - # add any subdirectories that are present - for JINCSUBDIR in $_JNI_INC_SUBDIRS - do - if test -d "$_JTOPDIR/include/$JINCSUBDIR"; then - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$JINCSUBDIR" - fi - done -fi -]) - -# _ACJNI_FOLLOW_SYMLINKS -# Follows symbolic links on , -# finally setting variable _ACJNI_FOLLOWED -# ---------------------------------------- -AC_DEFUN([_ACJNI_FOLLOW_SYMLINKS],[ -# find the include directory relative to the javac executable -_cur="$1" -while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do - AC_MSG_CHECKING([symlink for $_cur]) - _slink=`ls -ld "$_cur" | sed 's/.* -> //'` - case "$_slink" in - /*) _cur="$_slink";; - # 'X' avoids triggering unwanted echo options. - *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";; - esac - AC_MSG_RESULT([$_cur]) -done -_ACJNI_FOLLOWED="$_cur" -])# _ACJNI diff --git a/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_prog_cc_for_build.m4 b/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_prog_cc_for_build.m4 deleted file mode 100644 index 77fd346a79..0000000000 --- a/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_prog_cc_for_build.m4 +++ /dev/null @@ -1,125 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_PROG_CC_FOR_BUILD -# -# DESCRIPTION -# -# This macro searches for a C compiler that generates native executables, -# that is a C compiler that surely is not a cross-compiler. This can be -# useful if you have to generate source code at compile-time like for -# example GCC does. -# -# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything -# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). -# The value of these variables can be overridden by the user by specifying -# a compiler with an environment variable (like you do for standard CC). -# -# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object -# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if -# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are -# substituted in the Makefile. -# -# LICENSE -# -# Copyright (c) 2008 Paolo Bonzini -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 8 - -AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) -AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_CPP])dnl -AC_REQUIRE([AC_EXEEXT])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl - -dnl Use the standard macros, but make them use other variable names -dnl -pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl -pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl -pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl -pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl -pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl -pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl -pushdef([ac_cv_objext], ac_cv_build_objext)dnl -pushdef([ac_exeext], ac_build_exeext)dnl -pushdef([ac_objext], ac_build_objext)dnl -pushdef([CC], CC_FOR_BUILD)dnl -pushdef([CPP], CPP_FOR_BUILD)dnl -pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl -pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl -pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl -pushdef([host], build)dnl -pushdef([host_alias], build_alias)dnl -pushdef([host_cpu], build_cpu)dnl -pushdef([host_vendor], build_vendor)dnl -pushdef([host_os], build_os)dnl -pushdef([ac_cv_host], ac_cv_build)dnl -pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl -pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl -pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl -pushdef([ac_cv_host_os], ac_cv_build_os)dnl -pushdef([ac_cpp], ac_build_cpp)dnl -pushdef([ac_compile], ac_build_compile)dnl -pushdef([ac_link], ac_build_link)dnl - -save_cross_compiling=$cross_compiling -save_ac_tool_prefix=$ac_tool_prefix -cross_compiling=no -ac_tool_prefix= - -AC_PROG_CC -AC_PROG_CPP -AC_EXEEXT - -ac_tool_prefix=$save_ac_tool_prefix -cross_compiling=$save_cross_compiling - -dnl Restore the old definitions -dnl -popdef([ac_link])dnl -popdef([ac_compile])dnl -popdef([ac_cpp])dnl -popdef([ac_cv_host_os])dnl -popdef([ac_cv_host_vendor])dnl -popdef([ac_cv_host_cpu])dnl -popdef([ac_cv_host_alias])dnl -popdef([ac_cv_host])dnl -popdef([host_os])dnl -popdef([host_vendor])dnl -popdef([host_cpu])dnl -popdef([host_alias])dnl -popdef([host])dnl -popdef([LDFLAGS])dnl -popdef([CPPFLAGS])dnl -popdef([CFLAGS])dnl -popdef([CPP])dnl -popdef([CC])dnl -popdef([ac_objext])dnl -popdef([ac_exeext])dnl -popdef([ac_cv_objext])dnl -popdef([ac_cv_exeext])dnl -popdef([ac_cv_prog_cc_g])dnl -popdef([ac_cv_prog_cc_cross])dnl -popdef([ac_cv_prog_cc_works])dnl -popdef([ac_cv_prog_gcc])dnl -popdef([ac_cv_prog_CPP])dnl - -dnl Finally, set Makefile variables -dnl -BUILD_EXEEXT=$ac_build_exeext -BUILD_OBJEXT=$ac_build_objext -AC_SUBST(BUILD_EXEEXT)dnl -AC_SUBST(BUILD_OBJEXT)dnl -AC_SUBST([CFLAGS_FOR_BUILD])dnl -AC_SUBST([CPPFLAGS_FOR_BUILD])dnl -AC_SUBST([LDFLAGS_FOR_BUILD])dnl -]) diff --git a/crypto/secp256k1/libsecp256k1/build-aux/m4/bitcoin_secp.m4 b/crypto/secp256k1/libsecp256k1/build-aux/m4/bitcoin_secp.m4 index b74acb8c13..048267fa6e 100644 --- a/crypto/secp256k1/libsecp256k1/build-aux/m4/bitcoin_secp.m4 +++ b/crypto/secp256k1/libsecp256k1/build-aux/m4/bitcoin_secp.m4 @@ -1,69 +1,91 @@ -dnl libsecp25k1 helper checks -AC_DEFUN([SECP_INT128_CHECK],[ -has_int128=$ac_cv_type___int128 -]) - dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell. -AC_DEFUN([SECP_64BIT_ASM_CHECK],[ +AC_DEFUN([SECP_X86_64_ASM_CHECK],[ AC_MSG_CHECKING(for x86_64 assembly availability) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ uint64_t a = 11, tmp; __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); - ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) -AC_MSG_RESULT([$has_64bit_asm]) + ]])], [has_x86_64_asm=yes], [has_x86_64_asm=no]) +AC_MSG_RESULT([$has_x86_64_asm]) ]) -dnl -AC_DEFUN([SECP_OPENSSL_CHECK],[ - has_libcrypto=no - m4_ifdef([PKG_CHECK_MODULES],[ - PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no]) - if test x"$has_libcrypto" = x"yes"; then - TEMP_LIBS="$LIBS" - LIBS="$LIBS $CRYPTO_LIBS" - AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no]) - LIBS="$TEMP_LIBS" - fi - ]) - if test x$has_libcrypto = xno; then - AC_CHECK_HEADER(openssl/crypto.h,[ - AC_CHECK_LIB(crypto, main,[ - has_libcrypto=yes - CRYPTO_LIBS=-lcrypto - AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed]) - ]) - ]) - LIBS= - fi -if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then - AC_MSG_CHECKING(for EC functions in libcrypto) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - #include ]],[[ - EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp256k1); - ECDSA_sign(0, NULL, 0, NULL, NULL, eckey); - ECDSA_verify(0, NULL, 0, NULL, 0, eckey); - EC_KEY_free(eckey); - ECDSA_SIG *sig_openssl; - sig_openssl = ECDSA_SIG_new(); - (void)sig_openssl->r; - ECDSA_SIG_free(sig_openssl); - ]])],[has_openssl_ec=yes],[has_openssl_ec=no]) - AC_MSG_RESULT([$has_openssl_ec]) -fi +AC_DEFUN([SECP_ARM32_ASM_CHECK], [ + AC_MSG_CHECKING(for ARM32 assembly availability) + SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS="$CFLAGS" + CFLAGS="-x assembler" + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + .syntax unified + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .text + .global main + main: + ldr r0, =0x002A + mov r7, #1 + swi 0 + ]])], [has_arm32_asm=yes], [has_arm32_asm=no]) + AC_MSG_RESULT([$has_arm32_asm]) + CFLAGS="$SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS" ]) -dnl -AC_DEFUN([SECP_GMP_CHECK],[ -if test x"$has_gmp" != x"yes"; then +AC_DEFUN([SECP_VALGRIND_CHECK],[ +AC_MSG_CHECKING([for valgrind support]) +if test x"$has_valgrind" != x"yes"; then CPPFLAGS_TEMP="$CPPFLAGS" - CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS" - LIBS_TEMP="$LIBS" - LIBS="$GMP_LIBS $LIBS" - AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="$GMP_LIBS -lgmp"; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])]) + CPPFLAGS="$VALGRIND_CPPFLAGS $CPPFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], [[ + #if defined(NVALGRIND) + # error "Valgrind does not support this platform." + #endif + ]])], [has_valgrind=yes]) CPPFLAGS="$CPPFLAGS_TEMP" - LIBS="$LIBS_TEMP" fi +AC_MSG_RESULT($has_valgrind) +]) + +AC_DEFUN([SECP_MSAN_CHECK], [ +AC_MSG_CHECKING(whether MemorySanitizer is enabled) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #if defined(__has_feature) + # if __has_feature(memory_sanitizer) + /* MemorySanitizer is enabled. */ + # elif + # error "MemorySanitizer is disabled." + # endif + #else + # error "__has_feature is not defined." + #endif + ]])], [msan_enabled=yes], [msan_enabled=no]) +AC_MSG_RESULT([$msan_enabled]) +]) + +dnl SECP_TRY_APPEND_CFLAGS(flags, VAR) +dnl Append flags to VAR if CC accepts them. +AC_DEFUN([SECP_TRY_APPEND_CFLAGS], [ + AC_MSG_CHECKING([if ${CC} supports $1]) + SECP_TRY_APPEND_CFLAGS_saved_CFLAGS="$CFLAGS" + CFLAGS="$1 $CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], [flag_works=yes], [flag_works=no]) + AC_MSG_RESULT($flag_works) + CFLAGS="$SECP_TRY_APPEND_CFLAGS_saved_CFLAGS" + if test x"$flag_works" = x"yes"; then + $2="$$2 $1" + fi + unset flag_works + AC_SUBST($2) +]) + +dnl SECP_SET_DEFAULT(VAR, default, default-dev-mode) +dnl Set VAR to default or default-dev-mode, depending on whether dev mode is enabled +AC_DEFUN([SECP_SET_DEFAULT], [ + if test "${enable_dev_mode+set}" != set; then + AC_MSG_ERROR([[Set enable_dev_mode before calling SECP_SET_DEFAULT]]) + fi + if test x"$enable_dev_mode" = x"yes"; then + $1="$3" + else + $1="$2" + fi ]) diff --git a/crypto/secp256k1/libsecp256k1/ci/ci.sh b/crypto/secp256k1/libsecp256k1/ci/ci.sh new file mode 100755 index 0000000000..3636deafa1 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/ci/ci.sh @@ -0,0 +1,149 @@ +#!/bin/sh + +set -eux + +export LC_ALL=C + +# Print commit and relevant CI environment to allow reproducing the job outside of CI. +git show --no-patch +print_environment() { + # Turn off -x because it messes up the output + set +x + # There are many ways to print variable names and their content. This one + # does not rely on bash. + for var in WERROR_CFLAGS MAKEFLAGS BUILD \ + ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \ + EXPERIMENTAL ECDH RECOVERY EXTRAKEYS MUSIG SCHNORRSIG ELLSWIFT \ + SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\ + EXAMPLES \ + HOST WRAPPER_CMD \ + CC CFLAGS CPPFLAGS AR NM \ + UBSAN_OPTIONS ASAN_OPTIONS LSAN_OPTIONS + do + eval "isset=\${$var+x}" + if [ -n "$isset" ]; then + eval "val=\${$var}" + # shellcheck disable=SC2154 + printf '%s="%s" ' "$var" "$val" + fi + done + echo "$0" + set -x +} +print_environment + +env >> test_env.log + +# If gcc is requested, assert that it's in fact gcc (and not some symlinked Apple clang). +case "${CC:-undefined}" in + *gcc*) + $CC -v 2>&1 | grep -q "gcc version" || exit 1; + ;; +esac + +if [ -n "${CC+x}" ]; then + # The MSVC compiler "cl" doesn't understand "-v" + $CC -v || true +fi +if [ "$WITH_VALGRIND" = "yes" ]; then + valgrind --version +fi +if [ -n "$WRAPPER_CMD" ]; then + $WRAPPER_CMD --version +fi + +# Workaround for https://bugs.kde.org/show_bug.cgi?id=452758 (fixed in valgrind 3.20.0). +case "${CC:-undefined}" in + clang*) + if [ "$CTIMETESTS" = "yes" ] && [ "$WITH_VALGRIND" = "yes" ] + then + export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4" + else + case "$WRAPPER_CMD" in + valgrind*) + export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4" + ;; + esac + fi + ;; +esac + +./autogen.sh + +./configure \ + --enable-experimental="$EXPERIMENTAL" \ + --with-test-override-wide-multiply="$WIDEMUL" --with-asm="$ASM" \ + --with-ecmult-window="$ECMULTWINDOW" \ + --with-ecmult-gen-kb="$ECMULTGENKB" \ + --enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \ + --enable-module-ellswift="$ELLSWIFT" \ + --enable-module-extrakeys="$EXTRAKEYS" \ + --enable-module-schnorrsig="$SCHNORRSIG" \ + --enable-module-musig="$MUSIG" \ + --enable-examples="$EXAMPLES" \ + --enable-ctime-tests="$CTIMETESTS" \ + --with-valgrind="$WITH_VALGRIND" \ + --host="$HOST" $EXTRAFLAGS + +# We have set "-j" in MAKEFLAGS. +build_exit_code=0 +make > make.log 2>&1 || build_exit_code=$? +cat make.log +if [ $build_exit_code -ne 0 ]; then + case "${CC:-undefined}" in + *snapshot*) + # Ignore internal compiler errors in gcc-snapshot and clang-snapshot + grep -e "internal compiler error:" -e "PLEASE submit a bug report" make.log + return $?; + ;; + *) + return 1; + ;; + esac +fi + +# Print information about binaries so that we can see that the architecture is correct +file *tests* || true +file bench* || true +file .libs/* || true + +# This tells `make check` to wrap test invocations. +export LOG_COMPILER="$WRAPPER_CMD" + +make "$BUILD" + +# Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool +EXEC='./libtool --mode=execute' +if [ -n "$WRAPPER_CMD" ] +then + EXEC="$EXEC $WRAPPER_CMD" +fi + +if [ "$BENCH" = "yes" ] +then + { + $EXEC ./bench_ecmult + $EXEC ./bench_internal + $EXEC ./bench + } >> bench.log 2>&1 +fi + +if [ "$CTIMETESTS" = "yes" ] +then + if [ "$WITH_VALGRIND" = "yes" ]; then + ./libtool --mode=execute valgrind --error-exitcode=42 ./ctime_tests > ctime_tests.log 2>&1 + else + $EXEC ./ctime_tests > ctime_tests.log 2>&1 + fi +fi + +# Rebuild precomputed files (if not cross-compiling). +if [ -z "$HOST" ] +then + make clean-precomp clean-testvectors + make precomp testvectors +fi + +# Check that no repo files have been modified by the build. +# (This fails for example if the precomp files need to be updated in the repo.) +git diff --exit-code diff --git a/crypto/secp256k1/libsecp256k1/ci/linux-debian.Dockerfile b/crypto/secp256k1/libsecp256k1/ci/linux-debian.Dockerfile new file mode 100644 index 0000000000..241bfa9719 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/ci/linux-debian.Dockerfile @@ -0,0 +1,79 @@ +FROM debian:stable-slim + +SHELL ["/bin/bash", "-c"] + +WORKDIR /root + +# A too high maximum number of file descriptors (with the default value +# inherited from the docker host) can cause issues with some of our tools: +# - sanitizers hanging: https://github.com/google/sanitizers/issues/1662 +# - valgrind crashing: https://stackoverflow.com/a/75293014 +# This is not be a problem on our CI hosts, but developers who run the image +# on their machines may run into this (e.g., on Arch Linux), so warn them. +# (Note that .bashrc is only executed in interactive bash shells.) +RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> /root/.bashrc + +RUN dpkg --add-architecture i386 && \ + dpkg --add-architecture s390x && \ + dpkg --add-architecture armhf && \ + dpkg --add-architecture arm64 && \ + dpkg --add-architecture ppc64el + +# dkpg-dev: to make pkg-config work in cross-builds +# llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces +RUN apt-get update && apt-get install --no-install-recommends -y \ + git ca-certificates \ + make automake libtool pkg-config dpkg-dev valgrind qemu-user \ + gcc clang llvm libclang-rt-dev libc6-dbg \ + g++ \ + gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan8:i386 \ + gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x \ + gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \ + gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \ + gcc-mingw-w64-x86-64-win32 wine64 wine \ + gcc-mingw-w64-i686-win32 wine32 \ + python3 && \ + if ! ( dpkg --print-architecture | grep --quiet "arm64" ) ; then \ + apt-get install --no-install-recommends -y \ + gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 ;\ + fi && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Build and install gcc snapshot +ARG GCC_SNAPSHOT_MAJOR=15 +RUN apt-get update && apt-get install --no-install-recommends -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \ + mkdir gcc && cd gcc && \ + wget --progress=dot:giga --https-only --recursive --accept '*.tar.xz' --level 1 --no-directories "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}" && \ + wget "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}/sha512.sum" && \ + sha512sum --check --ignore-missing sha512.sum && \ + # We should have downloaded exactly one tar.xz file + ls && \ + [ $(ls *.tar.xz | wc -l) -eq "1" ] && \ + tar xf *.tar.xz && \ + mkdir gcc-build && cd gcc-build && \ + ../*/configure --prefix=/opt/gcc-snapshot --enable-languages=c --disable-bootstrap --disable-multilib --without-isl && \ + make -j $(nproc) && \ + make install && \ + cd ../.. && rm -rf gcc && \ + ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot && \ + apt-get autoremove -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Install clang snapshot, see https://apt.llvm.org/ +RUN \ + # Setup GPG keys of LLVM repository + apt-get update && apt-get install --no-install-recommends -y wget && \ + wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \ + # Add repository for this Debian release + . /etc/os-release && echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME} main" >> /etc/apt/sources.list && \ + apt-get update && \ + # Determine the version number of the LLVM development branch + LLVM_VERSION=$(apt-cache search --names-only '^clang-[0-9]+$' | sort -V | tail -1 | cut -f1 -d" " | cut -f2 -d"-" ) && \ + # Install + apt-get install --no-install-recommends -y "clang-${LLVM_VERSION}" && \ + # Create symlink + ln -s "/usr/bin/clang-${LLVM_VERSION}" /usr/bin/clang-snapshot && \ + # Clean up + apt-get autoremove -y wget && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + diff --git a/crypto/secp256k1/libsecp256k1/cmake/CheckArm32Assembly.cmake b/crypto/secp256k1/libsecp256k1/cmake/CheckArm32Assembly.cmake new file mode 100644 index 0000000000..baeeff0292 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/CheckArm32Assembly.cmake @@ -0,0 +1,6 @@ +function(check_arm32_assembly) + try_compile(HAVE_ARM32_ASM + ${PROJECT_BINARY_DIR}/check_arm32_assembly + SOURCES ${PROJECT_SOURCE_DIR}/cmake/source_arm32.s + ) +endfunction() diff --git a/crypto/secp256k1/libsecp256k1/cmake/CheckMemorySanitizer.cmake b/crypto/secp256k1/libsecp256k1/cmake/CheckMemorySanitizer.cmake new file mode 100644 index 0000000000..d9ef681e65 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/CheckMemorySanitizer.cmake @@ -0,0 +1,18 @@ +include_guard(GLOBAL) +include(CheckCSourceCompiles) + +function(check_memory_sanitizer output) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + check_c_source_compiles(" + #if defined(__has_feature) + # if __has_feature(memory_sanitizer) + /* MemorySanitizer is enabled. */ + # elif + # error \"MemorySanitizer is disabled.\" + # endif + #else + # error \"__has_feature is not defined.\" + #endif + " HAVE_MSAN) + set(${output} ${HAVE_MSAN} PARENT_SCOPE) +endfunction() diff --git a/crypto/secp256k1/libsecp256k1/cmake/CheckStringOptionValue.cmake b/crypto/secp256k1/libsecp256k1/cmake/CheckStringOptionValue.cmake new file mode 100644 index 0000000000..5a4d939b9e --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/CheckStringOptionValue.cmake @@ -0,0 +1,10 @@ +function(check_string_option_value option) + get_property(expected_values CACHE ${option} PROPERTY STRINGS) + if(expected_values) + if(${option} IN_LIST expected_values) + return() + endif() + message(FATAL_ERROR "${option} value is \"${${option}}\", but must be one of ${expected_values}.") + endif() + message(AUTHOR_WARNING "The STRINGS property must be set before invoking `check_string_option_value' function.") +endfunction() diff --git a/crypto/secp256k1/libsecp256k1/cmake/CheckX86_64Assembly.cmake b/crypto/secp256k1/libsecp256k1/cmake/CheckX86_64Assembly.cmake new file mode 100644 index 0000000000..ae82cd476e --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/CheckX86_64Assembly.cmake @@ -0,0 +1,14 @@ +include(CheckCSourceCompiles) + +function(check_x86_64_assembly) + check_c_source_compiles(" + #include + + int main() + { + uint64_t a = 11, tmp; + __asm__ __volatile__(\"movq $0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\"); + } + " HAVE_X86_64_ASM) + set(HAVE_X86_64_ASM ${HAVE_X86_64_ASM} PARENT_SCOPE) +endfunction() diff --git a/crypto/secp256k1/libsecp256k1/cmake/FindValgrind.cmake b/crypto/secp256k1/libsecp256k1/cmake/FindValgrind.cmake new file mode 100644 index 0000000000..3af5e691e4 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/FindValgrind.cmake @@ -0,0 +1,41 @@ +if(CMAKE_HOST_APPLE) + find_program(BREW_COMMAND brew) + execute_process( + COMMAND ${BREW_COMMAND} --prefix valgrind + OUTPUT_VARIABLE valgrind_brew_prefix + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() + +set(hints_paths) +if(valgrind_brew_prefix) + set(hints_paths ${valgrind_brew_prefix}/include) +endif() + +find_path(Valgrind_INCLUDE_DIR + NAMES valgrind/memcheck.h + HINTS ${hints_paths} +) + +if(Valgrind_INCLUDE_DIR) + include(CheckCSourceCompiles) + set(CMAKE_REQUIRED_INCLUDES ${Valgrind_INCLUDE_DIR}) + check_c_source_compiles(" + #include + #if defined(NVALGRIND) + # error \"Valgrind does not support this platform.\" + #endif + + int main() {} + " Valgrind_WORKS) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Valgrind + REQUIRED_VARS Valgrind_INCLUDE_DIR Valgrind_WORKS +) + +mark_as_advanced( + Valgrind_INCLUDE_DIR +) diff --git a/crypto/secp256k1/libsecp256k1/cmake/GeneratePkgConfigFile.cmake b/crypto/secp256k1/libsecp256k1/cmake/GeneratePkgConfigFile.cmake new file mode 100644 index 0000000000..9c1d7f1ddd --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/GeneratePkgConfigFile.cmake @@ -0,0 +1,8 @@ +function(generate_pkg_config_file in_file) + set(prefix ${CMAKE_INSTALL_PREFIX}) + set(exec_prefix \${prefix}) + set(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR}) + set(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR}) + set(PACKAGE_VERSION ${PROJECT_VERSION}) + configure_file(${in_file} ${PROJECT_NAME}.pc @ONLY) +endfunction() diff --git a/crypto/secp256k1/libsecp256k1/cmake/TryAppendCFlags.cmake b/crypto/secp256k1/libsecp256k1/cmake/TryAppendCFlags.cmake new file mode 100644 index 0000000000..1d81a9317a --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/TryAppendCFlags.cmake @@ -0,0 +1,24 @@ +include(CheckCCompilerFlag) + +function(secp256k1_check_c_flags_internal flags output) + string(MAKE_C_IDENTIFIER "${flags}" result) + string(TOUPPER "${result}" result) + set(result "C_SUPPORTS_${result}") + if(NOT MSVC) + set(CMAKE_REQUIRED_FLAGS "-Werror") + endif() + + # This avoids running a linker. + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + check_c_compiler_flag("${flags}" ${result}) + + set(${output} ${${result}} PARENT_SCOPE) +endfunction() + +# Append flags to the COMPILE_OPTIONS directory property if CC accepts them. +macro(try_append_c_flags) + secp256k1_check_c_flags_internal("${ARGV}" result) + if(result) + add_compile_options(${ARGV}) + endif() +endmacro() diff --git a/crypto/secp256k1/libsecp256k1/cmake/arm-linux-gnueabihf.toolchain.cmake b/crypto/secp256k1/libsecp256k1/cmake/arm-linux-gnueabihf.toolchain.cmake new file mode 100644 index 0000000000..0d91912b6d --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/arm-linux-gnueabihf.toolchain.cmake @@ -0,0 +1,3 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) diff --git a/crypto/secp256k1/libsecp256k1/cmake/config.cmake.in b/crypto/secp256k1/libsecp256k1/cmake/config.cmake.in new file mode 100644 index 0000000000..46b180ab19 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/config.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake") + +check_required_components(@PROJECT_NAME@) diff --git a/crypto/secp256k1/libsecp256k1/cmake/source_arm32.s b/crypto/secp256k1/libsecp256k1/cmake/source_arm32.s new file mode 100644 index 0000000000..d3d9347057 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/source_arm32.s @@ -0,0 +1,9 @@ +.syntax unified +.eabi_attribute 24, 1 +.eabi_attribute 25, 1 +.text +.global main +main: + ldr r0, =0x002A + mov r7, #1 + swi 0 diff --git a/crypto/secp256k1/libsecp256k1/cmake/x86_64-w64-mingw32.toolchain.cmake b/crypto/secp256k1/libsecp256k1/cmake/x86_64-w64-mingw32.toolchain.cmake new file mode 100644 index 0000000000..96119b72d1 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/cmake/x86_64-w64-mingw32.toolchain.cmake @@ -0,0 +1,3 @@ +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR x86_64) +set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) diff --git a/crypto/secp256k1/libsecp256k1/configure.ac b/crypto/secp256k1/libsecp256k1/configure.ac index e5fcbcb4ed..c62a391d78 100644 --- a/crypto/secp256k1/libsecp256k1/configure.ac +++ b/crypto/secp256k1/libsecp256k1/configure.ac @@ -1,203 +1,290 @@ AC_PREREQ([2.60]) -AC_INIT([libsecp256k1],[0.1]) + +# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of +# the API. All changes in experimental modules are treated as +# backwards-compatible and therefore at most increase the minor version. +define(_PKG_VERSION_MAJOR, 0) +define(_PKG_VERSION_MINOR, 6) +define(_PKG_VERSION_PATCH, 1) +define(_PKG_VERSION_IS_RELEASE, false) + +# The library version is based on libtool versioning of the ABI. The set of +# rules for updating the version can be found here: +# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html +# All changes in experimental modules are treated as if they don't affect the +# interface and therefore only increase the revision. +define(_LIB_VERSION_CURRENT, 5) +define(_LIB_VERSION_REVISION, 1) +define(_LIB_VERSION_AGE, 0) + +AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_PATCH)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-dev]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1]) + AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) AC_CANONICAL_HOST -AH_TOP([#ifndef LIBSECP256K1_CONFIG_H]) -AH_TOP([#define LIBSECP256K1_CONFIG_H]) -AH_BOTTOM([#endif /*LIBSECP256K1_CONFIG_H*/]) -AM_INIT_AUTOMAKE([foreign subdir-objects]) -LT_INIT -dnl make the compilation flags quiet unless V=1 is used +# Require Automake 1.11.2 for AM_PROG_AR +AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects]) + +# Make the compilation flags quiet unless V=1 is used. m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -PKG_PROG_PKG_CONFIG - -AC_PATH_TOOL(AR, ar) -AC_PATH_TOOL(RANLIB, ranlib) -AC_PATH_TOOL(STRIP, strip) -AX_PROG_CC_FOR_BUILD - -if test "x$CFLAGS" = "x"; then - CFLAGS="-g" -fi - -AM_PROG_CC_C_O - -AC_PROG_CC_C89 -if test x"$ac_cv_prog_cc_c89" = x"no"; then - AC_MSG_ERROR([c89 compiler support required]) +if test "${CFLAGS+set}" = "set"; then + CFLAGS_overridden=yes +else + CFLAGS_overridden=no fi +AC_PROG_CC AM_PROG_AS +AM_PROG_AR + +# Clear some cache variables as a workaround for a bug that appears due to a bad +# interaction between AM_PROG_AR and LT_INIT when combining MSVC's archiver lib.exe. +# https://debbugs.gnu.org/cgi/bugreport.cgi?bug=54421 +AS_UNSET(ac_cv_prog_AR) +AS_UNSET(ac_cv_prog_ac_ct_AR) +LT_INIT([win32-dll]) + +build_windows=no case $host_os in *darwin*) if test x$cross_compiling != xyes; then - AC_PATH_PROG([BREW],brew,) - if test x$BREW != x; then - dnl These Homebrew packages may be keg-only, meaning that they won't be found - dnl in expected paths because they may conflict with system files. Ask - dnl Homebrew where each one is located, then adjust paths accordingly. - - openssl_prefix=`$BREW --prefix openssl 2>/dev/null` - gmp_prefix=`$BREW --prefix gmp 2>/dev/null` - if test x$openssl_prefix != x; then - PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" - export PKG_CONFIG_PATH - fi - if test x$gmp_prefix != x; then - GMP_CPPFLAGS="-I$gmp_prefix/include" - GMP_LIBS="-L$gmp_prefix/lib" + AC_CHECK_PROG([BREW], brew, brew) + if test x$BREW = xbrew; then + # These Homebrew packages may be keg-only, meaning that they won't be found + # in expected paths because they may conflict with system files. Ask + # Homebrew where each one is located, then adjust paths accordingly. + if $BREW list --versions valgrind >/dev/null; then + valgrind_prefix=$($BREW --prefix valgrind 2>/dev/null) + VALGRIND_CPPFLAGS="-I$valgrind_prefix/include" fi else - AC_PATH_PROG([PORT],port,) - dnl if homebrew isn't installed and macports is, add the macports default paths - dnl as a last resort. - if test x$PORT != x; then + AC_CHECK_PROG([PORT], port, port) + # If homebrew isn't installed and macports is, add the macports default paths + # as a last resort. + if test x$PORT = xport; then CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" LDFLAGS="$LDFLAGS -L/opt/local/lib" fi fi fi ;; + cygwin*|mingw*) + build_windows=yes + ;; esac -CFLAGS="$CFLAGS -W" +# Try if some desirable compiler flags are supported and append them to SECP_CFLAGS. +# +# These are our own flags, so we append them to our own SECP_CFLAGS variable (instead of CFLAGS) as +# recommended in the automake manual (Section "Flag Variables Ordering"). CFLAGS belongs to the user +# and we are not supposed to touch it. In the Makefile, we will need to ensure that SECP_CFLAGS +# is prepended to CFLAGS when invoking the compiler so that the user always has the last word (flag). +# +# Another advantage of not touching CFLAGS is that the contents of CFLAGS will be picked up by +# libtool for compiling helper executables. For example, when compiling for Windows, libtool will +# generate entire wrapper executables (instead of simple wrapper scripts as on Unix) to ensure +# proper operation of uninstalled programs linked by libtool against the uninstalled shared library. +# These executables are compiled from C source file for which our flags may not be appropriate, +# e.g., -std=c89 flag has lead to undesirable warnings in the past. +# +# TODO We should analogously not touch CPPFLAGS and LDFLAGS but currently there are no issues. +AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [ + # GCC and compatible (incl. clang) + if test "x$GCC" = "xyes"; then + # Try to append -Werror to CFLAGS temporarily. Otherwise checks for some unsupported + # flags will succeed. + # Note that failure to append -Werror does not necessarily mean that -Werror is not + # supported. The compiler may already be warning about something unrelated, for example + # about some path issue. If that is the case, -Werror cannot be used because all + # of those warnings would be turned into errors. + SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS="$CFLAGS" + SECP_TRY_APPEND_CFLAGS([-Werror], CFLAGS) -warn_CFLAGS="-std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings" -saved_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS $warn_CFLAGS" -AC_MSG_CHECKING([if ${CC} supports ${warn_CFLAGS}]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], - [ AC_MSG_RESULT([yes]) ], - [ AC_MSG_RESULT([no]) - CFLAGS="$saved_CFLAGS" - ]) + SECP_TRY_APPEND_CFLAGS([-std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef], $1) # GCC >= 3.0, -Wlong-long is implied by -pedantic. + SECP_TRY_APPEND_CFLAGS([-Wno-overlength-strings], $1) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic. + SECP_TRY_APPEND_CFLAGS([-Wall], $1) # GCC >= 2.95 and probably many other compilers + SECP_TRY_APPEND_CFLAGS([-Wno-unused-function], $1) # GCC >= 3.0, -Wunused-function is implied by -Wall. + SECP_TRY_APPEND_CFLAGS([-Wextra], $1) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions. + SECP_TRY_APPEND_CFLAGS([-Wcast-align], $1) # GCC >= 2.95 + SECP_TRY_APPEND_CFLAGS([-Wcast-align=strict], $1) # GCC >= 8.0 + SECP_TRY_APPEND_CFLAGS([-Wconditional-uninitialized], $1) # Clang >= 3.0 only + SECP_TRY_APPEND_CFLAGS([-Wreserved-identifier], $1) # Clang >= 13.0 only + SECP_TRY_APPEND_CFLAGS([-fvisibility=hidden], $1) # GCC >= 4.0 -saved_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -fvisibility=hidden" -AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], - [ AC_MSG_RESULT([yes]) ], - [ AC_MSG_RESULT([no]) - CFLAGS="$saved_CFLAGS" - ]) + CFLAGS="$SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS" + fi + + # MSVC + # Assume MSVC if we're building for Windows but not with GCC or compatible; + # libtool makes the same assumption internally. + # Note that "/opt" and "-opt" are equivalent for MSVC; we use "-opt" because "/opt" looks like a path. + if test x"$GCC" != x"yes" && test x"$build_windows" = x"yes"; then + SECP_TRY_APPEND_CFLAGS([-W3], $1) # Production quality warning level. + SECP_TRY_APPEND_CFLAGS([-wd4146], $1) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned". + SECP_TRY_APPEND_CFLAGS([-wd4244], $1) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data". + SECP_TRY_APPEND_CFLAGS([-wd4267], $1) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data". + # Eliminate deprecation warnings for the older, less secure functions. + CPPFLAGS="-D_CRT_SECURE_NO_WARNINGS $CPPFLAGS" + fi +]) +SECP_TRY_APPEND_DEFAULT_CFLAGS(SECP_CFLAGS) + +### +### Define config arguments +### + +# In dev mode, we enable all binaries and modules by default but individual options can still be overridden explicitly. +# Check for dev mode first because SECP_SET_DEFAULT needs enable_dev_mode set. +AC_ARG_ENABLE(dev_mode, [], [], + [enable_dev_mode=no]) AC_ARG_ENABLE(benchmark, - AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is no)]), - [use_benchmark=$enableval], - [use_benchmark=no]) + AS_HELP_STRING([--enable-benchmark],[compile benchmark [default=yes]]), [], + [SECP_SET_DEFAULT([enable_benchmark], [yes], [yes])]) AC_ARG_ENABLE(coverage, - AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis]), - [enable_coverage=$enableval], - [enable_coverage=no]) + AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis [default=no]]), [], + [SECP_SET_DEFAULT([enable_coverage], [no], [no])]) AC_ARG_ENABLE(tests, - AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]), - [use_tests=$enableval], - [use_tests=yes]) + AS_HELP_STRING([--enable-tests],[compile tests [default=yes]]), [], + [SECP_SET_DEFAULT([enable_tests], [yes], [yes])]) -AC_ARG_ENABLE(openssl_tests, - AS_HELP_STRING([--enable-openssl-tests],[enable OpenSSL tests, if OpenSSL is available (default is auto)]), - [enable_openssl_tests=$enableval], - [enable_openssl_tests=auto]) +AC_ARG_ENABLE(ctime_tests, + AS_HELP_STRING([--enable-ctime-tests],[compile constant-time tests [default=yes if valgrind enabled]]), [], + [SECP_SET_DEFAULT([enable_ctime_tests], [auto], [auto])]) AC_ARG_ENABLE(experimental, - AS_HELP_STRING([--enable-experimental],[allow experimental configure options (default is no)]), - [use_experimental=$enableval], - [use_experimental=no]) + AS_HELP_STRING([--enable-experimental],[allow experimental configure options [default=no]]), [], + [SECP_SET_DEFAULT([enable_experimental], [no], [yes])]) AC_ARG_ENABLE(exhaustive_tests, - AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests (default is yes)]), - [use_exhaustive_tests=$enableval], - [use_exhaustive_tests=yes]) + AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests [default=yes]]), [], + [SECP_SET_DEFAULT([enable_exhaustive_tests], [yes], [yes])]) -AC_ARG_ENABLE(endomorphism, - AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]), - [use_endomorphism=$enableval], - [use_endomorphism=no]) - -AC_ARG_ENABLE(ecmult_static_precomputation, - AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing (default is yes)]), - [use_ecmult_static_precomputation=$enableval], - [use_ecmult_static_precomputation=auto]) +AC_ARG_ENABLE(examples, + AS_HELP_STRING([--enable-examples],[compile the examples [default=no]]), [], + [SECP_SET_DEFAULT([enable_examples], [no], [yes])]) AC_ARG_ENABLE(module_ecdh, - AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (experimental)]), - [enable_module_ecdh=$enableval], - [enable_module_ecdh=no]) + AS_HELP_STRING([--enable-module-ecdh],[enable ECDH module [default=yes]]), [], + [SECP_SET_DEFAULT([enable_module_ecdh], [yes], [yes])]) AC_ARG_ENABLE(module_recovery, - AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module (default is no)]), - [enable_module_recovery=$enableval], - [enable_module_recovery=no]) + AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module [default=no]]), [], + [SECP_SET_DEFAULT([enable_module_recovery], [no], [yes])]) -AC_ARG_ENABLE(jni, - AS_HELP_STRING([--enable-jni],[enable libsecp256k1_jni (default is auto)]), - [use_jni=$enableval], - [use_jni=auto]) +AC_ARG_ENABLE(module_extrakeys, + AS_HELP_STRING([--enable-module-extrakeys],[enable extrakeys module [default=yes]]), [], + [SECP_SET_DEFAULT([enable_module_extrakeys], [yes], [yes])]) -AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto], -[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) +AC_ARG_ENABLE(module_schnorrsig, + AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=yes]]), [], + [SECP_SET_DEFAULT([enable_module_schnorrsig], [yes], [yes])]) -AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto], -[Specify Bignum Implementation. Default is auto])],[req_bignum=$withval], [req_bignum=auto]) +AC_ARG_ENABLE(module_musig, + AS_HELP_STRING([--enable-module-musig],[enable MuSig2 module [default=yes]]), [], + [SECP_SET_DEFAULT([enable_module_musig], [yes], [yes])]) -AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto], -[Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto]) +AC_ARG_ENABLE(module_ellswift, + AS_HELP_STRING([--enable-module-ellswift],[enable ElligatorSwift module [default=yes]]), [], + [SECP_SET_DEFAULT([enable_module_ellswift], [yes], [yes])]) -AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto] -[Specify assembly optimizations to use. Default is auto (experimental: arm)])],[req_asm=$withval], [req_asm=auto]) +AC_ARG_ENABLE(external_default_callbacks, + AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [], + [SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])]) -AC_CHECK_TYPES([__int128]) +# Test-only override of the (autodetected by the C code) "widemul" setting. +# Legal values are: +# * int64 (for [u]int64_t), +# * int128 (for [unsigned] __int128), +# * int128_struct (for int128 implemented as a structure), +# * and auto (the default). +AC_ARG_WITH([test-override-wide-multiply], [] ,[set_widemul=$withval], [set_widemul=auto]) -AC_MSG_CHECKING([for __builtin_expect]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])], - [ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]) ], - [ AC_MSG_RESULT([no]) - ]) +AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm32|no|auto], +[assembly to use (experimental: arm32) [default=auto]])],[req_asm=$withval], [req_asm=auto]) -if test x"$enable_coverage" = x"yes"; then - AC_DEFINE(COVERAGE, 1, [Define this symbol to compile out all VERIFY code]) - CFLAGS="$CFLAGS -O0 --coverage" - LDFLAGS="--coverage" +AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE], +[window size for ecmult precomputation for verification, specified as integer in range [2..24].] +[Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.] +[The table will store 2^(SIZE-1) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.] +[A window size larger than 15 will require you delete the prebuilt precomputed_ecmult.c file so that it can be rebuilt.] +[For very large window sizes, use "make -j 1" to reduce memory use during compilation.] +[The default value is a reasonable setting for desktop machines (currently 15). [default=15]] +)], +[set_ecmult_window=$withval], [set_ecmult_window=15]) + +AC_ARG_WITH([ecmult-gen-kb], [AS_HELP_STRING([--with-ecmult-gen-kb=2|22|86], +[The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms).] +[Larger values result in possibly better signing/keygeneration performance at the cost of a larger table.] +[The default value is a reasonable setting for desktop machines (currently 86). [default=86]] +)], +[set_ecmult_gen_kb=$withval], [set_ecmult_gen_kb=86]) + +AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind=yes|no|auto], +[Build with extra checks for running inside Valgrind [default=auto]] +)], +[req_valgrind=$withval], [req_valgrind=auto]) + +### +### Handle config options (except for modules) +### + +if test x"$req_valgrind" = x"no"; then + enable_valgrind=no else - CFLAGS="$CFLAGS -O3" + SECP_VALGRIND_CHECK + if test x"$has_valgrind" != x"yes"; then + if test x"$req_valgrind" = x"yes"; then + AC_MSG_ERROR([Valgrind support explicitly requested but valgrind/memcheck.h header not available]) + fi + enable_valgrind=no + else + enable_valgrind=yes + fi fi -if test x"$use_ecmult_static_precomputation" != x"no"; then - save_cross_compiling=$cross_compiling - cross_compiling=no - TEMP_CC="$CC" - CC="$CC_FOR_BUILD" - AC_MSG_CHECKING([native compiler: ${CC_FOR_BUILD}]) - AC_RUN_IFELSE( - [AC_LANG_PROGRAM([], [return 0])], - [working_native_cc=yes], - [working_native_cc=no],[dnl]) - CC="$TEMP_CC" - cross_compiling=$save_cross_compiling +if test x"$enable_ctime_tests" = x"auto"; then + enable_ctime_tests=$enable_valgrind +fi - if test x"$working_native_cc" = x"no"; then - set_precomp=no - if test x"$use_ecmult_static_precomputation" = x"yes"; then - AC_MSG_ERROR([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) - else - AC_MSG_RESULT([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) - fi - else - AC_MSG_RESULT([ok]) - set_precomp=yes +print_msan_notice=no +if test x"$enable_ctime_tests" = x"yes"; then + SECP_MSAN_CHECK + # MSan on Clang >=16 reports uninitialized memory in function parameters and return values, even if + # the uninitialized variable is never actually "used". This is called "eager" checking, and it's + # sounds like good idea for normal use of MSan. However, it yields many false positives in the + # ctime_tests because many return values depend on secret (i.e., "uninitialized") values, and + # we're only interested in detecting branches (which count as "uses") on secret data. + if test x"$msan_enabled" = x"yes"; then + SECP_TRY_APPEND_CFLAGS([-fno-sanitize-memory-param-retval], SECP_CFLAGS) + print_msan_notice=yes fi +fi + +if test x"$enable_coverage" = x"yes"; then + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1" + SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS" + # If coverage is enabled, and the user has not overridden CFLAGS, + # override Autoconf's value "-g -O2" with "-g". Otherwise we'd end up + # with "-O0 --coverage -g -O2". + if test "$CFLAGS_overridden" = "no"; then + CFLAGS="-g" + fi + LDFLAGS="--coverage $LDFLAGS" else - set_precomp=no + # Most likely the CFLAGS already contain -O2 because that is autoconf's default. + # We still add it here because passing it twice is not an issue, and handling + # this case would just add unnecessary complexity (see #896). + SECP_CFLAGS="-O2 $SECP_CFLAGS" fi if test x"$req_asm" = x"auto"; then - SECP_64BIT_ASM_CHECK - if test x"$has_64bit_asm" = x"yes"; then + SECP_X86_64_ASM_CHECK + if test x"$has_x86_64_asm" = x"yes"; then set_asm=x86_64 fi if test x"$set_asm" = x; then @@ -207,287 +294,224 @@ else set_asm=$req_asm case $set_asm in x86_64) - SECP_64BIT_ASM_CHECK - if test x"$has_64bit_asm" != x"yes"; then - AC_MSG_ERROR([x86_64 assembly optimization requested but not available]) + SECP_X86_64_ASM_CHECK + if test x"$has_x86_64_asm" != x"yes"; then + AC_MSG_ERROR([x86_64 assembly requested but not available]) fi ;; - arm) - ;; - no) - ;; - *) - AC_MSG_ERROR([invalid assembly optimization selection]) - ;; - esac -fi - -if test x"$req_field" = x"auto"; then - if test x"set_asm" = x"x86_64"; then - set_field=64bit - fi - if test x"$set_field" = x; then - SECP_INT128_CHECK - if test x"$has_int128" = x"yes"; then - set_field=64bit - fi - fi - if test x"$set_field" = x; then - set_field=32bit - fi -else - set_field=$req_field - case $set_field in - 64bit) - if test x"$set_asm" != x"x86_64"; then - SECP_INT128_CHECK - if test x"$has_int128" != x"yes"; then - AC_MSG_ERROR([64bit field explicitly requested but neither __int128 support or x86_64 assembly available]) - fi - fi - ;; - 32bit) - ;; - *) - AC_MSG_ERROR([invalid field implementation selection]) - ;; - esac -fi - -if test x"$req_scalar" = x"auto"; then - SECP_INT128_CHECK - if test x"$has_int128" = x"yes"; then - set_scalar=64bit - fi - if test x"$set_scalar" = x; then - set_scalar=32bit - fi -else - set_scalar=$req_scalar - case $set_scalar in - 64bit) - SECP_INT128_CHECK - if test x"$has_int128" != x"yes"; then - AC_MSG_ERROR([64bit scalar explicitly requested but __int128 support not available]) - fi - ;; - 32bit) - ;; - *) - AC_MSG_ERROR([invalid scalar implementation selected]) - ;; - esac -fi - -if test x"$req_bignum" = x"auto"; then - SECP_GMP_CHECK - if test x"$has_gmp" = x"yes"; then - set_bignum=gmp - fi - - if test x"$set_bignum" = x; then - set_bignum=no - fi -else - set_bignum=$req_bignum - case $set_bignum in - gmp) - SECP_GMP_CHECK - if test x"$has_gmp" != x"yes"; then - AC_MSG_ERROR([gmp bignum explicitly requested but libgmp not available]) + arm32) + SECP_ARM32_ASM_CHECK + if test x"$has_arm32_asm" != x"yes"; then + AC_MSG_ERROR([ARM32 assembly requested but not available]) fi ;; no) ;; *) - AC_MSG_ERROR([invalid bignum implementation selection]) + AC_MSG_ERROR([invalid assembly selection]) ;; esac fi -# select assembly optimization -use_external_asm=no +# Select assembly +enable_external_asm=no case $set_asm in x86_64) - AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations]) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_ASM_X86_64=1" ;; -arm) - use_external_asm=yes +arm32) + enable_external_asm=yes ;; no) ;; *) - AC_MSG_ERROR([invalid assembly optimizations]) + AC_MSG_ERROR([invalid assembly selection]) ;; esac -# select field implementation -case $set_field in -64bit) - AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation]) +if test x"$enable_external_asm" = x"yes"; then + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_EXTERNAL_ASM=1" +fi + + +# Select wide multiplication implementation +case $set_widemul in +int128_struct) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT128_STRUCT=1" ;; -32bit) - AC_DEFINE(USE_FIELD_10X26, 1, [Define this symbol to use the FIELD_10X26 implementation]) +int128) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT128=1" + ;; +int64) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT64=1" + ;; +auto) ;; *) - AC_MSG_ERROR([invalid field implementation]) + AC_MSG_ERROR([invalid wide multiplication implementation]) ;; esac -# select bignum implementation -case $set_bignum in -gmp) - AC_DEFINE(HAVE_LIBGMP, 1, [Define this symbol if libgmp is installed]) - AC_DEFINE(USE_NUM_GMP, 1, [Define this symbol to use the gmp implementation for num]) - AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the num-based field inverse implementation]) - AC_DEFINE(USE_SCALAR_INV_NUM, 1, [Define this symbol to use the num-based scalar inverse implementation]) - ;; -no) - AC_DEFINE(USE_NUM_NONE, 1, [Define this symbol to use no num implementation]) - AC_DEFINE(USE_FIELD_INV_BUILTIN, 1, [Define this symbol to use the native field inverse implementation]) - AC_DEFINE(USE_SCALAR_INV_BUILTIN, 1, [Define this symbol to use the native scalar inverse implementation]) +error_window_size=['window size for ecmult precomputation not an integer in range [2..24]'] +case $set_ecmult_window in +''|*[[!0-9]]*) + # no valid integer + AC_MSG_ERROR($error_window_size) ;; *) - AC_MSG_ERROR([invalid bignum implementation]) + if test "$set_ecmult_window" -lt 2 -o "$set_ecmult_window" -gt 24 ; then + # not in range + AC_MSG_ERROR($error_window_size) + fi + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DECMULT_WINDOW_SIZE=$set_ecmult_window" ;; esac -#select scalar implementation -case $set_scalar in -64bit) - AC_DEFINE(USE_SCALAR_4X64, 1, [Define this symbol to use the 4x64 scalar implementation]) +case $set_ecmult_gen_kb in +2) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=2 -DCOMB_TEETH=5" ;; -32bit) - AC_DEFINE(USE_SCALAR_8X32, 1, [Define this symbol to use the 8x32 scalar implementation]) +22) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=11 -DCOMB_TEETH=6" + ;; +86) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=43 -DCOMB_TEETH=6" ;; *) - AC_MSG_ERROR([invalid scalar implementation]) + AC_MSG_ERROR(['ecmult gen table size not 2, 22 or 86']) ;; esac -if test x"$use_tests" = x"yes"; then - SECP_OPENSSL_CHECK - if test x"$has_openssl_ec" = x"yes"; then - if test x"$enable_openssl_tests" != x"no"; then - AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) - SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" - SECP_TEST_LIBS="$CRYPTO_LIBS" - - case $host in - *mingw*) - SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" - ;; - esac - fi - else - if test x"$enable_openssl_tests" = x"yes"; then - AC_MSG_ERROR([OpenSSL tests requested but OpenSSL with EC support is not available]) - fi - fi -else - if test x"$enable_openssl_tests" = x"yes"; then - AC_MSG_ERROR([OpenSSL tests requested but tests are not enabled]) - fi +if test x"$enable_valgrind" = x"yes"; then + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES $VALGRIND_CPPFLAGS -DVALGRIND" fi -if test x"$use_jni" != x"no"; then - AX_JNI_INCLUDE_DIR - have_jni_dependencies=yes - if test x"$enable_module_ecdh" = x"no"; then - have_jni_dependencies=no +# Add -Werror and similar flags passed from the outside (for testing, e.g., in CI). +# We don't want to set the user variable CFLAGS in CI because this would disable +# autoconf's logic for setting default CFLAGS, which we would like to test in CI. +SECP_CFLAGS="$SECP_CFLAGS $WERROR_CFLAGS" + +### +### Handle module options +### + +# Processing must be done in a reverse topological sorting of the dependency graph +# (dependent module first). +if test x"$enable_module_ellswift" = x"yes"; then + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ELLSWIFT=1" +fi + +if test x"$enable_module_musig" = x"yes"; then + if test x"$enable_module_schnorrsig" = x"no"; then + AC_MSG_ERROR([Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.]) fi - if test "x$JNI_INCLUDE_DIRS" = "x"; then - have_jni_dependencies=no - fi - if test "x$have_jni_dependencies" = "xno"; then - if test x"$use_jni" = x"yes"; then - AC_MSG_ERROR([jni support explicitly requested but headers/dependencies were not found. Enable ECDH and try again.]) - fi - AC_MSG_WARN([jni headers/dependencies not found. jni support disabled]) - use_jni=no - else - use_jni=yes - for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS; do - JNI_INCLUDES="$JNI_INCLUDES -I$JNI_INCLUDE_DIR" - done + enable_module_schnorrsig=yes + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_MUSIG=1" +fi + +if test x"$enable_module_schnorrsig" = x"yes"; then + if test x"$enable_module_extrakeys" = x"no"; then + AC_MSG_ERROR([Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.]) fi + enable_module_extrakeys=yes + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_SCHNORRSIG=1" fi -if test x"$set_bignum" = x"gmp"; then - SECP_LIBS="$SECP_LIBS $GMP_LIBS" - SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS" -fi - -if test x"$use_endomorphism" = x"yes"; then - AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) -fi - -if test x"$set_precomp" = x"yes"; then - AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table]) -fi - -if test x"$enable_module_ecdh" = x"yes"; then - AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module]) +if test x"$enable_module_extrakeys" = x"yes"; then + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_EXTRAKEYS=1" fi if test x"$enable_module_recovery" = x"yes"; then - AC_DEFINE(ENABLE_MODULE_RECOVERY, 1, [Define this symbol to enable the ECDSA pubkey recovery module]) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_RECOVERY=1" fi -AC_C_BIGENDIAN() - -if test x"$use_external_asm" = x"yes"; then - AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used]) +if test x"$enable_module_ecdh" = x"yes"; then + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ECDH=1" fi -AC_MSG_NOTICE([Using static precomputation: $set_precomp]) -AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) -AC_MSG_NOTICE([Using field implementation: $set_field]) -AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) -AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) -AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism]) -AC_MSG_NOTICE([Building for coverage analysis: $enable_coverage]) -AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) -AC_MSG_NOTICE([Building ECDSA pubkey recovery module: $enable_module_recovery]) -AC_MSG_NOTICE([Using jni: $use_jni]) +if test x"$enable_external_default_callbacks" = x"yes"; then + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_EXTERNAL_DEFAULT_CALLBACKS=1" +fi -if test x"$enable_experimental" = x"yes"; then - AC_MSG_NOTICE([******]) - AC_MSG_NOTICE([WARNING: experimental build]) - AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.]) - AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) - AC_MSG_NOTICE([******]) -else - if test x"$enable_module_ecdh" = x"yes"; then - AC_MSG_ERROR([ECDH module is experimental. Use --enable-experimental to allow.]) - fi - if test x"$set_asm" = x"arm"; then - AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.]) +### +### Check for --enable-experimental if necessary +### + +if test x"$enable_experimental" = x"no"; then + if test x"$set_asm" = x"arm32"; then + AC_MSG_ERROR([ARM32 assembly is experimental. Use --enable-experimental to allow.]) fi fi -AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) +### +### Generate output +### + AC_CONFIG_FILES([Makefile libsecp256k1.pc]) -AC_SUBST(JNI_INCLUDES) -AC_SUBST(SECP_INCLUDES) -AC_SUBST(SECP_LIBS) -AC_SUBST(SECP_TEST_LIBS) -AC_SUBST(SECP_TEST_INCLUDES) +AC_SUBST(SECP_CFLAGS) +AC_SUBST(SECP_CONFIG_DEFINES) AM_CONDITIONAL([ENABLE_COVERAGE], [test x"$enable_coverage" = x"yes"]) -AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) -AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$use_exhaustive_tests" != x"no"]) -AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"]) -AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$set_precomp" = x"yes"]) +AM_CONDITIONAL([USE_TESTS], [test x"$enable_tests" != x"no"]) +AM_CONDITIONAL([USE_CTIME_TESTS], [test x"$enable_ctime_tests" = x"yes"]) +AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$enable_exhaustive_tests" != x"no"]) +AM_CONDITIONAL([USE_EXAMPLES], [test x"$enable_examples" != x"no"]) +AM_CONDITIONAL([USE_BENCHMARK], [test x"$enable_benchmark" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"]) -AM_CONDITIONAL([USE_JNI], [test x"$use_jni" == x"yes"]) -AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$use_external_asm" = x"yes"]) -AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"]) - -dnl make sure nothing new is exported so that we don't break the cache -PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" -unset PKG_CONFIG_PATH -PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP" +AM_CONDITIONAL([ENABLE_MODULE_EXTRAKEYS], [test x"$enable_module_extrakeys" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG], [test x"$enable_module_schnorrsig" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_MUSIG], [test x"$enable_module_musig" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_ELLSWIFT], [test x"$enable_module_ellswift" = x"yes"]) +AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"]) +AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm32"]) +AM_CONDITIONAL([BUILD_WINDOWS], [test "$build_windows" = "yes"]) +AC_SUBST(LIB_VERSION_CURRENT, _LIB_VERSION_CURRENT) +AC_SUBST(LIB_VERSION_REVISION, _LIB_VERSION_REVISION) +AC_SUBST(LIB_VERSION_AGE, _LIB_VERSION_AGE) AC_OUTPUT + +echo +echo "Build Options:" +echo " with external callbacks = $enable_external_default_callbacks" +echo " with benchmarks = $enable_benchmark" +echo " with tests = $enable_tests" +echo " with ctime tests = $enable_ctime_tests" +echo " with coverage = $enable_coverage" +echo " with examples = $enable_examples" +echo " module ecdh = $enable_module_ecdh" +echo " module recovery = $enable_module_recovery" +echo " module extrakeys = $enable_module_extrakeys" +echo " module schnorrsig = $enable_module_schnorrsig" +echo " module musig = $enable_module_musig" +echo " module ellswift = $enable_module_ellswift" +echo +echo " asm = $set_asm" +echo " ecmult window size = $set_ecmult_window" +echo " ecmult gen table size = $set_ecmult_gen_kb KiB" +# Hide test-only options unless they're used. +if test x"$set_widemul" != xauto; then +echo " wide multiplication = $set_widemul" +fi +echo +echo " valgrind = $enable_valgrind" +echo " CC = $CC" +echo " CPPFLAGS = $CPPFLAGS" +echo " SECP_CFLAGS = $SECP_CFLAGS" +echo " CFLAGS = $CFLAGS" +echo " LDFLAGS = $LDFLAGS" + +if test x"$print_msan_notice" = x"yes"; then + echo + echo "Note:" + echo " MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to SECP_CFLAGS" + echo " to avoid false positives in ctime_tests. Pass --disable-ctime-tests to avoid this." +fi + +if test x"$enable_experimental" = x"yes"; then + echo + echo "WARNING: Experimental build" + echo " Experimental features do not have stable APIs or properties, and may not be safe for" + echo " production use." +fi diff --git a/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c b/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c index 5b141a9948..bf562303ed 100644 --- a/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c +++ b/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c @@ -1,11 +1,10 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include -#include #include "lax_der_parsing.h" @@ -32,7 +31,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_ lenbyte = input[pos++]; if (lenbyte & 0x80) { lenbyte -= 0x80; - if (pos + lenbyte > inputlen) { + if (lenbyte > inputlen - pos) { return 0; } pos += lenbyte; @@ -51,7 +50,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_ lenbyte = input[pos++]; if (lenbyte & 0x80) { lenbyte -= 0x80; - if (pos + lenbyte > inputlen) { + if (lenbyte > inputlen - pos) { return 0; } while (lenbyte > 0 && input[pos] == 0) { @@ -89,7 +88,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_ lenbyte = input[pos++]; if (lenbyte & 0x80) { lenbyte -= 0x80; - if (pos + lenbyte > inputlen) { + if (lenbyte > inputlen - pos) { return 0; } while (lenbyte > 0 && input[pos] == 0) { @@ -112,7 +111,6 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_ return 0; } spos = pos; - pos += slen; /* Ignore leading zeroes in R */ while (rlen > 0 && input[rpos] == 0) { @@ -122,7 +120,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_ /* Copy R value */ if (rlen > 32) { overflow = 1; - } else { + } else if (rlen) { memcpy(tmpsig + 32 - rlen, input + rpos, rlen); } @@ -134,7 +132,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_ /* Copy S value */ if (slen > 32) { overflow = 1; - } else { + } else if (slen) { memcpy(tmpsig + 64 - slen, input + spos, slen); } diff --git a/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.h b/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.h index 6d27871a7c..37c8c691f2 100644 --- a/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.h +++ b/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ /**** * Please do not link this file directly. It is not part of the libsecp256k1 @@ -48,21 +48,27 @@ * 8.3.1. */ -#ifndef _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ -#define _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ +#ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H +#define SECP256K1_CONTRIB_LAX_DER_PARSING_H +/* #include secp256k1.h only when it hasn't been included yet. + This enables this file to be #included directly in other project + files (such as tests.c) without the need to set an explicit -I flag, + which would be necessary to locate secp256k1.h. */ +#ifndef SECP256K1_H #include +#endif -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif /** Parse a signature in "lax DER" format * * Returns: 1 when the signature could be parsed, 0 otherwise. * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input: a pointer to the signature to be parsed + * Out: sig: pointer to a signature object + * In: input: pointer to the signature to be parsed * inputlen: the length of the array pointed to be input * * This function will accept any valid DER encoded signature, even if the @@ -88,4 +94,4 @@ int ecdsa_signature_parse_der_lax( } #endif -#endif +#endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */ diff --git a/crypto/secp256k1/libsecp256k1/contrib/lax_der_privatekey_parsing.c b/crypto/secp256k1/libsecp256k1/contrib/lax_der_privatekey_parsing.c index c2e63b4b8d..a1b8200079 100644 --- a/crypto/secp256k1/libsecp256k1/contrib/lax_der_privatekey_parsing.c +++ b/crypto/secp256k1/libsecp256k1/contrib/lax_der_privatekey_parsing.c @@ -1,11 +1,10 @@ -/********************************************************************** - * Copyright (c) 2014, 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014, 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include -#include #include "lax_der_privatekey_parsing.h" @@ -45,7 +44,7 @@ int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, co if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) { return 0; } - memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]); + if (privkey[1]) memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]); if (!secp256k1_ec_seckey_verify(ctx, out32)) { memset(out32, 0, 32); return 0; diff --git a/crypto/secp256k1/libsecp256k1/contrib/lax_der_privatekey_parsing.h b/crypto/secp256k1/libsecp256k1/contrib/lax_der_privatekey_parsing.h index 2fd088f8ab..3749e418fe 100644 --- a/crypto/secp256k1/libsecp256k1/contrib/lax_der_privatekey_parsing.h +++ b/crypto/secp256k1/libsecp256k1/contrib/lax_der_privatekey_parsing.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014, 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014, 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ /**** * Please do not link this file directly. It is not part of the libsecp256k1 @@ -25,20 +25,25 @@ * library are sufficient. */ -#ifndef _SECP256K1_CONTRIB_BER_PRIVATEKEY_H_ -#define _SECP256K1_CONTRIB_BER_PRIVATEKEY_H_ +#ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H +#define SECP256K1_CONTRIB_BER_PRIVATEKEY_H +/* #include secp256k1.h only when it hasn't been included yet. + This enables this file to be #included directly in other project + files (such as tests.c) without the need to set an explicit -I flag, + which would be necessary to locate secp256k1.h. */ +#ifndef SECP256K1_H #include +#endif -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif /** Export a private key in DER format. * * Returns: 1 if the private key was valid. - * Args: ctx: pointer to a context object, initialized for signing (cannot - * be NULL) + * Args: ctx: pointer to a context object (not secp256k1_context_static). * Out: privkey: pointer to an array for storing the private key in BER. * Should have space for 279 bytes, and cannot be NULL. * privkeylen: Pointer to an int where the length of the private key in @@ -87,4 +92,4 @@ SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( } #endif -#endif +#endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */ diff --git a/crypto/secp256k1/libsecp256k1/doc/ellswift.md b/crypto/secp256k1/libsecp256k1/doc/ellswift.md new file mode 100644 index 0000000000..9d60e6be0b --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/doc/ellswift.md @@ -0,0 +1,483 @@ +# ElligatorSwift for secp256k1 explained + +In this document we explain how the `ellswift` module implementation is related to the +construction in the +["SwiftEC: Shallue–van de Woestijne Indifferentiable Function To Elliptic Curves"](https://eprint.iacr.org/2022/759) +paper by Jorge Chávez-Saab, Francisco Rodríguez-Henríquez, and Mehdi Tibouchi. + +* [1. Introduction](#1-introduction) +* [2. The decoding function](#2-the-decoding-function) + + [2.1 Decoding for `secp256k1`](#21-decoding-for-secp256k1) +* [3. The encoding function](#3-the-encoding-function) + + [3.1 Switching to *v, w* coordinates](#31-switching-to-v-w-coordinates) + + [3.2 Avoiding computing all inverses](#32-avoiding-computing-all-inverses) + + [3.3 Finding the inverse](#33-finding-the-inverse) + + [3.4 Dealing with special cases](#34-dealing-with-special-cases) + + [3.5 Encoding for `secp256k1`](#35-encoding-for-secp256k1) +* [4. Encoding and decoding full *(x, y)* coordinates](#4-encoding-and-decoding-full-x-y-coordinates) + + [4.1 Full *(x, y)* coordinates for `secp256k1`](#41-full-x-y-coordinates-for-secp256k1) + +## 1. Introduction + +The `ellswift` module effectively introduces a new 64-byte public key format, with the property +that (uniformly random) public keys can be encoded as 64-byte arrays which are computationally +indistinguishable from uniform byte arrays. The module provides functions to convert public keys +from and to this format, as well as convenience functions for key generation and ECDH that operate +directly on ellswift-encoded keys. + +The encoding consists of the concatenation of two (32-byte big endian) encoded field elements $u$ +and $t.$ Together they encode an x-coordinate on the curve $x$, or (see further) a full point $(x, y)$ on +the curve. + +**Decoding** consists of decoding the field elements $u$ and $t$ (values above the field size $p$ +are taken modulo $p$), and then evaluating $F_u(t)$, which for every $u$ and $t$ results in a valid +x-coordinate on the curve. The functions $F_u$ will be defined in [Section 2](#2-the-decoding-function). + +**Encoding** a given $x$ coordinate is conceptually done as follows: +* Loop: + * Pick a uniformly random field element $u.$ + * Compute the set $L = F_u^{-1}(x)$ of $t$ values for which $F_u(t) = x$, which may have up to *8* elements. + * With probability $1 - \dfrac{\\#L}{8}$, restart the loop. + * Select a uniformly random $t \in L$ and return $(u, t).$ + +This is the *ElligatorSwift* algorithm, here given for just x-coordinates. An extension to full +$(x, y)$ points will be given in [Section 4](#4-encoding-and-decoding-full-x-y-coordinates). +The algorithm finds a uniformly random $(u, t)$ among (almost all) those +for which $F_u(t) = x.$ Section 3.2 in the paper proves that the number of such encodings for +almost all x-coordinates on the curve (all but at most 39) is close to two times the field size +(specifically, it lies in the range $2q \pm (22\sqrt{q} + O(1))$, where $q$ is the size of the field). + +## 2. The decoding function + +First some definitions: +* $\mathbb{F}$ is the finite field of size $q$, of characteristic 5 or more, and $q \equiv 1 \mod 3.$ + * For `secp256k1`, $q = 2^{256} - 2^{32} - 977$, which satisfies that requirement. +* Let $E$ be the elliptic curve of points $(x, y) \in \mathbb{F}^2$ for which $y^2 = x^3 + ax + b$, with $a$ and $b$ + public constants, for which $\Delta_E = -16(4a^3 + 27b^2)$ is a square, and at least one of $(-b \pm \sqrt{-3 \Delta_E} / 36)/2$ is a square. + This implies that the order of $E$ is either odd, or a multiple of *4*. + If $a=0$, this condition is always fulfilled. + * For `secp256k1`, $a=0$ and $b=7.$ +* Let the function $g(x) = x^3 + ax + b$, so the $E$ curve equation is also $y^2 = g(x).$ +* Let the function $h(x) = 3x^3 + 4a.$ +* Define $V$ as the set of solutions $(x_1, x_2, x_3, z)$ to $z^2 = g(x_1)g(x_2)g(x_3).$ +* Define $S_u$ as the set of solutions $(X, Y)$ to $X^2 + h(u)Y^2 = -g(u)$ and $Y \neq 0.$ +* $P_u$ is a function from $\mathbb{F}$ to $S_u$ that will be defined below. +* $\psi_u$ is a function from $S_u$ to $V$ that will be defined below. + +**Note**: In the paper: +* $F_u$ corresponds to $F_{0,u}$ there. +* $P_u(t)$ is called $P$ there. +* All $S_u$ sets together correspond to $S$ there. +* All $\psi_u$ functions together (operating on elements of $S$) correspond to $\psi$ there. + +Note that for $V$, the left hand side of the equation $z^2$ is square, and thus the right +hand must also be square. As multiplying non-squares results in a square in $\mathbb{F}$, +out of the three right-hand side factors an even number must be non-squares. +This implies that exactly *1* or exactly *3* out of +$\\{g(x_1), g(x_2), g(x_3)\\}$ must be square, and thus that for any $(x_1,x_2,x_3,z) \in V$, +at least one of $\\{x_1, x_2, x_3\\}$ must be a valid x-coordinate on $E.$ There is one exception +to this, namely when $z=0$, but even then one of the three values is a valid x-coordinate. + +**Define** the decoding function $F_u(t)$ as: +* Let $(x_1, x_2, x_3, z) = \psi_u(P_u(t)).$ +* Return the first element $x$ of $(x_3, x_2, x_1)$ which is a valid x-coordinate on $E$ (i.e., $g(x)$ is square). + +$P_u(t) = (X(u, t), Y(u, t))$, where: + +$$ +\begin{array}{lcl} +X(u, t) & = & \left\\{\begin{array}{ll} + \dfrac{g(u) - t^2}{2t} & a = 0 \\ + \dfrac{g(u) + h(u)(Y_0(u) - X_0(u)t)^2}{X_0(u)(1 + h(u)t^2)} & a \neq 0 +\end{array}\right. \\ +Y(u, t) & = & \left\\{\begin{array}{ll} + \dfrac{X(u, t) + t}{u \sqrt{-3}} = \dfrac{g(u) + t^2}{2tu\sqrt{-3}} & a = 0 \\ + Y_0(u) + t(X(u, t) - X_0(u)) & a \neq 0 +\end{array}\right. +\end{array} +$$ + +$P_u(t)$ is defined: +* For $a=0$, unless: + * $u = 0$ or $t = 0$ (division by zero) + * $g(u) = -t^2$ (would give $Y=0$). +* For $a \neq 0$, unless: + * $X_0(u) = 0$ or $h(u)t^2 = -1$ (division by zero) + * $Y_0(u) (1 - h(u)t^2) = 2X_0(u)t$ (would give $Y=0$). + +The functions $X_0(u)$ and $Y_0(u)$ are defined in Appendix A of the paper, and depend on various properties of $E.$ + +The function $\psi_u$ is the same for all curves: $\psi_u(X, Y) = (x_1, x_2, x_3, z)$, where: + +$$ +\begin{array}{lcl} + x_1 & = & \dfrac{X}{2Y} - \dfrac{u}{2} && \\ + x_2 & = & -\dfrac{X}{2Y} - \dfrac{u}{2} && \\ + x_3 & = & u + 4Y^2 && \\ + z & = & \dfrac{g(x_3)}{2Y}(u^2 + ux_1 + x_1^2 + a) = \dfrac{-g(u)g(x_3)}{8Y^3} +\end{array} +$$ + +### 2.1 Decoding for `secp256k1` + +Put together and specialized for $a=0$ curves, decoding $(u, t)$ to an x-coordinate is: + +**Define** $F_u(t)$ as: +* Let $X = \dfrac{u^3 + b - t^2}{2t}.$ +* Let $Y = \dfrac{X + t}{u\sqrt{-3}}.$ +* Return the first $x$ in $(u + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u}{2}, \dfrac{X}{2Y} - \dfrac{u}{2})$ for which $g(x)$ is square. + +To make sure that every input decodes to a valid x-coordinate, we remap the inputs in case +$P_u$ is not defined (when $u=0$, $t=0$, or $g(u) = -t^2$): + +**Define** $F_u(t)$ as: +* Let $u'=u$ if $u \neq 0$; $1$ otherwise (guaranteeing $u' \neq 0$). +* Let $t'=t$ if $t \neq 0$; $1$ otherwise (guaranteeing $t' \neq 0$). +* Let $t''=t'$ if $g(u') \neq -t'^2$; $2t'$ otherwise (guaranteeing $t'' \neq 0$ and $g(u') \neq -t''^2$). +* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$ +* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$ +* Return the first $x$ in $(u' + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u'}{2}, \dfrac{X}{2Y} - \dfrac{u'}{2})$ for which $x^3 + b$ is square. + +The choices here are not strictly necessary. Just returning a fixed constant in any of the undefined cases would suffice, +but the approach here is simple enough and gives fairly uniform output even in these cases. + +**Note**: in the paper these conditions result in $\infty$ as output, due to the use of projective coordinates there. +We wish to avoid the need for callers to deal with this special case. + +This is implemented in `secp256k1_ellswift_xswiftec_frac_var` (which decodes to an x-coordinate represented as a fraction), and +in `secp256k1_ellswift_xswiftec_var` (which outputs the actual x-coordinate). + +## 3. The encoding function + +To implement $F_u^{-1}(x)$, the function to find the set of inverses $t$ for which $F_u(t) = x$, we have to reverse the process: +* Find all the $(X, Y) \in S_u$ that could have given rise to $x$, through the $x_1$, $x_2$, or $x_3$ formulas in $\psi_u.$ +* Map those $(X, Y)$ solutions to $t$ values using $P_u^{-1}(X, Y).$ +* For each of the found $t$ values, verify that $F_u(t) = x.$ +* Return the remaining $t$ values. + +The function $P_u^{-1}$, which finds $t$ given $(X, Y) \in S_u$, is significantly simpler than $P_u:$ + +$$ +P_u^{-1}(X, Y) = \left\\{\begin{array}{ll} +Yu\sqrt{-3} - X & a = 0 \\ +\dfrac{Y-Y_0(u)}{X-X_0(u)} & a \neq 0 \land X \neq X_0(u) \\ +\dfrac{-X_0(u)}{h(u)Y_0(u)} & a \neq 0 \land X = X_0(u) \land Y = Y_0(u) +\end{array}\right. +$$ + +The third step above, verifying that $F_u(t) = x$, is necessary because for the $(X, Y)$ values found through the $x_1$ and $x_2$ expressions, +it is possible that decoding through $\psi_u(X, Y)$ yields a valid $x_3$ on the curve, which would take precedence over the +$x_1$ or $x_2$ decoding. These $(X, Y)$ solutions must be rejected. + +Since we know that exactly one or exactly three out of $\\{x_1, x_2, x_3\\}$ are valid x-coordinates for any $t$, +the case where either $x_1$ or $x_2$ is valid and in addition also $x_3$ is valid must mean that all three are valid. +This means that instead of checking whether $x_3$ is on the curve, it is also possible to check whether the other one out of +$x_1$ and $x_2$ is on the curve. This is significantly simpler, as it turns out. + +Observe that $\psi_u$ guarantees that $x_1 + x_2 = -u.$ So given either $x = x_1$ or $x = x_2$, the other one of the two can be computed as +$-u - x.$ Thus, when encoding $x$ through the $x_1$ or $x_2$ expressions, one can simply check whether $g(-u-x)$ is a square, +and if so, not include the corresponding $t$ values in the returned set. As this does not need $X$, $Y$, or $t$, this condition can be determined +before those values are computed. + +It is not possible that an encoding found through the $x_1$ expression decodes to a different valid x-coordinate using $x_2$ (which would +take precedence), for the same reason: if both $x_1$ and $x_2$ decodings were valid, $x_3$ would be valid as well, and thus take +precedence over both. Because of this, the $g(-u-x)$ being square test for $x_1$ and $x_2$ is the only test necessary to guarantee the found $t$ +values round-trip back to the input $x$ correctly. This is the reason for choosing the $(x_3, x_2, x_1)$ precedence order in the decoder; +any order which does not place $x_3$ first requires more complicated round-trip checks in the encoder. + +### 3.1 Switching to *v, w* coordinates + +Before working out the formulas for all this, we switch to different variables for $S_u.$ Let $v = (X/Y - u)/2$, and +$w = 2Y.$ Or in the other direction, $X = w(u/2 + v)$ and $Y = w/2:$ +* $S_u'$ becomes the set of $(v, w)$ for which $w^2 (u^2 + uv + v^2 + a) = -g(u)$ and $w \neq 0.$ +* For $a=0$ curves, $P_u^{-1}$ can be stated for $(v,w)$ as $P_u^{'-1}(v, w) = w\left(\frac{\sqrt{-3}-1}{2}u - v\right).$ +* $\psi_u$ can be stated for $(v, w)$ as $\psi_u'(v, w) = (x_1, x_2, x_3, z)$, where + +$$ +\begin{array}{lcl} + x_1 & = & v \\ + x_2 & = & -u - v \\ + x_3 & = & u + w^2 \\ + z & = & \dfrac{g(x_3)}{w}(u^2 + uv + v^2 + a) = \dfrac{-g(u)g(x_3)}{w^3} +\end{array} +$$ + +We can now write the expressions for finding $(v, w)$ given $x$ explicitly, by solving each of the $\\{x_1, x_2, x_3\\}$ +expressions for $v$ or $w$, and using the $S_u'$ equation to find the other variable: +* Assuming $x = x_1$, we find $v = x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions). +* Assuming $x = x_2$, we find $v = -u-x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions). +* Assuming $x = x_3$, we find $w = \pm\sqrt{x-u}$ and $v = -u/2 \pm \sqrt{-w^2(4g(u) + w^2h(u))}/(2w^2)$ (four solutions). + +### 3.2 Avoiding computing all inverses + +The *ElligatorSwift* algorithm as stated in Section 1 requires the computation of $L = F_u^{-1}(x)$ (the +set of all $t$ such that $(u, t)$ decode to $x$) in full. This is unnecessary. + +Observe that the procedure of restarting with probability $(1 - \frac{\\#L}{8})$ and otherwise returning a +uniformly random element from $L$ is actually equivalent to always padding $L$ with $\bot$ values up to length 8, +picking a uniformly random element from that, restarting whenever $\bot$ is picked: + +**Define** *ElligatorSwift(x)* as: +* Loop: + * Pick a uniformly random field element $u.$ + * Compute the set $L = F_u^{-1}(x).$ + * Let $T$ be the 8-element vector consisting of the elements of $L$, plus $8 - \\#L$ times $\\{\bot\\}.$ + * Select a uniformly random $t \in T.$ + * If $t \neq \bot$, return $(u, t)$; restart loop otherwise. + +Now notice that the order of elements in $T$ does not matter, as all we do is pick a uniformly +random element in it, so we do not need to have all $\bot$ values at the end. +As we have 8 distinct formulas for finding $(v, w)$ (taking the variants due to $\pm$ into account), +we can associate every index in $T$ with exactly one of those formulas, making sure that: +* Formulas that yield no solutions (due to division by zero or non-existing square roots) or invalid solutions are made to return $\bot.$ +* For the $x_1$ and $x_2$ cases, if $g(-u-x)$ is a square, $\bot$ is returned instead (the round-trip check). +* In case multiple formulas would return the same non- $\bot$ result, all but one of those must be turned into $\bot$ to avoid biasing those. + +The last condition above only occurs with negligible probability for cryptographically-sized curves, but is interesting +to take into account as it allows exhaustive testing in small groups. See [Section 3.4](#34-dealing-with-special-cases) +for an analysis of all the negligible cases. + +If we define $T = (G_{0,u}(x), G_{1,u}(x), \ldots, G_{7,u}(x))$, with each $G_{i,u}$ matching one of the formulas, +the loop can be simplified to only compute one of the inverses instead of all of them: + +**Define** *ElligatorSwift(x)* as: +* Loop: + * Pick a uniformly random field element $u.$ + * Pick a uniformly random integer $c$ in $[0,8).$ + * Let $t = G_{c,u}(x).$ + * If $t \neq \bot$, return $(u, t)$; restart loop otherwise. + +This is implemented in `secp256k1_ellswift_xelligatorswift_var`. + +### 3.3 Finding the inverse + +To implement $G_{c,u}$, we map $c=0$ to the $x_1$ formula, $c=1$ to the $x_2$ formula, and $c=2$ and $c=3$ to the $x_3$ formula. +Those are then repeated as $c=4$ through $c=7$ for the other sign of $w$ (noting that in each formula, $w$ is a square root of some expression). +Ignoring the negligible cases, we get: + +**Define** $G_{c,u}(x)$ as: +* If $c \in \\{0, 1, 4, 5\\}$ (for $x_1$ and $x_2$ formulas): + * If $g(-u-x)$ is square, return $\bot$ (as $x_3$ would be valid and take precedence). + * If $c \in \\{0, 4\\}$ (the $x_1$ formula) let $v = x$, otherwise let $v = -u-x$ (the $x_2$ formula) + * Let $s = -g(u)/(u^2 + uv + v^2 + a)$ (using $s = w^2$ in what follows). +* Otherwise, when $c \in \\{2, 3, 6, 7\\}$ (for $x_3$ formulas): + * Let $s = x-u.$ + * Let $r = \sqrt{-s(4g(u) + sh(u))}.$ + * Let $v = (r/s - u)/2$ if $c \in \\{3, 7\\}$; $(-r/s - u)/2$ otherwise. +* Let $w = \sqrt{s}.$ +* Depending on $c:$ + * If $c \in \\{0, 1, 2, 3\\}:$ return $P_u^{'-1}(v, w).$ + * If $c \in \\{4, 5, 6, 7\\}:$ return $P_u^{'-1}(v, -w).$ + +Whenever a square root of a non-square is taken, $\bot$ is returned; for both square roots this happens with roughly +50% on random inputs. Similarly, when a division by 0 would occur, $\bot$ is returned as well; this will only happen +with negligible probability. A division by 0 in the first branch in fact cannot occur at all, because $u^2 + uv + v^2 + a = 0$ +implies $g(-u-x) = g(x)$ which would mean the $g(-u-x)$ is square condition has triggered +and $\bot$ would have been returned already. + +**Note**: In the paper, the $case$ variable corresponds roughly to the $c$ above, but only takes on 4 possible values (1 to 4). +The conditional negation of $w$ at the end is done randomly, which is equivalent, but makes testing harder. We choose to +have the $G_{c,u}$ be deterministic, and capture all choices in $c.$ + +Now observe that the $c \in \\{1, 5\\}$ and $c \in \\{3, 7\\}$ conditions effectively perform the same $v \rightarrow -u-v$ +transformation. Furthermore, that transformation has no effect on $s$ in the first branch +as $u^2 + ux + x^2 + a = u^2 + u(-u-x) + (-u-x)^2 + a.$ Thus we can extract it out and move it down: + +**Define** $G_{c,u}(x)$ as: +* If $c \in \\{0, 1, 4, 5\\}:$ + * If $g(-u-x)$ is square, return $\bot.$ + * Let $s = -g(u)/(u^2 + ux + x^2 + a).$ + * Let $v = x.$ +* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ + * Let $s = x-u.$ + * Let $r = \sqrt{-s(4g(u) + sh(u))}.$ + * Let $v = (r/s - u)/2.$ +* Let $w = \sqrt{s}.$ +* Depending on $c:$ + * If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w).$ + * If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w).$ + * If $c \in \\{4, 6\\}:$ return $P_u^{'-1}(v, -w).$ + * If $c \in \\{5, 7\\}:$ return $P_u^{'-1}(-u-v, -w).$ + +This shows there will always be exactly 0, 4, or 8 $t$ values for a given $(u, x)$ input. +There can be 0, 1, or 2 $(v, w)$ pairs before invoking $P_u^{'-1}$, and each results in 4 distinct $t$ values. + +### 3.4 Dealing with special cases + +As mentioned before there are a few cases to deal with which only happen in a negligibly small subset of inputs. +For cryptographically sized fields, if only random inputs are going to be considered, it is unnecessary to deal with these. Still, for completeness +we analyse them here. They generally fall into two categories: cases in which the encoder would produce $t$ values that +do not decode back to $x$ (or at least cannot guarantee that they do), and cases in which the encoder might produce the same +$t$ value for multiple $c$ inputs (thereby biasing that encoding): + +* In the branch for $x_1$ and $x_2$ (where $c \in \\{0, 1, 4, 5\\}$): + * When $g(u) = 0$, we would have $s=w=Y=0$, which is not on $S_u.$ This is only possible on even-ordered curves. + Excluding this also removes the one condition under which the simplified check for $x_3$ on the curve + fails (namely when $g(x_1)=g(x_2)=0$ but $g(x_3)$ is not square). + This does exclude some valid encodings: when both $g(u)=0$ and $u^2+ux+x^2+a=0$ (also implying $g(x)=0$), + the $S_u'$ equation degenerates to $0 = 0$, and many valid $t$ values may exist. Yet, these cannot be targeted uniformly by the + encoder anyway as there will generally be more than 8. + * When $g(x) = 0$, the same $t$ would be produced as in the $x_3$ branch (where $c \in \\{2, 3, 6, 7\\}$) which we give precedence + as it can deal with $g(u)=0$. + This is again only possible on even-ordered curves. +* In the branch for $x_3$ (where $c \in \\{2, 3, 6, 7\\}$): + * When $s=0$, a division by zero would occur. + * When $v = -u-v$ and $c \in \\{3, 7\\}$, the same $t$ would be returned as in the $c \in \\{2, 6\\}$ cases. + It is equivalent to checking whether $r=0$. + This cannot occur in the $x_1$ or $x_2$ branches, as it would trigger the $g(-u-x)$ is square condition. + A similar concern for $w = -w$ does not exist, as $w=0$ is already impossible in both branches: in the first + it requires $g(u)=0$ which is already outlawed on even-ordered curves and impossible on others; in the second it would trigger division by zero. +* Curve-specific special cases also exist that need to be rejected, because they result in $(u,t)$ which is invalid to the decoder, or because of division by zero in the encoder: + * For $a=0$ curves, when $u=0$ or when $t=0$. The latter can only be reached by the encoder when $g(u)=0$, which requires an even-ordered curve. + * For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$. + +**Define** a version of $G_{c,u}(x)$ which deals with all these cases: +* If $a=0$ and $u=0$, return $\bot.$ +* If $a \neq 0$ and $X_0(u)=0$, return $\bot.$ +* If $c \in \\{0, 1, 4, 5\\}:$ + * If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only). + * If $g(-u-x)$ is square, return $\bot.$ + * Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero). + * Let $v = x.$ +* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ + * Let $s = x-u.$ + * Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square. + * If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$ + * If $s = 0$, return $\bot.$ + * Let $v = (r/s - u)/2.$ +* Let $w = \sqrt{s}$; return $\bot$ if not square. +* If $a \neq 0$ and $w(u+2v) = 2X_0(u)$ and either $w \neq 2Y_0(u)$ or $h(u) = 0$, return $\bot.$ +* Depending on $c:$ + * If $c \in \\{0, 2\\}$, let $t = P_u^{'-1}(v, w).$ + * If $c \in \\{1, 3\\}$, let $t = P_u^{'-1}(-u-v, w).$ + * If $c \in \\{4, 6\\}$, let $t = P_u^{'-1}(v, -w).$ + * If $c \in \\{5, 7\\}$, let $t = P_u^{'-1}(-u-v, -w).$ +* If $a=0$ and $t=0$, return $\bot$ (even curves only). +* If $a \neq 0$ and $h(u)t^2 = -1$, return $\bot.$ +* Return $t.$ + +Given any $u$, using this algorithm over all $x$ and $c$ values, every $t$ value will be reached exactly once, +for an $x$ for which $F_u(t) = x$ holds, except for these cases that will not be reached: +* All cases where $P_u(t)$ is not defined: + * For $a=0$ curves, when $u=0$, $t=0$, or $g(u) = -t^2.$ + * For $a \neq 0$ curves, when $h(u)t^2 = -1$, $X_0(u) = 0$, or $Y_0(u) (1 - h(u) t^2) = 2X_0(u)t.$ +* When $g(u)=0$, the potentially many $t$ values that decode to an $x$ satisfying $g(x)=0$ using the $x_2$ formula. These were excluded by the $g(u)=0$ condition in the $c \in \\{0, 1, 4, 5\\}$ branch. + +These cases form a negligible subset of all $(u, t)$ for cryptographically sized curves. + +### 3.5 Encoding for `secp256k1` + +Specialized for odd-ordered $a=0$ curves: + +**Define** $G_{c,u}(x)$ as: +* If $u=0$, return $\bot.$ +* If $c \in \\{0, 1, 4, 5\\}:$ + * If $(-u-x)^3 + b$ is square, return $\bot$ + * Let $s = -(u^3 + b)/(u^2 + ux + x^2)$ (cannot cause division by 0). + * Let $v = x.$ +* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ + * Let $s = x-u.$ + * Let $r = \sqrt{-s(4(u^3 + b) + 3su^2)}$; return $\bot$ if not square. + * If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$ + * If $s = 0$, return $\bot.$ + * Let $v = (r/s - u)/2.$ +* Let $w = \sqrt{s}$; return $\bot$ if not square. +* Depending on $c:$ + * If $c \in \\{0, 2\\}:$ return $w(\frac{\sqrt{-3}-1}{2}u - v).$ + * If $c \in \\{1, 3\\}:$ return $w(\frac{\sqrt{-3}+1}{2}u + v).$ + * If $c \in \\{4, 6\\}:$ return $w(\frac{-\sqrt{-3}+1}{2}u + v).$ + * If $c \in \\{5, 7\\}:$ return $w(\frac{-\sqrt{-3}-1}{2}u - v).$ + +This is implemented in `secp256k1_ellswift_xswiftec_inv_var`. + +And the x-only ElligatorSwift encoding algorithm is still: + +**Define** *ElligatorSwift(x)* as: +* Loop: + * Pick a uniformly random field element $u.$ + * Pick a uniformly random integer $c$ in $[0,8).$ + * Let $t = G_{c,u}(x).$ + * If $t \neq \bot$, return $(u, t)$; restart loop otherwise. + +Note that this logic does not take the remapped $u=0$, $t=0$, and $g(u) = -t^2$ cases into account; it just avoids them. +While it is not impossible to make the encoder target them, this would increase the maximum number of $t$ values for a given $(u, x)$ +combination beyond 8, and thereby slow down the ElligatorSwift loop proportionally, for a negligible gain in uniformity. + +## 4. Encoding and decoding full *(x, y)* coordinates + +So far we have only addressed encoding and decoding x-coordinates, but in some cases an encoding +for full points with $(x, y)$ coordinates is desirable. It is possible to encode this information +in $t$ as well. + +Note that for any $(X, Y) \in S_u$, $(\pm X, \pm Y)$ are all on $S_u.$ Moreover, all of these are +mapped to the same x-coordinate. Negating $X$ or negating $Y$ just results in $x_1$ and $x_2$ +being swapped, and does not affect $x_3.$ This will not change the outcome x-coordinate as the order +of $x_1$ and $x_2$ only matters if both were to be valid, and in that case $x_3$ would be used instead. + +Still, these four $(X, Y)$ combinations all correspond to distinct $t$ values, so we can encode +the sign of the y-coordinate in the sign of $X$ or the sign of $Y.$ They correspond to the +four distinct $P_u^{'-1}$ calls in the definition of $G_{u,c}.$ + +**Note**: In the paper, the sign of the y coordinate is encoded in a separately-coded bit. + +To encode the sign of $y$ in the sign of $Y:$ + +**Define** *Decode(u, t)* for full $(x, y)$ as: +* Let $(X, Y) = P_u(t).$ +* Let $x$ be the first value in $(u + 4Y^2, \frac{-X}{2Y} - \frac{u}{2}, \frac{X}{2Y} - \frac{u}{2})$ for which $g(x)$ is square. +* Let $y = \sqrt{g(x)}.$ +* If $sign(y) = sign(Y)$, return $(x, y)$; otherwise return $(x, -y).$ + +And encoding would be done using a $G_{c,u}(x, y)$ function defined as: + +**Define** $G_{c,u}(x, y)$ as: +* If $c \in \\{0, 1\\}:$ + * If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only). + * If $g(-u-x)$ is square, return $\bot.$ + * Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero). + * Let $v = x.$ +* Otherwise, when $c \in \\{2, 3\\}:$ + * Let $s = x-u.$ + * Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square. + * If $c = 3$ and $r = 0$, return $\bot.$ + * Let $v = (r/s - u)/2.$ +* Let $w = \sqrt{s}$; return $\bot$ if not square. +* Let $w' = w$ if $sign(w/2) = sign(y)$; $-w$ otherwise. +* Depending on $c:$ + * If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w').$ + * If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w').$ + +Note that $c$ now only ranges $[0,4)$, as the sign of $w'$ is decided based on that of $y$, rather than on $c.$ +This change makes some valid encodings unreachable: when $y = 0$ and $sign(Y) \neq sign(0)$. + +In the above logic, $sign$ can be implemented in several ways, such as parity of the integer representation +of the input field element (for prime-sized fields) or the quadratic residuosity (for fields where +$-1$ is not square). The choice does not matter, as long as it only takes on two possible values, and for $x \neq 0$ it holds that $sign(x) \neq sign(-x)$. + +### 4.1 Full *(x, y)* coordinates for `secp256k1` + +For $a=0$ curves, there is another option. Note that for those, +the $P_u(t)$ function translates negations of $t$ to negations of (both) $X$ and $Y.$ Thus, we can use $sign(t)$ to +encode the y-coordinate directly. Combined with the earlier remapping to guarantee all inputs land on the curve, we get +as decoder: + +**Define** *Decode(u, t)* as: +* Let $u'=u$ if $u \neq 0$; $1$ otherwise. +* Let $t'=t$ if $t \neq 0$; $1$ otherwise. +* Let $t''=t'$ if $u'^3 + b + t'^2 \neq 0$; $2t'$ otherwise. +* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$ +* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$ +* Let $x$ be the first element of $(u' + 4Y^2, \frac{-X}{2Y} - \frac{u'}{2}, \frac{X}{2Y} - \frac{u'}{2})$ for which $g(x)$ is square. +* Let $y = \sqrt{g(x)}.$ +* Return $(x, y)$ if $sign(y) = sign(t)$; $(x, -y)$ otherwise. + +This is implemented in `secp256k1_ellswift_swiftec_var`. The used $sign(x)$ function is the parity of $x$ when represented as in integer in $[0,q).$ + +The corresponding encoder would invoke the x-only one, but negating the output $t$ if $sign(t) \neq sign(y).$ + +This is implemented in `secp256k1_ellswift_elligatorswift_var`. + +Note that this is only intended for encoding points where both the x-coordinate and y-coordinate are unpredictable. When encoding x-only points +where the y-coordinate is implicitly even (or implicitly square, or implicitly in $[0,q/2]$), the encoder in +[Section 3.5](#35-encoding-for-secp256k1) must be used, or a bias is reintroduced that undoes all the benefit of using ElligatorSwift +in the first place. diff --git a/crypto/secp256k1/libsecp256k1/doc/musig.md b/crypto/secp256k1/libsecp256k1/doc/musig.md new file mode 100644 index 0000000000..ae21f9b131 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/doc/musig.md @@ -0,0 +1,54 @@ +Notes on the musig module API +=========================== + +The following sections contain additional notes on the API of the musig module (`include/secp256k1_musig.h`). +A usage example can be found in `examples/musig.c`. + +## API misuse + +The musig API is designed with a focus on misuse resistance. +However, due to the interactive nature of the MuSig protocol, there are additional failure modes that are not present in regular (single-party) Schnorr signature creation. +While the results can be catastrophic (e.g. leaking of the secret key), it is unfortunately not possible for the musig implementation to prevent all such failure modes. + +Therefore, users of the musig module must take great care to make sure of the following: + +1. A unique nonce per signing session is generated in `secp256k1_musig_nonce_gen`. + See the corresponding comment in `include/secp256k1_musig.h` for how to ensure that. +2. The `secp256k1_musig_secnonce` structure is never copied or serialized. + See also the comment on `secp256k1_musig_secnonce` in `include/secp256k1_musig.h`. +3. Opaque data structures are never written to or read from directly. + Instead, only the provided accessor functions are used. + +## Key Aggregation and (Taproot) Tweaking + +Given a set of public keys, the aggregate public key is computed with `secp256k1_musig_pubkey_agg`. +A plain tweak can be added to the resulting public key with `secp256k1_ec_pubkey_tweak_add` by setting the `tweak32` argument to the hash defined in BIP 32. Similarly, a Taproot tweak can be added with `secp256k1_xonly_pubkey_tweak_add` by setting the `tweak32` argument to the TapTweak hash defined in BIP 341. +Both types of tweaking can be combined and invoked multiple times if the specific application requires it. + +## Signing + +This is covered by `examples/musig.c`. +Essentially, the protocol proceeds in the following steps: + +1. Generate a keypair with `secp256k1_keypair_create` and obtain the public key with `secp256k1_keypair_pub`. +2. Call `secp256k1_musig_pubkey_agg` with the pubkeys of all participants. +3. Optionally add a (Taproot) tweak with `secp256k1_musig_pubkey_xonly_tweak_add` and a plain tweak with `secp256k1_musig_pubkey_ec_tweak_add`. +4. Generate a pair of secret and public nonce with `secp256k1_musig_nonce_gen` and send the public nonce to the other signers. +5. Someone (not necessarily the signer) aggregates the public nonces with `secp256k1_musig_nonce_agg` and sends it to the signers. +6. Process the aggregate nonce with `secp256k1_musig_nonce_process`. +7. Create a partial signature with `secp256k1_musig_partial_sign`. +8. Verify the partial signatures (optional in some scenarios) with `secp256k1_musig_partial_sig_verify`. +9. Someone (not necessarily the signer) obtains all partial signatures and aggregates them into the final Schnorr signature using `secp256k1_musig_partial_sig_agg`. + +The aggregate signature can be verified with `secp256k1_schnorrsig_verify`. + +Steps 1 through 5 above can occur before or after the signers are aware of the message to be signed. +Whenever possible, it is recommended to generate the nonces only after the message is known. +This provides enhanced defense-in-depth measures, protecting against potential API misuse in certain scenarios. +However, it does require two rounds of communication during the signing process. +The alternative, generating the nonces in a pre-processing step before the message is known, eliminates these additional protective measures but allows for non-interactive signing. +Similarly, the API supports an alternative protocol flow where generating the aggregate key (steps 1 to 3) is allowed to happen after exchanging nonces (steps 4 to 5). + +## Verification + +A participant who wants to verify the partial signatures, but does not sign itself may do so using the above instructions except that the verifier skips steps 1, 4 and 7. diff --git a/crypto/secp256k1/libsecp256k1/doc/release-process.md b/crypto/secp256k1/libsecp256k1/doc/release-process.md new file mode 100644 index 0000000000..a64bae0f0d --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/doc/release-process.md @@ -0,0 +1,94 @@ +# Release process + +This document outlines the process for releasing versions of the form `$MAJOR.$MINOR.$PATCH`. + +We distinguish between two types of releases: *regular* and *maintenance* releases. +Regular releases are releases of a new major or minor version as well as patches of the most recent release. +Maintenance releases, on the other hand, are required for patches of older releases. + +You should coordinate with the other maintainers on the release date, if possible. +This date will be part of the release entry in [CHANGELOG.md](../CHANGELOG.md) and it should match the dates of the remaining steps in the release process (including the date of the tag and the GitHub release). +It is best if the maintainers are present during the release, so they can help ensure that the process is followed correctly and, in the case of a regular release, they are aware that they should not modify the master branch between merging the PR in step 1 and the PR in step 3. + +This process also assumes that there will be no minor releases for old major releases. + +We aim to cut a regular release every 3-4 months, approximately twice as frequent as major Bitcoin Core releases. Every second release should be published one month before the feature freeze of the next major Bitcoin Core release, allowing sufficient time to update the library in Core. + +## Sanity checks +Perform these checks when reviewing the release PR (see below): + +1. Ensure `make distcheck` doesn't fail. + ```shell + ./autogen.sh && ./configure --enable-dev-mode && make distcheck + ``` +2. Check installation with autotools: + ```shell + dir=$(mktemp -d) + ./autogen.sh && ./configure --prefix=$dir && make clean && make install && ls -RlAh $dir + gcc -o ecdsa examples/ecdsa.c $(PKG_CONFIG_PATH=$dir/lib/pkgconfig pkg-config --cflags --libs libsecp256k1) -Wl,-rpath,"$dir/lib" && ./ecdsa + ``` +3. Check installation with CMake: + ```shell + dir=$(mktemp -d) + build=$(mktemp -d) + cmake -B $build -DCMAKE_INSTALL_PREFIX=$dir && cmake --build $build && cmake --install $build && ls -RlAh $dir + gcc -o ecdsa examples/ecdsa.c -I $dir/include -L $dir/lib*/ -l secp256k1 -Wl,-rpath,"$dir/lib",-rpath,"$dir/lib64" && ./ecdsa + ``` +4. Use the [`check-abi.sh`](/tools/check-abi.sh) tool to verify that there are no unexpected ABI incompatibilities and that the version number and the release notes accurately reflect all potential ABI changes. To run this tool, the `abi-dumper` and `abi-compliance-checker` packages are required. + ```shell + tools/check-abi.sh + ``` + +## Regular release + +1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that + * finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) by + * adding a section for the release (make sure that the version number is a link to a diff between the previous and new version), + * removing the `[Unreleased]` section header, + * ensuring that the release notes are not missing entries (check the `needs-changelog` label on github), and + * including an entry for `### ABI Compatibility` if it doesn't exist, + * sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`, and, + * if this is not a patch release, + * updates `_PKG_VERSION_*` and `_LIB_VERSION_*` in `configure.ac`, and + * updates `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_*` in `CMakeLists.txt`. +2. Perform the [sanity checks](#sanity-checks) on the PR branch. +3. After the PR is merged, tag the commit, and push the tag: + ``` + RELEASE_COMMIT= + git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" $RELEASE_COMMIT + git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH + ``` +4. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that + * sets `_PKG_VERSION_IS_RELEASE` to `false` and increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`, + * increments the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`, and + * adds an `[Unreleased]` section header to the [CHANGELOG.md](../CHANGELOG.md). + + If other maintainers are not present to approve the PR, it can be merged without ACKs. +5. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md). +6. Send an announcement email to the bitcoin-dev mailing list. + +## Maintenance release + +Note that bug fixes need to be backported only to releases for which no compatible release without the bug exists. + +1. If there's no maintenance branch `$MAJOR.$MINOR`, create one: + ``` + git checkout -b $MAJOR.$MINOR v$MAJOR.$MINOR.$((PATCH - 1)) + git push git@github.com:bitcoin-core/secp256k1.git $MAJOR.$MINOR + ``` +2. Open a pull request to the `$MAJOR.$MINOR` branch that + * includes the bug fixes, + * finalizes the release notes similar to a regular release, + * increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac` + and the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt` + (with commit message `"release: bump versions for $MAJOR.$MINOR.$PATCH"`, for example). +3. Perform the [sanity checks](#sanity-checks) on the PR branch. +4. After the PRs are merged, update the release branch, tag the commit, and push the tag: + ``` + git checkout $MAJOR.$MINOR && git pull + git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" + git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH + ``` +6. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md). +7. Send an announcement email to the bitcoin-dev mailing list. +8. Open PR to the master branch that includes a commit (with commit message `"release notes: add $MAJOR.$MINOR.$PATCH"`, for example) that adds release notes to [CHANGELOG.md](../CHANGELOG.md). diff --git a/crypto/secp256k1/libsecp256k1/doc/safegcd_implementation.md b/crypto/secp256k1/libsecp256k1/doc/safegcd_implementation.md new file mode 100644 index 0000000000..5dbbb7bbd2 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/doc/safegcd_implementation.md @@ -0,0 +1,819 @@ +# The safegcd implementation in libsecp256k1 explained + +This document explains the modular inverse and Jacobi symbol implementations in the `src/modinv*.h` files. +It is based on the paper +["Fast constant-time gcd computation and modular inversion"](https://gcd.cr.yp.to/papers.html#safegcd) +by Daniel J. Bernstein and Bo-Yin Yang. The references below are for the Date: 2019.04.13 version. + +The actual implementation is in C of course, but for demonstration purposes Python3 is used here. +Most implementation aspects and optimizations are explained, except those that depend on the specific +number representation used in the C code. + +## 1. Computing the Greatest Common Divisor (GCD) using divsteps + +The algorithm from the paper (section 11), at a very high level, is this: + +```python +def gcd(f, g): + """Compute the GCD of an odd integer f and another integer g.""" + assert f & 1 # require f to be odd + delta = 1 # additional state variable + while g != 0: + assert f & 1 # f will be odd in every iteration + if delta > 0 and g & 1: + delta, f, g = 1 - delta, g, (g - f) // 2 + elif g & 1: + delta, f, g = 1 + delta, f, (g + f) // 2 + else: + delta, f, g = 1 + delta, f, (g ) // 2 + return abs(f) +``` + +It computes the greatest common divisor of an odd integer *f* and any integer *g*. Its inner loop +keeps rewriting the variables *f* and *g* alongside a state variable *δ* that starts at *1*, until +*g=0* is reached. At that point, *|f|* gives the GCD. Each of the transitions in the loop is called a +"division step" (referred to as divstep in what follows). + +For example, *gcd(21, 14)* would be computed as: +- Start with *δ=1 f=21 g=14* +- Take the third branch: *δ=2 f=21 g=7* +- Take the first branch: *δ=-1 f=7 g=-7* +- Take the second branch: *δ=0 f=7 g=0* +- The answer *|f| = 7*. + +Why it works: +- Divsteps can be decomposed into two steps (see paragraph 8.2 in the paper): + - (a) If *g* is odd, replace *(f,g)* with *(g,g-f)* or (f,g+f), resulting in an even *g*. + - (b) Replace *(f,g)* with *(f,g/2)* (where *g* is guaranteed to be even). +- Neither of those two operations change the GCD: + - For (a), assume *gcd(f,g)=c*, then it must be the case that *f=a c* and *g=b c* for some integers *a* + and *b*. As *(g,g-f)=(b c,(b-a)c)* and *(f,f+g)=(a c,(a+b)c)*, the result clearly still has + common factor *c*. Reasoning in the other direction shows that no common factor can be added by + doing so either. + - For (b), we know that *f* is odd, so *gcd(f,g)* clearly has no factor *2*, and we can remove + it from *g*. +- The algorithm will eventually converge to *g=0*. This is proven in the paper (see theorem G.3). +- It follows that eventually we find a final value *f'* for which *gcd(f,g) = gcd(f',0)*. As the + gcd of *f'* and *0* is *|f'|* by definition, that is our answer. + +Compared to more [traditional GCD algorithms](https://en.wikipedia.org/wiki/Euclidean_algorithm), this one has the property of only ever looking at +the low-order bits of the variables to decide the next steps, and being easy to make +constant-time (in more low-level languages than Python). The *δ* parameter is necessary to +guide the algorithm towards shrinking the numbers' magnitudes without explicitly needing to look +at high order bits. + +Properties that will become important later: +- Performing more divsteps than needed is not a problem, as *f* does not change anymore after *g=0*. +- Only even numbers are divided by *2*. This means that when reasoning about it algebraically we + do not need to worry about rounding. +- At every point during the algorithm's execution the next *N* steps only depend on the bottom *N* + bits of *f* and *g*, and on *δ*. + + +## 2. From GCDs to modular inverses + +We want an algorithm to compute the inverse *a* of *x* modulo *M*, i.e. the number a such that *a x=1 +mod M*. This inverse only exists if the GCD of *x* and *M* is *1*, but that is always the case if *M* is +prime and *0 < x < M*. In what follows, assume that the modular inverse exists. +It turns out this inverse can be computed as a side effect of computing the GCD by keeping track +of how the internal variables can be written as linear combinations of the inputs at every step +(see the [extended Euclidean algorithm](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm)). +Since the GCD is *1*, such an algorithm will compute numbers *a* and *b* such that a x + b M = 1*. +Taking that expression *mod M* gives *a x mod M = 1*, and we see that *a* is the modular inverse of *x +mod M*. + +A similar approach can be used to calculate modular inverses using the divsteps-based GCD +algorithm shown above, if the modulus *M* is odd. To do so, compute *gcd(f=M,g=x)*, while keeping +track of extra variables *d* and *e*, for which at every step *d = f/x (mod M)* and *e = g/x (mod M)*. +*f/x* here means the number which multiplied with *x* gives *f mod M*. As *f* and *g* are initialized to *M* +and *x* respectively, *d* and *e* just start off being *0* (*M/x mod M = 0/x mod M = 0*) and *1* (*x/x mod M += 1*). + +```python +def div2(M, x): + """Helper routine to compute x/2 mod M (where M is odd).""" + assert M & 1 + if x & 1: # If x is odd, make it even by adding M. + x += M + # x must be even now, so a clean division by 2 is possible. + return x // 2 + +def modinv(M, x): + """Compute the inverse of x mod M (given that it exists, and M is odd).""" + assert M & 1 + delta, f, g, d, e = 1, M, x, 0, 1 + while g != 0: + # Note that while division by two for f and g is only ever done on even inputs, this is + # not true for d and e, so we need the div2 helper function. + if delta > 0 and g & 1: + delta, f, g, d, e = 1 - delta, g, (g - f) // 2, e, div2(M, e - d) + elif g & 1: + delta, f, g, d, e = 1 + delta, f, (g + f) // 2, d, div2(M, e + d) + else: + delta, f, g, d, e = 1 + delta, f, (g ) // 2, d, div2(M, e ) + # Verify that the invariants d=f/x mod M, e=g/x mod M are maintained. + assert f % M == (d * x) % M + assert g % M == (e * x) % M + assert f == 1 or f == -1 # |f| is the GCD, it must be 1 + # Because of invariant d = f/x (mod M), 1/x = d/f (mod M). As |f|=1, d/f = d*f. + return (d * f) % M +``` + +Also note that this approach to track *d* and *e* throughout the computation to determine the inverse +is different from the paper. There (see paragraph 12.1 in the paper) a transition matrix for the +entire computation is determined (see section 3 below) and the inverse is computed from that. +The approach here avoids the need for 2x2 matrix multiplications of various sizes, and appears to +be faster at the level of optimization we're able to do in C. + + +## 3. Batching multiple divsteps + +Every divstep can be expressed as a matrix multiplication, applying a transition matrix *(1/2 t)* +to both vectors *[f, g]* and *[d, e]* (see paragraph 8.1 in the paper): + +``` + t = [ u, v ] + [ q, r ] + + [ out_f ] = (1/2 * t) * [ in_f ] + [ out_g ] = [ in_g ] + + [ out_d ] = (1/2 * t) * [ in_d ] (mod M) + [ out_e ] [ in_e ] +``` + +where *(u, v, q, r)* is *(0, 2, -1, 1)*, *(2, 0, 1, 1)*, or *(2, 0, 0, 1)*, depending on which branch is +taken. As above, the resulting *f* and *g* are always integers. + +Performing multiple divsteps corresponds to a multiplication with the product of all the +individual divsteps' transition matrices. As each transition matrix consists of integers +divided by *2*, the product of these matrices will consist of integers divided by *2N* (see also +theorem 9.2 in the paper). These divisions are expensive when updating *d* and *e*, so we delay +them: we compute the integer coefficients of the combined transition matrix scaled by *2N*, and +do one division by *2N* as a final step: + +```python +def divsteps_n_matrix(delta, f, g): + """Compute delta and transition matrix t after N divsteps (multiplied by 2^N).""" + u, v, q, r = 1, 0, 0, 1 # start with identity matrix + for _ in range(N): + if delta > 0 and g & 1: + delta, f, g, u, v, q, r = 1 - delta, g, (g - f) // 2, 2*q, 2*r, q-u, r-v + elif g & 1: + delta, f, g, u, v, q, r = 1 + delta, f, (g + f) // 2, 2*u, 2*v, q+u, r+v + else: + delta, f, g, u, v, q, r = 1 + delta, f, (g ) // 2, 2*u, 2*v, q , r + return delta, (u, v, q, r) +``` + +As the branches in the divsteps are completely determined by the bottom *N* bits of *f* and *g*, this +function to compute the transition matrix only needs to see those bottom bits. Furthermore all +intermediate results and outputs fit in *(N+1)*-bit numbers (unsigned for *f* and *g*; signed for *u*, *v*, +*q*, and *r*) (see also paragraph 8.3 in the paper). This means that an implementation using 64-bit +integers could set *N=62* and compute the full transition matrix for 62 steps at once without any +big integer arithmetic at all. This is the reason why this algorithm is efficient: it only needs +to update the full-size *f*, *g*, *d*, and *e* numbers once every *N* steps. + +We still need functions to compute: + +``` + [ out_f ] = (1/2^N * [ u, v ]) * [ in_f ] + [ out_g ] ( [ q, r ]) [ in_g ] + + [ out_d ] = (1/2^N * [ u, v ]) * [ in_d ] (mod M) + [ out_e ] ( [ q, r ]) [ in_e ] +``` + +Because the divsteps transformation only ever divides even numbers by two, the result of *t [f,g]* is always even. When *t* is a composition of *N* divsteps, it follows that the resulting *f* +and *g* will be multiple of *2N*, and division by *2N* is simply shifting them down: + +```python +def update_fg(f, g, t): + """Multiply matrix t/2^N with [f, g].""" + u, v, q, r = t + cf, cg = u*f + v*g, q*f + r*g + # (t / 2^N) should cleanly apply to [f,g] so the result of t*[f,g] should have N zero + # bottom bits. + assert cf % 2**N == 0 + assert cg % 2**N == 0 + return cf >> N, cg >> N +``` + +The same is not true for *d* and *e*, and we need an equivalent of the `div2` function for division by *2N mod M*. +This is easy if we have precomputed *1/M mod 2N* (which always exists for odd *M*): + +```python +def div2n(M, Mi, x): + """Compute x/2^N mod M, given Mi = 1/M mod 2^N.""" + assert (M * Mi) % 2**N == 1 + # Find a factor m such that m*M has the same bottom N bits as x. We want: + # (m * M) mod 2^N = x mod 2^N + # <=> m mod 2^N = (x / M) mod 2^N + # <=> m mod 2^N = (x * Mi) mod 2^N + m = (Mi * x) % 2**N + # Subtract that multiple from x, cancelling its bottom N bits. + x -= m * M + # Now a clean division by 2^N is possible. + assert x % 2**N == 0 + return (x >> N) % M + +def update_de(d, e, t, M, Mi): + """Multiply matrix t/2^N with [d, e], modulo M.""" + u, v, q, r = t + cd, ce = u*d + v*e, q*d + r*e + return div2n(M, Mi, cd), div2n(M, Mi, ce) +``` + +With all of those, we can write a version of `modinv` that performs *N* divsteps at once: + +```python3 +def modinv(M, Mi, x): + """Compute the modular inverse of x mod M, given Mi=1/M mod 2^N.""" + assert M & 1 + delta, f, g, d, e = 1, M, x, 0, 1 + while g != 0: + # Compute the delta and transition matrix t for the next N divsteps (this only needs + # (N+1)-bit signed integer arithmetic). + delta, t = divsteps_n_matrix(delta, f % 2**N, g % 2**N) + # Apply the transition matrix t to [f, g]: + f, g = update_fg(f, g, t) + # Apply the transition matrix t to [d, e]: + d, e = update_de(d, e, t, M, Mi) + return (d * f) % M +``` + +This means that in practice we'll always perform a multiple of *N* divsteps. This is not a problem +because once *g=0*, further divsteps do not affect *f*, *g*, *d*, or *e* anymore (only *δ* keeps +increasing). For variable time code such excess iterations will be mostly optimized away in later +sections. + + +## 4. Avoiding modulus operations + +So far, there are two places where we compute a remainder of big numbers modulo *M*: at the end of +`div2n` in every `update_de`, and at the very end of `modinv` after potentially negating *d* due to the +sign of *f*. These are relatively expensive operations when done generically. + +To deal with the modulus operation in `div2n`, we simply stop requiring *d* and *e* to be in range +*[0,M)* all the time. Let's start by inlining `div2n` into `update_de`, and dropping the modulus +operation at the end: + +```python +def update_de(d, e, t, M, Mi): + """Multiply matrix t/2^N with [d, e] mod M, given Mi=1/M mod 2^N.""" + u, v, q, r = t + cd, ce = u*d + v*e, q*d + r*e + # Cancel out bottom N bits of cd and ce. + md = -((Mi * cd) % 2**N) + me = -((Mi * ce) % 2**N) + cd += md * M + ce += me * M + # And cleanly divide by 2**N. + return cd >> N, ce >> N +``` + +Let's look at bounds on the ranges of these numbers. It can be shown that *|u|+|v|* and *|q|+|r|* +never exceed *2N* (see paragraph 8.3 in the paper), and thus a multiplication with *t* will have +outputs whose absolute values are at most *2N* times the maximum absolute input value. In case the +inputs *d* and *e* are in *(-M,M)*, which is certainly true for the initial values *d=0* and *e=1* assuming +*M > 1*, the multiplication results in numbers in range *(-2NM,2NM)*. Subtracting less than *2N* +times *M* to cancel out *N* bits brings that up to *(-2N+1M,2NM)*, and +dividing by *2N* at the end takes it to *(-2M,M)*. Another application of `update_de` would take that +to *(-3M,2M)*, and so forth. This progressive expansion of the variables' ranges can be +counteracted by incrementing *d* and *e* by *M* whenever they're negative: + +```python + ... + if d < 0: + d += M + if e < 0: + e += M + cd, ce = u*d + v*e, q*d + r*e + # Cancel out bottom N bits of cd and ce. + ... +``` + +With inputs in *(-2M,M)*, they will first be shifted into range *(-M,M)*, which means that the +output will again be in *(-2M,M)*, and this remains the case regardless of how many `update_de` +invocations there are. In what follows, we will try to make this more efficient. + +Note that increasing *d* by *M* is equal to incrementing *cd* by *u M* and *ce* by *q M*. Similarly, +increasing *e* by *M* is equal to incrementing *cd* by *v M* and *ce* by *r M*. So we could instead write: + +```python + ... + cd, ce = u*d + v*e, q*d + r*e + # Perform the equivalent of incrementing d, e by M when they're negative. + if d < 0: + cd += u*M + ce += q*M + if e < 0: + cd += v*M + ce += r*M + # Cancel out bottom N bits of cd and ce. + md = -((Mi * cd) % 2**N) + me = -((Mi * ce) % 2**N) + cd += md * M + ce += me * M + ... +``` + +Now note that we have two steps of corrections to *cd* and *ce* that add multiples of *M*: this +increment, and the decrement that cancels out bottom bits. The second one depends on the first +one, but they can still be efficiently combined by only computing the bottom bits of *cd* and *ce* +at first, and using that to compute the final *md*, *me* values: + +```python +def update_de(d, e, t, M, Mi): + """Multiply matrix t/2^N with [d, e], modulo M.""" + u, v, q, r = t + md, me = 0, 0 + # Compute what multiples of M to add to cd and ce. + if d < 0: + md += u + me += q + if e < 0: + md += v + me += r + # Compute bottom N bits of t*[d,e] + M*[md,me]. + cd, ce = (u*d + v*e + md*M) % 2**N, (q*d + r*e + me*M) % 2**N + # Correct md and me such that the bottom N bits of t*[d,e] + M*[md,me] are zero. + md -= (Mi * cd) % 2**N + me -= (Mi * ce) % 2**N + # Do the full computation. + cd, ce = u*d + v*e + md*M, q*d + r*e + me*M + # And cleanly divide by 2**N. + return cd >> N, ce >> N +``` + +One last optimization: we can avoid the *md M* and *me M* multiplications in the bottom bits of *cd* +and *ce* by moving them to the *md* and *me* correction: + +```python + ... + # Compute bottom N bits of t*[d,e]. + cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N + # Correct md and me such that the bottom N bits of t*[d,e]+M*[md,me] are zero. + # Note that this is not the same as {md = (-Mi * cd) % 2**N} etc. That would also result in N + # zero bottom bits, but isn't guaranteed to be a reduction of [0,2^N) compared to the + # previous md and me values, and thus would violate our bounds analysis. + md -= (Mi*cd + md) % 2**N + me -= (Mi*ce + me) % 2**N + ... +``` + +The resulting function takes *d* and *e* in range *(-2M,M)* as inputs, and outputs values in the same +range. That also means that the *d* value at the end of `modinv` will be in that range, while we want +a result in *[0,M)*. To do that, we need a normalization function. It's easy to integrate the +conditional negation of *d* (based on the sign of *f*) into it as well: + +```python +def normalize(sign, v, M): + """Compute sign*v mod M, where v is in range (-2*M,M); output in [0,M).""" + assert sign == 1 or sign == -1 + # v in (-2*M,M) + if v < 0: + v += M + # v in (-M,M). Now multiply v with sign (which can only be 1 or -1). + if sign == -1: + v = -v + # v in (-M,M) + if v < 0: + v += M + # v in [0,M) + return v +``` + +And calling it in `modinv` is simply: + +```python + ... + return normalize(f, d, M) +``` + + +## 5. Constant-time operation + +The primary selling point of the algorithm is fast constant-time operation. What code flow still +depends on the input data so far? + +- the number of iterations of the while *g ≠ 0* loop in `modinv` +- the branches inside `divsteps_n_matrix` +- the sign checks in `update_de` +- the sign checks in `normalize` + +To make the while loop in `modinv` constant time it can be replaced with a constant number of +iterations. The paper proves (Theorem 11.2) that *741* divsteps are sufficient for any *256*-bit +inputs, and [safegcd-bounds](https://github.com/sipa/safegcd-bounds) shows that the slightly better bound *724* is +sufficient even. Given that every loop iteration performs *N* divsteps, it will run a total of +*⌈724/N⌉* times. + +To deal with the branches in `divsteps_n_matrix` we will replace them with constant-time bitwise +operations (and hope the C compiler isn't smart enough to turn them back into branches; see +`ctime_tests.c` for automated tests that this isn't the case). To do so, observe that a +divstep can be written instead as (compare to the inner loop of `gcd` in section 1). + +```python + x = -f if delta > 0 else f # set x equal to (input) -f or f + if g & 1: + g += x # set g to (input) g-f or g+f + if delta > 0: + delta = -delta + f += g # set f to (input) g (note that g was set to g-f before) + delta += 1 + g >>= 1 +``` + +To convert the above to bitwise operations, we rely on a trick to negate conditionally: per the +definition of negative numbers in two's complement, (*-v == ~v + 1*) holds for every number *v*. As +*-1* in two's complement is all *1* bits, bitflipping can be expressed as xor with *-1*. It follows +that *-v == (v ^ -1) - (-1)*. Thus, if we have a variable *c* that takes on values *0* or *-1*, then +*(v ^ c) - c* is *v* if *c=0* and *-v* if *c=-1*. + +Using this we can write: + +```python + x = -f if delta > 0 else f +``` + +in constant-time form as: + +```python + c1 = (-delta) >> 63 + # Conditionally negate f based on c1: + x = (f ^ c1) - c1 +``` + +To use that trick, we need a helper mask variable *c1* that resolves the condition *δ>0* to *-1* +(if true) or *0* (if false). We compute *c1* using right shifting, which is equivalent to dividing by +the specified power of *2* and rounding down (in Python, and also in C under the assumption of a typical two's complement system; see +`assumptions.h` for tests that this is the case). Right shifting by *63* thus maps all +numbers in range *[-263,0)* to *-1*, and numbers in range *[0,263)* to *0*. + +Using the facts that *x&0=0* and *x&(-1)=x* (on two's complement systems again), we can write: + +```python + if g & 1: + g += x +``` + +as: + +```python + # Compute c2=0 if g is even and c2=-1 if g is odd. + c2 = -(g & 1) + # This masks out x if g is even, and leaves x be if g is odd. + g += x & c2 +``` + +Using the conditional negation trick again we can write: + +```python + if g & 1: + if delta > 0: + delta = -delta +``` + +as: + +```python + # Compute c3=-1 if g is odd and delta>0, and 0 otherwise. + c3 = c1 & c2 + # Conditionally negate delta based on c3: + delta = (delta ^ c3) - c3 +``` + +Finally: + +```python + if g & 1: + if delta > 0: + f += g +``` + +becomes: + +```python + f += g & c3 +``` + +It turns out that this can be implemented more efficiently by applying the substitution +*η=-δ*. In this representation, negating *δ* corresponds to negating *η*, and incrementing +*δ* corresponds to decrementing *η*. This allows us to remove the negation in the *c1* +computation: + +```python + # Compute a mask c1 for eta < 0, and compute the conditional negation x of f: + c1 = eta >> 63 + x = (f ^ c1) - c1 + # Compute a mask c2 for odd g, and conditionally add x to g: + c2 = -(g & 1) + g += x & c2 + # Compute a mask c for (eta < 0) and odd (input) g, and use it to conditionally negate eta, + # and add g to f: + c3 = c1 & c2 + eta = (eta ^ c3) - c3 + f += g & c3 + # Incrementing delta corresponds to decrementing eta. + eta -= 1 + g >>= 1 +``` + +A variant of divsteps with better worst-case performance can be used instead: starting *δ* at +*1/2* instead of *1*. This reduces the worst case number of iterations to *590* for *256*-bit inputs +(which can be shown using convex hull analysis). In this case, the substitution *ζ=-(δ+1/2)* +is used instead to keep the variable integral. Incrementing *δ* by *1* still translates to +decrementing *ζ* by *1*, but negating *δ* now corresponds to going from *ζ* to *-(ζ+1)*, or +*~ζ*. Doing that conditionally based on *c3* is simply: + +```python + ... + c3 = c1 & c2 + zeta ^= c3 + ... +``` + +By replacing the loop in `divsteps_n_matrix` with a variant of the divstep code above (extended to +also apply all *f* operations to *u*, *v* and all *g* operations to *q*, *r*), a constant-time version of +`divsteps_n_matrix` is obtained. The full code will be in section 7. + +These bit fiddling tricks can also be used to make the conditional negations and additions in +`update_de` and `normalize` constant-time. + + +## 6. Variable-time optimizations + +In section 5, we modified the `divsteps_n_matrix` function (and a few others) to be constant time. +Constant time operations are only necessary when computing modular inverses of secret data. In +other cases, it slows down calculations unnecessarily. In this section, we will construct a +faster non-constant time `divsteps_n_matrix` function. + +To do so, first consider yet another way of writing the inner loop of divstep operations in +`gcd` from section 1. This decomposition is also explained in the paper in section 8.2. We use +the original version with initial *δ=1* and *η=-δ* here. + +```python +for _ in range(N): + if g & 1 and eta < 0: + eta, f, g = -eta, g, -f + if g & 1: + g += f + eta -= 1 + g >>= 1 +``` + +Whenever *g* is even, the loop only shifts *g* down and decreases *η*. When *g* ends in multiple zero +bits, these iterations can be consolidated into one step. This requires counting the bottom zero +bits efficiently, which is possible on most platforms; it is abstracted here as the function +`count_trailing_zeros`. + +```python +def count_trailing_zeros(v): + """ + When v is zero, consider all N zero bits as "trailing". + For a non-zero value v, find z such that v=(d<>= zeros + i -= zeros + if i == 0: + break + # We know g is odd now + if eta < 0: + eta, f, g = -eta, g, -f + g += f + # g is even now, and the eta decrement and g shift will happen in the next loop. +``` + +We can now remove multiple bottom *0* bits from *g* at once, but still need a full iteration whenever +there is a bottom *1* bit. In what follows, we will get rid of multiple *1* bits simultaneously as +well. + +Observe that as long as *η ≥ 0*, the loop does not modify *f*. Instead, it cancels out bottom +bits of *g* and shifts them out, and decreases *η* and *i* accordingly - interrupting only when *η* +becomes negative, or when *i* reaches *0*. Combined, this is equivalent to adding a multiple of *f* to +*g* to cancel out multiple bottom bits, and then shifting them out. + +It is easy to find what that multiple is: we want a number *w* such that *g+w f* has a few bottom +zero bits. If that number of bits is *L*, we want *g+w f mod 2L = 0*, or *w = -g/f mod 2L*. Since *f* +is odd, such a *w* exists for any *L*. *L* cannot be more than *i* steps (as we'd finish the loop before +doing more) or more than *η+1* steps (as we'd run `eta, f, g = -eta, g, -f` at that point), but +apart from that, we're only limited by the complexity of computing *w*. + +This code demonstrates how to cancel up to 4 bits per step: + +```python +NEGINV16 = [15, 5, 3, 9, 7, 13, 11, 1] # NEGINV16[n//2] = (-n)^-1 mod 16, for odd n +i = N +while True: + zeros = min(i, count_trailing_zeros(g)) + eta -= zeros + g >>= zeros + i -= zeros + if i == 0: + break + # We know g is odd now + if eta < 0: + eta, f, g = -eta, g, -f + # Compute limit on number of bits to cancel + limit = min(min(eta + 1, i), 4) + # Compute w = -g/f mod 2**limit, using the table value for -1/f mod 2**4. Note that f is + # always odd, so its inverse modulo a power of two always exists. + w = (g * NEGINV16[(f & 15) // 2]) % (2**limit) + # As w = -g/f mod (2**limit), g+w*f mod 2**limit = 0 mod 2**limit. + g += w * f + assert g % (2**limit) == 0 + # The next iteration will now shift out at least limit bottom zero bits from g. +``` + +By using a bigger table more bits can be cancelled at once. The table can also be implemented +as a formula. Several formulas are known for computing modular inverses modulo powers of two; +some can be found in Hacker's Delight second edition by Henry S. Warren, Jr. pages 245-247. +Here we need the negated modular inverse, which is a simple transformation of those: + +- Instead of a 3-bit table: + - *-f* or *f ^ 6* +- Instead of a 4-bit table: + - *1 - f(f + 1)* + - *-(f + (((f + 1) & 4) << 1))* +- For larger tables the following technique can be used: if *w=-1/f mod 2L*, then *w(w f+2)* is + *-1/f mod 22L*. This allows extending the previous formulas (or tables). In particular we + have this 6-bit function (based on the 3-bit function above): + - *f(f2 - 2)* + +This loop, again extended to also handle *u*, *v*, *q*, and *r* alongside *f* and *g*, placed in +`divsteps_n_matrix`, gives a significantly faster, but non-constant time version. + + +## 7. Final Python version + +All together we need the following functions: + +- A way to compute the transition matrix in constant time, using the `divsteps_n_matrix` function + from section 2, but with its loop replaced by a variant of the constant-time divstep from + section 5, extended to handle *u*, *v*, *q*, *r*: + +```python +def divsteps_n_matrix(zeta, f, g): + """Compute zeta and transition matrix t after N divsteps (multiplied by 2^N).""" + u, v, q, r = 1, 0, 0, 1 # start with identity matrix + for _ in range(N): + c1 = zeta >> 63 + # Compute x, y, z as conditionally-negated versions of f, u, v. + x, y, z = (f ^ c1) - c1, (u ^ c1) - c1, (v ^ c1) - c1 + c2 = -(g & 1) + # Conditionally add x, y, z to g, q, r. + g, q, r = g + (x & c2), q + (y & c2), r + (z & c2) + c1 &= c2 # reusing c1 here for the earlier c3 variable + zeta = (zeta ^ c1) - 1 # inlining the unconditional zeta decrement here + # Conditionally add g, q, r to f, u, v. + f, u, v = f + (g & c1), u + (q & c1), v + (r & c1) + # When shifting g down, don't shift q, r, as we construct a transition matrix multiplied + # by 2^N. Instead, shift f's coefficients u and v up. + g, u, v = g >> 1, u << 1, v << 1 + return zeta, (u, v, q, r) +``` + +- The functions to update *f* and *g*, and *d* and *e*, from section 2 and section 4, with the constant-time + changes to `update_de` from section 5: + +```python +def update_fg(f, g, t): + """Multiply matrix t/2^N with [f, g].""" + u, v, q, r = t + cf, cg = u*f + v*g, q*f + r*g + return cf >> N, cg >> N + +def update_de(d, e, t, M, Mi): + """Multiply matrix t/2^N with [d, e], modulo M.""" + u, v, q, r = t + d_sign, e_sign = d >> 257, e >> 257 + md, me = (u & d_sign) + (v & e_sign), (q & d_sign) + (r & e_sign) + cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N + md -= (Mi*cd + md) % 2**N + me -= (Mi*ce + me) % 2**N + cd, ce = u*d + v*e + M*md, q*d + r*e + M*me + return cd >> N, ce >> N +``` + +- The `normalize` function from section 4, made constant time as well: + +```python +def normalize(sign, v, M): + """Compute sign*v mod M, where v in (-2*M,M); output in [0,M).""" + v_sign = v >> 257 + # Conditionally add M to v. + v += M & v_sign + c = (sign - 1) >> 1 + # Conditionally negate v. + v = (v ^ c) - c + v_sign = v >> 257 + # Conditionally add M to v again. + v += M & v_sign + return v +``` + +- And finally the `modinv` function too, adapted to use *ζ* instead of *δ*, and using the fixed + iteration count from section 5: + +```python +def modinv(M, Mi, x): + """Compute the modular inverse of x mod M, given Mi=1/M mod 2^N.""" + zeta, f, g, d, e = -1, M, x, 0, 1 + for _ in range((590 + N - 1) // N): + zeta, t = divsteps_n_matrix(zeta, f % 2**N, g % 2**N) + f, g = update_fg(f, g, t) + d, e = update_de(d, e, t, M, Mi) + return normalize(f, d, M) +``` + +- To get a variable time version, replace the `divsteps_n_matrix` function with one that uses the + divsteps loop from section 5, and a `modinv` version that calls it without the fixed iteration + count: + +```python +NEGINV16 = [15, 5, 3, 9, 7, 13, 11, 1] # NEGINV16[n//2] = (-n)^-1 mod 16, for odd n +def divsteps_n_matrix_var(eta, f, g): + """Compute eta and transition matrix t after N divsteps (multiplied by 2^N).""" + u, v, q, r = 1, 0, 0, 1 + i = N + while True: + zeros = min(i, count_trailing_zeros(g)) + eta, i = eta - zeros, i - zeros + g, u, v = g >> zeros, u << zeros, v << zeros + if i == 0: + break + if eta < 0: + eta, f, u, v, g, q, r = -eta, g, q, r, -f, -u, -v + limit = min(min(eta + 1, i), 4) + w = (g * NEGINV16[(f & 15) // 2]) % (2**limit) + g, q, r = g + w*f, q + w*u, r + w*v + return eta, (u, v, q, r) + +def modinv_var(M, Mi, x): + """Compute the modular inverse of x mod M, given Mi = 1/M mod 2^N.""" + eta, f, g, d, e = -1, M, x, 0, 1 + while g != 0: + eta, t = divsteps_n_matrix_var(eta, f % 2**N, g % 2**N) + f, g = update_fg(f, g, t) + d, e = update_de(d, e, t, M, Mi) + return normalize(f, d, Mi) +``` + +## 8. From GCDs to Jacobi symbol + +We can also use a similar approach to calculate Jacobi symbol *(x | M)* by keeping track of an +extra variable *j*, for which at every step *(x | M) = j (g | f)*. As we update *f* and *g*, we +make corresponding updates to *j* using +[properties of the Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol#Properties): +* *((g/2) | f)* is either *(g | f)* or *-(g | f)*, depending on the value of *f mod 8* (negating if it's *3* or *5*). +* *(f | g)* is either *(g | f)* or *-(g | f)*, depending on *f mod 4* and *g mod 4* (negating if both are *3*). + +These updates depend only on the values of *f* and *g* modulo *4* or *8*, and can thus be applied +very quickly, as long as we keep track of a few additional bits of *f* and *g*. Overall, this +calculation is slightly simpler than the one for the modular inverse because we no longer need to +keep track of *d* and *e*. + +However, one difficulty of this approach is that the Jacobi symbol *(a | n)* is only defined for +positive odd integers *n*, whereas in the original safegcd algorithm, *f, g* can take negative +values. We resolve this by using the following modified steps: + +```python + # Before + if delta > 0 and g & 1: + delta, f, g = 1 - delta, g, (g - f) // 2 + + # After + if delta > 0 and g & 1: + delta, f, g = 1 - delta, g, (g + f) // 2 +``` + +The algorithm is still correct, since the changed divstep, called a "posdivstep" (see section 8.4 +and E.5 in the paper) preserves *gcd(f, g)*. However, there's no proof that the modified algorithm +will converge. The justification for posdivsteps is completely empirical: in practice, it appears +that the vast majority of nonzero inputs converge to *f=g=gcd(f0, g0)* in a +number of steps proportional to their logarithm. + +Note that: +- We require inputs to satisfy *gcd(x, M) = 1*, as otherwise *f=1* is not reached. +- We require inputs *x &neq; 0*, because applying posdivstep with *g=0* has no effect. +- We need to update the termination condition from *g=0* to *f=1*. + +We account for the possibility of nonconvergence by only performing a bounded number of +posdivsteps, and then falling back to square-root based Jacobi calculation if a solution has not +yet been found. + +The optimizations in sections 3-7 above are described in the context of the original divsteps, but +in the C implementation we also adapt most of them (not including "avoiding modulus operations", +since it's not necessary to track *d, e*, and "constant-time operation", since we never calculate +Jacobi symbols for secret data) to the posdivsteps version. diff --git a/crypto/secp256k1/libsecp256k1/examples/CMakeLists.txt b/crypto/secp256k1/libsecp256k1/examples/CMakeLists.txt new file mode 100644 index 0000000000..c9da9de6be --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/examples/CMakeLists.txt @@ -0,0 +1,31 @@ +function(add_example name) + set(target_name ${name}_example) + add_executable(${target_name} ${name}.c) + target_include_directories(${target_name} PRIVATE + ${PROJECT_SOURCE_DIR}/include + ) + target_link_libraries(${target_name} + secp256k1 + $<$:bcrypt> + ) + set(test_name ${name}_example) + add_test(NAME secp256k1_${test_name} COMMAND ${target_name}) +endfunction() + +add_example(ecdsa) + +if(SECP256K1_ENABLE_MODULE_ECDH) + add_example(ecdh) +endif() + +if(SECP256K1_ENABLE_MODULE_SCHNORRSIG) + add_example(schnorr) +endif() + +if(SECP256K1_ENABLE_MODULE_ELLSWIFT) + add_example(ellswift) +endif() + +if(SECP256K1_ENABLE_MODULE_MUSIG) + add_example(musig) +endif() diff --git a/crypto/secp256k1/libsecp256k1/examples/EXAMPLES_COPYING b/crypto/secp256k1/libsecp256k1/examples/EXAMPLES_COPYING new file mode 100644 index 0000000000..0e259d42c9 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/examples/EXAMPLES_COPYING @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/crypto/secp256k1/libsecp256k1/examples/ecdh.c b/crypto/secp256k1/libsecp256k1/examples/ecdh.c new file mode 100644 index 0000000000..67b8c2047a --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/examples/ecdh.c @@ -0,0 +1,121 @@ +/************************************************************************* + * Written in 2020-2022 by Elichai Turkel * + * To the extent possible under law, the author(s) have dedicated all * + * copyright and related and neighboring rights to the software in this * + * file to the public domain worldwide. This software is distributed * + * without any warranty. For the CC0 Public Domain Dedication, see * + * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 * + *************************************************************************/ + +#include +#include +#include +#include + +#include +#include + +#include "examples_util.h" + +int main(void) { + unsigned char seckey1[32]; + unsigned char seckey2[32]; + unsigned char compressed_pubkey1[33]; + unsigned char compressed_pubkey2[33]; + unsigned char shared_secret1[32]; + unsigned char shared_secret2[32]; + unsigned char randomize[32]; + int return_val; + size_t len; + secp256k1_pubkey pubkey1; + secp256k1_pubkey pubkey2; + + /* Before we can call actual API functions, we need to create a "context". */ + secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + if (!fill_random(randomize, sizeof(randomize))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + /* Randomizing the context is recommended to protect against side-channel + * leakage See `secp256k1_context_randomize` in secp256k1.h for more + * information about it. This should never fail. */ + return_val = secp256k1_context_randomize(ctx, randomize); + assert(return_val); + + /*** Key Generation ***/ + if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + /* If the secret key is zero or out of range (greater than secp256k1's + * order), we fail. Note that the probability of this occurring is negligible + * with a properly functioning random number generator. */ + if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) { + printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); + return EXIT_FAILURE; + } + + /* Public key creation using a valid context with a verified secret key should never fail */ + return_val = secp256k1_ec_pubkey_create(ctx, &pubkey1, seckey1); + assert(return_val); + return_val = secp256k1_ec_pubkey_create(ctx, &pubkey2, seckey2); + assert(return_val); + + /* Serialize pubkey1 in a compressed form (33 bytes), should always return 1 */ + len = sizeof(compressed_pubkey1); + return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey1, &len, &pubkey1, SECP256K1_EC_COMPRESSED); + assert(return_val); + /* Should be the same size as the size of the output, because we passed a 33 byte array. */ + assert(len == sizeof(compressed_pubkey1)); + + /* Serialize pubkey2 in a compressed form (33 bytes) */ + len = sizeof(compressed_pubkey2); + return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey2, &len, &pubkey2, SECP256K1_EC_COMPRESSED); + assert(return_val); + /* Should be the same size as the size of the output, because we passed a 33 byte array. */ + assert(len == sizeof(compressed_pubkey2)); + + /*** Creating the shared secret ***/ + + /* Perform ECDH with seckey1 and pubkey2. Should never fail with a verified + * seckey and valid pubkey */ + return_val = secp256k1_ecdh(ctx, shared_secret1, &pubkey2, seckey1, NULL, NULL); + assert(return_val); + + /* Perform ECDH with seckey2 and pubkey1. Should never fail with a verified + * seckey and valid pubkey */ + return_val = secp256k1_ecdh(ctx, shared_secret2, &pubkey1, seckey2, NULL, NULL); + assert(return_val); + + /* Both parties should end up with the same shared secret */ + return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1)); + assert(return_val == 0); + + printf("Secret Key1: "); + print_hex(seckey1, sizeof(seckey1)); + printf("Compressed Pubkey1: "); + print_hex(compressed_pubkey1, sizeof(compressed_pubkey1)); + printf("\nSecret Key2: "); + print_hex(seckey2, sizeof(seckey2)); + printf("Compressed Pubkey2: "); + print_hex(compressed_pubkey2, sizeof(compressed_pubkey2)); + printf("\nShared Secret: "); + print_hex(shared_secret1, sizeof(shared_secret1)); + + /* This will clear everything from the context and free the memory */ + secp256k1_context_destroy(ctx); + + /* It's best practice to try to clear secrets from memory after using them. + * This is done because some bugs can allow an attacker to leak memory, for + * example through "out of bounds" array access (see Heartbleed), or the OS + * swapping them to disk. Hence, we overwrite the secret key buffer with zeros. + * + * Here we are preventing these writes from being optimized out, as any good compiler + * will remove any writes that aren't used. */ + secure_erase(seckey1, sizeof(seckey1)); + secure_erase(seckey2, sizeof(seckey2)); + secure_erase(shared_secret1, sizeof(shared_secret1)); + secure_erase(shared_secret2, sizeof(shared_secret2)); + + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/examples/ecdsa.c b/crypto/secp256k1/libsecp256k1/examples/ecdsa.c new file mode 100644 index 0000000000..ae16c180dc --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/examples/ecdsa.c @@ -0,0 +1,138 @@ +/************************************************************************* + * Written in 2020-2022 by Elichai Turkel * + * To the extent possible under law, the author(s) have dedicated all * + * copyright and related and neighboring rights to the software in this * + * file to the public domain worldwide. This software is distributed * + * without any warranty. For the CC0 Public Domain Dedication, see * + * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 * + *************************************************************************/ + +#include +#include +#include +#include + +#include + +#include "examples_util.h" + +int main(void) { + /* Instead of signing the message directly, we must sign a 32-byte hash. + * Here the message is "Hello, world!" and the hash function was SHA-256. + * An actual implementation should just call SHA-256, but this example + * hardcodes the output to avoid depending on an additional library. + * See https://bitcoin.stackexchange.com/questions/81115/if-someone-wanted-to-pretend-to-be-satoshi-by-posting-a-fake-signature-to-defrau/81116#81116 */ + unsigned char msg_hash[32] = { + 0x31, 0x5F, 0x5B, 0xDB, 0x76, 0xD0, 0x78, 0xC4, + 0x3B, 0x8A, 0xC0, 0x06, 0x4E, 0x4A, 0x01, 0x64, + 0x61, 0x2B, 0x1F, 0xCE, 0x77, 0xC8, 0x69, 0x34, + 0x5B, 0xFC, 0x94, 0xC7, 0x58, 0x94, 0xED, 0xD3, + }; + unsigned char seckey[32]; + unsigned char randomize[32]; + unsigned char compressed_pubkey[33]; + unsigned char serialized_signature[64]; + size_t len; + int is_signature_valid, is_signature_valid2; + int return_val; + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; + /* Before we can call actual API functions, we need to create a "context". */ + secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + if (!fill_random(randomize, sizeof(randomize))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + /* Randomizing the context is recommended to protect against side-channel + * leakage See `secp256k1_context_randomize` in secp256k1.h for more + * information about it. This should never fail. */ + return_val = secp256k1_context_randomize(ctx, randomize); + assert(return_val); + + /*** Key Generation ***/ + if (!fill_random(seckey, sizeof(seckey))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + /* If the secret key is zero or out of range (greater than secp256k1's + * order), we fail. Note that the probability of this occurring is negligible + * with a properly functioning random number generator. */ + if (!secp256k1_ec_seckey_verify(ctx, seckey)) { + printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); + return EXIT_FAILURE; + } + + /* Public key creation using a valid context with a verified secret key should never fail */ + return_val = secp256k1_ec_pubkey_create(ctx, &pubkey, seckey); + assert(return_val); + + /* Serialize the pubkey in a compressed form(33 bytes). Should always return 1. */ + len = sizeof(compressed_pubkey); + return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey, &len, &pubkey, SECP256K1_EC_COMPRESSED); + assert(return_val); + /* Should be the same size as the size of the output, because we passed a 33 byte array. */ + assert(len == sizeof(compressed_pubkey)); + + /*** Signing ***/ + + /* Generate an ECDSA signature `noncefp` and `ndata` allows you to pass a + * custom nonce function, passing `NULL` will use the RFC-6979 safe default. + * Signing with a valid context, verified secret key + * and the default nonce function should never fail. */ + return_val = secp256k1_ecdsa_sign(ctx, &sig, msg_hash, seckey, NULL, NULL); + assert(return_val); + + /* Serialize the signature in a compact form. Should always return 1 + * according to the documentation in secp256k1.h. */ + return_val = secp256k1_ecdsa_signature_serialize_compact(ctx, serialized_signature, &sig); + assert(return_val); + + + /*** Verification ***/ + + /* Deserialize the signature. This will return 0 if the signature can't be parsed correctly. */ + if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, serialized_signature)) { + printf("Failed parsing the signature\n"); + return EXIT_FAILURE; + } + + /* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */ + if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) { + printf("Failed parsing the public key\n"); + return EXIT_FAILURE; + } + + /* Verify a signature. This will return 1 if it's valid and 0 if it's not. */ + is_signature_valid = secp256k1_ecdsa_verify(ctx, &sig, msg_hash, &pubkey); + + printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false"); + printf("Secret Key: "); + print_hex(seckey, sizeof(seckey)); + printf("Public Key: "); + print_hex(compressed_pubkey, sizeof(compressed_pubkey)); + printf("Signature: "); + print_hex(serialized_signature, sizeof(serialized_signature)); + + /* This will clear everything from the context and free the memory */ + secp256k1_context_destroy(ctx); + + /* Bonus example: if all we need is signature verification (and no key + generation or signing), we don't need to use a context created via + secp256k1_context_create(). We can simply use the static (i.e., global) + context secp256k1_context_static. See its description in + include/secp256k1.h for details. */ + is_signature_valid2 = secp256k1_ecdsa_verify(secp256k1_context_static, + &sig, msg_hash, &pubkey); + assert(is_signature_valid2 == is_signature_valid); + + /* It's best practice to try to clear secrets from memory after using them. + * This is done because some bugs can allow an attacker to leak memory, for + * example through "out of bounds" array access (see Heartbleed), or the OS + * swapping them to disk. Hence, we overwrite the secret key buffer with zeros. + * + * Here we are preventing these writes from being optimized out, as any good compiler + * will remove any writes that aren't used. */ + secure_erase(seckey, sizeof(seckey)); + + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/examples/ellswift.c b/crypto/secp256k1/libsecp256k1/examples/ellswift.c new file mode 100644 index 0000000000..d58e96b053 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/examples/ellswift.c @@ -0,0 +1,122 @@ +/************************************************************************* + * Written in 2024 by Sebastian Falbesoner * + * To the extent possible under law, the author(s) have dedicated all * + * copyright and related and neighboring rights to the software in this * + * file to the public domain worldwide. This software is distributed * + * without any warranty. For the CC0 Public Domain Dedication, see * + * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 * + *************************************************************************/ + +/** This file demonstrates how to use the ElligatorSwift module to perform + * a key exchange according to BIP 324. Additionally, see the documentation + * in include/secp256k1_ellswift.h and doc/ellswift.md. + */ + +#include +#include +#include +#include + +#include +#include + +#include "examples_util.h" + +int main(void) { + secp256k1_context* ctx; + unsigned char randomize[32]; + unsigned char auxrand1[32]; + unsigned char auxrand2[32]; + unsigned char seckey1[32]; + unsigned char seckey2[32]; + unsigned char ellswift_pubkey1[64]; + unsigned char ellswift_pubkey2[64]; + unsigned char shared_secret1[32]; + unsigned char shared_secret2[32]; + int return_val; + + /* Create a secp256k1 context */ + ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + if (!fill_random(randomize, sizeof(randomize))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + /* Randomizing the context is recommended to protect against side-channel + * leakage. See `secp256k1_context_randomize` in secp256k1.h for more + * information about it. This should never fail. */ + return_val = secp256k1_context_randomize(ctx, randomize); + assert(return_val); + + /*** Generate secret keys ***/ + if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + /* If the secret key is zero or out of range (greater than secp256k1's + * order), we fail. Note that the probability of this occurring is negligible + * with a properly functioning random number generator. */ + if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) { + printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); + return EXIT_FAILURE; + } + + /* Generate ElligatorSwift public keys. This should never fail with valid context and + verified secret keys. Note that providing additional randomness (fourth parameter) is + optional, but recommended. */ + if (!fill_random(auxrand1, sizeof(auxrand1)) || !fill_random(auxrand2, sizeof(auxrand2))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey1, seckey1, auxrand1); + assert(return_val); + return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey2, seckey2, auxrand2); + assert(return_val); + + /*** Create the shared secret on each side ***/ + + /* Perform x-only ECDH with seckey1 and ellswift_pubkey2. Should never fail + * with a verified seckey and valid pubkey. Note that both parties pass both + * EllSwift pubkeys in the same order; the pubkey of the calling party is + * determined by the "party" boolean (sixth parameter). */ + return_val = secp256k1_ellswift_xdh(ctx, shared_secret1, ellswift_pubkey1, ellswift_pubkey2, + seckey1, 0, secp256k1_ellswift_xdh_hash_function_bip324, NULL); + assert(return_val); + + /* Perform x-only ECDH with seckey2 and ellswift_pubkey1. Should never fail + * with a verified seckey and valid pubkey. */ + return_val = secp256k1_ellswift_xdh(ctx, shared_secret2, ellswift_pubkey1, ellswift_pubkey2, + seckey2, 1, secp256k1_ellswift_xdh_hash_function_bip324, NULL); + assert(return_val); + + /* Both parties should end up with the same shared secret */ + return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1)); + assert(return_val == 0); + + printf( " Secret Key1: "); + print_hex(seckey1, sizeof(seckey1)); + printf( "EllSwift Pubkey1: "); + print_hex(ellswift_pubkey1, sizeof(ellswift_pubkey1)); + printf("\n Secret Key2: "); + print_hex(seckey2, sizeof(seckey2)); + printf( "EllSwift Pubkey2: "); + print_hex(ellswift_pubkey2, sizeof(ellswift_pubkey2)); + printf("\n Shared Secret: "); + print_hex(shared_secret1, sizeof(shared_secret1)); + + /* This will clear everything from the context and free the memory */ + secp256k1_context_destroy(ctx); + + /* It's best practice to try to clear secrets from memory after using them. + * This is done because some bugs can allow an attacker to leak memory, for + * example through "out of bounds" array access (see Heartbleed), or the OS + * swapping them to disk. Hence, we overwrite the secret key buffer with zeros. + * + * Here we are preventing these writes from being optimized out, as any good compiler + * will remove any writes that aren't used. */ + secure_erase(seckey1, sizeof(seckey1)); + secure_erase(seckey2, sizeof(seckey2)); + secure_erase(shared_secret1, sizeof(shared_secret1)); + secure_erase(shared_secret2, sizeof(shared_secret2)); + + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/examples/examples_util.h b/crypto/secp256k1/libsecp256k1/examples/examples_util.h new file mode 100644 index 0000000000..3293b64032 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/examples/examples_util.h @@ -0,0 +1,108 @@ +/************************************************************************* + * Copyright (c) 2020-2021 Elichai Turkel * + * Distributed under the CC0 software license, see the accompanying file * + * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 * + *************************************************************************/ + +/* + * This file is an attempt at collecting best practice methods for obtaining randomness with different operating systems. + * It may be out-of-date. Consult the documentation of the operating system before considering to use the methods below. + * + * Platform randomness sources: + * Linux -> `getrandom(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. http://man7.org/linux/man-pages/man2/getrandom.2.html, https://linux.die.net/man/4/urandom + * macOS -> `getentropy(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. https://www.unix.com/man-page/mojave/2/getentropy, https://opensource.apple.com/source/xnu/xnu-517.12.7/bsd/man/man4/random.4.auto.html + * FreeBSD -> `getrandom(2)`(`sys/random.h`), if not available `kern.arandom` should be used. https://www.freebsd.org/cgi/man.cgi?query=getrandom, https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4 + * OpenBSD -> `getentropy(2)`(`unistd.h`), if not available `/dev/urandom` should be used. https://man.openbsd.org/getentropy, https://man.openbsd.org/urandom + * Windows -> `BCryptGenRandom`(`bcrypt.h`). https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom + */ + +#if defined(_WIN32) +/* + * The defined WIN32_NO_STATUS macro disables return code definitions in + * windows.h, which avoids "macro redefinition" MSVC warnings in ntstatus.h. + */ +#define WIN32_NO_STATUS +#include +#undef WIN32_NO_STATUS +#include +#include +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) +#include +#elif defined(__OpenBSD__) +#include +#else +#error "Couldn't identify the OS" +#endif + +#include +#include +#include + + +/* Returns 1 on success, and 0 on failure. */ +static int fill_random(unsigned char* data, size_t size) { +#if defined(_WIN32) + NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (res != STATUS_SUCCESS || size > ULONG_MAX) { + return 0; + } else { + return 1; + } +#elif defined(__linux__) || defined(__FreeBSD__) + /* If `getrandom(2)` is not available you should fallback to /dev/urandom */ + ssize_t res = getrandom(data, size, 0); + if (res < 0 || (size_t)res != size ) { + return 0; + } else { + return 1; + } +#elif defined(__APPLE__) || defined(__OpenBSD__) + /* If `getentropy(2)` is not available you should fallback to either + * `SecRandomCopyBytes` or /dev/urandom */ + int res = getentropy(data, size); + if (res == 0) { + return 1; + } else { + return 0; + } +#endif + return 0; +} + +static void print_hex(unsigned char* data, size_t size) { + size_t i; + printf("0x"); + for (i = 0; i < size; i++) { + printf("%02x", data[i]); + } + printf("\n"); +} + +#if defined(_MSC_VER) +// For SecureZeroMemory +#include +#endif +/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */ +static void secure_erase(void *ptr, size_t len) { +#if defined(_MSC_VER) + /* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */ + SecureZeroMemory(ptr, len); +#elif defined(__GNUC__) + /* We use a memory barrier that scares the compiler away from optimizing out the memset. + * + * Quoting Adam Langley in commit ad1907fe73334d6c696c8539646c21b11178f20f + * in BoringSSL (ISC License): + * As best as we can tell, this is sufficient to break any optimisations that + * might try to eliminate "superfluous" memsets. + * This method used in memzero_explicit() the Linux kernel, too. Its advantage is that it is + * pretty efficient, because the compiler can still implement the memset() efficiently, + * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by + * Yang et al. (USENIX Security 2017) for more background. + */ + memset(ptr, 0, len); + __asm__ __volatile__("" : : "r"(ptr) : "memory"); +#else + void *(*volatile const volatile_memset)(void *, int, size_t) = memset; + volatile_memset(ptr, 0, len); +#endif +} diff --git a/crypto/secp256k1/libsecp256k1/examples/musig.c b/crypto/secp256k1/libsecp256k1/examples/musig.c new file mode 100644 index 0000000000..bdb8fced0c --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/examples/musig.c @@ -0,0 +1,261 @@ +/************************************************************************* + * To the extent possible under law, the author(s) have dedicated all * + * copyright and related and neighboring rights to the software in this * + * file to the public domain worldwide. This software is distributed * + * without any warranty. For the CC0 Public Domain Dedication, see * + * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 * + *************************************************************************/ + +/** This file demonstrates how to use the MuSig module to create a + * 3-of-3 multisignature. Additionally, see the documentation in + * include/secp256k1_musig.h and doc/musig.md. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "examples_util.h" + +struct signer_secrets { + secp256k1_keypair keypair; + secp256k1_musig_secnonce secnonce; +}; + +struct signer { + secp256k1_pubkey pubkey; + secp256k1_musig_pubnonce pubnonce; + secp256k1_musig_partial_sig partial_sig; +}; + + /* Number of public keys involved in creating the aggregate signature */ +#define N_SIGNERS 3 +/* Create a key pair, store it in signer_secrets->keypair and signer->pubkey */ +static int create_keypair(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer) { + unsigned char seckey[32]; + + if (!fill_random(seckey, sizeof(seckey))) { + printf("Failed to generate randomness\n"); + return 0; + } + /* Try to create a keypair with a valid context. This only fails if the + * secret key is zero or out of range (greater than secp256k1's order). Note + * that the probability of this occurring is negligible with a properly + * functioning random number generator. */ + if (!secp256k1_keypair_create(ctx, &signer_secrets->keypair, seckey)) { + return 0; + } + if (!secp256k1_keypair_pub(ctx, &signer->pubkey, &signer_secrets->keypair)) { + return 0; + } + + secure_erase(seckey, sizeof(seckey)); + return 1; +} + +/* Tweak the pubkey corresponding to the provided keyagg cache, update the cache + * and return the tweaked aggregate pk. */ +static int tweak(const secp256k1_context* ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache) { + secp256k1_pubkey output_pk; + /* For BIP 32 tweaking the plain_tweak is set to a hash as defined in BIP + * 32. */ + unsigned char plain_tweak[32] = "this could be a BIP32 tweak...."; + /* For Taproot tweaking the xonly_tweak is set to the TapTweak hash as + * defined in BIP 341 */ + unsigned char xonly_tweak[32] = "this could be a Taproot tweak.."; + + + /* Plain tweaking which, for example, allows deriving multiple child + * public keys from a single aggregate key using BIP32 */ + if (!secp256k1_musig_pubkey_ec_tweak_add(ctx, NULL, cache, plain_tweak)) { + return 0; + } + /* Note that we did not provide an output_pk argument, because the + * resulting pk is also saved in the cache and so if one is just interested + * in signing, the output_pk argument is unnecessary. On the other hand, if + * one is not interested in signing, the same output_pk can be obtained by + * calling `secp256k1_musig_pubkey_get` right after key aggregation to get + * the full pubkey and then call `secp256k1_ec_pubkey_tweak_add`. */ + + /* Xonly tweaking which, for example, allows creating Taproot commitments */ + if (!secp256k1_musig_pubkey_xonly_tweak_add(ctx, &output_pk, cache, xonly_tweak)) { + return 0; + } + /* Note that if we wouldn't care about signing, we can arrive at the same + * output_pk by providing the untweaked public key to + * `secp256k1_xonly_pubkey_tweak_add` (after converting it to an xonly pubkey + * if necessary with `secp256k1_xonly_pubkey_from_pubkey`). */ + + /* Now we convert the output_pk to an xonly pubkey to allow to later verify + * the Schnorr signature against it. For this purpose we can ignore the + * `pk_parity` output argument; we would need it if we would have to open + * the Taproot commitment. */ + if (!secp256k1_xonly_pubkey_from_pubkey(ctx, agg_pk, NULL, &output_pk)) { + return 0; + } + return 1; +} + +/* Sign a message hash with the given key pairs and store the result in sig */ +static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64) { + int i; + const secp256k1_musig_pubnonce *pubnonces[N_SIGNERS]; + const secp256k1_musig_partial_sig *partial_sigs[N_SIGNERS]; + /* The same for all signers */ + secp256k1_musig_session session; + secp256k1_musig_aggnonce agg_pubnonce; + + for (i = 0; i < N_SIGNERS; i++) { + unsigned char seckey[32]; + unsigned char session_secrand[32]; + /* Create random session ID. It is absolutely necessary that the session ID + * is unique for every call of secp256k1_musig_nonce_gen. Otherwise + * it's trivial for an attacker to extract the secret key! */ + if (!fill_random(session_secrand, sizeof(session_secrand))) { + return 0; + } + if (!secp256k1_keypair_sec(ctx, seckey, &signer_secrets[i].keypair)) { + return 0; + } + /* Initialize session and create secret nonce for signing and public + * nonce to send to the other signers. */ + if (!secp256k1_musig_nonce_gen(ctx, &signer_secrets[i].secnonce, &signer[i].pubnonce, session_secrand, seckey, &signer[i].pubkey, msg32, NULL, NULL)) { + return 0; + } + pubnonces[i] = &signer[i].pubnonce; + + secure_erase(seckey, sizeof(seckey)); + } + + /* Communication round 1: Every signer sends their pubnonce to the + * coordinator. The coordinator runs secp256k1_musig_nonce_agg and sends + * agg_pubnonce to each signer */ + if (!secp256k1_musig_nonce_agg(ctx, &agg_pubnonce, pubnonces, N_SIGNERS)) { + return 0; + } + + /* Every signer creates a partial signature */ + for (i = 0; i < N_SIGNERS; i++) { + /* Initialize the signing session by processing the aggregate nonce */ + if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache)) { + return 0; + } + /* partial_sign will clear the secnonce by setting it to 0. That's because + * you must _never_ reuse the secnonce (or use the same session_secrand to + * create a secnonce). If you do, you effectively reuse the nonce and + * leak the secret key. */ + if (!secp256k1_musig_partial_sign(ctx, &signer[i].partial_sig, &signer_secrets[i].secnonce, &signer_secrets[i].keypair, cache, &session)) { + return 0; + } + partial_sigs[i] = &signer[i].partial_sig; + } + /* Communication round 2: Every signer sends their partial signature to the + * coordinator, who verifies the partial signatures and aggregates them. */ + for (i = 0; i < N_SIGNERS; i++) { + /* To check whether signing was successful, it suffices to either verify + * the aggregate signature with the aggregate public key using + * secp256k1_schnorrsig_verify, or verify all partial signatures of all + * signers individually. Verifying the aggregate signature is cheaper but + * verifying the individual partial signatures has the advantage that it + * can be used to determine which of the partial signatures are invalid + * (if any), i.e., which of the partial signatures cause the aggregate + * signature to be invalid and thus the protocol run to fail. It's also + * fine to first verify the aggregate sig, and only verify the individual + * sigs if it does not work. + */ + if (!secp256k1_musig_partial_sig_verify(ctx, &signer[i].partial_sig, &signer[i].pubnonce, &signer[i].pubkey, cache, &session)) { + return 0; + } + } + return secp256k1_musig_partial_sig_agg(ctx, sig64, &session, partial_sigs, N_SIGNERS); +} + +int main(void) { + secp256k1_context* ctx; + int i; + struct signer_secrets signer_secrets[N_SIGNERS]; + struct signer signers[N_SIGNERS]; + const secp256k1_pubkey *pubkeys_ptr[N_SIGNERS]; + secp256k1_xonly_pubkey agg_pk; + secp256k1_musig_keyagg_cache cache; + unsigned char msg[32] = "this_could_be_the_hash_of_a_msg"; + unsigned char sig[64]; + + /* Create a secp256k1 context */ + ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + printf("Creating key pairs......"); + fflush(stdout); + for (i = 0; i < N_SIGNERS; i++) { + if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + pubkeys_ptr[i] = &signers[i].pubkey; + } + printf("ok\n"); + + /* The aggregate public key produced by secp256k1_musig_pubkey_agg depends + * on the order of the provided public keys. If there is no canonical order + * of the signers, the individual public keys can optionally be sorted with + * secp256k1_ec_pubkey_sort to ensure that the aggregate public key is + * independent of the order of signers. */ + printf("Sorting public keys....."); + fflush(stdout); + if (!secp256k1_ec_pubkey_sort(ctx, pubkeys_ptr, N_SIGNERS)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + + printf("Combining public keys..."); + fflush(stdout); + /* If you just want to aggregate and not sign, you can call + * secp256k1_musig_pubkey_agg with the keyagg_cache argument set to NULL + * while providing a non-NULL agg_pk argument. */ + if (!secp256k1_musig_pubkey_agg(ctx, NULL, &cache, pubkeys_ptr, N_SIGNERS)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + printf("Tweaking................"); + fflush(stdout); + /* Optionally tweak the aggregate key */ + if (!tweak(ctx, &agg_pk, &cache)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + printf("Signing message........."); + fflush(stdout); + if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + printf("Verifying signature....."); + fflush(stdout); + if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + + /* It's best practice to try to clear secrets from memory after using them. + * This is done because some bugs can allow an attacker to leak memory, for + * example through "out of bounds" array access (see Heartbleed), or the OS + * swapping them to disk. Hence, we overwrite secret key material with zeros. + * + * Here we are preventing these writes from being optimized out, as any good compiler + * will remove any writes that aren't used. */ + for (i = 0; i < N_SIGNERS; i++) { + secure_erase(&signer_secrets[i], sizeof(signer_secrets[i])); + } + secp256k1_context_destroy(ctx); + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/examples/schnorr.c b/crypto/secp256k1/libsecp256k1/examples/schnorr.c new file mode 100644 index 0000000000..49baed24be --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/examples/schnorr.c @@ -0,0 +1,154 @@ +/************************************************************************* + * Written in 2020-2022 by Elichai Turkel * + * To the extent possible under law, the author(s) have dedicated all * + * copyright and related and neighboring rights to the software in this * + * file to the public domain worldwide. This software is distributed * + * without any warranty. For the CC0 Public Domain Dedication, see * + * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 * + *************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include + +#include "examples_util.h" + +int main(void) { + unsigned char msg[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'}; + unsigned char msg_hash[32]; + unsigned char tag[] = {'m', 'y', '_', 'f', 'a', 'n', 'c', 'y', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l'}; + unsigned char seckey[32]; + unsigned char randomize[32]; + unsigned char auxiliary_rand[32]; + unsigned char serialized_pubkey[32]; + unsigned char signature[64]; + int is_signature_valid, is_signature_valid2; + int return_val; + secp256k1_xonly_pubkey pubkey; + secp256k1_keypair keypair; + /* Before we can call actual API functions, we need to create a "context". */ + secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + if (!fill_random(randomize, sizeof(randomize))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + /* Randomizing the context is recommended to protect against side-channel + * leakage See `secp256k1_context_randomize` in secp256k1.h for more + * information about it. This should never fail. */ + return_val = secp256k1_context_randomize(ctx, randomize); + assert(return_val); + + /*** Key Generation ***/ + if (!fill_random(seckey, sizeof(seckey))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + /* Try to create a keypair with a valid context. This only fails if the + * secret key is zero or out of range (greater than secp256k1's order). Note + * that the probability of this occurring is negligible with a properly + * functioning random number generator. */ + if (!secp256k1_keypair_create(ctx, &keypair, seckey)) { + printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); + return EXIT_FAILURE; + } + + /* Extract the X-only public key from the keypair. We pass NULL for + * `pk_parity` as the parity isn't needed for signing or verification. + * `secp256k1_keypair_xonly_pub` supports returning the parity for + * other use cases such as tests or verifying Taproot tweaks. + * This should never fail with a valid context and public key. */ + return_val = secp256k1_keypair_xonly_pub(ctx, &pubkey, NULL, &keypair); + assert(return_val); + + /* Serialize the public key. Should always return 1 for a valid public key. */ + return_val = secp256k1_xonly_pubkey_serialize(ctx, serialized_pubkey, &pubkey); + assert(return_val); + + /*** Signing ***/ + + /* Instead of signing (possibly very long) messages directly, we sign a + * 32-byte hash of the message in this example. + * + * We use secp256k1_tagged_sha256 to create this hash. This function expects + * a context-specific "tag", which restricts the context in which the signed + * messages should be considered valid. For example, if protocol A mandates + * to use the tag "my_fancy_protocol" and protocol B mandates to use the tag + * "my_boring_protocol", then signed messages from protocol A will never be + * valid in protocol B (and vice versa), even if keys are reused across + * protocols. This implements "domain separation", which is considered good + * practice. It avoids attacks in which users are tricked into signing a + * message that has intended consequences in the intended context (e.g., + * protocol A) but would have unintended consequences if it were valid in + * some other context (e.g., protocol B). */ + return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg)); + assert(return_val); + + /* Generate 32 bytes of randomness to use with BIP-340 schnorr signing. */ + if (!fill_random(auxiliary_rand, sizeof(auxiliary_rand))) { + printf("Failed to generate randomness\n"); + return EXIT_FAILURE; + } + + /* Generate a Schnorr signature. + * + * We use the secp256k1_schnorrsig_sign32 function that provides a simple + * interface for signing 32-byte messages (which in our case is a hash of + * the actual message). BIP-340 recommends passing 32 bytes of randomness + * to the signing function to improve security against side-channel attacks. + * Signing with a valid context, a 32-byte message, a verified keypair, and + * any 32 bytes of auxiliary random data should never fail. */ + return_val = secp256k1_schnorrsig_sign32(ctx, signature, msg_hash, &keypair, auxiliary_rand); + assert(return_val); + + /*** Verification ***/ + + /* Deserialize the public key. This will return 0 if the public key can't + * be parsed correctly */ + if (!secp256k1_xonly_pubkey_parse(ctx, &pubkey, serialized_pubkey)) { + printf("Failed parsing the public key\n"); + return EXIT_FAILURE; + } + + /* Compute the tagged hash on the received messages using the same tag as the signer. */ + return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg)); + assert(return_val); + + /* Verify a signature. This will return 1 if it's valid and 0 if it's not. */ + is_signature_valid = secp256k1_schnorrsig_verify(ctx, signature, msg_hash, 32, &pubkey); + + + printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false"); + printf("Secret Key: "); + print_hex(seckey, sizeof(seckey)); + printf("Public Key: "); + print_hex(serialized_pubkey, sizeof(serialized_pubkey)); + printf("Signature: "); + print_hex(signature, sizeof(signature)); + + /* This will clear everything from the context and free the memory */ + secp256k1_context_destroy(ctx); + + /* Bonus example: if all we need is signature verification (and no key + generation or signing), we don't need to use a context created via + secp256k1_context_create(). We can simply use the static (i.e., global) + context secp256k1_context_static. See its description in + include/secp256k1.h for details. */ + is_signature_valid2 = secp256k1_schnorrsig_verify(secp256k1_context_static, + signature, msg_hash, 32, &pubkey); + assert(is_signature_valid2 == is_signature_valid); + + /* It's best practice to try to clear secrets from memory after using them. + * This is done because some bugs can allow an attacker to leak memory, for + * example through "out of bounds" array access (see Heartbleed), or the OS + * swapping them to disk. Hence, we overwrite the secret key buffer with zeros. + * + * Here we are preventing these writes from being optimized out, as any good compiler + * will remove any writes that aren't used. */ + secure_erase(seckey, sizeof(seckey)); + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1.h b/crypto/secp256k1/libsecp256k1/include/secp256k1.h index 76af839691..c6e9417f05 100644 --- a/crypto/secp256k1/libsecp256k1/include/secp256k1.h +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1.h @@ -1,20 +1,22 @@ -#ifndef _SECP256K1_ -# define _SECP256K1_ +#ifndef SECP256K1_H +#define SECP256K1_H -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif #include -/* These rules specify the order of arguments in API calls: +/** Unless explicitly stated all pointer arguments must not be NULL. + * + * The following rules specify the order of arguments in API calls: * * 1. Context pointers go first, followed by output arguments, combined * output/input arguments, and finally input-only arguments. - * 2. Array lengths always immediately the follow the argument whose length + * 2. Array lengths always immediately follow the argument whose length * they describe, even if this violates rule 1. * 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated - * later go first. This means: signatures, public nonces, private nonces, + * later go first. This means: signatures, public nonces, secret nonces, * messages, public keys, secret keys, tweaks. * 4. Arguments that are not data pointers go last, from more complex to less * complex: function pointers, algorithm names, messages, void pointers, @@ -22,20 +24,25 @@ extern "C" { * 5. Opaque data pointers follow the function pointer they are to be passed to. */ -/** Opaque data structure that holds context information (precomputed tables etc.). +/** Opaque data structure that holds context information * - * The purpose of context structures is to cache large precomputed data tables - * that are expensive to construct, and also to maintain the randomization data - * for blinding. + * The primary purpose of context objects is to store randomization data for + * enhanced protection against side-channel leakage. This protection is only + * effective if the context is randomized after its creation. See + * secp256k1_context_create for creation of contexts and + * secp256k1_context_randomize for randomization. * - * Do not create a new context object for each operation, as construction is - * far slower than all other API calls (~100 times slower than an ECDSA - * verification). + * A secondary purpose of context objects is to store pointers to callback + * functions that the library will call when certain error states arise. See + * secp256k1_context_set_error_callback as well as + * secp256k1_context_set_illegal_callback for details. Future library versions + * may use context objects for additional purposes. * * A constructed context can safely be used from multiple threads - * simultaneously, but API call that take a non-const pointer to a context + * simultaneously, but API calls that take a non-const pointer to a context * need exclusive access to it. In particular this is the case for - * secp256k1_context_destroy and secp256k1_context_randomize. + * secp256k1_context_destroy, secp256k1_context_preallocated_destroy, + * and secp256k1_context_randomize. * * Regarding randomization, either do it once at creation time (in which case * you do not need any locking for the other calls), or use a read-write lock. @@ -47,23 +54,24 @@ typedef struct secp256k1_context_struct secp256k1_context; * The exact representation of data inside is implementation defined and not * guaranteed to be portable between different platforms or versions. It is * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage, transmission, or - * comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. + * If you need to convert to a format suitable for storage or transmission, + * use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. To + * compare keys, use secp256k1_ec_pubkey_cmp. */ -typedef struct { +typedef struct secp256k1_pubkey { unsigned char data[64]; } secp256k1_pubkey; -/** Opaque data structured that holds a parsed ECDSA signature. +/** Opaque data structure that holds a parsed ECDSA signature. * * The exact representation of data inside is implementation defined and not * guaranteed to be portable between different platforms or versions. It is * however guaranteed to be 64 bytes in size, and can be safely copied/moved. * If you need to convert to a format suitable for storage, transmission, or * comparison, use the secp256k1_ecdsa_signature_serialize_* and - * secp256k1_ecdsa_signature_serialize_* functions. + * secp256k1_ecdsa_signature_parse_* functions. */ -typedef struct { +typedef struct secp256k1_ecdsa_signature { unsigned char data[64]; } secp256k1_ecdsa_signature; @@ -101,35 +109,62 @@ typedef int (*secp256k1_nonce_function)( # endif # endif -# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) -# if SECP256K1_GNUC_PREREQ(2,7) -# define SECP256K1_INLINE __inline__ -# elif (defined(_MSC_VER)) -# define SECP256K1_INLINE __inline -# else -# define SECP256K1_INLINE -# endif -# else -# define SECP256K1_INLINE inline -# endif +/* When this header is used at build-time the SECP256K1_BUILD define needs to be set + * to correctly setup export attributes and nullness checks. This is normally done + * by secp256k1.c but to guard against this header being included before secp256k1.c + * has had a chance to set the define (e.g. via test harnesses that just includes + * secp256k1.c) we set SECP256K1_NO_BUILD when this header is processed without the + * BUILD define so this condition can be caught. + */ +#ifndef SECP256K1_BUILD +# define SECP256K1_NO_BUILD +#endif -#ifndef SECP256K1_API -# if defined(_WIN32) -# ifdef SECP256K1_BUILD -# define SECP256K1_API __declspec(dllexport) +/* Symbol visibility. */ +#if defined(_WIN32) + /* GCC for Windows (e.g., MinGW) accepts the __declspec syntax + * for MSVC compatibility. A __declspec declaration implies (but is not + * exactly equivalent to) __attribute__ ((visibility("default"))), and so we + * actually want __declspec even on GCC, see "Microsoft Windows Function + * Attributes" in the GCC manual and the recommendations in + * https://gcc.gnu.org/wiki/Visibility. */ +# if defined(SECP256K1_BUILD) +# if defined(DLL_EXPORT) || defined(SECP256K1_DLL_EXPORT) + /* Building libsecp256k1 as a DLL. + * 1. If using Libtool, it defines DLL_EXPORT automatically. + * 2. In other cases, SECP256K1_DLL_EXPORT must be defined. */ +# define SECP256K1_API extern __declspec (dllexport) # else -# define SECP256K1_API + /* Building libsecp256k1 as a static library on Windows. + * No declspec is needed, and so we would want the non-Windows-specific + * logic below take care of this case. However, this may result in setting + * __attribute__ ((visibility("default"))), which is supposed to be a noop + * on Windows but may trigger warnings when compiling with -flto due to a + * bug in GCC, see + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116478 . */ +# define SECP256K1_API extern # endif -# elif defined(__GNUC__) && defined(SECP256K1_BUILD) -# define SECP256K1_API __attribute__ ((visibility ("default"))) + /* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static + * library on Windows. */ +# elif !defined(SECP256K1_STATIC) + /* Consuming libsecp256k1 as a DLL. */ +# define SECP256K1_API extern __declspec (dllimport) +# endif +#endif +#ifndef SECP256K1_API +/* All cases not captured by the Windows-specific logic. */ +# if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD) + /* Building libsecp256k1 using GCC or compatible. */ +# define SECP256K1_API extern __attribute__ ((visibility ("default"))) # else -# define SECP256K1_API + /* Fall back to standard C's extern. */ +# define SECP256K1_API extern # endif #endif -/**Warning attributes - * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out - * some paranoid null checks. */ +/* Warning attributes + * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out + * some paranoid null checks. */ # if defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) # define SECP256K1_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) # else @@ -141,50 +176,147 @@ typedef int (*secp256k1_nonce_function)( # define SECP256K1_ARG_NONNULL(_x) # endif -/** All flags' lower 8 bits indicate what they're for. Do not use directly. */ +/* Attribute for marking functions, types, and variables as deprecated */ +#if !defined(SECP256K1_BUILD) && defined(__has_attribute) +# if __has_attribute(__deprecated__) +# define SECP256K1_DEPRECATED(_msg) __attribute__ ((__deprecated__(_msg))) +# else +# define SECP256K1_DEPRECATED(_msg) +# endif +#else +# define SECP256K1_DEPRECATED(_msg) +#endif + +/* All flags' lower 8 bits indicate what they're for. Do not use directly. */ #define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1) #define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0) #define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) -/** The higher bits contain the actual data. Do not use directly. */ +/* The higher bits contain the actual data. Do not use directly. */ #define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8) #define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9) +#define SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY (1 << 10) #define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) -/** Flags to pass to secp256k1_context_create. */ -#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) -#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN) +/** Context flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and + * secp256k1_context_preallocated_create. */ #define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT) -/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */ +/** Deprecated context flags. These flags are treated equivalent to SECP256K1_CONTEXT_NONE. */ +#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) +#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN) + +/* Testing flag. Do not use. */ +#define SECP256K1_CONTEXT_DECLASSIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY) + +/** Flag to pass to secp256k1_ec_pubkey_serialize. */ #define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) #define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION) -/** Create a secp256k1 context object. +/** Prefix byte used to tag various encoded curvepoints for specific purposes */ +#define SECP256K1_TAG_PUBKEY_EVEN 0x02 +#define SECP256K1_TAG_PUBKEY_ODD 0x03 +#define SECP256K1_TAG_PUBKEY_UNCOMPRESSED 0x04 +#define SECP256K1_TAG_PUBKEY_HYBRID_EVEN 0x06 +#define SECP256K1_TAG_PUBKEY_HYBRID_ODD 0x07 + +/** A built-in constant secp256k1 context object with static storage duration, to be + * used in conjunction with secp256k1_selftest. * - * Returns: a newly created context object. - * In: flags: which parts of the context to initialize. + * This context object offers *only limited functionality* , i.e., it cannot be used + * for API functions that perform computations involving secret keys, e.g., signing + * and public key generation. If this restriction applies to a specific API function, + * it is mentioned in its documentation. See secp256k1_context_create if you need a + * full context object that supports all functionality offered by the library. + * + * It is highly recommended to call secp256k1_selftest before using this context. */ -SECP256K1_API secp256k1_context* secp256k1_context_create( +SECP256K1_API const secp256k1_context *secp256k1_context_static; + +/** Deprecated alias for secp256k1_context_static. */ +SECP256K1_API const secp256k1_context *secp256k1_context_no_precomp +SECP256K1_DEPRECATED("Use secp256k1_context_static instead"); + +/** Perform basic self tests (to be used in conjunction with secp256k1_context_static) + * + * This function performs self tests that detect some serious usage errors and + * similar conditions, e.g., when the library is compiled for the wrong endianness. + * This is a last resort measure to be used in production. The performed tests are + * very rudimentary and are not intended as a replacement for running the test + * binaries. + * + * It is highly recommended to call this before using secp256k1_context_static. + * It is not necessary to call this function before using a context created with + * secp256k1_context_create (or secp256k1_context_preallocated_create), which will + * take care of performing the self tests. + * + * If the tests fail, this function will call the default error handler to abort the + * program (see secp256k1_context_set_error_callback). + */ +SECP256K1_API void secp256k1_selftest(void); + + +/** Create a secp256k1 context object (in dynamically allocated memory). + * + * This function uses malloc to allocate memory. It is guaranteed that malloc is + * called at most once for every call of this function. If you need to avoid dynamic + * memory allocation entirely, see secp256k1_context_static and the functions in + * secp256k1_preallocated.h. + * + * Returns: pointer to a newly created context object. + * In: flags: Always set to SECP256K1_CONTEXT_NONE (see below). + * + * The only valid non-deprecated flag in recent library versions is + * SECP256K1_CONTEXT_NONE, which will create a context sufficient for all functionality + * offered by the library. All other (deprecated) flags will be treated as equivalent + * to the SECP256K1_CONTEXT_NONE flag. Though the flags parameter primarily exists for + * historical reasons, future versions of the library may introduce new flags. + * + * If the context is intended to be used for API functions that perform computations + * involving secret keys, e.g., signing and public key generation, then it is highly + * recommended to call secp256k1_context_randomize on the context before calling + * those API functions. This will provide enhanced protection against side-channel + * leakage, see secp256k1_context_randomize for details. + * + * Do not create a new context object for each operation, as construction and + * randomization can take non-negligible time. + */ +SECP256K1_API secp256k1_context *secp256k1_context_create( unsigned int flags ) SECP256K1_WARN_UNUSED_RESULT; -/** Copies a secp256k1 context object. +/** Copy a secp256k1 context object (into dynamically allocated memory). * - * Returns: a newly created context object. - * Args: ctx: an existing context to copy (cannot be NULL) + * This function uses malloc to allocate memory. It is guaranteed that malloc is + * called at most once for every call of this function. If you need to avoid dynamic + * memory allocation entirely, see the functions in secp256k1_preallocated.h. + * + * Cloning secp256k1_context_static is not possible, and should not be emulated by + * the caller (e.g., using memcpy). Create a new context instead. + * + * Returns: pointer to a newly created context object. + * Args: ctx: pointer to a context to copy (not secp256k1_context_static). */ -SECP256K1_API secp256k1_context* secp256k1_context_clone( - const secp256k1_context* ctx +SECP256K1_API secp256k1_context *secp256k1_context_clone( + const secp256k1_context *ctx ) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; -/** Destroy a secp256k1 context object. +/** Destroy a secp256k1 context object (created in dynamically allocated memory). * * The context pointer may not be used afterwards. - * Args: ctx: an existing context to destroy (cannot be NULL) + * + * The context to destroy must have been created using secp256k1_context_create + * or secp256k1_context_clone. If the context has instead been created using + * secp256k1_context_preallocated_create or secp256k1_context_preallocated_clone, the + * behaviour is undefined. In that case, secp256k1_context_preallocated_destroy must + * be used instead. + * + * Args: ctx: pointer to a context to destroy, constructed using + * secp256k1_context_create or secp256k1_context_clone + * (i.e., not secp256k1_context_static). */ SECP256K1_API void secp256k1_context_destroy( - secp256k1_context* ctx -); + secp256k1_context *ctx +) SECP256K1_ARG_NONNULL(1); /** Set a callback function to be called when an illegal argument is passed to * an API call. It will only trigger for violations that are mentioned @@ -200,20 +332,40 @@ SECP256K1_API void secp256k1_context_destroy( * to cause a crash, though its return value and output arguments are * undefined. * - * Args: ctx: an existing context object (cannot be NULL) - * In: fun: a pointer to a function to call when an illegal argument is - * passed to the API, taking a message and an opaque pointer - * (NULL restores a default handler that calls abort). - * data: the opaque pointer to pass to fun above. + * When this function has not been called (or called with fn==NULL), then the + * default handler will be used. The library provides a default handler which + * writes the message to stderr and calls abort. This default handler can be + * replaced at link time if the preprocessor macro + * USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build + * has been configured with --enable-external-default-callbacks. Then the + * following two symbols must be provided to link against: + * - void secp256k1_default_illegal_callback_fn(const char *message, void *data); + * - void secp256k1_default_error_callback_fn(const char *message, void *data); + * The library can call these default handlers even before a proper callback data + * pointer could have been set using secp256k1_context_set_illegal_callback or + * secp256k1_context_set_error_callback, e.g., when the creation of a context + * fails. In this case, the corresponding default handler will be called with + * the data pointer argument set to NULL. + * + * Args: ctx: pointer to a context object. + * In: fun: pointer to a function to call when an illegal argument is + * passed to the API, taking a message and an opaque pointer. + * (NULL restores the default handler.) + * data: the opaque pointer to pass to fun above, must be NULL for the default handler. + * + * See also secp256k1_context_set_error_callback. */ SECP256K1_API void secp256k1_context_set_illegal_callback( - secp256k1_context* ctx, - void (*fun)(const char* message, void* data), - const void* data + secp256k1_context *ctx, + void (*fun)(const char *message, void *data), + const void *data ) SECP256K1_ARG_NONNULL(1); /** Set a callback function to be called when an internal consistency check - * fails. The default is crashing. + * fails. + * + * The default callback writes an error message to stderr and calls abort + * to abort the program. * * This can only trigger in case of a hardware failure, miscompilation, * memory corruption, serious bug in the library, or other error would can @@ -222,23 +374,26 @@ SECP256K1_API void secp256k1_context_set_illegal_callback( * for that). After this callback returns, anything may happen, including * crashing. * - * Args: ctx: an existing context object (cannot be NULL) - * In: fun: a pointer to a function to call when an internal error occurs, - * taking a message and an opaque pointer (NULL restores a default - * handler that calls abort). - * data: the opaque pointer to pass to fun above. + * Args: ctx: pointer to a context object. + * In: fun: pointer to a function to call when an internal error occurs, + * taking a message and an opaque pointer (NULL restores the + * default handler, see secp256k1_context_set_illegal_callback + * for details). + * data: the opaque pointer to pass to fun above, must be NULL for the default handler. + * + * See also secp256k1_context_set_illegal_callback. */ SECP256K1_API void secp256k1_context_set_error_callback( - secp256k1_context* ctx, - void (*fun)(const char* message, void* data), - const void* data + secp256k1_context *ctx, + void (*fun)(const char *message, void *data), + const void *data ) SECP256K1_ARG_NONNULL(1); /** Parse a variable-length public key into the pubkey object. * * Returns: 1 if the public key was fully valid. * 0 if the public key could not be parsed or is invalid. - * Args: ctx: a secp256k1 context object. + * Args: ctx: pointer to a context object. * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a * parsed version of input. If not, its value is undefined. * In: input: pointer to a serialized public key @@ -249,8 +404,8 @@ SECP256K1_API void secp256k1_context_set_error_callback( * byte 0x06 or 0x07) format public keys. */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( - const secp256k1_context* ctx, - secp256k1_pubkey* pubkey, + const secp256k1_context *ctx, + secp256k1_pubkey *pubkey, const unsigned char *input, size_t inputlen ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); @@ -258,65 +413,94 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( /** Serialize a pubkey object into a serialized byte sequence. * * Returns: 1 always. - * Args: ctx: a secp256k1 context object. - * Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if + * Args: ctx: pointer to a context object. + * Out: output: pointer to a 65-byte (if compressed==0) or 33-byte (if * compressed==1) byte array to place the serialized key * in. - * In/Out: outputlen: a pointer to an integer which is initially set to the + * In/Out: outputlen: pointer to an integer which is initially set to the * size of output, and is overwritten with the written * size. - * In: pubkey: a pointer to a secp256k1_pubkey containing an + * In: pubkey: pointer to a secp256k1_pubkey containing an * initialized public key. * flags: SECP256K1_EC_COMPRESSED if serialization should be in * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED. */ SECP256K1_API int secp256k1_ec_pubkey_serialize( - const secp256k1_context* ctx, + const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, - const secp256k1_pubkey* pubkey, + const secp256k1_pubkey *pubkey, unsigned int flags ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +/** Compare two public keys using lexicographic (of compressed serialization) order + * + * Returns: <0 if the first public key is less than the second + * >0 if the first public key is greater than the second + * 0 if the two public keys are equal + * Args: ctx: pointer to a context object + * In: pubkey1: first public key to compare + * pubkey2: second public key to compare + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp( + const secp256k1_context *ctx, + const secp256k1_pubkey *pubkey1, + const secp256k1_pubkey *pubkey2 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Sort public keys using lexicographic (of compressed serialization) order + * + * Returns: 0 if the arguments are invalid. 1 otherwise. + * + * Args: ctx: pointer to a context object + * In: pubkeys: array of pointers to pubkeys to sort + * n_pubkeys: number of elements in the pubkeys array + */ +SECP256K1_API int secp256k1_ec_pubkey_sort( + const secp256k1_context *ctx, + const secp256k1_pubkey **pubkeys, + size_t n_pubkeys +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + /** Parse an ECDSA signature in compact (64 bytes) format. * * Returns: 1 when the signature could be parsed, 0 otherwise. - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input64: a pointer to the 64-byte array to parse + * Args: ctx: pointer to a context object + * Out: sig: pointer to a signature object + * In: input64: pointer to the 64-byte array to parse * * The signature must consist of a 32-byte big endian R value, followed by a * 32-byte big endian S value. If R or S fall outside of [0..order-1], the * encoding is invalid. R and S with value 0 are allowed in the encoding. * * After the call, sig will always be initialized. If parsing failed or R or - * S are zero, the resulting sig value is guaranteed to fail validation for any - * message and public key. + * S are zero, the resulting sig value is guaranteed to fail verification for + * any message and public key. */ SECP256K1_API int secp256k1_ecdsa_signature_parse_compact( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, + const secp256k1_context *ctx, + secp256k1_ecdsa_signature *sig, const unsigned char *input64 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Parse a DER ECDSA signature. * * Returns: 1 when the signature could be parsed, 0 otherwise. - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input: a pointer to the signature to be parsed + * Args: ctx: pointer to a context object + * Out: sig: pointer to a signature object + * In: input: pointer to the signature to be parsed * inputlen: the length of the array pointed to be input * * This function will accept any valid DER encoded signature, even if the * encoded numbers are out of range. * * After the call, sig will always be initialized. If parsing failed or the - * encoded numbers are out of range, signature validation with it is + * encoded numbers are out of range, signature verification with it is * guaranteed to fail for every message and public key. */ SECP256K1_API int secp256k1_ecdsa_signature_parse_der( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, + const secp256k1_context *ctx, + secp256k1_ecdsa_signature *sig, const unsigned char *input, size_t inputlen ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); @@ -324,71 +508,77 @@ SECP256K1_API int secp256k1_ecdsa_signature_parse_der( /** Serialize an ECDSA signature in DER format. * * Returns: 1 if enough space was available to serialize, 0 otherwise - * Args: ctx: a secp256k1 context object - * Out: output: a pointer to an array to store the DER serialization - * In/Out: outputlen: a pointer to a length integer. Initially, this integer + * Args: ctx: pointer to a context object + * Out: output: pointer to an array to store the DER serialization + * In/Out: outputlen: pointer to a length integer. Initially, this integer * should be set to the length of output. After the call * it will be set to the length of the serialization (even * if 0 was returned). - * In: sig: a pointer to an initialized signature object + * In: sig: pointer to an initialized signature object */ SECP256K1_API int secp256k1_ecdsa_signature_serialize_der( - const secp256k1_context* ctx, + const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, - const secp256k1_ecdsa_signature* sig + const secp256k1_ecdsa_signature *sig ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Serialize an ECDSA signature in compact (64 byte) format. * * Returns: 1 - * Args: ctx: a secp256k1 context object - * Out: output64: a pointer to a 64-byte array to store the compact serialization - * In: sig: a pointer to an initialized signature object + * Args: ctx: pointer to a context object + * Out: output64: pointer to a 64-byte array to store the compact serialization + * In: sig: pointer to an initialized signature object * * See secp256k1_ecdsa_signature_parse_compact for details about the encoding. */ SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( - const secp256k1_context* ctx, + const secp256k1_context *ctx, unsigned char *output64, - const secp256k1_ecdsa_signature* sig + const secp256k1_ecdsa_signature *sig ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Verify an ECDSA signature. * * Returns: 1: correct 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) - * pubkey: pointer to an initialized public key to verify with (cannot be NULL) + * 0: incorrect or unparseable signature + * Args: ctx: pointer to a context object + * In: sig: the signature being verified. + * msghash32: the 32-byte message hash being verified. + * The verifier must make sure to apply a cryptographic + * hash function to the message by itself and not accept an + * msghash32 value directly. Otherwise, it would be easy to + * create a "valid" signature without knowledge of the + * secret key. See also + * https://bitcoin.stackexchange.com/a/81116/35586 for more + * background on this topic. + * pubkey: pointer to an initialized public key to verify with. * * To avoid accepting malleable signatures, only ECDSA signatures in lower-S * form are accepted. * * If you need to accept ECDSA signatures from sources that do not obey this * rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to - * validation, but be aware that doing so results in malleable signatures. + * verification, but be aware that doing so results in malleable signatures. * * For details, see the comments for that function. */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( - const secp256k1_context* ctx, + const secp256k1_context *ctx, const secp256k1_ecdsa_signature *sig, - const unsigned char *msg32, + const unsigned char *msghash32, const secp256k1_pubkey *pubkey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Convert a signature to a normalized lower-S form. * * Returns: 1 if sigin was not normalized, 0 if it already was. - * Args: ctx: a secp256k1 context object - * Out: sigout: a pointer to a signature to fill with the normalized form, + * Args: ctx: pointer to a context object + * Out: sigout: pointer to a signature to fill with the normalized form, * or copy if the input was already normalized. (can be NULL if * you're only interested in whether the input was already * normalized). - * In: sigin: a pointer to a signature to check/normalize (cannot be NULL, - * can be identical to sigout) + * In: sigin: pointer to a signature to check/normalize (can be identical to sigout) * * With ECDSA a third-party can forge a second distinct signature of the same * message, given a single initial signature, but without knowing the key. This @@ -422,7 +612,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( * secp256k1_ecdsa_signature_normalize must be called before verification. */ SECP256K1_API int secp256k1_ecdsa_signature_normalize( - const secp256k1_context* ctx, + const secp256k1_context *ctx, secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); @@ -431,147 +621,279 @@ SECP256K1_API int secp256k1_ecdsa_signature_normalize( * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of * extra entropy. */ -SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; +SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; /** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ -SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default; +SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_default; /** Create an ECDSA signature. * * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) + * 0: the nonce generation function failed, or the secret key was invalid. + * Args: ctx: pointer to a context object (not secp256k1_context_static). + * Out: sig: pointer to an array where the signature will be placed. + * In: msghash32: the 32-byte message hash being signed. + * seckey: pointer to a 32-byte secret key. + * noncefp: pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_default is used. + * ndata: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + * secp256k1_nonce_function_default is used, then ndata must be a + * pointer to 32-bytes of additional data. * * The created signature is always in lower-S form. See * secp256k1_ecdsa_signature_normalize for more details. */ SECP256K1_API int secp256k1_ecdsa_sign( - const secp256k1_context* ctx, + const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, - const unsigned char *msg32, + const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -/** Verify an ECDSA secret key. +/** Verify an elliptic curve secret key. + * + * A secret key is valid if it is not 0 and less than the secp256k1 curve order + * when interpreted as an integer (most significant byte first). The + * probability of choosing a 32-byte string uniformly at random which is an + * invalid secret key is negligible. However, if it does happen it should + * be assumed that the randomness source is severely broken and there should + * be no retry. * * Returns: 1: secret key is valid * 0: secret key is invalid - * Args: ctx: pointer to a context object (cannot be NULL) - * In: seckey: pointer to a 32-byte secret key (cannot be NULL) + * Args: ctx: pointer to a context object. + * In: seckey: pointer to a 32-byte secret key. */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( - const secp256k1_context* ctx, + const secp256k1_context *ctx, const unsigned char *seckey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); /** Compute the public key for a secret key. * - * Returns: 1: secret was valid, public key stores - * 0: secret was invalid, try again - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: pubkey: pointer to the created public key (cannot be NULL) - * In: seckey: pointer to a 32-byte private key (cannot be NULL) + * Returns: 1: secret was valid, public key stores. + * 0: secret was invalid, try again. + * Args: ctx: pointer to a context object (not secp256k1_context_static). + * Out: pubkey: pointer to the created public key. + * In: seckey: pointer to a 32-byte secret key. */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( - const secp256k1_context* ctx, + const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Tweak a private key by adding tweak to it. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or if the resulting private key - * would be invalid (only when the tweak is the complement of the - * private key). 1 otherwise. - * Args: ctx: pointer to a context object (cannot be NULL). - * In/Out: seckey: pointer to a 32-byte private key. - * In: tweak: pointer to a 32-byte tweak. +/** Negates a secret key in place. + * + * Returns: 0 if the given secret key is invalid according to + * secp256k1_ec_seckey_verify. 1 otherwise + * Args: ctx: pointer to a context object + * In/Out: seckey: pointer to the 32-byte secret key to be negated. If the + * secret key is invalid according to + * secp256k1_ec_seckey_verify, this function returns 0 and + * seckey will be set to some unspecified value. */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( - const secp256k1_context* ctx, +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate( + const secp256k1_context *ctx, + unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in + * future versions. */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate( + const secp256k1_context *ctx, + unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) + SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead"); + +/** Negates a public key in place. + * + * Returns: 1 always + * Args: ctx: pointer to a context object + * In/Out: pubkey: pointer to the public key to be negated. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate( + const secp256k1_context *ctx, + secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Tweak a secret key by adding tweak to it. + * + * Returns: 0 if the arguments are invalid or the resulting secret key would be + * invalid (only when the tweak is the negation of the secret key). 1 + * otherwise. + * Args: ctx: pointer to a context object. + * In/Out: seckey: pointer to a 32-byte secret key. If the secret key is + * invalid according to secp256k1_ec_seckey_verify, this + * function returns 0. seckey will be set to some unspecified + * value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak, which must be valid according to + * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly + * random 32-byte tweaks, the chance of being invalid is + * negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add( + const secp256k1_context *ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in + * future versions. */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( + const secp256k1_context *ctx, + unsigned char *seckey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) + SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_add instead"); + /** Tweak a public key by adding tweak times the generator to it. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or if the resulting public key - * would be invalid (only when the tweak is the complement of the - * corresponding private key). 1 otherwise. - * Args: ctx: pointer to a context object initialized for validation - * (cannot be NULL). - * In/Out: pubkey: pointer to a public key object. - * In: tweak: pointer to a 32-byte tweak. + * + * Returns: 0 if the arguments are invalid or the resulting public key would be + * invalid (only when the tweak is the negation of the corresponding + * secret key). 1 otherwise. + * Args: ctx: pointer to a context object. + * In/Out: pubkey: pointer to a public key object. pubkey will be set to an + * invalid value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak, which must be valid according to + * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly + * random 32-byte tweaks, the chance of being invalid is + * negligible (around 1 in 2^128). */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( - const secp256k1_context* ctx, + const secp256k1_context *ctx, secp256k1_pubkey *pubkey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Tweak a private key by multiplying it by a tweak. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. - * Args: ctx: pointer to a context object (cannot be NULL). - * In/Out: seckey: pointer to a 32-byte private key. - * In: tweak: pointer to a 32-byte tweak. +/** Tweak a secret key by multiplying it by a tweak. + * + * Returns: 0 if the arguments are invalid. 1 otherwise. + * Args: ctx: pointer to a context object. + * In/Out: seckey: pointer to a 32-byte secret key. If the secret key is + * invalid according to secp256k1_ec_seckey_verify, this + * function returns 0. seckey will be set to some unspecified + * value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to + * secp256k1_ec_seckey_verify, this function returns 0. For + * uniformly random 32-byte arrays the chance of being invalid + * is negligible (around 1 in 2^128). */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( - const secp256k1_context* ctx, +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul( + const secp256k1_context *ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in + * future versions. */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( + const secp256k1_context *ctx, + unsigned char *seckey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) + SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_mul instead"); + /** Tweak a public key by multiplying it by a tweak value. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. - * Args: ctx: pointer to a context object initialized for validation - * (cannot be NULL). - * In/Out: pubkey: pointer to a public key obkect. - * In: tweak: pointer to a 32-byte tweak. + * + * Returns: 0 if the arguments are invalid. 1 otherwise. + * Args: ctx: pointer to a context object. + * In/Out: pubkey: pointer to a public key object. pubkey will be set to an + * invalid value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to + * secp256k1_ec_seckey_verify, this function returns 0. For + * uniformly random 32-byte arrays the chance of being invalid + * is negligible (around 1 in 2^128). */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( - const secp256k1_context* ctx, + const secp256k1_context *ctx, secp256k1_pubkey *pubkey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Updates the context randomization. - * Returns: 1: randomization successfully updated +/** Randomizes the context to provide enhanced protection against side-channel leakage. + * + * Returns: 1: randomization successful * 0: error - * Args: ctx: pointer to a context object (cannot be NULL) - * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state) + * Args: ctx: pointer to a context object (not secp256k1_context_static). + * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state). + * + * While secp256k1 code is written and tested to be constant-time no matter what + * secret values are, it is possible that a compiler may output code which is not, + * and also that the CPU may not emit the same radio frequencies or draw the same + * amount of power for all values. Randomization of the context shields against + * side-channel observations which aim to exploit secret-dependent behaviour in + * certain computations which involve secret keys. + * + * It is highly recommended to call this function on contexts returned from + * secp256k1_context_create or secp256k1_context_clone (or from the corresponding + * functions in secp256k1_preallocated.h) before using these contexts to call API + * functions that perform computations involving secret keys, e.g., signing and + * public key generation. It is possible to call this function more than once on + * the same context, and doing so before every few computations involving secret + * keys is recommended as a defense-in-depth measure. Randomization of the static + * context secp256k1_context_static is not supported. + * + * Currently, the random seed is mainly used for blinding multiplications of a + * secret scalar with the elliptic curve base point. Multiplications of this + * kind are performed by exactly those API functions which are documented to + * require a context that is not secp256k1_context_static. As a rule of thumb, + * these are all functions which take a secret key (or a keypair) as an input. + * A notable exception to that rule is the ECDH module, which relies on a different + * kind of elliptic curve point multiplication and thus does not benefit from + * enhanced protection against side-channel leakage currently. */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( - secp256k1_context* ctx, + secp256k1_context *ctx, const unsigned char *seed32 ) SECP256K1_ARG_NONNULL(1); /** Add a number of public keys together. + * * Returns: 1: the sum of the public keys is valid. * 0: the sum of the public keys is not valid. - * Args: ctx: pointer to a context object - * Out: out: pointer to a public key object for placing the resulting public key - * (cannot be NULL) - * In: ins: pointer to array of pointers to public keys (cannot be NULL) - * n: the number of public keys to add together (must be at least 1) + * Args: ctx: pointer to a context object. + * Out: out: pointer to a public key object for placing the resulting public key. + * In: ins: pointer to array of pointers to public keys. + * n: the number of public keys to add together (must be at least 1). */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine( - const secp256k1_context* ctx, + const secp256k1_context *ctx, secp256k1_pubkey *out, - const secp256k1_pubkey * const * ins, + const secp256k1_pubkey * const *ins, size_t n -) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -# ifdef __cplusplus +/** Compute a tagged hash as defined in BIP-340. + * + * This is useful for creating a message hash and achieving domain separation + * through an application-specific tag. This function returns + * SHA256(SHA256(tag)||SHA256(tag)||msg). Therefore, tagged hash + * implementations optimized for a specific tag can precompute the SHA256 state + * after hashing the tag hashes. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object + * Out: hash32: pointer to a 32-byte array to store the resulting hash + * In: tag: pointer to an array containing the tag + * taglen: length of the tag array + * msg: pointer to an array containing the message + * msglen: length of the message array + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256( + const secp256k1_context *ctx, + unsigned char *hash32, + const unsigned char *tag, + size_t taglen, + const unsigned char *msg, + size_t msglen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); + +#ifdef __cplusplus } -# endif - #endif + +#endif /* SECP256K1_H */ diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1_ecdh.h b/crypto/secp256k1/libsecp256k1/include/secp256k1_ecdh.h index 4b84d7a963..4d9da3461d 100644 --- a/crypto/secp256k1/libsecp256k1/include/secp256k1_ecdh.h +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1_ecdh.h @@ -1,31 +1,63 @@ -#ifndef _SECP256K1_ECDH_ -# define _SECP256K1_ECDH_ +#ifndef SECP256K1_ECDH_H +#define SECP256K1_ECDH_H -# include "secp256k1.h" +#include "secp256k1.h" -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif + +/** A pointer to a function that hashes an EC point to obtain an ECDH secret + * + * Returns: 1 if the point was successfully hashed. + * 0 will cause secp256k1_ecdh to fail and return 0. + * Other return values are not allowed, and the behaviour of + * secp256k1_ecdh is undefined for other return values. + * Out: output: pointer to an array to be filled by the function + * In: x32: pointer to a 32-byte x coordinate + * y32: pointer to a 32-byte y coordinate + * data: arbitrary data pointer that is passed through + */ +typedef int (*secp256k1_ecdh_hash_function)( + unsigned char *output, + const unsigned char *x32, + const unsigned char *y32, + void *data +); + +/** An implementation of SHA256 hash function that applies to compressed public key. + * Populates the output parameter with 32 bytes. */ +SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256; + +/** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256). + * Populates the output parameter with 32 bytes. */ +SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default; /** Compute an EC Diffie-Hellman secret in constant time + * * Returns: 1: exponentiation was successful - * 0: scalar was invalid (zero or overflow) - * Args: ctx: pointer to a context object (cannot be NULL) - * Out: result: a 32-byte array which will be populated by an ECDH - * secret computed from the point and scalar - * In: pubkey: a pointer to a secp256k1_pubkey containing an - * initialized public key - * privkey: a 32-byte scalar with which to multiply the point + * 0: scalar was invalid (zero or overflow) or hashfp returned 0 + * Args: ctx: pointer to a context object. + * Out: output: pointer to an array to be filled by hashfp. + * In: pubkey: pointer to a secp256k1_pubkey containing an initialized public key. + * seckey: a 32-byte scalar with which to multiply the point. + * hashfp: pointer to a hash function. If NULL, + * secp256k1_ecdh_hash_function_sha256 is used + * (in which case, 32 bytes will be written to output). + * data: arbitrary data pointer that is passed through to hashfp + * (can be NULL for secp256k1_ecdh_hash_function_sha256). */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( - const secp256k1_context* ctx, - unsigned char *result, + const secp256k1_context *ctx, + unsigned char *output, const secp256k1_pubkey *pubkey, - const unsigned char *privkey + const unsigned char *seckey, + secp256k1_ecdh_hash_function hashfp, + void *data ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -# ifdef __cplusplus +#ifdef __cplusplus } -# endif - #endif + +#endif /* SECP256K1_ECDH_H */ diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1_ellswift.h b/crypto/secp256k1/libsecp256k1/include/secp256k1_ellswift.h new file mode 100644 index 0000000000..0d1293e94f --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1_ellswift.h @@ -0,0 +1,200 @@ +#ifndef SECP256K1_ELLSWIFT_H +#define SECP256K1_ELLSWIFT_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This module provides an implementation of ElligatorSwift as well as a + * version of x-only ECDH using it (including compatibility with BIP324). + * + * ElligatorSwift is described in https://eprint.iacr.org/2022/759 by + * Chavez-Saab, Rodriguez-Henriquez, and Tibouchi. It permits encoding + * uniformly chosen public keys as 64-byte arrays which are indistinguishable + * from uniformly random arrays. + * + * Let f be the function from pairs of field elements to point X coordinates, + * defined as follows (all operations modulo p = 2^256 - 2^32 - 977) + * f(u,t): + * - Let C = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852, + * a square root of -3. + * - If u=0, set u=1 instead. + * - If t=0, set t=1 instead. + * - If u^3 + t^2 + 7 = 0, multiply t by 2. + * - Let X = (u^3 + 7 - t^2) / (2 * t) + * - Let Y = (X + t) / (C * u) + * - Return the first in [u + 4 * Y^2, (-X/Y - u) / 2, (X/Y - u) / 2] that is an + * X coordinate on the curve (at least one of them is, for any u and t). + * + * Then an ElligatorSwift encoding of x consists of the 32-byte big-endian + * encodings of field elements u and t concatenated, where f(u,t) = x. + * The encoding algorithm is described in the paper, and effectively picks a + * uniformly random pair (u,t) among those which encode x. + * + * If the Y coordinate is relevant, it is given the same parity as t. + * + * Changes w.r.t. the paper: + * - The u=0, t=0, and u^3+t^2+7=0 conditions result in decoding to the point + * at infinity in the paper. Here they are remapped to finite points. + * - The paper uses an additional encoding bit for the parity of y. Here the + * parity of t is used (negating t does not affect the decoded x coordinate, + * so this is possible). + * + * For mathematical background about the scheme, see the doc/ellswift.md file. + */ + +/** A pointer to a function used by secp256k1_ellswift_xdh to hash the shared X + * coordinate along with the encoded public keys to a uniform shared secret. + * + * Returns: 1 if a shared secret was successfully computed. + * 0 will cause secp256k1_ellswift_xdh to fail and return 0. + * Other return values are not allowed, and the behaviour of + * secp256k1_ellswift_xdh is undefined for other return values. + * Out: output: pointer to an array to be filled by the function + * In: x32: pointer to the 32-byte serialized X coordinate + * of the resulting shared point (will not be NULL) + * ell_a64: pointer to the 64-byte encoded public key of party A + * (will not be NULL) + * ell_b64: pointer to the 64-byte encoded public key of party B + * (will not be NULL) + * data: arbitrary data pointer that is passed through + */ +typedef int (*secp256k1_ellswift_xdh_hash_function)( + unsigned char *output, + const unsigned char *x32, + const unsigned char *ell_a64, + const unsigned char *ell_b64, + void *data +); + +/** An implementation of an secp256k1_ellswift_xdh_hash_function which uses + * SHA256(prefix64 || ell_a64 || ell_b64 || x32), where prefix64 is the 64-byte + * array pointed to by data. */ +SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix; + +/** An implementation of an secp256k1_ellswift_xdh_hash_function compatible with + * BIP324. It returns H_tag(ell_a64 || ell_b64 || x32), where H_tag is the + * BIP340 tagged hash function with tag "bip324_ellswift_xonly_ecdh". Equivalent + * to secp256k1_ellswift_xdh_hash_function_prefix with prefix64 set to + * SHA256("bip324_ellswift_xonly_ecdh")||SHA256("bip324_ellswift_xonly_ecdh"). + * The data argument is ignored. */ +SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324; + +/** Construct a 64-byte ElligatorSwift encoding of a given pubkey. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object + * Out: ell64: pointer to a 64-byte array to be filled + * In: pubkey: pointer to a secp256k1_pubkey containing an + * initialized public key + * rnd32: pointer to 32 bytes of randomness + * + * It is recommended that rnd32 consists of 32 uniformly random bytes, not + * known to any adversary trying to detect whether public keys are being + * encoded, though 16 bytes of randomness (padded to an array of 32 bytes, + * e.g., with zeros) suffice to make the result indistinguishable from + * uniform. The randomness in rnd32 must not be a deterministic function of + * the pubkey (it can be derived from the private key, though). + * + * It is not guaranteed that the computed encoding is stable across versions + * of the library, even if all arguments to this function (including rnd32) + * are the same. + * + * This function runs in variable time. + */ +SECP256K1_API int secp256k1_ellswift_encode( + const secp256k1_context *ctx, + unsigned char *ell64, + const secp256k1_pubkey *pubkey, + const unsigned char *rnd32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Decode a 64-bytes ElligatorSwift encoded public key. + * + * Returns: always 1 + * Args: ctx: pointer to a context object + * Out: pubkey: pointer to a secp256k1_pubkey that will be filled + * In: ell64: pointer to a 64-byte array to decode + * + * This function runs in variable time. + */ +SECP256K1_API int secp256k1_ellswift_decode( + const secp256k1_context *ctx, + secp256k1_pubkey *pubkey, + const unsigned char *ell64 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Compute an ElligatorSwift public key for a secret key. + * + * Returns: 1: secret was valid, public key was stored. + * 0: secret was invalid, try again. + * Args: ctx: pointer to a context object + * Out: ell64: pointer to a 64-byte array to receive the ElligatorSwift + * public key + * In: seckey32: pointer to a 32-byte secret key + * auxrnd32: (optional) pointer to 32 bytes of randomness + * + * Constant time in seckey and auxrnd32, but not in the resulting public key. + * + * It is recommended that auxrnd32 contains 32 uniformly random bytes, though + * it is optional (and does result in encodings that are indistinguishable from + * uniform even without any auxrnd32). It differs from the (mandatory) rnd32 + * argument to secp256k1_ellswift_encode in this regard. + * + * This function can be used instead of calling secp256k1_ec_pubkey_create + * followed by secp256k1_ellswift_encode. It is safer, as it uses the secret + * key as entropy for the encoding (supplemented with auxrnd32, if provided). + * + * Like secp256k1_ellswift_encode, this function does not guarantee that the + * computed encoding is stable across versions of the library, even if all + * arguments (including auxrnd32) are the same. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_create( + const secp256k1_context *ctx, + unsigned char *ell64, + const unsigned char *seckey32, + const unsigned char *auxrnd32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Given a private key, and ElligatorSwift public keys sent in both directions, + * compute a shared secret using x-only Elliptic Curve Diffie-Hellman (ECDH). + * + * Returns: 1: shared secret was successfully computed + * 0: secret was invalid or hashfp returned 0 + * Args: ctx: pointer to a context object. + * Out: output: pointer to an array to be filled by hashfp. + * In: ell_a64: pointer to the 64-byte encoded public key of party A + * (will not be NULL) + * ell_b64: pointer to the 64-byte encoded public key of party B + * (will not be NULL) + * seckey32: pointer to our 32-byte secret key + * party: boolean indicating which party we are: zero if we are + * party A, non-zero if we are party B. seckey32 must be + * the private key corresponding to that party's ell_?64. + * This correspondence is not checked. + * hashfp: pointer to a hash function. + * data: arbitrary data pointer passed through to hashfp. + * + * Constant time in seckey32. + * + * This function is more efficient than decoding the public keys, and performing + * ECDH on them. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_xdh( + const secp256k1_context *ctx, + unsigned char *output, + const unsigned char *ell_a64, + const unsigned char *ell_b64, + const unsigned char *seckey32, + int party, + secp256k1_ellswift_xdh_hash_function hashfp, + void *data +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_ELLSWIFT_H */ diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1_extrakeys.h b/crypto/secp256k1/libsecp256k1/include/secp256k1_extrakeys.h new file mode 100644 index 0000000000..48c98693cf --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1_extrakeys.h @@ -0,0 +1,250 @@ +#ifndef SECP256K1_EXTRAKEYS_H +#define SECP256K1_EXTRAKEYS_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Opaque data structure that holds a parsed and valid "x-only" public key. + * An x-only pubkey encodes a point whose Y coordinate is even. It is + * serialized using only its X coordinate (32 bytes). See BIP-340 for more + * information about x-only pubkeys. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage, transmission, use + * use secp256k1_xonly_pubkey_serialize and secp256k1_xonly_pubkey_parse. To + * compare keys, use secp256k1_xonly_pubkey_cmp. + */ +typedef struct secp256k1_xonly_pubkey { + unsigned char data[64]; +} secp256k1_xonly_pubkey; + +/** Opaque data structure that holds a keypair consisting of a secret and a + * public key. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 96 bytes in size, and can be safely copied/moved. + */ +typedef struct secp256k1_keypair { + unsigned char data[96]; +} secp256k1_keypair; + +/** Parse a 32-byte sequence into a xonly_pubkey object. + * + * Returns: 1 if the public key was fully valid. + * 0 if the public key could not be parsed or is invalid. + * + * Args: ctx: pointer to a context object. + * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a + * parsed version of input. If not, it's set to an invalid value. + * In: input32: pointer to a serialized xonly_pubkey. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse( + const secp256k1_context *ctx, + secp256k1_xonly_pubkey *pubkey, + const unsigned char *input32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an xonly_pubkey object into a 32-byte sequence. + * + * Returns: 1 always. + * + * Args: ctx: pointer to a context object. + * Out: output32: pointer to a 32-byte array to place the serialized key in. + * In: pubkey: pointer to a secp256k1_xonly_pubkey containing an initialized public key. + */ +SECP256K1_API int secp256k1_xonly_pubkey_serialize( + const secp256k1_context *ctx, + unsigned char *output32, + const secp256k1_xonly_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Compare two x-only public keys using lexicographic order + * + * Returns: <0 if the first public key is less than the second + * >0 if the first public key is greater than the second + * 0 if the two public keys are equal + * Args: ctx: pointer to a context object. + * In: pubkey1: first public key to compare + * pubkey2: second public key to compare + */ +SECP256K1_API int secp256k1_xonly_pubkey_cmp( + const secp256k1_context *ctx, + const secp256k1_xonly_pubkey *pk1, + const secp256k1_xonly_pubkey *pk2 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey. + * + * Returns: 1 always. + * + * Args: ctx: pointer to a context object. + * Out: xonly_pubkey: pointer to an x-only public key object for placing the converted public key. + * pk_parity: Ignored if NULL. Otherwise, pointer to an integer that + * will be set to 1 if the point encoded by xonly_pubkey is + * the negation of the pubkey and set to 0 otherwise. + * In: pubkey: pointer to a public key that is converted. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey( + const secp256k1_context *ctx, + secp256k1_xonly_pubkey *xonly_pubkey, + int *pk_parity, + const secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); + +/** Tweak an x-only public key by adding the generator multiplied with tweak32 + * to it. + * + * Note that the resulting point can not in general be represented by an x-only + * pubkey because it may have an odd Y coordinate. Instead, the output_pubkey + * is a normal secp256k1_pubkey. + * + * Returns: 0 if the arguments are invalid or the resulting public key would be + * invalid (only when the tweak is the negation of the corresponding + * secret key). 1 otherwise. + * + * Args: ctx: pointer to a context object. + * Out: output_pubkey: pointer to a public key to store the result. Will be set + * to an invalid value if this function returns 0. + * In: internal_pubkey: pointer to an x-only pubkey to apply the tweak to. + * tweak32: pointer to a 32-byte tweak, which must be valid + * according to secp256k1_ec_seckey_verify or 32 zero + * bytes. For uniformly random 32-byte tweaks, the chance of + * being invalid is negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add( + const secp256k1_context *ctx, + secp256k1_pubkey *output_pubkey, + const secp256k1_xonly_pubkey *internal_pubkey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Checks that a tweaked pubkey is the result of calling + * secp256k1_xonly_pubkey_tweak_add with internal_pubkey and tweak32. + * + * The tweaked pubkey is represented by its 32-byte x-only serialization and + * its pk_parity, which can both be obtained by converting the result of + * tweak_add to a secp256k1_xonly_pubkey. + * + * Note that this alone does _not_ verify that the tweaked pubkey is a + * commitment. If the tweak is not chosen in a specific way, the tweaked pubkey + * can easily be the result of a different internal_pubkey and tweak. + * + * Returns: 0 if the arguments are invalid or the tweaked pubkey is not the + * result of tweaking the internal_pubkey with tweak32. 1 otherwise. + * Args: ctx: pointer to a context object. + * In: tweaked_pubkey32: pointer to a serialized xonly_pubkey. + * tweaked_pk_parity: the parity of the tweaked pubkey (whose serialization + * is passed in as tweaked_pubkey32). This must match the + * pk_parity value that is returned when calling + * secp256k1_xonly_pubkey with the tweaked pubkey, or + * this function will fail. + * internal_pubkey: pointer to an x-only public key object to apply the tweak to. + * tweak32: pointer to a 32-byte tweak. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check( + const secp256k1_context *ctx, + const unsigned char *tweaked_pubkey32, + int tweaked_pk_parity, + const secp256k1_xonly_pubkey *internal_pubkey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + +/** Compute the keypair for a valid secret key. + * + * See the documentation of `secp256k1_ec_seckey_verify` for more information + * about the validity of secret keys. + * + * Returns: 1: secret key is valid + * 0: secret key is invalid + * Args: ctx: pointer to a context object (not secp256k1_context_static). + * Out: keypair: pointer to the created keypair. + * In: seckey: pointer to a 32-byte secret key. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create( + const secp256k1_context *ctx, + secp256k1_keypair *keypair, + const unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Get the secret key from a keypair. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object. + * Out: seckey: pointer to a 32-byte buffer for the secret key. + * In: keypair: pointer to a keypair. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec( + const secp256k1_context *ctx, + unsigned char *seckey, + const secp256k1_keypair *keypair +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Get the public key from a keypair. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object. + * Out: pubkey: pointer to a pubkey object, set to the keypair public key. + * In: keypair: pointer to a keypair. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub( + const secp256k1_context *ctx, + secp256k1_pubkey *pubkey, + const secp256k1_keypair *keypair +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Get the x-only public key from a keypair. + * + * This is the same as calling secp256k1_keypair_pub and then + * secp256k1_xonly_pubkey_from_pubkey. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object. + * Out: pubkey: pointer to an xonly_pubkey object, set to the keypair + * public key after converting it to an xonly_pubkey. + * pk_parity: Ignored if NULL. Otherwise, pointer to an integer that will be set to the + * pk_parity argument of secp256k1_xonly_pubkey_from_pubkey. + * In: keypair: pointer to a keypair. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub( + const secp256k1_context *ctx, + secp256k1_xonly_pubkey *pubkey, + int *pk_parity, + const secp256k1_keypair *keypair +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); + +/** Tweak a keypair by adding tweak32 to the secret key and updating the public + * key accordingly. + * + * Calling this function and then secp256k1_keypair_pub results in the same + * public key as calling secp256k1_keypair_xonly_pub and then + * secp256k1_xonly_pubkey_tweak_add. + * + * Returns: 0 if the arguments are invalid or the resulting keypair would be + * invalid (only when the tweak is the negation of the keypair's + * secret key). 1 otherwise. + * + * Args: ctx: pointer to a context object. + * In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to + * an invalid value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak, which must be valid according to + * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly + * random 32-byte tweaks, the chance of being invalid is + * negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add( + const secp256k1_context *ctx, + secp256k1_keypair *keypair, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_EXTRAKEYS_H */ diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1_musig.h b/crypto/secp256k1/libsecp256k1/include/secp256k1_musig.h new file mode 100644 index 0000000000..11b8f08c88 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1_musig.h @@ -0,0 +1,588 @@ +#ifndef SECP256K1_MUSIG_H +#define SECP256K1_MUSIG_H + +#include "secp256k1_extrakeys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** This module implements BIP 327 "MuSig2 for BIP340-compatible + * Multi-Signatures" + * (https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki) + * v1.0.0. You can find an example demonstrating the musig module in + * examples/musig.c. + * + * The module also supports BIP 341 ("Taproot") public key tweaking. + * + * It is recommended to read the documentation in this include file carefully. + * Further notes on API usage can be found in doc/musig.md + * + * Since the first version of MuSig is essentially replaced by MuSig2, we use + * MuSig, musig and MuSig2 synonymously unless noted otherwise. + */ + +/** Opaque data structures + * + * The exact representation of data inside the opaque data structures is + * implementation defined and not guaranteed to be portable between different + * platforms or versions. With the exception of `secp256k1_musig_secnonce`, the + * data structures can be safely copied/moved. If you need to convert to a + * format suitable for storage, transmission, or comparison, use the + * corresponding serialization and parsing functions. + */ + +/** Opaque data structure that caches information about public key aggregation. + * + * Guaranteed to be 197 bytes in size. No serialization and parsing functions + * (yet). + */ +typedef struct secp256k1_musig_keyagg_cache { + unsigned char data[197]; +} secp256k1_musig_keyagg_cache; + +/** Opaque data structure that holds a signer's _secret_ nonce. + * + * Guaranteed to be 132 bytes in size. + * + * WARNING: This structure MUST NOT be copied or read or written to directly. A + * signer who is online throughout the whole process and can keep this + * structure in memory can use the provided API functions for a safe standard + * workflow. + * + * Copying this data structure can result in nonce reuse which will leak the + * secret signing key. + */ +typedef struct secp256k1_musig_secnonce { + unsigned char data[132]; +} secp256k1_musig_secnonce; + +/** Opaque data structure that holds a signer's public nonce. + * + * Guaranteed to be 132 bytes in size. Serialized and parsed with + * `musig_pubnonce_serialize` and `musig_pubnonce_parse`. + */ +typedef struct secp256k1_musig_pubnonce { + unsigned char data[132]; +} secp256k1_musig_pubnonce; + +/** Opaque data structure that holds an aggregate public nonce. + * + * Guaranteed to be 132 bytes in size. Serialized and parsed with + * `musig_aggnonce_serialize` and `musig_aggnonce_parse`. + */ +typedef struct secp256k1_musig_aggnonce { + unsigned char data[132]; +} secp256k1_musig_aggnonce; + +/** Opaque data structure that holds a MuSig session. + * + * This structure is not required to be kept secret for the signing protocol to + * be secure. Guaranteed to be 133 bytes in size. No serialization and parsing + * functions (yet). + */ +typedef struct secp256k1_musig_session { + unsigned char data[133]; +} secp256k1_musig_session; + +/** Opaque data structure that holds a partial MuSig signature. + * + * Guaranteed to be 36 bytes in size. Serialized and parsed with + * `musig_partial_sig_serialize` and `musig_partial_sig_parse`. + */ +typedef struct secp256k1_musig_partial_sig { + unsigned char data[36]; +} secp256k1_musig_partial_sig; + +/** Parse a signer's public nonce. + * + * Returns: 1 when the nonce could be parsed, 0 otherwise. + * Args: ctx: pointer to a context object + * Out: nonce: pointer to a nonce object + * In: in66: pointer to the 66-byte nonce to be parsed + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubnonce_parse( + const secp256k1_context *ctx, + secp256k1_musig_pubnonce *nonce, + const unsigned char *in66 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize a signer's public nonce + * + * Returns: 1 always + * Args: ctx: pointer to a context object + * Out: out66: pointer to a 66-byte array to store the serialized nonce + * In: nonce: pointer to the nonce + */ +SECP256K1_API int secp256k1_musig_pubnonce_serialize( + const secp256k1_context *ctx, + unsigned char *out66, + const secp256k1_musig_pubnonce *nonce +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Parse an aggregate public nonce. + * + * Returns: 1 when the nonce could be parsed, 0 otherwise. + * Args: ctx: pointer to a context object + * Out: nonce: pointer to a nonce object + * In: in66: pointer to the 66-byte nonce to be parsed + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_aggnonce_parse( + const secp256k1_context *ctx, + secp256k1_musig_aggnonce *nonce, + const unsigned char *in66 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an aggregate public nonce + * + * Returns: 1 always + * Args: ctx: pointer to a context object + * Out: out66: pointer to a 66-byte array to store the serialized nonce + * In: nonce: pointer to the nonce + */ +SECP256K1_API int secp256k1_musig_aggnonce_serialize( + const secp256k1_context *ctx, + unsigned char *out66, + const secp256k1_musig_aggnonce *nonce +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Parse a MuSig partial signature. + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: pointer to a context object + * Out: sig: pointer to a signature object + * In: in32: pointer to the 32-byte signature to be parsed + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_parse( + const secp256k1_context *ctx, + secp256k1_musig_partial_sig *sig, + const unsigned char *in32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize a MuSig partial signature + * + * Returns: 1 always + * Args: ctx: pointer to a context object + * Out: out32: pointer to a 32-byte array to store the serialized signature + * In: sig: pointer to the signature + */ +SECP256K1_API int secp256k1_musig_partial_sig_serialize( + const secp256k1_context *ctx, + unsigned char *out32, + const secp256k1_musig_partial_sig *sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Computes an aggregate public key and uses it to initialize a keyagg_cache + * + * Different orders of `pubkeys` result in different `agg_pk`s. + * + * Before aggregating, the pubkeys can be sorted with `secp256k1_ec_pubkey_sort` + * which ensures the same `agg_pk` result for the same multiset of pubkeys. + * This is useful to do before `pubkey_agg`, such that the order of pubkeys + * does not affect the aggregate public key. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: agg_pk: the MuSig-aggregated x-only public key. If you do not need it, + * this arg can be NULL. + * keyagg_cache: if non-NULL, pointer to a musig_keyagg_cache struct that + * is required for signing (or observing the signing session + * and verifying partial signatures). + * In: pubkeys: input array of pointers to public keys to aggregate. The order + * is important; a different order will result in a different + * aggregate public key. + * n_pubkeys: length of pubkeys array. Must be greater than 0. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_agg( + const secp256k1_context *ctx, + secp256k1_xonly_pubkey *agg_pk, + secp256k1_musig_keyagg_cache *keyagg_cache, + const secp256k1_pubkey * const *pubkeys, + size_t n_pubkeys +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(4); + +/** Obtain the aggregate public key from a keyagg_cache. + * + * This is only useful if you need the non-xonly public key, in particular for + * plain (non-xonly) tweaking or batch-verifying multiple key aggregations + * (not implemented). + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: agg_pk: the MuSig-aggregated public key. + * In: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by + * `musig_pubkey_agg` + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_get( + const secp256k1_context *ctx, + secp256k1_pubkey *agg_pk, + const secp256k1_musig_keyagg_cache *keyagg_cache +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Apply plain "EC" tweaking to a public key in a given keyagg_cache by adding + * the generator multiplied with `tweak32` to it. This is useful for deriving + * child keys from an aggregate public key via BIP 32 where `tweak32` is set to + * a hash as defined in BIP 32. + * + * Callers are responsible for deriving `tweak32` in a way that does not reduce + * the security of MuSig (for example, by following BIP 32). + * + * The tweaking method is the same as `secp256k1_ec_pubkey_tweak_add`. So after + * the following pseudocode buf and buf2 have identical contents (absent + * earlier failures). + * + * secp256k1_musig_pubkey_agg(..., keyagg_cache, pubkeys, ...) + * secp256k1_musig_pubkey_get(..., agg_pk, keyagg_cache) + * secp256k1_musig_pubkey_ec_tweak_add(..., output_pk, tweak32, keyagg_cache) + * secp256k1_ec_pubkey_serialize(..., buf, ..., output_pk, ...) + * secp256k1_ec_pubkey_tweak_add(..., agg_pk, tweak32) + * secp256k1_ec_pubkey_serialize(..., buf2, ..., agg_pk, ...) + * + * This function is required if you want to _sign_ for a tweaked aggregate key. + * If you are only computing a public key but not intending to create a + * signature for it, use `secp256k1_ec_pubkey_tweak_add` instead. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: output_pubkey: pointer to a public key to store the result. Will be set + * to an invalid value if this function returns 0. If you + * do not need it, this arg can be NULL. + * In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by + * `musig_pubkey_agg` + * In: tweak32: pointer to a 32-byte tweak. The tweak is valid if it passes + * `secp256k1_ec_seckey_verify` and is not equal to the + * secret key corresponding to the public key represented + * by keyagg_cache or its negation. For uniformly random + * 32-byte arrays the chance of being invalid is + * negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_ec_tweak_add( + const secp256k1_context *ctx, + secp256k1_pubkey *output_pubkey, + secp256k1_musig_keyagg_cache *keyagg_cache, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Apply x-only tweaking to a public key in a given keyagg_cache by adding the + * generator multiplied with `tweak32` to it. This is useful for creating + * Taproot outputs where `tweak32` is set to a TapTweak hash as defined in BIP + * 341. + * + * Callers are responsible for deriving `tweak32` in a way that does not reduce + * the security of MuSig (for example, by following Taproot BIP 341). + * + * The tweaking method is the same as `secp256k1_xonly_pubkey_tweak_add`. So in + * the following pseudocode xonly_pubkey_tweak_add_check (absent earlier + * failures) returns 1. + * + * secp256k1_musig_pubkey_agg(..., agg_pk, keyagg_cache, pubkeys, ...) + * secp256k1_musig_pubkey_xonly_tweak_add(..., output_pk, keyagg_cache, tweak32) + * secp256k1_xonly_pubkey_serialize(..., buf, output_pk) + * secp256k1_xonly_pubkey_tweak_add_check(..., buf, ..., agg_pk, tweak32) + * + * This function is required if you want to _sign_ for a tweaked aggregate key. + * If you are only computing a public key but not intending to create a + * signature for it, use `secp256k1_xonly_pubkey_tweak_add` instead. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: output_pubkey: pointer to a public key to store the result. Will be set + * to an invalid value if this function returns 0. If you + * do not need it, this arg can be NULL. + * In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by + * `musig_pubkey_agg` + * In: tweak32: pointer to a 32-byte tweak. The tweak is valid if it passes + * `secp256k1_ec_seckey_verify` and is not equal to the + * secret key corresponding to the public key represented + * by keyagg_cache or its negation. For uniformly random + * 32-byte arrays the chance of being invalid is + * negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_xonly_tweak_add( + const secp256k1_context *ctx, + secp256k1_pubkey *output_pubkey, + secp256k1_musig_keyagg_cache *keyagg_cache, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Starts a signing session by generating a nonce + * + * This function outputs a secret nonce that will be required for signing and a + * corresponding public nonce that is intended to be sent to other signers. + * + * MuSig differs from regular Schnorr signing in that implementers _must_ take + * special care to not reuse a nonce. This can be ensured by following these rules: + * + * 1. Each call to this function must have a UNIQUE session_secrand32 that must + * NOT BE REUSED in subsequent calls to this function and must be KEPT + * SECRET (even from other signers). + * 2. If you already know the seckey, message or aggregate public key + * cache, they can be optionally provided to derive the nonce and increase + * misuse-resistance. The extra_input32 argument can be used to provide + * additional data that does not repeat in normal scenarios, such as the + * current time. + * 3. Avoid copying (or serializing) the secnonce. This reduces the possibility + * that it is used more than once for signing. + * + * If you don't have access to good randomness for session_secrand32, but you + * have access to a non-repeating counter, then see + * secp256k1_musig_nonce_gen_counter. + * + * Remember that nonce reuse will leak the secret key! + * Note that using the same seckey for multiple MuSig sessions is fine. + * + * Returns: 0 if the arguments are invalid and 1 otherwise + * Args: ctx: pointer to a context object (not secp256k1_context_static) + * Out: secnonce: pointer to a structure to store the secret nonce + * pubnonce: pointer to a structure to store the public nonce + * In/Out: + * session_secrand32: a 32-byte session_secrand32 as explained above. Must be unique to this + * call to secp256k1_musig_nonce_gen and must be uniformly + * random. If the function call is successful, the + * session_secrand32 buffer is invalidated to prevent reuse. + * In: + * seckey: the 32-byte secret key that will later be used for signing, if + * already known (can be NULL) + * pubkey: public key of the signer creating the nonce. The secnonce + * output of this function cannot be used to sign for any + * other public key. While the public key should correspond + * to the provided seckey, a mismatch will not cause the + * function to return 0. + * msg32: the 32-byte message that will later be signed, if already known + * (can be NULL) + * keyagg_cache: pointer to the keyagg_cache that was used to create the aggregate + * (and potentially tweaked) public key if already known + * (can be NULL) + * extra_input32: an optional 32-byte array that is input to the nonce + * derivation function (can be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_gen( + const secp256k1_context *ctx, + secp256k1_musig_secnonce *secnonce, + secp256k1_musig_pubnonce *pubnonce, + unsigned char *session_secrand32, + const unsigned char *seckey, + const secp256k1_pubkey *pubkey, + const unsigned char *msg32, + const secp256k1_musig_keyagg_cache *keyagg_cache, + const unsigned char *extra_input32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6); + + +/** Alternative way to generate a nonce and start a signing session + * + * This function outputs a secret nonce that will be required for signing and a + * corresponding public nonce that is intended to be sent to other signers. + * + * This function differs from `secp256k1_musig_nonce_gen` by accepting a + * non-repeating counter value instead of a secret random value. This requires + * that a secret key is provided to `secp256k1_musig_nonce_gen_counter` + * (through the keypair argument), as opposed to `secp256k1_musig_nonce_gen` + * where the seckey argument is optional. + * + * MuSig differs from regular Schnorr signing in that implementers _must_ take + * special care to not reuse a nonce. This can be ensured by following these rules: + * + * 1. The nonrepeating_cnt argument must be a counter value that never repeats, + * i.e., you must never call `secp256k1_musig_nonce_gen_counter` twice with + * the same keypair and nonrepeating_cnt value. For example, this implies + * that if the same keypair is used with `secp256k1_musig_nonce_gen_counter` + * on multiple devices, none of the devices should have the same counter + * value as any other device. + * 2. If the seckey, message or aggregate public key cache is already available + * at this stage, any of these can be optionally provided, in which case + * they will be used in the derivation of the nonce and increase + * misuse-resistance. The extra_input32 argument can be used to provide + * additional data that does not repeat in normal scenarios, such as the + * current time. + * 3. Avoid copying (or serializing) the secnonce. This reduces the possibility + * that it is used more than once for signing. + * + * Remember that nonce reuse will leak the secret key! + * Note that using the same keypair for multiple MuSig sessions is fine. + * + * Returns: 0 if the arguments are invalid and 1 otherwise + * Args: ctx: pointer to a context object (not secp256k1_context_static) + * Out: secnonce: pointer to a structure to store the secret nonce + * pubnonce: pointer to a structure to store the public nonce + * In: + * nonrepeating_cnt: the value of a counter as explained above. Must be + * unique to this call to secp256k1_musig_nonce_gen. + * keypair: keypair of the signer creating the nonce. The secnonce + * output of this function cannot be used to sign for any + * other keypair. + * msg32: the 32-byte message that will later be signed, if already known + * (can be NULL) + * keyagg_cache: pointer to the keyagg_cache that was used to create the aggregate + * (and potentially tweaked) public key if already known + * (can be NULL) + * extra_input32: an optional 32-byte array that is input to the nonce + * derivation function (can be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_gen_counter( + const secp256k1_context *ctx, + secp256k1_musig_secnonce *secnonce, + secp256k1_musig_pubnonce *pubnonce, + uint64_t nonrepeating_cnt, + const secp256k1_keypair *keypair, + const unsigned char *msg32, + const secp256k1_musig_keyagg_cache *keyagg_cache, + const unsigned char *extra_input32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); + +/** Aggregates the nonces of all signers into a single nonce + * + * This can be done by an untrusted party to reduce the communication + * between signers. Instead of everyone sending nonces to everyone else, there + * can be one party receiving all nonces, aggregating the nonces with this + * function and then sending only the aggregate nonce back to the signers. + * + * If the aggregator does not compute the aggregate nonce correctly, the final + * signature will be invalid. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: aggnonce: pointer to an aggregate public nonce object for + * musig_nonce_process + * In: pubnonces: array of pointers to public nonces sent by the + * signers + * n_pubnonces: number of elements in the pubnonces array. Must be + * greater than 0. + */ +SECP256K1_API int secp256k1_musig_nonce_agg( + const secp256k1_context *ctx, + secp256k1_musig_aggnonce *aggnonce, + const secp256k1_musig_pubnonce * const *pubnonces, + size_t n_pubnonces +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Takes the aggregate nonce and creates a session that is required for signing + * and verification of partial signatures. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: session: pointer to a struct to store the session + * In: aggnonce: pointer to an aggregate public nonce object that is the + * output of musig_nonce_agg + * msg32: the 32-byte message to sign + * keyagg_cache: pointer to the keyagg_cache that was used to create the + * aggregate (and potentially tweaked) pubkey + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_process( + const secp256k1_context *ctx, + secp256k1_musig_session *session, + const secp256k1_musig_aggnonce *aggnonce, + const unsigned char *msg32, + const secp256k1_musig_keyagg_cache *keyagg_cache +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + +/** Produces a partial signature + * + * This function overwrites the given secnonce with zeros and will abort if given a + * secnonce that is all zeros. This is a best effort attempt to protect against nonce + * reuse. However, this is of course easily defeated if the secnonce has been + * copied (or serialized). Remember that nonce reuse will leak the secret key! + * + * For signing to succeed, the secnonce provided to this function must have + * been generated for the provided keypair. This means that when signing for a + * keypair consisting of a seckey and pubkey, the secnonce must have been + * created by calling musig_nonce_gen with that pubkey. Otherwise, the + * illegal_callback is called. + * + * This function does not verify the output partial signature, deviating from + * the BIP 327 specification. It is recommended to verify the output partial + * signature with `secp256k1_musig_partial_sig_verify` to prevent random or + * adversarially provoked computation errors. + * + * Returns: 0 if the arguments are invalid or the provided secnonce has already + * been used for signing, 1 otherwise + * Args: ctx: pointer to a context object + * Out: partial_sig: pointer to struct to store the partial signature + * In/Out: secnonce: pointer to the secnonce struct created in + * musig_nonce_gen that has been never used in a + * partial_sign call before and has been created for the + * keypair + * In: keypair: pointer to keypair to sign the message with + * keyagg_cache: pointer to the keyagg_cache that was output when the + * aggregate public key for this session + * session: pointer to the session that was created with + * musig_nonce_process + */ +SECP256K1_API int secp256k1_musig_partial_sign( + const secp256k1_context *ctx, + secp256k1_musig_partial_sig *partial_sig, + secp256k1_musig_secnonce *secnonce, + const secp256k1_keypair *keypair, + const secp256k1_musig_keyagg_cache *keyagg_cache, + const secp256k1_musig_session *session +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); + +/** Verifies an individual signer's partial signature + * + * The signature is verified for a specific signing session. In order to avoid + * accidentally verifying a signature from a different or non-existing signing + * session, you must ensure the following: + * 1. The `keyagg_cache` argument is identical to the one used to create the + * `session` with `musig_nonce_process`. + * 2. The `pubkey` argument must be identical to the one sent by the signer + * before aggregating it with `musig_pubkey_agg` to create the + * `keyagg_cache`. + * 3. The `pubnonce` argument must be identical to the one sent by the signer + * before aggregating it with `musig_nonce_agg` and using the result to + * create the `session` with `musig_nonce_process`. + * + * It is not required to call this function in regular MuSig sessions, because + * if any partial signature does not verify, the final signature will not + * verify either, so the problem will be caught. However, this function + * provides the ability to identify which specific partial signature fails + * verification. + * + * Returns: 0 if the arguments are invalid or the partial signature does not + * verify, 1 otherwise + * Args ctx: pointer to a context object + * In: partial_sig: pointer to partial signature to verify, sent by + * the signer associated with `pubnonce` and `pubkey` + * pubnonce: public nonce of the signer in the signing session + * pubkey: public key of the signer in the signing session + * keyagg_cache: pointer to the keyagg_cache that was output when the + * aggregate public key for this signing session + * session: pointer to the session that was created with + * `musig_nonce_process` + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify( + const secp256k1_context *ctx, + const secp256k1_musig_partial_sig *partial_sig, + const secp256k1_musig_pubnonce *pubnonce, + const secp256k1_pubkey *pubkey, + const secp256k1_musig_keyagg_cache *keyagg_cache, + const secp256k1_musig_session *session +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); + +/** Aggregates partial signatures + * + * Returns: 0 if the arguments are invalid, 1 otherwise (which does NOT mean + * the resulting signature verifies). + * Args: ctx: pointer to a context object + * Out: sig64: complete (but possibly invalid) Schnorr signature + * In: session: pointer to the session that was created with + * musig_nonce_process + * partial_sigs: array of pointers to partial signatures to aggregate + * n_sigs: number of elements in the partial_sigs array. Must be + * greater than 0. + */ +SECP256K1_API int secp256k1_musig_partial_sig_agg( + const secp256k1_context *ctx, + unsigned char *sig64, + const secp256k1_musig_session *session, + const secp256k1_musig_partial_sig * const *partial_sigs, + size_t n_sigs +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1_preallocated.h b/crypto/secp256k1/libsecp256k1/include/secp256k1_preallocated.h new file mode 100644 index 0000000000..f2d95c245e --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1_preallocated.h @@ -0,0 +1,134 @@ +#ifndef SECP256K1_PREALLOCATED_H +#define SECP256K1_PREALLOCATED_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The module provided by this header file is intended for settings in which it + * is not possible or desirable to rely on dynamic memory allocation. It provides + * functions for creating, cloning, and destroying secp256k1 context objects in a + * contiguous fixed-size block of memory provided by the caller. + * + * Context objects created by functions in this module can be used like contexts + * objects created by functions in secp256k1.h, i.e., they can be passed to any + * API function that expects a context object (see secp256k1.h for details). The + * only exception is that context objects created by functions in this module + * must be destroyed using secp256k1_context_preallocated_destroy (in this + * module) instead of secp256k1_context_destroy (in secp256k1.h). + * + * It is guaranteed that functions in this module will not call malloc or its + * friends realloc, calloc, and free. + */ + +/** Determine the memory size of a secp256k1 context object to be created in + * caller-provided memory. + * + * The purpose of this function is to determine how much memory must be provided + * to secp256k1_context_preallocated_create. + * + * Returns: the required size of the caller-provided memory block + * In: flags: which parts of the context to initialize. + */ +SECP256K1_API size_t secp256k1_context_preallocated_size( + unsigned int flags +) SECP256K1_WARN_UNUSED_RESULT; + +/** Create a secp256k1 context object in caller-provided memory. + * + * The caller must provide a pointer to a rewritable contiguous block of memory + * of size at least secp256k1_context_preallocated_size(flags) bytes, suitably + * aligned to hold an object of any type. + * + * The block of memory is exclusively owned by the created context object during + * the lifetime of this context object, which begins with the call to this + * function and ends when a call to secp256k1_context_preallocated_destroy + * (which destroys the context object again) returns. During the lifetime of the + * context object, the caller is obligated not to access this block of memory, + * i.e., the caller may not read or write the memory, e.g., by copying the memory + * contents to a different location or trying to create a second context object + * in the memory. In simpler words, the prealloc pointer (or any pointer derived + * from it) should not be used during the lifetime of the context object. + * + * Returns: pointer to newly created context object. + * In: prealloc: pointer to a rewritable contiguous block of memory of + * size at least secp256k1_context_preallocated_size(flags) + * bytes, as detailed above. + * flags: which parts of the context to initialize. + * + * See secp256k1_context_create (in secp256k1.h) for further details. + * + * See also secp256k1_context_randomize (in secp256k1.h) + * and secp256k1_context_preallocated_destroy. + */ +SECP256K1_API secp256k1_context *secp256k1_context_preallocated_create( + void *prealloc, + unsigned int flags +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; + +/** Determine the memory size of a secp256k1 context object to be copied into + * caller-provided memory. + * + * Returns: the required size of the caller-provided memory block. + * In: ctx: pointer to a context to copy. + */ +SECP256K1_API size_t secp256k1_context_preallocated_clone_size( + const secp256k1_context *ctx +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; + +/** Copy a secp256k1 context object into caller-provided memory. + * + * The caller must provide a pointer to a rewritable contiguous block of memory + * of size at least secp256k1_context_preallocated_size(flags) bytes, suitably + * aligned to hold an object of any type. + * + * The block of memory is exclusively owned by the created context object during + * the lifetime of this context object, see the description of + * secp256k1_context_preallocated_create for details. + * + * Cloning secp256k1_context_static is not possible, and should not be emulated by + * the caller (e.g., using memcpy). Create a new context instead. + * + * Returns: pointer to a newly created context object. + * Args: ctx: pointer to a context to copy (not secp256k1_context_static). + * In: prealloc: pointer to a rewritable contiguous block of memory of + * size at least secp256k1_context_preallocated_size(flags) + * bytes, as detailed above. + */ +SECP256K1_API secp256k1_context *secp256k1_context_preallocated_clone( + const secp256k1_context *ctx, + void *prealloc +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT; + +/** Destroy a secp256k1 context object that has been created in + * caller-provided memory. + * + * The context pointer may not be used afterwards. + * + * The context to destroy must have been created using + * secp256k1_context_preallocated_create or secp256k1_context_preallocated_clone. + * If the context has instead been created using secp256k1_context_create or + * secp256k1_context_clone, the behaviour is undefined. In that case, + * secp256k1_context_destroy must be used instead. + * + * If required, it is the responsibility of the caller to deallocate the block + * of memory properly after this function returns, e.g., by calling free on the + * preallocated pointer given to secp256k1_context_preallocated_create or + * secp256k1_context_preallocated_clone. + * + * Args: ctx: pointer to a context to destroy, constructed using + * secp256k1_context_preallocated_create or + * secp256k1_context_preallocated_clone + * (i.e., not secp256k1_context_static). + */ +SECP256K1_API void secp256k1_context_preallocated_destroy( + secp256k1_context *ctx +) SECP256K1_ARG_NONNULL(1); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_PREALLOCATED_H */ diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1_recovery.h b/crypto/secp256k1/libsecp256k1/include/secp256k1_recovery.h index 0553797253..93a2e4ccbd 100644 --- a/crypto/secp256k1/libsecp256k1/include/secp256k1_recovery.h +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1_recovery.h @@ -1,13 +1,13 @@ -#ifndef _SECP256K1_RECOVERY_ -# define _SECP256K1_RECOVERY_ +#ifndef SECP256K1_RECOVERY_H +#define SECP256K1_RECOVERY_H -# include "secp256k1.h" +#include "secp256k1.h" -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif -/** Opaque data structured that holds a parsed ECDSA signature, +/** Opaque data structure that holds a parsed ECDSA signature, * supporting pubkey recovery. * * The exact representation of data inside is implementation defined and not @@ -21,21 +21,21 @@ extern "C" { * recoverability) will have identical representation, so they can be * memcmp'ed. */ -typedef struct { +typedef struct secp256k1_ecdsa_recoverable_signature { unsigned char data[65]; } secp256k1_ecdsa_recoverable_signature; /** Parse a compact ECDSA signature (64 bytes + recovery id). * * Returns: 1 when the signature could be parsed, 0 otherwise - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input64: a pointer to a 64-byte compact signature + * Args: ctx: pointer to a context object + * Out: sig: pointer to a signature object + * In: input64: pointer to a 64-byte compact signature * recid: the recovery id (0, 1, 2 or 3) */ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( - const secp256k1_context* ctx, - secp256k1_ecdsa_recoverable_signature* sig, + const secp256k1_context *ctx, + secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *input64, int recid ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); @@ -43,45 +43,48 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( /** Convert a recoverable signature into a normal signature. * * Returns: 1 - * Out: sig: a pointer to a normal signature (cannot be NULL). - * In: sigin: a pointer to a recoverable signature (cannot be NULL). + * Args: ctx: pointer to a context object. + * Out: sig: pointer to a normal signature. + * In: sigin: pointer to a recoverable signature. */ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const secp256k1_ecdsa_recoverable_signature* sigin + const secp256k1_context *ctx, + secp256k1_ecdsa_signature *sig, + const secp256k1_ecdsa_recoverable_signature *sigin ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Serialize an ECDSA signature in compact format (64 bytes + recovery id). * * Returns: 1 - * Args: ctx: a secp256k1 context object - * Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL) - * recid: a pointer to an integer to hold the recovery id (can be NULL). - * In: sig: a pointer to an initialized signature object (cannot be NULL) + * Args: ctx: pointer to a context object. + * Out: output64: pointer to a 64-byte array of the compact signature. + * recid: pointer to an integer to hold the recovery id. + * In: sig: pointer to an initialized signature object. */ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( - const secp256k1_context* ctx, + const secp256k1_context *ctx, unsigned char *output64, int *recid, - const secp256k1_ecdsa_recoverable_signature* sig + const secp256k1_ecdsa_recoverable_signature *sig ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Create a recoverable ECDSA signature. * * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) + * 0: the nonce generation function failed, or the secret key was invalid. + * Args: ctx: pointer to a context object (not secp256k1_context_static). + * Out: sig: pointer to an array where the signature will be placed. + * In: msghash32: the 32-byte message hash being signed. + * seckey: pointer to a 32-byte secret key. + * noncefp: pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_default is used. + * ndata: pointer to arbitrary data used by the nonce generation function + * (can be NULL for secp256k1_nonce_function_default). */ SECP256K1_API int secp256k1_ecdsa_sign_recoverable( - const secp256k1_context* ctx, + const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, - const unsigned char *msg32, + const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata @@ -91,20 +94,20 @@ SECP256K1_API int secp256k1_ecdsa_sign_recoverable( * * Returns: 1: public key successfully recovered (which guarantees a correct signature). * 0: otherwise. - * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) - * Out: pubkey: pointer to the recovered public key (cannot be NULL) - * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) + * Args: ctx: pointer to a context object. + * Out: pubkey: pointer to the recovered public key. + * In: sig: pointer to initialized signature that supports pubkey recovery. + * msghash32: the 32-byte message hash assumed to be signed. */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( - const secp256k1_context* ctx, + const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *sig, - const unsigned char *msg32 + const unsigned char *msghash32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -# ifdef __cplusplus +#ifdef __cplusplus } -# endif - #endif + +#endif /* SECP256K1_RECOVERY_H */ diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1_schnorrsig.h b/crypto/secp256k1/libsecp256k1/include/secp256k1_schnorrsig.h new file mode 100644 index 0000000000..013d4ee73d --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1_schnorrsig.h @@ -0,0 +1,190 @@ +#ifndef SECP256K1_SCHNORRSIG_H +#define SECP256K1_SCHNORRSIG_H + +#include "secp256k1.h" +#include "secp256k1_extrakeys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** This module implements a variant of Schnorr signatures compliant with + * Bitcoin Improvement Proposal 340 "Schnorr Signatures for secp256k1" + * (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). + */ + +/** A pointer to a function to deterministically generate a nonce. + * + * Same as secp256k1_nonce function with the exception of accepting an + * additional pubkey argument and not requiring an attempt argument. The pubkey + * argument can protect signature schemes with key-prefixed challenge hash + * inputs against reusing the nonce when signing with the wrong precomputed + * pubkey. + * + * Returns: 1 if a nonce was successfully generated. 0 will cause signing to + * return an error. + * Out: nonce32: pointer to a 32-byte array to be filled by the function + * In: msg: the message being verified. Is NULL if and only if msglen + * is 0. + * msglen: the length of the message + * key32: pointer to a 32-byte secret key (will not be NULL) + * xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32 + * (will not be NULL) + * algo: pointer to an array describing the signature + * algorithm (will not be NULL) + * algolen: the length of the algo array + * data: arbitrary data pointer that is passed through + * + * Except for test cases, this function should compute some cryptographic hash of + * the message, the key, the pubkey, the algorithm description, and data. + */ +typedef int (*secp256k1_nonce_function_hardened)( + unsigned char *nonce32, + const unsigned char *msg, + size_t msglen, + const unsigned char *key32, + const unsigned char *xonly_pk32, + const unsigned char *algo, + size_t algolen, + void *data +); + +/** An implementation of the nonce generation function as defined in Bitcoin + * Improvement Proposal 340 "Schnorr Signatures for secp256k1" + * (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). + * + * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of + * auxiliary random data as defined in BIP-340. If the data pointer is NULL, + * the nonce derivation procedure follows BIP-340 by setting the auxiliary + * random data to zero. The algo argument must be non-NULL, otherwise the + * function will fail and return 0. The hash will be tagged with algo. + * Therefore, to create BIP-340 compliant signatures, algo must be set to + * "BIP0340/nonce" and algolen to 13. + */ +SECP256K1_API const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340; + +/** Data structure that contains additional arguments for schnorrsig_sign_custom. + * + * A schnorrsig_extraparams structure object can be initialized correctly by + * setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT. + * + * Members: + * magic: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization + * and has no other function than making sure the object is + * initialized. + * noncefp: pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_bip340 is used + * ndata: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + * secp256k1_nonce_function_bip340 is used, then ndata must be a + * pointer to 32-byte auxiliary randomness as per BIP-340. + */ +typedef struct secp256k1_schnorrsig_extraparams { + unsigned char magic[4]; + secp256k1_nonce_function_hardened noncefp; + void *ndata; +} secp256k1_schnorrsig_extraparams; + +#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c } +#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\ + SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\ + NULL,\ + NULL\ +} + +/** Create a Schnorr signature. + * + * Does _not_ strictly follow BIP-340 because it does not verify the resulting + * signature. Instead, you can manually use secp256k1_schnorrsig_verify and + * abort if it fails. + * + * This function only signs 32-byte messages. If you have messages of a + * different size (or the same size but without a context-specific tag + * prefix), it is recommended to create a 32-byte message hash with + * secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows + * providing an context-specific tag for domain separation. This prevents + * signatures from being valid in multiple contexts by accident. + * + * Returns 1 on success, 0 on failure. + * Args: ctx: pointer to a context object (not secp256k1_context_static). + * Out: sig64: pointer to a 64-byte array to store the serialized signature. + * In: msg32: the 32-byte message being signed. + * keypair: pointer to an initialized keypair. + * aux_rand32: 32 bytes of fresh randomness. While recommended to provide + * this, it is only supplemental to security and can be NULL. A + * NULL argument is treated the same as an all-zero one. See + * BIP-340 "Default Signing" for a full explanation of this + * argument and for guidance if randomness is expensive. + */ +SECP256K1_API int secp256k1_schnorrsig_sign32( + const secp256k1_context *ctx, + unsigned char *sig64, + const unsigned char *msg32, + const secp256k1_keypair *keypair, + const unsigned char *aux_rand32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in + * future versions. */ +SECP256K1_API int secp256k1_schnorrsig_sign( + const secp256k1_context *ctx, + unsigned char *sig64, + const unsigned char *msg32, + const secp256k1_keypair *keypair, + const unsigned char *aux_rand32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) + SECP256K1_DEPRECATED("Use secp256k1_schnorrsig_sign32 instead"); + +/** Create a Schnorr signature with a more flexible API. + * + * Same arguments as secp256k1_schnorrsig_sign except that it allows signing + * variable length messages and accepts a pointer to an extraparams object that + * allows customizing signing by passing additional arguments. + * + * Equivalent to secp256k1_schnorrsig_sign32(..., aux_rand32) if msglen is 32 + * and extraparams is initialized as follows: + * ``` + * secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT; + * extraparams.ndata = (unsigned char*)aux_rand32; + * ``` + * + * Returns 1 on success, 0 on failure. + * Args: ctx: pointer to a context object (not secp256k1_context_static). + * Out: sig64: pointer to a 64-byte array to store the serialized signature. + * In: msg: the message being signed. Can only be NULL if msglen is 0. + * msglen: length of the message. + * keypair: pointer to an initialized keypair. + * extraparams: pointer to an extraparams object (can be NULL). + */ +SECP256K1_API int secp256k1_schnorrsig_sign_custom( + const secp256k1_context *ctx, + unsigned char *sig64, + const unsigned char *msg, + size_t msglen, + const secp256k1_keypair *keypair, + secp256k1_schnorrsig_extraparams *extraparams +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5); + +/** Verify a Schnorr signature. + * + * Returns: 1: correct signature + * 0: incorrect signature + * Args: ctx: pointer to a context object. + * In: sig64: pointer to the 64-byte signature to verify. + * msg: the message being verified. Can only be NULL if msglen is 0. + * msglen: length of the message + * pubkey: pointer to an x-only public key to verify with + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify( + const secp256k1_context *ctx, + const unsigned char *sig64, + const unsigned char *msg, + size_t msglen, + const secp256k1_xonly_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_SCHNORRSIG_H */ diff --git a/crypto/secp256k1/libsecp256k1/libsecp256k1.pc.in b/crypto/secp256k1/libsecp256k1/libsecp256k1.pc.in index a0d006f113..0fb6f48a6c 100644 --- a/crypto/secp256k1/libsecp256k1/libsecp256k1.pc.in +++ b/crypto/secp256k1/libsecp256k1/libsecp256k1.pc.in @@ -8,6 +8,5 @@ Description: Optimized C library for EC operations on curve secp256k1 URL: https://github.com/bitcoin-core/secp256k1 Version: @PACKAGE_VERSION@ Cflags: -I${includedir} -Libs.private: @SECP_LIBS@ Libs: -L${libdir} -lsecp256k1 diff --git a/crypto/secp256k1/libsecp256k1/obj/.gitignore b/crypto/secp256k1/libsecp256k1/obj/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/crypto/secp256k1/libsecp256k1/sage/gen_exhaustive_groups.sage b/crypto/secp256k1/libsecp256k1/sage/gen_exhaustive_groups.sage new file mode 100644 index 0000000000..070bc1285f --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/sage/gen_exhaustive_groups.sage @@ -0,0 +1,156 @@ +load("secp256k1_params.sage") + +MAX_ORDER = 1000 + +# Set of (curve) orders we have encountered so far. +orders_done = set() + +# Map from (subgroup) orders to [b, int(gen.x), int(gen.y), gen, lambda] for those subgroups. +solutions = {} + +# Iterate over curves of the form y^2 = x^3 + B. +for b in range(1, P): + # There are only 6 curves (up to isomorphism) of the form y^2 = x^3 + B. Stop once we have tried all. + if len(orders_done) == 6: + break + + E = EllipticCurve(F, [0, b]) + print("Analyzing curve y^2 = x^3 + %i" % b) + n = E.order() + + # Skip curves with an order we've already tried + if n in orders_done: + print("- Isomorphic to earlier curve") + print() + continue + orders_done.add(n) + + # Skip curves isomorphic to the real secp256k1 + if n.is_pseudoprime(): + assert E.is_isomorphic(C) + print("- Isomorphic to secp256k1") + print() + continue + + print("- Finding prime subgroups") + + # Map from group_order to a set of independent generators for that order. + curve_gens = {} + + for g in E.gens(): + # Find what prime subgroups of group generated by g exist. + g_order = g.order() + for f, _ in g.order().factor(): + # Skip subgroups that have bad size. + if f < 4: + print(f" - Subgroup of size {f}: too small") + continue + if f > MAX_ORDER: + print(f" - Subgroup of size {f}: too large") + continue + + # Construct a generator for that subgroup. + gen = g * (g_order // f) + assert(gen.order() == f) + + # Add to set the minimal multiple of gen. + curve_gens.setdefault(f, set()).add(min([j*gen for j in range(1, f)])) + print(f" - Subgroup of size {f}: ok") + + for f in sorted(curve_gens.keys()): + print(f"- Constructing group of order {f}") + cbrts = sorted([int(c) for c in Integers(f)(1).nth_root(3, all=true) if c != 1]) + gens = list(curve_gens[f]) + sol_count = 0 + no_endo_count = 0 + + # Consider all non-zero linear combinations of the independent generators. + for j in range(1, f**len(gens)): + gen = sum(gens[k] * ((j // f**k) % f) for k in range(len(gens))) + assert not gen.is_zero() + assert (f*gen).is_zero() + + # Find lambda for endomorphism. Skip if none can be found. + lam = None + for l in cbrts: + if l*gen == E(BETA*gen[0], gen[1]): + lam = l + break + + if lam is None: + no_endo_count += 1 + else: + sol_count += 1 + solutions.setdefault(f, []).append((b, int(gen[0]), int(gen[1]), gen, lam)) + + print(f" - Found {sol_count} generators (plus {no_endo_count} without endomorphism)") + + print() + +def output_generator(g, name): + print(f"#define {name} SECP256K1_GE_CONST(\\") + print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x,\\" % tuple((int(g[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4))) + print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x,\\" % tuple((int(g[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8))) + print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x,\\" % tuple((int(g[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4))) + print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x\\" % tuple((int(g[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8))) + print(")") + +def output_b(b): + print(f"#define SECP256K1_B {int(b)}") + +print() +print("To be put in src/group_impl.h:") +print() +print("/* Begin of section generated by sage/gen_exhaustive_groups.sage. */") +for f in sorted(solutions.keys()): + # Use as generator/2 the one with lowest b, and lowest (x, y) generator (interpreted as non-negative integers). + b, _, _, HALF_G, lam = min(solutions[f]) + output_generator(2 * HALF_G, f"SECP256K1_G_ORDER_{f}") +print("/** Generator for secp256k1, value 'g' defined in") +print(" * \"Standards for Efficient Cryptography\" (SEC2) 2.7.1.") +print(" */") +output_generator(G, "SECP256K1_G") +print("/* These exhaustive group test orders and generators are chosen such that:") +print(" * - The field size is equal to that of secp256k1, so field code is the same.") +print(" * - The curve equation is of the form y^2=x^3+B for some small constant B.") +print(" * - The subgroup has a generator 2*P, where P.x is as small as possible.") +print(f" * - The subgroup has size less than {MAX_ORDER} to permit exhaustive testing.") +print(" * - The subgroup admits an endomorphism of the form lambda*(x,y) == (beta*x,y).") +print(" */") +print("#if defined(EXHAUSTIVE_TEST_ORDER)") +first = True +for f in sorted(solutions.keys()): + b, _, _, _, lam = min(solutions[f]) + print(f"# {'if' if first else 'elif'} EXHAUSTIVE_TEST_ORDER == {f}") + first = False + print() + print(f"static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_{f};") + output_b(b) + print() +print("# else") +print("# error No known generator for the specified exhaustive test group order.") +print("# endif") +print("#else") +print() +print("static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G;") +output_b(7) +print() +print("#endif") +print("/* End of section generated by sage/gen_exhaustive_groups.sage. */") + + +print() +print() +print("To be put in src/scalar_impl.h:") +print() +print("/* Begin of section generated by sage/gen_exhaustive_groups.sage. */") +first = True +for f in sorted(solutions.keys()): + _, _, _, _, lam = min(solutions[f]) + print("# %s EXHAUSTIVE_TEST_ORDER == %i" % ("if" if first else "elif", f)) + first = False + print("# define EXHAUSTIVE_TEST_LAMBDA %i" % lam) +print("# else") +print("# error No known lambda for the specified exhaustive test group order.") +print("# endif") +print("/* End of section generated by sage/gen_exhaustive_groups.sage. */") diff --git a/crypto/secp256k1/libsecp256k1/sage/gen_split_lambda_constants.sage b/crypto/secp256k1/libsecp256k1/sage/gen_split_lambda_constants.sage new file mode 100644 index 0000000000..7d4359e0f6 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/sage/gen_split_lambda_constants.sage @@ -0,0 +1,114 @@ +""" Generates the constants used in secp256k1_scalar_split_lambda. + +See the comments for secp256k1_scalar_split_lambda in src/scalar_impl.h for detailed explanations. +""" + +load("secp256k1_params.sage") + +def inf_norm(v): + """Returns the infinity norm of a vector.""" + return max(map(abs, v)) + +def gauss_reduction(i1, i2): + v1, v2 = i1.copy(), i2.copy() + while True: + if inf_norm(v2) < inf_norm(v1): + v1, v2 = v2, v1 + # This is essentially + # m = round((v1[0]*v2[0] + v1[1]*v2[1]) / (inf_norm(v1)**2)) + # (rounding to the nearest integer) without relying on floating point arithmetic. + m = ((v1[0]*v2[0] + v1[1]*v2[1]) + (inf_norm(v1)**2) // 2) // (inf_norm(v1)**2) + if m == 0: + return v1, v2 + v2[0] -= m*v1[0] + v2[1] -= m*v1[1] + +def find_split_constants_gauss(): + """Find constants for secp256k1_scalar_split_lamdba using gauss reduction.""" + (v11, v12), (v21, v22) = gauss_reduction([0, N], [1, int(LAMBDA)]) + + # We use related vectors in secp256k1_scalar_split_lambda. + A1, B1 = -v21, -v11 + A2, B2 = v22, -v21 + + return A1, B1, A2, B2 + +def find_split_constants_explicit_tof(): + """Find constants for secp256k1_scalar_split_lamdba using the trace of Frobenius. + + See Benjamin Smith: "Easy scalar decompositions for efficient scalar multiplication on + elliptic curves and genus 2 Jacobians" (https://eprint.iacr.org/2013/672), Example 2 + """ + assert P % 3 == 1 # The paper says P % 3 == 2 but that appears to be a mistake, see [10]. + assert C.j_invariant() == 0 + + t = C.trace_of_frobenius() + + c = Integer(sqrt((4*P - t**2)/3)) + A1 = Integer((t - c)/2 - 1) + B1 = c + + A2 = Integer((t + c)/2 - 1) + B2 = Integer(1 - (t - c)/2) + + # We use a negated b values in secp256k1_scalar_split_lambda. + B1, B2 = -B1, -B2 + + return A1, B1, A2, B2 + +A1, B1, A2, B2 = find_split_constants_explicit_tof() + +# For extra fun, use an independent method to recompute the constants. +assert (A1, B1, A2, B2) == find_split_constants_gauss() + +# PHI : Z[l] -> Z_n where phi(a + b*l) == a + b*lambda mod n. +def PHI(a,b): + return Z(a + LAMBDA*b) + +# Check that (A1, B1) and (A2, B2) are in the kernel of PHI. +assert PHI(A1, B1) == Z(0) +assert PHI(A2, B2) == Z(0) + +# Check that the parallelogram generated by (A1, A2) and (B1, B2) +# is a fundamental domain by containing exactly N points. +# Since the LHS is the determinant and N != 0, this also checks that +# (A1, A2) and (B1, B2) are linearly independent. By the previous +# assertions, (A1, A2) and (B1, B2) are a basis of the kernel. +assert A1*B2 - B1*A2 == N + +# Check that their components are short enough. +assert (A1 + A2)/2 < sqrt(N) +assert B1 < sqrt(N) +assert B2 < sqrt(N) + +G1 = round((2**384)*B2/N) +G2 = round((2**384)*(-B1)/N) + +def rnddiv2(v): + if v & 1: + v += 1 + return v >> 1 + +def scalar_lambda_split(k): + """Equivalent to secp256k1_scalar_lambda_split().""" + c1 = rnddiv2((k * G1) >> 383) + c2 = rnddiv2((k * G2) >> 383) + c1 = (c1 * -B1) % N + c2 = (c2 * -B2) % N + r2 = (c1 + c2) % N + r1 = (k + r2 * -LAMBDA) % N + return (r1, r2) + +# The result of scalar_lambda_split can depend on the representation of k (mod n). +SPECIAL = (2**383) // G2 + 1 +assert scalar_lambda_split(SPECIAL) != scalar_lambda_split(SPECIAL + N) + +print(' A1 =', hex(A1)) +print(' -B1 =', hex(-B1)) +print(' A2 =', hex(A2)) +print(' -B2 =', hex(-B2)) +print(' =', hex(Z(-B2))) +print(' -LAMBDA =', hex(-LAMBDA)) + +print(' G1 =', hex(G1)) +print(' G2 =', hex(G2)) diff --git a/crypto/secp256k1/libsecp256k1/sage/group_prover.sage b/crypto/secp256k1/libsecp256k1/sage/group_prover.sage index 68882e9365..bb09295369 100644 --- a/crypto/secp256k1/libsecp256k1/sage/group_prover.sage +++ b/crypto/secp256k1/libsecp256k1/sage/group_prover.sage @@ -3,7 +3,7 @@ # to independently set assumptions on input or intermediary variables. # # The general approach is: -# * A constraint is a tuple of two sets of of symbolic expressions: +# * A constraint is a tuple of two sets of symbolic expressions: # the first of which are required to evaluate to zero, the second of which # are required to evaluate to nonzero. # - A constraint is said to be conflicting if any of its nonzero expressions @@ -42,7 +42,7 @@ # as we assume that all constraints in it are complementary with each other. # # Based on the sage verification scripts used in the Explicit-Formulas Database -# by Tanja Lange and others, see http://hyperelliptic.org/EFD +# by Tanja Lange and others, see https://hyperelliptic.org/EFD class fastfrac: """Fractions over rings.""" @@ -65,7 +65,7 @@ class fastfrac: return self.top in I and self.bot not in I def reduce(self,assumeZero): - zero = self.R.ideal(map(numerator, assumeZero)) + zero = self.R.ideal(list(map(numerator, assumeZero))) return fastfrac(self.R, zero.reduce(self.top)) / fastfrac(self.R, zero.reduce(self.bot)) def __add__(self,other): @@ -100,7 +100,7 @@ class fastfrac: """Multiply something else with a fraction.""" return self.__mul__(other) - def __div__(self,other): + def __truediv__(self,other): """Divide two fractions.""" if parent(other) == ZZ: return fastfrac(self.R,self.top,self.bot * other) @@ -108,6 +108,11 @@ class fastfrac: return fastfrac(self.R,self.top * other.bot,self.bot * other.top) return NotImplemented + # Compatibility wrapper for Sage versions based on Python 2 + def __div__(self,other): + """Divide two fractions.""" + return self.__truediv__(other) + def __pow__(self,other): """Compute a power of a fraction.""" if parent(other) == ZZ: @@ -159,6 +164,9 @@ class constraints: def negate(self): return constraints(zero=self.nonzero, nonzero=self.zero) + def map(self, fun): + return constraints(zero={fun(k): v for k, v in self.zero.items()}, nonzero={fun(k): v for k, v in self.nonzero.items()}) + def __add__(self, other): zero = self.zero.copy() zero.update(other.zero) @@ -172,10 +180,34 @@ class constraints: def __repr__(self): return "%s" % self +def normalize_factor(p): + """Normalizes the sign of primitive polynomials (as returned by factor()) + + This function ensures that the polynomial has a positive leading coefficient. + + This is necessary because recent sage versions (starting with v9.3 or v9.4, + we don't know) are inconsistent about the placement of the minus sign in + polynomial factorizations: + ``` + sage: R. = PolynomialRing(QQ,8,order='invlex') + sage: R((-2 * (bx - ax)) ^ 1).factor() + (-2) * (bx - ax) + sage: R((-2 * (bx - ax)) ^ 2).factor() + (4) * (-bx + ax)^2 + sage: R((-2 * (bx - ax)) ^ 3).factor() + (8) * (-bx + ax)^3 + ``` + """ + # Assert p is not 0 and that its non-zero coefficients are coprime. + # (We could just work with the primitive part p/p.content() but we want to be + # aware if factor() does not return a primitive part in future sage versions.) + assert p.content() == 1 + # Ensure that the first non-zero coefficient is positive. + return p if p.lc() > 0 else -p def conflicts(R, con): """Check whether any of the passed non-zero assumptions is implied by the zero assumptions""" - zero = R.ideal(map(numerator, con.zero)) + zero = R.ideal(list(map(numerator, con.zero))) if 1 in zero: return True # First a cheap check whether any of the individual nonzero terms conflict on @@ -195,20 +227,20 @@ def conflicts(R, con): def get_nonzero_set(R, assume): """Calculate a simple set of nonzero expressions""" - zero = R.ideal(map(numerator, assume.zero)) + zero = R.ideal(list(map(numerator, assume.zero))) nonzero = set() for nz in map(numerator, assume.nonzero): for (f,n) in nz.factor(): - nonzero.add(f) + nonzero.add(normalize_factor(f)) rnz = zero.reduce(nz) for (f,n) in rnz.factor(): - nonzero.add(f) + nonzero.add(normalize_factor(f)) return nonzero def prove_nonzero(R, exprs, assume): """Check whether an expression is provably nonzero, given assumptions""" - zero = R.ideal(map(numerator, assume.zero)) + zero = R.ideal(list(map(numerator, assume.zero))) nonzero = get_nonzero_set(R, assume) expl = set() ok = True @@ -217,27 +249,27 @@ def prove_nonzero(R, exprs, assume): return (False, [exprs[expr]]) allexprs = reduce(lambda a,b: numerator(a)*numerator(b), exprs, 1) for (f, n) in allexprs.factor(): - if f not in nonzero: + if normalize_factor(f) not in nonzero: ok = False if ok: return (True, None) ok = True - for (f, n) in zero.reduce(numerator(allexprs)).factor(): - if f not in nonzero: + for (f, n) in zero.reduce(allexprs).factor(): + if normalize_factor(f) not in nonzero: ok = False if ok: return (True, None) ok = True for expr in exprs: for (f,n) in numerator(expr).factor(): - if f not in nonzero: + if normalize_factor(f) not in nonzero: ok = False if ok: return (True, None) ok = True for expr in exprs: for (f,n) in zero.reduce(numerator(expr)).factor(): - if f not in nonzero: + if normalize_factor(f) not in nonzero: expl.add(exprs[expr]) if expl: return (False, list(expl)) @@ -249,8 +281,8 @@ def prove_zero(R, exprs, assume): """Check whether all of the passed expressions are provably zero, given assumptions""" r, e = prove_nonzero(R, dict(map(lambda x: (fastfrac(R, x.bot, 1), exprs[x]), exprs)), assume) if not r: - return (False, map(lambda x: "Possibly zero denominator: %s" % x, e)) - zero = R.ideal(map(numerator, assume.zero)) + return (False, list(map(lambda x: "Possibly zero denominator: %s" % x, e))) + zero = R.ideal(list(map(numerator, assume.zero))) nonzero = prod(x for x in assume.nonzero) expl = [] for expr in exprs: @@ -265,8 +297,8 @@ def describe_extra(R, assume, assumeExtra): """Describe what assumptions are added, given existing assumptions""" zerox = assume.zero.copy() zerox.update(assumeExtra.zero) - zero = R.ideal(map(numerator, assume.zero)) - zeroextra = R.ideal(map(numerator, zerox)) + zero = R.ideal(list(map(numerator, assume.zero))) + zeroextra = R.ideal(list(map(numerator, zerox))) nonzero = get_nonzero_set(R, assume) ret = set() # Iterate over the extra zero expressions @@ -274,8 +306,8 @@ def describe_extra(R, assume, assumeExtra): if base not in zero: add = [] for (f, n) in numerator(base).factor(): - if f not in nonzero: - add += ["%s" % f] + if normalize_factor(f) not in nonzero: + add += ["%s" % normalize_factor(f)] if add: ret.add((" * ".join(add)) + " = 0 [%s]" % assumeExtra.zero[base]) # Iterate over the extra nonzero expressions @@ -283,8 +315,8 @@ def describe_extra(R, assume, assumeExtra): nzr = zeroextra.reduce(numerator(nz)) if nzr not in zeroextra: for (f,n) in nzr.factor(): - if zeroextra.reduce(f) not in nonzero: - ret.add("%s != 0" % zeroextra.reduce(f)) + if normalize_factor(zeroextra.reduce(f)) not in nonzero: + ret.add("%s != 0" % normalize_factor(zeroextra.reduce(f))) return ", ".join(x for x in ret) @@ -294,22 +326,21 @@ def check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require): if conflicts(R, assume): # This formula does not apply - return None + return (True, None) describe = describe_extra(R, assumeLaw + assumeBranch, assumeAssert) + if describe != "": + describe = " (assuming " + describe + ")" ok, msg = prove_zero(R, require.zero, assume) if not ok: - return "FAIL, %s fails (assuming %s)" % (str(msg), describe) + return (False, "FAIL, %s fails%s" % (str(msg), describe)) res, expl = prove_nonzero(R, require.nonzero, assume) if not res: - return "FAIL, %s fails (assuming %s)" % (str(expl), describe) + return (False, "FAIL, %s fails%s" % (str(expl), describe)) - if describe != "": - return "OK (assuming %s)" % describe - else: - return "OK" + return (True, "OK%s" % describe) def concrete_verify(c): diff --git a/crypto/secp256k1/libsecp256k1/sage/secp256k1.sage b/crypto/secp256k1/libsecp256k1/sage/prove_group_implementations.sage similarity index 72% rename from crypto/secp256k1/libsecp256k1/sage/secp256k1.sage rename to crypto/secp256k1/libsecp256k1/sage/prove_group_implementations.sage index a97e732f7f..23799be52b 100644 --- a/crypto/secp256k1/libsecp256k1/sage/secp256k1.sage +++ b/crypto/secp256k1/libsecp256k1/sage/prove_group_implementations.sage @@ -8,25 +8,20 @@ load("weierstrass_prover.sage") def formula_secp256k1_gej_double_var(a): """libsecp256k1's secp256k1_gej_double_var, used by various addition functions""" rz = a.Z * a.Y - rz = rz * 2 - t1 = a.X^2 - t1 = t1 * 3 - t2 = t1^2 - t3 = a.Y^2 - t3 = t3 * 2 - t4 = t3^2 - t4 = t4 * 2 - t3 = t3 * a.X - rx = t3 - rx = rx * 4 - rx = -rx - rx = rx + t2 - t2 = -t2 - t3 = t3 * 6 - t3 = t3 + t2 - ry = t1 * t3 - t2 = -t4 - ry = ry + t2 + s = a.Y^2 + l = a.X^2 + l = l * 3 + l = l / 2 + t = -s + t = t * a.X + rx = l^2 + rx = rx + t + rx = rx + t + s = s^2 + t = t + rx + ry = t * l + ry = ry + s + ry = -ry return jacobianpoint(rx, ry, rz) def formula_secp256k1_gej_add_var(branch, a, b): @@ -45,29 +40,26 @@ def formula_secp256k1_gej_add_var(branch, a, b): s2 = s2 * a.Z h = -u1 h = h + u2 - i = -s1 - i = i + s2 + i = -s2 + i = i + s1 if branch == 2: r = formula_secp256k1_gej_double_var(a) return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r) if branch == 3: return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity()) - i2 = i^2 + t = h * b.Z + rz = a.Z * t h2 = h^2 + h2 = -h2 h3 = h2 * h - h = h * b.Z - rz = a.Z * h t = u1 * h2 - rx = t - rx = rx * 2 + rx = i^2 rx = rx + h3 - rx = -rx - rx = rx + i2 - ry = -rx - ry = ry + t - ry = ry * i + rx = rx + t + rx = rx + t + t = t + rx + ry = t * i h3 = h3 * s1 - h3 = -h3 ry = ry + h3 return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) @@ -85,28 +77,25 @@ def formula_secp256k1_gej_add_ge_var(branch, a, b): s2 = s2 * a.Z h = -u1 h = h + u2 - i = -s1 - i = i + s2 + i = -s2 + i = i + s1 if (branch == 2): r = formula_secp256k1_gej_double_var(a) return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) if (branch == 3): return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) - i2 = i^2 - h2 = h^2 - h3 = h * h2 rz = a.Z * h + h2 = h^2 + h2 = -h2 + h3 = h2 * h t = u1 * h2 - rx = t - rx = rx * 2 + rx = i^2 rx = rx + h3 - rx = -rx - rx = rx + i2 - ry = -rx - ry = ry + t - ry = ry * i + rx = rx + t + rx = rx + t + t = t + rx + ry = t * i h3 = h3 * s1 - h3 = -h3 ry = ry + h3 return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) @@ -114,14 +103,15 @@ def formula_secp256k1_gej_add_zinv_var(branch, a, b): """libsecp256k1's secp256k1_gej_add_zinv_var""" bzinv = b.Z^(-1) if branch == 0: - return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a) - if branch == 1: + rinf = b.Infinity bzinv2 = bzinv^2 bzinv3 = bzinv2 * bzinv rx = b.X * bzinv2 ry = b.Y * bzinv3 rz = 1 - return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz)) + return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz, rinf)) + if branch == 1: + return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) azz = a.Z * bzinv z12 = azz^2 u1 = a.X @@ -131,29 +121,25 @@ def formula_secp256k1_gej_add_zinv_var(branch, a, b): s2 = s2 * azz h = -u1 h = h + u2 - i = -s1 - i = i + s2 + i = -s2 + i = i + s1 if branch == 2: r = formula_secp256k1_gej_double_var(a) return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) if branch == 3: return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) - i2 = i^2 + rz = a.Z * h h2 = h^2 - h3 = h * h2 - rz = a.Z - rz = rz * h + h2 = -h2 + h3 = h2 * h t = u1 * h2 - rx = t - rx = rx * 2 + rx = i^2 rx = rx + h3 - rx = -rx - rx = rx + i2 - ry = -rx - ry = ry + t - ry = ry * i + rx = rx + t + rx = rx + t + t = t + rx + ry = t * i h3 = h3 * s1 - h3 = -h3 ry = ry + h3 return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) @@ -162,7 +148,7 @@ def formula_secp256k1_gej_add_ge(branch, a, b): zeroes = {} nonzeroes = {} a_infinity = False - if (branch & 4) != 0: + if (branch & 2) != 0: nonzeroes.update({a.Infinity : 'a_infinite'}) a_infinity = True else: @@ -181,15 +167,11 @@ def formula_secp256k1_gej_add_ge(branch, a, b): m_alt = -u2 tt = u1 * m_alt rr = rr + tt - degenerate = (branch & 3) == 3 - if (branch & 1) != 0: + degenerate = (branch & 1) != 0 + if degenerate: zeroes.update({m : 'm_zero'}) else: nonzeroes.update({m : 'm_nonzero'}) - if (branch & 2) != 0: - zeroes.update({rr : 'rr_zero'}) - else: - nonzeroes.update({rr : 'rr_nonzero'}) rr_alt = s1 rr_alt = rr_alt * 2 m_alt = m_alt + u1 @@ -197,21 +179,13 @@ def formula_secp256k1_gej_add_ge(branch, a, b): rr_alt = rr m_alt = m n = m_alt^2 - q = n * t + q = -t + q = q * n n = n^2 if degenerate: n = m t = rr_alt^2 rz = a.Z * m_alt - infinity = False - if (branch & 8) != 0: - if not a_infinity: - infinity = True - zeroes.update({rz : 'r.z=0'}) - else: - nonzeroes.update({rz : 'r.z!=0'}) - rz = rz * 2 - q = -q t = t + q rx = t t = t * 2 @@ -219,14 +193,16 @@ def formula_secp256k1_gej_add_ge(branch, a, b): t = t * rr_alt t = t + n ry = -t - rx = rx * 4 - ry = ry * 4 + ry = ry / 2 if a_infinity: rx = b.X ry = b.Y rz = 1 - if infinity: + if (branch & 4) != 0: + zeroes.update({rz : 'r.z = 0'}) return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), point_at_infinity()) + else: + nonzeroes.update({rz : 'r.z != 0'}) return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), jacobianpoint(rx, ry, rz)) def formula_secp256k1_gej_add_ge_old(branch, a, b): @@ -292,15 +268,18 @@ def formula_secp256k1_gej_add_ge_old(branch, a, b): return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), jacobianpoint(rx, ry, rz)) if __name__ == "__main__": - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var) - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var) - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var) - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge) - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old) + success = True + success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var) + success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var) + success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var) + success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 8, formula_secp256k1_gej_add_ge) + success = success & (not check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old)) if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive": - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43) - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43) - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43) - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43) - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43) + success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43) + success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43) + success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43) + success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 8, formula_secp256k1_gej_add_ge, 43) + success = success & (not check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43)) + + sys.exit(int(not success)) diff --git a/crypto/secp256k1/libsecp256k1/sage/secp256k1_params.sage b/crypto/secp256k1/libsecp256k1/sage/secp256k1_params.sage new file mode 100644 index 0000000000..68f95adec4 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/sage/secp256k1_params.sage @@ -0,0 +1,39 @@ +"""Prime order of finite field underlying secp256k1 (2^256 - 2^32 - 977)""" +P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F + +"""Finite field underlying secp256k1""" +F = FiniteField(P) + +"""Elliptic curve secp256k1: y^2 = x^3 + 7""" +C = EllipticCurve([F(0), F(7)]) + +"""Base point of secp256k1""" +G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) +if int(G[1]) & 1: + # G.y is even + G = -G + +"""Prime order of secp256k1""" +N = C.order() + +"""Finite field of scalars of secp256k1""" +Z = FiniteField(N) + +""" Beta value of secp256k1 non-trivial endomorphism: lambda * (x, y) = (beta * x, y)""" +BETA = F(2)^((P-1)/3) + +""" Lambda value of secp256k1 non-trivial endomorphism: lambda * (x, y) = (beta * x, y)""" +LAMBDA = Z(3)^((N-1)/3) + +assert is_prime(P) +assert is_prime(N) + +assert BETA != F(1) +assert BETA^3 == F(1) +assert BETA^2 + BETA + 1 == 0 + +assert LAMBDA != Z(1) +assert LAMBDA^3 == Z(1) +assert LAMBDA^2 + LAMBDA + 1 == 0 + +assert Integer(LAMBDA)*G == C(BETA*G[0], G[1]) diff --git a/crypto/secp256k1/libsecp256k1/sage/weierstrass_prover.sage b/crypto/secp256k1/libsecp256k1/sage/weierstrass_prover.sage index 03ef2ec901..be9cfd4c76 100644 --- a/crypto/secp256k1/libsecp256k1/sage/weierstrass_prover.sage +++ b/crypto/secp256k1/libsecp256k1/sage/weierstrass_prover.sage @@ -175,24 +175,25 @@ laws_jacobian_weierstrass = { def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p): """Verify an implementation of addition of Jacobian points on a Weierstrass curve, by executing and validating the result for every possible addition in a prime field""" F = Integers(p) - print "Formula %s on Z%i:" % (name, p) + print("Formula %s on Z%i:" % (name, p)) points = [] - for x in xrange(0, p): - for y in xrange(0, p): + for x in range(0, p): + for y in range(0, p): point = affinepoint(F(x), F(y)) r, e = concrete_verify(on_weierstrass_curve(A, B, point)) if r: points.append(point) - for za in xrange(1, p): - for zb in xrange(1, p): + ret = True + for za in range(1, p): + for zb in range(1, p): for pa in points: for pb in points: - for ia in xrange(2): - for ib in xrange(2): + for ia in range(2): + for ib in range(2): pA = jacobianpoint(pa.x * F(za)^2, pa.y * F(za)^3, F(za), ia) pB = jacobianpoint(pb.x * F(zb)^2, pb.y * F(zb)^3, F(zb), ib) - for branch in xrange(0, branches): + for branch in range(0, branches): assumeAssert, assumeBranch, pC = formula(branch, pA, pB) pC.X = F(pC.X) pC.Y = F(pC.Y) @@ -206,13 +207,16 @@ def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p): r, e = concrete_verify(assumeLaw) if r: if match: - print " multiple branches for (%s,%s,%s,%s) + (%s,%s,%s,%s)" % (pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity) + print(" multiple branches for (%s,%s,%s,%s) + (%s,%s,%s,%s)" % (pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity)) else: match = True r, e = concrete_verify(require) if not r: - print " failure in branch %i for (%s,%s,%s,%s) + (%s,%s,%s,%s) = (%s,%s,%s,%s): %s" % (branch, pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity, pC.X, pC.Y, pC.Z, pC.Infinity, e) - print + ret = False + print(" failure in branch %i for (%s,%s,%s,%s) + (%s,%s,%s,%s) = (%s,%s,%s,%s): %s" % (branch, pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity, pC.X, pC.Y, pC.Z, pC.Infinity, e)) + + print() + return ret def check_symbolic_function(R, assumeAssert, assumeBranch, f, A, B, pa, pb, pA, pB, pC): @@ -242,23 +246,30 @@ def check_symbolic_jacobian_weierstrass(name, A, B, branches, formula): for key in laws_jacobian_weierstrass: res[key] = [] - print ("Formula " + name + ":") + print("Formula " + name + ":") count = 0 - for branch in xrange(branches): + ret = True + for branch in range(branches): assumeFormula, assumeBranch, pC = formula(branch, pA, pB) + assumeBranch = assumeBranch.map(lift) + assumeFormula = assumeFormula.map(lift) pC.X = lift(pC.X) pC.Y = lift(pC.Y) pC.Z = lift(pC.Z) pC.Infinity = lift(pC.Infinity) for key in laws_jacobian_weierstrass: - res[key].append((check_symbolic_function(R, assumeFormula, assumeBranch, laws_jacobian_weierstrass[key], A, B, pa, pb, pA, pB, pC), branch)) + success, msg = check_symbolic_function(R, assumeFormula, assumeBranch, laws_jacobian_weierstrass[key], A, B, pa, pb, pA, pB, pC) + if not success: + ret = False + res[key].append((msg, branch)) for key in res: - print " %s:" % key + print(" %s:" % key) val = res[key] for x in val: if x[0] is not None: - print " branch %i: %s" % (x[1], x[0]) + print(" branch %i: %s" % (x[1], x[0])) - print + print() + return ret diff --git a/crypto/secp256k1/libsecp256k1/src/CMakeLists.txt b/crypto/secp256k1/libsecp256k1/src/CMakeLists.txt new file mode 100644 index 0000000000..f31b8c8f55 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/CMakeLists.txt @@ -0,0 +1,176 @@ +# Must be included before CMAKE_INSTALL_INCLUDEDIR is used. +include(GNUInstallDirs) + +add_library(secp256k1_precomputed OBJECT EXCLUDE_FROM_ALL + precomputed_ecmult.c + precomputed_ecmult_gen.c +) + +# Add objects explicitly rather than linking to the object libs to keep them +# from being exported. +add_library(secp256k1 secp256k1.c $) + +add_library(secp256k1_asm INTERFACE) +if(SECP256K1_ASM STREQUAL "arm32") + add_library(secp256k1_asm_arm OBJECT EXCLUDE_FROM_ALL) + target_sources(secp256k1_asm_arm PUBLIC + asm/field_10x26_arm.s + ) + target_sources(secp256k1 PRIVATE $) + target_link_libraries(secp256k1_asm INTERFACE secp256k1_asm_arm) +endif() + +if(WIN32) + # Define our export symbol only for shared libs. + set_target_properties(secp256k1 PROPERTIES DEFINE_SYMBOL SECP256K1_DLL_EXPORT) + target_compile_definitions(secp256k1 INTERFACE $<$>:SECP256K1_STATIC>) +endif() + +# Object libs don't know if they're being built for a shared or static lib. +# Grab the PIC property from secp256k1 which knows. +get_target_property(use_pic secp256k1 POSITION_INDEPENDENT_CODE) +set_target_properties(secp256k1_precomputed PROPERTIES POSITION_INDEPENDENT_CODE ${use_pic}) + +target_include_directories(secp256k1 INTERFACE + # Add the include path for parent projects so that they don't have to manually add it. + $>:${PROJECT_SOURCE_DIR}/include>> + $ +) + +# This emulates Libtool to make sure Libtool and CMake agree on the ABI version, +# see below "Calculate the version variables" in build-aux/ltmain.sh. +math(EXPR ${PROJECT_NAME}_soversion "${${PROJECT_NAME}_LIB_VERSION_CURRENT} - ${${PROJECT_NAME}_LIB_VERSION_AGE}") +set_target_properties(secp256k1 PROPERTIES + SOVERSION ${${PROJECT_NAME}_soversion} +) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set_target_properties(secp256k1 PROPERTIES + VERSION ${${PROJECT_NAME}_soversion}.${${PROJECT_NAME}_LIB_VERSION_AGE}.${${PROJECT_NAME}_LIB_VERSION_REVISION} + ) +elseif(APPLE) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.17) + math(EXPR ${PROJECT_NAME}_compatibility_version "${${PROJECT_NAME}_LIB_VERSION_CURRENT} + 1") + set_target_properties(secp256k1 PROPERTIES + MACHO_COMPATIBILITY_VERSION ${${PROJECT_NAME}_compatibility_version} + MACHO_CURRENT_VERSION ${${PROJECT_NAME}_compatibility_version}.${${PROJECT_NAME}_LIB_VERSION_REVISION} + ) + unset(${PROJECT_NAME}_compatibility_version) + elseif(BUILD_SHARED_LIBS) + message(WARNING + "The 'compatibility version' and 'current version' values of the DYLIB " + "will diverge from the values set by the GNU Libtool. To ensure " + "compatibility, it is recommended to upgrade CMake to at least version 3.17." + ) + endif() +elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(${PROJECT_NAME}_windows "secp256k1") + if(MSVC) + set(${PROJECT_NAME}_windows "${PROJECT_NAME}") + endif() + set_target_properties(secp256k1 PROPERTIES + ARCHIVE_OUTPUT_NAME "${${PROJECT_NAME}_windows}" + RUNTIME_OUTPUT_NAME "${${PROJECT_NAME}_windows}-${${PROJECT_NAME}_soversion}" + ) + unset(${PROJECT_NAME}_windows) +endif() +unset(${PROJECT_NAME}_soversion) + +if(SECP256K1_BUILD_BENCHMARK) + add_executable(bench bench.c) + target_link_libraries(bench secp256k1) + add_executable(bench_internal bench_internal.c) + target_link_libraries(bench_internal secp256k1_precomputed secp256k1_asm) + add_executable(bench_ecmult bench_ecmult.c) + target_link_libraries(bench_ecmult secp256k1_precomputed secp256k1_asm) +endif() + +if(SECP256K1_BUILD_TESTS) + add_executable(noverify_tests tests.c) + target_link_libraries(noverify_tests secp256k1_precomputed secp256k1_asm) + add_test(NAME secp256k1_noverify_tests COMMAND noverify_tests) + if(NOT CMAKE_BUILD_TYPE STREQUAL "Coverage") + add_executable(tests tests.c) + target_compile_definitions(tests PRIVATE VERIFY) + target_link_libraries(tests secp256k1_precomputed secp256k1_asm) + add_test(NAME secp256k1_tests COMMAND tests) + endif() +endif() + +if(SECP256K1_BUILD_EXHAUSTIVE_TESTS) + # Note: do not include secp256k1_precomputed in exhaustive_tests (it uses runtime-generated tables). + add_executable(exhaustive_tests tests_exhaustive.c) + target_link_libraries(exhaustive_tests secp256k1_asm) + target_compile_definitions(exhaustive_tests PRIVATE $<$>:VERIFY>) + add_test(NAME secp256k1_exhaustive_tests COMMAND exhaustive_tests) +endif() + +if(SECP256K1_BUILD_CTIME_TESTS) + add_executable(ctime_tests ctime_tests.c) + target_link_libraries(ctime_tests secp256k1) +endif() + +if(SECP256K1_INSTALL) + install(TARGETS secp256k1 + EXPORT ${PROJECT_NAME}-targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + set(${PROJECT_NAME}_headers + "${PROJECT_SOURCE_DIR}/include/secp256k1.h" + "${PROJECT_SOURCE_DIR}/include/secp256k1_preallocated.h" + ) + if(SECP256K1_ENABLE_MODULE_ECDH) + list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ecdh.h") + endif() + if(SECP256K1_ENABLE_MODULE_RECOVERY) + list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_recovery.h") + endif() + if(SECP256K1_ENABLE_MODULE_EXTRAKEYS) + list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_extrakeys.h") + endif() + if(SECP256K1_ENABLE_MODULE_SCHNORRSIG) + list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_schnorrsig.h") + endif() + if(SECP256K1_ENABLE_MODULE_MUSIG) + list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_musig.h") + endif() + if(SECP256K1_ENABLE_MODULE_ELLSWIFT) + list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ellswift.h") + endif() + install(FILES ${${PROJECT_NAME}_headers} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + + install(EXPORT ${PROJECT_NAME}-targets + FILE ${PROJECT_NAME}-targets.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + ) + + include(CMakePackageConfigHelpers) + configure_package_config_file( + ${PROJECT_SOURCE_DIR}/cmake/config.cmake.in + ${PROJECT_NAME}-config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + NO_SET_AND_CHECK_MACRO + ) + write_basic_package_version_file(${PROJECT_NAME}-config-version.cmake + COMPATIBILITY SameMinorVersion + ) + + install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + ) + + include(GeneratePkgConfigFile) + generate_pkg_config_file(${PROJECT_SOURCE_DIR}/libsecp256k1.pc.in) + install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + ) +endif() diff --git a/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s b/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s index 5a9cc3ffcf..664b921400 100644 --- a/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s +++ b/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s @@ -1,9 +1,9 @@ @ vim: set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab syntax=armasm: -/********************************************************************** - * Copyright (c) 2014 Wladimir J. van der Laan * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Wladimir J. van der Laan * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ /* ARM implementation of field_10x26 inner loops. @@ -16,15 +16,9 @@ Note: */ .syntax unified - .arch armv7-a @ eabi attributes - see readelf -A - .eabi_attribute 8, 1 @ Tag_ARM_ISA_use = yes - .eabi_attribute 9, 0 @ Tag_Thumb_ISA_use = no - .eabi_attribute 10, 0 @ Tag_FP_arch = none .eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte .eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP - .eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Aggressive Speed - .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6 .text @ Field constants @@ -35,6 +29,7 @@ Note: .align 2 .global secp256k1_fe_mul_inner .type secp256k1_fe_mul_inner, %function + .hidden secp256k1_fe_mul_inner @ Arguments: @ r0 r Restrict: can overlap with a, not with b @ r1 a @@ -522,6 +517,7 @@ secp256k1_fe_mul_inner: .align 2 .global secp256k1_fe_sqr_inner .type secp256k1_fe_sqr_inner, %function + .hidden secp256k1_fe_sqr_inner @ Arguments: @ r0 r Can overlap with a @ r1 a @@ -917,3 +913,4 @@ secp256k1_fe_sqr_inner: ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} .size secp256k1_fe_sqr_inner, .-secp256k1_fe_sqr_inner + .section .note.GNU-stack,"",%progbits diff --git a/crypto/secp256k1/libsecp256k1/src/assumptions.h b/crypto/secp256k1/libsecp256k1/src/assumptions.h new file mode 100644 index 0000000000..7961005350 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/assumptions.h @@ -0,0 +1,87 @@ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ASSUMPTIONS_H +#define SECP256K1_ASSUMPTIONS_H + +#include + +#include "util.h" +#if defined(SECP256K1_INT128_NATIVE) +#include "int128_native.h" +#endif + +/* This library, like most software, relies on a number of compiler implementation defined (but not undefined) + behaviours. Although the behaviours we require are essentially universal we test them specifically here to + reduce the odds of experiencing an unwelcome surprise. +*/ + +#if defined(__has_attribute) +# if __has_attribute(__unavailable__) +__attribute__((__unavailable__("Don't call this function. It only exists because STATIC_ASSERT cannot be used outside a function."))) +# endif +#endif +static void secp256k1_assumption_checker(void) { + /* Bytes are 8 bits. */ + STATIC_ASSERT(CHAR_BIT == 8); + + /* No integer promotion for uint32_t. This ensures that we can multiply uintXX_t values where XX >= 32 + without signed overflow, which would be undefined behaviour. */ + STATIC_ASSERT(UINT_MAX <= UINT32_MAX); + + /* Conversions from unsigned to signed outside of the bounds of the signed type are + implementation-defined. Verify that they function as reinterpreting the lower + bits of the input in two's complement notation. Do this for conversions: + - from uint(N)_t to int(N)_t with negative result + - from uint(2N)_t to int(N)_t with negative result + - from int(2N)_t to int(N)_t with negative result + - from int(2N)_t to int(N)_t with positive result */ + + /* To int8_t. */ + STATIC_ASSERT(((int8_t)(uint8_t)0xAB == (int8_t)-(int8_t)0x55)); + STATIC_ASSERT((int8_t)(uint16_t)0xABCD == (int8_t)-(int8_t)0x33); + STATIC_ASSERT((int8_t)(int16_t)(uint16_t)0xCDEF == (int8_t)(uint8_t)0xEF); + STATIC_ASSERT((int8_t)(int16_t)(uint16_t)0x9234 == (int8_t)(uint8_t)0x34); + + /* To int16_t. */ + STATIC_ASSERT((int16_t)(uint16_t)0xBCDE == (int16_t)-(int16_t)0x4322); + STATIC_ASSERT((int16_t)(uint32_t)0xA1B2C3D4 == (int16_t)-(int16_t)0x3C2C); + STATIC_ASSERT((int16_t)(int32_t)(uint32_t)0xC1D2E3F4 == (int16_t)(uint16_t)0xE3F4); + STATIC_ASSERT((int16_t)(int32_t)(uint32_t)0x92345678 == (int16_t)(uint16_t)0x5678); + + /* To int32_t. */ + STATIC_ASSERT((int32_t)(uint32_t)0xB2C3D4E5 == (int32_t)-(int32_t)0x4D3C2B1B); + STATIC_ASSERT((int32_t)(uint64_t)0xA123B456C789D012ULL == (int32_t)-(int32_t)0x38762FEE); + STATIC_ASSERT((int32_t)(int64_t)(uint64_t)0xC1D2E3F4A5B6C7D8ULL == (int32_t)(uint32_t)0xA5B6C7D8); + STATIC_ASSERT((int32_t)(int64_t)(uint64_t)0xABCDEF0123456789ULL == (int32_t)(uint32_t)0x23456789); + + /* To int64_t. */ + STATIC_ASSERT((int64_t)(uint64_t)0xB123C456D789E012ULL == (int64_t)-(int64_t)0x4EDC3BA928761FEEULL); +#if defined(SECP256K1_INT128_NATIVE) + STATIC_ASSERT((int64_t)(((uint128_t)0xA1234567B8901234ULL << 64) + 0xC5678901D2345678ULL) == (int64_t)-(int64_t)0x3A9876FE2DCBA988ULL); + STATIC_ASSERT(((int64_t)(int128_t)(((uint128_t)0xB1C2D3E4F5A6B7C8ULL << 64) + 0xD9E0F1A2B3C4D5E6ULL)) == (int64_t)(uint64_t)0xD9E0F1A2B3C4D5E6ULL); + STATIC_ASSERT(((int64_t)(int128_t)(((uint128_t)0xABCDEF0123456789ULL << 64) + 0x0123456789ABCDEFULL)) == (int64_t)(uint64_t)0x0123456789ABCDEFULL); + + /* To int128_t. */ + STATIC_ASSERT((int128_t)(((uint128_t)0xB1234567C8901234ULL << 64) + 0xD5678901E2345678ULL) == (int128_t)(-(int128_t)0x8E1648B3F50E80DCULL * 0x8E1648B3F50E80DDULL + 0x5EA688D5482F9464ULL)); +#endif + + /* Right shift on negative signed values is implementation defined. Verify that it + acts as a right shift in two's complement with sign extension (i.e duplicating + the top bit into newly added bits). */ + STATIC_ASSERT((((int8_t)0xE8) >> 2) == (int8_t)(uint8_t)0xFA); + STATIC_ASSERT((((int16_t)0xE9AC) >> 4) == (int16_t)(uint16_t)0xFE9A); + STATIC_ASSERT((((int32_t)0x937C918A) >> 9) == (int32_t)(uint32_t)0xFFC9BE48); + STATIC_ASSERT((((int64_t)0xA8B72231DF9CF4B9ULL) >> 19) == (int64_t)(uint64_t)0xFFFFF516E4463BF3ULL); +#if defined(SECP256K1_INT128_NATIVE) + STATIC_ASSERT((((int128_t)(((uint128_t)0xCD833A65684A0DBCULL << 64) + 0xB349312F71EA7637ULL)) >> 39) == (int128_t)(((uint128_t)0xFFFFFFFFFF9B0674ULL << 64) + 0xCAD0941B79669262ULL)); +#endif + + /* This function is not supposed to be called. */ + VERIFY_CHECK(0); +} + +#endif /* SECP256K1_ASSUMPTIONS_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/basic-config.h b/crypto/secp256k1/libsecp256k1/src/basic-config.h deleted file mode 100644 index c4c16eb7ca..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/basic-config.h +++ /dev/null @@ -1,32 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_BASIC_CONFIG_ -#define _SECP256K1_BASIC_CONFIG_ - -#ifdef USE_BASIC_CONFIG - -#undef USE_ASM_X86_64 -#undef USE_ENDOMORPHISM -#undef USE_FIELD_10X26 -#undef USE_FIELD_5X52 -#undef USE_FIELD_INV_BUILTIN -#undef USE_FIELD_INV_NUM -#undef USE_NUM_GMP -#undef USE_NUM_NONE -#undef USE_SCALAR_4X64 -#undef USE_SCALAR_8X32 -#undef USE_SCALAR_INV_BUILTIN -#undef USE_SCALAR_INV_NUM - -#define USE_NUM_NONE 1 -#define USE_FIELD_INV_BUILTIN 1 -#define USE_SCALAR_INV_BUILTIN 1 -#define USE_FIELD_10X26 1 -#define USE_SCALAR_8X32 1 - -#endif // USE_BASIC_CONFIG -#endif // _SECP256K1_BASIC_CONFIG_ diff --git a/crypto/secp256k1/libsecp256k1/src/bench.c b/crypto/secp256k1/libsecp256k1/src/bench.c new file mode 100644 index 0000000000..149f25fce4 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/bench.c @@ -0,0 +1,280 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#include +#include +#include + +#include "../include/secp256k1.h" +#include "util.h" +#include "bench.h" + +static void help(int default_iters) { + printf("Benchmarks the following algorithms:\n"); + printf(" - ECDSA signing/verification\n"); + +#ifdef ENABLE_MODULE_ECDH + printf(" - ECDH key exchange (optional module)\n"); +#endif + +#ifdef ENABLE_MODULE_RECOVERY + printf(" - Public key recovery (optional module)\n"); +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG + printf(" - Schnorr signatures (optional module)\n"); +#endif + + printf("\n"); + printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters); + printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n"); + printf("\n"); + printf("Usage: ./bench [args]\n"); + printf("By default, all benchmarks will be run.\n"); + printf("args:\n"); + printf(" help : display this help and exit\n"); + printf(" ecdsa : all ECDSA algorithms--sign, verify, recovery (if enabled)\n"); + printf(" ecdsa_sign : ECDSA siging algorithm\n"); + printf(" ecdsa_verify : ECDSA verification algorithm\n"); + printf(" ec : all EC public key algorithms (keygen)\n"); + printf(" ec_keygen : EC public key generation\n"); + +#ifdef ENABLE_MODULE_RECOVERY + printf(" ecdsa_recover : ECDSA public key recovery algorithm\n"); +#endif + +#ifdef ENABLE_MODULE_ECDH + printf(" ecdh : ECDH key exchange algorithm\n"); +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG + printf(" schnorrsig : all Schnorr signature algorithms (sign, verify)\n"); + printf(" schnorrsig_sign : Schnorr sigining algorithm\n"); + printf(" schnorrsig_verify : Schnorr verification algorithm\n"); +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT + printf(" ellswift : all ElligatorSwift benchmarks (encode, decode, keygen, ecdh)\n"); + printf(" ellswift_encode : ElligatorSwift encoding\n"); + printf(" ellswift_decode : ElligatorSwift decoding\n"); + printf(" ellswift_keygen : ElligatorSwift key generation\n"); + printf(" ellswift_ecdh : ECDH on ElligatorSwift keys\n"); +#endif + + printf("\n"); +} + +typedef struct { + secp256k1_context *ctx; + unsigned char msg[32]; + unsigned char key[32]; + unsigned char sig[72]; + size_t siglen; + unsigned char pubkey[33]; + size_t pubkeylen; +} bench_data; + +static void bench_verify(void* arg, int iters) { + int i; + bench_data* data = (bench_data*)arg; + + for (i = 0; i < iters; i++) { + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1); + CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0)); + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + } +} + +static void bench_sign_setup(void* arg) { + int i; + bench_data *data = (bench_data*)arg; + + for (i = 0; i < 32; i++) { + data->msg[i] = i + 1; + } + for (i = 0; i < 32; i++) { + data->key[i] = i + 65; + } +} + +static void bench_sign_run(void* arg, int iters) { + int i; + bench_data *data = (bench_data*)arg; + + unsigned char sig[74]; + for (i = 0; i < iters; i++) { + size_t siglen = 74; + int j; + secp256k1_ecdsa_signature signature; + CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL)); + CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature)); + for (j = 0; j < 32; j++) { + data->msg[j] = sig[j]; + data->key[j] = sig[j + 32]; + } + } +} + +static void bench_keygen_setup(void* arg) { + int i; + bench_data *data = (bench_data*)arg; + + for (i = 0; i < 32; i++) { + data->key[i] = i + 65; + } +} + +static void bench_keygen_run(void *arg, int iters) { + int i; + bench_data *data = (bench_data*)arg; + + for (i = 0; i < iters; i++) { + unsigned char pub33[33]; + size_t len = 33; + secp256k1_pubkey pubkey; + CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->key)); + CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pub33, &len, &pubkey, SECP256K1_EC_COMPRESSED)); + memcpy(data->key, pub33 + 1, 32); + } +} + + +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/bench_impl.h" +#endif + +#ifdef ENABLE_MODULE_RECOVERY +# include "modules/recovery/bench_impl.h" +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG +# include "modules/schnorrsig/bench_impl.h" +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT +# include "modules/ellswift/bench_impl.h" +#endif + +int main(int argc, char** argv) { + int i; + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; + bench_data data; + + int d = argc == 1; + int default_iters = 20000; + int iters = get_iters(default_iters); + + /* Check for invalid user arguments */ + char* valid_args[] = {"ecdsa", "verify", "ecdsa_verify", "sign", "ecdsa_sign", "ecdh", "recover", + "ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign", "ec", + "keygen", "ec_keygen", "ellswift", "encode", "ellswift_encode", "decode", + "ellswift_decode", "ellswift_keygen", "ellswift_ecdh"}; + size_t valid_args_size = sizeof(valid_args)/sizeof(valid_args[0]); + int invalid_args = have_invalid_args(argc, argv, valid_args, valid_args_size); + + if (argc > 1) { + if (have_flag(argc, argv, "-h") + || have_flag(argc, argv, "--help") + || have_flag(argc, argv, "help")) { + help(default_iters); + return EXIT_SUCCESS; + } else if (invalid_args) { + fprintf(stderr, "./bench: unrecognized argument.\n\n"); + help(default_iters); + return EXIT_FAILURE; + } + } + +/* Check if the user tries to benchmark optional module without building it */ +#ifndef ENABLE_MODULE_ECDH + if (have_flag(argc, argv, "ecdh")) { + fprintf(stderr, "./bench: ECDH module not enabled.\n"); + fprintf(stderr, "Use ./configure --enable-module-ecdh.\n\n"); + return EXIT_FAILURE; + } +#endif + +#ifndef ENABLE_MODULE_RECOVERY + if (have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) { + fprintf(stderr, "./bench: Public key recovery module not enabled.\n"); + fprintf(stderr, "Use ./configure --enable-module-recovery.\n\n"); + return EXIT_FAILURE; + } +#endif + +#ifndef ENABLE_MODULE_SCHNORRSIG + if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) { + fprintf(stderr, "./bench: Schnorr signatures module not enabled.\n"); + fprintf(stderr, "Use ./configure --enable-module-schnorrsig.\n\n"); + return EXIT_FAILURE; + } +#endif + +#ifndef ENABLE_MODULE_ELLSWIFT + if (have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "ellswift_encode") || have_flag(argc, argv, "ellswift_decode") || + have_flag(argc, argv, "encode") || have_flag(argc, argv, "decode") || have_flag(argc, argv, "ellswift_keygen") || + have_flag(argc, argv, "ellswift_ecdh")) { + fprintf(stderr, "./bench: ElligatorSwift module not enabled.\n"); + fprintf(stderr, "Use ./configure --enable-module-ellswift.\n\n"); + return EXIT_FAILURE; + } +#endif + + /* ECDSA benchmark */ + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + + for (i = 0; i < 32; i++) { + data.msg[i] = 1 + i; + } + for (i = 0; i < 32; i++) { + data.key[i] = 33 + i; + } + data.siglen = 72; + CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL)); + CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig)); + CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key)); + data.pubkeylen = 33; + CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + + print_output_table_header_row(); + if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "ecdsa_verify")) run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, 10, iters); + + if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "ecdsa_sign")) run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "ec") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ec_keygen")) run_benchmark("ec_keygen", bench_keygen_run, bench_keygen_setup, NULL, &data, 10, iters); + + secp256k1_context_destroy(data.ctx); + +#ifdef ENABLE_MODULE_ECDH + /* ECDH benchmarks */ + run_ecdh_bench(iters, argc, argv); +#endif + +#ifdef ENABLE_MODULE_RECOVERY + /* ECDSA recovery benchmarks */ + run_recovery_bench(iters, argc, argv); +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG + /* Schnorr signature benchmarks */ + run_schnorrsig_bench(iters, argc, argv); +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT + /* ElligatorSwift benchmarks */ + run_ellswift_bench(iters, argc, argv); +#endif + + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/src/bench.h b/crypto/secp256k1/libsecp256k1/src/bench.h index 3a71b4aafa..232fb35fc0 100644 --- a/crypto/secp256k1/libsecp256k1/src/bench.h +++ b/crypto/secp256k1/libsecp256k1/src/bench.h @@ -1,50 +1,115 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_BENCH_H_ -#define _SECP256K1_BENCH_H_ +#ifndef SECP256K1_BENCH_H +#define SECP256K1_BENCH_H +#include +#include #include -#include -#include "sys/time.h" +#include -static double gettimedouble(void) { +#if (defined(_MSC_VER) && _MSC_VER >= 1900) +# include +#else +# include +#endif + +static int64_t gettime_i64(void) { +#if (defined(_MSC_VER) && _MSC_VER >= 1900) + /* C11 way to get wallclock time */ + struct timespec tv; + if (!timespec_get(&tv, TIME_UTC)) { + fputs("timespec_get failed!", stderr); + exit(EXIT_FAILURE); + } + return (int64_t)tv.tv_nsec / 1000 + (int64_t)tv.tv_sec * 1000000LL; +#else struct timeval tv; gettimeofday(&tv, NULL); - return tv.tv_usec * 0.000001 + tv.tv_sec; + return (int64_t)tv.tv_usec + (int64_t)tv.tv_sec * 1000000LL; +#endif } -void print_number(double x) { - double y = x; - int c = 0; - if (y < 0.0) { - y = -y; +#define FP_EXP (6) +#define FP_MULT (1000000LL) + +/* Format fixed point number. */ +static void print_number(const int64_t x) { + int64_t x_abs, y; + int c, i, rounding, g; /* g = integer part size, c = fractional part size */ + size_t ptr; + char buffer[30]; + + if (x == INT64_MIN) { + /* Prevent UB. */ + printf("ERR"); + return; } - while (y < 100.0) { - y *= 10.0; + x_abs = x < 0 ? -x : x; + + /* Determine how many decimals we want to show (more than FP_EXP makes no + * sense). */ + y = x_abs; + c = 0; + while (y > 0LL && y < 100LL * FP_MULT && c < FP_EXP) { + y *= 10LL; c++; } - printf("%.*f", c, x); + + /* Round to 'c' decimals. */ + y = x_abs; + rounding = 0; + for (i = c; i < FP_EXP; ++i) { + rounding = (y % 10) >= 5; + y /= 10; + } + y += rounding; + + /* Format and print the number. */ + ptr = sizeof(buffer) - 1; + buffer[ptr] = 0; + g = 0; + if (c != 0) { /* non zero fractional part */ + for (i = 0; i < c; ++i) { + buffer[--ptr] = '0' + (y % 10); + y /= 10; + } + } else if (c == 0) { /* fractional part is 0 */ + buffer[--ptr] = '0'; + } + buffer[--ptr] = '.'; + do { + buffer[--ptr] = '0' + (y % 10); + y /= 10; + g++; + } while (y != 0); + if (x < 0) { + buffer[--ptr] = '-'; + g++; + } + printf("%5.*s", g, &buffer[ptr]); /* Prints integer part */ + printf("%-*s", FP_EXP, &buffer[ptr + g]); /* Prints fractional part */ } -void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { +static void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void*), void (*teardown)(void*, int), void* data, int count, int iter) { int i; - double min = HUGE_VAL; - double sum = 0.0; - double max = 0.0; + int64_t min = INT64_MAX; + int64_t sum = 0; + int64_t max = 0; for (i = 0; i < count; i++) { - double begin, total; + int64_t begin, total; if (setup != NULL) { setup(data); } - begin = gettimedouble(); - benchmark(data); - total = gettimedouble() - begin; + begin = gettime_i64(); + benchmark(data, iter); + total = gettime_i64() - begin; if (teardown != NULL) { - teardown(data); + teardown(data, iter); } if (total < min) { min = total; @@ -54,13 +119,70 @@ void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), v } sum += total; } - printf("%s: min ", name); - print_number(min * 1000000.0 / iter); - printf("us / avg "); - print_number((sum / count) * 1000000.0 / iter); - printf("us / max "); - print_number(max * 1000000.0 / iter); - printf("us\n"); + /* ',' is used as a column delimiter */ + printf("%-30s, ", name); + print_number(min * FP_MULT / iter); + printf(" , "); + print_number(((sum * FP_MULT) / count) / iter); + printf(" , "); + print_number(max * FP_MULT / iter); + printf("\n"); } -#endif +static int have_flag(int argc, char** argv, char *flag) { + char** argm = argv + argc; + argv++; + while (argv != argm) { + if (strcmp(*argv, flag) == 0) { + return 1; + } + argv++; + } + return 0; +} + +/* takes an array containing the arguments that the user is allowed to enter on the command-line + returns: + - 1 if the user entered an invalid argument + - 0 if all the user entered arguments are valid */ +static int have_invalid_args(int argc, char** argv, char** valid_args, size_t n) { + size_t i; + int found_valid; + char** argm = argv + argc; + argv++; + + while (argv != argm) { + found_valid = 0; + for (i = 0; i < n; i++) { + if (strcmp(*argv, valid_args[i]) == 0) { + found_valid = 1; /* user entered a valid arg from the list */ + break; + } + } + if (found_valid == 0) { + return 1; /* invalid arg found */ + } + argv++; + } + return 0; +} + +static int get_iters(int default_iters) { + char* env = getenv("SECP256K1_BENCH_ITERS"); + if (env) { + return strtol(env, NULL, 0); + } else { + return default_iters; + } +} + +static void print_output_table_header_row(void) { + char* bench_str = "Benchmark"; /* left justified */ + char* min_str = " Min(us) "; /* center alignment */ + char* avg_str = " Avg(us) "; + char* max_str = " Max(us) "; + printf("%-30s,%-15s,%-15s,%-15s\n", bench_str, min_str, avg_str, max_str); + printf("\n"); +} + +#endif /* SECP256K1_BENCH_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/bench_ecmult.c b/crypto/secp256k1/libsecp256k1/src/bench_ecmult.c new file mode 100644 index 0000000000..172292d570 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/bench_ecmult.c @@ -0,0 +1,368 @@ +/*********************************************************************** + * Copyright (c) 2017 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ +#include +#include + +#include "secp256k1.c" +#include "../include/secp256k1.h" + +#include "util.h" +#include "hash_impl.h" +#include "field_impl.h" +#include "group_impl.h" +#include "scalar_impl.h" +#include "ecmult_impl.h" +#include "bench.h" + +#define POINTS 32768 + +static void help(char **argv) { + printf("Benchmark EC multiplication algorithms\n"); + printf("\n"); + printf("Usage: %s \n", argv[0]); + printf("The output shows the number of multiplied and summed points right after the\n"); + printf("function name. The letter 'g' indicates that one of the points is the generator.\n"); + printf("The benchmarks are divided by the number of points.\n"); + printf("\n"); + printf("default (ecmult_multi): picks pippenger_wnaf or strauss_wnaf depending on the\n"); + printf(" batch size\n"); + printf("pippenger_wnaf: for all batch sizes\n"); + printf("strauss_wnaf: for all batch sizes\n"); + printf("simple: multiply and sum each point individually\n"); +} + +typedef struct { + /* Setup once in advance */ + secp256k1_context* ctx; + secp256k1_scratch_space* scratch; + secp256k1_scalar* scalars; + secp256k1_ge* pubkeys; + secp256k1_gej* pubkeys_gej; + secp256k1_scalar* seckeys; + secp256k1_gej* expected_output; + secp256k1_ecmult_multi_func ecmult_multi; + + /* Changes per benchmark */ + size_t count; + int includes_g; + + /* Changes per benchmark iteration, used to pick different scalars and pubkeys + * in each run. */ + size_t offset1; + size_t offset2; + + /* Benchmark output. */ + secp256k1_gej* output; +} bench_data; + +/* Hashes x into [0, POINTS) twice and store the result in offset1 and offset2. */ +static void hash_into_offset(bench_data* data, size_t x) { + data->offset1 = (x * 0x537b7f6f + 0x8f66a481) % POINTS; + data->offset2 = (x * 0x7f6f537b + 0x6a1a8f49) % POINTS; +} + +/* Check correctness of the benchmark by computing + * sum(outputs) ?= (sum(scalars_gen) + sum(seckeys)*sum(scalars))*G */ +static void bench_ecmult_teardown_helper(bench_data* data, size_t* seckey_offset, size_t* scalar_offset, size_t* scalar_gen_offset, int iters) { + int i; + secp256k1_gej sum_output, tmp; + secp256k1_scalar sum_scalars; + + secp256k1_gej_set_infinity(&sum_output); + secp256k1_scalar_set_int(&sum_scalars, 0); + for (i = 0; i < iters; ++i) { + secp256k1_gej_add_var(&sum_output, &sum_output, &data->output[i], NULL); + if (scalar_gen_offset != NULL) { + secp256k1_scalar_add(&sum_scalars, &sum_scalars, &data->scalars[(*scalar_gen_offset+i) % POINTS]); + } + if (seckey_offset != NULL) { + secp256k1_scalar s = data->seckeys[(*seckey_offset+i) % POINTS]; + secp256k1_scalar_mul(&s, &s, &data->scalars[(*scalar_offset+i) % POINTS]); + secp256k1_scalar_add(&sum_scalars, &sum_scalars, &s); + } + } + secp256k1_ecmult_gen(&data->ctx->ecmult_gen_ctx, &tmp, &sum_scalars); + CHECK(secp256k1_gej_eq_var(&tmp, &sum_output)); +} + +static void bench_ecmult_setup(void* arg) { + bench_data* data = (bench_data*)arg; + /* Re-randomize offset to ensure that we're using different scalars and + * group elements in each run. */ + hash_into_offset(data, data->offset1); +} + +static void bench_ecmult_gen(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + int i; + + for (i = 0; i < iters; ++i) { + secp256k1_ecmult_gen(&data->ctx->ecmult_gen_ctx, &data->output[i], &data->scalars[(data->offset1+i) % POINTS]); + } +} + +static void bench_ecmult_gen_teardown(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + bench_ecmult_teardown_helper(data, NULL, NULL, &data->offset1, iters); +} + +static void bench_ecmult_const(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + int i; + + for (i = 0; i < iters; ++i) { + secp256k1_ecmult_const(&data->output[i], &data->pubkeys[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS]); + } +} + +static void bench_ecmult_const_teardown(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, NULL, iters); +} + +static void bench_ecmult_1p(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + int i; + + for (i = 0; i < iters; ++i) { + secp256k1_ecmult(&data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], NULL); + } +} + +static void bench_ecmult_1p_teardown(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, NULL, iters); +} + +static void bench_ecmult_0p_g(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + int i; + + for (i = 0; i < iters; ++i) { + secp256k1_ecmult(&data->output[i], NULL, &secp256k1_scalar_zero, &data->scalars[(data->offset1+i) % POINTS]); + } +} + +static void bench_ecmult_0p_g_teardown(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + bench_ecmult_teardown_helper(data, NULL, NULL, &data->offset1, iters); +} + +static void bench_ecmult_1p_g(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + int i; + + for (i = 0; i < iters/2; ++i) { + secp256k1_ecmult(&data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], &data->scalars[(data->offset1+i) % POINTS]); + } +} + +static void bench_ecmult_1p_g_teardown(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, &data->offset1, iters/2); +} + +static void run_ecmult_bench(bench_data* data, int iters) { + char str[32]; + sprintf(str, "ecmult_gen"); + run_benchmark(str, bench_ecmult_gen, bench_ecmult_setup, bench_ecmult_gen_teardown, data, 10, iters); + sprintf(str, "ecmult_const"); + run_benchmark(str, bench_ecmult_const, bench_ecmult_setup, bench_ecmult_const_teardown, data, 10, iters); + /* ecmult with non generator point */ + sprintf(str, "ecmult_1p"); + run_benchmark(str, bench_ecmult_1p, bench_ecmult_setup, bench_ecmult_1p_teardown, data, 10, iters); + /* ecmult with generator point */ + sprintf(str, "ecmult_0p_g"); + run_benchmark(str, bench_ecmult_0p_g, bench_ecmult_setup, bench_ecmult_0p_g_teardown, data, 10, iters); + /* ecmult with generator and non-generator point. The reported time is per point. */ + sprintf(str, "ecmult_1p_g"); + run_benchmark(str, bench_ecmult_1p_g, bench_ecmult_setup, bench_ecmult_1p_g_teardown, data, 10, 2*iters); +} + +static int bench_ecmult_multi_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, void* arg) { + bench_data* data = (bench_data*)arg; + if (data->includes_g) ++idx; + if (idx == 0) { + *sc = data->scalars[data->offset1]; + *ge = secp256k1_ge_const_g; + } else { + *sc = data->scalars[(data->offset1 + idx) % POINTS]; + *ge = data->pubkeys[(data->offset2 + idx - 1) % POINTS]; + } + return 1; +} + +static void bench_ecmult_multi(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + + int includes_g = data->includes_g; + int iter; + int count = data->count; + iters = iters / data->count; + + for (iter = 0; iter < iters; ++iter) { + data->ecmult_multi(&data->ctx->error_callback, data->scratch, &data->output[iter], data->includes_g ? &data->scalars[data->offset1] : NULL, bench_ecmult_multi_callback, arg, count - includes_g); + data->offset1 = (data->offset1 + count) % POINTS; + data->offset2 = (data->offset2 + count - 1) % POINTS; + } +} + +static void bench_ecmult_multi_setup(void* arg) { + bench_data* data = (bench_data*)arg; + hash_into_offset(data, data->count); +} + +static void bench_ecmult_multi_teardown(void* arg, int iters) { + bench_data* data = (bench_data*)arg; + int iter; + iters = iters / data->count; + /* Verify the results in teardown, to avoid doing comparisons while benchmarking. */ + for (iter = 0; iter < iters; ++iter) { + secp256k1_gej tmp; + secp256k1_gej_add_var(&tmp, &data->output[iter], &data->expected_output[iter], NULL); + CHECK(secp256k1_gej_is_infinity(&tmp)); + } +} + +static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) { + secp256k1_sha256 sha256; + unsigned char c[10] = {'e', 'c', 'm', 'u', 'l', 't', 0, 0, 0, 0}; + unsigned char buf[32]; + int overflow = 0; + c[6] = num; + c[7] = num >> 8; + c[8] = num >> 16; + c[9] = num >> 24; + secp256k1_sha256_initialize(&sha256); + secp256k1_sha256_write(&sha256, c, sizeof(c)); + secp256k1_sha256_finalize(&sha256, buf); + secp256k1_scalar_set_b32(scalar, buf, &overflow); + CHECK(!overflow); +} + +static void run_ecmult_multi_bench(bench_data* data, size_t count, int includes_g, int num_iters) { + char str[32]; + size_t iters = 1 + num_iters / count; + size_t iter; + + data->count = count; + data->includes_g = includes_g; + + /* Compute (the negation of) the expected results directly. */ + hash_into_offset(data, data->count); + for (iter = 0; iter < iters; ++iter) { + secp256k1_scalar tmp; + secp256k1_scalar total = data->scalars[(data->offset1++) % POINTS]; + size_t i = 0; + for (i = 0; i + 1 < count; ++i) { + secp256k1_scalar_mul(&tmp, &data->seckeys[(data->offset2++) % POINTS], &data->scalars[(data->offset1++) % POINTS]); + secp256k1_scalar_add(&total, &total, &tmp); + } + secp256k1_scalar_negate(&total, &total); + secp256k1_ecmult(&data->expected_output[iter], NULL, &secp256k1_scalar_zero, &total); + } + + /* Run the benchmark. */ + if (includes_g) { + sprintf(str, "ecmult_multi_%ip_g", (int)count - 1); + } else { + sprintf(str, "ecmult_multi_%ip", (int)count); + } + run_benchmark(str, bench_ecmult_multi, bench_ecmult_multi_setup, bench_ecmult_multi_teardown, data, 10, count * iters); +} + +int main(int argc, char **argv) { + bench_data data; + int i, p; + size_t scratch_size; + + int iters = get_iters(10000); + + data.ecmult_multi = secp256k1_ecmult_multi_var; + + if (argc > 1) { + if(have_flag(argc, argv, "-h") + || have_flag(argc, argv, "--help") + || have_flag(argc, argv, "help")) { + help(argv); + return EXIT_SUCCESS; + } else if(have_flag(argc, argv, "pippenger_wnaf")) { + printf("Using pippenger_wnaf:\n"); + data.ecmult_multi = secp256k1_ecmult_pippenger_batch_single; + } else if(have_flag(argc, argv, "strauss_wnaf")) { + printf("Using strauss_wnaf:\n"); + data.ecmult_multi = secp256k1_ecmult_strauss_batch_single; + } else if(have_flag(argc, argv, "simple")) { + printf("Using simple algorithm:\n"); + } else { + fprintf(stderr, "%s: unrecognized argument '%s'.\n\n", argv[0], argv[1]); + help(argv); + return EXIT_FAILURE; + } + } + + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*16; + if (!have_flag(argc, argv, "simple")) { + data.scratch = secp256k1_scratch_space_create(data.ctx, scratch_size); + } else { + data.scratch = NULL; + } + + /* Allocate stuff */ + data.scalars = malloc(sizeof(secp256k1_scalar) * POINTS); + data.seckeys = malloc(sizeof(secp256k1_scalar) * POINTS); + data.pubkeys = malloc(sizeof(secp256k1_ge) * POINTS); + data.pubkeys_gej = malloc(sizeof(secp256k1_gej) * POINTS); + data.expected_output = malloc(sizeof(secp256k1_gej) * (iters + 1)); + data.output = malloc(sizeof(secp256k1_gej) * (iters + 1)); + + /* Generate a set of scalars, and private/public keypairs. */ + secp256k1_gej_set_ge(&data.pubkeys_gej[0], &secp256k1_ge_const_g); + secp256k1_scalar_set_int(&data.seckeys[0], 1); + for (i = 0; i < POINTS; ++i) { + generate_scalar(i, &data.scalars[i]); + if (i) { + secp256k1_gej_double_var(&data.pubkeys_gej[i], &data.pubkeys_gej[i - 1], NULL); + secp256k1_scalar_add(&data.seckeys[i], &data.seckeys[i - 1], &data.seckeys[i - 1]); + } + } + secp256k1_ge_set_all_gej_var(data.pubkeys, data.pubkeys_gej, POINTS); + + + print_output_table_header_row(); + /* Initialize offset1 and offset2 */ + hash_into_offset(&data, 0); + run_ecmult_bench(&data, iters); + + for (i = 1; i <= 8; ++i) { + run_ecmult_multi_bench(&data, i, 1, iters); + } + + /* This is disabled with low count of iterations because the loop runs 77 times even with iters=1 + * and the higher it goes the longer the computation takes(more points) + * So we don't run this benchmark with low iterations to prevent slow down */ + if (iters > 2) { + for (p = 0; p <= 11; ++p) { + for (i = 9; i <= 16; ++i) { + run_ecmult_multi_bench(&data, i << p, 1, iters); + } + } + } + + if (data.scratch != NULL) { + secp256k1_scratch_space_destroy(data.ctx, data.scratch); + } + secp256k1_context_destroy(data.ctx); + free(data.scalars); + free(data.pubkeys); + free(data.pubkeys_gej); + free(data.seckeys); + free(data.output); + free(data.expected_output); + + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/src/bench_internal.c b/crypto/secp256k1/libsecp256k1/src/bench_internal.c index 0809f77bda..8688a4dc77 100644 --- a/crypto/secp256k1/libsecp256k1/src/bench_internal.c +++ b/crypto/secp256k1/libsecp256k1/src/bench_internal.c @@ -1,382 +1,437 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include +#include -#include "include/secp256k1.h" +#include "secp256k1.c" +#include "../include/secp256k1.h" +#include "assumptions.h" #include "util.h" #include "hash_impl.h" -#include "num_impl.h" #include "field_impl.h" #include "group_impl.h" #include "scalar_impl.h" -#include "ecmult_const_impl.h" #include "ecmult_impl.h" #include "bench.h" -#include "secp256k1.c" + +static void help(int default_iters) { + printf("Benchmarks various internal routines.\n"); + printf("\n"); + printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters); + printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n"); + printf("\n"); + printf("Usage: ./bench_internal [args]\n"); + printf("By default, all benchmarks will be run.\n"); + printf("args:\n"); + printf(" help : display this help and exit\n"); + printf(" scalar : all scalar operations (add, half, inverse, mul, negate, split)\n"); + printf(" field : all field operations (half, inverse, issquare, mul, normalize, sqr, sqrt)\n"); + printf(" group : all group operations (add, double, to_affine)\n"); + printf(" ecmult : all point multiplication operations (ecmult_wnaf) \n"); + printf(" hash : all hash algorithms (hmac, rng6979, sha256)\n"); + printf(" context : all context object operations (context_create)\n"); + printf("\n"); +} typedef struct { - secp256k1_scalar scalar_x, scalar_y; - secp256k1_fe fe_x, fe_y; - secp256k1_ge ge_x, ge_y; - secp256k1_gej gej_x, gej_y; + secp256k1_scalar scalar[2]; + secp256k1_fe fe[4]; + secp256k1_ge ge[2]; + secp256k1_gej gej[2]; unsigned char data[64]; int wnaf[256]; -} bench_inv_t; +} bench_inv; -void bench_setup(void* arg) { - bench_inv_t *data = (bench_inv_t*)arg; +static void bench_setup(void* arg) { + bench_inv *data = (bench_inv*)arg; - static const unsigned char init_x[32] = { - 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, - 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35, - 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59, - 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83 + static const unsigned char init[4][32] = { + /* Initializer for scalar[0], fe[0], first half of data, the X coordinate of ge[0], + and the (implied affine) X coordinate of gej[0]. */ + { + 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, + 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35, + 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59, + 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83 + }, + /* Initializer for scalar[1], fe[1], first half of data, the X coordinate of ge[1], + and the (implied affine) X coordinate of gej[1]. */ + { + 0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83, + 0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5, + 0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9, + 0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3 + }, + /* Initializer for fe[2] and the Z coordinate of gej[0]. */ + { + 0x3d, 0x2d, 0xef, 0xf4, 0x25, 0x98, 0x4f, 0x5d, + 0xe2, 0xca, 0x5f, 0x41, 0x3f, 0x3f, 0xce, 0x44, + 0xaa, 0x2c, 0x53, 0x8a, 0xc6, 0x59, 0x1f, 0x38, + 0x38, 0x23, 0xe4, 0x11, 0x27, 0xc6, 0xa0, 0xe7 + }, + /* Initializer for fe[3] and the Z coordinate of gej[1]. */ + { + 0xbd, 0x21, 0xa5, 0xe1, 0x13, 0x50, 0x73, 0x2e, + 0x52, 0x98, 0xc8, 0x9e, 0xab, 0x00, 0xa2, 0x68, + 0x43, 0xf5, 0xd7, 0x49, 0x80, 0x72, 0xa7, 0xf3, + 0xd7, 0x60, 0xe6, 0xab, 0x90, 0x92, 0xdf, 0xc5 + } }; - static const unsigned char init_y[32] = { - 0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83, - 0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5, - 0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9, - 0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3 - }; - - secp256k1_scalar_set_b32(&data->scalar_x, init_x, NULL); - secp256k1_scalar_set_b32(&data->scalar_y, init_y, NULL); - secp256k1_fe_set_b32(&data->fe_x, init_x); - secp256k1_fe_set_b32(&data->fe_y, init_y); - CHECK(secp256k1_ge_set_xo_var(&data->ge_x, &data->fe_x, 0)); - CHECK(secp256k1_ge_set_xo_var(&data->ge_y, &data->fe_y, 1)); - secp256k1_gej_set_ge(&data->gej_x, &data->ge_x); - secp256k1_gej_set_ge(&data->gej_y, &data->ge_y); - memcpy(data->data, init_x, 32); - memcpy(data->data + 32, init_y, 32); + secp256k1_scalar_set_b32(&data->scalar[0], init[0], NULL); + secp256k1_scalar_set_b32(&data->scalar[1], init[1], NULL); + secp256k1_fe_set_b32_limit(&data->fe[0], init[0]); + secp256k1_fe_set_b32_limit(&data->fe[1], init[1]); + secp256k1_fe_set_b32_limit(&data->fe[2], init[2]); + secp256k1_fe_set_b32_limit(&data->fe[3], init[3]); + CHECK(secp256k1_ge_set_xo_var(&data->ge[0], &data->fe[0], 0)); + CHECK(secp256k1_ge_set_xo_var(&data->ge[1], &data->fe[1], 1)); + secp256k1_gej_set_ge(&data->gej[0], &data->ge[0]); + secp256k1_gej_rescale(&data->gej[0], &data->fe[2]); + secp256k1_gej_set_ge(&data->gej[1], &data->ge[1]); + secp256k1_gej_rescale(&data->gej[1], &data->fe[3]); + memcpy(data->data, init[0], 32); + memcpy(data->data + 32, init[1], 32); } -void bench_scalar_add(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; +static void bench_scalar_add(void* arg, int iters) { + int i, j = 0; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 2000000; i++) { - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + for (i = 0; i < iters; i++) { + j += secp256k1_scalar_add(&data->scalar[0], &data->scalar[0], &data->scalar[1]); + } + CHECK(j <= iters); +} + +static void bench_scalar_negate(void* arg, int iters) { + int i; + bench_inv *data = (bench_inv*)arg; + + for (i = 0; i < iters; i++) { + secp256k1_scalar_negate(&data->scalar[0], &data->scalar[0]); } } -void bench_scalar_negate(void* arg) { +static void bench_scalar_half(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; + secp256k1_scalar s = data->scalar[0]; - for (i = 0; i < 2000000; i++) { - secp256k1_scalar_negate(&data->scalar_x, &data->scalar_x); + for (i = 0; i < iters; i++) { + secp256k1_scalar_half(&s, &s); + } + + data->scalar[0] = s; +} + +static void bench_scalar_mul(void* arg, int iters) { + int i; + bench_inv *data = (bench_inv*)arg; + + for (i = 0; i < iters; i++) { + secp256k1_scalar_mul(&data->scalar[0], &data->scalar[0], &data->scalar[1]); } } -void bench_scalar_sqr(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; +static void bench_scalar_split(void* arg, int iters) { + int i, j = 0; + bench_inv *data = (bench_inv*)arg; + secp256k1_scalar tmp; - for (i = 0; i < 200000; i++) { - secp256k1_scalar_sqr(&data->scalar_x, &data->scalar_x); + for (i = 0; i < iters; i++) { + secp256k1_scalar_split_lambda(&tmp, &data->scalar[1], &data->scalar[0]); + j += secp256k1_scalar_add(&data->scalar[0], &tmp, &data->scalar[1]); + } + CHECK(j <= iters); +} + +static void bench_scalar_inverse(void* arg, int iters) { + int i, j = 0; + bench_inv *data = (bench_inv*)arg; + + for (i = 0; i < iters; i++) { + secp256k1_scalar_inverse(&data->scalar[0], &data->scalar[0]); + j += secp256k1_scalar_add(&data->scalar[0], &data->scalar[0], &data->scalar[1]); + } + CHECK(j <= iters); +} + +static void bench_scalar_inverse_var(void* arg, int iters) { + int i, j = 0; + bench_inv *data = (bench_inv*)arg; + + for (i = 0; i < iters; i++) { + secp256k1_scalar_inverse_var(&data->scalar[0], &data->scalar[0]); + j += secp256k1_scalar_add(&data->scalar[0], &data->scalar[0], &data->scalar[1]); + } + CHECK(j <= iters); +} + +static void bench_field_half(void* arg, int iters) { + int i; + bench_inv *data = (bench_inv*)arg; + + for (i = 0; i < iters; i++) { + secp256k1_fe_half(&data->fe[0]); } } -void bench_scalar_mul(void* arg) { +static void bench_field_normalize(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 200000; i++) { - secp256k1_scalar_mul(&data->scalar_x, &data->scalar_x, &data->scalar_y); + for (i = 0; i < iters; i++) { + secp256k1_fe_normalize(&data->fe[0]); } } -#ifdef USE_ENDOMORPHISM -void bench_scalar_split(void* arg) { +static void bench_field_normalize_weak(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 20000; i++) { - secp256k1_scalar l, r; - secp256k1_scalar_split_lambda(&l, &r, &data->scalar_x); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} -#endif - -void bench_scalar_inverse(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; - - for (i = 0; i < 2000; i++) { - secp256k1_scalar_inverse(&data->scalar_x, &data->scalar_x); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + for (i = 0; i < iters; i++) { + secp256k1_fe_normalize_weak(&data->fe[0]); } } -void bench_scalar_inverse_var(void* arg) { +static void bench_field_mul(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 2000; i++) { - secp256k1_scalar_inverse_var(&data->scalar_x, &data->scalar_x); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + for (i = 0; i < iters; i++) { + secp256k1_fe_mul(&data->fe[0], &data->fe[0], &data->fe[1]); } } -void bench_field_normalize(void* arg) { +static void bench_field_sqr(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 2000000; i++) { - secp256k1_fe_normalize(&data->fe_x); + for (i = 0; i < iters; i++) { + secp256k1_fe_sqr(&data->fe[0], &data->fe[0]); } } -void bench_field_normalize_weak(void* arg) { +static void bench_field_inverse(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 2000000; i++) { - secp256k1_fe_normalize_weak(&data->fe_x); + for (i = 0; i < iters; i++) { + secp256k1_fe_inv(&data->fe[0], &data->fe[0]); + secp256k1_fe_add(&data->fe[0], &data->fe[1]); } } -void bench_field_mul(void* arg) { +static void bench_field_inverse_var(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 200000; i++) { - secp256k1_fe_mul(&data->fe_x, &data->fe_x, &data->fe_y); + for (i = 0; i < iters; i++) { + secp256k1_fe_inv_var(&data->fe[0], &data->fe[0]); + secp256k1_fe_add(&data->fe[0], &data->fe[1]); } } -void bench_field_sqr(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; +static void bench_field_sqrt(void* arg, int iters) { + int i, j = 0; + bench_inv *data = (bench_inv*)arg; + secp256k1_fe t; - for (i = 0; i < 200000; i++) { - secp256k1_fe_sqr(&data->fe_x, &data->fe_x); + for (i = 0; i < iters; i++) { + t = data->fe[0]; + j += secp256k1_fe_sqrt(&data->fe[0], &t); + secp256k1_fe_add(&data->fe[0], &data->fe[1]); + } + CHECK(j <= iters); +} + +static void bench_field_is_square_var(void* arg, int iters) { + int i, j = 0; + bench_inv *data = (bench_inv*)arg; + secp256k1_fe t = data->fe[0]; + + for (i = 0; i < iters; i++) { + j += secp256k1_fe_is_square_var(&t); + secp256k1_fe_add(&t, &data->fe[1]); + secp256k1_fe_normalize_var(&t); + } + CHECK(j <= iters); +} + +static void bench_group_double_var(void* arg, int iters) { + int i; + bench_inv *data = (bench_inv*)arg; + + for (i = 0; i < iters; i++) { + secp256k1_gej_double_var(&data->gej[0], &data->gej[0], NULL); } } -void bench_field_inverse(void* arg) { +static void bench_group_add_var(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 20000; i++) { - secp256k1_fe_inv(&data->fe_x, &data->fe_x); - secp256k1_fe_add(&data->fe_x, &data->fe_y); + for (i = 0; i < iters; i++) { + secp256k1_gej_add_var(&data->gej[0], &data->gej[0], &data->gej[1], NULL); } } -void bench_field_inverse_var(void* arg) { +static void bench_group_add_affine(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 20000; i++) { - secp256k1_fe_inv_var(&data->fe_x, &data->fe_x); - secp256k1_fe_add(&data->fe_x, &data->fe_y); + for (i = 0; i < iters; i++) { + secp256k1_gej_add_ge(&data->gej[0], &data->gej[0], &data->ge[1]); } } -void bench_field_sqrt(void* arg) { +static void bench_group_add_affine_var(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 20000; i++) { - secp256k1_fe_sqrt(&data->fe_x, &data->fe_x); - secp256k1_fe_add(&data->fe_x, &data->fe_y); + for (i = 0; i < iters; i++) { + secp256k1_gej_add_ge_var(&data->gej[0], &data->gej[0], &data->ge[1], NULL); } } -void bench_group_double_var(void* arg) { +static void bench_group_add_zinv_var(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 200000; i++) { - secp256k1_gej_double_var(&data->gej_x, &data->gej_x, NULL); + for (i = 0; i < iters; i++) { + secp256k1_gej_add_zinv_var(&data->gej[0], &data->gej[0], &data->ge[1], &data->gej[0].y); } } -void bench_group_add_var(void* arg) { +static void bench_group_to_affine_var(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 200000; i++) { - secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y, NULL); + for (i = 0; i < iters; ++i) { + secp256k1_ge_set_gej_var(&data->ge[1], &data->gej[0]); + /* Use the output affine X/Y coordinates to vary the input X/Y/Z coordinates. + Note that the resulting coordinates will generally not correspond to a point + on the curve, but this is not a problem for the code being benchmarked here. + Adding and normalizing have less overhead than EC operations (which could + guarantee the point remains on the curve). */ + secp256k1_fe_add(&data->gej[0].x, &data->ge[1].y); + secp256k1_fe_add(&data->gej[0].y, &data->fe[2]); + secp256k1_fe_add(&data->gej[0].z, &data->ge[1].x); + secp256k1_fe_normalize_var(&data->gej[0].x); + secp256k1_fe_normalize_var(&data->gej[0].y); + secp256k1_fe_normalize_var(&data->gej[0].z); } } -void bench_group_add_affine(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; +static void bench_ecmult_wnaf(void* arg, int iters) { + int i, bits = 0, overflow = 0; + bench_inv *data = (bench_inv*)arg; - for (i = 0; i < 200000; i++) { - secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y); + for (i = 0; i < iters; i++) { + bits += secp256k1_ecmult_wnaf(data->wnaf, 256, &data->scalar[0], WINDOW_A); + overflow += secp256k1_scalar_add(&data->scalar[0], &data->scalar[0], &data->scalar[1]); } + CHECK(overflow >= 0); + CHECK(bits <= 256*iters); } -void bench_group_add_affine_var(void* arg) { +static void bench_sha256(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; + secp256k1_sha256 sha; - for (i = 0; i < 200000; i++) { - secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y, NULL); - } -} - -void bench_group_jacobi_var(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_gej_has_quad_y_var(&data->gej_x); - } -} - -void bench_ecmult_wnaf(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_ecmult_wnaf(data->wnaf, 256, &data->scalar_x, WINDOW_A); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} - -void bench_wnaf_const(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} - - -void bench_sha256(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; - secp256k1_sha256_t sha; - - for (i = 0; i < 20000; i++) { + for (i = 0; i < iters; i++) { secp256k1_sha256_initialize(&sha); secp256k1_sha256_write(&sha, data->data, 32); secp256k1_sha256_finalize(&sha, data->data); } } -void bench_hmac_sha256(void* arg) { +static void bench_hmac_sha256(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; - secp256k1_hmac_sha256_t hmac; + bench_inv *data = (bench_inv*)arg; + secp256k1_hmac_sha256 hmac; - for (i = 0; i < 20000; i++) { + for (i = 0; i < iters; i++) { secp256k1_hmac_sha256_initialize(&hmac, data->data, 32); secp256k1_hmac_sha256_write(&hmac, data->data, 32); secp256k1_hmac_sha256_finalize(&hmac, data->data); } } -void bench_rfc6979_hmac_sha256(void* arg) { +static void bench_rfc6979_hmac_sha256(void* arg, int iters) { int i; - bench_inv_t *data = (bench_inv_t*)arg; - secp256k1_rfc6979_hmac_sha256_t rng; + bench_inv *data = (bench_inv*)arg; + secp256k1_rfc6979_hmac_sha256 rng; - for (i = 0; i < 20000; i++) { + for (i = 0; i < iters; i++) { secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 64); secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32); } } -void bench_context_verify(void* arg) { +static void bench_context(void* arg, int iters) { int i; (void)arg; - for (i = 0; i < 20; i++) { - secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY)); + for (i = 0; i < iters; i++) { + secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_NONE)); } } -void bench_context_sign(void* arg) { - int i; - (void)arg; - for (i = 0; i < 200; i++) { - secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_SIGN)); - } -} - -#ifndef USE_NUM_NONE -void bench_num_jacobi(void* arg) { - int i; - bench_inv_t *data = (bench_inv_t*)arg; - secp256k1_num nx, norder; - - secp256k1_scalar_get_num(&nx, &data->scalar_x); - secp256k1_scalar_order_get_num(&norder); - secp256k1_scalar_get_num(&norder, &data->scalar_y); - - for (i = 0; i < 200000; i++) { - secp256k1_num_jacobi(&nx, &norder); - } -} -#endif - -int have_flag(int argc, char** argv, char *flag) { - char** argm = argv + argc; - argv++; - if (argv == argm) { - return 1; - } - while (argv != NULL && argv != argm) { - if (strcmp(*argv, flag) == 0) { - return 1; - } - argv++; - } - return 0; -} - int main(int argc, char **argv) { - bench_inv_t data; - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, 2000000); - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, 2000000); - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, 200000); -#ifdef USE_ENDOMORPHISM - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, 20000); -#endif - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000); - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, 2000); + bench_inv data; + int default_iters = 20000; + int iters = get_iters(default_iters); + int d = argc == 1; /* default */ - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, 2000000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, 2000000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, 20000); + if (argc > 1) { + if (have_flag(argc, argv, "-h") + || have_flag(argc, argv, "--help") + || have_flag(argc, argv, "help")) { + help(default_iters); + return EXIT_SUCCESS; + } + } - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, 20000); + print_output_table_header_row(); - if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000); + if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "half")) run_benchmark("scalar_half", bench_scalar_half, bench_setup, NULL, &data, 10, iters*100); + if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, iters*100); + if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, iters*100); + if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, iters*10); + if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, iters); - if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, 20000); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "half")) run_benchmark("field_half", bench_field_half, bench_setup, NULL, &data, 10, iters*100); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, iters*100); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, iters*100); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, iters*10); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, iters*10); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "issquare")) run_benchmark("field_is_square_var", bench_field_is_square_var, bench_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, iters); - if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 20); - if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 200); + if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, iters*10); + if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, iters*10); + if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, iters*10); + if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, iters*10); + if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_zinv_var", bench_group_add_zinv_var, bench_setup, NULL, &data, 10, iters*10); + if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "to_affine")) run_benchmark("group_to_affine_var", bench_group_to_affine_var, bench_setup, NULL, &data, 10, iters); -#ifndef USE_NUM_NONE - if (have_flag(argc, argv, "num") || have_flag(argc, argv, "jacobi")) run_benchmark("num_jacobi", bench_num_jacobi, bench_setup, NULL, &data, 10, 200000); -#endif - return 0; + if (d || have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, iters); + + if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, iters); + + if (d || have_flag(argc, argv, "context")) run_benchmark("context_create", bench_context, bench_setup, NULL, &data, 10, iters); + + return EXIT_SUCCESS; } diff --git a/crypto/secp256k1/libsecp256k1/src/bench_schnorr_verify.c b/crypto/secp256k1/libsecp256k1/src/bench_schnorr_verify.c deleted file mode 100644 index 5f137dda23..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/bench_schnorr_verify.c +++ /dev/null @@ -1,73 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include -#include - -#include "include/secp256k1.h" -#include "include/secp256k1_schnorr.h" -#include "util.h" -#include "bench.h" - -typedef struct { - unsigned char key[32]; - unsigned char sig[64]; - unsigned char pubkey[33]; - size_t pubkeylen; -} benchmark_schnorr_sig_t; - -typedef struct { - secp256k1_context *ctx; - unsigned char msg[32]; - benchmark_schnorr_sig_t sigs[64]; - int numsigs; -} benchmark_schnorr_verify_t; - -static void benchmark_schnorr_init(void* arg) { - int i, k; - benchmark_schnorr_verify_t* data = (benchmark_schnorr_verify_t*)arg; - - for (i = 0; i < 32; i++) { - data->msg[i] = 1 + i; - } - for (k = 0; k < data->numsigs; k++) { - secp256k1_pubkey pubkey; - for (i = 0; i < 32; i++) { - data->sigs[k].key[i] = 33 + i + k; - } - secp256k1_schnorr_sign(data->ctx, data->sigs[k].sig, data->msg, data->sigs[k].key, NULL, NULL); - data->sigs[k].pubkeylen = 33; - CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->sigs[k].key)); - CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED)); - } -} - -static void benchmark_schnorr_verify(void* arg) { - int i; - benchmark_schnorr_verify_t* data = (benchmark_schnorr_verify_t*)arg; - - for (i = 0; i < 20000 / data->numsigs; i++) { - secp256k1_pubkey pubkey; - data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF); - CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->sigs[0].pubkey, data->sigs[0].pubkeylen)); - CHECK(secp256k1_schnorr_verify(data->ctx, data->sigs[0].sig, data->msg, &pubkey) == ((i & 0xFF) == 0)); - data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF); - } -} - - - -int main(void) { - benchmark_schnorr_verify_t data; - - data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - data.numsigs = 1; - run_benchmark("schnorr_verify", benchmark_schnorr_verify, benchmark_schnorr_init, NULL, &data, 10, 20000); - - secp256k1_context_destroy(data.ctx); - return 0; -} diff --git a/crypto/secp256k1/libsecp256k1/src/bench_sign.c b/crypto/secp256k1/libsecp256k1/src/bench_sign.c deleted file mode 100644 index ed7224d757..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/bench_sign.c +++ /dev/null @@ -1,56 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include "include/secp256k1.h" -#include "util.h" -#include "bench.h" - -typedef struct { - secp256k1_context* ctx; - unsigned char msg[32]; - unsigned char key[32]; -} bench_sign_t; - -static void bench_sign_setup(void* arg) { - int i; - bench_sign_t *data = (bench_sign_t*)arg; - - for (i = 0; i < 32; i++) { - data->msg[i] = i + 1; - } - for (i = 0; i < 32; i++) { - data->key[i] = i + 65; - } -} - -static void bench_sign(void* arg) { - int i; - bench_sign_t *data = (bench_sign_t*)arg; - - unsigned char sig[74]; - for (i = 0; i < 20000; i++) { - size_t siglen = 74; - int j; - secp256k1_ecdsa_signature signature; - CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL)); - CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature)); - for (j = 0; j < 32; j++) { - data->msg[j] = sig[j]; - data->key[j] = sig[j + 32]; - } - } -} - -int main(void) { - bench_sign_t data; - - data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - - run_benchmark("ecdsa_sign", bench_sign, bench_sign_setup, NULL, &data, 10, 20000); - - secp256k1_context_destroy(data.ctx); - return 0; -} diff --git a/crypto/secp256k1/libsecp256k1/src/bench_verify.c b/crypto/secp256k1/libsecp256k1/src/bench_verify.c deleted file mode 100644 index 418defa0aa..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/bench_verify.c +++ /dev/null @@ -1,112 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include -#include - -#include "include/secp256k1.h" -#include "util.h" -#include "bench.h" - -#ifdef ENABLE_OPENSSL_TESTS -#include -#include -#include -#endif - -typedef struct { - secp256k1_context *ctx; - unsigned char msg[32]; - unsigned char key[32]; - unsigned char sig[72]; - size_t siglen; - unsigned char pubkey[33]; - size_t pubkeylen; -#ifdef ENABLE_OPENSSL_TESTS - EC_GROUP* ec_group; -#endif -} benchmark_verify_t; - -static void benchmark_verify(void* arg) { - int i; - benchmark_verify_t* data = (benchmark_verify_t*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_pubkey pubkey; - secp256k1_ecdsa_signature sig; - data->sig[data->siglen - 1] ^= (i & 0xFF); - data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); - data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1); - CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1); - CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0)); - data->sig[data->siglen - 1] ^= (i & 0xFF); - data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); - data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - } -} - -#ifdef ENABLE_OPENSSL_TESTS -static void benchmark_verify_openssl(void* arg) { - int i; - benchmark_verify_t* data = (benchmark_verify_t*)arg; - - for (i = 0; i < 20000; i++) { - data->sig[data->siglen - 1] ^= (i & 0xFF); - data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); - data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - { - EC_KEY *pkey = EC_KEY_new(); - const unsigned char *pubkey = &data->pubkey[0]; - int result; - - CHECK(pkey != NULL); - result = EC_KEY_set_group(pkey, data->ec_group); - CHECK(result); - result = (o2i_ECPublicKey(&pkey, &pubkey, data->pubkeylen)) != NULL; - CHECK(result); - result = ECDSA_verify(0, &data->msg[0], sizeof(data->msg), &data->sig[0], data->siglen, pkey) == (i == 0); - CHECK(result); - EC_KEY_free(pkey); - } - data->sig[data->siglen - 1] ^= (i & 0xFF); - data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); - data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - } -} -#endif - -int main(void) { - int i; - secp256k1_pubkey pubkey; - secp256k1_ecdsa_signature sig; - benchmark_verify_t data; - - data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - for (i = 0; i < 32; i++) { - data.msg[i] = 1 + i; - } - for (i = 0; i < 32; i++) { - data.key[i] = 33 + i; - } - data.siglen = 72; - CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL)); - CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig)); - CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key)); - data.pubkeylen = 33; - CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); - - run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); -#ifdef ENABLE_OPENSSL_TESTS - data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1); - run_benchmark("ecdsa_verify_openssl", benchmark_verify_openssl, NULL, NULL, &data, 10, 20000); - EC_GROUP_free(data.ec_group); -#endif - - secp256k1_context_destroy(data.ctx); - return 0; -} diff --git a/crypto/secp256k1/libsecp256k1/src/checkmem.h b/crypto/secp256k1/libsecp256k1/src/checkmem.h new file mode 100644 index 0000000000..7e333ce5f3 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/checkmem.h @@ -0,0 +1,102 @@ +/*********************************************************************** + * Copyright (c) 2022 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +/* The code here is inspired by Kris Kwiatkowski's approach in + * https://github.com/kriskwiatkowski/pqc/blob/main/src/common/ct_check.h + * to provide a general interface for memory-checking mechanisms, primarily + * for constant-time checking. + */ + +/* These macros are defined by this header file: + * + * - SECP256K1_CHECKMEM_ENABLED: + * - 1 if memory-checking integration is available, 0 otherwise. + * This is just a compile-time macro. Use the next macro to check it is actually + * available at runtime. + * - SECP256K1_CHECKMEM_RUNNING(): + * - Acts like a function call, returning 1 if memory checking is available + * at runtime. + * - SECP256K1_CHECKMEM_CHECK(p, len): + * - Assert or otherwise fail in case the len-byte memory block pointed to by p is + * not considered entirely defined. + * - SECP256K1_CHECKMEM_CHECK_VERIFY(p, len): + * - Like SECP256K1_CHECKMEM_CHECK, but only works in VERIFY mode. + * - SECP256K1_CHECKMEM_UNDEFINE(p, len): + * - marks the len-byte memory block pointed to by p as undefined data (secret data, + * in the context of constant-time checking). + * - SECP256K1_CHECKMEM_DEFINE(p, len): + * - marks the len-byte memory pointed to by p as defined data (public data, in the + * context of constant-time checking). + * - SECP256K1_CHECKMEM_MSAN_DEFINE(p, len): + * - Like SECP256K1_CHECKMEM_DEFINE, but applies only to memory_sanitizer. + * + */ + +#ifndef SECP256K1_CHECKMEM_H +#define SECP256K1_CHECKMEM_H + +/* Define a statement-like macro that ignores the arguments. */ +#define SECP256K1_CHECKMEM_NOOP(p, len) do { (void)(p); (void)(len); } while(0) + +/* If compiling under msan, map the SECP256K1_CHECKMEM_* functionality to msan. + * Choose this preferentially, even when VALGRIND is defined, as msan-compiled + * binaries can't be run under valgrind anyway. */ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# include +# define SECP256K1_CHECKMEM_ENABLED 1 +# define SECP256K1_CHECKMEM_UNDEFINE(p, len) __msan_allocated_memory((p), (len)) +# define SECP256K1_CHECKMEM_DEFINE(p, len) __msan_unpoison((p), (len)) +# define SECP256K1_CHECKMEM_MSAN_DEFINE(p, len) __msan_unpoison((p), (len)) +# define SECP256K1_CHECKMEM_CHECK(p, len) __msan_check_mem_is_initialized((p), (len)) +# define SECP256K1_CHECKMEM_RUNNING() (1) +# endif +#endif + +#if !defined SECP256K1_CHECKMEM_MSAN_DEFINE +# define SECP256K1_CHECKMEM_MSAN_DEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) +#endif + +/* If valgrind integration is desired (through the VALGRIND define), implement the + * SECP256K1_CHECKMEM_* macros using valgrind. */ +#if !defined SECP256K1_CHECKMEM_ENABLED +# if defined VALGRIND +# include +# if defined(__clang__) && defined(__APPLE__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wreserved-identifier" +# endif +# include +# if defined(__clang__) && defined(__APPLE__) +# pragma clang diagnostic pop +# endif +# define SECP256K1_CHECKMEM_ENABLED 1 +# define SECP256K1_CHECKMEM_UNDEFINE(p, len) VALGRIND_MAKE_MEM_UNDEFINED((p), (len)) +# define SECP256K1_CHECKMEM_DEFINE(p, len) VALGRIND_MAKE_MEM_DEFINED((p), (len)) +# define SECP256K1_CHECKMEM_CHECK(p, len) VALGRIND_CHECK_MEM_IS_DEFINED((p), (len)) + /* VALGRIND_MAKE_MEM_DEFINED returns 0 iff not running on memcheck. + * This is more precise than the RUNNING_ON_VALGRIND macro, which + * checks for valgrind in general instead of memcheck specifically. */ +# define SECP256K1_CHECKMEM_RUNNING() (VALGRIND_MAKE_MEM_DEFINED(NULL, 0) != 0) +# endif +#endif + +/* As a fall-back, map these macros to dummy statements. */ +#if !defined SECP256K1_CHECKMEM_ENABLED +# define SECP256K1_CHECKMEM_ENABLED 0 +# define SECP256K1_CHECKMEM_UNDEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) +# define SECP256K1_CHECKMEM_DEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) +# define SECP256K1_CHECKMEM_CHECK(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) +# define SECP256K1_CHECKMEM_RUNNING() (0) +#endif + +#if defined VERIFY +#define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_CHECK((p), (len)) +#else +#define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) +#endif + +#endif /* SECP256K1_CHECKMEM_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ctime_tests.c b/crypto/secp256k1/libsecp256k1/src/ctime_tests.c new file mode 100644 index 0000000000..f81bdb9228 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/ctime_tests.c @@ -0,0 +1,267 @@ +/*********************************************************************** + * Copyright (c) 2020 Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#include +#include +#include + +#include "../include/secp256k1.h" +#include "assumptions.h" +#include "checkmem.h" + +#if !SECP256K1_CHECKMEM_ENABLED +# error "This tool cannot be compiled without memory-checking interface (valgrind or msan)" +#endif + +#ifdef ENABLE_MODULE_ECDH +# include "../include/secp256k1_ecdh.h" +#endif + +#ifdef ENABLE_MODULE_RECOVERY +# include "../include/secp256k1_recovery.h" +#endif + +#ifdef ENABLE_MODULE_EXTRAKEYS +# include "../include/secp256k1_extrakeys.h" +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG +#include "../include/secp256k1_schnorrsig.h" +#endif + +#ifdef ENABLE_MODULE_MUSIG +#include "../include/secp256k1_musig.h" +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT +#include "../include/secp256k1_ellswift.h" +#endif + +static void run_tests(secp256k1_context *ctx, unsigned char *key); + +int main(void) { + secp256k1_context* ctx; + unsigned char key[32]; + int ret, i; + + if (!SECP256K1_CHECKMEM_RUNNING()) { + fprintf(stderr, "This test can only usefully be run inside valgrind because it was not compiled under msan.\n"); + fprintf(stderr, "Usage: libtool --mode=execute valgrind ./ctime_tests\n"); + return EXIT_FAILURE; + } + ctx = secp256k1_context_create(SECP256K1_CONTEXT_DECLASSIFY); + /** In theory, testing with a single secret input should be sufficient: + * If control flow depended on secrets the tool would generate an error. + */ + for (i = 0; i < 32; i++) { + key[i] = i + 65; + } + + run_tests(ctx, key); + + /* Test context randomisation. Do this last because it leaves the context + * tainted. */ + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_context_randomize(ctx, key); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret); + + secp256k1_context_destroy(ctx); + return EXIT_SUCCESS; +} + +static void run_tests(secp256k1_context *ctx, unsigned char *key) { + secp256k1_ecdsa_signature signature; + secp256k1_pubkey pubkey; + size_t siglen = 74; + size_t outputlen = 33; + int i; + int ret; + unsigned char msg[32]; + unsigned char sig[74]; + unsigned char spubkey[33]; +#ifdef ENABLE_MODULE_RECOVERY + secp256k1_ecdsa_recoverable_signature recoverable_signature; + int recid; +#endif +#ifdef ENABLE_MODULE_EXTRAKEYS + secp256k1_keypair keypair; +#endif +#ifdef ENABLE_MODULE_ELLSWIFT + unsigned char ellswift[64]; + static const unsigned char prefix[64] = {'t', 'e', 's', 't'}; +#endif + + for (i = 0; i < 32; i++) { + msg[i] = i + 1; + } + + /* Test keygen. */ + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_ec_pubkey_create(ctx, &pubkey, key); + SECP256K1_CHECKMEM_DEFINE(&pubkey, sizeof(secp256k1_pubkey)); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret); + CHECK(secp256k1_ec_pubkey_serialize(ctx, spubkey, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + + /* Test signing. */ + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_ecdsa_sign(ctx, &signature, msg, key, NULL, NULL); + SECP256K1_CHECKMEM_DEFINE(&signature, sizeof(secp256k1_ecdsa_signature)); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature)); + +#ifdef ENABLE_MODULE_ECDH + /* Test ECDH. */ + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); +#endif + +#ifdef ENABLE_MODULE_RECOVERY + /* Test signing a recoverable signature. */ + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL); + SECP256K1_CHECKMEM_DEFINE(&recoverable_signature, sizeof(recoverable_signature)); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &recoverable_signature)); + CHECK(recid >= 0 && recid <= 3); +#endif + + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_ec_seckey_verify(ctx, key); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_ec_seckey_negate(ctx, key); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + SECP256K1_CHECKMEM_UNDEFINE(msg, 32); + ret = secp256k1_ec_seckey_tweak_add(ctx, key, msg); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + SECP256K1_CHECKMEM_UNDEFINE(msg, 32); + ret = secp256k1_ec_seckey_tweak_mul(ctx, key, msg); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + /* Test keypair_create and keypair_xonly_tweak_add. */ +#ifdef ENABLE_MODULE_EXTRAKEYS + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_keypair_create(ctx, &keypair, key); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + /* The tweak is not treated as a secret in keypair_tweak_add */ + SECP256K1_CHECKMEM_DEFINE(msg, 32); + ret = secp256k1_keypair_xonly_tweak_add(ctx, &keypair, msg); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + SECP256K1_CHECKMEM_UNDEFINE(&keypair, sizeof(keypair)); + ret = secp256k1_keypair_sec(ctx, key, &keypair); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_keypair_create(ctx, &keypair, key); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + ret = secp256k1_schnorrsig_sign32(ctx, sig, msg, &keypair, NULL); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); +#endif + +#ifdef ENABLE_MODULE_MUSIG + { + secp256k1_pubkey pk; + const secp256k1_pubkey *pk_ptr[1]; + secp256k1_xonly_pubkey agg_pk; + unsigned char session_secrand[32]; + uint64_t nonrepeating_cnt = 0; + secp256k1_musig_secnonce secnonce; + secp256k1_musig_pubnonce pubnonce; + const secp256k1_musig_pubnonce *pubnonce_ptr[1]; + secp256k1_musig_aggnonce aggnonce; + secp256k1_musig_keyagg_cache cache; + secp256k1_musig_session session; + secp256k1_musig_partial_sig partial_sig; + unsigned char extra_input[32]; + + pk_ptr[0] = &pk; + pubnonce_ptr[0] = &pubnonce; + SECP256K1_CHECKMEM_DEFINE(key, 32); + memcpy(session_secrand, key, sizeof(session_secrand)); + session_secrand[0] = session_secrand[0] + 1; + memcpy(extra_input, key, sizeof(extra_input)); + extra_input[0] = extra_input[0] + 2; + + CHECK(secp256k1_keypair_create(ctx, &keypair, key)); + CHECK(secp256k1_keypair_pub(ctx, &pk, &keypair)); + CHECK(secp256k1_musig_pubkey_agg(ctx, &agg_pk, &cache, pk_ptr, 1)); + + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + SECP256K1_CHECKMEM_UNDEFINE(session_secrand, sizeof(session_secrand)); + SECP256K1_CHECKMEM_UNDEFINE(extra_input, sizeof(extra_input)); + ret = secp256k1_musig_nonce_gen(ctx, &secnonce, &pubnonce, session_secrand, key, &pk, msg, &cache, extra_input); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + ret = secp256k1_musig_nonce_gen_counter(ctx, &secnonce, &pubnonce, nonrepeating_cnt, &keypair, msg, &cache, extra_input); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + CHECK(secp256k1_musig_nonce_agg(ctx, &aggnonce, pubnonce_ptr, 1)); + /* Make sure that previous tests don't undefine msg. It's not used as a secret here. */ + SECP256K1_CHECKMEM_DEFINE(msg, sizeof(msg)); + CHECK(secp256k1_musig_nonce_process(ctx, &session, &aggnonce, msg, &cache) == 1); + + ret = secp256k1_keypair_create(ctx, &keypair, key); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + ret = secp256k1_musig_partial_sign(ctx, &partial_sig, &secnonce, &keypair, &cache, &session); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + } +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_ellswift_create(ctx, ellswift, key, NULL); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + ret = secp256k1_ellswift_create(ctx, ellswift, key, ellswift); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + for (i = 0; i < 2; i++) { + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift)); + ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_bip324, NULL); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + + SECP256K1_CHECKMEM_UNDEFINE(key, 32); + SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift)); + ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_prefix, (void *)prefix); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + } + +#endif +} diff --git a/crypto/secp256k1/libsecp256k1/src/ecdsa.h b/crypto/secp256k1/libsecp256k1/src/ecdsa.h index 54ae101b92..4441b08398 100644 --- a/crypto/secp256k1/libsecp256k1/src/ecdsa.h +++ b/crypto/secp256k1/libsecp256k1/src/ecdsa.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECDSA_ -#define _SECP256K1_ECDSA_ +#ifndef SECP256K1_ECDSA_H +#define SECP256K1_ECDSA_H #include @@ -15,7 +15,7 @@ static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); +static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); -#endif +#endif /* SECP256K1_ECDSA_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecdsa_impl.h b/crypto/secp256k1/libsecp256k1/src/ecdsa_impl.h index 453bb11880..ce36e85e6a 100644 --- a/crypto/secp256k1/libsecp256k1/src/ecdsa_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/ecdsa_impl.h @@ -1,12 +1,12 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECDSA_IMPL_H_ -#define _SECP256K1_ECDSA_IMPL_H_ +#ifndef SECP256K1_ECDSA_IMPL_H +#define SECP256K1_ECDSA_IMPL_H #include "scalar.h" #include "field.h" @@ -16,17 +16,8 @@ #include "ecdsa.h" /** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1 - * sage: for t in xrange(1023, -1, -1): - * .. p = 2**256 - 2**32 - t - * .. if p.is_prime(): - * .. print '%x'%p - * .. break - * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' - * sage: a = 0 - * sage: b = 7 - * sage: F = FiniteField (p) - * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) - * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' + * $ sage -c 'load("secp256k1_params.sage"); print(hex(N))' + * 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 */ static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, @@ -35,81 +26,81 @@ static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST /** Difference between field and order, values 'p' and 'n' values defined in * "Standards for Efficient Cryptography" (SEC2) 2.7.1. - * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F - * sage: a = 0 - * sage: b = 7 - * sage: F = FiniteField (p) - * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) - * '14551231950b75fc4402da1722fc9baee' + * $ sage -c 'load("secp256k1_params.sage"); print(hex(P-N))' + * 0x14551231950b75fc4402da1722fc9baee */ static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL ); -static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) { - int lenleft, b1; - size_t ret = 0; +static int secp256k1_der_read_len(size_t *len, const unsigned char **sigp, const unsigned char *sigend) { + size_t lenleft; + unsigned char b1; + VERIFY_CHECK(len != NULL); + *len = 0; if (*sigp >= sigend) { - return -1; + return 0; } b1 = *((*sigp)++); if (b1 == 0xFF) { /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ - return -1; + return 0; } if ((b1 & 0x80) == 0) { /* X.690-0207 8.1.3.4 short form length octets */ - return b1; + *len = b1; + return 1; } if (b1 == 0x80) { /* Indefinite length is not allowed in DER. */ - return -1; + return 0; } /* X.690-207 8.1.3.5 long form length octets */ - lenleft = b1 & 0x7F; - if (lenleft > sigend - *sigp) { - return -1; + lenleft = b1 & 0x7F; /* lenleft is at least 1 */ + if (lenleft > (size_t)(sigend - *sigp)) { + return 0; } if (**sigp == 0) { /* Not the shortest possible length encoding. */ - return -1; + return 0; } - if ((size_t)lenleft > sizeof(size_t)) { + if (lenleft > sizeof(size_t)) { /* The resulting length would exceed the range of a size_t, so - * certainly longer than the passed array size. - */ - return -1; + * it is certainly longer than the passed array size. */ + return 0; } while (lenleft > 0) { - if ((ret >> ((sizeof(size_t) - 1) * 8)) != 0) { - } - ret = (ret << 8) | **sigp; - if (ret + lenleft > (size_t)(sigend - *sigp)) { - /* Result exceeds the length of the passed array. */ - return -1; - } + *len = (*len << 8) | **sigp; (*sigp)++; lenleft--; } - if (ret < 128) { - /* Not the shortest possible length encoding. */ - return -1; + if (*len > (size_t)(sigend - *sigp)) { + /* Result exceeds the length of the passed array. + (Checking this is the responsibility of the caller but it + can't hurt do it here, too.) */ + return 0; } - return ret; + if (*len < 128) { + /* Not the shortest possible length encoding. */ + return 0; + } + return 1; } static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { int overflow = 0; unsigned char ra[32] = {0}; - int rlen; + size_t rlen; if (*sig == sigend || **sig != 0x02) { /* Not a primitive integer (X.690-0207 8.3.1). */ return 0; } (*sig)++; - rlen = secp256k1_der_read_len(sig, sigend); - if (rlen <= 0 || (*sig) + rlen > sigend) { + if (secp256k1_der_read_len(&rlen, sig, sigend) == 0) { + return 0; + } + if (rlen == 0 || rlen > (size_t)(sigend - *sig)) { /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ return 0; } @@ -125,8 +116,11 @@ static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char /* Negative. */ overflow = 1; } - while (rlen > 0 && **sig == 0) { - /* Skip leading zero bytes */ + /* There is at most one leading zero byte: + * if there were two leading zero bytes, we would have failed and returned 0 + * because of excessive 0x00 padding already. */ + if (rlen > 0 && **sig == 0) { + /* Skip leading zero byte */ rlen--; (*sig)++; } @@ -134,7 +128,7 @@ static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char overflow = 1; } if (!overflow) { - memcpy(ra + 32 - rlen, *sig, rlen); + if (rlen) memcpy(ra + 32 - rlen, *sig, rlen); secp256k1_scalar_set_b32(r, ra, &overflow); } if (overflow) { @@ -146,18 +140,16 @@ static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { const unsigned char *sigend = sig + size; - int rlen; + size_t rlen; if (sig == sigend || *(sig++) != 0x30) { /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ return 0; } - rlen = secp256k1_der_read_len(&sig, sigend); - if (rlen < 0 || sig + rlen > sigend) { - /* Tuple exceeds bounds */ + if (secp256k1_der_read_len(&rlen, &sig, sigend) == 0) { return 0; } - if (sig + rlen != sigend) { - /* Garbage after tuple. */ + if (rlen != (size_t)(sigend - sig)) { + /* Tuple exceeds bounds or garage after tuple. */ return 0; } @@ -200,7 +192,7 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const return 1; } -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { +static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { unsigned char c[32]; secp256k1_scalar sn, u1, u2; #if !defined(EXHAUSTIVE_TEST_ORDER) @@ -217,7 +209,7 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar_mul(&u1, &sn, message); secp256k1_scalar_mul(&u2, &sn, sigr); secp256k1_gej_set_ge(&pubkeyj, pubkey); - secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1); + secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); if (secp256k1_gej_is_infinity(&pr)) { return 0; } @@ -235,7 +227,8 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const } #else secp256k1_scalar_get_b32(c, sigr); - secp256k1_fe_set_b32(&xr, c); + /* we can ignore the fe_set_b32_limit return value, because we know the input is in range */ + (void)secp256k1_fe_set_b32_limit(&xr, c); /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) * in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), @@ -276,6 +269,7 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, sec secp256k1_ge r; secp256k1_scalar n; int overflow = 0; + int high; secp256k1_ecmult_gen(ctx, &rp, nonce); secp256k1_ge_set_gej(&r, &rp); @@ -283,15 +277,11 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, sec secp256k1_fe_normalize(&r.y); secp256k1_fe_get_b32(b, &r.x); secp256k1_scalar_set_b32(sigr, b, &overflow); - /* These two conditions should be checked before calling */ - VERIFY_CHECK(!secp256k1_scalar_is_zero(sigr)); - VERIFY_CHECK(overflow == 0); - if (recid) { /* The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log * of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria. */ - *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); + *recid = (overflow << 1) | secp256k1_fe_is_odd(&r.y); } secp256k1_scalar_mul(&n, sigr, seckey); secp256k1_scalar_add(&n, &n, message); @@ -300,16 +290,15 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, sec secp256k1_scalar_clear(&n); secp256k1_gej_clear(&rp); secp256k1_ge_clear(&r); - if (secp256k1_scalar_is_zero(sigs)) { - return 0; + high = secp256k1_scalar_is_high(sigs); + secp256k1_scalar_cond_negate(sigs, high); + if (recid) { + *recid ^= high; } - if (secp256k1_scalar_is_high(sigs)) { - secp256k1_scalar_negate(sigs, sigs); - if (recid) { - *recid ^= 1; - } - } - return 1; + /* P.x = order is on the curve, so technically sig->r could end up being zero, which would be an invalid signature. + * This is cryptographically unreachable as hitting it requires finding the discrete log of P.x = N. + */ + return (int)(!secp256k1_scalar_is_zero(sigr)) & (int)(!secp256k1_scalar_is_zero(sigs)); } -#endif +#endif /* SECP256K1_ECDSA_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/eckey.h b/crypto/secp256k1/libsecp256k1/src/eckey.h index 42739a3bea..d54d44c997 100644 --- a/crypto/secp256k1/libsecp256k1/src/eckey.h +++ b/crypto/secp256k1/libsecp256k1/src/eckey.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECKEY_ -#define _SECP256K1_ECKEY_ +#ifndef SECP256K1_ECKEY_H +#define SECP256K1_ECKEY_H #include @@ -18,8 +18,8 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak); static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge *key, const secp256k1_scalar *tweak); -#endif +#endif /* SECP256K1_ECKEY_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/eckey_impl.h b/crypto/secp256k1/libsecp256k1/src/eckey_impl.h index ce38071ac2..121966f8b5 100644 --- a/crypto/secp256k1/libsecp256k1/src/eckey_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/eckey_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECKEY_IMPL_H_ -#define _SECP256K1_ECKEY_IMPL_H_ +#ifndef SECP256K1_ECKEY_IMPL_H +#define SECP256K1_ECKEY_IMPL_H #include "eckey.h" @@ -15,16 +15,17 @@ #include "ecmult_gen.h" static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { - if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) { + if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { secp256k1_fe x; - return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03); - } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { + return secp256k1_fe_set_b32_limit(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); + } else if (size == 65 && (pub[0] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { secp256k1_fe x, y; - if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { + if (!secp256k1_fe_set_b32_limit(&x, pub+1) || !secp256k1_fe_set_b32_limit(&y, pub+33)) { return 0; } secp256k1_ge_set_xy(elem, &x, &y); - if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) { + if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && + secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { return 0; } return secp256k1_ge_is_valid_var(elem); @@ -42,10 +43,10 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *p secp256k1_fe_get_b32(&pub[1], &elem->x); if (compressed) { *size = 33; - pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00); + pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; } else { *size = 65; - pub[0] = 0x04; + pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; secp256k1_fe_get_b32(&pub[33], &elem->y); } return 1; @@ -53,18 +54,13 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *p static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { secp256k1_scalar_add(key, key, tweak); - if (secp256k1_scalar_is_zero(key)) { - return 0; - } - return 1; + return !secp256k1_scalar_is_zero(key); } -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { +static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak) { secp256k1_gej pt; - secp256k1_scalar one; secp256k1_gej_set_ge(&pt, key); - secp256k1_scalar_set_int(&one, 1); - secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); + secp256k1_ecmult(&pt, &pt, &secp256k1_scalar_one, tweak); if (secp256k1_gej_is_infinity(&pt)) { return 0; @@ -74,26 +70,23 @@ static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, } static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { - if (secp256k1_scalar_is_zero(tweak)) { - return 0; - } + int ret; + ret = !secp256k1_scalar_is_zero(tweak); secp256k1_scalar_mul(key, key, tweak); - return 1; + return ret; } -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { - secp256k1_scalar zero; +static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge *key, const secp256k1_scalar *tweak) { secp256k1_gej pt; if (secp256k1_scalar_is_zero(tweak)) { return 0; } - secp256k1_scalar_set_int(&zero, 0); secp256k1_gej_set_ge(&pt, key); - secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); + secp256k1_ecmult(&pt, &pt, tweak, &secp256k1_scalar_zero); secp256k1_ge_set_gej(key, &pt); return 1; } -#endif +#endif /* SECP256K1_ECKEY_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult.h b/crypto/secp256k1/libsecp256k1/src/ecmult.h index 20484134f5..326a5eeb43 100644 --- a/crypto/secp256k1/libsecp256k1/src/ecmult.h +++ b/crypto/secp256k1/libsecp256k1/src/ecmult.h @@ -1,31 +1,61 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECMULT_ -#define _SECP256K1_ECMULT_ +#ifndef SECP256K1_ECMULT_H +#define SECP256K1_ECMULT_H -#include "num.h" #include "group.h" +#include "scalar.h" +#include "scratch.h" -typedef struct { - /* For accelerating the computation of a*P + b*G: */ - secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ -#ifdef USE_ENDOMORPHISM - secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ +#ifndef ECMULT_WINDOW_SIZE +# define ECMULT_WINDOW_SIZE 15 +# ifdef DEBUG_CONFIG +# pragma message DEBUG_CONFIG_MSG("ECMULT_WINDOW_SIZE undefined, assuming default value") +# endif #endif -} secp256k1_ecmult_context; -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, - const secp256k1_ecmult_context *src, const secp256k1_callback *cb); -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); +#ifdef DEBUG_CONFIG +# pragma message DEBUG_CONFIG_DEF(ECMULT_WINDOW_SIZE) +#endif + +/* No one will ever need more than a window size of 24. The code might + * be correct for larger values of ECMULT_WINDOW_SIZE but this is not + * tested. + * + * The following limitations are known, and there are probably more: + * If WINDOW_G > 27 and size_t has 32 bits, then the code is incorrect + * because the size of the memory object that we allocate (in bytes) + * will not fit in a size_t. + * If WINDOW_G > 31 and int has 32 bits, then the code is incorrect + * because certain expressions will overflow. + */ +#if ECMULT_WINDOW_SIZE < 2 || ECMULT_WINDOW_SIZE > 24 +# error Set ECMULT_WINDOW_SIZE to an integer in range [2..24]. +#endif + +/** The number of entries a table with precomputed multiples needs to have. */ +#define ECMULT_TABLE_SIZE(w) (1L << ((w)-2)) /** Double multiply: R = na*A + ng*G */ -static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); +static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); -#endif +typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data); + +/** + * Multi-multiply: R = inp_g_sc * G + sum_i ni * Ai. + * Chooses the right algorithm for a given number of points and scratch space + * size. Resets and overwrites the given scratch space. If the points do not + * fit in the scratch space the algorithm is repeatedly run with batches of + * points. If no scratch space is given then a simple algorithm is used that + * simply multiplies the points with the corresponding scalars and adds them up. + * Returns: 1 on success (including when inp_g_sc is NULL and n is 0) + * 0 if there is not enough scratch space for a single point or + * callback returns 0 + */ +static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); + +#endif /* SECP256K1_ECMULT_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_compute_table.h b/crypto/secp256k1/libsecp256k1/src/ecmult_compute_table.h new file mode 100644 index 0000000000..665f87ff3d --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_compute_table.h @@ -0,0 +1,16 @@ +/***************************************************************************************************** + * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *****************************************************************************************************/ + +#ifndef SECP256K1_ECMULT_COMPUTE_TABLE_H +#define SECP256K1_ECMULT_COMPUTE_TABLE_H + +/* Construct table of all odd multiples of gen in range 1..(2**(window_g-1)-1). */ +static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen); + +/* Like secp256k1_ecmult_compute_table, but one for both gen and gen*2^128. */ +static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage* table, secp256k1_ge_storage* table_128, int window_g, const secp256k1_ge* gen); + +#endif /* SECP256K1_ECMULT_COMPUTE_TABLE_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_compute_table_impl.h b/crypto/secp256k1/libsecp256k1/src/ecmult_compute_table_impl.h new file mode 100644 index 0000000000..69d59ce595 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_compute_table_impl.h @@ -0,0 +1,49 @@ +/***************************************************************************************************** + * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *****************************************************************************************************/ + +#ifndef SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H +#define SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H + +#include "ecmult_compute_table.h" +#include "group_impl.h" +#include "field_impl.h" +#include "ecmult.h" +#include "util.h" + +static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen) { + secp256k1_gej gj; + secp256k1_ge ge, dgen; + int j; + + gj = *gen; + secp256k1_ge_set_gej_var(&ge, &gj); + secp256k1_ge_to_storage(&table[0], &ge); + + secp256k1_gej_double_var(&gj, gen, NULL); + secp256k1_ge_set_gej_var(&dgen, &gj); + + for (j = 1; j < ECMULT_TABLE_SIZE(window_g); ++j) { + secp256k1_gej_set_ge(&gj, &ge); + secp256k1_gej_add_ge_var(&gj, &gj, &dgen, NULL); + secp256k1_ge_set_gej_var(&ge, &gj); + secp256k1_ge_to_storage(&table[j], &ge); + } +} + +/* Like secp256k1_ecmult_compute_table, but one for both gen and gen*2^128. */ +static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage* table, secp256k1_ge_storage* table_128, int window_g, const secp256k1_ge* gen) { + secp256k1_gej gj; + int i; + + secp256k1_gej_set_ge(&gj, gen); + secp256k1_ecmult_compute_table(table, window_g, &gj); + for (i = 0; i < 128; ++i) { + secp256k1_gej_double_var(&gj, &gj, NULL); + } + secp256k1_ecmult_compute_table(table_128, window_g, &gj); +} + +#endif /* SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_const.h b/crypto/secp256k1/libsecp256k1/src/ecmult_const.h index 2b0097655c..080e04bc88 100644 --- a/crypto/secp256k1/libsecp256k1/src/ecmult_const.h +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_const.h @@ -1,15 +1,38 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECMULT_CONST_ -#define _SECP256K1_ECMULT_CONST_ +#ifndef SECP256K1_ECMULT_CONST_H +#define SECP256K1_ECMULT_CONST_H #include "scalar.h" #include "group.h" +/** + * Multiply: R = q*A (in constant-time for q) + */ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q); -#endif +/** + * Same as secp256k1_ecmult_const, but takes in an x coordinate of the base point + * only, specified as fraction n/d (numerator/denominator). Only the x coordinate of the result is + * returned. + * + * If known_on_curve is 0, a verification is performed that n/d is a valid X + * coordinate, and 0 is returned if not. Otherwise, 1 is returned. + * + * d being NULL is interpreted as d=1. If non-NULL, d must not be zero. q must not be zero. + * + * Constant time in the value of q, but not any other inputs. + */ +static int secp256k1_ecmult_const_xonly( + secp256k1_fe *r, + const secp256k1_fe *n, + const secp256k1_fe *d, + const secp256k1_scalar *q, + int known_on_curve +); + +#endif /* SECP256K1_ECMULT_CONST_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_const_impl.h b/crypto/secp256k1/libsecp256k1/src/ecmult_const_impl.h index 0db314c48e..0d78f7c3ce 100644 --- a/crypto/secp256k1/libsecp256k1/src/ecmult_const_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_const_impl.h @@ -1,239 +1,399 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015, 2022 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECMULT_CONST_IMPL_ -#define _SECP256K1_ECMULT_CONST_IMPL_ +#ifndef SECP256K1_ECMULT_CONST_IMPL_H +#define SECP256K1_ECMULT_CONST_IMPL_H #include "scalar.h" #include "group.h" #include "ecmult_const.h" #include "ecmult_impl.h" -#ifdef USE_ENDOMORPHISM - #define WNAF_BITS 128 +#if defined(EXHAUSTIVE_TEST_ORDER) +/* We need 2^ECMULT_CONST_GROUP_SIZE - 1 to be less than EXHAUSTIVE_TEST_ORDER, because + * the tables cannot have infinities in them (this breaks the effective-affine technique's + * z-ratio tracking) */ +# if EXHAUSTIVE_TEST_ORDER == 199 +# define ECMULT_CONST_GROUP_SIZE 4 +# elif EXHAUSTIVE_TEST_ORDER == 13 +# define ECMULT_CONST_GROUP_SIZE 3 +# elif EXHAUSTIVE_TEST_ORDER == 7 +# define ECMULT_CONST_GROUP_SIZE 2 +# else +# error "Unknown EXHAUSTIVE_TEST_ORDER" +# endif #else - #define WNAF_BITS 256 +/* Group size 4 or 5 appears optimal. */ +# define ECMULT_CONST_GROUP_SIZE 5 #endif -#define WNAF_SIZE(w) ((WNAF_BITS + (w) - 1) / (w)) -/* This is like `ECMULT_TABLE_GET_GE` but is constant time */ -#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \ - int m; \ - int abs_n = (n) * (((n) > 0) * 2 - 1); \ - int idx_n = abs_n / 2; \ +#define ECMULT_CONST_TABLE_SIZE (1L << (ECMULT_CONST_GROUP_SIZE - 1)) +#define ECMULT_CONST_GROUPS ((129 + ECMULT_CONST_GROUP_SIZE - 1) / ECMULT_CONST_GROUP_SIZE) +#define ECMULT_CONST_BITS (ECMULT_CONST_GROUPS * ECMULT_CONST_GROUP_SIZE) + +/** Fill a table 'pre' with precomputed odd multiples of a. + * + * The resulting point set is brought to a single constant Z denominator, stores the X and Y + * coordinates as ge points in pre, and stores the global Z in globalz. + * + * 'pre' must be an array of size ECMULT_CONST_TABLE_SIZE. + */ +static void secp256k1_ecmult_const_odd_multiples_table_globalz(secp256k1_ge *pre, secp256k1_fe *globalz, const secp256k1_gej *a) { + secp256k1_fe zr[ECMULT_CONST_TABLE_SIZE]; + + secp256k1_ecmult_odd_multiples_table(ECMULT_CONST_TABLE_SIZE, pre, zr, globalz, a); + secp256k1_ge_table_set_globalz(ECMULT_CONST_TABLE_SIZE, pre, zr); +} + +/* Given a table 'pre' with odd multiples of a point, put in r the signed-bit multiplication of n with that point. + * + * For example, if ECMULT_CONST_GROUP_SIZE is 4, then pre is expected to contain 8 entries: + * [1*P, 3*P, 5*P, 7*P, 9*P, 11*P, 13*P, 15*P]. n is then expected to be a 4-bit integer (range 0-15), and its + * bits are interpreted as signs of powers of two to look up. + * + * For example, if n=4, which is 0100 in binary, which is interpreted as [- + - -], so the looked up value is + * [ -(2^3) + (2^2) - (2^1) - (2^0) ]*P = -7*P. Every valid n translates to an odd number in range [-15,15], + * which means we just need to look up one of the precomputed values, and optionally negate it. + */ +#define ECMULT_CONST_TABLE_GET_GE(r,pre,n) do { \ + unsigned int m = 0; \ + /* If the top bit of n is 0, we want the negation. */ \ + volatile unsigned int negative = ((n) >> (ECMULT_CONST_GROUP_SIZE - 1)) ^ 1; \ + /* Let n[i] be the i-th bit of n, then the index is + * sum(cnot(n[i]) * 2^i, i=0..l-2) + * where cnot(b) = b if n[l-1] = 1 and 1 - b otherwise. + * For example, if n = 4, in binary 0100, the index is 3, in binary 011. + * + * Proof: + * Let + * x = sum((2*n[i] - 1)*2^i, i=0..l-1) + * = 2*sum(n[i] * 2^i, i=0..l-1) - 2^l + 1 + * be the value represented by n. + * The index is (x - 1)/2 if x > 0 and -(x + 1)/2 otherwise. + * Case x > 0: + * n[l-1] = 1 + * index = sum(n[i] * 2^i, i=0..l-1) - 2^(l-1) + * = sum(n[i] * 2^i, i=0..l-2) + * Case x <= 0: + * n[l-1] = 0 + * index = -(2*sum(n[i] * 2^i, i=0..l-1) - 2^l + 2)/2 + * = 2^(l-1) - 1 - sum(n[i] * 2^i, i=0..l-1) + * = sum((1 - n[i]) * 2^i, i=0..l-2) + */ \ + unsigned int index = ((unsigned int)(-negative) ^ n) & ((1U << (ECMULT_CONST_GROUP_SIZE - 1)) - 1U); \ secp256k1_fe neg_y; \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - VERIFY_SETUP(secp256k1_fe_clear(&(r)->x)); \ - VERIFY_SETUP(secp256k1_fe_clear(&(r)->y)); \ - for (m = 0; m < ECMULT_TABLE_SIZE(w); m++) { \ + VERIFY_CHECK((n) < (1U << ECMULT_CONST_GROUP_SIZE)); \ + VERIFY_CHECK(index < (1U << (ECMULT_CONST_GROUP_SIZE - 1))); \ + /* Unconditionally set r->x = (pre)[m].x. r->y = (pre)[m].y. because it's either the correct one + * or will get replaced in the later iterations, this is needed to make sure `r` is initialized. */ \ + (r)->x = (pre)[m].x; \ + (r)->y = (pre)[m].y; \ + for (m = 1; m < ECMULT_CONST_TABLE_SIZE; m++) { \ /* This loop is used to avoid secret data in array indices. See * the comment in ecmult_gen_impl.h for rationale. */ \ - secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == idx_n); \ - secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == idx_n); \ + secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == index); \ + secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == index); \ } \ (r)->infinity = 0; \ secp256k1_fe_negate(&neg_y, &(r)->y, 1); \ - secp256k1_fe_cmov(&(r)->y, &neg_y, (n) != abs_n); \ + secp256k1_fe_cmov(&(r)->y, &neg_y, negative); \ } while(0) - -/** Convert a number to WNAF notation. The number becomes represented by sum(2^{wi} * wnaf[i], i=0..return_val) - * with the following guarantees: - * - each wnaf[i] an odd integer between -(1 << w) and (1 << w) - * - each wnaf[i] is nonzero - * - the number of words set is returned; this is always (WNAF_BITS + w - 1) / w - * - * Adapted from `The Width-w NAF Method Provides Small Memory and Fast Elliptic Scalar - * Multiplications Secure against Side Channel Attacks`, Okeya and Tagaki. M. Joye (Ed.) - * CT-RSA 2003, LNCS 2612, pp. 328-443, 2003. Springer-Verlagy Berlin Heidelberg 2003 - * - * Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335 - */ -static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { - int global_sign; - int skew = 0; - int word = 0; - - /* 1 2 3 */ - int u_last; - int u; - - int flip; - int bit; - secp256k1_scalar neg_s; - int not_neg_one; - /* Note that we cannot handle even numbers by negating them to be odd, as is - * done in other implementations, since if our scalars were specified to have - * width < 256 for performance reasons, their negations would have width 256 - * and we'd lose any performance benefit. Instead, we use a technique from - * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) - * or 2 (for odd) to the number we are encoding, returning a skew value indicating - * this, and having the caller compensate after doing the multiplication. */ - - /* Negative numbers will be negated to keep their bit representation below the maximum width */ - flip = secp256k1_scalar_is_high(&s); - /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ - bit = flip ^ !secp256k1_scalar_is_even(&s); - /* We check for negative one, since adding 2 to it will cause an overflow */ - secp256k1_scalar_negate(&neg_s, &s); - not_neg_one = !secp256k1_scalar_is_one(&neg_s); - secp256k1_scalar_cadd_bit(&s, bit, not_neg_one); - /* If we had negative one, flip == 1, s.d[0] == 0, bit == 1, so caller expects - * that we added two to it and flipped it. In fact for -1 these operations are - * identical. We only flipped, but since skewing is required (in the sense that - * the skew must be 1 or 2, never zero) and flipping is not, we need to change - * our flags to claim that we only skewed. */ - global_sign = secp256k1_scalar_cond_negate(&s, flip); - global_sign *= not_neg_one * 2 - 1; - skew = 1 << bit; - - /* 4 */ - u_last = secp256k1_scalar_shr_int(&s, w); - while (word * w < WNAF_BITS) { - int sign; - int even; - - /* 4.1 4.4 */ - u = secp256k1_scalar_shr_int(&s, w); - /* 4.2 */ - even = ((u & 1) == 0); - sign = 2 * (u_last > 0) - 1; - u += sign * even; - u_last -= sign * even * (1 << w); - - /* 4.3, adapted for global sign change */ - wnaf[word++] = u_last * global_sign; - - u_last = u; - } - wnaf[word] = u * global_sign; - - VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); - VERIFY_CHECK(word == WNAF_SIZE(w)); - return skew; -} - - -static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar) { - secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_ge tmpa; - secp256k1_fe Z; - - int skew_1; - int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; -#ifdef USE_ENDOMORPHISM - secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; - int skew_lam; - secp256k1_scalar q_1, q_lam; -#endif - - int i; - secp256k1_scalar sc = *scalar; - - /* build wnaf representation for q. */ -#ifdef USE_ENDOMORPHISM - /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ - secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); - skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1); - skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1); +/* For K as defined in the comment of secp256k1_ecmult_const, we have several precomputed + * formulas/constants. + * - in exhaustive test mode, we give an explicit expression to compute it at compile time: */ +#ifdef EXHAUSTIVE_TEST_ORDER +static const secp256k1_scalar secp256k1_ecmult_const_K = ((SECP256K1_SCALAR_CONST(0, 0, 0, (1U << (ECMULT_CONST_BITS - 128)) - 2U, 0, 0, 0, 0) + EXHAUSTIVE_TEST_ORDER - 1U) * (1U + EXHAUSTIVE_TEST_LAMBDA)) % EXHAUSTIVE_TEST_ORDER; +/* - for the real secp256k1 group we have constants for various ECMULT_CONST_BITS values. */ +#elif ECMULT_CONST_BITS == 129 +/* For GROUP_SIZE = 1,3. */ +static const secp256k1_scalar secp256k1_ecmult_const_K = SECP256K1_SCALAR_CONST(0xac9c52b3ul, 0x3fa3cf1ful, 0x5ad9e3fdul, 0x77ed9ba4ul, 0xa880b9fcul, 0x8ec739c2ul, 0xe0cfc810ul, 0xb51283ceul); +#elif ECMULT_CONST_BITS == 130 +/* For GROUP_SIZE = 2,5. */ +static const secp256k1_scalar secp256k1_ecmult_const_K = SECP256K1_SCALAR_CONST(0xa4e88a7dul, 0xcb13034eul, 0xc2bdd6bful, 0x7c118d6bul, 0x589ae848ul, 0x26ba29e4ul, 0xb5c2c1dcul, 0xde9798d9ul); +#elif ECMULT_CONST_BITS == 132 +/* For GROUP_SIZE = 4,6 */ +static const secp256k1_scalar secp256k1_ecmult_const_K = SECP256K1_SCALAR_CONST(0x76b1d93dul, 0x0fae3c6bul, 0x3215874bul, 0x94e93813ul, 0x7937fe0dul, 0xb66bcaaful, 0xb3749ca5ul, 0xd7b6171bul); #else - skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1); +# error "Unknown ECMULT_CONST_BITS" #endif - /* Calculate odd multiples of a. +static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q) { + /* The approach below combines the signed-digit logic from Mike Hamburg's + * "Fast and compact elliptic-curve cryptography" (https://eprint.iacr.org/2012/309) + * Section 3.3, with the GLV endomorphism. + * + * The idea there is to interpret the bits of a scalar as signs (1 = +, 0 = -), and compute a + * point multiplication in that fashion. Let v be an n-bit non-negative integer (0 <= v < 2^n), + * and v[i] its i'th bit (so v = sum(v[i] * 2^i, i=0..n-1)). Then define: + * + * C_l(v, A) = sum((2*v[i] - 1) * 2^i*A, i=0..l-1) + * + * Then it holds that C_l(v, A) = sum((2*v[i] - 1) * 2^i*A, i=0..l-1) + * = (2*sum(v[i] * 2^i, i=0..l-1) + 1 - 2^l) * A + * = (2*v + 1 - 2^l) * A + * + * Thus, one can compute q*A as C_256((q + 2^256 - 1) / 2, A). This is the basis for the + * paper's signed-digit multi-comb algorithm for multiplication using a precomputed table. + * + * It is appealing to try to combine this with the GLV optimization: the idea that a scalar + * s can be written as s1 + lambda*s2, where lambda is a curve-specific constant such that + * lambda*A is easy to compute, and where s1 and s2 are small. In particular we have the + * secp256k1_scalar_split_lambda function which performs such a split with the resulting s1 + * and s2 in range (-2^128, 2^128) mod n. This does work, but is uninteresting: + * + * To compute q*A: + * - Let s1, s2 = split_lambda(q) + * - Let R1 = C_256((s1 + 2^256 - 1) / 2, A) + * - Let R2 = C_256((s2 + 2^256 - 1) / 2, lambda*A) + * - Return R1 + R2 + * + * The issue is that while s1 and s2 are small-range numbers, (s1 + 2^256 - 1) / 2 (mod n) + * and (s2 + 2^256 - 1) / 2 (mod n) are not, undoing the benefit of the splitting. + * + * To make it work, we want to modify the input scalar q first, before splitting, and then only + * add a 2^128 offset of the split results (so that they end up in the single 129-bit range + * [0,2^129]). A slightly smaller offset would work due to the bounds on the split, but we pick + * 2^128 for simplicity. Let s be the scalar fed to split_lambda, and f(q) the function to + * compute it from q: + * + * To compute q*A: + * - Compute s = f(q) + * - Let s1, s2 = split_lambda(s) + * - Let v1 = s1 + 2^128 (mod n) + * - Let v2 = s2 + 2^128 (mod n) + * - Let R1 = C_l(v1, A) + * - Let R2 = C_l(v2, lambda*A) + * - Return R1 + R2 + * + * l will thus need to be at least 129, but we may overshoot by a few bits (see + * further), so keep it as a variable. + * + * To solve for s, we reason: + * q*A = R1 + R2 + * <=> q*A = C_l(s1 + 2^128, A) + C_l(s2 + 2^128, lambda*A) + * <=> q*A = (2*(s1 + 2^128) + 1 - 2^l) * A + (2*(s2 + 2^128) + 1 - 2^l) * lambda*A + * <=> q*A = (2*(s1 + s2*lambda) + (2^129 + 1 - 2^l) * (1 + lambda)) * A + * <=> q = 2*(s1 + s2*lambda) + (2^129 + 1 - 2^l) * (1 + lambda) (mod n) + * <=> q = 2*s + (2^129 + 1 - 2^l) * (1 + lambda) (mod n) + * <=> s = (q + (2^l - 2^129 - 1) * (1 + lambda)) / 2 (mod n) + * <=> f(q) = (q + K) / 2 (mod n) + * where K = (2^l - 2^129 - 1)*(1 + lambda) (mod n) + * + * We will process the computation of C_l(v1, A) and C_l(v2, lambda*A) in groups of + * ECMULT_CONST_GROUP_SIZE, so we set l to the smallest multiple of ECMULT_CONST_GROUP_SIZE + * that is not less than 129; this equals ECMULT_CONST_BITS. + */ + + /* The offset to add to s1 and s2 to make them non-negative. Equal to 2^128. */ + static const secp256k1_scalar S_OFFSET = SECP256K1_SCALAR_CONST(0, 0, 0, 1, 0, 0, 0, 0); + secp256k1_scalar s, v1, v2; + secp256k1_ge pre_a[ECMULT_CONST_TABLE_SIZE]; + secp256k1_ge pre_a_lam[ECMULT_CONST_TABLE_SIZE]; + secp256k1_fe global_z; + int group, i; + + /* We're allowed to be non-constant time in the point, and the code below (in particular, + * secp256k1_ecmult_const_odd_multiples_table_globalz) cannot deal with infinity in a + * constant-time manner anyway. */ + if (secp256k1_ge_is_infinity(a)) { + secp256k1_gej_set_infinity(r); + return; + } + + /* Compute v1 and v2. */ + secp256k1_scalar_add(&s, q, &secp256k1_ecmult_const_K); + secp256k1_scalar_half(&s, &s); + secp256k1_scalar_split_lambda(&v1, &v2, &s); + secp256k1_scalar_add(&v1, &v1, &S_OFFSET); + secp256k1_scalar_add(&v2, &v2, &S_OFFSET); + +#ifdef VERIFY + /* Verify that v1 and v2 are in range [0, 2^129-1]. */ + for (i = 129; i < 256; ++i) { + VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&v1, i, 1) == 0); + VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&v2, i, 1) == 0); + } +#endif + + /* Calculate odd multiples of A and A*lambda. * All multiples are brought to the same Z 'denominator', which is stored - * in Z. Due to secp256k1' isomorphism we can do all operations pretending + * in global_z. Due to secp256k1' isomorphism we can do all operations pretending * that the Z coordinate was 1, use affine addition formulae, and correct * the Z coordinate of the result once at the end. */ secp256k1_gej_set_ge(r, a); - secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, r); - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_fe_normalize_weak(&pre_a[i].y); - } -#ifdef USE_ENDOMORPHISM - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_ecmult_const_odd_multiples_table_globalz(pre_a, &global_z, r); + for (i = 0; i < ECMULT_CONST_TABLE_SIZE; i++) { secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); } -#endif - /* first loop iteration (separated out so we can directly set r, rather - * than having it start at infinity, get doubled several times, then have - * its new value added to it) */ - i = wnaf_1[WNAF_SIZE(WINDOW_A - 1)]; - VERIFY_CHECK(i != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); - secp256k1_gej_set_ge(r, &tmpa); -#ifdef USE_ENDOMORPHISM - i = wnaf_lam[WNAF_SIZE(WINDOW_A - 1)]; - VERIFY_CHECK(i != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); - secp256k1_gej_add_ge(r, r, &tmpa); -#endif - /* remaining loop iterations */ - for (i = WNAF_SIZE(WINDOW_A - 1) - 1; i >= 0; i--) { - int n; + /* Next, we compute r = C_l(v1, A) + C_l(v2, lambda*A). + * + * We proceed in groups of ECMULT_CONST_GROUP_SIZE bits, operating on that many bits + * at a time, from high in v1, v2 to low. Call these bits1 (from v1) and bits2 (from v2). + * + * Now note that ECMULT_CONST_TABLE_GET_GE(&t, pre_a, bits1) loads into t a point equal + * to C_{ECMULT_CONST_GROUP_SIZE}(bits1, A), and analogously for pre_lam_a / bits2. + * This means that all we need to do is add these looked up values together, multiplied + * by 2^(ECMULT_GROUP_SIZE * group). + */ + for (group = ECMULT_CONST_GROUPS - 1; group >= 0; --group) { + /* Using the _var get_bits function is ok here, since it's only variable in offset and count, not in the scalar. */ + unsigned int bits1 = secp256k1_scalar_get_bits_var(&v1, group * ECMULT_CONST_GROUP_SIZE, ECMULT_CONST_GROUP_SIZE); + unsigned int bits2 = secp256k1_scalar_get_bits_var(&v2, group * ECMULT_CONST_GROUP_SIZE, ECMULT_CONST_GROUP_SIZE); + secp256k1_ge t; int j; - for (j = 0; j < WINDOW_A - 1; ++j) { - secp256k1_gej_double_nonzero(r, r, NULL); + + ECMULT_CONST_TABLE_GET_GE(&t, pre_a, bits1); + if (group == ECMULT_CONST_GROUPS - 1) { + /* Directly set r in the first iteration. */ + secp256k1_gej_set_ge(r, &t); + } else { + /* Shift the result so far up. */ + for (j = 0; j < ECMULT_CONST_GROUP_SIZE; ++j) { + secp256k1_gej_double(r, r); + } + secp256k1_gej_add_ge(r, r, &t); } - - n = wnaf_1[i]; - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - VERIFY_CHECK(n != 0); - secp256k1_gej_add_ge(r, r, &tmpa); -#ifdef USE_ENDOMORPHISM - n = wnaf_lam[i]; - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); - VERIFY_CHECK(n != 0); - secp256k1_gej_add_ge(r, r, &tmpa); -#endif + ECMULT_CONST_TABLE_GET_GE(&t, pre_a_lam, bits2); + secp256k1_gej_add_ge(r, r, &t); } - secp256k1_fe_mul(&r->z, &r->z, &Z); - - { - /* Correct for wNAF skew */ - secp256k1_ge correction = *a; - secp256k1_ge_storage correction_1_stor; -#ifdef USE_ENDOMORPHISM - secp256k1_ge_storage correction_lam_stor; -#endif - secp256k1_ge_storage a2_stor; - secp256k1_gej tmpj; - secp256k1_gej_set_ge(&tmpj, &correction); - secp256k1_gej_double_var(&tmpj, &tmpj, NULL); - secp256k1_ge_set_gej(&correction, &tmpj); - secp256k1_ge_to_storage(&correction_1_stor, a); -#ifdef USE_ENDOMORPHISM - secp256k1_ge_to_storage(&correction_lam_stor, a); -#endif - secp256k1_ge_to_storage(&a2_stor, &correction); - - /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ - secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); -#ifdef USE_ENDOMORPHISM - secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); -#endif - - /* Apply the correction */ - secp256k1_ge_from_storage(&correction, &correction_1_stor); - secp256k1_ge_neg(&correction, &correction); - secp256k1_gej_add_ge(r, r, &correction); - -#ifdef USE_ENDOMORPHISM - secp256k1_ge_from_storage(&correction, &correction_lam_stor); - secp256k1_ge_neg(&correction, &correction); - secp256k1_ge_mul_lambda(&correction, &correction); - secp256k1_gej_add_ge(r, r, &correction); -#endif - } + /* Map the result back to the secp256k1 curve from the isomorphic curve. */ + secp256k1_fe_mul(&r->z, &r->z, &global_z); } -#endif +static int secp256k1_ecmult_const_xonly(secp256k1_fe* r, const secp256k1_fe *n, const secp256k1_fe *d, const secp256k1_scalar *q, int known_on_curve) { + + /* This algorithm is a generalization of Peter Dettman's technique for + * avoiding the square root in a random-basepoint x-only multiplication + * on a Weierstrass curve: + * https://mailarchive.ietf.org/arch/msg/cfrg/7DyYY6gg32wDgHAhgSb6XxMDlJA/ + * + * + * === Background: the effective affine technique === + * + * Let phi_u be the isomorphism that maps (x, y) on secp256k1 curve y^2 = x^3 + 7 to + * x' = u^2*x, y' = u^3*y on curve y'^2 = x'^3 + u^6*7. This new curve has the same order as + * the original (it is isomorphic), but moreover, has the same addition/doubling formulas, as + * the curve b=7 coefficient does not appear in those formulas (or at least does not appear in + * the formulas implemented in this codebase, both affine and Jacobian). See also Example 9.5.2 + * in https://www.math.auckland.ac.nz/~sgal018/crypto-book/ch9.pdf. + * + * This means any linear combination of secp256k1 points can be computed by applying phi_u + * (with non-zero u) on all input points (including the generator, if used), computing the + * linear combination on the isomorphic curve (using the same group laws), and then applying + * phi_u^{-1} to get back to secp256k1. + * + * Switching to Jacobian coordinates, note that phi_u applied to (X, Y, Z) is simply + * (X, Y, Z/u). Thus, if we want to compute (X1, Y1, Z) + (X2, Y2, Z), with identical Z + * coordinates, we can use phi_Z to transform it to (X1, Y1, 1) + (X2, Y2, 1) on an isomorphic + * curve where the affine addition formula can be used instead. + * If (X3, Y3, Z3) = (X1, Y1) + (X2, Y2) on that curve, then our answer on secp256k1 is + * (X3, Y3, Z3*Z). + * + * This is the effective affine technique: if we have a linear combination of group elements + * to compute, and all those group elements have the same Z coordinate, we can simply pretend + * that all those Z coordinates are 1, perform the computation that way, and then multiply the + * original Z coordinate back in. + * + * The technique works on any a=0 short Weierstrass curve. It is possible to generalize it to + * other curves too, but there the isomorphic curves will have different 'a' coefficients, + * which typically does affect the group laws. + * + * + * === Avoiding the square root for x-only point multiplication === + * + * In this function, we want to compute the X coordinate of q*(n/d, y), for + * y = sqrt((n/d)^3 + 7). Its negation would also be a valid Y coordinate, but by convention + * we pick whatever sqrt returns (which we assume to be a deterministic function). + * + * Let g = y^2*d^3 = n^3 + 7*d^3. This also means y = sqrt(g/d^3). + * Further let v = sqrt(d*g), which must exist as d*g = y^2*d^4 = (y*d^2)^2. + * + * The input point (n/d, y) also has Jacobian coordinates: + * + * (n/d, y, 1) + * = (n/d * v^2, y * v^3, v) + * = (n/d * d*g, y * sqrt(d^3*g^3), v) + * = (n/d * d*g, sqrt(y^2 * d^3*g^3), v) + * = (n*g, sqrt(g/d^3 * d^3*g^3), v) + * = (n*g, sqrt(g^4), v) + * = (n*g, g^2, v) + * + * It is easy to verify that both (n*g, g^2, v) and its negation (n*g, -g^2, v) have affine X + * coordinate n/d, and this holds even when the square root function doesn't have a + * deterministic sign. We choose the (n*g, g^2, v) version. + * + * Now switch to the effective affine curve using phi_v, where the input point has coordinates + * (n*g, g^2). Compute (X, Y, Z) = q * (n*g, g^2) there. + * + * Back on secp256k1, that means q * (n*g, g^2, v) = (X, Y, v*Z). This last point has affine X + * coordinate X / (v^2*Z^2) = X / (d*g*Z^2). Determining the affine Y coordinate would involve + * a square root, but as long as we only care about the resulting X coordinate, no square root + * is needed anywhere in this computation. + */ + + secp256k1_fe g, i; + secp256k1_ge p; + secp256k1_gej rj; + + /* Compute g = (n^3 + B*d^3). */ + secp256k1_fe_sqr(&g, n); + secp256k1_fe_mul(&g, &g, n); + if (d) { + secp256k1_fe b; + VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero(d)); + secp256k1_fe_sqr(&b, d); + VERIFY_CHECK(SECP256K1_B <= 8); /* magnitude of b will be <= 8 after the next call */ + secp256k1_fe_mul_int(&b, SECP256K1_B); + secp256k1_fe_mul(&b, &b, d); + secp256k1_fe_add(&g, &b); + if (!known_on_curve) { + /* We need to determine whether (n/d)^3 + 7 is square. + * + * is_square((n/d)^3 + 7) + * <=> is_square(((n/d)^3 + 7) * d^4) + * <=> is_square((n^3 + 7*d^3) * d) + * <=> is_square(g * d) + */ + secp256k1_fe c; + secp256k1_fe_mul(&c, &g, d); + if (!secp256k1_fe_is_square_var(&c)) return 0; + } + } else { + secp256k1_fe_add_int(&g, SECP256K1_B); + if (!known_on_curve) { + /* g at this point equals x^3 + 7. Test if it is square. */ + if (!secp256k1_fe_is_square_var(&g)) return 0; + } + } + + /* Compute base point P = (n*g, g^2), the effective affine version of (n*g, g^2, v), which has + * corresponding affine X coordinate n/d. */ + secp256k1_fe_mul(&p.x, &g, n); + secp256k1_fe_sqr(&p.y, &g); + p.infinity = 0; + + /* Perform x-only EC multiplication of P with q. */ + VERIFY_CHECK(!secp256k1_scalar_is_zero(q)); + secp256k1_ecmult_const(&rj, &p, q); + VERIFY_CHECK(!secp256k1_gej_is_infinity(&rj)); + + /* The resulting (X, Y, Z) point on the effective-affine isomorphic curve corresponds to + * (X, Y, Z*v) on the secp256k1 curve. The affine version of that has X coordinate + * (X / (Z^2*d*g)). */ + secp256k1_fe_sqr(&i, &rj.z); + secp256k1_fe_mul(&i, &i, &g); + if (d) secp256k1_fe_mul(&i, &i, d); + secp256k1_fe_inv(&i, &i); + secp256k1_fe_mul(r, &rj.x, &i); + + return 1; +} + +#endif /* SECP256K1_ECMULT_CONST_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_gen.h b/crypto/secp256k1/libsecp256k1/src/ecmult_gen.h index eb2cc9ead6..43dd10c38d 100644 --- a/crypto/secp256k1/libsecp256k1/src/ecmult_gen.h +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_gen.h @@ -1,43 +1,143 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) Pieter Wuille, Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECMULT_GEN_ -#define _SECP256K1_ECMULT_GEN_ +#ifndef SECP256K1_ECMULT_GEN_H +#define SECP256K1_ECMULT_GEN_H #include "scalar.h" #include "group.h" + +/* Configuration parameters for the signed-digit multi-comb algorithm: + * + * - COMB_BLOCKS is the number of blocks the input is split into. Each + * has a corresponding table. + * - COMB_TEETH is the number of bits simultaneously covered by one table. + * - COMB_RANGE is the number of bits in supported scalars. For production + * purposes, only 256 is reasonable, but smaller numbers are supported for + * exhaustive test mode. + * + * The comb's spacing (COMB_SPACING), or the distance between the teeth, + * is defined as ceil(COMB_RANGE / (COMB_BLOCKS * COMB_TEETH)). Each block covers + * COMB_SPACING * COMB_TEETH consecutive bits in the input. + * + * The size of the precomputed table is COMB_BLOCKS * (1 << (COMB_TEETH - 1)) + * secp256k1_ge_storages. + * + * The number of point additions equals COMB_BLOCKS * COMB_SPACING. Each point + * addition involves a cmov from (1 << (COMB_TEETH - 1)) table entries and a + * conditional negation. + * + * The number of point doublings is COMB_SPACING - 1. */ + +#if defined(EXHAUSTIVE_TEST_ORDER) +/* We need to control these values for exhaustive tests because + * the table cannot have infinities in them (secp256k1_ge_storage + * doesn't support infinities) */ +# undef COMB_BLOCKS +# undef COMB_TEETH +# if EXHAUSTIVE_TEST_ORDER == 7 +# define COMB_RANGE 3 +# define COMB_BLOCKS 1 +# define COMB_TEETH 2 +# elif EXHAUSTIVE_TEST_ORDER == 13 +# define COMB_RANGE 4 +# define COMB_BLOCKS 1 +# define COMB_TEETH 2 +# elif EXHAUSTIVE_TEST_ORDER == 199 +# define COMB_RANGE 8 +# define COMB_BLOCKS 2 +# define COMB_TEETH 3 +# else +# error "Unknown exhaustive test order" +# endif +# if (COMB_RANGE >= 32) || ((EXHAUSTIVE_TEST_ORDER >> (COMB_RANGE - 1)) != 1) +# error "COMB_RANGE != ceil(log2(EXHAUSTIVE_TEST_ORDER+1))" +# endif +#else /* !defined(EXHAUSTIVE_TEST_ORDER) */ +# define COMB_RANGE 256 +#endif /* defined(EXHAUSTIVE_TEST_ORDER) */ + +/* Use (11, 6) as default configuration, which results in a 22 kB table. */ +#ifndef COMB_BLOCKS +# define COMB_BLOCKS 11 +# ifdef DEBUG_CONFIG +# pragma message DEBUG_CONFIG_MSG("COMB_BLOCKS undefined, assuming default value") +# endif +#endif +#ifndef COMB_TEETH +# define COMB_TEETH 6 +# ifdef DEBUG_CONFIG +# pragma message DEBUG_CONFIG_MSG("COMB_TEETH undefined, assuming default value") +# endif +#endif +/* Use ceil(COMB_RANGE / (COMB_BLOCKS * COMB_TEETH)) as COMB_SPACING. */ +#define COMB_SPACING CEIL_DIV(COMB_RANGE, COMB_BLOCKS * COMB_TEETH) + +/* Range checks on the parameters. */ + +/* The remaining COMB_* parameters are derived values, don't modify these. */ +/* - The number of bits covered by all the blocks; must be at least COMB_RANGE. */ +#define COMB_BITS (COMB_BLOCKS * COMB_TEETH * COMB_SPACING) +/* - The number of entries per table. */ +#define COMB_POINTS (1 << (COMB_TEETH - 1)) + +/* Sanity checks. */ +#if !(1 <= COMB_BLOCKS && COMB_BLOCKS <= 256) +# error "COMB_BLOCKS must be in the range [1, 256]" +#endif +#if !(1 <= COMB_TEETH && COMB_TEETH <= 8) +# error "COMB_TEETH must be in the range [1, 8]" +#endif +#if COMB_BITS < COMB_RANGE +# error "COMB_BLOCKS * COMB_TEETH * COMB_SPACING is too low" +#endif + +/* These last 2 checks are not strictly required, but prevent gratuitously inefficient + * configurations. Note that they compare with 256 rather than COMB_RANGE, so they do + * permit somewhat excessive values for the exhaustive test case, where testing with + * suboptimal parameters may be desirable. */ +#if (COMB_BLOCKS - 1) * COMB_TEETH * COMB_SPACING >= 256 +# error "COMB_BLOCKS can be reduced" +#endif +#if COMB_BLOCKS * (COMB_TEETH - 1) * COMB_SPACING >= 256 +# error "COMB_TEETH can be reduced" +#endif + +#ifdef DEBUG_CONFIG +# pragma message DEBUG_CONFIG_DEF(COMB_RANGE) +# pragma message DEBUG_CONFIG_DEF(COMB_BLOCKS) +# pragma message DEBUG_CONFIG_DEF(COMB_TEETH) +# pragma message DEBUG_CONFIG_DEF(COMB_SPACING) +#endif + typedef struct { - /* For accelerating the computation of a*G: - * To harden against timing attacks, use the following mechanism: - * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. - * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where: - * * U_i = U * 2^i (for i=0..62) - * * U_i = U * (1-2^63) (for i=63) - * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0. - * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is - * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63). - * None of the resulting prec group elements have a known scalar, and neither do any of - * the intermediate sums while computing a*G. - */ - secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ - secp256k1_scalar blind; - secp256k1_gej initial; + /* Whether the context has been built. */ + int built; + + /* Values chosen such that + * + * n*G == comb(n + scalar_offset, G/2) + ge_offset. + * + * This expression lets us use scalar blinding and optimize the comb precomputation. See + * ecmult_gen_impl.h for more details. */ + secp256k1_scalar scalar_offset; + secp256k1_ge ge_offset; + + /* Factor used for projective blinding. This value is used to rescale the Z + * coordinate of the first table lookup. */ + secp256k1_fe proj_blind; } secp256k1_ecmult_gen_context; -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, - const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx); static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); /** Multiply with the generator: R = a*G */ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); -#endif +#endif /* SECP256K1_ECMULT_GEN_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_gen_compute_table.h b/crypto/secp256k1/libsecp256k1/src/ecmult_gen_compute_table.h new file mode 100644 index 0000000000..bd41803a87 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_gen_compute_table.h @@ -0,0 +1,14 @@ +/*********************************************************************** + * Copyright (c) Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H +#define SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H + +#include "ecmult_gen.h" + +static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int blocks, int teeth, int spacing); + +#endif /* SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_gen_compute_table_impl.h b/crypto/secp256k1/libsecp256k1/src/ecmult_gen_compute_table_impl.h new file mode 100644 index 0000000000..6aa8d84082 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_gen_compute_table_impl.h @@ -0,0 +1,108 @@ +/*********************************************************************** + * Copyright (c) Pieter Wuille, Gregory Maxwell, Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H +#define SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H + +#include "ecmult_gen_compute_table.h" +#include "group_impl.h" +#include "field_impl.h" +#include "scalar_impl.h" +#include "ecmult_gen.h" +#include "util.h" + +static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int blocks, int teeth, int spacing) { + size_t points = ((size_t)1) << (teeth - 1); + size_t points_total = points * blocks; + secp256k1_ge* prec = checked_malloc(&default_error_callback, points_total * sizeof(*prec)); + secp256k1_gej* ds = checked_malloc(&default_error_callback, teeth * sizeof(*ds)); + secp256k1_gej* vs = checked_malloc(&default_error_callback, points_total * sizeof(*vs)); + secp256k1_gej u; + size_t vs_pos = 0; + secp256k1_scalar half; + int block, i; + + VERIFY_CHECK(points_total > 0); + + /* u is the running power of two times gen we're working with, initially gen/2. */ + secp256k1_scalar_half(&half, &secp256k1_scalar_one); + secp256k1_gej_set_infinity(&u); + for (i = 255; i >= 0; --i) { + /* Use a very simple multiplication ladder to avoid dependency on ecmult. */ + secp256k1_gej_double_var(&u, &u, NULL); + if (secp256k1_scalar_get_bits_limb32(&half, i, 1)) { + secp256k1_gej_add_ge_var(&u, &u, gen, NULL); + } + } +#ifdef VERIFY + { + /* Verify that u*2 = gen. */ + secp256k1_gej double_u; + secp256k1_gej_double_var(&double_u, &u, NULL); + VERIFY_CHECK(secp256k1_gej_eq_ge_var(&double_u, gen)); + } +#endif + + for (block = 0; block < blocks; ++block) { + int tooth; + /* Here u = 2^(block*teeth*spacing) * gen/2. */ + secp256k1_gej sum; + secp256k1_gej_set_infinity(&sum); + for (tooth = 0; tooth < teeth; ++tooth) { + /* Here u = 2^((block*teeth + tooth)*spacing) * gen/2. */ + /* Make sum = sum(2^((block*teeth + t)*spacing), t=0..tooth) * gen/2. */ + secp256k1_gej_add_var(&sum, &sum, &u, NULL); + /* Make u = 2^((block*teeth + tooth)*spacing + 1) * gen/2. */ + secp256k1_gej_double_var(&u, &u, NULL); + /* Make ds[tooth] = u = 2^((block*teeth + tooth)*spacing + 1) * gen/2. */ + ds[tooth] = u; + /* Make u = 2^((block*teeth + tooth + 1)*spacing) * gen/2, unless at the end. */ + if (block + tooth != blocks + teeth - 2) { + int bit_off; + for (bit_off = 1; bit_off < spacing; ++bit_off) { + secp256k1_gej_double_var(&u, &u, NULL); + } + } + } + /* Now u = 2^((block*teeth + teeth)*spacing) * gen/2 + * = 2^((block+1)*teeth*spacing) * gen/2 */ + + /* Next, compute the table entries for block number block in Jacobian coordinates. + * The entries will occupy vs[block*points + i] for i=0..points-1. + * We start by computing the first (i=0) value corresponding to all summed + * powers of two times G being negative. */ + secp256k1_gej_neg(&vs[vs_pos++], &sum); + /* And then teeth-1 times "double" the range of i values for which the table + * is computed: in each iteration, double the table by taking an existing + * table entry and adding ds[tooth]. */ + for (tooth = 0; tooth < teeth - 1; ++tooth) { + size_t stride = ((size_t)1) << tooth; + size_t index; + for (index = 0; index < stride; ++index, ++vs_pos) { + secp256k1_gej_add_var(&vs[vs_pos], &vs[vs_pos - stride], &ds[tooth], NULL); + } + } + } + VERIFY_CHECK(vs_pos == points_total); + + /* Convert all points simultaneously from secp256k1_gej to secp256k1_ge. */ + secp256k1_ge_set_all_gej_var(prec, vs, points_total); + /* Convert all points from secp256k1_ge to secp256k1_ge_storage output. */ + for (block = 0; block < blocks; ++block) { + size_t index; + for (index = 0; index < points; ++index) { + VERIFY_CHECK(!secp256k1_ge_is_infinity(&prec[block * points + index])); + secp256k1_ge_to_storage(&table[block * points + index], &prec[block * points + index]); + } + } + + /* Free memory. */ + free(vs); + free(ds); + free(prec); +} + +#endif /* SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_gen_impl.h b/crypto/secp256k1/libsecp256k1/src/ecmult_gen_impl.h index 35f2546077..070a121308 100644 --- a/crypto/secp256k1/libsecp256k1/src/ecmult_gen_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_gen_impl.h @@ -1,140 +1,239 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) Pieter Wuille, Gregory Maxwell, Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_ECMULT_GEN_IMPL_H_ -#define _SECP256K1_ECMULT_GEN_IMPL_H_ +#ifndef SECP256K1_ECMULT_GEN_IMPL_H +#define SECP256K1_ECMULT_GEN_IMPL_H +#include "util.h" #include "scalar.h" #include "group.h" #include "ecmult_gen.h" #include "hash_impl.h" -#ifdef USE_ECMULT_STATIC_PRECOMPUTATION -#include "ecmult_static_context.h" -#endif -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx) { - ctx->prec = NULL; -} +#include "precomputed_ecmult_gen.h" -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, const secp256k1_callback* cb) { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - secp256k1_ge prec[1024]; - secp256k1_gej gj; - secp256k1_gej nums_gej; - int i, j; -#endif - - if (ctx->prec != NULL) { - return; - } -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - ctx->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec)); - - /* get the generator */ - secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - - /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ - { - static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; - secp256k1_fe nums_x; - secp256k1_ge nums_ge; - int r; - r = secp256k1_fe_set_b32(&nums_x, nums_b32); - (void)r; - VERIFY_CHECK(r); - r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0); - (void)r; - VERIFY_CHECK(r); - secp256k1_gej_set_ge(&nums_gej, &nums_ge); - /* Add G to make the bits in x uniformly distributed. */ - secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL); - } - - /* compute prec. */ - { - secp256k1_gej precj[1024]; /* Jacobian versions of prec. */ - secp256k1_gej gbase; - secp256k1_gej numsbase; - gbase = gj; /* 16^j * G */ - numsbase = nums_gej; /* 2^j * nums. */ - for (j = 0; j < 64; j++) { - /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ - precj[j*16] = numsbase; - for (i = 1; i < 16; i++) { - secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase, NULL); - } - /* Multiply gbase by 16. */ - for (i = 0; i < 4; i++) { - secp256k1_gej_double_var(&gbase, &gbase, NULL); - } - /* Multiply numbase by 2. */ - secp256k1_gej_double_var(&numsbase, &numsbase, NULL); - if (j == 62) { - /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ - secp256k1_gej_neg(&numsbase, &numsbase); - secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); - } - } - secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb); - } - for (j = 0; j < 64; j++) { - for (i = 0; i < 16; i++) { - secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]); - } - } -#else - (void)cb; - ctx->prec = (secp256k1_ge_storage (*)[64][16])secp256k1_ecmult_static_context; -#endif +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx) { secp256k1_ecmult_gen_blind(ctx, NULL); + ctx->built = 1; } static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) { - return ctx->prec != NULL; -} - -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, - const secp256k1_ecmult_gen_context *src, const secp256k1_callback* cb) { - if (src->prec == NULL) { - dst->prec = NULL; - } else { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - dst->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*dst->prec)); - memcpy(dst->prec, src->prec, sizeof(*dst->prec)); -#else - (void)cb; - dst->prec = src->prec; -#endif - dst->initial = src->initial; - dst->blind = src->blind; - } + return ctx->built; } static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - free(ctx->prec); -#endif - secp256k1_scalar_clear(&ctx->blind); - secp256k1_gej_clear(&ctx->initial); - ctx->prec = NULL; + ctx->built = 0; + secp256k1_scalar_clear(&ctx->scalar_offset); + secp256k1_ge_clear(&ctx->ge_offset); + secp256k1_fe_clear(&ctx->proj_blind); +} + +/* Compute the scalar (2^COMB_BITS - 1) / 2, the difference between the gn argument to + * secp256k1_ecmult_gen, and the scalar whose encoding the table lookup bits are drawn + * from (before applying blinding). */ +static void secp256k1_ecmult_gen_scalar_diff(secp256k1_scalar* diff) { + int i; + + /* Compute scalar -1/2. */ + secp256k1_scalar neghalf; + secp256k1_scalar_half(&neghalf, &secp256k1_scalar_one); + secp256k1_scalar_negate(&neghalf, &neghalf); + + /* Compute offset = 2^(COMB_BITS - 1). */ + *diff = secp256k1_scalar_one; + for (i = 0; i < COMB_BITS - 1; ++i) { + secp256k1_scalar_add(diff, diff, diff); + } + + /* The result is the sum 2^(COMB_BITS - 1) + (-1/2). */ + secp256k1_scalar_add(diff, diff, &neghalf); } static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { + uint32_t comb_off; secp256k1_ge add; + secp256k1_fe neg; secp256k1_ge_storage adds; - secp256k1_scalar gnb; - int bits; - int i, j; + secp256k1_scalar d; + /* Array of uint32_t values large enough to store COMB_BITS bits. Only the bottom + * 8 are ever nonzero, but having the zero padding at the end if COMB_BITS>256 + * avoids the need to deal with out-of-bounds reads from a scalar. */ + uint32_t recoded[(COMB_BITS + 31) >> 5] = {0}; + int first = 1, i; + memset(&adds, 0, sizeof(adds)); - *r = ctx->initial; - /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */ - secp256k1_scalar_add(&gnb, gn, &ctx->blind); - add.infinity = 0; - for (j = 0; j < 64; j++) { - bits = secp256k1_scalar_get_bits(&gnb, j * 4, 4); - for (i = 0; i < 16; i++) { + + /* We want to compute R = gn*G. + * + * To blind the scalar used in the computation, we rewrite this to be + * R = (gn - b)*G + b*G, with a blinding value b determined by the context. + * + * The multiplication (gn-b)*G will be performed using a signed-digit multi-comb (see Section + * 3.3 of "Fast and compact elliptic-curve cryptography" by Mike Hamburg, + * https://eprint.iacr.org/2012/309). + * + * Let comb(s, P) = sum((2*s[i]-1)*2^i*P for i=0..COMB_BITS-1), where s[i] is the i'th bit of + * the binary representation of scalar s. So the s[i] values determine whether -2^i*P (s[i]=0) + * or +2^i*P (s[i]=1) are added together. COMB_BITS is at least 256, so all bits of s are + * covered. By manipulating: + * + * comb(s, P) = sum((2*s[i]-1)*2^i*P for i=0..COMB_BITS-1) + * <=> comb(s, P) = sum((2*s[i]-1)*2^i for i=0..COMB_BITS-1) * P + * <=> comb(s, P) = (2*sum(s[i]*2^i for i=0..COMB_BITS-1) - sum(2^i for i=0..COMB_BITS-1)) * P + * <=> comb(s, P) = (2*s - (2^COMB_BITS - 1)) * P + * + * If we wanted to compute (gn-b)*G as comb(s, G), it would need to hold that + * + * (gn - b) * G = (2*s - (2^COMB_BITS - 1)) * G + * <=> s = (gn - b + (2^COMB_BITS - 1))/2 (mod order) + * + * We use an alternative here that avoids the modular division by two: instead we compute + * (gn-b)*G as comb(d, G/2). For that to hold it must be the case that + * + * (gn - b) * G = (2*d - (2^COMB_BITS - 1)) * (G/2) + * <=> d = gn - b + (2^COMB_BITS - 1)/2 (mod order) + * + * Adding precomputation, our final equations become: + * + * ctx->scalar_offset = (2^COMB_BITS - 1)/2 - b (mod order) + * ctx->ge_offset = b*G + * d = gn + ctx->scalar_offset (mod order) + * R = comb(d, G/2) + ctx->ge_offset + * + * comb(d, G/2) function is then computed by summing + or - 2^(i-1)*G, for i=0..COMB_BITS-1, + * depending on the value of the bits d[i] of the binary representation of scalar d. + */ + + /* Compute the scalar d = (gn + ctx->scalar_offset). */ + secp256k1_scalar_add(&d, &ctx->scalar_offset, gn); + /* Convert to recoded array. */ + for (i = 0; i < 8 && i < ((COMB_BITS + 31) >> 5); ++i) { + recoded[i] = secp256k1_scalar_get_bits_limb32(&d, 32 * i, 32); + } + secp256k1_scalar_clear(&d); + + /* In secp256k1_ecmult_gen_prec_table we have precomputed sums of the + * (2*d[i]-1) * 2^(i-1) * G points, for various combinations of i positions. + * We rewrite our equation in terms of these table entries. + * + * Let mask(b) = sum(2^((b*COMB_TEETH + t)*COMB_SPACING) for t=0..COMB_TEETH-1), + * with b ranging from 0 to COMB_BLOCKS-1. So for example with COMB_BLOCKS=11, + * COMB_TEETH=6, COMB_SPACING=4, we would have: + * mask(0) = 2^0 + 2^4 + 2^8 + 2^12 + 2^16 + 2^20, + * mask(1) = 2^24 + 2^28 + 2^32 + 2^36 + 2^40 + 2^44, + * mask(2) = 2^48 + 2^52 + 2^56 + 2^60 + 2^64 + 2^68, + * ... + * mask(10) = 2^240 + 2^244 + 2^248 + 2^252 + 2^256 + 2^260 + * + * We will split up the bits d[i] using these masks. Specifically, each mask is + * used COMB_SPACING times, with different shifts: + * + * d = (d & mask(0)<<0) + (d & mask(1)<<0) + ... + (d & mask(COMB_BLOCKS-1)<<0) + + * (d & mask(0)<<1) + (d & mask(1)<<1) + ... + (d & mask(COMB_BLOCKS-1)<<1) + + * ... + * (d & mask(0)<<(COMB_SPACING-1)) + ... + * + * Now define table(b, m) = (m - mask(b)/2) * G, and we will precompute these values for + * b=0..COMB_BLOCKS-1, and for all values m which (d & mask(b)) can take (so m can take on + * 2^COMB_TEETH distinct values). + * + * If m=(d & mask(b)), then table(b, m) is the sum of 2^i * (2*d[i]-1) * G/2, with i + * iterating over the set bits in mask(b). In our example, table(2, 2^48 + 2^56 + 2^68) + * would equal (2^48 - 2^52 + 2^56 - 2^60 - 2^64 + 2^68) * G/2. + * + * With that, we can rewrite comb(d, G/2) as: + * + * 2^0 * (table(0, d>>0 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>0 & mask(COMP_BLOCKS-1))) + * + 2^1 * (table(0, d>>1 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>1 & mask(COMP_BLOCKS-1))) + * + 2^2 * (table(0, d>>2 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>2 & mask(COMP_BLOCKS-1))) + * + ... + * + 2^(COMB_SPACING-1) * (table(0, d>>(COMB_SPACING-1) & mask(0)) + ...) + * + * Or more generically as + * + * sum(2^i * sum(table(b, d>>i & mask(b)), b=0..COMB_BLOCKS-1), i=0..COMB_SPACING-1) + * + * This is implemented using an outer loop that runs in reverse order over the lines of this + * equation, which in each iteration runs an inner loop that adds the terms of that line and + * then doubles the result before proceeding to the next line. + * + * In pseudocode: + * c = infinity + * for comb_off in range(COMB_SPACING - 1, -1, -1): + * for block in range(COMB_BLOCKS): + * c += table(block, (d >> comb_off) & mask(block)) + * if comb_off > 0: + * c = 2*c + * return c + * + * This computes c = comb(d, G/2), and thus finally R = c + ctx->ge_offset. Note that it would + * be possible to apply an initial offset instead of a final offset (moving ge_offset to take + * the place of infinity above), but the chosen approach allows using (in a future improvement) + * an incomplete addition formula for most of the multiplication. + * + * The last question is how to implement the table(b, m) function. For any value of b, + * m=(d & mask(b)) can only take on at most 2^COMB_TEETH possible values (the last one may have + * fewer as there mask(b) may exceed the curve order). So we could create COMB_BLOCK tables + * which contain a value for each such m value. + * + * Now note that if m=(d & mask(b)), then flipping the relevant bits of m results in negating + * the result of table(b, m). This is because table(b,m XOR mask(b)) = table(b, mask(b) - m) = + * (mask(b) - m - mask(b)/2)*G = (-m + mask(b)/2)*G = -(m - mask(b)/2)*G = -table(b, m). + * Because of this it suffices to only store the first half of the m values for every b. If an + * entry from the second half is needed, we look up its bit-flipped version instead, and negate + * it. + * + * secp256k1_ecmult_gen_prec_table[b][index] stores the table(b, m) entries. Index + * is the relevant mask(b) bits of m packed together without gaps. */ + + /* Outer loop: iterate over comb_off from COMB_SPACING - 1 down to 0. */ + comb_off = COMB_SPACING - 1; + while (1) { + uint32_t block; + uint32_t bit_pos = comb_off; + /* Inner loop: for each block, add table entries to the result. */ + for (block = 0; block < COMB_BLOCKS; ++block) { + /* Gather the mask(block)-selected bits of d into bits. They're packed: + * bits[tooth] = d[(block*COMB_TEETH + tooth)*COMB_SPACING + comb_off]. */ + uint32_t bits = 0, sign, abs, index, tooth; + /* Instead of reading individual bits here to construct the bits variable, + * build up the result by xoring rotated reads together. In every iteration, + * one additional bit is made correct, starting at the bottom. The bits + * above that contain junk. This reduces leakage by avoiding computations + * on variables that can have only a low number of possible values (e.g., + * just two values when reading a single bit into a variable.) See: + * https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-alam.pdf + */ + for (tooth = 0; tooth < COMB_TEETH; ++tooth) { + /* Construct bitdata s.t. the bottom bit is the bit we'd like to read. + * + * We could just set bitdata = recoded[bit_pos >> 5] >> (bit_pos & 0x1f) + * but this would simply discard the bits that fall off at the bottom, + * and thus, for example, bitdata could still have only two values if we + * happen to shift by exactly 31 positions. We use a rotation instead, + * which ensures that bitdata doesn't loose entropy. This relies on the + * rotation being atomic, i.e., the compiler emitting an actual rot + * instruction. */ + uint32_t bitdata = secp256k1_rotr32(recoded[bit_pos >> 5], bit_pos & 0x1f); + + /* Clear the bit at position tooth, but sssh, don't tell clang. */ + uint32_t volatile vmask = ~(1 << tooth); + bits &= vmask; + + /* Write the bit into position tooth (and junk into higher bits). */ + bits ^= bitdata << tooth; + bit_pos += COMB_SPACING; + } + + /* If the top bit of bits is 1, flip them all (corresponding to looking up + * the negated table value), and remember to negate the result in sign. */ + sign = (bits >> (COMB_TEETH - 1)) & 1; + abs = (bits ^ -sign) & (COMB_POINTS - 1); + VERIFY_CHECK(sign == 0 || sign == 1); + VERIFY_CHECK(abs < COMB_POINTS); + /** This uses a conditional move to avoid any secret data in array indexes. * _Any_ use of secret indexes has been demonstrated to result in timing * sidechannels, even when the cache-line access patterns are uniform. @@ -143,68 +242,100 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25 * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006, * by Dag Arne Osvik, Adi Shamir, and Eran Tromer - * (http://www.tau.ac.il/~tromer/papers/cache.pdf) + * (https://www.tau.ac.il/~tromer/papers/cache.pdf) */ - secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits); + for (index = 0; index < COMB_POINTS; ++index) { + secp256k1_ge_storage_cmov(&adds, &secp256k1_ecmult_gen_prec_table[block][index], index == abs); + } + + /* Set add=adds or add=-adds, in constant time, based on sign. */ + secp256k1_ge_from_storage(&add, &adds); + secp256k1_fe_negate(&neg, &add.y, 1); + secp256k1_fe_cmov(&add.y, &neg, sign); + + /* Add the looked up and conditionally negated value to r. */ + if (EXPECT(first, 0)) { + /* If this is the first table lookup, we can skip addition. */ + secp256k1_gej_set_ge(r, &add); + /* Give the entry a random Z coordinate to blind intermediary results. */ + secp256k1_gej_rescale(r, &ctx->proj_blind); + first = 0; + } else { + secp256k1_gej_add_ge(r, r, &add); + } } - secp256k1_ge_from_storage(&add, &adds); - secp256k1_gej_add_ge(r, r, &add); + + /* Double the result, except in the last iteration. */ + if (comb_off-- == 0) break; + secp256k1_gej_double(r, r); } - bits = 0; + + /* Correct for the scalar_offset added at the start (ge_offset = b*G, while b was + * subtracted from the input scalar gn). */ + secp256k1_gej_add_ge(r, r, &ctx->ge_offset); + + /* Cleanup. */ + secp256k1_fe_clear(&neg); secp256k1_ge_clear(&add); - secp256k1_scalar_clear(&gnb); + secp256k1_memclear(&adds, sizeof(adds)); + secp256k1_memclear(&recoded, sizeof(recoded)); } /* Setup blinding values for secp256k1_ecmult_gen. */ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) { secp256k1_scalar b; + secp256k1_scalar diff; secp256k1_gej gb; - secp256k1_fe s; + secp256k1_fe f; unsigned char nonce32[32]; - secp256k1_rfc6979_hmac_sha256_t rng; - int retry; - unsigned char keydata[64] = {0}; + secp256k1_rfc6979_hmac_sha256 rng; + unsigned char keydata[64]; + + /* Compute the (2^COMB_BITS - 1)/2 term once. */ + secp256k1_ecmult_gen_scalar_diff(&diff); + if (seed32 == NULL) { - /* When seed is NULL, reset the initial point and blinding value. */ - secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); - secp256k1_gej_neg(&ctx->initial, &ctx->initial); - secp256k1_scalar_set_int(&ctx->blind, 1); + /* When seed is NULL, reset the final point and blinding value. */ + secp256k1_ge_neg(&ctx->ge_offset, &secp256k1_ge_const_g); + secp256k1_scalar_add(&ctx->scalar_offset, &secp256k1_scalar_one, &diff); + ctx->proj_blind = secp256k1_fe_one; + return; } /* The prior blinding value (if not reset) is chained forward by including it in the hash. */ - secp256k1_scalar_get_b32(nonce32, &ctx->blind); + secp256k1_scalar_get_b32(keydata, &ctx->scalar_offset); /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data, * and guards against weak or adversarial seeds. This is a simpler and safer interface than * asking the caller for blinding values directly and expecting them to retry on failure. */ - memcpy(keydata, nonce32, 32); - if (seed32 != NULL) { - memcpy(keydata + 32, seed32, 32); - } - secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, seed32 ? 64 : 32); - memset(keydata, 0, sizeof(keydata)); - /* Retry for out of range results to achieve uniformity. */ - do { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - retry = !secp256k1_fe_set_b32(&s, nonce32); - retry |= secp256k1_fe_is_zero(&s); - } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > Fp. */ - /* Randomize the projection to defend against multiplier sidechannels. */ - secp256k1_gej_rescale(&ctx->initial, &s); - secp256k1_fe_clear(&s); - do { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - secp256k1_scalar_set_b32(&b, nonce32, &retry); - /* A blinding value of 0 works, but would undermine the projection hardening. */ - retry |= secp256k1_scalar_is_zero(&b); - } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > order. */ + VERIFY_CHECK(seed32 != NULL); + memcpy(keydata + 32, seed32, 32); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, 64); + secp256k1_memclear(keydata, sizeof(keydata)); + + /* Compute projective blinding factor (cannot be 0). */ + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + secp256k1_fe_set_b32_mod(&f, nonce32); + secp256k1_fe_cmov(&f, &secp256k1_fe_one, secp256k1_fe_normalizes_to_zero(&f)); + ctx->proj_blind = f; + + /* For a random blinding value b, set scalar_offset=diff-b, ge_offset=bG */ + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + secp256k1_scalar_set_b32(&b, nonce32, NULL); + /* The blinding value cannot be zero, as that would mean ge_offset = infinity, + * which secp256k1_gej_add_ge cannot handle. */ + secp256k1_scalar_cmov(&b, &secp256k1_scalar_one, secp256k1_scalar_is_zero(&b)); secp256k1_rfc6979_hmac_sha256_finalize(&rng); - memset(nonce32, 0, 32); secp256k1_ecmult_gen(ctx, &gb, &b); secp256k1_scalar_negate(&b, &b); - ctx->blind = b; - ctx->initial = gb; + secp256k1_scalar_add(&ctx->scalar_offset, &b, &diff); + secp256k1_ge_set_gej(&ctx->ge_offset, &gb); + + /* Clean up. */ + secp256k1_memclear(nonce32, sizeof(nonce32)); secp256k1_scalar_clear(&b); secp256k1_gej_clear(&gb); + secp256k1_fe_clear(&f); + secp256k1_rfc6979_hmac_sha256_clear(&rng); } -#endif +#endif /* SECP256K1_ECMULT_GEN_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/ecmult_impl.h b/crypto/secp256k1/libsecp256k1/src/ecmult_impl.h index 4e40104ad4..0b53b3fcb9 100644 --- a/crypto/secp256k1/libsecp256k1/src/ecmult_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/ecmult_impl.h @@ -1,17 +1,20 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/****************************************************************************** + * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + ******************************************************************************/ -#ifndef _SECP256K1_ECMULT_IMPL_H_ -#define _SECP256K1_ECMULT_IMPL_H_ +#ifndef SECP256K1_ECMULT_IMPL_H +#define SECP256K1_ECMULT_IMPL_H #include +#include +#include "util.h" #include "group.h" #include "scalar.h" #include "ecmult.h" +#include "precomputed_ecmult.h" #if defined(EXHAUSTIVE_TEST_ORDER) /* We need to lower these values for exhaustive tests because @@ -19,39 +22,57 @@ * affine-isomorphism stuff which tracks z-ratios) */ # if EXHAUSTIVE_TEST_ORDER > 128 # define WINDOW_A 5 -# define WINDOW_G 8 # elif EXHAUSTIVE_TEST_ORDER > 8 # define WINDOW_A 4 -# define WINDOW_G 4 # else # define WINDOW_A 2 -# define WINDOW_G 2 # endif #else /* optimal for 128-bit and 256-bit exponents. */ -#define WINDOW_A 5 -/** larger numbers may result in slightly better performance, at the cost of - exponentially larger precomputed tables. */ -#ifdef USE_ENDOMORPHISM -/** Two tables for window size 15: 1.375 MiB. */ -#define WINDOW_G 15 -#else -/** One table for window size 16: 1.375 MiB. */ -#define WINDOW_G 16 -#endif -#endif - -/** The number of entries a table with precomputed multiples needs to have. */ -#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) - -/** Fill a table 'prej' with precomputed odd multiples of a. Prej will contain - * the values [1*a,3*a,...,(2*n-1)*a], so it space for n values. zr[0] will - * contain prej[0].z / a.z. The other zr[i] values = prej[i].z / prej[i-1].z. - * Prej's Z values are undefined, except for the last value. +# define WINDOW_A 5 +/** Larger values for ECMULT_WINDOW_SIZE result in possibly better + * performance at the cost of an exponentially larger precomputed + * table. The exact table size is + * (1 << (WINDOW_G - 2)) * sizeof(secp256k1_ge_storage) bytes, + * where sizeof(secp256k1_ge_storage) is typically 64 bytes but can + * be larger due to platform-specific padding and alignment. + * Two tables of this size are used (due to the endomorphism + * optimization). */ -static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_gej *prej, secp256k1_fe *zr, const secp256k1_gej *a) { - secp256k1_gej d; - secp256k1_ge a_ge, d_ge; +#endif + +#define WNAF_BITS 128 +#define WNAF_SIZE_BITS(bits, w) CEIL_DIV(bits, w) +#define WNAF_SIZE(w) WNAF_SIZE_BITS(WNAF_BITS, w) + +/* The number of objects allocated on the scratch space for ecmult_multi algorithms */ +#define PIPPENGER_SCRATCH_OBJECTS 6 +#define STRAUSS_SCRATCH_OBJECTS 5 + +#define PIPPENGER_MAX_BUCKET_WINDOW 12 + +/* Minimum number of points for which pippenger_wnaf is faster than strauss wnaf */ +#define ECMULT_PIPPENGER_THRESHOLD 88 + +#define ECMULT_MAX_POINTS_PER_BATCH 5000000 + +/** Fill a table 'pre_a' with precomputed odd multiples of a. + * pre_a will contain [1*a,3*a,...,(2*n-1)*a], so it needs space for n group elements. + * zr needs space for n field elements. + * + * Although pre_a is an array of _ge rather than _gej, it actually represents elements + * in Jacobian coordinates with their z coordinates omitted. The omitted z-coordinates + * can be recovered using z and zr. Using the notation z(b) to represent the omitted + * z coordinate of b: + * - z(pre_a[n-1]) = 'z' + * - z(pre_a[i-1]) = z(pre_a[i]) / zr[i] for n > i > 0 + * + * Lastly the zr[0] value, which isn't used above, is set so that: + * - a.z = z(pre_a[0]) / zr[0] + */ +static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_ge *pre_a, secp256k1_fe *zr, secp256k1_fe *z, const secp256k1_gej *a) { + secp256k1_gej d, ai; + secp256k1_ge d_ge; int i; VERIFY_CHECK(!a->infinity); @@ -59,170 +80,76 @@ static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_gej *prej, sec secp256k1_gej_double_var(&d, a, NULL); /* - * Perform the additions on an isomorphism where 'd' is affine: drop the z coordinate - * of 'd', and scale the 1P starting value's x/y coordinates without changing its z. + * Perform the additions using an isomorphic curve Y^2 = X^3 + 7*C^6 where C := d.z. + * The isomorphism, phi, maps a secp256k1 point (x, y) to the point (x*C^2, y*C^3) on the other curve. + * In Jacobian coordinates phi maps (x, y, z) to (x*C^2, y*C^3, z) or, equivalently to (x, y, z/C). + * + * phi(x, y, z) = (x*C^2, y*C^3, z) = (x, y, z/C) + * d_ge := phi(d) = (d.x, d.y, 1) + * ai := phi(a) = (a.x*C^2, a.y*C^3, a.z) + * + * The group addition functions work correctly on these isomorphic curves. + * In particular phi(d) is easy to represent in affine coordinates under this isomorphism. + * This lets us use the faster secp256k1_gej_add_ge_var group addition function that we wouldn't be able to use otherwise. */ - d_ge.x = d.x; - d_ge.y = d.y; - d_ge.infinity = 0; - - secp256k1_ge_set_gej_zinv(&a_ge, a, &d.z); - prej[0].x = a_ge.x; - prej[0].y = a_ge.y; - prej[0].z = a->z; - prej[0].infinity = 0; + secp256k1_ge_set_xy(&d_ge, &d.x, &d.y); + secp256k1_ge_set_gej_zinv(&pre_a[0], a, &d.z); + secp256k1_gej_set_ge(&ai, &pre_a[0]); + ai.z = a->z; + /* pre_a[0] is the point (a.x*C^2, a.y*C^3, a.z*C) which is equivalent to a. + * Set zr[0] to C, which is the ratio between the omitted z(pre_a[0]) value and a.z. + */ zr[0] = d.z; + for (i = 1; i < n; i++) { - secp256k1_gej_add_ge_var(&prej[i], &prej[i-1], &d_ge, &zr[i]); + secp256k1_gej_add_ge_var(&ai, &ai, &d_ge, &zr[i]); + secp256k1_ge_set_xy(&pre_a[i], &ai.x, &ai.y); } - /* - * Each point in 'prej' has a z coordinate too small by a factor of 'd.z'. Only - * the final point's z coordinate is actually used though, so just update that. + /* Multiply the last z-coordinate by C to undo the isomorphism. + * Since the z-coordinates of the pre_a values are implied by the zr array of z-coordinate ratios, + * undoing the isomorphism here undoes the isomorphism for all pre_a values. */ - secp256k1_fe_mul(&prej[n-1].z, &prej[n-1].z, &d.z); + secp256k1_fe_mul(z, &ai.z, &d.z); } -/** Fill a table 'pre' with precomputed odd multiples of a. - * - * There are two versions of this function: - * - secp256k1_ecmult_odd_multiples_table_globalz_windowa which brings its - * resulting point set to a single constant Z denominator, stores the X and Y - * coordinates as ge_storage points in pre, and stores the global Z in rz. - * It only operates on tables sized for WINDOW_A wnaf multiples. - * - secp256k1_ecmult_odd_multiples_table_storage_var, which converts its - * resulting point set to actually affine points, and stores those in pre. - * It operates on tables of any size, but uses heap-allocated temporaries. - * - * To compute a*P + b*G, we compute a table for P using the first function, - * and for G using the second (which requires an inverse, but it only needs to - * happen once). - */ -static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *pre, secp256k1_fe *globalz, const secp256k1_gej *a) { - secp256k1_gej prej[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)]; - - /* Compute the odd multiples in Jacobian form. */ - secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), prej, zr, a); - /* Bring them to the same Z denominator. */ - secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr); +SECP256K1_INLINE static void secp256k1_ecmult_table_verify(int n, int w) { + (void)n; + (void)w; + VERIFY_CHECK(((n) & 1) == 1); + VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); + VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); } -static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage *pre, const secp256k1_gej *a, const secp256k1_callback *cb) { - secp256k1_gej *prej = (secp256k1_gej*)checked_malloc(cb, sizeof(secp256k1_gej) * n); - secp256k1_ge *prea = (secp256k1_ge*)checked_malloc(cb, sizeof(secp256k1_ge) * n); - secp256k1_fe *zr = (secp256k1_fe*)checked_malloc(cb, sizeof(secp256k1_fe) * n); - int i; - - /* Compute the odd multiples in Jacobian form. */ - secp256k1_ecmult_odd_multiples_table(n, prej, zr, a); - /* Convert them in batch to affine coordinates. */ - secp256k1_ge_set_table_gej_var(prea, prej, zr, n); - /* Convert them to compact storage form. */ - for (i = 0; i < n; i++) { - secp256k1_ge_to_storage(&pre[i], &prea[i]); - } - - free(prea); - free(prej); - free(zr); -} - -/** The following two macro retrieves a particular odd multiple from a table - * of precomputed multiples. */ -#define ECMULT_TABLE_GET_GE(r,pre,n,w) do { \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - if ((n) > 0) { \ - *(r) = (pre)[((n)-1)/2]; \ - } else { \ - secp256k1_ge_neg((r), &(pre)[(-(n)-1)/2]); \ - } \ -} while(0) - -#define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - if ((n) > 0) { \ - secp256k1_ge_from_storage((r), &(pre)[((n)-1)/2]); \ - } else { \ - secp256k1_ge_from_storage((r), &(pre)[(-(n)-1)/2]); \ - secp256k1_ge_neg((r), (r)); \ - } \ -} while(0) - -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx) { - ctx->pre_g = NULL; -#ifdef USE_ENDOMORPHISM - ctx->pre_g_128 = NULL; -#endif -} - -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb) { - secp256k1_gej gj; - - if (ctx->pre_g != NULL) { - return; - } - - /* get the generator */ - secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - - ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); - - /* precompute the tables with odd multiples */ - secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj, cb); - -#ifdef USE_ENDOMORPHISM - { - secp256k1_gej g_128j; - int i; - - ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); - - /* calculate 2^128*generator */ - g_128j = gj; - for (i = 0; i < 128; i++) { - secp256k1_gej_double_var(&g_128j, &g_128j, NULL); - } - secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j, cb); - } -#endif -} - -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, - const secp256k1_ecmult_context *src, const secp256k1_callback *cb) { - if (src->pre_g == NULL) { - dst->pre_g = NULL; +SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge(secp256k1_ge *r, const secp256k1_ge *pre, int n, int w) { + secp256k1_ecmult_table_verify(n,w); + if (n > 0) { + *r = pre[(n-1)/2]; } else { - size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); - memcpy(dst->pre_g, src->pre_g, size); + *r = pre[(-n-1)/2]; + secp256k1_fe_negate(&(r->y), &(r->y), 1); } -#ifdef USE_ENDOMORPHISM - if (src->pre_g_128 == NULL) { - dst->pre_g_128 = NULL; +} + +SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_lambda(secp256k1_ge *r, const secp256k1_ge *pre, const secp256k1_fe *x, int n, int w) { + secp256k1_ecmult_table_verify(n,w); + if (n > 0) { + secp256k1_ge_set_xy(r, &x[(n-1)/2], &pre[(n-1)/2].y); } else { - size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); - memcpy(dst->pre_g_128, src->pre_g_128, size); + secp256k1_ge_set_xy(r, &x[(-n-1)/2], &pre[(-n-1)/2].y); + secp256k1_fe_negate(&(r->y), &(r->y), 1); } -#endif } -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx) { - return ctx->pre_g != NULL; -} - -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx) { - free(ctx->pre_g); -#ifdef USE_ENDOMORPHISM - free(ctx->pre_g_128); -#endif - secp256k1_ecmult_context_init(ctx); +SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_storage(secp256k1_ge *r, const secp256k1_ge_storage *pre, int n, int w) { + secp256k1_ecmult_table_verify(n,w); + if (n > 0) { + secp256k1_ge_from_storage(r, &pre[(n-1)/2]); + } else { + secp256k1_ge_from_storage(r, &pre[(-n-1)/2]); + secp256k1_fe_negate(&(r->y), &(r->y), 1); + } } /** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits), @@ -233,7 +160,7 @@ static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx) { * than the number of bits in the (absolute value) of the input. */ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, int w) { - secp256k1_scalar s = *a; + secp256k1_scalar s; int last_set_bit = -1; int bit = 0; int sign = 1; @@ -244,17 +171,21 @@ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, VERIFY_CHECK(a != NULL); VERIFY_CHECK(2 <= w && w <= 31); - memset(wnaf, 0, len * sizeof(wnaf[0])); + for (bit = 0; bit < len; bit++) { + wnaf[bit] = 0; + } - if (secp256k1_scalar_get_bits(&s, 255, 1)) { + s = *a; + if (secp256k1_scalar_get_bits_limb32(&s, 255, 1)) { secp256k1_scalar_negate(&s, &s); sign = -1; } + bit = 0; while (bit < len) { int now; int word; - if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) { + if (secp256k1_scalar_get_bits_limb32(&s, bit, 1) == (unsigned int)carry) { bit++; continue; } @@ -275,127 +206,139 @@ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, bit += now; } #ifdef VERIFY - CHECK(carry == 0); - while (bit < 256) { - CHECK(secp256k1_scalar_get_bits(&s, bit++, 1) == 0); - } + { + int verify_bit = bit; + + VERIFY_CHECK(carry == 0); + + while (verify_bit < 256) { + VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&s, verify_bit, 1) == 0); + verify_bit++; + } + } #endif return last_set_bit + 1; } -static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { - secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_ge tmpa; - secp256k1_fe Z; -#ifdef USE_ENDOMORPHISM - secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_scalar na_1, na_lam; - /* Splitted G factors. */ - secp256k1_scalar ng_1, ng_128; - int wnaf_na_1[130]; - int wnaf_na_lam[130]; +struct secp256k1_strauss_point_state { + int wnaf_na_1[129]; + int wnaf_na_lam[129]; int bits_na_1; int bits_na_lam; +}; + +struct secp256k1_strauss_state { + /* aux is used to hold z-ratios, and then used to hold pre_a[i].x * BETA values. */ + secp256k1_fe* aux; + secp256k1_ge* pre_a; + struct secp256k1_strauss_point_state* ps; +}; + +static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *state, secp256k1_gej *r, size_t num, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { + secp256k1_ge tmpa; + secp256k1_fe Z; + /* Split G factors. */ + secp256k1_scalar ng_1, ng_128; int wnaf_ng_1[129]; - int bits_ng_1; + int bits_ng_1 = 0; int wnaf_ng_128[129]; - int bits_ng_128; -#else - int wnaf_na[256]; - int bits_na; - int wnaf_ng[256]; - int bits_ng; -#endif + int bits_ng_128 = 0; int i; - int bits; + int bits = 0; + size_t np; + size_t no = 0; -#ifdef USE_ENDOMORPHISM - /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ - secp256k1_scalar_split_lambda(&na_1, &na_lam, na); + secp256k1_fe_set_int(&Z, 1); + for (np = 0; np < num; ++np) { + secp256k1_gej tmp; + secp256k1_scalar na_1, na_lam; + if (secp256k1_scalar_is_zero(&na[np]) || secp256k1_gej_is_infinity(&a[np])) { + continue; + } + /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ + secp256k1_scalar_split_lambda(&na_1, &na_lam, &na[np]); - /* build wnaf representation for na_1 and na_lam. */ - bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, 130, &na_1, WINDOW_A); - bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, 130, &na_lam, WINDOW_A); - VERIFY_CHECK(bits_na_1 <= 130); - VERIFY_CHECK(bits_na_lam <= 130); - bits = bits_na_1; - if (bits_na_lam > bits) { - bits = bits_na_lam; - } -#else - /* build wnaf representation for na. */ - bits_na = secp256k1_ecmult_wnaf(wnaf_na, 256, na, WINDOW_A); - bits = bits_na; -#endif + /* build wnaf representation for na_1 and na_lam. */ + state->ps[no].bits_na_1 = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_1, 129, &na_1, WINDOW_A); + state->ps[no].bits_na_lam = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_lam, 129, &na_lam, WINDOW_A); + VERIFY_CHECK(state->ps[no].bits_na_1 <= 129); + VERIFY_CHECK(state->ps[no].bits_na_lam <= 129); + if (state->ps[no].bits_na_1 > bits) { + bits = state->ps[no].bits_na_1; + } + if (state->ps[no].bits_na_lam > bits) { + bits = state->ps[no].bits_na_lam; + } - /* Calculate odd multiples of a. - * All multiples are brought to the same Z 'denominator', which is stored - * in Z. Due to secp256k1' isomorphism we can do all operations pretending - * that the Z coordinate was 1, use affine addition formulae, and correct - * the Z coordinate of the result once at the end. - * The exception is the precomputed G table points, which are actually - * affine. Compared to the base used for other points, they have a Z ratio - * of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same - * isomorphism to efficiently add with a known Z inverse. - */ - secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, a); + /* Calculate odd multiples of a. + * All multiples are brought to the same Z 'denominator', which is stored + * in Z. Due to secp256k1' isomorphism we can do all operations pretending + * that the Z coordinate was 1, use affine addition formulae, and correct + * the Z coordinate of the result once at the end. + * The exception is the precomputed G table points, which are actually + * affine. Compared to the base used for other points, they have a Z ratio + * of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same + * isomorphism to efficiently add with a known Z inverse. + */ + tmp = a[np]; + if (no) { + secp256k1_gej_rescale(&tmp, &Z); + } + secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), state->pre_a + no * ECMULT_TABLE_SIZE(WINDOW_A), state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), &Z, &tmp); + if (no) secp256k1_fe_mul(state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), &(a[np].z)); -#ifdef USE_ENDOMORPHISM - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); + ++no; } - /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ - secp256k1_scalar_split_128(&ng_1, &ng_128, ng); + /* Bring them to the same Z denominator. */ + if (no) { + secp256k1_ge_table_set_globalz(ECMULT_TABLE_SIZE(WINDOW_A) * no, state->pre_a, state->aux); + } - /* Build wnaf representation for ng_1 and ng_128 */ - bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, 129, &ng_1, WINDOW_G); - bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, 129, &ng_128, WINDOW_G); - if (bits_ng_1 > bits) { - bits = bits_ng_1; + for (np = 0; np < no; ++np) { + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_fe_mul(&state->aux[np * ECMULT_TABLE_SIZE(WINDOW_A) + i], &state->pre_a[np * ECMULT_TABLE_SIZE(WINDOW_A) + i].x, &secp256k1_const_beta); + } } - if (bits_ng_128 > bits) { - bits = bits_ng_128; + + if (ng) { + /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ + secp256k1_scalar_split_128(&ng_1, &ng_128, ng); + + /* Build wnaf representation for ng_1 and ng_128 */ + bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, 129, &ng_1, WINDOW_G); + bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, 129, &ng_128, WINDOW_G); + if (bits_ng_1 > bits) { + bits = bits_ng_1; + } + if (bits_ng_128 > bits) { + bits = bits_ng_128; + } } -#else - bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, 256, ng, WINDOW_G); - if (bits_ng > bits) { - bits = bits_ng; - } -#endif secp256k1_gej_set_infinity(r); for (i = bits - 1; i >= 0; i--) { int n; secp256k1_gej_double_var(r, r, NULL); -#ifdef USE_ENDOMORPHISM - if (i < bits_na_1 && (n = wnaf_na_1[i])) { - ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); - } - if (i < bits_na_lam && (n = wnaf_na_lam[i])) { - ECMULT_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); + for (np = 0; np < no; ++np) { + if (i < state->ps[np].bits_na_1 && (n = state->ps[np].wnaf_na_1[i])) { + secp256k1_ecmult_table_get_ge(&tmpa, state->pre_a + np * ECMULT_TABLE_SIZE(WINDOW_A), n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); + } + if (i < state->ps[np].bits_na_lam && (n = state->ps[np].wnaf_na_lam[i])) { + secp256k1_ecmult_table_get_ge_lambda(&tmpa, state->pre_a + np * ECMULT_TABLE_SIZE(WINDOW_A), state->aux + np * ECMULT_TABLE_SIZE(WINDOW_A), n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); + } } if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); + secp256k1_ecmult_table_get_ge_storage(&tmpa, secp256k1_pre_g, n, WINDOW_G); secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); } if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g_128, n, WINDOW_G); + secp256k1_ecmult_table_get_ge_storage(&tmpa, secp256k1_pre_g_128, n, WINDOW_G); secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); } -#else - if (i < bits_na && (n = wnaf_na[i])) { - ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); - } - if (i < bits_ng && (n = wnaf_ng[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); - } -#endif } if (!r->infinity) { @@ -403,4 +346,508 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej } } -#endif +static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { + secp256k1_fe aux[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + struct secp256k1_strauss_point_state ps[1]; + struct secp256k1_strauss_state state; + + state.aux = aux; + state.pre_a = pre_a; + state.ps = ps; + secp256k1_ecmult_strauss_wnaf(&state, r, 1, a, na, ng); +} + +static size_t secp256k1_strauss_scratch_size(size_t n_points) { + static const size_t point_size = (sizeof(secp256k1_ge) + sizeof(secp256k1_fe)) * ECMULT_TABLE_SIZE(WINDOW_A) + sizeof(struct secp256k1_strauss_point_state) + sizeof(secp256k1_gej) + sizeof(secp256k1_scalar); + return n_points*point_size; +} + +static int secp256k1_ecmult_strauss_batch(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n_points, size_t cb_offset) { + secp256k1_gej* points; + secp256k1_scalar* scalars; + struct secp256k1_strauss_state state; + size_t i; + const size_t scratch_checkpoint = secp256k1_scratch_checkpoint(error_callback, scratch); + + secp256k1_gej_set_infinity(r); + if (inp_g_sc == NULL && n_points == 0) { + return 1; + } + + /* We allocate STRAUSS_SCRATCH_OBJECTS objects on the scratch space. If these + * allocations change, make sure to update the STRAUSS_SCRATCH_OBJECTS + * constant and strauss_scratch_size accordingly. */ + points = (secp256k1_gej*)secp256k1_scratch_alloc(error_callback, scratch, n_points * sizeof(secp256k1_gej)); + scalars = (secp256k1_scalar*)secp256k1_scratch_alloc(error_callback, scratch, n_points * sizeof(secp256k1_scalar)); + state.aux = (secp256k1_fe*)secp256k1_scratch_alloc(error_callback, scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_fe)); + state.pre_a = (secp256k1_ge*)secp256k1_scratch_alloc(error_callback, scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_ge)); + state.ps = (struct secp256k1_strauss_point_state*)secp256k1_scratch_alloc(error_callback, scratch, n_points * sizeof(struct secp256k1_strauss_point_state)); + + if (points == NULL || scalars == NULL || state.aux == NULL || state.pre_a == NULL || state.ps == NULL) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + + for (i = 0; i < n_points; i++) { + secp256k1_ge point; + if (!cb(&scalars[i], &point, i+cb_offset, cbdata)) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + secp256k1_gej_set_ge(&points[i], &point); + } + secp256k1_ecmult_strauss_wnaf(&state, r, n_points, points, scalars, inp_g_sc); + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 1; +} + +/* Wrapper for secp256k1_ecmult_multi_func interface */ +static int secp256k1_ecmult_strauss_batch_single(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) { + return secp256k1_ecmult_strauss_batch(error_callback, scratch, r, inp_g_sc, cb, cbdata, n, 0); +} + +static size_t secp256k1_strauss_max_points(const secp256k1_callback* error_callback, secp256k1_scratch *scratch) { + return secp256k1_scratch_max_allocation(error_callback, scratch, STRAUSS_SCRATCH_OBJECTS) / secp256k1_strauss_scratch_size(1); +} + +/** Convert a number to WNAF notation. + * The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val. + * It has the following guarantees: + * - each wnaf[i] is either 0 or an odd integer between -(1 << w) and (1 << w) + * - the number of words set is always WNAF_SIZE(w) + * - the returned skew is 0 or 1 + */ +static int secp256k1_wnaf_fixed(int *wnaf, const secp256k1_scalar *s, int w) { + int skew = 0; + int pos; + int max_pos; + int last_w; + const secp256k1_scalar *work = s; + + if (secp256k1_scalar_is_zero(s)) { + for (pos = 0; pos < WNAF_SIZE(w); pos++) { + wnaf[pos] = 0; + } + return 0; + } + + if (secp256k1_scalar_is_even(s)) { + skew = 1; + } + + wnaf[0] = secp256k1_scalar_get_bits_var(work, 0, w) + skew; + /* Compute last window size. Relevant when window size doesn't divide the + * number of bits in the scalar */ + last_w = WNAF_BITS - (WNAF_SIZE(w) - 1) * w; + + /* Store the position of the first nonzero word in max_pos to allow + * skipping leading zeros when calculating the wnaf. */ + for (pos = WNAF_SIZE(w) - 1; pos > 0; pos--) { + int val = secp256k1_scalar_get_bits_var(work, pos * w, pos == WNAF_SIZE(w)-1 ? last_w : w); + if(val != 0) { + break; + } + wnaf[pos] = 0; + } + max_pos = pos; + pos = 1; + + while (pos <= max_pos) { + int val = secp256k1_scalar_get_bits_var(work, pos * w, pos == WNAF_SIZE(w)-1 ? last_w : w); + if ((val & 1) == 0) { + wnaf[pos - 1] -= (1 << w); + wnaf[pos] = (val + 1); + } else { + wnaf[pos] = val; + } + /* Set a coefficient to zero if it is 1 or -1 and the proceeding digit + * is strictly negative or strictly positive respectively. Only change + * coefficients at previous positions because above code assumes that + * wnaf[pos - 1] is odd. + */ + if (pos >= 2 && ((wnaf[pos - 1] == 1 && wnaf[pos - 2] < 0) || (wnaf[pos - 1] == -1 && wnaf[pos - 2] > 0))) { + if (wnaf[pos - 1] == 1) { + wnaf[pos - 2] += 1 << w; + } else { + wnaf[pos - 2] -= 1 << w; + } + wnaf[pos - 1] = 0; + } + ++pos; + } + + return skew; +} + +struct secp256k1_pippenger_point_state { + int skew_na; + size_t input_pos; +}; + +struct secp256k1_pippenger_state { + int *wnaf_na; + struct secp256k1_pippenger_point_state* ps; +}; + +/* + * pippenger_wnaf computes the result of a multi-point multiplication as + * follows: The scalars are brought into wnaf with n_wnaf elements each. Then + * for every i < n_wnaf, first each point is added to a "bucket" corresponding + * to the point's wnaf[i]. Second, the buckets are added together such that + * r += 1*bucket[0] + 3*bucket[1] + 5*bucket[2] + ... + */ +static int secp256k1_ecmult_pippenger_wnaf(secp256k1_gej *buckets, int bucket_window, struct secp256k1_pippenger_state *state, secp256k1_gej *r, const secp256k1_scalar *sc, const secp256k1_ge *pt, size_t num) { + size_t n_wnaf = WNAF_SIZE(bucket_window+1); + size_t np; + size_t no = 0; + int i; + int j; + + for (np = 0; np < num; ++np) { + if (secp256k1_scalar_is_zero(&sc[np]) || secp256k1_ge_is_infinity(&pt[np])) { + continue; + } + state->ps[no].input_pos = np; + state->ps[no].skew_na = secp256k1_wnaf_fixed(&state->wnaf_na[no*n_wnaf], &sc[np], bucket_window+1); + no++; + } + secp256k1_gej_set_infinity(r); + + if (no == 0) { + return 1; + } + + for (i = n_wnaf - 1; i >= 0; i--) { + secp256k1_gej running_sum; + + for(j = 0; j < ECMULT_TABLE_SIZE(bucket_window+2); j++) { + secp256k1_gej_set_infinity(&buckets[j]); + } + + for (np = 0; np < no; ++np) { + int n = state->wnaf_na[np*n_wnaf + i]; + struct secp256k1_pippenger_point_state point_state = state->ps[np]; + secp256k1_ge tmp; + int idx; + + if (i == 0) { + /* correct for wnaf skew */ + int skew = point_state.skew_na; + if (skew) { + secp256k1_ge_neg(&tmp, &pt[point_state.input_pos]); + secp256k1_gej_add_ge_var(&buckets[0], &buckets[0], &tmp, NULL); + } + } + if (n > 0) { + idx = (n - 1)/2; + secp256k1_gej_add_ge_var(&buckets[idx], &buckets[idx], &pt[point_state.input_pos], NULL); + } else if (n < 0) { + idx = -(n + 1)/2; + secp256k1_ge_neg(&tmp, &pt[point_state.input_pos]); + secp256k1_gej_add_ge_var(&buckets[idx], &buckets[idx], &tmp, NULL); + } + } + + for(j = 0; j < bucket_window; j++) { + secp256k1_gej_double_var(r, r, NULL); + } + + secp256k1_gej_set_infinity(&running_sum); + /* Accumulate the sum: bucket[0] + 3*bucket[1] + 5*bucket[2] + 7*bucket[3] + ... + * = bucket[0] + bucket[1] + bucket[2] + bucket[3] + ... + * + 2 * (bucket[1] + 2*bucket[2] + 3*bucket[3] + ...) + * using an intermediate running sum: + * running_sum = bucket[0] + bucket[1] + bucket[2] + ... + * + * The doubling is done implicitly by deferring the final window doubling (of 'r'). + */ + for(j = ECMULT_TABLE_SIZE(bucket_window+2) - 1; j > 0; j--) { + secp256k1_gej_add_var(&running_sum, &running_sum, &buckets[j], NULL); + secp256k1_gej_add_var(r, r, &running_sum, NULL); + } + + secp256k1_gej_add_var(&running_sum, &running_sum, &buckets[0], NULL); + secp256k1_gej_double_var(r, r, NULL); + secp256k1_gej_add_var(r, r, &running_sum, NULL); + } + return 1; +} + +/** + * Returns optimal bucket_window (number of bits of a scalar represented by a + * set of buckets) for a given number of points. + */ +static int secp256k1_pippenger_bucket_window(size_t n) { + if (n <= 1) { + return 1; + } else if (n <= 4) { + return 2; + } else if (n <= 20) { + return 3; + } else if (n <= 57) { + return 4; + } else if (n <= 136) { + return 5; + } else if (n <= 235) { + return 6; + } else if (n <= 1260) { + return 7; + } else if (n <= 4420) { + return 9; + } else if (n <= 7880) { + return 10; + } else if (n <= 16050) { + return 11; + } else { + return PIPPENGER_MAX_BUCKET_WINDOW; + } +} + +/** + * Returns the maximum optimal number of points for a bucket_window. + */ +static size_t secp256k1_pippenger_bucket_window_inv(int bucket_window) { + switch(bucket_window) { + case 1: return 1; + case 2: return 4; + case 3: return 20; + case 4: return 57; + case 5: return 136; + case 6: return 235; + case 7: return 1260; + case 8: return 1260; + case 9: return 4420; + case 10: return 7880; + case 11: return 16050; + case PIPPENGER_MAX_BUCKET_WINDOW: return SIZE_MAX; + } + return 0; +} + + +SECP256K1_INLINE static void secp256k1_ecmult_endo_split(secp256k1_scalar *s1, secp256k1_scalar *s2, secp256k1_ge *p1, secp256k1_ge *p2) { + secp256k1_scalar tmp = *s1; + secp256k1_scalar_split_lambda(s1, s2, &tmp); + secp256k1_ge_mul_lambda(p2, p1); + + if (secp256k1_scalar_is_high(s1)) { + secp256k1_scalar_negate(s1, s1); + secp256k1_ge_neg(p1, p1); + } + if (secp256k1_scalar_is_high(s2)) { + secp256k1_scalar_negate(s2, s2); + secp256k1_ge_neg(p2, p2); + } +} + +/** + * Returns the scratch size required for a given number of points (excluding + * base point G) without considering alignment. + */ +static size_t secp256k1_pippenger_scratch_size(size_t n_points, int bucket_window) { + size_t entries = 2*n_points + 2; + size_t entry_size = sizeof(secp256k1_ge) + sizeof(secp256k1_scalar) + sizeof(struct secp256k1_pippenger_point_state) + (WNAF_SIZE(bucket_window+1)+1)*sizeof(int); + return (sizeof(secp256k1_gej) << bucket_window) + sizeof(struct secp256k1_pippenger_state) + entries * entry_size; +} + +static int secp256k1_ecmult_pippenger_batch(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n_points, size_t cb_offset) { + const size_t scratch_checkpoint = secp256k1_scratch_checkpoint(error_callback, scratch); + /* Use 2(n+1) with the endomorphism, when calculating batch + * sizes. The reason for +1 is that we add the G scalar to the list of + * other scalars. */ + size_t entries = 2*n_points + 2; + secp256k1_ge *points; + secp256k1_scalar *scalars; + secp256k1_gej *buckets; + struct secp256k1_pippenger_state *state_space; + size_t idx = 0; + size_t point_idx = 0; + int bucket_window; + + secp256k1_gej_set_infinity(r); + if (inp_g_sc == NULL && n_points == 0) { + return 1; + } + bucket_window = secp256k1_pippenger_bucket_window(n_points); + + /* We allocate PIPPENGER_SCRATCH_OBJECTS objects on the scratch space. If + * these allocations change, make sure to update the + * PIPPENGER_SCRATCH_OBJECTS constant and pippenger_scratch_size + * accordingly. */ + points = (secp256k1_ge *) secp256k1_scratch_alloc(error_callback, scratch, entries * sizeof(*points)); + scalars = (secp256k1_scalar *) secp256k1_scratch_alloc(error_callback, scratch, entries * sizeof(*scalars)); + state_space = (struct secp256k1_pippenger_state *) secp256k1_scratch_alloc(error_callback, scratch, sizeof(*state_space)); + if (points == NULL || scalars == NULL || state_space == NULL) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + state_space->ps = (struct secp256k1_pippenger_point_state *) secp256k1_scratch_alloc(error_callback, scratch, entries * sizeof(*state_space->ps)); + state_space->wnaf_na = (int *) secp256k1_scratch_alloc(error_callback, scratch, entries*(WNAF_SIZE(bucket_window+1)) * sizeof(int)); + buckets = (secp256k1_gej *) secp256k1_scratch_alloc(error_callback, scratch, ((size_t)1 << bucket_window) * sizeof(*buckets)); + if (state_space->ps == NULL || state_space->wnaf_na == NULL || buckets == NULL) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + + if (inp_g_sc != NULL) { + scalars[0] = *inp_g_sc; + points[0] = secp256k1_ge_const_g; + idx++; + secp256k1_ecmult_endo_split(&scalars[0], &scalars[1], &points[0], &points[1]); + idx++; + } + + while (point_idx < n_points) { + if (!cb(&scalars[idx], &points[idx], point_idx + cb_offset, cbdata)) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + idx++; + secp256k1_ecmult_endo_split(&scalars[idx - 1], &scalars[idx], &points[idx - 1], &points[idx]); + idx++; + point_idx++; + } + + secp256k1_ecmult_pippenger_wnaf(buckets, bucket_window, state_space, r, scalars, points, idx); + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 1; +} + +/* Wrapper for secp256k1_ecmult_multi_func interface */ +static int secp256k1_ecmult_pippenger_batch_single(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) { + return secp256k1_ecmult_pippenger_batch(error_callback, scratch, r, inp_g_sc, cb, cbdata, n, 0); +} + +/** + * Returns the maximum number of points in addition to G that can be used with + * a given scratch space. The function ensures that fewer points may also be + * used. + */ +static size_t secp256k1_pippenger_max_points(const secp256k1_callback* error_callback, secp256k1_scratch *scratch) { + size_t max_alloc = secp256k1_scratch_max_allocation(error_callback, scratch, PIPPENGER_SCRATCH_OBJECTS); + int bucket_window; + size_t res = 0; + + for (bucket_window = 1; bucket_window <= PIPPENGER_MAX_BUCKET_WINDOW; bucket_window++) { + size_t n_points; + size_t max_points = secp256k1_pippenger_bucket_window_inv(bucket_window); + size_t space_for_points; + size_t space_overhead; + size_t entry_size = sizeof(secp256k1_ge) + sizeof(secp256k1_scalar) + sizeof(struct secp256k1_pippenger_point_state) + (WNAF_SIZE(bucket_window+1)+1)*sizeof(int); + + entry_size = 2*entry_size; + space_overhead = (sizeof(secp256k1_gej) << bucket_window) + entry_size + sizeof(struct secp256k1_pippenger_state); + if (space_overhead > max_alloc) { + break; + } + space_for_points = max_alloc - space_overhead; + + n_points = space_for_points/entry_size; + n_points = n_points > max_points ? max_points : n_points; + if (n_points > res) { + res = n_points; + } + if (n_points < max_points) { + /* A larger bucket_window may support even more points. But if we + * would choose that then the caller couldn't safely use any number + * smaller than what this function returns */ + break; + } + } + return res; +} + +/* Computes ecmult_multi by simply multiplying and adding each point. Does not + * require a scratch space */ +static int secp256k1_ecmult_multi_simple_var(secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n_points) { + size_t point_idx; + secp256k1_gej tmpj; + + secp256k1_gej_set_infinity(r); + secp256k1_gej_set_infinity(&tmpj); + /* r = inp_g_sc*G */ + secp256k1_ecmult(r, &tmpj, &secp256k1_scalar_zero, inp_g_sc); + for (point_idx = 0; point_idx < n_points; point_idx++) { + secp256k1_ge point; + secp256k1_gej pointj; + secp256k1_scalar scalar; + if (!cb(&scalar, &point, point_idx, cbdata)) { + return 0; + } + /* r += scalar*point */ + secp256k1_gej_set_ge(&pointj, &point); + secp256k1_ecmult(&tmpj, &pointj, &scalar, NULL); + secp256k1_gej_add_var(r, r, &tmpj, NULL); + } + return 1; +} + +/* Compute the number of batches and the batch size given the maximum batch size and the + * total number of points */ +static int secp256k1_ecmult_multi_batch_size_helper(size_t *n_batches, size_t *n_batch_points, size_t max_n_batch_points, size_t n) { + if (max_n_batch_points == 0) { + return 0; + } + if (max_n_batch_points > ECMULT_MAX_POINTS_PER_BATCH) { + max_n_batch_points = ECMULT_MAX_POINTS_PER_BATCH; + } + if (n == 0) { + *n_batches = 0; + *n_batch_points = 0; + return 1; + } + /* Compute ceil(n/max_n_batch_points) and ceil(n/n_batches) */ + *n_batches = CEIL_DIV(n, max_n_batch_points); + *n_batch_points = CEIL_DIV(n, *n_batches); + return 1; +} + +typedef int (*secp256k1_ecmult_multi_func)(const secp256k1_callback* error_callback, secp256k1_scratch*, secp256k1_gej*, const secp256k1_scalar*, secp256k1_ecmult_multi_callback cb, void*, size_t); +static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) { + size_t i; + + int (*f)(const secp256k1_callback* error_callback, secp256k1_scratch*, secp256k1_gej*, const secp256k1_scalar*, secp256k1_ecmult_multi_callback cb, void*, size_t, size_t); + size_t n_batches; + size_t n_batch_points; + + secp256k1_gej_set_infinity(r); + if (inp_g_sc == NULL && n == 0) { + return 1; + } else if (n == 0) { + secp256k1_ecmult(r, r, &secp256k1_scalar_zero, inp_g_sc); + return 1; + } + if (scratch == NULL) { + return secp256k1_ecmult_multi_simple_var(r, inp_g_sc, cb, cbdata, n); + } + + /* Compute the batch sizes for Pippenger's algorithm given a scratch space. If it's greater than + * a threshold use Pippenger's algorithm. Otherwise use Strauss' algorithm. + * As a first step check if there's enough space for Pippenger's algo (which requires less space + * than Strauss' algo) and if not, use the simple algorithm. */ + if (!secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, secp256k1_pippenger_max_points(error_callback, scratch), n)) { + return secp256k1_ecmult_multi_simple_var(r, inp_g_sc, cb, cbdata, n); + } + if (n_batch_points >= ECMULT_PIPPENGER_THRESHOLD) { + f = secp256k1_ecmult_pippenger_batch; + } else { + if (!secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, secp256k1_strauss_max_points(error_callback, scratch), n)) { + return secp256k1_ecmult_multi_simple_var(r, inp_g_sc, cb, cbdata, n); + } + f = secp256k1_ecmult_strauss_batch; + } + for(i = 0; i < n_batches; i++) { + size_t nbp = n < n_batch_points ? n : n_batch_points; + size_t offset = n_batch_points*i; + secp256k1_gej tmp; + if (!f(error_callback, scratch, &tmp, i == 0 ? inp_g_sc : NULL, cb, cbdata, nbp, offset)) { + return 0; + } + secp256k1_gej_add_var(r, r, &tmp, NULL); + n -= nbp; + } + return 1; +} + +#endif /* SECP256K1_ECMULT_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/field.h b/crypto/secp256k1/libsecp256k1/src/field.h index bbb1ee866c..1f6ba7460f 100644 --- a/crypto/secp256k1/libsecp256k1/src/field.h +++ b/crypto/secp256k1/libsecp256k1/src/field.h @@ -1,132 +1,350 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_FIELD_ -#define _SECP256K1_FIELD_ - -/** Field element module. - * - * Field elements can be represented in several ways, but code accessing - * it (and implementations) need to take certain properties into account: - * - Each field element can be normalized or not. - * - Each field element has a magnitude, which represents how far away - * its representation is away from normalization. Normalized elements - * always have a magnitude of 1, but a magnitude of 1 doesn't imply - * normality. - */ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#if defined(USE_FIELD_10X26) -#include "field_10x26.h" -#elif defined(USE_FIELD_5X52) -#include "field_5x52.h" -#else -#error "Please select field implementation" -#endif +#ifndef SECP256K1_FIELD_H +#define SECP256K1_FIELD_H #include "util.h" -/** Normalize a field element. */ +/* This file defines the generic interface for working with secp256k1_fe + * objects, which represent field elements (integers modulo 2^256 - 2^32 - 977). + * + * The actual definition of the secp256k1_fe type depends on the chosen field + * implementation; see the field_5x52.h and field_10x26.h files for details. + * + * All secp256k1_fe objects have implicit properties that determine what + * operations are permitted on it. These are purely a function of what + * secp256k1_fe_ operations are applied on it, generally (implicitly) fixed at + * compile time, and do not depend on the chosen field implementation. Despite + * that, what these properties actually entail for the field representation + * values depends on the chosen field implementation. These properties are: + * - magnitude: an integer in [0,32] + * - normalized: 0 or 1; normalized=1 implies magnitude <= 1. + * + * In VERIFY mode, they are materialized explicitly as fields in the struct, + * allowing run-time verification of these properties. In that case, the field + * implementation also provides a secp256k1_fe_verify routine to verify that + * these fields match the run-time value and perform internal consistency + * checks. */ +#ifdef VERIFY +# define SECP256K1_FE_VERIFY_FIELDS \ + int magnitude; \ + int normalized; +#else +# define SECP256K1_FE_VERIFY_FIELDS +#endif + +#if defined(SECP256K1_WIDEMUL_INT128) +#include "field_5x52.h" +#elif defined(SECP256K1_WIDEMUL_INT64) +#include "field_10x26.h" +#else +#error "Please select wide multiplication implementation" +#endif + +#ifdef VERIFY +/* Magnitude and normalized value for constants. */ +#define SECP256K1_FE_VERIFY_CONST(d7, d6, d5, d4, d3, d2, d1, d0) \ + /* Magnitude is 0 for constant 0; 1 otherwise. */ \ + , (((d7) | (d6) | (d5) | (d4) | (d3) | (d2) | (d1) | (d0)) != 0) \ + /* Normalized is 1 unless sum(d_i<<(32*i) for i=0..7) exceeds field modulus. */ \ + , (!(((d7) & (d6) & (d5) & (d4) & (d3) & (d2)) == 0xfffffffful && ((d1) == 0xfffffffful || ((d1) == 0xfffffffe && (d0 >= 0xfffffc2f))))) +#else +#define SECP256K1_FE_VERIFY_CONST(d7, d6, d5, d4, d3, d2, d1, d0) +#endif + +/** This expands to an initializer for a secp256k1_fe valued sum((i*32) * d_i, i=0..7) mod p. + * + * It has magnitude 1, unless d_i are all 0, in which case the magnitude is 0. + * It is normalized, unless sum(2^(i*32) * d_i, i=0..7) >= p. + * + * SECP256K1_FE_CONST_INNER is provided by the implementation. + */ +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)) SECP256K1_FE_VERIFY_CONST((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)) } + +static const secp256k1_fe secp256k1_fe_one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); +static const secp256k1_fe secp256k1_const_beta = SECP256K1_FE_CONST( + 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul, + 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul +); + +#ifndef VERIFY +/* In non-VERIFY mode, we #define the fe operations to be identical to their + * internal field implementation, to avoid the potential overhead of a + * function call (even though presumably inlinable). */ +# define secp256k1_fe_normalize secp256k1_fe_impl_normalize +# define secp256k1_fe_normalize_weak secp256k1_fe_impl_normalize_weak +# define secp256k1_fe_normalize_var secp256k1_fe_impl_normalize_var +# define secp256k1_fe_normalizes_to_zero secp256k1_fe_impl_normalizes_to_zero +# define secp256k1_fe_normalizes_to_zero_var secp256k1_fe_impl_normalizes_to_zero_var +# define secp256k1_fe_set_int secp256k1_fe_impl_set_int +# define secp256k1_fe_is_zero secp256k1_fe_impl_is_zero +# define secp256k1_fe_is_odd secp256k1_fe_impl_is_odd +# define secp256k1_fe_cmp_var secp256k1_fe_impl_cmp_var +# define secp256k1_fe_set_b32_mod secp256k1_fe_impl_set_b32_mod +# define secp256k1_fe_set_b32_limit secp256k1_fe_impl_set_b32_limit +# define secp256k1_fe_get_b32 secp256k1_fe_impl_get_b32 +# define secp256k1_fe_negate_unchecked secp256k1_fe_impl_negate_unchecked +# define secp256k1_fe_mul_int_unchecked secp256k1_fe_impl_mul_int_unchecked +# define secp256k1_fe_add secp256k1_fe_impl_add +# define secp256k1_fe_mul secp256k1_fe_impl_mul +# define secp256k1_fe_sqr secp256k1_fe_impl_sqr +# define secp256k1_fe_cmov secp256k1_fe_impl_cmov +# define secp256k1_fe_to_storage secp256k1_fe_impl_to_storage +# define secp256k1_fe_from_storage secp256k1_fe_impl_from_storage +# define secp256k1_fe_inv secp256k1_fe_impl_inv +# define secp256k1_fe_inv_var secp256k1_fe_impl_inv_var +# define secp256k1_fe_get_bounds secp256k1_fe_impl_get_bounds +# define secp256k1_fe_half secp256k1_fe_impl_half +# define secp256k1_fe_add_int secp256k1_fe_impl_add_int +# define secp256k1_fe_is_square_var secp256k1_fe_impl_is_square_var +#endif /* !defined(VERIFY) */ + +/** Normalize a field element. + * + * On input, r must be a valid field element. + * On output, r represents the same value but has normalized=1 and magnitude=1. + */ static void secp256k1_fe_normalize(secp256k1_fe *r); -/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ +/** Give a field element magnitude 1. + * + * On input, r must be a valid field element. + * On output, r represents the same value but has magnitude=1. Normalized is unchanged. + */ static void secp256k1_fe_normalize_weak(secp256k1_fe *r); -/** Normalize a field element, without constant-time guarantee. */ +/** Normalize a field element, without constant-time guarantee. + * + * Identical in behavior to secp256k1_fe_normalize, but not constant time in r. + */ static void secp256k1_fe_normalize_var(secp256k1_fe *r); -/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field - * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r); +/** Determine whether r represents field element 0. + * + * On input, r must be a valid field element. + * Returns whether r = 0 (mod p). + */ +static int secp256k1_fe_normalizes_to_zero(const secp256k1_fe *r); -/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field - * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); +/** Determine whether r represents field element 0, without constant-time guarantee. + * + * Identical in behavior to secp256k1_normalizes_to_zero, but not constant time in r. + */ +static int secp256k1_fe_normalizes_to_zero_var(const secp256k1_fe *r); -/** Set a field element equal to a small integer. Resulting field element is normalized. */ +/** Set a field element to an integer in range [0,0x7FFF]. + * + * On input, r does not need to be initialized, a must be in [0,0x7FFF]. + * On output, r represents value a, is normalized and has magnitude (a!=0). + */ static void secp256k1_fe_set_int(secp256k1_fe *r, int a); -/** Sets a field element equal to zero, initializing all fields. */ +/** Clear a field element to prevent leaking sensitive information. */ static void secp256k1_fe_clear(secp256k1_fe *a); -/** Verify whether a field element is zero. Requires the input to be normalized. */ +/** Determine whether a represents field element 0. + * + * On input, a must be a valid normalized field element. + * Returns whether a = 0 (mod p). + * + * This behaves identical to secp256k1_normalizes_to_zero{,_var}, but requires + * normalized input (and is much faster). + */ static int secp256k1_fe_is_zero(const secp256k1_fe *a); -/** Check the "oddness" of a field element. Requires the input to be normalized. */ +/** Determine whether a (mod p) is odd. + * + * On input, a must be a valid normalized field element. + * Returns (int(a) mod p) & 1. + */ static int secp256k1_fe_is_odd(const secp256k1_fe *a); -/** Compare two field elements. Requires magnitude-1 inputs. */ +/** Determine whether two field elements are equal. + * + * On input, a and b must be valid field elements with magnitudes not exceeding + * 1 and 31, respectively. + * Returns a = b (mod p). + */ static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); -/** Same as secp256k1_fe_equal, but may be variable time. */ -static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); - -/** Compare two field elements. Requires both inputs to be normalized */ +/** Compare the values represented by 2 field elements, without constant-time guarantee. + * + * On input, a and b must be valid normalized field elements. + * Returns 1 if a > b, -1 if a < b, and 0 if a = b (comparisons are done as integers + * in range 0..p-1). + */ static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); -/** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); +/** Set a field element equal to the element represented by a provided 32-byte big endian value + * interpreted modulo p. + * + * On input, r does not need to be initialized. a must be a pointer to an initialized 32-byte array. + * On output, r = a (mod p). It will have magnitude 1, and not be normalized. + */ +static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a); -/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +/** Set a field element equal to a provided 32-byte big endian value, checking for overflow. + * + * On input, r does not need to be initialized. a must be a pointer to an initialized 32-byte array. + * On output, r = a if (a < p), it will be normalized with magnitude 1, and 1 is returned. + * If a >= p, 0 is returned, and r will be made invalid (and must not be used without overwriting). + */ +static int secp256k1_fe_set_b32_limit(secp256k1_fe *r, const unsigned char *a); + +/** Convert a field element to 32-byte big endian byte array. + * On input, a must be a valid normalized field element, and r a pointer to a 32-byte array. + * On output, r = a (mod p). + */ static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); -/** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input - * as an argument. The magnitude of the output is one higher. */ -static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); +/** Negate a field element. + * + * On input, r does not need to be initialized. a must be a valid field element with + * magnitude not exceeding m. m must be an integer constant expression in [0,31]. + * Performs {r = -a}. + * On output, r will not be normalized, and will have magnitude m+1. + */ +#define secp256k1_fe_negate(r, a, m) ASSERT_INT_CONST_AND_DO(m, secp256k1_fe_negate_unchecked(r, a, m)) -/** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that - * small integer. */ -static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); +/** Like secp256k1_fe_negate_unchecked but m is not checked to be an integer constant expression. + * + * Should not be called directly outside of tests. + */ +static void secp256k1_fe_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m); -/** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ +/** Add a small integer to a field element. + * + * Performs {r += a}. The magnitude of r increases by 1, and normalized is cleared. + * a must be in range [0,0x7FFF]. + */ +static void secp256k1_fe_add_int(secp256k1_fe *r, int a); + +/** Multiply a field element with a small integer. + * + * On input, r must be a valid field element. a must be an integer constant expression in [0,32]. + * The magnitude of r times a must not exceed 32. + * Performs {r *= a}. + * On output, r's magnitude is multiplied by a, and r will not be normalized. + */ +#define secp256k1_fe_mul_int(r, a) ASSERT_INT_CONST_AND_DO(a, secp256k1_fe_mul_int_unchecked(r, a)) + +/** Like secp256k1_fe_mul_int but a is not checked to be an integer constant expression. + * + * Should not be called directly outside of tests. + */ +static void secp256k1_fe_mul_int_unchecked(secp256k1_fe *r, int a); + +/** Increment a field element by another. + * + * On input, r and a must be valid field elements, not necessarily normalized. + * The sum of their magnitudes must not exceed 32. + * Performs {r += a}. + * On output, r will not be normalized, and will have magnitude incremented by a's. + */ static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a); -/** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. - * The output magnitude is 1 (but not guaranteed to be normalized). */ +/** Multiply two field elements. + * + * On input, a and b must be valid field elements; r does not need to be initialized. + * r and a may point to the same object, but neither may point to the object pointed + * to by b. The magnitudes of a and b must not exceed 8. + * Performs {r = a * b} + * On output, r will have magnitude 1, but won't be normalized. + */ static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); -/** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. - * The output magnitude is 1 (but not guaranteed to be normalized). */ +/** Square a field element. + * + * On input, a must be a valid field element; r does not need to be initialized. The magnitude + * of a must not exceed 8. + * Performs {r = a**2} + * On output, r will have magnitude 1, but won't be normalized. + */ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); -/** If a has a square root, it is computed in r and 1 is returned. If a does not - * have a square root, the root of its negation is computed and 0 is returned. - * The input's magnitude can be at most 8. The output magnitude is 1 (but not - * guaranteed to be normalized). The result in r will always be a square - * itself. */ -static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); +/** Compute a square root of a field element. + * + * On input, a must be a valid field element with magnitude<=8; r need not be initialized. + * If sqrt(a) exists, performs {r = sqrt(a)} and returns 1. + * Otherwise, sqrt(-a) exists. The function performs {r = sqrt(-a)} and returns 0. + * The resulting value represented by r will be a square itself. + * Variables r and a must not point to the same object. + * On output, r will have magnitude 1 but will not be normalized. + */ +static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a); -/** Checks whether a field element is a quadratic residue. */ -static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); - -/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be - * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ +/** Compute the modular inverse of a field element. + * + * On input, a must be a valid field element; r need not be initialized. + * Performs {r = a**(p-2)} (which maps 0 to 0, and every other element to its + * inverse). + * On output, r will have magnitude (a.magnitude != 0) and be normalized. + */ static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); -/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ +/** Compute the modular inverse of a field element, without constant-time guarantee. + * + * Behaves identically to secp256k1_fe_inv, but is not constant-time in a. + */ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); -/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be - * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and - * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); - -/** Convert a field element to the storage type. */ +/** Convert a field element to secp256k1_fe_storage. + * + * On input, a must be a valid normalized field element. + * Performs {r = a}. + */ static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); -/** Convert a field element back from the storage type. */ +/** Convert a field element back from secp256k1_fe_storage. + * + * On input, r need not be initialized. + * Performs {r = a}. + * On output, r will be normalized and will have magnitude 1. + */ static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ +/** Conditionally move a field element in constant time. + * + * On input, both r and a must be valid field elements. Flag must be 0 or 1. + * Performs {r = flag ? a : r}. + * + * On output, r's magnitude will be the maximum of both input magnitudes. + * It will be normalized if and only if both inputs were normalized. + */ static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); -#endif +/** Halve the value of a field element modulo the field prime in constant-time. + * + * On input, r must be a valid field element. + * On output, r will be normalized and have magnitude floor(m/2) + 1 where m is + * the magnitude of r on input. + */ +static void secp256k1_fe_half(secp256k1_fe *r); + +/** Sets r to a field element with magnitude m, normalized if (and only if) m==0. + * The value is chosen so that it is likely to trigger edge cases related to + * internal overflows. */ +static void secp256k1_fe_get_bounds(secp256k1_fe *r, int m); + +/** Determine whether a is a square (modulo p). + * + * On input, a must be a valid field element. + */ +static int secp256k1_fe_is_square_var(const secp256k1_fe *a); + +/** Check invariants on a field element (no-op unless VERIFY is enabled). */ +static void secp256k1_fe_verify(const secp256k1_fe *a); +#define SECP256K1_FE_VERIFY(a) secp256k1_fe_verify(a) + +/** Check that magnitude of a is at most m (no-op unless VERIFY is enabled). */ +static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m); +#define SECP256K1_FE_VERIFY_MAGNITUDE(a, m) secp256k1_fe_verify_magnitude(a, m) + +#endif /* SECP256K1_FIELD_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/field_10x26.h b/crypto/secp256k1/libsecp256k1/src/field_10x26.h index 61ee1e0965..203c10167c 100644 --- a/crypto/secp256k1/libsecp256k1/src/field_10x26.h +++ b/crypto/secp256k1/libsecp256k1/src/field_10x26.h @@ -1,21 +1,36 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_FIELD_REPR_ -#define _SECP256K1_FIELD_REPR_ +#ifndef SECP256K1_FIELD_REPR_H +#define SECP256K1_FIELD_REPR_H #include +/** This field implementation represents the value as 10 uint32_t limbs in base + * 2^26. */ typedef struct { - /* X = sum(i=0..9, elem[i]*2^26) mod n */ + /* A field element f represents the sum(i=0..9, f.n[i] << (i*26)) mod p, + * where p is the field modulus, 2^256 - 2^32 - 977. + * + * The individual limbs f.n[i] can exceed 2^26; the field's magnitude roughly + * corresponds to how much excess is allowed. The value + * sum(i=0..9, f.n[i] << (i*26)) may exceed p, unless the field element is + * normalized. */ uint32_t n[10]; -#ifdef VERIFY - int magnitude; - int normalized; -#endif + /* + * Magnitude m requires: + * n[i] <= 2 * m * (2^26 - 1) for i=0..8 + * n[9] <= 2 * m * (2^22 - 1) + * + * Normalized requires: + * n[i] <= (2^26 - 1) for i=0..8 + * sum(i=0..9, n[i] << (i*26)) < p + * (together these imply n[9] <= 2^22 - 1) + */ + SECP256K1_FE_VERIFY_FIELDS } secp256k1_fe; /* Unpacks a constant into a overlapping multi-limbed FE element. */ @@ -32,16 +47,11 @@ typedef struct { (((uint32_t)d7) >> 10) \ } -#ifdef VERIFY -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} -#else -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} -#endif - typedef struct { uint32_t n[8]; } secp256k1_fe_storage; #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} #define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] -#endif + +#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/field_10x26_impl.h b/crypto/secp256k1/libsecp256k1/src/field_10x26_impl.h index 5fb092f1be..ea14c27318 100644 --- a/crypto/secp256k1/libsecp256k1/src/field_10x26_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/field_10x26_impl.h @@ -1,46 +1,56 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_FIELD_REPR_IMPL_H_ -#define _SECP256K1_FIELD_REPR_IMPL_H_ +#ifndef SECP256K1_FIELD_REPR_IMPL_H +#define SECP256K1_FIELD_REPR_IMPL_H +#include "checkmem.h" #include "util.h" -#include "num.h" #include "field.h" +#include "modinv32_impl.h" #ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe *a) { +static void secp256k1_fe_impl_verify(const secp256k1_fe *a) { const uint32_t *d = a->n; - int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; - r &= (d[0] <= 0x3FFFFFFUL * m); - r &= (d[1] <= 0x3FFFFFFUL * m); - r &= (d[2] <= 0x3FFFFFFUL * m); - r &= (d[3] <= 0x3FFFFFFUL * m); - r &= (d[4] <= 0x3FFFFFFUL * m); - r &= (d[5] <= 0x3FFFFFFUL * m); - r &= (d[6] <= 0x3FFFFFFUL * m); - r &= (d[7] <= 0x3FFFFFFUL * m); - r &= (d[8] <= 0x3FFFFFFUL * m); - r &= (d[9] <= 0x03FFFFFUL * m); - r &= (a->magnitude >= 0); - r &= (a->magnitude <= 32); + int m = a->normalized ? 1 : 2 * a->magnitude; + VERIFY_CHECK(d[0] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[1] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[2] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[3] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[4] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[5] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[6] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[7] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[8] <= 0x3FFFFFFUL * m); + VERIFY_CHECK(d[9] <= 0x03FFFFFUL * m); if (a->normalized) { - r &= (a->magnitude <= 1); - if (r && (d[9] == 0x03FFFFFUL)) { + if (d[9] == 0x03FFFFFUL) { uint32_t mid = d[8] & d[7] & d[6] & d[5] & d[4] & d[3] & d[2]; if (mid == 0x3FFFFFFUL) { - r &= ((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL); + VERIFY_CHECK((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL); } } } - VERIFY_CHECK(r == 1); } #endif -static void secp256k1_fe_normalize(secp256k1_fe *r) { +static void secp256k1_fe_impl_get_bounds(secp256k1_fe *r, int m) { + r->n[0] = 0x3FFFFFFUL * 2 * m; + r->n[1] = 0x3FFFFFFUL * 2 * m; + r->n[2] = 0x3FFFFFFUL * 2 * m; + r->n[3] = 0x3FFFFFFUL * 2 * m; + r->n[4] = 0x3FFFFFFUL * 2 * m; + r->n[5] = 0x3FFFFFFUL * 2 * m; + r->n[6] = 0x3FFFFFFUL * 2 * m; + r->n[7] = 0x3FFFFFFUL * 2 * m; + r->n[8] = 0x3FFFFFFUL * 2 * m; + r->n[9] = 0x03FFFFFUL * 2 * m; +} + +static void secp256k1_fe_impl_normalize(secp256k1_fe *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -87,15 +97,9 @@ static void secp256k1_fe_normalize(secp256k1_fe *r) { r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif } -static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { +static void secp256k1_fe_impl_normalize_weak(secp256k1_fe *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -119,14 +123,9 @@ static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - secp256k1_fe_verify(r); -#endif } -static void secp256k1_fe_normalize_var(secp256k1_fe *r) { +static void secp256k1_fe_impl_normalize_var(secp256k1_fe *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -174,15 +173,9 @@ static void secp256k1_fe_normalize_var(secp256k1_fe *r) { r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif } -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { +static int secp256k1_fe_impl_normalizes_to_zero(const secp256k1_fe *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -211,7 +204,7 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { return (z0 == 0) | (z1 == 0x3FFFFFFUL); } -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { +static int secp256k1_fe_impl_normalizes_to_zero_var(const secp256k1_fe *r) { uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; uint32_t z0, z1; uint32_t x; @@ -263,52 +256,22 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { return (z0 == 0) | (z1 == 0x3FFFFFFUL); } -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_impl_set_int(secp256k1_fe *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif } -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { +SECP256K1_INLINE static int secp256k1_fe_impl_is_zero(const secp256k1_fe *a) { const uint32_t *t = a->n; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; } -SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif +SECP256K1_INLINE static int secp256k1_fe_impl_is_odd(const secp256k1_fe *a) { return a->n[0] & 1; } -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { +static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { int i; -#ifdef VERIFY - a->magnitude = 0; - a->normalized = 1; -#endif - for (i=0; i<10; i++) { - a->n[i] = 0; - } -} - -static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { - int i; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - VERIFY_CHECK(b->normalized); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); -#endif for (i = 9; i >= 0; i--) { if (a->n[i] > b->n[i]) { return 1; @@ -320,53 +283,69 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { return 0; } -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { - int i; - r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; - r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; - for (i=0; i<32; i++) { - int j; - for (j=0; j<4; j++) { - int limb = (8*i+2*j)/26; - int shift = (8*i+2*j)%26; - r->n[limb] |= (uint32_t)((a[31-i] >> (2*j)) & 0x3) << shift; - } - } - if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) { - return 0; - } -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif - return 1; +static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a) { + r->n[0] = (uint32_t)a[31] | ((uint32_t)a[30] << 8) | ((uint32_t)a[29] << 16) | ((uint32_t)(a[28] & 0x3) << 24); + r->n[1] = (uint32_t)((a[28] >> 2) & 0x3f) | ((uint32_t)a[27] << 6) | ((uint32_t)a[26] << 14) | ((uint32_t)(a[25] & 0xf) << 22); + r->n[2] = (uint32_t)((a[25] >> 4) & 0xf) | ((uint32_t)a[24] << 4) | ((uint32_t)a[23] << 12) | ((uint32_t)(a[22] & 0x3f) << 20); + r->n[3] = (uint32_t)((a[22] >> 6) & 0x3) | ((uint32_t)a[21] << 2) | ((uint32_t)a[20] << 10) | ((uint32_t)a[19] << 18); + r->n[4] = (uint32_t)a[18] | ((uint32_t)a[17] << 8) | ((uint32_t)a[16] << 16) | ((uint32_t)(a[15] & 0x3) << 24); + r->n[5] = (uint32_t)((a[15] >> 2) & 0x3f) | ((uint32_t)a[14] << 6) | ((uint32_t)a[13] << 14) | ((uint32_t)(a[12] & 0xf) << 22); + r->n[6] = (uint32_t)((a[12] >> 4) & 0xf) | ((uint32_t)a[11] << 4) | ((uint32_t)a[10] << 12) | ((uint32_t)(a[9] & 0x3f) << 20); + r->n[7] = (uint32_t)((a[9] >> 6) & 0x3) | ((uint32_t)a[8] << 2) | ((uint32_t)a[7] << 10) | ((uint32_t)a[6] << 18); + r->n[8] = (uint32_t)a[5] | ((uint32_t)a[4] << 8) | ((uint32_t)a[3] << 16) | ((uint32_t)(a[2] & 0x3) << 24); + r->n[9] = (uint32_t)((a[2] >> 2) & 0x3f) | ((uint32_t)a[1] << 6) | ((uint32_t)a[0] << 14); +} + +static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a) { + secp256k1_fe_impl_set_b32_mod(r, a); + return !((r->n[9] == 0x3FFFFFUL) & ((r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL) & ((r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); } /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { - int i; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - for (i=0; i<32; i++) { - int j; - int c = 0; - for (j=0; j<4; j++) { - int limb = (8*i+2*j)/26; - int shift = (8*i+2*j)%26; - c |= ((a->n[limb] >> shift) & 0x3) << (2 * j); - } - r[31-i] = c; - } +static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) { + r[0] = (a->n[9] >> 14) & 0xff; + r[1] = (a->n[9] >> 6) & 0xff; + r[2] = ((a->n[9] & 0x3F) << 2) | ((a->n[8] >> 24) & 0x3); + r[3] = (a->n[8] >> 16) & 0xff; + r[4] = (a->n[8] >> 8) & 0xff; + r[5] = a->n[8] & 0xff; + r[6] = (a->n[7] >> 18) & 0xff; + r[7] = (a->n[7] >> 10) & 0xff; + r[8] = (a->n[7] >> 2) & 0xff; + r[9] = ((a->n[7] & 0x3) << 6) | ((a->n[6] >> 20) & 0x3f); + r[10] = (a->n[6] >> 12) & 0xff; + r[11] = (a->n[6] >> 4) & 0xff; + r[12] = ((a->n[6] & 0xf) << 4) | ((a->n[5] >> 22) & 0xf); + r[13] = (a->n[5] >> 14) & 0xff; + r[14] = (a->n[5] >> 6) & 0xff; + r[15] = ((a->n[5] & 0x3f) << 2) | ((a->n[4] >> 24) & 0x3); + r[16] = (a->n[4] >> 16) & 0xff; + r[17] = (a->n[4] >> 8) & 0xff; + r[18] = a->n[4] & 0xff; + r[19] = (a->n[3] >> 18) & 0xff; + r[20] = (a->n[3] >> 10) & 0xff; + r[21] = (a->n[3] >> 2) & 0xff; + r[22] = ((a->n[3] & 0x3) << 6) | ((a->n[2] >> 20) & 0x3f); + r[23] = (a->n[2] >> 12) & 0xff; + r[24] = (a->n[2] >> 4) & 0xff; + r[25] = ((a->n[2] & 0xf) << 4) | ((a->n[1] >> 22) & 0xf); + r[26] = (a->n[1] >> 14) & 0xff; + r[27] = (a->n[1] >> 6) & 0xff; + r[28] = ((a->n[1] & 0x3f) << 2) | ((a->n[0] >> 24) & 0x3); + r[29] = (a->n[0] >> 16) & 0xff; + r[30] = (a->n[0] >> 8) & 0xff; + r[31] = a->n[0] & 0xff; } -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= m); - secp256k1_fe_verify(a); -#endif +SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) { + /* For all legal values of m (0..31), the following properties hold: */ + VERIFY_CHECK(0x3FFFC2FUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); + VERIFY_CHECK(0x3FFFFBFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); + VERIFY_CHECK(0x3FFFFFFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); + VERIFY_CHECK(0x03FFFFFUL * 2 * (m + 1) >= 0x03FFFFFUL * 2 * m); + + /* Due to the properties above, the left hand in the subtractions below is never less than + * the right hand. */ r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0]; r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1]; r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2]; @@ -377,14 +356,9 @@ SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7]; r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8]; r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9]; -#ifdef VERIFY - r->magnitude = m + 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a) { r->n[0] *= a; r->n[1] *= a; r->n[2] *= a; @@ -395,17 +369,9 @@ SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { r->n[7] *= a; r->n[8] *= a; r->n[9] *= a; -#ifdef VERIFY - r->magnitude *= a; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - secp256k1_fe_verify(a); -#endif +SECP256K1_INLINE static void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a) { r->n[0] += a->n[0]; r->n[1] += a->n[1]; r->n[2] += a->n[2]; @@ -416,11 +382,10 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_f r->n[7] += a->n[7]; r->n[8] += a->n[8]; r->n[9] += a->n[9]; -#ifdef VERIFY - r->magnitude += a->magnitude; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif +} + +SECP256K1_INLINE static void secp256k1_fe_impl_add_int(secp256k1_fe *r, int a) { + r->n[0] += a; } #if defined(USE_EXTERNAL_ASM) @@ -431,11 +396,7 @@ void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a); #else -#ifdef VERIFY #define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) -#else -#define VERIFY_BITS(x, n) do { } while(0) -#endif SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) { uint64_t c, d; @@ -465,7 +426,8 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t VERIFY_BITS(b[9], 26); /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. - * px is a shorthand for sum(a[i]*b[x-i], i=0..x). + * for 0 <= x <= 9, px is a shorthand for sum(a[i]*b[x-i], i=0..x). + * for 9 <= x <= 18, px is a shorthand for sum(a[i]*b[x-i], i=(x-9)..9) * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. */ @@ -1041,38 +1003,19 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t } #endif -static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - VERIFY_CHECK(b->magnitude <= 8); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); - VERIFY_CHECK(r != b); -#endif +SECP256K1_INLINE static void secp256k1_fe_impl_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { secp256k1_fe_mul_inner(r->n, a->n, b->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - secp256k1_fe_verify(a); -#endif +SECP256K1_INLINE static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a) { secp256k1_fe_sqr_inner(r->n, a->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { +SECP256K1_INLINE static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { uint32_t mask0, mask1; - mask0 = flag + ~((uint32_t)0); + volatile int vflag = flag; + SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); + mask0 = vflag + ~((uint32_t)0); mask1 = ~mask0; r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); @@ -1084,17 +1027,78 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_ r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); -#ifdef VERIFY - if (a->magnitude > r->magnitude) { - r->magnitude = a->magnitude; - } - r->normalized &= a->normalized; -#endif +} + +static SECP256K1_INLINE void secp256k1_fe_impl_half(secp256k1_fe *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + uint32_t one = (uint32_t)1; + uint32_t mask = -(t0 & one) >> 6; + + /* Bounds analysis (over the rationals). + * + * Let m = r->magnitude + * C = 0x3FFFFFFUL * 2 + * D = 0x03FFFFFUL * 2 + * + * Initial bounds: t0..t8 <= C * m + * t9 <= D * m + */ + + t0 += 0x3FFFC2FUL & mask; + t1 += 0x3FFFFBFUL & mask; + t2 += mask; + t3 += mask; + t4 += mask; + t5 += mask; + t6 += mask; + t7 += mask; + t8 += mask; + t9 += mask >> 4; + + VERIFY_CHECK((t0 & one) == 0); + + /* t0..t8: added <= C/2 + * t9: added <= D/2 + * + * Current bounds: t0..t8 <= C * (m + 1/2) + * t9 <= D * (m + 1/2) + */ + + r->n[0] = (t0 >> 1) + ((t1 & one) << 25); + r->n[1] = (t1 >> 1) + ((t2 & one) << 25); + r->n[2] = (t2 >> 1) + ((t3 & one) << 25); + r->n[3] = (t3 >> 1) + ((t4 & one) << 25); + r->n[4] = (t4 >> 1) + ((t5 & one) << 25); + r->n[5] = (t5 >> 1) + ((t6 & one) << 25); + r->n[6] = (t6 >> 1) + ((t7 & one) << 25); + r->n[7] = (t7 >> 1) + ((t8 & one) << 25); + r->n[8] = (t8 >> 1) + ((t9 & one) << 25); + r->n[9] = (t9 >> 1); + + /* t0..t8: shifted right and added <= C/4 + 1/2 + * t9: shifted right + * + * Current bounds: t0..t8 <= C * (m/2 + 1/2) + * t9 <= D * (m/2 + 1/4) + * + * Therefore the output magnitude (M) has to be set such that: + * t0..t8: C * M >= C * (m/2 + 1/2) + * t9: D * M >= D * (m/2 + 1/4) + * + * It suffices for all limbs that, for any input magnitude m: + * M >= m/2 + 1/2 + * + * and since we want the smallest such integer value for M: + * M == floor(m/2) + 1 + */ } static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { uint32_t mask0, mask1; - mask0 = flag + ~((uint32_t)0); + volatile int vflag = flag; + SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); + mask0 = vflag + ~((uint32_t)0); mask1 = ~mask0; r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); @@ -1106,10 +1110,7 @@ static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); } -static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); -#endif +static void secp256k1_fe_impl_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { r->n[0] = a->n[0] | a->n[1] << 26; r->n[1] = a->n[1] >> 6 | a->n[2] << 20; r->n[2] = a->n[2] >> 12 | a->n[3] << 14; @@ -1120,7 +1121,7 @@ static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe r->n[7] = a->n[8] >> 16 | a->n[9] << 10; } -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { +static SECP256K1_INLINE void secp256k1_fe_impl_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { r->n[0] = a->n[0] & 0x3FFFFFFUL; r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL); r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL); @@ -1131,10 +1132,101 @@ static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const se r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL); r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL); r->n[9] = a->n[7] >> 10; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; -#endif } -#endif +static void secp256k1_fe_from_signed30(secp256k1_fe *r, const secp256k1_modinv32_signed30 *a) { + const uint32_t M26 = UINT32_MAX >> 6; + const uint32_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4], + a5 = a->v[5], a6 = a->v[6], a7 = a->v[7], a8 = a->v[8]; + + /* The output from secp256k1_modinv32{_var} should be normalized to range [0,modulus), and + * have limbs in [0,2^30). The modulus is < 2^256, so the top limb must be below 2^(256-30*8). + */ + VERIFY_CHECK(a0 >> 30 == 0); + VERIFY_CHECK(a1 >> 30 == 0); + VERIFY_CHECK(a2 >> 30 == 0); + VERIFY_CHECK(a3 >> 30 == 0); + VERIFY_CHECK(a4 >> 30 == 0); + VERIFY_CHECK(a5 >> 30 == 0); + VERIFY_CHECK(a6 >> 30 == 0); + VERIFY_CHECK(a7 >> 30 == 0); + VERIFY_CHECK(a8 >> 16 == 0); + + r->n[0] = a0 & M26; + r->n[1] = (a0 >> 26 | a1 << 4) & M26; + r->n[2] = (a1 >> 22 | a2 << 8) & M26; + r->n[3] = (a2 >> 18 | a3 << 12) & M26; + r->n[4] = (a3 >> 14 | a4 << 16) & M26; + r->n[5] = (a4 >> 10 | a5 << 20) & M26; + r->n[6] = (a5 >> 6 | a6 << 24) & M26; + r->n[7] = (a6 >> 2 ) & M26; + r->n[8] = (a6 >> 28 | a7 << 2) & M26; + r->n[9] = (a7 >> 24 | a8 << 6); +} + +static void secp256k1_fe_to_signed30(secp256k1_modinv32_signed30 *r, const secp256k1_fe *a) { + const uint32_t M30 = UINT32_MAX >> 2; + const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4], + a5 = a->n[5], a6 = a->n[6], a7 = a->n[7], a8 = a->n[8], a9 = a->n[9]; + + r->v[0] = (a0 | a1 << 26) & M30; + r->v[1] = (a1 >> 4 | a2 << 22) & M30; + r->v[2] = (a2 >> 8 | a3 << 18) & M30; + r->v[3] = (a3 >> 12 | a4 << 14) & M30; + r->v[4] = (a4 >> 16 | a5 << 10) & M30; + r->v[5] = (a5 >> 20 | a6 << 6) & M30; + r->v[6] = (a6 >> 24 | a7 << 2 + | a8 << 28) & M30; + r->v[7] = (a8 >> 2 | a9 << 24) & M30; + r->v[8] = a9 >> 6; +} + +static const secp256k1_modinv32_modinfo secp256k1_const_modinfo_fe = { + {{-0x3D1, -4, 0, 0, 0, 0, 0, 0, 65536}}, + 0x2DDACACFL +}; + +static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp = *x; + secp256k1_modinv32_signed30 s; + + secp256k1_fe_normalize(&tmp); + secp256k1_fe_to_signed30(&s, &tmp); + secp256k1_modinv32(&s, &secp256k1_const_modinfo_fe); + secp256k1_fe_from_signed30(r, &s); +} + +static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp = *x; + secp256k1_modinv32_signed30 s; + + secp256k1_fe_normalize_var(&tmp); + secp256k1_fe_to_signed30(&s, &tmp); + secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_fe); + secp256k1_fe_from_signed30(r, &s); +} + +static int secp256k1_fe_impl_is_square_var(const secp256k1_fe *x) { + secp256k1_fe tmp; + secp256k1_modinv32_signed30 s; + int jac, ret; + + tmp = *x; + secp256k1_fe_normalize_var(&tmp); + /* secp256k1_jacobi32_maybe_var cannot deal with input 0. */ + if (secp256k1_fe_is_zero(&tmp)) return 1; + secp256k1_fe_to_signed30(&s, &tmp); + jac = secp256k1_jacobi32_maybe_var(&s, &secp256k1_const_modinfo_fe); + if (jac == 0) { + /* secp256k1_jacobi32_maybe_var failed to compute the Jacobi symbol. Fall back + * to computing a square root. This should be extremely rare with random + * input (except in VERIFY mode, where a lower iteration count is used). */ + secp256k1_fe dummy; + ret = secp256k1_fe_sqrt(&dummy, &tmp); + } else { + ret = jac >= 0; + } + return ret; +} + +#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/field_5x52.h b/crypto/secp256k1/libsecp256k1/src/field_5x52.h index 8e69a560dc..f20c246fdd 100644 --- a/crypto/secp256k1/libsecp256k1/src/field_5x52.h +++ b/crypto/secp256k1/libsecp256k1/src/field_5x52.h @@ -1,21 +1,36 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_FIELD_REPR_ -#define _SECP256K1_FIELD_REPR_ +#ifndef SECP256K1_FIELD_REPR_H +#define SECP256K1_FIELD_REPR_H #include +/** This field implementation represents the value as 5 uint64_t limbs in base + * 2^52. */ typedef struct { - /* X = sum(i=0..4, elem[i]*2^52) mod n */ + /* A field element f represents the sum(i=0..4, f.n[i] << (i*52)) mod p, + * where p is the field modulus, 2^256 - 2^32 - 977. + * + * The individual limbs f.n[i] can exceed 2^52; the field's magnitude roughly + * corresponds to how much excess is allowed. The value + * sum(i=0..4, f.n[i] << (i*52)) may exceed p, unless the field element is + * normalized. */ uint64_t n[5]; -#ifdef VERIFY - int magnitude; - int normalized; -#endif + /* + * Magnitude m requires: + * n[i] <= 2 * m * (2^52 - 1) for i=0..3 + * n[4] <= 2 * m * (2^48 - 1) + * + * Normalized requires: + * n[i] <= (2^52 - 1) for i=0..3 + * sum(i=0..4, n[i] << (i*52)) < p + * (together these imply n[4] <= 2^48 - 1) + */ + SECP256K1_FE_VERIFY_FIELDS } secp256k1_fe; /* Unpacks a constant into a overlapping multi-limbed FE element. */ @@ -27,12 +42,6 @@ typedef struct { ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ } -#ifdef VERIFY -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} -#else -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} -#endif - typedef struct { uint64_t n[4]; } secp256k1_fe_storage; @@ -44,4 +53,10 @@ typedef struct { (d6) | (((uint64_t)(d7)) << 32) \ }} -#endif +#define SECP256K1_FE_STORAGE_CONST_GET(d) \ + (uint32_t)(d.n[3] >> 32), (uint32_t)d.n[3], \ + (uint32_t)(d.n[2] >> 32), (uint32_t)d.n[2], \ + (uint32_t)(d.n[1] >> 32), (uint32_t)d.n[1], \ + (uint32_t)(d.n[0] >> 32), (uint32_t)d.n[0] + +#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/field_5x52_asm_impl.h b/crypto/secp256k1/libsecp256k1/src/field_5x52_asm_impl.h deleted file mode 100644 index 98cc004bf0..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/field_5x52_asm_impl.h +++ /dev/null @@ -1,502 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -/** - * Changelog: - * - March 2013, Diederik Huys: original version - * - November 2014, Pieter Wuille: updated to use Peter Dettman's parallel multiplication algorithm - * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly - */ - -#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_ -#define _SECP256K1_FIELD_INNER5X52_IMPL_H_ - -SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { -/** - * Registers: rdx:rax = multiplication accumulator - * r9:r8 = c - * r15:rcx = d - * r10-r14 = a0-a4 - * rbx = b - * rdi = r - * rsi = a / t? - */ - uint64_t tmp1, tmp2, tmp3; -__asm__ __volatile__( - "movq 0(%%rsi),%%r10\n" - "movq 8(%%rsi),%%r11\n" - "movq 16(%%rsi),%%r12\n" - "movq 24(%%rsi),%%r13\n" - "movq 32(%%rsi),%%r14\n" - - /* d += a3 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r13\n" - "movq %%rax,%%rcx\n" - "movq %%rdx,%%r15\n" - /* d += a2 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a1 * b2 */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d = a0 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r10\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* c = a4 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r14\n" - "movq %%rax,%%r8\n" - "movq %%rdx,%%r9\n" - /* d += (c & M) * R */ - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* c >>= 52 (%%r8 only) */ - "shrdq $52,%%r9,%%r8\n" - /* t3 (tmp1) = d & M */ - "movq %%rcx,%%rsi\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rsi\n" - "movq %%rsi,%q1\n" - /* d >>= 52 */ - "shrdq $52,%%r15,%%rcx\n" - "xorq %%r15,%%r15\n" - /* d += a4 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a3 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a2 * b2 */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a1 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a0 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r10\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += c * R */ - "movq %%r8,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* t4 = d & M (%%rsi) */ - "movq %%rcx,%%rsi\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rsi\n" - /* d >>= 52 */ - "shrdq $52,%%r15,%%rcx\n" - "xorq %%r15,%%r15\n" - /* tx = t4 >> 48 (tmp3) */ - "movq %%rsi,%%rax\n" - "shrq $48,%%rax\n" - "movq %%rax,%q3\n" - /* t4 &= (M >> 4) (tmp2) */ - "movq $0xffffffffffff,%%rax\n" - "andq %%rax,%%rsi\n" - "movq %%rsi,%q2\n" - /* c = a0 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r10\n" - "movq %%rax,%%r8\n" - "movq %%rdx,%%r9\n" - /* d += a4 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a3 * b2 */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a2 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a1 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* u0 = d & M (%%rsi) */ - "movq %%rcx,%%rsi\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rsi\n" - /* d >>= 52 */ - "shrdq $52,%%r15,%%rcx\n" - "xorq %%r15,%%r15\n" - /* u0 = (u0 << 4) | tx (%%rsi) */ - "shlq $4,%%rsi\n" - "movq %q3,%%rax\n" - "orq %%rax,%%rsi\n" - /* c += u0 * (R >> 4) */ - "movq $0x1000003d1,%%rax\n" - "mulq %%rsi\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* r[0] = c & M */ - "movq %%r8,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq %%rax,0(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += a1 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* c += a0 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r10\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d += a4 * b2 */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a3 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a2 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* c += (d & M) * R */ - "movq %%rcx,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d >>= 52 */ - "shrdq $52,%%r15,%%rcx\n" - "xorq %%r15,%%r15\n" - /* r[1] = c & M */ - "movq %%r8,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq %%rax,8(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += a2 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* c += a1 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* c += a0 * b2 (last use of %%r10 = a0) */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r10\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* fetch t3 (%%r10, overwrites a0), t4 (%%rsi) */ - "movq %q2,%%rsi\n" - "movq %q1,%%r10\n" - /* d += a4 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a3 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* c += (d & M) * R */ - "movq %%rcx,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d >>= 52 (%%rcx only) */ - "shrdq $52,%%r15,%%rcx\n" - /* r[2] = c & M */ - "movq %%r8,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq %%rax,16(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += t3 */ - "addq %%r10,%%r8\n" - /* c += d * R */ - "movq %%rcx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* r[3] = c & M */ - "movq %%r8,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq %%rax,24(%%rdi)\n" - /* c >>= 52 (%%r8 only) */ - "shrdq $52,%%r9,%%r8\n" - /* c += t4 (%%r8 only) */ - "addq %%rsi,%%r8\n" - /* r[4] = c */ - "movq %%r8,32(%%rdi)\n" -: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) -: "b"(b), "D"(r) -: "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" -); -} - -SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { -/** - * Registers: rdx:rax = multiplication accumulator - * r9:r8 = c - * rcx:rbx = d - * r10-r14 = a0-a4 - * r15 = M (0xfffffffffffff) - * rdi = r - * rsi = a / t? - */ - uint64_t tmp1, tmp2, tmp3; -__asm__ __volatile__( - "movq 0(%%rsi),%%r10\n" - "movq 8(%%rsi),%%r11\n" - "movq 16(%%rsi),%%r12\n" - "movq 24(%%rsi),%%r13\n" - "movq 32(%%rsi),%%r14\n" - "movq $0xfffffffffffff,%%r15\n" - - /* d = (a0*2) * a3 */ - "leaq (%%r10,%%r10,1),%%rax\n" - "mulq %%r13\n" - "movq %%rax,%%rbx\n" - "movq %%rdx,%%rcx\n" - /* d += (a1*2) * a2 */ - "leaq (%%r11,%%r11,1),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* c = a4 * a4 */ - "movq %%r14,%%rax\n" - "mulq %%r14\n" - "movq %%rax,%%r8\n" - "movq %%rdx,%%r9\n" - /* d += (c & M) * R */ - "andq %%r15,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* c >>= 52 (%%r8 only) */ - "shrdq $52,%%r9,%%r8\n" - /* t3 (tmp1) = d & M */ - "movq %%rbx,%%rsi\n" - "andq %%r15,%%rsi\n" - "movq %%rsi,%q1\n" - /* d >>= 52 */ - "shrdq $52,%%rcx,%%rbx\n" - "xorq %%rcx,%%rcx\n" - /* a4 *= 2 */ - "addq %%r14,%%r14\n" - /* d += a0 * a4 */ - "movq %%r10,%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d+= (a1*2) * a3 */ - "leaq (%%r11,%%r11,1),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d += a2 * a2 */ - "movq %%r12,%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d += c * R */ - "movq %%r8,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* t4 = d & M (%%rsi) */ - "movq %%rbx,%%rsi\n" - "andq %%r15,%%rsi\n" - /* d >>= 52 */ - "shrdq $52,%%rcx,%%rbx\n" - "xorq %%rcx,%%rcx\n" - /* tx = t4 >> 48 (tmp3) */ - "movq %%rsi,%%rax\n" - "shrq $48,%%rax\n" - "movq %%rax,%q3\n" - /* t4 &= (M >> 4) (tmp2) */ - "movq $0xffffffffffff,%%rax\n" - "andq %%rax,%%rsi\n" - "movq %%rsi,%q2\n" - /* c = a0 * a0 */ - "movq %%r10,%%rax\n" - "mulq %%r10\n" - "movq %%rax,%%r8\n" - "movq %%rdx,%%r9\n" - /* d += a1 * a4 */ - "movq %%r11,%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d += (a2*2) * a3 */ - "leaq (%%r12,%%r12,1),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* u0 = d & M (%%rsi) */ - "movq %%rbx,%%rsi\n" - "andq %%r15,%%rsi\n" - /* d >>= 52 */ - "shrdq $52,%%rcx,%%rbx\n" - "xorq %%rcx,%%rcx\n" - /* u0 = (u0 << 4) | tx (%%rsi) */ - "shlq $4,%%rsi\n" - "movq %q3,%%rax\n" - "orq %%rax,%%rsi\n" - /* c += u0 * (R >> 4) */ - "movq $0x1000003d1,%%rax\n" - "mulq %%rsi\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* r[0] = c & M */ - "movq %%r8,%%rax\n" - "andq %%r15,%%rax\n" - "movq %%rax,0(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* a0 *= 2 */ - "addq %%r10,%%r10\n" - /* c += a0 * a1 */ - "movq %%r10,%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d += a2 * a4 */ - "movq %%r12,%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d += a3 * a3 */ - "movq %%r13,%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* c += (d & M) * R */ - "movq %%rbx,%%rax\n" - "andq %%r15,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d >>= 52 */ - "shrdq $52,%%rcx,%%rbx\n" - "xorq %%rcx,%%rcx\n" - /* r[1] = c & M */ - "movq %%r8,%%rax\n" - "andq %%r15,%%rax\n" - "movq %%rax,8(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += a0 * a2 (last use of %%r10) */ - "movq %%r10,%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* fetch t3 (%%r10, overwrites a0),t4 (%%rsi) */ - "movq %q2,%%rsi\n" - "movq %q1,%%r10\n" - /* c += a1 * a1 */ - "movq %%r11,%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d += a3 * a4 */ - "movq %%r13,%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* c += (d & M) * R */ - "movq %%rbx,%%rax\n" - "andq %%r15,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d >>= 52 (%%rbx only) */ - "shrdq $52,%%rcx,%%rbx\n" - /* r[2] = c & M */ - "movq %%r8,%%rax\n" - "andq %%r15,%%rax\n" - "movq %%rax,16(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += t3 */ - "addq %%r10,%%r8\n" - /* c += d * R */ - "movq %%rbx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* r[3] = c & M */ - "movq %%r8,%%rax\n" - "andq %%r15,%%rax\n" - "movq %%rax,24(%%rdi)\n" - /* c >>= 52 (%%r8 only) */ - "shrdq $52,%%r9,%%r8\n" - /* c += t4 (%%r8 only) */ - "addq %%rsi,%%r8\n" - /* r[4] = c */ - "movq %%r8,32(%%rdi)\n" -: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) -: "D"(r) -: "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" -); -} - -#endif diff --git a/crypto/secp256k1/libsecp256k1/src/field_5x52_impl.h b/crypto/secp256k1/libsecp256k1/src/field_5x52_impl.h index dd88f38c77..46dca6b981 100644 --- a/crypto/secp256k1/libsecp256k1/src/field_5x52_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/field_5x52_impl.h @@ -1,57 +1,46 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_FIELD_REPR_IMPL_H_ -#define _SECP256K1_FIELD_REPR_IMPL_H_ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif +#ifndef SECP256K1_FIELD_REPR_IMPL_H +#define SECP256K1_FIELD_REPR_IMPL_H +#include "checkmem.h" #include "util.h" -#include "num.h" #include "field.h" +#include "modinv64_impl.h" -#if defined(USE_ASM_X86_64) -#include "field_5x52_asm_impl.h" -#else #include "field_5x52_int128_impl.h" -#endif - -/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F, - * represented as 5 uint64_t's in base 2^52. The values are allowed to contain >52 each. In particular, - * each FieldElem has a 'magnitude' associated with it. Internally, a magnitude M means each element - * is at most M*(2^53-1), except the most significant one, which is limited to M*(2^49-1). All operations - * accept any input with magnitude at most M, and have different rules for propagating magnitude to their - * output. - */ #ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe *a) { +static void secp256k1_fe_impl_verify(const secp256k1_fe *a) { const uint64_t *d = a->n; - int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; + int m = a->normalized ? 1 : 2 * a->magnitude; /* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ - r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m); - r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m); - r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m); - r &= (d[3] <= 0xFFFFFFFFFFFFFULL * m); - r &= (d[4] <= 0x0FFFFFFFFFFFFULL * m); - r &= (a->magnitude >= 0); - r &= (a->magnitude <= 2048); + VERIFY_CHECK(d[0] <= 0xFFFFFFFFFFFFFULL * m); + VERIFY_CHECK(d[1] <= 0xFFFFFFFFFFFFFULL * m); + VERIFY_CHECK(d[2] <= 0xFFFFFFFFFFFFFULL * m); + VERIFY_CHECK(d[3] <= 0xFFFFFFFFFFFFFULL * m); + VERIFY_CHECK(d[4] <= 0x0FFFFFFFFFFFFULL * m); if (a->normalized) { - r &= (a->magnitude <= 1); - if (r && (d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) { - r &= (d[0] < 0xFFFFEFFFFFC2FULL); + if ((d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) { + VERIFY_CHECK(d[0] < 0xFFFFEFFFFFC2FULL); } } - VERIFY_CHECK(r == 1); } #endif -static void secp256k1_fe_normalize(secp256k1_fe *r) { +static void secp256k1_fe_impl_get_bounds(secp256k1_fe *r, int m) { + r->n[0] = 0xFFFFFFFFFFFFFULL * 2 * m; + r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * m; + r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * m; + r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * m; + r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * m; +} + +static void secp256k1_fe_impl_normalize(secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ @@ -86,15 +75,9 @@ static void secp256k1_fe_normalize(secp256k1_fe *r) { t4 &= 0x0FFFFFFFFFFFFULL; r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif } -static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { +static void secp256k1_fe_impl_normalize_weak(secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ @@ -111,14 +94,9 @@ static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { VERIFY_CHECK(t4 >> 49 == 0); r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - -#ifdef VERIFY - r->magnitude = 1; - secp256k1_fe_verify(r); -#endif } -static void secp256k1_fe_normalize_var(secp256k1_fe *r) { +static void secp256k1_fe_impl_normalize_var(secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ @@ -154,15 +132,9 @@ static void secp256k1_fe_normalize_var(secp256k1_fe *r) { } r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif } -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { +static int secp256k1_fe_impl_normalizes_to_zero(const secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ @@ -185,7 +157,7 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); } -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { +static int secp256k1_fe_impl_normalizes_to_zero_var(const secp256k1_fe *r) { uint64_t t0, t1, t2, t3, t4; uint64_t z0, z1; uint64_t x; @@ -226,52 +198,22 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); } -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_impl_set_int(secp256k1_fe *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif } -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { +SECP256K1_INLINE static int secp256k1_fe_impl_is_zero(const secp256k1_fe *a) { const uint64_t *t = a->n; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0; } -SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif +SECP256K1_INLINE static int secp256k1_fe_impl_is_odd(const secp256k1_fe *a) { return a->n[0] & 1; } -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { +static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { int i; -#ifdef VERIFY - a->magnitude = 0; - a->normalized = 1; -#endif - for (i=0; i<5; i++) { - a->n[i] = 0; - } -} - -static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { - int i; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - VERIFY_CHECK(b->normalized); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); -#endif for (i = 4; i >= 0; i--) { if (a->n[i] > b->n[i]) { return 1; @@ -283,142 +225,199 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { return 0; } -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { - int i; - r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; - for (i=0; i<32; i++) { - int j; - for (j=0; j<2; j++) { - int limb = (8*i+4*j)/52; - int shift = (8*i+4*j)%52; - r->n[limb] |= (uint64_t)((a[31-i] >> (4*j)) & 0xF) << shift; - } - } - if (r->n[4] == 0x0FFFFFFFFFFFFULL && (r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL && r->n[0] >= 0xFFFFEFFFFFC2FULL) { - return 0; - } -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif - return 1; +static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a) { + r->n[0] = (uint64_t)a[31] + | ((uint64_t)a[30] << 8) + | ((uint64_t)a[29] << 16) + | ((uint64_t)a[28] << 24) + | ((uint64_t)a[27] << 32) + | ((uint64_t)a[26] << 40) + | ((uint64_t)(a[25] & 0xF) << 48); + r->n[1] = (uint64_t)((a[25] >> 4) & 0xF) + | ((uint64_t)a[24] << 4) + | ((uint64_t)a[23] << 12) + | ((uint64_t)a[22] << 20) + | ((uint64_t)a[21] << 28) + | ((uint64_t)a[20] << 36) + | ((uint64_t)a[19] << 44); + r->n[2] = (uint64_t)a[18] + | ((uint64_t)a[17] << 8) + | ((uint64_t)a[16] << 16) + | ((uint64_t)a[15] << 24) + | ((uint64_t)a[14] << 32) + | ((uint64_t)a[13] << 40) + | ((uint64_t)(a[12] & 0xF) << 48); + r->n[3] = (uint64_t)((a[12] >> 4) & 0xF) + | ((uint64_t)a[11] << 4) + | ((uint64_t)a[10] << 12) + | ((uint64_t)a[9] << 20) + | ((uint64_t)a[8] << 28) + | ((uint64_t)a[7] << 36) + | ((uint64_t)a[6] << 44); + r->n[4] = (uint64_t)a[5] + | ((uint64_t)a[4] << 8) + | ((uint64_t)a[3] << 16) + | ((uint64_t)a[2] << 24) + | ((uint64_t)a[1] << 32) + | ((uint64_t)a[0] << 40); +} + +static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a) { + secp256k1_fe_impl_set_b32_mod(r, a); + return !((r->n[4] == 0x0FFFFFFFFFFFFULL) & ((r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL) & (r->n[0] >= 0xFFFFEFFFFFC2FULL)); } /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { - int i; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - for (i=0; i<32; i++) { - int j; - int c = 0; - for (j=0; j<2; j++) { - int limb = (8*i+4*j)/52; - int shift = (8*i+4*j)%52; - c |= ((a->n[limb] >> shift) & 0xF) << (4 * j); - } - r[31-i] = c; - } +static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) { + r[0] = (a->n[4] >> 40) & 0xFF; + r[1] = (a->n[4] >> 32) & 0xFF; + r[2] = (a->n[4] >> 24) & 0xFF; + r[3] = (a->n[4] >> 16) & 0xFF; + r[4] = (a->n[4] >> 8) & 0xFF; + r[5] = a->n[4] & 0xFF; + r[6] = (a->n[3] >> 44) & 0xFF; + r[7] = (a->n[3] >> 36) & 0xFF; + r[8] = (a->n[3] >> 28) & 0xFF; + r[9] = (a->n[3] >> 20) & 0xFF; + r[10] = (a->n[3] >> 12) & 0xFF; + r[11] = (a->n[3] >> 4) & 0xFF; + r[12] = ((a->n[2] >> 48) & 0xF) | ((a->n[3] & 0xF) << 4); + r[13] = (a->n[2] >> 40) & 0xFF; + r[14] = (a->n[2] >> 32) & 0xFF; + r[15] = (a->n[2] >> 24) & 0xFF; + r[16] = (a->n[2] >> 16) & 0xFF; + r[17] = (a->n[2] >> 8) & 0xFF; + r[18] = a->n[2] & 0xFF; + r[19] = (a->n[1] >> 44) & 0xFF; + r[20] = (a->n[1] >> 36) & 0xFF; + r[21] = (a->n[1] >> 28) & 0xFF; + r[22] = (a->n[1] >> 20) & 0xFF; + r[23] = (a->n[1] >> 12) & 0xFF; + r[24] = (a->n[1] >> 4) & 0xFF; + r[25] = ((a->n[0] >> 48) & 0xF) | ((a->n[1] & 0xF) << 4); + r[26] = (a->n[0] >> 40) & 0xFF; + r[27] = (a->n[0] >> 32) & 0xFF; + r[28] = (a->n[0] >> 24) & 0xFF; + r[29] = (a->n[0] >> 16) & 0xFF; + r[30] = (a->n[0] >> 8) & 0xFF; + r[31] = a->n[0] & 0xFF; } -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= m); - secp256k1_fe_verify(a); -#endif +SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) { + /* For all legal values of m (0..31), the following properties hold: */ + VERIFY_CHECK(0xFFFFEFFFFFC2FULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m); + VERIFY_CHECK(0xFFFFFFFFFFFFFULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m); + VERIFY_CHECK(0x0FFFFFFFFFFFFULL * 2 * (m + 1) >= 0x0FFFFFFFFFFFFULL * 2 * m); + + /* Due to the properties above, the left hand in the subtractions below is never less than + * the right hand. */ r->n[0] = 0xFFFFEFFFFFC2FULL * 2 * (m + 1) - a->n[0]; r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[1]; r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[2]; r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[3]; r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4]; -#ifdef VERIFY - r->magnitude = m + 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a) { r->n[0] *= a; r->n[1] *= a; r->n[2] *= a; r->n[3] *= a; r->n[4] *= a; -#ifdef VERIFY - r->magnitude *= a; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - secp256k1_fe_verify(a); -#endif +SECP256K1_INLINE static void secp256k1_fe_impl_add_int(secp256k1_fe *r, int a) { + r->n[0] += a; +} + +SECP256K1_INLINE static void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a) { r->n[0] += a->n[0]; r->n[1] += a->n[1]; r->n[2] += a->n[2]; r->n[3] += a->n[3]; r->n[4] += a->n[4]; -#ifdef VERIFY - r->magnitude += a->magnitude; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - VERIFY_CHECK(b->magnitude <= 8); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); - VERIFY_CHECK(r != b); -#endif +SECP256K1_INLINE static void secp256k1_fe_impl_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { secp256k1_fe_mul_inner(r->n, a->n, b->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - secp256k1_fe_verify(a); -#endif +SECP256K1_INLINE static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a) { secp256k1_fe_sqr_inner(r->n, a->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif } -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { +SECP256K1_INLINE static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { uint64_t mask0, mask1; - mask0 = flag + ~((uint64_t)0); + volatile int vflag = flag; + SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); + mask0 = vflag + ~((uint64_t)0); mask1 = ~mask0; r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); -#ifdef VERIFY - if (a->magnitude > r->magnitude) { - r->magnitude = a->magnitude; - } - r->normalized &= a->normalized; -#endif +} + +static SECP256K1_INLINE void secp256k1_fe_impl_half(secp256k1_fe *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + uint64_t one = (uint64_t)1; + uint64_t mask = -(t0 & one) >> 12; + + /* Bounds analysis (over the rationals). + * + * Let m = r->magnitude + * C = 0xFFFFFFFFFFFFFULL * 2 + * D = 0x0FFFFFFFFFFFFULL * 2 + * + * Initial bounds: t0..t3 <= C * m + * t4 <= D * m + */ + + t0 += 0xFFFFEFFFFFC2FULL & mask; + t1 += mask; + t2 += mask; + t3 += mask; + t4 += mask >> 4; + + VERIFY_CHECK((t0 & one) == 0); + + /* t0..t3: added <= C/2 + * t4: added <= D/2 + * + * Current bounds: t0..t3 <= C * (m + 1/2) + * t4 <= D * (m + 1/2) + */ + + r->n[0] = (t0 >> 1) + ((t1 & one) << 51); + r->n[1] = (t1 >> 1) + ((t2 & one) << 51); + r->n[2] = (t2 >> 1) + ((t3 & one) << 51); + r->n[3] = (t3 >> 1) + ((t4 & one) << 51); + r->n[4] = (t4 >> 1); + + /* t0..t3: shifted right and added <= C/4 + 1/2 + * t4: shifted right + * + * Current bounds: t0..t3 <= C * (m/2 + 1/2) + * t4 <= D * (m/2 + 1/4) + * + * Therefore the output magnitude (M) has to be set such that: + * t0..t3: C * M >= C * (m/2 + 1/2) + * t4: D * M >= D * (m/2 + 1/4) + * + * It suffices for all limbs that, for any input magnitude m: + * M >= m/2 + 1/2 + * + * and since we want the smallest such integer value for M: + * M == floor(m/2) + 1 + */ } static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { uint64_t mask0, mask1; - mask0 = flag + ~((uint64_t)0); + volatile int vflag = flag; + SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); + mask0 = vflag + ~((uint64_t)0); mask1 = ~mask0; r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); @@ -426,26 +425,98 @@ static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); } -static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); -#endif +static void secp256k1_fe_impl_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { r->n[0] = a->n[0] | a->n[1] << 52; r->n[1] = a->n[1] >> 12 | a->n[2] << 40; r->n[2] = a->n[2] >> 24 | a->n[3] << 28; r->n[3] = a->n[3] >> 36 | a->n[4] << 16; } -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { +static SECP256K1_INLINE void secp256k1_fe_impl_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL; r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL); r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL); r->n[3] = a->n[2] >> 28 | ((a->n[3] << 36) & 0xFFFFFFFFFFFFFULL); r->n[4] = a->n[3] >> 16; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; -#endif } -#endif +static void secp256k1_fe_from_signed62(secp256k1_fe *r, const secp256k1_modinv64_signed62 *a) { + const uint64_t M52 = UINT64_MAX >> 12; + const uint64_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4]; + + /* The output from secp256k1_modinv64{_var} should be normalized to range [0,modulus), and + * have limbs in [0,2^62). The modulus is < 2^256, so the top limb must be below 2^(256-62*4). + */ + VERIFY_CHECK(a0 >> 62 == 0); + VERIFY_CHECK(a1 >> 62 == 0); + VERIFY_CHECK(a2 >> 62 == 0); + VERIFY_CHECK(a3 >> 62 == 0); + VERIFY_CHECK(a4 >> 8 == 0); + + r->n[0] = a0 & M52; + r->n[1] = (a0 >> 52 | a1 << 10) & M52; + r->n[2] = (a1 >> 42 | a2 << 20) & M52; + r->n[3] = (a2 >> 32 | a3 << 30) & M52; + r->n[4] = (a3 >> 22 | a4 << 40); +} + +static void secp256k1_fe_to_signed62(secp256k1_modinv64_signed62 *r, const secp256k1_fe *a) { + const uint64_t M62 = UINT64_MAX >> 2; + const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4]; + + r->v[0] = (a0 | a1 << 52) & M62; + r->v[1] = (a1 >> 10 | a2 << 42) & M62; + r->v[2] = (a2 >> 20 | a3 << 32) & M62; + r->v[3] = (a3 >> 30 | a4 << 22) & M62; + r->v[4] = a4 >> 40; +} + +static const secp256k1_modinv64_modinfo secp256k1_const_modinfo_fe = { + {{-0x1000003D1LL, 0, 0, 0, 256}}, + 0x27C7F6E22DDACACFLL +}; + +static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp = *x; + secp256k1_modinv64_signed62 s; + + secp256k1_fe_normalize(&tmp); + secp256k1_fe_to_signed62(&s, &tmp); + secp256k1_modinv64(&s, &secp256k1_const_modinfo_fe); + secp256k1_fe_from_signed62(r, &s); +} + +static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp = *x; + secp256k1_modinv64_signed62 s; + + secp256k1_fe_normalize_var(&tmp); + secp256k1_fe_to_signed62(&s, &tmp); + secp256k1_modinv64_var(&s, &secp256k1_const_modinfo_fe); + secp256k1_fe_from_signed62(r, &s); +} + +static int secp256k1_fe_impl_is_square_var(const secp256k1_fe *x) { + secp256k1_fe tmp; + secp256k1_modinv64_signed62 s; + int jac, ret; + + tmp = *x; + secp256k1_fe_normalize_var(&tmp); + /* secp256k1_jacobi64_maybe_var cannot deal with input 0. */ + if (secp256k1_fe_is_zero(&tmp)) return 1; + secp256k1_fe_to_signed62(&s, &tmp); + jac = secp256k1_jacobi64_maybe_var(&s, &secp256k1_const_modinfo_fe); + if (jac == 0) { + /* secp256k1_jacobi64_maybe_var failed to compute the Jacobi symbol. Fall back + * to computing a square root. This should be extremely rare with random + * input (except in VERIFY mode, where a lower iteration count is used). */ + secp256k1_fe dummy; + ret = secp256k1_fe_sqrt(&dummy, &tmp); + } else { + ret = jac >= 0; + } + return ret; +} + +#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/field_5x52_int128_impl.h b/crypto/secp256k1/libsecp256k1/src/field_5x52_int128_impl.h index 0bf22bdd3e..f23f8ee1c4 100644 --- a/crypto/secp256k1/libsecp256k1/src/field_5x52_int128_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/field_5x52_int128_impl.h @@ -1,22 +1,22 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_ -#define _SECP256K1_FIELD_INNER5X52_IMPL_H_ +#ifndef SECP256K1_FIELD_INNER5X52_IMPL_H +#define SECP256K1_FIELD_INNER5X52_IMPL_H #include -#ifdef VERIFY +#include "int128.h" +#include "util.h" + #define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) -#else -#define VERIFY_BITS(x, n) do { } while(0) -#endif +#define VERIFY_BITS_128(x, n) VERIFY_CHECK(secp256k1_u128_check_bits((x), (n))) SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { - uint128_t c, d; + secp256k1_uint128 c, d; uint64_t t3, t4, tx, u0; uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; @@ -32,130 +32,129 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t VERIFY_BITS(b[3], 56); VERIFY_BITS(b[4], 52); VERIFY_CHECK(r != b); + VERIFY_CHECK(a != b); /* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. - * px is a shorthand for sum(a[i]*b[x-i], i=0..x). + * for 0 <= x <= 4, px is a shorthand for sum(a[i]*b[x-i], i=0..x). + * for 4 <= x <= 8, px is a shorthand for sum(a[i]*b[x-i], i=(x-4)..4) * Note that [x 0 0 0 0 0] = [x*R]. */ - d = (uint128_t)a0 * b[3] - + (uint128_t)a1 * b[2] - + (uint128_t)a2 * b[1] - + (uint128_t)a3 * b[0]; - VERIFY_BITS(d, 114); + secp256k1_u128_mul(&d, a0, b[3]); + secp256k1_u128_accum_mul(&d, a1, b[2]); + secp256k1_u128_accum_mul(&d, a2, b[1]); + secp256k1_u128_accum_mul(&d, a3, b[0]); + VERIFY_BITS_128(&d, 114); /* [d 0 0 0] = [p3 0 0 0] */ - c = (uint128_t)a4 * b[4]; - VERIFY_BITS(c, 112); + secp256k1_u128_mul(&c, a4, b[4]); + VERIFY_BITS_128(&c, 112); /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - d += (c & M) * R; c >>= 52; - VERIFY_BITS(d, 115); - VERIFY_BITS(c, 60); - /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - t3 = d & M; d >>= 52; + secp256k1_u128_accum_mul(&d, R, secp256k1_u128_to_u64(&c)); secp256k1_u128_rshift(&c, 64); + VERIFY_BITS_128(&d, 115); + VERIFY_BITS_128(&c, 48); + /* [(c<<12) 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + t3 = secp256k1_u128_to_u64(&d) & M; secp256k1_u128_rshift(&d, 52); VERIFY_BITS(t3, 52); - VERIFY_BITS(d, 63); - /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + VERIFY_BITS_128(&d, 63); + /* [(c<<12) 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - d += (uint128_t)a0 * b[4] - + (uint128_t)a1 * b[3] - + (uint128_t)a2 * b[2] - + (uint128_t)a3 * b[1] - + (uint128_t)a4 * b[0]; - VERIFY_BITS(d, 115); - /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - d += c * R; - VERIFY_BITS(d, 116); + secp256k1_u128_accum_mul(&d, a0, b[4]); + secp256k1_u128_accum_mul(&d, a1, b[3]); + secp256k1_u128_accum_mul(&d, a2, b[2]); + secp256k1_u128_accum_mul(&d, a3, b[1]); + secp256k1_u128_accum_mul(&d, a4, b[0]); + VERIFY_BITS_128(&d, 115); + /* [(c<<12) 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + secp256k1_u128_accum_mul(&d, R << 12, secp256k1_u128_to_u64(&c)); + VERIFY_BITS_128(&d, 116); /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - t4 = d & M; d >>= 52; + t4 = secp256k1_u128_to_u64(&d) & M; secp256k1_u128_rshift(&d, 52); VERIFY_BITS(t4, 52); - VERIFY_BITS(d, 64); + VERIFY_BITS_128(&d, 64); /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ tx = (t4 >> 48); t4 &= (M >> 4); VERIFY_BITS(tx, 4); VERIFY_BITS(t4, 48); /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - c = (uint128_t)a0 * b[0]; - VERIFY_BITS(c, 112); + secp256k1_u128_mul(&c, a0, b[0]); + VERIFY_BITS_128(&c, 112); /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ - d += (uint128_t)a1 * b[4] - + (uint128_t)a2 * b[3] - + (uint128_t)a3 * b[2] - + (uint128_t)a4 * b[1]; - VERIFY_BITS(d, 115); + secp256k1_u128_accum_mul(&d, a1, b[4]); + secp256k1_u128_accum_mul(&d, a2, b[3]); + secp256k1_u128_accum_mul(&d, a3, b[2]); + secp256k1_u128_accum_mul(&d, a4, b[1]); + VERIFY_BITS_128(&d, 114); /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - u0 = d & M; d >>= 52; + u0 = secp256k1_u128_to_u64(&d) & M; secp256k1_u128_rshift(&d, 52); VERIFY_BITS(u0, 52); - VERIFY_BITS(d, 63); + VERIFY_BITS_128(&d, 62); /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ u0 = (u0 << 4) | tx; VERIFY_BITS(u0, 56); /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - c += (uint128_t)u0 * (R >> 4); - VERIFY_BITS(c, 115); + secp256k1_u128_accum_mul(&c, u0, R >> 4); + VERIFY_BITS_128(&c, 113); /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - r[0] = c & M; c >>= 52; + r[0] = secp256k1_u128_to_u64(&c) & M; secp256k1_u128_rshift(&c, 52); VERIFY_BITS(r[0], 52); - VERIFY_BITS(c, 61); + VERIFY_BITS_128(&c, 61); /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ - c += (uint128_t)a0 * b[1] - + (uint128_t)a1 * b[0]; - VERIFY_BITS(c, 114); + secp256k1_u128_accum_mul(&c, a0, b[1]); + secp256k1_u128_accum_mul(&c, a1, b[0]); + VERIFY_BITS_128(&c, 114); /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ - d += (uint128_t)a2 * b[4] - + (uint128_t)a3 * b[3] - + (uint128_t)a4 * b[2]; - VERIFY_BITS(d, 114); + secp256k1_u128_accum_mul(&d, a2, b[4]); + secp256k1_u128_accum_mul(&d, a3, b[3]); + secp256k1_u128_accum_mul(&d, a4, b[2]); + VERIFY_BITS_128(&d, 114); /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - c += (d & M) * R; d >>= 52; - VERIFY_BITS(c, 115); - VERIFY_BITS(d, 62); + secp256k1_u128_accum_mul(&c, secp256k1_u128_to_u64(&d) & M, R); secp256k1_u128_rshift(&d, 52); + VERIFY_BITS_128(&c, 115); + VERIFY_BITS_128(&d, 62); /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - r[1] = c & M; c >>= 52; + r[1] = secp256k1_u128_to_u64(&c) & M; secp256k1_u128_rshift(&c, 52); VERIFY_BITS(r[1], 52); - VERIFY_BITS(c, 63); + VERIFY_BITS_128(&c, 63); /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - c += (uint128_t)a0 * b[2] - + (uint128_t)a1 * b[1] - + (uint128_t)a2 * b[0]; - VERIFY_BITS(c, 114); + secp256k1_u128_accum_mul(&c, a0, b[2]); + secp256k1_u128_accum_mul(&c, a1, b[1]); + secp256k1_u128_accum_mul(&c, a2, b[0]); + VERIFY_BITS_128(&c, 114); /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint128_t)a3 * b[4] - + (uint128_t)a4 * b[3]; - VERIFY_BITS(d, 114); + secp256k1_u128_accum_mul(&d, a3, b[4]); + secp256k1_u128_accum_mul(&d, a4, b[3]); + VERIFY_BITS_128(&d, 114); /* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += (d & M) * R; d >>= 52; - VERIFY_BITS(c, 115); - VERIFY_BITS(d, 62); - /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + secp256k1_u128_accum_mul(&c, R, secp256k1_u128_to_u64(&d)); secp256k1_u128_rshift(&d, 64); + VERIFY_BITS_128(&c, 115); + VERIFY_BITS_128(&d, 50); + /* [(d<<12) 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[2] = c & M; c >>= 52; + r[2] = secp256k1_u128_to_u64(&c) & M; secp256k1_u128_rshift(&c, 52); VERIFY_BITS(r[2], 52); - VERIFY_BITS(c, 63); - /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3; - VERIFY_BITS(c, 100); + VERIFY_BITS_128(&c, 63); + /* [(d<<12) 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + secp256k1_u128_accum_mul(&c, R << 12, secp256k1_u128_to_u64(&d)); + secp256k1_u128_accum_u64(&c, t3); + VERIFY_BITS_128(&c, 100); /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[3] = c & M; c >>= 52; + r[3] = secp256k1_u128_to_u64(&c) & M; secp256k1_u128_rshift(&c, 52); VERIFY_BITS(r[3], 52); - VERIFY_BITS(c, 48); + VERIFY_BITS_128(&c, 48); /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += t4; - VERIFY_BITS(c, 49); - /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[4] = c; + r[4] = secp256k1_u128_to_u64(&c) + t4; VERIFY_BITS(r[4], 49); /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ } SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { - uint128_t c, d; + secp256k1_uint128 c, d; uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; - int64_t t3, t4, tx, u0; + uint64_t t3, t4, tx, u0; const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; VERIFY_BITS(a[0], 56); @@ -169,109 +168,107 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t * Note that [x 0 0 0 0 0] = [x*R]. */ - d = (uint128_t)(a0*2) * a3 - + (uint128_t)(a1*2) * a2; - VERIFY_BITS(d, 114); + secp256k1_u128_mul(&d, a0*2, a3); + secp256k1_u128_accum_mul(&d, a1*2, a2); + VERIFY_BITS_128(&d, 114); /* [d 0 0 0] = [p3 0 0 0] */ - c = (uint128_t)a4 * a4; - VERIFY_BITS(c, 112); + secp256k1_u128_mul(&c, a4, a4); + VERIFY_BITS_128(&c, 112); /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - d += (c & M) * R; c >>= 52; - VERIFY_BITS(d, 115); - VERIFY_BITS(c, 60); - /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - t3 = d & M; d >>= 52; + secp256k1_u128_accum_mul(&d, R, secp256k1_u128_to_u64(&c)); secp256k1_u128_rshift(&c, 64); + VERIFY_BITS_128(&d, 115); + VERIFY_BITS_128(&c, 48); + /* [(c<<12) 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + t3 = secp256k1_u128_to_u64(&d) & M; secp256k1_u128_rshift(&d, 52); VERIFY_BITS(t3, 52); - VERIFY_BITS(d, 63); - /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + VERIFY_BITS_128(&d, 63); + /* [(c<<12) 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ a4 *= 2; - d += (uint128_t)a0 * a4 - + (uint128_t)(a1*2) * a3 - + (uint128_t)a2 * a2; - VERIFY_BITS(d, 115); - /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - d += c * R; - VERIFY_BITS(d, 116); + secp256k1_u128_accum_mul(&d, a0, a4); + secp256k1_u128_accum_mul(&d, a1*2, a3); + secp256k1_u128_accum_mul(&d, a2, a2); + VERIFY_BITS_128(&d, 115); + /* [(c<<12) 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + secp256k1_u128_accum_mul(&d, R << 12, secp256k1_u128_to_u64(&c)); + VERIFY_BITS_128(&d, 116); /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - t4 = d & M; d >>= 52; + t4 = secp256k1_u128_to_u64(&d) & M; secp256k1_u128_rshift(&d, 52); VERIFY_BITS(t4, 52); - VERIFY_BITS(d, 64); + VERIFY_BITS_128(&d, 64); /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ tx = (t4 >> 48); t4 &= (M >> 4); VERIFY_BITS(tx, 4); VERIFY_BITS(t4, 48); /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - c = (uint128_t)a0 * a0; - VERIFY_BITS(c, 112); + secp256k1_u128_mul(&c, a0, a0); + VERIFY_BITS_128(&c, 112); /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ - d += (uint128_t)a1 * a4 - + (uint128_t)(a2*2) * a3; - VERIFY_BITS(d, 114); + secp256k1_u128_accum_mul(&d, a1, a4); + secp256k1_u128_accum_mul(&d, a2*2, a3); + VERIFY_BITS_128(&d, 114); /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - u0 = d & M; d >>= 52; + u0 = secp256k1_u128_to_u64(&d) & M; secp256k1_u128_rshift(&d, 52); VERIFY_BITS(u0, 52); - VERIFY_BITS(d, 62); + VERIFY_BITS_128(&d, 62); /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ u0 = (u0 << 4) | tx; VERIFY_BITS(u0, 56); /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - c += (uint128_t)u0 * (R >> 4); - VERIFY_BITS(c, 113); + secp256k1_u128_accum_mul(&c, u0, R >> 4); + VERIFY_BITS_128(&c, 113); /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - r[0] = c & M; c >>= 52; + r[0] = secp256k1_u128_to_u64(&c) & M; secp256k1_u128_rshift(&c, 52); VERIFY_BITS(r[0], 52); - VERIFY_BITS(c, 61); + VERIFY_BITS_128(&c, 61); /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ a0 *= 2; - c += (uint128_t)a0 * a1; - VERIFY_BITS(c, 114); + secp256k1_u128_accum_mul(&c, a0, a1); + VERIFY_BITS_128(&c, 114); /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ - d += (uint128_t)a2 * a4 - + (uint128_t)a3 * a3; - VERIFY_BITS(d, 114); + secp256k1_u128_accum_mul(&d, a2, a4); + secp256k1_u128_accum_mul(&d, a3, a3); + VERIFY_BITS_128(&d, 114); /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - c += (d & M) * R; d >>= 52; - VERIFY_BITS(c, 115); - VERIFY_BITS(d, 62); + secp256k1_u128_accum_mul(&c, secp256k1_u128_to_u64(&d) & M, R); secp256k1_u128_rshift(&d, 52); + VERIFY_BITS_128(&c, 115); + VERIFY_BITS_128(&d, 62); /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - r[1] = c & M; c >>= 52; + r[1] = secp256k1_u128_to_u64(&c) & M; secp256k1_u128_rshift(&c, 52); VERIFY_BITS(r[1], 52); - VERIFY_BITS(c, 63); + VERIFY_BITS_128(&c, 63); /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - c += (uint128_t)a0 * a2 - + (uint128_t)a1 * a1; - VERIFY_BITS(c, 114); + secp256k1_u128_accum_mul(&c, a0, a2); + secp256k1_u128_accum_mul(&c, a1, a1); + VERIFY_BITS_128(&c, 114); /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint128_t)a3 * a4; - VERIFY_BITS(d, 114); + secp256k1_u128_accum_mul(&d, a3, a4); + VERIFY_BITS_128(&d, 114); /* [d 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += (d & M) * R; d >>= 52; - VERIFY_BITS(c, 115); - VERIFY_BITS(d, 62); - /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[2] = c & M; c >>= 52; + secp256k1_u128_accum_mul(&c, R, secp256k1_u128_to_u64(&d)); secp256k1_u128_rshift(&d, 64); + VERIFY_BITS_128(&c, 115); + VERIFY_BITS_128(&d, 50); + /* [(d<<12) 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[2] = secp256k1_u128_to_u64(&c) & M; secp256k1_u128_rshift(&c, 52); VERIFY_BITS(r[2], 52); - VERIFY_BITS(c, 63); - /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + VERIFY_BITS_128(&c, 63); + /* [(d<<12) 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3; - VERIFY_BITS(c, 100); + secp256k1_u128_accum_mul(&c, R << 12, secp256k1_u128_to_u64(&d)); + secp256k1_u128_accum_u64(&c, t3); + VERIFY_BITS_128(&c, 100); /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[3] = c & M; c >>= 52; + r[3] = secp256k1_u128_to_u64(&c) & M; secp256k1_u128_rshift(&c, 52); VERIFY_BITS(r[3], 52); - VERIFY_BITS(c, 48); + VERIFY_BITS_128(&c, 48); /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += t4; - VERIFY_BITS(c, 49); - /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[4] = c; + r[4] = secp256k1_u128_to_u64(&c) + t4; VERIFY_BITS(r[4], 49); /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ } -#endif +#endif /* SECP256K1_FIELD_INNER5X52_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/field_impl.h b/crypto/secp256k1/libsecp256k1/src/field_impl.h index 5127b279bc..896507a3a4 100644 --- a/crypto/secp256k1/libsecp256k1/src/field_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/field_impl.h @@ -1,41 +1,40 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_FIELD_IMPL_H_ -#define _SECP256K1_FIELD_IMPL_H_ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif +#ifndef SECP256K1_FIELD_IMPL_H +#define SECP256K1_FIELD_IMPL_H +#include "field.h" #include "util.h" -#if defined(USE_FIELD_10X26) -#include "field_10x26_impl.h" -#elif defined(USE_FIELD_5X52) +#if defined(SECP256K1_WIDEMUL_INT128) #include "field_5x52_impl.h" +#elif defined(SECP256K1_WIDEMUL_INT64) +#include "field_10x26_impl.h" #else -#error "Please select field implementation" +#error "Please select wide multiplication implementation" #endif +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { + secp256k1_memclear(a, sizeof(secp256k1_fe)); +} + SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { secp256k1_fe na; + SECP256K1_FE_VERIFY(a); + SECP256K1_FE_VERIFY(b); + SECP256K1_FE_VERIFY_MAGNITUDE(a, 1); + SECP256K1_FE_VERIFY_MAGNITUDE(b, 31); + secp256k1_fe_negate(&na, a, 1); secp256k1_fe_add(&na, b); return secp256k1_fe_normalizes_to_zero(&na); } -SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { - secp256k1_fe na; - secp256k1_fe_negate(&na, a, 1); - secp256k1_fe_add(&na, b); - return secp256k1_fe_normalizes_to_zero_var(&na); -} - -static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { +static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a) { /** Given that p is congruent to 3 mod 4, we can compute the square root of * a mod p as the (p+1)/4'th power of a. * @@ -46,7 +45,11 @@ static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { * itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)). */ secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; - int j; + int j, ret; + + VERIFY_CHECK(r != a); + SECP256K1_FE_VERIFY(a); + SECP256K1_FE_VERIFY_MAGNITUDE(a, 8); /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: @@ -130,186 +133,325 @@ static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { /* Check that a square root was actually calculated */ secp256k1_fe_sqr(&t1, r); - return secp256k1_fe_equal(&t1, a); + ret = secp256k1_fe_equal(&t1, a); + +#ifdef VERIFY + if (!ret) { + secp256k1_fe_negate(&t1, &t1, 1); + secp256k1_fe_normalize_var(&t1); + VERIFY_CHECK(secp256k1_fe_equal(&t1, a)); + } +#endif + return ret; } -static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) { - secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; - int j; - - /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in - * { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: - * [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] - */ - - secp256k1_fe_sqr(&x2, a); - secp256k1_fe_mul(&x2, &x2, a); - - secp256k1_fe_sqr(&x3, &x2); - secp256k1_fe_mul(&x3, &x3, a); - - x6 = x3; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x6, &x6); - } - secp256k1_fe_mul(&x6, &x6, &x3); - - x9 = x6; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x9, &x9); - } - secp256k1_fe_mul(&x9, &x9, &x3); - - x11 = x9; - for (j=0; j<2; j++) { - secp256k1_fe_sqr(&x11, &x11); - } - secp256k1_fe_mul(&x11, &x11, &x2); - - x22 = x11; - for (j=0; j<11; j++) { - secp256k1_fe_sqr(&x22, &x22); - } - secp256k1_fe_mul(&x22, &x22, &x11); - - x44 = x22; - for (j=0; j<22; j++) { - secp256k1_fe_sqr(&x44, &x44); - } - secp256k1_fe_mul(&x44, &x44, &x22); - - x88 = x44; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x88, &x88); - } - secp256k1_fe_mul(&x88, &x88, &x44); - - x176 = x88; - for (j=0; j<88; j++) { - secp256k1_fe_sqr(&x176, &x176); - } - secp256k1_fe_mul(&x176, &x176, &x88); - - x220 = x176; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x220, &x220); - } - secp256k1_fe_mul(&x220, &x220, &x44); - - x223 = x220; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x223, &x223); - } - secp256k1_fe_mul(&x223, &x223, &x3); - - /* The final result is then assembled using a sliding window over the blocks. */ - - t1 = x223; - for (j=0; j<23; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x22); - for (j=0; j<5; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, a); - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x2); - for (j=0; j<2; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(r, a, &t1); -} - -static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) { -#if defined(USE_FIELD_INV_BUILTIN) - secp256k1_fe_inv(r, a); -#elif defined(USE_FIELD_INV_NUM) - secp256k1_num n, m; - static const secp256k1_fe negone = SECP256K1_FE_CONST( - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xFFFFFC2EUL - ); - /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ - static const unsigned char prime[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F - }; - unsigned char b[32]; - int res; - secp256k1_fe c = *a; - secp256k1_fe_normalize_var(&c); - secp256k1_fe_get_b32(b, &c); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_num_set_bin(&m, prime, 32); - secp256k1_num_mod_inverse(&n, &n, &m); - secp256k1_num_get_bin(b, 32, &n); - res = secp256k1_fe_set_b32(r, b); - (void)res; - VERIFY_CHECK(res); - /* Verify the result is the (unique) valid inverse using non-GMP code. */ - secp256k1_fe_mul(&c, &c, r); - secp256k1_fe_add(&c, &negone); - CHECK(secp256k1_fe_normalizes_to_zero_var(&c)); +#ifndef VERIFY +static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; } +static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) { (void)a; (void)m; } #else -#error "Please select field inverse implementation" -#endif +static void secp256k1_fe_impl_verify(const secp256k1_fe *a); +static void secp256k1_fe_verify(const secp256k1_fe *a) { + /* Magnitude between 0 and 32. */ + SECP256K1_FE_VERIFY_MAGNITUDE(a, 32); + /* Normalized is 0 or 1. */ + VERIFY_CHECK((a->normalized == 0) || (a->normalized == 1)); + /* If normalized, magnitude must be 0 or 1. */ + if (a->normalized) SECP256K1_FE_VERIFY_MAGNITUDE(a, 1); + /* Invoke implementation-specific checks. */ + secp256k1_fe_impl_verify(a); } -static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len) { - secp256k1_fe u; - size_t i; - if (len < 1) { - return; - } - - VERIFY_CHECK((r + len <= a) || (a + len <= r)); - - r[0] = a[0]; - - i = 0; - while (++i < len) { - secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]); - } - - secp256k1_fe_inv_var(&u, &r[--i]); - - while (i > 0) { - size_t j = i--; - secp256k1_fe_mul(&r[j], &r[i], &u); - secp256k1_fe_mul(&u, &u, &a[j]); - } - - r[0] = u; +static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) { + VERIFY_CHECK(m >= 0); + VERIFY_CHECK(m <= 32); + VERIFY_CHECK(a->magnitude <= m); } -static int secp256k1_fe_is_quad_var(const secp256k1_fe *a) { -#ifndef USE_NUM_NONE - unsigned char b[32]; - secp256k1_num n; - secp256k1_num m; - /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ - static const unsigned char prime[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F - }; +static void secp256k1_fe_impl_normalize(secp256k1_fe *r); +SECP256K1_INLINE static void secp256k1_fe_normalize(secp256k1_fe *r) { + SECP256K1_FE_VERIFY(r); - secp256k1_fe c = *a; - secp256k1_fe_normalize_var(&c); - secp256k1_fe_get_b32(b, &c); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_num_set_bin(&m, prime, 32); - return secp256k1_num_jacobi(&n, &m) >= 0; -#else - secp256k1_fe r; - return secp256k1_fe_sqrt(&r, a); -#endif + secp256k1_fe_impl_normalize(r); + r->magnitude = 1; + r->normalized = 1; + + SECP256K1_FE_VERIFY(r); } -#endif +static void secp256k1_fe_impl_normalize_weak(secp256k1_fe *r); +SECP256K1_INLINE static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { + SECP256K1_FE_VERIFY(r); + + secp256k1_fe_impl_normalize_weak(r); + r->magnitude = 1; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_normalize_var(secp256k1_fe *r); +SECP256K1_INLINE static void secp256k1_fe_normalize_var(secp256k1_fe *r) { + SECP256K1_FE_VERIFY(r); + + secp256k1_fe_impl_normalize_var(r); + r->magnitude = 1; + r->normalized = 1; + + SECP256K1_FE_VERIFY(r); +} + +static int secp256k1_fe_impl_normalizes_to_zero(const secp256k1_fe *r); +SECP256K1_INLINE static int secp256k1_fe_normalizes_to_zero(const secp256k1_fe *r) { + SECP256K1_FE_VERIFY(r); + + return secp256k1_fe_impl_normalizes_to_zero(r); +} + +static int secp256k1_fe_impl_normalizes_to_zero_var(const secp256k1_fe *r); +SECP256K1_INLINE static int secp256k1_fe_normalizes_to_zero_var(const secp256k1_fe *r) { + SECP256K1_FE_VERIFY(r); + + return secp256k1_fe_impl_normalizes_to_zero_var(r); +} + +static void secp256k1_fe_impl_set_int(secp256k1_fe *r, int a); +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { + VERIFY_CHECK(0 <= a && a <= 0x7FFF); + + secp256k1_fe_impl_set_int(r, a); + r->magnitude = (a != 0); + r->normalized = 1; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_add_int(secp256k1_fe *r, int a); +SECP256K1_INLINE static void secp256k1_fe_add_int(secp256k1_fe *r, int a) { + VERIFY_CHECK(0 <= a && a <= 0x7FFF); + SECP256K1_FE_VERIFY(r); + + secp256k1_fe_impl_add_int(r, a); + r->magnitude += 1; + r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +static int secp256k1_fe_impl_is_zero(const secp256k1_fe *a); +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { + SECP256K1_FE_VERIFY(a); + VERIFY_CHECK(a->normalized); + + return secp256k1_fe_impl_is_zero(a); +} + +static int secp256k1_fe_impl_is_odd(const secp256k1_fe *a); +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { + SECP256K1_FE_VERIFY(a); + VERIFY_CHECK(a->normalized); + + return secp256k1_fe_impl_is_odd(a); +} + +static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); +SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { + SECP256K1_FE_VERIFY(a); + SECP256K1_FE_VERIFY(b); + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); + + return secp256k1_fe_impl_cmp_var(a, b); +} + +static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a); +SECP256K1_INLINE static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a) { + secp256k1_fe_impl_set_b32_mod(r, a); + r->magnitude = 1; + r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a); +SECP256K1_INLINE static int secp256k1_fe_set_b32_limit(secp256k1_fe *r, const unsigned char *a) { + if (secp256k1_fe_impl_set_b32_limit(r, a)) { + r->magnitude = 1; + r->normalized = 1; + SECP256K1_FE_VERIFY(r); + return 1; + } else { + /* Mark the output field element as invalid. */ + r->magnitude = -1; + return 0; + } +} + +static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a); +SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { + SECP256K1_FE_VERIFY(a); + VERIFY_CHECK(a->normalized); + + secp256k1_fe_impl_get_b32(r, a); +} + +static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m); +SECP256K1_INLINE static void secp256k1_fe_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) { + SECP256K1_FE_VERIFY(a); + VERIFY_CHECK(m >= 0 && m <= 31); + SECP256K1_FE_VERIFY_MAGNITUDE(a, m); + + secp256k1_fe_impl_negate_unchecked(r, a, m); + r->magnitude = m + 1; + r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a); +SECP256K1_INLINE static void secp256k1_fe_mul_int_unchecked(secp256k1_fe *r, int a) { + SECP256K1_FE_VERIFY(r); + + VERIFY_CHECK(a >= 0 && a <= 32); + VERIFY_CHECK(a*r->magnitude <= 32); + secp256k1_fe_impl_mul_int_unchecked(r, a); + r->magnitude *= a; + r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a); +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { + SECP256K1_FE_VERIFY(r); + SECP256K1_FE_VERIFY(a); + VERIFY_CHECK(r->magnitude + a->magnitude <= 32); + + secp256k1_fe_impl_add(r, a); + r->magnitude += a->magnitude; + r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); +SECP256K1_INLINE static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { + SECP256K1_FE_VERIFY(a); + SECP256K1_FE_VERIFY(b); + SECP256K1_FE_VERIFY_MAGNITUDE(a, 8); + SECP256K1_FE_VERIFY_MAGNITUDE(b, 8); + VERIFY_CHECK(r != b); + VERIFY_CHECK(a != b); + + secp256k1_fe_impl_mul(r, a, b); + r->magnitude = 1; + r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a); +SECP256K1_INLINE static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { + SECP256K1_FE_VERIFY(a); + SECP256K1_FE_VERIFY_MAGNITUDE(a, 8); + + secp256k1_fe_impl_sqr(r, a); + r->magnitude = 1; + r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); +SECP256K1_INLINE static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { + VERIFY_CHECK(flag == 0 || flag == 1); + SECP256K1_FE_VERIFY(a); + SECP256K1_FE_VERIFY(r); + + secp256k1_fe_impl_cmov(r, a, flag); + if (a->magnitude > r->magnitude) r->magnitude = a->magnitude; + if (!a->normalized) r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); +SECP256K1_INLINE static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { + SECP256K1_FE_VERIFY(a); + VERIFY_CHECK(a->normalized); + + secp256k1_fe_impl_to_storage(r, a); +} + +static void secp256k1_fe_impl_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); +SECP256K1_INLINE static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { + secp256k1_fe_impl_from_storage(r, a); + r->magnitude = 1; + r->normalized = 1; + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x); +SECP256K1_INLINE static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) { + int input_is_zero = secp256k1_fe_normalizes_to_zero(x); + SECP256K1_FE_VERIFY(x); + + secp256k1_fe_impl_inv(r, x); + r->magnitude = x->magnitude > 0; + r->normalized = 1; + + VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero); + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x); +SECP256K1_INLINE static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { + int input_is_zero = secp256k1_fe_normalizes_to_zero(x); + SECP256K1_FE_VERIFY(x); + + secp256k1_fe_impl_inv_var(r, x); + r->magnitude = x->magnitude > 0; + r->normalized = 1; + + VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero); + SECP256K1_FE_VERIFY(r); +} + +static int secp256k1_fe_impl_is_square_var(const secp256k1_fe *x); +SECP256K1_INLINE static int secp256k1_fe_is_square_var(const secp256k1_fe *x) { + int ret; + secp256k1_fe tmp = *x, sqrt; + SECP256K1_FE_VERIFY(x); + + ret = secp256k1_fe_impl_is_square_var(x); + secp256k1_fe_normalize_weak(&tmp); + VERIFY_CHECK(ret == secp256k1_fe_sqrt(&sqrt, &tmp)); + return ret; +} + +static void secp256k1_fe_impl_get_bounds(secp256k1_fe* r, int m); +SECP256K1_INLINE static void secp256k1_fe_get_bounds(secp256k1_fe* r, int m) { + VERIFY_CHECK(m >= 0); + VERIFY_CHECK(m <= 32); + + secp256k1_fe_impl_get_bounds(r, m); + r->magnitude = m; + r->normalized = (m == 0); + + SECP256K1_FE_VERIFY(r); +} + +static void secp256k1_fe_impl_half(secp256k1_fe *r); +SECP256K1_INLINE static void secp256k1_fe_half(secp256k1_fe *r) { + SECP256K1_FE_VERIFY(r); + SECP256K1_FE_VERIFY_MAGNITUDE(r, 31); + + secp256k1_fe_impl_half(r); + r->magnitude = (r->magnitude >> 1) + 1; + r->normalized = 0; + + SECP256K1_FE_VERIFY(r); +} + +#endif /* defined(VERIFY) */ + +#endif /* SECP256K1_FIELD_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/gen_context.c b/crypto/secp256k1/libsecp256k1/src/gen_context.c deleted file mode 100644 index 1835fd491d..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/gen_context.c +++ /dev/null @@ -1,74 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#define USE_BASIC_CONFIG 1 - -#include "basic-config.h" -#include "include/secp256k1.h" -#include "field_impl.h" -#include "scalar_impl.h" -#include "group_impl.h" -#include "ecmult_gen_impl.h" - -static void default_error_callback_fn(const char* str, void* data) { - (void)data; - fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); - abort(); -} - -static const secp256k1_callback default_error_callback = { - default_error_callback_fn, - NULL -}; - -int main(int argc, char **argv) { - secp256k1_ecmult_gen_context ctx; - int inner; - int outer; - FILE* fp; - - (void)argc; - (void)argv; - - fp = fopen("src/ecmult_static_context.h","w"); - if (fp == NULL) { - fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n"); - return -1; - } - - fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); - fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); - fprintf(fp, "#include \"group.h\"\n"); - fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n"); - fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[64][16] = {\n"); - - secp256k1_ecmult_gen_context_init(&ctx); - secp256k1_ecmult_gen_context_build(&ctx, &default_error_callback); - for(outer = 0; outer != 64; outer++) { - fprintf(fp,"{\n"); - for(inner = 0; inner != 16; inner++) { - fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner])); - if (inner != 15) { - fprintf(fp,",\n"); - } else { - fprintf(fp,"\n"); - } - } - if (outer != 63) { - fprintf(fp,"},\n"); - } else { - fprintf(fp,"}\n"); - } - } - fprintf(fp,"};\n"); - secp256k1_ecmult_gen_context_clear(&ctx); - - fprintf(fp, "#undef SC\n"); - fprintf(fp, "#endif\n"); - fclose(fp); - - return 0; -} diff --git a/crypto/secp256k1/libsecp256k1/src/group.h b/crypto/secp256k1/libsecp256k1/src/group.h index 4957b248fe..992ff5c98c 100644 --- a/crypto/secp256k1/libsecp256k1/src/group.h +++ b/crypto/secp256k1/libsecp256k1/src/group.h @@ -1,16 +1,18 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_GROUP_ -#define _SECP256K1_GROUP_ +#ifndef SECP256K1_GROUP_H +#define SECP256K1_GROUP_H -#include "num.h" #include "field.h" -/** A group element of the secp256k1 curve, in affine coordinates. */ +/** A group element in affine coordinates on the secp256k1 curve, + * or occasionally on an isomorphic curve of the form y^2 = x^3 + 7*t^6. + * Note: For exhaustive test mode, secp256k1 is replaced by a small subgroup of a different curve. + */ typedef struct { secp256k1_fe x; secp256k1_fe y; @@ -20,7 +22,9 @@ typedef struct { #define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} #define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} -/** A group element of the secp256k1 curve, in jacobian coordinates. */ +/** A group element of the secp256k1 curve, in jacobian coordinates. + * Note: For exhastive test mode, secp256k1 is replaced by a small subgroup of a different curve. + */ typedef struct { secp256k1_fe x; /* actual X: x/z^2 */ secp256k1_fe y; /* actual Y: y/z^3 */ @@ -40,44 +44,69 @@ typedef struct { #define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y) +/** Maximum allowed magnitudes for group element coordinates + * in affine (x, y) and jacobian (x, y, z) representation. */ +#define SECP256K1_GE_X_MAGNITUDE_MAX 4 +#define SECP256K1_GE_Y_MAGNITUDE_MAX 3 +#define SECP256K1_GEJ_X_MAGNITUDE_MAX 4 +#define SECP256K1_GEJ_Y_MAGNITUDE_MAX 4 +#define SECP256K1_GEJ_Z_MAGNITUDE_MAX 1 + /** Set a group element equal to the point with given X and Y coordinates */ static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); -/** Set a group element (affine) equal to the point with the given X coordinate - * and a Y coordinate that is a quadratic residue modulo p. The return value - * is true iff a coordinate with the given X coordinate exists. - */ -static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); - /** Set a group element (affine) equal to the point with the given X coordinate, and given oddness * for Y. Return value indicates whether the result is valid. */ static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd); +/** Determine whether x is a valid X coordinate on the curve. */ +static int secp256k1_ge_x_on_curve_var(const secp256k1_fe *x); + +/** Determine whether fraction xn/xd is a valid X coordinate on the curve (xd != 0). */ +static int secp256k1_ge_x_frac_on_curve_var(const secp256k1_fe *xn, const secp256k1_fe *xd); + /** Check whether a group element is the point at infinity. */ static int secp256k1_ge_is_infinity(const secp256k1_ge *a); /** Check whether a group element is valid (i.e., on the curve). */ static int secp256k1_ge_is_valid_var(const secp256k1_ge *a); +/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); -/** Set a group element equal to another which is given in jacobian coordinates */ +/** Set a group element equal to another which is given in jacobian coordinates. Constant time. */ static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); +/** Set a group element equal to another which is given in jacobian coordinates. */ +static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a); + /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ -static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb); +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len); -/** Set a batch of group elements equal to the inputs given in jacobian - * coordinates (with known z-ratios). zr must contain the known z-ratios such - * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */ -static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len); +/** Bring a batch of inputs to the same global z "denominator", based on ratios between + * (omitted) z coordinates of adjacent elements. + * + * Although the elements a[i] are _ge rather than _gej, they actually represent elements + * in Jacobian coordinates with their z coordinates omitted. + * + * Using the notation z(b) to represent the omitted z coordinate of b, the array zr of + * z coordinate ratios must satisfy zr[i] == z(a[i]) / z(a[i-1]) for 0 < 'i' < len. + * The zr[0] value is unused. + * + * This function adjusts the coordinates of 'a' in place so that for all 'i', z(a[i]) == z(a[len-1]). + * In other words, the initial value of z(a[len-1]) becomes the global z "denominator". Only the + * a[i].x and a[i].y coordinates are explicitly modified; the adjustment of the omitted z coordinate is + * implicit. + * + * The coordinates of the final element a[len-1] are not changed. + */ +static void secp256k1_ge_table_set_globalz(size_t len, secp256k1_ge *a, const secp256k1_fe *zr); -/** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to - * the same global z "denominator". zr must contain the known z-ratios such - * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y - * coordinates of the result are stored in r, the common z coordinate is - * stored in globalz. */ -static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr); +/** Check two group elements (affine) for equality in variable time. */ +static int secp256k1_ge_eq_var(const secp256k1_ge *a, const secp256k1_ge *b); + +/** Set a group element (affine) equal to the point at infinity. */ +static void secp256k1_ge_set_infinity(secp256k1_ge *r); /** Set a group element (jacobian) equal to the point at infinity. */ static void secp256k1_gej_set_infinity(secp256k1_gej *r); @@ -85,7 +114,14 @@ static void secp256k1_gej_set_infinity(secp256k1_gej *r); /** Set a group element (jacobian) equal to another which is given in affine coordinates. */ static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); -/** Compare the X coordinate of a group element (jacobian). */ +/** Check two group elements (jacobian) for equality in variable time. */ +static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b); + +/** Check two group elements (jacobian and affine) for equality in variable time. */ +static int secp256k1_gej_eq_ge_var(const secp256k1_gej *a, const secp256k1_ge *b); + +/** Compare the X coordinate of a group element (jacobian). + * The magnitude of the group element's X coordinate must not exceed 31. */ static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ @@ -94,17 +130,13 @@ static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); /** Check whether a group element is the point at infinity. */ static int secp256k1_gej_is_infinity(const secp256k1_gej *a); -/** Check whether a group element's y coordinate is a quadratic residue. */ -static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a); +/** Set r equal to the double of a. Constant time. */ +static void secp256k1_gej_double(secp256k1_gej *r, const secp256k1_gej *a); -/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). - * a may not be zero. Constant time. */ -static void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); - -/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). */ +/** Set r equal to the double of a. If rzr is not-NULL this sets *rzr such that r->z == a->z * *rzr (where infinity means an implicit z = 0). */ static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); -/** Set r equal to the sum of a and b. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ +/** Set r equal to the sum of a and b. If rzr is non-NULL this sets *rzr such that r->z == a->z * *rzr (a cannot be infinity in that case). */ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr); /** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */ @@ -112,16 +144,14 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const /** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time - guarantee, and b is allowed to be infinity. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ + guarantee, and b is allowed to be infinity. If rzr is non-NULL this sets *rzr such that r->z == a->z * *rzr (a cannot be infinity in that case). */ static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr); /** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv); -#ifdef USE_ENDOMORPHISM /** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a); -#endif /** Clear a secp256k1_gej to prevent leaking sensitive information. */ static void secp256k1_gej_clear(secp256k1_gej *r); @@ -135,10 +165,48 @@ static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge /** Convert a group element back from the storage type. */ static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +static void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag); + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); /** Rescale a jacobian point by b which must be non-zero. Constant-time. */ static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b); -#endif +/** Convert a group element that is not infinity to a 64-byte array. The output + * array is platform-dependent. */ +static void secp256k1_ge_to_bytes(unsigned char *buf, const secp256k1_ge *a); + +/** Convert a 64-byte array into group element. This function assumes that the + * provided buffer correctly encodes a group element. */ +static void secp256k1_ge_from_bytes(secp256k1_ge *r, const unsigned char *buf); + +/** Convert a group element (that is allowed to be infinity) to a 64-byte + * array. The output array is platform-dependent. */ +static void secp256k1_ge_to_bytes_ext(unsigned char *data, const secp256k1_ge *ge); + +/** Convert a 64-byte array into a group element. This function assumes that the + * provided buffer is the output of secp256k1_ge_to_bytes_ext. */ +static void secp256k1_ge_from_bytes_ext(secp256k1_ge *ge, const unsigned char *data); + +/** Determine if a point (which is assumed to be on the curve) is in the correct (sub)group of the curve. + * + * In normal mode, the used group is secp256k1, which has cofactor=1 meaning that every point on the curve is in the + * group, and this function returns always true. + * + * When compiling in exhaustive test mode, a slightly different curve equation is used, leading to a group with a + * (very) small subgroup, and that subgroup is what is used for all cryptographic operations. In that mode, this + * function checks whether a point that is on the curve is in fact also in that subgroup. + */ +static int secp256k1_ge_is_in_correct_subgroup(const secp256k1_ge* ge); + +/** Check invariants on an affine group element (no-op unless VERIFY is enabled). */ +static void secp256k1_ge_verify(const secp256k1_ge *a); +#define SECP256K1_GE_VERIFY(a) secp256k1_ge_verify(a) + +/** Check invariants on a Jacobian group element (no-op unless VERIFY is enabled). */ +static void secp256k1_gej_verify(const secp256k1_gej *a); +#define SECP256K1_GEJ_VERIFY(a) secp256k1_gej_verify(a) + +#endif /* SECP256K1_GROUP_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/group_impl.h b/crypto/secp256k1/libsecp256k1/src/group_impl.h index 7d723532ff..c668fb2401 100644 --- a/crypto/secp256k1/libsecp256k1/src/group_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/group_impl.h @@ -1,104 +1,165 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_GROUP_IMPL_H_ -#define _SECP256K1_GROUP_IMPL_H_ +#ifndef SECP256K1_GROUP_IMPL_H +#define SECP256K1_GROUP_IMPL_H + +#include -#include "num.h" #include "field.h" #include "group.h" +#include "util.h" -/* These points can be generated in sage as follows: - * - * 0. Setup a worksheet with the following parameters. - * b = 4 # whatever CURVE_B will be set to - * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) - * C = EllipticCurve ([F (0), F (b)]) - * - * 1. Determine all the small orders available to you. (If there are - * no satisfactory ones, go back and change b.) - * print C.order().factor(limit=1000) - * - * 2. Choose an order as one of the prime factors listed in the above step. - * (You can also multiply some to get a composite order, though the - * tests will crash trying to invert scalars during signing.) We take a - * random point and scale it to drop its order to the desired value. - * There is some probability this won't work; just try again. - * order = 199 - * P = C.random_point() - * P = (int(P.order()) / int(order)) * P - * assert(P.order() == order) - * - * 3. Print the values. You'll need to use a vim macro or something to - * split the hex output into 4-byte chunks. - * print "%x %x" % P.xy() +/* Begin of section generated by sage/gen_exhaustive_groups.sage. */ +#define SECP256K1_G_ORDER_7 SECP256K1_GE_CONST(\ + 0x66625d13, 0x317ffe44, 0x63d32cff, 0x1ca02b9b,\ + 0xe5c6d070, 0x50b4b05e, 0x81cc30db, 0xf5166f0a,\ + 0x1e60e897, 0xa7c00c7c, 0x2df53eb6, 0x98274ff4,\ + 0x64252f42, 0x8ca44e17, 0x3b25418c, 0xff4ab0cf\ +) +#define SECP256K1_G_ORDER_13 SECP256K1_GE_CONST(\ + 0xa2482ff8, 0x4bf34edf, 0xa51262fd, 0xe57921db,\ + 0xe0dd2cb7, 0xa5914790, 0xbc71631f, 0xc09704fb,\ + 0x942536cb, 0xa3e49492, 0x3a701cc3, 0xee3e443f,\ + 0xdf182aa9, 0x15b8aa6a, 0x166d3b19, 0xba84b045\ +) +#define SECP256K1_G_ORDER_199 SECP256K1_GE_CONST(\ + 0x7fb07b5c, 0xd07c3bda, 0x553902e2, 0x7a87ea2c,\ + 0x35108a7f, 0x051f41e5, 0xb76abad5, 0x1f2703ad,\ + 0x0a251539, 0x5b4c4438, 0x952a634f, 0xac10dd4d,\ + 0x6d6f4745, 0x98990c27, 0x3a4f3116, 0xd32ff969\ +) +/** Generator for secp256k1, value 'g' defined in + * "Standards for Efficient Cryptography" (SEC2) 2.7.1. + */ +#define SECP256K1_G SECP256K1_GE_CONST(\ + 0x79be667e, 0xf9dcbbac, 0x55a06295, 0xce870b07,\ + 0x029bfcdb, 0x2dce28d9, 0x59f2815b, 0x16f81798,\ + 0x483ada77, 0x26a3c465, 0x5da4fbfc, 0x0e1108a8,\ + 0xfd17b448, 0xa6855419, 0x9c47d08f, 0xfb10d4b8\ +) +/* These exhaustive group test orders and generators are chosen such that: + * - The field size is equal to that of secp256k1, so field code is the same. + * - The curve equation is of the form y^2=x^3+B for some small constant B. + * - The subgroup has a generator 2*P, where P.x is as small as possible. + * - The subgroup has size less than 1000 to permit exhaustive testing. + * - The subgroup admits an endomorphism of the form lambda*(x,y) == (beta*x,y). */ #if defined(EXHAUSTIVE_TEST_ORDER) -# if EXHAUSTIVE_TEST_ORDER == 199 -const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0xFA7CC9A7, 0x0737F2DB, 0xA749DD39, 0x2B4FB069, - 0x3B017A7D, 0xA808C2F1, 0xFB12940C, 0x9EA66C18, - 0x78AC123A, 0x5ED8AEF3, 0x8732BC91, 0x1F3A2868, - 0x48DF246C, 0x808DAE72, 0xCFE52572, 0x7F0501ED -); +# if EXHAUSTIVE_TEST_ORDER == 7 + +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_7; +#define SECP256K1_B 6 -const int CURVE_B = 4; # elif EXHAUSTIVE_TEST_ORDER == 13 -const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0xedc60018, 0xa51a786b, 0x2ea91f4d, 0x4c9416c0, - 0x9de54c3b, 0xa1316554, 0x6cf4345c, 0x7277ef15, - 0x54cb1b6b, 0xdc8c1273, 0x087844ea, 0x43f4603e, - 0x0eaf9a43, 0xf6effe55, 0x939f806d, 0x37adf8ac -); -const int CURVE_B = 2; + +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_13; +#define SECP256K1_B 2 + +# elif EXHAUSTIVE_TEST_ORDER == 199 + +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_199; +#define SECP256K1_B 4 + # else # error No known generator for the specified exhaustive test group order. # endif #else -/** Generator for secp256k1, value 'g' defined in - * "Standards for Efficient Cryptography" (SEC2) 2.7.1. - */ -static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL, - 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL, - 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL, - 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL -); -const int CURVE_B = 7; +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G; +#define SECP256K1_B 7 + #endif +/* End of section generated by sage/gen_exhaustive_groups.sage. */ +static void secp256k1_ge_verify(const secp256k1_ge *a) { + SECP256K1_FE_VERIFY(&a->x); + SECP256K1_FE_VERIFY(&a->y); + SECP256K1_FE_VERIFY_MAGNITUDE(&a->x, SECP256K1_GE_X_MAGNITUDE_MAX); + SECP256K1_FE_VERIFY_MAGNITUDE(&a->y, SECP256K1_GE_Y_MAGNITUDE_MAX); + VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); + (void)a; +} + +static void secp256k1_gej_verify(const secp256k1_gej *a) { + SECP256K1_FE_VERIFY(&a->x); + SECP256K1_FE_VERIFY(&a->y); + SECP256K1_FE_VERIFY(&a->z); + SECP256K1_FE_VERIFY_MAGNITUDE(&a->x, SECP256K1_GEJ_X_MAGNITUDE_MAX); + SECP256K1_FE_VERIFY_MAGNITUDE(&a->y, SECP256K1_GEJ_Y_MAGNITUDE_MAX); + SECP256K1_FE_VERIFY_MAGNITUDE(&a->z, SECP256K1_GEJ_Z_MAGNITUDE_MAX); + VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); + (void)a; +} + +/* Set r to the affine coordinates of Jacobian point (a.x, a.y, 1/zi). */ static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { secp256k1_fe zi2; secp256k1_fe zi3; + SECP256K1_GEJ_VERIFY(a); + SECP256K1_FE_VERIFY(zi); + VERIFY_CHECK(!a->infinity); + secp256k1_fe_sqr(&zi2, zi); secp256k1_fe_mul(&zi3, &zi2, zi); secp256k1_fe_mul(&r->x, &a->x, &zi2); secp256k1_fe_mul(&r->y, &a->y, &zi3); r->infinity = a->infinity; + + SECP256K1_GE_VERIFY(r); +} + +/* Set r to the affine coordinates of Jacobian point (a.x, a.y, 1/zi). */ +static void secp256k1_ge_set_ge_zinv(secp256k1_ge *r, const secp256k1_ge *a, const secp256k1_fe *zi) { + secp256k1_fe zi2; + secp256k1_fe zi3; + SECP256K1_GE_VERIFY(a); + SECP256K1_FE_VERIFY(zi); + VERIFY_CHECK(!a->infinity); + + secp256k1_fe_sqr(&zi2, zi); + secp256k1_fe_mul(&zi3, &zi2, zi); + secp256k1_fe_mul(&r->x, &a->x, &zi2); + secp256k1_fe_mul(&r->y, &a->y, &zi3); + r->infinity = a->infinity; + + SECP256K1_GE_VERIFY(r); } static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y) { + SECP256K1_FE_VERIFY(x); + SECP256K1_FE_VERIFY(y); + r->infinity = 0; r->x = *x; r->y = *y; + + SECP256K1_GE_VERIFY(r); } static int secp256k1_ge_is_infinity(const secp256k1_ge *a) { + SECP256K1_GE_VERIFY(a); + return a->infinity; } static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a) { + SECP256K1_GE_VERIFY(a); + *r = *a; secp256k1_fe_normalize_weak(&r->y); secp256k1_fe_negate(&r->y, &r->y, 1); + + SECP256K1_GE_VERIFY(r); } static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) { secp256k1_fe z2, z3; + SECP256K1_GEJ_VERIFY(a); + r->infinity = a->infinity; secp256k1_fe_inv(&a->z, &a->z); secp256k1_fe_sqr(&z2, &a->z); @@ -108,78 +169,99 @@ static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) { secp256k1_fe_set_int(&a->z, 1); r->x = a->x; r->y = a->y; + + SECP256K1_GEJ_VERIFY(a); + SECP256K1_GE_VERIFY(r); } static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) { secp256k1_fe z2, z3; - r->infinity = a->infinity; - if (a->infinity) { + SECP256K1_GEJ_VERIFY(a); + + if (secp256k1_gej_is_infinity(a)) { + secp256k1_ge_set_infinity(r); return; } + r->infinity = 0; secp256k1_fe_inv_var(&a->z, &a->z); secp256k1_fe_sqr(&z2, &a->z); secp256k1_fe_mul(&z3, &a->z, &z2); secp256k1_fe_mul(&a->x, &a->x, &z2); secp256k1_fe_mul(&a->y, &a->y, &z3); secp256k1_fe_set_int(&a->z, 1); - r->x = a->x; - r->y = a->y; + secp256k1_ge_set_xy(r, &a->x, &a->y); + + SECP256K1_GEJ_VERIFY(a); + SECP256K1_GE_VERIFY(r); } -static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb) { - secp256k1_fe *az; - secp256k1_fe *azi; +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) { + secp256k1_fe u; size_t i; - size_t count = 0; - az = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * len); + size_t last_i = SIZE_MAX; +#ifdef VERIFY + for (i = 0; i < len; i++) { + SECP256K1_GEJ_VERIFY(&a[i]); + } +#endif + + for (i = 0; i < len; i++) { + if (a[i].infinity) { + secp256k1_ge_set_infinity(&r[i]); + } else { + /* Use destination's x coordinates as scratch space */ + if (last_i == SIZE_MAX) { + r[i].x = a[i].z; + } else { + secp256k1_fe_mul(&r[i].x, &r[last_i].x, &a[i].z); + } + last_i = i; + } + } + if (last_i == SIZE_MAX) { + return; + } + secp256k1_fe_inv_var(&u, &r[last_i].x); + + i = last_i; + while (i > 0) { + i--; + if (!a[i].infinity) { + secp256k1_fe_mul(&r[last_i].x, &r[i].x, &u); + secp256k1_fe_mul(&u, &u, &a[last_i].z); + last_i = i; + } + } + VERIFY_CHECK(!a[last_i].infinity); + r[last_i].x = u; + for (i = 0; i < len; i++) { if (!a[i].infinity) { - az[count++] = a[i].z; + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x); } } - azi = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * count); - secp256k1_fe_inv_all_var(azi, az, count); - free(az); - - count = 0; +#ifdef VERIFY for (i = 0; i < len; i++) { - r[i].infinity = a[i].infinity; - if (!a[i].infinity) { - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &azi[count++]); - } + SECP256K1_GE_VERIFY(&r[i]); } - free(azi); +#endif } -static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len) { - size_t i = len - 1; - secp256k1_fe zi; - - if (len > 0) { - /* Compute the inverse of the last z coordinate, and use it to compute the last affine output. */ - secp256k1_fe_inv(&zi, &a[i].z); - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); - - /* Work out way backwards, using the z-ratios to scale the x/y values. */ - while (i > 0) { - secp256k1_fe_mul(&zi, &zi, &zr[i]); - i--; - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); - } - } -} - -static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr) { - size_t i = len - 1; +static void secp256k1_ge_table_set_globalz(size_t len, secp256k1_ge *a, const secp256k1_fe *zr) { + size_t i; secp256k1_fe zs; +#ifdef VERIFY + for (i = 0; i < len; i++) { + SECP256K1_GE_VERIFY(&a[i]); + SECP256K1_FE_VERIFY(&zr[i]); + } +#endif if (len > 0) { - /* The z of the final point gives us the "global Z" for the table. */ - r[i].x = a[i].x; - r[i].y = a[i].y; - *globalz = a[i].z; - r[i].infinity = 0; + i = len - 1; + /* Ensure all y values are in weak normal form for fast negation of points */ + secp256k1_fe_normalize_weak(&a[i].y); zs = zr[i]; /* Work our way backwards, using the z-ratios to scale the x/y values. */ @@ -188,125 +270,193 @@ static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp secp256k1_fe_mul(&zs, &zs, &zr[i]); } i--; - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zs); + secp256k1_ge_set_ge_zinv(&a[i], &a[i], &zs); } } + +#ifdef VERIFY + for (i = 0; i < len; i++) { + SECP256K1_GE_VERIFY(&a[i]); + } +#endif } static void secp256k1_gej_set_infinity(secp256k1_gej *r) { r->infinity = 1; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); - secp256k1_fe_clear(&r->z); + secp256k1_fe_set_int(&r->x, 0); + secp256k1_fe_set_int(&r->y, 0); + secp256k1_fe_set_int(&r->z, 0); + + SECP256K1_GEJ_VERIFY(r); +} + +static void secp256k1_ge_set_infinity(secp256k1_ge *r) { + r->infinity = 1; + secp256k1_fe_set_int(&r->x, 0); + secp256k1_fe_set_int(&r->y, 0); + + SECP256K1_GE_VERIFY(r); } static void secp256k1_gej_clear(secp256k1_gej *r) { - r->infinity = 0; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); - secp256k1_fe_clear(&r->z); + secp256k1_memclear(r, sizeof(secp256k1_gej)); } static void secp256k1_ge_clear(secp256k1_ge *r) { - r->infinity = 0; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); + secp256k1_memclear(r, sizeof(secp256k1_ge)); } -static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x) { - secp256k1_fe x2, x3, c; +static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { + secp256k1_fe x2, x3; + int ret; + SECP256K1_FE_VERIFY(x); + r->x = *x; secp256k1_fe_sqr(&x2, x); secp256k1_fe_mul(&x3, x, &x2); r->infinity = 0; - secp256k1_fe_set_int(&c, CURVE_B); - secp256k1_fe_add(&c, &x3); - return secp256k1_fe_sqrt(&r->y, &c); -} - -static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { - if (!secp256k1_ge_set_xquad(r, x)) { - return 0; - } + secp256k1_fe_add_int(&x3, SECP256K1_B); + ret = secp256k1_fe_sqrt(&r->y, &x3); secp256k1_fe_normalize_var(&r->y); if (secp256k1_fe_is_odd(&r->y) != odd) { secp256k1_fe_negate(&r->y, &r->y, 1); } - return 1; + SECP256K1_GE_VERIFY(r); + return ret; } static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a) { + SECP256K1_GE_VERIFY(a); + r->infinity = a->infinity; r->x = a->x; r->y = a->y; secp256k1_fe_set_int(&r->z, 1); + + SECP256K1_GEJ_VERIFY(r); +} + +static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b) { + secp256k1_gej tmp; + SECP256K1_GEJ_VERIFY(b); + SECP256K1_GEJ_VERIFY(a); + + secp256k1_gej_neg(&tmp, a); + secp256k1_gej_add_var(&tmp, &tmp, b, NULL); + return secp256k1_gej_is_infinity(&tmp); +} + +static int secp256k1_gej_eq_ge_var(const secp256k1_gej *a, const secp256k1_ge *b) { + secp256k1_gej tmp; + SECP256K1_GEJ_VERIFY(a); + SECP256K1_GE_VERIFY(b); + + secp256k1_gej_neg(&tmp, a); + secp256k1_gej_add_ge_var(&tmp, &tmp, b, NULL); + return secp256k1_gej_is_infinity(&tmp); +} + +static int secp256k1_ge_eq_var(const secp256k1_ge *a, const secp256k1_ge *b) { + secp256k1_fe tmp; + SECP256K1_GE_VERIFY(a); + SECP256K1_GE_VERIFY(b); + + if (a->infinity != b->infinity) return 0; + if (a->infinity) return 1; + + tmp = a->x; + secp256k1_fe_normalize_weak(&tmp); + if (!secp256k1_fe_equal(&tmp, &b->x)) return 0; + + tmp = a->y; + secp256k1_fe_normalize_weak(&tmp); + if (!secp256k1_fe_equal(&tmp, &b->y)) return 0; + + return 1; } static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) { - secp256k1_fe r, r2; + secp256k1_fe r; + SECP256K1_FE_VERIFY(x); + SECP256K1_GEJ_VERIFY(a); VERIFY_CHECK(!a->infinity); + secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); - r2 = a->x; secp256k1_fe_normalize_weak(&r2); - return secp256k1_fe_equal_var(&r, &r2); + return secp256k1_fe_equal(&r, &a->x); } static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) { + SECP256K1_GEJ_VERIFY(a); + r->infinity = a->infinity; r->x = a->x; r->y = a->y; r->z = a->z; secp256k1_fe_normalize_weak(&r->y); secp256k1_fe_negate(&r->y, &r->y, 1); + + SECP256K1_GEJ_VERIFY(r); } static int secp256k1_gej_is_infinity(const secp256k1_gej *a) { + SECP256K1_GEJ_VERIFY(a); + return a->infinity; } -static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) { - secp256k1_fe y2, x3, z2, z6; - if (a->infinity) { - return 0; - } - /** y^2 = x^3 + 7 - * (Y/Z^3)^2 = (X/Z^2)^3 + 7 - * Y^2 / Z^6 = X^3 / Z^6 + 7 - * Y^2 = X^3 + 7*Z^6 - */ - secp256k1_fe_sqr(&y2, &a->y); - secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); - secp256k1_fe_mul_int(&z6, CURVE_B); - secp256k1_fe_add(&x3, &z6); - secp256k1_fe_normalize_weak(&x3); - return secp256k1_fe_equal_var(&y2, &x3); -} - static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { - secp256k1_fe y2, x3, c; + secp256k1_fe y2, x3; + SECP256K1_GE_VERIFY(a); + if (a->infinity) { return 0; } /* y^2 = x^3 + 7 */ secp256k1_fe_sqr(&y2, &a->y); secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_set_int(&c, CURVE_B); - secp256k1_fe_add(&x3, &c); - secp256k1_fe_normalize_weak(&x3); - return secp256k1_fe_equal_var(&y2, &x3); + secp256k1_fe_add_int(&x3, SECP256K1_B); + return secp256k1_fe_equal(&y2, &x3); +} + +static SECP256K1_INLINE void secp256k1_gej_double(secp256k1_gej *r, const secp256k1_gej *a) { + /* Operations: 3 mul, 4 sqr, 8 add/half/mul_int/negate */ + secp256k1_fe l, s, t; + SECP256K1_GEJ_VERIFY(a); + + r->infinity = a->infinity; + + /* Formula used: + * L = (3/2) * X1^2 + * S = Y1^2 + * T = -X1*S + * X3 = L^2 + 2*T + * Y3 = -(L*(X3 + T) + S^2) + * Z3 = Y1*Z1 + */ + + secp256k1_fe_mul(&r->z, &a->z, &a->y); /* Z3 = Y1*Z1 (1) */ + secp256k1_fe_sqr(&s, &a->y); /* S = Y1^2 (1) */ + secp256k1_fe_sqr(&l, &a->x); /* L = X1^2 (1) */ + secp256k1_fe_mul_int(&l, 3); /* L = 3*X1^2 (3) */ + secp256k1_fe_half(&l); /* L = 3/2*X1^2 (2) */ + secp256k1_fe_negate(&t, &s, 1); /* T = -S (2) */ + secp256k1_fe_mul(&t, &t, &a->x); /* T = -X1*S (1) */ + secp256k1_fe_sqr(&r->x, &l); /* X3 = L^2 (1) */ + secp256k1_fe_add(&r->x, &t); /* X3 = L^2 + T (2) */ + secp256k1_fe_add(&r->x, &t); /* X3 = L^2 + 2*T (3) */ + secp256k1_fe_sqr(&s, &s); /* S' = S^2 (1) */ + secp256k1_fe_add(&t, &r->x); /* T' = X3 + T (4) */ + secp256k1_fe_mul(&r->y, &t, &l); /* Y3 = L*(X3 + T) (1) */ + secp256k1_fe_add(&r->y, &s); /* Y3 = L*(X3 + T) + S^2 (2) */ + secp256k1_fe_negate(&r->y, &r->y, 2); /* Y3 = -(L*(X3 + T) + S^2) (3) */ + + SECP256K1_GEJ_VERIFY(r); } static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { - /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate. - * - * Note that there is an implementation described at - * https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - * which trades a multiply for a square, but in practice this is actually slower, - * mainly because it requires more normalizations. - */ - secp256k1_fe t1,t2,t3,t4; + SECP256K1_GEJ_VERIFY(a); + /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. @@ -317,8 +467,8 @@ static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, s * the infinity flag even though the point doubles to infinity, and the result * point will be gibberish (z = 0 but infinity = 0). */ - r->infinity = a->infinity; - if (r->infinity) { + if (a->infinity) { + secp256k1_gej_set_infinity(r); if (rzr != NULL) { secp256k1_fe_set_int(rzr, 1); } @@ -328,46 +478,24 @@ static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, s if (rzr != NULL) { *rzr = a->y; secp256k1_fe_normalize_weak(rzr); - secp256k1_fe_mul_int(rzr, 2); } - secp256k1_fe_mul(&r->z, &a->z, &a->y); - secp256k1_fe_mul_int(&r->z, 2); /* Z' = 2*Y*Z (2) */ - secp256k1_fe_sqr(&t1, &a->x); - secp256k1_fe_mul_int(&t1, 3); /* T1 = 3*X^2 (3) */ - secp256k1_fe_sqr(&t2, &t1); /* T2 = 9*X^4 (1) */ - secp256k1_fe_sqr(&t3, &a->y); - secp256k1_fe_mul_int(&t3, 2); /* T3 = 2*Y^2 (2) */ - secp256k1_fe_sqr(&t4, &t3); - secp256k1_fe_mul_int(&t4, 2); /* T4 = 8*Y^4 (2) */ - secp256k1_fe_mul(&t3, &t3, &a->x); /* T3 = 2*X*Y^2 (1) */ - r->x = t3; - secp256k1_fe_mul_int(&r->x, 4); /* X' = 8*X*Y^2 (4) */ - secp256k1_fe_negate(&r->x, &r->x, 4); /* X' = -8*X*Y^2 (5) */ - secp256k1_fe_add(&r->x, &t2); /* X' = 9*X^4 - 8*X*Y^2 (6) */ - secp256k1_fe_negate(&t2, &t2, 1); /* T2 = -9*X^4 (2) */ - secp256k1_fe_mul_int(&t3, 6); /* T3 = 12*X*Y^2 (6) */ - secp256k1_fe_add(&t3, &t2); /* T3 = 12*X*Y^2 - 9*X^4 (8) */ - secp256k1_fe_mul(&r->y, &t1, &t3); /* Y' = 36*X^3*Y^2 - 27*X^6 (1) */ - secp256k1_fe_negate(&t2, &t4, 2); /* T2 = -8*Y^4 (3) */ - secp256k1_fe_add(&r->y, &t2); /* Y' = 36*X^3*Y^2 - 27*X^6 - 8*Y^4 (4) */ -} + secp256k1_gej_double(r, a); -static SECP256K1_INLINE void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { - VERIFY_CHECK(!secp256k1_gej_is_infinity(a)); - secp256k1_gej_double_var(r, a, rzr); + SECP256K1_GEJ_VERIFY(r); } static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) { - /* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */ - secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + /* 12 mul, 4 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */ + secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, h2, h3, t; + SECP256K1_GEJ_VERIFY(a); + SECP256K1_GEJ_VERIFY(b); if (a->infinity) { VERIFY_CHECK(rzr == NULL); *r = *b; return; } - if (b->infinity) { if (rzr != NULL) { secp256k1_fe_set_int(rzr, 1); @@ -376,7 +504,6 @@ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, cons return; } - r->infinity = 0; secp256k1_fe_sqr(&z22, &b->z); secp256k1_fe_sqr(&z12, &a->z); secp256k1_fe_mul(&u1, &a->x, &z22); @@ -384,7 +511,7 @@ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, cons secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { secp256k1_gej_double_var(r, a, rzr); @@ -392,28 +519,42 @@ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, cons if (rzr != NULL) { secp256k1_fe_set_int(rzr, 0); } - r->infinity = 1; + secp256k1_gej_set_infinity(r); } return; } - secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); - secp256k1_fe_mul(&h, &h, &b->z); + + r->infinity = 0; + secp256k1_fe_mul(&t, &h, &b->z); if (rzr != NULL) { - *rzr = h; + *rzr = t; } - secp256k1_fe_mul(&r->z, &a->z, &h); + secp256k1_fe_mul(&r->z, &a->z, &t); + + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_negate(&h2, &h2, 1); + secp256k1_fe_mul(&h3, &h2, &h); secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); + + secp256k1_fe_sqr(&r->x, &i); + secp256k1_fe_add(&r->x, &h3); + secp256k1_fe_add(&r->x, &t); + secp256k1_fe_add(&r->x, &t); + + secp256k1_fe_add(&t, &r->x); + secp256k1_fe_mul(&r->y, &t, &i); + secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_add(&r->y, &h3); + + SECP256K1_GEJ_VERIFY(r); } static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) { - /* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ - secp256k1_fe z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + /* Operations: 8 mul, 3 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */ + secp256k1_fe z12, u1, u2, s1, s2, h, i, h2, h3, t; + SECP256K1_GEJ_VERIFY(a); + SECP256K1_GE_VERIFY(b); + if (a->infinity) { VERIFY_CHECK(rzr == NULL); secp256k1_gej_set_ge(r, b); @@ -426,15 +567,14 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, c *r = *a; return; } - r->infinity = 0; secp256k1_fe_sqr(&z12, &a->z); - u1 = a->x; secp256k1_fe_normalize_weak(&u1); + u1 = a->x; secp256k1_fe_mul(&u2, &b->x, &z12); - s1 = a->y; secp256k1_fe_normalize_weak(&s1); + s1 = a->y; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + secp256k1_fe_negate(&h, &u1, SECP256K1_GEJ_X_MAGNITUDE_MAX); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { secp256k1_gej_double_var(r, a, rzr); @@ -442,32 +582,43 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, c if (rzr != NULL) { secp256k1_fe_set_int(rzr, 0); } - r->infinity = 1; + secp256k1_gej_set_infinity(r); } return; } - secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); + + r->infinity = 0; if (rzr != NULL) { *rzr = h; } secp256k1_fe_mul(&r->z, &a->z, &h); + + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_negate(&h2, &h2, 1); + secp256k1_fe_mul(&h3, &h2, &h); secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); + + secp256k1_fe_sqr(&r->x, &i); + secp256k1_fe_add(&r->x, &h3); + secp256k1_fe_add(&r->x, &t); + secp256k1_fe_add(&r->x, &t); + + secp256k1_fe_add(&t, &r->x); + secp256k1_fe_mul(&r->y, &t, &i); + secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_add(&r->y, &h3); + + SECP256K1_GEJ_VERIFY(r); + if (rzr != NULL) SECP256K1_FE_VERIFY(rzr); } static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) { - /* 9 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ - secp256k1_fe az, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + /* Operations: 9 mul, 3 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */ + secp256k1_fe az, z12, u1, u2, s1, s2, h, i, h2, h3, t; + SECP256K1_GEJ_VERIFY(a); + SECP256K1_GE_VERIFY(b); + SECP256K1_FE_VERIFY(bzinv); - if (b->infinity) { - *r = *a; - return; - } if (a->infinity) { secp256k1_fe bzinv2, bzinv3; r->infinity = b->infinity; @@ -476,9 +627,13 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe_mul(&r->x, &b->x, &bzinv2); secp256k1_fe_mul(&r->y, &b->y, &bzinv3); secp256k1_fe_set_int(&r->z, 1); + SECP256K1_GEJ_VERIFY(r); + return; + } + if (b->infinity) { + *r = *a; return; } - r->infinity = 0; /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to * secp256k1's isomorphism we can multiply the Z coordinates on both sides @@ -491,42 +646,53 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe_mul(&az, &a->z, bzinv); secp256k1_fe_sqr(&z12, &az); - u1 = a->x; secp256k1_fe_normalize_weak(&u1); + u1 = a->x; secp256k1_fe_mul(&u2, &b->x, &z12); - s1 = a->y; secp256k1_fe_normalize_weak(&s1); + s1 = a->y; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az); - secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + secp256k1_fe_negate(&h, &u1, SECP256K1_GEJ_X_MAGNITUDE_MAX); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { secp256k1_gej_double_var(r, a, NULL); } else { - r->infinity = 1; + secp256k1_gej_set_infinity(r); } return; } - secp256k1_fe_sqr(&i2, &i); + + r->infinity = 0; + secp256k1_fe_mul(&r->z, &a->z, &h); + secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); - r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h); + secp256k1_fe_negate(&h2, &h2, 1); + secp256k1_fe_mul(&h3, &h2, &h); secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); + + secp256k1_fe_sqr(&r->x, &i); + secp256k1_fe_add(&r->x, &h3); + secp256k1_fe_add(&r->x, &t); + secp256k1_fe_add(&r->x, &t); + + secp256k1_fe_add(&t, &r->x); + secp256k1_fe_mul(&r->y, &t, &i); + secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_add(&r->y, &h3); + + SECP256K1_GEJ_VERIFY(r); } static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b) { - /* Operations: 7 mul, 5 sqr, 4 normalize, 21 mul_int/add/negate/cmov */ - static const secp256k1_fe fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); + /* Operations: 7 mul, 5 sqr, 21 add/cmov/half/mul_int/negate/normalizes_to_zero */ secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr; secp256k1_fe m_alt, rr_alt; - int infinity, degenerate; + int degenerate; + SECP256K1_GEJ_VERIFY(a); + SECP256K1_GE_VERIFY(b); VERIFY_CHECK(!b->infinity); - VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); - /** In: + /* In: * Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks. * In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002. * we find as solution for a unified addition/doubling formula: @@ -540,11 +706,11 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const * Z = Z1*Z2 * T = U1+U2 * M = S1+S2 - * Q = T*M^2 + * Q = -T*M^2 * R = T^2-U1*U2 - * X3 = 4*(R^2-Q) - * Y3 = 4*(R*(3*Q-2*R^2)-M^4) - * Z3 = 2*M*Z + * X3 = R^2+Q + * Y3 = -(R*(2*X3+Q)+M^4)/2 + * Z3 = M*Z * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.) * * This formula has the benefit of being the same for both addition @@ -577,82 +743,104 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const */ secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ - u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ + u1 = a->x; /* u1 = U1 = X1*Z2^2 (GEJ_X_M) */ secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ - s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ + s1 = a->y; /* s1 = S1 = Y1*Z2^3 (GEJ_Y_M) */ secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z1^2 (1) */ secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ - t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ - m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ + t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (GEJ_X_M+1) */ + m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (GEJ_Y_M+1) */ secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ - secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 */ - secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */ - secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ - /** If lambda = R/M = 0/0 we have a problem (except in the "trivial" - * case that Z = z1z2 = 0, and this is special-cased later on). */ - degenerate = secp256k1_fe_normalizes_to_zero(&m) & - secp256k1_fe_normalizes_to_zero(&rr); + secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 (2) */ + secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (1) */ + secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (2) */ + /* If lambda = R/M = R/0 we have a problem (except in the "trivial" + * case that Z = z1z2 = 0, and this is special-cased later on). */ + degenerate = secp256k1_fe_normalizes_to_zero(&m); /* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2. * This means either x1 == beta*x2 or beta*x1 == x2, where beta is * a nontrivial cube root of one. In either case, an alternate * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2), * so we set R/M equal to this. */ rr_alt = s1; - secp256k1_fe_mul_int(&rr_alt, 2); /* rr = Y1*Z2^3 - Y2*Z1^3 (2) */ - secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 */ + secp256k1_fe_mul_int(&rr_alt, 2); /* rr_alt = Y1*Z2^3 - Y2*Z1^3 (GEJ_Y_M*2) */ + secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 (GEJ_X_M+2) */ - secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); - secp256k1_fe_cmov(&m_alt, &m, !degenerate); - /* Now Ralt / Malt = lambda and is guaranteed not to be 0/0. + secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); /* rr_alt (GEJ_Y_M*2) */ + secp256k1_fe_cmov(&m_alt, &m, !degenerate); /* m_alt (GEJ_X_M+2) */ + /* Now Ralt / Malt = lambda and is guaranteed not to be Ralt / 0. * From here on out Ralt and Malt represent the numerator * and denominator of lambda; R and M represent the explicit * expressions x1^2 + x2^2 + x1x2 and y1 + y2. */ secp256k1_fe_sqr(&n, &m_alt); /* n = Malt^2 (1) */ - secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*Malt^2 (1) */ + secp256k1_fe_negate(&q, &t, + SECP256K1_GEJ_X_MAGNITUDE_MAX + 1); /* q = -T (GEJ_X_M+2) */ + secp256k1_fe_mul(&q, &q, &n); /* q = Q = -T*Malt^2 (1) */ /* These two lines use the observation that either M == Malt or M == 0, * so M^3 * Malt is either Malt^4 (which is computed by squaring), or * zero (which is "computed" by cmov). So the cost is one squaring * versus two multiplications. */ - secp256k1_fe_sqr(&n, &n); - secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ + secp256k1_fe_sqr(&n, &n); /* n = Malt^4 (1) */ + secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (GEJ_Y_M+1) */ secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ - secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Malt*Z (1) */ - infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); - secp256k1_fe_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */ - secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ - secp256k1_fe_add(&t, &q); /* t = Ralt^2-Q (3) */ - secp256k1_fe_normalize_weak(&t); - r->x = t; /* r->x = Ralt^2-Q (1) */ - secp256k1_fe_mul_int(&t, 2); /* t = 2*x3 (2) */ - secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (4) */ - secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*x3 - Q) (1) */ - secp256k1_fe_add(&t, &n); /* t = Ralt*(2*x3 - Q) + M^3*Malt (3) */ - secp256k1_fe_negate(&r->y, &t, 3); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (4) */ - secp256k1_fe_normalize_weak(&r->y); - secp256k1_fe_mul_int(&r->x, 4); /* r->x = X3 = 4*(Ralt^2-Q) */ - secp256k1_fe_mul_int(&r->y, 4); /* r->y = Y3 = 4*Ralt*(Q - 2x3) - 4*M^3*Malt (4) */ + secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Z3 = Malt*Z (1) */ + secp256k1_fe_add(&t, &q); /* t = Ralt^2 + Q (2) */ + r->x = t; /* r->x = X3 = Ralt^2 + Q (2) */ + secp256k1_fe_mul_int(&t, 2); /* t = 2*X3 (4) */ + secp256k1_fe_add(&t, &q); /* t = 2*X3 + Q (5) */ + secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*X3 + Q) (1) */ + secp256k1_fe_add(&t, &n); /* t = Ralt*(2*X3 + Q) + M^3*Malt (GEJ_Y_M+2) */ + secp256k1_fe_negate(&r->y, &t, + SECP256K1_GEJ_Y_MAGNITUDE_MAX + 2); /* r->y = -(Ralt*(2*X3 + Q) + M^3*Malt) (GEJ_Y_M+3) */ + secp256k1_fe_half(&r->y); /* r->y = Y3 = -(Ralt*(2*X3 + Q) + M^3*Malt)/2 ((GEJ_Y_M+3)/2 + 1) */ - /** In case a->infinity == 1, replace r with (b->x, b->y, 1). */ + /* In case a->infinity == 1, replace r with (b->x, b->y, 1). */ secp256k1_fe_cmov(&r->x, &b->x, a->infinity); secp256k1_fe_cmov(&r->y, &b->y, a->infinity); - secp256k1_fe_cmov(&r->z, &fe_1, a->infinity); - r->infinity = infinity; + secp256k1_fe_cmov(&r->z, &secp256k1_fe_one, a->infinity); + + /* Set r->infinity if r->z is 0. + * + * If a->infinity is set, then r->infinity = (r->z == 0) = (1 == 0) = false, + * which is correct because the function assumes that b is not infinity. + * + * Now assume !a->infinity. This implies Z = Z1 != 0. + * + * Case y1 = -y2: + * In this case we could have a = -b, namely if x1 = x2. + * We have degenerate = true, r->z = (x1 - x2) * Z. + * Then r->infinity = ((x1 - x2)Z == 0) = (x1 == x2) = (a == -b). + * + * Case y1 != -y2: + * In this case, we can't have a = -b. + * We have degenerate = false, r->z = (y1 + y2) * Z. + * Then r->infinity = ((y1 + y2)Z == 0) = (y1 == -y2) = false. */ + r->infinity = secp256k1_fe_normalizes_to_zero(&r->z); + + SECP256K1_GEJ_VERIFY(r); } static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *s) { /* Operations: 4 mul, 1 sqr */ secp256k1_fe zz; - VERIFY_CHECK(!secp256k1_fe_is_zero(s)); + SECP256K1_GEJ_VERIFY(r); + SECP256K1_FE_VERIFY(s); + VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(s)); + secp256k1_fe_sqr(&zz, s); secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */ secp256k1_fe_mul(&r->y, &r->y, &zz); secp256k1_fe_mul(&r->y, &r->y, s); /* r->y *= s^3 */ secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */ + + SECP256K1_GEJ_VERIFY(r); } static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a) { secp256k1_fe x, y; + SECP256K1_GE_VERIFY(a); VERIFY_CHECK(!a->infinity); + x = a->x; secp256k1_fe_normalize(&x); y = a->y; @@ -665,6 +853,20 @@ static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storag secp256k1_fe_from_storage(&r->x, &a->x); secp256k1_fe_from_storage(&r->y, &a->y); r->infinity = 0; + + SECP256K1_GE_VERIFY(r); +} + +static SECP256K1_INLINE void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag) { + SECP256K1_GEJ_VERIFY(r); + SECP256K1_GEJ_VERIFY(a); + + secp256k1_fe_cmov(&r->x, &a->x, flag); + secp256k1_fe_cmov(&r->y, &a->y, flag); + secp256k1_fe_cmov(&r->z, &a->z, flag); + r->infinity ^= (r->infinity ^ a->infinity) & flag; + + SECP256K1_GEJ_VERIFY(r); } static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) { @@ -672,29 +874,101 @@ static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, secp256k1_fe_storage_cmov(&r->y, &a->y, flag); } -#ifdef USE_ENDOMORPHISM static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) { - static const secp256k1_fe beta = SECP256K1_FE_CONST( - 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul, - 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul - ); + SECP256K1_GE_VERIFY(a); + *r = *a; - secp256k1_fe_mul(&r->x, &r->x, &beta); + secp256k1_fe_mul(&r->x, &r->x, &secp256k1_const_beta); + + SECP256K1_GE_VERIFY(r); } -#endif -static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) { - secp256k1_fe yz; +static int secp256k1_ge_is_in_correct_subgroup(const secp256k1_ge* ge) { +#ifdef EXHAUSTIVE_TEST_ORDER + secp256k1_gej out; + int i; + SECP256K1_GE_VERIFY(ge); - if (a->infinity) { - return 0; + /* A very simple EC multiplication ladder that avoids a dependency on ecmult. */ + secp256k1_gej_set_infinity(&out); + for (i = 0; i < 32; ++i) { + secp256k1_gej_double_var(&out, &out, NULL); + if ((((uint32_t)EXHAUSTIVE_TEST_ORDER) >> (31 - i)) & 1) { + secp256k1_gej_add_ge_var(&out, &out, ge, NULL); + } } + return secp256k1_gej_is_infinity(&out); +#else + SECP256K1_GE_VERIFY(ge); - /* We rely on the fact that the Jacobi symbol of 1 / a->z^3 is the same as - * that of a->z. Thus a->y / a->z^3 is a quadratic residue iff a->y * a->z - is */ - secp256k1_fe_mul(&yz, &a->y, &a->z); - return secp256k1_fe_is_quad_var(&yz); + (void)ge; + /* The real secp256k1 group has cofactor 1, so the subgroup is the entire curve. */ + return 1; +#endif } -#endif +static int secp256k1_ge_x_on_curve_var(const secp256k1_fe *x) { + secp256k1_fe c; + secp256k1_fe_sqr(&c, x); + secp256k1_fe_mul(&c, &c, x); + secp256k1_fe_add_int(&c, SECP256K1_B); + return secp256k1_fe_is_square_var(&c); +} + +static int secp256k1_ge_x_frac_on_curve_var(const secp256k1_fe *xn, const secp256k1_fe *xd) { + /* We want to determine whether (xn/xd) is on the curve. + * + * (xn/xd)^3 + 7 is square <=> xd*xn^3 + 7*xd^4 is square (multiplying by xd^4, a square). + */ + secp256k1_fe r, t; + VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(xd)); + + secp256k1_fe_mul(&r, xd, xn); /* r = xd*xn */ + secp256k1_fe_sqr(&t, xn); /* t = xn^2 */ + secp256k1_fe_mul(&r, &r, &t); /* r = xd*xn^3 */ + secp256k1_fe_sqr(&t, xd); /* t = xd^2 */ + secp256k1_fe_sqr(&t, &t); /* t = xd^4 */ + VERIFY_CHECK(SECP256K1_B <= 31); + secp256k1_fe_mul_int(&t, SECP256K1_B); /* t = 7*xd^4 */ + secp256k1_fe_add(&r, &t); /* r = xd*xn^3 + 7*xd^4 */ + return secp256k1_fe_is_square_var(&r); +} + +static void secp256k1_ge_to_bytes(unsigned char *buf, const secp256k1_ge *a) { + secp256k1_ge_storage s; + + /* We require that the secp256k1_ge_storage type is exactly 64 bytes. + * This is formally not guaranteed by the C standard, but should hold on any + * sane compiler in the real world. */ + STATIC_ASSERT(sizeof(secp256k1_ge_storage) == 64); + VERIFY_CHECK(!secp256k1_ge_is_infinity(a)); + secp256k1_ge_to_storage(&s, a); + memcpy(buf, &s, 64); +} + +static void secp256k1_ge_from_bytes(secp256k1_ge *r, const unsigned char *buf) { + secp256k1_ge_storage s; + + STATIC_ASSERT(sizeof(secp256k1_ge_storage) == 64); + memcpy(&s, buf, 64); + secp256k1_ge_from_storage(r, &s); +} + +static void secp256k1_ge_to_bytes_ext(unsigned char *data, const secp256k1_ge *ge) { + if (secp256k1_ge_is_infinity(ge)) { + memset(data, 0, 64); + } else { + secp256k1_ge_to_bytes(data, ge); + } +} + +static void secp256k1_ge_from_bytes_ext(secp256k1_ge *ge, const unsigned char *data) { + static const unsigned char zeros[64] = { 0 }; + if (secp256k1_memcmp_var(data, zeros, sizeof(zeros)) == 0) { + secp256k1_ge_set_infinity(ge); + } else { + secp256k1_ge_from_bytes(ge, data); + } +} + +#endif /* SECP256K1_GROUP_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/hash.h b/crypto/secp256k1/libsecp256k1/src/hash.h index fca98cab9f..6d903ca7e0 100644 --- a/crypto/secp256k1/libsecp256k1/src/hash.h +++ b/crypto/secp256k1/libsecp256k1/src/hash.h @@ -1,41 +1,44 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_HASH_ -#define _SECP256K1_HASH_ +#ifndef SECP256K1_HASH_H +#define SECP256K1_HASH_H #include #include typedef struct { uint32_t s[8]; - uint32_t buf[16]; /* In big endian */ - size_t bytes; -} secp256k1_sha256_t; + unsigned char buf[64]; + uint64_t bytes; +} secp256k1_sha256; -static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash); -static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t size); -static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32); +static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); +static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); +static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); +static void secp256k1_sha256_clear(secp256k1_sha256 *hash); typedef struct { - secp256k1_sha256_t inner, outer; -} secp256k1_hmac_sha256_t; + secp256k1_sha256 inner, outer; +} secp256k1_hmac_sha256; -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t size); -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size); -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32); +static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); +static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); +static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); +static void secp256k1_hmac_sha256_clear(secp256k1_hmac_sha256 *hash); typedef struct { unsigned char v[32]; unsigned char k[32]; int retry; -} secp256k1_rfc6979_hmac_sha256_t; +} secp256k1_rfc6979_hmac_sha256; -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen); -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen); -static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng); +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); +static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); +static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); +static void secp256k1_rfc6979_hmac_sha256_clear(secp256k1_rfc6979_hmac_sha256 *rng); -#endif +#endif /* SECP256K1_HASH_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/hash_impl.h b/crypto/secp256k1/libsecp256k1/src/hash_impl.h index b47e65f830..956e0ea48b 100644 --- a/crypto/secp256k1/libsecp256k1/src/hash_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/hash_impl.h @@ -1,13 +1,14 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_HASH_IMPL_H_ -#define _SECP256K1_HASH_IMPL_H_ +#ifndef SECP256K1_HASH_IMPL_H +#define SECP256K1_HASH_IMPL_H #include "hash.h" +#include "util.h" #include #include @@ -27,13 +28,7 @@ (h) = t1 + t2; \ } while(0) -#ifdef WORDS_BIGENDIAN -#define BE32(x) (x) -#else -#define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) -#endif - -static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) { +static void secp256k1_sha256_initialize(secp256k1_sha256 *hash) { hash->s[0] = 0x6a09e667ul; hash->s[1] = 0xbb67ae85ul; hash->s[2] = 0x3c6ef372ul; @@ -46,26 +41,26 @@ static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) { } /** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */ -static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) { +static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* buf) { uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = BE32(chunk[0])); - Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = BE32(chunk[1])); - Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = BE32(chunk[2])); - Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = BE32(chunk[3])); - Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = BE32(chunk[4])); - Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = BE32(chunk[5])); - Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = BE32(chunk[6])); - Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = BE32(chunk[7])); - Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = BE32(chunk[8])); - Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = BE32(chunk[9])); - Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = BE32(chunk[10])); - Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = BE32(chunk[11])); - Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = BE32(chunk[12])); - Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = BE32(chunk[13])); - Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = BE32(chunk[14])); - Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = BE32(chunk[15])); + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = secp256k1_read_be32(&buf[0])); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = secp256k1_read_be32(&buf[4])); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = secp256k1_read_be32(&buf[8])); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = secp256k1_read_be32(&buf[12])); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = secp256k1_read_be32(&buf[16])); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = secp256k1_read_be32(&buf[20])); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = secp256k1_read_be32(&buf[24])); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = secp256k1_read_be32(&buf[28])); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = secp256k1_read_be32(&buf[32])); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = secp256k1_read_be32(&buf[36])); + Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = secp256k1_read_be32(&buf[40])); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = secp256k1_read_be32(&buf[44])); + Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = secp256k1_read_be32(&buf[48])); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = secp256k1_read_be32(&buf[52])); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = secp256k1_read_be32(&buf[56])); + Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = secp256k1_read_be32(&buf[60])); Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); @@ -128,47 +123,66 @@ static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) { s[7] += h; } -static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t len) { +static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t len) { size_t bufsize = hash->bytes & 0x3F; hash->bytes += len; - while (bufsize + len >= 64) { + VERIFY_CHECK(hash->bytes >= len); + while (len >= 64 - bufsize) { /* Fill the buffer, and process it. */ - memcpy(((unsigned char*)hash->buf) + bufsize, data, 64 - bufsize); - data += 64 - bufsize; - len -= 64 - bufsize; + size_t chunk_len = 64 - bufsize; + memcpy(hash->buf + bufsize, data, chunk_len); + data += chunk_len; + len -= chunk_len; secp256k1_sha256_transform(hash->s, hash->buf); bufsize = 0; } if (len) { /* Fill the buffer with what remains. */ - memcpy(((unsigned char*)hash->buf) + bufsize, data, len); + memcpy(hash->buf + bufsize, data, len); } } -static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32) { - static const unsigned char pad[64] = {0x80, 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, 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, 0, 0, 0}; - uint32_t sizedesc[2]; - uint32_t out[8]; - int i = 0; - sizedesc[0] = BE32(hash->bytes >> 29); - sizedesc[1] = BE32(hash->bytes << 3); +static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32) { + static const unsigned char pad[64] = {0x80}; + unsigned char sizedesc[8]; + int i; + /* The maximum message size of SHA256 is 2^64-1 bits. */ + VERIFY_CHECK(hash->bytes < ((uint64_t)1 << 61)); + secp256k1_write_be32(&sizedesc[0], hash->bytes >> 29); + secp256k1_write_be32(&sizedesc[4], hash->bytes << 3); secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); - secp256k1_sha256_write(hash, (const unsigned char*)sizedesc, 8); + secp256k1_sha256_write(hash, sizedesc, 8); for (i = 0; i < 8; i++) { - out[i] = BE32(hash->s[i]); + secp256k1_write_be32(&out32[4*i], hash->s[i]); hash->s[i] = 0; } - memcpy(out32, (const unsigned char*)out, 32); } -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) { - int n; +/* Initializes a sha256 struct and writes the 64 byte string + * SHA256(tag)||SHA256(tag) into it. */ +static void secp256k1_sha256_initialize_tagged(secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen) { + unsigned char buf[32]; + secp256k1_sha256_initialize(hash); + secp256k1_sha256_write(hash, tag, taglen); + secp256k1_sha256_finalize(hash, buf); + + secp256k1_sha256_initialize(hash); + secp256k1_sha256_write(hash, buf, 32); + secp256k1_sha256_write(hash, buf, 32); +} + +static void secp256k1_sha256_clear(secp256k1_sha256 *hash) { + secp256k1_memclear(hash, sizeof(*hash)); +} + +static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) { + size_t n; unsigned char rkey[64]; - if (keylen <= 64) { + if (keylen <= sizeof(rkey)) { memcpy(rkey, key, keylen); - memset(rkey + keylen, 0, 64 - keylen); + memset(rkey + keylen, 0, sizeof(rkey) - keylen); } else { - secp256k1_sha256_t sha256; + secp256k1_sha256 sha256; secp256k1_sha256_initialize(&sha256); secp256k1_sha256_write(&sha256, key, keylen); secp256k1_sha256_finalize(&sha256, rkey); @@ -176,34 +190,37 @@ static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, cons } secp256k1_sha256_initialize(&hash->outer); - for (n = 0; n < 64; n++) { + for (n = 0; n < sizeof(rkey); n++) { rkey[n] ^= 0x5c; } - secp256k1_sha256_write(&hash->outer, rkey, 64); + secp256k1_sha256_write(&hash->outer, rkey, sizeof(rkey)); secp256k1_sha256_initialize(&hash->inner); - for (n = 0; n < 64; n++) { + for (n = 0; n < sizeof(rkey); n++) { rkey[n] ^= 0x5c ^ 0x36; } - secp256k1_sha256_write(&hash->inner, rkey, 64); - memset(rkey, 0, 64); + secp256k1_sha256_write(&hash->inner, rkey, sizeof(rkey)); + secp256k1_memclear(rkey, sizeof(rkey)); } -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size) { +static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) { secp256k1_sha256_write(&hash->inner, data, size); } -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32) { +static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32) { unsigned char temp[32]; secp256k1_sha256_finalize(&hash->inner, temp); secp256k1_sha256_write(&hash->outer, temp, 32); - memset(temp, 0, 32); + secp256k1_memclear(temp, sizeof(temp)); secp256k1_sha256_finalize(&hash->outer, out32); } +static void secp256k1_hmac_sha256_clear(secp256k1_hmac_sha256 *hash) { + secp256k1_memclear(hash, sizeof(*hash)); +} -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen) { - secp256k1_hmac_sha256_t hmac; +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) { + secp256k1_hmac_sha256 hmac; static const unsigned char zero[1] = {0x00}; static const unsigned char one[1] = {0x01}; @@ -232,11 +249,11 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 rng->retry = 0; } -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen) { +static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen) { /* RFC6979 3.2.h. */ static const unsigned char zero[1] = {0x00}; if (rng->retry) { - secp256k1_hmac_sha256_t hmac; + secp256k1_hmac_sha256 hmac; secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, zero, 1); @@ -247,7 +264,7 @@ static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 } while (outlen > 0) { - secp256k1_hmac_sha256_t hmac; + secp256k1_hmac_sha256 hmac; int now = outlen; secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); @@ -263,13 +280,14 @@ static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 rng->retry = 1; } -static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng) { - memset(rng->k, 0, 32); - memset(rng->v, 0, 32); - rng->retry = 0; +static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng) { + (void) rng; +} + +static void secp256k1_rfc6979_hmac_sha256_clear(secp256k1_rfc6979_hmac_sha256 *rng) { + secp256k1_memclear(rng, sizeof(*rng)); } -#undef BE32 #undef Round #undef sigma1 #undef sigma0 @@ -278,4 +296,4 @@ static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 #undef Maj #undef Ch -#endif +#endif /* SECP256K1_HASH_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/hsort.h b/crypto/secp256k1/libsecp256k1/src/hsort.h new file mode 100644 index 0000000000..d54995caad --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/hsort.h @@ -0,0 +1,33 @@ +/*********************************************************************** + * Copyright (c) 2021 Russell O'Connor, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_HSORT_H +#define SECP256K1_HSORT_H + +#include +#include + +/* In-place, iterative heapsort with an interface matching glibc's qsort_r. This + * is preferred over standard library implementations because they generally + * make no guarantee about being fast for malicious inputs. + * Remember that heapsort is unstable. + * + * In/Out: ptr: pointer to the array to sort. The contents of the array are + * sorted in ascending order according to the comparison function. + * In: count: number of elements in the array. + * size: size in bytes of each element. + * cmp: pointer to a comparison function that is called with two + * arguments that point to the objects being compared. The cmp_data + * argument of secp256k1_hsort is passed as third argument. The + * function must return an integer less than, equal to, or greater + * than zero if the first argument is considered to be respectively + * less than, equal to, or greater than the second. + * cmp_data: pointer passed as third argument to cmp. + */ +static void secp256k1_hsort(void *ptr, size_t count, size_t size, + int (*cmp)(const void *, const void *, void *), + void *cmp_data); +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/hsort_impl.h b/crypto/secp256k1/libsecp256k1/src/hsort_impl.h new file mode 100644 index 0000000000..1c674ff1c4 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/hsort_impl.h @@ -0,0 +1,125 @@ +/*********************************************************************** + * Copyright (c) 2021 Russell O'Connor, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_HSORT_IMPL_H +#define SECP256K1_HSORT_IMPL_H + +#include "hsort.h" + +/* An array is a heap when, for all non-zero indexes i, the element at index i + * compares as less than or equal to the element at index parent(i) = (i-1)/2. + */ + +static SECP256K1_INLINE size_t secp256k1_heap_child1(size_t i) { + VERIFY_CHECK(i <= (SIZE_MAX - 1)/2); + return 2*i + 1; +} + +static SECP256K1_INLINE size_t secp256k1_heap_child2(size_t i) { + VERIFY_CHECK(i <= SIZE_MAX/2 - 1); + return secp256k1_heap_child1(i)+1; +} + +static SECP256K1_INLINE void secp256k1_heap_swap64(unsigned char *a, unsigned char *b, size_t len) { + unsigned char tmp[64]; + VERIFY_CHECK(len <= 64); + memcpy(tmp, a, len); + memmove(a, b, len); + memcpy(b, tmp, len); +} + +static SECP256K1_INLINE void secp256k1_heap_swap(unsigned char *arr, size_t i, size_t j, size_t stride) { + unsigned char *a = arr + i*stride; + unsigned char *b = arr + j*stride; + size_t len = stride; + while (64 < len) { + secp256k1_heap_swap64(a + (len - 64), b + (len - 64), 64); + len -= 64; + } + secp256k1_heap_swap64(a, b, len); +} + +/* This function accepts an array arr containing heap_size elements, each of + * size stride. The elements in the array at indices >i satisfy the max-heap + * property, i.e., for any element at index j (where j > i), all of its children + * are smaller than the element itself. The purpose of the function is to update + * the array so that all elements at indices >=i satisfy the max-heap + * property. */ +static SECP256K1_INLINE void secp256k1_heap_down(unsigned char *arr, size_t i, size_t heap_size, size_t stride, + int (*cmp)(const void *, const void *, void *), void *cmp_data) { + while (i < heap_size/2) { + VERIFY_CHECK(i <= SIZE_MAX/2 - 1); + /* Proof: + * i < heap_size/2 + * i + 1 <= heap_size/2 + * 2*i + 2 <= heap_size <= SIZE_MAX + * 2*i <= SIZE_MAX - 2 + */ + + VERIFY_CHECK(secp256k1_heap_child1(i) < heap_size); + /* Proof: + * i < heap_size/2 + * i + 1 <= heap_size/2 + * 2*i + 2 <= heap_size + * 2*i + 1 < heap_size + * child1(i) < heap_size + */ + + /* Let [x] be notation for the contents at arr[x*stride]. + * + * If [child1(i)] > [i] and [child2(i)] > [i], + * swap [i] with the larger child to ensure the new parent is larger + * than both children. When [child1(i)] == [child2(i)], swap [i] with + * [child2(i)]. + * Else if [child1(i)] > [i], swap [i] with [child1(i)]. + * Else if [child2(i)] > [i], swap [i] with [child2(i)]. + */ + if (secp256k1_heap_child2(i) < heap_size + && 0 <= cmp(arr + secp256k1_heap_child2(i)*stride, arr + secp256k1_heap_child1(i)*stride, cmp_data)) { + if (0 < cmp(arr + secp256k1_heap_child2(i)*stride, arr + i*stride, cmp_data)) { + secp256k1_heap_swap(arr, i, secp256k1_heap_child2(i), stride); + i = secp256k1_heap_child2(i); + } else { + /* At this point we have [child2(i)] >= [child1(i)] and we have + * [child2(i)] <= [i], and thus [child1(i)] <= [i] which means + * that the next comparison can be skipped. */ + return; + } + } else if (0 < cmp(arr + secp256k1_heap_child1(i)*stride, arr + i*stride, cmp_data)) { + secp256k1_heap_swap(arr, i, secp256k1_heap_child1(i), stride); + i = secp256k1_heap_child1(i); + } else { + return; + } + } + /* heap_size/2 <= i + * heap_size/2 < i + 1 + * heap_size < 2*i + 2 + * heap_size <= 2*i + 1 + * heap_size <= child1(i) + * Thus child1(i) and child2(i) are now out of bounds and we are at a leaf. + */ +} + +/* In-place heap sort. */ +static void secp256k1_hsort(void *ptr, size_t count, size_t size, + int (*cmp)(const void *, const void *, void *), + void *cmp_data) { + size_t i; + + for (i = count/2; 0 < i; --i) { + secp256k1_heap_down(ptr, i-1, count, size, cmp, cmp_data); + } + for (i = count; 1 < i; --i) { + /* Extract the largest value from the heap */ + secp256k1_heap_swap(ptr, 0, i-1, size); + + /* Repair the heap condition */ + secp256k1_heap_down(ptr, 0, i-1, size, cmp, cmp_data); + } +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/int128.h b/crypto/secp256k1/libsecp256k1/src/int128.h new file mode 100644 index 0000000000..5355fbfae0 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/int128.h @@ -0,0 +1,90 @@ +#ifndef SECP256K1_INT128_H +#define SECP256K1_INT128_H + +#include "util.h" + +#if defined(SECP256K1_WIDEMUL_INT128) +# if defined(SECP256K1_INT128_NATIVE) +# include "int128_native.h" +# elif defined(SECP256K1_INT128_STRUCT) +# include "int128_struct.h" +# else +# error "Please select int128 implementation" +# endif + +/* Construct an unsigned 128-bit value from a high and a low 64-bit value. */ +static SECP256K1_INLINE void secp256k1_u128_load(secp256k1_uint128 *r, uint64_t hi, uint64_t lo); + +/* Multiply two unsigned 64-bit values a and b and write the result to r. */ +static SECP256K1_INLINE void secp256k1_u128_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b); + +/* Multiply two unsigned 64-bit values a and b and add the result to r. + * The final result is taken modulo 2^128. + */ +static SECP256K1_INLINE void secp256k1_u128_accum_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b); + +/* Add an unsigned 64-bit value a to r. + * The final result is taken modulo 2^128. + */ +static SECP256K1_INLINE void secp256k1_u128_accum_u64(secp256k1_uint128 *r, uint64_t a); + +/* Unsigned (logical) right shift. + * Non-constant time in n. + */ +static SECP256K1_INLINE void secp256k1_u128_rshift(secp256k1_uint128 *r, unsigned int n); + +/* Return the low 64-bits of a 128-bit value as an unsigned 64-bit value. */ +static SECP256K1_INLINE uint64_t secp256k1_u128_to_u64(const secp256k1_uint128 *a); + +/* Return the high 64-bits of a 128-bit value as an unsigned 64-bit value. */ +static SECP256K1_INLINE uint64_t secp256k1_u128_hi_u64(const secp256k1_uint128 *a); + +/* Write an unsigned 64-bit value to r. */ +static SECP256K1_INLINE void secp256k1_u128_from_u64(secp256k1_uint128 *r, uint64_t a); + +/* Tests if r is strictly less than to 2^n. + * n must be strictly less than 128. + */ +static SECP256K1_INLINE int secp256k1_u128_check_bits(const secp256k1_uint128 *r, unsigned int n); + +/* Construct an signed 128-bit value from a high and a low 64-bit value. */ +static SECP256K1_INLINE void secp256k1_i128_load(secp256k1_int128 *r, int64_t hi, uint64_t lo); + +/* Multiply two signed 64-bit values a and b and write the result to r. */ +static SECP256K1_INLINE void secp256k1_i128_mul(secp256k1_int128 *r, int64_t a, int64_t b); + +/* Multiply two signed 64-bit values a and b and add the result to r. + * Overflow or underflow from the addition is undefined behaviour. + */ +static SECP256K1_INLINE void secp256k1_i128_accum_mul(secp256k1_int128 *r, int64_t a, int64_t b); + +/* Compute a*d - b*c from signed 64-bit values and write the result to r. */ +static SECP256K1_INLINE void secp256k1_i128_det(secp256k1_int128 *r, int64_t a, int64_t b, int64_t c, int64_t d); + +/* Signed (arithmetic) right shift. + * Non-constant time in b. + */ +static SECP256K1_INLINE void secp256k1_i128_rshift(secp256k1_int128 *r, unsigned int b); + +/* Return the input value modulo 2^64. */ +static SECP256K1_INLINE uint64_t secp256k1_i128_to_u64(const secp256k1_int128 *a); + +/* Return the value as a signed 64-bit value. + * Requires the input to be between INT64_MIN and INT64_MAX. + */ +static SECP256K1_INLINE int64_t secp256k1_i128_to_i64(const secp256k1_int128 *a); + +/* Write a signed 64-bit value to r. */ +static SECP256K1_INLINE void secp256k1_i128_from_i64(secp256k1_int128 *r, int64_t a); + +/* Compare two 128-bit values for equality. */ +static SECP256K1_INLINE int secp256k1_i128_eq_var(const secp256k1_int128 *a, const secp256k1_int128 *b); + +/* Tests if r is equal to sign*2^n (sign must be 1 or -1). + * n must be strictly less than 127. + */ +static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n, int sign); + +#endif + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/int128_impl.h b/crypto/secp256k1/libsecp256k1/src/int128_impl.h new file mode 100644 index 0000000000..cfc573408a --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/int128_impl.h @@ -0,0 +1,18 @@ +#ifndef SECP256K1_INT128_IMPL_H +#define SECP256K1_INT128_IMPL_H + +#include "util.h" + +#include "int128.h" + +#if defined(SECP256K1_WIDEMUL_INT128) +# if defined(SECP256K1_INT128_NATIVE) +# include "int128_native_impl.h" +# elif defined(SECP256K1_INT128_STRUCT) +# include "int128_struct_impl.h" +# else +# error "Please select int128 implementation" +# endif +#endif + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/int128_native.h b/crypto/secp256k1/libsecp256k1/src/int128_native.h new file mode 100644 index 0000000000..7c97aafc74 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/int128_native.h @@ -0,0 +1,19 @@ +#ifndef SECP256K1_INT128_NATIVE_H +#define SECP256K1_INT128_NATIVE_H + +#include +#include "util.h" + +#if !defined(UINT128_MAX) && defined(__SIZEOF_INT128__) +SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; +SECP256K1_GNUC_EXT typedef __int128 int128_t; +# define UINT128_MAX ((uint128_t)(-1)) +# define INT128_MAX ((int128_t)(UINT128_MAX >> 1)) +# define INT128_MIN (-INT128_MAX - 1) +/* No (U)INT128_C macros because compilers providing __int128 do not support 128-bit literals. */ +#endif + +typedef uint128_t secp256k1_uint128; +typedef int128_t secp256k1_int128; + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/int128_native_impl.h b/crypto/secp256k1/libsecp256k1/src/int128_native_impl.h new file mode 100644 index 0000000000..7f02e1590b --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/int128_native_impl.h @@ -0,0 +1,94 @@ +#ifndef SECP256K1_INT128_NATIVE_IMPL_H +#define SECP256K1_INT128_NATIVE_IMPL_H + +#include "int128.h" +#include "util.h" + +static SECP256K1_INLINE void secp256k1_u128_load(secp256k1_uint128 *r, uint64_t hi, uint64_t lo) { + *r = (((uint128_t)hi) << 64) + lo; +} + +static SECP256K1_INLINE void secp256k1_u128_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b) { + *r = (uint128_t)a * b; +} + +static SECP256K1_INLINE void secp256k1_u128_accum_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b) { + *r += (uint128_t)a * b; +} + +static SECP256K1_INLINE void secp256k1_u128_accum_u64(secp256k1_uint128 *r, uint64_t a) { + *r += a; +} + +static SECP256K1_INLINE void secp256k1_u128_rshift(secp256k1_uint128 *r, unsigned int n) { + VERIFY_CHECK(n < 128); + *r >>= n; +} + +static SECP256K1_INLINE uint64_t secp256k1_u128_to_u64(const secp256k1_uint128 *a) { + return (uint64_t)(*a); +} + +static SECP256K1_INLINE uint64_t secp256k1_u128_hi_u64(const secp256k1_uint128 *a) { + return (uint64_t)(*a >> 64); +} + +static SECP256K1_INLINE void secp256k1_u128_from_u64(secp256k1_uint128 *r, uint64_t a) { + *r = a; +} + +static SECP256K1_INLINE int secp256k1_u128_check_bits(const secp256k1_uint128 *r, unsigned int n) { + VERIFY_CHECK(n < 128); + return (*r >> n == 0); +} + +static SECP256K1_INLINE void secp256k1_i128_load(secp256k1_int128 *r, int64_t hi, uint64_t lo) { + *r = (((uint128_t)(uint64_t)hi) << 64) + lo; +} + +static SECP256K1_INLINE void secp256k1_i128_mul(secp256k1_int128 *r, int64_t a, int64_t b) { + *r = (int128_t)a * b; +} + +static SECP256K1_INLINE void secp256k1_i128_accum_mul(secp256k1_int128 *r, int64_t a, int64_t b) { + int128_t ab = (int128_t)a * b; + VERIFY_CHECK(0 <= ab ? *r <= INT128_MAX - ab : INT128_MIN - ab <= *r); + *r += ab; +} + +static SECP256K1_INLINE void secp256k1_i128_det(secp256k1_int128 *r, int64_t a, int64_t b, int64_t c, int64_t d) { + int128_t ad = (int128_t)a * d; + int128_t bc = (int128_t)b * c; + VERIFY_CHECK(0 <= bc ? INT128_MIN + bc <= ad : ad <= INT128_MAX + bc); + *r = ad - bc; +} + +static SECP256K1_INLINE void secp256k1_i128_rshift(secp256k1_int128 *r, unsigned int n) { + VERIFY_CHECK(n < 128); + *r >>= n; +} + +static SECP256K1_INLINE uint64_t secp256k1_i128_to_u64(const secp256k1_int128 *a) { + return (uint64_t)*a; +} + +static SECP256K1_INLINE int64_t secp256k1_i128_to_i64(const secp256k1_int128 *a) { + VERIFY_CHECK(INT64_MIN <= *a && *a <= INT64_MAX); + return *a; +} + +static SECP256K1_INLINE void secp256k1_i128_from_i64(secp256k1_int128 *r, int64_t a) { + *r = a; +} + +static SECP256K1_INLINE int secp256k1_i128_eq_var(const secp256k1_int128 *a, const secp256k1_int128 *b) { + return *a == *b; +} + +static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n, int sign) { + VERIFY_CHECK(n < 127); + VERIFY_CHECK(sign == 1 || sign == -1); + return (*r == (int128_t)((uint128_t)sign << n)); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/int128_struct.h b/crypto/secp256k1/libsecp256k1/src/int128_struct.h new file mode 100644 index 0000000000..6156f82cc2 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/int128_struct.h @@ -0,0 +1,14 @@ +#ifndef SECP256K1_INT128_STRUCT_H +#define SECP256K1_INT128_STRUCT_H + +#include +#include "util.h" + +typedef struct { + uint64_t lo; + uint64_t hi; +} secp256k1_uint128; + +typedef secp256k1_uint128 secp256k1_int128; + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/int128_struct_impl.h b/crypto/secp256k1/libsecp256k1/src/int128_struct_impl.h new file mode 100644 index 0000000000..962a71d13b --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/int128_struct_impl.h @@ -0,0 +1,205 @@ +#ifndef SECP256K1_INT128_STRUCT_IMPL_H +#define SECP256K1_INT128_STRUCT_IMPL_H + +#include "int128.h" +#include "util.h" + +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) /* MSVC */ +# include +# if defined(_M_ARM64) || defined(SECP256K1_MSVC_MULH_TEST_OVERRIDE) +/* On ARM64 MSVC, use __(u)mulh for the upper half of 64x64 multiplications. + (Define SECP256K1_MSVC_MULH_TEST_OVERRIDE to test this code path on X64, + which supports both __(u)mulh and _umul128.) */ +# if defined(SECP256K1_MSVC_MULH_TEST_OVERRIDE) +# pragma message(__FILE__ ": SECP256K1_MSVC_MULH_TEST_OVERRIDE is defined, forcing use of __(u)mulh.") +# endif +static SECP256K1_INLINE uint64_t secp256k1_umul128(uint64_t a, uint64_t b, uint64_t* hi) { + *hi = __umulh(a, b); + return a * b; +} + +static SECP256K1_INLINE int64_t secp256k1_mul128(int64_t a, int64_t b, int64_t* hi) { + *hi = __mulh(a, b); + return (uint64_t)a * (uint64_t)b; +} +# else +/* On x84_64 MSVC, use native _(u)mul128 for 64x64->128 multiplications. */ +# define secp256k1_umul128 _umul128 +# define secp256k1_mul128 _mul128 +# endif +#else +/* On other systems, emulate 64x64->128 multiplications using 32x32->64 multiplications. */ +static SECP256K1_INLINE uint64_t secp256k1_umul128(uint64_t a, uint64_t b, uint64_t* hi) { + uint64_t ll = (uint64_t)(uint32_t)a * (uint32_t)b; + uint64_t lh = (uint32_t)a * (b >> 32); + uint64_t hl = (a >> 32) * (uint32_t)b; + uint64_t hh = (a >> 32) * (b >> 32); + uint64_t mid34 = (ll >> 32) + (uint32_t)lh + (uint32_t)hl; + *hi = hh + (lh >> 32) + (hl >> 32) + (mid34 >> 32); + return (mid34 << 32) + (uint32_t)ll; +} + +static SECP256K1_INLINE int64_t secp256k1_mul128(int64_t a, int64_t b, int64_t* hi) { + uint64_t ll = (uint64_t)(uint32_t)a * (uint32_t)b; + int64_t lh = (uint32_t)a * (b >> 32); + int64_t hl = (a >> 32) * (uint32_t)b; + int64_t hh = (a >> 32) * (b >> 32); + uint64_t mid34 = (ll >> 32) + (uint32_t)lh + (uint32_t)hl; + *hi = hh + (lh >> 32) + (hl >> 32) + (mid34 >> 32); + return (mid34 << 32) + (uint32_t)ll; +} +#endif + +static SECP256K1_INLINE void secp256k1_u128_load(secp256k1_uint128 *r, uint64_t hi, uint64_t lo) { + r->hi = hi; + r->lo = lo; +} + +static SECP256K1_INLINE void secp256k1_u128_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b) { + r->lo = secp256k1_umul128(a, b, &r->hi); +} + +static SECP256K1_INLINE void secp256k1_u128_accum_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b) { + uint64_t lo, hi; + lo = secp256k1_umul128(a, b, &hi); + r->lo += lo; + r->hi += hi + (r->lo < lo); +} + +static SECP256K1_INLINE void secp256k1_u128_accum_u64(secp256k1_uint128 *r, uint64_t a) { + r->lo += a; + r->hi += r->lo < a; +} + +/* Unsigned (logical) right shift. + * Non-constant time in n. + */ +static SECP256K1_INLINE void secp256k1_u128_rshift(secp256k1_uint128 *r, unsigned int n) { + VERIFY_CHECK(n < 128); + if (n >= 64) { + r->lo = r->hi >> (n-64); + r->hi = 0; + } else if (n > 0) { +#if defined(_MSC_VER) && defined(_M_X64) + VERIFY_CHECK(n < 64); + r->lo = __shiftright128(r->lo, r->hi, n); +#else + r->lo = ((1U * r->hi) << (64-n)) | r->lo >> n; +#endif + r->hi >>= n; + } +} + +static SECP256K1_INLINE uint64_t secp256k1_u128_to_u64(const secp256k1_uint128 *a) { + return a->lo; +} + +static SECP256K1_INLINE uint64_t secp256k1_u128_hi_u64(const secp256k1_uint128 *a) { + return a->hi; +} + +static SECP256K1_INLINE void secp256k1_u128_from_u64(secp256k1_uint128 *r, uint64_t a) { + r->hi = 0; + r->lo = a; +} + +static SECP256K1_INLINE int secp256k1_u128_check_bits(const secp256k1_uint128 *r, unsigned int n) { + VERIFY_CHECK(n < 128); + return n >= 64 ? r->hi >> (n - 64) == 0 + : r->hi == 0 && r->lo >> n == 0; +} + +static SECP256K1_INLINE void secp256k1_i128_load(secp256k1_int128 *r, int64_t hi, uint64_t lo) { + r->hi = hi; + r->lo = lo; +} + +static SECP256K1_INLINE void secp256k1_i128_mul(secp256k1_int128 *r, int64_t a, int64_t b) { + int64_t hi; + r->lo = (uint64_t)secp256k1_mul128(a, b, &hi); + r->hi = (uint64_t)hi; +} + +static SECP256K1_INLINE void secp256k1_i128_accum_mul(secp256k1_int128 *r, int64_t a, int64_t b) { + int64_t hi; + uint64_t lo = (uint64_t)secp256k1_mul128(a, b, &hi); + r->lo += lo; + hi += r->lo < lo; + /* Verify no overflow. + * If r represents a positive value (the sign bit is not set) and the value we are adding is a positive value (the sign bit is not set), + * then we require that the resulting value also be positive (the sign bit is not set). + * Note that (X <= Y) means (X implies Y) when X and Y are boolean values (i.e. 0 or 1). + */ + VERIFY_CHECK((r->hi <= 0x7fffffffffffffffu && (uint64_t)hi <= 0x7fffffffffffffffu) <= (r->hi + (uint64_t)hi <= 0x7fffffffffffffffu)); + /* Verify no underflow. + * If r represents a negative value (the sign bit is set) and the value we are adding is a negative value (the sign bit is set), + * then we require that the resulting value also be negative (the sign bit is set). + */ + VERIFY_CHECK((r->hi > 0x7fffffffffffffffu && (uint64_t)hi > 0x7fffffffffffffffu) <= (r->hi + (uint64_t)hi > 0x7fffffffffffffffu)); + r->hi += hi; +} + +static SECP256K1_INLINE void secp256k1_i128_dissip_mul(secp256k1_int128 *r, int64_t a, int64_t b) { + int64_t hi; + uint64_t lo = (uint64_t)secp256k1_mul128(a, b, &hi); + hi += r->lo < lo; + /* Verify no overflow. + * If r represents a positive value (the sign bit is not set) and the value we are subtracting is a negative value (the sign bit is set), + * then we require that the resulting value also be positive (the sign bit is not set). + */ + VERIFY_CHECK((r->hi <= 0x7fffffffffffffffu && (uint64_t)hi > 0x7fffffffffffffffu) <= (r->hi - (uint64_t)hi <= 0x7fffffffffffffffu)); + /* Verify no underflow. + * If r represents a negative value (the sign bit is set) and the value we are subtracting is a positive value (the sign sign bit is not set), + * then we require that the resulting value also be negative (the sign bit is set). + */ + VERIFY_CHECK((r->hi > 0x7fffffffffffffffu && (uint64_t)hi <= 0x7fffffffffffffffu) <= (r->hi - (uint64_t)hi > 0x7fffffffffffffffu)); + r->hi -= hi; + r->lo -= lo; +} + +static SECP256K1_INLINE void secp256k1_i128_det(secp256k1_int128 *r, int64_t a, int64_t b, int64_t c, int64_t d) { + secp256k1_i128_mul(r, a, d); + secp256k1_i128_dissip_mul(r, b, c); +} + +/* Signed (arithmetic) right shift. + * Non-constant time in n. + */ +static SECP256K1_INLINE void secp256k1_i128_rshift(secp256k1_int128 *r, unsigned int n) { + VERIFY_CHECK(n < 128); + if (n >= 64) { + r->lo = (uint64_t)((int64_t)(r->hi) >> (n-64)); + r->hi = (uint64_t)((int64_t)(r->hi) >> 63); + } else if (n > 0) { + r->lo = ((1U * r->hi) << (64-n)) | r->lo >> n; + r->hi = (uint64_t)((int64_t)(r->hi) >> n); + } +} + +static SECP256K1_INLINE uint64_t secp256k1_i128_to_u64(const secp256k1_int128 *a) { + return a->lo; +} + +static SECP256K1_INLINE int64_t secp256k1_i128_to_i64(const secp256k1_int128 *a) { + /* Verify that a represents a 64 bit signed value by checking that the high bits are a sign extension of the low bits. */ + VERIFY_CHECK(a->hi == -(a->lo >> 63)); + return (int64_t)secp256k1_i128_to_u64(a); +} + +static SECP256K1_INLINE void secp256k1_i128_from_i64(secp256k1_int128 *r, int64_t a) { + r->hi = (uint64_t)(a >> 63); + r->lo = (uint64_t)a; +} + +static SECP256K1_INLINE int secp256k1_i128_eq_var(const secp256k1_int128 *a, const secp256k1_int128 *b) { + return a->hi == b->hi && a->lo == b->lo; +} + +static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n, int sign) { + VERIFY_CHECK(n < 127); + VERIFY_CHECK(sign == 1 || sign == -1); + return n >= 64 ? r->hi == (uint64_t)sign << (n - 64) && r->lo == 0 + : r->hi == (uint64_t)(sign >> 1) && r->lo == (uint64_t)sign << n; +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1.java b/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1.java deleted file mode 100644 index 1c67802fba..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * Copyright 2014-2016 the libsecp256k1 contributors - * - * 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. - */ - -package org.bitcoin; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import java.math.BigInteger; -import com.google.common.base.Preconditions; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import static org.bitcoin.NativeSecp256k1Util.*; - -/** - *

This class holds native methods to handle ECDSA verification.

- * - *

You can find an example library that can be used for this at https://github.com/bitcoin/secp256k1

- * - *

To build secp256k1 for use with bitcoinj, run - * `./configure --enable-jni --enable-experimental --enable-module-ecdh` - * and `make` then copy `.libs/libsecp256k1.so` to your system library path - * or point the JVM to the folder containing it with -Djava.library.path - *

- */ -public class NativeSecp256k1 { - - private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); - private static final Lock r = rwl.readLock(); - private static final Lock w = rwl.writeLock(); - private static ThreadLocal nativeECDSABuffer = new ThreadLocal(); - /** - * Verifies the given secp256k1 signature in native code. - * Calling when enabled == false is undefined (probably library not loaded) - * - * @param data The data which was signed, must be exactly 32 bytes - * @param signature The signature - * @param pub The public key which did the signing - */ - public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws AssertFailException{ - Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < 520) { - byteBuff = ByteBuffer.allocateDirect(520); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(data); - byteBuff.put(signature); - byteBuff.put(pub); - - byte[][] retByteArray; - - r.lock(); - try { - return secp256k1_ecdsa_verify(byteBuff, Secp256k1Context.getContext(), signature.length, pub.length) == 1; - } finally { - r.unlock(); - } - } - - /** - * libsecp256k1 Create an ECDSA signature. - * - * @param data Message hash, 32 bytes - * @param key Secret key, 32 bytes - * - * Return values - * @param sig byte array of signature - */ - public static byte[] sign(byte[] data, byte[] sec) throws AssertFailException{ - Preconditions.checkArgument(data.length == 32 && sec.length <= 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < 32 + 32) { - byteBuff = ByteBuffer.allocateDirect(32 + 32); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(data); - byteBuff.put(sec); - - byte[][] retByteArray; - - r.lock(); - try { - retByteArray = secp256k1_ecdsa_sign(byteBuff, Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] sigArr = retByteArray[0]; - int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(sigArr.length, sigLen, "Got bad signature length."); - - return retVal == 0 ? new byte[0] : sigArr; - } - - /** - * libsecp256k1 Seckey Verify - returns 1 if valid, 0 if invalid - * - * @param seckey ECDSA Secret key, 32 bytes - */ - public static boolean secKeyVerify(byte[] seckey) { - Preconditions.checkArgument(seckey.length == 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < seckey.length) { - byteBuff = ByteBuffer.allocateDirect(seckey.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(seckey); - - r.lock(); - try { - return secp256k1_ec_seckey_verify(byteBuff,Secp256k1Context.getContext()) == 1; - } finally { - r.unlock(); - } - } - - - /** - * libsecp256k1 Compute Pubkey - computes public key from secret key - * - * @param seckey ECDSA Secret key, 32 bytes - * - * Return values - * @param pubkey ECDSA Public key, 33 or 65 bytes - */ - //TODO add a 'compressed' arg - public static byte[] computePubkey(byte[] seckey) throws AssertFailException{ - Preconditions.checkArgument(seckey.length == 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < seckey.length) { - byteBuff = ByteBuffer.allocateDirect(seckey.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(seckey); - - byte[][] retByteArray; - - r.lock(); - try { - retByteArray = secp256k1_ec_pubkey_create(byteBuff, Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] pubArr = retByteArray[0]; - int pubLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); - - return retVal == 0 ? new byte[0]: pubArr; - } - - /** - * libsecp256k1 Cleanup - This destroys the secp256k1 context object - * This should be called at the end of the program for proper cleanup of the context. - */ - public static synchronized void cleanup() { - w.lock(); - try { - secp256k1_destroy_context(Secp256k1Context.getContext()); - } finally { - w.unlock(); - } - } - - public static long cloneContext() { - r.lock(); - try { - return secp256k1_ctx_clone(Secp256k1Context.getContext()); - } finally { r.unlock(); } - } - - /** - * libsecp256k1 PrivKey Tweak-Mul - Tweak privkey by multiplying to it - * - * @param tweak some bytes to tweak with - * @param seckey 32-byte seckey - */ - public static byte[] privKeyTweakMul(byte[] privkey, byte[] tweak) throws AssertFailException{ - Preconditions.checkArgument(privkey.length == 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { - byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(privkey); - byteBuff.put(tweak); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_privkey_tweak_mul(byteBuff,Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] privArr = retByteArray[0]; - - int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(privArr.length, privLen, "Got bad pubkey length."); - - assertEquals(retVal, 1, "Failed return value check."); - - return privArr; - } - - /** - * libsecp256k1 PrivKey Tweak-Add - Tweak privkey by adding to it - * - * @param tweak some bytes to tweak with - * @param seckey 32-byte seckey - */ - public static byte[] privKeyTweakAdd(byte[] privkey, byte[] tweak) throws AssertFailException{ - Preconditions.checkArgument(privkey.length == 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { - byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(privkey); - byteBuff.put(tweak); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_privkey_tweak_add(byteBuff,Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] privArr = retByteArray[0]; - - int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(privArr.length, privLen, "Got bad pubkey length."); - - assertEquals(retVal, 1, "Failed return value check."); - - return privArr; - } - - /** - * libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it - * - * @param tweak some bytes to tweak with - * @param pubkey 32-byte seckey - */ - public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak) throws AssertFailException{ - Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { - byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(pubkey); - byteBuff.put(tweak); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_pubkey_tweak_add(byteBuff,Secp256k1Context.getContext(), pubkey.length); - } finally { - r.unlock(); - } - - byte[] pubArr = retByteArray[0]; - - int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); - - assertEquals(retVal, 1, "Failed return value check."); - - return pubArr; - } - - /** - * libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it - * - * @param tweak some bytes to tweak with - * @param pubkey 32-byte seckey - */ - public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak) throws AssertFailException{ - Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { - byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(pubkey); - byteBuff.put(tweak); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_pubkey_tweak_mul(byteBuff,Secp256k1Context.getContext(), pubkey.length); - } finally { - r.unlock(); - } - - byte[] pubArr = retByteArray[0]; - - int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); - - assertEquals(retVal, 1, "Failed return value check."); - - return pubArr; - } - - /** - * libsecp256k1 create ECDH secret - constant time ECDH calculation - * - * @param seckey byte array of secret key used in exponentiaion - * @param pubkey byte array of public key used in exponentiaion - */ - public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException{ - Preconditions.checkArgument(seckey.length <= 32 && pubkey.length <= 65); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) { - byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(seckey); - byteBuff.put(pubkey); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_ecdh(byteBuff, Secp256k1Context.getContext(), pubkey.length); - } finally { - r.unlock(); - } - - byte[] resArr = retByteArray[0]; - int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); - - assertEquals(resArr.length, 32, "Got bad result length."); - assertEquals(retVal, 1, "Failed return value check."); - - return resArr; - } - - /** - * libsecp256k1 randomize - updates the context randomization - * - * @param seed 32-byte random seed - */ - public static synchronized boolean randomize(byte[] seed) throws AssertFailException{ - Preconditions.checkArgument(seed.length == 32 || seed == null); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < seed.length) { - byteBuff = ByteBuffer.allocateDirect(seed.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(seed); - - w.lock(); - try { - return secp256k1_context_randomize(byteBuff, Secp256k1Context.getContext()) == 1; - } finally { - w.unlock(); - } - } - - private static native long secp256k1_ctx_clone(long context); - - private static native int secp256k1_context_randomize(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_privkey_tweak_add(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_privkey_tweak_mul(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_pubkey_tweak_add(ByteBuffer byteBuff, long context, int pubLen); - - private static native byte[][] secp256k1_pubkey_tweak_mul(ByteBuffer byteBuff, long context, int pubLen); - - private static native void secp256k1_destroy_context(long context); - - private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff, long context, int sigLen, int pubLen); - - private static native byte[][] secp256k1_ecdsa_sign(ByteBuffer byteBuff, long context); - - private static native int secp256k1_ec_seckey_verify(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_ec_pubkey_create(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_ec_pubkey_parse(ByteBuffer byteBuff, long context, int inputLen); - - private static native byte[][] secp256k1_ecdh(ByteBuffer byteBuff, long context, int inputLen); - -} diff --git a/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java b/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java deleted file mode 100644 index c00d08899b..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java +++ /dev/null @@ -1,226 +0,0 @@ -package org.bitcoin; - -import com.google.common.io.BaseEncoding; -import java.util.Arrays; -import java.math.BigInteger; -import javax.xml.bind.DatatypeConverter; -import static org.bitcoin.NativeSecp256k1Util.*; - -/** - * This class holds test cases defined for testing this library. - */ -public class NativeSecp256k1Test { - - //TODO improve comments/add more tests - /** - * This tests verify() for a valid signature - */ - public static void testVerifyPos() throws AssertFailException{ - boolean result = false; - byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" - byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - - result = NativeSecp256k1.verify( data, sig, pub); - assertEquals( result, true , "testVerifyPos"); - } - - /** - * This tests verify() for a non-valid signature - */ - public static void testVerifyNeg() throws AssertFailException{ - boolean result = false; - byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A91".toLowerCase()); //sha256hash of "testing" - byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - - result = NativeSecp256k1.verify( data, sig, pub); - //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); - assertEquals( result, false , "testVerifyNeg"); - } - - /** - * This tests secret key verify() for a valid secretkey - */ - public static void testSecKeyVerifyPos() throws AssertFailException{ - boolean result = false; - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - - result = NativeSecp256k1.secKeyVerify( sec ); - //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); - assertEquals( result, true , "testSecKeyVerifyPos"); - } - - /** - * This tests secret key verify() for a invalid secretkey - */ - public static void testSecKeyVerifyNeg() throws AssertFailException{ - boolean result = false; - byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); - - result = NativeSecp256k1.secKeyVerify( sec ); - //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); - assertEquals( result, false , "testSecKeyVerifyNeg"); - } - - /** - * This tests public key create() for a valid secretkey - */ - public static void testPubKeyCreatePos() throws AssertFailException{ - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.computePubkey( sec); - String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( pubkeyString , "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6" , "testPubKeyCreatePos"); - } - - /** - * This tests public key create() for a invalid secretkey - */ - public static void testPubKeyCreateNeg() throws AssertFailException{ - byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.computePubkey( sec); - String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( pubkeyString, "" , "testPubKeyCreateNeg"); - } - - /** - * This tests sign() for a valid secretkey - */ - public static void testSignPos() throws AssertFailException{ - - byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.sign(data, sec); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString, "30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9" , "testSignPos"); - } - - /** - * This tests sign() for a invalid secretkey - */ - public static void testSignNeg() throws AssertFailException{ - byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" - byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.sign(data, sec); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString, "" , "testSignNeg"); - } - - /** - * This tests private key tweak-add - */ - public static void testPrivKeyTweakAdd_1() throws AssertFailException { - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" - - byte[] resultArr = NativeSecp256k1.privKeyTweakAdd( sec , data ); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString , "A168571E189E6F9A7E2D657A4B53AE99B909F7E712D1C23CED28093CD57C88F3" , "testPrivKeyAdd_1"); - } - - /** - * This tests private key tweak-mul - */ - public static void testPrivKeyTweakMul_1() throws AssertFailException { - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" - - byte[] resultArr = NativeSecp256k1.privKeyTweakMul( sec , data ); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString , "97F8184235F101550F3C71C927507651BD3F1CDB4A5A33B8986ACF0DEE20FFFC" , "testPrivKeyMul_1"); - } - - /** - * This tests private key tweak-add uncompressed - */ - public static void testPrivKeyTweakAdd_2() throws AssertFailException { - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" - - byte[] resultArr = NativeSecp256k1.pubKeyTweakAdd( pub , data ); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString , "0411C6790F4B663CCE607BAAE08C43557EDC1A4D11D88DFCB3D841D0C6A941AF525A268E2A863C148555C48FB5FBA368E88718A46E205FABC3DBA2CCFFAB0796EF" , "testPrivKeyAdd_2"); - } - - /** - * This tests private key tweak-mul uncompressed - */ - public static void testPrivKeyTweakMul_2() throws AssertFailException { - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" - - byte[] resultArr = NativeSecp256k1.pubKeyTweakMul( pub , data ); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString , "04E0FE6FE55EBCA626B98A807F6CAF654139E14E5E3698F01A9A658E21DC1D2791EC060D4F412A794D5370F672BC94B722640B5F76914151CFCA6E712CA48CC589" , "testPrivKeyMul_2"); - } - - /** - * This tests seed randomization - */ - public static void testRandomize() throws AssertFailException { - byte[] seed = BaseEncoding.base16().lowerCase().decode("A441B15FE9A3CF56661190A0B93B9DEC7D04127288CC87250967CF3B52894D11".toLowerCase()); //sha256hash of "random" - boolean result = NativeSecp256k1.randomize(seed); - assertEquals( result, true, "testRandomize"); - } - - public static void testCreateECDHSecret() throws AssertFailException{ - - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.createECDHSecret(sec, pub); - String ecdhString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( ecdhString, "2A2A67007A926E6594AF3EB564FC74005B37A9C8AEF2033C4552051B5C87F043" , "testCreateECDHSecret"); - } - - public static void main(String[] args) throws AssertFailException{ - - - System.out.println("\n libsecp256k1 enabled: " + Secp256k1Context.isEnabled() + "\n"); - - assertEquals( Secp256k1Context.isEnabled(), true, "isEnabled" ); - - //Test verify() success/fail - testVerifyPos(); - testVerifyNeg(); - - //Test secKeyVerify() success/fail - testSecKeyVerifyPos(); - testSecKeyVerifyNeg(); - - //Test computePubkey() success/fail - testPubKeyCreatePos(); - testPubKeyCreateNeg(); - - //Test sign() success/fail - testSignPos(); - testSignNeg(); - - //Test privKeyTweakAdd() 1 - testPrivKeyTweakAdd_1(); - - //Test privKeyTweakMul() 2 - testPrivKeyTweakMul_1(); - - //Test privKeyTweakAdd() 3 - testPrivKeyTweakAdd_2(); - - //Test privKeyTweakMul() 4 - testPrivKeyTweakMul_2(); - - //Test randomize() - testRandomize(); - - //Test ECDH - testCreateECDHSecret(); - - NativeSecp256k1.cleanup(); - - System.out.println(" All tests passed." ); - - } -} diff --git a/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java b/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java deleted file mode 100644 index 04732ba044..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2014-2016 the libsecp256k1 contributors - * - * 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. - */ - -package org.bitcoin; - -public class NativeSecp256k1Util{ - - public static void assertEquals( int val, int val2, String message ) throws AssertFailException{ - if( val != val2 ) - throw new AssertFailException("FAIL: " + message); - } - - public static void assertEquals( boolean val, boolean val2, String message ) throws AssertFailException{ - if( val != val2 ) - throw new AssertFailException("FAIL: " + message); - else - System.out.println("PASS: " + message); - } - - public static void assertEquals( String val, String val2, String message ) throws AssertFailException{ - if( !val.equals(val2) ) - throw new AssertFailException("FAIL: " + message); - else - System.out.println("PASS: " + message); - } - - public static class AssertFailException extends Exception { - public AssertFailException(String message) { - super( message ); - } - } -} diff --git a/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/Secp256k1Context.java b/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/Secp256k1Context.java deleted file mode 100644 index 216c986a8b..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/java/org/bitcoin/Secp256k1Context.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2014-2016 the libsecp256k1 contributors - * - * 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. - */ - -package org.bitcoin; - -/** - * This class holds the context reference used in native methods - * to handle ECDSA operations. - */ -public class Secp256k1Context { - private static final boolean enabled; //true if the library is loaded - private static final long context; //ref to pointer to context obj - - static { //static initializer - boolean isEnabled = true; - long contextRef = -1; - try { - System.loadLibrary("secp256k1"); - contextRef = secp256k1_init_context(); - } catch (UnsatisfiedLinkError e) { - System.out.println("UnsatisfiedLinkError: " + e.toString()); - isEnabled = false; - } - enabled = isEnabled; - context = contextRef; - } - - public static boolean isEnabled() { - return enabled; - } - - public static long getContext() { - if(!enabled) return -1; //sanity check - return context; - } - - private static native long secp256k1_init_context(); -} diff --git a/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_NativeSecp256k1.c b/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_NativeSecp256k1.c deleted file mode 100644 index bcef7b32ce..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_NativeSecp256k1.c +++ /dev/null @@ -1,377 +0,0 @@ -#include -#include -#include -#include "org_bitcoin_NativeSecp256k1.h" -#include "include/secp256k1.h" -#include "include/secp256k1_ecdh.h" -#include "include/secp256k1_recovery.h" - - -SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone - (JNIEnv* env, jclass classObject, jlong ctx_l) -{ - const secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - - jlong ctx_clone_l = (uintptr_t) secp256k1_context_clone(ctx); - - (void)classObject;(void)env; - - return ctx_clone_l; - -} - -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - - const unsigned char* seed = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - - (void)classObject; - - return secp256k1_context_randomize(ctx, seed); - -} - -SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context - (JNIEnv* env, jclass classObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - - secp256k1_context_destroy(ctx); - - (void)classObject;(void)env; -} - -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint siglen, jint publen) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - - unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* sigdata = { (unsigned char*) (data + 32) }; - const unsigned char* pubdata = { (unsigned char*) (data + siglen + 32) }; - - secp256k1_ecdsa_signature sig; - secp256k1_pubkey pubkey; - - int ret = secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigdata, siglen); - - if( ret ) { - ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); - - if( ret ) { - ret = secp256k1_ecdsa_verify(ctx, &sig, data, &pubkey); - } - } - - (void)classObject; - - return ret; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - unsigned char* secKey = (unsigned char*) (data + 32); - - jobjectArray retArray; - jbyteArray sigArray, intsByteArray; - unsigned char intsarray[2]; - - secp256k1_ecdsa_signature sig[72]; - - int ret = secp256k1_ecdsa_sign(ctx, sig, data, secKey, NULL, NULL ); - - unsigned char outputSer[72]; - size_t outputLen = 72; - - if( ret ) { - int ret2 = secp256k1_ecdsa_signature_serialize_der(ctx,outputSer, &outputLen, sig ); (void)ret2; - } - - intsarray[0] = outputLen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - sigArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, sigArray, 0, outputLen, (jbyte*)outputSer); - (*env)->SetObjectArrayElement(env, retArray, 0, sigArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - - (void)classObject; - - return secp256k1_ec_seckey_verify(ctx, secKey); -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - const unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - - secp256k1_pubkey pubkey; - - jobjectArray retArray; - jbyteArray pubkeyArray, intsByteArray; - unsigned char intsarray[2]; - - int ret = secp256k1_ec_pubkey_create(ctx, &pubkey, secKey); - - unsigned char outputSer[65]; - size_t outputLen = 65; - - if( ret ) { - int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; - } - - intsarray[0] = outputLen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - pubkeyArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, pubkeyArray, 0, outputLen, (jbyte*)outputSer); - (*env)->SetObjectArrayElement(env, retArray, 0, pubkeyArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; - -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* tweak = (unsigned char*) (privkey + 32); - - jobjectArray retArray; - jbyteArray privArray, intsByteArray; - unsigned char intsarray[2]; - - int privkeylen = 32; - - int ret = secp256k1_ec_privkey_tweak_add(ctx, privkey, tweak); - - intsarray[0] = privkeylen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - privArray = (*env)->NewByteArray(env, privkeylen); - (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); - (*env)->SetObjectArrayElement(env, retArray, 0, privArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* tweak = (unsigned char*) (privkey + 32); - - jobjectArray retArray; - jbyteArray privArray, intsByteArray; - unsigned char intsarray[2]; - - int privkeylen = 32; - - int ret = secp256k1_ec_privkey_tweak_mul(ctx, privkey, tweak); - - intsarray[0] = privkeylen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - privArray = (*env)->NewByteArray(env, privkeylen); - (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); - (*env)->SetObjectArrayElement(env, retArray, 0, privArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; -/* secp256k1_pubkey* pubkey = (secp256k1_pubkey*) (*env)->GetDirectBufferAddress(env, byteBufferObject);*/ - unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* tweak = (unsigned char*) (pkey + publen); - - jobjectArray retArray; - jbyteArray pubArray, intsByteArray; - unsigned char intsarray[2]; - unsigned char outputSer[65]; - size_t outputLen = 65; - - secp256k1_pubkey pubkey; - int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); - - if( ret ) { - ret = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, tweak); - } - - if( ret ) { - int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; - } - - intsarray[0] = outputLen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - pubArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); - (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* tweak = (unsigned char*) (pkey + publen); - - jobjectArray retArray; - jbyteArray pubArray, intsByteArray; - unsigned char intsarray[2]; - unsigned char outputSer[65]; - size_t outputLen = 65; - - secp256k1_pubkey pubkey; - int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); - - if ( ret ) { - ret = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, tweak); - } - - if( ret ) { - int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; - } - - intsarray[0] = outputLen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - pubArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); - (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1pubkey_1combine - (JNIEnv * env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint numkeys) -{ - (void)classObject;(void)env;(void)byteBufferObject;(void)ctx_l;(void)numkeys; - - return 0; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - const unsigned char* secdata = (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* pubdata = (const unsigned char*) (secdata + 32); - - jobjectArray retArray; - jbyteArray outArray, intsByteArray; - unsigned char intsarray[1]; - secp256k1_pubkey pubkey; - unsigned char nonce_res[32]; - size_t outputLen = 32; - - int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); - - if (ret) { - ret = secp256k1_ecdh( - ctx, - nonce_res, - &pubkey, - secdata - ); - } - - intsarray[0] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - outArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, outArray, 0, 32, (jbyte*)nonce_res); - (*env)->SetObjectArrayElement(env, retArray, 0, outArray); - - intsByteArray = (*env)->NewByteArray(env, 1); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 1, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} diff --git a/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_NativeSecp256k1.h b/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_NativeSecp256k1.h deleted file mode 100644 index fe613c9e9e..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_NativeSecp256k1.h +++ /dev/null @@ -1,119 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -#include "include/secp256k1.h" -/* Header for class org_bitcoin_NativeSecp256k1 */ - -#ifndef _Included_org_bitcoin_NativeSecp256k1 -#define _Included_org_bitcoin_NativeSecp256k1 -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ctx_clone - * Signature: (J)J - */ -SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone - (JNIEnv *, jclass, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_context_randomize - * Signature: (Ljava/nio/ByteBuffer;J)I - */ -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_privkey_tweak_add - * Signature: (Ljava/nio/ByteBuffer;J)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_privkey_tweak_mul - * Signature: (Ljava/nio/ByteBuffer;J)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_pubkey_tweak_add - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add - (JNIEnv *, jclass, jobject, jlong, jint); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_pubkey_tweak_mul - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul - (JNIEnv *, jclass, jobject, jlong, jint); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_destroy_context - * Signature: (J)V - */ -SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context - (JNIEnv *, jclass, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ecdsa_verify - * Signature: (Ljava/nio/ByteBuffer;JII)I - */ -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv *, jclass, jobject, jlong, jint, jint); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ecdsa_sign - * Signature: (Ljava/nio/ByteBuffer;J)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ec_seckey_verify - * Signature: (Ljava/nio/ByteBuffer;J)I - */ -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ec_pubkey_create - * Signature: (Ljava/nio/ByteBuffer;J)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ec_pubkey_parse - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1parse - (JNIEnv *, jclass, jobject, jlong, jint); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ecdh - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_Secp256k1Context.c b/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_Secp256k1Context.c deleted file mode 100644 index a52939e7e7..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_Secp256k1Context.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include "org_bitcoin_Secp256k1Context.h" -#include "include/secp256k1.h" - -SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context - (JNIEnv* env, jclass classObject) -{ - secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - (void)classObject;(void)env; - - return (uintptr_t)ctx; -} - diff --git a/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_Secp256k1Context.h b/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_Secp256k1Context.h deleted file mode 100644 index 0d2bc84b7f..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/java/org_bitcoin_Secp256k1Context.h +++ /dev/null @@ -1,22 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -#include "include/secp256k1.h" -/* Header for class org_bitcoin_Secp256k1Context */ - -#ifndef _Included_org_bitcoin_Secp256k1Context -#define _Included_org_bitcoin_Secp256k1Context -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_bitcoin_Secp256k1Context - * Method: secp256k1_init_context - * Signature: ()J - */ -SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context - (JNIEnv *, jclass); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modinv32.h b/crypto/secp256k1/libsecp256k1/src/modinv32.h new file mode 100644 index 0000000000..846c642f8c --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modinv32.h @@ -0,0 +1,43 @@ +/*********************************************************************** + * Copyright (c) 2020 Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODINV32_H +#define SECP256K1_MODINV32_H + +#include "util.h" + +/* A signed 30-bit limb representation of integers. + * + * Its value is sum(v[i] * 2^(30*i), i=0..8). */ +typedef struct { + int32_t v[9]; +} secp256k1_modinv32_signed30; + +typedef struct { + /* The modulus in signed30 notation, must be odd and in [3, 2^256]. */ + secp256k1_modinv32_signed30 modulus; + + /* modulus^{-1} mod 2^30 */ + uint32_t modulus_inv30; +} secp256k1_modinv32_modinfo; + +/* Replace x with its modular inverse mod modinfo->modulus. x must be in range [0, modulus). + * If x is zero, the result will be zero as well. If not, the inverse must exist (i.e., the gcd of + * x and modulus must be 1). These rules are automatically satisfied if the modulus is prime. + * + * On output, all of x's limbs will be in [0, 2^30). + */ +static void secp256k1_modinv32_var(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo); + +/* Same as secp256k1_modinv32_var, but constant time in x (not in the modulus). */ +static void secp256k1_modinv32(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo); + +/* Compute the Jacobi symbol for (x | modinfo->modulus). x must be coprime with modulus (and thus + * cannot be 0, as modulus >= 3). All limbs of x must be non-negative. Returns 0 if the result + * cannot be computed. */ +static int secp256k1_jacobi32_maybe_var(const secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo); + +#endif /* SECP256K1_MODINV32_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modinv32_impl.h b/crypto/secp256k1/libsecp256k1/src/modinv32_impl.h new file mode 100644 index 0000000000..981d2abc6d --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modinv32_impl.h @@ -0,0 +1,725 @@ +/*********************************************************************** + * Copyright (c) 2020 Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODINV32_IMPL_H +#define SECP256K1_MODINV32_IMPL_H + +#include "modinv32.h" + +#include "util.h" + +#include + +/* This file implements modular inversion based on the paper "Fast constant-time gcd computation and + * modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. + * + * For an explanation of the algorithm, see doc/safegcd_implementation.md. This file contains an + * implementation for N=30, using 30-bit signed limbs represented as int32_t. + */ + +#ifdef VERIFY +static const secp256k1_modinv32_signed30 SECP256K1_SIGNED30_ONE = {{1}}; + +/* Compute a*factor and put it in r. All but the top limb in r will be in range [0,2^30). */ +static void secp256k1_modinv32_mul_30(secp256k1_modinv32_signed30 *r, const secp256k1_modinv32_signed30 *a, int alen, int32_t factor) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + int64_t c = 0; + int i; + for (i = 0; i < 8; ++i) { + if (i < alen) c += (int64_t)a->v[i] * factor; + r->v[i] = (int32_t)c & M30; c >>= 30; + } + if (8 < alen) c += (int64_t)a->v[8] * factor; + VERIFY_CHECK(c == (int32_t)c); + r->v[8] = (int32_t)c; +} + +/* Return -1 for ab*factor. A consists of alen limbs; b has 9. */ +static int secp256k1_modinv32_mul_cmp_30(const secp256k1_modinv32_signed30 *a, int alen, const secp256k1_modinv32_signed30 *b, int32_t factor) { + int i; + secp256k1_modinv32_signed30 am, bm; + secp256k1_modinv32_mul_30(&am, a, alen, 1); /* Normalize all but the top limb of a. */ + secp256k1_modinv32_mul_30(&bm, b, 9, factor); + for (i = 0; i < 8; ++i) { + /* Verify that all but the top limb of a and b are normalized. */ + VERIFY_CHECK(am.v[i] >> 30 == 0); + VERIFY_CHECK(bm.v[i] >> 30 == 0); + } + for (i = 8; i >= 0; --i) { + if (am.v[i] < bm.v[i]) return -1; + if (am.v[i] > bm.v[i]) return 1; + } + return 0; +} +#endif + +/* Take as input a signed30 number in range (-2*modulus,modulus), and add a multiple of the modulus + * to it to bring it to range [0,modulus). If sign < 0, the input will also be negated in the + * process. The input must have limbs in range (-2^30,2^30). The output will have limbs in range + * [0,2^30). */ +static void secp256k1_modinv32_normalize_30(secp256k1_modinv32_signed30 *r, int32_t sign, const secp256k1_modinv32_modinfo *modinfo) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + int32_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4], + r5 = r->v[5], r6 = r->v[6], r7 = r->v[7], r8 = r->v[8]; + volatile int32_t cond_add, cond_negate; + +#ifdef VERIFY + /* Verify that all limbs are in range (-2^30,2^30). */ + int i; + for (i = 0; i < 9; ++i) { + VERIFY_CHECK(r->v[i] >= -M30); + VERIFY_CHECK(r->v[i] <= M30); + } + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(r, 9, &modinfo->modulus, -2) > 0); /* r > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(r, 9, &modinfo->modulus, 1) < 0); /* r < modulus */ +#endif + + /* In a first step, add the modulus if the input is negative, and then negate if requested. + * This brings r from range (-2*modulus,modulus) to range (-modulus,modulus). As all input + * limbs are in range (-2^30,2^30), this cannot overflow an int32_t. Note that the right + * shifts below are signed sign-extending shifts (see assumptions.h for tests that that is + * indeed the behavior of the right shift operator). */ + cond_add = r8 >> 31; + r0 += modinfo->modulus.v[0] & cond_add; + r1 += modinfo->modulus.v[1] & cond_add; + r2 += modinfo->modulus.v[2] & cond_add; + r3 += modinfo->modulus.v[3] & cond_add; + r4 += modinfo->modulus.v[4] & cond_add; + r5 += modinfo->modulus.v[5] & cond_add; + r6 += modinfo->modulus.v[6] & cond_add; + r7 += modinfo->modulus.v[7] & cond_add; + r8 += modinfo->modulus.v[8] & cond_add; + cond_negate = sign >> 31; + r0 = (r0 ^ cond_negate) - cond_negate; + r1 = (r1 ^ cond_negate) - cond_negate; + r2 = (r2 ^ cond_negate) - cond_negate; + r3 = (r3 ^ cond_negate) - cond_negate; + r4 = (r4 ^ cond_negate) - cond_negate; + r5 = (r5 ^ cond_negate) - cond_negate; + r6 = (r6 ^ cond_negate) - cond_negate; + r7 = (r7 ^ cond_negate) - cond_negate; + r8 = (r8 ^ cond_negate) - cond_negate; + /* Propagate the top bits, to bring limbs back to range (-2^30,2^30). */ + r1 += r0 >> 30; r0 &= M30; + r2 += r1 >> 30; r1 &= M30; + r3 += r2 >> 30; r2 &= M30; + r4 += r3 >> 30; r3 &= M30; + r5 += r4 >> 30; r4 &= M30; + r6 += r5 >> 30; r5 &= M30; + r7 += r6 >> 30; r6 &= M30; + r8 += r7 >> 30; r7 &= M30; + + /* In a second step add the modulus again if the result is still negative, bringing r to range + * [0,modulus). */ + cond_add = r8 >> 31; + r0 += modinfo->modulus.v[0] & cond_add; + r1 += modinfo->modulus.v[1] & cond_add; + r2 += modinfo->modulus.v[2] & cond_add; + r3 += modinfo->modulus.v[3] & cond_add; + r4 += modinfo->modulus.v[4] & cond_add; + r5 += modinfo->modulus.v[5] & cond_add; + r6 += modinfo->modulus.v[6] & cond_add; + r7 += modinfo->modulus.v[7] & cond_add; + r8 += modinfo->modulus.v[8] & cond_add; + /* And propagate again. */ + r1 += r0 >> 30; r0 &= M30; + r2 += r1 >> 30; r1 &= M30; + r3 += r2 >> 30; r2 &= M30; + r4 += r3 >> 30; r3 &= M30; + r5 += r4 >> 30; r4 &= M30; + r6 += r5 >> 30; r5 &= M30; + r7 += r6 >> 30; r6 &= M30; + r8 += r7 >> 30; r7 &= M30; + + r->v[0] = r0; + r->v[1] = r1; + r->v[2] = r2; + r->v[3] = r3; + r->v[4] = r4; + r->v[5] = r5; + r->v[6] = r6; + r->v[7] = r7; + r->v[8] = r8; + + VERIFY_CHECK(r0 >> 30 == 0); + VERIFY_CHECK(r1 >> 30 == 0); + VERIFY_CHECK(r2 >> 30 == 0); + VERIFY_CHECK(r3 >> 30 == 0); + VERIFY_CHECK(r4 >> 30 == 0); + VERIFY_CHECK(r5 >> 30 == 0); + VERIFY_CHECK(r6 >> 30 == 0); + VERIFY_CHECK(r7 >> 30 == 0); + VERIFY_CHECK(r8 >> 30 == 0); + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(r, 9, &modinfo->modulus, 0) >= 0); /* r >= 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(r, 9, &modinfo->modulus, 1) < 0); /* r < modulus */ +} + +/* Data type for transition matrices (see section 3 of explanation). + * + * t = [ u v ] + * [ q r ] + */ +typedef struct { + int32_t u, v, q, r; +} secp256k1_modinv32_trans2x2; + +/* Compute the transition matrix and zeta for 30 divsteps. + * + * Input: zeta: initial zeta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Return: final zeta + * + * Implements the divsteps_n_matrix function from the explanation. + */ +static int32_t secp256k1_modinv32_divsteps_30(int32_t zeta, uint32_t f0, uint32_t g0, secp256k1_modinv32_trans2x2 *t) { + /* u,v,q,r are the elements of the transformation matrix being built up, + * starting with the identity matrix. Semantically they are signed integers + * in range [-2^30,2^30], but here represented as unsigned mod 2^32. This + * permits left shifting (which is UB for negative numbers). The range + * being inside [-2^31,2^31) means that casting to signed works correctly. + */ + uint32_t u = 1, v = 0, q = 0, r = 1; + volatile uint32_t c1, c2; + uint32_t mask1, mask2, f = f0, g = g0, x, y, z; + int i; + + for (i = 0; i < 30; ++i) { + VERIFY_CHECK((f & 1) == 1); /* f must always be odd */ + VERIFY_CHECK((u * f0 + v * g0) == f << i); + VERIFY_CHECK((q * f0 + r * g0) == g << i); + /* Compute conditional masks for (zeta < 0) and for (g & 1). */ + c1 = zeta >> 31; + mask1 = c1; + c2 = g & 1; + mask2 = -c2; + /* Compute x,y,z, conditionally negated versions of f,u,v. */ + x = (f ^ mask1) - mask1; + y = (u ^ mask1) - mask1; + z = (v ^ mask1) - mask1; + /* Conditionally add x,y,z to g,q,r. */ + g += x & mask2; + q += y & mask2; + r += z & mask2; + /* In what follows, mask1 is a condition mask for (zeta < 0) and (g & 1). */ + mask1 &= mask2; + /* Conditionally change zeta into -zeta-2 or zeta-1. */ + zeta = (zeta ^ mask1) - 1; + /* Conditionally add g,q,r to f,u,v. */ + f += g & mask1; + u += q & mask1; + v += r & mask1; + /* Shifts */ + g >>= 1; + u <<= 1; + v <<= 1; + /* Bounds on zeta that follow from the bounds on iteration count (max 20*30 divsteps). */ + VERIFY_CHECK(zeta >= -601 && zeta <= 601); + } + /* Return data in t and return value. */ + t->u = (int32_t)u; + t->v = (int32_t)v; + t->q = (int32_t)q; + t->r = (int32_t)r; + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2, the + * aggregate of 30 of them will have determinant 2^30. */ + VERIFY_CHECK((int64_t)t->u * t->r - (int64_t)t->v * t->q == ((int64_t)1) << 30); + return zeta; +} + +/* secp256k1_modinv32_inv256[i] = -(2*i+1)^-1 (mod 256) */ +static const uint8_t secp256k1_modinv32_inv256[128] = { + 0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59, + 0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31, + 0x2F, 0x05, 0xE3, 0x79, 0xF7, 0x0D, 0xEB, 0x41, 0x3F, 0x95, 0x73, 0x89, + 0x07, 0x9D, 0x7B, 0x51, 0x4F, 0x25, 0x03, 0x99, 0x17, 0x2D, 0x0B, 0x61, + 0x5F, 0xB5, 0x93, 0xA9, 0x27, 0xBD, 0x9B, 0x71, 0x6F, 0x45, 0x23, 0xB9, + 0x37, 0x4D, 0x2B, 0x81, 0x7F, 0xD5, 0xB3, 0xC9, 0x47, 0xDD, 0xBB, 0x91, + 0x8F, 0x65, 0x43, 0xD9, 0x57, 0x6D, 0x4B, 0xA1, 0x9F, 0xF5, 0xD3, 0xE9, + 0x67, 0xFD, 0xDB, 0xB1, 0xAF, 0x85, 0x63, 0xF9, 0x77, 0x8D, 0x6B, 0xC1, + 0xBF, 0x15, 0xF3, 0x09, 0x87, 0x1D, 0xFB, 0xD1, 0xCF, 0xA5, 0x83, 0x19, + 0x97, 0xAD, 0x8B, 0xE1, 0xDF, 0x35, 0x13, 0x29, 0xA7, 0x3D, 0x1B, 0xF1, + 0xEF, 0xC5, 0xA3, 0x39, 0xB7, 0xCD, 0xAB, 0x01 +}; + +/* Compute the transition matrix and eta for 30 divsteps (variable time). + * + * Input: eta: initial eta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Return: final eta + * + * Implements the divsteps_n_matrix_var function from the explanation. + */ +static int32_t secp256k1_modinv32_divsteps_30_var(int32_t eta, uint32_t f0, uint32_t g0, secp256k1_modinv32_trans2x2 *t) { + /* Transformation matrix; see comments in secp256k1_modinv32_divsteps_30. */ + uint32_t u = 1, v = 0, q = 0, r = 1; + uint32_t f = f0, g = g0, m; + uint16_t w; + int i = 30, limit, zeros; + + for (;;) { + /* Use a sentinel bit to count zeros only up to i. */ + zeros = secp256k1_ctz32_var(g | (UINT32_MAX << i)); + /* Perform zeros divsteps at once; they all just divide g by two. */ + g >>= zeros; + u <<= zeros; + v <<= zeros; + eta -= zeros; + i -= zeros; + /* We're done once we've done 30 divsteps. */ + if (i == 0) break; + VERIFY_CHECK((f & 1) == 1); + VERIFY_CHECK((g & 1) == 1); + VERIFY_CHECK((u * f0 + v * g0) == f << (30 - i)); + VERIFY_CHECK((q * f0 + r * g0) == g << (30 - i)); + /* Bounds on eta that follow from the bounds on iteration count (max 25*30 divsteps). */ + VERIFY_CHECK(eta >= -751 && eta <= 751); + /* If eta is negative, negate it and replace f,g with g,-f. */ + if (eta < 0) { + uint32_t tmp; + eta = -eta; + tmp = f; f = g; g = -tmp; + tmp = u; u = q; q = -tmp; + tmp = v; v = r; r = -tmp; + } + /* eta is now >= 0. In what follows we're going to cancel out the bottom bits of g. No more + * than i can be cancelled out (as we'd be done before that point), and no more than eta+1 + * can be done as its sign will flip once that happens. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + /* m is a mask for the bottom min(limit, 8) bits (our table only supports 8 bits). */ + VERIFY_CHECK(limit > 0 && limit <= 30); + m = (UINT32_MAX >> (32 - limit)) & 255U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 8) bits. */ + w = (g * secp256k1_modinv32_inv256[(f >> 1) & 127]) & m; + /* Do so. */ + g += f * w; + q += u * w; + r += v * w; + VERIFY_CHECK((g & m) == 0); + } + /* Return data in t and return value. */ + t->u = (int32_t)u; + t->v = (int32_t)v; + t->q = (int32_t)q; + t->r = (int32_t)r; + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2, the + * aggregate of 30 of them will have determinant 2^30. */ + VERIFY_CHECK((int64_t)t->u * t->r - (int64_t)t->v * t->q == ((int64_t)1) << 30); + return eta; +} + +/* Compute the transition matrix and eta for 30 posdivsteps (variable time, eta=-delta), and keeps track + * of the Jacobi symbol along the way. f0 and g0 must be f and g mod 2^32 rather than 2^30, because + * Jacobi tracking requires knowing (f mod 8) rather than just (f mod 2). + * + * Input: eta: initial eta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Input/Output: (*jacp & 1) is bitflipped if and only if the Jacobi symbol of (f | g) changes sign + * by applying the returned transformation matrix to it. The other bits of *jacp may + * change, but are meaningless. + * Return: final eta + */ +static int32_t secp256k1_modinv32_posdivsteps_30_var(int32_t eta, uint32_t f0, uint32_t g0, secp256k1_modinv32_trans2x2 *t, int *jacp) { + /* Transformation matrix. */ + uint32_t u = 1, v = 0, q = 0, r = 1; + uint32_t f = f0, g = g0, m; + uint16_t w; + int i = 30, limit, zeros; + int jac = *jacp; + + for (;;) { + /* Use a sentinel bit to count zeros only up to i. */ + zeros = secp256k1_ctz32_var(g | (UINT32_MAX << i)); + /* Perform zeros divsteps at once; they all just divide g by two. */ + g >>= zeros; + u <<= zeros; + v <<= zeros; + eta -= zeros; + i -= zeros; + /* Update the bottom bit of jac: when dividing g by an odd power of 2, + * if (f mod 8) is 3 or 5, the Jacobi symbol changes sign. */ + jac ^= (zeros & ((f >> 1) ^ (f >> 2))); + /* We're done once we've done 30 posdivsteps. */ + if (i == 0) break; + VERIFY_CHECK((f & 1) == 1); + VERIFY_CHECK((g & 1) == 1); + VERIFY_CHECK((u * f0 + v * g0) == f << (30 - i)); + VERIFY_CHECK((q * f0 + r * g0) == g << (30 - i)); + /* If eta is negative, negate it and replace f,g with g,f. */ + if (eta < 0) { + uint32_t tmp; + eta = -eta; + /* Update bottom bit of jac: when swapping f and g, the Jacobi symbol changes sign + * if both f and g are 3 mod 4. */ + jac ^= ((f & g) >> 1); + tmp = f; f = g; g = tmp; + tmp = u; u = q; q = tmp; + tmp = v; v = r; r = tmp; + } + /* eta is now >= 0. In what follows we're going to cancel out the bottom bits of g. No more + * than i can be cancelled out (as we'd be done before that point), and no more than eta+1 + * can be done as its sign will flip once that happens. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + /* m is a mask for the bottom min(limit, 8) bits (our table only supports 8 bits). */ + VERIFY_CHECK(limit > 0 && limit <= 30); + m = (UINT32_MAX >> (32 - limit)) & 255U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 8) bits. */ + w = (g * secp256k1_modinv32_inv256[(f >> 1) & 127]) & m; + /* Do so. */ + g += f * w; + q += u * w; + r += v * w; + VERIFY_CHECK((g & m) == 0); + } + /* Return data in t and return value. */ + t->u = (int32_t)u; + t->v = (int32_t)v; + t->q = (int32_t)q; + t->r = (int32_t)r; + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2 or -2, + * the aggregate of 30 of them will have determinant 2^30 or -2^30. */ + VERIFY_CHECK((int64_t)t->u * t->r - (int64_t)t->v * t->q == ((int64_t)1) << 30 || + (int64_t)t->u * t->r - (int64_t)t->v * t->q == -(((int64_t)1) << 30)); + *jacp = jac; + return eta; +} + +/* Compute (t/2^30) * [d, e] mod modulus, where t is a transition matrix for 30 divsteps. + * + * On input and output, d and e are in range (-2*modulus,modulus). All output limbs will be in range + * (-2^30,2^30). + * + * This implements the update_de function from the explanation. + */ +static void secp256k1_modinv32_update_de_30(secp256k1_modinv32_signed30 *d, secp256k1_modinv32_signed30 *e, const secp256k1_modinv32_trans2x2 *t, const secp256k1_modinv32_modinfo* modinfo) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + const int32_t u = t->u, v = t->v, q = t->q, r = t->r; + int32_t di, ei, md, me, sd, se; + int64_t cd, ce; + int i; + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(d, 9, &modinfo->modulus, -2) > 0); /* d > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(d, 9, &modinfo->modulus, 1) < 0); /* d < modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(e, 9, &modinfo->modulus, -2) > 0); /* e > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(e, 9, &modinfo->modulus, 1) < 0); /* e < modulus */ + VERIFY_CHECK(labs(u) <= (M30 + 1 - labs(v))); /* |u|+|v| <= 2^30 */ + VERIFY_CHECK(labs(q) <= (M30 + 1 - labs(r))); /* |q|+|r| <= 2^30 */ + + /* [md,me] start as zero; plus [u,q] if d is negative; plus [v,r] if e is negative. */ + sd = d->v[8] >> 31; + se = e->v[8] >> 31; + md = (u & sd) + (v & se); + me = (q & sd) + (r & se); + /* Begin computing t*[d,e]. */ + di = d->v[0]; + ei = e->v[0]; + cd = (int64_t)u * di + (int64_t)v * ei; + ce = (int64_t)q * di + (int64_t)r * ei; + /* Correct md,me so that t*[d,e]+modulus*[md,me] has 30 zero bottom bits. */ + md -= (modinfo->modulus_inv30 * (uint32_t)cd + md) & M30; + me -= (modinfo->modulus_inv30 * (uint32_t)ce + me) & M30; + /* Update the beginning of computation for t*[d,e]+modulus*[md,me] now md,me are known. */ + cd += (int64_t)modinfo->modulus.v[0] * md; + ce += (int64_t)modinfo->modulus.v[0] * me; + /* Verify that the low 30 bits of the computation are indeed zero, and then throw them away. */ + VERIFY_CHECK(((int32_t)cd & M30) == 0); cd >>= 30; + VERIFY_CHECK(((int32_t)ce & M30) == 0); ce >>= 30; + /* Now iteratively compute limb i=1..8 of t*[d,e]+modulus*[md,me], and store them in output + * limb i-1 (shifting down by 30 bits). */ + for (i = 1; i < 9; ++i) { + di = d->v[i]; + ei = e->v[i]; + cd += (int64_t)u * di + (int64_t)v * ei; + ce += (int64_t)q * di + (int64_t)r * ei; + cd += (int64_t)modinfo->modulus.v[i] * md; + ce += (int64_t)modinfo->modulus.v[i] * me; + d->v[i - 1] = (int32_t)cd & M30; cd >>= 30; + e->v[i - 1] = (int32_t)ce & M30; ce >>= 30; + } + /* What remains is limb 9 of t*[d,e]+modulus*[md,me]; store it as output limb 8. */ + d->v[8] = (int32_t)cd; + e->v[8] = (int32_t)ce; + + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(d, 9, &modinfo->modulus, -2) > 0); /* d > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(d, 9, &modinfo->modulus, 1) < 0); /* d < modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(e, 9, &modinfo->modulus, -2) > 0); /* e > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(e, 9, &modinfo->modulus, 1) < 0); /* e < modulus */ +} + +/* Compute (t/2^30) * [f, g], where t is a transition matrix for 30 divsteps. + * + * This implements the update_fg function from the explanation. + */ +static void secp256k1_modinv32_update_fg_30(secp256k1_modinv32_signed30 *f, secp256k1_modinv32_signed30 *g, const secp256k1_modinv32_trans2x2 *t) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + const int32_t u = t->u, v = t->v, q = t->q, r = t->r; + int32_t fi, gi; + int64_t cf, cg; + int i; + /* Start computing t*[f,g]. */ + fi = f->v[0]; + gi = g->v[0]; + cf = (int64_t)u * fi + (int64_t)v * gi; + cg = (int64_t)q * fi + (int64_t)r * gi; + /* Verify that the bottom 30 bits of the result are zero, and then throw them away. */ + VERIFY_CHECK(((int32_t)cf & M30) == 0); cf >>= 30; + VERIFY_CHECK(((int32_t)cg & M30) == 0); cg >>= 30; + /* Now iteratively compute limb i=1..8 of t*[f,g], and store them in output limb i-1 (shifting + * down by 30 bits). */ + for (i = 1; i < 9; ++i) { + fi = f->v[i]; + gi = g->v[i]; + cf += (int64_t)u * fi + (int64_t)v * gi; + cg += (int64_t)q * fi + (int64_t)r * gi; + f->v[i - 1] = (int32_t)cf & M30; cf >>= 30; + g->v[i - 1] = (int32_t)cg & M30; cg >>= 30; + } + /* What remains is limb 9 of t*[f,g]; store it as output limb 8. */ + f->v[8] = (int32_t)cf; + g->v[8] = (int32_t)cg; +} + +/* Compute (t/2^30) * [f, g], where t is a transition matrix for 30 divsteps. + * + * Version that operates on a variable number of limbs in f and g. + * + * This implements the update_fg function from the explanation in modinv64_impl.h. + */ +static void secp256k1_modinv32_update_fg_30_var(int len, secp256k1_modinv32_signed30 *f, secp256k1_modinv32_signed30 *g, const secp256k1_modinv32_trans2x2 *t) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + const int32_t u = t->u, v = t->v, q = t->q, r = t->r; + int32_t fi, gi; + int64_t cf, cg; + int i; + VERIFY_CHECK(len > 0); + /* Start computing t*[f,g]. */ + fi = f->v[0]; + gi = g->v[0]; + cf = (int64_t)u * fi + (int64_t)v * gi; + cg = (int64_t)q * fi + (int64_t)r * gi; + /* Verify that the bottom 62 bits of the result are zero, and then throw them away. */ + VERIFY_CHECK(((int32_t)cf & M30) == 0); cf >>= 30; + VERIFY_CHECK(((int32_t)cg & M30) == 0); cg >>= 30; + /* Now iteratively compute limb i=1..len of t*[f,g], and store them in output limb i-1 (shifting + * down by 30 bits). */ + for (i = 1; i < len; ++i) { + fi = f->v[i]; + gi = g->v[i]; + cf += (int64_t)u * fi + (int64_t)v * gi; + cg += (int64_t)q * fi + (int64_t)r * gi; + f->v[i - 1] = (int32_t)cf & M30; cf >>= 30; + g->v[i - 1] = (int32_t)cg & M30; cg >>= 30; + } + /* What remains is limb (len) of t*[f,g]; store it as output limb (len-1). */ + f->v[len - 1] = (int32_t)cf; + g->v[len - 1] = (int32_t)cg; +} + +/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (constant time in x). */ +static void secp256k1_modinv32(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo) { + /* Start with d=0, e=1, f=modulus, g=x, zeta=-1. */ + secp256k1_modinv32_signed30 d = {{0}}; + secp256k1_modinv32_signed30 e = {{1}}; + secp256k1_modinv32_signed30 f = modinfo->modulus; + secp256k1_modinv32_signed30 g = *x; + int i; + int32_t zeta = -1; /* zeta = -(delta+1/2); delta is initially 1/2. */ + + /* Do 20 iterations of 30 divsteps each = 600 divsteps. 590 suffices for 256-bit inputs. */ + for (i = 0; i < 20; ++i) { + /* Compute transition matrix and new zeta after 30 divsteps. */ + secp256k1_modinv32_trans2x2 t; + zeta = secp256k1_modinv32_divsteps_30(zeta, f.v[0], g.v[0], &t); + /* Update d,e using that transition matrix. */ + secp256k1_modinv32_update_de_30(&d, &e, &t, modinfo); + /* Update f,g using that transition matrix. */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &modinfo->modulus, 1) < 0); /* g < modulus */ + + secp256k1_modinv32_update_fg_30(&f, &g, &t); + + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &modinfo->modulus, 1) < 0); /* g < modulus */ + } + + /* At this point sufficient iterations have been performed that g must have reached 0 + * and (if g was not originally 0) f must now equal +/- GCD of the initial f, g + * values i.e. +/- 1, and d now contains +/- the modular inverse. */ + + /* g == 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &SECP256K1_SIGNED30_ONE, 0) == 0); + /* |f| == 1, or (x == 0 and d == 0 and f == modulus) */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &SECP256K1_SIGNED30_ONE, -1) == 0 || + secp256k1_modinv32_mul_cmp_30(&f, 9, &SECP256K1_SIGNED30_ONE, 1) == 0 || + (secp256k1_modinv32_mul_cmp_30(x, 9, &SECP256K1_SIGNED30_ONE, 0) == 0 && + secp256k1_modinv32_mul_cmp_30(&d, 9, &SECP256K1_SIGNED30_ONE, 0) == 0 && + secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, 1) == 0)); + + /* Optionally negate d, normalize to [0,modulus), and return it. */ + secp256k1_modinv32_normalize_30(&d, f.v[8], modinfo); + *x = d; +} + +/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (variable time). */ +static void secp256k1_modinv32_var(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo) { + /* Start with d=0, e=1, f=modulus, g=x, eta=-1. */ + secp256k1_modinv32_signed30 d = {{0, 0, 0, 0, 0, 0, 0, 0, 0}}; + secp256k1_modinv32_signed30 e = {{1, 0, 0, 0, 0, 0, 0, 0, 0}}; + secp256k1_modinv32_signed30 f = modinfo->modulus; + secp256k1_modinv32_signed30 g = *x; +#ifdef VERIFY + int i = 0; +#endif + int j, len = 9; + int32_t eta = -1; /* eta = -delta; delta is initially 1 (faster for the variable-time code) */ + int32_t cond, fn, gn; + + /* Do iterations of 30 divsteps each until g=0. */ + while (1) { + /* Compute transition matrix and new eta after 30 divsteps. */ + secp256k1_modinv32_trans2x2 t; + eta = secp256k1_modinv32_divsteps_30_var(eta, f.v[0], g.v[0], &t); + /* Update d,e using that transition matrix. */ + secp256k1_modinv32_update_de_30(&d, &e, &t, modinfo); + /* Update f,g using that transition matrix. */ + + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ + + secp256k1_modinv32_update_fg_30_var(len, &f, &g, &t); + /* If the bottom limb of g is 0, there is a chance g=0. */ + if (g.v[0] == 0) { + cond = 0; + /* Check if all other limbs are also 0. */ + for (j = 1; j < len; ++j) { + cond |= g.v[j]; + } + /* If so, we're done. */ + if (cond == 0) break; + } + + /* Determine if len>1 and limb (len-1) of both f and g is 0 or -1. */ + fn = f.v[len - 1]; + gn = g.v[len - 1]; + cond = ((int32_t)len - 2) >> 31; + cond |= fn ^ (fn >> 31); + cond |= gn ^ (gn >> 31); + /* If so, reduce length, propagating the sign of f and g's top limb into the one below. */ + if (cond == 0) { + f.v[len - 2] |= (uint32_t)fn << 30; + g.v[len - 2] |= (uint32_t)gn << 30; + --len; + } + + VERIFY_CHECK(++i < 25); /* We should never need more than 25*30 = 750 divsteps */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ + } + + /* At this point g is 0 and (if g was not originally 0) f must now equal +/- GCD of + * the initial f, g values i.e. +/- 1, and d now contains +/- the modular inverse. */ + + /* g == 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &SECP256K1_SIGNED30_ONE, 0) == 0); + /* |f| == 1, or (x == 0 and d == 0 and f == modulus) */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &SECP256K1_SIGNED30_ONE, -1) == 0 || + secp256k1_modinv32_mul_cmp_30(&f, len, &SECP256K1_SIGNED30_ONE, 1) == 0 || + (secp256k1_modinv32_mul_cmp_30(x, 9, &SECP256K1_SIGNED30_ONE, 0) == 0 && + secp256k1_modinv32_mul_cmp_30(&d, 9, &SECP256K1_SIGNED30_ONE, 0) == 0 && + secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 1) == 0)); + + /* Optionally negate d, normalize to [0,modulus), and return it. */ + secp256k1_modinv32_normalize_30(&d, f.v[len - 1], modinfo); + *x = d; +} + +/* Do up to 50 iterations of 30 posdivsteps (up to 1500 steps; more is extremely rare) each until f=1. + * In VERIFY mode use a lower number of iterations (750, close to the median 756), so failure actually occurs. */ +#ifdef VERIFY +#define JACOBI32_ITERATIONS 25 +#else +#define JACOBI32_ITERATIONS 50 +#endif + +/* Compute the Jacobi symbol of x modulo modinfo->modulus (variable time). gcd(x,modulus) must be 1. */ +static int secp256k1_jacobi32_maybe_var(const secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo) { + /* Start with f=modulus, g=x, eta=-1. */ + secp256k1_modinv32_signed30 f = modinfo->modulus; + secp256k1_modinv32_signed30 g = *x; + int j, len = 9; + int32_t eta = -1; /* eta = -delta; delta is initially 1 */ + int32_t cond, fn, gn; + int jac = 0; + int count; + + /* The input limbs must all be non-negative. */ + VERIFY_CHECK(g.v[0] >= 0 && g.v[1] >= 0 && g.v[2] >= 0 && g.v[3] >= 0 && g.v[4] >= 0 && g.v[5] >= 0 && g.v[6] >= 0 && g.v[7] >= 0 && g.v[8] >= 0); + + /* If x > 0, then if the loop below converges, it converges to f=g=gcd(x,modulus). Since we + * require that gcd(x,modulus)=1 and modulus>=3, x cannot be 0. Thus, we must reach f=1 (or + * time out). */ + VERIFY_CHECK((g.v[0] | g.v[1] | g.v[2] | g.v[3] | g.v[4] | g.v[5] | g.v[6] | g.v[7] | g.v[8]) != 0); + + for (count = 0; count < JACOBI32_ITERATIONS; ++count) { + /* Compute transition matrix and new eta after 30 posdivsteps. */ + secp256k1_modinv32_trans2x2 t; + eta = secp256k1_modinv32_posdivsteps_30_var(eta, f.v[0] | ((uint32_t)f.v[1] << 30), g.v[0] | ((uint32_t)g.v[1] << 30), &t, &jac); + /* Update f,g using that transition matrix. */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 0) > 0); /* f > 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, 0) > 0); /* g > 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ + + secp256k1_modinv32_update_fg_30_var(len, &f, &g, &t); + /* If the bottom limb of f is 1, there is a chance that f=1. */ + if (f.v[0] == 1) { + cond = 0; + /* Check if the other limbs are also 0. */ + for (j = 1; j < len; ++j) { + cond |= f.v[j]; + } + /* If so, we're done. If f=1, the Jacobi symbol (g | f)=1. */ + if (cond == 0) return 1 - 2*(jac & 1); + } + + /* Determine if len>1 and limb (len-1) of both f and g is 0. */ + fn = f.v[len - 1]; + gn = g.v[len - 1]; + cond = ((int32_t)len - 2) >> 31; + cond |= fn; + cond |= gn; + /* If so, reduce length. */ + if (cond == 0) --len; + + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 0) > 0); /* f > 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, 0) > 0); /* g > 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ + } + + /* The loop failed to converge to f=g after 1500 iterations. Return 0, indicating unknown result. */ + return 0; +} + +#endif /* SECP256K1_MODINV32_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modinv64.h b/crypto/secp256k1/libsecp256k1/src/modinv64.h new file mode 100644 index 0000000000..f4208e6c23 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modinv64.h @@ -0,0 +1,47 @@ +/*********************************************************************** + * Copyright (c) 2020 Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODINV64_H +#define SECP256K1_MODINV64_H + +#include "util.h" + +#ifndef SECP256K1_WIDEMUL_INT128 +#error "modinv64 requires 128-bit wide multiplication support" +#endif + +/* A signed 62-bit limb representation of integers. + * + * Its value is sum(v[i] * 2^(62*i), i=0..4). */ +typedef struct { + int64_t v[5]; +} secp256k1_modinv64_signed62; + +typedef struct { + /* The modulus in signed62 notation, must be odd and in [3, 2^256]. */ + secp256k1_modinv64_signed62 modulus; + + /* modulus^{-1} mod 2^62 */ + uint64_t modulus_inv62; +} secp256k1_modinv64_modinfo; + +/* Replace x with its modular inverse mod modinfo->modulus. x must be in range [0, modulus). + * If x is zero, the result will be zero as well. If not, the inverse must exist (i.e., the gcd of + * x and modulus must be 1). These rules are automatically satisfied if the modulus is prime. + * + * On output, all of x's limbs will be in [0, 2^62). + */ +static void secp256k1_modinv64_var(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo); + +/* Same as secp256k1_modinv64_var, but constant time in x (not in the modulus). */ +static void secp256k1_modinv64(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo); + +/* Compute the Jacobi symbol for (x | modinfo->modulus). x must be coprime with modulus (and thus + * cannot be 0, as modulus >= 3). All limbs of x must be non-negative. Returns 0 if the result + * cannot be computed. */ +static int secp256k1_jacobi64_maybe_var(const secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo); + +#endif /* SECP256K1_MODINV64_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modinv64_impl.h b/crypto/secp256k1/libsecp256k1/src/modinv64_impl.h new file mode 100644 index 0000000000..548787bedf --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modinv64_impl.h @@ -0,0 +1,780 @@ +/*********************************************************************** + * Copyright (c) 2020 Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODINV64_IMPL_H +#define SECP256K1_MODINV64_IMPL_H + +#include "int128.h" +#include "modinv64.h" + +/* This file implements modular inversion based on the paper "Fast constant-time gcd computation and + * modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. + * + * For an explanation of the algorithm, see doc/safegcd_implementation.md. This file contains an + * implementation for N=62, using 62-bit signed limbs represented as int64_t. + */ + +/* Data type for transition matrices (see section 3 of explanation). + * + * t = [ u v ] + * [ q r ] + */ +typedef struct { + int64_t u, v, q, r; +} secp256k1_modinv64_trans2x2; + +#ifdef VERIFY +/* Helper function to compute the absolute value of an int64_t. + * (we don't use abs/labs/llabs as it depends on the int sizes). */ +static int64_t secp256k1_modinv64_abs(int64_t v) { + VERIFY_CHECK(v > INT64_MIN); + if (v < 0) return -v; + return v; +} + +static const secp256k1_modinv64_signed62 SECP256K1_SIGNED62_ONE = {{1}}; + +/* Compute a*factor and put it in r. All but the top limb in r will be in range [0,2^62). */ +static void secp256k1_modinv64_mul_62(secp256k1_modinv64_signed62 *r, const secp256k1_modinv64_signed62 *a, int alen, int64_t factor) { + const uint64_t M62 = UINT64_MAX >> 2; + secp256k1_int128 c, d; + int i; + secp256k1_i128_from_i64(&c, 0); + for (i = 0; i < 4; ++i) { + if (i < alen) secp256k1_i128_accum_mul(&c, a->v[i], factor); + r->v[i] = secp256k1_i128_to_u64(&c) & M62; secp256k1_i128_rshift(&c, 62); + } + if (4 < alen) secp256k1_i128_accum_mul(&c, a->v[4], factor); + secp256k1_i128_from_i64(&d, secp256k1_i128_to_i64(&c)); + VERIFY_CHECK(secp256k1_i128_eq_var(&c, &d)); + r->v[4] = secp256k1_i128_to_i64(&c); +} + +/* Return -1 for ab*factor. A has alen limbs; b has 5. */ +static int secp256k1_modinv64_mul_cmp_62(const secp256k1_modinv64_signed62 *a, int alen, const secp256k1_modinv64_signed62 *b, int64_t factor) { + int i; + secp256k1_modinv64_signed62 am, bm; + secp256k1_modinv64_mul_62(&am, a, alen, 1); /* Normalize all but the top limb of a. */ + secp256k1_modinv64_mul_62(&bm, b, 5, factor); + for (i = 0; i < 4; ++i) { + /* Verify that all but the top limb of a and b are normalized. */ + VERIFY_CHECK(am.v[i] >> 62 == 0); + VERIFY_CHECK(bm.v[i] >> 62 == 0); + } + for (i = 4; i >= 0; --i) { + if (am.v[i] < bm.v[i]) return -1; + if (am.v[i] > bm.v[i]) return 1; + } + return 0; +} + +/* Check if the determinant of t is equal to 1 << n. If abs, check if |det t| == 1 << n. */ +static int secp256k1_modinv64_det_check_pow2(const secp256k1_modinv64_trans2x2 *t, unsigned int n, int abs) { + secp256k1_int128 a; + secp256k1_i128_det(&a, t->u, t->v, t->q, t->r); + if (secp256k1_i128_check_pow2(&a, n, 1)) return 1; + if (abs && secp256k1_i128_check_pow2(&a, n, -1)) return 1; + return 0; +} +#endif + +/* Take as input a signed62 number in range (-2*modulus,modulus), and add a multiple of the modulus + * to it to bring it to range [0,modulus). If sign < 0, the input will also be negated in the + * process. The input must have limbs in range (-2^62,2^62). The output will have limbs in range + * [0,2^62). */ +static void secp256k1_modinv64_normalize_62(secp256k1_modinv64_signed62 *r, int64_t sign, const secp256k1_modinv64_modinfo *modinfo) { + const int64_t M62 = (int64_t)(UINT64_MAX >> 2); + int64_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4]; + volatile int64_t cond_add, cond_negate; + +#ifdef VERIFY + /* Verify that all limbs are in range (-2^62,2^62). */ + int i; + for (i = 0; i < 5; ++i) { + VERIFY_CHECK(r->v[i] >= -M62); + VERIFY_CHECK(r->v[i] <= M62); + } + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(r, 5, &modinfo->modulus, -2) > 0); /* r > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(r, 5, &modinfo->modulus, 1) < 0); /* r < modulus */ +#endif + + /* In a first step, add the modulus if the input is negative, and then negate if requested. + * This brings r from range (-2*modulus,modulus) to range (-modulus,modulus). As all input + * limbs are in range (-2^62,2^62), this cannot overflow an int64_t. Note that the right + * shifts below are signed sign-extending shifts (see assumptions.h for tests that that is + * indeed the behavior of the right shift operator). */ + cond_add = r4 >> 63; + r0 += modinfo->modulus.v[0] & cond_add; + r1 += modinfo->modulus.v[1] & cond_add; + r2 += modinfo->modulus.v[2] & cond_add; + r3 += modinfo->modulus.v[3] & cond_add; + r4 += modinfo->modulus.v[4] & cond_add; + cond_negate = sign >> 63; + r0 = (r0 ^ cond_negate) - cond_negate; + r1 = (r1 ^ cond_negate) - cond_negate; + r2 = (r2 ^ cond_negate) - cond_negate; + r3 = (r3 ^ cond_negate) - cond_negate; + r4 = (r4 ^ cond_negate) - cond_negate; + /* Propagate the top bits, to bring limbs back to range (-2^62,2^62). */ + r1 += r0 >> 62; r0 &= M62; + r2 += r1 >> 62; r1 &= M62; + r3 += r2 >> 62; r2 &= M62; + r4 += r3 >> 62; r3 &= M62; + + /* In a second step add the modulus again if the result is still negative, bringing + * r to range [0,modulus). */ + cond_add = r4 >> 63; + r0 += modinfo->modulus.v[0] & cond_add; + r1 += modinfo->modulus.v[1] & cond_add; + r2 += modinfo->modulus.v[2] & cond_add; + r3 += modinfo->modulus.v[3] & cond_add; + r4 += modinfo->modulus.v[4] & cond_add; + /* And propagate again. */ + r1 += r0 >> 62; r0 &= M62; + r2 += r1 >> 62; r1 &= M62; + r3 += r2 >> 62; r2 &= M62; + r4 += r3 >> 62; r3 &= M62; + + r->v[0] = r0; + r->v[1] = r1; + r->v[2] = r2; + r->v[3] = r3; + r->v[4] = r4; + + VERIFY_CHECK(r0 >> 62 == 0); + VERIFY_CHECK(r1 >> 62 == 0); + VERIFY_CHECK(r2 >> 62 == 0); + VERIFY_CHECK(r3 >> 62 == 0); + VERIFY_CHECK(r4 >> 62 == 0); + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(r, 5, &modinfo->modulus, 0) >= 0); /* r >= 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(r, 5, &modinfo->modulus, 1) < 0); /* r < modulus */ +} + +/* Compute the transition matrix and eta for 59 divsteps (where zeta=-(delta+1/2)). + * Note that the transformation matrix is scaled by 2^62 and not 2^59. + * + * Input: zeta: initial zeta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Return: final zeta + * + * Implements the divsteps_n_matrix function from the explanation. + */ +static int64_t secp256k1_modinv64_divsteps_59(int64_t zeta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) { + /* u,v,q,r are the elements of the transformation matrix being built up, + * starting with the identity matrix times 8 (because the caller expects + * a result scaled by 2^62). Semantically they are signed integers + * in range [-2^62,2^62], but here represented as unsigned mod 2^64. This + * permits left shifting (which is UB for negative numbers). The range + * being inside [-2^63,2^63) means that casting to signed works correctly. + */ + uint64_t u = 8, v = 0, q = 0, r = 8; + volatile uint64_t c1, c2; + uint64_t mask1, mask2, f = f0, g = g0, x, y, z; + int i; + + for (i = 3; i < 62; ++i) { + VERIFY_CHECK((f & 1) == 1); /* f must always be odd */ + VERIFY_CHECK((u * f0 + v * g0) == f << i); + VERIFY_CHECK((q * f0 + r * g0) == g << i); + /* Compute conditional masks for (zeta < 0) and for (g & 1). */ + c1 = zeta >> 63; + mask1 = c1; + c2 = g & 1; + mask2 = -c2; + /* Compute x,y,z, conditionally negated versions of f,u,v. */ + x = (f ^ mask1) - mask1; + y = (u ^ mask1) - mask1; + z = (v ^ mask1) - mask1; + /* Conditionally add x,y,z to g,q,r. */ + g += x & mask2; + q += y & mask2; + r += z & mask2; + /* In what follows, c1 is a condition mask for (zeta < 0) and (g & 1). */ + mask1 &= mask2; + /* Conditionally change zeta into -zeta-2 or zeta-1. */ + zeta = (zeta ^ mask1) - 1; + /* Conditionally add g,q,r to f,u,v. */ + f += g & mask1; + u += q & mask1; + v += r & mask1; + /* Shifts */ + g >>= 1; + u <<= 1; + v <<= 1; + /* Bounds on zeta that follow from the bounds on iteration count (max 10*59 divsteps). */ + VERIFY_CHECK(zeta >= -591 && zeta <= 591); + } + /* Return data in t and return value. */ + t->u = (int64_t)u; + t->v = (int64_t)v; + t->q = (int64_t)q; + t->r = (int64_t)r; + + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2, the + * aggregate of 59 of them will have determinant 2^59. Multiplying with the initial + * 8*identity (which has determinant 2^6) means the overall outputs has determinant + * 2^65. */ + VERIFY_CHECK(secp256k1_modinv64_det_check_pow2(t, 65, 0)); + + return zeta; +} + +/* Compute the transition matrix and eta for 62 divsteps (variable time, eta=-delta). + * + * Input: eta: initial eta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Return: final eta + * + * Implements the divsteps_n_matrix_var function from the explanation. + */ +static int64_t secp256k1_modinv64_divsteps_62_var(int64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) { + /* Transformation matrix; see comments in secp256k1_modinv64_divsteps_62. */ + uint64_t u = 1, v = 0, q = 0, r = 1; + uint64_t f = f0, g = g0, m; + uint32_t w; + int i = 62, limit, zeros; + + for (;;) { + /* Use a sentinel bit to count zeros only up to i. */ + zeros = secp256k1_ctz64_var(g | (UINT64_MAX << i)); + /* Perform zeros divsteps at once; they all just divide g by two. */ + g >>= zeros; + u <<= zeros; + v <<= zeros; + eta -= zeros; + i -= zeros; + /* We're done once we've done 62 divsteps. */ + if (i == 0) break; + VERIFY_CHECK((f & 1) == 1); + VERIFY_CHECK((g & 1) == 1); + VERIFY_CHECK((u * f0 + v * g0) == f << (62 - i)); + VERIFY_CHECK((q * f0 + r * g0) == g << (62 - i)); + /* Bounds on eta that follow from the bounds on iteration count (max 12*62 divsteps). */ + VERIFY_CHECK(eta >= -745 && eta <= 745); + /* If eta is negative, negate it and replace f,g with g,-f. */ + if (eta < 0) { + uint64_t tmp; + eta = -eta; + tmp = f; f = g; g = -tmp; + tmp = u; u = q; q = -tmp; + tmp = v; v = r; r = -tmp; + /* Use a formula to cancel out up to 6 bits of g. Also, no more than i can be cancelled + * out (as we'd be done before that point), and no more than eta+1 can be done as its + * sign will flip again once that happens. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + VERIFY_CHECK(limit > 0 && limit <= 62); + /* m is a mask for the bottom min(limit, 6) bits. */ + m = (UINT64_MAX >> (64 - limit)) & 63U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 6) + * bits. */ + w = (f * g * (f * f - 2)) & m; + } else { + /* In this branch, use a simpler formula that only lets us cancel up to 4 bits of g, as + * eta tends to be smaller here. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + VERIFY_CHECK(limit > 0 && limit <= 62); + /* m is a mask for the bottom min(limit, 4) bits. */ + m = (UINT64_MAX >> (64 - limit)) & 15U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 4) + * bits. */ + w = f + (((f + 1) & 4) << 1); + w = (-w * g) & m; + } + g += f * w; + q += u * w; + r += v * w; + VERIFY_CHECK((g & m) == 0); + } + /* Return data in t and return value. */ + t->u = (int64_t)u; + t->v = (int64_t)v; + t->q = (int64_t)q; + t->r = (int64_t)r; + + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2, the + * aggregate of 62 of them will have determinant 2^62. */ + VERIFY_CHECK(secp256k1_modinv64_det_check_pow2(t, 62, 0)); + + return eta; +} + +/* Compute the transition matrix and eta for 62 posdivsteps (variable time, eta=-delta), and keeps track + * of the Jacobi symbol along the way. f0 and g0 must be f and g mod 2^64 rather than 2^62, because + * Jacobi tracking requires knowing (f mod 8) rather than just (f mod 2). + * + * Input: eta: initial eta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Input/Output: (*jacp & 1) is bitflipped if and only if the Jacobi symbol of (f | g) changes sign + * by applying the returned transformation matrix to it. The other bits of *jacp may + * change, but are meaningless. + * Return: final eta + */ +static int64_t secp256k1_modinv64_posdivsteps_62_var(int64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t, int *jacp) { + /* Transformation matrix; see comments in secp256k1_modinv64_divsteps_62. */ + uint64_t u = 1, v = 0, q = 0, r = 1; + uint64_t f = f0, g = g0, m; + uint32_t w; + int i = 62, limit, zeros; + int jac = *jacp; + + for (;;) { + /* Use a sentinel bit to count zeros only up to i. */ + zeros = secp256k1_ctz64_var(g | (UINT64_MAX << i)); + /* Perform zeros divsteps at once; they all just divide g by two. */ + g >>= zeros; + u <<= zeros; + v <<= zeros; + eta -= zeros; + i -= zeros; + /* Update the bottom bit of jac: when dividing g by an odd power of 2, + * if (f mod 8) is 3 or 5, the Jacobi symbol changes sign. */ + jac ^= (zeros & ((f >> 1) ^ (f >> 2))); + /* We're done once we've done 62 posdivsteps. */ + if (i == 0) break; + VERIFY_CHECK((f & 1) == 1); + VERIFY_CHECK((g & 1) == 1); + VERIFY_CHECK((u * f0 + v * g0) == f << (62 - i)); + VERIFY_CHECK((q * f0 + r * g0) == g << (62 - i)); + /* If eta is negative, negate it and replace f,g with g,f. */ + if (eta < 0) { + uint64_t tmp; + eta = -eta; + tmp = f; f = g; g = tmp; + tmp = u; u = q; q = tmp; + tmp = v; v = r; r = tmp; + /* Update bottom bit of jac: when swapping f and g, the Jacobi symbol changes sign + * if both f and g are 3 mod 4. */ + jac ^= ((f & g) >> 1); + /* Use a formula to cancel out up to 6 bits of g. Also, no more than i can be cancelled + * out (as we'd be done before that point), and no more than eta+1 can be done as its + * sign will flip again once that happens. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + VERIFY_CHECK(limit > 0 && limit <= 62); + /* m is a mask for the bottom min(limit, 6) bits. */ + m = (UINT64_MAX >> (64 - limit)) & 63U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 6) + * bits. */ + w = (f * g * (f * f - 2)) & m; + } else { + /* In this branch, use a simpler formula that only lets us cancel up to 4 bits of g, as + * eta tends to be smaller here. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + VERIFY_CHECK(limit > 0 && limit <= 62); + /* m is a mask for the bottom min(limit, 4) bits. */ + m = (UINT64_MAX >> (64 - limit)) & 15U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 4) + * bits. */ + w = f + (((f + 1) & 4) << 1); + w = (-w * g) & m; + } + g += f * w; + q += u * w; + r += v * w; + VERIFY_CHECK((g & m) == 0); + } + /* Return data in t and return value. */ + t->u = (int64_t)u; + t->v = (int64_t)v; + t->q = (int64_t)q; + t->r = (int64_t)r; + + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2 or -2, + * the aggregate of 62 of them will have determinant 2^62 or -2^62. */ + VERIFY_CHECK(secp256k1_modinv64_det_check_pow2(t, 62, 1)); + + *jacp = jac; + return eta; +} + +/* Compute (t/2^62) * [d, e] mod modulus, where t is a transition matrix scaled by 2^62. + * + * On input and output, d and e are in range (-2*modulus,modulus). All output limbs will be in range + * (-2^62,2^62). + * + * This implements the update_de function from the explanation. + */ +static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp256k1_modinv64_signed62 *e, const secp256k1_modinv64_trans2x2 *t, const secp256k1_modinv64_modinfo* modinfo) { + const uint64_t M62 = UINT64_MAX >> 2; + const int64_t d0 = d->v[0], d1 = d->v[1], d2 = d->v[2], d3 = d->v[3], d4 = d->v[4]; + const int64_t e0 = e->v[0], e1 = e->v[1], e2 = e->v[2], e3 = e->v[3], e4 = e->v[4]; + const int64_t u = t->u, v = t->v, q = t->q, r = t->r; + int64_t md, me, sd, se; + secp256k1_int128 cd, ce; + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(d, 5, &modinfo->modulus, -2) > 0); /* d > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(d, 5, &modinfo->modulus, 1) < 0); /* d < modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, -2) > 0); /* e > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, 1) < 0); /* e < modulus */ + VERIFY_CHECK(secp256k1_modinv64_abs(u) <= (((int64_t)1 << 62) - secp256k1_modinv64_abs(v))); /* |u|+|v| <= 2^62 */ + VERIFY_CHECK(secp256k1_modinv64_abs(q) <= (((int64_t)1 << 62) - secp256k1_modinv64_abs(r))); /* |q|+|r| <= 2^62 */ + + /* [md,me] start as zero; plus [u,q] if d is negative; plus [v,r] if e is negative. */ + sd = d4 >> 63; + se = e4 >> 63; + md = (u & sd) + (v & se); + me = (q & sd) + (r & se); + /* Begin computing t*[d,e]. */ + secp256k1_i128_mul(&cd, u, d0); + secp256k1_i128_accum_mul(&cd, v, e0); + secp256k1_i128_mul(&ce, q, d0); + secp256k1_i128_accum_mul(&ce, r, e0); + /* Correct md,me so that t*[d,e]+modulus*[md,me] has 62 zero bottom bits. */ + md -= (modinfo->modulus_inv62 * secp256k1_i128_to_u64(&cd) + md) & M62; + me -= (modinfo->modulus_inv62 * secp256k1_i128_to_u64(&ce) + me) & M62; + /* Update the beginning of computation for t*[d,e]+modulus*[md,me] now md,me are known. */ + secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[0], md); + secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[0], me); + /* Verify that the low 62 bits of the computation are indeed zero, and then throw them away. */ + VERIFY_CHECK((secp256k1_i128_to_u64(&cd) & M62) == 0); secp256k1_i128_rshift(&cd, 62); + VERIFY_CHECK((secp256k1_i128_to_u64(&ce) & M62) == 0); secp256k1_i128_rshift(&ce, 62); + /* Compute limb 1 of t*[d,e]+modulus*[md,me], and store it as output limb 0 (= down shift). */ + secp256k1_i128_accum_mul(&cd, u, d1); + secp256k1_i128_accum_mul(&cd, v, e1); + secp256k1_i128_accum_mul(&ce, q, d1); + secp256k1_i128_accum_mul(&ce, r, e1); + if (modinfo->modulus.v[1]) { /* Optimize for the case where limb of modulus is zero. */ + secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[1], md); + secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[1], me); + } + d->v[0] = secp256k1_i128_to_u64(&cd) & M62; secp256k1_i128_rshift(&cd, 62); + e->v[0] = secp256k1_i128_to_u64(&ce) & M62; secp256k1_i128_rshift(&ce, 62); + /* Compute limb 2 of t*[d,e]+modulus*[md,me], and store it as output limb 1. */ + secp256k1_i128_accum_mul(&cd, u, d2); + secp256k1_i128_accum_mul(&cd, v, e2); + secp256k1_i128_accum_mul(&ce, q, d2); + secp256k1_i128_accum_mul(&ce, r, e2); + if (modinfo->modulus.v[2]) { /* Optimize for the case where limb of modulus is zero. */ + secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[2], md); + secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[2], me); + } + d->v[1] = secp256k1_i128_to_u64(&cd) & M62; secp256k1_i128_rshift(&cd, 62); + e->v[1] = secp256k1_i128_to_u64(&ce) & M62; secp256k1_i128_rshift(&ce, 62); + /* Compute limb 3 of t*[d,e]+modulus*[md,me], and store it as output limb 2. */ + secp256k1_i128_accum_mul(&cd, u, d3); + secp256k1_i128_accum_mul(&cd, v, e3); + secp256k1_i128_accum_mul(&ce, q, d3); + secp256k1_i128_accum_mul(&ce, r, e3); + if (modinfo->modulus.v[3]) { /* Optimize for the case where limb of modulus is zero. */ + secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[3], md); + secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[3], me); + } + d->v[2] = secp256k1_i128_to_u64(&cd) & M62; secp256k1_i128_rshift(&cd, 62); + e->v[2] = secp256k1_i128_to_u64(&ce) & M62; secp256k1_i128_rshift(&ce, 62); + /* Compute limb 4 of t*[d,e]+modulus*[md,me], and store it as output limb 3. */ + secp256k1_i128_accum_mul(&cd, u, d4); + secp256k1_i128_accum_mul(&cd, v, e4); + secp256k1_i128_accum_mul(&ce, q, d4); + secp256k1_i128_accum_mul(&ce, r, e4); + secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[4], md); + secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[4], me); + d->v[3] = secp256k1_i128_to_u64(&cd) & M62; secp256k1_i128_rshift(&cd, 62); + e->v[3] = secp256k1_i128_to_u64(&ce) & M62; secp256k1_i128_rshift(&ce, 62); + /* What remains is limb 5 of t*[d,e]+modulus*[md,me]; store it as output limb 4. */ + d->v[4] = secp256k1_i128_to_i64(&cd); + e->v[4] = secp256k1_i128_to_i64(&ce); + + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(d, 5, &modinfo->modulus, -2) > 0); /* d > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(d, 5, &modinfo->modulus, 1) < 0); /* d < modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, -2) > 0); /* e > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, 1) < 0); /* e < modulus */ +} + +/* Compute (t/2^62) * [f, g], where t is a transition matrix scaled by 2^62. + * + * This implements the update_fg function from the explanation. + */ +static void secp256k1_modinv64_update_fg_62(secp256k1_modinv64_signed62 *f, secp256k1_modinv64_signed62 *g, const secp256k1_modinv64_trans2x2 *t) { + const uint64_t M62 = UINT64_MAX >> 2; + const int64_t f0 = f->v[0], f1 = f->v[1], f2 = f->v[2], f3 = f->v[3], f4 = f->v[4]; + const int64_t g0 = g->v[0], g1 = g->v[1], g2 = g->v[2], g3 = g->v[3], g4 = g->v[4]; + const int64_t u = t->u, v = t->v, q = t->q, r = t->r; + secp256k1_int128 cf, cg; + /* Start computing t*[f,g]. */ + secp256k1_i128_mul(&cf, u, f0); + secp256k1_i128_accum_mul(&cf, v, g0); + secp256k1_i128_mul(&cg, q, f0); + secp256k1_i128_accum_mul(&cg, r, g0); + /* Verify that the bottom 62 bits of the result are zero, and then throw them away. */ + VERIFY_CHECK((secp256k1_i128_to_u64(&cf) & M62) == 0); secp256k1_i128_rshift(&cf, 62); + VERIFY_CHECK((secp256k1_i128_to_u64(&cg) & M62) == 0); secp256k1_i128_rshift(&cg, 62); + /* Compute limb 1 of t*[f,g], and store it as output limb 0 (= down shift). */ + secp256k1_i128_accum_mul(&cf, u, f1); + secp256k1_i128_accum_mul(&cf, v, g1); + secp256k1_i128_accum_mul(&cg, q, f1); + secp256k1_i128_accum_mul(&cg, r, g1); + f->v[0] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62); + g->v[0] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62); + /* Compute limb 2 of t*[f,g], and store it as output limb 1. */ + secp256k1_i128_accum_mul(&cf, u, f2); + secp256k1_i128_accum_mul(&cf, v, g2); + secp256k1_i128_accum_mul(&cg, q, f2); + secp256k1_i128_accum_mul(&cg, r, g2); + f->v[1] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62); + g->v[1] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62); + /* Compute limb 3 of t*[f,g], and store it as output limb 2. */ + secp256k1_i128_accum_mul(&cf, u, f3); + secp256k1_i128_accum_mul(&cf, v, g3); + secp256k1_i128_accum_mul(&cg, q, f3); + secp256k1_i128_accum_mul(&cg, r, g3); + f->v[2] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62); + g->v[2] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62); + /* Compute limb 4 of t*[f,g], and store it as output limb 3. */ + secp256k1_i128_accum_mul(&cf, u, f4); + secp256k1_i128_accum_mul(&cf, v, g4); + secp256k1_i128_accum_mul(&cg, q, f4); + secp256k1_i128_accum_mul(&cg, r, g4); + f->v[3] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62); + g->v[3] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62); + /* What remains is limb 5 of t*[f,g]; store it as output limb 4. */ + f->v[4] = secp256k1_i128_to_i64(&cf); + g->v[4] = secp256k1_i128_to_i64(&cg); +} + +/* Compute (t/2^62) * [f, g], where t is a transition matrix for 62 divsteps. + * + * Version that operates on a variable number of limbs in f and g. + * + * This implements the update_fg function from the explanation. + */ +static void secp256k1_modinv64_update_fg_62_var(int len, secp256k1_modinv64_signed62 *f, secp256k1_modinv64_signed62 *g, const secp256k1_modinv64_trans2x2 *t) { + const uint64_t M62 = UINT64_MAX >> 2; + const int64_t u = t->u, v = t->v, q = t->q, r = t->r; + int64_t fi, gi; + secp256k1_int128 cf, cg; + int i; + VERIFY_CHECK(len > 0); + /* Start computing t*[f,g]. */ + fi = f->v[0]; + gi = g->v[0]; + secp256k1_i128_mul(&cf, u, fi); + secp256k1_i128_accum_mul(&cf, v, gi); + secp256k1_i128_mul(&cg, q, fi); + secp256k1_i128_accum_mul(&cg, r, gi); + /* Verify that the bottom 62 bits of the result are zero, and then throw them away. */ + VERIFY_CHECK((secp256k1_i128_to_u64(&cf) & M62) == 0); secp256k1_i128_rshift(&cf, 62); + VERIFY_CHECK((secp256k1_i128_to_u64(&cg) & M62) == 0); secp256k1_i128_rshift(&cg, 62); + /* Now iteratively compute limb i=1..len of t*[f,g], and store them in output limb i-1 (shifting + * down by 62 bits). */ + for (i = 1; i < len; ++i) { + fi = f->v[i]; + gi = g->v[i]; + secp256k1_i128_accum_mul(&cf, u, fi); + secp256k1_i128_accum_mul(&cf, v, gi); + secp256k1_i128_accum_mul(&cg, q, fi); + secp256k1_i128_accum_mul(&cg, r, gi); + f->v[i - 1] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62); + g->v[i - 1] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62); + } + /* What remains is limb (len) of t*[f,g]; store it as output limb (len-1). */ + f->v[len - 1] = secp256k1_i128_to_i64(&cf); + g->v[len - 1] = secp256k1_i128_to_i64(&cg); +} + +/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (constant time in x). */ +static void secp256k1_modinv64(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo) { + /* Start with d=0, e=1, f=modulus, g=x, zeta=-1. */ + secp256k1_modinv64_signed62 d = {{0, 0, 0, 0, 0}}; + secp256k1_modinv64_signed62 e = {{1, 0, 0, 0, 0}}; + secp256k1_modinv64_signed62 f = modinfo->modulus; + secp256k1_modinv64_signed62 g = *x; + int i; + int64_t zeta = -1; /* zeta = -(delta+1/2); delta starts at 1/2. */ + + /* Do 10 iterations of 59 divsteps each = 590 divsteps. This suffices for 256-bit inputs. */ + for (i = 0; i < 10; ++i) { + /* Compute transition matrix and new zeta after 59 divsteps. */ + secp256k1_modinv64_trans2x2 t; + zeta = secp256k1_modinv64_divsteps_59(zeta, f.v[0], g.v[0], &t); + /* Update d,e using that transition matrix. */ + secp256k1_modinv64_update_de_62(&d, &e, &t, modinfo); + /* Update f,g using that transition matrix. */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &modinfo->modulus, 1) < 0); /* g < modulus */ + + secp256k1_modinv64_update_fg_62(&f, &g, &t); + + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &modinfo->modulus, 1) < 0); /* g < modulus */ + } + + /* At this point sufficient iterations have been performed that g must have reached 0 + * and (if g was not originally 0) f must now equal +/- GCD of the initial f, g + * values i.e. +/- 1, and d now contains +/- the modular inverse. */ + + /* g == 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &SECP256K1_SIGNED62_ONE, 0) == 0); + /* |f| == 1, or (x == 0 and d == 0 and f == modulus) */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &SECP256K1_SIGNED62_ONE, -1) == 0 || + secp256k1_modinv64_mul_cmp_62(&f, 5, &SECP256K1_SIGNED62_ONE, 1) == 0 || + (secp256k1_modinv64_mul_cmp_62(x, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 && + secp256k1_modinv64_mul_cmp_62(&d, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 && + secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, 1) == 0)); + + /* Optionally negate d, normalize to [0,modulus), and return it. */ + secp256k1_modinv64_normalize_62(&d, f.v[4], modinfo); + *x = d; +} + +/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (variable time). */ +static void secp256k1_modinv64_var(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo) { + /* Start with d=0, e=1, f=modulus, g=x, eta=-1. */ + secp256k1_modinv64_signed62 d = {{0, 0, 0, 0, 0}}; + secp256k1_modinv64_signed62 e = {{1, 0, 0, 0, 0}}; + secp256k1_modinv64_signed62 f = modinfo->modulus; + secp256k1_modinv64_signed62 g = *x; +#ifdef VERIFY + int i = 0; +#endif + int j, len = 5; + int64_t eta = -1; /* eta = -delta; delta is initially 1 */ + int64_t cond, fn, gn; + + /* Do iterations of 62 divsteps each until g=0. */ + while (1) { + /* Compute transition matrix and new eta after 62 divsteps. */ + secp256k1_modinv64_trans2x2 t; + eta = secp256k1_modinv64_divsteps_62_var(eta, f.v[0], g.v[0], &t); + /* Update d,e using that transition matrix. */ + secp256k1_modinv64_update_de_62(&d, &e, &t, modinfo); + /* Update f,g using that transition matrix. */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ + + secp256k1_modinv64_update_fg_62_var(len, &f, &g, &t); + /* If the bottom limb of g is zero, there is a chance that g=0. */ + if (g.v[0] == 0) { + cond = 0; + /* Check if the other limbs are also 0. */ + for (j = 1; j < len; ++j) { + cond |= g.v[j]; + } + /* If so, we're done. */ + if (cond == 0) break; + } + + /* Determine if len>1 and limb (len-1) of both f and g is 0 or -1. */ + fn = f.v[len - 1]; + gn = g.v[len - 1]; + cond = ((int64_t)len - 2) >> 63; + cond |= fn ^ (fn >> 63); + cond |= gn ^ (gn >> 63); + /* If so, reduce length, propagating the sign of f and g's top limb into the one below. */ + if (cond == 0) { + f.v[len - 2] |= (uint64_t)fn << 62; + g.v[len - 2] |= (uint64_t)gn << 62; + --len; + } + + VERIFY_CHECK(++i < 12); /* We should never need more than 12*62 = 744 divsteps */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ + } + + /* At this point g is 0 and (if g was not originally 0) f must now equal +/- GCD of + * the initial f, g values i.e. +/- 1, and d now contains +/- the modular inverse. */ + + /* g == 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &SECP256K1_SIGNED62_ONE, 0) == 0); + /* |f| == 1, or (x == 0 and d == 0 and f == modulus) */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &SECP256K1_SIGNED62_ONE, -1) == 0 || + secp256k1_modinv64_mul_cmp_62(&f, len, &SECP256K1_SIGNED62_ONE, 1) == 0 || + (secp256k1_modinv64_mul_cmp_62(x, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 && + secp256k1_modinv64_mul_cmp_62(&d, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 && + secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 1) == 0)); + + /* Optionally negate d, normalize to [0,modulus), and return it. */ + secp256k1_modinv64_normalize_62(&d, f.v[len - 1], modinfo); + *x = d; +} + +/* Do up to 25 iterations of 62 posdivsteps (up to 1550 steps; more is extremely rare) each until f=1. + * In VERIFY mode use a lower number of iterations (744, close to the median 756), so failure actually occurs. */ +#ifdef VERIFY +#define JACOBI64_ITERATIONS 12 +#else +#define JACOBI64_ITERATIONS 25 +#endif + +/* Compute the Jacobi symbol of x modulo modinfo->modulus (variable time). gcd(x,modulus) must be 1. */ +static int secp256k1_jacobi64_maybe_var(const secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo) { + /* Start with f=modulus, g=x, eta=-1. */ + secp256k1_modinv64_signed62 f = modinfo->modulus; + secp256k1_modinv64_signed62 g = *x; + int j, len = 5; + int64_t eta = -1; /* eta = -delta; delta is initially 1 */ + int64_t cond, fn, gn; + int jac = 0; + int count; + + /* The input limbs must all be non-negative. */ + VERIFY_CHECK(g.v[0] >= 0 && g.v[1] >= 0 && g.v[2] >= 0 && g.v[3] >= 0 && g.v[4] >= 0); + + /* If x > 0, then if the loop below converges, it converges to f=g=gcd(x,modulus). Since we + * require that gcd(x,modulus)=1 and modulus>=3, x cannot be 0. Thus, we must reach f=1 (or + * time out). */ + VERIFY_CHECK((g.v[0] | g.v[1] | g.v[2] | g.v[3] | g.v[4]) != 0); + + for (count = 0; count < JACOBI64_ITERATIONS; ++count) { + /* Compute transition matrix and new eta after 62 posdivsteps. */ + secp256k1_modinv64_trans2x2 t; + eta = secp256k1_modinv64_posdivsteps_62_var(eta, f.v[0] | ((uint64_t)f.v[1] << 62), g.v[0] | ((uint64_t)g.v[1] << 62), &t, &jac); + /* Update f,g using that transition matrix. */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 0) > 0); /* f > 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, 0) > 0); /* g > 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ + + secp256k1_modinv64_update_fg_62_var(len, &f, &g, &t); + /* If the bottom limb of f is 1, there is a chance that f=1. */ + if (f.v[0] == 1) { + cond = 0; + /* Check if the other limbs are also 0. */ + for (j = 1; j < len; ++j) { + cond |= f.v[j]; + } + /* If so, we're done. When f=1, the Jacobi symbol (g | f)=1. */ + if (cond == 0) return 1 - 2*(jac & 1); + } + + /* Determine if len>1 and limb (len-1) of both f and g is 0. */ + fn = f.v[len - 1]; + gn = g.v[len - 1]; + cond = ((int64_t)len - 2) >> 63; + cond |= fn; + cond |= gn; + /* If so, reduce length. */ + if (cond == 0) --len; + + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 0) > 0); /* f > 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, 0) > 0); /* g > 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ + } + + /* The loop failed to converge to f=g after 1550 iterations. Return 0, indicating unknown result. */ + return 0; +} + +#endif /* SECP256K1_MODINV64_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ecdh/Makefile.am.include b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/Makefile.am.include index e3088b4697..7f7f95f1fd 100644 --- a/crypto/secp256k1/libsecp256k1/src/modules/ecdh/Makefile.am.include +++ b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/Makefile.am.include @@ -1,8 +1,4 @@ include_HEADERS += include/secp256k1_ecdh.h noinst_HEADERS += src/modules/ecdh/main_impl.h noinst_HEADERS += src/modules/ecdh/tests_impl.h -if USE_BENCHMARK -noinst_PROGRAMS += bench_ecdh -bench_ecdh_SOURCES = src/bench_ecdh.c -bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) -endif +noinst_HEADERS += src/modules/ecdh/bench_impl.h diff --git a/crypto/secp256k1/libsecp256k1/src/bench_ecdh.c b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/bench_impl.h similarity index 54% rename from crypto/secp256k1/libsecp256k1/src/bench_ecdh.c rename to crypto/secp256k1/libsecp256k1/src/modules/ecdh/bench_impl.h index cde5e2dbb4..c23aaa94d1 100644 --- a/crypto/secp256k1/libsecp256k1/src/bench_ecdh.c +++ b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/bench_impl.h @@ -1,25 +1,23 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#include +#ifndef SECP256K1_MODULE_ECDH_BENCH_H +#define SECP256K1_MODULE_ECDH_BENCH_H -#include "include/secp256k1.h" -#include "include/secp256k1_ecdh.h" -#include "util.h" -#include "bench.h" +#include "../../../include/secp256k1_ecdh.h" typedef struct { secp256k1_context *ctx; secp256k1_pubkey point; unsigned char scalar[32]; -} bench_ecdh_t; +} bench_ecdh_data; static void bench_ecdh_setup(void* arg) { int i; - bench_ecdh_t *data = (bench_ecdh_t*)arg; + bench_ecdh_data *data = (bench_ecdh_data*)arg; const unsigned char point[] = { 0x03, 0x54, 0x94, 0xc1, 0x5d, 0x32, 0x09, 0x97, 0x06, @@ -28,27 +26,32 @@ static void bench_ecdh_setup(void* arg) { 0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f }; - /* create a context with no capabilities */ - data->ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT); for (i = 0; i < 32; i++) { data->scalar[i] = i + 1; } CHECK(secp256k1_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1); } -static void bench_ecdh(void* arg) { +static void bench_ecdh(void* arg, int iters) { int i; unsigned char res[32]; - bench_ecdh_t *data = (bench_ecdh_t*)arg; + bench_ecdh_data *data = (bench_ecdh_data*)arg; - for (i = 0; i < 20000; i++) { - CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar) == 1); + for (i = 0; i < iters; i++) { + CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar, NULL, NULL) == 1); } } -int main(void) { - bench_ecdh_t data; +static void run_ecdh_bench(int iters, int argc, char** argv) { + bench_ecdh_data data; + int d = argc == 1; - run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, 20000); - return 0; + /* create a context with no capabilities */ + data.ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT); + + if (d || have_flag(argc, argv, "ecdh")) run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, iters); + + secp256k1_context_destroy(data.ctx); } + +#endif /* SECP256K1_MODULE_ECDH_BENCH_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ecdh/main_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/main_impl.h index 9e30fb73dd..842b5359e3 100644 --- a/crypto/secp256k1/libsecp256k1/src/modules/ecdh/main_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/main_impl.h @@ -1,54 +1,74 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_MODULE_ECDH_MAIN_ -#define _SECP256K1_MODULE_ECDH_MAIN_ +#ifndef SECP256K1_MODULE_ECDH_MAIN_H +#define SECP256K1_MODULE_ECDH_MAIN_H -#include "include/secp256k1_ecdh.h" -#include "ecmult_const_impl.h" +#include "../../../include/secp256k1_ecdh.h" +#include "../../ecmult_const_impl.h" -int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) { +static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { + unsigned char version = (y32[31] & 0x01) | 0x02; + secp256k1_sha256 sha; + (void)data; + + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, &version, 1); + secp256k1_sha256_write(&sha, x32, 32); + secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_clear(&sha); + + return 1; +} + +const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256 = ecdh_hash_function_sha256; +const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default = ecdh_hash_function_sha256; + +int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pubkey *point, const unsigned char *scalar, secp256k1_ecdh_hash_function hashfp, void *data) { int ret = 0; int overflow = 0; secp256k1_gej res; secp256k1_ge pt; secp256k1_scalar s; + unsigned char x[32]; + unsigned char y[32]; + VERIFY_CHECK(ctx != NULL); - ARG_CHECK(result != NULL); + ARG_CHECK(output != NULL); ARG_CHECK(point != NULL); ARG_CHECK(scalar != NULL); - secp256k1_pubkey_load(ctx, &pt, point); - secp256k1_scalar_set_b32(&s, scalar, &overflow); - if (overflow || secp256k1_scalar_is_zero(&s)) { - ret = 0; - } else { - unsigned char x[32]; - unsigned char y[1]; - secp256k1_sha256_t sha; - - secp256k1_ecmult_const(&res, &pt, &s); - secp256k1_ge_set_gej(&pt, &res); - /* Compute a hash of the point in compressed form - * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not - * expect its output to be secret and has a timing sidechannel. */ - secp256k1_fe_normalize(&pt.x); - secp256k1_fe_normalize(&pt.y); - secp256k1_fe_get_b32(x, &pt.x); - y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); - - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, y, sizeof(y)); - secp256k1_sha256_write(&sha, x, sizeof(x)); - secp256k1_sha256_finalize(&sha, result); - ret = 1; + if (hashfp == NULL) { + hashfp = secp256k1_ecdh_hash_function_default; } + secp256k1_pubkey_load(ctx, &pt, point); + secp256k1_scalar_set_b32(&s, scalar, &overflow); + + overflow |= secp256k1_scalar_is_zero(&s); + secp256k1_scalar_cmov(&s, &secp256k1_scalar_one, overflow); + + secp256k1_ecmult_const(&res, &pt, &s); + secp256k1_ge_set_gej(&pt, &res); + + /* Compute a hash of the point */ + secp256k1_fe_normalize(&pt.x); + secp256k1_fe_normalize(&pt.y); + secp256k1_fe_get_b32(x, &pt.x); + secp256k1_fe_get_b32(y, &pt.y); + + ret = hashfp(output, x, y, data); + + secp256k1_memclear(x, sizeof(x)); + secp256k1_memclear(y, sizeof(y)); secp256k1_scalar_clear(&s); - return ret; + secp256k1_ge_clear(&pt); + secp256k1_gej_clear(&res); + + return !!ret & !overflow; } -#endif +#endif /* SECP256K1_MODULE_ECDH_MAIN_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ecdh/tests_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/tests_impl.h index 85a5d0a9a6..3c3acdaf8c 100644 --- a/crypto/secp256k1/libsecp256k1/src/modules/ecdh/tests_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/tests_impl.h @@ -1,76 +1,87 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_MODULE_ECDH_TESTS_ -#define _SECP256K1_MODULE_ECDH_TESTS_ +#ifndef SECP256K1_MODULE_ECDH_TESTS_H +#define SECP256K1_MODULE_ECDH_TESTS_H -void test_ecdh_api(void) { - /* Setup context that just counts errors */ - secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); +static int ecdh_hash_function_test_fail(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) { + (void)output; + (void)x; + (void)y; + (void)data; + return 0; +} + +static int ecdh_hash_function_custom(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) { + (void)data; + /* Save x and y as uncompressed public key */ + output[0] = 0x04; + memcpy(output + 1, x, 32); + memcpy(output + 33, y, 32); + return 1; +} + +static void test_ecdh_api(void) { secp256k1_pubkey point; unsigned char res[32]; unsigned char s_one[32] = { 0 }; - int32_t ecount = 0; s_one[31] = 1; - secp256k1_context_set_error_callback(tctx, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(tctx, counting_illegal_callback_fn, &ecount); - CHECK(secp256k1_ec_pubkey_create(tctx, &point, s_one) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_one) == 1); /* Check all NULLs are detected */ - CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); - CHECK(ecount == 0); - CHECK(secp256k1_ecdh(tctx, NULL, &point, s_one) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdh(tctx, res, NULL, s_one) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdh(tctx, res, &point, NULL) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); - CHECK(ecount == 3); - - /* Cleanup */ - secp256k1_context_destroy(tctx); + CHECK(secp256k1_ecdh(CTX, res, &point, s_one, NULL, NULL) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, NULL, &point, s_one, NULL, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, res, NULL, s_one, NULL, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, res, &point, NULL, NULL, NULL)); + CHECK(secp256k1_ecdh(CTX, res, &point, s_one, NULL, NULL) == 1); } -void test_ecdh_generator_basepoint(void) { +static void test_ecdh_generator_basepoint(void) { unsigned char s_one[32] = { 0 }; secp256k1_pubkey point[2]; int i; s_one[31] = 1; /* Check against pubkey creation when the basepoint is the generator */ - for (i = 0; i < 100; ++i) { - secp256k1_sha256_t sha; + for (i = 0; i < 2 * COUNT; ++i) { + secp256k1_sha256 sha; unsigned char s_b32[32]; - unsigned char output_ecdh[32]; + unsigned char output_ecdh[65]; unsigned char output_ser[32]; - unsigned char point_ser[33]; + unsigned char point_ser[65]; size_t point_ser_len = sizeof(point_ser); secp256k1_scalar s; - random_scalar_order(&s); + testutil_random_scalar_order(&s); secp256k1_scalar_get_b32(s_b32, &s); - /* compute using ECDH function */ - CHECK(secp256k1_ec_pubkey_create(ctx, &point[0], s_one) == 1); - CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &point[0], s_one) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &point[1], s_b32) == 1); + + /* compute using ECDH function with custom hash function */ + CHECK(secp256k1_ecdh(CTX, output_ecdh, &point[0], s_b32, ecdh_hash_function_custom, NULL) == 1); /* compute "explicitly" */ - CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1); - CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); - CHECK(point_ser_len == sizeof(point_ser)); + CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_UNCOMPRESSED) == 1); + /* compare */ + CHECK(secp256k1_memcmp_var(output_ecdh, point_ser, 65) == 0); + + /* compute using ECDH function with default hash function */ + CHECK(secp256k1_ecdh(CTX, output_ecdh, &point[0], s_b32, NULL, NULL) == 1); + /* compute "explicitly" */ + CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); secp256k1_sha256_initialize(&sha); secp256k1_sha256_write(&sha, point_ser, point_ser_len); secp256k1_sha256_finalize(&sha, output_ser); /* compare */ - CHECK(memcmp(output_ecdh, output_ser, sizeof(output_ser)) == 0); + CHECK(secp256k1_memcmp_var(output_ecdh, output_ser, 32) == 0); } } -void test_bad_scalar(void) { +static void test_bad_scalar(void) { unsigned char s_zero[32] = { 0 }; unsigned char s_overflow[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -84,22 +95,58 @@ void test_bad_scalar(void) { secp256k1_pubkey point; /* Create random point */ - random_scalar_order(&rand); + testutil_random_scalar_order(&rand); secp256k1_scalar_get_b32(s_rand, &rand); - CHECK(secp256k1_ec_pubkey_create(ctx, &point, s_rand) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_rand) == 1); /* Try to multiply it by bad values */ - CHECK(secp256k1_ecdh(ctx, output, &point, s_zero) == 0); - CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 0); + CHECK(secp256k1_ecdh(CTX, output, &point, s_zero, NULL, NULL) == 0); + CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, NULL, NULL) == 0); /* ...and a good one */ s_overflow[31] -= 1; - CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 1); + CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, NULL, NULL) == 1); + + /* Hash function failure results in ecdh failure */ + CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, ecdh_hash_function_test_fail, NULL) == 0); } -void run_ecdh_tests(void) { +/** Test that ECDH(sG, 1/s) == ECDH((1/s)G, s) == ECDH(G, 1) for a few random s. */ +static void test_result_basepoint(void) { + secp256k1_pubkey point; + secp256k1_scalar rand; + unsigned char s[32]; + unsigned char s_inv[32]; + unsigned char out[32]; + unsigned char out_inv[32]; + unsigned char out_base[32]; + int i; + + unsigned char s_one[32] = { 0 }; + s_one[31] = 1; + CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_one) == 1); + CHECK(secp256k1_ecdh(CTX, out_base, &point, s_one, NULL, NULL) == 1); + + for (i = 0; i < 2 * COUNT; i++) { + testutil_random_scalar_order(&rand); + secp256k1_scalar_get_b32(s, &rand); + secp256k1_scalar_inverse(&rand, &rand); + secp256k1_scalar_get_b32(s_inv, &rand); + + CHECK(secp256k1_ec_pubkey_create(CTX, &point, s) == 1); + CHECK(secp256k1_ecdh(CTX, out, &point, s_inv, NULL, NULL) == 1); + CHECK(secp256k1_memcmp_var(out, out_base, 32) == 0); + + CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_inv) == 1); + CHECK(secp256k1_ecdh(CTX, out_inv, &point, s, NULL, NULL) == 1); + CHECK(secp256k1_memcmp_var(out_inv, out_base, 32) == 0); + } +} + +static void run_ecdh_tests(void) { test_ecdh_api(); test_ecdh_generator_basepoint(); test_bad_scalar(); + test_result_basepoint(); } -#endif +#endif /* SECP256K1_MODULE_ECDH_TESTS_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ellswift/Makefile.am.include b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/Makefile.am.include new file mode 100644 index 0000000000..8251231ea3 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/Makefile.am.include @@ -0,0 +1,5 @@ +include_HEADERS += include/secp256k1_ellswift.h +noinst_HEADERS += src/modules/ellswift/bench_impl.h +noinst_HEADERS += src/modules/ellswift/main_impl.h +noinst_HEADERS += src/modules/ellswift/tests_impl.h +noinst_HEADERS += src/modules/ellswift/tests_exhaustive_impl.h diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ellswift/bench_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/bench_impl.h new file mode 100644 index 0000000000..b16a3a3687 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/bench_impl.h @@ -0,0 +1,106 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_ELLSWIFT_BENCH_H +#define SECP256K1_MODULE_ELLSWIFT_BENCH_H + +#include "../../../include/secp256k1_ellswift.h" + +typedef struct { + secp256k1_context *ctx; + secp256k1_pubkey point[256]; + unsigned char rnd64[64]; +} bench_ellswift_data; + +static void bench_ellswift_setup(void *arg) { + int i; + bench_ellswift_data *data = (bench_ellswift_data*)arg; + static const unsigned char init[64] = { + 0x78, 0x1f, 0xb7, 0xd4, 0x67, 0x7f, 0x08, 0x68, + 0xdb, 0xe3, 0x1d, 0x7f, 0x1b, 0xb0, 0xf6, 0x9e, + 0x0a, 0x64, 0xca, 0x32, 0x9e, 0xc6, 0x20, 0x79, + 0x03, 0xf3, 0xd0, 0x46, 0x7a, 0x0f, 0xd2, 0x21, + 0xb0, 0x2c, 0x46, 0xd8, 0xba, 0xca, 0x26, 0x4f, + 0x8f, 0x8c, 0xd4, 0xdd, 0x2d, 0x04, 0xbe, 0x30, + 0x48, 0x51, 0x1e, 0xd4, 0x16, 0xfd, 0x42, 0x85, + 0x62, 0xc9, 0x02, 0xf9, 0x89, 0x84, 0xff, 0xdc + }; + memcpy(data->rnd64, init, 64); + for (i = 0; i < 256; ++i) { + int j; + CHECK(secp256k1_ellswift_decode(data->ctx, &data->point[i], data->rnd64)); + for (j = 0; j < 64; ++j) { + data->rnd64[j] += 1; + } + } + CHECK(secp256k1_ellswift_encode(data->ctx, data->rnd64, &data->point[255], init + 16)); +} + +static void bench_ellswift_encode(void *arg, int iters) { + int i; + bench_ellswift_data *data = (bench_ellswift_data*)arg; + + for (i = 0; i < iters; i++) { + CHECK(secp256k1_ellswift_encode(data->ctx, data->rnd64, &data->point[i & 255], data->rnd64 + 16)); + } +} + +static void bench_ellswift_create(void *arg, int iters) { + int i; + bench_ellswift_data *data = (bench_ellswift_data*)arg; + + for (i = 0; i < iters; i++) { + unsigned char buf[64]; + CHECK(secp256k1_ellswift_create(data->ctx, buf, data->rnd64, data->rnd64 + 32)); + memcpy(data->rnd64, buf, 64); + } +} + +static void bench_ellswift_decode(void *arg, int iters) { + int i; + secp256k1_pubkey out; + size_t len; + bench_ellswift_data *data = (bench_ellswift_data*)arg; + + for (i = 0; i < iters; i++) { + CHECK(secp256k1_ellswift_decode(data->ctx, &out, data->rnd64) == 1); + len = 33; + CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->rnd64 + (i % 32), &len, &out, SECP256K1_EC_COMPRESSED)); + } +} + +static void bench_ellswift_xdh(void *arg, int iters) { + int i; + bench_ellswift_data *data = (bench_ellswift_data*)arg; + + for (i = 0; i < iters; i++) { + int party = i & 1; + CHECK(secp256k1_ellswift_xdh(data->ctx, + data->rnd64 + (i % 33), + data->rnd64, + data->rnd64, + data->rnd64 + ((i + 16) % 33), + party, + secp256k1_ellswift_xdh_hash_function_bip324, + NULL) == 1); + } +} + +void run_ellswift_bench(int iters, int argc, char **argv) { + bench_ellswift_data data; + int d = argc == 1; + + /* create a context with signing capabilities */ + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + + if (d || have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "encode") || have_flag(argc, argv, "ellswift_encode")) run_benchmark("ellswift_encode", bench_ellswift_encode, bench_ellswift_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "decode") || have_flag(argc, argv, "ellswift_decode")) run_benchmark("ellswift_decode", bench_ellswift_decode, bench_ellswift_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ellswift_keygen")) run_benchmark("ellswift_keygen", bench_ellswift_create, bench_ellswift_setup, NULL, &data, 10, iters); + if (d || have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "ecdh") || have_flag(argc, argv, "ellswift_ecdh")) run_benchmark("ellswift_ecdh", bench_ellswift_xdh, bench_ellswift_setup, NULL, &data, 10, iters); + + secp256k1_context_destroy(data.ctx); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ellswift/main_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/main_impl.h new file mode 100644 index 0000000000..745a969139 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/main_impl.h @@ -0,0 +1,592 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_ELLSWIFT_MAIN_H +#define SECP256K1_MODULE_ELLSWIFT_MAIN_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_ellswift.h" +#include "../../eckey.h" +#include "../../hash.h" + +/** c1 = (sqrt(-3)-1)/2 */ +static const secp256k1_fe secp256k1_ellswift_c1 = SECP256K1_FE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa40); +/** c2 = (-sqrt(-3)-1)/2 = -(c1+1) */ +static const secp256k1_fe secp256k1_ellswift_c2 = SECP256K1_FE_CONST(0x7ae96a2b, 0x657c0710, 0x6e64479e, 0xac3434e9, 0x9cf04975, 0x12f58995, 0xc1396c28, 0x719501ee); +/** c3 = (-sqrt(-3)+1)/2 = -c1 = c2+1 */ +static const secp256k1_fe secp256k1_ellswift_c3 = SECP256K1_FE_CONST(0x7ae96a2b, 0x657c0710, 0x6e64479e, 0xac3434e9, 0x9cf04975, 0x12f58995, 0xc1396c28, 0x719501ef); +/** c4 = (sqrt(-3)+1)/2 = -c2 = c1+1 */ +static const secp256k1_fe secp256k1_ellswift_c4 = SECP256K1_FE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa41); + +/** Decode ElligatorSwift encoding (u, t) to a fraction xn/xd representing a curve X coordinate. */ +static void secp256k1_ellswift_xswiftec_frac_var(secp256k1_fe *xn, secp256k1_fe *xd, const secp256k1_fe *u, const secp256k1_fe *t) { + /* The implemented algorithm is the following (all operations in GF(p)): + * + * - Let c0 = sqrt(-3) = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852. + * - If u = 0, set u = 1. + * - If t = 0, set t = 1. + * - If u^3+7+t^2 = 0, set t = 2*t. + * - Let X = (u^3+7-t^2)/(2*t). + * - Let Y = (X+t)/(c0*u). + * - If x3 = u+4*Y^2 is a valid x coordinate, return it. + * - If x2 = (-X/Y-u)/2 is a valid x coordinate, return it. + * - Return x1 = (X/Y-u)/2 (which is now guaranteed to be a valid x coordinate). + * + * Introducing s=t^2, g=u^3+7, and simplifying x1=-(x2+u) we get: + * + * - Let c0 = ... + * - If u = 0, set u = 1. + * - If t = 0, set t = 1. + * - Let s = t^2 + * - Let g = u^3+7 + * - If g+s = 0, set t = 2*t, s = 4*s + * - Let X = (g-s)/(2*t). + * - Let Y = (X+t)/(c0*u) = (g+s)/(2*c0*t*u). + * - If x3 = u+4*Y^2 is a valid x coordinate, return it. + * - If x2 = (-X/Y-u)/2 is a valid x coordinate, return it. + * - Return x1 = -(x2+u). + * + * Now substitute Y^2 = -(g+s)^2/(12*s*u^2) and X/Y = c0*u*(g-s)/(g+s). This + * means X and Y do not need to be evaluated explicitly anymore. + * + * - ... + * - If g+s = 0, set s = 4*s. + * - If x3 = u-(g+s)^2/(3*s*u^2) is a valid x coordinate, return it. + * - If x2 = (-c0*u*(g-s)/(g+s)-u)/2 is a valid x coordinate, return it. + * - Return x1 = -(x2+u). + * + * Simplifying x2 using 2 additional constants: + * + * - Let c1 = (c0-1)/2 = 0x851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40. + * - Let c2 = (-c0-1)/2 = 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee. + * - ... + * - If x2 = u*(c1*s+c2*g)/(g+s) is a valid x coordinate, return it. + * - ... + * + * Writing x3 as a fraction: + * + * - ... + * - If x3 = (3*s*u^3-(g+s)^2)/(3*s*u^2) ... + * - ... + + * Overall, we get: + * + * - Let c1 = 0x851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40. + * - Let c2 = 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee. + * - If u = 0, set u = 1. + * - If t = 0, set s = 1, else set s = t^2. + * - Let g = u^3+7. + * - If g+s = 0, set s = 4*s. + * - If x3 = (3*s*u^3-(g+s)^2)/(3*s*u^2) is a valid x coordinate, return it. + * - If x2 = u*(c1*s+c2*g)/(g+s) is a valid x coordinate, return it. + * - Return x1 = -(x2+u). + */ + secp256k1_fe u1, s, g, p, d, n, l; + u1 = *u; + if (EXPECT(secp256k1_fe_normalizes_to_zero_var(&u1), 0)) u1 = secp256k1_fe_one; + secp256k1_fe_sqr(&s, t); + if (EXPECT(secp256k1_fe_normalizes_to_zero_var(t), 0)) s = secp256k1_fe_one; + secp256k1_fe_sqr(&l, &u1); /* l = u^2 */ + secp256k1_fe_mul(&g, &l, &u1); /* g = u^3 */ + secp256k1_fe_add_int(&g, SECP256K1_B); /* g = u^3 + 7 */ + p = g; /* p = g */ + secp256k1_fe_add(&p, &s); /* p = g+s */ + if (EXPECT(secp256k1_fe_normalizes_to_zero_var(&p), 0)) { + secp256k1_fe_mul_int(&s, 4); + /* Recompute p = g+s */ + p = g; /* p = g */ + secp256k1_fe_add(&p, &s); /* p = g+s */ + } + secp256k1_fe_mul(&d, &s, &l); /* d = s*u^2 */ + secp256k1_fe_mul_int(&d, 3); /* d = 3*s*u^2 */ + secp256k1_fe_sqr(&l, &p); /* l = (g+s)^2 */ + secp256k1_fe_negate(&l, &l, 1); /* l = -(g+s)^2 */ + secp256k1_fe_mul(&n, &d, &u1); /* n = 3*s*u^3 */ + secp256k1_fe_add(&n, &l); /* n = 3*s*u^3-(g+s)^2 */ + if (secp256k1_ge_x_frac_on_curve_var(&n, &d)) { + /* Return x3 = n/d = (3*s*u^3-(g+s)^2)/(3*s*u^2) */ + *xn = n; + *xd = d; + return; + } + *xd = p; + secp256k1_fe_mul(&l, &secp256k1_ellswift_c1, &s); /* l = c1*s */ + secp256k1_fe_mul(&n, &secp256k1_ellswift_c2, &g); /* n = c2*g */ + secp256k1_fe_add(&n, &l); /* n = c1*s+c2*g */ + secp256k1_fe_mul(&n, &n, &u1); /* n = u*(c1*s+c2*g) */ + /* Possible optimization: in the invocation below, p^2 = (g+s)^2 is computed, + * which we already have computed above. This could be deduplicated. */ + if (secp256k1_ge_x_frac_on_curve_var(&n, &p)) { + /* Return x2 = n/p = u*(c1*s+c2*g)/(g+s) */ + *xn = n; + return; + } + secp256k1_fe_mul(&l, &p, &u1); /* l = u*(g+s) */ + secp256k1_fe_add(&n, &l); /* n = u*(c1*s+c2*g)+u*(g+s) */ + secp256k1_fe_negate(xn, &n, 2); /* n = -u*(c1*s+c2*g)-u*(g+s) */ + + VERIFY_CHECK(secp256k1_ge_x_frac_on_curve_var(xn, &p)); + /* Return x3 = n/p = -(u*(c1*s+c2*g)/(g+s)+u) */ +} + +/** Decode ElligatorSwift encoding (u, t) to X coordinate. */ +static void secp256k1_ellswift_xswiftec_var(secp256k1_fe *x, const secp256k1_fe *u, const secp256k1_fe *t) { + secp256k1_fe xn, xd; + secp256k1_ellswift_xswiftec_frac_var(&xn, &xd, u, t); + secp256k1_fe_inv_var(&xd, &xd); + secp256k1_fe_mul(x, &xn, &xd); +} + +/** Decode ElligatorSwift encoding (u, t) to point P. */ +static void secp256k1_ellswift_swiftec_var(secp256k1_ge *p, const secp256k1_fe *u, const secp256k1_fe *t) { + secp256k1_fe x; + secp256k1_ellswift_xswiftec_var(&x, u, t); + secp256k1_ge_set_xo_var(p, &x, secp256k1_fe_is_odd(t)); +} + +/* Try to complete an ElligatorSwift encoding (u, t) for X coordinate x, given u and x. + * + * There may be up to 8 distinct t values such that (u, t) decodes back to x, but also + * fewer, or none at all. Each such partial inverse can be accessed individually using a + * distinct input argument c (in range 0-7), and some or all of these may return failure. + * The following guarantees exist: + * - Given (x, u), no two distinct c values give the same successful result t. + * - Every successful result maps back to x through secp256k1_ellswift_xswiftec_var. + * - Given (x, u), all t values that map back to x can be reached by combining the + * successful results from this function over all c values, with the exception of: + * - this function cannot be called with u=0 + * - no result with t=0 will be returned + * - no result for which u^3 + t^2 + 7 = 0 will be returned. + * + * The rather unusual encoding of bits in c (a large "if" based on the middle bit, and then + * using the low and high bits to pick signs of square roots) is to match the paper's + * encoding more closely: c=0 through c=3 match branches 1..4 in the paper, while c=4 through + * c=7 are copies of those with an additional negation of sqrt(w). + */ +static int secp256k1_ellswift_xswiftec_inv_var(secp256k1_fe *t, const secp256k1_fe *x_in, const secp256k1_fe *u_in, int c) { + /* The implemented algorithm is this (all arithmetic, except involving c, is mod p): + * + * - If (c & 2) = 0: + * - If (-x-u) is a valid X coordinate, fail. + * - Let s=-(u^3+7)/(u^2+u*x+x^2). + * - If s is not square, fail. + * - Let v=x. + * - If (c & 2) = 2: + * - Let s=x-u. + * - If s is not square, fail. + * - Let r=sqrt(-s*(4*(u^3+7)+3*u^2*s)); fail if it doesn't exist. + * - If (c & 1) = 1 and r = 0, fail. + * - If s=0, fail. + * - Let v=(r/s-u)/2. + * - Let w=sqrt(s). + * - If (c & 5) = 0: return -w*(c3*u + v). + * - If (c & 5) = 1: return w*(c4*u + v). + * - If (c & 5) = 4: return w*(c3*u + v). + * - If (c & 5) = 5: return -w*(c4*u + v). + */ + secp256k1_fe x = *x_in, u = *u_in, g, v, s, m, r, q; + int ret; + + secp256k1_fe_normalize_weak(&x); + secp256k1_fe_normalize_weak(&u); + + VERIFY_CHECK(c >= 0 && c < 8); + VERIFY_CHECK(secp256k1_ge_x_on_curve_var(&x)); + + if (!(c & 2)) { + /* c is in {0, 1, 4, 5}. In this case we look for an inverse under the x1 (if c=0 or + * c=4) formula, or x2 (if c=1 or c=5) formula. */ + + /* If -u-x is a valid X coordinate, fail. This would yield an encoding that roundtrips + * back under the x3 formula instead (which has priority over x1 and x2, so the decoding + * would not match x). */ + m = x; /* m = x */ + secp256k1_fe_add(&m, &u); /* m = u+x */ + secp256k1_fe_negate(&m, &m, 2); /* m = -u-x */ + /* Test if (-u-x) is a valid X coordinate. If so, fail. */ + if (secp256k1_ge_x_on_curve_var(&m)) return 0; + + /* Let s = -(u^3 + 7)/(u^2 + u*x + x^2) [first part] */ + secp256k1_fe_sqr(&s, &m); /* s = (u+x)^2 */ + secp256k1_fe_negate(&s, &s, 1); /* s = -(u+x)^2 */ + secp256k1_fe_mul(&m, &u, &x); /* m = u*x */ + secp256k1_fe_add(&s, &m); /* s = -(u^2 + u*x + x^2) */ + + /* Note that at this point, s = 0 is impossible. If it were the case: + * s = -(u^2 + u*x + x^2) = 0 + * => u^2 + u*x + x^2 = 0 + * => (u + 2*x) * (u^2 + u*x + x^2) = 0 + * => 2*x^3 + 3*x^2*u + 3*x*u^2 + u^3 = 0 + * => (x + u)^3 + x^3 = 0 + * => x^3 = -(x + u)^3 + * => x^3 + B = (-u - x)^3 + B + * + * However, we know x^3 + B is square (because x is on the curve) and + * that (-u-x)^3 + B is not square (the secp256k1_ge_x_on_curve_var(&m) + * test above would have failed). This is a contradiction, and thus the + * assumption s=0 is false. */ + VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(&s)); + + /* If s is not square, fail. We have not fully computed s yet, but s is square iff + * -(u^3+7)*(u^2+u*x+x^2) is square (because a/b is square iff a*b is square and b is + * nonzero). */ + secp256k1_fe_sqr(&g, &u); /* g = u^2 */ + secp256k1_fe_mul(&g, &g, &u); /* g = u^3 */ + secp256k1_fe_add_int(&g, SECP256K1_B); /* g = u^3+7 */ + secp256k1_fe_mul(&m, &s, &g); /* m = -(u^3 + 7)*(u^2 + u*x + x^2) */ + if (!secp256k1_fe_is_square_var(&m)) return 0; + + /* Let s = -(u^3 + 7)/(u^2 + u*x + x^2) [second part] */ + secp256k1_fe_inv_var(&s, &s); /* s = -1/(u^2 + u*x + x^2) [no div by 0] */ + secp256k1_fe_mul(&s, &s, &g); /* s = -(u^3 + 7)/(u^2 + u*x + x^2) */ + + /* Let v = x. */ + v = x; + } else { + /* c is in {2, 3, 6, 7}. In this case we look for an inverse under the x3 formula. */ + + /* Let s = x-u. */ + secp256k1_fe_negate(&m, &u, 1); /* m = -u */ + s = m; /* s = -u */ + secp256k1_fe_add(&s, &x); /* s = x-u */ + + /* If s is not square, fail. */ + if (!secp256k1_fe_is_square_var(&s)) return 0; + + /* Let r = sqrt(-s*(4*(u^3+7)+3*u^2*s)); fail if it doesn't exist. */ + secp256k1_fe_sqr(&g, &u); /* g = u^2 */ + secp256k1_fe_mul(&q, &s, &g); /* q = s*u^2 */ + secp256k1_fe_mul_int(&q, 3); /* q = 3*s*u^2 */ + secp256k1_fe_mul(&g, &g, &u); /* g = u^3 */ + secp256k1_fe_mul_int(&g, 4); /* g = 4*u^3 */ + secp256k1_fe_add_int(&g, 4 * SECP256K1_B); /* g = 4*(u^3+7) */ + secp256k1_fe_add(&q, &g); /* q = 4*(u^3+7)+3*s*u^2 */ + secp256k1_fe_mul(&q, &q, &s); /* q = s*(4*(u^3+7)+3*u^2*s) */ + secp256k1_fe_negate(&q, &q, 1); /* q = -s*(4*(u^3+7)+3*u^2*s) */ + if (!secp256k1_fe_is_square_var(&q)) return 0; + ret = secp256k1_fe_sqrt(&r, &q); /* r = sqrt(-s*(4*(u^3+7)+3*u^2*s)) */ +#ifdef VERIFY + VERIFY_CHECK(ret); +#else + (void)ret; +#endif + + /* If (c & 1) = 1 and r = 0, fail. */ + if (EXPECT((c & 1) && secp256k1_fe_normalizes_to_zero_var(&r), 0)) return 0; + + /* If s = 0, fail. */ + if (EXPECT(secp256k1_fe_normalizes_to_zero_var(&s), 0)) return 0; + + /* Let v = (r/s-u)/2. */ + secp256k1_fe_inv_var(&v, &s); /* v = 1/s [no div by 0] */ + secp256k1_fe_mul(&v, &v, &r); /* v = r/s */ + secp256k1_fe_add(&v, &m); /* v = r/s-u */ + secp256k1_fe_half(&v); /* v = (r/s-u)/2 */ + } + + /* Let w = sqrt(s). */ + ret = secp256k1_fe_sqrt(&m, &s); /* m = sqrt(s) = w */ + VERIFY_CHECK(ret); + + /* Return logic. */ + if ((c & 5) == 0 || (c & 5) == 5) { + secp256k1_fe_negate(&m, &m, 1); /* m = -w */ + } + /* Now m = {-w if c&5=0 or c&5=5; w otherwise}. */ + secp256k1_fe_mul(&u, &u, c&1 ? &secp256k1_ellswift_c4 : &secp256k1_ellswift_c3); + /* u = {c4 if c&1=1; c3 otherwise}*u */ + secp256k1_fe_add(&u, &v); /* u = {c4 if c&1=1; c3 otherwise}*u + v */ + secp256k1_fe_mul(t, &m, &u); + return 1; +} + +/** Use SHA256 as a PRNG, returning SHA256(hasher || cnt). + * + * hasher is a SHA256 object to which an incrementing 4-byte counter is written to generate randomness. + * Writing 13 bytes (4 bytes for counter, plus 9 bytes for the SHA256 padding) cannot cross a + * 64-byte block size boundary (to make sure it only triggers a single SHA256 compression). */ +static void secp256k1_ellswift_prng(unsigned char* out32, const secp256k1_sha256 *hasher, uint32_t cnt) { + secp256k1_sha256 hash = *hasher; + unsigned char buf4[4]; +#ifdef VERIFY + size_t blocks = hash.bytes >> 6; +#endif + buf4[0] = cnt; + buf4[1] = cnt >> 8; + buf4[2] = cnt >> 16; + buf4[3] = cnt >> 24; + secp256k1_sha256_write(&hash, buf4, 4); + secp256k1_sha256_finalize(&hash, out32); + + /* Writing and finalizing together should trigger exactly one SHA256 compression. */ + VERIFY_CHECK(((hash.bytes) >> 6) == (blocks + 1)); +} + +/** Find an ElligatorSwift encoding (u, t) for X coordinate x, and random Y coordinate. + * + * u32 is the 32-byte big endian encoding of u; t is the output field element t that still + * needs encoding. + * + * hasher is a hasher in the secp256k1_ellswift_prng sense, with the same restrictions. */ +static void secp256k1_ellswift_xelligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_fe *x, const secp256k1_sha256 *hasher) { + /* Pool of 3-bit branch values. */ + unsigned char branch_hash[32]; + /* Number of 3-bit values in branch_hash left. */ + int branches_left = 0; + /* Field elements u and branch values are extracted from RNG based on hasher for consecutive + * values of cnt. cnt==0 is first used to populate a pool of 64 4-bit branch values. The 64 + * cnt values that follow are used to generate field elements u. cnt==65 (and multiples + * thereof) are used to repopulate the pool and start over, if that were ever necessary. + * On average, 4 iterations are needed. */ + uint32_t cnt = 0; + while (1) { + int branch; + secp256k1_fe u; + /* If the pool of branch values is empty, populate it. */ + if (branches_left == 0) { + secp256k1_ellswift_prng(branch_hash, hasher, cnt++); + branches_left = 64; + } + /* Take a 3-bit branch value from the branch pool (top bit is discarded). */ + --branches_left; + branch = (branch_hash[branches_left >> 1] >> ((branches_left & 1) << 2)) & 7; + /* Compute a new u value by hashing. */ + secp256k1_ellswift_prng(u32, hasher, cnt++); + /* overflow is not a problem (we prefer uniform u32 over uniform u). */ + secp256k1_fe_set_b32_mod(&u, u32); + /* Since u is the output of a hash, it should practically never be 0. We could apply the + * u=0 to u=1 correction here too to deal with that case still, but it's such a low + * probability event that we do not bother. */ + VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(&u)); + + /* Find a remainder t, and return it if found. */ + if (EXPECT(secp256k1_ellswift_xswiftec_inv_var(t, x, &u, branch), 0)) break; + } +} + +/** Find an ElligatorSwift encoding (u, t) for point P. + * + * This is similar secp256k1_ellswift_xelligatorswift_var, except it takes a full group element p + * as input, and returns an encoding that matches the provided Y coordinate rather than a random + * one. + */ +static void secp256k1_ellswift_elligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_ge *p, const secp256k1_sha256 *hasher) { + secp256k1_ellswift_xelligatorswift_var(u32, t, &p->x, hasher); + secp256k1_fe_normalize_var(t); + if (secp256k1_fe_is_odd(t) != secp256k1_fe_is_odd(&p->y)) { + secp256k1_fe_negate(t, t, 1); + secp256k1_fe_normalize_var(t); + } +} + +/** Set hash state to the BIP340 tagged hash midstate for "secp256k1_ellswift_encode". */ +static void secp256k1_ellswift_sha256_init_encode(secp256k1_sha256* hash) { + secp256k1_sha256_initialize(hash); + hash->s[0] = 0xd1a6524bul; + hash->s[1] = 0x028594b3ul; + hash->s[2] = 0x96e42f4eul; + hash->s[3] = 0x1037a177ul; + hash->s[4] = 0x1b8fcb8bul; + hash->s[5] = 0x56023885ul; + hash->s[6] = 0x2560ede1ul; + hash->s[7] = 0xd626b715ul; + + hash->bytes = 64; +} + +int secp256k1_ellswift_encode(const secp256k1_context *ctx, unsigned char *ell64, const secp256k1_pubkey *pubkey, const unsigned char *rnd32) { + secp256k1_ge p; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(ell64 != NULL); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(rnd32 != NULL); + + if (secp256k1_pubkey_load(ctx, &p, pubkey)) { + secp256k1_fe t; + unsigned char p64[64] = {0}; + size_t ser_size; + int ser_ret; + secp256k1_sha256 hash; + + /* Set up hasher state; the used RNG is H(pubkey || "\x00"*31 || rnd32 || cnt++), using + * BIP340 tagged hash with tag "secp256k1_ellswift_encode". */ + secp256k1_ellswift_sha256_init_encode(&hash); + ser_ret = secp256k1_eckey_pubkey_serialize(&p, p64, &ser_size, 1); +#ifdef VERIFY + VERIFY_CHECK(ser_ret && ser_size == 33); +#else + (void)ser_ret; +#endif + secp256k1_sha256_write(&hash, p64, sizeof(p64)); + secp256k1_sha256_write(&hash, rnd32, 32); + + /* Compute ElligatorSwift encoding and construct output. */ + secp256k1_ellswift_elligatorswift_var(ell64, &t, &p, &hash); /* puts u in ell64[0..32] */ + secp256k1_fe_get_b32(ell64 + 32, &t); /* puts t in ell64[32..64] */ + return 1; + } + /* Only reached in case the provided pubkey is invalid. */ + memset(ell64, 0, 64); + return 0; +} + +/** Set hash state to the BIP340 tagged hash midstate for "secp256k1_ellswift_create". */ +static void secp256k1_ellswift_sha256_init_create(secp256k1_sha256* hash) { + secp256k1_sha256_initialize(hash); + hash->s[0] = 0xd29e1bf5ul; + hash->s[1] = 0xf7025f42ul; + hash->s[2] = 0x9b024773ul; + hash->s[3] = 0x094cb7d5ul; + hash->s[4] = 0xe59ed789ul; + hash->s[5] = 0x03bc9786ul; + hash->s[6] = 0x68335b35ul; + hash->s[7] = 0x4e363b53ul; + + hash->bytes = 64; +} + +int secp256k1_ellswift_create(const secp256k1_context *ctx, unsigned char *ell64, const unsigned char *seckey32, const unsigned char *auxrnd32) { + secp256k1_ge p; + secp256k1_fe t; + secp256k1_sha256 hash; + secp256k1_scalar seckey_scalar; + int ret; + static const unsigned char zero32[32] = {0}; + + /* Sanity check inputs. */ + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(ell64 != NULL); + memset(ell64, 0, 64); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(seckey32 != NULL); + + /* Compute (affine) public key */ + ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &seckey_scalar, &p, seckey32); + secp256k1_declassify(ctx, &p, sizeof(p)); /* not constant time in produced pubkey */ + secp256k1_fe_normalize_var(&p.x); + secp256k1_fe_normalize_var(&p.y); + + /* Set up hasher state. The used RNG is H(privkey || "\x00"*32 [|| auxrnd32] || cnt++), + * using BIP340 tagged hash with tag "secp256k1_ellswift_create". */ + secp256k1_ellswift_sha256_init_create(&hash); + secp256k1_sha256_write(&hash, seckey32, 32); + secp256k1_sha256_write(&hash, zero32, sizeof(zero32)); + secp256k1_declassify(ctx, &hash, sizeof(hash)); /* private key is hashed now */ + if (auxrnd32) secp256k1_sha256_write(&hash, auxrnd32, 32); + + /* Compute ElligatorSwift encoding and construct output. */ + secp256k1_ellswift_elligatorswift_var(ell64, &t, &p, &hash); /* puts u in ell64[0..32] */ + secp256k1_fe_get_b32(ell64 + 32, &t); /* puts t in ell64[32..64] */ + + secp256k1_memczero(ell64, 64, !ret); + secp256k1_scalar_clear(&seckey_scalar); + + return ret; +} + +int secp256k1_ellswift_decode(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *ell64) { + secp256k1_fe u, t; + secp256k1_ge p; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(ell64 != NULL); + + secp256k1_fe_set_b32_mod(&u, ell64); + secp256k1_fe_set_b32_mod(&t, ell64 + 32); + secp256k1_fe_normalize_var(&t); + secp256k1_ellswift_swiftec_var(&p, &u, &t); + secp256k1_pubkey_save(pubkey, &p); + return 1; +} + +static int ellswift_xdh_hash_function_prefix(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { + secp256k1_sha256 sha; + + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, data, 64); + secp256k1_sha256_write(&sha, ell_a64, 64); + secp256k1_sha256_write(&sha, ell_b64, 64); + secp256k1_sha256_write(&sha, x32, 32); + secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_clear(&sha); + + return 1; +} + +/** Set hash state to the BIP340 tagged hash midstate for "bip324_ellswift_xonly_ecdh". */ +static void secp256k1_ellswift_sha256_init_bip324(secp256k1_sha256* hash) { + secp256k1_sha256_initialize(hash); + hash->s[0] = 0x8c12d730ul; + hash->s[1] = 0x827bd392ul; + hash->s[2] = 0x9e4fb2eeul; + hash->s[3] = 0x207b373eul; + hash->s[4] = 0x2292bd7aul; + hash->s[5] = 0xaa5441bcul; + hash->s[6] = 0x15c3779ful; + hash->s[7] = 0xcfb52549ul; + + hash->bytes = 64; +} + +static int ellswift_xdh_hash_function_bip324(unsigned char* output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { + secp256k1_sha256 sha; + + (void)data; + + secp256k1_ellswift_sha256_init_bip324(&sha); + secp256k1_sha256_write(&sha, ell_a64, 64); + secp256k1_sha256_write(&sha, ell_b64, 64); + secp256k1_sha256_write(&sha, x32, 32); + secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_clear(&sha); + + return 1; +} + +const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix = ellswift_xdh_hash_function_prefix; +const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324 = ellswift_xdh_hash_function_bip324; + +int secp256k1_ellswift_xdh(const secp256k1_context *ctx, unsigned char *output, const unsigned char *ell_a64, const unsigned char *ell_b64, const unsigned char *seckey32, int party, secp256k1_ellswift_xdh_hash_function hashfp, void *data) { + int ret = 0; + int overflow; + secp256k1_scalar s; + secp256k1_fe xn, xd, px, u, t; + unsigned char sx[32]; + const unsigned char* theirs64; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output != NULL); + ARG_CHECK(ell_a64 != NULL); + ARG_CHECK(ell_b64 != NULL); + ARG_CHECK(seckey32 != NULL); + ARG_CHECK(hashfp != NULL); + + /* Load remote public key (as fraction). */ + theirs64 = party ? ell_a64 : ell_b64; + secp256k1_fe_set_b32_mod(&u, theirs64); + secp256k1_fe_set_b32_mod(&t, theirs64 + 32); + secp256k1_ellswift_xswiftec_frac_var(&xn, &xd, &u, &t); + + /* Load private key (using one if invalid). */ + secp256k1_scalar_set_b32(&s, seckey32, &overflow); + overflow = secp256k1_scalar_is_zero(&s); + secp256k1_scalar_cmov(&s, &secp256k1_scalar_one, overflow); + + /* Compute shared X coordinate. */ + secp256k1_ecmult_const_xonly(&px, &xn, &xd, &s, 1); + secp256k1_fe_normalize(&px); + secp256k1_fe_get_b32(sx, &px); + + /* Invoke hasher */ + ret = hashfp(output, sx, ell_a64, ell_b64, data); + + secp256k1_memclear(sx, sizeof(sx)); + secp256k1_fe_clear(&px); + secp256k1_scalar_clear(&s); + + return !!ret & !overflow; +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ellswift/tests_exhaustive_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/tests_exhaustive_impl.h new file mode 100644 index 0000000000..839c24aee4 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/tests_exhaustive_impl.h @@ -0,0 +1,39 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_ELLSWIFT_TESTS_EXHAUSTIVE_H +#define SECP256K1_MODULE_ELLSWIFT_TESTS_EXHAUSTIVE_H + +#include "../../../include/secp256k1_ellswift.h" +#include "main_impl.h" + +static void test_exhaustive_ellswift(const secp256k1_context *ctx, const secp256k1_ge *group) { + int i; + + /* Note that SwiftEC/ElligatorSwift are inherently curve operations, not + * group operations, and this test only checks the curve points which are in + * a tiny subgroup. In that sense it can't be really seen as exhaustive as + * it doesn't (and for computational reasons obviously cannot) test the + * entire domain ellswift operates under. */ + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { + secp256k1_scalar scalar_i; + unsigned char sec32[32]; + unsigned char ell64[64]; + secp256k1_pubkey pub_decoded; + secp256k1_ge ge_decoded; + + /* Construct ellswift pubkey from exhaustive loop scalar i. */ + secp256k1_scalar_set_int(&scalar_i, i); + secp256k1_scalar_get_b32(sec32, &scalar_i); + CHECK(secp256k1_ellswift_create(ctx, ell64, sec32, NULL)); + + /* Decode ellswift pubkey and check that it matches the precomputed group element. */ + secp256k1_ellswift_decode(ctx, &pub_decoded, ell64); + secp256k1_pubkey_load(ctx, &ge_decoded, &pub_decoded); + CHECK(secp256k1_ge_eq_var(&ge_decoded, &group[i])); + } +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ellswift/tests_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/tests_impl.h new file mode 100644 index 0000000000..3c314c9b50 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/ellswift/tests_impl.h @@ -0,0 +1,436 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_ELLSWIFT_TESTS_H +#define SECP256K1_MODULE_ELLSWIFT_TESTS_H + +#include "../../../include/secp256k1_ellswift.h" + +struct ellswift_xswiftec_inv_test { + int enc_bitmap; + secp256k1_fe u; + secp256k1_fe x; + secp256k1_fe encs[8]; +}; + +struct ellswift_decode_test { + unsigned char enc[64]; + secp256k1_fe x; + int odd_y; +}; + +struct ellswift_xdh_test { + unsigned char priv_ours[32]; + unsigned char ellswift_ours[64]; + unsigned char ellswift_theirs[64]; + int initiating; + unsigned char shared_secret[32]; +}; + +/* Set of (point, encodings) test vectors, selected to maximize branch coverage, part of the BIP324 + * test vectors. Created using an independent implementation, and tested decoding against paper + * authors' code. */ +static const struct ellswift_xswiftec_inv_test ellswift_xswiftec_inv_tests[] = { + {0xcc, SECP256K1_FE_CONST(0x05ff6bda, 0xd900fc32, 0x61bc7fe3, 0x4e2fb0f5, 0x69f06e09, 0x1ae437d3, 0xa52e9da0, 0xcbfb9590), SECP256K1_FE_CONST(0x80cdf637, 0x74ec7022, 0xc89a5a85, 0x58e373a2, 0x79170285, 0xe0ab2741, 0x2dbce510, 0xbdfe23fc), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x45654798, 0xece071ba, 0x79286d04, 0xf7f3eb1c, 0x3f1d17dd, 0x883610f2, 0xad2efd82, 0xa287466b), SECP256K1_FE_CONST(0x0aeaa886, 0xf6b76c71, 0x58452418, 0xcbf5033a, 0xdc5747e9, 0xe9b5d3b2, 0x303db969, 0x36528557), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xba9ab867, 0x131f8e45, 0x86d792fb, 0x080c14e3, 0xc0e2e822, 0x77c9ef0d, 0x52d1027c, 0x5d78b5c4), SECP256K1_FE_CONST(0xf5155779, 0x0948938e, 0xa7badbe7, 0x340afcc5, 0x23a8b816, 0x164a2c4d, 0xcfc24695, 0xc9ad76d8)}}, + {0x33, SECP256K1_FE_CONST(0x1737a85f, 0x4c8d146c, 0xec96e3ff, 0xdca76d99, 0x03dcf3bd, 0x53061868, 0xd478c78c, 0x63c2aa9e), SECP256K1_FE_CONST(0x39e48dd1, 0x50d2f429, 0xbe088dfd, 0x5b61882e, 0x7e840748, 0x3702ae9a, 0x5ab35927, 0xb15f85ea), {SECP256K1_FE_CONST(0x1be8cc0b, 0x04be0c68, 0x1d0c6a68, 0xf733f82c, 0x6c896e0c, 0x8a262fcd, 0x392918e3, 0x03a7abf4), SECP256K1_FE_CONST(0x605b5814, 0xbf9b8cb0, 0x66667c9e, 0x5480d22d, 0xc5b6c92f, 0x14b4af3e, 0xe0a9eb83, 0xb03685e3), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xe41733f4, 0xfb41f397, 0xe2f39597, 0x08cc07d3, 0x937691f3, 0x75d9d032, 0xc6d6e71b, 0xfc58503b), SECP256K1_FE_CONST(0x9fa4a7eb, 0x4064734f, 0x99998361, 0xab7f2dd2, 0x3a4936d0, 0xeb4b50c1, 0x1f56147b, 0x4fc9764c), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x00, SECP256K1_FE_CONST(0x1aaa1cce, 0xbf9c7241, 0x91033df3, 0x66b36f69, 0x1c4d902c, 0x228033ff, 0x4516d122, 0xb2564f68), SECP256K1_FE_CONST(0xc7554125, 0x9d3ba98f, 0x207eaa30, 0xc69634d1, 0x87d0b6da, 0x594e719e, 0x420f4898, 0x638fc5b0), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x33, SECP256K1_FE_CONST(0x2323a1d0, 0x79b0fd72, 0xfc8bb62e, 0xc34230a8, 0x15cb0596, 0xc2bfac99, 0x8bd6b842, 0x60f5dc26), SECP256K1_FE_CONST(0x239342df, 0xb675500a, 0x34a19631, 0x0b8d87d5, 0x4f49dcac, 0x9da50c17, 0x43ceab41, 0xa7b249ff), {SECP256K1_FE_CONST(0xf63580b8, 0xaa49c484, 0x6de56e39, 0xe1b3e73f, 0x171e881e, 0xba8c66f6, 0x14e67e5c, 0x975dfc07), SECP256K1_FE_CONST(0xb6307b33, 0x2e699f1c, 0xf77841d9, 0x0af25365, 0x404deb7f, 0xed5edb30, 0x90db49e6, 0x42a156b6), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x09ca7f47, 0x55b63b7b, 0x921a91c6, 0x1e4c18c0, 0xe8e177e1, 0x45739909, 0xeb1981a2, 0x68a20028), SECP256K1_FE_CONST(0x49cf84cc, 0xd19660e3, 0x0887be26, 0xf50dac9a, 0xbfb21480, 0x12a124cf, 0x6f24b618, 0xbd5ea579), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x33, SECP256K1_FE_CONST(0x2dc90e64, 0x0cb646ae, 0x9164c0b5, 0xa9ef0169, 0xfebe34dc, 0x4437d6e4, 0x6acb0e27, 0xe219d1e8), SECP256K1_FE_CONST(0xd236f19b, 0xf349b951, 0x6e9b3f4a, 0x5610fe96, 0x0141cb23, 0xbbc8291b, 0x9534f1d7, 0x1de62a47), {SECP256K1_FE_CONST(0xe69df7d9, 0xc026c366, 0x00ebdf58, 0x80726758, 0x47c0c431, 0xc8eb7306, 0x82533e96, 0x4b6252c9), SECP256K1_FE_CONST(0x4f18bbdf, 0x7c2d6c5f, 0x818c1880, 0x2fa35cd0, 0x69eaa79f, 0xff74e4fc, 0x837c80d9, 0x3fece2f8), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x19620826, 0x3fd93c99, 0xff1420a7, 0x7f8d98a7, 0xb83f3bce, 0x37148cf9, 0x7dacc168, 0xb49da966), SECP256K1_FE_CONST(0xb0e74420, 0x83d293a0, 0x7e73e77f, 0xd05ca32f, 0x96155860, 0x008b1b03, 0x7c837f25, 0xc0131937), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0xcc, SECP256K1_FE_CONST(0x3edd7b39, 0x80e2f2f3, 0x4d1409a2, 0x07069f88, 0x1fda5f96, 0xf08027ac, 0x4465b63d, 0xc278d672), SECP256K1_FE_CONST(0x053a98de, 0x4a27b196, 0x1155822b, 0x3a3121f0, 0x3b2a1445, 0x8bd80eb4, 0xa560c4c7, 0xa85c149c), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xb3dae4b7, 0xdcf858e4, 0xc6968057, 0xcef2b156, 0x46543152, 0x6538199c, 0xf52dc1b2, 0xd62fda30), SECP256K1_FE_CONST(0x4aa77dd5, 0x5d6b6d3c, 0xfa10cc9d, 0x0fe42f79, 0x232e4575, 0x661049ae, 0x36779c1d, 0x0c666d88), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x4c251b48, 0x2307a71b, 0x39697fa8, 0x310d4ea9, 0xb9abcead, 0x9ac7e663, 0x0ad23e4c, 0x29d021ff), SECP256K1_FE_CONST(0xb558822a, 0xa29492c3, 0x05ef3362, 0xf01bd086, 0xdcd1ba8a, 0x99efb651, 0xc98863e1, 0xf3998ea7)}}, + {0x00, SECP256K1_FE_CONST(0x4295737e, 0xfcb1da6f, 0xb1d96b9c, 0xa7dcd1e3, 0x20024b37, 0xa736c494, 0x8b625981, 0x73069f70), SECP256K1_FE_CONST(0xfa7ffe4f, 0x25f88362, 0x831c087a, 0xfe2e8a9b, 0x0713e2ca, 0xc1ddca6a, 0x383205a2, 0x66f14307), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0xff, SECP256K1_FE_CONST(0x587c1a0c, 0xee91939e, 0x7f784d23, 0xb963004a, 0x3bf44f5d, 0x4e32a008, 0x1995ba20, 0xb0fca59e), SECP256K1_FE_CONST(0x2ea98853, 0x0715e8d1, 0x0363907f, 0xf2512452, 0x4d471ba2, 0x454d5ce3, 0xbe3f0419, 0x4dfd3a3c), {SECP256K1_FE_CONST(0xcfd5a094, 0xaa0b9b88, 0x91b76c6a, 0xb9438f66, 0xaa1c095a, 0x65f9f701, 0x35e81712, 0x92245e74), SECP256K1_FE_CONST(0xa89057d7, 0xc6563f0d, 0x6efa19ae, 0x84412b8a, 0x7b47e791, 0xa191ecdf, 0xdf2af84f, 0xd97bc339), SECP256K1_FE_CONST(0x475d0ae9, 0xef46920d, 0xf07b3411, 0x7be5a081, 0x7de1023e, 0x3cc32689, 0xe9be145b, 0x406b0aef), SECP256K1_FE_CONST(0xa0759178, 0xad802324, 0x54f827ef, 0x05ea3e72, 0xad8d7541, 0x8e6d4cc1, 0xcd4f5306, 0xc5e7c453), SECP256K1_FE_CONST(0x302a5f6b, 0x55f46477, 0x6e489395, 0x46bc7099, 0x55e3f6a5, 0x9a0608fe, 0xca17e8ec, 0x6ddb9dbb), SECP256K1_FE_CONST(0x576fa828, 0x39a9c0f2, 0x9105e651, 0x7bbed475, 0x84b8186e, 0x5e6e1320, 0x20d507af, 0x268438f6), SECP256K1_FE_CONST(0xb8a2f516, 0x10b96df2, 0x0f84cbee, 0x841a5f7e, 0x821efdc1, 0xc33cd976, 0x1641eba3, 0xbf94f140), SECP256K1_FE_CONST(0x5f8a6e87, 0x527fdcdb, 0xab07d810, 0xfa15c18d, 0x52728abe, 0x7192b33e, 0x32b0acf8, 0x3a1837dc)}}, + {0xcc, SECP256K1_FE_CONST(0x5fa88b33, 0x65a635cb, 0xbcee003c, 0xce9ef51d, 0xd1a310de, 0x277e441a, 0xbccdb7be, 0x1e4ba249), SECP256K1_FE_CONST(0x79461ff6, 0x2bfcbcac, 0x4249ba84, 0xdd040f2c, 0xec3c63f7, 0x25204dc7, 0xf464c16b, 0xf0ff3170), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x6bb700e1, 0xf4d7e236, 0xe8d193ff, 0x4a76c1b3, 0xbcd4e2b2, 0x5acac3d5, 0x1c8dac65, 0x3fe909a0), SECP256K1_FE_CONST(0xf4c73410, 0x633da7f6, 0x3a4f1d55, 0xaec6dd32, 0xc4c6d89e, 0xe74075ed, 0xb5515ed9, 0x0da9e683), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x9448ff1e, 0x0b281dc9, 0x172e6c00, 0xb5893e4c, 0x432b1d4d, 0xa5353c2a, 0xe3725399, 0xc016f28f), SECP256K1_FE_CONST(0x0b38cbef, 0x9cc25809, 0xc5b0e2aa, 0x513922cd, 0x3b392761, 0x18bf8a12, 0x4aaea125, 0xf25615ac)}}, + {0xcc, SECP256K1_FE_CONST(0x6fb31c75, 0x31f03130, 0xb42b155b, 0x952779ef, 0xbb46087d, 0xd9807d24, 0x1a48eac6, 0x3c3d96d6), SECP256K1_FE_CONST(0x56f81be7, 0x53e8d4ae, 0x4940ea6f, 0x46f6ec9f, 0xda66a6f9, 0x6cc95f50, 0x6cb2b574, 0x90e94260), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x59059774, 0x795bdb7a, 0x837fbe11, 0x40a5fa59, 0x984f48af, 0x8df95d57, 0xdd6d1c05, 0x437dcec1), SECP256K1_FE_CONST(0x22a644db, 0x79376ad4, 0xe7b3a009, 0xe58b3f13, 0x137c54fd, 0xf911122c, 0xc93667c4, 0x7077d784), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xa6fa688b, 0x86a42485, 0x7c8041ee, 0xbf5a05a6, 0x67b0b750, 0x7206a2a8, 0x2292e3f9, 0xbc822d6e), SECP256K1_FE_CONST(0xdd59bb24, 0x86c8952b, 0x184c5ff6, 0x1a74c0ec, 0xec83ab02, 0x06eeedd3, 0x36c9983a, 0x8f8824ab)}}, + {0x00, SECP256K1_FE_CONST(0x704cd226, 0xe71cb682, 0x6a590e80, 0xdac90f2d, 0x2f5830f0, 0xfdf135a3, 0xeae3965b, 0xff25ff12), SECP256K1_FE_CONST(0x138e0afa, 0x68936ee6, 0x70bd2b8d, 0xb53aedbb, 0x7bea2a85, 0x97388b24, 0xd0518edd, 0x22ad66ec), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x33, SECP256K1_FE_CONST(0x725e9147, 0x92cb8c89, 0x49e7e116, 0x8b7cdd8a, 0x8094c91c, 0x6ec2202c, 0xcd53a6a1, 0x8771edeb), SECP256K1_FE_CONST(0x8da16eb8, 0x6d347376, 0xb6181ee9, 0x74832275, 0x7f6b36e3, 0x913ddfd3, 0x32ac595d, 0x788e0e44), {SECP256K1_FE_CONST(0xdd357786, 0xb9f68733, 0x30391aa5, 0x62580965, 0x4e43116e, 0x82a5a5d8, 0x2ffd1d66, 0x24101fc4), SECP256K1_FE_CONST(0xa0b7efca, 0x01814594, 0xc59c9aae, 0x8e497001, 0x86ca5d95, 0xe88bcc80, 0x399044d9, 0xc2d8613d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x22ca8879, 0x460978cc, 0xcfc6e55a, 0x9da7f69a, 0xb1bcee91, 0x7d5a5a27, 0xd002e298, 0xdbefdc6b), SECP256K1_FE_CONST(0x5f481035, 0xfe7eba6b, 0x3a636551, 0x71b68ffe, 0x7935a26a, 0x1774337f, 0xc66fbb25, 0x3d279af2), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x00, SECP256K1_FE_CONST(0x78fe6b71, 0x7f2ea4a3, 0x2708d79c, 0x151bf503, 0xa5312a18, 0xc0963437, 0xe865cc6e, 0xd3f6ae97), SECP256K1_FE_CONST(0x8701948e, 0x80d15b5c, 0xd8f72863, 0xeae40afc, 0x5aced5e7, 0x3f69cbc8, 0x179a3390, 0x2c094d98), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x44, SECP256K1_FE_CONST(0x7c37bb9c, 0x5061dc07, 0x413f11ac, 0xd5a34006, 0xe64c5c45, 0x7fdb9a43, 0x8f217255, 0xa961f50d), SECP256K1_FE_CONST(0x5c1a76b4, 0x4568eb59, 0xd6789a74, 0x42d9ed7c, 0xdc6226b7, 0x752b4ff8, 0xeaf8e1a9, 0x5736e507), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xb94d30cd, 0x7dbff60b, 0x64620c17, 0xca0fafaa, 0x40b3d1f5, 0x2d077a60, 0xa2e0cafd, 0x145086c2), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x46b2cf32, 0x824009f4, 0x9b9df3e8, 0x35f05055, 0xbf4c2e0a, 0xd2f8859f, 0x5d1f3501, 0xebaf756d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x00, SECP256K1_FE_CONST(0x82388888, 0x967f82a6, 0xb444438a, 0x7d44838e, 0x13c0d478, 0xb9ca060d, 0xa95a41fb, 0x94303de6), SECP256K1_FE_CONST(0x29e96541, 0x70628fec, 0x8b497289, 0x8b113cf9, 0x8807f460, 0x9274f4f3, 0x140d0674, 0x157c90a0), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x33, SECP256K1_FE_CONST(0x91298f57, 0x70af7a27, 0xf0a47188, 0xd24c3b7b, 0xf98ab299, 0x0d84b0b8, 0x98507e3c, 0x561d6472), SECP256K1_FE_CONST(0x144f4ccb, 0xd9a74698, 0xa88cbf6f, 0xd00ad886, 0xd339d29e, 0xa19448f2, 0xc572cac0, 0xa07d5562), {SECP256K1_FE_CONST(0xe6a0ffa3, 0x807f09da, 0xdbe71e0f, 0x4be4725f, 0x2832e76c, 0xad8dc1d9, 0x43ce8393, 0x75eff248), SECP256K1_FE_CONST(0x837b8e68, 0xd4917544, 0x764ad090, 0x3cb11f86, 0x15d2823c, 0xefbb06d8, 0x9049dbab, 0xc69befda), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x195f005c, 0x7f80f625, 0x2418e1f0, 0xb41b8da0, 0xd7cd1893, 0x52723e26, 0xbc317c6b, 0x8a1009e7), SECP256K1_FE_CONST(0x7c847197, 0x2b6e8abb, 0x89b52f6f, 0xc34ee079, 0xea2d7dc3, 0x1044f927, 0x6fb62453, 0x39640c55), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x00, SECP256K1_FE_CONST(0xb682f3d0, 0x3bbb5dee, 0x4f54b5eb, 0xfba931b4, 0xf52f6a19, 0x1e5c2f48, 0x3c73c66e, 0x9ace97e1), SECP256K1_FE_CONST(0x904717bf, 0x0bc0cb78, 0x73fcdc38, 0xaa97f19e, 0x3a626309, 0x72acff92, 0xb24cc6dd, 0xa197cb96), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x77, SECP256K1_FE_CONST(0xc17ec69e, 0x665f0fb0, 0xdbab48d9, 0xc2f94d12, 0xec8a9d7e, 0xacb58084, 0x83309180, 0x1eb0b80b), SECP256K1_FE_CONST(0x147756e6, 0x6d96e31c, 0x426d3cc8, 0x5ed0c4cf, 0xbef6341d, 0xd8b28558, 0x5aa574ea, 0x0204b55e), {SECP256K1_FE_CONST(0x6f4aea43, 0x1a0043bd, 0xd03134d6, 0xd9159119, 0xce034b88, 0xc32e50e8, 0xe36c4ee4, 0x5eac7ae9), SECP256K1_FE_CONST(0xfd5be16d, 0x4ffa2690, 0x126c67c3, 0xef7cb9d2, 0x9b74d397, 0xc78b06b3, 0x605fda34, 0xdc9696a6), SECP256K1_FE_CONST(0x5e9c6079, 0x2a2f000e, 0x45c6250f, 0x296f875e, 0x174efc0e, 0x9703e628, 0x706103a9, 0xdd2d82c7), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x90b515bc, 0xe5ffbc42, 0x2fcecb29, 0x26ea6ee6, 0x31fcb477, 0x3cd1af17, 0x1c93b11a, 0xa1538146), SECP256K1_FE_CONST(0x02a41e92, 0xb005d96f, 0xed93983c, 0x1083462d, 0x648b2c68, 0x3874f94c, 0x9fa025ca, 0x23696589), SECP256K1_FE_CONST(0xa1639f86, 0xd5d0fff1, 0xba39daf0, 0xd69078a1, 0xe8b103f1, 0x68fc19d7, 0x8f9efc55, 0x22d27968), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0xcc, SECP256K1_FE_CONST(0xc25172fc, 0x3f29b6fc, 0x4a1155b8, 0x57523315, 0x5486b274, 0x64b74b8b, 0x260b499a, 0x3f53cb14), SECP256K1_FE_CONST(0x1ea9cbdb, 0x35cf6e03, 0x29aa31b0, 0xbb0a702a, 0x65123ed0, 0x08655a93, 0xb7dcd528, 0x0e52e1ab), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x7422edc7, 0x843136af, 0x0053bb88, 0x54448a82, 0x99994f9d, 0xdcefd3a9, 0xa92d4546, 0x2c59298a), SECP256K1_FE_CONST(0x78c7774a, 0x266f8b97, 0xea23d05d, 0x064f033c, 0x77319f92, 0x3f6b78bc, 0xe4e20bf0, 0x5fa5398d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x8bdd1238, 0x7bcec950, 0xffac4477, 0xabbb757d, 0x6666b062, 0x23102c56, 0x56d2bab8, 0xd3a6d2a5), SECP256K1_FE_CONST(0x873888b5, 0xd9907468, 0x15dc2fa2, 0xf9b0fcc3, 0x88ce606d, 0xc0948743, 0x1b1df40e, 0xa05ac2a2)}}, + {0x00, SECP256K1_FE_CONST(0xcab6626f, 0x832a4b12, 0x80ba7add, 0x2fc5322f, 0xf011caed, 0xedf7ff4d, 0xb6735d50, 0x26dc0367), SECP256K1_FE_CONST(0x2b2bef08, 0x52c6f7c9, 0x5d72ac99, 0xa23802b8, 0x75029cd5, 0x73b248d1, 0xf1b3fc80, 0x33788eb6), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x33, SECP256K1_FE_CONST(0xd8621b4f, 0xfc85b9ed, 0x56e99d8d, 0xd1dd24ae, 0xdcecb147, 0x63b861a1, 0x7112dc77, 0x1a104fd2), SECP256K1_FE_CONST(0x812cabe9, 0x72a22aa6, 0x7c7da0c9, 0x4d8a9362, 0x96eb9949, 0xd70c37cb, 0x2b248757, 0x4cb3ce58), {SECP256K1_FE_CONST(0xfbc5febc, 0x6fdbc9ae, 0x3eb88a93, 0xb982196e, 0x8b6275a6, 0xd5a73c17, 0x387e000c, 0x711bd0e3), SECP256K1_FE_CONST(0x8724c96b, 0xd4e5527f, 0x2dd195a5, 0x1c468d2d, 0x211ba2fa, 0xc7cbe0b4, 0xb3434253, 0x409fb42d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x043a0143, 0x90243651, 0xc147756c, 0x467de691, 0x749d8a59, 0x2a58c3e8, 0xc781fff2, 0x8ee42b4c), SECP256K1_FE_CONST(0x78db3694, 0x2b1aad80, 0xd22e6a5a, 0xe3b972d2, 0xdee45d05, 0x38341f4b, 0x4cbcbdab, 0xbf604802), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x00, SECP256K1_FE_CONST(0xda463164, 0xc6f4bf71, 0x29ee5f0e, 0xc00f65a6, 0x75a8adf1, 0xbd931b39, 0xb64806af, 0xdcda9a22), SECP256K1_FE_CONST(0x25b9ce9b, 0x390b408e, 0xd611a0f1, 0x3ff09a59, 0x8a57520e, 0x426ce4c6, 0x49b7f94f, 0x2325620d), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0xcc, SECP256K1_FE_CONST(0xdafc971e, 0x4a3a7b6d, 0xcfb42a08, 0xd9692d82, 0xad9e7838, 0x523fcbda, 0x1d4827e1, 0x4481ae2d), SECP256K1_FE_CONST(0x250368e1, 0xb5c58492, 0x304bd5f7, 0x2696d27d, 0x526187c7, 0xadc03425, 0xe2b7d81d, 0xbb7e4e02), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x370c28f1, 0xbe665efa, 0xcde6aa43, 0x6bf86fe2, 0x1e6e314c, 0x1e53dd04, 0x0e6c73a4, 0x6b4c8c49), SECP256K1_FE_CONST(0xcd8acee9, 0x8ffe5653, 0x1a84d7eb, 0x3e48fa40, 0x34206ce8, 0x25ace907, 0xd0edf0ea, 0xeb5e9ca2), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xc8f3d70e, 0x4199a105, 0x321955bc, 0x9407901d, 0xe191ceb3, 0xe1ac22fb, 0xf1938c5a, 0x94b36fe6), SECP256K1_FE_CONST(0x32753116, 0x7001a9ac, 0xe57b2814, 0xc1b705bf, 0xcbdf9317, 0xda5316f8, 0x2f120f14, 0x14a15f8d)}}, + {0x44, SECP256K1_FE_CONST(0xe0294c8b, 0xc1a36b41, 0x66ee92bf, 0xa70a5c34, 0x976fa982, 0x9405efea, 0x8f9cd54d, 0xcb29b99e), SECP256K1_FE_CONST(0xae9690d1, 0x3b8d20a0, 0xfbbf37be, 0xd8474f67, 0xa04e142f, 0x56efd787, 0x70a76b35, 0x9165d8a1), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xdcd45d93, 0x5613916a, 0xf167b029, 0x058ba3a7, 0x00d37150, 0xb9df3472, 0x8cb05412, 0xc16d4182), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x232ba26c, 0xa9ec6e95, 0x0e984fd6, 0xfa745c58, 0xff2c8eaf, 0x4620cb8d, 0x734fabec, 0x3e92baad), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0x00, SECP256K1_FE_CONST(0xe148441c, 0xd7b92b8b, 0x0e4fa3bd, 0x68712cfd, 0x0d709ad1, 0x98cace61, 0x1493c10e, 0x97f5394e), SECP256K1_FE_CONST(0x164a6397, 0x94d74c53, 0xafc4d329, 0x4e79cdb3, 0xcd25f99f, 0x6df45c00, 0x0f758aba, 0x54d699c0), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0xff, SECP256K1_FE_CONST(0xe4b00ec9, 0x7aadcca9, 0x7644d3b0, 0xc8a931b1, 0x4ce7bcf7, 0xbc877954, 0x6d6e35aa, 0x5937381c), SECP256K1_FE_CONST(0x94e9588d, 0x41647b3f, 0xcc772dc8, 0xd83c67ce, 0x3be00353, 0x8517c834, 0x103d2cd4, 0x9d62ef4d), {SECP256K1_FE_CONST(0xc88d25f4, 0x1407376b, 0xb2c03a7f, 0xffeb3ec7, 0x811cc434, 0x91a0c3aa, 0xc0378cdc, 0x78357bee), SECP256K1_FE_CONST(0x51c02636, 0xce00c234, 0x5ecd89ad, 0xb6089fe4, 0xd5e18ac9, 0x24e3145e, 0x6669501c, 0xd37a00d4), SECP256K1_FE_CONST(0x205b3512, 0xdb40521c, 0xb200952e, 0x67b46f67, 0xe09e7839, 0xe0de4400, 0x4138329e, 0xbd9138c5), SECP256K1_FE_CONST(0x58aab390, 0xab6fb55c, 0x1d1b8089, 0x7a207ce9, 0x4a78fa5b, 0x4aa61a33, 0x398bcae9, 0xadb20d3e), SECP256K1_FE_CONST(0x3772da0b, 0xebf8c894, 0x4d3fc580, 0x0014c138, 0x7ee33bcb, 0x6e5f3c55, 0x3fc87322, 0x87ca8041), SECP256K1_FE_CONST(0xae3fd9c9, 0x31ff3dcb, 0xa1327652, 0x49f7601b, 0x2a1e7536, 0xdb1ceba1, 0x9996afe2, 0x2c85fb5b), SECP256K1_FE_CONST(0xdfa4caed, 0x24bfade3, 0x4dff6ad1, 0x984b9098, 0x1f6187c6, 0x1f21bbff, 0xbec7cd60, 0x426ec36a), SECP256K1_FE_CONST(0xa7554c6f, 0x54904aa3, 0xe2e47f76, 0x85df8316, 0xb58705a4, 0xb559e5cc, 0xc6743515, 0x524deef1)}}, + {0x00, SECP256K1_FE_CONST(0xe5bbb9ef, 0x360d0a50, 0x1618f006, 0x7d36dceb, 0x75f5be9a, 0x620232aa, 0x9fd5139d, 0x0863fde5), SECP256K1_FE_CONST(0xe5bbb9ef, 0x360d0a50, 0x1618f006, 0x7d36dceb, 0x75f5be9a, 0x620232aa, 0x9fd5139d, 0x0863fde5), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0xff, SECP256K1_FE_CONST(0xe6bcb5c3, 0xd63467d4, 0x90bfa54f, 0xbbc6092a, 0x7248c25e, 0x11b248dc, 0x2964a6e1, 0x5edb1457), SECP256K1_FE_CONST(0x19434a3c, 0x29cb982b, 0x6f405ab0, 0x4439f6d5, 0x8db73da1, 0xee4db723, 0xd69b591d, 0xa124e7d8), {SECP256K1_FE_CONST(0x67119877, 0x832ab8f4, 0x59a82165, 0x6d8261f5, 0x44a553b8, 0x9ae4f25c, 0x52a97134, 0xb70f3426), SECP256K1_FE_CONST(0xffee02f5, 0xe649c07f, 0x0560eff1, 0x867ec7b3, 0x2d0e595e, 0x9b1c0ea6, 0xe2a4fc70, 0xc97cd71f), SECP256K1_FE_CONST(0xb5e0c189, 0xeb5b4bac, 0xd025b744, 0x4d74178b, 0xe8d5246c, 0xfa4a9a20, 0x7964a057, 0xee969992), SECP256K1_FE_CONST(0x5746e459, 0x1bf7f4c3, 0x044609ea, 0x372e9086, 0x03975d27, 0x9fdef834, 0x9f0b08d3, 0x2f07619d), SECP256K1_FE_CONST(0x98ee6788, 0x7cd5470b, 0xa657de9a, 0x927d9e0a, 0xbb5aac47, 0x651b0da3, 0xad568eca, 0x48f0c809), SECP256K1_FE_CONST(0x0011fd0a, 0x19b63f80, 0xfa9f100e, 0x7981384c, 0xd2f1a6a1, 0x64e3f159, 0x1d5b038e, 0x36832510), SECP256K1_FE_CONST(0x4a1f3e76, 0x14a4b453, 0x2fda48bb, 0xb28be874, 0x172adb93, 0x05b565df, 0x869b5fa7, 0x1169629d), SECP256K1_FE_CONST(0xa8b91ba6, 0xe4080b3c, 0xfbb9f615, 0xc8d16f79, 0xfc68a2d8, 0x602107cb, 0x60f4f72b, 0xd0f89a92)}}, + {0x33, SECP256K1_FE_CONST(0xf28fba64, 0xaf766845, 0xeb2f4302, 0x456e2b9f, 0x8d80affe, 0x57e7aae4, 0x2738d7cd, 0xdb1c2ce6), SECP256K1_FE_CONST(0xf28fba64, 0xaf766845, 0xeb2f4302, 0x456e2b9f, 0x8d80affe, 0x57e7aae4, 0x2738d7cd, 0xdb1c2ce6), {SECP256K1_FE_CONST(0x4f867ad8, 0xbb3d8404, 0x09d26b67, 0x307e6210, 0x0153273f, 0x72fa4b74, 0x84becfa1, 0x4ebe7408), SECP256K1_FE_CONST(0x5bbc4f59, 0xe452cc5f, 0x22a99144, 0xb10ce898, 0x9a89a995, 0xec3cea1c, 0x91ae10e8, 0xf721bb5d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xb0798527, 0x44c27bfb, 0xf62d9498, 0xcf819def, 0xfeacd8c0, 0x8d05b48b, 0x7b41305d, 0xb1418827), SECP256K1_FE_CONST(0xa443b0a6, 0x1bad33a0, 0xdd566ebb, 0x4ef31767, 0x6576566a, 0x13c315e3, 0x6e51ef16, 0x08de40d2), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, + {0xcc, SECP256K1_FE_CONST(0xf455605b, 0xc85bf48e, 0x3a908c31, 0x023faf98, 0x381504c6, 0xc6d3aeb9, 0xede55f8d, 0xd528924d), SECP256K1_FE_CONST(0xd31fbcd5, 0xcdb798f6, 0xc00db669, 0x2f8fe896, 0x7fa9c79d, 0xd10958f4, 0xa194f013, 0x74905e99), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x0c00c571, 0x5b56fe63, 0x2d814ad8, 0xa77f8e66, 0x628ea47a, 0x6116834f, 0x8c1218f3, 0xa03cbd50), SECP256K1_FE_CONST(0xdf88e44f, 0xac84fa52, 0xdf4d59f4, 0x8819f18f, 0x6a8cd415, 0x1d162afa, 0xf773166f, 0x57c7ff46), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xf3ff3a8e, 0xa4a9019c, 0xd27eb527, 0x58807199, 0x9d715b85, 0x9ee97cb0, 0x73ede70b, 0x5fc33edf), SECP256K1_FE_CONST(0x20771bb0, 0x537b05ad, 0x20b2a60b, 0x77e60e70, 0x95732bea, 0xe2e9d505, 0x088ce98f, 0xa837fce9)}}, + {0xff, SECP256K1_FE_CONST(0xf58cd4d9, 0x830bad32, 0x2699035e, 0x8246007d, 0x4be27e19, 0xb6f53621, 0x317b4f30, 0x9b3daa9d), SECP256K1_FE_CONST(0x78ec2b3d, 0xc0948de5, 0x60148bbc, 0x7c6dc963, 0x3ad5df70, 0xa5a5750c, 0xbed72180, 0x4f082a3b), {SECP256K1_FE_CONST(0x6c4c580b, 0x76c75940, 0x43569f9d, 0xae16dc28, 0x01c16a1f, 0xbe128608, 0x81b75f8e, 0xf929bce5), SECP256K1_FE_CONST(0x94231355, 0xe7385c5f, 0x25ca436a, 0xa6419147, 0x1aea4393, 0xd6e86ab7, 0xa35fe2af, 0xacaefd0d), SECP256K1_FE_CONST(0xdff2a195, 0x1ada6db5, 0x74df8340, 0x48149da3, 0x397a75b8, 0x29abf58c, 0x7e69db1b, 0x41ac0989), SECP256K1_FE_CONST(0xa52b66d3, 0xc9070355, 0x48028bf8, 0x04711bf4, 0x22aba95f, 0x1a666fc8, 0x6f4648e0, 0x5f29caae), SECP256K1_FE_CONST(0x93b3a7f4, 0x8938a6bf, 0xbca96062, 0x51e923d7, 0xfe3e95e0, 0x41ed79f7, 0x7e48a070, 0x06d63f4a), SECP256K1_FE_CONST(0x6bdcecaa, 0x18c7a3a0, 0xda35bc95, 0x59be6eb8, 0xe515bc6c, 0x29179548, 0x5ca01d4f, 0x5350ff22), SECP256K1_FE_CONST(0x200d5e6a, 0xe525924a, 0x8b207cbf, 0xb7eb625c, 0xc6858a47, 0xd6540a73, 0x819624e3, 0xbe53f2a6), SECP256K1_FE_CONST(0x5ad4992c, 0x36f8fcaa, 0xb7fd7407, 0xfb8ee40b, 0xdd5456a0, 0xe5999037, 0x90b9b71e, 0xa0d63181)}}, + {0x00, SECP256K1_FE_CONST(0xfd7d912a, 0x40f182a3, 0x588800d6, 0x9ebfb504, 0x8766da20, 0x6fd7ebc8, 0xd2436c81, 0xcbef6421), SECP256K1_FE_CONST(0x8d37c862, 0x054debe7, 0x31694536, 0xff46b273, 0xec122b35, 0xa9bf1445, 0xac3c4ff9, 0xf262c952), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}}, +}; + +/* Set of (encoding, xcoord) test vectors, selected to maximize branch coverage, part of the BIP324 + * test vectors. Created using an independent implementation, and tested decoding against the paper + * authors' code. */ +static const struct ellswift_decode_test ellswift_decode_tests[] = { + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c), 0}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x47, 0x5b, 0xf7, 0x65, 0x5b, 0x0f, 0xb2, 0xd8, 0x52, 0x92, 0x10, 0x35, 0xb2, 0xef, 0x60, 0x7f, 0x49, 0x06, 0x9b, 0x97, 0x45, 0x4e, 0x67, 0x95, 0x25, 0x10, 0x62, 0x74, 0x17, 0x71}, SECP256K1_FE_CONST(0xb5da00b7, 0x3cd65605, 0x20e7c364, 0x086e7cd2, 0x3a34bf60, 0xd0e707be, 0x9fc34d4c, 0xd5fdfa2c), 1}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x27, 0x7c, 0x4a, 0x71, 0xf9, 0xd2, 0x2e, 0x66, 0xec, 0xe5, 0x23, 0xf8, 0xfa, 0x08, 0x74, 0x1a, 0x7c, 0x09, 0x12, 0xc6, 0x6a, 0x69, 0xce, 0x68, 0x51, 0x4b, 0xfd, 0x35, 0x15, 0xb4, 0x9f}, SECP256K1_FE_CONST(0xf482f2e2, 0x41753ad0, 0xfb89150d, 0x8491dc1e, 0x34ff0b8a, 0xcfbb442c, 0xfe999e2e, 0x5e6fd1d2), 1}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x21, 0xcc, 0x93, 0x0e, 0x77, 0xc9, 0xf5, 0x14, 0xb6, 0x91, 0x5c, 0x3d, 0xbe, 0x2a, 0x94, 0xc6, 0xd8, 0xf6, 0x90, 0xb5, 0xb7, 0x39, 0x86, 0x4b, 0xa6, 0x78, 0x9f, 0xb8, 0xa5, 0x5d, 0xd0}, SECP256K1_FE_CONST(0x9f59c402, 0x75f5085a, 0x006f05da, 0xe77eb98c, 0x6fd0db1a, 0xb4a72ac4, 0x7eae90a4, 0xfc9e57e0), 0}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb, 0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41}, SECP256K1_FE_CONST(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaa9, 0xfffffd6b), 1}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x9c, 0x18, 0x2d, 0x27, 0x59, 0xcd, 0x99, 0x82, 0x42, 0x28, 0xd9, 0x47, 0x99, 0xf8, 0xc6, 0x55, 0x7c, 0x38, 0xa1, 0xc0, 0xd6, 0x77, 0x9b, 0x9d, 0x4b, 0x72, 0x9c, 0x6f, 0x1c, 0xcc, 0x42}, SECP256K1_FE_CONST(0x70720db7, 0xe238d041, 0x21f5b1af, 0xd8cc5ad9, 0xd18944c6, 0xbdc94881, 0xf502b7a3, 0xaf3aecff), 0}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c), 0}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x64, 0xbb, 0xd5}, SECP256K1_FE_CONST(0x50873db3, 0x1badcc71, 0x890e4f67, 0x753a6575, 0x7f97aaa7, 0xdd5f1e82, 0xb753ace3, 0x2219064b), 0}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x28, 0xde, 0x7d}, SECP256K1_FE_CONST(0x1eea9cc5, 0x9cfcf2fa, 0x151ac6c2, 0x74eea411, 0x0feb4f7b, 0x68c59657, 0x32e9992e, 0x976ef68e), 0}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xcf, 0xb7, 0xe7}, SECP256K1_FE_CONST(0x12303941, 0xaedc2088, 0x80735b1f, 0x1795c8e5, 0x5be520ea, 0x93e10335, 0x7b5d2adb, 0x7ed59b8e), 0}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x11, 0x3a, 0xd9}, SECP256K1_FE_CONST(0x7eed6b70, 0xe7b0767c, 0x7d7feac0, 0x4e57aa2a, 0x12fef5e0, 0xf48f878f, 0xcbb88b3b, 0x6b5e0783), 0}, + {{0x0a, 0x2d, 0x2b, 0xa9, 0x35, 0x07, 0xf1, 0xdf, 0x23, 0x37, 0x70, 0xc2, 0xa7, 0x97, 0x96, 0x2c, 0xc6, 0x1f, 0x6d, 0x15, 0xda, 0x14, 0xec, 0xd4, 0x7d, 0x8d, 0x27, 0xae, 0x1c, 0xd5, 0xf8, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x532167c1, 0x1200b08c, 0x0e84a354, 0xe74dcc40, 0xf8b25f4f, 0xe686e308, 0x69526366, 0x278a0688), 0}, + {{0x0a, 0x2d, 0x2b, 0xa9, 0x35, 0x07, 0xf1, 0xdf, 0x23, 0x37, 0x70, 0xc2, 0xa7, 0x97, 0x96, 0x2c, 0xc6, 0x1f, 0x6d, 0x15, 0xda, 0x14, 0xec, 0xd4, 0x7d, 0x8d, 0x27, 0xae, 0x1c, 0xd5, 0xf8, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x532167c1, 0x1200b08c, 0x0e84a354, 0xe74dcc40, 0xf8b25f4f, 0xe686e308, 0x69526366, 0x278a0688), 0}, + {{0x0f, 0xfd, 0xe9, 0xca, 0x81, 0xd7, 0x51, 0xe9, 0xcd, 0xaf, 0xfc, 0x1a, 0x50, 0x77, 0x92, 0x45, 0x32, 0x0b, 0x28, 0x99, 0x6d, 0xba, 0xf3, 0x2f, 0x82, 0x2f, 0x20, 0x11, 0x7c, 0x22, 0xfb, 0xd6, 0xc7, 0x4d, 0x99, 0xef, 0xce, 0xaa, 0x55, 0x0f, 0x1a, 0xd1, 0xc0, 0xf4, 0x3f, 0x46, 0xe7, 0xff, 0x1e, 0xe3, 0xbd, 0x01, 0x62, 0xb7, 0xbf, 0x55, 0xf2, 0x96, 0x5d, 0xa9, 0xc3, 0x45, 0x06, 0x46}, SECP256K1_FE_CONST(0x74e880b3, 0xffd18fe3, 0xcddf7902, 0x522551dd, 0xf97fa4a3, 0x5a3cfda8, 0x197f9470, 0x81a57b8f), 0}, + {{0x0f, 0xfd, 0xe9, 0xca, 0x81, 0xd7, 0x51, 0xe9, 0xcd, 0xaf, 0xfc, 0x1a, 0x50, 0x77, 0x92, 0x45, 0x32, 0x0b, 0x28, 0x99, 0x6d, 0xba, 0xf3, 0x2f, 0x82, 0x2f, 0x20, 0x11, 0x7c, 0x22, 0xfb, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x6c, 0xa8, 0x96}, SECP256K1_FE_CONST(0x377b643f, 0xce2271f6, 0x4e5c8101, 0x566107c1, 0xbe498074, 0x50917838, 0x04f65478, 0x1ac9217c), 1}, + {{0x12, 0x36, 0x58, 0x44, 0x4f, 0x32, 0xbe, 0x8f, 0x02, 0xea, 0x20, 0x34, 0xaf, 0xa7, 0xef, 0x4b, 0xbe, 0x8a, 0xdc, 0x91, 0x8c, 0xeb, 0x49, 0xb1, 0x27, 0x73, 0xb6, 0x25, 0xf4, 0x90, 0xb3, 0x68, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8d, 0xc5, 0xfe, 0x11}, SECP256K1_FE_CONST(0xed16d65c, 0xf3a9538f, 0xcb2c139f, 0x1ecbc143, 0xee148271, 0x20cbc265, 0x9e667256, 0x800b8142), 0}, + {{0x14, 0x6f, 0x92, 0x46, 0x4d, 0x15, 0xd3, 0x6e, 0x35, 0x38, 0x2b, 0xd3, 0xca, 0x5b, 0x0f, 0x97, 0x6c, 0x95, 0xcb, 0x08, 0xac, 0xdc, 0xf2, 0xd5, 0xb3, 0x57, 0x06, 0x17, 0x99, 0x08, 0x39, 0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x31, 0x45, 0xe9, 0x3b}, SECP256K1_FE_CONST(0x0d5cd840, 0x427f941f, 0x65193079, 0xab8e2e83, 0x024ef2ee, 0x7ca558d8, 0x8879ffd8, 0x79fb6657), 0}, + {{0x15, 0xfd, 0xf5, 0xcf, 0x09, 0xc9, 0x07, 0x59, 0xad, 0xd2, 0x27, 0x2d, 0x57, 0x4d, 0x2b, 0xb5, 0xfe, 0x14, 0x29, 0xf9, 0xf3, 0xc1, 0x4c, 0x65, 0xe3, 0x19, 0x4b, 0xf6, 0x1b, 0x82, 0xaa, 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0xcf, 0xd9, 0x06}, SECP256K1_FE_CONST(0x16d0e439, 0x46aec93f, 0x62d57eb8, 0xcde68951, 0xaf136cf4, 0xb307938d, 0xd1447411, 0xe07bffe1), 1}, + {{0x1f, 0x67, 0xed, 0xf7, 0x79, 0xa8, 0xa6, 0x49, 0xd6, 0xde, 0xf6, 0x00, 0x35, 0xf2, 0xfa, 0x22, 0xd0, 0x22, 0xdd, 0x35, 0x90, 0x79, 0xa1, 0xa1, 0x44, 0x07, 0x3d, 0x84, 0xf1, 0x9b, 0x92, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x025661f9, 0xaba9d15c, 0x3118456b, 0xbe980e3e, 0x1b8ba2e0, 0x47c737a4, 0xeb48a040, 0xbb566f6c), 0}, + {{0x1f, 0x67, 0xed, 0xf7, 0x79, 0xa8, 0xa6, 0x49, 0xd6, 0xde, 0xf6, 0x00, 0x35, 0xf2, 0xfa, 0x22, 0xd0, 0x22, 0xdd, 0x35, 0x90, 0x79, 0xa1, 0xa1, 0x44, 0x07, 0x3d, 0x84, 0xf1, 0x9b, 0x92, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x025661f9, 0xaba9d15c, 0x3118456b, 0xbe980e3e, 0x1b8ba2e0, 0x47c737a4, 0xeb48a040, 0xbb566f6c), 0}, + {{0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x98bec3b2, 0xa351fa96, 0xcfd191c1, 0x77835193, 0x1b9e9ba9, 0xad1149f6, 0xd9eadca8, 0x0981b801), 0}, + {{0x40, 0x56, 0xa3, 0x4a, 0x21, 0x0e, 0xec, 0x78, 0x92, 0xe8, 0x82, 0x06, 0x75, 0xc8, 0x60, 0x09, 0x9f, 0x85, 0x7b, 0x26, 0xaa, 0xd8, 0x54, 0x70, 0xee, 0x6d, 0x3c, 0xf1, 0x30, 0x4a, 0x9d, 0xcf, 0x37, 0x5e, 0x70, 0x37, 0x42, 0x71, 0xf2, 0x0b, 0x13, 0xc9, 0x98, 0x6e, 0xd7, 0xd3, 0xc1, 0x77, 0x99, 0x69, 0x8c, 0xfc, 0x43, 0x5d, 0xbe, 0xd3, 0xa9, 0xf3, 0x4b, 0x38, 0xc8, 0x23, 0xc2, 0xb4}, SECP256K1_FE_CONST(0x868aac20, 0x03b29dbc, 0xad1a3e80, 0x3855e078, 0xa89d1654, 0x3ac64392, 0xd1224172, 0x98cec76e), 0}, + {{0x41, 0x97, 0xec, 0x37, 0x23, 0xc6, 0x54, 0xcf, 0xdd, 0x32, 0xab, 0x07, 0x55, 0x06, 0x64, 0x8b, 0x2f, 0xf5, 0x07, 0x03, 0x62, 0xd0, 0x1a, 0x4f, 0xff, 0x14, 0xb3, 0x36, 0xb7, 0x8f, 0x96, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb3, 0xab, 0x1e, 0x95}, SECP256K1_FE_CONST(0xba5a6314, 0x502a8952, 0xb8f456e0, 0x85928105, 0xf665377a, 0x8ce27726, 0xa5b0eb7e, 0xc1ac0286), 0}, + {{0x47, 0xeb, 0x3e, 0x20, 0x8f, 0xed, 0xcd, 0xf8, 0x23, 0x4c, 0x94, 0x21, 0xe9, 0xcd, 0x9a, 0x7a, 0xe8, 0x73, 0xbf, 0xbd, 0xbc, 0x39, 0x37, 0x23, 0xd1, 0xba, 0x1e, 0x1e, 0x6a, 0x8e, 0x6b, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0xd1, 0x2c, 0xb1}, SECP256K1_FE_CONST(0xd192d520, 0x07e541c9, 0x807006ed, 0x0468df77, 0xfd214af0, 0xa795fe11, 0x9359666f, 0xdcf08f7c), 0}, + {{0x5e, 0xb9, 0x69, 0x6a, 0x23, 0x36, 0xfe, 0x2c, 0x3c, 0x66, 0x6b, 0x02, 0xc7, 0x55, 0xdb, 0x4c, 0x0c, 0xfd, 0x62, 0x82, 0x5c, 0x7b, 0x58, 0x9a, 0x7b, 0x7b, 0xb4, 0x42, 0xe1, 0x41, 0xc1, 0xd6, 0x93, 0x41, 0x3f, 0x00, 0x52, 0xd4, 0x9e, 0x64, 0xab, 0xec, 0x6d, 0x58, 0x31, 0xd6, 0x6c, 0x43, 0x61, 0x28, 0x30, 0xa1, 0x7d, 0xf1, 0xfe, 0x43, 0x83, 0xdb, 0x89, 0x64, 0x68, 0x10, 0x02, 0x21}, SECP256K1_FE_CONST(0xef6e1da6, 0xd6c7627e, 0x80f7a723, 0x4cb08a02, 0x2c1ee1cf, 0x29e4d0f9, 0x642ae924, 0xcef9eb38), 1}, + {{0x7b, 0xf9, 0x6b, 0x7b, 0x6d, 0xa1, 0x5d, 0x34, 0x76, 0xa2, 0xb1, 0x95, 0x93, 0x4b, 0x69, 0x0a, 0x3a, 0x3d, 0xe3, 0xe8, 0xab, 0x84, 0x74, 0x85, 0x68, 0x63, 0xb0, 0xde, 0x3a, 0xf9, 0x0b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x50851dfc, 0x9f418c31, 0x4a437295, 0xb24feeea, 0x27af3d0c, 0xd2308348, 0xfda6e21c, 0x463e46ff), 0}, + {{0x7b, 0xf9, 0x6b, 0x7b, 0x6d, 0xa1, 0x5d, 0x34, 0x76, 0xa2, 0xb1, 0x95, 0x93, 0x4b, 0x69, 0x0a, 0x3a, 0x3d, 0xe3, 0xe8, 0xab, 0x84, 0x74, 0x85, 0x68, 0x63, 0xb0, 0xde, 0x3a, 0xf9, 0x0b, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x50851dfc, 0x9f418c31, 0x4a437295, 0xb24feeea, 0x27af3d0c, 0xd2308348, 0xfda6e21c, 0x463e46ff), 0}, + {{0x85, 0x1b, 0x1c, 0xa9, 0x45, 0x49, 0x37, 0x1c, 0x4f, 0x1f, 0x71, 0x87, 0x32, 0x1d, 0x39, 0xbf, 0x51, 0xc6, 0xb7, 0xfb, 0x61, 0xf7, 0xcb, 0xf0, 0x27, 0xc9, 0xda, 0x62, 0x02, 0x1b, 0x7a, 0x65, 0xfc, 0x54, 0xc9, 0x68, 0x37, 0xfb, 0x22, 0xb3, 0x62, 0xed, 0xa6, 0x3e, 0xc5, 0x2e, 0xc8, 0x3d, 0x81, 0xbe, 0xdd, 0x16, 0x0c, 0x11, 0xb2, 0x2d, 0x96, 0x5d, 0x9f, 0x4a, 0x6d, 0x64, 0xd2, 0x51}, SECP256K1_FE_CONST(0x3e731051, 0xe12d3323, 0x7eb324f2, 0xaa5b16bb, 0x868eb49a, 0x1aa1fadc, 0x19b6e876, 0x1b5a5f7b), 1}, + {{0x94, 0x3c, 0x2f, 0x77, 0x51, 0x08, 0xb7, 0x37, 0xfe, 0x65, 0xa9, 0x53, 0x1e, 0x19, 0xf2, 0xfc, 0x2a, 0x19, 0x7f, 0x56, 0x03, 0xe3, 0xa2, 0x88, 0x1d, 0x1d, 0x83, 0xe4, 0x00, 0x8f, 0x91, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x311c61f0, 0xab2f32b7, 0xb1f0223f, 0xa72f0a78, 0x752b8146, 0xe46107f8, 0x876dd9c4, 0xf92b2942), 0}, + {{0x94, 0x3c, 0x2f, 0x77, 0x51, 0x08, 0xb7, 0x37, 0xfe, 0x65, 0xa9, 0x53, 0x1e, 0x19, 0xf2, 0xfc, 0x2a, 0x19, 0x7f, 0x56, 0x03, 0xe3, 0xa2, 0x88, 0x1d, 0x1d, 0x83, 0xe4, 0x00, 0x8f, 0x91, 0x25, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x311c61f0, 0xab2f32b7, 0xb1f0223f, 0xa72f0a78, 0x752b8146, 0xe46107f8, 0x876dd9c4, 0xf92b2942), 0}, + {{0xa0, 0xf1, 0x84, 0x92, 0x18, 0x3e, 0x61, 0xe8, 0x06, 0x3e, 0x57, 0x36, 0x06, 0x59, 0x14, 0x21, 0xb0, 0x6b, 0xc3, 0x51, 0x36, 0x31, 0x57, 0x8a, 0x73, 0xa3, 0x9c, 0x1c, 0x33, 0x06, 0x23, 0x9f, 0x2f, 0x32, 0x90, 0x4f, 0x0d, 0x2a, 0x33, 0xec, 0xca, 0x8a, 0x54, 0x51, 0x70, 0x5b, 0xb5, 0x37, 0xd3, 0xbf, 0x44, 0xe0, 0x71, 0x22, 0x60, 0x25, 0xcd, 0xbf, 0xd2, 0x49, 0xfe, 0x0f, 0x7a, 0xd6}, SECP256K1_FE_CONST(0x97a09cf1, 0xa2eae7c4, 0x94df3c6f, 0x8a9445bf, 0xb8c09d60, 0x832f9b0b, 0x9d5eabe2, 0x5fbd14b9), 0}, + {{0xa1, 0xed, 0x0a, 0x0b, 0xd7, 0x9d, 0x8a, 0x23, 0xcf, 0xe4, 0xec, 0x5f, 0xef, 0x5b, 0xa5, 0xcc, 0xcf, 0xd8, 0x44, 0xe4, 0xff, 0x5c, 0xb4, 0xb0, 0xf2, 0xe7, 0x16, 0x27, 0x34, 0x1f, 0x1c, 0x5b, 0x17, 0xc4, 0x99, 0x24, 0x9e, 0x0a, 0xc0, 0x8d, 0x5d, 0x11, 0xea, 0x1c, 0x2c, 0x8c, 0xa7, 0x00, 0x16, 0x16, 0x55, 0x9a, 0x79, 0x94, 0xea, 0xde, 0xc9, 0xca, 0x10, 0xfb, 0x4b, 0x85, 0x16, 0xdc}, SECP256K1_FE_CONST(0x65a89640, 0x744192cd, 0xac64b2d2, 0x1ddf989c, 0xdac75007, 0x25b645be, 0xf8e2200a, 0xe39691f2), 0}, + {{0xba, 0x94, 0x59, 0x4a, 0x43, 0x27, 0x21, 0xaa, 0x35, 0x80, 0xb8, 0x4c, 0x16, 0x1d, 0x0d, 0x13, 0x4b, 0xc3, 0x54, 0xb6, 0x90, 0x40, 0x4d, 0x7c, 0xd4, 0xec, 0x57, 0xc1, 0x6d, 0x3f, 0xbe, 0x98, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xea, 0x50, 0x7d, 0xd7}, SECP256K1_FE_CONST(0x5e0d7656, 0x4aae92cb, 0x347e01a6, 0x2afd389a, 0x9aa401c7, 0x6c8dd227, 0x543dc9cd, 0x0efe685a), 0}, + {{0xbc, 0xaf, 0x72, 0x19, 0xf2, 0xf6, 0xfb, 0xf5, 0x5f, 0xe5, 0xe0, 0x62, 0xdc, 0xe0, 0xe4, 0x8c, 0x18, 0xf6, 0x81, 0x03, 0xf1, 0x0b, 0x81, 0x98, 0xe9, 0x74, 0xc1, 0x84, 0x75, 0x0e, 0x1b, 0xe3, 0x93, 0x20, 0x16, 0xcb, 0xf6, 0x9c, 0x44, 0x71, 0xbd, 0x1f, 0x65, 0x6c, 0x6a, 0x10, 0x7f, 0x19, 0x73, 0xde, 0x4a, 0xf7, 0x08, 0x6d, 0xb8, 0x97, 0x27, 0x70, 0x60, 0xe2, 0x56, 0x77, 0xf1, 0x9a}, SECP256K1_FE_CONST(0x2d97f96c, 0xac882dfe, 0x73dc44db, 0x6ce0f1d3, 0x1d624135, 0x8dd5d74e, 0xb3d3b500, 0x03d24c2b), 0}, + {{0xbc, 0xaf, 0x72, 0x19, 0xf2, 0xf6, 0xfb, 0xf5, 0x5f, 0xe5, 0xe0, 0x62, 0xdc, 0xe0, 0xe4, 0x8c, 0x18, 0xf6, 0x81, 0x03, 0xf1, 0x0b, 0x81, 0x98, 0xe9, 0x74, 0xc1, 0x84, 0x75, 0x0e, 0x1b, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x65, 0x07, 0xd0, 0x9a}, SECP256K1_FE_CONST(0xe7008afe, 0x6e8cbd50, 0x55df120b, 0xd748757c, 0x686dadb4, 0x1cce75e4, 0xaddcc5e0, 0x2ec02b44), 1}, + {{0xc5, 0x98, 0x1b, 0xae, 0x27, 0xfd, 0x84, 0x40, 0x1c, 0x72, 0xa1, 0x55, 0xe5, 0x70, 0x7f, 0xbb, 0x81, 0x1b, 0x2b, 0x62, 0x06, 0x45, 0xd1, 0x02, 0x8e, 0xa2, 0x70, 0xcb, 0xe0, 0xee, 0x22, 0x5d, 0x4b, 0x62, 0xaa, 0x4d, 0xca, 0x65, 0x06, 0xc1, 0xac, 0xdb, 0xec, 0xc0, 0x55, 0x25, 0x69, 0xb4, 0xb2, 0x14, 0x36, 0xa5, 0x69, 0x2e, 0x25, 0xd9, 0x0d, 0x3b, 0xc2, 0xeb, 0x7c, 0xe2, 0x40, 0x78}, SECP256K1_FE_CONST(0x948b40e7, 0x181713bc, 0x018ec170, 0x2d3d054d, 0x15746c59, 0xa7020730, 0xdd13ecf9, 0x85a010d7), 0}, + {{0xc8, 0x94, 0xce, 0x48, 0xbf, 0xec, 0x43, 0x30, 0x14, 0xb9, 0x31, 0xa6, 0xad, 0x42, 0x26, 0xd7, 0xdb, 0xd8, 0xea, 0xa7, 0xb6, 0xe3, 0xfa, 0xa8, 0xd0, 0xef, 0x94, 0x05, 0x2b, 0xcf, 0x8c, 0xff, 0x33, 0x6e, 0xeb, 0x39, 0x19, 0xe2, 0xb4, 0xef, 0xb7, 0x46, 0xc7, 0xf7, 0x1b, 0xbc, 0xa7, 0xe9, 0x38, 0x32, 0x30, 0xfb, 0xbc, 0x48, 0xff, 0xaf, 0xe7, 0x7e, 0x8b, 0xcc, 0x69, 0x54, 0x24, 0x71}, SECP256K1_FE_CONST(0xf1c91acd, 0xc2525330, 0xf9b53158, 0x434a4d43, 0xa1c547cf, 0xf29f1550, 0x6f5da4eb, 0x4fe8fa5a), 1}, + {{0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x872d81ed, 0x8831d999, 0x8b67cb71, 0x05243edb, 0xf86c10ed, 0xfebb786c, 0x110b02d0, 0x7b2e67cd), 0}, + {{0xd9, 0x17, 0xb7, 0x86, 0xda, 0xc3, 0x56, 0x70, 0xc3, 0x30, 0xc9, 0xc5, 0xae, 0x59, 0x71, 0xdf, 0xb4, 0x95, 0xc8, 0xae, 0x52, 0x3e, 0xd9, 0x7e, 0xe2, 0x42, 0x01, 0x17, 0xb1, 0x71, 0xf4, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x01, 0xf6, 0xf6}, SECP256K1_FE_CONST(0xe45b71e1, 0x10b831f2, 0xbdad8651, 0x994526e5, 0x8393fde4, 0x328b1ec0, 0x4d598971, 0x42584691), 1}, + {{0xe2, 0x8b, 0xd8, 0xf5, 0x92, 0x9b, 0x46, 0x7e, 0xb7, 0x0e, 0x04, 0x33, 0x23, 0x74, 0xff, 0xb7, 0xe7, 0x18, 0x02, 0x18, 0xad, 0x16, 0xea, 0xa4, 0x6b, 0x71, 0x61, 0xaa, 0x67, 0x9e, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x66b8c980, 0xa75c72e5, 0x98d383a3, 0x5a62879f, 0x844242ad, 0x1e73ff12, 0xedaa59f4, 0xe58632b5), 0}, + {{0xe2, 0x8b, 0xd8, 0xf5, 0x92, 0x9b, 0x46, 0x7e, 0xb7, 0x0e, 0x04, 0x33, 0x23, 0x74, 0xff, 0xb7, 0xe7, 0x18, 0x02, 0x18, 0xad, 0x16, 0xea, 0xa4, 0x6b, 0x71, 0x61, 0xaa, 0x67, 0x9e, 0xb4, 0x26, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x66b8c980, 0xa75c72e5, 0x98d383a3, 0x5a62879f, 0x844242ad, 0x1e73ff12, 0xedaa59f4, 0xe58632b5), 0}, + {{0xe7, 0xee, 0x58, 0x14, 0xc1, 0x70, 0x6b, 0xf8, 0xa8, 0x93, 0x96, 0xa9, 0xb0, 0x32, 0xbc, 0x01, 0x4c, 0x2c, 0xac, 0x9c, 0x12, 0x11, 0x27, 0xdb, 0xf6, 0xc9, 0x92, 0x78, 0xf8, 0xbb, 0x53, 0xd1, 0xdf, 0xd0, 0x4d, 0xbc, 0xda, 0x8e, 0x35, 0x24, 0x66, 0xb6, 0xfc, 0xd5, 0xf2, 0xde, 0xa3, 0xe1, 0x7d, 0x5e, 0x13, 0x31, 0x15, 0x88, 0x6e, 0xda, 0x20, 0xdb, 0x8a, 0x12, 0xb5, 0x4d, 0xe7, 0x1b}, SECP256K1_FE_CONST(0xe842c6e3, 0x529b2342, 0x70a5e977, 0x44edc34a, 0x04d7ba94, 0xe44b6d25, 0x23c9cf01, 0x95730a50), 1}, + {{0xf2, 0x92, 0xe4, 0x68, 0x25, 0xf9, 0x22, 0x5a, 0xd2, 0x3d, 0xc0, 0x57, 0xc1, 0xd9, 0x1c, 0x4f, 0x57, 0xfc, 0xb1, 0x38, 0x6f, 0x29, 0xef, 0x10, 0x48, 0x1c, 0xb1, 0xd2, 0x25, 0x18, 0x59, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x11, 0xc9, 0x89}, SECP256K1_FE_CONST(0x3cea2c53, 0xb8b01701, 0x66ac7da6, 0x7194694a, 0xdacc84d5, 0x6389225e, 0x330134da, 0xb85a4d55), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x01, 0xd3, 0x47, 0x5b, 0xf7, 0x65, 0x5b, 0x0f, 0xb2, 0xd8, 0x52, 0x92, 0x10, 0x35, 0xb2, 0xef, 0x60, 0x7f, 0x49, 0x06, 0x9b, 0x97, 0x45, 0x4e, 0x67, 0x95, 0x25, 0x10, 0x62, 0x74, 0x17, 0x71}, SECP256K1_FE_CONST(0xb5da00b7, 0x3cd65605, 0x20e7c364, 0x086e7cd2, 0x3a34bf60, 0xd0e707be, 0x9fc34d4c, 0xd5fdfa2c), 1}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee}, SECP256K1_FE_CONST(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaa9, 0xfffffd6b), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x82, 0x27, 0x7c, 0x4a, 0x71, 0xf9, 0xd2, 0x2e, 0x66, 0xec, 0xe5, 0x23, 0xf8, 0xfa, 0x08, 0x74, 0x1a, 0x7c, 0x09, 0x12, 0xc6, 0x6a, 0x69, 0xce, 0x68, 0x51, 0x4b, 0xfd, 0x35, 0x15, 0xb4, 0x9f}, SECP256K1_FE_CONST(0xf482f2e2, 0x41753ad0, 0xfb89150d, 0x8491dc1e, 0x34ff0b8a, 0xcfbb442c, 0xfe999e2e, 0x5e6fd1d2), 1}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x84, 0x21, 0xcc, 0x93, 0x0e, 0x77, 0xc9, 0xf5, 0x14, 0xb6, 0x91, 0x5c, 0x3d, 0xbe, 0x2a, 0x94, 0xc6, 0xd8, 0xf6, 0x90, 0xb5, 0xb7, 0x39, 0x86, 0x4b, 0xa6, 0x78, 0x9f, 0xb8, 0xa5, 0x5d, 0xd0}, SECP256K1_FE_CONST(0x9f59c402, 0x75f5085a, 0x006f05da, 0xe77eb98c, 0x6fd0db1a, 0xb4a72ac4, 0x7eae90a4, 0xfc9e57e0), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xd1, 0x9c, 0x18, 0x2d, 0x27, 0x59, 0xcd, 0x99, 0x82, 0x42, 0x28, 0xd9, 0x47, 0x99, 0xf8, 0xc6, 0x55, 0x7c, 0x38, 0xa1, 0xc0, 0xd6, 0x77, 0x9b, 0x9d, 0x4b, 0x72, 0x9c, 0x6f, 0x1c, 0xcc, 0x42}, SECP256K1_FE_CONST(0x70720db7, 0xe238d041, 0x21f5b1af, 0xd8cc5ad9, 0xd18944c6, 0xbdc94881, 0xf502b7a3, 0xaf3aecff), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x64, 0xbb, 0xd5}, SECP256K1_FE_CONST(0x50873db3, 0x1badcc71, 0x890e4f67, 0x753a6575, 0x7f97aaa7, 0xdd5f1e82, 0xb753ace3, 0x2219064b), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x28, 0xde, 0x7d}, SECP256K1_FE_CONST(0x1eea9cc5, 0x9cfcf2fa, 0x151ac6c2, 0x74eea411, 0x0feb4f7b, 0x68c59657, 0x32e9992e, 0x976ef68e), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xcf, 0xb7, 0xe7}, SECP256K1_FE_CONST(0x12303941, 0xaedc2088, 0x80735b1f, 0x1795c8e5, 0x5be520ea, 0x93e10335, 0x7b5d2adb, 0x7ed59b8e), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x11, 0x3a, 0xd9}, SECP256K1_FE_CONST(0x7eed6b70, 0xe7b0767c, 0x7d7feac0, 0x4e57aa2a, 0x12fef5e0, 0xf48f878f, 0xcbb88b3b, 0x6b5e0783), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xce, 0xa4, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x64998443, 0x5b62b4a2, 0x5d40c613, 0x3e8d9ab8, 0xc53d4b05, 0x9ee8a154, 0xa3be0fcf, 0x4e892edb), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xce, 0xa4, 0xa7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x64998443, 0x5b62b4a2, 0x5d40c613, 0x3e8d9ab8, 0xc53d4b05, 0x9ee8a154, 0xa3be0fcf, 0x4e892edb), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x02, 0x8c, 0x59, 0x00, 0x63, 0xf6, 0x4d, 0x5a, 0x7f, 0x1c, 0x14, 0x91, 0x5c, 0xd6, 0x1e, 0xac, 0x88, 0x6a, 0xb2, 0x95, 0xbe, 0xbd, 0x91, 0x99, 0x25, 0x04, 0xcf, 0x77, 0xed, 0xb0, 0x28, 0xbd, 0xd6, 0x26, 0x7f}, SECP256K1_FE_CONST(0x3fde5713, 0xf8282eea, 0xd7d39d42, 0x01f44a7c, 0x85a5ac8a, 0x0681f35e, 0x54085c6b, 0x69543374), 1}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x27, 0x15, 0xde, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x3524f77f, 0xa3a6eb43, 0x89c3cb5d, 0x27f1f914, 0x62086429, 0xcd6c0cb0, 0xdf43ea8f, 0x1e7b3fb4), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x27, 0x15, 0xde, 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x3524f77f, 0xa3a6eb43, 0x89c3cb5d, 0x27f1f914, 0x62086429, 0xcd6c0cb0, 0xdf43ea8f, 0x1e7b3fb4), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2c, 0x2c, 0x57, 0x09, 0xe7, 0x15, 0x6c, 0x41, 0x77, 0x17, 0xf2, 0xfe, 0xab, 0x14, 0x71, 0x41, 0xec, 0x3d, 0xa1, 0x9f, 0xb7, 0x59, 0x57, 0x5c, 0xc6, 0xe3, 0x7b, 0x2e, 0xa5, 0xac, 0x93, 0x09, 0xf2, 0x6f, 0x0f, 0x66}, SECP256K1_FE_CONST(0xd2469ab3, 0xe04acbb2, 0x1c65a180, 0x9f39caaf, 0xe7a77c13, 0xd10f9dd3, 0x8f391c01, 0xdc499c52), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3a, 0x08, 0xcc, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x60, 0xe9, 0xf0}, SECP256K1_FE_CONST(0x38e2a5ce, 0x6a93e795, 0xe16d2c39, 0x8bc99f03, 0x69202ce2, 0x1e8f09d5, 0x6777b40f, 0xc512bccc), 1}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0x91, 0x25, 0x7d, 0x93, 0x20, 0x16, 0xcb, 0xf6, 0x9c, 0x44, 0x71, 0xbd, 0x1f, 0x65, 0x6c, 0x6a, 0x10, 0x7f, 0x19, 0x73, 0xde, 0x4a, 0xf7, 0x08, 0x6d, 0xb8, 0x97, 0x27, 0x70, 0x60, 0xe2, 0x56, 0x77, 0xf1, 0x9a}, SECP256K1_FE_CONST(0x864b3dc9, 0x02c37670, 0x9c10a93a, 0xd4bbe29f, 0xce0012f3, 0xdc8672c6, 0x286bba28, 0xd7d6d6fc), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x79, 0x5d, 0x6c, 0x1c, 0x32, 0x2c, 0xad, 0xf5, 0x99, 0xdb, 0xb8, 0x64, 0x81, 0x52, 0x2b, 0x3c, 0xc5, 0x5f, 0x15, 0xa6, 0x79, 0x32, 0xdb, 0x2a, 0xfa, 0x01, 0x11, 0xd9, 0xed, 0x69, 0x81, 0xbc, 0xd1, 0x24, 0xbf, 0x44}, SECP256K1_FE_CONST(0x766dfe4a, 0x700d9bee, 0x288b903a, 0xd58870e3, 0xd4fe2f0e, 0xf780bcac, 0x5c823f32, 0x0d9a9bef), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8e, 0x42, 0x6f, 0x03, 0x92, 0x38, 0x90, 0x78, 0xc1, 0x2b, 0x1a, 0x89, 0xe9, 0x54, 0x2f, 0x05, 0x93, 0xbc, 0x96, 0xb6, 0xbf, 0xde, 0x82, 0x24, 0xf8, 0x65, 0x4e, 0xf5, 0xd5, 0xcd, 0xa9, 0x35, 0xa3, 0x58, 0x21, 0x94}, SECP256K1_FE_CONST(0xfaec7bc1, 0x987b6323, 0x3fbc5f95, 0x6edbf37d, 0x54404e74, 0x61c58ab8, 0x631bc68e, 0x451a0478), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x91, 0x19, 0x21, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x45, 0xf0, 0xf1, 0xeb}, SECP256K1_FE_CONST(0xec29a50b, 0xae138dbf, 0x7d8e2482, 0x5006bb5f, 0xc1a2cc12, 0x43ba335b, 0xc6116fb9, 0xe498ec1f), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xeb, 0x9a, 0xb7, 0x6e, 0x84, 0x49, 0x9c, 0x48, 0x3b, 0x3b, 0xf0, 0x62, 0x14, 0xab, 0xfe, 0x06, 0x5d, 0xdd, 0xf4, 0x3b, 0x86, 0x01, 0xde, 0x59, 0x6d, 0x63, 0xb9, 0xe4, 0x5a, 0x16, 0x6a, 0x58, 0x05, 0x41, 0xfe}, SECP256K1_FE_CONST(0x1e0ff2de, 0xe9b09b13, 0x6292a9e9, 0x10f0d6ac, 0x3e552a64, 0x4bba39e6, 0x4e9dd3e3, 0xbbd3d4d4), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9b, 0x77, 0xb7, 0xf2, 0xc7, 0x4d, 0x99, 0xef, 0xce, 0xaa, 0x55, 0x0f, 0x1a, 0xd1, 0xc0, 0xf4, 0x3f, 0x46, 0xe7, 0xff, 0x1e, 0xe3, 0xbd, 0x01, 0x62, 0xb7, 0xbf, 0x55, 0xf2, 0x96, 0x5d, 0xa9, 0xc3, 0x45, 0x06, 0x46}, SECP256K1_FE_CONST(0x8b7dd5c3, 0xedba9ee9, 0x7b70eff4, 0x38f22dca, 0x9849c825, 0x4a2f3345, 0xa0a572ff, 0xeaae0928), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9b, 0x77, 0xb7, 0xf2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x6c, 0xa8, 0x96}, SECP256K1_FE_CONST(0x0881950c, 0x8f51d6b9, 0xa6387465, 0xd5f12609, 0xef1bb254, 0x12a08a74, 0xcb2dfb20, 0x0c74bfbf), 1}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa2, 0xf5, 0xcd, 0x83, 0x88, 0x16, 0xc1, 0x6c, 0x4f, 0xe8, 0xa1, 0x66, 0x1d, 0x60, 0x6f, 0xdb, 0x13, 0xcf, 0x9a, 0xf0, 0x4b, 0x97, 0x9a, 0x2e, 0x15, 0x9a, 0x09, 0x40, 0x9e, 0xbc, 0x86, 0x45, 0xd5, 0x8f, 0xde, 0x02}, SECP256K1_FE_CONST(0x2f083207, 0xb9fd9b55, 0x0063c31c, 0xd62b8746, 0xbd543bdc, 0x5bbf10e3, 0xa35563e9, 0x27f440c8), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x3f, 0x75, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x4f51e0be, 0x078e0cdd, 0xab274215, 0x6adba7e7, 0xa148e731, 0x57072fd6, 0x18cd6094, 0x2b146bd0), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x3f, 0x75, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x4f51e0be, 0x078e0cdd, 0xab274215, 0x6adba7e7, 0xa148e731, 0x57072fd6, 0x18cd6094, 0x2b146bd0), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xbc, 0x1f, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x16c2ccb5, 0x4352ff4b, 0xd794f6ef, 0xd613c721, 0x97ab7082, 0xda5b563b, 0xdf9cb3ed, 0xaafe74c2), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xbc, 0x1f, 0x8d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x16c2ccb5, 0x4352ff4b, 0xd794f6ef, 0xd613c721, 0x97ab7082, 0xda5b563b, 0xdf9cb3ed, 0xaafe74c2), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x64, 0xd1, 0x62, 0x75, 0x05, 0x46, 0xce, 0x42, 0xb0, 0x43, 0x13, 0x61, 0xe5, 0x2d, 0x4f, 0x52, 0x42, 0xd8, 0xf2, 0x4f, 0x33, 0xe6, 0xb1, 0xf9, 0x9b, 0x59, 0x16, 0x47, 0xcb, 0xc8, 0x08, 0xf4, 0x62, 0xaf, 0x51}, SECP256K1_FE_CONST(0xd41244d1, 0x1ca4f652, 0x40687759, 0xf95ca9ef, 0xbab767ed, 0xedb38fd1, 0x8c36e18c, 0xd3b6f6a9), 1}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe5, 0xbe, 0x52, 0x37, 0x2d, 0xd6, 0xe8, 0x94, 0xb2, 0xa3, 0x26, 0xfc, 0x36, 0x05, 0xa6, 0xe8, 0xf3, 0xc6, 0x9c, 0x71, 0x0b, 0xf2, 0x7d, 0x63, 0x0d, 0xfe, 0x20, 0x04, 0x98, 0x8b, 0x78, 0xeb, 0x6e, 0xab, 0x36}, SECP256K1_FE_CONST(0x64bf84dd, 0x5e03670f, 0xdb24c0f5, 0xd3c2c365, 0x736f51db, 0x6c92d950, 0x10716ad2, 0xd36134c8), 0}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfb, 0xb9, 0x82, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xd6, 0xdb, 0x1f}, SECP256K1_FE_CONST(0x1c92ccdf, 0xcf4ac550, 0xc28db57c, 0xff0c8515, 0xcb26936c, 0x786584a7, 0x0114008d, 0x6c33a34b), 0}, +}; + +/* Set of expected ellswift_xdh BIP324 shared secrets, given private key, encodings, initiating, + * taken from the BIP324 test vectors. Created using an independent implementation, and tested + * against the paper authors' decoding code. */ +static const struct ellswift_xdh_test ellswift_xdh_tests_bip324[] = { + {{0x61, 0x06, 0x2e, 0xa5, 0x07, 0x1d, 0x80, 0x0b, 0xbf, 0xd5, 0x9e, 0x2e, 0x8b, 0x53, 0xd4, 0x7d, 0x19, 0x4b, 0x09, 0x5a, 0xe5, 0xa4, 0xdf, 0x04, 0x93, 0x6b, 0x49, 0x77, 0x2e, 0xf0, 0xd4, 0xd7}, {0xec, 0x0a, 0xdf, 0xf2, 0x57, 0xbb, 0xfe, 0x50, 0x0c, 0x18, 0x8c, 0x80, 0xb4, 0xfd, 0xd6, 0x40, 0xf6, 0xb4, 0x5a, 0x48, 0x2b, 0xbc, 0x15, 0xfc, 0x7c, 0xef, 0x59, 0x31, 0xde, 0xff, 0x0a, 0xa1, 0x86, 0xf6, 0xeb, 0x9b, 0xba, 0x7b, 0x85, 0xdc, 0x4d, 0xcc, 0x28, 0xb2, 0x87, 0x22, 0xde, 0x1e, 0x3d, 0x91, 0x08, 0xb9, 0x85, 0xe2, 0x96, 0x70, 0x45, 0x66, 0x8f, 0x66, 0x09, 0x8e, 0x47, 0x5b}, {0xa4, 0xa9, 0x4d, 0xfc, 0xe6, 0x9b, 0x4a, 0x2a, 0x0a, 0x09, 0x93, 0x13, 0xd1, 0x0f, 0x9f, 0x7e, 0x7d, 0x64, 0x9d, 0x60, 0x50, 0x1c, 0x9e, 0x1d, 0x27, 0x4c, 0x30, 0x0e, 0x0d, 0x89, 0xaa, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xaf, 0x88, 0xd5}, 1, {0xc6, 0x99, 0x2a, 0x11, 0x7f, 0x5e, 0xdb, 0xea, 0x70, 0xc3, 0xf5, 0x11, 0xd3, 0x2d, 0x26, 0xb9, 0x79, 0x8b, 0xe4, 0xb8, 0x1a, 0x62, 0xea, 0xee, 0x1a, 0x5a, 0xca, 0xa8, 0x45, 0x9a, 0x35, 0x92}}, + {{0x1f, 0x9c, 0x58, 0x1b, 0x35, 0x23, 0x18, 0x38, 0xf0, 0xf1, 0x7c, 0xf0, 0xc9, 0x79, 0x83, 0x5b, 0xac, 0xcb, 0x7f, 0x3a, 0xbb, 0xbb, 0x96, 0xff, 0xcc, 0x31, 0x8a, 0xb7, 0x1e, 0x6e, 0x12, 0x6f}, {0xa1, 0x85, 0x5e, 0x10, 0xe9, 0x4e, 0x00, 0xba, 0xa2, 0x30, 0x41, 0xd9, 0x16, 0xe2, 0x59, 0xf7, 0x04, 0x4e, 0x49, 0x1d, 0xa6, 0x17, 0x12, 0x69, 0x69, 0x47, 0x63, 0xf0, 0x18, 0xc7, 0xe6, 0x36, 0x93, 0xd2, 0x95, 0x75, 0xdc, 0xb4, 0x64, 0xac, 0x81, 0x6b, 0xaa, 0x1b, 0xe3, 0x53, 0xba, 0x12, 0xe3, 0x87, 0x6c, 0xba, 0x76, 0x28, 0xbd, 0x0b, 0xd8, 0xe7, 0x55, 0xe7, 0x21, 0xeb, 0x01, 0x40}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0, {0xa0, 0x13, 0x8f, 0x56, 0x4f, 0x74, 0xd0, 0xad, 0x70, 0xbc, 0x33, 0x7d, 0xac, 0xc9, 0xd0, 0xbf, 0x1d, 0x23, 0x49, 0x36, 0x4c, 0xaf, 0x11, 0x88, 0xa1, 0xe6, 0xe8, 0xdd, 0xb3, 0xb7, 0xb1, 0x84}}, + {{0x02, 0x86, 0xc4, 0x1c, 0xd3, 0x09, 0x13, 0xdb, 0x0f, 0xdf, 0xf7, 0xa6, 0x4e, 0xbd, 0xa5, 0xc8, 0xe3, 0xe7, 0xce, 0xf1, 0x0f, 0x2a, 0xeb, 0xc0, 0x0a, 0x76, 0x50, 0x44, 0x3c, 0xf4, 0xc6, 0x0d}, {0xd1, 0xee, 0x8a, 0x93, 0xa0, 0x11, 0x30, 0xcb, 0xf2, 0x99, 0x24, 0x9a, 0x25, 0x8f, 0x94, 0xfe, 0xb5, 0xf4, 0x69, 0xe7, 0xd0, 0xf2, 0xf2, 0x8f, 0x69, 0xee, 0x5e, 0x9a, 0xa8, 0xf9, 0xb5, 0x4a, 0x60, 0xf2, 0xc3, 0xff, 0x2d, 0x02, 0x36, 0x34, 0xec, 0x7f, 0x41, 0x27, 0xa9, 0x6c, 0xc1, 0x16, 0x62, 0xe4, 0x02, 0x89, 0x4c, 0xf1, 0xf6, 0x94, 0xfb, 0x9a, 0x7e, 0xaa, 0x5f, 0x1d, 0x92, 0x44}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, 0xd5, 0xe4, 0x41, 0x52, 0x4d, 0x57, 0x1a, 0x52, 0xb3, 0xde, 0xf1, 0x26, 0x18, 0x9d, 0x3f, 0x41, 0x68, 0x90, 0xa9, 0x9d, 0x4d, 0xa6, 0xed, 0xe2, 0xb0, 0xcd, 0xe1, 0x76, 0x0c, 0xe2, 0xc3, 0xf9, 0x84, 0x57, 0xae}, 1, {0x25, 0x0b, 0x93, 0x57, 0x0d, 0x41, 0x11, 0x49, 0x10, 0x5a, 0xb8, 0xcb, 0x0b, 0xc5, 0x07, 0x99, 0x14, 0x90, 0x63, 0x06, 0x36, 0x8c, 0x23, 0xe9, 0xd7, 0x7c, 0x2a, 0x33, 0x26, 0x5b, 0x99, 0x4c}}, + {{0x6c, 0x77, 0x43, 0x2d, 0x1f, 0xda, 0x31, 0xe9, 0xf9, 0x42, 0xf8, 0xaf, 0x44, 0x60, 0x7e, 0x10, 0xf3, 0xad, 0x38, 0xa6, 0x5f, 0x8a, 0x4b, 0xdd, 0xae, 0x82, 0x3e, 0x5e, 0xff, 0x90, 0xdc, 0x38}, {0xd2, 0x68, 0x50, 0x70, 0xc1, 0xe6, 0x37, 0x6e, 0x63, 0x3e, 0x82, 0x52, 0x96, 0x63, 0x4f, 0xd4, 0x61, 0xfa, 0x9e, 0x5b, 0xdf, 0x21, 0x09, 0xbc, 0xeb, 0xd7, 0x35, 0xe5, 0xa9, 0x1f, 0x3e, 0x58, 0x7c, 0x5c, 0xb7, 0x82, 0xab, 0xb7, 0x97, 0xfb, 0xf6, 0xbb, 0x50, 0x74, 0xfd, 0x15, 0x42, 0xa4, 0x74, 0xf2, 0xa4, 0x5b, 0x67, 0x37, 0x63, 0xec, 0x2d, 0xb7, 0xfb, 0x99, 0xb7, 0x37, 0xbb, 0xb9}, {0x56, 0xbd, 0x0c, 0x06, 0xf1, 0x03, 0x52, 0xc3, 0xa1, 0xa9, 0xf4, 0xb4, 0xc9, 0x2f, 0x6f, 0xa2, 0xb2, 0x6d, 0xf1, 0x24, 0xb5, 0x78, 0x78, 0x35, 0x3c, 0x1f, 0xc6, 0x91, 0xc5, 0x1a, 0xbe, 0xa7, 0x7c, 0x88, 0x17, 0xda, 0xee, 0xb9, 0xfa, 0x54, 0x6b, 0x77, 0xc8, 0xda, 0xf7, 0x9d, 0x89, 0xb2, 0x2b, 0x0e, 0x1b, 0x87, 0x57, 0x4e, 0xce, 0x42, 0x37, 0x1f, 0x00, 0x23, 0x7a, 0xa9, 0xd8, 0x3a}, 0, {0x19, 0x18, 0xb7, 0x41, 0xef, 0x5f, 0x9d, 0x1d, 0x76, 0x70, 0xb0, 0x50, 0xc1, 0x52, 0xb4, 0xa4, 0xea, 0xd2, 0xc3, 0x1b, 0xe9, 0xae, 0xcb, 0x06, 0x81, 0xc0, 0xcd, 0x43, 0x24, 0x15, 0x08, 0x53}}, + {{0xa6, 0xec, 0x25, 0x12, 0x7c, 0xa1, 0xaa, 0x4c, 0xf1, 0x6b, 0x20, 0x08, 0x4b, 0xa1, 0xe6, 0x51, 0x6b, 0xaa, 0xe4, 0xd3, 0x24, 0x22, 0x28, 0x8e, 0x9b, 0x36, 0xd8, 0xbd, 0xdd, 0x2d, 0xe3, 0x5a}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x3d, 0x7e, 0xcc, 0xa5, 0x3e, 0x33, 0xe1, 0x85, 0xa8, 0xb9, 0xbe, 0x4e, 0x76, 0x99, 0xa9, 0x7c, 0x6f, 0xf4, 0xc7, 0x95, 0x52, 0x2e, 0x59, 0x18, 0xab, 0x7c, 0xd6, 0xb6, 0x88, 0x4f, 0x67, 0xe6, 0x83, 0xf3, 0xdc}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, 0x73, 0x0b, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 1, {0xdd, 0x21, 0x0a, 0xa6, 0x62, 0x9f, 0x20, 0xbb, 0x32, 0x8e, 0x5d, 0x89, 0xda, 0xa6, 0xeb, 0x2a, 0xc3, 0xd1, 0xc6, 0x58, 0xa7, 0x25, 0x53, 0x6f, 0xf1, 0x54, 0xf3, 0x1b, 0x53, 0x6c, 0x23, 0xb2}}, + {{0x0a, 0xf9, 0x52, 0x65, 0x9e, 0xd7, 0x6f, 0x80, 0xf5, 0x85, 0x96, 0x6b, 0x95, 0xab, 0x6e, 0x6f, 0xd6, 0x86, 0x54, 0x67, 0x28, 0x27, 0x87, 0x86, 0x84, 0xc8, 0xb5, 0x47, 0xb1, 0xb9, 0x4f, 0x5a}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x10, 0x17, 0xfd, 0x92, 0xfd, 0x31, 0x63, 0x7c, 0x26, 0xc9, 0x06, 0xb4, 0x20, 0x92, 0xe1, 0x1c, 0xc0, 0xd3, 0xaf, 0xae, 0x8d, 0x90, 0x19, 0xd2, 0x57, 0x8a, 0xf2, 0x27, 0x35, 0xce, 0x7b, 0xc4, 0x69, 0xc7, 0x2d}, {0x96, 0x52, 0xd7, 0x8b, 0xae, 0xfc, 0x02, 0x8c, 0xd3, 0x7a, 0x6a, 0x92, 0x62, 0x5b, 0x8b, 0x8f, 0x85, 0xfd, 0xe1, 0xe4, 0xc9, 0x44, 0xad, 0x3f, 0x20, 0xe1, 0x98, 0xbe, 0xf8, 0xc0, 0x2f, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xe9, 0x18, 0x70}, 0, {0x35, 0x68, 0xf2, 0xae, 0xa2, 0xe1, 0x4e, 0xf4, 0xee, 0x4a, 0x3c, 0x2a, 0x8b, 0x8d, 0x31, 0xbc, 0x5e, 0x31, 0x87, 0xba, 0x86, 0xdb, 0x10, 0x73, 0x9b, 0x4f, 0xf8, 0xec, 0x92, 0xff, 0x66, 0x55}}, + {{0xf9, 0x0e, 0x08, 0x0c, 0x64, 0xb0, 0x58, 0x24, 0xc5, 0xa2, 0x4b, 0x25, 0x01, 0xd5, 0xae, 0xaf, 0x08, 0xaf, 0x38, 0x72, 0xee, 0x86, 0x0a, 0xa8, 0x0b, 0xdc, 0xd4, 0x30, 0xf7, 0xb6, 0x34, 0x94}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x51, 0x73, 0x76, 0x5d, 0xc2, 0x02, 0xcf, 0x02, 0x9a, 0xd3, 0xf1, 0x54, 0x79, 0x73, 0x5d, 0x57, 0x69, 0x7a, 0xf1, 0x2b, 0x01, 0x31, 0xdd, 0x21, 0x43, 0x0d, 0x57, 0x72, 0xe4, 0xef, 0x11, 0x47, 0x4d, 0x58, 0xb9}, {0x12, 0xa5, 0x0f, 0x3f, 0xaf, 0xea, 0x7c, 0x1e, 0xea, 0xda, 0x4c, 0xf8, 0xd3, 0x37, 0x77, 0x70, 0x4b, 0x77, 0x36, 0x14, 0x53, 0xaf, 0xc8, 0x3b, 0xda, 0x91, 0xee, 0xf3, 0x49, 0xae, 0x04, 0x4d, 0x20, 0x12, 0x6c, 0x62, 0x00, 0x54, 0x7e, 0xa5, 0xa6, 0x91, 0x17, 0x76, 0xc0, 0x5d, 0xee, 0x2a, 0x7f, 0x1a, 0x9b, 0xa7, 0xdf, 0xba, 0xbb, 0xbd, 0x27, 0x3c, 0x3e, 0xf2, 0x9e, 0xf4, 0x6e, 0x46}, 1, {0xe2, 0x54, 0x61, 0xfb, 0x0e, 0x4c, 0x16, 0x2e, 0x18, 0x12, 0x3e, 0xcd, 0xe8, 0x83, 0x42, 0xd5, 0x4d, 0x44, 0x96, 0x31, 0xe9, 0xb7, 0x5a, 0x26, 0x6f, 0xd9, 0x26, 0x0c, 0x2b, 0xb2, 0xf4, 0x1d}}, +}; + +/** This is a hasher for ellswift_xdh which just returns the shared X coordinate. + * + * This is generally a bad idea as it means changes to the encoding of the + * exchanged public keys do not affect the shared secret. However, it's used here + * in tests to be able to verify the X coordinate through other means. + */ +static int ellswift_xdh_hash_x32(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { + (void)ell_a64; + (void)ell_b64; + (void)data; + memcpy(output, x32, 32); + return 1; +} + +void run_ellswift_tests(void) { + int i = 0; + /* Test vectors. */ + for (i = 0; (unsigned)i < sizeof(ellswift_xswiftec_inv_tests) / sizeof(ellswift_xswiftec_inv_tests[0]); ++i) { + const struct ellswift_xswiftec_inv_test *testcase = &ellswift_xswiftec_inv_tests[i]; + int c; + for (c = 0; c < 8; ++c) { + secp256k1_fe t; + int ret = secp256k1_ellswift_xswiftec_inv_var(&t, &testcase->x, &testcase->u, c); + CHECK(ret == ((testcase->enc_bitmap >> c) & 1)); + if (ret) { + secp256k1_fe x2; + CHECK(fe_equal(&t, &testcase->encs[c])); + secp256k1_ellswift_xswiftec_var(&x2, &testcase->u, &testcase->encs[c]); + CHECK(fe_equal(&testcase->x, &x2)); + } + } + } + for (i = 0; (unsigned)i < sizeof(ellswift_decode_tests) / sizeof(ellswift_decode_tests[0]); ++i) { + const struct ellswift_decode_test *testcase = &ellswift_decode_tests[i]; + secp256k1_pubkey pubkey; + secp256k1_ge ge; + int ret; + ret = secp256k1_ellswift_decode(CTX, &pubkey, testcase->enc); + CHECK(ret); + ret = secp256k1_pubkey_load(CTX, &ge, &pubkey); + CHECK(ret); + CHECK(fe_equal(&testcase->x, &ge.x)); + CHECK(secp256k1_fe_is_odd(&ge.y) == testcase->odd_y); + } + for (i = 0; (unsigned)i < sizeof(ellswift_xdh_tests_bip324) / sizeof(ellswift_xdh_tests_bip324[0]); ++i) { + const struct ellswift_xdh_test *test = &ellswift_xdh_tests_bip324[i]; + unsigned char shared_secret[32]; + int ret; + int party = !test->initiating; + const unsigned char* ell_a64 = party ? test->ellswift_theirs : test->ellswift_ours; + const unsigned char* ell_b64 = party ? test->ellswift_ours : test->ellswift_theirs; + ret = secp256k1_ellswift_xdh(CTX, shared_secret, + ell_a64, ell_b64, + test->priv_ours, + party, + secp256k1_ellswift_xdh_hash_function_bip324, + NULL); + CHECK(ret); + CHECK(secp256k1_memcmp_var(shared_secret, test->shared_secret, 32) == 0); + } + /* Verify that secp256k1_ellswift_encode + decode roundtrips. */ + for (i = 0; i < 1000 * COUNT; i++) { + unsigned char rnd32[32]; + unsigned char ell64[64]; + secp256k1_ge g, g2; + secp256k1_pubkey pubkey, pubkey2; + /* Generate random public key and random randomizer. */ + testutil_random_ge_test(&g); + secp256k1_pubkey_save(&pubkey, &g); + testrand256(rnd32); + /* Convert the public key to ElligatorSwift and back. */ + secp256k1_ellswift_encode(CTX, ell64, &pubkey, rnd32); + secp256k1_ellswift_decode(CTX, &pubkey2, ell64); + secp256k1_pubkey_load(CTX, &g2, &pubkey2); + /* Compare with original. */ + CHECK(secp256k1_ge_eq_var(&g, &g2)); + } + /* Verify the behavior of secp256k1_ellswift_create */ + for (i = 0; i < 400 * COUNT; i++) { + unsigned char auxrnd32[32], sec32[32]; + secp256k1_scalar sec; + secp256k1_gej res; + secp256k1_ge dec; + secp256k1_pubkey pub; + unsigned char ell64[64]; + int ret; + /* Generate random secret key and random randomizer. */ + if (i & 1) testrand256_test(auxrnd32); + testutil_random_scalar_order_test(&sec); + secp256k1_scalar_get_b32(sec32, &sec); + /* Construct ElligatorSwift-encoded public keys for that key. */ + ret = secp256k1_ellswift_create(CTX, ell64, sec32, (i & 1) ? auxrnd32 : NULL); + CHECK(ret); + /* Decode it, and compare with traditionally-computed public key. */ + secp256k1_ellswift_decode(CTX, &pub, ell64); + secp256k1_pubkey_load(CTX, &dec, &pub); + secp256k1_ecmult(&res, NULL, &secp256k1_scalar_zero, &sec); + CHECK(secp256k1_gej_eq_ge_var(&res, &dec)); + } + /* Verify that secp256k1_ellswift_xdh computes the right shared X coordinate. */ + for (i = 0; i < 800 * COUNT; i++) { + unsigned char ell64[64], sec32[32], share32[32]; + secp256k1_scalar sec; + secp256k1_ge dec, res; + secp256k1_fe share_x; + secp256k1_gej decj, resj; + secp256k1_pubkey pub; + int ret; + /* Generate random secret key. */ + testutil_random_scalar_order_test(&sec); + secp256k1_scalar_get_b32(sec32, &sec); + /* Generate random ElligatorSwift encoding for the remote key and decode it. */ + testrand256_test(ell64); + testrand256_test(ell64 + 32); + secp256k1_ellswift_decode(CTX, &pub, ell64); + secp256k1_pubkey_load(CTX, &dec, &pub); + secp256k1_gej_set_ge(&decj, &dec); + /* Compute the X coordinate of seckey*pubkey using ellswift_xdh. Note that we + * pass ell64 as claimed (but incorrect) encoding for sec32 here; this works + * because the "hasher" function we use here ignores the ell64 arguments. */ + ret = secp256k1_ellswift_xdh(CTX, share32, ell64, ell64, sec32, i & 1, &ellswift_xdh_hash_x32, NULL); + CHECK(ret); + (void)secp256k1_fe_set_b32_limit(&share_x, share32); /* no overflow is possible */ + SECP256K1_FE_VERIFY(&share_x); + /* Compute seckey*pubkey directly. */ + secp256k1_ecmult(&resj, &decj, &sec, NULL); + secp256k1_ge_set_gej(&res, &resj); + /* Compare. */ + CHECK(fe_equal(&res.x, &share_x)); + } + /* Verify the joint behavior of secp256k1_ellswift_xdh */ + for (i = 0; i < 200 * COUNT; i++) { + unsigned char auxrnd32a[32], auxrnd32b[32], auxrnd32a_bad[32], auxrnd32b_bad[32]; + unsigned char sec32a[32], sec32b[32], sec32a_bad[32], sec32b_bad[32]; + secp256k1_scalar seca, secb; + unsigned char ell64a[64], ell64b[64], ell64a_bad[64], ell64b_bad[64]; + unsigned char share32a[32], share32b[32], share32_bad[32]; + unsigned char prefix64[64]; + secp256k1_ellswift_xdh_hash_function hash_function; + void* data; + int ret; + + /* Pick hasher to use. */ + if ((i % 3) == 0) { + hash_function = ellswift_xdh_hash_x32; + data = NULL; + } else if ((i % 3) == 1) { + hash_function = secp256k1_ellswift_xdh_hash_function_bip324; + data = NULL; + } else { + hash_function = secp256k1_ellswift_xdh_hash_function_prefix; + testrand256_test(prefix64); + testrand256_test(prefix64 + 32); + data = prefix64; + } + + /* Generate random secret keys and random randomizers. */ + testrand256_test(auxrnd32a); + testrand256_test(auxrnd32b); + testutil_random_scalar_order_test(&seca); + /* Draw secb uniformly at random to make sure that the secret keys + * differ */ + testutil_random_scalar_order(&secb); + secp256k1_scalar_get_b32(sec32a, &seca); + secp256k1_scalar_get_b32(sec32b, &secb); + + /* Construct ElligatorSwift-encoded public keys for those keys. */ + /* For A: */ + ret = secp256k1_ellswift_create(CTX, ell64a, sec32a, auxrnd32a); + CHECK(ret); + /* For B: */ + ret = secp256k1_ellswift_create(CTX, ell64b, sec32b, auxrnd32b); + CHECK(ret); + + /* Compute the shared secret both ways and compare with each other. */ + /* For A: */ + ret = secp256k1_ellswift_xdh(CTX, share32a, ell64a, ell64b, sec32a, 0, hash_function, data); + CHECK(ret); + /* For B: */ + ret = secp256k1_ellswift_xdh(CTX, share32b, ell64a, ell64b, sec32b, 1, hash_function, data); + CHECK(ret); + /* And compare: */ + CHECK(secp256k1_memcmp_var(share32a, share32b, 32) == 0); + + /* Verify that the shared secret doesn't match if other side's public key is incorrect. */ + /* For A (using a bad public key for B): */ + memcpy(ell64b_bad, ell64b, sizeof(ell64a_bad)); + testrand_flip(ell64b_bad, sizeof(ell64b_bad)); + ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b_bad, sec32a, 0, hash_function, data); + CHECK(ret); /* Mismatching encodings don't get detected by secp256k1_ellswift_xdh. */ + CHECK(secp256k1_memcmp_var(share32_bad, share32a, 32) != 0); + /* For B (using a bad public key for A): */ + memcpy(ell64a_bad, ell64a, sizeof(ell64a_bad)); + testrand_flip(ell64a_bad, sizeof(ell64a_bad)); + ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a_bad, ell64b, sec32b, 1, hash_function, data); + CHECK(ret); + CHECK(secp256k1_memcmp_var(share32_bad, share32b, 32) != 0); + + /* Verify that the shared secret doesn't match if the private key is incorrect. */ + /* For A: */ + memcpy(sec32a_bad, sec32a, sizeof(sec32a_bad)); + testrand_flip(sec32a_bad, sizeof(sec32a_bad)); + ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32a_bad, 0, hash_function, data); + CHECK(!ret || secp256k1_memcmp_var(share32_bad, share32a, 32) != 0); + /* For B: */ + memcpy(sec32b_bad, sec32b, sizeof(sec32b_bad)); + testrand_flip(sec32b_bad, sizeof(sec32b_bad)); + ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32b_bad, 1, hash_function, data); + CHECK(!ret || secp256k1_memcmp_var(share32_bad, share32b, 32) != 0); + + if (hash_function != ellswift_xdh_hash_x32) { + /* Verify that the shared secret doesn't match when a different encoding of the same public key is used. */ + /* For A (changing B's public key): */ + memcpy(auxrnd32b_bad, auxrnd32b, sizeof(auxrnd32b_bad)); + testrand_flip(auxrnd32b_bad, sizeof(auxrnd32b_bad)); + ret = secp256k1_ellswift_create(CTX, ell64b_bad, sec32b, auxrnd32b_bad); + CHECK(ret); + ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b_bad, sec32a, 0, hash_function, data); + CHECK(ret); + CHECK(secp256k1_memcmp_var(share32_bad, share32a, 32) != 0); + /* For B (changing A's public key): */ + memcpy(auxrnd32a_bad, auxrnd32a, sizeof(auxrnd32a_bad)); + testrand_flip(auxrnd32a_bad, sizeof(auxrnd32a_bad)); + ret = secp256k1_ellswift_create(CTX, ell64a_bad, sec32a, auxrnd32a_bad); + CHECK(ret); + ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a_bad, ell64b, sec32b, 1, hash_function, data); + CHECK(ret); + CHECK(secp256k1_memcmp_var(share32_bad, share32b, 32) != 0); + + /* Verify that swapping sides changes the shared secret. */ + /* For A (claiming to be B): */ + ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32a, 1, hash_function, data); + CHECK(ret); + CHECK(secp256k1_memcmp_var(share32_bad, share32a, 32) != 0); + /* For B (claiming to be A): */ + ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32b, 0, hash_function, data); + CHECK(ret); + CHECK(secp256k1_memcmp_var(share32_bad, share32b, 32) != 0); + } + } + + /* Test hash initializers. */ + { + secp256k1_sha256 sha, sha_optimized; + static const unsigned char encode_tag[] = {'s', 'e', 'c', 'p', '2', '5', '6', 'k', '1', '_', 'e', 'l', 'l', 's', 'w', 'i', 'f', 't', '_', 'e', 'n', 'c', 'o', 'd', 'e'}; + static const unsigned char create_tag[] = {'s', 'e', 'c', 'p', '2', '5', '6', 'k', '1', '_', 'e', 'l', 'l', 's', 'w', 'i', 'f', 't', '_', 'c', 'r', 'e', 'a', 't', 'e'}; + static const unsigned char bip324_tag[] = {'b', 'i', 'p', '3', '2', '4', '_', 'e', 'l', 'l', 's', 'w', 'i', 'f', 't', '_', 'x', 'o', 'n', 'l', 'y', '_', 'e', 'c', 'd', 'h'}; + + /* Check that hash initialized by + * secp256k1_ellswift_sha256_init_encode has the expected + * state. */ + secp256k1_sha256_initialize_tagged(&sha, encode_tag, sizeof(encode_tag)); + secp256k1_ellswift_sha256_init_encode(&sha_optimized); + test_sha256_eq(&sha, &sha_optimized); + + /* Check that hash initialized by + * secp256k1_ellswift_sha256_init_create has the expected + * state. */ + secp256k1_sha256_initialize_tagged(&sha, create_tag, sizeof(create_tag)); + secp256k1_ellswift_sha256_init_create(&sha_optimized); + test_sha256_eq(&sha, &sha_optimized); + + /* Check that hash initialized by + * secp256k1_ellswift_sha256_init_bip324 has the expected + * state. */ + secp256k1_sha256_initialize_tagged(&sha, bip324_tag, sizeof(bip324_tag)); + secp256k1_ellswift_sha256_init_bip324(&sha_optimized); + test_sha256_eq(&sha, &sha_optimized); + } +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/Makefile.am.include b/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/Makefile.am.include new file mode 100644 index 0000000000..0d901ec1f4 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/Makefile.am.include @@ -0,0 +1,4 @@ +include_HEADERS += include/secp256k1_extrakeys.h +noinst_HEADERS += src/modules/extrakeys/tests_impl.h +noinst_HEADERS += src/modules/extrakeys/tests_exhaustive_impl.h +noinst_HEADERS += src/modules/extrakeys/main_impl.h diff --git a/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/main_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/main_impl.h new file mode 100644 index 0000000000..0c7e266777 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/main_impl.h @@ -0,0 +1,285 @@ +/*********************************************************************** + * Copyright (c) 2020 Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H +#define SECP256K1_MODULE_EXTRAKEYS_MAIN_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_extrakeys.h" +#include "../../util.h" + +static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context* ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey) { + return secp256k1_pubkey_load(ctx, ge, (const secp256k1_pubkey *) pubkey); +} + +static SECP256K1_INLINE void secp256k1_xonly_pubkey_save(secp256k1_xonly_pubkey *pubkey, secp256k1_ge *ge) { + secp256k1_pubkey_save((secp256k1_pubkey *) pubkey, ge); +} + +int secp256k1_xonly_pubkey_parse(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) { + secp256k1_ge pk; + secp256k1_fe x; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(input32 != NULL); + + if (!secp256k1_fe_set_b32_limit(&x, input32)) { + return 0; + } + if (!secp256k1_ge_set_xo_var(&pk, &x, 0)) { + return 0; + } + if (!secp256k1_ge_is_in_correct_subgroup(&pk)) { + return 0; + } + secp256k1_xonly_pubkey_save(pubkey, &pk); + return 1; +} + +int secp256k1_xonly_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output32, const secp256k1_xonly_pubkey *pubkey) { + secp256k1_ge pk; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output32 != NULL); + memset(output32, 0, 32); + ARG_CHECK(pubkey != NULL); + + if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) { + return 0; + } + secp256k1_fe_get_b32(output32, &pk.x); + return 1; +} + +int secp256k1_xonly_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_xonly_pubkey* pk0, const secp256k1_xonly_pubkey* pk1) { + unsigned char out[2][32]; + const secp256k1_xonly_pubkey* pk[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + pk[0] = pk0; pk[1] = pk1; + for (i = 0; i < 2; i++) { + /* If the public key is NULL or invalid, xonly_pubkey_serialize will + * call the illegal_callback and return 0. In that case we will + * serialize the key as all zeros which is less than any valid public + * key. This results in consistent comparisons even if NULL or invalid + * pubkeys are involved and prevents edge cases such as sorting + * algorithms that use this function and do not terminate as a + * result. */ + if (!secp256k1_xonly_pubkey_serialize(ctx, out[i], pk[i])) { + /* Note that xonly_pubkey_serialize should already set the output to + * zero in that case, but it's not guaranteed by the API, we can't + * test it and writing a VERIFY_CHECK is more complex than + * explicitly memsetting (again). */ + memset(out[i], 0, sizeof(out[i])); + } + } + return secp256k1_memcmp_var(out[0], out[1], sizeof(out[1])); +} + +/** Keeps a group element as is if it has an even Y and otherwise negates it. + * y_parity is set to 0 in the former case and to 1 in the latter case. + * Requires that the coordinates of r are normalized. */ +static int secp256k1_extrakeys_ge_even_y(secp256k1_ge *r) { + int y_parity = 0; + VERIFY_CHECK(!secp256k1_ge_is_infinity(r)); + + if (secp256k1_fe_is_odd(&r->y)) { + secp256k1_fe_negate(&r->y, &r->y, 1); + y_parity = 1; + } + return y_parity; +} + +int secp256k1_xonly_pubkey_from_pubkey(const secp256k1_context* ctx, secp256k1_xonly_pubkey *xonly_pubkey, int *pk_parity, const secp256k1_pubkey *pubkey) { + secp256k1_ge pk; + int tmp; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(xonly_pubkey != NULL); + ARG_CHECK(pubkey != NULL); + + if (!secp256k1_pubkey_load(ctx, &pk, pubkey)) { + return 0; + } + tmp = secp256k1_extrakeys_ge_even_y(&pk); + if (pk_parity != NULL) { + *pk_parity = tmp; + } + secp256k1_xonly_pubkey_save(xonly_pubkey, &pk); + return 1; +} + +int secp256k1_xonly_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) { + secp256k1_ge pk; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output_pubkey != NULL); + memset(output_pubkey, 0, sizeof(*output_pubkey)); + ARG_CHECK(internal_pubkey != NULL); + ARG_CHECK(tweak32 != NULL); + + if (!secp256k1_xonly_pubkey_load(ctx, &pk, internal_pubkey) + || !secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32)) { + return 0; + } + secp256k1_pubkey_save(output_pubkey, &pk); + return 1; +} + +int secp256k1_xonly_pubkey_tweak_add_check(const secp256k1_context* ctx, const unsigned char *tweaked_pubkey32, int tweaked_pk_parity, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) { + secp256k1_ge pk; + unsigned char pk_expected32[32]; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(internal_pubkey != NULL); + ARG_CHECK(tweaked_pubkey32 != NULL); + ARG_CHECK(tweak32 != NULL); + + if (!secp256k1_xonly_pubkey_load(ctx, &pk, internal_pubkey) + || !secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32)) { + return 0; + } + secp256k1_fe_normalize_var(&pk.x); + secp256k1_fe_normalize_var(&pk.y); + secp256k1_fe_get_b32(pk_expected32, &pk.x); + + return secp256k1_memcmp_var(&pk_expected32, tweaked_pubkey32, 32) == 0 + && secp256k1_fe_is_odd(&pk.y) == tweaked_pk_parity; +} + +static void secp256k1_keypair_save(secp256k1_keypair *keypair, const secp256k1_scalar *sk, secp256k1_ge *pk) { + secp256k1_scalar_get_b32(&keypair->data[0], sk); + secp256k1_pubkey_save((secp256k1_pubkey *)&keypair->data[32], pk); +} + + +static int secp256k1_keypair_seckey_load(const secp256k1_context* ctx, secp256k1_scalar *sk, const secp256k1_keypair *keypair) { + int ret; + + ret = secp256k1_scalar_set_b32_seckey(sk, &keypair->data[0]); + /* We can declassify ret here because sk is only zero if a keypair function + * failed (which zeroes the keypair) and its return value is ignored. */ + secp256k1_declassify(ctx, &ret, sizeof(ret)); + ARG_CHECK(ret); + return ret; +} + +/* Load a keypair into pk and sk (if non-NULL). This function declassifies pk + * and ARG_CHECKs that the keypair is not invalid. It always initializes sk and + * pk with dummy values. */ +static int secp256k1_keypair_load(const secp256k1_context* ctx, secp256k1_scalar *sk, secp256k1_ge *pk, const secp256k1_keypair *keypair) { + int ret; + const secp256k1_pubkey *pubkey = (const secp256k1_pubkey *)&keypair->data[32]; + + /* Need to declassify the pubkey because pubkey_load ARG_CHECKs if it's + * invalid. */ + secp256k1_declassify(ctx, pubkey, sizeof(*pubkey)); + ret = secp256k1_pubkey_load(ctx, pk, pubkey); + if (sk != NULL) { + ret = ret && secp256k1_keypair_seckey_load(ctx, sk, keypair); + } + if (!ret) { + *pk = secp256k1_ge_const_g; + if (sk != NULL) { + *sk = secp256k1_scalar_one; + } + } + return ret; +} + +int secp256k1_keypair_create(const secp256k1_context* ctx, secp256k1_keypair *keypair, const unsigned char *seckey32) { + secp256k1_scalar sk; + secp256k1_ge pk; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(keypair != NULL); + memset(keypair, 0, sizeof(*keypair)); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(seckey32 != NULL); + + ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &sk, &pk, seckey32); + secp256k1_keypair_save(keypair, &sk, &pk); + secp256k1_memczero(keypair, sizeof(*keypair), !ret); + + secp256k1_scalar_clear(&sk); + return ret; +} + +int secp256k1_keypair_sec(const secp256k1_context* ctx, unsigned char *seckey, const secp256k1_keypair *keypair) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + memset(seckey, 0, 32); + ARG_CHECK(keypair != NULL); + + memcpy(seckey, &keypair->data[0], 32); + return 1; +} + +int secp256k1_keypair_pub(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_keypair *keypair) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(keypair != NULL); + + memcpy(pubkey->data, &keypair->data[32], sizeof(*pubkey)); + return 1; +} + +int secp256k1_keypair_xonly_pub(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pubkey, int *pk_parity, const secp256k1_keypair *keypair) { + secp256k1_ge pk; + int tmp; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(keypair != NULL); + + if (!secp256k1_keypair_load(ctx, NULL, &pk, keypair)) { + return 0; + } + tmp = secp256k1_extrakeys_ge_even_y(&pk); + if (pk_parity != NULL) { + *pk_parity = tmp; + } + secp256k1_xonly_pubkey_save(pubkey, &pk); + + return 1; +} + +int secp256k1_keypair_xonly_tweak_add(const secp256k1_context* ctx, secp256k1_keypair *keypair, const unsigned char *tweak32) { + secp256k1_ge pk; + secp256k1_scalar sk; + int y_parity; + int ret; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(keypair != NULL); + ARG_CHECK(tweak32 != NULL); + + ret = secp256k1_keypair_load(ctx, &sk, &pk, keypair); + memset(keypair, 0, sizeof(*keypair)); + + y_parity = secp256k1_extrakeys_ge_even_y(&pk); + if (y_parity == 1) { + secp256k1_scalar_negate(&sk, &sk); + } + + ret &= secp256k1_ec_seckey_tweak_add_helper(&sk, tweak32); + ret &= secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32); + + secp256k1_declassify(ctx, &ret, sizeof(ret)); + if (ret) { + secp256k1_keypair_save(keypair, &sk, &pk); + } + + secp256k1_scalar_clear(&sk); + return ret; +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/tests_exhaustive_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/tests_exhaustive_impl.h new file mode 100644 index 0000000000..645bae2d47 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/tests_exhaustive_impl.h @@ -0,0 +1,68 @@ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H +#define SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H + +#include "../../../include/secp256k1_extrakeys.h" +#include "main_impl.h" + +static void test_exhaustive_extrakeys(const secp256k1_context *ctx, const secp256k1_ge* group) { + secp256k1_keypair keypair[EXHAUSTIVE_TEST_ORDER - 1]; + secp256k1_pubkey pubkey[EXHAUSTIVE_TEST_ORDER - 1]; + secp256k1_xonly_pubkey xonly_pubkey[EXHAUSTIVE_TEST_ORDER - 1]; + int parities[EXHAUSTIVE_TEST_ORDER - 1]; + unsigned char xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - 1][32]; + int i; + + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { + secp256k1_fe fe; + secp256k1_scalar scalar_i; + unsigned char buf[33]; + int parity; + + secp256k1_scalar_set_int(&scalar_i, i); + secp256k1_scalar_get_b32(buf, &scalar_i); + + /* Construct pubkey and keypair. */ + CHECK(secp256k1_keypair_create(ctx, &keypair[i - 1], buf)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey[i - 1], buf)); + + /* Construct serialized xonly_pubkey from keypair. */ + CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pubkey[i - 1], &parities[i - 1], &keypair[i - 1])); + CHECK(secp256k1_xonly_pubkey_serialize(ctx, xonly_pubkey_bytes[i - 1], &xonly_pubkey[i - 1])); + + /* Parse the xonly_pubkey back and verify it matches the previously serialized value. */ + CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pubkey[i - 1], xonly_pubkey_bytes[i - 1])); + CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf, &xonly_pubkey[i - 1])); + CHECK(secp256k1_memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0); + + /* Construct the xonly_pubkey from the pubkey, and verify it matches the same. */ + CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pubkey[i - 1], &parity, &pubkey[i - 1])); + CHECK(parity == parities[i - 1]); + CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf, &xonly_pubkey[i - 1])); + CHECK(secp256k1_memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0); + + /* Compare the xonly_pubkey bytes against the precomputed group. */ + secp256k1_fe_set_b32_mod(&fe, xonly_pubkey_bytes[i - 1]); + CHECK(secp256k1_fe_equal(&fe, &group[i].x)); + + /* Check the parity against the precomputed group. */ + fe = group[i].y; + secp256k1_fe_normalize_var(&fe); + CHECK(secp256k1_fe_is_odd(&fe) == parities[i - 1]); + + /* Verify that the higher half is identical to the lower half mirrored. */ + if (i > EXHAUSTIVE_TEST_ORDER / 2) { + CHECK(secp256k1_memcmp_var(xonly_pubkey_bytes[i - 1], xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - i - 1], 32) == 0); + CHECK(parities[i - 1] == 1 - parities[EXHAUSTIVE_TEST_ORDER - i - 1]); + } + } + + /* TODO: keypair/xonly_pubkey tweak tests */ +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/tests_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/tests_impl.h new file mode 100644 index 0000000000..ab4ef4a74b --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/extrakeys/tests_impl.h @@ -0,0 +1,483 @@ +/*********************************************************************** + * Copyright (c) 2020 Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_H +#define SECP256K1_MODULE_EXTRAKEYS_TESTS_H + +#include "../../../include/secp256k1_extrakeys.h" + +static void test_xonly_pubkey(void) { + secp256k1_pubkey pk; + secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp; + secp256k1_ge pk1; + secp256k1_ge pk2; + secp256k1_fe y; + unsigned char sk[32]; + unsigned char xy_sk[32]; + unsigned char buf32[32]; + unsigned char ones32[32]; + unsigned char zeros64[64] = { 0 }; + int pk_parity; + int i; + + testrand256(sk); + memset(ones32, 0xFF, 32); + testrand256(xy_sk); + CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1); + + /* Test xonly_pubkey_from_pubkey */ + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, NULL, &pk_parity, &pk)); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, NULL)); + memset(&pk, 0, sizeof(pk)); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk)); + + /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */ + memset(sk, 0, sizeof(sk)); + sk[0] = 1; + CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1); + CHECK(secp256k1_memcmp_var(&pk, &xonly_pk, sizeof(pk)) == 0); + CHECK(pk_parity == 0); + + /* Choose a secret key such that pubkey and xonly_pubkey are each others + * negation. */ + sk[0] = 2; + CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1); + CHECK(secp256k1_memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0); + CHECK(pk_parity == 1); + secp256k1_pubkey_load(CTX, &pk1, &pk); + secp256k1_pubkey_load(CTX, &pk2, (secp256k1_pubkey *) &xonly_pk); + CHECK(secp256k1_fe_equal(&pk1.x, &pk2.x) == 1); + secp256k1_fe_negate(&y, &pk2.y, 1); + CHECK(secp256k1_fe_equal(&pk1.y, &y) == 1); + + /* Test xonly_pubkey_serialize and xonly_pubkey_parse */ + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_serialize(CTX, NULL, &xonly_pk)); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_serialize(CTX, buf32, NULL)); + CHECK(secp256k1_memcmp_var(buf32, zeros64, 32) == 0); + { + /* A pubkey filled with 0s will fail to serialize due to pubkey_load + * special casing. */ + secp256k1_xonly_pubkey pk_tmp; + memset(&pk_tmp, 0, sizeof(pk_tmp)); + /* pubkey_load calls illegal callback */ + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_serialize(CTX, buf32, &pk_tmp)); + } + + CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_parse(CTX, NULL, buf32)); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, NULL)); + + /* Serialization and parse roundtrip */ + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1); + CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk_tmp, buf32) == 1); + CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0); + + /* Test parsing invalid field elements */ + memset(&xonly_pk, 1, sizeof(xonly_pk)); + /* Overflowing field element */ + CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, ones32) == 0); + CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0); + memset(&xonly_pk, 1, sizeof(xonly_pk)); + /* There's no point with x-coordinate 0 on secp256k1 */ + CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, zeros64) == 0); + CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0); + /* If a random 32-byte string can not be parsed with ec_pubkey_parse + * (because interpreted as X coordinate it does not correspond to a point on + * the curve) then xonly_pubkey_parse should fail as well. */ + for (i = 0; i < COUNT; i++) { + unsigned char rand33[33]; + testrand256(&rand33[1]); + rand33[0] = SECP256K1_TAG_PUBKEY_EVEN; + if (!secp256k1_ec_pubkey_parse(CTX, &pk, rand33, 33)) { + memset(&xonly_pk, 1, sizeof(xonly_pk)); + CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 0); + CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0); + } else { + CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 1); + } + } +} + +static void test_xonly_pubkey_comparison(void) { + unsigned char pk1_ser[32] = { + 0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11, + 0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23 + }; + const unsigned char pk2_ser[32] = { + 0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d, + 0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c + }; + secp256k1_xonly_pubkey pk1; + secp256k1_xonly_pubkey pk2; + + CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk1, pk1_ser) == 1); + CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk2, pk2_ser) == 1); + + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_xonly_pubkey_cmp(CTX, NULL, &pk2) < 0)); + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, NULL) > 0)); + CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0); + CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0); + CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0); + CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk2) == 0); + memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */ + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0)); + { + int32_t ecount = 0; + secp256k1_context_set_illegal_callback(CTX, counting_callback_fn, &ecount); + CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0); + CHECK(ecount == 2); + secp256k1_context_set_illegal_callback(CTX, NULL, NULL); + } + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0)); +} + +static void test_xonly_pubkey_tweak(void) { + unsigned char zeros64[64] = { 0 }; + unsigned char overflows[32]; + unsigned char sk[32]; + secp256k1_pubkey internal_pk; + secp256k1_xonly_pubkey internal_xonly_pk; + secp256k1_pubkey output_pk; + int pk_parity; + unsigned char tweak[32]; + int i; + + memset(overflows, 0xff, sizeof(overflows)); + testrand256(tweak); + testrand256(sk); + CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1); + + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, NULL, &internal_xonly_pk, tweak)); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, NULL, tweak)); + /* NULL internal_xonly_pk zeroes the output_pk */ + CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, NULL)); + /* NULL tweak zeroes the output_pk */ + CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0); + + /* Invalid tweak zeroes the output_pk */ + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0); + CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0); + + /* A zero tweak is fine */ + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, zeros64) == 1); + + /* Fails if the resulting key was infinity */ + for (i = 0; i < COUNT; i++) { + secp256k1_scalar scalar_tweak; + /* Because sk may be negated before adding, we need to try with tweak = + * sk as well as tweak = -sk. */ + secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL); + secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak); + secp256k1_scalar_get_b32(tweak, &scalar_tweak); + CHECK((secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, sk) == 0) + || (secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 0)); + CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0); + } + + /* Invalid pk with a valid tweak */ + memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk)); + testrand256(tweak); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak)); + CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0); +} + +static void test_xonly_pubkey_tweak_check(void) { + unsigned char zeros64[64] = { 0 }; + unsigned char overflows[32]; + unsigned char sk[32]; + secp256k1_pubkey internal_pk; + secp256k1_xonly_pubkey internal_xonly_pk; + secp256k1_pubkey output_pk; + secp256k1_xonly_pubkey output_xonly_pk; + unsigned char output_pk32[32]; + unsigned char buf32[32]; + int pk_parity; + unsigned char tweak[32]; + + memset(overflows, 0xff, sizeof(overflows)); + testrand256(tweak); + testrand256(sk); + CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1); + + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &output_xonly_pk) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, NULL, pk_parity, &internal_xonly_pk, tweak)); + /* invalid pk_parity value */ + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, 2, &internal_xonly_pk, tweak) == 0); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, NULL, tweak)); + CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, NULL)); + + memset(tweak, 1, sizeof(tweak)); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, NULL, &internal_pk) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, output_pk32, &output_xonly_pk) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1); + + /* Wrong pk_parity */ + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0); + /* Wrong public key */ + CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &internal_xonly_pk) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 0); + + /* Overflowing tweak not allowed */ + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0); + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0); + CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0); +} + +/* Starts with an initial pubkey and recursively creates N_PUBKEYS - 1 + * additional pubkeys by calling tweak_add. Then verifies every tweak starting + * from the last pubkey. */ +#define N_PUBKEYS 32 +static void test_xonly_pubkey_tweak_recursive(void) { + unsigned char sk[32]; + secp256k1_pubkey pk[N_PUBKEYS]; + unsigned char pk_serialized[32]; + unsigned char tweak[N_PUBKEYS - 1][32]; + int i; + + testrand256(sk); + CHECK(secp256k1_ec_pubkey_create(CTX, &pk[0], sk) == 1); + /* Add tweaks */ + for (i = 0; i < N_PUBKEYS - 1; i++) { + secp256k1_xonly_pubkey xonly_pk; + memset(tweak[i], i + 1, sizeof(tweak[i])); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i]) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &pk[i + 1], &xonly_pk, tweak[i]) == 1); + } + + /* Verify tweaks */ + for (i = N_PUBKEYS - 1; i > 0; i--) { + secp256k1_xonly_pubkey xonly_pk; + int pk_parity; + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk[i]) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk_serialized, &xonly_pk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i - 1]) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1); + } +} +#undef N_PUBKEYS + +static void test_keypair(void) { + unsigned char sk[32]; + unsigned char sk_tmp[32]; + unsigned char zeros96[96] = { 0 }; + unsigned char overflows[32]; + secp256k1_keypair keypair; + secp256k1_pubkey pk, pk_tmp; + secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp; + int pk_parity, pk_parity_tmp; + + CHECK(sizeof(zeros96) == sizeof(keypair)); + memset(overflows, 0xFF, sizeof(overflows)); + + /* Test keypair_create */ + testrand256(sk); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0); + CHECK_ILLEGAL(CTX, secp256k1_keypair_create(CTX, NULL, sk)); + CHECK_ILLEGAL(CTX, secp256k1_keypair_create(CTX, &keypair, NULL)); + CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_keypair_create(STATIC_CTX, &keypair, sk)); + CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0); + + /* Invalid secret key */ + CHECK(secp256k1_keypair_create(CTX, &keypair, zeros96) == 0); + CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0); + CHECK(secp256k1_keypair_create(CTX, &keypair, overflows) == 0); + CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0); + + /* Test keypair_pub */ + testrand256(sk); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1); + CHECK_ILLEGAL(CTX, secp256k1_keypair_pub(CTX, NULL, &keypair)); + CHECK_ILLEGAL(CTX, secp256k1_keypair_pub(CTX, &pk, NULL)); + CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0); + + /* Using an invalid keypair is fine for keypair_pub */ + memset(&keypair, 0, sizeof(keypair)); + CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1); + CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0); + + /* keypair holds the same pubkey as pubkey_create */ + CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_pub(CTX, &pk_tmp, &keypair) == 1); + CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0); + + /** Test keypair_xonly_pub **/ + testrand256(sk); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1); + CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, NULL, &pk_parity, &keypair)); + CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, NULL, &keypair) == 1); + CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, NULL)); + CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0); + /* Using an invalid keypair will set the xonly_pk to 0 (first reset + * xonly_pk). */ + CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1); + memset(&keypair, 0, sizeof(keypair)); + CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair)); + CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0); + + /** keypair holds the same xonly pubkey as pubkey_create **/ + CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1); + CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0); + CHECK(pk_parity == pk_parity_tmp); + + /* Test keypair_seckey */ + testrand256(sk); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1); + CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, NULL, &keypair)); + CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, sk_tmp, NULL)); + CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0); + + /* keypair returns the same seckey it got */ + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1); + CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0); + + + /* Using an invalid keypair is fine for keypair_seckey */ + memset(&keypair, 0, sizeof(keypair)); + CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1); + CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0); +} + +static void test_keypair_add(void) { + unsigned char sk[32]; + secp256k1_keypair keypair; + unsigned char overflows[32]; + unsigned char zeros96[96] = { 0 }; + unsigned char tweak[32]; + int i; + + CHECK(sizeof(zeros96) == sizeof(keypair)); + testrand256(sk); + testrand256(tweak); + memset(overflows, 0xFF, 32); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + + CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1); + CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1); + CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1); + CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, NULL, tweak)); + CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, NULL)); + /* This does not set the keypair to zeroes */ + CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0); + + /* Invalid tweak zeroes the keypair */ + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, overflows) == 0); + CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0); + + /* A zero tweak is fine */ + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, zeros96) == 1); + + /* Fails if the resulting keypair was (sk=0, pk=infinity) */ + for (i = 0; i < COUNT; i++) { + secp256k1_scalar scalar_tweak; + secp256k1_keypair keypair_tmp; + testrand256(sk); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + memcpy(&keypair_tmp, &keypair, sizeof(keypair)); + /* Because sk may be negated before adding, we need to try with tweak = + * sk as well as tweak = -sk. */ + secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL); + secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak); + secp256k1_scalar_get_b32(tweak, &scalar_tweak); + CHECK((secp256k1_keypair_xonly_tweak_add(CTX, &keypair, sk) == 0) + || (secp256k1_keypair_xonly_tweak_add(CTX, &keypair_tmp, tweak) == 0)); + CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0 + || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0); + } + + /* Invalid keypair with a valid tweak */ + memset(&keypair, 0, sizeof(keypair)); + testrand256(tweak); + CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak)); + CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0); + /* Only seckey part of keypair invalid */ + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + memset(&keypair, 0, 32); + CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak)); + /* Only pubkey part of keypair invalid */ + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + memset(&keypair.data[32], 0, 64); + CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak)); + + /* Check that the keypair_tweak_add implementation is correct */ + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + for (i = 0; i < COUNT; i++) { + secp256k1_xonly_pubkey internal_pk; + secp256k1_xonly_pubkey output_pk; + secp256k1_pubkey output_pk_xy; + secp256k1_pubkey output_pk_expected; + unsigned char pk32[32]; + unsigned char sk32[32]; + int pk_parity; + + testrand256(tweak); + CHECK(secp256k1_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1); + CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1); + CHECK(secp256k1_keypair_xonly_pub(CTX, &output_pk, &pk_parity, &keypair) == 1); + + /* Check that it passes xonly_pubkey_tweak_add_check */ + CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &output_pk) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk32, pk_parity, &internal_pk, tweak) == 1); + + /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */ + CHECK(secp256k1_keypair_pub(CTX, &output_pk_xy, &keypair) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk_expected, &internal_pk, tweak) == 1); + CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0); + + /* Check that the secret key in the keypair is tweaked correctly */ + CHECK(secp256k1_keypair_sec(CTX, sk32, &keypair) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &output_pk_expected, sk32) == 1); + CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0); + } +} + +static void run_extrakeys_tests(void) { + /* xonly key test cases */ + test_xonly_pubkey(); + test_xonly_pubkey_tweak(); + test_xonly_pubkey_tweak_check(); + test_xonly_pubkey_tweak_recursive(); + test_xonly_pubkey_comparison(); + + /* keypair tests */ + test_keypair(); + test_keypair_add(); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/musig/Makefile.am.include b/crypto/secp256k1/libsecp256k1/src/modules/musig/Makefile.am.include new file mode 100644 index 0000000000..796443c93b --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/musig/Makefile.am.include @@ -0,0 +1,8 @@ +include_HEADERS += include/secp256k1_musig.h +noinst_HEADERS += src/modules/musig/main_impl.h +noinst_HEADERS += src/modules/musig/keyagg.h +noinst_HEADERS += src/modules/musig/keyagg_impl.h +noinst_HEADERS += src/modules/musig/session.h +noinst_HEADERS += src/modules/musig/session_impl.h +noinst_HEADERS += src/modules/musig/tests_impl.h +noinst_HEADERS += src/modules/musig/vectors.h diff --git a/crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg.h b/crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg.h new file mode 100644 index 0000000000..a0b37252f8 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg.h @@ -0,0 +1,32 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_MUSIG_KEYAGG_H +#define SECP256K1_MODULE_MUSIG_KEYAGG_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_musig.h" + +#include "../../group.h" +#include "../../scalar.h" + +typedef struct { + secp256k1_ge pk; + /* If there is no "second" public key, second_pk is set to the point at + * infinity */ + secp256k1_ge second_pk; + unsigned char pks_hash[32]; + /* tweak is identical to value tacc[v] in the specification. */ + secp256k1_scalar tweak; + /* parity_acc corresponds to (1 - gacc[v])/2 in the spec. So if gacc[v] is + * -1, parity_acc is 1. Otherwise, parity_acc is 0. */ + int parity_acc; +} secp256k1_keyagg_cache_internal; + +static int secp256k1_keyagg_cache_load(const secp256k1_context* ctx, secp256k1_keyagg_cache_internal *cache_i, const secp256k1_musig_keyagg_cache *cache); + +static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk); + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg_impl.h new file mode 100644 index 0000000000..0db4fce859 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg_impl.h @@ -0,0 +1,291 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_MUSIG_KEYAGG_IMPL_H +#define SECP256K1_MODULE_MUSIG_KEYAGG_IMPL_H + +#include + +#include "keyagg.h" +#include "../../eckey.h" +#include "../../ecmult.h" +#include "../../field.h" +#include "../../group.h" +#include "../../hash.h" +#include "../../util.h" + +static const unsigned char secp256k1_musig_keyagg_cache_magic[4] = { 0xf4, 0xad, 0xbb, 0xdf }; + +/* A keyagg cache consists of + * - 4 byte magic set during initialization to allow detecting an uninitialized + * object. + * - 64 byte aggregate (and potentially tweaked) public key + * - 64 byte "second" public key (set to the point at infinity if not present) + * - 32 byte hash of all public keys + * - 1 byte the parity of the internal key (if tweaked, otherwise 0) + * - 32 byte tweak + */ +/* Requires that cache_i->pk is not infinity. */ +static void secp256k1_keyagg_cache_save(secp256k1_musig_keyagg_cache *cache, const secp256k1_keyagg_cache_internal *cache_i) { + unsigned char *ptr = cache->data; + memcpy(ptr, secp256k1_musig_keyagg_cache_magic, 4); + ptr += 4; + secp256k1_ge_to_bytes(ptr, &cache_i->pk); + ptr += 64; + secp256k1_ge_to_bytes_ext(ptr, &cache_i->second_pk); + ptr += 64; + memcpy(ptr, cache_i->pks_hash, 32); + ptr += 32; + *ptr = cache_i->parity_acc; + ptr += 1; + secp256k1_scalar_get_b32(ptr, &cache_i->tweak); +} + +static int secp256k1_keyagg_cache_load(const secp256k1_context* ctx, secp256k1_keyagg_cache_internal *cache_i, const secp256k1_musig_keyagg_cache *cache) { + const unsigned char *ptr = cache->data; + ARG_CHECK(secp256k1_memcmp_var(ptr, secp256k1_musig_keyagg_cache_magic, 4) == 0); + ptr += 4; + secp256k1_ge_from_bytes(&cache_i->pk, ptr); + ptr += 64; + secp256k1_ge_from_bytes_ext(&cache_i->second_pk, ptr); + ptr += 64; + memcpy(cache_i->pks_hash, ptr, 32); + ptr += 32; + cache_i->parity_acc = *ptr & 1; + ptr += 1; + secp256k1_scalar_set_b32(&cache_i->tweak, ptr, NULL); + return 1; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("KeyAgg list")||SHA256("KeyAgg list"). */ +static void secp256k1_musig_keyagglist_sha256(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + + sha->s[0] = 0xb399d5e0ul; + sha->s[1] = 0xc8fff302ul; + sha->s[2] = 0x6badac71ul; + sha->s[3] = 0x07c5b7f1ul; + sha->s[4] = 0x9701e2eful; + sha->s[5] = 0x2a72ecf8ul; + sha->s[6] = 0x201a4c7bul; + sha->s[7] = 0xab148a38ul; + sha->bytes = 64; +} + +/* Computes pks_hash = tagged_hash(pk[0], ..., pk[np-1]) */ +static int secp256k1_musig_compute_pks_hash(const secp256k1_context *ctx, unsigned char *pks_hash, const secp256k1_pubkey * const* pks, size_t np) { + secp256k1_sha256 sha; + size_t i; + + secp256k1_musig_keyagglist_sha256(&sha); + for (i = 0; i < np; i++) { + unsigned char ser[33]; + size_t ser_len = sizeof(ser); + if (!secp256k1_ec_pubkey_serialize(ctx, ser, &ser_len, pks[i], SECP256K1_EC_COMPRESSED)) { + return 0; + } + VERIFY_CHECK(ser_len == sizeof(ser)); + secp256k1_sha256_write(&sha, ser, sizeof(ser)); + } + secp256k1_sha256_finalize(&sha, pks_hash); + return 1; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("KeyAgg coefficient")||SHA256("KeyAgg coefficient"). */ +static void secp256k1_musig_keyaggcoef_sha256(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + + sha->s[0] = 0x6ef02c5aul; + sha->s[1] = 0x06a480deul; + sha->s[2] = 0x1f298665ul; + sha->s[3] = 0x1d1134f2ul; + sha->s[4] = 0x56a0b063ul; + sha->s[5] = 0x52da4147ul; + sha->s[6] = 0xf280d9d4ul; + sha->s[7] = 0x4484be15ul; + sha->bytes = 64; +} + +/* Compute KeyAgg coefficient which is constant 1 for the second pubkey and + * otherwise tagged_hash(pks_hash, pk) where pks_hash is the hash of public keys. + * second_pk is the point at infinity in case there is no second_pk. Assumes + * that pk is not the point at infinity and that the Y-coordinates of pk and + * second_pk are normalized. */ +static void secp256k1_musig_keyaggcoef_internal(secp256k1_scalar *r, const unsigned char *pks_hash, secp256k1_ge *pk, const secp256k1_ge *second_pk) { + VERIFY_CHECK(!secp256k1_ge_is_infinity(pk)); + + if (!secp256k1_ge_is_infinity(second_pk) + && secp256k1_ge_eq_var(pk, second_pk)) { + secp256k1_scalar_set_int(r, 1); + } else { + secp256k1_sha256 sha; + unsigned char buf[33]; + size_t buflen = sizeof(buf); + int ret; + secp256k1_musig_keyaggcoef_sha256(&sha); + secp256k1_sha256_write(&sha, pks_hash, 32); + ret = secp256k1_eckey_pubkey_serialize(pk, buf, &buflen, 1); +#ifdef VERIFY + /* Serialization does not fail since the pk is not the point at infinity + * (according to this function's precondition). */ + VERIFY_CHECK(ret && buflen == sizeof(buf)); +#else + (void) ret; +#endif + secp256k1_sha256_write(&sha, buf, sizeof(buf)); + secp256k1_sha256_finalize(&sha, buf); + secp256k1_scalar_set_b32(r, buf, NULL); + } +} + +/* Assumes that pk is not the point at infinity and that the Y-coordinates of pk + * and cache_i->second_pk are normalized. */ +static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk) { + secp256k1_musig_keyaggcoef_internal(r, cache_i->pks_hash, pk, &cache_i->second_pk); +} + +typedef struct { + const secp256k1_context *ctx; + /* pks_hash is the hash of the public keys */ + unsigned char pks_hash[32]; + const secp256k1_pubkey * const* pks; + secp256k1_ge second_pk; +} secp256k1_musig_pubkey_agg_ecmult_data; + +/* Callback for batch EC multiplication to compute keyaggcoef_0*P0 + keyaggcoef_1*P1 + ... */ +static int secp256k1_musig_pubkey_agg_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data) { + secp256k1_musig_pubkey_agg_ecmult_data *ctx = (secp256k1_musig_pubkey_agg_ecmult_data *) data; + int ret; + ret = secp256k1_pubkey_load(ctx->ctx, pt, ctx->pks[idx]); +#ifdef VERIFY + /* pubkey_load can't fail because the same pks have already been loaded in + * `musig_compute_pks_hash` (and we test this). */ + VERIFY_CHECK(ret); +#else + (void) ret; +#endif + secp256k1_musig_keyaggcoef_internal(sc, ctx->pks_hash, pt, &ctx->second_pk); + return 1; +} + +int secp256k1_musig_pubkey_agg(const secp256k1_context* ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_pubkey * const* pubkeys, size_t n_pubkeys) { + secp256k1_musig_pubkey_agg_ecmult_data ecmult_data; + secp256k1_gej pkj; + secp256k1_ge pkp; + size_t i; + + VERIFY_CHECK(ctx != NULL); + if (agg_pk != NULL) { + memset(agg_pk, 0, sizeof(*agg_pk)); + } + ARG_CHECK(pubkeys != NULL); + ARG_CHECK(n_pubkeys > 0); + + ecmult_data.ctx = ctx; + ecmult_data.pks = pubkeys; + + secp256k1_ge_set_infinity(&ecmult_data.second_pk); + for (i = 1; i < n_pubkeys; i++) { + if (secp256k1_memcmp_var(pubkeys[0], pubkeys[i], sizeof(*pubkeys[0])) != 0) { + secp256k1_ge pk; + if (!secp256k1_pubkey_load(ctx, &pk, pubkeys[i])) { + return 0; + } + ecmult_data.second_pk = pk; + break; + } + } + + if (!secp256k1_musig_compute_pks_hash(ctx, ecmult_data.pks_hash, pubkeys, n_pubkeys)) { + return 0; + } + /* TODO: actually use optimized ecmult_multi algorithms by providing a + * scratch space */ + if (!secp256k1_ecmult_multi_var(&ctx->error_callback, NULL, &pkj, NULL, secp256k1_musig_pubkey_agg_callback, (void *) &ecmult_data, n_pubkeys)) { + /* In order to reach this line with the current implementation of + * ecmult_multi_var one would need to provide a callback that can + * fail. */ + return 0; + } + secp256k1_ge_set_gej(&pkp, &pkj); + secp256k1_fe_normalize_var(&pkp.y); + /* The resulting public key is infinity with negligible probability */ + VERIFY_CHECK(!secp256k1_ge_is_infinity(&pkp)); + if (keyagg_cache != NULL) { + secp256k1_keyagg_cache_internal cache_i = { 0 }; + cache_i.pk = pkp; + cache_i.second_pk = ecmult_data.second_pk; + memcpy(cache_i.pks_hash, ecmult_data.pks_hash, sizeof(cache_i.pks_hash)); + secp256k1_keyagg_cache_save(keyagg_cache, &cache_i); + } + + if (agg_pk != NULL) { + secp256k1_extrakeys_ge_even_y(&pkp); + secp256k1_xonly_pubkey_save(agg_pk, &pkp); + } + return 1; +} + +int secp256k1_musig_pubkey_get(const secp256k1_context* ctx, secp256k1_pubkey *agg_pk, const secp256k1_musig_keyagg_cache *keyagg_cache) { + secp256k1_keyagg_cache_internal cache_i; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(agg_pk != NULL); + memset(agg_pk, 0, sizeof(*agg_pk)); + ARG_CHECK(keyagg_cache != NULL); + + if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { + return 0; + } + secp256k1_pubkey_save(agg_pk, &cache_i.pk); + return 1; +} + +static int secp256k1_musig_pubkey_tweak_add_internal(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32, int xonly) { + secp256k1_keyagg_cache_internal cache_i; + int overflow = 0; + secp256k1_scalar tweak; + + VERIFY_CHECK(ctx != NULL); + if (output_pubkey != NULL) { + memset(output_pubkey, 0, sizeof(*output_pubkey)); + } + ARG_CHECK(keyagg_cache != NULL); + ARG_CHECK(tweak32 != NULL); + + if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { + return 0; + } + secp256k1_scalar_set_b32(&tweak, tweak32, &overflow); + if (overflow) { + return 0; + } + if (xonly && secp256k1_extrakeys_ge_even_y(&cache_i.pk)) { + cache_i.parity_acc ^= 1; + secp256k1_scalar_negate(&cache_i.tweak, &cache_i.tweak); + } + secp256k1_scalar_add(&cache_i.tweak, &cache_i.tweak, &tweak); + if (!secp256k1_eckey_pubkey_tweak_add(&cache_i.pk, &tweak)) { + return 0; + } + /* eckey_pubkey_tweak_add fails if cache_i.pk is infinity */ + VERIFY_CHECK(!secp256k1_ge_is_infinity(&cache_i.pk)); + secp256k1_keyagg_cache_save(keyagg_cache, &cache_i); + if (output_pubkey != NULL) { + secp256k1_pubkey_save(output_pubkey, &cache_i.pk); + } + return 1; +} + +int secp256k1_musig_pubkey_ec_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32) { + return secp256k1_musig_pubkey_tweak_add_internal(ctx, output_pubkey, keyagg_cache, tweak32, 0); +} + +int secp256k1_musig_pubkey_xonly_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32) { + return secp256k1_musig_pubkey_tweak_add_internal(ctx, output_pubkey, keyagg_cache, tweak32, 1); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/musig/main_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/musig/main_impl.h new file mode 100644 index 0000000000..a1311e4191 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/musig/main_impl.h @@ -0,0 +1,12 @@ +/********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_MUSIG_MAIN_H +#define SECP256K1_MODULE_MUSIG_MAIN_H + +#include "keyagg_impl.h" +#include "session_impl.h" + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/musig/session.h b/crypto/secp256k1/libsecp256k1/src/modules/musig/session.h new file mode 100644 index 0000000000..d6d76bc6c1 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/musig/session.h @@ -0,0 +1,24 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_MUSIG_SESSION_H +#define SECP256K1_MODULE_MUSIG_SESSION_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_musig.h" + +#include "../../scalar.h" + +typedef struct { + int fin_nonce_parity; + unsigned char fin_nonce[32]; + secp256k1_scalar noncecoef; + secp256k1_scalar challenge; + secp256k1_scalar s_part; +} secp256k1_musig_session_internal; + +static int secp256k1_musig_session_load(const secp256k1_context* ctx, secp256k1_musig_session_internal *session_i, const secp256k1_musig_session *session); + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/musig/session_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/musig/session_impl.h new file mode 100644 index 0000000000..dde3808582 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/musig/session_impl.h @@ -0,0 +1,816 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_MUSIG_SESSION_IMPL_H +#define SECP256K1_MODULE_MUSIG_SESSION_IMPL_H + +#include + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_extrakeys.h" +#include "../../../include/secp256k1_musig.h" + +#include "keyagg.h" +#include "session.h" +#include "../../eckey.h" +#include "../../hash.h" +#include "../../scalar.h" +#include "../../util.h" + +/* Outputs 33 zero bytes if the given group element is the point at infinity and + * otherwise outputs the compressed serialization */ +static void secp256k1_musig_ge_serialize_ext(unsigned char *out33, secp256k1_ge* ge) { + if (secp256k1_ge_is_infinity(ge)) { + memset(out33, 0, 33); + } else { + int ret; + size_t size = 33; + ret = secp256k1_eckey_pubkey_serialize(ge, out33, &size, 1); +#ifdef VERIFY + /* Serialize must succeed because the point is not at infinity */ + VERIFY_CHECK(ret && size == 33); +#else + (void) ret; +#endif + } +} + +/* Outputs the point at infinity if the given byte array is all zero, otherwise + * attempts to parse compressed point serialization. */ +static int secp256k1_musig_ge_parse_ext(secp256k1_ge* ge, const unsigned char *in33) { + unsigned char zeros[33] = { 0 }; + + if (secp256k1_memcmp_var(in33, zeros, sizeof(zeros)) == 0) { + secp256k1_ge_set_infinity(ge); + return 1; + } + if (!secp256k1_eckey_pubkey_parse(ge, in33, 33)) { + return 0; + } + return secp256k1_ge_is_in_correct_subgroup(ge); +} + +static const unsigned char secp256k1_musig_secnonce_magic[4] = { 0x22, 0x0e, 0xdc, 0xf1 }; + +static void secp256k1_musig_secnonce_save(secp256k1_musig_secnonce *secnonce, const secp256k1_scalar *k, const secp256k1_ge *pk) { + memcpy(&secnonce->data[0], secp256k1_musig_secnonce_magic, 4); + secp256k1_scalar_get_b32(&secnonce->data[4], &k[0]); + secp256k1_scalar_get_b32(&secnonce->data[36], &k[1]); + secp256k1_ge_to_bytes(&secnonce->data[68], pk); +} + +static int secp256k1_musig_secnonce_load(const secp256k1_context* ctx, secp256k1_scalar *k, secp256k1_ge *pk, const secp256k1_musig_secnonce *secnonce) { + int is_zero; + ARG_CHECK(secp256k1_memcmp_var(&secnonce->data[0], secp256k1_musig_secnonce_magic, 4) == 0); + /* We make very sure that the nonce isn't invalidated by checking the values + * in addition to the magic. */ + is_zero = secp256k1_is_zero_array(&secnonce->data[4], 2 * 32); + secp256k1_declassify(ctx, &is_zero, sizeof(is_zero)); + ARG_CHECK(!is_zero); + + secp256k1_scalar_set_b32(&k[0], &secnonce->data[4], NULL); + secp256k1_scalar_set_b32(&k[1], &secnonce->data[36], NULL); + secp256k1_ge_from_bytes(pk, &secnonce->data[68]); + return 1; +} + +/* If flag is true, invalidate the secnonce; otherwise leave it. Constant-time. */ +static void secp256k1_musig_secnonce_invalidate(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, int flag) { + secp256k1_memczero(secnonce->data, sizeof(secnonce->data), flag); + /* The flag argument is usually classified. So, the line above makes the + * magic and public key classified. However, we need both to be + * declassified. Note that we don't declassify the entire object, because if + * flag is 0, then k[0] and k[1] have not been zeroed. */ + secp256k1_declassify(ctx, secnonce->data, sizeof(secp256k1_musig_secnonce_magic)); + secp256k1_declassify(ctx, &secnonce->data[68], 64); +} + +static const unsigned char secp256k1_musig_pubnonce_magic[4] = { 0xf5, 0x7a, 0x3d, 0xa0 }; + +/* Saves two group elements into a pubnonce. Requires that none of the provided + * group elements is infinity. */ +static void secp256k1_musig_pubnonce_save(secp256k1_musig_pubnonce* nonce, const secp256k1_ge* ges) { + int i; + memcpy(&nonce->data[0], secp256k1_musig_pubnonce_magic, 4); + for (i = 0; i < 2; i++) { + secp256k1_ge_to_bytes(nonce->data + 4+64*i, &ges[i]); + } +} + +/* Loads two group elements from a pubnonce. Returns 1 unless the nonce wasn't + * properly initialized */ +static int secp256k1_musig_pubnonce_load(const secp256k1_context* ctx, secp256k1_ge* ges, const secp256k1_musig_pubnonce* nonce) { + int i; + + ARG_CHECK(secp256k1_memcmp_var(&nonce->data[0], secp256k1_musig_pubnonce_magic, 4) == 0); + for (i = 0; i < 2; i++) { + secp256k1_ge_from_bytes(&ges[i], nonce->data + 4 + 64*i); + } + return 1; +} + +static const unsigned char secp256k1_musig_aggnonce_magic[4] = { 0xa8, 0xb7, 0xe4, 0x67 }; + +static void secp256k1_musig_aggnonce_save(secp256k1_musig_aggnonce* nonce, const secp256k1_ge* ges) { + int i; + memcpy(&nonce->data[0], secp256k1_musig_aggnonce_magic, 4); + for (i = 0; i < 2; i++) { + secp256k1_ge_to_bytes_ext(&nonce->data[4 + 64*i], &ges[i]); + } +} + +static int secp256k1_musig_aggnonce_load(const secp256k1_context* ctx, secp256k1_ge* ges, const secp256k1_musig_aggnonce* nonce) { + int i; + + ARG_CHECK(secp256k1_memcmp_var(&nonce->data[0], secp256k1_musig_aggnonce_magic, 4) == 0); + for (i = 0; i < 2; i++) { + secp256k1_ge_from_bytes_ext(&ges[i], &nonce->data[4 + 64*i]); + } + return 1; +} + +static const unsigned char secp256k1_musig_session_cache_magic[4] = { 0x9d, 0xed, 0xe9, 0x17 }; + +/* A session consists of + * - 4 byte session cache magic + * - 1 byte the parity of the final nonce + * - 32 byte serialized x-only final nonce + * - 32 byte nonce coefficient b + * - 32 byte signature challenge hash e + * - 32 byte scalar s that is added to the partial signatures of the signers + */ +static void secp256k1_musig_session_save(secp256k1_musig_session *session, const secp256k1_musig_session_internal *session_i) { + unsigned char *ptr = session->data; + + memcpy(ptr, secp256k1_musig_session_cache_magic, 4); + ptr += 4; + *ptr = session_i->fin_nonce_parity; + ptr += 1; + memcpy(ptr, session_i->fin_nonce, 32); + ptr += 32; + secp256k1_scalar_get_b32(ptr, &session_i->noncecoef); + ptr += 32; + secp256k1_scalar_get_b32(ptr, &session_i->challenge); + ptr += 32; + secp256k1_scalar_get_b32(ptr, &session_i->s_part); +} + +static int secp256k1_musig_session_load(const secp256k1_context* ctx, secp256k1_musig_session_internal *session_i, const secp256k1_musig_session *session) { + const unsigned char *ptr = session->data; + + ARG_CHECK(secp256k1_memcmp_var(ptr, secp256k1_musig_session_cache_magic, 4) == 0); + ptr += 4; + session_i->fin_nonce_parity = *ptr; + ptr += 1; + memcpy(session_i->fin_nonce, ptr, 32); + ptr += 32; + secp256k1_scalar_set_b32(&session_i->noncecoef, ptr, NULL); + ptr += 32; + secp256k1_scalar_set_b32(&session_i->challenge, ptr, NULL); + ptr += 32; + secp256k1_scalar_set_b32(&session_i->s_part, ptr, NULL); + return 1; +} + +static const unsigned char secp256k1_musig_partial_sig_magic[4] = { 0xeb, 0xfb, 0x1a, 0x32 }; + +static void secp256k1_musig_partial_sig_save(secp256k1_musig_partial_sig* sig, secp256k1_scalar *s) { + memcpy(&sig->data[0], secp256k1_musig_partial_sig_magic, 4); + secp256k1_scalar_get_b32(&sig->data[4], s); +} + +static int secp256k1_musig_partial_sig_load(const secp256k1_context* ctx, secp256k1_scalar *s, const secp256k1_musig_partial_sig* sig) { + int overflow; + + ARG_CHECK(secp256k1_memcmp_var(&sig->data[0], secp256k1_musig_partial_sig_magic, 4) == 0); + secp256k1_scalar_set_b32(s, &sig->data[4], &overflow); + /* Parsed signatures can not overflow */ + VERIFY_CHECK(!overflow); + return 1; +} + +int secp256k1_musig_pubnonce_parse(const secp256k1_context* ctx, secp256k1_musig_pubnonce* nonce, const unsigned char *in66) { + secp256k1_ge ges[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(nonce != NULL); + ARG_CHECK(in66 != NULL); + + for (i = 0; i < 2; i++) { + if (!secp256k1_eckey_pubkey_parse(&ges[i], &in66[33*i], 33)) { + return 0; + } + if (!secp256k1_ge_is_in_correct_subgroup(&ges[i])) { + return 0; + } + } + secp256k1_musig_pubnonce_save(nonce, ges); + return 1; +} + +int secp256k1_musig_pubnonce_serialize(const secp256k1_context* ctx, unsigned char *out66, const secp256k1_musig_pubnonce* nonce) { + secp256k1_ge ges[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(out66 != NULL); + memset(out66, 0, 66); + ARG_CHECK(nonce != NULL); + + if (!secp256k1_musig_pubnonce_load(ctx, ges, nonce)) { + return 0; + } + for (i = 0; i < 2; i++) { + int ret; + size_t size = 33; + ret = secp256k1_eckey_pubkey_serialize(&ges[i], &out66[33*i], &size, 1); +#ifdef VERIFY + /* serialize must succeed because the point was just loaded */ + VERIFY_CHECK(ret && size == 33); +#else + (void) ret; +#endif + } + return 1; +} + +int secp256k1_musig_aggnonce_parse(const secp256k1_context* ctx, secp256k1_musig_aggnonce* nonce, const unsigned char *in66) { + secp256k1_ge ges[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(nonce != NULL); + ARG_CHECK(in66 != NULL); + + for (i = 0; i < 2; i++) { + if (!secp256k1_musig_ge_parse_ext(&ges[i], &in66[33*i])) { + return 0; + } + } + secp256k1_musig_aggnonce_save(nonce, ges); + return 1; +} + +int secp256k1_musig_aggnonce_serialize(const secp256k1_context* ctx, unsigned char *out66, const secp256k1_musig_aggnonce* nonce) { + secp256k1_ge ges[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(out66 != NULL); + memset(out66, 0, 66); + ARG_CHECK(nonce != NULL); + + if (!secp256k1_musig_aggnonce_load(ctx, ges, nonce)) { + return 0; + } + for (i = 0; i < 2; i++) { + secp256k1_musig_ge_serialize_ext(&out66[33*i], &ges[i]); + } + return 1; +} + +int secp256k1_musig_partial_sig_parse(const secp256k1_context* ctx, secp256k1_musig_partial_sig* sig, const unsigned char *in32) { + secp256k1_scalar tmp; + int overflow; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(in32 != NULL); + + /* Ensure that using the signature will fail if parsing fails (and the user + * doesn't check the return value). */ + memset(sig, 0, sizeof(*sig)); + + secp256k1_scalar_set_b32(&tmp, in32, &overflow); + if (overflow) { + return 0; + } + secp256k1_musig_partial_sig_save(sig, &tmp); + return 1; +} + +int secp256k1_musig_partial_sig_serialize(const secp256k1_context* ctx, unsigned char *out32, const secp256k1_musig_partial_sig* sig) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(out32 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(secp256k1_memcmp_var(&sig->data[0], secp256k1_musig_partial_sig_magic, 4) == 0); + + memcpy(out32, &sig->data[4], 32); + return 1; +} + +/* Write optional inputs into the hash */ +static void secp256k1_nonce_function_musig_helper(secp256k1_sha256 *sha, unsigned int prefix_size, const unsigned char *data, unsigned char len) { + unsigned char zero[7] = { 0 }; + /* The spec requires length prefixes to be between 1 and 8 bytes + * (inclusive) */ + VERIFY_CHECK(prefix_size >= 1 && prefix_size <= 8); + /* Since the length of all input data fits in a byte, we can always pad the + * length prefix with prefix_size - 1 zero bytes. */ + secp256k1_sha256_write(sha, zero, prefix_size - 1); + if (data != NULL) { + secp256k1_sha256_write(sha, &len, 1); + secp256k1_sha256_write(sha, data, len); + } else { + len = 0; + secp256k1_sha256_write(sha, &len, 1); + } +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("MuSig/aux")||SHA256("MuSig/aux"). */ +static void secp256k1_nonce_function_musig_sha256_tagged_aux(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0xa19e884bul; + sha->s[1] = 0xf463fe7eul; + sha->s[2] = 0x2f18f9a2ul; + sha->s[3] = 0xbeb0f9fful; + sha->s[4] = 0x0f37e8b0ul; + sha->s[5] = 0x06ebd26ful; + sha->s[6] = 0xe3b243d2ul; + sha->s[7] = 0x522fb150ul; + sha->bytes = 64; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("MuSig/nonce")||SHA256("MuSig/nonce"). */ +static void secp256k1_nonce_function_musig_sha256_tagged(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0x07101b64ul; + sha->s[1] = 0x18003414ul; + sha->s[2] = 0x0391bc43ul; + sha->s[3] = 0x0e6258eeul; + sha->s[4] = 0x29d26b72ul; + sha->s[5] = 0x8343937eul; + sha->s[6] = 0xb7a0a4fbul; + sha->s[7] = 0xff568a30ul; + sha->bytes = 64; +} + +static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned char *session_secrand, const unsigned char *msg32, const unsigned char *seckey32, const unsigned char *pk33, const unsigned char *agg_pk32, const unsigned char *extra_input32) { + secp256k1_sha256 sha; + unsigned char rand[32]; + unsigned char i; + unsigned char msg_present; + + if (seckey32 != NULL) { + secp256k1_nonce_function_musig_sha256_tagged_aux(&sha); + secp256k1_sha256_write(&sha, session_secrand, 32); + secp256k1_sha256_finalize(&sha, rand); + for (i = 0; i < 32; i++) { + rand[i] ^= seckey32[i]; + } + } else { + memcpy(rand, session_secrand, sizeof(rand)); + } + + secp256k1_nonce_function_musig_sha256_tagged(&sha); + secp256k1_sha256_write(&sha, rand, sizeof(rand)); + secp256k1_nonce_function_musig_helper(&sha, 1, pk33, 33); + secp256k1_nonce_function_musig_helper(&sha, 1, agg_pk32, 32); + msg_present = msg32 != NULL; + secp256k1_sha256_write(&sha, &msg_present, 1); + if (msg_present) { + secp256k1_nonce_function_musig_helper(&sha, 8, msg32, 32); + } + secp256k1_nonce_function_musig_helper(&sha, 4, extra_input32, 32); + + for (i = 0; i < 2; i++) { + unsigned char buf[32]; + secp256k1_sha256 sha_tmp = sha; + secp256k1_sha256_write(&sha_tmp, &i, 1); + secp256k1_sha256_finalize(&sha_tmp, buf); + secp256k1_scalar_set_b32(&k[i], buf, NULL); + + /* Attempt to erase secret data */ + secp256k1_memclear(buf, sizeof(buf)); + secp256k1_sha256_clear(&sha_tmp); + } + secp256k1_memclear(rand, sizeof(rand)); + secp256k1_sha256_clear(&sha); +} + +static int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, const unsigned char *input_nonce, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) { + secp256k1_scalar k[2]; + secp256k1_ge nonce_pts[2]; + int i; + unsigned char pk_ser[33]; + size_t pk_ser_len = sizeof(pk_ser); + unsigned char aggpk_ser[32]; + unsigned char *aggpk_ser_ptr = NULL; + secp256k1_ge pk; + int pk_serialize_success; + int ret = 1; + + ARG_CHECK(pubnonce != NULL); + memset(pubnonce, 0, sizeof(*pubnonce)); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + + /* Check that the seckey is valid to be able to sign for it later. */ + if (seckey != NULL) { + secp256k1_scalar sk; + ret &= secp256k1_scalar_set_b32_seckey(&sk, seckey); + secp256k1_scalar_clear(&sk); + } + + if (keyagg_cache != NULL) { + secp256k1_keyagg_cache_internal cache_i; + if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { + return 0; + } + /* The loaded point cache_i.pk can not be the point at infinity. */ + secp256k1_fe_get_b32(aggpk_ser, &cache_i.pk.x); + aggpk_ser_ptr = aggpk_ser; + } + if (!secp256k1_pubkey_load(ctx, &pk, pubkey)) { + return 0; + } + pk_serialize_success = secp256k1_eckey_pubkey_serialize(&pk, pk_ser, &pk_ser_len, 1); + +#ifdef VERIFY + /* A pubkey cannot be the point at infinity */ + VERIFY_CHECK(pk_serialize_success); + VERIFY_CHECK(pk_ser_len == sizeof(pk_ser)); +#else + (void) pk_serialize_success; +#endif + + secp256k1_nonce_function_musig(k, input_nonce, msg32, seckey, pk_ser, aggpk_ser_ptr, extra_input32); + VERIFY_CHECK(!secp256k1_scalar_is_zero(&k[0])); + VERIFY_CHECK(!secp256k1_scalar_is_zero(&k[1])); + secp256k1_musig_secnonce_save(secnonce, k, &pk); + secp256k1_musig_secnonce_invalidate(ctx, secnonce, !ret); + + for (i = 0; i < 2; i++) { + secp256k1_gej nonce_ptj; + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj, &k[i]); + secp256k1_ge_set_gej(&nonce_pts[i], &nonce_ptj); + secp256k1_declassify(ctx, &nonce_pts[i], sizeof(nonce_pts[i])); + secp256k1_scalar_clear(&k[i]); + secp256k1_gej_clear(&nonce_ptj); + } + /* None of the nonce_pts will be infinity because k != 0 with overwhelming + * probability */ + secp256k1_musig_pubnonce_save(pubnonce, nonce_pts); + return ret; +} + +int secp256k1_musig_nonce_gen(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, unsigned char *session_secrand32, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) { + int ret = 1; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secnonce != NULL); + memset(secnonce, 0, sizeof(*secnonce)); + ARG_CHECK(session_secrand32 != NULL); + + /* Check in constant time that the session_secrand32 is not 0 as a + * defense-in-depth measure that may protect against a faulty RNG. */ + ret &= !secp256k1_is_zero_array(session_secrand32, 32); + + /* We can declassify because branching on ret is only relevant when this + * function called with an invalid session_secrand32 argument */ + secp256k1_declassify(ctx, &ret, sizeof(ret)); + if (ret == 0) { + secp256k1_musig_secnonce_invalidate(ctx, secnonce, 1); + return 0; + } + + ret &= secp256k1_musig_nonce_gen_internal(ctx, secnonce, pubnonce, session_secrand32, seckey, pubkey, msg32, keyagg_cache, extra_input32); + + /* Set the session_secrand32 buffer to zero to prevent the caller from using + * nonce_gen multiple times with the same buffer. */ + secp256k1_memczero(session_secrand32, 32, ret); + return ret; +} + +int secp256k1_musig_nonce_gen_counter(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, uint64_t nonrepeating_cnt, const secp256k1_keypair *keypair, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) { + unsigned char buf[32] = { 0 }; + unsigned char seckey[32]; + secp256k1_pubkey pubkey; + int ret; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secnonce != NULL); + memset(secnonce, 0, sizeof(*secnonce)); + ARG_CHECK(keypair != NULL); + + secp256k1_write_be64(buf, nonrepeating_cnt); + /* keypair_sec and keypair_pub do not fail if the arguments are not NULL */ + ret = secp256k1_keypair_sec(ctx, seckey, keypair); + VERIFY_CHECK(ret); + ret = secp256k1_keypair_pub(ctx, &pubkey, keypair); + VERIFY_CHECK(ret); +#ifndef VERIFY + (void) ret; +#endif + + if (!secp256k1_musig_nonce_gen_internal(ctx, secnonce, pubnonce, buf, seckey, &pubkey, msg32, keyagg_cache, extra_input32)) { + return 0; + } + secp256k1_memclear(seckey, sizeof(seckey)); + return 1; +} + +static int secp256k1_musig_sum_pubnonces(const secp256k1_context* ctx, secp256k1_gej *summed_pubnonces, const secp256k1_musig_pubnonce * const* pubnonces, size_t n_pubnonces) { + size_t i; + int j; + + secp256k1_gej_set_infinity(&summed_pubnonces[0]); + secp256k1_gej_set_infinity(&summed_pubnonces[1]); + + for (i = 0; i < n_pubnonces; i++) { + secp256k1_ge nonce_pts[2]; + if (!secp256k1_musig_pubnonce_load(ctx, nonce_pts, pubnonces[i])) { + return 0; + } + for (j = 0; j < 2; j++) { + secp256k1_gej_add_ge_var(&summed_pubnonces[j], &summed_pubnonces[j], &nonce_pts[j], NULL); + } + } + return 1; +} + +int secp256k1_musig_nonce_agg(const secp256k1_context* ctx, secp256k1_musig_aggnonce *aggnonce, const secp256k1_musig_pubnonce * const* pubnonces, size_t n_pubnonces) { + secp256k1_gej aggnonce_ptsj[2]; + secp256k1_ge aggnonce_pts[2]; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(aggnonce != NULL); + ARG_CHECK(pubnonces != NULL); + ARG_CHECK(n_pubnonces > 0); + + if (!secp256k1_musig_sum_pubnonces(ctx, aggnonce_ptsj, pubnonces, n_pubnonces)) { + return 0; + } + secp256k1_ge_set_all_gej_var(aggnonce_pts, aggnonce_ptsj, 2); + secp256k1_musig_aggnonce_save(aggnonce, aggnonce_pts); + return 1; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("MuSig/noncecoef")||SHA256("MuSig/noncecoef"). */ +static void secp256k1_musig_compute_noncehash_sha256_tagged(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0x2c7d5a45ul; + sha->s[1] = 0x06bf7e53ul; + sha->s[2] = 0x89be68a6ul; + sha->s[3] = 0x971254c0ul; + sha->s[4] = 0x60ac12d2ul; + sha->s[5] = 0x72846dcdul; + sha->s[6] = 0x6c81212ful; + sha->s[7] = 0xde7a2500ul; + sha->bytes = 64; +} + +/* tagged_hash(aggnonce[0], aggnonce[1], agg_pk, msg) */ +static void secp256k1_musig_compute_noncehash(unsigned char *noncehash, secp256k1_ge *aggnonce, const unsigned char *agg_pk32, const unsigned char *msg) { + unsigned char buf[33]; + secp256k1_sha256 sha; + int i; + + secp256k1_musig_compute_noncehash_sha256_tagged(&sha); + for (i = 0; i < 2; i++) { + secp256k1_musig_ge_serialize_ext(buf, &aggnonce[i]); + secp256k1_sha256_write(&sha, buf, sizeof(buf)); + } + secp256k1_sha256_write(&sha, agg_pk32, 32); + secp256k1_sha256_write(&sha, msg, 32); + secp256k1_sha256_finalize(&sha, noncehash); +} + +/* out_nonce = nonce_pts[0] + b*nonce_pts[1] */ +static void secp256k1_effective_nonce(secp256k1_gej *out_nonce, const secp256k1_ge *nonce_pts, const secp256k1_scalar *b) { + secp256k1_gej tmp; + + secp256k1_gej_set_ge(&tmp, &nonce_pts[1]); + secp256k1_ecmult(out_nonce, &tmp, b, NULL); + secp256k1_gej_add_ge_var(out_nonce, out_nonce, &nonce_pts[0], NULL); +} + +static void secp256k1_musig_nonce_process_internal(int *fin_nonce_parity, unsigned char *fin_nonce, secp256k1_scalar *b, secp256k1_ge *aggnonce_pts, const unsigned char *agg_pk32, const unsigned char *msg) { + unsigned char noncehash[32]; + secp256k1_ge fin_nonce_pt; + secp256k1_gej fin_nonce_ptj; + + secp256k1_musig_compute_noncehash(noncehash, aggnonce_pts, agg_pk32, msg); + secp256k1_scalar_set_b32(b, noncehash, NULL); + /* fin_nonce = aggnonce_pts[0] + b*aggnonce_pts[1] */ + secp256k1_effective_nonce(&fin_nonce_ptj, aggnonce_pts, b); + secp256k1_ge_set_gej(&fin_nonce_pt, &fin_nonce_ptj); + if (secp256k1_ge_is_infinity(&fin_nonce_pt)) { + fin_nonce_pt = secp256k1_ge_const_g; + } + /* fin_nonce_pt is not the point at infinity */ + secp256k1_fe_normalize_var(&fin_nonce_pt.x); + secp256k1_fe_get_b32(fin_nonce, &fin_nonce_pt.x); + secp256k1_fe_normalize_var(&fin_nonce_pt.y); + *fin_nonce_parity = secp256k1_fe_is_odd(&fin_nonce_pt.y); +} + +int secp256k1_musig_nonce_process(const secp256k1_context* ctx, secp256k1_musig_session *session, const secp256k1_musig_aggnonce *aggnonce, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache) { + secp256k1_keyagg_cache_internal cache_i; + secp256k1_ge aggnonce_pts[2]; + unsigned char fin_nonce[32]; + secp256k1_musig_session_internal session_i; + unsigned char agg_pk32[32]; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(session != NULL); + ARG_CHECK(aggnonce != NULL); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(keyagg_cache != NULL); + + if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { + return 0; + } + secp256k1_fe_get_b32(agg_pk32, &cache_i.pk.x); + + if (!secp256k1_musig_aggnonce_load(ctx, aggnonce_pts, aggnonce)) { + return 0; + } + + secp256k1_musig_nonce_process_internal(&session_i.fin_nonce_parity, fin_nonce, &session_i.noncecoef, aggnonce_pts, agg_pk32, msg32); + secp256k1_schnorrsig_challenge(&session_i.challenge, fin_nonce, msg32, 32, agg_pk32); + + /* If there is a tweak then set `challenge` times `tweak` to the `s`-part.*/ + secp256k1_scalar_set_int(&session_i.s_part, 0); + if (!secp256k1_scalar_is_zero(&cache_i.tweak)) { + secp256k1_scalar e_tmp; + secp256k1_scalar_mul(&e_tmp, &session_i.challenge, &cache_i.tweak); + if (secp256k1_fe_is_odd(&cache_i.pk.y)) { + secp256k1_scalar_negate(&e_tmp, &e_tmp); + } + session_i.s_part = e_tmp; + } + memcpy(session_i.fin_nonce, fin_nonce, sizeof(session_i.fin_nonce)); + secp256k1_musig_session_save(session, &session_i); + return 1; +} + +static void secp256k1_musig_partial_sign_clear(secp256k1_scalar *sk, secp256k1_scalar *k) { + secp256k1_scalar_clear(sk); + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); +} + +int secp256k1_musig_partial_sign(const secp256k1_context* ctx, secp256k1_musig_partial_sig *partial_sig, secp256k1_musig_secnonce *secnonce, const secp256k1_keypair *keypair, const secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_musig_session *session) { + secp256k1_scalar sk; + secp256k1_ge pk, keypair_pk; + secp256k1_scalar k[2]; + secp256k1_scalar mu, s; + secp256k1_keyagg_cache_internal cache_i; + secp256k1_musig_session_internal session_i; + int ret; + + VERIFY_CHECK(ctx != NULL); + + ARG_CHECK(secnonce != NULL); + /* Fails if the magic doesn't match */ + ret = secp256k1_musig_secnonce_load(ctx, k, &pk, secnonce); + /* Set nonce to zero to avoid nonce reuse. This will cause subsequent calls + * of this function to fail */ + memset(secnonce, 0, sizeof(*secnonce)); + if (!ret) { + secp256k1_musig_partial_sign_clear(&sk, k); + return 0; + } + + ARG_CHECK(partial_sig != NULL); + ARG_CHECK(keypair != NULL); + ARG_CHECK(keyagg_cache != NULL); + ARG_CHECK(session != NULL); + + if (!secp256k1_keypair_load(ctx, &sk, &keypair_pk, keypair)) { + secp256k1_musig_partial_sign_clear(&sk, k); + return 0; + } + ARG_CHECK(secp256k1_fe_equal(&pk.x, &keypair_pk.x) + && secp256k1_fe_equal(&pk.y, &keypair_pk.y)); + if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { + secp256k1_musig_partial_sign_clear(&sk, k); + return 0; + } + + /* Negate sk if secp256k1_fe_is_odd(&cache_i.pk.y)) XOR cache_i.parity_acc. + * This corresponds to the line "Let d = g⋅gacc⋅d' mod n" in the + * specification. */ + if ((secp256k1_fe_is_odd(&cache_i.pk.y) + != cache_i.parity_acc)) { + secp256k1_scalar_negate(&sk, &sk); + } + + /* Multiply KeyAgg coefficient */ + secp256k1_musig_keyaggcoef(&mu, &cache_i, &pk); + secp256k1_scalar_mul(&sk, &sk, &mu); + + if (!secp256k1_musig_session_load(ctx, &session_i, session)) { + secp256k1_musig_partial_sign_clear(&sk, k); + return 0; + } + + if (session_i.fin_nonce_parity) { + secp256k1_scalar_negate(&k[0], &k[0]); + secp256k1_scalar_negate(&k[1], &k[1]); + } + + /* Sign */ + secp256k1_scalar_mul(&s, &session_i.challenge, &sk); + secp256k1_scalar_mul(&k[1], &session_i.noncecoef, &k[1]); + secp256k1_scalar_add(&k[0], &k[0], &k[1]); + secp256k1_scalar_add(&s, &s, &k[0]); + secp256k1_musig_partial_sig_save(partial_sig, &s); + secp256k1_musig_partial_sign_clear(&sk, k); + return 1; +} + +int secp256k1_musig_partial_sig_verify(const secp256k1_context* ctx, const secp256k1_musig_partial_sig *partial_sig, const secp256k1_musig_pubnonce *pubnonce, const secp256k1_pubkey *pubkey, const secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_musig_session *session) { + secp256k1_keyagg_cache_internal cache_i; + secp256k1_musig_session_internal session_i; + secp256k1_scalar mu, e, s; + secp256k1_gej pkj; + secp256k1_ge nonce_pts[2]; + secp256k1_gej rj; + secp256k1_gej tmp; + secp256k1_ge pkp; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(partial_sig != NULL); + ARG_CHECK(pubnonce != NULL); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(keyagg_cache != NULL); + ARG_CHECK(session != NULL); + + if (!secp256k1_musig_session_load(ctx, &session_i, session)) { + return 0; + } + + if (!secp256k1_musig_pubnonce_load(ctx, nonce_pts, pubnonce)) { + return 0; + } + /* Compute "effective" nonce rj = nonce_pts[0] + b*nonce_pts[1] */ + /* TODO: use multiexp to compute -s*G + e*mu*pubkey + nonce_pts[0] + b*nonce_pts[1] */ + secp256k1_effective_nonce(&rj, nonce_pts, &session_i.noncecoef); + + if (!secp256k1_pubkey_load(ctx, &pkp, pubkey)) { + return 0; + } + if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { + return 0; + } + /* Multiplying the challenge by the KeyAgg coefficient is equivalent + * to multiplying the signer's public key by the coefficient, except + * much easier to do. */ + secp256k1_musig_keyaggcoef(&mu, &cache_i, &pkp); + secp256k1_scalar_mul(&e, &session_i.challenge, &mu); + + /* Negate e if secp256k1_fe_is_odd(&cache_i.pk.y)) XOR cache_i.parity_acc. + * This corresponds to the line "Let g' = g⋅gacc mod n" and the multiplication "g'⋅e" + * in the specification. */ + if (secp256k1_fe_is_odd(&cache_i.pk.y) + != cache_i.parity_acc) { + secp256k1_scalar_negate(&e, &e); + } + + if (!secp256k1_musig_partial_sig_load(ctx, &s, partial_sig)) { + return 0; + } + /* Compute -s*G + e*pkj + rj (e already includes the keyagg coefficient mu) */ + secp256k1_scalar_negate(&s, &s); + secp256k1_gej_set_ge(&pkj, &pkp); + secp256k1_ecmult(&tmp, &pkj, &e, &s); + if (session_i.fin_nonce_parity) { + secp256k1_gej_neg(&rj, &rj); + } + secp256k1_gej_add_var(&tmp, &tmp, &rj, NULL); + + return secp256k1_gej_is_infinity(&tmp); +} + +int secp256k1_musig_partial_sig_agg(const secp256k1_context* ctx, unsigned char *sig64, const secp256k1_musig_session *session, const secp256k1_musig_partial_sig * const* partial_sigs, size_t n_sigs) { + size_t i; + secp256k1_musig_session_internal session_i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(session != NULL); + ARG_CHECK(partial_sigs != NULL); + ARG_CHECK(n_sigs > 0); + + if (!secp256k1_musig_session_load(ctx, &session_i, session)) { + return 0; + } + for (i = 0; i < n_sigs; i++) { + secp256k1_scalar term; + if (!secp256k1_musig_partial_sig_load(ctx, &term, partial_sigs[i])) { + return 0; + } + secp256k1_scalar_add(&session_i.s_part, &session_i.s_part, &term); + } + secp256k1_scalar_get_b32(&sig64[32], &session_i.s_part); + memcpy(&sig64[0], session_i.fin_nonce, 32); + return 1; +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/musig/tests_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/musig/tests_impl.h new file mode 100644 index 0000000000..ce6ae1784d --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/musig/tests_impl.h @@ -0,0 +1,1143 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_MUSIG_TESTS_IMPL_H +#define SECP256K1_MODULE_MUSIG_TESTS_IMPL_H + +#include +#include + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_extrakeys.h" +#include "../../../include/secp256k1_musig.h" + +#include "session.h" +#include "keyagg.h" +#include "../../scalar.h" +#include "../../field.h" +#include "../../group.h" +#include "../../hash.h" +#include "../../util.h" + +#include "vectors.h" + +static int create_keypair_and_pk(secp256k1_keypair *keypair, secp256k1_pubkey *pk, const unsigned char *sk) { + int ret; + secp256k1_keypair keypair_tmp; + ret = secp256k1_keypair_create(CTX, &keypair_tmp, sk); + ret &= secp256k1_keypair_pub(CTX, pk, &keypair_tmp); + if (keypair != NULL) { + *keypair = keypair_tmp; + } + return ret; +} + +/* Just a simple (non-tweaked) 2-of-2 MuSig aggregate, sign, verify + * test. */ +static void musig_simple_test(void) { + unsigned char sk[2][32]; + secp256k1_keypair keypair[2]; + secp256k1_musig_pubnonce pubnonce[2]; + const secp256k1_musig_pubnonce *pubnonce_ptr[2]; + secp256k1_musig_aggnonce aggnonce; + unsigned char msg[32]; + secp256k1_xonly_pubkey agg_pk; + secp256k1_musig_keyagg_cache keyagg_cache; + unsigned char session_secrand[2][32]; + secp256k1_musig_secnonce secnonce[2]; + secp256k1_pubkey pk[2]; + const secp256k1_pubkey *pk_ptr[2]; + secp256k1_musig_partial_sig partial_sig[2]; + const secp256k1_musig_partial_sig *partial_sig_ptr[2]; + unsigned char final_sig[64]; + secp256k1_musig_session session; + int i; + + testrand256(msg); + for (i = 0; i < 2; i++) { + testrand256(sk[i]); + pk_ptr[i] = &pk[i]; + pubnonce_ptr[i] = &pubnonce[i]; + partial_sig_ptr[i] = &partial_sig[i]; + + CHECK(create_keypair_and_pk(&keypair[i], &pk[i], sk[i])); + if (i == 0) { + testrand256(session_secrand[i]); + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[i], &pubnonce[i], session_secrand[i], sk[i], &pk[i], NULL, NULL, NULL) == 1); + } else { + uint64_t nonrepeating_cnt = 0; + CHECK(secp256k1_musig_nonce_gen_counter(CTX, &secnonce[i], &pubnonce[i], nonrepeating_cnt, &keypair[i], NULL, NULL, NULL) == 1); + } + } + + CHECK(secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1); + CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1); + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache) == 1); + + for (i = 0; i < 2; i++) { + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[i], &secnonce[i], &keypair[i], &keyagg_cache, &session) == 1); + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[i], &pubnonce[i], &pk[i], &keyagg_cache, &session) == 1); + } + + CHECK(secp256k1_musig_partial_sig_agg(CTX, final_sig, &session, partial_sig_ptr, 2) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, msg, sizeof(msg), &agg_pk) == 1); +} + +/* Generate two pubnonces such that both group elements of their sum (calculated + * with secp256k1_musig_sum_pubnonces) are infinity. */ +static void pubnonce_summing_to_inf(secp256k1_musig_pubnonce *pubnonce) { + secp256k1_ge ge[2]; + int i; + secp256k1_gej summed_pubnonces[2]; + const secp256k1_musig_pubnonce *pubnonce_ptr[2]; + + testutil_random_ge_test(&ge[0]); + testutil_random_ge_test(&ge[1]); + + for (i = 0; i < 2; i++) { + secp256k1_musig_pubnonce_save(&pubnonce[i], ge); + pubnonce_ptr[i] = &pubnonce[i]; + secp256k1_ge_neg(&ge[0], &ge[0]); + secp256k1_ge_neg(&ge[1], &ge[1]); + } + + secp256k1_musig_sum_pubnonces(CTX, summed_pubnonces, pubnonce_ptr, 2); + CHECK(secp256k1_gej_is_infinity(&summed_pubnonces[0])); + CHECK(secp256k1_gej_is_infinity(&summed_pubnonces[1])); +} + +int memcmp_and_randomize(unsigned char *value, const unsigned char *expected, size_t len) { + int ret; + size_t i; + ret = secp256k1_memcmp_var(value, expected, len); + for (i = 0; i < len; i++) { + value[i] = testrand_bits(8); + } + return ret; +} + +static void musig_api_tests(void) { + secp256k1_musig_partial_sig partial_sig[2]; + const secp256k1_musig_partial_sig *partial_sig_ptr[2]; + secp256k1_musig_partial_sig invalid_partial_sig; + const secp256k1_musig_partial_sig *invalid_partial_sig_ptr[2]; + unsigned char pre_sig[64]; + unsigned char buf[32]; + unsigned char sk[2][32]; + secp256k1_keypair keypair[2]; + secp256k1_keypair invalid_keypair; + unsigned char max64[64]; + unsigned char zeros132[132] = { 0 }; + unsigned char session_secrand[2][32]; + unsigned char nonrepeating_cnt = 0; + secp256k1_musig_secnonce secnonce[2]; + secp256k1_musig_secnonce secnonce_tmp; + secp256k1_musig_secnonce invalid_secnonce; + secp256k1_musig_pubnonce pubnonce[2]; + const secp256k1_musig_pubnonce *pubnonce_ptr[2]; + unsigned char pubnonce_ser[66]; + secp256k1_musig_pubnonce inf_pubnonce[2]; + const secp256k1_musig_pubnonce *inf_pubnonce_ptr[2]; + secp256k1_musig_pubnonce invalid_pubnonce; + const secp256k1_musig_pubnonce *invalid_pubnonce_ptr[1]; + secp256k1_musig_aggnonce aggnonce; + unsigned char aggnonce_ser[66]; + unsigned char msg[32]; + secp256k1_xonly_pubkey agg_pk; + secp256k1_pubkey full_agg_pk; + secp256k1_musig_keyagg_cache keyagg_cache; + secp256k1_musig_keyagg_cache invalid_keyagg_cache; + secp256k1_musig_session session; + secp256k1_musig_session invalid_session; + secp256k1_pubkey pk[2]; + const secp256k1_pubkey *pk_ptr[2]; + secp256k1_pubkey invalid_pk; + const secp256k1_pubkey *invalid_pk_ptr2[2]; + const secp256k1_pubkey *invalid_pk_ptr3[3]; + unsigned char tweak[32]; + int i; + + /** setup **/ + memset(max64, 0xff, sizeof(max64)); + memset(&invalid_keypair, 0, sizeof(invalid_keypair)); + memset(&invalid_pk, 0, sizeof(invalid_pk)); + memset(&invalid_secnonce, 0, sizeof(invalid_secnonce)); + memset(&invalid_partial_sig, 0, sizeof(invalid_partial_sig)); + pubnonce_summing_to_inf(inf_pubnonce); + /* Simulate structs being uninitialized by setting it to 0s. We don't want + * to produce undefined behavior by actually providing uninitialized + * structs. */ + memset(&invalid_keyagg_cache, 0, sizeof(invalid_keyagg_cache)); + memset(&invalid_pk, 0, sizeof(invalid_pk)); + memset(&invalid_pubnonce, 0, sizeof(invalid_pubnonce)); + memset(&invalid_session, 0, sizeof(invalid_session)); + + testrand256(msg); + testrand256(tweak); + for (i = 0; i < 2; i++) { + pk_ptr[i] = &pk[i]; + invalid_pk_ptr2[i] = &invalid_pk; + invalid_pk_ptr3[i] = &pk[i]; + pubnonce_ptr[i] = &pubnonce[i]; + inf_pubnonce_ptr[i] = &inf_pubnonce[i]; + partial_sig_ptr[i] = &partial_sig[i]; + invalid_partial_sig_ptr[i] = &partial_sig[i]; + testrand256(session_secrand[i]); + testrand256(sk[i]); + CHECK(create_keypair_and_pk(&keypair[i], &pk[i], sk[i])); + } + invalid_pubnonce_ptr[0] = &invalid_pubnonce; + invalid_partial_sig_ptr[0] = &invalid_partial_sig; + /* invalid_pk_ptr3 has two valid, one invalid pk, which is important to test + * musig_pubkey_agg */ + invalid_pk_ptr3[2] = &invalid_pk; + + /** main test body **/ + + /** Key aggregation **/ + CHECK(secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1); + CHECK(secp256k1_musig_pubkey_agg(CTX, NULL, &keyagg_cache, pk_ptr, 2) == 1); + CHECK(secp256k1_musig_pubkey_agg(CTX, &agg_pk, NULL, pk_ptr, 2) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, NULL, 2)); + CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, invalid_pk_ptr2, 2)); + CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, invalid_pk_ptr3, 3)); + CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, pk_ptr, 0)); + CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, NULL, 0)); + CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0); + + CHECK(secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1); + + /* pubkey_get */ + CHECK(secp256k1_musig_pubkey_get(CTX, &full_agg_pk, &keyagg_cache) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_get(CTX, NULL, &keyagg_cache)); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_get(CTX, &full_agg_pk, NULL)); + CHECK(secp256k1_memcmp_var(&full_agg_pk, zeros132, sizeof(full_agg_pk)) == 0); + + /** Tweaking **/ + { + int (*tweak_func[2]) (const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32); + tweak_func[0] = secp256k1_musig_pubkey_ec_tweak_add; + tweak_func[1] = secp256k1_musig_pubkey_xonly_tweak_add; + for (i = 0; i < 2; i++) { + secp256k1_pubkey tmp_output_pk; + secp256k1_musig_keyagg_cache tmp_keyagg_cache = keyagg_cache; + CHECK((*tweak_func[i])(CTX, &tmp_output_pk, &tmp_keyagg_cache, tweak) == 1); + /* Reset keyagg_cache */ + tmp_keyagg_cache = keyagg_cache; + CHECK((*tweak_func[i])(CTX, NULL, &tmp_keyagg_cache, tweak) == 1); + tmp_keyagg_cache = keyagg_cache; + CHECK_ILLEGAL(CTX, (*tweak_func[i])(CTX, &tmp_output_pk, NULL, tweak)); + CHECK(memcmp_and_randomize(tmp_output_pk.data, zeros132, sizeof(tmp_output_pk.data)) == 0); + tmp_keyagg_cache = keyagg_cache; + CHECK_ILLEGAL(CTX, (*tweak_func[i])(CTX, &tmp_output_pk, &tmp_keyagg_cache, NULL)); + CHECK(memcmp_and_randomize(tmp_output_pk.data, zeros132, sizeof(tmp_output_pk.data)) == 0); + tmp_keyagg_cache = keyagg_cache; + CHECK((*tweak_func[i])(CTX, &tmp_output_pk, &tmp_keyagg_cache, max64) == 0); + CHECK(memcmp_and_randomize(tmp_output_pk.data, zeros132, sizeof(tmp_output_pk.data)) == 0); + tmp_keyagg_cache = keyagg_cache; + /* Uninitialized keyagg_cache */ + CHECK_ILLEGAL(CTX, (*tweak_func[i])(CTX, &tmp_output_pk, &invalid_keyagg_cache, tweak)); + CHECK(memcmp_and_randomize(tmp_output_pk.data, zeros132, sizeof(tmp_output_pk.data)) == 0); + } + } + + /** Session creation with nonce_gen **/ + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk[0], &pk[0], msg, &keyagg_cache, max64) == 1); + /* nonce_gen, if successful, sets session_secrand to the zero array, which + * makes subsequent nonce_gen calls with the same session_secrand fail. So + * check that session_secrand is indeed the zero array and fill it with + * random values again. */ + CHECK(memcmp_and_randomize(session_secrand[0], zeros132, sizeof(session_secrand[0])) == 0); + + CHECK_ILLEGAL(STATIC_CTX, secp256k1_musig_nonce_gen(STATIC_CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk[0], &pk[0], msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, NULL, &pubnonce[0], session_secrand[0], sk[0], &pk[0], msg, &keyagg_cache, max64)); + + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], NULL, session_secrand[0], sk[0], &pk[0], msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], NULL, sk[0], &pk[0], msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + + /* session_secrand = 0 is disallowed because it indicates a faulty RNG */ + memcpy(&session_secrand[0], zeros132, sizeof(session_secrand[0])); + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], zeros132, sk[0], &pk[0], msg, &keyagg_cache, max64) == 0); + CHECK(memcmp_and_randomize(session_secrand[0], zeros132, sizeof(session_secrand[0])) == 0); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], NULL, &pk[0], msg, &keyagg_cache, max64) == 1); + CHECK(memcmp_and_randomize(session_secrand[0], zeros132, sizeof(session_secrand[0])) == 0); + + /* invalid seckey */ + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], max64, &pk[0], msg, &keyagg_cache, max64) == 0); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk[0], NULL, msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk[0], &invalid_pk, msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk[0], &pk[0], NULL, &keyagg_cache, max64) == 1); + CHECK(memcmp_and_randomize(session_secrand[0], zeros132, sizeof(session_secrand[0])) == 0); + + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk[0], &pk[0], msg, NULL, max64) == 1); + CHECK(memcmp_and_randomize(session_secrand[0], zeros132, sizeof(session_secrand[0])) == 0); + + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk[0], &pk[0], msg, &invalid_keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk[0], &pk[0], msg, &keyagg_cache, NULL) == 1); + CHECK(memcmp_and_randomize(session_secrand[0], zeros132, sizeof(session_secrand[0])) == 0); + + /* Every in-argument except session_secrand and pubkey can be NULL */ + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], NULL, &pk[0], NULL, NULL, NULL) == 1); + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[1], &pubnonce[1], session_secrand[1], sk[1], &pk[1], NULL, NULL, NULL) == 1); + + /** Session creation with nonce_gen_counter **/ + CHECK(secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt, &keypair[0], msg, &keyagg_cache, max64) == 1); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_musig_nonce_gen_counter(STATIC_CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt, &keypair[0], msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen_counter(CTX, NULL, &pubnonce[0], nonrepeating_cnt, &keypair[0], msg, &keyagg_cache, max64)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], NULL, nonrepeating_cnt, &keypair[0], msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + /* using nonce_gen_counter requires keypair */ + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt, NULL, msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + /* invalid keypair */ + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt, &invalid_keypair, msg, &keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + CHECK(secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt, &keypair[0], NULL, &keyagg_cache, max64) == 1); + CHECK(secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt, &keypair[0], msg, NULL, max64) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt, &keypair[0], msg, &invalid_keyagg_cache, max64)); + CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0); + CHECK(secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt,&keypair[0], msg, &keyagg_cache, NULL) == 1); + + /* Every in-argument except nonrepeating_cnt and keypair can be NULL */ + CHECK(secp256k1_musig_nonce_gen_counter(CTX, &secnonce[0], &pubnonce[0], nonrepeating_cnt, &keypair[0], NULL, NULL, NULL) == 1); + CHECK(secp256k1_musig_nonce_gen_counter(CTX, &secnonce[1], &pubnonce[1], nonrepeating_cnt, &keypair[1], NULL, NULL, NULL) == 1); + + + /** Serialize and parse public nonces **/ + CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_serialize(CTX, NULL, &pubnonce[0])); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_serialize(CTX, pubnonce_ser, NULL)); + CHECK(memcmp_and_randomize(pubnonce_ser, zeros132, sizeof(pubnonce_ser)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_serialize(CTX, pubnonce_ser, &invalid_pubnonce)); + CHECK(memcmp_and_randomize(pubnonce_ser, zeros132, sizeof(pubnonce_ser)) == 0); + CHECK(secp256k1_musig_pubnonce_serialize(CTX, pubnonce_ser, &pubnonce[0]) == 1); + + CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[0], pubnonce_ser) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_parse(CTX, NULL, pubnonce_ser)); + CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_parse(CTX, &pubnonce[0], NULL)); + CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[0], zeros132) == 0); + CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[0], pubnonce_ser) == 1); + + { + /* Check that serialize and parse results in the same value */ + secp256k1_musig_pubnonce tmp; + CHECK(secp256k1_musig_pubnonce_serialize(CTX, pubnonce_ser, &pubnonce[0]) == 1); + CHECK(secp256k1_musig_pubnonce_parse(CTX, &tmp, pubnonce_ser) == 1); + CHECK(secp256k1_memcmp_var(&tmp, &pubnonce[0], sizeof(tmp)) == 0); + } + + /** Receive nonces and aggregate **/ + CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_agg(CTX, NULL, pubnonce_ptr, 2)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_agg(CTX, &aggnonce, NULL, 2)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 0)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_agg(CTX, &aggnonce, invalid_pubnonce_ptr, 1)); + CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, inf_pubnonce_ptr, 2) == 1); + { + /* Check that the aggnonce encodes two points at infinity */ + secp256k1_ge aggnonce_pt[2]; + secp256k1_musig_aggnonce_load(CTX, aggnonce_pt, &aggnonce); + for (i = 0; i < 2; i++) { + secp256k1_ge_is_infinity(&aggnonce_pt[i]); + } + } + CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1); + + /** Serialize and parse aggregate nonces **/ + CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, &aggnonce) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_serialize(CTX, NULL, &aggnonce)); + CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, NULL)); + CHECK(memcmp_and_randomize(aggnonce_ser, zeros132, sizeof(aggnonce_ser)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, (secp256k1_musig_aggnonce*) &invalid_pubnonce)); + CHECK(memcmp_and_randomize(aggnonce_ser, zeros132, sizeof(aggnonce_ser)) == 0); + CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, &aggnonce) == 1); + + CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, aggnonce_ser) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_parse(CTX, NULL, aggnonce_ser)); + CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_parse(CTX, &aggnonce, NULL)); + CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, zeros132) == 1); + CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, aggnonce_ser) == 1); + + { + /* Check that serialize and parse results in the same value */ + secp256k1_musig_aggnonce tmp; + CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, &aggnonce) == 1); + CHECK(secp256k1_musig_aggnonce_parse(CTX, &tmp, aggnonce_ser) == 1); + CHECK(secp256k1_memcmp_var(&tmp, &aggnonce, sizeof(tmp)) == 0); + } + + /** Process nonces **/ + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, NULL, &aggnonce, msg, &keyagg_cache)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, NULL, msg, &keyagg_cache)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, (secp256k1_musig_aggnonce*) &invalid_pubnonce, msg, &keyagg_cache)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, NULL, &keyagg_cache)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &invalid_keyagg_cache)); + + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache) == 1); + + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, &session) == 1); + /* The secnonce is set to 0 and subsequent signing attempts fail */ + CHECK(secp256k1_memcmp_var(&secnonce_tmp, zeros132, sizeof(secnonce_tmp)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, &session)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, NULL, &secnonce_tmp, &keypair[0], &keyagg_cache, &session)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], NULL, &keypair[0], &keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &invalid_secnonce, &keypair[0], &keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, NULL, &keyagg_cache, &session)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &invalid_keypair, &keyagg_cache, &session)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + { + unsigned char sk_tmp[32]; + secp256k1_keypair keypair_tmp; + testrand256(sk_tmp); + CHECK(secp256k1_keypair_create(CTX, &keypair_tmp, sk_tmp)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair_tmp, &keyagg_cache, &session)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + } + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], NULL, &session)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &invalid_keyagg_cache, &session)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, NULL)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, &invalid_session)); + memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp)); + + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce[0], &keypair[0], &keyagg_cache, &session) == 1); + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[1], &secnonce[1], &keypair[1], &keyagg_cache, &session) == 1); + + CHECK(secp256k1_musig_partial_sig_serialize(CTX, buf, &partial_sig[0]) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_serialize(CTX, NULL, &partial_sig[0])); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_serialize(CTX, buf, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_serialize(CTX, buf, &invalid_partial_sig)); + CHECK(secp256k1_musig_partial_sig_parse(CTX, &partial_sig[0], buf) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_parse(CTX, NULL, buf)); + { + /* Check that parsing failure results in an invalid sig */ + secp256k1_musig_partial_sig tmp; + CHECK(secp256k1_musig_partial_sig_parse(CTX, &tmp, max64) == 0); + CHECK(secp256k1_memcmp_var(&tmp, zeros132, sizeof(partial_sig[0])) == 0); + } + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_parse(CTX, &partial_sig[0], NULL)); + + { + /* Check that serialize and parse results in the same value */ + secp256k1_musig_partial_sig tmp; + CHECK(secp256k1_musig_partial_sig_serialize(CTX, buf, &partial_sig[0]) == 1); + CHECK(secp256k1_musig_partial_sig_parse(CTX, &tmp, buf) == 1); + CHECK(secp256k1_memcmp_var(&tmp, &partial_sig[0], sizeof(tmp)) == 0); + } + + /** Partial signature verification */ + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &keyagg_cache, &session) == 1); + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[1], &pubnonce[0], &pk[0], &keyagg_cache, &session) == 0); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, NULL, &pubnonce[0], &pk[0], &keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &invalid_partial_sig, &pubnonce[0], &pk[0], &keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], NULL, &pk[0], &keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &invalid_pubnonce, &pk[0], &keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], NULL, &keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &invalid_pk, &keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], NULL, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &invalid_keyagg_cache, &session)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &keyagg_cache, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &keyagg_cache, &invalid_session)); + + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &keyagg_cache, &session) == 1); + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[1], &pubnonce[1], &pk[1], &keyagg_cache, &session) == 1); + + /** Signature aggregation and verification */ + CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 2) == 1); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, NULL, &session, partial_sig_ptr, 2)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, NULL, partial_sig_ptr, 2)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &invalid_session, partial_sig_ptr, 2)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, NULL, 2)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, invalid_partial_sig_ptr, 2)); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 0)); + CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 1) == 1); + CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 2) == 1); +} + +static void musig_nonce_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes) { + secp256k1_scalar k1[2], k2[2]; + + secp256k1_nonce_function_musig(k1, args[0], args[1], args[2], args[3], args[4], args[5]); + testrand_flip(args[n_flip], n_bytes); + secp256k1_nonce_function_musig(k2, args[0], args[1], args[2], args[3], args[4], args[5]); + CHECK(secp256k1_scalar_eq(&k1[0], &k2[0]) == 0); + CHECK(secp256k1_scalar_eq(&k1[1], &k2[1]) == 0); +} + +static void musig_nonce_test(void) { + unsigned char *args[6]; + unsigned char session_secrand[32]; + unsigned char sk[32]; + unsigned char pk[33]; + unsigned char msg[32]; + unsigned char agg_pk[32]; + unsigned char extra_input[32]; + int i, j; + secp256k1_scalar k[6][2]; + + testrand_bytes_test(session_secrand, sizeof(session_secrand)); + testrand_bytes_test(sk, sizeof(sk)); + testrand_bytes_test(pk, sizeof(pk)); + testrand_bytes_test(msg, sizeof(msg)); + testrand_bytes_test(agg_pk, sizeof(agg_pk)); + testrand_bytes_test(extra_input, sizeof(extra_input)); + + /* Check that a bitflip in an argument results in different nonces. */ + args[0] = session_secrand; + args[1] = msg; + args[2] = sk; + args[3] = pk; + args[4] = agg_pk; + args[5] = extra_input; + for (i = 0; i < COUNT; i++) { + musig_nonce_bitflip(args, 0, sizeof(session_secrand)); + musig_nonce_bitflip(args, 1, sizeof(msg)); + musig_nonce_bitflip(args, 2, sizeof(sk)); + musig_nonce_bitflip(args, 3, sizeof(pk)); + musig_nonce_bitflip(args, 4, sizeof(agg_pk)); + musig_nonce_bitflip(args, 5, sizeof(extra_input)); + } + /* Check that if any argument is NULL, a different nonce is produced than if + * any other argument is NULL. */ + memcpy(msg, session_secrand, sizeof(msg)); + memcpy(sk, session_secrand, sizeof(sk)); + memcpy(pk, session_secrand, sizeof(session_secrand)); + memcpy(agg_pk, session_secrand, sizeof(agg_pk)); + memcpy(extra_input, session_secrand, sizeof(extra_input)); + secp256k1_nonce_function_musig(k[0], args[0], args[1], args[2], args[3], args[4], args[5]); + secp256k1_nonce_function_musig(k[1], args[0], NULL, args[2], args[3], args[4], args[5]); + secp256k1_nonce_function_musig(k[2], args[0], args[1], NULL, args[3], args[4], args[5]); + secp256k1_nonce_function_musig(k[3], args[0], args[1], args[2], NULL, args[4], args[5]); + secp256k1_nonce_function_musig(k[4], args[0], args[1], args[2], args[3], NULL, args[5]); + secp256k1_nonce_function_musig(k[5], args[0], args[1], args[2], args[3], args[4], NULL); + for (i = 0; i < 6; i++) { + CHECK(!secp256k1_scalar_eq(&k[i][0], &k[i][1])); + for (j = i+1; j < 6; j++) { + CHECK(!secp256k1_scalar_eq(&k[i][0], &k[j][0])); + CHECK(!secp256k1_scalar_eq(&k[i][1], &k[j][1])); + } + } +} + +static void sha256_tag_test_internal(secp256k1_sha256 *sha_tagged, unsigned char *tag, size_t taglen) { + secp256k1_sha256 sha; + secp256k1_sha256_initialize_tagged(&sha, tag, taglen); + test_sha256_eq(&sha, sha_tagged); +} + +/* Checks that the initialized tagged hashes have the expected + * state. */ +static void sha256_tag_test(void) { + secp256k1_sha256 sha; + { + char tag[] = "KeyAgg list"; + secp256k1_musig_keyagglist_sha256(&sha); + sha256_tag_test_internal(&sha, (unsigned char*)tag, sizeof(tag) - 1); + } + { + char tag[] = "KeyAgg coefficient"; + secp256k1_musig_keyaggcoef_sha256(&sha); + sha256_tag_test_internal(&sha, (unsigned char*)tag, sizeof(tag) - 1); + } + { + unsigned char tag[] = "MuSig/aux"; + secp256k1_nonce_function_musig_sha256_tagged_aux(&sha); + sha256_tag_test_internal(&sha, (unsigned char*)tag, sizeof(tag) - 1); + } + { + unsigned char tag[] = "MuSig/nonce"; + secp256k1_nonce_function_musig_sha256_tagged(&sha); + sha256_tag_test_internal(&sha, (unsigned char*)tag, sizeof(tag) - 1); + } + { + unsigned char tag[] = "MuSig/noncecoef"; + secp256k1_musig_compute_noncehash_sha256_tagged(&sha); + sha256_tag_test_internal(&sha, (unsigned char*)tag, sizeof(tag) - 1); + } +} + +/* Attempts to create a signature for the aggregate public key using given secret + * keys and keyagg_cache. */ +static void musig_tweak_test_helper(const secp256k1_xonly_pubkey* agg_pk, const unsigned char *sk0, const unsigned char *sk1, secp256k1_musig_keyagg_cache *keyagg_cache) { + secp256k1_pubkey pk[2]; + unsigned char session_secrand[2][32]; + unsigned char msg[32]; + secp256k1_musig_secnonce secnonce[2]; + secp256k1_musig_pubnonce pubnonce[2]; + const secp256k1_musig_pubnonce *pubnonce_ptr[2]; + secp256k1_musig_aggnonce aggnonce; + secp256k1_keypair keypair[2]; + secp256k1_musig_session session; + secp256k1_musig_partial_sig partial_sig[2]; + const secp256k1_musig_partial_sig *partial_sig_ptr[2]; + unsigned char final_sig[64]; + int i; + + for (i = 0; i < 2; i++) { + pubnonce_ptr[i] = &pubnonce[i]; + partial_sig_ptr[i] = &partial_sig[i]; + + testrand256(session_secrand[i]); + } + CHECK(create_keypair_and_pk(&keypair[0], &pk[0], sk0) == 1); + CHECK(create_keypair_and_pk(&keypair[1], &pk[1], sk1) == 1); + testrand256(msg); + + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_secrand[0], sk0, &pk[0], NULL, NULL, NULL) == 1); + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[1], &pubnonce[1], session_secrand[1], sk1, &pk[1], NULL, NULL, NULL) == 1); + + CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1); + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, keyagg_cache) == 1); + + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce[0], &keypair[0], keyagg_cache, &session) == 1); + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[1], &secnonce[1], &keypair[1], keyagg_cache, &session) == 1); + + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], keyagg_cache, &session) == 1); + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[1], &pubnonce[1], &pk[1], keyagg_cache, &session) == 1); + + CHECK(secp256k1_musig_partial_sig_agg(CTX, final_sig, &session, partial_sig_ptr, 2) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, msg, sizeof(msg), agg_pk) == 1); +} + +/* Create aggregate public key P[0], tweak multiple times (using xonly and + * plain tweaking) and test signing. */ +static void musig_tweak_test(void) { + unsigned char sk[2][32]; + secp256k1_pubkey pk[2]; + const secp256k1_pubkey *pk_ptr[2]; + secp256k1_musig_keyagg_cache keyagg_cache; + enum { N_TWEAKS = 8 }; + secp256k1_pubkey P[N_TWEAKS + 1]; + secp256k1_xonly_pubkey P_xonly[N_TWEAKS + 1]; + int i; + + /* Key Setup */ + for (i = 0; i < 2; i++) { + pk_ptr[i] = &pk[i]; + testrand256(sk[i]); + CHECK(create_keypair_and_pk(NULL, &pk[i], sk[i]) == 1); + } + /* Compute P0 = keyagg(pk0, pk1) and test signing for it */ + CHECK(secp256k1_musig_pubkey_agg(CTX, &P_xonly[0], &keyagg_cache, pk_ptr, 2) == 1); + musig_tweak_test_helper(&P_xonly[0], sk[0], sk[1], &keyagg_cache); + CHECK(secp256k1_musig_pubkey_get(CTX, &P[0], &keyagg_cache)); + + /* Compute Pi = f(Pj) + tweaki*G where where j = i-1 and try signing for + * that key. If xonly is set to true, the function f normalizes the input + * point to have an even X-coordinate ("xonly-tweaking"). + * Otherwise, the function f is the identity function. */ + for (i = 1; i <= N_TWEAKS; i++) { + unsigned char tweak[32]; + int P_parity; + int xonly = testrand_bits(1); + + testrand256(tweak); + if (xonly) { + CHECK(secp256k1_musig_pubkey_xonly_tweak_add(CTX, &P[i], &keyagg_cache, tweak) == 1); + } else { + CHECK(secp256k1_musig_pubkey_ec_tweak_add(CTX, &P[i], &keyagg_cache, tweak) == 1); + } + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &P_xonly[i], &P_parity, &P[i])); + /* Check that musig_pubkey_tweak_add produces same result as + * xonly_pubkey_tweak_add or ec_pubkey_tweak_add. */ + if (xonly) { + unsigned char P_serialized[32]; + CHECK(secp256k1_xonly_pubkey_serialize(CTX, P_serialized, &P_xonly[i])); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, P_serialized, P_parity, &P_xonly[i-1], tweak) == 1); + } else { + secp256k1_pubkey tmp_key = P[i-1]; + CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &tmp_key, tweak)); + CHECK(secp256k1_memcmp_var(&tmp_key, &P[i], sizeof(tmp_key)) == 0); + } + /* Test signing for P[i] */ + musig_tweak_test_helper(&P_xonly[i], sk[0], sk[1], &keyagg_cache); + } +} + +int musig_vectors_keyagg_and_tweak(enum MUSIG_ERROR *error, + secp256k1_musig_keyagg_cache *keyagg_cache, + unsigned char *agg_pk_ser, + const unsigned char pubkeys33[][33], + const unsigned char tweaks32[][32], + size_t key_indices_len, + const size_t *key_indices, + size_t tweak_indices_len, + const size_t *tweak_indices, + const int *is_xonly) { + secp256k1_pubkey pubkeys[MUSIG_VECTORS_MAX_PUBKEYS]; + const secp256k1_pubkey *pk_ptr[MUSIG_VECTORS_MAX_PUBKEYS]; + int i; + secp256k1_pubkey agg_pk; + secp256k1_xonly_pubkey agg_pk_xonly; + + for (i = 0; i < (int)key_indices_len; i++) { + if (!secp256k1_ec_pubkey_parse(CTX, &pubkeys[i], pubkeys33[key_indices[i]], 33)) { + *error = MUSIG_PUBKEY; + return 0; + } + pk_ptr[i] = &pubkeys[i]; + } + if (!secp256k1_musig_pubkey_agg(CTX, NULL, keyagg_cache, pk_ptr, key_indices_len)) { + *error = MUSIG_OTHER; + return 0; + } + + for (i = 0; i < (int)tweak_indices_len; i++) { + if (is_xonly[i]) { + if (!secp256k1_musig_pubkey_xonly_tweak_add(CTX, NULL, keyagg_cache, tweaks32[tweak_indices[i]])) { + *error = MUSIG_TWEAK; + return 0; + } + } else { + if (!secp256k1_musig_pubkey_ec_tweak_add(CTX, NULL, keyagg_cache, tweaks32[tweak_indices[i]])) { + *error = MUSIG_TWEAK; + return 0; + } + } + } + if (!secp256k1_musig_pubkey_get(CTX, &agg_pk, keyagg_cache)) { + *error = MUSIG_OTHER; + return 0; + } + + if (!secp256k1_xonly_pubkey_from_pubkey(CTX, &agg_pk_xonly, NULL, &agg_pk)) { + *error = MUSIG_OTHER; + return 0; + } + + if (agg_pk_ser != NULL) { + if (!secp256k1_xonly_pubkey_serialize(CTX, agg_pk_ser, &agg_pk_xonly)) { + *error = MUSIG_OTHER; + return 0; + } + } + + return 1; +} + +static void musig_test_vectors_keyagg(void) { + size_t i; + const struct musig_key_agg_vector *vector = &musig_key_agg_vector; + + for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) { + const struct musig_key_agg_valid_test_case *c = &vector->valid_case[i]; + enum MUSIG_ERROR error; + secp256k1_musig_keyagg_cache keyagg_cache; + unsigned char agg_pk[32]; + + CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, agg_pk, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, 0, NULL, NULL)); + CHECK(secp256k1_memcmp_var(agg_pk, c->expected, sizeof(agg_pk)) == 0); + } + + for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) { + const struct musig_key_agg_error_test_case *c = &vector->error_case[i]; + enum MUSIG_ERROR error; + secp256k1_musig_keyagg_cache keyagg_cache; + + CHECK(!musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly)); + CHECK(c->error == error); + } +} + +static void musig_test_vectors_noncegen(void) { + size_t i; + const struct musig_nonce_gen_vector *vector = &musig_nonce_gen_vector; + + for (i = 0; i < sizeof(vector->test_case)/sizeof(vector->test_case[0]); i++) { + const struct musig_nonce_gen_test_case *c = &vector->test_case[i]; + secp256k1_musig_keyagg_cache keyagg_cache; + secp256k1_musig_keyagg_cache *keyagg_cache_ptr = NULL; + unsigned char session_secrand32[32]; + secp256k1_musig_secnonce secnonce; + secp256k1_musig_pubnonce pubnonce; + const unsigned char *sk = NULL; + const unsigned char *msg = NULL; + const unsigned char *extra_in = NULL; + secp256k1_pubkey pk; + unsigned char pubnonce66[66]; + + memcpy(session_secrand32, c->rand_, 32); + if (c->has_sk) { + sk = c->sk; + } + if (c->has_aggpk) { + /* Create keyagg_cache from aggpk */ + secp256k1_keyagg_cache_internal cache_i; + secp256k1_xonly_pubkey aggpk; + memset(&cache_i, 0, sizeof(cache_i)); + CHECK(secp256k1_xonly_pubkey_parse(CTX, &aggpk, c->aggpk)); + CHECK(secp256k1_xonly_pubkey_load(CTX, &cache_i.pk, &aggpk)); + secp256k1_keyagg_cache_save(&keyagg_cache, &cache_i); + keyagg_cache_ptr = &keyagg_cache; + } + if (c->has_msg) { + msg = c->msg; + } + if (c->has_extra_in) { + extra_in = c->extra_in; + } + + CHECK(secp256k1_ec_pubkey_parse(CTX, &pk, c->pk, sizeof(c->pk))); + CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce, &pubnonce, session_secrand32, sk, &pk, msg, keyagg_cache_ptr, extra_in) == 1); + CHECK(secp256k1_memcmp_var(&secnonce.data[4], c->expected_secnonce, 2*32) == 0); + /* The last element of the secnonce is the public key (uncompressed in + * secp256k1_musig_secnonce, compressed in the test vector secnonce). */ + CHECK(secp256k1_memcmp_var(&secnonce.data[4+2*32], &pk, sizeof(pk)) == 0); + CHECK(secp256k1_memcmp_var(&c->expected_secnonce[2*32], c->pk, sizeof(c->pk)) == 0); + + CHECK(secp256k1_musig_pubnonce_serialize(CTX, pubnonce66, &pubnonce) == 1); + CHECK(sizeof(c->expected_pubnonce) == sizeof(pubnonce66)); + CHECK(secp256k1_memcmp_var(pubnonce66, c->expected_pubnonce, sizeof(pubnonce66)) == 0); + } +} + + +static void musig_test_vectors_nonceagg(void) { + size_t i; + int j; + const struct musig_nonce_agg_vector *vector = &musig_nonce_agg_vector; + + for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) { + const struct musig_nonce_agg_test_case *c = &vector->valid_case[i]; + secp256k1_musig_pubnonce pubnonce[2]; + const secp256k1_musig_pubnonce *pubnonce_ptr[2]; + secp256k1_musig_aggnonce aggnonce; + unsigned char aggnonce66[66]; + + for (j = 0; j < 2; j++) { + CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[j], vector->pnonces[c->pnonce_indices[j]]) == 1); + pubnonce_ptr[j] = &pubnonce[j]; + } + CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2)); + CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce66, &aggnonce)); + CHECK(secp256k1_memcmp_var(aggnonce66, c->expected, 33) == 0); + } + for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) { + const struct musig_nonce_agg_test_case *c = &vector->error_case[i]; + secp256k1_musig_pubnonce pubnonce[2]; + for (j = 0; j < 2; j++) { + int expected = c->invalid_nonce_idx != j; + CHECK(expected == secp256k1_musig_pubnonce_parse(CTX, &pubnonce[j], vector->pnonces[c->pnonce_indices[j]])); + } + } +} + +static void musig_test_set_secnonce(secp256k1_musig_secnonce *secnonce, const unsigned char *secnonce64, const secp256k1_pubkey *pubkey) { + secp256k1_ge pk; + secp256k1_scalar k[2]; + + secp256k1_scalar_set_b32(&k[0], &secnonce64[0], NULL); + secp256k1_scalar_set_b32(&k[1], &secnonce64[32], NULL); + CHECK(secp256k1_pubkey_load(CTX, &pk, pubkey)); + secp256k1_musig_secnonce_save(secnonce, k, &pk); +} + +static void musig_test_vectors_signverify(void) { + size_t i; + const struct musig_sign_verify_vector *vector = &musig_sign_verify_vector; + + for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) { + const struct musig_valid_case *c = &vector->valid_case[i]; + enum MUSIG_ERROR error; + secp256k1_musig_keyagg_cache keyagg_cache; + secp256k1_pubkey pubkey; + secp256k1_musig_pubnonce pubnonce; + secp256k1_musig_aggnonce aggnonce; + secp256k1_musig_session session; + secp256k1_musig_partial_sig partial_sig; + secp256k1_musig_secnonce secnonce; + secp256k1_keypair keypair; + unsigned char partial_sig32[32]; + + CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk)); + CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL)); + + CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonces[c->aggnonce_index])); + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache)); + + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0]))); + musig_test_set_secnonce(&secnonce, vector->secnonces[0], &pubkey); + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session)); + CHECK(secp256k1_musig_partial_sig_serialize(CTX, partial_sig32, &partial_sig)); + CHECK(secp256k1_memcmp_var(partial_sig32, c->expected, sizeof(partial_sig32)) == 0); + + CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce, vector->pubnonces[0])); + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig, &pubnonce, &pubkey, &keyagg_cache, &session)); + } + for (i = 0; i < sizeof(vector->sign_error_case)/sizeof(vector->sign_error_case[0]); i++) { + const struct musig_sign_error_case *c = &vector->sign_error_case[i]; + enum MUSIG_ERROR error; + secp256k1_musig_keyagg_cache keyagg_cache; + secp256k1_pubkey pubkey; + secp256k1_musig_aggnonce aggnonce; + secp256k1_musig_session session; + secp256k1_musig_partial_sig partial_sig; + secp256k1_musig_secnonce secnonce; + secp256k1_keypair keypair; + int expected; + + if (i == 0) { + /* Skip this vector since the implementation does not error out when + * the signing key does not belong to any pubkey. */ + continue; + } + expected = c->error != MUSIG_PUBKEY; + CHECK(expected == musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL)); + CHECK(expected || c->error == error); + if (!expected) { + continue; + } + + expected = c->error != MUSIG_AGGNONCE; + CHECK(expected == secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonces[c->aggnonce_index])); + if (!expected) { + continue; + } + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache)); + + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0]))); + musig_test_set_secnonce(&secnonce, vector->secnonces[c->secnonce_index], &pubkey); + expected = c->error != MUSIG_SECNONCE; + if (expected) { + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session)); + } else { + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session)); + } + } + for (i = 0; i < sizeof(vector->verify_fail_case)/sizeof(vector->verify_fail_case[0]); i++) { + const struct musig_verify_fail_error_case *c = &vector->verify_fail_case[i]; + enum MUSIG_ERROR error; + secp256k1_musig_keyagg_cache keyagg_cache; + secp256k1_musig_aggnonce aggnonce; + secp256k1_musig_session session; + secp256k1_musig_partial_sig partial_sig; + enum { NUM_PUBNONCES = 3 }; + secp256k1_musig_pubnonce pubnonce[NUM_PUBNONCES]; + const secp256k1_musig_pubnonce *pubnonce_ptr[NUM_PUBNONCES]; + secp256k1_pubkey pubkey; + int expected; + size_t j; + + CHECK(NUM_PUBNONCES <= c->nonce_indices_len); + for (j = 0; j < c->nonce_indices_len; j++) { + CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[j], vector->pubnonces[c->nonce_indices[j]])); + pubnonce_ptr[j] = &pubnonce[j]; + } + + CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL)); + CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, c->nonce_indices_len) == 1); + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache)); + + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[c->signer_index], sizeof(vector->pubkeys[0]))); + + expected = c->error != MUSIG_SIG; + CHECK(expected == secp256k1_musig_partial_sig_parse(CTX, &partial_sig, c->sig)); + if (!expected) { + continue; + } + expected = c->error != MUSIG_SIG_VERIFY; + CHECK(expected == secp256k1_musig_partial_sig_verify(CTX, &partial_sig, pubnonce, &pubkey, &keyagg_cache, &session)); + } + for (i = 0; i < sizeof(vector->verify_error_case)/sizeof(vector->verify_error_case[0]); i++) { + const struct musig_verify_fail_error_case *c = &vector->verify_error_case[i]; + enum MUSIG_ERROR error; + secp256k1_musig_keyagg_cache keyagg_cache; + secp256k1_musig_pubnonce pubnonce; + int expected; + + expected = c->error != MUSIG_PUBKEY; + CHECK(expected == musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL)); + CHECK(expected || c->error == error); + if (!expected) { + continue; + } + expected = c->error != MUSIG_PUBNONCE; + CHECK(expected == secp256k1_musig_pubnonce_parse(CTX, &pubnonce, vector->pubnonces[c->nonce_indices[c->signer_index]])); + } +} + +static void musig_test_vectors_tweak(void) { + size_t i; + const struct musig_tweak_vector *vector = &musig_tweak_vector; + secp256k1_pubkey pubkey; + secp256k1_musig_aggnonce aggnonce; + secp256k1_musig_secnonce secnonce; + + CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonce)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0]))); + + for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) { + const struct musig_tweak_case *c = &vector->valid_case[i]; + enum MUSIG_ERROR error; + secp256k1_musig_keyagg_cache keyagg_cache; + secp256k1_musig_pubnonce pubnonce; + secp256k1_musig_session session; + secp256k1_musig_partial_sig partial_sig; + secp256k1_keypair keypair; + unsigned char partial_sig32[32]; + + musig_test_set_secnonce(&secnonce, vector->secnonce, &pubkey); + + CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk)); + CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly)); + + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msg, &keyagg_cache)); + + CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session)); + CHECK(secp256k1_musig_partial_sig_serialize(CTX, partial_sig32, &partial_sig)); + CHECK(secp256k1_memcmp_var(partial_sig32, c->expected, sizeof(partial_sig32)) == 0); + + CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce, vector->pubnonces[c->nonce_indices[c->signer_index]])); + CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig, &pubnonce, &pubkey, &keyagg_cache, &session)); + } + for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) { + const struct musig_tweak_case *c = &vector->error_case[i]; + enum MUSIG_ERROR error; + secp256k1_musig_keyagg_cache keyagg_cache; + CHECK(!musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly)); + CHECK(error == MUSIG_TWEAK); + } +} + +static void musig_test_vectors_sigagg(void) { + size_t i, j; + const struct musig_sig_agg_vector *vector = &musig_sig_agg_vector; + + for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) { + const struct musig_sig_agg_case *c = &vector->valid_case[i]; + enum MUSIG_ERROR error; + unsigned char final_sig[64]; + secp256k1_musig_keyagg_cache keyagg_cache; + unsigned char agg_pk32[32]; + secp256k1_xonly_pubkey agg_pk; + secp256k1_musig_aggnonce aggnonce; + secp256k1_musig_session session; + secp256k1_musig_partial_sig partial_sig[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))]; + const secp256k1_musig_partial_sig *partial_sig_ptr[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))]; + + CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, agg_pk32, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly)); + CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, c->aggnonce)); + CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msg, &keyagg_cache)); + for (j = 0; j < c->psig_indices_len; j++) { + CHECK(secp256k1_musig_partial_sig_parse(CTX, &partial_sig[j], vector->psigs[c->psig_indices[j]])); + partial_sig_ptr[j] = &partial_sig[j]; + } + + CHECK(secp256k1_musig_partial_sig_agg(CTX, final_sig, &session, partial_sig_ptr, c->psig_indices_len) == 1); + CHECK(secp256k1_memcmp_var(final_sig, c->expected, sizeof(final_sig)) == 0); + + CHECK(secp256k1_xonly_pubkey_parse(CTX, &agg_pk, agg_pk32)); + CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, vector->msg, sizeof(vector->msg), &agg_pk) == 1); + } + for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) { + const struct musig_sig_agg_case *c = &vector->error_case[i]; + secp256k1_musig_partial_sig partial_sig[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))]; + for (j = 0; j < c->psig_indices_len; j++) { + int expected = c->invalid_sig_idx != (int)j; + CHECK(expected == secp256k1_musig_partial_sig_parse(CTX, &partial_sig[j], vector->psigs[c->psig_indices[j]])); + } + } +} + +/* Since the BIP doesn't provide static test vectors for nonce_gen_counter, we + * define a static test here */ +static void musig_test_static_nonce_gen_counter(void) { + secp256k1_musig_secnonce secnonce; + secp256k1_musig_pubnonce pubnonce; + unsigned char pubnonce66[66]; + secp256k1_pubkey pk; + secp256k1_keypair keypair; + uint64_t nonrepeating_cnt = 0; + unsigned char sk[32] = { + 0xEE, 0xC1, 0xCB, 0x7D, 0x1B, 0x72, 0x54, 0xC5, + 0xCA, 0xB0, 0xD9, 0xC6, 0x1A, 0xB0, 0x2E, 0x64, + 0x3D, 0x46, 0x4A, 0x59, 0xFE, 0x6C, 0x96, 0xA7, + 0xEF, 0xE8, 0x71, 0xF0, 0x7C, 0x5A, 0xEF, 0x54, + }; + unsigned char expected_secnonce[64] = { + 0x84, 0x2F, 0x13, 0x80, 0xCD, 0x17, 0xA1, 0x98, + 0xFC, 0x3D, 0xAD, 0x3B, 0x7D, 0xA7, 0x49, 0x29, + 0x41, 0xF4, 0x69, 0x76, 0xF2, 0x70, 0x2F, 0xF7, + 0xC6, 0x6F, 0x24, 0xF4, 0x72, 0x03, 0x6A, 0xF1, + 0xDA, 0x3F, 0x95, 0x2D, 0xDE, 0x4A, 0x2D, 0xA6, + 0xB6, 0x32, 0x57, 0x07, 0xCE, 0x87, 0xA4, 0xE3, + 0x61, 0x6D, 0x06, 0xFC, 0x5F, 0x81, 0xA9, 0xC9, + 0x93, 0x86, 0xD2, 0x0A, 0x99, 0xCE, 0xCF, 0x99, + }; + unsigned char expected_pubnonce[66] = { + 0x03, 0xA5, 0xB9, 0xB6, 0x90, 0x79, 0x42, 0xEA, + 0xCD, 0xDA, 0x49, 0xA3, 0x66, 0x01, 0x6E, 0xC2, + 0xE6, 0x24, 0x04, 0xA1, 0xBF, 0x4A, 0xB6, 0xD4, + 0xDB, 0x82, 0x06, 0x7B, 0xC3, 0xAD, 0xF0, 0x86, + 0xD7, 0x03, 0x32, 0x05, 0xDB, 0x9E, 0xB3, 0x4D, + 0x5C, 0x7C, 0xE0, 0x28, 0x48, 0xCA, 0xC6, 0x8A, + 0x83, 0xED, 0x73, 0xE3, 0x88, 0x34, 0x77, 0xF5, + 0x63, 0xF2, 0x3C, 0xE9, 0xA1, 0x1A, 0x77, 0x21, + 0xEC, 0x64, + }; + + CHECK(secp256k1_keypair_create(CTX, &keypair, sk)); + CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair)); + CHECK(secp256k1_musig_nonce_gen_counter(CTX, &secnonce, &pubnonce, nonrepeating_cnt, &keypair, NULL, NULL, NULL) == 1); + + CHECK(secp256k1_memcmp_var(&secnonce.data[4], expected_secnonce, 2*32) == 0); + CHECK(secp256k1_memcmp_var(&secnonce.data[4+2*32], &pk, sizeof(pk)) == 0); + + CHECK(secp256k1_musig_pubnonce_serialize(CTX, pubnonce66, &pubnonce) == 1); + CHECK(secp256k1_memcmp_var(pubnonce66, expected_pubnonce, sizeof(pubnonce66)) == 0); +} + +static void run_musig_tests(void) { + int i; + + for (i = 0; i < COUNT; i++) { + musig_simple_test(); + } + musig_api_tests(); + musig_nonce_test(); + for (i = 0; i < COUNT; i++) { + /* Run multiple times to ensure that pk and nonce have different y + * parities */ + musig_tweak_test(); + } + sha256_tag_test(); + musig_test_vectors_keyagg(); + musig_test_vectors_noncegen(); + musig_test_vectors_nonceagg(); + musig_test_vectors_signverify(); + musig_test_vectors_tweak(); + musig_test_vectors_sigagg(); + + musig_test_static_nonce_gen_counter(); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/musig/vectors.h b/crypto/secp256k1/libsecp256k1/src/modules/musig/vectors.h new file mode 100644 index 0000000000..8407c2a69a --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/musig/vectors.h @@ -0,0 +1,346 @@ +/** + * Automatically generated by ./tools/test_vectors_musig2_generate.py. + * + * The test vectors for the KeySort function are included in this file. They can + * be found in src/modules/extrakeys/tests_impl.h. */ + +enum MUSIG_ERROR { + MUSIG_PUBKEY, + MUSIG_TWEAK, + MUSIG_PUBNONCE, + MUSIG_AGGNONCE, + MUSIG_SECNONCE, + MUSIG_SIG, + MUSIG_SIG_VERIFY, + MUSIG_OTHER +}; + +struct musig_key_agg_valid_test_case { + size_t key_indices_len; + size_t key_indices[4]; + unsigned char expected[32]; +}; + +struct musig_key_agg_error_test_case { + size_t key_indices_len; + size_t key_indices[4]; + size_t tweak_indices_len; + size_t tweak_indices[1]; + int is_xonly[1]; + enum MUSIG_ERROR error; +}; + +struct musig_key_agg_vector { + unsigned char pubkeys[7][33]; + unsigned char tweaks[2][32]; + struct musig_key_agg_valid_test_case valid_case[4]; + struct musig_key_agg_error_test_case error_case[5]; +}; + +static const struct musig_key_agg_vector musig_key_agg_vector = { + { + { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, + { 0x03, 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 }, + { 0x02, 0x35, 0x90, 0xA9, 0x4E, 0x76, 0x8F, 0x8E, 0x18, 0x15, 0xC2, 0xF2, 0x4B, 0x4D, 0x80, 0xA8, 0xE3, 0x14, 0x93, 0x16, 0xC3, 0x51, 0x8C, 0xE7, 0xB7, 0xAD, 0x33, 0x83, 0x68, 0xD0, 0x38, 0xCA, 0x66 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05 }, + { 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, + { 0x04, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, + { 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 } + }, + { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, + { 0x25, 0x2E, 0x4B, 0xD6, 0x74, 0x10, 0xA7, 0x6C, 0xDF, 0x93, 0x3D, 0x30, 0xEA, 0xA1, 0x60, 0x82, 0x14, 0x03, 0x7F, 0x1B, 0x10, 0x5A, 0x01, 0x3E, 0xCC, 0xD3, 0xC5, 0xC1, 0x84, 0xA6, 0x11, 0x0B } + }, + { + { 3, { 0, 1, 2 }, { 0x90, 0x53, 0x9E, 0xED, 0xE5, 0x65, 0xF5, 0xD0, 0x54, 0xF3, 0x2C, 0xC0, 0xC2, 0x20, 0x12, 0x68, 0x89, 0xED, 0x1E, 0x5D, 0x19, 0x3B, 0xAF, 0x15, 0xAE, 0xF3, 0x44, 0xFE, 0x59, 0xD4, 0x61, 0x0C }}, + { 3, { 2, 1, 0 }, { 0x62, 0x04, 0xDE, 0x8B, 0x08, 0x34, 0x26, 0xDC, 0x6E, 0xAF, 0x95, 0x02, 0xD2, 0x70, 0x24, 0xD5, 0x3F, 0xC8, 0x26, 0xBF, 0x7D, 0x20, 0x12, 0x14, 0x8A, 0x05, 0x75, 0x43, 0x5D, 0xF5, 0x4B, 0x2B }}, + { 3, { 0, 0, 0 }, { 0xB4, 0x36, 0xE3, 0xBA, 0xD6, 0x2B, 0x8C, 0xD4, 0x09, 0x96, 0x9A, 0x22, 0x47, 0x31, 0xC1, 0x93, 0xD0, 0x51, 0x16, 0x2D, 0x8C, 0x5A, 0xE8, 0xB1, 0x09, 0x30, 0x61, 0x27, 0xDA, 0x3A, 0xA9, 0x35 }}, + { 4, { 0, 0, 1, 1 }, { 0x69, 0xBC, 0x22, 0xBF, 0xA5, 0xD1, 0x06, 0x30, 0x6E, 0x48, 0xA2, 0x06, 0x79, 0xDE, 0x1D, 0x73, 0x89, 0x38, 0x61, 0x24, 0xD0, 0x75, 0x71, 0xD0, 0xD8, 0x72, 0x68, 0x60, 0x28, 0xC2, 0x6A, 0x3E }}, + }, + { + { 2, { 0, 3 }, 0, { 0 }, { 0 }, MUSIG_PUBKEY }, + { 2, { 0, 4 }, 0, { 0 }, { 0 }, MUSIG_PUBKEY }, + { 2, { 5, 0 }, 0, { 0 }, { 0 }, MUSIG_PUBKEY }, + { 2, { 0, 1 }, 1, { 0 }, { 1 }, MUSIG_TWEAK }, + { 1, { 6 }, 1, { 1 }, { 0 }, MUSIG_TWEAK }, + }, +}; + +struct musig_nonce_gen_test_case { + unsigned char rand_[32]; + int has_sk; + unsigned char sk[32]; + unsigned char pk[33]; + int has_aggpk; + unsigned char aggpk[32]; + int has_msg; + unsigned char msg[32]; + int has_extra_in; + unsigned char extra_in[32]; + unsigned char expected_secnonce[97]; + unsigned char expected_pubnonce[66]; +}; + +struct musig_nonce_gen_vector { + struct musig_nonce_gen_test_case test_case[2]; +}; + +static const struct musig_nonce_gen_vector musig_nonce_gen_vector = { + { + { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 1 , { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }, { 0x02, 0x4D, 0x4B, 0x6C, 0xD1, 0x36, 0x10, 0x32, 0xCA, 0x9B, 0xD2, 0xAE, 0xB9, 0xD9, 0x00, 0xAA, 0x4D, 0x45, 0xD9, 0xEA, 0xD8, 0x0A, 0xC9, 0x42, 0x33, 0x74, 0xC4, 0x51, 0xA7, 0x25, 0x4D, 0x07, 0x66 }, 1 , { 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 }, 1 , { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, 1 , { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, { 0xB1, 0x14, 0xE5, 0x02, 0xBE, 0xAA, 0x4E, 0x30, 0x1D, 0xD0, 0x8A, 0x50, 0x26, 0x41, 0x72, 0xC8, 0x4E, 0x41, 0x65, 0x0E, 0x6C, 0xB7, 0x26, 0xB4, 0x10, 0xC0, 0x69, 0x4D, 0x59, 0xEF, 0xFB, 0x64, 0x95, 0xB5, 0xCA, 0xF2, 0x8D, 0x04, 0x5B, 0x97, 0x3D, 0x63, 0xE3, 0xC9, 0x9A, 0x44, 0xB8, 0x07, 0xBD, 0xE3, 0x75, 0xFD, 0x6C, 0xB3, 0x9E, 0x46, 0xDC, 0x4A, 0x51, 0x17, 0x08, 0xD0, 0xE9, 0xD2, 0x02, 0x4D, 0x4B, 0x6C, 0xD1, 0x36, 0x10, 0x32, 0xCA, 0x9B, 0xD2, 0xAE, 0xB9, 0xD9, 0x00, 0xAA, 0x4D, 0x45, 0xD9, 0xEA, 0xD8, 0x0A, 0xC9, 0x42, 0x33, 0x74, 0xC4, 0x51, 0xA7, 0x25, 0x4D, 0x07, 0x66 }, { 0x02, 0xF7, 0xBE, 0x70, 0x89, 0xE8, 0x37, 0x6E, 0xB3, 0x55, 0x27, 0x23, 0x68, 0x76, 0x6B, 0x17, 0xE8, 0x8E, 0x7D, 0xB7, 0x20, 0x47, 0xD0, 0x5E, 0x56, 0xAA, 0x88, 0x1E, 0xA5, 0x2B, 0x3B, 0x35, 0xDF, 0x02, 0xC2, 0x9C, 0x80, 0x46, 0xFD, 0xD0, 0xDE, 0xD4, 0xC7, 0xE5, 0x58, 0x69, 0x13, 0x72, 0x00, 0xFB, 0xDB, 0xFE, 0x2E, 0xB6, 0x54, 0x26, 0x7B, 0x6D, 0x70, 0x13, 0x60, 0x2C, 0xAE, 0xD3, 0x11, 0x5A } }, + { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 0 , { 0 }, { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, 0 , { 0 }, 0 , { 0 }, 0 , { 0 }, { 0x89, 0xBD, 0xD7, 0x87, 0xD0, 0x28, 0x4E, 0x5E, 0x4D, 0x5F, 0xC5, 0x72, 0xE4, 0x9E, 0x31, 0x6B, 0xAB, 0x7E, 0x21, 0xE3, 0xB1, 0x83, 0x0D, 0xE3, 0x7D, 0xFE, 0x80, 0x15, 0x6F, 0xA4, 0x1A, 0x6D, 0x0B, 0x17, 0xAE, 0x8D, 0x02, 0x4C, 0x53, 0x67, 0x96, 0x99, 0xA6, 0xFD, 0x79, 0x44, 0xD9, 0xC4, 0xA3, 0x66, 0xB5, 0x14, 0xBA, 0xF4, 0x30, 0x88, 0xE0, 0x70, 0x8B, 0x10, 0x23, 0xDD, 0x28, 0x97, 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, { 0x02, 0xC9, 0x6E, 0x7C, 0xB1, 0xE8, 0xAA, 0x5D, 0xAC, 0x64, 0xD8, 0x72, 0x94, 0x79, 0x14, 0x19, 0x8F, 0x60, 0x7D, 0x90, 0xEC, 0xDE, 0x52, 0x00, 0xDE, 0x52, 0x97, 0x8A, 0xD5, 0xDE, 0xD6, 0x3C, 0x00, 0x02, 0x99, 0xEC, 0x51, 0x17, 0xC2, 0xD2, 0x9E, 0xDE, 0xE8, 0xA2, 0x09, 0x25, 0x87, 0xC3, 0x90, 0x9B, 0xE6, 0x94, 0xD5, 0xCF, 0xF0, 0x66, 0x7D, 0x6C, 0x02, 0xEA, 0x40, 0x59, 0xF7, 0xCD, 0x97, 0x86 } }, + }, +}; + +struct musig_nonce_agg_test_case { + size_t pnonce_indices[2]; + /* if valid case */ + unsigned char expected[66]; + /* if error case */ + int invalid_nonce_idx; +}; + +struct musig_nonce_agg_vector { + unsigned char pnonces[7][66]; + struct musig_nonce_agg_test_case valid_case[2]; + struct musig_nonce_agg_test_case error_case[3]; +}; + +static const struct musig_nonce_agg_vector musig_nonce_agg_vector = { + { + { 0x02, 0x01, 0x51, 0xC8, 0x0F, 0x43, 0x56, 0x48, 0xDF, 0x67, 0xA2, 0x2B, 0x74, 0x9C, 0xD7, 0x98, 0xCE, 0x54, 0xE0, 0x32, 0x1D, 0x03, 0x4B, 0x92, 0xB7, 0x09, 0xB5, 0x67, 0xD6, 0x0A, 0x42, 0xE6, 0x66, 0x03, 0xBA, 0x47, 0xFB, 0xC1, 0x83, 0x44, 0x37, 0xB3, 0x21, 0x2E, 0x89, 0xA8, 0x4D, 0x84, 0x25, 0xE7, 0xBF, 0x12, 0xE0, 0x24, 0x5D, 0x98, 0x26, 0x22, 0x68, 0xEB, 0xDC, 0xB3, 0x85, 0xD5, 0x06, 0x41 }, + { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x33 }, + { 0x02, 0x01, 0x51, 0xC8, 0x0F, 0x43, 0x56, 0x48, 0xDF, 0x67, 0xA2, 0x2B, 0x74, 0x9C, 0xD7, 0x98, 0xCE, 0x54, 0xE0, 0x32, 0x1D, 0x03, 0x4B, 0x92, 0xB7, 0x09, 0xB5, 0x67, 0xD6, 0x0A, 0x42, 0xE6, 0x66, 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 }, + { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x03, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 }, + { 0x04, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x33 }, + { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x31 }, + { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 } + }, + { + { { 0, 1 }, { 0x03, 0x5F, 0xE1, 0x87, 0x3B, 0x4F, 0x29, 0x67, 0xF5, 0x2F, 0xEA, 0x4A, 0x06, 0xAD, 0x5A, 0x8E, 0xCC, 0xBE, 0x9D, 0x0F, 0xD7, 0x30, 0x68, 0x01, 0x2C, 0x89, 0x4E, 0x2E, 0x87, 0xCC, 0xB5, 0x80, 0x4B, 0x02, 0x47, 0x25, 0x37, 0x73, 0x45, 0xBD, 0xE0, 0xE9, 0xC3, 0x3A, 0xF3, 0xC4, 0x3C, 0x0A, 0x29, 0xA9, 0x24, 0x9F, 0x2F, 0x29, 0x56, 0xFA, 0x8C, 0xFE, 0xB5, 0x5C, 0x85, 0x73, 0xD0, 0x26, 0x2D, 0xC8 }, 0 }, + { { 2, 3 }, { 0x03, 0x5F, 0xE1, 0x87, 0x3B, 0x4F, 0x29, 0x67, 0xF5, 0x2F, 0xEA, 0x4A, 0x06, 0xAD, 0x5A, 0x8E, 0xCC, 0xBE, 0x9D, 0x0F, 0xD7, 0x30, 0x68, 0x01, 0x2C, 0x89, 0x4E, 0x2E, 0x87, 0xCC, 0xB5, 0x80, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0 }, + }, + { + { { 0, 4 }, { 0 }, 1 }, + { { 5, 1 }, { 0 }, 0 }, + { { 6, 1 }, { 0 }, 0 }, + }, +}; + +/* Omit pubnonces in the test vectors because our partial signature verification + * implementation is able to accept the aggnonce directly. */ +struct musig_valid_case { + size_t key_indices_len; + size_t key_indices[3]; + size_t aggnonce_index; + size_t msg_index; + size_t signer_index; + unsigned char expected[32]; +}; + +struct musig_sign_error_case { + size_t key_indices_len; + size_t key_indices[3]; + size_t aggnonce_index; + size_t msg_index; + size_t secnonce_index; + enum MUSIG_ERROR error; +}; + +struct musig_verify_fail_error_case { + unsigned char sig[32]; + size_t key_indices_len; + size_t key_indices[3]; + size_t nonce_indices_len; + size_t nonce_indices[3]; + size_t msg_index; + size_t signer_index; + enum MUSIG_ERROR error; +}; + +struct musig_sign_verify_vector { + unsigned char sk[32]; + unsigned char pubkeys[4][33]; + unsigned char secnonces[2][194]; + unsigned char pubnonces[5][194]; + unsigned char aggnonces[5][66]; + unsigned char msgs[1][32]; + struct musig_valid_case valid_case[4]; + struct musig_sign_error_case sign_error_case[6]; + struct musig_verify_fail_error_case verify_fail_case[3]; + struct musig_verify_fail_error_case verify_error_case[2]; +}; + +static const struct musig_sign_verify_vector musig_sign_verify_vector = { + { 0x7F, 0xB9, 0xE0, 0xE6, 0x87, 0xAD, 0xA1, 0xEE, 0xBF, 0x7E, 0xCF, 0xE2, 0xF2, 0x1E, 0x73, 0xEB, 0xDB, 0x51, 0xA7, 0xD4, 0x50, 0x94, 0x8D, 0xFE, 0x8D, 0x76, 0xD7, 0xF2, 0xD1, 0x00, 0x76, 0x71 }, + { + { 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 }, + { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, + { 0x02, 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x61 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 } + }, + { + { 0x50, 0x8B, 0x81, 0xA6, 0x11, 0xF1, 0x00, 0xA6, 0xB2, 0xB6, 0xB2, 0x96, 0x56, 0x59, 0x08, 0x98, 0xAF, 0x48, 0x8B, 0xCF, 0x2E, 0x1F, 0x55, 0xCF, 0x22, 0xE5, 0xCF, 0xB8, 0x44, 0x21, 0xFE, 0x61, 0xFA, 0x27, 0xFD, 0x49, 0xB1, 0xD5, 0x00, 0x85, 0xB4, 0x81, 0x28, 0x5E, 0x1C, 0xA2, 0x05, 0xD5, 0x5C, 0x82, 0xCC, 0x1B, 0x31, 0xFF, 0x5C, 0xD5, 0x4A, 0x48, 0x98, 0x29, 0x35, 0x59, 0x01, 0xF7, 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 } + }, + { + { 0x03, 0x37, 0xC8, 0x78, 0x21, 0xAF, 0xD5, 0x0A, 0x86, 0x44, 0xD8, 0x20, 0xA8, 0xF3, 0xE0, 0x2E, 0x49, 0x9C, 0x93, 0x18, 0x65, 0xC2, 0x36, 0x0F, 0xB4, 0x3D, 0x0A, 0x0D, 0x20, 0xDA, 0xFE, 0x07, 0xEA, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, + { 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 }, + { 0x03, 0x2D, 0xE2, 0x66, 0x26, 0x28, 0xC9, 0x0B, 0x03, 0xF5, 0xE7, 0x20, 0x28, 0x4E, 0xB5, 0x2F, 0xF7, 0xD7, 0x1F, 0x42, 0x84, 0xF6, 0x27, 0xB6, 0x8A, 0x85, 0x3D, 0x78, 0xC7, 0x8E, 0x1F, 0xFE, 0x93, 0x03, 0xE4, 0xC5, 0x52, 0x4E, 0x83, 0xFF, 0xE1, 0x49, 0x3B, 0x90, 0x77, 0xCF, 0x1C, 0xA6, 0xBE, 0xB2, 0x09, 0x0C, 0x93, 0xD9, 0x30, 0x32, 0x10, 0x71, 0xAD, 0x40, 0xB2, 0xF4, 0x4E, 0x59, 0x90, 0x46 }, + { 0x02, 0x37, 0xC8, 0x78, 0x21, 0xAF, 0xD5, 0x0A, 0x86, 0x44, 0xD8, 0x20, 0xA8, 0xF3, 0xE0, 0x2E, 0x49, 0x9C, 0x93, 0x18, 0x65, 0xC2, 0x36, 0x0F, 0xB4, 0x3D, 0x0A, 0x0D, 0x20, 0xDA, 0xFE, 0x07, 0xEA, 0x03, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 } + }, + { + { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, + { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, + { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 } + }, + { + { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF } + }, + { + { 3, { 0, 1, 2 }, 0, 0, 0, { 0x01, 0x2A, 0xBB, 0xCB, 0x52, 0xB3, 0x01, 0x6A, 0xC0, 0x3A, 0xD8, 0x23, 0x95, 0xA1, 0xA4, 0x15, 0xC4, 0x8B, 0x93, 0xDE, 0xF7, 0x87, 0x18, 0xE6, 0x2A, 0x7A, 0x90, 0x05, 0x2F, 0xE2, 0x24, 0xFB }}, + { 3, { 1, 0, 2 }, 0, 0, 1, { 0x9F, 0xF2, 0xF7, 0xAA, 0xA8, 0x56, 0x15, 0x0C, 0xC8, 0x81, 0x92, 0x54, 0x21, 0x8D, 0x3A, 0xDE, 0xEB, 0x05, 0x35, 0x26, 0x90, 0x51, 0x89, 0x77, 0x24, 0xF9, 0xDB, 0x37, 0x89, 0x51, 0x3A, 0x52 }}, + { 3, { 1, 2, 0 }, 0, 0, 2, { 0xFA, 0x23, 0xC3, 0x59, 0xF6, 0xFA, 0xC4, 0xE7, 0x79, 0x6B, 0xB9, 0x3B, 0xC9, 0xF0, 0x53, 0x2A, 0x95, 0x46, 0x8C, 0x53, 0x9B, 0xA2, 0x0F, 0xF8, 0x6D, 0x7C, 0x76, 0xED, 0x92, 0x22, 0x79, 0x00 }}, + { 2, { 0, 1 }, 1, 0, 0, { 0xAE, 0x38, 0x60, 0x64, 0xB2, 0x61, 0x05, 0x40, 0x47, 0x98, 0xF7, 0x5D, 0xE2, 0xEB, 0x9A, 0xF5, 0xED, 0xA5, 0x38, 0x7B, 0x06, 0x4B, 0x83, 0xD0, 0x49, 0xCB, 0x7C, 0x5E, 0x08, 0x87, 0x95, 0x31 }}, + }, + { + { 2, { 1, 2 }, 0, 0, 0, MUSIG_PUBKEY }, + { 3, { 1, 0, 3 }, 0, 0, 0, MUSIG_PUBKEY }, + { 3, { 1, 2, 0 }, 2, 0, 0, MUSIG_AGGNONCE }, + { 3, { 1, 2, 0 }, 3, 0, 0, MUSIG_AGGNONCE }, + { 3, { 1, 2, 0 }, 4, 0, 0, MUSIG_AGGNONCE }, + { 3, { 0, 1, 2 }, 0, 0, 1, MUSIG_SECNONCE }, + }, + { + { { 0xFE, 0xD5, 0x44, 0x34, 0xAD, 0x4C, 0xFE, 0x95, 0x3F, 0xC5, 0x27, 0xDC, 0x6A, 0x5E, 0x5B, 0xE8, 0xF6, 0x23, 0x49, 0x07, 0xB7, 0xC1, 0x87, 0x55, 0x95, 0x57, 0xCE, 0x87, 0xA0, 0x54, 0x1C, 0x46 }, 3, { 0, 1, 2 }, 3, { 0, 1, 2 }, 0, 0, MUSIG_SIG_VERIFY }, + { { 0x01, 0x2A, 0xBB, 0xCB, 0x52, 0xB3, 0x01, 0x6A, 0xC0, 0x3A, 0xD8, 0x23, 0x95, 0xA1, 0xA4, 0x15, 0xC4, 0x8B, 0x93, 0xDE, 0xF7, 0x87, 0x18, 0xE6, 0x2A, 0x7A, 0x90, 0x05, 0x2F, 0xE2, 0x24, 0xFB }, 3, { 0, 1, 2 }, 3, { 0, 1, 2 }, 0, 1, MUSIG_SIG_VERIFY }, + { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, 3, { 0, 1, 2 }, 3, { 0, 1, 2 }, 0, 0, MUSIG_SIG }, + }, + { + { { 0x01, 0x2A, 0xBB, 0xCB, 0x52, 0xB3, 0x01, 0x6A, 0xC0, 0x3A, 0xD8, 0x23, 0x95, 0xA1, 0xA4, 0x15, 0xC4, 0x8B, 0x93, 0xDE, 0xF7, 0x87, 0x18, 0xE6, 0x2A, 0x7A, 0x90, 0x05, 0x2F, 0xE2, 0x24, 0xFB }, 3, { 0, 1, 2 }, 3, { 4, 1, 2 }, 0, 0, MUSIG_PUBNONCE }, + { { 0x01, 0x2A, 0xBB, 0xCB, 0x52, 0xB3, 0x01, 0x6A, 0xC0, 0x3A, 0xD8, 0x23, 0x95, 0xA1, 0xA4, 0x15, 0xC4, 0x8B, 0x93, 0xDE, 0xF7, 0x87, 0x18, 0xE6, 0x2A, 0x7A, 0x90, 0x05, 0x2F, 0xE2, 0x24, 0xFB }, 3, { 3, 1, 2 }, 3, { 0, 1, 2 }, 0, 0, MUSIG_PUBKEY }, + }, +}; + +struct musig_tweak_case { + size_t key_indices_len; + size_t key_indices[3]; + size_t nonce_indices_len; + size_t nonce_indices[3]; + size_t tweak_indices_len; + size_t tweak_indices[4]; + int is_xonly[4]; + size_t signer_index; + unsigned char expected[32]; +}; + +struct musig_tweak_vector { + unsigned char sk[32]; + unsigned char secnonce[97]; + unsigned char aggnonce[66]; + unsigned char msg[32]; + unsigned char pubkeys[3][33]; + unsigned char pubnonces[3][194]; + unsigned char tweaks[5][32]; + struct musig_tweak_case valid_case[5]; + struct musig_tweak_case error_case[1]; +}; + +static const struct musig_tweak_vector musig_tweak_vector = { + { 0x7F, 0xB9, 0xE0, 0xE6, 0x87, 0xAD, 0xA1, 0xEE, 0xBF, 0x7E, 0xCF, 0xE2, 0xF2, 0x1E, 0x73, 0xEB, 0xDB, 0x51, 0xA7, 0xD4, 0x50, 0x94, 0x8D, 0xFE, 0x8D, 0x76, 0xD7, 0xF2, 0xD1, 0x00, 0x76, 0x71 }, + { 0x50, 0x8B, 0x81, 0xA6, 0x11, 0xF1, 0x00, 0xA6, 0xB2, 0xB6, 0xB2, 0x96, 0x56, 0x59, 0x08, 0x98, 0xAF, 0x48, 0x8B, 0xCF, 0x2E, 0x1F, 0x55, 0xCF, 0x22, 0xE5, 0xCF, 0xB8, 0x44, 0x21, 0xFE, 0x61, 0xFA, 0x27, 0xFD, 0x49, 0xB1, 0xD5, 0x00, 0x85, 0xB4, 0x81, 0x28, 0x5E, 0x1C, 0xA2, 0x05, 0xD5, 0x5C, 0x82, 0xCC, 0x1B, 0x31, 0xFF, 0x5C, 0xD5, 0x4A, 0x48, 0x98, 0x29, 0x35, 0x59, 0x01, 0xF7, 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 }, + { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, + { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, + { + { 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 }, + { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, + { 0x02, 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 } + }, + { + { 0x03, 0x37, 0xC8, 0x78, 0x21, 0xAF, 0xD5, 0x0A, 0x86, 0x44, 0xD8, 0x20, 0xA8, 0xF3, 0xE0, 0x2E, 0x49, 0x9C, 0x93, 0x18, 0x65, 0xC2, 0x36, 0x0F, 0xB4, 0x3D, 0x0A, 0x0D, 0x20, 0xDA, 0xFE, 0x07, 0xEA, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, + { 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 }, + { 0x03, 0x2D, 0xE2, 0x66, 0x26, 0x28, 0xC9, 0x0B, 0x03, 0xF5, 0xE7, 0x20, 0x28, 0x4E, 0xB5, 0x2F, 0xF7, 0xD7, 0x1F, 0x42, 0x84, 0xF6, 0x27, 0xB6, 0x8A, 0x85, 0x3D, 0x78, 0xC7, 0x8E, 0x1F, 0xFE, 0x93, 0x03, 0xE4, 0xC5, 0x52, 0x4E, 0x83, 0xFF, 0xE1, 0x49, 0x3B, 0x90, 0x77, 0xCF, 0x1C, 0xA6, 0xBE, 0xB2, 0x09, 0x0C, 0x93, 0xD9, 0x30, 0x32, 0x10, 0x71, 0xAD, 0x40, 0xB2, 0xF4, 0x4E, 0x59, 0x90, 0x46 } + }, + { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } + }, + { + { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 1, { 0 }, { 1 }, 2, { 0xE2, 0x8A, 0x5C, 0x66, 0xE6, 0x1E, 0x17, 0x8C, 0x2B, 0xA1, 0x9D, 0xB7, 0x7B, 0x6C, 0xF9, 0xF7, 0xE2, 0xF0, 0xF5, 0x6C, 0x17, 0x91, 0x8C, 0xD1, 0x31, 0x35, 0xE6, 0x0C, 0xC8, 0x48, 0xFE, 0x91 }}, + { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 1, { 0 }, { 0 }, 2, { 0x38, 0xB0, 0x76, 0x77, 0x98, 0x25, 0x2F, 0x21, 0xBF, 0x57, 0x02, 0xC4, 0x80, 0x28, 0xB0, 0x95, 0x42, 0x83, 0x20, 0xF7, 0x3A, 0x4B, 0x14, 0xDB, 0x1E, 0x25, 0xDE, 0x58, 0x54, 0x3D, 0x2D, 0x2D }}, + { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 2, { 0, 1 }, { 0, 1 }, 2, { 0x40, 0x8A, 0x0A, 0x21, 0xC4, 0xA0, 0xF5, 0xDA, 0xCA, 0xF9, 0x64, 0x6A, 0xD6, 0xEB, 0x6F, 0xEC, 0xD7, 0xF7, 0xA1, 0x1F, 0x03, 0xED, 0x1F, 0x48, 0xDF, 0xFF, 0x21, 0x85, 0xBC, 0x2C, 0x24, 0x08 }}, + { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, 2, { 0x45, 0xAB, 0xD2, 0x06, 0xE6, 0x1E, 0x3D, 0xF2, 0xEC, 0x9E, 0x26, 0x4A, 0x6F, 0xEC, 0x82, 0x92, 0x14, 0x1A, 0x63, 0x3C, 0x28, 0x58, 0x63, 0x88, 0x23, 0x55, 0x41, 0xF9, 0xAD, 0xE7, 0x54, 0x35 }}, + { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 4, { 0, 1, 2, 3 }, { 1, 0, 1, 0 }, 2, { 0xB2, 0x55, 0xFD, 0xCA, 0xC2, 0x7B, 0x40, 0xC7, 0xCE, 0x78, 0x48, 0xE2, 0xD3, 0xB7, 0xBF, 0x5E, 0xA0, 0xED, 0x75, 0x6D, 0xA8, 0x15, 0x65, 0xAC, 0x80, 0x4C, 0xCC, 0xA3, 0xE1, 0xD5, 0xD2, 0x39 }}, + }, + { + { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 1, { 4 }, { 0 }, 2, { 0 }}, + }, +}; + +/* Omit pubnonces in the test vectors because they're only needed for + * implementations that do not directly accept an aggnonce. */ +struct musig_sig_agg_case { + size_t key_indices_len; + size_t key_indices[2]; + size_t tweak_indices_len; + size_t tweak_indices[3]; + int is_xonly[3]; + unsigned char aggnonce[66]; + size_t psig_indices_len; + size_t psig_indices[2]; + /* if valid case */ + unsigned char expected[64]; + /* if error case */ + int invalid_sig_idx; +}; + +struct musig_sig_agg_vector { + unsigned char pubkeys[4][33]; + unsigned char tweaks[3][32]; + unsigned char psigs[9][32]; + unsigned char msg[32]; + struct musig_sig_agg_case valid_case[4]; + struct musig_sig_agg_case error_case[1]; +}; + +static const struct musig_sig_agg_vector musig_sig_agg_vector = { + { + { 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 }, + { 0x02, 0xD2, 0xDC, 0x6F, 0x5D, 0xF7, 0xC5, 0x6A, 0xCF, 0x38, 0xC7, 0xFA, 0x0A, 0xE7, 0xA7, 0x59, 0xAE, 0x30, 0xE1, 0x9B, 0x37, 0x35, 0x9D, 0xFD, 0xE0, 0x15, 0x87, 0x23, 0x24, 0xC7, 0xEF, 0x6E, 0x05 }, + { 0x03, 0xC7, 0xFB, 0x10, 0x1D, 0x97, 0xFF, 0x93, 0x0A, 0xCD, 0x0C, 0x67, 0x60, 0x85, 0x2E, 0xF6, 0x4E, 0x69, 0x08, 0x3D, 0xE0, 0xB0, 0x6A, 0xC6, 0x33, 0x57, 0x24, 0x75, 0x4B, 0xB4, 0xB0, 0x52, 0x2C }, + { 0x02, 0x35, 0x24, 0x33, 0xB2, 0x1E, 0x7E, 0x05, 0xD3, 0xB4, 0x52, 0xB8, 0x1C, 0xAE, 0x56, 0x6E, 0x06, 0xD2, 0xE0, 0x03, 0xEC, 0xE1, 0x6D, 0x10, 0x74, 0xAA, 0xBA, 0x42, 0x89, 0xE0, 0xE3, 0xD5, 0x81 } + }, + { + { 0xB5, 0x11, 0xDA, 0x49, 0x21, 0x82, 0xA9, 0x1B, 0x0F, 0xFB, 0x9A, 0x98, 0x02, 0x0D, 0x55, 0xF2, 0x60, 0xAE, 0x86, 0xD7, 0xEC, 0xBD, 0x03, 0x99, 0xC7, 0x38, 0x3D, 0x59, 0xA5, 0xF2, 0xAF, 0x7C }, + { 0xA8, 0x15, 0xFE, 0x04, 0x9E, 0xE3, 0xC5, 0xAA, 0xB6, 0x63, 0x10, 0x47, 0x7F, 0xBC, 0x8B, 0xCC, 0xCA, 0xC2, 0xF3, 0x39, 0x5F, 0x59, 0xF9, 0x21, 0xC3, 0x64, 0xAC, 0xD7, 0x8A, 0x2F, 0x48, 0xDC }, + { 0x75, 0x44, 0x8A, 0x87, 0x27, 0x4B, 0x05, 0x64, 0x68, 0xB9, 0x77, 0xBE, 0x06, 0xEB, 0x1E, 0x9F, 0x65, 0x75, 0x77, 0xB7, 0x32, 0x0B, 0x0A, 0x33, 0x76, 0xEA, 0x51, 0xFD, 0x42, 0x0D, 0x18, 0xA8 } + }, + { + { 0xB1, 0x5D, 0x2C, 0xD3, 0xC3, 0xD2, 0x2B, 0x04, 0xDA, 0xE4, 0x38, 0xCE, 0x65, 0x3F, 0x6B, 0x4E, 0xCF, 0x04, 0x2F, 0x42, 0xCF, 0xDE, 0xD7, 0xC4, 0x1B, 0x64, 0xAA, 0xF9, 0xB4, 0xAF, 0x53, 0xFB }, + { 0x61, 0x93, 0xD6, 0xAC, 0x61, 0xB3, 0x54, 0xE9, 0x10, 0x5B, 0xBD, 0xC8, 0x93, 0x7A, 0x34, 0x54, 0xA6, 0xD7, 0x05, 0xB6, 0xD5, 0x73, 0x22, 0xA5, 0xA4, 0x72, 0xA0, 0x2C, 0xE9, 0x9F, 0xCB, 0x64 }, + { 0x9A, 0x87, 0xD3, 0xB7, 0x9E, 0xC6, 0x72, 0x28, 0xCB, 0x97, 0x87, 0x8B, 0x76, 0x04, 0x9B, 0x15, 0xDB, 0xD0, 0x5B, 0x81, 0x58, 0xD1, 0x7B, 0x5B, 0x91, 0x14, 0xD3, 0xC2, 0x26, 0x88, 0x75, 0x05 }, + { 0x66, 0xF8, 0x2E, 0xA9, 0x09, 0x23, 0x68, 0x9B, 0x85, 0x5D, 0x36, 0xC6, 0xB7, 0xE0, 0x32, 0xFB, 0x99, 0x70, 0x30, 0x14, 0x81, 0xB9, 0x9E, 0x01, 0xCD, 0xB4, 0xD6, 0xAC, 0x7C, 0x34, 0x7A, 0x15 }, + { 0x4F, 0x5A, 0xEE, 0x41, 0x51, 0x08, 0x48, 0xA6, 0x44, 0x7D, 0xCD, 0x1B, 0xBC, 0x78, 0x45, 0x7E, 0xF6, 0x90, 0x24, 0x94, 0x4C, 0x87, 0xF4, 0x02, 0x50, 0xD3, 0xEF, 0x2C, 0x25, 0xD3, 0x3E, 0xFE }, + { 0xDD, 0xEF, 0x42, 0x7B, 0xBB, 0x84, 0x7C, 0xC0, 0x27, 0xBE, 0xFF, 0x4E, 0xDB, 0x01, 0x03, 0x81, 0x48, 0x91, 0x78, 0x32, 0x25, 0x3E, 0xBC, 0x35, 0x5F, 0xC3, 0x3F, 0x4A, 0x8E, 0x2F, 0xCC, 0xE4 }, + { 0x97, 0xB8, 0x90, 0xA2, 0x6C, 0x98, 0x1D, 0xA8, 0x10, 0x2D, 0x3B, 0xC2, 0x94, 0x15, 0x9D, 0x17, 0x1D, 0x72, 0x81, 0x0F, 0xDF, 0x7C, 0x6A, 0x69, 0x1D, 0xEF, 0x02, 0xF0, 0xF7, 0xAF, 0x3F, 0xDC }, + { 0x53, 0xFA, 0x9E, 0x08, 0xBA, 0x52, 0x43, 0xCB, 0xCB, 0x0D, 0x79, 0x7C, 0x5E, 0xE8, 0x3B, 0xC6, 0x72, 0x8E, 0x53, 0x9E, 0xB7, 0x6C, 0x2D, 0x0B, 0xF0, 0xF9, 0x71, 0xEE, 0x4E, 0x90, 0x99, 0x71 }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } + }, + { 0x59, 0x9C, 0x67, 0xEA, 0x41, 0x0D, 0x00, 0x5B, 0x9D, 0xA9, 0x08, 0x17, 0xCF, 0x03, 0xED, 0x3B, 0x1C, 0x86, 0x8E, 0x4D, 0xA4, 0xED, 0xF0, 0x0A, 0x58, 0x80, 0xB0, 0x08, 0x2C, 0x23, 0x78, 0x69 }, + { + { 2, { 0, 1 }, 0, { 0 }, { 0 }, { 0x03, 0x41, 0x43, 0x27, 0x22, 0xC5, 0xCD, 0x02, 0x68, 0xD8, 0x29, 0xC7, 0x02, 0xCF, 0x0D, 0x1C, 0xBC, 0xE5, 0x70, 0x33, 0xEE, 0xD2, 0x01, 0xFD, 0x33, 0x51, 0x91, 0x38, 0x52, 0x27, 0xC3, 0x21, 0x0C, 0x03, 0xD3, 0x77, 0xF2, 0xD2, 0x58, 0xB6, 0x4A, 0xAD, 0xC0, 0xE1, 0x6F, 0x26, 0x46, 0x23, 0x23, 0xD7, 0x01, 0xD2, 0x86, 0x04, 0x6A, 0x2E, 0xA9, 0x33, 0x65, 0x65, 0x6A, 0xFD, 0x98, 0x75, 0x98, 0x2B }, 2, { 0, 1 }, { 0x04, 0x1D, 0xA2, 0x22, 0x23, 0xCE, 0x65, 0xC9, 0x2C, 0x9A, 0x0D, 0x6C, 0x2C, 0xAC, 0x82, 0x8A, 0xAF, 0x1E, 0xEE, 0x56, 0x30, 0x4F, 0xEC, 0x37, 0x1D, 0xDF, 0x91, 0xEB, 0xB2, 0xB9, 0xEF, 0x09, 0x12, 0xF1, 0x03, 0x80, 0x25, 0x85, 0x7F, 0xED, 0xEB, 0x3F, 0xF6, 0x96, 0xF8, 0xB9, 0x9F, 0xA4, 0xBB, 0x2C, 0x58, 0x12, 0xF6, 0x09, 0x5A, 0x2E, 0x00, 0x04, 0xEC, 0x99, 0xCE, 0x18, 0xDE, 0x1E }, 0 }, + { 2, { 0, 2 }, 0, { 0 }, { 0 }, { 0x02, 0x24, 0xAF, 0xD3, 0x6C, 0x90, 0x20, 0x84, 0x05, 0x8B, 0x51, 0xB5, 0xD3, 0x66, 0x76, 0xBB, 0xA4, 0xDC, 0x97, 0xC7, 0x75, 0x87, 0x37, 0x68, 0xE5, 0x88, 0x22, 0xF8, 0x7F, 0xE4, 0x37, 0xD7, 0x92, 0x02, 0x8C, 0xB1, 0x59, 0x29, 0x09, 0x9E, 0xEE, 0x2F, 0x5D, 0xAE, 0x40, 0x4C, 0xD3, 0x93, 0x57, 0x59, 0x1B, 0xA3, 0x2E, 0x9A, 0xF4, 0xE1, 0x62, 0xB8, 0xD3, 0xE7, 0xCB, 0x5E, 0xFE, 0x31, 0xCB, 0x20 }, 2, { 2, 3 }, { 0x10, 0x69, 0xB6, 0x7E, 0xC3, 0xD2, 0xF3, 0xC7, 0xC0, 0x82, 0x91, 0xAC, 0xCB, 0x17, 0xA9, 0xC9, 0xB8, 0xF2, 0x81, 0x9A, 0x52, 0xEB, 0x5D, 0xF8, 0x72, 0x6E, 0x17, 0xE7, 0xD6, 0xB5, 0x2E, 0x9F, 0x01, 0x80, 0x02, 0x60, 0xA7, 0xE9, 0xDA, 0xC4, 0x50, 0xF4, 0xBE, 0x52, 0x2D, 0xE4, 0xCE, 0x12, 0xBA, 0x91, 0xAE, 0xAF, 0x2B, 0x42, 0x79, 0x21, 0x9E, 0xF7, 0x4B, 0xE1, 0xD2, 0x86, 0xAD, 0xD9 }, 0 }, + { 2, { 0, 2 }, 1, { 0 }, { 0 }, { 0x02, 0x08, 0xC5, 0xC4, 0x38, 0xC7, 0x10, 0xF4, 0xF9, 0x6A, 0x61, 0xE9, 0xFF, 0x3C, 0x37, 0x75, 0x88, 0x14, 0xB8, 0xC3, 0xAE, 0x12, 0xBF, 0xEA, 0x0E, 0xD2, 0xC8, 0x7F, 0xF6, 0x95, 0x4F, 0xF1, 0x86, 0x02, 0x0B, 0x18, 0x16, 0xEA, 0x10, 0x4B, 0x4F, 0xCA, 0x2D, 0x30, 0x4D, 0x73, 0x3E, 0x0E, 0x19, 0xCE, 0xAD, 0x51, 0x30, 0x3F, 0xF6, 0x42, 0x0B, 0xFD, 0x22, 0x23, 0x35, 0xCA, 0xA4, 0x02, 0x91, 0x6D }, 2, { 4, 5 }, { 0x5C, 0x55, 0x8E, 0x1D, 0xCA, 0xDE, 0x86, 0xDA, 0x0B, 0x2F, 0x02, 0x62, 0x6A, 0x51, 0x2E, 0x30, 0xA2, 0x2C, 0xF5, 0x25, 0x5C, 0xAE, 0xA7, 0xEE, 0x32, 0xC3, 0x8E, 0x9A, 0x71, 0xA0, 0xE9, 0x14, 0x8B, 0xA6, 0xC0, 0xE6, 0xEC, 0x76, 0x83, 0xB6, 0x42, 0x20, 0xF0, 0x29, 0x86, 0x96, 0xF1, 0xB8, 0x78, 0xCD, 0x47, 0xB1, 0x07, 0xB8, 0x1F, 0x71, 0x88, 0x81, 0x2D, 0x59, 0x39, 0x71, 0xE0, 0xCC }, 0 }, + { 2, { 0, 3 }, 3, { 0, 1, 2 }, { 1, 0, 1 }, { 0x02, 0xB5, 0xAD, 0x07, 0xAF, 0xCD, 0x99, 0xB6, 0xD9, 0x2C, 0xB4, 0x33, 0xFB, 0xD2, 0xA2, 0x8F, 0xDE, 0xB9, 0x8E, 0xAE, 0x2E, 0xB0, 0x9B, 0x60, 0x14, 0xEF, 0x0F, 0x81, 0x97, 0xCD, 0x58, 0x40, 0x33, 0x02, 0xE8, 0x61, 0x69, 0x10, 0xF9, 0x29, 0x3C, 0xF6, 0x92, 0xC4, 0x9F, 0x35, 0x1D, 0xB8, 0x6B, 0x25, 0xE3, 0x52, 0x90, 0x1F, 0x0E, 0x23, 0x7B, 0xAF, 0xDA, 0x11, 0xF1, 0xC1, 0xCE, 0xF2, 0x9F, 0xFD }, 2, { 6, 7 }, { 0x83, 0x9B, 0x08, 0x82, 0x0B, 0x68, 0x1D, 0xBA, 0x8D, 0xAF, 0x4C, 0xC7, 0xB1, 0x04, 0xE8, 0xF2, 0x63, 0x8F, 0x93, 0x88, 0xF8, 0xD7, 0xA5, 0x55, 0xDC, 0x17, 0xB6, 0xE6, 0x97, 0x1D, 0x74, 0x26, 0xCE, 0x07, 0xBF, 0x6A, 0xB0, 0x1F, 0x1D, 0xB5, 0x0E, 0x4E, 0x33, 0x71, 0x92, 0x95, 0xF4, 0x09, 0x45, 0x72, 0xB7, 0x98, 0x68, 0xE4, 0x40, 0xFB, 0x3D, 0xEF, 0xD3, 0xFA, 0xC1, 0xDB, 0x58, 0x9E }, 0 }, + }, + { + { 2, { 0, 3 }, 3, { 0, 1, 2 }, { 1, 0, 1 }, { 0x02, 0xB5, 0xAD, 0x07, 0xAF, 0xCD, 0x99, 0xB6, 0xD9, 0x2C, 0xB4, 0x33, 0xFB, 0xD2, 0xA2, 0x8F, 0xDE, 0xB9, 0x8E, 0xAE, 0x2E, 0xB0, 0x9B, 0x60, 0x14, 0xEF, 0x0F, 0x81, 0x97, 0xCD, 0x58, 0x40, 0x33, 0x02, 0xE8, 0x61, 0x69, 0x10, 0xF9, 0x29, 0x3C, 0xF6, 0x92, 0xC4, 0x9F, 0x35, 0x1D, 0xB8, 0x6B, 0x25, 0xE3, 0x52, 0x90, 0x1F, 0x0E, 0x23, 0x7B, 0xAF, 0xDA, 0x11, 0xF1, 0xC1, 0xCE, 0xF2, 0x9F, 0xFD }, 2, { 7, 8 }, { 0 }, 1 }, + }, +}; +enum { MUSIG_VECTORS_MAX_PUBKEYS = 7 }; diff --git a/crypto/secp256k1/libsecp256k1/src/modules/recovery/Makefile.am.include b/crypto/secp256k1/libsecp256k1/src/modules/recovery/Makefile.am.include index bf23c26e71..156ea690fa 100644 --- a/crypto/secp256k1/libsecp256k1/src/modules/recovery/Makefile.am.include +++ b/crypto/secp256k1/libsecp256k1/src/modules/recovery/Makefile.am.include @@ -1,8 +1,5 @@ include_HEADERS += include/secp256k1_recovery.h noinst_HEADERS += src/modules/recovery/main_impl.h noinst_HEADERS += src/modules/recovery/tests_impl.h -if USE_BENCHMARK -noinst_PROGRAMS += bench_recover -bench_recover_SOURCES = src/bench_recover.c -bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) -endif +noinst_HEADERS += src/modules/recovery/tests_exhaustive_impl.h +noinst_HEADERS += src/modules/recovery/bench_impl.h diff --git a/crypto/secp256k1/libsecp256k1/src/bench_recover.c b/crypto/secp256k1/libsecp256k1/src/modules/recovery/bench_impl.h similarity index 58% rename from crypto/secp256k1/libsecp256k1/src/bench_recover.c rename to crypto/secp256k1/libsecp256k1/src/modules/recovery/bench_impl.h index 6489378cc6..57108d4524 100644 --- a/crypto/secp256k1/libsecp256k1/src/bench_recover.c +++ b/crypto/secp256k1/libsecp256k1/src/modules/recovery/bench_impl.h @@ -1,27 +1,27 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#include "include/secp256k1.h" -#include "include/secp256k1_recovery.h" -#include "util.h" -#include "bench.h" +#ifndef SECP256K1_MODULE_RECOVERY_BENCH_H +#define SECP256K1_MODULE_RECOVERY_BENCH_H + +#include "../../../include/secp256k1_recovery.h" typedef struct { secp256k1_context *ctx; unsigned char msg[32]; unsigned char sig[64]; -} bench_recover_t; +} bench_recover_data; -void bench_recover(void* arg) { +static void bench_recover(void* arg, int iters) { int i; - bench_recover_t *data = (bench_recover_t*)arg; + bench_recover_data *data = (bench_recover_data*)arg; secp256k1_pubkey pubkey; unsigned char pubkeyc[33]; - for (i = 0; i < 20000; i++) { + for (i = 0; i < iters; i++) { int j; size_t pubkeylen = 33; secp256k1_ecdsa_recoverable_signature sig; @@ -36,9 +36,9 @@ void bench_recover(void* arg) { } } -void bench_recover_setup(void* arg) { +static void bench_recover_setup(void* arg) { int i; - bench_recover_t *data = (bench_recover_t*)arg; + bench_recover_data *data = (bench_recover_data*)arg; for (i = 0; i < 32; i++) { data->msg[i] = 1 + i; @@ -48,13 +48,15 @@ void bench_recover_setup(void* arg) { } } -int main(void) { - bench_recover_t data; +static void run_recovery_bench(int iters, int argc, char** argv) { + bench_recover_data data; + int d = argc == 1; - data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); - run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, 20000); + if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, iters); secp256k1_context_destroy(data.ctx); - return 0; } + +#endif /* SECP256K1_MODULE_RECOVERY_BENCH_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modules/recovery/main_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/recovery/main_impl.h old mode 100755 new mode 100644 index c6fbe23981..76a005e017 --- a/crypto/secp256k1/libsecp256k1/src/modules/recovery/main_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/modules/recovery/main_impl.h @@ -1,13 +1,13 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_MODULE_RECOVERY_MAIN_ -#define _SECP256K1_MODULE_RECOVERY_MAIN_ +#ifndef SECP256K1_MODULE_RECOVERY_MAIN_H +#define SECP256K1_MODULE_RECOVERY_MAIN_H -#include "include/secp256k1_recovery.h" +#include "../../../include/secp256k1_recovery.h" static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) { (void)ctx; @@ -40,7 +40,7 @@ int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* int ret = 1; int overflow = 0; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(input64 != NULL); ARG_CHECK(recid >= 0 && recid <= 3); @@ -60,7 +60,7 @@ int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) { secp256k1_scalar r, s; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(output64 != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(recid != NULL); @@ -75,7 +75,7 @@ int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_scalar r, s; int recid; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(sigin != NULL); @@ -84,7 +84,7 @@ int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, return 1; } -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { +static int secp256k1_ecdsa_sig_recover(const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { unsigned char brx[32]; secp256k1_fe fx; secp256k1_ge x; @@ -98,7 +98,7 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, cons } secp256k1_scalar_get_b32(brx, sigr); - r = secp256k1_fe_set_b32(&fx, brx); + r = secp256k1_fe_set_b32_limit(&fx, brx); (void)r; VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */ if (recid & 2) { @@ -115,73 +115,39 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, cons secp256k1_scalar_mul(&u1, &rn, message); secp256k1_scalar_negate(&u1, &u1); secp256k1_scalar_mul(&u2, &rn, sigs); - secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); + secp256k1_ecmult(&qj, &xj, &u2, &u1); secp256k1_ge_set_gej_var(pubkey, &qj); return !secp256k1_gej_is_infinity(&qj); } -int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { +int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { secp256k1_scalar r, s; - secp256k1_scalar sec, non, msg; - int recid; - int ret = 0; - int overflow = 0; + int ret, recid; VERIFY_CHECK(ctx != NULL); ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(signature != NULL); ARG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - /* Fail if the secret key is invalid. */ - if (!overflow && !secp256k1_scalar_is_zero(&sec)) { - unsigned char nonce32[32]; - unsigned int count = 0; - secp256k1_scalar_set_b32(&msg, msg32, NULL); - while (1) { - ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { - break; - } - } - count++; - } - memset(nonce32, 0, 32); - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - } - if (ret) { - secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); - } else { - memset(signature, 0, sizeof(*signature)); - } + ret = secp256k1_ecdsa_sign_inner(ctx, &r, &s, &recid, msghash32, seckey, noncefp, noncedata); + secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); return ret; } -int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { +int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msghash32) { secp256k1_ge q; secp256k1_scalar r, s; secp256k1_scalar m; int recid; VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(signature != NULL); ARG_CHECK(pubkey != NULL); secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ - secp256k1_scalar_set_b32(&m, msg32, NULL); - if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { + secp256k1_scalar_set_b32(&m, msghash32, NULL); + if (secp256k1_ecdsa_sig_recover(&r, &s, &q, &m, recid)) { secp256k1_pubkey_save(pubkey, &q); return 1; } else { @@ -190,4 +156,4 @@ int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubk } } -#endif +#endif /* SECP256K1_MODULE_RECOVERY_MAIN_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_exhaustive_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_exhaustive_impl.h new file mode 100644 index 0000000000..6bbc02b9a8 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_exhaustive_impl.h @@ -0,0 +1,148 @@ +/*********************************************************************** + * Copyright (c) 2016 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H +#define SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H + +#include "main_impl.h" +#include "../../../include/secp256k1_recovery.h" + +static void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1_ge *group) { + int i, j, k; + uint64_t iter = 0; + + /* Loop */ + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { /* message */ + for (j = 1; j < EXHAUSTIVE_TEST_ORDER; j++) { /* key */ + if (skip_section(&iter)) continue; + for (k = 1; k < EXHAUSTIVE_TEST_ORDER; k++) { /* nonce */ + const int starting_k = k; + secp256k1_fe r_dot_y_normalized; + secp256k1_ecdsa_recoverable_signature rsig; + secp256k1_ecdsa_signature sig; + secp256k1_scalar sk, msg, r, s, expected_r; + unsigned char sk32[32], msg32[32]; + int expected_recid; + int recid; + int overflow; + secp256k1_scalar_set_int(&msg, i); + secp256k1_scalar_set_int(&sk, j); + secp256k1_scalar_get_b32(sk32, &sk); + secp256k1_scalar_get_b32(msg32, &msg); + + secp256k1_ecdsa_sign_recoverable(ctx, &rsig, msg32, sk32, secp256k1_nonce_function_smallint, &k); + + /* Check directly */ + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, &rsig); + r_from_k(&expected_r, group, k, &overflow); + CHECK(r == expected_r); + CHECK((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER || + (k * (EXHAUSTIVE_TEST_ORDER - s)) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER); + /* The recid's second bit is for conveying overflow (R.x value >= group order). + * In the actual secp256k1 this is an astronomically unlikely event, but in the + * small group used here, it will almost certainly be the case for all points. + * Note that this isn't actually useful; full recovery would need to convey + * floor(R.x / group_order), but only one bit is used as that is sufficient + * in the real group. */ + expected_recid = overflow ? 2 : 0; + r_dot_y_normalized = group[k].y; + secp256k1_fe_normalize(&r_dot_y_normalized); + /* Also the recovery id is flipped depending if we hit the low-s branch */ + if ((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER) { + expected_recid |= secp256k1_fe_is_odd(&r_dot_y_normalized); + } else { + expected_recid |= !secp256k1_fe_is_odd(&r_dot_y_normalized); + } + CHECK(recid == expected_recid); + + /* Convert to a standard sig then check */ + secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig); + secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); + /* Note that we compute expected_r *after* signing -- this is important + * because our nonce-computing function function might change k during + * signing. */ + r_from_k(&expected_r, group, k, NULL); + CHECK(r == expected_r); + CHECK((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER || + (k * (EXHAUSTIVE_TEST_ORDER - s)) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER); + + /* Overflow means we've tried every possible nonce */ + if (k < starting_k) { + break; + } + } + } + } +} + +static void test_exhaustive_recovery_verify(const secp256k1_context *ctx, const secp256k1_ge *group) { + /* This is essentially a copy of test_exhaustive_verify, with recovery added */ + int s, r, msg, key; + uint64_t iter = 0; + for (s = 1; s < EXHAUSTIVE_TEST_ORDER; s++) { + for (r = 1; r < EXHAUSTIVE_TEST_ORDER; r++) { + for (msg = 1; msg < EXHAUSTIVE_TEST_ORDER; msg++) { + for (key = 1; key < EXHAUSTIVE_TEST_ORDER; key++) { + secp256k1_ge nonconst_ge; + secp256k1_ecdsa_recoverable_signature rsig; + secp256k1_ecdsa_signature sig; + secp256k1_pubkey pk; + secp256k1_scalar sk_s, msg_s, r_s, s_s; + secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s; + int recid = 0; + int k, should_verify; + unsigned char msg32[32]; + + if (skip_section(&iter)) continue; + + secp256k1_scalar_set_int(&s_s, s); + secp256k1_scalar_set_int(&r_s, r); + secp256k1_scalar_set_int(&msg_s, msg); + secp256k1_scalar_set_int(&sk_s, key); + secp256k1_scalar_get_b32(msg32, &msg_s); + + /* Verify by hand */ + /* Run through every k value that gives us this r and check that *one* works. + * Note there could be none, there could be multiple, ECDSA is weird. */ + should_verify = 0; + for (k = 0; k < EXHAUSTIVE_TEST_ORDER; k++) { + secp256k1_scalar check_x_s; + r_from_k(&check_x_s, group, k, NULL); + if (r_s == check_x_s) { + secp256k1_scalar_set_int(&s_times_k_s, k); + secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); + secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s); + secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s); + should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s); + } + } + /* nb we have a "high s" rule */ + should_verify &= !secp256k1_scalar_is_high(&s_s); + + /* We would like to try recovering the pubkey and checking that it matches, + * but pubkey recovery is impossible in the exhaustive tests (the reason + * being that there are 12 nonzero r values, 12 nonzero points, and no + * overlap between the sets, so there are no valid signatures). */ + + /* Verify by converting to a standard signature and calling verify */ + secp256k1_ecdsa_recoverable_signature_save(&rsig, &r_s, &s_s, recid); + secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig); + memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge)); + secp256k1_pubkey_save(&pk, &nonconst_ge); + CHECK(should_verify == + secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk)); + } + } + } + } +} + +static void test_exhaustive_recovery(const secp256k1_context *ctx, const secp256k1_ge *group) { + test_exhaustive_recovery_sign(ctx, group); + test_exhaustive_recovery_verify(ctx, group); +} + +#endif /* SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_impl.h index 765c7dd81e..7a28a3ce65 100644 --- a/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_MODULE_RECOVERY_TESTS_ -#define _SECP256K1_MODULE_RECOVERY_TESTS_ +#ifndef SECP256K1_MODULE_RECOVERY_TESTS_H +#define SECP256K1_MODULE_RECOVERY_TESTS_H static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { (void) msg32; @@ -25,22 +25,17 @@ static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned c } /* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */ memset(nonce32, 1, 32); - return secp256k1_rand_bits(1); + return testrand_bits(1); } -void test_ecdsa_recovery_api(void) { +static void test_ecdsa_recovery_api(void) { /* Setup contexts that just count errors */ - secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); - secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pubkey pubkey; secp256k1_pubkey recpubkey; secp256k1_ecdsa_signature normal_sig; secp256k1_ecdsa_recoverable_signature recsig; unsigned char privkey[32] = { 1 }; unsigned char message[32] = { 2 }; - int32_t ecount = 0; int recid = 0; unsigned char sig[74]; unsigned char zero_privkey[32] = { 0 }; @@ -49,105 +44,55 @@ void test_ecdsa_recovery_api(void) { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_error_callback(both, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount); - /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + CHECK(secp256k1_ec_seckey_verify(CTX, privkey) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, privkey) == 1); /* Check bad contexts and NULLs for signing */ - ecount = 0; - CHECK(secp256k1_ecdsa_sign_recoverable(none, &recsig, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(sign, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(vrfy, &recsig, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_sign_recoverable(both, NULL, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, NULL, privkey, NULL, NULL) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, NULL, NULL, NULL) == 0); - CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign_recoverable(CTX, NULL, message, privkey, NULL, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign_recoverable(CTX, &recsig, NULL, privkey, NULL, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, NULL, NULL, NULL)); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_ecdsa_sign_recoverable(STATIC_CTX, &recsig, message, privkey, NULL, NULL)); /* This will fail or succeed randomly, and in either case will not ARG_CHECK failure */ - secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, recovery_test_nonce_function, NULL); - CHECK(ecount == 5); + secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, recovery_test_nonce_function, NULL); /* These will all fail, but not in ARG_CHECK way */ - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, zero_privkey, NULL, NULL) == 0); - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, over_privkey, NULL, NULL) == 0); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, zero_privkey, NULL, NULL) == 0); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, over_privkey, NULL, NULL) == 0); /* This one will succeed. */ - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1); /* Check signing with a goofy nonce function */ /* Check bad contexts and NULLs for recovery */ - ecount = 0; - CHECK(secp256k1_ecdsa_recover(none, &recpubkey, &recsig, message) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_recover(sign, &recpubkey, &recsig, message) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recover(vrfy, &recpubkey, &recsig, message) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recover(both, &recpubkey, &recsig, message) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recover(both, NULL, &recsig, message) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_recover(both, &recpubkey, NULL, message) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_recover(both, &recpubkey, &recsig, NULL) == 0); - CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_recover(CTX, &recpubkey, &recsig, message) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recover(CTX, NULL, &recsig, message)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recover(CTX, &recpubkey, NULL, message)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recover(CTX, &recpubkey, &recsig, NULL)); /* Check NULLs for conversion */ - CHECK(secp256k1_ecdsa_sign(both, &normal_sig, message, privkey, NULL, NULL) == 1); - ecount = 0; - CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, NULL, &recsig) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, &normal_sig, NULL) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, &normal_sig, &recsig) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &normal_sig, message, privkey, NULL, NULL) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_convert(CTX, NULL, &recsig)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_convert(CTX, &normal_sig, NULL)); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &normal_sig, &recsig) == 1); /* Check NULLs for de/serialization */ - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); - ecount = 0; - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, NULL, &recid, &recsig) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, NULL, &recsig) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, &recid, NULL) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, &recid, &recsig) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, NULL, &recid, &recsig)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, NULL, &recsig)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, NULL)); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &recsig) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, NULL, sig, recid) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, NULL, recid) == 0); - CHECK(ecount == 5); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, -1) == 0); - CHECK(ecount == 6); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, 5) == 0); - CHECK(ecount == 7); - /* overflow in signature will fail but not affect ecount */ + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, NULL, sig, recid)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, NULL, recid)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, -1)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, 5)); + /* overflow in signature will not result in calling illegal_callback */ memcpy(sig, over_privkey, 32); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, recid) == 0); - CHECK(ecount == 7); - - /* cleanup */ - secp256k1_context_destroy(none); - secp256k1_context_destroy(sign); - secp256k1_context_destroy(vrfy); - secp256k1_context_destroy(both); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, recid) == 0); } -void test_ecdsa_recovery_end_to_end(void) { +static void test_ecdsa_recovery_end_to_end(void) { unsigned char extra[32] = {0x00}; unsigned char privkey[32]; unsigned char message[32]; @@ -161,52 +106,52 @@ void test_ecdsa_recovery_end_to_end(void) { /* Generate a random key and message. */ { secp256k1_scalar msg, key; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); + testutil_random_scalar_order_test(&msg); + testutil_random_scalar_order_test(&key); secp256k1_scalar_get_b32(privkey, &key); secp256k1_scalar_get_b32(message, &msg); } /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + CHECK(secp256k1_ec_seckey_verify(CTX, privkey) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, privkey) == 1); /* Serialize/parse compact and verify/recover. */ extra[0] = 0; - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[0], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[4], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[1], message, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &signature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[4], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[1], message, privkey, NULL, extra) == 1); extra[31] = 1; - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[2], message, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[2], message, privkey, NULL, extra) == 1); extra[31] = 0; extra[0] = 1; - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); - CHECK(memcmp(&signature[4], &signature[0], 64) == 0); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[3], message, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1); + CHECK(secp256k1_memcmp_var(&signature[4], &signature[0], 64) == 0); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 1); memset(&rsignature[4], 0, sizeof(rsignature[4])); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 1); /* Parse compact (with recovery id) and recover. */ - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1); - CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recover(CTX, &recpubkey, &rsignature[4], message) == 1); + CHECK(secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) == 0); /* Serialize/destroy/parse signature and verify again. */ - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); - sig[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &rsignature[4]) == 1); + sig[testrand_bits(6)] += 1 + testrand_int(255); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 0); /* Recover again */ - CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 || - memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); + CHECK(secp256k1_ecdsa_recover(CTX, &recpubkey, &rsignature[4], message) == 0 || + secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) != 0); } /* Tests several edge cases. */ -void test_ecdsa_recovery_edge_cases(void) { +static void test_ecdsa_recovery_edge_cases(void) { const unsigned char msg32[32] = { 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's', @@ -215,7 +160,7 @@ void test_ecdsa_recovery_edge_cases(void) { }; const unsigned char sig64[64] = { /* Generated by signing the above message with nonce 'This is the nonce we will use...' - * and secret key 0 (which is not valid), resulting in recid 0. */ + * and secret key 0 (which is not valid), resulting in recid 1. */ 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8, 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96, 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63, @@ -242,14 +187,14 @@ void test_ecdsa_recovery_edge_cases(void) { secp256k1_ecdsa_signature sig; int recid; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 0)); - CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 1)); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 2)); - CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 3)); - CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 0)); + CHECK(!secp256k1_ecdsa_recover(CTX, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 1)); + CHECK(secp256k1_ecdsa_recover(CTX, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 2)); + CHECK(!secp256k1_ecdsa_recover(CTX, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 3)); + CHECK(!secp256k1_ecdsa_recover(CTX, &pubkey, &rsig, msg32)); for (recid = 0; recid < 4; recid++) { int i; @@ -294,40 +239,40 @@ void test_ecdsa_recovery_edge_cases(void) { 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04 }; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 1); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigb64, recid) == 1); + CHECK(secp256k1_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 1); for (recid2 = 0; recid2 < 4; recid2++) { secp256k1_pubkey pubkey2b; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid2) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkey2b, &rsig, msg32) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigb64, recid2) == 1); + CHECK(secp256k1_ecdsa_recover(CTX, &pubkey2b, &rsig, msg32) == 1); /* Verifying with (order + r,4) should always fail. */ - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderlong, sizeof(sigbderlong)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderlong, sizeof(sigbderlong)) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); } /* DER parsing tests. */ /* Zero length r/s. */ - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0); /* Leading zeros. */ - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt1, sizeof(sigbderalt1)) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt2, sizeof(sigbderalt2)) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt1, sizeof(sigbderalt1)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt2, sizeof(sigbderalt2)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0); sigbderalt3[4] = 1; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); sigbderalt4[7] = 1; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); /* Damage signature. */ sigbder[7]++; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); sigbder[7]--; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, 6) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder) - 1) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, 6) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder) - 1) == 0); for(i = 0; i < 8; i++) { int c; unsigned char orig = sigbder[i]; @@ -337,7 +282,7 @@ void test_ecdsa_recovery_edge_cases(void) { continue; } sigbder[i] = c; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); } sigbder[i] = orig; } @@ -358,36 +303,36 @@ void test_ecdsa_recovery_edge_cases(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }; secp256k1_pubkey pubkeyc; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyc, &rsig, msg32) == 1); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(CTX, &pubkeyc, &rsig, msg32) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 1); sigcder[4] = 0; sigc64[31] = 0; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 0); sigcder[4] = 1; sigcder[7] = 0; sigc64[31] = 1; sigc64[63] = 0; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 0); } } -void run_recovery_tests(void) { +static void run_recovery_tests(void) { int i; - for (i = 0; i < count; i++) { + for (i = 0; i < COUNT; i++) { test_ecdsa_recovery_api(); } - for (i = 0; i < 64*count; i++) { + for (i = 0; i < 64*COUNT; i++) { test_ecdsa_recovery_end_to_end(); } test_ecdsa_recovery_edge_cases(); } -#endif +#endif /* SECP256K1_MODULE_RECOVERY_TESTS_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/Makefile.am.include b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/Makefile.am.include new file mode 100644 index 0000000000..654fa2e5ae --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/Makefile.am.include @@ -0,0 +1,5 @@ +include_HEADERS += include/secp256k1_schnorrsig.h +noinst_HEADERS += src/modules/schnorrsig/main_impl.h +noinst_HEADERS += src/modules/schnorrsig/tests_impl.h +noinst_HEADERS += src/modules/schnorrsig/tests_exhaustive_impl.h +noinst_HEADERS += src/modules/schnorrsig/bench_impl.h diff --git a/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/bench_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/bench_impl.h new file mode 100644 index 0000000000..93a878ede3 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/bench_impl.h @@ -0,0 +1,104 @@ +/*********************************************************************** + * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORRSIG_BENCH_H +#define SECP256K1_MODULE_SCHNORRSIG_BENCH_H + +#include "../../../include/secp256k1_schnorrsig.h" + +#define MSGLEN 32 + +typedef struct { + secp256k1_context *ctx; + int n; + + const secp256k1_keypair **keypairs; + const unsigned char **pk; + const unsigned char **sigs; + const unsigned char **msgs; +} bench_schnorrsig_data; + +static void bench_schnorrsig_sign(void* arg, int iters) { + bench_schnorrsig_data *data = (bench_schnorrsig_data *)arg; + int i; + unsigned char msg[MSGLEN] = {0}; + unsigned char sig[64]; + + for (i = 0; i < iters; i++) { + msg[0] = i; + msg[1] = i >> 8; + CHECK(secp256k1_schnorrsig_sign_custom(data->ctx, sig, msg, MSGLEN, data->keypairs[i], NULL)); + } +} + +static void bench_schnorrsig_verify(void* arg, int iters) { + bench_schnorrsig_data *data = (bench_schnorrsig_data *)arg; + int i; + + for (i = 0; i < iters; i++) { + secp256k1_xonly_pubkey pk; + CHECK(secp256k1_xonly_pubkey_parse(data->ctx, &pk, data->pk[i]) == 1); + CHECK(secp256k1_schnorrsig_verify(data->ctx, data->sigs[i], data->msgs[i], MSGLEN, &pk)); + } +} + +static void run_schnorrsig_bench(int iters, int argc, char** argv) { + int i; + bench_schnorrsig_data data; + int d = argc == 1; + + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + data.keypairs = (const secp256k1_keypair **)malloc(iters * sizeof(secp256k1_keypair *)); + data.pk = (const unsigned char **)malloc(iters * sizeof(unsigned char *)); + data.msgs = (const unsigned char **)malloc(iters * sizeof(unsigned char *)); + data.sigs = (const unsigned char **)malloc(iters * sizeof(unsigned char *)); + + CHECK(MSGLEN >= 4); + for (i = 0; i < iters; i++) { + unsigned char sk[32]; + unsigned char *msg = (unsigned char *)malloc(MSGLEN); + unsigned char *sig = (unsigned char *)malloc(64); + secp256k1_keypair *keypair = (secp256k1_keypair *)malloc(sizeof(*keypair)); + unsigned char *pk_char = (unsigned char *)malloc(32); + secp256k1_xonly_pubkey pk; + msg[0] = sk[0] = i; + msg[1] = sk[1] = i >> 8; + msg[2] = sk[2] = i >> 16; + msg[3] = sk[3] = i >> 24; + memset(&msg[4], 'm', MSGLEN - 4); + memset(&sk[4], 's', 28); + + data.keypairs[i] = keypair; + data.pk[i] = pk_char; + data.msgs[i] = msg; + data.sigs[i] = sig; + + CHECK(secp256k1_keypair_create(data.ctx, keypair, sk)); + CHECK(secp256k1_schnorrsig_sign_custom(data.ctx, sig, msg, MSGLEN, keypair, NULL)); + CHECK(secp256k1_keypair_xonly_pub(data.ctx, &pk, NULL, keypair)); + CHECK(secp256k1_xonly_pubkey_serialize(data.ctx, pk_char, &pk) == 1); + } + + if (d || have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "schnorrsig_sign")) run_benchmark("schnorrsig_sign", bench_schnorrsig_sign, NULL, NULL, (void *) &data, 10, iters); + if (d || have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "schnorrsig_verify")) run_benchmark("schnorrsig_verify", bench_schnorrsig_verify, NULL, NULL, (void *) &data, 10, iters); + + for (i = 0; i < iters; i++) { + free((void *)data.keypairs[i]); + free((void *)data.pk[i]); + free((void *)data.msgs[i]); + free((void *)data.sigs[i]); + } + + /* Casting to (void *) avoids a stupid warning in MSVC. */ + free((void *)data.keypairs); + free((void *)data.pk); + free((void *)data.msgs); + free((void *)data.sigs); + + secp256k1_context_destroy(data.ctx); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/main_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/main_impl.h new file mode 100644 index 0000000000..2ed7be677f --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/main_impl.h @@ -0,0 +1,271 @@ +/*********************************************************************** + * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H +#define SECP256K1_MODULE_SCHNORRSIG_MAIN_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_schnorrsig.h" +#include "../../hash.h" + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */ +static void secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0x46615b35ul; + sha->s[1] = 0xf4bfbff7ul; + sha->s[2] = 0x9f8dc671ul; + sha->s[3] = 0x83627ab3ul; + sha->s[4] = 0x60217180ul; + sha->s[5] = 0x57358661ul; + sha->s[6] = 0x21a29e54ul; + sha->s[7] = 0x68b07b4cul; + + sha->bytes = 64; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("BIP0340/aux")||SHA256("BIP0340/aux"). */ +static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0x24dd3219ul; + sha->s[1] = 0x4eba7e70ul; + sha->s[2] = 0xca0fabb9ul; + sha->s[3] = 0x0fa3166dul; + sha->s[4] = 0x3afbe4b1ul; + sha->s[5] = 0x4c44df97ul; + sha->s[6] = 0x4aac2739ul; + sha->s[7] = 0x249e850aul; + + sha->bytes = 64; +} + +/* algo argument for nonce_function_bip340 to derive the nonce exactly as stated in BIP-340 + * by using the correct tagged hash function. */ +static const unsigned char bip340_algo[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'n', 'o', 'n', 'c', 'e'}; + +static const unsigned char schnorrsig_extraparams_magic[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC; + +static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) { + secp256k1_sha256 sha; + unsigned char masked_key[32]; + int i; + + if (algo == NULL) { + return 0; + } + + if (data != NULL) { + secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha); + secp256k1_sha256_write(&sha, data, 32); + secp256k1_sha256_finalize(&sha, masked_key); + for (i = 0; i < 32; i++) { + masked_key[i] ^= key32[i]; + } + } else { + /* Precomputed TaggedHash("BIP0340/aux", 0x0000...00); */ + static const unsigned char ZERO_MASK[32] = { + 84, 241, 105, 207, 201, 226, 229, 114, + 116, 128, 68, 31, 144, 186, 37, 196, + 136, 244, 97, 199, 11, 94, 165, 220, + 170, 247, 175, 105, 39, 10, 165, 20 + }; + for (i = 0; i < 32; i++) { + masked_key[i] = key32[i] ^ ZERO_MASK[i]; + } + } + + /* Tag the hash with algo which is important to avoid nonce reuse across + * algorithms. If this nonce function is used in BIP-340 signing as defined + * in the spec, an optimized tagging implementation is used. */ + if (algolen == sizeof(bip340_algo) + && secp256k1_memcmp_var(algo, bip340_algo, algolen) == 0) { + secp256k1_nonce_function_bip340_sha256_tagged(&sha); + } else { + secp256k1_sha256_initialize_tagged(&sha, algo, algolen); + } + + /* Hash masked-key||pk||msg using the tagged hash as per the spec */ + secp256k1_sha256_write(&sha, masked_key, 32); + secp256k1_sha256_write(&sha, xonly_pk32, 32); + secp256k1_sha256_write(&sha, msg, msglen); + secp256k1_sha256_finalize(&sha, nonce32); + secp256k1_sha256_clear(&sha); + secp256k1_memclear(masked_key, sizeof(masked_key)); + + return 1; +} + +const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340 = nonce_function_bip340; + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */ +static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0x9cecba11ul; + sha->s[1] = 0x23925381ul; + sha->s[2] = 0x11679112ul; + sha->s[3] = 0xd1627e0ful; + sha->s[4] = 0x97c87550ul; + sha->s[5] = 0x003cc765ul; + sha->s[6] = 0x90f61164ul; + sha->s[7] = 0x33e9b66aul; + sha->bytes = 64; +} + +static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32) +{ + unsigned char buf[32]; + secp256k1_sha256 sha; + + /* tagged hash(r.x, pk.x, msg) */ + secp256k1_schnorrsig_sha256_tagged(&sha); + secp256k1_sha256_write(&sha, r32, 32); + secp256k1_sha256_write(&sha, pubkey32, 32); + secp256k1_sha256_write(&sha, msg, msglen); + secp256k1_sha256_finalize(&sha, buf); + /* Set scalar e to the challenge hash modulo the curve order as per + * BIP340. */ + secp256k1_scalar_set_b32(e, buf, NULL); +} + +static int secp256k1_schnorrsig_sign_internal(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) { + secp256k1_scalar sk; + secp256k1_scalar e; + secp256k1_scalar k; + secp256k1_gej rj; + secp256k1_ge pk; + secp256k1_ge r; + unsigned char buf[32] = { 0 }; + unsigned char pk_buf[32]; + unsigned char seckey[32]; + int ret = 1; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(msg != NULL || msglen == 0); + ARG_CHECK(keypair != NULL); + + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_bip340; + } + + ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair); + /* Because we are signing for a x-only pubkey, the secret key is negated + * before signing if the point corresponding to the secret key does not + * have an even Y. */ + if (secp256k1_fe_is_odd(&pk.y)) { + secp256k1_scalar_negate(&sk, &sk); + } + + secp256k1_scalar_get_b32(seckey, &sk); + secp256k1_fe_get_b32(pk_buf, &pk.x); + ret &= !!noncefp(buf, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata); + secp256k1_scalar_set_b32(&k, buf, NULL); + ret &= !secp256k1_scalar_is_zero(&k); + secp256k1_scalar_cmov(&k, &secp256k1_scalar_one, !ret); + + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k); + secp256k1_ge_set_gej(&r, &rj); + + /* We declassify r to allow using it as a branch point. This is fine + * because r is not a secret. */ + secp256k1_declassify(ctx, &r, sizeof(r)); + secp256k1_fe_normalize_var(&r.y); + if (secp256k1_fe_is_odd(&r.y)) { + secp256k1_scalar_negate(&k, &k); + } + secp256k1_fe_normalize_var(&r.x); + secp256k1_fe_get_b32(&sig64[0], &r.x); + + secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, pk_buf); + secp256k1_scalar_mul(&e, &e, &sk); + secp256k1_scalar_add(&e, &e, &k); + secp256k1_scalar_get_b32(&sig64[32], &e); + + secp256k1_memczero(sig64, 64, !ret); + secp256k1_scalar_clear(&k); + secp256k1_scalar_clear(&sk); + secp256k1_memclear(seckey, sizeof(seckey)); + secp256k1_gej_clear(&rj); + + return ret; +} + +int secp256k1_schnorrsig_sign32(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) { + /* We cast away const from the passed aux_rand32 argument since we know the default nonce function does not modify it. */ + return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, secp256k1_nonce_function_bip340, (unsigned char*)aux_rand32); +} + +int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) { + return secp256k1_schnorrsig_sign32(ctx, sig64, msg32, keypair, aux_rand32); +} + +int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_schnorrsig_extraparams *extraparams) { + secp256k1_nonce_function_hardened noncefp = NULL; + void *ndata = NULL; + VERIFY_CHECK(ctx != NULL); + + if (extraparams != NULL) { + ARG_CHECK(secp256k1_memcmp_var(extraparams->magic, + schnorrsig_extraparams_magic, + sizeof(extraparams->magic)) == 0); + noncefp = extraparams->noncefp; + ndata = extraparams->ndata; + } + return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata); +} + +int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) { + secp256k1_scalar s; + secp256k1_scalar e; + secp256k1_gej rj; + secp256k1_ge pk; + secp256k1_gej pkj; + secp256k1_fe rx; + secp256k1_ge r; + unsigned char buf[32]; + int overflow; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(msg != NULL || msglen == 0); + ARG_CHECK(pubkey != NULL); + + if (!secp256k1_fe_set_b32_limit(&rx, &sig64[0])) { + return 0; + } + + secp256k1_scalar_set_b32(&s, &sig64[32], &overflow); + if (overflow) { + return 0; + } + + if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) { + return 0; + } + + /* Compute e. */ + secp256k1_fe_get_b32(buf, &pk.x); + secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, buf); + + /* Compute rj = s*G + (-e)*pkj */ + secp256k1_scalar_negate(&e, &e); + secp256k1_gej_set_ge(&pkj, &pk); + secp256k1_ecmult(&rj, &pkj, &e, &s); + + secp256k1_ge_set_gej_var(&r, &rj); + if (secp256k1_ge_is_infinity(&r)) { + return 0; + } + + secp256k1_fe_normalize_var(&r.y); + return !secp256k1_fe_is_odd(&r.y) && + secp256k1_fe_equal(&rx, &r.x); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h new file mode 100644 index 0000000000..601b54975d --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h @@ -0,0 +1,214 @@ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H +#define SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H + +#include "../../../include/secp256k1_schnorrsig.h" +#include "main_impl.h" + +static const unsigned char invalid_pubkey_bytes[][32] = { + /* 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, 0, 0, 0 + }, + /* 2 */ + { + 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, 0, 2 + }, + /* order */ + { + 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, + ((EXHAUSTIVE_TEST_ORDER + 0UL) >> 24) & 0xFF, + ((EXHAUSTIVE_TEST_ORDER + 0UL) >> 16) & 0xFF, + ((EXHAUSTIVE_TEST_ORDER + 0UL) >> 8) & 0xFF, + (EXHAUSTIVE_TEST_ORDER + 0UL) & 0xFF + }, + /* order + 1 */ + { + 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, + ((EXHAUSTIVE_TEST_ORDER + 1UL) >> 24) & 0xFF, + ((EXHAUSTIVE_TEST_ORDER + 1UL) >> 16) & 0xFF, + ((EXHAUSTIVE_TEST_ORDER + 1UL) >> 8) & 0xFF, + (EXHAUSTIVE_TEST_ORDER + 1UL) & 0xFF + }, + /* field size */ + { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F + }, + /* field size + 1 (note that 1 is legal) */ + { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 + }, + /* 2^256 - 1 */ + { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + } +}; + +#define NUM_INVALID_KEYS (sizeof(invalid_pubkey_bytes) / sizeof(invalid_pubkey_bytes[0])) + +static int secp256k1_hardened_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg, + size_t msglen, + const unsigned char *key32, const unsigned char *xonly_pk32, + const unsigned char *algo, size_t algolen, + void* data) { + secp256k1_scalar s; + int *idata = data; + (void)msg; + (void)msglen; + (void)key32; + (void)xonly_pk32; + (void)algo; + (void)algolen; + secp256k1_scalar_set_int(&s, *idata); + secp256k1_scalar_get_b32(nonce32, &s); + return 1; +} + +static void test_exhaustive_schnorrsig_verify(const secp256k1_context *ctx, const secp256k1_xonly_pubkey* pubkeys, unsigned char (*xonly_pubkey_bytes)[32], const int* parities) { + int d; + uint64_t iter = 0; + /* Iterate over the possible public keys to verify against (through their corresponding DL d). */ + for (d = 1; d <= EXHAUSTIVE_TEST_ORDER / 2; ++d) { + int actual_d; + unsigned k; + unsigned char pk32[32]; + memcpy(pk32, xonly_pubkey_bytes[d - 1], 32); + actual_d = parities[d - 1] ? EXHAUSTIVE_TEST_ORDER - d : d; + /* Iterate over the possible valid first 32 bytes in the signature, through their corresponding DL k. + Values above EXHAUSTIVE_TEST_ORDER/2 refer to the entries in invalid_pubkey_bytes. */ + for (k = 1; k <= EXHAUSTIVE_TEST_ORDER / 2 + NUM_INVALID_KEYS; ++k) { + unsigned char sig64[64]; + int actual_k = -1; + int e_done[EXHAUSTIVE_TEST_ORDER] = {0}; + int e_count_done = 0; + if (skip_section(&iter)) continue; + if (k <= EXHAUSTIVE_TEST_ORDER / 2) { + memcpy(sig64, xonly_pubkey_bytes[k - 1], 32); + actual_k = parities[k - 1] ? EXHAUSTIVE_TEST_ORDER - k : k; + } else { + memcpy(sig64, invalid_pubkey_bytes[k - 1 - EXHAUSTIVE_TEST_ORDER / 2], 32); + } + /* Randomly generate messages until all challenges have been hit. */ + while (e_count_done < EXHAUSTIVE_TEST_ORDER) { + secp256k1_scalar e; + unsigned char msg32[32]; + testrand256(msg32); + secp256k1_schnorrsig_challenge(&e, sig64, msg32, sizeof(msg32), pk32); + /* Only do work if we hit a challenge we haven't tried before. */ + if (!e_done[e]) { + /* Iterate over the possible valid last 32 bytes in the signature. + 0..order=that s value; order+1=random bytes */ + int count_valid = 0; + unsigned int s; + for (s = 0; s <= EXHAUSTIVE_TEST_ORDER + 1; ++s) { + int expect_valid, valid; + if (s <= EXHAUSTIVE_TEST_ORDER) { + memset(sig64 + 32, 0, 32); + secp256k1_write_be32(sig64 + 60, s); + expect_valid = actual_k != -1 && s != EXHAUSTIVE_TEST_ORDER && + (s == (actual_k + actual_d * e) % EXHAUSTIVE_TEST_ORDER); + } else { + testrand256(sig64 + 32); + expect_valid = 0; + } + valid = secp256k1_schnorrsig_verify(ctx, sig64, msg32, sizeof(msg32), &pubkeys[d - 1]); + CHECK(valid == expect_valid); + count_valid += valid; + } + /* Exactly one s value must verify, unless R is illegal. */ + CHECK(count_valid == (actual_k != -1)); + /* Don't retry other messages that result in the same challenge. */ + e_done[e] = 1; + ++e_count_done; + } + } + } + } +} + +static void test_exhaustive_schnorrsig_sign(const secp256k1_context *ctx, unsigned char (*xonly_pubkey_bytes)[32], const secp256k1_keypair* keypairs, const int* parities) { + int d, k; + uint64_t iter = 0; + secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT; + + /* Loop over keys. */ + for (d = 1; d < EXHAUSTIVE_TEST_ORDER; ++d) { + int actual_d = d; + if (parities[d - 1]) actual_d = EXHAUSTIVE_TEST_ORDER - d; + /* Loop over nonces. */ + for (k = 1; k < EXHAUSTIVE_TEST_ORDER; ++k) { + int e_done[EXHAUSTIVE_TEST_ORDER] = {0}; + int e_count_done = 0; + unsigned char msg32[32]; + unsigned char sig64[64]; + int actual_k = k; + if (skip_section(&iter)) continue; + extraparams.noncefp = secp256k1_hardened_nonce_function_smallint; + extraparams.ndata = &k; + if (parities[k - 1]) actual_k = EXHAUSTIVE_TEST_ORDER - k; + /* Generate random messages until all challenges have been tried. */ + while (e_count_done < EXHAUSTIVE_TEST_ORDER) { + secp256k1_scalar e; + testrand256(msg32); + secp256k1_schnorrsig_challenge(&e, xonly_pubkey_bytes[k - 1], msg32, sizeof(msg32), xonly_pubkey_bytes[d - 1]); + /* Only do work if we hit a challenge we haven't tried before. */ + if (!e_done[e]) { + secp256k1_scalar expected_s = (actual_k + e * actual_d) % EXHAUSTIVE_TEST_ORDER; + unsigned char expected_s_bytes[32]; + secp256k1_scalar_get_b32(expected_s_bytes, &expected_s); + /* Invoke the real function to construct a signature. */ + CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig64, msg32, sizeof(msg32), &keypairs[d - 1], &extraparams)); + /* The first 32 bytes must match the xonly pubkey for the specified k. */ + CHECK(secp256k1_memcmp_var(sig64, xonly_pubkey_bytes[k - 1], 32) == 0); + /* The last 32 bytes must match the expected s value. */ + CHECK(secp256k1_memcmp_var(sig64 + 32, expected_s_bytes, 32) == 0); + /* Don't retry other messages that result in the same challenge. */ + e_done[e] = 1; + ++e_count_done; + } + } + } + } +} + +static void test_exhaustive_schnorrsig(const secp256k1_context *ctx) { + secp256k1_keypair keypair[EXHAUSTIVE_TEST_ORDER - 1]; + secp256k1_xonly_pubkey xonly_pubkey[EXHAUSTIVE_TEST_ORDER - 1]; + int parity[EXHAUSTIVE_TEST_ORDER - 1]; + unsigned char xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - 1][32]; + unsigned i; + + /* Verify that all invalid_pubkey_bytes are actually invalid. */ + for (i = 0; i < NUM_INVALID_KEYS; ++i) { + secp256k1_xonly_pubkey pk; + CHECK(!secp256k1_xonly_pubkey_parse(ctx, &pk, invalid_pubkey_bytes[i])); + } + + /* Construct keypairs and xonly-pubkeys for the entire group. */ + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; ++i) { + secp256k1_scalar scalar_i; + unsigned char buf[32]; + secp256k1_scalar_set_int(&scalar_i, i); + secp256k1_scalar_get_b32(buf, &scalar_i); + CHECK(secp256k1_keypair_create(ctx, &keypair[i - 1], buf)); + CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pubkey[i - 1], &parity[i - 1], &keypair[i - 1])); + CHECK(secp256k1_xonly_pubkey_serialize(ctx, xonly_pubkey_bytes[i - 1], &xonly_pubkey[i - 1])); + } + + test_exhaustive_schnorrsig_sign(ctx, xonly_pubkey_bytes, keypair, parity); + test_exhaustive_schnorrsig_verify(ctx, xonly_pubkey, xonly_pubkey_bytes, parity); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/tests_impl.h b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/tests_impl.h new file mode 100644 index 0000000000..2d716a01f8 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/tests_impl.h @@ -0,0 +1,982 @@ +/*********************************************************************** + * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_H +#define SECP256K1_MODULE_SCHNORRSIG_TESTS_H + +#include "../../../include/secp256k1_schnorrsig.h" + +/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many + * bytes) changes the hash function + */ +static void nonce_function_bip340_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes, size_t msglen, size_t algolen) { + unsigned char nonces[2][32]; + CHECK(nonce_function_bip340(nonces[0], args[0], msglen, args[1], args[2], args[3], algolen, args[4]) == 1); + testrand_flip(args[n_flip], n_bytes); + CHECK(nonce_function_bip340(nonces[1], args[0], msglen, args[1], args[2], args[3], algolen, args[4]) == 1); + CHECK(secp256k1_memcmp_var(nonces[0], nonces[1], 32) != 0); +} + +static void run_nonce_function_bip340_tests(void) { + unsigned char tag[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'n', 'o', 'n', 'c', 'e'}; + unsigned char aux_tag[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'a', 'u', 'x'}; + unsigned char algo[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'n', 'o', 'n', 'c', 'e'}; + size_t algolen = sizeof(algo); + secp256k1_sha256 sha; + secp256k1_sha256 sha_optimized; + unsigned char nonce[32], nonce_z[32]; + unsigned char msg[32]; + size_t msglen = sizeof(msg); + unsigned char key[32]; + unsigned char pk[32]; + unsigned char aux_rand[32]; + unsigned char *args[5]; + int i; + + /* Check that hash initialized by + * secp256k1_nonce_function_bip340_sha256_tagged has the expected + * state. */ + secp256k1_sha256_initialize_tagged(&sha, tag, sizeof(tag)); + secp256k1_nonce_function_bip340_sha256_tagged(&sha_optimized); + test_sha256_eq(&sha, &sha_optimized); + + /* Check that hash initialized by + * secp256k1_nonce_function_bip340_sha256_tagged_aux has the expected + * state. */ + secp256k1_sha256_initialize_tagged(&sha, aux_tag, sizeof(aux_tag)); + secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha_optimized); + test_sha256_eq(&sha, &sha_optimized); + + testrand256(msg); + testrand256(key); + testrand256(pk); + testrand256(aux_rand); + + /* Check that a bitflip in an argument results in different nonces. */ + args[0] = msg; + args[1] = key; + args[2] = pk; + args[3] = algo; + args[4] = aux_rand; + for (i = 0; i < COUNT; i++) { + nonce_function_bip340_bitflip(args, 0, 32, msglen, algolen); + nonce_function_bip340_bitflip(args, 1, 32, msglen, algolen); + nonce_function_bip340_bitflip(args, 2, 32, msglen, algolen); + /* Flip algo special case "BIP0340/nonce" */ + nonce_function_bip340_bitflip(args, 3, algolen, msglen, algolen); + /* Flip algo again */ + nonce_function_bip340_bitflip(args, 3, algolen, msglen, algolen); + nonce_function_bip340_bitflip(args, 4, 32, msglen, algolen); + } + + /* NULL algo is disallowed */ + CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, NULL, 0, NULL) == 0); + CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, algo, algolen, NULL) == 1); + /* Other algo is fine */ + testrand_bytes_test(algo, algolen); + CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, algo, algolen, NULL) == 1); + + for (i = 0; i < COUNT; i++) { + unsigned char nonce2[32]; + uint32_t offset = testrand_int(msglen - 1); + size_t msglen_tmp = (msglen + offset) % msglen; + size_t algolen_tmp; + + /* Different msglen gives different nonce */ + CHECK(nonce_function_bip340(nonce2, msg, msglen_tmp, key, pk, algo, algolen, NULL) == 1); + CHECK(secp256k1_memcmp_var(nonce, nonce2, 32) != 0); + + /* Different algolen gives different nonce */ + offset = testrand_int(algolen - 1); + algolen_tmp = (algolen + offset) % algolen; + CHECK(nonce_function_bip340(nonce2, msg, msglen, key, pk, algo, algolen_tmp, NULL) == 1); + CHECK(secp256k1_memcmp_var(nonce, nonce2, 32) != 0); + } + + /* NULL aux_rand argument is allowed, and identical to passing all zero aux_rand. */ + memset(aux_rand, 0, 32); + CHECK(nonce_function_bip340(nonce_z, msg, msglen, key, pk, algo, algolen, &aux_rand) == 1); + CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, algo, algolen, NULL) == 1); + CHECK(secp256k1_memcmp_var(nonce_z, nonce, 32) == 0); +} + +static void test_schnorrsig_api(void) { + unsigned char sk1[32]; + unsigned char sk2[32]; + unsigned char sk3[32]; + unsigned char msg[32]; + secp256k1_keypair keypairs[3]; + secp256k1_keypair invalid_keypair = {{ 0 }}; + secp256k1_xonly_pubkey pk[3]; + secp256k1_xonly_pubkey zero_pk; + unsigned char sig[64]; + secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT; + secp256k1_schnorrsig_extraparams invalid_extraparams = {{ 0 }, NULL, NULL}; + + testrand256(sk1); + testrand256(sk2); + testrand256(sk3); + testrand256(msg); + CHECK(secp256k1_keypair_create(CTX, &keypairs[0], sk1) == 1); + CHECK(secp256k1_keypair_create(CTX, &keypairs[1], sk2) == 1); + CHECK(secp256k1_keypair_create(CTX, &keypairs[2], sk3) == 1); + CHECK(secp256k1_keypair_xonly_pub(CTX, &pk[0], NULL, &keypairs[0]) == 1); + CHECK(secp256k1_keypair_xonly_pub(CTX, &pk[1], NULL, &keypairs[1]) == 1); + CHECK(secp256k1_keypair_xonly_pub(CTX, &pk[2], NULL, &keypairs[2]) == 1); + memset(&zero_pk, 0, sizeof(zero_pk)); + + /** main test body **/ + CHECK(secp256k1_schnorrsig_sign32(CTX, sig, msg, &keypairs[0], NULL) == 1); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign32(CTX, NULL, msg, &keypairs[0], NULL)); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign32(CTX, sig, NULL, &keypairs[0], NULL)); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign32(CTX, sig, msg, NULL, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign32(CTX, sig, msg, &invalid_keypair, NULL)); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_schnorrsig_sign32(STATIC_CTX, sig, msg, &keypairs[0], NULL)); + + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypairs[0], &extraparams) == 1); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign_custom(CTX, NULL, msg, sizeof(msg), &keypairs[0], &extraparams)); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign_custom(CTX, sig, NULL, sizeof(msg), &keypairs[0], &extraparams)); + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, NULL, 0, &keypairs[0], &extraparams) == 1); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), NULL, &extraparams)); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &invalid_keypair, &extraparams)); + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypairs[0], NULL) == 1); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypairs[0], &invalid_extraparams)); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_schnorrsig_sign_custom(STATIC_CTX, sig, msg, sizeof(msg), &keypairs[0], &extraparams)); + + CHECK(secp256k1_schnorrsig_sign32(CTX, sig, msg, &keypairs[0], NULL) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), &pk[0]) == 1); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_verify(CTX, NULL, msg, sizeof(msg), &pk[0])); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_verify(CTX, sig, NULL, sizeof(msg), &pk[0])); + CHECK(secp256k1_schnorrsig_verify(CTX, sig, NULL, 0, &pk[0]) == 0); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), NULL)); + CHECK_ILLEGAL(CTX, secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), &zero_pk)); +} + +/* Checks that hash initialized by secp256k1_schnorrsig_sha256_tagged has the + * expected state. */ +static void test_schnorrsig_sha256_tagged(void) { + unsigned char tag[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'c', 'h', 'a', 'l', 'l', 'e', 'n', 'g', 'e'}; + secp256k1_sha256 sha; + secp256k1_sha256 sha_optimized; + + secp256k1_sha256_initialize_tagged(&sha, (unsigned char *) tag, sizeof(tag)); + secp256k1_schnorrsig_sha256_tagged(&sha_optimized); + test_sha256_eq(&sha, &sha_optimized); +} + +/* Helper function for schnorrsig_bip_vectors + * Signs the message and checks that it's the same as expected_sig. */ +static void test_schnorrsig_bip_vectors_check_signing(const unsigned char *sk, const unsigned char *pk_serialized, const unsigned char *aux_rand, const unsigned char *msg, size_t msglen, const unsigned char *expected_sig) { + unsigned char sig[64]; + secp256k1_keypair keypair; + secp256k1_xonly_pubkey pk, pk_expected; + + secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT; + extraparams.ndata = (unsigned char*)aux_rand; + + CHECK(secp256k1_keypair_create(CTX, &keypair, sk)); + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, msglen, &keypair, &extraparams)); + CHECK(secp256k1_memcmp_var(sig, expected_sig, 64) == 0); + if (msglen == 32) { + memset(sig, 0, 64); + CHECK(secp256k1_schnorrsig_sign32(CTX, sig, msg, &keypair, aux_rand)); + CHECK(secp256k1_memcmp_var(sig, expected_sig, 64) == 0); + } + + CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk_expected, pk_serialized)); + CHECK(secp256k1_keypair_xonly_pub(CTX, &pk, NULL, &keypair)); + CHECK(secp256k1_memcmp_var(&pk, &pk_expected, sizeof(pk)) == 0); + CHECK(secp256k1_schnorrsig_verify(CTX, sig, msg, msglen, &pk)); +} + +/* Helper function for schnorrsig_bip_vectors + * Checks that both verify and verify_batch (TODO) return the same value as expected. */ +static void test_schnorrsig_bip_vectors_check_verify(const unsigned char *pk_serialized, const unsigned char *msg, size_t msglen, const unsigned char *sig, int expected) { + secp256k1_xonly_pubkey pk; + + CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk, pk_serialized)); + CHECK(expected == secp256k1_schnorrsig_verify(CTX, sig, msg, msglen, &pk)); +} + +/* Test vectors according to BIP-340 ("Schnorr Signatures for secp256k1"). See + * https://github.com/bitcoin/bips/blob/master/bip-0340/test-vectors.csv. */ +static void test_schnorrsig_bip_vectors(void) { + { + /* Test vector 0 */ + const unsigned char sk[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 + }; + const unsigned char pk[32] = { + 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, + 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, + 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, + 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 + }; + const unsigned char aux_rand[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const unsigned char msg[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const unsigned char sig[64] = { + 0xE9, 0x07, 0x83, 0x1F, 0x80, 0x84, 0x8D, 0x10, + 0x69, 0xA5, 0x37, 0x1B, 0x40, 0x24, 0x10, 0x36, + 0x4B, 0xDF, 0x1C, 0x5F, 0x83, 0x07, 0xB0, 0x08, + 0x4C, 0x55, 0xF1, 0xCE, 0x2D, 0xCA, 0x82, 0x15, + 0x25, 0xF6, 0x6A, 0x4A, 0x85, 0xEA, 0x8B, 0x71, + 0xE4, 0x82, 0xA7, 0x4F, 0x38, 0x2D, 0x2C, 0xE5, + 0xEB, 0xEE, 0xE8, 0xFD, 0xB2, 0x17, 0x2F, 0x47, + 0x7D, 0xF4, 0x90, 0x0D, 0x31, 0x05, 0x36, 0xC0 + }; + test_schnorrsig_bip_vectors_check_signing(sk, pk, aux_rand, msg, sizeof(msg), sig); + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 1); + } + { + /* Test vector 1 */ + const unsigned char sk[32] = { + 0xB7, 0xE1, 0x51, 0x62, 0x8A, 0xED, 0x2A, 0x6A, + 0xBF, 0x71, 0x58, 0x80, 0x9C, 0xF4, 0xF3, 0xC7, + 0x62, 0xE7, 0x16, 0x0F, 0x38, 0xB4, 0xDA, 0x56, + 0xA7, 0x84, 0xD9, 0x04, 0x51, 0x90, 0xCF, 0xEF + }; + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char aux_rand[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0x68, 0x96, 0xBD, 0x60, 0xEE, 0xAE, 0x29, 0x6D, + 0xB4, 0x8A, 0x22, 0x9F, 0xF7, 0x1D, 0xFE, 0x07, + 0x1B, 0xDE, 0x41, 0x3E, 0x6D, 0x43, 0xF9, 0x17, + 0xDC, 0x8D, 0xCF, 0x8C, 0x78, 0xDE, 0x33, 0x41, + 0x89, 0x06, 0xD1, 0x1A, 0xC9, 0x76, 0xAB, 0xCC, + 0xB2, 0x0B, 0x09, 0x12, 0x92, 0xBF, 0xF4, 0xEA, + 0x89, 0x7E, 0xFC, 0xB6, 0x39, 0xEA, 0x87, 0x1C, + 0xFA, 0x95, 0xF6, 0xDE, 0x33, 0x9E, 0x4B, 0x0A + }; + test_schnorrsig_bip_vectors_check_signing(sk, pk, aux_rand, msg, sizeof(msg), sig); + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 1); + } + { + /* Test vector 2 */ + const unsigned char sk[32] = { + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x14, 0xE5, 0xC9 + }; + const unsigned char pk[32] = { + 0xDD, 0x30, 0x8A, 0xFE, 0xC5, 0x77, 0x7E, 0x13, + 0x12, 0x1F, 0xA7, 0x2B, 0x9C, 0xC1, 0xB7, 0xCC, + 0x01, 0x39, 0x71, 0x53, 0x09, 0xB0, 0x86, 0xC9, + 0x60, 0xE1, 0x8F, 0xD9, 0x69, 0x77, 0x4E, 0xB8 + }; + const unsigned char aux_rand[32] = { + 0xC8, 0x7A, 0xA5, 0x38, 0x24, 0xB4, 0xD7, 0xAE, + 0x2E, 0xB0, 0x35, 0xA2, 0xB5, 0xBB, 0xBC, 0xCC, + 0x08, 0x0E, 0x76, 0xCD, 0xC6, 0xD1, 0x69, 0x2C, + 0x4B, 0x0B, 0x62, 0xD7, 0x98, 0xE6, 0xD9, 0x06 + }; + const unsigned char msg[32] = { + 0x7E, 0x2D, 0x58, 0xD8, 0xB3, 0xBC, 0xDF, 0x1A, + 0xBA, 0xDE, 0xC7, 0x82, 0x90, 0x54, 0xF9, 0x0D, + 0xDA, 0x98, 0x05, 0xAA, 0xB5, 0x6C, 0x77, 0x33, + 0x30, 0x24, 0xB9, 0xD0, 0xA5, 0x08, 0xB7, 0x5C + }; + const unsigned char sig[64] = { + 0x58, 0x31, 0xAA, 0xEE, 0xD7, 0xB4, 0x4B, 0xB7, + 0x4E, 0x5E, 0xAB, 0x94, 0xBA, 0x9D, 0x42, 0x94, + 0xC4, 0x9B, 0xCF, 0x2A, 0x60, 0x72, 0x8D, 0x8B, + 0x4C, 0x20, 0x0F, 0x50, 0xDD, 0x31, 0x3C, 0x1B, + 0xAB, 0x74, 0x58, 0x79, 0xA5, 0xAD, 0x95, 0x4A, + 0x72, 0xC4, 0x5A, 0x91, 0xC3, 0xA5, 0x1D, 0x3C, + 0x7A, 0xDE, 0xA9, 0x8D, 0x82, 0xF8, 0x48, 0x1E, + 0x0E, 0x1E, 0x03, 0x67, 0x4A, 0x6F, 0x3F, 0xB7 + }; + test_schnorrsig_bip_vectors_check_signing(sk, pk, aux_rand, msg, sizeof(msg), sig); + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 1); + } + { + /* Test vector 3 */ + const unsigned char sk[32] = { + 0x0B, 0x43, 0x2B, 0x26, 0x77, 0x93, 0x73, 0x81, + 0xAE, 0xF0, 0x5B, 0xB0, 0x2A, 0x66, 0xEC, 0xD0, + 0x12, 0x77, 0x30, 0x62, 0xCF, 0x3F, 0xA2, 0x54, + 0x9E, 0x44, 0xF5, 0x8E, 0xD2, 0x40, 0x17, 0x10 + }; + const unsigned char pk[32] = { + 0x25, 0xD1, 0xDF, 0xF9, 0x51, 0x05, 0xF5, 0x25, + 0x3C, 0x40, 0x22, 0xF6, 0x28, 0xA9, 0x96, 0xAD, + 0x3A, 0x0D, 0x95, 0xFB, 0xF2, 0x1D, 0x46, 0x8A, + 0x1B, 0x33, 0xF8, 0xC1, 0x60, 0xD8, 0xF5, 0x17 + }; + const unsigned char aux_rand[32] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + const unsigned char msg[32] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + const unsigned char sig[64] = { + 0x7E, 0xB0, 0x50, 0x97, 0x57, 0xE2, 0x46, 0xF1, + 0x94, 0x49, 0x88, 0x56, 0x51, 0x61, 0x1C, 0xB9, + 0x65, 0xEC, 0xC1, 0xA1, 0x87, 0xDD, 0x51, 0xB6, + 0x4F, 0xDA, 0x1E, 0xDC, 0x96, 0x37, 0xD5, 0xEC, + 0x97, 0x58, 0x2B, 0x9C, 0xB1, 0x3D, 0xB3, 0x93, + 0x37, 0x05, 0xB3, 0x2B, 0xA9, 0x82, 0xAF, 0x5A, + 0xF2, 0x5F, 0xD7, 0x88, 0x81, 0xEB, 0xB3, 0x27, + 0x71, 0xFC, 0x59, 0x22, 0xEF, 0xC6, 0x6E, 0xA3 + }; + test_schnorrsig_bip_vectors_check_signing(sk, pk, aux_rand, msg, sizeof(msg), sig); + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 1); + } + { + /* Test vector 4 */ + const unsigned char pk[32] = { + 0xD6, 0x9C, 0x35, 0x09, 0xBB, 0x99, 0xE4, 0x12, + 0xE6, 0x8B, 0x0F, 0xE8, 0x54, 0x4E, 0x72, 0x83, + 0x7D, 0xFA, 0x30, 0x74, 0x6D, 0x8B, 0xE2, 0xAA, + 0x65, 0x97, 0x5F, 0x29, 0xD2, 0x2D, 0xC7, 0xB9 + }; + const unsigned char msg[32] = { + 0x4D, 0xF3, 0xC3, 0xF6, 0x8F, 0xCC, 0x83, 0xB2, + 0x7E, 0x9D, 0x42, 0xC9, 0x04, 0x31, 0xA7, 0x24, + 0x99, 0xF1, 0x78, 0x75, 0xC8, 0x1A, 0x59, 0x9B, + 0x56, 0x6C, 0x98, 0x89, 0xB9, 0x69, 0x67, 0x03 + }; + const unsigned char sig[64] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3B, 0x78, 0xCE, 0x56, 0x3F, + 0x89, 0xA0, 0xED, 0x94, 0x14, 0xF5, 0xAA, 0x28, + 0xAD, 0x0D, 0x96, 0xD6, 0x79, 0x5F, 0x9C, 0x63, + 0x76, 0xAF, 0xB1, 0x54, 0x8A, 0xF6, 0x03, 0xB3, + 0xEB, 0x45, 0xC9, 0xF8, 0x20, 0x7D, 0xEE, 0x10, + 0x60, 0xCB, 0x71, 0xC0, 0x4E, 0x80, 0xF5, 0x93, + 0x06, 0x0B, 0x07, 0xD2, 0x83, 0x08, 0xD7, 0xF4 + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 1); + } + { + /* Test vector 5 */ + const unsigned char pk[32] = { + 0xEE, 0xFD, 0xEA, 0x4C, 0xDB, 0x67, 0x77, 0x50, + 0xA4, 0x20, 0xFE, 0xE8, 0x07, 0xEA, 0xCF, 0x21, + 0xEB, 0x98, 0x98, 0xAE, 0x79, 0xB9, 0x76, 0x87, + 0x66, 0xE4, 0xFA, 0xA0, 0x4A, 0x2D, 0x4A, 0x34 + }; + secp256k1_xonly_pubkey pk_parsed; + /* No need to check the signature of the test vector as parsing the pubkey already fails */ + CHECK(!secp256k1_xonly_pubkey_parse(CTX, &pk_parsed, pk)); + } + { + /* Test vector 6 */ + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0xFF, 0xF9, 0x7B, 0xD5, 0x75, 0x5E, 0xEE, 0xA4, + 0x20, 0x45, 0x3A, 0x14, 0x35, 0x52, 0x35, 0xD3, + 0x82, 0xF6, 0x47, 0x2F, 0x85, 0x68, 0xA1, 0x8B, + 0x2F, 0x05, 0x7A, 0x14, 0x60, 0x29, 0x75, 0x56, + 0x3C, 0xC2, 0x79, 0x44, 0x64, 0x0A, 0xC6, 0x07, + 0xCD, 0x10, 0x7A, 0xE1, 0x09, 0x23, 0xD9, 0xEF, + 0x7A, 0x73, 0xC6, 0x43, 0xE1, 0x66, 0xBE, 0x5E, + 0xBE, 0xAF, 0xA3, 0x4B, 0x1A, 0xC5, 0x53, 0xE2 + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 0); + } + { + /* Test vector 7 */ + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0x1F, 0xA6, 0x2E, 0x33, 0x1E, 0xDB, 0xC2, 0x1C, + 0x39, 0x47, 0x92, 0xD2, 0xAB, 0x11, 0x00, 0xA7, + 0xB4, 0x32, 0xB0, 0x13, 0xDF, 0x3F, 0x6F, 0xF4, + 0xF9, 0x9F, 0xCB, 0x33, 0xE0, 0xE1, 0x51, 0x5F, + 0x28, 0x89, 0x0B, 0x3E, 0xDB, 0x6E, 0x71, 0x89, + 0xB6, 0x30, 0x44, 0x8B, 0x51, 0x5C, 0xE4, 0xF8, + 0x62, 0x2A, 0x95, 0x4C, 0xFE, 0x54, 0x57, 0x35, + 0xAA, 0xEA, 0x51, 0x34, 0xFC, 0xCD, 0xB2, 0xBD + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 0); + } + { + /* Test vector 8 */ + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0x6C, 0xFF, 0x5C, 0x3B, 0xA8, 0x6C, 0x69, 0xEA, + 0x4B, 0x73, 0x76, 0xF3, 0x1A, 0x9B, 0xCB, 0x4F, + 0x74, 0xC1, 0x97, 0x60, 0x89, 0xB2, 0xD9, 0x96, + 0x3D, 0xA2, 0xE5, 0x54, 0x3E, 0x17, 0x77, 0x69, + 0x96, 0x17, 0x64, 0xB3, 0xAA, 0x9B, 0x2F, 0xFC, + 0xB6, 0xEF, 0x94, 0x7B, 0x68, 0x87, 0xA2, 0x26, + 0xE8, 0xD7, 0xC9, 0x3E, 0x00, 0xC5, 0xED, 0x0C, + 0x18, 0x34, 0xFF, 0x0D, 0x0C, 0x2E, 0x6D, 0xA6 + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 0); + } + { + /* Test vector 9 */ + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x3D, 0xDA, 0x83, 0x28, 0xAF, 0x9C, 0x23, + 0xA9, 0x4C, 0x1F, 0xEE, 0xCF, 0xD1, 0x23, 0xBA, + 0x4F, 0xB7, 0x34, 0x76, 0xF0, 0xD5, 0x94, 0xDC, + 0xB6, 0x5C, 0x64, 0x25, 0xBD, 0x18, 0x60, 0x51 + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 0); + } + { + /* Test vector 10 */ + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x76, 0x15, 0xFB, 0xAF, 0x5A, 0xE2, 0x88, 0x64, + 0x01, 0x3C, 0x09, 0x97, 0x42, 0xDE, 0xAD, 0xB4, + 0xDB, 0xA8, 0x7F, 0x11, 0xAC, 0x67, 0x54, 0xF9, + 0x37, 0x80, 0xD5, 0xA1, 0x83, 0x7C, 0xF1, 0x97 + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 0); + } + { + /* Test vector 11 */ + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0x4A, 0x29, 0x8D, 0xAC, 0xAE, 0x57, 0x39, 0x5A, + 0x15, 0xD0, 0x79, 0x5D, 0xDB, 0xFD, 0x1D, 0xCB, + 0x56, 0x4D, 0xA8, 0x2B, 0x0F, 0x26, 0x9B, 0xC7, + 0x0A, 0x74, 0xF8, 0x22, 0x04, 0x29, 0xBA, 0x1D, + 0x69, 0xE8, 0x9B, 0x4C, 0x55, 0x64, 0xD0, 0x03, + 0x49, 0x10, 0x6B, 0x84, 0x97, 0x78, 0x5D, 0xD7, + 0xD1, 0xD7, 0x13, 0xA8, 0xAE, 0x82, 0xB3, 0x2F, + 0xA7, 0x9D, 0x5F, 0x7F, 0xC4, 0x07, 0xD3, 0x9B + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 0); + } + { + /* Test vector 12 */ + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F, + 0x69, 0xE8, 0x9B, 0x4C, 0x55, 0x64, 0xD0, 0x03, + 0x49, 0x10, 0x6B, 0x84, 0x97, 0x78, 0x5D, 0xD7, + 0xD1, 0xD7, 0x13, 0xA8, 0xAE, 0x82, 0xB3, 0x2F, + 0xA7, 0x9D, 0x5F, 0x7F, 0xC4, 0x07, 0xD3, 0x9B + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 0); + } + { + /* Test vector 13 */ + const unsigned char pk[32] = { + 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, + 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, + 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, + 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 + }; + const unsigned char msg[32] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, + 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44, + 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89 + }; + const unsigned char sig[64] = { + 0x6C, 0xFF, 0x5C, 0x3B, 0xA8, 0x6C, 0x69, 0xEA, + 0x4B, 0x73, 0x76, 0xF3, 0x1A, 0x9B, 0xCB, 0x4F, + 0x74, 0xC1, 0x97, 0x60, 0x89, 0xB2, 0xD9, 0x96, + 0x3D, 0xA2, 0xE5, 0x54, 0x3E, 0x17, 0x77, 0x69, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, + 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 + }; + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 0); + } + { + /* Test vector 14 */ + const unsigned char pk[32] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 + }; + secp256k1_xonly_pubkey pk_parsed; + /* No need to check the signature of the test vector as parsing the pubkey already fails */ + CHECK(!secp256k1_xonly_pubkey_parse(CTX, &pk_parsed, pk)); + } + { + /* Test vector 15 */ + const unsigned char sk[32] = { + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + }; + const unsigned char pk[32] = { + 0x77, 0x8C, 0xAA, 0x53, 0xB4, 0x39, 0x3A, 0xC4, + 0x67, 0x77, 0x4D, 0x09, 0x49, 0x7A, 0x87, 0x22, + 0x4B, 0xF9, 0xFA, 0xB6, 0xF6, 0xE6, 0x8B, 0x23, + 0x08, 0x64, 0x97, 0x32, 0x4D, 0x6F, 0xD1, 0x17, + }; + const unsigned char aux_rand[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + /* const unsigned char msg[0] = {}; */ + const unsigned char sig[64] = { + 0x71, 0x53, 0x5D, 0xB1, 0x65, 0xEC, 0xD9, 0xFB, + 0xBC, 0x04, 0x6E, 0x5F, 0xFA, 0xEA, 0x61, 0x18, + 0x6B, 0xB6, 0xAD, 0x43, 0x67, 0x32, 0xFC, 0xCC, + 0x25, 0x29, 0x1A, 0x55, 0x89, 0x54, 0x64, 0xCF, + 0x60, 0x69, 0xCE, 0x26, 0xBF, 0x03, 0x46, 0x62, + 0x28, 0xF1, 0x9A, 0x3A, 0x62, 0xDB, 0x8A, 0x64, + 0x9F, 0x2D, 0x56, 0x0F, 0xAC, 0x65, 0x28, 0x27, + 0xD1, 0xAF, 0x05, 0x74, 0xE4, 0x27, 0xAB, 0x63, + }; + test_schnorrsig_bip_vectors_check_signing(sk, pk, aux_rand, NULL, 0, sig); + test_schnorrsig_bip_vectors_check_verify(pk, NULL, 0, sig, 1); + } + { + /* Test vector 16 */ + const unsigned char sk[32] = { + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + }; + const unsigned char pk[32] = { + 0x77, 0x8C, 0xAA, 0x53, 0xB4, 0x39, 0x3A, 0xC4, + 0x67, 0x77, 0x4D, 0x09, 0x49, 0x7A, 0x87, 0x22, + 0x4B, 0xF9, 0xFA, 0xB6, 0xF6, 0xE6, 0x8B, 0x23, + 0x08, 0x64, 0x97, 0x32, 0x4D, 0x6F, 0xD1, 0x17, + }; + const unsigned char aux_rand[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + const unsigned char msg[] = { 0x11 }; + const unsigned char sig[64] = { + 0x08, 0xA2, 0x0A, 0x0A, 0xFE, 0xF6, 0x41, 0x24, + 0x64, 0x92, 0x32, 0xE0, 0x69, 0x3C, 0x58, 0x3A, + 0xB1, 0xB9, 0x93, 0x4A, 0xE6, 0x3B, 0x4C, 0x35, + 0x11, 0xF3, 0xAE, 0x11, 0x34, 0xC6, 0xA3, 0x03, + 0xEA, 0x31, 0x73, 0xBF, 0xEA, 0x66, 0x83, 0xBD, + 0x10, 0x1F, 0xA5, 0xAA, 0x5D, 0xBC, 0x19, 0x96, + 0xFE, 0x7C, 0xAC, 0xFC, 0x5A, 0x57, 0x7D, 0x33, + 0xEC, 0x14, 0x56, 0x4C, 0xEC, 0x2B, 0xAC, 0xBF, + }; + test_schnorrsig_bip_vectors_check_signing(sk, pk, aux_rand, msg, sizeof(msg), sig); + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 1); + } + { + /* Test vector 17 */ + const unsigned char sk[32] = { + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + }; + const unsigned char pk[32] = { + 0x77, 0x8C, 0xAA, 0x53, 0xB4, 0x39, 0x3A, 0xC4, + 0x67, 0x77, 0x4D, 0x09, 0x49, 0x7A, 0x87, 0x22, + 0x4B, 0xF9, 0xFA, 0xB6, 0xF6, 0xE6, 0x8B, 0x23, + 0x08, 0x64, 0x97, 0x32, 0x4D, 0x6F, 0xD1, 0x17, + }; + const unsigned char aux_rand[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + const unsigned char msg[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x11, + }; + const unsigned char sig[64] = { + 0x51, 0x30, 0xF3, 0x9A, 0x40, 0x59, 0xB4, 0x3B, + 0xC7, 0xCA, 0xC0, 0x9A, 0x19, 0xEC, 0xE5, 0x2B, + 0x5D, 0x86, 0x99, 0xD1, 0xA7, 0x1E, 0x3C, 0x52, + 0xDA, 0x9A, 0xFD, 0xB6, 0xB5, 0x0A, 0xC3, 0x70, + 0xC4, 0xA4, 0x82, 0xB7, 0x7B, 0xF9, 0x60, 0xF8, + 0x68, 0x15, 0x40, 0xE2, 0x5B, 0x67, 0x71, 0xEC, + 0xE1, 0xE5, 0xA3, 0x7F, 0xD8, 0x0E, 0x5A, 0x51, + 0x89, 0x7C, 0x55, 0x66, 0xA9, 0x7E, 0xA5, 0xA5, + }; + test_schnorrsig_bip_vectors_check_signing(sk, pk, aux_rand, msg, sizeof(msg), sig); + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 1); + } + { + /* Test vector 18 */ + const unsigned char sk[32] = { + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, + }; + const unsigned char pk[32] = { + 0x77, 0x8C, 0xAA, 0x53, 0xB4, 0x39, 0x3A, 0xC4, + 0x67, 0x77, 0x4D, 0x09, 0x49, 0x7A, 0x87, 0x22, + 0x4B, 0xF9, 0xFA, 0xB6, 0xF6, 0xE6, 0x8B, 0x23, + 0x08, 0x64, 0x97, 0x32, 0x4D, 0x6F, 0xD1, 0x17, + }; + const unsigned char aux_rand[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + const unsigned char sig[64] = { + 0x40, 0x3B, 0x12, 0xB0, 0xD8, 0x55, 0x5A, 0x34, + 0x41, 0x75, 0xEA, 0x7E, 0xC7, 0x46, 0x56, 0x63, + 0x03, 0x32, 0x1E, 0x5D, 0xBF, 0xA8, 0xBE, 0x6F, + 0x09, 0x16, 0x35, 0x16, 0x3E, 0xCA, 0x79, 0xA8, + 0x58, 0x5E, 0xD3, 0xE3, 0x17, 0x08, 0x07, 0xE7, + 0xC0, 0x3B, 0x72, 0x0F, 0xC5, 0x4C, 0x7B, 0x23, + 0x89, 0x7F, 0xCB, 0xA0, 0xE9, 0xD0, 0xB4, 0xA0, + 0x68, 0x94, 0xCF, 0xD2, 0x49, 0xF2, 0x23, 0x67, + }; + unsigned char msg[100]; + memset(msg, 0x99, sizeof(msg)); + test_schnorrsig_bip_vectors_check_signing(sk, pk, aux_rand, msg, sizeof(msg), sig); + test_schnorrsig_bip_vectors_check_verify(pk, msg, sizeof(msg), sig, 1); + } +} + +/* Nonce function that returns constant 0 */ +static int nonce_function_failing(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) { + (void) msg; + (void) msglen; + (void) key32; + (void) xonly_pk32; + (void) algo; + (void) algolen; + (void) data; + (void) nonce32; + return 0; +} + +/* Nonce function that sets nonce to 0 */ +static int nonce_function_0(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) { + (void) msg; + (void) msglen; + (void) key32; + (void) xonly_pk32; + (void) algo; + (void) algolen; + (void) data; + + memset(nonce32, 0, 32); + return 1; +} + +/* Nonce function that sets nonce to 0xFF...0xFF */ +static int nonce_function_overflowing(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) { + (void) msg; + (void) msglen; + (void) key32; + (void) xonly_pk32; + (void) algo; + (void) algolen; + (void) data; + + memset(nonce32, 0xFF, 32); + return 1; +} + +static void test_schnorrsig_sign(void) { + unsigned char sk[32]; + secp256k1_xonly_pubkey pk; + secp256k1_keypair keypair; + const unsigned char msg[] = {'t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 'm', 's', 'g', ' ', 'f', 'o', 'r', ' ', 'a', ' ', 's', 'c', 'h', 'n', 'o', 'r', 'r', 's', 'i', 'g', '.', '.'}; + unsigned char sig[64]; + unsigned char sig2[64]; + unsigned char zeros64[64] = { 0 }; + secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT; + unsigned char aux_rand[32]; + + testrand256(sk); + testrand256(aux_rand); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk)); + CHECK(secp256k1_keypair_xonly_pub(CTX, &pk, NULL, &keypair)); + CHECK(secp256k1_schnorrsig_sign32(CTX, sig, msg, &keypair, NULL) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), &pk)); + /* Check that deprecated alias gives the same result */ + CHECK(secp256k1_schnorrsig_sign(CTX, sig2, msg, &keypair, NULL) == 1); + CHECK(secp256k1_memcmp_var(sig, sig2, sizeof(sig)) == 0); + + /* Test different nonce functions */ + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, &extraparams) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), &pk)); + memset(sig, 1, sizeof(sig)); + extraparams.noncefp = nonce_function_failing; + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, &extraparams) == 0); + CHECK(secp256k1_memcmp_var(sig, zeros64, sizeof(sig)) == 0); + memset(&sig, 1, sizeof(sig)); + extraparams.noncefp = nonce_function_0; + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, &extraparams) == 0); + CHECK(secp256k1_memcmp_var(sig, zeros64, sizeof(sig)) == 0); + memset(&sig, 1, sizeof(sig)); + extraparams.noncefp = nonce_function_overflowing; + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, &extraparams) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), &pk)); + + /* When using the default nonce function, schnorrsig_sign_custom produces + * the same result as schnorrsig_sign with aux_rand = extraparams.ndata */ + extraparams.noncefp = NULL; + extraparams.ndata = aux_rand; + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, &extraparams) == 1); + CHECK(secp256k1_schnorrsig_sign32(CTX, sig2, msg, &keypair, extraparams.ndata) == 1); + CHECK(secp256k1_memcmp_var(sig, sig2, sizeof(sig)) == 0); +} + +#define N_SIGS 3 +/* Creates N_SIGS valid signatures and verifies them with verify and + * verify_batch (TODO). Then flips some bits and checks that verification now + * fails. */ +static void test_schnorrsig_sign_verify(void) { + unsigned char sk[32]; + unsigned char msg[N_SIGS][32]; + unsigned char sig[N_SIGS][64]; + size_t i; + secp256k1_keypair keypair; + secp256k1_xonly_pubkey pk; + secp256k1_scalar s; + + testrand256(sk); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk)); + CHECK(secp256k1_keypair_xonly_pub(CTX, &pk, NULL, &keypair)); + + for (i = 0; i < N_SIGS; i++) { + testrand256(msg[i]); + CHECK(secp256k1_schnorrsig_sign32(CTX, sig[i], msg[i], &keypair, NULL)); + CHECK(secp256k1_schnorrsig_verify(CTX, sig[i], msg[i], sizeof(msg[i]), &pk)); + } + + { + /* Flip a few bits in the signature and in the message and check that + * verify and verify_batch (TODO) fail */ + size_t sig_idx = testrand_int(N_SIGS); + size_t byte_idx = testrand_bits(5); + unsigned char xorbyte = testrand_int(254)+1; + sig[sig_idx][byte_idx] ^= xorbyte; + CHECK(!secp256k1_schnorrsig_verify(CTX, sig[sig_idx], msg[sig_idx], sizeof(msg[sig_idx]), &pk)); + sig[sig_idx][byte_idx] ^= xorbyte; + + byte_idx = testrand_bits(5); + sig[sig_idx][32+byte_idx] ^= xorbyte; + CHECK(!secp256k1_schnorrsig_verify(CTX, sig[sig_idx], msg[sig_idx], sizeof(msg[sig_idx]), &pk)); + sig[sig_idx][32+byte_idx] ^= xorbyte; + + byte_idx = testrand_bits(5); + msg[sig_idx][byte_idx] ^= xorbyte; + CHECK(!secp256k1_schnorrsig_verify(CTX, sig[sig_idx], msg[sig_idx], sizeof(msg[sig_idx]), &pk)); + msg[sig_idx][byte_idx] ^= xorbyte; + + /* Check that above bitflips have been reversed correctly */ + CHECK(secp256k1_schnorrsig_verify(CTX, sig[sig_idx], msg[sig_idx], sizeof(msg[sig_idx]), &pk)); + } + + /* Test overflowing s */ + CHECK(secp256k1_schnorrsig_sign32(CTX, sig[0], msg[0], &keypair, NULL)); + CHECK(secp256k1_schnorrsig_verify(CTX, sig[0], msg[0], sizeof(msg[0]), &pk)); + memset(&sig[0][32], 0xFF, 32); + CHECK(!secp256k1_schnorrsig_verify(CTX, sig[0], msg[0], sizeof(msg[0]), &pk)); + + /* Test negative s */ + CHECK(secp256k1_schnorrsig_sign32(CTX, sig[0], msg[0], &keypair, NULL)); + CHECK(secp256k1_schnorrsig_verify(CTX, sig[0], msg[0], sizeof(msg[0]), &pk)); + secp256k1_scalar_set_b32(&s, &sig[0][32], NULL); + secp256k1_scalar_negate(&s, &s); + secp256k1_scalar_get_b32(&sig[0][32], &s); + CHECK(!secp256k1_schnorrsig_verify(CTX, sig[0], msg[0], sizeof(msg[0]), &pk)); + + /* The empty message can be signed & verified */ + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig[0], NULL, 0, &keypair, NULL) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig[0], NULL, 0, &pk) == 1); + + { + /* Test varying message lengths */ + unsigned char msg_large[32 * 8]; + uint32_t msglen = testrand_int(sizeof(msg_large)); + for (i = 0; i < sizeof(msg_large); i += 32) { + testrand256(&msg_large[i]); + } + CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig[0], msg_large, msglen, &keypair, NULL) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig[0], msg_large, msglen, &pk) == 1); + /* Verification for a random wrong message length fails */ + msglen = (msglen + (sizeof(msg_large) - 1)) % sizeof(msg_large); + CHECK(secp256k1_schnorrsig_verify(CTX, sig[0], msg_large, msglen, &pk) == 0); + } +} +#undef N_SIGS + +static void test_schnorrsig_taproot(void) { + unsigned char sk[32]; + secp256k1_keypair keypair; + secp256k1_xonly_pubkey internal_pk; + unsigned char internal_pk_bytes[32]; + secp256k1_xonly_pubkey output_pk; + unsigned char output_pk_bytes[32]; + unsigned char tweak[32]; + int pk_parity; + unsigned char msg[32]; + unsigned char sig[64]; + + /* Create output key */ + testrand256(sk); + CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); + CHECK(secp256k1_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1); + /* In actual taproot the tweak would be hash of internal_pk */ + CHECK(secp256k1_xonly_pubkey_serialize(CTX, tweak, &internal_pk) == 1); + CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1); + CHECK(secp256k1_keypair_xonly_pub(CTX, &output_pk, &pk_parity, &keypair) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, output_pk_bytes, &output_pk) == 1); + + /* Key spend */ + testrand256(msg); + CHECK(secp256k1_schnorrsig_sign32(CTX, sig, msg, &keypair, NULL) == 1); + /* Verify key spend */ + CHECK(secp256k1_xonly_pubkey_parse(CTX, &output_pk, output_pk_bytes) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), &output_pk) == 1); + + /* Script spend */ + CHECK(secp256k1_xonly_pubkey_serialize(CTX, internal_pk_bytes, &internal_pk) == 1); + /* Verify script spend */ + CHECK(secp256k1_xonly_pubkey_parse(CTX, &internal_pk, internal_pk_bytes) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk_bytes, pk_parity, &internal_pk, tweak) == 1); +} + +static void run_schnorrsig_tests(void) { + int i; + run_nonce_function_bip340_tests(); + + test_schnorrsig_api(); + test_schnorrsig_sha256_tagged(); + test_schnorrsig_bip_vectors(); + for (i = 0; i < COUNT; i++) { + test_schnorrsig_sign(); + test_schnorrsig_sign_verify(); + } + test_schnorrsig_taproot(); +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/num.h b/crypto/secp256k1/libsecp256k1/src/num.h deleted file mode 100644 index eff842200f..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/num.h +++ /dev/null @@ -1,74 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_NUM_ -#define _SECP256K1_NUM_ - -#ifndef USE_NUM_NONE - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#if defined(USE_NUM_GMP) -#include "num_gmp.h" -#else -#error "Please select num implementation" -#endif - -/** Copy a number. */ -static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a); - -/** Convert a number's absolute value to a binary big-endian string. - * There must be enough place. */ -static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a); - -/** Set a number to the value of a binary big-endian string. */ -static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen); - -/** Compute a modular inverse. The input must be less than the modulus. */ -static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); - -/** Compute the jacobi symbol (a|b). b must be positive and odd. */ -static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); - -/** Compare the absolute value of two numbers. */ -static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); - -/** Test whether two number are equal (including sign). */ -static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); - -/** Add two (signed) numbers. */ -static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); - -/** Subtract two (signed) numbers. */ -static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); - -/** Multiply two (signed) numbers. */ -static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); - -/** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, - even if r was negative. */ -static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); - -/** Right-shift the passed number by bits. */ -static void secp256k1_num_shift(secp256k1_num *r, int bits); - -/** Check whether a number is zero. */ -static int secp256k1_num_is_zero(const secp256k1_num *a); - -/** Check whether a number is one. */ -static int secp256k1_num_is_one(const secp256k1_num *a); - -/** Check whether a number is strictly negative. */ -static int secp256k1_num_is_neg(const secp256k1_num *a); - -/** Change a number's sign. */ -static void secp256k1_num_negate(secp256k1_num *r); - -#endif - -#endif diff --git a/crypto/secp256k1/libsecp256k1/src/num_gmp.h b/crypto/secp256k1/libsecp256k1/src/num_gmp.h deleted file mode 100644 index 7dd813088a..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/num_gmp.h +++ /dev/null @@ -1,20 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_NUM_REPR_ -#define _SECP256K1_NUM_REPR_ - -#include - -#define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS) - -typedef struct { - mp_limb_t data[2*NUM_LIMBS]; - int neg; - int limbs; -} secp256k1_num; - -#endif diff --git a/crypto/secp256k1/libsecp256k1/src/num_gmp_impl.h b/crypto/secp256k1/libsecp256k1/src/num_gmp_impl.h deleted file mode 100644 index 3a46495eea..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/num_gmp_impl.h +++ /dev/null @@ -1,288 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_NUM_REPR_IMPL_H_ -#define _SECP256K1_NUM_REPR_IMPL_H_ - -#include -#include -#include - -#include "util.h" -#include "num.h" - -#ifdef VERIFY -static void secp256k1_num_sanity(const secp256k1_num *a) { - VERIFY_CHECK(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0)); -} -#else -#define secp256k1_num_sanity(a) do { } while(0) -#endif - -static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a) { - *r = *a; -} - -static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a) { - unsigned char tmp[65]; - int len = 0; - int shift = 0; - if (a->limbs>1 || a->data[0] != 0) { - len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs); - } - while (shift < len && tmp[shift] == 0) shift++; - VERIFY_CHECK(len-shift <= (int)rlen); - memset(r, 0, rlen - len + shift); - if (len > shift) { - memcpy(r + rlen - len + shift, tmp + shift, len - shift); - } - memset(tmp, 0, sizeof(tmp)); -} - -static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen) { - int len; - VERIFY_CHECK(alen > 0); - VERIFY_CHECK(alen <= 64); - len = mpn_set_str(r->data, a, alen, 256); - if (len == 0) { - r->data[0] = 0; - len = 1; - } - VERIFY_CHECK(len <= NUM_LIMBS*2); - r->limbs = len; - r->neg = 0; - while (r->limbs > 1 && r->data[r->limbs-1]==0) { - r->limbs--; - } -} - -static void secp256k1_num_add_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs); - r->limbs = a->limbs; - if (c != 0) { - VERIFY_CHECK(r->limbs < 2*NUM_LIMBS); - r->data[r->limbs++] = c; - } -} - -static void secp256k1_num_sub_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs); - (void)c; - VERIFY_CHECK(c == 0); - r->limbs = a->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) { - r->limbs--; - } -} - -static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m) { - secp256k1_num_sanity(r); - secp256k1_num_sanity(m); - - if (r->limbs >= m->limbs) { - mp_limb_t t[2*NUM_LIMBS]; - mpn_tdiv_qr(t, r->data, 0, r->data, r->limbs, m->data, m->limbs); - memset(t, 0, sizeof(t)); - r->limbs = m->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) { - r->limbs--; - } - } - - if (r->neg && (r->limbs > 1 || r->data[0] != 0)) { - secp256k1_num_sub_abs(r, m, r); - r->neg = 0; - } -} - -static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m) { - int i; - mp_limb_t g[NUM_LIMBS+1]; - mp_limb_t u[NUM_LIMBS+1]; - mp_limb_t v[NUM_LIMBS+1]; - mp_size_t sn; - mp_size_t gn; - secp256k1_num_sanity(a); - secp256k1_num_sanity(m); - - /** mpn_gcdext computes: (G,S) = gcdext(U,V), where - * * G = gcd(U,V) - * * G = U*S + V*T - * * U has equal or more limbs than V, and V has no padding - * If we set U to be (a padded version of) a, and V = m: - * G = a*S + m*T - * G = a*S mod m - * Assuming G=1: - * S = 1/a mod m - */ - VERIFY_CHECK(m->limbs <= NUM_LIMBS); - VERIFY_CHECK(m->data[m->limbs-1] != 0); - for (i = 0; i < m->limbs; i++) { - u[i] = (i < a->limbs) ? a->data[i] : 0; - v[i] = m->data[i]; - } - sn = NUM_LIMBS+1; - gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); - (void)gn; - VERIFY_CHECK(gn == 1); - VERIFY_CHECK(g[0] == 1); - r->neg = a->neg ^ m->neg; - if (sn < 0) { - mpn_sub(r->data, m->data, m->limbs, r->data, -sn); - r->limbs = m->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) { - r->limbs--; - } - } else { - r->limbs = sn; - } - memset(g, 0, sizeof(g)); - memset(u, 0, sizeof(u)); - memset(v, 0, sizeof(v)); -} - -static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b) { - int ret; - mpz_t ga, gb; - secp256k1_num_sanity(a); - secp256k1_num_sanity(b); - VERIFY_CHECK(!b->neg && (b->limbs > 0) && (b->data[0] & 1)); - - mpz_inits(ga, gb, NULL); - - mpz_import(gb, b->limbs, -1, sizeof(mp_limb_t), 0, 0, b->data); - mpz_import(ga, a->limbs, -1, sizeof(mp_limb_t), 0, 0, a->data); - if (a->neg) { - mpz_neg(ga, ga); - } - - ret = mpz_jacobi(ga, gb); - - mpz_clears(ga, gb, NULL); - - return ret; -} - -static int secp256k1_num_is_one(const secp256k1_num *a) { - return (a->limbs == 1 && a->data[0] == 1); -} - -static int secp256k1_num_is_zero(const secp256k1_num *a) { - return (a->limbs == 1 && a->data[0] == 0); -} - -static int secp256k1_num_is_neg(const secp256k1_num *a) { - return (a->limbs > 1 || a->data[0] != 0) && a->neg; -} - -static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b) { - if (a->limbs > b->limbs) { - return 1; - } - if (a->limbs < b->limbs) { - return -1; - } - return mpn_cmp(a->data, b->data, a->limbs); -} - -static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b) { - if (a->limbs > b->limbs) { - return 0; - } - if (a->limbs < b->limbs) { - return 0; - } - if ((a->neg && !secp256k1_num_is_zero(a)) != (b->neg && !secp256k1_num_is_zero(b))) { - return 0; - } - return mpn_cmp(a->data, b->data, a->limbs) == 0; -} - -static void secp256k1_num_subadd(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b, int bneg) { - if (!(b->neg ^ bneg ^ a->neg)) { /* a and b have the same sign */ - r->neg = a->neg; - if (a->limbs >= b->limbs) { - secp256k1_num_add_abs(r, a, b); - } else { - secp256k1_num_add_abs(r, b, a); - } - } else { - if (secp256k1_num_cmp(a, b) > 0) { - r->neg = a->neg; - secp256k1_num_sub_abs(r, a, b); - } else { - r->neg = b->neg ^ bneg; - secp256k1_num_sub_abs(r, b, a); - } - } -} - -static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - secp256k1_num_sanity(a); - secp256k1_num_sanity(b); - secp256k1_num_subadd(r, a, b, 0); -} - -static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - secp256k1_num_sanity(a); - secp256k1_num_sanity(b); - secp256k1_num_subadd(r, a, b, 1); -} - -static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - mp_limb_t tmp[2*NUM_LIMBS+1]; - secp256k1_num_sanity(a); - secp256k1_num_sanity(b); - - VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1); - if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) { - r->limbs = 1; - r->neg = 0; - r->data[0] = 0; - return; - } - if (a->limbs >= b->limbs) { - mpn_mul(tmp, a->data, a->limbs, b->data, b->limbs); - } else { - mpn_mul(tmp, b->data, b->limbs, a->data, a->limbs); - } - r->limbs = a->limbs + b->limbs; - if (r->limbs > 1 && tmp[r->limbs - 1]==0) { - r->limbs--; - } - VERIFY_CHECK(r->limbs <= 2*NUM_LIMBS); - mpn_copyi(r->data, tmp, r->limbs); - r->neg = a->neg ^ b->neg; - memset(tmp, 0, sizeof(tmp)); -} - -static void secp256k1_num_shift(secp256k1_num *r, int bits) { - if (bits % GMP_NUMB_BITS) { - /* Shift within limbs. */ - mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS); - } - if (bits >= GMP_NUMB_BITS) { - int i; - /* Shift full limbs. */ - for (i = 0; i < r->limbs; i++) { - int index = i + (bits / GMP_NUMB_BITS); - if (index < r->limbs && index < 2*NUM_LIMBS) { - r->data[i] = r->data[index]; - } else { - r->data[i] = 0; - } - } - } - while (r->limbs>1 && r->data[r->limbs-1]==0) { - r->limbs--; - } -} - -static void secp256k1_num_negate(secp256k1_num *r) { - r->neg ^= 1; -} - -#endif diff --git a/crypto/secp256k1/libsecp256k1/src/num_impl.h b/crypto/secp256k1/libsecp256k1/src/num_impl.h deleted file mode 100644 index 0b0e3a072a..0000000000 --- a/crypto/secp256k1/libsecp256k1/src/num_impl.h +++ /dev/null @@ -1,24 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_NUM_IMPL_H_ -#define _SECP256K1_NUM_IMPL_H_ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#include "num.h" - -#if defined(USE_NUM_GMP) -#include "num_gmp_impl.h" -#elif defined(USE_NUM_NONE) -/* Nothing. */ -#else -#error "Please select num implementation" -#endif - -#endif diff --git a/crypto/secp256k1/libsecp256k1/src/precompute_ecmult.c b/crypto/secp256k1/libsecp256k1/src/precompute_ecmult.c new file mode 100644 index 0000000000..021fe3940c --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/precompute_ecmult.c @@ -0,0 +1,91 @@ +/***************************************************************************************************** + * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *****************************************************************************************************/ + +#include +#include +#include + +#include "../include/secp256k1.h" + +#include "assumptions.h" +#include "util.h" + +#include "field_impl.h" +#include "group_impl.h" +#include "int128_impl.h" +#include "ecmult.h" +#include "ecmult_compute_table_impl.h" + +static void print_table(FILE *fp, const char *name, int window_g, const secp256k1_ge_storage* table) { + int j; + int i; + + fprintf(fp, "const secp256k1_ge_storage %s[ECMULT_TABLE_SIZE(WINDOW_G)] = {\n", name); + fprintf(fp, " S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32 + ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n", + SECP256K1_GE_STORAGE_CONST_GET(table[0])); + + j = 1; + for(i = 3; i <= window_g; ++i) { + fprintf(fp, "#if WINDOW_G > %d\n", i-1); + for(;j < ECMULT_TABLE_SIZE(i); ++j) { + fprintf(fp, ",S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32 + ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n", + SECP256K1_GE_STORAGE_CONST_GET(table[j])); + } + fprintf(fp, "#endif\n"); + } + fprintf(fp, "};\n"); +} + +static void print_two_tables(FILE *fp, int window_g) { + secp256k1_ge_storage* table = malloc(ECMULT_TABLE_SIZE(window_g) * sizeof(secp256k1_ge_storage)); + secp256k1_ge_storage* table_128 = malloc(ECMULT_TABLE_SIZE(window_g) * sizeof(secp256k1_ge_storage)); + + secp256k1_ecmult_compute_two_tables(table, table_128, window_g, &secp256k1_ge_const_g); + + print_table(fp, "secp256k1_pre_g", window_g, table); + print_table(fp, "secp256k1_pre_g_128", window_g, table_128); + + free(table); + free(table_128); +} + +int main(void) { + /* Always compute all tables for window sizes up to 15. */ + int window_g = (ECMULT_WINDOW_SIZE < 15) ? 15 : ECMULT_WINDOW_SIZE; + const char outfile[] = "src/precomputed_ecmult.c"; + FILE* fp; + + fp = fopen(outfile, "w"); + if (fp == NULL) { + fprintf(stderr, "Could not open %s for writing!\n", outfile); + return EXIT_FAILURE; + } + + fprintf(fp, "/* This file was automatically generated by precompute_ecmult. */\n"); + fprintf(fp, "/* This file contains an array secp256k1_pre_g with odd multiples of the base point G and\n"); + fprintf(fp, " * an array secp256k1_pre_g_128 with odd multiples of 2^128*G for accelerating the computation of a*P + b*G.\n"); + fprintf(fp, " */\n"); + fprintf(fp, "#include \"group.h\"\n"); + fprintf(fp, "#include \"ecmult.h\"\n"); + fprintf(fp, "#include \"precomputed_ecmult.h\"\n"); + fprintf(fp, "#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u)\n"); + fprintf(fp, "#if ECMULT_WINDOW_SIZE > %d\n", window_g); + fprintf(fp, " #error configuration mismatch, invalid ECMULT_WINDOW_SIZE. Try deleting precomputed_ecmult.c before the build.\n"); + fprintf(fp, "#endif\n"); + fprintf(fp, "#ifdef EXHAUSTIVE_TEST_ORDER\n"); + fprintf(fp, "# error Cannot compile precomputed_ecmult.c in exhaustive test mode\n"); + fprintf(fp, "#endif /* EXHAUSTIVE_TEST_ORDER */\n"); + fprintf(fp, "#define WINDOW_G ECMULT_WINDOW_SIZE\n"); + + print_two_tables(fp, window_g); + + fprintf(fp, "#undef S\n"); + fclose(fp); + + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/src/precompute_ecmult_gen.c b/crypto/secp256k1/libsecp256k1/src/precompute_ecmult_gen.c new file mode 100644 index 0000000000..cd0fe70fc2 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/precompute_ecmult_gen.c @@ -0,0 +1,101 @@ +/********************************************************************************* + * Copyright (c) 2013, 2014, 2015, 2021 Thomas Daede, Cory Fields, Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *********************************************************************************/ + +#include +#include +#include + +#include "../include/secp256k1.h" + +#include "assumptions.h" +#include "util.h" + +#include "group.h" +#include "int128_impl.h" +#include "ecmult_gen.h" +#include "ecmult_gen_compute_table_impl.h" + +static const int CONFIGS[][2] = { + {2, 5}, + {11, 6}, + {43, 6} +}; + +static void print_table(FILE* fp, int blocks, int teeth) { + int spacing = CEIL_DIV(256, blocks * teeth); + size_t points = ((size_t)1) << (teeth - 1); + int outer; + size_t inner; + + secp256k1_ge_storage* table = checked_malloc(&default_error_callback, blocks * points * sizeof(secp256k1_ge_storage)); + secp256k1_ecmult_gen_compute_table(table, &secp256k1_ge_const_g, blocks, teeth, spacing); + + fprintf(fp, "#elif (COMB_BLOCKS == %d) && (COMB_TEETH == %d) && (COMB_SPACING == %d)\n", blocks, teeth, spacing); + for (outer = 0; outer != blocks; outer++) { + fprintf(fp,"{"); + for (inner = 0; inner != points; inner++) { + fprintf(fp, "S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32 + ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")", + SECP256K1_GE_STORAGE_CONST_GET(table[outer * points + inner])); + if (inner != points - 1) { + fprintf(fp,",\n"); + } + } + if (outer != blocks - 1) { + fprintf(fp,"},\n"); + } else { + fprintf(fp,"}\n"); + } + } + free(table); +} + +int main(int argc, char **argv) { + const char outfile[] = "src/precomputed_ecmult_gen.c"; + FILE* fp; + size_t config; + int did_current_config = 0; + + (void)argc; + (void)argv; + + fp = fopen(outfile, "w"); + if (fp == NULL) { + fprintf(stderr, "Could not open %s for writing!\n", outfile); + return EXIT_FAILURE; + } + + fprintf(fp, "/* This file was automatically generated by precompute_ecmult_gen. */\n"); + fprintf(fp, "/* See ecmult_gen_impl.h for details about the contents of this file. */\n"); + fprintf(fp, "#include \"group.h\"\n"); + fprintf(fp, "#include \"ecmult_gen.h\"\n"); + fprintf(fp, "#include \"precomputed_ecmult_gen.h\"\n"); + fprintf(fp, "#ifdef EXHAUSTIVE_TEST_ORDER\n"); + fprintf(fp, "# error Cannot compile precomputed_ecmult_gen.c in exhaustive test mode\n"); + fprintf(fp, "#endif /* EXHAUSTIVE_TEST_ORDER */\n"); + fprintf(fp, "#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u)\n"); + + fprintf(fp, "const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS] = {\n"); + fprintf(fp, "#if 0\n"); + for (config = 0; config < sizeof(CONFIGS) / sizeof(*CONFIGS); ++config) { + print_table(fp, CONFIGS[config][0], CONFIGS[config][1]); + if (CONFIGS[config][0] == COMB_BLOCKS && CONFIGS[config][1] == COMB_TEETH) { + did_current_config = 1; + } + } + if (!did_current_config) { + print_table(fp, COMB_BLOCKS, COMB_TEETH); + } + fprintf(fp, "#else\n"); + fprintf(fp, "# error Configuration mismatch, invalid COMB_* parameters. Try deleting precomputed_ecmult_gen.c before the build.\n"); + fprintf(fp, "#endif\n"); + + fprintf(fp, "};\n"); + fprintf(fp, "#undef S\n"); + fclose(fp); + + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult.c b/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult.c new file mode 100644 index 0000000000..cbd030ce50 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult.c @@ -0,0 +1,16456 @@ +/* This file was automatically generated by precompute_ecmult. */ +/* This file contains an array secp256k1_pre_g with odd multiples of the base point G and + * an array secp256k1_pre_g_128 with odd multiples of 2^128*G for accelerating the computation of a*P + b*G. + */ +#include "group.h" +#include "ecmult.h" +#include "precomputed_ecmult.h" +#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u) +#if ECMULT_WINDOW_SIZE > 15 + #error configuration mismatch, invalid ECMULT_WINDOW_SIZE. Try deleting precomputed_ecmult.c before the build. +#endif +#ifdef EXHAUSTIVE_TEST_ORDER +# error Cannot compile precomputed_ecmult.c in exhaustive test mode +#endif /* EXHAUSTIVE_TEST_ORDER */ +#define WINDOW_G ECMULT_WINDOW_SIZE +const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)] = { + S(79be667e,f9dcbbac,55a06295,ce870b07,29bfcdb,2dce28d9,59f2815b,16f81798,483ada77,26a3c465,5da4fbfc,e1108a8,fd17b448,a6855419,9c47d08f,fb10d4b8) +#if WINDOW_G > 2 +,S(f9308a01,9258c310,49344f85,f89d5229,b531c845,836f99b0,8601f113,bce036f9,388f7b0f,632de814,fe337e6,2a37f356,6500a999,34c2231b,6cb9fd75,84b8e672) +#endif +#if WINDOW_G > 3 +,S(2f8bde4d,1a072093,55b4a725,a5c5128,e88b84bd,dc619ab7,cba8d569,b240efe4,d8ac2226,36e5e3d6,d4dba9dd,a6c9c426,f788271b,ab0d6840,dca87d3a,a6ac62d6) +,S(5cbdf064,6e5db4ea,a398f365,f2ea7a0e,3d419b7e,330e39c,e92bdded,cac4f9bc,6aebca40,ba255960,a3178d6d,861a54db,a813d0b8,13fde7b5,a5082628,87264da) +#endif +#if WINDOW_G > 4 +,S(acd484e2,f0c7f653,9ad178a,9f559abd,e0979697,4c57e714,c35f110d,fc27ccbe,cc338921,b0a7d9fd,64380971,763b61e9,add888a4,375f8e0f,5cc262a,c64f9c37) +,S(774ae7f8,58a9411e,5ef4246b,70c65aac,5649980b,e5c17891,bbec1789,5da008cb,d984a032,eb6b5e19,243dd56,d7b7b365,372db1e2,dff9d6a8,301d74c9,c953c61b) +,S(f28773c2,d975288b,c7d1d205,c3748651,b075fbc6,610e58cd,deeddf8f,19405aa8,ab0902e,8d880a89,758212eb,65cdaf47,3a1a06da,521fa91f,29b5cb52,db03ed81) +,S(d7924d4f,7d43ea96,5a465ae3,95ff411,31e5946f,3c85f79e,44adbcf8,e27e080e,581e2872,a86c72a6,83842ec2,28cc6def,ea40af2b,d896d3a5,c504dc9f,f6a26b58) +#endif +#if WINDOW_G > 5 +,S(defdea4c,db677750,a420fee8,7eacf21,eb9898ae,79b97687,66e4faa0,4a2d4a34,4211ab06,94635168,e997b0ea,d2a93dae,ced1f4a0,4a95c0f6,cfb199f6,9e56eb77) +,S(2b4ea0a7,97a443d2,93ef5cff,444f4979,f06acfeb,d7e86d27,74756561,38385b6c,85e89bc0,37945d93,b343083b,5a1c8613,1a01f60c,50269763,b570c854,e5c09b7a) +,S(352bbf4a,4cdd1256,4f93fa33,2ce33330,1d9ad402,71f81071,81340aef,25be59d5,321eb407,5348f534,d59c1825,9dda3e1f,4a1b3b2e,71b1039c,67bd3d8b,cf81998c) +,S(2fa2104d,6b38d11b,2300105,59879124,e42ab8df,eff5ff29,dc9cdadd,4ecacc3f,2de1068,295dd865,b6456933,5bd5dd80,181d70ec,fc882648,423ba76b,532b7d67) +,S(9248279b,9b4d68d,ab21a9b0,66edda83,263c3d84,e09572e2,69ca0cd7,f5453714,73016f7b,f234aade,5d1aa71b,dea2b1ff,3fc0de2a,887912ff,e54a32ce,97cb3402) +,S(daed4f2b,e3a8bf27,8e70132f,b0beb752,2f570e14,4bf615c0,7e996d44,3dee8729,a69dce4a,7d6c98e8,d4a1aca8,7ef8d700,3f83c230,f3afa726,ab40e522,90be1c55) +,S(c44d12c7,65d812e,8acf28d7,cbb19f90,11ecd9e9,fdf281b0,e6a3b5e8,7d22e7db,2119a460,ce326cdc,76c45926,c982fdac,e106e86,1edf61c5,a039063f,e0e6482) +,S(6a245bf6,dc698504,c89a20cf,ded60853,152b6953,36c28063,b61c65cb,d269e6b4,e022cf42,c2bd4a70,8b3f5126,f16a24ad,8b33ba48,d0423b6e,fd5e6348,100d8a82) +#endif +#if WINDOW_G > 6 +,S(1697ffa6,fd9de627,c077e3d2,fe541084,ce13300b,bec1146,f95ae57f,d0bd6a5,b9c398f1,86806f5d,27561506,e4557433,a2cf1500,9e498ae7,adee9d63,d01b2396) +,S(605bdb01,9981718b,986d0f07,e834cb0d,9deb8360,ffb7f61d,f982345e,f27a7479,2972d2d,e4f8d206,81a78d93,ec96fe23,c26bfae8,4fb14db4,3b01e1e9,56b8c49) +,S(62d14dab,4150bf49,7402fdc4,5a215e10,dcb01c35,4959b10c,fe31c7e9,d87ff33d,80fc06bd,8cc5b010,98088a19,50eed0db,1aa1329,67ab4722,35f56424,83b25eaf) +,S(80c60ad0,40f27da,de5b4b06,c408e56b,2c50e9f5,6b9b8b42,5e555c2f,86308b6f,1c38303f,1cc5c30f,26e66bad,7fe72f70,a65eed4c,be7024eb,1aa01f56,430bd57a) +,S(7a9375ad,6167ad54,aa74c634,8cc54d34,4cc5dc94,87d84704,9d5eabb0,fa03c8fb,d0e3fa9,eca87269,9559e0d,79269046,bdc59ea1,c70ce2b,2d499ec,224dc7f7) +,S(d528ecd9,b696b54c,907a9ed0,45447a79,bb408ec3,9b68df50,4bb51f45,9bc3ffc9,eecf4125,3136e5f9,9966f218,81fd656e,bc434540,5c520dbc,63465b5,21409933) +,S(49370a4,b5f43412,ea25f514,e8ecdad0,5266115e,4a7ecb13,87231808,f8b45963,758f3f41,afd6ed42,8b3081b0,512fd62a,54c3f3af,bb5b6764,b653052a,12949c9a) +,S(77f23093,6ee88cbb,d73df930,d64702ef,881d811e,e1498e2,f1c13eb1,fc345d74,958ef42a,7886b640,a08266e,9ba1b378,96c95330,d97077cb,be8eb3c7,671c60d6) +,S(f2dac991,cc4ce4b9,ea44887e,5c7c0bce,58c80074,ab9d4dba,eb28531b,7739f530,e0dedc9b,3b2f8dad,4da1f32d,ec2531df,9eb5fbeb,598e4fd,1a117dba,703a3c37) +,S(463b3d9f,662621fb,1b4be8fb,be252012,5a216cdf,c9dae3de,bcba4850,c690d45b,5ed430d7,8c296c35,43114306,dd8622d7,c622e27c,970a1de3,1cb377b0,1af7307e) +,S(f16f8042,44e46e2a,9232d4a,ff3b5997,6b98fac1,4328a2d1,a32496b4,9998f247,cedabd9b,82203f7e,13d206fc,df4e33d9,2a6c53c2,6e5cce26,d6579962,c4e31df6) +,S(caf75427,2dc84563,b0352b7a,14311af5,5d245315,ace27c65,369e15f7,151d41d1,cb474660,ef35f5f2,a41b643f,a5e46057,5f4fa9b7,962232a5,c32f9083,18a04476) +,S(2600ca4b,282cb986,f85d0f17,9979d8b,44a09c07,cb86d7c1,24497bc8,6f082120,4119b887,53c15bd6,a693b03f,cddbb45d,5ac6be74,ab5f0ef4,4b0be947,5a7e4b40) +,S(7635ca72,d7e8432c,338ec53c,d12220bc,1c48685,e24f7dc8,c602a774,6998e435,91b6496,9489d61,3d1d5e59,f78e6d7,4ecfc061,d57048ba,d9e76f30,2c5b9c61) +,S(754e3239,f325570c,dbbf4a87,deee8a66,b7f2b334,79d468fb,c1a50743,bf56cc18,673fb86,e5bda30f,b3cd0ed3,4ea49a0,23ee33d0,197a695d,c5d9809,3c536683) +,S(e3e6bd10,71a1e96a,ff57859c,82d570f0,33080066,1d1c952f,9fe26946,91d9b9e8,59c9e0bb,a394e76f,40c0aa58,379a3cb6,a5a22839,93e90c41,67002af4,920e37f5) +#endif +#if WINDOW_G > 7 +,S(186b483d,56a0338,26ae73d8,8f732985,c4ccb1f3,2ba35f4b,4cc47fdc,f04aa6eb,3b952d32,c67cf77e,2e17446e,204180ab,21fb8090,895138b4,a4a797f8,6e80888b) +,S(df9d70a6,b9876ce5,44c98561,f4be4f72,5442e6d2,b737d9c9,1a832172,4ce0963f,55eb2daf,d84d6ccd,5f862b78,5dc39d4a,b1572227,20ef9da2,17b8c45c,f2ba2417) +,S(5edd5cc2,3c51e87a,497ca815,d5dce0f8,ab52554f,849ed899,5de64c5f,34ce7143,efae9c8d,bc141306,61e8cec0,30c89ad0,c13c66c0,d17a2905,cdc706ab,7399a868) +,S(290798c2,b6476830,da12fe02,287e9e77,7aa3fba1,c355b17a,722d362f,84614fba,e38da76d,cd440621,988d00bc,f79af25d,5b29c094,db2a2314,6d003afd,41943e7a) +,S(af3c423a,95d9f5b3,54754ef,a150ac39,cd29552f,e3602573,62dfdece,f4053b45,f98a3fd8,31eb2b74,9a93b0e6,f35cfb40,c8cd5aa6,67a15581,bc2feded,498fd9c6) +,S(766dbb24,d134e745,cccaa28c,99bf2749,6bb66b2,6dcf98df,8d2fed50,d884249a,744b1152,eacbe5e3,8dcc8879,80da38b8,97584a65,fa06cedd,2c924f97,cbac5996) +,S(59dbf46f,8c94759b,a21277c3,3784f416,45f7b44f,6c596a58,ce92e666,191abe3e,c534ad44,175fbc30,f4ea6ce,648309a0,42ce739a,7919798c,d85e216c,4a307f6e) +,S(f13ada95,103c4537,305e691e,74e9a4a8,dd647e71,1a95e73c,b62dc601,8cfd87b8,e13817b4,4ee14de6,63bf4bc8,8341f32,6949e21a,6a75c257,778419b,daf5733d) +,S(7754b4fa,e8aced0,6d4167a2,c59cca4c,da1869c0,6ebadfb6,48855001,5a88522c,30e93e86,4e669d82,224b967c,3020b8fa,8d1e4e35,b6cbcc5,37a48b57,841163a2) +,S(948dcadf,5990e048,aa3874d4,6abef9d7,1858f95,de8041d2,a6828c99,e2262519,e491a425,37f6e597,d5d28a32,24b1bc25,df9154ef,bd2ef1d2,cbba2cae,5347d57e) +,S(79624144,50c76c16,89c7b48f,8202ec37,fb224cf5,ac0bfa15,70328a8a,3d7c77ab,100b610e,c4ffb476,d5c1fc1,33ef6f6b,12507a05,1f04ac57,60afa5b2,9db83437) +,S(35140878,34964b54,b15b1606,44d91548,5a169772,25b8847b,b0dd0851,37ec47ca,ef0afbb2,5620544,8e1652c4,8e8127fc,6039e77c,15c2378b,7e7d15a0,de293311) +,S(d3cc30ad,6b483e4b,c79ce2c9,dd8bc549,93e947eb,8df787b4,42943d3f,7b527eaf,8b378a22,d827278d,89c5e9be,8f9508ae,3c2ad462,90358630,afb34db0,4eede0a4) +,S(1624d847,80732860,ce1c78fc,bfefe08b,2b29823d,b913f649,3975ba0f,f4847610,68651cf9,b6da903e,914448c,6cd9d4ca,896878f5,282be4c8,cc06e2a4,4078575) +,S(733ce80d,a955a8a2,6902c956,33e62a98,5192474b,5af207da,6df7b4fd,5fc61cd4,f5435a2b,d2badf7d,485a4d8b,8db9fcce,3e1ef8e0,201e4578,c54673bc,1dc5ea1d) +,S(15d94412,54945064,cf1a1c33,bbd3b49f,8966c509,2171e699,ef258dfa,b81c045c,d56eb30b,69463e72,34f5137b,73b84177,434800ba,cebfc685,fc37bbe9,efe4070d) +,S(a1d0fcf2,ec9de675,b612136e,5ce70d27,1c21417c,9d2b8aaa,ac138599,d0717940,edd77f50,bcb5a3ca,b2e90737,309667f2,641462a5,4070f3d5,19212d39,c197a629) +,S(e22fbe15,c0af8ccc,5780c073,5f84dbe9,a790bade,e8245c06,c7ca3733,1cb36980,a855bab,ad5cd60c,88b430a6,9f53a1a7,a3828915,4964799b,e43d06d7,7d31da06) +,S(311091dd,9860e8e2,ee13473,c1155f5f,69635e39,4704eaa7,40094522,46cfa9b3,66db656f,87d1f04f,ffd1f047,88c06830,871ec5a6,4feee685,bd80f0b1,286d8374) +,S(34c1fd04,d301be89,b31c0442,d3e6ac24,883928b4,5a934078,1867d423,2ec2dbdf,9414685,e97b1b59,54bd46f7,30174136,d57f1cee,b487443d,c5321857,ba73abee) +,S(f219ea5d,6b54701c,1c14de5b,557eb42a,8d13f3ab,bcd08aff,cc2a5e6b,49b8d63,4cb95957,e83d40b0,f73af454,4cccf6b1,f4b08d3c,7b27fb8,d8c2962a,400766d1) +,S(d7b8740f,74a8fbaa,b1f683db,8f45de26,543a5490,bca62708,72369124,69a0b448,fa779681,28d9c92e,e1010f33,7ad4717e,ff15db5e,d3c049b3,411e0315,eaa4593b) +,S(32d31c22,2f8f6f0e,f86f7c98,d3a3335e,ad5bcd32,abdd9428,9fe4d309,1aa824bf,5f3032f5,892156e3,9ccd3d79,15b9e1da,2e6dac9e,6f26e961,118d14b8,462e1661) +,S(7461f371,914ab326,71045a15,5d9831ea,8793d77c,d59592c4,340f86cb,c18347b5,8ec0ba23,8b96bec0,cbdddcae,aa44254,2eee1ff5,c986ea6,b39847b3,cc092ff6) +,S(ee079adb,1df18600,74356a25,aa38206a,6d716b2c,3e67453d,287698ba,d7b2b2d6,8dc2412a,afe3be5c,4c5f37e0,ecc5f9f6,a446989a,f04c4e25,ebaac479,ec1c8c1e) +,S(16ec93e4,47ec83f0,467b1830,2ee620f7,e65de331,874c9dc7,2bfd8616,ba9da6b5,5e463115,e62fb40,d0e8c2a7,ca5804a3,9d58186a,50e49713,9626778e,25b0674d) +,S(eaa5f980,c245f6f0,38978290,afa70b6b,d8855897,f98b6aa4,85b96065,d537bd99,f65f5d3e,292c2e08,19a52839,1c994624,d784869d,7e6ea67f,b1804102,4edc07dc) +,S(78c9407,544ac132,692ee191,a024399,58ae0487,7151342e,a96c4b6b,35a49f51,f3e03191,69eb9b85,d5404795,539a5e68,fa1fbd58,3c064d24,62b675f1,94a3ddb4) +,S(494f4be2,19a1a770,16dcd838,431aea00,1cdc8ae,7a6fc688,726578d9,702857a5,42242a96,9283a5f3,39ba7f07,5e36ba2a,f925ce30,d767ed6e,55f4b031,880d562c) +,S(a598a803,da6d86c,6bc7f2f5,144ea549,d28211ea,58faa70e,bf4c1e66,5c1fe9b5,204b5d6f,84822c30,7e4b4a71,40737aec,23fc63b6,5b35f86a,10026dbd,2d864e6b) +,S(c4191636,5abb2b5d,9192f5f,2dbeafec,208f020f,12570a18,4dbadc3e,58595997,4f14351,d0087efa,49d245b3,28984989,d5caf945,f34bfc0,ed16e96b,58fa9913) +,S(841d6063,a586fa47,5a724604,da03bc5b,92a2e0d2,e0a36acf,e4c73a55,14742881,73867f5,9c0659e8,1904f9a1,c7543698,e62562d6,744c169c,e7a36de0,1a8d6154) +#endif +#if WINDOW_G > 8 +,S(5e95bb39,9a6971d3,76026947,f89bde2f,282b3381,928be4d,ed112ac4,d70e20d5,39f23f36,6809085b,eebfc711,81313775,a99c9aed,7d8ba38b,161384c7,46012865) +,S(36e4641a,53948fd4,76c39f8a,99fd974e,5ec07564,b5315d8b,f99471bc,a0ef2f66,d2424b1b,1abe4eb8,164227b0,85c9aa94,56ea1349,3fd563e0,6fd51cf5,694c78fc) +,S(336581e,a7bfbbb2,90c191a2,f507a41c,f5643842,170e914f,aeab27c2,c579f726,ead12168,595fe1be,99252129,b6e56b33,91f7ab14,10cd1e0e,f3dcdcab,d2fda224) +,S(8ab89816,dadfd6b6,a1f2634f,cf00ec84,3781025,ed6890c4,84974270,6bd43ede,6fdcef09,f2f6d0a0,44e654ae,f624136f,503d459c,3e898458,58a47a91,29cdd24e) +,S(1e33f1a7,46c9c577,8133344d,9299fcaa,20b0938e,8acff254,4bb40284,b8c5fb94,6066025,7dd11b3a,a9c8ed61,8d24edff,2306d320,f1d03010,e33a7d20,57f3b3b6) +,S(85b7c1dc,b3cec1b7,ee7f30de,d79dd20a,ed1f4cc,18cbcfcf,a410361f,d8f08f31,3d98a9cd,d026dd43,f39048f2,5a8847f4,fcafad18,95d7a633,c6fed3c3,5e999511) +,S(29df9fbd,8d9e4650,9275f4b1,25d6d45d,7fbe9a3b,878a7af8,72a28006,61ac5f51,b4c4fe9,9c775a60,6e2d8862,179139ff,da61dc86,1c019e55,cd2876eb,2a27d84b) +,S(a0b1cae0,6b0a847a,3fea6e67,1aaf8adf,dfe58ca2,f768105c,8082b2e4,49fce252,ae434102,edde0958,ec4b19d9,17a6a28e,6b72da18,34aff0e6,50f04950,3a296cf2) +,S(4e8ceaf,b9b3e9a1,36dc7ff6,7e840295,b499dfb3,b2133e4b,a113f2e4,c0e121e5,cf217411,8c8b6d7a,4b48f6d5,34ce5c79,422c086a,63460502,b827ce62,a326683c) +,S(d24a44e0,47e19b6f,5afb81c7,ca2f6908,a507668,9a010919,f42725c2,b789a33b,6fb8d559,1b466f8f,c63db50f,1c0f1c69,13f9968,87b8244d,2cdec417,afea8fa3) +,S(ea01606a,7a6c9cdd,249fdfcf,acb99584,1edd28,abbab77b,5104e98e,8e3b35d4,322af490,8c7312b0,cfbfe369,f7a7b3cd,b7d4494b,c2823700,cfd65218,8a3ea98d) +,S(af8addbf,2b661c8a,6c632865,5eb96651,252007d8,c5ea31be,4ad196de,8ce2131f,6749e67c,29b85f5,2a034eaf,d096836b,25208186,80e26ac8,f3dfbcdb,71749700) +,S(e3ae19,74566ca0,6cc516d4,7e0fb165,a674a3da,bcfca15e,722f0e34,50f45889,2aeabe7e,45315101,16217f07,bf4d0730,de97e48,74f81f53,3420a72e,eb0bd6a4) +,S(591ee355,313d9972,1cf6993f,fed1e3e3,1993ff3,ed258802,75ea8ce,d397e246,b0ea558a,113c30be,a60fc477,5460c790,1ff0b053,d25ca2bd,eee98f1a,4be5d196) +,S(11396d55,fda54c49,f19aa973,18d8da61,fa8584e4,7b084945,77cf032,55b52984,998c74a8,cd45ac01,289d5833,a7beb474,4ff536b0,1b257be4,c5767bea,93ea57a4) +,S(3c5d2a1b,a39c5a17,90000738,c9e0c40b,8dcdfd54,68754b64,5540157,e017aa7a,b2284279,995a34e2,f9d4de73,96fc18b8,f9b8b9f,dd270f66,61f79ca4,c81bd257) +,S(cc8704b8,a60a0def,a3a99a72,99f2e9c3,fbc395af,b04ac078,425ef8a1,793cc030,bdd46039,feed1788,1d1e0862,db347f8c,f395b74f,c4bcdc4e,940b74e3,ac1f1b13) +,S(c533e4f7,ea8555aa,cd9777ac,5cad29b9,7dd4defc,cc53ee7e,a204119b,2889b197,6f0a256b,c5efdf42,9a2fb624,2f1a43a2,d9b925bb,4a4b3a26,bb8e0f45,eb596096) +,S(c14f8f2,ccb27d6f,109f6d08,d03cc96a,69ba8c34,eec07bbc,f566d48e,33da6593,c359d692,3bb398f7,fd4473e1,6fe1c284,75b740dd,98075e6,c0e86491,13dc3a38) +,S(a6cbc304,6bc6a450,bac24789,fa17115a,4c9739ed,75f8f21c,e441f72e,b90e6ef,21ae7f4,680e889b,b130619e,2c0f95a3,60ceb573,c7060313,9862afd6,17fa9b9f) +,S(347d6d9a,2c48927,ebfb86c1,359b1caf,130a3c02,67d11ce6,344b39f9,9d43cc38,60ea7f61,a353524d,1c987f6e,cec92f08,6d565ab6,87870cb1,2689ff1e,31c74448) +,S(da6545d2,181db8d9,83f7dcb3,75ef5866,d47c67b1,bf31c8cf,855ef743,7b72656a,49b96715,ab6878a7,9e78f07c,e5680c5d,6673051b,4935bd89,7fea824b,77dc208a) +,S(c40747cc,9d012cb1,a13b8148,309c6de7,ec25d694,5d657146,b9d5994b,8feb1111,5ca56075,3be2a12f,c6de6caf,2cb48956,5db93615,6b9514e1,bb5e8303,7e0fa2d4) +,S(4e42c8ec,82c99798,ccf3a610,be870e78,338c7f71,3348bd34,c8203ef4,37f3502,7571d74e,e5e0fb92,a7a8b33a,7783341,a5492144,cc54bcc4,a944736,93606437) +,S(3775ab70,89bc6af8,23aba2e1,af70b236,d251cadb,c867432,87522a1b,3b0dedea,be52d107,bcfa09d8,bcb9736a,828cfa7f,ac8db17b,f7a76a2c,42ad9614,9018cf7) +,S(cee31cbf,7e34ec37,9d94fb81,4d3d775a,d954595d,1314ba88,46959e3e,82f74e26,8fd64a14,c06b589c,26b947ae,2bcf6bfa,149ef0b,e14ed4d8,f448a01,c43b1c6d) +,S(b4f9eaea,9b69176,19f6ea6a,4eb5464e,fddb58fd,45b1ebef,cdc1a01d,8b47986,39e5c992,5b5a54b0,7433a4f1,8c61726f,8bb131c0,12ca542e,b24a8ac0,7200682a) +,S(d4263dfc,3d2df923,a0179a48,966d30ce,84e2515a,fc3dccc1,b7790779,2ebcc60e,62dfaf07,a0f78feb,30e30d62,95853ce1,89e12776,ad6cf7f,ae164e12,2a208d54) +,S(48457524,820fa65a,4f8d35eb,6930857c,32acc0,a4a2de42,2233eeda,897612c4,25a748ab,367979d9,8733c38a,1fa1c2e7,dc6cc07d,b2d60a9a,e7a76aaa,49bd0f77) +,S(dfeeef18,81101f2c,b11644f3,a2afdfc2,45e1991,9152923f,367a1767,c11cceda,ecfb7056,cf1de042,f9420bab,396793c0,c390bde7,4b4bbdff,16a83ae0,9a9a7517) +,S(6d7ef6b1,7543f837,3c573f44,e1f38983,5d89bcbc,6062ced3,6c82df83,b8fae859,cd450ec3,35438986,dfefa10c,57fea9bc,c521a095,9b2d80bb,f74b190d,ca712d10) +,S(e75605d5,9102a5a2,684500d3,b991f2e3,f3c88b93,22554703,5af25af6,6e04541f,f5c54754,a8f71ee5,40b9b487,28473e31,4f729ac5,308b0693,8360990e,2bfad125) +,S(eb98660f,4c4dfaa0,6a2be453,d5020bc9,9a0c2e60,abe38845,7dd43fef,b1ed620c,6cb9a887,6d9cb852,609af3a,dd26cd20,a0a7cd8a,9411131c,e85f4410,99223e) +,S(13e87b02,7d8514d3,5939f2e6,892b1992,21545969,41888336,dc3563e3,b8dba942,fef5a3c6,8059a6de,c5d62411,4bf1e91a,ac2b9da5,68d6abeb,2570d556,46b8adf1) +,S(ee163026,e9fd6fe0,17c38f06,a5be6fc1,25424b37,1ce2708e,7bf44916,91e5764a,1acb250f,255dd61c,43d94ccc,670d0f58,f49ae3fa,15b96623,e5430da0,ad6c62b2) +,S(b268f5ef,9ad51e4d,78de3a75,c2dc89b,1e626d43,50586799,9932e5db,33af3d80,5f310d4b,3c99b9eb,b19f77d4,1c1dee01,8cf0d34f,d4191614,3e945a,1216e423) +,S(ff07f311,8a9df035,e9fad85e,b6c7bfe4,2b02f01c,a99ceea3,bf7ffdba,93c4750d,438136d6,3e858a3,a5c440c3,8eccbadd,c1d29421,14e2eddd,4740d098,ced1f0d8) +,S(8d8b9855,c7c052a3,4146fd20,ffb658be,a4b9f69e,d825ebe,c16e8c3c,e2b526a1,cdb559ee,dc2d79f9,26baf44f,b84ea4d4,4bcf50fe,e51d7ceb,30e2e7f4,63036758) +,S(52db0b53,84dfbf05,bfa9d472,d7ae26df,e4b851ce,ca91b1eb,a5426318,da32b63,c3b997d,50ee5d4,23ebaf66,a6db9f57,b3180c90,2875679d,e924b69d,84a7b375) +,S(e62f9490,d3d51da6,395efd24,e80919cc,7d0f29c3,f3fa48c6,fff543be,cbd43352,6d89ad7b,a4876b0b,22c2ca28,c682862,f342c859,1f1daf51,70e07bfd,9ccafa7d) +,S(7f30ea24,76b399b4,957509c8,8f77d019,1afa2ff5,cb7b14fd,6d8e7d65,aaab1193,ca5ef7d4,b231c94c,3b15389a,5f6311e9,daff7bb6,7b103e98,80ef4bff,637acaec) +,S(5098ff1e,1d9f14fb,46a210fa,da6c903f,ef0fb7b4,a1dd1d9a,c60a0361,800b7a00,9731141,d81fc8f8,84d37c6,e7542006,b3ee1b40,d60dfe53,62a5b132,fd17ddc0) +,S(32b78c7d,e9ee512a,72895be6,b9cbefa6,e2f3c4cc,ce445c96,b9f2c81e,2778ad58,ee1849f5,13df71e3,2efc3896,ee28260c,73bb8054,7ae2275b,a4972377,94c8753c) +,S(e2cb74fd,dc8e9fbc,d076eef2,a7c72b0c,e37d50f0,8269dfc0,74b58155,547a4f7,d3aa2ed7,1c9dd224,7a62df06,2736eb0b,addea9e3,6122d2be,8641abcb,5cc4a4) +,S(84384475,66d4d7be,dadc2994,96ab3574,26009a35,f235cb14,1be0d99c,d10ae3a8,c4e10209,16980a4d,a5d01ac5,e6ad3307,34ef0d79,6631c4f,2390426b,2edd791f) +,S(4162d488,b8940203,9b584c6f,c6c30887,587d9c4,6f660b87,8ab65c82,c711d67e,67163e90,3236289f,776f22c2,5fb8a3af,c1732f2b,84b4e95d,bda47ae5,a0852649) +,S(3fad3fa8,4caf0f34,f0f89bfd,2dcf54fc,175d767a,ec3e5068,4f3ba4a4,bf5f683d,cd1bc7c,b6cc407b,b2f0ca64,7c718a73,cf71872,e7d0d2a5,3fa20efc,dfe61826) +,S(674f2600,a3007a00,568c1a7c,e05d0816,c1fb84bf,1370798f,1c69532f,aeb1a86b,299d21f9,413f33b3,edf43b25,7004580b,70db57da,b182259,e09eecc6,9e0d38a5) +,S(d32f4da5,4ade74ab,b81b815a,d1fb3b26,3d82d6c6,92714bcf,f87d29bd,5ee9f08f,f9429e73,8b8e53b9,68e99016,c0597077,82e14f45,35359d58,2fc41691,b3eea87) +,S(30e4e670,43538555,6e593657,135845d3,6fbb6931,f72b08cb,1ed954f1,e3ce3ff6,462f9bce,61989863,84993501,13bbc9b1,a878d35,da70740d,c695a559,eb88db7b) +,S(be206200,3c51cc30,4682904,330e4dee,7f3dcd10,b01e580b,f1971b04,d4cad297,62188bc4,9d61e542,8573d48a,74e1c655,b1c61090,905682a0,d5558ed7,2dccb9bc) +,S(93144423,ace3451e,d29e0fb9,ac2af211,cb6e84a6,1df5993,c419859f,ff5df04a,7c10dfb1,64c3425f,5c71a3f9,d7992038,f1065224,f72bb9d1,d902a6d1,3037b47c) +,S(b015f804,4f5fcbdc,f21ca26d,6c34fb81,97829205,c7b7d2a7,cb66418c,157b112c,ab8c1e08,6d04e813,744a655b,2df8d5f8,3b3cdc6f,aa3088c1,d3aea145,4e3a1d5f) +,S(d5e9e1da,649d97d8,9e486811,7a465a3a,4f8a18de,57a140d3,6b3f2af3,41a21b52,4cb04437,f391ed73,111a13cc,1d4dd0db,1693465c,2240480d,8955e859,2f27447a) +,S(d3ae4104,7dd7ca06,5dbf8ed7,7b992439,983005cd,72e16d6f,996a5316,d36966bb,bd1aeb21,ad22ebb2,2a10f030,3417c6d9,64f8cdd7,df0aca61,4b10dc14,d125ac46) +,S(463e2763,d885f958,fc66cdd2,2800f0a4,87197d0a,82e377b4,9f80af87,c897b065,bfefacdb,e5d0fd7,df3a311a,94de062b,26b80c61,fbc97508,b7999267,1ef7ca7f) +,S(7985fdfd,127c0567,c6f53ec1,bb63ec31,58e597c4,bfe747c,83cddfc9,10641917,603c12da,f3d9862e,f2b25fe1,de289aed,24ed291e,ec67087,3a5bd56,7f32ed03) +,S(74a1ad6b,5f76e39d,b2dd2494,10eac7f9,9e74c59c,b83d2d0e,d5ff1543,da7703e9,cc6157ef,18c9c63c,d6193d83,631bbea0,93e0968,942e8c33,d5737fd7,90e0db08) +,S(30682a50,703375f6,2d41666,4ba19b7f,c9bab42c,72747463,a71d0896,b22f6da3,553e04f6,b018b4fa,6c8f39e7,f311d317,6290d0e0,f19ca73f,17714d99,77a22ff8) +,S(9e2158f0,d7c0d5f2,6c3791ef,efa79597,654e7a2b,2464f52b,1ee6c134,7769ef57,712fcdd,1b9053f0,9003a348,1fa7762e,9ffd7c8e,f35a3850,9e2fbf26,29008373) +,S(176e2698,9a43c9cf,eba4029c,202538c2,8172e566,e3c4fce7,322857f3,be327d66,ed8cc9d0,4b29eb87,7d270b48,78dc43c1,9aefd31f,4eee09ee,7b47834c,1fa4b1c3) +,S(75d46efe,a3771e6e,68abb89a,13ad747e,cf189239,3dfc4f1b,7004788c,50374da8,9852390a,99507679,fd0b86fd,2b39a868,d7efc221,51346e1a,3ca47265,86a6bed8) +,S(809a20c6,7d64900f,fb698c4c,825f6d5f,2310fb04,51c86934,5b7319f6,45605721,9e994980,d9917e22,b76b0619,27fa0414,3d096ccc,54963e6a,5ebfa5f3,f8e286c1) +,S(1b38903a,43f7f114,ed4500b4,eac7083f,defece1c,f29c6352,8d563446,f972c180,4036edc9,31a60ae8,89353f77,fd53de4a,2708b26b,6f5da72a,d3394119,daf408f9) +#endif +#if WINDOW_G > 9 +,S(90a80db6,eb294b9e,ab0b4e8d,dfa3efe7,263458ce,2d07566d,f4e6c588,68feef23,753c8b9f,9754f18d,87f21145,d9e2936b,5ee050b2,7bbd9681,442c76e9,2fcf91e6) +,S(c2c80f84,4b705998,12d62546,f60340e,3e6f3605,4a14546e,6dc25d47,376bea9b,86ca160d,68f4d4e7,18b495b8,91d3b1b5,73b871a7,2b4cf61,23abd448,3aa79c64) +,S(9cf60674,4cf4b5f3,fdf989d3,f19fb265,2d00cfe1,d5fcd692,a323ce11,a28e7553,8147cbf7,b973fcc1,5b57b6a3,cfad6863,edd0f30e,3c45b85d,c300c513,c247759d) +,S(57488fa2,8742c6b2,5a493fd6,60d936e,a6280b0c,742005ab,ce98f585,5ad82208,31b3ca45,5073bea5,58adbe56,c27b470b,af949ae6,50213921,dc287844,f1a29574) +,S(f1133cbe,6be8bbc8,dc8df2b8,d75963c2,d40ed616,c758cdc8,4edbc5eb,4899447d,57fc2447,2225b23f,5714626d,8d67d561,10bd3a60,dd7a1687,cbbb893,f652f50f) +,S(95083e75,3301bd78,7f8989c7,9065bb81,3f3d69bf,f3e42505,f4e0417,5bbe89c0,844adb5c,e7d10de9,4617c73c,a77040e4,ee4e92e0,156b3c70,cc593fa4,94b33482) +,S(1a908355,cbb75675,5e576ed2,9c99af63,8668c7b3,63c8d973,62100443,bc5c75c6,d765466c,6e556e35,2f778722,25627d80,a7353807,4b44ff27,57ad22e,2f2454a2) +,S(c5922f74,bd343d5,aa867308,fad97f9f,8a2d1f63,c5f31db4,f04df3be,f349b648,77b1f068,7cfcdbe8,812605e5,d8b752c,da811844,236a4c43,77f53c94,6e7bd648) +,S(64e1b196,9f910297,7691a404,31b0b672,55dcf31,163897d9,96434420,e6c95dc9,c16f60c7,c11fc3c9,eb27fa26,a9035b66,9bfb77d2,1cef371d,dce94e32,9222550c) +,S(33b2e76,687744ed,6c521bad,3333dd37,c602f8a7,549e9ce7,808fb7ea,7ce08de,e1bcfe7f,c8ed8ae9,5cf6c243,7fdd94bf,d742e8ca,a6de7811,4c25112a,86988efd) +,S(20f18f4c,866d8a1c,c2a31033,17b4ac31,89fbf30f,f294a75c,951473be,45e4f294,8d6857c9,d08ef7b4,fd888336,3d37bee7,fe8529f,7173f589,43fcae81,d2d0ea0e) +,S(4d1623c9,44c9c716,a0eb4c68,5e2a8b9d,2df34653,54643bef,d1444176,d7b69a8b,ddf1b9fe,8744ad03,f996bf6b,96ec3496,2b601bd5,ed952f78,54f58388,8917be80) +,S(a901b0db,e8ab292d,280d6b36,85894785,4faad0a4,dd0da7e2,d4ad0ff5,3db079e0,3f27e7e1,834f1a61,af6f04dc,61e7ae64,716bc5e0,a6b063b3,1d0e60e,47298a9d) +,S(7e0af071,30218ffd,50bd66f4,484645b1,2f42a24f,7c80889b,3031c9a6,ebfc9a70,50bc23f3,926cd0c4,9f53fbb2,35eb1e89,d579517,f5bdc3ab,2416db78,5aaedb3f) +,S(7ba8187e,1a7b25a2,c185d335,440a9038,b47f0528,546e9da4,ef82aab0,5aebf20d,6e6aee6c,9625370a,f866c25c,7ca5dd78,527efbc,e7d8b3a3,9ab24930,9a185187) +,S(8c050fc3,4d83b279,b6000816,e18fca38,9767b796,e926772,55b84a39,d93a6807,986314ef,75b68fb2,827c2965,4198139,5d699fcd,81cf23ce,7019bc41,35174870) +,S(53b7849a,78e4df86,25860583,a5249948,9d7201a2,cbf50620,2a7b8b1b,c99c2ec9,4e31ea12,ac607d07,5de4b22d,e1be2c52,e0a44d25,4728d2c5,44d2ddf9,e3e469c0) +,S(9bdf9e67,a5d0c995,6a075a01,fe762be,b6335004,31dee78e,febc527e,53313b33,94264621,a5960e0e,e24c2792,6f16cad2,907f2636,762e8d5a,17e94afd,8e9d2bb0) +,S(7caa72b3,7a8ab3bd,bac031a,47606f89,17d9f42c,6ec2d2fb,429fd990,4a381f34,5b5853ab,7ee5de8d,34e3d6be,b201094f,ff8fbd1e,682f7f1,ef87ddd6,5d7303c9) +,S(2ef29b9f,9827975,79c0295f,c3f48db7,925d62c7,5532493d,de16b97e,3993d81a,496c944d,d9875ba6,a537ef9,6bf4c714,a0afff24,387d95e8,9b42337a,33110753) +,S(df157cad,95b07875,573c1860,ae5d02c6,4029e952,ec354e6a,9e5c34be,97317ff8,f2eccac7,75922b50,899c979a,2b3cc30,b629e62e,85693ba4,70f6ee38,1284c162) +,S(dd55c150,a29ca526,b6182e64,3b9eb544,e651d236,b71920e7,b15a9870,16454b1d,44c757a5,42f4ea2e,b39605d4,268c2510,ac685aab,d77a8f5c,4d95e23f,4c2e9368) +,S(16886cf4,6ed42c79,19147763,63d3256,c4d5d393,87f01723,25b9e4b8,98227f27,7421a220,7ee73299,d46192fc,93ca03de,c824ed8d,e2f48367,ec538317,a17fffb) +,S(6ff180fc,daa30618,8e8b306,d6f0acff,27968c22,484ff45e,56aeaa7b,2b60732f,7d16d654,f0c2aff0,fc254dad,63761a2,6c8d4022,ea85b8cc,22f3ea1e,f69961a9) +,S(3ea4511,a00dc2a0,3eb4f51f,40ee677c,aa912b55,39f685c4,f8bcc8ea,dc395e36,6c9ed1f1,528b0215,93a39839,340ddb53,a2f2e36,5290c498,24b035c6,73c9259d) +,S(b82cd70,dc3de9ea,b38742d8,f32dfb8d,53e4150a,835e54b6,3c7cca20,f253081d,e8bcbfe,1f7f6e75,d32e2049,9329765f,2effc56,a922f268,60d4bc0a,add0e24d) +,S(fe2fc3e0,748745,84ee23bf,105a69a6,6d056f0,17327d49,b7b38b57,a196c77f,3e18941c,c3c6d297,cc9a32f6,95807b1c,7da8561d,e4fde71d,4f9bbdb6,e9bf3916) +,S(4b90176,cdaa3693,47e8778b,12db9d6e,e8b00114,46ea35ec,845dbf57,4bb7858b,f60547ab,6e9c5fd3,eca6e349,b85880c6,1fdad0fc,2f7ab155,295caaec,b973c154) +,S(35f38251,1d34600b,4b8c86a9,f0dbc9ed,defc4272,f59528a0,cd3ec10a,5944c6d2,29a835f6,ef7fa1e5,f6f37a80,cf96ca98,43762bb1,b12a0dae,ae83234b,d0b5ccd5) +,S(1d74b297,311b7ff,a1027e26,587d3f5b,e1d0e9ac,3f0111cd,f3cc2371,722cb94a,5c7bcf8b,57f114e0,b73bcfb8,10f5c60d,35dc99ae,9dc7f0e2,606cc1f7,28c2071e) +,S(50a094f3,9c6f956,b020737,b9ec722e,4f75d1b7,c41593e6,f934a68a,98450428,a286e222,dfe10cfd,9689eaba,6a81f044,89c86db6,869aa1b5,54a90f1e,83778eee) +,S(9b65bb81,2129157c,dfecf12e,275ec38c,282dbcd9,14b48105,99b0a6d6,27c63db7,c582db1a,3f0f2242,1913b2e9,51e98a78,660b4c40,ad08fd65,528593bc,18223188) +,S(8b4544fc,1fdfa06e,456c1115,a1dc831c,85e7f1c5,e620eca5,1c20802d,36a4bc6b,e3e77c41,288f2602,e722af7f,4b70e64d,e4116fb9,955b03b0,6ea8b19f,7a20350d) +,S(6c709880,b959eb7c,5179b29c,c5578fdc,6cb2ae13,ddcede29,d5f81d95,de0ab4aa,c9e33fae,bd8eba42,6736c0c7,6f3deaba,ee2b59c5,953fb43,c2dcc513,9e7c4bdc) +,S(77760b51,37ba6a71,95d891f7,94a087a0,76fc9d67,802b81e7,85b5677,3d537806,f5202cf5,aaeea58b,f4f58c7e,df4417be,1b87ffde,e68e77f0,d7e81abe,158e3a25) +,S(1a8bd783,6a0b0c82,e9a904a8,a8c91a67,e23cd4f8,efd625d0,df4c426e,7e163102,61fe64ca,b0952cae,3c574f28,2f74a87d,c2a96316,b7009f2e,4e9c5fcc,12285844) +,S(fe217db6,59079913,fb1e453e,d24d91d6,a3fb3099,e69471d7,53db5390,864abc30,5dcf9abb,a9625ed6,80b0f20f,b1f047d5,93a0c61c,53969253,8cdf6b03,4d730b58) +,S(2504d637,54afd5eb,c38f58b6,5ead696d,7e3abd7,48cb6c5f,212aed49,f5b33b91,79a6bf43,75f1469c,4f5321c6,c72fbbf4,ba7cec10,5675f437,b5e013ad,7b5d75d4) +,S(b06f702,f47b22d7,89a9bd3f,687105c3,6160abbf,5cc8976b,7fbddcaf,db197b5c,7669bbd4,19a4d491,f592a35b,6aa3dfe4,5bd2fe7f,d179c778,1cd5f918,d732f63d) +,S(803b203b,b31f9cf9,4034eeb9,31b54480,a6f3f99e,bd23d0ac,bc2128a6,d044e23,308abc8d,f271f759,59b20c5c,7fa62baf,bfc9ccbf,49b946a9,54e5381c,1728d1c7) +,S(266a9cb4,c5f5cead,bb50e5bd,a03a7312,e52de1de,8e95a8dc,d57289fe,302749a,9eea970b,a856b2fa,a3e82877,cc84ed4f,3dc0efba,1e7c3baa,8b386ffc,46e0ae7e) +,S(fd8a9d95,d80c7ad5,2599a7ab,98163df3,64c4c141,e9abea35,5d7360bc,f84eba94,a9fb1702,100953b3,59b2e268,8ae7fd33,a30377da,47bfda71,3e2d7d73,dfb1030c) +,S(a7322df3,9f28f23,59fc339a,8b2c80be,6e84acc5,b7b0b8f8,f2cb6f26,f9db0a7d,22f6fe9d,21749501,7fdb7f5b,2f12fa57,95f40e1,31714885,c12a2ea1,6edb6be6) +,S(82a8c10f,336a6649,63a104dd,bf7f0f18,bd4c461a,ea569ffc,82c3c7e4,cb052d36,737ceca2,c0ef7227,8b90501c,cb71b671,5e5c31d4,cd0478c1,18fe1287,95f1dd0c) +,S(9b50d1b6,8e3bf795,7cd12f,5a60c26,6c4ef2b7,5ba5c516,c54784a9,4f15d6df,2afc8d09,b79176d8,d003fd2a,4f18d526,403fff27,2d47e778,7376feb7,cbddd8fd) +,S(3f9083dd,c8b423fe,7de3a822,81d3056a,b8dcb9d7,ee82cb80,6718595f,bae08d32,cb13c152,fd511d91,a9e0ed90,afa021a0,81f77f6d,20cc1376,e2195ffc,f28fa758) +,S(c75c85c1,ee17c1a2,56eff6bd,592666cb,c9231706,59d50bfa,dbd1074e,f2167faf,1ab4eabe,5e09409d,75cca892,2647f48d,bd698a16,d4f7cc85,96daf169,40023a52) +,S(c5341fea,f8a0f5d3,b4d0cf0d,2f7aad7c,60ea8e2b,3d4b7fb9,5c68d576,98656045,95f9f4e9,7e5b9f,a48fa422,a26ab982,dc48a4d5,4d712398,6e6d3ab9,74e88915) +,S(83acda3e,2a8997e0,d52bd4c6,8705dd22,220852b7,752d67fd,8967a032,60c2d89b,dce1bae1,d655ba51,7f5b5580,99711757,a77cd3b,dd4b8e8e,330e9779,1bc31df0) +,S(5b819146,8b299074,5b9c4164,e29d594c,f1c0d571,6c5d3962,5bd279b3,25237b,cc3636a0,3fddddfa,bed88daa,b081f359,1c48d2ca,71ba34fc,f6989f4a,f7625d8e) +,S(64778122,214e38ef,f8041796,166104e7,32f5f664,d38d7721,9b89045e,2c3b0e6c,329cf049,7e15eec7,b8eafc4a,b8a7d1c,d8b63203,8d4aef81,974cf984,4611a32d) +,S(ed4d826a,fe5762f4,79509909,9aee8664,2b475a9d,6da1017c,43d0cb9f,1af12323,8c6f81be,3fafa5ee,c8296f92,8ac7919d,c4d88c9a,59442274,d0531b7b,f7e48e78) +,S(38b42924,419aecc3,acd6f551,346fd61a,4d82ac2b,55f7afe9,7a06eb40,cd109c4a,7f42c096,2feb2f73,b2b0965a,1f359a6a,de49d768,a2ce6b07,b5acb92b,73e05583) +,S(c3cad4a8,d8bb94a7,b434cf70,183e8615,bb2a8f62,24f216e3,446ac2e9,82138911,f649be27,8cad9764,20742ce3,82dce3a1,420e372e,f1b25b27,59a8ed38,7282765e) +,S(2d408ff4,d3d236fd,54fae40d,ce3ea9ec,d9212e57,36591a9e,55588e4a,54bd6538,d596adf0,e8692a06,bc6284bf,299bef6,85e2a171,585aa132,4b9a05b5,ce815b7) +,S(ee7adf6d,247f25fb,76e90cf8,13f888eb,d67423a3,a3c6fdae,bafb7eaa,7a33c854,e077184b,4ae8f705,6c10dd9e,f541689d,143f6871,789e1801,deaefc1d,527a8fb4) +,S(2f9457c8,a9ffaca1,3d91151d,c4c5e89d,dd5d37a3,7c9a864b,7c811f3e,1144b34,eb4c9848,9093d573,a295407e,1d6fc48a,787120ce,b3d3dcfb,b40634e0,e75e221d) +,S(d3f332b8,a0f11582,1ce3478c,efe18de3,60120483,ef531c27,7b30c46e,b7fec294,ea75b9b2,5d717861,d1af1c01,9c372941,c8968b90,ef134f9f,323215e1,bb0b2155) +,S(183408d3,38b05aad,3521fcd8,6ef36dd7,5f3ddb86,66b52f7e,9a4cdf1f,8e152b91,66998520,6edf4ac6,f39be21f,20c98824,210e204c,e4499809,5de35537,1641218c) +,S(283fec5d,b1145e53,ba8f1f0f,f9cf89a7,21faffd6,c2534686,3d395609,5f40374e,70b01237,74af550e,68e68e5f,65ca6e98,8846e03,cf39af77,8511be82,bc32fefe) +,S(ce7570a,4f943cfa,413bd249,d8e7dbfc,ebc73579,770fd6da,f54a0dfb,dd52fa62,e115b14b,ef4695cf,fb85bdf9,8ba3985c,bd5e5b89,83e05390,7c36f9ce,8b75d41d) +,S(7e9c4f19,c8f4ec3f,1269f648,cd919525,df790315,74cbeb15,37794a4c,838fd470,e9d9dbfe,8cf5f5cc,a855d6cc,bd11f480,60fafa8d,ad6bd3e9,c86df5ce,b0fa5270) +,S(e2a9bbe6,d5d5bfe,a7c7f919,df2309f9,ba04f4c,722a3ec2,3bf451b4,64cb001b,e4177ce1,c3cd6ac7,78925bd6,7e72cb77,d1925b91,d06a7f16,98411a47,86393fb0) +,S(504512a4,3e17ef50,e43bf37d,42a94990,f55e641b,1558c265,e7099002,75271012,954a5fd8,57ba3acf,2d4b1f41,e8e1f2cd,1f21c4b9,6899781b,742a49d2,e61ed18b) +,S(81d1f013,a6bb325f,4b2d1d51,ba72c721,859945d8,a17b3411,cd5cbe87,285f850d,2d5d2fb1,f0c30855,3b1fe249,298b2059,259d3d49,d4d7071a,dce4bcc5,dc937193) +,S(5b66c2df,c1d28266,18a87276,7e66c33d,d90dd514,14a3b87c,a733383d,1d895022,9bd0178e,38189569,2217267b,7407e987,27fcaeda,12d8cf54,49eb5472,d554e0ff) +,S(aeb5f70e,98ec5e38,dbd2d544,bdbff8ab,99b583d9,af58c597,afaf8688,20381186,618bd6b0,d25ca70d,f08b7692,9336e421,691b0973,f2f5a05,2e7adc17,3584427b) +,S(b289eff,e841943b,84761e3c,67a9c02a,557679ca,76ad753a,707a9821,2505052e,7a981f0,c21862a8,53b4f895,dc62482c,530ed738,5e5d1e33,cfb9d0f,e879992c) +,S(abae3945,8b12199e,6b0c8360,cfd28288,3f585917,e44e1200,f81bd356,f619291c,adb23bcd,b3d069c5,e83be30b,2469b068,b2a81b7,b667e934,233b75ef,b5753f28) +,S(4a9583a6,485b5a5a,81ac224a,518eb29d,1e0f658c,8d91b013,9419c809,55fbacaa,d8003c9e,e3c842f5,ede375a8,a7768db4,803ecf11,9b7b37de,cea15631,b4e8dbca) +,S(d52f630e,dba6f7cb,65fcf465,44ab0d9e,ea236ac1,460f17ae,3a210102,10ebc169,21155748,9fa93b88,3e5bea50,da005c53,68e21a0c,41bc83d9,145c13e1,370d26d0) +,S(bdc5237,82c75858,f5c50fc0,52e4c1e9,c74a2a63,35bca9bf,8d10e120,9add6a4d,abb1d9f8,74637668,e214efba,fbf529d3,12ff023b,c1d5723e,58540436,6834f189) +,S(44770a33,8bf0aab8,3bb64e47,6eb6167a,88156d16,8f13ce86,26ee0912,e59ad087,5b5930f1,2e9c40bc,b3393a89,5c2d6457,6a3abd23,b7291b99,c965c33d,ef60a55c) +,S(b15e7b32,2e404aee,319ac203,23e36672,6503108d,8ee8e1c8,3e32d924,515e1679,5246a819,bbfb291,5f82ed56,50796f50,5ced5c25,87347d57,a873ceaf,3d997e7a) +,S(a1ed7557,5225cd0,f2c50f75,8a1c1df9,665ae108,d5e04190,27bbd9ae,ddb00f22,3c83145d,ad9f8748,7b97e746,4850ed02,d71dbd04,93281a1,3d212776,6a791ee2) +,S(e8aaf361,6a1bc60f,d9bfc43c,2c60580f,479e9ec9,c23a37a2,3cf8afb3,1d918af5,6ce693b6,4a37c672,7e141041,ab9a0d58,9ab9c303,a5ac3d3e,c89b6f27,9e79827c) +,S(5dc6f8cd,2c855e63,52a4a4ef,6187a6d6,759c043,38a3db76,c5a3aa37,54c20a3,f602c342,8593a9a8,d671d1bc,7c1d8834,fe9f5f5,2e6a7f0f,bb870146,4e6f4838) +,S(63327311,67bed8af,68a063ef,22aa489c,f6563620,461af26a,5f1a07cb,6b42f3a6,b8f7c3b2,20701320,f20ca036,761d3e56,bf94a700,9a919f1a,3ea0cb81,b74424a6) +,S(8a40d925,9a393b38,2305c201,7e8654db,ad66e50a,d798a0d3,535230f9,48080263,afb6a74d,9849454e,dd7f703a,5c6616d1,43f9cbcc,9a9a5d6f,6a7b5d1f,9d9fcaff) +,S(e7147107,27c7420a,f517fd3f,9a05b7de,a6a02c8b,cc20b17d,cdfdeaf8,2078645a,da7d67cb,c1ede9d4,fedd5dcd,c96b04f9,a3561ba0,2581b055,eaa144eb,4217daca) +,S(6131291c,d95fb878,1e42a68,553952c2,9922bce8,91c026c0,cae1f69c,9661c82d,160e1c1c,13342fd4,59d4f989,8ae632b8,42b89479,13733b89,384fc104,2d30bf01) +,S(4bc4f845,b6764692,d0a9bfa8,1788809e,fc5e2aa9,da5003bf,b782bcf1,d1ca4951,87092dcb,b9c3d254,e3b055ff,3a76ec05,64c4a7c5,7fb1783c,efdc40fc,10b751f0) +,S(45a880a2,7bbee9df,29f9bff5,c985f364,52865b5d,582a201f,698e6eca,a2be67df,fe49a6a8,b5e46bf1,ef679714,dabd590e,a831d46b,8ee94eb6,13132ba3,7855fabb) +,S(6a826a38,317c0c86,64d6847a,220145d1,877e5495,b21500d3,f21f1a0d,4af4f2a4,4521954e,fcc98263,df2f14e0,e6e6b47a,f6b83f0b,bc20722c,15445f87,e05f4513) +,S(15356506,f255f7e9,6cc8aa1b,9dce572,8bd860de,7c6cc75f,613e8a34,366a23a9,cd15abbc,d744d485,d5e401f,1f89a5df,122f37b4,e362b4ce,e3e53b1c,110bf3) +,S(f3bc12ae,f53d9f5f,6b865178,2dac2ec,cacff3a5,cca6443a,2b5e1ca0,f2b89b91,cfd4d36b,eb2e11f2,41fd0f36,7a0737ad,303e915f,f247f131,368ca509,18e00957) +,S(7e3c8c6d,fa04a536,f7a26ef1,8b387649,22320bef,58453373,6f728297,335c0fd4,72ea16b5,32a7336d,3332400b,303c0236,b6a1294d,88ce7fe9,15571284,d1f7c189) +,S(198cbfcf,a0575fc2,c161c696,d85155fe,6943ab9b,d6e17223,d8844608,ad0369d8,d5e6268b,30952422,be59fe0e,fe7ba2e7,3215994,827a46c2,f2972b26,153cf7ae) +,S(1e056e89,b68cf35a,22183c08,9089b90d,5a147caa,780b1fd6,3aeb1350,afb0e5e8,b8241453,abc44c57,ddad6ff3,86d416f4,3e258a39,c6f8837,9f80472b,943f32b9) +,S(dc7ff974,8d827e7e,a6173b2f,1a646d47,d8108144,ce7f98fb,3fac729e,72faaa21,c1fdac5a,ef4c6f0f,fcb8e1c5,c4417c71,3e3d5f07,146daa1a,aaf2e7fe,e70c4914) +,S(71b95efc,c4981e07,5354bc1,1cdfbc48,36b2eff0,bf8f8ec2,9a99da1b,2fd28e79,fd5a3197,6fad6aee,c304752c,c3ebbc51,1f3695b0,9a737fa3,af42cc6,efd684cc) +,S(43854caf,29dc2bd6,c9f3e8ff,a25bba83,f6b96121,897044ae,6876883a,de542b3a,56365176,897632f,8dde3167,7a24f558,34c5c9a5,5c1cbf36,fd8b4480,3c9c6c81) +,S(2adfe17,90e9f9c,708c9b73,d5fd084,b6eff990,fb877961,45c2ecf2,d427b222,b5ce3160,5d6dd9c6,22cae425,ccd28912,c4439820,c06950cd,4c86d9b4,53abd7ed) +,S(a123452c,2b7eaf31,15b3a534,3b3ff31a,9f70c54,ae33c620,471e3e82,27a9d6f9,933d3483,78a71f44,3788194a,afc545e7,f53e37a6,f779f96e,8fa14ccd,ede3b4eb) +,S(9b89a3c2,ca995a81,86c15217,61348737,aab166ae,7decca60,3d06e32c,cec0a6ab,2a7d3701,a8724b12,bd7c4830,224ac083,cbea83d0,543b5414,80ba8c8a,e7731232) +,S(64dd7457,e7d9d739,8e2b9a0,dc45272b,384b0433,9ed8b2ed,c9079646,11e9e9b2,ea90f8aa,e214ee16,ed608a72,36699899,4e311dc7,780ef885,b29290c3,823c470e) +,S(59227431,be607c6b,d327fd71,4eb71c87,20abba42,1c7f550a,6b35767d,6fa2176c,cb7571c4,71c5527,65bd289e,a3cf3f38,796da2b1,2c953d0b,8705125c,4861d598) +,S(53d765cd,adb26e9e,1c80ddf1,99374363,843b7d08,a7237bdc,8c5106ef,795fe2c2,7bbbb198,eb39973b,76d87f81,94d45150,a66d4f3b,128a40be,c989a405,ad7c287b) +,S(e507de9e,c16b3bf3,523a989c,f5ff6c1,452ee90,9b66ffc1,6d7b519a,57bb66af,a2f2f02a,8272de6e,3dc8b395,8959ad2,51b6d3d0,4c81952,59a501e2,8ff7892a) +,S(16f48c6,eb84fb2,81903b8c,b9f60b7a,65601d76,e2a57983,5569c983,39b4a6f2,8613bb84,8398681d,66f1e75d,5b6ef44f,d827b629,f4956a4,41d8f503,dd32b289) +,S(650471ae,774265e3,270b5132,33d12d85,bb98e38,2a3b3af9,cab6339,e1446056,838e7793,34aa6fe6,cae90a62,d359c339,187b4032,15d97cda,4e62724a,a5a50306) +,S(15dea416,fa34584f,cc90e19d,69825fae,348d1ba1,fd7ac821,559aac2a,bc21dda8,1fcabf2,1e19ce68,ee12a3d2,84bd1304,10fa5f5,d45f9c15,d4070243,a8433047) +,S(b42b2495,4f1f70ed,3db90087,8357ba46,ee9d6a07,b4f7c751,dc5cba07,b05b46e2,e15723eb,e0bdbe6,d6f28d6d,a0443c63,4851f5b4,c551bec6,9f9196a0,969ed71) +,S(8e9e4f5,c6aeac31,1dab1125,dec9b460,6ab10b7e,8e250960,a17fc57f,c0230f83,ffb0e211,c79fbb79,78bd4e53,a05a267f,f1e32c34,d6287dee,64576d31,ab959ab2) +,S(87be7323,73bd4b73,8627fb63,bd4d50bf,d6f2bb81,f804b528,29549fe9,3fe1ac2e,f6a9186f,f147b9b5,ffc844b2,ec0e255a,1ae5537d,75624288,ce8421f8,7e94e1a4) +,S(43601d61,c8363874,85e9514a,b5c8924d,d2cfd466,af34ac95,2727e1,659d60f7,8791c000,7c09c94d,b328034b,88c5bbbc,11333536,6679eb09,9a5e75b5,83bc2c2a) +,S(341b1580,f83071c5,365f0bcb,ba66af96,6902e394,2a2560ac,a0daafa3,2ab49d0d,4b985b13,c5499026,7ff564d2,d4649c6f,7e8fdbe1,ba101d94,1c034e14,64877b20) +,S(175e7cb3,ce4a3a43,7c7181e2,c79fb154,33ac1aa8,e56492eb,57627171,f14dad95,31ce61a8,7834f52e,fcf8703f,93696f42,58130155,63ca5d9c,e92d8fc2,81135b0d) +,S(5ad430cc,64e61c61,e3b3c848,2ca3ecac,89c1e495,4c80ba98,249e45c1,307165ad,bea2a060,505c13bc,317ca083,c5a8b85c,9ead5f6e,1ac23fbe,ac7cecea,9251c791) +,S(41dce0d9,6dace318,988602df,7fa84c1,80f0ce3,dd7d09f2,8aefefa6,db8b837,74962c3f,ed9a6e9c,896635ea,855323b6,8850091,f84dee33,3cdff8d0,d2827928) +,S(a5ef4498,87104dda,103c1dc2,52067643,9aed2d5e,432fe5b,a23cc142,39961bcc,1cbcf83e,a363e0d9,3e6ecc32,8653ba7a,a165c526,765b09f0,696b0d61,f122db3a) +,S(4da26ece,9ad46003,38bdf68b,852a2cbe,18225f2e,2d6d5e62,6db57235,fb3a9d45,d10b5a63,7ab546bf,cc610e2d,1c3d61f4,61b0a806,e7ba29c7,3d3de909,e9fae659) +,S(6e621e6f,53d2408e,488d8eb1,6a19a4f7,e9d95585,11e69111,29dedc69,f98f4763,7b148ef2,73e1b131,341ad477,9342c7bc,7b945a2c,b52c448e,4bb5fd50,3cea1a19) +,S(ebaf5764,5bed7469,9b57ea75,8a395a90,66bae20a,8f082ab6,da4554d5,278be83b,5847f4e0,6c653033,5e29ea94,389ee3e6,d916314a,60126028,650ab9e0,bfcfbba7) +,S(c0f88a71,711b632d,24b55dbf,52b15d2,faa38ca1,1438c17a,6a6ff635,3310182f,2cbfad4d,16c07021,86611eec,408082fb,fb2e9898,141a5248,1c59e44e,cd0676ff) +,S(5d9b6c18,84b79498,c6244fbf,262922c6,dc1cddb7,3cf70ae0,1b5287b0,5b5c6350,328e831d,2f2b162c,4abe1644,bb54cc85,18db178c,5b6ae97e,5e85110c,7d7fdf1d) +,S(d1d1360f,37ed6e69,d4f214c6,323a53b7,e57d7595,55904016,654c49f0,4e02e21c,627eea93,c6c9b53f,94559414,40a8b100,6eba68d4,6c922b6a,1521f394,6dd15e4e) +,S(efc987cb,f1023af5,58acfa18,97b1b2b2,ace29a83,65674703,e4969ccb,ee411731,195a6a65,d3790bec,71642986,3bcef432,e38242fc,9f565dbb,e159bc42,f5740c69) +,S(f3026b97,163df3bd,61b88b78,73864480,968d1d7b,83ef6b01,31090faa,18284ff0,177c3a61,682363ab,bf281615,d59f06ff,5f87644c,84d670e9,a6c56ac1,b611509b) +,S(5d34ff5f,123b5b69,92ac92c6,8c9cff46,deeecf9,68ff830b,5622090d,682c5873,2d1a0b9c,8eaba065,43204df1,48eb1618,25443efa,80f8aff3,d49b6626,c5955ac8) +,S(cbf9ba17,94a95247,c39da065,84308cc8,e0ee591d,31a9b0bb,dac67280,468447f4,549b18c3,10feaea1,225fade,934112d3,4058101d,74f00538,1b82796a,d0461736) +,S(920975ba,9e2261b,bf5982a6,b57a7344,8e7747b8,368d7a53,79acacd4,c7dcd31f,e95e0508,81af550d,9221f5a,e9541031,6367d24b,d545bdcb,434e7638,acb46dbd) +,S(815b2ae4,6fdcb55d,926cdce8,2b4f25d0,39132312,3bc180ff,33fcf132,7eeca64,62f637c6,7d886374,8f1e2e26,865118b9,99285b87,55f25512,c968b4fe,49b8c971) +,S(1bb9a6c2,8e28d4ba,30ea8639,7a4d387e,27ca8025,da231926,de3c454,f7e0b16e,a0cbc016,5e32171c,8184265e,ac7e0147,206349d5,41035a94,f56efc49,dcd7ab93) +,S(6f0153fe,dffd83ea,b099d29d,dde278f1,9c05a4ba,78eb4c3d,34d337c6,da68bc22,a532d00d,35013f85,9f4041d3,aa231f2b,9fc49967,e0e2f82,4d5051f9,e7f0c626) +,S(3454f73b,3bee77a4,d00d384,71bf555a,ed23e5e6,c6dae855,2e9cb7a9,1b20258a,92c20846,cfdf1e8f,3fe5bcaa,6bdedc3,9926833a,3f40d28f,23a8f952,d8d18dde) +,S(367807c9,a3606b4e,1b8c2616,ad528030,1dfcf686,40eddf02,fc59317c,230e9a86,1f023f2f,a2bbece7,3dba14c,124095cb,fdc4f92f,281a14,8304a412,c16ecae6) +,S(8ec4fdc3,9891f6af,1374e06f,c44b815,1b82541,75fc4909,acba5941,201af62b,2dc6cae5,cac2d887,83dca0e5,3c798f8,fe067bcf,5fc29751,13756cf7,ef4e5f1b) +#endif +#if WINDOW_G > 10 +,S(5cc24a6d,4c5b24f9,14542f91,e5fa937f,ffa08551,51b8b842,8729b06a,9178a263,b1da8635,81531a1f,bfb38a4e,419fa1fe,ca8d55a8,3ddbcb98,da19d5cf,fb7da472) +,S(83905926,c03905c3,a9644a6c,da810dd2,92602a50,50c52a21,9134fc4d,e3599e9f,4293260f,e8af6792,a20b115e,aa837638,9094298b,21d9de16,cf20e0c5,7a46089a) +,S(944b097e,4721e9dd,f8204ac3,d3878fa,e8fa6c14,34ae4822,481b2985,6589b6c7,5fc47565,30e9b095,f8b79643,1e745b99,1525bd4c,4764e8e,e8af4b96,9bd6ddf6) +,S(ab0b4a3f,cfb7c134,e1caaf04,a63a7331,17327a1e,5fa90301,7b5ebbf,3423b73d,e1e79263,a5bbba8a,cd78c92c,faeccd3a,b84944d3,785c0781,3763bf1a,ce96c9da) +,S(57a344b5,220f2b0e,f7bf7fbf,5a2e4e7,1aa2c3d8,7bf090bc,f803dfee,fe8b85f,f82b7d0e,8ef9620,e48c9f13,53a72a95,a9e11a3c,1678cf10,576e639b,b1a7d04e) +,S(6e053e1a,800b7c4c,51f8c4c9,5cf0f4ff,3608e396,ec46188d,a1a9263f,c8d81ac5,86389e98,e3c823c9,e1b5384f,fce428c3,62e36579,7202fdba,dc3d8c49,395e7473) +,S(62d76406,1804717f,b30d4a7c,7567b545,48a289ec,7f083f1c,59deae25,ce485cb7,f1d6314b,661d1f8d,8531d57b,9470fb53,d1509b2d,a626a0fc,4cafc941,b668be84) +,S(e5db28f2,219fb2aa,830cf108,bd2449a,5c4d0800,82d34658,9e347f31,dd29250f,c296e646,32f97dd5,ba3b7012,ead44b6f,324fcfd2,f35f8b24,8e58fe68,888bd453) +,S(4725b3e9,a3d00de4,8a53177c,9fff831f,733ec89b,c2994ab2,3fe815f1,9b32729,ac3b7747,de38c00f,145fdb74,1482bb52,324127cd,2979ee12,d4a9e689,b9f8e778) +,S(d0d3afb6,492c72e7,394ed918,7013e347,b036b65e,a76e0569,bbe9e346,41d72b3e,2dd3a45b,94aafe07,53061caa,a28560,bd952b0b,2f63f13,96f42fb7,8e02fef3) +,S(7853e735,d717c857,97b85654,a24acff3,104143ed,cf4b4b4c,7869068f,c304632c,a873d9,e70fd14a,c2777a8f,b5a02922,bae3a31a,14938e69,cb535355,de1efadd) +,S(6db26b3,7d4fdc59,13a1a01a,14c92356,ee44e2c9,7f9d72ca,7789de33,8ee904a4,14fe2225,bf2ba0cc,28c1c409,e9849c4a,d8adf792,63869b68,54a28ae9,631941fb) +,S(b52f0869,bb98af3c,b2f7f5c,669fa43e,538e400f,63a9cce6,99aa2ef8,eb2848df,24566b24,55bc454a,e7b378cc,a0e57b6a,8b821c8c,a76fb858,bb616e17,8907be5a) +,S(8614dde1,1ee6af03,eb34a9e9,970fa7c3,234152c0,1384f7e4,c1e1f93a,197b448,2a1125a2,ac996870,2ba22b5a,d230c40e,4e5c7e55,d8ba6ba1,5e54d3cc,7b72f3cc) +,S(982a37ae,625f6e5b,78e71c18,f20bdd0,8b3308eb,59d0cab2,dbc20937,938c1cfa,671fe16f,a65128,591249e2,b5070bf,2a689e2b,dd6c57dc,18e5309a,b6a40d0c) +,S(6bea9305,26b4829c,ec99742f,c9231c00,627a09af,22ca9d9b,4081a2fd,4c3e703a,aec5402a,54517b4c,1f344d14,b1943e69,d7541f10,c45bd483,2b02b059,499a6cc1) +,S(b5724781,8694487e,7cc188b3,36d116b0,54016a99,20731920,ba7bd29,96583edb,5cbbd186,1f80a4bd,3d58262d,ebc58ffd,1d278fb3,b4d7fec6,208f6286,77845cdc) +,S(de1ade62,7ba00e91,786f4f53,18ac5392,4df5a534,704edbb6,2e0e9e2d,997c5412,7ef486c5,bf23bfb,fc6dc15a,41c0673f,a9d003e6,e1d09a8e,4bffee9d,ae2021e0) +,S(3738a57c,b1721c41,9f9e465d,fb80e1d7,33720398,bc01166d,d476d36f,3398c0a0,e1f25bb2,1662b16d,6d28a629,ad84385a,43df566c,52924bfd,11854a78,b70c22f5) +,S(4cae21c1,6b2a1239,a85575f1,2ddf6daa,1955feb8,b7502e37,6940006e,7a81885d,2affe855,388660d8,27671e89,c82832b2,25fa2c9b,29d559e2,37af565c,b4dc99c3) +,S(4c511a1f,ba8a0be3,6e37cf55,85bcc3a7,97bfa7ee,1baa6039,5732faf8,dcc2bd7b,ea69f794,5c6babff,23400fd4,a95d6833,abb27269,887c372d,8a6a45ca,b25651af) +,S(d811d8c4,323b4370,2607c25a,de936c0a,c2e4a44b,2ba51f83,20c5179e,745a7e29,6ff970a2,17bf47f8,da0aeab,cb490e3b,46c6df3f,69f9e93c,3c4dd94a,e7c05345) +,S(101eb5d3,b5e5aaff,e39bbafd,f13b5ffa,33db68ae,1fb09b0b,1cae25e6,16c43eee,9d6a5514,9867725a,607a1c96,eb03120c,a4970939,34e0cf4a,1631a63a,bac5ddb3) +,S(89eb1152,b8dde45f,e141f21f,62fead1,ecdc7f70,eff8f968,de21cf8b,72480519,f8a337c4,3181e3d5,69ec99d7,f2bc4770,cb6703a8,63fbd95b,41fdb07c,b697b447) +,S(53d633f3,f48ea44d,273d8f1e,455019a9,49d95eeb,68de70cd,bd1e964d,9ad0dc16,1b26ed76,964dcf1b,3f7fe6f3,2e6db7e6,8e8ff4ee,48fe63af,48ffd33b,cd1645fe) +,S(de106910,49891106,59a94d26,b9cedb64,6ce3db4b,8398ad1a,92f8f95f,d8d9be6a,87640b41,dbd99d16,578a3d06,d23d4088,8768a4e6,dcf83e7b,5b9d9133,5eb43d32) +,S(40ed1e6f,b9ee245,ac189a9a,7809da10,cc6daa7b,41a163ca,f761773c,6af5bea2,ffed1501,7298fb9a,78eb7bdf,1430ac04,82bae82e,a7197adb,50bcc1e1,fc217b2e) +,S(55faaaee,59a20b9a,3784d171,9ea529cc,1b7ab3a3,29f26dfa,a3b11bd6,67ba15c1,a9f8939b,52ac53e3,5ed4771d,8e47065c,d7f2805,a7e5475c,37353ddf,182f4a65) +,S(b51de64e,21cf88af,2180ca17,24956d10,a95ac607,f034fccb,a53bd02b,fa8af3fb,175d9b70,1c652ebf,46b99f1f,6e66c4a6,9b840019,a48b1ac4,878b386c,3b7f81e) +,S(5156b0dc,bcd91e82,4bb235be,9367cf40,7b8927e8,cd874171,556f997b,7b07b143,1d457c0f,a29d4c3f,e65ded19,1127016d,d40ada90,cbb0d8de,c2af4bf8,20cc91dc) +,S(3bf51d72,60b4973,161fac55,88e441a7,f1993c06,791b6bcd,e11d8e,96dd63d,7bc6b470,90a7afdb,fc63905d,df698499,73e1e4e2,af74f126,63eae8a4,f4722d49) +,S(d2971091,20088102,1154f4d3,ba6f2da1,22fa74c6,4faae05a,d76db7b0,9ad61fe5,7350ebaa,f2ccf3c8,f940cc14,151c23c2,bc33cb73,65528156,92648f6b,628e3fc8) +,S(c2ee47ca,8e17112f,a255a520,21ffd30b,6d7a3b7e,2341526c,559b60a9,c768013d,2e6e8b6b,d83b7f5b,1dc8e83b,edb3b23a,80d9ff08,2029831a,45305016,2bece448) +,S(559998d6,9ddcce0d,9e0da39e,96cc4c00,c5ef444b,561dbaaa,e475adbd,3e70b6cf,c49c2a00,95aeee5b,8deb5e8c,db4d21e4,cf0f3173,1af2fac5,25c534c2,34ffb328) +,S(4b4b02c3,e4c8badd,e45305c3,9721a98d,7c1955dd,90dcb2f9,e9d54901,6bbaf363,a0b67b7e,be8f59b3,c25d546e,3dc304d,d22a6a64,615bcfb9,25b685e3,18d43468) +,S(fbafe7fd,7836b427,51cf897c,5d42897c,7650ade8,ee1ed01f,e0d7dd2c,aac549c5,2f511943,52d07e51,7b7841f5,8eda5225,229a7e28,9a453aeb,5e70110e,12668436) +,S(ccd306f9,c65b8a0,7884e620,b73ac4e6,81b21bd0,2a4b219f,954de1b6,7076c06c,823fa47f,a7b0b50c,907056dc,73e04574,3f68a7,5a4c8566,8ab5f5b1,5657510b) +,S(bafbd838,995a691d,3b5a870a,7847452d,9124155d,d89a9980,820b8d56,18195a3b,8df4c9fa,c94829ee,fb0e7f52,1020b5b0,4f05f4d5,839c8687,4e893e7d,8ad92a3) +,S(d125cc3a,8073156e,a166af8,ff940a64,713d8f37,b86919fb,157cc380,224f458f,a030e8b6,ac4e37a7,df01054a,ea23a78e,1bb7a22e,f26052a3,a034ecbc,bc35abde) +,S(7d491f28,1b5ddaba,ef2c6433,be22e42d,f2d1bbfd,8a7e8866,8cbf278e,cb8187c2,ca18161d,70360966,ca381ea3,f760b2fe,28b040c7,ebc82af9,bea27ba6,f4dfe8ed) +,S(31ccda33,9f29123a,86c2995c,6a9f4979,6d70a595,5079b961,6015f07b,cdf8c39e,aeb27d0b,edf61fac,99528a9f,f060d1f2,376626b0,bc807a19,561c2e4f,e8b49f65) +,S(79e64c7,f45f9189,6c92073e,71b76fb1,e5ec912f,de11ba7,d7439f4a,297807ba,57d93436,b354963c,5891abe3,825d89b4,d17685bc,c9632e7e,fe85ded7,5823c921) +,S(d6232edf,fccb3868,71ef057b,60bda43f,69f422d2,debce06c,78a31f6a,8c42274e,13daefa0,b2e2e09d,36f472f2,29b5f7d1,58a18f63,ac3dc4d6,d62cc7d7,ec0ef826) +,S(21c0f298,b2d6e3a5,3738fc00,c8289458,722d78d2,48a33ea6,a7ebb667,446e368e,867553ec,17d2fd95,b895eede,15da569e,cbb3f25a,e5f334a2,b20660df,df062383) +,S(1d1a3d01,dcbf799,d551621c,54f74720,eaa2311c,3fd9b1d0,f4f2caee,4c3196c8,d5a7a115,9900f90c,879b1a30,13945d8c,5453bf1c,7e5e33d,6f8faeae,439734eb) +,S(57488680,8fa99ede,ca97d1,8582a151,62e26d5c,7753a561,4f4bb1dc,28e76735,debda859,7117ede0,dcc0ecc5,4ec1a494,b3bbee34,95db2b1e,ebaa1db9,2fc17c6f) +,S(b6dd34d3,4ce1dffa,4e1e820c,4c8bde9f,607194d3,1c1ce07c,9f6fadc8,9791715a,8bf48868,e405d533,2adc0ec9,49bc7cf,1487e554,3a043200,71786521,8a39cc9d) +,S(90f9ded5,69088772,ca2bc887,1522df9b,5821df6c,9e20b160,f3504bd,4a91d0de,d17e64a,dd534a6e,fdd0af26,b4494339,f76b3c1b,126397f9,a2beba76,eaf902ac) +,S(c55f34e8,58d19353,9106e4a0,c3002873,db07b239,9b10299d,260acc65,6b2cfa59,7d9f38d4,74b5a22e,72949f7f,e2cefb34,9a8fe1fb,c16b8dda,11f162de,30e50f5b) +,S(6ae44192,d38981c5,9b3f8452,c4a2b627,f39c16d2,b6f52575,c5f1722,56b8ecad,9bbba8dd,7c49204a,9edc4b91,e38e4973,fa61de1c,eda6ad61,603d9715,7f0b099d) +,S(33a7d639,423e1b36,6a93ad99,eab6444c,bd0c251f,6cd8b79a,e0344eef,6fdcffbc,c26112cc,6dca2a,fa52684f,c9ed22d3,2f067891,d5bac2c0,2bb86e3b,9411c61e) +,S(48471331,eac48670,28fa6642,a76ca6c5,3380c1d9,f52a4b2,ea640d47,f159af0a,b4ea8546,93fde01c,fb903a31,18bb61f5,c5047b94,705a714d,5b586d47,a0142704) +,S(565ac39,9ae731c0,4cffaab7,43d24b71,72defd79,beb8ce86,d46012a5,c2587917,deb56aa5,d45031ea,fc411fec,e09a9646,14664989,fd4f40d7,79c02981,98bbab48) +,S(964838b5,3b6c2b7d,6a8d017d,c5a32fc,99549094,6dcbf773,eaa7085c,98314c0b,2daf9f3c,ec44034f,c8a71ee0,ee76bd77,ac6fdc9e,fa042a2f,6caf9c5e,fd130b97) +,S(bc00da90,7b8d078b,9d83522d,ae548b14,6f9bff0d,2ef887c,4aae2f1e,c4eb88d5,6bd0fd11,f9e2db73,65f21dd1,34cb29f6,fef4d7f,b419abef,eafe15a4,20ddb152) +,S(1a59f855,f89f0c,f13dd8ae,9f5e550c,a2082bb3,27fb111d,75455ab,dba7bea4,7ea2fb40,d460adff,c9e25c53,a65c508,e77e6e76,e2e435c2,150c870a,7600c823) +,S(7a3b611b,d3bffc6a,d4508162,45695024,452706a3,279a6fda,d88598a5,4eccc764,16e09589,68066e52,c873d6ef,e549d3aa,83d30bd6,a1d730d3,68aa1ad2,32233145) +,S(2fed5577,9cbe0a5a,786fa95b,5c56e27a,a0a1cc28,51112bef,4cd5e1b7,15d6d91,7eeacc27,b2297fb5,63d691fa,36dc650a,f66fd3e6,6fe5e637,9959d46e,2d4bddfa) +,S(267ad217,952edf65,673efaea,6bebb44b,18326dd,f1b36d02,f0154a0d,774a9558,77593cc0,7e9d5e5e,688a7b33,bf54a01,703cc9b7,a0485e6d,907515bb,11a13fef) +,S(eb6ed62c,239b99c8,6978ccec,a5f32145,e0d341b,ca7eab10,6fa05ee1,7f6687e8,ad899e22,50f6a8e8,ce29b225,83ad8755,2a6e6ab8,9061d33b,6629fbfc,52c0a241) +,S(ca5cf17c,e03d214f,b4ef33c,41686c4f,5087a59b,f88ca7b1,891094d,430a9e5b,17e44eeb,473f75ba,cffae683,c8ea0299,e1935180,7257803e,f9963ad3,d0989ce9) +,S(4c7bc29c,acf0642e,63f035ec,a93e6b6c,c82f21cf,46623a2f,e4c7215e,51e82f7c,7c55e76e,8756796c,143f64e7,e40a402b,eb537be4,f1f5322,e59d2be2,82776875) +,S(57cab8e9,b42289f0,503e5013,acf4dd7,79783184,2389fd20,80b61bc3,671058e3,78225318,6671273d,a7b0b884,e72e9bee,2b048c45,9430d2ca,7c398aaa,9fd9e2bc) +,S(3c2bf23d,f1120c34,de813a82,a56843f5,abf3d272,ed2e6c27,53ff6310,9bc4823e,1759db63,88aed233,ce0c5b47,ec9dcb88,76740928,e12fe9d0,d08eb759,2d3f1990) +,S(c010a9ac,83e0742a,d3348dc,3dcfddd2,34170aa2,28d36856,d8581b1a,eab38d2,634c97ed,644a68f,e1f1da1f,190cf920,2b2dc810,446b78ea,9cd27684,3c76aafd) +,S(a4abd9ee,548ba468,e4cb632,b3d9c8a9,4f1b773f,ba3a9660,5504593a,92071994,3a14266a,ba263297,fc6ab00a,8403565d,c9390b48,ebffcb61,11b5e8ef,c8f87182) +,S(dc02c852,efc115f1,c5c08540,deceffe5,d68b82e5,99b78711,5a7a333d,e8dda172,e4e6593a,8e1ae842,ca7f4eae,d8cccaa2,8a35f8dc,cb8549ba,2367faf5,5f6c29c6) +,S(ee4769e8,223822ff,c28a5a4b,5f29fd7c,a54fc81,72175cac,1b6db5a2,91ec57c8,fca2c6bc,4076c8eb,a0978b9a,2b0158c4,33890514,28094619,38413fe6,c020385f) +,S(f3006c1d,34910c0f,d435a6de,cf088c38,2cf990cf,3124f2ab,b11d2727,d93ef066,7629f5,aa367f51,a29ebaf1,235cf267,f8016a6c,88dfcd9b,82d36904,c949eae2) +,S(7cfb203d,7bf5669,129f0a3e,325c3fd6,b1b9c804,4932f0f3,794b9357,1e7313b7,4f76b9fd,24339c38,c88c4217,387b016d,e4ae08fe,67182d39,82a45bb4,e82bc60f) +,S(cca3ce0,36e00993,9d30be8,e70455ad,efeabe71,83aeb206,a324d0eb,32312c0a,9674ae58,fe947c6d,34c63725,2058c88c,91b437dd,98da58b2,efd7e8d,1615b9e5) +,S(9fb64148,81cd5c27,82da071c,1f98d71,d9815fd2,2389d212,c66ace66,ab0d9c8,4c25454,1a513742,5f75e515,c04f1c73,d11d5047,9c76b09b,ce23c13e,d1813251) +,S(1dbbebf,3e3d459,10d39de2,32560b4d,eb5d2ad8,6aa1542,c2c070b6,51558b25,ec68e71c,2e94e490,4194753f,d7484ca1,940eae51,69831876,877b9ce7,2d0b9db1) +,S(7751d219,92f47421,7742856b,4c84d41,5a890ee9,24185e21,5a210a3f,a46bb5f7,2915a9c5,b770c86c,edd32749,3f698c17,6371f6a1,4cac5a22,73a3c648,1b237fef) +,S(39a849a0,5b189c3e,20782983,ecf664b1,e7b89c96,4e11d737,70797fca,ecf36a2d,d3e6f8f1,6191db06,be2274d1,56685895,48e69253,54f41114,f43b5ed1,13690c5) +,S(67e56125,b29ced20,f9f95522,d412d67c,80e3d628,b8bfddea,768117cb,e79b25bb,608dfc15,7e3c23f4,4aa0fd88,3d02d293,3c83edcf,66ea57f,9167b712,8d03da21) +,S(a51aeda,2f7d59d,d31eec20,e95839f6,ecdd01ef,529327bb,5cb229b7,b78f1525,704967df,93fb862b,3d38b18f,4c6818ab,6621c7d0,80d92cdd,1f0092c0,d7847903) +,S(c980693e,73a1cb46,f5eb71b7,73b00389,f8bcb36f,fb489e7a,aae64c23,6ac1745d,bf3b808e,fe6b7efb,771853e5,6fbba6e8,b3b21fef,706bd4,274cc058,b6fae474) +,S(c78df930,bcf54c1c,28e27aab,2975e9f3,94167bd2,948d4713,6b17a374,a1391a9,9a424f36,6d3a79be,55bb5e9a,283be1e0,163bfe22,1bc65e5e,318f0de,304d9ae7) +,S(9a75f7bc,c6d2f3a9,e6168ebc,8f7f1e50,a998b1e4,e67316e5,fb242fc4,6d284089,cb478e6,dff8b9aa,3ad06c6e,8fc7e35a,39bf6ec3,787977bf,d40f3159,bf169e01) +,S(76b2131a,db0bb3e7,db48277d,95ce73e4,7eba1e7c,b6f801c0,d20b71a3,8b6e6224,32e3cda,ef60e55b,a9e36e6,cd287737,196c5af8,120c47b2,f79d2492,9979263a) +,S(21898361,4ec5971d,f55f96c9,3da89483,cdcc4c46,deb8de68,f32a42b3,5c1384e1,2c396c50,44a4953a,b22a2d22,47769741,c5eda54a,d9c9ac97,d6486b5f,126dac3e) +,S(ac0b0a49,4e9d180d,101dbe1c,a528fecb,a08449a6,cf5d82a9,aa14f875,e3db8adc,26d1d412,25a1b583,2dd53b9c,56a6a8e8,371dd19f,31462dd9,b2aefe3e,70412554) +,S(f869b58c,851a65f,bd6d3329,75f596a2,9d1a78cd,bbf04a1b,6dca6c27,30e04625,40dee344,fc6f5c72,c18b1603,e149949c,a0cfb31b,b8b91b09,c3cbabb0,c6a5bff0) +,S(f74f02db,2406250f,8984a5f2,273c63ed,a640a43a,8e7d72aa,ecf78d6e,b9544c3a,882e3a6d,cacc1e92,8a3c1a61,85f2bcf1,5e364f7a,1eeeaaea,1c0af593,cf86185b) +,S(c0613eb6,1d6755eb,2ebc9284,a0aa69d2,88c39050,4b7e869f,f3d943aa,67ea65d,72f61ae5,27b5c82e,4afa8966,55d9289d,29931c1b,f0d36c09,fe4213c5,27848cba) +,S(eb66ff98,60ba08a6,3c0fd8c4,7117aeb0,ae0dbf63,524307a7,eb739f08,f31285db,c3142ca,54bcf2ae,8b05dfb9,4e40f4ba,7d3662f3,774e616,55c7515a,87ddc5d5) +,S(3a7108e6,a1256061,fc25d58b,ca534602,e41c6b15,156c15b8,71a516f0,ec4a861d,daae2d02,41cabb2,191b5be,c17e7e88,957bfcd7,66df1226,a183064e,3c4393a6) +,S(d17e3a58,c83169d1,33ee7371,7b205f2c,ea1a2ff3,4e744958,949e9403,b8f89d5f,98c35f7d,69e5d98b,920ffafa,6d15d349,2d75fcb9,81ca5022,5ac7ff32,618b1a20) +,S(d6e32892,cefbb8ed,14350cbf,2618e2fe,98caf6d4,f7679385,fff36bab,bf6541c,7175462e,be0f5ec0,7872b55,356f2498,976196bc,edbe021e,8081ebd,b2636298) +,S(318d49ff,60e900ae,6e8e2182,f38ec006,82ddc8ae,93aa6291,86d5ddf8,affef75,6e97ec27,dd7d614d,c1ed4fd8,fdf6aa70,8dcc3eb,be288831,a9888166,66333b2) +,S(fd6f9e30,1772db8b,a68ea5ae,b585abbd,c075e72b,68d6f67c,5a2f8144,98cf6346,dadd16e7,64775bd5,ca5c5f51,35843556,d7608230,aaff4125,4d4eab38,1d28d2c0) +,S(8fe25b38,a2c74761,a90ed08d,4bce768c,f074282a,e9560d31,566ae43a,182ddd36,6ee1e84a,77c6ab78,a2cda1b3,2fbdfe2e,51d66843,271d15c7,3f8e1a82,1e4c23a2) +,S(37cf0ed2,88ed8fef,4ae17bcf,f6bfb815,3e12bab2,a46d7e5d,2e6feb99,9793bef8,92e7a57,18eb0751,c99254f4,ddb5c278,e17a417b,21793339,119a146d,bbe3e0d3) +,S(688c2061,6b9d0c8,76deb812,b60000e8,eca0e04f,531ed1e0,9158442,7bf403c,bab4b2ba,41ba4d53,df512e76,32200bdc,11d8583,f2ceb5bd,a8b7eb14,5ccc01fe) +,S(4b4caaaa,f5399535,d822371d,63965216,d1b53584,d89a84e9,d868395a,70b3d804,3ddd27af,cd18049a,3b01d043,7761e4ea,652fbd91,115c470a,e4c7bd40,51ee73d2) +,S(6f5acbc4,4135da60,758ed9a5,18b39b5f,47cca398,24e20e56,1444dd52,e2fa1d2e,5dc9d46,e5f6d94d,48af2efc,2f197a2,f729f1d7,335fa569,524d37c,4acd58c4) +,S(79d2d449,3dffcb91,6fda527b,f8b6b622,661d6f23,738288c6,ce94313d,c267fc42,b2683bf1,3fa8f7fc,be302823,dfbc9153,8d902791,d5d6dde1,d2805f37,a0c08db) +,S(33a8e87e,246b7b9c,9c77a6b0,7cc67d41,f3915dbc,2180118,c0800b33,f9f95524,baa8244c,584fd05f,2655e36b,e2e5c459,207d30ef,dcdb2294,70b34333,9d16ff8f) +,S(9a169132,f3887df8,20561a7a,e4bd5461,3235ddb2,fba7a19,3f4daaba,79868e95,686fc317,995446c4,42945216,1a96595a,a233b100,e5f8bbc0,71990229,44630bcd) +,S(790b74f4,8405ce3f,9abdc7e9,439f2f5,c859989e,2ca5e6fc,29046104,8783ac42,8961c913,562385ca,990593a3,77111a5d,1dc6762b,b1a928a6,6ebb304b,8a24a701) +,S(e2a3d0cf,ae1fc2d9,87caaeb6,9f32fcd6,95471785,f524e438,b5487aa3,72f9e49c,9cc24205,ecf2708c,357edb54,308ce452,11f7dc03,98fb48db,4982d337,14c93046) +,S(cb30c43,5992c195,76d372b1,96f2ae68,cfd2653e,63e3ba7a,2b3c21ec,960bcbea,f65735b9,708338c9,acc9cba1,4b491b8a,fb683058,266a483d,4987cdd3,89ccd0b4) +,S(1faedc95,d6310bee,6298ffb1,6fb3e6a3,296ca66b,7c995d2d,fe924381,10e8b46a,35039e3f,8201e904,e5378d03,2bd8b766,26d9f0ce,4425d2ce,e7bbd24f,b8725089) +,S(a646cf5a,2be8c1d1,3f05410c,ed51b3f5,8e93ea53,1e28bf31,8f6c750b,52b3e8f9,58c58ecb,7727a920,b47a7e78,e1e51d11,e427d7e4,465429bd,a01f4650,a4c102bb) +,S(32734727,18537d38,e9b8c397,a5cc322d,1c77c0c6,15eded39,dcebc020,debe2205,c2debc89,58c3f60b,d4c7b072,d475a7d5,c1ea784b,c3e532bb,72c02490,9a42d65) +,S(16a1a718,855a212,c068c095,d930a270,9906dd22,e7db3f4d,4ce2f393,d572827e,d389d64b,b30ba9eb,6ce80335,cbe8f7dd,b1ef3016,a8b74660,2196b724,d115605c) +,S(b4bf4d14,5de25571,33694b86,76166e90,eeb1ebf8,4a7402e9,a61af4cf,23687596,49db20a4,d82397e5,6318640a,6b605e96,37d38961,a58ae3db,fac2fc11,bbd11242) +,S(d4ed67a9,ccf4665e,418a0de0,8d9380cb,fc311413,e90a964b,bf367b9b,b892630,8ff7e57c,e79a0883,1fe8a972,92493764,7472b77,61b055fa,37105d18,b51df131) +,S(8ad256f1,9f413ef2,eae906f,c1c2ca4,44d5dfdc,f916d366,b32f1f47,f54fe70d,bdeeeb41,8d2c4dc5,82547f65,91c97219,34778f5e,d25eff4,94e243ed,a6d34da7) +,S(8dd3e2fa,fe55b5f1,f13723e0,1a5587b9,c67d22ee,21f1f62f,7f62a15,31f17f8e,aa23d2a4,7d6b717e,55d7c6b6,5d9c46c6,8f2db41c,ba66960b,4b4bf93f,5fc88cb0) +,S(44fd9e28,2a8e30af,ac34db01,a7b0e939,3c13917,554d9a67,8e577a5d,4b3d0f6,cb079061,353319b3,a1669d59,295bdbe2,18927d06,ccb1290e,4840cc16,911a61d0) +,S(5d249a02,4464ed65,831d2aa9,c9645f46,2db7c9f4,e5a46477,746b1a71,88b7aa42,2bff7386,527d6b5c,2c595f80,e08b4d20,23bb8dfb,f294da12,b54f8b14,77281d0) +,S(d98eb458,1edcd51d,465e123c,d891c481,ddd18b54,b9408ca,85ac47c8,e10fb23,15bfd3be,d3756ac6,f2f1f9e6,f254c9b,2b153717,1b265081,6a2cc21b,78b4dcf2) +,S(2f12c369,19a2aeb6,2132134d,2e85150f,6edb486e,9d672eb5,876804d6,44db6082,c0111edd,3b4d28c4,edd264b8,dc2bd0e3,20834dc7,bda82dd0,827133c5,7f8cf73b) +,S(4d949684,7099c9f8,421d35df,ebce57aa,71326034,8f07e3e6,f03017c3,144b4624,9afb5a57,d71369c7,28db308f,b8b07da0,b91f954d,b182eadb,126b1fff,ddb673da) +,S(cf1db910,5e95f1c8,e360b39a,752ab17e,fca8f24,d9ddc8b2,a9768700,e2af2466,e7c99f66,c49c8674,a6c1b94b,4b964019,5e645ca7,b3d2e004,ad8dc73,f647ca5f) +,S(e71eb425,7d2ffa8a,b79d63a2,42c67585,d4b1747f,5b27f22,a9ee4284,6aa62b85,a906aeec,f901a376,7d721f45,da53e342,3bc0a779,870e33c3,d10f6426,6a2c8865) +,S(bcd987d3,b2575f4,3bc5c3e1,b4a299bf,21c58b6c,a27ebb21,8f9882ab,30559887,403804c9,4339ae27,2bafd894,e63a4eb4,690c1b4c,9289db00,761e9b3a,1d483f65) +,S(b74d5cf7,48af7162,395d2d5e,8a69f740,7a2bebba,69564042,ea9c7e34,b1f8cab0,b5c5fddb,332bfb59,835e9a23,4afa4543,5728dfaa,7dcfca3e,a3c57deb,e849b336) +,S(46f3def5,9835c9ae,1a7b3b13,a920bea9,e9bc12ee,633b3edc,57251b72,3560837d,587b2e1f,2e8eb9cb,37aa6977,870214ec,818fb71c,1035eeca,91d53e68,150ce67b) +,S(8d3418fd,eb3f0968,de51f4d7,cbb60299,a50ceba4,1915d8b6,5774cfb7,7667d572,cee79910,16a28462,aa9da7c0,f67b4c7,e8b3dd38,f4b2203,9d05115a,ac661db8) +,S(98cb0f09,4510695d,78a0a672,eb67253a,30f4327b,7864fbcf,529cf212,ad6f7c10,25952dac,4e1b5035,9b47e9b5,52852d1f,300fde75,a6bd532f,9fd56af,2a0ab333) +,S(96045e4c,ca075fc,4a5383f3,f03de105,a34c7c4c,b030ceff,b58b98e1,2b39a3cf,f527b8fd,92234151,ba11f24f,7bd5dfed,6ebd03e3,a5048c6e,8f2d5231,7201bafe) +,S(f262e891,42addef8,cba26a9c,ad779761,c3f4b3e5,5990a93e,703bf56a,99cc6030,275cc764,86c86a90,f597dd6,7092ecff,5382c7b7,33939ca1,d1f3218d,6f0b594b) +,S(cd79c02,ee175336,5f9f7900,be51bb2b,ad75ef81,3c6c5634,7cc717db,156d17fe,b5ebe8ff,b30de5bd,a5326044,16abbae1,4ff9198e,b491794a,c4500031,947a985d) +,S(28b4bf22,5b1d40dd,e0122e03,e630830a,d9ba4629,cc51c9d2,80a225f9,48f858f4,24756189,98bb414d,4a534c6b,e300297b,aadf4ffc,b10e6795,4ea36e25,2cf3cac0) +,S(f018f206,7dd55df3,9c53344b,c6128a5f,cc765c36,c7b0bea0,16c8465c,c6ed2ff7,d9fc5ab2,cd619d4a,c66c1cd2,251504cc,cda34a76,86c5661a,960a00f8,e4aa7e66) +,S(496968cf,8086d02,9a5dd5c7,4f47cbda,7f661ef1,488b3942,18ed886c,424a7a13,d7d8df98,442060e0,f17a363,579c6600,360b5124,2774e2df,c8d4b787,1e1874e7) +,S(242d4c59,e9113b77,68e48574,93600da7,b984355c,a1d07949,8921016b,22efedab,470dcfd7,b0c8c2ed,63a28074,a505573b,42f50920,6b0ae577,27a8b796,7a0f42b1) +,S(b6b804cc,1a1a59d3,84c4afac,c5e5050f,466280bc,d5ab1586,1d20f4dd,1385e8c7,2f789346,2a636a9,9ba2a1d2,32829f41,39b57967,bb26d0c,898798bb,6521d439) +,S(dc30a3d0,7ecc5fdd,38b8048a,f281024b,46904b2d,2a4c51ca,d1b49b7,1d918a4e,326409b0,70550e97,58f53698,7936a54a,b701f7b6,78a7d10f,ebb511a6,c18cc917) +,S(e1fe434d,345bf330,83abb628,f4f44ac,5fb22934,977813c2,c015f2b,43d3fab8,1b251ca5,2af897ac,4c08df48,ce3d1607,d3b31b2c,2dcd7f7a,59a95b07,774c4d83) +,S(a8ed88da,e08ac5e2,afbe4a40,ee775645,82c2f513,cfd72060,bd1fd5d1,76fb8d08,f4fb60b0,74419630,fbaf5b53,717b2a6f,5cc2d98f,1d29481b,77b1f9f3,84175729) +,S(b52cf828,de1e9cd7,c95c083e,ec50d228,8e770713,a0e2543f,76fa5790,2c7c6481,635a3953,46fbbf,903dc729,d3e3b52b,43eebdc5,3748ed83,3c95eaf7,1b75790f) +,S(702079ae,f76d9bfd,ccb957a9,4aad93fc,b1297c54,d634978e,4dc78292,161d5e83,4983c08b,f2d81c52,d3b3a202,e0c6ddb9,32a43a45,c4b95f82,c8c10642,5a783b52) +,S(4638d4d1,8e9de1ce,ef4fe8cb,db4378e2,3ed3dcb9,513cc9a0,dd73ee2e,be57bbf5,561ee032,45cc3066,968853f7,51fa36be,cb50740,a5951e87,cf77ef20,cb27e110) +,S(eeb34eb7,5facadde,d561dc5e,e3d0a039,d98e4880,910439cb,ecfb22d9,3b386bfc,f2b23cff,5ebdc8c,558db8c,1c311a94,e9d8f63a,d1cf4af4,c21c2349,a6e57c4c) +,S(7f2c6e5,becf3213,c1d07df0,cfbe8e39,f70a8c64,3df7575e,5c56859e,c52c45ca,950499c0,19719dae,fda0424,8d851e52,cf9d66ee,b211d89a,77be40de,22b6c89d) +,S(6ec76722,1ec5d27c,f7e11064,d4f8b016,3cea090f,6a950f81,85623303,23e53647,9b03c757,9704e839,c8eec7d0,f063c4fd,d0aa7ba0,5ad75254,984b1703,ae69a3d6) +,S(98f6f69d,320d5eca,1f184b0,378f67cd,b44a707a,c5b2af54,99e9f8a4,524dea7e,26ef6b3d,7b037663,979333fe,56bc33a,ca54a3dd,78c9244d,79ef5426,f2b69a02) +,S(cf1ef445,58b82c76,5d77ac99,8c0170c9,2d308668,2d9ed7af,2961cf05,5b47e390,8bcc1d05,fb880ec7,8762d8f3,f5afefe8,f4345bd8,36397d23,befdf446,498511c3) +,S(10e01651,efa26f2e,f88cc5c1,594f378,9ab62b82,5a0875aa,37c280a1,8c6f07e8,2e6a15e1,1f776335,30fb2cdb,788aaa98,83105da3,7e28c0a,8fad503e,b9779df2) +,S(b94e2fe0,41ce209b,6efd77d7,44983130,af90945,120b9a58,5427966,e93eee4a,8f7abf1,103e92f5,5dcb1dde,746df10d,a86bfb8d,2776a0f0,1d07142d,c9bca443) +,S(cf9e7d02,c671a9ea,145d233e,244d8af6,6d71cc34,e17f2ccc,1225d2b3,16d41154,82eeb8a1,f0b966f,bbc3858a,3878f969,a853e2bb,e1b60c4e,e13eff85,d2d2ca7) +,S(da3a3c29,94ad3b91,319d18eb,dcf4b934,df8e4f2b,e052f436,6d539aff,4bd48bb2,28f9d653,c4042478,831ccfe7,bec86663,5e0d32ed,f6db4f54,25669a91,d1dc0193) +,S(ab812818,2b80378b,d914c9fc,d2831f30,a0a095c9,d0e52450,d4ba27b0,f1eec101,5abc582,274876d6,3dce366a,fbb1d80a,2286dc2a,dc0c078f,1424d45e,26666b3) +,S(ea5b82a2,bf02caa5,d5d64391,c0965c53,f0edd967,f8df94ab,831408f7,e5c4977a,81fe8299,f320837,acddd504,7b888e6,2518d53e,897dacac,5d28bce8,ff3d9339) +,S(50605c0b,ab201d7d,3dd618b,e3da2d29,318aeac1,7df58d2c,a95b8fbc,fbe70fa2,e50b1e,7b5693,c4ecc160,d928cd6e,d4c978fc,6c2a68af,c03f397d,72a60383) +,S(f76c50b6,6d7dcace,f45409d8,854f79b6,51356661,108b7168,31b58b25,ea1191dd,7d055b74,b0195140,bc0e2e93,a97f07b3,a3040148,7720df86,d3bd1810,6df3cc72) +,S(de5053ba,d716047c,cc2367db,272e4e11,41312690,2bd79b32,f6d3d959,93260e7d,1c54a2d3,9c34b0db,deb61b5,b5f46033,b1e4c581,5113bf3,d3f38de1,c97cc7e2) +,S(ad3e719f,180e946b,1b98a332,bde18e54,437f1a24,949d712,1aff7c8d,fa06499d,b458d7f1,390fa4d7,d2473863,abedc063,ef310adf,7ca2f2c8,82bcad3e,2f1b554) +,S(270a0234,5560af6b,6310c867,332f8b79,839a3ae7,6e2666ec,b46c840c,c36bae4b,8daab84b,92157d16,ca0f160,99877a1,ef7ef072,1bdb5bc6,89d16a19,4ebedeaf) +,S(eb5ed17e,3027c9c4,c87ffdb2,94a84ff7,25ba2b5b,2bf72d30,f98334ee,68624621,39fffcb3,8f74d471,9be8d1a2,14c61ad3,df4a91bf,d599c3ae,3b54b4ec,860a942) +,S(b9c11df2,8a0b98cc,623f4e80,75acd469,fb1f6621,a7572d6a,7bac135c,2ce0a5dd,5bfa8a78,d42b95ef,327eb0c3,692b3ba9,5eb506a2,4e2fca1e,391ec545,40a76278) +,S(eed17043,80abe259,fe661106,6eda0408,f60f1399,3c49a21c,a8a6310c,ebe74b5c,6dcb6276,cbe37b91,162a243f,57afcd9a,8cc2c661,652c324a,567d5db7,22a0d750) +,S(8e4b0f6f,5f5b9cf4,68e5524a,4adf62b6,8c68e310,5ee374c2,5265000c,53aa97a7,d1f880ae,c18d0191,b74578c1,6d0418f6,c7e59f2d,157c0d56,e25137ec,c1b7f74a) +,S(77ae21bd,fc6596b9,ae85ce9c,93112b1d,a7f393da,1238d76e,90cf59c8,caa5ebbe,f4484581,1e3266cd,f4625390,e729154f,51694717,3206ef9b,9106c547,ff4a21d1) +,S(1d379ca8,71c02ef4,59a8bd35,f5066265,92922533,f0503999,e16d6b07,dbd2346f,c0550b9a,72899a7b,42197cfe,d195c704,a6333d5e,178d91c1,d50b772,4140cad0) +,S(625017f3,28fc16ae,99367199,5f02772a,5c7ea721,7d47c296,cbad670c,3fef1ccc,1b44e253,af3b214f,edbeb4ac,50110df6,d7056d06,617c2bf3,6189a74d,64450603) +,S(c7a4fe49,6bdc3509,3ae3f508,d43877e8,d1019d16,740a5eb7,8eaa72b8,638412d,1b5b12a8,95fb7130,e8792406,74b8f735,6730938b,675996fb,a30a9744,960febef) +,S(cff9f83c,e8f9c4ef,3e80102c,bc48c409,b65c6166,b74f052f,a5628348,b2441d3f,4cc418f8,2180207e,fc846a41,ed6973f2,814ceb07,a8bd252e,338e32cd,e352ee6f) +,S(84027710,45b8c295,c938ae98,a9ea11dc,2fd23ae5,7ade6ef8,2c604721,66700541,72946592,d3c11404,881b972c,eba81d4f,f3f80dcd,40b15da5,f56e0723,841e4f99) +,S(f7ab1330,e00cb9ec,61a346b,d8f5522d,5e304a4e,a94f84af,b5c70614,d2e0d2c,5d4ac851,89350a54,af58def4,6f3f3d69,2ef0f6a3,9dd4ef86,6bb1101b,df5e6144) +,S(a7c84e19,2303b778,8c1a4d5b,786c9829,d0da4ddc,c13f692c,7851884c,6fd4e618,56e32e5b,8fc2db2f,21d64bad,35e3f115,65928533,a829d744,939ba456,bb1774fe) +,S(b8b0c884,a680dac0,363bc55a,fa677a72,c65f4139,7f5cdcc,f199d80d,ac98c43a,43e4188a,c92606c1,cd6bec5b,a4edb045,6569f87a,625db932,d0f8e71e,516b8127) +,S(816ec443,d0576135,5a3bc33c,1db4a179,c5bef98e,943af8dd,ac250482,a65e0df6,89a7b2c9,e9f3588d,990f6fa1,96e366b6,54f9a30,1218a2a9,c9b87c48,55f0b360) +,S(8ded2103,823d07d5,33fba24f,7fccc47c,b101960f,3b717fd2,af39d49a,a91e28a0,3f03ed1f,be1a661e,f43ef9f7,d753eaad,e3e1a391,2a682ad4,fb19526c,c0011728) +,S(b1c4b39c,e874d478,bfbdf9e3,ce8c3165,ff4f7c4,bee20c87,4849aeaa,d0d6260b,38af8b61,30701881,fbbfe724,5396adc9,32c25b84,dfbc4dbd,a54bd236,c04b4fde) +,S(7d5bce3b,e5953eb3,a17f657c,fabc8209,f011bcf2,7e10b90d,e75dad9,fab2c971,7380d686,5f5fd782,b0708b3b,62c39e49,864b2ba7,4066167c,bbcede2a,b0f84787) +,S(2af5111a,422af2cd,14e7717f,bc7171c4,96af178,8b229497,a54d2b87,4c00f285,4468bf1b,ee43f100,7e800b68,b7b3b243,2f3445c5,c8aca59f,7534beae,bb771f41) +,S(b46e29c0,6dc8ddef,f8bdfb65,f4043b61,fe010dae,a2d0955d,c81a7b49,637af766,62777495,ae16314f,d7d0cef8,24a27a9f,748c5c9b,9c51645,9c1ec9dd,9d7b59f5) +,S(105786d3,f44ea40f,71eb3bd5,339cd514,aef6d8fa,5923b4a5,89b219c,fba6b1ea,2a4ea7da,c87522cb,7d92c450,8e86d0b9,39fad024,9fc2cf15,1ba005cd,b743d0bc) +,S(1f3c0c81,be856e30,18934573,892ceb22,d2d2d8ef,f08b7857,5c624f48,16adb23f,7321690,de24499c,f52f4840,89c4d7b4,11158d52,d32731c9,faaea567,8bf6072b) +,S(16dcbae3,a95a95fa,912484f,f833ba0e,e437876b,f16f9c9f,5abf46aa,468bd2b3,56727c07,247b12d6,c1ade473,3c691700,30e5582a,cde14034,3449f241,59ffa44d) +,S(114be56c,d6723c8f,924ff3c0,f5edabc6,e42314a6,49edbfff,1c794438,dae70726,984dd72,855cdeae,7c580046,b32cfa7a,45b61b75,944735e1,d5fd9065,268ac521) +,S(8d0cb2e6,1f98472,e169dbac,7f5babff,51766b3a,8d74e17d,747b7eac,d903fdaf,d1593bf5,b9e793f7,25cea368,2ceabb11,f06b36ab,899e160a,f1f736a,80bc9b92) +,S(5b420754,188c82e4,db72f3a2,c8049691,34e3b43e,484b45ca,ab4727f5,31714db3,4a89307d,27d7f360,7acd1643,719be148,1c7eed5c,77598883,8bf6cc13,a4723d9f) +,S(91e3761d,95761d96,8d856a72,800fe0b5,9f01c62e,1cc446ed,18c1b58f,88cbf74b,b5ab61e3,96f88376,28f3389e,9999ef55,b73a58c0,d33debc7,25812530,2b96c772) +,S(31380b83,dc77e5f2,9c2f5548,abe052a,16e0f1f,2d8aad3,5b05d29c,5c1a4655,23ccafae,cc84ea72,3c434342,b839cd0a,b42173bc,1aa1db20,1073fe26,6593403d) +,S(ae40198c,bcd54264,904b44c7,c9019553,8f3f3727,a0c9639a,764cda80,b21edd27,3a57f08,ffecccfc,cd9a0e7c,827d98a2,ffceea9a,6c39d200,5cfae623,34eeba8f) +,S(f4729787,abeac0f1,249b1d3a,c19bb025,5764a854,727b415f,73e24c88,a8a981c8,e31161a5,68d81328,c7f9783f,de146d07,b51aae15,bfe719d,ab4e9e,ae65d172) +,S(f92f02b8,34148934,f7059b61,7e84d0a6,f52d3b8c,a7d7b69,ce4c8175,7ed5884a,faed7ef8,82733020,888eb530,5c6dea4b,cacd208f,fbb66b7,6f3cf41,a8864080) +,S(a2bed8aa,e93bd682,be8cc4d,d1f84fc2,9efe4022,b2b0dec4,9ed3ce17,7cc93363,287ab9c9,62126fb7,e0340f29,9edeb89e,7bf235b3,b3f08213,d630c9df,198ada1d) +,S(5a42cfcd,3d1811d1,99b09dc8,9308134,cf6219e2,e029598e,899418f9,b7af4724,95ce721c,39929d76,b0ea83b1,80bf25c2,e301413d,60fb8717,2e0ee8f0,593f8423) +,S(1d27ab05,67e8bf19,323f1eca,44175085,2e768a6b,a1436789,40ba2b94,5b0e530f,18439939,496d29a1,58a532be,76b04932,a23e3ddd,d51a1b07,c6c33e6a,11e1afa8) +,S(592bf859,22c05bf4,4b42fcf6,e4cdf3fd,bbbf8088,b7263d31,9bc74914,6eab4326,84cbd8c3,8dccf0ef,de3946f3,ba2eac25,3aaab976,8f7f601e,7d95bc74,4c7f65) +,S(66730a70,5ae3dab8,bfc01f4a,deeadc41,d4df156,d03c4fcf,1dd9e16f,9359d5,c04c7cc4,4ea1d8b2,273b9170,19b9efb3,6e8f422c,4863f718,582f57a0,778273ee) +,S(3d002600,532420ac,9fb246d,84e48560,1ce6897b,979491ae,7c5914e,dbb7fe83,5bd73264,2f16d4e7,7bcc4855,72494523,c221fa1d,321c552a,53241dd7,94c7d98e) +,S(d42ae36,2b5dd22f,d2089d37,d22e2c2a,750395ad,710aa1c0,61ed4275,43a24487,84439e00,1571e1ea,53bcc24b,a11b6f7c,ded0a649,b2a12fc9,c2a618fe,cb39ada7) +,S(37c761ca,486fabfd,b306d,c18e9074,409e101e,5bdd1670,edef1253,aa253743,e53840e3,1110db1,89ec241a,e7b2cb89,29669da9,5c07f3d0,6277f667,b90cad12) +,S(4e672ef8,bbafbc8e,eb819f37,15ac0d6c,2afa9781,a197345b,2889ed0a,f3b0e788,9c10f0db,bb16d807,4680133f,e62e0eab,130cb0b9,51937852,4afcf4c,38814061) +,S(c1f2943b,23c07929,e9c635ae,66f62949,8e1df12,f35aba68,ed8791d6,8fd51fec,3376b6c8,93ad5ec5,991f7ef9,6a6b1105,2f2262c6,680045fd,fc4d4bfe,ea64ae75) +,S(3df2461e,739cd984,72cf10cd,f663e651,351e826d,7afdcffc,e17602ae,c0370be6,5e48fcb3,3ed9c0ec,3594eeb0,81adaaa,bd5ec5a5,7eeaf01f,c9f00d02,c692cb06) +,S(d4d3d528,f98b92d5,f4c4ecfb,ab60fd85,50f12327,5b63b3fd,5518c1f3,d62a82b7,64496d50,85435de6,991a838e,d984bc09,2554053b,54b05a2e,490d2ce,da7d5b76) +,S(ecd8399b,4aa3368f,1a7a4113,63ff03a7,ad644847,e225108,b3ee7d02,1209236b,2e1209fb,a7921c29,e351e61,73c02cb5,c629d88f,4ca51af,30f37123,75355213) +,S(d5990be5,7e6a0da9,333354a,fb344d59,416d1a70,785cdae3,8c332e09,cdf78722,b2a2cd8b,73f76f3d,1079198d,34441008,278f73c8,93979ece,eefc5911,7ba17814) +,S(7598ab65,1d8ced00,af3d5978,661d801e,b57e9089,287bd74f,85ef042a,90374b1b,589fc426,9466b1ff,b9c0cbd4,b022e9ee,7edaae87,8f4cc240,b60db60d,6c28f04f) +,S(fd071417,b12d2d31,852048b7,61c5301b,be088cfd,98ebce7d,7e0922cf,41f694e7,2d9c53f1,ee63b93,2adf679d,96b548d8,d47d8f74,58ef8b45,9664da23,be32c363) +,S(5a5b4990,e290868a,d1d571ac,8e9347f2,b1e513bf,cbc2b8d1,5e56ce01,2b72ca0e,c76852f5,7159524,541569f6,3c4c9c7d,424285e7,e83145d5,e5161998,efebf968) +,S(93deec24,3cd4f146,42f5a415,f6ea6f36,25c90081,5f3d20f5,9728c056,fde7f2bd,88f919be,b9993a16,61f78145,f54149f4,6abfa859,1907736d,d5e85f25,bf2dc7cb) +,S(9224d17b,a65ad967,969104c9,3068d439,9c9bec7e,7613a602,f5c9917e,46df82b6,346c98e3,2bc2a4e8,c7689e54,eeb1064c,1b5691fb,cf5a4710,55cefbcf,18a32f65) +,S(851acc91,24ddff9c,14cf054b,87347a71,cfc91637,6e559189,f055143,3b79c38e,d959bdf0,58d21cc3,430527e8,cc49dc56,2dd20bf1,30f0e13a,55cc69cc,1e116f35) +,S(ff6c1303,b7c111c5,87e01ef,44829510,eff0a612,931f9212,2b71075f,2cea4d96,24f09bbf,7bcf50aa,ca239be,b925505e,7e99d0ff,5a959574,5370eea1,7b4841f6) +,S(f23bd9f0,55e7bd1d,433fb51e,c8b6ecb6,fd5014f,4f4ca9d0,6a4bc636,435fdac0,9652b458,9d269ad9,68ee7012,aee47447,25ba917d,f120bda6,9d2194ee,a56d7b60) +,S(9d622c56,ea6d5d19,7b823e60,1bbd4af0,1fe070f9,391bb564,2a05527a,49f46ff7,8061bb94,d6485fe,d9fbd557,66db3dca,c648c7c4,2e025494,e6c3a91c,fd5c609e) +,S(9494efe4,cff5d5e7,6394b67c,407b9961,2915afde,56933b80,370d0adf,2f020c13,ab0c7e38,c85ee1cc,27964b2,de42372f,fd86ecb8,fd3f0a81,84f5af38,58a7e4ea) +,S(a8e4d7ba,ffbc52fc,a8cb6c,2938a01c,e028c259,97403268,dbe1600a,952e1a86,8d5b83d,dc3022c,4f79723,c6f16722,cc7eeeb9,c964496f,c9f67c29,351a0bed) +,S(83841f64,938e460f,eff191ad,4d72d7a5,203c01af,1519cdf1,f17c3bb5,e4927ac5,f5868f2,c2e87249,21373397,40415c4a,ecb1f30d,b204fe41,80e01d79,eb536800) +,S(ee8974d9,5ef03f8a,860dcba6,7b597fb2,af2a2df6,950aeacb,d623c883,20612f6,5cf10d74,3085dd7,cc695145,3f9f763d,6596abfa,eb7cf216,34ee07f8,a4f141ac) +,S(68e88d8c,23616ca3,b136e5fa,3427628d,a92dde6b,2691d857,b2d01a60,b6579606,5a9090,3766d6eb,c58c5d60,9b6a5675,e5ec7b73,86a17c41,2574d179,a0fd5450) +,S(fe34dd8a,c62ec8b6,20dbea79,44ccca40,cfe6ab5a,ce3b2e7c,50ac589a,9522345b,88cf0055,adf1e122,535611d7,bd3e00a7,30c9edd5,898d25bf,f0abb9bf,6bd6c8c0) +,S(423a7a9c,c0f81489,aaa62479,c1317368,9989366,fd18bff7,f6a5f235,8251bc1f,c926b3dd,519241d,2e776ea,16112e41,259ce896,472ce71f,de4261bd,29c678ee) +,S(7fa60bf9,7cbf54ff,e61bb840,b2e08d91,ffb0eb4,727c0e73,ed4f157,ad0b98f4,d5b1aadf,84d387b8,fddc7b26,a7f736a6,7e296fed,7978e81f,6e7b3b09,e94d733) +,S(9e53cb0e,f1eddebc,77edf8a6,6917f915,8294815d,eef898c,f1e77433,60153a66,5358daf2,60fea2a1,b9a4c6f1,b8bebe09,4983499c,fe5577a2,ed8f817f,46b41ccf) +,S(adf93641,c616c677,99b44ad5,354332c0,1404718e,8ec91e96,31e69552,3ad6f119,da3c66af,e4cfb3df,f55f6761,5c6ac42a,8dc17241,5ad38619,dfe2a13b,7e42ff9e) +,S(701e3ec,485db367,b0687ddb,2be15f4b,5b6242c4,396f6f0c,9726ecb6,474e4ca8,1098fa76,13dce1c5,29f7fea,30740377,691aa3cf,3d13cf94,6f2d8191,2d3b9e83) +,S(d8fc5ba5,d3ecaa05,9e9a7e04,2c52500a,d513645e,6149e84,aac0d910,f8ccfefc,72724b4d,eec94da,7494b4d9,83a2df06,df96ee83,e578d920,c2597089,7b4b3d8a) +,S(7bc88f9a,8279ffb7,658a186,faaa5f0c,c900cb9d,4a33b8dc,c9eea83e,ff71398e,cdcd21df,e5ed8151,1a2d8c77,e08b76f7,4939d39f,1f5581b0,aa956066,fa14a7c) +,S(8578d531,bc79e1f,6e219bc7,7f2172a3,e5fb92a5,efbf9919,f46ea11,6f5ef0e5,fcd1b2ac,39c262c6,94eef5e0,52338f9c,cac2d04d,ed17c290,768759cd,13b7d550) +,S(98bc22d7,3ea2661b,545eb5f4,37e1cc0a,d4124020,44bb9093,5cdde758,a8020a62,143c7dde,d33ba5b,c2ac8d83,cc462f94,2607bff2,a1aa32d9,f32e14c2,82232226) +,S(7fcf821e,95d2176d,d088106c,a5bf0855,9980f265,ea3c401a,aca44b0a,d5e8ee10,27c341ae,87e7afee,f8af4598,e8e27cab,c127b054,1b389cfb,266ec9d2,fe400284) +,S(898a39b9,d440ef05,f87e195b,6a334f93,67acd67a,1fc76ca8,316292ea,216a5f1,eb642fbb,fe3274e5,2fd1cae9,744fabfa,c0db80e6,2bd4f7c3,fc2ca43b,18ce52ef) +,S(3ee974a2,8918c216,a962480,1f18bf9a,87d6a627,83323e3c,bf138bf4,3f2192a4,f5b386df,ac71eb35,499d5b2a,960fd20e,fde39fc,10dd5c63,dc50b55b,cd660d9c) +,S(bdd10d2f,de76df34,9ab753ee,d06c1251,9766bbf4,2fb610a5,7ddc3f36,4047c14a,504532ed,34f97eb9,b8b27664,ab440032,2b8b47f6,9c403bbd,6bc74330,16923dec) +,S(2c179437,39784124,4ff9a4a0,eb9ff292,477a5148,c4176b23,c000a1ce,3bedd63d,a367b584,4f9b7b2b,a82fccca,b9a12a8c,2c1ca5f7,3e630173,e37e600f,f2fcfb6) +,S(282ef30e,f2d61d13,6f71e6df,6ee97ebd,a83036a3,2d3cd841,36289798,b3e71580,90b0cd33,c350ea2e,54c25264,7a3fc91f,5b4f9dc3,1f58e86f,c47825dc,e3d0f43a) +,S(a42b4d55,42acfa7c,b54ab3d5,ee0bebd,85bf6ea,db138ef7,1ea38c73,899eff23,17e38880,f10b9927,764c4997,326b0b9f,63d0e03a,fd2f0bd,b1ff3cca,1f566bb7) +,S(b23acc64,c5b00c8f,4b580d47,49589559,a06fcea5,75f3d38b,1a02251e,ff7ef00e,66bb180a,7eaa64d8,4bfe6a17,d457f5e7,73964ac,ff908729,3bc540aa,1cb6464f) +,S(942dce6,96aeb063,4681ce7a,407516e9,89df029c,ecc77023,411a628f,75885ea7,e208be8a,88be7b3f,6b6b06ce,a3aafb45,c439f0ba,d517a784,ba13f80b,707caf14) +,S(b8a6a2b9,52194ec0,8238e4db,e71eb948,23e64a94,e10ea0e1,610465ab,88392d16,f8029f31,b8e5ee3f,77a758ae,343be258,34c7bef4,c1b555c7,4cb63d51,cba5fec1) +,S(a36d3369,a1ee05f7,b1fdb083,ea614cb6,f15feac4,17a416d9,cc83fc2,868fc20,e4abd7f9,fe40f27d,5b7b7651,6a9fd714,aacd2ae0,5f0a1f10,e94327e3,76f0af52) +,S(4ea30108,3d711ae6,ffccc89b,9d6fd4d5,6f03bd68,f4508cc0,ebef5e43,88dda1d,81e9997a,8b1c5949,6554bcf,154166d3,40f9ea5f,ce55ec83,eed793d5,5ca3e513) +,S(20228716,1c1c89c7,64742e62,e427b712,fee118f,406a175e,ce2f424e,2affdc55,7837965e,cf26a7f3,428d2864,41e1d09a,91eaff0c,5ecd2c28,bc817766,67fa35b1) +,S(d3c072fc,8e4bf160,5790d429,61206123,95be9092,f166784c,f5adb7e8,6070d20c,72688262,594c75bb,bb55c0fa,af7991c8,f412e0eb,afd1c0c,f5bcab82,d8daf31a) +,S(294dac7c,e307fa7c,cf0e8f34,28a354d2,94003dbd,ca763dad,3e6df60e,530ec82,479fc222,a7bcaa62,aee807c4,ba6309e6,cfbcc783,afd49ecc,fb9b45f,cf84673d) +,S(3956ca5c,c09fe8d9,e4042a8d,67b276fe,225de609,ea24575c,7075d9ac,4e732fae,1c965fe7,a8219052,9d25ee0c,e1fd62f3,7196431d,7bd78302,e287a26a,2eeaa23e) +,S(24d2e396,da144b48,e736eb06,84940175,4f4109d6,6d87a9e6,97ee82bf,91fb3def,bb79e772,24b02fcf,dd1e3c9c,edbad212,ea875c75,1fe7c81e,76d7d0d9,a372236e) +,S(638d4042,f16e5c07,fcbf9619,dd9c2f91,18852889,3e12cd3a,b49e2b9b,99a2aa5e,d0d97842,4f0010a4,df9eb8b,8e5d8147,f618da43,74b8a4db,222e4ab2,b32b3d92) +,S(f91ad5b,a99972ba,bb323a1f,d3032e1d,94202d88,63680c5c,d7d67828,8f0d866c,60b66d45,a693175a,3a38bb4f,efb32dac,1cb558e1,b0d13571,e24a14d5,9452bdc0) +,S(3154137d,779c25f1,4ff1fb88,a6d0370b,9e6af48d,88e7fc39,c6417272,eaa69b7c,eb3bd91e,9c09178a,398e112a,9264484e,c1980c19,b1993b13,560d39fb,92295f7a) +,S(f8821e1f,dfdf9fc8,1e3acb3c,1d1d7a65,f710be2d,94a19355,721cb93,61549597,bb507868,c1e05282,51b635b9,dcf28e5a,c5770c05,c7afc2a3,f4b4c45b,7d8993ec) +,S(8409463a,521404a5,a2d8aa90,50e3ad8,ec5d6faf,870333b0,6dd4f63e,8354a655,cc99452b,85092ca5,39cc1b66,83b7ab37,1b8a6525,269a1ecf,91b857be,e1db3bd4) +,S(96802411,12d370b5,6da22eb5,35745d9e,314380e5,68229e09,f7241066,3bc471,ddac2d37,7f03c201,ffa0419d,6596d103,27d6c703,13bb492f,f495f946,285d8f38) +,S(9d1abaec,9f5715a1,5c762824,4170951e,f85e87f,68ca5393,d3f9fc3f,a23a69c8,f21ee700,50dbb61c,238c89e6,29423538,71b010e7,98867bdd,149ad28b,3f28cadf) +,S(1fb96691,8db3af46,c37234b6,a4b04371,9886d6a0,5859ba32,f72742d6,141f7ae6,8bc13ecc,207efd91,f7f4c442,6e9a425a,a17b5578,20404eca,b09d5582,d41f7379) +,S(22d9e364,b9274dab,98bcb23,e0428e8a,416d54f0,5a781281,ee221db6,9e1ec7b8,5dc23258,f93d7db5,e5799195,b74e9519,4c300a91,28f924c1,c1e4865e,2d8407d) +,S(625fa450,aed083fb,30166766,d5874131,adb168c0,247cbff8,3987297b,f873e45d,720a8104,473dc904,65585ed2,1a0244f0,fbb5a286,5b8e5117,5a21f644,8776bb7b) +,S(24acb1c1,9b6dfc25,defb01c2,e2681ae8,2deacc0f,f21ae8ff,1f82f37,a6a2147f,f729d335,210e8061,8a8abdcd,b71aabe1,93f50ada,dfaf7d52,783991dd,d3ca5d4b) +,S(d2856803,a99d30d4,f3a328e3,bbf7db3b,6c6d1896,ba5b339f,33c1302c,f75ab555,9649994d,64705b87,62c98bbf,1b41b725,2b814a89,3e780fdf,5689c9da,692d6ff) +,S(80529e65,9d196884,b15e95ef,871e5fd8,8fb5298f,3bc7831b,50a0bc98,4cb5fe0a,868b3e4f,9ae4bea8,efde50bf,c5a5b268,b74b4a8,74e86de6,e9ae476f,10b3b778) +,S(7f9199aa,3b8201ed,5d288e49,49c43277,e0bb316,953f1dde,d0674d7e,8728e183,1aba673,d0372029,546c174a,3a72268c,ee9d7e41,dd97de2f,fcbe1f9f,1a5288b9) +,S(7d32c885,8e959f6,48c4674c,dcccb191,29b4566d,644d2fb7,6d0c8966,2c29ecbc,d90e94ec,b50bfee8,c951afb8,e65c7386,875ea99e,31f553e8,66e00342,6d39698) +,S(f2b961c0,9291ecc8,576ce67e,bbd1bf01,1f1727ff,ad9eb74c,bf8819e3,2d1abfbf,ebfe5849,5a1e6a36,46c38220,8656f638,ed0aec0a,d40c0524,1707102,3126f795) +,S(d9a0c689,95283291,972d6a72,897181b2,6b4ae317,4e98a676,f75bbfbf,81be876e,d36ae886,a0acbc9a,d1564d97,4d3f0309,e9039b93,bb350d92,2b7f8c7a,c6bfa042) +,S(c7a36324,6aeb7c8c,991b2aa7,10abdf5c,fff29912,30b3a69f,be2dd481,7c7c3e0a,1298fdd7,e448d2d,79986302,6b4b2d49,2b32148,d6d1e5f8,15f5b0c0,5c9e21f) +#endif +#if WINDOW_G > 11 +,S(635cd7a0,5064d3bc,66535a0,4dbf563a,640d2464,c7fe0ac4,8304214f,e4985a86,e40265,913e77f6,46735cfc,af9e2f30,e8d5f047,f3281a4c,e0453e27,e9e3ae1f) +,S(5da624f,38edea25,37f5b632,695b481a,eca54bb7,2169cadc,c5b91e10,989ee5f5,d3ea6dba,a1080300,fffaeeb2,43a5256e,48c28822,37b16505,a220d771,ca721779) +,S(aa4f64a2,b19775ec,92c1f687,1fe4b6d5,ce05278c,2976c80e,fe19284f,e87d4d5e,f39f117e,95fce0fb,6976e949,9583a66c,224ea028,8396518e,293793dc,3ed4f240) +,S(9b6518ea,99ff1b42,22a93f26,62e05551,d60969ec,ebe378c1,477b5c36,427e0641,2e9f1655,8650fb3b,43aea9dd,30532ff9,bebdf7c5,1d421656,27b7487d,8f93165a) +,S(6c9b9aa2,b5972e0f,a1e01138,1ddcbeb8,6547f47f,fb101159,4b193d00,ae97b562,af09d91c,8d4c71d2,be523d0f,9d205bda,a6e78eb2,67476d3b,1624a038,6275e27d) +,S(a2a1c880,3cdc95c5,5e636541,c7112a0,cf80aec6,a37e5f71,f5366612,db467cbe,c4cf570f,3638f040,ffe5410d,50d4b175,802e2e1a,c422fc2,73eb9b2d,4e23fc09) +,S(63d3750,c961ccd6,34a5af10,48897366,13102bae,20f2c8a9,ca8437e5,ab650427,87415332,74b39a76,72de90dc,698742a1,f21125f0,71393fa0,6d670045,8e339248) +,S(8d070e66,e4428255,a53e8fb,5845d14c,bcc97dbf,19b6930e,1f5160b2,52bdd04a,4bc98c82,4f2b4f04,c9884099,f173cd22,48cdef90,ceef4bb2,497da8dd,99487ecd) +,S(f1fe56a7,2e5f008b,b5014395,cc1658f,e3f3d4df,7b361456,175bfd2b,4a91c8bd,be5ffebe,e57a7da5,d01e302a,d3688567,a19caa5f,fe8a57b2,be2c866e,f5f275f2) +,S(802c9adb,d2eb969e,9ba71a95,675bcc7,b412399d,5aecd635,7476a1fe,73554b21,42132026,f547ce69,66e6527d,370f9c0e,cc3344c9,be1047ef,b7422e13,6772bc5e) +,S(95b1b6c0,9d6ced22,f0a5cd,abc7a594,9d24cda4,f178a745,c718204b,1493db56,bc143681,53033d16,ac8ce5e9,a6cf240d,27b2331d,36cb23dd,f69009d4,b6adb01d) +,S(eaed529,1f94eae,183b2aa4,e17022f1,7b79a06e,d76b169d,2d6483a6,a6ede35d,53d5b276,91c5899c,ddac1efa,3ad6baf0,bc6e377c,99ac7f8f,9cb27fb9,5dd559b3) +,S(77c44fe5,9f6f448c,72eb485b,6ef3f7f3,906d690e,367beabe,ac7b7359,9c27d770,bcd75022,6c440f80,2ccf0360,4e3d6b38,e6629c9f,facc49d3,83322eeb,fb1102fd) +,S(e863b2e2,f00f0a46,b6752002,cd936a88,11b6279,5411944e,fadae5fb,e40a0306,b5c79ba3,6da29f17,5b9caff,631e8ead,c2ed937d,66008358,b36fe044,67243a5f) +,S(226f5bef,93df71d0,b2feedda,4ada3098,3883adb4,f3dcedec,2721e72e,eef8f191,a09204b5,2bcebc14,8a0a08fb,e8458618,f966078b,d75ccfbc,c13233ce,741707c3) +,S(aa222fb0,8c1e7c53,9f3a82b3,9c6f08de,c33beda4,aff7c46e,3a4e9036,83467184,41105cf,21cafd39,821a7c3a,a6dff931,c1653d29,906b5d4a,c5dd6431,7c1c3765) +,S(1879c2cd,26ef4ed3,dc5220bb,397b1501,f94482cc,1236da82,239754f1,e1fec96a,912d5f35,75eade14,91fb1609,21d63042,4fc68951,cb73d351,464725b7,71f0d67d) +,S(be39e4a4,e7eed88b,f4a4cfc5,970d4b7e,6df6211e,bdc2bb76,7657ecb1,ac9902e0,d8b1e4f1,13fca7b7,6306d9a2,b4cf5a49,32ae54a4,5615c899,f94cc476,7e27cb4e) +,S(1ea72fce,33378c3d,d0302836,86c3f8a8,1c2912e4,7cf44631,d3fbdc2f,752d5786,e20f4558,fe1cdd14,ccff261a,fe506b78,cb6e2b0,807fc7c9,aed0b888,3748906e) +,S(56e33dd,67bff57d,e8c638e6,f32bc396,2d0ca011,b74db242,3ac662fa,da036806,4039c0cc,165e7130,9317d4e,41de57bf,50d78ecf,3e14ee2e,fbb3b93f,c393f461) +,S(51981691,a5f1d8df,1cafb95a,738b9e3e,d036ce54,f10a7447,c470cc2,e80f37ad,9fb9047,67cf2a99,766e3c2,6e97f045,d03fabdc,471ef664,d31aa662,c5972261) +,S(ef3a5685,77a59783,6b0be7f9,5f927996,b90db9b9,bcd57f30,16ec5979,98869dbd,51cfe457,ff22749e,949782c6,ae1f4783,fabe1136,4bb524d3,72ac3d8c,1b7c5e07) +,S(efc652a1,8c3a85ba,7ee9e0b1,6e3c6433,79a66882,5304a22,523c060d,af196415,8a656c14,cef91af3,1db2498,f5987083,8fcee71c,98c09d49,737447b3,54f7b2a5) +,S(cdda1fef,f4d5ce2c,d9802198,389880f1,8adc7962,c04a95de,f07370a1,884bbf82,8bc26ffc,b0c9dc05,d799174b,4a478162,4417f9ab,8536235a,e55c9b0,49e31d6c) +,S(6f3f3985,3454aa13,134b76d7,77dedd40,d46bb6ac,dc3a3a3f,93886847,b96cf0d4,a8ba499c,4f7ca1b5,ae7e5192,ea408344,b6e32491,e5649637,e4eec5c9,2cadba81) +,S(e52d11af,91abfb83,ea842065,ed8d804f,a2a3627d,85149ee8,61cd5df,e54b13e4,59f3106d,619e5672,cb21f6ed,4e73285d,2e132a3d,e3ed069,46838e12,a9cfff97) +,S(89fec736,f0de1cb6,45654d13,b32b3cab,8fb91869,c30e2ac0,66c0cfa3,9e7256ff,f9417ae8,4d3e1a6d,b6ab938d,9dfde62d,73e708db,b58f5ded,46b455ae,7e44274) +,S(5140f56,91b10553,ce86ce73,3028749f,52261520,a8903f75,31bdac09,22b70b29,91a1962b,9e02c23d,61f4ce,21c0ce90,ad0acf0b,fa250afd,dd67d72,aa2dc024) +,S(3c16130,93109917,1075e199,ed32f94b,579d0eb,85520d09,c0f90fc8,7d267b5c,d50d04df,e4040db9,3aa0010,7693ac01,e9f156ca,5e800e51,a5f7d36b,78ac64c3) +,S(fd87690e,63a50237,258b8a58,f0240552,a2d0b952,911d1fa8,be13eeb8,9be8bac9,406dc1ac,ccb968f5,6fa3ee35,247fc66b,b40f04e3,ac512474,58e4fea4,8a1b9225) +,S(8e4d1de,17e78f3,2ce8ad59,973b328e,99005ce0,6a8d9347,ebc7434b,d5a12a81,c6348f3e,744ca65d,744c843b,4bbf0d8a,992bafa8,8c31b6da,42919401,b1a2a8ae) +,S(382c7bcf,ea62c678,173b6eeb,ba58caaa,f4988104,1677bff6,ea739a0c,6c7743c2,190a5da,77e64243,53df7f27,e01c0f6a,67e9addc,afcd3523,7cf5539a,69c5eb7d) +,S(f56a8b4e,74b84807,539fa471,bea50795,25b0dac9,53bf5d29,e87d90d5,f914ed0f,5456d908,da57e612,3ab881c6,56a6ea24,8f9f201c,13915a48,c50151fb,c096db8b) +,S(908e9ffb,6a5e557a,1fef8ea2,b16b80c4,3af3652c,55f12a04,4ecfdb06,17965b80,beae28c9,d1b14cf0,f8182ca0,7ebc3137,b9c01094,ed6b6043,562de75a,878bc2ce) +,S(a6c30718,433381fd,16b22533,52934eb,3fad254b,99d41e78,7ef2e6e9,bec86ef4,47a9a286,a60d5102,4d129e4,e0309c72,9e266f82,5ee26f4,4bf90057,623fb818) +,S(948bad86,6c3e2c26,2d46163,52be20ae,30a652e3,4a299361,4766eb7,98b3e903,30d30622,ad478a2b,99c43b0f,915de0c,4321da4a,76a18d33,95b4c484,d9c35164) +,S(d6c92b9d,cb8a17ae,77788125,18782d36,9d536edc,f96d2c9f,c9e84d2,1cf6a3f2,dd9367a0,93518377,97b0ae88,1aec5d4b,ed68624,8ec2207b,9e0104af,2ade09b9) +,S(f9ff3d7b,7d8b13d6,46c641ca,64df802f,7b082209,a75ae328,54cef0fd,65566abd,ac58619e,1f192095,f7223022,43d811d1,b9269d28,a18711c8,c84e5960,32deec98) +,S(3dae1dba,3a70e0f7,209a920,42837ed5,7f4e767f,834d14e1,c3528f6e,92c8d5e0,7ae2468d,6ea1f2cf,e1fcdfad,3ffe87c9,5c7816d9,ea99332e,8b4d055,280f797f) +,S(27045105,6fcc937c,9cbffe13,f2aaeb0,8ffd227e,dbbc7ca,d0b4b01d,19b49937,11766a54,6c24fdfe,220d3724,661d6c75,bbd801f5,c4286ad4,d08a698f,1ffa4397) +,S(f9d95ff9,6c3260ee,cd434075,262fba81,2024c556,649c4865,bb90d65e,20defd22,37cbf7fd,8f741411,80a632ba,8304730b,a89d54a,1a5b1dda,24b026bc,17a13c2d) +,S(4e8df18,f90f67e9,fed8c6d5,b66cfbe6,ff0a86bb,db990214,48ab57c5,c5a7021f,7e69f8c5,ccf56413,453a2b1b,3b34843c,e9badfd,3a83729e,a2293fda,f2a621f5) +,S(8c2a4d2a,710a7fb2,1ba78383,63c66458,ab3d32bd,3be35821,c8a5b779,d2ffef9f,d532447d,27e42583,46171515,71bd6577,f82d8f91,ff39d205,caa5aac6,365511d6) +,S(28b7f3a0,19749cce,6fc677af,a8fae72e,c10e811e,d4b04e19,63143cef,87654b75,30471eb,3245ab39,1597c881,e71f4a1d,e241ba31,a678fe39,2ced5a63,845ec782) +,S(cb474d0f,fcb8e72c,257b5acb,999ec8e,d89f6494,cf4b008,8f6d7db,59be416b,ff7cd0ce,fc293cbb,8ab9a950,8759f856,9a0e59b3,effc00c7,e3a3051a,a16622fd) +,S(c33e6982,5dbebc40,265567fb,ede2a4a5,1a180034,2e9963f5,bd57b35f,4055b36c,22ff3ff5,7ce265ce,253b5061,599ab066,82c0cb5,91a51e0d,b798ec2c,c546be18) +,S(84bfc106,44d37123,71a441a8,4444a9ab,257e0745,b3d0ca0e,ee341838,19bd2237,7cbe56d5,7b7af706,c33d13ff,b3e4197b,afd7f421,1ece235a,e1c2187b,289ef6f1) +,S(9c312ec,d53b244e,fd40f003,f7e0835f,6063028a,5b0488dc,73599653,f97b713a,11bcbd0f,58fc77ef,854d0b16,188b4e8,59698ba5,fee41fe6,165449b1,4eb76d14) +,S(5c06af59,a22d6f2d,cd83bf4,e3bbcf21,d474f61a,e01d0433,2d0a82dc,af15cefc,476b4be9,f1c265fd,a8c6d70d,6c669aaf,41fbefb1,425e2be2,9048165a,4322aae8) +,S(777259c6,81a3ed43,b4c0eb54,7af39ebb,f44f0d71,c84602bf,2d6d45b3,f1b6bdcf,8a9d3753,5481858a,eec44851,4c834667,d6742b9c,f563ebba,22fde187,fb3bf754) +,S(b370601e,ae1fc1d3,14e4328b,4d0244de,174b8c4,766283c,e3820c50,41266842,8ef05079,2174c3b0,752a9abc,8d980ee3,eda7b5aa,4042a932,3e136834,bc125ac0) +,S(5af94ac0,7f8d6492,a472ad40,67097206,78086856,b01528bf,8248ac8e,dafe6584,8a54c7ce,57eade51,1d5f32ef,cef5f56c,b40dffd7,8cfe5655,2a9c3966,e62daf1a) +,S(8fe3c19c,e2e87055,385d4f23,c5832f37,4f84b41f,3f945945,81acb8e7,5b0586c6,f923099f,d16f44c3,a4314d49,1af193c9,2f5e2017,156f860,674f5ac,91728c28) +,S(d580961d,2642bd1e,5f9211b3,9b65eb5,e531d17f,a37bafc3,b5f288fc,13ac9a71,500c0554,337e8b43,36e50a6e,b12fa86,d9678cdc,5b38f650,e4f897e9,1b4185cb) +,S(255dced,529fa623,49e46033,86790c32,234e7967,5a9c5405,256cfbf1,4295e82b,7eeda9c4,7f3e1c7b,fc3253d3,faa46317,5dfba7cd,94f6cb10,c8f4b4a,7d799815) +,S(4b7ebfa7,9240451f,ab8476a4,ae48e55f,1a27c338,a8dd8458,bdbe422,ec891557,dfb260e9,f89135f6,fca23cf,ad7ed812,c12622d7,e4285284,8c63d83e,85b59085) +,S(919d0780,9e6092a9,a3b5819e,c67719d,3119569d,3bd14c7d,8f47f555,1f2fbf28,ca0b6af8,76d70f2c,ecbb2fa5,98d6118,c204d3d4,a30e24fd,cbcaf283,843d8094) +,S(466867a9,de89a944,5bed73bd,5ae342a4,9b8c896b,59eebf42,393dd536,8c70ee78,2a5d9707,b3e15823,79bd6ca,e8b7ed09,9cbb9f93,4ee96029,385d5678,aae042e1) +,S(71274d08,c8784517,8921526f,cf71258d,fc740d5b,be655f3c,d985cba2,c1db3f7b,e0af0130,a5be1434,f8d652bc,4406177b,3cdd2ca6,6abe7f56,d848def,fb4b25e0) +,S(a46e9048,2d25241d,13c693c1,f4e6068f,b6e8256d,1fb3111f,a0ae0e37,7ebe2bcd,7567700c,f22aab69,8126e7ac,961726ad,fdd708bf,d5ae5111,40f921be,94474eda) +,S(f7590b91,f2431126,85873b0f,77be6851,10ea918b,a26d3b5b,aec02bfa,a5e84abd,481848f8,594c94d0,c9b5d6cc,858dcbc8,2d25128d,5ea28e2e,ded935a4,62708999) +,S(2d7aa8e5,1282e1da,dad39d64,398f0790,4f966edf,aff5e3bc,9a22edde,428c2edf,12b2133c,42032099,eb33ea24,f1755f9d,a30b4da1,708cdfb5,7635b61a,335d9d79) +,S(91313f40,3302c47f,d9f113a5,581f135c,82280927,5f658607,99550fa9,7236d0e3,f8b6ec07,5e7804bf,461daee9,1f21285b,aa9e96c2,2e0cff27,c323f627,90838a77) +,S(da248119,9d385a7,8468e86e,1b146fbd,e0be031c,3a19d0de,2f44a1d5,6c6743cb,c07c897b,5f76f6ee,f2c62511,19b37c47,5d418b6,1d2cda66,6d39ef67,40348cbf) +,S(95e36a24,b1bc2e3,fb5e6082,de9ed432,760ec3f9,6f01dbd6,2e820268,dde82220,be6990d7,3abc4a3a,8f03b209,dcb4202b,52a74a87,1e1e3d01,7665e9d1,1ce1cb63) +,S(8b05b060,3abd75b0,c57489e4,51f811e1,afe54a87,15045cdf,4888333f,3ebc6e8b,1d10f881,45db40fb,889e2ddc,e81bda7c,27f5b615,acd6179d,bb30f4fe,7f40fb39) +,S(ffabca3b,764a327a,750bbb2b,a1cb8329,d43ec0b7,dcd8f728,55a9d30c,f3020f54,93970a65,c90ba260,5b2fb393,a4e994b4,c791965c,b60a1302,cf585443,6dd0f05a) +,S(b3a85aef,ef35e4a9,8f0f05fa,9752998a,d3514868,b133e7c0,a18fb053,b866c72,30115ee1,c21e5b9e,3d6b36c,54e700e8,9ee78c7,e88a2752,38f46d1f,5b6005e2) +,S(a4f1fd5f,4c233cf2,b9c5659,f666d51,5b78fc32,ebcb52d5,d155250c,c95b7ab5,91d19f85,726a1258,444419fe,c5219c7,33754325,89d92d52,c363d61c,81faa0da) +,S(97b84b4b,7baecf13,94bf3923,2b58b5ed,9eb14637,d29b3c98,bec3e624,15bbb0a,497db4af,be8e7b3a,13493d73,ca92b4b6,5eac7f30,d86dbbf4,8b86f495,2d162435) +,S(2ceba0d9,203e3666,75e78e96,51b5b57b,a9de5f82,3cc8569a,1c274d19,946312b3,d4c2fe86,f042cfde,41f0a88a,6d77c188,b7805db6,c6ab440a,488a75c3,8ed2b437) +,S(ab8b1930,6cddaca2,8be57b78,b4836998,912391cb,c6a41e10,e91b86a2,3f2b7009,fdbbabdc,79fba1ae,9d8472a1,7a648206,7abed651,36892a03,35128650,374172cf) +,S(2763029,1ff140b1,57eac2b5,9938f26b,c149705d,aa2dacd,6bb0d305,1a15b394,c2b6b32a,38dcb9e2,f4640838,c52f5ca0,55359479,86ecd875,a91504ac,49374ee6) +,S(22d1edbd,1cc1514c,7f91d793,3e9dd124,9e703fd0,8c65ed8e,6cc79eb5,cafc78c5,7453e7ee,a53ae741,13024fca,208a3816,a93942c1,2378ff7a,5e65678,c0a85efe) +,S(70d869c0,c5729e94,270fa559,bdb3fb8,b6146527,5ecedb7c,c8e7c9bd,acffe222,4bfcad32,8ce78fb4,617baec8,48c2c3a8,f8d41474,9c131657,115dcbb8,f6ec30c5) +,S(a25b45de,da8d5782,64f60dcc,da97bd28,ed9039c0,6bb7c97d,d4a24eb8,791b1647,8fd84983,fd2ad956,32376555,4c43a664,f306f11e,2f030c7d,fe1c68d8,aa43db8f) +,S(823fcd6c,9b237c0d,5aa38336,6737066f,3e77fa14,b975a5cf,39ca8a74,3b1024b8,e691a44d,29a4f2dd,e99c2ba3,bb6d4345,d1433e4b,d1c65d72,198f16b5,4424dde0) +,S(39a5a63,8244aef6,432b1247,d394d305,ee594bd2,6ed2433a,3a96c4ce,5a158d0c,147ced39,dd8b8494,d57ff37e,a24cb108,ee4b9f43,50c556cd,32df8b27,626a8023) +,S(8f9febb5,b85bb2dc,74aaf7b,81b27796,2a18f6bb,4879f5f8,de94aa56,b3206487,48daebd6,d4175a00,e37dbde,c2b57b3d,dc7474f2,ab6a093c,32a86acb,f610c2a2) +,S(fc16fb14,2f500856,4509158a,5f6b4e35,6a08db53,36e9d3f8,4f7a03d,9143f60c,8e9326f2,7e02b73a,10f4ada5,9db85fe7,4027584e,6b32aeaf,58bcf804,dc1f7a36) +,S(7db09ea7,17446f6e,9115d8f0,987eba83,eaecae01,f4201d78,8e292486,85c5a281,b4469cee,426d455d,f736b2ad,c12fd17e,79fd2167,c5a6f864,2733e327,c215742b) +,S(d45d1bf5,28baef1c,3ea56fda,b1f8d3c6,3df7caf5,c7ecb0b8,564fbc94,a4d9a57e,91e26984,64830e89,1cd21d3d,81ad7000,ad0c84d1,3c05a191,c1a172e1,16aeccc1) +,S(3faf0b75,1b6f85d8,550a9ffa,a7a26bb1,6a4d9c99,ae97678a,d43a1a91,75f03901,8a5d062a,a4e43cf6,5caaa39f,6386311c,be775d14,3b8d9368,b555c436,1844328f) +,S(54608cbe,8e08a472,79cc5e39,c65e1ec0,1eefdba3,3b127107,4926b06c,76efd121,a7695bc,40def81e,48ec5f91,cc98fc2b,9bdc2776,71d05afd,cb789e20,c540f038) +,S(559a0d89,50dfcd4,364e6955,23b56972,e8a201da,4e196d46,64dd580d,909823ec,7bf8e1ad,d6528b90,cedb8d5c,87f5953,5641e32b,6a6a7b4,c46e8052,e8dc71c3) +,S(166e8858,b5e2b9f2,b1648c34,41e5fc28,bb305ea9,b0679c3,1a996b94,acf467a8,9c9b306d,ff82fb42,acd8a6b9,108f9994,dc1b7c37,dd0c9d2a,f64205a3,92e5bdb2) +,S(40e29e8c,e66e83ba,a94ec5fc,3ae438ee,e5284f94,c5efe5a8,d41da738,38fe1941,7c71f71c,c01e7868,1cf154e2,73a23d0b,84ae684f,b0e709c3,9551884d,39acb2dc) +,S(6829c8f9,eb659ce6,7f87fc76,4661b400,6aeb8b3d,bf674408,1a844380,72d4ee7e,1d35530a,8332dc05,54e82522,5e9ff30b,6647fcb3,304fd908,ea506945,ca22913b) +,S(4a3fe05a,322e9fd3,93393b13,6e2af237,e25a2540,42d10e7a,dbb35d41,13658196,859a41f8,d4527641,a93c40d9,ef0ab175,78dbdc45,7edeaea1,f147018c,7901574c) +,S(de5817c9,a675eb2e,c1567ad5,a6467cc2,9e9ddec2,177f382,25a5e101,9aa44f94,4050ebd0,5413311c,df17e625,6d4bf102,71b45e17,4c8fcaf5,ec36567a,ccf723a4) +,S(fde29245,4f07f411,abdf1a2,6f3d8f38,daa7b9b3,1b51fe7a,155da5eb,5662a108,f2a4e6d3,7b39e929,ccf347a3,ac6c719f,f09d1756,e407371e,d98dfdc8,b727808a) +,S(f28d3cfb,6eb98ba1,76fc536d,6a772861,b0917415,d08c22e8,a43a90ed,eff42436,4508be2b,b328250d,e043dc82,d8894aa4,1971fe8c,42e6cb61,e9d02735,1279d1bf) +,S(c7655c30,4d1cb5b7,d0992afb,119a6df7,7bb65496,420f78c7,117b951,7f16e3ee,898162c2,cdb730dc,4b986b1c,b0de79c1,a348b0be,51b9070d,2e427e2d,e71dfdfd) +,S(e57d97c7,2fa3ee66,71d67936,eb62f4d8,53ffba74,f2158d0d,7ae3eca0,7b4b147,b1e3012c,a3d92975,91ab80b9,a668ca13,1ed42660,47c34958,c07c720f,e1fecd64) +,S(eada8642,155025bf,c0644f92,fe014ccb,6cd3d37b,76686a44,bccdf8c1,e22b0c01,89035d7d,71d71bb0,117c37c5,540f82a5,7152aac,af79fe91,6aed7d2,9dfeeed) +,S(3e76267e,3f172198,9f9d7e8e,11fa3ff,62dbf8f9,77503e27,5567ec84,e60d0e25,a1835790,9631c6db,a453001e,c7e3973a,416f8bc7,e2fe0871,82d8a236,6e1160b6) +,S(a11d97d8,9c262f35,2279e69,2d66be7e,5de7235,18e6750c,6972d250,91a3df70,d18df8a3,dd6fb016,df2e48fe,ab889165,44768d77,e9488b71,fd31c6db,d52a69dd) +,S(b16e3f75,cefec06e,edd54bf8,dae7cc29,a5ab5208,fd58d787,922f4221,f5f20651,57fbfeb4,5a6e32ed,74fc1989,16909891,233ae90,c539b81d,a758761a,a6d0eb2d) +,S(37de800a,3f73ea6e,9eb564c2,faf147a4,837339b3,44a33d9f,beb25784,c74628b2,59339259,9da55803,196b7e5,3596aad7,e33fc96c,fa2ae0a0,2f41ec13,e6254050) +,S(6f68412d,65b3abaf,6fcb781d,8b6e6baa,4ae57fb0,9325a1f1,9beec438,cbd68055,884fd59d,406171bc,b31042,21abb5d,27dc1433,ef49af08,ec031543,2f8d3bcc) +,S(91479a9e,6bc5e261,24cf0ce2,b52f070f,980f1f9a,f60bca79,572902d6,cb6e4366,2304f70a,22de4435,99f6025d,4b13be27,47932524,112f64a,ef935d1a,9c2f5288) +,S(8ba6b0df,36ac8708,8c1e7c1e,4177dcc9,4cceabc7,4a6c7701,8358c194,4d19bd8a,e96b720e,e9d515e2,922abe8a,177ac755,989dff1b,789a85ba,ad17f859,62ab9ed4) +,S(ab152195,871f3fcc,58f59a8c,a35514f0,f11b8a69,54e4ec9e,f4aacb7b,29d567cc,c1ddad48,623ebda1,42899ad1,75f88ff1,965ec1ca,651b419c,3c8ea037,f267fb4) +,S(7eb23f48,5eb92bd0,1c0e6448,e19adc22,6ca45c46,d4d5c756,e552ce7d,551600c5,953e9b12,4278b939,7b3de07,63e30c55,a300ef97,a8587328,b3dc27b1,a7c57ac5) +,S(b23f4c2b,a4b2700d,c7520a92,25890491,e0212fb7,eeb1f0a,2f624905,4e21ee17,a38b6772,9e95b3af,2cc7d5a5,c10386c2,8a2c287e,6349f811,457ae0dd,8b598530) +,S(85d2e723,387e55b6,a2c1a02b,96cfad64,67a6c12e,b75424a9,a10ab77,2769c2a4,727abdac,223898af,1b077fb,7d481434,ded380cf,21a131d0,db845150,c8e4d303) +,S(27c1715e,8dba4cc,41383d59,e669f66a,54ae6901,88a794be,9fd8da6c,9b09273d,2767ca54,306e6ca2,3517d884,1e7f30f3,e16e22c5,cf2bbf9d,998d5cd4,b5b1a266) +,S(e70b8cd3,7f9a5e8e,9e0c4fb5,6f85a6ab,42cf4042,4080350f,4465cf8b,95eed89,2e3d8c58,94788d1b,9734e93c,7508cad,faacdf06,319854fe,5ec4b0fe,6b0cb31a) +,S(e23dd455,24058396,98c81a39,f3f076ae,93932c61,d0e7f65e,e2c2013c,dde956b9,6c53cbd0,cd8ab8,bf5cef85,a8aa0b64,52b57e79,cb53315b,1dcdb68b,78cf77c9) +,S(5e923f81,ccc49813,11a09f2c,47677cbb,9aaf0832,10c683b7,d7a07399,4d919c9f,604d7112,e64cad06,fe0e64a8,af7054fe,7059667c,fb5159f7,738b97f4,38306873) +,S(23d9f253,1a9fa278,e02b71d7,113fde6b,1380e543,633286a5,60037ab7,70142507,55dc8247,b6eb6119,a6ef49f6,bb4e85e3,a9fd201,4f696564,42d3372b,fe44a9ac) +,S(eeb23095,ad2551ef,15dbb281,5ef6d252,886c79ef,12c7318a,50f5d89,d73b8f24,d1a71b94,b9810ce8,eb0c3896,3e7cfb90,56a80f82,9d384eac,67d9859b,11ba1ddb) +,S(64a6de7b,57bdf7e2,54beee53,6efeea9b,899a8436,e421e3c0,e7a2682b,54b7c21b,6427936e,2e344fca,c402e2d,2902fc6f,181ad190,e3f0d537,cf40c96f,27b4755b) +,S(9e4676ce,d76daf3f,1c1aad5e,51e700b8,8207fd45,3cec846d,779f02c2,cc270073,5685c781,1d7610ad,4655019,5d8a844b,6ffc4acc,eb458c38,d9d74f4b,cbdc9e42) +,S(95ee1228,80616ba1,76e0ee23,14428c7b,1d83c635,6ec843e5,d134b359,8d645473,7be34c64,41914c07,58081278,9b254c71,49a60d13,c6ee3a3,7d12e29e,a3bf4054) +,S(e53ffeef,d92081a2,f91df506,6453cbdf,d0b1089a,c598da9,94fe4c03,fc6516ad,560f02c1,4a600d02,a2e70b28,5164618f,5dcd1b67,ac071929,ecc1d891,e4c59c2f) +,S(9c332744,7c75488c,5a14f1ad,fa3d9974,90d4eb10,63afba83,fafcc3ea,62a7b68,9cc759fb,9a7fc3b,4d0ff7d2,24d0cc54,cacfb78f,5590eb8a,d689b6ee,19791c63) +,S(e826d500,2f4315ff,77eb22b0,c8b74142,f1d1037e,81e3c58e,4ea39430,973d3c45,3a466e58,82f971f4,3ab9316d,fc7d53a4,e8ab16e0,2ae75045,5d8d1999,bc8b65de) +,S(ced4df0e,af93b5c4,8dcf196c,6e9b16bc,dd38a87b,3fd67512,d387b388,115e13c7,fe08a63b,dd149dca,b4f2c930,99cd11e1,8c754271,cedd597e,910462c6,d68b74cc) +,S(b056ed27,88ea50df,2b220182,df38f54f,8065e36d,e0218b27,ee8c5416,db7eb33d,97338375,cef457f9,ebe43aa8,28e9a1e9,8d514d9f,fc300a6b,a1a83db,dacf6409) +,S(35dec74,2fef94a,7fe60b66,7341f6a3,eba030c0,4061d156,1c9ee288,5b7830df,2599121,39c810fd,e7f02fe6,eb6e9221,3eb8be6e,4d8f045c,aba1f058,789b933e) +,S(3f23cc8,7733213f,d2e15cb9,942af44f,d7981e97,37c5af1f,81addfb,324e020b,24e8ccc0,d43ccde3,4e392455,dcdec100,7ffc0c61,3b5f865a,c8afc051,756e8f83) +,S(9ba96c76,c0805cea,d7ecfa43,dba0d86f,c8471dcc,8bce9bc1,e06537ef,2bbabbdb,c1a3c433,1c2ae04d,be2f8e3a,8f4f07b1,622d9820,607ee3ae,e93bc37,f943def3) +,S(83c1479a,31475395,8d510396,5decc9ce,1d414f41,610e2ac5,c2e887d7,d16a3815,84d4d018,1354cd46,e5f39bbf,f9fffbba,c123d470,d07c292c,7f085740,289b5b7a) +,S(bacf627a,2db11d88,76e6714a,2857db8,a8d7010d,7b349ab1,fcb5ebc7,efe0a32d,a287dc0d,a44c448e,68b777b7,36ace20a,14b3e586,bab7ef5e,d57ae303,e8c83129) +,S(73063c55,30129f79,10bfd2d3,a0147167,4ca888d1,d64d24d4,619c5cff,2776ebd7,d57941d9,44ccf8c8,2fab0362,b14986c5,9d71906c,d28584ea,368c4bb2,2c159489) +,S(4ee8632,df55ad15,12ba4ce3,4ddb403e,a3f51a12,d445a011,4d08a00b,3b5d6637,c29f7199,dc30275a,39ff01a3,19723d19,91687901,9616fd81,88ae6c45,92b14820) +,S(fc46e66d,68bbd41f,98b18a16,a23efaca,8f5345ef,b567786c,cd42afe7,d7e7ef28,8b42a2df,abf8849d,53daf38a,4a4c28b9,a0238231,ec8f69d5,d702715,a643c18a) +,S(a71ad1b0,158d7978,7eece5e,2a3907b1,3f9b6b98,aefc7963,8a9de618,b3a7dc13,6fd7e86d,a956c464,e538a864,41b9b7d2,ccfc5c44,e80a66ea,4375e6a1,ef08bf90) +,S(602185f3,6075a67f,d7bb9957,60c6af59,61a7c553,d51d828d,ed37768,f1860a3a,90d312db,706b835e,647a027c,e7a89d39,2265cd4,dd52e802,165c32bd,4d10b2e7) +,S(db0fca83,76729191,b9d9976d,37dc62c3,36b4437f,943706b5,98e7b7df,607a77ca,23dedd6e,8eba7ebf,e0c9f0b3,2a1802fa,78699a68,99507dd9,c4f4841d,82efc29d) +,S(6919b861,598d4f09,2a159909,fff8de82,237d0aec,339d884,7618f257,a4a54939,ab9f82fe,1fa53aa3,b85c0784,59a4e191,27a1a214,392c3ff2,f3e1cbdb,6f34b90c) +,S(f4a7d2e9,f1f51ba7,c3cf0a5d,5d53a00e,877ec118,f7e39e39,299efb2e,8074bd59,9f050900,6aa6ace2,da4e6380,cbce7983,c9bea9d,99741be0,ef17e190,2c5bd257) +,S(8a5d7210,d4f1de13,1091ae23,2fffbd96,3927317e,54197656,366b2e35,cd453da3,9aff8a1b,5b71da0e,a6558a05,a9306adb,4cae1004,e532aa98,abcd1644,b0580a54) +,S(99eb23dc,e40d7159,b0a0406b,ea04b87a,2c9195c2,2afd79f3,f938018e,b8e86f16,2ef21938,a66efdec,7ff6cdda,a79fcabf,b1f17fde,9e80db37,82b47d41,64ecff66) +,S(3bf16e84,1a874418,ac7f0d0b,9abbe781,611ad0e4,7acbe904,a99ba65a,b4d37472,1d3cb9f4,e1948cb2,fc88c0f1,9277437c,7d1138b2,8aef4355,1fb35121,a3e714ad) +,S(a3ef83ff,19eb394e,b87c133,36388a86,561811ce,5449895a,f459fe4f,e7f01f3e,1955dd39,8bdcaccb,cdc7ddb4,711d08e1,9d687ccd,d335a4a1,45d13a4,8178cbab) +,S(26816f51,da9b4e81,3edc024c,223dd6b4,5a344d11,f5ade552,63ef17e,70b1af90,46278e1d,1d6b67a3,57280967,6604e897,65611b7f,bbccfd30,22007a60,294aabd6) +,S(5e1653c0,d640f148,ecbb14f6,97940b0f,1d47dcc9,48e7525a,909e8444,afdea823,9b8b81ed,e7cb8350,ecfaef22,92bdc528,8e499cc9,6feedc86,cd45cccf,4cb092c7) +,S(1bd88e45,b0d3694,56348c23,125b12b6,b7725d6f,addc08f2,47fe9dbd,e828de9e,182939e3,2d8bddda,577dae7c,a1d40164,9f6faf68,69808fe2,98dba2f,b8a95db0) +,S(4b03fe06,3adc4e40,315e754f,bebb7802,b80ab716,d4201fbd,31b12c5f,d9b73c02,a864d0a8,e2c5e519,ced537,e03f98e3,a5623c31,ea4a430e,73e8cf54,1c80fb06) +,S(e20a515,7818f33,1ed927f1,3c46f3b5,2146860f,d085e68c,5884f1e8,45d35f61,a1c12002,1a79d6c5,89e466c4,3fd48f66,a924e9a0,a3d20db0,484875e6,96bcf328) +,S(e3d11a4e,74a1e1cd,8be24d87,4885e1eb,4aaecea1,c802ba73,2db925c7,f81e37be,8f1ec01e,a1ef01f,63806787,b8831d4b,22b0a9c,7b44bc7f,73d2a3b6,861645f5) +,S(8a233215,57fe0dbe,e8e92b58,4729b163,da71fa32,f400617,d1e2a081,3e37f6e5,af5e471a,bb8c7505,aea1ed74,bd7798cb,267dbd29,61c35f5e,93889056,aecce950) +,S(3bbc0a2c,b43f4683,151070e0,7015cd6,997e8dfa,99685cbe,99f9a76d,6851d20d,9a1dfb8e,a5f14c40,b9968e88,b6083111,fd140843,96fa8278,bb0e351b,7cb4f97d) +,S(8c04d781,82d83ab,e8c59dac,9407b4b9,65380f38,39431184,811e133c,911d1deb,4d74e493,fdb22316,fcf21340,88039534,c0a3e098,7198ceab,4a65260b,4c0a3db4) +,S(467d4d0e,72312cde,df0aa7c4,62e03644,1ed9f915,c9e7e8c8,5770a4d6,d6a0291f,83db40a9,d7c2954a,30c624dd,f11d565a,f117e240,183a81fc,d4dda1d,70a1ce32) +,S(b62f60cd,8e55a101,ab060186,941cbd52,ce73ae2d,e19ac195,d55f498c,45a3dc8c,59da48b0,7c6d2562,eeb0ed09,158cd20b,4a5108b8,fbf6fcef,428cc301,b314ef41) +,S(6b5d6210,f98aee61,df36d7f1,9546efe9,166e88cc,6492183,379dd1b5,cb9e681f,dbfb1748,59c88a6b,72c8afca,830045c2,7c6de87a,c47228e7,7f246e6f,698a0d76) +,S(88744d04,e8c7842b,68d2cc9e,f58977cc,548768db,48d3c286,49ecd0a,22300c97,84573aa5,1ea3c51e,5a0b0e42,5c7c90b6,149d2993,91085bc0,393f58a2,8fb9c38c) +,S(fdf2c824,40f2ac58,19b06571,216ad938,d0218ba5,be4d3d4b,ada80e32,c32e37c8,c2abc4b5,9e961ffb,e48c6f20,58602dfd,9172031a,740668b5,5876d5aa,5d538f74) +,S(4d2fdf64,1f5a883b,322273bd,24755405,15178ce0,9b4ce8a9,36648957,ef777559,22ba1d01,210bf31c,6421b89b,9b3217ae,b2837f01,c344a9fa,bed0b385,4aa41b11) +,S(ec7cbca1,e743bfdf,81af3fae,a5c64a8f,5a54dccc,2afca269,9c461592,34ddc633,9f193da9,ea76a050,7b528c05,e5a10107,dc5263e4,98fcee29,5f57816e,4eab0917) +,S(ff2fa113,771998b8,b801e779,3cb804c,da9cd6df,9d371943,c7fabbc0,44b44fdf,962127f2,1ac57670,c79d966d,b8cd6f0a,2aec6824,22cac54,23746bcb,2df6093c) +,S(6d1b406b,2dfb02d2,34ec21be,c436d6af,4fd418c9,29f175ee,6475e77a,8a57580,b8945668,9dba8e2f,8f0693d6,d3e7b602,f157efe5,38b9ef07,b2dea23d,bce895eb) +,S(4abb9dfb,449e00ce,46476727,dc6b96,317bff7,74c21df5,87bef539,644d7963,6086f2b7,c016c69b,2ad80786,89af1c98,4d6dbba8,7545d8e4,9c2c58bd,f86e6407) +,S(db0c51cc,634a4096,374b0b89,5584a3ca,2fb3bea4,fd0ee236,1f8db63a,650fcee6,7ec0bd2b,aea1ae18,4bd16fd3,97b0e64d,5d28257f,85836486,367fe33c,c5b6e6a0) +,S(ae6f6dbc,d0664919,a65e02ed,646de704,6996a382,21aa8e74,4954d22c,37fdb287,abe70eae,f8ae7404,11931379,19f9102e,c5bbb2f5,f5fefd1b,b76fb6a1,c3f2f201) +,S(aea3eb97,cb321f30,bd0771a9,17fc9770,f4079a62,fac51fda,63dd3ac8,d35f6227,b6a53416,398515c5,e9133704,a287dfdf,878145a1,4416b525,6f1ae46,6abf39b6) +,S(90c9f8cf,711d50de,81f7234e,f6c13af8,39355c06,3e891ded,51bca1c,852233be,8d95778,18f19649,f2d3d452,81358783,17d2c32e,aa01551e,d7fe21c8,3421bff5) +,S(5ad7ece5,ab1d0344,5528dcde,34b48efe,fd954aab,920260e2,1495ed8c,86d976e0,2df2163b,2c3c63ab,bef274e9,3c46b6e0,62ac9444,b17843d8,70014b03,f78569b0) +,S(b6ba2e2c,8e942ef0,16e6d3ee,13ab0cac,1d80ae7d,588a831c,b7844e8e,3bd28d9a,41180a35,f923dfdf,501b6b06,7d241160,a2ebf453,d00b501d,855ddb7,1bef7fb4) +,S(7e409bc9,bba26c7d,fabdd450,bc84589c,799555a9,c6809cc4,13a4c674,7ff5f37d,c518961,9cc5afe2,e41c4260,481d8fdf,6066b034,19fe030c,e423dee7,79c9e6b1) +,S(9486cd14,70b2f2ee,28d01060,6c7c4c22,2c72636a,a50b64e0,3008516e,de4f602c,886ccb8c,fc5b006f,df931785,f732367e,c062e9a3,49f452ce,aacfb74b,deb467af) +,S(e7c11d7b,c8b07205,1e1af6d8,745ba05e,94b1ee9c,5482d83b,1af9ed8b,21338d2a,fdc4d293,828cab1e,fc9062aa,192f35a9,6ad4683d,797fcf79,c74852de,d75c8e50) +,S(dfe627b,ff315cb0,1b1b67b2,776ded35,19b1a85d,8e802217,c98000f0,93d50bcd,993c55eb,bb65087b,6fdd2480,c9d68e6b,ea0f69d1,b95efc28,5f32a8ee,55f9e773) +,S(a0f0cc17,fd00a2cb,5fc7c981,860f02f3,eb31c26d,54841dde,189eac65,a446f516,bfae884c,31d58a3b,f11077a7,d3edd37e,14bbe4ea,bd30fa74,ff5c295e,4b3b8969) +,S(c1dbb6bc,bc14286e,d6eef926,c946b52b,d37e7f53,91fe1dd9,dd7b72ba,a3e37338,67b02d87,bd336882,f4b6fdc8,1a3a88d7,aa5e2735,139e1bd0,e793e6a6,12df7bf0) +,S(20b9065b,c7d495c4,c92cb1f0,6eedf5ef,7025511,10343eeb,e82505bc,bb4bebb2,a6987316,5c231d92,bd21a4f9,60242d9,4fec71a7,4b24fbd,55d51246,10756835) +,S(7bedfdd0,c4d8c38,dda9544d,38fc8786,55ab9a66,4f8dbf2e,3c54810,eda69190,9994f0b0,d4f52de,6ead0049,172fee05,365556e5,3c9d4591,690715a6,f8af77a1) +,S(26762eaf,997983f6,ac63815b,720e97cb,5adcadd2,419d368,df4d385e,6b5918e0,81f5448c,e11b4dbc,24be2e9,be5620fd,25f0c0d6,76aae549,2792188d,5a27e6be) +,S(7148cae7,ee18e152,c3354ff5,dda86e13,ea14f175,92d0d3d9,a944f4cd,f387bb79,bdb35fa,f6f86e90,41465efe,dac6bc0e,ffd42a0b,eee83365,93dcb4de,2310b18d) +,S(27e45dd9,33ae2c33,a69ae00b,156845b5,bb4d8f06,593c2723,5038ce17,87bdbc90,a2bce33f,a93579a3,f8d9c75c,9271a2b1,7dfe36a0,590f2db1,f7cabfd6,51801ac9) +,S(af0c7215,5b28ae8c,2a2d79c7,d81e603c,d0539c11,fed2aa98,fa2bf2b2,d7d6b7d7,ae6bdfcf,a25109c0,b80bfc,71cfac3e,3b5b26e1,e4f2c856,40d2c69a,a7ac41f9) +,S(7b63c408,d4f8d34f,314e609b,21e8e372,de0f5a19,1accabec,7ecfe02a,63cbabf4,aa08009a,78fa96bd,8ceb6f65,e88859b6,236925d0,bccba7c,e0db29be,94f16327) +,S(ab768853,14f3e88b,d63cffb6,8f4f3232,4f4b4801,41aeff93,94d58f9b,85c6890c,1a71c833,d6d96bc1,c33610e,d7ff1481,c9ff9841,157c59e0,5d3a036f,cf7f192c) +,S(641437f0,7ad75112,f8375487,cc0ed859,ccd308da,4b25e5a9,953e351c,9e3bd32e,3c58f7e6,b255346a,f50f1ba8,3f008662,7d2ec950,84c326b0,ccc3a388,81a9b131) +,S(f532fd2d,600ed478,c1dcceaf,fd01ae87,60f7ecc8,7739580b,9b4a7649,67a082cb,7393514c,71117d7f,7cdbb4d6,c803c9f3,221847ad,697c945e,440bcfa1,1285fa96) +,S(33679959,2c4bab44,d89e6f60,8f882938,db73dbd4,75f0dc3e,e1fbd075,b1c7631,4c1f8004,6fe89cf3,6d078251,5ff57cde,17125d62,5cf675aa,1fd70163,49694fbc) +,S(e184c16d,2a34ca57,b06b5396,28cac285,6f18b7e0,32970a5b,e2221a07,be56c9cb,7dffc17b,51ef9c4d,f16ab068,8c66df57,d646cd34,46b509c7,7f85e03d,e2c5bf73) +,S(f8a97d16,2fb49d55,bb8de990,9a20c1e3,4f6ce6d6,efb8c68f,e26c884,6415d419,3cd3cc53,4dbfca01,9492e161,61f2e86c,5f20a83a,866874a7,ded4c2e4,42061146) +,S(9eb6aa2f,6c6ad821,d46dd612,38d3dc53,28cfc406,ad71964e,b32de0ea,12475781,14501a83,79d32e09,3664ce34,1a419b28,53dfe3e8,fbc204af,cb33e347,6c45c299) +,S(ebc2566a,68e68955,e1e42740,323fd401,7c40315f,ceba7642,5f887a3c,3602668a,75e8109,96ff56e2,655f9f85,ae9ec9a5,fab3bdc1,42ef063a,a06931e4,d4c7ea39) +,S(55646438,a966ce5c,2fa5b29d,ba4840cb,ab9c5e4b,4074a9fd,674b7eb2,f52bc392,34631a86,76034a89,cfc3f68a,45cd52e6,2987d80c,e9a8e28f,a37020f,981c8d66) +,S(b87f8309,befb81f3,313257b8,c7dd914c,82eff5d,6729f2e7,eceb0337,7b16575e,bea66832,59e4002d,6fbdf03f,b80bec1b,eda5e1c2,cc55c630,deedb7fd,a96ea298) +,S(45957585,b440d63e,acf598b2,16e435e,24b6cf15,2892c8d7,953471df,70a0a93e,f4cb6260,776a4f4f,23ac366a,565067fb,b29739fc,233493a0,b3eaaea,c4b71427) +,S(2c90f64c,8d9c42bb,1824c821,8f9cc057,3fe8d648,b960ee11,1487bbe4,9648ca87,829bcd57,ac643cb6,9f000a9,f22fcf57,69bebf7d,6b1d8ab4,da21be41,d3c25a8a) +,S(eb327ac7,779c9abd,9546a3fc,c7731729,2e753912,2ba9f7be,36db0548,144b5efe,21ac2c85,8d2fcd38,8c32c594,d6e74803,2cbbf365,238565a0,8c439190,518c9435) +,S(95ec7e2,272ccca7,aa2b07fd,d37d0f08,daa35418,1ae30e6a,dba0cb1d,2c6d007d,733786ef,59df6050,552ac913,c10b8890,2d589e7e,4f740f33,75f78fc5,2ba12b5f) +,S(4b7a6698,8b4fa080,f27c845d,7ff17371,91104a29,2c6195f5,fc367c69,fc0cbbd1,8b043bd0,a3605612,87b38fd4,d99b29e4,8e52494d,8241207c,9284581b,63a85b8f) +,S(89b2c58b,6df581df,352ab28a,619027c0,a9233792,fc6525e7,47dabd31,a342e6b2,300b1b34,d459e65b,e265edea,203b74bc,9b053feb,888e81f4,10045a10,d7f53a2b) +,S(41099b5d,9f6a28d0,e4a7ff0d,b75ec487,1c926327,89f0c800,7ada8114,9bc43cf1,2a0aba96,2e2b92b6,e949253b,e06588d1,3e07919a,3594b26,995c15b7,7a62cae5) +,S(bcb0fc64,9ec508c3,507396b2,9a663555,8825ea9c,1389c817,af7fd616,7229be4,168c7992,cf3bf5ab,6c3a12ae,922e647,13664db9,2d7bfe5c,2c746933,3a07d606) +,S(7a3fc958,5a6256af,9e314ca7,55a8096,9cd3b3d6,f70349a5,ec719cd,ed8b762e,fe8b280c,29cd0716,35288526,b7179d90,dadecd78,39128f22,17d445cb,d3df1346) +,S(377093e1,b968a35e,e0f229e1,e656da9a,7583c1e6,d06fe1,c89e3f06,61a8176a,e7c0860d,f6c9f461,7e6a4dd0,b8c0d800,6aba8e88,20aeb82,e6e0f8a0,c2c601d9) +,S(c5eff3da,f4a5cccc,f1f27a93,361301a1,919b1dd2,5a98ea37,5ba63f14,4aafecd8,34e11634,26f983dc,18c8a02c,2222c2fd,a94129f,4e3f1d67,f424964c,dcb97a1c) +,S(fc7919,eb560d33,44230f72,8368afcb,3c0fa6f1,52ec54e9,84ea9ccb,e63ffb27,1c7d3782,af766ff9,bc1cb838,8e4a7dd0,a04bc4ce,adad3fa9,4132842a,9859a6b3) +,S(2783d7fb,49386d72,54434cd6,edc6f46f,b3118322,43d381c6,287d8b24,861ca5bd,a3aaf271,b806ac0,e3c45026,28f89c79,e4c68574,81710111,a9316e38,c7fa5c70) +,S(7407a478,68d4e0d0,f77f8949,5e5bbf95,88f54a6f,fd35d229,8ad4b30f,2d8a02f3,1250d562,96e18cb0,aa5b393e,a933297e,debf3d94,59ac1ce,24cc11b5,87fdec9c) +,S(c2d2cce3,2940ecda,77ac108e,71544079,c5899fa4,f8461df6,cc54dd21,a861a321,f0beb1fa,40bb8071,928b05e3,ecc8545b,a919eaa,e830db72,9e6de85b,f05a1909) +,S(8cf6b189,c5051956,6a94e1f5,ab5e9530,d459a935,4cb13eb,349fac3e,ade8a56f,bf6a9d70,32e52886,ce6d06d3,b22d47a8,327aa788,1621338c,1606054b,cfcf9c96) +,S(d6b07586,ed9f8471,f96ac5f,53277d1e,2deeaa2b,7fd09d51,ece6766d,29a94968,dab4d4b4,ce5655cf,4aef0d0d,5e3fa292,2f79041e,d2e23c9c,75be83f5,f09c5326) +,S(a720b733,60a03edf,f33a0921,90795834,9e661d33,44da800f,b857227b,ef4d647,1f213c6a,721c2d82,6037e3a5,a0f4867f,13d79dff,bd44f5b1,1bb5c0b5,4884ea63) +,S(558a5698,3b03c6c6,717db862,e59dd075,b39f9ba2,ca01b0ac,95a69cec,1f3a5ff7,7e07c752,db21b68b,21738458,a045fc60,fe3ae869,887fd557,92ecc6c7,d4ffb1a4) +,S(b927dfc3,278668a8,c5329941,f11d0e0a,a7c2d9d7,f8d6c263,9cab5550,10e14ca4,3ce83725,9954227b,b420e35f,77705225,72f4d854,999af552,4b8795c2,b723388c) +,S(2b70d499,1085aff5,88e23ed5,ab55a374,3c35f71c,651c0165,13f98ecc,4f0e6da8,df413b4d,aa1e5c9c,a2398469,7d82762f,a701413,1cae25cd,1a94f02a,506a8b06) +,S(b8836cdc,f72f6e00,99a9181d,94ba77e9,e1368e54,a62e1144,1421f2ef,2daefe56,9ad452f,e31f26d,cad7014b,68ceaeb6,1beecaa,5394c359,afa52209,e50427ce) +,S(252b297b,65f0e23a,9788b48,f33809a,ec66b445,cd90db00,4dcb6a80,c4af93a7,8cc4e0c4,3c346211,736a3bcf,c24a58bf,9f77c7d0,c53350e8,6cb0de2,60916838) +,S(9f3d30ca,1c15cc66,8efd5fa0,3d6b7bdb,d34f2704,cd729892,aad9171c,debe6330,448b6434,f95ee7a,bc056974,f1476171,353d9b98,4e22057b,38662327,b23211b0) +,S(8225e16e,5bc9add9,ff8a771b,5bc7bce1,653b545e,4e54b9e6,6e2d2985,2fd35e49,6254c5e3,aaefa2c1,6ca4e1de,87f09d94,df836b9d,d100612c,7174aa75,7d0570fa) +,S(a7dcee48,4d6e99b1,b72a80b7,4de255b1,74f4767,4d3c5799,4669ca6,aad02ebe,1d6f0cfa,76a2901f,4861f541,bef7a948,78586178,8c7c42a4,2db583ba,1c170a7) +,S(a91445a8,5d4ce90e,98d3372f,d2c664b8,9a6baa2b,a396fd1e,210e315e,809976b4,adc4c68b,99b072b1,b51d1512,cd94007c,72deacf9,4e7c5449,f1d83876,78b1d100) +,S(7462c9ce,907c9655,75c41096,3510e00f,6f6ea6ad,886cdc79,ed685ee2,2a7ce1f1,4ffa41c5,f02c2299,c42df5ac,79cc4140,47a854e8,332f8f2a,e67ffa20,bb71c7df) +,S(d42895f3,dea495bd,af8e36bb,6a79f234,dfd85544,965a8506,5d38ca86,28cd4f40,2fedeb18,13a11c42,e7869b20,7bb8486c,9821710f,a80d9bbd,59c92ae0,b50d9cf5) +,S(ef9b6b62,ce85588a,f13434b2,7ef53d12,e8291e6d,76a65669,c29d99a1,4d388adc,159f5fcf,9af0c962,ed907955,e91407ca,80261255,45b6938a,db18aee0,9bbf912f) +,S(4003f1a0,bc659daf,df5fb7bd,bc96afff,92877c7e,2a693f39,2afb06c8,fdbc9f32,ebffcaa1,7458f0b0,28ff1dcb,74be865d,7faeafa6,c2707cc9,ea685eb5,7961fef9) +,S(4390488b,6b03d851,648786f0,7486f5cd,aa9ae1d9,4867de,bed7036a,6ac09a8b,78329de5,a10db56b,1c35b88a,21ddf393,452001c1,29a0bd6e,5dd76a63,8682f07a) +,S(ae6da0d2,9ea3fb66,b6006c56,5dff8b41,6074ee16,f9ff86b9,60574067,abfadea1,74caaa63,dd012a63,e76f0916,f370614e,29e3f01e,b88b49c0,5ca33234,c11cdac7) +,S(78f879df,98614721,b7c65652,4e806f6,35942e0,950514fb,2fad8a86,bbcfc72a,4194e58c,478ae80b,fab661b7,ffb85cc7,2318aad3,88d61c68,a755296d,38281ac6) +,S(80684365,4f41b0c6,d6cd51cc,838355dc,352e028,7b1c1d1d,edd2f96e,5fc97e01,8b0c223f,13c61b4e,1e141a0d,35f29a7,7546bc7e,3b1e5c45,262033eb,92b62461) +,S(29509d9f,4fd975f4,6efd1169,1d97d0aa,f83b5934,9c797010,5cb3908,4b87466c,1477eb75,69a0af96,c9cfccbe,135e3c86,a33de585,2ead38da,8a0eba6a,6d0da81) +,S(191d1443,3d9c722f,c1532fe,33c63a9c,4e3d5741,6ebf799c,2d8ffeae,df1dfa4a,5bd00409,b6b571ad,745ecf83,91884eed,a5e3c7b6,65ec9706,eae4b4dd,703a2cd8) +,S(2843d42e,d2738168,5eed65af,eea82bf2,a50f0e1e,3db201e1,ebf8b159,1b0155a8,807cea66,c0fa9f53,b47e6e2c,232cb225,77edafb8,99a6f98,ff87d091,bbc63ee8) +,S(5568b7b0,9656d36f,5347514b,8e8212f8,e96ed02d,4516c018,4d653bd1,2bc8f644,5b44eba6,54836dc4,3fbda30d,7ea36406,4960459b,a4128911,8b2d8638,50e60d87) +,S(5b84e0e0,809e44a6,9e8d81ab,595b32f8,4a7dd421,c073fd6e,5f38ec5e,b145e803,1a65a2d0,fa791ced,72fa1522,ae431155,7e6109c0,fe934243,cb43d3ef,ad13d398) +,S(ef42c56b,dd241071,47e1519a,18d32910,675ba842,92cc8ede,900a64ea,bedfa672,70151747,33359977,611e0c25,4addbf6b,26a618a2,31474e3c,c9e7bcd3,8bff75ac) +,S(48dff2dc,b50d4a56,4be6ed00,3b1415b4,adc653ec,87eae94c,92b7c129,5656eb63,a9be97fb,53afecf6,f0bc59e9,8bfad542,fa29e63d,f701f6b5,f0f66081,8d643928) +,S(672e90f5,246ad174,10c9a2df,c22b098c,d1923bd4,19fdc337,f881e4fb,4ae938d4,73fd3380,1fda6db6,883e678b,31e5f09e,f331b624,5617ec9e,97aa28b9,a1781f19) +,S(59cdb9b1,71fb819c,909e094a,95dc15de,dbfe5521,4a7cb723,ee7cb761,4b315cde,55ac212,670b4a63,ecf3f8e7,3082009d,7f2d38d9,e490ca18,7a6db01b,e88351a2) +,S(5ce38d0a,357a58ab,134db879,b99994c4,6b827f82,8e1ce8f0,43108de,ad2ddb18,5e816202,d9c1d86e,c2f84b33,ddbcc51b,94748c67,1089c9c1,745a14d9,3b97f716) +,S(c982196a,7466fbbb,b0e27a94,b6af926,c1a74d5a,d07128c8,2824a11b,5398afda,7a91f9ea,e64438af,b9ce6448,a1c133db,2d8fb925,4e4546b6,f001637d,50901f55) +,S(383cb084,79e61bec,dca81d29,7796d00f,60bfbcc2,83c83d31,725f5329,839ec818,26e26fa2,49008933,8bde0498,15f34d9,bbc3426,ad8644ff,db1a190f,79dec91e) +,S(e6945731,2ad4f14a,71917b52,448011df,28b88c9b,6ac84550,248ca4fd,102f612b,30ed2082,51fc701e,5ebeddda,c9eb0b44,c81cc86f,9706889c,1b1c3386,4d76f53d) +,S(2d0071ba,8f799352,212168d2,1262a729,250809f2,24fa58a7,f283c4c6,bb9976f7,cdca6901,4e4873f1,16945544,800079d,ccc118f1,a5709b03,c872b017,5f1dfd8b) +,S(c82b9457,65b74fbf,91cf35f0,679877b9,da35c2b0,8437d789,8d748f22,1e927e,2e504dd1,bb06bfc,7e057dae,9aac8f07,b57a0f2a,39b1533d,9313d9f2,45fd6a2) +,S(9c1a4c2e,7eac21a9,fed135ed,e737dd19,2654eda2,fb3a4227,63cb6328,75bbf0a6,f3134b6c,12f71c58,226c9128,9b7b5a06,80eb6646,e9da2e60,20008efe,10e9197f) +,S(971d3d9b,bc693222,ed8bd645,e80b7cf9,9b170a36,2d57753b,6a2ac27e,8d6c9b28,d63d49a,e296dc2c,6c4a73af,7fc5e86d,e2039433,f3858980,80a36f7f,91d22e2e) +,S(f5493a73,86bc1151,23f29f2a,e0619e05,660a317a,bf5ac23f,a67802fa,8b917d2b,e6adbccb,8b780530,2b305157,b427b8b5,38455e02,80133e23,9642306e,65e0f1d7) +,S(831f123e,500e0a0a,e497a321,5ebde2ad,763244fd,40b386da,dde05537,99b6e014,35616862,2ff588ac,552fa508,ceef5ef9,ac04af0a,9db6b950,f44719c8,cb221d6c) +,S(9b8ce06d,18474c,3394c334,2ef385d6,7a338c22,98e92975,f1728c87,897cfb35,76940220,b8dc3e04,7cda50c4,c1f53747,7ce8757,a4a3731d,712cea05,42a40d72) +,S(f70a916b,a98d2bc9,60172410,42bf3e14,14f06cad,dffa7cb,1e8137a7,3fc5b855,f1b8c1f4,70d7896f,f39a3fbe,997a88f3,b5426d84,43c4023f,ff98fffb,280275a2) +,S(2d2ab7bb,c44e7fe4,ab283661,2f621d05,a64d6909,fd94e599,92d52afa,c0763d56,53450e00,2a6991c8,68fe044e,8b61c2d3,c5fec8af,3605728a,e57d32cc,c55328e8) +,S(8178deb8,c516978c,ea25423f,3a913157,321ff7c5,5d8058f3,dc9b9d46,f4d10005,16a71b2b,46c9d303,f4ae6a28,235249bd,f9c00146,a26b6bfb,5983bfb6,8d6ff4bc) +,S(b470bb76,d012ba7e,67ef9c32,add59940,1f700ca,16003011,26e6a692,36b56a64,f7d093e0,7d179861,871f36f1,58d26987,1775f082,a2fbfa69,27cc2272,614fd95c) +,S(164f2aba,837cac12,19b48eb3,30f02141,d3a89921,1cdb3f78,fe17133f,e2de29ce,3bc05608,95f7d034,4a9ec79e,b821c06,c2837c50,66925197,2c076374,871d28dc) +,S(c77a3a04,2a86d2e,f512268b,35cbb89d,e6a210ea,883e2283,ec59fec5,12e725f4,2ebcd56b,edf1a07f,e587e592,8ed602b3,6d1db4e2,5b49e914,8dc9eedc,131cfba2) +,S(e2defa1,f714cf71,557a3f1d,71c6abe8,11df5504,da38e9f,60ad335,3b11349,5ed64303,7a53bbc7,2f41912e,a657d944,c5107da,3b9ab54b,d88b545a,e045f229) +,S(ee2d12cb,b4cd9e4c,163fca1e,5a4330af,35280ce9,cc1d57b2,d2112443,b6313e3c,e28b1dc1,a4377c65,838ecafa,bfffb696,4057fb6f,dd4baf08,49f9223a,ee153262) +,S(4392c96,73e6deca,f3c39c34,f5be7c3d,a2109b45,2271467c,78f256d6,7d9e28bd,7fe4c183,ae352533,b049edd5,343a6bb4,747d63d7,d0f406fd,5902a886,110c50) +,S(5972e2ee,167374ad,93a655f1,6008f49a,f5586b2,f81197a6,712ff31c,a0d6960,6d70fc55,d0a57c74,8a2e485a,d903bd72,779343fc,7c090847,bc3dec1a,6f7c71d6) +,S(a85d800a,fc2c0315,889f1faa,29e5766a,a180f31a,400e3c19,85589af0,302c78aa,7429d7f4,903c76a0,a4437b41,92865b7a,ff5aca7a,52dd32a5,8f8b00d,b97ec85e) +,S(c9836b0f,d594fcc,9a89e85d,7d506386,ccee3f38,72759cdc,9548569f,a5f1c245,9f0b1926,93b7fed6,2f1a7d06,fd716727,bed1c2c5,9bb431ed,943b7082,d094fac0) +,S(ca2184fd,b2b84654,d0348e5f,6d963193,75f2c441,ae64622b,588cae7f,d202bd3b,d1222820,3d657aac,493dbb2,fe9729b9,e2563cc8,1f671626,83c4f0fd,726a4de9) +,S(9e0515c6,3c9b9664,8762704,80605d56,b5dea0cc,c7a4c66b,44a2e605,36941fd8,29de3224,a2eb2d86,afef789e,2dba061e,95f0b762,117ede50,6d4b21c9,54be831a) +,S(42042c25,33203a7f,c22cf7a,fa5f3d79,8a3447da,51d66f60,53a8f000,af5dc1cc,f075a67a,6d6c3872,315420d5,bc13d13,c54f3c1d,61f73d9d,ff688da7,f5e6c05a) +,S(6645a1bd,4eab02be,45884ffd,288955fe,3f5a68ca,9ae431bc,cd3967c7,12295b96,231f79f9,1d264ed4,28ed4b30,f0e92c4c,bf902865,24050b67,30cccd12,bb84cfad) +,S(4e281e6d,2c316e88,231482ab,1587de37,6898f3a8,870f475f,30bd1ee8,d4b32f9f,f48cadc8,1c119edd,e5f78062,cddc3416,c3f708d5,f37e4910,11ef7581,c065602c) +,S(77236414,96e41e9f,f13c7ffb,c7a66203,4fbaf7d3,e432ce02,fcd54ef0,4aaf5136,222e0174,d6cc01e,fb4b4bf2,9000f697,98bec7a0,657f328c,80083074,242dd218) +,S(3f2b704c,8d467859,ada6070c,b1221840,18ab009f,f7b5ebdd,af31d977,dd45860,a47167a5,146aeb5e,8c38dd21,5d61a2df,e2b6ab8b,fd05ea9f,b59faea8,3b4dd88a) +,S(794ec130,d243d811,2ebb70f0,35f983db,84b3acd0,ae4c5b51,640b9e92,ecad4146,49edecbe,95c25c7c,eeca537f,937aef5c,658f2dd5,d8c0de71,c80777aa,d07be84d) +,S(750ff9ec,e363e12b,79b04cf4,a7b1c0b1,49c554cd,6e9fe3ba,808c9614,95a96aa3,5a28269d,d1c5a3ed,f4e70f14,9a060b42,2d4474bf,1e4c6dfb,2de1502f,7a1d59a9) +,S(d65c05d7,df6668ec,b96c9ec1,fd129462,263b082c,9b7f4169,6335fb2a,b66272cf,d7728c5,1c10d42d,242cc5b7,fc77fdad,7e48be06,6b2f7c37,891ba4f0,de188839) +,S(d3804cb6,8cb2e9e9,b5b9d270,db9a172,aecffe39,72a3d2f6,1225bef5,595190c3,11fb350c,9568648b,30af4131,46053428,2879023e,6ff0d613,482c2471,b5e30d5e) +,S(f762de26,35c6349f,6cc95c61,9ecf8d37,6a938241,1106db3d,b34e9e84,70351bf6,dc67f9e0,c8a50f9e,e753352d,a99112e4,ccfe22d,3e88410b,1cadc0ba,bc9fd814) +,S(ab18b4bf,a827ff4b,17ee163e,d17e3927,d7dcecee,ba87ce7d,ac5e5767,53b87a71,6db83bd5,73e40926,c882bc09,c4d07f72,29706d1c,d2b1ded5,b57ea9b9,2b0da919) +,S(f754c248,fec21ae8,da343a87,459622a,b12478ad,8f63ad8b,f5c66695,198c95e,2cfb76a2,5f9c8776,b848d8e6,7f544774,e056ca7a,32bbae52,93b27992,6052b1bd) +,S(f8d9473e,3c3f0798,f893ecdb,716bca16,103516c3,1341c8e2,c2462d4f,9a46c51c,55f0065f,a422fe3a,26b314da,c7547835,5c53bd3b,e11b4686,9e05be92,d7924e02) +,S(8639942,d294cbc8,9a75fa22,5b29fda9,2f7c5ab4,bfbc4395,352d050d,754eb741,3913ea2a,445de35a,36d79abd,db3ed7cf,741da883,4cb81c29,6779d8a9,e7d11e4d) +,S(2a588c6c,706a388b,f1719230,b5a71b4a,6857282,83aec61,794d1a78,bb95d5c2,af25ed77,1a56f6d9,6407f07e,a7e11f97,61f458ae,bfbb1b00,96842c4b,6cc47592) +,S(137bd1ee,8931b9a8,b26dba4a,d9a5edb0,a5459717,22e1fe3,37ee8d54,20a0cb6,cde9fb7b,8197c77d,273e9f0e,e87d76a1,eaea105e,21154b7f,f5848a30,17ceea62) +,S(46580345,c686313c,97152371,13af2c2a,f9b5fea,a1e0bb48,d21bbe32,d2de2bbf,75bc5d7b,b6329ffb,2bfbc79d,b66f4c2a,7edade8e,a16bb051,a3a8ee9,ec92ef64) +,S(4a149252,afaf5acd,982fc491,c26af545,2ef93d6,1b282a85,56d5ef64,391bd233,fbc100bc,10b55b60,96656ea3,863f5d4b,bb9e83fc,5a25e59a,3b53d78f,60cfe285) +,S(894ebda6,fc0bcf8f,e025131,3475d64b,95bdf089,7d9753fa,ad0f92f2,15a01f18,b25f3150,155772cf,c69d0251,97d37ae0,1e4ede02,e2994377,9fae26cf,5f5ec056) +,S(e70d8a93,a91b891,30def1b2,bfd720ac,2deedca6,f9e5a85a,3c2a6eae,45eb032e,bd3aee53,a3b0ff6b,45fb96ea,4911cb02,fe102681,878a1b0a,693fdf11,4cd9f9cc) +,S(7cb1fdc3,e5ccb1dd,4a16765b,f9546b6a,1189883f,135d447e,eb245fbb,4eb36852,90ee0d6,becf5ff7,b80edbe1,75dbf258,d1889008,a8fed4e0,1968e2ca,8fca582d) +,S(51278ad8,331da17,8fc90a21,432b9058,b39f57d0,31210685,bf9bfbc2,87b9bfc1,5aaf547,f39ce678,8c3ad759,b25db3e5,7bc1f9e1,f75bc040,536ddce9,d3a66b6f) +,S(f0eeaa1f,c52b3068,48b56308,22fcf0f3,fee5008,54e276ce,e9fe9904,54f59cdd,90ff89b,944d70bd,eb5e5e01,6afbeb30,d51cf7fa,81182e63,ab3bb2c9,f2124f02) +,S(36fc9bf2,8bf90fd2,613670c2,27b51c00,df5b4caf,252b5df6,648ddb6b,3aeea71,887c3876,f1ac6c28,606c8161,4ddbbbe7,d975ecc6,9fd9075e,13d0e3a3,e7836683) +,S(6e31e26b,cf9436c,e14d2d04,1c29f62e,135c549d,5e65bacd,ba4df2a8,9b91b68b,2389684,9e63bdaa,b5f7d9f7,7a778b31,94c1af87,d09a9a85,85896188,acd0e7ae) +,S(c5044649,a4b1c2bf,ac6a8a1c,ead33aa0,3da9fad8,4f742eac,35792672,1d98e864,6d2602d2,83e696bb,717d1327,cc1143b,45fdc84d,b8d400af,537b201d,a7a1027b) +,S(a933e71,f13c44d5,bda8e963,b5a007bb,b9b2e84c,c45211e6,eca804ec,6a99ca28,931bf3bc,ec45e2f6,e6571207,31d42fdc,c3ce0279,542114f5,c1c0f659,f6200faa) +,S(9003f61d,840c2d62,1ba98884,e117038b,b8559d0,b132a1aa,83adf65d,f8e4a58b,50c75124,f72b3952,9feb7ece,cba26854,1388a1ac,73631532,b67f56dc,e8d30895) +,S(fc807c18,3cb370cc,8638abdf,c17281a6,914e21a9,e9f3e2c5,33fb7c37,caa0a886,3ac79d3e,75ac1d5b,a9af7263,9d564256,1ccf6fd0,6b8d2cde,e9d24a1b,e8af00ba) +,S(3d072ae4,aca4ac23,b43b608f,150bcd4b,cd780dae,7e4073c1,86293cce,dfee9cbd,6d9e443,f721c9f8,a98fc563,8d7627,f9c60414,67da3857,92fd55d2,7e65d9b6) +,S(d0cb8594,7061b4a7,d2bc5eed,522faf8b,ba6e26bc,7acb1d3d,106aabd9,a7f80dc0,fbfd0f26,e9d0dcc1,a0107b82,d1a9876b,8d7562f1,41f0892c,9b739e47,7b012e0a) +,S(e4edc0ab,6416c644,1e59f46c,c7221cc0,267aadac,242cee32,41a6d25b,635bc9fd,f41c3ae9,cea7b4c4,4834482,980807d1,c496fd4e,bb06964,b84c1fc3,4fcdc71e) +,S(6233b50b,2d3d9101,8f5a83c8,84be0f5e,ffb80641,1b0b5271,557d32ab,dd7eb4b2,8dfaad24,ffdd2ac2,5770f21e,328588b1,34a3a2b,dda40399,7911ef19,855dbcc5) +,S(6ca00162,e27265e2,27b4e544,7e981f6b,c427e65e,bde295df,9434b7dc,52a19ab5,d33f5f63,a8f227e0,a43fe297,babb3a07,223e8916,e153a5c,e0f57e65,1154cce1) +,S(c01205aa,5d2a8d5d,c0d328ae,7ce7cb16,d6c9d992,8b6105b3,cd68666e,36fefcfc,b65e5f99,c4f48095,e1bd6f6f,6af8ba7e,cf2988ab,ffa9bb45,3ad01859,e831d3e) +,S(e3965393,e6268cb,61d6fb19,58050f39,7b8a597,4a6c4abb,4e0b78d2,dae0e155,1f78ad46,2ed6e1d9,18004892,85383b2c,3f971fa5,cda0c828,a2f289bf,80731737) +,S(27bfd0f3,702a9d43,50c1a6,9fd990fd,3dc03af8,50bd84f8,1248222,6cb099ce,22e16b60,e8caaebd,19b0c0bc,e40be7c0,c49fd3f0,d9094f39,fec1b1c,bc643de8) +,S(8210fbc0,23319565,9eec1777,12997a89,2a37172c,6f75e3c6,cbf080a0,6f96a2f0,1ddd7792,101166cb,bb11d552,85e1eeb3,bfacbb25,6d1a5097,16dea91e,46afee8d) +,S(15cc66b6,5fcbbd80,df15298a,25e2ff80,ae4d5065,f8befab0,89cd21a7,4e347b5e,944b47e9,35748296,deb324c9,f5616d28,7b225b34,488fb34b,6ddacd32,7937c97) +,S(eb7b7aa2,45960169,1ea1a482,a9e6c35e,c7bb08fc,726c2c4b,ff801ae0,94c97976,4d2e9570,cc187791,fcbd20e9,3f0656a,f5596f4e,104c3f2,27c23f82,2ed1b1f6) +,S(4598fafc,ed29e844,c22436e0,996a8469,18e7c106,b40a5ea1,5fb0e7df,5e9ba12c,e73d96b6,d292ea2c,39779dfe,7f716609,978a8555,e5b09629,7dce228f,f35e6093) +,S(49835a86,3612e594,572a2591,76f90e18,e57d4dfc,1910c705,8e37eeb3,1a8600f7,3b7613a,fbd2cc1,cc23b147,e0e80d36,464c08a2,e488d7b9,8250ed37,dfcfa531) +,S(3a6d6fed,1fcc8067,32a3177b,4dbdc33,3cbfe0b7,d19305b9,965916f7,ce335351,cc3f3d8a,314d617f,148a6706,d7f10641,11eb2b56,1bd1dd0d,f2986925,5a6624ea) +,S(21208586,6860fe30,ce92d2ef,b2035b74,f672a024,ee7baa78,fb0d6c7b,3ad7a9f5,aaf145be,51b1ec,3fee8be1,1f6e9d73,96ff0ce3,41f25d7c,e1074a09,78bebbb7) +,S(f819132a,c9bb2f09,663d609c,51cb11b9,833ac082,6ceffcc8,67cda04d,266e4e06,b1fde638,ec6a305c,aaffd1a0,6404aeec,c52f48ef,7646abb3,7e227239,4c891de5) +,S(536c05d8,8786640c,43734d72,aed62d9,168385a1,213c4428,423a9437,c2ec009d,7f4be100,d827de18,68bc2b43,c83a08c5,fd84ddee,1fa9ef13,4b489325,db6df0d5) +,S(4328123e,c4c6db76,37ee3ed3,42c8a859,9de2fb1,a39a24bd,650b73ba,a1df722b,81c002ea,1277753,e6a22fa7,1b4f86f5,4ee11f10,f5d5b15,94c9d7e9,63a40857) +,S(f3e156fe,f8529951,86a9e536,f985c1,6a85fc32,d50e9a08,1550da68,112a5f17,91ffd66b,56ff0e6f,65d67e83,c362b853,a2f441ce,7418d091,5d5dd09a,b48892d2) +,S(32ba7359,84e13f42,d2e8a716,a54c40ac,6645a1af,eaf030e6,8242a8d8,8b456cc9,67ffcf1e,1c32b150,a82ab317,8ef24c93,f055765c,9e7e6200,f868b183,bcb4c6f5) +,S(cb9c2b3a,43d105e,518674cf,64d8b4aa,9c868b93,18abbddd,ccabc0ac,59829311,1fc67ef2,233f076b,ded3ac47,99c859d1,834bea5f,bd2bd5db,242607ee,842b691f) +,S(e14f2858,b7bf7070,32349695,e09bcd3b,5effa957,abc19e85,6efa31bd,2e9234f0,3e04e49d,d3f3fd39,883cbc25,80d5ff06,cf8cbf0d,4a895761,f3cd15e4,dce08bdb) +,S(156beb7b,1c27b8e3,cc78113,c97ff026,74810dec,58409e01,d7b7388,87550d82,c711730a,80216ec8,352adf2f,d5939991,3a8e92c6,c16c17b,16e27a91,90bc5371) +,S(de5ea7e6,b9b46864,4b80e495,9a2ddaa1,a24a3399,f8039355,7b798b5b,2c55d600,8901a027,e6a823d2,dc0a9d24,e182cd52,b9b1de67,22b7f7d5,3a03c615,8cd48ee8) +,S(8eddd368,8bfaed46,25b7312e,7b2bf0ec,aea07414,a1281ade,b79b9e3f,ec17c3c7,2db43af9,26171d34,d5ca48a8,9223e57b,59b885b1,5c4f7231,6d8edb6c,7955da7b) +,S(5c971b6a,665ad1de,8fa489ae,22237ed9,87872e0f,ef95eb85,fb2ad3d7,f0b1d4e3,4d71f598,37c2af6f,af32ff7,42ba01d9,aa8d4d7b,302d39a6,c4fc693a,5f8b1f66) +,S(edfb253c,28212b6a,d5b66589,a2a8f1cd,bd3586ef,34254768,85cfb70a,46b9e228,3e5b6608,b7e81f69,b8cb26b8,4f306292,594e42e0,25134c1d,7f7b2a24,b2616c00) +,S(4395f24a,e127772c,db163dd4,e22574bb,d2373cc6,b2c67384,737c56b7,dd525c13,bac6e725,4c800c2c,64896913,df739574,676581dc,1b4447a,819be64c,10103526) +,S(81100ad5,73a766b7,f8913b64,b5f5a87f,8c782353,5f62a3eb,182f0ff1,946866f5,52cac16e,325b0899,9d068f7d,51dd9d5,c6afb8ba,9870a9c9,d28b4170,e9a00c73) +,S(fd3a0551,41168146,6ae358c3,aa14216d,dee3a05e,e5ddee40,7f72347b,eb95120f,2af2f30d,45ceb12a,b89b7b88,b7e04b20,11a3c607,58ce7250,e4c7bcd3,da8ee5b7) +,S(17a55b58,a7eceefa,3ff05b6d,fa17d6c2,76d1a032,abd198fa,4e3fc3ef,e6435ff9,d7273958,a3ad67c1,fdcee72,e71f0536,418f35a4,57e06240,bc99bf71,b9574d4f) +,S(870cb7b8,e2ca5ea0,8c5c73ae,e15e8b22,793fd005,5ed7003b,c49b4089,3b789b6d,c33c8b40,7b701caf,26d7a9bc,e22644a9,4badbec,ad509cc6,a7b0ee04,1be67aa3) +,S(f951c5fc,dc46ef00,adc53c89,a50ca0a7,ffbf7c36,d80e4897,5452cc1b,4e71f8a7,6ae2f821,7849cc24,30864d7d,24df9e59,c1705b92,5792e648,75120738,c792c95f) +,S(aeb8077f,3b92c676,ae11bb06,a18ada3f,6cbd832a,1637ed61,31e4902c,96a0caf1,29f41d1d,f5d4a430,94e75fb9,8bf317ff,6c8a6d7d,b37ccfd,e0232e1e,afcc1e35) +,S(d46f4d97,5d2f2e58,6d18a7e,5d8587c3,8482b78b,595de60c,b9d2035f,313b78f9,95d781aa,3bdc1176,396154ef,31fee42,f704e199,4316e33c,1053491a,e86392f0) +,S(6afb44,4b4bd89f,2e21b54a,c49b9ec3,af810b97,73c76eaf,4f3a5f1c,7a29b201,3502901f,d7d3b4ce,134ed90d,1388ab37,64db460d,bed334e,af061822,6ebf932f) +,S(5f02e582,a38b1703,a7bf6086,9587af5d,e6634954,cfaf8394,932f7ed,ebd86976,a0487cde,92f3a796,b24b06bf,740b8fe2,ccfa5d0c,a2b68a7d,ef46a005,2d7afec2) +,S(26427482,60432ced,5a07b885,f354667f,ad70eb75,9c556e33,c6652d3a,a0599fe,119238fe,2560382f,d76ea737,9340453b,a63867cf,6e044c62,949f858e,b828ce85) +,S(6b2a3e5a,d327adda,52b19a7d,d5e837ed,4f03a5a7,e1e5b7ff,2cd66660,469f91dc,2f9f4526,6b482fa,f336560,1da9e945,354ed265,e8d7e57a,22f04bce,8a54c6d9) +,S(2588b88b,7e214fba,ab10934d,def13e8a,e5fbaf77,d7497dc4,fcc0345c,435daa79,3e5cf90b,d3ba6d4c,8d7f142c,ef1a51da,61ca644f,acba35e1,51ebc114,c5435bbf) +,S(d9484146,92852eef,fa8178b4,a01404a,e4e3d846,c20c3fcb,cff5cff9,de551a93,d5b0fd7f,e628c427,434a1219,6ad99862,13ea0abd,969864cc,dbb8258b,96a6d5a4) +,S(5cf81fdc,3a2f2087,cb64b1c,9b6f4754,5ccc1e78,67cee5eb,9fe9c4ea,3b0de2ff,e0b0ab1c,f6bb8e5d,f7ddc700,5ec73471,e7ff3125,daf113,1b78fb8c,15bc0d7d) +,S(41b4ef7e,b719fdb5,704b3f17,4132c694,f8ed2471,1677a320,3b866660,dbe879a7,a6fe65b1,cbae2235,cda8b459,eeac19a4,9f44c2aa,1c8a881a,e12093b8,3621c85f) +,S(43ed572c,41f691e2,a8dd1691,86404ec8,7a4c0a3f,406f3bdc,5c2709a9,bb117af7,b7b9e1b8,90b40334,6bacbbab,7be4d477,90a2b093,dafbac3,fd4d2073,fa481da3) +,S(4e010a19,223086a6,314bb526,2f1955e,81722b41,e85fae42,1c338e46,1b397de3,f0d3f11c,3475ed8,44876e7b,3bd0bb8c,283b44e3,70c46ec4,a6159a27,eba65fa2) +,S(b3609cbb,7fc86bcc,4dbc385e,81edcd84,45e15d2a,7d355e22,41dd442f,ee11f36b,8607e5ac,a3df34ff,804017dc,977bba88,c308911a,aa1698e2,e6190c8,dc9c5f68) +,S(445e60b2,543fbd3,7bd68cdf,6db1125e,d1bdd6b6,b27249d1,df96e43e,df965b4e,a5fa458a,8c4ab47a,bebfdc7c,f922e713,c65f8b52,287a65b0,b5dcf0b,c7715fd1) +,S(709f8227,9264c99f,86b59a7b,ef14c189,be875b49,e00cb64c,f9dbb643,10f50fc9,168027f0,cd28d2be,8a69064b,468e4de5,3d4903ff,faaaf628,83f15031,58960d10) +,S(62aa200d,cbd1240b,a252e725,a333f21c,8a2e9d5e,fbf18cdb,e1567ff9,29fb4ba3,19aafd6c,7017bdbc,4b906b46,843e41ac,1ec3282b,12dee1b7,b18e3f28,9e0a1347) +,S(2ba73958,8ed54646,fa9f2389,802e2ab9,e123987f,c881ae11,f38f10ac,b882c09e,f37daa1c,9c0a98ae,f86cc45d,34801353,d8f8a193,77518423,721f3e12,375a25a6) +,S(8672b9cc,e8fbb69a,ae5c0f54,9b59dfe1,e266e9e0,3592a397,7314e6f,79005de8,20d8476a,efb61c79,adcaac68,fbf9eae,c411e875,a66b5aa3,99a97a86,9b05af65) +,S(334cb002,84202999,79fdbac1,5ee5c17,1f32bee6,133300ed,a26571e8,bdab6ab5,8827d99f,3da7878f,46b45bfd,579c5cb8,e4e972b6,49d6438d,96e5a188,5aa574d4) +,S(32b30e07,d260ec07,354cad6a,2f64f81c,e9f25f4e,47bf1afe,602f229a,35ac6d4d,71ffcf0d,64ee9078,6f290418,1126c44e,5c5e3688,f3063941,85660874,3c3c0427) +,S(e5099658,7a4b4e63,43e401ff,299e9bfb,3b5ce402,5c38fa05,761e600,a39a8451,7b0382a8,65429a86,94eacccf,5c6b3380,683a3916,70fc7241,f132c465,b3bb2ece) +,S(b3872c4c,2bf539bc,e0aea035,3b3d786d,ca684121,29db66ab,d316e930,e5d6477d,7ce04af,e4c8c86f,3b37ed1f,a9dd4161,59391c71,22d0f4f9,2424d090,901e285) +,S(d2b56fdf,9156e3ab,2e414d96,49f4c418,6095e74,a2df8908,f3b406de,9935d07b,443c2c1b,67668c56,a84b4925,946a8e5f,b06a33af,371552aa,adc3b500,efe3b23f) +,S(f69867e,1074c765,923f32e1,ec9f41b3,4e8288fd,62b0a081,15db15a9,f37fbacb,fd6c6e25,2a11a516,9ce04c6e,d719c22b,68709be7,6fdd0e58,cd0505c6,413fca16) +,S(bc1830b4,a9ab11c1,ad8778c8,688fccec,cae23898,555b6579,62670d8a,b9e64988,b6244089,f3c46133,1979a0fa,f3d0c8f2,8e95cdcb,12db9ea5,b6d95ac4,c22e3c81) +,S(fabaae21,dc729fda,98c4bbe8,3cd5fb92,126cfa1e,a21f43b7,445e4b47,f38dbafc,1b569775,64465832,c73513b3,ed6aed9f,177ce1ba,b2c09fbc,c4c33600,582d8cdc) +,S(93386101,4d5d4c3d,f912497e,a248d8e3,bcd3fc03,216dd57b,5473d96d,791f8bd4,3d8fc96a,c141163c,4ff3add5,44a6ad71,9e57f22b,8e806d95,1d630fa3,6c936725) +,S(c5312d5f,85c42820,59546b8e,ec6b186e,da0a4324,d30147f2,94a83fe,a6fd07f8,f8ae6e2a,79ba0756,523be12c,8d544734,332898e8,b35b651b,edaf806c,45d2992f) +,S(a08f2496,52c52f40,6db75c4d,da022f41,b73b1128,11aa7388,558480b5,f203b057,a396c7de,9ab5e1d9,5e9aa925,1ecfe3ca,191d7a25,37c4cccc,845dc745,2f3eb2e5) +,S(93d5330f,e8df6fa6,a74b34f,a251a6,a036e0b5,89b8a05b,c525e4bd,40f634df,ca15faea,10f424e5,5d6774f7,7c87da28,c4df567,7d153a08,f5ac560b,71838756) +,S(4622bcc,dfcab72b,e850a994,1f652110,5c35b813,f05a4f6,17055f92,aab51fa2,d960702d,31eeb256,d25cd245,695b53c8,e883d2a4,60965a8c,d29b41e9,d7ca2d4f) +,S(a326036c,7dd885d9,94ba5872,8138c30d,fb6c83e,d17c8d88,7aee086,e0ef9fe5,b465ce69,3719a155,31caafcd,e7689a17,456a6ce1,c75e5a53,4893cd67,32cb9bf7) +,S(2354417e,19637e79,71b0c887,bfa5c553,f3d5e7a9,84a6c946,b1d20b5a,7eef77a5,815a9721,b6ead3cb,b254fbf9,9f34f409,ea740053,3cf4ed4d,2169f48b,29f4bd4b) +,S(9d346d6d,fc53174f,5cda746b,23810d7,3a407819,ddd5df9f,2b07cc8b,b7ce6fca,9b6cc06b,64293e5c,a55a8ff9,f1e90551,4a199b03,df08e9b9,8512b357,9776c806) +,S(73c82b8e,c643a7b7,f95f000a,debe210f,bba638b4,5508564,bb5a3330,fd48dd01,fff15699,a0885c61,fe35f61b,84cb2bda,7d2acf5c,df0d6f07,5fff1369,805b614) +,S(902469d5,a0b2d5d1,cf931672,88506b95,f2d29bf,6ca291af,c9b39cbf,fc798ac8,356d011,d71c769d,342378bf,fcafe4ff,cd78addb,abe8b0d4,fa63de89,1fc3ade4) +,S(e670a0fb,3a0c86f0,53523afb,819b8944,dc4013e9,fd500371,b1efe23e,1f110637,869136b,cd13dcb2,157db5a3,d07e59ef,272557e0,9dcb250a,9bf659df,260b31b8) +,S(f3fef06d,526581e6,b0f68e27,cfb9cc9,b57f11e5,849545fc,b9ad3d5b,8a05c395,32b2e997,144420ec,c4c45176,efa5fbbd,570752d1,4b092f4,ff375544,19b8f553) +,S(72a37663,3958d844,560fc28a,8cc19d88,f942c09c,471d2cac,70ca5d39,396a05bd,de9b1b0e,6e121070,f684b3b8,402e8d8d,729ce846,d2f7ba8,503f4548,735ee1ad) +,S(38b78ad9,c43b7def,4119c3a8,190cde68,4172894f,a84cdae2,2b637bd8,805300b0,a181567,6c4f5f51,87204f17,5bff32e9,de7cc69,dc851c84,23de74a8,b3d01e6f) +,S(db968ac8,1d2e7c53,6c66fac9,e194fb23,540e2e89,8cbd3af,68e158ff,2b34752e,4d5c57ab,79d9972b,ac6b4af0,a6347271,4179e8e,fd14c769,a24e5a73,aab48a0a) +,S(2ace1679,2d3a4d83,71114f28,c1ed35b2,505dd4f9,97c72435,a145d367,a8aad318,5314312a,246874e4,cec63b87,f685f6d1,405b0ef,a1ae3539,cc88e73f,3626f625) +,S(32d80e69,c390ded,db8a4600,862727c4,bb1fda18,2563277e,852f93af,3dbae108,3c7d96f,ea89d06a,6d3cb3f8,181f7cdb,bc1c3e12,3d9f1d08,cbd557a9,60dc7c07) +,S(3ef49e8a,e7fe6b40,628e61a2,945db3cb,f1bf050d,e525d521,d8e8a408,76ee3908,4381c75c,62f45fb2,4d431b54,d63115af,3ff72d27,58c3c92b,d3d1de08,1a123f2) +,S(853808d5,cdb82cd0,39b517d4,1c88d7b0,e280ee6,59e5c640,5aa27542,3c9722da,c1677c44,9b2a9626,698a652f,81722242,3ed18d03,92d4200f,b4dc229f,5f7e8f5e) +,S(572fd483,490c05fe,857520bd,8861fccb,306ee4f3,29adef49,58c1db78,1fc8584f,82acc906,10392302,cf0107c0,6b3b6194,d38e9155,b31ebca0,be300036,3413f4a5) +,S(b1cbabb2,9aa8ca31,75aa9a2d,d4d956e4,fa771344,d4592481,38c93583,376e1386,888cc0f1,7f9afdf0,6ba1de03,41409c1,265cb2f6,c015fc,bc58d2dd,66292ec9) +,S(f856cb92,42393134,7580a65a,149a6e81,2c5c960d,670701a1,6ddbbb98,2f6bab20,c33511ba,192c00e9,991f580f,65c111df,77d9d6c2,d5d63869,c5595011,48536674) +,S(e1601cd4,773e129e,2c042887,b56bbb3b,9eed92fb,6c128e23,fffc3a7,ee73920e,180748c8,a38c7796,ee247c71,49ba1fcc,a78648c,a0508ec9,6f4a016f,301054ca) +,S(98ee20d4,5ffb6177,5ca206a5,b0cbf1d8,e8b37cab,97489534,a98928e3,367c7e72,2df4ace1,ea42db51,68ab5e6e,88fc405d,854b70e0,4521bc30,6978e465,6273c610) +,S(4796ca57,acde905a,31dcfe95,bedd1e13,5417bc41,f5acc246,ec0ad4ee,ddfe179f,7413f522,395a3802,b37637e5,9564c239,5bc565a3,463f815f,8ff962a1,f0a367a8) +,S(b367c864,38adb0b8,d5b627fd,56c7df9f,cfd55536,9abbdd40,6c68bdd,1a341200,c0364744,b99e816,7982f365,72268702,b4986cf5,c9c5749d,fd22499e,2e8fba51) +,S(db36884b,723ddecf,7e2244c0,20de844,e740760a,4f27d386,a747f4a7,88914d29,8ae487cc,2a743a3c,2a1e0750,7def0f2b,fef90e24,fda0e3b4,e5f3333,7d79e023) +,S(65971818,f71c212b,a8e45821,31eef4f9,76b4732e,6c6c3123,ccf5c6a0,99a316c4,415f6791,353350d3,3b087f39,13761119,526a2831,c70375db,4cd07754,e13604db) +,S(f2f4eb3a,13a8f4b2,42182a63,97eb6cd9,9053903f,961a1338,fcbccac7,60ebd65a,a575d67b,667e94d7,20adc8b7,4eab8ebc,18811b3f,3a3bcb6e,7950cafe,8ef9ca8) +,S(a24e7a0d,a058f0c6,3328fa51,fd3c927f,884b3f77,cc068a47,e8c6b4d3,1d113a49,be8db830,79aca569,9eb2fe3f,829719d5,bcee615,645e4c81,a9a7212f,450ef78b) +,S(e59a3ccb,77e11797,7db6cc32,5ebd5981,42212da7,48f0a4b8,981db72,41efad5a,a8e07545,fdda2668,cc0a10a2,2389a2d8,d6903416,a4a05299,9d4c2d4e,4a800d9) +,S(3191b263,a3c70be5,bec721f9,3dabe9c9,fc6c1a75,aaa94e9f,daf6060,fe4b8f32,339192cc,1c7a9bc7,2a9a87c4,ea3cbab0,c7af7b27,53e74491,717b1f99,5df38a96) +,S(63dd5fc6,4f9ddb0,8fd47e27,5e839b20,12f408e5,3c139463,8b97874f,9187023a,1af048b4,2e8b7e6,d456cccf,d12ef7ef,67e0910,4162239b,84f35cbc,8504bd9a) +,S(a92e457,cd8312ec,cb87229b,7f751c4b,2e1d8640,c2b8e5c1,2d3dbf4b,671bcf13,d7aedb56,5447eb5d,18449241,3a07d672,be46ab4f,3d5b4b3f,551f292e,5ffba768) +,S(1ee6b970,b9e09d22,2b20f02,14f00bb4,4789f55e,585f35ba,6c0dd6f8,39b10495,7c910fec,eff9eef5,d1a3c8a0,46252885,9dcf73bb,d4a0b2be,3f8d10e0,dc9e9462) +,S(b19c23b9,c2ac1957,5328d7c,43d04870,1abe9e97,30285ceb,e4fd1659,8f06a76a,79a811be,c07c8b70,6f380f8c,fe369e45,c605607c,d08c8a49,2745b283,37a38398) +,S(3c20db9f,9ed35fc2,7c0888f5,e266a455,4f3fbf98,b8b2a016,b1e9aef3,14f49a5,bb3ac294,3f29e63a,f610815a,4a1e5a12,9327c1b5,ccf489ea,7d8950e3,5bfbc4d5) +,S(fd1ccdba,b4746e9e,44eb5904,d338244,efa29ffc,8ce8014,f6b922c5,2eea4389,e1065546,52146f90,fa52439f,c43ce4eb,73961a52,10f6c040,97a82032,9a8df06e) +,S(e30fd18e,abdeb8a6,ef252dc7,3c2b0d75,83641a29,8db37ab5,1e2da099,9b64020c,49663672,1824f481,962bcab8,6716eb41,8e195d29,6afe9704,cfbc24c1,28dce88b) +,S(4bc1f789,26ddf930,e1aea784,83a9dc09,5cd72300,5540548,e6e217e7,515bda37,966b32b6,95dc1b00,8dcbfa2e,734bd9ab,36d8a26c,2a52c471,63a4cfcd,d200ca69) +,S(23d3e27b,9c864b8b,40f0f7d2,6ece9bc4,9004f98e,d46b539a,affffea1,54f036d4,be4617eb,f680a27c,cc4143d6,ac150d51,b3dfefbb,2892a6c7,1b36c794,8ac0b05d) +,S(28adcbd0,14cd3b70,f46e0a89,477b5cc0,4a513091,cb6c1aab,56de4894,3e6009c0,7c49a838,75204cca,38f250b4,608cfe4c,25040dc7,3ded4fda,f4a92cce,fce31601) +,S(776084b8,a86f0823,a5044ab8,70d84f60,ea52ec7b,a545ea0c,c86f219f,1ca29d08,60bbbecb,1048d250,b410bc38,49e567db,def17272,58570b2c,d0834532,581c60db) +,S(45df2e0f,fd32ef48,95d9667b,c6044951,e3db94b9,ed6af5fb,d4fe1e7d,228f2350,a732464b,1a8cfe06,69e4076e,d4164b98,4de155cb,68bb3994,73fd7918,63eaf095) +,S(6904976b,46a5fd1f,a74bff80,c493a2fc,8ae9bbe8,783cfebe,7f69f0e1,be7dd7ea,19d071b8,df9d1436,6241a22,1a00b340,30f1df45,5e66fcfd,5ad621ae,ca2c3e64) +,S(849d8728,f977d075,a8de805c,8e80980f,e01def35,1ee80f0b,ef528e85,29aef659,d84955c4,6c886283,b9d7adad,bc069d0d,8042dd9a,ec7246ff,edf31594,ae5bf428) +,S(e3d64b4c,234506e6,e7facec,8d7534ac,54588dc7,ea685281,e27c6746,472d58eb,4a32ad3c,cf822a84,74447baf,68aea598,11a9c839,4c9970ef,bc61f363,ae5a36eb) +,S(f41c7928,57d15a31,19b6f132,3b67639a,889877aa,e9213ece,c787d53,5463bbaa,73cfcd0e,c84c55,4d007594,152d9ddc,630c458e,7ea456d0,7cc60503,794d9328) +,S(e1d21747,47ab84c,e47a4a02,caed939f,e0cba1c,41e7b21d,67f52fd7,79186079,17b0b628,aa4bc0a3,ed9728a3,e24a8101,fb26da66,9ac92f63,af81aafe,7db2b668) +,S(a8a0018a,f8f86795,3189da2d,d52b4db0,5d7ddb4b,8d290c80,95a8e7dc,d86ef1d8,8bb9606c,84b88a1e,df980c7e,9360823e,25b927d7,9cab4c17,fc8aba7d,6826518b) +,S(7383c671,6ee05e44,daba57c0,50ebda60,e4e0c0e1,3df338f4,cd8d627f,736fffed,3bdcb946,5f164a74,638cb973,fc77daaf,38eafd48,9521cba0,4ad896c,8e89f0e0) +,S(61fa7e1c,8bc8ac97,96be6431,20858063,1ca36af4,520cc1e,858f90b,ad372dfd,3f0d6768,36c3e694,32287909,c8841de0,a5f646b0,94b0c207,8d634486,c3eba33d) +,S(86029e2b,ca0ac601,99092def,cf4882a8,b4f14349,43bf116d,3cb310a3,b2c4a740,b8be906e,cd9056f0,f3261cff,d12216c8,ef5f1553,dd708480,15463b7d,241c2f7c) +,S(e172f7e5,912aa487,589d6c4c,d0d6b9ab,48c4a6b0,5fc5f90e,2f6474c0,4fad95cc,edbd23c1,2b0a0ed3,b899920c,e8b64d7d,d7bfd79,5009c290,ea0673dc,8acc401) +,S(7986ba8d,322efc24,8b7b22ab,f838de93,2d931c78,cd6a8616,d1f37dbe,32873494,693eab22,4c750592,319b7544,d29fe0c,2420a5d3,d3b7e01e,e6ebc968,12a13634) +,S(ba594138,4a727673,7600a6d8,8d36b133,400bb5d3,6a8a9d46,3e8c65c,e1e00383,746f4e28,bc1b812b,227fc953,531058bf,d9c68545,2f6219bd,86799dbf,3c2ce557) +,S(45ff41c9,92d6b117,c86eeb77,bb17789f,6bf96cd7,2cf0c6b9,802af869,20476c8f,9324f5bf,6422e3ae,2010c9e1,27167d8,4f522e86,87fc95cb,ec3d6972,2002b59f) +,S(bad79e35,487a4da0,7171c282,e8666ed4,d00bada4,d9576a7d,9a93ecc3,c16ed68f,19397a2e,efb184a4,31a02e12,91db0cd4,5b153517,9038a920,7a6d50dc,787b57d2) +,S(ddfe2107,2d8875ec,60c4d583,59755bfc,22cf890d,d3665b79,cfa403bc,9e3c8a41,c62bd917,491d0a8a,9215674c,28c28872,8dbe0d3f,87c10d90,ce22b608,473f62e7) +,S(925f6a53,c07f923f,968ccadf,bef9d95c,d7594269,a3d9fa64,b1180edb,667eb299,1080e8ff,1f918e6,6f08b26b,7f9cee48,58f00038,b8ca50b7,b2939960,b1e7809c) +,S(c28e49dd,a75f0283,38e5d2c7,d1f03af0,12768bd0,6b0e0d0d,87878ba8,2720dd80,670f8989,c941a49b,cc512c5b,4987e167,ec5ae6b4,d7f68a98,331845ab,5d0db12b) +,S(7a9053e,95035be8,8188c196,d5e8e05a,b21dae48,d59406f3,7b9f86ca,2c837cbb,40ee088e,8e7694b7,994774e7,9d097d76,6de026f6,f7fbe352,e7f2bd0f,443a7e1c) +,S(33af78ea,bfbb00c5,4d88ef81,e9661b16,e0b32c85,a1b61b95,6c6a79fd,e036aa2,713e7aaf,537a796,c4d79644,c855d0b,15331988,5ef4629,d8048c69,d3cfd3c0) +,S(c588d014,5a3f3d33,29695573,96d674c3,1326dfa4,797d63d,f9a0c720,49583bd0,b5c0cfd1,6c67cdad,ababaa8f,cfd2cd76,7f747024,8caf60d7,37531c66,ac53cdfa) +,S(96b3d5ed,b93742c6,7c48ef12,c649341b,97223f22,1f0edd5a,2f2ab523,8038d29e,db475caa,38a3a05d,3719a2e6,4ce7b4ed,bf25fe57,4b28d6aa,9961ec0c,b0e44c4e) +,S(412f4b6e,3d894ee6,fb0cb00b,14662a9c,1eea3a42,5a286782,a62da77f,5644f0c7,a84ef636,ab9bc805,bffde813,93874429,a8503e89,8c03f1d6,f139af86,f6a676fe) +,S(25f0a785,c7b43028,52f1421d,a32c418d,32fdfdc4,89c39049,3794e1fa,e4563252,efeb090d,457190b5,89c953a3,aebef406,da716af5,1dc6e334,a0226883,6004e4bc) +,S(50fd4ab7,f367faf4,acb4403a,49ea3e7f,f02fed58,4327acfd,e0bd58a4,ed741c6f,78abc1a7,3c9dcd48,6520cb52,adb1c3a,2d08abcf,a079607e,a56307c6,3d46dd5f) +,S(157583d4,cfaf7f79,33b8fa66,430f107e,c357621f,4b94f313,bbcfbed1,46a477a,9aa6b235,ce8cd1fe,60cd4355,c46d4859,fe35ed8d,659d2aaf,fc09cdea,297e8db5) +,S(3c44bb62,5d262603,e44affc1,65b35976,f2edcedf,8be6b494,f4b3bc4a,5b3300be,88b1c561,67973ab8,5ecd4594,90598152,1ef0e8c7,1ff707b9,79ec2bf,3cbc2535) +,S(31d4264d,e1606b97,f2f71d19,33f23cc4,8fc5d9c6,e087dd93,5ee25b8f,ba298958,460609c0,a3aa1d26,2865180c,98555b98,c8e41db6,2e62b2c4,4ae01190,718251cb) +,S(1f551f0a,8ff14724,60ab206d,3dc1834b,352d1d1d,80a8fb78,a87247ae,5d03ad2f,24253c06,a4c8b148,db944f81,802bee34,fcb97ab6,50957b32,eccea33e,c116a6e3) +,S(de2c4e1d,27f08407,31334311,9ff5a8c4,206a1f73,2aaec3a8,7aab6bb5,c1cf333e,dc813ba1,40fecd3a,31ff4a8e,41fa498d,9226ca2a,cb2d5a71,c5a5cfe2,8195170d) +,S(6fdc5db2,adf54ac8,132c4a22,c382c2f0,c1f54bd1,8aed5620,a54bc4c1,18a95612,db3fa4e5,f318e94d,c0c11053,61d21643,cf60b0ca,a6dc4d26,944e8915,970e221e) +,S(c7eb76c6,ea0e1c51,a3aea6f4,dd7eba10,bb76650d,85df0fc,7fd77b73,53680603,5ae1c1d7,b788092a,3c41c3d,7bc32ef2,a4f4a39,a82b53e0,e6f47712,df5bf655) +,S(c81505a2,b7e78b5b,64ce048e,6312bfba,1a52c7b7,8219d857,b4813a98,c8aa89ed,46db2842,6d6ce211,5e1e49be,459f033d,c222be7f,96b247fa,87d5dfc0,df096806) +,S(cad75255,15f9c3d5,8705ff0d,83ac3508,f7dec312,bdc71c9,a17eb9e,78503bf8,32b36a02,76cfdb97,ecd2ddc7,638e4d61,6231be5,25b6b4c5,2d19c12c,6e6bd719) +,S(94d22144,e22b7e30,56eca8a4,7d6b15d8,f17f3c65,82533fab,c70e900d,be4cdd25,12c0760d,5fef2f85,d89dfbbd,bd0124cb,828bf72d,79b4ae5f,6121a84d,47d93bf9) +,S(325c5c23,ef00601f,ddf52040,7721bde2,13cba19f,c0f2e225,3b112b8b,916731a3,59d3cb98,c09c1643,993f3dd3,64c7d29,5cb38cb2,45d8f70e,9628e5ee,d62498e0) +,S(9c907089,544b8316,4a251516,81bdfda6,7d187438,3e7f4a7c,da96d861,91ee2318,f639dee7,e7010630,364539eb,5c225059,547117de,9fbe4911,d9718e6f,8372d20d) +,S(34f14807,ede9c06c,4cb2a1d8,97a4fb81,ec5544dc,eac1bfc0,f32f9835,302b7a82,78437a8c,ec6aa228,f5f18813,a68bde68,3c54c367,5d6be482,8d01f2a4,96d9c57) +,S(9498d30b,3f080828,e03d459a,fcb81fdd,490b47ff,c344d75,3887b600,1639788b,7a5c8305,b97abe3e,b241627d,c5187a9c,677865b3,567cfd2e,ce136852,e42522f7) +,S(eba08f6f,efd36e37,aa53ec32,d3cef88e,5d4f36ff,ebb978c8,76d452f5,7754f226,fe0e66b5,43aa54ca,7afeade9,b38cbe0b,39e17178,4d029470,608c7e38,bd2015c1) +,S(555d4bc2,bd21729,f6119b77,ae8c9bce,c8ef49bd,992cde50,4c794484,7240091b,cccebdb8,69521e33,2ca86941,593eb4a7,6c9052ff,a54f8315,d30119cc,7f437b54) +,S(33729b9c,19da3474,42f33833,d1723d45,3f3060ec,c692d823,679f087b,ffe8872,a94b6a4f,283af604,eb885405,6bfb8044,fac2f007,d7ebc800,b4abd64c,5c34fc30) +,S(2a1a889f,afe64678,647b060a,73ab92cf,78124ee0,d44c7c32,d8ae15e0,df1dc11,626f963d,3bf11f8e,686ba46b,e6dbbf0e,75aba0d0,7ef91218,98605ff3,fc8b75d8) +,S(4702854c,a303e6fc,ffc62f70,258bb2f5,639148b3,4e3927ff,f2dbcb0b,7c197d6f,7da261b2,8513257c,d1475c2d,e059372e,2da76eb3,f3b2c51,95c44447,d71e1156) +,S(7002edc5,a0cc23a0,65015cae,6e49e7b,51d90cfd,7da04e03,4857c596,cd319c5b,6f2845bd,6b7aa58,7ad2d2ae,19fd6115,78c47b56,84fc6975,db63e230,c3db73bb) +,S(273294d4,483d610d,b2169f05,71d5450f,f4cc5bc8,725d8ae6,7c1adf0b,6f48d485,99b241a2,ffec9e0,a039a003,18239aa2,a71e3cc1,1cfbb6d3,7268874b,67d942b1) +,S(1beccf82,3055b440,fad26a53,5a852a5d,710c72a,c4d28e83,b0335e8f,e98c9a69,f3ab566,ac0eee20,7c8ce0a4,d471eac,2c5db716,5e24b489,e2fde03f,7b8aecfc) +,S(dbe4eecf,4f033d53,5d949cae,c8fe672c,a1902323,77892197,fae8e192,53128160,b3f50bc7,927f0e5b,56241c72,24960fc5,896fc806,1c0a8a1f,5fd3d47c,d5aa566f) +,S(6643fc75,bed80c69,4591887a,5dc573ff,caf7f484,b0ae2631,133ecf4a,39bd1e20,4701285,f7ac7c93,bac1875f,dc4a26e3,8ec1e69c,293c3b7a,1f8b5c5f,878d58e5) +,S(99f90bde,cf1dcd5e,7158280,53f820e7,ef19d936,bca63f14,516342fe,5422a21,a04dfd30,6dfc615b,5390a86,8bebead6,5cfd7719,33f91e2a,180d2d79,b99cd4fd) +,S(54e7ce48,3184b7fe,45fb4e35,192b5678,bcf71f7e,49c033e,aad1dd32,86e33433,cac2833b,65ba9cb7,83a8b85c,b7f4e4e2,4d4f8546,3c6a2c3c,4decec88,14c0e8ef) +,S(cf864a4f,fb60993e,444f4e7b,8f4a9973,4705aa16,295627d3,1f7686b8,4bf02e08,7a98d20f,b736eb4d,465db874,ce98bdf1,6b8a1951,7744aa51,af276c7c,db6f1bde) +,S(6ff160d6,516fff91,5ae2cd45,7a98afe2,a2569345,60a7f26,c9e07212,6d59d1ae,5d1f1355,bf1410ac,e4f8b415,350f9c75,7db5d5ed,1f34de,aff5c197,b4eedc4a) +,S(9adba62,aefd2690,1d77f2a2,c6287da9,a56fe35b,3702da46,f231fe4c,9f5dfcc9,ba58ec45,cb4a359b,7126af,fd2c4bdd,2e708d43,41d96e7e,4825f153,abb04161) +,S(204ea41e,bbdcdc48,cd4ea945,72c10dfe,b5d90060,e9dcf5d6,52c0e2aa,14a2402d,7b2889ac,a1952f3c,b2c5db8a,9924a6fa,fb0b9e32,3ec09809,789f780b,ac36ae38) +,S(f7d6c669,364d3114,225a6826,c20d26ba,a4b4f190,e842696a,82aace97,5fc8ba22,15abb177,b42538c5,67d160,cb3c761b,1ff47cf4,4b0cbd16,36f67a5c,879d3470) +,S(7bc4d30a,87dd28c7,8b066e00,c02bd221,e50a7e64,45b57f0d,cb466f27,7d352587,f4ed4854,2e7e0164,da66e0c9,fcb04a1e,6efbc9c1,206b552e,c68cab96,d0c294d4) +,S(55442584,b046bee6,c245dfb9,59f20629,c200eb21,b42509d7,8564943b,1e316ef1,2e2aa971,c8111ed9,6666353a,103f2e4e,a29c4162,d19da280,905031a9,48580d82) +,S(8e7df8c0,de88903e,71224c97,3a8ca65a,923f872,841f2dcc,bcd69e64,b1dce1eb,e4153083,9ae86d51,e7147873,f1fba8db,c31205e2,34c94662,52ae43c1,25d2a0cc) +,S(672321dc,69d8aa18,25569d06,65fae079,b84a9bc9,35bda491,5d546f51,c651de8f,8ad6430b,8708897d,be809ab1,803a6eee,f977b1f1,6b34c188,d333d6f6,e7ef005f) +,S(f4e2bbc1,43e99b00,52032718,285d7698,1b8beb9a,f693dbfc,2d20f472,89ac3abc,e54990f5,dc330eab,2e722b7f,70cd426f,6d80e93e,205eba89,7eabf0b1,5d651a2a) +,S(5aa3aa5f,c6d2258c,907c7275,805c160a,72694f46,6b5fdad8,9134f1,d39ffff,22d72170,617eafa5,b843e82b,5f670cc2,3146aa98,cb07644a,7f4c0600,48ea9531) +,S(34752ff9,d2bf499a,c6b3acbd,1b78633c,9e9a31ea,45c34383,be3eb008,7be2e7ef,b53ea374,2cf3d886,51f7d076,3f67c8bb,39d73ca9,8306bedd,91a6db47,2c1104f8) +,S(d6502624,2ea44f7,d9b4c9b,5069e1c5,88977062,db2bad6b,51735366,27047327,52f5c99a,f2f2a8be,c034db3f,b573757e,d8014321,86db2c28,8c7151fc,4ab16f2d) +,S(52b3aec6,553d025f,d164a0e0,b1f39abd,915d4a9,ed5db2ac,b4593c30,11f4cc9,51547402,1c17b2bb,9d401683,931b25d7,77af18bc,e0e7bba2,432a7717,f4e2f8c9) +,S(8cbb677e,f7979224,12728418,68b79c12,eaa0ec6e,ba4f9b17,4d99547e,827ef9ca,a32809b8,b07e1312,b6a40ec6,411b60be,92974f98,bfedce19,ae590f98,40183f2) +,S(d8f55de0,e2eef17d,e94b1564,d74734b9,3f89f2d6,c317a248,7f1724e3,d531d47b,e9fd46f5,da576370,e0416f71,f271e64c,fa7dc64c,5e086930,523e92c,9ab7d770) +,S(fa6fc9bb,faa2b31f,f9d57301,4777169f,a4ddb8ed,ed4bab79,d0f4cf62,356b6fdb,b6ff57cd,dfdd790c,7aefd1e4,d4b111d8,43a2adcf,9f781b33,1b4420e0,f57d494) +,S(239f028c,e748edd9,69f752d9,abad0498,f9359017,653e6ae6,bb93f09d,61b58e9a,17dffeb7,8831f6ba,7ba463b7,bb7b142d,d55c8aa2,91bdaf7c,644e8ec,14f8b516) +,S(2ef6cbfb,728d976f,99c71db0,5389bba4,ecad3c14,8f2597bd,99af8f74,965e4f3b,19a27ba7,a382078c,3f1ebe8c,1d93a37b,deeef542,cf174273,b411b60f,79b0fd00) +,S(972d732b,9af8315e,88f042f1,3377871e,1a429247,d8537436,98b975d9,33064a0e,308153ba,ba4c3b87,40a380fe,e4bcbba2,a5c2ae3f,25fde1d4,f40af4db,aa4fd28b) +,S(3d378b34,ba4998f1,833aa295,185414be,e788bced,af422ed3,3c4f2747,6e062a4c,46a4559c,9217f919,80887b50,29f75c01,3c3d5238,d3758170,93eda1a8,f2c4c8a3) +,S(fbb2003b,1fc1b3aa,fd32b289,abe3b362,b13d70f2,7d6451e3,76bf882d,395c3087,97c866a5,c462362a,4ceb96bb,9c17db03,f28e5b1d,4e418a81,653a315c,4dfdabd) +,S(28fa94e,8eeab1fa,bd27a9,258e26c4,295efdb7,afb5a47e,6e14de8f,877a0471,f7619d0a,f2eee8f3,c0c7b5e2,8ce9d0f,62221919,4d1762a5,5145a909,9d23276) +,S(4708a285,7eb9c115,71627ede,6fa8fe29,4be27233,8798f25,c12cca0e,f9308ae9,f35f9964,2e773990,b2e0ab60,1a92cf56,85403466,87a8c35,50e36b91,ca4fa449) +,S(93408097,6ff4b874,d88903dc,b3ceed6e,a82427cb,36b62c6a,6364f2f8,9848a62f,e25a6962,d4e26764,9ab2d4fe,a0babf7,daf64d48,98bc60ae,ff3cfb63,e95f3c6f) +,S(f4a42ba0,818201ca,e3195da9,3a566623,9e0d24dd,256cbcac,3959dbc,720ddf9a,8fd26fcc,be3eff0,75d194af,e7391285,10bd4c8e,7230f96a,60fd27e0,a000f86) +,S(c5ada616,e65bcd40,cf39ef6,197e0a97,791cacef,b41b0991,9c51b166,e3a6240c,e4c65d68,fe41c62d,c85b0b32,39106ae9,cc26787a,60d351a0,4a7008a7,f96eb8c3) +,S(7c193ec3,d3f1d91b,cbd7c62e,5061a5a5,e8b1fa48,561102ba,ca2ae100,80c640e7,cc7cf895,511408f3,e400ff31,8a53685,3b8e068,1d4b333a,26b59cad,97873ccd) +,S(77542543,8e7cf128,32165629,3e6a1c19,22b76355,1ec716f1,d96002b0,ad1bd3c3,3747169d,212c37be,1906eec2,8860af9,edf7d932,c187c4,debbf800,8bd2137f) +,S(92dd5399,fa75e786,fa5c0f7f,90abd1a8,bb48ff43,e54dac5a,3b9990f6,27d90992,5cb1be8e,f93783e0,c2e5c824,ac6c5348,ee493231,9932e9a4,6e54921,3f11b7ba) +,S(c1770828,468eeb90,10b55053,2a532fe0,4f66e7a7,b7a1cb37,6eb6ddef,d693157d,da5643d,a0147d47,fd29e262,f61ae4a2,70e5e9a,77a76bc2,d2e7d24a,819a2e11) +,S(1372e116,e90ae522,4649a534,111392fd,a8baabe5,be8a8ad5,33cfddcc,af6378c8,5efbd4a2,695775bb,dc38c2aa,f8da6f45,1d0a1cf3,2bc584d6,e9b2b6e5,c8346af9) +,S(2bbdf21e,9fa1a2b2,bcd52009,7f30929d,5e2b7fa,e1038c00,8f32d86a,65dda936,51b78998,6008bddc,616c0dcd,2a883361,1806ebcc,5843b64c,b0ba02c9,339d45ec) +,S(36694ca4,d0495ed7,78230d49,e6f21217,9b63cc7c,26ee3f7f,6a7438bd,753005e1,2e49e3f3,bbdcb133,3ff1e17d,b18d5267,a87f48b6,95b5f907,5f5aa0d1,70bc0af8) +,S(243d84b1,dc9ce143,a6913bf8,d13c4aaf,6fbc1373,6bb8a7e8,5e648958,32013b8,39317ad,b6bec71d,ffe3c2dc,6dec5e10,21a3dd83,2dffeb91,108abd5b,6e7f28bf) +,S(1d888387,5255f3f6,838eab82,1a12a8fe,ba6dfde,f190585d,e039542b,2d91ec92,a9d38be2,e919f815,5d633538,d2f0aef3,9ccabdad,dbd912bc,46c2037f,3324b489) +,S(39a21f75,4c0d3376,f7560e2a,a743751d,5512d628,7a480955,6456f9ac,b1be3765,3cf324a5,2a7fd79e,3bc188c4,d55bb449,ef4950b1,3a4531bd,e0b2ea9d,4035e005) +,S(a10ff60c,d8e25df2,a1d394a9,52c67f6d,18ab0a1f,a56569e9,48d9278e,b42e21c8,b45f2d63,3ce82ef8,1dc0c0bd,4f891473,89fd2b35,f02cb237,bfd4f502,df9e991) +,S(bc269792,d5042f7,1051f7a6,46b971f9,bb801acd,dc24a2b2,5bbc459e,b7bcbcb1,b70445fc,1c032061,61b01530,c9205d7e,c7fab6de,1d83f1f4,78b35bd7,71235665) +,S(3d7279fe,fd5a3682,a82a7f95,d1db4442,5f0ef448,f6bccda9,9a61c240,9037cb95,df5226ca,e6365b7e,22b42cca,2ba2494d,9a2ea193,cd92162,2de6602f,70159740) +,S(e0c56d30,ef92af00,b936c2bd,951b3d51,bc439ad0,e4216e2f,d552c2d5,e8dbe588,c2bd177d,2a75c44,40dbd186,27669a0f,f35189c7,a4873e0f,6484b3b,68555fee) +,S(9bf960e5,2b7bbf52,fd839830,634baf1c,f0d6e332,4272bc15,d9999ae2,7873315b,b28719d,20e01dcc,b0016cb1,6a453739,551862f7,d9cc81c9,6662387,1d8d0405) +,S(20df196b,e60ba71a,e617a6b1,44757e0e,87fffb45,d447d9dc,d5480a0,34351198,9c722d43,c0d071b,a07d4953,9ad0abaa,f12ba358,42fee0ae,9960ce1f,26eb07d8) +,S(843c136,208b40b,9459693d,8154980,455a5f71,23b5f633,a26661d,ca9bac17,d5b5bd8d,9095fc40,d2d1820d,31dba542,d0c74f23,86770ede,c9b4df46,f2f12078) +,S(9109b4df,702c1ea0,dea4ee0c,ab46d6ef,708a3fcb,72f9dc03,e05bc722,408d11a0,75baa2c1,8be5801c,b5315195,4c2c3024,7348e9c7,913bb242,cf4ecc8b,96dc507a) +,S(f10cd1f5,c960a9bb,12adff03,c203c59d,8e51552e,3727edb2,329eef3c,5991113c,a84ac8e1,6f65daa6,16574689,8fee662c,9d2e03c6,4796151b,8f3f0bf1,5e8c465a) +,S(9f07713c,ffd3602f,ad077b69,a8a5f539,ae0d6d0,df58ba07,1eafe6ad,10e747a8,adfcc873,42b59083,cdc3d735,782f8ec1,cbb4ea3a,57970afe,58cd5e5c,8fee867b) +,S(6d1d9d0e,32905734,13b2b870,fff8978c,5ce9ec6c,b120d9f3,64063342,cd95801a,650be4a8,95d3b602,4d745f7c,23bbdce3,25a3f597,922e50ef,ba154f8c,6831018f) +,S(497185a5,6b3acc94,7a27791c,7e1fb149,5c649f99,dc767fa7,12820cc6,6cdcbd82,7d511b7c,11dae1b1,7e4078b2,fe7565a0,f33ce5bf,74181c3d,f5b6a951,fe6568c) +,S(fff738f9,848eeb9c,4ddb8bc7,52cd87c1,9a35f7be,14a470a2,c3154ff3,100a743f,106b8a55,cd913c97,76837cdc,f45c58a0,211b979a,17085df5,7bdff373,2f2c38ec) +,S(320391a4,8d3546cb,4466876a,37d60015,41899ef4,5dfc8e38,ccb9021b,981b4830,46f63030,b4559411,e742f303,25707b4b,23fa2d7d,e633800f,9c71205,6651b102) +,S(be44ce40,a925e88d,26937f7f,b7631f18,55879106,122813f9,adf16e00,5d85fe9e,1755ade7,d22e6dc6,7e6806d4,bf44b6e2,ca6948ca,9a418893,24db0266,2b6e1dc4) +,S(8d3f06b1,58ddd609,f83b0531,466fc2a3,da6aa80b,433a92dd,eeb20435,cf33ddae,2d554a99,efde513b,b8b6e5f4,dbd2e942,f1d0a641,98c3df2c,4c74705d,4b37af63) +,S(f814a79c,f258f553,255c1cb3,a054fcc0,d0c71d74,742b6627,210ea846,91596729,119fc95,be48b4b2,23c80c42,fd1f3d45,271ce8a,edeb82dc,31813f75,a32d867d) +,S(95e8fd46,1c37f1db,5da62bfb,ee2ad305,d77e57fb,ef917ec8,109e6425,e942fb60,ddc28b1e,dfdbcda1,aa5ace31,60b458b9,d3d5b1fe,306b4d09,a030302a,8e2db93) +,S(c06543fc,47e18816,bc720604,cfc20826,6f4e5cc0,f436e149,e2dab0e8,a7981e77,22070465,f3a4a7c2,1134819a,c194cc9d,28185431,17ec634e,e6634831,97021441) +,S(4983d95b,3716aefa,4a14d116,bded84e1,fd5b050,bd6001ca,a2b97086,b4d5c68e,1373426d,a2efcd14,333d47bc,ebd3befc,f5e609a6,6fac1b02,80cdae2c,7f0a279) +,S(a2bd5cc6,92e84b97,3ba2cd09,25e0850f,ad8054ed,e6b73ef6,1fdcc958,3eafe6ab,cca6e78a,f9141b1e,6159011b,99f8024d,33d8d797,9795aa4e,4f0b2767,e6a5ce2b) +,S(61c99231,a18f4e73,95076281,b367d084,b8f85226,3117ab60,bf698d4f,6b6d741a,82314b97,9e7f1d30,64861609,a08c019,af886db0,67d49929,9d340814,6e6cbfe5) +,S(4a5acfef,32c55299,3a7114fc,7913321a,d4072a2f,6c6bcdb7,3ed60bfd,6ab34304,7295a29,c06859b2,69bf9f29,64b26dbf,1323e89,4affa4da,9f61b056,9a0c03c9) +,S(e0467755,866f494c,2b36dcb6,c65ecac6,604e5013,4216ad48,7d4f5b68,bb7f4023,dead03c5,974dfa1b,f532f955,826189ad,ae945975,28ece029,d9e5a42c,30b336b3) +,S(686fdf05,c9265fdf,5b54ca74,b5b1e231,c4e8be60,20844596,40dc0d2b,bb215ea7,f4d43e1c,edf9b974,aef950e,bff3677b,c93723f2,c5901710,b6561e53,d57ea7da) +,S(12476985,f9b20c,ea62b7d7,b0d96d2f,e2bcd924,d1f15cb9,fce5ecbb,8bd21253,d3437cb3,9e904fc6,43a7b356,b4389c0b,3f1950f2,43dd7842,e32de16d,2b522004) +,S(656bdcec,9a87c9b2,e5b32291,9f657b,b5eb1e1e,d2fa724e,45388026,2ad17b1b,c7748d0c,47b6e4f7,f63f704b,3fdc08ff,cdfc830,d17c1d11,6aa3dce2,f92fa64d) +,S(5b7f710e,f721612,ca79b24,483ced12,7a3d403e,60ebc04c,3aebeb96,b483e4b5,1b5157a7,f0688aee,634196e8,de5a9eec,11db4b72,bd96b86b,698f7284,bfb08080) +,S(bfca66d0,552ba6f5,5795bf18,40f90d85,2545213d,81d2cdea,bc8d3d04,a1e6b4da,4910b0cc,290d4257,c04c4638,30cb3a10,223043a0,bddd8690,84b6dd1a,f1754e75) +,S(663fa68f,b79dcbbe,4798f8ef,2057bd14,1447c11b,cec70924,7f566032,88496f16,3ace2efa,1f3bbd23,d885598a,91d1f420,a42597a2,ab30f951,f2b27aa6,83c41786) +,S(27cce333,8a3db8f2,1fef2f86,ede68a25,7c1675ae,80cf004,6085f1de,495c4321,7156bd8c,8babe472,eb144a00,263d4fdf,7aefa69f,da2a9c29,4b16a82b,24d373ae) +,S(d49c06c4,52ec5c09,be27940e,13c575ef,b727be4b,1c0e8ce3,5aa5bc4d,64bd9560,2c653518,b298100a,72a66469,f9a03635,5d7ad789,546df3c2,f5175238,e78d18b0) +,S(6960807e,bd028026,d3cecd25,140d3bd6,3d7bf4fd,10afd129,cfa017f7,544ad08a,a785044f,28befae7,2b7cb546,5bda6bdf,6f9a6383,aa9abf4c,f7baeac0,920e7c7c) +,S(8382bf36,54b63a71,a3b75abe,ba57dbae,fc9263c5,5a54faa1,edeb5325,3df8faa1,e05eb9dc,c319cb53,4461da26,9627661e,dc9bef3d,945766dc,b6d0fcf1,849b011) +,S(803b9379,30ec876e,78c8cca9,fa932f22,b7e7059a,f605379a,cc45a3d1,4ab0bffb,7db2341c,5202d1c2,c6fec7d0,b7869471,cb90d1dd,17cd1152,b52af046,55e5790f) +,S(cb4db129,ab6ae9f,11165ff4,f73fab02,cb78fb0e,89647e08,f998ba11,d2c5292c,ccaef9a,1776384b,b5a80ad6,5bb366fe,745c2408,d754ee9e,f6154188,d7d1c9c2) +,S(fab28757,50e9f672,3838be8a,fc070fc7,8fd6af7b,84c9579a,a8152acd,ecd115a2,d59fe028,89cd562d,5397d3b8,3ae85303,764ee931,d9c6e495,6c311490,c0b3f065) +,S(dd879eba,f870ee3d,f6e3f03,60833e12,fbdf844c,d6a5b76c,19802485,6649bbc1,e7bb04c3,a99a5c11,dd7a324c,1d5696c8,b041a12a,c6a538f7,3094716c,9943c55a) +,S(7aa4afbe,29b06a1e,da9319d5,72572b13,1df68f74,1b5f8d8e,d00ccc04,80f8016e,15f79a9f,b77b8587,7f02e3c1,3202b972,423fd00d,937c0d2d,c9d94b17,53fe7130) +#endif +#if WINDOW_G > 12 +,S(9145f3f5,876a3265,5d7fee64,f2d6e660,c34354e9,1571d68b,a19e4cc5,8c39f890,45e0a95d,cf369fd0,5bc9ba7f,da108d6f,37650c1d,5766b6c9,98ecda28,b285d8ff) +,S(5450b752,36fb010d,1ef37afa,2077f3dc,a5a7f6c8,91a21317,13df740f,4511ac9e,a7c7ed57,62bef86d,4de1084d,3ded2d7b,13ff563a,67109ef0,8b6f0180,fe6ba175) +,S(ba6c0d72,5e48de2c,cb8256d6,7417d075,bbf2766f,d13501b8,4c32cf88,c0666a0f,cd2a9132,7137299f,50eda669,3a599032,bdecd64b,91bcc640,5ed186f3,e525e442) +,S(b94821ff,1feeebb4,6fd1006b,798fbdf5,d25a649d,aad58b05,53adb7b3,9605c921,21589ba0,79bb92a2,c7c3d950,c574afcd,f45ccfae,eec4365a,72dc58ab,f9077c05) +,S(46436446,497f7c76,b70e0d7a,5a963cc8,432f14de,93d61f81,98f8879f,da0681d,29344a4e,90c4d810,10da8aab,5ea25e5f,48c367e5,b3ec9239,8a3e608d,49c83a5f) +,S(bd8e5ac6,a2e210be,4959185b,7bcb0cf1,bd3be917,5baa0d08,2bb0b38,e4c1ae1d,6b381be4,6dcc9755,da7773a5,eec888a6,69c6f71a,7c3ec0a9,4edf08aa,2db1fa19) +,S(c27c1e1a,c428a7a5,f4c3405,58ace76d,7fb64593,b3942319,74cd18ff,99f22493,fc95d661,c12f7b3a,1cb1884c,fa9f5994,25108af3,c05e04a4,9544f919,c59cf57c) +,S(a1765561,837e4ca5,5268168e,ed90466c,44c17c01,4040fc02,9e53af22,77eb30d5,8a2dede2,b8d488bf,cd655d0b,30e6e2f7,3032c775,d0fa15ae,cfc8b66c,b6c28eb5) +,S(2bf6930d,35cacc91,87e9279f,678ba368,e9eea737,8300ef93,b03e98c1,81ddbea9,8a2d4d43,3aaa8bb0,3ffee538,38ca8e16,d0f3f930,c35d0db4,6e2fa069,e625209d) +,S(766a7725,9cc5aefd,90f005f4,d6755924,a36d085a,3a5856a,6a066a70,6877c8d7,db3fac97,4fd9e2e7,f05bfad1,5e938ef0,90b46d04,bf40bdc4,171c1e33,48049190) +,S(d25a60cd,953f21d4,5fcc333c,97329da,134196e3,9a913242,88792ff9,18461268,89bf2be8,bd04835f,dbb874e7,12352980,a07ad598,9035270f,397f24ce,790c7863) +,S(c7b28e9e,8b7125b2,6721f467,b665eafd,9bf56986,8ca180b3,60dfe429,cad95d68,ac28d58,b3a7b61a,71f947ed,8bca4768,9ec7bf34,7646a167,b37c3aa7,9e95c398) +,S(e2a5208a,c61f8c29,ada2d7a7,4cfce985,20c29160,f1f7a97,ce8b34dd,7c59bc24,de8ba14,49708a04,ccb4483b,4e90e383,a152ce27,777fce4a,880d9f5b,3dc70830) +,S(e1e8e4cd,2e8df95,d3b2b152,a540967d,6976e001,88287ca5,3e844adf,12e205b1,a5dbc6f9,cdc7547b,cb3f0091,8233723e,d34aa97,f546a491,a77d8cef,43bfc9e2) +,S(b20f0a51,4a684e55,2b228480,3f3b1c2a,3c3143b3,b895f75b,ea454bf0,9d2b6512,bc3db380,676d0d14,9c0b0c3,1941a07c,f7c95585,cd44ec31,e0edda96,e80d02c9) +,S(b71a6923,b1adbf77,94cd9d8d,407ac96f,9582cbc9,b9748949,9cfa696a,c29d3ec,75182389,9d59558f,b93113c8,d38c72d2,7b6d75ee,7679fb1c,89bfce1a,64b4f151) +,S(ca47adac,68ba38d1,8ccef76c,7565788,a82f415f,d9dda65,2004d5c6,a7d3bb3f,bd598ab,1b783382,44035385,e165fd5a,ccd8454c,3969d378,42fad050,4a8701df) +,S(5fade148,aceee9ee,9fb4eeec,edd5e4c9,4fb989c4,d99f65ee,a45f99d0,2d40e441,ba6fca3a,e82e5581,ac5104ca,c8dd2c00,15afd1cb,3943f1cb,5e61dd4c,d73831f0) +,S(767dc9d2,14fccf00,900ba01,a1cf30fa,e834c851,e633849e,8adada63,fe5f84e9,8c650911,aca30e56,2d6b97a5,2fd7cbfd,1a5bcd1,9ae197d6,9ee3215e,64404639) +,S(27f8f961,445e2a20,5daa7648,fc3c06d9,523544d7,477e686b,91d7178b,7e4f06d9,39110b27,82cd7be9,75596bce,6b79e5de,37933242,21be8172,427cdfd,82a73a60) +,S(8de0485b,343b5e4b,ada4070b,f79dde48,8a1b2889,839735bc,6a403165,3f3de668,90305767,6f43e0f7,d7d1c1a4,4c59124a,12fbba72,8302e143,1c2cfae2,ed5729d) +,S(5e43db6c,8770e8ae,8ab8d318,8e700c28,5b6af8a1,eec95fe1,b68e5cc5,952df0ff,6882628d,d85fbcfe,3a2a1091,15e59c78,9aeebb3d,37075f90,ae02a439,506c7aa6) +,S(7db2baab,4bf4300d,e7caf4e3,52df1423,6102863c,edfeb7a0,89311f42,59a4ed54,387561a2,fbbb44be,303fbbcd,685909cd,e553a84c,a3d4c0cb,d33026fe,178e8a84) +,S(96da8525,39106887,d1fdf9e8,232db3e4,cdbefdcc,abb90bbe,fc04d10d,b996c6f1,65271a31,49127341,9fb5d651,3dc33287,45948c92,b7fcc509,4023d300,9bf9edcc) +,S(84eff1cb,14eb1284,f5ba51fa,838b485e,64cd4c0f,acb97b00,81ba7848,add50613,926c9c8,a6540a8d,7b1e602b,6ce818c7,609f4511,32f284fc,7f578c52,a6febd9e) +,S(1eb96371,8e2a2a0f,f5ee6000,7bf94a00,416e6a92,25d59705,7fe19941,e2adfbbe,4870aad8,9635ddfa,dc3d4011,500639aa,d3cf0523,cff0dbb0,9c9f6a1,3005b855) +,S(2994a36a,6ea3f307,1bda8696,baf193df,c75fd4a1,f7683fd8,d454dcb8,77bdc098,e465e8ee,a7273d4c,d786bd0b,e96fd3e8,9969bf03,1b76aeb3,fc82c4c4,bf856766) +,S(25e7fb70,f3d357a2,c29b115b,5e2d97d9,d2b68fcb,b7f2fc00,237758d5,9d26c414,4959a370,a3bb895e,bf530fa0,13a86ab8,206b7330,efaca631,fed26773,f356c4f2) +,S(fc387f98,80bf6bbe,19f0481a,2d66bc5b,c3945c52,588860ea,dfd5893,347c0623,89d7b80e,83caf032,9c9d07af,734604aa,7ba33274,c1081ff,16e663eb,b49d67c4) +,S(c50af368,c25fc9fe,10220fa8,2f177720,ef5c00b4,85fa99,e2f03294,fe01e1d4,c3777b26,41983094,912b80d,9e94af7b,27d9f10f,978c931b,a4294cb6,b97579fb) +,S(a0f9d109,d524d9ba,a2e00362,941a5f20,d7015c48,554f5bea,7c97617e,10041f94,28c51c02,daa5e108,3e77ff2,c64560e1,2eae923a,3a699f1,daf3c62a,710e9ad0) +,S(41d12627,58b708,58727138,908004b3,2138bc23,cbcdfa28,5da862a3,48316de1,6277029,153bcec9,5c95f451,3d515d90,341d90a4,90eb2999,d29df4f0,7c1b9673) +,S(944c58ce,fe6cf543,d93afb77,e33adb3a,5774448c,d61d621c,fb80f856,6e99ca87,c071ec1c,9b7fc717,ca91c557,66bcb222,3294958a,b7d7b056,e7473170,284d66b5) +,S(3307ab12,e06d71ce,9c029bf1,88eebb58,9a27be59,17290635,f2babebf,be437145,889c3cb9,28cf9091,4748dd9b,f89e9809,4a6966d0,97d854c3,c6b6a949,c861d213) +,S(42baf011,1eb2224e,4ca03abd,24307b6,72b74572,2db6a8ac,dee1b7f3,45cb9ae6,bf32e128,d608dea2,4b564bec,38d22c5e,879515d2,7379cb11,25695faa,2e12ee06) +,S(856baabb,be7b4bd0,49fbe898,110d1175,166c69c0,a2bc86bf,e734c854,c402c621,24a323c9,b6d31fd3,cd424161,be229e89,1f825197,9ed4721b,943d7418,4912ac0c) +,S(38dbc18e,d998143d,874c224e,de83834d,95aeeadc,805cac1c,3216d830,d24a9cd4,273ec126,f7e85778,ea38e2ea,a90ab5c5,271c6eee,7f934a03,570891e5,167eae4a) +,S(359dc85b,ffcd2329,3166bb20,c8374af1,5e24c065,a5f48d92,c981eb81,4988dc59,de5dedf7,deef588b,90237d06,e437bdfe,c4a05703,f77b584a,e58162fa,bfbf39c6) +,S(e1068065,e2e91c88,3de2f73a,6a5f3da7,1d872a74,9d7f283b,b1ca35b7,c63666ea,810c3a52,b5df0851,87928afa,a7685035,a7e155fa,c8dd4523,c5ed1f01,73752cd9) +,S(50767f71,37e7c9a6,6e317183,cddfdfc,b564956d,cbd5f3c7,fd8506d,dbb19d83,e1c2dd5f,5e9d5fed,807d24dd,3f2e0ae2,393b6167,563db9fa,5e338664,a0d4fff8) +,S(44cecbf0,cdf88355,f1216d0d,efcea137,5e01275f,f53d8a72,5a0b5980,e6e65864,469568e,5094e9b9,ee290550,e67bc636,e8e3f022,f15c8d2e,25c3ad6,f51cd40e) +,S(1830c8ea,43cbb07e,fa2fe597,6afca2bb,87ed8a92,602e05e8,86ce3447,96aa18b3,df551328,e064aee7,67f56203,7fa31c11,3c8ce2fa,b5445d65,8bf1dd84,2f1da49d) +,S(58d54b7a,473a7ab2,51c33417,a41f4ee4,708245ea,c4f8eb79,9bf90aa4,bd9326c6,a191f338,15e2e07c,ca4c331b,fb1cb2ca,a1692093,faf5e789,1ce45a2e,c49b2a85) +,S(f0dce604,9507812e,603af104,42fc9861,70a18b6e,44e81af7,ba192b55,12c6792c,c221a221,b5e86ed6,23e48df5,5cf0f560,4cc60eb4,c54d95ce,3ada7b09,bbb966e4) +,S(42fb09e5,72c0302b,286aaa04,644b26ae,e4b958cf,ae5293d4,d7ba505,59dd2ab5,79c10573,a00e6888,fbc7ec76,983e7d17,f46e1ba8,27494099,43781bd5,19f2299f) +,S(7adf1551,ddae0c9a,8628db25,e0dad10c,935465bc,88b005de,ea2d0412,f3502ecb,657c0ba2,143cea92,c9ef5c3,69d110a1,2e031e67,9d945a9b,b3c5886f,29acfd20) +,S(dd5a48b9,56fdf6a6,d6271310,afc2f5bd,3a7bfdc9,28125345,4dffd91c,282c7a5a,7390d037,2e067f36,fab52107,29590464,2ac6b0cd,91a161e3,85df7cc1,7ca52657) +,S(631850b5,15374594,be1c783b,104d2ce0,13ac763b,1d36301d,2936c2d8,8a1466fe,2490ce1e,a9b67e44,a9241416,c5729ace,2016d202,b77efa85,78bf3228,c590882e) +,S(332e39e4,d6732229,aed85cd5,83a3ccc4,24466869,bdc6a8e0,741b0e06,f3a0bca5,90840f03,60db52ae,a58b1b4,74ad65c,b66ac30d,f4d465aa,60244d48,5d7578e7) +,S(de019556,f0c7e1c1,6567224e,826532f1,d72c0eb2,91e70980,de7513a4,362f0c97,39a3d79d,1cc98840,4162227a,66382529,d75fa5bd,64977e47,9af0aed8,68411ea3) +,S(4c44c0c8,e675da80,c6ffbf2,61b82e46,4f81b76c,a3f902a6,8094a2cb,24ed859f,59e1ee88,1ecc45de,d8ff2800,243ab8ac,c5497897,1a3a2246,63b2b593,e45ac34) +,S(e60339b8,481e19e,5c1f4d1a,85ddcec6,a4e0dcbe,113e7d28,2793654f,309286a2,9a1eeacc,a607941f,b51c7998,ed2a5a98,bc58e3f9,4737f72d,1b08a706,a49d9d59) +,S(10f42ee3,e7292f3,9f4bc472,708ffec5,c6ad955,c5285be0,d44d02c3,d8a25e66,6f365f0,53ebe28f,db9d5f2b,c967cf14,183e130d,f01a5106,34a975c,ec916a25) +,S(7e0931ca,d1286687,7d2fb0f3,1c58d74b,703af3ae,593a9548,b6d53d86,6729c445,5e4b9fc,75eab41d,663caf7e,8056f4c8,a9c34af9,22773ffb,f5a12174,1f6b0b0b) +,S(36313f7e,f9613c6c,ff14cd1a,78362f7d,b7f1acc0,db278f1c,6a011435,57963f22,1e6946ab,2a94231,4ac6627f,5494205c,33960a91,ba663a69,8641bab4,43d7edc2) +,S(223eeed8,8eedc265,b2e18a63,ceaa2e9e,83f9ba59,2fc8f3bb,55cec574,2869fe01,72122173,4ae29bfc,f3632cc8,92d72d10,5593f7b8,d687e5ff,eff21095,c1bbd71c) +,S(b6bd5ec9,33302c5e,3fb9b32,18795a11,60dbb2bc,f9a9b5fc,31b7a5a6,28b3ec20,fb9f87f2,98a8e5fe,b15f051d,63b48bac,34f373f3,9b42a42c,d0f1d2d9,c99dd495) +,S(a365a760,3b1c24fb,157f69ce,8fd57ae,5a802dbf,3b8f92c9,8f0a8b01,4ce24668,73e6422b,7746abda,2a38cc7,298180e6,578005b4,1b0d3760,6f2bec3f,5c0a89f9) +,S(e86f8fac,43e436f6,f4adba30,9d446a07,e24bac1e,d379e13a,a235ca1e,d7cebe6e,1e7bb4ef,aa75a9bd,713a592c,42a01134,930b7402,77cc1cd4,a913d6db,f4a166af) +,S(f5a57dfa,d2b25571,dad09304,cfde1da2,5cab3e2,e85895cc,9933e868,eb9bd5ac,d265de5e,8fc90e41,d518dad2,68997a24,8eb90906,becba9b0,c768c5e9,877c1ff6) +,S(e1dcd17a,7259374,7e6fd8ca,b2464a9d,6656607c,a2bf10f1,45c45947,75f76c7b,efa2c310,23f86d2,6489feb6,1232bd44,dff819ce,6b95678a,130de640,4af9a20e) +,S(83f8abdd,84996ad,1be74b80,a05da9ab,cb3774fd,cca40c3b,afd386cd,cfa801ff,267ebd64,329fb10e,56ee792d,966868d8,1c85ff37,6aa24287,3d37c63a,4bc3f63d) +,S(54cc9d79,6ca85a90,27487c71,6511485b,ca324b1a,f34fe454,ea9ba54b,4f259fae,18c39071,ef0b861d,7d016e9e,deb6e83a,3c6ce8c1,517ce0f2,e201da0b,fab2da2a) +,S(9d12a52a,e0091654,e2875ac1,b11f8744,1c3f65ac,940e6a51,6351c219,31402ba4,5ffbb334,276219af,418d17f3,9f5fad63,c6d7e42d,d53f6e52,bbee2f01,38e81d2e) +,S(659bfdb7,66821a91,cd030917,ff21aea4,488007f0,b7ef3824,4f23b665,e6496998,2ad708bc,4506e85a,341ef96b,78bc247f,d7321a8e,bc21f9db,8444e7ca,254784e0) +,S(e2cc4e33,d4a08374,4866a253,81549a6a,76ba1b4f,57312413,d601296e,5eb4670b,528b2b25,347e7f34,7b79780e,a64c3718,80497f0b,a3b28e18,79714089,a4672476) +,S(529c0b9c,9e21c36c,9b2164c0,fa505601,e8dbbac4,cfcac131,e248e103,e6edec68,7fa44821,72a0ca01,33669e6a,bd2e0386,6cb74f5f,9cbb7e4,96770129,567125f4) +,S(289d6baf,be6a7d1c,154d6532,a80fb65b,3d89e57b,eb2f1dda,654d3553,683b63a1,801f4863,d3ce8d61,60e2c62c,55267877,db149ff0,c3cdbb53,38893168,7d005400) +,S(d16a84c9,e3b36660,7c005bb3,425ab432,2eab9b58,58d1899e,51f2ecf0,790f14a1,2c6f5dab,10715328,f9ffc5ea,4ad6e0f1,46ec79cf,19cb2313,79bb5198,5156dd07) +,S(d03cac39,4fdabfbf,440a6893,e410dab2,a7062df3,ecbe1aff,d30703b1,6b6348f1,152313ce,f530b317,70d85c08,7de95b1b,5dc4a86d,38e4040a,e5d1ba34,449d19f9) +,S(b66b3c6c,a673c4a9,77ca7d85,1f969858,d4c4b604,bc497101,c89207b5,a863379b,54ba2563,771c6aac,482c63cb,7156961c,4b00faff,187f0560,9a470b06,31624da4) +,S(be684644,11c47cd7,dfd3127f,4e7d7308,2a43fb68,79c5e86,236e4516,a98c8c45,79290f83,c61d368c,2e395aae,b9cc50e9,7d78ddc2,fdee9f19,a15fae85,826733da) +,S(478ac3a0,9f34f463,4d61de70,9ee01878,4ca421f,91d20e0c,5c62bfb7,afcbde9b,f752f3b2,ccbc1096,1ae7526f,5574b5f6,e4bc7d4b,f77edc34,f6e37655,7b0988bf) +,S(745f355a,f2ed71a9,9d4d7de9,c9bd4a13,7271a2a0,c077c796,e7064179,8f3dcfc8,18ea61f4,6b0c87f0,9ed05816,c31e1992,d4fe8826,630c5f6e,67242063,86e288b9) +,S(54e7bd6f,9878a8b0,909aede5,9286427c,a3157a8e,38ab94b2,18db520e,86760ce0,d7b7d80d,c1eab448,d1f3c638,675dc0b4,e04bdba5,340d3f2d,dc1d24f3,dfb8e49) +,S(ff56afb6,55eb431e,f3c6f5c7,fcc6febf,99b018ae,3dc95208,27e4a01f,a07d510e,9bfabdb8,42d7b1c7,9f4388b4,49a28d6,ec723210,ea27509,655e9b44,2591e371) +,S(c2bcc099,ed298fc8,679d0250,6d8ea790,ea511b41,5ff3ebe3,82d39d21,fe9cda72,6c7bf2c4,35ecf773,5b6c31a5,82fd38c4,825de4f0,58efb070,aa1ecb58,530f971f) +,S(2383f144,9811331e,6c54b9a1,19c681fe,c8549e36,890b80f5,99a80187,8e2ec4e,13ab411f,d846b6b5,938a999a,704470f0,d8fff03e,9dd35cb1,44860a0e,3533a1f9) +,S(2f2271c0,d4fa1d8b,f8a44584,ba4f5266,9953f72,89de16b8,17d6bf0c,6e096048,646ef05d,b40e50e8,b6f32c22,63ef553f,a957173d,a6f14ab5,7cd60b60,2fb42fc4) +,S(b7b49b1b,f067a27,eedbe55c,bb011eeb,809e7ada,ada5d08,9bf1f26a,25e951c7,fec760ac,a8160525,ad6ec95c,7cb0329,4a9b7f20,45907331,5b2dee2c,7f7c33ed) +,S(36c8e1ca,d9933e5c,971866eb,12daf81e,7765d4cb,9f0af557,94181aa5,e5409223,895eb6d0,a0252282,d71cc730,9116ea95,22f2e35f,52498853,e291932a,dc8b8fdf) +,S(3cbe9127,63283592,13173e01,8cc2b0e0,fa5b8a11,5684cd6a,6ee7bde3,bc1ed523,7b2d3dc9,22f96c9b,9970aa9d,c75f1e15,c5149ab3,d0993055,e4df30cf,ce44dc81) +,S(76e94d41,c4639419,23448d38,8b239e6,fe0aec99,314ed16,4e67e97b,6247213c,8ee4a6c3,2f010749,103460bf,d75fa38f,f9efe4e4,bf283cb5,a3bc186b,21fa1278) +,S(493925cb,12c0e7e7,a15749e0,7fe9dba,5b265d27,8eec0c08,506f3433,4b1851ec,70900c6b,3960a465,6cab318f,9f730a66,e4a2400e,d819da9a,1f5b16bc,4c62b193) +,S(b37fdaba,d1a1393d,79820eb4,a4823d38,3873306a,a9f5e6b7,51173aed,c43cdcbf,8506f0de,57fad139,e20df67b,e30a75a7,dfd325f2,9e35652f,28fec608,f27030a) +,S(4451960c,48e95c49,32b0c90e,9f90724,8f2b7023,9c6c703,3c29f4a5,b0a5e8c1,83553a18,d9ce9f66,961c9e1a,47766a4e,28bc404f,bef524de,53b1b687,d4d7490c) +,S(9b0ac1a8,697c69b9,80cab20e,b3f98718,7857721b,c869c704,caf63b80,dfea3449,210e4c53,bf1bbf3f,71e32a58,22809853,61b61723,72e845d,65b5661d,fa7e60e9) +,S(e6697355,ccae4f7e,122d62de,1c00dcc5,32eca4fa,7dbd1ceb,e92684b4,781e0851,1f122cff,dbe5ef3c,944353f7,18806a82,9d3ded91,427bdda1,736ba236,e9bdc3cb) +,S(ffa890f1,1a1aa4ca,1f26f86,1288bac7,ad480a4e,1cc47f2a,fe39f260,f167201e,1688dfc4,1716fc3d,473c4149,77d0ee8c,ac569cda,b01ab5d,69d449ca,85439cb4) +,S(9088d4f2,6ce238cf,63eb09b1,5c04a04c,c41fcc57,946c6c14,cd3b1b4f,54b6bf47,9e380417,bc61004e,3d5c9943,b3d359db,2ae4ec81,2b70e909,bfe265d5,e4d2c2b9) +,S(a3395dda,c1e760e0,fe7f7e5f,e3296bc2,99949ca2,2c034707,67c08ffc,d9576a91,4f8a879a,54036d17,16f07016,23dfcfba,3141850c,de003870,6ee940e7,452393d3) +,S(11e54d64,54aac1e0,58cef234,51f686a9,1a77300d,75330ecb,d208678b,2b8ad651,749b2960,5a8419f9,c5521dfe,f552a24d,aaa53f45,908d2679,6e08b396,c9c020f2) +,S(c8f13cdf,7b41e822,ab6d5a70,7c701d29,98f5f0da,8e4c9746,75e808fc,64327f30,489a69df,17c09c1c,dec329d6,a1f34f60,445d7aad,d609d94d,44168947,c3199404) +,S(9175e6dc,cf674838,a94c628c,3e1a9dc2,9487f394,8a25e50c,d463cf6e,92d84442,8705713f,ed377125,51e37e51,78ca7a7,c13e193b,1b83c729,8cb08186,8fde1c22) +,S(8eed492f,b6d5f0e9,ee78f6b8,953ac0a0,5df8b9ec,db17a09d,22863bf4,3620099b,23a45742,17672e98,d9cf8b94,62439ec8,82e1acfd,40db9d9,9ece889d,1e0ff1bf) +,S(cb95ce23,dbac06ef,79793f54,3105f5d7,5cde90bc,651b7756,bebfa367,d5c2dd9,9612a6ba,c023b0c0,73b5ed99,271ddeb4,57d22d74,f7ecea4f,c618be5e,164a9a48) +,S(667218c8,bbd3ff37,d42a8ebf,8b5a7791,d8fdd493,9ce447c9,15dac906,67a3c980,dd401179,9e19afdd,46b44aab,1055b554,452a21e7,6750f2a,ce98083c,8cec26c0) +,S(884799c6,ded4851,ce53e855,dc429698,c7627b5,a0ed3852,19b59af8,32f76e5f,238d75ed,84e6408c,79cd2d37,152cde78,22e34377,fccf05ac,3afda662,c21c4a6b) +,S(8d98f36b,5fc0082c,597a05ba,e24ea6d2,2cc8bb90,3a6bf96a,256eeead,6911d143,26e8ad1a,fc902a6d,505b2fcf,80168177,de7df931,b1dc1516,f2ad7b38,e0ab3cd3) +,S(ba9062ca,c0ddc6d3,27f2cbc2,8d2efb1f,d1db2388,c86741ae,7403f4b8,3fd70ad2,473b335b,3036e754,d9d71ccd,53814455,674539fd,7b73d9f7,8f24bb0a,668b38c2) +,S(4a2d36d7,3bf0e609,7a69be67,55621051,7453ca53,11e288f0,1ff1dc03,acdca29,ff691e7,a90331cd,44e83ac6,c298f5fa,9d694a81,48db01d8,595a4386,b2ca8f83) +,S(e868f28f,d99c4b16,b64fb0d9,32c325c8,6b365136,e0055c4f,cd362e1d,cf37d0c4,ad3346c1,83401034,8e8e0440,e889109a,40e5fa11,37d94bca,2742adec,4cd4a9eb) +,S(6c5e8689,830a6ca5,12d77e56,62239833,ea77e696,da40feea,99da3519,2babbf3b,c29e05f1,5fd00b60,7bdc333d,d753647f,56b9830d,46a597c1,2bee9465,ad779540) +,S(b3a172a5,6ebf2dff,aeb91cc8,6b9d5a91,c317adc6,250ae210,e1a25bec,1c046344,28f6dd79,9ae40d6d,bd31fff9,9a4c2fa,f06401c0,de7a5d11,9fc5faf8,3b4ac3d5) +,S(198f05d2,e2f9d779,a50aed67,39468a8c,ac4a22ec,71a3ab80,91a94e2,100d8f47,cc6a183f,c9813173,caee3baa,f3fcb223,39708968,360c02b3,cbf899e0,b7cd0414) +,S(78b2178f,a943a791,4bc7703a,e850b07b,41ae77db,79fc39d8,9f0f50aa,b077f48e,85fd3e34,f2cbb092,8bb89004,e1801be1,d78fceec,c29eabeb,11b9cb15,625274e7) +,S(6f70df00,1d4c5175,f997a795,170e28a4,23828ef9,d5f72dcc,cec43fb8,d9943f3e,26315213,b77183e4,5979c34b,e730e2a6,956a66c2,a8dfbee5,f0f1eedc,ce8315ce) +,S(ab813144,3c946d29,d05509e3,b45b5926,e3964b2d,1cd0fbd0,9cfc359d,b5a9dccc,aebdf315,c1273af,a0c5e587,6c6c6132,16b7710b,3f505062,6336ca9,4f5c5ac) +,S(e72b3791,dd751127,23723e62,77e5e6ed,6b94569e,ba3321a2,a3e883e,5473ad3,131b3074,2dbcaaa0,fd3109ab,5e3a2847,9c2091ac,8830b19f,d4df4c82,9b28a3d8) +,S(ca5a3296,ecdd5e50,38fdf77a,fcc507da,bb525d7c,56b50c74,61928432,ce3ded63,8bdb6794,b7e177ba,9027258e,42b365bc,5a14209d,2bdce54b,3f865fc6,ffc4ab9e) +,S(eaa3be9f,26ae8cff,cedbe59d,cc03b202,e7d2e815,a7269819,c881a700,e31a9222,1b5a2cd7,a367d34c,60ef8026,51df2d3b,36ac2816,7cd7eacc,735e45c1,9524ec1c) +,S(ebba882d,3ab4ff6a,e162076d,56791554,35a011e6,74872206,582b03de,e8e97728,94222a05,3d8dd2cd,cdaf2ac7,69ed8c65,8a004c58,7bdfd0ed,355be474,65be16ac) +,S(ca0d97ea,537a5dd1,147cb784,eda20601,ba88e0d1,68e8df44,6d8923c8,353aba86,874ac858,89eb86f1,88ebb979,a4490e65,96c97892,874b5b68,167ca99,f68fba1f) +,S(51de2965,34807454,7e798f98,c5fc19c5,84a90a0b,e1dda24,7718cfb3,ebb797e1,81374e3a,ad04e6b9,55c1952b,fcdf9a7,ace0ee4b,99e487bf,87ceff58,3f7c54d) +,S(69d611f,3136be2,cce39bd,a1d48fb6,87b52135,365b8df5,151c6ec8,c1387509,75e2d820,563b64ca,c4d127e1,a5c29720,fb84c0aa,6b271fa7,e9da2c22,3195bde0) +,S(31163083,558660f,23220456,1dcde218,6fa4a4c0,de450a9c,b2f57de1,3a8aa135,25d6d496,b1341688,3008c636,ae1d8b76,29e14207,e5fbb817,539ddbf6,ff46eae2) +,S(84e342aa,efa9cd4d,4d82e5b4,4d0ad9a9,11f4623d,8684c274,cc3cd561,2c7ac334,fb90dbff,260f9997,c84f0a32,4fe5d2f6,f552affb,50aed654,fb8f660,2a92a70e) +,S(95efc402,969db115,22446814,3d4e3aa0,fa812aac,8867a5bc,64d66692,67bf6562,315bcc31,6149252c,56f3f00d,445255fa,e4567d9f,d77ab4b3,e82c1359,9f371883) +,S(5223623c,f87e9da0,bd289993,a55bb9be,55b40149,bb501507,e3d5c9e8,d78d07fe,6bfd0a21,dd2df437,9b1c16,b0076f88,832e921,db3cbdef,fa5808fc,ac613b56) +,S(f212d199,a6b707e,61d87ab3,109e1178,ea180f19,66b0a55d,f5f4cb97,c0cb0a4f,3280446c,7edbb64e,e47c3142,7c0ea113,7f511422,19ec3824,12f6b069,a0f7c84b) +,S(6b55063f,f25d76f8,2154431b,20058f96,e1e19ce2,210e1b50,835cf58c,31cfe8c9,5427dd62,36450762,46e99707,6f60ffed,558a82a3,dd7e31c6,492088da,9069f8bf) +,S(2539e5cf,a09690c0,12ae0c12,9e6f8b27,c9388d41,a82e1e96,47219d57,9b23045,94cb83f6,1e26a4dc,d1b93000,e5113347,31d804b4,a259e24a,77c457ad,d9021ac3) +,S(aa9b6ad3,4aaf1c30,71aed31e,8f28c3f7,9106421e,f0e53fb6,297fae54,a47d51d,dc0958e4,9fe4ae00,98b4e7db,10ab4d99,58cbd87e,ca443d3e,d1c9de77,83544c47) +,S(a850a313,aad224fb,f5ed6e63,5a3f6b0f,e08964e5,e9ca262f,780532f6,13487ad,7e476ad5,4cbc55c2,3b9708ca,eef3479,d9a5e570,26f15a4c,43b83363,ed4ccbe7) +,S(314fec33,f4fd0c96,d04889fa,b18e29d2,5da44132,6477b28c,7418d4ae,5fa09c1a,a2c9513,a98ffb7,9b5dd4f5,49534fdc,d9b4b8d3,1aa6a4a9,76b7b94f,ebd25f42) +,S(6e7dc3c8,9ec57e79,ae1581ae,1afbdcef,183998b8,cf52dc85,329afa35,4f3d0963,6b636805,6d5a8e9f,9651e3a8,2598ab1b,8f057830,fccac964,a83515f8,9d9f87d8) +,S(596df693,fc4ba2d5,20497a50,7d1841c4,38b6cfc0,58c274ad,9557d400,573337c5,6609ede9,1c97b09b,3a171723,e9ec5cfe,74b75c33,d5ccb3c6,bd03fd04,b37f4ff5) +,S(235f8dd4,10de7800,58550e8e,77bd42d4,ee3ba259,97bcb4ee,13cf0a12,14e8afb7,bf6e0ccd,b8e8e136,800f8d59,510a4455,53b72c33,824b71bd,189e158b,6cfa6712) +,S(a9d8ba97,b259e91f,125fbb28,c80e81f0,3f03906a,ef692279,4c9cc23,13db8b47,e668b954,19b580f2,67472afe,221f5895,5e6ce6f6,45ba737b,f14754ac,ec048656) +,S(53b44dc6,4f74c170,142bc629,51349b88,c4e2cc35,b7d9a7f4,827b07e8,4a288e5c,4aff13e1,404562c4,d8f006ea,dfee7b5a,32216187,d8c96c7e,5896e157,97075d4) +,S(76e6e038,a6baf9f7,1acb56ca,1494486a,a9187279,486f62f,947b5a02,580af1a0,51a5d110,66884076,44c18348,be045910,3b57e0d7,2266ffd4,465e6b4d,e1f0f0fa) +,S(7761ff19,2fc70129,10eda284,dde864bc,1c45b4c7,1bec7870,2bcf53bf,9bc1e6b5,80980f70,a82f7196,61f7e1fd,fc3e7d37,e0bb75cb,b1ab47c1,d947dac4,296e11b2) +,S(8199c9d6,1224f51f,e6dcdc33,3869d860,95c0bd8e,210d2d7f,8fed2804,a89aadf9,be89724f,5cbd2384,ae9bbd73,f030dc74,a158ee7d,2a9d292d,daae3057,4b1ec89b) +,S(15c279fc,760a2556,bbd62680,3bd779d8,8bd4dcb,e508b3b7,99d27405,91c55c0e,fd5038bf,ed80c963,4915d352,bca040fd,ea0b9b0,67215dee,3373e4d3,53390c39) +,S(fb3f8d06,b2804047,6f7b46a3,ecc2e7ed,9724ace4,14831a8,3c111615,f8a39b46,f9250cb6,ff851b61,3b3fd70c,63c1bd72,3177ed50,ac991185,4fbfb3cf,6bd2154e) +,S(39b2b547,3c964125,da2723e3,97c3fde,f9faf415,db0b389b,5eac9a6e,ba012edb,8ac1c2a5,a586f413,bd68aedf,1f65f231,6bce7bae,ddf9564,2882f2,1bfb7547) +,S(42d5dffa,e476151a,1d3f6d0b,bb24e8cd,bf72d73e,ac87e848,20cff44a,47f1552b,631d9645,d941c001,627ebe3a,f403bcf6,663f6e46,17d86ee2,922fadb4,b8847ee4) +,S(84dc96c6,24ecabf0,a5edd071,1e922d9a,630a0bd2,6d9c6158,e311fb7a,e6e0bd8f,40af318a,16b7324d,2acff10a,8bd2fc25,c795cc71,c0aa5a8,2cc8eae3,ef8703c6) +,S(636e760a,797bceee,11b812af,37bf7cbb,4663ba02,c36d93bf,1873983,4bbf505e,ed5c5e4b,6cc8cf76,436dab98,104b9458,69924f40,57d92ff,d74f703a,65f724d2) +,S(137fd025,4bb5ee78,669ca6f4,ae278064,7d32bc0f,f6175090,d4ff7580,98d06ae4,282d6aa2,25eaaaa0,e9b186a3,36e92e7,e07ec23d,e9ce4bc8,8fb7f09,328d0fd4) +,S(218ab848,39e49256,b55bc7a5,cb250fc0,df781f60,17abcb61,1b6734d2,12459e92,7eb14f56,b53fb0dc,430c49c8,d32f39f0,1a7212fc,701ca444,c994b3ce,4d0e1599) +,S(6b3f7ba0,106f22f8,df69e3a7,8f137605,1b2f0a99,ebb4f4fb,61915495,5f8eda65,c5788c4,4c946bef,86d9a4ab,481e8873,6c831000,5d36d3b7,aaafb7b7,2330d299) +,S(9b414ecb,a2de1195,196fdf19,62eb5b86,131ad1ca,f7fefd08,c5de31fd,d9e8ceca,38e6f31f,9550df40,80db0626,9da9f4e6,51e94e85,95e74797,639225e,a725a637) +,S(436b07a1,857425e1,86933af0,d1d444d6,156a4a8e,f3f2df8e,cbaf661b,26940653,94a52f35,f124ebde,ca642713,724fcc63,c6822dd1,bce4c53a,ce155b31,443f2d44) +,S(cc0a9338,9b25f82,33419bd1,87b5e290,b8d76f28,2099b4d1,fff32cd5,128fbc6b,cc7e86d,ec7ac7a9,448cb627,875500e0,e713ad7a,430ee9ec,220bfe87,6e3f458e) +,S(5a1b316e,aaf877af,cc7b1907,eaf8dcab,7ea684ea,72fbf888,8f21fe83,c3a19858,4af0339a,da08846a,6b6b3466,da69412e,74411094,22dbc450,cf7424ce,cd81e7e1) +,S(faf89165,74444bb2,1fe1e411,40398b25,ac4a5725,2f9ff274,e7d409,6d6c53ee,cfa7795f,af75547f,5dcb6426,3b16c9c5,d87984ac,81083cb3,99714f6c,99a43100) +,S(39e5fd8a,ca141623,1840c68c,6c6cb028,c94cd22d,49619e33,aa9e4dea,d174f248,f8121f65,7083da65,74013e78,88f66276,a8d3686,528aa105,61d10a6f,8c3c1ff1) +,S(20a135ec,147d0cf2,ccd3cddf,6fbe1356,a64b8ed4,219bc0e9,25743098,325cbc1,b17514ab,ea1a3725,4c101fd2,675d30a9,fa1d170a,811f06a7,15622ae6,ee82c013) +,S(a181a1b8,af48f73f,a13d69e2,ac75b13b,9903ca11,8a8851fa,b461c2b4,2c72320a,c96c8467,3f487e62,3d72c432,ad5887a0,a66fbd3a,c43aa5a,219c84b2,97a6df20) +,S(395fc031,720a5da2,faf5d76a,9516de8d,eb462695,5eb87fc2,752462c7,7db3ee4f,4aebc86b,53783895,ab4e14e7,c3ec449c,962ac869,9b340523,1288bf41,c759ad6a) +,S(a36de9ec,f6df2b96,87d632a6,1bb6337d,3fffce5,71b9fd17,4246b33d,1b64fa6f,784e4c4f,a133d140,1b212e14,77deb40d,620fe29f,d0f05ea9,cdbdc862,651999f4) +,S(8cb5a899,ecee4430,f7381820,4535f57,e55a3ab8,3dbdc359,d04746e2,9840ba8c,12a7282a,e9c3a3c1,2c1df0ec,c3d28b4d,731dedb1,ef02cb2c,b92da5de,17ff59a) +,S(de441e1,4d9c9ba1,90e37201,22fd1fbc,4cee72d8,b26b1f29,9c450b66,60b60985,add1a30e,d12ddd33,d4f740d4,427fbeb6,2927b3c6,75032110,508e2114,271b63e) +,S(88e38b56,b5e5544a,f2f3c1b,7128d118,520646c3,97295067,4078207a,9b9fbab7,8833208e,d44e9656,e5bac529,cbdaf184,dc8ea020,a2d8f4b7,8101d8e6,1000e5e3) +,S(a4f0f992,f5616420,b9ffa3d1,58d2d729,3ee217c9,60f5266c,6c5f3374,f4640a7,da6741a8,437a86bc,40ec9188,a1af42fd,b131a8e,81289e71,3d80e201,f82e6ddb) +,S(5f00a8cf,f2d1aaae,604a40be,e451d8d2,86899fbf,37f96ad7,efe52407,1c5c945b,135fc8b6,9ea76d6e,39d1549f,b4692d5b,b48ead3,ae6c662a,424b63d2,b59deb12) +,S(59351a0e,bfd6fca2,ee04c799,838ddb8f,9d168967,a9e6cda0,b416ce31,88f99218,6e01a267,3184f4a8,28e27b6d,4291e7c8,fc4159d,73a465b6,4fe3d4e9,d50fdb34) +,S(175ee35,f5c533b3,de87387a,5f263d0c,6705ef73,e77f39f7,2c796f91,2cb1aecf,a3792715,4540e426,1e0d40fc,4c5fbd60,5fca3b63,3cd7b506,a80d0280,b9d9513f) +,S(75189b41,597b18ac,9ab6362f,a7905ad4,5655951d,fad033b0,2047dfbb,f347b8fe,f536fd21,ffa10ea,57c023de,256a59ed,aa246842,845afed5,b0177b77,21b2527e) +,S(91af9ec3,2522d65c,70bd2a31,57efd23a,43885573,6b5a1c72,49a414,a19bd4ae,312007c3,8462b858,6b44898e,d0b4419b,31c9cc19,a2ca6d6e,6436bb08,741a32de) +,S(ddb2fc8d,41fad5d0,5d109443,2f283c5c,732273a4,1a14db04,712a1d84,a4565c27,4f7e30c5,2cec6f4,201673a0,9893d092,8f6ac9b6,d7f2da38,d63ba2fa,d69c1d0a) +,S(9ce65d22,d7240dc3,50144936,ea412539,ad40a907,f2b04f96,f7ddc1df,f63641a6,af93e587,7f25bc64,2460b425,76062f54,c3037e43,80542340,cf927609,79d97c8c) +,S(7dc0d0d4,1fedec58,91c3932e,b0bf492d,5489f1b0,1e7f95f5,4936d76f,776e9a2b,d55a279e,760c3c13,bfa1c7a4,93831a14,1e9bbcf5,a535934f,a5269995,b107c47a) +,S(d01215c,b6b4d728,9dd8d351,f3e4aa7e,f190d40f,3281c8c1,63d03a95,4c0e5ead,ef98344b,ccbd7eee,723ce7fe,641854d,c68be6c6,99eea25,48b2c881,b0fdc662) +,S(d4d1c31,a9faef8f,5991b0d2,9bdff3d4,bb6498c6,2933eaf3,e1d06767,8d7cb92f,98f3a848,ac6b91fa,85bccd42,f2185e46,715faedb,a4f6590a,4df5f862,ae6a4831) +,S(cc659ecf,42abf24c,3da2d83c,84b1e32,3d718f0c,41a1b5a4,9fad2f24,c6080839,7bbdfd55,4d843399,b6edf249,ae795758,c7aef094,3f84ccbb,f0f2761a,c81f963c) +,S(19ba1567,d5cff385,9d074e94,478bef34,f0eb4775,6708d04e,594d1641,71ea4b04,34ea281b,d536b02e,da858311,4e59c110,30555c91,c8b90ed5,d4f53485,4a820f9a) +,S(3f0f02e3,1a6e5907,631960e5,fd52d2da,e825d8e7,529586a5,437798f5,d7bbc30f,b93e27c3,3aecd4da,59079ddc,be2cd6a5,62a3bf29,7b40519a,3509061,e3e63c3b) +,S(9884c48f,35f63fd9,5a9dd895,b0f382b4,8d0fb096,e5fab23e,df07924,149ab12,5688c266,7070437c,3d5e321f,58b6f41b,e011545e,989feaa0,13f241fb,4180eb44) +,S(940f2a93,79bc9c55,3082e85a,c2f83e5a,bb4a6fe0,2b23cb47,4489bb7c,c46c7b4d,b4b82380,77ba9d8f,51e7c735,cbc6a784,2aa7429d,2cae2284,700c0e2c,7f21fd9d) +,S(a9a7699c,e5353d9f,41afeccb,b5343ea4,5f4beb03,42f9001c,e0742eb,58b782f0,3c759eaa,b3e18cf1,a4341f77,8a601ac9,b0536fbc,5fb498b4,c7ca9597,9587c994) +,S(a21e348a,9cdb00,56e36cc2,82d0112a,93f4da1d,23f274af,b1522263,b218913,141543fa,652f9506,6ecb8e28,a701e663,c70b1873,b1e778da,588c1f4c,7ebe89ed) +,S(d6d54d95,1121e118,52b298d6,18ce738,e8142906,306a5ca4,1f048fb3,5a5fd383,897dccb8,de891fe2,304fe9d0,38d8eed2,8f76c8f3,535a2912,41253445,828a7a83) +,S(7e0a635d,c937eafb,488c7f7b,5efb12fa,6232b464,a3a47ebe,21cc0f1d,c31e6cda,d2d1d4a,75525e1d,2ce5b34e,3adcbf36,74489c86,ced61e82,2d63ac63,8de921e2) +,S(4ce2080f,66a21c68,428870e8,36b3fae9,55bafa14,fac200d3,afea00b8,d451a659,29e1fa26,565b02fd,318d0f3e,f0df93ae,f0ca1b92,73e31b1d,891f055f,6c7da4c4) +,S(dab86b87,b633bf65,59cd5caf,1b89e815,e6d4b7b4,d8f58f7f,c091f542,712bad2e,8e49b109,d79a55f3,8d8159d7,f55bd930,4506a634,7e57bbdf,8fd15eb3,53c85b5e) +,S(c6a14ac2,90fa32e4,e8b5386e,a7672d39,ba16224a,152897a5,6ae29001,b365aca9,42aadcd6,dcc588fe,2421967a,42ff615e,45cd5f2d,fa258164,b2c0eac7,735dbc67) +,S(2599fa40,880b108f,28f24400,4f3458f6,63510bac,c8a1041d,e694e214,ea450a27,54792ad,4ae1cdf4,6a7a973a,1a02bfd2,a424c46e,548c13e6,951d94c8,7ba57a01) +,S(f6ab0cb4,a6afa8f7,aaed8fe9,e79ec43d,31265533,6fa4553b,bf3d7476,8ed9f9ff,4ea12589,c4ba0090,48c1a476,1907fcd6,82e913bc,57af13f9,73fd9746,845026ef) +,S(f51bd48b,ab8f020e,2d97ecdb,d3ff4da7,72738ff2,bc71dbeb,dfdd48b2,707f1dfc,6b168ba0,947f47fa,8a7fe7bc,e7ef90f9,b361c752,248bde43,8c93f3f,4a697c40) +,S(b601f114,6c9ca90c,af798f2b,1d0bf7d2,a50b286,53521362,5c898f0a,4a2a3443,a6ca3041,36b6b675,5f317a11,59f0f110,6877fed0,fcc167ed,f0cf2391,c61f87dd) +,S(792dd67a,e5957c04,76f0511f,c5b7191,5be6a158,f2871ccb,37e90651,f85f974b,9b7f5cb9,bec59f69,3a44774d,d2f463e1,1a4c1c5c,84ac3bcb,94175809,4b1dd44b) +,S(7d884669,33b6f4ad,b3700eb4,f02514ac,4c29c420,33c34377,93101302,8bb093f9,2fc8c35e,674500db,5287ead3,5e46c306,2ebeb5f8,a5134885,a2f9461f,b5e2cb3b) +,S(9c76eb91,6d0f860b,21b82038,77089435,ead4bc41,df82c249,10edb80,692a5351,72badbf3,38800156,1e235a6d,a8c7769f,e51d1e0,d6de06b0,d9998290,f5c88b62) +,S(a49b5638,3d8a93e1,55e52a2a,a1e47c33,8fef18d8,2dafc24e,cf5bb0f3,1fd807f9,1bc271b3,9bf34c4c,ee4b0760,bc934646,9dc392e6,1fce976d,bee58e8d,901d3ae0) +,S(4d3135a,675bb0b0,ca9d5cc9,68f1c72e,a704c9fe,77aea9e0,a4d6247c,dc634460,ae5d7cbe,72f5f4bc,f2f1ffea,cf02b13a,cb74bcef,68cced38,395a76ee,280cfc4e) +,S(59572fbe,17dd6e38,fc0421b9,b42f192c,eff95583,a9204e37,11f33089,9e53f588,57134640,a8cb3f9e,6a1ab805,1d60a047,a01c8f2f,9b72782a,39c45421,de1c7c24) +,S(73cccc6d,49b4780e,caaa1c61,228d2e9a,a5fff08,f5605a5,cb5ea1e6,712d9511,463a8d74,f986c8f1,1c12ea8b,59b158d3,6a52c06d,6a85b08e,dbb2cd4f,e3752cf4) +,S(b6c8ebfd,db620aa9,476f7280,e8fdcf6e,ae3885f1,87683d1e,e503c2a3,8c4c1e46,9a6faed9,f0210048,be575c2a,c8194a5e,76a25d55,f3215dde,b4091060,e7d39802) +,S(b4162e0f,92de5493,da996c53,93067de3,b9cc4a8d,4c21df7e,b507fc9c,4c5e392e,ccce10d0,c9211d36,46397873,3060d982,eecf2217,7b8ed120,a4052561,6a3b385b) +,S(46bf2566,ca4235d7,abe91955,2a0b8d40,a581008d,6544d9b7,a2a469d7,8d2b33a2,6f66fd6b,b8278841,92d82e39,cd0bc9d5,285b5cf0,2171ef1,b77c87f,c6785040) +,S(78446da4,e869a9cf,8badfcd1,b89c135d,b5422a68,2a9ef6b7,419a914e,3d59ab2f,4215b131,db7e46c1,9e03c051,f33bebde,3f5f31bf,2d428983,27d2b586,5a8c9ce3) +,S(86886a05,511080cd,42bdc762,95eb8edb,fa2b01ca,5cbd1d1f,4bebf001,5605f3b7,c71b69f3,5579c0dc,7078854a,83add404,f9b753ed,597a77d7,67507e77,f7914466) +,S(a02e675e,37f8fc43,fd38675a,744406e0,36d5fafc,b28a7371,e16d94bc,83713388,d6f9a541,835c80d4,eae16251,277e9eac,4ee66bd5,a1899c36,de3173de,fc41239e) +,S(a16b6aa8,432c6ced,cd110096,697bc04c,9b299777,ee287f14,ea4cc889,8492bf26,5c11a70,ef9e42ac,d0ed644,6ea7e14e,1e734da1,89ef1ace,d2fd7241,4e0db298) +,S(66a3f2fe,775fe5e5,d0ba1205,f7b81fca,12d7fc2b,f8685c5c,97114b98,e0f45b5a,5059bd14,a49ad49d,550daad0,30b4eb21,e626e2,95ed01c8,c1823050,5e5e3eaf) +,S(9a47a3ce,bf9a04c6,755c6321,61150ba,a1f09460,ea855785,96213784,5314b3a1,22da5ece,8f387e6a,f37c7045,b9296927,efd3a3f2,2b95eacb,c6cefc0e,ec40a80a) +,S(1c014014,9027b9a1,e3ce3c28,8f18fa87,12b25a53,49f9ac6f,97af6273,5b6628c5,672190fc,d048d3d6,b78bc34f,f160f978,87b49934,5753bd35,3a456c96,e448a4f) +,S(c2d9670a,1de5e876,5ac965cd,497e0765,8d137400,9e4ea31d,57effe5,2e8d84cc,ff818647,a6ddfbb1,3ab56b58,52956d08,b97a2e8c,f852379,cc7a7271,f13ccdf1) +,S(1a9fec47,16fd6a69,70ce094c,4141d68f,d21339e5,5396a691,e01b1e5,c996ec1d,e38eb2eb,6c8373fe,94f7639b,595de291,d29b8738,11f5d40c,24006d8b,93f8557e) +,S(b7df52ed,15e91a6d,40e9e500,6b1ab26c,53a51466,98d63bae,77856afb,1d8c464,ea60f1bf,d915fd8f,99d0706f,ff180d51,705c360d,a5fdac1,162ec530,b6e21254) +,S(2f95cca,bd092e2f,bdc86a53,40353350,918ba7f8,8488b9d1,295f9959,d7db6b5f,31456814,fe6ced86,59ea9c3d,f09bf38d,d5b0f893,8db1ea7b,5234648d,a1693ad2) +,S(763926c8,64dfe4db,6a1a432c,a37e4022,3b6ae1a3,7def3fea,883a6612,bd8a7c1c,f34d5b72,4378d10e,bb4b3e63,d80f1f98,a3e741e5,b9e4fa41,bd3f0a5,c361bd1f) +,S(2e43be7a,12916cf6,f312a513,fcb6c98b,708ce2dd,18dc4ebf,72a807c9,c8a31b0d,db919224,ce1b7e57,16e57b6c,ed514cd0,a3a9dc09,8cb59c5,971e99d0,dc24acfa) +,S(7d65e48f,1a867d28,76731984,afc6873c,2d1acdfb,13a5adf9,a56960c1,cd4a5561,9c73b955,f0957ad2,ff0e2d4b,caf795d8,bc992436,be7e69da,7b97ccbe,d983ebfc) +,S(1c6becc0,3131b772,cae166f0,4d715390,6b132c87,c5c76b7c,10b94a71,7819d725,2c3c64ff,94998533,97dd26c,dafdf608,41b84a22,cfb4906e,318c4d24,b23280ad) +,S(f5042a5d,5d118102,32ac83c7,d7edf079,aff339b0,7e9d20f8,198b2a64,13347675,19c10fbc,e644fc6d,2f238802,a045052,b2723f57,5a8bdd20,b597dffd,79a3e4c8) +,S(7c387866,c2c0353e,6e00c887,240e084f,e0ee9f0,2de12539,b4833588,bd4be300,ccc66f94,587fc58d,42fc49c6,d074800f,56f08855,6caf4ab4,c37b43,ef2b8f79) +,S(ece8ad23,d33adc2b,6ce38194,58ba2ede,104b35d1,1691f4e0,b7b206e4,eab3c140,eec976c0,7fa1d3f5,f3c245a1,2c9b728f,1c7e672f,53665e7c,5c6a408f,7c0c0a88) +,S(822b0926,a274dc38,c9eefecc,7d021774,b951cf19,3e2cbc56,a1baf58f,19d12b9d,48bcb10a,f9cac375,8314d2c4,9fcf0512,3638f008,510fe63f,1be0c2de,44118313) +,S(d26a3a03,6ef5f428,fa058d25,7ce62fe3,401dfe47,80c468a8,5cd2e77b,f85b8c3,98c39762,3a644329,7d5c6759,a308c2db,62f1bbcf,9bae4ba0,10fb1175,126a6fa7) +,S(7febb81d,8aa0cbbd,3002ab6,ca247d1d,24c8fcdf,bb1664be,b5b3c346,93019090,ee625bcb,12ca6da7,544ca6c0,2a84b9bf,966dc923,d8b23b44,6cfa4604,a6c3ec26) +,S(839e44e7,2d43b6bb,e6f63a75,cc3644ba,b7aa002a,6de2c087,33df2b0e,51d3473c,8368f635,26f41422,a563806,d775bf68,2d876d98,542b3da4,3e591e31,340fb9a9) +,S(52e947da,1c96e07c,9e2c84f3,23f2eed9,7e049b97,86d21135,ea958eac,db0d7afe,6bcfdec9,e0c70d3d,39de19a9,9fa72ba,bdbbe50e,dc44897d,9fa670e6,d473a831) +,S(72ec5426,5e4a743,1d7f6dd7,1c8e9e4c,c8b22074,cfcb00ce,db18c6b4,c67f3603,ddb9360b,7f9def94,f5ea6d71,51eed4ba,49455cf8,15bc9023,6156d4fa,786b5ee5) +,S(370a3f15,59a55689,16bf9ba,f2863d11,2ac051e9,d6a90f36,af39add3,1406c849,854cbda6,8517cee6,95ab5d3,20b1067b,ee80d993,235d1dda,ba3a0ec6,1f005840) +,S(12e57888,60d2fbdb,cb3af527,577ef6a1,41d1cf0c,f719ac6a,714f9a39,9bef5dc2,f5af7aca,5dd8126f,7dbb79ea,d5a4b475,a094969c,64adc821,ab46c5c1,86bd9ea2) +,S(b494abcd,b2fa5de,17b1abad,757bf9d2,8b7905c8,aca0a5bd,fe2ad8c3,30a2b722,c397ffd6,dad8619d,9ff8d8ae,e401a4f8,cbacf710,c6409adf,bf991d72,9294cb87) +,S(2957692d,900d0b94,b208245c,f71bdcb,118ea6e4,499dea83,1064605e,8ab9d89c,a3c55447,9284afea,37e94,fc24d50,f129342b,7ebbaa91,857d655a,40444a7b) +,S(61101879,f325e072,bca13642,dc14a5e7,1969aed3,2e49ccda,39cbf723,a1bd20eb,4e199c82,4816e4bb,d5b67269,e9d8eb0b,e5c2483e,d66757a9,c1d59847,e443b3) +,S(9eea48b2,99f3474f,8aa8c648,c2721fbe,c65f6ad4,990ab4e4,29a9c41a,ba55ab18,13954697,35ced1bc,7e857049,7f2b5a1f,b6802892,fbee0654,c1d7d89c,1f234443) +,S(dbb054d7,8ba7b707,ca475982,6a36808d,3fff42b6,31f1bc5c,c9df403b,518bd97a,396ef6c0,96343a55,dd404885,427e781f,a55a1f8,1ab95d4a,89d87975,611b923a) +,S(dba95bd5,7fdd2ef4,9dbcc0ea,35c14dc9,b2f62541,5b08e75c,d70f3caa,b61bbcf1,2af0965e,b7a17e46,18b6dba8,415159ba,b8f76ac,ae9384cc,64a90e32,d20a3d) +,S(6c312c9,7979bb0f,e72d8feb,c3c755db,bf1a132,722f6ef5,297beafb,8ad0e5be,36366388,db74739d,df78d5ea,3d8fab54,6c435961,71f78643,8be00718,8202c6ea) +,S(65eb7057,a494bc8f,549b8638,e18cd717,ad987030,aa3161e5,b9fe31b6,dc8825cd,458202a1,67f285e0,9196b4ac,f87068e2,160b7b42,2095bc92,7656694c,2fa80312) +,S(a0696917,b0e868da,ed5db7cb,d2aebd1e,c1117426,d842c0d6,b567e2b9,4effa7f6,c874d20d,a1bb4dc8,f01cb828,be8bda8b,c797ec3e,37feb0f5,ba55675c,41ecba78) +,S(4191bb82,19372a13,2dd37830,1086b64d,10874479,1d3b7879,3b27c65,782cced2,c74907c9,8ce4d218,d1ee52bf,82e130bc,49335279,2497b4a,34892fca,67dc3f2c) +,S(75f37d33,721293ee,5923b9b2,b95c958f,945e3f2,909c38f,3c3e7f5c,79b218c3,ac041f8e,c6b222a7,a2f28e18,1cf11aa2,a7d2fda1,1f402a33,9afdeace,a5928be7) +,S(cbc3173a,b58b2f29,20b3bef,6f18a84a,6004d1f7,1dd6c65,78571afb,96fb154e,c413a0b7,6f264414,2d3c166d,e9577ee1,b8f36ec9,618e8892,26de4de0,f9fd5c37) +,S(64e56b09,a139fa59,69688832,419cd1bd,64f212f4,5bf4cdd9,2a5e4370,dae226cc,a9194eee,f2429016,4b41eb3d,b429415,d10915a8,62a02fa7,671bc19e,50fbbbe) +,S(e33795c5,e2886cf2,9a22c2fb,8e02f913,34e13350,9cfc14f,73bcfb49,355285a6,7890fd21,f33d48c7,24e580cb,7b4bb065,f7c575d0,c6cdf5e1,5c2d6423,1afb304) +,S(7975e6b,7a73d0a0,d1543d2c,76c79233,6e6a0994,35eb7699,8f25ce75,a6b0b6dc,10b160ae,c68993ed,d5e48d5f,7562bc24,8f16eb10,a27f7115,121ce2f,f63eb06f) +,S(6d0d13cb,f9c13967,92e093d0,801f441b,c1ca4484,92ce3ce0,2ad71cdd,d1580f6f,17ae4238,84caf022,bbddcfe3,37a44309,4bdb25d4,71da56f1,bae4bf2c,ebb45746) +,S(2195f14a,23af2b59,c9fd3f90,42608037,60d39867,3fbd0856,a974a20,1bdf0154,fc05b38c,9a44ef01,f4db3a10,b500a372,5ff1aa58,86ff6111,da53ee14,f8136a8d) +,S(47679c73,60acf8b9,d1b54e16,7d1dd1a2,1f558288,3844fc4d,ac2a7fdf,8b713628,82a02225,f3b8e81d,e4d4bbde,94f7cd97,7ca0180a,ff3a4751,a93f6ca,17803ea7) +,S(b0bd02f5,1636a69b,23ffe514,cc2166bf,8cb4ff2e,2f7c8655,ac9aa7c9,de30831a,73fad62,48bacbc5,2a7ffc51,fbeba3d8,f4843b3f,ba6c8814,48add0d0,8fd5f518) +,S(dfaeffd6,bfe9f81f,ed3f81af,adbec5b8,aab5f15,23cb7452,c689b01,a3660158,3f54d105,c3ef4814,e6ca4bf9,ccb5b54f,30c4bf80,10d7b24d,f3b5f3da,c9240583) +,S(eb016abb,da661e49,8f53d2e7,96fd6be4,80dffae3,eb7e4ba7,46ae06b,f40d42ed,310d6dbb,aa7659a9,6cd4d50a,dc2e5e85,10f005ed,6d29d1f5,18bf83a2,7af895be) +,S(989e1bc4,3c0880b3,6d35b5eb,137f8e61,7263784c,d2f35173,e517afb0,c99fb2ed,4c4ceb5f,110cccc5,3a35963d,11df77d8,999b3bb4,c2cd92fe,b53b7476,9dfaa1d8) +,S(beb0170,be4a7bbf,1f65bd40,776d5efc,dd801d6f,909250bb,fbee1198,c2033811,1356b98a,1d329a38,57a99820,26d3ce6c,f52349d,fcc59644,ff4dcc13,8486461f) +,S(2d90bc1,986f9a4d,6f75e596,96c4296a,ea9bc55d,5b60d12e,337cb42a,ffc0b145,7d57cf64,734d1997,bf84b721,e67eafb6,b377ccbe,d2ef3b5b,48dc9f06,f71a0c4c) +,S(6b7a6a54,c9608062,de196848,dc3673bd,59fd53f3,fee72481,e829ca77,789f51bf,6a9ee208,157b8a69,f0879f30,c58afbe3,dd4dc42b,43cbf21a,5795224e,6c09af23) +,S(c99244c7,32cbdfe7,68df8fa8,7b7e7eeb,16faf0e8,8870fa8b,f4abcb68,368e8393,20ad1b55,53ba2ad2,40563453,b2dae2e8,58cc9b8c,c6a49951,bc0c0fc2,875620ae) +,S(553fc07b,402a8dc5,5f1cf4fc,609a01fd,350fef26,9c1f93f6,d2871f94,70f01b6b,3b518c75,39616def,fa7cd0dc,7d7d53ab,9b310217,7e470290,9c199137,34e5a824) +,S(c5930378,6ed8a7c,b3cdfc80,a34c85bb,721fa927,9492e369,a4e4bec0,c0fe2f69,3699e469,8a3e9129,3796dea6,213fd702,d7580e67,9f446300,1e1c7a53,3717c149) +,S(cb6f1118,f4d59964,b8f4613d,8c349d74,8cda0e7f,f1d11c6a,79dbecc8,911e7eb5,62b0ae88,98b0d5cf,723cc88f,48257c47,ca0fe3d,7de676f4,cf4835c8,fdde20ee) +,S(da2cab8f,8c26668d,d9722ae6,1decb99c,78b5d48c,966889a9,46fc522a,31a26db9,6a03377e,234f949,4a614cb7,c93b131,1808496b,12485ad8,fc21e1a7,6d0c7e98) +,S(fc6a4d42,3f9be3c7,fe337411,f03eef,fa595b83,9a6eca82,b228d5e6,b43b7d86,6c089544,eb8fbe1a,3dc78fdd,ac253fa8,27dfbd6e,269196f5,bb476865,a298beff) +,S(73c9a91a,b9c6e0d0,773258e8,3ca9460c,3d09fb49,9426fe09,db73756d,e3dee882,8b314327,efc0508a,d5a90259,c9ed876b,52040a10,45d06224,78cd635f,e571d2b3) +,S(a69f061,45b8cd1c,343e6127,14b80996,2bc02848,ae976762,933744ca,3b4516d3,87518d90,b4503741,ec16caf0,18615e27,96b6d91b,47f649ae,a86da209,d70ebe3d) +,S(1cbe4a25,70df40b7,1cddfb2a,c15ba441,376a430f,446a2572,fc95235f,28ed9691,12554ecc,f262e1aa,cf2a2d10,ab3953ee,c8ac69f3,99c5380b,6ef5d202,5613de85) +,S(8dea49c7,406dccfb,4305ac85,ba08b191,4ee2f11a,8827852f,d13c837d,b788e27d,c73d61a8,3b517c3e,bab8b15a,b7a0506c,2b6071e5,697b4056,d902957b,cfe9d9b0) +,S(de926377,b175cc3b,1ecab5af,81d38d6a,5e4b717d,55bc94f,6e4c43a4,86d0ade5,29d5f3e7,9169d974,d4289115,d8d4b8b1,6be387ac,e60d1cb9,73c387d5,17d0e11f) +,S(6e76eaa7,aeb37ab4,ab455a2f,3d525140,f6e8a9cc,5eb18fa3,8a9a25b0,d3b41497,7e3cc5a,78909d15,bbffb936,a47aabd9,44c40a3c,d690908a,89f193e4,95e066fa) +,S(37131ecf,22d57f0d,a662b03f,c9891f99,4678539d,37f5ff8f,9eed0f8,bc607574,c03b2d21,69d42968,f611d596,e173d4b9,281323aa,6abae6ac,c177a1c9,1249f3b3) +,S(72088814,82c89957,28e76633,bcdf0ebb,65155c8f,4979a4e7,66713f37,4a5d8152,6783c59f,8c0adc8b,da8e26f8,1990a00c,588a7974,b48aee92,d2a762e5,c974eedc) +,S(1b8263df,baca44b2,a7fa7a7a,dbf9d3ce,d4567fcd,144d9e8a,db712365,d3241864,1fc7e3e,24f01143,1944b98d,b2dac036,edf36680,80196785,783a41be,d788606d) +,S(7a372de,27ca7f2b,8199714d,bd583edf,ea41bae0,5a1313df,f1a8c260,cef5fd43,a0e3216b,b32c5785,b5c60f22,f5e4ed5,a5d3ab64,ba0eb2e2,916f1b9,b6281142) +,S(71815daa,55254491,c8bb9432,755ac1f0,c30f22fd,79d4232a,72bec0ea,8cd02300,8b341392,8de15c16,5fafcc68,84ebe3c0,3ade0918,4c463804,876f1600,c76471b4) +,S(1a54b7a,d3cfcc64,b62d866a,9f2056e,5535d4c,12c89c78,5d1c5c53,ff654d2b,b7c77ae3,9f4b87bd,22c77395,a91ec307,e9f5aef9,dd2892e8,41d8390b,47a12f19) +,S(85cb4457,1fc973e5,dcb0b695,3d75a2ec,22cd2820,74039987,7262b7ed,999c44a6,efdd1df3,bd13fe66,c0d4ef02,8e142093,58037a7a,bd06ed53,280d3318,9d0f6aa5) +,S(98e8649c,64a010c9,424b305a,2407a36a,cd72df8e,138df962,c35bdf75,fcfd4e4e,a804c569,34395d7c,549f7770,4c3faed1,624a8cf6,fcce08ef,cd3aa486,d5a6c60b) +,S(1eac47e6,a297e5a8,8f433895,874fac8b,5019a164,69c6a881,7e500b94,74a5a72b,8b7daa6b,784ddeae,f380bb1f,fe64b9ed,43a10a2,95c30325,f519e4ae,da11105) +,S(f079ac65,91f27363,17e9e0ab,6a723e25,e29950c7,a02a66bc,96c4ae68,44f42f5,ea87d1bf,c99f4374,4acc3ca0,214a1ef7,490186d0,3d924562,24981469,c432dfc5) +,S(d6d09d79,bf1f30e0,f011c3ad,a077b1d8,fa0d94e8,8683186e,ba471caa,32539643,8770bc64,fac8f541,f730494d,cdad2d48,ef510037,466bc049,876f5cc9,7caa8adf) +,S(376e4bd9,f8963368,7059565,68313f89,d6416ca6,b1e4e91e,3aff3ba0,b8351f65,ba436de5,67248f1d,5e99e8b9,6447cb28,497deea,47fae95b,78a5378d,e65f13f1) +,S(270f3a18,4b42c799,a2193dae,c96f834c,b17cb53,bba1610c,6578c741,b9f20d7,ccceb12b,9ab98bbb,a0fb0d0,1673377e,3a7054a9,f4a3b000,21b67328,57e7e5bc) +,S(ae271b64,1a1e5348,29e47a8a,93b496d0,b055d2b7,fa98ade2,f505a5d,ec1a599,14e9552f,39b481f2,522a9a23,f87afa9d,5847908a,53c1581e,45dfb244,7fc2bdd3) +,S(569eacfb,177d8a74,a9288ad6,4ee5390e,db36a93a,943fd6a2,5ec869b5,a7f28c8c,1cf62c32,9127642b,99a7508a,a6f4f136,bfda9af5,45f52844,cb9c71b,5f732f7c) +,S(77c7f27f,fdc4e7ba,a326a246,89790f8c,41bfb5ed,6d365e46,f277cf81,5f15b558,4d3440dc,138be5d9,566a6828,852c2ec0,e0f970eb,4501a43,25af933b,821c3007) +,S(d66292db,f1730306,a87f67e9,b044fef9,7d46761e,7b8301ed,132ed7d8,94adbb25,ceef7755,8ceca4ed,92145f23,8bfcb32b,3d36db14,6fc50209,cb0e58f6,2c8b83c5) +,S(1c42832e,12ea6f44,b77927ef,7ebb1f3,8769e3bb,f5507a49,25e8565e,a77ed0d6,8b9383a4,b31b4f5d,a717917d,9e1e41da,786a62a3,327be11e,280e538a,9c29d5ee) +,S(63e57eff,942262a8,cc362911,fb98cf30,60832435,3cd394cc,5d6abf77,b21f7968,9e3c1e2d,fb9083f2,4c344e7d,322ea530,146062e2,a25fb6b0,4502ea35,59b009be) +,S(be233fa1,86f38a5c,72c88e59,19094ea8,cf3ed3a9,b4ea3f9b,2a51489,97b83c90,402eb2b3,362fadb2,6e389ef9,edc537bd,40bd48ea,6296956f,efd19d0d,eddba564) +,S(636ddb80,4e7c74fa,9c5f4d06,5a730fce,f2cc6956,4a24b579,aaa0c3f1,61844b78,6a4a3569,583212c6,22feb59,897eac8a,6aa31ffb,916262e7,deef47eb,e6a2496c) +,S(d251c1d1,7250d87f,f7b5af1e,ee2f2566,215ae7c2,b6e69e60,5bdd6c2c,dee1c5e7,245accf5,7df52fa8,cab5c986,2b96658c,5de60d06,c84584cb,f554b518,7fb4ae78) +,S(405d4cb8,c62f133b,7051cbe0,54b06f42,9055f917,3ba8248c,c3bdc744,198ed407,8463df10,a8963cb4,298e8031,bd2bc3ed,523553fc,60746720,1a9abba7,305deb54) +,S(97f05aee,9ab33a07,e14a0314,4fda5be4,ab329394,1ce8f003,546ed8e3,9be983b8,59e62a26,7fd9138b,c4c70b15,533782cb,d321f120,1e3d1a7c,3be4ad5b,eb849261) +,S(3388161,18e125c0,6a9060f2,6b9ad691,c99fdf8d,4309553d,ea160749,eb91ac8,583e918b,5b8e1a68,c053af0d,245a9902,a571788f,dbdc0c88,7281767d,9404384b) +,S(ddd20c46,6bbe6a25,9f706b1a,ddc3b607,8cf65366,3369fc31,dc8f7fd3,3d17a9f9,b2df7b29,b4ea9868,bbaadcf4,6621ccf1,7833e159,acb43daa,7cf78e89,c1de5a99) +,S(923c6d2f,71ae0ee5,596c26bc,31389cbc,eecd0712,e8df91cf,dfe00172,3bdfc9f7,6fdb28ad,27c41243,6a41ae96,99a03d40,5ff2ed87,3207f082,414a4370,34be948) +,S(6d42a6bd,28d57e87,66a12461,b8a7d111,a448876c,149071a7,fde9df18,dca09e65,4df07ab8,1dbe97c,3585554d,f0226234,dcdd2826,747f2775,640bed6b,95fd28bf) +,S(7fd42961,59f9f259,d3c3610d,8539ece1,70efe104,31c9a3f0,4b9630ec,21d761ae,fd695441,b8ce2bf5,1037d00c,4d50e640,e85b6001,6d5d26dc,787f1df1,25d7e280) +,S(48c1050b,128d97df,e7900a01,70559990,944045dd,f408d8a7,5b59bb25,ea6770b5,8f7ceda0,4b6e319c,1cc61b31,53538a09,d450e49f,8863061e,f9b017c1,6cf66559) +,S(54462d9d,a12d62dc,96abaa1b,4883c67c,b3214c40,de5a4a09,689658f7,dee2a686,7673ad6f,916011d7,fd33bb5,eee819e,6a3f0016,d51ae37,bcfec2e,59ccd957) +,S(698534c4,e4e11d89,82a5a46e,44b771f0,95c5fe47,54d7a261,44373982,1e6435e8,36d602ac,b2720c71,8d619a8a,5e7d6873,9faba099,f71c1137,6a8f41d4,e1cbba18) +,S(4493f759,51c681c3,bb376b0d,7c88ecd9,d0bc2a21,26fd341a,d8c4832a,be77ecc,e553e21d,d4d99aad,97f15857,4bfd54be,df7143f4,e829c12a,39109892,c120351e) +,S(b054daa9,330080e1,89784cf5,f917c024,6c06325e,687e6ec8,cf8be248,ccf8313b,51f04715,5c9ce55a,c755f2a4,602420d,4ed52a5a,1dee9a83,b0688b1d,b767d866) +,S(4b4272a4,fa996b1f,9ffe6796,e6519db2,c1f8cfc9,606fbc57,1fe03713,c029583e,9526f2d0,dce7c53d,5cb36f8c,fcbc517b,cecde833,4384d10c,f5fc80a6,ff0edb83) +,S(d61eb681,c69de82e,caed8e64,7d1a3948,6cf63f83,f1f04bff,46a04aa3,63e29604,9b5a92fb,156d7b8f,37c6d9a4,30ae28eb,f62fdf5d,5bf441df,aa386259,721f08b8) +,S(bf8f002,57f979c0,9f973c8f,3dc15eb8,8349e340,efd8d57d,5763e4e0,c2bf507f,561d862f,1041e670,fdc265a8,36d363a3,43346739,f4f177d9,f66414a0,820614fe) +,S(63b254e2,a7a6fad6,4d9ca03f,7293a86f,b471fd45,51ec72d5,eb03e289,774cb498,f4145111,3a4ce922,dc7b3819,a2de49cd,f5be7d53,6befd880,837bbe7,51948c8b) +,S(bae6facd,e1da6ed8,63491f33,c4c9efe7,50fdd908,6b93c09a,e0418a29,d3968725,7c7dc955,e483176,f6bdf74c,6654e6a2,e4ca46c5,2526349b,b4d66090,6ea30533) +,S(f56285f8,ea15aa08,f3ed8139,59c660b0,d30a6317,5380429b,59584623,aceb34af,110033c1,a202194a,40703c9d,ea2dcb9a,d9a0f6da,7b99b8ee,31eb1ce9,55a9eb9) +,S(876c7c95,3de3d451,edb9191c,60e8e36a,eafbad2,198ec6a5,40d72633,8151d87a,95efff74,72ce0c6c,4010d17,7e52a859,cf55011d,1005bd27,df54e25e,972279b8) +,S(e956c7ed,77c7bd5,68096902,4ab1c758,a024d86d,ba3f30e3,fbfd83ac,940a6d30,1b5dfca6,f0d19ab7,7a57a9da,259a564a,5aa5759,ce6826b,45c71771,7aad9da) +,S(f53fde61,abdb4543,1456e9c0,65048cd7,ab743b5a,81a468bd,8fe2ffaa,99dd3f16,1d28b539,47ea22b5,178e86b,ab3561bd,a65ac78e,e0e2a6bc,1a26b64e,d790222f) +,S(b91a8681,52eb435d,475b9103,936a7c62,5e49b0b4,f7bcc3b5,f5d36449,c8043ad9,c758d17,56939bc0,61696f3d,11dd1bd5,722dc90d,1e8be88b,b3430062,a13aaa75) +,S(5a87bc70,23e32927,db4c55d0,abc97536,61f5adcb,b24c2897,b16f08cf,8d8f8cc7,9ceaae4b,aa6a0d5c,46d2120,fbff74b4,9d1ac32d,88a89b2c,3d2aa6e0,6f731e54) +,S(ac0b1b43,e54eb354,3bca80b9,efc5cdb1,215622a8,66b66e80,de979f79,71ceb034,a891575e,5731e152,17bc2b87,197da9b5,439477fb,d2bf07f6,9bd13f3,f4638d8d) +,S(d3c41ebc,2017cd82,76f4d6f3,f6ba2370,e84f1949,df3abdc1,45073467,e85ca915,52ab1d52,8be55945,1f6b1e91,610fcf35,bc1e9576,3ba3ece6,9da5e4d,8cdcf7b7) +,S(68cffc57,f4c82cc6,f7900d00,fe1b0f36,ab842e4f,49ee9063,4d1ebe95,47923b02,729955bf,aac10741,c3fda281,c18a306b,367ba904,baed26b2,6fe6a485,9ab1d8e2) +,S(7e0f58e1,246299ee,e08566b3,35324a66,579dc765,343f874c,d30f2553,8c177d9c,39652583,587293f0,809af7b,5d366740,86b9015,6a05928d,cd340196,8821447c) +,S(c72abbdb,d1816498,eb53d4bf,1b325fd6,5dc45086,73257bbb,97a15eb8,e4c9b542,3c8fafa5,5df5f3d2,88441ed3,e46cd318,841a068c,b681b782,88e77afb,2b25a7b9) +,S(74747f5d,3eb09144,1f64d76c,ef690378,943654ca,73fe15a1,b720abb5,d2363d0d,12c6724,bc7e8f7,321f993a,5caf0547,bf54c1a6,41f959b9,746fad7c,1c443649) +,S(f2a702d1,ab1de7c4,34cb5d71,dad689a9,29db862c,d1fb06e1,212ffc8f,91b67067,5b91e2c,c730ac9a,cb7452bc,7fb4dcfb,1d5ec11a,bd146429,62c7bd16,37afd854) +,S(a92d4f08,14e76b46,5fda87b6,201c46e8,c2535b3d,4be91e1b,530b5634,d00d9340,4d829a8f,3c02fb40,569fd9bf,e754dad8,38d96dbc,2350f0be,6f4ba065,5cd0277) +,S(79e30cb1,ac06c3b3,f90ea320,60a80fba,df5ea142,84a15746,2aaf917a,26f205a1,ad220a0a,81459495,5ac8a79e,d0cba974,7f17364a,9f6168d5,3521f276,c8d5c82f) +,S(6d55dc53,d412577f,463252b,e240fa32,88c8d6a3,babd6ff3,20231b6,8c9401d1,83a41c96,aa3b32c0,59155345,2679f056,c98e17c8,a0a5e154,d732fd3,7b006eb3) +,S(cf9c9f1f,604eb909,b37ea5eb,4cb8a0c2,11ef14e2,d3e2f48,7c83b56a,49b3f20a,2b90b9f6,4e649988,77260b5b,ecb441de,da24eaf9,df56ff93,dd3d1c8b,a247dff8) +,S(60d4299f,29ed994a,b3367780,9ef6fcac,e30f435b,ba9a8346,a2fd925e,186b35dd,df69b88,b8aab4c5,8ff86ddd,2d8e424b,40d51a4,9d189437,37b23695,4760331e) +,S(d93a6edd,1b674a60,6b6bbb85,4114a3bf,7de3be59,82cd2122,887c5376,d9493540,87da37d7,dc79197b,c0159006,4f921ae7,acfdb08c,447ed230,423c51bf,f9e5f7ff) +,S(cf8c3d37,7e108d98,b72bb6b3,1cb7b5f5,fd5869da,1a06fc60,25d9191a,bd652962,6f5cd02,bb96ad02,db42b034,321b3cae,fc54271a,879edc93,afc9c8b1,34128fbb) +,S(6ca99247,4637ecf9,827ab65a,c7b9ca0c,715b9048,f24c42a6,90847e68,8cdf29eb,51378da5,fefa454e,d96a446e,dab57c3e,8bb6160d,d015c1f6,d93983e4,feb55439) +,S(6f7d2c04,3cb813d5,dea67758,cacf2e3f,3cc3064d,7b9f08c5,58ed686d,28d17afd,4794e278,13ecec48,33f9106c,17c5e161,b590a5f2,ac293c8,c65a6cc6,5233bc6f) +,S(f8aee0d0,bc9883f,ab6a82b0,184e9199,e818d01a,7d99f475,d2ca8a24,e924f3e1,acf9cb2b,69135df0,9426bfa,c6b1b3de,44f1055e,5cd21b8a,b526f34a,839442b5) +,S(8b00fcbf,c1a203f4,4bf123fc,7f4c91c1,a85c8ea,e9187f9d,22242b46,ce781c,61e9e58a,3e81e690,ec026428,ee5442a,a8de699,dadfbcac,478985cc,89d35bc9) +,S(fbacbb07,8e84a2b2,c201ebbc,1cc3212c,a7278523,e984bc1a,b0eb7fa1,39d6dd4d,2c6c9dd6,f5eb0899,797df675,ccbbaa25,4e557d5f,d16c6083,3aa84a7e,4c3a0f52) +,S(1556875c,2f32f053,8d28f993,53ba2804,5ba601bb,3df8a175,bfa33dac,ac5c0611,53623050,c3da9464,8e9fb540,5888e387,d2eb783a,10e45cf8,ebaafe84,a4e240b7) +,S(b602b095,7f5b5e98,ce3e690e,c683f803,49a8ced0,5985f79e,2e972bb0,2d93d77,78868390,ddd6b821,e30046ac,b1bb7b31,ff358838,af5b89d9,60d39b4e,85435227) +,S(2a110165,23a5244e,89d66f8,a06f0553,7a846216,75fe4377,24f51501,da2dd17a,24d3b525,e1ca62e9,b02de498,30737f3a,b881d078,7d2c2bff,938c53a1,b8825159) +,S(7314759,1148f9a9,ce326a8e,4f43d2d9,a13edb92,56fc9d38,35a35da6,457efce0,b195cc94,80d0aa04,d3ac7cfa,45766472,1ad5adf0,3060b790,c7fb0ff7,77b2d8b3) +,S(a36e4fe4,c7e23d7,16362979,c5a9d8e0,525d864,37d96e3d,b2f45edd,b36206fc,56ace785,a428db4,a8a70de8,708339a4,346699f,697a6707,c745635e,66844751) +,S(97864be7,a2c54118,5d61b61d,5a2494f4,85b877d7,e8864402,3444d778,f43cac9a,43332a78,a85b8391,551dcd90,e93e71c,3a6c5428,71b980ab,138eda2,b9f2ff69) +,S(34a52dbf,2449eea6,da2c92c8,45dcd47f,daa7ca41,5ff02458,b74eb996,8519893e,add41829,900f26c9,f7ba8d55,21f3bb23,b3545a35,699d41b9,4270547f,e303ece4) +,S(e250aba9,94eea617,5fb7b2b4,8631f5bb,d8bdbbb,799f6fcf,5afde8a6,2ff3d629,803f34f5,9db0fa86,bcb6fae,689530fa,2e92c4ec,bff1757,409bd836,8143b0ea) +,S(18356a6d,b5946e2,1149347a,4558e116,7953042e,e3b2a372,869ae29,b871ae00,56ef0971,6b176f81,e1f98ec8,dca127c4,ba6de23,ba8c1f08,f19e9abb,995385cb) +,S(35a8ebf5,e5306084,365ef3f,30c29e56,ca5932d6,f73d688e,ed3cf2a9,10205533,9eae5d95,42954de,23d41032,5ada759e,20d30fd5,c2d058c4,53a18520,7f259958) +,S(37e06f5,25ea8fe9,ea862b92,53a965f,7b3dbe90,9ca487bd,a705041f,e6a4e1b9,83919fd3,5e489bea,23f13b60,41a19940,3f2f6568,fdcf60d7,3f57fb6,1fceb97c) +,S(abbbe697,ac6c002f,11062947,6e4a6ffd,48316646,718d8713,1a4dec19,5e131c27,b2c926cb,9d5122ff,7f8d8a24,a20eaf4e,fd704944,9aa48300,92971572,b12f9dcb) +,S(4df36acb,1484dcc3,f7c29c8b,78915315,5a1a3636,aeaca043,68a585a4,69b05878,fe16fe6f,c08af026,3fc417fb,19564534,aa059f4b,b7fced09,d4fc20de,6a41c41d) +,S(5ff14ee3,10256a0a,889570e5,ebdaf6af,c8f49c60,dc7c4731,23a7d29b,e799d0d7,96ff1538,55eb2fac,8f2a923e,ead9851a,95382d6c,56cfd0d8,9891d2bc,f7e65d7b) +,S(16a12c52,c1d422f4,791281a1,b7ab7186,a24dbac8,36af6810,4f62dea2,855d119a,7a6ef272,f67356de,46996cb3,8bbaaba9,d36a4bf4,60e3b2a,b3a81723,24c17478) +,S(8f4c9c33,83688920,a48b3d15,4fd567e4,5fcdbac,bea44eda,60600ffa,a1489ef5,2bb5bc4d,e06444c7,b2bc0082,d629e2e5,a4b0abd4,8cbb9b4e,37d564ca,db885717) +,S(498bf39b,7547010,854ca399,e50399ca,19236d2f,d05f5777,6abd6d2a,aab83310,8e2debff,cb58e36,bcc7beb5,8a45d4ba,b5edcd46,2c355d0c,4dde51a6,6afd691c) +,S(78147e0a,2978d396,b22247d1,74958336,2ba51d90,11e89c11,71e6e136,eefb5996,a66b7b0c,a73b661b,e71bf0fb,2eb4410c,4c75bff5,b8b05fd4,1d830d27,ff85989) +,S(351298d9,fb236c7e,5477aea1,d2df0048,47e112a2,e16adf66,3f4d77dd,828d4927,6c9c91af,8b6f23a9,d15c3884,e618ae51,241094d4,5878ff20,67f2ac81,dcfe00f9) +,S(fb5ffc0c,88fb609c,24cffc14,848549ad,c1814668,9e5f8a67,a342bcbe,16399d10,a995e13f,9ced94cb,90feff32,8e92e978,88cf5791,c885ca09,46f46e5f,b8229ab3) +,S(8352b7c4,4cc09c5d,717bd197,40dcaaa0,89565e94,77cd76b3,6c7a4fa0,4832097b,9507c998,fa25d9,758ca78,6774ae68,f91c8fab,694c5e23,6f8af6c7,7d0fe6bc) +,S(1be65c0f,273a2746,d6d014d7,6bb1c595,5d5ed1db,62ad940b,d8204115,85919f4a,dac98f30,2a38f839,a3d470a8,3ef83ae8,f044e93c,80b23552,da3da359,5c09a3f2) +,S(7107f3a5,2f4be227,eeb65037,ae800f64,8de14d89,ebf743a7,ed65f98c,b58418e,bfcf1c09,bd1af327,d14e429d,18eeae45,927b2df2,aa15ce60,69f6a74a,69fca7a4) +,S(117284b,e8edae5b,1ce54a13,3b1f9d98,983389cc,a4ccff,9dd04973,97312e3e,91e48c1e,724fed49,8bf51999,4c84d0b8,84e3af77,86e61539,638b45c3,8212b03d) +,S(a08d86de,b1ff9ab4,651f1cd0,d89b6714,41c243b6,c7e655de,d31b44a7,b00de54e,4d0fe7f6,344d39d1,57764fee,f74cc949,a72ed8d4,c2dbc12c,ec2629c,830f0d2f) +,S(9c44c1ce,df67418a,eef2cbf3,68d48a08,98cfc633,de711550,3f78ecb5,a4e8c25f,3cda2020,86d3f096,31da959b,9f9870c3,de3d3c6d,e4c1b35f,81f64dbe,31e743fa) +,S(d933e475,5215c065,bab118da,6f24d714,f8597949,a52ae319,250338b2,2339f149,5fb0f28e,313af04d,de3abfa6,4981287,e277e39,d2f19dcb,547d6fc,88baec45) +,S(7fe1f197,ddd0532c,a2010528,9f243bc6,4c2f9e53,65aad5ff,63c0f1d3,188a42cb,813b133f,a1869218,ee361828,6561e75d,a9ec6bac,6ba2ac7c,d3f5678f,fe472af7) +,S(e3568521,89612102,7ad0789c,72dc6d57,7ba412ae,b3d7551a,96aab952,c507f79c,7645c505,8e2ca8ac,ae5fe225,eddf4d45,7d820114,cd5e69a8,4966465a,423e3a30) +,S(c56afd46,8a5644a2,abebcefc,3b6a9da0,c667a183,b822780d,146ecf82,b6ebece4,9e41c655,a80e2844,89fc587c,b686549a,2915ba14,1c691e75,cc635f9,54f1a8d4) +,S(b242eb39,60e6a8f0,73b6042e,1095f0e1,440f9f8f,d1abed56,ad1f26,a1589345,944da76d,f063f0a0,3602decb,696f2a34,378579ad,e8469ca4,bb5041e5,876dfde0) +,S(3a52fd66,6d2e2e2e,888a43f2,fce68703,78f835a6,b5c3bd42,af57b107,323bb827,12e51177,a7b37a46,2755cea0,18f4f29e,96c7d6,d0e434cc,4874da99,a7af91c7) +,S(b77d5615,c8831ad1,147072d2,598a8c6b,4a71c0fe,967a6cf,70877aea,24d28f53,25d5b7cf,a068a665,deadf83d,5f793605,f5cff2c3,36a8d176,d18c634,9ebf3132) +,S(e4420c3b,61e435a8,53784728,8426aa27,f23d224f,4ff7a14d,79898369,c08530dc,422b04b4,857984b9,9bebd74e,1588ad96,9b3c67a9,89b119a7,f7cd2c84,ecca8572) +,S(888bfdbf,c6ab299e,3ba0fadd,a614fb01,236e3c44,98ad07ce,cae08105,630aaaea,86e7253d,58cfe580,628fb94a,a1a8f40b,7ada97c9,d8713453,f06f4773,3770eb3c) +,S(f74d258b,f7d78b30,ddbde398,a1398164,d850f2d,48616cce,8ef4c436,10ef419c,d13d49af,1e6dadfc,94332213,cbb12d32,5d60eb6,d48cec9d,fcaa7ff2,53029204) +,S(a8b33e90,98d60483,a7009786,11b92257,65cea0d4,b7ac0ae0,67914110,5cda6df0,58cc238c,c08d957b,1172598e,96ff4762,1182b6c0,652c9ddc,650f3b51,3521c553) +,S(5af8b154,7477fad9,8e5dbbe3,d4a1a15e,7a4a6cb6,5ae13cb8,9699470a,1a3ef1ff,525ed201,d0c61832,36c8fac1,366e8173,3c0a8c15,b6ef7672,cc84b1a3,7d6f25bf) +,S(155c454,6d4c5c4a,21d14383,3df8662a,fa71e665,ab7ff0bc,8119f29e,3bec21c,20e99f67,2f641185,cdceaefe,8fd7247f,63842282,edeff6d0,378966bf,50411aae) +,S(53918586,ee182d66,e7c22aea,5a663770,c8fd7f0c,6738d473,1010660c,7425a56e,c7fea092,3052ec1d,7e2564a1,e70b8924,cdbf727a,7212052f,abc58d9d,1856152e) +,S(f7964dd9,a0fab716,74804abb,a7740f4d,cc52d7f2,8d5acd4f,67998bba,3bad6414,6a989f64,aba0f60c,e7bdc5c2,aec11de6,d469a122,f1bbfccb,31cac834,89f62c59) +,S(741c8c8a,f514f2de,7880a909,b327c6ee,ffd72ee2,b5b1658e,72059edb,cd663183,f35d276d,e5de1460,dc53532d,48afe736,e40b6b31,fb6fdb49,1224544,a487b2ae) +,S(de8c69bf,6cc2a28a,fc6ea9f1,26ef4f22,606e55f1,312177e9,b2ef8835,8b47945a,8de62853,6900d614,780e2fec,b4ff7066,70d84742,3b1c852c,8b85ca4b,40a48a02) +,S(81e16f39,619bb41c,d8a523b2,d3dd0135,d6a8d5fd,9a8446af,cd058ea3,6f57c537,6786fc73,7cd2ecca,d146de9b,951deec4,375c434d,7dbac32f,2395c265,bbf4b31e) +,S(459e9589,d079b22e,8c5625b8,a725b30a,e70f7f04,8ab21a20,f0123aae,7a6f988d,a56ede93,5b71a292,c4ad26ac,cc3506cc,915de21a,4557512e,e767e8c4,33f38e08) +,S(b079d755,4faba7ff,20818806,a70b4ead,f2e5bb51,d1abb758,2284f385,868ebddd,495ddc2d,552f174b,210f6577,3e434fa9,20b6c0c4,574601dc,fcf5b701,fe74dffe) +,S(75391bbb,5983fb21,41580de1,dd5b10b4,bb30af17,3f05c100,569abd2c,674f288b,57c7a6ba,c9154ab9,eb66032f,2135a52a,b319f534,d1f1c80d,b58a4af7,de958d67) +,S(71436957,f2848f75,fc461069,e4fc691f,5bda94f7,32fcbe7d,5a89e136,41524db4,1287f852,ef4fadd5,65a2813c,51b93c81,95658a5a,5cef224f,e92511db,df3f0007) +,S(b9038b33,fa75d097,dcc74c9,e25970ec,94ad076b,7279f785,3b7c98f1,41543f9c,a28c3169,69295ed0,3fbc1bf4,8e39c8d6,af59cef3,d6f66660,73470ab0,dbcf838e) +,S(b2c63c28,a9fbd900,fbc664e6,36dbe0cb,f259bdb9,d67c34b0,83b8af17,a5f86196,a8f050fc,69c63c4,67308421,89510ca5,b7920723,6f5c12b0,ee7103ee,cd49ebdd) +,S(cdd2a5be,a32b2195,f4a7edfa,dfb7c785,d06bf346,f38e928a,5c92cc7a,2417f39c,ab66e78,ac421c36,3203ee7,22b380ae,2133864c,83829f04,d2daddd6,b7fa621b) +,S(825d0864,b079a737,acef03a8,28838ec5,a27d740c,724f9c39,780cfa61,9f3db80f,bf3ee8b7,749e44a6,7f27e427,fe05eba5,c2154fad,bc2e2b43,a877219b,461071d3) +,S(37b79e3c,bf6bf402,c96930a8,79f4ce3d,d0c36477,f0b0e218,608b890f,bf5e24c7,d97142c7,cec5630b,a090ff4c,9213c2f0,c32a5bb2,f7b0ee29,2045ad03,10f66f1d) +,S(fba64ad0,678ea75d,409105bf,5b452ebf,89560b0e,fbb079d8,aed22c33,552b6135,e665362d,e4e637a8,a85dd844,1a806ad7,5c628f19,7d6dbe3b,df63c0b2,d1f938c) +,S(76787b8e,77ed36f,9d84897d,e84c476f,d3bd490d,184327a8,59ea3f97,ecd9cf72,cf79f14,1a3f38c3,cc126011,d1d78dfc,e3ba228b,33d64158,210cd942,3980a9b3) +,S(26babdd0,ffb3a334,85e6ba1c,5661a551,f16a129e,42f9fe8a,3691a50d,157b31,1b3a4ae2,b1cf1a46,fb666e33,a20370b2,e66a6c71,27edc8ee,e4c4072d,8c2c530d) +,S(15aedbb7,7a2fa1e9,7a6aa864,7729f28,7ca4d3f2,36046008,c1b031d6,9f76307a,3342a142,bf8b2360,6a574643,9c05f36b,f9408878,5354c788,a6dcfd96,ff073649) +,S(98ece0a3,9bb7cd4f,df4d5767,c6ef4cc1,c2b072a0,dfde5fb3,de100f57,466fe467,c4e924a8,218c93e7,eb829d0f,839556c6,1e679d29,6a0a6bba,6f4f463e,ab227e28) +,S(7d867505,fc213eed,4cdffafa,b067bb71,8a48cda2,fb323304,1989b6a8,3ff373a9,5df51ff0,3c212078,197c417e,f4a4014c,96e167f8,8cea0c1b,9199ef75,7c97d47c) +,S(f24f19d7,43578e1f,be3ece8b,7b00d5e2,bf269a48,9d76d17f,410b73a2,95b3001f,644a43ff,55448b66,7b048bbb,b34f4c79,16d2b547,5148020d,53e53627,623631f) +,S(93853304,5c22296e,1e911281,ed4bea22,1fd1061d,2039a27b,923dd3bc,800efd59,22988cf6,cd2d15,f799bbf,e4cc905e,2607da21,e9fad162,8c2fe699,8beb7040) +,S(f090c705,39834f16,253b14ee,8e4d2685,b91ff4ec,9897df0d,af1531c9,46319743,c1171885,1d30271d,a8a08391,f53a02b6,28c59c8c,9af3ad2a,bf158341,280bd522) +,S(e8fc8ec,ab5bf3b7,4a0234ae,b2a8eafc,df9bb08,a90078e6,7fb6cd3e,fea78c6e,b08165,34ce9bb7,46efcd71,362e0a75,a8397c0b,490e75c2,9b007b28,26ddabe5) +,S(46258cd1,87cb43e7,3003cef6,94af37e3,c7426dba,c8033aa0,9b0a0d71,9f126785,846141a7,5f060822,764dd82e,2c369821,75576ebf,7082c6d4,601ad237,55ad4fc4) +,S(e7f38b3b,db3887ef,529d27c3,f433410b,94109bf3,45f9b7a1,e65bee6a,cca3e430,f52440f1,5eaec702,90adec0c,b07e8ac,ab1fafb7,adbc8f81,9fac349,2acd589f) +,S(2d29e833,1472798d,75fd5b75,1f569da,fa9a0167,f73fc62e,da5b03a5,2f537aec,52d3dd1a,b117b9fa,a17c58cf,c0593603,d9e2f55f,5a230001,d18976e9,792d2be6) +,S(a3b2ec9c,abf7a7b7,77fb44c9,c7552dd8,f47609a4,6f943c7c,8ac97d1c,3891ffb6,6ce38c70,f091381f,53093385,22a5ad66,4d528061,5b01b417,d559cbbf,3cfc19de) +,S(afcb3c1e,7582a56c,e6504dd,ab3d1a8e,6cefe762,58543015,a21f65d3,3100f473,6baf1f9d,fbeb8499,8a6afc61,8e193103,67edbd87,57b2c4a3,8e5a76c6,8b171af8) +,S(88b2f212,dc899567,bf62bbea,9466a8c2,6650f74a,490b86ec,cdd35625,d90e2ac8,73fd757b,def6153f,d7f6d4f5,da1723e2,6ecd6c42,d994a08e,7e458a64,d18c30a5) +,S(bfdea9f,4ca32916,651c971d,7da6a2a7,395c5945,5c4940d4,93d991be,1dadef3c,82747044,7ef3f684,4200adea,5b8077cc,4166bc65,1f6d4a17,578b64d8,21bc20d8) +,S(5d45cb81,aa765d69,ca52e386,9491ecf0,e8fdf6a6,3d64e65b,5213647e,e4973ae5,a4a4a32b,51a76d77,773517e7,c103a7dc,fdab36fe,3cafa2bd,b17f82b1,2fd019db) +,S(f3a503ce,e14e9994,aa34fa53,1c43e5db,6d6fe092,45d2f3ae,87d06753,7ae7109d,2b1714c0,a24d50b4,20722daa,d1951b63,568aa5ba,7325785,ac555e55,f3ec49e8) +,S(94c3a76d,6f812ed2,454c225e,ab8e6b8a,4261953,37d1d2d9,b666ade3,88cbeeb5,bb89cee6,aa406746,dd4893b9,5bf1818a,3d1351fa,d66e104c,bc8d63a1,efa953e3) +,S(23dbfe81,5232403,39d5a662,51fda5bd,b9a2d3d1,181dea3c,c0c908c8,f0f4c050,caef3a71,229f10ef,488f8385,c79ed0e4,b5c16899,d40ab679,4e45b84b,4deae6b2) +,S(3907e3d1,20ef8619,c11dc69d,c57935f5,d2dcbeca,1b4bbb88,e4629ec6,acbbf1d2,438f96b7,d74e2b9d,cc17b0a6,c936844,e6aad1bc,58a20055,ba298446,1415e853) +,S(c140b19,3eeb04fd,80aa6a37,3407f591,651c944b,33788b71,e6f05e1,672b7d9c,949bfd15,59e24543,9d5fef6b,70763b63,899450ef,430d2e64,1f7077b9,29e44072) +,S(977cf05b,c96a39c8,1dd2fe26,930f75e4,2563c3b6,b06e28d1,740a547e,f2ea56c,3802e3a,8508164c,36e95e23,46ca468b,7e15878,36a9edc0,e70c0e6b,9aa10d52) +,S(1069c0d6,3995e0d4,cad51e5a,9e4e57f6,795a7bb3,9ee3c376,1e827b20,d8a034e3,e1aa1487,9c0e4c65,581d89c4,7abb5e48,47963aac,788fe804,1d2c194c,5a7fe33b) +,S(ff78c680,c3414181,ff3ab10c,74e2a755,42419af5,3527a45b,ba3825b3,c93e3682,eeb70adb,f05390f3,76b2382e,20b2dbed,86c8c574,df2f256e,1fc4a376,24d3615e) +,S(5ec9eb03,3acd3d6a,9c04c3ff,5838a6a0,2b0cb26b,d5c37d05,9056afd9,86bcddc7,92a287f6,eed0df0,17c0bed1,ed9445c3,e39d92b4,8c3a9c8b,9ae26749,732aff03) +,S(eaa206ba,792dd34b,7ee67e14,d8dbc7e8,bef0a54d,a7dc7ee9,339d8ec8,471b37d1,5577e65e,be719ca0,7fef2530,c40c1617,55e00d21,1d78e5e2,695107c6,8d1ee92e) +,S(26d062f5,6034012a,3d76789d,455cefa2,689ef08e,d3d87f54,af952afd,ceb3ed7,5eff1dac,ef6f5877,99c340c5,f0d1f6dd,dbe6faa2,5ace9109,4e7b5836,d1323424) +,S(800d415a,e50db62a,4f49e449,d11eda8e,1a2413f9,c341bbd1,492f2271,1e602d48,569cad6d,5d19b5d,2299ec5c,fd12d9f3,d5c8cb0e,756036fb,dc5957f5,7c02eb50) +,S(6c01a352,bc16dc19,973aaca5,f1a21676,e1531fbe,f8586bb,9853c627,9c9a1c90,833dd742,c9596a0f,2767226a,b2548139,a39a17d2,d64d6765,4c073b18,f8cc04e7) +,S(3accc922,f1b3ff0c,504e7c4d,4738d1ad,f0b914b8,d08ef8e8,a54e431,37742c26,aa9cd483,27d60b34,304dee26,c52b2979,52a2d118,82e10b17,86a09acb,3cb0ad7) +,S(a0df5c72,828b73f2,a380f75,3f8e6352,f8d978c1,ee6ebedf,2ec70ff1,d0f8ec72,b230adbe,f1e0bd13,1e622689,379e7232,b1327db6,eb0ee306,80d7a89f,a4ac6670) +,S(9d5f0d94,9776ec98,607a8dbb,d54865c6,d4bbc970,d3ff85a4,49d57b97,33b52c73,ff08efba,f4893add,54b8a056,ff60d345,ad7faf15,7d11acf2,2cea0f2,afc1a8) +,S(def5d92d,9ea1822e,dea5b293,58a51ec8,228f54b5,a6738917,fb7f2108,6dd3d84e,b6c740d,b94aebc3,138d3ad0,202bff37,9d5bc20a,d7c0307a,479599ee,8b3129) +,S(fa90b105,cdc8d74e,3f87136c,f4d075f,643fb0f1,ba6eb832,73642e65,84df33de,3e6b28c3,73f58eba,49e9e852,f0f0e244,3a180d92,52624c27,3c079dea,50bba36d) +,S(8212e821,ff2f7b90,c01c8461,3d4d9df9,ce077cb2,9706a349,575b8cd1,a3d0eb52,d59c05db,2fa3e756,fda56e8f,33540639,d24bb5ed,2c8aeb5b,8f8e43ff,703185f0) +,S(ee340cc8,1d1f71d7,4b1a641e,101d15e5,24f155b7,2afb4e49,f9cd8b20,ec61220d,915d833f,25355fd7,f1efa796,4a8e8b04,86f8141e,f5811438,f0083382,ae286f37) +,S(2c535525,dd2e3d83,740b257f,bb7223e2,302b5009,7f8366b5,aa26f65,442afee1,1cd4514e,f945b668,4f38f966,2f3b5402,92d43a79,7f73f947,67272713,b61cf765) +,S(df7763cf,8b57a288,cf4a9083,a2a5f977,404b9e1d,6e814f2b,aae9ad45,fa67d94d,4f7dc336,31fdb48c,612276bd,d388ee9d,bf05295c,1a92709c,b4fc33ac,b1580ce2) +,S(3514c240,d6d0f218,11374b92,8cd6d063,8ff99b8f,4d5e4da1,8fd126a0,ecdcee60,2a0d1f4a,1a1baf80,3c98421c,7777ed1a,ac17abb2,720975ce,e530a5c6,4197fca2) +,S(3de75d9,e58bcb81,94dde551,ab541d54,237a1b58,d935f60a,b54bd3c,6ae40a27,9ada14db,be2db058,c6bad8c4,86f25037,3ec422da,fdd5bddc,455b2b8d,25d97c75) +,S(a728ce0b,1804355b,c5c144f8,1d5eb1c2,90ad3d52,f502c5dd,ae28a08a,6de0420f,4387cca8,f72b51a0,cfb4893f,a85491fd,42cce3b9,ec3344f7,ac93d001,47ddad3d) +,S(ec3c9a8a,5b844c0,947b22e0,2503a815,1d8234ab,aa94032e,16c1d874,5551c39b,7b08bcef,45f0fa93,660845ca,44edfae8,c8ac51ce,e836b043,3825e410,8ebd7fa6) +,S(b0173d56,24945acb,3bab7e6c,617532cf,e619e7cc,e9872e93,26a8ec55,a24761db,78d27b5f,3e9a0761,d0feff12,198dcb11,72a81df3,1320f10d,44591ae3,5f1b381) +,S(d9eb3bf3,cd43dc8b,977c3890,ed3a4b8f,4e04bd11,f95963a7,970d9600,40cd73f6,98196b5c,c42e808a,3f1db718,98c50048,510b9e4,c9b69c41,e7f5b2fd,63b23044) +,S(fbda51af,8a40230a,c7602606,21f92b38,29bbf1b0,1c027f10,7ca54c08,65a84e74,64833994,aa453bd5,4c8729e4,e9010fcb,8fd427ba,3bbe7c71,e812513b,fcd6ccf5) +,S(ae4b9a7,51be1966,f564661,61262faf,472b14c5,f0532cf8,8af872f,ba583f9d,8b2c248b,aa9d7e5a,6f0c6eed,9ad3ab5f,e2bd4078,da4fa281,f4b672e4,9695ee5e) +,S(58040152,6088026,1668c6a2,e462845c,f29764e0,31edf6dd,a40b6e0c,4ccf6ff5,d2f96ae6,4a83c04d,a072f9a4,e39976d8,a2e5f88f,fed070cd,5fb1a701,db329485) +,S(4c28d686,57380f81,639abbd9,fafcf47f,cf477e26,1c46a03b,57ca7326,4c7e029e,694b8a9c,4fa75e14,56a67e8,acfac16,3122a941,150da022,59fb024e,ced8a70) +,S(de205ab3,9e005587,f23b51a7,3d806f81,6984fc77,7179a6b9,465a92c,ff25c9a4,ed84325e,12efc1c2,db42cf1f,eacc12c,48f68e42,9aec9135,5af5c327,c5273d83) +,S(5ea82868,c2cb0a7,4b658dd5,721e6571,b968f589,6d22a5f1,b3ec6b69,594273f4,88d10eb0,8db264f8,13adecce,636f6c58,e1828539,1e538ad,6e2237d2,384a9499) +,S(189cf7c8,64497416,420bd98a,3e3db4e7,c3b0dd46,d7b9bc9c,37f2d036,324998ba,bb3409ce,d46dff28,36601b1c,f7dd606d,7422118d,723f7da2,4d25802,1edaa083) +,S(70a17187,38f50d43,8868026,58100245,3c3c41d7,8ee5e14d,3cf536f9,bc82789f,15c95120,e112537e,41f33870,18f09d1e,101dc445,a9f36296,2b9462d7,bc27c1d6) +,S(578ac0ff,622adb6e,8c20eed,f3011085,8e4271aa,46833865,cff46b9b,fb3a368,f711a1dd,f5f3172d,2b9b2f7d,9d50818a,6b0ceaf5,1d67e15f,1f01ca5b,bbd7f851) +,S(dc9fbc03,476aa747,d64738ba,ddce8a5b,5887f177,fa6cdaea,3e3b05e2,8d840071,c0f6752c,8087dd25,f8d94a19,d294e550,8bd26774,cf4e7ab9,515f0a4e,89eee1b4) +,S(9749acff,a348cd5f,2e84dec0,b3d73151,4bb817dc,4596d78f,e0295215,47b0294d,df667dea,35e54810,daeec20b,e0e7d203,d89856c9,94501167,23de84e0,5781a1c6) +,S(e39fbdcf,2fd2730d,c3359f21,fa815478,ae8e7a98,d6b132e8,e92d343e,32657d85,bafe9881,70a78596,76a6ae3e,364885a2,62441578,8c31c283,20a06b0b,e5b5e01c) +,S(6009014e,27f13712,c00bda4,dc913516,e04b692a,ea32b89,e0fab8bf,91402c09,34910894,f6bd1cd2,cb796f58,8ddba661,eb4006a8,6cec32e5,7086099d,42359f6b) +,S(bf04f247,d02e46d8,2fb9bec4,f76b3eef,b644c92d,43622162,d419488e,87f2f773,d646f4e8,bb3c2e4c,f19ab00,4674e354,302e125b,c1ed684d,32b1cebc,7c2172f6) +,S(9609f7ec,b122b353,85871efd,915c6d99,3e5468ab,c30e9acf,f5b4dfaa,31e5e3c3,106bc52e,b933f0b8,71578ac7,74e2ad89,ebb4d9f9,eeb95592,5d6b50dd,988f9a27) +,S(b690cc3a,e1ebe25,a07440fb,5cbdf56f,f5ae581d,4dec7366,8da2ad62,bab9abe,83cd0023,fd3a3ddb,2cda9603,2b6c1657,35e5f9f6,249a535f,b9666a97,e049dbd1) +,S(72da508c,ed507744,1aa2bc11,4a9098d8,2c947948,395bf38d,6cd00977,91d326d4,165baa93,3433ea2b,e978036,4fec922e,e5d743db,b8117e09,5eafb467,3f668457) +,S(e0fd116e,540a3009,2954322f,5125a72d,1133201b,985d1017,29b1c9b7,a9851c37,c6bc7276,48aa707e,549e899d,630d3155,a516a06b,777997ac,8509045e,e5b88a92) +,S(9d4b8bea,85d4e412,ee0d6389,e883f9db,297f01c,d0695c13,abe2b682,94c10af1,5e2280d7,3f7c0832,d9ae62fd,6a884973,5bb66ebb,e68a38d3,8a95258a,97556181) +,S(eef84395,aa4b6e04,ddc56123,cd5eb31d,69f1255,1c216d25,5057a2d4,388e08ff,45098aa4,34e14364,40d8b26c,73179c48,87797e6d,59963928,b1d6b61,d62d2376) +,S(66fe5c7d,56e38e48,6134371e,76ef427,b4652daf,6e60cde7,39aa1165,c90d7654,2d72926b,b6edc93b,7e40ad43,3cbb6c4d,96d4c384,966ca582,a108a84d,c11a2fba) +,S(5135f9cc,1818caec,cc55a304,aa983c98,82f9e1c2,939f27af,dc2c6df2,c08ea2ed,5a526dd2,7dfe1750,4f8baf4e,115ae1b4,2619b5e1,47986954,27ca3621,e03f22d6) +,S(1a37c089,af7f4a9c,2ffa2bc,c22a3e29,82e3318a,ce1ae29c,3fdf9b62,3e6487ca,d389c033,8522230b,a96b33d2,373672cf,509b0312,35d2ec18,3c955ff0,3d2464a5) +,S(49f7a5ff,15daaf40,913c68df,c9016f95,ed1edb22,22fb1576,e4a11848,47a248a0,f9b55b01,3d637bc9,e9794246,fa6bbef4,d5ebec82,1a5d7f61,1a18c7a7,b9abd8fd) +,S(8247845e,5d9ef839,207f0f1e,26eb0470,3b87f835,ac3af130,253aaf88,1e641ed7,577d790c,1a23984e,7f1b1947,4cb42ad7,b4409c8f,23f391de,3e2440a9,e53c5f1e) +,S(8295984e,cd160241,ace92ef6,10853e8e,57b7823e,25eea4fb,8f118593,d90e0749,635321a6,6798d5f7,39a450e7,67b1c38a,2c5dac96,780c83c1,4c38dbc8,c0ac8353) +,S(d4c32bf6,d8fcf5ff,be0ba34e,770c68b5,fb5db412,b1341537,7b2e9c80,3dd75461,b3c73602,e23845b3,2c44272b,4eda70b9,a1a71e51,66d13353,74153f66,4485f93d) +,S(1a08e32d,4a968e6,a44703af,6b526a32,3babe7ca,6882cd84,9fd3f769,6cc897ff,46ed98bd,b77bed4a,25c2e19b,e2b14a8d,3fdc8209,70344b39,9a6b2a8e,afad4141) +,S(8559be0e,96723f04,4b05965,da8c9777,6b40e1ee,ce49de82,e7cfdc34,354f4af7,63e24b88,854e20d1,2c3f049b,2dd0906a,ba4db6de,aba42dc0,5af03dd4,91333ef6) +,S(e0e0b223,fc7a478a,849c0ee3,f2ef2a6,edd0f08d,e8ccc8c5,5e28bdc6,5e211e8,ca38832c,3aaffac1,206d38e1,25b8847a,6609a5e,d1288d1a,511d6037,9fca60fc) +,S(a237be98,2d8ed250,75801eaa,5917582c,265c3424,5679b4e2,34539ce,68e40a19,f4cd227,976a3780,454d5de4,7026d668,dc1bfc32,9003c87c,f48982a5,5a231318) +,S(28a84882,1eb08d07,f03fe770,5a16f2bc,5edbd0d6,b4367ef2,474f9b60,1205ccf2,9067d3e9,e7d77628,ba0526b1,71d23da9,162551bd,f00fa301,eecb5fc3,f856a17c) +,S(142fe8d5,42bd6b5d,325b8fdc,3820de5b,cc83e2ee,13d59d16,f4c69adc,98c1d5e8,2973f278,32533b9,559d1421,38d7fa60,1b66d106,1bf9c453,9c8310a1,dc75b150) +,S(5b3b611c,5d20649d,19bb00a,11b4b928,8f3d5ffb,700fb6b9,9c97b012,98ad87d2,849059c8,cde0e12,cdfa7621,9ed70bb4,192ead87,5a22c58f,8ebcb58a,f2519182) +,S(248a2249,5d4905a3,f61f74c3,5f35f6f5,2edbdc63,9454cf6b,192c7ce,50beb8af,b5a6f3ff,b707c108,1cd97b24,38867a1d,61eaf73e,9b89b5c3,b1136ac7,bbfd4c83) +,S(8a474a2a,292b50e9,d4d1fa99,a229023e,31ea2093,2d3a5d2,875384d3,dbff075c,7745285c,7d5341b1,e5c39289,16cf8fd2,45b5f045,d30d5dc8,721d6b65,ef804dd9) +,S(3fa01255,7fc042ea,67cbe4ea,86637313,826d10d2,48d5bb22,8ca8d113,5015ffec,10b9d325,f59b4b8e,ecbdca5a,58c48e18,162d436c,a3228b25,e3f75f27,26a937b3) +,S(b77b5c0e,7b94f1a4,dd88f007,1af049b3,6b778d5f,c8a828c0,46ac2195,9fd65648,31246bc0,6722bbea,8c9d5722,26edd609,e2b65d2e,9df6c21a,d54cb157,faaeccc5) +,S(2635f482,67e82b97,6c2ccad7,89bd4bb4,5671846e,d5d1d8e0,8f2c41ff,8535b44a,7edc804e,956091fb,667f9e4d,47b7353d,d2ce39c,b53234d,afb6d5a7,a72b8def) +,S(2306b52d,ae0952c9,c6b6f39b,6d1ea36b,ed0012da,18d77238,4a4e0866,361b474d,438250b8,8d7b8f6b,9a63688b,b2cefcf4,bd767472,bcd21221,582b56cf,325486c0) +,S(caa866b8,dde8284,8f586f9e,ed5a1d1f,aa5604ee,a8c0016e,248d897b,a9f74b4c,2818f140,349f78c4,572834ce,b805a424,e33746a7,d58fb8f2,9954a55f,dc09c341) +,S(818def5a,a0793d50,5f5e9cc4,29c01ed3,fb5e577b,b25277cb,b74c70fe,88bb1641,da9eee80,f7621031,80e2d54d,796367d1,f48ea2b4,93a1445f,bddb3ee2,ee4f276d) +,S(2c62cdfa,568d412f,cd764ed0,1bcac5bb,c36e11c3,5a295bf0,8b12df92,447bf736,e8b8e025,58117062,705ef985,9aba6418,ee73eabf,195325a8,f82c051a,3ec31979) +,S(28ab54d9,9db06e8c,d4a2f7cd,517d049,4e477f1a,b6eb3416,59bce807,e1f04adb,993b5319,a5cb9602,be656276,bf3e7d84,4fb00304,1ecbfb08,72aa29e6,7494541c) +,S(493e7c16,2254a40c,54b4eca4,223a8241,d6c2abf5,f15ebbb6,3ea4814c,512b6061,56387f7b,588d9d4c,fee36b59,7ae8f21e,5fcf817b,f097ec89,7def80ba,3ceed628) +,S(672e11be,e7439165,4fe118dd,a2c5d389,8922a68e,222c9bce,902d2062,b9c51d4f,3555134a,2382a9d,b4bcfbca,45e9d62b,db6bbfa,bfce7c5f,c5102dc3,23dc36e1) +,S(8f8d0f6e,e3b86889,8de86c06,b59f8e5c,27524b2c,2959e701,38b2c3,8eda550a,e7def281,9e27abc5,9940fed6,687bcb3b,f364296c,26bf1fd4,5d417103,49212f34) +,S(da8c5783,4a11f0a5,797cf4c7,9179f30b,118f2802,1205d495,e8213fb5,78b293e3,6ecfe35c,6f663975,86bb1c3,ab5dc518,7c7a0ce1,b6338d28,a2c01df3,89c35f91) +,S(4953e0f5,3b1965ff,3efec2d6,fa99ba0c,fbce09b3,83e20ef4,2657faa1,49681955,c210c78d,9d1635b2,3e468324,7980766,3c28fa97,18d0ca39,fc09b541,975541c6) +,S(5491fdaf,48a0e1e1,be21f7fd,be910bd6,5cd3e0c8,16da38db,6c742042,3775f293,65273688,5d1c5338,a3be9b29,9b51f4f3,9c82de96,318643e,3d34ecd2,fc7ffae7) +,S(b9c4afa8,42363b9,fb583885,8f17d1b6,b0a8529,43c907f0,af3ec9b5,abc168d1,ebd3106b,1b75ebed,5d013aa1,eca7d8d5,e24d511b,6d4178e,514fe156,4b550d9a) +,S(918da36c,444847a1,b5f9826d,eab809d5,d6802e73,3abca386,24237683,92d2bd62,6e6237af,d7cc87e6,15e14113,ab38989e,889d5e6e,6166eeca,abf1ddc,8a53e218) +,S(777d2994,da1f514a,800240e,59b743cc,748eb42f,4572ac93,a2e42e37,1d3392a,6193d7,e9eb3195,2cab96f4,14e1d24f,9d92505a,9d21f864,5e6dd3a3,8a9680c6) +,S(108e6ea0,9a08c5c5,e27b8b3e,af24ef55,3988c650,34ef954c,4d17f232,5723bf3d,1a8b974b,86db6bb4,7c314ebf,f811937a,b8a0dd76,e824dbe2,88fde1bf,fc13b2eb) +,S(36d9dadb,65a54d49,1198a486,8deae1fd,3c2dcef4,4a682839,b5dac54a,456bf185,25e84356,d93b5d86,25eec306,565bef19,1edd9bf8,347dcd8d,785024b,2147bbf7) +,S(3e0ebab1,43ece776,729d8a9e,302726ce,aab89654,23292fe3,ab2e71d3,66531fa7,6e7b2608,556d6236,8948f32b,2fb04b34,8e38eae1,3d9abd5c,691383d9,958d41cd) +,S(923dc76a,f315f31a,a1de9521,a13ee9ab,ab08ab42,157f483,2babdb5c,18fa3728,7a8f17b6,7439857b,3141bfca,6d89e649,7facf685,6331003e,f6bee07c,ed3ae47) +,S(f87fff32,2dfeae3,4ce9cb81,51ce2e17,6bee02a9,37baac6d,e85c4ea0,3d6a6618,74e49037,aa726e0a,357ace25,603cdbfe,7c14a4cc,2e1e4e13,c7176121,585a03e0) +,S(1388065d,dd7f69a0,11dec106,b539f7e9,e00b5aff,7568820,e33f9c1,18881ed,acab1d8f,140661dd,422f72a5,5ab4242c,65d1a932,23fe732c,92b32317,4d13408e) +,S(e5476b1e,a99b6a08,83731542,7a3751b8,3d685b34,acc5201e,59e9b623,ac4b6941,57d5b2f1,c4dd795a,323c794c,aa8fa754,bc86dd67,3cc8577b,b418b2e9,5f3b4e21) +,S(f938ff60,f1e8ebea,4c229d89,4c98418e,90c14981,4ed7909c,3dd47cb0,15cd1f15,d7172212,1a0cc646,a0576e29,372bfbd6,37fe2c5,b6ed6821,4da50318,eebb13e1) +,S(b31bd410,7c4a5108,1795544d,5854f9bd,180b494f,a08878ad,8ad5a3bd,98a30aa3,94261097,6bd58962,5e941aff,a007eab3,d33828f0,e12b31c1,8fb6f5c0,50519e82) +,S(b3ed87ba,83210d01,1a2df141,b9a6c6d3,33abd692,55da3af7,b4447d03,f4c1cb2f,949dd379,29c757e1,a970273c,b6341e66,b90be71b,347e747a,be0914aa,4dd632b3) +,S(60e6c240,1ea790d8,4bb95e78,731bca08,89a57c0e,38b87f46,668ee16d,31221e17,f247bf35,c722098f,2a5c800a,571eaf0,36738704,4050d98c,c03bd146,ca9465c2) +,S(2ae806b0,4cc8d047,e7dd8d37,713cd71,eaf3e16a,f74c3b87,994afaf1,c3750a80,a8d978ac,b29771b5,1a87fafe,605ca0ee,6facf6a2,41aa135a,e38de4eb,b2e2e954) +,S(9af178a4,bbba2d29,e7a0bb15,51f6f3a9,d2384386,3779f439,58a424c2,29bb5c47,c1031fba,a0238857,a487ac85,72fbb3d1,4052a4ba,adcdf259,78101a21,ae79abd3) +,S(9dd6a721,e9cb27af,2e7da097,c9e8a250,fd78a531,330ecb2c,3a116d99,6008f523,e6837b7d,647309c9,4712adb1,4bc65787,fc4e975d,f4e82173,57dc9d3f,e7f36080) +,S(cf5f16be,d7a1a1e5,3b3e3f1d,e44efbb7,fcb717b6,9a28bf0f,e31a1da,a5e91c52,9549ebd5,4d87207b,c63912c9,99920cf4,b0c80a0d,8a69d4b1,4852834a,c4487497) +,S(c6794890,810954d0,782466a3,c52a0149,de577cfb,3a2001af,d45e905e,dfa64722,4a4fdf51,deb64031,bfca5fbd,5c827829,8621b625,1be69187,fcc2460d,f75ca468) +,S(a25fffcb,bee9e0ff,1659c1ea,41406aa,b03b4920,fe1a63e4,442d5241,30599713,176b9e06,5a821189,ac3fc28a,fb72a1ba,40fab791,4de987e2,1236f244,bf41486a) +,S(6079a722,fd5d923b,16acfafc,7248e329,128cab6a,cae9e5ec,dca49774,e0c5bf71,c09972de,99ca5a45,c4f6f1d9,10337efe,23f5292,bd5ecc45,df0f7aeb,d18c4bcc) +,S(188cb43d,9d4078e7,18fffc42,8b16723e,f64b950f,cab7582c,8139dcb9,2b66b403,a038fa37,ec9ea240,9a2879,9556916d,fcc8c2f3,358ab14c,140f7f1a,23af5404) +,S(e310fc40,cb575c68,f5792506,65567ec8,c445ca34,68cfd02c,d781b27e,f819bb30,31328a65,5ba312ee,5e901def,66e7b946,e0c18336,a0f1784d,df66b89e,2abe625e) +,S(dd86485d,1c8245dd,d940bdeb,1f462cc8,f15693df,246c3c8e,52b574bf,77dea4ac,cd6bb7c2,56c9a270,4c690175,ba298a09,8963a8b4,7e743b48,33fc09c6,9966ce2) +,S(1b7ed20c,f81567b8,6f7dc67c,ab69e197,dba77399,9b36097b,de85d02a,7019aef,f814e92a,d1cb4386,550d89b5,9a4bc378,df428d54,d314d531,be6fc35e,f0e3d1bb) +,S(a15587b,2d528338,ed146a03,670b3f1d,9b41cd0c,a0645897,a0f719a7,b5ded284,2aefe34b,5aba1a4e,e30d225c,c4023ee7,12fc1522,ad6b452b,fe6ea727,122e925d) +,S(57bb9f9,c99da691,98cfcf20,9a0940ce,8d19463,9e4d1054,484953e,936a5484,63d0fba8,d90226e8,2c7be5e4,1d77bf0f,700dc57b,d8d3079e,9a6a47c8,331660e4) +,S(224295b3,7fa1b4a0,d7d7f7a1,2113b21,291f84fb,8fa4b746,bab925d5,93bd262c,d60ac40,b1e4b0da,7563eb74,c222660a,46ed388e,c4517ddc,ea2962b9,38195796) +,S(2434eae6,a34ec53e,7c031b2,9e74354e,d6101ca0,f228055e,53b39a6b,5453b0e3,2ff5ed61,d57a04bb,138f3956,33a20e60,8b04f775,6476d0ed,6ce7a382,743ce23d) +,S(448de592,907c1113,bdb04c64,9fb22b05,ef2e6ab6,36d0a03b,700a5871,89885ce9,d7aacffd,6ab35068,debe6dea,25b02930,63af8b10,d4592880,3d0421cc,a879eabc) +,S(8405cf73,5aef7674,7feb92e7,1aa3ba0,defc0a1c,c1da698f,7c2a3718,6393dd76,5795d006,49cd10a0,4a661c78,3f4a8711,89c9ef2f,ba86853f,c7955258,e6c407f2) +,S(698974c1,e5c1487d,fe9349aa,371eb86,9318accd,72c66d5,581211cd,6e08efc9,37c2238c,dc8f4bf5,1f76536c,2ab9af61,bcec872a,bb84ce15,90bc1c0f,ef84509c) +,S(8a37857a,be3cabc6,7197781d,f315f78b,e6548c61,1b846d8d,ce2e5732,643fee05,29882f68,9154cd0,7e455e4d,9e3866d4,5e28e99b,21dde0b7,8b87698b,4cf674ed) +,S(a871b34f,5cdd39fe,13104c96,87a8a717,25ec8cdf,fa60846,793bce03,2397eaef,84f96417,9de103c0,9f7e2dc6,86c9213c,642312de,8de6cc5d,f3ffd7a2,c387cb28) +,S(49bcafb8,9f78a7f5,a8857905,e99e74ac,9ec66ec7,aeab8fb4,fd964ce6,8286f44a,e7db8ccb,5641ab74,a791d2ca,7bd193ea,71124a61,2716d94f,4eae407c,ed9eff6f) +,S(d5c7d92f,2f05c9e5,8f586289,dffe8499,40d9b84b,79feb686,c3f71300,f68b6df6,a68b2a5c,219ea38e,a04b272c,e1cf42bb,6fcb2b2b,fce36043,4f1802af,1d51c08e) +,S(2ac2fe3c,fea4cd7b,9c74a249,cb0c8ed0,6a825cbe,2826c56c,fe4a8db5,3b286696,7d90a659,b008a51e,ca2f6031,c6ca6078,505bb46c,f00a3834,a67e7804,b60f43f) +,S(7c09acbc,62827ecf,4f63a85f,5a0eda7a,5b0069ef,b03b51d9,2f61c5aa,10a39234,e07d2539,c29128c5,685f8641,45fdc318,854b56f2,962b001,5a96c688,69624836) +,S(e886dd56,7e1b42e7,69941ae7,13b2fad3,3bb4ff02,34a27a7f,2c496bbf,6ffbf9f0,d4b2277b,abeef80f,371c097f,df4e5de,5a4666f3,c630b010,81d1172d,c667a877) +,S(edf65cc8,e83983,c5a178f0,ff60bb1b,8ca8a6e5,85344464,73a199d,59c2dc,a2426713,f0c5309f,84a4710a,2de1cdfb,118a4db,1070d23a,92c76244,89ab2d5e) +,S(29c12f04,b78a6ebb,9356dbbe,5b152323,435ad7bb,a3d2d036,a746af6e,d26d17f8,8399275,bf6211aa,78ea211f,39ec451a,b3336d27,fa059935,8b7fcece,216eae4a) +,S(d5db8b8c,280e9914,f0a034ac,3e0f9fcf,169f2046,4a618789,994f8a79,6663c3e2,41163c3a,85a0039,f5e5635a,819941f7,98f27078,aa65ecbb,eb60d577,c263412b) +,S(990a4fa5,630eb00d,958e57ac,8bb4f7fe,10e1055a,c547d165,7000a17c,d9135f8d,f25ee025,491fa289,446a0364,68c71217,eb252414,f8fcf291,2ecb23d7,4bc9653b) +,S(d784ecf0,1c7849dc,ec901c3b,3315cf53,4e3049ec,c68d71b7,41637b57,9e9c0935,5de98d22,cc382aed,d8c82a84,1ec6fd46,30672008,8567dde,6b2d64fb,6b4205ce) +,S(6576cd0,58850cbb,aaf53b67,bdf3c19d,9b4d38e5,19c99338,3204cd35,6ce38193,a329993e,92d1e56e,31c1fbeb,27648fe3,d984960e,30bf3420,658f74c6,5710eaca) +,S(957788e5,f675c0c6,4649a808,1c4549ff,20ccb177,3d26e4d8,bb94844e,bc35efce,7ea4431c,dc4bee37,d95c3948,615e17cf,1d32906,9bc10a8c,515aa0e,521d9b5b) +,S(8af7ca80,5053b537,ec501abd,78c13ff0,da5549f3,b045096b,1452c05,e39e4a2e,25e86225,aac042e4,cfb235e6,da40543,6a436206,e9d67fb8,e1b5836a,2d7e8402) +,S(49bf0393,e16e634e,202ff642,ad79c179,e6eb7456,637b2ba2,623937d0,e215236c,8590613f,401de0d4,1cc0ce1e,e9a13441,41e5f80c,179ac722,d603e697,a431a85d) +,S(c82e2a25,2572863,527b6858,18c9b6dd,df3653ed,a264b5af,dc5ebd19,d4192063,3b86f800,cd87c1bd,3d70af04,47f9e939,c2717ff7,376f91c7,b2675e3e,39a6de8c) +,S(9ce43920,2b9a8f7c,3aefc9c3,fe4d227d,42ec1355,158b2041,a3712dfd,d8eedbf3,dbbb5b05,859aedd3,faef15d5,9a939ff9,53a54bb3,dc2ee6e2,6d5a20c9,ff5b52f6) +,S(e07009e,49de05ca,52d20221,3ecab4b8,baa707ad,96ef24a,168bdb6b,16fe6227,6a35b0bf,e752ba26,81b865b0,ade8d4eb,2583833c,a1523b2e,4178f9ce,6cbc33c9) +,S(eb4dcdb4,7e09af61,e4694814,79612715,d588615f,f4c23fab,65015bd,821da888,63e38168,584602fa,1e06536a,d4c8115c,86305c,41040083,4a55d153,e9661b8f) +,S(be5f8681,2bf20113,1d257015,dd29dacf,a2c65907,26078f7b,f864f339,10e49db6,d0f420e4,56174aff,5995a92d,a73fa511,43c4f1b8,c40e9f30,8f04011d,956d9da7) +,S(3b32dc39,10e75f9d,98fa1318,edd7e8ef,db214a5c,b31d5ed7,4a61f881,355b99a8,1a12de86,19c2e9e5,9fddf756,e752e54b,6e4e0aac,572fbc42,18baf1a2,a3a18bc5) +,S(95ac5dce,5c06e885,65d2922e,a3f386b7,dde10735,169729d0,a3c3e7a4,86e04db1,1a22cd87,ab1b1821,e3c49e85,616b7b49,680edb77,251969fd,e77b5b27,3ef39838) +,S(6e4ed0fb,a4b0f13e,335d1b74,a5ed295e,7dad591e,a8dc5cc,d301836d,7ce708eb,9056166a,c61c4e09,ed988e6e,59cd9ab0,16a2ef99,e99c1a54,ac37f152,a34b931) +,S(8b7c3394,208e0ee1,374925e1,7827d849,ea8d9a79,91d2d859,898eba2c,23a42e10,b6ab9237,96720bcc,910e6440,75ef3ff,2c8bebf6,2f21ad0d,3abeb2,7043d193) +,S(fda7b47,f6690d73,884965b9,8b6f5dca,dd48ab4d,8f96edcc,8e20584b,b0f871c6,9b402435,a272cc6d,28b487e8,b54b473c,30929222,55e47560,e18b8e6b,ca926c5d) +,S(f15da0f5,395a5a1a,ef8beb53,4c0e9aa3,6e63018b,cc91a55d,ad6106a3,3dbcb217,28cf69ea,bb3b0151,917571ac,48609723,80be252f,bcf98f6d,db6ebf76,578a8f1c) +,S(c6e266dd,2c7817e0,c92378e6,38709a97,d9a208b8,7fa832f4,abfd881b,bcaf9253,2af100c1,fa9bb3a3,c8e95e3,5d0bef58,5ffa7adc,93232082,84291ee7,cb769626) +,S(4bf8aa02,fdd201e,488c21a8,33925687,7f5a727a,4fdab13f,d133d08,b6e28753,58812658,ad9c4d59,a15c6bd7,9e6c622,d8fe5f05,95cbdd88,f39be9d3,cd5fc8b8) +,S(aa985f28,6dd485a,5589fc39,da77fb95,5cda673,db61e48b,972fc129,7cd0a6d3,abb0f897,2f1163b3,29a5a92d,a1ff02e0,7c277710,10e24a04,e1e5f60d,1e4b75b2) +,S(8174d101,ec13a1cf,4eb9f88d,88c14121,6c2fa04b,ced197c,8e1732ec,61c41c9d,c6765dc2,31b02e7f,eaf7a662,5a639b00,c6e5d94b,1a791bbb,46f6a758,8fd79aa7) +,S(f9f64ea9,d6039297,b728fe09,85a9a3a2,92573aac,fdbe6cbb,8702f04f,6df3d876,4146c7c1,406067d0,160950f2,1172e879,188069fb,d87eef9b,1a67d2c9,9a4ca01a) +,S(3e643a70,5a6885eb,3d34454a,2a5de925,f8067cbc,1ca92951,d8865ecc,a8f1b3b4,2deca704,5525534e,de9d54d1,d777a996,8b5e5882,7162ef11,b0fe08b7,e2fb0355) +,S(444df411,fcc3ac07,7e95d200,d6f76d03,caae45d2,b87a882e,4c0966f3,376c63c5,b4566598,643d964a,a7cd1a4d,f2decf3d,ec520c93,ac6e32bc,64350aa5,5416cc23) +,S(12a2f61f,58be35fe,314a7beb,1a6810a4,19cdaa6a,8424d465,bbb7a87a,646946a0,9a7bdf44,94c2cc8f,f1953946,1a69fbca,48410b31,95d79069,8dfd535d,290ba47d) +,S(bdd72692,462573c7,3d48af94,b687bd22,511b2b7a,93f48793,3d52b2b7,e264cb9f,56e6c4e,b794fab0,bd5ac992,3f7469aa,858e6df7,dc40f4ed,955c0df7,a2123874) +,S(e1bd5558,77c3f55d,12b4f156,ea4da9ef,c974bd29,d7d043d6,ec7fe56,a4066bdd,8dcd9b99,fbe7436a,2382bea5,6c5a32f7,789cbf1b,1c44433f,f5a95075,c3233170) +,S(a7c68de4,781c8294,bea46609,f4a1f550,fc064eb8,b071985d,804351d2,60132ad9,a08278b6,3d9efeb5,1062b240,d45989ba,6f6bbf9b,ebfa0766,8428862b,adb42c32) +,S(4f3a8769,b4c6e369,cbdeb90f,5137d07a,5fa0d66,3d8ca79a,56b3c70d,2a9aa855,f6c051c,5f701e15,348ed9f2,c4707584,b9d6db2c,b62bf93e,35b6486e,ea6ea169) +,S(deaabc1c,8089ebfd,841cac66,d8a6bb58,36fd047f,cb435a8d,74463dde,f444f232,fb7cc4ba,49c26e7a,a826e654,7c8a6d64,ccd14a49,62a6d4f9,f50c293,c228e8a1) +,S(c411af61,547b1b38,12551e1f,4ef2b32e,fd7f33ab,7cfce378,8b5b8f93,319c0695,d2bee7d7,3d50f82a,e9266d21,2fcfbb76,294ace4e,f6222ab4,797bbf88,558cb66b) +,S(d0ff6a94,485bdda8,d0c28494,5b9dddc4,4a35f101,d0a89637,8210bdea,909ec5e7,ab3f60fd,2923a8f2,d02b7e83,d8f953c4,cb1910ff,83a92a65,e2121f22,364f620f) +,S(a0d05cc,9555ed92,2851baea,35ad6cb1,6f2744,b3fe424,98235aa7,1f08c0f1,843b1105,237158a7,bd7e67c,a20b2705,50afe2ad,318077dc,4714c7c9,d6339948) +,S(bea08445,eb295fba,5c83ef6,7d909978,7d599642,893fb9d0,568e5920,1e3f5d32,2a81a7ff,b3f7f453,d78bb2bb,41d12ed1,e26594d6,bd4f5cc7,908f322a,6cce10e3) +,S(e8ebcc4c,431be689,9eb5aea6,f6ab9700,551c3098,c5acece3,e822c7de,e6f0d5f0,ef99a461,760ae4f5,8fbd511f,59a2ae79,6d65db64,eaa0d61e,97d0a3b,31fa902e) +,S(4948606c,dd73dc44,ecf1db77,c796d8b6,806bab5,85877cd1,d9630bce,966e8fd2,3c67333f,786c8c67,841630aa,639446a8,cb8c13ed,f3db9123,bc64b925,beb95f80) +,S(4f259b32,40d9efba,4e3e40cc,a66cd494,fb5a19a6,5b5c8a16,5c18792e,9ea778c2,fdd88087,78c26999,c4a00605,49f4ea2c,b1590f7f,4748cefb,1b68eaae,4d17446d) +,S(f303a493,e14d7f52,f276e2b4,3e118eeb,1e7e918d,e7aa7f33,7e350fa4,7adfcc29,c49fa46d,befe53f,5f5bc49d,aa6ad265,453f7977,c5fe4163,cfa1bd4b,69141b57) +,S(e00c4b17,f4c0800e,c1b11859,c40a560d,58b9fdfc,29df5a41,ea4b2f53,c1df595d,62441a66,c3ec4d29,d18d0d95,7b4ccd18,a72a1003,d34832fb,8c81fb75,9763b99d) +,S(484b8486,1af6af52,a47603bd,2b754be7,ca16bef2,21581171,4cfb2301,db72ce70,36f84ff5,a0ac79a3,fe696865,2a0a6759,cf72e5c5,8c76359,d477e72c,4d32fbc7) +,S(88be58ea,d8b51f44,a1be6a8a,7cbc149b,ca07fece,11a7adab,210467b8,4cd93f14,94c10caf,7037fbc1,71cd6cd6,a0697b19,8ebbebf4,9f00c67d,4d46ebca,92687fdc) +,S(abf6ceaf,9fddd7ef,44a75e11,b10119b7,7372a3d4,7c163b77,384de944,47da781b,5cadb30c,6320c67a,e9dfe2f3,b9bb4ef5,41718392,81c4a59a,7960eccc,6795d290) +,S(e8c26522,9ef665b2,67fcf10a,17c6c3cd,4e221e0d,95663deb,74f8384e,b89d173a,9a69fbad,f9b050ef,d231965b,30d91646,bec7ba26,9fcd0934,35ae11f,ca2aeeb3) +,S(66652bd8,bf72ecb9,5e670a24,e8683155,e031f3ea,91fff58d,f60fa4ff,d9c6c23e,4844ec08,3f182b73,22c2fbb6,6f6630a6,5fa6901,52dcfb3b,4b65a3a9,30be994e) +,S(207880c2,d8421040,dc8202c4,45bf6d58,75cac841,532aaf0b,adf252dd,4c2c0964,2b1819d7,3eb24de1,ae4ef316,7c92a7b1,a562d93,80fdc54,e916d1f0,c1860cfd) +,S(46b9bde4,53d0692e,ec933485,ed0dff68,7e8f262c,7d9270cc,763fd959,2013f581,58af9be6,3ae599c0,f499b0d6,3085b7d5,394cc786,9f2fe225,6ecabd2c,a14f9bf7) +,S(5d9b2574,dbebe5d0,9756e2f,29af3aa,a2fa2555,d629a78b,82b1d679,75ea3e11,ed9f40ac,aa6ac68f,cee3dd50,7629758f,f3a64190,1658f0f0,2b87b645,ee59263) +,S(ecb5ad82,8b986425,9a76a649,1774338b,dc598fd7,77cfec52,d086c172,6e590e4f,2b78936,73c6d87e,a954b5bf,52f8212f,65d33ea7,ccc4b4e3,1d98df2,c9887886) +,S(b32b64c1,5e711b8a,1d174725,de55c,ddd62e99,fc90e96e,8f3ca532,3924ea67,af5d61d3,6dceadf2,34a7a94d,e7e4be1a,4d81b84d,e0fe16a5,403b0c24,a6ac2083) +,S(5137f71b,71582334,a6d57aa1,5cf6ab3c,8b7f6842,a800b4ab,1c308fc5,820cd364,f7ea5fec,c9b17dab,c6a248d,49757711,e4a3b38,95658381,efa652a4,4df1eab4) +,S(b9bb0e1a,390b5889,3e113a89,801c3f5c,25f94e65,63161539,e7c56297,ce9ea866,d8db3c90,3c3d35fb,ae4e14ec,e81e4e31,247f60a8,2539880e,6b66951f,8324a11) +,S(3f091967,6da40ec2,4691c21,1c42f47b,88cc1192,ec1827d3,17beb468,924fe9af,f1b44826,3e882c1f,18ae6a81,238d0724,ba4c04bd,d3fcd395,8775df5c,16bb8de9) +,S(b5fa25f1,dad4600e,8d55e7af,c70a1b2c,3767da47,d625ced8,d55ac88,d893b4fe,7575f661,f2ba296c,7ed3a190,8a49d099,83e49503,ba17a70e,1d6939b2,8ad22347) +,S(a0371ce2,dc6a025b,78db797e,90373069,e4ca06ea,6b1cc018,3d4c6f7d,680d17b0,92b5a8a8,9a5005ce,e851c521,4599b774,24f0ff74,5c4af6bc,6937c432,e859919d) +,S(5aae6e90,a49107,78863967,d7d42020,cd0a9828,da25ac8c,7b19942a,1ee2f210,ed9cc20,82a54f3f,fd7218f7,b79ec399,7e82fdc4,cd783957,5760e4f7,b7ee8fd7) +,S(54e7daec,f4a9b6f4,b100f964,850deb65,64efddb2,e6ce7b05,3fed2a28,1a0841a0,d9ada32a,54773a81,d5a857ad,8b34d96,70d46785,70943dae,cc83deca,97c9c63d) +,S(e9b29910,d8bcef46,b48d8be0,c7649b84,383ed752,391ecd7a,bdb454c8,8fbf44e8,eb268094,f669e91f,a5173965,50e4c40b,d7a26792,9a8df3de,b84c703c,261d6b69) +,S(43f95222,f254a513,1977c589,577d1d9d,3f537a1c,9fe14ef6,384e1779,da546a97,d7d3c653,43345c47,f245b305,b662a2df,eef80b3,97b3f5e1,4b0eceb5,71cb18cc) +,S(9fb45fd5,3999fb92,830bc090,216ae485,6723385c,7224b1d,cc91294b,a6c3b103,5b47081b,dbfd82d3,90d7bf7f,39a494bb,6731b506,b827213a,277f7ac9,febdf451) +,S(dd92282b,835529cd,3295919b,2eb466f5,9ca840e,20ad87f2,3cbc824b,b71dcce9,ec45f6e7,bc59d668,b1ef4a29,d1e23bcd,f3796268,3b58fb7a,d58a9e1c,5f726371) +,S(7482f012,9fbdd7,bf99def4,f3de23c5,fe29036f,c1ad5c38,686c05da,dc16348d,a43c4a0d,5497f6f0,bf2b2a20,b65bad11,73fc0dba,c24e65f8,db1663a6,b840abd1) +,S(fa4cfd95,97fd6278,1dd2f587,a5b03195,537fca30,f7a9a377,a69a6869,70ebd9a5,4568b6c9,9ddbf778,bd31d269,be18a8fd,e2a35031,a30505c,1b8ebe1d,c7ae823a) +,S(51e0d3da,e7763e8e,81905e1b,4f1ffebe,2f1078d3,27944c53,d9b7d110,3fa60b9e,118da0c4,ab572fac,cf9f20b9,2108ed0,1da673a5,2395f3f7,bfa2ff2a,36da6740) +,S(7d8e567c,c0552335,38c3b857,289e96f4,502fc674,f40ebf86,c482a668,dbc9530,76c3fc46,c6446a,4b9fe552,ba8b2614,7484581c,585c8ad7,600c2ea6,8eb37571) +,S(d924c6d3,b400196f,dd1f216f,dfa18c79,1c316d67,9ef4c0ed,8d12b94a,cd1dfb1f,ec33cee,881c04b8,b11eb3f2,88dd9b92,90b9d119,26c692e5,9d82aa80,4febcea8) +,S(8dcb330b,6f629c8,d18d28b9,7a99d82b,3965cb1a,bf953b8f,33074457,5e93c0db,3d8a2d19,8323902d,1b129b57,313f81a8,b58b7340,f6f7c97a,b6d74f37,a46857a3) +,S(dd1c4a3b,94b06378,8cf86797,ddaeb671,57910f1d,35a32e80,d3f749f6,bea5d2b5,efbec0c7,5a69583d,643e5be9,ab78cb78,3d2afebc,73d7c64c,869bede,b3230777) +,S(2b03de34,1dfad7f7,395f6ec4,84d292c1,ec0275f2,bc762dab,7658a885,37f5e772,3235e8fb,3818582c,55bd48bb,49f78e5e,803d7d1,ae49bbdf,97166a76,c3c0d0e3) +,S(3a795b0f,ba145bc9,7e7a80ef,a6b77132,677f06bd,4c3e7f39,47978c83,1428dde2,f4125b9d,df038a26,37cbc9e1,eed40aec,81af644e,a3f1352b,526df579,44914691) +,S(ecf813b,a133d6cb,9c46c081,b0a851db,121f5c21,788d1e59,ef8c0588,684fcbbf,69e0daf2,a7b7b473,7f2becd0,789529c2,597e3915,ebe12093,ecd7738,13e53560) +,S(637c4982,c14163e4,1037191d,d4e09d3f,74383245,5368cc33,57669186,d6217d5a,da5a2ab8,fd83d2e3,25baaa5c,a378318,f6fb3747,5ac64b77,a74da573,deecb410) +,S(19fe73a2,d8875b57,dcff5fac,20530da0,54255658,1251f7c6,b198b3e3,71b90e87,3b03ac18,2ccc2518,c367a77a,1fe5e8b9,a3264681,28fc1ad3,5a39f7a0,d8151ca0) +,S(16ea62a,d4cdc00,9d151b3,b6680b0,c68b4cbd,f144c234,71d55b7f,3bb7ebb2,8cac4a1c,53672e59,338612a8,995980c1,35f02060,2e3b9f6a,8fffce9d,e53fa629) +,S(6b9d68b5,454c6d21,678e5413,279f9a28,e1eed485,fbf512e8,49f35394,22a40970,b63f5044,98ebe37d,af9e6969,da888eb7,907f8565,4b05d472,fa4b1b27,ae365482) +,S(1fa20c8c,8f0812c,2e7dc948,afb7ec92,32c3c27d,23165d05,868dd127,b5ed3e6,c5257f4d,82133642,7df68606,2c229fea,6cd16857,280a60cf,ed84deb6,29838076) +,S(73a83c92,7daeb4de,1cf1df6b,31d8f536,af15bb38,be506263,e8e8a6a1,bf6acc86,a08acbe4,cd6c30b,82b4e24d,e8c9b891,26a21dab,e4df40ab,2fb7ad6a,82eb8adc) +,S(3a995664,924e2dee,ca278cf9,3ce265e2,85ba90ce,fd2a55a4,8e1761ee,7588bdbe,f3221adc,99eb33d3,52465d93,91caf18e,d011a1bd,3b7cf39,dd48d45c,44cbbb0e) +,S(7c65ee19,b032f5cc,1d45cd9b,9c160e86,5ca516fa,b4f88596,5e07f269,3d429c26,47c7faf9,e3df277,d31076ae,4be2224d,8cc54a5e,3743e287,ff9572a4,23704c5) +,S(c010694c,6750dbbd,bd953118,dccb8d03,2f05e6d9,65db8fb0,3dc00b22,e4d397dc,3b4914c6,dd6c5441,59dfde10,a196f132,5a5e6101,52d41be2,39583b80,6c8e730c) +,S(e255848e,d28d8b6d,6f95a12b,92136131,a33dcb2c,a723fae7,5e317cf6,62519d57,62f7d5aa,1757dad7,98207dcd,18183b24,377c9ac0,1e106fe4,d36d9264,3fcfb7b6) +,S(f31418e5,73232992,3a878dfb,f1de30d1,a9669da7,76effc45,bd1a56d0,2c236ed9,e62ab884,dce0d946,55e34c8a,630b5aef,16a1eff6,1f889552,af7234b8,ae56b84c) +,S(9adb945,b876313b,ac9c290d,47c1e6aa,1f3f3c9a,e8c67770,61512c2b,bd703181,b21fc142,b4632616,4820b82b,edddf2b2,51531d0e,df0f0f86,50f74d1e,9f0908fd) +,S(c4682b2b,9d4a63a1,855132e9,b35b390b,ca04b846,b83bf36,1726c3c5,808da322,f25a906a,7100ba32,1b659762,23e36f04,14e9075a,835ce5a2,6eeb5d03,d35f6972) +,S(ebb0fd6d,60f49c47,8167c405,597c765e,559159f3,ae04003d,a99a1066,ea80d63a,eb37d160,667ac862,1da2ffcf,28b431c8,c4202f67,706f4350,afdc868e,6aa0b0f7) +,S(78f12d20,70d8bcb4,267cbb,bff637f1,65ffb098,95f5734e,3551bcbc,9a5597a,42976ab3,36621756,1bb574d2,c87d99cb,7419a3e3,39973740,7de17090,2bbb78f8) +,S(3dffc4a,f6214b63,9839fbc2,b949621a,35ae41bb,e7679eee,5798afbe,85919f69,58174b6b,1b4021ae,22dd15a4,29d97502,a13480fe,902860e9,36fead8,57f2c456) +,S(410c9393,a4ed42ca,2115198f,4db76eb8,bd16bf0d,324528bf,55d5d745,b55a15cc,404ff4b1,df71b89b,c14c2cf9,bca25176,83c2981a,731fc3d7,59faa0a,5ed58306) +,S(6b4d5156,87d6b079,3df36632,6fe6977c,b93e6569,66797196,6c16c495,be4e3649,647a4894,bbac207f,5d2a0315,2db1760c,1a25560a,95511c81,5d6c11a5,e969f4e3) +,S(58ffad7a,e87d5986,f0bccfd8,5005d9c1,6f0d8724,6be4dfd9,4a771c5b,a5f34247,ad8b7ad8,f9ab15fa,f50d6f93,ec8629c3,b33fba6b,ee36ace5,e505cf00,f0069817) +,S(e6d3e41d,1835fade,af27738,23e883b4,adb95669,72892c72,b310eacf,a6a757fd,a136c88c,b580ece7,cef03e42,5dbdb8ef,d6395cab,b427ae61,45a0ef0,21359c15) +,S(fc47c62b,43aaa030,ac104479,21bc1026,3b561b42,a2d32a5,573ae947,d953b35,5d318d1d,65fc7806,732b5810,40a1f511,62723626,b393b29,50230600,246224f0) +,S(ceae2867,cbcb37bb,8e78da9,3553866,d0a1b8a2,933cb1ca,36bacb7c,6fdb251b,48bf2c7e,c163aa95,79417b37,343727b7,956cc629,3a188c16,d4c2d1dd,abb3dfd) +,S(abb12378,c84735b5,c23408d8,2516d887,9195fb74,c8972d78,daa8243e,1befeab0,5a0bf64b,da5a465,d9d0be91,3c8a56d9,ce901c36,67041a02,abb591b3,3f66698e) +,S(d7781e39,8330c7c9,2185302b,e116316,1a576ce9,43a4824f,274ea700,3159eeaf,6341a432,4e07c5c7,3ee7398d,d1be3d7d,261aed99,96f6f310,fbb464af,d06651a) +,S(a6918dcd,46ec2045,72d71646,d2a21df1,6f3ad133,dfd41a6d,be5b7684,7e4c760c,c0e51aba,378d498d,9a70e4b5,3521397c,1d6c7cfb,2f6634e5,1f056e7d,932fa9c) +,S(413a4ee4,fbb5de60,392b340a,65fd9706,7785e2e0,248d2770,6ef044ca,83d1a204,a0362506,c18a8f34,3bebc668,d1b08fd1,6595a674,51db27c3,43af172f,8a3dd197) +,S(e1a7bc24,de8b0920,f6c4aa08,2fbd1126,87fd8766,237311a8,9681581c,5e04001c,3e3ba9fd,d0a2873d,149aeea2,61a55c65,3a3d90b1,efa8e49b,29bab100,1a6bed16) +,S(ff9292a0,a147ccc4,b5ae077f,8a337e05,ab1dde9b,1795942d,8a9a0fc3,dd333a75,e50f027c,5f7a3463,7654b412,25ad5dfe,b555ea2b,8305c7a4,3b6f5b78,7a23a166) +,S(eae56623,437c9dd3,9dc7a36b,45c2d3,afe849c6,1980140d,900039d4,4ccb9c0c,f1b8c9e9,92847436,dcab5a9b,22fe7e78,55e62e40,372d77be,39f68974,dd32e043) +,S(7dd20cbe,3467a3df,e1eda0f3,48c39e5,7f9c6004,bcc89227,3d002cb5,54bd5282,ec4d2f23,f035d2d5,4cf4c3f8,31772a46,ee922582,8ddfd4c6,4eb6a689,7c1485d0) +,S(359811cc,5acf1291,547b8870,33bda3c3,e4e245eb,db0dbfc7,3a02da3f,12a877eb,ed2f5087,8b97a3de,6ff916f,511c3a27,7702d1be,2b683a59,bb6acd98,e908a792) +,S(fb33e89c,f2bcca4e,4ead57ea,1a24d1b,5a6c76ca,bc605a2,c031102e,49a71c24,c75e02f5,ca602705,7ab5b958,42a9272f,d7fca940,c26e980e,192861d,2f1c9f45) +,S(a1cd33e,5eed74a0,1534f836,b05a5129,b7b2970e,f293b606,9d1ebb56,e5f687aa,f90d1ab9,ccfc345,3b2b60cc,1e4380e9,bdefc37a,896a1abc,c9978d08,1ec4a6b0) +,S(461696b9,3643b7a,bfb383cf,ced8ac92,5d9f169e,1db30999,b8553504,c4213614,674f5c77,5f300fa0,c8f40a85,9aebffd3,ee91c4ce,695998d6,de0d59a,3033bc72) +,S(6c6aaa22,1b589f6b,ccc885ae,93f7e8aa,1fd5cdf2,27471727,f390d5bd,e14ab025,a77c5e03,40e1b90d,1ad64483,fb50fa76,aeb84417,88ca415c,9f8d2cbb,aa077538) +,S(c918d391,927f3310,d032c7ee,6e729e6d,792eff1a,72acc268,3874fcd7,4e61c38b,58fd746c,346048f8,eda1bed0,e5b6cb58,fce24a72,6e27f965,74243c80,780dfb5b) +,S(48679e16,1ca0a3f5,e4ac2654,213c494d,9240c3f0,33fbe2c2,142ec589,6dea5918,556f93fe,300cafe3,e93a2966,767840e3,b2a19fe7,9cf204a9,a30d1f1e,3e1d1a41) +,S(c68c05a9,e46b6440,a72d6eed,eaac085a,5e945659,ac46a584,69968a30,c6e7b858,b8b4b5dc,35d4ff80,be3d64a1,d036a117,c768746a,4d2bf2b6,1b126460,15de450d) +,S(d133ef10,6358489f,8f976dc4,b6c54699,21e3dfe3,6f326dc9,f0538757,9d444e6a,2c66abc4,db690d2c,272b0f57,afd66a6e,327ec3eb,e32b45be,cbf3c502,baf968cb) +,S(53544f59,8d759dea,b10766dc,48a7e2da,61ca0a60,a201d193,92dad05b,3df976ae,449a205e,61cb7aef,204e3f0,3a199ad7,993d711,537e17e8,79a42bfe,2869cd47) +,S(3108a074,fda5133,39e26385,14b6b7c0,9254c65d,ee374a62,2fe34acb,83b8b331,42edc90d,54263fea,8b1a473d,ac2f2244,d6fc05d1,f59e115b,5d930132,268b6243) +,S(1666c40d,52c1c04,d9e95099,aeb55861,2ee58ac0,6b22f962,154cd8ca,7cb4b23c,5065bb41,ae046638,aab55923,e0752954,abafc247,d201e84f,b6c444b1,93a82fb9) +,S(c96d07eb,d3eee6a8,f001290d,f76b2d82,ed80fa90,bbd5ead5,3a572457,ee47722e,d3d69c04,447fb7e9,a3416af1,798b749d,13ba06e4,78a432c8,d00dc2cc,7e20baf3) +,S(a9ffc39,b11b5b05,78769a9e,8ce7542c,647fa7bd,7b2c3479,fce84d91,1d81b49d,bec21248,82e928f7,e98894dc,25840712,80a64449,38e53747,375d2122,68bcbee7) +,S(52ca128c,cd4c9380,8e55d3f5,29320fd3,e825787f,1a600f27,37fc5fbb,f7af0632,846e8a80,95a98cb7,b4ebab01,4d9dbfb9,37ffa493,83676ec3,70f42cde,3135f7c4) +,S(ff92aac1,77fd9927,7b8abc41,e49f7c94,698525,2329b9ae,8e0fa34e,a9407c20,af0d8cdd,5aaf5273,ebbbf2a9,b7230373,dafd9a93,42a47331,a3379f45,8ffdcfb5) +,S(a692a73e,d3c10a3c,38163c97,314d02fa,5fb653b1,d729ff09,a541d01b,27991e0c,722f55a,3e5bd3e8,d863d00,6b82415a,aa05c949,9a537809,cff9be69,e468b905) +,S(d9e59c3f,7a629a93,e32fc4cd,2c98d480,6b813ba6,315ce4e2,e2fc7fed,4120aefd,24ce2594,23073119,4f5bf658,909a47fd,3234be39,13aa8d30,eb08e14f,af0214bb) +,S(74e5270f,7771b109,64991ef7,9abcf05b,4dde8d5a,605ab587,14b8e534,4a0f6ff,2ad861a3,a4a83f09,687a285f,1356b1e3,71ced066,69154887,14bb0461,b3b1670f) +,S(b9169230,1c43f7e7,61a85615,7957c3a2,744668a4,8587ff58,7a201f59,31d4420c,bd36065b,c1268280,4cd818e0,c6515a5b,659ea423,f5b23e5b,ebe1f74e,5819536f) +,S(37faf253,864568da,972d7211,505b7fb2,cd01fdc9,5953bcd8,79239d90,364d51ee,b69ae2ce,749db3e7,e6aea736,a3bc961,d8c12523,6f7be823,65749ead,3bc15f85) +,S(e194114c,4a1c138b,34882477,f0dcd065,1c379f98,c198614b,43b087bb,a20cf8d2,7a3afb4b,b90ae22e,3b182cf0,6514a998,889f2ad3,d71d4d67,89e3758a,e898a93b) +,S(2ce2db01,d3fb451,7388e4b3,c81588d1,1c8b13ef,917333c,ca054379,fa17ddaa,9232da9d,af0e76a9,85e1529a,ed1a5568,74285cb3,8010c922,e2c30d77,367bbbc0) +,S(c292ec48,4bdb7045,3dce2e82,1fea7688,bd66c6e,59635f49,98618f9f,3d6f051f,210a74f0,6b81e69c,4d0af49b,fd153247,12b77736,126f4887,2b119ec8,97b57d6d) +,S(15bcc9c0,97618aef,697b423c,cd83ad3e,933db83,d77b42ad,3e132036,a5acfeee,e9fc7ef1,1bb996fd,bfb3c490,14912ca1,a1bb98a9,e9611c,1a83a806,b88a7a33) +,S(46119caf,50f13bd7,97be45fe,55f2d298,848639c6,99d5b113,fd24cb24,6e1e7785,6a203f91,f4c56eb9,7762cf8f,9ef932b4,ba301501,5aeb1215,b1327a93,842ea3b) +,S(f3a17794,3e4df182,a9549a3d,2da1f9fd,cf141094,5e6b3a64,9d9df885,b6f9ecf4,b34eb7cc,5e82ad39,fc2b6619,859f8328,444a1dff,c82ee115,c80cec10,6ecf7e8f) +,S(cef90a74,84a7f468,db9cbd45,f5b9a0c5,fa98bdfa,50297d67,536075c6,b7913fe4,d090eead,2a43fbc2,86702946,52507875,fb79a555,e5c55737,30fa40a2,6a301815) +,S(21d8a214,987aa938,ec4b88b2,4bfa5661,26c528b6,b9060b06,833c6ed2,a35702ce,c354340d,5b65a23b,c628167c,8a2830,f736dfe9,a501fc8e,94b66f26,d84579e4) +,S(6b18ff27,9049be4a,62a04f6c,f82dbd24,e19196fa,46e0761d,5d139518,3a1ca53e,ef806f0c,52c01367,8f81e9b2,6698fa32,6343f0d7,2522f8d8,6cacfdb2,c5ffa3b7) +,S(7d8ef4f2,452cc04,d5332afb,ea3e673c,bab07c36,c081a0ee,850ae31d,cb466e6f,32461667,55a2ceef,273367d0,df10f6c9,d224da47,f19117bc,137a6244,2cfa0c0d) +,S(c7de1821,55d15649,f5bb6327,65ac74a2,3413560,b1d31afd,6994b488,20d12cab,d9965856,c5fb2c0f,c93b8659,5c3240d8,7fbe0136,11d7e844,48252ce7,96eaa23a) +,S(4cecb33a,915e2c3b,189eb6ee,45fa4eb3,eddeff09,729945c6,f893bd,4381b294,cf17f112,b5e61cb8,44625035,7b700cd7,3534d6e1,3310b6ff,d1bbbd8e,1ea3aeb1) +,S(826cf464,bfce606b,b4c3ab5d,4cf00fe4,1c9bc72b,285c8c10,204aa658,66255749,6ba3b431,527d285b,5156fabf,b150aa2f,6d7ca564,b18011cb,b878e235,7b6849c4) +,S(c812dac6,f497d245,5192ba92,2d6fc10d,de51d608,d82e828e,b2187e7,648f8f62,d02e8c7,73630680,8126ee1a,efaf53fc,2be94dd8,7773e8f6,1ba6b4ab,b08b317e) +,S(5269550e,bd967f47,e45eaa8b,c9f14ebb,aa45926b,6e38cd1e,3c6d5d3f,e0ff8851,a1597d20,26e3eced,443422ff,cd1b3fd1,b45963d0,3086a95a,38b8661f,99a7455b) +,S(7fcfcb29,80e652cf,bc42721f,cdc40ba8,c7c2ae6d,54a51e9b,af1afee7,e84d7676,abf72d90,4a408e34,ec6bcbaa,ac8f19d6,a4d044f5,66a9cce9,f95debf8,882cfcdd) +,S(85f01aa0,4597e104,848e18a2,132a6a07,3d5f25eb,8baa857c,79dc4b6,64a9f451,f7463ceb,8a058187,7bbb71ab,35bcf456,5398cec1,cb4e0132,4b4ec47,e5f081af) +,S(95b4a1a,7dcd860f,ac3fee1d,10febeec,dc1a5fbc,224035fd,a01f8dff,92885628,2a0cdf9c,5bd94467,efa9dfa6,94c6ee3e,1f80bced,23738d97,f70406ec,bef7f772) +,S(4f624a6,24dddd0b,b254b38c,e37753d8,8cd95cac,ec4709f0,49b90ecd,7f6c51c5,874a9a83,2efecd9,2a20dcd,8ccfd454,668de4eb,1b976bd0,70ce584b,c77a4fa5) +,S(39e06912,e18b537b,ce440f58,545e9c6e,a2914d85,698d4043,437dd66d,7506b48d,eff20e0a,16e93096,abc80153,c128aa12,f06c6d,4695bef1,8db7a167,6f352e0) +,S(52edc132,66d67831,74ff4f59,cadb979,4c1d41b6,5efb9310,7a717b46,78f1ace9,e569e202,c6781e3f,e32c0bf4,9684d7d3,cb07cf55,8f46927c,3af6bbc1,c4d402d1) +,S(e3764b48,964b8107,3e287f07,c915fc8d,e4e9458d,6f2a8d3a,1dfa43f3,4328465f,bde2a64b,fb13e0ba,351b460f,6d0d7574,5b7261aa,53a79b6c,3ad5c8f3,4cfdb023) +,S(80efe507,7c77698e,3ec38768,ef81732b,e1c81aad,9c42cebe,75627eff,bcf513e6,690c671b,c54391e9,695e6059,953d3d9e,a9df2e17,5aed4bc3,483f104a,388b709) +,S(484ac7d5,ebcc497,a2f2bcac,87cd23ef,19b0bf7e,93f8e728,5173f70f,c908b641,1d9570e6,f3b17236,9f2b8551,653f3271,5bc8c995,14c2aeb6,1b44ea5e,90ef371e) +,S(9c989e3f,bf1fbdd8,4dfca53e,4415cdfa,adf26c26,3801ff65,36b8fb5f,77e3d124,a34ae61f,5755163b,964b3b80,28fee3ac,2993c442,d7f16dd4,c79aab0c,88212a38) +,S(8b8fb0f,601afe7f,6456570f,19e37f80,32846dd2,97b0d8e0,9308c57d,75a5066b,7858afe,ffc4e6c9,b2e32f10,fd67a1,d6166c72,26f03b3c,240b29e0,e848c9e7) +,S(e37d0e74,ee1d79a,981baa79,e0a5d807,bce0953a,211c00ef,451d9d60,7ee78177,d28a1285,2ad25f4,df1b5625,bfe59875,a07d0593,aab4ee6f,4bd23ebf,b09f8f9c) +,S(80c8577e,9a003683,ad658e75,47657b1f,281052d5,54cd0e19,4b2a9e70,1325c147,b3fd0cd,7ca3a2ea,ec7ba8a0,d7297347,fe2baf99,bcfbbfe4,32a6346f,564d945c) +,S(e7045d6d,34121e5,536f7902,67ae01a9,50f6ba8d,2d05349a,ddeb3833,3ea8c6a1,7306a8db,326994df,e15571d9,c2a5dd24,60b37c2f,e97559e4,e7d88ab8,8a181fba) +,S(55d2da4b,850a47fb,6b3af0b1,3c03889a,d87554f7,cb346980,4f2978c8,652e0d71,6ac0f982,c861d0f6,cd20b7b4,f22eee5d,189a56d,5cc46780,72361e79,dfe16e7c) +,S(ce562e09,55a22f7f,c83a5ff2,11500c03,a1e86d1c,404019f5,5bd1cdb0,b1a38d2f,91de004d,b4aac47b,c6b0a165,edc5f82e,47407032,6f1ced31,4bd6d96b,521bb865) +,S(74e00e1f,596af05,7f91bd64,53107f1d,cd0eb8,6b93b6fe,cc7592e3,7854773b,11ca88a3,38e52a53,eb311867,b10a146d,6fa9f015,11791374,e13fb749,d8e1d217) +,S(ae8f0b6b,c194f6c9,1d83e400,ac92ed97,68214d39,95868530,a2e99f9e,2104eb48,e973fc42,dc0a930,36127de9,eb57cbf8,d4aa8f73,14646362,c855ceec,d7ce4cf2) +,S(40a8c06c,8df83675,e108e0c0,565f33d3,7854e722,6f76b674,1582fdcd,ef891ae7,16ba7850,b5116afd,3d29e0b0,40faabed,b8ff9c09,83af624e,a100555d,887bf7ed) +,S(61ea9e54,5c57f6fa,a2ab410f,861f1fff,926795b0,4d240e48,7f6df1bc,6df83b33,c69ec12a,e0b217c3,72e1791f,7d4529f2,b9063e67,38a8c03c,49071581,da79ed15) +,S(1c889cd4,440caaa4,fcdf55f7,2145fc17,d73e25ec,264831cc,30a0cb5e,c1d37632,41b5246,131fa67c,7314a223,7db5e4b0,574f5b86,11560166,ee55bc94,22d72fdf) +,S(ff295890,791d87e7,982a99d3,ab50bfa5,c58e0d06,25392abb,4ab166a1,8e49525d,a09664de,19951364,19649baf,88806fbe,c370879f,efbe4a58,e619a01a,19454570) +,S(5eb2eabf,cfca1fd0,7c939e5,b8f890cd,74e399ae,d9bdf785,7bca8767,84e95f99,4c42e970,1c9a783c,201aff12,16265d8,1f46f25,fe110f63,31fb8fb,f72c9871) +,S(43e5508c,dbccc93b,5b3f8ce1,7a071c1b,3b17bf4d,8153f61f,cfc7b6b4,f6cbaf91,b5ed8f78,438ba71e,509ec388,d09a5307,c853bb73,db240638,15a07343,9bdfdcfc) +,S(f5d16930,23cb20df,c8607261,cafe533c,eb513f87,7f6e2c99,5b0c0f75,fdb56f53,e539b168,1528332,f7fc4bf8,73e2965c,2557dd40,6eb2c8f4,92ce0dc2,126ece68) +,S(db9d66d1,5dc5a918,46180a62,d662a2eb,72313c6f,ba511eb6,c7fe0c0f,78aba2a1,c96de8a3,61f0dc5a,9e2762d9,2257857c,3cfb46b5,81c3f0b1,f89a20f2,a1517227) +,S(e760d3d8,46fd63bc,4f565bfe,7bf5133b,56ffce08,27b99ab6,833a64b8,868ecdf2,60ee6685,8be2eb4,1821cc82,54062e01,2c1c1e12,285c8381,e60e5d4,12f102ce) +,S(2bdb2299,caca7ab,d22533e7,12e37004,e3a956b0,31da4d99,1351d790,5c33e026,64675cdf,c2738105,dac3e877,e27d00e7,80193286,24cbbf82,a784713f,b6e44731) +,S(1cce0bfd,5992134,b7813773,9fd6c844,7be48d20,e001bbbf,c3c87b9a,8166bee4,2d4a8ee5,1ed7fe30,c3a1253c,4cd9e83e,b5eeb73e,c166f4cc,42788bbd,cad37057) +,S(6d6be3c3,7f5dae7b,ff5b5bd8,ec6b8c65,ec8405c5,bb6575bd,6ebf89a5,77641075,4fd3cc1f,5c6fd3bc,6011507f,7c4eaf4b,24d1938d,35159b80,39246ccf,ac9c2c7f) +,S(d82c180,d96e781d,783fb1ca,8758fa1d,b3c67f2f,143e836c,c6007d8b,bdb22351,3802f669,952aada8,93b3e9a9,74a43218,37415af6,7964b1e1,51a7b8e2,7ad0c7d9) +,S(4ec61edd,7e03fd34,f91dfed1,b546f1b8,fbf9fcee,8c73e343,b228ce18,3db3cd71,e1199709,b5b2e2ec,8af90340,de9ec3c6,db7d948f,aa941cff,b1984856,b03ba9a9) +,S(31aad469,73aea11b,a54744d7,bead13ee,a8df7a8f,8e735643,add781e9,e17a034b,64676f41,3e49f606,3f68bdf5,7ced7486,a94680f8,e60e2913,f13b674f,84b37adb) +,S(a9842189,2fccdb8e,f6515903,b589ea62,1f946bd,97e2931a,5eb1ce4d,4d173e02,50be76ac,3b2dd7a3,a3370e13,3cd6fb37,7ea266d,a566049,abe488a4,89a3908b) +,S(822b54f3,3ec00433,7a6cfa09,277540ce,fee79b08,a50695e3,f8fe0ece,b7bef099,393623c6,20d3f604,7343ddce,d8805bf0,7405d336,fda8c712,8d044851,236bf7f6) +,S(100f6b55,fe3d7000,c5f8de14,ebfc5d7e,15793d10,e99dea3d,33adf25c,15065e0b,d1bb44f7,58c4dde2,7c928267,6d6c1114,a352ffd0,dcec8e51,9b2cd74a,4eecb4c2) +,S(ca5d8318,6a09c227,481aa6ec,d195d094,6a54257c,5adb71bb,2d4e8836,d6142f7f,d890847f,b9747a0a,f3ba0c38,84ae057f,878d8d31,fc73933d,e014f4d9,2677b42d) +,S(e91c25f4,2234d20e,2931a352,f98ff610,e8ffe53f,101b56ca,fa5da12e,24bfbf14,b1ec15e5,441ec52b,c71740f6,d60e99a7,7a26bcf5,143ceb41,872b4a22,964dbb86) +,S(57a8c8dc,310902d8,8569b290,22e99ae7,acb54547,2ccf7065,9e9d42c,1ae34445,85224541,442e09d,f4e92db5,64866aee,50e7cc3f,b8c20acc,b9c6161e,30ab1fb7) +,S(232b8c67,2502d16d,badd0d41,28c02b6f,55a8531d,a6fe87d9,581045b0,7104500f,38110a0e,9e7d8587,227c476f,6549492f,4f5255d9,e618cf39,9a7a40f5,85f93fb9) +,S(7d0be68a,d71f69b3,4f5d4876,319f7e7a,750d5c7,e3dc876,187627fe,77004fec,3e72a050,7d0af3e6,1d6f5402,8a5b971e,a12b1d18,2ca45e67,ca09efcd,45124633) +,S(4dd85f0b,77c2a271,c95fa436,90c43485,b70b02c4,9a46cd83,6ba7a2d2,7af93292,843642e5,c9554d98,48ab6ff8,5dada7a0,f139e64d,2081978e,8c9e3bf5,1c11d597) +,S(537a93f5,88f02004,70b531a1,74ba9a7a,3eb2e5c1,eb767214,9e264e2f,712e52f8,b0d9b3a0,dc009266,8e25f06,71895af3,94efa1f9,78257ebb,3f839b61,340e161f) +,S(13faf471,325b1e57,98ce60a4,6f82bfd1,ab346590,82588ae8,b972b331,9ee48684,a6720384,e84eb529,e22f2585,79b2201a,dce7ba18,845b8bfa,49a21ade,7634f743) +,S(691e24ed,5861b344,e015dbea,809dede7,ca17c482,22d9e06b,e1be4405,cfe8acb8,e3564adc,c197b0f,cc520d90,9d9c6347,5ad00294,3d0f3f96,6f49b76b,91c529ab) +,S(36543b91,aaaea850,15aa394f,fb334923,b754b3f8,9047f73f,423c15dc,7d3d7ea2,73b4693,b79b800e,8e48c838,9218094b,9dff44fe,5a1fafd5,2d68a2f1,bbbe5799) +,S(ff25abe0,394180cb,1e045045,5320ea80,e007bb0,fe3bc8a2,24f20b07,8433f05b,a512b109,26dfe650,e6dbd678,ad9db412,938f69e0,8aee6c2,f903631e,530b7e51) +,S(1dec07b,5faafdaf,51051f57,cd0247ac,cc607bc1,70c53222,72d389a1,7d87e443,7e77e937,382b2bc0,5a2207a9,2598dad4,d870ce67,d0e138d3,bb35094b,9fa9a325) +,S(2f10f776,f62f8632,ea20147e,d14e0919,485ab78d,fc636236,29c2994,9f413c32,3b2c5fc6,e760462e,b9d8c8b,5aa6b1f6,35c23668,33e7ef5a,d25269ec,68d2184a) +,S(7974f394,e61c2cdb,acf09681,4bcafb4a,ade31943,cc180188,31160022,dabd73ca,e1b34da0,3bc1aa66,87df854e,813ba451,2be4cde8,310e4056,73c83600,89e98309) +,S(54c5f39,3c5cc416,56577469,84aa3695,32af1ede,3a51b14,436748cf,1701c332,3dc67b49,49769cc5,22b0626a,eeab6ba,ddbde8ac,ef78a0cd,800c1b6a,5043e4e) +,S(199aa296,f047c7eb,1d8a972a,318585ae,8092e905,e555915d,81c1a3b,425f3783,f5823679,64d17a96,b4ca7946,dfd3a266,585154e1,cee02e2,b87e8fc7,eb46c262) +,S(d15d39d6,fb616dfa,6c292a3b,a1fc58e7,cbcdf0be,7976be87,9a7f088a,9bb7f299,4c8ae97c,4e37f837,bdbd4912,f43bfc79,679dd418,b57d061,f705ba60,2bd7a900) +,S(76d65134,880e7dfc,81a332c6,a04b82bd,bff26eca,9a5aedf5,a6f6683f,364ef58b,b71ae708,bbd22d83,a1ec9048,6975b9a2,7b4aa5bc,5bf1246a,6464406b,401507e7) +,S(1eb4d2a5,d4dffe36,30ae9ead,792ffa9b,452ef0e1,94c06a02,a0308143,dcae51b7,88d978c1,e6ab8e79,9a286af4,58cb3eda,7cc94b67,589b144c,9a55cdbd,6ff47b0b) +,S(dee03251,35708790,361c3451,6710623d,e474bdd2,4513562f,95512f0c,dddf571d,d22dbcfd,cbf6d809,2c68a28d,c118ffec,496d9623,b20667c3,7fc487a,1690f565) +,S(2eb0272d,c98ac6bd,ff68f0d5,5f13f509,bf1dbd9d,f36385ae,ef02356e,56d4760a,f80d4355,4aaf4eba,27aa1832,90573687,5c69ad44,7211f746,111ca02b,26a04277) +,S(eaf62e69,7509672d,8ff6ff7f,c7788822,b75853ea,27636b5,c39b0321,ab0eabf3,442e56aa,1c8fe22d,71b88b96,90733f1c,8614e160,35070095,6effdedb,2e0a3b7c) +,S(2059070a,13d96fd9,6bdc442c,236ef463,cbc70185,b8799d3b,15ef72ae,4592858,bc9042e8,3f259ae8,f6221d7f,46ae56d8,f426fbfe,901b94a2,80da34bd,14961ec8) +,S(ff2ef7fd,9e7f3e7e,6f7b4cee,a44ec281,4b8b4a44,208c462a,f925d27,ad2f52fe,6ace74fb,fa6f72b4,8156cb52,a67f5137,956a447,6b69fe3b,233ce4f3,df0a5e24) +,S(e3e5cef6,fc4553fb,d337a7b0,4357ff1d,d8fd0de6,4df17bf6,20f7f9d8,9d14d83,acddfda1,baa7b60f,d0d1863f,769a475f,e667b6fe,8a047365,1b84f44d,238f0460) +,S(97a8726a,41c02880,e9942341,a66b9c21,a0c64577,bde3c54e,c11119cd,bf57a6c3,b5f37cae,27023d07,78cc5c7,26d845e1,fe160aff,3459d164,681cc38d,8b67b4e8) +,S(ab01e6e9,4862f943,8639484a,119eadb4,12fd9002,1d7781c4,1b020450,9dcc81e6,6ae50c32,101b5c3a,51fab05,2ed79e5,48853cf4,15a30043,6b11ee05,7483b14b) +,S(c464410,da2dcf6b,2e6ba5a,c8d8479e,58ed9a4c,a8c2b0d,5a2ea15f,7673668f,3698c590,62392c7d,e597f333,cd3ce45b,eadee944,5209d361,adbbc386,b499945) +,S(17eacc68,5f721f3e,2013b0e6,76c10795,ee49d524,26edbd86,48f098f4,17867534,cc3116e9,cb19f49,bbf7214b,b3ab76fb,fec0f856,e994a01b,d6b63ece,189ef300) +,S(c040dd40,2908ef17,539b77bd,5befd53d,3ed2e8bc,d7d3608f,2b114dea,d4c00d73,7a6384ae,55ec2580,4d1403d8,45113dce,b2053ecb,6ce0d3d7,427835b4,15279c00) +,S(a5963498,3658f70c,2ec25fed,6659a290,41bf2ba2,ba92db93,41b03e39,2ebddb42,dc114caf,260ec4a7,a8e8bf4,1695785d,1ce7c2d2,82359600,a950ade4,d79f4872) +,S(44fe22d4,51dcf63f,c7e33d09,533836c7,66382372,339de279,9897cea1,1b29aa0d,1718c4e7,3d4bd434,929e9ffa,e2496f79,4f3bf80f,ae805a9e,53b577cc,4c4279b3) +,S(8bd718aa,1358c15e,fa3b246d,e244bfd8,4fc6b5f3,ed5ec91c,ff466a11,2c71647b,172f1a88,ba6c11f0,1b7deb8d,e4002793,65a0a3c8,443b2fa5,f406dfe8,4bd737fa) +,S(8ebdcc25,bbe6aa23,809aa53c,3ff3a7a5,d7ad4cd5,5dcf3cfc,d9ff8ce1,738680d1,5c563b26,af86adfa,c3728c,f886d83c,5be64766,78ac5872,cd798875,45e5641a) +,S(5cf54e1f,688faabc,99742fb8,be896cfa,b469e5d2,feb72f4e,9dbc67e0,e91713d2,d82d6590,d06330d8,2f86393e,190155b3,4920e8a8,86324b18,5694786b,e4fd09c5) +,S(6c0d96e4,3f01a1a7,2ec16ff4,e04571ed,387185c1,4c8a2f8c,db4c187a,85845f1a,f399a14b,763ec2ec,f3415c1b,b9bb6f70,abcf013a,3117ddd6,e55a96a6,b0798c08) +,S(eae928fe,fb6a2fdc,d05f1515,5726a133,9a15ef0b,ea716ad6,90d32dc3,92b74046,bdf87ad9,f086339d,cbfda797,8d6ed40e,f6fd4626,60d6db09,84ecc577,14c76bc) +,S(e5e5e30c,bbe72fde,d9f0dbbd,e08dda,b61d5cb3,1aa688f0,d572008e,447b3a21,9fb4adb8,f80b6e67,47c6ec03,d5171ce8,5de65682,a105435c,5610065a,85b248ae) +,S(711212ac,c9e26bb7,c5ace176,26b300bc,78df6b0c,a79a0b79,7dbcca,138223ee,dc68858,4ef44ddd,9e6b343b,c4c73fe3,6b873239,18e11cbb,dc3aa72a,ef027757) +,S(3b52ebb3,531aa4f6,ddbb9ea3,fb5e5784,c4cf11b2,a4c67d50,6b6340f0,21c5e22c,3da3eebd,dc0046a1,3facf02e,46818640,b698c8a6,3c5fb9de,55a9996b,b190938a) +,S(30f28481,110345e2,7dee7292,fe1c7a56,45294a17,e96cadf9,1eb76bdc,cf56b78b,70c610fc,26ece34b,f047864d,25116fac,3c149164,a1deb08,8e6d702b,77abb049) +,S(4a844a8,12c55b6,4e4d37b6,1ca4a1f1,5cfef527,699d5ab5,edf1564d,e930ff58,49874548,508de6e4,dbbe6bd3,8d0a9ff6,5826f9c0,63274cd3,f3189d59,683dfa3c) +,S(a5ca561e,a7c8484a,642e0fd9,a999e14c,5ce2b5d,edc51026,4519e6c6,7868b06f,cc917942,a5e2eeea,ac09b00e,affa7f6b,7abe386a,241de5a4,7a7c43a3,85afa7ed) +,S(f61b7ed3,1e16c456,c3851a68,e10f614a,1fa547c6,456e57ef,3c1f8ee4,dfd6e72c,cb26d0b7,fc401865,91f5fbdb,4d17bfa6,a0c5a811,4d099a54,734a3280,5f622f2b) +,S(f8e4d462,889700c4,b52859f9,e766fbe6,55976866,a22207fc,aee56185,15f678b2,30bb039f,c1b16fb0,aa09c271,bfbb76b1,6791e95,9dd51ae,6f01aa4e,bac77554) +,S(89cafc1a,5d25915,b2f6f71,71814a2f,d5d97a06,a717a91c,a392909d,332ab653,1a24a0ab,b4e4858,d29c0055,714f34e1,5eac02da,60e87ce1,6fe2f144,257ab76e) +,S(d285370b,d04f5dcf,caa01dca,7a2ad510,33c5b555,6aea60bb,4a48d97d,477c4f20,d4b427b7,32e885d0,13a2adf8,ec705145,c61386b2,c6981b41,6c44d202,4693b9d4) +,S(3c532f2,d9bdbfb3,219dc90d,17aba269,fd335066,e1fd4974,9026f66a,4df217c0,86fd5e7c,a6c97fd0,2c33c7b4,28413977,2791a6f9,f8c80576,75b3e306,66ac5d59) +,S(24d1950b,fc35706a,21b17a16,53037226,2984453e,37e26924,b730314c,cc8ac1ee,4d22a45d,6a31a90,bb247c68,59ae9a75,b05bb9e0,8b57ded8,4b9c1ea9,c9f918ac) +,S(cc6ab0f3,6227b1ab,149f8ace,ea036fc2,d8505341,ab67d44,59582b36,4e7615a9,f9ad93cc,40b1258,67c806b1,20fa6f21,bac918af,54a0f7d7,107680a3,83761cb8) +,S(de24a954,f36e94b6,ca816bcf,f730b99d,6320f20d,9b141cde,f08ff71b,25318cf,3e34b1d9,1ac24a49,b982d235,44afd62f,8475c35e,a48394d9,67904a41,db899933) +,S(77ab04c3,4900aba9,d83a12c,7953cfbd,5f8243db,48fab618,f83ff252,5a1ffec7,6265ac27,3bcd77ff,496265af,75a8db31,231c871a,30a32bd,ae873efe,bcac2f00) +,S(a47af706,5f4699e5,e0079885,d19580a2,51ff8dee,1dab741e,ce84ad51,16e78209,393cbbfd,f1b1f78b,a563f7cb,3465ab97,5b786088,3daffabf,bb8f34b9,7a257440) +,S(a9f5f9fd,c55c7b7,4dd170fb,d0322026,93d709e1,d52a37ea,8a545e9e,9cd7016d,98717925,4badf22e,8fd847b2,e9e80ab2,54f0d327,f6b6162b,8734b105,f1d5e0e1) +,S(d57e9ebc,96b938a2,8fa200c4,e586e7e1,ba866864,a947b71,6cc7cd63,4e18ec38,9aa0d2ef,68239110,5b4c8b7c,b412df87,25de16ea,f28596a3,62a6aac,d1b6bd36) +,S(7463a8d8,fb4dc14d,5618e66c,aa85d73a,e27ccc1c,ab820611,9f506829,faa58e9,82fd6ab2,275af504,aa0645a2,8438db86,ae7990c4,b4c389f,569aad0,68d4829f) +,S(2e7a708a,29c44831,9a02d03e,4eb331b1,3927ae64,534db2fc,a3c6e7cf,d53bf412,84f3f199,73500cdc,aeae0073,f39b3b2b,ebdf6824,ec018160,fd2e3b3d,4b1e11d1) +,S(8707b0bf,540bc058,faf2f3c2,e8ba304e,180d094b,b7fa8dda,414d30c4,d9dd5e03,70b61175,fb791033,50c6bd25,aa0594d7,18db5ee9,9667c25d,fbb49c20,f100b915) +,S(3fdb370c,3ce6cd02,886070a7,28e66749,22f67dce,1b6c08b9,613aa2d6,53ca842d,163518f2,474a0344,a5c4c5ec,10b1efef,5d3a5ef9,94010063,17a486b0,c8e0dafc) +,S(c37da302,412cd549,a01411e7,6f58d4b,33077960,94b31af,2a283d89,48472f62,aa08f287,16c642f4,8702d1da,aa0a82bd,ca849000,b8ad1d26,801c6fe1,3a21f92a) +,S(3eba0550,381ab0f9,251f923b,5c7a339,60ade9ec,2b0b47cf,25726fc7,a5e08a1c,1427b0eb,b681dd3a,88639652,5afc4e00,492a1ad9,a0c5a396,55741a5f,cf0fa7d9) +,S(96723ea1,8ce5d5d4,bf64628f,7754fa0e,e43f20a7,85356e01,94eaf8e6,bb50cee8,5ad09fbb,b9bbbf10,e86eef51,2d448aed,6cf51b5b,b28c8e8a,713066a5,81f49bdd) +,S(d7645211,7ecfb6cd,3a09d346,55d5c58,ab822892,67910f13,29f8d604,a3663748,ab7cc104,d20fde08,2c889dbe,2baaa9cf,bf2c9b10,c225da46,eebb8031,c28540f7) +,S(1f6b23dc,7e0ab136,20d907af,ad4bc944,8c866065,b4ac7e43,4dca8906,d0ada5e6,8c37b25d,6bc639da,ad092040,5daa9eb1,56041440,e48f6602,398ec256,763e247c) +,S(46ff04bb,aa06a168,79479e64,bc0e8ed7,6abb5a12,8afd1f9d,9bd80d50,75459945,b1104ec2,6af2ba0e,39133bb9,e47a61ab,e7e9d229,41d71764,91ef9da4,f51bcd4a) +,S(ca1b3c25,38888069,3b076e54,58bb0451,3bcdffb3,d824af86,f3f4a883,2a597ce2,f02916fb,dd1b6dc4,76109d11,bd9e81ed,dfc9d6f5,79847622,51bfe2,a1e0285a) +,S(c961e9a,adb69ec4,8efec7fe,dcdbdfb0,5fad1277,2b801763,ee747a10,99ece6b4,469a6c33,e0b253e5,270bb70a,d16c4b70,56bb9b3c,35f0a2a9,84e2f269,9d8fb6e4) +,S(3a2ea279,1418cc94,d3f81708,9d44e777,7b3132f5,b9b67393,ea4f28bf,939d99dc,15805143,c035d921,be217dc7,18d13e2e,b981bf8e,6525f88,31a96c65,6bf164be) +,S(416dcdf,b3a1f0be,1a3fd6ad,52fb1c03,4e24d48c,cf34d189,e7dedea6,b65a7a4a,76909ec2,bbc93359,ac177781,2132db31,47e90a0a,3c6ca35b,ebadd113,60c204c3) +,S(b397c245,9aefc175,8ba5177,2d4b3ed3,2ed9d1c4,85d2a2b1,7318545b,93c63eb3,a106a360,30763676,ab418ffc,692043ee,22813574,e3117a7e,4471ccb6,f5e71748) +,S(75c5589b,efd61646,329dbb75,5e809b2a,c1bdb8c0,d29a3065,32ef3909,d40637df,26f3e1e5,1492105c,90ea19dd,81fce6bb,95e60295,a1fe347d,cba27adf,a3e6f631) +,S(2eeecd12,a3517432,17d5158c,439a9046,e4b0dc80,119e58b6,620e6f08,969135a5,e1deebd0,48c58ed3,1b53d753,9c4c5791,13606467,14147707,806f491d,2daaba4c) +,S(a981f091,5d39d650,66b1d52e,5addda67,8cab860a,c75ac124,aa100593,9cbe65d1,4cb09fcb,7ab60293,2d98b23c,96e5109,88d4f149,4f334e7b,66c60040,7d3ed069) +,S(1a19fae3,a7e81d02,a1260c9,a759e79e,545cd869,2666b31a,9aa4c0a0,9bd4ef62,2807d657,8af25c69,e29bf7bf,d877dc7b,79714df0,68ae0707,89c5b72a,b0937902) +,S(cff8696c,1ee7d196,d76f139,2662e776,9b0f4314,99d30567,1952813d,2420c61a,8497e013,8a399690,25c04b1a,136bb816,3581f122,b62b70c1,47fc52c5,e6d16df8) +,S(6817a420,4a8b3479,caaa9582,4d48eb04,9669115a,9e5a5cd6,6cc905e2,1e27ce8c,9585468b,c3377a5c,98725465,35c8385e,8182a0c2,763226fd,95e72937,7b3052ad) +,S(9ceffc84,6e0ecc26,af13eb99,579478f3,7d114b19,59253233,bcd33d6c,8dd9d58e,e01aca1a,5cf8fa1b,67c4d4a,fef1c7ec,51060234,3ea64426,856d0aa8,fa5d2582) +,S(6a6e1dc6,f203f7fd,d9796589,2301e5fb,995a3731,8c410543,835f0edc,d3456c49,2a072b98,98b93e9e,b05f9ad8,6a97546d,83b579bf,6efd3482,f93baca1,3784496b) +,S(7e7bae1a,588d761b,5158b4f0,fb9186e8,8ba3a521,89ac36d2,4dd31d7c,d2a9129b,5198f63b,37995cc7,289e60e5,7d0f8738,17e6bbbc,d40d29d,cc4856fa,ab3dbdd6) +,S(13fc3a8,63deab2b,ed54966f,fa85e553,ffa15863,ee12f9f8,5dc5b35,6bd253,e31c3245,91275056,ffca59e7,6e76a957,a8b77c82,702e5d58,b3b5b577,73821459) +,S(ffe28deb,3f39d917,f6b6dbed,ae89ea4b,e5650326,d148ccb,becbc6d1,16e9c167,8d8a52b3,b878444d,e5385760,4e02b3fd,383c4be1,128c5b2c,262aaed6,9dbb988a) +,S(28ed423,9bf26de7,d0379a88,30fa0ecc,481c4354,1dcbc3cd,44483b0f,5cc57be,192122e2,ea018e67,4520d860,b4b8d859,2d560872,19bd0ac3,7bc0405b,10ce126e) +,S(7bf3827c,7be8c484,52acc00,eee769da,5aa4ca38,2f806d72,76c72c8b,bf8a708,925f3eee,e505529b,45c601fa,1d71d706,24a75d07,1ad29172,6bb243e8,a559eebe) +,S(cf1a7e99,21a01c3,f8ede862,71f7b6bd,2acb5aab,330a17a4,a7be1380,6fce7000,21365a83,7b3ba611,16a3e740,33a3463,5f1e70a3,f38a878a,7c3a155d,59d3d673) +,S(e779ea37,d1517cc4,e36c812,1bd0a986,af3bdd67,52626944,afcbcae9,11bb29c7,32c635ac,4b19775a,a04e2c6c,29c6f42,6472bb6d,45c1bf81,e8ac8015,d78a8a2f) +,S(10309d2b,76b54210,1599785d,6c381d52,f9697728,8e0182a1,638b7f68,f26c2a92,21edf83,4c859870,efb9b37,7f931316,f3abceac,c19b6a1a,438d020,658265a9) +,S(79927b09,701e46d4,2eb2240d,e9132036,f2b6b311,a7140701,813e721a,533a27f9,fb7c6513,a81886c1,a4c75640,36136104,8a0f47ee,b8d2b905,3b3d84ed,3b58920f) +,S(743b4e33,77da3429,9f593e68,3ce24e3f,85b1de0,4a3dd37e,fdd8c73,1528849e,37900069,b5ee63ec,7b3f178c,aae73281,fbba7de6,849e14f1,8164d6b6,742f3216) +,S(d73cd2e1,ce1bb7f,1aacd9b4,9951fe6a,e46064fb,a73acbf,49868605,c4f04da,e6a762e4,4cc6e71f,f5887fcd,6a33ff1c,cae7f84e,2f22a096,14b7f4ad,b253dde8) +,S(3e1c00d3,f563246b,3ff318a1,77b3ebf1,ba632481,47c073e8,ed32d697,95f6fa68,df2b60cf,87d5c129,1036aecb,80e381d,18ce2e00,c23fcef6,b4a72f0d,2d0776d3) +,S(96e07f90,92da1653,e5cf10e6,87526db4,ed90c2e4,c629b221,a32fdc6c,d968053c,d65c1c3b,b8a2ea6b,9ee20ea5,bfad3b9a,1f8517fe,2e5e3616,4ab20787,4dc2bd66) +,S(6d230440,26b1ee02,531cc124,b2e0796a,d27a7652,33862854,d8e177aa,afe1debb,f3a8f995,faa14689,50fbde47,1e4ec008,e3dc6228,a8cfd2c2,5983bc09,ed79bbd3) +,S(8dda9f5c,1f949dc0,314e43c4,9e716138,ad7d4511,a4b06d9d,c76fcef1,e5707781,d0563faa,7585b0a5,12b674f5,db737435,ad9d9bef,ae5ba77,5c78a582,6801310d) +,S(5070613f,98667363,f5eda369,fffda417,b4bf17fa,b4c276c4,e5aa357b,bbde97cd,b20eff,4fe77ea3,4185751f,9b16db86,eb40e47e,486a4817,8a0cf09b,dc34ebc2) +,S(3a4a70f0,bfab1456,b9b8838e,ac1aa188,4986d74,6a9b3a8e,fc792eb0,af16bce7,e4524a93,19168eda,a1832980,c04e8423,843b3e89,82381e24,8bdf5a3c,adc4f3e5) +,S(2cdcf892,183159a9,da9a82f5,4630773e,db5fba99,3bcdda38,b5291230,aab33532,c88ea6ea,c9113f32,85e299e7,42abce8d,fd95692,32292044,e0a35870,757677b9) +,S(1a85928d,f8f15f61,12e0cd6,f33199ea,2b7fed02,98c203d,781a2dde,28955c99,1b3986b2,821c76a3,fe13a6b0,30725c29,534a124,51ebe945,5682ce39,74db4299) +,S(86d14da1,d6b03065,a1520663,41b9f010,dde01966,3e622c1a,6b66b84f,1da1d388,679514ec,764f5cc9,e884a6f9,f38042cd,cfe5683e,1f6e5055,fd1380c2,8399b2de) +,S(e41f754f,bdfc879,43334341,5a5078e3,30045999,7c245441,565d0357,16201cc2,dd059641,c21d191e,dfef119f,492ee9b4,743f5e0,bb3cee47,dcbb0fdd,790e8e8e) +,S(b7ec9268,45b5bec4,79668d8f,4e444643,2946e17a,8338e2fc,756996d3,4475cae4,ab4a18b,b7539e90,10e210f5,779476b4,d945e350,978ec2cb,7cc62e71,4fdda53b) +,S(240fd9dc,f1eade19,1662554a,a25850b,bf3ecfbc,83249d4,56b769d4,b7518912,af03fa5e,e0ba3908,853a3a62,eaa6a804,5318a897,31352207,76a06b08,d104515b) +,S(353c4ec,ee7d3114,979e39d2,88cc3faa,2b88aadf,8f1cc129,a5c57237,875bb769,9fa7ec40,90af4e12,e940118b,ad70ab8e,28e607b8,5ae33cf0,2a0da4fc,d12d147e) +,S(f4eed58a,a8556688,11606ae1,1628fd1b,89340988,cbe0482d,39e80376,2bd933de,4278cf64,fe74e070,d071969c,a8ceb40d,18b40bfa,52d7feb9,1606f0f8,df3b3d44) +,S(698ffae2,e2d02660,434c17d5,b5552d4,b284f0a,736bc0fa,1a1290e,266ef1ce,1966cc8d,7845b74,1da7e53a,496fc12f,8bd50cff,b0bd143f,ab608198,e1ffc970) +,S(b53b596d,5c88c140,d6e0587d,417c8945,22d884a0,4fb596b,5957121a,65314098,ddff60b9,9befe76,c87de485,76c32eec,25deeb70,4cc19a56,77197ae8,8f2c745a) +,S(97604b21,d4393bf9,d6e4cba6,7e9f2768,79151865,9f626d65,52712fb7,1a13066a,e7aef384,e1cf7f7c,65c5b0d1,7357f266,7d871c54,fa027616,36062623,4a8d17f8) +,S(7a35c9ba,6edaee60,312b234c,1062f7bd,3b38760e,da1d47ed,b63484e9,51bb8623,33897a7b,a4546761,6ae92b58,6ef704a0,769f3a57,86ef8245,7ebd6a42,4d84a5b1) +,S(86d40c75,f989115d,ca26e0cc,9263010e,c9638b17,86707e01,b6a20d95,d1e2804,759bd762,4ffd8c1e,e71dcc8,a846b5c9,dddf2842,c4170410,c0f38742,ec315ca3) +,S(603bff47,9a4bb79f,663ddea4,93b90e5d,fc77f6e9,b2a401ce,3e8deb31,609badb7,62879fc,65281aaa,6aeeefff,cd33a02f,358c86dd,dc03720e,e1e23998,9da4f4b4) +,S(5c8b8f3,c7dc7a7d,721e0bbf,8a75a36c,fa13ebdc,14987d7b,5dee68b1,32203ed,6b601f38,2bc4c6bd,7d9d304d,88fcd6e5,3faa43ca,141bd90c,e7749340,ce08e7d3) +,S(313c1ec5,a91694c2,41e7a55f,f83b7378,25a6f27e,90090505,a7963ce8,7544fb05,9c3153ff,9a4365fa,fb644699,bc4462c5,1ed858e,24752e59,82566037,103c6384) +,S(51aca51,4616aefb,30268cb2,968e0fa0,150b4bd5,a79746bf,98b01543,a9d923bd,7c51f9b4,73a7747,bfd63ca4,f4e2b361,a0a66ec4,31df41cc,203457a7,4ee028b4) +,S(4ae8d399,27ea0648,4936d3f9,2bbe97a9,353071d6,7743ca12,2ab7b6c3,2619677d,f9dc519b,c251bce8,38ea332b,9110538,f350f5e,4352e7c9,19e677d4,3c8a47a3) +,S(6bd1c95d,3f9cb5a0,8c1a054a,884d4bbf,b100c289,c4af257b,aa0784de,a256dcca,7936283b,de39b12f,6f71fc40,1b07de78,80192357,a8887e71,39654ef8,6b803b5b) +,S(e2278a29,4642caad,ae370a62,e07fbbcb,5737f700,9ef9e8ce,19bdd283,aa49480e,43122fcd,f3943ce7,35b570b7,ed82f61d,87bc8b5,83d64f77,b36f143b,4837dd01) +,S(68537cd5,9f9469fd,d104bb01,93335830,8d24fb2c,b22471f,feef4ac4,fe96c644,765360ef,41107a51,dbf99ff3,26e3b19c,4003ab45,979de4a7,32063c81,8400050e) +,S(5ec9ffc6,69c99f9f,8f8a0735,fc088824,70be08ef,3f81bb54,b1290a07,765af330,abb54008,e76f8716,78c3229,56b47c0,1f4f1cdc,dd1cbb38,1a421397,1163b222) +,S(4e00188e,5d4930fb,a9471aba,465154a1,1a330f6,15cae31d,b2399874,704dfae9,7e76f30,282436aa,73f656dd,35b40209,5ed3fe29,d2086bba,57fbb81d,4d317868) +,S(4ae347a4,d480152e,ffd39ede,b4c2f3fb,a2659ce4,bd3b6e3c,8aaddfd5,f15ed984,383e2f46,d44cfdf,4fab8ba7,ba72c635,65bb6ac1,f35c7307,ca2c5c3,62d4e523) +,S(32cade24,a8d3ac0e,f96d90fc,86509a5e,35fd09c4,d8f7719c,603ce1b8,9c6665ef,87273873,5c63b137,5b63c5aa,6ca89f9a,266939f2,e0c936af,55c10d0a,fb8bea36) +,S(8e4ef195,60147576,6ace6891,f87c22f,20c703c3,d4f7204f,5f422444,51cfcbee,2fa72e3,89d97c1b,79eda0af,c00fbcfe,cd5b9d0c,c949c666,459706e,6ed47af) +,S(35fd575c,4adc03f6,c4d54991,18607a01,559d7316,9efc2509,aae7e7ff,a4a2c30a,f9a5779d,274881e7,cb700926,dcd10ac7,dbf3eecd,9c948aa1,3474add1,ca48e000) +,S(932e4c50,7fd02595,148929a5,2c4126c7,efc12f5f,5f5db287,3c635fed,c90a9cf6,ce6bca21,bbaca19c,29f6b1b2,4d1982c0,9e84effb,cdbf1f28,75f61ef9,ba8ba783) +,S(cad8de44,22a051c1,be36a37f,2f459707,55d3e2ad,35debfb2,11a45d73,49fbea11,48b0df1d,4f6669f2,80a41c90,34f86f11,308eebd7,8a9fd3e0,53323a66,f01c347a) +,S(9fc7d304,c847fae7,d016aa64,6cb36383,1919ffc8,fceb757b,462fbe90,6c9594d6,dd17c0e1,3bc6a187,cda9dd38,a7afdca4,1963676c,e4d4bc9e,516e3a45,d9860ff) +,S(41ba6cdf,10d4a05d,c6865453,894debb8,8300e4f7,4c17c0b4,c8935761,988b5849,7eb62b15,8c3f0965,e571e278,b2833321,ece57e84,cf153ac5,9309841f,e47ad4c5) +,S(1ff9fe5a,aef36ae6,a2d74248,cefb8693,d5bbf30d,f057e884,b227ba44,11c7377b,6ba24b6c,585c0038,49c9cf41,fcb55f09,50690850,5be64692,16520575,f1e74278) +,S(299d7c44,d706d29,e6d9d070,4856c272,6d134814,1f8f7ebd,893f38c6,cbf5d660,e4a74f3,4d0374e0,ca9b4887,76de9acc,62f7d1ff,9b494040,fc85eea,2d03ff32) +,S(a0333ed9,ec1c987,6e318ceb,83d6e93a,b607c2d,cea512d6,9f7b2bfd,72e3a67d,da7dd365,5f51769d,35b37393,21fe7b50,19f83e3b,b6b8941e,d685919,fba0539e) +,S(5a4412a2,2e52a330,534093d0,ba96865f,2821cf01,564ea0d2,e75b84fa,404251e0,6a4788e0,7e6c570e,8390bc0a,b06d293b,3675ab27,54eb700c,7cd4078d,8f0e4313) +,S(d772ec4c,3b141dc6,e534ea6,a69f9b65,783351d,c2fe7cdc,3e823cf6,32b7b0b5,bd93400d,1036487e,7090979d,ddab3821,c9ccd92f,db89bcfd,da929be6,689ac0df) +,S(949782d2,c7694c3b,ffb3e1cd,6e40f807,d4452fa4,eca1321c,d04a2367,6df89336,e7c5e67f,b8ba22b5,4372e5db,bcd63c55,9f4e2c14,c97bc930,b68d459c,bad436dc) +,S(7ee7d5f5,75e6f59f,3e0a9e4d,4c49c71f,6d9ca0c8,6177470e,2334f616,a457e6de,4462da9c,76123e66,c9074add,76fa310a,9cbbbe02,d6a07d01,97e732ee,d7d9f3ee) +,S(7a4b630a,e08d47b5,b785ba7c,15417951,8a554847,bb8320b,50faebb7,b13f843e,ca24e44f,b86801e9,7163a524,db4980de,69a3b219,7f9e5dc,6b5d7076,9d937c00) +,S(d2d90a42,428ac40a,40aa5503,2bb623c1,3a18eef3,2994f793,9c31c6cb,1aa82b96,75852e33,2367d59f,30039e06,40b1e0e1,394a3b6e,582dfb66,7464d5a3,f234972a) +,S(d92499ab,6206dfb3,da1b5606,62ed4f2f,a4809b5c,48349b91,340e0b16,e95d13e0,423544ed,26a4fe1a,8f940074,993aba60,fa4dfc64,be002941,11f29b2a,b271be38) +,S(ec0c1ec2,58875e66,d24e2d31,5b7ff87a,bba6f2be,6c6bf4dc,8d5830f5,c5d09a23,e526a7f1,648abd18,1c49a237,e608bf79,8b798c98,75804d7a,ee8ba416,28591421) +,S(69380968,835b5989,885b4805,290ea050,3a6ae508,17798c2e,f30e1009,6bba8863,71bea39d,80f0ba63,45297137,a14d07c7,7522df75,8192f345,a6170f5e,2f11e5f4) +,S(d66b1da1,9fd1637e,44cfe8d2,e1ff2fed,15a40a5d,f596c62b,ebbadc8d,fca9ab23,68cf64eb,bd2b4bb7,1ca17c4e,607b3315,5cc5d91d,26583b68,78a69476,586b9946) +,S(9dd98ca2,c6fa62cb,92750d70,c9931641,5036475c,a6b59695,a510dc88,3298c95f,55a88bb8,53b99cd6,f8d278b7,e63b31db,40750905,d98ffc81,87a0e07d,acfbe821) +,S(1b66bc2c,842cf1bb,ea4ecccd,c1e2d71,4efd848c,db7a9b92,5b9a9ade,d141bfa2,fe0b4701,55fe82b8,af43d88b,68423cb6,402b3501,8831ca89,ddb9a70,83673bea) +,S(b280dc4,8a9231de,d396a61c,2922e003,c7d2d5c9,f0e8312,c1c075ca,c8eb688a,81b745a6,a2f8be66,b32cb3ad,62babaf0,498c8261,531cfff7,da9ce306,d2738a74) +,S(7bc5951c,9eb3ba1c,828125ad,510e2e92,413e906c,f015680f,8cf1cdc5,f18a6b5d,41b905d8,480ba8bd,b8a6fc7f,49adc6d4,fbda2f0,ee229a1c,d43af5a6,98352a07) +,S(69ff74d1,2318548d,76a53095,25ca8695,11647908,dc4f2ea3,4ed2c53b,f6eabfc1,f3a3e628,8eb99f78,12eaca1e,b3adf5fd,1d617397,dcc95bde,d4be775,afde2419) +,S(5fe6dd3f,1f6d3a5,9fa8f8cd,de7f689a,ffa46098,aa0f03b9,2c552e1a,c84af209,9eeae901,acb8d022,4ed197a9,15510eaf,f356cc16,274a1aac,d6dbc74f,60dbfb55) +,S(469e9122,cb0475db,7469fafe,9c53f911,d3b52bc7,8cce23b1,21d22e59,c505f5f0,fe7487a8,38b2ba6b,f5a5825f,a4d22c26,80d8a580,9db637e,cb84e2fc,1058d812) +,S(1f4a3ebf,6b62923,b2df816e,8b30f8e4,72a5e718,70c1cc1c,6d63b4d,9160e6ab,98da1295,7602ae19,89938bd4,298a67d,1ebeebde,88706d39,b77c6a61,4dc89e2f) +,S(d8ea95fe,1c12ff0c,cec226ac,26f510a0,4117222d,d0fa4773,c2f78ebd,53b86b0f,155bef9e,dde6f293,b88bebb3,ce92c249,f154b59b,a01d7f5b,25fef472,8c6288d9) +,S(1ad8a3c7,97b38071,2214b2cf,87045300,2bb36f5d,dc7f2527,1797bd4f,1227cac6,680a77aa,3755237f,15418957,6fcf51ed,58398c5d,4d56a1c,cfa3c05f,4857814c) +,S(ffea7104,5d1d26e,d942646,9f0b0f88,355540b2,c32aa92a,3fdec318,24fa7d66,eca244e2,2d8da06c,44ec8db7,5702edd4,81f67af,2ca64ed4,cb5d04c2,2434eac8) +,S(4ac55ba3,f7fc8898,54a141c8,cfd6f675,d3abe9ba,55d90f3f,c1764ac8,b959d8ab,9c7b2b91,f135fb7b,fd252d14,118b104b,714821b4,1bd879ce,15bbc93b,f8be2bd2) +,S(5f814467,7aa9a4ce,f29de0eb,865b8a02,bc7061a9,ca525536,fe27af50,bb718ac4,bda965dc,4062b26f,e6434071,6301fb02,2b8cb894,73e39b36,69acf101,90d9c042) +,S(f372cb04,37917498,4b29f213,5981f32,da5f96a4,d1acb903,88beb154,75dd88bb,82d68f5c,1e62d500,1a0a0ea0,7694194c,7ceda2ec,e32c4efc,b2a0ab46,1a367d89) +,S(fb12bc5,45760478,36313375,3fbfa4b2,878ec6f2,243e2692,7a3c5320,bb59b128,3f820118,67dae1b5,bb5ac0cb,a24ca681,96193077,fd7bfe17,a926be5c,4953aef5) +,S(3d9759ac,918a4a34,f4307560,17a9747f,4adafea1,b0a92447,316ff819,60c0ea07,cd9dbcf,6d6a330a,b671d5dd,aa96497c,caa317a6,77bebecc,6fca559a,56018aaa) +,S(eae0aab3,699c521c,3fb49be4,669bc7dd,9f476fdf,58e42909,84455c82,fe3e00ce,badce8dd,450ee7c2,99b77b56,25e808a3,62c7ef1e,11e30bdd,9777fae1,4f17259e) +,S(fed252ee,c2c0ceaa,57625d0e,925ee5d3,43718a7d,24ca3384,55e0abed,451eb851,66bbb6ae,56ceefcc,21d66b27,70756f64,dd07211c,5cf0bb4c,457a5a8a,e82c648f) +,S(da639ebd,22ac3c1,417fb04d,3bab0b22,2362af2f,9d3013c9,bc08793a,2d7f9dbd,83f27620,55f1e9f2,fa74ed0d,536bbe54,3627aaea,3e7a031c,10aa7b4e,822466d5) +,S(524d24de,d77345af,4d4d3ac6,7c71df91,32ced2a6,acae682c,e097cfc2,7eab90dd,e4cf5cf7,c6927c5c,31b6f55c,90fe7cff,2d010a00,887b3b01,b2f7a074,fab7f5c2) +,S(7dac2ed5,fb52b60c,35c7cde0,c28617b4,28672da4,5fbc21c4,b24c5268,54ae4f94,cc6acc7a,e9168866,70b5c4a2,bd2466c2,f6cc11b6,d282b09e,a578ee0f,e7794038) +,S(5f46b64d,da61f59f,6b99d10d,e9291a,887e5d9c,a3893ea6,f7c51cbe,e56083ae,6043d055,da252655,506dcfb9,c5572929,9bfa6ba,7e1b582e,5ee1f3d9,e283a8ae) +,S(8863ec33,b6a25f21,6e641ec2,b8c5df0f,48ef0fc2,38a7f635,175961a1,7de14aa3,9d6618f3,1e52581c,2f829277,7490655b,45b2a583,da0ff7a1,17dcb12b,eb42541) +,S(85403446,3ac459ce,6d8184c7,ef26f91f,b377f3f7,3e92ea03,a1bd6a68,33a2f9f4,2d1f1296,8ac56499,b252a5b1,8313fe35,8f7719f2,3b0c9430,438f7278,c5b399cb) +,S(bf6b3f6,217e412b,fe651dbc,362266b4,6a325d27,5eb7f201,379cadd6,5e223c7f,a1160954,c14aa455,fb041e7d,ceee3ded,ebfad90d,6af1beaf,a9b1aef,97ba748b) +,S(4b20202d,3c186135,4aa079ea,409aa4cf,860ca219,8ba1bffc,77124e5a,bed9e59d,9f684503,c107c0b0,ba5d858f,2f11d904,7703eb45,510602ba,b555e8a9,f5b8873) +,S(4087f880,6d679a4b,3a24f533,127b5931,99c050f2,627cbe28,2686a5aa,6421dd2,4838ad84,b3d9d488,33c8c883,698f5a59,69880041,589f921b,5a5707d2,bd88e8b9) +,S(15a79287,cb2e7406,a2db91e0,5a4fc34,53877504,c790eac7,66d9131a,fe97b79c,9f4ef322,76572e3,d3fce497,c2c6160f,1bd597cf,b96a83fa,df2a41a6,b94a238a) +,S(1c4fa063,c0524bc4,ff233d61,bcb3d40a,404fb10a,7e222812,2739b343,e3bcecbe,2a8561ec,a2d82eeb,97209e9e,bd730b2b,d39c90b2,bf4d0353,3aa8c73d,62d48bd6) +,S(a0708ba7,43c1b2c5,267936c1,85312f2a,bb50b8a6,d4886c26,56d163b5,adf2a636,958f45f1,916988cc,6c9b8155,12e1d2c,7dc66a62,359a4324,5845e94d,371a20ea) +,S(d7960b4d,f01a42e6,e109d71f,2e33ffd,9b79754,b129a858,c213793c,e8acad7d,8caf19aa,5a841d2b,61c3d0e1,dc65730a,33566193,63118707,d81c1e19,dbdeb920) +,S(7a03dc6b,f8ba70d5,96e25ba3,8fca1b32,a7c4506e,6e8a3789,daac3240,bf8ba611,70f19e22,292d6856,5a63e378,b773e170,48a3681,d096b881,fcb84a4f,7f7d9028) +,S(53a9a662,a8fa3411,c3989850,c6c83aa5,da516ca0,726fddba,c2f38f25,c7443b97,5deac250,6179c31b,f313279e,844d1e5e,2adcfdc5,b803036e,140ff59e,3945e25) +,S(86b946b6,3dbb0d86,ffe69af6,3c1bbaa9,b7ee99b2,876836f2,a450d9c,feb2cdf7,44407783,d3d0e2a6,cb18ea1b,a1e4f133,7cbc39c0,19997a62,ed74b598,f74b1fa) +,S(ce81cf5,cb884b46,f6956726,20d2423f,6b28c8ff,ba71d9ba,bef152e6,ef752d8e,75afd973,8120644c,349bf924,c04c1aaa,979177ff,2890c926,2d0b5404,5ea9248c) +,S(41106e41,3a464d2d,9f86cb9e,47d57d47,7b791d43,133a2b8f,bc6ce92d,e1172ed9,e2ca44c2,30e920b8,5601a2,773a0f88,2ce4e42a,7379b374,d2ec6fa1,f76741c6) +,S(e9c1f2a0,4e830a12,e546541e,c7ac6f6b,bca3f1ca,2052c152,4e141b4a,20b49777,51df3843,8dd12c2,29973fcd,516712c8,5ca73721,f5d50308,86b91f9b,32a58124) +,S(8bb9e12d,c5e8ff3e,4ba25775,f1552e3b,9be21f27,4250d511,fce5cf15,e73bbf2c,8a822b7a,273c3730,1c24fcf5,c19c4de,b4d0968a,bc23962f,91ef11a8,d00d1152) +,S(b0058ef1,da227791,e4694c3e,ef66e031,697f3f3e,297d139,9ad597a7,acb6bd0f,7f5bab4a,5793814,d8c0bee6,8ffe8025,e5deb644,7d2ba978,c805b2f0,be205a2a) +,S(1dedd42d,8df5fdd6,52e02b78,4dfcab0,6dfc3557,4b8725c8,db95368c,ac2522a5,3055a449,23730d25,18ff4a8f,983b61b8,24b918de,f357654f,5b46559e,b6bca540) +,S(761a5248,c6794ba9,3f45b0b5,12bc39db,e471813d,9d5c5f7d,a46f2ef4,380ea544,185ded30,c4f5ceac,5e18d0a3,95ba8ed6,9f703408,5fad1fc5,c60d10b0,832c1292) +,S(f1d5b60,e515d0cc,8dc20982,a13c1b5b,a1749687,501a4f2f,fefab898,e3aa5caf,55fd766c,395fd8c2,173a9e4,8eb63f07,ee6f9ab7,54994708,e42ed9cf,78a0d91d) +,S(569cb44c,9b7900aa,576ba0bf,61c4455a,fb09ff4b,c30242d7,fba993fd,bb37425f,dfdeb8d2,ff1ae3d4,1e78f646,ac7dda3d,c1131de8,e2566d0,d3340272,cc350b1) +,S(3e59b69a,d99839e8,51947a78,7d8f850b,9c2dda11,7dcd0776,d22c787c,ba1851eb,732cd2a4,8bfeb030,6bdd9358,37ec4f27,7050745e,b2c9f6d4,34cd8834,592e20b3) +,S(a46d6621,7b45682,98250240,3fc0886d,81acec57,32c3087b,e6ea4c4,95296967,140cccf4,29a5b062,24097a73,f9a8208d,46147884,e6127464,51acef,b9763d33) +,S(b920e59c,f25c53ba,7c00c427,d1575c9c,4ad70efe,daeb7927,74d16c46,5079ab1c,606160f1,d4ba888d,1d5435a6,1656b937,9201ec5f,37f585c9,d43197c1,f045b67f) +,S(12cf1ae1,e7d837b9,eafda1ef,db270db6,3b88b6d9,8d05c713,896e06b7,f8bfa8c5,e0d66613,181b934b,9f23d7b,e9cfd8b3,c4c1d66d,485075d9,1e8cca69,39c99c0f) +,S(6aad27ae,a4eaca2,e60620e5,a328154e,eb93a900,be13a302,87ff39d3,8dc0ec1f,932155c5,caa21539,e27e8cd2,dc57fd7a,d4681474,342c0811,2fe626bb,94a1f46a) +,S(134cd94e,7cb166be,82b48916,6c06c1b8,8d168bf9,21f75c36,ce9343ec,acf870a0,42a673c5,e956fd45,e82a51cf,ff09a399,2f7c8fe7,e73d14c0,fab88c3b,9453236) +,S(d5dcd58c,7b7cc786,8c42971f,a1c85cee,429b1d18,dca68e2c,56d9f5b5,5a3989ee,e0ca4130,ef1bcae4,ecda0529,7a338bc7,45bedd0a,f0bb75c5,e316624e,21208100) +,S(951d6534,c344908b,905fa4cd,b691f33b,3e3567bd,1538a861,f66ac9d0,e0d8c8e,eef35922,eb847928,6681a990,345255f6,95a5f691,9a7d79f9,d575f306,ed7046f1) +,S(cedba44b,25f7964d,76d84c9c,9b521156,690af0ba,966ede27,b33665cf,c1cdd0fc,806a9049,cb8e9af1,d187b6b6,493316b6,187e7124,91a8f7d9,4c21b79a,87c79e7e) +,S(4ff03660,d1306bee,29abd39d,32beca15,d1c7d2d1,14492a20,49c6f4aa,d8a10b54,c2c75e69,8fd89951,e36e8bc8,be71f689,4990f25d,d2ff1893,d99e2773,6d1e574) +,S(c08bd508,8dbd6465,e87b7702,dfb7200,c78061a2,683b9824,389042ce,ce2e0ca7,562019d6,1343497a,b1640884,23a9f171,1db329b6,8c63e78,41793255,f88d7307) +,S(48dfdcaa,6fd2ceb2,3b85cdd2,28bac318,955bdda8,274a1e3a,7afd5db,4bf9857d,2a46622e,896167ba,5154e76f,ce429554,af60f4b5,1431d171,d55ffa2,ea0287ce) +,S(40420900,d81af883,cbf76b47,17025382,802c1479,a33a3cee,bbfacff3,16a1f236,866044e0,dbbcb53b,308f50fa,2b54255c,7831e96e,f19e1b4b,e4168d1b,7b85e3f7) +,S(96a3747b,23b667c7,70ec2018,4e99208e,ec1e3142,3b1156f,8b12f37e,322bdc42,67b0b3c8,df8c4647,3310b04b,ad325d6f,dc7545f4,a4a07af7,98c7cd86,3cf22ab2) +,S(cf07017d,e4037969,24361f0c,b151484b,f1db3e91,a8d16784,5039132b,c8460182,b7a1b107,62f29e30,d0f6e762,f6940638,e2eb60c9,e65ad067,99b1bb39,3797939d) +,S(12b5b8b2,5b0bb6f7,ad1b90de,d75fdd5b,93507aa3,dd7276dc,805cf5a,218beb15,5d3d4767,8cefa19b,80ed6368,d40ca199,5a5bc165,b3609ae,e89b56ed,b78933da) +,S(879b449c,e866e6d9,3998b9ac,e18b6f19,77ecd299,bd9b727d,cd99c37a,13a46765,b0c480eb,758cfb12,acf50c4e,91a8d9e5,f0c45215,f03e6bae,c6c13a83,63781c63) +,S(2ec48783,e9d3a01d,d1fa401d,d3fef249,e502280c,cb36d21d,d2b7b90a,cc7dead,fb029124,78f9e2ca,1a5e6150,5eb469a2,83fd8f81,6798703,ca2f0c7e,85a67fce) +,S(79cca258,27bedb07,39fe8fcd,2145956a,5b7878fb,bd873a83,aee22093,437c3ce7,ff488a93,d82e8750,14cb7c48,3eb74b30,bee990b2,2c1915a8,d3381cea,9cac467e) +,S(c444a4ca,3d2b8b7a,826b9eed,40616aa6,8e146a80,d49a9cd9,3e93cdd5,5adbd207,4d1368a9,63d504c2,541ae338,1ded0684,ac00ad0f,b8fc3231,9d1fc273,92d0f18) +,S(3ee47c50,cc0e44b2,5864e205,835e8d6,dbed328a,60493c26,7ee5529b,cff3e7a8,fa555339,56ea87b,c3249640,145e243c,b6229a30,3d1b91f,84e1ca9e,90a5f095) +,S(e963c987,3036bb7f,422251a2,9f9b0f47,8e69e2d9,2d1920a8,1c012d7d,c809980c,ff95bb0,779bbf2f,1242bfa4,880b173e,140f92d6,c7f8e5e6,18027a3c,55c52fd6) +,S(aaf6075b,b6a1b8b9,afe4b747,a46fa394,23738e50,e686c8bd,3f711cc6,548fc07d,4cdb0aec,6d11ca1c,1e85bd16,2eb411ea,53ab326e,bbdf898b,1bbd5219,aaf2b0cb) +,S(691e4817,d8e9756d,8e174a18,d5d708aa,842b44d5,ea921298,6e4c7585,4157ac0f,9eaeba0b,3bfa7ad7,80d0eb15,72f92873,4bb9a8df,29f508c2,d1ff4076,a0c0c222) +,S(c3e6fdbb,45af4a48,941c9d4c,583dad8c,c77dbfb3,1caf3fd8,1d9e087f,e744996a,ca998d1e,65ab29b8,fee07bfd,1ac4e979,b869474,b5498a73,e642bc9,608366f2) +,S(edbd6320,a55d25cf,21f2630b,e7c5c996,923eadf8,333d386,8cec00b3,940701f,d65192e7,afcef5e4,c88cd12b,fe28f94a,5e3d3d50,f6b2c3e3,f7a14243,4de4889e) +,S(c959ed83,a80ae0b8,ac2fd249,43c37412,b29684ed,9d4d85da,d7cb4c34,ea95d336,80c1dabb,8dccf252,ad8b0e97,25970c1,4de5f58e,12f7e5f,8b59a2e1,a72b168b) +,S(778cc574,471004e9,d88c9022,4d2d5cfa,2c5bc6ed,da64a312,74e3df83,3eed9237,eea23d31,6b2a1c02,7b92e502,db921d9d,675720fe,51cc3609,46b2dc93,92916c17) +,S(a1f87438,8c3656af,43f299f8,1d98d2c0,173e7e46,d3fbed9a,5c2afc96,63b42055,10bc8443,820d6c5,b3150e79,b9936785,5d874afe,dc72a84e,abb987a7,d56f4afc) +,S(c8ad7f0b,2d5f8b8a,cd9a1839,c3d043ee,8f7fa583,7540f6a3,d002091f,68224a5d,3018b580,eebe5b9a,2d1507cf,18a7fe4a,2a1cd4b5,1157dec3,8e65f191,c7aebf8b) +,S(c25d5264,b93fd7b,b7e4e426,1ae767f7,1ecf3840,a2a7ad20,bea810db,4820055f,fa15c8c7,6e3f2b0f,a29fffbc,eb48ed32,bf331aec,3a147524,c349e8e2,465ad684) +,S(d0b972eb,7e4cbfad,baf224dc,cb2d873b,28316877,88b5f2f2,ccc62bf5,e978f92b,ef5d3ca1,606a5852,aafbcb4c,f23e787a,75610b31,8420bf56,e94e420d,f7ab8e3b) +,S(f8b44c83,58564479,6448791a,b98132b6,d393e851,bbc294ab,56c8042b,1b0a2d07,c28242bf,42040be,e9851362,fc8e764e,2dbe0c01,d5bb0ed0,b8e1edfe,e870a27c) +,S(e7cb8901,6f72aade,39410adc,12fd1234,5d942419,51a6d36,8acb7c83,da5666b7,de367522,46b6d9d7,efd4ee6c,53a1656f,f0c87e80,cb0f8f63,95341c35,d6b21697) +,S(8b2128f,14e3f4aa,92e89478,64c5eaf5,f40f93e4,95cce167,fb2c7424,c279d87f,e7ed384a,f469b4b1,1812068,a830303e,699926d5,b8304c11,cbeb0e49,cf5d246) +,S(f34db5db,3cbcd586,38b6a5f3,ab5b31f4,1f3f631d,785e8317,658408f5,93b4afb,dfce7372,bb2c8466,fa31a1c7,4ffc1ac4,5bf11263,4c98ef2d,56e30fd5,c3dd3d9) +,S(c3689e09,a445d685,daca48ea,bca533b9,10b4fee4,dd251c86,a965d5c2,ecaabdb8,7804d05a,6a263fbb,c33efbe4,f4075d1f,d62e187e,3a5917a1,55c1f22f,1679e3f4) +,S(7ff995ec,f776a10d,7a66d62,6095892f,f1e47d4a,2b47ca78,d708a0cb,3f005cbc,edcdc774,5f17e430,cdca4d11,56d08288,e3911d0,e92999f5,cd5c5eac,ca6ea90d) +,S(3662a262,62234bf9,69b18351,2423ebb5,db78bd6,1cfca8e4,1c0253ec,427d4d27,88a62042,f07e69c,f40f671,ccaca36b,d550ef9b,79b4999f,c41cabac,1c2e1b09) +,S(2c127c2e,6d9c42e,970e66ee,24a07388,b6b4ebe9,1614b951,1763b414,3f54e8d1,a4773eb8,dacbadfa,afa26c8f,f4adae30,856be023,6022d93a,aae59c9d,fdd6629) +,S(c420ffa6,116f161f,fd94863a,9fe30b7e,b7dfcb0b,8cf9acb3,7f6d6515,4ac17802,e6cc469c,25c68f6c,8499e9cf,95eda8c1,7fd76d97,2ee8fbc0,79b143b,e50a028c) +,S(77896743,220343dd,58c2f06f,d3217468,34d386a7,e7fc969b,50c77847,eae3de0d,4350d59e,4408dcd9,710bcd7d,629e92a8,cd906759,627921f8,57054a4d,21fd9369) +,S(cf7ea42c,1a14dcb4,3334f9b,636ff0f7,7147688f,19133c83,dc127139,349f5827,b9c02c80,166bf9dd,139c2846,895e4aa6,ad1a689,66460a29,f8e951dd,d99e6d9d) +,S(d1793439,ab1fabdd,ada8ab1b,33c9f96e,417b1c84,7f753630,9d815fa5,a673a91f,ac13d659,3b5941b2,3b19f6f7,f9a67d0f,b429add2,5a40d05f,9bc0d1cf,ced3b3e0) +,S(bb1568d6,727dde70,c52f5863,133dc9e,54722577,4a74026b,e9864f02,9e92b420,b5654756,268d74c6,cc6adf80,ceee29c0,9e137d2b,e15aafe7,b170c95,22af3992) +,S(732912d7,83e8a5a3,a7468177,231ba93f,ce07c42d,778dc205,35cdea7a,db877dcc,d34b8388,1b128d23,e68ffd7c,29c7a945,1664f5d3,fed3dbab,6f78c8e,77df80a2) +,S(c74f0f71,fb8532e8,2c3e1865,1684d3b7,4927b6dd,22504afa,9084688c,7297074c,9da5ea61,c0bd178e,8bfe5a92,dd040c6e,35984bd4,1102806a,53a9f1a7,bd006ac1) +,S(bd4fa939,8bda5a0c,5a4e9e49,43060d9b,1785a613,3c970aac,91fcbc68,9e3283b0,631d4fed,b6614b49,459be1ca,ccbac0d6,e79cfdbb,f14de95c,5d2a5cda,30e433a) +,S(9fa65462,733f13d3,2483e0c8,15cb6bd3,e9bc2d79,7b89ba72,f2465c64,a341cc8f,7051fc5b,afc5b18d,748ada32,c4a27151,443505fc,2f14f130,10fa02e2,6a12db04) +,S(eaea6f7d,ab3dbf1e,816434a9,ddbe53bf,715168fe,2c1ebd4a,6cd40744,c35e31aa,b96962c2,4f202b96,c2080619,ff4ba905,a594b9b0,1f709e6a,76a1a7ab,9784d61d) +,S(b3df7ab6,3b947504,f33e6d5b,7b8e2553,9a117c8a,497f8751,6b97bfc5,3b17a2fc,72df7500,a35ae6ce,d6fa6265,1a759dd,f11f00ea,9152a5b5,ec51bbc4,9d758b9b) +,S(ef875ecc,46da48ae,45619be9,950e294f,4341df09,726417fa,3a8d1ac6,c3281bbf,7ab9e204,af4c05b6,d6d0eb6e,8306c987,51ced2c2,b9e8dbc2,8a642bb3,7f1c72f5) +,S(74c3c446,576a8a3a,5082f234,afca508b,3d748757,4cbf14e7,fc26f36c,70024fdc,73d57916,4ddb6fa8,72dd2afb,f9d8a307,b6ccac9c,94a4eae8,8c4fe8e1,dc136506) +,S(959c4b2c,409f2e3e,6c020493,33ba2f18,c06b7182,5a664e1a,cf33846d,cf39274,17cab35c,7401629f,b73cd398,dc5bedd,d319919f,1a3995d9,45f42f68,2c9aad47) +,S(404f0dd6,94195313,1953b53c,67fdfab7,f67c24bc,92fb4d69,a9479a9b,6c9175fb,857c75e7,f40a48d3,ab156085,1d42b037,7e7d3e79,86efd570,147917bd,f24d87b3) +,S(3e040511,233b0f5a,53df4d5a,b0854137,2db4ecef,170b566,807c4923,6ce82075,f9337271,dd443843,77a35ebf,56753b22,1fda08e0,1b790e02,b9603827,600df3d3) +,S(942ea853,10dfdc3e,1f7993e7,47bdac04,ecc8692b,94847bd3,e044cdf2,2cd77e6e,bbf2f7c8,e688b6e9,b4510bbe,58c41b1d,f33e9afa,5428ce51,e02e624b,9ea155e5) +,S(1e577a74,9883a5fb,85593809,7d0180a1,dce21791,e10b2c0a,3fe6cea1,cd03b532,a147662f,856f5e15,dba53000,7278e878,7b575612,d5dcd790,19417ec3,ac41c003) +,S(ebc9d95a,8a237b64,212e9dfa,607fe4a3,7a05fbfe,7c5594c8,ae472c4f,6ffeaa5a,39406dc0,e311a47c,cf15fb45,8f8b48d3,8fec2fd8,6b4afc05,b1747957,e7f1162a) +,S(c78eaf60,1afdfc20,2123d228,8496189,b9081637,1fb2c475,2773faf0,63cac063,95325b1,e0c22dc5,df6e84c5,16d396f9,bacb42cf,6c1fe9c7,6df83b3f,3eb42de7) +,S(b5918719,a1d504d2,b44a3d0e,117c2798,4f2e536a,3571db8,752685cf,df6d34a0,9b01e8cb,585cb7c8,fa29828a,ac899050,16beacb2,5e62ea35,6d54e9a6,18184abe) +,S(8706a73e,b59fc9d1,92907dfd,cc6f75b6,454f1045,4a5e9584,bdac978e,8e0042cd,8b1b5f56,6f1f78d6,f528405a,2b6a87e8,4265e2dd,1e34c1ce,7109286d,5bdc3a49) +,S(93e9256e,4ddb4bfb,6f4a9289,6e2ad04,793e5642,3a22230a,e645529d,712d6ca,83b242db,d9b3dfec,3640ea62,f0e3989b,d874f247,90a75cd6,9756a8ed,6eafdcea) +,S(2dad49af,8702f39b,cb353956,a1d5601b,a24fffbf,58ab527f,e9ac6ff9,ea2ac295,b5af68b8,e6040762,55c0704e,2cace8c0,ed403611,40dc02fe,2773a625,27e4675b) +,S(5ffc1899,4da42fa4,54962719,5ebe332c,86a2c364,f43b14f7,59710c54,4f6950a0,22eac0a8,79815faa,220e6141,9db053cd,4542ad2f,9ba9f63f,4331ad5,c2c9bb88) +,S(71be09bb,1832a799,c4e21bb8,a2bb5ad0,324c639c,e6e62b6e,69fa60bf,d41c51ba,c5227fc5,719a5b8f,28c40767,b54eb249,950588dc,c15e1656,e4ff238d,54dda472) +,S(4f94305,f92799f0,a64a3cb3,7df2bac4,56d661d6,44568277,bac0ed6,6a587212,4c48691f,bd8683d6,b94ddc7c,ad8d1d7e,6baf796d,6d00f344,511fc13,13c054ab) +,S(55ef868b,6fc2923e,e624fc09,65f61852,b3aeb38c,e2c6b3bc,54b86b3a,60f0ab81,ec198aea,ab16b4cc,5354d0ad,c66051fb,76cff6df,22dc1a0e,72ce6e79,1622efab) +,S(26ad5590,46e19dbf,e60953e,d40a3958,a357f6bc,23642279,cbcc355,74fdab68,af6fc5ef,906721c0,553c6a74,60bc6894,e5bb77e7,4dbc25e2,184fb3f0,fa795508) +,S(739fb43a,b1b07155,39c0b0ae,43901bf2,bc051a69,8ee8d503,84fcc1f0,ec37312a,c1223704,3c882226,2d4abe33,1de6ab4d,ff90d6b8,4c0b59e7,a193e763,6c6b7e28) +,S(2144649d,508cf5da,a7b422f8,22e9125f,d5a10965,a9d32c6c,c299bad4,6616771d,1153178c,e33c445,f03ef96b,35067ceb,76ddeaca,d9ddba1a,74acd229,d01ca76e) +,S(62cc463c,16ee8e8f,16ea8517,5508278d,4d5577e3,556d3580,ec8d90e3,bbb97072,cd294843,e299c500,846a6c91,c913395b,56b48efa,2f9ab3fc,b81863fe,8a6a891e) +,S(1196301,33edf190,d14fdb00,640f74cc,4317e1dd,b9dff1c9,707eac33,53ef9c21,f16ab4e5,e3a3ee6d,74385187,6da07034,caa4f519,6106a0c8,3136d21,5420494c) +,S(b250bf86,3fdaf93f,28f15bae,d9555287,777d4e34,2673c16,2b4a6319,2289adcd,295c05be,de343d28,87d3543f,6b40d5f9,da1e06ef,39fad6f8,28ad5ac1,39b3d2c1) +,S(93a40bbc,ae584739,9f10945a,72c199b1,27ef008,14e87e69,6f4f46f6,483e7c6c,81ed70c0,29809674,f5f289a4,5926864b,f088e2e0,af66173,89fe8cbc,aa858a09) +,S(b9e6761b,4e909d75,b17e76b3,4e9825e0,19ff7ddd,4faa9f90,eff8c0c0,f60978cc,640c1503,5fb91270,8881b70f,bf2c8575,65c75e3b,c98d211b,76279090,7b5aa117) +,S(4dc22812,fe3d9ba4,687e260c,f5b2dc08,ae454751,b022b9be,ebf4360d,10cfec24,9c35ef4a,56858135,552e986d,a4d68056,27f0822e,43031c43,5b2df5f,7f9a90d1) +,S(431276b3,1127f9c2,406b94ba,683d2d3b,e198e225,23663540,9348286c,4c9deadf,2265ed84,c7f1df86,4b46280d,ddc8cbee,c26d39c8,ddd5b743,13938c4a,e01efb3e) +,S(75c5b6c3,c99058f4,2b4b81d7,6cfaa917,328f1736,b8788360,aa810acb,3683632a,549f009f,def17b7f,70a309ef,49a890f1,4a5aaa1b,a80f0464,affdb5c5,a8f719d) +,S(3c900027,205af742,976b1a37,7a4801df,26d4d4e9,12ea757c,815ef99d,cea827d7,e28cff3,37eca7de,2387fa7c,339dab2,7a2446,fe7184c,83c578b1,8649cc0) +,S(5660f31a,3676b95f,9fa8ab0,d5c23f30,c89637bd,3a8ea97f,3a87aeab,3310d9ff,d6069cd6,6bc4ca0a,7d892ff3,e4d9aff3,955bb76c,2ba3f839,efbd786c,b11c568b) +,S(2b8b68a4,1b45dc86,7f7979ce,5b71d778,e6733cd4,79af6f61,8cd786ff,5f3babe9,7c831244,d5441b33,c20923f6,3ad9a093,840f89c4,6c1421ab,40ac52c5,8de4097a) +,S(8635004d,b817bcdc,4b357886,96b3fca0,1d369d4b,303e9290,44229cea,89c18610,2472da40,2bd46e6b,e2f84cc0,5158da1c,7e9f3512,1fc4b00c,4c3ec329,6eb909e2) +,S(6c991a6b,6eeb4f97,9b7afbde,46e1eccd,b0d39d03,dc64fb69,3a56a234,88cb28d0,1e5df74f,c2cd6350,50277188,d3eb4473,e0b753e,4cd41372,2bc119ef,65c95620) +,S(acdac19d,4283cc91,b9698ed7,e92288b8,554569a4,962ffa0c,a52a197e,9f41570c,fa536d87,523c8541,f530c6bf,e71742ba,451d41a6,f97d9afe,ea03a520,c6d7b66e) +,S(b1496ba3,f696cbb9,548b107c,3d28a7cb,85bba7f0,aeb50abb,a3e2a596,465fc6c0,77fb6cd5,727a4a6e,e0fc8f8e,ae807827,487740bb,ff5cc57a,8572ef3d,c86318ad) +,S(3fd97db5,6098e9ca,fccab31,d6d128e6,c2c9f878,adb07ec9,4d854034,d9b09126,1bd77c36,1494e374,fc45127,38b246f7,24e37d4b,27e14a2,2c0401f3,222b4578) +,S(5e8df855,f2a468ed,5476d5c4,409c7cfa,eb174cff,ad793338,8982ae2e,c2aefce9,52e73a82,3bb8ca88,a0977184,38701841,d50da8ec,c46f357a,17eb8cb1,36a6845f) +,S(99f106eb,1417cb69,e95e6fb0,a0fb932c,62021a1d,b940c661,3f814086,c64672bd,9e7fb038,e1e70011,6a926e6,a1c27fe5,e484d843,d184d533,7e9825ff,f7a6501d) +,S(686fc498,5526d87f,fd11d686,4ff0e208,68bb14fd,4a5c71f7,ac43063a,7e51ef8c,1d28f532,d793af85,bc96dd6b,2e0f23fe,4137dc5f,5b3d6244,22f60919,44588e5b) +,S(cfa5df56,cc450bca,914f3a85,b370f864,e4c83600,560bfb20,93df96bc,bff6b83d,cefb9a46,bab7ffc9,1b1d96c7,48f81706,61cf56f0,264e203f,78b05f3b,8d37604b) +,S(991b6b4c,3fbb9693,f7641eed,534e7cbe,8937606a,962a83e8,b39089e4,713e404e,3ffeba6b,be556688,d3b8a0a2,f4b92b8a,98dab79,d5847c71,13bb60ee,be3f8d3e) +,S(d104c5d3,b9b0121c,58a1fa14,f226c513,2955c4e3,56938bcd,6891bb92,13c8c0d7,8c8399a,814d7cfd,32cea21,85c77738,91ddb00,a091196a,3d90d056,b0caa6e9) +,S(76192853,a45c3648,749c9a40,719424eb,415a06f7,c74b31bc,ad93194b,e355dfce,31139287,3cbb5012,d7ebc934,52613c62,b5517b37,91475ecf,84ef3745,324ad2fc) +,S(173304a8,509c1f4,c05b1de5,c51093b2,10c7f9b9,81a7d6c8,8059fb1a,e5070725,43bfbd98,c8e08394,543db2e9,c692297a,800cdc8b,398c13d5,f9e21f89,341d353e) +,S(aca057e1,d28c5514,107f5b6a,9e46fc95,9eaccaa8,b14d4c4,6b7ae515,bda104a,e17f1717,70bd76ff,18095be9,a4b72b8c,cb00e6cd,23f6d702,4dcba433,e6bf6ce8) +,S(fb202550,e0098fb1,c30a7385,900a7dc3,85b2945f,60e6eb04,b7e8489d,3476dbaa,1aaf8420,3f72c68d,bd3bc98c,77f473cf,cedda922,dfc3c996,45e4f565,ef9a0f28) +,S(e95b710c,a0227ab8,e5b66c66,c2958be3,af1aa298,422c501c,8f879bc,e11ae7ac,e645f4e1,ab5cf4b7,da909022,cedd01f8,c745a968,d9ca30a2,c5525d50,9f97cf19) +,S(6db4525c,3589bff9,605cf203,cced45ff,ab136c6c,ce77ea15,14766f3d,e844770a,e6b7f403,f5f7584b,2331d295,82c0698b,799cd7bb,3c59c903,eb5d6848,72658c81) +,S(8893aa9e,49daeae7,15fc2959,e4db9c45,1690438a,6964a2c8,fbe73133,35085eb3,70fbd83e,ae803f3b,6377a4b0,265f62c9,bd15cec5,baec8c10,d01c7094,e5987cdd) +,S(be57f6cf,ac6e8cda,871e3ece,8aa78bc9,2cd9e2c4,8f3adfd5,6e39414d,8e0207a0,78170872,99abf89c,fdcd141d,899aa7ba,8893eedd,36bb3aa1,58120f2b,ee93d5f2) +,S(77fa6d2,85a01129,c5e05ddd,8d02b5d4,a2f69bf4,5a9e7562,6718cb54,20b34925,315bb23c,13a3d218,ce886288,ec0edfeb,37a2da99,e017b97,ce04db45,326455cc) +,S(2fed7bfe,8414dc33,62c834ca,767ffb0e,61094ad,978ddd00,b2ea09b8,d1f4dc03,14e5e8f7,aa0b3d31,565e434f,11c61b,63332a60,b6c4cff2,a6de2c5,98117e01) +,S(9f4c2cd0,5a871ba1,fcb43df2,bf03ee3f,7f8af242,ce8ee6a1,1aeac89,b4d66c6,eb421f52,f2427887,8ff8a2ab,dc384e23,d0fd7df5,fc341acf,83bc5940,be922920) +,S(53c0e0b6,824a04cc,b7203ef6,e37383f0,15f0a48b,bbc1d3ce,7c8fa7ca,5dbea647,6a9b598d,9246ca1a,539729f9,be809397,13c59d5e,105a8e91,836fd3a1,4d618cf9) +,S(dbc0cc82,d7906b84,b6b7bba5,433d68eb,bb20fdbf,7b4eefd5,c0a3ad8a,ad17d714,5ebc1f86,23ff2c3a,6f81b090,4e5e6338,8aee42e2,85306e37,a4fc7676,2dcd7211) +,S(7862af32,a3c08e04,7b1a8cbb,8131d55e,ca93a478,40c52165,af20aa6d,248f5f0b,bb5f6607,6b10353c,8a367a64,587b3bf9,7e8c272e,8da92684,f1efdc33,8bfc15d8) +,S(d3571fc,800158b7,6ed2bad8,15c93b1,f8238fc9,b8753752,4e44c0ca,931049ee,162dc9e8,3e6630aa,9d0872fa,915af449,70a9e6f9,526bf15f,4d26bc74,82a44bc3) +,S(a851c894,cebbc758,642b98e5,5df3584f,b9f531da,88faea26,e908b0b7,88589d9b,74702d5c,adfac1ef,71df3898,3ae433ad,1e1af1f9,b5fae0e1,151258e3,b375b422) +,S(a92e43f4,12effaa,e0978a08,cdb2e885,2d9af1f9,1f0931e,972016ce,da58012d,d8f5a09d,5560170e,b35d7bd1,28252096,535c687b,23bc13c6,bb903b95,d02fb668) +,S(75cafe44,8b4369c8,42e658c6,4760ecda,bb29e129,d283c24c,9007fb5,f3cff6bb,ca0e12e2,43c73553,1e2affab,51d4738a,db1ea5a2,fba215f5,3c9477b1,b55dc39) +,S(ab0066,4db959ec,2f17a233,78023b5a,c48c4177,7b6e6b56,a2148453,8c41d006,8cf9e2fc,35545169,f46762fb,940758ad,e3d3387d,eb72e9b7,b5d37175,9f5d8b31) +,S(27510ef8,2e4b2134,180855bf,469d1f0,f89b9afd,573f2781,4a1bea50,9db7ecb7,20fe00e8,86b54c06,1fe07355,5be99fd3,b0a1b20c,dec68aeb,90055c34,acfb87e1) +,S(773ff5a8,d388277b,7921405c,99c9c207,f4a6c2ee,3b59ac1d,7452c8ca,4db16d3a,cf45e631,f51cc65b,afc806bd,87318e3a,f75caf,3e734284,8d7435be,f8a52f8e) +,S(2f8f2c98,e69ebfc3,b7277e35,9da1a8ef,4293fc37,2e24386f,e14cc455,1ef45746,f85d23ec,c4dcaba0,23c3e406,604aaae8,8150a6c8,feea2c36,42ccad40,9968ec06) +,S(1878acda,ab8dd0e2,a0884952,26356ce5,74575678,64da41c0,61a83de9,6277f67f,412c868d,64e092c,ade96f05,bfa48af3,ecbcc128,e6d09bb,9684565a,d5477020) +,S(8cf281a,eac4e4e2,7ec4f3cd,d1373f62,c5a17b0f,49cf69c4,cad8c4bc,4f5618c1,2f17f995,29c9ea27,cda3911e,de33029a,7dbf09db,64ffa625,cd9fd86f,29ed5973) +,S(3a597c9f,f165369e,5d90d191,3dc2aefe,a0957936,717f1ec3,9ea20698,d08939f9,8c2203b2,90c9a2de,5b464b0,988e07,a7b48c86,f5891926,da462b4e,b00a14d4) +,S(cbe3205,96f10ff,5de9c861,55290393,b9ceec90,bbac68ac,5054facb,950ca15e,446cb06a,b76aba12,c32b4855,716001cb,9bf7c72c,ade16bd0,5472b947,4fee27f4) +,S(4313c9cf,8224e70,18413b09,e6544731,1cde7100,5ee60bd5,3a8db041,56fed594,dfaf359d,d3045a8c,b181021f,9a025208,e80bbd4,abc4a331,7ab9d735,1b329a96) +,S(cead2b51,f8d8adec,2d89651b,2da5ffa5,1f5cbfab,19fb7688,2bdf0faa,bf73c60e,ab2a2480,6992f0e8,c73e7932,2bf144ae,6dd3bda7,ed2d221b,f8451ca4,56a25897) +,S(9ce75c8d,848762f,645164b8,45ee6eee,98e34dad,9f8be0e5,2d8f27ae,4a7b79a0,e0556d4f,e11ba906,6b97c04c,8b742a26,9f627559,b9163571,d0a29dbc,9aa30a05) +,S(6024489c,621de255,f92106bf,8c23847b,10214b83,1d653a9,6ba00889,326741d7,950eb24,80a90200,ec932621,6b82e5e,abf63e08,6626faa9,b1fd8e2e,104ea858) +,S(d3c746f0,108f6bcd,406c2638,c07255fd,1f55e1a3,c6845e11,546d22ed,5f08e51d,d124dbe5,d349c739,e641a776,c57ef3db,35ed4e1a,6ffc165e,25d0bcce,438dfab6) +,S(a1eb5f5c,d85dc222,f97b9e11,e08594dd,a69c69f9,bcfa4c63,52cf2717,136514b8,46ed3d35,a393e017,76247ddd,7dda3ba0,ff5e3f76,30253b68,750a7c,f8a15fff) +,S(2b24a357,fa3ac2cb,faa5f1c6,1c14147c,e4406556,b82c7639,721f7561,485a8736,d67219bd,707aad55,1a8fd7ae,d5721d45,ad192a5f,5d0b643c,18330cd,1bd73ade) +,S(9901a1ab,9dc60159,63cc9cfb,42ecb41a,ab6a623e,62e9f306,126a4f6c,fd87b2ec,8f766594,17cd7f2,fff7a3df,6cb414e7,eb5950c1,ee265730,633ccd8f,f0339317) +,S(311e8445,5890e2f1,e1d8e600,37d58c83,28a2a4e1,b21c3763,4aeb9965,8477e8da,cf593f67,6cc75762,a1b0dd00,f6703bc1,e017e927,1e61c829,a0459056,ecce030c) +,S(905f72e3,97140f6e,298ad8b8,c8faf66f,122d27e4,6fee88b3,67a8ecc7,9e83bb77,c03f155d,bde9c265,d90b94fc,1b5b253a,2d98528a,a12e19b4,698714a6,f1b65257) +,S(61df77a5,d5940001,2fcc2f02,199cbb4c,39eafd33,27dc85e,4a3f55b,a339350c,27c88b7d,de9b3f,73b0603f,2d6e40f5,f3664020,8d6dc05f,684626a2,d9049161) +,S(e1f8e199,886d4b1d,5dd6af90,6eec06c7,de36dd4,ef026129,5bc42bac,5df18c28,502c12e9,b956eaf1,2865bc4b,ae7e6348,56a98db5,4c65a5e2,9ecf8ab7,51ca45a8) +,S(ade2f5b8,3804a21c,7dfe6a7,7044cf96,9180e154,79a4aac1,9b686076,fbb8565a,d0d65e1d,7c8168c,308985d6,f5d267e5,98a9e6f6,45715eee,3751bc26,ef066aca) +,S(c55820bb,154f972,ac345dd5,c62880b8,9f7f6b85,a1755b88,ea5821de,6f268187,911b0fea,1e6ca659,263b698c,8a17488d,4dc35f5a,d817e7a2,1241e56b,cc613086) +,S(ea20966e,321020f4,53964352,b8ccc2d2,1285888c,152ddd08,9f7039c6,6c7778b5,c942f591,cdc81e52,6abdc9bd,643429c1,66f5476c,dde18d39,59e29f26,9f4fc18c) +,S(3c57552d,9c2dfe5a,67301bbd,3e1ef84a,220c908a,8e80c707,9f9f4df4,607e2bf5,d49fa0ff,bc4a6397,3e71a0a1,7265ff65,6fd34754,ed508522,b9f0200b,e71f39e3) +,S(f188ccc6,e1043ec0,59e8e133,94ada165,a3fd5c0b,cf7f071f,eb5a0951,9bd4e1c3,5f1f371f,e53e79d0,2d6fb190,8207649b,db045c41,a2fe1cf,94486053,7bfdbe4) +,S(a0145fd2,7e72232e,8055a146,aa7bfb49,447112a2,d1ca53ca,d4835e42,c11c8c6a,7bc018a0,e5e70ccc,c4bb675,f0709cb0,ceb874bf,22c7ecc5,243e49c,3de679cc) +,S(53400de8,c221153,1fb85706,b558185,c17b7bd8,b17416bd,9c93df80,f16ff48e,e1228e47,3ba565f1,e50840b6,a36ea970,2df87320,8a66a44c,89cd33da,41a6cc6f) +,S(82115d2d,9d37e3,50ce3482,1d59af85,cc8960b4,52b99904,8c6c6674,ce64b1ac,98deaa09,659a0c24,4aadab0,3b9d1881,bffc1b3d,e9226f05,e75fb9ef,b61eb048) +,S(273d8c18,53d86f1c,c49e6e9d,450dce26,8669cb7c,3083968,1fc17894,59fe7c3c,6c5531aa,8ad026c8,174c25a2,51efbadb,14974e1f,7f7f88af,2e16d101,c2ea00) +,S(616e16,a7e38191,70e33f4f,bf428fcc,41e68ccb,5b059bfe,4036751b,ba5ee319,7dbcad21,182a3efd,b99173f5,cca99374,7c7dc3c7,3e8af2ea,ba84b0e4,f506748a) +,S(6761896a,76a39812,1f773402,d033f210,dc566610,275f6774,52c37c01,60b82812,7fdd01cf,1b40939f,8091184c,8e2c8ce5,11848df1,a23607eb,e760782e,67302c9b) +,S(77f7abaa,e97605da,12535bd9,e177b6b0,bd6eb020,92345fe6,dd4a6d4f,89e508b9,fb04996c,cc7b830d,fcf5fd19,bb7c9332,dbf20fa,10d61231,889e4b65,cc7f0b9e) +,S(c12f6717,3a2e2bba,3da97378,501f9cf1,bc4b4a8a,67b0c5a4,a0d8caa3,98bce311,de930986,44d31401,510012aa,3b6cb541,97cd133,6e583853,a330319f,779a47a8) +,S(6553a2de,19c7552c,8db9d268,ddf3a034,4afe8ffa,a76bb304,ee77ef95,c18e66aa,91a72010,7c180bb7,2af4dbb7,752d374d,69f95bce,c9bbb7f5,37377060,70edb93c) +,S(f54b4be,353f4185,22e2e936,3400caa9,bba98023,e6a3d3ee,c1fc5046,b7b834e3,96be786c,bdd5f1f0,a835afde,219745ab,ab6f78b4,577d3a5,1246437c,8e96f17e) +,S(c2d317c2,a0fa6522,bbc806e,45b4dc8b,f86be37c,4b677c64,c0d5b4b4,eadbb2a,c5710969,bd68cabb,718cb16d,fc9994a7,100f078d,4a3aeaf5,8e8eb35e,d313ab6a) +,S(52a567c6,a5b8a64f,dc74b9c9,57f5d472,cc43e143,4136fcce,fe1ff313,1b89f384,332631bf,a314298a,dd45f7d6,b8192956,d7de27e9,7d835d48,5c16f7a2,9c9e8f53) +,S(f7dc086c,891a4412,88543527,831247bd,3530f0f1,99b4c5e9,8d24a207,1dba4e20,734ed712,452e59ae,b0ef5f75,10485860,da055003,ff1067e7,b82de345,b74444aa) +,S(954f9fa9,7bb6dbc0,cbed8d8c,de6f8f75,b3f2ae51,e512cd3e,90520d8b,22ec06c6,b65b43bb,8bd9660f,4bdb3017,bb4f8214,5426f614,8f04378b,f65c39db,185dd9bb) +,S(20e69b98,41416588,20b66947,f775cd96,6def2dbe,416b545e,8188db14,2604e87e,e6514659,bd12b9b,35ae45a3,d43f6023,dcce04d,87df1f51,caa67f89,28632539) +,S(5cde5b82,2dc42f04,44187fb5,33029577,71bed484,2ab39dc3,709e7c57,c72ed1c,a0f7bad8,64e405b5,94416e7,53fd6137,cea3dcbe,7625fe41,b4929299,a9a0ea9f) +,S(b586cb4c,6ba6b0dc,2aafd03f,49d4d6e8,45b20460,5de71c34,6e73b131,fb26421f,ced613e7,c26ea3b2,a31de623,506afb86,6767b469,98bb116d,2b4ac9ab,58948744) +,S(7d3f6170,35803a82,c8e13dbf,a8d601c5,4e192a54,377e4a8b,2a2a5de6,90ba6ede,138e810e,62f413c2,fb56477,80c0bcbd,77eaf84b,e78e900f,1969f4d5,2ec6cb15) +,S(e7a314be,fc4af863,e7fe6713,5304ab81,c9fa32dd,80fa9b41,d8577ec2,8f7eb925,cd978600,f0e04acf,fa99b6d0,7da970c1,13ec94ce,c50808fb,91a44f4,80f3eb1f) +,S(179c3be4,9f41902e,e21cd8e8,10f0dfc8,ba5fc0ad,9e454231,ec090263,d3c6a577,75f9f60e,fb9b9aa0,29eb03f5,a50b7e4e,64021689,a4e889dc,5b9ff0cb,4c9cf184) +,S(10a55871,464bc182,b957808e,25754fa5,8d76269,5cf8c6f,e50610b0,91e6401f,d36493b9,6d2bda2c,e305c679,f906ba9e,99a787f2,aa8cb8b3,29516a3,41b56ff4) +,S(4a903722,5e858c84,15508d45,b31ec7f6,585827a2,f3a9c99f,96af3e9a,e88e555e,da4d45a7,fb9e44d0,cc52463f,20fcde14,31c9a477,d02c464c,70c7d132,3247d145) +,S(6d109d8c,2505808f,7b4052d6,b170ec80,c68373bb,e02f2b62,1cd29773,a96acb3e,c8dea0de,511f6e40,5141088e,cb023bff,200c870b,9cb952ad,c5038b28,eadc9a57) +,S(9c219898,6d202467,c055c734,73557505,6105b3e,2874dbf2,8f7f0c39,66e1af88,8637496c,8eddff12,f9dd4146,36565e0f,efddf5cd,52d48455,ec9fb2d,8dd0914a) +#endif +#if WINDOW_G > 13 +,S(22ca5039,e660f60,1036dd75,2bb973b,dcd104b5,dcb8f2e7,4de8edc6,c292b03a,86fd4471,1ef6b81e,4416449a,708fa0c9,cb6731ba,c403e58e,da5e915f,646b11e8) +,S(cfc18f02,cc004640,f2116fdd,1f6ca202,2e39be25,df75e27c,80bde842,e6b6f938,d62b58df,4f79d0e5,97ba2923,f708cbe5,c09236a4,d9d01398,6451d684,6290df7d) +,S(3388bcc2,3425458e,991f46ca,6235c50a,57490556,becbaf25,9d3c14f9,9a80a087,7d4aa2f8,6f65783,1c22316,6958fbf3,6c3dca5,d4ac413b,3102e13e,a645c016) +,S(d26bd013,1b8c12de,3dd8fefc,136d9f95,44ac963d,4cbcbaa8,2ba941e,f0b46a19,66f89ea3,31b6795c,6b694872,4cab492a,d045a7d,a6780653,cb10ac25,b68d3a99) +,S(dcd3370c,db67e8f2,163960ed,fef5f66b,465a03d4,d447f5ca,1d99d29e,57d1fdb9,8b93747a,320abf87,2cf8d448,393bf732,8a9eb4bd,9b64ded9,922616a7,347084ef) +,S(74074d05,e602ad56,337105af,59c63819,21d449bb,3fe0806f,80589f3f,4f8d8e7a,1a4d4bd4,adee80ad,44fd515,a1dd5236,bf0dd8f6,c44782cf,e19b8414,b03d574d) +,S(a89cc81,f3a23ebb,6a8df438,a78092a9,97120394,d6bb4dd,732373a8,2f05c174,4b6f83dd,676df063,4e5ddc9f,db979dec,326a9ce7,5707fd77,873a9644,a3c4fda4) +,S(8f1a10ba,fa913f0e,1902ae36,b07f964a,6443c540,b60ace03,7dda380f,6616424c,1028d644,45c177c3,24416ad4,e740f31d,14e3a462,d5a0326e,86998555,5de5525f) +,S(ad8fda79,14f9a236,a7957268,ada499ad,9154a2f8,478fa6d6,f4c74048,89e27b51,9ca1d2ab,1f7da6c6,f76deffc,5c3c933,703b74f0,26063834,6174e4be,320e82ae) +,S(6c6e990a,797b2970,4408cc24,6f238e2f,2192700f,e4fb3c87,4d15e32c,fd67fbe7,1ffc1798,f355659,9fa5b32c,c040da31,39811b87,93d4d9e1,be83061a,3f91dac1) +,S(202b13ea,31ad2abd,9635351d,e09f237b,9f86f75c,a340a47c,edc1f9a3,25118969,c52fb505,a14e37f4,d5111184,ebc81873,868a4521,700004c0,fe3cc535,181bcba0) +,S(5355f0a1,25142fa,b0dc7c7c,f9855953,34053c6,12326f5f,d2284291,d7b748a5,75bbe36a,553501f6,c1c8ff9d,e60ee3ef,9cddd36a,781c518f,4b1ccf17,7e281949) +,S(b8852d78,eacbdec9,d1cf1664,4a83aec2,79a39ab1,34706235,f913aeac,c29829d7,763bab50,52b3c61f,ae42735d,2e89ec3b,8d51eed0,f729e0fa,eb431613,df183156) +,S(cab2e44b,294df78e,1c17d4d6,a09ecd0d,696d18e8,b0f188b,eecced5b,7057ae2,f351b09a,501a499a,ced49607,c55b506e,de28bfad,5b20ed5,4059a068,19ff2f43) +,S(1400b9c9,9c6d555a,2bd2355e,b54b756b,b16f9f36,b9b86658,9d46853c,57056b31,8b290816,62f41167,a0a6993b,3d4211df,5709b91f,96f24436,e569c32a,dfa077a8) +,S(52ae372e,973e9c1c,687ae7a9,a111446b,b3d31b19,5588d8a5,fbec6e6,bfd9141e,f982b40d,e6d0e42d,b9638721,a4590db4,1f87cfcc,d8ece56b,71ebfe0d,82351ccb) +,S(3d14ffbd,40824625,be241e14,850dc030,1139b708,b937f2e0,fe5f65db,61899c24,b10a64fa,477ee047,4d9cf16b,8d2213a2,799882ef,d3766872,981fc761,88a1dfb7) +,S(c6f52adf,54e0c197,a8bbc270,d4c987b,e7ab3fd1,a95fe46e,82415ecd,baa48930,7524c06f,b53873b4,9050281c,99fa44b,b9ef9193,2adeba8f,77e5afd9,3856811d) +,S(90089264,bdc47cb6,7a3c838a,4c79c1c0,5f2d1dd8,6d18f55,9fe60a3e,c944c1aa,18963846,d70b3226,6a9d582c,c430e4b6,ca140bcb,91de7064,eea0fb39,d2ee04de) +,S(e27c24ea,478b37c1,6275b2d4,ce8212a5,2db74166,96f3c6eb,c1bf7091,efda0662,27ec5279,c3a267cb,fad532bb,5031791b,bb99f4da,fc3b7b7d,8537cf09,12783de3) +,S(ca5daa12,9cf1d6eb,70025d85,7955d3bf,2549b8ee,6064092b,917eff84,c40a3eb2,682d4905,500f6f7d,33e7c7c2,7d420b4b,7c4aa5f2,77b89e9e,f6a84259,de7a9811) +,S(9069ec0f,2b2ac688,46623fb5,c89d1424,6c98ac5b,4250c170,4871699e,fc877f55,cc500ec4,eff83712,16c0617e,e2407dfe,a6c3c3a8,c8b80266,975d3a56,e71fb05e) +,S(5fe1feeb,bd5ee1b,6ba742d3,c5e8aba0,536393c,592650f,b8cb1391,c3bda16c,db11b327,1ac64ed,3425ba06,8072f76f,ea02ae6a,4375daf5,3bf942b7,9865a34b) +,S(a4a91a5,f168f883,49035b6c,f90e4e0a,6bf2602a,85e0ccb8,31866c4a,ac1b2c34,5bfeea8,fe36ed1d,18af2ff8,e2b898aa,ff7265a9,c08f4857,ce082030,7f837596) +,S(f4135f36,f0c35b52,4a870505,4eaabe4d,43f5366e,d3c7d9e3,5f06f746,fa884849,1c6707f1,b8b6c078,b4d9d0ea,43075d75,ba1a5d30,c3a9c52d,d55fc4b2,650c526b) +,S(d5a8998a,9363fbae,d2b44992,883e84b8,14a504d,92b41e0f,dcc3a9f3,94380203,96016b03,6fddc805,8bb8ae7c,6d46cd7f,2f20c5af,a62abd4b,bf9b3da,ea60e9fb) +,S(8804ca34,4b30dbd,a07fb62,210c1938,d50297e7,9910dfa8,cc38b9be,4bf3d176,5b64bee5,79927c63,7788c55f,f3871631,eb65db50,b11cac91,24caede7,57d37b0d) +,S(8691c1fc,440c21b6,bc48e78e,78bda5a5,c947c74,7d098e74,ac5dbf6,2b811021,fd8ec1c5,35f51181,556c330a,f02a7110,682f4539,f66c1c09,3d48bca,d7b1787e) +,S(445fc1f6,343be2e1,fdebfe3f,894e9293,c3ee5fab,b0ed01eb,58a40637,ef093229,857f17fe,6737f853,d04aa1b7,3eded13b,c3c087f3,48da90af,32907bdb,7d85b605) +,S(5c397fde,a657d1b0,b2e3aaf9,5b88c4d6,af1a5555,a1dcf966,7d1c5001,a76493b4,9ce74820,7b6f3c75,2d736aee,6a9fc54f,ce5cb52c,f487fd32,de79a06f,df0aff0a) +,S(9b5565cb,28d7e028,361d2bc5,bdfe1912,d9f53584,372d30c1,d7e36fa4,c7fc1b7e,7d5cfa8d,2de2a832,58a57f05,4e3f6c6d,a23af075,d98b062d,82799b11,63879eea) +,S(afbdec63,1bbf870d,3971b165,71bb195a,a5229a9f,1012bb4b,89654da3,c9194f1d,cfcba749,b9492525,f9874ad1,bbb0a267,83fe5714,1f54316a,773c2453,8f27e296) +,S(7712abcb,ca3a5347,5cbc6160,5e9e9ec7,a7cc11c6,2c4b3f4d,e01d688,acad916b,7b91c9bc,eb12555,ad2b43af,8c3bd332,b57cbbfd,1ffefead,c68f0a2,6a4b82fb) +,S(3c452346,f2935e41,2e5fe506,fdf5066b,11b43a11,66e75c9f,7a2d38b,1ca2b7e2,fd3f6de1,27f96829,3af532f8,d4811fd9,e02038a,352b6696,2c608c7f,f59cd800) +,S(bd8582f,b4dbda3f,c7da53d6,70c994b8,e04eda44,ddf0b054,7d182db0,aa48b7be,799e2769,c18268bb,8c16b282,ee7d0828,ef0dc4b7,9767033a,d6de8c63,45285c68) +,S(c41010a7,8dd9dd40,62bfb71c,1691338f,befe03ea,d99eb719,74dce6cf,b2c84112,5008c39d,e71ebc22,3b1c5dbc,f824a63c,f270f807,3143e08d,29b162da,42a2ff83) +,S(e89e807e,6cf4ba27,6586a6,a509bc8f,f786bc5d,dedb5f4a,1b6253cc,2521d311,aadecb79,7c4948de,9379fcfc,4c040029,2228f9c1,c099117a,ad6d9949,f2fea2cc) +,S(363df1b3,be2dbf90,64137919,51218c34,84091f73,866f3fdb,dca1b90f,dcb08577,aefd04e,5634e36c,49621493,f7e76f20,f9ea5b64,6309a605,7e3bdf0f,75848bae) +,S(5c8d1638,83d2824e,48121322,85cc44bb,ca8fe33a,34d5c3be,cd4a3c8b,c78ea16e,f66f91d9,c7ce66c0,89500591,49f7525a,355347df,8f31a685,872aebae,1ac0456f) +,S(10ac6676,83583ed,d837789e,ed9254da,4181dd58,be75dff4,8085e87,eacbe126,6d3eaade,23f3e7bb,7465acb,c6b25af,72e0dba0,1815ea1a,1f57ebe,bb17d22d) +,S(1e79a1ea,7bb65540,44567796,2208ea3e,974c4c0f,9b61f7da,8dba697a,8c153048,b63e3d79,20a34888,68987406,4a8008eb,e07d35be,33a055dd,394ef2a5,f0787fc4) +,S(db0d1c73,97b0a23f,508df2ab,b00ff13e,11699118,11d6476a,7bebcd09,53fa9a5b,1c9d0877,3ca74f1e,d1972431,2b5c8eef,2f85fd41,6629cdc9,d0b9e328,4900dfe8) +,S(e1fdd7b3,481ece8d,266bdc22,92e775bf,96904223,e620f622,3a03ed,cb385f27,3cfab39f,28953ff7,d6dee65,83fdc6a7,d9b31f93,e2103e6d,9e4066a,970a4c77) +,S(96797134,2b69bb8f,3d6701c9,22130c8f,9ed85fe5,bf189880,3b2df11a,a223ffd3,2d43343f,630b6f9f,7c4b6d93,cd29a3e6,632c0dc6,c095794e,5997e47,e631d31) +,S(dfb40218,6e27d494,c69d2a0f,399dd480,ec0a776d,9a99fba8,cba81417,d9c33efc,332d91dc,e9f93273,15e45bcb,79603050,9bd8501c,17820f48,61f7b12b,5d37796e) +,S(6b65c5eb,ed13dca4,51608da7,b5c1a331,171de004,7fbe35e5,189b8468,c27681ec,afd0ee8,e0aebc0b,2f246b51,f6fd4f85,3e71fc4d,f5bb9f43,e2679c8e,89a34f62) +,S(bc1c3da1,60b03965,e26396aa,5d426df3,21e5c22,fdfcd004,80a390f5,28c4b619,fd657174,65e4fea9,ad7862c,422c11b,86ad94cd,35acbbc8,76ed464,aca31640) +,S(589b1d17,96d6ca35,53f8a6a8,cbc587e1,9026406,c2c6f8e2,de613dfa,8c05913a,e655d5ec,ac254f46,e279365d,e3bba2a4,3c7b6469,da45ec87,9742cbae,503fb3e0) +,S(9e726385,6d1e6c2a,94dc2ef5,c92d94bd,6ada63cf,cea75677,6125bf98,78ae4ed5,8c238df5,1e5b38f8,b628a48e,dc7aa2b,a83bc40,43c91896,69f5341,60e304dd) +,S(12269d78,14e0f74f,ba40c551,b2080e00,4f9bd3af,255218d5,7eab5dbd,c6764263,f0f70bd,6584975c,106febcd,bbd16920,daee58c7,c22dda70,4a95f864,e385b3d6) +,S(d3212f2f,cc509014,e0c48cdd,6273effc,5c73fdbf,1676faa3,15e9173b,573088a6,39af39f1,673f51f,362618c8,49c6934c,ff59b6ea,853fafc0,9db64084,4832df82) +,S(c535f72b,9bcc0bad,44014e72,4f649623,4ef288fd,9f42adcc,dae45a20,84250052,3f79985b,6fb7631b,62814a17,f7ce829a,88447302,293000a7,4655c7ee,4a271022) +,S(4f5b7126,9b169fa5,8602bb18,60ed0df7,271e3912,ec0d7c12,1c80fad3,93399605,b60fc104,7f2a58ea,9102c6cd,b97c932a,576f63f2,6204fb5,dbe41363,cdcfd0a7) +,S(cb459b3b,244c38b1,af2c2863,e0029c14,ec70e7d,737a7851,de9c8f1b,b7d5d065,7b67b15d,3c0376c8,2f646241,1e890b3a,a888bd15,692c90ea,53a74a4f,1957fbd0) +,S(787d61c7,ebde0c5,18f121bb,7f434196,d389f563,d1a46597,ea72a1fa,4e19054e,5baf56f2,5fcf8cb8,c271cf39,6b3d150b,f42e9ebb,d72b54ba,4b93bcbe,ae72a658) +,S(c38afc2a,31d0b0c9,4b77d97c,bd639082,3373538a,602352ba,cc93b6eb,c5f6115c,b925dfca,b138fcc2,4b9a26a4,c645f8d5,875e098b,d2e58469,d842688,43ee529f) +,S(37661e3b,8e606e95,b9dc6ad5,e5b9b25f,39a5dd0b,8ab7a82a,d6ec879a,ff406d0a,ab735e5d,430d8fce,1317e07b,d6cf9441,60d8bc39,132382a4,df1b1638,a7e9b977) +,S(e5127851,b8c22b47,c3d8e934,8dc0c677,88ea5ad9,f64e6062,abd68a16,51e256ba,5847f77e,349eb7,90b4b7dc,5537ffa,5b1e7d4d,b87044b3,f947f387,270405c6) +,S(f3c7f45d,a6b8a8a1,3713e7cb,7380fe06,127a3698,520bb41,955647b9,ad7382e9,2acf9a11,eb1b9d31,f71decd0,90093677,4b469301,719d4a51,ddfe5fbd,f63e7c87) +,S(86de4047,e8d5b252,523733a1,848a990a,79125f95,3bb0e4de,ff4b2f0,84d745ba,71e6a472,dac005d,2b284cf7,d5de92d3,56921105,1a9ee007,4279a746,71bc969a) +,S(c6115c30,72259d66,d960cd96,3f3aa16a,3029d9ca,c0c5ec63,5e2875c2,f3f57504,18d690d0,b33fdd78,d797f56c,23c821a1,ced02401,3443c770,50d12850,9f7a712f) +,S(cb545099,8b43473b,91838cbd,76929b05,8bfae0f1,e2bfbc6a,c61d3674,42f53c5b,4119d74d,79e34f08,cd7684b4,f9b9df55,c00ba8ba,7bfb4ddf,de38db78,91572bbf) +,S(d0dce704,b9362bb4,fb1771e2,660a98a2,a333b73,c6d09372,5a752f28,52922d2a,f92c3b70,7947ce0d,f1f3891a,259cc2ee,124d3f54,a4c518ff,de5a3915,96e37e47) +,S(db93e238,e5aa5986,38eab857,655cc53,d4270259,e7d73a96,249a19bf,216b20a4,8d19dc8b,670e8eb6,50b4f60c,d26ef657,3ab17895,c62fc94c,815d7eb5,fbbcc7c5) +,S(c387c37f,d8cebef8,29e07e54,b0796129,4d6c6cfc,bbf11835,ba85d4ef,68c3f486,852580d9,ae7eb300,6ca0f7d7,f12d7fe7,c8e3ae0d,b6258897,994fe78e,11ddeda9) +,S(ebb58d34,f04de551,37c01b5b,192bb4b6,4d3b22dd,23ad9092,f943749c,7606c232,1b979d05,9c99f9d4,db1d3e82,905abc9b,d92ae72c,509c912b,c59488fc,ddd1ae16) +,S(7891cc66,acfda29b,765810b1,730cad13,2f13178a,fbf238d8,2525ce42,96e38e6b,22193729,20188c6c,462987ad,7ecaec3,a21ff6e7,db00adb9,72facf65,367caaf1) +,S(c0b02542,e4bc1e8d,2c2578a5,3793fd8c,acec800,c0a311f4,72c50de3,5814d081,24bdc71,f5917c0,1ae6bb5,71c09197,76b1a884,ebffd673,13698bc1,b57f8371) +,S(ea15d574,b8704507,f12fd9a3,e40ea603,c2000cf4,4eb3d4b2,f07a36b5,c426d2dd,b6596d4f,4d8ca39f,4e0faf58,ab7e3894,c5cdc16c,589a524b,6ca25a51,8a30944e) +,S(77d387df,c35a6af7,b88d5726,a249d34e,70877698,1358c672,6e51b779,cf9604de,e5daeecd,2d70a962,d2d3c235,14fa2b1d,45916506,de017249,93fcd9a4,f08b4a87) +,S(a92742cb,7d1a24fb,c1a4dc2f,9d6fefbb,1064f9d4,c3152db8,3296a9dc,9dccd7ec,665a9cf9,8cdaf0a4,ec346df6,823f3c6,66d4f163,b3e7225a,d9d18e42,31679f76) +,S(253e54f7,9f0c393d,5d34053d,37b55304,f62de9da,29e0eb6f,36cb105f,a6316a46,54e168cd,ed78ec0c,32a9417a,c5b27ef0,67c8577f,8fe0bfd7,b2ae33eb,ce7155e0) +,S(d13048e0,e9c38720,6179586f,9e38029a,55fc01c7,b33d8443,4ee45cc0,3fbf2,7c4466db,94502477,85490689,7b251c39,af257840,b9bc61e3,64075080,84743f37) +,S(e9234110,387c2122,2887d079,7bdbc9aa,a632b237,2a5632c8,8e604653,70a284a2,2b98b08c,4ca3521b,4ffb3afe,66f98ed9,839a2651,f740f63a,e80b0cfb,6f6523c4) +,S(302e03a7,ab6978ef,73891a5a,7bb25764,7428341c,94f8a713,32ba9dad,83a29be5,4abe0adb,210c35be,b2ee850d,2e56bb3f,e8430db,644082ee,a98a2f83,5710120b) +,S(53701389,44400f30,dca0571e,eb0f8c7a,4fea8bdc,31d68859,8d7cd156,11665368,ca345664,39c1f221,a5731bbe,5a9a36e1,a712e2db,f16a6d19,71b1a74f,eaa97cbe) +,S(8c0e8186,645d7cb8,fad2b6f7,a5a2d399,656aaadd,5423cff4,9579529a,f28383cd,2ef275ea,14c44981,9307319d,18fbb482,63c6d24e,c94e18ff,cdcd7757,4c48d27f) +,S(64a70831,26baa3c9,a11615c4,5ff8ca99,adddc512,c697901d,afc43d7a,5fad8af5,ba43c48b,59a65f6a,c3a45c35,4bb17968,148efe4a,288f742c,43253e70,aafe29d5) +,S(fdbd066e,82ff8e24,b2f785e2,e166245f,63559acf,b4f56680,51db47aa,5d438e06,60dadcf,a19ed8c2,376a5d38,28b9499e,875731d5,b2417def,144e2a84,12973d63) +,S(b287ccb8,1ff90731,19ddba01,d9461512,82cf15cf,2dcb3e0a,f1b26f41,eead174f,6ff15339,7a9a0bee,4b38a463,5db66ed2,36d1beab,c0039bd1,acfbdc09,fb74e090) +,S(18047a48,b65234a4,fa5f2188,8b3032fb,3b3f8457,1bdec3c,962d5cd7,fd068116,13627669,18198832,306c5444,6cea5681,80134209,101a117b,1f34e15a,624574b) +,S(f1d3b54f,be4e2ce5,88a2dd32,8a41e136,6b74ffe9,5bd4aaae,ce7e7a8,235f914,37c25d41,300e817e,b4ae1471,e8486232,c0c21165,97efe33b,e86d6277,a8a3981a) +,S(9b0da9e9,5046dfab,7ff509a6,10ad56d,9770da36,c5e22a83,9ce3a36d,853bec4a,27d60345,30c25a36,e80bbc3f,f43829cf,df757c19,1a2924d9,6da77503,38135faa) +,S(d0833bd9,5155d18b,be55d40,3717568e,2d3e4d24,f2eb65f9,f13d8d65,d899c5cc,e509aec3,b5044ab5,11fb1e4c,56db7146,ffeefb82,ec4e9de1,3c473bc9,964741e8) +,S(8c41627c,185f17e4,28a01b40,27980e6b,ed62ad62,17c9f8a6,26c329e2,2fc37117,75ca226c,3316a552,37e8a1e7,483f73ee,a36da441,c732dca7,7d95b7b9,3a3662f7) +,S(371f0105,e43aaa30,5cc7099e,9a13b97c,2d75c26e,5b50b11e,7cc6283b,27728d27,c969dbe7,d0976d68,8cc64312,4538ead,b1194426,cedf149b,293b80c,6ab3ce99) +,S(5102f59a,4238a358,f8b4d3a1,85d864c2,d94aeb83,7a8f3e03,541ffbdc,2ccb1710,9e14c4f9,adb63c3f,4cd30606,cd41cabd,bbffdc3,89e996ce,91522093,85ef1445) +,S(ca21b6c,fd40403c,78353c7,836162f0,a7f57eaf,bd4a8cc2,6df2baa7,1ff08beb,108a3c46,47eba55b,3fd9f2ef,751edb0f,d6b68482,1424bffe,e6ae3e58,1f7f12f9) +,S(d9cd44b3,ff40d19c,e8368bc8,200e3dc9,7ec3642c,acc40769,7c94e68a,31d775d9,b6b6fb6c,683ef701,d4cf7101,79de4af,fd7c4a1b,5babf3cb,85c95eb,485f0901) +,S(9a1354b2,cbcb6888,bb564426,71bd4904,510da508,3fcc61e1,4fbdf44,15a10360,3f5f5291,707c48b4,4da3a2a8,93e24037,bc4927f3,81dd9b9b,710e8b82,874f953a) +,S(c5e55e0f,271a81c4,ae7deb0b,ceb0fdbe,20fc60c5,38692941,bd50ab9d,ad0fdf79,138a0f35,eab49301,7a53e7c,c62ae93a,85ed9e7d,708a00ae,cb10776f,fdc83a63) +,S(5ebc2f64,7f66bd3d,2290e4dc,6cc5f662,7c67ea72,599d2c6,9a004aed,9060f919,68f7dbce,df2085e2,27cf7920,65369637,3ec1e860,b10c8f1e,56e996d6,854659c) +,S(4f28eb9c,7d060dd0,5051a5a7,9a79c960,161d7081,d3a58b2d,a421075c,cf966e03,ec378861,5434741,bb2aeb8e,4a2afe78,44849f3d,2cf12a6c,2eff3e05,d267fafc) +,S(f50e20d1,ce113e09,850c7a9a,10b347c9,9fa039ee,57ec85c0,efe15b4a,1a83fe8f,4db7c231,90df41a2,8218595f,61407f20,cee46478,27d54aa9,4db9bfc3,fae975be) +,S(cce6b2d0,1adeab95,dd78cdf2,b55882bc,79de945c,d4249e76,ab2841a3,abeff5ef,1d690674,1312140a,fdf764bb,560b1bd5,bab1dbaf,9fa26bd5,604427e5,34626e52) +,S(55a65174,fb10557d,2ecc7312,15afcec1,e4830be5,2d34bbbf,bc80ed6e,9f2d8475,c69795f1,de1e537a,970dd412,65493806,3f0623d4,e7353eec,611c8917,278012c0) +,S(78221cfa,7b4db3dc,7e22779e,97ac8d46,d0c1d819,76594ab0,267ed28a,6127f290,8ddcd5ed,fd8e8c62,4883a158,2eab5652,ace0660c,2e358b66,3ad53e90,cbc46a54) +,S(9b985039,441ee434,ed4da39d,6010782c,9006cce2,8f92ff96,2b2d6fa,986ed178,e1cf85c8,7b537b2b,78bf67d2,2d9388c2,8a50dae1,73f003bb,85fe5f9c,12c6cfa4) +,S(9aa2ffb1,4a9e48de,57db9d78,d9b6757a,6c27e7b0,291dc4f3,8ae9f204,f7edf20,771c7be3,78e0f794,fe0066ef,8592952d,8f80d7d5,2772ca11,5ff8b7f6,377d1040) +,S(d1059083,66a0b463,17c510cb,40922a0c,949de251,6d80ec02,1e359a89,c6937e1f,84053a25,c9ea4414,a897155c,c45e0da,e5e6f2f,aec780ac,99c41545,fac8630e) +,S(1f3ecacf,7456984a,fedc2d81,2a81f7f,1ac58ad9,c70ba7c2,3e7a2ff1,f9c5d066,c6add8fa,2bfd24f1,73f4539e,f21681f8,15f1f362,e0f98d94,cd435d80,71a23e54) +,S(a312c709,a16d0cad,25551ece,86c8f947,5e504d06,eb3524fe,569cdca0,da2c4371,865ecc2a,ea04c5da,2089ea2c,66b5bb84,8c1fc29,ac7bf969,c778039,b3ae7b03) +,S(f21c4675,e829ba78,fbcf6410,9c2eed38,8c3493db,1017d69d,953f32f6,744197af,fd2c673e,43377caf,5db0ee06,1a37b03d,43d9373,482d3ef2,b37f74ad,98b2f57) +,S(116174ea,2a029a02,fbcb2eb6,1851ab31,f4836933,a73bd426,8feed7c0,18865692,2123d027,e1cead9d,b5fca2a2,d6f5d1d5,25cf3855,44b64352,ee772d4d,d70aaefd) +,S(358e77d0,919e4c6c,f64a2117,357e72d6,2334fcd0,f5e7e60a,962335fa,73f9d663,7ef8d620,6f99f403,10781985,988ac7cf,dcf5cdaf,a086a0cb,8b5b6eb6,7837bc08) +,S(509f7e0d,9e81f146,39157e20,3165faac,8056deb3,a813460d,b86c6daa,baa33fa9,55148e1a,340eb6c4,e6a8645f,93f1ad3b,fd12165f,c3bff090,a095b8d2,a0db6ea9) +,S(358e325c,185f0e26,1e9e30c4,9346f21c,a15c95bd,438020b9,ad9c7e6a,d2a4ed09,5fcc074,c97715b2,812ef690,3b3d6185,54aa11bd,34789b3d,97f9b65f,2d18c4b8) +,S(1e1c712d,bc00af2d,37f37e4e,a2589e02,e314c310,47890d26,8d36be3,dda2fc4c,4898f9a,e3136bbe,36798cf5,ad30b38b,974e7e75,42d4c14,5bfb1f6a,490655dc) +,S(a6516f9a,aa3f79b0,ff3b794d,c80a9590,64e31720,7361b918,bd797b57,23ffcd1d,c5934c6b,59f3b830,53f77b07,47c7c312,812373dc,ebdbcf9b,ed550300,3a54f5d4) +,S(e46b48d8,8b1e1b84,b9fab824,3044469,50cb5633,da599b79,295011b8,b1098155,43e9ba24,4a339976,e342e551,25974350,3e7c8a80,cd950a80,a5d79365,b0c94f51) +,S(ca7a5099,97a9c2e0,625105b,1df9e714,e1cc2d40,1227400,e583370d,3f65aa0b,dd8ca4e4,d2eecd1a,20d994fc,ef7cb0ef,19c61844,cd2ce039,b7a1eafe,66e1f071) +,S(326b5ec0,d29b576f,111352d4,b7786c40,8486599e,ec01ed0d,a390d586,96313f08,f4a3f171,a4ac654b,e7aa6063,3d5b2a0d,c2d5d3a0,3da4d264,95e828a8,1011d384) +,S(b762982,54f5c75a,a557038d,bfe9bad9,7c5bf8ee,e512fe2b,39293228,e70d306d,8b808f9f,b36e3e86,2c75bb2d,d7de8be,cc85c75,398496fb,f92db3db,143606c5) +,S(8bd624e1,2b1d36ff,dde50a09,6f1a811b,ae66f1a5,790654f5,ef79a21b,872286ca,6687ea2e,f4538961,b6731c74,744234af,8bf6a2a2,170544d0,fe9b8057,ad1f02df) +,S(ed25eac7,2a9f9290,bd414cc,cf846c65,509d1c33,d5573da4,2d78d25d,5de48a9,556fa9ed,2710fd03,b6d1583c,682cd7bd,8705a9d0,1f73a8b9,8f3a1eb5,d89eaa) +,S(f1943b6c,9ed76a84,9c67bc94,c755fb30,e8facc1,de280060,df4b9e7,8bc02bf,98c7ba08,85dc4e0f,6acbb646,42cb876f,a3156232,df1f84b0,4818ca56,882a40a7) +,S(c5b60b14,2de3ab8f,b0c24276,dcedae7b,83422821,6ac8ef39,1d351832,a5e9e5d3,ce86e4da,1174e609,f55e10d9,14d4a5e,33259578,e07c1260,e912acdf,9eb5cd69) +,S(b06638e,706cfe63,3359647b,253f99e1,c7778200,c168d4f5,92e2c409,493755ab,e6401fab,1b4d5229,136e2493,39f95357,e16dd37b,87e7f69d,3e88a383,cb44bbd5) +,S(cef8c1b5,486dacfd,29650ea5,432fa563,f0ec5fe4,6814bcd8,9f539b7d,264b14cf,80cc2c1,8d0b0be3,939ea,761d7281,5ed4fd2a,b252d66c,9316aac1,1a5a2fcf) +,S(f616904d,f868f2a1,5fcdccac,4198b1c1,62defb40,269754f3,8e546da2,4b85d7ce,fb971012,344024c9,f0bb93e0,b73b31cf,de8b4d37,aaeae3e4,7f62633a,7b8255b3) +,S(97386144,bc7e4a7b,33a51697,902fef4d,1613d8e5,ed80a599,a59f62c3,f98632e3,bd12d584,58429939,2dd834a9,5431af27,8e56065,ba79bb6a,5a806d36,cfc16b4) +,S(946f130c,7a70fa00,f403a56f,6656b279,1eb08ddc,561311b,551ce437,bb0200c8,acd698f6,a5037e60,7f5a923f,3af05784,186d9794,a7bf7105,7a66949,e1945b8d) +,S(ee0cf184,72c453b0,c38c064,fc0d2589,d5f1afc3,3423687d,91740bdc,c3929230,d817775a,7fecd397,e954db12,fca24990,8c773c28,b36e991f,79c78264,9fff8dc8) +,S(f335f7fe,9542a587,9d48b4f,4ab1287f,ef007289,4d93bc21,23463a77,7d535d7b,336e49a3,2465d29,35389c06,d8eafb4d,7639dae9,a6b19bf7,45518502,e3350283) +,S(55bf8179,4fb37f8d,dcc200d7,b76a9040,b1326d6c,559d7f06,f0eb0e0f,c97e7739,ca33cf00,79155cc1,e902ade6,f7d703ed,3053f6a4,f49d0866,32e930a2,afe69bfc) +,S(dffccf81,6143da46,5ee2195f,abb6d943,1033b901,2fe0c623,49b7d6f6,29de29b0,9bfdf3f6,e1dc4ae7,dc29fc06,f85e1588,c04bc39d,5fded90b,bfe75b9c,74f0aff7) +,S(b9748c94,25fc6fa2,fe5c1395,b556bb12,c435bc11,2e8f577f,3c5e7d82,3539dec3,f5238bb2,b995d23b,5e96b233,6d5141ec,f76d31bc,63aa96e3,dfaca8a8,c94007a2) +,S(92c43c54,e951b157,38f29e33,5f52ad9a,2c5349e5,fa6a39a3,fb615878,ae97f7ca,7c7a6b73,dedd1bca,308924fc,6364b62a,bdc4ae79,d68a62bf,71bb0195,612b4a17) +,S(b1937ea,25995e55,ee1ef139,d7a58923,5677afe9,f4726d96,40b66b0,d21eb272,d0f95a57,544ac7cf,e6c3e0ca,5e44494c,5585c503,a8ea9919,5a993180,cf043dd6) +,S(2c1cd64d,bd7ee24b,2bc5a6b7,2009b788,e2a5047a,8d10dfc9,4a46d807,c133f457,fe8a63df,ce7d7a4b,e7c31a1f,5e68826,7a9449fa,9e9ce30c,fd8684b7,660aabe3) +,S(4ff10a78,be6ea8a2,b6830649,b0a403d6,6d544368,6cc854ed,447f53fc,45004834,b3cb30c3,56d50596,2e81cf5b,f4e2db0d,e43384d7,28f5d8bd,b362d287,e58765d8) +,S(33f55b66,6c90665a,b60a7c2a,c714591,f877e8c8,517344d,9da03558,f43d28de,399848ab,6aa95ed5,8ae0ea80,c93931a2,af146754,385edce0,8c2a4f64,2d5163f6) +,S(b9712359,5a7237eb,18b7cc15,ff2d6be,408da66d,5885a636,20887ab,340d3e04,a283a3bd,643ac5a4,1b3f0ab8,fc693146,dd125f88,fa87cead,817788b3,be72363a) +,S(d20f9067,6efa9435,f602c1e9,fff7338f,5a4204a5,4d984dcc,f0ba5fc1,60a1035b,ac3a3c7a,452003f8,7244406c,ea315175,ca1af26f,6645486f,3faae77b,8f404139) +,S(322d6ea3,157c9f0d,444b2d0b,d072e192,81d8b3e0,3ee2ef5,4e294b53,fef41f2d,838147f1,9dc12dde,676a9e67,6a638c42,6e096df6,ea62ba97,ec359b4d,f92936b3) +,S(95925c08,68341b6,b7564ea7,bae00b0d,1d2bfacb,94aae4cf,8f29ed9e,fa0c26d5,c63edb9,13152232,c255557b,2207c2ec,edf14cfc,bdd246d0,2b46f7f8,76b92130) +,S(7592aab5,d43618dd,a13fba71,e3993cd7,517a712d,3da49664,c06ee1bd,3d1f70af,554ee877,af74284d,5ac0aef1,ccfa8ab2,7a9222ae,977a1b45,7d79d386,16eaa410) +,S(ed9d298b,e13eb71f,8631ad31,1b391680,8062574a,6053f503,671d9a59,1209e0eb,97a9abc0,dab8886d,9a07caa3,f40d87d,7b479efc,d500eb6f,e54ba1b8,9d85c3cb) +,S(cdfef636,a5900bc3,bd28daf3,308d469b,78ae69a2,ffc39fcb,9f8e4942,fa355fad,f8338fcc,54c0ef4e,a46a1c25,591607aa,f4f6c7c5,378f2d51,79f80e46,520db6d7) +,S(f638cf22,ca3bd6a,ca7a8fc4,26d9f5db,dbc0943d,6a587584,8ca52e6a,7949db49,56a267dd,8309eab7,90b49003,9d595141,653a7926,9fd1f732,f3691e0a,41675295) +,S(4340fef2,9b1e43f5,3c76cab,163920b3,7a66163a,bc942e1e,6387a2b1,8f14bd1c,2d5a782d,6889d353,c6c908f0,b6f7a9dd,59ff2f15,8bbb9eb6,ad62bc2b,832210a0) +,S(78af8680,5e3db13,cd2c01f,beeb826c,1aa83296,c6ed1a30,bf2822f1,a9b80991,19c7ca36,37a6ce91,2680d95b,6b94f835,ec458cdd,86206a2a,49d41af6,248c3725) +,S(d87e590f,e6a4bef7,54a831c0,13b3d561,72064279,38b96d49,58a2ae11,c9c41ef4,3928a93a,c9b43489,f1fff97f,f8ed4ebf,53b97aa1,b50896b3,e30b40b9,be1d1dc6) +,S(b59d19f3,69c547e9,4155cfd0,a0b9076e,85ea8569,195b8a7f,630a8446,ddc54c32,b8f5588a,ffe7abe0,e2b83d55,28162c5f,2d50827e,c44a4357,f81ff085,da661865) +,S(34f643da,7cd59b00,3aa64cd,81c143ab,662726bd,5eaf543a,6d83d30c,60f3ee78,41574cf2,91a7f573,5a0bd29b,3ee5a36,91906c1e,3fa47b22,d5204446,f4501ee8) +,S(56ef37d0,583e9de4,33f78757,dc31c968,fd007bf5,6b05db4e,cac395d6,233dbbf3,a140e01a,b5c898f9,10ae2807,53ba14ea,ba8cb5df,b9e9629a,92c14b9a,df5c9286) +,S(1e43f34,815b568b,1139ca5c,b3a5dd42,fc54dd76,78454fc8,7e3dd00a,edc957d7,5cc38274,ac96ee20,78a82d9e,64dc2bdc,8e947afa,d043302c,85d724f7,7e334cc8) +,S(ce79e49,35d2db7c,d9a9046d,3d81b7dd,f8b06c82,98f78eab,ad93062f,c339a952,fc2f6eee,1b90626a,5ad8c494,3bc3cf5b,8765c8f5,fdc05dc7,fffa08a1,b84f9686) +,S(b4144804,ca862c26,70cc3365,e1a00cf8,f6766cc3,4b3dce2c,76c40c31,86fe4fd9,e4368a1f,ca9b6e00,a3f752f0,3a00fd4,29cbdaab,5e2a04b8,7175b9ad,51b2219c) +,S(eaa29724,7406f824,8e79cf65,ced49d39,5416341e,c1bc46a7,b71d422,1f4fd39f,68e7f81b,e3b75cc3,de4d9932,85e21842,d0d4b6cf,38a1d46,248dd28b,a97c14a6) +,S(4e2d10ff,1f7288bc,3b8c6caa,3dcbfc72,eb7371c9,f42c6999,e7a2ec50,30f5b6a5,68da3c5c,df2a4fb0,a93515ca,3e417d00,6ba793f5,eb678f82,be88200f,a5a8774) +,S(834f21e1,114dec96,2a8a4b45,c67c2894,7d073b94,457c1adc,e009dda2,230659f1,e9fa61b6,edb5a0a0,2f7acb27,d04a67c3,39263adb,6320ca6e,f78ac7fb,25adc89c) +,S(a84b44ac,a0a64455,a97268d7,cd3d68fd,c43caed9,f9bdc381,ece7139e,30c7d0c7,2f903f3b,74e702bb,d2fbde43,f919af7b,d1267879,3882cd6d,a05af259,bbf6b74) +,S(21219e06,98bcb977,47b1df66,f9e0fa6e,600cbe7c,bb432cbd,d413481f,241d6789,7a4388d3,c8961874,a897d968,8b5d3266,2e6970be,324bb736,aefd1892,70954055) +,S(fa514e1f,93bfccf6,88b4bbdb,e4f49879,7b946549,82a27562,6867b22f,9baeafd4,ccd48215,52572b4a,9e087b51,8c930e09,2c2f6156,c26a730a,478f257d,a4f91b74) +,S(b60afbf1,643099f0,c0533a4a,99bd8c2d,2204d4f5,3f2fdffa,4cafa02c,79451ffb,fed8f90,1a029926,cd4b3bd2,76bda6e9,d321e006,3eef3f43,886eef8b,4b21294b) +,S(f29cf9a3,196ce34a,86efcca6,554694e8,17c2b765,39c6cdef,c74850e8,a7ed76cd,5130863a,f7c333cf,b37f1bf6,2db5bacc,994b2977,9951e8f6,2471129f,88c9c5f7) +,S(9cd9e23a,cb00bfc5,1a3af34b,3e23f1d,d8fe314a,322254ed,563b9275,c5084e4d,ecf0235c,c66ea710,151d6c1a,17b31705,4f31bd4c,f8d2a77d,4d36fc4e,1298e1d5) +,S(56f889b0,2cfa048a,f96d99a6,be56a282,18ed6691,ab2b25bf,f3d3b6f5,f6e5d65c,352b20ea,4a2372af,f674f824,8dc8fca1,bb8ecc29,ea0c8d92,1b7ea07b,241fe4bc) +,S(de32beb7,f8fad8fc,16d69a7d,d3def556,8e2366e5,246bfdea,16c936ab,5dff2a08,d731f11c,93a71c22,46c2bd06,fe265fab,eaa216cc,b0de1acb,a7c004d4,249e145f) +,S(85ec7dc1,dc1729d8,c03dfa58,fefaacdb,7d12dc3a,f984a693,968895e,2a6ba256,523038af,8e9aabcb,f98c73b5,afba31dd,89e4b9f2,ba1a841b,194b0b45,9a4a747c) +,S(f7948995,60528ec1,ed7f5efe,42db8bf6,e223280e,2b26d4ab,e23a5caf,41e2e141,9f7594e2,96ed1f98,86837e9f,da8d6d9e,58871e56,16cdd2fc,dd6fcb7b,80c6ff98) +,S(588d6fd3,b4208825,3d76e8ee,f01a93be,866bd53a,e228c137,62199ce0,f3454f10,a5fc9653,3e41208b,ba3f29ad,e31b7e32,6320b81,ad0ded2c,6d922a4b,b42af573) +,S(186fe08d,bbe5c8a7,56f87d4e,8976777b,b01db294,e834659c,bf423de,1ccc7443,d99ded39,a46f7820,3437a93a,435fd0ca,29f12e26,a6449bdc,a256f99e,9bdfbdc0) +,S(e549cb08,3055abf3,3b7eac38,cee13336,2af22e98,2f576bb,5a06d5de,59bd3d25,cdf37f20,e7b51483,6641c7f7,afc35ae5,5ababde4,34a945fd,4fe0325c,7d332381) +,S(a4e42afb,fd7f5158,5c86108f,cfe84b58,b930df79,f53a86e1,8ac93389,224422b,e9f8e1b,3963102,b58d6177,f915d7ac,541e551c,bbea3e2f,1ea47960,ce1e30) +,S(5f7ed844,42022f42,6b09e9cf,b7750fa4,4755fba9,7199fd4e,d09efdca,d803dadb,91d5ded,d06a8eb0,9c9592fc,c9096f1c,e852d9c3,9bfcdadd,ccbe1bdd,2b76ffad) +,S(3fac4743,32f064e1,b33fa22,3f67bd15,91dcf7f9,afa38f1,868e180e,c2938d66,45744e67,6b203799,3386d10a,b11730bb,eebf270f,9ea65920,6f93da61,e2aabe5c) +,S(5fb983ff,f058d214,2e4d13df,97d8e784,d4b10e0f,6a18c6b1,90e64bdf,fb7a7aa9,33394601,8dc540cd,eb73f73,a9733d74,ec581181,8a6d58e8,3460f1a6,8ddabd6f) +,S(baf35c3,fa939a2,db15eec1,ab083664,9c6e941e,19d3e0e0,43e0f5e6,df41f88a,42583cd3,e53fa1bc,4eebdc3f,e3b8b069,9de41445,54fed966,214108d2,f68e9201) +,S(97641f5a,a51e7ff0,f1d86183,a3fb3d60,4266c4d9,acdb9f9a,c704a05,809a8602,134ffa32,aa9fbdbe,d8d82fc9,1cfa78f,1ab169fd,459da39b,5b0d3287,ad9517dd) +,S(96a3711e,acdaf6dc,5adaa8fb,4be05c37,f59febca,1a876a5e,e23c6b55,2727292e,8fb0cfb9,681ebb7b,5e1fce0e,67ad5d81,34be9123,56100e96,b82ecd3f,a5da4392) +,S(ae64428b,8e540c6d,28d38892,6136320a,9f9f16b0,3e9d5e2a,14faadef,4f154b0a,db202e5e,b9bf73cd,b9ed5193,b0ff59e7,cc68aded,6fe6c2e4,d5b79493,fc118aeb) +,S(2c5932df,65c0c2c1,14b532cf,15b48433,e16424ff,ba87438d,42229075,6cc984fb,161ef8c4,b908a056,d395deec,38b9ff4d,1c643628,2ceb1e47,f59a2c24,c7d29130) +,S(76e21c78,6937ba69,18252d56,3ebfcbfe,2415389d,bc692071,f9c48f55,7aecca3e,de7786fe,9db47d61,e3b61d0d,49309fe9,ca634d28,8d71aa77,a3fa4efd,4533c8e6) +,S(7170dcef,ca8a138d,1d20b346,6afc6a46,99df363,fc964a36,eaa70805,b267900f,196bfd39,476f1455,98f89f7b,f870f8f8,440562e4,623fb203,3b36d5d,d8c0bb8d) +,S(98eddeb0,75bdd245,aa1fb466,ed1e89f7,61a95662,e35836f2,e6907c5b,691b6ccd,af3fb5f6,b59124b8,c9c2ddc2,108a3a2c,bdbcdc99,ab296814,731a841f,570c91be) +,S(bf42f806,59ae606f,a5e36fc5,c58379c1,8dd1c34e,fa98e67,68bf6da8,ba8e8849,d343fb70,6e4adb94,46f49578,26bae8c4,ca74a0d1,21cee98f,26be68f8,7555b8af) +,S(40c1c4a5,891e8dc6,29075c36,56249fc2,c42fd65c,8c338a0,d82df955,4662e1cd,667223d0,e68ef6c3,7195d819,2bcc12b3,f2025327,3a05703a,e5aa10e9,cc689ec3) +,S(162dd310,c8e3fe4,8384cf1b,1a0a2d6f,bfd3ef3c,5492fc92,b921133e,8f883dc1,1f2311d5,c82f02b9,f7197685,cf490e1c,3d0ebf4e,86ea0e21,a653c8e0,db5cff0) +,S(ff0f8146,89eaae3c,f3f302e5,1089ec58,5d63c4fd,5157bb3d,bdfc7e40,cc6331cb,4dc1fdb9,4eb529e3,bae54973,778d1daa,f8814cdf,5a3b0c2d,ac2b5647,551bf2e) +,S(143ae674,b011b557,2f472b22,44c6d9ab,14b3e641,54f4a033,c3ea3917,4607b78e,1528d582,faefba2,6018820c,a03dfd7,ca20298a,e199c99f,db9cb421,3601c35c) +,S(f3adce28,8fffd45f,96fa0efd,32974d98,4115a80e,cd6b86f3,5e17b017,8d9009a3,20202f00,96329bb0,69a0915e,494a586b,805580a4,eabd4ba7,2d20665b,4916a20e) +,S(d2270829,e2730d0e,2c8e6bc6,fa4c2247,4904ad22,f44fb2f8,5ad07558,c4d8cccf,d5a6b4ac,9d5bf669,5989741d,f262e412,27c66c7a,ae067a93,c6302f5e,8879a3bc) +,S(26d17eb6,7d9bf2a8,45c57a94,82bb2f3d,8347538a,65c9f567,56ecadf4,352964a6,954af3d4,7d67c345,bcfc4a52,a49aa70,b8703d1a,fcd21c6b,7f7719c1,e2068fb2) +,S(e4437f8b,e104c899,5cd1618c,e5ee7d10,36a52d99,31346476,bf68f21,e7fac74b,d6c156d5,b8256e6c,1a820dbe,3b56fc8c,f9b015bd,b81c756e,27b70db8,d995cb81) +,S(8932e04e,96db6079,662b63ed,29b5a39d,ac5bb51c,d1ec70,851474ef,a2d3c1d4,5437e77f,e030225d,53f5166,8c3551c9,fc912a0d,a3bd336e,c0587544,77e58541) +,S(fe776976,465b86c0,5b2003c7,36c8141c,933ed0e4,5c6dfd0,c7c82517,16617b26,b279dc5f,d576d506,d302b0af,359ddd50,94364d3e,255102aa,472e6d9c,c52aac39) +,S(6c60a4ff,b2a29224,5c84ecbe,1633817d,f69eb73c,a6b9f72c,b86fc91c,535b45f1,278dee6f,814bcc1c,70301a51,f9c7853,6489af2b,d23d6223,1b55cd29,2a2a0a2c) +,S(3132e58f,625f902a,98d556c5,ec9e8617,a955beb4,6e9c2a81,e121e473,9c9af04d,a5880964,a2443c5e,14db9220,446904c5,cf0a957c,945c5006,9438d869,45a9e461) +,S(b05cee36,361a9bf6,eb9003fd,c8d38587,640e180a,9de822dc,57e5012e,34903f6f,fb473886,29519a28,b745ce16,d625d85d,26fe21a2,30d798c5,305d8e82,545c9a5a) +,S(e202120f,5659e580,7a14e68d,e3aad7cc,23cd2f6c,abd86739,3a05f16,12005e83,49928b05,b66af992,d937cb4d,c05fbaf2,a70e8fac,7c081544,849d55e,fada136) +,S(57a91d89,2e5409e0,b07e68f0,450614cb,9a9bf0cd,8c5b3459,2f198633,c7a796b,47905cce,59018fa8,baa612c3,124b1192,1dbf7706,c5d8d16b,bd5c1e9f,8498e7fc) +,S(e092c40a,3ba465c2,d59e7c5,8265ddde,91c0468d,67428ee1,dd153b64,a5a7e8da,83f4e2b4,bdfc4248,2d4ab1d3,13b097f7,baa51411,134eb042,feb26f71,5bffd39b) +,S(73a3306e,7baa4fc4,a081a9c2,c335d3df,7c1ee84f,f5a46554,f78a6009,1de0ab38,1f68c8f9,2022c326,e37a7043,9552191a,3d93f684,3af0a235,bce893d,eda1f938) +,S(7c7a79f8,6e904961,73552caf,4a1401db,e99883c5,a39e493a,6a6eabbe,5f3a4434,85ceb252,e4883931,96c8ce8a,c0b596cc,a2670981,2c293554,15e17f8e,26e869bb) +,S(6a9df561,ce4ff772,b37054fa,e513657f,19f03086,eda93918,623a1c47,84a37788,bcf0274a,d9b3bf58,331ba398,a6611fed,fe719867,106eadb4,2b25b623,fdb65280) +,S(fe7bb24d,47b3adff,1c545d2d,ad2c6aff,81934cb5,bf2299ee,f3f8c53b,ff91c950,7fe65f86,9d2623c,930c27d6,f0a292cf,a881738b,4af0c5b,efde5c40,8a574e7f) +,S(26d1d2f2,7944b77c,290ba60e,17d05347,82ce2b64,ae815453,1da42907,30407d3d,ec3c5024,3106000b,d0b2372,53581384,51b768d1,d5aa206f,4d1055b4,b4f0f495) +,S(f00e51f9,38f91573,4ac563ff,8ea44de3,fb85cf4d,8f034806,e6c096d,8e73e2b8,7b7bffed,3a39a491,d3ab6a13,6fd88e0a,5854081d,21380c70,3c596771,a22c727b) +,S(73e15472,f42f8750,93abe811,a4d4bca8,8bd179d1,4e3e3b30,9e011e27,37cfc4d8,392ef4ae,58321768,1106426c,9b00b4a9,c53c826b,84bcda34,b5d0609,f85b9231) +,S(ed4667a9,aff30464,c851d86e,479df8e4,d29d2348,edaf8333,a7faf560,a9568092,77367875,6892d42d,469a9ab5,ff577e0,6d9f4fda,679882e4,3dadc7e6,3d49bb0c) +,S(d6ec16ab,10811cbd,dcc346a2,64dbfe0f,51066f2c,79034d74,af5b0ef2,541dde26,981f1cab,7ac7be22,9a91b733,6c0b89bf,4763b01e,4a1b715e,f4857e9e,4ad0527e) +,S(284ef47e,691931ac,8241d92d,2ee5b717,3f762ef2,bd1f48e6,8dca4b53,ab4c593f,ab739ee1,e6a7be47,83e1288,7ffe1b6b,b53a4d2e,3bfad3e1,c7ac5415,1bcf5e82) +,S(530f9e7,5a267d0a,fc3ba53a,c49018ef,44b490bc,835774f6,c6cc3f87,8d505c3,630c481e,44e5e9cb,cf6d7fba,8f7fded4,bee9fa70,4b88a8d3,6e2b3bc3,4e85e3f1) +,S(66a9b4fd,81d0165b,6737a4b3,8025d2da,ef9c4d20,3c49a2bc,1ba4d59c,eaa905f8,2770c44e,6a4dead9,7dd7311c,195d3051,12c86bca,257955f1,21b7b1cd,4e525e8c) +,S(25812e7e,dca47b64,9b18d739,7474de25,39bb7898,96ddb94f,60192135,23a289be,4bba3d83,72aa76e,6ba76f7f,18cb8644,788d3ab8,b58d0e5c,795c6213,6f17e2da) +,S(3c81be70,af162448,170f88b5,8fbf587e,df1a0e8a,3576cfd7,24acba77,dfb29608,ab16e48e,da59f480,7a0b5250,7102e9ba,ed9dc9fa,e0de8700,27bd5ff4,2aee13d4) +,S(ab626dcd,a5142933,ece82c8d,125aada8,39626e90,85c57525,2fb24f76,e0d6e39d,8add774b,34fa4b1b,d571f2a3,4d8ebfc2,bb7be73d,dab73cf,e7eedc01,764abff6) +,S(47f25106,120720ff,8cad6532,1a3e2873,aaaaed57,98e3933d,e1ccfe0b,f36bd85d,f6d472e,729512e4,ecb74ea3,f96583ac,cb44e013,ecd0bc60,c38b16f9,20585b60) +,S(6fd30299,f7398f1b,3c538d59,71b8bb0,e1640926,752d0842,36148b9f,23c26b1b,3b8d6166,a79ce235,1a2e9c4d,c5c89ff5,7810bef0,277f3d33,372e05bb,ba6799da) +,S(dd5b07c,784e1cd6,58c51ab7,45c4a09d,49db1287,dd7871e3,f449bd66,4a02e040,b26dad8a,62a491b8,dcced2a7,c0feed9b,6a04597c,d8a0f857,a4731078,d68d8659) +,S(3cf5836,104b4227,aa275e5f,16b84bca,15b61a8a,700b56b7,dff2adf2,167fcdad,1cc6f65a,2cb579fd,f6812340,88018dc9,445af726,2db43b5c,e9e49e4a,ce00c9fb) +,S(683b5455,8b9421c,c3aea163,d74c043d,d4cd804d,23857f41,3e01d28d,4919bb58,1bbe4576,2cd5c056,8add6943,8111cfed,691e2369,55022da,17cfddbe,79a11f0a) +,S(d78661b7,897a40dc,5f42f7ec,4202ae53,e83ff0e0,d73ce7d2,19503279,e43b724c,465299b0,e3f478ec,fc3db82a,61d5f290,aeead2fe,d0ec4a02,6652b29d,cad20b21) +,S(1258c664,fc15e794,e64dbb87,b4eebf1b,32e89e7d,50ec114a,1afa5506,19e15a21,327c4a92,81a73880,70d1a7de,c2a0e5c7,28c5997,bbc21571,94b0521a,141be0b1) +,S(f2d04fb5,1cffe2bd,c6e43cdf,ae7314c5,387f4dd2,4bf7fbb1,a6ccd627,86e8be00,89af3f8d,435f2152,8d32ee47,a86a2ae1,78d3a7da,c27ceb37,93250a8c,27061c9e) +,S(b67bbec1,4ab23ad8,e52cc402,def0083b,d21551a1,92a9df6b,b335481e,3f0dfb08,d6ca6bd1,93838993,5284528,56587554,3757cc13,fee01fe6,698b30f8,10a64a23) +,S(1baef1b9,fa401fd6,a053ce90,f2d661b8,8a466584,83a8489d,90d48312,2b79235e,28a19a14,a2f7817d,922b3872,cba558ad,bc1a69c6,c0b65ee8,3352494,a31699d7) +,S(6c0f066b,23623a48,b2b6a746,801baa85,f58de56c,e5287c79,c3c10ff1,b851aa8e,ec837256,84cb0f8,e528bd94,e1c86327,2347a479,2059f357,4ccdbb93,15ff0868) +,S(fbd5bb09,65bb9d22,bea6d6cb,7aebcf28,a0c815d6,18b79c0d,94913dd9,f63619d7,3303574d,5e605e5b,fe298f77,e20f3f6c,60ccc063,37a29c7e,6612dfca,3f00b924) +,S(2246042a,c4b22334,af6c81ac,8106bd1a,f8bd5f2,8dad88fe,7e568fa0,b35b1739,1da0d8eb,9c10116f,ce29bd9,61f92e36,9e538282,345a4f79,7cdabc70,5aff6e7c) +,S(470a914f,2fff2d37,835b3caf,542cf50b,9606cf6d,fd294c51,5632d9f3,4182bc4a,6b3805a8,d2c74856,a5be3cc9,e9c6a8eb,4398c606,81ce12db,b3a58660,1d426e) +,S(4e03f50b,ffb6d933,4282153b,a3f909d0,44bb7a11,50300c1e,cc8027b0,321b4be0,596c58ae,963e71ec,f1fe8f9c,b4de8cbc,9149b125,31e83e0,95f6e5a,b08c504c) +,S(5a6c4fea,b806bb76,191567e9,139dde28,188a26b4,a1803b7,d999278,fc57455e,6e81d07c,6505366b,c28ea476,a718e5f7,353d73c4,2f551459,d59a7d7,82e6ce49) +,S(ed73c9b2,9adf52e2,1280bb1b,ef63dd4d,74f4e09d,1be56c3,a246dc37,9b29bd5f,e9917b6,19ebe0ac,c7d1fa5b,7c4b7c52,e272ad9f,2df62161,59dc87b3,f913828b) +,S(68c6145b,38cbf9ed,4af10608,503ca13f,710dd34c,2386fa99,bdf93b69,c01c04bd,c963585e,607d9eac,5016f884,df535a9e,e7cb74d2,2e0c1e9d,e928d7ca,3fedc73a) +,S(1b651863,927317bc,1dc6094c,3f5c91cc,92269a12,59879b6,a8439a77,b0454126,31c6125f,8ac3d09b,d8c1fe92,c31bf13,c42b1915,e7147cf9,1371dc01,e8f5009f) +,S(45593ccc,dadbde3d,456b74f7,a3b705de,7229ff20,90a0df0d,38166d4e,6a09c52c,13d6657d,89fd0205,3c2b9a31,1ee964cd,e14634dd,20d85866,a43a4ea9,bc0bd737) +,S(1409c06e,d6f2fa2f,cd532983,d28c2109,e4dd7c1a,4ce77960,566d3eb4,37927da5,dc05f98d,4206fdba,e3b69836,e694b71e,fbeda304,537bc623,90edcad1,460984e4) +,S(d9e08c6b,c307b056,d4323921,5426febe,5d6e5cc8,4eb73707,4e2f00dc,e85f4580,a23c1647,c6b47a43,a3ab52ad,da32605d,172f4de4,201834f9,15d5a4b6,292c632d) +,S(7df319f3,d3c2b6b7,3533a916,64d5fa26,5ac0f18b,bbd5e8ee,1aa15dba,bd62fb32,9120f6af,e023bb98,1d6d8d96,31de0814,a9bd169b,a91af0b7,9c3db58d,2bc9f8c0) +,S(1a94e587,38b9fd1f,93146232,e2165798,11d74244,9bad3711,a373445,6986d7a5,332a27b3,17eee7ae,fb4604b,197f2db2,fc32549,ad86765a,74820428,abe4352e) +,S(dfa2cb4d,6db266db,2a82ef8d,fc0cf871,4aefff41,895ff691,fa0781f9,1b619a47,c5e5dbab,3a28a6c1,8cf20fef,4cba62f9,d2a1a0f7,6ea7056e,45acfe4c,49ad8b19) +,S(c2201007,be6bf76b,5e82c135,2a6e053b,acf4e2eb,c10a417b,f35e4c79,3a876730,92408aec,b9ae4d74,3af97c15,9c387343,9a735de8,90d1abe7,c8d14dd,fbefa581) +,S(d45632d2,ab087f0f,9d0d4d85,26730742,2f25c794,efa3815e,33e8285a,1bd7edc3,b7ce3697,c4994fa8,2479e99f,9c9e4b1d,814e7258,da7ba569,5543d6ef,8d5ff44f) +,S(8cef362b,cdc292b4,885f34ca,923a171a,df6c25b8,f6b7cded,c9003b71,cf5df93f,b3910f34,ed8b7fa2,bfa4f1c1,9d41d99a,d702e13b,5dab6bdf,2608186d,d09aaf5e) +,S(247f7be1,874c2831,17d60431,8184878d,3a415ae5,59595bfc,7f17583b,3cbf9838,90e235e6,a779b4fc,f9521da,65f65091,efd513e8,df338464,2f8a7cc8,f1f30eb8) +,S(b8c0cef1,c8703adf,411dd0b0,acaa2b82,f2609348,e36aac56,b0148ad8,981cf568,a0419411,47019aa1,4b8e74a8,1d49a97b,45e7aaa4,54c0f916,a33472ae,1275f14) +,S(8e55776e,6e1c791,2aa6b43a,4dd1bd17,a35ab0d,aad792c0,ab51bd86,8208cf09,dfe4ccc3,a025abbf,c2d12bc,6d462e6a,cec7307f,6daa9c01,2c8a7ad8,70822d56) +,S(f1cf6d3,fc9d9824,4e122790,de390241,db813b70,c48b667c,5f05846a,c3ad1ad,4925c6ab,3952d1b2,35ef1ec7,7ae7a84d,75006993,b173a6f6,c8b969af,c3984799) +,S(b49dbf88,dce5ee49,2b4495ab,9db762c3,81164147,cacbc00a,9e56670a,edb9ea31,c0f92f17,ab5797c7,758d703e,fd288a46,8971f7c2,de8923fe,b8b7acfa,ffa9ef2a) +,S(d6afe2ad,257b57ed,15573c50,a25f7dcc,399e2643,9e64acab,9a8c9f75,d8ca362,5df236b8,6919b56b,17140249,16282b11,38d355a3,561c5b42,b47ac6f3,8d35749d) +,S(bb0284c5,f23365fa,5972a439,fcee4b4b,45b48a9e,6844a44b,53e12004,1ae8e89f,684bcc0d,e09e5932,79018fb2,aed55329,53221dca,6f14f493,6ae76099,ba265300) +,S(57e95714,8a409697,1b8be621,98a04177,c4779627,ab5a77e4,6e82d847,e64467ec,714bd1b1,14ce2580,7c6d3a8,f12a5375,fd8e7cd2,5e854c12,6bb519f2,cd443f13) +,S(b0c82f60,b33c3b47,523ef2a3,de804521,a1e14478,eb637757,d17526d9,1e713094,cfc8d1b9,d763f52e,6522f70a,c93f7fd9,23d163d6,5a82b2ee,ac1af994,a2cea63c) +,S(2ba76170,404785bd,5932c185,c6d98ed0,667d8324,ff7f85a3,5c24a4bd,553e1ee3,1810790,74262af5,607167d6,b55164d1,e56aef19,f3e2f307,205d5603,eeea35b9) +,S(5bd54e13,d508b920,fb1d15c8,27e0ca59,3eb1c85,a7228895,b5c9235c,6ed3e88c,d65d35fd,5607e193,ea70ab1e,4ac7d822,878017ac,ef3bd6fc,2b1933af,660cf0c9) +,S(b0bbc2d2,753bd89a,b2bf1664,e6cf212c,a590d65f,5664e694,7ccdf977,3ea8d09a,9057b6c1,a1078bab,a1419065,4cc67052,7225741,1f34d47e,47f09bdc,8f993c23) +,S(c1701203,3cca38ac,ddc0fe41,95452129,b38b4630,20e8c459,224e9dc6,cd3133a8,c495d87b,1cfb6f67,46c07188,86c08616,624f78b5,ebf4fb14,fb6b636a,f5557e9a) +,S(1e0bd20e,5f1e49ff,32287961,7fbc28c4,7c9fa4dd,d93532ea,74930a24,5fa21bda,2d407400,e98f15d,e5da681b,2472fa11,b2a5869c,66be1cd5,7038e160,43dd6177) +,S(5cfc223f,ec4c6618,ff12a974,8533a70,f39defa3,bc05f88b,3a1b158,317ec15f,7d928bd4,89e3719e,6386ec22,6c738b09,eb4468f7,b6718cf9,3da33544,aff21411) +,S(f506560a,bebd668e,57e514e,bad47a84,5da345ce,50ac0e88,1cccc2c,81efa67d,e2ff0bf7,c9c2a99a,bc3580ad,17f64a26,63111fd8,15bdcd63,9d9a7d3a,ca0fc7e9) +,S(8448fe98,ec887485,45a46e4c,449d0168,1d00dcae,5bf96ef8,306e7bd8,26c54f45,d0f07229,17500322,2dda8271,33481376,85b20045,f69d656a,66aeedab,ea6f0407) +,S(c9a6857f,db037c2e,36d5ca71,32942f34,2480cf28,a98644f5,6bc455ba,97cffc55,a69e08b9,8f678e61,6c0b8326,ced6f97d,f742d974,b68cd1c6,b798e367,8faa149f) +,S(b5d13f5,c611eb3b,c82f7db2,d89ab19f,b8fc286d,8e4699d5,3dc664d,bac4011d,27eb1650,7cdc0fdf,5b92493f,f2487d0a,ef2692d8,9c702bb6,259808b1,324b7adc) +,S(bf9ec5f3,2e0ed4ac,c001b887,18c29c6e,90218471,d7f1afad,75abb34e,da35ce44,13846488,892b4065,b79224ed,368c47a4,a1734f68,7386546b,dd837a80,467ef2d1) +,S(2c3812be,4d3b1c13,aed1f6bd,1ca6f5b8,893c5a87,ad6a8f2e,d6d92ac1,3a526e19,366b82f1,45d551e0,b7bcf877,db340bcb,1b11edad,1466baf3,24a94cef,3433aece) +,S(77bdef28,dc8ef6c8,7fcd0a13,c08a26e5,9fd17253,8d8bd3a6,f21c5c86,ca33f572,da66b0c7,bf3bd49b,ec1fec,aa580a51,6977ba8a,83f957ef,8167f69,ea3c3a1b) +,S(bc4a799d,3185877b,cd86503e,3f34c606,8693bac0,654eeb15,4effd116,8b71afe5,53fcd7f8,99a8190e,a7159c99,e261525b,f59abf6b,d331be66,4f7f7757,7255569e) +,S(301fd884,733dce05,6190e4c7,d0375078,6fccdb6f,2e13f9dc,e275c188,2efcd040,79e4f9d5,185b9f51,fd835cef,64be607c,312c910c,e25cb73,5de2c88a,51e25cb6) +,S(241b4a9b,be5e7e54,214d0bda,13719c42,133f8377,e50db2f3,87b6018a,814adb70,c66edc08,fa4fd22e,1f76bca2,7fcc00cb,a8ce2100,248b3959,3c164847,b410bdb0) +,S(be6f1639,68191289,3c5c1351,d633d51d,dcd28c16,f3294981,56ea1602,d8c79585,6f674a7e,1a65539e,a7f8a966,8f5fe5e6,1ade5da0,a543335a,5f7a71e5,fbafff21) +,S(c8b5008f,79c69e2a,7e209ef6,a2d14b9,b3f7bfba,b7fcb285,e237cb31,3dd3a283,1dc79348,6c3cf7e0,bc36dd7,46efcb36,3cea15ca,a63008f5,2d83ec0a,6bb54bb9) +,S(5014af9e,aad5ed62,4e997ec3,a796ad1e,b038edac,77cf27d4,eeda7ff4,c06c0998,e01d786f,b8faa1c5,2d44a77a,987b4b6d,91143953,34977151,1a488602,3189dd7d) +,S(6ffefde6,2c40643e,da2d4f28,4f28fcdd,b0845ec0,8d882d2b,45dadd8c,a7bb989a,8e2b183c,782d3a9e,2229e4bd,9a2becbd,ff0a5480,6a6f4471,7fb6fe5c,8411cc0e) +,S(ac762bbf,190e1374,d32a7e5d,b4c0c36,ad0140f,c1e92290,4aaff1f1,487d463f,ccd79f18,31016b40,a381bfec,5db6b12f,bc34d850,ed81aa7e,435a513e,5f3adefe) +,S(973496d6,3ec05c75,93244e7,b737b1db,d791a5cd,e828f342,7968eae0,e811cb24,4b2c9bc0,44e3351,f637ff52,5c3f34f3,d7420b65,2f57bb7a,bf573e67,25647533) +,S(a9d89166,5f77bc30,74357753,9ea39e36,c39ce300,6fa03429,1a799b34,84a15d32,d09c3a17,fdedb8fc,f4f9ce98,20635a50,56dd884f,ccfaa96b,8d0813b8,4b80e213) +,S(108a8ffd,aa2b544d,8b8a7419,f2421bae,cbab636f,60d6ef76,9eca9a20,a0c5710b,ad3e9fc,ab04ad58,a265776a,75f0e389,cebbb273,9df328d7,b125665c,d4e0249d) +,S(ef969d7b,c8843c57,bfc0ac6d,f5e4495f,9543878d,95120a36,de8c5bed,727c5fb5,5ab81bb2,26738036,b145d81a,1deaada5,d1d4d653,7b80b02a,fc1cf85c,361f16fb) +,S(ab825bc2,4d505453,f12dafb2,8f70b245,d74200f2,410f5162,b0ba3096,43c39b62,789e7df2,23774415,da7e31da,277a81c9,708098b8,d455594c,6f9cb065,b1281a1d) +,S(4984a4e5,2c173c02,ec79198c,f8496972,eeed4e39,9933bac0,59856bb0,48bf2622,4596b67b,79be2e61,a0887a9c,2cc3ccf6,f199e924,3991f434,8e7cf897,acc5df3f) +,S(285c6ff4,93c1be13,f4f60d0d,8aa7cb24,4bf0f76a,23f3efbc,cfa4a132,625f7272,39dfe9a5,cf9cef28,d5cfd998,49db9b23,c4caace5,e8a27c12,12d7b3d9,d3ed49d3) +,S(1e14b1d1,7e721971,e9266717,13100aa9,9bc6e506,c278ac7b,348b708f,843db340,63a239d,d705f627,347fe464,c4d4143c,394d7dfc,5f79ea11,64d05f04,4ce41cee) +,S(b8f73b9,ed71cd1e,f61dcf30,9cd48587,3b1394c0,4cf318fc,10140bb5,be17c8aa,8af5dae0,bd66ec85,2ff4823a,a1be65ed,745676a,5ac42ec5,827107e6,776f665c) +,S(7e0c7297,e878fcf6,cb636776,d15afd0,49c995d3,1cd49d15,e624bf6e,8714540a,df5795f7,4c512043,f48b7568,bb271a00,ffd59530,a0280e5,8aaaf0fd,aeddd658) +,S(9f0ed1d,465bed9f,a2b51133,fcddfe48,10999011,b754acba,de5fd027,6b798545,7005ec9c,73bb0e00,64badde0,12aa99d9,d85b6c38,e63256e9,21799990,14a8459f) +,S(2d556f5e,b5c5af0,160608d,80e23cef,cc8e4000,b1e35b12,5a0a51aa,9c8e12bf,7600144,25bc3baf,1dc7f6fc,1fd86f41,d24d4488,f80ab8a9,4e4422ca,15f12000) +,S(2617667d,7637e02c,b479524,d9c7dcc1,2cc14ce5,4149928e,e8d81bcc,835ed3f2,521573ba,2cd809eb,8f5496be,478ca639,7a2c4e16,1b299ba,bc6ae419,4780884b) +,S(6247916c,5b519a64,7b76e10f,8810a3f3,4cae40cf,ed05a492,ba1b061f,d9aac10,ffd02570,535ba978,906a193c,500da1d4,602b0969,c3e9f4ca,f2d33026,eee7f098) +,S(c40b27e0,8ed50a88,60017e78,ececfb9,ea14c64a,95137db4,fa55d4cf,9a3c52af,2415cb8c,7d025b84,fd9d1e97,7105aa54,c4149fb8,30ea801b,a86f1acd,e07b6493) +,S(ba5aec8a,54a3a56f,cd1bf17b,ceba9c4f,ad7103ab,f0666974,8b66578d,3e0de12,348dab11,abecc4bf,3c7474d2,8ea5ba60,a705de60,39f9b70d,c49d58b0,6d57ffbd) +,S(ba14e658,f8dd294e,1331262c,ffb3f31a,c1e9e504,e55c7f67,5c002248,94076268,ced74905,fc43e55e,c70cb36c,66dd9a10,c221b0e3,a326e365,9b96de4a,c81aa1dd) +,S(3375af69,8880c7fa,29e718cb,4139ab30,f9c1d00e,a1c22d4,cfbdfa16,a7f4aff4,cfa8b491,a83be5b1,b66fa0b8,5e26c68e,8d27db79,ce55d726,ddde67ee,ce295a27) +,S(68d2614b,306cfdfa,e9fa109a,2c4b276f,5b9a8ee2,f7d502d5,efc94aa4,bd9f01fe,148c36bc,f04365ed,7ddf54e8,4d40fb59,ef9e1d48,8408c8f3,661386c8,5f48550e) +,S(93facea5,597703b0,ad2990d7,1d63387b,900ece6b,6c3677b,7fc47b7f,1c533edd,3c801bfa,8fa114e8,b5c19985,39a1f6c1,c20bbe44,d8ee7179,7454797c,942ad5f4) +,S(f11dd4a6,72f73118,95775ae1,76c90b2a,5a0a61f1,6ca205d6,eef6c275,75054277,bc06a16d,2ef2ac0f,7ea2083c,ac18d0d0,6c307d45,51e0a0e8,3f59b568,b9556ef6) +,S(42ebcc5d,710ba454,fd29a94e,f83c8004,b71fe85,9725c010,f10ca39c,864204f7,f8aa84eb,643101ed,4c7d5cdb,271d067c,e633c17c,dc698e40,279064d2,d65f223b) +,S(d40877dc,d96d5a94,87b6fbc,e89d19a0,549e96da,13f1fb2e,67e9e3e1,85c80e52,be9bb9b3,85f20fcb,8e57b59a,ffc01442,c0be8306,f5d9087c,837e234c,5e789444) +,S(c18b2c98,cd2110ab,888ec934,239240a7,aa40c1bb,ab8d7e39,8fa74358,2562931f,d9621034,9147d74c,75df18cd,1066c40b,b83f189c,937c01cb,24c2ce97,155773f8) +,S(154d6b22,1a44f841,1cf4fa0c,4bb4debf,6fe94658,c648f9e4,d14f88e3,e05c0bd1,df0bc307,c705332f,328bbb6a,dd94e63f,7c1074f3,ebc55976,de552a59,5875559a) +,S(a38259e5,629f93b1,a397d228,59842dbc,24485d59,c3ab86e0,a9326a35,e1a26f15,69b5accc,2fe52a63,b3874932,e8a79b8c,1713274f,f435d892,367bb9ea,91f783fb) +,S(9d729eee,e91e3493,9925a7d5,2eeded18,14827029,6f822013,d4db2a3c,763fcd19,6d832154,3cc8621,166f731f,2d874fb0,9cadc09e,4e330339,657aa2f0,e3e89a1f) +,S(2674f008,86307c7e,576cede7,944a9f9b,46398c93,8a0f8b39,b25701b3,67751e3a,3e9eb42,6ac9d1ef,837638d0,7b0f1f4e,e31bdec7,a9d22fa2,12a666b8,193f83cf) +,S(b2a06d5e,adb1b856,dd28e9fd,bb626c0f,b7c1642c,6f70c2c2,743f3451,4e237f41,5d4caf8b,8673b268,227baed4,481ad60b,de579a98,4d005f5f,f3bcead6,3bf664d3) +,S(20b27d64,d61debdc,ec3e4ec9,2040f05d,2b278c0f,1415ba60,f0bf23e1,222d713d,481d85e7,ff5c2df3,5cd26488,6056750e,c8c5c809,bb3afffb,41e447b7,a4e516a3) +,S(4f4a610c,450eaa25,f60d7c15,20c551f7,5270930f,45a7c51b,fc7cd5c5,3ce3f2e5,df1e8e11,db416228,672d8d8e,f9d68ed,e824234e,fd7de39c,2b32fd90,3a47f328) +,S(9b375ed8,504358,25570b4b,e359bc07,bc06c989,14659e9e,776fba36,a8aceaa9,3d056593,385c0069,915de5b1,f59c3483,22683440,86dcdf26,d1e6ae22,35e90927) +,S(43640804,5d432c87,31f865e7,2390b7ff,c13aff87,37fcfba4,60c0192,2ec9d1be,e2338eaf,6fc73fe1,e3df2aac,54bb4fbe,5aff2a92,5b8b16eb,2346b220,6070cbeb) +,S(a6e59c4f,24461172,4161f35c,fbe88d4e,59287f2e,f2b9ea39,4c476127,f41e0b66,75c70747,f5dd75f9,41cfa470,c4cf718a,57a8ae2b,2e7ab277,5f5ec5fe,7d9f334d) +,S(ff639617,ae7351fd,977bf1e8,46a6d33a,5293a959,74b296ed,7c9a007b,25322d51,e6123dab,fa2355f7,653f81ff,ee798353,e21dca71,ef40639f,79d73116,53dac457) +,S(77914840,1710d8e6,8a37cbc,5ad5e284,c254dfee,1c8b043,5f8ddbe9,4ef4faf3,d97f44e9,9ef3d4c7,4075dc3,894d2a6a,623be446,32c98eca,a54b8ed8,e0611414) +,S(f68910aa,29254aa,10551c00,adc135c4,947cf1fc,6dd8ee5,d42579fb,79484aad,40bdfbdb,33a56d63,ad587ea,fc9784de,69f9f5c4,3f5c7c94,1b9b59e4,c052c1fc) +,S(15be8f81,473d4cef,719c7501,1d560d84,f2d4d8d2,def1d696,29f62464,1b6e0fd3,7e66f926,fc991b41,c451ead0,6d93267,64b85ea8,849047bb,1d28eeee,70fd9a2a) +,S(e113d5a,2e22302e,f4327297,7c41c8b,d0c5c26f,9a0bd9db,9091abdd,8a84e9ca,2e4862d8,34c6dc45,17a6b70b,2f1b2c5b,b54941d1,cb803530,26a257ca,f5574dc0) +,S(96b10770,485bba67,7f620d9d,ec0d1be2,2c94dab0,57d6d595,aa78dfe7,47bea688,e060aaae,222726a,c1a1bd58,fc779d9a,ff854ac2,4a4996a5,2259e9f1,bbdbf30b) +,S(81742f00,5555954e,17e5e899,d2cfd8c,57f6f7c7,5a38e183,de878934,2405545d,a1763fc2,e5f705f2,e6f2fbb0,73578fb0,a8d742c6,8f92236e,df1ee03d,2ed2fc0e) +,S(17c19f13,96988f62,77cb72ea,f90d37bb,86bc7a0b,e16c1c17,fcc481ff,bb78a480,cb1290d5,210164eb,621c2642,ae3e51b9,3f430e60,718f9fd9,c5ec3bb6,53c78833) +,S(7b0f06,e8746ec9,c6648b2b,bb861548,bfeee507,63c01c3f,40319beb,a2497a3c,c6949378,84297d8e,308b318f,1caa0c7b,1634b758,9d6e8c6a,2fdb778e,d6a70020) +,S(715c2b06,2414183f,9a67d8c2,8a89b754,55a80517,cb1b8134,5f56e91,12c5e8b3,f89b89c8,9a795dc7,1e2d4cca,7f84b4d5,23167f03,97787b33,9205773f,2520370b) +,S(e0d0ce00,f974fc78,76777662,efe5dbf5,57aed09,dd89a4c7,8f1f40dc,8f74d3b6,acc5be65,ed704847,94bc7f05,c4c5511f,c253befe,7cb3c0d3,e85704e2,e3e3eb56) +,S(37553289,76fbb8b7,9a5aaf75,ecd9d2a1,bdba9a87,5bad6222,e770ab1f,d26432a2,6dbbe233,1b7e064b,d80bc7d0,12b2a088,1087e7c,2c5c1d77,eb016108,c2ced92d) +,S(2e95c3ef,51ea9036,8683f6b0,8b2afb04,f46ca651,2abdc699,446ab3a0,6fe3d3ff,905ea87,b1d8dfe0,48463b94,c61dbc62,1556c66,b2b498,39cb40c3,299b554a) +,S(25310e1e,721f3245,7f35c67f,b73553f6,6467580d,b5916cf4,fe7d75a,c4ff8eb5,9c5e52f9,be42eeb5,425a359b,87dcab1d,46ecd662,c17eb041,16b5430,786b4ace) +,S(25932b1b,2b24fc2d,d7877911,7d7cb506,27a23b7d,7faf53b0,cf707f51,b7830b7b,7e8e23b4,acdb26b0,1d7969a6,ddf3a2ae,2215e206,109cf3e,4e32d91,df536765) +,S(7d232af6,251f7667,ba69ba44,397f5b8a,892e135e,b09b684e,22b16a44,73c5ed3e,a3e8f638,c8a589b5,8cfdea61,d9824f1c,131b9045,9509b92c,1cd26571,a6d8356e) +,S(4d56caa0,1b65ea87,ba3e05b0,a4495606,6afc8645,4847633,cb9e9755,c8c720f9,14c34678,36e65197,ca3f1ada,936f0348,7c1eaee1,977ae08f,50f41771,77537330) +,S(71abd165,ca6ff8bb,775c81f4,2c722ed7,2615b503,3727dc2c,122efbd9,c500a88b,79ba2467,7284f86,2fb1c46a,e11ac4b9,a5969352,64224eb9,c39ab884,492620f1) +,S(8462fccc,c3810519,cc449634,5c5d9e56,30215e74,c41179f4,2002e906,56a48965,535a966,cd7fb998,bc548a7e,29fc4640,f0eb75a7,5c3c05cb,64d09048,a7787d4b) +,S(f68eac93,fed751d0,b578b5c,665684a8,b9c2b104,6fe45ae3,286e9351,36c09826,98e0c32b,98b0a8a2,8f119ff2,fa50e54b,66f7d8d5,732a1831,7334fc45,fd48bff5) +,S(61447250,9a8d935,9c0e4014,f6ff569a,43467dc7,e4940b16,15f442b2,d9f72041,fb7177f,c7f57ee7,deea7108,dfbea888,fa58f209,2aeb2d2e,b2f33141,7ac8f807) +,S(ea69ee11,4ffa1bd2,e2259a26,e2d88cf1,c9846ac9,379a1497,fc28ecc5,4b15614f,589b81b5,1dd6d750,91014108,3dd6cf3d,63183d1b,809b62c9,b17b768c,5ce4e2de) +,S(34727b24,3404de96,641a1ce0,d7ff150b,38e6aa15,c51fab78,1464c660,4e5d5263,9198326b,cf56ca77,35b9baad,dc0069d3,1920bff2,d5bbf804,435289d4,d827d4f2) +,S(952452ae,613778dc,29e2d275,6e98b4f0,eeebf4d9,526cead9,52f8d0d9,9e217461,c08b3a28,c195fb5a,f9a50eb1,1b1411b,c17f6582,dc14b5ff,797175b,2ad486a8) +,S(fbca3f18,dc4a8bc7,7e9afeba,66610306,401b8342,bde2dbfd,2d4a156a,e78e49ff,2b829d6d,6027b2de,eda0db7b,c76b924f,4cf75573,bb9329b6,c7b7e443,f94129c9) +,S(c7ddf11d,7ddc643a,957dff64,a08a4a70,5302bfff,b940882b,57bc4c15,5bd8c141,e9ca11f1,ac93b018,3fe8146,839be79b,b3711ee1,8a3daa88,89d55669,6e708e20) +,S(71043a30,86e3063e,b831f7e4,4e682181,1b3f2353,9cb6efa2,cd0ee4a6,70ce31b8,4db3f338,ef9fd273,4aa9cc92,55e2984d,9334c164,5320b411,ebcb7cb4,89322c9d) +,S(6de4ea40,15347cbb,d9349d36,80fa375c,5d70f044,799134c3,dbb6a776,48602585,3b76588,65ab52db,eea8d839,47025cf2,458a3243,38c73d70,f1d77df2,7f960418) +,S(29faa79f,467cecb7,ea17e23b,6f7ba03d,db9a0cc0,e1fa6215,bc425696,ba4fecbe,e5aa691f,c42fbc29,c1f027d0,46bdf106,64a2245e,d2ff1154,e50ffa1b,48f34838) +,S(ff880bfc,25ae5b22,78e5f15a,2bf8f5b,d750f8b8,74910f79,c8c42f93,16aafc99,9535f70a,728f79,37825bd8,1bb502db,60e7a166,bc8a0b10,5eeeee82,3a5747df) +,S(b781b6a0,3837f6f5,8520c566,352e8c09,60eff0b2,42524eee,f6a6bd2f,a4a2a378,acd7b7d4,6c683dd9,43722ee7,3c12b69d,cbf8389e,62755e4f,c44fffbf,4cdbbb62) +,S(6d976593,e8bac5d0,da732c64,82e4ac2b,b3f19062,59045990,ee540a3b,467406db,30c353e4,af6d8161,6c0bb9c0,f2a4aaed,6cbc1825,9a8b9658,3bd7e9c1,2f2a8b6b) +,S(18ed676a,4dd3e0db,46212112,9fad1e13,683ec782,2a6d9401,5d0866bd,6cdc3032,c86b06e1,5dbfa82a,5f7b9762,65e03670,6f9a6e7,7ee319bb,8ef26b16,a51bd5) +,S(3138e38,e9440ffc,c2cbce4d,aefd4b8d,d1e859d3,b951d18c,eb3540ca,db5ce2a1,df8ab1b2,a11a8667,dd660a13,490c6e6f,fef4bc40,94efa9a3,430e28c9,6895c241) +,S(757df4ac,2025c9aa,b8ab1e76,149a9762,163ce608,f4903c3a,91571cf,e8b00c95,ff0af5fe,ab36c5d8,47d15ab7,65000765,c56bd7cb,4d0fd8c4,a37d4ecc,dfa03430) +,S(8a697a52,7156589b,d13319a0,81e3b2f2,ce09de8,450b95cc,9aa70409,884c27e1,9eeb93c,b6029e9e,37f2815a,d332d5d9,5a5edde6,bbf03ca1,3df09f86,ad51f39d) +,S(b0bb6987,36f9e0b1,6cfc2198,e37a84d5,d35eb89b,d4f4c0b1,650d60e3,e58c721b,33d5b200,ce25b501,6f09808f,b38e82d,b855615,2f48c1eb,b3b6363b,ed6e00dc) +,S(1ca0edde,5dde4634,2637882a,d2f8ff7,ef6d6f5e,906ae2d8,d9f1b545,c837efed,19efb5ae,4cff683d,a7d5d4c0,f5eb9f3e,4c4d3a4f,ac58ee41,acb9ebda,a82863bc) +,S(780e5b0e,b9a4e57d,66a84931,1e1b765,d59ad11a,de4e921e,d90fc422,4d474aa7,5ebd9ccc,58cc5f21,2da579f4,c79aa3a4,1d8f34ff,418516a3,d339320c,133ab811) +,S(f7e92ce9,39808505,2d2af620,cdf210a7,30ec079a,54bf1468,edf686da,34eb4c9d,2c559dcf,e113a961,58fd54c0,32f14ada,57c23496,7a88b585,7b1f7ab9,78f93666) +,S(3c3afa20,75bb20a7,8f9ff809,20d80d61,3a5688a4,269336f5,4bc7da5c,4a89f938,7ef38308,1dd235d6,e563a9f5,46435f22,3bd836d9,3f1d132b,978f3f9c,7b888c8d) +,S(71d6f01d,ee60f9b5,75dec59e,7e56123,89fb9edc,3019115,af4fb155,f22097ee,e1ccc245,4a31a35c,52854091,fb414321,38da4fd2,eaf1680,2ef0470e,1c80bfee) +,S(9726660f,5705ec80,908a77b2,8e6257de,b107fc31,c58ab6ea,1f5f75b9,38c4fa2d,94cc07ae,3102d1e9,6118c213,b6db0c65,d3636fe7,8ea40c6,90c86949,b48cd4c1) +,S(ace5d0c7,54b2a1af,691a1a2,97e8b632,297fad12,ec1fc4b8,7fd02ac2,b2802719,924f9f24,8d3e725c,eba491f0,5f188d6a,7fc843ca,d24d0858,1f4c9485,8b9f85eb) +,S(fa51306b,34800ff0,ccd778f2,838a4a2a,8200eafd,622e98b8,8fa566b3,85943f64,b60ee616,6b144873,a1cee030,fc92b50d,4b67757,ad34d5c8,5f05c871,4296e293) +,S(85df9018,329d25a6,79c097ee,458eafcc,b716a59,611730f1,7c19d584,2dbea60a,c555d5b6,46d211c,e99ad7c0,9e787774,b7bc64c6,f2f6980a,e62e8911,897ab0fa) +,S(2f77c00d,c2024467,ab461b52,ae634a99,337ff5f4,780637f3,efb989ce,24af5e3a,c7f4a678,ebcbfabd,870c52b0,be7efba6,c5d28e7,aef2b253,3f0e7fa,905e3e39) +,S(52d8a23a,720050d6,ff6a499,7b802bf5,1f238df5,b0ef6001,58fc48c2,228bb34e,98ae81a7,861b8e1a,162d29b5,1c30c786,cebb1812,c91780f2,ccd302db,803d9136) +,S(a7f3e479,eaca0049,22fb8320,47555b5c,701daf22,407462fd,37b0edb1,7212b211,80f6190c,8c4ca7c1,7ba68498,d1bac039,3e33767c,c476fae8,e926500b,9fbdaada) +,S(31ef3150,e67bd326,61bbf4d7,942382af,73db5799,8f4880,ea04607c,a2356103,7db8f5d6,655d28d1,93b50bb5,14b16ed5,bc03c46a,e3d2c954,631834b1,a8a9a8ee) +,S(ee82f155,469c0299,39ad1ee3,52edea30,599b0cd3,868131fc,eabee245,3b8b058d,fd0c0d4e,2d77c2c4,2add9ed6,cadb898c,32de9398,f0394400,eed2ff30,5092b10c) +,S(dec7c7a,bfcedd6f,a9f7d45,8a071575,27354990,b456873e,206d1f7e,556b4586,af841ab4,cad597f4,186f0912,b79fe320,2c7626c7,b85cb276,73c18010,747200c4) +,S(c28e3370,48cd6fe9,7591ba40,5519bd80,2bf34f12,ee48762e,526b34d1,f4d2369d,e00abdd,da456731,7f486dba,6976ba13,b8640f52,39325a64,7d50eb17,f0636e8b) +,S(47157ca9,2c275f65,c29e9d,b0f23531,37027731,1cf05a93,7145123,df222195,648b17fa,c911fd25,af87e9ed,441cc874,9fefeb72,b34f8dc4,f430e0ce,89cbef6e) +,S(84d11702,745c53ce,d81b5503,79ff1947,9a0a9253,a7ab3868,f5471a64,6ca73241,4f16b6a2,c3c087a,4efb1353,644e64cd,fc593ec1,d8d656b6,2c0e0bc2,25f858c5) +,S(3bba3022,196060b8,6b2b2f28,ea8811c7,c74e8128,8e91adcc,b7fbe2d7,97d63fc9,7f34054a,f0945373,a77c5aa1,2ea4f54c,879d3f98,b6e7ef3a,9d73d2a2,a734e286) +,S(85637f4,7a2c6143,2437485a,b3d40e70,b9f74606,aa8538f4,425e8a06,98651c6b,bc6a95d5,6fb42b1e,67b07576,83a5036,f76e8531,a30d0096,c3500ad9,93396054) +,S(25302e98,5e75019a,21ed1605,dd3c543e,e8021a42,a40a967d,8ea6ed31,4dbbd123,849ccbe0,23097591,d46f9b4b,a13713f9,c0220639,11fdd0f3,267a4d8e,66797a83) +,S(e59a30bf,88e393e3,c08d73da,ba720ae3,485fde0f,b6b85f8e,4117f5e4,f43bea40,6fd7824f,e222cb37,1a0fa6bd,33e4bf83,83ebbb64,87872fb4,42284498,6197dfd5) +,S(c5902df6,97981a60,589e9bc3,b935de2e,de05331d,2c1365bd,a83f8183,f6247e4e,c67eb14f,5af551ef,1ab5ecb5,8feb7ce1,21d0736e,b93dac91,f865ac7d,2d75fe3c) +,S(df8bdac7,fe27127e,c679a9b4,74e3c809,b8b6409c,2e6c4c1b,277ab4e6,d5e66ad,3ff26fe4,9f0b3896,54d802ed,72eb4708,2738256f,c0266dc7,645b1027,717d43e1) +,S(1d55404e,9c7cb8ca,c39c7c02,b810d5f0,9eff9125,9166cf3,f1e8cf76,2c65a82c,c1787023,f6a1c8a3,5c499f64,a2fc4d23,e5a760ea,9a04707,c24bb9bd,b2a7632f) +,S(35f390c9,b035fdfb,68506073,d585e450,2d040e96,67a1b4ef,804ee088,df43b44,6a85cd88,86aad8b7,7dc36fec,50eb9754,4c3cad2a,da43d038,3c55da38,bff512a2) +,S(fbb0840d,ee888fa6,f26d7005,b2449cfd,1d22786e,d43d06d5,88f744c4,c5e059b0,6460514f,d89a70f2,3a4ffa21,9f651bae,203b05f4,bd3d45a6,508d2b25,cdb8d3bf) +,S(24056cf0,1c2275dc,44608ac4,66931e91,61fa0ae1,3353cac9,ce481271,a34d78d7,43ebd3c6,7e7381d1,bf03088f,434a5275,965a3fa0,d86a51bf,7dda1b63,cbc7751f) +,S(3b1043df,e8447c78,8e07c938,cd72f6b3,54f9f745,d7e71297,e7791972,70f9cd78,28e028c4,abf0d511,126c29d4,b2b185c7,b67ba361,e16c50c,34af129a,5e40d6fc) +,S(aef909d1,41793638,80d75b23,6635805c,8088b08f,5c577a81,a5bedd20,69a040e6,cbb4c6f,de26b6c,5d0c2b43,df40a3fa,93350cc0,1c497382,d8a1bb7c,8600dc51) +,S(c8d494f7,386331cb,6ff59aef,5f229bc7,913367b8,10f407ac,2c9f9d3,ca833f28,cb2c76f9,4b6285d4,d39afdac,bd3ef114,c7b85027,8d62da67,e70aa74b,b10de4d2) +,S(25afcff7,af14ca32,3dc74443,71de7b5f,c1b52e17,6fe5f3f5,f4f39139,34f75b28,d867a4a4,7f9d7e97,6cb1f57f,8d505a66,5010cdfb,4af4b781,75271722,6942b789) +,S(2436c86,f773930d,872c220d,c8bd72e5,d407682d,7708e2f8,19ad9632,3d32e2c7,6e396dea,92af663c,c44de690,24e1407f,20a95887,37f01662,bc89cdea,88ab67a5) +,S(61ceebd5,9e5733c7,910bcb86,e19159ee,57638bb8,7f3cc56b,d0f4d25,147f349d,2a850545,e9b0ed08,fb63082e,741a30ea,7d85218f,86282aef,3e74b15c,f2fadb9e) +,S(5a1133b5,d45d0071,42b91a73,79e2a46f,dcbfee6,e102d16d,d77e817e,b4b6c187,2ffd96ae,afd6d9c4,3c9c0517,133a4b7d,34c1c2e8,f398f81f,f6f0305,28d492e1) +,S(b74a3849,8b701b41,29eb5abe,8dcb13b9,fff0f191,314dd293,9c38d0f,4563c8ac,9d844e57,e50a20fd,864d6f7c,5a677855,689be528,f8431186,ffa96679,9cb9014f) +,S(c35c9cd0,4afb20b4,3fd1c337,5a952ad4,8e9a806c,a64aa4b7,52fcb204,5f89d26c,b041c6aa,4a83efcb,dee79d84,19e195b2,48c765c3,f069d5a4,b7e87792,79a9c65a) +,S(9a85aa58,753868b3,f04b2af4,479141d7,11703dde,e5b6e5e8,fea8ad37,d0b82b96,465c70ab,aa16f03b,d24b8075,233ec626,4e062041,3bf485f2,551d9952,7bd75d27) +,S(3ec71bcc,e051f3e5,12d83c14,cbd23f49,b3e825a3,cfa4c61b,d12eb057,5c86fe14,f198c21d,e2daa56a,55294c5a,b033f1aa,45caba3a,9a950007,db35f05e,e9915bdc) +,S(ee1cbe22,939e1ede,9010e23,535bf33f,6b09e579,3737db45,aea48f00,b359ae63,bf604026,d4444df6,27f7d297,1dab6a91,acecb6d9,de53228d,47178017,921b90a5) +,S(ebcbf3e1,71de3a62,ef47677d,1ff4d027,5a8cd92b,bc889ee7,8dcf0c99,6746073e,878d63c7,bc9c7224,914a3f3,2dadeb9,95c6d890,a3823f98,5c3f574,9ef6ebe8) +,S(e4e92ee4,ce72ef15,b87c57d5,259520d9,b6066430,c090dae5,6e81b2fd,ab9db797,3faac465,4a03a753,559f47db,f5877452,6d21838c,9c1f8217,ebef6965,655f944c) +,S(fc1ce758,8e292b03,7b4ef743,12eb1f67,cf275fc6,7c1e3d63,5bc42dd0,deac1cc1,176b79bf,44f7d9af,7f7c791e,8cafcb7a,495bc392,c23899b4,2fe7963d,e65186d7) +,S(f1f5bfff,179e6a6c,692a86b2,1c95ef85,49482b3a,b97a491f,9e9c7056,ba94fc56,389257a8,a2cd3bc3,fb4f0620,5c2aae70,67041512,10c62093,13a2584f,8a39e143) +,S(980e7414,61c3e001,ba6bfef8,d175a141,2c7aaa2e,748c3323,ac744fd6,ab793eb9,6e37ddae,29e05e83,b3cdde28,d4286005,34cbb33a,636c4259,c7fa7625,1b31826c) +,S(f519cff7,686a5257,71986dc,7e6c1955,adb7faa6,a6f7a07f,66a257ed,a1b1c179,3e803eb0,8c765c98,7941d008,a93b8503,174ed4ed,1c31e97f,9eeb8f2,a55a807) +,S(2dd8d9ea,3851fea9,1ba9bafd,bcc5cc0,9011d939,10edceee,144e2755,ba8f8061,6147f1af,d4224689,37cd058b,4ef52618,7adfdea9,ce970dc1,365fe04d,1da52ae3) +,S(860c4262,9483537,47ac0c41,5aa00f63,2854f88c,d7d09b35,edefd780,1454a4ae,a2a7a22a,7d826d25,8e7dfc56,1eef0d85,d15378a2,80535cef,95ce6e2e,d73392f4) +,S(e76b20ec,17d82c3d,987d4ea,20535209,e0697f90,2c964b28,ae97ad0b,aed732a6,c97844b6,85f6613b,fdb7cec9,cc47f701,32bc1137,d997f8f4,ad182492,67f54bf0) +,S(26731d0d,12fba582,636862b1,62a417b7,718ec9cd,e3d047a6,50455efd,910ab88,3c10efb3,b464a61,6e2023b,b0736d6e,8d298609,47ba5714,3b1a71fc,9b542192) +,S(50cb4878,52db811a,87fe46f5,ed014db0,3fc4570e,8b2d8ea8,9865df9d,a224dcde,bb8488a8,7937ae89,88f572a0,c100e450,c69db48d,303d06f9,5d54bd83,8b39621d) +,S(fb69453b,1d67ffdb,670f9fb9,2b3fae5f,64b0c4d,cb28ba0e,7ebeeb21,ffb02a60,b0fdef36,92d881b6,3ebb1387,984120f8,d1ba17af,477364ca,41e303ee,a4fd2c39) +,S(a8f1280b,4b720226,19faec4f,ea3f784d,3f4061a,56dbbb99,38c7706d,8bb249b4,ebb3b571,ac505913,4572e501,4be7be33,a97e12b9,bc1fd9d4,484703f4,6e39b8cc) +,S(4292ce09,df305790,f17cb3be,30996016,420f83c1,bc19abb8,78b49027,6eacaa98,1b14d94c,bf2b1d1d,82cf1873,3461b76c,f32c8d5b,6746e2f9,aa2aa248,1c745d36) +,S(ac241177,f16f747f,b796750,49c83f8f,8e1a062c,9796b05b,8c5a5587,a4c9464f,dd057503,8261d044,ec84eb03,73065687,266b695c,ef5cb41d,1cba3b5d,9176cf58) +,S(692eca73,26bf2da5,7fd9d640,acf7f846,78e75c9b,86b18e7d,d7fd2545,751823d3,17d6d462,548ea78a,18557320,289d61da,14c3850,4ff03347,8f17fdd3,71c8e97f) +,S(d01b1a44,55ef5011,e4ecf946,ec02e6f5,d0e129d4,d2f59889,e823cc5b,6f10e216,84a4d89e,55e33edd,d54f38f2,1649f5fd,807879e3,388df988,34556ae6,57f91a0f) +,S(1eba61f2,96a788d8,9273a67,18f2a0cf,fb0798c2,393330f1,2f890bc7,9bfc1e9b,89f298cb,e8471046,2df0a6a6,b6c4b6af,505da2c0,9ee13266,bc47cd5d,2ddc9661) +,S(26dff8da,94603121,4649fe1f,721edcc1,a2300ca,b1a6d548,9c9b68d7,415980ea,d8264a21,55e1bbdf,c3b65862,efb9548f,3c4a0a5f,97f5b713,9d3da15c,90004e60) +,S(4e642b51,425e1822,1275f64f,283e9eb1,a3116adc,a6e25047,cee3bc0f,323fe676,f28b7d65,9125468c,4951db0a,bc35d4dd,65b9c5a0,ed27d742,47a68a23,89eafbb2) +,S(354aff5c,ee9a27db,37e7c97b,4cea476b,b4f3700c,e9c26b21,e94d2e1a,78f448a2,8d6907d1,624b79e5,6392d008,2f6a794e,99b4c4d1,6ca78dd5,97709c86,2930fcdb) +,S(5286d074,949369fe,8f69f020,c0b65f75,e76995ee,5f49b9dc,d570b956,8ffbdc3d,255ef2e5,3dd2c40c,1e462a45,27e6ee00,e0a23d3e,b16b05e2,2781de6,879703ab) +,S(b84a8346,c86e2299,9acc8ff9,1a893592,6bddeeb8,6fde121c,266d5f60,3268add7,31179a8c,79f40238,e1b80c87,81e46597,29f5c8d3,d8bea0a3,f65b403b,ef20789f) +,S(1e7bd5e6,63fc9a50,2258b9f1,14fc51c3,1b9dfc27,9022c67e,fde7872,dd12bb94,6287a9b4,555b146,7d250f11,e77ee8b5,7accefe,6d91cb6b,927611f2,c2c1b84) +,S(7ee68a21,37289ebe,7a5cfde6,be672ca6,9d28acc4,54d6b8da,9c96b2ad,37d2bc81,3ec34064,a6c3ca,f2a8aeee,9b24e023,3d7dcbe,b7acddcc,8a53db84,c570c83e) +,S(29d4b10c,f4be3bfa,a9d07fdd,da6ba7ae,f3adef75,67c3c33f,8d4d914c,f8ce570e,b6a74385,96a4f40a,40d03c25,2c7070da,2ec79e08,dbef71f2,422392ce,1058bf4c) +,S(7907c5d9,5c5cd647,e312a43b,42c3f053,50218f10,da6279c9,895516d7,328c359e,6c65a9e1,ec062a1b,f2abca52,fdeeac18,26888378,58f985d4,c8f1c987,64d6a625) +,S(cc436eae,ce11bbc3,36014fe7,bc68fcfa,e5bc2c55,c53430ad,fc994b8d,959d31b1,16160de7,d6ffbf64,d644e608,96052985,6b2bd539,66d7edb3,a50c924b,fa9706a2) +,S(cf023d5d,278d4201,ae659d55,6239dfa2,1b5fb30b,14adbea,7351b620,150ec1f0,d6007395,ffcec07a,6e71c26e,7575cdb4,34c473b7,57d4574,9e5154e4,d4990741) +,S(1a2a093,f718c59b,d4d35b73,2c547b61,12b6a257,e807a38d,71b04125,e7746a21,2674b542,652fa39a,1a2cadcc,3924796e,16c0f8b0,5d83f919,f8b93547,98fd4c95) +,S(534ed420,4b8ac51,7518fdff,224ffae,f712e4c7,6a84215,fac925b7,eeb799d7,35e5852,3ea6199f,b9fe497f,576dfae8,fa30782f,d24cd439,c0708118,dbd82155) +,S(8d31e4ad,9e6f30ae,6c78ff18,8f4b0457,e9ba646b,3a26138c,f11d84c1,4a00d08e,f0dbefc1,909396c1,3a1e36a4,844b2a87,e4b0b1cd,4b30e996,47839bcd,4dd5feb2) +,S(81748452,267405a,bf664379,16ff7f73,c418439f,86b73159,54c15fd2,2d2b3412,13d1209b,435b50b,1409389,9961f5ae,9f6f95fd,280beba7,cb3f3f5d,a0f19bbc) +,S(bca87f72,e604e885,64552b,edf380ca,45842270,57efe12a,6cc23847,658aaa3,ee508af5,28b77125,72c123c6,276ba23f,af26538d,5752d84b,54ee82ba,df9e3d0e) +,S(de2baa9,a19652f6,c0c0365c,d6e78cb9,d527e546,1240fc52,e8c59183,7fcd3fb2,aeb418ef,466c32fd,4cb5f2be,571672dd,86573941,a9cf9bd,73377aca,1ed38905) +,S(7b8ce1e9,14df7919,b54a0591,c077135e,556f6cab,c7665e5a,c0004390,22acca9e,a60a3ff3,9cd8ad49,c100b72,4338a54,d06a96a9,f3fdc7c2,fb8ae598,c0b40628) +,S(cd71c179,13fe7443,19bc80f8,205d7617,4d6d44fd,a6ac3d1b,402279b,eca50e75,9f1e73bf,cf3438d0,1f01d1a9,3f633929,ae385812,528ad211,967bf38c,71419064) +,S(42cad02e,32dc8dc3,4ba36161,d0816af1,619b70e,117da444,f4f1e454,73ca8fe4,97cb2134,5a259cff,8870823d,fe11031a,79e59d7e,dd2593c6,65128a8c,36e75568) +,S(98a89130,4f0652c6,2986644a,62a1dfab,48331756,c8b9e1f6,d473c03c,b98ff8c7,c130f2ce,cc506903,9ca49b3e,534ad484,b277e0ad,7b2a8733,98864000,e9a824e8) +,S(23c45c76,84762aa,7bfd39ff,284403b0,d7a4a128,6bd7b455,22c09d2e,df8a4328,f4ab7317,95c46f47,c3d46dc7,cb0d43de,d57cb274,ff0c350a,f0d79548,bb303cde) +,S(8b700037,d584c4f2,f65416f2,dbd37c35,9e6a7b83,108dad34,3a6c4d0c,6a21d856,8371ec03,9ed0066d,4e8e7d86,69169f9a,5a172cf6,c324c2b,ecdfc76a,c365ca35) +,S(da6164a8,d0fb4111,ca1d78f2,83e8180,4f4ae8,50ae8596,cdb97d9a,a30f8a7b,f9a8463,717e4f17,a77caf4e,10c11101,1cc0b5a1,c788307f,c7aba482,2a9a342d) +,S(49f37d65,a9d1a54d,1929b9c2,6db7d7e,c45924e2,9e6010fa,2202d47d,eb5fd6b7,f9b9b785,28f62629,7bd0dbba,9340c142,1e64895,b1befa94,ca677de7,686aa51e) +,S(8755f088,e26859a0,1a56b78,ba1898ab,12d80837,308677cc,b38e9c53,e36efa10,5d67013d,1eec7a88,215b4768,f55f83f6,434906a9,f2f6a9a9,de5df75f,6ef7e478) +,S(35321796,b7aba6dd,873550fc,5a35e081,a4e6d134,a127c534,69ff777,c609045c,47ff0f43,efa93f4e,f197a680,4f1e1133,c5c8301c,b49de8ba,6fe10167,f0a1e832) +,S(3abedd2b,644bd2bb,e77ab5ea,2823b42,83479fec,df2b3421,56fe9ace,612559b3,4269b08e,6c13b818,131824ba,11e3369a,87bbccfa,330e408f,17985b21,e5e32b06) +,S(e30112a2,2c23462a,a803dc53,e3277d7,c14b62cc,92787f77,5be98ffc,7c956de8,d0c7e3d0,dbb10e8b,7a9f4e0f,f93e7581,99d90f6d,d869368a,8d2ad369,4898da40) +,S(6250858,439c4b4f,30d47f6c,b9259103,bcdf497b,f09d3762,f1073f5b,973cd06b,3437f5e4,84ce4258,5584407a,fb0e4383,87e4c930,2fcc902e,cd26b721,5075328e) +,S(77ad4485,b8c94cfa,4e904bc3,90e93e3f,66838d50,fb16e09b,dcb39ad6,88f826ea,4dbc505a,9798879e,137c8444,750ec3c3,34c2ecb5,485bab73,6b0b9bbf,806001d4) +,S(5dcd3e92,e413601d,b9dce337,7a8e67e4,3852b8cf,ac41066c,ad579199,3ac0b7db,acccd081,35efb43a,306760ed,ec278f7f,36996ed0,d6367f85,417754cb,a4e997c9) +,S(3a26663b,adce051f,c41d2e6b,9b931851,e65ca385,15f59737,fc8c27f5,caff788d,2d647eab,af01d846,70110e,7272cb4,9b9db0b8,88a8113,bab5f89b,90abc2bb) +,S(f57cceb9,51dc98fc,712fe9c2,c024031f,4e3b0f02,5067ac4,b8bb0096,e4b1aec0,696093eb,7a8aebed,a751455,782f99fb,ddb2c66d,438a7bca,9c4df301,b7a1ea25) +,S(a89a4778,bca06e14,bdbd46c,948ccd36,df47c83a,2dbba9b0,93589406,be9b4a0c,f4224dd6,9d08262d,22b98e2e,4e781e6e,939d69ed,d59f30d1,d23f9ea1,6ef366cf) +,S(64738381,84fe8247,2b463f4c,7ff04a6f,6a3be92f,ba295d72,adf065b8,10b962a9,bcd100c0,d09f6e93,4fe9d58d,d58004d0,9ba164fa,324010bb,c973709a,2ce32de) +,S(4a683a38,21261e28,2e0196ba,d9f8727a,f7bcaa4c,afd5e686,6c7cffaa,3adc7774,b5aba4d0,ec3d9aa4,39b37f0b,15f40fed,913af371,b1b94f20,2cc93378,954ff3b0) +,S(1025e16e,fdaeccd4,436cfd9e,b8ee1614,53fee046,e420296f,53cc2e5a,bb5cb3c7,f806b96b,67ce92a3,e159b807,58f38f73,704e4d8,3bd611c2,25314400,f0c48f3b) +,S(6149d809,675a5353,6fe2217b,7f6777c7,60039cb3,5a0840e4,552e2ac6,db6650d2,e4ae636c,9a9808aa,4f49b03f,bd12f786,c72f07f2,9e397a11,68154505,b1a96ca9) +,S(ba24112,43888342,54ee8327,4bb03dd3,2fff3edb,4d607047,d8c141d4,c3fec47f,8a6bf123,29c3fcdd,38e6a18d,ed28c8a1,3717e997,9d0c366d,aa640dd,bad5c35e) +,S(c20df096,3c7cac7e,9dbaa259,538af550,35c00550,94ad4993,2190688e,7856a961,491e995d,16cf7ae9,85b8dd8d,6a5890b8,fb4f2c42,aea7c33b,ad84835f,b245d40a) +,S(6f53d8ca,4dbb4d72,d9ef3dcb,93dd2ec1,aac9f38b,1b4cb2a5,c76449d,4faf0c50,6784a02d,f449beb7,24156de2,486753c0,77bbecc3,27caee12,f7888687,4e7ae24a) +,S(e57e78bd,71a08f60,51c8a046,184757eb,6364ae0f,8eca86b3,51317712,737bdda3,a0623c7e,8a535f66,57116c82,da77554e,31a1d263,28ec0e8f,116976d0,f4385342) +,S(f52f6f29,aad496ab,9e0abd0e,a7cb53a7,7853e8e1,a6e5ffff,285e97c4,f7ab099a,3df7c1fc,6d5c5e81,8b5de4b7,66f2995d,c361511c,198a68e0,b7196204,559d55a3) +,S(da74f5fb,5c0a6d09,6fb26268,b33d9c86,ec5cf08d,8bd65fe2,59f836a7,3efb0dc3,7e50e989,de5e2847,7e31c816,42a51edd,8d0ea031,35423f3e,ffea07a9,48a62c47) +,S(2a2c9aa8,7bd45217,f341d35,9a9d2de8,35d14414,cfd3eed8,a2337a64,e051f4ff,bf9efdeb,99335f68,a01fd7e5,d8aec9f9,49688221,59d18bf8,a466c6ef,9648a1ce) +,S(2a3440b1,91dc5314,c6d0da7d,b07e2cf3,7d13bcef,1ebfd23b,492ad632,92022266,bdec24f5,c993a020,2f2fda24,e8707947,e4c1e9f2,2c34efc6,dd1e62d3,e2ae2b40) +,S(a3a9bd74,3d1d36ad,fad36e8b,d5544500,e0accea,d53d081c,28740109,e10942a2,cc33decf,f8cae7d8,dedab1fc,ea1b4c16,2cb71104,ff75c16b,66db334f,ec794ca0) +,S(5b83d48f,70a2f212,93dc724,77f4d87f,80db7eac,2b08d70d,308953d1,88804950,f78c0488,a10c66c2,e11368d7,690fcc4d,982ecdb4,7ed539c3,30d4b14,4248b545) +,S(dd5b46a5,6e3e4a22,39e210,a871db8e,d901ab96,3c6fec29,4140d77b,be9736a,d9b76eba,ebdd45ac,35c52268,ccd35df8,9e7136ef,879848ce,ae647c13,d421d46b) +,S(2f74db5a,25486127,6236bc5b,22214097,d1ff781f,3798f64,62cc6dcb,3f61a6d3,b6d635ed,256f6d2f,a91b868e,a3014db3,64647147,ac89248e,ca983c09,53149c1c) +,S(32adc0c4,1f7c939a,58640b8b,fde1c8ba,119bff26,dfe4b0be,c5058ddf,23ab2e09,cf317248,7f0bb297,d7d7772d,2a01d917,40beed83,3a35a293,66bbb0dd,3946ae3f) +,S(4fe53ca7,172da8,272a152e,d74c07ed,4e336cb5,85cb2ae9,36f9f301,87c6cdce,81f6d1c4,bd711c16,21cc2986,916578c6,baf42870,58b84843,27e46e98,81e3a8ce) +,S(601934f5,577fa2a6,702f316e,b4dfed9a,3b08dc06,5d3e58ae,63f8548d,9fb2569f,6df7d882,4360fd7f,b5f96f68,93b1f1de,55e19690,f6acf954,362074d0,30f714cc) +,S(79da708,8ff4806c,64492ee5,2e9dda2f,e1bec3c6,79fa3129,8173c0f7,aa79d321,2b1eca29,76f2884a,35167e8a,bd2055af,44be734b,b0e0847f,f90abe8b,17f9a47) +,S(602b8209,c39f299c,bc208b51,ca8bf691,5b8d4fc8,d8399186,7e589dce,79262974,f8b6cda,5d7ca83,6aac43f9,4791a5d8,a5ed1f05,af90f5f2,267cd9da,567f5555) +,S(57a4f368,868a8a6d,572991e4,84e66481,ff14c05,c0fa0232,75251151,fe0e53d1,d6cc87c,5bc29b83,368e1786,9e964f2f,53d52ea3,aa3e5a9e,fa1fa578,123a0c6d) +,S(4f9b48f0,ae9df110,70c4c5ae,2b012cd6,4599063e,5bd32b54,43548b78,6a06db2a,d5a7a0fe,3cafc78f,66f563eb,f6fe42ae,980cd621,bf18aa15,7bdeded7,dd5ea016) +,S(e46a5308,4b11349f,44661589,38bb663d,e1910aad,35de0708,5a053b5f,6c5e7375,da46da88,9583632d,fbf923be,9f07ace2,cb8c3d2b,fa6bfc47,9e1a7d32,e1183ce9) +,S(3643d766,b94b161e,323e64de,3c925040,d62f2ad6,2b60a674,15c8b962,1c071ea,faf69af1,1f2b9e05,db29dcff,a020f6d4,80835d4f,83d35a96,7aff1b5b,9f16fa98) +,S(96769694,c026152,1bbe1b48,544e05dc,e6bea57b,7fa31478,f6ff1b1b,bf497dca,4eb5a6fd,7d0dae14,9673b033,bd97c08f,8210fd12,c759293c,40782702,b3e30b03) +,S(2e41def,2c479931,89be0ff4,b4110e28,7f80fda6,f4134ef6,5c867e66,59a24d07,26a14d7b,b8388b12,a3ba1f50,e56ffb3a,69bde3c1,17441f52,158531d,c874c313) +,S(f39d941a,f6eafe0e,9a44fbf7,71eb63e4,db94cbf0,854a837d,b7f284c5,ac03c29b,1ffed770,dac4d12,2241f8b5,507e04b0,72cd5934,c03b0183,d8b62e73,8cbd7b73) +,S(90900d34,4576beea,911f8dc,c2d90625,1cdac045,28017d1c,59576449,50136419,60d38bbb,2a338102,da044498,a2b2c5c,1457cee6,eb34d666,b0c0956a,48161ad6) +,S(3a5e4627,1007f4a6,2e744226,f1d2b782,44a523e3,97b6509e,e3e1a513,d8ac2e06,50f01fc1,74cfc3f,256dee2,fa415f35,bcdfcfe,57b79d90,f75226ba,e8202449) +,S(f66ea256,f6d711e4,1ea5492e,f6f6e46a,b13ac258,a8f0eb87,a06b6c3f,13e24355,fb8a1c47,980ea6c,87ec2401,4c0f6d2a,8f32a2a0,6f3fd0b5,7fa00307,26243841) +,S(cada0520,19a16ccc,fbb6d4ed,6c7436d0,c946a485,ab3362a8,5c62580b,d3038fa0,e249940a,34804324,ac706963,91ae7393,421de971,af0f203,2b5f2d21,7d32ae6) +,S(d16f5b5e,820b7295,96bd5192,9dd830b2,ce208413,5c2db712,2c4e75fa,cb759cf1,70edb084,cfbebcd7,ddd36380,75e05147,6ecdd585,e228749c,e61e3784,6a448ed8) +,S(bbccce8d,dc6bae0d,cb6e5149,8c666f31,3dc31ac9,d4d949a4,84751134,d5f71535,4da772fc,63ff92be,5271b479,68e7bbf5,c8941f68,989fa6e,a23ce5ad,23f91eed) +,S(515f28f5,cd8b75c4,325e940d,6821eba,e7d5d2f8,e836b291,5f606152,ed4243fe,a13143cc,f5d2b8fe,14a09f46,68229258,e1855a82,6f7db2a2,4ba2f1c4,63668b47) +,S(bd2f46ae,a78c462d,8691ed6f,9d381278,68d356b5,b8fd7f79,df6ed845,21233837,8f645ed3,f3cc803f,7eb32f70,ed7d6fe2,84ddd9ae,62ab8324,b92bd7c8,79c4af11) +,S(8576f13c,c3d32122,69e10b51,2011a450,4f8d7d3,92e0f133,47d7d65d,f9e37dfa,fbbf2048,3fa0e131,2309eb8c,19eede8b,86ff9028,45b66195,8d19d903,f68b1a4f) +,S(70be1e91,8fdf4e47,d73f262a,bf2361fd,763a83f2,d31cf41a,23b8c9f3,8309db4a,82f80575,e4246ef4,c13fa48,8892943b,a1897ac9,dc3ef188,29f3f708,428bc573) +,S(bb8a093d,1d586b53,9bf54a46,1a353af9,173529a,12312361,c8064e91,4b41180f,460e0ed7,8456a251,cd68d66b,ccf5de7e,28707540,d221d65e,72334d85,af478269) +,S(7817ae4f,34d9194c,f4b30628,7071fa1e,7b976a84,754c1860,6dc4a124,bc5c2e69,25f4ec56,c4e3b1b5,bc6ed346,e4f8b340,6afe1c0c,f84ad7b,481be5dd,2cd55cbc) +,S(85c760dc,411f59fa,6feed8e2,a0e5bb5f,e72af5f1,2734c9a5,bccfed11,bf66abcc,92583db0,b57c9c71,bf0f1248,23a67e5b,89a8910e,6500e8ad,10666b26,cbcb8cc4) +,S(20d80d35,4d9d762f,f2c739e3,b1e7377b,d9ee7123,47ea979a,d4c81abc,5d5086c3,6e191d7b,8017a675,e8123b7f,1f1351b5,ef6ed6b,1b225cf7,48941df7,62f0efe5) +,S(3306922d,43f2c4b0,65f6d9c8,d1289804,ec26cefc,97090fde,86dc3e0,fdba5657,98a8cc9f,c93dd7ac,7079f76e,fa1c4065,86f0e941,9f87cd88,1b865c30,13c7efc4) +,S(b35c7597,54d37f12,440f7703,39223681,8a1b9aac,b085fc1,8acde6c7,3b2fb001,484b90,69b08485,95c58ffb,df5968e,2ea789b4,6f93d660,a7af6b75,13cd649d) +,S(9bd41b53,7f8bc303,6cc9d010,45922b1a,5c647f8,e90fd587,86ef0975,474e1f33,590afbf6,55ece125,da486bfe,1ff389a5,8b866776,8d2013ae,c25d03bc,bf0274ac) +,S(2a3a672c,a9b3aef0,bce89703,a38e0dcb,6950d93a,7359420e,5278f160,541ded42,4c3a94b6,13f3383d,b908ebef,6b62bab2,c95f850c,f88aea5f,c6af3b89,c2693d8e) +,S(31ba6af2,a2d94f8,d4df3800,353806dc,c8db945f,16dc5bf6,93794382,58f74d3d,ad19dd02,b290eb1c,ba5d915e,f60344c5,fc1e6a82,c5427f4a,236238cc,2329df5a) +,S(fa2199bd,74b014f0,5df0f9b8,ebf44a98,587c0251,e9c49bb0,5bb12952,bc869720,4328917d,6efdf5f4,b0f5c483,860e1e9b,41ab6ee,b1f5631a,66d2d213,b163f45e) +,S(417b9046,c7f53c0f,5ccf2847,692ab63d,8aaac02,e3bfd99f,30a469a9,8be22d52,78c15e65,5f309788,dff6eae6,91706e00,7aede9a8,3bdb08e0,d495d6a4,863b82c0) +,S(56ac91f2,47d51fd8,8a0e6eca,67a69ffa,6158f498,1714964,f33e43d5,6f18bc2a,351b7d5c,9e1b1a4b,717c518b,37b81c64,429beeae,26e7a740,c54b1a66,dd0680c7) +,S(aeba32f8,83307ef3,152d835a,a0babec9,e164ae70,10c90250,68507d65,37215f8a,8d747d39,35cf5f2e,6ff16557,7ccef843,7ce7e3c6,a41cc40f,dcde2ae8,582c4e21) +,S(42c7b219,9af00c97,693d6bcc,256ed047,79ee10eb,e4dbe63,d47d681d,21db5813,a15fb708,1fb1c7cb,2ce44a4d,f8958432,a5fd875d,1fcf7c75,c3c4865b,b219378f) +,S(4337b297,ecf365a8,88bfe19d,1bcd5fe,25e0dba2,9c39e2c,36ca116d,a24e5d98,49c723ab,c6541edb,cbc83348,5e06db73,28d1ef8b,c9cd9722,915415bb,2242b7ad) +,S(18998c76,1481932c,e968af0c,eb84b250,aeefbf25,27e4ef84,a2519a1d,b7f857bf,455ebc85,64518443,5cac9ae7,7f3289d0,91133054,d0bf9ba3,9b7c8128,26c97fa2) +,S(64c76320,fa24572a,590516f,1bfd8b4f,87767b64,1e65588e,69cb895b,6a49b2b,a39a2a5,c4795095,a03ae76f,86825ec1,78366c8a,8799d395,d39fe8cf,74b9603f) +,S(41657405,e35eb87c,a5ba5f2d,3c6f12a6,dea917a3,3b3b44e1,ebbd3bf4,812b0ad7,8e2169ae,36f1452b,4577fe78,7adccb53,4d0ed75c,2096b491,6b68dd6f,95ff815d) +,S(aa200fa3,768a4b89,16e110c8,f4a6315,7bfd4a11,2c10cb6,8b76e30d,c0391f6e,567bd959,28b21555,dfec898b,d7d198a8,c49b79d4,6905afde,7fb3534e,a584695b) +,S(7aa78328,841d2f54,b843ba48,c8c9c623,eb529bd6,9e584966,555f9bba,77131599,6b4a2715,e4b8478b,24da7e7a,64e2f6f1,32711246,29a583ba,1bb44af3,69f698ed) +,S(94b1a7bd,6a2767ff,459234f,c78fbbbe,48446b4f,64bbdfdf,dae34475,396969a1,8f3065ef,2273a871,dd29320a,8b9aa41e,e77e2178,e8b8854f,df1e88cf,991cc33d) +,S(6b957ba7,1bfeebf5,294c8cb2,7681e0c0,5407df71,37a34710,35fd98ce,d526573a,67e4808d,3fc1853c,5e5cd4ff,6efb5092,35c6df0e,c0a5f7f4,583fdb88,7a2724a0) +,S(8b274330,ea34100,3be93892,ab1fcb2b,f9a6dfb6,80bd9cb2,b8aa6916,43717f7f,54fa2abb,77855883,e627f828,49c71389,4ed141aa,9c9cda3,c99afaf1,7998db90) +,S(d3f64f9b,67362339,491274de,77ac665f,3b686372,499a12e7,5d145e26,7b58db05,c06116c8,52bd15f4,145284f4,3899faa8,9bea5850,4018310e,5c82a050,c9a52449) +,S(198926f8,ce0e4329,1bb9280,390f795e,870d071e,801b4d4b,c4aeb555,f237ba79,76125bd9,5b8d07e7,5e27658f,a0dcf10f,5d6c10d0,4548dd76,a833f206,d2b3d34e) +,S(1bbd4d,595152f8,39746cfb,6ddc2584,ee4358fc,6f878309,9adca58b,cf01a13f,18f534de,cceac5ea,7083cdfe,3de5ebdf,ebdc70fc,4f0856e0,b587e9fc,df8d7733) +,S(88737f45,b2639272,37cb551f,52022693,52457f,21db398c,1312e275,f5a3132a,79a5672c,2895e1e8,4b1a7b22,21ba0c5e,e3e61cfe,c95aa029,b2a179d,e0c496ed) +,S(cbf3e18b,1f277773,34cca35e,8fe1cfa9,2d68497e,46e7a252,4e14bf,cccb1e83,db00c395,65bd456c,3c9d242a,5f24748c,7b91f770,926ba9a4,1ff5c94,86bc3f99) +,S(8070ef0c,f186efae,5f9c8846,72a93a98,8ab65b20,2720893c,40b1a641,c7022f70,da9805b0,46946a05,46824cf5,a87fd838,cc85c853,a745d8ca,a249d881,127bd9e5) +,S(acaf984b,8fa45dbb,e84c5064,8b6fe23,5c57dcb6,21243e21,90286980,c3f71eab,46f4ec16,8259fa2e,f144dfb0,bbae2907,801b8c1d,f17dd0b5,d1db3bd1,2ceb278e) +,S(2893a05,91f9ecea,735e8a32,a57e3d25,e8916252,52a44099,4eeda971,fbfdc965,6ea29941,91e4b123,12b5186,efb7d255,372aa6c2,aaf12a1,8c3b15a0,7bcfbb6a) +,S(64974631,68f0cb60,9c926e28,5ed12df0,cfccab0a,58f11b39,dc05b644,c2be951d,ea74181b,2fa885e2,4344bb21,9f2509c7,d432b5a9,c178b406,160489a,31eafb7c) +,S(b938443e,513394c8,b2d4f7c2,9811039,918621c,5d3a86e2,d1bf0e88,ba1faeef,af47f2a8,c7d98642,50784f38,45ff9414,c52473c8,9b669be0,96387daf,c353fc85) +,S(bd1ee245,ad10f50e,9f8fd4a7,876346b9,24f4758c,cf69bb8d,42f6dac5,9d2a5320,776e2e3e,69d88d5,c26477ac,74ffe92c,134ce443,64b39518,af787348,e0039605) +,S(cb7ec68,805e855f,17e7dc05,4279d8fb,6d8e1320,67a486a9,7d49df43,c660650f,f50790b2,84c04103,11f302eb,71525fd,b12d7339,6d259b5a,91ce4fd8,229e903c) +,S(ef07cf7e,affbb5a,29e22a1c,7c84cda7,1968c615,fbde2a15,e1c1211b,ab30cf83,98f4a6c9,422630d4,103fc2fe,e4c80f2c,2ca5565e,25859979,815c425c,70ef574f) +,S(4ffc1948,4d7fcc59,ccce4ca0,d11400f1,13dc5064,8626781,4eec26ad,3e7b8fc6,be9ebe07,98ff3d83,cb5ac107,5dc87f12,d94b65e3,937ee669,61b4e587,7fb75aa9) +,S(cbdd5373,339ed493,b8cdf0ef,ac6371b0,fad1ad6b,2da4db63,b4ed68bc,61d18396,527de487,c3212d47,1f538b6f,f709c130,3784a7d7,c803e5fa,c77bfa1a,d6bdb13f) +,S(ea035b2b,d8a1d7e9,db7f6b06,5e003f99,4e650aa0,e3035fed,65e7bf5b,c67cb5d2,aecb4370,2219f488,86772e91,afe81c6b,2cd57e96,2a3b0edd,dbc64608,8c3761c4) +,S(de1a4fd6,c1d6240a,d6e9dda6,b2d43fda,911648f6,901ed0cd,99ba8ef5,99f8db89,effc94d1,61c0ff41,d1ca6085,371e2e62,f85f90b1,542d2cd,3a4223ea,884da03e) +,S(2e644141,e8d87ed6,e1215787,8bcffebc,d75e118a,f00fb7f0,e58cf5b7,e6a076ed,4aa858dd,f2ba62d8,6b8a7011,26d22c2,b45c240d,f65f85b7,320e80ff,cb34b8d2) +,S(3844386a,90d6b878,90fb78ad,8f2d28e,47ff8879,2d275c3e,956883b3,71b73a33,f7f5df12,1a8149c0,75f6bde1,2ca8ee89,ff284557,f17cd57c,714fd474,b365cd18) +,S(e1fe9b32,1b91d362,2b618cd8,9ae8203d,bde185e0,bab2fae8,ff7e96f0,74358e42,c590fe90,1797132e,a25eff10,f2bf2a76,cef4f064,acaba1d5,f8537b4a,ddf3e1c4) +,S(560a00da,2f57d821,b6a0144d,45898af0,aefbbded,a1e08a49,9cc727c4,b27a3c0b,64874e4e,39db1377,3bcb79ff,983b152e,5db86d63,4dbbeeaa,a8b0112a,e795e208) +,S(9f33fba7,7ec8de2a,c1b16424,856e2814,1afe9b1d,bd0cd1dc,e5cbb2f2,f379094d,97cb8cd8,1838e2a7,26034f19,b5decd61,d972abd9,bffe3848,92fb0a9c,26fe94b0) +,S(98822fa8,24057512,48f9da04,2a0cfb15,e46ee253,e06a1226,da75047e,72d7a1b9,3e9eea35,7bc54ac,da547561,1f9590f3,db975d4c,ce7c4cc2,a553df14,feb19285) +,S(b814d1ac,4b757268,6ad88327,32f0f84b,bc72875e,7e21707c,c4086a06,ac1dbd88,b6364488,3749a122,401b8ab3,c4a7b8a8,c03462ff,18d69c36,cf145299,f18a98) +,S(246484c4,1e42113c,cd39f7b7,eed9dfcf,b39cf842,85c28cd8,6233c1a2,bd043e97,f35025b0,2e31bdd8,41d36f7,9d0b75e6,80f431eb,44a50502,3877f5d0,eb9552d3) +,S(9f330365,7b41b2ec,d87fff0e,4284e4c3,bbe8c524,91d358e,847afb98,ff51db91,4b9a7bcb,221c8870,de176a43,d4f7cce5,adf519c1,75613dad,317f4337,72d5e70d) +,S(c2e78e9b,3c75433c,5f5623a,8f5a4dc2,b0e71951,4b16161c,225b9bca,9d529d25,1e75c8f1,938376ca,c6387b20,9b24a2e3,e794362a,d62441b9,50588a3c,ab9079bb) +,S(89340ec4,b6e81b7c,855c9636,b548aeae,2125c40d,2907f86,7ce5e6ba,a7695391,f739a94e,263e796d,df1cc2c1,3e2bc10,2b2a9c9d,55248671,575c3ea3,792c72c6) +,S(9204ff15,f1443cc2,78facd4,8d38a6c3,5d66a93d,8fd8e2da,a7e2bbe2,d6629d22,2b9de875,456b50e9,6205020e,c293ff3c,13120555,82727253,be10263a,7559c019) +,S(f156da10,41122fd7,ce6b518d,c325f5de,61fad9e4,a7bd684d,7abc495e,ebff04d6,c73294ab,f4f2adfe,dcbaa78d,2031a5d9,7f2c404d,739f5703,76e46a0e,1b631d4) +,S(771a2d78,37d6413a,13099861,6050c362,2c379a55,26506265,9fa7da02,3280fa75,8b6bc39f,5cfe1f5b,82bef0b0,f6c8dd1b,e4270304,d5bc70f6,6b600b26,5d4c9aca) +,S(14cd58e0,36bb2c59,f63b52b1,f40e51cd,aec29f0e,b1cc0401,8e512366,85a18f69,79c254fd,ed354641,744c7262,39ea4e8f,ea15b19e,746b372e,f270c8d9,9c5e2006) +,S(e5f54077,1060072,5800bff1,390a67de,cd539cc9,52b6b43c,22bff27b,1a8633f1,d6e1c6c3,9baa86c7,5838e691,f9af8a06,80274da9,b0f54b5f,4c3b2028,8d666367) +,S(b0eaaf42,9c072037,fbfd14ba,79693d93,6791344b,3d37c3d7,5b8eaf8a,e7429197,d72661e,4a171b65,4f124d9b,d0201710,bc237382,6a2f0341,51051716,9b7af26d) +,S(e022d70b,44edaed,35957383,284e4ea0,5380f92e,cf62ce88,3c2e11e6,604d67c2,423c55d4,3ba0ed0d,1455228a,3153e9c2,7aed89b,2c3ddc71,52d2b11c,91ab4143) +,S(92a2d73e,b2eaaaf2,65a70f07,b949511b,af1a3eda,9e5d8651,349a665a,4bc5ab5f,4492d419,4794d254,9a089fff,53a32631,5f1703c,5ac34049,92d68121,e00fa973) +,S(43409686,de50a9c,cf35ac44,47a9ceeb,b12f102e,3ee6003e,c96235a9,8db9cb30,2f781040,952e1017,8e4e38ad,bd9c6c8b,c8e1e898,7f316cb0,37d2cddc,4e10bba9) +,S(d349dd1b,643f8d4,1b83aa5a,d735dc4e,94542643,3888a4e1,aaaa0ade,2394cd12,67f2f057,1da2b6ac,295c71c9,ea00efe9,cf082257,ece35bc6,72adece,433249a5) +,S(9a909a95,7fb87ebb,35f6834d,272d8ce7,babad39d,8f8323d9,c6813781,66dd10e6,ce3ead1a,32771a28,7f624835,2a2f6001,c12f16d9,f7093cec,86386572,a2ddbca1) +,S(f38b1e18,df2a2a64,9a3be25d,3686b5fb,1d77f971,1214d452,a67bccf0,ac07fa0b,5c9e9a,7f71b201,ba11ced5,9c0a4623,419a20d8,c488f9d4,591671ef,71e65ea6) +,S(42360fca,26b8d095,df52738b,c2762ed2,7b909784,c12b79a6,a86e06c8,31535a67,6b6f4ce5,e43ec003,be88bc43,2bddc453,db93aec1,657f6f66,5dec1912,468345e4) +,S(e3d7198d,a7c5e3b9,997993ea,a32377b1,b87325c0,5a002a94,53404c36,303f4a1e,72437218,ece6148c,df742be8,35fabfe4,a05f19cf,3205e65f,5c813781,2053ef4d) +,S(39412945,a8301110,6b54f625,8191529e,2f93db5,bd68db48,d6bc6d9,687cb59b,b8db822c,60f5c319,18b05784,40a958b4,e08b0a80,a1015d9f,d2826506,f250f08d) +,S(4d275f7,7e0ee98e,76b857c7,ed9368ce,d93dc914,d54ad4f4,21d2c097,cd241fc2,ecb803d4,9b502911,f619d361,f952ab13,935448e8,90cc2f05,277e48ab,a39d7473) +,S(29364876,c1db9cbd,a3efcd5b,6599ed59,160b145,3c8a9e03,c013f807,869556ce,2bdb4af4,cc44950c,84f56237,95941f7e,43ffb56a,77df186c,2dc31910,f23f6ede) +,S(7531f4a9,63dccdf7,ab83ef10,d3ba1333,6febcf41,f4b21e55,d380ee6d,e4878034,4753da9f,91d56bc2,1e9628ca,2d6269b1,e1dcb1bb,87c55e,9c44034a,1ba36ae8) +,S(8266d626,3d12feca,440dce7a,4bdf8ac1,6050ca28,5bc16777,a3d9450c,5c286e08,2500f2bf,fb8a4eb6,6a5e7e36,399f633c,96d908e2,5cda4877,5455df2c,afe2328b) +,S(66480001,4f339f15,8c39b26e,84389f87,6d5e62aa,59cb63d6,9eaa86d1,4bc589e9,a0699b3f,e3eb5a37,9f078526,375ac319,f145ffc1,da8a42f5,96c7016c,4ad92e2a) +,S(f8efcc85,8b9c0fba,605921b5,e6c89343,f641e2b8,e1f45134,86b77ab6,4cc70d49,ba97202f,7086f0d9,af5a0ae3,35d9a3c,5f4de2e2,79278834,f8b1d875,50a9d607) +,S(a5c1227d,254324a3,b1ec627c,93abfb3d,6f2485b0,1d8e2e73,6c542e09,9c992540,c9189db4,8a163bb5,6d99bed7,f38a7f7a,64cfef45,cf977da5,a1d16dbc,86ecc7cc) +,S(271b2619,a5b253df,fbb655d,7702dec5,6c85bb00,9260d893,8e050606,b8bbaf3,58ccf3fc,22cb8f27,dcdbd174,6abe5591,72bca7e5,d5af3bd8,d86c9a49,3ecd2ce5) +,S(c9e1382b,20c79741,d81800c,e721d4f2,1202ba30,92cac36a,d90c1dfd,570ae16,7eb1fcab,2a47cea0,3a92f707,d799749,6f7a0dfb,f9a43f6,90d213b8,1231e5b2) +,S(574b25,65232a04,1d58cb75,12b48945,45897e6a,8bd47dec,b1e0941e,309f2,bbfb86a9,567d74bf,93fbf2cc,6a9c9dd3,474db8fa,c2b5fb72,38b3af8,fe4615a9) +,S(9efe86ac,a6305eda,4b520e00,4dff6c56,1135e7ec,6953d2b4,a988d508,63046c38,4f92a291,32cb0818,af7cbe67,ec3b4d8a,7afa4f79,91a9ae42,551ad831,aae9af70) +,S(82ea48a0,ff76fa17,374bf4c3,d0918e6a,df26cafa,33d87284,13aa2dcb,d813f254,6a029539,9bb555aa,39de1ca1,417a8950,49b4c2d6,26ddf8e4,a7086b1d,bf2ac9f2) +,S(c289483e,817bb06c,31352a24,ba60adfb,e3af2feb,de329f4f,5fbde755,bdd2baaa,3b7ee90d,8b4aecef,62b6854a,1feb595f,9c49945e,c19685c0,4b13a1ce,1c780a53) +,S(6bde46cb,b5580d58,ea68deb3,1b0587b6,1698660,d78a8300,1c740b4,96e12cc4,3188a6a7,c1cd166a,4894ce75,c79d076,a41cc5c,d142ed91,e096eb32,e9293292) +,S(d1d2a3ae,2844615e,57f0a11d,66fd7571,176738f,a066cbdf,4519ac1f,65827cf4,7c0cfff7,c01c196,8b7697d7,c51562eb,8271f936,5c7daee7,f963122,67f603db) +,S(b74c0c87,4d195557,3b551c85,2abf9a5c,e276b088,cfaa0be8,f6515ed7,ba27370a,f0cb0e,380c571e,fe5e307b,ec4ed8c2,6f0c325e,114d71b5,51e0f1f7,45a662ab) +,S(a9a71b9a,9f126c3f,a17c3041,2317e118,84950077,baee298f,47d42609,f9015874,c05f3ffd,b31bf0cb,7fa4be1d,f634cecf,f1b1137f,551220f0,8f34c2a6,a42e0586) +,S(d6de1153,a161f27,ddb51416,2b3f823b,2b1b99fa,3fa21c25,9b02274a,80dbc68c,6c620863,659785a5,eec15d25,9acbdefc,714fab61,4e766215,348c80bd,bc59764a) +,S(dcaa1dbc,3acdca5c,51f8c22f,359487fa,73a7dc36,2a796df,11292a74,776b73f1,dc4131fc,c22c607b,4833719b,1715179,b4b4d49a,958c7514,7c8c4a8f,cc85159) +,S(135537a0,c4be13,1c3aa93c,677094d5,5f3a1300,95499d21,2206a244,5ab6c,7ef69f1f,d2d3df67,335f0d1d,dd52370b,8f3ebcf,e3483330,48c2f045,64fb0f69) +,S(28f1d817,c23262e6,4cd572bb,e3fd99ae,751dd6e5,5e9e804a,fb3fe9d8,39de93ac,24f5861,987e3da4,2dae0e89,67c835ac,8f5dfe8b,d41e5cb0,97029b48,39e2cb7e) +,S(f7c4ef83,6e8fb7fb,8eb31155,c08102df,e0779b87,9ad641e2,5f8ce135,44294289,7f9a781,db339621,d6150f09,16eb9682,16470d23,6957a0d1,3629964f,1f6bce2c) +,S(f1f5ae5e,1ddc9b35,18b66f7e,25a735d4,ddc8d018,5112faed,a8da8f66,1a28b3e6,9dbff12c,97924d80,50a4a8df,24fe7a8f,5c5c3486,3edb7cb4,1c6d9ddf,b9ad4288) +,S(95f83173,d170ce9c,1ca0dbc7,4578b639,257c10a1,eb65827d,c2afbd73,8b654f,63a83ebc,8294a88,413c3c91,c6918a31,7d5ab83b,7bee35b8,b75d1cbc,3412487) +,S(f4ada65c,9f095e11,eb88c8e3,77d60553,96474935,91be3a7d,f8c83c09,6a3ff750,e7683f28,a38545b2,e6cbc87c,3dbcc4a5,2ede1676,1b0dd78d,3ac51a5c,ad861ed3) +,S(41afac96,f714db3b,1b7bcd59,1dc7bc24,40b82756,d9394fd0,3afe7ae4,299e5fd2,9c2e9c6a,3292ff12,426e98ae,ac654a44,61c52d00,5da7af20,474e9a47,499fedc) +,S(37f30b1b,2cb81c9b,61941fe9,cca35f0d,e1b8dffd,c42f3ffd,ccaa16e,e8487405,92bf7a85,e3401d51,d9fdd08e,1086b649,8086bb3c,a4c9a2bb,61b1d54d,8cb88a0f) +,S(2f577166,646e7eaa,21531202,2ce0c8eb,605a2199,454c205b,9d760716,584fb3ce,f0d7326f,e43dcead,5ae0dc68,4d04b969,af32e8da,ed624ee0,98567dff,3d5f446) +,S(8abbc780,92c5512b,5eba0af9,4affdbf8,3c2e24ff,bf9fe7d,fd57e5ba,64b5150a,58f5998f,c2ec19a,a495b974,ffeccf6d,bb87dec,49152327,91a167d7,f6896b75) +,S(e41ace8f,a01376b3,27c73fe4,7e57cfc,f6da7cf5,c2810aed,219dd065,c147571c,b590aada,3c2a714c,322d0459,272f98e5,715d4545,196127a3,7d8a94bf,776844a2) +,S(300c9877,8b6355ee,ddd80f7f,4124789d,7c0c84fc,9d9ebb5a,be714cd9,890f1d88,dac2ba62,c5718731,c8f5c7a,4e1a7b80,68c5076c,834dd385,20f5e93b,e39c9002) +,S(69e339d2,19d40f84,25a072c1,f7876c3f,dcdb6623,26ca1b5c,87681707,12e24c61,8d439150,59a44700,2157e849,9b535921,4cd47280,937405a1,bad0b86d,38babc50) +,S(e56493df,8e47a99f,8ab3ccf6,41fab7b4,cddd779f,51fc746d,a2fdd484,cbbdb909,68dba20a,559e14fe,d0806036,d41c18b5,9745319d,758c1145,b6e49ca3,e3f5ee59) +,S(37a91c57,8998511c,d39c11e5,86e00eb0,f76532de,574d9c61,1a34d38d,e7f50587,e3a188af,d2d8a24,735975dc,9da895,feac2710,ab9d381e,e5d1dc43,b3145f18) +,S(c5f059fb,5cc262e1,12c629c7,194d783a,6224016f,65e4d24a,86c52742,dee88c1f,1c85bf52,1a96a95a,5177792d,590b46d5,8c090705,1efa0623,ab15578f,b38c890a) +,S(566edecc,d605ceb1,a298c59d,78401acf,c6323c63,f2845827,62678924,9b8716a1,ee0d1373,5adf6f20,789f85b9,32d332ff,8c40b3af,c02010a1,5ad062d4,5a44cc90) +,S(327e7033,c6ef4f87,52e33d,bccb4642,3e6cf4e2,c3ebb4c8,db69ccde,db2c7c7b,fc49092b,2be0f29b,4aa3e266,709aeb1c,12266239,f7bd9263,4aae16e9,53e8db36) +,S(989a7f69,3ac0ac86,55f29704,ea6caff6,84ef5ae2,8c5f5e1a,1eae7009,97778024,573d127b,3396458e,74bb5bd4,4acfea64,e8eb1fd7,3b0b292b,d1b7b642,80dadfd0) +,S(9ca7672f,14f27f54,ed1cec4b,74f49a57,7ce313fa,4a665976,9c22cc61,b30fc94,f920c4d7,31d52a4a,30803f81,82df8d30,6ab14104,eeec11dc,d2d6ca0f,3904e4a1) +,S(db100645,654fe8e1,95831687,17e2721a,6097850,ed2ef0cd,e1d5555e,7847f5f5,2b2c3ece,a9c90ecf,34fcdf89,5f76c8b6,619287ce,e745014c,96281928,31056567) +,S(4e2a0c9e,82743b42,5e6110a8,f3bff14e,418a34fa,65269c07,bb94d00c,d53295a9,512ac2e3,e00bb04b,6b4b9059,a3ac69c,8a34e5ec,8dfa14b3,d98b2c4e,3cccca7a) +,S(c12b3f70,24ea8acb,5136f98,185fb1cc,60c71a77,2943b68d,7334352f,66ac77f6,b799f99b,6f4b76f0,1f09f5a7,bfbe2526,d67a195,83327323,9c07bddf,2544803) +,S(64e5a2e,daf34e1d,ebd7c0cf,616413ff,d6c09b82,bfa783fe,aa755464,8ffd7e58,e020e09,66f032e2,e905d611,adf0926e,7509a2a4,b51844ff,72651f34,3c2f4a50) +,S(2b0b8b55,fa734380,f6ad1857,e03f02dd,3d66ec57,2cfb3b9f,ef040895,3f0a838a,ac897251,a9146597,8e0b45ba,e1c880a4,147ce01c,3408e476,5bd9013d,9e73a61a) +,S(ae0e3d30,a2026133,d3a54529,965a9679,6523e8b4,1efd4c5b,d6778930,2a88525e,fb6918ff,85632d24,250be67b,339ab260,c80c087d,da1efee9,7ec5dfb5,38f80552) +,S(2ff9c711,4dfea166,ffae46cb,1f44c3,3bfa1530,edf23454,a83de862,8fe00dd9,53f667a,4441817,a3e38351,78195c5d,acb0d707,bd20e759,9b5e82c4,6f318783) +,S(cc027014,88b959c6,c043f60c,c42b1449,9e2614e4,c19f5726,3edb116a,4e7bf695,eab3f590,9b22f677,666ce655,149a5f07,7b5325c,2036dfe2,e572e64a,5bb6007a) +,S(1801efd1,3c8035a6,5efe3b47,68495d27,f9dbf45a,f019d455,84d68be8,28a945d5,dff2d19e,fcb5968e,f4ef49d5,9a82f8b,f44a5abc,e0b68568,1acbda1b,fa59c4fe) +,S(6da2a9d5,7b60962,357c09de,4c7ababd,5b698fe3,6e747f8b,e6ab78fc,3cdd7cbf,1e274e70,4aeb8ae2,295ac9f9,b37c0af1,71310b82,99acc378,d505bdcc,e275060c) +,S(7e8fc96f,6a9215dd,3bf9e8a6,ea944ff0,c7dfe23a,1a99f44c,832a11ad,bafc82e4,e9a4fbe1,e0c26ca7,f739ed00,c63f3886,57d09503,a808ed51,ddc872e3,b1342bff) +,S(a6362f3a,77d6d6f7,fe266ab3,78707641,9f53e133,718ccf27,559bb448,7e0caf64,c01622da,3fc2385c,60a5cd86,66f751b,e29d8539,f473cd70,8784d61,d2cc787e) +,S(51865222,28b47493,a3da19b4,7076c1a9,8582bd55,37c25557,44970075,9b37d2b3,f0f0b979,68638d9d,93fca65b,f40cb8ce,826558b8,52451ad1,7d0afbd0,44287be1) +,S(a2a0909b,a9f1b9c3,8c714ff4,f71995ab,4d80212,9e8ee8e6,7e8bc3d1,81d472ce,4123900b,d45ec7bf,71bfdf98,ec453392,8b364d1e,cd925a6a,1e8f5c5e,ec40068d) +,S(da518122,454e7f36,a63f5ac2,a1bf979e,f1357bea,f9f0c921,2b031f87,b83aef2d,bf877efd,d415e80,c828c5e,1b9dd8b9,6cb7f3f8,b9a0cb32,b6bd8f37,686da722) +,S(41c40c54,1a983125,e59aa572,910c5aa4,8a698306,d483f82e,6cbd7506,3947a87d,76dabb65,6b89910a,bba9f129,ffbdf5e7,ef840033,c30f4c81,4e86f101,a3bfc57f) +,S(c49fde83,87f2e464,6847c980,acc50d88,28745e4c,88a41318,709099cc,9aaddbfd,a65bc512,dfd07bd3,79cbaf9e,628be7f8,c7ddb4ee,6611fa94,bbb48c7e,ae7227e1) +,S(85b17d61,b6ee743d,4df21940,6d7b7426,3a6c6b88,e8c51071,7a1f0183,e0fceae,22b9e8a2,74c71feb,5046ce02,2f4bffbb,ebddc53e,704f6be8,92d3092e,55868fef) +,S(c8e1d37f,e6d677f1,3e752189,505639ee,3914afc2,c8d4e43e,883f5c54,f117964f,b0cacd18,d08f5a91,af46ba55,91f99497,ee4a7ab4,36ab48e4,f88ad5ab,39bfc21e) +,S(dfec0030,7d25888c,5a7d6f83,33112995,1a30baa0,b97add9,866078a7,e483836b,4e5a8a06,bf2e9447,ef466416,82af8e44,f407ca0b,6fb97809,56e13a90,bafaa00d) +,S(eac6c438,7c18d8c6,eed7618d,c9d3076e,c842ff6e,5f4d4b20,92594d7f,7f0be9d6,19d69bbf,fc0c1b82,ba71802a,c0feebbd,77a86a67,d734a163,4e823a6b,2265b8d1) +,S(9ff38c4e,4dcddec,a4824db7,97f6ac80,69432c15,9cbc99b7,4d642011,b3424cde,f72fa660,b7c1bbfe,df45b0c9,3cc84b81,266bd041,b94f54f9,1d26221b,51619ebc) +,S(5e78593f,3a5a3293,5f9e4f8c,4fe28555,9153f69d,d44b2c1c,146fc644,a5313f36,9d9d5844,dc63bdd1,b2d95b70,5d63c97,58cbc5a6,1b2d114b,89da9b9a,8afd9c47) +,S(a107c7a4,89284b6f,b01ba38b,3e221c2,ad31a48,77af9b32,d22c8544,71009ae4,66072d4,6be46591,ee386cd5,bc0f9f2b,653b580b,c515d4c4,a0fc369a,27d9f6b5) +,S(241f1d0,308d9845,fe2445ba,67929976,ff98e88e,cc23a8f4,190ce5fa,41b02af1,886697ec,d413a88d,fa15723a,daf91d32,9c881ee,c5ac9c74,366b7ea8,a7e194a9) +,S(319ee8d2,627f906e,83d5c6d2,6eac3b42,34186016,8b9a9283,c8790c6b,e48a72fa,59e496ed,a67816e0,3409f849,1cb458c5,76034453,65fb281,9d0cc427,3e9eaa57) +,S(1866811a,fdf9bd,937f4f7e,96985759,e0100866,192878e1,a2614625,bfca4822,215e0465,e85f9c88,2783a131,6b65fa7c,585f0319,1a642501,72e51269,d5b7ae19) +,S(7effbed7,b949000,5db429fb,8cf64099,3989675a,f7394ce6,9ff2f769,53992f26,6efbb5ba,28f26d4b,5256affa,cbf2dc0b,616d8b6a,c6cd2aa7,a1d09ac8,40c7c749) +,S(d8c72bd0,e59315f2,1fee45c1,937952b2,665c8d66,70f14bf0,957a4d25,2b168867,64c02d62,fdd40a6f,d11e2cc3,a73fc60a,8a2da31b,2c99ae6e,5a946c61,be56fbcd) +,S(710ec622,ce64f381,43b96bbc,b0b0d691,87bbfd51,fab4d47a,bcf18308,18d0db4b,edfd1086,526c3af0,c2e9b961,890f531d,3d275c36,beabb0c5,4963314e,4534d994) +,S(9427964b,9aeaedd4,9c168e76,38086ddb,70574f27,9e4c3348,68e4c595,30d51ca6,110b41cf,2a6b0067,eb3b312e,928583d9,e0026bea,684c57af,7300a611,5c4e2dd8) +,S(aef79435,a8b3ed9c,9eb515c0,6db62165,c5a2e816,5eaa4a5c,46a59b39,8f55565f,6616e8f2,1274c425,c50cb93d,8942aab3,3653511,3c3552a0,118b17a4,5584b91d) +,S(3ebdd832,3546063a,68f40193,59d72f26,f49f0ce,4a5af994,a4ac67f3,3074b5a3,12367d4,b29549ee,d0eba318,f395d712,db7962f2,c8e2d9be,ed895006,78460238) +,S(a38d9e5e,c52b0871,d0bc6bc3,b673c848,19af86e2,534d60dd,729b405e,426aeff2,ebe46771,d9ae6c5d,13895538,3c8de4d5,f6d13428,8ac36a1c,b01c75e9,f32cad02) +,S(e7d29f82,619cbb19,90c407f7,b452cb8e,334369a1,16901b0f,9f4ec342,48a7d624,7595ced4,618b5160,6b8ce230,45d7616f,15b6ce14,aa8eee07,42bec5b5,9fc4e614) +,S(ec869eb0,279227b9,4ae333e2,6018f00c,7523de5c,e3e8c4ed,f81cefcf,4043ceae,a421aa55,2c89c841,a48bdd26,4e67d82b,ca3fe577,64101556,ec6ba7dc,711ac92b) +,S(4549d908,e44a8c8b,6fc5c057,144a352a,6f07523c,e026fae7,c070ff35,c6ec5e71,71d8e320,7707e04,10208c19,e2c8dc79,64b48600,1a6d640f,44c1138b,7ab5dd7a) +,S(51bb6e9e,fef7b8c9,b0a4f381,3e1406b3,2cc7a53d,165b385f,f98144b0,a5b070b2,65282be9,dd794fd0,8a31de11,d46df7cd,5268eedc,aadf3bef,de5956b5,a467044e) +,S(7cdc3297,4c7caa82,44203afc,d48e625e,aa2027d4,d91613e4,5a83eba0,696d001f,b92b9943,3b1a55b3,b78027a7,a289e5a2,6060a411,6c2cca36,19253490,83519565) +,S(3ca9c6be,b8e989b6,a67722f6,d817a6be,aa478fba,10146fc9,3099575,609c9314,5502ed7f,f4b81bc3,8386bba3,4124ca30,74c6e0da,bd148e4d,6bb7f096,ceca2c0f) +,S(aa2abe6c,45edcada,f01bc1c8,38ed5e63,90e1a229,cc920436,864111e8,ad354d0c,1b8229c6,6f91304a,24c61251,f1ba2b26,95bb3da8,87154d47,c44dc9f2,f824f6cd) +,S(b52cae3d,f28c9d59,319f226d,ef73b60f,75466aad,fbe6f75a,2ab6936d,8e3bc7ee,ebee735e,22c091d,cc873848,8a7c958a,421e0759,2e17fa3a,4462db88,8bcfe220) +,S(c1085703,62a6dcb6,13da6283,23496169,635469c3,47b65661,838d9053,3821ef54,fe6442c8,c1e6a8eb,2dc2cac1,40ad4c7c,44511cdd,82b79cde,c38cf9b3,4ceaf517) +,S(f09e9d1c,fcaf127f,59d45476,56422907,83477fcd,2fa6c768,d5a3965d,af08c11d,f01a722,1f44fb15,bf428fc9,c5d7efd9,a5b2e663,cfecc9a2,7e8f964e,8bc15d10) +,S(602462ef,1e473ebe,d88b3b17,9d71b597,fd3e805f,e03d341a,36c277f,495c4527,f91db461,71411dce,aaad9f23,53f2159e,fed2a9b1,eb9d2ce2,844e1f6d,63a079c3) +,S(273a881e,8e0d99fa,104ae355,8126a20d,6b828d13,96bbc70,720197fe,9bb582d,5bb26c58,14a7b914,cd3b2f72,7f76b6c0,d1b40775,79a2c3da,29534a1a,684b0d5d) +,S(7c1df346,616cb72,b42f4172,36fc98f9,e8cd0504,1da47d9f,566c8df2,e80cd54d,ad3e7e0d,d602b9be,45ba8d45,6bc12558,73153c2e,c16773b9,390ad630,4fc41dd7) +,S(796e2634,657ff114,7394551f,3ce800b7,9ad644b0,539786d3,c62c6551,3d942f94,b65bbe38,ed587111,c480eb9,c30081a4,1e8ec66a,8400db11,bb1cc7c2,a14f1c60) +,S(5e2761fa,9985f68a,a469953a,2a6642c8,62b0565b,602fc206,193bded6,1a302bd1,5ba09b70,9db24f5d,2f47c07,51367d0,3715c9da,b7d430b4,713dbac5,7253e274) +,S(46458c92,fd341a0f,eb1ab038,5a246b40,5c004c22,98db90e6,164126c5,4fabe794,859d68b,345341b8,58afc324,263f1ca6,9d018fae,eecf33ea,f02a3dd8,d7446725) +,S(fc481830,bf817c1c,ffc9ddc3,d6f4e624,a410e134,cbfb952c,5c7379a5,81153265,a188b228,bd3d7da1,44a48e89,fd9db4ab,8dfe385f,ace8e169,a43a2787,59322551) +,S(42d9767d,9771a550,3c702742,ce2aedbf,3a780466,804ad901,7792610d,5eed03e6,df69432e,9764f337,3a2c782b,e02d2433,d2e0f568,d0dd83ec,e89ea1c2,5ad50417) +,S(37122c49,993ab297,72e60222,615ed912,462deefd,d28e04dc,dc72f4e1,b9477148,627ff4f0,924cfbc3,aa0422cc,36402b8e,410b3ede,a552408e,f1d3820c,5996e39d) +,S(9c548182,94bafcbe,743e52cc,a76e1ead,3619a557,a5cb8bb7,3140ea1a,5c6896c3,5fcc472e,b88e8528,ec71dafb,f70504c2,ec0478b3,209494c5,b53bf05,b38f7fcc) +,S(7b9d7ad7,aa5b1f69,75c4e025,17123608,a59277f,d63f2a07,7ae69b80,f65a2db9,6cde1ee8,714aa229,d01c14d6,f514ecae,c4a7f15c,a756812f,abfd61fd,d7d1bf8) +,S(af5ddaf2,c985560a,d656d948,e41e082e,6990e950,6c77d53e,171cdea,58a9a102,e348451b,72896ff3,c4839ff7,6ce16b59,1f685348,eff943f5,fd4581f9,eca5b505) +,S(42667f18,e957bd19,5fab366,2e0d1565,d26394b4,14e2a9a3,95becb69,2111293d,288dd2b2,69e9bb63,4e7fb16c,1fe25797,3c0076b1,aecaa2a2,e57020d5,66bbc7a5) +,S(5e9c7a1d,50ab8326,74c2a5a6,f32665ce,9be97161,5e59b618,587541b7,40b276d7,92283461,1f39af42,34292c61,2c70744a,ec466418,ee08b5b1,a298456d,5fa11f17) +,S(98c60ffa,f486b582,2b4d9ac9,7b320b97,8b52b506,8b46bc48,9a2a4f28,dfed8b2a,a1c26113,c2534955,812f42fa,306edbe5,70416d84,aedc132b,5807b29b,745280f9) +,S(92bfa982,1ed52cd9,3c286e71,f350e5a7,f309481f,d866516c,f0a7599d,c385babc,a3fc9796,c71ab4b1,b7a54e73,8dfe24f7,6f527692,9516bcb8,2fae9ed,b2c1ddb4) +,S(9be27408,bd8eb59f,ace413e8,402b0c37,7b7798b9,3bb18c4,ec197382,fa5b865f,11085580,19646a39,68eed2c8,1bb92dde,def3ec29,5024c027,f54e8bfd,a67a2f61) +,S(27cd6a6c,b7bab059,6b791ce3,8c0918bf,7751bc59,db9e5827,5b1b9c46,976350bc,890d5167,8fce2ac5,f13761df,68651e7,2f41d04d,4feb4011,a16f80ee,83faeda8) +,S(e896e14d,aaf96139,4c8f6597,a0c66463,5f22be3c,96f30e1f,5d8881ce,f468f2eb,beb004b0,512c1ab1,dc4d971a,fd88baca,efea7e84,dadd2726,bb9f2b3,b196030b) +,S(24e2d269,ac485401,634b3779,efab2c0f,a9dd2389,850bb3da,54ec0d67,e53f8ec0,de702ec2,642bd4c2,3bca2ca,663a05a3,f5beda5b,e41fa460,8929aa58,219e525) +,S(97a627c9,48c1c9e4,5d50159b,4b121a50,9b5c4d01,de0a7db9,5a9d9c09,681d1676,19bd095b,55399c29,fcad4303,7f5d5c21,8d5f3cf9,a7c90b9f,fef7ee92,6f3203d9) +,S(a70d8251,e604ec5f,777234c7,f9d3c850,33ed6760,1fa0814b,40bd5370,7195b08f,df28d907,74e23de3,f152c016,ac710d43,85325a89,6a859f4e,e126d50,acbccc4f) +,S(2d676c43,4b276472,ce01a007,13d78b17,27743a97,36f3412e,a7c8c15a,fa42f42b,be28cde4,6ef5d32,403b8f94,1082b684,52fa703c,339498ea,24c08ff,c9fa7312) +,S(f66c25e1,75167275,5db857cf,cf27c036,46c89d29,b4a0d729,28fd42b4,b29cf5,3ee23ad4,22c4a884,4c049150,cd9c18ca,8d2a0231,bad69b6e,5926de9,c7193201) +,S(dba47c4b,9d39d87e,ef44f81d,24e8e005,ce6e77ad,8e4fdc6c,29393d7d,2427060,2d5c6492,e53d000f,977eedd,4dc3b5c5,5240f28b,9fcfb597,338edbbb,3d8d7622) +,S(a17601d9,4f627dc5,5895aeda,e91da3b6,94788f65,f083b01b,bfdf8815,27e10f0f,74089fc8,cfea1b15,afb025bd,99905b3a,baded5b,45e30890,fa3d8403,360a1183) +,S(dd70309f,b84afe90,7e261a12,5fb7ac8d,1c24c6c3,54eb83d5,188f3a13,4d80e141,32014ac0,ac93a77f,9d35b786,2c88ddde,4bdfd566,f6555868,2a836535,44bed563) +,S(79fd503d,e746baf9,701253f0,4c6a2f3,cadefb93,920c83f7,83b57768,87037afd,3c5cb658,63180931,3fa20c26,647a523e,86a4e600,8e8b17f,1e0d690d,eca61b93) +,S(d1aaf37d,77c7d63b,1f4eb896,16a29a4a,1e72658a,93560956,6b92c122,ba0ff6a0,e535b7ae,5cfbba07,2bdf0e0b,bf435bdc,c7cac39d,9d9ae32e,cfd13945,3ca93bec) +,S(68ff1b82,b351d94b,9b6b74fc,2cda4345,fe525d58,d6599644,5c752757,aad93c4f,abbb0ef1,c422ac08,d06194aa,c5d93bdd,9186e374,8518192b,79818f3a,b465a13c) +,S(22785c97,18063e5d,5db73bc,f4ca6487,14393ea2,62ece24a,5c41c059,9610552d,9c08026a,d7a7a80c,24c5e75c,8a75cd6e,1933e64a,25cb98c4,157181aa,ae1d8774) +,S(626cb5e7,563fb757,5f066258,3fc21762,e2678063,a77d8580,8891f244,4f5ffebf,8369ff6,72c3c3f2,43516184,5a9851c1,953a6da2,5662e11c,ce170cbc,668498b4) +,S(a99f0ef4,d6f46105,80ffa430,b88a4f28,61c8c4e4,b6fadac5,5e668f5a,80d12d2a,972adf29,39db0083,77802c40,6ae2aef6,4e2f064a,f8304d3e,28fff33e,b1053d06) +,S(b243ce27,2ff0b2db,cb80a3fb,dfbe94ab,784afe3c,cab3fe61,1931de9,c7f02645,db2ead19,fbb8c820,c7233df8,fea51836,3e85b858,4622be9f,41a0448e,360b7559) +,S(c74e3c9d,685cb62c,6a71b21a,a1dff5,43efb264,543222f3,f8bdf570,4363deb3,987d8261,fbf23d05,a38358ef,c4efb61a,5cd550b6,1e833ed4,38734486,edc4b2ec) +,S(ff2f64a7,fc984d4b,d1c885f3,4c096e9d,d34710c2,43dc3047,8886ef0d,ddf71c47,14c06258,fd5e2fdf,1eec9125,7690c0d7,9eac60d,785f2497,65e1a85a,a06e906d) +,S(7d92c4e1,3f4cab24,d36e8a8b,140f743a,6819b514,f6a19bad,ec162141,bb712085,606b5762,2ec7d7d2,a9b19330,9da686b8,3e0dc920,e6be33d1,b726f416,81b698c8) +,S(3a43d4d,9ef45289,89c9487c,77951602,4ce0cc20,ffbcd518,a0bd2546,fe13b6c,5f24d325,5768905e,6ba28d61,e6b126a8,eedad2a1,53499912,dfba3fc0,d9deb36e) +,S(8e72f02,80105e4d,15cc67e7,371d0c5e,6e59fd05,b3c66308,67342a6c,eea25f8f,94ddc51,58fdb86d,f09870da,47b79b03,1eada5ad,9bbdd509,9ea1d9de,96b368e) +,S(b89cfc23,6dc02762,ca77f9d1,8343f12e,ab8789b0,e5872d6b,fd9d013c,ccef54dd,9c9a7285,45a5996b,4a6ce6f9,df860d11,c3ad135c,f1f7437d,2ba7b904,411141cd) +,S(e85ee008,979868b4,bb190b53,5624b3b5,6744a43e,2c473ebb,c64e4910,41ccb59b,d3afe70f,9edec50c,227e3b3d,7eddd1d,e1c9a8b,f842d723,a8075a52,12cbd6a2) +,S(d8dd6bf2,774d6d15,93cc8e16,d5134066,f7f90651,39915b3b,fb0d5d93,b6cb97b5,5a203094,5f734f3f,11431862,b85e9f8b,25f7e6d1,91512b2c,6d256f4a,535e26f4) +,S(77e081c5,328fbdeb,45fbd554,5d133d84,33968ef,98d36aec,3e6385a2,76aa94e8,2ce853f7,ca25f2f8,45a6291a,3e080504,ba597fb7,91a21669,c0cb6be1,14c2959a) +,S(510786ea,e8a49682,6820b82f,549f07a2,b5b9203d,b1ad18c4,fb9c479f,67c904ab,dc130385,4e4dc69f,f63e21ae,71dc8674,b39382c1,eab1d8a8,fbd96867,af9cd96b) +,S(2fbafeb3,fbdad5b6,4c121056,e080d0c2,1169e433,3abc0dda,bb642789,a242639d,a85d82f,d9e6a14d,e599ef0a,11d3eb39,5ff199c9,5ea5f1c9,2f3f8a7c,14405cd3) +,S(200dbfeb,6e6e463c,1f3fbbc2,6b5f00c6,aec80809,1e28eae6,73b2b5e4,7b12ae0a,4852a219,bdaa3d97,83e1f071,15491827,83212776,fcd1b44a,c59dc01c,bba95ecf) +,S(27b140f6,259f7dc,93d46b6,e52cdb85,3ec22572,54218ab4,1acff2be,24b8a3d9,3ceed09f,70cbadba,d40054c4,f130e312,28bb5d63,71a74f7b,c85aa7ff,c0583387) +,S(fe4941ee,535c5311,8222ec35,14c2b02c,e175cca,d728ca0f,cd1d64ab,e95b7e71,e9cdc9ae,286d651b,d89cb442,2a64ada3,748e0ade,585cb70e,d357004e,e51f56f6) +,S(317d209b,4cae94bd,36f443d7,65be2f17,ce47ced,59935d88,5a03925e,75ff1cdf,c191495,68fe571c,ff945af,4b6a801e,c942a5df,78a62864,5434a5eb,8a262d72) +,S(f951a777,764e30e4,7705f8ab,150e9ab,df32e80b,593cecea,d9f9a143,cc93f9ea,efb951d6,25f2223e,e6ccc6b8,b12cddde,6ac2613b,11ae3052,65570f15,23afd925) +,S(71adf0eb,f5fd8e8b,f0f229a9,ffe496aa,4f251af6,6e5a284d,3091f344,3389c8ef,13f47463,293a5536,674dfdf7,2dc73add,98ed5672,e7676425,39ce655f,6b6969f4) +,S(2ea0406,58c0e80d,499cff39,ad463412,c3fbab1e,81f6eea5,911c45,236be75,be52c74,6073721,f09743d2,9a0a4e3,d82c08ed,feee2234,29163bc8,954f923f) +,S(42352390,4b3e80c2,750c4222,33f0b1f3,a373442d,96278935,d9b7e51,b6182aea,7f582349,b27b5166,30c8e48b,a9603224,fe09e8f,814fa966,395fed67,d9221d91) +,S(524d3c82,a92b285b,96064bf8,e9abe0b5,7702a29e,dc08ce53,771fab9e,fa7dda91,a47a0217,fdc6b2dc,d4b68e05,331bfd5c,366a8477,d3ed894,ec747240,f0f29c3a) +,S(f6ee1e08,5ce04de6,6aaeb5f5,f232329c,fc83caf,d16bcc48,776bae16,c056f7e8,3328b26a,7e2bd49a,aa193977,4947d7b4,ccbc955d,18b27c75,c2f6ac6d,bccea4d9) +,S(9c2f7d2b,b88f1417,722b5d11,95077d20,2ea84e6f,9bd93dae,3134d16b,17273978,1089f003,66c8b435,ce73c592,7c5e56bd,d338a4ca,ee5307da,a571be3c,2dab2a3a) +,S(593a1eb6,730fb6e5,1fd24f15,253ae1e7,5897b7b,48efe28f,9b9813c6,ca99cc3c,fcfb7820,fbd22d91,bc03a630,f74e519,9e35c1a,a3b1cace,40433001,7744f079) +,S(62ba10c3,83a7bacc,bcc4bc60,37f87a5e,8ec0eaff,de5a39f4,ef352b1,51f957e3,c267a1b0,dc84a161,a565fa19,aa0a2501,9fd01e0e,d7a660be,c2a7e9fc,cc7bdd45) +,S(1de2ac10,deae62a1,63f641fe,3a4a9da,39e12390,14a77c6a,6d73c619,5f731f64,60f43c95,b6d7969d,427b5ad,782214fc,a512b75f,a6f50006,d7141a89,dbc8d2b2) +,S(f11a5552,709083c8,83d08612,31772f18,c48e9271,6acbaa6d,a43416c2,fd4e1d3,a6d0ad64,7cf48c41,b6ce397b,38d5b3b0,2be51554,da2f3f4c,df593514,a2d742f4) +,S(f4454640,d75697e5,21d5cc01,fca5c7f5,3dbad43f,116c243d,2aeae96d,7cdc33fc,42972cef,46fe7704,5d6d7053,1a74ec87,6b25996b,c4cf66cf,b3784f79,66549102) +,S(2bfaf073,97be067c,1b7c20fa,3b319fad,10905b8d,8ecdad4,cad2ec8d,a1b8780a,ed526499,ea97c967,3d28bdee,9970f4fb,9077deb1,5f823cd5,775cc526,4e590285) +,S(fc1abc81,2b5fed90,bde3ca16,3422f73a,6df6e058,8ed69222,cfec54f7,4cf5f73b,db1c6edb,471cfcbe,468481dc,4b1cd1c4,7ac68f6f,4fe9dd8f,af0d1136,972b975f) +,S(d838c2ac,82e02f9b,a376f92d,293c02ad,b717d65f,be31cc76,12476e6f,4c506a8d,d87a3067,388f8e0,3c176f6c,a7eab123,532dd1cb,3e0f6ae2,51d7b31a,35189377) +,S(4b3a82ff,7295749,a259d54c,a9a5e539,32c53ff1,33a1c4b9,2f697e06,b13ee38c,44372b41,a788456d,3f66a0c4,6c815210,bf60734b,e570a290,32db3075,ba8d6265) +,S(d77cbbf3,6731ad4e,325eaf6a,9bd52f70,8e79d290,e379c2f2,b8d6ad3,fce411aa,ee466d25,f07813c7,91a81237,748bda9a,51f4266,4a385b50,5259bf84,ff8372f0) +,S(3867f6b2,58920b82,6eca75dc,953ac307,bed1872c,c0f1c6ec,84efc6d2,eeea1483,cc6a6adc,e6078097,a013ff18,dca9c5c9,254d70f4,68ac1cf4,b8267135,af88aee3) +,S(7b008875,e85fc84f,618ea7df,f20f7f17,2123fe98,c07b5279,930b52ef,cc1b0a9a,3f3b30bb,8dbc9169,a5c55a1c,4150772e,331f7834,b50bb904,a8c56600,bf075f90) +,S(ba5b44d9,16304a49,87579560,4d4b796,907e9b7a,4da49a5,ba7a1d77,8e34ef3a,16b49baa,48219e3b,9bae124f,dcd4de,4d47ea76,3ed39e13,f874c75b,cf333661) +,S(691eafe2,7fe4120d,852b3a23,b5bfa646,910fe521,355a3594,342d629c,e2b8d9df,43a06097,42184dca,7c294fd6,a5227dbd,bd71ea1d,c4bca878,1887f9f8,b6c71d85) +,S(13a6cbb,c9f5a86f,35173e38,a45dca65,551377d7,c37542d8,44006e48,54a54123,ecf3809c,9a964d9e,ffdcc2e6,2e8faf9e,8a43d38f,3023c4b8,84d18948,8488620) +,S(33fd2af3,fb595cd2,93d731e9,1b4f0e5a,da665420,2dcc36ce,b712e8d5,e6f10e45,e26a307a,a8bdda4,4b981bf9,808cfa3a,80ca5331,b3a94c31,f6331e60,98ed2cf) +,S(75954033,59e47f78,76b3ba57,5a758493,b0033298,22f4e44c,15cbe58b,34b774f6,7ee9a040,70b8568d,b0a99855,3442c000,b6e6651c,a7ad1253,f8e703de,5e0458a9) +,S(79199fb0,c3b17e68,4e815e7e,8414bef4,b3dd3665,10d032f3,6505da59,6f5b9480,95bca973,f358c9cf,ef3aacba,54a055b8,abaab383,4191a1b5,54ac3ee,53d9a0ab) +,S(9705f4e7,962ece0b,2e7ed64e,a33fd40,6edd0bc1,ac8997b5,d6d70000,a51aa352,4d4ce757,ad4547a8,a126193d,8921d6d8,58f40855,f71ab99d,b2bdd728,499ff347) +,S(881af067,b841ab5f,30560b98,3376674d,cadeeb75,b8b16e12,df7da3ce,312fd777,ccc13fd4,512ef05d,7c10f62d,8b144b1d,7588be3d,1a3a3701,9accdec9,3483b84f) +,S(fe8f7a44,33c2c9d8,f42e14cd,97ad0794,41bfc3b7,2fd412fb,1f6d5f5c,10e99621,e5b576ee,cf34374,96dc4ee3,a846c79b,4c8babf3,cc46a657,2a93fdd4,b6b3b2a9) +,S(ff43c8da,18e08b38,3f92f832,3c34e83,84f40064,9e0506cb,91893abc,5c4d798f,a575a059,23a9da02,c0c9dde1,981dbd86,f5a75433,a4bb2fd5,2427db01,7ddf2e7f) +,S(4715056,b97f4e21,13485242,74bb1b33,d8f9d841,73678a42,ed3c6fd5,28db276b,b4c0d146,3521f1d9,fe8cd71e,fb98aa28,73a18bee,66fae12f,cabfa201,854302b2) +,S(85c9d808,c5f51d5a,c2a51394,cb83e7ee,acd85eeb,31a88814,9744871c,271fff51,2a7c3bf,23829b88,66991454,d6ec7f5e,185050d,1982deb8,b4992bbe,5b666a7d) +,S(c02b94ef,8b1e368e,3cb4b25,903445cf,f46b60c7,6d6d2f24,529997f9,7d70dac9,bbb97d29,bcff81e4,8d417825,ade1d28b,10fadba2,acf961d6,80a343c1,e725f3a0) +,S(4b1593bd,28e26f7e,431ac439,3d353a1e,fcb8b63,fee7adb3,e29472a8,38241df6,8a67a728,f4966855,26225b11,3ac9d858,3f184f8b,3ccc8ef0,d6e4e34e,f2fdcc56) +,S(f640755b,ba51dee3,ad650555,9d52869b,7a8e7f6e,4b9dcdd2,31d1cd4f,26a64dd4,7387f800,a53e290b,d4c29f6e,ec24ac07,91e0e3c8,55d14882,a48d0539,6e87e1c8) +,S(949346a9,436836c6,3df6f42c,d708cef8,16d0a522,914a606e,2276979,7789515b,a903932d,952a0201,ef65c847,b8754174,31dd41d3,ede5c073,31383b9,a8e2b356) +,S(1824099e,c769edfc,2390b1f6,698c22f2,cdcc9783,c5cbe45c,de46008a,67f91a60,f8405fa,81e04dd5,6ce051f3,bfa088e2,804a8780,37892ae0,adf42767,311bd1e2) +,S(e6b46fd8,e4633d92,8805f34c,ce95f3dc,683aa792,139c62f9,2ec8acd1,d601d341,533db813,f3fea63a,528faf4a,7cbf58d8,d6c0bea4,c28391d1,6391d300,cc1d824a) +,S(63799b30,dc19b18d,d48d150d,3d4139d3,a04c6252,f176015d,60a436cf,ff992b93,26205112,5ebf4dee,d00e72f5,ff064178,7f485cb,2ba35507,3c3cdb0d,16dcc41b) +,S(8cd02f5a,b1d5a02d,e85b88d3,ae370b0f,7fac5324,9f1fd676,670a29f1,2ead7338,358b42ac,ceb689d6,612cb70f,bc9bba7,511d56ee,c4390627,8e2f0961,bcc0d8e4) +,S(d5e167e6,d48bd1dd,e95aba41,bf33b065,f7612766,4a0a8991,d3ea1a9e,ddf82fab,6cc23982,d653cdf4,fc4ec9cb,3cd86ae2,aaf45f62,38257d70,849c2686,ae71d1f7) +,S(c4073500,6987f2df,1334f09d,97f00c19,d72b1942,5864b0cf,4ff19dcf,7c9bfdba,f6566846,6b461326,a9b366bf,30378f82,b760ff0a,ca568ca8,2bf0c9d3,ff7ff262) +,S(9df1e71,9c501bfb,8a21db2,a838318e,29a7c2c0,fb2deb91,1840c7aa,f0c4fde2,cd628cae,6d0e0c02,b0315ae5,4901e703,e977c75b,43defea5,80a5325c,fad00fc0) +,S(95176429,df73c309,23108ee,6922c597,1c91c249,ad7165b,7d08b84d,2a4c696c,3ecffc49,3b62dbcc,82208470,375c929,1994fbb7,240740cb,dd8086cb,e9c0fbe4) +,S(708c48e8,692b0d35,e13a7e0e,94be8fb6,f57fe187,34f5556d,a318f600,c5628c6e,9534e302,deee1d1f,27e0432e,9f6a2f00,5af7e601,3f7da9bf,e1cde320,a105a664) +,S(2775e17a,b82dc739,b5d62079,4b26be15,46275ec0,9d32622b,2991cca1,4e5b4c09,3aa6ee7c,80e8359f,deeb52c2,8da1328f,338ab228,8744d52e,8a9b7908,1b1ccddc) +,S(47c1aac2,39c4f31,cf334959,b8fb48a0,44da6b34,3c383270,be19229c,30192da,5dad651c,5ba6c21d,845cd402,59a051c4,e5813f5a,21228355,1fde158b,600d7cc0) +,S(f80f445a,4b864c96,1bb2bf5,9cfa25f1,eef459d4,fa28ac70,d77daa1b,b8bad15e,a383de04,6b8c6996,6d0b9da6,ce9f88e5,83cd57f4,a5f12c88,63f7ff70,b374ff16) +,S(2924e7b9,1ad33619,a8df436d,578b7172,b2208125,9f2d5bf6,f9cb903e,bd4d2f66,b8642169,e2319f54,348e4f3f,e15d1f06,afa41255,ad62ceff,a768bdb8,48841875) +,S(37d6087b,91a64ed2,8341854e,3a2b9ac4,4310785e,77e32e2a,f13405f3,76dc4d83,35a23917,e068bccb,a823092f,32e6fcdd,a3ac9f09,2c251b1f,9bdb9971,3df25003) +,S(d748a96d,c79f1be0,6b43691c,bcf84b4f,e000d2ce,8294cfd8,391dcb92,10f4fab2,75b4ade0,65da902e,ce57e5c0,4b817228,975c0927,aafb76c8,223c4da6,f05bf51c) +,S(d05d2a25,eb5084ff,262361ea,33b6fb97,9492414e,c255fa8f,a0233d06,e42cc30c,14bbbeee,cecdc8f3,85b51429,8aa03d9,ba57a198,5ba98f4e,75efab60,69a6f2d2) +,S(69ba995b,d137edbe,5aff3906,764eca9c,b4684bf5,e8a8c302,78c89d97,483ff793,2b1cf451,b6226596,9833e864,91c5db95,a79ad96c,701580b2,46de1936,5bb63e32) +,S(7f01e9a1,5d0ecf28,fde0342f,f506104b,3a50aff2,f1ec997d,9a82ff71,54419461,1c3c9594,a6b8d375,361e25d1,fedcab63,d2704065,a83470e5,e03dcc43,ad12dc68) +,S(719232fd,193b9041,fd201bc4,7184e4cc,f2413d03,f0f8619d,813a409e,56e48cc6,161fc718,7dccb053,5337ff60,9eae05ab,12fb55a0,65f82d1e,68b19d3c,ae29a953) +,S(15b84120,155f7310,3386009a,57bd28bf,9a63bcfa,46c8bd08,2f53dc86,76e78c27,47dd637e,c9017e2f,e9804e0c,840aca4f,188171a0,ea9fb605,1402c503,31737816) +,S(ff429d97,bd380047,7db52ed4,eba69914,4a95ce2,7414da2c,74c074,bbfec567,7b3a6fbd,6e635bab,34973f62,4df77c03,6708c00a,cbcb8f25,69a5aa01,d57b3048) +,S(ccd705b,16be74c,cf1f476d,12c77e81,37917404,b2611ed8,858b1e55,d50a6ee3,8741ade7,5cc7b252,4dd55e17,897f78d6,946cb4c,31ad9f1f,737affc3,40e87c01) +,S(65b61a5e,24b3c57f,91678e81,8300ecaa,94e4b406,8d499534,d54c37d5,bb65b27,90d75e28,aab97b82,f1b86fda,2ae0851e,f65ac4c7,a5c664fd,79c16a76,75ed0c40) +,S(671529df,8f4073d9,43f82bdd,758fb8e5,4ffe0487,c1a38cf1,73c1419f,7ba06ef0,c46d9f2d,1f23349a,dd1121e1,d51ebe4,454fd141,c7076950,4d854cfd,14fede59) +,S(2af8a76,e7a1697,7af8e70,30bbd2c0,73da3fdd,4c6735b6,8e823cff,901b0440,55565be7,9ada7153,c7165976,91ee33cd,7c34f5ad,d65f543f,72ffd026,26c3c1cb) +,S(acd81d6f,c5ffbb87,4fcb3b1f,b7cc730a,4def3fd5,ef59fc4,2fb9472a,6f575707,8e319a8e,c8b8ea9e,11ef47eb,5071b696,b87c0ec9,63e851cc,e0929646,1d181a3) +,S(ab77e7d5,3ab9e8bc,2052d0bb,360aa7f2,ae062ca9,9b91441b,d60ce8db,80ffb912,5f92b6d9,cb0ab95b,9eb992e5,e1d70412,aca90998,b5d6ed8f,dfa4c752,2df96b5a) +,S(798b8195,1a6a8c7e,f8beda09,b06a2303,1d7efaf3,7b663265,e0188ab3,78124046,9592da1b,baea430,3644a7e5,4e67476f,d91382b5,f1181de7,a1bf9d44,e02b1bf6) +,S(f2486aae,c3be77d,8dddea22,488aeb4c,9dbff93a,24ff6f29,ed6d528b,9777b096,8e2b2d50,fe75c847,7c50327f,e36afb0b,d8409b62,8d83a8cc,41325aa8,4829126b) +,S(222e3d09,3b8aea8b,e0f64ee3,3aeeee72,d16ca088,264f4333,f9397488,146d2d54,eff500f,bfe6bbc4,1c2dd16e,8a0ebd79,37ba1f78,ccb098a4,351b539d,cacdcaa9) +,S(6768d3fe,7ca93476,245a18ee,ab53e002,4f99241d,9c321bd0,165b7d04,c121c1c9,402c9d73,c9b99722,2319ff1d,9e1c778,c4dc825,d030a43,823aee8b,90272877) +,S(6eb6740f,b2f0880c,eff25697,bfd7815d,b0b62884,cf8c8ef2,5137f098,f22dda79,cf7e8531,c12f5713,c302061c,1f42e6ac,79c4b695,e458db68,5209f03f,1485c86f) +,S(7101f348,4eb05a7e,aa0f385f,367b6a7e,5ede8959,71729ac2,950006aa,965fe51b,8d1fb913,a040fb75,778fff9f,c71afc2c,2605595a,1e44944b,e264f893,10d5c3f3) +,S(75a9e45c,acc6a25e,3fe4b25f,12030362,a0de03ea,cefba87a,11c8e6d3,e886579,52a85995,e91986d9,26a02cf3,1001fd82,854c49f9,55683f7a,dbe7c02b,cff69c6e) +,S(31194d92,bad76572,98bffc54,27f99ade,ceac14f7,830ac1b2,954d6730,3737dcbc,99e81c45,f5318eee,9d2449fa,33cc5bc6,8c556ebc,dac2ef19,a2d1ff3f,5fdd2832) +,S(904fa3fe,76fd6f43,86ac6138,70b4cce3,c1d743c3,8457d23c,522958ac,bd505af,94273262,1adf4633,79e929e4,54c70595,8dae9bfb,3957a304,5c8aae41,a7c1763b) +,S(1d1861f3,1a828b32,3699aede,f3fa265b,40de142,78a7df26,b5fa93ff,a4a8e0fd,b9657781,f13ffeb2,8e1306e3,b84bb965,3ffc30c2,63a65f61,1995f44d,d899f7dc) +,S(3bd33def,6de1a5d5,e5ef0289,e8565dce,aac95922,8443c09b,73ce545e,6819ad64,993f0109,eb560bd4,97436627,9a70e9bf,8bc9851d,f52441c2,97535ed5,d4f9c810) +,S(ca1b7d45,2a39aed2,a7f27b24,8e5a07c7,e4c257eb,7150e61c,7bec7f6c,58958634,ab11fe1b,c0357c37,b7da9804,39fb5481,179c0f7,442af2c7,298facda,3c4afcff) +,S(273a95ca,dee8386b,53ff29a3,6ce7d9ac,df145f7d,5f928f61,da6d57d1,8671aa58,88a6359d,bb06537d,1a6c6d83,24065284,315a031c,73c53ac2,adb14f95,1a5bbe2b) +,S(7ea4c0fc,a139bbac,553ad79c,d3921c01,c06923f5,29446279,d0f910f9,ac5561e6,bd049d47,45830e2,f31e7982,2639f198,2eb71c37,71aed93a,54dfa0bb,296dec96) +,S(71f1801c,a2babe5,d4793240,15ccc684,d3823f68,fcd12ce8,bc49607,9607d336,41ed07d0,8384e54,209b7de3,7e8fe7a6,14430c0e,439dca6c,f5ae6ddb,1ff1b4b1) +,S(b2838873,652ba1ee,ae8aec51,55541a3d,7000ffd9,6279cf2a,1c90582d,21cd8828,47ff155,73f5e3a5,245faf65,86afcc31,ee4d19f2,a1efc79d,2a0b4811,d27dce5e) +,S(34ca8da7,22634bc1,6873fbdc,c089224b,d9f8164a,6bf0acb5,b68d898e,b55a3e21,d8afb760,36a9c91c,7769055,d85a3ff7,1f041a90,5192df4b,73f9100c,e5c5d986) +,S(212cb397,d97341af,ca0cf5b2,ef6d796b,4b76eb87,89c3915a,a0e72337,4b19cc8f,f06e2cec,5f29f06f,97685f50,1126c50d,ff17e273,2f78de64,875c35d6,42f170a1) +,S(bc0367f6,43bd13dc,32582dfd,e7893f69,d5f29d2f,ce4b42e9,ffa8091c,6ca6228a,9bec6c89,d1251f06,4aff3e44,ab59ac32,c1764179,7b96f73f,527ff429,74556e78) +,S(8fcb1423,5d8e8894,5ab169bb,4d198e4a,5e489e33,cdeb69d8,dec100f1,a9bd5672,fa1cb396,bab390b2,60302a46,b4408427,c45ae320,5b1d1f5f,e52db790,e7fc057c) +,S(70ad8505,6675ec20,cbc43e80,11df60f4,d4917e84,cca25044,e15c2fa,e51e64ae,f4a51356,af9fa7c9,a5e62475,df5b713a,b63d68e0,cbef44e8,c004fa61,1d5a800d) +,S(ada7af47,48074168,86e6df81,f9718c06,bcf6e6d9,846fa880,3ede1f6c,b9695842,f66d51f,50f427d4,dc748bbe,771d952,98369c91,c41dd,575b76db,988a582f) +,S(f1b87d8d,7323ebb1,1bb8108f,9d34f8e9,bf1e977b,a527c52c,7f045d8b,1102eeee,bd95703,51ebe7a0,9ede5842,47b755b3,7e2aa0e7,7e380b7,9bddf768,b4346556) +,S(93659d5a,d55264ea,c900c301,cfed7b83,1fbf7c51,766cc833,cc591356,492a0553,b69389e9,646d0165,afa137df,1c1d02a3,519ff65d,8856c89c,cf46de05,c0154beb) +,S(e9d2bc49,2a9b4ffd,c482f54a,415beeec,409a62e5,d1781f48,b1738f7d,8ed4ffe2,893e4652,2dccbf80,ddde313,f4f25383,8d639208,36150631,60830408,44305df5) +,S(1424160a,7bf1ad91,18103eea,372da6a5,825e0bc1,a8760744,229e2af7,906cb210,c94da226,96a75d71,1e6f1d0e,10b23e96,4f1519e9,1f63743f,209ef8a1,3996af23) +,S(7f902712,402e4bd4,aabe434a,eb5fa7e9,8686d058,e6f26300,c458cee8,9c9efd87,bc00460b,2aefb418,b16cdcdd,c88446a7,1b8b018c,15261602,669188ac,62f95fb5) +,S(d327ce7c,66cb0f53,e86e5f16,c8dc2936,2a133f6a,38147c01,255c61f5,6f72745c,4dc1498a,c3cb39c1,6908b85,b8c52dca,618cc6d4,1c6f95f8,353758a3,86bea436) +,S(f044eb19,c9d81106,13803b,e8bbfc31,137dffce,547bfd1a,d5396ad,e32db3b3,5ad4428d,9c4c3e66,7f8551ce,ab282cfe,8128a8de,ffccfaf7,c102b9df,7e526f2a) +,S(7a6c5237,b95d19be,af46a81e,bdd54403,d135bbb7,f3c03d55,f67c5cbc,e18daf4,62a2e8b8,47fceb5c,484fc6e7,4ff68fed,bd492c66,8a70c1d7,cce2922,a204385b) +,S(59c7fcdc,b069c0b7,bb772afa,f5c20846,ffae949b,47589bb5,80495bc1,b59f82f0,82ec588c,6657566b,71ba4d79,ac8e2c7a,c09b3652,f24d46ec,3358eeba,126c38ad) +,S(f8cf3c21,1ed4558c,c40d3dc6,dbb85e54,81d99fdb,cdf27ae0,ea01bd4,6b6543d7,bd8049d0,1c3df630,8951f5db,dcce3043,5506a5c3,e0a8bb20,54de9dc,87a9778b) +,S(3855d764,b2389d4f,1ff47189,33aca82a,4d2dd23f,cfd13764,2782ce71,524504bc,82c4ea25,4af2abd0,2724ec34,6aae3aa3,b14a71ee,df13df95,9446c0bc,759ef72d) +,S(77644b31,1de4f0d8,d30b1d73,35553dab,6d3e0e6d,af7e6ffa,48cddd1a,52de5431,645e17ce,c0a0735,737730f9,92bb7431,7581c930,695829b4,cdbf5214,f45916b4) +,S(a4d4af43,afd6afbc,b2a511da,a6537abd,56bfc0cf,76659d34,56530663,d9ca138d,be6c9fd0,dd2df31b,b907f073,7d63df34,88b5db5f,3d5ff747,a25a2beb,73bb09dd) +,S(417ffa3f,e673a081,f72c3d64,5e64bc61,2da352ca,fb66d1aa,aa8fc060,74a75be5,9ab8be2f,90849474,809472af,d5a7490e,cfd9ca4a,7f738be1,de093e0,68c50151) +,S(78175154,93115041,6cbd772c,c74212c4,4f19eb04,95e88622,f75ee838,caef73cd,37d4d5c8,ffec3650,26381b91,d7cb18de,fdaf2cb0,a5d94ac2,dd7bf7fd,34d0d3e6) +,S(365c560c,3acc28ea,f560c66c,7e76625a,3c2ee7a4,8f62ef0f,736253fa,b1b5121,25cbc6fa,96c0f15e,38b03f88,338f8dd1,6990aa15,dcec58d6,4517d37c,5b74868f) +,S(c945ad25,1010023e,9126b6cb,3a19a925,6c6757fd,d88cf808,a94fa182,8f5bac7c,c9a8e90c,b4ac43bc,ef08ae3d,fc66f6db,99df4abb,2679de5b,174df92a,d654e2bb) +,S(4aad85ac,45e6d57d,73822387,632863de,ac8c3fb7,b7d3beec,629c0e1e,2c2e0213,38eee8e1,9e81bf64,9641c192,de53a071,29c03689,376f6595,2130b63c,fd6a2708) +,S(2bc10248,b0f6596,adcf9f66,3f624461,907e37ea,7d35367f,24b9f69a,26a291df,e0ac3ed3,3016b37a,91a780f6,b90b7743,24ad0c30,50812b2f,4f35426f,4311c79) +,S(cdc05991,abd28f93,e81a2c0,9a04e1fa,eca89400,81fcfcff,eb91c8d3,93ddfde2,dfda4ac4,4458e2b0,3feb9852,d1a8822f,8bf90a4e,bc79ab32,afc9a1b7,580193a5) +,S(5a24eff0,af2dc429,ff4ea857,f8aab10,31d285ae,9c8beb7d,793bf9d,db46a047,179db914,59739160,897f40dd,b7af0b8,a98b6f61,6aef7327,b53b6005,9c4c8f9a) +,S(16c1e53f,51603ca9,374aae6b,57d15fdb,e7c1d2b0,b0545467,636fe2ac,7838183a,bf858ef0,56e09bbf,5d8af50c,7e0fdc90,8d1f6c1a,570594b,a5368976,63a183e3) +,S(792f1eea,71b92f9a,d893a116,ac177801,a2f2405b,1c6846eb,c3a6559,eb01ccf4,bc062f0c,c610ef39,311ecf87,a7866b9c,52c0df0b,be1e0129,3ccd0b7a,2832a79d) +,S(1b399c40,f057719c,f544dc51,51137fe3,917dabac,f0804dd7,335ba65d,a57378e1,4d6794d3,b6e8a085,41de872c,1dd333a2,bfdd0712,aa846f6d,380a775c,600b425f) +,S(138b313e,b9c45ced,e0cd8219,b888c51f,9f8cd278,abe16ede,c210bffa,ba238e4f,a199a357,cbc8042f,4b6d4951,2f0acd26,13f0f76d,cd6dbf7f,d9e8723c,e6ac56d6) +,S(3e06c311,9c765664,d0068b24,cf4ae1a4,8f401811,17c93122,84ffc24d,eb542338,63a65596,e5607f1b,6a9c4596,39a90d06,93b08ab3,2807b696,498e7557,673624f) +,S(3f32f9b,49c88932,574e5455,c179e9de,80f0f6de,ed1ed25f,8a3de8b4,bbf8bd2e,a2d2bb1a,5fc96f89,ef490257,bf42a9dc,91f49ce,e2b86472,8551fa6b,6a589f17) +,S(89adc417,ffccc50f,a129602b,f5b1b82a,2c4f5efb,e3382b04,1fe77299,46414ec5,4ce7e75c,291b751d,155c291,5aa619ef,6c3daa28,25da8bc8,e2c7ef54,8c253215) +,S(f33fbd62,6bec8c9f,6597d486,2f54f65,e9f208fa,7c1d619,a13feaae,5ce4e9b5,c8f0602b,ebb9f152,87fe2eda,3050b032,a6f43c8b,7726825e,df02b424,51593774) +,S(eccc8ab,7b90e2f7,e45f7703,a0e97406,117fa04f,4512071d,568e3e64,a4a7d6b8,8456f705,a9c4a0d8,f2f3c233,3c8bb367,fcc8a645,f1fc560,48e1699a,58a1b6f4) +,S(f6962b33,a7ad862e,58181c75,42743ed0,e6e31d5,4df1fdfc,a4e3e95a,157de915,af3d47fb,48515ceb,f9f7e8ad,2a0159aa,55c155a,83359cf2,9ee3202,ea9e6605) +,S(3f1f3c6,7996fb10,65ed5df0,2095926a,5c45d2f2,38ff59e8,42b9d234,daace24d,d585c9e4,f0a29f0a,28e3c30b,22228dab,73750706,5690811f,1104bd4a,6d0ea28e) +,S(fcae019,36290e43,d8bf93c1,6ad2cd5e,dc33592d,4081b0e3,4aedd451,6e6e589c,8e98579e,cc42a444,2dc710d8,8cd09996,c8acb958,b9702c24,3a207ba1,471165cc) +,S(548f27ba,355229d,23b7922b,5fc8efad,abc4247d,baa312c6,d89570ab,151f522c,e5597d8,bbb47cd7,c8cba774,ff37c81e,b7b63c63,39b9600a,cb77f1b8,86ab6fa9) +,S(e2f64914,e8bf347e,d465cf1e,f086b7be,49797db8,611803ab,6e439bbd,5c146fa0,8e69e76f,7c641e4f,15248257,77aef9b,88b27a94,72d565d1,d2ed7463,fc6ae76e) +,S(8c532a0,2d970c0f,1d8f9762,2298b40d,c7d362c8,f38cd122,2cdbeaba,2c13db1d,90f8a2e9,428d66d,9e8ffc9f,bcb7606f,568251b6,2dec2768,1b6ffa8,7062bd0e) +,S(64646efe,e3c51972,f6af7e0c,8052aec4,6fc0ed97,af566f6d,3c323218,62291a23,9e29e150,f6ca370b,36a76ee7,171f2ddb,a10eb88a,986ffc50,d6c8f4f7,287a69fe) +,S(6e8ba4da,1df8dff7,cbff69a,6ef65c9,329199bf,9a67d1b5,1eb1e1f3,473be659,ae7562c8,959441a7,35ff2188,3e537bd7,eb5a34a2,7e144a06,f674679,815d852a) +,S(8c21abc8,f7812c0f,6de0d7e1,cadbf1f6,c94c871c,d5b8e9ca,e76c1f33,2b6bcaef,5a7c9cc3,13be03e2,5410ed03,7e0cefe9,5a36d6fe,68ff46b2,663a0ca9,747ed53e) +,S(ce0e383a,7c487e14,26636ff7,657a28f0,10ce5102,1eb89fea,3426b269,2f9f6353,3f95a465,d43f7804,2804e9da,4c73c8ec,97fcb9f6,fdace280,532c0c0d,6232e03a) +,S(7e33097f,51477c4f,f4459848,34673fc2,8078b6c7,c01cb700,80a37ee,1d698eb8,c1275bc0,7317c679,d881d274,e49065a2,e282b7e6,970065ad,141c1ca5,ca2d75a7) +,S(ef4d9cd6,b1487e61,fb31cf42,9eff2731,d686eb66,cfb3f867,9317b0e4,116837a6,c4f6beb4,280ddd5a,24f6461a,6ea1eba2,3bd2ff58,7ff612ec,d118b76a,3d63be1f) +,S(f3edc145,2ee49324,f7890bcb,9a5f8ba3,ce53f4a2,df0c94b9,92c573b2,f3716290,995446ab,fbc9b27a,8db301f0,87c2ae93,5c390565,491c0dbf,552a9820,d3fb2f2d) +,S(c1f62251,7398e914,d6134160,318d20c6,87d17427,2bc62c92,bd170ca8,2bcaa975,1c85ae27,36735b76,d5328d59,3292f718,f6d6da52,1c75cab,fcb06720,87769e99) +,S(a7e81df9,605f0881,d4856153,3e310715,b206c601,9a55b889,7141321e,463dea8e,3ae220fd,1f361be0,f0b70dbb,a7df796a,eb23deb,5c5440ad,aa16fef9,7cae8a4f) +,S(1b69bf29,8f5df296,7a3ac028,87d4ae5e,f46af5ac,5a8cf326,2fe7282b,e46a536b,c9c624aa,2d99a71,ea375c68,419b38a2,d7e9d7fd,8880dc60,28c24f2e,a846a91f) +,S(cddfef74,31763b9,8df15cb9,6b3b3127,b31c9987,fd17251d,b56122ed,dbbb44bb,972fef4,2e935aa3,4c679ce2,6a32a38c,225f0867,8f780b65,854459e7,f24869f5) +,S(32fe1cef,2c8a5163,66b47d30,9ef01e20,ee07f235,e7c0129c,fcb70fff,60e957ff,9e861731,bd376124,8b33babe,c354ea,3d13b2c7,c45b436f,e754edf2,4fb4588e) +,S(a382fbe9,f4914119,d31d0ccf,6afb61fe,4a759657,26556908,505225b8,79c24b0d,aa300360,39a1bfdc,273e0287,c7c222fe,cdde6318,c9838a55,5136cda8,d2111857) +,S(b53b5439,9ae330ea,e13e2467,7c0344d,59e305a7,96a228bc,6d6914ec,1a80ef88,99809053,8dfc6c5d,748f43cc,8ba8a8e2,969d8d1c,47551a36,8f30ee30,d5fadc7a) +,S(621b5253,f11cfec3,fb4bbfed,98b0ad9c,710fe2af,6aedb8d,f521d0da,fb64169a,2a234dc4,8b716af6,22dd025b,63e05c5f,3b93005c,13614bb3,abe0dbe9,260378aa) +,S(83332b6c,cc9c3c7f,3163f442,80f5758c,1e5979fa,b9a500be,d5b315e0,f9435b04,85360612,258c1f1c,bda41025,c402dd84,60c77df6,8762d2d4,16aa16af,dcd30ea0) +,S(27c8d8e3,91202622,2f72d926,da01b10e,fd54e21a,7a4746b6,68aa868f,dbf6538a,88768e3f,b8f2484d,56c9fe83,fde0fff7,4d0c0a81,213ac090,e90d2b42,22d6eb91) +,S(f349c70b,bcd82005,2fd2e05a,c42556ef,6ee768d4,f08b7a91,55d1ebfe,60067e5,6d595c19,4011d050,c7c3c4e9,e7aea90a,93fdc5b0,71d6c9fb,9f621a4e,750c6604) +,S(4966567a,b2029966,62b1368b,ac3f89e1,a0183b20,173a7156,edb827a7,13b24f90,6ef89436,c2bb3bb0,94910ee7,6c083e35,a097b859,16658947,1f59c33,37e21ab) +,S(4909501b,491da13f,78645b84,9bc63fea,75611b76,5ff6eb6,9a7414bf,913e0886,2c20c6b6,f2ee070d,c1dd4c95,6822ac5c,38b1acf7,5e093f17,c54b65aa,81014df8) +,S(1ed2e667,f5a2d140,18cd3ee4,f4163f7,bd5f898e,ee3dda72,bf84e356,10cddb76,bb4970c5,64fa4cea,e204babd,d869e36e,934810ef,68a22794,f9919e3,26db8e7d) +,S(c47bab41,a0bc37f,addf9c8c,7de86d68,c15d1a0d,85257d57,2a1d60d,4612f17b,e52acb1,36f47de1,1128091a,1a3cc3e0,e84ce767,cf8395cb,b09eea81,a2db09e3) +,S(e21068c1,4993cfc4,35490b52,5ece7657,f70825f3,dd2138c1,8f5ec6a0,c67a7394,cd610137,d48f8d9b,2bf99755,35fab6fb,65360fc,9db04a12,43027083,c732da) +,S(635f547d,47a72f5e,b069e144,6508a46,bd6a6f,11eefb87,da07e4f4,3ffaf917,8ea0a9f2,3da273b4,f324c8ed,81cb0bf0,21fecb57,54eaa642,21736923,2be64128) +,S(24632c0a,8648b4b1,fff2f79a,b3f8e64d,3837b6ae,9329eaa8,48565f02,45bdb47b,9c6d0788,c9e155d3,3c260360,862ab236,177ff875,a3823179,8146e442,f66e0426) +,S(43748dc3,cfb229d4,8549cc56,ecbcb01b,146541e1,5d2c3b5e,d59fbf7a,6b7bf503,9975a1ed,23a09906,3b87ea7f,2ccd88fc,b20607e,1aded9a9,265f34c1,45fb9c5c) +,S(8f848323,b8c41d68,31603b40,69be1dda,bb8750d0,11527a58,4bffdca,c3ae3ac0,77a8ac87,128260c2,86f5805a,b17e5a45,be81f83a,2a575c6e,2c88288a,c2d1b37f) +,S(29ebc368,b54d846d,bb5e8be4,81c19c80,2d8907db,c54412cc,6e2952ba,2948422c,e6b793a2,81d59d90,53aeb2d6,f79cbd1a,426f79a1,6860310a,ec72fe26,37c7e845) +,S(9414cbc4,ccf4012c,8c0cbe21,eb714953,d84bc602,9f8e4810,5ba79967,23ed345,ad1eeb92,89e4a109,2d132790,ece35cbd,da45bb64,bb6ae72b,39b9eb80,d57fdeee) +,S(1bd8565b,769d0024,613ab814,90f214c8,bea90a5,db1e75d4,11ec3dc7,288f756e,c050a46c,fc781e91,b79cfcb0,2abdae50,b69c2cd7,dcc56b13,1df2175d,c1d375d8) +,S(4f7584c,35ad66be,3d409154,eb8ded67,14ed0ae3,288593f2,76cec90b,629cb01,f4be9248,232a120e,11ccf1b3,e9c5a17e,1520fee1,8f1da048,fb01eb3c,17712bb0) +,S(5b0009de,7e85b317,ab127401,fd2f3ced,cffd1684,c4772b35,2b9c783e,1dd9f13b,f4585704,f531c34e,3377cb7c,e672c78d,cb8839be,ecfe048d,bb412328,b973ba64) +,S(c66f31c3,79396f01,2ea5fdbc,4222df38,37f85353,3f3ed9c3,ad13bcac,63b32815,7d7b808,4ae5e9cb,c123ca86,1b505242,4113ee84,bbac5ca3,ea1cd3da,6eb22668) +,S(33097f5d,c8b09934,26ba51b3,ee99e696,3d7ba455,e91a7af1,a57c85e6,5e63abd6,fbd26b3b,200c189d,c8b9e120,61869766,987401ed,66e4ed80,63835922,c270d7c4) +,S(1ace5245,a3b7ec60,b9a922d5,ffbbe43d,aa71cf0b,84e395f8,c37dd2a9,c85ffff4,72c0ed67,94708f9b,f29c51cb,b6cbb69c,6ad3f4d,10d62987,1c444da1,bb25084f) +,S(bc197b9e,4cce4c2c,bfb22524,93f9202c,6ed54e32,cd52f512,692a5af3,6b0c4471,d5137663,5182065d,a4d6be56,cec50889,3cad9b95,4d5d17df,adb084fb,dd673f70) +,S(66997931,334bdbed,174cfa73,3ecad896,13c6f500,b79a7fab,76ad0bc8,dcc7df70,fdbd3301,948e198e,ee3e7d3a,504ac560,ab00afdf,26940331,d49bd2c,6599435a) +,S(3ba86cdf,b38d82f9,7c20b962,103f79a,5637422f,370b08b3,89083cc3,1a6eb4bf,acec9811,76debb13,9bd7f981,9b476e1b,5377e32a,bdecafee,33dd6ad2,3258dfc8) +,S(f62432f,9db971d8,4c3acdbd,c2d915d6,6395199f,76e81243,fed930db,ef1603cd,ee89cf3d,177b4cc6,e5856acd,5de8757e,82269f4e,eb11a444,c2e0c797,4a7b5f28) +,S(84b41bdc,6a6dea46,ad6e650,5b280a1,b6d81250,794e0b1d,688aeea9,c067bbaf,9f78703c,b535b4bb,2b88cdf7,b5f0f0cb,e452fe6e,5cd0f2b2,ab8c2439,9fc00e7c) +,S(8e2dfea9,3ea64a14,e28f4883,98b8d455,48c52ac,a5399f88,28a42c1a,c89d4c67,fec01549,cda53605,335df10d,d8ed04eb,e09d7474,f69deff7,5935a499,f2781271) +,S(c3bc6dae,5401ac1d,3fd75e36,4cbc2fa1,dbd2f6a2,40e912f1,18b27759,9b105e0b,170fdcf5,5b739326,fd234506,303700b1,9c5dba48,b6f0cc34,a650c3f,3b63d6b4) +,S(33093e93,1b1e52e7,ac5a289e,27ff810,c2defced,e935795d,a10ecc89,a3c14691,7fbba584,5bd55ebd,a67dc842,1ae10fb9,2114f0b,d68bc47a,7ee87a7f,70deec38) +,S(21b35438,b6d1a3ce,6c765e,dc78dd89,3f121132,ecbcc208,a36fe734,d8141ef9,f6115a5,ed237dc8,f61a82b3,66fb508d,e2d516be,3b166a7f,2566bf06,eae300d0) +,S(ced66583,aa1bed17,30248edf,28e9e4fb,ade70821,1c2e48de,3782fc6,d3892df3,4f43ad36,f29da03b,f0fe634e,3c441c42,c3a81835,2407f1b6,cb38e738,18fdec96) +,S(c5a74420,f541a8ae,b0673122,29fbccaf,37f6eb7c,ccf2bec0,23a8573b,ee6f71f8,ae634c02,44263d36,c00a6e25,d25fa592,1612a535,4934d709,6c864865,60adb259) +,S(304a048b,f30f6b4b,2a725521,15b15ea4,8311c51f,c4cd212e,f0a4bac1,48b9de9e,8f935900,3d6ebf0d,129cb5dc,8a953fab,11ceeb85,b2123fec,154b065e,63bb3cd) +,S(ff96b5ae,7eba0af5,ac9875e,97811e91,6ecb66f1,3bb06519,72ebfbcd,5b9c2048,24af2186,bca71cea,e58a0b1d,b56aed1b,3de89cc8,70fd4e3c,31919e2f,6352a887) +,S(5909ce1c,df732eed,4147243,76fdb3ce,8b6d38b9,4a0b35d0,50bdce27,b1b701a3,2e44944,665e761,825cf223,90383a3f,7d3731bb,bf7792b0,37fc05e0,b224dfdf) +,S(ff6b771f,86d66610,6fa032b7,92844548,8ef9974,caf05ad7,cfb6b30e,abd1d527,6abd2a9c,9393e91c,ff77e055,7e9f6a86,9fcd0bae,3544bf50,b25f0427,908ba4b3) +,S(943ccf04,94dd1fad,1efda48a,12d9ace7,be919685,7e7fc5f4,befd7d23,3a1aa8d9,4f08b4cc,2dd93f8b,3751a23f,ca7e4f10,6014e01c,58791c52,3d01134c,1a0a7bd6) +,S(a79a7a7,a89e1cdc,908e0968,bf26c341,47a4638b,1d9cb5b3,ee6c49f7,405f172c,cb53d967,14b5be3a,e5497f34,ec0325b3,ebadcb76,b9838cd1,b3cee90f,f3bb8ceb) +,S(28ff2efc,71176efa,a861667c,d173f78a,4f548b36,aa33db2f,a50c0515,1c7b89dd,475b3707,db4ba15f,1485e165,68d7dbdf,8e67cdb3,37d79988,dc6e2249,d6fe4941) +,S(85b2c332,16a86885,c0704fa2,55b4ca00,223e897a,f0ae7557,f8687eb3,b1012968,a1f58d45,ba664056,efbcbe7a,f0ef479e,1f2bcbe7,98d055c5,7045d735,d657ea11) +,S(e9fc2d09,eefb32de,4068e2ad,d7bd3692,7a02b3e0,d354dd47,c2a70c9a,5cbb8778,ee009aa5,1216d068,3ee219b,bf53ccf4,f249d7ec,bd8c9cdf,80d0ec5a,5b65c312) +,S(da2dcb50,afd510d3,26e38af9,5a22850a,a1cc88d0,620fed65,763042f9,a0005d9e,1eef47b1,c3700963,5e16af23,f1308de9,ae0eab9a,b16c9443,6d501ebe,133eaeab) +,S(20daa29c,c6b166eb,ce717402,70873566,327891d3,ff7b6f08,b9b7da3c,1eb352e0,2ff6982c,ecd6fa4d,ec1d6692,92c3a326,a30cb526,4dc27a4,299dd3f7,7ae8a3fb) +,S(e16b08dd,2ae5be13,67547a53,496f9f4e,3aab8440,6cc34bdd,71b2ebf7,53674d9b,b70f724b,d9522b1c,8e43d60d,6357b5ba,48a1afc8,b7136c1d,9317a1d9,1ba06846) +,S(888a2daf,2d69db34,ff9485e,b06d44,c59670ec,3c68475,80753567,e56b93d3,ddbe4fa7,792e0b82,ac4753f0,5b271aba,8e804384,b7949a9e,9ba79fb6,31d4e3f5) +,S(747768e2,9090fdd5,2c22e308,131f97b2,ee6d8e0c,bf43d704,d50d60c7,616abd12,eaa75f40,8d1ce0b4,bb52879e,5ee7ff36,27b26645,c8ce3840,99dbac60,9cb61058) +,S(8569f2ac,1c7d131a,8d337cc8,87c00c1f,80897a58,f9131143,5a17d79c,fd8d6eda,504f0b44,252d06e8,2f8e700a,746a3393,85e43baa,a4e5da8e,dda7ed6d,83eacf71) +,S(4f15f3f9,a67221dc,4fca1d68,429b874,c4418df8,be480591,e57d6841,e11860c9,982c0d56,1783a9c1,a16bda10,87d29061,3f1154bc,4cc62a82,b795c54,a496b7ed) +,S(21e51a20,1f226e1e,3ebd56ce,6f7258d6,4e4f9db,aa425943,9e1bf7c0,144a92ce,4c47a801,b6a5a4ad,25c1486f,ec9bd0aa,428f3167,45136359,18d47079,75aac869) +,S(fac7e42e,8865ec0c,d0b4c4f9,dff6bf8b,e0f28336,395bdf2e,d5e2a118,9c0211a0,36812d9c,8337199e,fb1fece1,1997307a,ce656fb7,3bad65c6,41e6bba2,c4dd695e) +,S(a147839e,c91bc77e,cc568671,442d29ee,57f0f42d,7b9cb469,91064549,1a26d225,f404350e,bf7267f1,86120257,fa29fc1a,fc0d064e,2f14eeda,b730770a,c85bc5a4) +,S(d1212cf9,e5086804,44883c1f,4158f3e3,44a7900f,716ade2b,df19e41c,18636b8c,720b851,7b91665,128183a0,f3235c6a,2f9c21c8,e8c6ec0,5553acb0,27fc0964) +,S(13d5f334,a7ab2578,977c125,1a07d7a,2e4852ca,8927ce7,2dd9fe90,8b948975,973869e2,d1d0abb5,1ce31db1,ae8c3816,ff998753,479fe82a,7d87b6eb,798773ca) +,S(1f066961,6dae9e8e,76a9bec3,26bc2136,5ec754a5,34c787e6,b9abdfb0,e463507d,da48070e,b4ea111f,881f9fc1,2993a9bf,c6f99974,b3353ce,b5bd1cd1,c75b262d) +,S(729e187,38681dc3,c4ad9a49,59f975f5,907b15d0,114e029,8d4aad5f,69150269,dbf2ed8e,c60ea01b,6de0022c,8b035a7e,c1901c82,9e8d83f2,4560659f,8d455442) +,S(e92fcbe9,61353477,4d42435f,de190c26,8e3692ee,c2042fa0,2ee21687,1dfda12a,a75b5c0e,3f5280d6,41e36957,5e6ec5cf,585b1451,1f01da84,fb852cc8,2d64f2ff) +,S(85c2e61a,c69f8d39,e9c4dfbf,93f6b904,1ad35bcd,7f2b5c1c,789812d4,c8da36df,ca6d9187,694429e1,a5ca50b3,332ab11a,575264db,bf297752,f38fabb3,c0b53f45) +,S(10d17632,c33cc6b4,f5c2791,b5ae4f00,3adf9958,879c24f,10f147e1,bd1bc05c,e15ee734,f1ddec6f,45dbae00,88e4c5c0,be8464f,31205718,a8b2c929,939a687d) +,S(a6942345,25938972,f39820bd,27ea0bbc,92511dd6,827476f0,28fec86b,e25d609a,e06b3616,870f73f4,93f6d1b6,6256cb48,af49ee6c,b5296bd,ea73083,4f11d6e9) +,S(b4a7d8ed,2b3dae3f,43eba052,45b6c4c7,c401a675,6bb0d906,4f66d88,df94d8ac,ffc81c63,1a2cdb5a,fd7def11,9d07af35,74dcb04,e10a5ecf,d2b0a46d,90963456) +,S(5aebe21d,aebd3c57,285cb660,d9aa55d3,f84fb2ff,584f1266,3031e2ab,dda6fd17,22ea513,6a51b532,d178c40,cd5c8453,8f5994ef,7b35cff6,d9dcd999,daf1abe8) +,S(ac684664,194388d5,b796d64c,b4563aa6,69388d0d,83861c51,278316e7,2c8c7f87,cb9426d8,2dc90b01,97bf114,3f693e93,4d710988,26586e5f,f8913ab3,9ef41ac1) +,S(6f94bd49,f89e621,874c58c2,f27ce8a9,76ad2764,1627e835,6b82157c,24955250,d24330ce,4a54dc7c,5c7d9cf6,8f8622f5,e3633a85,8ec0d2ec,d8df3f9,bc7c5614) +,S(3f96c8c,e149947a,6d9ec5c,9ac5ff44,775e068a,785a2fa9,d0940905,a008f137,a91dcfaf,7111a506,3cf613d4,e360c9fc,9b7d9e40,30e00ce2,b120eacc,805f3f40) +,S(d805b05c,dfd675d3,b862a4c1,74909974,405a5b61,9b2a73c8,f3470959,779c707d,a68b544c,c7279f2d,e3a2abdb,fbb7fcb1,84366ef1,3cc3a66,b6d8cec8,3c3b6865) +,S(d2293c0b,d4189cb6,6be0efa7,874abe9b,59142233,6f2f71d4,808be34e,79df0e4,5fbc3248,87c54960,b9bfe70a,5cea3871,7f24f79a,3fe0d313,18cc068f,212682b1) +,S(931f090b,e22623fe,7ad49d26,e76b3c5d,e3f107fb,556f9657,facad9c,5b209d5f,cc255e79,d2a89899,865daf74,81aea395,848f57c0,1850c144,d5ad1a17,4b1cc087) +,S(118a6283,6707ff6b,c8ea72f6,285403a4,6e4e690a,db340987,a0359732,39e5ddc9,91f00fe5,e65a9058,36f9d447,d96af84,b6f5a18d,85c127ad,72221980,f7ff818b) +,S(81096ceb,5b6cb49a,d014ba42,d1d49e1,b811ca2d,2e6614be,1891c6a4,1f6a985a,da051c5,f8f9f3e5,78050a3c,1354b674,3f494860,6b04b8f5,b4dfe970,b7607e5d) +,S(9a80a438,5ff45ed6,2dd3559e,783eb47c,351b7e43,6ddc468b,9f410989,300cae06,845d1f99,21b69c5b,4628aee8,b0c55398,bee65659,e3e41cad,30e57bf8,b804b6d0) +,S(6a3168f3,b89955b9,7fac1d59,61e95fea,2143954d,fbbb6090,81c2408f,46747906,5b5f1f88,6778f108,3ae44a3f,82c901b6,12c741e,811d5403,c483c572,8cccc005) +,S(9a03ab11,78d165ba,23bd4298,58bc8ed7,797710fe,f4f8d8a7,3db0a90f,e1214af8,70888ce7,e61e4bf4,91512f2b,fa556f51,59a5550a,1d50a65c,a652b5bc,89e85665) +,S(8c90c18d,78b8d9e1,59a61575,48c14971,296c8c41,991dce25,e7878ef6,f4ea2f5d,2a5428cf,de628e51,a1644a5e,5dbb7227,2b97c0f9,b6909a68,2814882,cb1ca074) +,S(2e9bab7f,3062024d,84f7a5da,a02c9ed0,93327923,339fdd43,b68d6dd3,508a8957,c9af80b7,3f3803c9,f21e21f1,9523b2df,ea7e4f8c,9a376aca,4a147530,d2a43345) +,S(2734bf2e,718ecfef,64a95e7c,1fbe6a37,e2129898,343af84d,b5c17671,9a466322,f530098a,9f115f0c,e36a0ce3,4697312c,7d0a1e4b,df8a3ca8,f0a63631,e684216e) +,S(ab9ecaf9,500e4a4e,6e81b997,579b5214,4af3257b,8c8f40d5,e21c2a51,d56aab58,f7d38746,8e081844,9bd5e9d1,938a8859,d0aaede7,5743dbc3,ff30d51c,3de0f047) +,S(ae25f546,a4c09ef2,e5a9cd3e,85baa880,292b4d4d,4e8440c0,1696435a,cb1af368,46a2b3b3,7373840f,b739a9f2,2953c6c4,80bd59f2,11013d59,e051055e,f7f3da84) +,S(54285da6,4ef21cda,f597efaa,884fc00f,4e35abb2,bec04ace,54a83dc1,c12e6142,483beb2,144d7b5b,a47c2dc2,9225dd5c,b962a849,d46ff6e,5220b6c3,20cdbc3d) +,S(bece8434,4bc231f,60ad542e,d6a7857c,35a627ee,a2914874,c8deb661,37dca65e,a229fb80,2f9e72f,8e477fb8,de081254,fe1c93ad,a4d3b4f8,e9c2f4eb,3e2f6a95) +,S(3d55747,b148b857,472fe5af,1e820bbf,89994a2d,ae6c326b,26fd9cb4,fb5e81d1,dedeca5a,e86728a4,f635bc4f,1b2b162f,c9ea7dfb,efd5852d,b90001cf,bde465df) +,S(13c68219,d1633c73,59f6361a,88bf6a72,1846b520,33475715,fbc97dcf,75cde5d4,ce8a3cc2,39fc7f20,96abfe7c,52d79e9f,bddf0ce2,ab2b6e55,935413f9,37f83af4) +,S(e9e40ae1,a8041a47,274c481a,dab52f18,36690a29,be837433,43650126,d5b0a6ac,c19958b7,9c9839b8,1371f314,749147cd,9a22fa22,a55da9a9,577646f2,38c6bb7f) +,S(2e3b4553,7460a1a5,f7353a53,78db61c9,13af4371,9a268eea,6321b4c8,a1493068,f7ba5e56,104966c8,4959d3e2,290e5501,5ccf5cf2,b6fb5bb6,e0452c5d,cba54dcf) +,S(9855bc82,b9214b00,67eaa40e,bf670dce,6a59f3dc,4cca491e,db1f0f48,b4c62b8,a7d93f6e,3be6c73c,e9e37d6b,5b071603,87184e21,38478009,8d4c1c80,ccfcf435) +,S(37f820a9,b9342913,6d44bee2,69cf27df,67486bc5,233b8866,982f8476,15253979,fdcaea9d,aa629d37,7f345a5a,37c566a5,50dd893b,9d7ba88b,2a568a28,7870ca15) +,S(e82d2c98,a92a3b0c,690f6ba2,8070c59e,3e0cd0a2,a384d3b0,3cba9d1f,ded41a98,31e73a32,32d85b36,14833d34,4c7d502d,d09d7ecd,614b060,95c86be0,c8501460) +,S(bd492fc3,6dd4c906,6a071182,7eaece3b,ad46901e,b400bf3a,24b93799,9a923419,caada3c5,1e1fd5a4,6676dbd0,a7fd4049,8b93da93,bcd25af5,fdc6a0c9,1dd7798) +,S(6c8b46da,42d1ec4f,3ca2c4dc,15a69c80,cd8f0d99,7bdf3964,1cded32b,8629577a,d3ad4f62,729e42e0,f72ef596,5bcbc239,cbeb988e,e62b30a9,7f124004,c718c956) +,S(78b1e9e6,799bd3dd,854a25d3,4d356b4f,effee71a,ad0c8f05,ea9ebcc0,f8f5dd62,31503ed6,a26788dc,c07d7005,7a300665,d726ce2b,702e65c1,dd25f892,3931145d) +,S(f2ed02a6,63c5523e,3c68cda6,bfa4ab6b,cb53fa5c,15f0375,c8974eea,5aebdccf,3bde5c3,afdc0320,e3b92241,3220ad32,937720a8,d1477b67,773e725a,3cf36382) +,S(7e43f643,a45800bf,7e54d83,5ff6ba20,f67ab101,5d1aaa60,cde0967d,42caffd3,1f456eda,f473399,b57fbb37,807b5269,58600d12,b556879a,76e21459,5798d68a) +,S(df15e177,5eb73697,aa4c0a62,4b4d2ce9,7ccde2ca,66555d07,6430b656,61319be8,496cdc,f1543818,c2173dfb,8a60ee2d,8397cca,b16e4e53,b35079cf,b27311ad) +,S(edf1d706,295bb20,12dc1648,7940e84b,6707a3fb,91a14fce,ef37f669,c782e2ae,e3a0f2f6,fcd76c97,b20b2dd6,8e888eaf,9ed8f598,f08e4d7d,239a8964,fe019a2e) +,S(c15022b2,6b15821f,3be3c313,73d0464d,fd92cecd,6ba87c2d,9b18fb5c,16f8f6c0,78cd2370,d94e2842,e07961e6,92e9fa04,65d57f25,a80feda9,327581bd,ce136c2e) +,S(bd4df6b,b6ae15e0,109886a2,8a8f8c90,c6cc2bcb,b52dd105,e277da7e,c76001d9,499659b2,b0b4cb96,5b8e5029,96ced2e3,a6f6fadc,da01b875,72f8727d,8ef1446f) +,S(dfcec232,873894ce,525f9b4f,162f180e,1e2d6eb4,c846bed4,b2109700,8fbc0b76,afbc761b,f4c88e71,9c318f05,9a10ab3c,5a477ec5,33243b95,3f8ef006,69b4f92e) +,S(b0076c4d,e3c94fae,23659b00,5b8b41fc,b8473935,764e48e1,a9eb1fef,f5c94e54,e1eb3255,3c55a687,6f42ee5e,44830a09,fe17fda1,b84e8551,f3ea2308,f9c7d4f) +,S(9a1fe9c,17c4255c,c11e9fe3,3d66787a,fe9ebb0,99be88be,94b4c3f0,da2d0c11,e6aef709,99a8e739,6e23e1aa,c7ad1cab,25f6fd6e,62df02b0,96af568d,e88e8379) +,S(1d89a934,126bbc15,d9b99b88,b6c65106,e1d8b16e,799630f2,2576e9e4,15212899,b7e32256,92db0722,e9a79ef,7d95c509,37d64644,ed36cfd7,56780d59,a6f8f4eb) +,S(c60f5c68,b67b3796,3c462d4f,7530edfa,34546956,21bc80a6,ac2be433,700c7fa4,88f8b071,97fff0e3,a19b5a67,60dc92d3,b5507b53,5cec02c6,53f75a60,bf8a7e08) +,S(52cd2b6f,d9b2699,1b76499a,d301be43,6205761c,f768eec9,e6b7d6c2,52d9d949,d127cc66,1fa33508,a0d11a3e,ac782b26,26356382,f547e4aa,13802138,30ec835) +,S(1e44499e,a639835f,f384f107,fd16bb19,c21fbea5,cf4e3be9,20a34024,6d05dda9,41c6a8e9,a9042f9,950d12db,74fd0f21,8f8adf23,e961488d,27412c2,f2d1f53) +,S(139144f0,a56394ba,d1e53bae,360136eb,984ecc56,56a05cb1,c6727543,fc6861de,70394737,ff37e9b2,1bf174ab,6c042bb8,964f3d01,6ea1edc1,25ed3b4,2ed0742a) +,S(934ca02a,2454df18,61fcb954,6634e685,34fe75c8,b6db6eb7,5a2a74f8,654a2280,779e9784,266cfca0,b83caee,74fd24f1,6865ce3a,6be78be4,375fa15c,db195761) +,S(a64f047d,9e1c2459,77da8c32,9d35ecd4,af913baa,2d4b679a,7acd326d,886a3be6,e11e830f,f3b4ed6d,102145e3,b24759de,3210f309,8ec57581,e6014818,79112b2b) +,S(e1c688bd,cd629088,8d8820cc,df15fe8f,cfcf45c4,b8bd434e,2a15428e,818757e1,bc10c6e1,71e7c8e0,13b8e00,e77bb745,a34e7d1a,15267600,d130f6f2,18c77f7d) +,S(b1a30c95,123170f2,d9456de6,827afcc9,ba2bded,d955354,c6deeaac,68137358,9c76a0ab,c16c1caf,d3844346,9040373e,a678797e,dfa1b298,5a17d410,b04071f5) +,S(24cc27b5,fbb0291c,3468ba23,58f5e253,4c7cf99f,699af4d0,d6892bea,e6166e85,eaf369af,2516ba42,673c52e3,ff0768fe,d51aabce,2312b8dd,d7aa1ed8,cf9f71d5) +,S(8bb4017a,6166d1e2,f7fe8921,cbd31cee,bacab577,84da8a92,217aab2d,948f6a57,c899740e,6c476986,356e34fc,7182996d,a09cad72,93d78c8a,5c30d56b,88dc331) +,S(55d8b7dd,d82fdd96,e0ec17dc,20b303fd,e6dafef5,a527368b,ec99a33,60497f6f,fd624511,78bd66f,4361709e,44e72e9f,f4f29230,d1fff657,bbf84762,b7b8beca) +,S(82aa2def,5a5531af,519cbfe6,105dbde3,109d4626,ec47a845,5dbe2852,34c94df3,61160bea,9f83a2e5,8c2df91,925fbb25,8d1e60fa,6a147c4,ebc0ee38,cd811511) +,S(36c1277c,c6df7ff8,47c2cfbf,3cfa9198,804b03b0,c28e1636,ad3438cf,2cf6f7f4,2304fba2,74f81c74,5455d821,ea58e047,a7bb3b60,e32f020,aee5a2a5,16fe4833) +,S(f376fdcc,5b44cad7,e16c9e86,c00b366,d57b8925,fa49b18c,eb8856a,e0cd9119,2d6acd32,e4dee81f,489e3ef,11acfc8d,c3d0e7ac,bdf5c6ac,74fe7aa0,50a028cb) +,S(ea4e10dc,5372e9f5,d96e8ecb,907d3a89,97150b6c,39ecfd1c,c7aaacca,5dc5030b,b0896ea3,93b626bf,c2f486d2,9fdeb897,36d6be60,144fc3f9,5206666c,36d96ff5) +,S(74f392b4,b2664a17,9d3f0a2c,71b144b8,a376ea19,f1a9d91a,d181ca3,a6fdeb08,9bd4db21,428d588f,64ecef67,99b46735,c9523036,406d2636,c6eee083,e09e1fc0) +,S(3a36c842,59ba7774,a41a17da,f0e4c821,11c13a6b,58b82774,ca6962ef,cd4855eb,6ddad1ad,9ede928c,d65720c7,15ef39e5,f35e46ba,45d8ff48,2f095d2b,e0fa5e3c) +,S(9d77b2ad,5636a44f,16e73981,46b17ea9,7635ef18,8f32764d,eae50d2a,5c98c019,532dd027,a775861a,b9392b8a,cb2db097,eb5936cd,9d2f7234,f30c371a,22ee3eef) +,S(2e7402e9,450e2f80,e05168a0,f0c5f1bc,deb6117,ee46ac1b,39aae7e7,bea3c4ab,41e8f36b,5606fe2b,8ed6b3fe,f8821013,cf85721c,f242eb60,34b82afa,cd82fc3b) +,S(aeb2cb25,4ed0b5bd,81b33d35,e8f00a5c,6a6806f1,5314b320,de0c376e,533ebe6f,6b8116f5,2d7bfa2c,b3028249,fc83f317,5d761c0f,76833d0b,142c4d6a,29b9d59c) +,S(c86224bd,55d62c97,a00adabe,3a797929,4cca663a,ba3a3655,fbbcc3f4,5cca7895,a319a3b7,104f7935,36693adf,a6009db4,1d857353,fa950c21,844323bb,cd1cc214) +,S(1d1164cc,2c576a0d,d7b5a28b,cfdce6f4,d53ddde0,534b3a66,aaccfbba,3eefe561,b85890de,aa25d897,fccba694,7c470e45,ec600989,243ea91c,4670a,b44995a7) +,S(2b54fab4,13b915b5,ce76620a,5c493ccf,5e7f0f41,8bcd793b,92f26118,a440e3c8,8aff8d25,56fead8d,7e9bdfef,bddddf37,7a61ce4b,2effcdb,30ad0016,4f9bf5d1) +,S(1f1f2a24,a4e72a1f,609428ac,853e46d7,a9718c25,f2df9887,9a3aa60,5729b340,450dca4,f4920bba,bcf94f39,26871032,b631120,4b217170,991df216,2c421cbd) +,S(412f658e,e6777e4d,24e5682c,5007e057,83fbc559,f22f3200,f185ee52,c8ebd4e5,c2e0b64a,9d9394fe,b930b3d7,afa64cb1,c8399e3,27690e32,887b789b,6571c8f4) +,S(8495dcb5,567791de,976fec9a,367e250d,95102ef9,f92c11fb,f561f854,4cf4912b,65f809c5,7d3d824e,f5e63f19,153bda4f,542e511f,464e11c5,e2a9c32a,2a152443) +,S(f8e7bdc0,d841c95e,3a945b8b,c85ca4c7,b4a18a9,7a5646ee,1bb4ff08,5956cfde,cd0ac83,f93a3679,37c9d28c,24b9fc08,6d6660d6,15df5011,1b4edd5d,f0ed6d42) +,S(8324625a,4e4c1071,24876751,7df28ad4,8c8c5648,76e4a131,64f2f730,62854c94,761b1960,49922825,609c7ec3,70626025,de65e2cb,240b8356,1f5cc230,1f9bfaeb) +,S(8b1c49ff,99f87e22,af4b6bef,d353df1e,16a8e160,3023f2cf,213ed859,13ca04d4,cd4513d1,e178865,2d1cff72,822de250,6abbf975,7e2774c0,2ca1bde3,23ad6c23) +,S(e2ad61a1,20d24d80,8c830e89,d630b466,59deacf2,87aeb790,bcaacb82,96f4f138,51cd19dc,fc1c4867,daad2940,5acdc7ca,91849769,6003321a,bf5dbc6f,b2186291) +,S(e8dcd7e,a9a9a6f3,16a6aa91,53105601,e10356ce,7f4793ba,9eae3ad0,34c197a4,c835bad7,91f3aaf5,d32e2a99,e71c4add,95f69892,6a68695c,2e61ca85,38ea6b5e) +,S(f0b748e3,5875b8ef,361bba69,cfb05c4,d8643f95,9b207556,e46908e9,bcf81233,6a264e51,5d163a7b,678765f6,c29ca61,c1c0aeab,a9ff423e,91e9401b,2dd6e908) +,S(900de96f,9975a16,766dd305,bffe2423,e6eef8ae,93ebd796,2ce97d53,39af3a87,894ab2ec,d9c058a3,a331bf65,dbe69a49,f33f8e9b,12121439,650aa700,4d164478) +,S(8cbe7930,d2ea2342,730e306,7e9ecf95,ce7fbda1,e6d34645,a6e214a0,ed88aa53,867b156b,f875a67d,ae27f2c8,e232c934,85092c70,ec071ac9,919ddd85,70186b83) +,S(a0cbb1c9,5b35d243,945a65c0,fc5706d4,e79237df,c13583e6,9a292fec,9a25e68d,b6d7e9d1,3cd61a45,f81c8a55,40dc06e1,3c6d7024,5e850a40,55ba4eb1,82047e4f) +,S(148aac72,a3fa8cb5,aa6d3bbe,5e987fc,d8050c3d,63b47f4c,832a4488,262463cf,7f29de49,a6e24485,5aa45f6d,36f2e2bb,72749f91,8258c0b2,92a33322,677e4a61) +,S(3b9fed07,3a1afd6d,e6ecaf7e,fa20e2e6,c28616fa,25a218ce,fb07cf33,66f3977f,f0a85b3c,5084c964,a1f0c936,e96ad3e3,4fa9e7a1,348ed0fe,ac7003c,12c65fc9) +,S(7de45ced,5228bfd9,557b443c,30fa431a,7c9cbcea,dfbfe0fe,cc565ac7,ce3537aa,515ddd37,69107033,bcb794f3,ac55062d,78e0118a,60c98fc1,1999cdde,fa2686f0) +,S(9cc1a35a,534f562,98010274,74f3a857,c17cf99c,eba1d5aa,251e61b2,55913dd2,c092cda8,f30fa4f9,96115da3,7bf8e12f,c653e243,af2bc7cc,c691684c,3e433ae5) +,S(d82f1968,759b3b9c,c76ad729,828a7283,10fc71fb,22258562,920b690,7ab52ec6,54cd0a05,26983b0c,73808f8c,ae1c9d81,1b372082,dcac3306,c470af50,8818c607) +,S(16e6a947,3d95a95,c31bffc,c291b60d,1f9c548,85e5a498,24195ead,b87b7586,19e29938,581b6b8c,2e50d365,5a957c04,80ff4c8e,4ed73276,f882c558,dbd8aafd) +,S(d07e7af3,ee4f24,e46b4670,477c3463,ad57a74e,57a17197,ff098e52,3b5cd237,fff34e0f,43c91656,69b1019b,ef618888,d4d175de,b6f20b1b,c696f24c,135d0e20) +,S(2bf644e5,6dc027fc,63a118a3,43faa4e9,8ffe42b9,c983014,50a1f4d9,e5665380,bef5c175,77be1fc5,f8f66fb7,a06b55f7,eb84ca5f,66ea4477,c924f925,5a262ec5) +,S(518f0d37,db1db93,48c80101,442597c6,7a88107e,5e25fa3a,b97ed524,fc5cb045,dca8750e,a4e9ed01,66f113a1,44974250,6eb9f3f4,df8ab741,8dba0397,694d7294) +,S(bd48eb6,c50774a1,2be9893f,8c21f624,57bf54ba,8799928e,9a9c725d,6f0554c7,200a6da8,cd8f0300,6774bad9,769f738,dd58f350,632742d2,e2cfa787,f570f6e1) +,S(ccc8d93a,871169e3,69336622,b64fa1c0,800c5b45,e3c0b130,2aa99e34,db1517e2,40ee7e4,d45e6478,efa11f1b,c4548668,88837309,4809f056,11efd6c3,6d01d845) +,S(86f6392c,75877992,311d2e9a,27be9ea7,27e8d01c,fc27dab,8f4527f1,dbf6bd1a,7ee29611,b647aa2a,3d2b1304,c49ee690,57150518,fd46add3,e7caf34d,10f7922) +,S(e034f4e5,927b0fa6,c3794105,338751f9,9bb5a381,6da1dc1b,bfc41d83,b7d7fdfd,dc9f02cb,838242e4,13282b05,cbedcab9,e902567b,b279fb6f,f2248e75,41a5f89d) +,S(8fc36a16,a9dbf00,5ee3a66a,b825510,75eadfef,b86e1062,837b49cc,6ab51045,c7ee2c40,9605981d,217d9957,a004a4be,66a88527,9ec9f74a,70594999,23d200a6) +,S(d7bb40bc,54077d96,d6489b71,e65dcfe3,997130de,b517d12d,9c10adc8,e73278e0,e2096366,2f64bae4,5aa0706b,d96b5cb6,5897c0be,3a8a9b46,8ce9074a,a68b0a4b) +,S(d7357685,8054c714,1147d2d6,c265ce40,3c882681,157b07e0,b8be0a88,63bd2ac5,94f8754b,2fc94239,c254099e,9cd5804d,d2ce03a5,380c59c2,4f42ebe5,85a9932b) +,S(5b6f8aae,d9353ffa,71da7e99,bd3fe165,3e720ffd,657dc2b6,669ae0da,858f8392,4eeafd05,369c6eed,fa6f85ec,34e245f3,e4966840,30253c10,6e74f473,418f9089) +,S(39444d12,67cc29e4,384b4f4,9c4f4886,ab4076a0,19a0fb39,f7b72c4e,42222000,65c2502a,af90ee2d,8de48adf,35388eb9,329f3057,1b77d0ba,50ea01a1,ca83d771) +,S(53de00db,f1efb0a3,c159c4a7,dbc9888e,16ebad95,cec2d003,a18488b,1b0752c7,328ecbd9,99475dfa,752d6228,5e7bc51a,87dc6166,4d14a6d3,3a556322,5e2fbda) +,S(48a3baf,9b4f7213,e280eef0,d5fb6033,194d1bce,eb48d9e3,d4814a4c,bd5ead39,3b4ac9c9,e04a3852,bbc6f7fb,cc94b20f,7e749eed,44a9a9ce,7099a8bb,28334186) +,S(f00d7630,503c1ced,3c418237,27e22d7,acccf406,fa16eb6e,b524707e,5b3ac541,9a1ddd3f,ec177626,b1254605,df8ed593,c9e2bcff,db7d0404,f47571b7,31ca95b5) +,S(e1ff1994,3ce7eb59,e570858,2e8c21a0,c4f8eec8,40815ee8,9a482658,8941eaac,528e5572,746e72e6,ce61b53d,78aa57e9,dbf27e3e,bc36c3dd,3b4972,d7353b7e) +,S(e4f13c20,c48e750e,e15a665,275c27be,23b3aa04,5915ac55,2562bef0,7459bd49,bebc7ece,c6e51f99,a2e6b9d6,a7b1bbb3,63901053,362a9ebc,a2d21cc7,6e87ca30) +,S(e36e8cf3,824b66e8,7083d371,60cf2719,598c6c04,ac693ea4,d2dd5c83,886f5f20,4ea0e193,8afe57df,3db74910,481a54dc,f5be9fe8,64f249f6,c88d0cbd,a086c60b) +,S(51e1f319,3286d2fb,29cb4a06,84d7c547,797ff5dc,fde9572a,63dd1e0d,2646365f,ac470e3c,6f30ecc6,31a90d7e,6c4c3d43,b8640ced,b9465cb2,ace2cc87,52370e3a) +,S(8e82daa9,c40d4e72,605dadd6,45bc26dc,22277f41,56d2a248,29bcf79c,d5a5fae0,7f8155fd,be9057b2,2b191dd7,233e291b,b01b961e,32a124d7,33ad99b8,167c53ee) +,S(79e56744,273c7aa4,34ffd5e9,525fa788,38bea674,64e2a595,9881b359,3e2c41e3,625089a3,c50defb9,f00ec764,b47122d7,eb786a20,f278bc33,e806e7cb,f385ecab) +,S(a97e00e2,d19c1957,51deb891,84e24a22,af7fe156,f2f1e068,79ded3f6,62743f79,881d7ebd,8bcb2c49,354726bb,c44ff91e,f3f5835d,ea73b282,944a5097,cd8284a0) +,S(3bf10546,7bbf5c3,14e1c3fb,40542378,9bc52fbe,8fb38aa8,f4a70727,b338542,e789586c,fad5b7ff,6dc68e5f,ef840e05,9a87ba51,e58462b6,39042c64,24f6367) +,S(80296c77,58791dff,39b4ee87,ecf3406a,49cce0cf,8437fb2e,1f4880b,55d9cc5d,3b06be11,3c7f781f,ce28753b,708bc514,902e4834,bdb09284,846c4ddb,90152dcb) +,S(48e2cb7a,a3eedbfd,f6a9cc12,359c4ff1,b7b0fe4e,87e57023,59896506,20ba52fe,dc78417a,fa909bbc,594411ba,87f72ee0,a0a45631,3cff4aac,7ad564b0,9ee8ed1b) +,S(dc91351f,cb775488,286b482a,a187d79c,31a3db2e,99730b6b,7b4805a9,73403d46,ed720e0d,2d13192e,8c180ecd,5e09fa5f,fc52e35c,4e509b2f,fa93ff96,f7adb1a3) +,S(5d37c139,48ceb4fa,9cd05b15,1fb344e9,3a2b2653,5b052b9f,1797319,e990a670,f790933c,2590ba48,7a832ad,6b940634,b62e16d2,7c9e748a,1856d53a,1974cb01) +,S(98bcbab0,f8d69b22,6fd7eece,a848ff4,15c8e325,ad9e8157,708eca17,77070aa2,7671e3b3,db715487,e6affd61,5218a7ef,a08aa949,9bb10206,e2de58d,ea150212) +,S(60e2c1cb,3de9486e,fa594384,d5903340,12ce308d,2247a18,8fa5c112,3f35b1c5,6de7031b,9767c66f,5c3c11a3,853bf722,4d58d086,b68e08fa,63942f2f,9369d1bb) +,S(814716c5,aa8256b7,50bf2f70,2e2f9bcd,aaf513bb,329eb467,d873ea72,304885c7,eca644ee,8fa96189,13fba31e,23533de9,eb7efac9,a0fcb58,6300a42d,c7d297ee) +,S(25789f3f,1db412ef,af60f7b,636686d5,9fb71586,200e8e3b,e6d934fb,72f8de77,e5222798,99d1e21b,5734a6f7,7881a686,863bc03b,8c58cce9,633c8302,2c7de0ac) +,S(5382f40c,98bff8e5,646a87fd,f3fcb6a6,27f2a91e,780a1527,ef18cdf2,a0f1bdcd,231d01de,e41ca3a1,da068ce1,39d97a16,39c027d8,38c7879d,9a1e85c6,4a32b502) +,S(448cfd20,9db2fadf,fcaab14d,8f57dd01,67d9ecb3,f18e9dc6,e573238b,a11d1f2b,bad8e2e5,5a4f56c2,435e8d18,14d2824b,2ba1bb67,9520587,5a11c315,9166fea6) +,S(d917ca4b,fe6335f,5012b69d,5444bbf9,f6c4893d,eb612ab5,667afbe8,2e5653d,3fde9a4b,e6a49756,27950f1f,f17ce5f0,aeabc055,3102c33a,4bb85bae,f32bad17) +,S(c7ee9f5,17a883ad,733de053,be3ef583,1dd974e6,a4e8570,db35f24e,91ba8f72,8db7738d,26d367bf,657d2a31,c6a08ce2,e06a7e4d,2df39f3a,2bffd062,79bba44) +,S(83f0a19d,983ed6de,7a2b173,77c843bc,819a77b8,a32acaed,b7085e0,94d9a30b,d2ab3e96,67be4473,d8748b63,6113be60,880acd47,6d574e00,c37f4875,2cafe6a7) +,S(f3f8aa6a,61687c40,98fb56bd,e74d83dd,59674079,7c52f2e,2b299277,2313989d,3a690c9d,98503a3,2d201ff9,a896365c,caa1b54c,36857a21,ad63994f,41a109fb) +,S(4c1a11ca,a30bd6c7,d95d6e8b,3ebcb4e7,914fdd40,4384716a,283ee1ff,5032249e,e7e718c9,4653ef40,d214c604,e65339d0,6598f17c,37f82880,9b7e5215,b9424da0) +,S(2941b952,3419a018,53f3bdb0,420f3182,529ebbc8,5a1c8f6c,1d922c19,3ee5477d,377f226c,29ca66a0,aaa05baa,7f6c1ede,80482b51,8982763,864392dd,3e628413) +,S(9d04d07,aad49af8,65bb3eb1,8c7078ac,4b5f25ef,e18572c3,3842161d,8591a6a1,f572968d,ec2ca89f,b45ae02d,119644b6,779eb0ca,1d48f724,f8512ba2,2c83cd34) +,S(4401f767,c3c3a101,b99a983c,9a622824,d660c50,177bfef4,a2646b06,43d26e20,7952faf7,8e1b114e,16429309,1d0669e6,999f8bde,ee980c0b,b7d669de,86d4e342) +,S(94b6f427,fc4017d3,b328665b,acc863a8,ab8a1c4,7b283fa6,8d7b7f0c,1bbba31f,1336067d,35f0d2d4,6ec8199e,99dd07a9,9cbe7725,a9981868,e09a0217,df40d85a) +,S(41621ba2,92c79bbd,463b87cd,de75574b,f2fba59f,92025445,7389b4a2,4de7288f,355337d5,b6f30b78,81389951,fe67b943,3bc70a07,b294d11b,717ca2e1,a2cd3188) +,S(b0838415,6256c1d3,55900dde,6126818b,8a9b27ba,ab14d73f,c33c399e,fda3594e,2aaf9190,55b162e2,91cc5371,b6a4285f,843ef8d1,5069ec7d,c5d68475,c5a954a5) +,S(cc99a14f,ef418fea,5de9f437,7ccc1426,7d910f13,e8448fb,8ba92746,6c0dc9bd,2e30b64,7c01c12d,d42f164b,ac0c9bf2,22f7b3d9,2cffd7f5,c77aebb7,18536f28) +,S(8d2bb24a,dbec1858,d565d59c,1d805d8e,7b21d6b5,b967dd50,a2f420dd,5764e37,cdc6d730,e78daeba,712537c7,8a09322,fc371d0d,6a5645ef,e7014bf8,999f712f) +,S(63cee6de,f18cf4a,e6ca1871,7750e328,dbb94c6f,27422192,3b233a3,e50f7c9b,81230dad,ad2d233a,1b631b8f,7a885828,ce005031,e1365436,7ca34173,1efdfeb8) +,S(62084e9c,1dc6dd03,9a68d5cb,fba19dda,b2e4d07f,b8f46114,926a59e6,92755a0c,6dbeb4f4,62fb1af0,dc273a,aa827e0a,cc9c7f1a,fbcdf02c,c4bd98b7,5061a26) +,S(110c0eba,f65b6280,14e368ec,17072acc,3f34a937,7df79238,c2773625,5d8dd827,1a4ba716,6f236258,961d5865,b020b83b,c3c3e74,2dafaba9,649ff85b,2ae75c6d) +,S(d848a51e,50fb234b,a807306c,fab97405,baa50a5d,23cd12b6,8927c9e6,f1c87e00,9db9be62,88fb00c8,4cae4b1c,c99449ed,51fdb49f,3cb7aadc,16a72b6f,a96a4fd8) +,S(42311893,a2706ab4,52547f3b,3901b9ee,a8cf2660,581b0023,96bc9a7c,e14c2b5a,750f86db,9ba6222c,199c2a9f,77609a47,d6129a1c,e9ef4d70,daad3d2c,ae4165bc) +,S(4439c4ee,471adc41,32f45496,77ca1e32,6b252f1e,5f17f741,9fdaec0e,3834d37f,bd75c32c,22c5c3de,62f16ab6,6f86f93b,617c9565,b3859195,81a00ee5,75897e87) +,S(4dfce3da,b19231da,648b0bbd,8c52fdb6,e02e9e79,9806fbbf,36bacafe,c113b053,de8c5f1f,4b727fba,440a1c3e,147cc1a2,9d647c59,42feb42f,69d45a2a,13042c3a) +,S(3bba2b2e,e8e72736,f54f9158,281f6c14,9d0ba6f3,ec6d89ef,cddeff9b,8117dc9d,ff087274,77897e56,e5e93f94,7af6ca0f,6f9a2186,a6a60d2b,af690a30,da16ab24) +,S(a2fede43,37bc6b2,482d92ff,f55ab0c,e239a00f,4fbb0595,27f7d67d,8317deae,2a791508,43beffd7,ef08e195,d0ce022c,f780116,2f1852da,98c3638d,45869ed4) +,S(221c4e2f,f503eb4c,4a1aa8e6,77370085,b3d64d09,8430a185,2cb1cc3e,304bc0a3,c3c37b1b,f954e79,c124fd70,ad3f8765,a70a7929,4a262de1,99e11dd1,95b7ae41) +,S(a0c32f80,f7e4ba05,caf945b,49b91306,f909c8bd,559e4bfc,a58ef3c5,14740ed0,d3eb8f01,46ab4700,41de4cfb,dced45c9,966aa1c6,38a42c90,41ba1891,36f9562a) +,S(762e7a18,b4fe627f,1e1ca7,57740811,bf33395,cc962aa1,dff79be4,18da85c6,a0df0f46,50461c0f,4f8a743c,3455b842,5875f795,4af56b93,dce93234,c4f51ec5) +,S(2f02d935,cd95caf3,d56cfbe4,4337b1f,78389f34,1146f561,b8d632c4,b93a29f0,173470d8,23f190b4,f8008872,b23f1a32,9c45441,c12fe87b,e74e927,18f44569) +,S(c9f877d7,2eb816df,1c5adbd5,9fc98a39,c5877d6e,24ef1612,314e6392,e7eab212,14ce9917,88cf7eec,5a5a52b5,8fcaa9f5,88bb0052,754b3ad1,b0858e4,6a067c4c) +,S(cc4dff69,18a05cb7,a6f296df,6cbf5d0e,d6dd1c23,ae76c5df,239d2179,a0baa172,1cd438b1,b8471750,261b0650,663b4a56,e4dda0ba,b5390cd5,b7869448,654a4dc6) +,S(faaac74b,3ed2713a,29c10219,a78acd51,ca015a8a,65646a5b,cccec828,efcbfaa1,adcad43b,dcc2ec0d,bd65c46b,7fe79549,b2e74cc9,13fbcecb,f8bf661a,7d30d934) +,S(171356c9,30fa9bd0,da1444b7,35be6c0e,8a0025f2,3d1a2480,dd0aefc4,44fdbf46,770e9edc,991efb9d,ab44361e,d2398e54,62e2464d,2ee2a14e,b2e149bb,9c9bce3f) +,S(933f56a,e0473763,d2d491af,55f9fb19,c055017a,7a81b43,b641007b,e5680214,66059c47,481cdb63,481ea647,f494e541,ad1d70ff,93b1eba9,f85a9cab,a0ea76ad) +,S(a300f22,b182ad37,d7e44691,bc9c9c9,8a397f76,1ec1acf6,64ac1fe0,5bbb6b34,bd6f2ffc,a90974b9,460de269,4722f215,684abe44,6228b500,7b42bab4,5433593d) +,S(fc5e57ed,6e901355,f97c1d62,dee4d630,878b79b5,528e3fd6,85d6e3ec,af8fe1ea,1122127a,6c21cbb9,e598b1b5,68507bee,bc7c8549,345c9d49,8c4a9b2b,2f5bab01) +,S(5a2f40e2,7a64811f,bd4721c1,99019523,899e956,ea340bff,f3f452fb,5231ef3d,6b2bf95d,12578c79,74a06d26,39d71c31,d8c4a53a,6279886c,20a122d3,2093d547) +,S(59783333,df0b99c5,be76610d,67d7ef62,fb15757d,8dd1f310,6f9179b5,64f2084f,f2a9ea80,dd3d170c,813f4623,ba7583eb,7d309d97,c34f4c4f,a7676694,7e5b7f5a) +,S(cf61124,6b513fc8,73f72bb3,87a29c2d,a1c8bed7,4ca7ca08,1546db1f,37672d95,d23c3c76,697f0443,9ed1d1a5,661fb0fe,1e182cf4,2e07c787,3eff7abc,2f8c70ee) +,S(edd14f05,133a1480,e26eb7eb,8063f8eb,1cb871c9,606957ba,ac14b173,2ffe7d52,d682f280,d295d528,4c1b3aa8,445c274e,ee603308,ca4792a,61b5f8d6,34b1b70a) +,S(f9b0fce9,cdc8af3,8b26e790,2c95926c,33cb8d30,a5de80d1,75fd95c7,fc1a1713,ec7e8df6,f3d163d7,181083cd,c8cf4a89,df958b8b,d6fce2b5,d4752240,f2a3e6ac) +,S(ae906599,54187f57,89306981,7417c566,d9ea4315,f07094e4,e46bfd24,1746a3b7,2241bdad,c09d3313,e9d006ff,2a04709d,17335573,5be5b10,6775457f,231a129b) +,S(55f0f800,76492f7b,f5e134cd,e581ae3b,f68fe9f3,44107540,c54b350e,47d956e9,22a0891d,e68488a1,dfbb4b8a,35fe9835,e258dcb5,c70ccb98,2c8a48cb,c33956ff) +,S(90c8ab06,86fb40e2,31923bb1,df86647c,6cb7e3c4,c451d0c1,b871994c,19663bbb,dc748cd9,570eeb2d,c6fbb2c5,c417979,cb30d718,94c8e463,e3b7be3f,fcc80ab4) +,S(cbf47c2d,6b21ebb9,fb268e73,56ea849d,3e476d6b,ac09eb60,4bb2e27c,84a4c694,f0288fe6,8042894a,39abf8bb,e5962421,416ed9df,dab081cf,16e86fba,7abb2873) +,S(7c30885f,c18b68b2,8fff758,2148d738,d8f1bfb2,46543b16,37e9fce9,7d11fe80,3e2d1cb9,31a11c15,b26c6d37,8c886e10,52c06718,a63e621c,7ea51c76,3c013f2f) +,S(ad614919,d1bcba0,dd2a9da9,de9207db,e137c772,37f333e6,4f11433b,f66d7753,fcaea18b,3512a188,9d604619,2ba759b4,190b72d7,ec53d0b,aad9e01e,d239753d) +,S(8df7041b,af8c9c15,70ab50a8,1ed335b4,a7bc4171,a3939715,a295ca7c,4e5e29a2,e892e43,82677bdd,f3566b24,c7ddc6dc,e12eabc3,84a19a13,99b64ba4,bdce02e7) +,S(9f4c1e57,61c8520e,9a751891,ac1bb5f6,217f4e77,7dd88fbf,2a127804,2cfdadd6,fda210ad,c6cee889,c35831e,b3e12c7a,ed4b6963,9f3d4860,9d9b960f,4e7d0f50) +,S(a436f4dd,23ac70a2,c093bacf,91de3093,174de618,7525947c,2ee8ccab,a515acbf,c0e9d9d9,2a615b9a,9439a450,927bc128,5879e8b3,7d460ec,9fe57eff,7e19afb9) +,S(a38eed16,699743d9,16d8627c,5039695c,37497c67,c59547d5,67bdfa20,b86f1930,6e3e3ed6,effc3b5a,c9b5b5fe,3f26c91d,3be89bb1,48414c18,bb0e5454,49d9d7fd) +,S(5f4590d2,d4043a1,faf659e3,36b0f24c,b6f1de5,88e92586,83361eba,e2fbf3d6,250c0a73,42ceec0,3ec1af11,764e7ff6,ccc833b7,240466,15890be0,55197db) +,S(7565860d,c6ebb900,68ed16ff,8f7282a3,d52beac7,73cebc55,1be51f44,34cf56c0,4b56ecbe,526ed458,5428ad7d,e9d7f3eb,9b84687f,e01e1346,c32461f0,bae24c26) +,S(3e7c7fce,3a56ef01,cabad50f,2003a5a,77292742,be80b5de,c537b50f,95a9320c,98cd94b7,926e7111,f3778904,599fa9d9,d5dc342c,c495b914,a32d2722,93dbfaf1) +,S(131eb457,14cecf84,abf1aaf5,ec4c62ab,2ac91a0f,6af57552,2eb07274,b7cda208,a93aed4f,f0512604,46c61393,faec55aa,9b017a13,60d13031,27bfd897,e320839e) +,S(371bc601,e46963d7,388bff6,9c4b5f42,a98e68e0,2db3e6f1,637dd24e,a2a11ec8,e2fbeef1,932fa241,a9785238,c1b89269,21bbc7f1,3aa6bdd3,7b39d94a,49f84622) +,S(4770db04,92ca73e8,a0136bc2,2c45185,b4d45934,e4430237,1bcf5045,cae47d6d,e1af748c,25b1d906,ab77e080,d21df4bf,99a92f7b,4b1d790a,f1aeef36,2d41ec22) +,S(b31a8643,5af5db57,759dbae1,67ce3af5,e8e2ae34,20786fe0,da82812c,9594bfff,3793425e,860dc99a,a96a85a2,585b06a4,f5aaabd0,551fe0cf,3c743be3,c09aa4a2) +,S(e05eec52,84a2501,fddfe6dd,1619c374,a94121bd,7d1c99bf,9b2e665,bd3631f4,c0115f17,2122f806,99a24ea4,bd742425,4d883d77,6d269ed4,f6cc5626,ffb8e622) +,S(e55ddc84,ee407d3,45b84305,d97d3f57,e57810ef,bff3b35c,e4d8a325,2973d5c8,71f77bb5,b0fa6141,7e43e425,78ebb13c,abb87a6a,fa0cd1a1,26e8936,427ee677) +,S(ed7b6ab1,a5c8a9aa,284bf3ea,5501d33e,1aabbe76,f26a9f0e,d46dd23e,decd788f,2280bb54,19d1a620,18454a4b,cdfd82fb,824027d8,c51770d3,77233e01,1d0db63e) +,S(d4e331fc,3da4d8ae,e13a3329,acd4ee69,ce5cb71e,224f2001,f9606714,8090e79a,895141aa,2f63cd30,9f4a6b42,d6a88112,77821e51,6d08c52,1ae8e158,655e10d6) +,S(4f0ada0e,a8ec1ffe,6682545a,bd8152c7,2654718e,120d3d54,d648b487,896d4417,a603b9ac,6026ab46,47f5acf5,5a9fbaf7,20aaff54,56c88cd4,dc5ec7f5,935aa591) +,S(a2d13541,b08eeee2,4f086a9d,20df7528,a884cc05,4106b1b7,543eae3e,fdca84,5ac0b166,294d6b91,527a5249,7fd605ca,4bb67c35,85e002d1,74503b7f,5c803a45) +,S(4c1d520,14a0459,2b8887fd,afa945ff,cbfc4722,2ce008f,64fe8123,b5b6c8a4,243c4280,17b7918e,57d06597,f348efd4,ebcebff4,3950a608,3bb3e334,50ed738d) +,S(5f9e5a6,7d13e9b4,cc35b8e6,b2305cb0,fc2f5b7d,ff32ac55,1a5970a9,2bc54390,74808637,96965f7d,bc45833c,e8bedf00,85eb0cb7,26f3276b,30d9543b,7395ff6f) +,S(d76c6f80,95381b17,80ad28a8,80e29ab4,4447c297,34a4d286,98534bca,8954575,44b6c3f8,6b30e01a,61205178,90e429de,aa8273f1,277bc498,59c87300,a561b27b) +,S(7577729f,f78775af,703a9eae,b5864a18,6ad19f1d,dac658,e7a8a05b,d9df3344,6b519916,cceaaa53,92d2f822,98e7ecf3,3fa7c5b1,2e705345,32ec3f99,2f0afec9) +,S(50378f2b,457f04ba,d0b19425,86ada992,78700c8b,36bba67,fca916c5,8edc17db,cbd1451c,26bdcd49,1adbf40b,ac5338cf,26957364,f82fcad0,5fea3c2f,76273fc1) +,S(3748dc68,64365160,26384ba0,ec078ff2,7606eb44,e3d62b50,b9138be8,cc9ba86c,6c04e414,f624ae9c,ddd005a0,4e01828d,6e7bfb81,d350d271,96583c99,6611d709) +,S(b23a59be,8ea8d561,fbdeaea4,49eac729,3402f342,d05fd404,7f9c5d1c,57eea53b,bea47c68,f2d35b82,ce3c359c,83f5fa1a,95d40eff,702ed9c4,2fef0e84,406dfb9b) +,S(e4b451e8,7b42a5be,5c5f443,5701d2bb,9538fc06,925ccb49,ebfd71c1,16a64770,2af84669,9a790749,48efa86b,2b79b985,4cb261a6,8a9081e9,e1467b77,2f156da4) +,S(864ac6ec,65b8b086,346e671e,8651ddf9,de74a215,64f3da12,42ff7548,96dff165,f35738a7,7ab48555,91ca5103,c8d2bebd,b2cbf902,dfa93188,d68eb600,271a8730) +,S(b7d04a3d,a6a863d9,b7809022,56643864,fd36c5d7,9a056ac4,ecb27257,f02ecab0,cc40634c,6ba5dc23,e59e4e3b,fe6a07c0,1519abbe,7530f1a1,5ec7ef70,6f83b0c1) +,S(ddfc1af9,b51eddd8,2020de0c,4a8377cf,bd6e2531,ebc844c,7ca8fca2,714c1a0e,cf77c8c,1742c4e8,b22d9f54,a25daab9,c30f23f4,da3e1ad9,57b9660e,3ffe3951) +,S(78fcfe69,d5bb91e3,a13de26a,614d8479,e00c828f,8868fc30,ea75b47c,d51fcbe3,9ec67963,6b7053ba,b0cb231a,ac28143a,98021b48,4340f060,66da6e72,47f2d47d) +,S(dcd918de,16961d71,8222b4f8,19e76ecb,138c9884,7833a8fc,d4204dda,1115863f,abc3d8ba,c8d808cf,ca12318d,d13c2932,3ff7fb0d,813a5ed2,f5e52aba,cb23bb04) +,S(39ce2ef0,5de08106,93294eef,537bc212,e6f64fa2,96ccd2b2,94a0806c,c6c3177e,25eaf4cb,b7697a3,97a0ca92,6f3a266a,bbb5dda,78943492,39fd29db,78730556) +,S(495e4db6,43d4e89e,df50e937,e97ac4ba,1464514f,d3a46b5a,bae6a53d,3157a04,7d327e18,b2960d69,ebe4251c,f8c416b4,f84bb81b,a20ce6d4,6e6b1c57,e6ec1701) +,S(91c17e8c,b6357c0c,1c36dde5,29f9e6f7,a6cb6e97,f5b67dbe,fcaf5b96,637c33c1,2fe52097,fedb8ac2,efde2692,20f586af,f07b76e0,f685ce85,c965ec1b,a54c39ba) +,S(e3c4f480,3dffed44,6291f11e,cc5c9590,1c28749b,d6ae18d4,c0371221,d5ecfdbc,5a2e7102,571e27ce,974ad71d,acef8b28,4e7fb827,5453e40c,65b2be92,cbdc62d8) +,S(b3ee17f5,a0e81e7b,48814377,af9dcbb8,59ae7bea,5680f33a,cc15d8ed,75c25073,135a3c0c,9a6d2825,a6035afe,139ede23,b46332d5,5739ecb,6d092e7d,6cbfe86d) +,S(e4cca844,2bc91bed,342628e1,f6492335,7ca6e8d9,5e5b5732,29866066,eae76b75,dd55a555,39b5670f,f70b42b0,f319ac72,409f74e2,31d9cec,ecc8d90e,516f76b9) +,S(ab39cfc1,81c96089,998c02a4,64eae7ae,e517e4ea,962b6359,b5ebfbf7,da223b2c,def6dc57,b4dcbbe2,e6dcfec1,8281a189,72ba3b50,f996096,a22e4ea9,77d2fc4) +,S(22a32663,9e6e0469,fe4cad40,964f081a,677572d1,94b3ae01,f8e45c84,dfab402a,1c9c9d95,bd4e0ef0,5acf6148,44c98fcc,db44cf50,5d42af26,1b855f98,40d2b437) +,S(2bc788cc,eff94bf0,307c5ead,4fbc4dea,db269da1,7790a903,7c2fcc24,21f9cae9,172f3461,648c5520,44081c43,a8c78c3c,ccecb248,9d60d384,aa703e4e,24bc4b41) +,S(b930dbd2,a6720601,35a75bb8,8bbe69e8,3872c636,9fbcfe4,c622a300,2052729,9983f03,a872e8b8,2830e7f9,a7438b39,ff3f6836,3334debd,83940ff5,ae06f366) +,S(b435738a,2aa9ea40,702db448,da6f186f,29bcd03e,872a3466,f33b2e39,7514e3d3,5828d246,2d3c671f,85617e55,bcc34905,1678cb8e,f61c74e,92c54473,9098636b) +,S(c91f2e81,3acc9baf,2c52df27,d4180dd6,ee1fe67f,9db6223b,532dffb9,3072bd25,1c9c57d6,96c12f13,13afa0c2,b377e1e2,b027350f,bd24f455,69c15f07,85b73c0c) +,S(bb0946c2,8099ba93,8f28068f,416d9003,bad0d06,f8c7d31d,2b995f00,5c8d36c8,8e3878d9,3b575fe9,78fe1a62,1e978f28,1560421f,7782c164,8673906b,ed76da4a) +,S(485e3aa1,2e823374,cd506521,a707f367,5298dbf7,cb44f398,c31a06a4,8f085c8d,a12c8af5,7079b2b1,5a339d4c,302fc262,af0153e0,dfb4f878,a4b60017,86ca9a61) +,S(850f9448,d3282256,940da03f,e8a96eaa,f21d02a,78867db3,e8a9fb9a,713e844d,4551e4fe,3201ba2c,a74df3a,f58a820d,3a67836,a5a8d82,59ab2442,3bfccb7b) +,S(a74816b3,f66c1fe4,9f8e51b1,8eaf51d9,449cd4c0,54b6dc43,682c853b,be39884,4e7d5fb2,47ed7ea1,45af0cfd,c4cc1059,396626e4,80ec804f,15ecef7e,b372f7fc) +,S(2af5c56f,c71da217,79abcc1,73412016,e1eb702d,6b98af77,85ead6b7,7b20136d,7f3110a2,c6a82623,b2c49e95,a31a6b8e,783911d9,b532932,1b651541,86b706bd) +,S(9291ec91,a61adf1e,90d63135,fae60edb,1a313714,97260903,9684fee4,339b5834,d530506b,e8b0dbb3,fc09649f,1832de93,feef42bc,ade2de09,bac1dd17,bdd03884) +,S(160ad3c3,659a7816,4e9cb47,4e18ff6b,a8581fd1,823ce8e1,14444292,cc605b54,1618464d,5f28d719,a61f939e,b1eb91d9,a59f2c1,818dbb58,b6e1f426,a4d141fe) +,S(352599bb,8640920c,2d85a5d7,673dad8d,ea4280f8,6358a572,b4071934,60ba9d58,a78a591b,e8064f2b,22d7707a,d3c95cac,aa2ac3d8,638d564a,50f7d1c2,8b538d0c) +,S(ec20efbd,9a8c634d,92f7a728,1e9e15d5,adb37ce1,2236bf33,4d12c4fb,7b6ba527,acdb29bc,2a5a3115,3919315e,27af9d8a,e8c54792,fd5421e2,a9a57b3b,d51b70d) +,S(40d1e4da,8bdac6ec,55ee847d,c59781e9,bbd38785,1863c64c,5cfad460,e2dbebc3,c630581c,b7c92e68,a67c7d5b,dba3ec18,4e3755ff,27fb53ac,d3a2655a,316e9ab0) +,S(fbe12740,2faadf2e,2b1ac1c3,98b66df4,81674c2d,f0ffb512,7dbba444,e7d08c7,d00edcd7,f97914d0,3ac87182,14491698,f3dfee34,e6e8587c,52f2f7b8,b7f412d6) +,S(d781b5a7,47d191fb,8850fbd8,fb1e123,4070d9d6,2643008b,b0cd930d,c191eb03,a4aa95a2,5c74ab55,f95f2924,519b2911,9762ef30,248db792,d906b18f,346afa11) +,S(6472fc42,d926bc7c,115045d0,395b5e9,22790c39,ee520529,44a446f0,9ccf02cd,512014,a92593de,e2264e37,633c842b,45d1ab5,e2ad068,63db7894,4605a99d) +,S(eee180c2,e09601e8,6a517a93,54607a2c,5fa6cf26,4c80ffd2,c5715ed6,395e0c21,c8cba798,221d6fc5,b4fdaff7,f785ca3,49490af1,ae655711,e0649669,7483e7ea) +,S(900b262d,a172ad41,15bec071,c5763077,9103bed4,db500ab4,fad4b750,45ada2d6,316457f2,bbadfe91,3f418e7f,b3fa34d4,82c4c1d8,516755aa,371423e0,51e2cbaf) +,S(7e93db87,4e1e5070,772d3371,b9ef29d1,5d5e03b1,e66bce20,420801a2,13a34c9e,cdeaa624,750032a6,f5faa0fe,e00cdc10,63f3ec47,b5bfb56a,bc2c2339,e38465a8) +,S(461fb424,65f3a55d,e66761b8,44abfe3a,d172877a,3edb1f5,da98c82f,89a379ca,768261fd,ba032718,f5501dad,c05e41c1,1f584aa6,6b8e732b,7f15285b,18e815d9) +,S(1d9f581a,f0f61a0f,e5d0f0cc,91ba4f93,6de28aa6,5f35059e,997de778,9419e09f,7fe9c98c,7d59dc56,160302e1,89676f54,3f02db1d,622251f8,adf369b4,891bf6cd) +,S(8cd70b52,904b2aa7,240f7a70,e4efe379,66386dff,3ccdf62b,e2343821,767542c6,b3c3d03f,4c7e0b1f,f08bb2,f72bc6ba,e9e293d,886541f1,ff86bec9,b5ddc2f2) +,S(a0b547ea,9c08865b,99a5b8b3,800daefd,99097b23,4e442a2e,819aa628,eb4a5261,607ef115,e585100d,c003cb4e,1a27eb60,fd9d1e18,f2d23a22,80cddd89,f2ca2952) +,S(ea8a60f6,547038e3,683a649c,27e81ab4,192406f5,5fdbd775,78dd6360,4344d289,98afcac0,b05ad5ea,8fcb9f3e,3bc22f16,881b5fcf,5060c691,ac10f746,79822fb0) +,S(e6051a9d,882f9ef,77d488fe,55bb7829,48bce506,91350755,1a8cd4a,14b0a711,1c9cdabe,9d9eb555,cb9257b8,a60af75c,c1ec0c82,4d933498,ffaa14f6,2e920fce) +,S(600876c9,c50fd337,6ce5efb,c07e0e5b,165338c5,4f8eaa4b,39a525e9,88765674,401a671e,f52b21f3,83df5da0,aa0b215b,b044202e,606a746a,213796e4,dbea4189) +,S(3b045b9c,5ef6fdd0,9b3efe12,169e0414,3c0eca56,5b7e0185,274f1e97,f6b2ff40,aa5773ac,b21107c4,2a8085d0,5d6914c3,a135a47b,cb136dfa,d20e6813,62780a28) +,S(dce98d32,ee0b55e0,4d67807f,ded9cef5,f9504b1d,e552a2dc,643ee7f4,b1f0f1b6,d03ac27c,9e992497,cbb746d6,7acf5427,aba058e2,801df1b8,d435a1de,1f3fb086) +,S(365b1148,6e8a60fe,8a91c07a,93686787,dd5aea7f,22fa1449,58be984c,e378fd76,2c7f5217,319e5d50,4c5ecbbc,bdbb8ec1,b36e2767,54f405c3,f852b761,ef01c9c0) +,S(2e37935a,4dc465ed,ee8dc3ca,d4ede356,3c3720e8,57c986cb,b9c73b2e,ab6b5806,bd0873f1,5278f46d,802dc7f9,d7f81a4a,839cb690,10c6d522,c0e3945d,4bce346b) +,S(49b68e1,93745ad7,b60ddf92,70d71958,81cd8585,6e47b0bb,fbae94,f1647568,ca1d4bf0,13e43ef,53bcb2d0,5f4b85be,1dc82d31,f4a7795,755693c0,72819dc1) +,S(6df53d6c,c79c5a88,2c2b6f66,e9ede075,6c8cc6ba,3e60620c,b8130fcc,fa744564,48c3d6ed,3b2b7c59,2472f291,41a61495,4597f77c,afb576e1,729804d1,26431344) +,S(d99f8f06,9104e3b9,26163672,767145a2,2f9467c1,c8e32b8b,d28e170d,bf4865a1,ccfc46b0,55aa5d93,64e67c4e,2c06cb18,c2b43333,e4111479,fd1bfe50,52543d7f) +,S(77727c17,ebbf8338,ba807572,8558a059,e23af7fd,c68c342a,538ead93,e59930d1,a037dc7e,2cde1802,fe3bc65,75f50ca4,ede75194,133e7083,66de0338,40c629ea) +,S(1d40ead8,563a4ff7,c14c84cf,ad1339ac,36ae3789,99ec2663,77e0ca2f,6be22604,8497b443,b093917f,ee65a5ac,1c4dfb87,3a6b0c2d,a968d713,a711ec12,20d1face) +,S(2a39f41,adf5ab33,71a27c20,51840d37,e3226999,17a3d0ef,40590710,406bfae0,cdaf7a8,58e99fb8,23a36b04,8e844c18,8dd1a49e,c70488ed,155f2ac6,905c27c5) +,S(aaae4b1,d8b08cc4,8971cc92,fd974a21,66f5ea92,b6ce215e,28137088,19c684e0,9237995,c10a348a,84fd5cd5,5151e33,c63739d1,3a425bde,a34d78e9,e3cd8f0c) +,S(a5b0c042,591a53b6,334939d2,9ac2c9e2,11315a54,831ef440,965fdafc,e6477d40,ac3e7cfd,5d1f0248,b362b206,b3c7dd60,bc9904c8,d2a416d7,e117a5cc,4a62ca6) +,S(c1b7164,e6166a96,a8f643b4,7f094be4,3c16e3b5,3ebf5a1,2782e41f,27c63f0b,8469161a,4ffaf1ff,5b50ba81,1de3ac79,e34810bf,73ed1207,fcc0f01e,75663a98) +,S(98fd825,4b7963f0,4d8e0f2c,8eb26dd0,342e605d,8fdf28b4,57b98e14,adca63bc,e297a80d,213f6664,77f9dba6,5cbcb99d,2dc14325,be12098f,22061115,b1a192d6) +,S(f1f08649,71b6ed49,2d34127d,8c2e6f19,48c464cd,816acdc1,63eb3aad,594c3281,26ae2a0,f9e04fa9,13b8954d,85602e6f,506a0de5,2fdec31a,346338ab,f31f5c) +,S(ff470cd,c324d2ac,a63441ea,c0506fb5,b63af83a,61a23a91,17240e23,930dd197,e601f66b,b18e77e8,4607a772,a1efa73b,30734b4b,8fd31eba,5a5260d2,5627788f) +,S(90eabc6d,968aa196,b5808127,baabbaa8,ad0f82b9,332ed6dc,d04442df,bc6c63a6,d6df0f67,ffb23cd7,2dffc4be,44476b2b,2faed3e3,dcdc30f9,4c1fa4ee,bb5038f1) +,S(e217b126,acc507a1,b41e0826,b300363e,bc0a43b6,feaf3866,ecd4b8bb,cc7e11af,7eb28def,83db33d5,8b8eb733,2b27a386,921e3a5f,b0321ecd,a8d1fc6e,49e98f30) +,S(2a196fd5,82b85d5e,1772bc21,84d8aad2,b5d008ee,c795628d,20de68a9,fce1d184,994b4657,ee9ee3d4,fdf8dc8c,cad2ff1f,68526c67,89d82230,c3399f6,62201303) +,S(bc9e3bc8,3a6eca7e,8a9897c8,1118f7be,ca770cbd,7e66c2e6,1321d026,7ade4342,9d7ef7e2,d544a561,ab899291,75f35d24,e2b07661,2f84b0a3,f346542d,714f3f4b) +,S(ff2813f3,842a9f84,fea9e367,6f12f209,7e76b8ed,e691ccdf,6f6512aa,b2f198b3,206e3bd6,66d0c161,ac6de438,809f485,b8b6682a,f402bf76,18a484a2,c3fe1949) +,S(6e7599df,2d38d63e,be142321,769d7ca,34a50bbe,4e0adbaf,6c7479b8,d1af05f7,233dcf1d,4b0e4d88,4a9ed56e,b6b4946b,25614345,ecd182cd,5556faa5,e3654c8d) +,S(1edd9cd5,6c82eb28,14d844d1,a9e5c167,8397662e,b576f9f9,ba250719,33666146,a00f4a85,b2ee83e,949b5cb0,4d16820e,39d48ddc,95dd965f,e24251be,3df43f4c) +,S(2723de06,1f794cd7,76a4a090,738a81ea,818a2f73,92d7ab07,18d79fb6,407324af,35c7a9be,f9810c50,3c53429e,344ab888,38daad72,77cd0e78,3db1c1fe,c6bbf41f) +,S(4c4fb244,4cb54def,6d9659ee,b43c13c2,3874ec2b,a7c6b53a,f469ca26,ab9a213d,bbd2eafe,56447a9f,feb9ad15,349b338f,d4a1aed8,5a356472,82751e5,5b8efa3d) +,S(736359f7,347995a8,8e306977,1fb3fbcd,12847ed2,8e4e612f,25095720,667593e3,23bb37ed,4bce0512,35a215ca,6b8f9868,e303fda4,80d655f9,72c95bf9,12bd3741) +,S(15cb9594,ee936bd1,4b981394,60879bee,6f33b0f7,c0ccb293,825794d9,85f595be,aaad772a,2ec81ab6,13775e9,edb274ef,e2e133e6,5e58949a,c7f25429,fb1bb152) +,S(3b5489ab,97e5cf1e,84a90eb8,20b8772a,df574777,a61f0a9b,41e6c567,6be78fa4,145d13c8,e9674a17,ccecad63,f113d64a,d59a1eb,bbb10cf9,e7134cf6,562219be) +,S(78d1b99a,a6f9d385,b09bec7b,b59ce26b,23323e4c,3a259c56,68417597,a29dd2f5,1c8d11f8,e883b210,cf54369c,e9f6a280,a6b890ce,15b4a0ef,3cd8837b,7e16a122) +,S(385e4e8c,5ceffbbd,3a813e3f,938912e,d2fd2d18,2be81210,70cd15fb,39661e85,f4a1c414,9f5cfbc5,213ceb21,c1cc08ca,c9b168e2,58cdec70,36e2dacb,ab68069c) +,S(310f8c70,d8e46c6e,48930df3,c53e9292,a7c87230,292d6b1f,c28d9711,951aec6a,6fe319d3,c92c07b2,56715154,d5d7046f,59d92d5f,6dcedefd,b0386f5c,3417146f) +,S(764f3c30,23d1d50a,e170b80d,48d58923,c1f91a96,42210912,94066585,d7c70bbb,bd92fb1a,becdb4a0,ed941146,878c99cf,c3ee9eb8,c8f2b8e4,b547cb40,e3dca724) +,S(3d5d23ba,b357a37f,1bd3c86f,84010b8a,b37a8075,3c47b1ab,36f7ef72,a3e68126,2bbd1841,bdcf0265,838893c5,f5f9c0dd,7ccbb461,93068e0,8211595d,6b34255b) +,S(a70431ad,cdfc7b8b,febd2aff,d6759e94,6d4ddd7d,50f50dc0,87e256b8,2a7f8a1e,3ca4362b,9362b2ea,c33d77e8,befeccb8,23163921,86ff5f20,384247f5,9147f593) +,S(2a388212,2c1b2ecf,3c800432,7c5dd403,2263e9da,245dc697,bf7d63e6,300e8a7d,ac96d188,53b87bf0,3dc5f2fa,fa9b73a9,a339c0d9,a7245175,fd72c822,12f6ff78) +,S(e99c59a4,ae3022e,b50bc545,f57e3013,56b49bff,33069a9a,b4d17c0a,424b5451,29b24b79,fe55fab7,6c3737b5,61505916,b4fe1a98,20837349,baf445d6,2e9bada0) +,S(a0a42ed1,bd5ac5ed,f63f1a3c,3c3fe2d3,c0be26d6,b0da384b,f19c034e,83306d4,c39ff3d2,d4442374,7a293e28,8c320ee8,8aad0879,672679e4,e5bcf611,5ca0bbc3) +,S(b952e5d6,9ba9f063,f1d1670e,1419730f,5cc17e87,b6f0b01,c0b86ebb,c09e0053,c1e8099f,a230b8da,6e71c9b5,bbf250ae,273a4f9a,f53cd0ca,fe8f0c7,2dc46ae0) +,S(3aee273a,130f5f4e,463892b4,512621c9,be83c18c,655d5a2e,620f83fe,95a4e904,edf475c6,921fb6dc,f2c3c6a0,b93f9470,9237b035,9e8c9131,eb7eeb0f,bf0af7e7) +,S(96ddcdc,dc65af06,acb10d91,b87827fc,aa2f9e65,d28d0449,65ce255d,ba66ceac,2e6d0368,17fd4024,c830d4fe,310bbc23,9e2bf37e,60203584,215f852e,d100ab39) +,S(fd50f406,c757ec9d,b10e111c,32941fa1,e0d07ae7,9e3584d5,af45fae4,d30334a3,71b77494,d49c068f,c7db1d36,4f8db288,ed9ccb0e,c6137348,324f4bcf,d53fde6f) +,S(6f2d8268,11954523,614915c,9568ab9b,bd061112,bca3ba77,d3c64f91,6ba097d1,abe41199,849ca7c4,d317fe72,2a5647a2,97261d68,d025f5af,e880ef78,34787a87) +,S(d88c0db7,6dffb62a,27683d2c,e832a312,9c5099db,e2623c9d,3f064247,21cc1400,5134f15a,df6d7e92,5d81726d,f08732b6,ba5aa289,431bb4ea,542e6352,8dcec51f) +,S(a8de9ae4,ddde3f28,ead01363,2202fe4c,b6c0fd4a,a71d5562,d95f557e,747105fe,179e946b,5a71b614,90bc39a5,17dc752a,53682043,6efa907e,383e3da,a3be8803) +,S(626c6827,f7dc3d40,9daa4811,80e65b0d,799c94ef,e48077ae,6eb250aa,8fcd45ac,3d659db,87cf7b28,32e4a2db,8db88e5e,b30b7ea1,7819c00,fcec5d63,31bf2f32) +,S(28a3a2c,f00efa47,db4b2ef6,9f56cf02,1666ebef,b5220495,5b5484f4,2ca77d02,8dd00ed,fc9870ed,99ce90fb,927086c7,fc16837,9794db01,f7799b16,8393c82b) +,S(df0b029f,27c46405,245d0dc2,f178a48e,c3b67275,7fb92bd5,dbb29370,c1545786,f133ed05,c7e159a8,810a5ad4,e1019f15,757b474b,fea1679c,6ccd18a4,2a1099a) +,S(dc6f57af,9c1e0be5,2d2162a4,e8a6b63a,c549783,4c7c2c8b,421bbc5f,dc1a49ef,6f586aaf,e610fe5c,962ee20d,9b389bab,66fca44a,1c19379e,9e97e104,10f1a0c4) +,S(db796ea2,e0d2c690,19adcc0f,a81c1d93,8162472e,a0e3eac4,bf13b398,b255cd15,2e60c6a7,32e1fb44,641e0766,2191e28e,79375420,43bdb3e2,9474313c,7d05ac88) +,S(569b669e,72ea98fd,a5ba3efc,e74f88ce,881fe269,30b063ca,59fe369,35633a2d,badd8eaf,2551f872,5db3f740,6eb5e376,220b6a6f,ff4f8ca2,f76b7755,f8ca0c8c) +,S(36132420,1f9a33bb,d4b6b6f0,e2d175c6,ec795111,85fd2451,421ac333,78468ae4,f47b56ce,f7bc7366,6eeba135,14756486,62a58e17,d955dee,2821618f,fb3c4314) +,S(cdeb2037,1e4d2014,918fa243,182db0ff,855a0783,c92fd5b1,b604ed33,494a469c,7d3c7718,6829381d,2fd0098b,c84ee506,970a7ed5,5518b393,a83c6f79,d8dfa7d8) +,S(6035cfa9,d750c5ec,d3b721,ade88fff,ff6c4d74,f8db7755,c8717cfc,171598ef,fe1798da,160b2436,412dcde6,5482d202,9bb129d7,d58c9cb7,49f9fdb6,7dd675a) +,S(b1f52e97,e49998e4,e0e75b0c,47178f4,bb250b5d,97d92ac1,8dc9e41a,3b79c0f7,d83f3d65,4e4cfd8c,5f24370c,a2651c5f,de484cf8,1024f33d,8087a50a,d3df795f) +,S(aa799b53,4c73da0,9f011395,dd5f709b,f1a5e056,42536477,d7862b21,6df1b641,3a327047,b5e95b64,593f6887,9f38aa86,dd592007,cbbe7338,a003d2d3,33248646) +,S(da4a1964,45bdf4fc,479e56b6,6d339a45,262d629b,dd8c63c1,8d35e9bb,a445aa03,7b3a5eda,25cc63a4,66cff29,634d5eca,353376e7,26c2c6d5,63f3f92c,b69cb70d) +,S(c300b4ad,c2346d0d,433eba80,f0eef071,7e620d46,a07b384c,231e733f,a1b8d656,32083bb9,48d27ac7,f36aa439,a100b95a,f73448da,454de356,6f4a8771,e3cdba42) +,S(c559a528,67937244,d639bf7b,90df2b2,ed64a907,e20cebe7,6a358b2b,94359f04,9fcac1aa,5c08c983,20d671b5,63f4434a,806d78da,15964474,d2470cd,49bf5977) +,S(39b10147,a46dbf4,f074bca9,a83c10b1,b0911ceb,d3e795fa,9b96333b,dfe83540,ad35dcc8,c3b22743,4daaa313,cd6334e0,168da417,d162855e,64294196,2d308278) +,S(39c9cab7,d2dec601,7f840597,19994c9,4129ab2e,a2779d6b,34774a04,2f7d6d42,c73ebd6b,835a8a13,354cdd45,37ddfb3e,72ca72b4,c8049362,3afdce9e,43781845) +,S(1a625998,8a30b462,adec6097,2e218ec3,f8f81c4d,44131466,fc7b5eee,eec679ed,739beabb,1a97c9b,bf6776e6,2e213bd7,3651a39d,ba042037,bf5f8cdd,334114ab) +,S(396ed910,cd35c308,d412761e,bf283a98,85f33ecc,3ef643bf,3f422dfa,ea4c4308,721cdda6,a08a614a,4dc48cf8,442a46b1,3945e158,83671b7f,556d19e1,144dfe57) +,S(a50e06e8,a2e8ccfd,94aee96a,b0bd831c,83e15340,25e3abec,af7b7af3,9b299a47,593205b2,59a18063,fe5a4575,e8e085e1,4521fc1a,3ab5e14f,3fcd64fe,2bbeba52) +,S(4a9f8023,17b0d1c0,e62c8bcf,7393fa34,dbe15cd6,46e8f4a3,dc3f26b7,11c3e1de,40eff6d,915fff,cdb30c24,434e8928,239867c3,962655ac,2894bea9,f7c6bb71) +,S(8ce5e20d,9decb7e6,10b18562,e2ffbb88,7f323262,55ed9f05,5d2da2fc,8d608b73,eb69b6c,f363e164,e92371,b592727a,63f024b2,aa7011b5,4f1f698e,1ac720de) +,S(f32695d7,9b53e9e5,1f2525e2,8a5540ed,84143ed6,3700be0a,36726f9b,b483f24b,e8d36488,eea2055f,6592ca1f,6fe23493,1d81bd16,1c61523e,f1ee1907,c08471c8) +,S(3826fd86,3bf6592e,5b51ad14,6e02089,d9274881,25d25959,4856de1d,d6c34d07,ea86f1e6,a29035c7,43e82058,a7ff9f82,20da001,a8901e97,26583b1c,ffe4cc83) +,S(7b1afcd3,2e32b0f5,1ba09868,4ec72762,ae8611a8,98e87ddd,dc6410a,40ccd551,deba6ef7,79e10931,8036ee3,9bb6d0a8,a3ce0eb0,bc5620ef,c70828d3,d2e37884) +,S(3eb1fdfe,d2c27587,540d39b1,b66a36d1,8dedddcc,7f7f7b63,348460c1,35a91bd4,b8aeaaca,536ae794,619506cc,a812a67a,642c5345,8cfcf7b9,eb898f96,d26b36cb) +,S(9d61dac8,aae9fc5f,532290cb,683eea2e,b71b4d9e,901b7c45,c214beb5,9b56da8f,2e7caca4,2ea1b22e,7024fc3e,e267ce99,280a8f1e,78a2a271,7938762b,3a446036) +,S(2db372dc,3167faa8,e8e1e37a,85ed5546,e91a43ef,fddba39b,e38d0eae,3e11c7d8,16ab6f61,bc1abd6a,16e79697,fb59f0e8,84f00534,b7196380,9b06e10b,59707ffe) +,S(98f7cef9,f7a2b538,538e83cc,9ad3132a,5b03dd67,f7fc4030,2ff023d2,8805dc80,3b40f823,2813e6c6,bd56df89,1e96a175,468bedd3,f9518dd8,d658105f,aeb98943) +,S(eeab2e6c,c8ab0d24,d5df5852,8a89db42,c48f0861,4d488c7a,363cd195,edb62548,607c41ed,65d3328d,72be2503,f5edf14,523a7f74,402822cc,1709927,c82649da) +,S(955feeff,b2161c70,3469a9d6,c5fb31b7,b7cb5ed1,ada6b537,6d935705,b3db942a,a9195a48,a561c342,779c984,6a710059,283fcd0a,682cb5a3,fdf48ee4,15c0864b) +,S(219a4d2d,70d2ee9e,d3c8f541,1cdac36f,4db23bdd,a981a5c9,d44ce5ac,dccd85a7,67441968,43008ec1,71284aef,2c64f7dd,3dbfdda9,5c6c8e4,70a564f5,c4ef53b4) +,S(4976290d,7794b161,2e2f5cbd,282c1036,d594571,722e28a5,ed542972,f91ddb23,4cfd95f1,60fc5655,2fc8354b,446dc510,23571c24,56f57aec,79004616,ce17ebc4) +,S(472d53e0,268ead1d,bbbb99ed,599f5676,1866e0b3,c14d4a4b,5c44d722,b072b1c1,e9b9c009,6115d4d4,a8ed42e3,1d967b89,e4dfe82b,ec642db8,e31693ec,c2831232) +,S(2a6f5b7e,7a4db95c,af875d61,75a6e1b0,3f3462fb,c0dd5d50,da3327b4,70ab18ef,91b247a3,92aadc19,7d9f5b78,f0b013ce,c9f3724e,a2f37347,9ade7e03,8659d506) +,S(dc1815a3,bf48d81b,b5e5e654,fe0c8c3c,7431a62b,9d1065ba,17df9c45,23146c19,fe20729a,311550f0,e47e2af7,4747effa,d837c5f7,b08c8f36,d0fbdf2f,d594be8f) +,S(8e7953ec,ad8feeb8,97a95db4,f03ffb98,a8b47ecf,3e68bc4f,1df0b6e6,98397776,5dadf2ef,81b21cc4,26c40a39,51f31462,12f7c6fc,dabb5157,893b1637,c141ac5d) +,S(a4d91e6b,49d5724b,9e899fe1,c6686c89,faf96a05,6e666a74,72ee44cc,119b41a5,abd68615,e296498,f5abb820,cbdcfc26,fef10b2a,ba72e474,14ae9de1,960a4893) +,S(b97081a4,f3e426b9,d3a66dd6,8e0e442,754c4922,acae141d,d0294843,6b00eee9,558f6c83,99214bb4,baa9cb64,11550b12,2c8c2f77,8e28a4f1,ea61ed6c,b8f153da) +,S(6882b6ed,82279bce,70a73c6e,f6412c54,b873a5a6,b634a25e,a8c34210,fb825848,c6fdeee9,c8233e39,2ea79c61,6689e8a3,1e3a3b09,21f2b5ae,d6b9e14b,9ff21b3b) +,S(9c542731,1c715709,cabbf11f,a4fdeb3d,1a0dba80,ad50d1a4,62c7ee1a,44717fe8,aa041b10,78163458,c446bd40,ca77f760,ef4b6471,c4f2058d,7ea42975,d1f2b045) +,S(73a14da6,776b5c12,e838779d,e3be58de,4a5ed917,3b195d9,3577330c,780cd32c,c4068ffd,e98ec4d5,a7467bb7,e8bf2c89,ceb58574,cccb3a78,b0ce4a70,7ad2c49c) +,S(6488a286,27d26c4d,bade9d26,1e6ddb7e,8748d835,d9def8eb,fdc6c576,b6af91b5,27f8b1f0,b0501191,8af0916a,945bb07f,3c7f0695,5ada697,b5c601bd,3d6d8ff3) +,S(96546e7a,5b544c98,db9ee2ef,47dcfbce,cca1d38e,1978f71b,d8c9d4d0,5151046c,d04fe32f,8fe9ecff,220f07d2,2095c982,3b10f772,b261189e,84160ca7,5f4309d) +,S(ba046f56,4598b143,a02cdb90,972022ed,e769986c,82d28066,761463ed,8cfecdf8,fc6e23ab,d42457c1,5407d37c,d3d9daa,3e57bc0d,778dd68,53603232,3e27250f) +,S(39554751,e633ca7d,df6d82ed,86a8204,5e76557f,b13ca7df,310b80af,5ad0e4ec,a456ba84,f040f20e,977df5e9,5faa3f67,cdb2ba3c,2fb9bb4f,89486b02,a06d3b1c) +,S(c5f550e7,5fef9fd7,d96c924,11046c3d,ba56b8d7,e1b17c,d46a68a4,989c22aa,548582e0,3aeab617,556a987a,cee7d0fb,8d65ea42,dc8f2cc2,173c3636,27ac3fa9) +,S(2ccc1610,a48d8db3,9a80b2a0,ee063a43,26d4ba75,79b2727e,b999aacd,6e5fa050,de6dd7db,2114002c,8dcb17b,179e5843,fa205d69,4928eb70,a073f97f,f8348c84) +,S(93b07ce7,3e941c84,1e4089ff,2d8e6464,3ae59cf8,fe6e92c5,add89e10,f7084b3f,a6c0476,c5a7267e,54ec362d,3629a1ae,533efcfe,e18d3634,cb5a80e4,4018fa63) +,S(453c01f0,55c14679,5e3aeec8,26859b16,b0ec2707,61cbba3e,438c0566,5a91e7e9,f28eaec9,b9d3c8a2,2ef73843,6088425b,e14ac99,e52e73d9,8745bc49,a56766b2) +,S(3c6df1fd,ac078c28,a0a148fa,d15595b8,c1d09a4c,4a96794,6f8d6465,e80f12f1,4619a84d,4eaa134b,a06a6821,2e7ed292,d443db5c,150b54f,6dfcf267,82a5b58d) +,S(1b7f6968,39959785,30542989,59020dbf,f12054f9,2705efd6,dcc583,11b98630,279dc63e,e3e8fa8c,fbd731c9,b88ec6f0,67ee9e15,d0c14a37,372d9c20,c645c25) +,S(e1b7b953,9d49d0b9,9b90a642,74d2276c,6256f2f6,9cd03006,97ad842f,bffccc19,2b23b96f,51dc6569,8504628b,19e81534,f2acfedb,27f93316,fd0dd8d0,d5f9500f) +,S(404cf0c5,6fbf4233,4bd5f79b,ba97464f,9ce5525f,a56212bf,4bc817c8,af54f911,b5920609,88300588,5c61a6e0,75e3657a,23c04b5,79897c0f,2e22ca64,1f1ef662) +,S(43f1d986,da626bd8,efee817f,a09a3440,e7819aec,17ea971f,43fe2ec9,caae0c1,c5fa5ace,ce891aa,d2811f51,8175179f,3e93f438,2b3ab583,e51a200b,2a74f9ad) +,S(a18845c6,b3209951,16a183b8,1b762112,7bbcaae8,b67ee8fc,d23ecaf6,c5b9c1f,980ed5d9,d7e07e6b,2cfc5350,e818671b,8f54e7f1,5cebbb02,dfcc2951,bbef1f44) +,S(4d9c7eb,af99824,605cc17b,e03c929c,254c38ad,c026d5aa,2a304920,e7ac01ed,c64c5b35,bb0dce53,2273cf00,f3360f74,97065bb9,9fa9b1c9,70d41c19,53e781d3) +,S(e18d22f2,fbc3db09,bcd31783,3e8aa605,55953ef7,4c64814,edaeadc8,97e7c25d,cc258a81,71152072,24f7989d,fcaa8700,f15b8b2,85700b59,53ef2a22,efc7e07e) +,S(160575f9,f220904f,8d2ec9a6,c1417e8,35083aa7,9bc37d5a,3c8bdbe5,2a47879d,1e56b4a6,127e978d,41191c60,ad439fed,2c38704b,309d34ce,d655f93,5279a5e5) +,S(3b651bc7,57b1d626,4d6b7ebd,d3c5355b,4c3c9f6a,a1437e53,f9aa0372,5192d514,977a8774,95990312,ff1d8ec,5dc8a49e,5feb285a,8a1e2e4,19e56186,80231c3f) +,S(9085bdef,56facc02,76025015,498ab286,a9660e96,1fd6bb0c,d9579a8f,16ba532a,fd05d108,a557559c,5e7f791d,90e80e7b,68364c16,8f6b93b8,c55510f1,7ae9fe89) +,S(4224306d,f64a3862,fd33aab8,c1f0ace8,67cf1b25,76e1cc21,fef45448,e40569ec,8740b667,5279bc1d,ce887c2d,c59e42e4,63e72395,ff967249,8bd13d58,f60661bc) +,S(b7376697,4a512e31,a6f806b3,5bc55ee6,e0e2b2c0,ff5a0918,2f83ca35,dc22935c,d350c820,2676fade,ee4152a2,48fd5cbd,890b3e03,9d688462,51c2a082,85420103) +,S(73ba4f8e,d3b5d4d0,a7c505ab,1c1a7486,bb82e068,cba81574,557424da,4d0eb97a,93af3914,552dc360,549b4a2d,863d3f9,3a58ba9b,72541215,adca4bfe,26188271) +,S(285a014e,174724d9,8f0576c4,5694b052,ae93540,6bce1bef,524be03,6fd3d8ea,6fdad1d8,d2ce7757,e6ff5213,f91d4db7,9d406765,968ce8ca,b393e7c8,6a9af7dc) +,S(b0934dd7,27bfb54b,a2a5cea7,c6f8c0ab,84c2fd78,eca0d180,963869de,c28e768f,dcaf0d11,56029f31,4bebbb26,edb09913,484c94f7,d14d71bf,2bc709d8,f0b982c6) +,S(3b627add,8b69a9dc,b751c8bc,cef15d0a,ffcb49cf,357bb65e,c45c8c0f,5b681561,bda1980,9e380b7,2da13364,9d27cff7,693cd2bb,a77215e1,536296fc,dc46d19d) +,S(7e48fdec,1f2289df,a052e3f9,a4766daa,e4593876,5c8aa7c9,a62a369,52cb5ac2,e87af87a,ac116885,66e1e10c,5bedb49d,68449b8e,612939ac,61e384b9,bd8cb5f2) +,S(4031f08a,5de33bba,b6a2c267,feec2e40,d094d890,caa1008b,181ce43e,263ffd9d,cfdc4fd9,9737a5f0,9a789beb,91dfef45,a8f23be3,11b946b5,8a79b7f0,51b0be07) +,S(ba652b7c,61dddbb5,bf6e656f,4d441cc0,ec00a22c,7b900b1d,d5407ebf,931ed764,87fcb392,d1228156,a330b5d8,d3c67e00,1d207095,9a590088,a3b44d07,29556) +,S(fb936572,d1017653,ac7dd95d,2d8c30f3,62c967b9,ba0d3b1b,ffdc1ed0,6590e72d,adfa37af,db6b6a31,a779965,9958be2e,94038246,6b4a4587,b0879882,4836d8ed) +,S(294473cb,5e7c0852,f7c6fdb7,8861129d,b97ff328,19685148,99198870,b03bae7b,bd905536,f991867a,78a09f95,1bd5b4a0,78463e5a,6c767617,246eec38,7d90c86a) +,S(2fc0f44f,73a633fd,91737ced,1683b74c,7687dc8c,6d3a4c09,44a6c873,c5bc574e,29917cee,ffa063f9,4e949991,2ae373eb,ac572f50,9a451184,15e07354,1d22ad1f) +,S(811fb251,882c5a7e,f59d34f2,c8ed8a31,8da210dc,83bb8c40,b9ac0251,116d569e,74df6547,2cb55afa,4ee04ad3,f940de6a,d480e407,5c3cc00,ad291918,d8a0c55d) +,S(45a9e17c,c1d6cf09,1f451894,ad4e7e53,c47996c5,82fdc57b,a9e7e614,b7fc5d07,5169dc4f,2661f5,fb2d1920,89832b7,4e19196d,c37fdbbb,16d1caad,7b069be1) +,S(d577f7fc,45cda7ad,4743d96a,ab5c7bd4,abd06538,b78c0102,645d09ae,b5588e67,55172b71,7ea257df,ced1db61,88c78cea,765e2c2c,30bfd25e,52107128,303be07a) +,S(a6429a95,8098aa6e,39b71e08,d4b0cefe,4fb22d8b,777a59c0,650e11b1,9b06e44f,af494e62,5587055d,cac440f5,786240ab,36ab1825,f2c3a7dc,f6aa64b1,947dd2ed) +,S(f77c304,b89314b4,258b1c80,cf478ee8,50bca37a,63e20679,7396967,a39a743d,c487a176,29d914be,60845213,60f40f19,1c32f414,558e2c72,7e78637f,8dc1c7ee) +,S(41c6f2f6,15981247,71ff0a82,e1ededea,cd76ea2f,fb2f9f5d,ef766165,96d1c988,58a0f544,146c1a07,5ff9ed4f,f9b687c6,3642770e,45dbf1d3,407b52a9,5accb68) +,S(c8724ec8,c13d37af,9eaaacb,35765e3f,7ac2d2d7,1fdb5916,cdf66ed3,2eb968d0,70ecf721,42103e6d,e7d4bbf2,42bd9a6e,6ade66ed,a7862989,5ecd255e,44d81221) +,S(e2888c46,dd58e36,be2204a2,b75fab66,3b139e4a,e070c650,653ba9f3,ff1fbbf2,715910da,e1393b8a,b7d88879,720bd601,bc158498,9522108c,3312b353,2342509e) +,S(f1f4c384,d72d80b8,6b5999c9,aaa66f99,f56cf736,11ea9ec1,c14ac36f,66d834dd,b5543bc2,480142c8,ebb8527a,3c9aa786,2198388a,696b3c44,835e7375,24cc7e3f) +,S(487477f5,832fb7db,768d412,6edd7f5a,17aec3a6,3419de73,f61812b4,31940a5b,90322dde,4203fa98,bc44e3dc,32a6d56a,284f556,36db7c54,c5f78d5e,1b2608a7) +,S(a726963a,583167e2,4b8f957e,b3ee9f5,c55df02,9fe1229b,ff8af037,14ca75af,8fd7a984,d68929c0,81154d15,6b6541ff,4a636925,53a5a32d,99f6516d,c08f7449) +,S(d4c20db4,cf80eb1c,9d93a231,e699a68c,baa763c2,e2013033,8762ac5b,8b99e97c,ba1c77ba,2555a50c,84aa2071,39190a35,f5abc50e,589287a,426c6f9f,6ceca01f) +,S(7cf9c53,89ae702b,bedb5a55,ad8d0f36,5159ba1d,ac56fafa,fa59efe2,3a748168,ece3b324,338c7bbc,a2cec347,c31348ef,489bee0a,6ea4296f,6ec38502,b72336b8) +,S(920108e3,c1ebd4af,3979f9c3,326806f,eec92833,b4dbaf49,6992541b,44b73e55,3e22b133,d8adc483,4f03f348,eba48e65,6cf8f478,524f5395,ba92e200,95f466fc) +,S(1566af8a,98c48762,9b361337,2ad32a53,fc760538,49566a8a,4feb69c4,26479e90,2848c566,4bd72be4,c797db98,62fe1c7b,da5d3ba,eb3f7926,daba8516,da997796) +,S(a4db5e71,2eb8ceb,c7d7a704,12b0a8b1,d2f6d9be,271ef044,c0f76abc,af61723c,663e16e0,75a73ddd,f604bc0a,27a9407b,272f5f2a,f2b9f6a5,6958c8ca,c42e8ca4) +,S(d0c9cf53,8bbdb8f9,625d110,6c79cf1b,33d90e77,60778c13,8493bca7,8d53e5fb,b6ecce0e,8b9fd407,cc0a2125,b8bd30c,9975ad88,7dc1bd9,68379063,8a1d9a60) +,S(765fba92,480f57bd,70596d67,bcf3a389,4a58d514,54e3a04c,e657ce78,ffd8391f,5cb1dbba,1035350e,5a3b552e,3f41ab4c,50879bbd,5f3ae3db,af6ec902,1e18302f) +,S(9f9da9e8,e846702b,4aaa7b9b,68b652f8,9bd3f88e,5af4a503,2c51ee6f,8bfb4a5e,5dbd499d,7ecf17b0,eb17320c,a0688aca,1d8da08d,d2c0684d,edfa2d7f,5696a0f6) +,S(af86c83b,db95894b,72fb1a16,61aef5f0,ad949c9c,b465a5bf,b1192022,13fdd3f4,ec06827d,55410119,603d2b25,cc41c26f,4a7bb9,b1b88e55,123f3c12,d799e117) +,S(fbb48993,2fccbc8d,772b3fc,c80be33b,64c8e3b2,2ccbb09c,d94fa350,fd587e77,f9cdd24,279333da,b3451abd,634075a6,58598ad4,257bbe04,81111b6c,d8c0b858) +,S(40ecb1a3,ad97c2af,62b15eca,e2adc9c0,621f36f8,90a9269b,ae6edc1e,7ed60684,ff9ec194,fa3a617d,920e3e2b,32301fb9,9a41f4b3,ed9845f2,88daa005,3558b32e) +,S(31f892f1,c762b42,fcbd9014,bfe0238f,39873c30,c7d3b691,9736009c,18878f52,d9bd5005,f31f7345,53131066,ef6b92c1,5cd610b8,f7d4fff7,be536734,95718c95) +,S(ba122529,e9f6051e,2d94d150,c5d7739f,921f8193,8cab68f3,1c696fc8,24886c5c,c33c071f,7e9bd539,1b0577d3,37ac9c20,7c02859c,c396bc20,d9c7249a,856b1ed1) +,S(35316412,9a26d311,c993ecbc,5b9a0263,ef45d993,d58158c5,30c215f,2924cf03,86a620d9,521623bb,9ce3e2d9,c5b6385b,f92ef06f,91834e3f,6a9c6d35,7a3a9742) +,S(3024770b,e4134aa6,35ece92c,a4ec7f9c,4a4aa7ac,7851b3eb,f9718a21,52c8e462,1fcfafbd,72147afe,16dc1579,ce7384e4,ab3f8faa,f818d225,bbceb050,ffc8c8ee) +,S(f5ba313d,a40ee86c,5b6dbf16,9941d8e2,533c1ba6,4dd0871a,672d01c8,6bda6564,10a910d,b9697907,c96e95ec,15557649,8f965282,437f58c7,2944bbad,b800647d) +,S(685e17e2,972ccd05,34f7f426,b18c9518,e485a23e,132c18eb,b33b59c5,7264e2f1,96545b38,be84aac1,a77a3f47,51156daf,470fd42d,dea0fa0c,b930144e,b9f291c6) +,S(e01285fd,facc9822,a59e1bca,7e91c07d,fdd481dc,61d268e0,504f65d1,9bf119eb,ae82153a,2479daba,ef83615b,a7202b99,40bf5b5e,41c65063,f77d6e5,9dc39909) +,S(c61e4586,327710ec,784d6720,93201e4,93798a93,7635f220,b5421cb0,55839601,e461fbf5,aa5b64e7,a1e3e016,3ba555ca,5d42fcf1,7433c26d,cdeb8cb2,746c04ea) +,S(1c427acb,4e5890b6,e24d8ca2,513b61d9,3106fc34,90029af3,be87d65f,1fd192d4,1d96e025,1518528b,9bb04fa6,ec3430a1,84935ad5,ee8ae3e9,c9cec0c4,36cf29d0) +,S(5e577bfd,6d51897b,4b6ddb3b,a7d470b8,5a932619,b5982f54,431df6f1,f12fd8e7,c1a17292,9734c19d,3a836e90,8a5a7fd0,123cb044,c7ad1ff9,203d4d79,211c6eb4) +,S(cc78b333,1f968a40,bafaefc8,dfbcadf2,adc6ae76,6d3ea8a6,8173b40a,28237b30,5b7691b2,a5bc068,ff1ef04b,41238cb4,dfc2ce7c,9436f8aa,14eb0a40,45857d42) +,S(3855c437,487b44f2,9e5dc288,faf3ecea,c445372a,95adc16a,b1830a4,ec919fb6,df2e1e9a,48cbfa28,54fbcd5b,308bdbd5,ed1949f5,e1a39519,11c287c8,289359d2) +,S(c05233b4,a83356f,c5ffcf6b,97db3d6c,dc62cb21,b7de7c92,8f158466,b9d16b19,b1bda39,ce78847,3fa0eac6,51e8de54,956616f5,16233275,25ee3bf7,9e54f500) +,S(6c064d3c,f34226a7,d9a00024,5901f355,b736c1e,6561810b,455e7dec,99dfffb,160d9442,d25ec1a1,f80f8fd2,a1c5c42e,aa544477,28d242e9,925824cd,609eb9a7) +,S(9658eb89,70bb1aa5,1b61a93a,de6a7d,b3e20772,4789d009,bf37ba9d,8b714cf2,cd4ba4af,f7da8f8b,7821a903,f40d89e0,96be8949,997d5ff7,a58301ea,92c51cc2) +,S(6e023910,a5546f70,91f2b0c4,c3f996f7,5cf1f969,a71c31b8,7a3e7ea6,4bb4f0c8,f6ed65d7,90ec734d,d9ed8cfc,7d8921b8,7faa9b36,651c3589,99b9addb,34c459c5) +,S(3a35ac98,e9700499,f903528e,330537f,9262901b,d60c7a14,1e68f899,54c7ff6e,913d9516,da631c30,5394ac0c,9eda3824,1f247ff8,a7644eb6,c4d38da1,972069ed) +,S(d089fa51,15dfaa45,a8b6def3,b1948be,2317c66f,249763db,7350e57,76af212,4e6ae973,f326fac4,77a5120c,f3ffa113,a18e5dac,4a190f6a,b12fdc83,18a6da9c) +,S(e733c52f,2aa62ab4,748ea0f2,33d9531c,5b9cd9d5,f790b6ab,45bb2c2,d8cf2ef,701155c9,3c677293,acb23ab2,8d7ff753,36ac4885,70c52d89,fb80ddf1,d582a291) +,S(4b6f7b7d,c006684f,e64aa6f2,42babf86,1eb4770b,b8195b9b,e8caf763,e7f14c7a,6c58b780,ac757b33,c1805d8,a53a04c9,7bfaea05,d8f21d5a,2b0645eb,2194e00d) +,S(1b520402,cd1fac0a,c4d7aeb,8c552e73,44ff51c2,3b4778b4,81126e5f,e267f79d,8ee0d00,56649304,a0c4ee94,39add4d8,30b252f1,93d93c1,9e8ec375,37db1a39) +,S(8936e6d5,d7f1ed85,fc2da4c6,38a885e6,3400cc3f,43d864f5,bf9af2be,b97139b1,29812a20,b4b932a3,770cdc8a,6fd32625,8879f217,a5bd7c47,78d2b041,829b402b) +,S(6808ae7f,4813554d,aa36c043,a55d9171,aebd396f,5ba1a1ee,c4f11045,c96b518f,6afcae6e,88728ddc,578e85fd,5f41575c,f581b983,7c749c22,31b993a5,9c425810) +,S(586c6694,44c73f66,1211bba7,601d8009,93e23293,55a9b10f,2367924a,35a2cd1c,74b0901f,f6eba3cb,408f5507,d37cb7c7,873537dd,ef0671c8,862012ac,fe5416c7) +,S(789c825d,deadf1e0,4c788453,e918541e,b183aa5,99ccc66b,7897be8,1ff89e11,8106aa6f,641bb13c,6be7480b,89f98a9b,e40cc357,ffe9903c,b8f78938,e46cb5ab) +,S(d7ab80bb,fd26faa6,620d0ddf,97f64bca,e520426e,e1d8e076,acd7cfbe,a9419797,26af9f72,a6d1b103,aef4a85f,5139d14e,6e50a58b,9f32eefb,c7184537,90c5a823) +,S(18f712d4,4daf1ab8,4612b311,b1ebc418,bddf0f33,ca02b315,4c256d2f,36f67f7f,c40b1950,f92fd4ce,edb3c3f4,34ff7bf8,6b06d8d3,215d3ee9,f2d9bda6,77d25bc) +,S(8873276d,9f6d188f,78e2a7cb,f998bcc6,fc399d32,21de85b3,eb9e6ea6,c7e5a06e,297e8137,8ee9b9e8,ee820a3a,7e566178,dac97743,c04b6b4e,54a7081,e7c9e1a6) +,S(101b8101,5bd217eb,c08f57cd,fdf431cc,30fadd66,4df79157,1452ca66,c688e0ad,fa6c1b2f,ad203831,185816d4,a8f8dc9,4c7542b4,6c94dab3,39b73718,5d179e6a) +,S(77b3c157,76c31460,11e520a8,cb2071fb,abe3b3ca,2984bb6c,d81d4c53,7f42dd57,8d0bceb1,dab601b7,1c084c9b,443ef5ac,40cce5d,14f0c244,92589905,fc4a645a) +,S(151f2d52,56ac60b6,ff7aca33,8ba66f12,fbe2c189,33c805d3,ecf6a6a0,fddaec7a,d2aacd77,10cd4bf9,917038d6,49e94235,c4833c88,9cd57ea6,74ece9f0,764f62d6) +,S(dd75cf27,f41e417b,46338dbe,24b46df8,9508811c,111bd1a2,29a3809,171d32c7,e328b855,a3389b80,4ab03c33,cc91d86c,ee22170c,d8fb53dd,46c32224,19b67be5) +,S(faa1feb,bdd1d9c4,9de366ab,3f661b1e,6a3f6b76,335b428a,494d7eee,791d7a83,df361d4f,8fce02ab,8c248ee5,61e46555,948bb29d,81a569c4,13b5713d,b825d572) +,S(3cc10dbe,5bc2bb31,fddee65b,66789594,a4cadadf,8c6a7545,671dafed,4d8f8be5,802d45ef,8c66ad6f,e692a3a,9d42c974,7101120a,ea42510d,bc08e657,7039c2df) +,S(9544e725,325dec1c,914dee7f,752802e1,856cc485,35e3a1e,af576bec,a7b93ba2,cec7dba6,81513c04,ebf39b03,717338cc,aaf137dd,e5087686,aad83115,deeeeb49) +,S(94a0fbdc,d5d06236,7b17ff8b,4dcdf6c1,54eec66e,2779deac,38be37c,9f83a964,f25f34fd,5ef06c81,b7223e16,9a42e2e3,fea74213,5a2a30e5,76f29ef4,cfefe82a) +,S(989e29b2,c3fc7e2f,695fbd4b,f217ba43,14f67c3b,9f77633,100e84b3,c6b579c7,608a6d28,cd00297,2b4f3e9,917daaf9,ed003a43,1c22771,17250efd,b621c888) +,S(c38c5fc4,4295a59d,3b0e979b,5934ac2,49b4bd5c,e94097f1,c81064bf,73494a5,16240bf6,d354b36a,648e471a,e0ebc167,1d1dbc71,7cbeeecb,7600462d,61d1e2fb) +,S(de9cf667,35c4046c,58b41d8c,5c658efa,7dc656b,7ad877e1,546c138f,fa7a63b,2fc2824f,ba9162e3,e2372927,5448010b,ecc19de7,d9b94cb7,57586de3,506639ac) +,S(24cfd37,e56708b5,79d84b3,88c33c9f,f1dd9e08,4675a3c4,c8c440c0,f6c06522,1cbcc8ea,9820157,b4b4d289,55ac8672,1aee676a,cdb7df00,7383ac79,c42af897) +,S(9d6e3108,6ad8b9b6,2f4414a9,5e091e9d,2b275d8f,62641ed7,26421639,e87cc121,b924700a,6792a67d,4dab59ad,5a743cf0,43c46ab4,de751bca,757979b6,ead3abe0) +,S(52a89ae,28b28395,739c21e5,38ed38df,74aea22d,d2765d38,673be080,8609354d,c183ed57,9b65830b,d37cccd2,76b2f61,469b06d5,987b5708,89c5b1e,d8334e51) +,S(2ffd3272,491d1807,243f5d31,d727caf5,cda3bf8c,2c172550,46bd3420,da27571d,812e8fbd,6f38b334,a31e48be,6deaef58,599934b5,d3419d52,131cc9a6,535b6ad5) +,S(5d60c609,4269a43a,35e51b66,db193b16,65df689c,270662f2,eba959c5,9c973fca,f591324f,d1afd619,2b31bb7e,3f40cd40,6d3b9285,969c448a,3aff1f48,850efadc) +,S(23e0c40a,bfe53353,f4426340,e1c1b560,4c86daf9,85784d0a,e6da6b4b,3d12ff75,e90844b5,fc86092a,91baf68,280ca144,f19d5a79,9bacf827,f9921511,28191d9d) +,S(945818ab,5d4a1c12,ca6f20d7,7f37da80,50e67d79,30bd2bb1,155885ce,7c6094f6,b5f2c1d0,e2f9ae6d,aa669c96,9ededb60,32ca8163,fafcbb6f,9a11cd56,4a695e03) +,S(d1f4db7d,2586bf6a,187a469c,a0cd7bcd,5043be5d,6206d24b,c41ecd8f,d8724c8c,64054f82,77c4774b,bd480ce9,b2929c66,b1525eab,1c6f365,a1ca5ace,12206839) +,S(4f5c4d4f,24586e9c,1a85f2d5,b42a3d11,158b4f2a,5cf75e18,60f7f4ec,ec14a18d,57576e71,6d547960,6953be2b,e7ffbec2,1e48bb9e,970fb350,986b4a31,b0efdbe5) +,S(c13b605b,dcb31443,d8a3cf5c,5e4f903d,3f8edfc5,1e9a118,c3840cb9,4998150a,8dce2eaf,99f1fbf5,2e62a8ea,948b01c0,6c368e49,f41922b5,2f603cb2,16cb8435) +,S(1937b32a,b66f254e,4964a5b5,a1ceeb5b,a3df2466,e2669753,39174cd0,2429cbb6,9712b0a0,6f1b075c,bbceabb0,53fffb1b,181e079,813e022b,b5701738,ef2e385) +,S(e4a5333f,2f1772f3,84ef386,c3be1f58,d757bbdb,7ad2c4d7,47e61b07,419ba2e4,e84f7da7,2ec2e4b9,389b717,8bc15642,132571cc,9bc14c7c,5af14a7a,cb6b6f56) +,S(2f8a38b0,a3f42a8c,5080a0cf,5cc1085d,d57a8341,ae154dcf,fc7fdb4b,5606cca6,8764c6a5,2c301db6,56408d9c,4eed6294,2fa2a72e,1b1264f1,134f38c6,8e4681c1) +,S(3d2bdc2,c51c2d77,b6c585b6,3ceab5fe,acd14599,b841870b,8735712a,81a55ff7,33f749ad,bbe263df,a99a808f,f0476e44,92246036,a3e8b5e9,496b8dcd,b6d3e9e0) +,S(fc87f808,d6764ce3,376b9acf,62bfa3e2,1ecec215,22dbdb3e,6e5f3cc1,efab7d3a,ce75eb03,c1f4f937,70815dd8,750a4ac1,c0343024,ce1bc581,717cb971,2835176a) +,S(7f81b85c,62dee11e,be8885dc,cc98485,32354952,1c7e6cb4,374270bf,5b1e68d5,b7adef7d,6a84db61,c15ba062,d96cf739,1750aa4a,ed5c97f3,ad70d2a7,6a9c4558) +,S(d618d43f,7afd3ae5,e8dd8f47,f62ef91e,33cc8f89,3c21688c,8268b903,e1fd5557,6180817b,c8ab9b0,82b21267,9900c7e4,42ce9e8d,fc8c3fb4,fc5bcaa6,e0cd34b8) +,S(ba5a4c4f,f2379b06,daff540f,c8383b9b,694430bc,df76c931,ccf94cb,896e4940,3a221d1a,b138e6f,4ed309b2,4f2e9333,25299de5,534a528d,b91075a8,fd07b1f2) +,S(c69189b6,bee3746,88359141,5b35bac3,80136395,c83098ab,cec29fa3,18cfdf56,a185dbc2,b862da3a,cdc232fa,7e3407b1,9795e61e,29b7a79c,5828bd49,d739268c) +,S(51f67d44,32fb401,ab863423,b99d403a,70dffd86,87e5ad71,bcd3732c,1cefae12,88b17485,a2c404a3,2bcae68a,3cbf2166,403e23f,8a64df5c,a8eb2d94,61e10e59) +,S(cdacfe09,e5585f8d,4346fb69,a94b8b65,6001e117,ed3cca36,fa8bee6d,eb7c4bd5,ddf1bc5a,993131d0,15812176,206699d7,af5fc403,59455ece,fdb84492,6e028542) +,S(8129e771,e1fce476,9c701d70,cce90888,481eaaa1,d1661be3,19f33c93,8bf0e769,3eb5713d,a864bc56,39ed8b6f,974966af,8a4db189,b5446d70,d40a816,f045c6e2) +,S(b97062ef,6d415bc0,f302fc0f,8aa730d4,f39c14aa,f82889ad,a68132bf,5abce3ab,8ad70688,cd76c93c,fd8dfdd3,8522247c,6644c9e5,51116829,490f313,d53db3a6) +,S(19c3c98b,4e811b5f,ea5d6af8,c4e86be6,50de67ec,5154bca4,22a6a14f,4f0bd913,bc523f96,48bdc993,30e1b5c7,385097cb,c18b9d5e,924767bd,d5d746fa,a190a109) +,S(b9ef34c7,3616ee74,b1ebe43f,889118e2,ad7697b,efe63559,67a9b3c2,b5b42b9c,12f1cddd,d55b1ac1,b89be271,5e623952,e8dc05aa,3570e254,3b70ea68,5b661bea) +,S(7718e34f,58e2cdb5,80f9c39a,96d84dc7,59dd2a3e,bdebaca8,6e8edb97,f503c34a,a6d105fb,dc0841b8,12dcd8f9,6c4bd17d,cf5e3728,8e0e3093,13567b10,3e96df7) +,S(dab3884b,8e6de737,63bba89b,8d35a369,e259c1b1,8afb6ed6,21fcc871,c77e8dba,f44b6f29,c59a2d42,2babd4b5,edb4a009,c9316e09,2aef953e,e503a278,14a11577) +,S(cb3d0e10,1139782d,e5e6a897,8b5be6df,a6736751,e847ca18,76aedab1,e67f4366,27fe888d,d227943e,67969b33,be48f1d9,572aff67,69c150cf,189f9709,bd57d3ea) +,S(eb1b1ff8,55619d41,8d193db,bf62b4b7,656ea564,6ea2e79f,cca7fb3b,e8c3c6a0,c27fa0c7,5b73d5c1,d7113741,40384565,d36ae93a,49b327a5,cedd03c9,62282ea4) +,S(5d5079e6,bc40f11,f75a1117,3ab6bdc,bee8f9f3,d2e57aeb,58709786,1c39c5dd,14ae112b,a40db9d5,dd65829b,4be7bdf9,4d8435de,1872bab,80581221,446e46d0) +,S(1060ef7,6beb6af0,6d28acd2,6b214bb1,b708098d,e0300502,384fcc0a,a1a7b38e,ce40f39f,f6c6c642,9585464d,aa2183d7,34252c05,5207e2e2,75d0ec48,c3bdf9a3) +,S(9651c463,c001f731,8947c271,ac274529,e7bcc894,70d63e1a,fd723873,aa170695,4e362e7f,e8ff06da,73d6d17f,e8b63c99,3b16ba7a,5a9b154d,21837fb0,e654eaf7) +,S(5c422b76,592821b4,2f6822cd,cb428b19,895cda4c,d224400e,e0928f27,1f363dcc,2fdb4f4f,9e4c77ca,3448258f,f6c07f5,4cb6b4d8,15281484,44e5fcf6,492b9400) +,S(db147d2b,5d98250d,73a3ce51,9452cc4a,ab3868a6,cd4f43d2,b7224d93,a9faba2c,73254380,ad3c6acd,fa343227,a7299684,9fdebffe,64c4925,8a391a7a,50ed0de) +,S(9a6763a0,f97abfd1,65223767,8881e899,e1beca26,ed84d384,a41d16cb,e5454b4c,bb51407d,b6aa5817,32f1a3d5,51082908,e7952f75,92c8bcb2,737a01d3,3890306a) +,S(36fe7933,e9108af4,f4e5c889,ef94f584,7b45a9e,8c520000,7db6a00,e5daea8,d024a5ba,ecdd5a21,c8c3a0f4,a71e15c3,1943c7bb,66b459e2,7fc85bb4,25227ee5) +,S(40dae663,f04f7e68,ce782fb,87529681,44c749ea,5b7386af,c445568a,3bc784e7,49a463fd,ac6bcdd0,2458c85,423cf252,cea2ab47,44b16bb9,47811176,5755050b) +,S(ba1616d,c8fff3b0,8e8c6d10,b15afd9d,da55faba,79fa8a75,42c5c9cb,adc5b8d1,ef096c42,a6233c66,1965a3ac,eca095b2,7710455e,5f0e1019,7641ab25,b0a786ff) +,S(30486f67,23a54952,4d68c948,dbc71273,d69b4a05,5fb9e7d,a702d027,619c4a66,38ca4d4d,279ec9c0,85ea6369,5470a4b9,fd6acc6d,9a049ab6,5743ecba,c2444c76) +,S(1b83ee94,95ead1d5,80f67174,dec2a026,d6accd93,9a89d970,90f25bc8,d9e6932a,196d448,fb5e4851,e1b73d6d,a2e7d0eb,3d263034,9c2b3e0e,34584bc1,d6e20196) +,S(4ea9dc2e,edfa5a11,2fa76671,5c1579d9,328b6132,14ee64f,2e30f10c,b7517396,7414efc9,6ef83e29,5883f0b1,4019b41c,d4a192d9,d06cac9c,21e8f0f5,b06e50c2) +,S(4166c19d,bee9ad08,83b217aa,3b657436,87677792,d5cb9b31,1a097fcd,2eb033da,62c5065c,5fae6aa6,932b4d29,ab375ac6,b80e113f,d38d81f8,abc236eb,7eed541c) +,S(b17567eb,b112f54a,69c511a8,7d3d2f96,bbbc6686,af8e3f31,a2bbe0a,85a74899,f6676341,3788be54,ae3fc693,4b8936df,a6936721,c671cbb1,bdbfd72d,4c9f52c2) +,S(cd2b6515,2ab97f34,89d81fd,f3513131,a6df0685,5022102,12c2b8a9,be8095a5,cfe7952f,9ca41935,15ee40c7,2d44d023,22afff84,b8700bb4,5f492e31,e78f6a53) +,S(375603c4,9f33140a,3241a72,907ac0c7,2086c979,3aeaf74a,44732097,3618229f,7bb740f6,6322a773,e11ddb46,300975db,de08ba13,84480699,6681637b,eb85e837) +,S(102067d4,390a3dd9,6d83c176,f341dde9,7e10955d,2e001632,978f202e,efbb7432,7cf6cfd5,4d28ccc3,a7019f11,b6ba9df6,1d8b7eef,7e70722d,afa81a2f,839ba83e) +,S(47617e73,e3fbc53b,a703042c,f8b48fad,374ef42f,e8c2dd54,4fb7625c,de63081d,1fa4f423,c92a95b,b2c40f07,f43caaff,50cbae67,87c3e2a0,e4782f39,c1d439e8) +,S(2c431baf,57f75062,9f57aac0,8e28a060,46b814bd,318d74ca,82e1174e,f880f84,ddb9e7bc,68574b32,c1004108,9853f41e,62755a52,ac58badb,b8ee58c6,f209de50) +,S(91963643,8143b6e4,19b86b1f,79b708ab,3f4df44b,d774b41,338570dd,8343d599,9034ee17,7171a0d2,9fb91d68,26b87bbc,21be334,90f44049,69622a8b,76312f0d) +,S(bf28c201,af656c7b,838d42db,95683b06,2871859,2b016ddd,a4a4f7f7,c4b7754e,bbd4f04,dda510d2,a8a66c2f,46ab0681,ce6ffb5a,ac320e20,c50b6df3,a345d109) +,S(fcac7386,21825f4,4e1d531b,f598e40b,1aa4262c,a5aeb5a1,babb4f35,9518b137,3b196b7a,957bbea1,f3f2d1e4,1ba37eef,7dcca7fe,87e7c593,6ffff685,52e67b64) +,S(9cfea1df,caaee192,141f0278,e467f809,8ad89cc9,b47ed982,3029c1dd,726e9331,72d81e4e,7f30ee05,8fd0b646,95086e30,96a071c1,5b75df47,b10146b,18db211d) +,S(548d3f42,123553c7,965c7f21,f2802c30,455c5151,99b98e20,1e966f34,6a1334da,612ea25,cebb03d2,89538eeb,15b94686,8c0afb1,311278a,42694a0e,956418ae) +,S(e5be619a,ccf84c26,9b5c545,e8c4990e,ebd46756,c628de22,a6c8bdd6,74295bc0,640864a5,7d841af7,ad83aa74,fa858b91,89e246cf,9b361837,a742e2a0,71b08bf3) +,S(b560933e,3400ed4a,eea8f733,d2368c8f,a260460d,f734e209,e194e9ae,a1ac668f,5438f93d,31337853,9feab182,6cf17bbc,ac0975f4,de29a886,1b1c0c02,2c5f9da3) +,S(21dd9a97,baca3e79,77ecf7d,d74433fd,dedf2d96,8c3153c0,2c652aa2,1ccf60b1,de6e60e0,e048b0b7,b699bbd7,cda0c0c9,b851c4cd,34f4b8d9,17c07cd0,2684797e) +,S(5cfa560c,6d39439b,4c9b0a52,f9bda301,2f147874,48c9ff37,bcaf2900,fd934bbd,c7927a63,cc1959b,f3556998,ce936f29,29d5a5d3,3f0dda32,35affab9,a5b11b06) +,S(4a3b95bb,5adcd41,5036204b,394fcc95,6377afe7,b4902f49,461c4b6,866d4fc6,d59e3ee2,f1bd1e4c,c089179a,4db9387d,8d6be47b,df708023,2a0d00af,a8e84f2f) +,S(cc49a313,b4c69c9,13c06b7b,add06f17,404edb0a,dcdb3d4a,81c4b765,35f4671f,4bd722ec,c35e525e,af36c194,3d375592,ba483715,2c7a91b2,4dd57a89,687bc278) +,S(9d75085a,7426a69d,9ccf4f90,d8b4ee0,e07fdac0,18df3d37,40b264cc,d4146d98,5991253,de04b32d,4772f44,de49467d,ce174ae9,3f941ae6,a4f6e3c2,2cc4b0a9) +,S(dfd064df,737bdadd,2eb12cf5,d9f1e192,caa87c0e,fad20d18,b95b0d06,83210fb8,519f883d,a5bf8d33,50b1d2b,89012fd5,9f317299,3eae1226,13d81b92,9103805a) +,S(2b50a35c,d2356c35,d609013e,a66318bc,1cf20582,685c12e3,bf618102,807eaf9a,7d0b51d,303aeefe,b81f5a77,d9b5829e,fdf4241e,435380f6,ce74abab,1dc76335) +,S(e26e8f4b,2cf175e7,c76e2a59,459cd45e,f3202f3,3027f0c3,70481fa8,685abbc7,4c82e7ba,aa0d5161,53076702,997c34dd,716e5fe2,460eac0f,194f72fc,3ac2013a) +,S(5903db7d,54f4d857,6a584057,ce78dc07,1fd90e51,f825c959,b46d3483,5d0f87fb,c55e2fd3,e9ce119e,47c00332,9d18d6f7,febf9440,a18de0f3,81608011,1e9e99c8) +,S(4bbb0ecd,342a82d,c8b881e9,635241b6,1040e6ee,28b98204,fde953d4,4d25e9c1,12eb090,f3445b7,52abee8d,604e8784,82e97e9,b44d2335,8211a8c8,2cb0ef04) +,S(4a2455a,ae87bf97,c6e6eb38,fd3279e2,7029967d,41b9575b,647550f9,4bc4e8d2,5a340ac4,ffe3bee6,2d52bea1,e276178f,9af3422,f9c61c47,4a595550,73936074) +,S(f086d68d,c8ca19aa,54c329c4,c07b530f,94470abd,dce244ad,1decaf87,53477623,911c49d3,84a16af1,65be4161,cc4869ab,4d9e8ba2,808afd80,20d30971,b4bdbd08) +,S(4f1b177e,83b76c4e,24a53f91,2095f1b5,d4b7cdf7,29788cb4,c989f921,b7ba856c,a5568c4e,b060909a,fc3dc2ff,5bb9534b,99debb69,dc0b811,e1044705,7d80eaf2) +,S(eba87899,29a7e45a,23d2fcbc,884778d,c4fb5ae7,fa67954c,76534303,97db5823,e6f8c729,b3570917,9fc46b4,7f03af9e,801b26a6,1724aafe,e730217a,2dcbf68f) +,S(df117b13,34c9a5a7,92d58084,4444559f,130ee539,89cc6e7d,87723b63,a82282c2,dd87ca57,8eea3c51,2aec5492,ea55111c,1a2fc55d,4e2335a8,c9be5641,516f7120) +,S(d775543b,3e68ab88,36eaa1b,df5f6a06,1f5768e4,baa01a68,621321c6,e6ee82c5,70221b05,47c97398,3cee7a26,c4197f9c,27a2bf46,10506e18,493a9ee,1881436e) +,S(a7f10dd5,5a231ae5,abc5c611,68cd58ca,5e006f7f,fdf064c7,1482febf,4578515d,492a33a7,b66b9694,e225eb38,d1d99399,b2c24af2,d69c31e,b4797a9e,703c13b0) +,S(c79545ef,3119abd9,11336c86,c6b74846,801c6b3,812da05b,5d36e9c,620120ec,24c8fcdb,95b6eae4,51473f8e,f7dea06c,738a33c4,f1214382,bd7204dd,d3c28718) +,S(98bab5e,744f888f,5f843ba2,9e2104a3,afa14dd6,6a2206ec,8e783e0c,52c2cb11,83b5699f,e5e87ed8,c51d929b,8146bcd6,a7abaed4,636afcbe,b2c30d2,bcb94df6) +,S(6dce2828,7b6fa44a,c8213053,d39dfff5,60d84a84,ac264110,547752ef,dcac586e,1e1eb62a,b9d60cc4,5ab2fa8d,d065d1a4,c79be399,53578a5c,adcfc629,e237ed66) +,S(e386a59,287a73c9,306b091b,5b24ad8f,db06a9dd,8f6f0c1,b7fb0ace,623dfa83,4a7e73da,663b64a5,e624ce89,9e16fcd5,c0d3b221,42284ed6,852960a9,d05b34e6) +,S(8fdff782,e62fbe31,98c283fc,9b9543ac,cea0a318,2626d180,4beaa27,ea4fe4d5,fef8f471,9fe0d95b,673ed650,8107e887,a4f5301f,4317c708,c5222d2a,ac086675) +,S(4c9093ae,7842b148,1bbb8b8,4ea564e9,36ed1cc4,35c89089,a10e0442,292eaa37,2d683334,93d245fa,e5ac0903,fe9356f7,8642362b,f85a7426,ea2950a0,a65298dd) +,S(cc0634c5,5c5c52a9,d92b80f9,be072a35,56318c6,fd76cf2f,e866d5ba,33103a1b,750b7d41,b13cb69e,6d236eb0,87fc8600,4004aa77,1b699e88,7e8f0b08,d07f0b32) +,S(9749a673,41fa7ac5,8bd33f5f,9cca4ad9,1d53c7ec,cff76656,9a56f71e,3b918255,b685f1c1,9dc7d6,7692a2aa,fe37d9da,5e68fd69,cfa58d87,ec6ced8,68916068) +,S(b04abcef,b57862f2,5a57fdc,b7da0b1b,a25bd253,72bd91bc,9e0377b4,697d8e75,50479a64,66ad4be3,489b5869,d8b9bbe,62dcb8af,da8e7d42,78b5014a,19e168f6) +,S(d11f7de8,5481fbed,f1a3b395,785f00d6,295059b7,c8049768,22624e85,45c78902,1d163368,be0c1290,1a7369d8,11266982,b48928cb,448039c3,17333658,6f5c3416) +,S(a21c65f4,65c4c7a4,93225af,73b63cb2,fd615160,b29b2b90,970b880b,5756fd4b,69a26b89,394de60e,7dde3476,7048a295,57f1e3e2,5f7a586c,7666aa30,9345ecfe) +,S(53c626fb,b080360e,9243d399,9a58ced0,36ccda8b,186c76a4,fdeefee1,6a497a1f,ad926008,62a7ff1e,519106fb,933616a8,8264d7a,c40476bb,eda7e1b7,742ac9b7) +,S(cf67b587,1b2a3ad8,d0364fcc,8741f10a,11d96933,11b72870,60116c4e,74e6ff0e,2c963b7c,10ccd74e,f68ac068,cce1e30a,7be6537f,259abcae,6d36d29d,22b68422) +,S(50216d8,8cc8700,29da89a4,b34cde0d,36428829,de9f58d7,31ecd6a6,c90b4bc7,920c1df0,96bc4891,8defce32,2a512d5a,36f65d7e,65525e0c,123d9fa7,49e38b21) +,S(1d845594,f4686fbb,7b0cc62d,af790aff,3d6000bd,e26ec1a2,67766c3d,93d1aef3,eae11ba6,bd9dda02,ef134035,1847dc6c,92450b36,cd6a9734,25c09f9f,3134d260) +,S(11ad4f50,b6c5b97d,767d590,859e2ab5,2e7750a5,6f7e70c3,d5c52bb7,9e4785e1,2c2bba36,8725d9c5,2152496,f14cfa71,1826e846,fbf7e7ac,4e263db5,a8023b94) +,S(3568d27c,d72373e1,29a4a519,86082a1f,f76ee425,969d6e3d,12b242b0,bd49388c,e36dfa9,6d094047,16e35668,10a8e57,8eff108d,839cf3da,f04c76d5,8754fdb3) +,S(3772ab35,45e09d0c,5d2abb91,97007742,46310f72,bdc0b8ab,afaa2c17,f17801d7,25229a8c,eae0c746,2d7a50cd,a8b012e0,775693af,8edb7260,5340042,a78884e) +,S(8151b24f,72c4701a,e4624779,c8b93ad2,44f3b299,d1ee131f,a13054e5,c29274f2,58938307,25ffd619,de73fca0,50c28d77,73420724,4d2e4c99,86ed5512,b8bb6429) +,S(46a4855a,d4101f8c,60c59705,e537080,1b57a81d,9227f4c8,69234946,5d539c9a,8fa66dcf,21117195,e2c117ae,e2f20bb,9517ad24,5fea8864,beed3e68,89e36b59) +,S(b81bd54,3e654f3d,eec15001,c38bd2a4,efa7c45f,4ece2d4f,fd893c6,15803d16,15c3f7aa,31299a76,34431622,8f93b6a3,2b3947fe,5a894c4a,75d2ba01,4e9d3e75) +,S(3e169a1c,f2a0324d,2478c054,94d58801,423f10f2,4cfc9fab,a5cd5cad,12e7706,20405bdd,d814ac7c,53469075,a700b4bf,4d454b,fca920f9,86923562,19389135) +,S(74283e4a,b161b33f,f67a1b8,cde619bf,557f39b8,5443efdf,534bdd2d,4da65956,22296be2,89785c04,6773ad2b,c881744d,380c1717,1c77b159,bfee3689,d0b3df3a) +,S(62715786,cb76bc9f,b65da0a2,3b7954e6,1a617fb4,de828092,bde3da39,ea6b756e,3c27bbe3,8829a150,3b563337,bf995110,eec54d58,21e1f17d,34a5fd90,52c2db32) +,S(96200105,db23b893,84336bc9,d5596740,2c93aee2,ca35df73,9c55a000,6f7c8aae,3192968d,400a2604,c80307c5,d9865f49,ea41cdd8,e3fd3b19,a2bdfa17,84a6ba26) +,S(bd477798,bd2691b0,8cc52fb5,cbf8b2c5,31787535,541b5c31,3aad9696,b71d13fb,be2b51c9,a4ab0033,c21dae50,c4e7b2b,51978b39,4a66d50b,6be7e140,abddfc3b) +,S(fa149388,e46ff849,bb5490e8,3aac6788,70da101a,f52dab05,9039c305,475289e7,8455577f,a8d85674,3b32080a,dcd26a1e,c75af3d1,c184d5e3,7f22030b,8867b2a7) +,S(4228db83,af1ffb1,d4bbfae7,3781a70a,8ab50d3c,47200e86,ff436ae0,3391ba90,45db1d0a,b0e6f0a1,801560b6,419bd2e3,2413ddc9,4b4ad637,d4071d8c,b7a270a7) +,S(a97ab279,fe0df5a0,3d494c02,eb69c686,1dc3a39a,fca2bd49,f4161ff3,817c85c,5006c8bf,f128de17,3d72f99f,7cd6deec,5d4b7441,6b1ca290,e535c8d,c59bec7d) +,S(c0d46c57,6bdcc661,4e1a3a1c,c19fba37,9f27dc45,5135eb63,f8d44666,904c668f,396b60a3,b28b250,2c97d7cc,f93c7609,3d19172f,47fffa71,f190936d,cb215f58) +,S(73c5d7e0,4599fa7d,e09b8c2c,25c5bca2,b7ae4c6,e1b88e63,6de3363f,b1a8dbbd,1d9ed08d,558bd642,9e986b0,c431d67,9229adf,6fa8dea3,faf17da2,747bc617) +,S(370481d,a2ef4843,8d897c6e,f1a01750,b4788c65,62ad3ab7,bbf3c89e,e24827a7,a88b3876,c2051901,1d84acc3,3000f0f1,ccf794b4,5385aaaa,190e435c,760fa7b1) +,S(2dcbe303,3006f0a4,99dbb7d8,d34790be,f2b68cbf,649b9d54,eda8819d,637807ec,b82b46e3,c7ab329e,b915de2d,f3fa28d6,92cf43d,584f9bda,5d6f58f7,1a90c1e1) +,S(f45f3ca9,16db45c5,de35d957,c24f7a59,44052b64,f8f423c9,8a442f6,17bb4b7,79ddf02f,b3154d6c,da1d6a79,5c64de61,5b4a0ff7,810bbfc1,dad68e60,229b5a96) +,S(500caa8b,cad0567a,465c99bc,c4802553,ee17346b,e3a9ae93,4fe7e95d,e787605e,40847ed0,75dfc8d6,ae19dccf,73ddd256,4e1beea4,7f822a58,f0570c62,f238370a) +,S(30562986,a23962c5,5b746191,e23b893b,7bcd8b87,6fa85557,c525eec4,d64c3aff,2d5abe,41c45383,1b60c034,7bb55464,e19d8d98,8a5d5fe9,37337507,80577a53) +,S(f687d51a,32526b72,9ed3f690,be1e6205,ec72382b,6a30478f,63a18e0e,b48e422e,efce1b35,19c94f7a,fc54da2e,d36b15bc,f197e2ce,a0c2d680,211e12ab,7d515704) +,S(104a63f0,d385351c,c9ce207e,500ae7eb,22199ea7,dea65018,472884cf,a1ca505d,69c21887,50b20b3c,5af1600a,a2a2edc,a6de0be9,33d2e67c,e05ac4a8,30239cc5) +,S(50966099,4b7b8ca1,abf963e2,ff4d295a,eb3d59bd,43029c03,5e6ac9a3,ea80fc6e,d48589cd,40d019b1,81211674,854aea3e,56be56a7,bc8ae519,72963adf,327287b1) +,S(3106d6e7,94e5e135,1d788e85,eb0f2c7c,7ac22e9f,d1c86a0d,d22cf88f,54513c95,c05e593c,4568cc2,992849d8,4006ae18,4ad2888c,82ce8dfa,dbf984bd,2fa2bca0) +,S(4c967d1c,9977bdce,84f76ac7,13b9e5cf,d1081b43,de681235,e7914f6e,2059fdce,866470b2,a3e99b74,15c2cb09,83a5c7dc,fcc10d02,a28e90ee,206be515,e88968cd) +,S(96319099,ae8d7741,1d8bbb7f,bf58f62d,b4027b02,ff5e32b2,e4aff910,3a781a52,6c110074,daf2849,a3b148f8,dbba2f0b,d776eb4d,b787ced4,22edc5f5,67947389) +,S(7c93bb23,87a36cea,9dd7406d,95af56f2,b972242b,759728b3,bdf30fa3,58247ee7,21e4de98,33487c86,6da01e16,895a0e24,17cb34f6,e3d64e01,8f7c4d99,9e989942) +,S(c65e4a03,88de1618,6d9db143,387a3229,c764dabb,7c6ddcdd,c3ba9195,7f1e074,d586d143,8005b28,cea25a45,7c45c1fa,2137bc2,fd78417b,daa499bb,cfca658b) +,S(d895a924,90c28692,bcda380c,71d8d1b8,381b1fb1,a8108f35,4d9a17d8,64d674d5,d30bda25,a63013f,79ef5728,dbbcd259,c7cf2ba2,b00af73d,9804f758,7fde17f5) +,S(90467c3a,5b36b9bb,faffa164,63d1f70,c892e23a,3c7f1132,27bff1e1,5fdef988,4ec70191,40247d9b,3cfccb41,ba22ad76,20522577,1e33d568,946c8081,ea9b15a7) +,S(5cd03d63,d0e025a,7af268f7,8f53efc7,b4d38e5d,58da5981,abcad74,3e294c7e,c3729f6e,5517d41c,ab1510cf,ee4e0e48,f168e043,34dd8781,1a10b70f,b42dfb3e) +,S(5130c49c,652bc5ce,a3dd7629,bf362294,8bf69c02,f9806988,fc700a25,c7e964b,7e46e219,4bc9dbd3,99f98c7,b7a44313,a027ef23,1abe336b,7381c215,6f2cf563) +,S(95899c2a,33b8d4e9,13947306,6b924812,261a3155,e5a7ddbc,c5447796,8edd34da,8967be99,84240292,9ea7277b,5be0d045,bac79fb4,93a08a41,d4dc5991,da6b7cb3) +,S(3928013,8cb3e93f,7c4650c8,8184dfcf,6e55d238,2e75e604,9dd6e40e,f489745f,70b25e98,b897f3a1,c89bd6d4,72f2555a,56bdf04,6fb43799,58709471,f8006a52) +,S(a47e1331,b5fdbedc,e490497c,bff1088d,ba72070d,3cfc7997,fa388fc3,2f80b451,ca54b8be,fff00465,4086c75b,da3ccb9c,6244746,522124ec,ec22666e,a9576b19) +,S(cc1a608e,16c57528,3cbbb134,4083cfd3,f1b325cb,b48df6c8,2d50bed1,e0cfb96a,5b8aca44,67d9b224,413b0c98,78e09213,591b8f87,b024bab5,55120a83,38cc6734) +,S(d8354bc7,591ebaeb,7ae4d1df,2db3bde3,b7438d1d,69b5991a,5d70f6c2,c3fc3cea,efc89693,6765f03f,29422703,97591bed,7d95afc7,29807a31,fe266f08,9eab5ad3) +,S(6ac1c963,ceb2740b,212ef42e,6da07647,481ee21c,4e3fdd6f,f2ae3da2,8ddef8aa,4fc8817,1b6d5ae2,45453c94,f5f2031c,c52140d7,a110d9f,b1bbf3e8,e5164281) +,S(be130f59,b52e4148,f9c47469,778fb36e,74d4da3d,a00f5c4,dddd2e47,6f18b42d,16dcd9e2,f739a58a,22a7d76,1c1cdf61,c5b9f8b9,46449516,9398dc1,fbc47069) +,S(685db8cc,39864a55,68b56e59,96265bb1,24ee71f9,1f9f4f3f,fc3c79e6,c063bd2f,730a7141,8e5b2f7c,2d333b8e,5be3021,22b396bf,9a75f493,37bae5c,86b50f29) +,S(39f41ff3,89f74c1a,e25e564,b9bc189b,f31f9af,cf0ee4ea,aad66ee6,55d743ae,fbea0f6d,e25d4fee,53f0aad0,9338f739,26fdaeb2,edf9d8d8,8e1e520d,d66c8622) +,S(d7a69574,41bc9639,994737b3,d483bc0f,c29b1b62,cbf59f28,b12b208c,4c20ed1f,ce44e2da,cdf8158e,9c07ca25,1b9a3d06,91eea29f,41f824ce,ef2d631b,65ba8cb) +,S(85bad160,9139cbb7,2be86793,42b37884,22f5981c,5fdf30ba,4914395e,c1eaec9a,99fcd461,29e576b2,b25c57e8,8e3fe3ea,362055c7,843838db,4196a485,cf14dfec) +,S(2380bac4,d428a159,23c2ffbe,8f17da09,74d986fe,4210b72d,51a1eb80,23ea49e5,f4af7313,fde4c7f5,e45e38bf,c4d44bbb,3ca1015b,d209065e,5a6ab074,5ed6f54b) +,S(c0561359,b7d61dd0,e359108d,f221202b,97c1acfb,894f4e9e,46fc29fd,364f9cf2,3c377d80,1c72a9f6,2cfea5ff,350ceb32,75b16103,cecf492e,2901327,d27d83dd) +,S(72c499c1,b8f4f2a,eb9181d3,9bba5b2,76481c04,a588fc6,4ed438c4,920c2a06,6c994c8e,60825314,2a34867b,1f82bc1a,f05ff8ff,b3045e7a,72d01243,b2b1ce53) +,S(8de84cbe,2b66209,f8f8e2f3,f06feb45,66e02c9c,b5df26f8,84e20454,ffcf477d,c7f2f680,c4d07d88,69348e98,6a3b7ac2,ac9e8542,a019f379,6410b993,742a34a6) +,S(dbfec9d8,6581d762,e5ac8048,886b9d2e,9a2d02ee,63c5f442,7d02d12e,401710f2,6e611ff9,827bb1ac,a885acb5,906648d9,b46496a8,98a13c90,48868d,c0daafea) +,S(9dd651f8,6099edd1,b3d0ade7,82aae6b3,9588dc2a,291577f9,f2456f23,d1d0453d,4f6db617,f0d7860e,18be81a,dfb6d773,cd3f905f,98611845,5f5a0b05,ee715ebd) +,S(2fd8161a,c869de35,e777a885,ee608f96,356445f2,fa2f33d1,926260bf,9bd66a15,1d2c21e9,674c2d92,b64163eb,12de6347,98c6e7a2,9787daa,7c6b4c80,fd307f25) +,S(3f25bf89,24f505b2,3f1538ce,4940edf4,8b6d8765,f88778a8,495e8a84,a29dc391,70253583,e7e0782,18ab0252,52c613b8,34438254,9dc57c30,afd47297,2c8164f2) +,S(3c0f0359,d5f72344,f8f3d2fe,28458f30,467dc770,b55eab47,ff2e1ee2,6c773f0b,49583a39,459f19c4,5ac50d78,74626524,b9c25030,e45f2c7b,12729ca8,1edb33c7) +,S(56380666,ec1b5df2,36045855,fa0dd93c,87e38d70,fb170dd7,3be5c308,36b73a15,700690f0,b210ac6a,9aa91252,c8af8f60,b5cbbf93,8291fb11,7bce1f0a,759921a7) +,S(71ca710b,b9a5f7f,ec6b228a,af3fc47e,25f90201,fbe3c673,8bc6d2fa,9c9298bd,7dd2528d,c0750899,b1891287,170159ae,c759bca3,51e243f8,fcc9efe3,2f9abc89) +,S(78ddec3c,c938850e,7c2ec20f,98e1be3c,6ed87fae,827c9102,5112d0b3,5d264575,19072951,766a4050,c8585048,d6f19e60,22b9c163,f1799ddf,d486dedb,3d680321) +,S(9aaebafd,8852857e,8c670950,93dac29a,5813249,ed03e67f,3226ab3c,7b4ed70b,8c6a2acc,b541bd51,65e13bc,a3c4d2f3,2457bdcc,406ba71c,7b9cecd3,4705fffb) +,S(586eca74,941180fd,da16c7b2,8b9bf139,a3096a6a,20ab9bcc,6d12be5b,db2f79e2,b3b1d12,361609e5,afc5a7f8,26a21ea,ac4bfde,56016ad5,bfde6f93,a3488d71) +,S(1857bc3e,dbe4de2c,86fed7d4,cc3ee63,c0e0b6b1,36acf97e,e3638183,8d50ddf8,ea5e807b,e7a588cd,ec759c67,3584675a,8a7fbdb7,cc5a1835,119a4f64,8c275363) +,S(aa4cc744,7572c62,22a6cd,bcb8813b,64206796,27f5f7ba,863d8566,78e5b01a,ba969ac9,d259244a,9a3b7f9b,b3821a61,a4a97b8d,af7e08bf,f39f099f,8fa2f836) +,S(4588ec09,59174367,6885fad0,a43d85cf,d6f736b,cb276179,e794da35,204f36aa,fb835e7e,cdc681c6,ee1c89d1,dcbae3b,a9511692,a54c9c37,2f86f4b,cc7c62e) +,S(867acd03,7a3e5f86,99e33f22,72f7b1fc,25ce6622,5020a4e,ca3b3111,e880653c,e9112ac7,57d3f905,3249ba3c,ff64640e,639cd94e,5d6cf946,d8d7f3ad,25764646) +,S(5e0a4169,e4f81dc2,28ae4663,9ae3bd4,b527814f,4616fc13,318fd5db,26df370b,5bd335a8,fc23934e,bee2e32c,3bacad4c,c38cd624,8cb34ca9,e58f8add,3140d001) +,S(90053469,39df2418,1b5b2e57,82a82f15,542a55a3,adfe8263,663b4fff,b101c0f6,4ff0d589,973985f6,858f3837,89c3a5e1,74460778,3a1b1476,e3f1ea51,37e3d991) +,S(a99439a5,53df33ba,6a32f33,d90b1500,4e2db077,22a73561,8f4c3b0d,63cec63f,198e0929,f11fc777,ea9cd8a2,e4e6987e,6f9c1fc5,f703ce7e,7e6423db,39656cd4) +,S(51f2a136,1381ba14,c8fab71d,f82aa2e7,1c7789b1,b78c355,a0e2fdf1,5f085282,fd5f129f,ca15fea4,d6f23bbe,43197a3e,6e2b7b26,84934ea5,a97197cf,eb2d16a2) +,S(3a91f81c,8b064b2c,99509777,864c5b4f,bed208b8,f541f68e,82053158,2ea91d3a,9d59003a,d4ae39e1,95077329,e585a8e8,a542b594,b6010404,8573a01,23a513c9) +,S(71e99d50,aa22fa17,3f026dee,e728c114,5e491e84,e140b462,1056af19,9736c5c8,ff3e4f77,68588846,7c662729,1d947e77,699806e3,9bb0bb26,53f67ec4,176a4995) +,S(ad149e93,3a0344f7,3fb53286,ace2f3cc,46f7450e,e859980e,6d392001,7c8aaa39,7dbf4798,85a4f354,b4f14060,39a83789,65a5ab3f,f1157e3f,2a4f6fae,909e81bd) +,S(44f0a37f,5ad78f6c,4a40ca20,7969105e,86e79ed7,7ebbcc32,1a247f91,751ccb01,f404d867,911eb3fb,efb1e559,66b5128,70836d9a,12891905,af649555,c353044a) +,S(4f77dcc3,de8de08c,4c0a4a8b,29717868,50f5c0e3,b271ec1d,c0d38a61,b30ad5d,73c7424f,8ae80ee9,2118aa5a,b0aa65b3,58dc7300,806ef2fa,55836a39,4df57c69) +,S(794a108b,102a0923,6366efd3,8ef658c1,6d6d5c24,e5e2dc0d,38d71371,e6005555,871965ef,efd79050,69acf0fd,c1f84798,7c9e304b,5fdcbf75,1a6f6737,ce46ba2c) +,S(f1988561,234b863a,df5bd49f,5a0b1252,a72e297c,ea3083a8,22da48d7,14e8e594,7adba507,d0ab51a1,8c036612,dfda3f8f,abd2f573,d31aa03f,ca6eb361,a83fc418) +,S(48bed556,c07c99e0,71249b8f,7790aaee,f3fd27db,f82d1c75,491a18bd,cc3f4a80,9dae5280,21be418d,1b4dd08c,be5dbca8,46cf0122,d4943543,8561e555,66316e94) +,S(bbfef3fb,e53779d3,8f376fef,974bac74,ec8449bf,c2dc8a1f,3bfcb33f,943ab9c1,bea5b772,ee798aff,c610e849,5be0ea8c,ed462563,848030b0,8006c6cd,e312551b) +,S(42af3415,27b3cd52,3806b04b,ecc175c4,156839af,eebc212e,b74bd6,95b7f06,686e5fe5,ebf16ff6,2376d096,188de980,f91a5518,25bfa137,e7b46df,59dcef4f) +,S(3c56d78b,74ae87c4,6efea376,d58b7d5e,30749726,40c24d69,38ade127,71ce10e6,ce97decc,f9d1e215,d363b36b,6ca2bc6c,39fed00b,511bf883,50732752,48d54a41) +,S(4b122599,1944ef0a,ae6404a9,e48f69ce,67b52a1c,da4f291d,33afdb09,b789b61a,5c8be350,27a3f992,5377932c,b6d92bc0,62b1bc80,78e4611b,f3ebbe66,b6089571) +,S(9e42867,c02c9314,a3658f18,14d8c59d,71674955,2b00be9a,cd37350d,18d49db5,5d26d035,1ff90d73,d783155d,afe20cf0,39f65b1e,6d8d5d0d,831977c7,17a8c761) +,S(9643390c,5a95345,2a027d0d,47bf6fa8,306ab31e,5dbd8b94,402db973,275359ae,b354d7f7,1019e9c1,d23560d0,50fbd4bb,abbf492d,f595c0ce,a699721a,b27a3933) +,S(8b4916fb,86f77deb,505374f9,1f15782,1b6f7884,feae9f77,bacf5620,7e126b69,9a83c0,6d86db13,55c3d59,cbc87fae,ce6d2af3,64f9c213,816cb326,28be1fd4) +,S(d29df4b,109782c4,1f5ee9ab,b8488f7c,11de8efe,9552eff3,7ba3cf0c,d0054b9f,1bf06237,ea242c4f,bbe08f6,a79b6808,d1a5a444,1989fd1c,98a60981,40ca07a8) +,S(2aaf397b,a5405044,539167d0,55113acb,d4a20265,206ddede,203b8ea7,21dbd41d,374e32c7,1132bbac,91e4b4a8,aa32f308,13a81c2,4f7b3c66,63d8821e,9ef73081) +,S(2239b3d2,23eace6b,8ebd287c,8b6a398c,1ca58a94,5d8b7b81,7b1133f9,cf57ef48,fda880b7,4b54a8b2,8af4b26,78e03f28,f01d70fb,3e4ebbda,94ccbd43,e2b4cd46) +,S(8b3287bc,f47e72df,7edc9178,51edb145,b88ee233,9f254f62,e86ec624,a7c7e365,54a06bc0,9f60d54e,5f900868,c0c3d37c,db6d9969,1eb605be,321f0f20,9fecabb) +,S(d9accea3,3e3cfee9,10d7e1ff,3e87539d,ace742c7,24d6d36d,d8d981ca,984f7993,6adc974a,a901e5d2,d8cf5a05,a20bd02d,62947f81,5425e690,565638a8,427dc88b) +,S(d7fc57f8,34c348bd,e6692b50,474ee038,4af245da,40b8f6b3,8df2ae5,a8b3206d,b253e4b,41fd9fea,9b28e04b,a6db0324,231edb1,1f9af406,e38d2b30,244e2d19) +,S(25808fe0,ec4a1409,36b34e16,595021e2,b815f660,7a23d505,9ad5b5c3,14d9588a,d0664ad5,b1d46ef8,8c8a1eef,bb9df1ff,a75bc16c,e8bbcec6,6f4798f7,c58e7b96) +,S(e4474780,113955d6,72152fa5,70da35a7,59e67a76,29a39ecc,3226ea13,99927914,493cc170,aa2f0486,da6834d3,3566c78e,ad4eb3d2,837ef5ea,c1adf3f9,43793bee) +,S(c5040dbe,2af9d706,76ddd900,d00f1046,44e2b985,82d46f11,47602b91,126311ad,840aab11,a2316171,cc9b6466,778a9ce5,a7cabc1b,1077586b,91a8d280,324ddb15) +,S(23391baa,316d33eb,3a7ca123,6c47d4e4,8116cd4f,93bda3a8,12a228eb,437d9f14,1d81341d,9e6d76fc,1ca69af,f6d8d119,bc97c79,c7cb8b7f,1ebb54f5,cb7efd4d) +,S(13211756,3de3ba72,2fc6682c,beb39494,8aeb8fd8,c0b95eb9,45eab34f,bc39ac38,9b772721,8a4b0823,7c961431,e26cbfb9,aa527905,41b753df,89eb9ad8,8d74f006) +,S(3b8bb898,b27a2fc7,a1cf896b,bb5cd7e1,708b943b,afee896d,2ff77a95,ba789708,d81e541c,668003e5,5a1e13e9,6a1635de,7fdcbf79,c34068c9,248100c8,9d36c1cb) +,S(e1d70a2c,9af5c4ba,c505e4f5,5c0040ff,d94f162c,815a2e21,c7ce899f,e0217b4d,b25630d6,d20e0e4b,3686d66d,e2b1e53d,eb063b99,e79c212c,2fd3cfec,97a4532e) +,S(1b1e3823,a51778fa,d38f0c56,e2b36dff,a7e681c8,30fb41b5,ff1aaa7b,d912de1c,f2e99a90,a951201d,ce725855,6bf7fd27,bebe1626,8328116c,d593ff32,2584d4c1) +,S(1e31d838,94f56191,2c134817,55e467e1,8745a91c,d903102,e48f7282,21bda7a1,11dcef88,35dae18f,3c02c6d9,7f80896e,477a7b27,41203aee,5048c94c,7cd610ce) +,S(cb9ac34,795cbc99,bf67a7ff,2bc3b497,311f687a,51b5028c,422b0301,8ab7100e,5e5f0621,c804b35c,e01e95e9,a8dc13f7,e5ff32dd,8a44f320,74e44836,3cd0db1d) +,S(afc34ac4,67dad38,a0e326fa,1a656c48,24dcb884,f00a20ce,56c73835,b4e11c1b,c8b1c404,3f6d647a,382ef031,a02c10cb,77a033ae,bfc6dde1,d7508136,28bdcb96) +,S(3a6fc160,ca85aba1,619430bc,ba14e12,3330f636,7a78273e,603f85fb,e270aa81,594a2b72,86dbb390,945a7a48,3707bc32,cb72cfc9,19c241bb,61774dba,222bc0a) +,S(a840f695,657c9c3a,3f64f56e,af18debd,bdc1e4a8,e3eaee43,46b19601,433ce7d4,8a8a7ac0,ca41e2df,461eae96,bc00131b,1a77b824,7273269d,7a41f49f,ea126fbc) +,S(c044e01,70ec6914,c39d08c3,4a293268,65cd7762,d6e0f3e5,5f69d80a,e80a39d6,7bd63082,7ae51516,25ee0b5e,c2f97b37,6dd5fd7b,9205852a,92dbf922,3a0b4657) +,S(cb90135b,352b969b,45eb5c6,7cfdd288,2bf9271a,41da4b2a,a89dde94,eaa00b3a,14cbeca0,762d9b11,fe4b6d26,7277a8f7,b4dac82c,52634b49,2a84b616,2d79be93) +,S(fa7bc437,a24dab0f,21c7c063,3aa4a8ff,c8216676,75ea6963,c58c84d0,b182a0e,e24267c6,d7300c6b,6dd09326,c49359e0,fdf72114,401f244b,383eee54,d1a5aa35) +,S(e6354cdd,3f503d25,37b2bef9,91533ad8,35e95657,3bc8afcd,d0c1c05e,57b3299a,d6c17b70,6291c8a1,989955b9,ae9ef9c7,cdc2b6f3,f5cada0a,3c4d0b86,859ead7f) +,S(9da36530,7e815e3,df0dce9d,50d7d812,132ec23d,2bf0453b,483af1f,bb45cce8,bb374566,98a28ace,a86a1b10,2909ae91,3bbc4b23,22f4d09e,bd298e51,d067a8dc) +,S(dc457a1e,1a19cdc7,6ed1c3b,a416a886,13b25788,22d691ba,76319b8a,38c9d4db,39f93f66,de5a650d,d49919fa,294638a7,85e25bd8,f8285776,dfce813f,bbdc3b58) +,S(b2377b1f,1b1a0e98,5ff57bc6,64ca456f,ec216c6e,b7b389a9,62b9d82a,ccf0374d,383a5580,d723509c,bf114e74,b3eb9746,7a040fc0,6232adb5,dac199ac,77578c1a) +,S(8b1a6446,755d3a85,3851fabe,b95c24d8,2a5a86ce,5e5df65,78051124,acfc7e50,42b885d4,cb632a67,51a88aef,192a5bfd,ed1cd461,438cb623,1caf3346,9655cf75) +,S(9408819c,bacf1a0c,9e5f1416,23a907a7,c3a7efa2,30a15b3e,7d5a6ff2,5103f5b1,a9758ec9,d6f84f73,fd107451,f0ab79a2,1df08c30,cbb2456b,d6c68cb,c506f98) +,S(8bfef047,7b3f8cb,99d7c933,a884da4e,9ce6d473,c243d3ee,9c319870,b06ce25c,8bbcbd87,d06af17,550d17ee,83017c58,627f1d84,e8a07e37,ca73c12c,f7e5c498) +,S(2a857f0,c12202e1,1dcb84b8,adf582f9,8eff647f,c3803cc0,dc1d294b,414bdb61,9bac456d,a7fd9318,244af8c6,48ea23aa,62c8ae1d,af7fa9af,e430efec,46db6548) +,S(937b8c5a,90485ed3,d06b224,2ff53e6b,b94b1ee6,a493c835,25e3acb6,5d5cb5ec,d37b136f,f9fb374a,50f5a311,ae366ca6,c9c3d867,e9b7e788,da3b2766,a7ccd808) +,S(5f544d53,e2bfd6be,d9150ff3,6a1e5c5,22b24933,489201a0,65a0e0a0,3a43c77a,ba9c20e2,8c47cd98,1752c413,70ced32,8f4c847e,20165562,c3137e0b,12990f51) +,S(67b63388,90bf8baf,a5b64fa7,eb9fa4c9,e3249cfa,81a55cbd,9c297e7a,a7c807b9,dc185675,2d94b811,42b54577,edf808a5,d871ec1,6c8ba567,62061dbe,ae7625e6) +,S(587a9dd5,99cb448f,9f92ffa3,d6328032,b76604d8,386a2e2f,bd324628,98439442,496998e9,a893faa7,a49e73ca,2dbbf533,488aa687,51ffbdee,6b6d6dcd,dbae9870) +,S(36fb7b1e,c576ff9f,81077312,35d18612,18dfe51a,58642a56,8f80294a,63c29b38,34a45ac9,b82cb1bf,2c96fc1a,67de8a63,5c1a1589,61baf8e8,a2f01572,1566c4aa) +,S(87b71c8c,a0afecd2,dd8f49c5,109ff434,ab8a273d,4e4efcae,f775624c,71f4ba95,8519151f,51122588,76527c56,e1e6d9c8,5b3626a1,bd6ad0b8,1bc382cc,525676f9) +,S(acf65cf2,805c370b,a3bed962,c3ba3b0c,56c98,b81a696c,f433a0e7,a463e040,f093929b,f45be16a,f962762b,52f57ef2,dc7b0e23,cd68e3d6,63b3b402,15692d5b) +,S(e092bfed,8b010c85,b91f1674,1cdfb1d,e3e045ba,81297f44,8990475f,2147acf1,e0bb9842,ecc8683d,e4016072,86070da9,8c4d18af,8bdda91b,65770a98,77902c37) +,S(9bdfd7b9,8260bcbf,17812735,c70501db,ba386b7f,28ece691,97c871ca,610a52ae,9bc65398,3f8c4cce,731e01ba,a5f509f4,887d9a78,40620d9a,ffbcfdeb,5e371eeb) +,S(3db22321,d9311589,5c85587a,9095421c,afc8a80d,86a4240e,9a4a2f82,8643545f,42af30b8,2c57868d,e0f23c9a,fb19947e,fdd6bb45,4efc68bf,ddbf7349,8fb78eae) +,S(e9d3f14,a6a77ffc,f86decbd,c5e43fa3,c3757a64,22d37da6,25627961,622b3e5f,83ac0bed,1e2a714c,c6ed0764,da92cc17,fd18ee84,36d667f0,2f90f818,30e67de7) +,S(412486e4,f29b4887,e1448af,ad59599,b31b9085,8682580f,891d51e,9842f2a4,c31c5931,8c0d6790,c2fbbb03,9c2e761c,bc5577b,53161a8f,80d397f,de7ee3d) +,S(e9deec71,41ed506f,e2dafbe0,c9ab75f9,609f8422,a4b2da26,7c529d92,36b4ddaa,8728544,d8463bc2,d846029e,5d2a0a40,8dfb767f,9adb79eb,2209478f,6d94a21d) +,S(5a0a2292,553c46a0,823a1761,2b8925e1,bbf01c2c,5bcb7173,5f0fd6ff,b264218a,3097cdf0,adda0f10,a261f897,6447ff9c,12de696,8f05009c,e90d1575,e55dbae2) +,S(49cb2a37,8b681ad1,ba1dc23d,8d12f186,563a40f9,ce0ffd00,5bade11a,4928d1f,f235e2af,c0f65fa0,ff15a938,ad804a3c,fbecc5b6,e276bbd6,32a06959,3d6732d6) +,S(d4d71cb6,36881177,b05ad510,a621cd44,3dd1afd4,84d177cc,f99abdb9,1615feb3,3ad65378,de3eb9b1,606f385f,a950d533,5316c363,fb076c02,ac7f12f0,7562645b) +,S(591b2e1,4bdd6e00,64f798c3,14e86cc5,529c99b8,3f47d148,b7e3e642,35bfab2f,4f686266,fd2a4c66,4d6bbaf1,2a368d59,12a51789,5d783aec,a986a568,a8fa59b0) +,S(ee503c85,c984bc49,3d7b63c2,92eac9de,be253400,f4988086,970be236,47356876,bd828abb,6f9e89cc,741704e9,614d6711,39449bb3,a7ebdccb,976c573c,4bdaa47e) +,S(2f9b4fa7,2e5a1fc,ca36a3f9,8987c3af,756e78c9,77fd5697,758c95b3,14b3f89e,9668615b,3d5b3c74,4ea2e1ce,e909d9c3,956657f2,1a65fcf3,3f0ea150,1ca4a15d) +,S(18b6d06a,a34124f8,5f92b204,e2a010aa,a1f4aebc,6e13a62,34eb1c92,7afd46c3,66cc31b9,bdf600b0,7e624bf,a3e079f3,258b0ba5,5437264f,b460481d,1f4bef4e) +,S(3bc07963,bf758dd8,fff37d0f,30db6eb,67662a4d,65395688,1cc30340,ddb44ba0,60e11ef2,68209a1c,2df9a3c2,276db6f8,8e6dc1ec,b74548a3,57d770c1,ad057e5d) +,S(bf585d6,5b325423,afd49af3,c9fa68a,91498b5a,f0ee9e3d,d089b288,53a46a8,2f8944e9,ea484b9a,51256e2c,fa9e5396,4c000c1,3451cc05,94bcf6ad,e38e66a6) +,S(887c0a2e,be7a0257,5d5b59a9,11f40ef8,f0cf1438,d7f05a7f,64e9c133,cfb69294,45f334c8,4f9bc66f,50fde594,94175491,9c37c30d,d20f6a58,40271e71,60aec5c9) +,S(9dad7af9,a73325c,59a17700,fc3dc6bc,3718e79f,804a2116,1bf9a36,622f7d4f,2b7c225e,99c6a94,c7e326ec,b89eb8dd,40644bad,1893136,6442985a,e6159525) +,S(847e4f95,72bd29f7,4f3e9a2e,d73cdfcf,63bcb61c,9caf8694,7cb84594,a7dd551b,ba6ed282,e0a92c62,fa86286d,370cb344,f6f1182,a101c4b8,1ea89a15,b393ee16) +,S(25213205,df1c3600,4673c4b4,49256c70,b5d8c62c,cdd3d580,2684af47,f047a593,36dc81de,5af4709,fae2a47a,8a205647,95aabfec,42a79f3c,54763d67,ef096837) +,S(75228cd8,4866df7a,4713a25e,f2fb29fc,95ebfd70,5d73229a,b170cbce,1058e87a,fba4879b,cc02d3f4,fd25f056,c0854415,68a47355,929bb812,a7dbb30b,c012fe6d) +,S(74945539,22867c08,6d02fb07,c0424890,981a1337,42c63fe4,b6adadbb,59b68568,7d774917,8df8b19c,8af0bf0b,5247e751,3e3b8d04,46465180,341ebb54,1d1af3e2) +,S(69db7f53,2899e39c,fa0cbadf,c29946f2,71d28ce3,57f47f7a,609e0fcb,ffc9b04f,cb0243bb,103255da,ad423ffe,e1d50f9f,26da7cdd,764a11f0,a6694b63,199feabc) +,S(727ecdc1,fb4a0dbe,fd2fc37,8902f922,ec4aedf5,53dae225,1d173c29,2929f8c7,ae5bb2ed,13778d60,66446ee5,e5754db2,bfc4f7c1,64bc035c,224d495e,651f453b) +,S(903ced8f,ec2544b,e207f5c9,e2c7f2bd,91213873,5eebc382,b129e334,7ef25b72,2117ca29,ee13d31,5e89bf33,afa8b7db,ff75c795,6be40c8b,b2e41cd5,943190a6) +,S(c4d467ef,5149e117,3638a5ad,6fd36373,1c8906f0,80336ca3,3a6bbb99,1a03f33b,ea5b5b24,4c536bcf,ce3d437e,abf2fcec,431ad80c,ff975b63,bf398163,629b5c7) +,S(16b577a6,5f6d09f7,b23b2b7a,dd80a2f1,cff7a8a6,c36bfcf9,d325e37c,ea37326f,66ba8e2,14674e5e,228a6576,a52a791,84d98be1,db1a2dcb,e9073934,d09f15c1) +,S(ad4bcaf2,e480adfc,e1e45384,6bd7ddf7,67fceedb,d2bf1f5a,6768531d,9b63412f,51fa0360,47810f59,11b1b3a4,525ee72c,c4c891b7,56737f4a,a61a380,e9e741ac) +,S(b249eb38,52d2e787,4a52d776,d1bcb399,51ca65de,dd9e9dd5,87d73362,c33b571a,3e260824,14e4ece8,83cd84e,b177096c,62dd7706,a79c31d9,b1103232,53a66258) +,S(634192c7,696a01ae,81310d3a,59d2c53b,74dd0560,7e3be9db,ccfd1ec4,bde14a65,455b4850,e366e077,d86dcd70,9c787b18,4fd4cce4,4b92954a,dcbe5222,57b0e00f) +,S(ffbecbf5,d433f80,49e159cc,c14b198a,acc3c5ed,fbb1ace6,fd295dcc,4a2f5099,422e7aba,1ec66cf4,36489acf,9c03ba33,dd68d368,8a48685c,aaa1de52,440be3c0) +,S(65b4c4dc,1067e823,9cf4f1a9,d0632da,b6a8c83b,509a75ad,8c133dd1,5c1868af,f7cf5d9d,d7654618,5183f8ae,7f42a03,20c67817,9d5226d8,40dac1e5,f94d260e) +,S(d380ecce,9d603502,d518dbed,405b8d0c,8de48dbb,35d5b559,24c1a560,9bf9c67e,1ae84480,fd18ab10,9eb0ac15,265c609f,8b241b4d,a80b13ae,50c35f8f,db64c128) +,S(17189d28,b5ce1bbe,d78a1d96,15dd1a50,3fce43f7,19d042df,63484ff4,ce44511c,fbca28f4,7c7b3e39,4121b948,ba561289,85c53298,8db2fbb5,7596a473,a782350d) +,S(fbe332c2,e2a8b07d,a85ae4e6,1925bf3d,be685e4,fafcdee7,3f558382,80c2e84d,aa917342,5e187da0,e3f8c6d7,79b42cbe,b11c43e0,6b594eb3,e1a5797,ea4e29ca) +,S(8b9e8a87,8b5e725f,8b4bd518,22e9cd21,2100d1f5,cdaaf210,2d7963b,a0bc834f,331fb31c,c28f56bd,5ff1d6ad,80b65702,b2e873dc,4552c563,bed77a08,cc3ed659) +,S(97e92411,a3c0bcad,17a798ac,eca61ac2,34e1a68a,b668aa3b,d730cc8e,8de111ca,b0f170a4,bac15e17,2e75fb75,93c21a41,4794976,bafc7eb,7cdc4bf1,6947f48f) +,S(20358813,33a13c6e,cc8c76f8,2c279577,49aa3c1f,d4d51691,9cd23b25,d044eea8,480afaa4,8c86af0a,ece2f951,7df0f344,259fc4f1,4d9a5c0,ee73c891,780c7f29) +,S(caa1eccb,1575740a,90155103,9849befe,617579e6,22b7c343,a665beb7,a67dbcff,aa695bf9,f1c972ff,b6fd3451,1bf042d9,1aee5113,9c1ea577,e0bd52e0,a4e0a20b) +,S(8e7c2ba2,36f7a8e,fdaa212a,7fd6b883,f331049e,6e8f2bbd,138a3adb,c2620719,bd03702f,1434fb3f,5846c4e2,e779f8c0,d9b6e031,1feced02,20a618f8,2eec105c) +,S(e07dc033,6dcd04c1,fcfebf09,40c07783,88fbad11,8e4eb3b2,4dd637c7,baace975,b13bd0a0,e5eecb0,762ccf31,1bd53156,ef6f9268,50044195,10d6616a,b32a2c2c) +,S(6606c825,2679af01,9d8a904,4db0b28c,95aba791,d1c33072,97afa2df,bb8ce0cb,7505e59c,a9807993,5710de77,747868fb,10fe6c57,36ba2054,6477cac8,8e1d3cc) +,S(9fbf4cdc,ec48226c,b45450f,b0de5dae,2b31f935,2b99e0b5,22ab9935,1de6f061,f2e4d0a2,3da020e8,60a0d58a,2362b7dc,e9c5b646,7034ec91,a7dfa601,1ef850dd) +,S(e06d697,5195ffc2,988b0403,e977d32c,b7cc8167,e800db1b,976f6186,286916bc,8015370a,27d3d221,7af80e04,a49003ea,68302bb,c1a5c83,63244c0b,c30bb8bb) +,S(adcd67ab,21d2aac,65112fd4,e6e16cd7,ff792577,e9785a6b,cf4a3f0a,9293a6e2,6527b620,29062aaa,5058608,f5cc3bad,8e4f40d4,9b5be93d,faa5c2b,57fd7fb8) +,S(1d9069ea,b43a64cb,1187e963,d96809b3,5a447317,68910e13,3e0bf7a2,e1f2bd38,ab03dede,854b8fe9,4ad2f9a6,8ef5415c,fc78c28f,a4ec33bb,f15df31a,91e29108) +,S(f1f6b776,b8ec892f,148168ae,8ce83f4b,603206f7,2a38140e,3a422e67,a20a768,892ba036,3413da21,17d9b11a,7bb25cd9,e7136a7d,82a7f45d,14abfcb2,b9bff25a) +,S(a884f94a,ce79f4cd,f3a8d1b,f8a2dc3b,c21d1c23,433a7fb0,401c5df,1efab379,5f53356c,6e45248c,ec282fbe,ef03ddf7,c611affa,5d0d3082,dd630f80,dea05c96) +,S(b1988430,197a8800,e1016564,b48d4f7,1fb2be08,35e9efe9,81a80f10,e61da9ff,d5c7864d,ea7d12d2,5be7ace5,86e141a0,e515a41,5ec70bdf,44a68d8e,4dd849b9) +,S(15b73aa7,529d5b84,bd5c1db8,2b6c93aa,46985aae,942f6d4d,1094434e,d27fedb,297e32a2,bc8ad13c,42011259,b1ca3d40,632ac6de,f2fca262,75dabc8,ee721f89) +,S(339a76e0,443c1fb1,65992630,116e523f,8e35cc7a,16cd0f3f,57f7782c,7d97d40f,8990652e,fecd784c,33e75620,13b52e6f,914f0f6b,c413aa22,9e5bd773,cdfe9659) +,S(bef26cff,fb80ddab,9458312e,9b09044b,b1c535e1,84f4e51b,f64b5183,b67adfef,3818929a,ef076a83,58f20518,c5b310f5,2c6943f2,1675bbb5,ba1bde45,9d37490b) +,S(cdc56c81,8dafc273,4f4dae10,84f91b08,3dd40d86,23125894,c71d9243,8b2427e,f4b309d,e9c828b5,44542569,45579f91,b4376935,3f586c71,f07107f0,1f503cca) +,S(3ddefe81,b1f38479,ec9be80a,1961c5fb,a09312a6,2a775911,cd65200e,7d75bc6d,75d83edd,1eb9b479,4effae4e,ba8007d2,7c7e2d51,a9e95d3,a1e58358,56df055d) +,S(da7c6776,99032cbc,4c2bae12,59212cf2,a18879d2,63aaf99e,76339041,10576826,2e7a6d88,360ac45b,9871f779,9e80698e,4314cc3c,3f1cb1d0,c07ae9f3,38553f08) +,S(2611b435,e0bc20c5,88cfaa80,17f4555a,b8aba4c4,ae1c0385,9dfaa911,aa80d927,eb58f81a,e51dc504,465ff8c1,c0529fac,e47549d2,429e5b41,7ce0cad3,7d4508d4) +,S(b0fbe548,36f07c4a,a715aa08,806b71d6,b8f4c09,6945a7bc,3defec7b,67962961,cc60a224,66e7744d,c58668f,ede30ca2,1c1749b0,45ee50de,2a881a53,83e5abe0) +,S(1a03336f,dc51ee75,facb7688,b4603c86,77d371eb,5ededa9e,b50bb49e,c9020581,3fcf1b03,9c0edf8,99855fc3,6acfdbc7,bd507145,9be7e18c,e9f715e4,98daa7d7) +,S(763a1215,c8349155,aa849b20,f2f68a36,cf72892,49e4d3c3,810ee72f,78c159ed,37826a1c,cf30e1ed,a1795fba,d1f2f227,7b68d5c6,9ffd390b,d7dde5e6,58482684) +,S(7fc7b4c2,30183e37,dce0a586,a6f0188c,f7e664d8,5fa05eff,63f2c27d,cada4edd,fd7a780e,6ea89a06,f0649343,abe7bcf,6338d2fa,fe457f50,ac415c91,2bed6a8f) +,S(222807c9,b0686f55,d9eb7d7,412588f,dc543bfc,f016c8d7,74726135,dc65ddd8,b9670902,456c22ef,cb36d155,319393da,9a34b2b4,301c898b,43d957b0,a56cc2ab) +,S(79d8eb36,98d8d06e,6ca33f69,ca04d3c6,db636346,abfd603,ed0189f0,fc5fda77,bffc97e1,1b0234a9,8dd1d460,e19db522,931fd49e,26d7ab28,f1326517,23d955f1) +,S(a2366618,8e72e1b6,d5ab7713,decf6e3,1f801a6a,ac88ddc5,d464d127,ebadd34b,ef23da36,f3e71913,2774cd1c,d150ffb0,70e99ac8,5193faeb,b1736abe,77d60ed1) +,S(b6bad04d,dde6816d,9123e8e7,43fa46a5,b1fcbdb3,fa1f13be,480fc1bb,49dd9612,585fae09,a290b273,a68b7f34,645b80b1,850c6507,d959b546,7f1b0100,b6a4e511) +,S(2bf21c25,3353e715,283113db,8bb5018d,33fcbd58,f3d6face,b491e1d2,f4c3dfbd,e3a033a7,4e8a4d5b,c8c49121,43a47b07,b9fec4d8,a0d5b3ef,569c44c9,cf8d896e) +,S(64c27a41,e978e35d,63f3a90,e71091f4,41e9ad26,6a05edda,358dddd2,5d842744,fcbb625e,8fda695,988aac9e,cfe67c16,bed76802,3b527d27,521c1339,3dae32d1) +,S(620a1ef6,fdfe5b5e,9a4ef435,63cd7c8,af62acad,a02fb399,b7542d2b,6481a58d,b0b79e3c,550393a6,fa07f105,c547e203,a45fa7c5,ec825ae5,7bec305a,ddb8054f) +,S(1523f131,7cef7154,347ef68b,424ee0c6,15e71251,a06bf8a1,ecd74675,307b95cd,c72554cc,1d8ad664,dc1fe67a,3f11e5b4,a55806c5,53dc2612,bf5516ff,f0743b1d) +,S(d765303c,a9c8794,c00d4d8c,2cd73fcd,b43f763c,b753700,f66d7294,4eea0cfd,bafcaca5,204dd77a,a3a17b73,da3064dc,35b4cd22,ae01a623,781603d2,57bc267b) +,S(a75eb61a,fafce965,65198759,c25cbc41,ffbbf87b,61839a8e,a17f04ad,64c468b6,99802893,240f48aa,53c49b18,1a6d50e7,a8eba321,64d587b8,41497d9,65869873) +,S(7fa41b4c,d0bb91b6,c25813c7,1241e691,e7053f7d,beb0bcfa,4084e06b,bce59f2a,a0941779,755a695f,8317e7e2,f6a2c57,9431e22c,4aa09f,7e583b1c,e184aec7) +,S(816c0db7,2240f12a,d8deb440,8ae2276f,3bfa1bfb,d820bd6f,cc5ccff6,16e4dbf5,2a52c93d,d91ee658,9449dd4b,bf70255e,e57acbd0,a981ac9f,67c16604,3f7e52d0) +,S(33f635f1,317f1425,51390ac7,346905e0,ddbb3d87,b0c1780f,bb7dc950,c23414f8,7435a155,84eb1988,b974d570,bbc2b2c1,15123580,2bf93bd,b626a543,e54bfbcb) +,S(d2943ad7,4b0bb03,35307185,fbc438a7,bdfe11e,7b5e0eb3,e94bec46,a251999c,2dca8fcf,19aaa314,ebde41de,fff6e9fc,b6097d6b,3bfec06f,19aa4941,676d577e) +,S(26aa1fbf,c54375a6,fec54390,b5e44a0c,fb524b65,c10d1516,b0112525,9dfb1da6,49eceaa6,4c575ce,337d0b6,ee7e8198,83973c6f,abfa2f,d4b24e03,99a91b02) +,S(780aec1a,f866a030,5ca6d7da,1948f2f6,ab18717d,e82300cd,65eb58cf,a7d28d20,da650041,e45a0e1e,a9075b6d,107b6f7a,414b3a02,18aaf929,92cf2978,bc08b91a) +,S(1dcff259,8e59dd4a,3e515853,b3cc41e5,ef98113f,29ff7b3d,5eed6d50,2cb88b67,d7978630,7c6871e4,5654307a,e3836e07,aed86cbe,a9ab92f2,8c680172,1ab77271) +,S(b19af4a2,77321937,93e367eb,5ece1c63,8f336f3a,9cdb4b01,e2488ee4,373ff70d,a3ea8839,a5105a2d,4277f27a,26a8ee73,b9e73fcd,d54f641d,c214d5f7,9c821dec) +,S(1c8c1f29,548a9df6,f28b6126,b9324972,35f24e2d,a488e066,acf782f6,b4f6755e,1a79ab52,6a1e1aec,5ccc7e2a,3196a07e,78108b23,a86630c9,1795ef96,11ff432d) +,S(b6ff8dda,1ad6c3c2,3c8a10b7,b4313968,e4d70075,12c421d4,f0b1153e,bd5716ce,4d3869c6,b7b74167,ca0d21e4,edb3e01c,af8dbec2,aa87a32d,7c9306f9,a5ce61b8) +,S(dceff4ac,f61ba84a,81821932,9fa0ad60,ec08cf9d,830e6ccb,375488ce,d0f47b5c,949aece1,92bc61b4,883d5508,aa4a4aa8,fb1b8db0,385613b1,736a6eb5,c137d6f9) +,S(5561e7a7,b709689c,97c4aa18,9a3ce841,843ccf98,be851c8b,131eeb37,dca5ebef,4b108c17,f298be36,430e6b7f,26b414a2,33b924a6,e65dd5a7,9a1f15b,a99a14da) +,S(4d989577,89b01595,8e5d5bb,2e064e9d,9c56a254,5b3c8802,7ca0c997,a395a257,aaebaf33,ac950756,c5b200c9,f5b009c4,506964ce,5b706675,7951f221,40b6e0d0) +,S(82b58e6e,6373c4b,30ad55a9,d66cc804,e9da512f,bf4af668,1246a12f,e33bfc8e,8378122d,98dc1e37,2c33b5c2,1ff4c429,d6d7577d,2ff353d3,87cc0478,1a5ffb38) +,S(f49fa88a,a773784b,fe57d880,9efac44f,714c3d75,3669463a,d1199be8,2c6cdf3,41aff6c0,2164a411,c8be7281,493483be,aa9855b0,49820772,b96aa39f,9a18b3f4) +,S(67d485db,ac8445a1,8c1b97a7,8c1852a5,ce910f0,d78b073,969c58ce,c0efd78c,71dda92a,24ff2b31,5fcaa5a8,28bf07d9,596f49b9,cf19f4be,44e6f320,84981e97) +,S(9145f6f2,c19038c3,cff99883,b5a71760,30a46f7e,8b5d350a,db2a9610,4704d4cd,9d9179e7,852ac5fe,1d4664d5,4d778b3b,6c8e422b,b6e78add,56700dbe,6a22b0bc) +,S(492d5247,efc2f5f1,1cf3848c,e0719abd,53674089,808de4b3,5503e23f,46b2631b,374b0762,7812c898,7ed68877,c995a4d4,9f021d0b,29270863,d50b8c40,808fd750) +,S(5b8ddfb8,bb811678,9298d231,72bdb9c5,25c6610b,46187549,a381ca6,17dd1dec,b47d3764,fce3218d,17d0dee0,133d4f3b,c7ae170c,3e8831ce,a92a3531,7b1f7568) +,S(88db73ba,25a61641,af5e603c,cd54c6d4,63c6feb,da11ec5c,6a35d30f,e406c65,39b06f7b,1c1dd7b7,884c67a,e295f8c0,9b8b5be1,c14456b,4027bf1b,4800a753) +,S(3495cc9a,a23c1eb4,2cd85070,bb095563,2a7037bd,e330f721,fb38091a,9c382451,7feabb21,6f3982df,74429957,3c7557bf,b82ff4f,462fc64d,d9b3e10f,b69799ef) +,S(e8a5cea6,970e10c7,93f75666,9d2309b1,a4f7b52,c19db4f1,cd69a652,c445d7a2,daacdabf,bd5259bb,96d2dbf3,668e8c16,fab47624,294d9982,b961f0ea,32402b96) +,S(6e8c78a,e81a7ade,3989c483,7d9efe50,51af33f2,b2b2ee32,b5700b43,67931f9a,e5664504,751b41a1,45b5412c,be10a782,7d1d5193,30dd69ca,47be2975,2c291d35) +,S(b8f520a3,10c5b2f,8291722b,1e3a92ec,b9551db7,744dd208,ab4d1709,310a539e,65901c3a,b6712ded,8f66451e,1915113f,a96d3d1e,d9074790,9e291d00,970f3d75) +,S(a0538458,64459815,888bd917,3a2c16fc,ae0deaa7,cb804adf,e49dec0b,b2d8005a,27882f00,23dcc9fb,890dab73,f98925d3,e712608b,3d6069c8,ca58ca6d,de0d7a67) +,S(41280416,aa7f0924,1ed8b631,fc2959be,2117cf03,9c12f600,1faf8a05,15222144,c2fef80d,fd8e8433,ee55c363,c43f7e06,613f354e,32aef8e1,808817b1,af7f58e4) +,S(c4b8ff36,cbf83d10,51d130b7,e3d613b2,8b536f0e,b050a41a,7dd8f8aa,18c7a1ee,87d3c44c,8867337b,466ba76b,47512399,f6cf6c14,ad4977fc,276d67ec,5e7b4d47) +,S(40eb693a,7cb938e3,a6b85010,6b7cd257,1de630b9,86da02a9,3b7a7f5a,a0a51ac1,27b875e0,14d3417d,cbc3b770,c4cb8805,c7ede7a4,efa9f89f,a51e36c3,af6d8d18) +,S(f7491902,54e30180,75365d67,5f2ddf24,ac0c9d84,df371fb8,6e94a9bd,7f81dad4,6a271b36,c549080f,dc9bf1b5,ad275d62,68af0cc7,2ec68c7c,17ac24cd,5c5a6e46) +,S(cf13261d,e4ce19da,14e6996c,97a23f8e,f16388ac,c364f2e3,6a053254,849f287e,5568858d,be1a7447,f7e4ab51,bb872a78,8218c483,c771ab7c,4a0a968,73adac10) +,S(9c6bda62,9dd087df,d5516606,62226847,94cfd517,72c72a81,7263c761,ad3e8cb3,2c77dc7b,9c7fca7e,bb35628e,d62ffc79,9e5fbcc5,e25bb0be,5b1b67a,10c0eb3) +,S(d8d1035f,64439dec,20ecc9a5,5b314959,c1526d7b,d15b1922,bb7ab7e5,b9d26bf3,ab7e34d6,ccfdfea3,f607f697,b941bbf7,b922a436,b9cb4314,3eb1b948,ccdbbe30) +,S(c6f40a23,b8227a60,de32e104,7080f087,7d53aea5,b00a22a9,39cbc228,d1c1d424,e16bc58f,cf4b8c5c,9106f1f4,b8b2374a,63a3136b,e5a8c64d,7fe6bd0b,c1d80345) +,S(3a69da22,9477d3a5,7147c2de,cce22de1,d1e007cd,61d22509,49400b8f,63a43536,c79c4fd5,c4ba6062,c7cc95e1,c9b79cfa,46b98cd7,389cbc39,25cc2fbe,49a0e284) +,S(1b5fb8e5,492fc48a,46b7f6fc,a658f218,814c3d82,90aa339b,7bc7b794,325fc9d,a6290b12,4c9e0819,2b6f49f4,c4935b01,d2ca4235,8efea982,1646fbe7,dc7fff39) +,S(fdba0f02,b004b4ea,dc9e1c37,d1a7fa7e,8a755922,31f054c7,47bbe8ec,349a3845,42da61c9,e96471c2,6fedefd7,e30c43c9,6c3c09d,d72d662a,e2b82022,391646fe) +,S(c39391bf,cb7b9662,be7279f7,6338988,7c166343,2faf1760,f38f0cb3,a35140df,ea14e034,53dc82cc,484b8b3f,ff79d81b,449f9f81,d7a52d66,4c5b563c,9af556e1) +,S(254ff13d,c716cb2a,1ac0e36c,c6cb20c4,19aedd0a,2219321,675e1744,859cbcb,2644cf3,916d26af,9e36bfe3,247f5be8,896e02cf,83eb3701,c400ad2b,92e35921) +,S(24e4aa60,e9b464ad,a2c8974e,98568026,1769d35d,aa7c8c5b,71c9f57,28930474,9df7c2d1,82a94fe0,80a2244b,ccc9406f,6ed37c38,d9cbaaf7,8d973538,e8479f8e) +,S(7ad9bbad,f906685c,3efd81b3,8599fc02,fb19a4c1,8bff1ef8,702c4f6,d17543a6,9878b970,9c4018a4,f713ac8f,d8a533dc,da45e243,44926df0,133aad64,c5246f95) +,S(97d8fcd9,383a8717,e0c9eb2d,f7dfbaa8,c6e08339,be5fa2b5,1d12565,62d8ae53,1879ca4c,f5784f86,7f8363e1,5d85afa7,b1f114ca,7f8f474c,4a2c028f,7c6a777) +,S(3e0fc785,5a08c32e,1e14d1a9,2c56ffac,2af1acef,505ed72c,b8771ddd,8afe7572,6d79b7fc,fd1e8894,f0844fc9,da30b555,bb1768f3,df15a0b5,884e5b09,6e149390) +,S(d9da17db,b132d864,1da3a9b5,389d6f5e,fda483e7,fc7577ec,55b7ecfb,65602562,80e471e4,5feb0d70,2ee7f9e6,3f8f23b0,33a4f35e,8a0841a7,b67f8c63,c623b70b) +,S(1848f766,afcd1e34,82935daa,7b71212b,f38e2853,9d6fb9ec,a3d9809b,6fca18f3,ca9a7882,645d54f2,49d35df6,3748ed94,5f9196f4,a93d4b7d,ee70f44d,b6f5884) +,S(ed3744ae,9a7dac76,5ad65b2d,4fc2d15f,1a9d0047,f72c6be0,a849ca04,497a9f2f,3cf76d2e,d4e5c6f7,e4b23d03,23c477ef,2fdc5248,7066ef36,b763444f,6ab5fb5b) +,S(c4607b73,edf3545a,b10a3a65,e0312707,91212acc,a86226b7,b1ccfefe,5f3676d7,31ad465b,8595f783,d5c0cd03,6230e3dd,2628ac9c,45dc6d77,28c42093,3d7eb3ec) +,S(1c0962ed,2aaf69d7,8b20af04,93a3fa50,bfb9ad1b,64eb0699,641e4b0a,bc0e96f0,49f11af6,e088e3a2,a429c5b0,a87a7f6a,591b5a60,a397c123,2d56a4a,adaede44) +,S(6a0476c,9a41959e,98dc6ca,fb7b4381,82250e1a,ae62445b,1f09a098,ddc19454,56842c97,8ae3c4c9,2c266cd3,7c8e3514,ab4288b9,ccc7e33f,be552ec6,f511c7e1) +,S(24da0f6,53a30aa0,a6b14999,329f03c6,cdb59a80,e9ca68f6,b9367830,a0191f1c,83e79080,aa78bcf5,b810683a,f061c614,cdbd3b69,9e200b53,d1a2c757,2c138235) +,S(6c3483,22479d07,f5871901,3264402,a078728f,227c75f,6f33743f,9a1a7764,a377af74,4a125408,6bf128d8,45bda458,be779210,f0d85bff,eb192c0b,a0dcc4c6) +,S(212aabbb,4d14cb26,b26cf249,882b36e1,1cdc26f4,a1494905,15478f99,d5c43baf,e9140a0a,81d1582b,98eed57d,7ba8e584,11c22ea3,fc265148,ca1d6050,3847e281) +,S(a27478f1,2afca20a,8d46824e,5b0ba272,f26ee0c4,24a951ed,f371425a,b343b10e,51e74b86,a7fc97aa,5a3bdecb,67818d7a,70ad0ba3,7c7cd759,8ec80a4b,bc4036a3) +,S(e1c1269a,7171f9eb,a2e2fa7e,8f55e0e2,b9b8a507,e8cdbfe5,716f711a,572e293,41cfa170,8953242,f98d8e24,2e827684,5562c4a7,6d034848,e639335c,32afba46) +,S(204d544c,19418e19,bb328e1,ecc0fbd8,62f0f78b,24208780,4d5827c0,f5e09efb,c66098e3,1f5d1587,10a3799c,b4f980c0,18cf4ed4,534e49f0,6d057059,93d52fb7) +,S(16eddf0a,11a6f2f2,df230de2,f78b4cf0,980138b2,3ab196ee,361486c5,7a5172ad,e3db358f,ed8ab3c1,9204a792,6102c420,1327bdb4,fb81718b,b39a0ce2,b5992684) +,S(7c9f7831,2298d96b,65e6b7c1,2315379,3df7001a,79cb080e,af6829d3,2b8995f1,2037cc3c,90e3a0f1,b242018f,c53cb32e,b2481dd1,bbb700e4,a6019546,edf51e5c) +,S(129c2d46,1dbeb8f6,c1b913a5,b2d69602,63aee7e9,530c6dee,21168b16,6198fb1c,29ffeeb9,61c027f9,a2a14b72,a287d566,7bbd80bf,7cea0dc1,747ac25f,55137964) +,S(8be2e565,30d4932e,f6d1f9da,a3225b52,de204927,e0633b12,570a049c,1f6175aa,364b4e87,1a130cd1,40007056,e3c0951f,fabfe4bd,6a687404,23cc1800,505510c8) +,S(40b43f08,42ae9c67,ab0ceb62,453b4c41,42a6e12e,5f880c5e,27c90997,6252fa6c,6d1ac6c5,de1b2e5b,b225e46f,2c5a2d2c,248f11fe,d123ecca,4432a04b,cea2068f) +,S(47e2238a,2f34df3,cf1caa55,93c49db5,4c2cba9b,e3724f17,87473a0,5ac669df,4d04cfa2,3ee255f,eca104a3,60a52f7c,acfc6127,608dd908,9399be82,9cf31f3a) +,S(17286c55,3a45c6da,b4843323,84c565d7,b3de474b,5df8ed60,7c7a5c9e,e1cfc35a,6172d347,75a45151,60b104b2,79543107,5b194d24,793340cf,6d8723c9,6320007f) +,S(3451af9d,3c1492ca,d090bd34,45632ac5,a3e96c9,4d9ed258,b7fb2042,8dd7bb31,dd493383,21236e06,e7284fd7,84c1a3b0,7687c513,927cc79a,cc5f8b41,b14974d6) +,S(b00aa481,eccc5e7f,cb5bee2d,a6e0ac44,ed9afa3a,5b2a9619,d23d0252,14e5ce2,687b486,1f0032ce,f42ceb7,441f81fa,10d732a9,e7e76242,4a2ca8fb,e88866a1) +,S(53ec8e9c,c75bc91f,f248a239,34d735b2,ef706d4,c0761e2f,a8a55c7e,a0b23311,1b11dfc0,63c4b1ed,1b5104e0,15d5c5a8,c352f54b,9fd82768,8b5104f6,45d45919) +,S(1ecde1b3,9c072c9a,3b3eddd8,d71e3383,2fc80d78,7abb70a4,cdc9186c,a5efab66,4f5aec7,5a799762,b70cecb1,82049cd0,239f0c30,948a25f3,daae0bc,ae6dd626) +,S(1fe2fc3,702b558c,7ab9b479,fa08efa5,1e90239d,677052e6,5afc8754,9bb1394e,f6b586ae,3a395d3a,c216df2b,66d48fe6,11a64c0c,8a7db26d,30fbd720,c6845c2c) +,S(b53d0b2f,b8ac2ad5,582ba0c2,f031c7b,76e64cc5,28a5b9ba,872718b1,e06d5dec,8984e589,51ab87aa,64bb034c,17d23252,4101577,9476887b,351f034e,92e3a289) +,S(54e516,3bc2366,673fe5d8,1f335d81,a06ca310,a2116ea7,bc0ade12,8f37cf95,f471c826,9deb2c2b,f1b7206d,6e817355,9236607a,4b9930b4,c5b3a781,7312bd4a) +,S(e7efb772,a1d423a2,d39e2224,4c8bab91,3b8087ac,65d51f59,8c4db283,67b29a7b,f2dfb586,31d08b0,bf2b47f4,17f6a18f,704a39a0,a152e3bd,587e45c7,93a9b6e7) +,S(5ec59daa,e8a263a8,2afb4309,79ef0321,b163f2a,dc083e67,3446b98,d0b519fe,2eab4cc3,6a3deae5,30dc6aab,94e5584f,a8a5316f,5c05b04e,84215ea8,79ef82b9) +,S(427b5cd9,20589dfb,dae975c8,efc1f098,1119f69,c40d1216,58ccb903,d4bb62f5,d055e6e3,b8794842,4162803c,35fca878,6500b5a3,6871b18,d9846866,56d1213d) +,S(54954b15,fc594f3d,8f422c7,9dd42cb8,2cc30dd8,c0d10736,554844ef,9d05bcad,86a7cc65,73569c20,2aff8e04,21a00e4a,9c6b88f5,ebcc3975,64b4734c,f735373a) +,S(ff6f8f8d,23670fbf,2a1aa7b3,39568653,573eb480,67a2a1f0,1b55a1e6,b1f32559,7a53f1a6,c7cabc57,d731552f,9fd9447,36cd33f4,3f8f57cd,2d4ac1dc,1ac7e218) +,S(74d725e9,9021c210,e82d852f,41e0cb8a,3bba8efb,8a01552b,8420c265,958a2381,4ee69646,aa9f70bb,883d6ca4,e1016dd9,92f18de6,26ca27c,aeb5854,f5bb2bb0) +,S(e9439f7e,fc0342c9,c2d68fbb,c58d85d9,feca0570,d77448d7,6d3c3251,e49c845b,27da0d98,1b7e257a,eee90b45,9d0d7065,566667e7,a9287592,2031be02,3e233916) +,S(9684a48d,81a60856,6dd26622,b3ffd133,5facb32,9f2c4f1e,2c055cb0,a5c0b911,92038ad2,50adfbaa,5d587c31,f5e7b4e7,294bbd25,e7af1816,1be3532b,f24e68b2) +,S(1d003af9,469e26e,c7f0f121,4dc58728,9e4cf837,5f9d19b4,16277c97,1a0e7609,99c7c3a5,30822c72,b31dad8,146d2604,ed795f1a,7c37e139,c84afe9e,f71e5123) +,S(f96468f8,73cfaab7,76c32fa5,89f72c09,d680abf,c601642d,1c649ca,e197a149,1ffb4bc4,8495d31,b24a7ff3,353857e3,b6708186,c18936e9,9793e4d4,fa083b1d) +,S(b6ad4106,e30294d2,bcac86a2,131150bf,d93c14f6,51ec65f5,32904412,b3f89d32,19a366a6,74279641,d055201c,c4c42b43,4fa40792,90c1c3ee,5db2a4e6,38d228ce) +,S(875472f7,190bf305,9120fec3,ebb69fb2,2d47828,6cb1c108,a977e7cf,e45b9b9a,1adeffc5,f5dc59ad,e15d163a,95f8049f,a172d8e,30544562,50a7898,55a97c21) +,S(5445a9fa,f4245414,e64f7ae2,a1cb1b1f,54bb6fd5,af4a7407,4d9eeb05,9a27a670,496c5207,7da2e082,3e48978c,a3fb7a1d,3bdf07ea,61fde94c,e87741c4,e9418018) +,S(dae18625,704bac88,51f35026,7856830f,74d3a8f9,7c1f662b,f4c4cc3d,7814d138,abc059fd,7ba90619,83988ee6,35ec835f,c20f62fb,c68e2bff,373bda91,3be6f87) +,S(8a088f12,e8523de5,c7ce659c,107e1929,3d009b81,1fe94d02,deeca893,9d9845c9,4251212a,fb8ebb76,5d2d703c,bc18b208,41f8df47,fc5e44ba,ef7b0f76,7e29114a) +,S(d78f46a8,8f3b08d1,334ed25c,78f57910,716755cf,2bceaf6e,c25b52e4,d7af6d01,eb1855f2,29cb2010,f20b3f01,9cbf1b2d,929046d3,242446ee,5c9526ef,5b06f44d) +,S(1e0b4312,78ae0e27,5e55c4ca,cfefcdd6,f589809c,6faaefa8,3ec0d5c5,f99b034b,f38c53c5,544d3ab4,2ebd74ed,b8348503,fb523fae,9d73657,8bba2881,904918a7) +,S(f03155b2,9edb119c,f411f14,4a588f34,ab02d7f7,c415638,cd534465,ed7cbbd1,72d153e3,ff4fff14,b41d07cd,31960565,31736749,7f9c6495,599d3f06,b8e85813) +,S(f61fd68,3edc7fb4,d14c84fe,3416654b,8df66578,6d0bab41,53a96e39,e5de4c8e,952db567,cf0913b1,885d6884,d260fe4e,e11fc139,f58da12f,d38472e3,d42e5f92) +,S(78310e7a,29e437b2,5cb00e3b,13a4d86e,1ede6d8,4b1f344d,7ee9c7f7,e017dd77,26ff358a,4d5629e0,4c20f700,97c202d4,7030bd3f,43134a51,a7d101b6,e182f2d2) +,S(63ae8c4d,6b7329cb,a61509c2,d0b61ebf,4e6ac94b,c8a096b9,7a4027e1,1f781a3a,a8e954cf,bf407857,d19629cb,338a93a1,af16c929,ef8b96ce,2e483e95,dcd14f88) +,S(948d592a,594b354e,e2d03961,6338574c,ae662f26,ff79afa9,16579725,7cca739,37ff98e2,5ea0396e,89d3992f,773bd6d5,ce02758a,4ee25557,edc867b,2f1876c) +,S(653cf16f,a3140368,50b04de1,8bfee880,660a4161,4dc67a55,398e2d34,46100f45,acaaaede,5ff1e552,6766741a,ee43105b,ea4d3419,3e615c36,49c1db35,125a9202) +,S(46fb6882,8a5edc8b,f24fd1ee,e6a7789,141e1888,64508d2a,f3c511ff,8e8cc782,9d4ae53f,d52ce9bd,6ac9ff4a,e82c2e36,f4d26698,47ec90cf,ef383e01,37fd8887) +,S(5f11a0c7,23ea2a71,7c1face2,b4b0f28a,4ca44208,7a2ae0ea,e24c2005,7138c0ed,5ecaec84,ad97612f,ba7925dd,f126e4e6,3906eacf,6f991d5,bb273316,b80c8452) +,S(b9f49e1c,929bef7a,6d6b6b3b,deb10890,dbf2ba3b,3eba62c0,320bdc84,c2a9039f,98729e76,7e4f8b7b,bd0ecc1c,534aa030,6e1b684c,6f42d15c,2bf6820c,b501e558) +,S(ec8a102,e7d2905f,f273eea7,6c9a4608,965dc2b0,3631d2dc,63c38e72,15ade2c3,d8c899e7,242d96cb,49383686,8f671612,706ffe5c,368ccb6d,be5a3edc,f74371c0) +,S(107f02b3,c351805a,6c92a3c7,742a5259,582c5b0,39cf6daf,cdace604,2be236c6,517236bf,1ab47601,57d74685,8dc724a7,c5c2d55e,82c4a3e,685f389c,a99bfb9f) +,S(f0fb14a1,a5c1c016,d7b8c1fe,a8317872,b10d637a,daf6f6cf,b9860653,56298971,e1d9ed14,d33e65d,4258e87c,7280001c,c40b89ff,b3164337,92fbc547,964540d1) +,S(a5371adb,ea784ede,f6cce83c,ebde068,78a1c80a,ff83b47a,333f9b35,44489459,f5780572,127f5d74,773acbe7,b2a22cbc,7e3d09bc,ccd13edd,48ece3f2,c8129224) +,S(3c031e5e,1b0ba576,13c10971,5fa7d92e,2bbbb817,9603d3b9,99e4fadf,be17300d,d275a3fb,392036dd,474e65a2,cd7b6cc4,79cb40d7,1c363e6b,bf9c272e,ae9c83f3) +,S(87b5899e,685db530,a0969a68,9392080d,f8a1b9ae,523ce18b,2171c69c,5a5318f,6ae3204,e3f0afa5,a2d40b01,a42e84d1,1b1166fa,f99cec08,1f5af48f,fda775d4) +,S(d9f077dd,c002c16d,f9d8eedb,56b7e7b1,ea00d04e,3fe838dd,2ae40501,9b8bf74,6518d51e,503118e2,53cfc486,f70cb9ee,11c27302,ee5512f2,78f21265,af3ffeaf) +,S(9c09ab63,8d15acc9,609ce305,32277f63,7558a492,aefb98e,c9bc721c,f8921af7,b2cac58d,535abc10,8bed6ab3,165225f1,bf2f84a,9fbdf3d9,1caa4b79,e0f6fc) +,S(6ed1ef8b,4c2d9232,5cf8948a,5c369a24,52ab250d,ed0e48ae,1676dc73,9a8a7fc0,c1b7a08c,2cfe5154,fca74136,863da75a,5c6423bc,1c904585,f54ac87e,f6742008) +,S(882e8d70,154b7f6c,279f71c1,e2ba6087,cfc458a9,3079d8f1,3fbd3be2,506928d1,8949b22e,97c41872,9094ac62,e67ac1f2,8b31565,edbb3d1d,9b23a73a,6fe64131) +,S(708472a0,24c86ea0,7119d0af,b2509814,516840e9,fc23246a,a6da139f,b37aba52,9809b7a5,1d551532,a5b378d6,594a3665,3a8b057b,80cd530d,b7a53fbb,128fe5ac) +,S(3a44fad5,9a8b708,4ada1250,d8d08353,769d573d,71a225eb,d87a8cc3,af9fac3e,f29f4551,1250d0d0,a1974bf8,46124813,f9186e45,2d3c5c85,cb0c69fb,4b7f20cd) +,S(a3519dd8,e09e1bd4,160564c0,41c23362,36ba4c84,5899f90a,fcc370b3,cdfb9f30,64cff159,7c910711,d0199faa,6c74d08e,7150088e,34fce674,72dd3ec6,1b881d7e) +,S(5af16ce3,765f5c96,4eb3513f,19d99ff2,bea1affa,d68f829,1c4f0767,5cfcf1dc,864eb5,3bd711ed,4a842db6,b0164a78,511ff7b8,a87aa3dc,1f2402eb,a3815daa) +,S(1ff9a522,19cae5c2,5de1ec08,2641040,18848bd1,37a5949b,4021c2d0,563d54a8,546d634c,122276e1,b5cfb919,a5374309,8f85d7dc,149b14d4,791c83b0,1718e031) +,S(d7a6dcad,72a51ed8,f84926eb,cfab368c,7f02fcdc,aa66482a,c6b6dd6f,43d3e938,9a273cd6,3ea6ac86,5a68f378,e4466ae9,8598a058,6c97278,bde63b22,14e41c96) +,S(154f63e5,5bdccc7d,a696dfb5,2b6cd4c6,3c874b93,1f221282,3f4a8d19,1f32d797,e98f9722,17bca1c8,ea7269b0,d2aa6bc6,f0f29d7d,b340c67a,2df59135,77f76fae) +,S(f6ade08b,8513615c,ccd29095,c21bbdea,dbdbb7da,87ce9991,c27ec758,4c399bf1,98c81be0,19fccaba,131af074,b28a6311,3fc1c5ca,1318e96a,f037ad33,8f234ad1) +,S(9661cec0,3b2715f6,c6d29048,65fec2bc,b786b3f6,943a883a,3e51cb2c,c747637e,eaa1f7d9,9b34104b,74a8056a,9ec739f,cb9c3735,95f0b254,7fe75620,4f5358bf) +,S(e0a5323a,27d608c7,34c03465,f03705c3,480520cc,f5ac777f,53d498b4,655d19a1,1f727d78,a8b8c562,ebc60679,8462975f,63d88eb5,8e7cbaee,836bd629,260cc606) +,S(bab82efd,4646f2,f281980d,5250c6af,8206e95,dece4118,c24ce31d,282f6409,2a60b1dc,26a20126,8df8375a,5656c55f,cafbdbbb,46b7977d,137cd584,8d1fb82a) +,S(389e1399,ebbe958b,1806e9b3,ee51baef,2d7edd20,79e6a2c2,21e814ad,e1eb2631,6c158633,1f3cfe45,9e71fb4d,112a624c,e48adabd,435e6fd5,2c9459f6,ce9ae2be) +,S(b78179ca,c0dc553d,19f08174,7fa4511d,87d8961,1ba44045,8c307727,729d4515,7020be98,c496a50,6e4caa5a,94577d71,ce0a80c9,bb974c97,a6892351,e83e0de2) +,S(867ecd3d,d170f9a7,123d13fc,fd90058e,baa6a6f4,12ecadc9,f1e14d55,ff104306,3c0db3e1,bb91ee23,8fb27689,79f2b543,d698c5e2,fde48dc9,e2535e4a,946759bb) +,S(be71654c,26a1025d,41fd4d08,384b2ccb,db25bb2b,c15704e5,697be2f6,d4eecd38,316ed20f,c37a2dc7,a0af8d18,e4da0efd,2dcdaee4,44b2c1df,cdfaf6af,49406afa) +,S(5a8e1cb0,24d62685,e755b9a2,ad1e0165,41690544,7963dfda,6b6deba9,76e9079c,4c793173,743330de,7a8f4351,68dde95e,3889db2a,91de0a27,d088a222,f11ebba7) +,S(3bfad00b,2347bd0c,f13a761a,d0630453,bb884d0f,ae3d31f8,57216412,b82e6131,ef33c560,94157fec,3f7fe8e6,36d48183,71e3cbab,6f5b0518,96ebdb42,aa545f61) +,S(2447ede,684dce09,c896c2d2,b5c68cb7,60e02635,3b4f2dc7,428191ef,5d2c1961,ad38a82f,e80f860b,62b39e55,44438242,5ad6cb54,d6e7f377,62427f30,1ef7bfcb) +,S(a5eae321,eeb4b9f8,e8807e49,ba8de764,e7685f07,417c5239,9d857d4,8bcf985d,2acf8aa9,f5c1b7d3,2ad5f523,39e65595,17881d,48a7696e,ed3b1023,ab4def1d) +,S(97de995c,5337d938,3cca5b97,3ab05e8f,dc035e11,5c435251,7e575a,e890b13c,4fb2d969,2e308a29,34c3fb4d,c4dcef50,9202505b,cd891f79,e8f91210,e069e6dd) +,S(b8caf25f,a864918a,f803dad8,d0abdf95,25b70f44,546b1f3c,c6b1726c,4438f479,7c51b5fa,c0f56eb3,6ffa8c5a,76c074a,c30e2f36,b069ed79,23663da,c9c05c9) +,S(b5bc868c,1b96e2a1,b24f3001,af140107,b2cade8a,5b1f3443,44521764,ad07b2e6,8d6cfe29,4e929f33,d5aaa456,f545c33b,672a8c07,b214a6f2,38bba367,4938d639) +,S(5f51587c,242a3b22,10db666b,f2414c28,32ea2662,1f13f6e9,784a8a1,373ff602,2c3b260f,ebf20a4e,b853950f,99ccbb9f,1b39418a,66adb427,f5886944,8b46c858) +,S(1d0be0f9,5009a2b5,12a52e17,e044f3f7,4f08e695,60d0dfeb,822b4674,7a2bcfde,c3a82bc3,dbd81877,3783181c,f7b81ddb,a742c3b2,4f866538,9335ce4d,8f3a159b) +,S(3ef0ec28,b8003331,a6621bcd,6ce30ed2,9e0e62d5,b492592c,cecaf4bc,8d22fb8a,fe2c84ad,77d40e86,c92a03da,e43cc7f7,512fd363,98db0133,7d929ba7,a144b16d) +,S(84c29a24,a4ec04da,c76bef42,732a3648,f62f12b0,e7f0ead3,2ef9649,b7555fc5,e7620ebb,283a54a7,10eb454c,f22e49fb,929ec453,38e457ec,b18a7f0a,794f970e) +,S(6bba6634,e75d5fe9,21f40f4e,5f1c177b,a309cd73,107f1e9,28331573,eacf43a8,33ffe08c,42168243,1f086b44,12209c56,5b47fdea,54671a97,9d86be36,fb421582) +,S(13b67af0,51b0c01b,c49a6046,d9e5b6ea,488f6298,9559dbfa,47cf1674,6def0150,d0e8914b,1c1bf0b,5337cc35,d84acacb,a54add59,2321509e,e29f1d93,a0237608) +,S(161221bf,b5dcb62a,ebeabc94,6ccc4a26,fdf779cb,63640720,2c5cf13e,93af9300,d3fde2c5,dd9d6df8,70a66bd3,2b5213c,d1a212db,61aec7b7,2a49b7e9,2cf83b2c) +,S(30c5360c,c62f5846,3af60277,2b52201,7eda1fbf,866dc3d3,9a590bf8,e2eb508b,c8e91af5,9b9a2b,8837dbe8,edeac615,6c30e8c0,1b7679f0,1aab4a81,cac44efe) +,S(c0659a7f,dd9151f5,ea67f38b,7249727e,640364f0,87371007,a38b800b,ec3576,a6f648cb,6fa131c3,5458b5a7,77440361,8c57faae,1ca33ded,648f1601,a5cf47e3) +,S(3215224d,b795a892,446472a,8e1ab1cb,7d50fe95,a6844be,43e2787f,2679386,25750662,97f28d86,690c7eb5,92cffc5f,faba831b,efc3e38c,c5e501f9,358a9bf0) +,S(257654e2,a87a7048,3bd15445,da5c554f,fe776264,998975b3,b19a68a1,a1871145,fcb9319d,c67f14f,9d7fc4ee,fca05b18,9efe2430,96691043,9c28c88d,32636ec5) +,S(a4786a01,e504f154,f3d7926e,6e6908a8,17c8a66d,6db33e80,ce98b17,82f1b49,576e4d42,fc2e4f9f,e81a2967,8b7cfa7a,7f86e8e2,662afbfd,b028612,d323a2fc) +,S(5140f7a9,260c9856,4493ae62,a8af369c,90b484f7,e82e1e38,3c5a59a6,62db1e71,4e5172c2,b0879dfb,63a6aa92,cebf9153,94ddcdc0,985261fe,2f64714d,350bae86) +,S(f559d60c,f0f50b7,9c7d6d90,18a579d7,b781fe13,5210d342,31e6cf32,4ca66dfc,12d9ceae,8e5852a5,ca95fb56,abda8e42,5f1f05dc,ca29e08e,2052bab0,8d4eed15) +,S(88907ff5,fa2d01b,c970e0be,53a05354,a4fb73df,9a337857,cc869a1,b0547e7c,f5853b56,cc1211b6,427145f2,6fca6aaa,5b26401b,c00db73d,ab9157b9,7fa3d2f5) +,S(cc1e4bf6,4541506d,8e91fba3,1e1d8ffb,c8ac82f2,4def27ec,fe4b3ea6,e58c45ca,7617497d,a875183c,684585a6,306956d,1efcf1db,2753fb77,5902a63f,38d27592) +,S(7ee2c437,ef744210,5b6a6f9e,f1edde01,6c39557c,93454dd4,eca10daa,cbca99d5,21754734,5eeff5d9,f30503f6,9515da57,3e6d7b70,dbdee5b1,8274968f,6f3772d6) +,S(72feea2,39f9b4a9,a3f3af3e,f6bf420c,3605ba4b,b42da90f,6539e05e,33e2465c,a036ff,df7adedd,c8c2ad9a,d029428c,85482cd1,6b0cd20a,36d2aed9,e9f553cc) +,S(363da33e,94a0dd00,669b627c,4d7a3a6f,c8a0cbae,2641707c,938c8f5e,99914a,9bda9a77,ef1307a4,e236099,c1506f47,a2f936dc,d478b59c,3d0e98c0,7af58bd9) +,S(76540864,c8394290,9af4a48b,bbe05fdf,93af0f8d,1ec9b6e1,a7e91860,f2c133fe,f06923d7,738ceb02,2213a236,daf3d6f1,b3cc98f5,a5ed4845,83ce5c3e,54a3ecc2) +,S(573f0821,7a318a9f,8bd945c1,62e9a4a2,51e38189,34709606,c94cb401,f2b239c4,7e78e4f2,7de69e4b,948b105f,ec3ebd14,496cc128,d7c73fbe,7ca1d53a,b746bef5) +,S(8537981,89234b93,b5009656,f57e5ed6,f90d2184,819a5467,213a934e,22b01f5f,c94a79e8,cc990998,e1c69bbe,89ccefa2,9281fc0e,c99fa820,ed26f01f,62e475f8) +,S(53388512,29890336,3b1ccd4c,1cf0ed85,6f00a30c,78004512,57f6132c,edeb6041,d56e2a52,f856d1b9,a4f8feac,dbc9a844,dd22f55,469bf722,fd78b44b,6983334e) +,S(41ede48a,750ef7b6,5c49f913,afb98961,c5cb478c,39c4c85,2f33aaae,b0e4796d,d74c7bf9,4b6c4680,18892ea7,f04b53c9,4bdfe9c,d1a4c65b,8de2409c,32559de4) +,S(97e931f3,6596f736,992eece4,eed6a9df,fe762139,3acffeef,b6dd3b53,e5f08148,3da89933,53b9c52a,9e76ce7,7404fba4,39a24614,b62d42c0,9b660e2a,14dd5f1b) +,S(4caf4eea,3ca8b104,39847633,5252b37b,5c55b664,cc4979a5,4db00937,b222579d,c266732,a93bdc0,7cf88580,771d58a3,45a19100,4c0d1464,62171cd6,291607bb) +,S(857c1e90,5b3483c3,3ab24ee4,e51e3839,b52960f8,21a8706b,b7ea7c84,9e7b1ca4,8d6e9d0c,7a578771,b358380c,4a2e6bc5,1c6b09fd,e9b40c01,be5915ba,fe69dd80) +,S(410ef70b,e0dbf7ad,a68fc124,8dcba3cb,10ec39a4,9686b22c,1e7ed2c1,bcb5a182,d26e9ea3,331a56f5,cef074ae,e0b4a5c0,e6925d79,808ffdb3,b7cb9423,247f9e94) +,S(8caf87a8,c831eb10,817e5ec3,7aa431a,89dff6f9,a7e63f7a,30710419,5751029f,3f0bd6e1,c8dda6c3,c8e65ba0,7c3a4649,13aad207,3c5da058,bfe90872,67c8890a) +,S(eedee2cf,e92d2483,54a6a8a3,9d314fb1,b35ca18b,ffb9b779,8c16d5fa,fef10e8e,cb515ab0,21f0befe,4b31181f,3f9ce1dc,9fcd12c9,6793d624,c1eb35aa,e514c4c3) +,S(8cbf7ac7,1e77b7f7,7bad6a4e,9116db52,48bb2a75,744d4312,f02eecaf,2aebcee1,765c4b31,f67b26b5,3d17f97c,30d09636,b6f6697f,db6b799,169a2c05,779b7320) +,S(70cd45b4,cd449aaf,34ff0627,f0e01122,715dc6cb,98642dfc,c19fc672,54995db2,82e59456,761497b1,84320eac,3ada16c6,ee184ad9,10b60c41,20f0c538,2f535c8e) +,S(cfe217f9,783fcfd9,1e79d558,e37bec3f,50e5146,e0f442ea,702fdfb,6c7c45d5,537cbd0e,86453fbf,c57d70d8,78c7c3ac,da225186,17bb4dfc,7b6f7079,95c419d5) +,S(9826c0df,6486bb8e,2bf3d4f7,4cfafa71,ccabd2cb,12bf317e,651790f,48579d52,3dbf3586,f86d6253,d3749c05,2fc36d16,ae3bb457,8d4eeda7,34f172dd,b9c57342) +,S(ea18fcef,381b4bc2,c6b3fa3e,3744e9c4,a13e13df,576c8e74,d0f4f596,e28a02c4,c3e6bf9d,2bc445d7,87103c7f,e595a30a,41c9aa4,c41d1874,d7ffe69f,ee09f397) +,S(6de2c465,c09d5a54,61c618be,c9c16ffa,21b82e5d,673033a0,e88cf90c,fe6d8f4a,367acbd2,8950882b,428a8199,d3b21f5b,e1c4ccb0,3280bf5d,28b65cf2,bc4ee2ba) +,S(d6286e13,ee10c7d4,5ae50f80,3d1a5417,cecc9c68,9efd2847,6ffa73f,1a183f4e,7ab92bb7,55204e89,c7e3ca41,1c829e41,e965ab93,57db88ad,37f13e93,6aa56f56) +,S(7526e6fa,ea67460a,25525962,fdb6f209,73f0c861,ef3c364d,fce83df7,23c3bf58,2c76a8e0,d5a8611b,d3274411,cb323751,25a21fac,12e35ae8,f008f48c,18e3a674) +,S(fccaaada,56d64a3d,6d1d5d89,719f51f6,e737c803,893e8b2a,b785070f,8879308d,8262c566,3facf792,efd750ef,a969fab9,a2ee95d3,fe6e7d7d,8685c6a8,479362d1) +,S(b60d13b8,eb8a5f43,cc448379,7a397847,bd6d91a8,b3a6888a,fef4b115,59b57fe3,abf73ebe,5d2b8585,76104acb,ec885f1f,8405b053,3755b8ae,94ecf838,60ebaa54) +,S(332d4b0f,4a0dd872,ffd6d2c1,4379f925,4250fd66,dfaa2d90,127e6ce8,c377f8be,37f3143,47c2350b,f4333d7d,9e0b17eb,110dfacd,d87ce354,b7887cf3,1bc6232b) +,S(e99b2ee6,2ce6d633,1e0e880,37bd138e,5d021620,b555b94e,52def87b,4cc5788f,c9ea06fe,dabcca9f,6df1df26,8bb3e550,e2858dc2,b91a7c6d,2c048416,4e5546bc) +,S(89ead438,2a977aee,7fe692a1,d7199bdc,5af24191,e80573b1,dfb056dc,49c54353,b572ddce,db2d776c,2a967f70,6b7010ad,7fec43b,ebe5f19c,2de0f9af,d9994ece) +,S(cdad98e,529b413f,b46f6fa,98c74058,4777baff,b090d488,59587b4e,d598268f,d405a95e,543e639,470f10db,821f8786,ceabc281,788b0cac,3efee830,bfed034e) +,S(5096ef41,1cc1332b,e67f69ad,3cc3140a,c269849d,5e0f4f5b,e41290e4,86ee2cc3,7f33869f,ccd4b06b,ed61f312,30a7b3f1,49ef34a6,f2d46bb4,18c45343,73f8268a) +,S(bc0bea70,a0966734,8607253a,2c8be987,8c4d59ed,638ecdbb,8b9f60e2,a4a5be61,e19111ac,3c2b4e0b,4a86129,e6c4c275,54d1ff0,29ddf320,873e20cd,16873b78) +,S(2d166569,ac8f5a08,e0674d3,8aa7d747,b024bb8a,5c8407a7,dc451403,87223ec1,48af1b38,62216a5f,12a7d92d,4eec4e59,445c1587,e22238f7,3dd1bd77,e19a597a) +,S(b8cbcfae,bb8b1150,ddce37b3,26ec77b5,2947cddf,e3cf1d40,f27e8b7f,8145ba30,d5234cab,8b2ad2dc,8630ec02,2868a1e8,ffc2c3fb,cd5f5a05,62b6fddb,34823ca4) +,S(fb396092,563f12f4,ddddb9c0,f1ac19d9,fb2e3ebe,608eea22,7a9aaec6,dc960ee7,65e565df,fda1a394,3d27f661,c2eb01e9,646e88bb,6943953,58c9e62e,c9823c45) +,S(1c6e9d76,b8dcdfa,90625150,db2274b2,f8da06ee,21000225,80affa54,a414b297,706b450d,9ab0b0,5466edcb,bbed8b10,85679fb9,78d74057,607bc2ef,a5666255) +,S(2e043dc1,46ecff0e,6e566b13,d985cecb,77f55a0d,555e0277,dc660351,b9fca1c3,1c4f1ca,f75ceaf0,a051103b,90a7abf,665da500,2aac4e14,28a71e45,726d8398) +,S(5ae17b0c,a1bf8e90,e663ee12,d97d7855,9549f9ee,2d89592c,b4b0bc9a,585f482f,bb0df734,931700bc,73c6966c,1e8e5a77,a71806ad,88d731c7,16f236bc,b4fc8111) +,S(fa8bf342,6a24c3e5,d3c11c46,e75eda94,fca910df,c906a71c,1b08f468,a7caafc4,ca69817c,db07fbd9,e35e6c84,65b3cf05,4e2884f9,e57c0043,5dcada4c,2f5954e2) +,S(2cdff1c1,846dd7f7,b9df67ae,a3f4394d,1e1031b5,de7083cb,f905afb,991a88a4,4bbd724f,3827e42b,7d0530fe,de304711,6ea0d88f,8e564d3b,507ff3e2,ef76f39e) +,S(6fadbc00,55ca49ec,afdf82b2,96504f89,c5bb8291,ca942df9,5f5b3322,9d3b6905,f7671184,33a8326,a56f9472,8c411917,911a3053,f593e868,c06f57ef,54b7df62) +,S(c514695a,2f26aa40,dceb15f5,5d5ea8d2,6f4a1e06,12591fca,2f5a00e4,b8dd0841,5056ba08,2e78b06a,90937567,73fc4ef1,652905b1,16d8fa6e,8005283a,b113266c) +,S(83dcb8d4,93474f85,54c368dd,3e188c11,aad758ee,fdd1f064,66c11e16,cb7ff933,104e5b3d,4e57192,7c67a029,e119e79f,d6ed6fb,e61e288,e9f8bd84,630a53c7) +,S(bc65cf8a,cf9a0b26,43b69089,565f9a9,5f9ae882,2e2b1127,a8bcabb1,fcc8a93f,fdf9716b,a31ddd06,a080ac90,f6699b78,23ff28c1,155a79c3,ae9c292a,14fb2143) +,S(48778fa9,520b12a4,12d74b47,65ad37a2,695e37d6,4070d53c,1e09cbd2,4c9f140b,cdc64805,bec15940,387b4c02,bc51b469,446dd3c5,b2e35b39,fbeca21d,769c373e) +,S(9db2c42c,6a735886,8edc8831,2ed6873f,28077bb5,32d186e8,41f67ddf,a301dc25,e01cb235,ec9db45e,e1193e06,46a325b0,aa0ac5d4,786d0ac8,56990262,bfb3a0dc) +,S(cbcff58f,62bf025a,43a1ef44,256b27ff,37c6c8f,2496d2ae,fb280734,9cf8da6b,4fd99ed5,2da32753,3a9251f,e1e136bd,28f5331b,c1101da2,818de6e5,3bb1896d) +,S(9d520b97,87e68c45,817a12a2,93b1df96,70cbcf3,91788270,93367253,6f4f3639,615e115d,2b539895,d91885ca,a325625,41fec07,9d8fb6bb,22d9ecef,b6bc0f14) +,S(c648ddc4,57c2bc,bc23d182,8cc6d6e,4b0bfd3d,f83b2e7b,3ef6a341,9225dbbd,ac9a863,38dd1966,9bb47e99,e67a3d9d,ec16fe61,dc17ecaf,209a7fbc,518ab3d8) +,S(ae11f835,ea96f767,afde3f1e,79221dee,b80ead29,7b45e29a,7e596461,e82137dc,20453bec,b65a62f2,8996e1b5,f1953acb,4c5dfee5,4e5f9a15,c2a2178e,4c452596) +,S(a35549ad,56f8a64d,d23b9293,d8ef5128,699f6fe,365c0fec,29280d0,a364d46f,c84041cb,a38c9981,3015ffce,17ffece0,8f55a292,3c64868,f11cd6e1,bfbbe75) +,S(75877029,af5575e1,8dbfaef,37dac89a,2aad8308,d473a64,9c347097,e35f8077,843b0497,d19851bb,ed243762,177cc69,603cd674,216cd65b,2e5a85cf,5fc2b8b6) +,S(44ee3168,ca7ffd50,c467b1f6,83e532c1,ae00b9e9,f2eb1ca,917607fb,32d4ea99,10a20ea8,120b5a13,beda9f9a,9110eef,22564e3,9b96c141,1e73eb7f,c92c3270) +,S(9a013c89,8dafaf0b,90678f92,f3bb98c9,461e4595,42cb07d6,477b6f66,7a5337d4,11f8485a,c96623a4,e6c9b773,f5cd9fcb,fec396f1,ff53205e,8774ba1f,da3c2a73) +,S(b45e28a1,44d54182,20819a61,5f50b349,3fa12d17,2b8b5bea,83e73d69,b6b47d5c,d987db83,ccdacd21,dfff1dec,43997253,fb1c2092,95bcae4,5b76c306,92c29f4b) +,S(9e7d6a53,49845888,a8865d07,310192f8,9a659205,1d2a603,cdc03d35,a641a0c9,ca1774ed,ace29fa7,f57e5690,b4d1c0b2,ce5f1fbc,b21fb323,3c001498,54f462d9) +,S(113a1429,be1b613c,567b306d,5805c163,e433a940,8ef14b01,b9afea43,54991f47,225ee5fa,6d26cbb8,49191ec1,a51e385c,321e801,9152a3c7,50014567,7b928697) +,S(32ec8dd1,2cf85df,931e2597,f6b005e9,6d6eb0a6,d0dd7964,77655d71,418d9181,fd718dd0,78b3e4a5,9bef7f4d,9c430764,3423bc05,e1aa22ab,dd7bbb,aff9d8b9) +,S(ada43267,f2cedae4,5e1a5f1,46151f89,b145db70,ef477865,b1218e91,72e9246e,d148bee0,4d1f4d29,f9f15c57,8b047469,16e39686,c2b2ca54,1f3e0d4b,247cf82c) +,S(818a0abe,debd74a6,91fe662b,edba1a52,65f5ca07,2017c6bb,bf7b9847,95bf0cbe,e7b2d06a,1872c73,6988da9b,ce273b7b,ac0f03b,90903bc8,da719ce3,89c0a53) +,S(2f49eb55,ef77da10,804c1a1b,f596f09e,ae76026d,f2d12f14,d80be810,7d0b3c94,6a225810,2f1118,eb689aa1,e6d4ced1,1a79036b,802caffa,5694e383,3e038b83) +,S(7fe54d70,54cb025f,6bef8029,bedbd15e,bf66d5c7,986c678b,a5cc5353,7afaf74a,fdc617ec,72ac6632,6d16afb6,69188554,a47a82fd,db757695,2296c10,b4ad89b0) +,S(84f59366,2b8284a0,c9db8675,db9c55d7,411ec9ba,deec1319,56aa3f75,8eed2689,836e65d9,6bef6ed7,825119c4,c4511c89,48042592,f41eddfe,4de98e83,acd0d88) +,S(c90aa830,1a84820d,e06eb6b7,1ccc9bfc,a46b1612,5e2b5f52,da0a6fb5,4185ee1b,ea86d7c0,b285d82,9331e05c,d99c58a1,cc213449,d9226efb,16135237,f90dc8df) +,S(ffb4d576,abae49be,69f047ef,636142a9,8669b2ad,9cfdcadd,c057d96e,192ef100,3740cd14,b2d5e018,33a700e4,c80f6a8d,3d95966d,a5238120,80a9101b,b7ec6c7a) +,S(408a8d89,67ad6bcc,eb7ebb61,89afefff,12c24b5d,2c33ca3c,8b78fca,cd403de0,3b761fa6,378cc42e,a28fb66f,f1d8171d,4acd3557,fd6313a2,cdcbce47,e1caecf3) +,S(580a33f6,153109db,fdde27e3,f1b0ab04,6c80c04f,18326712,3e3482e8,7c53b787,bb8073c3,fddc81e0,e99ac5ae,69702ff6,f70a33a3,5639add8,1d353c0,e428431a) +,S(2d310a94,7054ccca,c46b1100,88349ad1,4c7860db,38c698c2,505e789f,8344130f,1ea2069c,3c6ec90e,9c11be0a,913d90e,2df1875a,2e26aa9a,5d28dc81,3e3db697) +,S(2874282b,e7b11cad,3f22f2e3,ab835aed,5d82b424,24697b32,985231f8,6a7aa450,286332d,b2e1b922,222e3860,e41d90ba,cf39ce03,21f26b74,cfa23171,f0415c42) +,S(af9e779f,f77bf3a0,10af5e41,82b77981,6940f85b,9530eea4,8b36e401,eb6231cf,9d3d4350,dbaf15c9,269d958b,86d6b88f,4deb7083,ab1ff389,c13f7541,98e84c67) +,S(445edb8d,515ca735,26fd2757,73b2778c,bc93ad8c,a661b35,4471d035,688c1ef3,94917a3c,fde762f8,3b774361,1f36a13e,e94b759a,455382f5,55d64f25,7090dc49) +,S(e010c20a,370d5306,f89993c,f7ec34d1,3e76feba,2b6612aa,dc75012,701811b4,cb45172d,280d9be0,52d57a21,4cb3cc47,798a6426,f215e3ce,e3af64ff,106fd8af) +,S(d34277ca,4625c7e5,b1134080,cfb44cd2,ef548b3b,67bb73f9,eed42352,ae5af8f9,a35f5779,7a628f7e,bb37bd60,9e3f44ee,c391909a,ce27ab44,1ece58c8,d7e4a4df) +,S(be0b9399,3bd54241,b684977f,ea4733e3,d96182c3,c9fb1c5d,d665eeca,cb1d628d,37904353,744ed26a,df76272,8ec41898,13218b0f,5fb09da,dbf5be84,fb7fdb8) +,S(308295f1,ed4a21e9,1ed9f48f,d6b42829,edd9bd34,e812f09d,c3b2c319,fd8f3980,6835c34d,5c360e1a,49a14c31,4ee4cca3,797d434,897c4181,a8ba5d7e,aeac0230) +,S(66cfeb51,61aa879d,fd791604,e10f5fa5,c2e07a5e,66a37b41,2b88db32,dc495b1a,a0e07a9b,f8a2fc01,3e229602,b483bc26,5ffba9c5,fb6ebfe3,f9ff9c9b,3252a1e1) +,S(f42b8fb,849cea70,4cfb3d9d,334a4a11,bf7b3aef,9b55f648,ec885a2d,6fe39ba4,b60621e2,a36d4aff,9f75db65,dd381ae1,f5b0fb4a,bc9f19a7,36d160a,61e8b22f) +,S(429c1785,22906323,2ecfdc46,2666f8f4,c57b7fda,608cc8e3,85a31254,bfab034f,e190ba59,1a868f57,40bbfcb0,481aa04e,50b3969e,abc941f1,8e69816b,2962af35) +,S(c8939d7c,94789a0c,b95e4237,fb378ee4,9895b985,6fc67d7d,fafdf7b8,debf611,143aff62,6e94617,c36d05e2,3062d2d4,47feb77e,9b15e2b0,4370f81f,1cad3682) +,S(5e4155bf,56303243,24e15ae4,142ad81e,2b82aeb7,8dc3ccfb,1d36f3cc,4398ef94,6801f527,2325a3b9,a9f3807f,216d7425,b9083364,203f3b75,ed6f4ff5,eb5da55a) +,S(1196b198,53f093be,7bbfa851,a7114e23,eb01c530,6078965b,5e9dbd3f,8d1b573,794cf0,54bfee20,d80dea44,d183db44,fe79dced,fef0a97e,5c557fd2,bc628795) +,S(d818d920,74bb737b,7db8fcd0,168030e3,39803e5f,6b76ba1d,ea836ed2,c73a6094,6ac7dbb5,1f63118a,80cd2aac,fb5f086e,ff15d51b,fb4ccafe,9d96f179,176e504) +,S(c0276b4b,f5ccabe9,ed9a433e,eae5c989,7039042d,b273ed88,51db464f,b06c6204,489270ae,6349ac81,d481a582,a8581520,972593d4,9b3facc5,fd52efca,24f4756b) +,S(94b2a1c,ca23cd30,eb9b300b,43d0b24a,b898906,1c4d8a7a,d3343d7,cdd83307,47c5ed56,b709bdca,5b960801,58338b9e,e6e74683,99a50640,6075302f,9e481df1) +,S(f2aee379,df2bf54e,e4a1c385,c28fb64,9f157d2b,d345995a,66868876,ae7d5108,ae766bae,9c90a1f9,c9079d35,1676eefb,19a7bf8f,bd56a311,13f2dd56,35c8ef08) +,S(fc8fe44f,3dbdc4b2,afa9cd04,3601c6a9,e81e4da0,456ce222,8306bb85,ba9833ad,6a321b78,a98f52d7,64330a52,ea5082b9,2b07655e,ce8c5094,ce307538,6d56fe15) +,S(d38cdd79,19a4f3cb,fbdaa3eb,e2ddc10d,7444d04b,5830eb7c,5b8b464e,4c255c14,6a0f1ef1,823a2fdb,94a311fe,cdaebe7,e1904095,1ddaae6f,1a565551,2c8c15fa) +,S(ac02e6f6,13d8690,d0c71943,a26b5e9f,916ea119,d7773f4c,14247538,9a4b41f,eadc499e,436b4eab,bed9c5e7,68fd2f67,72659819,437708f3,99531ba6,c05ea2b1) +,S(3948b1a,c36bd462,ac7b5cd0,7076f9ce,dc6d1a75,1ff65177,d7d9b701,d06419c8,ca91fceb,a01c03c7,ab141ea7,1cceb61f,72d5d18e,77964bd2,732bb95d,191765ba) +,S(4c7dbc8d,21d600da,6dd4c0c2,cffd8842,ea9e73d0,5dbcb554,35e31971,7e706e9a,86a77f44,b87b7abd,29c2f412,97f7e859,6db46ebd,8cdb442d,35dc17f5,278230fe) +,S(75228daa,b3825e2d,9f8c2f7,a0743b0d,b7dec731,d9df5e06,98ee11e4,8244f623,963c2987,e122f107,dba37bdf,ed282ea4,75e33665,260a5aa4,51021a88,780a1676) +,S(aa3a86b3,2ed2161f,8f6ea92c,71b7a47a,b584a73f,102c0147,632d2c2b,e80a579,b8fe249d,2b4ec64f,dd345d3,210244d7,f7e517ff,7722c2ab,bc4601ad,ae4e6cb7) +,S(702b912d,9828039d,a58b992f,7d6f3af9,4c03227d,3d3c368a,bcfd3164,193f22f7,25892c49,3a32cd78,130a4e14,c714cc7e,b576ccba,396ad36f,71de5c42,c6bac387) +,S(4ca10c88,6d44bfa6,2a221dfc,10c57011,269f703b,8f6f3567,829d3b5c,9c90ba75,3323eab2,9282e358,d4de6f27,72d77db3,95b04a22,7f0374b9,dac3ecfb,4ffde3e7) +,S(1619ea36,30da6972,2caa436,2c174efc,f3601c35,2e946d34,2da56738,92b9c325,22ad140e,13b8679e,a6d88dd6,148ded7b,a1c12697,91c7ede4,b98a72f9,f0e881e) +,S(21dfdc38,18debfb4,9cd409a8,a302f8ac,64d589ba,b65074c6,365bd398,d34d3032,bbbe7ec2,e835204,a786ddcd,bb6026e6,106d193e,21725c45,79eb17ce,784099a9) +,S(60fbe5dd,802f1ab2,cbae99aa,12cce0ef,36a472e,bbb1bd1,c0ddbd40,85069fe1,ea83b59,2dd304d6,82fd07a6,85408f0b,99feb1b2,b78b1316,7f9be524,a7349dc3) +,S(c804b465,fdcdc5bb,a848ee97,559405d3,dd7c2479,4dc4866a,e29676cc,1e147f96,aa4a2eb7,1fd82b70,ebebf43a,9b828e4f,fb10cca2,cf9bb522,3a7eeef2,5badc5a2) +,S(77a6e3e5,51373b55,dc51b338,3c32f6c0,5c74cfbb,3192fb7b,d96d9d3d,d50336d9,21d2326e,86efac71,48e075c1,ffcd573,5de35d6e,3856f2b6,7d358b6b,c6f047f) +,S(86ddc187,4a72eed2,666706ff,26a4ec65,a89d82cf,64e3d8c9,4731d62d,d5f7a5a,51f7cc40,ce45a123,a9217816,ba3e6dcb,40507b5e,4cde95c,443ce5ab,4f0cc29c) +,S(cf49d0f8,db8eeac4,6c108675,a155e327,8c80d5ef,84ea28ce,4a596f3f,c7d3beca,6ffdc741,ebae75c3,ed82dcd6,a6191d68,7cdd64a5,c3146d41,235b96df,420086fc) +,S(1d75ef89,57eb6722,2d60e872,1e126cec,c9f5c851,5fe18381,518cb54,b75875f4,82c5dfdd,9288561d,dbe4ae2f,5fa1d429,c2076625,7765b3e3,7b99dc66,b78dbdb4) +,S(bea4b735,f62e6122,9d8d9466,69503348,5bb5b7e3,c6ddb6dc,a292ca89,e7ad0689,90e3278a,8ea9e10,e7d9a451,7b7c01f2,7cda5836,f52a011c,d8e20ad3,7a08901) +,S(e85b0ade,a90e5170,18d0aaa2,75d5989e,577f5cf0,b3acb728,1af396a9,6169f2bb,d42970cd,3ca175c6,3916fec5,757b7f5a,30ef1269,d4083358,667f599,e650aaa8) +,S(d97592dd,24050526,e41ed550,fcf7cc2c,82ca5584,c0228f5e,3ffe42d8,a3928934,eac6c169,6bf01c3b,759a3852,a0236f4e,4de0db45,26f2d26a,2174dc4e,fe2d102e) +,S(e023ea4,50b620e2,378e60a9,a8c65778,fd772575,5aeb53eb,edd35ee1,666e00e7,4e4ed850,6dbdcf89,b060f0e7,8915f506,6bdd544c,e37e1e30,6a966353,6894797e) +,S(615b5c95,5cd4fd6e,a581b9f7,e6a857be,a7c0ec2d,c302dc9c,c8304ec2,d935e5a,c221c766,2602325b,bcd845bf,f5d754d9,46fc8074,f36a78d3,6e421b14,fd5f4d46) +,S(b1dfa434,2e12021,b9ce34d6,1391bdb,fa2a0d85,a004985b,c2cc7358,96ec13a7,fa3d115a,8162f828,1dbb7e9b,6f818b4,13c2a5cc,58993ead,d103ef59,9748438e) +,S(b64b601f,afbe47fd,ac675b83,5e4ecdc8,68c7e1ab,32598974,36ba3c9c,bbeada7c,af78c039,d2315746,feb60662,462dbc9a,652ae90d,573487d8,5ea52374,e9dbe68d) +,S(5429d346,fda1d9c8,6c5027d4,e94d7565,b0981f23,52715336,4a0f3264,6bb579cf,5b8ce197,dfecd92e,390754dd,2d74636e,162d6659,51464f37,ac696a32,995b1880) +,S(890694f2,56d6718,b040bb78,1041749c,20e21669,f3787f94,ff954b16,2a6f005b,d966934a,890dbbfc,bb90d7b2,26afd0f8,7bf505b7,31b94df3,5df1c141,2d753341) +,S(3ae75292,cd0526b7,fa6987a0,5fe060c8,269b5d1e,44a2867c,cb92c2b6,743cc117,10959cc1,5a74a82d,8f7d5416,a33256bc,f004eee9,87b82871,d22a2dd5,f2416a94) +,S(9d745a9b,ff717d55,5a353fd5,f1b9fa1d,347bbade,8a4abce9,3bb5dc7f,299b0707,cef338ae,d513c60c,7304f615,ae734de6,10461cff,ade0f69b,bac28e6,7ede8134) +,S(699e9c2c,8130c939,105ce7f4,f922c060,abf1b896,648509f0,aaab9519,d144f166,882b490e,1fb9f944,95d14583,83809d69,bfb7da29,97d244a4,38da39ed,7c3a19cd) +,S(e3a01cc1,dc520509,a91ea704,bcbfe298,ae79b4a5,4f433550,3884a1a7,85591f87,f3c641f3,68d19d57,fca87e54,6ddaf495,2480a891,37490b96,6617fd4,1edcc64e) +,S(5d150dc3,d9df375d,46dd2362,34498514,cc7ccee6,fd8ff5f1,ee5ee38d,6ac433d1,2c091250,d2e2ea0e,7d80263f,18401092,399a83fe,bfadc061,a32316eb,52ab0316) +,S(49fb9761,bb12ba3f,644aea5b,5e011f80,ec477880,58a6eb16,c100c5c2,e0996a66,7134220f,b7208914,58499caf,21654c5c,d9086b1b,92978370,89cfd06,d655e23c) +,S(34c55eb3,a4512dfb,de799021,1adcddc0,bdea055a,1f4f7b13,d530c945,2a44738e,258cc688,beff401f,9a910e26,d0c979e5,fdbb695,323321f2,ba39a4c5,4f98fd16) +,S(7068fcf0,7c3efe00,4ff7b82c,2af0c9cb,9b1c39f2,30dc602a,b2508d42,30a3a98c,e48730d8,844578c5,2e7657bf,202b5df5,2fe50679,7e2e1d77,aaab197a,e37ef1fc) +,S(e1d8910,a987aaa1,12ba1f95,ae8e346e,f49e5254,a2b01909,f73b874f,6b355a1e,8ad0311b,cc4947d8,999c2c14,9fd5c59d,d4a56a20,a0b90235,d7bab907,fe3cdb8) +,S(92509b88,ba8631b,16c6b2d,c60df45c,6bdf06d8,ed4dbd57,c10ac3cb,72d2caf2,3ea47a31,633b6299,a9f95651,b95f1411,ee6f0f33,35ddb8c3,3978af58,746a3ccf) +,S(90fd402a,e8d505e9,96aec994,db7d29a5,6446471e,34dc7512,6a356ac,1a66a519,68c0ff7,bcdc36e0,ada31816,ec4f0e67,9a6dc658,46aaaa62,e1958ba5,bada3b6b) +,S(b380ecb,7d9bca8e,1e35b0dd,d412b128,4cbc77f,c66c5f5,eb390d9f,a9400704,fd2a2092,77d9b783,9df69a7,229d55cd,18fa71db,e1f5f8a7,d78f450c,846a01a4) +,S(40e2e041,aecbb6cf,6f866140,b6149257,f3d029ef,ccf2a752,d3ef7b0,32b83f0c,122710a5,3c83888f,54e26679,417f2329,e1eda641,8e525326,704744c6,bc2291f0) +,S(8e609fc4,3f4e30c9,3893a38e,9aeacceb,7d254eb9,f77b49c8,c99c20a8,aaa03583,947c4c6e,9a821504,7f259a86,b1d70378,837fb57b,e0d696d,66a3dc3,7ac1a3e8) +,S(b871c5b2,2bfe9fd1,6898d00,1af89a8f,8d9c9324,52fce0bb,2ecc0835,f435f5ce,e302e5a3,ecbd0ee9,9f87226b,6f038003,507fe8ee,60b64,cd656f26,8f1d3078) +,S(526daa7e,39e891a,bb524170,96fff4d5,c6f80f57,cce87f83,2ac07cd5,50841682,69f04499,4fb7130e,758fd397,5ad40f68,c477bc9c,cc5c5f43,c5f5a554,b3d210df) +,S(c15c244a,514e3057,ce67cc07,3fb66fa1,5c031f51,8add9ba2,edc12f94,861ad25a,db1021ac,ecc3c897,8de34780,bbc9a8fc,16449ddf,5cb05b90,1ba39598,72846c50) +,S(37e20b19,466a038d,b3b63873,50dd3dc5,d3494876,cdb7f344,3e234173,eac1d388,b80a24,546541e2,ecabcfa2,7db57aba,5ea5bb79,f69ecf25,2d68ef63,fc3b89f0) +,S(6d091f28,feae0142,b311cd81,f57958a5,6a0da5c9,7ff5eab,c598e4fb,564ea528,48bc97f0,4d7ea6c1,38189719,6c85dd22,6e9d9f7c,5a8ba74c,27c29063,fdd07906) +,S(3bdbd416,a76efb56,ed01664f,b819dbfe,d3e545cd,3edd48d3,5ca635e0,bb54fd71,a6954d72,3ed7253f,ef301621,91fbad8f,9a63a893,82b98d26,a6bf36f5,2ceb0639) +,S(cd4e36a9,f111b55f,8c05d41a,4bc33ef0,c4109540,d9871237,4018b2e4,7e9d61ce,478dfa16,52632e69,6ef95ec,452df807,abded9bc,264e6dda,df0c6215,454e3e57) +,S(f23cc4a,9c59c0e,3bf21413,170ac67e,24845771,2e77f1c6,272a9f11,2df24efd,e933bc72,99b6effd,5cf58fc0,72f7a466,dc71cdce,74a3d3da,9ed5e7dc,577fa4b2) +,S(d98c6585,8c97eb35,b6846840,cb6db623,d7a349,435d4989,31a695ad,ed3c33e0,443fea24,ffe8825d,eb6c953c,70627395,ba13781a,164f2eb2,a85b862d,e3114990) +,S(2269daa6,c055dae1,b6d2b9d1,6c74a9bd,65325ddc,a249085f,a946e66b,6c744225,159d01f9,a61f0456,b08f0fe6,a42efdcd,30e14ff3,bb47fdee,2352dc9b,f5bfb3dd) +,S(335044fd,8eea8792,8de3880a,546b01ad,eb4d75b4,23ae7ba4,87740c03,167c48d5,69e503f5,26266bbc,63b0f2bb,757b3be8,cfe1d9c,e63d8226,8187a309,ceda1cc1) +,S(ee7a263d,86f9a83e,54cee87b,7bcae75,a601da9b,637aba50,46bc5f9a,3ff6c512,9fdd3192,203268e9,2388ac1c,840e7635,22271483,161f8f60,42d82909,41373d56) +,S(529b33b3,36f1631b,6c7b6111,ef44a888,bf95f344,766a2d97,6c5e5d5a,53f44245,12856106,93da6f4a,2fabc1a0,3280249f,6f29f9ee,9ccd7000,4cf0a857,ea061099) +,S(f2b3346d,a6cee9f5,1a933718,2d655a88,6a251353,8ebd243d,d3e3cd65,abdf1849,d41df628,be7703fe,9e866526,2f6278d3,55aaefcb,324df2e1,f483b0f7,77b77da3) +,S(535e9dbc,f03d98c6,70d03d04,5d638c7d,1db7a12a,22f3837b,3f559b70,4582befa,2c233228,bad897c5,bd4fa98d,67f8384a,62ea4761,4f64e4e7,40bc1f65,9e358392) +,S(c131688b,70da6ac6,5ee3172d,dff34624,b019bf78,85033970,8253b4a0,b299a7f1,fef187b6,e0e748d9,69a11d82,e9f996f8,d6e1aff,8b84d20,7dd78519,dce5f3cc) +,S(75dc84d3,f7ab7985,10ceddf3,da6bf832,a984d00c,98726a64,5dc71b21,754d3ba9,f5d9edf3,5e110491,2cc5e4d2,82eeaa53,84f62deb,1dc2a183,af5b232a,e3841c50) +,S(591dc7bc,9136c38e,ae727310,25c5fd52,82c6dad7,6f98c648,78847ed4,f32a36c5,fccfa4c4,f81cd382,e003aabb,4cb6c5e8,8d4875b7,21d44233,95397268,d7a421a0) +,S(83a59c89,2a8392ba,e7548fad,b87acf7a,d2c78db6,4c588f0f,b14753ce,12712596,7d00ac1a,33b12065,d67c598,8822ff3c,46f090e3,15cf919b,e3e5030c,e7c5873b) +,S(e9b0dfa5,8c52b2f4,a9c1b8c3,76391eff,6608f968,ec45bfc7,6ca93e2c,ba6f6f83,6449b28d,5846de0d,27489124,feb3f3fb,5c1f0839,a7809be2,e5cb5def,2e0a7c8d) +,S(16cd2f9,67b090c3,d151c002,d3a3d25c,c76adf50,d55a6f81,b1b9a650,b72bc03b,c592601e,2fe77090,39ccc091,bd78458b,a23db74f,848ee06f,50ffe4c6,8ad63a7b) +,S(f347d3fd,1bcde363,69e3d9e2,44d6e5f5,d80b8dba,7b1866b6,f584a38a,3aff1cbe,1c435ab9,ae38a13,98dcfc6d,64125e8,c7349f81,1584fa97,66dc4d24,7e87977a) +,S(5b190d87,d644854c,90c49f11,34921545,f349edd2,b4e9926d,534374cf,da428b1b,8a4eacc3,63efd6bb,5c93ab25,65d2c157,9c1d3176,b2713ea8,56bc97be,fa5401f3) +,S(a7786cb2,d7314ce8,f21e9665,bccacad,c49e78f3,7772c3ab,105f67d6,1c30834f,4fc7acd4,18982e3f,2fb1f911,cb70bfc0,6c4ea71b,a05f6371,46e96bd4,a9441953) +,S(d3654f53,e9071a18,8c5faedd,c0ef3616,abf74d26,f073ddcf,545a01fb,2fbf33cb,a56f20c7,213c0394,5978502f,c4a716f3,77c7a3d9,26c3cde1,880f103b,432f4383) +,S(e1138a87,400acbda,69d8ac3,bb6db4cd,27d03176,ee88994,2039a93,7822399c,f29a8fbf,dd3f6d46,5c640de6,b6853e40,1803cd95,f5e012c,9ce967d5,13a162c1) +,S(d29eb63c,91c0f4e5,b3c49c6,9c9ca952,5714730e,76bb87e7,374ac995,86317708,4ad93702,4e9180a5,9d22ab4a,c856de6a,d9d38c9f,1cb3fdd9,d73aff61,fea5f1a1) +,S(a9d403ba,a6717fd7,6577da1,d8b8ecb3,d2124b30,d18df147,ca48b482,26ee49f8,1eedfe7a,8c5ee1ee,50937bca,d9591144,56f1e49e,db74133f,f45176b7,26d5323b) +,S(ff7b58e8,dbb6055a,eeac6bfd,112d89c9,8d8f3763,98e41e39,ca076bd0,9ef57528,4e4e39d1,ad7a51e7,d6cb57c,836c0685,8e39f1f5,bd41aee6,cf5d250a,fc381121) +,S(43c50a9d,f7839f61,e1b6db23,4e2f146e,1672ea1d,566f5613,1e7bafd1,bd362979,f20fda98,81541a8b,a83e908f,69e05218,1e215885,f60cfbd6,1ada74ea,83f449ae) +,S(f608a9b7,1c91298,75662ae1,6be6d043,5803a9d5,29d3be53,9843f227,174ac30c,5ef364fa,e919dd42,1bad3243,413bb565,d788d266,d7b508f2,83c486a,327ad5bf) +,S(c913e029,dd1ef043,f9bc48d0,c267657,3cc11722,5cdad56,8d013327,445a117e,97573f0b,9c31cbb3,7bdcf07c,13526a04,32a38f18,43e26d8b,ace85a50,19a83049) +,S(aae0c49d,b17e7bc1,66c0c58a,cca847f,61318bb1,3482f63c,ce7dc55c,82a7d728,41170bf3,f68c3dac,22051aae,658cdc0e,810396ff,9d5d9251,6a7e6377,5c6be0b8) +,S(f2805f1f,45a0b622,59b9b15e,3de4a05d,e306c8b5,ebc5ac96,d35aa388,ebc846c8,f5d72739,6ba37244,57725cdd,912fa38,b36e201c,26409dc9,9789d087,6b8d1267) +,S(6969e4e6,e150d12e,4a230e59,37d865a0,f7d2323a,781270d8,7b0a7a90,fa4f39,c71c33d6,d323ed0c,3e77ebe0,8595dc9f,e030a0db,aae16f88,8dab7187,5e14de3a) +,S(aec2bf0,7a0e257a,be4fbdb8,e872dfbe,2aa0643a,411943e3,e4cef039,8d988f3e,d8e9f557,e686c380,c84bc528,fff0a830,bcc3b6a2,724d9df6,ef21d545,c8c931d0) +,S(9c6ff99a,13dfc35c,a502890b,69d91dd5,198f561c,790bf322,6bb243bd,4926f710,2aef920c,84a4f5ad,9d88f541,1ff46839,2f7f4e63,3422b11e,9b683403,f7ef849d) +,S(fa43745b,37a5e238,df0246d6,7eede652,ade75aec,b5dd8aef,afb8e6e0,96d7f1c2,df9d5aa4,2a3c6540,3793c8f3,fef939ee,48aba7f8,59fe9ead,dc44e82d,a98689b1) +,S(694a3288,6c4e26c7,eb3b84d0,9e777f96,ce3b74e,58658741,27643dda,a78d46b9,a54d6c6d,7645e5,6e8909be,922cc5a,a700d932,cb1318b0,1446a9e1,8bdfe67a) +,S(65499597,5be06b28,b4c339a2,b126210d,930fe920,7cc72be4,3d4ad17a,c08f38a0,bdee23bb,467fdce3,2d2cd92c,e81e3f5b,d29fe8b0,8b35abe1,c684443f,72f7900c) +,S(3791c8f6,75bb14e4,b7d4f084,483aec44,ea38eb2,9b108137,400099b0,799f0bd,2dc8f74a,da5e5eb6,f3b96ddb,cbee5ee5,8b2a3f45,c31cb16d,15a4e918,eef7bc76) +,S(d5e41065,eaf890e9,e9046936,acf6a43,59795c7a,1939d8ed,42941a8c,6ef31364,191ec4c8,a559fd4e,7abbb6b8,f2e4c32c,bd2f30cb,d06ff6d,21f156cb,f65bbcad) +,S(16ce2280,fa0b404d,28a29acb,62058b99,e504e6f2,eaaa3ae8,b77ad650,2c970dec,3d4683f4,486addb9,e54bc252,74e590c,b6eaec5e,7f96e9b8,8174b81d,56efb09b) +,S(a6b0ab30,6cdfb1f3,90e5b447,816841b7,e08f997e,d7d47016,bf3b501,c6107d07,2a62842f,b67e2794,92ed337f,d72abc9b,94e96e4,a10f658d,9cb9a4b6,a80abf7a) +,S(d7ca6d38,760b320b,21cb779c,d709f376,52b9d08a,8ff6ad90,21e00628,56033583,d6c05f72,866d59b9,6b91b6cb,b1401619,5e2d1cfa,9982db04,6d672fff,849e7bb5) +,S(78ab0563,2d3f707e,738cb134,7121c73f,e162405d,61a0bef3,75f6cb45,f5609d33,fe1a390c,10c7cb4f,297a4b42,4baa5c50,350eba49,55fb74f2,1094ec5f,ee75a6b0) +,S(c053553a,5b9fe803,65fc5a9,60e48fd9,218e2128,28935879,bd1072c5,180d6f04,e02da774,214dab04,e11c45cf,57be2802,7d0d28dc,51cc08a4,7528869a,3e719192) +,S(bf85d713,e2a995c3,ef98d403,30fc1fb3,5faf8e95,81385b4e,b65d5ebd,23f02d03,a5d45947,58d7b0e1,a8542a6f,21ddd207,dcb68e96,88284bbd,6b940748,b3e59b18) +,S(fb73b6c9,2be578b8,fe2ee0d,eb0aeec0,13816905,9e55031d,69a4d0f1,1bd280a,72ce7893,9bf5a55f,d4430bd2,55bde818,e15bbc98,37e3dcf3,e31d22c5,9614cd16) +,S(56496e5a,ed338dc9,201b04f7,8f4b6c2c,d9928135,83360dfc,1e2f370c,1628aa79,81dbf48a,824fca70,12315d3f,a56d5150,92ffa54,d1300725,86c8a476,be8c2db1) +,S(d698e395,9e81f098,485edcc6,2f2a421a,aecc0a79,58c9f6df,7905c931,b7a2130c,5903debc,e61eaa39,dac01a8e,3e970a39,79408bbe,1d0ffba4,5ce78c9c,79563d27) +,S(84b32e40,86709450,b32ade00,d3404b34,7fad8d7b,9387d931,780764e4,c566ff80,4c80d078,56cc4296,2b7941e3,195c5350,9bb5b0e4,325c24,4aa3a581,bb1cfdc8) +,S(7129c799,2a3689b4,c1873a45,f1ed3327,6528e243,28f30cf0,5ac38a61,8db2ed6,362b4fe8,482125a5,d4d15456,79009aa8,44f86619,cf3fca68,ce38995a,660810e4) +,S(93164c87,fa48b6ea,6b6cac08,8c991c34,5f8cad7e,f68c5b98,78139d28,d180d824,a3ac0d5c,c91cf0f9,cb97771,d16396ab,bd183221,c8d36a87,2785e847,b5d9e26b) +,S(4f90e8e2,37c4937c,a384c7b1,f929f329,94744d5e,8b89ad94,808ed9b0,9f305a68,cde776e0,2b6b484b,83f417c,fceed07a,ce725e00,343c4e70,14748f08,992430b8) +,S(4d9603bc,9f40716a,e6913fae,253eccd3,4442f6a1,3c058ed6,a10f91b6,75f716a1,92b679fc,278ce355,97165827,aa6fb450,9c52a412,284aa493,c6654ee4,3924add6) +,S(8b6f651f,91c54143,12c94f3b,c1632e13,f90cd718,67f906a5,aed13c4c,4ab17203,88c159a4,b80f2556,bb4e2b78,c126c40d,9ded995,bac6ac13,bf83655,210c7066) +,S(6f58b852,cab98347,e86448f0,78d49916,1909e1eb,60556ee9,8cdc20bd,b25ec256,3a4c05f,233d9305,e6abd30d,da0cebea,1681dab2,ad805cd3,2fa7023c,98239885) +,S(6be7f6a8,4021411c,acb710da,3ffafa32,8bb6ca91,59a91008,6cb98071,100c44bd,bf64a6f9,d461dfb4,581c8d59,b5fc1191,86f339ff,320e968b,b5810145,4836bee9) +,S(b2fcd0b,b8ea9e66,f2cfdbe1,3ecff9aa,99661f0f,2ac1844a,b3983d2c,ae102d39,a046989,bb3b8fa3,eb2cbba,d3a7e810,27c38cb0,ea33ec74,1444e8ce,7182bb86) +,S(a1d6ed0e,ab559b29,edf7770b,50cc5913,3916826b,6d99ef12,91bf744a,79a6fd96,bb91657e,c9255ae,173bf93b,51848094,2f17df30,ac6b391,df2237b4,c04ab69b) +,S(28f6570d,ed7130d7,35366201,e9ab639d,440da5e7,e1c9701b,d08a811e,912a9575,39191f60,119c59b2,3e91a7c7,fbf4c2c,e2216e5e,955db62e,dece6adc,f2d2884a) +,S(14c8ced,dbb83de4,218b089d,101d7b6c,31cfce22,49637853,b9c804f,90271fa3,48052d2,a5d02e71,135cba3d,24c7894b,de1293d,44a2f84d,7a8fece4,ea9a41fc) +,S(eaff9f05,fec737d3,d2a28fa1,bc8450a7,a75f563b,9221bca9,eda2f8fa,e12d489b,d6d4419b,5c9873d,7d3349fa,520f463a,2ad9f348,1a111c3d,d3fb70a9,23b8c139) +,S(e8ee4c6e,b42a3712,85b52457,52e7fc3c,ce0757e0,96932a43,d92bed15,14b35e95,d86bd4c,27ef1831,f107ff4e,6246cb7c,ee55abfc,cbc5de2d,5f230a2b,6a3b748a) +,S(98c61909,8213b06,6b70759,1c88a51a,d5e90922,6778386,a0776e6a,ee41e7e4,eb3d2e2c,f98bb904,42e90e2d,38ce4c53,fd72da8,1a37fefb,fc241aef,f65d4c8c) +,S(d4f66b81,f5d62986,c57a0dbb,c38bcb5d,89319806,4e28e17d,946cf7f3,f946dd29,c1930f8d,eedf1a00,cb7c5579,d814b5b8,2a12298e,530bb32,867821fb,7b7a5fc2) +,S(14d73ce7,5f8919b,55d54369,69866f0d,a13dd4c2,ad447c4e,b9879060,1411087f,69b94622,b9cb0d3c,5d106df2,caf4208b,b71c48f2,629d467d,16ee06c6,93ededf8) +,S(57efc935,59c7a0c,6ac51105,8a50a8d5,5646ab40,8a711711,5bc34c20,23da3aec,fca9329a,60b855c1,74bfba0d,92ae5529,27f959f0,5332cc4b,26272c02,b5c5dfd1) +,S(91f13a86,63da80d,a90b9458,55a9f3e4,171213f5,3683873d,cb6372fd,95b3677f,7405e0d8,6734f110,c329a7ae,92055639,e0332ece,134156d0,3cab4efb,419a90ea) +,S(dcc84d0b,46145e25,a83dfd64,b40dc5c2,c3322716,d1337767,5f9d6aff,a1607592,e46a4cf4,8e4dfeac,8df1526,f53246a,51b95161,a7030adc,8bba8ba8,1d2d6c66) +,S(28ab06ac,d5a6f432,116011e,6bf3c6a0,df0bfa1f,df16adb0,54250174,3348676c,51272a1c,967f49da,e9d1d6b7,a4ffcfef,cc31f42b,e0da52d4,27e56b63,97b0cb9a) +,S(7c01b21,f8d1dfdf,d3f2adb4,5915c636,d9c2a92,320c2d00,beff0f45,21d8b240,b4a48fcc,99906d81,fc6f78fd,aaa96b3d,6e7ffd62,d36d1aed,f76fa25c,542c8b48) +,S(f94eeb78,30f8e95f,2a362423,9c0e8fb,a0d3279b,e0cb5f5b,428a99ac,d14d98f1,c96d5b64,69676b9c,a5dc91be,8bb4a93f,7157221d,9513cd23,5cfe3ca,43649527) +,S(ea4674e4,7788cda4,bde0dd8,5f5e32d3,9a6d6477,30e9045b,d406f5f8,11ec35ca,769bf79,a9b9122,3070032b,a18bd769,fb622a61,424e9a0f,e1a46230,a75a235a) +,S(da5a7419,7f8f8685,1317260,682bfe28,19b7b38d,376745d1,7283c250,1fb40112,a60b5eec,5871e18,1325ef5f,5d6373bc,b5a19f41,2107290c,eb663e3b,95c37a39) +,S(c1017fa5,52560fda,18c6820,ded7b76d,a75ebcec,23b8fb6c,22ff72f2,26e9d41d,e947b19d,af2647f9,167da3b8,dff05897,9b5dc1da,6782929b,1b078114,349fed39) +,S(be7c0e1,4e814476,78a15238,b5809a75,1b964658,19bf0b16,4b3e914b,29216a7f,a30ebe97,f64219a6,f0b072b1,5d648e81,880840b,8a36204e,4f1627a0,feb392e) +,S(6758eec1,a4d6c0fd,cc118405,62fff82c,59e0fff2,cf80414f,cb53b139,97007cea,4653bc66,20fcd852,422c8898,862631e8,a0149bba,d0b9cedc,b4fe3eaf,7cb316b3) +,S(9cbb51d3,f88f4d99,9d80cf05,9e8735b3,11014de,69acddae,70d850dc,405b6116,dfa2e748,cad75b52,800e0ed5,17efc4d2,47c6381,9190a3d6,e2510bb,25902360) +,S(63a5aae7,b170792f,17350229,eaa5ad18,65328bd5,3421cdea,3d6e1510,d8bf0bc3,1125afd0,f25d5f49,f7e6250a,ed3634c2,12a261d7,8ce58ea1,95afb883,52da1010) +,S(adf96249,3e5f0328,ebae11fb,243da21,4e036d24,1da62430,b0fe2c89,b2f10657,509834ba,fcd8ddb3,2d018b16,d17d4b5f,219a29de,8a03f7f7,84f34b57,9b1ea1e) +,S(a0d8f5b,7fb44a15,93583364,e04d7225,bfdfa549,c2b25f32,f00765d9,e34d472f,61eab66,f84c2687,949da99f,3d97fe3d,630b6c22,f9f7c48d,d539b122,ef998ab2) +,S(b98308ea,9596a2db,adcdbf81,56d8025e,7a3ee0d2,5b27c33e,f686690b,ae61fc1,cdb4e317,7566a4ce,b4cc582a,3cfd259,445bae6e,586786f5,1250cd05,27ddbd37) +,S(e1a64f1d,37e3d6cc,119eefe3,793ba303,cf3969c8,db4abf63,7f0232af,70b98134,588d7ad8,885dd2f5,ec4d2084,b3f581b5,ddbd3567,8f4ecfc2,f955ced4,1c3231da) +,S(fbd5dfed,e8543aa6,e72253a1,bd711911,318929ee,7af14eca,49c2276a,65fdaaed,317cef0a,432c3516,3c405d51,65b8c310,f234891a,dbd0d6f2,f76cfbf0,193b78bc) +,S(fac4b7f3,b0a39510,84f1a882,2f7b6f20,30b87c4d,c0178a2a,e3077ce6,84da6bc2,7029b920,9e9522fc,160a5c54,a628fdd4,386ce0d1,55f19fae,390b2995,bc867d75) +,S(ca8643de,834fcf50,802c0296,41b5fc7d,3c29fc51,5c75c53e,e64a8185,43ef7c2b,907a6c27,111e296e,2436fd4d,ad9d9fa,f8ecea31,cee714c3,b26fa964,afcf17f9) +,S(71873649,d700ea1,7ea26b19,efe4b48b,a4a73b22,bc54066b,1202c96c,f3315f1f,f6cd8447,4bb374b7,753fc614,de5cf429,51512748,2042215a,bd82c11d,87ded2fd) +,S(67e738ff,21c3c732,26e57482,677c63f0,175b768f,776cbe6f,15ac3c53,48c5e3d7,14e5140f,2343dd72,577a5064,47cf6093,ebd2854,5d1326bf,ac79350e,eaf2bdb2) +,S(514b3f31,f875253f,205339f6,434ee17f,6c5a5c42,662ce934,280f55f1,9a198893,4eb33993,a2fbec70,4cd1c538,ce7cde4d,a61c0fc2,dca9669f,e469807e,4ae9a090) +,S(426acfa6,eab03e75,6ab30a41,418a0392,ca53c216,f84b3586,f9858501,8bc2dab3,c3d63eab,21cc10c5,c0a06682,d0573bb6,d34944d1,749da74,acb59aad,f1083926) +,S(b946bb46,68c05737,ffdcbee,94597c85,b8ad4a72,c58205ca,d420e8f7,a2d7a09c,cc700ed4,12633826,567e63a5,e65bc603,969ea13a,49feeb2c,dc723bad,1e3401b9) +,S(e6a844b3,f6c8b45f,511d7d3c,ccd75df4,1d1e38f8,fb28adcd,80335b95,d98e33ac,7f24789,3939890c,74a3268e,e1f717ab,6c4aa109,cc9257e2,c0b176c2,ec58cce2) +,S(43e62bbf,d9e052e8,c1636b41,5524b98c,493e903f,2313dcd,117d140f,96458001,f481853d,a90d528,30999300,dcff31d,ebee23bb,49ecbcec,8e147799,a63b352d) +,S(c44ef40e,3427476d,42e23e1c,41ddb9bd,e555a844,9125aad9,e94f44b8,8047f817,bedd4313,e43ee593,f2818e14,776f4ae2,38f664b2,db84c9d2,498b9ea3,8e236fac) +,S(a1b35313,dcc11895,c096f93f,5f8e4997,7f58f2fa,afd9b7e8,d408bde0,53212385,bd7eb25a,bf0d50c3,7309f9cf,5093d817,135a9ec0,20262c55,bdc8e8a7,a3079f5) +,S(48a6f3f9,fd6201c9,a37f2f0c,735bd98e,1382229a,d1589c91,b6748a92,1b5e964e,1b545155,3d41a8a0,64862c81,fa9d5966,2c73e039,53a5dc91,9712c50c,5b4481b4) +,S(8e01f574,651db06e,8a19181d,c8eecf1b,75f050cd,c5b2354d,b06285d9,a4061e9f,9d156ea0,9800e7d5,b6c6e90a,2eecada,7d7ba964,ba1f0cae,256fbfb2,275e108b) +,S(4bc0f8db,9e6db576,3eb68b19,5a79f8e6,28e375f3,1694a58f,43da4dca,fa05345d,c6a70789,a1e6b164,bba380e8,126a4a69,6338053b,6a32d9d9,8d0f215c,43a5b555) +,S(966fd0cb,5f5edead,d6230a66,50b7dab8,f4c7ee8d,b00ce55f,32d54a23,ba97a768,9d644e43,bb4f9b65,f5819a1d,ee0a16b8,1e8929c,a9e544e1,6546cf79,811a994b) +,S(6ab519ad,49522ea6,592dc7c7,4438e337,20d50eb8,862467f8,2962c510,857b0d8a,c5ba3a34,2b7250a2,62b67ec3,554c21ee,e82653a0,378ee0da,8a809151,a3ae44d) +,S(f8b0b8e4,3e5060f5,39bd0a0c,d076e163,e55f18a4,25327856,d526d6ef,aa76c62f,743de052,a65853fa,58cf29c8,62839aa1,7d5c95ba,43673ad1,fe1ecf6f,d4d48ba4) +,S(c4509ef8,579d8ff0,ab585c0e,5223d5fa,967e9763,9d15b0e1,6587a125,3ed18bad,7b91f7e8,ee979a58,5a36d8d3,574b8ae7,81199dc0,86f11cf9,7fe58e4f,1db08362) +,S(9a00135a,6ff450f8,e2207c53,894c0e4c,4cef732,cfab43c3,aacb00fd,ab42379f,393ec748,3684c5b1,4760902a,28cabb90,b481596e,8b847d59,4dfb8ff8,1fa9975d) +,S(3d775bdf,173f8d7c,de90c17c,25d3dee2,a484d331,4e525e3e,aa4a405b,6f488601,7e6b08bc,a560f6a,5bf287f5,59d74e25,38a4025b,89972046,b3de98c7,b30e51d4) +,S(cebafd3e,a60118b4,513380a8,d10a29a,a95e5002,d703d7b8,f5d0e983,7b03b529,19477ab6,46f59f61,ff603594,e33ba046,5f6d8b1b,f55290c0,fd61534a,87b74b4e) +,S(ae8a3cac,1ff3e3e1,ef01ac16,2e49b237,7ecbc963,f58adde1,58cb1987,cfa731b2,5a4b0675,2052b749,733f6af9,e8dc773a,ee26fd2b,114a7ac2,baca1e9e,51531efe) +,S(d74d38bb,8bd47123,5c118ede,e477ac4d,fd39b635,d0fbeb28,30843753,ade3b38e,f3e505b6,f17a2839,7a985084,31ba6de2,1ec0a0fd,3936dc32,5d66bb37,7cb54451) +,S(f4287675,7780785c,d14dc1be,fe075d1d,4d4f0b33,b0ce9db2,49595b14,f6beb2a8,a3df2231,eefc62dd,c658bf6d,a361ad6f,950f34d5,3ff25536,4eb1e1d8,60514b38) +,S(e91d576b,da19ad62,76bcaaa8,69cb2099,e6277688,3ca1d454,50dc9401,46378e94,b57e2038,c8da2cb9,9ac313db,83265d8c,20e7918,37e75db8,7acca971,3840779c) +,S(269944e8,7d77e176,3791b53d,af2aaa43,e035e1dd,f3c7daec,7e830cfe,38c66ea2,cb011764,34bdc7fb,528ca43,9b323c9,56764145,7b7eeea7,39ace76c,193707f6) +,S(ed41e68a,8f0b3681,1aa61c68,57bb1765,fb099317,2ff6ea5e,e94e01fb,644a3d1,f2cc907b,880cbe04,26ba1e44,83d95800,71c918e0,8cc085dc,1dd0deb8,c508231c) +,S(6947664a,96cfcba5,e2e36e4f,53a33d69,538192f1,3322113a,b0b79642,dfec0de,6481d1bc,5b65b6fb,a91b76c4,d6ade333,25610195,decf5dc7,7f95dc2f,a38fb6cd) +,S(aa3e187c,e22b63df,6a80a42b,ba9265b0,4379012c,70e8ef66,8ea85c57,1e27fb03,a638dd6b,98109fd1,96ffcab7,3010543,e8732f48,e5cdb29c,38fa91ff,8d011be) +,S(5de4e1,a4bef94d,b4a9fbab,6543fd6e,bfd5ea37,9124e1c5,eff9be18,f84a944b,21c4a282,693be294,b699513,f7744761,58f8aed1,a7ec7442,9679ba9e,7957e2d6) +,S(6533dcc7,2c87b477,81c96c79,3af0af22,fdd18fee,a33a30a0,9646c2b4,287a7ce5,7f03e5f2,3d82f9bb,ce9589fc,23442174,482748cf,a3aeccd3,f8c37058,837ccc51) +,S(139e5f3c,129e584a,bda008ab,85343531,c5109f23,a70b9871,a5ebb00a,64fdf354,497b7e57,41fb8eaf,a53182ee,98352b62,6bf011e4,826ac9de,6190a2f7,773f0a98) +,S(493fe9cc,f7e1e950,83cea991,8d8f2561,3ce57b81,81915f0c,7c779aee,8161f7c3,e69763fd,62fce1d0,454aff6a,6a3bb448,639ab615,8bcc2f40,88cbe4c1,67020cd5) +,S(ed675fdb,d8dd70b8,641ac2fb,4903ca77,900e3c15,766ec8a7,446e6b36,52a064a9,a61bb379,85cef5b4,6e0669b4,b0188ae,23ccffb2,5ce777fd,1f26f313,68416de9) +,S(173670a8,9a769e3a,797c14e3,15393d52,b6d48444,3861cb83,136b0ca9,9a260a4d,4dd43921,c1ba4d2e,95ea1b28,e4908410,d140b3f7,7dd82bc6,d683da27,c7bd4904) +,S(d5a5e3a0,8f87e154,6f11e05a,c106e80,a1da933d,2cca528c,df9e1f09,635d1610,7c6c55e0,daf3c092,8d0a9c6f,2c1ffb0d,aa20df74,20a35167,2552914e,5d175352) +,S(54f5e9a0,4ab321c,692f2e2b,94d6697d,a0a99932,74ee4ebe,4175a338,daf6fa2a,58cf13d1,75fa6e47,34aeb761,4f828dda,58a7d9ca,855ff42b,5cbd66d8,89f2de21) +,S(d6682898,154de995,62e5544a,442622b2,fd9a632d,94445d4c,9e8725bc,7febe6da,98091e3b,9ba3b857,50e02c50,a7971aa3,b2d5045,f760c1eb,d1371dc6,3190f206) +,S(253019b9,2af2c4c4,8d9f6e1a,82decd36,610becff,18c908ca,fef49bf6,cdc2da08,617d335a,d9509d74,e5eebdce,810872e2,3ffbdd3b,da53aa5a,495b86ba,397c680a) +,S(56f64ca,461bebde,560d2bcf,ac08f292,ced72574,50e44f16,bab67cd5,104da6cb,5b2085cf,dc278328,a992bca8,f2ee8142,757cb553,b903a3ee,bd83bf3d,593aee44) +,S(f39c9571,1e153a9a,f0e5c192,87e3ee38,5a31a1e9,bef312f6,4dded245,8f553420,4cc94ac1,1c206b9f,7879df90,8498c132,e742ef62,48bdfa97,4b882930,e3b0b1cc) +,S(437eaa8,cbdf873c,32d3dad,95c5aae5,b2f3034a,5de0c536,8c8ddd62,c13128b5,27d8ea0e,b00310bb,59424599,3d60da59,2f8d1b2d,df0c1fcc,721e3080,993c59c6) +,S(ade1a589,3f5d6798,4490ae62,11c57534,3f13e7a6,14ef71f,a79eb4b,a880e9b2,bd49c17c,537e6a3b,ac7404d8,c3c1b429,e801882b,7f241304,9022e262,3791c715) +,S(936275d5,c3091a5a,b9f57d97,7a4e1b6c,a87ef978,c7ad198f,d16e2d93,3ac1224e,6852690a,d8bd84c5,eab75d96,c6e224d0,ed598851,b17b857e,5aa01207,df6b9f32) +,S(29e55fd,3e8fd5cd,e046db20,5c80b9d3,e294971d,76b5e8c,c33fb5a7,6b9b786e,769e57a,7eb934b9,4578312f,720ce44,2bbf3e2a,d61a6f57,af6cde49,8c010a0d) +,S(df8362a7,350185ff,198b5275,45e16f78,3ae37804,7647c584,168b159b,809051ef,afcb3446,fbd4a3bd,e826b604,84b16c3b,735ece80,ee48da26,3a6cae0b,62af6bab) +,S(5f443123,9a35fe0,f9566037,96cc619d,b9a01e83,96cf433c,25415ece,58a427e,385c2812,fc0aabc5,29272b60,56aa9c17,37d81c72,48fafc90,6fd7d4c2,b0901ac0) +,S(c19c4215,53c6037c,525b77a3,1693fc4c,8c5323ff,5d3dd63f,4b7e3448,15dd2de5,9f76ea8a,879177e1,27116189,6d9e6b20,a19d2255,92c99822,159c8ec1,a93900a4) +,S(8abf3a1d,d1e02332,ead62fdb,36394246,14d19d92,a82113f1,d62a1423,af2d45ac,325a967f,dcf5ec3f,75e7a984,ecc2d9f2,defc2941,6dd507ec,7de1b598,a7e36dde) +,S(c8bfdf90,b93161e6,c4d4a58f,a71ea84a,57c1dd76,c0607b94,33fa3cdd,f759ae7a,23dc38a3,d172fb63,ed47efd3,c3e5aa3c,fd7990cf,1535ce5,b51944f3,270b20f9) +,S(976666c,35c55997,a759e7ab,85f90d7a,a26ccc40,5b77b8b4,43c7e86e,2d2c78d,6d342c3e,44facf25,bf2db2e4,e20cceef,92c52cfe,b4370f89,60551614,381ed0ff) +,S(e7790ba7,7737e4e1,c7bb8e8a,5bd89c3a,1fd65b6c,feb2273a,1c12a8cd,f963252b,2635e20,1534b58f,70e754ea,db28998d,f7138ff2,a9e92e1a,810259dc,ffbdba42) +,S(42cb817f,6bfcec83,f60e3ecd,5b986ac3,b471cec9,975f3efe,37577d81,4576fb0d,ed35e128,b2f9bd90,f2162050,a5737909,144a8596,5075fcce,2708a4de,c45cf49a) +,S(a0886870,1a239333,ffc60397,ae11f145,31902428,a4fd58f0,2450e0f,412f3cbb,c8486f37,1ad6e034,8e51995,b4887ebb,fc6002c9,9cc00ad6,d8a81f99,1883af52) +,S(a40cca41,9f101b8b,40fd8e8,b364a52e,e6a9642c,22661aab,3486f25,732c4bb3,f421b69,3ec096f0,2d1e611d,f0701cc3,b0655b9b,95009285,babb150a,9445a910) +,S(90aef978,bbb0472c,5a75b70b,c9f5755e,c532940f,141a350f,efe604a4,35beb721,f9f05c70,737cf6e4,ca88cde9,2e478ea5,93f58510,9479d187,a5f87e11,e14bbf0d) +,S(ffc23a81,a0f61f39,600292f6,8db9acb6,d73ae433,bb827f1a,7bc6997,ac3407c3,b76a0612,bce5e139,277c7463,d47cce0,4f313b37,a0746803,6865f284,574d4b66) +,S(d3ca7b94,40bdf990,4262bc16,298425a6,742c852e,df99ded,2ab0ff50,20a112a5,9daecbac,ca7e825c,4f44281f,9813ce2c,5ef191b7,341fa2cb,1f9780ff,de4d637a) +,S(2a53a2bb,720ab31c,2a6b7589,ce0e1ac7,469b21ac,d55eeb41,b23b3cca,51bb9f06,11aff933,ffde9646,7a4d0f52,220d06ec,27f7810d,ba44b256,c21a57e3,d451f84e) +,S(487e5356,80c40287,a6fd2f77,bb8f5cbf,22b2fc71,7fb7487d,5a08474,ada1ac96,53bd7fd5,46070d63,77b65326,d5130445,29c9625,520c3a73,1e990d0d,5aa849c8) +,S(3e5a5fcf,291da0c1,fc332cfd,62f4b629,cf23c0b4,8209fa29,63de5b99,667b3e16,86987f2c,43389a1f,4b028df,773bb130,8b33d7ef,7f55dc97,b060ded0,fab86825) +,S(4f90afc5,15a847c2,2c42493d,22dd5704,601840fb,57086b8e,d5f7d779,e3e256f,46e31958,ac2e6892,335f6b08,9ac0d3c2,4ef93994,2b585e33,226ded0f,aab831be) +,S(be07392b,40be3ea7,a6a73807,121be982,c2ff4b38,a4585a17,82c585c1,e23601fc,3a158457,657c9e8e,7bd775b8,1dbe2109,43172771,e66ec38d,a57a8216,f1f258db) +,S(86c274e5,2140375f,222f9e6d,47c24e06,ecc2f741,51b5a603,e0563412,fa1108ed,4a02fab9,4065d590,32eb90b6,4c98987d,2703f276,f92c03a2,aa009692,40a96ef8) +,S(4fd3a6b,e7923898,127b3056,1dac13fe,287277aa,21127626,2678e04f,3573cf97,6498a1a1,63cfecb6,c6cf4b4b,43bc7e96,f07ebea2,3b4380d2,38c0342d,f11173e4) +,S(cfa435ca,5423bdd7,8aafe78d,1fccfd07,cd2a5f86,ba81918c,b68c7695,dd117c94,bf4c891c,2dff79e,35b77854,66845389,c399b53b,4a9f4cef,d7d68357,10ce1fe8) +,S(aa5acb1b,79533cc5,9b29e927,77469afd,414119e6,1f3c90c1,cdf93e2c,3e1d446c,b0df29b7,8713c001,fb6d3854,e183767e,8b11bf10,9c75dbc2,6bb408f4,22a498ab) +,S(1b93c2ec,c21bf558,ddbfa1c4,41bca52f,435c09f5,4d06d175,6353e0a1,545c3d15,56c455ff,718190e6,5ace8a5f,d5c6d263,f72e67b1,a20dcc4a,eb53fb4a,33195ed2) +,S(1744cbf0,2566d20b,f639438b,55f72b0d,c8480092,246410ac,d8551498,2fb91760,7e77a7a2,32b0b5c5,9d1d5da5,7a7d2570,68dc0f8,4bda1f6c,683f5229,df4c66f5) +,S(a0be98a5,ed448c02,8c2f8ffc,607b316,1b9cb9a7,a2291bed,d24a8407,ff02582b,e7cc2c6a,2393525,b4d44462,cf6ac8f,76b86981,ddd369a2,274c1971,11da6ea) +,S(e0e593f5,dab5f7a9,562b2591,d8d75ea3,8b2f2b19,cdc8fe71,14891006,7b845882,9088c762,15e35db5,b3bc2614,1a42ce2c,b5464dc6,49f469c7,e785f5c2,cad67334) +,S(7824d895,a4982eab,d6f1b928,de7b0d65,ffe5796c,5e492b40,8b9fc879,c29290f5,ae175c68,8e428528,38a2d8bb,fc232c60,d6bcf117,57cdad44,8a4af01a,bcc7ee88) +,S(49d2e57e,e0b611dc,214e4a2c,d019ae2d,2aa51393,e976cb5c,4211cf10,f9d96e66,ffa0c4ca,88011f72,779b7919,829bb9fb,11c81e4f,a78154d2,5cfa3cb2,bd5b770a) +,S(da605f6b,8f701a85,86012e8f,83898aea,eeb3de32,e9c7bee8,be2139cf,c75ead00,5ba0c12c,e98a1c1a,89f0ca5e,a93f50fa,5a24307c,6751f633,d699e5ce,9411d246) +,S(aeeaabeb,cde94e6d,5a1de2bd,1d9c380a,9307be3c,1c32e785,652ffd9c,bac16ff2,30094755,8510ecde,500a52b,f107093f,b62e491a,c2596460,6641abaf,d50bf840) +,S(62f1892b,35f3fe64,b1ad1e1f,4305f9e8,66ca0a0b,e5cb778c,b0e1feb1,a10c40b7,1a44205e,e600bf4a,2e287f09,c5bedbf,f1f89052,2d14a883,8e1813a7,3f5780d) +,S(c2091ec5,46772d69,28ebe9f5,50a68083,3a567b33,dae25e94,4ac4d589,96979382,599a765b,d2e89d31,735fa722,a1fe1946,eb610c69,2d5a82b2,3828502d,cad4b31e) +,S(bfd7c15b,19519235,700e1b23,79fe7c22,e50a2455,5f83dba5,97d00fdf,1b242367,ac6de7de,545ec735,ea127213,fafd287,f4cddac4,8d6fe694,372bd46,bc66b17b) +,S(d4d4e784,3cabfdf7,903d8507,3831da81,9581629f,74f3cfd1,16b5f635,132ddc7f,1e49611d,582cbacb,fce65a28,44755cb1,d1cd6d4e,2b8f082d,219742d4,61758a6) +,S(1e575009,c378b34d,f3b434a4,95dd8c31,4945b4f8,df617d02,cddc11c8,8f908fdc,5ce37fa2,810c95a1,2697458c,b8f209cc,10bf2123,3ffa8565,5bd8587f,cf6cdb7) +,S(b5a66a2e,ac237eb8,a1f5e690,ffdf65e5,c9268c6d,37104ee1,108f95c3,b9408fd0,99005ac0,aaa4f6ea,60842ba8,68668c6f,f8cc3280,307630de,3c43ef28,cbf72798) +,S(1da39d35,2599593c,66c90b06,3baeaf8d,66bc3a30,21e3f6e6,cfc3ee6,7f26fe0d,9272a05e,b6b0151b,5470d076,c01c3000,f7e58aa7,8fc7fe48,9f285b85,c941311f) +,S(7f3b10b6,b10000a7,652862d7,21f428fe,4e900c5a,f3844500,2b374434,b5a971b2,b94a2fe0,7907ee33,113bd4c9,256fa08,8c4a4f74,df3c3a9e,1f5d205c,a2ecd385) +,S(426107c6,61850f9b,f6beb61a,e200c2da,e5dc368a,3f5d18cb,baf84cbd,7a4eb2e0,e1fa7c78,a9e6ed0f,8d713488,bd3afea4,857cece,8e8e54f5,40f8c70c,67e511af) +,S(555e2656,708fc4c4,312093c2,1489cfa9,d6c94099,680f53e2,fa374a43,45be9697,f5efb7,1e3bb76a,22566e06,c674ba11,a7822422,c6f44cb0,2f2e2be,284db6e7) +,S(7170b17b,5736e07c,262a927e,725b709d,3360625,4642a8b3,af8fdb12,917dd290,ef437ea3,f8998813,b5ad86e6,9a77ce0b,98b2c6a6,b6df5608,627ae735,30973b1) +,S(1ca8ab3e,66fefd13,49e329d0,72a44f1,eb4de646,c8930172,aaaec311,5a5c2180,6fc641c9,2a87d776,81dda2a0,f4984ed2,c70103a1,5531b274,fd20efa6,3b0a3c49) +,S(8352546a,f6d42e82,bf150c1e,41c1a72b,85f057d3,487b4797,7d5e4f8d,c05366b8,76be5ab2,7ca25b12,a888d7e7,21c2b1c9,ac92b0e6,ea0c484b,1383a835,86c5fdb1) +,S(2f112f7b,1730b9d5,63f988ea,765c48ef,353123a1,4d92e44c,3e988459,9c904cd7,eb348e97,f6487d5a,32f70b16,d2ad1740,27d7a8bd,41a031bb,743a6825,2e34a44f) +,S(e84023c,164dc6c7,1d72494a,d410a5e4,2eb6fd09,16a70f1d,5192508f,3ea5648a,634f3585,29be0328,89b2f510,622816bd,225aa031,ab145b8a,48a6fc80,1ef4462d) +,S(951c4d17,45daf527,b803929,114d57f4,4da40342,31c669af,d6e40127,8e28fc6b,f9083b11,a8b30fbb,2c696f60,8ae82627,b9592ef1,c72fc921,bb2ae4ad,5a27f0a7) +,S(adaa9457,f60b9f3e,e0a5548c,51f945b9,78845841,51ae87fd,689b892f,8ccb19f4,834657f9,2145fefb,8df9b047,55674997,f899b951,40ce5830,2e468588,1761caa6) +,S(649296b3,9800a3b,516ef3d8,52d7fba4,597f3e35,1d303397,7495fdee,619e6ef7,44ce9c90,10215167,fdc5f078,e2edfebc,5c8b441d,d88cf853,5c78533e,d61df105) +,S(2c1d7e97,908575bf,38afe2ba,7875f1d6,9f1e9db6,b11f92ce,4bc94d3f,6006266f,9eb250bc,30abd08,bbbb4e4b,bc09cb03,8c6c8ec1,fd1a6ff5,ba23726,da2cf7f) +,S(b130ff8b,ed4ebc32,78293b10,52fa197,b44adaa7,d1bbd74f,f6d56f9,744647ec,4a0a45e9,b785c7f6,76fd0a95,66e4228,136f60b,dcc1806,212590ff,eea5eb33) +,S(4f2a5997,62ecb2d9,31ae9c74,ccd71cc,29bf684a,d68f0117,32a0cd50,cb0e6231,debf8db4,5cfc7083,fa700dde,7309edc0,fc44216,cf7bc237,377c0bf5,7ccf17de) +,S(97f9e9a1,7fbe6e25,e41419a1,8a5a24da,a178c0b,a99e30d1,cab0d2de,7a23c0b,1ab1226b,cceb480,fb4fdc8,70fb5386,6cb622bb,e71d3c0a,4ddda232,57559128) +,S(e17f3fe5,e9f5d17e,40182067,3b710940,bfd486f1,ad3ef4c,bb93b47d,9d9d8cb,f1126a52,615d3a8a,6b360b26,305124af,44ad7d62,e03ed96b,59c2903b,b5272f58) +,S(1a39f846,7d638182,900c3e94,538a0fe3,3ae66853,aac36688,7a5a8bb6,7b2fa2de,ae7c1399,5a625a4e,42b4dc01,9d7c7501,18492f3f,bb4567bf,28ddef5b,82903aa5) +,S(8a5ddc61,27f6fa44,90a93e52,f4faffb8,baa60581,5142be68,cd18692e,b42f5320,5eb62325,853dddf1,a42559eb,bd5dfcc0,328e69a5,fc787389,74c80d1a,896b0d8e) +,S(117dbfb5,74b7d6fc,d47dc17d,56f5b5da,b864906f,f08d190f,7afe1f9c,fe38c299,4acd2151,30b7144e,437bc923,302640a8,c504712f,6b903b26,bd5db8dd,5d90196b) +,S(b0c31228,431c7eb5,7310706d,950a2a60,eec84ec7,418199f3,f2985a39,8a70a537,a7de9b34,792876ff,e98c3237,260d8237,85e47c,438fe419,a1048b00,b064ff78) +,S(7c210cb9,f493275a,e17e6d5b,517606be,736cbc86,5a5897e0,8d1d1f03,f243946f,17b07523,a8bd185c,ea4a92d8,7af1f1dc,920a7fac,30faedb1,c38e3529,1759c63a) +,S(172e5167,578bed44,6397b519,2b0eca17,177b14b2,f4570aa1,38771610,6ed6e650,9c15752e,4776b805,d63de803,83c73ad3,9d3ba817,c1f88cee,1737cd85,33830ba7) +,S(161afc40,df25fda1,3637317,3dad8046,c95a6ef3,aa9c19ca,47e9ce2a,20030686,5e6fd083,c1265f76,b4b9c819,3a45e0e8,9926f160,b6257759,ab90d6f0,126089ce) +,S(b991f2a8,e18aed33,4d769cf8,b6e39144,2d194e90,ee1518d9,459d3ec3,8a16a85f,1d2ba9a6,b89f71c8,ea169d3e,923d2c1,7e6e590e,21b28e8b,1a0d0cd6,1bcab7b0) +,S(dae0689f,5a6cee77,f796f488,1fb3647c,7d623348,7d5ab502,6f1ca30d,44ca8afc,ee67b670,f730bae2,a15e6964,33be5b95,43ccc1b0,314cdfa8,c6cc8873,c39c329c) +,S(47a58ccd,75f89c15,46a17ba1,4629fb5b,d72805a4,16a12e61,aeafd8ec,8a7e4e41,c15e7fed,1bbb810e,b4be60bb,61fc1f0a,a4bc43b9,73d94767,9b954f3c,29fdd889) +,S(f7ae2fd0,2e3b6ee3,30c0697c,94ef65b6,d7582f69,5c509698,cef09b44,6b040e3c,ade9f8aa,c527139b,c54d8e6d,ddd41ac9,5eb49565,79934ea3,6a9dd8ad,d419ca03) +,S(155f9ea8,9be2ae20,8d7e9c21,4c244a58,ae61cf24,5d5f8dc8,b6c448d9,7c12989d,1204f5f3,840cd19a,fda04abe,6cbf4490,cf5ea60f,4cd17680,8c1ce9d3,65b009ff) +,S(a83cc9c3,933b5f14,fa5348a0,e0d3ee39,e35057b9,13c5a51,89a61663,1e9d74f6,40aa66d7,fad68476,1e2a9c78,e1fbe478,52b91d11,a283e1db,e30d4baf,f072a74a) +,S(ca4951cf,c07b5c23,298a20e0,fa44b554,d7acefbd,bf2a6cce,11fc3ea5,67b5f5df,186a8bd7,6700cafa,c79791a6,b28c799a,35aac545,78586050,b8012c4f,9f4afc2) +,S(cf92dde6,1bad101f,5e71f2a0,dbc2438d,d6760ba5,b84791a9,ae0ce712,9eb6787c,a7d351b7,f3e31e6b,cbcc1f05,329458e2,6c9d8a9d,1137d595,28f53e23,5c3bcbd8) +,S(b1ab0b3e,cfd8283a,3b79df9b,e83e8b37,b06154a9,6e2a687d,8f51985,129c1179,cdb7f2f3,4bab534a,41f4cd97,b812900c,99e97395,3837f058,12d5d0d6,e9506bbf) +,S(a1743329,9cd4c9e8,4fb99295,f3febad9,197296a2,98b30354,24e9524a,e1789ce,40994ef4,4cf53577,6f078088,adcfa6d7,5bee11a4,4f2f3fc4,4282f5d7,f77e1afe) +,S(241b486,4efcac7c,3c7b946a,61a55317,38b31846,607f1e0b,d0a1a2b,d9c0573b,5cce8848,eec61cd3,325f3ba8,fbca403c,2f980159,bad3997c,832f5c98,1fa0d574) +,S(81f88209,64997984,699559ad,f799ab0b,e3efd354,d258137e,d753e3e4,de91b387,8f9fedb8,5bfd7061,1b9e5caa,5f3cc8da,43bda599,afa29967,a32c71e6,aa26d15c) +,S(49d64231,bd2c2145,200793d6,4a2ec254,c22da96b,655706fe,8fbf5d49,464e5a5b,faec8eda,b0d72cad,81df8121,671c6dd9,bf986440,3f1a702b,548d4333,c751e825) +,S(74c14c32,4fad3a41,1c7e1f15,9b740980,6daea24d,9476e938,7e77db6d,66e0ae4,af795203,1fbee5cb,f031a2cb,946e6b65,3ee0165d,abdb89fd,5aa73880,e0641a41) +,S(88bc209c,7342d94c,be3f4215,81383c6c,930f9c19,d09d91b2,a984b6d7,12a1e7c3,acb7d745,76dd8723,89a88866,e287610d,b817ebe6,1581aa23,46ac994c,4c5b3e08) +,S(486c8c68,c81ca88c,df7b93c8,5a1525f4,9bee242,676aae77,c1bd85ce,2a6eb3f8,e0fec94b,35fa97c,d5e64870,6f5e6849,d6249004,fb33e34e,c1add26f,4fe52d54) +,S(4a1efa11,6c588e23,7b5e30fb,5d0ddf37,ba39043d,6e5faf14,e28ceb90,4a681a3,bb196737,3c907165,a8937dd3,1bce476f,65f2acc1,41bd8d53,8fcfbf1a,997b64f4) +,S(d7745c06,c69609ed,db17f30,8efe7bb4,2632e85b,7f7f792f,8da44294,78eb28d2,7575a75,4d1b2bd5,5fc46e11,b1addb1a,5371f007,f702a97c,ad13f082,39b96a73) +,S(bd752f2e,a3db27c6,a6a08ced,df74a87c,dc333d50,fd9995f4,9ca7afa4,2be68def,378f8aaf,67478d20,ba4725ed,26d50c62,ef5c576d,da9c24d7,91dec38b,a5e9491a) +,S(ef588333,15a3c7eb,c6602bff,ace00d5c,55eb304c,7f3301f9,4be457b0,1f224d21,56eb3aab,6253dfbe,3d9a95f7,e843751d,eb52e054,cb5a523f,f46a0c12,b517abd) +,S(2c1de374,7355825d,a09beea4,f42df241,6b495ce,7edf1f1f,c1dc6043,5253727a,98593660,9082f5d8,8f9986bd,f77672a8,5ff92cd0,28d2c588,73a3b1d3,87a150c2) +,S(49f8d71b,23e60140,f50c9001,6f39b2e8,b78e2a22,a88f2535,324ff50f,280daf99,f66bb665,4807e7dc,330ec339,3f6fde20,308111c8,1fe42546,22b93a86,b58b04ec) +,S(365c9f85,754b61ca,2b2a30f9,954f3a52,d18fdf78,db593ceb,6df617ab,189f37be,c43fefe6,aca56bcb,ffa6aced,60a32794,7681b601,22369a3a,f1405a41,5132825e) +,S(1cf2cfe9,e89668ed,c1a446c4,da311cf2,7e2cb53e,1984a310,8e24e8bf,21f1b5af,71e56dac,43c53094,7b78f104,1a685f23,aebc7b12,e2caf803,6731ef5a,20c966b7) +,S(f3303479,62660226,f391c26f,a7e87796,219694f8,e01cbd52,25dce636,b48ca3ec,7dea0bf4,c110e945,dbb59ab8,74f83a42,afa585c8,56a93002,6f48f8fa,62762827) +,S(b689244c,4bc16c88,398664f9,2297ea0,8756a969,1ae7adf0,587c3253,e4b27154,9b488748,1357368c,c97f89a9,b4a75a0,bd7483ae,5c700364,c27d19a8,e450c856) +,S(bf34fcd2,d6b4371c,fef2f874,5e4be021,a78b4302,240d4517,f3eb1140,638cbe41,ce6888d2,7e326eae,8e772914,e1b43bc0,1ef6a238,27f67546,5464e195,5f97ac02) +,S(c2097a6d,231bc796,ce85a594,44c00250,d51ffe63,c45b9cd1,10ed4821,118d74fe,58b06413,fc4ac173,e1e3a85a,ca674885,d1f92b3e,5b99f72b,1350b6a0,bfe4ac87) +,S(874a6222,3d8804f3,a11b1de,3c647aea,e3e81798,40db2618,4d46a330,417afa81,4132a5f6,7986e622,976b181d,5c98f356,b31668e0,ef70f8f,6b13a0ed,af80b429) +,S(ac7c6e8a,1a05d592,8142227a,b0c3ed46,1f28463c,ccaa3b85,b9784e0a,f5bc605c,1a59a195,581e3397,eba60a0a,963f5c71,c107a9db,68794da4,a08b14b3,118a2186) +,S(3f13e2d8,d825a3f6,8875c01,a1715a5f,44bc12b8,2f254a65,575b163a,3333342c,baff6882,fb2c2611,ffef76a6,8b5e2293,6a2e6ecf,d7ba6724,3393fa1c,5825e3b7) +,S(1ebeb354,515e7f39,dc3e2631,51d0630d,aa7e400f,4c9f7cec,4d5f95ec,bfa8fe2d,a2e35cef,c2cdcf,384a2473,c185f3a4,c70724b9,84c72dac,a6ca11f7,ae5c85cf) +,S(c2dcdb65,b211e765,e6c59218,d12b45d8,b47d8f9c,e22b99a0,d2d19a1d,de02b2ab,e0aa5b9c,a960117a,7289326e,9259f886,8722e032,c96b5237,b146f50e,24f3be50) +,S(495d69f7,e2a9d144,8e2ed8a9,c038f6c6,7f360b8,270c9b85,841e8791,64bc0d45,5fb3fe2a,1dabce7b,83b4465d,74fac6f7,c48584be,134283e7,bdf59e0,957088d2) +,S(ceac4569,2139e4f9,701be43d,8da3f515,270a9477,bad5969d,2037ac87,3453bab2,bd1fd9d8,15f4e872,b602f2bd,9604b6b2,f385ea40,d5520b3b,ca32c160,44908070) +,S(7ed1d0b9,3196b8c0,1cd284cb,c0a206af,4e6dba1a,d6cd406,82f55897,9407e0d,e95a3ac9,6ba60be6,22f4ee73,2d75a9c5,11018ec0,d840ce0a,f1bca18a,1d2801c5) +,S(72fb366,4f42cec8,940fd436,5ba7cc97,ac5fe4b2,131250fb,a24b7178,a1040b04,c182b1a,93a211f5,f5de5c9b,4b52ce90,63d551dc,a21ee9bc,dbba2653,c47dce41) +,S(dd06cd8c,9ca91e45,d6720043,d3e6d857,4690192d,59154309,2160f04,6008beea,cdc17327,6eebea3b,f9fa8a7e,e83ebd81,4189705b,900b3ce2,72b85dc6,c41e7ecd) +,S(80f6129,e90a7f0f,1e650439,8bfedb10,3c708c43,2e2c743,da8a9a99,3978cd13,74d97812,145feff4,a3ef594f,85b644a6,d95a3082,3828c00f,e7226d4f,39deb82a) +,S(56af34da,f56b508a,eee970af,bafb9dd2,b48f83c,4c051b24,f5bc27e7,105995b6,d41dfe52,9e788e19,89105a4c,c219dcd3,decca65a,dcc5f34d,8a3ab0de,d1ae68bf) +,S(820225ba,795565b4,c45e29c,4689d91c,148cf693,a1a1c1f6,ca33c44e,4e3f91ee,3622ae5b,c89b9c2e,66bf5a3,17826928,11a0f4f1,4b387334,b24028be,ba4b7db4) +,S(7925fdbf,cfcc202a,895a1b7c,a8c7f09f,ad388db1,5652b703,3bf232be,a2ea57d2,46f7ef01,c9cb7dc9,1559cf5e,c6d3f5f2,1ebcc21c,a8414d0a,9dc37309,4e90525c) +,S(4b224b6a,f38ae731,5b316eb,8dbd2b1e,6638794a,9bff79f6,1027f60d,5d81808,3143ea08,b1633002,bbb2ad2e,11ffe5b4,b6dc6888,1fc669d4,23ff9cb1,595c3dac) +,S(2c0767fa,4135f4eb,602a1a36,e6ce488e,2c1bdd64,aa4113cd,28daf20c,687380ee,ddc3effc,e78d3061,7cc2da71,1373de0,6a65d2b,1050b89a,5f71be3b,fbc16a7) +,S(83837d3e,e7179a84,ef6ed2d9,41a9f835,37b5a2c2,5d511ef1,982d9bba,50a7ae7c,62201e16,60957b4c,a86f1a49,5a6027b5,fe2294f2,7946c8d8,556024b6,e3b66dbe) +,S(cf075b34,e560f057,53a8e011,835bf1da,25e50d9e,1d70dd9b,da427109,5895387a,c73209d0,330ff4d2,38e19f6f,33df38d7,2b11d8dd,180d6a14,4b07184,a2127018) +,S(d583f8ff,9b1875d1,ef468030,e3ebb7,9d06ba2c,1008329d,cb01b883,7c8931a4,f8cfcf1c,3f092ba,6bfcfcc6,9596b508,aaac7c9c,333ba58c,d55be53c,6fae3292) +,S(551fe9b6,21d2389b,fc185372,342edb1b,27568bb2,da1fe220,3431b792,43eaefaa,6c76904a,e48563cc,c6aff505,7f31119f,ff48e5fe,971223d8,c3badd02,563c24e0) +,S(1bb778fc,74062f24,b0962be7,bce7c990,51f06394,bc8e6da9,a9d63f6e,d16a80b2,2754f53d,2f4ed167,3d2700b6,8ff036fa,60e9352f,1dd7bbdb,14be1740,61d88318) +,S(a150af7,1261582f,8949f1a9,3ff8d539,aa0744c4,e97cfbe6,e4a3fe10,e7e364aa,e22a1afe,a68671c2,f9e12471,56e1bf47,100737ed,5f96fab9,9e0df721,eaea4773) +,S(c94ec3df,727fdf91,d7963a03,8e93d68,835ed2bc,2578780b,7242e15a,e72e2a9e,a476a0e9,7bda53c5,46312b35,f0fad09e,11b2810,b3f570d5,a934d21,7152009c) +,S(3366b9db,ebe13231,7c542739,4235a72a,f186bda1,784c7f25,5f8b65f7,f146875a,5ea2478,95f52889,42321383,5439195e,6b620619,20171862,eea32726,1345d3cf) +,S(616c8e6c,e52265ec,cb85ef36,5092b2bb,58bec6be,444c2373,974c38e5,e0e8ba25,4d3d5543,3d6e258c,d8b286f4,5f41249a,724a9890,2f1ef3ca,ba049bf1,cdaa0970) +,S(74df2177,2e38e84e,8b81d86e,f45dc4a7,2617b3a6,32094b1d,432291f,6a651827,4c32baf,30f09527,fc4abc6f,9c9b9a57,2a9ccf1c,6a1b360c,48746d8c,22e01334) +,S(1814a1bf,76b74532,979966d1,5ef42faa,532f8dd9,bee0cce5,d68fc500,21accbd1,5f5df5ff,da9d439,b2205ad2,5fa93b9b,7af1746e,9b2eef3,154bfbad,acd46bdc) +,S(28911e94,98ff7526,badf2287,8e85fbdb,5f444d66,c422a975,c7476c02,b98625cc,5a341cf3,5cf26006,9d869542,fb221ba6,eac150bb,e3809ada,5e4c903c,1e638537) +,S(d5acff71,e82a455c,3a1ce292,689e8686,f441ce1b,e644e79a,bd6d0efe,29270865,aac6d48f,1b46e970,a044971a,ad13f033,ca8cde96,958d870e,dc7d80,1d26d5e8) +,S(5cf51c1b,2210d85,9d765e17,32109514,8f03fc57,51004b6a,91f098e2,e2711596,1eeb19e0,610df459,2c31e58e,aa2a2148,17fe9ee,a3995838,f395bdcf,26d5c3b3) +#endif +#if WINDOW_G > 14 +,S(21456873,b58e3687,52c75800,8d3bcae,9efaf1f5,c5727842,25e3d854,8fd421cb,a2f2d10,c85e8a0f,4a136ad0,5df991ce,7d3c5585,a263d5cf,da50a4f4,3db76cb0) +,S(c10de5c0,51ae2d73,28ac06ca,cca840b4,ed7ab204,21c6122f,1d68fe7f,7893d38d,ee30e086,a891484,2ad4041,f9ab9c57,cff1a315,f0642d31,b31c2914,faac99e0) +,S(be778032,f12c1b77,9bba3d9e,d290ca90,30ac7050,bdd77a2,7eac09be,eea65c0b,8657348b,a1e27a63,1dd2a54b,e2d5270f,4cca817a,219c5378,4d4f73ba,2c932e63) +,S(a05e7551,f8f090c1,bfc8ffcf,fbf7fd57,9d033163,67d5ee64,b85c4f69,33d0ff6b,8eba561a,f42d43c4,99e1fafd,43b49698,a8f3babc,c9c94c4c,4822cbed,a741b309) +,S(6e4d47f6,b17501b8,f3b220d3,83cf5f11,a395c0a,f0023988,c4e7b8b0,ef66ed23,e01c4330,16e3e6a9,535f1d40,905e9b3f,8be9f05c,b53e6143,e81091f5,4b76b57d) +,S(f626750e,b7eacac1,7cf24afd,43345019,c6c32292,c72503ad,d4125d40,67b7e66e,d669f903,67f407d4,5307578c,ee91fa01,f030bb9c,b66c7111,34b91757,1c993f4d) +,S(437acc60,c555f7c4,778595af,db4676a2,1fc8b3cf,2c8538f,cecbae12,811511f1,985fd2c0,7385fba8,4cf25a1f,46cd2c3e,de8dd359,1c6d20ac,584b4a8d,8a65dd67) +,S(8d50555c,6245e43c,a619fb76,ce45441e,dc585c7c,4fb2f33e,1c07965e,d4e35f5c,ea828c37,331ad0aa,44d168ce,c328a9f1,c7deaa35,47ee4757,c776fc46,439ea5d2) +,S(87f5f6ae,580ebfe7,1b2c19c8,cfe770ce,cf8d4223,62718914,eb853f1b,7f4cbaec,eb61df09,12e06f58,ed6d85da,7240dd72,aad00c3c,6a3a9c11,1f378664,cf359386) +,S(c1cfcacc,b95e6577,4e2a7d12,3cb0071b,3325c27c,5d58beb6,781a30d,ff6306d3,fa9ba55,cd95e721,12d98a19,8e3769ef,8cebb355,dde5b62e,e6f3b8e8,52a3e81d) +,S(d68bf50c,89f25969,a765af90,854bdb89,d67acdf8,f1e16bff,64868338,8b88e311,b62d1866,55835dcf,8064e13d,aca1e896,2157576,a02e178c,78d27c99,9cce81a9) +,S(b8d7c25b,8c20438e,702197cd,a3bfc05d,c6577717,c9b6a527,15ef84a0,2c0df867,316b527d,4be0e62a,2015f15a,17a412fb,72ebbffd,b02e53ab,6e5e9791,b771b45c) +,S(d98b3403,a299106c,9c6fd52a,8abd9ee5,cea9ab0f,17a15b4,7eafc809,c34e356f,bebcd24a,9300c739,9bb3af8c,12fa813c,78c6838,dbfa00a7,4ab09669,4df9700c) +,S(dcd15a1a,7cccd53e,db08c2b2,c6367126,de55cc46,a4eaf5d3,335ccff2,1238bbdc,7de57d26,bf74764d,bcc7e15b,72ec272c,58061f47,cc0715ec,48bcc032,60e63a81) +,S(2f6a844e,e758e3cc,8f299e01,ba5753a9,d35e6c51,6a87a683,8f5ce28a,fca17c62,5c29172f,f907c0ef,95e78768,2625c8ff,27e26eb2,cd86df92,b9371203,8b332e73) +,S(e63add7a,e511eed6,93f62498,17f89221,c7a3a909,253faef9,23f37a64,9e2a2f67,c392df22,5ffa1438,c3d10c6f,813c3956,4f94367d,6fa26c63,1d562049,99a77e0a) +,S(f9955ec9,20fc68b6,cfcd163f,34bd033f,4ed7dc8c,30da7f16,e41adb,908c9b7b,4dfc49e4,ab583975,90bdfae8,56ce97af,91c92f60,a17df9fe,9ee923b9,9fe2cf14) +,S(d974d713,bce1db76,c5ea1143,b63ace02,5a2362ae,fe6b84b0,ebb0c49f,22341d7c,991181fa,3ae5f188,38a94047,9ea9e4dc,e8ff9366,78583189,bc340d2b,40481577) +,S(4f0af691,424d441c,698dfa3e,c3e56bea,e2c52fa3,bfd9ca45,763d7805,33a3037e,caac2486,81590630,b0c67160,89db929d,26a4e15e,b06aa9a5,2e19c92f,a9f9817e) +,S(ef6300a0,70060df2,3f9818c1,6ff4d315,fb1c7d4d,fef41e85,c96760d1,3cea49e7,a0622360,2def9738,d87803e8,6405bc00,88afa82e,39666246,10f5d935,993334fd) +,S(fef30954,1cd2a90e,1d473ae3,699ea7cc,ef69fe75,54f7d710,33b1f23,c9e96886,c2479c48,59423c87,5d76f6b1,5c671ed5,c9489af7,79266341,4ca68675,cab64fec) +,S(457cdf17,b1230409,c3d35a88,390f1bef,859994df,3ba21d2e,ba5f826b,6dcb4fc6,5aff71af,708863df,3074c236,446ddd33,5695c0c1,a45bc482,e0787788,a0e4ede3) +,S(a66e86f,fe0e9cfc,686ab0fa,11b641f4,28499f3,450d69a0,dbce1895,6181ea39,de0cb1e5,ca720556,7c6756ce,868df6b,5174887a,61afd354,653e759d,b3e3ec64) +,S(ddad5a09,c37f0de6,67eab59b,fa2cb47f,b79bf6f5,b8b0403b,f689acfa,627f1014,8aed1b91,c9e567b1,9806082c,79ec433e,1a152279,69df00bd,239fd8f3,f8e8d385) +,S(45c5156b,f1439eaf,16a43b39,5c0a393f,a674e17f,76f96d53,9aa6c99b,49042c42,c9bcc2ed,c5b5c8c4,b17d633c,90d45b9e,1583898e,41bb9d90,1d1b5097,57f5f516) +,S(c83b3c9b,564906dd,60049c3e,9f6ed0fa,b848366c,3b93650b,7923e9ab,8172a8d7,5709dd74,1326ab97,8853304c,a02315f1,1f0bed5e,bffab6f,467816b4,4c60a332) +,S(a857354,dd08dc83,ce7b0324,7594e4c6,99692c95,9a4887e5,344cd0a8,7970174e,becb7001,ddafd72f,1f845579,ca8d56d7,2145c8a9,be816924,957ba324,3c396691) +,S(8bba6b47,88259a19,578adb4b,6f7f51f8,d09eb70,ea790d62,abb2ed45,84f94f33,afa42da3,8526a485,60919f12,d30549e7,1d19608a,81f4cf6e,8e49cb00,2492b143) +,S(bb4d27eb,412e73ca,d2697d6c,46a143ca,e4420ec9,30440025,47aefb71,c99a53d0,9ec07a19,842a1e5c,9cf9f76b,55ad98d1,9485e683,b6b6700b,c905e190,bd9da19) +,S(af6f6827,d197688,f00dd3f5,ded1849c,11fc2abd,f90fc7f2,18b33776,e5753277,f9227693,c9405a2b,10e9b725,aac7ed35,eef4281b,ca04e,bd75b143,89323646) +,S(40453814,445cc67b,e7a4b71a,55e0b993,2b8b3477,f093df6b,f27f55a2,8bad2e1b,ec71d7d5,4e823687,d01d7558,6de9a1a3,7edc927f,e221941f,46051747,a69baab4) +,S(f35a6c29,bd596f0d,93cabc3d,c07b5f68,300f6ab,8ecde5d5,da8299d,112c7bcf,73fe2c46,e1b13112,718526f9,7a39f1f0,3d47ced1,84a2e4cf,1e32c168,1c470121) +,S(ecc7ce7e,bbe5da1a,596bf41c,4d19b51,b77f7019,bc431aba,e5ecea57,b095fa93,1ab89d03,9e7c6ddc,7751c9bc,4eb84ed1,b077cc8e,dc828ffa,37426609,e089c8aa) +,S(559820d6,bb3e47e,f68f48fe,1259da06,cd0b380,1f6bedb7,970c079b,7e373bd9,2373137a,a4d88574,151540cd,ab8cbdbc,5831fb7c,4b901c27,8c9a593,172a64e0) +,S(9c9b7e18,4e76bd16,856addae,9352590e,310d653d,809ec800,415f3c64,149be4a0,182cd167,55eedfc3,21d71199,7543b26b,d08047d7,c9363e23,20bb9516,da37a146) +,S(88e4e3d2,2cc3e6f6,19e62ffa,c7a4aff,63b16733,202e5410,52cedde6,9cda2733,ec6e32aa,498a7a30,e1c47136,5671d356,bf174630,d1b984ec,d9453e24,d275e067) +,S(7f2f8043,8e7d7fcf,593e337,a91b06ad,3ad1c461,fcee7bd5,82df516d,cb1c198f,2cb484f7,5a4472b3,230369f0,79f5e654,8dfdce60,98c4e561,a1310224,13dc1d80) +,S(fe0c5945,c5e67d74,ed498120,dae194cf,33a3fe5b,ef0f1ac,2c64c292,59827d7c,4ebff1a1,7d59c8c,469fad0c,79ef819a,8a897ce4,c0fa1121,741c03f6,cab0f659) +,S(ac0662e0,1be37c28,be457bc9,4af19e72,34a9d3e0,8667c009,ec58ee79,7e539642,b3adc375,bdc81a76,8385c9e7,2ecec61e,9b2b21d2,55f65450,c5956187,837f3767) +,S(15e0f7bc,d74e77a,af933c13,6cdc5b1a,1622de61,251090a8,f8509b05,d7dd527e,4d51a063,1fb81f2,fa1ef534,5fa306c1,a0c64f94,66961cc8,b574b06e,646767ea) +,S(e4119d0f,b79bd8c,e1687abd,4ad63790,814f9972,50fac9a4,f1b52d71,93ce282c,cabde097,8f9a566e,32ab229e,63bdfbd3,89f01378,c7d27b0b,f101cc3b,36bf3fe6) +,S(27a5b030,2005a21,5d89c0b3,4e4ee323,5e94742c,262a89b9,29e286c0,ab8e3c24,4548d58c,3792f7fb,18238cfc,993fdb26,f755379c,e0ed1b0,4df26132,8f987a02) +,S(a18ec59f,7621c8a0,59bcad5a,12d3f536,142d5c94,4c7a54d8,b9206132,d993e08,abd8204e,867035ac,8cde70cc,f7daa29b,d47b888e,1faa9be9,b20744e6,ec5a43a) +,S(9bcc19a6,71b787cb,9da72c91,8d7b2264,b9497ab6,313de85d,c3efbeaa,2f492219,4bea790f,67b8100b,9ad9a301,61e3bd9e,583daec8,b77f4628,568ed554,70894bbc) +,S(7ccb2731,cc3eb3a3,36d36af7,f44a0a64,e23aa0b1,12ba0e6a,11280c5e,1ab36205,8d60552,1813ede4,dcfcbe46,c75c5aef,7ec40c69,99cf301b,28b0e875,3031c6af) +,S(94107245,fa13427a,7d21f7c7,cfe0c4e3,2943821f,da0f77b4,23fde091,ba596939,89846c62,7868b1c7,4c546492,dd4821d0,cfe15fae,36896af4,547deea9,295ccf84) +,S(959bf7d3,989d3460,5f4b8f3c,cd12ed86,cd0a2a93,a8d4e1fa,aeb5d6bf,24f1115d,7cc703f3,5417d7b2,b7229626,558be68c,66a915fd,7cc52829,dc98c81e,c0162b7f) +,S(8e92173,ff2de4bd,f468e2cb,fbf6264c,5fff8f23,2fb57e1d,2a07ee75,3b45e7ac,2655133c,8833040e,4ef4c98c,e5c75818,be781f42,cc0b7314,7baa3ef7,99cc017d) +,S(4acbd2e6,98f349cc,42998c5c,53de7b6,3dc29b1,c2b8a569,48cd3489,190f0255,8837f8d4,15b3551,4544878e,1a71922a,ba4a0790,22c74b60,325c6f49,a411b978) +,S(f79cfd2e,b63f6be3,bf0f12d1,fea3524b,1188959a,425f5e38,fa569648,df433fce,9e412cf1,698805e2,a92114de,5694a925,17c31f49,ddca7e0d,b2d83d80,74d92b2b) +,S(41910c81,78f7a61d,7957c065,5d7e2596,a0e6d5e9,a0a9cf23,28f23569,5d818c76,26b318c7,e8a880ec,94c59a6b,d6f1cad,84031d0,e62ded95,1e265ba8,c3603367) +,S(5a864466,9fd276ac,ad8782d3,51bc27b4,9445835b,75f70a80,2ef42a0b,4885cfe3,b2510d98,60be4e66,edb8c935,3c8ff8d,2e008c37,6dd271b0,1f77276b,f3a5a48b) +,S(5e3974b8,1b87348e,e3ae5c83,2dc56d1,85004b16,90445b74,1b8e262b,ecfe0e01,63f644bc,397a1809,a4d57ba8,f18f0372,cd4fd083,1c3d3449,1ef2a654,46275568) +,S(154e9c88,589ff342,6fe2eb5e,dd6e1db,e253498b,2c0b3e0,52e84211,caf9cc4e,3a897093,df7d31c3,754f84c2,68b0594e,85cfd4a7,c2731fce,e01cc3bc,2bbc383e) +,S(b95aa134,e48967f1,bd3a7a48,d89d550e,3c3c3c6b,3c73de48,f2e6fba1,81c93faa,b6f2d3b8,8d0821b0,6b1134d7,ddc898fc,e84898fc,4719f8aa,e3570daf,168b03e8) +,S(316564c4,ff00502c,f159db79,62984516,4d6d24c9,1f20ba73,66669808,95e58b92,6110a6d5,39ddc,d4185b72,cc576b7d,a4577e80,3dd47a92,d4bf346d,ec5905f5) +,S(222b179c,29ff89ee,d6f2a0d2,d38c6246,33237c5f,7803d8c5,e4315f93,6a9bd225,8bddc333,6eeb3cee,a0c3ac01,e7caf4f2,f44a50f2,587e3e31,7046c85b,a57cb6f4) +,S(10347fab,33fb4ee5,6cbf75ac,6cb768dd,f51f9b0c,5498466a,6679439a,32048904,a351f45e,30f32caf,e10d99f6,9e9e4be,c3f4aa22,5388984,bc45bb78,c0c5148e) +,S(7048c0f3,1e600042,4544e9f6,e26783d7,baeb411b,a2c29c7a,5aed8953,bf831629,4683ad69,1d9f14a3,f67131bc,55d28c61,1b78b2aa,329668fa,8fc41736,c95840f7) +,S(a65f7371,b35de05a,78b71171,40ea9e02,7b777785,13fdcc3b,484ad9a0,4bcfa1a3,41d1268a,77b31744,5a270f73,956bbcfa,3f291770,d248d1e3,364b4aba,72b961c6) +,S(dfa35552,8518d1da,ee31f04a,2673d053,11db4eee,cdc81f15,bce79c64,3267a315,19ed047b,4fa52430,18863cd1,d8ade0d7,dad60ecf,10b767ab,52f5cef5,9eea9a8a) +,S(663ec2a0,80564f1f,943a25b7,2f60d3a4,17b62130,3015e17c,85782460,c601a48d,fce25852,5a4dbb52,4057f8fb,a4393116,ebcffea5,5ae3459d,3d8b19b6,a0387232) +,S(cc714eaf,26f9960a,b2cb139b,d2fa0928,7a309c9b,ea852537,e10b6333,2912431a,c1c5c0c,48c98ea9,b57eb13c,fa64146e,67a95569,b45b8643,7752b037,9269d070) +,S(a6ceed6a,bb8f1ac6,13799527,38a19b35,ece44537,e74e9185,a4ce3939,c14f8e77,c0090ebe,d410f2e0,2e56b4b6,adfd5495,488c2930,2c5e7a61,3926880a,88beedae) +,S(e0b0c34c,8d4f77f1,dd09ea34,8b0ec683,cb5ca777,6720546e,27ffcf55,a5e5bded,ed4adb20,ab5da65c,2d1d5d68,9ad63ebd,90170904,65f7ad03,1bf3d811,f407d09f) +,S(2362ff0b,9a2d0f7f,d779a83,8b26da93,65730d32,bc4411ef,fc4fd182,d9e486a6,d3eb4ee4,42bd6157,557e4e9a,dcc9c103,892ca05f,5c5af804,f736ecee,d8a6fc3e) +,S(2f1636ab,a1516634,a00a464b,aa30c507,af25e83,3f7f6fdd,ccf0706e,d5fb57a0,a664c955,c24a54ee,d56f1aaf,fc853c2f,6a81c53f,1ee36c48,46b26452,fcbcc054) +,S(243a8fff,6230829c,73368eed,fb4d62f5,bf478b4f,1752400a,91ac177f,70c303ac,29318b21,9f371dfe,4048c4b1,2f5317cc,b2e9c44f,ed72b537,a2f56d06,65229235) +,S(b17182a8,5f442a65,839230ca,5cc8f67e,835e54b,e0296c6d,e2b62298,74ae804e,11a4fbcb,9f6f8775,9d131a81,939e0125,7f7b4fca,e36ea644,4da3cc16,a161e5aa) +,S(5c9abfd1,9cae1a47,bebdd324,d11cf758,a1224471,6e83795,e42ff5f5,a8142a6f,38a38db6,f64d9d07,4a08a909,28768bdd,adbdd858,79ec847d,28c94dd3,a122e0d) +,S(44a8a4f2,ec3dd02c,226ae0af,d73a12b9,726e03c3,2a41099e,b70cdce2,767e390c,b7e18dd1,e6adcd88,1d1dbead,e1c83ed0,1f1d7b2e,50246539,b6bc2811,d63233b7) +,S(8e477766,c4de01c2,5cc17218,7f3cb6f0,dbc8eb54,fa888911,33131b7c,219e6e13,ba8f447f,10286c86,d1330c82,2647a999,b4b60e56,4131986,a6c05128,a480d83) +,S(c5f862ce,dd253879,8100eea2,92e860fa,321d7709,596a4dfd,6faf6345,82fcd3ae,81ab1260,684fd3d8,1b47c5d4,d5f0c319,93ae7db4,fed1a781,61d9d9d4,50ff831e) +,S(a674db01,836fe328,8566d977,753ebc2e,d55f0116,5ebf0349,51caecd6,ebf899db,12ae8327,737f7db3,56e26fb4,1ab306e0,2294136d,71206f43,78300b95,60f580f) +,S(b0cf999e,f11dea14,3e6b6254,aedf30aa,ba1e8e92,96c500f5,481eee45,a0e15adb,e4970d00,e02adc6a,be5e2433,7e017dab,17a61de1,d977ee99,969591,91a5563a) +,S(b3615f09,29f9b2a0,6a4c68ef,c844ae5,54959ffd,f03f9266,f918f16a,b517380b,31a7675b,83677cc6,ca87c525,27fbba60,d06ea317,fefb17a4,7d7a4242,3595f1d4) +,S(7be97bde,b271f807,96930353,b82c3cd2,c6cce373,198572c7,d289511d,7cf262a1,1af89a8b,cfa4a399,bce5bc21,e26c97d0,5126f8c3,211d8051,626c4f2e,c6f128b6) +,S(692e447d,df9c77f0,2db1d34,101bc355,519d40b1,3fff2cbc,aafeb555,29473d4d,d21950ec,fb7bb723,4e4e48c1,98b93a10,8a85bb5d,5228116e,da6f5cfd,8968fda) +,S(61b6fe3a,21b0bbd2,dfccad11,5123db4a,98058bbd,4f8a61b5,e416b03d,b1414243,75d3dabe,f3e2266d,65d408ef,af6b32da,7591f08c,7fe7de,ff20b9d6,7a3a8a8c) +,S(fe0f9f,aa49555,2afe97f,8462869e,e8a584ac,3c3fba4b,886208f9,fe260ec2,a9c0fd7b,cfa239a0,299afa47,e2861197,f382a331,7607e129,967bb22d,3ae3077) +,S(7f7c9a0,a240180d,c645e77e,c628bff8,fff90d48,c85d2fdb,faaf76d9,b93e26a2,1b12ec74,f801fbe3,ddeeb37b,c940c605,84b0ef14,85e9d888,f3f81c05,607d1222) +,S(3e444ef3,b77b49c2,75aa0524,77da59d5,a68dc6ee,6288e2ce,140512,92e54c60,e211ba3c,6860a898,9e1ee04c,ea9ddf52,25ed88a2,c6ecd9fe,3c2fd500,88367b7) +,S(4844747d,d33f7e4d,39aee79f,138b5fd9,223b4e51,c86e4894,c917a3d4,746d824,68cd147,2560b5d1,6b9bf538,b7f1e193,d2f220f9,ed9f742b,d36a003c,28e2357c) +,S(f0211c1c,8f87fb96,bd591255,6a799865,7382380d,6b5b020d,9095f482,4e8f531d,649112c5,9cf7a8cf,7f9d920a,6b6d1102,d92441f1,1bde7561,9cda8eb4,a26d7493) +,S(918118dc,15520a31,c715adcb,3e02ca4a,4d77c92e,310ef057,3f9c7a4b,d5d2d54d,37d2c580,337de379,925506ab,c6b7d9,4a61584f,4cb2179d,560d3a7b,406873af) +,S(78734d5d,833a5d24,5546e5bf,9d3e5ce5,61f818c4,a4c90fab,c8ae4630,a2c307f4,4b150c27,e054fdad,73506310,80eb5308,b39c6861,23b851ba,aa2349f2,c26b5981) +,S(ee988075,34a02de2,9fda41b1,c821c41d,3ddd5d85,9c5a4ce0,d14ad743,25943f13,ba7fda65,4389494b,40a9fbbb,4b72739b,6f85effe,245b895c,b8c7e423,8d6b7973) +,S(4a821b26,bd1326a8,26be6fec,b90229f7,d7a37a2a,c49e97a2,5bddabef,e854e509,8a645892,37ea07bd,929aee46,6fad63bb,5612de36,cb951200,b9faaec8,b11bfdd8) +,S(23658500,fe8b5ddb,93dd3b50,a46f9914,d04af9d2,2a786be5,9c0fa7be,7c3eb2bf,840e5cca,f9f3e8bf,fe51c1d0,a84de234,d7122cef,fa1f0ed8,9f1701ff,d17c40d3) +,S(71dccb97,7f8e77f5,a03c8e8d,e4b2a30,11d01e13,549949ff,42af13cf,d7ecf208,b70ad10a,5f03ad94,dc8d91dc,e7797eca,6ace74cb,4715bf6d,2b628bd5,f767f34f) +,S(6174a230,e15b2584,7a25217b,9d95f07a,e183f2e4,74d0503e,108994cd,69d20e6b,18cda952,ccd68c2a,5d78060c,6849fb21,e2379b48,425003c0,6f148a34,bf876efb) +,S(57cfc1ee,38d905d2,897dee9d,105fd4b6,90967618,2a2a5d3d,70781cc,9134bb97,bf6b5fa6,4de9110e,7d26e67f,65cd2765,fcedc182,1627243d,a85bc955,2bdcac33) +,S(26605be2,e03705ea,7f199cad,d4d6e711,9805453d,6d4feea5,ec2ae3f8,cdba59c,ced5f775,b62bddf,5935acd,9786847c,e7825da1,5807b117,7459f51b,72fe5774) +,S(6d89e2a6,9ff96c49,a3110a5e,7e17421c,4ca2d07e,6e807a3a,98d79954,7fde2457,4835767c,8f96da1e,78f1788,d9764dea,e4e4a0cd,238ff35d,851ee7d0,9c915df3) +,S(e3607608,338f4229,d77c51fa,cef2697e,f6010c8d,5138e0c6,2b724ad5,6ae79a74,da6a0617,a42d6ccb,44155f27,7c56c58d,42d6037,d234f1ee,ffd720d9,2ae23373) +,S(c8cf20c0,c12de1ba,1ad4dd44,46f76533,7cfefc3e,213c426a,e0cd25ee,2e8bea9a,ef7285a5,ea7393a0,cd78ea31,ef74f605,3d3312ba,f17bf6a0,77b919b2,33227ed2) +,S(f3d2870,fe782b7e,26a1a4f,9c7c3ba9,30e0ee0d,df6593f1,9bf11509,1fa63477,e470c266,ae26fadc,b2780985,9b9d60ca,fcbd9de3,5dfdfb67,9f4fd450,4ed6f3fc) +,S(702a6778,bdf2f3bc,4ee954d8,1e7acda3,1df7127e,a7920e59,a7028253,9019c6c9,2ce19ef9,10d773d0,cc32a503,83f9e968,ca3e407c,c1dfb652,377d08dd,1dca5b96) +,S(ea85cddf,4f79d7d2,a5db06ff,f1c1e3b0,87b0242e,1d7de713,53d8f73e,1bc83888,3806d40d,ccd867c2,2d166056,77d2d64f,d7433dd4,b1e83e25,91860599,2e66fb83) +,S(d0631e8b,30ef6467,de6af60e,61b99112,1949b324,786ff1c2,fe633249,a832aec5,deaf31e3,703df166,b0f92ee4,eff1cc02,684911dd,40054bed,4b21d4da,17f4c05c) +,S(b56cb88b,617a7104,c205e089,b83320c0,5dce438a,50411e5a,d342e9,8b258a3b,757edc72,52d76fbc,24a5515e,417625ae,11db0072,24c02fe1,1e249064,b5127800) +,S(e91ffec8,bc3fa3bf,b0a600b6,89db92ea,7c3ad411,d025a42,95570596,f44702a8,38fd56ef,1f7b476b,2e36aff7,73e190b8,61ec6370,f6ae524,d5dea16d,cc4833c1) +,S(4cd9e6c4,8bf7b1ea,9f855b14,fc904ad4,5e3bb71a,5745b449,e1ab3165,3bdf53b1,b5a075d5,ca9060b7,7d3a00c3,6fbc6404,88df6846,c712afdb,1115798,f382b4e9) +,S(abb07ce9,c4b711ab,d01a12ba,45f0040d,e3ff5a4,e59140d7,cf4ff289,42b5cde0,a8a0e68,350a88b2,397a162f,fc969d28,ed937f60,4704dcf5,2faf755b,d21f503b) +,S(95fac51a,c9deb5d2,b794423,a71cd282,b0604afa,bb3160ec,557a8b74,c578f18b,da99fcf2,abf21cca,c6f4e89b,de2a6e9e,ad199cb4,b97f4122,4f68bb47,b7caead8) +,S(2ecd3e62,b79b4f69,609f33f,2042b56,bad2a9a4,18e2852e,9e8f0d41,1fba8ab9,ef964275,95061068,478e11ec,942b6a2d,99e5b557,830ed0c2,c4291305,41104046) +,S(437d446a,d139d88a,b5437f06,6fdf8acf,7b538798,6baf9551,a414fd4f,101a6440,6c532bb3,38a34a07,28d3273f,e9d9c70,aa79c484,6cb337ed,b41f6029,1e2caa13) +,S(63149b01,94b4955c,1b7e9d51,24e7e7d0,4bb5d902,7e86e63d,f3add9c4,8ab2a44c,c867234b,b4ed27d0,dcdf544,be060a12,4c460c5,7a9312b1,46d2bb61,fdfa6c1a) +,S(78e509ae,99e6469c,41c44dd6,868ee402,8fda1cf8,2c83be01,9fdf912c,1e638bfa,ff3b584c,5ffcb1af,4980e2b3,ace00f12,3be630be,cd91d045,4e031120,245e92be) +,S(cb1d5bf3,f97b2bc4,bb33babc,72de78ea,34cd0a0c,e841cb55,7b3dbc98,61e1544d,e619e8a,dac79a61,eb46add0,96bbcbe1,31d33a6e,b6c99220,123dc9ac,3f27df60) +,S(3247eaa3,9ed5b604,d3038127,9661f350,53ddad8b,8e29d0fa,5c27ed6f,551cf374,1d29a713,d7dd351d,87175b49,afab518b,f268ce81,7fa39ccb,f08b3c58,de1e5378) +,S(d493ab52,8d6c627e,aa3dbd3c,8d809ba9,8a9fe920,307a0c66,2917f8cf,f68b3941,30e4336d,e1621a2f,fe7247ff,157a37c1,edc4f83b,e9fbd84c,af4f96b,8997c7ad) +,S(8dfac8d8,b65eec8a,a65f96b5,571830d9,22469450,42fb2baa,f76a4db2,ea5258c6,c204e9c0,72f643a4,1f53d8fa,dc66e3f0,fdf0d000,c27a5492,6323b2bf,b376af16) +,S(331ca867,1098b530,1b1e6f12,d231793c,de67de5c,640f0a1b,fbfe485e,5d2adff9,b52fb89,3a466c80,ae61d534,cb03fde5,95078592,1da21e0a,a8103d7c,c2e3d8f3) +,S(f34a338b,bb05db6d,55beb49e,526c9d49,fd515792,f407397d,3b520fda,3ffcf26d,6a6921c,4831df6d,91e7cafe,869c4274,faada27d,9d09175e,e86a0b9e,dd70910a) +,S(56d97dfb,284c7417,2e08fb73,3a2d0305,ff774495,2f229bed,cd36e7ff,6058e75f,3775df48,aeaafe14,a8005434,dfc19538,2d10ca90,d05bcba8,edddb2ce,4a4ed7d1) +,S(70e668b0,e854cd8d,d3469cc8,ffab1709,2d9341c4,4831196d,72d9673b,43dfbf7a,60567ba3,5546cd93,f2c356e3,927dc89a,c43fdf50,5e33ca9b,52552587,c905e311) +,S(675af615,9fb50100,56ebed3f,4c9784d1,17538d58,afc5ec75,fa93ee00,29d32390,c501aa90,4f9dfa9d,78107844,983e17b4,34872e3a,a94e37fb,6677186c,fa1abdc1) +,S(99f8e5cc,86ac5587,81a67270,3059442,88b19703,551474a9,9d433d6f,37672d90,30148ff0,9fa33b4f,f4410d57,9afcb705,c1146663,bdbd0fbc,8434f4f8,eacb09dd) +,S(8dcec207,3d74b9bb,bd47f52c,394b263b,e71881af,363bcd80,9adc345c,b9ce9892,d8bc1ef1,79ac54e2,68a685a4,db35e3cb,5b6774d8,e8d6b738,f4d65b66,86782a5d) +,S(d83f7e8d,adf27d5a,f8502d8,3ab81001,a2219805,d942cbfc,76db2764,c4235773,48472e1b,2609f81a,8b12326b,1b19b422,763b0ed9,d6fd67,51751c2f,8aa46c2) +,S(e6f8bcf5,d9ea8209,cb46ab60,643555e0,d0569f3a,dc62ac76,edc09a43,e02fea2a,7974cbc9,5a9dde1f,34560043,7b628eac,3641498e,612c19d9,9a79ae4c,cbde2d82) +,S(d2f30716,e4c1a665,a37d0606,3987d0c5,c19c072b,f1cca8ae,cd0e4d8,6a9e8c1a,e26e6d9,9fbd198a,ab83d0aa,ea53228b,539efd37,ee7ee791,365cabd3,8850eb29) +,S(d7a891eb,551ae5ac,baf366b8,65755a56,edc7bbce,7304a806,2729655c,f7f61cf8,8a7d915c,3a9a1500,616205eb,798915fd,9b33d7b0,6671e9ab,cf02b5f4,667173ab) +,S(5bb03484,f02ef87a,fa07f852,e3ec0664,67ffdc38,39fa28db,de0da07,2fc31246,e0515751,c377266e,ff95f755,f9c9373d,226ccb66,3678e8ef,176af5f,2fea3504) +,S(58716b31,48a0cac1,2024760,60d3734d,ab066ad8,c0f8d8ed,cf5824ea,83e111ce,71ae487,701d16a9,c1d2ab68,1ec7c8b5,8367a4f0,179dfc18,6778579c,553cf608) +,S(4a344869,db8d561d,96944c8,94a3c196,8d649fcc,bd430c7d,4a66ef0c,dc2ca550,285433f1,ff0e7dba,5bae081c,1b33c762,6f30224e,dcacfe66,46787818,da0f810a) +,S(3ecc369b,e7789b92,cf1448ee,28c0448e,ebc5d277,a8bdb5bc,a22d3151,5e246f7c,a5532e1,47848951,cf11e065,3f0627c4,6530436a,5f3773f2,b02c9bea,c1b60e78) +,S(28a5d794,21db38dc,8d7c8cf9,d120a3c9,97eea170,f0f6ed43,7222bf4e,27f170be,88cb09e5,ea40b566,39cce9ee,1245384d,2f02f983,3b3116b7,31ae5576,daed7cf9) +,S(4f54f945,b3afc07,c38e1aae,16dafcbb,b7c5097e,4895a789,e70e0993,cbc905f,6ba69303,24adb3b1,2fc1f8c7,8ea58729,5115adad,52bb1138,7281b9b2,997fa597) +,S(f490bc4a,20f1ecbe,ac2dbbd0,56f2bb77,d258a914,9b0732a,f29aef2f,7ec25f47,aec6fa89,74c124a6,576475a,60931a6b,533d0da6,4e621fe9,c298f03c,a894336) +,S(73b2f8d0,e91e2516,d2ebe348,85b973d,4a0c7919,1ac857b4,74f713d7,348d343d,9dd7a951,efdaa060,19ec71b,e41b294,d047ab97,d0cef4ce,25a607f2,f11bbc26) +,S(d911f5e9,977489d2,847aeb66,8c3cdc6a,ffbc7b5f,4a5aff62,1761ee01,567c5647,3ee4afd0,2ef6d3af,a2b16d34,b59444a4,2c70b3d,4db17788,ad3aac57,184e02da) +,S(87b695f1,5c5d7852,88218586,96bca8c1,9c5a6f3e,f23786d1,fe010fd,d063b0c3,21b54a,46ee82fa,bb5ffe0,e3137892,31623502,9a8e0505,645a9ec9,29984895) +,S(39de5a90,4ba6989e,5d16dda,a7ff67b2,15e08f3f,b593d7a8,4b6babe2,ca25c658,eaf5e6c4,1e1e2fc8,c1581f6,211bc8cb,34dcc08d,58f570a6,e6719626,7124c019) +,S(18c1f673,ca19f805,c426162f,11e7eaea,c675974b,6b4cf0f5,9eb03288,83bb0af1,ad1690ae,65783091,27f602fb,93652b59,d7507414,e76d9b3a,82fef166,68b7aecc) +,S(8d70ebda,893e8d03,d15fbd68,67528b7d,308ddee7,b2620698,15e7f3c7,332d42a1,254be26e,d9e9009f,e4aceb8a,b97020a9,9196a9be,60777fb3,a9d1243c,66df1707) +,S(c32fa0af,ab39b1c0,c96852cf,8e2382e3,93e5b59d,2e83ed50,d5307a0,14ea330,381e8afb,85d47c3d,dc5da037,d6bd82aa,ff2324ef,ab0e48d5,5da3fcca,bf0ee3da) +,S(c350235f,e5ad084a,1aaaee80,d156b302,d34ec03,360a7c0d,3a883cb5,19f4b27,e5ea7c5d,3184e9,b62fc3a9,6c8bb9ae,72535fc0,497f1b58,67bbae06,672a1f79) +,S(8ef5e1f4,8d905df,dbbba4b2,d4b22162,db839ba5,b28c755d,46bc2f00,e25e20d5,6300d9e3,11971dd8,a3e88192,84f3a228,9986270,45b901a1,80f831b2,4153103b) +,S(9b3783f9,c638a6fc,166aa2a3,3a40d95f,35a4e7a6,c8cb5fb5,1e596b9a,f285279c,41b2dd9,c3abce77,fcf798a9,159f36c8,94b55ac6,7c917de8,75b18cd4,e70dcaf0) +,S(c262215d,720180ac,669f0bb6,885dceb1,2c941730,93e561c2,660a4a1e,cdf0a244,7fea7ed7,f654741c,c67b12b9,f115aa40,ce427cb3,8c6498f3,8bd291a9,d73e9f2d) +,S(bb72f723,f0a16f09,7716272b,b905a111,c290c229,94f400dc,c6a24814,f41816f9,52a83ee6,53214a5,3ed2b13b,a367324e,e5606fc2,e3dc05ae,7ce0cf05,ccd6c36a) +,S(d896a5a9,a833d66,51b17632,70b03d36,eb423236,bf3b2b7b,6b2ba97a,f9282a03,e8a823f,ecec375e,280e0d50,49625dc2,1f48e269,77ab5eb1,b467d3e8,a0fccb37) +,S(198cb33d,9a2b790a,2d6fa355,58733bc7,f64cad76,e3921dbd,8d7a1f,8db52b64,c7e93702,ad7df0a4,94fba344,8a8157bc,eba10ee2,8f66f000,7e7f7655,8e6b4a74) +,S(4354e475,81d63d84,df19bd08,d98b2315,67a55550,477e1c53,cd425854,e67cd81a,a612c262,74d79c46,89734884,5b87ef50,29d0f87b,4a06e4a2,8ab36bee,ae6a6ce3) +,S(d956c71c,1c8b110e,19f96ffe,5709f2b2,83a095ad,977878fe,287de35f,283b2606,7c029c97,9a807375,bb589c12,a20ce37c,75178be2,5d5af713,f4fd4070,429c8d0) +,S(2c04b299,1775ae36,ed7d5b1b,d9b0e65e,fb2bff8,ab99dc97,2cd860fe,19b1789d,8b3f3b00,6d63c81a,86f225a,bd8e658d,c9c4c1d6,6787678b,6fa4a692,bc7f78e6) +,S(c7897c17,debd6456,a81f8d96,c0ea580b,db5daffb,5fc8e8e8,9c8612b3,7b229f7,f7334550,d20a1a21,c422f73e,d23fb159,2fb3d9b7,ca61d7b,6e124fa4,147ea63c) +,S(3b37b93e,ff554f0c,7e7f36b1,864ecb73,7b33a93f,6ff31d6,9ea18aab,a9487505,50ccac12,e071f469,3f5e5339,462a0cb8,66bde539,5842ff44,620f7acc,aff09a71) +,S(4584ea49,8a2785e0,b12c86d5,2b839212,f21b2e33,3b64bb0a,9713674e,66216547,2851de5a,b67354cd,6610dd4c,91aaf4ce,b75c4c97,26d524d7,69ae0ba7,997ad79c) +,S(c0c971d9,f5644eac,851ae8a1,d87b4f09,a802ae07,32d9b5a2,d9589051,f139963c,83e07a5a,2b7614c,c064b4f,815b8a76,6df7eeb6,449fdd50,5c43faaf,b0bd075f) +,S(370e8fd0,858c6fbc,f479deed,f35fef5e,80cd2338,90d4b227,1867ea90,6cd15b5f,ef382477,fd2dec6a,fce439ba,9b341a21,17d6ecf4,c8c8d63f,b5775094,6cedcaab) +,S(ad402a30,99c5d5dd,c7ad9631,b592d5a5,862e8d3b,5ed47dfa,c288193d,69366625,b8c0d468,5d0eadfb,9f7e4ce6,11c61f5,7098da29,aaed61f7,6a50961b,b45b7c5) +,S(ec16de3f,32ea8f58,c1dc93da,d1cabecb,5ca33ce2,e3fa3bfe,bf0ee989,f3ebf5f9,aeec3532,c5391ce6,1e23bea4,5b7b5847,2c36cb8a,6c5f1363,e457c003,b18824fd) +,S(5a51f9d5,f5c48520,dbd826b9,49f62f67,c299a228,259e09cb,b3bd6fe2,f4b0e60b,3c498d86,225a83a1,f506eb62,a2e530f9,511c56a2,eeed77a4,18ddec4f,4404b9f5) +,S(9696865f,64523eaa,456ea65c,40ca6e0b,12c6e6a0,211cf8dc,20963f03,7980b684,8f879d8b,491f11a4,1f0025f7,b35dc8e7,c71e420d,7d7d9001,bf5da111,9ad6c2c7) +,S(80c43c8f,6325cc30,8065d4c8,6e3d7bec,6ed85f74,412f6127,4fc3ae49,b1e185a5,31dfbe69,a48f1f39,a0cca355,f3d68f28,cbf3e14f,7d47cfc7,d9e82e25,19bdc292) +,S(54940550,ec4a6ca7,561946c0,65769b4d,d4683f1d,11dfda66,4aa2f8cb,8f1ab2d7,f41aef26,64466fa,ecc076ed,cd383d3f,132b4fe7,5a17f16c,c394b6ec,e4079378) +,S(a9787f8,42b3549a,9a3bea8e,4182555,99addeb6,416118bd,901afd9d,ad4c134,4efc4f67,65c7cf5,ccc2336a,e9eb14c5,a1361067,7632ce89,68033d57,4bc686b0) +,S(fa83e81d,63b85491,92e800e9,7a422ca8,35c03bb1,5579bc05,bdb4367,198a24da,779940b2,ad301a1e,205c0504,fe3ea104,cef6a459,e0479849,90fc94a6,871954eb) +,S(ae9a8d1c,a8a560e4,8a373666,544a7b9c,84bf0475,9de1a63e,4a20b55a,2f25c132,b9b0bd66,4c46edfb,ca2a0bb3,a94ff043,c00c1441,9f1df886,2aaadc02,e25017dc) +,S(a2f47145,296dd22b,3a6f5185,47ab0957,4d3487b6,8786f87,6758cbe3,5f4c0ae7,2ec4171c,15e7a82a,f6ace24a,60176f7b,6239561f,3c369a9e,efc80d52,3fd216e8) +,S(1bdcf82f,a7dd441d,91332a11,35f50be8,4d275358,f95df300,25187f2f,9828f219,99f12980,92a3ecf3,dbeb290a,67d72aae,6acd9cfc,c21918e8,9ff7ad4e,548d3510) +,S(b73c91e1,ae33767b,11bd329,361fdae6,36642d92,6c2792b6,e19b6e3f,947a5be7,b6502357,11ffe955,be5798d1,467eafdc,94df5911,29d2aaa9,b747a2ec,befa9d7) +,S(b23b4ad2,e983e556,e941a35b,b84846a4,40cd25b6,82487f37,a3a30eef,eef15d1,7010f10,88749d1c,f95e52dc,eae1a379,b87762fb,55593d32,a65ef0fe,dcba2485) +,S(e3aad2b8,96fe34ef,9d775743,6e70a70c,b3bb0c6b,8436e616,a23174ca,985fd8f7,5d6edc38,89beb099,dd191564,eaa83c14,3ef0b74d,7789590c,d6083704,61c6676f) +,S(2f22a14a,f69e6257,b909e3a9,50aab3ea,dc09c281,ec52e47,8c578f49,68910244,4ab723e2,43c71baf,d2aead8a,479a1a2e,fd2aba74,800b5eff,56ca46d0,532e81d7) +,S(93806026,554bae5e,9b91f534,f864b79c,81e581f7,bdf3b2ef,dd007e32,dd6872f0,800f8162,a6836801,d052871f,6892ba33,b2f60f82,89a658ea,a8af25fb,f9d9c444) +,S(8895d121,ad1f2be2,3c578faa,1e33656a,e9403ddb,a1f1aea6,1cc7bd03,817a46d9,4f7577d2,420d0d0d,7cc9ed68,ba3645b8,f9466f59,570ddf16,ba168de2,8cfec881) +,S(1838c15c,3bcf1189,546a9e3d,69fb8a73,de39c862,f5faa4bf,423e1dbd,29046ccf,49484789,1b67ea0e,2e7f7eba,4a596d66,b3ed9842,3ffc54b0,e9292a4e,bd6f5487) +,S(111e8eab,d9cb3ec,5eb63cd4,14ecf59e,3a3f0d56,70959226,ec8f203d,947204b0,4ab9b3bf,dc853571,2c0db9e1,5fc2832e,4560e420,af96b043,e587d1de,d996e38a) +,S(80369d1,ec5ab7c6,492db1f9,aa2fa368,ec083d86,75d6c1,e7262e73,a612e493,cbb28c30,db7f7d03,6b8dda93,7e0c4e18,6a09f1ee,2407e55,7f6dc54b,a8c0553) +,S(903c9034,dbd3f982,41351979,c9306a8,42b88892,48cace15,c3e3a8bd,aafe1ffe,d55adb43,d0142740,71499c92,e9b851d8,e6ece26f,f82ceaff,ba63a003,14960f38) +,S(d6490ce4,74bd1e80,82c99e87,a0510a2a,c2c2772b,1921cda7,dcdcd5e8,6ecaacc,85a1fcc6,de4b93b8,b2314da6,31d7abdc,f96b22e4,b44a5545,f274f941,454e98f4) +,S(12f2342f,aa8b19a8,bb0e080b,2ed3487a,14ddd1b4,83e0bfa4,9ea08484,157d5306,eee0b9e4,30a51a3a,49da893e,50360ba1,21660b4d,ebd3ad8f,82805416,10f4b7fd) +,S(3bf1ef66,57bdcbba,a9d9a23,36c75429,c4df4a86,1d71a767,2d7e956a,deff234f,fa98467e,83dd1ca2,2a85cd8f,f12be1f,53d5a939,352f4046,a626a208,601ef6b5) +,S(d0d0f8b7,9a04ac8e,b6e010fa,3608926f,3b5bd886,f84c361a,8e1d9dd4,b01ff717,9bb32b90,6d7de56,c75bd202,b9353128,b6440fb,42dae8e6,74ade0c8,fc96386d) +,S(19507738,80caa9c1,f042f8b5,d1594a12,161635b5,a83e4675,35ffe51a,fcf631fc,9280d033,f7a8efc3,ff22f501,6a6ddfd2,f78159bf,1f13be4c,f758b150,21126ba) +,S(f4f50c3c,eb750a04,95973b47,53b96ec7,22cef833,f4ee7459,a51f884a,f9a251cd,41f554fa,d3d521e9,65fb0768,66caeac7,d9f5c6eb,ba7ba7b1,d1d38c9d,c06d85ce) +,S(8b669c9e,22452528,57e20692,2726f045,e97b8cf2,1154fb74,e199f49d,11951b84,550c47fa,c46060df,4d893afa,9f08713f,cc8e719f,a369e90b,fa8846df,7938c65b) +,S(941cb4b0,31edf346,64dd5e7,92ca135a,1d6cc6f,55341322,66644493,aee5fe32,cfa91a79,29b3b47,d73b8ae6,77cf64eb,cacf9408,3cdc76f1,79e25631,d574ff68) +,S(557e36b1,27307c56,72232c6f,6e92e4f6,f5da9d22,1567b464,8e79d97b,bf589023,ab741e35,109a0313,e7adee7a,2cec2c10,79d18d72,6c27f1c6,5a808b98,8e99b523) +,S(d8081ed,9e7cf1cb,e1ff07c0,b8ef3f9c,c7eac02f,1cf1c6ff,833f4b74,b2a33269,efa297d7,10fb71c8,43e358f3,e04ac308,53027f00,eea43d03,9b87c3ca,2b0fdd2e) +,S(b5e4fdf0,7a443146,263f6539,f6c8d991,7486da78,95b4ba7,fb4c9f14,78324d44,a3ef979f,93ec1a0d,602950d2,ddc400c8,4f018643,229cfba8,7cd9e3,f2fe657b) +,S(1a573259,a5100c21,d75efcc4,41d5a834,a81d96b,f4149731,eed4ae67,508bffcc,8a993dcf,49f94f6b,bc71766,9d37ebfc,614a45f4,1d70a1ca,f4da8834,5711223d) +,S(33d9f9f6,c9ba653b,f9c52166,c29e9c06,2cb7700d,ea2f40cd,28520bf,237b4558,dc80f57c,fc0e73ab,bdfc4a8f,f7e8f4c0,3353e889,bd54cf84,6361c1a9,af5a0a79) +,S(e4ca84fe,307c9237,4d39b2bb,b017b5b9,e478b26b,95236b8d,5bdfb220,f44419d,c0cfc7d8,92271c95,7ef235f7,2f310c7c,7d0ac297,97d42ffc,ba37061c,83775507) +,S(8f1f2d2d,cccb07a2,a8716b77,8c74f3fe,22990d36,b951e6dd,92f5896f,51bc23aa,9eaa792b,426d3400,31a862ca,b805d0da,ed9a4c73,591c204f,c5179b17,22aef870) +,S(20f7f6da,86eb5ae6,6a1b7818,43fd7fe4,c458e3e7,bfb590c8,76afb601,257b2ee0,6dfcd6c3,93e7e9dd,32c7e826,42f90d69,ff1e1ffe,18988de2,bc1cb9ba,db246fbc) +,S(3a3df365,8d65d718,2dc05797,8bc48fe1,5c5eb6d8,6bb241e5,9e178ca3,9cf9a010,ffb89791,7435e8c5,4865bc79,52fb7bd4,1578af51,6f611c54,1f7cfd5,651b293) +,S(7aa435,7dbbc5b9,a01b5f94,6b0240a1,36daa942,1ae1a1c9,b50f66c1,c7f15e48,4640c8d1,ace8f69,6b08ba1f,9a46d04c,f75c5914,3339d5a,181a7dfd,bfc92c0f) +,S(198e4848,8176664d,40fc14c7,acca9eb9,aa22599b,b2370959,5856d78b,5e932e94,fb9dcfdf,b27d062e,8ea5246,275d80e5,6fc7cb09,e81bf066,dfca888a,8df1de6e) +,S(25da8876,d3215051,75694915,c25056e1,2c1329b7,7795b7ec,1d4b66f9,3c911cc9,b8cf4a83,db78787a,6d80a157,c7c205f1,3664a71d,a6e78db5,b52b012b,930c4583) +,S(893d2e9c,3b6fa8e2,136994e6,14121842,bb82e577,89826ccb,eef51fab,de32c0b,d7cb9b4a,1d49b34b,f3f743f2,10c32a25,cf8df45d,8552a7f2,1268e270,ee6fed67) +,S(dde2e8a2,988fd777,4959457a,5c14384f,c8248d1b,a32c7ce1,a727af27,7b217688,1fe0272,137e4c9b,1c6df618,41a240a7,be3b5de1,7b93fa24,ccc055f0,e7972b1) +,S(52a73b51,5326198c,81bd988a,3033e1db,abd9ee27,9a91a434,e7a76813,453e27c1,c23130f,c4b8990f,ee308443,1cbeff25,62963b1a,4a5acb4b,a1319b4e,d77c745b) +,S(1b5afdc6,4598bfee,4ef31904,f0d06796,17b0149d,ac19e7ef,a1d4f19b,c5385490,fcc0c62,47d96d4e,430ae0e9,c19dfa2a,3719e66c,ce25a2cf,d7428d4,4c91e96e) +,S(76da558b,d533e761,4d97b7bc,5a1a98d2,af043ce1,1f2b323,185377da,c0e0abf0,f8dfecd7,94b3d069,ec22f01d,8418bd90,27c3dfc0,62beb597,e352bb70,271d3cee) +,S(17f01b77,d2417d97,e3c14f10,18af67be,c12c31a3,58521f6d,203f101b,227cdbc0,fe16d66f,a194c800,e3c14bb3,f1df0a2e,3ec319a8,66c69d9b,3b492d96,327bba04) +,S(6010e0a1,2cacb745,6e3a8f73,d5219a87,cc14dae6,54be7265,ffbf70c8,c4d5433,7d5f0faa,579afe50,2541a2de,4d525bd4,e7b950fe,2b2dcdb8,d67d3d9a,7b11da54) +,S(91e938c8,3f319320,baa876fa,23773a7b,d0fb81f9,bf9d99bd,13180560,bfdfad6f,b662f401,7a4fa2ff,6603864d,77a6b930,181372f2,5fd6a67e,12a1df6b,f75509ee) +,S(de2ef2ee,633355c3,3d259357,efca96a0,5b669f13,b515e64a,c0bc467f,2abd665e,d3d6254c,5c30daf4,64843190,7c2a8c1a,51baeb23,13605a58,b88c9a78,a6147c73) +,S(186151f0,dc37e48b,3178bdaf,900e7bab,49cf251f,7a2a1b8a,76da8750,2dee93a6,2a240dc,acbbfc19,876c3680,fdbd7ee5,d1085b79,96317e4f,db73d5a1,9f097f8b) +,S(6f19619f,ace0c63c,4dda566a,9a1e78f,a9568db1,1c46f3e9,771756b2,7d8a5c1e,4716efed,7166e06,722a744a,af89d145,4ddd2f0,f7652862,cc38eb3a,2beb1925) +,S(a0e450d6,fb8a6da7,e8f6e62f,7a08c2c7,277a832b,4e5c6dd1,8cbed37c,37db23a2,775223c6,3f81b2be,1bdf0831,9ed65ab8,d3e11c56,38830851,d55a8893,730979d0) +,S(6337ffcc,64f5d358,d90fad1b,646d8d7,46e2fb7a,2a6cc378,9b55ec52,3824de5,98286287,578bfd97,4c161a01,55f9a2ef,707858e2,a32c3fc7,319416f8,5a6e5427) +,S(914a8565,cc1bcf80,19e1eef2,87c9467c,bc42faaf,726d4399,6485efe4,6f99e32f,846c42d3,b1dd8c20,3a744f5,560396e9,b9a92380,2fccffba,c6ee22c7,65bffde8) +,S(dd79a02e,2460ef86,cb4e9ba8,3ee7e231,e99b3303,1d4a6d7d,6dee8b1f,b0050daf,d6a75b67,ba13f76b,172ae0e7,d63b20be,db3e54f9,e54a96d2,aebc326a,131ea271) +,S(b2776e23,3e759f8e,38c52394,d50fe177,c6842acb,f238eb56,c7638549,174c1b2,e18c89b2,dbb6453f,7b610518,8bf090c,f0410e51,97885d52,b50b2507,ffe4dc81) +,S(e0716c4c,c5e84f7c,282adc42,f294a36b,56bb26a2,58cef4bc,c36a7f53,1d5283e1,1442ddf1,57491db5,1692c7ea,5c92976b,8a2488b6,6aa6f38f,7a62946b,a24fc5bf) +,S(2b10c9f1,bfdd659d,9d1e073b,faaa4b13,2a08b678,f757ef39,a137e53c,b291df70,7d22ac48,f4e0aa71,8cf7882a,57a46746,94e0f456,f2cc3aca,30a3f8d4,2b240dab) +,S(fa762181,26a4813e,e97f2718,c6eed96d,da9f6912,ac463af6,a52f3aff,f80f07e4,8c8a04b,f38e2599,4cfd8905,27ace017,e57e3f8d,d378b205,2e767954,80dd5701) +,S(6b893eef,bea81e30,7ece156a,e79abc26,d9f0ca5a,b2dbde11,bb0d8192,f138e58e,510a308b,9fc47167,f72bbc4,f92eebb9,88a6512a,b1679102,f9016b0b,d82c559d) +,S(6cd9b970,332f421d,1aba33e4,75f26a4c,5c5fec37,4a549ac6,d8c10fa6,cbc40032,b57dbee6,68bef693,67188a54,52e3b4d2,cf1c8c25,8e36bc09,432b4f4a,dcc24086) +,S(ba4847ad,40530fc5,f77ea79e,ef7a1c0b,821b5285,5ec4ab8e,d238ce46,48a09fa6,627ba437,8e0f2044,20e61431,5f3d110f,2da9cbe6,2025bbdc,5bc1cede,c36030c9) +,S(92837329,4f59a142,ba84f897,7acf2e7d,9df06a27,74ad88d8,98689900,3750c513,4e938012,b6e55d6b,6f7871ae,c34511c8,40912a1,1a32012f,3bdd27b7,90f86c37) +,S(470c19f7,9aeb9a7a,142ba010,10ea4929,3de57e25,68658d45,42b5a626,864600b9,2e99dcc4,b93d9a36,7544b842,ef4a3085,2e24bc41,e98ff2a2,d9aede05,da703225) +,S(2496996d,c38e4bbc,851f9bd,f9a21b42,5fc7ce2f,2b06993e,97604a0e,db555c34,b6e02a63,f0e2e54e,1cfb9d28,7607bae5,8a68ae6e,a8300ee1,c1170f0a,9e567323) +,S(92366ed3,23ded4df,f4029e42,685c51fb,a8a916d1,999c42c0,a90feb44,4112a78c,88dc8af5,f6d1d14c,5c09d216,8af0e752,3fad76a1,5b311021,7ead491c,12b63191) +,S(ff9760e1,ce161564,22c4962,4962d89c,37e66e64,cd7f8e94,4125fd00,c05974a8,8ca4457c,a5e52e23,d70639c,a9a26f3,12312451,8f0de070,86d385b6,777a63a8) +,S(50d1d5ad,79f919b3,d23c16b1,428d971,5deb186f,2b92b64e,7a1ea1fa,dfca4981,ddb07de,d4ad81b3,cfefe726,33521be1,c7418c5e,aa759440,20dfe92e,b4653ce4) +,S(4934f753,29844b23,80183df0,254d1c7d,342d7d27,9fa5e804,68dbee16,4e9c2c6e,a4f8aba6,7a488a33,40e8e943,14f7eed,5cc25487,5acbaedb,afecfc2d,5405609a) +,S(d7b99142,9cbdf755,5cadf030,7b2c4a91,c0d25710,a0553511,eac6afb4,c544ff81,17bf03a6,83b1a0f2,366b944c,aabe57d4,eac4d86f,bfabd006,66693983,e0241420) +,S(834b036c,145d6905,58199bc1,e7a7bfc2,4831417b,530b0b97,8cc1fc16,af00b966,4a45a9eb,299f24a0,1c520751,2cbee44c,bfb75d0d,14a7eb08,b1668b58,ae58c47d) +,S(d7a8c30b,fd7b8aaa,78dd23bb,86ef2624,5a363857,6ed69739,25ea9d9,194bfb3a,7b5f9ce6,380abb91,6e041388,13baaf24,229ece27,3541f4ca,2883ad77,9e501fa6) +,S(ea4c7ed2,7ced8b13,4a2ccb2d,3828d29f,f80c4825,e5607597,3faace04,d2fb7763,a8454c9c,be19ec44,8a3234ea,97b8fbb,b256a148,11ba0ede,becd8641,42684d14) +,S(a2cb70b,f80d9f6d,696ceaf8,fe8052bd,e59215a9,99d4b92c,ce806a19,71d555c,997bd94c,e5cb12ff,886c1cac,bd21c3c,e2f144f0,3af644a2,c2aaba2c,825f75b5) +,S(89a91f5,c7c8700,175ab017,8c4104f4,a927af06,f269645,36cb78d0,19f8b8f2,6a2f8ebf,e1258b4e,31bf9a5c,31c51a3f,1cb58aea,6e18582,3e87920c,3df8e7e9) +,S(27d7191a,71ecb0eb,71b43dfd,5840079c,bd368c0,5ce62fdf,2967dcca,78f5a6d6,11120002,d0d0fa9c,8db51506,4e1fcc2d,92d8fa9c,8b454294,bfd01c64,889d5e6) +,S(cefb996a,d36deffd,c3c7ddbb,11a5013b,70baa98c,1057adfb,185b4c9,62f3384a,c93cab46,7523b0d2,baef4425,c9ff048e,c586d4c8,69c69cff,3ab9d72e,e3d80f83) +,S(5a8ff765,84746f42,4e06b557,77986825,e91312c4,4f79003d,c1b381cd,4fe5ce8f,3946177c,3c741458,7bdb9506,85ad0c73,b422a8b2,5cc3ad3a,cd486e76,99a42f08) +,S(b179dac7,d2f400bc,bb039f32,91e813e6,f9a7331,80a1a5d0,db51aafb,af582fb6,89a70304,d70cbb61,ffb3a499,1815cb17,458404fe,e43f09bf,d630d480,5978b1dc) +,S(6e14a53f,ab32be84,4eb14242,a3b6a86e,e178cd7,51dbb7a2,b14cb763,ab2fe6de,a22ed4a6,d98c59d8,ca85e111,cce0efcc,60e20df9,6b06615d,69aa3cfb,206494b9) +,S(12ac42bf,d8f919d8,c79a8138,1aae69ef,b789a573,f58332b5,79694dfd,27e7ff20,4ebc3b7e,4b0136f5,19a8df5f,baa7ff59,17f4f632,f85ab1f2,ce502fee,bb3a3a87) +,S(87bf22af,5e9dc061,eabb01c4,eaa867c3,4656599e,da744da7,774fa8d9,aad68630,d34f530d,fbea0d52,9d2d64d1,323fa44a,d80cbe01,fa2806e5,ff069e6b,fc0ce729) +,S(33fe6bd7,ebe2b197,76251415,8bf866cf,b6d3ad5e,1f68519b,edb513fe,6076c96f,c5970cce,f44aa84e,f95a56eb,588b7a8e,d9164f5f,5a2eed83,1f70d308,2320e9e1) +,S(5fc2f44c,fc0f7ab9,9f03b67a,d7b6ee99,d73fa9cb,d74eb5ba,6d931d9e,26ba51af,8b1fbfe9,de201400,6c07da02,4bbcf53e,13bb9f2b,ff3dd6d9,5135a6fd,5842f0f0) +,S(38fb5cfb,e4f348cc,1fa7f9b2,ea600daa,e8330aca,53308f09,b6a7d8b8,5ca8a88b,ac1bf91b,7f53e824,d845c0f6,9534291f,cec2808f,95acf58e,4afba07c,fc735be9) +,S(3ec2457f,fc848504,6f74912b,5c58b270,1be6eeb6,f88da0b3,c5cc4454,48750875,b63209d2,641c65bb,7105af10,61d7513e,409f153e,5d1b5073,232eacc6,f76dde22) +,S(32fe812,e67ef62c,687d248f,e75ef399,48fe8ae4,a01ae10d,ed65264b,fb5050fb,d9c85369,db22ddeb,baf7682f,53642962,cfec2afd,3a20de77,588e7473,18044f6f) +,S(97d7c69b,2aa0277d,2b20e9c7,bb1066a2,be6f443f,d0a428b6,d78c5fc9,6ff71b57,f84ba781,70837aa1,f75936cb,fc50c444,c40c9fa3,22d90088,ac6889f7,e7c0f861) +,S(3621a4af,4d698e4b,60e7f497,6e0c10e9,ca32834f,ff917aa0,6aff912b,2ad80cd,22cfd248,a17886a,ae5d0e11,53621e9b,46289acc,ecd8155,a1bd6372,120c4da7) +,S(ae79a6e5,848b1dc6,cb64958e,87b737c1,858442b3,63d4a2,e9f04561,7d73f8c7,c147238c,59885f2d,dc5dec63,de421eb1,c5a19438,ed0600b3,4c77f4e0,e7aa557a) +,S(36eec623,700e51e7,723a632a,55370ddd,d6b1f917,6ea39a2e,54a2a1ac,52598c35,29698c0e,56b4e2b5,5389dd9c,3d8b509a,e0b87f99,4872d865,3fc74269,7f5bb7c) +,S(50f70061,804dbeab,cf2ab4a9,87ebde2,1f5496c9,a4cd28a,4dd9da7b,310e876f,77e27710,edf831db,6ba9e64c,545f03a7,eb390842,8d9cfa3,3d0e1c87,61371706) +,S(c2ad6b2d,e84bf60,7fe77b8f,a9fe26ff,bb5e1906,1494e469,8da44a33,25843844,17b92ad9,d3938fef,7a17f543,a169a7ad,8ee65dce,36eeedfb,5e3c0c8e,a1b24fc3) +,S(a53504f,e2286269,427fd2fc,fcb64827,bdefdfd9,feb89d50,12651d2d,c60ae99e,6b9d73e7,e046d11d,ce78b114,8aea837f,770d8267,6642dac8,f3b3c035,c10eab45) +,S(5410db61,40a77b31,9f19c969,34a8364a,4881ab60,ad76a6c9,34f317c1,1b658dec,ac45bb6e,2e5fe23d,57297370,cd04ffdd,dd89a9,15a1e9ad,15d7f9e7,6d8b3aeb) +,S(882cbd69,fbd3e262,5093385e,ab82fc9e,7597c38e,45fa5df7,f98c94a9,3bf25467,2083f00,b25b28b7,f92b040d,a4294dc0,8a3d97e3,d951e724,da0e692a,5737a87a) +,S(3141e0d1,22b4c136,f7793c73,9c48f308,c5ec8043,19db116d,64eb14f5,aee83942,9c2d06cc,d765c6c3,cee09b70,247f8806,227d0178,13becbb6,96c5a344,b68b33b1) +,S(1b2f3686,5a63df41,65caea4e,305d8d66,1de6ccc1,c2a28cf5,2373527e,27cecfc,1239d8c8,d60fdcb9,fcf3f5d4,63305037,6d47fd97,4cd6bc64,99e0e951,2d2209a9) +,S(725168cd,9fd59e41,14918b77,6ea96fc9,6315b4f0,86672dac,1eaf59a5,e61ed25f,946f03a9,84a6735d,e72acb38,dfd21905,fa2358a5,e66e7b0a,2f8836a1,8f5d73c3) +,S(4207faa5,c9dc9622,9644df1b,a099a84d,654ec6d2,aa69efcd,a4a31a3c,61f2e1d4,ea72a92,836d1597,5275c18a,900c0e7d,d0502610,d97b6f79,1f6a28c2,1b3ddfd7) +,S(53900d38,a4740830,a6129a11,9dc90f6d,30f32847,708d48d4,20b77764,ff5b9cc7,66822ed6,ed941eb2,20aefe94,4325daa7,a619dfed,5c76bf75,1fc25342,8178d3fa) +,S(d0204932,a3fb8d33,9779851c,d69f6adf,be1a9957,59fcfce1,b8d4f047,e4e4dd2,8ded18ff,bbfc663a,9c658ae9,286f82e0,9ee9381b,3291f5c9,efabf0d5,fae318f) +,S(3ed8ce15,2d34e621,94b8b16d,55605766,41fb2673,14a08c91,d916fa14,f21abde5,48490fe3,9769c60e,38996370,27b57df7,230060c,2505f414,5a1c7f1,4ba16660) +,S(b7d57614,9b5e2ce5,edef3c30,b8cce79e,6f122c70,351d04fc,ed2b67c7,f5cb2aed,7c8fc1c6,bd42b25d,d45e37c2,5cb06f0a,bd2f7051,4a50e6e1,2a67c0b5,b199eda1) +,S(2489e06c,c8f0bfed,9d5ea722,c07ca795,e9ab40e5,45b036e0,f0c11f28,53c0d35c,dff65f5c,20766078,9737f1fd,5af05ce8,3b8edf91,37002b19,f5e1599a,e76c48bd) +,S(9b2140e5,509817c4,465e6689,a3bdadcf,b79c1803,883d493d,4e4e99cd,55f30a29,86374501,705fabc6,62e8c869,a22d2813,f7106006,ee09b6bd,b582b690,50186688) +,S(48d6fff7,d5c37c30,11c9e63b,b3342f92,776060a6,dd179e3a,e2c6bb69,d2f88b3e,783353e,adb6daec,536d37dc,76ae3ff,8dce14d9,65d21d3b,7a17515d,7d3341aa) +,S(35d46a17,b6951355,a055e253,42b4244d,8ce65459,c630f2fd,4708687b,e6a49e7d,13bc21d5,7cc2954,62927cf8,bc31ef3b,5407021a,62c5253a,5950e8eb,b9c735d7) +,S(17ba438,24168f06,274b2f5a,d080fda2,3c0dc34b,f77e81c3,c4413cd2,f594575d,e8b34f9,1ef09f92,7b5d9e51,662216a1,30ef8f87,2e0febe,3f5cce8b,318fc77a) +,S(2a09e4bb,4f6d6b40,f59d0299,93eeea7c,755eb00a,5eba0477,3fc0c796,aee68a07,cbe72772,e5d8b761,15ed6f92,f20028b7,cd06aea6,74e10667,899e78a3,df403f0e) +,S(f3838250,e9a03da6,87139583,2bc6b35c,2d427b60,4cb7d25b,149b6816,235b0e4c,164b211a,60562190,d415bcc3,87d1a147,66e45f14,dfbeda44,833ce45f,b815598e) +,S(b307de85,c4c2e8,4e076d19,647bd205,8c1a3c96,a0261481,322e73f9,f4a2e94f,5af7f6f5,ae7f65cb,b62f021,608473e6,b68d032b,4835540a,f265049a,e506b2d8) +,S(ff92c7ba,5f89d3d4,5273688,907ab9bb,794e5622,f8f300fc,804934d3,b5820e00,3b2e2d1c,420fafaa,e53c9da4,957e22b2,bc76ccbd,99f323d,763fa1ef,f92ea71a) +,S(49630ee0,a8ddf91d,ea678a3e,1dcb623c,688b7c3b,9e39196c,b578d30e,196e63b0,4c1aa073,d1375475,11d81776,e2e59404,aa08db5f,95b80e56,c39613be,fc2bfcdb) +,S(d41ead31,f2fac884,e762ccac,85825cbc,6ab2f8df,a069b2f3,fce3c6f3,d5c95a33,f15e3e23,e19baea5,677390cb,acf97180,86876f96,50fac740,9b6e62f8,b6d40652) +,S(5e62e95d,27ba07d0,781ad685,75a7a11d,df9f2776,48cb5cb0,869ba586,6ff02869,291717d,1a1ff532,e92f0311,881fe2d1,6c8844a,6f5ad7f3,b1ced51,e5088302) +,S(dbdd4f57,1f6d01cc,8a1025ce,3b92ce3d,56d396d9,635e456a,fd856239,27b53bd5,b929d5dd,816bcdd7,78abd34b,c15f2fb9,deff3f9a,aa44de0b,9f7b46d8,b8d70373) +,S(63a8349e,1a891037,9a74a60,babb68a1,4c8cda6f,c2cbc0e2,1a5aca7a,fff7a19f,38858c42,9cfb1e49,5fc90633,ce07abf5,b7c4a4fa,22b955ef,e2c137df,143ec70b) +,S(1805ec70,2cbb1e4a,5da4841e,9e24afcf,b84a3e45,dd6c39a6,cdb6a661,d5c6b1af,193be01d,d3f28479,e352f164,de99d21d,1b3fe8c4,b0af8587,8f21c858,cdadc27) +,S(2d6ff24d,fcfeddca,ab3b19ec,b6a79793,7f5c5d3d,373b9df0,6ec68549,6d075423,b8bbca01,551b2b3e,f6ec3a37,ff020f3b,6b1f5456,69bd8b90,f8a55216,3fb48fb6) +,S(3aa21099,52cf0464,4bfe5de8,69cb2d4a,19d3c4c4,661d6782,967dad8d,cc353a24,68252574,69dd7940,fbdd26a2,483149f0,f71a4b12,fd25b063,73765c52,d45985af) +,S(d6422a71,443b0e37,cbc06f90,4ba1f62d,c2351b7f,e4e0b909,5fc227a1,7f8f551c,ca92a69d,2c9aa758,46c2518,f1ae03c0,d7138170,447b55d9,37108604,f71b9feb) +,S(51e297bc,46529246,a36f8460,f285d713,b1e9ed67,2027eb35,37806d5c,7e756177,5d56e447,63bde166,b456531d,94be0d,7057081b,edbbb89c,be8c4732,13eb0ad9) +,S(378a552f,c061e796,c9ddd101,63851ea0,663f09f1,3fdf852b,ddbafd7b,bf6c258a,6396c9f2,a26b62c6,f33b73fd,98824958,8cbc7c10,e679bd4e,ea0f4ab1,dbf38f72) +,S(bd85fb00,1db4f2fe,95c61f1e,825e65c3,80761832,37be8a86,a20f6fc0,7a586daa,52c21cd8,9bf874ab,7d7e0f4c,d0095d7,6e8c737b,e2ba9d1,a21fb795,d968f61f) +,S(fe68e6ec,3c8e681c,e7230a92,e8762f0,af3e206f,f3b0afe8,be61ab34,2ca076b3,f8683d06,af0c88f6,93a0a6b3,1200cd25,ea2c7e9d,2b8048f8,b983474b,b1dc20fc) +,S(83e55d38,bbe2daa9,f8147b1e,674be115,d919445f,70d2b3a6,cb917a4a,9ff284d1,92d6c7f6,dbbcdee5,8b11a244,34cbe7c,9f9fc0dd,c93f6fa8,b6354a06,5bf90ab7) +,S(fc9cbaca,ed0e1df5,e9d8120,6bb55f26,67e114e7,30347030,8b333554,d0735ad0,d41fc02f,2d4b3f74,f4e9ec00,7a879540,54d12fc9,3d53242c,a45bd38,c75deb9e) +,S(7adf7a3d,12268d0f,c2568d5b,ee296d61,fafcd739,f081e5a1,7b39fe7,40132b05,51aeb855,a84f377b,899392c8,a7daa18b,70ec2a94,7929c93c,67ed8217,41adaa21) +,S(e9631ea3,7da9e68f,eb61f9c5,6eb91bb0,2fdb4d58,d99874c5,2c4af40f,9716aa0c,51d5a6ea,1a5fffae,39c598f0,158272ec,bdb48c4d,faa93da3,89af20a7,d2a1b8d3) +,S(e892f70d,15639bdd,ab70739e,83ab9f04,963e1dff,e2bd81eb,e075173e,6bdd116,2e78cfa8,30b68c55,68f635f1,b260d823,55f38ed3,f5f43c33,b178be12,dc006b4b) +,S(6f3ef2e1,e8d4fd02,2533f4d7,410778c6,ccd9a7be,aaeb3c8d,d9f01699,89598def,c4388130,c278f8f2,7a9947ed,4948f8e4,febe81bb,88bf873d,2d565b4e,3481b86) +,S(cf24cd64,84b07e12,37640f0e,da7e776e,3d4db192,6da8e929,19b36383,15de412e,a353cd6f,a796c46c,49f34c72,64d36df8,6d53f556,a36f430f,7f3f6ac9,3527ca7f) +,S(a2e98e5,36d517d6,528d6353,8bc2be93,4eeae1c1,cd8dcec7,a60080d3,fed33749,205e752c,49a09b0c,8804cba0,62b28ec4,6d9e8f37,9cbcacd4,a7cc9049,47bfb296) +,S(e5ef194,498445cb,718f7c77,6aecd0f1,949a4a49,73e32ce9,a4915867,dc27139c,fc774f2e,1e51f03e,71e637a4,158a0013,5aef5a18,b15ef0b1,e5696338,82bb513b) +,S(311b36a7,1a1d13b8,29c78813,6a989c0e,1b7039d4,d75110b6,ba97f000,749a8d06,2f441c15,6b80f4d,51dce0d9,bceca566,2f3fdd9b,965a0d84,55f6d154,3a661f7f) +,S(324420fb,a5076214,9be852e5,ffb88d20,d1120e1d,2eb9c132,32bdb13f,403a5f6c,378f5d4,1dc1011d,1fd338d,b6073df8,903fb4c1,e17b2122,bdad5eaa,496965b) +,S(7cf4998f,5095c102,a0db72bf,9935ca91,eac814c5,4120eb0a,262f246e,ede142d4,73e6db13,d6db9486,fc870698,7be096f7,7440dd35,67064888,e61dfeea,e98c1fb3) +,S(d6fe26df,d501241b,f8c5e74f,e30714da,7d690be0,91cfbe14,68ed6bbe,23598f7a,102c4907,60fed9b7,239c0443,d01f2742,fed0a0f0,fd7ab9f6,9fb1c58d,c5752fe7) +,S(805ee58e,66ab8020,c9c32afd,4c7fe30e,960f4c3,ae51e94e,da9e5242,af09c6f,19154d86,59fb1837,3d0adf6,daedcfc8,3937af0b,ef9a7d15,f990f60a,c5457617) +,S(491717b1,f22f93ba,d0a3cce4,fac57160,8ad7a746,ba73d375,1713e605,8bcd8450,9c38b3e5,4c89d38a,2307546f,f46bbd68,d4e4ad08,cc45bcc1,575fd120,acdacaff) +,S(a8e23e38,27c54d4f,ae2589ba,cf3c4e1,93f97e59,b11506f2,2016fbe,a9fc2522,ffaa8b74,22b50822,dadd781f,d31b5a31,eb384c50,2fa0bc2,89252665,1c602f3e) +,S(9fee31c6,88b0f7f7,78a39786,a84567e8,34da7ffb,350cfdc8,95d65c4a,afdf69c4,2116e31c,2a0d25f6,48a3ab47,1c897484,d71dd9e5,c678af4a,292a6388,d9e45e94) +,S(6256ced3,f08f1812,ca7ad618,383f1542,baa2bb06,332d4c1f,72d862c2,318854e9,9ae0bbd9,d2fd51d2,9347aa62,12b6c0ca,be530b55,bfd8cf18,6732be1e,c66ced06) +,S(ca1cf364,a5e1f47e,cd0ab0e7,52e785fd,935b8c37,964c5654,2cfb3249,a136d669,17412d75,2f350795,30db27a1,7394c362,45fa376e,d20583fe,b9f7a7a1,2c3b67f3) +,S(19004a4b,28e5352c,7c74def,cf129ca1,cb5c7dc1,5099b37f,dfdb0d5d,1e694400,68ed1edb,9ac650b2,965a4034,2812a692,23b3cf6f,24ab0a05,2e1b8eba,f7335020) +,S(c605e97f,27199d86,18fca176,54e44c9c,8dd20994,aeae0466,dbdbbf0e,ffd1b3c0,606955ce,33ff7b6a,cc6de4bc,4ef80b34,bdf6ea17,b29dada,4ee54f06,f61e9d22) +,S(3e89970f,15e79b51,fba90202,a16da6ec,3d3d5d53,72218d72,bbed0626,31affdfe,5d9e27d0,bdefa8cb,b02ca682,a062ccb0,61a8fc47,b2cc72a3,9b687b45,5f83182e) +,S(c077c861,575ab0d2,944f8e65,8a9dbe54,9fc1172c,6b7b7428,476af472,e625d5cc,c01e7abf,6a3abe2,d2aa2457,76068afd,9ba78fb4,fa39e531,8155597a,90fededc) +,S(8567c87d,c12f1479,5f351d1c,807604c6,636c670e,11edb286,92552ab,382ddaa5,71f0be2a,12ebee63,8a63e848,fc4d8116,e2dcbf99,ecdb15ae,1f4ec6c,84f359ff) +,S(9f1b7785,7421626f,87978ee1,780d0,1e9d0b28,df34c2ad,15332b8a,d94d8dfd,6df504cf,66144d9d,ed530e2a,1436a4df,634a84c6,9de752d8,42e076c9,1f129b8e) +,S(f45c2c6a,2754fc31,c5770e3d,38b19e72,47b0dd1e,5ade8ed1,f2f3219,ea7accce,ee07ec18,8190ce54,e736ffd2,912075a1,128d24d9,b178a7ee,72aeb6e4,9b593f4f) +,S(51a5441a,f3446fb4,cc63ece6,c9650a87,2fa5567c,4918f5b4,ec8668c4,ddba6e0d,413186bb,adad4943,6abc46e9,280a1571,a97ed7f2,a839cad2,935675b9,d167a54a) +,S(adee3e1a,e9a2ab1b,da34fd5f,afd3b3e4,f51255f3,5dbd94c6,8efb994d,afdeeade,f330f0cb,973fd732,eda39ebb,82dcc589,4c148165,428adfa3,b4ff865,1ea83e24) +,S(a8946504,eb084214,d0153ac9,c3437fe7,3ff5696,16e01672,413a62ee,27c97db5,3dd63d46,f74a56c7,2cd5d45b,5bd6f2a8,d913300f,b4ce536a,e504d4b1,b2e311dd) +,S(e34ce586,990e48c5,febc2fd4,70770cf0,4c81c782,3702cb5f,289be0,f4a97205,d1774a35,cdd7cc54,dc68827e,f7c723d7,5c167982,c314dc62,bba17478,611f5854) +,S(7a8a5d9c,edbc4c76,1fdf2958,8289bea,d524edd4,f7cad978,deaeca8a,de47435,559d473f,3a9a7ee3,4ee0a1d0,4acdffc5,6766db36,94fbf08a,5ccef8cf,31e25b6) +,S(848cd57c,62c67249,d84710a1,5c7abc27,93fcba46,497a6b0e,b23c2ad,f8acaac8,a48424a9,59922131,31a763ed,30369b72,b331d9f0,cf46f8a2,a15515ed,6726f735) +,S(6afbce14,1f2d2c4a,c52e7e05,5ba6ea60,7612a590,d74a2a5c,1344cd5b,c49f2f03,910d69d1,cce10aca,bb1593be,2d4d4d28,9745f97a,29fb78a2,a1eb6f0c,a58e4b61) +,S(61f3727d,718644a9,2e08ab04,814c4446,c5dfae82,c26540cb,44fbd310,a5315a11,56665e3,ee6edadd,a154563b,11fdc203,fe4365d1,ac36879f,a30778c2,badab836) +,S(582962de,e00668e7,91741dda,8e86ddb7,b8ff7773,ac1ea51d,1aac139e,a810f3d1,6bd353b2,e004d66,f1e90cc0,7c68a0a5,b532e709,75a7bc58,7a6b1c67,71022f6c) +,S(5c4426f9,f6071fde,a9304e6a,4a2374a2,e2591225,28b62d20,5fc3016,c471b636,ff6e8c71,fccddb0b,5cff9e2a,10c606e7,c571245e,8f5bb5f7,77e0a7d9,733560a1) +,S(ee02633f,c6b41f01,c3c24c33,719db7fd,a9e04b1f,7070395f,e8898a0,efbf6af3,ecdab00c,83cb3465,1d48a696,6a8e4f03,ebecfba6,f73a66ec,4d62a668,48f14798) +,S(fab36b80,e5bba465,63c9078b,b727e0af,c9bb0af0,2e394f9f,2c90e0e,fe9fb816,75173a7f,f5599da0,ab84519,c7c25be4,1f10172f,fea39762,8e7dab7a,3ecbcfa0) +,S(68a89a2,62015a57,5f882215,48c6d3a7,b4ad1f92,f5665980,367107a9,f4cc37a,43ea7b7a,79397dea,c8354436,d53e7731,c94773d1,5b067063,b108c559,c05bc46f) +,S(fa6e2972,87a0e97c,35454378,4a76fb0b,56106727,136474d8,a3edf8b4,e03f95f4,1e80751f,9c127fff,ce28ae,8ce5afe2,eea1c566,fb0a9f20,8030cc96,e1197725) +,S(25474cb7,805d22f8,7a641116,34628321,f086d1a0,40404c47,ebee913c,e9e02a6,2b3aac5c,85ce9672,61757c61,d6a72dd,4ff81e00,87f0b8a4,999b927c,7b069609) +,S(6f7051ef,10fc1485,a9c80ae0,8683397d,c0af15b5,f78fec70,fe4c456f,f33b6689,625086ce,ab7a9173,d9c370c4,c336c63d,2aa85ac7,b8391993,7ffe4118,f6a7b849) +,S(f4720462,2f579de0,701f1e90,558c74b4,ab634664,197c03ed,a85b0fe4,50df4951,c66a490f,f9b588c9,2d17b80f,7f66e5fc,a65187b6,d965e81b,c16039f4,477fdb54) +,S(3b718764,7e722fa3,de42fca9,e3ba181e,de982728,5b8b006b,d51a58e5,ed898c8,bf872047,f3cd3ea,d7a439b,9d4f7776,7175f940,d6cae8fc,930aece7,e1b92202) +,S(5255ba09,df1e199,4c99bf21,709849a1,cd7c4f58,a283e344,6b98872d,a416c40f,a1099eee,e3ad10d9,6bce7a58,839fcaee,1b43e0fb,29ac0300,4e0eb15c,63d1f604) +,S(f4b64a08,16dfe224,595d3a15,8173df8a,7d941a4e,968ac02c,bf87d9d8,93954805,e5585209,2d0cf600,b8b2342a,8371894,f422e3b6,68ec4078,2379a60e,944228ee) +,S(236d83ad,b789d7df,5fde69cd,86d45d5c,f20c5867,b7f2b398,b9373960,b22b29ab,9758044,d3e06295,e33bebaa,befc5776,5db45475,b3aab963,5fea8dd6,77a478cc) +,S(42071659,65af2fda,c9e87319,6dd0c723,e7d61bf9,b71e5e70,667c9858,6371f3f2,fddfce02,588c1d4a,b744301c,6117e504,8f9c2636,5ccafafc,8a6e19a1,ea7b1b37) +,S(7d0c2917,aaa71cf2,e79f1041,5e5e583,ff01b24b,65f1f409,240f794b,d346a452,1e857dbc,c86c1032,e748d8e7,c8f5839d,57295223,22e6bdb6,187b00f1,f489576e) +,S(f0609605,d6e39141,e5e4f0e0,6bb6d55b,9ea2ced0,6a58d4e1,7c46a3df,18257255,e6d54c0b,10826de6,e95553ac,e4689fa4,cb03b959,65472e65,a085988b,d045374c) +,S(86e66299,819b0807,af30c89,228447f3,71fad56b,75f238b5,30bef3e0,b1123204,de635715,b1997f4e,c367bcf2,8f8def4,7a7a2069,3a555b5,396dbe4d,19b1e8ff) +,S(7710dc40,f72bb934,f5f9328a,1284efbf,fad3518a,70c2a0a4,55028bb3,a8b87e9f,d2ebdd39,7dd91ec3,7ffcd8d1,a9b412c1,78f6d228,5e099162,76f9e8f4,a6a28e02) +,S(3d377c80,25607e9a,fd512e8e,7c37a2f2,8d316701,dff7f318,eb24cc34,348d935f,20d2d95a,e8503a11,de19db36,5bb62213,6cd55735,966c25cb,2a56f07f,19cb2664) +,S(812a4ad0,d004003e,fb190ea9,336659d9,7b7d6df0,29f29f97,bc9c8d68,f284a696,6303a024,b2d95d18,f04fa94c,df3d0749,60ed45df,584e16ca,d60a0843,551f94e7) +,S(51cb80b1,9c0dc55a,888421e2,411baddf,6c0eb167,ed9bd04d,294623ed,1bb61dad,d14f756b,f905da5b,6466bc6b,26685501,1fc90892,93633c74,479afacb,c34559f5) +,S(837afe72,82af09de,108711a7,998dd45c,36654f3d,a3cb392d,c46bee0a,b43cfc8d,88b0ae50,5c30a2b5,72c0f69,8e7ecfea,87ea1253,ec133fe7,fb2aff9f,6adc2e15) +,S(ab967cb8,463da438,ad360a8b,3e066669,231fbd,cd590904,fe827ecd,dff3cca7,d82043ef,c614db53,8d06f6d9,9fae98e1,ee6f5065,31b05822,ed2141f3,25ebe544) +,S(5a0b6177,50d828ab,fbf4fbca,576ff8ff,5bd19330,bd357eaa,a5564e39,c718eb49,f6e8d743,e528429c,2cacc478,368d7226,823a45bf,358d9128,9da334b8,5a1b4426) +,S(351b4334,83fae045,ce964f04,f63af62a,6964e0b3,5c1444ca,68d09edc,9a43c9ea,f571f442,7b308ac4,83bfdb4e,87987455,a2a49f77,73220511,dfedc616,20bc18a) +,S(fe64fb54,727ce446,c00dc3cd,5de496e8,2d5a0e9,b13a9a7b,99a96a49,2d0d288d,452c4c9,aee35675,33ce8cbb,e444590e,f5756f14,33865ba0,efd00c4d,26db7d8d) +,S(9403ea3c,773544f4,4eae3cb8,91457ac,89b11f1b,66c3c397,aea8d816,ccab1d49,46ec1e05,d13b40a5,f21ce743,b2ac9756,8ba98b2,8fe1443b,3b0c9cc8,f8a49deb) +,S(e81a5512,2af7093b,b361ab58,534df80f,dac734d,7a863ad1,b080d691,c4396dde,fb33ea54,fbc0c05,f9854f1c,49cfabe,90e259ce,9aafae3,353e8f51,594d49f8) +,S(b7511df8,fccf50c8,192dc3cc,bd79985b,15eaa528,89c4d01a,e21767e3,96bec9ee,c937db57,ddcf0997,aec742e9,cd522c10,d4a52b27,b50104e7,b59c441e,3d0fad4a) +,S(5625f122,4406dbff,a818d98,1e88b5d4,80039f5b,415acc20,ae69ae7a,704dead4,aed9f73d,5265c976,760d094c,e9ced8dd,722122cd,e0b1b34,a8296fb1,dccacfe7) +,S(1b89696,dca54369,27bcf0a5,de32ff1e,e79f6ea5,6f6ffeaa,bce6190e,bc7e2c8a,52bdf0c7,52cc3e5b,1cb9b5df,adccaca7,929046b,bb67daf3,10ba793d,9369b358) +,S(4ef2516d,796d1c0d,9baa8491,7c2db149,e7b89f61,a8f8fb95,e14116bd,473d730d,9a0063bd,6e25255a,70479159,d3089a75,834e54a0,a28c5c61,ea3c33a8,7ab20969) +,S(b36c8db5,51fabcb0,c3fa59e5,9faefed0,1a53b4d,5470ce15,937c889a,a93faecc,1be63f1e,7f85bfe7,2e782cd8,22776567,e3b58794,5f37e2d6,b137da7d,42c8cc10) +,S(7db8ebbb,88c7c04b,fed18b7e,1830df41,490028a2,2918098a,9b34b8eb,c110457b,73fe3f91,f0f8a43c,490f4cbb,f8bab5b,9a6569b9,22a69e9,93ab910c,520fa9c2) +,S(47bb0b5c,c207ef1a,db28a389,7606661d,e5d4c740,3b2858f3,209b7dc0,cac3021f,150e2ce4,44f541ff,7883cf31,79befa4f,5df9c3e1,9da098f2,1d73c37d,1ca48b16) +,S(7803d64,d7622ab8,70a8b927,74e012c6,ab97fad8,4bedfc7b,ac4ce6a,74dad4e6,2662e4c6,1a60a1ff,5485bb34,c1d41d29,3a09a69f,7fe8a049,95245e2a,7770cbe0) +,S(61a64d4a,9a801549,4fa670f8,85988b67,7d317b9f,9b75e3eb,fc6d734e,fe3d3aa4,ff25af65,16e639b2,b6b0dd56,c0e12610,b1b00c3f,d8c59cf1,3fbb1b74,6282d91d) +,S(f2de8cdc,ce609b80,af8b34ca,1c1166c4,3ae0ab9b,e742b510,2ecdd5d,2e94307,d624709e,79346b3e,81b98871,84bf252,949c7f21,861fe6f6,666ef5e7,18ec5be8) +,S(8c740f9f,386f5a0a,228ea52,18a43461,142f744f,87511e9,67080dd0,f3c65d2a,a641bdc8,ae1d4051,a15b1083,27581bf0,22e92b26,a5bbd186,86fb4e59,79f7cd06) +,S(b15a4b19,17448b75,df927416,2795eb5f,60cdb4f0,e657afa9,989e5133,646ae240,e09f731a,226189fb,429c76cf,1ed9fe62,2c148475,92f26b50,c2c45344,ddc73370) +,S(44a65d90,26bbdbc9,89b0dbfb,aa645860,d7a15652,5286a9e8,c67b5a3c,e2dde08b,f2f23e44,bb6cd570,f58ec2b7,b90eb66c,30775109,81279b50,2fc90762,3f12b52b) +,S(60bc8123,92f1e7a2,4eafd5f8,ca0d8fe9,c5880133,209f17d8,6b95cdb2,c9df479a,4d39ae61,cf4368ef,279231ca,b72be100,cfee501a,da7c873c,3db18742,82076a98) +,S(ad5b9079,36391697,61edf9bb,6ed7ae2b,f7e852d4,bae22afd,655a5ed5,754f3618,bdb40449,723089b,ad8221c0,8a46824e,cefe4899,d5e073fd,8606524e,a81a35e3) +,S(c8166cf6,97edc986,6f824df3,82a515f,68ef5d13,dba7e0d,43e85727,c6e15911,86804e47,8118c092,3ab97ef1,ab9dac34,2bc48c7e,3fe24e6c,fbaa74a2,2390f4d6) +,S(3e0a96a,94dcdcb2,9f0df535,970146d9,7f0fd71d,7a4196ed,cd626903,aafbff06,5f6eda99,4651016b,86d28c9b,39efdb4a,b8ad08a8,5c87b230,eaf7ba70,6062a8ce) +,S(e72351db,dcab669a,f1df2767,f5e5f05,ca80608e,29ac5f09,b1ff76ad,43178a5a,552249f7,7a8b3462,c9a268f0,fee20713,5cc14ccb,15914be9,2cd16d99,b2520af1) +,S(a08e1278,71ec784c,4f80099b,5d83c5f0,91978e38,7b0b37e1,f4622c15,80fea335,48e6aef5,349f25d7,40ffc9c2,5de543c8,7e0553f0,54990aef,fec51f0a,9b3585a) +,S(ffb6f3d7,92596141,f7d15157,d1a42bb9,e9b51e21,61a8e297,5aa05688,ba67617d,aea9ba56,8aa7cd30,b9940c75,29cc1e7a,dd60a5b6,8911498b,9fff470,bc4453df) +,S(9c644072,318933ab,4d1459b1,d684c066,d3df3371,d7659a82,fd396bdc,a9fc9e,a115ce28,5a7d9bed,a2a962db,5041cace,9d3b2a3a,12149b05,ddbae7de,30cf52c3) +,S(5cd3475d,8a6fee1f,a6e3800e,911de939,a7568762,4f0a6e69,26ea6160,4ddec04,20063702,1d1d525a,f250876c,c4b49590,9ca8b39d,74603979,8c8b4b39,fa07c17f) +,S(28519616,c035ec81,4e851ef5,191e0545,5f0bbb57,12fcacf3,2b36de77,1c351f88,42ed56f5,5c51953a,6a367398,815963e2,64363681,f9a0723e,7b622784,5cc939c1) +,S(a4e11f70,b3554f05,d0634209,86549001,53d2ed50,1f09f787,99b83308,4dc894b,331b9d59,4260e0fe,381176a7,1873a66d,a7a3b9f6,2a930e0f,696f68c8,6939755d) +,S(c5d7c22d,7a8cc553,7ed85a85,46adde7e,ebddff6a,f7e8a6c9,96f50df4,248a4ddc,dd4749ec,bc029503,1106812a,cee59bb7,acf41451,45883a71,3256912f,be9ee03b) +,S(b56ad6a5,c6fab0,934257f2,9e266052,cdba0bc7,8c8aded9,f0e08490,71770c7e,6aaa84a8,99a4f8f6,3ca8dee1,6df7c090,264e644,de1e58e0,49f99fb5,fd5f4c34) +,S(16c4dbde,37e8df54,aff88810,678f4707,310f29b6,e9e5fba0,384220b8,4f0dec11,4fbdd92d,56a3f76,56b4dcfd,8be6b589,eb02c645,8a247c9d,264fb65e,c84a3a3b) +,S(15e63d71,f02f6bd8,1899f95b,d3051871,84b68d93,6a2ac10a,d29c39c8,d5ba9748,20204657,ae0e1078,6df04a71,938055c,ae208105,ef1beeff,663d8cc1,df478ed8) +,S(3c07006b,8a1e1fe6,fcbc3a6f,fbb7a780,a0008ed,513c9967,853a8cd2,5827dcc9,b2fe428,d4c8d974,72066ca5,ddf32e99,18b5e79a,e81fd6c5,e00b8142,566ce904) +,S(c7f2ddf3,b3dcfa04,91846f0f,2341b1c7,81ce2cd6,ec20acf9,a304fa5a,7dbe73ab,595d0b02,faae2b6c,f6e84bfe,1183ab9e,dcfd6c9f,411d7125,dafbf9d6,60ec5d01) +,S(4c239c01,c05d9c11,3d25dad3,3d14ab28,f94742d6,8c9c748f,1773b739,445bb643,dab0d447,de6a8c79,6809563b,e77c89e7,956f6c9b,ed930d18,f25696a2,e436ebf4) +,S(9e1a100a,c44c33ca,543ae407,f98fef31,28bd1755,6a16e5a7,c1390792,187fac5,540a4e2e,9864a32e,3eedd96a,bb08fe11,b499a551,497e0c83,cdba140,3b303821) +,S(c3b4d7e1,bf3485e4,d028e424,81608ab3,9fe37649,de75733d,78f725f3,63255d18,8f8b00c0,2210cd63,c04f07a1,e10b1a50,f05ad863,b8cbbbff,9b73c84e,c59b5ab6) +,S(dc226233,8dadc96e,5feebb65,b290ceca,f8f5bcf3,e1794f9f,6ade4eaa,b89f3372,25bebe7,cae8b7e8,d755862f,dbb929cb,872e1c88,6b7d03cd,b32303a3,b8b5ab9d) +,S(184b11c0,a52865a4,5f530101,24cb353,dfbc2d26,bdb3af35,d5f029e,6bfe53c9,237a79d,b53bcada,f0a96804,d8072832,4f59f03e,1dc7a76d,ac5fcd01,3838b110) +,S(4ab97ea3,943e8157,3cfaa8ca,680252f6,577ff2a,a93178e1,e1a3dcee,242b460c,b8a6293d,f316c9f1,5fb8850a,87bce47,27d2a38a,d1f5f63a,39d08c92,e9d6d242) +,S(a531936,799791f3,cfc8bc58,4a2967ea,66328c66,98ebad8b,5e5fe8ad,8cd025b,c24d6ae0,8fac8028,a3e0e079,426b94ee,2ca7c845,8efffe1,58f6cb2b,c9046c3) +,S(37cc3686,a6e75e4c,8d7375a9,f291ccaa,937c833,f9e16d77,2591e74c,787b1f7f,557c1bb0,a7c7ed52,93e44cd3,75b04a47,7788181b,b20dc1f1,f6704c10,5a8e399c) +,S(94fab00a,9418e31a,9a229706,112f9386,d537bff,f5f0c4f1,b241c475,4d7336ed,14bced66,1c6eb134,7684cf29,6a303e0f,fa5abc38,ad569011,c09cbfb7,8316540d) +,S(14b851dc,c6b4382f,ca64791c,74a3faf5,adbefe65,b36de8f3,74e12e6f,e3c20e1a,6353d0b,ceff99b8,53557d0f,a893df50,598e0335,249f96c9,4e7a46a,3c02ce1f) +,S(d08e3027,5e05da0c,22991340,8317ec6c,e4362dfc,45b946aa,41e6b541,92c7589a,9553748,22228787,2ae61975,d0969373,8cb346dc,15d07e23,68800ab4,deb5d463) +,S(365ab0ab,6d51bff8,d4bb479e,a666e110,9a838863,2a5f8cbc,b3241bcd,5ba88ed8,bca2f90,ef0d4145,90cf9add,2a9d6793,d678f981,1ad851b,b2f54b6e,6bd093d3) +,S(879e8da9,e1363822,b113e70a,b8072081,f0e34a99,49d698ed,a0f55b4,6704089c,d5091dc9,d33861e3,daec5550,1f52378b,65b25a74,27a04483,c862e0a2,dc1038da) +,S(17006515,8ceda656,b23941e6,33ab3ab,ebb527f9,52ea9876,a8341600,24dc10e7,39a7ce82,b0afdbb6,33e74517,5fef5165,cd44c8c9,d81be0c4,56ee0251,6410b0f2) +,S(574a4f4f,67e294f8,2055793d,e94bf7f8,aa7106a7,f7ef0f2c,3bcbf2a7,352f017e,eac4aaa8,f4b4cf2d,ed8c328a,99b24623,16ee6e08,8805f1ce,783c4cc9,eff7baf3) +,S(4ab81205,32603ea2,9f88ba75,f2f0c4ae,330bb5e8,7f371806,de04f87e,69d5e6b2,1f1967ff,cd42f9fd,1f892f43,f8ea945c,c0135544,acb8010b,8285403d,5e621456) +,S(9a4e968,82b11f0b,5e431867,80dd208a,ba25b3fd,1350ed84,f34f2b43,f03c4378,15653ab8,375c04c3,d7488006,1acf13d9,c5d669f7,bbf70490,44dba189,372f611b) +,S(267b8cc8,3ed6ef12,47a93f07,b4f1195,2fb1de83,6c3e3fa6,782b5e82,80cbd8b8,19bc5752,1a41c7a2,a9dc29b5,cafc66d,7e2016a3,334b4be0,e2811ee2,4ab8599c) +,S(69a8b170,876bb1aa,2faca2d0,a4ed8c02,44d2cfee,a849293f,5ffb4243,256a1017,f77d7a37,5315381d,97ce835c,296593b2,80c395db,a5311a6c,c7fc2c98,d314b4fe) +,S(88aad570,3a4365c2,96946510,5a3a7fdb,6e1f3e66,618c3fbb,ee4c4e13,f333b1ca,10ded35e,c15df656,fabfc4df,a1140b09,196d10af,e1e99b3d,7e1113ef,f7fb8670) +,S(50709e9b,8620f7f7,7b8b6c69,1360062b,cfbea4ef,6448917b,471c3485,55691440,3946b364,3cb1bd81,818b828c,77c771d3,833a1d4d,dc509705,2e5db99d,6cde2137) +,S(1ac1d530,7cf465b9,8f1140ea,bbe7a939,df8155a1,bd656168,55ae128e,bd3959e1,eb02a759,82bfa30,1f9fe87c,75b9dd8b,fe2d64d,7ea89836,1aafe22d,448b418a) +,S(126a8f88,e7f59ac7,3226f2c8,8851773e,873f1ea7,a87342fe,da5d9795,3a1dc956,1ce623ab,abb29b2b,b9fcbde6,a6a6f12b,ec68bfd7,aa98733d,f2452860,bf9349f5) +,S(592fe608,92c09243,20fb32dc,39e7a42b,1f5125ad,1e7d6790,9978ac10,5471427,c4d6ed82,4d33f52c,d975d34f,b9df5698,968a0c57,9b44bd19,8a67fee,9935d310) +,S(babab912,e526a92e,d903a942,ae8ad2a8,930ea5c6,17cbf913,7c074060,6462f0bf,76c7ced2,4318c1b6,c7295d9b,52bbd4b6,707a4170,d020e7dc,1c7b5e92,aee7a4c8) +,S(6554e9c9,bdb1757b,408164ad,1cafdaff,4642a3bb,cf64e785,42c324c7,5be1a903,439d023e,f6c63252,311cf494,4c46a8cc,a3d684a1,d66556e5,dc488d40,e5ddd500) +,S(79ad3f8f,4c429721,281a9b17,d9c05463,f26bdfd9,c856451a,1050b3f7,805304f2,3be5cb37,da868333,4f9a4def,aa8711a0,adb6721f,d4b2bd38,5ad7298e,940dbb87) +,S(fe559c8b,e982e801,7427d308,e50e4d94,d7094aa0,635e553c,c591181b,c9593015,9186fd9,c9fbecaf,f4747597,22b34b72,49fb72f9,f02a67a7,627c1562,ae80485f) +,S(d2b4bcca,38d1b073,5248b4a,7f43f277,8e03f46c,8d7f3a33,ad2dd9f1,70ce0af0,fe0bfaed,846a3f80,10fca999,d0c3b0d0,b54e2fd8,7a0bf751,ba40f560,9eb952e6) +,S(f6b9ecb9,631c784c,8b33a7f6,3fd0903d,baec116b,3dfd2414,4865b297,5c290faa,95fa4ed7,e67b828b,4c685850,4b003928,8ad9e27c,da175b4c,81730fc4,5b063355) +,S(3e70eafc,653ef528,aa12ce46,59c90ee4,32979f0e,9df260fa,b9063f3,d30de2ee,e240ec33,b224a5db,3761796d,2c1285d8,9cff64b0,7c36a184,996cdca4,839a0a65) +,S(dcc76f61,46d05c0d,67bdb161,dc395c83,663ebd48,6bbc6e62,f3576335,a8ee0c59,e451ed85,a9ae624d,4617f11d,67552eef,7279811,6767a29,59708e,3c21208d) +,S(3bb03660,430c43f7,e3b68acf,fe692b,5ed6703c,c808d7a7,503b3536,381180fe,c84c669b,2822cee3,627d4ff7,7c01c9c2,57c57e80,f35e4fdd,eab84a6f,b96fa1ba) +,S(5e266477,dd106005,6a59fc2f,df36b540,e051bd56,c9120b9a,41471c46,b1c5c60f,d6a7ff4a,ee4abbe,cee617,1ad01373,d7916899,5370031f,66f62229,1057e6d9) +,S(c1c13157,56ce83c7,93ca3a0e,12dfc0f7,270a0bf5,38177522,8850863d,37e5e537,750dae34,9090f275,5487778,5a126ea0,f3c2c0b,e3cb9241,326a863d,3179af7e) +,S(c03ae6f7,96692287,4cd10b76,d06ac08b,578511cd,c502762a,cf14eac6,4f1a913a,b3ba2ed0,6cd40752,dc97e450,10699cba,90f38f65,cc4623b5,44d7a57f,250640e1) +,S(5938d249,4edde81e,6fd50332,d81342eb,6cd0d938,f1f02ae,562d1305,cc665bf7,b585c184,1e17e6fa,9924361f,8d06b172,89782433,1d65b3c1,7f2a109c,8be27b13) +,S(e3457146,bf3f5667,e0621ccb,500854b7,a08836b1,e4315d4e,6479b3af,e5c2bcac,3de9142a,5c495249,14d3619,a92dc5e9,f20e4603,5cbe2c8a,95a8e683,bb287fc3) +,S(4187afe,4918d05b,74a969cb,14f54b70,95387e68,c043a581,7dcd1d80,4ca917a3,4e1c19eb,b38f0a15,36afd31d,bda30d09,3c776545,f2d8d823,bc3eae61,35585569) +,S(60cabe6e,ffbc3735,dcc19c15,1abfdf4b,cf082768,e62a1176,f056c4be,ff04640c,7b0fbd84,ee9d787,2896b9c7,19448412,c68a1ef4,e5c6cff2,51ea823f,76d6c4df) +,S(fc6883a1,231355da,115af629,4f06eef7,83447185,edc19e62,b53f3156,e0f540a9,73805d95,d8b2e4f9,d0fb36c7,9f09780f,c315c1b,724c5de6,98d96861,c521a6c3) +,S(90f37677,e738ee2b,3abc9d42,54085349,9cd02836,474624c3,9513950b,c325b66b,90884e24,a4171613,da7fc192,f1bc913b,31bda925,38fc0501,6a55af21,e08bb960) +,S(55e68c72,f76925a8,52d38e8,172e6340,3966f148,2a212131,cfca2497,ca40db3,ebd22c3a,1388485a,e4b48b4a,8b69b98b,755084f7,9f9018e,36769d5,d78cb7e7) +,S(c74f257e,e1bd81f4,fcf512a1,f866b9a2,19586a3c,62e7abc1,112b5946,d5b90e8e,aebcdd14,5555164a,bfa127ab,9f352034,f31a19a1,d36cda02,f51a88ed,9662f44a) +,S(bc63fc6e,d1963da3,7fa064be,f7a371a1,fb471ded,5bf084d,946a6eac,fdbb8d36,a26a6ee7,e178a31c,4ca535e8,e3d1dfc4,dadee69e,140a37cc,a306546c,26a75a2c) +,S(9d11ff44,5e331ca6,fa99f29a,78f5e769,44fbebc3,e3b45a6c,d46ad17,74a1f29d,2f007088,110e9ec,66e5f134,b6d61ae8,70b14741,e9b6259b,ff06753b,fcbfbccb) +,S(5aa47205,f01abec,79b52b1a,2625b773,659166f8,1e300d9f,46bbcdd8,532599e2,f56747f5,c7431031,5b630fe9,b162fa49,26757780,c6ba59e3,6e91c29e,c82fd357) +,S(14dafde6,c8818744,2059563d,1e2cc095,f4bf18e0,f7e41b9e,97a74089,f678ce60,6f6a348a,a4f72e60,9a44b01c,b688ea96,cdc7c3f5,e559ed8e,d9a1c7bf,cf1747b9) +,S(ad8cb71f,1a3739c,afc8a4e1,ea77bd9,f5703d4a,55812381,c5a04847,e85e9950,238d1945,cd5d6094,dee8c6f9,41a19b48,d1eb88,5c986dc4,b8f3908a,508d46d1) +,S(e88df4e2,8b7cb050,aa81792e,ad108c4a,d95e735,6443dc11,f77d70b0,5968de2d,9541f907,f29d79ef,83c25f29,fdfbf819,49f21604,adb5a5df,e939afe7,511cdcd9) +,S(d6b6549e,1ef4fecc,ab56860f,c7a8a549,a354d9d5,63b9d459,9bbfcd71,7631c879,df7a0e04,18a86774,ba87bbe6,132028e2,927985e3,b1319c83,4e1a400c,7b0ae231) +,S(d919b999,faaa7cba,99c79a2c,febbdc68,6d94e07b,3edf8350,6e9a729b,f0f834d0,4b19faba,9b6041f3,9d33a21d,285fbf7d,638f3a07,63e2b15f,df102131,49b94ed4) +,S(b89d011c,57cfd499,fffd2d1,8734f604,83df00a5,6efd43a8,35d5983d,573d902,977f7c06,ed8cb0d4,980c3160,b152a7c9,294d489,2c90fb88,1da40f39,adfe2825) +,S(264873d1,cf9f6f35,d6bbff5,a2405f40,a5568a80,2fa35069,ce422c61,d9f2146f,36b8e9c6,e73044dd,b9b9753e,c682db1b,550d8310,7e3ea3ce,e8ecf031,500b3c31) +,S(d4c388e0,950d24ad,6cc1dfef,a3735bf,bd9e729d,99fafc8f,e4fb5266,8816dde1,3d583de6,27789a58,fd4afbe1,af3f931f,5d12df61,7f5adfaf,95830cb5,4b13743f) +,S(80a2e2fa,40aed900,a7a55f84,d4965f0,2c5632b6,1317e801,b83ec659,cc06e35,9e61e863,69c8a367,72d6a4b4,c2b7bd89,405fad38,4f99514b,485974d3,2342f47) +,S(e36eb1d7,72d5d498,3cdbeed9,b64fa04,1da7f1bd,e324f1b,a734323e,9f5331ea,6c879df5,4a96d33e,6a66895b,f4d12fef,46d5fe48,8d62f073,238fdbbf,d94126d) +,S(7852402c,a08ff966,44a4c1a9,3f7186c1,43f0e1fa,203b5991,d3fda009,1e0a4e76,a9b15d95,3ce9b219,a53da27e,e1b03aee,5431e26c,f035fa1a,a067f1d2,d36d5402) +,S(5d33032f,f7bf3996,14a08ee3,a5b67ff4,850f37b5,eed88e4a,675b020b,90cc4ac,ff5c96f0,5ba73287,f3279907,ebd0fb7,9e0b4866,c32f6fbc,2541d8c5,cbe12112) +,S(138d3701,98eb6569,17b3fc46,c2a3a1c2,3f7c95d9,d355d51e,c85b6062,4675030d,94314f22,6581dec4,3518cd7,61150f31,51ccd59f,3ecf79af,482c4dde,8a24e28e) +,S(3f6ddeb3,4756ed69,de83946,b48281b,c2b60882,d0cd721c,5d76c5d9,ff898c2,be8b8841,12fbfe09,9af67a96,8f4bdcdb,db4469d2,34d64d96,99c6a575,518c48d2) +,S(74676fc7,cf3bce8f,c0c4a774,89b320c4,736b9ed6,171d0b42,17a1433,eeee384e,fce3cf3f,630452a8,1cf3fb72,63c1b5,b66df4fb,864d4b39,7e66c69f,2913c54b) +,S(e0d1a049,cd49ee87,d71ebd9a,95eef0a0,b1d7450f,617841b,590eab0f,3e883eca,99e00118,42e6a78a,d4c3ec3f,f7a61bea,a1a5f8ec,2f4e9066,978e96d0,cbaef51c) +,S(531b455c,c6051fc5,f0f3190e,9523aa5d,2d0485d4,3901600a,aaf207dc,7d2b1fdd,b95f8c0a,b0e63acc,542df948,4b112b2e,e49f53fa,7f3e1dd0,307d9161,7c0f313d) +,S(b86ba09a,2b05e91c,c23db107,9b34807a,778749c0,ed725437,69ff6c17,316e7db7,a91c815f,f8a3b2b7,e5d44357,20e3a513,32cf405f,7501ca3f,b1aa1f59,a01c10ab) +,S(b63b43c5,af63f2ac,3f6e004b,c790404f,a146ea97,94b1bcfb,c4d0544f,2ca3f33,31654108,481b7dac,cbd48e8,c20de95,11406381,ef38fe6f,950b4321,4b145093) +,S(63a09087,e237e0c9,686f2a79,af977ba7,26d77118,29c8ed91,4f99dc43,90c64d08,7771ce4,a5e7d43f,e12b5e8b,c819506d,3b85f52c,fdb0f9c2,92c22bad,790d3b93) +,S(77640a42,4ebd84f7,71734050,7ba400cb,9e8462a6,a91fd0a0,b8f152a5,f5f7868b,516688cc,f422e660,15afa46,b5889331,3cf2d622,d6c829b5,f1d11386,bce41640) +,S(963ae02d,62739bbf,e75965f3,d1b7786d,c3dc6fc,5667aebb,5544db3,157f8a17,b3a109d1,b56570cf,2a5e5056,fd9feb05,2e8f53c4,f2ced1a5,27c3311d,87ba9dfb) +,S(81324144,454cb304,36f365d1,c78ea5f8,9a73706,acc49d5f,125fa282,c28ebad5,77a71aa5,54c0da45,31ed307c,c7fdad32,ab82a4b7,2f2a5154,cc405a2a,fddd3cc3) +,S(eadb105,e80bf2d7,cba9b468,6f6b88ad,34008c85,a7ac4d53,d3fff09d,dcd566b4,199ebce5,872f9dd7,6c14821,622fd343,2b7b6437,3484fe84,714b137e,fa782bee) +,S(a030450b,52b387b3,35cfe8ec,683fe625,884ad73e,2fc1c728,c8d9629e,dd2024ed,895545be,a9009f2c,dcb20441,33f2fad7,ac704ab4,9435fffe,b92836f5,57a114fd) +,S(57e8022d,816255a5,f4d577dd,867d65bc,7d7fdfe9,ed8f993e,d9b30531,fa36888b,9b0b7929,3cef66be,c21b6fca,140e6fe7,9b9f2e8d,48555338,868b6c78,d300233b) +,S(74c14e1a,d52761b1,7206b61f,fdff526,f7008f94,b3707a5d,e5c2a600,97b0dd29,18778822,89711679,c5e41fb0,41b1a806,9b12b709,b526ca1c,44839d5e,3b51e72f) +,S(5a9ce7b6,6368077a,73c09869,38656705,c017faa9,2d9cd40c,69d8e57e,63f8e229,f716b144,cebe2907,928f4618,821af2fc,9de249c9,5ac61bd5,99a550d5,e97363d0) +,S(f0fe4fd9,99c66687,3ab4c904,b9b7c0d2,7f033a0c,7e6c1b6b,4488097b,cdb49fdd,1f4643f0,6f700657,90aa51b5,911b4866,c286128e,de489dc2,8e2d6b64,972738e9) +,S(e86c729d,19347238,a9e97433,355530c8,7b701aa7,d710d26e,6b15ebe7,4796857c,d6260d35,466dbe3f,58d2aab2,1c8d76df,18271247,9715bacb,2a76bb95,5b75730d) +,S(b4e3a39c,8fcb0dc,5a23610b,bbb564a6,765c0135,1a8b666e,d680291f,c97df351,3f1eef0a,7a235130,b5236a2f,f8c9d2a5,fe5f1cbe,22326ba0,54557513,82ec651d) +,S(a9c8482d,a54adc98,4db2d7ac,8fac659b,51c1237,eaf1d524,9bcfcf1c,4ae601b5,446ec925,fc148900,8ef10348,ee167a63,a10686f0,7a01772c,10f7592a,2a544a9) +,S(17adc7b2,c36b1ff9,ea40b398,53246d71,bb973bd8,b469f7dd,fce49aa5,e77b8c06,fc3111a3,8dfc5219,7f41ea77,1682bd8,618f9825,bb2f842f,c7de15bb,224bf573) +,S(328e9a6c,e7397c45,617aefee,130cb6a1,dd26e727,efcfc30c,3d8f415c,187d23b5,6320e80f,e4a57574,1fed0624,c0f956f1,d5b30914,b5da88d5,f63e17e5,64f8b927) +,S(22188680,f765065c,360c52d2,851f3081,b2d3eb5,4201dad0,60b536bb,a45a1a41,b1107c8d,430df246,3b3e91fd,904883b5,cb877b,c10b6f,397a0cf1,c4b6eb35) +,S(620f5772,5919db4d,53b8f89c,5669fc6a,5a3f3846,c31faee1,1e93e53f,b1d20bc7,7d739bc7,4becbd29,2784be81,294185fe,db047d4c,c16c764b,678f9d00,6d27feb7) +,S(49b1228b,b624c71b,2c23e334,b098e84e,d3d8fca0,56303057,49dd39bf,5296666c,3f316e5e,ca9c1aa1,fd5d23a2,613e756f,8ac5e819,8ac16650,a9dff05a,1c8d76d7) +,S(97ca98cb,fedaeddd,b13b86cc,4b6bd7d2,140fde57,dae7b847,c51b118e,e3d6b8c5,1b95c9f,1d6c808f,397c3ec2,a2a2b220,6fdf546e,8c70ac2a,78086ad5,ebe28142) +,S(a679e7e7,3df904aa,e80270b4,d5d57dfe,f5ae819,f240369,b773fa3c,609a1ed0,93201a4b,17286928,be5fdfef,473565be,879cad73,24124c6d,6e1614b5,4e6e5124) +,S(fe17af2f,70887958,1b9b176,4d45d76a,afac0afc,ff50ac8d,9179e53a,c5e3777f,f59728d8,67c3ab63,6d387352,a029b5d2,e9f2d531,7a508894,9a0f6515,f5c4d61f) +,S(f7601ed6,fd64cf22,57cc15e8,e554dc8a,e19e4f4d,ad3fb3ea,a7e819f1,98b3946b,a3292ed3,ff088c22,e9a62b85,4ec87dbf,394cd681,501184c0,b841656b,def0fa3) +,S(3dec302f,cad72c11,54c6b588,ad7f77b2,9368557e,77a723ba,6dcf9357,82d9d917,6484365f,537611ff,49f157f8,6c4bbf07,25094f7f,d8db9a2c,b318ab4e,632cbfce) +,S(a847783e,46ccf334,d7b15f1e,d3aa7dd8,c5b3ef4a,7ced2501,c26d1dd9,4358adbd,7c56f1f3,323a500a,a3496729,ace84a91,6bc6dddf,90435a09,8ca51f6f,5fe5fa99) +,S(dac6ee37,3c655763,b01c5012,fe01518,c3ac1b52,543cfd7e,9ca24d6f,42e4bcfd,6b861af2,f2a82f0,d4c458f2,2d264d82,54f16f46,87e31cce,7199f061,bdbc941f) +,S(27dc7253,90de6a8f,6cd9918a,e3b2f33a,8ca4307d,ca4acf6b,f9c5d0ad,f01b4dd,2a0798f6,7e583426,cca8ab26,e6742692,ee790f21,cb3560af,271b0a09,eb9f8b31) +,S(1c6a5d3d,10983673,5e27dd2e,ff04adfc,7bae277a,870eb4c6,d6379467,de2dea5b,92658db0,8b6b85d8,5c20ad21,f3ad33c3,8de02319,4bc54d0e,4d758093,b4e8695a) +,S(cab35e2c,b731cb9a,402f77ee,44565fa,d6623951,be9deb97,88da09cd,d5abb56e,37bdbec3,638594e2,59018bb,9145c4e7,dfb55b13,bda50c6a,c33e975e,6c5d96a6) +,S(97e4cfd,9e1ec85e,cc49cb90,ada87b99,bcaf8160,9b04417a,70fa66e9,78bf54b6,7423ded2,bc56ddb8,11db577d,f1863fe7,dc758999,55989e4a,d344ed4d,5faa9ecf) +,S(f2a9b193,6f63e9f1,8333cc3b,745fb2ab,7b3749a6,c59e7d6c,42e387b1,1e9d86fe,3c6b6bf9,1c2c4a,859538c9,db95a2c7,abbf8c37,b6e172b3,cc2be8f0,f18b5484) +,S(49024a25,11bdedd9,6c84aeb0,707b5b70,f027afb5,8b4053e5,234a9312,771160c0,22ab8282,914e69ad,8d573e7b,841e9eec,2fdfb939,c76ff330,fb2fa5b4,14a4523d) +,S(781c9886,4bf29760,c44e1f98,9a5266e0,4d25c6c5,f941e2b5,cf92b958,99ecaebb,994a771d,eac92f91,58ecbeae,6227d2b0,4c09df72,c5ee4439,509f0b2f,6e361509) +,S(8f7e703a,ae008b13,590ccda8,b70d2cfc,4c98480e,2a5032bd,dbd5edeb,aefb7f8b,54226771,863fa87f,ec101303,9238da1c,74f9f446,26b50f07,f35d6b59,bb7ff81c) +,S(ecb2e955,ed796695,3eb1ee21,564125e6,e860935b,20fb99da,91556cd4,e5e57bbc,75103469,9b958e18,638f4e00,654d6eae,f5631483,4c890ebb,7e2d93e6,9f4d8bf7) +,S(971cd7f2,9ce90bff,4c46eef1,9df001f7,afa6af09,b553e8c7,792f4ae4,d3f82cf9,d4180c19,7a579e31,f27874df,f29cd17,98e5740a,36380349,6f7dd211,59bda50c) +,S(7ad3b286,3952489d,42cc8394,413545bd,90fc63d9,8558323c,feb8e7e2,50ececf5,5c566bdb,5efc3683,2b22aac3,c0b81f6f,bf656c11,5514ac9d,8a223071,168f139d) +,S(c905b52c,ad0e0281,a90eead3,3939c836,ebd591b9,26787a4,2983804d,e658aae8,df2a40ca,f95aa72a,181f3424,98024f72,f1b9e46a,3816cf3f,ba5ac699,5b996fc1) +,S(e2517e6c,84856497,8ac94585,5c80bdf5,7c074b6e,fdb01cea,e93c17dc,ae4b3ff3,373ede93,2f369807,56afd100,e2f65794,69247690,61a597da,80d10fb6,bbadd3a8) +,S(4d52a8e7,2f3cd95,2e25c8,175e82b2,726a8d95,b735c8d8,a0f1805b,6d94ad78,248b7174,61287611,8000136,dc92b841,de63ef18,a7c9ff71,a10a662,af76ff17) +,S(58e5b42b,e614cca8,e131cbea,24b3debc,9d9390af,469df700,35a01957,3307ac,be4a397e,7809c9eb,2113246e,7812c403,4d42d8d0,c353d841,3001280f,db6bc220) +,S(3f177142,a6e6eb65,ca5e1609,cc89df40,3e3c74c9,e5b291cc,49fb0d8f,eff86ecc,2a445bb0,b648487d,3b962bfe,dc74e4da,d1d98845,cea5f4c8,d2f0c4a8,2bc4c514) +,S(3389c700,9b2b0c6d,a25a9610,4660a164,172a4c21,d0ddaada,c6902bd1,c9f04b38,413344db,77b83806,80647da0,d6086ea4,d1b8394a,a0047a9d,4c21c667,ade67a90) +,S(ecf3f933,4b2b656e,24ea0b14,7528c490,c3a566ea,c4c51885,d3ee94f5,7370b218,3c07fab9,b6404f24,77e4605c,345d3a93,adf9a06b,649206a4,b369712f,7388af0) +,S(a090739b,58310867,5e460a26,7e29f228,effc954a,137f358c,12be2fb5,8011b2bf,a3563d1b,7f242a1f,7ff5e505,280c3898,13251c4a,d9392d82,d3b12a07,e22271f3) +,S(a251cd29,357e5300,5a8600e5,bb9d56f4,c8251f6b,46b4d99d,5dca7b2a,31f8201f,51764fe4,596059a3,b1eb06de,56c6e21b,d58e7194,8e1b6e65,51e53333,5f9721b9) +,S(1f9aafb3,eb39814d,7173b85e,b027ad41,be210c3e,e5c857d3,56288b3f,3b05c5a6,d34526cd,16e7d3fb,76ecdfc8,c11b1bc6,38762bda,b03c1c07,94565cbc,df41febb) +,S(dbd4b724,1fa4769b,db161472,1179fdf2,6df4372c,d3b0c4d5,1e37fce5,317e7e42,7e9bca3b,bda0e211,5f2e69cb,8fcfc333,fc1b8b85,70123816,802b22c4,9634219a) +,S(9ce40b75,7a257205,fdf51545,7d6f9691,7e54a5dd,32b76230,4ec50c2d,3b89b06b,9b128748,851dbe81,255f60f8,1e5e9de4,6b20a545,afec40f0,38beb9a3,f7402e88) +,S(12f6c70f,46efbb73,2150f775,5f597fd9,2a527a33,7039def6,5533cfb,18df3406,7d9f18a2,4988ea,a41a1364,2a1555c2,bc9bfce0,dd62ba87,fa628b84,850e92b5) +,S(3132e530,9b169a3b,7401651a,351f7fce,43471b19,7ded3d1d,cb0b768c,5620fc5d,3e377f54,92c99dab,84f4e45a,7cba38e,9b589fa7,77dfb334,849310ce,53294287) +,S(87160125,8a8a69ed,d52986a9,25a54ed9,51f561cb,8ee9e1ca,6c58b826,495b9977,c5484596,8ebfc8c9,5f317681,78379b88,2e9c2548,b3c579eb,f6da5186,5d51f36d) +,S(82674b33,ef500391,2dfd5f2c,26722df8,19fd265b,3b6e4cbe,239bea50,298653f6,bb6d0457,2adf23db,86b07019,f2f59fa7,ebb4fd2a,ac36ff16,6b22e92c,3952245) +,S(2efc1011,28432933,56af99ba,ea2628de,a518fe02,c5b0eddb,3688c8ea,39d4b07f,d54a087e,bef0923b,6244b21b,f260eccf,e7d590b5,cf98be51,856347da,ea48779a) +,S(f2164194,5de0542c,de90f1c,4be955cd,98f6bb14,ff30ab44,92691985,882fad46,a87f6725,e89afd3d,6f24db13,39fafd45,5f578c9a,104f6509,c83d0694,ef795dda) +,S(72d2c60c,6f9bf0e5,5de82932,88c298b1,4d851deb,6ba7421e,ad22f3d4,2b47ee88,29626eaa,712e6d76,d85b9f7a,7a17461e,132c9bb7,a2943379,c5eee30b,1ffeb1d8) +,S(9bc6dede,ebdbd843,a5534fc4,71212480,ecfba4d,96acfbf7,25e980bb,8a509773,24ef23cf,e1580173,797ffe5e,baff2fc4,3cbd3161,e87e32bf,463333db,5ca904ef) +,S(20ea6c3f,51565fc2,bd5b8eb8,1ccd20fc,f3aafee0,9ccc9de0,733df6ed,8caa9c81,78328fb1,ff260b0f,cea69e1b,77b35679,d6663513,8f136c59,127ec2c7,d9668dd4) +,S(aaa2ee28,a4724d91,f37044a1,3b264ea6,9dd9123a,b3b7b300,999564d1,73057339,250b6164,2ade568b,8a56ae82,4488e740,b9a65f7e,a2b95f3b,4b11b6a3,1b49fddd) +,S(a1e54535,4a8976a9,33c04366,f0361775,824383e5,2c3aff3a,357788b,38014ab1,a6a306b9,b0a7d3c3,d6530094,9efb038f,a0a2cd1d,79bd495a,487a95f6,ef2b7a7) +,S(f2b0c76,18fc3ca9,f9ec5d65,2f39b6e0,158598b3,cb90b20a,53fdaf97,ac58f7d7,1d63cacc,7e8e46ab,47ce7e4a,e5a3336b,8d3d9bf0,f05bc428,f6f769fc,7ec6cd15) +,S(91843b8a,90a43571,4d7500de,fff102a2,fdb53914,2bab12bd,d3f23576,75a9d62e,3cc6365c,7dc3813a,d51cb2a3,d86491c2,c4e38f2b,10a33181,374bb0c7,ac90237e) +,S(f73b2226,8122a4e1,a440f891,14fd8d72,19cad2c2,9798cd0e,3631eeaf,6b125a92,bc14e84f,ed149aa8,ac261f96,6b192168,26f5a2b7,cfb997c8,3f293101,e758aae5) +,S(e87cfcb7,1f2b1c9e,8506b0e5,c56b14a6,52201397,1bb4c53c,855f1de,45644ff3,7e3399af,b4a9f70e,63907a29,c02e4d58,b2e76517,e4f2f2cf,a3d2fdff,808d5b08) +,S(b9657f0a,6de5cebe,47151293,de1fc3fa,b2745a18,bd5c4b8c,62282f26,84404f21,89590e9f,a787f41f,79a0b8b7,682bc353,1ad60107,771233d9,ec303830,e8e8dad4) +,S(b62d02b9,de395843,eb69e8bb,4d974590,7c8d3b26,cd4b13a5,6b4a0e27,44f449d5,173cb5ee,60d3999c,7e795607,bdadf8b9,acf9282a,d7a68ee5,6a204eff,ce5fe751) +,S(b6998e3c,31e9cca5,251a9d89,1aeb5384,fa86c92,74a0f027,8f2dc67,34b5f8fe,7658a71a,fe032a5b,ccb80a1b,1516faf1,5a3e8638,6f74b2b9,b6d17cea,61c3ac5a) +,S(864d4c66,4db88b56,6471852b,eacce0b3,52b55404,46444cbc,afad4f17,204a0170,7001969a,fb35a3ad,fc553e00,b6faeb21,c8fb1af6,135e86c7,f7e91397,a826346a) +,S(22a0ec9d,ecf7a2d4,6f550ff1,5a8f1c8f,6efeff9d,3ff65d47,97512980,216c025e,9d60fca8,97662f4e,947c962b,48522cda,c7ba956c,5a23c3b9,67f46073,af0980cd) +,S(f1be1f63,769f74f2,947eb25a,194171a3,9f9096af,cd454ad3,35809b17,d7e69fb4,b78b3a16,b734c528,c1911d95,895bf873,fcab1440,b62211c,25aa247c,161af243) +,S(7b196c23,1a7650a5,9db8faa7,39b7ffea,488b3623,a0bd7a2c,48b51c97,f5726c76,56e84642,2c430157,bfab8821,9112124d,6bb968e9,3ddd6b77,7ee08228,9a7e1241) +,S(6ad31b05,5a1f1a65,f4e554eb,31e3e048,8570032f,8af2891f,4436c640,9420849a,edeafdae,d10bf173,5de8ffe8,41871909,79f6377b,4cb566f6,3386534d,89bde755) +,S(fb0f3da3,a44c0921,85d90b80,1e7f5aad,6c85d5d0,b9cc4575,ad95ab34,4fa6aa7f,7857f22d,6f9356b7,96020384,919e26de,b9abd707,4dc6db0d,768f630d,b3589b18) +,S(c39b4ddb,edb892fb,2394e875,7c7815e2,f487f81b,45c60749,1c314350,c929d96,530f0c07,68e66dde,e10f0d95,bd66c07c,ba10f165,dade7bb3,77f8b7ad,ac4a673f) +,S(c50b3ae6,d14b11b9,a74dffeb,a5bfb9cb,73652cdf,a2bee6dd,6cc3c912,c312e537,85ac82f8,e3aad88f,9af29cb7,ba66f8a5,8c340d03,a1f32654,2071ba6e,99705377) +,S(a763e636,4e4959d8,9d3047,bff6fbb1,912d99f0,c092fe62,947d4385,2427ec02,bd799a82,a3cea8e1,db94946d,c7d32236,13b008b,da8eca4,921c985c,c022622f) +,S(2abdc992,b2ba838,1da0c2c6,2b35d3c4,ec1a1e39,516b6afe,81fdc7c9,cf3715cd,8115c826,d214c36,36a8fcca,37e89dcf,4be7f34a,2cce7357,3a6c42ea,9e084a66) +,S(2cb83bfa,ef83ab3e,53216500,944b2db0,e8cdb6a2,caad1eec,c9e14c33,a16a07ec,5b1b1199,6e84c17c,13c070a7,99dc0975,3d374018,6f9ce89a,bced7539,7121ec7) +,S(2687de95,b368b07a,7808ebf,e45fde24,d66fdc81,a02744cb,3e96e847,f0a3ca41,5728b8fa,aec73963,236ca282,d1a8946a,b2a26f28,a239590f,9d38bdda,d05a846b) +,S(b143029e,7f32bd1b,a381fe82,8da79713,b53550e,f3cf867,4ef1e952,d4dff9d,a44a622f,ff5fb466,83b69803,c6ea5c16,8d86c673,3ed94058,81aff0a,2a8edfd2) +,S(4c54d53f,cefac583,6fcf3b87,7202afc4,ccd68695,567c7fe7,6068546f,aa9070d,7f42728d,78193fd5,946f3787,6ab124f9,b1045ae7,45df58bc,cab6f59f,a27c6f18) +,S(6b625111,556e3ff5,db9cd8f3,7f610b3d,718220b,e459f546,47314b04,b2ba9d6e,b3ae66ca,fc58bb7,5a057767,8bf806b2,c204b90a,fd114ae8,4ed51378,53b30a78) +,S(b3fb12d6,e16e4279,5fcdc1ee,23d42f9c,198debdd,56217af,5b76989a,271b473f,d38adb77,4ce1d0b5,e41b65c,7c973a27,10c5621f,594e6f70,d235f5e,a4a89386) +,S(9c7c908,6976b590,ba9c80a5,fe12c5f5,ce6bbdb3,5a4058a,3cc59899,82073ae4,399687af,4d3e221f,6168ded6,31644c35,e41606e,94583429,34693221,9322da67) +,S(28cdf6d0,f0374a35,4dd169a9,1c3beef,fc88dea0,4922f841,401ffe91,8bfbddb2,2b8f1d3a,6f001d60,95aab0d9,d6248cef,cf3b97a4,850d1a43,ad2bbb3e,d2ea4518) +,S(1974b196,a25b6446,2ceda38d,d99662b9,7dcd0d7d,15299c00,9b8d14b7,f139e7af,c685622d,96fd6379,6bfc3f2b,6eacd54f,83281ef3,50d2fed0,2507a157,9fcdb74d) +,S(3beafb9f,4cfa3570,3d3346f1,afa48acc,25909889,a60b76c0,6e7774c2,acfe4367,6c8c09ea,7233ce1f,cacc82fc,9c1dd357,51021b92,fb86d6ca,3749bd58,6dfa369f) +,S(b5cf157c,4586fdda,16a111c3,9a500daf,b1aefb07,e32f78ac,a23664b,cef3be73,1d273f45,58e7c2ed,6f46ed71,e297dac3,59489934,b10afdc2,cf0f4270,ad6fd53e) +,S(9bd52baf,cde37895,9439aba4,b1fd4080,84441657,c2b1b36,c45446a6,7b661d6c,87f63761,6dba07e5,96d71dba,f86df28d,c506a123,c6f082ff,47886a93,da068ebc) +,S(20cfa2f5,b391d687,b89cad8a,a4c5ac8d,8624d4c1,ebc94cd5,d47999fd,3278febc,1bd4a896,4641d8cc,f6926323,8b1be2c0,49141736,ee780ba,d2110f27,a674239f) +,S(e54db30e,e18cff40,56473478,2c61d437,c79adc23,51739315,ba845adf,c7e8b6cc,ef631e42,9529a407,cb3f832f,6aee6fb,a26b125c,fd28f43,b9f07e4e,ad8b0632) +,S(588f13bc,3dd3b927,7508ca9a,82ffe280,fabd5cb3,1413e848,2a2aa4d1,78a290b0,95c81a4a,44e6af9,5d8f6fbc,ba3884d6,d6a54057,1835184e,50f5db88,d08517b6) +,S(1927e8dc,ddc7ed4e,62a32a82,bd4a0977,fe24a571,10b1acf3,78826484,de7e757c,e0a9674f,76122a18,dc6004a7,ebd1da86,f98e896,5585518f,bc5f91d0,4699719b) +,S(7b82c663,aa2201cd,71dd7c2f,b8303264,8639f9a7,9de52706,e2deb38b,85dfcc36,90dd6e59,e98c611f,a7162fdf,8fc503ce,71b0ad1,dd150698,e4c21916,d5ded962) +,S(a15fa4f5,97086036,9e9c3946,5f16a458,c7b36ec6,6ad384db,7803ce19,555a2bbf,bd406283,43e40d18,25a02557,6bbf752,35e34400,dfabf022,6cf2bd3d,8fe80901) +,S(2b6199ea,7c42b7b4,2230da51,a895ba86,83950dd9,d4d5ecef,80512976,a0df55af,26ecea05,16faa497,3fb9865,16415ebd,93ce4a6b,e4b5cf11,3507d3e6,6a70b692) +,S(35ad2f4b,b5ba61de,364e8198,f5404ecd,4cdbf26d,7072dbed,d9892804,364b43f4,5481372f,7d1af5e,9e60cb02,ae8512a,6bcee9c,eab1344c,6ac5898b,aeca2e94) +,S(f4eeca4e,2ab38839,8a459df5,b94cf98c,68017522,353aaa98,bc606bf7,5008c6a3,e016b7f9,aba6e910,6a647662,1e7a5b7,12ab97f6,498f451c,21902e0b,9b6c2c2) +,S(6c488180,aeb6c444,78ef24de,21a47431,b2e26d9c,bbf059a5,84631829,a75ec053,ccf084c9,38491cfb,8cf0349f,fe80a315,71bbe0cd,dad9a7d,a4434cbc,9160baae) +,S(a52e5bcd,2214d405,57360828,10ebe384,a94f79a6,579a8966,6f1ef7cb,bc80f4e,c28bb594,e15c47df,9bf4ef2,2666fe4b,d916dd9b,e62b60d3,49c2ba11,506fb79d) +,S(c55414db,3374563e,5c79d9b1,1103ad01,7b7c04b2,3afb5431,8c469cb,49ea9754,f54a4335,7bbaf088,4d18bd70,6f3d69a2,44f4d527,a6dccf5e,52f468e3,752a998a) +,S(b7771609,335ac0ee,1e82539,3fd3cfad,5cb4b06c,98a05bb9,95966e4b,6fc1f24e,f305d878,33f95e99,ff6a3b4a,2b77ffa2,4cddd5af,d253ebcd,d60abb1,438e0745) +,S(da220e1c,c66af350,10736e75,483e2573,91f6d2e1,d355d05b,8471cbcd,4b64832d,bd028d5,5db1c54b,86f6f123,bbabe6b0,f3e52e02,ca48d92d,464311a,aaad3cea) +,S(1a680b36,991edb40,ada892dc,6c102b0b,186bce17,280f9850,ca50eae4,6951ac7a,f03d7958,b0789cc1,43d61fc5,11b70f9f,1ef17239,dd6a057f,ca394f62,225ed9f6) +,S(af8ca10d,b1975668,b8071ea9,5d474b5e,424d461a,e98b5ab7,bc240cc6,44da9c57,e74ea4ca,59f926fd,89bb2bac,61790ee0,50d746af,5e30019c,5b53130b,9cb9786) +,S(e6014570,2ad63dd0,5d98c576,c3d5158d,162857f,7b83045e,d91865ac,bb347922,52931836,4a9fe323,40f13c0e,15c955fe,f718ec64,4b45b141,33fa2edb,c65baa18) +,S(56eedaf1,fec96ae,c2f1e051,9a1c4a76,dc0ccd67,1781cfbf,7804d215,626dd5de,adb8a791,b73aebc9,c6406e2f,83e611b6,286761d1,a6c759c1,de85658c,a4788923) +,S(43c5272d,a3dc8c2f,edb0f5bc,a5bd5f40,fea4bd48,9f367675,cb578690,636fe0ad,52c62fe5,1cc2dbbc,57de501b,839cad13,b94c9e12,12b1cf30,d8463605,f7871c43) +,S(66e76528,7cd0ebb1,9d9e0d76,aaab4230,1aa87367,c3a3f96a,101c6125,84f816da,39a4d3ef,8d263217,3a3a8c3e,d9c1b460,e240cdc6,9c9cbaf9,89535604,a2f28edf) +,S(1a274502,31f1b5c4,9df7564b,f311a7bc,d5123e75,2471c243,65c0e142,d3b292d4,5eb550b4,ffcb5e1e,c695f22c,dafada32,1e967ac3,7e1fc20b,e0e695c4,324c1131) +,S(36f1c3b2,ab6a692b,5d3b1e10,f53b43c7,7d5c4e76,90e089dd,9e70eac2,773c3620,5553cea3,8e56a7dc,384458b,84c419cf,2d493246,1f75f16f,2d1a547a,6fdf0289) +,S(1ff0f8e7,8318fcb0,2b23a1d3,61015c67,6b1a446e,784bbdcb,c088b241,3da40369,39db7b2c,6923a1a2,379b58ee,cb91ad5,554ed5c5,60d5ddba,225c0074,e9fa4415) +,S(c5d7b7f5,d6dddac5,2a2021e8,437f771c,216bfb43,24c57ba2,e8b43a0b,dfd17e8a,78fc37a3,9586cdd2,f1145cd6,f9beda83,43e8ee5c,854c256d,419fdb4,1c9d2bc0) +,S(4af5a3c8,cf107e16,fdf3522c,47fff7c7,b2fcff70,c6c8b36b,7d66a3e0,4b107250,b1b6e5cf,de869937,45ae8632,c5e2860c,76a5f481,ac24ac86,ad135136,e9ff4e04) +,S(37b59d45,86fff48f,67ff3ea3,f31f721c,3daee8f1,a2ff960e,3f77b793,3e35b50,73a7d048,2c93b9eb,4c2f6359,3ce61497,ed455970,9b2ad7af,2d0f834d,6f070d98) +,S(6e9dd180,d5b7c41c,5f529439,e46534ae,b80bd802,b8b12e0c,ccf532ad,a99e663d,e981b043,e936da7f,ecef09e7,cd118646,5bdeaa64,45a00a59,1139eb9e,5628004e) +,S(fde9062a,9f7e13dd,39117543,be4aa5a8,fa10b810,a2285661,720b4586,68acc236,fa39cd20,a5eee1cf,3727df99,32c5289a,96b1409a,5721b9bf,1ad8f42,ee35069b) +,S(d7ef4012,ecc74538,16c392d0,4d1ffdac,76a30992,4c1489e5,159149bd,84847835,b2f5e699,9883a21b,edda98cc,ccc1ee2f,258fe291,c508cee7,39619659,e18c9720) +,S(8355ef2c,f0e37956,56b77adb,5f700f75,47e2c14a,b5f6a0ef,8716c99b,a919612d,d75dc6c2,fdf0260c,6682b16b,42d022f2,f03bdd1b,1e6ef520,da295465,a1988eee) +,S(cd49e795,63655bfc,87bbba18,b72a0c50,52568a26,53bc0543,3661f3e2,2ff159ba,ab28dd46,696b7414,1365316a,c8cd8dc3,2c2f5e01,6ae34302,d103cac7,4e37d25c) +,S(8f93b20f,28f89a46,1afdf08d,7550964a,dfa8df2e,ba2c00e9,9d351b84,2d6e0b78,92ffb09,812b6970,7746493c,c833bdde,6849a2b6,ee7778b8,2b41adcd,62b5620e) +,S(a7b3fa74,4621cc50,f6719d0d,5fd3f2d9,6acd3163,4dad1114,3ece3db5,d114ab2,948a3716,9394841d,68e5b64d,2f86798b,d78c8530,bb8d4d61,f82b5f51,ed0f56c6) +,S(e16b540,d62e3237,361ba514,a11f2ccd,ff72ae57,b37e58c5,d4c3c49d,2cc8fb7a,67efad5f,f02c36ac,a0c0ab0f,ee5e5135,fa7bb3c4,51472d37,abd0711c,6618a7ff) +,S(589645ff,5c3dc06,9d2ff542,5278a51c,c4fff14c,3de96036,b773497f,8940d240,1ea7ba1a,95f65259,c30ce21c,a95b3b95,83d11b10,3c8e633f,6dacbd2a,fbe44116) +,S(d551239e,3448ccc8,9a83b8dc,41396df7,d3db0c3d,f79490be,9d44636e,f5f0d0d6,779118ae,a8db8a05,f2231b5d,923e9d97,5e69a462,5c2ad551,5a8e7777,b1b25899) +,S(c45a22f2,9f611893,d8577d7c,9c1cd46d,82f41b48,a7c18628,ddb609e5,abc434f7,515624f8,5776268b,5a5c74fd,8d87f8e3,3e47648e,2eb8c2e8,27e9b57f,7fee5a1e) +,S(fb8e4546,639d9571,90f2840a,2f72ba12,a72063fd,85f160e7,18477d01,26132b85,3cead630,f8bf75c9,31d19cd9,6f4f3718,1efc4854,b937ac31,c3e0dc6e,363db575) +,S(ec51e7e1,6cbc70cf,1f053860,fd21e120,98b652f8,df9eb31c,74eb787e,87e5ca5d,bd5afa95,6996b7b,357b475,fa7a326c,d6c2505d,1ebf6fa6,feaa27c2,c2685867) +,S(52c497f6,f8b9189d,30fc42cd,9c2a44d4,2d4f70ad,815ccf05,4f50571b,2570bea5,35f54d97,a45e2712,b0f9a720,38adbb27,a31cfefe,c065ba9f,883d36c5,c070e9fa) +,S(2fd360f,1680b7b6,5f49f64d,5a648e8c,97e4a756,fe88e107,91fce9b6,295cfc85,7a88eccf,c4d82e86,72780c6,e1c34bb7,51a6029e,dea0cb77,3d29a85,b0689f5) +,S(7b328546,25307c85,f9ad0c31,ce2c31dc,e746931a,57ec42ac,16231165,74f63d78,6862d363,4360e404,9693dc03,772f4840,4a30f167,993c8f1b,56244c0b,af6e29ec) +,S(af76b473,4cf5f641,25124792,fb558b97,df60d67e,41c2b104,ba27ff35,e3be96c9,21e6d4c6,c1e0d3a0,69520227,c4cf2ef2,8204d85e,26f4ebc4,5d6f81cf,10defdb2) +,S(5b1237e0,54c98238,df2ccb28,a5b42b64,cabac24d,1126c8ea,5520ed69,ac449521,de7ac1bd,4994cce1,8800ac0d,5499c33d,bdde3096,1a0c9028,58de0325,b91ffc36) +,S(b81bcaa2,25743a49,36fec95e,13c8c20f,f818ee5a,6bda3850,870492bb,b3380d5b,6ea959d5,483ea6f3,5b3a4a5c,1987673,a8196c98,d8efe8d0,3aed5884,dcb391ce) +,S(5f6ca7cd,1054051d,3d8a2a83,73be30f3,516b305c,feffe073,ea2773fd,77eeab3c,89287d8,22775f53,61c931ab,bbc43d38,380488fe,5e35124c,2daa5441,3b36c126) +,S(ffb3a36a,8345f9ca,30369f21,f04dc9f9,d5f0282c,d0e1d68b,f5ca1cc0,c05ca91e,21ddcc3e,f5a94fd,8046295f,c0629b61,b1e8fea9,364fe659,d298e0b1,be5a6c17) +,S(51902e3d,8801dff4,e6bfe7e8,8f600d75,42eef0f6,e186df29,3a8c691c,d57b36f6,48a27fbb,cf9dd38,a1ab966b,f635fbeb,35bc3fcc,52f0cae0,d9a3ad5b,2654eaf1) +,S(f1a68a75,8f0f8937,e14a48d7,15c4cda0,679d9b9,12682182,493cd9df,c3ccb345,db85d3bb,b8431e56,d21e8c1f,4eb1c750,225bb222,38da0bc0,30e5da0b,d4f4a985) +,S(81d88ea8,4969d53e,fd0aaaf4,248a3558,f37059da,a4b3d32,da538bf,ca1a4d15,840fe961,11756d96,5c8cea1,32067ccf,31ac66bf,e1086f16,afccdbed,f16a2d33) +,S(b5830ab6,2e236cbe,345044f3,af940029,39b00b52,e779ce10,b02c446c,84163e95,d8720333,b210a391,499f38e,134a0989,254faef5,126750c0,ec2a5850,e1d4a821) +,S(b50caed0,a4e9e41f,f03d16ee,1848d92d,d4e6b76e,4e2332f3,793e8650,20bc4d11,39195ffa,13745502,eed8801c,40f36e2b,d9b636bd,11d62388,8ebab8a6,41d3ab54) +,S(6190402a,3750824a,149945fa,df942c0b,3622acc,b2ee1304,f260593,8de5c333,290f4d4a,73a1c72d,c5ff4228,41e2949d,966da112,5278d082,ab779e8e,d4cb179d) +,S(8966488f,4e991a1e,e34552be,c6246b2d,b9486442,47fda545,f8083b7a,b0435060,7daa3ab7,87283446,a7900c83,b726b849,f7dad684,6326148a,aeeb6233,738c6c4f) +,S(edfa388c,fd246c1c,6bb7bd9e,6d9d335f,9cbd7018,ff2a750b,4ba976d9,dd922b5,c74e1113,f10e6954,6848e4f4,11a5afe4,bbf7dfd5,d252e66,5789627b,b81ce714) +,S(304740e5,1b99d9ae,97de2a55,8dc1abc8,60bb8b5d,a52f6208,af8e28f8,89904951,8ab409b2,3606089e,4a111377,c8a94e5e,75ecf098,4f62aa63,faaf7e18,f93a37d0) +,S(d4ca8aa5,e31028a9,37d77295,96b011aa,c26f58cf,3a7ff671,99aa7f30,3e00bc30,5ecc09b3,bcd9afcd,309280d2,617cbfb7,e4a9350,b4ef79ee,1e46a8c9,56d46fb1) +,S(4110ec3b,ae03a061,59910aac,4f2e4bd7,77d5e055,4eb6920d,aac4b835,2d7cfb4b,c1237e1b,d6f1cf1b,6fb0f248,9e3712ae,5557e4b2,f72ea7a2,2c482e6c,d84eba92) +,S(f7c55f97,3e9df72c,c9da8e04,b1926688,1d53f810,fef5e664,99b81f44,e4f9800,4b45e93f,e02c3993,95238c80,b65533d5,ebd01cbf,1b3dbf44,4d550cbc,4652fa89) +,S(2de3290f,56fbee3e,15def5a0,5d65436b,9d722e3b,a435f269,a5ee0231,857cbd29,f80d2ac2,356ac72,f3106b47,5cbf3701,bf924e3,48e93c9b,f3327b55,bc203828) +,S(c8e3d2b8,21922146,1862d5d3,319c2abc,7dfd568c,59df4367,eb975a95,6e22fda8,d6ec1b9c,e758a8c6,47e718a3,ee8ae232,c416d763,d2887e19,54ae4c30,30404f20) +,S(50c1a147,c117d907,fc831f72,9be19b3e,e93733e3,aa3bf402,e64760e2,edc82065,acebcfda,80706b53,116e4cc8,cdede6d,5aa1b7ec,62ffc942,572f729d,47396289) +,S(7bab8930,55114c0b,e4f7637d,ad165491,c21d6970,c8036375,1387012a,7b785528,6e31589e,2ecb13e,b7bca5ee,39e3bca,fd2e5645,6574a642,131d6178,901c0d97) +,S(dc94ff4,44a12ca9,5180904e,58802ed3,d1be43d9,8396360,e9e932e5,622d257f,ee2a426e,4da3dbf9,8a6d5ad7,9a5437ce,6fdbede1,25e836fa,697685b5,989c86e2) +,S(efb2b411,e66f8e8e,186b0fd0,c572381b,e9edc68a,903e95f3,759a11b6,b6a9dc40,4a7af79c,a1383f20,55bd080b,f410f554,24a21ae5,7b57b63c,bea36486,6c30dbd1) +,S(2f37ff22,26a0c4b8,77a36da6,7a423f59,497a26ca,8066a651,c13573c4,4954599f,f9d1c91,2b74f663,56798637,9de41a46,683a7cb7,61ac6e3a,86d65094,d1e07a8e) +,S(63aa61b2,e24fa178,95688d95,442844cd,7e68edcd,98eb3496,ea071c4,5b46abd,9423daf8,b6c241f8,785b76ab,a40803b0,97da461d,cf6579d4,4308c9a5,e63ac4e5) +,S(58618e22,93c52375,4db8187,34e355ae,27b73f7c,4469d7d9,115623f4,e8e20900,8531be34,22616853,c2c095aa,138819b0,bccd7c51,1380c64c,65ba2500,ae18794f) +,S(61418bdd,2619e7c8,f32c8cc5,34097cc7,4a9a0c57,a38db50b,ad828a60,f658fc0b,acec4e21,774d283b,db9a8a11,115d20be,20cbfcd8,2d67b10a,3d57dba7,74537c48) +,S(79ed2dcc,dd4bd25,67dad04a,b32c9273,39a9c592,95a69b09,be7965a8,c779b2fd,64860dc5,d17e409b,4feef8ea,8a7d7350,3eec186,1fa15f8b,f5576a9a,39f65283) +,S(a20434a4,c51da2a4,c7a6699,84f41ef4,67bd4de8,a628fbe1,385693ee,6b6d8a52,e2a00a0,d00aa33b,b49743ae,6f9c824,d2fe1f7a,f51f7720,cfb0d800,94279dd1) +,S(d8c0bf47,530ff603,c140503e,84fdf6d1,ed908b98,cd27136d,ecb2c4ce,da9f8c61,19e02399,bd898b4c,b9987fb3,4262df35,9b32cca,430e7cd3,aea9d20f,530610aa) +,S(29f06c46,a20b5387,aeb6e490,ef9a7bda,ce16fc2c,8e8eb202,b75973ea,8dc4f3c0,2220f678,daae0cd6,8514c091,a1dd7060,b21c2630,138b5e32,e0d57d79,b7b06d7c) +,S(b18aa504,d9cda828,e67d4f55,ac51c961,e9603d0c,ff737c16,42f1c8b3,fe81aeb9,1f6d7e83,480a9290,789c016b,b62e6e8c,adb4b500,fac710a5,7969bff2,89578ba8) +,S(e7591f42,e649f9f4,477c9cb,bc8559e1,f01eeec5,e9f3a0b4,8d9bf515,6d2044c,24c8777d,5e7c3f7b,2c6fe0e1,cd0e3845,45bef898,aff192ab,c4e719d8,ae466385) +,S(65992fef,50a1983e,bca478b,419ae258,77ce7a52,339ecbe9,2394dba3,8ba72081,32491cbf,baa7f8a,9cf21a4e,57ffa85b,eaba7653,d46d9f95,b4e25212,7bf76781) +,S(771b52ad,e47d035c,ddbb1012,bb89aa9e,b774e0bc,aded4998,86e1e358,ccabf9be,1a897dc8,420a076c,5a723f30,206db0bc,e9760b09,1f698952,1c4edc17,f2dcb202) +,S(a7d5c532,bcaa8ed6,6846046f,d1570837,111281c0,795d3e50,16cd8108,5721d644,13ccc5ee,4bab0d34,2f740ae9,e538d50e,900aa30c,bfe99e54,c69cecc,f18f6aff) +,S(fb504652,a55d01c8,b45ed7,6c71d,9067026b,27e9ceed,c38bf6fc,aee16d50,a150b6fa,f37b0c6e,ce4ebbef,22277b37,44933fd7,a135a25e,5ba8f7b6,1a6b7d0c) +,S(6242a221,115863a3,73bea0fd,39974dea,3c33b794,68e04087,8ebd8bf3,ca09f1d,b806de29,fe9eddde,1556c09e,973fa20d,c4ff916a,3d22504e,19e33169,f6f903e2) +,S(30382a2a,fefc7110,77af1a7a,d8a4a4bd,622635bb,73e50bab,c58116af,d1e8f3cd,d7ff3c80,9845a620,d53299ee,98cf3c6c,499ade93,84791af5,d6618866,3b6b74c7) +,S(b69ab576,13d1527e,990d747a,bab1582c,af995b34,6b25ed1f,df3490c,5549f36c,cf896a0e,4878bc0b,ffa3a750,f83dd329,ade24fa3,76acdba6,dfdc294,768e3f41) +,S(36f6c331,4071ed0d,b2be8f45,fe19be0f,9b37a675,a56679e8,bb49925,9339257c,d593ff7e,a32103e4,9cbf2995,21ad3da1,5b1b44f9,d6c95418,9c794291,b1e6769e) +,S(fc312428,7a9ab1b8,3efce7f8,17f707ae,320dbe77,e5937cd1,513bbbbb,90ed9995,11bce5f0,91dd9ef8,42a46aee,6f3a1d,7cc23da7,381a5f24,4b5a2638,45b2bb0e) +,S(b0de8720,58e1165f,ae1207ec,5ec0888,5f14bab9,35a2fe6b,1f7212f9,7b4913b4,5bab24ac,2589b8a8,c5e102,26a907ac,391289ed,23fba10,b2acdb74,a142b395) +,S(699828ec,db84587e,31ad233d,c27ce5de,a8f4e03e,2c450706,d625e387,12c0af3d,db1d9e5b,9a74caf5,855aef9b,6b8d0c18,c98c27b8,ce0d8a67,c6bd8467,261f726b) +,S(8d133509,d51edc48,97830f8b,3f8a6688,7a16834a,5ea31602,1649e219,cf899cac,9d188e67,2940f23a,39ac6ae4,fa532478,9c5df2d6,57f8b4e4,eca17e02,5560f08e) +,S(9cd47f8c,a9d3ebaa,d94dab36,4412ac4,a74a4b18,bb516538,10da1df3,9efc7582,de1e5cb0,fd5e7a20,322636d1,883b1ce9,71bd0565,a0eb60fa,559b552b,34b42e1e) +,S(1fef4107,648ca126,d5c4fe59,1f190f21,57274d0d,d9c57fdb,ffe2c348,35d36ddd,abf8fe20,87ca3feb,d8150e5e,c66c5d07,45731121,9b759430,4465bb14,55f992ab) +,S(e372b12e,8d3fed92,9e01babb,1a6517c9,ecb54d3e,6d0524ec,42ce57f8,5351d32f,43e910a,32447627,e2d9d5ef,53cb9c0,ab60333c,b07e72d1,c2c6644c,83e7d8a2) +,S(37c346cd,ae9d76e5,7ba2f30f,d05c33fa,3e6058af,642fb1c1,1810b4a0,b97e2dd5,9939c619,e1e49ec2,bf716714,1c23e135,157c7e4e,949e4fcc,b7dac7b9,7d4932d0) +,S(14e337ac,39f0c1d,98333716,a6e596eb,ad0d0688,b815c7a0,c182b546,88e5c3bf,fe45e34e,bfb94cff,a72b6312,a422562c,8ba782e2,16d5ee31,6425651e,e67d3d22) +,S(25517b3f,79da61ae,dd50cd1b,69b1ee36,fce0a44b,feb572e2,e6eb4aef,d751146d,7d2a017d,b9089d13,9a072803,dba874f0,f169ea36,95786e13,7fcd36d8,8b28a213) +,S(7d5957a6,92fd532,b9991383,cae895f2,8554e6c7,83ae3bcf,e72e3678,3475cb46,fa4b9b07,2bc725f8,e35b01b9,590ec1d8,f205f6c1,3203e91d,d9d39954,922d7f65) +,S(77eaf892,c4f9e0d,f63e33a5,1c088e0b,323ddff5,6f854475,b143b458,3e0e2f81,93d0f67d,51abf50,ea260593,96effe6,7f985caa,a9d68250,224e7193,414105f5) +,S(812c11a8,2851f474,e5a0a175,fb527539,7f1c73e7,6a766cd8,7147c9c4,4c970ec4,f9e22a19,a35179de,30379c37,a616d226,666311d9,4ad62b6d,59fcc579,cd024af8) +,S(b633f071,57c5a0a3,7ff5f626,17de24dc,14b3bcd8,4eb43385,e5a59be5,1c371fab,93e70e48,68ab5a3b,e29dab87,8a50e2c3,a09edb5,bf5b47d9,a09ccf59,53b67673) +,S(5e78caf1,9a2031a2,d92e1ba2,1f43f91b,10a98672,5d23ef95,1bdc1f83,cbb16343,b438317e,9446b88e,92206d81,883d5f3f,6497ec33,d144cfc,3a7dba41,db53cbc1) +,S(dd082ebf,88d49fed,50b76df,8e64d3a4,a1d4bbb4,fcdee50,c3ad6d0d,a91e4ec3,9efe99d2,f15d46bd,26d67bc5,ccc122ed,bf5034d9,28bcc946,e4714784,5edb6244) +,S(1ba1e135,62c06b5,63db5c49,7ed46ee5,73399a56,15fbfb1,4e080815,874e6a2e,f298d5df,43111fb,2f050cfe,2a06b3,c9a1fa02,d409dbe8,a225a3e,bec2d8be) +,S(49477847,a590a536,e7370341,5380459,843da9c1,78a1d176,f2f0133d,6ca214f3,3d1b8f64,a1d94169,2baeef3,86b4740c,4eaa84a9,15e4d03,2bd7bfd9,f5d5bad7) +,S(c4336d6a,4fbc288a,2c69fcc9,691fc8e0,e277fb98,e34b7a66,bf29d2d4,32c1339d,64ca0adc,72f0ff2a,f150f01,ea243a51,e91da8e7,480e0553,c7bb268a,22fbd383) +,S(a510cb67,9970c117,49e4e9d9,acdb97c6,d8712ca2,7961ca45,ddc9669d,9e02207,afa065b1,46b75ee2,ff7ada4f,ac7b863c,f4937cfd,15ca2ff9,c0901c7d,faac88b7) +,S(7cd63347,59eec80b,666237b2,abdd6c6f,e5e24a60,9305165,b5bb1a04,2898cc7d,abf7dab,f9e12893,a8040b13,afe16524,1d749660,93cf2da,157e2a78,e89cc758) +,S(e0786f8d,6f339bdc,9ff47416,4070bc08,c864d0d2,6d507762,19c2ee87,61cb7959,892cfd2e,62f4c352,b296a508,455a1dee,8dcec943,f5109add,9d38437e,87ec58c9) +,S(d81f740b,123cfd5,9c5ceb73,47668148,995ca21c,a3ca1b8c,b48e20db,32f6b55d,3af34294,c83c41df,7d5f821c,68e71e34,4656be14,f09d1858,7a204244,6f74f4ff) +,S(f4ba0503,6ffc1812,efbf3fe3,81423d91,38eca2,a67a0f4c,2d0474e6,5db9efc0,b2b3c3b4,4af46f2d,e53b1e8a,adb83d59,4c32b6ca,a7113207,b7993bef,dcdf78b) +,S(aa6f03ed,50640e0d,72fa4de7,ec3964ab,82e7758f,5e6c16d7,78c18296,e3b1a527,322223f7,ecf473a8,36bcfd41,e50f871d,715f9729,93df1359,80794587,59d9767f) +,S(f2d48f68,23984bd9,e8e87772,28da095,4ca134a0,6b43e0d1,1a8843d7,1fd0232,f0b7d9e5,982d0f6f,5ef74bc6,78ee504b,6202f52e,8db7c069,e179d175,c6f760e4) +,S(70e9ec90,7db14601,9741a4d5,ba604187,a7313b7b,500864b5,383b3763,be303979,63f9ef9d,eea1d1bf,a84e0d19,c8f15665,60b4f1dc,839aef5d,b6fbef7e,d6dc6a4a) +,S(23cfe5f9,7198efd3,f34f657d,158f092a,29748586,29983927,9c58944b,146cdf1f,3b8fdd8d,cd82a757,44152552,35de0cae,c39e20e5,f82c7b6a,2afde8f4,1c6afab6) +,S(b1e2b9d6,4c14d667,4de9a6a7,5499cfb,12b30a92,b9bf7578,f8fdbb55,b6d414de,1e91c321,24341a58,e2c6d65f,18f3f735,f9f98d2d,76d124a2,c694db84,37cd0483) +,S(5092db9e,5bde4edd,f385c67f,357e43a7,c8fc8e09,f5c07c14,25bb405b,7e52d1fb,cbad30f3,f96767f9,553c9be3,2adbae2e,1f27f9d5,3fbb2f99,a361056c,ddf52858) +,S(59d39b90,2143ace3,3a1a1e54,a5cd83e9,6cf56f65,4a91f524,af8c8e19,e25496a5,be21c89c,baaffe09,4f2114be,72ff26a8,22db9a1b,818d96a2,bafa797a,3af056a5) +,S(89cc95d8,cf45bab6,9b3f86f7,9e1fa71a,34fa83cd,3d4dfd16,1c9df1b5,817edc16,5eff0aef,63fc853a,f8b65e8,8a45740e,6c78aade,4bcfeca4,c7413ad6,714eef84) +,S(6c2b8809,79398e60,87c756c,443fb032,f2adf5f0,17bf9ac6,44d164b7,d2aeed3f,bc46cb71,c9ed9f46,b34a22cc,e1332cbd,44318165,85407951,580e4b26,270f3eca) +,S(767ca583,c950f7bb,e3aaa6db,b6aa9867,792e0b8a,6930ab97,5c46d09c,30e14a6e,bb90634f,87133104,1c7eeaa0,4a09887a,e5946daf,e88828a,68761cb6,21412d49) +,S(cf742ea0,35c4d9a6,40fd0686,a460ab96,e2015d0,2c15fc8f,333ecb7b,8af4b08d,2bb94f28,bd69b51e,de993065,fd61fbad,c65fc62,90059a8b,d29948da,20b704e5) +,S(84d5d76a,a5a6ec84,52f024ea,b365290d,9c3b6be8,f33a93ea,b0a0ac4e,e6271059,f5565742,f1a47a88,8d0bb802,b002ea6e,f5acea8,864e2f64,fbfb1565,dda51952) +,S(8f5752a,8fbdc1a6,201b6e0b,7bd5db3,cda2eafe,f18cd6d,559724b9,56767d32,d63c0fad,de72b753,6d0c8606,88e0a82b,9f9e35d4,b1db7be7,efa9040b,82298008) +,S(20578def,f94e3597,50ee95bc,61ca76db,f8fc059f,e25e42c5,bf887d49,665d1871,5fc52a36,c95c6edf,46bd5c38,60e151b3,9f123e9b,c58b2079,cd165c1d,e6f33d3c) +,S(30f2b825,739fdf4c,5af0ca08,47f50323,d3ad6eb0,413b052e,525f837c,38f97a4e,d698b076,4417357c,a49b4306,7d73206f,d3d97036,26ab15d4,f11c56bf,4bc820ff) +,S(2350eca0,b4d0c460,12024be,6d458444,b37b20cb,50042830,182b5e41,d564e26b,5909eee2,e3999d60,4cbe0832,58012001,30a344c5,f72ff127,35e66cdd,904623d7) +,S(ea660cfc,45971e57,852d382a,ae8cc6b,1887fe68,dc1b84bf,31f4409,89f89b2d,52297e86,dfec0730,81a280f,9451623f,9e69c320,6f3c205a,f07e56a2,54cd5837) +,S(9cded450,2a7da3bb,77e06ae3,ef398954,7687d21e,df522f3a,cb6b4fd9,d3d49beb,7b13f455,35a49049,277abc34,3cc6f0a,336242e8,7b69815a,e27122e1,d7838a8) +,S(ac8705f2,cf8dcd77,d409a962,f98a6abf,198dd238,3a5eb258,6b0d2def,81daa172,892fa835,a0af6cf9,dd5bf158,44b22cf8,2af258c0,519955dc,ee4966c7,bd5e995c) +,S(fa026b1b,d5e5fe3c,d6b144bc,6b22f7e7,5512ca6c,9525f62,fc7fb4ea,bcd2282c,4ec40de5,7ffc1768,edb20cae,d3a11380,fcc32f45,f410ad9b,8b674d95,6614aad0) +,S(a928eb73,28285c79,5717dc0b,ccb5280f,92f9a4be,5a0b0ed7,67e58eaa,8b9097db,af57cb66,61a9d08f,4d4e9e25,aeeea2dd,e4c88767,c4e177b,37a87ba4,c2bb772e) +,S(bfc9197f,80fded3,c601a0f,1c8c1d77,cbccaab,1c8357ee,4fb67875,cbbc8261,6a721e0,241ef436,69cd386b,d07fa2e8,900527eb,ec3c0025,24bb457e,1bc7aa28) +,S(ae0de043,b332bb4f,91395870,4f3a41f,65e0f3d9,ff77c1d5,ec3add49,6087d5db,34d697f5,dbef1bdb,f581127d,bcd2755,a5a6b32d,73164665,ef84f6bc,145c2afd) +,S(4433db73,29d75b3f,7df0e229,538b7a33,e41183ad,7a7a5e3e,ccf5863d,6bbb692c,3a66630,a03ab85,9f23ae3c,a0a38717,d82ac240,d271b3a6,ccde1407,d0dfdfa1) +,S(bc7380bb,128a6f8a,5cdb971c,31ad12e2,ba593acf,718f5468,285b7f14,69ca2b90,a17af518,9a7b0445,cb37e797,a281c84f,8cf8ecaf,c661e601,4ecc2467,18f1d8e4) +,S(bb53297b,18d2d785,a4756437,70b387d3,ab0fe62,8b78c09f,bb6cc226,79bc92ab,5c34b9b7,cfb3737,bb515ee8,fcff8592,1fe8f30c,e97d21b7,47a4b084,22b0c811) +,S(1accc1c3,f46945d5,7b46b1fa,15291ae4,2f0a616f,df23f1c3,3f0dcf97,53851fb6,bb434ef5,e30fb9fc,15e99b15,b5f9d766,9681be30,d2b0a6f5,a4946268,158d5369) +,S(2fd61a9a,b99c588d,fbe74fde,e8ce95cd,1c0ee9a6,da7ae59,910485bb,9a3ed9c6,2c214840,e2bd764f,74f9db81,43ddd549,3d322dd2,b25790a8,a681c97e,2fda07c3) +,S(4bfd09f1,4cb492a5,7b9ef3ca,d245a0ab,c4bd97ef,12bf7204,8ecfee47,660f7161,57102f3a,ecc42742,657032bd,aa36526c,e67f2589,2775fdb7,e8b029d8,1cc7ec9c) +,S(f60eb13a,8e6485ea,fe653e74,de1c1376,2df7ba0d,4ff0c65f,24bb1c0d,74cea3fe,c5830078,5b74cc82,80128896,f275fca4,9be94edc,744f8535,128ba7a0,5c1d9552) +,S(2b4c7864,9f568eb1,ce1be63d,aaaba4e9,7c31349f,aa353371,6e9123f6,4c57b041,b5dc9c1a,b39325f9,3ead6f35,66c30479,5f817ca1,b3c37258,554c4fb2,51a0ca39) +,S(7fb057e8,5f559f11,b5d41538,6a25a77a,aeb904c5,d1be33cc,bece20ad,57715ac4,2352db61,6fad3f10,a2decdef,5a7fc369,5c8462b3,7d2d5ae8,bde17311,ac6b4ad3) +,S(a49bc870,bfd62cf1,1dd1bd23,9499157d,247ac61a,a9b34210,65d4d029,56f71a0a,b639709,88ffd1ae,ed1b62b1,83ba629e,f5f0c088,f8a9016,d7fa9157,46642e3b) +,S(30b1f21,f8dd3f40,697878a9,fa0b9fbe,d51c1ddd,165bd5f,ed9d1fd6,49ae913f,d5a55164,4628de36,25895fa1,471e0f5,77326d14,132d8ffa,37e0277d,a928532) +,S(8a015768,8aefcd7d,13cb3b98,373a8823,aad11a4e,718a6ea8,5fdb8a9a,6edfd879,e7d92909,4d198910,44c00be,69f267f3,84aca1db,642648d8,34a5b9fe,518e1363) +,S(810ee87e,45d8a5ee,c0e3fd0a,cb771d2a,5a3116be,f4dd7d5f,bfac0dd9,fe072778,92abfc24,9500ba0a,9cfa1725,da4c37b6,cf081f5c,c6cb6a8a,3af889ab,ddd2b7f1) +,S(a0eaaed7,687f6a94,398656fb,3fb15f49,6522c3dc,c19e04b4,598ac4a5,6408d1d9,792a67cd,677ae878,eae040e1,6378cc36,9583b513,bca68fa1,cca3cbdc,37aa61d5) +,S(ca438737,ffa6f30d,9aa695fb,3d29db01,f805f480,ddf1b227,3a0515b9,5f8eba97,56238731,ff5314f4,af6a3835,b30ae83d,feaf0db,dd4449e0,5736efba,8a8cd51b) +,S(b252f5e5,4b67554c,ba3d481d,66a2f223,a633b5e7,f335e357,29928264,e744279c,c6296730,5007e2c9,3fbdb25d,a33a9fa7,411218c2,87b937c5,dfcf8f45,472533a0) +,S(f61b57a2,237befe8,2f1545cb,131acb03,3015a5ee,f0cb77d8,c73add0d,ec0083f7,9b1e0c93,b326a265,eabf096f,f8eedfd5,9f765b51,5007c5cc,d0d3b569,838f381) +,S(30df434c,1051cc43,4ca35671,3957f964,af406830,38ce82a9,5cdf2c7b,55c50f7c,883bc89b,f54c490b,3be0d434,fffb6b,7e829be1,55280401,eaf44bee,7c445424) +,S(fd0ab148,727eb712,adee1fe3,4e3d0fe4,99bf8307,fbe18e4e,d20d5236,f7ac25e7,f5f38f32,df094903,b3219b02,8413cfc0,e56b8ed5,6ad80e5b,aaa00f4e,3877377c) +,S(b4a8fcf2,b406becb,6111c030,ae375f12,79de175,7f2f3b90,13e7ac55,12de747f,d1634039,59a6600a,fa05b1cc,3c459fa4,f1a5fd4c,27ee5382,c5f01e4d,a0259889) +,S(a6c10f0b,33d1518c,8f8b7055,b139aa84,c96e9998,8e8a256c,5883bb44,10687c72,8f0dfa52,ccaec6c6,789941f3,cab90b55,4d4f587f,bb6f3354,b5f7158c,758e4f9b) +,S(7188fb46,e244a5a2,6e38cf13,bf2e3c4a,ff5bdcdf,8d9f78ae,88213692,d866f5c9,8cb07d12,ec743540,3be09b19,4cfb2f1f,c4a85d27,d940cad1,15ab53ea,4b8e0d88) +,S(fe4f9f00,308670fc,48e45208,4063fa94,a6cf7141,d75a6ef7,4f92b474,5bf692ea,5dc45ab4,77f80594,4355698b,e95bc582,efea563a,970217e5,2bd28ede,d7e8cbdd) +,S(93f3b5df,43006183,47c7bc14,3eb046a3,842614ad,78d3cfc9,a6b665e,3327b7cd,ffe5f378,7ac36947,d635d156,7a28fa5d,45c0b5e1,70508cc2,7fd621b4,47b63b53) +,S(dd350a89,e0c3128b,54a3955c,bf802ff7,3a565760,39e1e068,e783ad00,36c13604,45cdb508,3c33c35,fcdbb29a,efddcc63,c4cf3fe7,c08a15d,8b2cd4ae,dec2c3e9) +,S(4f164801,17c1d338,7738b728,96442b9d,66f44eec,e3eeb7ff,ffa87d24,4226e44f,750e6348,490d0ecd,3be07303,5a8e653c,1b1f7c30,d89e27dd,4efedc9d,755b89ee) +,S(b7c62749,aaf79754,de281314,acb4b2f0,271f2a35,fd187307,20349a3c,a4b577a3,f100956e,ddc307db,56542c1,d2c8f176,e0636ba,b04877cf,3dad451d,edcb0df4) +,S(fa5c1278,1dd929a0,2ae4755c,70531cd6,c309261,36ef51ed,7d57c117,c1c8a885,57c5280a,5f08f0c9,393aab6f,eba0ae81,a32f8c6e,2a76c780,a871170a,e37856f4) +,S(e16d6dee,7830b0d,e6cc5e4,9b1cfb7b,50b7d89,57fa4e6c,42ce9925,2e6a29b6,cd5955da,4c1ba840,a3c98d1,7dea8d8c,f4a3d2c0,1e0cf164,2cdc35ee,87fea835) +,S(a2c659f0,a0ef6147,ba84ff26,ca81443c,ac8ba9be,f6fb32f9,50653384,a5db0213,5176a4b1,88b5bbef,3680e875,437e4209,d2fd2462,77c5f84,4a0eaf5,e9d8c129) +,S(7d507179,6a7c037,77fcf84e,62e6eac5,456f88fe,76e71301,76fe458c,8f301a68,14018264,59d3f62,6788fba3,1505c83a,4161674,21dbc2a9,dc14e1a,f45a50a8) +,S(642721c9,20d9b3e6,72db8d82,34ad60f4,bc74684f,11f2ef1a,8171d02e,b9eb1f12,fdde8b98,8aac7393,be2366b5,6e853c7,b72034fb,2cb176ee,770063dc,42b63d48) +,S(65fc35bd,2f604eae,48a1b68e,1d66cac3,627b1498,247d8376,47082702,293c97d,d01018e4,85dba402,17ac631a,9b88d240,de32ac74,79c7d47a,9f5d9188,f8ac01d7) +,S(65c8b230,2e51129a,b81de5f5,22217f06,f5d5360f,af191c56,8f395a33,2b04375a,3201b7ec,117fceb2,b225f137,877ef481,2be4d6b4,52d1c855,f73adb0f,e99b2943) +,S(b82aa6a2,86fb19a,d2eeaac8,9019782b,d0d6009a,8fa07a02,a0d6295,ea8637f0,426f8d72,ec1b08d2,72671566,1f77f470,f334e4fd,3370d96f,b0acca8f,2df99398) +,S(a3222e7a,c6c27f2,8b24b33d,ac78d873,1ce060dc,be055100,862e71dc,e6671a18,6f2c2a1c,4b80534f,8ea53777,71760fb6,5148d47e,ca097fd2,b7bb2f53,bb07ce22) +,S(281ffed7,48a4022b,c663d08b,5681733d,f1343818,d68c8b63,9f4405db,ad7020e2,b5f18609,d8e5c6e7,990808ec,b4fa7d2d,7d4cd106,b7ad2c6a,e356f239,9a535eea) +,S(c520ea8b,a481c220,bab0f218,72ccfcd5,d7014d8c,fe55d1ef,743af305,c0277d5e,e23eaf34,33e4369f,30d371d6,e396b0dc,a065506a,c4159967,fec4475c,8f6bf78b) +,S(54d39ed1,114ec02d,8005d7a0,82178175,78f827c2,1b55a95f,330a7af9,34727958,4aecf190,229c49c9,31862a57,9131aeed,5518cda9,4695e8ac,7ebf7667,d9afb23e) +,S(756b9bf0,1da8d7f6,1627cb2c,b3ce3ba,a9b6450,c2d24596,feae8bd1,2ef67a23,51c47b15,b2ac96c3,5d7b7dc2,d8c57ee9,69b347ff,dadb04e9,cbfd6889,a0ef70b7) +,S(eef22145,6ff200f,ddced960,f422588e,333a437e,d68c04ca,9758d77e,a938ac54,21587cf5,8b8ffb72,6d29aed2,3c984a4f,25df40b0,abc9b7cf,2c07436,ab7e09e2) +,S(b841b560,c0af44a,35bc9320,3c05cb32,250fcca3,f83dafe,30d1dbe6,61aa3d1,e7956525,3d07a89b,2335e2ce,9e11fb89,96e2c146,271189b3,461cf944,2ceee2d7) +,S(14b98f62,5849b798,48f32547,efccc33c,3ead6cd1,a290f03e,618acc2c,1ce065e1,4e7a2415,805a4486,476221f1,ce8234e6,5b81ee60,e1ce5eb6,b6a2e041,ac885e00) +,S(fb0aafb7,68c19f64,17e417b6,f1c22dfc,737bc74,fe8b23e7,4dc1c1c9,aad7ae44,88b83e23,631c58d,c3729cf5,54343721,e9ec7dc4,a889b85e,31cb302f,f2a6ab3b) +,S(885497ab,e34d1745,a3e2ff8b,bdea904,eeacf100,324540c6,86de137a,9756468f,63f3f160,bd266c3a,7c49b13f,c5b06403,d0614b79,17c49824,bf507257,2ac0b948) +,S(52dc7bd7,17e4d8e,8b634439,f6f06b8f,7121a0e0,cfebe7a8,3031668b,9832b8b3,90679373,9bbce1e3,5c48f41e,942d9f15,9161e9ab,273a2217,d9e857c4,3bdd0a5c) +,S(e6ed2c69,a8bd7af3,35591f4e,4dfba7ac,d82e87ee,e2b3bd28,f0f87f02,3abaa7c0,dfec6118,7396bd5,e32ba2e7,a8fc912f,1e54e078,6f2ee222,35adcd22,8feca28) +,S(9e2171a2,c1025129,1757e26f,ba979e5d,6b68c2b4,975c7289,2afe7898,cafc46eb,3dd062bd,210bfc4d,d30cf01c,51d810b5,cf1b8ee3,d3baf490,6bf5d381,b87c9a56) +,S(ef4b8648,3bf209f3,b1c2e166,a32cda39,44b21282,db8acb94,6ef62122,63bc44cb,903d1088,ccc0ba47,b5ac3252,33ef9b55,924e61ba,7ca80bd8,1925b269,3998920b) +,S(64ec6d14,7ecb6e44,6331907b,b9006b2b,fa4fb854,20ab9aba,f1026bc3,4ccdc4b5,583cad3,b41bbfec,d0817207,dd312cdc,26c0411,b888ce5c,c6ee025,baafac63) +,S(128cb9de,125429dd,e5b9b33c,ef9f34a3,e7b38ba,f22dbcdf,8e169894,3f7ae5a9,a10a01dd,33f5a4eb,66091348,c4dbd90d,62879ff6,7559229a,e53c2896,8fb4584b) +,S(a7d2e7db,ca0890ee,e07c4bbb,399a0120,e71fc284,c5b7c96b,4889fbb6,db95dbbe,b8caef70,404a19dc,15670cae,b19d5b74,e70b7492,50390b12,5f559b11,feda83de) +,S(298b17c0,b8beadff,5e6eafb8,ad7d756,8e961468,d8e12c94,78ff3870,dc722450,a0542f35,c7b95774,b1c10f75,3e9da029,ec7a54a6,97bcd9fb,46c98d26,91ac1a43) +,S(31a39bcd,a3d10e9f,6b46e1e,c30b41aa,557ba664,9b12db64,a13557d7,5c592d1d,814f1a6,15382d4,e57b8d41,351fd782,ce7dd9d7,86aa9bbb,c5b1ca7c,207ab12a) +,S(3317f1a8,1afa54f6,ffa6df13,bd3f818d,e9a29bed,7c119b6d,fa31560d,31d81cfd,aa8eb746,4e9acaea,19a42509,a23a281c,e9917788,6d3de977,4398c57,8867e095) +,S(85511857,80eab56a,274cad22,966ca547,3027d3c,3cdd7e25,7d8ed8cd,a5c6ef30,b13de0f4,45d71bd7,db0327eb,15438e9e,84fefc1a,464d8a2b,bcb8c6b9,f59f93dd) +,S(fdbffe5,7e378262,c32bc4b1,e84ae01e,a2d6dd76,28e10b04,9adf6a3e,ef106e83,f19d0c4f,1411ba50,35d3ef23,153f306f,d40b22c6,69e92ea9,22bd7d5f,83a98ad) +,S(7562779e,6aae0c51,52acc7ee,43bed76c,831ba008,82d89c9c,e29a5f3b,8855b3c8,c83c1662,7cb9e1d9,126e07b3,354b82a8,a0cd49eb,3936c14a,8d8d64ed,2a4e217e) +,S(130b292c,10d5b336,4635d43a,fb6d6e02,d5acec2,c2033525,ed72c030,e82a4a08,d534b710,e1201276,6f6fce50,ed6efec7,3e0c3e75,50e0bf36,d5d625b5,4855fed5) +,S(19fecb77,bcfc0db3,e595fe22,e96f1212,b3ed032d,183be5e0,ed4c1b8b,d0501bb3,6b0fafde,2f0636e7,2b4ea946,a0e5c27e,4e5dfb5f,e8b8a1d1,b36bdee5,75d02e81) +,S(ffc668c7,9c6f9fd2,f5c56104,aac1286f,cd4a390d,ca586af2,c348458f,b4130f77,fd7b748,d15f10b6,4eaf4946,34fb4ddc,439919a1,1155e40f,24f3eb2f,482445f4) +,S(b9797c7b,d4112aa4,8abbc827,fae12fd9,6d19f3c7,81626e21,5c26ddcd,b2d4552,ddb0aa81,3113288f,1fd2505b,d23f2a9b,a1ba0a38,dcbbfbcb,46da78bc,5c705327) +,S(9388c9f6,5bda9c81,62ec04ec,5345ff80,da4afe34,7281f768,4d8daa1c,cc3d7869,23ef5140,3f926d0a,d2ebbe6e,48858850,aa98149c,89490e99,65dafeb3,c82644fb) +,S(44cf864,6c2d2f30,e62f63fd,8e145786,80c1d5b8,a27fd496,a8e34bab,5f88270,9784e329,a434b442,fef9af66,b23ea917,edc0f6ca,8d28a992,bf6944ff,26c5cd25) +,S(ebe08589,930001bd,ecb83ca4,45c4a9fb,fd61b229,60ba9848,2e0fd520,1af5a0a9,ce2d31fe,3c271048,24ed891a,910e2cd2,2b99b39b,480ad812,a5d6860f,71ec817d) +,S(176d14f2,5491c2f1,c1d4fc87,a8f59aef,f560bbd9,41872f6f,2a1a6adc,7620f1d7,42c1e0f3,8a3379b0,c5de8a01,11b846b4,35db7783,caa9b84,8084a985,f0e123a4) +,S(74e96d3a,972baa6f,8ad6876c,9494f451,a12adecb,681c4d55,57eb58a6,de920fc0,c2cd92a9,994ad5,f4700561,e8b57201,96e61a5e,b4cb4a55,66959bf1,35a07f83) +,S(6751dff8,5079fa45,7f5df468,624c4a85,db970586,889cd80f,d4514bbe,8de42d60,7cc20505,deeb3f91,3d78a265,cb301c68,49cd5a53,dc029af5,c0db1876,762ba3b0) +,S(f9c63056,24d8cffd,abce64ac,65dd3a09,ebd344a5,5404d08f,b4140a4d,8489628d,49ad5449,bf1b6def,74283afd,2f315f77,3de82cda,d4c9de21,7995a2ff,c44e934e) +,S(69e8c4f7,3f757235,d0e4f39a,f2595cde,f7ff4d20,dd2d45c9,78f32d19,921b6672,8ffc35fd,8a6d541b,3f7135f5,643efb00,14f275ba,d929671,df610748,6f763f55) +,S(3d03e571,ed2aa88a,3309f014,caddfd64,26ae84a2,a526fe35,f30ceb8a,4e645e22,db95c744,6bf115d9,4af9074a,6b274725,adbcbfa6,77f9ce48,535003ad,dd37bc6a) +,S(e5b764c3,dc73619e,51a2afa,fb2292ad,db2b7b0d,e12b46b7,f14b66ce,f8aea7bc,41fbe1bf,41838b6e,9a57fcbc,b3e2e3c8,60170122,29a5ffe1,7394139f,5e8edf2c) +,S(adabcca6,b4252849,76596462,36b17b0f,9d1b4e9d,279af84a,c02f556c,e0f4c385,7d12959,9b411665,dd23b676,57229f84,ae46773a,e13284ab,1cb608d2,ccedafd5) +,S(963094f7,7ea2a7d0,3115e201,45dc6f6a,7318f8b9,a55ab015,8096db54,48e341e7,36bb26ce,3852ba30,dcb1a8ee,ec834f4d,d5342ab9,f7bbe85d,7addce07,62cb22aa) +,S(30ca6324,b4f34e1a,4c3dbe4f,d6dc6b13,a8ebcb35,2f632fc1,5725bff5,f260c508,5c04aa15,8dae7205,3bb608db,1b9245cf,fc57c10f,d015e80f,7afc7532,632eaaea) +,S(8356d1c4,55479df3,adbca347,fdb73f89,6027471b,e528da9a,d9e6a968,8dfba744,c325c86c,cd603953,8f610b03,21b6147a,371314cd,2c41df91,745e579d,8564a177) +,S(996ca7b0,4ae2dde7,b5ee87d8,c077bf97,9a63ce83,cfb84349,c7d231b3,1e15bfd7,cd1d1b48,d75f9736,68b91101,8ade913c,19a1d785,65adcf71,6c805863,fa6c1f17) +,S(8a15dbd3,5cc16f77,b22a87b4,4f93e5e5,810f0503,56e47d53,95769128,a2047738,cf96df1,9ecb6da4,3895641e,4fbd4f27,f00f58ce,cd34d38d,e258fa78,410a1f7f) +,S(23c1e11c,be9f6a93,6c5f8abb,6cc501a1,ca38b03e,f00b31a,79057156,f382ad7c,1d996782,9f709951,2c9728ac,68c16db,1889bcbb,7df432b7,f430ebe6,56b1e050) +,S(d937ad87,70737b1f,d52bfb7f,86e207f1,9e4bed5a,43b165fc,981685e6,24b8e84c,202913d6,1eb467fc,b488fffe,5914f853,73aaac20,1acde09,ef975cc8,a05fd181) +,S(6457f59b,2c744ca7,89537c59,6485abe9,7835368b,47de3667,4740ecff,72e5596d,30b6ffac,65e34e88,43681e64,f041870b,c85b3b5c,86c032b1,e290848d,ad2f7a5f) +,S(7101d56d,813abe1f,c50aa99a,bc7b2363,9532d79d,facc17c9,f2a5b4ff,50edf82e,62a0b9d2,bcab5b18,9075f6f0,e648a4f6,fa66741c,389a4196,a4c5ead7,cbef14d8) +,S(2dd4cb3e,5cb59cbe,b961af3f,d1154fbf,c21916f1,d5331ce4,c8a32ad6,8f7ad818,397dde68,7b1f6b5d,38e457ae,2f5fb332,74917949,801151e5,3d4fe19,9a34289a) +,S(509c6fcc,ae22b09d,b8f3d191,434e584c,9d17dc76,c268560f,2290d81d,53ed66dc,cbf69e20,c3f9ada3,41e32dfc,581f0ba,f015413d,735d33a6,260e0cfa,7a4e4d05) +,S(71babe5a,9458bf5e,112b23a5,3f87007b,66ddd721,32a45a34,2a9c521a,c2029aae,55ac872,a0275be6,4f569901,d84dca32,ea13e2c6,cbe608ac,de228185,34e031a3) +,S(f5f2144a,46fe975f,82b91da3,a98ebcb,6d5769a3,4e5fc50f,3ca640fa,152fa7fd,2fc05c22,2b20b895,5503f23e,627558b0,e023988d,f02993f8,f495750d,db6344fe) +,S(d6f274fa,fdfcf64,25972a56,640e53b8,15c4d213,8e4a72a0,b8ab3394,2955e416,738e267b,2fe0d9,5774afdc,7c4f559b,7bfe2824,ea6b7a49,d3220eb0,460ca733) +,S(81a12fcf,cc6acf7b,89f30fc,8f61e2cd,7882f664,55923993,2b8d3f9b,1d6e11e7,a8dbc6c1,cdca67b0,64b285c4,e2f69242,cf55f06c,5eb28868,d9bab656,eaf9116a) +,S(57019cc4,941f6f5,9ed34305,92f35a83,39a495ee,fb3e311a,fcef9001,cb8123be,a3d632f2,54083f5d,6f2857b6,9556205f,59578908,9d8d8fd2,4d10bf1a,e6d2e635) +,S(4205a71f,504362cd,576c4d84,c8b65252,3d4227fb,d6aa28a7,e7fc3d70,d1387c80,781bfe55,7fecdfff,c54d1c1f,e147792c,5ea7a1dd,7224954e,e110cc6e,18ab452b) +,S(1c42ad3d,f90472e9,e5c041da,52476ea0,896a2032,ccff22a8,fd7bbab1,4c3961f3,a5072a70,be702dae,f9f93148,4bdfaa00,1e2f2ad6,7d79f46b,5717147,17c5499c) +,S(6c9225cb,668ecf25,1f7862ad,999516c0,145faa37,b4fe92eb,561104f8,f1dc2997,8c12c1a1,e372baa1,4e9b1443,d3530548,d7d1d05b,fa354c7,f47ecab3,23993a31) +,S(72a0fd2d,eced2a05,6885dc81,fb61e881,b09104f3,8650a872,44e40471,ed189992,d9c67490,43bb493d,9aea4a1b,3a50da8a,e1c48523,9a480442,32406d2a,68487e6e) +,S(b1d531af,8faa24b5,69945ec8,1448915b,a46fd13a,f7fecb8e,16cd5d03,52c6c2ab,b3ba6cf4,bd36bee,66deba09,35bb85e0,b9ff7e62,5b5c793b,543a091b,dc83292b) +,S(da79daea,d6ea65e1,4e8747b8,b4546560,a9e5a99e,eb572f17,f2ebcf3f,9a307a86,f5b3c430,e0f2d4aa,2f278088,2d683c48,d84f926f,6feea88b,10e06930,6567a290) +,S(1fe7fb5c,99a69a75,a2276ca8,92f67da4,951bbb4f,ee4df8b4,a54c9833,d0d33869,e2b2b4c6,fe0f63f,d97fa179,331e9bb,55786006,f0425e98,71452aa8,361f177a) +,S(fcdb7de9,4eacf36a,9d662371,edd2b535,af33de37,1985ff49,6ce5293b,9d2ac00a,e332723c,7a9708e8,5172e56a,c4291760,baa17e83,72c98dbe,83a186de,77c2aa06) +,S(daeaa6cb,19bdb4b7,78077495,a9cead03,3be16d2,97e742c6,97ac18ed,e5b514c6,4545ca53,bde3c1ff,6bf32604,ef037da,93134215,7057ab10,cf6af451,e7753f4c) +,S(83e4b4c9,1a923321,196fffb9,b45d089e,7fa1f6b0,5ff45a6f,d099f7ec,fe283088,926c28cc,bf405fb1,17c5f168,20216226,4c89cda2,cf669937,2739ea05,279325d5) +,S(cd7f2b53,8363914b,2e83f1e1,c9bced9,32a682fa,cd72b46a,eda578c0,640089bc,ddf6dc27,a5281d3,b4d66af6,8fc80f5b,16cbb7b6,ebfff06c,6902d38d,4632ed2e) +,S(6f3f5a27,b19dbfc0,238bccc8,a9adcf95,adef6480,fd4ca405,454509b2,97a40928,36a56db2,abf62faa,b2255d86,d8a46aec,361fd2a8,65740c31,babb2e2,c551a85e) +,S(f7aa5c92,a523b86b,c27cf714,51f7dcec,fa18ef3a,9e839c41,a8b20c4e,30ba3b77,fa7d3ce9,8009f23d,f5eae927,acf1b28d,5ce4a2f8,8a92da7d,fcc1acb1,3c8cadc5) +,S(4adaaf95,5bfa6a94,b518f7f5,b0ebbdca,493798f6,72293e4b,36d5fdfd,5f641b89,ce675ffa,cff579c0,61e63c2f,36e77f3d,5c2571b3,aa99d3c2,74086b22,a862577c) +,S(2d737aac,3600371c,f6b638e8,8a29884c,978b783,cb843922,bd449e95,814db692,205d944f,13b21441,76d8276d,74da68e5,142aac9f,ba632568,79753c01,e54cf4f) +,S(7cb5d365,10ef241d,ac378fc,ebad8738,e8f2e6ad,6d838731,e5c82bb9,169d51d4,33b088df,5a572e8e,1010886a,d01b68f1,9f345770,81a465ba,8c5c784f,225f6510) +,S(9872a376,e530e254,8b623b6,b9dbd6d4,d123f2f7,30579f47,4d910831,7c714c0c,3de01ddb,3145d81e,6ac002ec,70086f74,6eb2bdee,6295f5fd,9d2cf8b6,1b222e58) +,S(8242fc8b,2e848618,ba0f26c2,6acac090,8eb21b4f,41a08b76,beb35f85,3b8c2f33,58b94d44,3379ea4f,829fc809,ce2632cd,78d8675e,45a29c58,e29fda43,785f2e9) +,S(88800a95,cf1682df,4e5bcde3,a96de21c,3353751c,5300dfa0,d0f802d6,7b60eeeb,2a35b86a,4e213e9e,c53dfe04,d91afb48,25bc8794,a1574ac4,53e81ff,4b6e453f) +,S(3c8e2755,9611937c,b7e2b2cf,8a87fa5a,e5c696df,fc6703b7,e1e65ac9,111ad87c,c54d129a,be0c774d,dd415707,bfabafdb,daedd1bb,2ea9cff3,bcfae0e4,55c916e) +,S(281af73e,a1f092c5,535557f9,3b5a8c94,54165f8,76650801,856bf926,19f06cb8,deaa8495,30951f12,ea157714,3caab5fd,d30f0dce,ac9b80bc,fcdb3477,dc01ea1c) +,S(6b353e5,3202f63c,69bce96,30535f11,1939fa,849dedb,92ad21c4,89f5174d,bd961eed,c16f285f,2eccfa69,d37a6d63,be5fad00,4858c80e,6fc4dfb4,2717acc4) +,S(68c184f1,a06685de,fd20f36c,82b5446,7446d5d9,8fc9c312,4852bb02,f35ed91d,486a3d16,7d94c66a,31f9e134,1652f658,76d49379,f3e3429f,e9f2da30,84f56532) +,S(5e884531,fa011576,3d36e1ad,74b22e23,f765db14,8b8e965c,80f7c9bb,7d561bf0,34c4f03,b137b627,3fbdb6e4,8ac09ef9,bc3c8ccc,e720853c,61ae58da,ee3a0cca) +,S(10c13f0f,313e5ad8,ea61ba5f,ed509aef,5ddd3016,c3339eec,ffc8f9d8,6f131118,28f6ad5b,324e44ae,64ee65c1,b86710a2,91a8e71,c33adbcf,a84f18fb,144dd67c) +,S(aa99d8b3,1031d4e9,8c078a68,7254968a,9141c710,cd8e4842,5a384bf8,414f5c5f,ee6eccfc,1dbdd5a,c9080cc1,ffedbc6e,64fcf847,ab9c0ce,fa91c4fe,d1de44bb) +,S(f087945d,a464e66c,4c73b58c,5034f057,b96ebe34,f5128397,cfadd7be,22ac6100,c5485411,d78fb395,3f229109,45aac354,1a2b2acd,1d95c38a,f51f36dc,d3cd92b2) +,S(2e4d8752,ac21c22f,e4d465e,3d2f5ad8,d9168080,b2b44930,e5de75a0,d9bf91ad,92f394c5,963c0817,500d5a98,2eccdeac,aa55043e,27a9a035,1a6ce245,a8d048bc) +,S(68b59755,44feb608,15a6ae70,9c2647b1,5c7fe073,aa6af8e6,202b9782,83daffac,b3745e92,fd86bfef,ab9d3d26,cdaf57c1,2a329889,cf646b6f,d6cf869a,f727e0c) +,S(15f5f668,e9576897,a287f131,bcbe1216,84f7a108,3c28c09a,afa77074,63dba49b,133e33fe,9bf06bb0,3b814938,7a099da4,77a3e758,82fb19a4,463ab360,bfbc368f) +,S(f2bf3cc8,ea752c11,db2ff594,d3f9b085,1dc9dff5,7999aa39,b5af2a29,30d50491,6e01a801,c5b7e4a0,a16af1ff,b011bc12,cb0483dc,6127fe52,c992b07a,9fd77635) +,S(1b04817f,46dae06c,120f8088,b3cd09e,267d4ed2,db14881b,bc32b5d6,345dc54e,31634e28,56f61b80,56a414e3,94a34ced,200bb172,e9a9aa07,6a224329,61f55ecb) +,S(693f066a,bca2046,ffb860f6,5e769ca2,3d1f46a3,6c09273d,afe5eb89,d2da45c5,719dd749,5c1b1938,a92af84d,eef309e6,ff1978b7,9adadb96,c58caf2b,625fff9) +,S(3fb25a02,bb232d18,c798f688,b16193ae,cb2eb9f5,e124c999,225f0720,63417008,90db4fbe,fdbf8a26,ff9b4afd,355e3771,c7c95891,68e2abea,264aba44,ad74707c) +,S(4c878f4e,6ebfed8e,e12a0a6d,17298b70,79d9de5c,6a7b5359,5ddefe4c,db82a79c,837592e6,927938cf,dc82252b,2cbfd9f6,cbff1950,405b4511,f2c21fdf,a3f72715) +,S(5ccaf6f4,2b75e152,49263cb9,5fdb34a8,770e8828,98a1a0cf,5407c48b,b9ad4ba0,70851419,379e5e2f,dca9613a,a9f92fd3,8ad8904e,e0ce0048,b2510943,ba8ee24) +,S(455907ae,713d1ec9,3792d488,7d9857bf,a02bc2ce,abd2c599,cf576f09,f7d09d11,1fc9ee5b,90a039f8,eb3200e2,ee58022,3f0cc699,60221d67,86f0deba,f13ca6b9) +,S(6f7acd2b,3683482f,c2c2d55b,eb62a89a,37578a34,417bcabf,ba7c56b7,bec14f0b,6049db59,b6210e55,b06401d6,17247d91,64e84e2c,b8de91a4,d4998c15,6f46d621) +,S(100f00d4,eee4ccf5,ea2558bf,92bec83b,223fa214,ad692ae3,b0a2ac93,c546d558,fe055fdc,1ae02552,1557db5b,96a62c92,556f918c,ca908708,46ffa1bc,8192b65e) +,S(8650c359,664c9f15,935dd776,bc6fbcc8,d9cb02d4,c22428e2,aee3e3cc,6e9d0c6f,89dba800,919866cc,8c16895f,785fc9cf,2661f78a,9e065472,652b71ce,d5ec8732) +,S(22b6df12,b3932756,713e2ee8,2d296c64,5d10364e,cca1ff94,9b477fa4,9a2ce5ac,ac58a22f,42769cf1,e2e23308,b3b5f139,4d329323,4bbd6053,4817ab5c,624e995b) +,S(ce87a23a,1554ae1b,9579ae96,863128cb,926a0cce,e51f17db,75155607,754b5992,4bb953b8,9d590216,e326f23e,66768c0d,17626262,6fecf80f,97435b50,d5dbd503) +,S(e3ae6365,29e3fe6b,cd1c89da,d72b17d4,8bf05c1b,c487ad41,d3b97838,a2cbc19c,4634e222,316b6ee6,c7616cfd,cddaee07,7fb2cd0d,26dd9f81,9d0ba43,313b3f4a) +,S(2825cc59,3a0678fb,e0d37d42,df72037b,6be96e98,18c52c49,fd426d75,324bd620,ea0079c9,2ef91a7c,dc587343,7b454763,f2fd4adf,561cd023,8379c8cb,1d281f6e) +,S(a6b2a170,fb23ae2f,943408ef,60fcb145,106735c,8876238,5d0fdd9b,75a2c46,1ab40091,e000012,60837529,58e3134,5f260890,d1bf6930,ddccedb1,dce20255) +,S(99a36f38,759f0a70,d719e3d5,b741a40f,daef1ad2,bcc65293,3992f134,39ff339f,a36d4b07,a7258053,61430332,6be79a,61ce8eb6,97944c6d,8bbf433b,a565bb66) +,S(e511e0a,de5a9be1,1b8513e,a5706258,6de09e2b,e2df739f,d647fd33,7890d36e,c6cc03ed,e9e50830,bd5579c5,9d6db693,dfa5c057,b1c214da,e4064804,9cd7ed70) +,S(bc9de66d,a406288c,a8a94e96,5ca16dfd,379608c2,63222a24,e3fc1116,20a82125,ac471a7e,579cfeaa,fdfdb5ff,9cccd4e,dca4202b,1b0149ab,ba9f6c09,aa219626) +,S(e98cd505,bd593bc1,496b1203,436f6038,ebe3fa4f,361ce4a6,54315402,a74c3a4c,1350c197,1c7979ca,7464c4d2,39b24a55,a1e50812,aaf92479,d566fffc,9135d977) +,S(47c0c788,2490ca53,37cc668c,5a549bde,dac661cc,f77534ed,d11f7ddc,9e0f37ac,ece10949,be122263,26819032,a2d952c3,60b27e2,7e527673,e8fcef08,a8f27685) +,S(e8224d65,35ea98a5,e3fd8833,7bd167cc,776f89ee,7d0ccfdc,46a15fed,93bee5e3,44b260e0,e0b1e1e9,383041cb,1dd985e7,22edb214,ae58f784,f174ba84,ef51c59e) +,S(c195ee35,5880dd77,67e01659,ecaf07b4,571e324b,b8a1a4fb,75265af2,3ea74709,95c39cef,f781f53f,31bde05b,d0289313,4e478b2d,1c55e741,aef8035a,2ecd4226) +,S(60d989b9,c9cccc66,139bbfed,e2902a95,fb9ca9a8,6c2e863f,21eceb4a,7d73c4bb,8295928a,a48ec1fb,775ea29d,9da1ceab,47e82f3f,1e6ef7fb,c7505e26,92bb51d8) +,S(a33b33f6,9db29609,8cfd34,caefd3e8,c3c0d863,ab695b06,b47d102e,f827fe62,669d9d96,842ee809,2cc31cfe,baab0f1f,4007c3e9,e7e41be3,7a08d221,1c6bc905) +,S(bd25afea,d9b8c833,fe332a2a,a9f3b627,d8328152,8fe1422c,5da90163,4b971584,35bb66e7,35326f67,63f4f38a,c18f8412,26da97da,c9e66902,f28904eb,b49cd78) +,S(4d7e208a,4264b565,d8563cd7,80773012,581e8688,a62921f2,d6a334c3,25625279,6729dd4f,b45ecd25,2c5cb033,dcb2f520,dc928ca5,71026fdd,b42943e8,b5da9988) +,S(5dd46f97,fc740db3,ec56348d,ed73fbbb,c440e3f3,33c64a3,a37b7a73,7f0e987d,7e2d9ee6,9e1c07a4,b764cac,aef3d780,e2d43288,2863f76e,35ff4cc6,832ede1a) +,S(4631992d,d72c02d2,2073222a,d35917f9,2770198b,ad13a847,8d3c9ca0,6ac91a3f,e28ce87b,35a69d5,c43b685a,e59d5f9d,ccf187bb,62517a92,90992b39,86d9e1eb) +,S(9153ad32,32177422,e03b6739,d5654209,7fe04d22,28b1e873,f02e990f,8936d1e3,8eb9f3c6,b54726b0,b4e867e0,5ab2fbca,e76d2e20,ce07983d,6edbd5fe,ebd0cc8d) +,S(939a7349,28fd798b,5036e2e9,60360387,b9c080a8,982d4530,78415667,848c2eff,30d2a2d9,5890d023,7d117cde,2eb3c532,e419770a,8783a7dc,dfe40674,709776f1) +,S(8e67bb29,9f11e01,b50be7fc,bee1f73a,5b335f5e,5ece8619,9a514156,dc243f3f,7fd0cb92,d6f9cd8f,bee9d337,90a4492,b8a7fa02,a0914c48,1f8becf5,d9a9d7da) +,S(a2cab3c2,537d8fec,b2f891a8,1da2f523,de4f869d,3c812806,855013c,73485ab2,765d058,c681af53,36ccbc8e,88d2391,b4894b18,15441342,4c4e73ac,1a8e0d71) +,S(9b39be40,976c13c2,faad320b,9338f985,b0718123,d2fb543,b65473a5,3bc2fce0,10f8234d,455fa7df,d09d76ee,41035515,9b560db,7b92988e,a42f9e9c,f7baabeb) +,S(35011530,6f2975be,73e7685,6456c94d,700e9b1c,4685639e,4f60efd6,9e513692,5992efac,9dcc0a58,ac6e00e3,54e44582,7e2d66c7,248e4b86,f8c216fe,a9e44270) +,S(df5a5b75,d96ddb93,9a341f58,7e1f997,3cb9e799,b04ccdfb,9907b57a,7b005d1f,3fd070b9,8d759043,8a53c302,b7ac0dbf,594094ad,7101d500,1cd5d687,e80066f0) +,S(91f14eda,a0db8441,10fa531e,eac54762,d52ca420,bb872327,6b383587,d40fa761,86cbd213,358d1f70,c3f6ac7e,913daf0a,47a80f8c,bd72445d,fcbef37,d0d71e69) +,S(53ddba06,46853311,9fe95719,15a9efe0,bc7fcf80,59d638e0,be6c1aa4,c5f21ffb,e59de2f6,5e583ab,5ac86c77,fc298301,70a18b68,a1979074,c21c0d8e,4a562567) +,S(56599462,4ad07c16,607afcd,76e86218,b15b50b6,9df84695,e60a15f0,3d7bcc49,c6d36636,ef58556f,9b688db0,eecb6bd4,5a7b30e,a9748732,68be57d8,542c966a) +,S(76fd5413,fdee9cb9,7f92fefa,5efa27e9,9aab744,e1e15029,241e35bc,743307a3,bb23f425,9aeb64e3,8ae82c3,b4691bf9,3b4a719e,a8ce076b,d0345a2f,d02a6d05) +,S(511ff159,2127502d,7499b988,7a3b3bd6,1242518,58bb62e3,dc1638be,89204a0e,21da5ba4,34b7819e,53b51e46,29f5fb77,e739ae5,97af55fa,aa09500a,dbd502f6) +,S(8e948cec,51635ab9,5a057404,39ff17c5,ae2e05e4,523bf2a2,3df28fd9,86de6b15,e16aa2ac,6c3d34b,9535b795,29a82b67,34bfa260,4a74ebe8,86110d73,ba564375) +,S(ebda8670,9277fecf,9b8507d9,40da6c74,210c8c7e,ddcff0d6,e3b52ded,3bf57095,3ca95e8e,112c8137,fe8c5088,bf041674,fb657260,70625890,1fdc5626,7655d654) +,S(eb5ffc4f,559f7ad,2469f48,1c730925,1ebf3863,357dbe72,41a29205,5b667682,b1f72d74,a5a16ef1,d55804ce,76974f46,61a49210,8a1a36f8,a59484da,a9bcbb96) +,S(2a93ae8a,d15c82ed,19fd2161,4a7a65a4,cf562432,623bf7f8,6c765548,b02fb57,5a949ca6,60a1430,9d4baa6,9be69b34,848e9874,62471d74,54c4817b,336584e0) +,S(9ac4a3e9,f1c8d115,138bd299,b6fb9132,c5d64a92,1fd94adc,82eb4ae,fa64704e,47f0eecf,a9eea827,ff339f3,48e67e8f,da9f00e1,a6b9086b,6f5441c3,7ae1d335) +,S(add254af,39d99d6d,355510d7,4f8985ad,3d8ec1e0,1e8d0210,27e80049,f555d65f,5b147a1,fc4bdeae,6c2f1224,b35e9e61,ad0799db,53597ef2,a23a8f3a,344dc526) +,S(d374d326,52cd006e,3b27b8d0,3ab47d44,bfb1c5d4,48adc992,5f63235b,c34aa128,3cc6ee09,c04d4cb0,aae8b1e6,6018640e,d0964fb7,148181ab,e9fd0374,642ad9a3) +,S(fa7632b4,78e5389d,cbf380d,8efbf6b1,d4bef9a1,70aa3517,e4c2005a,71a283f,ef2bcbb0,4b20be5,d4bda0f4,26dd0baa,31037d2b,7b530e2c,24105c3d,c817ce89) +,S(68ea197e,76af6950,1633ff9e,c825a817,80c7405d,ba513f96,6106632f,ea73ede5,633a5f90,587d4ea1,72129820,2ccefb30,c14a052a,6c0ca723,65e2f91d,53b3ff4) +,S(8874397e,1813f0c7,6946a84f,b05a0f44,224bb110,8aee722e,736e807b,b045b73a,ced2e2ec,85ae00e0,2952f55d,3626b613,641d2a8e,84b4c9ae,36177bb6,9ef80d9e) +,S(2ffe42bd,89256069,2e460701,b94208d4,85915043,8a85f71f,32246b8,5dea7594,6e7e4050,a35f1570,f8cc40c0,862e9cb5,59e744bd,8788646e,b0dad904,8b2777d8) +,S(c6d3a6f8,c997cfe,779a9a30,79de4bae,c19c226a,21f166d2,71ab4da2,cbc6defe,a8f8a618,3f6c8b2b,1486e60c,337725c9,9a9adc07,7dbb6581,e5b0119e,ca10f418) +,S(9b51cd75,442203ca,c4b8aba6,e9829b73,abe29f96,92b8dee8,500e1a90,9ea9767f,ed0ee32d,6042b6dc,dc818dbb,8cb00619,6bfeb2d7,88f35626,789cabb6,5d159c51) +,S(952c518f,775c8bc4,dbd7629c,8dcf8807,1b208033,8aee2ffa,eabad5d0,be6eaa1d,8a3b10a3,d9343d39,e7bef8c1,193f5cbd,717efa3b,cd2491f0,2dc1aa17,2e5b629b) +,S(49a18372,63eb11af,77a2e33d,2743393a,7eb269aa,f64589fc,8f81507e,55e8ee4d,7feb4a59,64b781b9,640d60f9,4e7eb291,6025d190,95945aab,7ac7771b,6f96cff8) +,S(cf974d8f,46aceb5e,a8c04e55,703b5a43,ac577e84,cb174abd,88198e1c,12708c9d,c50cf6d2,afd79d3,ce275e91,26bdaf0c,f46c1eb,536d0753,9dcf6c2d,d79afc35) +,S(461a831e,8beb6da0,df92dcdf,2697d551,cbf8f903,138d13f2,ec9b7fa,4a7d4763,e5fd85fa,c251705c,27d4e870,64af33b2,ff99b19,14496d96,6fa18916,faf40e01) +,S(eef4eb8a,9eba3f2e,b27e3aca,6cce7335,49f2656a,c26f1921,60c05bb8,fc3f1165,58f74526,a812ddc3,713217f6,fa4be02b,7062d042,2dbf5625,abd1f422,58b54c36) +,S(d674ace8,a7e8ae,d4bd4b7f,235b9f4c,41ef4355,4d9e6e44,3b6a26a2,d16f798f,8a25a7f7,896c0dd9,b1639f99,5c4b3df1,a3536104,b7d59348,c2c56c0b,bb21c609) +,S(a8eb465a,8a2869cd,6419af81,b3ad1355,1508727c,2b2494a4,93b5ffe6,2c1375,f1a27219,f59f29c,bb93bdc0,6157618a,454075ab,b95184e6,a4601ef4,eb2c8a1f) +,S(ccbd9d,6253fae3,f7d2527b,17854e21,58581e95,11a1f11b,55e3e04e,7326e6db,51ddefc2,5d9083ce,e9999e91,cde32f70,344ec937,d6aa5272,3dd62496,c4b0485b) +,S(524bc1e1,5c75e8f0,6718d2c6,da0f6599,c8b5d83,7cb9b48d,615e8e46,49dc6659,f6c91d14,72a50c31,1bb202b2,3d76f224,b55af957,c7bf3c19,69d175a1,d36ed19) +,S(520e667b,a0604a23,dde663ea,1a29971e,7e753301,9b2217af,296b02f9,de1df35d,9c2a2c52,290b6927,ac566ea8,4caa31ef,cb19b65f,29b4833f,5f4eae8c,f12b38bc) +,S(156282cc,65317dc1,3323aae2,d5d83e8,b7113d59,a50e54d8,dc54c1a1,ffc85d23,840cca23,67da3c5a,15b6427,72f0cd7e,675bb8b7,fb5dd58e,8cda9fcf,cb21606c) +,S(15afddb0,5adcc8d8,f1322a7d,f451fee9,873d4b8b,78b0c1e8,1d99f002,84aca6a,15465563,a129272c,b5e25bc3,ac76c52e,b4e115b7,b216a40c,145c4699,175cec9b) +,S(9eec4fea,e9508445,4bd275e3,f8d0d6d2,9040ae95,c8268f55,918d5f3f,2f75865,b7a873a7,5fb4ef70,3d62a723,81df2ded,102726ac,81685725,424a7733,8307ed7d) +,S(3aa7be96,660652c4,de1c82f5,cce1a864,c37725ba,848180bd,52e4dead,1a33f60c,f323d266,3e5d14dd,18fbab76,271f6c8f,32d7de0a,42724fde,f6ed3582,c886c402) +,S(bae9e070,a8e5a976,8347368,c32b4287,c7a6a20c,b491bebe,fc6acc71,aeeecea7,b5791703,f98ae848,1a9c66ab,878f7c27,d37a3e0,133b4e36,82ccb2af,b518e8ef) +,S(7b12ed88,be061d1f,7dab874b,17602bb0,ef5ccefa,54f9ff40,e753312c,335f5f86,70930f8,c465292b,b02ded5,59a235e6,c4c83480,9eb94442,8440846c,377498d6) +,S(9eb22b3c,8faad620,ba002990,4a5d8d1e,8cb4a054,179e3310,73f4ae8c,def4e1f7,6d58b972,ee88dfd9,4e429a2,4f6961a7,d085f00e,8d6f8d14,ff2066e7,df68bc34) +,S(bb2aa6cc,d8402cb8,e7a9a6f,a755c66,366c659e,bd2e5c85,7fa486e8,aa86b857,443e7128,674c040c,b0316d9b,3908bcd3,298e727c,c805bc8e,ca58894a,d51f4130) +,S(c58704a9,fc3bb18b,c460c4e1,f17a880e,c0dce45b,e2caf759,72f55061,d59d30d9,75216472,aee1c9c,280aef07,7208fe42,136b495c,f80d8a79,e8309272,c6c4d6a7) +,S(b7d7c721,70af0b6a,489c41a6,e817da2b,ce59f30c,88a82b11,83a6af8b,174c70eb,59481a78,52f3726,3a02ef48,dfb366ce,7bf170b0,af3c2000,2c1053e6,5dae1ef8) +,S(b1386833,25f5450b,f4f68dc9,93d72fa1,1e636a3e,8b881ac2,f237cc44,42f3461,64d18f1b,87f9463,10627931,cb003c09,981c4a94,969a0df1,7f717830,4daa6cd6) +,S(7e27af99,500cb8d4,d812a82d,29ca369,5e543231,8432c9f5,96f5b76d,c6d1bd8c,25a477c5,a275daad,10973822,40961da7,5385a367,6dff887c,42bd904d,8e885997) +,S(62e04f6f,d953c744,aeca984c,bad13c91,f4e09c1a,d5441603,2bfbc277,5ebbfdc1,4f1f609,db0befd5,fe781afa,d21efe44,846f9f78,9ed9f99d,f3291eec,3cf3fc89) +,S(b08a1f84,a3cbc3fa,f952247e,6d8d8d9b,1ba3ab01,ba03ef8e,836b94ec,dfe2e2c4,5027889d,e524fd0b,e6ada02f,4f33d1a3,4d0c3822,f0ca6651,ecebaa37,3c54692b) +,S(d417933b,c7a8f68a,9e023d64,498b5117,850f8885,b6254256,f9a12a47,538d5bd6,7ad14679,21349d14,10e35750,167282ee,9a6f6044,b6c9d71a,633f4475,5b432ed7) +,S(575909cb,46a36dc1,c270267a,10a62f31,941fb7bf,3699aa43,1a3bc770,fa37d5de,c12ef954,c937d6a7,bda47e2e,67d9ebb4,9434cda,e1571ec9,f604c41e,b49d6189) +,S(5298ad25,cc5a6bf4,d88b693a,d32a61fd,efd763f0,e4008ca0,eee17730,4365de57,75f821d1,66b60185,41cf7653,9a0cc41,597b8b78,10fd1fed,f0da4542,3a26d5f1) +,S(5aab0fa4,b0beb77,d5d2a8fc,c95d516f,1dfdc402,3e3d36b1,4ecb206e,ee8c5ff,7a4659c7,7c062356,c51ee28d,fd0cea92,a1f36d5a,b78a3ae,8b48ac9c,7fc63fca) +,S(482fc791,7c739041,41b69e59,62b0b815,8a9bfa00,f203afa6,46973980,9b250a23,89b117bd,485ac6ef,4de8eae0,a9e96edd,a3615285,e33282b7,bf0b6a6d,e11a9c8c) +,S(a576ceef,40728a7b,b63756f7,f3095c75,ff2ef84,c7933d02,b9dd8a0b,a6046653,b4c707dd,9d880fd6,d7a1ea13,87dcb6a8,e2433e21,8ef3a7f5,e348d2b3,f9a9796a) +,S(3c9d7c33,f8c62b35,fe977359,f290dbd,c2b46fb0,a2fe126c,d06e0422,54d1527f,cf92e34,3ce9f624,84c04c9f,d97569d6,67065598,9418d858,aa7368d5,bd6a2df1) +,S(56bdd1e7,363c52b8,2198cbe8,62ed6d7c,7b96d184,7da44036,2401368e,b2c83b89,505d385b,747c9545,6669809a,a9da035c,364e7971,7cd89417,3d1d5d58,298a1869) +,S(99e0696d,ed30d242,bff69e9f,ff4ec88d,eaa3de35,34dc7f35,c2bb7df5,9f8b440e,2cd1fc77,3bd071b4,c9695f25,458be688,f662f7ee,ae8f313d,9c373172,6185acc) +,S(7d5cb46c,81f4a4ec,f1e5d913,1772277e,d17de7ca,7a4b277a,d6b135e4,dbe61916,cc854503,d73e8034,7a6ad7e7,f5bab321,b130d7d,3d938423,9e0656d9,74971849) +,S(45cb6ec8,9dda9aed,5242347c,a20377bf,c93ebbd,50e48ea8,159530f4,4f4a250a,411a2ade,aaaf43e7,240bb0f7,cde77d8f,846bc700,4721f6c7,4d313fbe,70ae38c2) +,S(a7e23331,bf08ecce,2dda8c2e,a6c3c4ce,9bbbe3a4,4d40068c,e39e94fc,edea42e1,d1f12d24,144bb258,dcda7060,5348c1d,85faf076,fdd3611b,ecf6c34e,843788e6) +,S(d81aa0fc,b0a8fafe,d4c67dcd,6fddd414,80cd5548,cbd6aa58,35e5896b,18797f12,92af7ad3,89320814,bbe53ab,4cb5bd26,3df11ad1,8d2ef235,ae9ba163,74495d8a) +,S(8d379fd1,fc0acf5b,c96d03e,b73b340,5a7326ec,82882235,918a380b,c3e2669,f8c6063a,eefc0e2c,ef94d8d,ac4e5b5,ccccdf25,663d993f,7f9a0172,6756564e) +,S(5e20f600,6f533af1,8f3b6e65,17aaa2a1,2876b79,c99ca059,c2791a1f,1e466e8d,b23fb129,57640a9d,d38bf206,7649216f,50b913b8,69d241c2,baedd5e9,dafac9d3) +,S(1a0a4f54,80d37257,c62d1b0c,18dda7ce,f2b64754,be9a3d77,b3d80ca9,215026df,2f76696f,f4001927,9ceb5652,44d4a60a,9e353266,42bc2138,1191a51d,7661ca1) +,S(be868184,dc2e91fa,b11833b6,f78577f7,8c190220,a2b46551,53cc8ea0,73a217e7,6ffa3f78,1c64c118,68abc331,beb8c284,2919d593,12bad699,53edd222,2b98a31e) +,S(a4650db1,917b10d9,1fffa809,d9f9cdaf,f07faeb3,8f0ecda6,9c80e0e0,fd27592a,d5a6fdf5,647e26c4,1d7b9c78,7880c76a,b0cbc23f,d4c1840b,78717b34,2ade1422) +,S(944b1701,4a7c7eaa,754c9e03,d56516d9,e21e254e,9a871683,7a14f19a,9ebaa517,ee198337,3822c796,3ae7df88,24687dda,eea01e83,c82e66fd,baa746ac,485a6dae) +,S(f9e76020,cb9087d3,a60ba7ef,7ed5e552,3e5a3645,f61f9ee7,27d630b7,98d37ede,28371db3,433bcf49,f6d77711,d7ed9101,f5e478de,49c58103,b021457b,7a0b526f) +,S(7ac0c7bc,e17509a3,e4dc004b,d18c322e,600aeb83,8fe2045f,6da348ec,6f178b41,8b5cbafc,33469334,4886f60d,ee7626e5,36e9a977,60c0dd18,7bab7e45,6b264956) +,S(1d7ef98c,c8520f5,2310ad12,107351f1,966b651b,4b2a39a1,7a47f658,857e3bde,2b78bf4b,7be6f1ec,61cb235,a26e252c,71d91f58,69752719,8125712,55d47664) +,S(fc57f5ea,b40add8,f00c2da6,c7d24540,1b24b6b1,f102836b,4041009e,2fc6d5f0,11d3e017,bbc33913,b7861dff,bc11bca5,5aea26dd,f956d21d,2f333755,ef823af1) +,S(340c47cd,3b473c01,80526815,64e77f7,6ec29eb4,b6603985,d6ef7b64,29e2f289,994d98c9,c1de0dad,d27f3386,eeb7da40,6144e060,ef4db403,ee8a76cb,8e21bf89) +,S(81b13929,f08e9a23,69127ba,3e6e839b,8e9cd05,b19a9bf5,2292148a,26bc47f9,b6c33861,ae8fe20c,7a6c7830,4dd03fc1,a281ea57,59661e74,7f9e904,e4261226) +,S(6f325fba,15a463ba,4a61e2e6,82655af2,72603643,8a48075,f76c9882,4d7e252a,1f205971,70f9f48d,5421b73e,97bb6260,cd2235e4,6f611e9e,99b7f8ae,cf435d45) +,S(4b388e91,fadb26f9,b23b015b,398c8666,91521b8b,484d4510,b3c162d5,834bc109,ade8365,9d59c363,3191c3b,20e395cd,13ddabe7,1933045b,cfd8e941,f2096d25) +,S(2d1c0ab2,83c80dfb,ead3e083,76024910,c1d97acd,6c8be069,252bfd94,ac1a0db6,c4856c74,e5ef2e6a,17ebc35e,3b310f6f,8e7b043b,abfff733,aa3ed9f8,5a391c98) +,S(4c77a1b5,b88ffcce,1f98fd89,251c0085,9d4197f7,d45bee5d,edfded14,a97e5b87,48b8135c,b067c292,6c316424,2392fb06,f698b6d6,e98b2ffb,bcdb028f,4d85e5bb) +,S(d39cd5fb,11cabce0,e31f6fac,10cce3c1,c0bdbcc7,294119e0,2b433b0c,20e3a4ee,487695cc,8a8ec5fa,aafdfe25,3aa7d635,8d44e82f,77328e8e,4541f7bd,f629bb5d) +,S(238a05a5,519ff4e6,29b0f86f,9d259eee,4e620685,a2f0509a,cc9fb1eb,4e89f5f,6772f6b7,816018af,ec95717d,a6be2d05,3d740ec1,80241798,117ed39f,91f3beb1) +,S(c146bf13,72816407,b5f8532d,91210d59,a8a6db2e,54fcfd3b,fe910365,99f7ed14,e952ca9a,f88779c7,eea67194,3df6fad9,72b717a2,19d1eca6,33106f97,2dfdf0b3) +,S(4cd9154,861edfa7,c29378aa,1a7d6d0,83b134a7,572383ef,3010f34e,19d40bea,9ad99f1c,b5841c57,5f7db959,362542fc,40b0cbec,58d16ce1,54c5944b,6ff2aabb) +,S(d35f2995,2478be06,e86b342b,fd2d2cc5,ede30ee8,509da11,504bbffd,5884765d,a0f66db4,a21462ee,e51e226e,2d20d896,2c4edb1c,babc45b2,645968a9,c7810fb4) +,S(caf9c953,ef1f57e6,905bfec0,2fd64fca,92ded9a1,9435ad1c,a672cb7b,117c6fa,23b01776,7662984f,9c2f9e43,756ed3a1,3a574960,558db4ec,8670122f,472d0ccd) +,S(4bd40ba0,21d2beec,ec7317ac,df3b719c,179ec012,1274a198,d0ebd9d5,165bbfaf,9a5751dc,d7885a78,20d8ccfd,1db3e3d,aaa2bd65,b7b6fb2a,2d7b2902,c629d81f) +,S(560928ae,7b15a63,62eb4444,d4c0e069,1ae43323,77a2de40,83f056b2,70259814,ae97006e,fa5986b6,5da4ddbc,2bcea172,f12945d9,b6f5184,4027085d,bf644794) +,S(7870209,38e53dac,8e250835,9e41e313,25b09faf,95b03a8d,c25e83ae,f8255301,49fd164a,915e0af1,a66af8ff,d215d1d3,92e4996e,5ef68f8f,51a4b895,145bbd90) +,S(7aa3742a,6c82c90a,7e6c1b04,a41e4643,47925d,66f4e7c9,ab2aff17,e64932fb,7317dd5c,f2cb9b3d,5cc0fd6a,c433d1be,d1dc8345,b26e10b9,a2b8cbff,ce2db0c6) +,S(7a400535,be3b134d,4572e0bf,75c13098,dccc0f04,1c10068d,31e2b0b9,149c2e08,c00fd102,309626e5,a2f97ef4,e0374a3e,de0a7ed2,e45aede1,40521086,5d10466e) +,S(f4d71adb,438460c7,9003e150,c4143557,ffe30efa,eed122f,dd97c572,e1dbbbb7,e73588e0,fbae054c,140c0474,348b7ce2,92a1976f,e8c940e3,62c29ea4,31bb719a) +,S(34b68d32,810bd1ae,51d0c82e,ef99752e,8206aa04,8c5c30,7c3e9a25,b2d68b94,4d044a,6781875,6aeb8982,61bff840,a3ab951f,bf60cd03,e8befb25,97203c7e) +,S(f83b78af,f18f22b1,f2081707,3dbb9c79,4f180b0d,8871a1af,94d16d29,5c71f1c2,93ea5b8,c7847ea0,2cd5b783,5021d37c,dbbd395e,fe6eff8d,866e333e,9d6083e) +,S(a4a0d5aa,f521e1bc,2e818063,f4575f1c,99bd2447,80eaf848,2737b297,b2deaffb,3906373f,2111a47b,102b0294,f9fe1a4a,7ea9a9e9,aa2d9595,68ff8419,9f1abd97) +,S(cc211da7,28671182,1f0bca25,b9703fdd,ac9d0277,7e1829b4,4d9921d7,998011ff,c0cc46fd,5519211f,3a4cfa43,d84e5b3,bfb316de,39a5f4,9a50b1b1,8dcef321) +,S(8a07ed5b,e0397b5a,8c33ef,108df270,4b385c45,c8296593,1ed3e391,17b2f531,432023e3,8fc1a637,fb5a92f5,9911932d,f5cd23f7,eb16ef68,c8c573fc,86e8c1a9) +,S(8add7841,86b68399,b08a0bf2,a92a3987,36fca803,3807b564,f97af438,ac70d49b,758cdffc,ef477c3a,fb3028a3,2866d860,c65aa2ef,7b3d6261,9664ace3,658add34) +,S(ec6b9f2a,a1cdedaf,306b8a5a,b021e430,e9931126,a1c505d4,a10e71ec,3cc60453,8139b262,40e2c1ca,8ec89808,2a37d7a9,b78a7e5f,6330ed32,f9786cb3,c4ddb722) +,S(22ce2541,dd8a47ae,227dfec0,95ac361b,88ae2cd2,c9547344,f551f6bb,cada196a,68ce4f4,a677a0f9,60aaf4a4,f8e83a24,ebfbf46c,6ce2a470,255d2ede,c4431581) +,S(ee7dd0d0,3e5b6d8c,ae78caaf,27b902fe,4136201c,12a49551,bf208c0b,f88bd33b,aff0eef0,609bbf68,7ce2aef,9f48f87e,67aedd82,e5342159,3809cf5c,da4ac004) +,S(f7f9a352,ca18b2f4,3aa18c00,9ae0eb31,17679db8,d9fd7e5a,41b77e85,b54140cd,afd30383,ccd2a6f7,ae76b953,5bc80330,4419d38e,73e12d1e,dc407ef2,f3b50326) +,S(7793ef5f,8e57e872,ea9fbb18,bd710ab9,6ea4f646,134d3308,930cbf62,e73f0e1c,8d5b3b79,3573090f,a4a7e7e5,c38fd987,e889bc3e,720e05b2,43e856f6,32ae7cc5) +,S(db743211,ba814bf,e6371ddf,d03ba554,b558548a,a90e81b8,e1421321,656065a8,8236f24d,965a9003,84b382e8,d772d7e9,2dee2ce6,c3cb3388,3ea627d5,4a5170c4) +,S(48c22865,6e51199f,6306a6f1,7dac1e6a,13f82d42,61de0f0a,9158ba98,715d3cf9,19a2a4dc,35d2bd03,5bc5daa2,5526598a,8eac11c3,52e5fe70,be726531,747035ef) +,S(70a28bf4,ce75b491,582b48d5,9a5069b,9dcc1e49,c41702d,ee5d688e,6e643a59,7183750e,2995f655,1b58d5e7,21a5f33b,69045934,27f27f34,f8ebf62e,74e49de2) +,S(a90d8505,596b3d01,a5e8dad0,fe652cb2,4a008a7a,61ba3cc6,8401a7a5,5c2e3132,f98af047,6e925c87,e13bb7db,f992b81b,1be564b6,8589cf2d,b79e4800,3ff7b0d9) +,S(88647576,8e960c09,6aec9832,448decac,6574491c,df737dca,dcc42b84,d7e775bb,ad94bcbb,7309f483,19077724,2582f5cf,a39ead6,a4050afd,89a49ecd,7a9090bd) +,S(c505d2cc,ef72aef5,8130f472,2ab3b2c2,3a6864ab,bcfffd5a,725a6df3,fae02112,dcb82329,cc51dc7a,54e7104,462997c,3d135d6d,5c82463f,45e875f5,8738652c) +,S(24a1d4be,c709cf8c,8b8927a8,8bcfb11,43b0d579,10e0900d,68fbb682,d4e14df9,9ccab057,8440f6a2,edaa4f41,28f427de,adce5584,692b79d,624e8724,572a043f) +,S(48c44581,51df1654,fa78370a,6975e59e,576eeb40,e94f636e,72aeb37e,8fbdc4bb,f48e8dfa,bb085834,43a7b495,ced76171,348e92b0,41b9620d,3cd5a84a,d9ee4eb4) +,S(42a7838,d33d0b15,b4409534,18024a33,e93ccad,946b50cc,a543ea1f,1bb457da,dc2f0e6,4f30e973,cdf6289d,d8f6455d,51c2da02,bc4e1d13,6668250c,e4dd791f) +,S(80988f4f,c2dfcb86,f1f65196,d93a6cfd,5c664e1b,5f8875d2,61e7c4f7,b2ea31e4,1e695c33,b526d582,6210e694,49c4673a,8697e1d4,a197c9bc,a3ecafda,2a7d5b93) +,S(a0ae003c,65d7f1c7,b65cf828,124701b3,876d0be,587c2589,9a618c4e,7b79d480,d7f4ec52,bccd57a,9515e80f,2c79be42,a6b53ca6,253ee13d,ca33c917,ff2ddf02) +,S(392f57a0,ebe08b06,cb4946ff,3c1df6c7,c5cdd97,b9cb2190,dbd4678,cdbab3bb,1be9f9db,dfca7981,b3dbbb1f,daf50e6b,c5662fa8,1b8a58f9,9953eebc,d1d0be1c) +,S(cd904f6a,3d8c4ebf,6ebc4e5a,e536c544,4a04e278,389d771f,d5e7566a,fc592d3d,e3e10f61,a15399c5,f3f29626,af323cd4,3d6572fa,bad4f02d,cf76c0f4,9785919f) +,S(27a4480c,df5782bf,52ddb140,ea5a908b,38dc1ec6,a570580d,2b72b922,e7eb05d9,bd96ddd8,1a6aca1f,88847632,5a6d48c8,4d61e76e,b4d0d957,15d39f80,faa42f3f) +,S(6673ae66,3511292f,fa4dd8cd,bc0f7b36,613c56d2,775602ff,a8cf9302,4329f5a5,d8b4ffd8,8ca2530b,18d85762,529d056,e8048cdc,51730082,2d24cf42,e4053141) +,S(3dbae13,5c395043,d5b88161,4dde355d,5a669076,98c36b23,ac4c24bf,80e34f2a,b7d46059,3154fad7,eaa37c3a,291c6c67,16df2944,4274b044,a9f12ac0,a34139db) +,S(f2db4c09,1c3c606c,9784f6af,7dbfb26c,2b18bae3,b22f13bf,4188d761,6cbc1371,8c84e295,f57a9722,260d5816,c5d57719,c6fe2a12,3ba20a48,189bee04,ac252f32) +,S(918e415d,92e768e9,f5a875a8,aafa7dd6,66109cd5,8fb6044d,d2c8640b,f6b966a7,b53400ce,9ee9f6c6,9cc35b5a,3e04eec3,dc89c931,e545068e,ed4a818e,42073e71) +,S(5eda3e22,bbb8c368,82d46c19,2068b3e9,a65624ae,31feba8b,df725d5e,47bc3437,1cc2c541,ce3ad8fb,ac3cfabd,a492c03,87099e1,659cbf88,bc8f27aa,f9a2fe26) +,S(7df83e06,9cf09a92,5405e0d4,3cf0c7bf,52a8e603,d286e26f,f273e218,b455e61c,9eba2975,7f61b054,29c9e915,a092a591,ac1d6044,8a63a8f1,313f4018,1650f4bd) +,S(b778c25,d78b0bc4,68dcdc80,5de93809,1c3c36c5,b5f9569,a9394b5d,c7afb162,901a4ecf,b4821145,c7d9e56b,75e43ab9,cb7ef8fb,1d384a4e,27033e9f,90b80fc) +,S(dd4965e,f6fb759,104f7877,307e2a6a,f837ab6,8c19aa40,6fbea75e,e8a7adc3,45e92312,b5c77585,3c4b95ca,6b4c1740,a70b57c9,97124883,2c53d291,4b0fd4d8) +,S(ac971379,7dffd8d8,2e33f927,48ca063f,f1c8ccf2,5b88fb6,bf80946f,1dc9dede,6ce10e3b,ee4db87d,40e8de66,fb5263db,2a578d6d,be100fef,d6e28bd6,7377bc26) +,S(6046fab5,37fb413b,29797312,5a6049b5,5c085194,4b058264,c39926ed,fe85c6,dcdf9ed1,cbe469ca,2976333,5a159e42,af6f0d32,664ffb5e,173986d3,a277180d) +,S(a0d94b05,8e3b4d30,7f3b3f09,ba5ba28,d0285a3a,22cd577a,1d949b8,bd23f1ae,37fcdfb2,e3027e07,ea77f28,447ea13,93971c67,974304b5,dbb7621,2ad2db10) +,S(da15b971,1b974ef9,14433ca5,71175233,693cab3a,dfd5f6e8,cf034254,6f73dcd,e08c7f62,90f87fc5,4e2f4ec5,a5a93d19,f4484868,3b5ae9d3,810b0615,c7e79402) +,S(b26ba5d2,72a744f5,562cd745,a3f3f143,32980458,60be4e97,d737fbb9,b3b0d544,3d308307,9830f281,14de6c5a,f3876446,507558e2,95353dcb,738deabd,80c0ff20) +,S(fa26c55b,bac04fff,ccee0610,ba9b60a2,4042aa08,7a564ffa,b891e087,7a2185f5,5b5a62eb,1ff579b9,ee4c5d6e,ceeb57ec,e9881b47,dbfc24f4,3b9a18d1,4addf4ab) +,S(5ada4a59,4802163d,4da685d9,b7479f,4b70b489,5ddac7a3,b06a1c4e,a5f46dbe,2ec25e70,871b4958,81f6b0e5,cf821b91,febe83db,a52fe2f8,1a2e4e82,165c7e3f) +,S(a57751d8,895282ac,bef2384b,db4817a3,539899b1,e7fe7a62,2596ad18,5dcf878f,651eee9c,12ecaf92,9eccf109,635680a,a7499537,f2054e2f,69b0f062,c820784) +,S(3f17f0f2,6a540098,d18f8d88,ad323e9e,e300b029,b7b8101f,6aac6ece,8d375f3c,9c0713,79e35319,7f1e76d,55616e5f,8e573a54,b6bfa56e,5dacd2aa,e2e0deeb) +,S(eabdf476,d2e9d76d,775388c,da759930,4e1ebd59,b3a7e491,e3c9c62a,4d0968ba,f4bfd5b5,e0e8ab41,a04c4cd7,763b243f,b82f56ae,9f08a6ef,bc365f3d,fa227c4a) +,S(c5b76ae8,dabb664d,fc1fd499,36399e3f,c2b7366e,a21cba10,dc7eec7c,5c93e0d3,ef30249,19bc03a,c24c8544,9467728a,c160edc5,7c901e64,b947f298,9bb1242) +,S(7161dbf8,6b1080bd,bd6aa47e,dcdf8a77,17b7e281,c692e9d8,739caf9a,f3f23d6,3c30b786,b095288a,4522749a,3d32a35,5a8bc694,cc9cf7ea,989675e9,a1688e8c) +,S(ed6a7b49,9b74e62e,53183b15,6867d41,3ce902a8,4b71fdc4,fa414f8f,249c2ce,793d0356,1bca65c6,be127ce5,a1034b9,86285fe1,f52075e8,1a9b5bcf,87348c4f) +,S(fe6e1abc,3ee3be4e,22456f4c,bf93810f,282f0fec,96ab5cc8,2b35b08,54492bad,96c76282,3adc2cea,1563c02b,fdb25b55,eb15e769,90a7ed7a,3fb8aabe,47bb077c) +,S(979e7ab1,96e66818,b67bf79,31232826,713648bb,ad956add,ed594cdf,8aec2937,696a9505,e3c473a7,2df68f96,13c2e494,406782a4,f92a8fd6,5017a83e,d7912491) +,S(9f947cb3,f859f2af,11a63400,800c18de,b8813c1a,b396ebd6,a1d5bf4a,9689160a,8efeced6,7f1e6fdc,191ac965,5002a02c,386a20b3,eb2aa1be,7fc12008,b8bead1) +,S(71790030,58caecb5,dcd2e281,b42eb59e,57de1e6e,b77f6bad,7d2d1897,6a512eb4,abff54d0,e20347bb,c10a79c4,127f5f7d,868176a7,4e34077a,8ede1d54,7e339483) +,S(d786ec15,c140af46,841b7eb7,de5fc9a3,c0636885,3950bab9,ffdbad01,d836b8b0,fc90191b,63616a44,72efb2ac,a7d84da3,4892af1e,25bca0e2,d41268c8,d381d062) +,S(2d553f03,31eb83ca,edf2508e,67054734,d929367b,ffdd5b7c,dd78dc6a,2e724534,9abcef4e,ee588e28,fa1dee0a,b8c426c1,67d37cde,f8aae9e4,248c036b,baa1af70) +,S(326b36b,eab4d932,c40182f0,fde043ff,d6b84b16,72fe1dc7,3bc7e518,6ef68062,9d86868e,2e871ce5,c3488624,bec901d1,47b91bf9,a3154cab,6445870e,d51e8f1d) +,S(f7a6a26f,4e3583bb,9552556a,5d248735,7ea4af7d,ad1f7a92,717d19ab,34dfa11,7ace27e1,dab2dea9,704c01ce,50ea3de,529d864d,9a5fc11f,fbc0e8c7,81778b2b) +,S(8ca708ea,c072334,42eae4e9,eb0c7b45,83e153ba,84ed7a0d,3ece41f9,4df6cd15,33f41d25,e446c47b,68ce1bc7,d1dd1740,fc701538,3ac90e05,1dc89a9f,dc97592b) +,S(4fca2ed9,e1948697,208a87f9,a890cc96,4aa9e5e5,7c7274b1,deea92bb,586875da,98a9303,4df7185a,df9f557b,b7def9a6,41e7ad5,a3f24051,435673ff,12f0580) +,S(466da0aa,97c68c05,21b8fda0,fc70d74,bb586eb3,da7eab4b,6c104404,d9234d37,5834296,f94f5b54,beddc0e,3d7f6004,659952b7,90a6341a,de99ff26,5530e5e6) +,S(ae22ae10,d016b54c,c0b5423b,3f4c332e,3180ff23,c279078b,864e8e07,77e26a5e,ee21d64b,d6043d56,de3346dc,f93e2c40,b9a51498,b4d7df61,d476d339,7a2d0c8d) +,S(58cd60cc,ea7e0896,2f65a353,5d45ad06,517fea5,575c5511,277103d9,fabb5167,175a68a9,850b4026,bc7b5684,e859c808,edb5f3,7acebc47,9ba489d5,5aa9774b) +,S(4be8a0cf,7ce26101,49cd90a8,68f4049c,43054aa5,68bfb2a1,a5bfa386,9b2b485,a3bab0f3,e3bec469,f779404b,d025ca14,79e3f6ca,9d496f8f,8ce4aa6f,b7e3b404) +,S(428599d9,398a2c59,58c5f74f,1226605f,3c5c8e74,ad8f9bc2,d62b8d9f,d679d3c3,12a1b04f,add5d70,bdc5e15e,d6347f7f,6785c425,61f14ae6,275cf050,3a1bd5a7) +,S(134ba4d9,c35a6601,7e9d525a,879700a9,fb9209a3,f43a651f,daf71f3a,85a77d3,21c112f7,6a9b9b21,e2e3a7c2,8cf500bf,f48aaf1c,48e0e13e,f15618b9,ca62287d) +,S(d53cf8f3,cc5e5739,bc9f9144,a44e7b7b,bb8f2c36,b50844ca,9b2d9cf0,cd0616d2,799c23b6,c57aac44,90d71450,4388cfa4,689393ab,6f30a347,4503400e,c568e03f) +,S(a1e22cfd,e8d12f17,eea1eca4,ea0b520b,6598c036,d1bf837c,e23bc300,a384e5a7,cfbb52a6,e1fb6a65,77cd0377,8bc965b2,a3df592f,f73c34d2,a91b8008,74ecc295) +,S(72bf047f,a0da1391,78b97ea,7b317168,ed0576fd,71f49409,39a8daa5,2a02ead8,f8d93088,cb3457e,7828ba9c,bd8492e4,9eb2bf0e,2e23bfb0,4591e9bb,5273f462) +,S(c5373038,4b951abb,3bcd1f4f,98d983bd,cb5b36a,42719531,c4d1797,2e9bce59,d921f353,a9f7309,6dc16028,f9e1b562,f406bf49,54d78bf9,f2b4c8b9,2db26a82) +,S(ab20d194,e2a6c4a1,5705d3d,19300810,89342b15,e9fc6224,7be58805,a8682a5e,44dc39d1,8342502d,cafafe40,33c4893a,2dddddd8,ad7b238a,efca50cb,5d5b3186) +,S(1432ddfb,108ee664,2eaa9c97,585f47b7,b92a5ae5,39a38093,b8f3153c,e971c8f9,5362084b,5482e375,1662aa95,dd3b9a6e,65235aca,b0ce1eae,f5153951,1391e269) +,S(f199ede,4a69d778,61e107c9,376bdee5,6430e279,28c74d75,66e65589,be8c433c,5e7f6fb7,1b68a535,f407a9ee,2e42f65e,9835bcc7,2c34b8e7,712e5332,a65e9ac6) +,S(b24dbf51,47452b5b,ad94bf4b,493120ab,61ce2ea4,37b3ad71,62e568a,1d595d1a,b3af5a90,8d063602,6b3869d0,c9f31793,61afd6c3,8db99cb9,77b14e0c,46427518) +,S(d7fc29eb,b681e025,992d9ef7,295db58b,40f36c64,d1be10e8,c8e66858,d4d0d9aa,c587764,ca84b3c7,2f95eba,eb62494f,ce391202,90c42b9,e8b2105d,ed972595) +,S(5c71e90,d5f00ee6,e033f0c9,c1ac495b,d148a31d,143a8e3,59a99c7d,faa3cc9c,4acc164,ea3071b7,a4830a27,24135c49,562ea631,9dc4455f,808f1282,4e3bbbb3) +,S(4c9904a9,a33f7e33,9a3d85ac,c12b21ad,11f7d7f2,76e46620,76878593,9d11eaad,2387a445,b0967403,86ce4634,62dd101f,95650365,ac02ef1d,2417321a,3fac1df9) +,S(58f457ec,12d22482,2a91b78e,26f7d8f8,5fa39d90,59fb833c,bce4b1f2,5c9720f7,90808a70,79d4970c,b2b70ae,390844a,2f0283ee,eae05a5c,7d2dcdde,be656f2d) +,S(9867259c,51414805,3be6a73c,de522d91,a8d8b359,9f9bd39b,9c9575a3,90405bdd,9904fa47,34973bc1,77a3d0dd,f0edc0bd,cbd77b36,357734c0,a0feff89,4895f3b4) +,S(663b4991,913148b6,631d16fc,27471938,20a7ace4,ee85c335,17b60cca,b5e12b5b,1b295a18,16b92c5f,15b88bbc,177dc011,f6ef0760,15b5ea47,9bca876,ae072070) +,S(5e3ff13f,bed18235,fe28dcc0,72f09cfd,41394cd,a9a3aa52,5286cddc,e56acf05,c1488c2c,903bff6a,411697f4,44e6e72,6ed9c0bc,5aa87cbc,ed8f8802,6998fc7f) +,S(54c8aa07,2f1fc5a6,ade56cef,d7c6aae4,846f6855,34912868,b84b195f,78bbe14b,ef11dea9,5cb01680,e7205f1c,62aa5242,2c0db969,9b2a0202,966873f3,1fdff34c) +,S(bc69e00d,4118d8af,baef7647,6e435883,2ae9864b,f154368c,e2ccdadd,c58cfd9c,148aea9b,2babfe00,3a6592f4,d3788893,5be42ac8,a50f68d7,ba2cd738,47dd9c52) +,S(50ccf184,c0213602,af114924,fe100f78,1f0d0cc5,beafb671,9dedea00,c7c3ebe2,b6559878,d7c33082,4588dd33,3054c4d,2da86b8,ff23fa9d,6413920c,d876e36b) +,S(c24ca0a4,8ff2cbb6,235ef33b,42ba032,386d5475,3cdda799,e9bc53c0,5c299aee,8555bb16,bf4d7bb7,5c0cbdc8,8594454,bfc819de,72c3954e,76b65780,2be28fe4) +,S(cebc8853,3f6c3a01,58dfab12,ef52b4e0,a7473d1d,209b3585,bc94a13f,a83abf17,42fe28d4,136bf80a,7149a0b,7ddce53c,45e23c0e,7be85fcb,73c0e66,2c4c0593) +,S(7d921a84,65b11feb,7a755a4c,5d96b6b2,f17e07a,95db112d,48c03bd,18f61422,f0ccffdf,7f04e350,13ae7f36,411dea5a,ef69f220,790c37d7,354ce5e,83925f4) +,S(b6909fe5,6824e868,f4cbdd10,d3d00ca,23e5b4,35c78aac,c78a9a1e,321d178c,3d513c55,136d61b0,73dec253,e1ed817,782d9f76,b536d3f7,c3b0d1f,d06e6c1) +,S(5a3df3e8,c78c0fc,56971dea,ced3a6ea,e1ef668e,2485bcb3,d4e24408,7f53cb74,960721cf,316278bb,56bcdd1d,9f3385fe,8feea6b0,661bdf1d,44771067,661aaacf) +,S(dc65c06,50cc30e4,d759fa93,d4d0ab65,5cb16591,289206d8,7a988290,20c22f9e,be39ae0e,a41a81d0,2175dfd5,5e004e19,fa925a99,2166d862,296899e,2532b6a6) +,S(f659d02f,f2d4bc82,9f816525,24019a88,6ad539da,3f38b083,5d8265cc,bf3a67ed,bc9c7a81,9036c702,338c57ef,26134647,2a22b8cc,5543f4b4,4a4f7d4d,d4339573) +,S(b89bbc05,420a8a65,aa03441e,da1c54da,9ca84f11,e85a393d,47cc54b9,78b8e5c0,5f3a2fba,4cef4457,ca6befe2,7dd3f9af,a5d8b6de,86679eb4,c877c7b4,cf03c08f) +,S(b9bbb789,690b53e6,e42266bb,853cfbbb,f6788b58,b325097,a55470e3,d4cbc3cb,1f984f38,78427212,cbfc8a93,8c1f0d87,59792ca7,17635c75,71b2c4f1,29e35c2e) +,S(d8ae91cf,8a99ef6d,2ca0c15e,3132974,33cd46cc,55a2c8f3,9f909e96,7d50006c,4fe4696a,79d2f269,9fecfce8,8375cc1,81c2c2e5,4109f380,3377a020,5496d733) +,S(35dc2c70,181aea7b,ccf6a15d,1f708c87,cc8bc5af,93671c97,35867367,549357bf,6f27dad,a9abbe5e,5e59141b,78a2e6dc,5b5433ef,dc8c9cde,a6269c2a,68346f87) +,S(a4c042b7,d54b67b5,877442e7,2e81de4a,7edbe667,f00838f2,34f567a7,9e3791af,a8c6f7b1,6b23a9cb,64732852,c9734547,69ef3e4b,9165ebf0,a1dc4967,36c73242) +,S(d6ab68a3,353b6c65,3836b66a,8c39f2d0,892cf856,90ebb56,a5e8e4c9,e669da34,4847a9d5,f39ea1e0,ce392c8f,9e63e88f,8f3feb9d,7b2a05c7,23a932d4,b07e38e4) +,S(e161c34e,644eb3f4,fa217d33,dd3129b9,c2b85ad6,40b56e56,e20982d1,c5483d43,ceafd0af,a8cf7a25,be092307,22c30e41,b6ea151c,d027326e,5152aba8,d9a50749) +,S(94959a2,fdc2650c,b4b0219b,83ac99c7,c477132,eeab585c,1fb262e7,6cca22f,6243f3b6,ba7d4f26,24f7b7d5,8e070b2d,64610aad,b281b4a3,b93b030c,ac0cdab9) +,S(491129ee,3130c2,f262c4d0,a1bfede9,e470c3cc,8e80774f,52ea023,67e2e3de,c1e61e2,a5310866,762a0cf0,ebbae0f,738b9527,46001aed,a991e0ee,d95f0db5) +,S(e2967539,b0b29fee,a668eebe,eb8e47c0,1ed84950,a1f9fda8,6884a421,5ab6f265,c304cf3b,b7faabe8,cfeab6b1,b88d3d41,7e950963,745c2479,85211d50,888346dd) +,S(d90a380f,5283132e,7d6760ca,f2b28576,49445507,b8e8872b,d0e1d5f,56a15af5,97fa0739,7a1357c5,e24d0a3e,ce608332,107e41f7,c65d3c6b,98ed66c3,af30a4ed) +,S(cb917a08,153599e3,e531b1ac,63fb8e71,fcce572a,29fde1b,17de843,a99ea2b5,701c08a4,a9da11c9,3b4be64a,6832af1c,900ad3c1,4b4dbe70,c62e3e08,55b41b6d) +,S(e6ee53e2,98efb026,bce900e7,8d31f3c4,539108bf,d4c5139,16417f8b,49199a0a,bedd41e4,751f657e,8cfc65c3,2a82f981,4b223e62,95ec36cd,da5125eb,da736429) +,S(5f777c41,f4e3441e,75c66f28,852e7815,59d0f3fe,b8b05b59,b6966fa0,de84df2a,7fcc66b8,127d26d8,e0ff69cb,b80acf44,bae5546,edc9bc52,90b73da3,447a2731) +,S(16d312a8,1295ab9d,c08f9fbd,61e6445b,5ef1dc51,fce19d,89f04e7c,66ba2e07,6c555fca,2a1d2f4a,24ced2bb,c3966f4e,1bfc1912,eca39067,503df586,41a4d4b7) +,S(660d3993,fa887e1e,8b05d80b,96e2b70c,341c3ba3,351d2562,5792acaf,3859de3e,87b06f5d,4c6f854a,8714eb3a,55454346,f931c21c,c77da23c,2d069d33,7dcf12c) +,S(9d45e660,879b6e8,b8007a8,ba7fe7f0,c7090cf6,9c733bf9,43f4eef9,965a1ae2,c81a3fd3,9b6b83ba,d163c763,f3010359,ac050e64,a47167ae,2ca41345,c7d95662) +,S(c95d92f8,c81d15fa,a68f645a,c1ebebd8,57c6942e,e75ba13a,3a4eb9b0,c45c43ba,2f55ceb6,c1de7877,7b322a91,7f3e48d9,480b80f,d49e362c,99f8104b,a20f392d) +,S(95d445ff,e8cf8240,fc4e9856,9d41164f,50e9ebcc,1fd3bf19,d4309de3,34b4c97d,7c391704,a75cffe2,f8971ddb,417e8158,f97a3688,6841f02a,c4b699b8,df6c0d32) +,S(40f028ca,907d6521,df1f052f,ba5268f9,a60e705,bdf94328,17881b44,1500170d,4eae26bf,37d04379,126ce777,b1fe1115,8c34d077,bba66994,78ede7e,244cc8c6) +,S(dab90c34,e7460068,d80d2be2,2bd81f9e,667bbd96,4e30c23d,3eaa7a75,a61e862d,cafa2892,5128bf3a,4821cd14,8503ca8a,86f06388,d21df6ee,af92d514,e66c5f1b) +,S(6df2280e,381ef8cf,922505d6,7646c1af,105f91c0,59e8e7a5,3ae2e7e6,cb456be,d94a020e,7776b713,b31aff5f,d72be6c,f29bfe46,16ea3d29,95913db4,698ae3ca) +,S(a13d83d1,3c60cf65,cefc8692,f5d339b,2873582e,938373cf,3e4df54e,ae32ffd2,8f511212,a65d8963,d7df7ed6,27d87fd9,208f83a,1a4dd14f,ab0593d6,38ac71d0) +,S(ad4c1ec8,39950ae4,a7fa551e,5aa637a2,e5d40bfb,3fab696f,ea886a4f,40bf2167,fea9b599,202841d0,c3afbf08,ef1da210,cdd92a4e,6cad485c,a0d5275e,8a5dacfb) +,S(64188be9,af657254,1314e661,848970f6,35a0b6be,7e594824,6dcf36d8,66840610,58880b5f,c3df9b6a,45b49ee6,b90f6b5f,f3fc440c,37855167,a30ac013,3d48e53) +,S(9b71366d,a66b165c,6495e4fb,46ecdc15,84a193ca,d65ad8b3,7a01a3b2,cf2e43f6,d7315165,ecec296c,4b71a860,f3b2f0dd,fb9447ed,5c59a458,8b81f679,34321301) +,S(4a3c5006,74814f95,9e9c7726,595658ff,84e369af,636f6aff,ab579bb8,5583d395,1b495757,1a302c2a,d1cbe53c,2ba34a6d,66bf1aa1,8bddad33,679e4890,5f9a21e9) +,S(e4305e5f,72c43558,79a749b3,d563d4d1,dca704c9,c8867d01,ef503cf8,97c90034,ee563dca,4d31945f,c536a318,e9297d28,81954b37,af992722,9e4e0e9,1c16244d) +,S(3aea4eb8,ee74c9d5,2259f37a,da33ae1c,78f5dd8,d97511b0,2e0a0201,82840a8a,8fc58135,757b8c0a,a8f2c2ab,ec9d9152,20ad2046,f429667c,c4586765,10e93e87) +,S(58e8e94d,e9f85066,7cc4c61d,acd212f4,77454942,33deb015,858e500e,9530228d,5a95aa24,fb782a4a,e64e155e,eac2b644,cd614315,9b46db6c,9bb4fe4d,5e5fd690) +,S(6642c782,7e1df912,ff54dbf7,41fa1567,3e9c3aae,5e7630c6,9cb74b60,c070af1c,ff338a86,34a404c0,cb26af9f,59df36a9,e1a848e1,ac178b25,c37ac177,db45e947) +,S(c5c69fa4,65c79a50,a98996ee,cae55474,5c544a3,ea838a42,e12a733e,9181b30a,6e805461,5a424a9a,1fc229b8,7e594211,697386ef,189d1ad6,ac75eaa2,5727253b) +,S(f4faf099,fb16a1e0,e5f64428,5317d91,a31daeed,fbb6a6ec,b70a213f,ee95217d,ebfd8445,42fee872,1f721f3,11ef28e,30618bd1,bdd097c1,ca573285,5b079734) +,S(773b3e69,fda8abed,fa61ef37,57101756,9d9d2a6a,ebb4fc5d,d9049d56,9c66b76d,1bc051c6,302a383c,dc0756b5,114dfc69,1dd2180a,88a4ea9b,6acebccb,a59f27ca) +,S(bcf80e7,b2b54cf7,971fae7b,db8b3826,85acc1b0,f987f352,d9b0b3c7,ac78142a,20620b00,8c010ad9,7a98f093,8d9a381,f9935d5d,4bc9b060,af2ee6ab,151eedce) +,S(865dff30,47f31564,99337316,ea20223c,5967e034,83d92d54,7486fddb,fda959d2,2b655c9e,37697f10,5535b736,a31b2c6,7f5726eb,602f1438,f808ff62,4bac074f) +,S(e48e0e18,101eef40,f351067e,63d2b34f,4fce76c,d204d6f8,85d2664d,fbc92d3c,594061c,8d3f4748,bff85cdb,f70a4035,5ad826f3,46d44aa6,7eca3196,e433bb65) +,S(9807e350,7a03e134,9bca9101,cacca5d1,a564b647,8c906619,61ba503c,5ee15bdb,301e68f2,d584b1fe,3eeee7c5,85cb4d0a,26621bda,229589cc,2704dfa1,1cb8d927) +,S(95f94e75,8602dcd4,60ded52a,c9d7ab40,1fdf1405,b271acb4,133a86be,cfe5027,f08d34eb,e9cf1b1e,78e1fbec,452e1ab0,412c642e,1328b2dc,f5e08b08,38aa3c51) +,S(7ffa20eb,ebbad406,deec68c6,9bdb7b0c,7615a56f,5c62a646,a57535e1,68a82a31,230241b2,3dde374f,7a039eb5,5181e954,f0472056,79edc688,7c4ca6b8,778333e4) +,S(1dc7e0b1,487fbb33,d1ecdf84,7bdbfef5,f7df9f31,d07ff024,be063a51,53eb5498,ebcf72da,18a1a55a,5aec4aa8,efe09407,263a7b36,f09552e,22cbceba,7a3cf980) +,S(a8052e02,e39d9981,2ac6c4e6,2cef526b,9cb29843,127f2227,50a8021f,4ced5cd8,9011f0b4,9dad7e5c,11222b64,c5d8c9fb,297d9afd,c683f545,849d833d,f2697220) +,S(3edfc4d7,f1f699c2,8e8ac2e7,5cd93e69,fff31607,d99a8195,30603437,f9bfb20d,f901260d,68c6dfe8,aef8879f,ea1ba009,a1e1d931,fa6ba39a,ce1e2673,ba759311) +,S(fdf8ae7d,c10d01f1,c39bee75,3be3307b,53307caa,4af0e8dd,9de7d696,45ce527d,2425a3f8,c6147073,3a44d3eb,eff3d8cd,61e5fd55,ffdac357,d7906600,153a8dd6) +,S(1cd5ba80,fcfc77c3,d06e230e,e7ad8ff4,f9ee6c60,a71d37b8,3718d8b3,15d5a4e0,f90ac118,30b963ab,fc64492b,415db7e3,47eba55e,d2c5a64f,578a13ea,b4435cbd) +,S(3cdb43ea,b7afc936,24b80269,18319fa0,e75de21a,c0587af3,541e492f,1510257b,49b6411a,c74a2eb3,ac2ec784,feface51,8d5a5bd6,e76d694,bf5ab8f5,c146abfe) +,S(165b6f5b,9b1e6d08,14e44cc7,c7969297,bba7c659,58dc3274,7e7c4148,e30c09da,e715e411,2e6cb67d,cb8e1ad,997691f3,bd6119c1,3a5f0329,1ea3928e,35c04551) +,S(d4c1190d,da3c01cf,6c75fa06,7b4dd1ee,e645a0cc,8b034f4b,24580661,8ced0bff,c837ed81,b6a0e5fc,6a02d6d5,f837db1a,20eee55b,41ff531b,9bb642d0,52c42bfa) +,S(f7359bd0,bf7db6b0,48f1a040,a0163fba,285780e7,909ab689,7963168a,a7de9c29,8c71bc3e,95ac0f52,54db6192,5c6f9112,759635fa,95846be4,6a28573e,2b25562b) +,S(4d54a2f6,dbebbee3,8950627e,8cf2c65,6ca071e7,86687f3b,a0a77178,be14c55d,6579dace,73dd14c,695fd781,218786ee,bad84445,ccd910d3,43aa2478,f5576671) +,S(f70b532c,e7203208,d6440bf8,55e1293f,cc6ebd75,96a04b27,9fc056e1,2ee32dee,e9d18f7,126ed56b,4a657104,2441bc08,1778736b,91062c9f,cac28cbf,b8737be1) +,S(bbf3ff3e,577aaf34,157e32db,d977b907,e62b16b5,1ae0abd4,f14e71fc,cca11357,cc1a78ff,44af7c2c,cdf17423,9b3aec17,b660ff2e,fc07953,2d9f9d6e,55d3abf7) +,S(53bb2321,b36d1dad,226ceb24,f55d4292,be245444,b2349611,5a649560,59729700,a5db4fb9,46c4a2db,b1a634cc,4032b7b,cf23f7d1,717a0ee9,6c02f131,24f834b6) +,S(3b863ec5,5e4ff2cd,d32cbc81,6e645009,da444255,9bf96267,2cd012e1,15372186,914682bd,d6a052bc,25cb4d41,e9bb28ed,76e9aa55,3f5aaf25,75140e04,eca69fbd) +,S(4cc4a750,d641c574,5c68a48b,953ee51a,258239b2,fda1f5e0,80831417,7b837946,cd6f665f,6f32246a,1cc8fa61,4da2783c,f4c7b92c,4f42749e,b6bd4a8d,8a84c54c) +,S(6f9b5d79,efddf08d,26183b4c,d6001d6b,fdad9e8b,dc5853,f3a8c47e,7e6f9e96,b81148f2,1e50152a,8cd7727c,ad14862a,37fd186e,2054d4c4,a4cdbfba,a9076991) +,S(9e13d0e0,44cd3fc1,1c7596f2,9946313c,918caa65,bcb6387d,361eec31,ebaa6977,c5f55650,7691bc2a,b2c9e4b8,512f7282,24276490,257288c5,2387fee5,54bc9c0d) +,S(a4441292,d0e0db3,2a4f33c4,8bbc5fbf,d40650c8,d9f5c4f4,88a1f69a,d71571bb,a23ef48d,38abc24c,608dd688,d524bed,a3709a5b,3567ef3b,e43f0240,796b7ad2) +,S(def598a5,c4828c5,16b7076b,9682aa82,4e74ab42,e4d4692d,17c8f289,67f3cbb4,e6b4bf28,6dba0803,e4a97a1e,be55a088,10660466,3d7726e9,300109ee,a1d62a49) +,S(8e991fb7,372df8d7,7b09436d,c9424a8,5a14888b,583b3c58,6d2a19e6,91e75b67,1780f6e9,b8379b0f,ebb1328a,69a96878,9f58b45d,8e3ff218,81d753f4,8ed6c43d) +,S(bae09288,e10351fe,fa0b0971,400ac3d1,a7eed65a,b11d1ba4,8a1c6240,bb981114,dfc2979e,dcc2de8c,abd9abd2,27cf7351,4079d950,aba60e3b,f4c775ac,72c30f4f) +,S(4d09ae3c,b484fe27,411d4142,e41de523,2c54c42,b387c7c2,cf42a23e,e7611fc1,b94fa116,27eaf5ab,8fb7fc25,1345eb28,8f5249e5,ec65e056,d60e1294,41481375) +,S(32f57ac4,3cb29fb,f8a00d8b,c95da8e8,3f0f541d,ed6c9e78,8af17a14,6a2704bd,2a969b58,9a3f9a5c,26b51ab6,1a5717bf,c06eb438,85e4f4a,84b903b2,da5bbf09) +,S(595503ae,e179f59e,bfc581b8,7ac18e1d,55b4c794,87d90d62,492d3ea1,1ec57579,1f25d8ba,e38c0a69,50a17836,a842b418,b0f7c317,9486fb16,9ba11b23,d315ada0) +,S(5555fae0,6f1563af,238184c9,304e26ef,f8b2121,394e6856,79de6792,31a56842,6840bd14,faf202c6,60650541,48bb87,df27b979,4ec0da66,9ded6830,b0623980) +,S(714321ed,2f0432f8,a05c33d1,84619de5,f81fb8db,95ab3121,c24fc998,ab9b9ca4,4470cdaa,7067de2a,e6678cd0,6d613e19,35b1edf3,bf278205,da69ee8d,6086c2a7) +,S(d41b84d5,9a0085b,86e88fc1,499151da,b0b9a574,92b01df6,36cc2288,313bb592,c04c54d2,57fe5ba,691f6023,bd72edaa,20e71a97,1a760bf5,3c990a39,f5ef7c23) +,S(ae34a065,b42f5158,e6a5b91b,9ff54b0e,6d5bc906,f6d18c3a,82865e,e9038f34,bf2c90fa,30639811,2ca2ed02,b7ad090d,8bc990db,b6140a05,afcdc80c,bae8490f) +,S(9b3c2682,3050a52,a164ab,f4504ca4,7750c889,b6465f95,658ba7b1,c279139f,ee36938d,8a675824,51ca289a,55265606,cb9ae4fc,8cd274aa,41db5ea9,9a5b4299) +,S(27dc9a57,999ed109,c3dff978,58d44ab2,73987af7,b617e9c,766331d5,c06e0dfe,4e97536e,67e363c8,add07030,d59061,33a726de,38dec51,e5a20009,61ee0fe1) +,S(c3415e9f,9c823521,bad3090f,f2c48e8c,647e438d,70397e5f,7d7a6f2,b7d7d4b4,8c3bb607,c746147c,d5efbef,7e27d236,c4063116,89794cc0,40c235b4,6af412d4) +,S(f47e44dc,90c8bd2f,150d9dd3,e4922395,14990fa1,f2fc361b,a24f853a,b37e33a0,f4282a26,bf5f358f,2dac4956,8bcc15a0,d7eddeee,b43e6fd1,8f35d5e5,4295ddb4) +,S(3cfa945e,6044ec2a,da895f9,9dc24575,deee57e,df8b1a10,a2d2ece1,9951a812,d0ab59a7,46ac6edc,69307a0d,caa00aa9,e7b73897,b89185fa,9dc3899,ae7e3664) +,S(29df8149,9d83bd0f,8fe61eb8,8f0abe0,96a75e5a,2cb0a0a9,76d8d27b,6533a4ed,7eefc80b,63f927c2,e905a56,62d5ed34,e9bde8ff,4402491f,19215c9d,494e62d4) +,S(eea85a80,566d13bd,da65f553,b2077607,c8b9184,6a5a8096,f57afe93,ada9fff4,b5389645,fd772da0,1cf3b535,6ec40279,cf76d812,11f20a16,71d7ecfc,441d71bb) +,S(e1a69e64,4434db7a,54550d44,adc43682,c128c560,3907615b,9282cf1e,e2b74f82,bd434a85,984a6e64,441134e6,d1f1a3a3,adeab658,c29af8b5,4bc42667,634d20ee) +,S(2d99f69f,a7e9f3f6,6a53eea4,381a4c80,ed17e8e1,4507d7f,4a80ef25,293c5fba,25a6aff9,a23a406e,9e34ad6a,21627acc,96b6ceb0,7896382c,833b8fe4,8e603e0a) +,S(d2482127,1554a14a,7283dc8,1ca70179,42a35cfa,c8659b2b,db78c426,51807cb8,a252027f,3fac319f,c767652e,469421b8,d34decd9,c9042d58,f8aa0ab,70e5ceac) +,S(bd030cbc,5f0de61,ef194eac,38f7443c,d231f75a,a0b568c5,416c5b8b,917545d,ad0833b1,4f1e23a,76c0626e,71129455,60fe62d7,4b3a1b95,69e4887e,c0661e78) +,S(afb44b49,ef00b1e9,59c7a864,19d2a4db,71d9bb0c,4e1746,9550d39c,9a37a161,eee390a9,530a5baa,5350019a,f756185,8038c2ee,7f78c365,dd6f62f0,f0589aa5) +,S(9e584f1b,e06ea4d6,5f8dd96f,206cf4b,88aec6b9,ccf06779,53acf110,99e2165c,6994ce27,46b0eab3,d8608ef9,33b61339,d3e589b,c2acb7bd,aba3af72,b082fd24) +,S(d2265b51,b4f7f4ce,1d0966,e7012f9,76433dfe,444b2351,9505b29c,d520c6df,44414498,df439478,328b330b,6f8c6876,682b6a32,b5d01355,2494286e,a635bf65) +,S(fcd56867,58c797c8,3aa1f1d8,a9ba34a8,8e624aeb,666507fe,706b310f,3342264b,680e0b98,455f0e64,94622fa9,e36f76d4,863a9fdb,a3df93af,c688c45d,fdc5967b) +,S(bb9a0c0c,74db0525,370e8235,9d733aa3,494afc03,fb61a1b,7c2536ed,9903fd91,239929a2,1c0ed586,b9bc8f03,af422994,f81619c6,b2fe637f,a511c07c,d9421603) +,S(2358b078,1989d6b5,666d9158,2fc640b1,13d52e61,ea2147cf,a0a103e1,5ae80db0,73f84f47,a78fe2c6,e4d01d7e,3dc10065,e052401f,64796358,c784d59f,742cc8f5) +,S(ddb3409,ce3184a6,d9d7b4c2,cbdf32ef,ebea1be3,595ba19c,42933882,237dae94,59215423,3760cdf0,513442bd,2fbef84b,9c8c0fb1,ef16fa31,783d4dcc,50f24f24) +,S(f99aaa8d,8d42ce59,86ee8ffe,d4dc8a48,81810a6f,cdfa9519,46f00857,4ab1c3c7,d0f29fd1,32bd65d,7f9820b6,830a3e42,8664f9e3,9cb25729,1adc36db,4e177187) +,S(83042093,46ced0d5,a33f491a,c98aae7d,51f17ea4,1e5722cd,29c47f15,49c183aa,1f680d05,ca015018,664dc767,4de0305c,b09efffe,e7b164c8,c733d2ed,18c15d8f) +,S(339f95d5,5e293243,ec10b3a9,a8dba385,dcaa23a1,bb424bbe,4c894deb,c61cc881,3a4ec84d,67831768,e9ad1d9d,db82f785,52883fd8,b0b63bf8,38495a4c,455d5865) +,S(f94de87d,1123f6b6,97d4536f,7bb6a995,ff158060,b7d72b9b,3c9d74c7,1afb6009,f123cea4,bd4859b7,a852270a,17c76c06,e6050a26,9c035bf3,6c505fc4,1fa81066) +,S(71341ad1,bbebbb4a,17a7701d,30dcbf7e,2a70b901,5f6c5ff9,9fb614c3,d3338fca,6ab14a0,4b4956d4,a687acaf,30d7997e,cf70df2c,b49356fc,5b86453c,5ef6d55) +,S(79b8571c,f52ee30a,4d3632d4,965cc6f4,cc6ea06e,fe1cb7a6,ca2c9c9f,1e835bfd,259c0c7c,b8fa8345,57febdba,2183042e,78f8cfaf,24a41dd8,2eb0ad3c,426683fa) +,S(f3ce9dd9,d879e70e,21737426,dbbb27c9,7af84307,6855bf4d,af141d55,5006e402,302a436c,f8be3a4f,dd70a9d1,8f63cc8b,ecd3ba1,ddc9aa3d,f4285239,61e7553d) +,S(4a66f7b1,52a8cafa,78d0e98c,2f8361b9,a0bbad47,d23b24f,5184477b,e90d6318,7555fd5e,87676154,8f7afd4a,33511daf,b3bc4a72,c9f54d4,92327a2c,c235c02f) +,S(cd3b4037,5cd6da61,ff432898,fc592175,c90fbc31,373489ee,c988f280,3459bba7,b0e86ab2,2f2d8d97,5f68a7ab,3ffa3be,511390df,5b647608,fb07f29d,3155728d) +,S(e96f166b,84d98bc5,41ea8885,f7a48612,227bc907,795782c5,d0e2325d,96cb44a0,18ac220b,8def89a1,e3bcc2f2,7a66c0ab,3ee27c3b,882dc16f,e2571963,92b94310) +,S(87adb3fc,7fe6b07f,795bb7d7,ab8383eb,a3f91564,ce89d267,599657b6,9d793838,68677cee,bc7b3d09,efd0f118,d392d0f,d2d5f2bf,f2b50230,e127acb4,97f5c886) +,S(fdaa2f5c,ad1da3c6,3d241a7a,b4365e63,8eede0f8,229a8187,6cd76a3a,7020c545,5b04616a,a1a84785,c4315dda,da6289bf,e57cb9e2,80c42395,a1b13d69,dfb2ddfa) +,S(7eafa986,1a94fc8f,d263cd4a,1e481e1e,8bc1a385,c4ab748,8715b032,3bcdb52d,d655b395,607bb0b,c9092364,803798d8,17a4bdc9,a30e2844,94be8322,42af9949) +,S(a7fe4656,98538c32,844337ea,bc90fb49,feaf2fcb,8b86da6c,d173bf9a,70e62a53,cfb26d1d,689a9075,55057ab0,d4261e2c,acbf30d6,cdd09f95,9cf1830e,5d635aad) +,S(8bcc3b82,d543f365,478fe32f,dc9860f0,10d51f74,b7b5344b,ca6b868d,3c11264e,6bcc32,f7ff3e48,fa1775da,44b64848,f52329d7,d8bb0a09,338b799d,7452b4af) +,S(faf9aa3e,f1ccd659,2feb2add,a1b58ed8,27511b39,bb981cee,4fbe47db,5cab2917,854b88e3,50a6e9a1,fc7e9e45,f3fdb69c,8111c654,877cd620,fd82ee18,ba2d195b) +,S(77012901,ea269067,4d8b4397,e8976f98,e33b1709,c81624a0,7916da35,af75cb29,b63695d7,cc896358,e119eb98,7dc0f67e,22a70c5b,5e6e2072,e61ef62f,9333bc4) +,S(127602ed,f5f1a04b,813e2b6b,2c27f50f,803b70b7,b9525b7d,902f348e,c03591a4,1f791f7d,2427532,968f7a08,f94df6be,a95b7e6c,5490fa9b,5eb5a3f3,207455ce) +,S(17e82c3a,3731a73b,36501eaa,fde3ee8d,ca9f2573,dae1e4fc,594cee8f,e1d19179,8af04092,79792fe2,273e3f0c,e642f3fe,edf1ffed,59c5826d,a7fb2716,ed365a3e) +,S(3c34e27d,5d5737b7,78e968a7,fe8e4113,f802bd30,1e0367ea,41fc8b5c,14b0dd84,67bfc61f,bbd062ce,6224e883,9092a962,eb3105a3,b6634dcd,d59c61da,906a4ce0) +,S(b7a35907,c7b55a8f,7173a5da,c73e306d,64ee0f6c,cf4f5c76,3416bd4d,4f5359f4,d111c21c,e5a8674e,3a64adbd,4f56b1c3,61350b,44a552fb,19186b8f,95ed534e) +,S(6c7d4836,62c28812,7b904cc8,969ff925,8d9fafae,e88f6d3a,e6e4d771,bf8ee7b2,b593dc47,3c29694f,95b00169,286e3981,afeae4b3,dd7a788d,f32a14fb,6e6a8e7a) +,S(dfc406d7,625719b9,4f709993,c5d15062,4c725ef8,eecb2308,bfeec0b3,6050bf4b,651c0d2a,fb29eab7,d4740b5e,1fc2c069,54ced865,7a6bb980,2de8d873,a451717e) +,S(1631fa0f,4e9fdf51,a2842994,da94f835,52b5bb40,348c706b,54079073,665c6bfa,de202803,9a8d1ba5,b133ff28,6df237d2,a8d73343,a08e7c2c,4560954b,eda5ade7) +,S(fc52b3a8,8f712053,2c7667f9,62146d40,eaa3e924,327d959c,a49b74a7,da11e5f6,7bf890f3,daf8f9d9,49e800de,8a3f5458,5aa46e2f,25535cdc,18170391,e2101daf) +,S(6b7036e5,c5993c6,8a744776,abb0b5b3,31a886b4,93e49d41,bc7d93b2,28566fd8,6ebe771,42a56189,f272b6e8,8f70f356,ed1a3d37,ea2d5e4c,998e47c1,319e2ec7) +,S(b13dc5ee,7333e3a,4b13628f,7ef96ae9,4faee9d7,3a46297f,f1e357f6,e7a57a48,4f30b474,99c66456,33f5b521,9164a890,d8cdb78f,8c7ee211,1bd37fc2,d41bb2bc) +,S(1888e944,6fe20426,d4fd677c,5cf1043b,605e93a2,c8532623,b5951e22,34de08ae,9e1f4fed,d5de001b,378ad1a9,98e31f00,30af9674,c383f287,50172e03,ea0b0f81) +,S(2495b334,9884d5f3,166f8fdb,7ff81f9,9042383d,def7cab6,3c2775ad,226189f8,846850e0,2a1cc051,eea77bbf,d5f44499,673f40c1,190e379a,9b37201c,51a06e9c) +,S(e4c0e483,f21102eb,7dd2a78b,5a605b8c,410bafcd,f2ee4bdd,fcfe1374,ab32d17,b53fd34,568f5edd,a6a3abaa,2d2c3a4a,bbeef0f6,c37bec1b,fcf012c3,dac15b9f) +,S(8f9bfd7a,2e798812,eb927fc2,b0ad5eaf,81a0a30f,a97efbee,a1d6d9ef,19348a5f,1eec535d,1bee520a,13a8410b,6f3824cf,7c9d5a82,8208d2ae,dc89fa13,8bb7c2b3) +,S(1d95c760,f3fc2eff,df51cf0c,4b708538,efb56675,eba3ff8d,4f6abe65,d3f167cd,c2bb1122,5016ffe5,6859da47,4b777703,49e4e655,5da3d9a1,6dacbdd2,d42ab0a0) +,S(9df72bbf,fbcdc42e,adb71d69,1791f073,7f945e8,bfbf4e2c,68c5e3f6,5f6955f,24d47aa0,1626b0ac,ce77827,fd7daff,7424d4c7,1d76ad3e,b66d22b2,6f7d1df9) +,S(2df6ef96,7c0e1a41,2bb48bdb,f2cdf8f4,22829abb,4b7a42e,95bd9cbe,8b7f860f,bace2e70,7915069a,bdecd097,9d133cad,bcfedbaa,7eb9891e,ad3380e,9ca99401) +,S(82bf2a99,624e408,188da19,59599de0,eb947438,fcd45784,9a731a1c,15796028,3b6c668a,e5b8f394,3ee713c,a8fbfde5,8ef0f9fd,84054a9d,b626e274,37e611aa) +,S(60260fff,1f213916,9261edeb,5f1d2d0c,a143ca69,400b2776,21793c11,fbc89d41,bec4bfeb,9d09f8d5,cdb11e3c,f65c6a7f,d4aa87f4,e41d7f4,69717a64,5dcf9945) +,S(6391ed61,80cc46fc,33481faf,d21151f3,cb678e3f,4d667748,1a24a01a,c5e9180,c48495fb,fa5962b,44bfbc4f,491b89a6,a8588fe,91677b19,b872dea8,8e34026c) +,S(20807816,758361aa,d5f62d25,8e3951c6,da518890,26507a7b,c0ceb7f6,a96c141c,8526d53b,61c8427b,eb141d91,7a338fe9,f7789a60,cc1a4a62,15dc754d,a73903a9) +,S(1ecceb4f,8acc649a,dbff29c0,fbc62c11,498c7cb3,7d29ed15,e0ebdf03,e994b67d,1c701af7,a9f3d870,81efb798,2382bed6,5d56b8d3,f050bfdf,6da32b10,a18fd4d4) +,S(be82742,dcafe3ca,f646cf01,80202cb4,7086e0f8,ccea3c11,dcccd9de,aeae688d,236d1fd2,5e05d6ab,8651d88e,33d18a3b,caa66c06,b2b68c50,f6158717,f23b4866) +,S(15252ce2,3f666836,dfb47b60,1e642abf,6e56ff2b,5d58fc97,ab09f29e,1b4ec3a9,9a6b2658,f52dfc45,32e6b482,fe909e47,ba7b4442,3be4d474,a524df32,d6149913) +,S(b0429186,21f94599,f7032b4c,1b53bc6a,9259f142,27922f42,fe774772,4b0ee9e7,e73c32d9,ede68eab,e77d681,dd4cbd9e,a356fdf3,bf066f33,6ff2c367,59bed08b) +,S(5fe0917c,1bca66f6,f34bdf1f,dad88a5,b3dc5f5e,2e0227e6,5f3a79c8,9e66c888,885dfcee,c0947b01,71dbaf65,52c09ab4,c0414f8c,7373ec5,e3080521,401ed575) +,S(455985e6,44d9b679,85980752,a13a3f94,94bf9cc,8e6f10ba,fc7a70c2,27ce272c,47eadad3,15e88a99,9d3f5ce7,792ebc10,2fc68f18,cdfa1df,564601f6,3b26c22b) +,S(3562aca3,2291c1cc,ed072a4a,85fbf82f,6b3299f5,2626154,2b41840a,1c868d4,ab4b2656,11db5875,10c48284,7f72c75e,f822f46c,2e7760e2,a46070eb,5db7100c) +,S(54225801,f82406ae,74416373,7408e94d,d3990eb0,60581c47,b453a859,cf63042c,43834935,a6a7acb4,9c086391,24e80fde,72c0a876,1c13a340,1a4e48a5,d96f6a2e) +,S(3c253039,fc8278b2,8135e21,700af1e4,dad4263e,ddc867cf,a3532499,c2c1e48e,ee01ce7c,f8c56c74,1b4b3593,b0cb90a5,9c59cbe6,9a48235d,1295c1d1,ac657081) +,S(8adead1,d898eca7,9e043f71,aa735a32,763f75f6,f6ba7a70,bc47a284,4b580972,7a370bda,412df63d,5590b3da,80365c71,1267cf8c,e3fdd1bb,91ddb981,d213bcd) +,S(8361e522,34c8d62b,9051a95,8af3f090,4f15ee35,4b69a560,7155ea4f,69548037,ca2c329f,8cb65e8a,eb6488f2,2131c525,29df97bf,c8847c87,47145767,7f82c954) +,S(97d65162,d96feb36,e8f00221,52c92c06,2e97087c,703a9dd7,7241216,2262807,15a260bd,bd591c7b,91bdcbb4,c2684545,4706f039,8fef8de,9173e7fc,a3f31f44) +,S(2609f072,5ec8e5ed,4ec86128,dcee3baf,9e62bc24,aedbaaa1,eed8dd31,c9c07503,d51fcfc2,55398507,7e471397,ece94d92,e26375d2,2bddc0b0,d1b780a9,65caf2c3) +,S(820e8f01,5b4ec57,b884dd3e,6a740d90,68fce86a,a4833636,4b65ba6e,9e272357,bfc87d52,eaf352bb,91f071ab,6e986308,4f197671,298eb614,93152f54,345ce5db) +,S(2116bb76,7a56312e,71ac58f5,ff2a7071,1be5b711,1e9e56d9,aa098af4,b991db0,2ebd4fc2,abd618d7,d1798739,7e9b8eaf,8276086c,2a5066e7,e7525603,fbb4c40d) +,S(e43f029f,97f4370d,65826870,3f29422e,7b81112,61364972,e26892f,77eed56f,4e265fe8,40524def,23b7ed34,54c6618e,ec70d3b1,92ff30d2,1b9b6fc,b1f7164c) +,S(9b4ca445,5cada269,2a77f7e8,9aa3082f,ace4de3,898408eb,6a7d1cb0,8ac15c14,1446e397,d1c3fd20,283f43a8,4679e728,64f05251,b1d3bead,58aca70c,4c0fcc29) +,S(e2abb09,c0566f51,7947f99b,2d6fc4a5,637310b5,5f9d9014,84decbb6,ca22cbfe,f334bda6,a1d9cfa8,2b18f8f7,e90b8426,ae13e20d,8834e061,ab1671fe,4f4665f5) +,S(3579fd9,9cdf0be0,2d7e8587,2e213ed3,3a424650,5608d66f,8f936ae7,72511e28,dd93278e,ce754f69,4b3f09d5,a3c32c99,2c5f2e04,cce0a517,de750a38,ccd88abf) +,S(f307f2fd,d0f6c0b3,12841e5e,1e17b966,47d7ca93,4ba4970f,4f9c0c0c,3ccb071f,4829a5bd,40555e18,bf80ae66,b9742249,32679acc,d0e46003,e079e2e3,d20d248f) +,S(a462e750,9e718317,dbc72b9b,fce5909a,bdd2fc36,d56a525,97d3adc1,fe4b98a1,2f9ee390,13b70415,d2e6de97,7aba55ab,1f7c6f2a,a5a7b541,a7101a62,f2799836) +,S(72ec447a,245624d1,1e1270ea,1c4c060d,c6501f11,70c69f4b,229bb98c,e7c47804,cc32a876,33bb7d62,e660ba5,59cc1804,10a51cc9,dc48a9ae,fc3d8225,35fb8ff2) +,S(b97345ad,2a7eedfe,71ae185,11a3e2d6,c431e628,363e01a5,21622c17,e92b32a3,2ba1cb4a,abe0aaa9,619ea819,4e5c0222,3bea32fa,e4ee3378,ba798472,19670e2f) +,S(f417f269,de287f06,8a74a330,14331059,73ee691d,a7f5aa1c,4e00a100,1e2ccd56,1bb297c9,5b3fb72a,3263f126,719a82a6,b8bf415c,e81f6838,2c8b3a9b,42917584) +,S(cdf7b5d5,f7632248,be1bcc1b,61f56491,e81cfe76,1ee897c6,fcebdf4d,109b9b41,118f3f6,32f18892,d37a2aba,1c8d22f6,587ad56e,eacef09,b9202005,75ab7b11) +,S(3540c9dd,992dc4e4,9aba8fbe,8f28950a,24921b05,e1bae568,2714aa6a,95eebb81,841d9499,7bd92dff,53ee3c86,eafc5f6c,6ffac94d,3161ae86,2182caab,8d5a9268) +,S(70f4ef3,37a5519f,466cfdc7,ae779588,74c9a9a1,9a558550,8fafe6fb,d61decfc,413476f7,78f5d377,31aa712b,5c866100,bcc2a33f,ae1a078e,c5e5cbc8,4b7bac5e) +,S(d08990b7,ad5c205a,e5be2700,63bcf8a7,e13c2a,73dbf321,b0d9cdca,a1648da6,b0aa7acc,f47376c,115b0226,1494162e,d425b496,a2392aa9,254655f2,4db6cf48) +,S(53d6c5ec,f59c49fa,d970611d,b8423bbb,e2f5aecb,d4575877,d903d95e,eb88e455,6a954f77,532c80c4,42f2bf65,8e9d763,617c802f,369f1a62,34927e55,ac549f56) +,S(af7216c1,e51fbfb4,a5ec1e93,717f7375,9f15dbaa,86706ca3,6636f499,416ce194,4ed49771,f858a8c2,bad65a31,b5ea5a53,8841553b,accdced4,8c41e2f6,984470f0) +,S(c560d2be,2f2fa6d7,3f5224e,36acdead,8d91eee3,b99a219,a762adfd,a5e79d07,30d4b54d,a96fcda2,2187a2bc,1562d59e,24ab55ce,f9cbfbb8,570cd89,4d436343) +,S(30b40200,c728bdf7,510db9f7,a8a63792,ff70a9f8,c6262e89,4ef902b7,eb30fb8e,8c98fdbf,29f8c5c1,ce6d7d4d,61a2907,ab57b4ea,a25888b9,e8ce751d,6a19a88c) +,S(d7239e30,814ef236,5193c19e,dc91fcbc,955dab78,45b4f3ac,be994264,2a434e1a,454dc941,4500f4a0,f93f751e,1e2d4c25,8c0f10e1,b4f0c6f,3be39b0d,e5170dc9) +,S(60e511c7,7c8d7496,a3f262f6,376d3958,dfdc4645,73aa303e,a6e6672d,b1c21b36,bf86ea8b,c8a37a4e,c5ee1a60,d6e1888a,ac90530d,eadf40c5,b4f61a38,2ea1e340) +,S(55cd8f35,5a242219,3b64633c,27b1c1fb,7ffeed51,c815e1fb,ebaecfb2,3883d739,b6508643,7e53ad24,1fdf4dac,871e58f3,b5abb87a,d4920057,3c37a1c4,b2bd4b3) +,S(73cdc2fd,468a2d21,72a9e0ea,3d4a04c5,ab5fb13e,2e2ff2e0,8af5d70d,ac9bd41b,682e525d,1263abaf,f070bb47,6f754da9,f6c74d,27f319d8,5d9d2882,6d06fd04) +,S(e5f30676,3c9f620,1c5ada9f,6d01201f,97e36fc7,5bb10a12,4cf69cee,619f07fd,611f0f16,39aaac35,5e311a18,a5dd65ca,70e1a52f,452bed2b,3382ac03,dd50546b) +,S(c2c21323,b156ca78,5e53c41d,10bc235b,8e32e4c8,ee377fc2,42d089a0,d2a27d84,6b9f3faf,64331dda,d25d603c,d8f334c8,5cefcf5d,3bf640ac,96fe3bf7,71ce9cf5) +,S(599ff1d4,806aa8c8,b1440a92,9e2383bc,efd9b16d,899289a4,a335dd06,7e63d9,459cb346,7c387470,1b86aa34,c47b8214,7f48a0d2,7b9098bd,2b53d7d8,93e25316) +,S(f02ddd62,a2456e7,b4a90bca,1cb01e98,8b0a09e,62c90154,42db0f52,b635b006,a5666540,6cad4d01,aab99686,90a7ad3,b1ce936,957c317e,57bdb763,b8867583) +,S(f332b89d,1977afdc,aaf681a5,19bca58d,59852f74,78572346,b688d55a,d55a34b,988afdb1,afa1041a,51ed913d,d780b21,5dc90b8a,b5ae857d,73df2883,50ca78d4) +,S(d6fa4679,4fd4d05b,d6b7bdae,22a970f,8c3c3628,ea0d2656,55c0ebf5,2f1b3a73,d9f47018,86512ff9,9c4691a1,60b62e2,616f5c8a,fa2151cb,fd6dcd80,308ad947) +,S(2a13e09f,5c00016b,d974d62f,2c7c7ce9,e46fb142,e7334f5d,98fa2428,e26b25f7,f300cba4,26636d5f,7f8fcb2,bee6e5dd,b9697cdc,9f9c0636,b02b3fa1,820ca235) +,S(c6480cb1,c1bd41ff,e57cbf57,ea854158,36284048,e79dbb51,44a59027,13d13ba0,fee7ee1b,1652e63d,ad49736,8505b302,f135df7d,4a2f8720,74631646,244cd43b) +,S(559613e,8111c9e8,25fa96,aeaf4b2a,4019ea61,4c67446d,76305484,c9a4d7f7,cee9f4eb,2680a723,9187d407,f39390c6,4fed596c,b40f58a3,aa6c96e5,c8c9c2af) +,S(3a95b2b1,e6d19b19,84dcd59,501c33c2,4ca50b59,d410d99d,b9b6da4d,b1dc85ec,7a802198,a5c61542,81669bc0,640a8f40,6815d25,3bf8090,3ed894be,a1b09c72) +,S(5ae541d,b816522a,5d347339,713e92f5,25a637dc,75c9d9b1,5d834f2d,b265c2,e98a115e,f76b2102,7953f65f,cbbfd29b,a79b43ff,8cd6813a,b65174d2,b03027f7) +,S(88b5506a,72d681bc,d34eb118,3d6a7fc3,77e7f496,6d4c65da,bfa60a18,210ec487,c29638a6,ad91272b,3525ab40,1ebcd1ce,ecebab3e,b506cfec,e7e9df0c,6ee40501) +,S(2942de16,93ce8b88,e7e45657,daf88b2a,2118fb7c,9d2296ed,a1725ec2,f7d408a5,778f43,8b4f088e,fb99cb1,819fe6e7,55b0641,8d8679c9,d684faa5,16970f5) +,S(25c22037,e5a46e15,4adfcc47,480a088f,fb53410c,dea814f8,a4f2c387,df2afd0a,45cfaef5,5c5d3742,3380be3c,c38e6785,c85a90be,7cc92fa7,a390bca6,d3e7b3c1) +,S(b1f78a73,d0b935c9,80cd8ab3,b8237e3a,df5a40bd,5f875f7f,bcb13bfb,cc45839a,466141e5,d465c35e,37f80e57,c4923c84,c3a3ba98,549cc8f2,db6e0dde,915293b2) +,S(39405322,a57a4846,d8b42bb2,58f851cb,5570295d,71ded6cf,b803852a,8b4d8304,c81047d5,92fab5a8,c6139ffe,6887d966,e809d2bb,ee3a10b4,5adc5587,ffb302b3) +,S(7faa8352,31e2c6d5,b331ada,5e175954,6142b131,5347196f,bbc5759b,dd6add0,8779b0c9,2c176b72,5355bfb5,ccf5f739,5fc82ae9,48896a38,1be85e58,c48d154d) +,S(b786c145,61fe4677,54e14766,56d33daf,adddce8,e86e09db,ea93f1a,2ff0c3c0,4c5c35f5,99bb9637,75b4d61c,b30da8ad,a4e83a56,2cf7d2a1,fc22f06a,fff92aa8) +,S(ea4b9a9a,b4b509da,d1e70ebf,6604d624,8b6b63d1,c905720a,648e208a,993ce4fb,f5ab8356,ce28ccb,b6f1368b,344e15dd,372d732a,d8953864,21ce415e,6f0a92c) +,S(c986010d,6339bf7d,2ae3e9a6,c977b9a,a2033a42,14a1e9b3,e700abd5,428e2491,4156f13b,a68ebc80,ad12efe2,d5a0469a,a41adc0b,1dceb765,f651b4b6,b652a85d) +,S(385b81d6,e023164a,3662209f,5d694910,22e84b5b,7034e8ea,346941b9,c04df428,9d12b15e,c1868f27,362662eb,cb3c9bc3,1626ef22,36c2d75c,65e82c75,7ff81a2d) +,S(82196a55,104624b7,6710b4b,864b738d,36ebcfec,55226aca,990474b2,58aa978a,48dbd01c,5af9b1fa,21d88b0f,f6b994a8,38d47755,5ad85171,1a4e3d0e,14ab1914) +,S(dcfbdad8,34d74f6f,9df6c143,abd6dbd4,57f954ef,6323ff77,3a19c367,8d6616c,698d3051,8f8d7ffd,b45f0bde,c32c22e,2cb97acc,a8aa0aa9,c16d8789,a128c3a2) +,S(343b04d9,babecad6,5479cf60,e43350d9,8c56f989,69eeca59,5a5e97d,89c25489,14d00978,2729ea38,a79765af,ce78ff5f,16ada59e,9d275274,e6e0778a,facc25ee) +,S(25af2270,88a6beb,7c76a80c,9e87a412,ed166a71,d65d5722,a082e57f,8ac7bb77,d01d89c7,39508a84,5ea64e03,697c2867,5b14bbc,fb484f94,a530e57a,cf19ead9) +,S(1292823c,1759fa5e,48d0724e,67c93df2,c8ce9fef,9124c5b5,8a477aa4,dd3f5e32,c481025f,ece1bed9,26ecd3e0,3cd7eddc,3cc31836,a12855d1,639a85df,7c69650e) +,S(ed92246a,5a5cb2a2,1618deb0,794ea013,20560b42,273638cf,afc901d6,2ff0bb6e,3675cd33,825e611b,8802c746,9cd82b97,b659e31e,c31ceee6,681a35d6,2d5097c) +,S(8174e89c,9b3666aa,69ed3bda,6c73c572,ff3384e9,60863f87,b7d346bf,afd553df,154d75ce,caff95ba,4b5b7b7e,9ea99dff,499a522b,f0252691,cb6b92bd,98182d0) +,S(54169816,f0440f73,1f14de95,e7ab32b6,702c0183,62794ac9,e55ad632,95c4484d,12e541c3,ee64efd3,b5b8781e,bcc5e273,3544653c,d8b55d51,fa3f887e,d8f42465) +,S(c654d2a5,e31ce452,739f9cfd,b2784d37,eb974a4,fda45fad,13a2aea2,f7fdee9,47c9d2e5,24e7391a,f645ed92,cb04a0e5,6aef0362,9b57d593,edc85b1c,686ca4b1) +,S(59724a3f,eb1a1cd3,7fd6a5c,57c3d055,28fbdf48,5102e709,7ac35912,3f9c2ed0,4df18ea4,c0de4053,6bc5a6be,2df794c3,2db2a9cc,19367473,d88829a5,8603010) +,S(d99168a1,3fbeee0b,6aec4b7b,a0060649,1c4ca151,1cadddb9,2ab3478a,325b1073,c2b0876f,528de53a,f2f695b9,b8225fe0,4660a447,c9e9bd9e,4ba5e52f,beb0ce6) +,S(769c1b07,c26b402a,9a4b60f0,5bb0b318,d20f65b4,e941f525,43a15697,5a8f876b,7880299,413ffe86,94a76f26,9acde007,6e64a753,94701bf0,84324215,debf3d69) +,S(6074f53c,ddf9467e,b9fcc4f7,ea4b18ff,777abd8,895c9eb9,71195a9d,57b1b1ac,de1aa32d,e5488e69,eae8a06c,3c89422,a26f819f,af3cd9cc,762d7fa6,1fda3094) +,S(1f9ea27f,3e9e789b,1cde3fff,94bf8046,f5399046,867a2f37,2da59221,e85c655,c47b5ce1,3d399032,89449260,7db3f7a2,52a74084,20ab1846,fa378674,1e7bf7dc) +,S(c2551e26,5d3978ce,49cee376,ac86a0ec,7ba10804,bd894019,e79f51eb,ec9830c3,23dc4415,10635bfc,2af8f85e,c4cc59de,fed9e9e4,198304f7,e57a1f42,736871b1) +,S(2ca9e4d8,3358ea8a,40bc15b7,8c06169d,ed7a5abd,47147972,45078e94,75264d20,f3324029,9fe328b7,ecd14a11,6fd82bf6,5d925532,85a176a9,b7ec892c,ebb2cd94) +,S(e0db4052,8e3eafca,1f514b26,8b673afd,277c5aa9,e2dbe85a,74478d6a,f2ec1f94,f868c782,40dd75ba,3c6809d2,d62f80f1,ab7fead3,c67a90d4,ecc242c1,687376a7) +,S(d34cd3a5,764d99f3,16a260c,9659955,fda3cd9c,cb305f73,d3aaa61,27d422f3,3f3b80ef,74bec102,2e442e69,8fd4e28e,514d3a9,5011ba18,1299793b,b760da72) +,S(588dadd0,79d2280f,37dbeb16,3e05a70f,48ec61c7,cf3e6455,f3ea312d,4ab2e075,731a5c9d,f803c2fd,b22de461,d51af493,5874b745,4ab8417a,940383b2,9404fa3d) +,S(1731c955,931905d1,ccad3bc6,133f5d9c,9fbb10c5,e800be80,643ed02d,6d7477b1,d7e89b3,1f18ac07,6c7b7380,64d2449d,2d9beac,728ffa8f,6d8a7498,d43baf1d) +,S(e2f990d7,6818c0c6,e73d066d,5644e9e9,29f495ef,507b18cc,594871a5,88e45b46,2ca12307,fb565d0,7c60b6c3,e92c9757,45777970,1733c0ad,2b299a20,8f50925) +,S(b92872d8,a146c0da,ec576be7,35a22896,5242cc61,ba37313d,31b0e5ff,21a2273d,8178dd34,e552e97,fff949e9,b101b44d,35d6b57e,79c0e78d,f91ff3f,2817daf1) +,S(b980d2e,9440c3c3,be5cf393,6eb9634e,923cbde7,bbf2a07a,d7a97287,7d6caf11,51b7d51a,8685bf75,c6d376d,441dcd69,cac67b77,762f6ad6,97a9649b,f3d3719a) +,S(db2f9a64,3c3e3706,e9b5aaa4,5ebf08f2,ee9e967c,205a49c1,7dc76b8f,b20a3a52,d05d486f,ab967e27,b9e8c175,e93df203,4657dd,750ad788,1bcc4897,b80f3d40) +,S(5d5985f8,910be82c,538d70d8,9614ec3f,bc9e1f91,9a19950b,a8fc99d9,203d92b5,3efd77d1,27e43849,a710d1e5,7b18b681,c1acb293,2244fa7a,30f360ea,88565e35) +,S(fac2a758,a063dd8b,46b41933,9c70d2ed,3807bdca,69d3b36e,6369f8b1,23200866,8294340d,6154afa2,d7b730b1,301f5ab,322bdcf8,6fb5676,78fc47cf,b15809e3) +,S(cb92092a,d45ab0b8,559846b0,d02a0c67,a13edc86,7d0cce5d,fcc09e63,d1b6cbde,d2593de2,6371136e,390bd52a,c9811334,e13fddd4,e9b86b1d,942cacf5,4615b287) +,S(d715f4a3,66a4a770,bec8abea,49ab6c7e,99e9473b,73e479c,14011843,9470c844,40aff69e,ec6da9bc,38ec119,df4482ff,3bc2b67d,31284db1,8c757990,de6cd0d6) +,S(77312617,4a395a4e,f7bad07d,f2f38843,22293a17,ebf09f20,4732e7f1,2c418417,602cca39,d6352365,420c5ce2,9d2282cc,5d8919b5,e0669b09,22384b69,7bd48a7f) +,S(a7c4b675,f529ba17,e9f1ef44,c88a8066,66131845,dd98da82,4cb04f24,518a4071,d88edc2a,1eb0cd48,57283e3,f8658d8,2da27a7c,7ec16129,78fbb484,41ef438a) +,S(6362f575,d459b970,db814a7f,9a142605,f26f577c,4357be2d,dc16793,64906f7b,fbc9f007,bd08b6ef,cd49c1f7,1e199fa5,ede01123,5d9b015d,515bf7a9,7192f8c2) +,S(6cfc45f8,515813d5,dacdcbd4,c34c155d,c66b0298,8b8a8702,73a5342a,9249b623,f85c980e,394ea0b6,39bdc5a5,ed185de1,7b1f44cf,b7e51c7b,b9f56b3,496b5ee) +,S(d76c0b83,b8a8a8bc,4e8985da,f6f1535b,9ff3b4fe,e13eed4b,39d6426c,87cec8f6,15ddc103,bc6c4f43,6f7e23a4,78e47166,e3f4156b,5ad2d581,7f3a7ade,7d80dcae) +,S(c4f98324,57330d12,e4e26735,464f24a9,a93dcf75,9194fcd8,a2d12ce2,bce0449,e24a6f24,f9a09aa6,f58f29aa,f4e24a0f,864410cd,80280432,d82cd9a4,ea2ac2b9) +,S(e86da865,238fcc7e,d8c2721f,89c2619f,a2caccd8,5e05a21d,8d23a095,634cc439,85b35268,31871eb4,3323caec,13de6de7,94ddc6e7,5d44835b,7443137d,25ee2194) +,S(a6398918,6969469a,939e774,eabbce54,109b833e,b3dfb566,876cf50e,bdc7613a,c48430c3,fa8c730b,dccb53,451b5a38,888f2e85,1f510ca7,64360c9c,b72b6eb7) +,S(6986ef9e,88c8dae7,ecc8184e,a4c5d131,32a87ad2,ff8367ee,63fa0ecd,b7a2972e,e9acba9a,896e1eb5,bc1d2625,983fd2c4,13f54b47,3056a893,7197f940,92eb4bf0) +,S(47bf849a,e428bdde,ceb221ab,e0ea2fd8,c0a5bd39,175aab96,c2fddc57,e809527d,401a7ba5,1999aead,4dfa6ce0,fbad17e8,e7187e52,806a58a6,7033f653,67aa7c02) +,S(c0c02bb0,92af6a5b,73582a14,89067933,8b31318a,f2d5b142,d58833b4,cf07fbe4,a19dff69,5ead3a33,d8f9f7a6,76b8287f,4bf6b23c,6761b084,12d86508,830f8990) +,S(f2185913,405156ab,22baf16e,644063da,b3ba25ab,f191efee,1ff028e2,f7d175e0,814c64f9,9a4250be,2265cf8e,47c8276b,9e5245cf,16ec98b6,b789dd26,be894f3d) +,S(40d840cd,ac4060f6,de850df7,c37462b9,b4d5892f,a1e74f35,89ab3955,a5d941f8,9892b0dc,ff43a872,6974705e,3a3fd077,c2b91a2c,1c6ee153,7b728359,d3217833) +,S(6f6b79e7,9006fe48,5546c3e8,52a33dd1,cfb63f3,96b44d1b,af1fb112,93271b35,f5aa0beb,50a628b7,b5348817,8344527e,d1ecf0ff,a0766a78,faea2361,e8fde7eb) +,S(4edf60c8,c0488128,29e7bac8,7b03ce49,c8df0f1e,6a3e02e2,ea8ad097,f66163d7,9861393e,fcec430c,c00ccd49,3d4e2d2a,a45e1034,fd9a81e4,b015bd5d,56f16dea) +,S(7ab0c44f,f6a444c4,e0feb1c5,a6650c37,26249caa,38f53e62,b6bf225d,bb1e008,e7f9af86,a2839ce0,80c6ee9b,d86529eb,7a7abaed,aa6aa4e7,207e67e1,a500e5f0) +,S(6a90e50d,3dd2f382,1dde8714,57012b3,5c1103b5,80ee4982,f9bb78d4,2541f8b1,5ccd34c1,8455aa76,4cfe6c9d,61507ca3,cb613bf1,4b9eae3f,8391e1a0,9dec03f1) +,S(289d4d81,cccf40af,a61ef56c,242ef8a2,c9883267,54139e1,dbf018ad,5d251df8,f3fead19,c49de6b4,32869220,7e60408e,dcdfad25,26e6e555,9b022941,592081cc) +,S(a1ee466b,c561919,2e82a316,ac3b7514,b109f442,1c93fbeb,234f5862,d37ade3c,db12d4b7,246e8ee5,55dde2b4,9b5c42e7,408eff9c,a853af00,5a6f6c7,73aff21c) +,S(ab30a856,403a1622,14be9837,2ebaa8cf,8d946074,abfddf2b,8e65e2aa,51554329,7a6b7f22,a6ea52be,8c0c8002,29613020,a247c026,86eaf960,7fc56cb7,d696c56f) +,S(17c5f1b8,8e3e4e08,dab8a5c9,2a679c05,688a7437,df6336e8,7b0d22d5,ed56e5b1,96068e6c,72fa9b39,5993913b,305caf70,3186404e,17131b5a,24e14273,a83dccc9) +,S(a76fbdb4,b99e31ba,c434462a,64c0557,8e961a53,dacb9bd7,68400b8a,823190ec,52e31883,5ac1a3fa,e269a4d3,17bab065,7e890844,c3fe96c6,d04fa015,89c89f14) +,S(17b8bb76,10476261,ebd75e4f,299f1805,5c88f36d,ae65cc57,3c959820,25bb794d,1bd9a52e,585a40d2,67db59c6,b9b1bc59,4b8d5344,29b5d4b0,82bb1c9b,b54e0392) +,S(65aa92ba,8fa51cbb,3954b93d,68cfdfa4,d64d97c0,9e099b1b,d1ba853f,18500b37,a2b12d21,b7a1ffd1,af48e4fc,e80c6fc2,e624783c,7b0cdce7,9f01ae7a,5fc96e14) +,S(3450bcca,5d3b30b0,3743f0d2,6b61ea09,de6ef7cf,eed44b3a,c58641ab,93ad7867,4fca3307,5328a298,d310d447,4806f297,3b09d885,9fa3b949,11817d8,39be66ad) +,S(484bf072,134849c7,695ba73e,5f25a8bf,74a183f2,bfe35ad7,34b53878,a2036be4,a5295452,a0830b3e,3c45043,43fe950b,3289d402,73d3bd49,6c0cd7c9,156a1d6a) +,S(2cdf1bc8,920ec641,63fbc8fc,c72fe5c2,dfcb87ec,15725e04,163e1ac5,1b7ec763,c680476a,28f054a9,ac3a073d,67ceecf1,c8262ed,4bc462bc,44798e88,d0e48e54) +,S(59c3c60,8031a214,d3e6be15,c644265c,b6f3526c,2b37d840,86532c24,52359bf9,2248b28e,922e0468,fd98856a,41ca37ec,2fc7bcf9,a13c7a9d,b4135e28,5cdc1bf5) +,S(4f20493a,a7a1e558,a44e54e3,b81c889c,d45b6384,9b8448d4,20a34a31,c7c451ef,bc1adcc0,d00384e7,93c2433a,a76f1f08,b8b23170,6e285d56,3155dc19,d5aaaf1) +,S(bed9949f,dec9813,5bcf76b4,83117fca,57525221,8a6a52c6,a44f2468,29d48ff3,6ab35499,8cad07f6,250dec89,a0840192,b62777df,6e241a4e,325b0c4c,bdad23ba) +,S(1cf32b2c,46deaef6,fbc892ae,4f05653a,3cb69d0d,821a7125,3c2eed77,4e75f767,caa6268b,b8574b47,840b3626,74f4a479,5a2c6478,c440aa4c,36d88a2d,ebacc8f6) +,S(9d3f7c5e,5e0947cb,d9bef5a2,dc1a3e9e,ac22d6a5,9071d0eb,5f270100,3e66dc96,6ad63f62,22f3a787,9544c330,4c3ff653,2a00a764,5ddce01e,c4ac4933,a5c7aedf) +,S(a5a927a3,f03dcbc,b3d069ec,156a6ba3,474f48cd,4828f54c,a673e10d,265eab6c,b5e360fb,39f65847,b63eb29c,a8b403d3,272d9ef1,8127d3f3,7650d13a,9a5736c4) +,S(48de778b,7bf72a21,871ea379,c02b8887,5da9688,37faeaa9,93e68eea,926db673,d25cb808,7a7c13b,fbe8b1d5,522ac2db,6c44526c,13ca0327,586d6a5c,1aaca91a) +,S(a029831,66e7cb1a,fff65515,48faf447,cee8ab2c,d4937269,db002cbe,b8f1d1ef,ef34ec5,42554e97,1ae8897,b049097e,3430c99,d8e93c50,94377c07,a5619ea) +,S(6ed75b96,c4e976cf,75cf0b72,df83c043,5b15d2c3,f8fb319a,94a4d97f,1394df6f,9b63c36c,1e31becb,e1a5a6e2,1abb99d0,d5c39694,cec00fd0,ffc27b53,309bf6eb) +,S(9372c1d1,6997f792,688a55f0,8f246cb0,f206ce31,d0f416c0,c81cbdd6,8487aa5f,ff97433b,be60eaf6,6f19c182,e8a8bbbf,b24cdcb3,7aabf79d,5dac9f13,9c5033b4) +,S(269c7d84,b42f90b2,f39b4db7,5ea0724f,fa6a1a5,4c66a1bd,a21e4254,6f243bf6,8f6f8b36,e278c6fc,bb0c9918,7325f1b9,75ec3add,69708be1,b4703c5d,53d8f8f5) +,S(62f9cd79,921ec46c,d470a12a,9619ad4e,3bed051c,14f47071,e55f9da7,d103793c,92211db,6c846f43,2867b9ee,3b1ff00a,a08f179c,13aa7475,d64d0731,23a69e4a) +,S(fa432dcd,e7e3b40d,a127d65a,e0955d58,a009d81b,46b48745,c4e24597,4e589a8e,a8dee557,cae7e50,d96555ce,c56255b7,c64d10b7,6639b3bf,8d60aea7,58716f68) +,S(a424d18d,c6861074,40f42e5e,f2bfc95,f4c8f94f,e3adf681,79086502,fd9d80a4,cb30797e,1d973012,d488f54,6033b1b3,d6b50c8a,39badf8,fcc12bfb,3a1c4d0f) +,S(c2a6369e,e2857d2e,fce4ab31,49556c08,3ac6af90,6be418e5,ddc5677c,f2f7ec8d,a7097ae2,9fea3774,11ce3f81,b6b3356c,9a2abb69,986ad81f,46b13f8e,a0e7f0a1) +,S(f5eac1a2,3dc91862,d8022931,3be5c7a5,364c0880,23c0650e,53e22f42,2f91ec98,7dd62b80,3ad606c3,3d8d9bd6,cb397ab8,1cbd688f,8375a405,23bb7315,a3f48c24) +,S(dd94fec9,3bf7ec6f,cfa0ced9,df31a1c,131c39d7,e110b5e7,b988c59c,dd594fec,cb858565,6a32e03e,2eb84732,4bdfe2e6,3601148f,7bc7e56d,22cf9aa4,54f063f4) +,S(d3dfdaab,8f9db2d8,edd3db27,d96be5d0,678e9088,5448222c,5b3171da,38fbd501,6b210554,df32021f,35170e13,42e2da18,72be61e9,481a4b74,ec470ed0,b942025c) +,S(47ff9918,3e452838,f63eb828,a239d95b,62f8a746,8acd0b43,6c149985,2afbe3f9,33b7b8a3,a5b51b15,fadc1f9,baec6b8a,88e0da56,5a54bea6,1b2d728f,eabbdc48) +,S(1e99e92b,aae56401,1cc10c94,dac071a9,27565a17,2d6d4a20,224e1b49,c007660,914b98dd,a92484e5,a43d7de4,7bbf57cb,2346d852,f743fdd9,15dcedca,4393aa21) +,S(e150364e,d95ca778,70fb3367,64f9f417,70bb672f,7e794416,13678dd3,65d84fc8,23ddee4,30d7b565,cf545837,58df61fc,502bf86b,a4cbc1cb,7630a9bf,e339ab85) +,S(44dbe753,dd822ae3,f3ef4939,a1d96a98,33e697f8,c4979191,c64114f6,71e8fbb8,b909bdb1,e6e55571,b03517a3,c2345b49,a5793d21,15fac018,2afbefe9,c726c8d5) +,S(fb843458,725d557d,b1a17ad0,427b4d98,6ba189e5,d6da81a8,81867259,6d9d2858,18f1c9ea,bd8e71cc,72e2dcbc,532b101,c7381475,46c24790,d010a6cc,32d4eb10) +,S(48f43c41,b63bbb05,57f8d71,edc739a9,57baed23,efe9c814,848c54e8,54159144,cb75c418,d5557cfd,b29d4807,3f193343,6eafc209,bdf9685a,72f57b98,6676b193) +,S(5520f175,9be037bd,cb5af2a9,a0bdbcc4,9e1531c0,32fd17a4,66f59b38,6d7de1b7,45b933b4,cf256aa3,c6513a2,8a4eff90,7691a34d,e6cc2e7b,a0b83f8e,a7ed4e52) +,S(83936718,1d7d065d,5c15e246,ce8391a4,bec58c71,7f82419a,ed6547c,63f081a9,4c903568,f5ce9a54,65fa845f,985f24d7,6e66cbe,3ce256fc,1703b4b0,5dd636c3) +,S(66a82c47,e756062f,6586ece,86911ac2,23b84c9a,e53e5307,4e22bfbd,3eae6b30,ab2051c,4c231a40,c6da6ac3,5ee32b9,b7eeea17,222cb1d5,a3abf9b6,512db8ec) +,S(974ce35a,9d5a4ef5,84d252dc,3c365423,1335c52a,e3daefa2,8ff9b75,56bf3b46,8c82a9a9,c49d167,4f3995c2,90ae06ac,fa0a5c14,b1c5f41e,c1e449d9,5effb2c0) +,S(1139c2f3,60cb8a4c,e020bb8c,3d19bce2,1c6802e8,5fb3df33,8fc9ffbc,8fc231b6,59adaa14,7980b3e4,73801b73,9f1e0248,2e9f1e17,65df2ec0,183d9f81,d57723d6) +,S(c1bd3793,3b03d95a,b17c10bf,c5167556,4294e38c,740fa3ef,9b356be6,71883b94,c68bd82f,5e926a59,95a83f1f,1a8c2f4,5966b073,91ee74a5,ae2ed99,106c6dca) +,S(c7778ce7,ce668003,86db9263,cddcf608,aff769e4,b4755858,20554ecc,8407bbf2,92509200,9c57f224,8f9b4e71,532c698c,88b91b77,4a3907ae,1ef30c51,78d807c3) +,S(14aa1177,51626b67,8f32418f,1855cc34,52d4ec13,d2d900d8,8a22432c,70ec022b,6151fdf4,f4372a2f,e803478c,da340678,c18a0a7c,d540b0bb,4168f9da,2edd6d81) +,S(a53443b1,b6065cb6,abb18c84,1f171b3c,7152b34,293a7ad1,2e8599fd,f1398cd6,3a07e076,35254aaf,eb30efea,328e3ffc,3a7d280d,5cb2c8ae,9e70b412,38fe704d) +,S(35c3e3ab,ba4c946b,1eafff67,a9831588,d6631e18,9507eca7,66e22449,f8d294fa,94973920,58f6830a,4e5f413e,4d7d442c,4348328a,5115fdc6,ae5ab638,339e313e) +,S(1aabc2db,5ac6df10,1d097db6,26e3623b,295ae6c9,941e3717,ca849065,512a7fa,2d2781c7,b42ce42f,b40b737e,9100ea24,ecfdf58,fd724244,dd67d84f,4a6cb097) +,S(383103b5,5a4beefc,89dd082e,f0e14211,9bacc5fe,8acde710,7429241e,f16820ca,2000fe09,2b820a28,f065924,7823d6b5,18756044,1856dc46,a9fca8c3,84913398) +,S(2cb0f0b6,35022212,88b8be63,a0ed5d71,bc6b89ca,4b2fb4f8,54123124,49445107,9a9eacc7,cea4c27f,ac63a2be,96884112,435d5f6a,bf4ad519,461017c6,1c87b2a4) +,S(ae63a05f,306e6980,f439afe1,b34c7b3c,1453e110,e477e3a8,d7e9ad3e,fe2af088,6facce76,d579afb1,cded78a4,1dc64c79,b6e90279,d8c5f07b,fc2b0a3c,7243b309) +,S(83207533,78d5c6ee,ae26aee8,4f2a0833,a65a94ef,53a477b3,c8708ac0,35dbc24b,d8306300,4caf8d6,7fdcd09b,267a2d5c,b0e83e97,60fc4d8d,2b07e2bb,c2b387e5) +,S(f38888f9,3337633c,9873d501,8b9fbfc2,ad135870,89f6becb,528ea063,a817af28,8beb556d,8e5342f0,6fe06215,891e6091,f8b940fd,b6eebc08,ded95ea0,99985ecd) +,S(c15cc888,7d13a93e,c2411ea1,6f21e86e,4fabe47a,55a94a6c,aff7681e,d47ba1a4,5bcf5b68,91f3e01a,3754fed3,f70e5052,e33fb62a,753c5f3a,532112e7,f7f58f55) +,S(9b3b0b21,1befb305,b02d035a,1e7cad04,3b8ce04,f9315bd6,5067a73,f2680030,75828df7,eeec11f2,e0dab801,5c75213d,cd93cc84,7e873e19,b7d03eab,e368f989) +,S(2028eed7,50cc8973,c1ca2f28,a30c05c7,73e2a05a,db916825,60d41cea,3b4d0a18,40efea34,b941571e,98a0878f,a13c4efe,1e3410d8,d5166661,115cfd55,53bd0d71) +,S(ca697e9f,8954a7cf,593068b9,1078486b,c8c9a71c,d1f7a890,a0a3e0ec,e48521e0,4268dc9,28ef996b,56af66b4,2f410831,b9f8c6a0,2658d706,975a7624,6468322c) +,S(26c2615c,ebe251a8,a78b00d8,1733aa70,f8f9a97f,85c2fcb5,d9287e34,b786d4d3,ecd17c3b,e1b3232e,bde8f859,39f5158e,f8c340ef,cec4e758,cd54eb7b,df4df77f) +,S(7296b5f2,c4ac6a83,c180cc55,2fc79a84,691c50df,8e56ca8c,731ac368,2d8737f,d4410073,1f98235e,cd75e26f,d251bf8f,f93ee806,52446208,c9643fc1,1b938aaa) +,S(465d9610,c3f6c8e7,366ff5e3,9e1e17be,53ab9eb9,f299be2d,3d9dfe6f,fc601a5e,741cfef2,cd41ca9,4b847ad6,93f29e2c,7e0bef4e,6244dfd9,8e3bcbeb,8c3ae7c) +,S(d3264c87,fe435796,b4d40631,a0a64a34,570e36a9,809d98a3,7ffec23d,9f3775e4,e6fa5190,b66bd281,538787c7,40bdaad6,f37a1eb3,90b19c3d,cbc65b19,9bad22ad) +,S(d925ed62,5551d49d,151dd55b,2cde29d8,fa5dfa21,e9454c17,a834f090,7d744640,e398cb93,1c9fc1ea,d9912968,b335015d,162a04fd,c17049da,80a7ad4a,b3b21451) +,S(2f8339f7,72cc9ff5,c59ace6f,d38a13d8,21562e0,a0d5dc2b,a2c074a4,f697413f,d09d6be4,3678836c,e110e805,68a2fbb0,b87d1657,d568d7d0,e4ba1237,dbb4fa4a) +,S(f954909d,f67de727,72437ad4,d3229c50,8440d23a,9215394d,d09c7232,fa5cd0a3,6656c1b9,8e726305,644994b1,eed6234a,834f74d9,2fe16ec2,c945478e,ec53fafe) +,S(962b9348,d9b64aec,7ae38297,e80a5f80,ee1ea253,6964742,99c5196f,cd58f33e,10601c5,87838f02,5b6735c1,b711141d,ed04ed16,2fdc5bb,4dc593fe,9b804145) +,S(b70436c8,4c6e25a5,34c3c2c3,34f13350,7050b552,72a04032,84a744a8,6336efd7,1b9911f4,72a19b13,e8bad704,ad3fc911,3223a5ae,4939138f,86422536,da1009d2) +,S(8989063e,49605ac9,78705f40,cb916505,615cc465,40c4760c,db302cc7,a9e4c6a,e76c05d8,5b32b5f1,9913472a,be4322e9,ff5149e6,e224da9d,dde930c9,948ce8ca) +,S(9e2c1711,29d01e44,25e4d5a,802f4c5,84eaa0a2,2aa8fe0b,bc0aecc3,15fb00ae,b1385087,ff34618a,d126ce7c,dac3a7f5,1f0fec09,2a7a9601,b65c2786,c733fe81) +,S(3a88a3cc,164795e9,cc668d88,d9ffb6d3,52f90edd,c6b0aa5f,dba493e7,273731f7,95f0b3f8,2fc2c9c8,a25b337e,af92ca08,e17ef68,ae5abcd1,43bbf5ce,d68a1fd) +,S(f5cc5ffc,ad18ea3b,c15ed2e7,d0ee8e9a,141bcd7f,8e6fbe1f,81be287e,e7281725,ec049ad7,6ae3bc58,9a60bb7c,ae79dea4,b512fe66,bd812ec6,91fb3182,27d9a288) +,S(c8af958a,201a29a,bf880688,89c211c6,da59b59f,ffcc02db,9010bd6,65b7ccd7,3755194c,76d6e0a9,3f2424fa,f26a512d,f0605393,ecb5216e,d5f1d452,99b247f0) +,S(16f10ca2,a11493a1,361c80df,40066683,93c02635,78f11f2e,d9153dd5,5d6019d7,b9fbc23c,39323b8f,6fcfbfbc,b1a4b81f,e7eb1bb7,2855f46f,5379c68a,dc4680dc) +,S(1b218d55,81d012c,5e804030,ed342308,29675ecb,e1608d75,1ac1fb26,434744dc,8ac73d03,b888545d,dd8d0321,afe66cdb,e8dd7c6d,f1fbc3d,74f7ca46,c551f357) +,S(d16f309a,820828d5,e2d30f78,2f055428,fc8e7bb9,dcedf9c6,34640c19,7562685c,1f27768f,9a2c63f1,cda9f0f4,132f41ba,dd48a03e,5e387abc,d6c73a51,2d1b23f6) +,S(75c161ae,1b38e93e,b623305,e2566957,a277e515,44c2fe13,e02ccb8c,c72886bf,384bd613,39e4e389,5cddf7e5,b0cce8d5,35c03c29,118624c7,32b75a23,a9befea6) +,S(3327a22a,c4891ceb,2a704a19,e60d04fc,64cbb0d1,dbd5a1c7,bcb2f4b9,8a1d0d2e,1ef62067,d81d66,8a7960ea,a63832eb,5c6fe33d,3ed99147,b7f68eec,cf81551d) +,S(8c9fcb52,65eb08d2,90cc1f6c,9c3d70f0,2b553119,2a0c96c5,f59231ed,370c4036,c986a64d,f3972c00,5618cae9,4a84e74f,2566fe4f,aaa0e2b4,d3f52e9b,4acee6bb) +,S(2465bc60,19bab7e0,72bfeefd,9d974124,19bf47c3,24477dd6,c83ea3a9,e9a3f353,675034ba,c62cc0f3,afbf5027,23127859,280e2b2b,91aab521,9b48a36a,d5bcf77f) +,S(3eaaad77,af1f4e6d,a267bce9,e7095672,c44deecc,a71ec3b8,c86d8774,ad06805f,8a3277fa,6247ad67,e6aab22f,a7e7375c,b95eea16,a055ca8b,32615122,30033ff7) +,S(21734e43,c3ab4ef3,55d36330,adc76a02,7fef2658,92c29ea1,a26972fe,48c3528c,e1d82d68,612ba50f,cba70f17,3cfc17a5,d2d380c8,d62322d9,e6e93d3e,475ea6cd) +,S(d21f30a1,19f86a54,2c7d74ba,20796cbf,dc6644fa,2327392b,3aaf9f9f,ada97235,22d5e9ae,2940960f,6722d2bb,c077d9ac,aa12b5f8,b9a404a,e28224d5,5b604f6b) +,S(41741846,c3c6355b,69e39c98,fcedb9b0,73a5b526,75ef5388,819fbf5f,ce1d00aa,3978dffd,d11f4f53,ae1f5aa6,a04153d1,e9ad984d,8feffa10,9ab57fe3,f58145f7) +,S(cca0a89e,6612524b,a9c318a6,879ef971,d346e29a,4cca7c2b,4619a1a3,1f567163,8ed2e1b3,587cb5cf,37e18db,e9a95ca5,17795137,a8215cd5,293aefd4,92b74dd9) +,S(dd3be3cf,83feca12,c3dbd1af,a9166d2f,138efa4a,297c742b,778da203,dfff3728,b0a156d2,93dc289b,94abc958,f17cbdf5,94f04cba,15b71ed0,197e239,8b56976c) +,S(6c535f98,868e9ec3,31135e87,b80aae3b,a0609455,8d426bdd,3dd400e0,344a3cd2,30bb8bb3,4ccc439f,c343d3cd,ceabc511,3efd9087,d17004fc,37f70d98,94e3c04a) +,S(338bec98,1bbaacd8,8b82a53d,d1ec2ea8,aaf7fcfc,e5f502c0,a13b95b1,d5fd9000,dcda1b41,ca43c103,f0c6b294,5f9e94be,be971eb3,12f18197,b4dc795b,1efe13d3) +,S(b70accd5,24961804,40dbb087,c3c11f33,f27c7e9,886aed80,b89b121e,8d51ada9,6272d04b,3ec35419,be43ecf,72824127,ae4fd87b,640a5a4d,8e8ea05b,5f3f9b6b) +,S(dbf05f1e,b489594a,146de62e,c9423699,a7aa2d19,93919b0a,2a26b53a,a0f1a033,9608352e,a1abfc2f,47c42ed3,8f1d2ee4,bb28ce2,9dc98325,eb137acc,36924d65) +,S(56e94226,a4237f18,c57b5ffc,cfe795cc,b11522e1,fc47d549,6dfad2a7,2f109783,f137a96c,7965b8d3,2eaadbce,d86abe0c,5ee79de0,9b94bf60,8d72a4d8,8cafb542) +,S(c206cc19,28af717e,63e6e7be,781ea37e,d7dd1766,f1553fa3,2acc34ea,c1157bfe,78963ba6,f03b670d,602fdb93,d71dafc5,bb5ec7,b541b9e3,a84d42ac,1a444e29) +,S(8b579cc3,6455002c,372bf1c3,21012fbc,c29e102a,9acb149c,93c651ef,e3dee157,9fa8c521,e2f911c5,3438015f,48134dfd,66fa5acd,8916902,c1aadb94,7ceab096) +,S(3ddca5bc,e582f08f,ded36cce,395f4672,9fbfe7a2,c9aa3479,7fd2e332,352daca8,d77a9165,e281ae70,f1e9a265,630acb60,bcb79f30,9cd926b3,550b6c9b,644e5e6f) +,S(ee7c92d3,d81c3d1c,6384c771,b609de3e,e4979ce8,84df6312,fff84a0a,bd5e662,f131dacc,28415d22,729f2b70,934ef8e,3033b7b,c5a38dd9,1a11e4b1,7843978d) +,S(b9f80abf,ab86d596,521bf2d9,cf500e15,adedade8,b51fd8fe,c1d8de53,f4191222,82548186,bb97991f,1f28a93,804cd0a6,378355b,f7c7ed41,4cd585ed,af0afdab) +,S(1ab67bc1,50fcd943,f0b3419f,e5de2969,fb4428a0,b90981d1,a3893c6,18aeeae9,56fb8eb4,4671006a,805e161e,6e3f2bb6,b0199659,667967cd,3c72ba65,97a2c39c) +,S(17425974,39a91dd3,72c09b53,68d9821b,2acba5bf,a5440118,ddb5c494,fa0a807c,1b73d3d8,5eaad3c9,b37f7451,2a7ddd17,97e10e71,b640a820,181757a7,6cd27cba) +,S(72b080f4,d8e812fe,b485361b,59213f59,cd708e6f,d2f7ee71,27af3d87,971633a9,5b9c6a0f,d7a6f32e,f26a4584,542c15fd,e3504935,baa7b48a,d67848b9,67229f32) +,S(94e5f999,b8927b65,a2f4d318,8e3f2fee,229e42b9,ae3e6b46,9f7ea373,d3f11beb,aa27336,204738d3,b2a306d0,4c6efad0,2ae3a431,1da988f2,c6c1decd,b1fb3c92) +,S(2f59f652,2f045980,833c45cf,ef8f3a37,d65ed946,9b3beaac,2167eff8,142e8a03,9101d9d0,60f1a770,9f604eae,4b4243c4,6096c041,2f861106,dc4b8d1a,d9f9b170) +,S(95a443a7,22a88b70,32194130,a349a952,67b89786,e33938c9,7bef7fdb,d211b54d,3d80619,399c0975,a67ea7b8,9a5f6427,ac454278,42f54932,cbf71711,3ae460e7) +,S(c8430fa0,2ce95d35,96eef42c,69f68502,100a29c3,6ddd1f46,daca1e14,4f382d0c,f26c4baa,4a6d9711,e6de2b92,5042c6e3,cadfe60b,93d4f385,d759ec72,5a32bc21) +,S(67504cc3,ffaedcd0,c5a2704f,af1aa41b,4cf489d3,5c23b6d1,4529f4f5,c49afa03,b3858859,b3749792,4d01676c,d96fc03b,37be7b82,aee57e64,a44ba433,2fd936c0) +,S(d4fd8a19,6a56052f,71e8d51,ee3db667,7465ea90,f8449939,be9d1814,86fdb56f,7fc64dee,2bf744a5,ba155865,fb722e11,f3087010,b566182e,8a39f718,922953dc) +,S(12810eca,7f3087,944d3dd2,69baabcd,491113de,99b36ed0,65520569,484fa7ad,f25d02ff,81ed030f,1e67e002,6680a3df,3f27edd7,76155966,6f043f85,f82c9e4a) +,S(b347e0a4,102d2954,cf3ebf6b,7c0e5f88,6a823cb4,c134897e,3169b081,8bd35f4,78494910,3eaf28be,b2d9732,f88dc9a4,66a8b5fd,cc50a2b2,8b347436,2e05cc93) +,S(54cf5638,7972ba75,48dcd07f,1bcc47eb,5d99c95c,a18de15e,9d2ac40f,1435b27,48558294,410d7ed9,9fb008c2,32cc6ae5,33bffa9f,3f02f0a,76b1f390,9e78e507) +,S(e75c0831,ab9569f6,4844f67c,3650f691,e1f84366,46a28613,653c354a,3107cdb,5e2da0f6,83cf019a,82e44f84,e7bde49c,5d477f34,fcbfc3dc,2a9a2a4e,3ead0a1a) +,S(f9eb5462,7d88b64,5899b177,99257d92,4570b3fa,59fca83e,1e302f38,5c524693,dd187873,9fe69020,970609f8,ca1ff56c,3aeac075,43e6cc5b,bcf75af0,2932d516) +,S(8890093c,5bbdd22d,69c91acc,5608e19b,59d2b105,b75e054c,8e873b88,59865997,1f18b0bd,e9b546a,9a2955ad,492290c1,a041b61c,7b534e1a,bcd4db3,b5148bee) +,S(76b95d04,88c9bb7d,2cb28589,f7f3f9a,e2ae24a8,33adf557,76bc3132,4bb80168,590b3022,81649af7,bb2cb0cf,fa0e90ee,13b97294,1a7a8748,bc9ce53,88744e53) +,S(8b3526c5,afd2a987,f8a04949,bb5695da,8b073b93,d8418878,28f9d49,2a6ff4f7,387954e7,60f2ce55,17213bf9,c987a9e7,f9b9b05e,c4677911,22e7a28e,777ab4f4) +,S(2aaaa06e,244684c2,571785e,a77a76f4,2c4bca21,14fb290,ef66d150,74ff2658,49e3135a,3e8ed289,4dcf61d5,7e4cce47,815ecfe2,5bb1d8a,a5d067a7,924fcab4) +,S(981b94b,be061268,c02db0f1,fbc330b7,351d6229,b645e4d4,3d908be4,241795af,c294f8d0,7b6c70e1,c18ce6da,b3d28c4,d53f3e9d,1f8d9ba9,de18cd39,51c8ff5a) +,S(53721e95,737d09b1,49eb185a,1663999d,23429e88,51ab849,a671c0,d86efa3f,d36f27f1,9f812f8c,c9d770a4,1655ef57,efc1f126,ecfea4ac,dd5bd42b,13e20a54) +,S(9ab129e9,a4d92118,3ebf686d,97286d1c,9608003e,67b026ee,d3d06a8a,e21c0bcf,4683a375,85be92d3,331732b7,8e12f452,480a9569,4c309907,2bbb9427,602ab016) +,S(330ed8c3,3c3647e,7b80f38,f3a1865b,d33abc8,ecd4d0d3,390e8ab1,a20d1c0c,5e3db6e9,33d6d0d9,43cb4202,f9ed135d,ced588f,8742556c,2012989e,768dc770) +,S(66c40c78,6933308b,9397f3c0,3c4263f0,357d0f8,a6a9eb06,725c4c15,c226d57a,697777c7,13cf3b5a,ca964377,fb124f87,81743794,afbb1966,4b126a86,9f90bb6b) +,S(36ce2c7a,9c7f1267,c081c9b4,296a191b,951415eb,12e95b02,e5f5d3da,47809b23,ffad6d8a,e00096f3,878f54df,5cf714b9,6646b5f0,9cce0d06,ea38c558,140223e) +,S(73fefc2e,ca71a95d,2e9d5d0d,464a7408,e38e21e,4450ce8c,51ec9d6d,79b43f52,cd47ba4d,6c2ed98a,c369ccf1,a3d65e05,758f7f70,1ca87a02,5baab12f,5b765a20) +,S(cac2c00,567cd06b,d4e98e04,e911f7b8,7d4fcc19,28a5b58c,635fcb96,bc7c0a8f,fde04dd0,3235a3c8,9b304c97,7889506a,c3ef937a,e1dfce4d,ce29a1cd,dd385090) +,S(f6eb390,2654aad1,1c69c028,2d1449a3,4198e774,3d329c3e,85a8af7d,f6219e1,6403deda,8911378f,7defebc1,ef7a4ee6,20802e76,499993e,15b22e42,3e492d0c) +,S(91a7da19,ecc1a979,7d5dd222,edd74bd5,af76d200,30cc27bc,41304ef4,578d8773,a32b1a26,e77631f9,6a3dfe17,ddf16ef2,f38f4026,4d3fb882,dfb34cf1,5fee2f1f) +,S(90c3942a,7b00bc3f,7b852097,ed4590af,cef6fbe,783fd717,9fdc4955,a4fed12a,aa7d174a,8d9f1292,b8e4d9d0,19dd336e,da305ccc,ab69659f,90011b69,85366751) +,S(717c0973,ee959e19,6d11939c,acabeb83,607f9367,83dbfe6b,911f30a3,c51af3a4,f93d840e,88497801,223992dc,24dc976e,dc0b442f,2f845650,4903c9d8,338c1ce2) +,S(831f9794,c88cc5b2,2d202130,3731371d,a0ab67f3,c080cfa4,d958e6db,aa85d140,46ed65d2,1c8b5565,14e83074,e84267d8,43f47154,8774533d,cc11e6aa,cc655895) +,S(f6c7e9f6,69447c19,843ff209,72c47cf9,5341e0f9,d2d5f14e,c9b17abe,20eacdab,1bc7e847,a9f2824b,5895edf,cde746d4,5ef0fb67,b7db1637,e62d2d40,e046650f) +,S(c0ce97e7,ccec223f,947c0db2,62fe3865,9e06fc77,99a41581,7ec36642,9d5f120a,dc281020,af95986,dfafdfc6,ce122d33,e797197e,c24c09d,7e6f04a1,c5b4793f) +,S(e1eae094,f68fad14,5d905240,e79abdef,562ac20e,d52f3503,db34b2db,d2f72d43,71e4754f,ca9df5ef,b3b86c88,7e3eba7a,33554a83,cd68ebed,f6dcdea7,fecc6486) +,S(acaa286,bfd582c2,c938ee36,23a20db7,5cb6f0d4,95419f33,b0b35f2,59841bad,c3eea949,18a16138,caecb54e,ac03b6c9,282006f7,14d4b024,2bad29e9,aea7f667) +,S(87f6893c,137f60ad,22a5d543,2dc2cb2f,f2e05fac,d643839,38936c2d,206afc82,f6bc3092,1de852d4,4894d318,aaff9243,a9a521e,501ca78f,c7baa82a,3a118ed4) +,S(9df94d49,e9508ab5,63ea1,16cc4502,aeed0bb,7b1db426,c6695da5,8da1f59d,51786cb4,a7caea66,39546ae7,5826dcb2,5abc5a76,402fbe9,b32432cc,aa48adc1) +,S(8a902a14,5ecfe343,503f46c9,71693677,80499405,5df02c32,9446a373,e34777e3,fdfaf856,f777d30c,24ce54f9,d503fc8e,a3cdef47,e292ec5f,f98d6449,a69b3f0a) +,S(ad6128cb,8d9903d4,23558eb2,23fa580d,e31c454c,d3985ac2,6a2854c,733c05c9,9b69c9e1,564c9271,5562d4cb,fc040495,6ca539c9,691e2f02,5f41151,ca6667e2) +,S(c2a2ff9f,6d064f4d,551cae44,f726a8cc,b14c9742,96725620,1d01581e,5375e57b,ae53fd93,fc405150,3d6cf2bd,bb51720e,7555cb24,ef7ee8bb,9ca306a0,59563e65) +,S(56c0fc7d,c2ae8f26,4e132fb9,3a52a634,2b80dd38,f329fe9d,1871e2c1,6529996b,5d012467,cd511264,82399d80,c7f8d248,d9267251,e4d18aef,ccb9bbcf,d854414f) +,S(2131bb4c,5014e751,ef0690bd,562ad29c,d8db4461,9eda575c,9f0f75c2,da4e0f32,7bbb234f,7a83afa6,47599f05,8ab8f5d2,83f1f02a,8f8d5292,15c7cdc4,71f03fef) +,S(e8adbaa7,bb0542a9,9b9f7598,59637f1a,cb734257,13247db4,540b8268,6c14a462,72de1317,fb5ed43d,ec57ebf3,dbec4eca,bef50923,a4743359,72aee4b3,c03190f6) +,S(827e8e05,2a084162,19c8894f,ec6f31c1,a7902792,a1e8cdce,6fa5f732,4b428417,d46d9c86,4fb85e09,81bd40b,b6c3a563,8a74c222,6e7c8299,3ef6b408,4aaff5b1) +,S(3dca9759,338dc06a,8e81218,4c14c82d,3fffc50a,6d0125d1,1af0523e,d14fd699,e6c98f39,b3fd3ca7,66ac5444,be93fe24,3085a38,7b484f28,da571afd,4b8ba210) +,S(3ceb28d2,e59d3692,63432323,c36bd680,f531697d,c33245aa,bc7c5838,52bb8eb1,d2456980,96a36ca1,7301778f,d1661743,f43ed9af,3968e4e7,55ab39a1,6ded2d19) +,S(47ce6c4d,c1dc8371,de44ee1c,828e4b3c,6ba040c6,8dab0802,417ecc31,1e7d79ce,2d6b7bc7,c43e478,6df00ca9,75268b3,39f0ad68,7b0c70c9,ca857913,485419e6) +,S(ad6387f,fde71126,d0784af6,fc8a1ca7,be9bfee6,176245cc,2a18c9c1,c17f156,3233a7a,d7d50605,8cb63aa9,becf9eb2,bf8fa88c,afb2ce9d,a9236736,803dda1a) +,S(8c9c591f,e2afc468,4b64d9c,44b92627,e70babb1,aa9f7f00,6dd5b0ba,4ae794b5,5ed4c9cf,30c7d1f1,ab31e9eb,8d20fd16,77b67152,44db075c,c9de1b49,58607617) +,S(2d601d55,1b07c8bd,10db6a9f,516882b3,1525d819,9df56324,cef2c40c,6753ef7e,d32e4bd8,eeb642a4,38a9493a,87824f86,6731bcf1,6c4b1f42,240f07fe,ff075a2e) +,S(2c67af99,3de02d6c,b9db16fb,7fa99fd3,6e32aff3,69e855b3,581af5bd,cf8f81bc,69fc1c49,501a76b6,e21abdc0,27aca6b,a062dc11,5cfdeebc,b8b98ea,ae35d935) +,S(a904b9b9,a0abbb60,4be04958,74b0bf72,5c1c21fc,1ad75b9f,99ed5d60,d1beaa3c,a2cc5370,58dcb26,6677e730,449cafa1,c0135179,4afa24e5,47b10479,a2590069) +,S(bafa5456,e50152d3,115d40f,b9571d79,7ae8fa48,97801c13,238d8b98,b919302d,8108653b,f4f9bb59,de7e26d8,55f72103,20eeb48e,9f127778,5f05ed34,3e63ac43) +,S(fce057b,560e9da2,7621d46f,bb709275,4a6793fa,eedfcd7f,9a782aae,e35cd9a1,c59891ce,d7c19c5e,7a841620,8d0d819,c8634bbd,2466ed60,214a726a,dbefd784) +,S(b8dd80d9,6b6229fd,d13dac50,23f53657,3b353efa,45016033,58a9bcfc,ab61fe7f,a72beda2,c2cefe01,eaf1ceea,714b538d,8b052eac,3df84158,dd3530f8,9c5bcd25) +,S(c676cd53,7366b97d,9a056e87,2bec47df,e2c35e88,947275b0,53212536,a6231c5,9d5fe80f,763e202e,6919c760,bc96c732,844c4c18,7e7a3a1a,a0760c29,80c076af) +,S(626a28b9,c897481,19d6c4b0,bab6e81b,9d6747cc,6c49521e,6f032f50,36c9fa87,f8373b3c,748231d,b8aaf580,90898566,27b112f5,6697b18b,3cd6a73a,16f2203a) +,S(d72eae41,548363f7,cf5b5b9e,ab73076d,650f7616,e7584fd5,1a5ff2a8,ce1959b0,c867515b,46c9973b,53498582,5bebdc1a,54181a33,74b507e1,f0aa21d0,7a6c0e0f) +,S(6e34489a,4ca57c6b,f3b8a98,dac3b2a2,995a7bd,f90acac3,b81d56d7,678920ea,efe88e16,e60cdf2c,3e6a07a0,ad323e7,ff9e731b,26f9cac7,87bf43f1,b3401169) +,S(a8214f4f,1ab2d150,b66eb9e6,f64ea4f4,6ae08909,9248663d,8491cd2e,90a56ae7,5d252b54,ec694068,a0944f8d,4e0ead5f,2cf0982f,3981240,5165b5a7,e4d628fb) +,S(76591c34,fdb90d13,14c5f85,e76e18c3,aff3aceb,4385011c,d4a74bc,b36f775d,f13c54f9,c32fcde6,94d29b12,f2a8d8fb,a99d19be,80ed9a8f,903b33c1,ae52a447) +,S(17d22fdc,c48ec732,afd7bf62,7fd09d22,d2989437,a8ce1950,3acc99f,ef2c0cf9,3bf80fed,48c4c2f2,f25ccee1,9a717067,976f108e,b1cee625,1fb6257d,f1788384) +,S(2ffd19a7,f46bc028,9b11d7d8,2b391091,e08202cd,95c7a4f6,fc351713,d3645b6a,807ee1d7,af310183,fa9edc73,4c098b90,5b0d4021,6c19b797,1429725a,5763d01b) +,S(63496320,c4eaa16d,ca4ed516,bcbae7cb,124af3ef,10969329,dfec9a92,22f143ab,3ce522ae,ffd08245,d5dd6ce0,17ea6915,aece97b9,9314d61e,2d4e9fbb,5b92406e) +,S(685a372c,ead446b,6f8797c6,dbbdf442,e337a200,1b09c03a,84dd523f,674c1e31,9436ad88,7c61bd79,d0a73f9d,1d06ca0b,37f19511,9d9f9f10,6a6d6d97,f0654d96) +,S(d1aa115d,ebf2ca79,61b1a13a,9f8f2f38,8367280b,c36f6208,15cab71,d235b866,9dffc173,6590390d,a2f3239c,f85ac4c5,3e842aa1,3ba035ac,2824a269,c7c2a487) +,S(d12c58f,5e20c6de,34a27270,d29ed5ce,c2a36ac0,8f2a1b1b,69cdf2a5,d501bc3c,cf7bd006,5bedb875,bef1861a,335457ad,66042a17,c9249006,60ee461c,db0a7de6) +,S(95d9af48,d2d3ad22,4ca83889,2d7f14a0,bb4770d0,42ecca6c,d71b9278,79e69898,39e47d1f,6acf9570,5755c560,22a8faa2,e961b25e,c5ca36e6,3a5ecf5a,e54a48d1) +,S(6e4dac4d,1b6d8404,e84152ad,f5d49de8,d269c9dd,1c66136c,65b8f78,5cffec16,62d1dd58,22c06f57,f2ccefca,31c318d1,175a3c60,2aad99f2,e5c63e2b,c8e33afd) +,S(d026e847,3e8eec4b,d9ffb21d,49c13900,34a9a66d,5423174a,40c8b4b3,4f6fe060,682d65fa,cbb29cc0,91a290e9,305e4615,5a5d472e,16d37c7f,e06a9a40,f578c58d) +,S(683bda54,87643e28,8799658,baee6ec4,73ca9c66,4a76c302,b26f5762,877e766a,d3d80b37,117d6b18,c04174aa,2aba0774,43fbb78a,2649eb38,e5798935,75fa237a) +,S(fe2f54a1,830a0d86,ba30acd7,d208f6c7,22e2deda,4e554a5a,533e8e07,dfc76f8f,6a6f032b,5bb03b33,3b28e6bb,30b2b04,305e0aac,cf53e2b,53f215ac,2f1ab8e4) +,S(2486b52c,511b2499,7ef5d49f,8098f596,568fbd0b,756334b5,d5f01852,191d677,ef82dd7f,9dd36f42,55b75292,40af86da,bbbdeccd,6ebb3197,11fb3432,236f5ccc) +,S(c6fe27cc,79f316ca,5a59acd5,911963e3,bd6ae911,c50bfa1a,f2ae8b6d,69ff8ef,70aa6fed,ba4c57ee,5b3b33ec,ab6efe75,e05b8b43,41c3a7b9,bca5053c,40292101) +,S(be4ff208,8334d043,2d35c9f3,806e516d,fae58bbc,d2f69565,ec461006,99af2be2,49de6b17,c8636af4,25ed00f4,228ecdb0,4208d18e,b5c9c194,d6714550,26396adc) +,S(c5789253,316faa6c,2f87f888,a8fa4312,42618ebb,37a5184e,29abf20a,e6b4aea4,77647e3a,e083159f,afe92726,6c60f666,12e4fd31,ace116a5,11678291,185df958) +,S(27d2c091,b2212a3c,b2a827d0,951a4bea,6994953a,cbfff146,cac83f20,f164ffd7,e9fb5899,d757055d,f0e273ef,c38cf691,e958c6e3,943aae43,85f77a14,8189eb92) +,S(94d45ebc,ce92d10a,3294114d,743db35a,8e2ddb7b,7f5bee72,7d093c89,15d98d45,802386db,bd731bbc,5dc793e4,88fcf20d,15be9024,b94d1d19,edf99ea5,ab1c0acd) +,S(46739c9f,6245639b,692a68bb,8587499c,43184d0c,f0ff467,7b264985,b4a2fb62,9f8f41d7,2eb951ff,17d4517a,3fe7dfed,556aeec6,be518188,8c39a57c,913f7da4) +,S(5c9f57b1,baacb2f,67f1bdb5,3fc85aa9,3293a2d9,d85d1f2f,f62ff40e,d26e8c30,6bcc8a89,7ebf12b7,2f397b5d,ba072f3,c91f413f,df14e441,ae2a2155,887c1527) +,S(9ccb3d34,4c813c15,e9b85517,95ddb04d,c3c790a3,a1ae051b,60202b56,b735f3fe,e24525a9,fa784ee6,2576fa15,6ad350b9,eb5802f6,e5d5bbbc,7f4217e8,73f85916) +,S(f0826eec,162f343e,4cd7e135,df33219b,507876ef,5d29fa13,d8fa2326,3e7ca425,649c1d78,6547e29b,d266f2b3,cb70b823,8e71d198,6791fb09,a19ee4fc,1823e02f) +,S(8b672a2e,1b76096c,80b87519,10b6a09e,1b7204e3,ec139cea,46aabe84,4302dfa7,33f05056,ab88de5,e036f8e8,5bcd51f5,423ef431,4faa1015,7eacfd8a,9db71787) +,S(93cb8f71,9db52708,986fcbc6,26679315,fe79d119,9f8abffc,5c02f375,8e5a50e7,ed7d055d,91843e32,4193d866,81551f5b,36b484d1,f0dd5fec,f59e51ba,57b93bed) +,S(da506843,86019984,4004a723,7ae11605,a7132e86,55145d8f,ce9e0e50,feef7d5d,260f6393,886e1b8a,93986894,a4a98fa2,61771a46,16d04ebe,baf8bc48,29816d53) +,S(2d469c5f,26610e4,6bfe1cc9,43cfe267,e1bd0a22,e451aeb3,e74f17b,b9ec2f76,1d702b5f,fe2101cd,f5a5cdc8,4d4a4890,6720ac6f,ca626979,d942c218,163474a2) +,S(1ea83777,5513ab9,cadd3b53,66cd9049,da1b01c5,d347f7b1,c8a74f6f,658cd621,b9e312c7,2dee3d7e,d6e67596,70c65bca,5bec92a,2eb82fab,a122ffde,5b1c7f5) +,S(70bb25c7,9589530e,f129166f,cac1d5d0,81083ed5,fc5b9b99,e744585a,1d6b6816,63234c19,dad2914,3e99ff95,a906a5f7,a48b3e87,2d45436c,8d987baf,a93b3588) +,S(fd9989c8,f68537ea,a3248b19,ae721256,ba8d0d2f,d825980f,f89bb158,a700f0a0,eb76c5d4,93e52d45,5d27a12f,fcdba859,664bb048,1686e67c,e79e40c2,e0160c97) +,S(f1c32c17,8b36e837,b058e9ab,ed3c65a7,e2c76397,4936a524,838a480d,b3089b7,dd4101fb,92488a78,480cb6af,6cf73dec,5aac619f,3bb42594,c3dbef4e,cc7a3a11) +,S(842d8101,ed396c79,b5b19779,c245dbdb,b1ecba7,9ad77d5d,f78fedce,f9d83f33,6fe77300,9117a404,f4b28ef2,57441145,c5afc6ae,2e655ecd,2497486a,fb1ebc16) +,S(6e9e1a2e,847fb133,cc92a79f,767a5ea8,cac887a3,16903a98,f3ea86ad,3e8cf24f,d71de5dc,12be0a35,b996d880,8442fdfe,4a6cd810,7fe29548,da99783d,9049ce3d) +,S(f6739fd0,1f5429d,27c216fb,2b02d871,7028366f,7af115d1,e154f87a,812b5e37,15186c87,f776c8a0,3532b554,1e1b583a,5a465334,45bcf93e,dcf539b,21663c95) +,S(c3acbd98,43bbbd8c,68f153d8,553a81c2,81dbc584,42edb9d0,e51d056f,2b80e2f2,8397a220,483081ec,ea7de090,5d063412,1dfbcc32,ce70379e,c58b33b3,20f39d25) +,S(aa9c8bec,c845e691,a4c3daaf,a9bf687c,ad733290,32abe151,a26c2a27,1fb94732,b82dd0fb,c53fa616,74b684f9,7da10e8b,77f1f7e7,388007d6,656988df,e18df322) +,S(3df35629,654d5b70,db9547b7,5373efd7,e1781dac,da11607f,e4f3c903,5493c8a7,56fbe92b,25cbc615,96f2cd4,10290da,239ec3d9,360b3561,4199b006,c2d2b54) +,S(bcc8b337,98973e00,771a1955,89165cff,83870f8b,a897b8da,84c1bfb7,57168bb9,483a7f4a,70c8250f,62105842,310ed427,168382a2,5d687290,d54e65c4,c83bb16) +,S(bd2b07e,a84da89e,bf5e39f4,d3f03df8,658061fd,8f78d5cb,99f488a3,e992b870,33ae1dde,77c5b467,f5b3da9b,c71a6557,b0cb3aaf,892d0e76,d9f34b40,1fe60c9d) +,S(2c55718b,87b4facb,8ba9a6d,287a2db7,1b5a03cd,c7d933d4,c6014232,ec35d05a,aab1de0a,d8e3f72a,ae822bdf,f3ff70bc,bc5aa56f,1dcc5352,d1f81614,f3f461dd) +,S(eb837dc3,b2e346c2,aba58441,8c84b20,d144f93f,841180f0,860f7280,a7ee23e,6a342fb8,38a63813,e279d1c6,94b2ed26,79c3dd21,652d5678,5f47aed1,5230137b) +,S(827719c6,9b097381,da18519,ecefa193,9a9eba18,189092f4,89bde77d,33046fb1,e73b0e1d,76e40777,4ee6fbf5,2bafe516,f6d94fa7,c7dd1eee,b3c36f7f,6429dd3c) +,S(2b0da4f1,23095370,1f1b9444,847ab289,5cbfecb5,800f2d7c,16e7a56b,c6988d2,fa8b4d9e,5da41962,68e10a3a,7d69b1ca,7963d4d8,cbb5fc1c,83239212,dbc340fc) +,S(95744eb5,13436e2e,877fb0a5,20d5f1e2,1e1ab59e,15bbaf46,206550f8,d5563134,5fb1c034,62040ef2,28adad1e,83fc2c74,57344c38,7b7ffde0,d247bd35,6b5ed1af) +,S(4c805d94,78793e63,4833e90d,d19822a0,ab7d263b,1ab67654,bb77358c,67b327c8,863cb8f0,dbca3c1e,4011928,e5827619,53df792d,449f8980,bd10cef4,472ab56b) +,S(fac22633,3ffa2cc8,93c434b,46fb0cbb,cdee765f,e848cb50,b1dd6e70,272e0ec3,6a6b07ed,46f9b9c0,86e970b1,d2323fa5,d7d66b0e,3ad3077e,da5766ca,ac5b500e) +,S(b9d6af71,c59f0fed,ca4ecc31,25aaa645,f78d43eb,79c22034,1034de56,f59ec4ef,5509e17e,3d7ea457,c428e10a,7e9d8bd6,69f0fdc1,165169bd,a2101d8f,6f4041b8) +,S(57a68137,90725717,2dcd8c46,3a9b274,69c5ef27,2ae2be60,b10b96e8,e6b47537,9f294700,1c04c06f,2e2e5aca,cf4b9549,265db1f5,74b2328,ef4469b0,1c2bcb98) +,S(58ee2a22,9aba401a,637c4d34,2b1ef408,d9f47c53,6133fcc1,de030d00,25e2f53c,d361b0e5,5ef24c74,94cb9e65,cd273e9e,73da6e50,f452f8b1,7d30eadf,32ceabc0) +,S(b8bae4e3,f2e22824,7ac9cd8c,a68632e5,1bb13d4d,735fabb7,305a8169,31b0e34d,ae8ed4e8,6ac41b60,60ca3423,fe6bffcf,a7f215a4,7076f270,a2d1017b,887b8002) +,S(a81d5e0,f11549c1,373b4c02,a61c8908,dd109f4e,7f0cd250,a667508b,aea3feab,8c6cd790,4cb4bc0f,7e56d928,ac362cdb,f096841b,dee9dd48,429c52e7,23511bc1) +,S(fea67ebf,f8f092fb,dbb3110b,77d6981,efaab5c4,97a23c3,42afe294,64f4746b,1dc947e2,94b0fd7f,952a6d5e,1f5ddc9,5f0acde4,de8db93e,41f37ec8,965d4310) +,S(4db2ae8e,6b8e674f,2d79e1a2,fb7c7d10,921c9280,d8eff92a,df1a2b02,4485bffc,8ed56cea,38c2a96f,b6e0ecf3,22b745cb,35c43313,9b3dd28d,9189a9c8,9f2c055d) +,S(be31fba,3995348a,78303047,24ff117a,48dcf5e8,72356d03,ac059306,fc5ae314,8bf72f6b,70189284,ecf86059,affb4a2b,c7b5f923,d7c34429,6f401490,5a94061d) +,S(e8d716d7,18078be7,78535c20,4f9cb681,e8f49ac1,85baf865,e7b78e19,58ee703,2c79f768,c6d3bb3d,b0923d19,74647e8a,966ce69f,d06a8fe7,5601e51,61f49f85) +,S(20ae34f7,f3497d67,6b0496fa,1a68178a,f4fdd57d,15131ab9,c60bedbb,1a840070,21fc951a,2b29ab95,994cd404,b3da37f7,d21fa790,820339df,84f17b50,3572edce) +,S(73db09f1,3c8e7bb4,48629f24,83d56f1d,a207617f,454edbd9,d51ce59f,b7ae1ec9,1e4e5175,efe03956,cce3f160,791595ad,35bea993,139e8967,f591b973,785dc29f) +,S(14f5ae1f,af20b6af,9953fe91,db5bc192,31f302e6,cc03a265,d661b25f,8f07cb18,b790b1d5,ef6ad5ef,97ddb309,354756e,138f4db3,208a873c,17cff3a3,13a8be2) +,S(94ec6992,d2531cdf,3a1002cd,efb12e68,868be66,b704dc26,3dd422b9,9cc379ec,d2c4e479,ce9e0227,4d9175dd,e2a42639,67ed377e,d0416101,7e41e8bc,8adf7fe3) +,S(f73b5edf,c8d60e77,328279af,ae99381f,4ce0de22,17a4edd6,4c228b4,84816527,86758bc6,f44e1204,68555e71,786f7d50,da7f9c72,665a7475,e77c32e9,dcb13419) +,S(94b51939,45a518e7,c602570f,863902b4,385c8e76,c335cae1,b80e1d0c,e118b573,7c285008,4d398cfa,24c5cc6d,879868f4,d8eb60ad,ffc77214,5debabc1,3f154ea2) +,S(26acc055,2fa90d45,1dd6f2a3,9bd46a9b,99b0f66f,3e6e72c3,16e09e52,f7b265b,997dd988,5d5b15a1,957e1cc0,a45518fb,b0e1f847,d58fe9de,9be95273,cbe61b00) +,S(e8a5ac01,959edc90,2050922f,af51365b,ecebc967,8e57cac,420faa6d,4e2fce98,2c2998c6,fdd97d15,fd0cd228,e9975064,f2576316,6e61a45e,ae532481,9dd96227) +,S(d903bdf2,5ce9e855,60f63d72,512626fc,fee11c4e,304d249e,e13a4b69,60f95019,1027435d,bab3c246,c93897bf,ef7779f8,9a165595,a7c9c536,176fec9,1adb645f) +,S(eea105c6,fc04a751,cdc27e40,25f0d50a,99f8d01e,1110a505,eb95206,922e50fc,b93db8cd,b914dd8f,2b57b907,4df41e9a,d8cca9e9,c3a9754b,e8473446,ef3a6c68) +,S(801b116a,1fc2c2d8,fc8b412f,e9b1b7eb,b19f4e96,16b420ce,16f1b4b8,dad235f0,53def02d,8a6deddc,250de95b,d6a96d27,1c197d36,e137e640,4123501c,15fbaa9d) +,S(db3b8667,1b0dc54,436520fa,c8d437cb,7a4c23b6,bb3c3cbf,dd34b605,af406939,36562d35,a298b620,f7a06498,b1032f4a,33cc3b3,ee185e0e,aa8d3e4f,3ec5c481) +,S(7bb26eab,8b808402,a9fb3fa3,8f0e2f6a,7d82d7c7,eef75cec,43594713,dbc17706,f4f86283,713738b2,a9209e49,f82ae1bd,9bcc908e,b9565546,3a8a5dd,8d0c4b9c) +,S(e89fe301,8d87bdae,20fee2ec,7a3f6cd6,cf932d20,a026e1bb,a82f9c63,a47b97d9,92a7e80e,e7657ad7,c72f471,8f0c28ba,acfc748d,a6090026,1191912d,32b8a498) +,S(c9a10a8b,14d1845d,be6eb6a8,65cd2ce3,a4d0be4d,fad24912,b01fed8f,8bc812da,5852b791,85afd22a,6f9ab486,91340dfc,e9979cf0,bc9732b3,637434a2,25001d71) +,S(257df2e8,cf535cb7,954b52dd,7e3ee08d,24cd4415,d1075dba,8f75bf74,74afad3f,f72d1e76,d4da3c0e,5b41fa82,28639f2a,f4e114c4,94073ddc,3e8fb2aa,f82596b7) +,S(3c64aa9e,548a430f,a815bd54,713ed69d,bc32a0a1,30ae7ca4,1541ff21,a5314886,8377911,7426e30b,dbf84c57,b110cc3f,df5acc95,7313cbc9,86e895d,6e0ec912) +,S(cd509f83,3b65a7f9,671b9239,c5e71323,f183e956,2c2c115b,751046a2,33424ee9,579243a,c7fbd433,81cbd0fc,4330d087,cfe0c41e,449ef82e,12def6d9,8977338f) +,S(27adfe4,febc3501,3ca7a0a0,b5f7e525,3768df69,9d236f63,9ab80782,c2d426f0,97cb4e7b,73b065a2,499a1675,88fc116,be5606f,80619d42,ddb63286,4d20521) +,S(ef5bb148,98dd6802,6f25c363,16a34acc,c6131851,a4efe8af,219fcbf4,13a45207,49f30d08,291e60f0,975c93ec,403d2a14,3742aaeb,3777cb9,87ff38ec,b51967af) +,S(58df8d45,955e923,ec7fc327,f8081ec3,7ca6e261,7fdf7785,6eed51dc,95057034,cdfca79c,92dfe719,2ec63f6f,f93d211b,d7cdcf69,4deac173,d3393fd3,7655a310) +,S(2a4ca8d3,fff5ac47,bce452f0,1587a769,443e66c0,164558b6,301a6a2b,d3d44270,ed73b405,521274a2,3abe589d,c5ecd607,b6467691,f81e3c9e,6a2096db,2ec82366) +,S(84bafd1c,7c6072cd,fce244c4,8ea004ad,9b8e1765,bb8796d9,118d6dcf,a5ac58ce,86ab8db1,7c26c921,604a3c3f,f0155a2d,14bd7274,16f9e319,efb68f50,2b636c00) +,S(c3785528,7cc4e3df,f5e95951,c5bc5964,28705a12,10927e89,890726a2,ce00b657,302ebd13,5643eb43,f0bd14c3,65e385a4,c9a177f,96595054,3c3d96db,69ee8f79) +,S(c3aa3cae,efa22927,56c72aa,53507474,50f7a64e,2df1bf64,333d0402,5dc87d25,c2eed94d,ff9c5cac,248f77bb,9e189302,286db019,64214d71,1a199119,4818ac4e) +,S(443b9c8c,7d8c4f7e,de7168fd,666e79,5da85e6d,6c0f6448,7d349de7,66acff4f,2d4f1d59,b0d1688c,9fff0f2,f80e3434,db72d76e,6ff886f0,63dd63fd,e192b01e) +,S(2afe7ea8,688081e5,ee8a4ae9,87aec6d2,ede5ec3b,ca887bbc,1461709c,bfc6e5d9,5c319df3,2556ffc2,56194b7d,eb46dcee,59208922,1e55c384,2a03ddd8,78add90b) +,S(c62004ce,4d82ee0c,e2edb82c,e0ca98fd,413bbf44,55b96624,a86aa252,c346af6c,b68e4fb6,88f78331,bc2218f7,6a5e43f1,cac49fe3,4c5302cc,d6a3f1a3,258564c9) +,S(f759c4c6,e0bd72a3,9aabbb17,fc62c900,d57e0b5d,ab9ecce6,8f439025,2b17cd1e,6dfaaff8,5f9f3990,ad2c55f1,3c74e3aa,aa0f10b2,90def714,229cd3da,d5d18d98) +,S(b527a6a9,d27d0a1d,5adfc1c1,35308e5b,9a805638,132f61d7,e5e60709,ac3a9d9,e387f69,62ad151a,d920c82a,739af00f,628865ad,4ca42405,efd87e89,55b91042) +,S(ba23656a,6b0a5c57,f9a00d6a,9e6a331e,cf0c8097,3675f41c,7f0172fb,caf4eb02,b48ac68f,1a108de9,18d76d4,95a811c2,b7614aac,3c5f6b18,f28de8cc,7bd4041b) +,S(ad94ec6,fa161fd1,60dea3b3,2c63a480,9f7bbb91,49de206d,8cc61306,dbd18aa8,5240858c,ec88a022,7c1c12a7,862b4d18,e5acb344,5d66bf85,79ff9fc,ba866a4e) +,S(db4cc48a,de1bff28,c8987eb4,d00e1c5c,4c49fa6f,125d213d,bd814c34,cb81adc2,ffd64cf7,3c62c097,a2cb3b84,c62bc32c,54fce797,74479146,7b9a2cb5,d6f821dc) +,S(27d276df,fa39d889,beb0b586,42a0e479,8057760f,c392d052,6751f2bf,d0c75aed,c670b966,575401a2,a790440b,e5e5db56,2914aa74,e8304e3a,407aadc5,c87e12d8) +,S(7663e9d8,e34b525,b336587,eba3678f,488f95f0,6e9a6848,d2e72d35,36b569da,472b1c5a,8ee189f0,7a06addb,e6a8d90c,dcb87039,aa35e896,79143547,34e2786d) +,S(b2c81e15,1c1f8ef6,51ea1810,97eaa280,7e3b4a96,fbe210eb,b49554ad,6e0c0c4f,2d914319,f5ff59f8,c7038de7,dc70d1fd,6c4434ca,e5c0451f,4fa99f46,55bf8e4c) +,S(25131e21,9406fae4,ab96326c,7bf22892,1f18aa90,c52f46fe,b23f90ac,59ca570f,2e8a380c,eed5d51,6c190251,4937aa0b,1f39d3e4,42ab2537,e9e8d9aa,396e4c20) +,S(c2694b68,8e33025c,fb9929a8,c7ccd1c4,7fc5811b,9658ecb0,f41e4558,5d9a0c3e,c443d593,e68abc49,cbaa92b1,757ab2ab,c30671d8,4699a5c4,85a30b05,6b1ca701) +,S(8d528cc5,17a371bd,9605d8f4,e7f030fd,8a82d489,5bfffb9e,fb11f63b,be534fd7,ef2f16fe,64ceab2a,d261bd1b,314ebc65,4b4127b8,643466a8,f367b991,d28795d) +,S(409e69c7,62f856a2,4b6e80aa,baec8496,33b75c21,8943dbd,7280bf,e917b032,7f049016,62884d22,dfbda29a,c8061b7e,b82eb94c,13d7efcb,77531f8f,980babdd) +,S(82c9b4b0,2451fde7,8ae877c,ed9af540,1ec0e258,119e27d4,1938f71d,ebae71c8,212d6e4,99b91fd6,372db1a9,4ce3fd9,c5443b7e,fb37a566,f0c5f54b,fd8edae8) +,S(6c9fd728,37a39ae7,1f0b5852,e5c09d7d,cde66ec,e8f19a2f,2ab46fdd,d17c7f88,430d3385,aac729f3,8ef5ed,922e709a,73df8e70,eb9cdb83,c41e5958,272e8687) +,S(9f012582,e527901f,ad1f350e,1a64702a,ca1f6670,e693bea8,fc3eb0fc,2c090329,a2fa07ae,c15e9457,b2c75e50,56c79a6e,a4c8f431,d3c720f0,60f7b5b6,da6e3dfb) +,S(6a1a49b0,7b2b61d6,474834e9,953aa455,63910582,57db16bb,406b600d,bb01300,d4b93b7f,66ace505,cbbc2326,ddfa2fa4,ebab145c,ffbdc2c0,606e2ffa,9dbb41f4) +,S(981d0638,a585970d,4b12e577,95e76c26,1e10d65c,c5a94f19,43560d10,472fc9c8,f9babd66,3d02e030,1fc0ed0f,75cdaf94,fafc18ad,2cc68db6,d2eff7ca,e6c013bb) +,S(7edb47d2,b6295063,6cdda3d7,169b4296,3616b6dd,79e2e148,609a7722,476e564d,179a20ac,a6deb286,76fd466f,be78c3b6,789d31b4,91622149,4d7d634,d4bba999) +,S(51867800,4bd8a43,8f180cdd,efa17ff6,e16e29e1,e5fc4ef3,f5fb9bd0,bbf14ae3,306cc2c8,60ae5871,8632f94,c9acb7,321ba1f3,5092a0b5,72c33b9a,cd8cc956) +,S(bade1926,d8b0d136,69e056ea,ea46b2c8,2bf0f0f9,a25bc481,8a40ca8e,201500aa,7ac76679,c9807217,ee802773,dde582b5,6f0a4b66,f6e21764,285a6a81,4d584502) +,S(87815e7c,d1e5e88e,eb882b23,955de59a,d63f14fd,457a8d96,4b47a611,b3e40043,ca82343d,8e2eff9e,314ababb,15cd03c9,6fe6660c,421af876,63500d49,ade0d492) +,S(77d815d8,886cbf43,c1b4ce94,253e93ef,767bacc2,42ba7c1f,bfb7ffa5,308d855a,a8bb3f95,37ef9a77,ad7e282f,8ae05ab1,8131e59b,46a67c3c,7e85ca00,a2d3e1fb) +,S(49079a0a,7d9d9add,3a17ea11,747c8baa,d0922a7a,e766e5e3,fb80ae0f,dbb7d6a9,162b4e23,58f03e01,b4e09264,8cd0657c,f2cdcf54,f6c25d5e,fe7330ce,421e0093) +,S(28d61211,c183ccc,2b08168,5a4487d1,57bc0714,d3ffb16e,96bf0768,ff8075da,3da98c13,a2d1b07,2ddda165,3fb68a21,aad4a9fe,b4536dc1,507dd78b,7e51e0a8) +,S(40c34a4b,6196561a,d4591c49,df51b8e0,4106e545,26092e88,72018720,41448080,7a6e7478,3ce7d82f,b83f15e0,b74ae6d4,435593a1,67da6f57,f2e285fa,8c107e4f) +,S(88754e6a,e12e77ec,21e64cc2,bfaee207,f5c882df,80c8b15e,983fb1aa,99037c2d,5ae10e7c,e7464c69,472ce85f,5183a836,6ed5b3a9,1fb1af7b,d5078c76,2512f37c) +,S(8bb7094f,ed62beba,d628ef9a,84a0679d,7e0d2b45,a655fa3b,68d9a6ef,b24c738d,9f5370da,993a3811,48ad4da6,2d7845ce,4cc81766,f26189c,2199ca73,4312d102) +,S(79814e63,7bf2cfc1,cad39a36,b06fcc4,f7e865b3,ab2de1f0,c786f9f6,40dd80ea,aae4d149,f1e44635,e4800962,f533eb38,5f067114,3bfb87ab,9e68e27c,b56df226) +,S(d493573f,93018d4b,8599b54f,848c3afb,816e098b,8e218e2e,6304baf6,c726513,383c7ff9,b3ab6472,ecb80f72,2f70feac,7ff26989,bcb6f984,628d5eb6,a409b9ce) +,S(59599fc8,7d6a7532,5ce8f205,204596bc,4cec40b2,f3eae8ca,4530053d,1b7c731a,7a8d91e5,5d989961,889949a4,bbb71e17,84055697,b396a011,eeb33889,88f0681d) +,S(4a834ec4,da3c9afb,c62fec5e,898aa2c9,5a835e60,ef199346,3e4bf255,e32df096,8736155,ecbec836,e8d51d79,9176a5c6,6672aec9,548aa63,b7f5524f,6b20cf73) +,S(2142b447,f2707c37,45e877dc,8039161f,d222c69b,9236592c,c1b3f56a,d30a975,9a48f0a7,1ebfef1e,615a7d5,a9decf8c,70764133,88b0e57e,da554257,256e41d0) +,S(c3831b8a,eb58dd77,e21762c5,f2e88035,63fa8b1d,f5d1fab6,3d012fbd,27971797,45d1f565,6fb2779d,6ae18e96,4d9bdf61,924a5f6,a7dfbecd,2224f1c5,70292f46) +,S(a09dd11d,b78332da,663acf08,c08b3d45,d0f4740f,5df66e39,d53e6c68,f5654040,649959b5,bfdfe8cd,45fc89b1,ea21cff5,94f6083c,da8f5e5b,94525d22,3e326217) +,S(53b22e4e,8a17b408,6b119087,2b8fbc9d,fc667b40,223ecd99,27cdf4d2,a9dadaa,87eb7fdf,b9c6e23f,e7c6a8d7,fdf94438,88c6c0b7,1a3728ae,ca8e83a9,4403bbe9) +,S(7de0aeb6,d3c264c7,f39b087a,e62dfb5e,aac6fb17,483bf33e,bc34a903,f0ee35a7,43f92307,6a2205a7,f2f0737b,2167863c,43f3cec2,ea3abe32,9bba3792,6f070847) +,S(ef20ed3f,3dd1cd8e,a610f1da,64086eda,a4a646dd,e2bff224,ae72f069,f341b532,c3477d8a,a0acf4a1,e9c83a1b,c890e59a,1b739a82,55d3747c,7403034b,221fd0f3) +,S(ab21ffa5,3c7baab0,4ee74647,5a5e5800,dcae9a10,644c84f3,a108cd41,cb0dda53,3a02b102,dc21cf05,3abfe19a,2747f34a,35ec6347,ccf02880,5aa95119,110cdebb) +,S(ee8aa184,532ceae,2c3a5071,d905c6ba,bd1982cb,391151f0,fa869339,aaa50ad5,157d9d2,be135082,9eaf2c54,94e6f90f,8a82ad35,2d486dc,58068cf1,c96a421e) +,S(6b234cdf,fed7575a,f1cd7ac0,76c4251d,5853718e,2ea07c04,77959afe,5c0af2ce,223c14f3,d3d61375,d104402b,bbd51026,a7644b15,4f4d254,85e9a4a6,e8dc2831) +,S(e04eb879,7821557,a875d846,75496d9e,420ac3c8,6e718e45,347a616d,7616e836,59f33383,8354990f,2189cec8,af523611,df4a1b30,3001c5d,84e1de70,bbc6bf31) +,S(6b8c79d7,791e8423,788627b7,a99be936,145a8eed,178c8bec,affa8a2d,72965da8,28fece24,22f67bd8,a2d6ef6c,66fa51b4,c4abe766,7480b520,4f77bd8b,2e3863a8) +,S(d21a9136,eed220a9,708c09ed,2b22f5f2,87868a1d,493f6ed6,2fe9a455,42a4da0e,efb15959,cc7a2c02,7ab7f5f6,ec8a538e,91df38be,f78de45d,dabcd8ef,9b5394b) +,S(f950b37e,a5bfc8c7,a76ebefb,f228043f,de066a1b,cbb30688,b73e085b,cce1ce6a,6bc569cd,609a15d4,28ce7874,53ab8d02,fcdc9c50,c8c44016,ee2b62a4,16849616) +,S(75a72a76,520a5f29,368338ec,fba063c8,977548f3,7bbe08a2,e1ff5e97,88b9bd3e,41c140e4,5e2be58a,dee8af9b,e64cbe8b,4c82860b,98299d52,3b27737b,3266f978) +,S(4474da75,3d9c68d7,2218648,1ce835ca,4e17220d,533adb53,38a1978f,cdfbc3f9,b5e2d3c4,ae2c8276,5a337068,58e76666,52a81638,27cb6b94,3d2b80cb,36ad3eb2) +,S(e3f3e682,fd38b067,33f3e91d,585f3ef2,aaf90409,ca125479,b93039fe,3437388c,aaef5ad5,4bfddc87,f7c3f969,94564ac2,27e6d5ac,ffd345ab,246ee2d8,60d9242) +,S(140ea6a8,ad374157,396b064,f7a952f5,358ff408,951895ee,b66b6140,d969afc7,2f340af0,b08a67db,e6ea7535,581b763,24308f37,6015de2,a4dbfa64,1990cc78) +,S(257c1e04,2fcceda7,9aac2bb1,1f01bce9,37b445b2,bff51fcb,555395d2,d0c16b89,73b21d9,75bf23f1,aa0efe21,5141bad2,5a235978,e36645d,8503a60,3956cb5c) +,S(c243452d,664d2610,d1acedb6,ab5201b9,cddce44a,b9320806,4824329a,e0b7a550,50607848,db2b53c3,c9ed2b4,8c0adc28,322d2e,1b30c3df,1ab9dc37,64b001ab) +,S(a0ae37a7,3aee0e63,c0ca3e50,e59a660f,c7ced178,10dcab26,7f91ed44,3f265fe,8332d25b,94e0555c,21ebab61,cd209599,bab277d2,fb9660f1,f237c9bb,4327668c) +,S(2e4886d6,678f10a4,460b4ca4,a9964125,413a739c,64b6abb9,c44f675,1b47dca9,96f6bb70,9602de31,1be57a61,966c8227,e5dda6c0,48d3f1d3,bb5bafa,fc1e8de) +,S(855b47b,efa7dee6,2452a602,980258cc,de813ae4,6f580a46,d5d18432,5b423f8c,c27f5513,114fea7f,b5a405d2,3f25915d,775ac895,7fdc6e74,2d968bbd,d86c181f) +,S(dd360b5,38fe460f,9d6ba828,e2ac7973,46dc386,de05022f,fe48e891,a115e2ac,8fbc127c,d9e79454,a0be9bb9,cf25b7e2,71a02e7f,b4c68653,b7e08329,747cd68f) +,S(993aa6eb,47f7713e,e6c5bea8,1a65af55,1036d0eb,3df8a6f7,e091c16d,3f424c7,8478497f,a774307,d47ed357,35462f3f,a680eb87,fda11107,275c1883,e859ee34) +,S(4828feb,5e3abb4a,2df7b990,e20e1214,804ef219,4cb8acf6,cb8e85b7,5696d961,d8d2636a,6b664b15,f371ab5d,3ff31279,f7c42678,ff380ab0,9c220b02,6ecf3e3f) +,S(fb8dbd84,64bbb5b1,904a2610,2321e59d,ee9debbd,afdbe585,3e1af139,f8fc472a,54e088c0,91a67284,6c81d136,85b4edb4,391e5121,3c4d35e8,47863018,62844742) +,S(851fc8f,cf378f62,5edb262d,e0360d2c,2e9566c6,93abea8a,aec29e5c,275ecc9f,dbe6025,e9857155,83b38b7,a167adff,da70398e,85223a6d,9b940fa8,30a9d9e3) +,S(4d5d07c4,23079d83,d001c000,8c76fb6a,e03bb39e,325d5794,b5414b,46c6777c,d1c1e970,5b80fef0,8450f941,1b8d6197,21f1491e,87745c26,9458d58c,18d14678) +,S(8164d5c9,cc72b489,b6a54e8b,d9cfa9f,8496cd34,3a227a74,f37948f9,5d35340d,90b51776,9e8c68c9,20f5e948,755b4da3,2b294bd3,eae81da6,e0c0b287,ce229bf7) +,S(19a42dbb,9ff7a400,aa821c88,807281ee,ff7df5c6,e047cc51,9693c191,6145e00,369e9596,903c35a8,bb38f4d2,a74da3c3,cd2246d6,b0391e98,e01d6101,439a1018) +,S(7299deb0,a9b7bb52,76c8acae,37ba0ee7,bbfc9c0,7845765c,136cd762,7e7b7f09,8a0a1d16,f00e3090,cfd9cae,d8aed291,ebc56d97,66a131a1,4fdcf6c9,ce6b49bf) +,S(12c7adbf,112e7718,a3ec6774,1597d6e9,87763a10,4350650,e6a804fa,507ecf6c,b3eced7f,bc3073f2,5f86d647,6d822b8e,eeeab7f2,1b3263be,615517e8,ef3b1a64) +,S(b2d76aba,c1af6c6a,b4840b34,db1125c8,d5baf2be,90dc7e6a,52edbf79,a4b0ccf6,92938b87,641e0886,3f22f5ef,e27f9b18,80210d14,312ea6a1,eacaca0e,58c0f73f) +,S(818baa52,8251c326,bf545ff3,a56596b,58e0b525,64ae359a,c1d5199,4b52106a,9f8b4753,a7b56b26,e0e79b9e,9ae5f30a,64d0ce27,5898bf3,c0f12e43,faa69681) +,S(e08080aa,21c9b6ba,da128bad,62dddd3e,e8e5afc1,c460b997,45eab92b,b1663a80,2b878efb,95a19892,8b3609a1,cdbbc1ad,d1530a38,b528539a,c52fff24,2c382dcc) +,S(7a8486a4,1d774bb1,32321247,f7b87964,1b18a621,508f5376,99b31798,490f3e8,ee8c3085,5c3fa5c1,6f90b68c,89944aa8,dcb824c8,c37a0feb,ac796403,15ee96a0) +,S(f74e74f1,6e67c1f3,f5952373,e53cb85e,650a6dae,2302f495,f6882b9d,e2b71cea,1b15103c,8566d2ee,cf5c59c,dab607e4,97075e30,1443b75,42620545,2d1d2bd6) +,S(3ab4150c,cdfd6793,5f8718f0,dc961126,114a5d82,e1791c2d,48740425,8e8ba004,2a6c6f1b,9b546945,f9d327b1,437b1c58,30a48eef,6a14887a,9d8ca24c,c6bc446d) +,S(effec0ed,bb80580a,7bdf80cb,38cf775a,43b786e4,2c80d73e,7a254216,ed7ab7c9,c7c27bd9,57c996e0,42ceda33,2d0b5972,91ae5725,6df77e82,48bb1716,127c582b) +,S(5f49ea21,4d80f735,fd5f51d0,55d4e2f0,fbf0f804,a8f32615,340bd6c1,65a059e1,72e0f032,83684df0,98e740df,bcc39d61,6956ea36,275ca5ae,dbcbd682,510496ca) +,S(2327c29a,7f906,4cbfd900,43d28618,5c555bb9,bb64bab1,c3e20417,4cee2591,db1711bd,ac9095db,39e3d2f7,d2b84129,41dc6f8d,116115eb,7bfe710c,13b9e41b) +,S(12f2f427,64f77c84,f8a97c5d,7743bd8c,cd0c6132,5cd10fd1,76975a97,b447991,713e4660,cadecd98,3b0e4986,855c2c67,bc220334,2991a18c,bb0c08f6,8282b246) +,S(cdd3eb6c,b496141c,b99bde6e,a66b2c78,7264e6c8,74efdda,5ffc53e4,b3292a08,d1270d9,7cd63394,b385739f,4da31dc0,80f410a6,aee164fb,8147b7f6,9f2f1cc9) +,S(2ad4df2,1ff316e7,ce29d76c,da40cb7e,31aa7e14,49fce23b,93f0d096,e1b74159,972c77aa,160c98d6,c64dd9d1,4a0cedad,875e09b5,b0d5378a,7311cd2d,a7d641a5) +,S(df0ed61,d6c8f906,f970b9af,b4080368,2f12127b,e318575f,8e2111bd,514c33a8,e9e67c4d,7b1b0fb6,fa0a4640,62d72f,28180e6,bc8bef1d,60a1ea79,2c4f259) +,S(9572faff,160577b1,83aca01e,45d61647,7dfe147f,a6ae0b26,ca0264aa,23d2870f,b7de270f,572e1503,8a4a9b3b,706eb7c0,2a6e5e56,ab0f73ce,9f4b7926,a79c5c5) +,S(52583f1f,1d51acb9,bd25b63e,158f66b9,8e021432,427efd5b,bd629594,ba951264,3267373a,94719487,344c9af6,1eb4b726,a595bfd3,41d78b33,f3db8897,7e53427f) +,S(c95cd125,7e59d04a,6d953d7d,f68089c0,c29b6a28,90ff264f,74b469fc,af7cfa58,f5c7c7fd,82d3fd51,4031ce72,657cffd2,da83d072,9b0c4d6c,66180214,9e6ac90b) +,S(67a190df,e1a2bf4e,cc23972d,24d1f13b,803a9b4e,5c1f3cec,55d2c2c,3b0b2487,5c35f795,c29a2f07,74ded776,72ab5a7d,45902f50,e76a229a,212d580e,5edeb8c9) +,S(7ffcb588,ee9192c4,3bc5bd3b,4d0c8211,28c3f2a0,62ec3b0d,77752ada,69f468e3,9204301a,fd0ecd0d,26f49878,47c42c70,e526f7d2,e69a97f9,2aa1c357,d4140a8a) +,S(7d693f1e,6e35e062,83f35910,3c1cdd8a,5279c4ad,ed0edb63,d6c574ea,322e91d6,a9042da9,ff323c4d,46b2b40a,1d44970c,92e3cb32,ddd8dc21,d32d609,c5611888) +,S(7e0e5dae,8ce3c883,49a9ee95,fb357694,a7bd48d0,f27c2eba,49896e4a,3da04fab,a397f8ac,dd4077f9,58d7b5fe,28582bcd,4c46d1ea,fa253db5,18fe90c7,61dbaa4d) +,S(715ea4a8,e5eca76e,48605688,560872d6,7a499a8f,e84f715e,a91d724d,71fc0f06,9a7b3eda,8b82dcb4,60ba3515,18c22f59,fade0636,dc893050,a51530d,77ef8501) +,S(52a9c85c,ca99e4ca,50f5efb0,118fa604,b7e789b6,b589a5d6,368bab11,44c8dbda,3796e4e7,87dda75a,59c7503a,f27732d,8c973414,c1ea0a90,fb6cede8,a5066fa8) +,S(58f1c65d,ee5ea200,57644796,a94e4a42,771c827,fe032116,657e990,b56e42e,7f12725d,388a22e3,4f191714,9f48f0a3,3d537c8a,1037247c,de0594ea,a11de507) +,S(3ce165f6,5f569bb5,e594110e,ef91f30b,7e330586,e86cc4c8,347d1ab0,f4a8eda1,90480327,7376335,72d92c00,10313f96,9a0c5d18,c852597d,1f88020d,f69987bd) +,S(133bb4fb,1a16b008,80379e4d,ca980355,c747683,cbd7e81d,87a9eb8f,4219a314,30e76cea,f57f8b17,de6d31e,447fb926,b1678651,e980338e,8f8327d2,648ba25c) +,S(cb26bb35,4cf94461,c675838f,653c3844,24ce543f,32ed7b5,ec1b6b33,a2f7670a,d6f9be8c,7f3781ea,fc765264,c9e84f2f,6d2ff771,25b8d381,199b67c3,763c4f2e) +,S(7d944d40,58cb78ac,739b85e,6dd3be5,6b08fd56,767fd02b,1d5bba08,d4639f1a,79716d18,44baabcb,aded3600,ffa68989,45920de9,1f2cbc83,e6326ed4,e37c3fc0) +,S(c4577e42,ad4014,e1fbc0a4,d69fe37f,49937d1c,19a95765,74f2437a,d06e6589,4a76bf04,18a4a8b,af103581,b6c2cd16,727fccaf,12a3998d,52b1a095,c5388570) +,S(c71f462,9196f35a,cefd651b,3f6f2b30,485e35f3,305dc774,21535961,60a17a0f,9ff53452,52ccf823,b83d47a1,a6a70f84,b9c83142,db0136cf,d03b1f24,6ec57590) +,S(35acf6e1,cad058b6,7543eb60,ef4d896d,c21c4b5e,292c3885,d9e42cf3,85bd22be,cce4ea31,c9a37f8f,21e32a5f,6f272699,7cddc6fd,8ab11c0d,12c3ca4b,fe6b0e92) +,S(c2872bec,f2abb3fe,8a258b3c,51a2bf82,6712ec12,587cb33c,a6765a4f,e3a3e448,a739cf63,63cdf69c,15c9827a,f759e0fa,f7d92112,9bce9e18,bad86c0a,9f6bf467) +,S(50fa12eb,c3dfb3b,dbb61a16,a8b0cc6b,6e6882ae,f245360c,e5524143,27d2bfe3,873afcc9,5ed9a3e5,2f1b0515,d901e9c9,3677d49,4e64a478,11ec59c4,c3374393) +,S(3ff1688d,65cc134e,c6f27fa2,eba78abb,2cf22eeb,57163e2a,150ed7aa,17b3640b,ec8f8f66,11d8f7ed,a296e690,63b3393e,58d8bf85,90630da7,3dc2c0ec,e9e05870) +,S(91a113c6,c53b57dd,60b2eb66,e6bf7ab0,e721dac1,acd71d76,2c278b31,f2fc2701,beb6c79a,2fdba188,4f98ec5b,fd97626a,131f5c16,d4466a84,a9d77213,96220b17) +,S(732b5521,e6cb7053,ebfec5a9,c5b35f47,8da4a9b4,c4bc5708,42b0e8b1,242bad45,30afe970,fa640757,bff0e825,93a102b2,e1b619db,7f7d68f1,17f27543,e72f57c) +,S(94831570,f0146aaa,fd2a7ee5,11f992c,6e2999a4,b22cb176,dd516dbe,e0e16e5f,eb275132,385efd06,35baab61,5367697b,8bef0c93,14fac991,4a2c04e4,aaf785df) +,S(dadb60a9,3af95d47,cebb540a,1c0aecf2,839f1be3,e264a294,bbd03317,686726b0,8b4bb755,46efb999,cddcb88a,ad5b28dd,b73ae1c6,48c810bc,cd9d0f03,c200e27d) +,S(148ebf0f,7e23a220,52ca69ee,57237eca,6c1caf1f,faeb8718,b9b8dade,4b97be1e,32f68bfb,464ae6a2,b23ac7dc,3910a87b,89ff7042,e863ed3d,3038d75a,f3689f4e) +,S(ec532193,614ca440,33a8275,49c65e0a,af446a21,6705f9e0,68e448e8,6e882bd4,30277366,58dd1673,d9f701ab,50dc3238,f073a297,d579cb8e,2ee51dc8,bcd44b36) +,S(bcb65ed5,b16fe248,bddda875,28eab71f,d9357099,af71ddd2,9a8471e9,b2b26e99,ed827c35,e6e13dff,ade8b9c9,d2c620e6,576db5a7,1b1e22a0,3f943f96,cb7282c5) +,S(de30301f,18df0e9c,15d709a1,35c30473,28cd3356,95922ae0,f283290a,638d516e,89398261,37dbf197,53012e47,6846f6d5,45a48312,bd6f4c65,255b89f4,a1b9df99) +,S(2eb56a7d,b051e9a5,8a7c12a3,a92509d9,5da4956e,8b820006,aef166fa,92873644,30867ff9,7ef8d955,d497abfb,463838aa,c946d487,d702956f,b75ebf89,e25bddc2) +,S(88f839f6,d7f06f85,82ed781d,12062442,66d4f9a1,e2007a89,f660fd24,ebb30d5f,29ce1d8a,376a587e,96fae37b,521a8903,8f0bffd8,9f9934d4,eada0750,32faba00) +,S(112cb93a,8db33b09,641aef75,c3f9a399,b1808314,64e8a855,16e309c4,99ca9a16,66b1a1cc,f2255c2c,119bd0ed,a75dfe73,fe2e9d9f,3aa9a6d7,43a4b7aa,9d76bccc) +,S(407dbfb5,53b43e95,639aa6c8,d6868ef3,2f41f1ea,70cd4aa5,9d76ea2c,83b567d7,69fdde78,a4971ce0,b05a57a3,8891691c,d1fb371f,b1322a6f,97849c64,bd7b57ed) +,S(16fb5fd1,fb41d76d,ffc130d8,9549465f,7976a3b1,ecd6a4d,9e5d55e6,b2a6a40d,3d39a810,95904ac4,9559aa89,8fa087b9,b84ed72b,55f17fa3,aef8b32a,10e942c4) +,S(e40302f0,6c102ca6,e6be1370,2aa6e860,5e71fd37,6c87e2d0,c0ebbf49,6fcb31c1,d32d294e,1e80cd,94925538,2156db9f,2bea101a,f652309b,8943cdf,b82d75a3) +,S(8f2cfdc0,eadf8b00,f74305c7,892a4326,9cd31300,d716d652,92a7a36f,7f1b3b9d,6d0e726,838fd161,32d19538,147248a9,5d76c7c0,beadf1d0,b553e4b6,b7d1a2d1) +,S(c7a636f1,1a9cf793,4385daa0,5c3f3abc,8c3a1589,7be0b49d,ae789fbc,e07674cb,4f715f0e,e52c638c,954b8b3a,84baac76,6a891889,db0b7f82,6bdf81e8,4040cfbe) +,S(245aed6e,5fc309bd,980d5597,9380e8c5,79dcc887,a2758e13,24ed3a1,833dc820,a7980b85,c6ce770b,13a888ff,22a1356e,4136eaf2,49238c38,dd103016,f0d0b1da) +,S(91ea17c1,d90556a3,722dffa5,631286b7,f9db0f01,e411ac16,f5203c4,1a8a824d,281023e9,88fdcec1,94af265e,c407910c,54d25f20,69d64b13,c5261f0,c157a3c5) +,S(729db97d,35fdb72c,a354c65,a0e7f76,7bff9ade,964b1d57,a98f9bf0,39a74eb1,59596a57,7c888b01,6e00143c,63f0be1b,d86d95a1,ef59e075,fe7e377,1472bfc4) +,S(f8cb711d,f74a4961,1391871e,d8de6a63,89679130,b587beef,f4eebcbb,9daaae9b,4c52c310,c6f960c1,53f386ed,6842c4d5,bc1b4c99,433567b0,fbc40e93,91a5e022) +,S(1700d0a,32624d75,258d80a6,2228b6ec,91e66949,a463f3b5,16dffe43,b9fa08fd,a007bbb6,b687b509,f450908e,b617f176,92918f18,be3113d3,8a80ebe4,4ee750b5) +,S(9f2f3ee7,70a2c422,b9b92eb8,a52570ab,b5354154,57f0efec,fcd9141f,62894132,c977d79f,ef198135,b69aa3c3,77a7f251,3274911a,73736b2e,c543a721,17908588) +,S(86f75064,8a2b829a,91acae01,4beb20f9,aa9ee46e,8e513678,c4fbd7c3,2ac36e6e,1768035e,bd1fd375,7caacc22,495a5902,a3c616e6,49eeebe7,4377b996,30192b28) +,S(1d4207d7,adcbd969,d432bc74,35f2fb75,b35adbe3,fa1f45ab,bf3ee074,b8269f68,11d80191,accff888,928a0835,562186c7,30367e90,91d310d8,2a712a9b,13d70f99) +,S(f782bf74,2e55fd7c,ab249b2,1570d9e8,cfc12f46,5330d2e6,57eff609,7c3d19b6,896e9e48,a60ace9,84d07ebf,12449980,9d96639d,101b3405,59eed877,908394f) +,S(22bde2e7,e3c0d268,f556c478,82e50f2b,634c4235,9067cbd5,a0daed53,1a166a7f,5e03a94a,5baf0f92,7f4beaf7,6b7e9649,aa578eb3,f105515c,ed670c3e,e1fa3e72) +,S(85ef9f8e,b54cc4f3,aeed4769,85529945,7eb4f3bb,1e5849a2,aec7b257,a8a9a074,8a0245d2,f0c8eaf2,84a01114,d29c65f1,c146af0c,dedfb5ff,9e3be650,e2acaab5) +,S(3bd6c026,63620684,4d2e1a89,2378ec64,177145d6,24062d23,ce9c2d08,4f34ca81,7f0e5053,87fade82,8596f440,3687b04f,4a2693ee,25361442,1d9712e4,b3e0c179) +,S(364f9a2d,641173de,4a0cd185,972f6d78,75b06722,3cececc2,9bfb8aed,7ccd3311,39e7616,8d64795b,504de9d5,3049dcb3,a95fb3c9,affa2d5e,8e8cb35b,6cf71219) +,S(8833f933,f4049c7,98493b,e5f764bc,47dae8fa,baf420d8,44c7436c,eec27898,bf615e47,1b0f1029,1afb2839,2c874f83,ae55b15a,58e61be4,12b7c7a6,13868279) +,S(d4fa5129,4835f9dc,49cc3ad,b9401f61,97654f43,ec88f206,9a63852d,6abb4a6,f24535f9,9efed47e,80d66925,8924e56a,44530eba,a2aff32b,70f36551,1db59521) +,S(50eb8613,99f79883,58b9de58,88c47cd7,bd4547c3,96e1280f,2806efd0,d0715b89,dff64137,f74442a4,dd0c25ff,ea968845,f9e14ff4,d3e32010,f1c64ca7,6afb1be) +,S(f8608ede,92c5a1e0,5f61c065,606ae232,b0f81161,bcec88bf,b4f2b14e,22165cca,e583acc4,7ee133b4,8c3c1eb6,5d6f4891,b53c84ec,7bb352ec,3b6e41ff,aa6a2089) +,S(2c00145a,60e21169,98f23b9f,6f83223a,6ceafa12,c1b92844,2a17bd63,582a4fd,ed76c7cf,c65a881c,5dd270bc,7be9ce49,c2990e43,425ccb7a,eebe64e7,eff423d) +,S(b42d4c38,79f7aeec,96f212f,1d5bd79f,bdeb9850,ae44af81,b4b3467a,85c29c49,7bdbbcb6,1eb04e41,9ea8f9ba,dd5289e0,d718158b,63ef0599,55e3c5de,41f833f1) +,S(a5831ace,8c19fd68,85e9b9cf,34b9fa4a,9e80eb3c,36e256cc,44cbe521,6efb7128,e10dc489,3e0fa1ca,f2dee476,5b8ab518,c3778f4c,583abe27,af293869,c765955a) +,S(9fccb821,59ed46e9,18a407b4,967e1154,4566afbd,df6c0639,d5cced94,50e56b17,c430e829,438188ed,a443cb2c,aa7d6939,3004ed75,5ff61e57,8dbe9e64,251615ee) +,S(c1efe41f,44186467,cc0def62,eb0f0ac9,22b8bad8,e2347849,28b465e7,1789fcc5,5d73f89f,709d54d4,e167806f,a07ef07a,7fd1a7aa,dab9896d,33c290f1,dca74872) +,S(805c0816,43fffffa,c9055f2a,996fc2f,fa02b4ab,4fa440f4,8af5878b,4eadb694,b0a0dacf,d9b3b9d0,51ac59e2,b367a8f2,eaae274a,ee2b05d9,18cc0042,eb02b6c5) +,S(d5da1b82,9b477768,bec17829,1c9abc82,b595bab8,6240e705,715de420,fefe498,dba833fd,df1915b8,fb43b39d,dbbd635,8f12d4c4,31b547c4,af07a6fd,75fde785) +,S(73a2441b,1f1b9ddb,844caf0f,8cb0a91b,5adc6556,6f883026,8ceeca8f,7c6c5cae,512e46ba,b47e9eaf,64cfce27,24566bf9,ab43e32a,bb0e098a,5dac9687,11927437) +,S(dbff750d,bed18702,eacea6d8,b54540e6,ae60ea05,85d77db8,7a63a050,806037f4,1f349895,29ce56b8,bba91938,16e842fc,f74b56e1,568857d8,2f193e02,207f84db) +,S(57c73f7d,57c7882c,5d574f70,fa225552,ab3d7741,260bfd3c,b616d6be,9698dbb9,f633edba,f7f6cc7a,9d8ff9eb,75bced20,f865fc9e,81245e77,32db2ed3,876e42f) +,S(6663e27a,7760f187,a1f67823,64044da8,d4cb82ef,e296f5ca,90c5d81a,49b7cc5,4df0d12,4ca9c8db,4885f8d5,18cbf06d,f5b437e,242cf86b,b11df29c,5c83937c) +,S(83f688c5,88ee13f4,a9e72023,5169dbd7,ebbe0c68,4cb61827,3e2b75bf,5fc581d3,f76e519a,151ba05f,df5f11e6,f3cfbcdc,4b00776b,14c4598c,51783088,2b2bc6c5) +,S(2114e129,1f65c339,d1bd4373,6c677937,4385b3a5,5dafa8e4,a0515134,6b650389,88103399,1b682f7e,9ba02fd3,e104932f,802ed44e,b996beff,7fa9523e,c9c2a9d4) +,S(a68b163c,db6c8aae,8ddeda39,7d8031a1,394ddc36,48168f13,47774ad1,d569233a,eba470d3,4ae15c94,57ba1b3e,cf5f3d96,682b8095,f83eba7b,f319feee,6740d3e1) +,S(a44b2a55,baa92a2b,cdd2f06f,36874d69,40416b79,20bb6daa,2bd9edaf,c12bbaf6,d06941d8,28f1092d,3667ce3d,59d23159,54d6cbcf,c0da31d5,1663a6bb,ccedbb47) +,S(5630eea0,8fee5570,c094ded,917746e9,18535cb8,b0286bf6,f6cc294d,5714fd33,91f60b64,3457dd9a,b2a02ff,99f931e,b38b4d87,204de10,d8a30cea,ce576b62) +,S(cc8b173b,d3112432,cd0c741a,8620fc26,ac5c5d89,e05c18c3,13067fe0,a41b4b00,8cdcccfe,b4ca500c,34dc3087,58f424f8,52517974,9a33e27e,8859515a,2f7c0926) +,S(abe16c8b,e0c99bf4,d396e70d,af00af89,b5d95f5a,3ba33570,892d086c,4b807943,14b2bcfe,8cec39c5,826fad38,9b8f8788,51e1595b,b25b1a87,149d8627,1218e9b) +,S(62411146,ca2da616,b557f0af,ccc2cb75,d278b07a,4dacd864,7e449ddd,cf29c09b,d081b63d,67ff0c07,5f00a3c7,2771c581,87804c1e,4ec5bf68,faffbd21,4c71e15f) +,S(5952a672,a50af560,66de08ad,be4f5cc2,38f3e4ee,84160b1d,14534c4e,2b50ed52,f7d7e2e3,e9612005,a0344e93,454f112c,792f825,f3d3044a,28d9af6b,798da761) +,S(128fd5b5,420f68be,3742def,c987da3e,bca771d7,af1cf8e3,12d6b3ba,df162492,afe5edc4,80c1c8b9,5580dd8c,aef14338,c09fbf6a,a1c951d3,57ca4df2,9d3f183) +,S(6315678a,13cd71e4,6e283287,24499671,6adedf31,38841718,cf5168f,60d4bf8d,ff691d8d,c5f97f7a,f2ae319b,dc590518,6ec3bd36,7f492d0a,95cda47,9492ad3b) +,S(50277159,4169f70a,ab39095d,d8027324,e212f78b,c3b0865a,a57f1574,dba1bdb1,e31fb30a,58eca0da,aea93548,bdeb9f32,325d6c30,69b3d936,d610bbc0,de3b771f) +,S(51eac8f8,8cdd7ac2,46375960,c6b7d9fa,a89352a5,4024003b,cada1e6f,df389721,6d4c8750,95d6ccfd,9d8a5830,c4672c71,d414ffe7,cff2cc15,b7b5d169,48e872d9) +,S(bd39330,76c0f542,a0590ad6,398b2418,92b899ab,75ba0065,b1ace928,b8cc0ecc,12f4bfc4,57e97c3c,9d4a21c2,ad106ee8,8cb5bfc9,92d151ad,589e90f7,d65b5d8) +,S(bd0eb600,5ae967e,81214a1,889f7dc5,d1e765a1,af74a93,f5292758,539d6dd6,2e532797,9e6a22a2,63025e57,4805e4c2,6d62b33c,5269d35b,bdeee7f6,4a2cfc3) +,S(b7b068b6,8ed18d80,67a0c971,a06cb3f0,5c96ad7f,371dd849,aec3a2f9,bbe23eb6,89871d76,d3e6b605,9997345d,4246087a,a3fa61c7,dd75f5c7,b2ed1e20,59a00350) +,S(10cf2c38,643a08b,dd842c4b,79efa2c0,3b5dcd1b,c708b253,ef71fba7,f0e51f48,e37d14c,934524d2,dc562f6f,997227e1,44094184,e8342995,d5562000,34e71f4f) +,S(5936b571,20b6dc97,ee242ba2,deaafad4,5ab83795,9f1e7390,54a0c026,df7bb342,86bab74f,b9d4f776,e82831c6,3a409237,d5923c7e,7b3e0b18,12ae203b,64fc750) +,S(67bb9ab0,bc48fafa,3ca66493,995ea995,e36cdfb7,152d64ed,ddc56aa2,6c315896,cfa9a456,dc2c82b7,f87f4216,e365f5e7,97223d2a,820a127c,a5ee4ee9,281b71b5) +,S(5580326,678b44ad,fb313c23,dd8a7dbd,c6869fd,70cc58b6,d20f8b92,ecfd81b5,6d343687,f3dc733b,55dac794,c895e5d5,9032613,563f2d72,ee94afe4,c2a932d9) +,S(fe285767,53d2466d,d056d2bb,b7141cf7,e52c2b96,d0ef3c8,52c728a7,d2dd8126,f344b3ad,c8077e92,24c6c5a9,c9f40a1a,d8721351,6b8691ab,c5fa9f73,726a6c98) +,S(12f25359,638fe4f3,97a17f99,c233b2ea,7a794d71,e677b206,aa32f251,8cef615,dd0d68e5,324e4325,ebd45766,441677de,40c15792,19d65c6e,9c63f15a,91519c20) +,S(f1e45fa7,21bf7fb4,45fe3eed,29c26bb8,bf1ea59e,de7c1a6b,e652663d,233c3e9d,6d145f2a,c3a041a9,83b9865e,66775342,a0f8a435,de19626d,ca8b9328,797e20eb) +,S(6b6ab442,d2623235,dcc7e3e4,85d00ade,7f219576,509c528e,6a3417a4,fefd328d,5d627367,ed25278a,6d3505c8,e13970ba,253a26a3,c605d11f,1eb345c5,56584e95) +,S(83e10be5,d21bbef2,ed1ceb33,c4e558ce,bee76405,257d9573,51f5d90e,f219552,41f5e174,c6e9b283,2a39c2fc,4d4fc573,634a8975,e143243d,14dc4be3,434a4380) +,S(2ba25948,9571ce20,f792129d,f43caf4d,ddd93b76,e4c8cd63,7a9de68f,f8d615c5,9469a49a,d1a814d4,2f460325,b7d58f2b,eeb85183,a370cc3,69a685e6,a87f6e61) +,S(3fac1508,b669f540,77a840ca,3ddeec5b,b70c03b0,ff93a77d,f2f73df,2728f36b,dfbac9d5,ceb21745,a6d27c3f,d6fd96b,af708066,a3bf765a,208b7231,d5fb6955) +,S(8996dc02,9b79d0f9,d57b8c8,549fc01c,2e1c1c7c,2ce2cd70,7a0bba0a,b3420ee,d08fcc05,5194c4bb,2d17ad54,2f9ec734,f2a9ab8b,a7dd0467,c5d916aa,10f7b8b1) +,S(16af9433,c9baf15d,921f931e,f530a477,b04b2e03,e1e8cd05,42e20628,df7c3241,65863e2a,acae34b5,a1dd53e0,5efd423b,165235cc,69195973,2d0f64e,c5b56fac) +,S(d82af39e,eda70e3c,f28e2f6b,b8009131,59ada2d3,854e81a9,3798e402,43d1d3c,fe03de8a,326e8bd,b202b5b9,929c2f3d,4bc8abea,a2377cb2,29cd4630,d1dc1c50) +,S(a7ad92e4,7a442903,c2f91033,7e2ebc98,14bfc943,f2747eda,666bc813,c04382ef,ffba6b43,9379448b,56b20163,44439b9e,8d6da764,72f67a27,9c7f45a,359234c1) +,S(fe9b9274,7b27f7b0,6419dd38,53e61762,de7a5116,48008802,681bf521,21a1ff92,f32bec26,b9d24872,1a47c65b,48426130,b8e72e68,d231bd4d,82c5d4c2,bde605a9) +,S(8e22ed5b,e5d80940,970de428,5ca609af,872b8a4f,b8c93942,fa1e62d8,588ac5f5,6a461962,b74b0f93,afa72284,4837ec30,b99a65da,d688c161,cfa42028,2ed97167) +,S(bd3bb0ec,bfdcf06a,62f0046a,989b45e9,c76f4d9e,b3225495,eff70685,71518fb2,5592029f,3eed8e35,727865f1,dd2a6de5,e19e6eb5,f92e520,529fe97a,c296820a) +,S(50a9dbb0,b08a48b8,76dc65fe,6e2efd92,d44053ed,73b8c279,5b688e00,a1fd1455,4a1fae82,51581f9e,32fe8f67,5675ef70,dd7c2ec6,2a42eb3d,e1aa13e6,717df147) +,S(6c1dc44e,67b52cf5,a4564ce1,7a9da713,c718833a,6d527e7d,ebc6b1f2,c893693,89cb4508,681d58ad,77900c1c,aeb25c59,b307c9f6,c84f1329,35e32af1,e39f8f67) +,S(3ffc35e2,4d4fd0e6,ffe4d1c9,b5097d10,c12dc7c0,4356cea3,b5fad66b,5f3333c0,89718e69,78748c6d,e99d181f,137eb74,6e28b05f,27af7726,e86c5f5c,daa1eaea) +,S(fe2261bd,b40fc492,99be54de,1d0bf22a,634aec85,77b5e9e1,51626d67,3f4214eb,896bf33a,5c9b7537,b621a168,f3da1bd7,dbc94816,922350fb,38925c96,5e57c175) +,S(129b6e5,dba2fe86,749274a4,f1ec5999,b2fc682,933a1120,cb8e16bf,4f4131e8,24dce651,b0fe4770,6c78c217,f0d5ed4d,4bda4e7e,4e7ea6b9,ca59e751,b018b5bc) +,S(c2d1b280,79d91abe,1a44c4bb,96ab548,90323054,94075907,37b39ea5,e1fedd72,6974b9f3,80edabdf,e7961bbd,71ba1971,ded6ba24,90466d1d,a5715d9f,92472637) +,S(d8dc5f38,76f6049d,a9a5c9e9,396d287f,911e06cb,ac0148e8,26c8de93,15bd464c,701d0a43,ab41f321,b8f86ea1,b1f51d0e,c22a3399,c1d8534a,433ebc2,38ec248e) +,S(2b1a41d7,ebb9756a,b62a96fa,57909ad1,a747dad4,b3730da9,a12dac8e,3ee4c414,8ebb1512,3f43224a,c2cb4ba7,c90ed765,5470a968,454d0c81,1ebe3384,5c6ca968) +,S(724fe9d6,e7f75b52,7da19421,3c984e31,f63ac3f7,1b5819bc,344ea339,567bc179,a1db688d,ba1d85fb,20da08f,802b5195,163d179c,7bc60f70,4ade1f26,4e1552fc) +,S(835b30f2,8e54b834,5ce95569,7d71b7a5,7cd4b5b3,17ee3fce,57722454,7695c9bf,f431ded9,b7ba9477,ff041f83,22685e4a,8c88c91e,15a14f21,6b16e302,e243cd11) +,S(f5015d22,16cfe581,e650e579,c49b6ccf,b5ca4dc6,42561256,21df7fc8,19047ee6,45b099ab,febbb493,5356872c,40c06825,47aaef2a,72e80d27,521b65ea,e2d4918a) +,S(df0b1b57,f3a0dde8,b136a92f,bf953a83,694244bf,99782ea,98050bcb,3313f826,6f7c8326,bf5f6e15,538a1f31,273adea,6908e5db,7f38f395,49284822,12124d5) +,S(a5a24cab,96c04bdd,6e5180a5,8fe27f9e,51897bcc,3a0aa9d8,de06de65,53d2890d,4f6dfa5a,a6b44550,105fbf39,7dce3a4c,e0b42362,4a97d979,eb31324f,f1215525) +,S(849c2e79,422d1dce,4b568aa4,c80eba4d,d8acd237,71f6dff7,40849bd3,ecdb7e41,a465929c,a3ab167a,dcc4fcb1,7ef9102c,35d8937c,fa900ef1,8022918a,6ebfe79e) +,S(a9a98d5d,d8f8ce0e,ddcd90ae,671c52b7,1b09b75d,b4185d4a,1ff12c71,70b499a0,a4eb522e,3aad7f1,6aec7758,c9528bb0,c07184c9,e3c965f7,afefe128,bd285c5c) +,S(8d60786e,1ec1fbe9,61e056c2,d6a57c5d,813d7f20,bc8c68ac,eea0020a,2c4e57af,3a39b0f1,6cc346c7,fc695f45,91b557b6,3c1f8500,89d742b1,60c39744,90e55720) +,S(4710166e,65b9a2d,8de5b80c,192303ed,25cbb80c,b91c57a0,b31a38c5,5c218fd1,b4cd95bc,fa48a016,658382af,37ada302,26887fc9,8200f77c,2b8819a9,ef489206) +,S(e2183510,40815901,c78a304,e6f0d545,5a116560,a91d84fc,157f061,5ed6c0de,6c557bb5,358454d,419c5cb5,1bcb85e7,db3b04ba,d18e1a63,a75687c9,8fd6d973) +,S(807cf529,8730d656,e68b4aa6,5f8d8692,ce246c2c,4e668c69,b5e93e8c,d26b289c,b22a6fc3,d7ffdf57,f18e7447,38cb1bb0,aafb7b39,101d3259,d31574f9,fff644e2) +,S(568f659d,f19f14e1,5d91f3d6,bd2a4690,b274901e,cf6fc684,dd0d8615,8dfbdd85,28eaf8bc,1db68471,4ffbfbce,30977c7,606bc591,dfb8ec02,e43a31c2,ecafbde7) +,S(651dacbc,564fdedf,f4e5e3b6,f2dd366,37c69140,7fa923a8,ce88ed1c,a65e6b86,88dfdb8e,6f117a1e,b99ba423,89ed2db6,cd5608e7,8be2c896,334ffb8d,2e19aa79) +,S(5a17c956,8214ae71,80322b0e,574529c4,dd7d951c,872809c6,b33ece6d,8cd7cd0d,ba4b0cdc,7d7e6ff9,5a97e4c2,6af714ae,f00c9142,5e562ffa,16942fe2,852a3e06) +,S(6d564251,5edd2987,568dc237,b5b98fa8,de9b86a3,e7176e62,f2609dfd,65810920,a99a0d1a,12534f64,fa97227,825b094a,22fc16bb,e8777669,d5aedc4d,58e81ff0) +,S(e3687c75,c0689381,22f60fc5,b346e8dd,17b2dff9,cd7fbea,94aa54b7,ba1f6de9,4dfd4537,1f62a968,399cfaba,87a0b985,cb333510,dfca666d,395e0f8e,2b7f473e) +,S(1a3d974b,49e7e68e,bb2851c9,c9f22d9a,5929ccde,9d635e8d,61aff93f,f7244472,f6c9e7e2,98815ef8,d53a7bd7,9f10275e,ea74ccd8,5d97cc3d,cf2e97b1,83c97c86) +,S(8e0dba73,12c4afe,8e1bc508,4d9f4944,654a5693,81a64158,d7db7007,3f897cb3,560eb34a,2451905f,2e9daeaa,63dff50f,761bd68a,2321a714,45930de0,4801875) +,S(35d9eaef,6c4ded5c,371a655f,2fdbac45,35471c32,b369955b,f8f30d95,21cd5817,c5a084ba,7b2ea4c2,e3c3d081,dab53c9a,ee40e10f,607ce88c,899f0e3f,5850d75a) +,S(44d1dd16,c42b7811,f78374d8,2ec9983,7fbee7ce,4b3a8ccf,81ae4ed6,3b7d2c73,6a7bd35c,b10c4e89,60e3eba1,8f658510,3be8d1a8,5c4932f9,f1e48d81,e3f66604) +,S(4b7a54a5,e7153a54,e4400ef,9311d6,cc16f641,6695fd92,5fcae9ed,6b2738d5,43a7bf76,ac2f663e,daf0036d,b665291f,cf983c0,791a8a6d,a5ee1956,2dc18850) +,S(add4a15d,d1a350e9,e5df62b5,4a6638d,76ee221a,4007a19e,db5bc93e,87f11ea6,c26d6fcb,3a8bc1fc,f1474c26,31a4216d,740cf94b,a9d7e48c,8f01be28,885ee849) +,S(9b52aafa,119ada49,ce33340d,ff75ac50,ac9a9d87,775e8e45,da58452f,228a23c2,67640253,503b5e3f,89f7ad07,b9379bfe,77c946d,4f61b83d,3fced91b,69e850af) +,S(965916f5,89854944,26c1efb7,88079a55,f8109cb3,8bb111b8,42ef7f00,2d4a45d6,9aa2ef4e,61902148,aea7769c,a561d04b,cbe1b340,a231388,e332c30b,8488e531) +,S(3af7890d,c045aaa4,2f7a8f26,5fcff9ea,41bae0f9,87c75c22,3ae3311d,e09b6ffc,dbb31417,27adbd5d,e34202b7,f7a880a2,41f18b0f,b1a40a25,376c4a30,ec607152) +,S(dc465cfe,c07f839b,46406f4d,9a0078d7,57c2fe0,e62aa4e2,212ed33d,5b2026a,1ef12aff,a98868bf,b51901f7,2693f868,5ba2248d,91440380,53bd137b,24b3bc8) +,S(5ae92f8a,cb9e2ca7,2f4d4c70,f4daaf96,bd237bab,2a83c0de,693d8207,baaa0f4b,54e266f7,aa1b7f22,8f24ab91,5e3f0a92,3220512a,de239da3,1069bbf2,35d63049) +,S(38134bb,c6c5a4b3,63421af6,ae573ce7,20421d36,1f4966c7,b9e7f125,f49659ac,5d42678c,d6f89848,72399321,fa86318f,7a4e3f05,4c3bc6f4,6782be35,4ac4aa16) +,S(f2b807a1,3fd603b4,111ac02d,5c646f6e,eb819a4f,7893992b,9132aa83,76892a57,6f1beea1,a315c000,3c957d85,bc5171d0,ccb8ff06,446f4748,738a3c78,f9ec2d4b) +,S(debe05cb,b308a6da,a1eb55bd,73c3f1ba,248ade5d,ceb1ef3a,baecc6ac,7a5e8c09,f4fb16b1,44beb4ca,789aff58,9374e476,efccbbbe,b74e2693,a4d05ba5,a809ff05) +,S(15cbbf1,2720f8f5,fa1a7752,b6f33333,91cf3d0e,c40f0292,24f5b7b2,c966c099,be3b1573,fe38200,a464f4f0,c3c2f9d6,24bd59bc,9412110f,6eca2ada,2f1c7294) +,S(e4fadc29,2f0cf77e,4b14c3cd,b567f5c9,be82fc93,dcdf2b50,bdf20fdb,f5984769,2858e2ba,c9834a2f,942ea7fe,2e339d8e,b384c255,6a48d688,a9510808,a1235452) +,S(b0a8c6dd,f57434e8,a8bee1a9,530cb9d,3d4ac31e,edd17653,3d84780c,6909554a,4f7467d3,62185e38,f6d6c30,e4c3e4ac,e167f3cb,aefcab8b,eac754eb,c76ea3dd) +,S(a4398869,26e4d06e,5337e61d,dcc6f491,4f40c04,eb3ec752,47d9d058,9dfea2af,ac1fdc5b,70d792c0,7bf7e55a,b07ea1ce,477dcef6,cce8585,84cc90ad,c62b6272) +,S(84b362fb,1597f179,f30b7e2c,b516153,94619081,1131d45c,ba55fd1,94f369be,d2a80ffa,44965152,78c2ee3b,122b5c3f,e6d27f9d,6ed6ba94,9258c2fd,94eed4dc) +,S(75182684,96e2d037,24c11192,e9112501,f7c27d19,8b92fa1c,3b0e931c,2b85d32d,eddd2a6d,d884f93a,b6f8d225,c9fb32b8,9f396f1c,2613be98,d866b713,14a00d70) +,S(aa96e0b8,104884cd,7e22211b,8b12e6e6,b3f3e3f7,fdff04fc,202d8946,838fe15f,d8a9b5c3,9739fae3,dd3b2483,4fd2981d,ea529097,2ba52541,56905664,f289e3e0) +,S(ada17e80,82a0a15f,366f3d6e,6775b5ef,35c980f7,12ea7522,1aa796f4,2454988e,7df4c1e3,191214b6,e40fdae,2f5dabaa,b6e9837b,f53eb10b,dd28e674,230cf2e5) +,S(322a0524,20f0fdbc,85f35fc2,de6690e5,a61260f1,428ec662,4185ee8c,d2385caa,fc81cabd,789995e7,d36d3de0,1b650a20,1befd7a7,a415d250,697114e3,c95e096d) +,S(5082ad62,3bf2ff8c,b4571b9b,86303032,ecd137bc,86c5514d,b9f218c,4f091153,b29d3823,eb4ed958,9b0fbfc9,2d006fb3,698ab596,d3e60360,e435bbdc,be4c80b3) +,S(de9e45fc,e9e0dee8,3bc806ae,286a2c5a,a7978608,42ddf02,d29a6ac3,9fbec470,bcda9466,e7207f7b,7d986e,36b3f238,d5bc51ac,90ec35bc,56e0949b,334ef964) +,S(95cbc3a5,61ff4cfa,278678a5,6f8b16a1,efe2d286,c7103047,310454cf,a1a822bc,8720fda5,58d23b5f,af9b80eb,dd5fa625,93325a6b,eb5ffbd8,f333cd9d,9c8b7366) +,S(fa0e59a0,969de9fa,aaf7be60,24136559,cb384b76,26d3bdec,f70f3e55,696a0632,2e8af3c2,a54e837,ddbfc32d,8a47f342,a856b854,7ec4b0ea,6fb3695,48b8b588) +,S(56aadb8,2056ff5b,3337aa5d,337671a8,77168b0c,f0330e8d,8f5445a0,cdd75075,d6c4cd4f,db81d8df,b095f681,f7349fdc,c2cc80d9,399fc16e,5fa3e86,9460a5f0) +,S(7da6a13c,11d5b063,8132254f,c064ff3f,d3818a5c,e07168eb,ed5b7345,53bbc19,26e912dc,5b03258a,f914cd86,88d6a068,266eef77,7d4f45f1,7c47cf92,16d00c4c) +,S(4004b235,d58417a0,ea1a2071,32b30a8,1dcd6a9c,3ea875a3,6d2a6225,e2b56917,1c960bd1,443c22fa,96f06eff,a717b5bd,efe8b105,7402cd93,7a6aa909,5775e226) +,S(b12c4d85,6ec6c85f,3553bfee,c7dacbf4,f742ccc1,356fbc8d,ab3d25b7,52bdfe93,a8a11692,49dba87,8c8e6c56,ff8f699f,d7e69c6,f994d05d,4e0643a9,7f9cd2e2) +,S(a78d9a2e,8b74ccdf,97c6ea9c,aada2644,8b560287,7d7b0970,41d24840,91490970,39cdd434,1d1e16dc,b89fe937,665e70da,ea80a174,5ae7b99d,dcad04e0,efe841a6) +,S(c8233855,b1f242bf,59b86372,ae49a985,2528440f,e3aa8e,28d594e0,114d2ae8,6f515202,a14738ee,ae4b430c,27391144,c551bfe6,bf24005b,81f92900,bda92b7e) +,S(6da24dec,9d6ec569,8dda9655,672a9b79,4923f595,9157af10,64cb53cd,5e5e8f6d,59517e76,8b0d39d0,2c075a46,c1e653f8,cf876fe,cfb10746,a8c248cf,4c73fcba) +,S(d0c55dca,ab79e0c,84ef08ad,57ff67c5,b36336f,2f6231d6,8efa2fac,54558ef0,d4365ebb,4096888f,c9a74d90,1adc4c5e,16f5dddb,442cb5d6,b5e22b32,99aa573) +,S(d76f084f,237dedd,ac8a1936,319d198e,baef2c4a,3b81ae42,e92f96b6,e222490c,c7737563,9639b7c8,32e4bf45,efc8da2f,53e20e25,641ea714,85674a40,1dd5f14) +,S(6a1f6920,9196c02e,6919abd2,c8fc835b,889c5ca1,6bb25e3d,ef7d0c4b,9f4e6d29,84371bc2,7bd206d7,389534ef,f2a49c6,cca4c9c9,874f59b1,ccc8b5b,bd5df3b) +,S(693b3520,85e1ea36,bc5c8ce8,3fa49843,369300c5,170010c1,b11a3c76,4deb12d6,4441c9b7,808b1ba9,8199349b,243f08db,6cdf5326,d7453828,16f008d9,45c1251e) +,S(5ee94c65,70953f27,37c16a59,590f7cd7,87143bab,405f6b23,718878c7,bc95741d,8578d18e,a49f9204,e51513a8,94920224,70837b2b,ee480929,5e4c4f0d,cf5c7794) +,S(30c174b0,e7b0cec7,e6da6a5d,335f48ee,6f59ef16,984e8912,32e874d6,2e51fe2e,af7f955a,8807444,56b2c965,5c4ad915,e040a360,eef0c4c7,891db1ae,6983867) +,S(3121068a,eb60a54f,dd427eb0,92e30895,92335900,cf191eea,79118442,67b7f4ca,d9e8f74,b8d9c0e7,c35e314b,51a52a95,bf672adb,9c6fb104,8d2ea489,5135aeae) +,S(a06f5e3,6513a659,106ec301,cf1f2df5,6093e690,38daaebd,4b17ea45,9e977ff1,eb19f18a,15630965,d2bd8bce,9e350374,1ab35f0e,4b442f12,9c9d831f,3811cffa) +,S(a26af0b6,50967dba,1c4a33b5,5226c2a,ad445f43,84567580,3b97ca1c,f3d217c7,22c8aba1,604df49,abe16949,59b33cce,db11c241,cbdb171c,50b0fb0a,399e6839) +,S(8e4471cb,b650097e,d3b0e938,18b8ec5,a86fedd1,addc6ed1,8703a99b,4128919b,fa5457bb,4068bf35,7b050244,6eef2507,c1d87051,28770161,ef0e92dd,d2308495) +,S(e9116ea3,24650463,fde960ed,eb7d5dd1,f5754915,62c99f48,31b553ba,2663ba1b,e30d7323,fc29e388,94244422,63434cdb,aebc5895,8a6fb350,33141e96,46a4529b) +,S(8b2267e6,9052f769,833b0fb0,ffe413f3,4b8edb93,9a2009b8,59d6673c,4ca6ec37,97f80a18,ac047152,178432b3,d445a0e9,84755d9b,7ad43165,8707185d,d573fc5e) +,S(79947669,d7bc732d,ca08e0cd,d3e601f3,c4344532,e35aa7a7,12271b12,339ee2b8,55906cbf,e782d32c,13cea8e,83812e8c,84c76d38,472ee59e,134994b4,b7b92897) +,S(ca6d40aa,2f863c02,b6444727,d00f8923,ec58afec,3b4a4e51,f4be232a,4b4c7c7d,ec73856,b0529f1d,9d2ed892,b22b059f,35e4a91b,b60c6a6d,e919d611,d9bd90e9) +,S(7ba23bca,5f9a88c4,588dec37,3861b699,ddfc9f5a,5b277bc5,e6e16f54,513fe7d4,25f10a4f,eeb77ff0,e24170af,dea0e2d2,3f2289a3,e53ad674,1640cc69,c042dcf5) +,S(186da622,d0e8a9ba,e26d43e0,b601c68b,311d2046,4eb36f2b,f86c3e0e,5d4ffcf7,53a6f54a,dd11af9d,50bd82d9,70825bcc,fe9da1d5,ab55e64,bbe4582b,f5248d37) +,S(e9601474,568cfe7e,6cdbf488,63f11f12,fa17ecdd,c623cb11,4818eb52,cafcdf8b,96d51b2,7b5e4fd8,1bbb009a,2ce40fc7,65fc6a3,7f8bda60,c4927766,a52267da) +,S(811f5957,accf9f32,3e48ac3a,33fbaeaf,c5120858,943e7065,9c0da185,71d1d4e9,ede77562,cc8ac601,e3dbdfb5,944d59af,63bd1aa2,ffb35bf4,1f79c418,d1d67937) +,S(77424acd,1d55424a,edb0149,a6ea0349,afcf44c6,667caa51,302b70f9,5fddf277,70e15309,989a2512,422a5bff,221c0e0e,df608746,7a34dbaa,99e77f9c,62b56c3f) +,S(e9e139fd,73c2c50,375d3966,ed4af6f0,4bd80bb,439121,d61bfe66,99dabd2e,260efa55,805918e,d45c98b9,c119bed4,21483d88,722e0f87,de7a31b5,e4b541fb) +,S(a9a5313b,e634813a,b10b9b3,6b38ed1d,a971c0de,5b6d1010,4cbe426d,544e7d79,ef7b3203,2a95144f,17803f09,72f6e2cb,80e6a099,5196911f,916225ac,e97bbb97) +,S(ff29a1dc,b5c97b7c,c5e2b73d,7a0e0244,bef71dfc,765127f5,f7e0f38b,f8a099db,b8334f11,682b9a22,ec08a376,dc3994c2,7d235d5b,a4a77803,79ec0fb6,7b4d0345) +,S(c98df4d2,da452118,852c096c,bb34c8ca,a2ebcb6a,e9a3420d,a4fd3eec,cc31c5f,f4f9c618,44cea236,edef80a1,4634159c,72663322,7372cbda,4b2680,b5dbbf7) +,S(66126139,77cfafb2,283e1a92,d6327174,86add807,b88cf793,12fef2b7,197289a8,504387f6,70caf906,2db248c3,ed5faee0,269d0190,70dd5acc,c8599f5f,5e01d1d0) +,S(efa8bcf,281ad4da,2f083e6e,182765cd,ab0e66f2,e8411007,e216a69b,d73d5e94,6e1afd7,e97061c6,cd0794f6,837aefe6,e8ab76b6,53d80846,98747ed4,64e20a) +,S(d4f9fa7e,6e385f02,c068ce7a,1b80343c,20f85b7a,4699c126,575915bf,69a2f6e7,a6496004,f280f970,c1028b3c,e0d94187,34dece11,3f9fc737,2ef0125c,851de143) +,S(5980a5c,456f383e,f0add523,13fe37a8,874059ee,497b0a23,c6dfbb2f,9f6c494,e1da9a59,c8e3d482,ece7972,9c77308,e47bcd90,cdff915c,32a94908,db1651fd) +,S(988ca976,ac6bcfb0,b42125c0,939a1207,2eb13565,29da3e72,6b70b2b9,5c310e12,97368d81,79a76a51,7c7d063a,179a2941,fe5df19f,25f1e1fd,42a32af9,d5de16cc) +,S(ca49ad0d,25b36130,cc878861,f4b72a4f,e945bc0b,dbae2f4c,629a6375,3d88037f,5ad2c0b7,2e084bb3,95b9268f,22ba1774,c6e423e2,4a5191d5,b940c89c,e1039f0e) +,S(ec18622f,b9771723,c8e6e6e3,5096e517,38c4dafb,82b10317,1f55f900,b24c2e06,5803ea86,c839ddad,6c288b8c,b382a1cf,76a790c5,6f99df9a,fc9915e,eac6dd61) +,S(c53aa261,60e627bf,bd905ff2,6b50a171,18062ebc,af9d9ca0,c486430f,b6de5da2,7d6298e0,f17a515,529fc5bd,2b85c7ef,d183710b,96d62a2c,5a0195cd,ea561790) +,S(ad138110,f9161559,229ead18,4b7ea7b2,846384e9,dc22b8eb,5b771027,8c8913d2,135a3ed1,d9df6a0e,105c7c,e6ce625a,f8173d76,60ea04b4,9ee781a8,90595eef) +,S(46946390,304df8d9,15705fc4,5714f3b4,233a5ec1,afdaf145,b6c09717,9c6b43e1,aef28d5f,88f62a7,e3ecb978,6efc97f1,1123fde3,88ec1bed,bbeee3c9,f9d3e014) +,S(d464a300,df9de2ee,220ae23,4d59b6cf,44f4d280,7ab4f588,aa21dd1e,eeb80819,89988349,b1ab280,8b829754,7e5b36cb,e66ddd16,4d7542d1,cb0cf210,44a8be1c) +,S(5e99ed21,9ade424e,25b807c5,bcbeb05,9b638b7a,4ffb3c6d,d3bd054b,b7af9f41,a373ab0c,4aba0b04,878451bb,96807604,7d811fd3,605e8e46,57574efb,21681aae) +,S(805edc92,6fddf92,d33db068,9334d778,4b30f73e,4e65517,42e62c50,fc6ff2a3,170e4317,4361275c,2102aa8f,5406ff9e,7bd35523,8bf1e946,1a6f16c0,38beecdf) +,S(ec6e5a3f,bb96f0af,dd700701,8c046998,49a879ef,5ebcaf67,456748f2,f25fd18a,9401937d,cf584df5,a9399fa7,bb309ffe,80ae015,20933d63,df1fc181,b2979fbf) +,S(94f226aa,a25c710e,2cc68683,2b9124a,ffc5c3fa,179ace52,327c6866,cfdbb3ca,b92762c3,a4c56d95,1ef16db7,b3992e9e,aa2f9c3,ec48f077,62a379f8,408f94a) +,S(8d2668fd,5d46bd4a,fc84183f,4fc31dac,964358b,fa6b03f9,16ac5bec,a619a92d,c24f6815,3e49048c,a461eea8,ce50c8db,7794b10d,d8080236,2af6677b,45e45f95) +,S(2a3ef112,d00514a,c562de17,a68bc4de,c4c04db7,8266892d,b645ac6b,ced47f67,6e93173d,64333933,c3db0f56,8c05410d,8a1dc73b,6a30c6bc,2b0d5493,d9f9fe1f) +,S(6eaa1185,19d6cdff,45d88426,6fac5867,790faca7,4ccc31bd,6eb19551,8f752dd,affb02eb,277a2bdc,db79d91,10ee8a7d,58c9662,22cfac03,b3d26cd6,3c678f9b) +,S(d17802d0,1944d9f7,aab2b542,fac985ce,e56172b9,e5629e53,ddf57e0a,8dd07137,485ae7ac,34d13d9c,9ade04f2,b3fb8cc7,d0cff406,97abbe2d,4961e753,b8de013) +,S(9e4cd82,67c121f8,96c8104f,988a140a,71f0cf18,782b574d,407a4840,607f5804,c05f08,3fb5c4d3,9d3e237b,101f46e0,6547828e,f05040ae,87db7874,9d7f3bf6) +,S(927758c2,12452995,886e97b4,b1d16c53,4603c,7362e190,dd2558a8,43521a41,30e4d5df,c5ff4b5a,5f4f757a,3483234d,4c658b7b,f24dd509,7968627a,a2a86d56) +,S(589906c5,90a1e143,ae7ea4fb,84edc7a,9f00bc90,dfeadfba,1933c36b,57f2bd25,e9d1d51d,92223636,cab62cab,362b79b2,12a18be6,6468f06b,a543921e,bc9b1c61) +,S(5b516216,1171c076,b10d4987,3aff89b,c080d2b1,9e3ebc3a,de8dcfd1,734e2f35,572c40fd,24965ce8,a78c3402,381bfd90,b683d6a0,d379d7ca,21e66804,31b8ffe8) +,S(1603bb4b,3dced105,b1a2b748,21080a5c,2629a52b,56823524,84deb617,2f6a9694,2dc4243d,fd20fd16,d1f2798f,23e43be5,f88d5feb,1f6fecca,6fadd5c3,f5a63c37) +,S(7bbf7555,4c14bf1a,63ef9f38,ae3ec279,5cf0aa1f,335c816e,580bdeee,10d95ed2,d2e12648,81ba6d5e,e8cf389e,84e37ee1,7c178b8,dda63756,32d9330c,beeeac53) +,S(b2d3aee,d083787,eb4e14f,328640a3,c557724c,e06a62b9,17134ebd,fe576073,68cd90be,2df0fa6b,da2693b0,f18357b7,ea5205e,2a1f5fd7,5a1413b4,fd9ce0d6) +,S(dd10759e,86121fd,6296f171,57a90f2d,bc217238,53969f85,4a71461b,27df81be,713442b0,65546c39,1b71ef30,3bb6ebc0,659471be,fc165a3a,686aae0b,270f13c9) +,S(54229d57,3a274ca,6eda6194,62dce4b9,35ed143d,16e470f1,239f1045,6dd2de16,a6739dc0,916112b7,4fd6ab7a,134093fd,55541758,5b3fb39f,da647bc6,5cde08b3) +,S(141f3cdc,124460ea,15fc80fa,dbba8fce,d89c4426,74e9a3dc,55f74f69,66bb8ff,f0c8d7d4,dac4ba66,1768514f,c9bb9e2b,319645da,735e5be1,51790483,d7b477ac) +,S(e9795743,efacb0d0,4c91c74d,33837b61,8d08acc1,cc2603ac,f02b1610,16fd1363,9f1c8ab6,735f3161,811f710a,1b5703d6,aac65c23,35fc1af1,32ba005b,bbe66d7c) +,S(e5e8c40e,c6c9475d,d4cff6a9,c9db5cb3,f8202bf1,bf60ed41,3e213d6f,2c860797,a9570e76,482a8177,b1adf9a0,1a7716f4,b1e754ef,864d2deb,354a96dc,ea1decb) +,S(5292362e,a095d145,c002f027,be53a28e,d5244982,bcea97c,b56d9ab6,162f7ae9,e7f00a61,8e63664,4555170d,9f13420e,fe1849dd,641bbabd,d3648250,81934e37) +,S(a6772998,3d6a765a,67e9e3a7,45e7de0e,1e42f34e,46b7cdde,8ab20262,ad246822,53281b0b,bb45bbf6,a1e804e4,cb6f443,537b4bb,d551c9d0,8976d53c,1020407f) +,S(7ed3bc8a,8a68ea64,c9dd316f,48f012ed,229e5f9,1a294666,4546ef68,bb48959a,238e6696,a7cac135,ac551927,fef28c04,5bbf23ac,9d24ef52,3d69aaef,27312e69) +,S(96702aaf,a9e17a9b,5fa4fe87,d3b45633,b59779ba,57002679,63a3a5,7e7442c8,53deadec,73ed54d4,db98093f,9e269442,d9a4a955,f9b18878,8be2c410,84014a4) +,S(bd3e9c04,42a9b0db,b063aa20,b09e7e0b,4ea18ecc,55a5794e,14108aea,1ffdea66,b5e43b5,fd8cfa37,dfd49f34,1ef14b0b,c2cc571e,cf9f7511,f2f11e15,825a57dd) +,S(d95c6dde,f07abe75,215e14ba,e76a3be1,6dc514f1,7542a246,e48a2a35,108c0833,e49d6c1b,baaf6f7e,44fa7389,31767757,76d6756b,ce8353ab,ca6e648a,cd2e8fdd) +,S(86f7406,7a86227b,2f5414cd,12c9907a,b78464be,8a5c2284,7d8442ea,d585fe8a,53c73db9,3ebd3340,2856a7e3,d91d29e2,e9439a3d,c43120e2,1fb5bb04,384a8e68) +,S(bdd92d35,ba51344e,4deb6b77,126fde21,9e7030e6,5e1d96fd,4987f1ec,bc5ee6ca,a49915dc,b4f29eb5,af9d643a,6c6f581d,94a205de,3a8bf3f6,a26d294a,be11cebb) +,S(dd4b5fdd,3ca88300,74f19532,728a31e4,152be230,2e6ef55d,a6ef9209,fc70b65e,fed2978a,3cc4c8d8,2012cd5,7e06ea37,4ac5f802,a0032e8a,21d58239,860856bf) +,S(fab1a71f,f8a64cb5,14c94e0d,1c67fb23,70998570,ebbb0e25,9e09df03,e82aaeed,6208c3fe,3fd0d9c,640a1908,1a6a6db4,cdeaf7f2,ede4835d,46549734,c1c50035) +,S(4d6fcaff,167a869e,311e8dd3,f736230e,78634ebc,c4470b91,686018c,7b529509,e860a3b9,28927956,1cd132de,a1de3456,576c4cc6,138bb079,a166b9a6,79555751) +,S(502caf19,5004fb43,75b13ca5,16583e1b,3f60b32f,d9769832,b42423a,f7ec78c3,c0aadc3,36019a17,ebf7f2f0,5afc036e,e807df5a,c2869bcd,19c2aca0,1b5ccec8) +,S(35727dc6,ebe8f38b,1a84d201,2fb24a2e,9ddaedbc,63e8de82,e18de4a3,c4d021ac,8eaca26b,3b88adf2,d19d9d52,c84d83ff,89451750,6a77b4fa,fd717b07,4b414322) +,S(7ced897a,47b5b0d5,f4db6d9a,ecd9c5d,54b35789,91902324,6f270d7e,7ac4b377,1c6ce993,fb84c89,ef5dbdfe,68dad70d,ca39a4ce,29cbc658,d5332d1a,6f6cb157) +,S(60d1d74f,660a5f6d,bac1ee84,5aa43dd8,889c9e4c,6b0ce1ab,e9952ea2,7146972d,dc4291c7,db1dcde0,8e618261,b8d177aa,77b5b0f,2aa8f341,8afc9eeb,dbf068b) +,S(a8b28606,e7040dac,7941cca0,b9cec031,31db3f95,bee7d6a9,8d60c3a,1091f81c,3fbac401,61c81632,ac8655c6,d5c02744,7c836244,e228b9a5,bf5d799f,1fb810ea) +,S(6418a48d,2705a27d,5fe68188,58a61a21,4e4dd39e,4151aa89,9fc6d414,95f975c5,21abfd32,14d98ff7,5b154250,8480b32d,ea8c50c2,3400235b,be800520,1609c7a4) +,S(b46f6f80,c71cb354,3058372b,9ba5e6d5,2617728c,54c10cf6,6ead7ca1,de2700bc,2008111e,c4b86ec4,26bde7ab,f52bf201,10787bed,d7b2e922,e3a5a60f,e68a0f4e) +,S(a0ef81c3,c9f78950,41a8d90,69cc22e9,22bc0cac,4e61a030,495ddf48,eaa6dcfe,8617df0,b32975a1,6666f86c,136e8c99,c07ff948,ff8d8176,9d968544,aee5eaa8) +,S(c03cfcd4,21cc7095,5a3e10e4,a4ed12f0,d31abe86,506da6e9,c83cf6e1,df73d093,8d6f0b3,c0d6edf4,b5d2041a,94d13f89,91adbb03,22ba9f,a56b31cb,63d4400f) +,S(4085a2aa,95e4e8f,11b0e94e,2673c48d,d42506a1,81d93a19,b5f79d45,ab88b688,cc769f7d,f45cece,d3cddf9f,c75c4dc9,bb7018cb,f54986da,434128af,b26c0f28) +,S(a485186a,b21c4650,e9f7375b,2ba644db,f22e2db2,20933cce,2bf0ca7a,c404fcb,2d227efb,68649a60,bee9461e,9390ba02,eb133cb0,eb8388e3,f64d23a4,332ec903) +,S(9faa3103,b212c2ba,9a454898,fb451d17,c3632b7f,c9368452,3ddb88a,7599f14f,9dcb34ce,51f7c4db,7cebb0a2,1b50ff2a,d67c6bd9,7066e505,60132168,3be236e9) +,S(1bb9ddd4,804edffd,78d00b86,ccf6a07d,a798d91e,5d88f2a9,37575d96,81187564,6577e8f3,ac22184b,d46339b8,25a426cf,2dc8cc86,78767d87,999a8e63,5789dfe0) +,S(7b32d099,c78bb658,24868172,1b375689,b91f0650,45fe3d9c,8af4a331,2acfdf58,a4c92e67,f4bc53c5,aa84cef5,908a36ab,afcbaf66,a946d98d,4254271a,b4f088a5) +,S(daf23c72,c67145d5,e2a55109,f95742d9,28cc16da,e53d0453,c8dc22fe,a9eec7f4,205dac83,6614ebe2,a55c04a5,970d4ae5,a9ba4b1d,d8d51f52,50de622d,2a2a472a) +,S(6f156518,addc53c9,76a16944,a059a465,8c49f6c8,6ac4339e,82a2f69f,a3599279,50a277ea,6650fd6a,4a5e4c2e,fb09bfe2,78fe8fc2,c7a86089,b4bb0fa5,fa7262d8) +,S(17661b7b,5b5a8a4c,f700397a,1f819c7d,a6c44cf9,a7d28bcc,df6e7fdb,efe50580,dc1d7f84,841d8ee9,3a9f9fa4,6a03b2a8,365398c3,f94b57d6,77ad4238,264c7868) +,S(c3042389,1483fe1b,12f16146,f48ffe67,3a1ca3ea,ea330d54,db5f7c95,fbfce6b2,131d108c,14a4fda7,77d323f3,f717fdd0,a422acfd,20b9db1e,2b2c4039,a330ce3b) +,S(654da43f,70e4c85f,c9aa2d5a,12ce1a51,d4364a09,5c230ce4,f8ae61b3,cde7fa4c,f82cfe9d,bec57ffa,4109e9fc,c9d79135,49817f50,9fde8195,79190d38,f0afd2f2) +,S(c17be24f,d7d2535a,c4eb722b,bbc4444c,fa529cb1,283585c0,730813de,7219b481,2d35a0b2,27582d2c,b8155b92,680f6651,c0040508,ae3de034,cac87591,654c0c86) +,S(fcb1fa46,f8178153,fe5f10b8,a91a411b,cdc4cfc5,61b5eb2d,29446a79,8deb14fb,29c75252,4cb13054,2b9c1a26,b4606eae,6f40ba1a,f73d006f,5bac65e9,3821f0f0) +,S(7b86452,e43ae1f7,177c131d,999b5fa,a6e4a107,e0a06f6f,4305a8ff,d1ead9d8,3e7cd53b,b2f27d89,829e331b,8236f92e,fcf674c6,478846c2,c18307c6,e82691f5) +,S(8271b58b,67a27540,c1d8305a,840475f5,3faa0031,4e779e2b,9e578c07,366a342b,5cf145f8,6fdff832,6712be08,ca1f3a27,d3e58fc0,baee76f7,a052f7df,450dbed2) +,S(3f027c76,4ebf933b,50df3d37,77f60210,4b997d1d,4b9cee19,cb549c58,b5d0fa23,cb44dc89,c533abb3,e255fbd2,6dace4aa,836caf4b,2589113d,82ad1886,7eee5d80) +,S(fbeadb62,ffe218e5,d0245d5c,4bce7334,cbbfbe91,610e8bd9,f0b89953,bf472bf6,7e824c09,9727cd33,1aafba9c,6776815e,3f954fb,539efa5c,fc4ce034,db602c09) +,S(ee2807ab,44643652,12b021b0,dbe94618,5d22fae2,f500a740,127f4dfe,32ee4c60,d958ade6,cb9d3a,ae21602e,d25556b3,b3869202,beab0910,1a1d97e4,8e360e1) +,S(94ab159f,2448f865,f3d38d65,12273da4,ff476289,3dbf74d2,ef889807,81d6802,88739de5,da331b70,87c58bd0,d734bd75,5853753d,1d3b97fe,39c68555,8868576d) +,S(98d2e8e5,a41a0bf4,a880a510,b4b65321,7b9a62f0,c466c589,d0c1634f,557666cf,aa24bed8,a5cacda,bc3c950f,d56bbd1f,f156efb2,4632e073,ac822875,2617d1f6) +,S(64efcff2,76cda1b7,c8e5ab1b,12c73a48,5a25113,eb9a5be,496e52b,ec6ad16,ac29e2d7,18bbf63a,16003992,d85a9090,98ae89,834dcb24,293d6bf1,b8130e3a) +,S(6a8e3376,1636ef4d,b1116d54,34f3fa05,d8cde7e5,31b260ee,6aa9ee61,1c4cf5ed,5161b5ef,4bafa1af,f76a1e21,bdad444a,2526cf5c,c81636cc,36f18400,b8dc47af) +,S(4786ac32,6312dcbf,a1386ca8,c505715f,2bc7f85c,22b6049a,e4386bec,11648013,67c80d39,bfb6cc58,7fb312c3,8fea53cf,6937216e,8e7f3b3b,4a2290e,6d6df687) +,S(b87d2d08,ee206c18,646713e,8af6bfad,c77754c9,59158fac,c31928af,c66bf596,6110c98f,bafaffc1,7b40277c,17ad9650,15de7069,705019c6,b7a74cae,eec6e65b) +,S(ea9f310b,d088429e,236d565f,d1b3129c,7ca8573c,191d1893,c1c157d2,a0867d4e,61c95d39,c1893c68,fdc60ddb,27909f2d,98c9ddd6,efc67ccc,7482c0e4,3c05b144) +,S(abf862bb,9db85d51,5d6a37f5,5f3942b4,5404238e,d49d3124,59f9ab38,29b34ebb,30d13c26,2157c1f,1ffc8a46,a3679e65,35be1981,c202e7de,10de5386,db863739) +,S(80767b75,df3e69dd,757b4c4b,fd0b4be,f75fecc6,ae22b488,214b0035,a276e492,ceea1fbd,bcce30be,2d88b601,895a8fd2,92f61b61,cafa5589,f9eb9652,8a78fbce) +,S(8b7a47e7,dfc35093,77771622,482e45fc,84708ab2,c9c734d4,fdc9e8d2,499dd950,dbbd399a,d62e8309,14bd0ba6,19a9963b,8aacc765,cad19734,e2526af4,2b2013d4) +,S(13700ef1,f1e82cab,7e9a7d79,d76fcfb0,b6e8c18,ec1e6546,d27eb919,bd871f2c,97488000,f96aa2a1,5913502b,30ae5bd5,f9edc84a,f97dac7d,c79be68d,a0f7f4e0) +,S(51f9a79a,991fe61e,c5b7c93b,d0905bf1,2fea0e0c,bb9e9a7b,d5d99188,f42c8a16,a3ffae0e,92e3bde2,51c9a8c4,1a6d05ef,2fa2ed53,d7a21402,e759c102,65d96000) +,S(ec7c6892,644bcff,715b027b,be48936b,26dde18c,bb4a1a9c,fa1628ba,84d5b456,51bc2b69,b76646df,51644c28,8570bac5,d51a0e9d,6e9f0ce7,1abf6812,650b18bd) +,S(efb8249f,bed3299f,7715b3fa,b6a23bf2,86560ad3,72e31e6c,ec725522,227f5c2,f36f4624,59a7fced,3c621158,8eac73c5,54593c4e,b7c82fe7,b0951bfc,8987bba0) +,S(4efe94a4,c34083dd,49762ea,eaf58feb,72f6e283,9931b706,56427bc,e9913bd,5c8b9448,5c687c16,76605dc2,d414f37c,da98a562,c71e7e72,fb2b8d5e,6ae0d60d) +,S(ecc5864,fd6a1f7e,1e20a84c,d9dc7090,9775446e,2e0bf6cc,bf896bf7,97f9dd73,49eefb1,981d4b87,ff21ca80,5471770e,8e063541,58e9c1fd,9995718b,14d9d6f) +,S(133f3710,9bcf5655,48d03c90,b82d55de,cfae1cf8,a5f3e117,5eaee107,aa7eb121,1af96963,e9113d2c,588ab083,58df45cc,8b68312c,9aaed504,3f17fffa,b29bdd7f) +,S(a8b1b9f3,971667be,2a65072c,efe8b1e5,e64f652a,4758f51b,4888087d,4fb489b4,556d9a3e,c2861fdc,da258a1f,8c6e81d8,1df43669,e64e3daa,90dad4c7,c6c0b662) +,S(104889df,dd81534b,655921ae,5483db4b,b3227f2,fc3563fc,4af46e1e,2c4fa88c,a70984a0,ce97af36,b827aaa5,218a9743,73feb2e6,fd7e2a02,408590,47323ee1) +,S(4603c58f,4fbc4575,7e9e165f,8a4b41e6,b0d2bf09,b1124998,3881ecef,2a8852d7,37e5990d,7c50bed3,2b72a43a,2e6a0ac7,5676cc82,113e3196,d6569e21,3adcd0c) +,S(5d1ddb75,774d6419,9f07f578,21786ad5,9fd7119c,f895196f,deec090f,1240748e,519140b0,1b340a4,a7aa2864,fef5a066,feb59c6,3355c222,6805e45e,160bcd9d) +,S(c9f86104,62644b3a,ec4daa3e,bac656b9,de816cc3,a5aff1a3,633f90af,8401a97f,405087e8,80403629,516d485,f17590a,1277e058,840b3fac,4e02d3bd,7be92954) +,S(b774b1e9,9f42b296,dab0e371,6d4ee04f,8bd517e6,7846d0b3,3ef5e0f2,569e97ae,ec78bffc,d6cfa76e,513a2b4b,db638f73,519b570f,f423936,ec0a54f7,9ceb5f9) +,S(d7a1e238,ad3eddf5,29002e8e,87476ae3,6668d656,595b3d10,2486f1a5,c30e6a28,5c9fdd1b,e132b9eb,4d7b935c,2209e105,55cb28e6,c4616be5,7b248607,697ef6e2) +,S(832b146a,cd002cb8,199e800c,47b2a0cf,d96591e9,91f1b406,b2db981f,c0aff924,f64632de,b99254ce,9d60b026,76551e8c,e21b300c,86fa5bd,8bd7c32a,4a81a18c) +,S(635f97ae,1785487f,437fee89,9ec21d13,dd8228f2,e209637e,18c85ecd,6cf50202,b53fec65,1a1af1ab,2f51eaf8,8a3af104,e1a40e82,691da03d,9a179c6a,3b30e5f9) +,S(f882f983,99891dcb,d58b931d,c215ca05,a232aa9a,7cfe5acb,5226ebe4,f4a598de,3d0313cd,aa36668,5422a6e0,2dd7c560,11fef0ce,3c268a42,3509991a,97cb4562) +,S(5b16de8e,3f8b8670,a98099a5,250e3102,51107cd5,d04bb804,e2a7175f,48183594,33c3d3f9,e3099917,e707a429,3c83205,4a26cf2b,2a9e3118,fa64f441,e7561fcb) +,S(b47e085e,c7a7977c,be3e2329,ea417e98,e86eea9b,aa23fc93,67cc06db,cf06647,cf6f1cc3,f564879a,f9515604,4b7b856b,827335af,5cdcd55d,1f8bde5b,d3f539e5) +,S(afd1a856,e0624d6c,16a876c1,2f78ba44,303460f4,d3cc793b,5dd32a98,d8aca9b7,3b334e53,83301f24,df0e2df6,12cbd7fe,3e1b6650,d5355bb6,c9d3873d,f42d73b8) +,S(454316e,69f558ff,6e19057c,9c754b2b,83eab233,f696ccd1,b80bbb42,3c81ae57,ebbbce3d,4e1cf2a7,315a394d,d03bfb64,300ac0f5,11627d06,7a5341b,43a4ace9) +,S(a51f1d61,dc60b34c,65345205,b2a316ec,766560b9,c50d72a2,330f828a,ec978d05,d4e9b10a,58bfcc59,ef24379f,532784a7,ccc4c077,8aa11bd8,bf008846,44175faf) +,S(771329ba,3ae1f814,764fb9c9,ebe68f37,26b8260a,90d4e49a,7dfbfd30,80cc6128,128479e4,bbcd5b06,ddf46f49,614f6ae1,bb8914a0,7a0a5bc7,34b69b39,caf71b1d) +,S(aaa59016,d18bc9e6,2716bdb8,6d0c6bcc,e04f74f1,98f17675,c021d078,166c9fee,36cd35fd,53be5c17,84dec1ce,80ab3ff4,95abf363,17824a12,71cef620,2784f91) +,S(be187d0,b3afc0,bcbf98ec,bf31bfcb,f4121265,c4b815d6,9403d9ef,926cd254,a3aa0d55,8b5f6720,9d8a6514,fe22026e,66e8d972,912a6503,5faaecf0,ac2d9b25) +,S(228afb7,a9564fd3,641bd417,20a0e44c,d2ab5d99,844fa61e,264ca823,e197da88,24457982,391e3209,88cc44fe,e42cd242,80fe1f64,b87814b9,bb485d2,ed0d7757) +,S(dd55db40,e3333379,7b8ae013,297b477e,bca2f586,16f29300,6625aab4,6c367ee9,836a69d6,603fd34f,92d3f775,d25ce89d,b92d2803,48a21178,44f9273f,1a97a9e9) +,S(f82dfaf2,5113d8d5,728c53de,3b43f2b9,d2aac0f2,f90b762f,390f745d,7e10093a,1097ff80,ef2f5dc,88873c1,2b5acf0c,a8a803cb,ba3624d,4a036649,ffa07bcb) +,S(666f1006,57ebb1b,f05f50c1,2bfa7fe7,cdf11e0d,6cb37c99,4b39df89,acefc7e1,3e3ceb4b,eb292e5,3c00e4bf,ab6dd9d3,becfab1f,19880c3e,cbb93a4c,415f67a7) +,S(9769b542,3b098d8c,18871a53,8403ba2c,d32f556a,7ca7b089,ceb9134a,5d983e73,536e7c80,5c71c49,9d9acbed,c6fd94a8,3e64a2c,8afd8721,12f6848d,60851084) +,S(26081d34,3771ce6e,39ba59dd,2c2e15c2,4c6903eb,b6c157fd,b1c51dc4,e5343bf,82f6d675,39d04825,4cda5bea,e4879547,9570f86c,9ccbe1a2,ee0deb39,afcf5efb) +,S(feef7b4a,dbb0e287,a0762b14,445a8fae,b860e08b,19600b41,45d92447,be732bde,44e79fff,55aed478,f8d951e7,f4a327f6,c4a1e282,ce617a3b,5128f528,33851e5) +,S(ffb8488d,f26d306b,70b5b1be,4b6f2e4e,b6d6b2b,4cf05d3e,9502f3f9,81406cef,f2891496,f5affbf0,bc60c46e,b96baf7,2a4e6797,3297a28a,948adb92,1cfd5dcb) +,S(fd1ec3c1,736f2edc,5c080981,fdd99fca,9e301851,cbe8d840,38f03a6,59f21ea2,86755e0c,7b01dbff,ed701a7e,b5deb21,3566f331,d707888f,4f658879,cfbf3bf0) +,S(addbda08,d536486c,b9d0b4f1,5ffc9104,ff75be96,739d4641,a405e2c4,2775fa4d,4d70179e,1237e2d4,61a0a0b3,c3bf9df7,9483afcc,1b8fe02f,47d4b312,2f339089) +,S(fb5e9c09,8ff0520d,b162e57c,19b80ced,7c63ea68,1c7a2c56,2557a1ea,d2d7a46b,c4d9cfa0,d31cfac0,78c187dd,2ccea738,4667776f,b8eb0935,9330fab4,b9f67e2c) +,S(28c33364,1762626a,c9e4d2d0,53a1e5f0,771449e7,a0977f2c,63db4681,1c675b45,239e717,a76b80f6,2b11c6f2,c459d516,bf81dbb1,4dabba88,9f1e627b,5fcb525f) +,S(68e783ee,84fea44c,59c46bbb,170d7751,c47fb05b,602e9995,2469def7,cd061c9b,7054cae8,31dcb37f,ae8d8298,859b4e56,772f8a6c,d079918d,b49c7bbe,cde61f16) +,S(1526613f,fda17eea,1a7930da,c1be4a6a,4ddffaa5,1adf3c92,73f3a2da,44d69c46,c9c3d04c,996c4d40,b906bbcf,5b0ac89,f541ae4,81b7c5c1,8f9b5762,7b9796af) +,S(263e6099,2adc9f24,1cd1c16c,de291760,babe6e41,d4e3d064,f1a8768b,94bc5439,3ba3eade,1c5b8225,7559c0d7,97c47e5c,41f60195,463b2eac,74801439,b3a6663) +,S(ce58e7e0,73c871b2,673e18e3,c9ebbb8e,e6bbb2d6,226e3d0f,4bbe6bb6,73e72816,85ba41f4,13158058,fe8d068d,df70f97c,acd4f512,cdcded1d,ff9c3c39,eb1ce1f3) +,S(47c3eb29,1402d2d5,25a95ee6,fc54d1f9,721f29c1,e5b51cb9,d82d234b,94de6594,beb5da30,3383e0d1,4d13eca0,8eb8af0,14f8220a,81b1e8f6,47c1f95c,4503380e) +,S(8f5e8092,c71ce97e,af578fa,52f174d,ad0133f3,94bf2ca,ef5c7adb,bbb37ad,1ca41380,ac714a5d,3c6be070,117b10b2,dcff62d1,bef220e2,4063c971,89f6ffa5) +,S(edefd606,5883e90c,31215558,b05f297c,45c64fcd,34cb864e,3f0265e5,7e7d5a4,924502b3,1d0e8df2,2a54ae07,edf1b0bb,f2ad1df4,7de805a,43ae11ae,8cf3d628) +,S(31516a47,50773473,6e691ec4,e6891eef,601d6e42,d7f4ea4a,1e5008cb,b77e151e,7f243d73,6ec9d71c,d2047cd8,d97c159d,345003d8,72556e94,4f7aaa74,acb8562e) +,S(9049e0ee,149d379b,77963972,1027627f,5cf68f7a,9b1c81fd,189ae6dd,eea5c552,ecd60031,71dd9199,77ef92b4,262388a0,7aec9cbe,65d80882,1847a5b8,c758ad26) +,S(977ac11,98214ec6,eb92699c,aaa9c219,6246df82,85a6afd2,fbef31,a5a93b8c,27e01787,d6e29c74,f6308e21,24f9fa99,6a5b78b5,4f45fc95,b71430a,abfb964c) +,S(bd7ead55,e8ebc96e,5429f59,52427ca3,8dad3d9d,649676c5,52a01099,3c359a26,9e596b26,8c90186f,8cf38e1b,f47d6d6a,d7204c78,b557b3bd,25125bdd,c3ef7824) +,S(90c82d89,9178857e,e2563cdf,d822b872,2901b53d,3b93a6f9,2905a4a2,163be70d,3779d0d,c99fc814,8b2f58c9,fab70952,373365d6,1adb6e5d,9ac3f761,9f27e943) +,S(a312a0c,3111faf7,2cea8b7c,3e2786a1,65362caf,11919687,3368c77f,117ac42f,1b78c42e,af0e6219,ccbe3ed2,384f5529,dff57894,b9c82566,255fc4d0,fc798b6a) +,S(7cd723db,c046d3f4,5b0fa248,1197790f,688632b4,5f57569e,2f7754c0,9fc9bcca,eb5fb704,a5cc0b22,979bd64a,790f428,b57bcc79,3bde8fc4,4d6bc9b1,8c21e495) +,S(2b24dc16,59324483,3851815c,1675d051,60713a5,7dff00f8,9e72df7b,d1c7352a,ab05061c,224fb577,a72f5d2a,38a9e59d,18c52645,9564afca,a9539d0,c64c8fc6) +,S(955ffe05,c4653033,c2b4afa1,fcf8d3f1,3b55c9ba,80d67c37,598f6d87,97f11b1f,d3502a31,bb37b950,93b3e594,944d4bac,3314d490,d375e118,4e8c5a7f,2346e6a5) +,S(699392f3,c2baba31,1bfa8aea,180283c1,9036ea92,f287fc08,adb32fa,6785fefa,242acb3f,fcbce5f5,9dba097f,3d358862,11232403,2730700d,724488e,8bee3478) +,S(193d04f3,61eeec14,633c702a,f8e7eb22,2c3de17c,a0130e9b,cbfb3daa,94674d24,39b68a32,79e62533,8bfda780,9f0f8264,ed2ba2b5,ea9c0035,6459882a,a943e088) +,S(564387e1,ed778e70,baf9f876,2a0171a2,6a4e660a,bc6eaf1c,7ef9f00,69794817,7cf553f9,128d0716,e3c81039,3d1ca83f,1cf0fd82,7f7d4ff0,ff538637,34ef42cf) +,S(f0eba12f,b282171f,d20aef8e,192741e5,4469c5c7,bab13f51,7084d293,c3c294cf,bb0211fd,18229247,5238ba93,f6992d34,a41a7ae6,78750b04,fd34f3cf,af61f90e) +,S(a54b91bd,b09d29ab,f4cb354d,283c436f,a8e9cb20,d3a7fd35,e59f59c4,200bc13f,bae1af42,3459a852,bc16d45c,cd35fd94,c0033d89,5c86fdfc,f4fad5e6,3bec2cd2) +,S(a9294788,b2c9d997,18193553,403350af,78008113,ed58cbcf,a2816c80,46f75d47,dea8059,c24c1c84,44a0263b,2896725b,79c2c8a2,6d425479,f44bb7ad,225bed8f) +,S(b6967b59,ea3d2899,c14fd2,cdd4590e,68dce683,de275313,ec94d5d6,1bee65d1,67eb4a27,8813f69f,e5bbc586,15dcab17,11bca30,77327665,2fc333d0,52fd2a0c) +,S(ffc0f3fd,241ebede,ddb0c43a,a9b8fc2a,9e778963,1af8d54b,bf99c64,add0cd7f,203e3aec,321e40fd,414c002c,e5c6cf90,2f3e75d8,ae0e3604,61028ca1,e21da260) +,S(d8f86220,c390bcfc,f714ec3,8b6f6ee3,d37b41da,4026805d,6fbbc798,8a936ab2,7c0ad863,31ab776f,c22b2539,fd65086,2cfd2ba6,2f5d67a1,6eb957b1,8d812bf7) +,S(11295381,19a146b,442c3447,400b6e7e,9b2190ba,dd42a75e,24460ca6,45a3cb88,44950501,75662a98,793416c5,3c55febc,7babcd29,398d6099,23e1c3e1,92dac1ab) +,S(d7cf3779,236c4a8f,d592525,d30dc0a9,a3318c05,1823e0b0,43a6542d,f38d92d4,1f866df2,429a3dcf,1a285265,18308c25,262c1ea7,2aa2267c,39a315c6,dcd22ac) +,S(d2bb0f89,a0897404,25fc85ce,4d8fe24c,ca061808,e426b08f,ff49a525,137449b0,fc4c4bfa,2bf202e,4d10969a,2c4ca383,17a8c179,20dcb965,7de7aaa9,6b97ff33) +,S(832d95a0,cfb91494,5b43d9a0,4f037266,2ad4453d,353f6e78,47d4aefc,449dabc2,6ec0aabd,3c3981b,8ff55747,63bfb800,453f302a,8161de79,b6b623d9,253124f0) +,S(3a224983,f83c41d,33d3aa2a,c9d29ca9,55850388,a968407,664b2830,3967f25c,7cc31841,96c4fb8a,953602ec,3c79ac75,69e1fd1,7a263946,27826a88,7d651f79) +,S(81197d87,1452332c,2fb18793,c0ebeca,3d1b8a4c,f161b709,e3da21f,3917917b,56a0980d,1ed1f77,3c960de3,1ce4aad3,90a5ea76,fc410a2b,107ed82d,b8bdbef9) +,S(b8204012,c77ebdcf,790f48fc,4acb23f0,b03e5d40,6fdcf212,81545200,faa2b4b6,b8718e0,12ed5a02,16485561,8a5fb6c4,ee4db08e,dc9c1842,881287c7,dc7191b3) +,S(766d82f3,b602c418,d020596a,58e61400,20f58fd1,52448443,2f816dc4,8d437750,d17969a3,c71ea79a,3854b526,efd56f8,148b2d79,3ea3c76e,eb14ab7e,de5841d4) +,S(35fe7655,5d4c88c,dacad9ac,1bf125d9,924276c7,8c2ea9c6,a9c1ae87,52d1e323,9ce2d43,ef8fdb37,82a38d69,972229df,9b9c0c98,abad263,1df192f7,e0e75324) +,S(a29581d2,55efc206,4d1d1839,621daef2,ab049724,167ced73,7566f4cc,3a81f5ad,7eced1c0,575b6152,38db2928,964f7713,f65edd4d,c31a4b34,ae20b6a2,babaa8b1) +,S(d7787fd3,75473801,2370e71f,4d2575a5,b9f89e11,aee370ca,2660dff9,dc6a807e,2875ab09,bb1b2a7e,cc6cb39a,939e4a91,2ddb1dbd,5ca43ca7,93ac663,552ae91c) +,S(1fb6cf61,e8be4d39,b36578cd,8853da6a,1e62cc7f,29426838,a7ecf0a2,77395288,1c018114,2dfbefaa,6bfc2957,6b79c91b,16cf03d3,81285e2e,b74f71db,1986e43f) +,S(511e9c97,866e651b,c4e32e41,92f75019,42316ead,6a0cd78d,fa61e0f1,e76aab8a,2e8cd531,d55bb19e,886b86cf,f7105591,68a9507c,7d78d34b,9ec50f92,5485931f) +,S(74afe7a5,6387bd58,d5996a9a,9650730,44141ca3,1f5236e9,da977289,73c9d434,be7311c2,b4566819,12d13546,8ac1e26f,6113b960,3039c24c,5e77edcf,de452567) +,S(5b545191,25d5f8e,cfbae2ed,bb724782,d07ff380,10eca9a9,29ccc9c1,ecd0f04d,21126f87,a0cf1824,1040d707,4d37e8a3,f035471,63de669b,9f502fd8,92322dfb) +,S(5286fb50,1a525e82,a944d1ba,eab49572,52d86693,19af1367,eaa8d5c3,e73ee8d9,f2abec43,68f3800b,30da81de,5b81e564,f94942a4,9409bcb,a9faffd2,51daa0ec) +,S(7b01eb86,c102438,4be1f023,90a5ed7d,beea652d,cf3ef77f,92fd883c,f2993069,becae52a,915d1393,15435d9d,edb72e2f,fb9bda33,4b2e39ed,6e698344,9e1ef819) +,S(3955e911,874fd6d6,74e04ed1,ea3b43a4,486a0ac4,19735114,3b451c3b,3028a674,3552c619,a845adea,64951c82,75994959,8609a3d,2f691d0d,5947b474,4636e06c) +,S(b67801c6,d96aca89,22d8e7a9,96e95729,c4c29d63,180e4f73,dcf013f1,98eb0d29,876e3361,d82f58f3,f1292315,1509ed62,2e2a73af,d063466d,4af5cf1c,1ffbb150) +,S(1efe4004,1c7ddbba,1aade160,cec007e9,8abfcba4,7d292839,4598b5c0,1b763b10,d9f00f5e,d0868390,230168e7,c5839be7,cef8ebe0,b3b70d73,ebd92931,678dadac) +,S(2083d5be,389e4bd0,23f7685f,2ad00b23,e3687672,72183afb,d5d02384,36d122fb,11b6176c,c7554617,935304d0,4e12e8a7,4bacc20d,d438bf77,a1729a15,b424937e) +,S(8a9420d3,93ff0ba0,25bcbb4f,eaaf715e,4ab14281,85b2dd91,f8eede56,f3006e46,f48edd10,dff93031,2b5df63d,ec9c7a2f,ca373d77,65033de3,8a54d37b,2ab1f4c8) +,S(64a2e8bf,b42de0b4,b2dc8fd5,9e3b2c18,753b43dc,e914fbc1,478818f8,145891c5,82583660,40ebc62f,d5526ecb,9f952091,47f7048a,4004a0a4,7b08905,12ac098) +,S(eb97193,28c44e0a,3f2568bc,b99815a7,c5c2e7b7,90e7fcb5,a2e7f7d9,920404f,cfd26c16,e6709873,1219fdc4,aa8ed998,c6fef955,78d7908c,c72c04a4,4bcf305) +,S(cea3219c,e03a2433,f9ad8d93,73a6bef6,c1f30b3f,fa79d7cc,6ced36be,9abc9c03,13ea8ed6,a0dd8fa3,29bd7563,a34f3499,6442b03a,f2eb703b,d8d5228c,cc4c4e7f) +,S(2e1675b4,f00a0843,89b0587b,f0cb723e,1a833539,c024caed,36101cb2,bc4c4774,ec1d76d2,2752a662,5dafb3c9,6235eb94,f9af1286,2b3eff6d,2a0fb965,ad3173c7) +,S(b0eb3277,7c8d1b09,e22c9b9f,1c37e8ab,74be3c49,7ab6d73e,7fb6ec11,10602438,6d44054e,a4cb4a22,3811bbf6,6d2ab2dc,f7263d7d,6421a368,9a9ca4f,97fac66) +,S(48254bd4,8df24e2a,759c5ef9,cee30855,1c1f79da,b0a32695,2196ea1f,987b6d70,9c12a458,f39f4880,ff04b96c,72b8877f,b4ad0020,495626f4,1d9b32a8,84f7a36) +,S(e3c6dc6,cfd0b94a,57b3d34b,3a77f4f4,45328a12,764e4619,efef75f9,f49fe8e9,5c229420,500f2fa2,888d834f,a517188a,207d8f88,c98b7b7d,31484a49,c4d43a31) +,S(a8d9d9cd,def3362c,b260ad0f,3de51aa5,db066c74,4166d9ac,57db782f,656be9e4,bc696df,80eaccdd,bccc9ac8,960325bf,1a0e9aa6,100908b3,cd0c0ce3,43205db2) +,S(38281034,a34cd153,34b6fdc3,26fdc558,555147cb,534a1c31,89beec74,5a2eca97,f4371a13,a65de538,f31ecc5b,50ce4b92,d5dc5645,9e523851,f6fcdac6,5994b5e0) +,S(b745114b,449f0d7a,4521d7e6,728c89ff,54131e6d,8add9f3b,bf18edff,bebc6ca1,18678d66,781a9120,ba33e01c,ee3fb1ac,b7790f18,b30a651a,99b913c,e621eb67) +,S(5987629f,9c26a8cf,ff39955c,3144f4ab,c4d094c8,8270f3de,620fcdaf,93a7fa9,a554b7be,24e49819,f1256c9e,72b8d981,2aa5984a,c942bd81,5709ee03,67894a07) +,S(8fc9dd0,d84cf297,75ece75e,8cfd7c38,dc9f602a,b0152b01,982be4a1,f29b7290,ed128f96,2cf60503,7acdf6d5,9578ca8,9a232a0c,c432364f,2b661ac9,2a3176b5) +,S(c8b5b1af,90d64379,f2c02ac9,51ff715b,2978ef0,bc87f721,3edfd09,983ecc35,c295c0d4,964ef85a,59490ae,dbfd98bb,f6096217,d7633f0,44470b6c,a1816b55) +,S(b4eabf60,c44d78fc,298b2c90,6cdcf7da,a23d095d,867fd304,513f90c5,437775c5,82d906a1,2d10d6d8,e4c843b5,48ab645b,e6f32104,f07d8fd8,c128351b,e7b526bd) +,S(b19350e8,a5163076,bba0b2e7,2159865f,59a8ea83,b0154fb7,64308bc7,4d0bcfa5,29e4ca7a,554269c3,21a12b37,a4fd0fb2,d3e57ed5,4e79423d,f715bd2,ecda9907) +,S(fecf1ff7,663c7921,40f4deac,ced92484,8c66bec6,f4a5550d,c340896c,5543b886,b2621f65,d52538e2,92a50808,9008efa0,8f530fd9,a321bf30,6dd24f26,c9a1208d) +,S(ab70fe2,355d6d6b,5c5a3f5,a6bdb605,86372165,b8f07d2b,ccfd61f4,798dcb7,7adfb6d3,dd44adff,87ce3727,efef0bc,6fdf9f49,44fbd238,822974d6,dd57e8ea) +,S(5ae5d60a,efd1dae2,43df9d7e,ca025c3f,452b6c62,216c1c1e,8b315ceb,b94769b,d90d73b9,6e33cbe3,6d96c45,656f098b,e7e57d25,dd03be95,8b9cb2a1,d00bb434) +,S(fc51f965,bf8dbdde,b5fa4af8,7abee8a9,a380918d,4d8524e6,73f8501a,291eb96b,ceebbb7e,35eda612,47ad8c8a,5d54af8c,9dbc9bd1,194ba5a9,5844fae4,b658496f) +,S(368b51e3,778f8ddc,2d09e9b7,fc2808c8,ac793edd,244fe177,fe3229a,e5a6d919,5b3ff9e5,af4c6ae0,575b553c,c0ce17cf,fc4da66e,e19fc3f6,2d047007,e1716db) +,S(ac9c4efa,5f63ca07,35fafa0e,9612b459,1a764955,d435c14f,91717e42,26ec0186,5d4d3ebf,9a064670,e09f1d48,79bc9e3e,22198188,5610731,29aa403e,73d7777a) +,S(2b5f951f,360dbecb,9eb1d31d,b414aa13,9d9a7d7c,ed952a72,c0f93a61,d52fbc08,8d46f1b9,cb8883e4,cb504715,eae4326f,11187e46,de477dec,2108ccbc,2b3ddd35) +,S(25a3593f,9670924a,a35c2008,bd8278a9,a78d22d6,572841c,98c4399e,26f67cfa,3b07ab0b,8d400f1,af88561d,af8bb7c6,a6e4b7c6,a8bf5915,4cd85291,66ecd965) +,S(3f03be51,b35e265d,d9cb974c,4ac021d9,d22b2291,40016bb4,e9edf52,36193eca,a17df05d,e4b0e5bf,c7ecac3e,e3253017,cc1d47b2,9fd3d1d5,411f2660,c34932f9) +,S(edbe9bd6,f16782a5,a00d7003,488b9291,faa4f22c,9602c736,a3698587,995d25d,64569751,212d2f6e,c2e7a6a8,973be7fb,c49d7a0c,8857fe76,f9c48011,735179ed) +,S(1f477d33,1fb16ac7,45c29e48,77df8c17,83f69e85,5a111a30,e4717fc8,ebf85377,64c947cf,64a66ad,8a417bae,1bbc1cff,56826349,e024d3bc,bc4a9078,f4bda708) +,S(b8ef8b11,901602cc,9fd1559f,c4bd6bdb,22f9bb7d,8b289c6b,fdae85c3,e9aa3e9a,60b3594a,7349c920,33d816fb,295f41b2,7c4d1d86,b4c9d2e2,2cc3f4f,e603f582) +,S(eb6b31eb,198741f7,49e4b69f,85c23e4b,58e3223b,df8537cf,60a94411,f03e0071,576746c8,ba579896,969c228d,67a57cd8,8501e27c,773a3444,35b7e860,bec9f471) +,S(47193aec,aeae207,ad675228,f4506db8,40a316a2,6cdb328c,2af6c24b,bd5e9a8b,dc67bbbd,ca7cfeb5,981571f5,7022986a,4ec3e408,b641c34a,57b7cfd5,5139a1ad) +,S(ae3c9591,c2768a02,f99b0076,9c56fdf3,1a98fae,1eca3680,38698abb,1d44f961,ba9b0c42,90c2fb0a,ad84754b,e1c3fa0d,7e34f737,f3874af0,4ed2824a,46efdb24) +,S(178ef542,8c4cc38f,f088c383,71f0ead1,4e7b4423,6d90bc7e,9ffc3db2,fdbe9b9d,a5f01afd,74aa9324,b10f6041,27ccae19,24da7b23,72269ef,ab984fe6,ba1b347b) +,S(2df7e5c1,3d0fdda3,3ef8f69b,f0ebe1d0,8649b106,8c965d97,37a7e9b3,c13f4c92,eddbf5c6,324853c3,7d478864,a68d0b40,2c28ac46,295c00c2,2359e10d,d0693d94) +,S(671abd13,fe274da6,a5cb6119,f33fc88e,37ee1b75,59adf215,e08fcead,ee946b8,49d7cd3f,3b8162f4,a85787c6,91bc29fd,69eaccb7,1354bbc2,8ba17227,8a8689fc) +,S(b69fbdbe,e72b1418,6fab59f0,6b57d940,fb8cb5cd,92c53727,a0eed42e,532ed39e,71f488d2,e104d21f,c816631e,d774a714,94c0c609,c86ee052,210113d,672ea302) +,S(1d5b8e6a,25fcc50e,a4a5429b,6233e276,47d978d1,28a5f495,a66b1b12,d7cd8714,8428efab,d2bd23c3,2de8da3b,cb630ee7,ebe84541,ec3eff60,645ec4fa,3978a6) +,S(4844a10e,ffce265b,1a5338e6,a10c4f18,b95b0681,bd702e30,9a376e23,7fcefa22,9018e1d0,34bf225,b4826e42,565a76d9,43c868c3,168d74b9,33b34596,98b5192b) +,S(9567ea6e,231a9c9c,3ea5bd83,59b7340c,dff96e3f,d1fa7a5b,c56c88a1,a57d951c,507e21e0,cc59bab1,f2c38cb3,42b9f83b,f291992,a0c83edb,4cb62b49,6c54759b) +,S(60f2f714,71258f56,6de74774,eda196e,46a30d66,3dc0b308,1cbad662,72f07bcc,12588be3,f62dd2c8,1e485efc,76c754d2,de642f53,d3937c68,f058c61b,ed7b6c22) +,S(4276ad32,b33ba53,ef2ab0af,9fc42af6,6c7bb23d,c7b7a9df,9c00e1dd,f76b6283,9c477729,c61fccfc,a2dc0c3,c3a9ac89,b98f437f,bb221be1,268a6f17,5d0dcd9b) +,S(fa3ec157,f8186c36,3419d818,4473745b,fdd2d054,e0c16e1e,fccd514e,95c9336,a7864a68,91aec12c,fe8104a0,eb3cbec4,4a907380,11a3acbb,d5fb6680,289cfa2a) +,S(7d7d2728,b1db5fdc,38ad6a75,3f39df22,88d50838,b106475e,28ba6eb7,5248b600,25d9d454,8b505739,16ec7bcc,877f6aef,e2641eee,8f78f1b1,a7f74c11,40173e1c) +,S(8cb9cc7e,4ec87013,b6994670,aae06b1a,a4785c06,614ca24d,cb6534,6592ffb9,728c4a8b,36bf36b2,a0bedad9,144c3261,71df8448,e87d151b,d8bee067,769113c1) +,S(8a9aadfc,84aa81d4,46442635,d47a9a4e,988e64de,6fe8836,79b8de44,f57c0169,60f39bce,be18abd,10afefa0,2d076d49,73d9615,10017a1f,469eab8a,c15eab60) +,S(3ea01e46,3a9bfcfa,39125216,7b6ce771,5fb309e4,37d495b7,852be3c1,af2a0b5f,2b756a06,75da2633,b8d2650a,a2102738,d5918420,9c57dd64,7b4c6c2c,c5250252) +,S(a0683395,c5245bdc,24b2b275,e8c2a196,5068fda,253343f7,49ab56e8,93672c4c,7f25a7ca,92d25547,975ddfab,fe50c247,6b4855cb,8f9ec4b8,ecbe9271,779431ea) +,S(b8293e68,1e33b654,7d2902ce,3addaeed,2fcc021a,cf7ee396,9be12661,b2abfb5e,7943e6b6,fd0c90fa,824b1e8d,25d63a1b,c01f16fd,3c9e2254,e1dc35fe,416a5afb) +,S(412722e8,ba1809cf,2df25d5a,49c7648d,b19e42c7,3cc30b7e,1107ee4b,f0aabaa1,557a299c,38ef6a75,61d79a10,ea052a52,818ce67e,1b341c1a,d70b984e,8e41fa39) +,S(7a62c6fa,f4a1f6fe,4a45aa48,a854a16d,a2fb19a1,a5647e3e,28a35d0f,619b2844,dab31641,6241ad42,3e7ee774,acb52a96,26b4b6ca,a4ea0b4a,67a513fd,9637dfd4) +,S(c3915b0c,19df99,ac0ef05,3a07b36d,62643630,201073b2,8e3ec588,6714a695,8f21f136,3cb4ff42,a52f74b4,b10f1dc3,5bcd782d,b477ecf6,38866d79,541de3bf) +,S(2a373fd3,ddd12547,3e30efe2,5533316f,355dd52a,6854d7f4,8144d19b,648f4b59,2ba90aa0,b3de3887,c1ba231f,49b28294,677adcb3,2e81c2f0,3c563e0d,221260a3) +,S(d8729e12,46cc8a52,a5c9b7ee,dcdf4d3b,3d0ff8aa,6efafdc5,ddf37480,2dda4476,1966d7a8,7e527a7a,bc1e829f,90e4e3e8,f4a7df30,48f098c0,df8a5eb0,2a8bc40) +,S(ce45fb7d,2ccb83af,dd1662e0,3ffec83b,5173dd2e,448eaa87,edc980f9,10a20dfa,5973238,531c5a84,1388c656,3d4f3579,41283e31,44d84ea3,31374d8d,e2122244) +,S(230a69,f0fff585,a1163702,4b16481f,65bf27a5,3ad7992d,47ec8ff5,edfe073e,61ae3fbd,90f157ba,6332de25,a571777c,30d8144b,e12d9a25,42bc1877,1b6abedd) +,S(d7f91496,1bdd4fe4,7b538429,df2bee94,cc4d66d9,270da392,a85e8c62,1527700b,67ee9184,bb2cb2b,9671aaec,57634814,b6a1a9f5,dd0430e6,6c5e2774,5afa9f13) +,S(4f2e459b,3eac7349,41cb81d9,2d8b3942,ee7b0ded,b2d9d8c1,90ff390c,aff7e4c3,4188f6be,c3526afa,2b29f953,f5044bf3,8e583c27,395c9f8c,979ff539,b4198e17) +,S(8a4a7b6c,3b598e42,851b0913,209a95fd,edf0f8be,6f152b33,1dac61a2,6f9b6997,53c457a9,f8926415,63e85b0c,b39ac9ee,69b31c65,5e3bc200,d37d86ae,d4291997) +,S(a48f69c2,9dbbc922,78a5f8b4,4a2fa2be,f432a4d1,e6fcfda3,8ad60dbe,6d157990,f251873,152f4ec8,fe5fc88b,cdf28ae,acef895b,1d0f0ce4,44105e14,7ac0ff22) +,S(fc0ec54e,20f7e8b1,fed5cc89,d18a5004,b7aa55ba,7520dc18,c9cbd935,7c78eb4c,17374d8d,36116ef6,49b723af,62a48350,4bd47bd4,c17c7990,fb0e119b,47f21ba8) +,S(8203924d,9fc7e5d7,6e3c593,ad439d3f,8512c0fe,5c298163,c8caaa3d,f7b39755,a224b743,258a82ac,2dec871a,dca1dafc,2bfa8e33,b2217785,2b97e57,2e1344f7) +,S(c4f66a17,a595217d,58d5b5b5,da997a7c,79b870c0,f5fa9dde,e146fa5d,c21f9380,13bc8ef7,ce6f915e,fd7a3522,f5fb9c3b,ac603d0e,343d344c,74565eb9,e8e3c777) +,S(4341f0a1,efdd7d68,435f1998,559e43b7,7d1c6780,d3d3e7e6,212efd96,5b30cb47,1777a450,1a693970,c2bf759b,a253e716,b17cd5eb,9a247d47,cc382424,48ae90a1) +,S(865d8a50,ad3b8c21,f8ff0e92,8e853789,a607abe6,e155b04b,3b81d80,c97c29d4,2a506b83,c4166a1e,fdc32c2f,b2d027e4,837d9989,a82d08ee,a31a46c9,dc72b272) +,S(d8d95cfa,ac50b79f,3189093d,50b03b38,3b798532,3f01ba52,d76f033c,83c832e2,cddf6560,d9942228,5a3c0f18,58a7c27d,fd7b8bac,9b23477d,8677a1a3,c01a8454) +,S(d09fa59,8ae65883,60247b05,519aef86,2b1c5196,d38aed11,e8350fe0,5bfd6cd0,45f51a97,67445680,37b1bde9,86696834,6dfaca49,719c5174,a9f9eea2,92ed4ab8) +,S(e19796c9,c9b48a5e,59556b72,9d9b8073,71cd7267,812b044d,637aae50,d6d3d1d3,1b86acc0,d904a31a,b5637e18,872eb31d,32617930,2f3d6bb9,36016653,9f218d89) +,S(6a88899f,be0c3c82,96fd27f8,6f89283a,f83df13c,a273217c,fef69d8,b048afb8,68ba38cc,bee044a7,a026ada9,d51e8d49,97083dfd,f65bd483,a45eb58d,5cc774b0) +,S(e5082ab6,a112848f,9f5f3362,8be3e267,87e24cbc,6d5563c0,7addeed7,ee44662,c3c1727c,d0c09130,8323326d,210a68d3,68bcbf81,bb3814f,dcfe6631,d42968da) +,S(795f456f,5d0cc15c,72ea286c,c881d8a0,21294e05,cf80ef7f,4497caea,92235487,bea99154,424f54d1,e91322cc,c52d3a51,4627fb1b,2fe9062d,91d90177,20530ccd) +,S(6e9e5f96,8c233f4d,8d2bcb8f,25d9232b,f2230e9e,fbafc89c,dca17498,8d7909ba,3f8b0b0f,e60aaf3a,89f5de79,35f9979a,ac3f3fc6,fb161d3f,29ab2ad5,d50411e2) +,S(72ef1e88,89cb7f22,19b4a7ac,92d5678e,a04c898c,5b83128a,1f7fa8a1,63772f28,dffb88e5,3f348c29,411e4d47,3ccd7d41,8a0617a2,6a640a9c,4b03aa08,15ab10d3) +,S(4a91fcd4,32f6d2e7,ad20787d,749524b2,e3e1c348,31b41041,c311421c,1aff04f1,bcd9108e,6e8c6da6,a15156c5,5c9d60be,e4aecad3,b0756cd5,81b1eaf0,ad300b9f) +,S(5f5255d9,8c7465d6,63fb4507,ac985629,8a434d5d,429d5a9,7b645256,e2cebab2,7c38536c,31e7331a,362fc944,38510aed,bad4cf29,bf0e7cab,c995ac6c,1fec04ec) +,S(866b5f8d,a735ab93,e84f7811,a33f1604,40a51373,7b52e675,7f212c8d,65c9eb05,af2cfb6f,9e32f412,5f1c66ac,61393756,b8c6016f,9d45a58b,43e16c6,d3549be5) +,S(636aca,387e767f,4702fb3a,d7b50b4c,4b40fb78,2c8c44b3,a298051d,bb3a71f1,70e580b,6993c9ac,5a48c2f7,558773c1,f5c4ff3f,aa929635,a2a44e97,c0eacae9) +,S(31a28d8c,2205f5c5,75ddd861,df94bfa,5b6b6e38,83797d1c,7d4a487,5fcf7f7,a790eae6,788407dc,89df860a,9ac25011,8b8c65f5,f47e0bae,6aae95ee,2d733698) +,S(c7f36e08,bcea178f,7acb0b92,fdb32411,a028ce88,be5e3480,a47c2c88,891827c8,5c285010,4742764e,7df86e80,e6e2d975,472abeb1,bd5664d3,a994289c,112a9e9d) +,S(85a82c69,2a5e248f,42a3f0d3,e092840c,de52e31f,19a2a161,85b2ad10,6afd92d3,eeec281e,55c79f17,332c4ce0,7ac4edc4,a3d75e67,558b4b3e,4dc86532,6132155c) +,S(e67482d2,4c2e3a75,3c1fa968,bf120a4b,7883d00,950bb0bd,ef5472e0,dfb09287,f9801b51,e0450fcb,9e405ebf,cb535355,24db5e9,91bf1572,6f446aad,34ae4194) +,S(c6ba17e7,81fad656,c9c93e54,36409414,c58e2761,b0297b8e,1811dd68,62779f1a,92583a9c,515a096e,8691b384,4104419d,c4e86966,4da70b3,afcfceb4,b9d74c92) +,S(67cf02c5,a616b59a,ddd421dd,15812e95,f36e6d16,af501663,9e60dd4,a8706b24,7856ad72,8a5f0d18,bf4bc3d3,75468f85,7bbdb1c1,206fcbc4,7ae66b5,6ac91b29) +,S(72bb64a0,aa8c690e,7bb6ed99,847488b9,f37490cb,a7fa120e,a7b5df10,8fce4b61,6057c37e,198f6428,3b9481f0,53441e97,dc827cde,edc55410,5108fdba,a14d81bb) +,S(1b132067,209e179a,5b77977b,eb81aea1,c480b32d,81729c5,32d100df,310575cb,67482a94,b5ddae4f,cfd613eb,68680dd6,c8172553,18478bf,79b5c07a,b0cd817b) +,S(96f5f126,4b68fd7e,f633330e,f32951c0,3716b62,7d1f3368,703447,f9dbb5a0,941fa02f,c6262bcf,dccb1cdd,1637c9cf,719077c8,1b26e7e7,2bb8fe4a,4d530e19) +,S(95335907,9c15cfa4,a674ce65,113127f7,a1ce740a,ecceef55,da5ceed8,e4e56a51,57ee067a,5f506b14,5c1c20ad,6e5d6b11,9bca103a,60c2e6e3,b5049b4d,db15baa) +,S(72ca7d41,76c687b2,1125c290,e737075a,3281ce7d,76b72725,c7680956,e0463f23,1e6a85aa,246b0f1b,324365fd,19809840,242fef0e,6d658cae,cc84bbc3,ad56af44) +,S(d5376a10,2cf819b3,a439feec,b04d9fa3,c90d76c3,b9bb749f,bcd6aa26,39ed5ea,3659d2df,266a0ff9,c2854f6e,f5a5ab04,1c0d8547,77fd4f75,320e064c,c4d0a4da) +,S(664a26cf,a965b59d,10c05dd6,e0aa4e6b,c66f356f,bb61b699,113a83d9,e0a2b4ff,fd191a92,c88d577e,47e725eb,a3c38b3b,9074bc42,16c5d6b,4edb3af7,2c4e20f9) +,S(7729abf,ecf9ca40,e8867936,7fef2d84,29bd877a,56f36780,1e677273,8e8cba7e,d5cb7517,42c9de11,84dcbfb7,5c9e139b,a59b6255,b59c7ef8,539de55e,7a709d36) +,S(c6d5f50f,e8e784db,630bc589,b4df5810,a2001482,9ca1608a,cd3e3634,7bd8141,eedd06e7,95d063ef,3d1627f0,bc7ef37d,a4846580,61e472b8,89679d3c,d88ab294) +,S(baa60dda,3cf83a11,82dc2ef4,f79d362e,6b32304f,896d30a5,b363c639,56ec70d9,cc9e6274,75feba44,b93451d2,753e94a2,85315277,7674b3fb,c67490e5,3627043b) +,S(370243c0,92b957c4,74df755f,e0951321,49dd3669,1a89fa84,e43a0668,8ca235ff,bbe8ff04,6600f245,349fbf3b,1c8ff04d,8d51185,3e35d13b,30deba91,84383ba2) +,S(1182291,92b1e768,2abe56b1,9f90e41a,c882edb2,27b25559,ce4448cb,dd19ff06,24271274,e6156ea9,e3f82ba2,8a72d476,8509dfad,b985c200,244687d5,8a11c1be) +,S(dd134e0,e4fe672,38716aa4,edba1ad7,6879be6,8b5bb029,b32704b7,9edfb2b6,7aed5398,40cd7dd4,7e94c224,151627a5,62f6a519,2f0d0b5c,416e6f1e,5e8a337f) +,S(ab7e722f,458d3acb,ad28a29,2f90cd8f,c2e09b2a,2beff3f8,f08517dc,e673e3a3,522a2227,c724f9bf,1ae08d93,c4c6ffc2,f5434173,7fbfa502,d6e49b1c,2ec4c792) +,S(2fa16842,ebebd6fa,e6c67327,bd5fdcdc,7e985b1c,22dfe307,23a9e2dc,ec43df8d,f027937c,9624aaf1,ccbf7c58,66bdd9d4,5bbb279,c2a37813,9166b720,32030773) +,S(adf5e014,e1f18c38,fd1863cf,76a6dcfe,65827107,fbe0eb99,117a859b,c5268bc5,c9cb3584,728b1771,16985b28,f5259aa5,279e15a8,1c1cc6b9,2b9e5f8a,6206961d) +,S(d939322b,a9b2cff2,6a2b1c4b,5ffcd96d,822dde66,ad0aca31,c24a8260,c9fc6d26,162fb654,6118a68d,7fb88bdb,3e3ab784,9278a5eb,13a940e3,3228580a,2258c8f5) +,S(18fb2621,71f79e5f,46c0087c,ac8e55d9,66f29a49,e2c91363,58900787,3d7e3a6d,cac82dd2,4a0f75ee,adfe906e,ccafd36c,5b0c97d9,cb150fcf,d08b28cb,83787a05) +,S(b8c0ac07,5d009e4b,5ee44298,89864cf6,fd54092,df835ec2,6658c902,57b670d3,2dbc6d4b,6ff28cc1,14e1f34d,2b6cbe52,7ca7dead,24f84681,4407c4e,a0df0bdb) +,S(6477536e,43a3ba01,8988c8ba,753d732f,9ec061a3,49f7826e,2c426ae5,3f2232bc,ede465d7,6b7798de,832e5f68,512cf3c4,d17282a5,ef88725b,36d8af1,5c5d2679) +,S(55b052a6,52008a83,41135e55,ef7de2b1,33eca8b9,ea0c4800,ce4f8019,5f7067db,a823cc05,63efbc19,d47c2c92,5771497a,ef6377a3,8be0d23c,81a56f06,25c43e56) +,S(c86a02fd,becc3647,16c58f5d,f3f150da,6ba86499,2df09dd5,82b9653f,10cc9289,263d1b5e,eff52a27,1a9c46ee,8adf1194,1da9d3bf,e69f62b7,262099af,43d6fe3a) +,S(23c659e0,3a59381b,3d47beea,60f0244f,66af0596,5f903297,c53aeeaa,d143e90a,1c14650e,3aa16bd5,b67e6077,be307cac,2bd2cd39,b246d6f7,216d73dd,dacbaf64) +,S(2f6d8482,734aff4e,21094c39,2c5fe833,1c8f9756,4de252c2,f6f690ad,8b2fa9d,8b143db3,7e14b40,3fa98a74,a81adc79,c34f17ce,5c9e6f21,68770957,1eb639ae) +,S(6d58e265,d6b08c0b,b050ee18,5175a9ed,51b5c64f,d523ab35,ed1457d2,f9caf153,d0675517,eb71ed0c,4fbb86c6,a2b4a7df,259a7795,3293777f,3a87f620,2265edee) +,S(4af09f2f,69d7b9,6676f472,d7f2009b,f0bb6f0,986f502f,322afacb,7e9d570f,1f93342b,ddfe5896,52e8b64f,a348f333,5396012d,3e870885,5b31024,f14f8e7f) +,S(813e446f,87d923ab,ad8b8649,71b1ca39,d00217f8,232a71cc,d6346798,3a9a0e9b,8ce9f4b3,541a8029,f1476728,2bedf1f4,367ff257,60f2ccce,7b273b2c,dccff418) +,S(53c4fd57,ca0b1eb8,7f5ca0f2,3ecae8eb,c44e9c19,aee3477a,3ca8524e,dcdefaf7,b3db3613,aa916430,a3227d73,35bd0532,74c122b8,18e4ac52,858e513f,c3ab95a4) +,S(e0f8afc2,ec89411,d926355,2c33af71,328331dc,9c9452fe,b0665c39,ae90121f,13523c16,1a00784b,f15d2867,15cc05ec,227248ff,80082e73,ecb139e8,f229eb4e) +,S(fe3efcee,6b82a5b5,a8c9a51d,ccc11f01,ef8f1a7e,588ec4b,17ba1369,cc6bb80b,be17246a,4d8660ca,98d57f07,ddbabc29,650f9a89,9da60a53,d21c6c96,dfdee15e) +,S(8a5182ea,591089a5,11ba9f19,ce4fe062,31b7e2ce,ec4cf75e,5c11094b,9ddc8de5,73688cc,f13d97eb,19a86c2d,8b010406,1c69ca94,fc9ec90d,8ada10ae,37503600) +,S(2d95aecf,72501ef8,e20bc117,22dbcc09,38c552f8,f4e0596c,9974d62b,a99fc884,7d9c418e,e1745ac9,e8f5e4c3,9ada4400,e65acb22,d336bcc9,fa2cdbe9,97f7de88) +,S(7908e4f6,ede4d311,3dfaf114,9bf6e40f,e1f8e33d,72094448,5105a113,21d18b80,11d92d74,9b011e83,5e06d7e6,1103cbe,bf958d8d,bd47d0b0,1ac2ad22,2f7d275) +,S(2c6dc24a,687d8437,44baf725,c75e7524,c0e6571,f32817f4,40183b6e,cbaa9f95,9692bdaa,775b832b,48584ccf,713421e7,5074f1b7,ed5477f1,4335db2,7abf03bc) +,S(a019d9a0,4a9780c9,43dd65fb,b87534cb,ab7c0831,f845e724,d663578,ec7bc090,38de35e6,faa2a1ae,e0649333,898a6ca9,264dcdd5,ad9f289d,ef750110,9bc99d4d) +,S(ced934dd,5c15335d,d050af1d,a8295d2e,bd9b8272,58d689ac,f4a48d85,5ef8a0d9,bc0c9237,1ee7fe7b,69c7c100,e5258c9f,1d68b6dc,309736e4,e05718dc,3a49cb6b) +,S(65e5ffe6,502ea7a1,47fe9c98,9cc745a3,b5262bd3,888069c3,92d1d1f0,a08dbb83,c80ee080,84dc5e65,de8df271,c1132cab,b8be293b,69a390a6,fb3932e8,51ffaf38) +,S(f4466d47,2365b665,6d1947b0,6e67e393,4c0e4f3b,91d52ea6,1f4588f2,4d217655,17afe3f7,2d384ccd,9beb59c3,d64353ba,57713f03,b8644e3c,eef45db,c74ae84e) +,S(66a80bd8,ec0d08ef,3d9aca5b,4329198c,b949ce84,7933ef2a,10baac28,dc98cea,7457685c,600a707d,5fd5d527,9f309b9d,5b14e668,1656869d,b041ba77,97029537) +,S(240e3632,7c3f4c63,afdb84d0,8586bf90,9b359c8d,7012f9ff,aec81986,4c44d597,a701b76c,d369e013,7b627216,f75d0ec9,fa208b66,2d7075bb,a6b6d39c,6a1cbb30) +,S(137f0df8,cafdb26d,36e1b57,c427ce08,444516da,ad1ca806,9dd60e2f,2ee23f92,c2922219,9e4e7bf2,f9159138,13e68273,6bb6a998,6c015caa,43cd30a5,aec74a49) +,S(965fef87,a63bedda,fd4b2e35,e1d0baf9,17d5850b,1f6beca4,64d4fae1,997d3a41,5f19603,369108a5,c599ce56,22bbf02b,cf541867,a57cff2d,8b527148,30124ed3) +,S(1e2ca98e,519c60e6,cf7ff3c9,51cde109,209188e0,6c68f4dc,c22eacf1,34a4125e,edaf4c8d,8bb97032,89f9fb0d,d0023783,fd35e779,41773a00,fb4289cd,ef8411bb) +,S(e8e0e2f0,378595db,68f96e6a,882752bf,df039778,e261375a,47fd4394,2b68006d,75b42822,1e2fbf9c,42772d35,e4bf1e0e,8d3b1ad7,92ff25ca,a488b51d,4ef7186f) +,S(a405f5b0,28e89d81,79e7fa9c,2ebac86c,ffd20ade,60dc5226,cfe6c91e,5c2f6634,c27ea4e3,b0da9e58,665f507,84225107,7893d6cf,5225d5d8,a06f68d1,1d863550) +,S(bcbc3c77,7367168e,169f3fcf,dd2340cf,9e6af955,d6038a0c,b763f036,6f4564cd,c7c120cf,99138201,40ec5339,ec23f5c,1ac0dd73,c9f947dc,e19c034f,7e7a502d) +,S(fd569bd5,14843a2d,e86ab2c0,475e0c67,4959c04f,bc230255,db3e82d1,15cb0758,aea9c73b,bc083366,fc5e31fc,90a1da72,66a9c43a,9d16f6ee,67bd56b7,9c354cc9) +,S(c2fdf561,eca2e3b8,f1107475,9cc43b9a,789ef592,e8afe885,d88b9dba,469c616b,678f57fa,fb2e42fb,bd1482d1,e22c866e,683e4fa7,6c1d2714,6540610d,9cbd1360) +,S(50f20965,510b3317,2836e1e2,d6e00ea6,160a9c71,2aa30bbf,ac527c62,9d8f4088,fd9852c6,974c603,7e88bf45,a279b565,d1246924,e3c4a0f4,8877b716,69b68141) +,S(3f293417,1e371e20,cbe0a858,e5984175,ba465906,fd64a7e6,161c8a7e,5847764c,763e8dbe,571ac3dc,1e803f32,7e2f4585,7268774f,1a45c50,9390dfd4,96bd374b) +,S(8276d399,fe32e931,65f2ef6a,2f4198e7,944bb9a3,226b1a55,fff52dce,d2b92b3d,e955a591,5c496a1,623466be,88c45a3,f545527b,4edd4283,582c03f7,2a2d897b) +,S(e77e7701,f4b405c3,5c8b7a6e,ee7d0637,fa1f566f,d2a2cb64,531dbcc6,19a9e474,23fae4c0,7661e588,365ddde2,63b97f2,cca2023b,c70633a1,41a2eb,1d3799cb) +,S(7ae8112a,732d6428,25aa2eef,10298300,42939628,69e7eea9,3fbc7b3d,2c5210a2,3590e349,f878af6,7f7754f9,abf4ffdc,4d4f4442,48c1e039,6071271f,be5971ce) +,S(f9fe96f6,8e20a422,5b563483,c1d2389a,ebd8a97,b1b9accb,ed7bc51,8077771e,cf3802de,20b5ae42,b1d1db65,b033f2e3,602ca08d,972eed63,9234e1c1,48542478) +,S(b9c5eb6d,ab28292e,49a76b34,49cf903c,dfe79b85,f7797623,924a4295,bf0cd171,adc0a5d8,18926d8d,7bdc83fc,72b2ed11,19b87592,900ae961,ffbb165c,4d5bced1) +,S(b7e25a76,3f3b8bd6,1c57da51,bd90ab57,1df3fcab,28003104,30c44fa5,4a6a5765,c471aa74,babc3fb7,dc80138c,83940e42,961f80a3,23e9741c,c44607a8,258141d) +,S(5808e4f3,e01937f0,e9c887ff,8ea3a34f,8fca4d8d,7868a9d5,7de6d854,a0582d71,fee8cfef,2d78896,55dc9560,68e1a23a,4308a8f7,7962c2e4,f90b2ddc,87f011bd) +,S(92ac7dd9,8da0a4e6,60964943,3887974c,5ec4b32f,875c02ba,1163d06c,b424793b,857b2046,8104a986,a0030596,62039e60,71c8f950,b7f7f746,16fcacbf,b8eee5fa) +,S(5c38092f,fba5798d,48d0068d,d1037563,1f40a693,194584fb,7199c409,b85d52b2,32b1d628,15ee2555,f582f16d,d59c4658,67691e1b,389d1fe3,222b5444,294ab391) +,S(ad7beb62,cec8aa9a,b619693,eb40c477,53e22897,a0007693,f10ce664,21d5c15e,49f98176,a360297,42402a93,26e34a38,cc837278,3873b076,f887c811,e2bd98db) +,S(aa335f87,c61f2e9,7d87355e,2a1c2e51,f2a0ac92,1cfd3cb7,5189f256,386ef185,b39741b2,fc158d6a,435bfa8e,1a68eedf,13deab27,388032fa,fa22d649,c9c9a8a0) +,S(854ef509,24fa2fb4,9b7b7b49,44ad8c9d,87627883,60ce8bd9,36e64f12,a550356d,c5af2246,96c7e32c,a385f7e,3eb8326b,7d9e3537,43a95c8f,3010a160,1d6f534b) +,S(71b6366e,42a8e2c5,31ad6770,ff01481f,5a39c54a,d38e0ac6,f068117d,8d5c9d5c,d6684df5,92f085cd,aee8313,59bbceb0,1a357edf,b36f8e14,706245ef,f01db334) +,S(3a4d1869,55b698d0,5e760d75,8842bd1f,cd869e84,c2c29e44,4ca83bd0,3408d6b4,5ddd1b14,15ff793a,80fc196a,83ff2736,e9791418,fba7eb98,71b51269,170d9904) +,S(f596d242,7e51e5ce,403d673,cbdd71b,75550271,dd2d7d93,79883258,9d3c5739,cb9ef0ea,f6326a5f,83e40428,79675f81,188763b1,ec06fa26,3d7793cb,82b4ceb0) +,S(4bb25028,b5598090,15286b2a,a8858e52,227f3b11,9075077b,3083fe16,77efd4ef,cb63c7c6,9de6503a,d33ee35f,95d4533e,1e978f30,2762b478,e88d18aa,5c4ff098) +,S(77c7c018,4c89f974,df648e0d,ea57ee40,73acd63f,c6e22a55,6269ca4e,a5dc1c99,978faba,232a2b0a,9cf3de55,976ca950,ce3f197e,e774b2e0,d4bd1e5f,e65a1b41) +,S(834d038,926b1ff6,13dc9001,7d021bf4,5bae5,d3741460,db681332,61975c30,f5624b83,614f5e82,10190b34,9f966fde,cd4eeefb,e3e6b046,b3028d6c,3807b475) +,S(370045a0,a7f8a64c,a2b9c64e,85a07fe8,9a7f725b,2cdec8db,258b3d3a,d9cf379e,cbec192c,cfc58b62,6b89d6d3,9b4bf622,81e308b2,2aa3ddf,51d45561,37b1811c) +,S(61302164,6103ee82,1c3103d5,f4d2aba4,645816cf,a67d94d8,ca53dcc2,92ca36d2,935e3db4,5ee1789d,ed8f0ded,ac0430e2,7317f38a,87682850,9568feb8,15e20a1d) +,S(4d6868cd,4df5b1eb,8d27e045,ef04209b,c1dd0bd7,aa712937,8f7bc025,e569d90f,dc0079be,850ab0ab,ef9881ac,740140c6,958e12ad,edfcbd79,2f446d78,7157780a) +,S(43413ee9,a35c7c44,bc95369d,38d9e7ed,53175f17,6f9eb54,6df98540,93105549,9eaef64f,45b421d1,ee80731f,ed61f658,861feb4c,72b5b2b0,ec659825,63172f7b) +,S(1e728340,95183b28,a443e00d,6ae01921,75844d9b,ffb1c77f,c00d388a,80a6b76,d1931ac7,fccf26d3,a2ef72ec,e8c7ecef,c51ad264,ecca5748,7e9cfe5e,d798428c) +,S(7b5995f0,fb0b8246,c588e393,4499404,415f0d03,c9174317,6cb2f4ae,b06960c0,716c7849,b6963a9,f1a7998f,49cfac4c,42a329f8,77d7c8fe,5b35f958,ceb9c0eb) +,S(9c5efff9,2be6057,f5223d41,87fbafd1,a59c364b,239120a2,fa1c4596,4fdad960,4f4aa66e,e42548c9,4d6cafa0,81e59ce7,ab65cbd,78027de6,b1edaa,25e6d7dd) +,S(46970472,192c3690,3c7bd061,dee19fee,5f3a973b,a70430f3,581abae1,3a61e55d,4d232a77,62e04a36,c62894d3,41665ff9,ad8ba55d,353d52cf,44f392cf,7787922b) +,S(add62a3e,583dce2c,55e97257,b64c26bf,5e86b0db,92962b3f,a54e7c52,ac00b32e,3c700f82,c5365611,f3cb1ca9,cb6b0c2a,dda80e04,617142ef,eccfabee,178d3dae) +,S(526115b5,34b212fd,9836a98f,853ab3c1,24bb68bf,afc1d641,b47d08d7,39566c4f,29c983e6,2a4de19,4efa5b2a,9cd4971d,6a86c8e9,f535d599,ee04db95,120fdf4b) +,S(87908ac3,ee8f4e5f,31aa08c0,ac97e93b,81ac75fe,33bfbff0,7d4f0934,7c911f45,b756def7,52c71c51,3f69235e,8d515d6b,f3289a5,a579b999,a695a2f6,49586ba8) +,S(2d6e6ed5,d2ea8912,6797b396,8ac1b0e,f876904b,acbace80,a2613b35,d9bbdd11,b1b66613,50ee7a2b,d149ec9b,25a502a1,6ba6143d,32da00f3,13cc389a,7c0e480b) +,S(f076c9e9,8590180d,dfd36cd6,160c21fb,7dc60263,77435e74,30f74cc3,c46533f9,2c9decd8,6da7b49b,1b4d0a8f,47aaaf9d,19d9e8bb,365c383b,63726f64,ae56fb98) +,S(fb52489b,6d101de1,2f51720a,60a78207,84ab4dd8,39d05c9d,a3b9c349,a74452d6,f1a967ae,deb5329e,faac7381,f3f0bc76,9eb8cc89,78d5d56e,f382a17d,4c3baf4b) +,S(dc1e911,53b3435a,8f23cb08,a7b52f64,a5e2870c,9345896d,ab4ab880,9710241c,3468d632,eb3a51fe,133381ce,2b5dc9a1,64f8eb68,9c019b0b,7e48d504,50e85630) +,S(2d8c6759,6c7856d,b7062c63,2aaffbee,46779bdc,777f0be2,a64093d,41d4000,c7006eca,b64904f2,9cd7baaa,14a5226a,e5c4b3fa,68c62cf,65789066,2eb8e8ca) +,S(31e9d361,fa0041fd,bb73665f,2e1541f6,c41764e7,78023272,478cd7f8,e9552f06,62fdf441,4effb45c,5408a0dc,c0a78041,cbe39cac,562659c,ab8c2b89,1a940c11) +,S(792f50cf,66aa0f00,68bd7fb,ee12bf44,e1fa6662,41c43d2f,275a248c,29459830,633cf86a,a3f10f31,40aaffe1,d04ee094,aad1cc56,129149c3,2702c33e,40d91e3f) +,S(be4f52ab,8f6ad1f0,664e4d28,b67be76b,c3d318f3,9f455708,94060e03,2f8547b3,22ffbfca,44482e40,19ef36d9,209b4262,48d62591,7d81b6a1,57ad945a,1878b4c1) +,S(bb693c4f,7110d2d3,8bdcd6af,d8b29b43,80d003a7,d0f6420b,e8d02cec,3e7cf385,3bdfb9c3,948034e9,31904f13,e3dcfa78,13d3413f,5c2daebc,744bac87,9e4314b2) +,S(56e8a65d,2eb188d4,64dd4280,b987b5f9,8b92b8e4,34b6bb1d,1800fc4a,f8f2deb5,11cd5d14,63777189,f8c7d19a,c692461b,d21fa20f,f12d1976,3b915fa4,33006cbc) +,S(f09d5cee,514e56e5,9566953d,f8600a94,cbad003e,9c898261,5bb998f6,a5b8cbb4,d07ee0a9,a0e88f5d,6da3d918,d5f309ca,7234373b,d528cd8c,21ee9ca5,3d1bafd0) +,S(58671c9f,687ab0a6,f6b7c687,ef546765,7f29ecd9,d6250088,d588742,7b96fa6c,70355403,abefa39a,72d89348,9a8251c2,10d59df,80b4d284,f3f02246,f3f6c60c) +,S(e47ec1f,8a7169d2,9c05cb96,42ba126c,aff841f8,c2edfcf,25ec9303,772eea78,ce97644c,ca60474,4c269973,fdfbf169,bf0fa377,61737dd3,77692b9b,ac775c9d) +,S(ed95cc7a,a24a4ed4,1dfb019e,31abc80d,93ca5c04,b0515f2c,492e9105,efdb12cc,1602bbfa,f17e8c16,30ab470f,bd8fd829,b4a466ca,9f210904,7e0903c4,e012d789) +,S(b6fa3ced,a07a9cf4,db717242,9de8069,216a7b51,4145470d,d811755d,a2908a2e,64f695ae,7f19c7d1,17af6ca9,36dcb2df,8715ff96,c8134313,c111da69,7a354dfe) +,S(2e3047cb,4d210007,39b8d5ce,e4884a5f,ae969eef,898a600c,2202da33,239b3627,197f37c0,7c11943e,40328e3a,3c7c11d8,f2d77d16,84532631,53b7cbd7,69808c9d) +,S(df9c446,7a691cae,b8a01ec1,a4a8ebc,fbbacfc,ca347aa5,39d56853,c14ecd3e,acf9554e,906e86ba,8459c108,d49f7aa1,e1e4b2ee,9957101a,f16d43f7,7dfaf6aa) +,S(d452f3bb,2e3e54c4,1f68267b,f846f504,99f39f28,5edb86cd,68330ed9,510aff54,52c5d16b,41eb1029,7f86a30,28d1b610,6f6c5aad,61b63bd3,53d95b2b,fd214755) +,S(cc196d06,9ad60096,c4ba1057,fa4fcd9c,4a50b28b,78227074,22d531b9,dd85a5be,bd930456,14388283,b28cb67,758c792e,5f9d6c0e,2d4c1a86,745e0504,ec902b24) +,S(4974252f,9c246a45,1187b1b6,546cbf27,af9c21cc,d03c7b37,df7a604b,a3b6859c,276e69e5,b85e3241,33f9ec76,d628fee8,3af37bd8,def6e677,bba19739,9da14305) +,S(311548d2,d9f880a7,17e77608,8574ff4c,185cb0f0,a9660ef6,7a94d090,3e2fd845,82b2dfdc,2d0ca2e1,d403c1db,7593dc01,2043122a,fb50961e,d5f86174,18a3d7b7) +,S(30068568,4497d5d3,2c98d3ee,1136a9af,d5bbc79e,340528cc,4e0b3c55,74e867f4,57c141af,fd650050,79ea563b,e9ebb161,a7725bb8,e41e3c13,ec528b2d,df23430f) +,S(1c223f58,1f03b4fc,68024db4,876b743d,8a2b635f,988340f0,d22c389c,43d130a1,9d99aaea,d3bd3b1a,9891dae7,4a3dd857,3a86b643,6c623c00,6604b211,4e27c133) +,S(a675c89a,5d453821,429109cf,45cac77a,880e0e6,396a0b4f,16053ff9,eabfe4c1,8cda99bf,c3426739,c4888767,113b7f4c,9b321a61,1b63b4d1,2dd50a79,d80b90f7) +,S(e990a236,d7854ca7,3e40c661,93dbf3ab,74198351,1236988b,cca29eef,772b32c3,a3d42c05,851b8138,ef1bbb7b,41510bb6,fc893baa,928c98ac,91127b3b,a100aa12) +,S(2a6eff8,af4b8049,2c3d31ed,f6672d1c,d0b231d7,6deeb590,a8d0c4c0,83586027,2a7427d6,951e07fc,4d5cd4f3,ca8a3415,8f0d03c2,3cd2f250,541c0f11,8013a623) +,S(7dad1061,9c4a7bd5,1edf6813,daa8fb4a,2a9e494f,9835db8a,42f4b0ca,827df50a,3e3b2b7b,a44500d0,277b792c,8a529fb3,41667560,1c4e443c,9c2fb2e0,dd17f1ee) +,S(39d5b162,fd48725,1bb42303,b7b8887b,92180fa,ddbdfb7b,a14ef2e0,3cc32aa0,3a8bafa4,5645e4e9,bf4e0175,69fad346,210e65ea,fa92b971,413a2190,b64b6f09) +,S(f9ac329c,ba09d60b,5aa62bed,81e9ca15,7a3bc53d,acd83836,89742ef3,cfcfd795,9c2fff50,aad80c18,2e6593ae,796ada7a,e0a42a4,17ce77bd,ea7be927,161be4ff) +,S(19adeabb,6e9aea9c,fe245329,623b8bcb,3554eff3,999b0b0b,8e035450,14cd964f,c570d99,99e9c62d,a3321f3f,a548d43b,99f05df3,e17273cc,2a45a3d9,20654cf8) +,S(978f705b,eb9b6009,22285468,521eddae,e71f6521,1ae79567,3b122090,fd4eb3c3,8eaa7bc6,1ae92adb,506f9e32,c66f5457,4e1d929b,ef4953cd,a1cd3f8d,c98ff8ef) +,S(e29b57d8,f6808d6b,ec982a12,ac70afca,1c9c19ff,a7b0c724,4fcc5b0e,3dc2fcf1,f7d60b14,133721c3,471fd91a,864e576d,84e5a06e,b031b1fb,3a2947b2,a33b159b) +,S(72073aee,f39510e2,81cca2d9,7831e533,56cc6016,9462a9f0,45100dae,3443bca8,bd761539,177458ee,dff87628,d155c9a2,d6a00e26,51158def,6ce72c35,84d56a3c) +,S(c949cbc9,48db844d,2cd04810,433f982a,680b6a95,e3461ff2,108492f9,247fefb3,162ca70c,c9f19d2,d3da47b,3b0a2361,f5c21492,a12828ae,9c0ff9c7,ef1d7b20) +,S(9acb7d8c,e958f7e5,189676c3,e7248ad7,9f717a67,2d4c80b5,9c425663,e078810d,112dc86f,1b241c26,30d87412,2faad000,473bce32,95bd6989,8b6a4521,7773284a) +,S(e468a13c,e5ad4c24,4df9aaa5,e13987f9,50900b4,a32ba33f,430935c2,1250e4bf,61e3e755,a91bb2a5,3fc2ac70,bb232b2,c1aa356,d494656c,5df93232,a866e400) +,S(26779f67,75d8caf1,46638c17,71e33b02,b41c61df,325acbd4,506199c1,bea8310,e9de26b5,c076eb9,cf3436dd,d9bc7f8e,5772720a,a8401227,7af573eb,65a769) +,S(8c408da9,a816c7ba,ae2846ed,bd923211,926e5e5c,ad595a5f,f2dbb190,f48857a9,89373ca7,e9f3f96c,1f0bc7ee,d427dea,99808bd3,b943964e,f0db4bc4,a7a1256b) +,S(9ccbac95,d80bafbc,b7e699c,aaccea8d,3169db5e,328e1519,825a3f4b,adee6a19,5a8d6936,a2859d57,6accb35a,5e80c944,4d71612e,76cd755e,aa3465b0,dcad8aee) +,S(34c7b7ed,6fe88bc9,803567ae,71ea7c28,c9511f60,e2ebfa8,fffeba31,dbbce2d7,31a3bfbd,c42cffa6,c77aa417,955c671a,426497e6,b35efaee,83a58bf,84de02c8) +,S(7940ca7f,c3bc810b,5679456b,88a73cae,4b2abed8,47260052,ffcb33de,edef6155,8923cf73,9285b368,d32d690c,488d8b38,5d3285aa,c399fdf,6e263daf,4e0b35c5) +,S(2cb10da7,104ff7d8,d8f1742,43425c2c,5e8773ed,71e62e4d,cc0c2d4a,56ac3a08,610cb16f,53ddfd28,7a7ff301,a8047555,801c13b4,81033c94,4e145b1f,98458520) +,S(ced78e5e,58e2893c,3910bd9d,d43fc362,ce06dcea,f44c5aec,ca17eb0e,cdc1fc53,c66050cb,835c97cb,c08ae0df,242895c8,f0f0085d,85a020b5,122e041f,8fb09607) +,S(5e83a4f7,7c4cc672,a7a381f3,e527c8fb,331e8d75,f8578a85,39ae1007,51903f24,545cda31,25c29fca,b343c22f,824c86e8,89f2cd3c,d2a6f3b8,9e3308fa,2968b8fb) +,S(c62958f8,33217811,cb099492,fb8c13a4,5b3d04b8,12a0c1f1,68cac595,e7efcfa0,e179e98,1b92f1be,25c9f892,d6a71ef4,62f3e1c5,43127fe1,f2b711f1,bf61aba2) +,S(7eba00b2,f151282b,83c7fa9b,5df6d9a7,b764e7f,42ca29a9,2734859f,a2f0f016,9e3162bf,a619123e,8e87728d,da825814,4b760c2a,3d05fc2f,1fc25565,1d72a7cb) +,S(8f68c1f4,83ce557b,98d96444,4a2a7d2c,a05d8f25,e6f9f909,cb44b58d,a030cd90,30f15dc2,17e7ce70,a6fae901,70930130,8f7d8706,80c43840,765ee89a,5f864e00) +,S(393d5b72,a9bbc392,4f712195,51ba7f65,4bc4df18,cf93dcaa,bace126f,c4262b5b,976cf232,fe59a3eb,c6514242,19128395,2945cfb,f792e4c8,19248346,37f16e9c) +,S(e1648650,d0d4ca1e,8fac2522,cda2a042,bc93b879,2d6f870,29c6d888,a11312ca,4d919105,9ea261fd,9470ffb9,e60c703,6d21da3a,ce975880,39e1a820,c636f269) +,S(efc7519f,4676989a,a12d823e,8e49b1de,96397ca2,11fe729c,cf0fd67b,bc6d6a74,3f304e50,be6dc6f1,b7c79979,4ae38ff,ed11a253,778d0294,13a98547,e3b889d5) +,S(85726e3e,aa8f7016,1c3629c2,84b7a7ef,79259de0,84f8bbf6,9358f66d,a439133f,756800a8,11a472ec,a72604e4,c2eea080,94971b58,3738e7eb,2c817250,2595e47f) +,S(2e238f2f,de3c39e1,19119541,9eccde3e,b0c4fee3,e432fcf3,f58c4f77,4ba070b1,7ce6b671,c0c79a82,2fdcb88a,a10a8033,bcd0e1a9,2cfab941,d052c09e,4e5e4c81) +,S(9cdc6aac,41e79b7b,ae77a7b9,bc027e99,1d4f8c1c,2b4913a3,1eaaf1a0,9bd87f24,9d666c3c,3503b9ab,d609b074,743f8a3f,460c0122,ad7a0cc5,a22a6d17,9d948ba1) +,S(360dd1e4,608c9215,287936b6,97e5e819,390629a0,7bec616f,7fc713fc,5ef8ec3f,7628d770,5c744125,d5885c2b,de25693c,5afaf8a,3d5739a5,deeeb5e9,ac1c62da) +,S(8657fbee,524c5f5e,25aecdf7,7306c97b,78119e0a,5f155c4f,37918e87,12302d35,242172c2,f90ea26d,b1f7d2cd,dbb9af4d,78a1660a,32402a83,6e598c92,df9e999f) +,S(3ae7e8db,7b069528,acea3e0a,dc005d52,7ca9e1ca,dd3d3cdd,5564ea86,5e1a453,ac203ebf,98b7e46b,bcad5156,cc058857,f32a8d62,2114acc4,55cde626,591fc5c9) +,S(81bdb0a1,9852adc7,afcd9775,54143362,c7e724df,884f1a2e,796d88bd,1c1696cd,2f189af1,a90f9445,353d0549,4d5562f7,4a3d37cd,1362d92a,aefe0393,9b46ef0d) +,S(e95b0171,dd117d45,263141e6,95ceaa52,3498a8d9,d1f09ae6,855fad1c,5e5c3e8,dc8bf907,ea6a4824,9cf930b0,bad3e3a6,c179fda4,107a0812,76f02a9b,9c689416) +,S(20e3979,e95fb62e,ecfa4ff1,3aa3fd46,94b24ab,c814f560,ce180262,11b70bc8,c9d01545,50f1d7be,da471272,822522dd,d6924a98,f6331fd1,cf6837d7,db91da1f) +,S(e0405598,cda639ec,6c058a61,4c39d56,f71c43ea,693f9b86,c9df1bf9,e4fef30b,9df9b561,a7bb2ebd,67b67031,a92dda6e,12550d0f,5cc2368a,603ae64f,ed20ef3b) +,S(faea8667,646d1600,2dbbdfd8,74a59ddc,a2b8024,b2f7f6f0,f2c2036d,ab5c5e9,8112167f,ed386f1,d1e02307,de202bd2,363cd1f5,fefe0621,1c4564fe,eb0220a9) +,S(f01d6b90,18ab421d,d410404c,b8690720,65522bf8,5734008f,105cf385,a023a80f,eba29d0,f0c5408e,d681984d,c525982a,befccd9f,7ff01dd2,6da4999c,f3f6a295) +,S(5906b143,9b994465,c9f3d4fd,f7f09a4a,b9ae0864,262b0140,def21014,8b097533,2917b92b,d0368fff,6e6a98d9,18cfeda4,d039c73,a3cb865a,5d77abff,9fe7970b) +,S(d6443bcf,53ba252e,925f5ae3,5d508732,a3289059,308fa67c,7b051ed9,66b6cc92,e0155fa0,366a2d1c,af8d2c17,a4ad9cf7,f4fc0102,f1e1ec13,7f1b2b51,1af0e7dc) +,S(b95a72a1,dbcfa0eb,ed2200ad,b57d71f0,b96a9703,8bd3cba5,78eff5f4,e9454196,f89c7cd9,783a4c34,1bdd05d8,241ec4eb,d8815463,4d05cc84,d5601f4a,6f3fac0d) +,S(50b287b4,d8b41f03,88804ae2,2b56abc7,be632cb8,a20629b5,3a00fd3d,9a879b6,67c3bbfa,4d8307c0,bd32106,57f5c0b4,78bc070e,53a3024e,1ffe103e,e5397076) +,S(64feb83a,5a81f6d8,8218e2a0,4e6f97b4,6efb89a,6f394264,d905c93a,cb7e5493,3fa224d4,eda77580,4d6ba88e,63df4c3b,5d9fab1e,519eca92,1ada5f44,741d5035) +,S(9434b5f9,2d63c2c,c90ee2fd,b7f7289f,b6277c69,3076d73e,cc38b032,bc8b5cd6,c940b3a6,4c04e6b7,1de7f727,d6fc0883,29443276,6d2ccd51,6d24dc22,3998aee9) +,S(a6db8e98,6d1bda8,995015e4,807b900d,704f8d3b,8ac5fc49,aa16bc61,82390724,3277c29e,bf27d0b5,ef8af507,5e295f23,92c41f29,3803a8b1,6ce601eb,2abedbd0) +,S(50733cc1,dd80ddbd,b254ea6f,14d0679c,6839e6b1,73aa0bc0,9d0ef5bb,bc5c2f9c,246e1742,a5a9172a,ed4e1e0a,9c0d623a,5233334e,47bcb68a,aec41101,92771eaa) +,S(4252122d,5a89f621,2c7b0a99,5ebfa8c3,b980e142,f7a89e07,d4788d91,1163ad99,bc63b87b,fda041bd,f9ac11c,e2e8ab3d,a1368cd0,2e276b55,6419e0ee,3d7fe284) +,S(6bc86411,d3f9d25,bad0a922,21f0146c,9173cc99,d00470ba,a41897fe,b5678f5,e2c1cd75,3915e977,c20d4508,1af1946b,1d8c5926,cca74ab5,c4ec0bd7,921c4cda) +,S(c786df9c,6b2e656d,a30146cb,14da5372,64683e46,5569b1dc,df4c1541,580d40a0,b8d229d1,d8773d5,dedde14a,dcf8816e,acaa274a,1f4ebd01,2086159d,1feb32f) +,S(f42032f7,dc6dc676,5b1a9453,74ee45f8,486e9b94,6a57e651,7dfefb0f,9ea3164c,ad2d7a22,e477f5ce,ad0fbcc1,fe2c2533,78920fd6,cd9ed4ec,1095fa88,2189131a) +,S(3c2fb5d9,a5bc7ad2,d4ce0970,5090a5fe,ef54a6ad,7f8d827b,2ce51785,b29ba5f3,3ec2d878,a4d836c1,71f68648,f8cac869,472847f3,4c267139,5f38e0b5,e96b653d) +,S(b182d837,dbb1e47c,bdbe559e,f30f03e9,ae1efc93,a5a165e3,10285bfd,ffe47303,c40cbcdb,d7f1fd56,c486a35,67420a7f,e4ed4ca8,43a68bdc,81eccbdd,213d7c5e) +,S(75a35130,cea9cec2,81792d7f,ffe84375,a4aec378,57496122,9a77270b,43b12391,988821ee,b6ee31c9,8201a90e,853c4afb,8e330592,6349d405,90c4840d,fdf3fb5c) +,S(a97b9c85,97362b4b,aab43b64,db7e5e0f,3e4cfea9,82939289,e5266f09,87fc8503,ccb75937,fd647eb6,7da4aa7b,72e8d873,c9f035a5,cfa120fd,4d4881f0,9924d8a7) +,S(d129bad3,4c7674ca,60a6f07e,1c1ee8b4,aa3dce4e,82ff890b,cd256324,13a56fe7,b3c8d404,7c8610a1,a56af634,b54dc568,6af075a0,a0cdd4f1,75855fa6,d22cc4c5) +,S(d8a0aed3,cf37542e,a0f06c6e,754503d7,3bd693cf,c3c357f2,7445989e,137f73e2,ba4ad8e6,3bde0d8c,42172a7b,59e1f4f4,581f48e,cffc45bf,929d815f,8133e6a9) +,S(9f905bc0,a5f479ee,6162ed38,24d74a1b,d6d48bd5,4611f840,ab1ac55b,7b84be18,5babdad,4248a4ef,4606dd26,1807e25f,6206dc81,6eeaddda,fd8b5082,52e3da53) +,S(d51c86e1,4519166d,c2aa7604,c88670c6,ca44a84c,6735f692,ee4dda79,e957b85d,fcee6753,29130c5,f4b260a9,cc7efb73,d51e6ec,8ac1ec52,28ca0ab6,51d5b8f0) +,S(ce251fde,ffdf0f59,5a563941,179f6f8a,86402b2c,6bddd1ea,7b37b89,bc649102,5b26a79,882b2f89,79610eb6,5de06e02,b09412e8,bbff66c5,cc650211,d1b9ccf5) +,S(6168ac7b,101fbe73,5b9339b6,9c459fbe,44a6f6c7,bd488beb,bf0b81da,ce511f3,65b6e531,f350983a,2f55db14,588e92db,436f7068,5117255f,ed474aa2,53b5c9ff) +,S(aab2deff,7e77f414,59d4361d,2722b448,6530f0c9,46b93d96,975f5a96,eb4bd091,b416562d,c5b057ef,7e63ec2d,daf0aed4,84320d7b,60695809,c6fa3aa9,e4eaa431) +,S(9ebed934,ca30351f,44b7ea4f,f3f6453f,6d0c7f81,869226c,c8f4312f,d413056,766a6f8c,311550eb,a8500ab6,f3466ca3,52e6b960,c4a52cb9,870ff784,4191a2aa) +,S(a2e78d35,d51970c3,42d03a09,bf3286c2,3a131ff9,abc4bea6,352826d4,5fe2da0e,fcb844e0,4bdf8d96,f423c499,44275ac5,8885c384,57975268,ec8cd880,dc640346) +,S(1a49f352,5203a773,9c7cce34,d21c51fe,dfeba5e5,c0f21622,eb954621,e3d6726d,e617de36,7c6a9283,8d4bcfd2,bf2fd21c,15b53007,6a0367b7,6d6ea65b,af032213) +,S(be65c6c,de6c54b6,c0c4d306,65cb4d61,211c97dc,a74c57b7,13f41028,e2d14832,d7875fb7,5cce3a40,9a74e48a,9b577a04,4c09a43a,989606b5,b44fbade,89e6c03f) +,S(a1572e58,60b10c96,bb3e0b6,7a047d4a,9957448d,74bd8a44,823de9cb,50aaa639,5ae37e0d,88c9f6d,173026ac,58ef45fd,17b0a0da,40304954,f9671c56,93946d1b) +,S(21917639,b6ef2333,378bafe5,fed1780b,24d9fa82,17ee49e7,369099a8,8c9baee5,fee39df,4bcb318b,4dcc4017,7f1af605,f22c44ec,d67a15cc,297f02fc,dfec4eb7) +,S(ac2a8d9b,b2219c98,444d03a0,36db728,ffa182d0,d31831ad,f2643010,bb76d3fe,adec7f18,c9474dc8,d0741d1a,5e72e479,c8b86f74,327fc5d3,cd79cf86,869310ab) +,S(c540463f,bf62ef36,a972d797,2bf79054,80b8e67,415f1895,d42d261c,165d1b86,f04a3516,83039c2e,8bac5ef5,1db4e105,95a27e25,cfe680ed,e7d840e4,f70e50b3) +,S(df63238c,77e75ec9,b844431b,d15007d6,56b849eb,4b6902b4,e79f0d6e,9527ef29,63846f3f,dfba6f2e,46bc7f2f,17af5067,a953cd0b,dbe2fef2,52e73be,b8a17330) +,S(43dd347a,1bf0ee84,ad774d4f,70c67cea,594946c2,94cbc330,15bbdd21,890998d4,b6f58d9e,e6e13c1d,b65dbd28,2343d8d2,3f73035a,b4399672,15b0300c,f7dfb48) +,S(5af8e3e7,f5ba9d80,73c5c1e3,c8d0a62,52eef1c1,17043e01,7d610f20,8b5eff0,246c7a4c,6f6e75aa,eb60e256,756e6365,711e98a6,aefa5345,adefb632,321d39da) +,S(60e7513a,b327df8e,e3d44222,95e0d886,b264f560,1c4e3d03,3b405d37,f6ae8518,4c58466e,b68d6c81,33fa6639,12f4a12c,a4a9f3e3,d4e0f6e2,7e92a85d,4d541cd3) +,S(126520ec,f3129775,786c4d64,7226174d,3ccaf5ae,2e4a1514,90e1b691,f07946a0,d5a2544c,efec281f,e70f05e8,2494085c,133fb918,6416435d,4b7fe673,88c440) +,S(b588e8a0,2396bfa7,8512585b,cd0d0e4a,7d14b5e9,f76e1426,b4591c9,6602c585,d7c6a7d0,827852f9,e34942f9,a6f5eae9,cd0a7f29,d30057cc,46d13e2d,4ec04caa) +,S(257f90fe,4409ef7d,30730e37,d7358c7b,60a1cc21,57acedd0,355d7a1c,89b5750b,b14da56d,9aa8fb67,b2d1260d,8de63c00,a9a7aafc,6fb890a0,e1a148ed,5e371201) +,S(8072b8cb,47c71331,9ed2ce85,cf913c87,85955c84,d338daed,58528427,3f3a4a56,6d7a0ed6,bf3383be,8953b47,d93ac5a5,e40e8547,2fc6d3d7,71f89007,f8d20d39) +,S(fab935ba,b2b72a27,b338ef89,509b3830,b7800817,19c2b3ec,8467c736,24ca2640,2a610c06,77fb514c,b224dcd6,56c5136d,88f87f34,86fa0699,eb71319d,c85a103a) +,S(7c6364c6,4906b7c2,e1ca0d87,6c163932,7e8e146b,afd94c83,2330f990,f979ae52,c97e7b44,26b91f6c,88ab7e39,d57f7b7d,4a5e0f9c,ff15aad5,e58e7017,d51c5317) +,S(98beb1ac,48c8824d,447a10cb,43b51167,b8e7cf0d,9eb4e4c8,43403b03,2208570c,1712c13e,ddff8fd5,191fdb28,717efb74,ed52a9f,f47bc21e,b15838d,fcf00af3) +,S(f683a667,31241c44,4adcf062,156f3fdc,d04e8450,911908e1,95bbea2d,8c5bf918,460eac53,48ea1e78,9fdef168,a150065e,1e4a2f83,85268385,3355586c,87453f1c) +,S(38f065a7,165e5d4,d31238de,8dc38f43,4dd024c6,6eca026d,de03c4cb,b43639a5,790bacf5,d35a688b,130bdb38,29073b8,28837b9c,9357544e,1e44d766,e401d044) +,S(cee8a218,2b3004fe,76714511,30340b0,7cf10241,d9e933c4,97ae84e9,a1d525f2,ed373709,3e0eb05d,3ee2823b,25bbbb11,ec943848,1a3ceae1,89573d71,7a596b3d) +,S(164c6ee5,620f4582,35520eb0,8276d85,9a14e266,b7b59576,d0a3e0a6,636f124a,fe92dd66,139f02c8,76ff6e57,8c769a4d,63484072,5c909bc9,481d4a52,f60565f3) +,S(d4606a18,1a0bd363,eb63849a,81c77d0b,942ff14e,7f885c61,d1fb772,78ef1008,81e7b2cd,e7c5d9,29e1d69a,309a334f,2c01b084,e82b789a,835a7aa8,5d7e93a4) +,S(905f5725,1df1651e,83aa8b3,dec2d96b,a32155eb,90d7f985,b3ce5213,2092be07,e4acfdaa,9eb8995a,a4ac8a0a,2b66cbbb,d561fe6b,389c56f,3af6f62a,d7579632) +,S(2e3ab14c,d3aa69de,a35a8ad4,99130302,b16f3d3,9df06b77,7c30e404,91eb6dda,ade534e7,ea0217a8,88c50bf4,ef81dddb,a5c7ffbe,bc0f90e7,110df2a8,e0c7c2c0) +,S(98207cc0,23f50a6e,5f5ce8a5,68c5b24,d4f4f741,94de76a6,d1e6f44e,72619a9b,fdacc236,bd424684,52508806,b08fabdd,98a15b15,6751953b,95b4c5f1,40bce374) +,S(b6d8bc0f,894863a2,3a793c3d,a33a5e66,cafe8696,f9cdd40e,777a40ea,aa203ee2,7e9b246c,8555b4c2,47c45fe1,d1e5d160,c7ed7d37,a3a43440,deee6ef4,15dc092c) +,S(56d030ad,eb30f1b4,7f806276,651a56d8,7f0d8b6c,458092e1,61351368,8cd0f6c3,bb3a1513,155c5885,e084180a,1728902b,33e1a61b,364c8d9c,94d67ca2,e386f131) +,S(77251aac,f919aa4e,b7610a77,ba27d94,c85b973c,af04c885,92fe5272,a48ec088,ef27aac0,593cc67b,93535bc8,4d0a04a3,e8a865a1,bdf65312,85beac2b,d58e149d) +,S(cb7b6a,cbbbdc23,64711585,6d80df3,2ec9aaa0,c6380b3e,677299d0,13658121,1f818bab,72575e35,a60ce7f1,c720e9ce,2f59b086,63cba841,ea288920,16a40ca4) +,S(4a18eb1c,bddb4c3f,ed44fdfc,6242959c,29720142,21d10154,c7fbca68,5c475d0,bb24f347,ebdcdc0a,6429f8ba,49065475,9cce87aa,8df10496,6d2ebcf2,97e70ffd) +,S(384286ca,1003c97d,7d151032,97d81cfb,e3e3dbbe,5dc70c76,6a8dbdc7,c1e625c,7201deb,638d2ec,6cbb4db4,e955ee1b,a3015cee,e06d2ddc,f024daab,8f07a277) +,S(84b6d6ae,d5e00e31,73c24d39,80f05cd6,f61625e3,11439a55,e03ae2db,d79a7d55,a3da9e1a,4c32e4f9,a1d326c3,6670296d,3ffb18fc,266e169,a99d4d00,4de383b1) +,S(aa1cab51,f7239cd4,dd27a4c4,805e614c,5d972cbe,c2830ebe,7daf6ed8,781c37e9,cf8bb72e,535fc8cd,12a2f4d5,e8f9e257,38a28812,1c93b061,5fd4fdeb,368be5bf) +,S(7c4f183a,f4abbe43,d7fa6d5,77ea6c14,83302f2d,b863a7c5,bf072e51,3d2140bc,1eb08c67,a417c0b,58fe8185,1a66902a,a608db07,24dc38c6,706bb80f,5956c808) +,S(dc30f68e,58ff30a,4bf2f6b,28b30708,506140a2,1a971c04,8afe04cf,94b54d31,6f996e08,8d4f7f53,aa1c2050,644a47ed,bcc1da4f,519978f8,6496ba1e,c7be2688) +,S(145185a9,ac6b036f,d0d3cd25,c904b3b7,c8f1d0ad,3ffe5f89,d87b7804,8b017426,d7f6acb2,828ccbc0,db0708e2,79db6313,fc955d2b,cf9e2754,1a7535e3,24c7bc90) +,S(e8700138,5c0bc4e2,9911f29a,e39a5ae3,ad3cf1cf,d690cbef,32f313ea,fd190fa9,92d83708,2e5139d0,f8084001,8ebf8703,da250361,466caa96,717edd0d,6e7ada7f) +,S(5fac0aa7,9963a1e4,5e1c668e,3512d0fe,2eb2c709,d5ecc71f,c862d5dd,523f864,9c7bfd73,445e7d9e,139b96e6,813f1f80,2ec632c6,a76e9dfb,8afecf40,2788d16a) +,S(441f40f6,f3ca4dde,5a085c15,57f14cf3,fbb7c3f2,5716c33c,63ee90f,45c564e2,c81f1205,1179c2a6,f2614495,322cf40a,34cab55d,c90d61b4,d1bc3787,ec3baeae) +,S(a4068c1f,c63d8f21,203cb6af,b37d796a,3c454bd9,db974ab8,e8bfba8b,b832b043,b5318b99,e9354250,a837f8cb,cf8d9cde,d95bb1d,1db0becb,1e887535,4ddb96ca) +,S(44563417,c647b097,d0238a57,74998fce,3c809a26,f6d2b71c,eeecebfb,134cfad3,3f417680,1c15172c,ef636dc3,12742429,13d59079,73ad09c3,9fd8c6a,8a95104) +,S(d57a5fde,47873327,728f5706,d2f0d64,1c5386a9,fdc41808,a2c062ab,942acb6a,cffcd62a,c0c85aae,4a6b7881,f3be170d,9836abda,baa47d60,8c0b8f60,f9aaedd1) +,S(9dcedd10,d495fa2b,6f4b4387,57cb38be,d6f09949,17e7ece,7de913f7,8cb111fd,73196e22,59d4ae9,950725dc,77321567,167d7761,29cc32e9,d92b6dcd,4c056223) +,S(aea290f3,a4ffd405,d51f1c8b,5f11cf74,60f05300,a1e24c08,25b96910,b24e32c1,f6c100a6,3c918f8,f64ffe8a,95840421,dc384635,e3465cf8,65034bde,17ca8eb9) +,S(bbfcd317,5091846f,181696f6,35fb1b05,802e7659,7ca97040,31339381,46812234,2a0a4ebb,1f09b31e,aab4478,89000fbb,5876d7e2,dd889393,3001a977,8aaa3a15) +,S(2a3b4e65,d9d7661c,addfe1e1,96beaca3,ccbc0348,dff6d2df,21f394c7,a7f4594d,74c6f171,1a2c0c01,78bb6a27,b6e17cda,bddb7260,acbc533,a49b19d1,e0b4a110) +,S(d8e47e32,15cbe145,aaa9efec,ada428f1,8d8c599e,98d2f9d7,8177215c,c85dc2ae,5c4d4f6b,aadcd87c,7ac76eb8,22e1c0db,e7c81342,702bfd98,e193df1,809e0511) +,S(5b5954d1,25d77778,f3c1514c,6256ef65,2ae0ab97,151f8856,dda6c87d,1e04a34f,1c5ddf3f,b185edb9,14769482,95e687e4,40497582,26b36fc6,3502922f,cd1bf81e) +,S(e8097e1a,12c6837,a8f29eec,31ccbd16,f191e7a7,d7b199dd,d6d9ee6b,7f26ef55,84ab3d24,e2c4407b,53e4299b,8de1aa8a,22dab9be,b6efa5c,5715a943,65174b9a) +,S(495ebcc5,b0573416,f2b3e705,fe4a4bfe,1e756211,5f37b8a2,dec57688,dedbdd45,3bc65725,6783970c,7696d5a7,b04ac7ca,8c627ce9,251844e9,e7cca774,4d385be7) +,S(4ffc69af,b9cf40ff,c94beac6,aa020109,b7855e0,a993984f,5e59ba16,fc78ad51,6d43d1f9,e3283528,494c9783,cdcbe9ae,2ede071b,ed494c57,2539df6e,b185ca1) +,S(b047e0d1,afc92251,7eaf5c0d,a9d0a093,fde5e829,84c8483e,d256640d,166dfc75,dca2ef00,a282972,d4bf67cb,74fb31af,da5b8145,ec1b7a65,6636376c,504a70df) +,S(ea7b0b93,48e0b3e2,be800ed,6ca4b121,277a496e,84fb6680,2658f68,37b1d530,cef40d2c,e1cf820b,19b435bb,a541ff1c,fa572b1,ca3693d0,cfeb3b32,8ddf918) +,S(e35a53cc,ad74738a,bde75a3e,e2b10d7a,d4ec39bf,e32e1daa,ecc151f3,bef1966b,ad06a8ab,a0296c17,fb24eff3,b27284c5,6ebca204,f6eee752,276ab9a8,1f1bce13) +,S(70334511,ae9acd50,e094f034,17dbba05,4a104c84,ea8d6250,13e1f8f6,907261a3,d1f603e0,5af2e1df,4b8eac69,b4067810,c302ed18,f02bc964,2eba34f6,bc67e84a) +,S(13adc074,c3ea8877,4598d0b9,ad653285,c81bd98d,d4bb6a43,c126db2c,d1f08d7,4bbda9d3,c83c7a64,fcccf3e2,c4251a7e,f61966b7,ec48e89,c991d44b,9588c83b) +,S(4a2a5fa0,71702fa0,934b66ae,7c003f00,306f07b8,625d92f2,d2276efd,18ce5f0c,f9c2f4ac,d8c594a4,117a836,7fa5224e,a7ccbe60,2475e3ed,b19a317c,5feff6e9) +,S(e2f7dc14,79bac0e,a95b5a2,1a9f4e,8c42a23b,8f25d09d,dacb9a3b,fe3ec638,ae6c82,c4f3dc5,41f140a5,2eb6b0c,dd0e200e,d0d951b,e85efd4b,b9b086ad) +,S(eb1d6d07,8f6b74f5,c48a913b,8510e8d0,5cfeb954,856f3ebc,628d0db1,a253963a,f3d73300,e216d14f,d5a67c35,91b362be,f13818c3,36a93784,875ce9b4,2cd8c7d2) +,S(a22c6d71,1d79ae71,403feb96,6dc11adf,253a5d3f,d3d74b44,5f7268bd,84b52277,86d5212,bf37db8b,4e873476,36201714,3f295f0b,d69d2187,8904a53c,831af06) +,S(42f7eb02,797cc76a,21c95db3,c9a0014,4ec5defe,553a45b5,1b701c0b,6f5ed3d0,60525877,3cb86452,928e37d,ce19e2ad,4da63174,2f049214,9f9823ed,ba679519) +,S(f5250698,b37da26,20a3a80d,a9c1c88f,792677a2,6d2b9fa5,49065339,ecc1e95c,b0826c,66edbd2c,5562bb14,d6f8df25,a5d0bc54,7a1163dd,4a8dc1e3,7d140266) +,S(b845d4a0,bc8db805,43526506,cac5c093,cece5c5a,85750d54,317dd78c,7bc10832,e38db2fa,207ce0b4,d9b01ee8,b174a24e,f28591c9,9d203ca5,7d90080,807279b) +,S(4955d281,746b8c9,4bac7d53,26aa28c3,9fba7149,7b4fc036,f9971f7a,870a67cd,ce72ebf4,aef6e987,3fa5cf3,e66ec918,911885ae,848aff22,eeef12e2,e50e6cee) +,S(20fdca2a,a03d6105,50f2eab8,d5e7d47d,c4e2e9ed,e6d2c7b,bfe64d75,176b9e9,1e077683,2c44d6d2,19d19c7b,aec0a303,f4d3d5f6,4ad8ca35,83f87325,6aee262f) +,S(418de9de,9adbec78,769eba7a,cab3853a,9a85ebc7,2bdffc86,844d0f32,15de4877,20d521c9,974c8ee0,f817ee37,a0fa14d2,eefc4e05,2c93ce87,ee665898,9e49c5a2) +,S(135b5a4a,f64eaa0f,d288bee5,c1bb7846,30df305b,5d3b13da,d8c446d3,6e13485f,3e571c3c,fe32fe42,669b08c9,14a655ce,828f41cb,12b9c18,9234f4eb,1aac0437) +,S(7eb64f50,5e26671d,21d3b2c9,fefbe094,c6300348,25248e86,5daa8939,f8b7e90d,be847834,f303ae8a,55ebaf3b,5bccfd61,6284e836,13eecdae,ab43bb6e,d4d4e986) +,S(9ee1ccd1,670be914,f9b7a070,962f7ac5,ac9d069c,eb3e0748,72db2e08,32870fd6,7d3d9dd4,9e71fd68,4271b17a,a8203ab6,1d2bf6d5,2fe3773c,78a8ccbe,d256cfed) +,S(a256c06a,796cffbc,5c90d91e,93ded565,b9755b7c,b760794e,e3060b33,3c217e71,e9ef8b6d,7731c262,6c93fb06,b7a6b3fb,fbbe0e0f,54682409,e5218a74,d4a064fd) +,S(dde8a9af,ec32c1fb,be9470d7,a435b4fb,bd34416d,e703a1ab,5188fe8f,f721aa4b,e7dbb850,aced2fb2,fcf5ea6b,edeaf383,e4ae0fe7,98badf41,66e58f13,6a87f3ae) +,S(fe88599,811d0e9,f780d359,2e8106fa,2f54fb6b,ba1df66a,b7b0b41,2c130c49,b3b0b8b3,c7f36d43,86f30438,1989d885,31edab91,f25251b4,e01b3d3a,6ec97f2d) +,S(d7da001e,8a606b37,ca65ae71,32214cf8,258dd422,efe0fc83,adabd56d,64b0467d,97f503ce,8eee1873,7e422bdf,91f051f7,1025353b,3a1f6f1,545206f8,2a32aa5d) +,S(65237583,e3e1a640,c2c16a9,a49d09c1,f5dbe2d7,a3845989,574abe33,397e747b,2296a1b1,e2350d8f,14a6fed3,afe30fac,a45ff345,9f8f515a,370aa260,d435f7a3) +,S(419a8e03,2d8fd27c,afda6538,9b757550,313307d,12fd185b,4d2f026a,40ae1de4,2932ea7d,3421d738,d821030,f75b0343,fffe9d25,8b605cf7,e20f6b48,1a94db03) +,S(275d261f,7ae2ab4a,4ad1fd66,1621a223,7ce08787,beaeeee1,a537b103,c0a44023,da955bd0,4ef1256c,9e184615,c4ee666d,c9ae14c7,d95caa7a,5dca6f11,1e5e2e58) +,S(3ac6681b,d0a2968,290ad83,cb0e00c6,6a9962cb,4c082366,953e294,58ff3651,28348b56,38ede228,7578cf14,ae385066,4595a2a8,d86282a0,edcc389a,346066d4) +,S(d4ba242d,9407df55,a9f672b7,e01cb1db,99ef744b,d24d3e47,9b1841af,a6c1f05b,9e395144,aa1fe50,9d72d086,4a1673c5,24c4ad65,fb7bdb16,cbd52053,1c6f11a3) +,S(c6525077,2bd399d9,901d57b5,7e8fc941,cae0f5fb,6d47ee3f,5b3a7cea,3fba2e83,629f7edc,a6ec6b0c,579cf9f1,867e1bef,e3bf9bea,8d8e64b7,2b18532a,47280efa) +,S(f12daac6,d38fcb00,c2425a79,2c52225c,a94d544,c6b96076,7ec9c885,d6d4430d,1764feee,2584dee3,abf2aaf,737a068f,fa6aec89,6c02e2fd,cf0ccad2,7ee8f210) +,S(db858a7f,4a84d88f,236b5994,dca409b3,d7111df4,f7e5c009,4ad1decd,82036673,c0606c89,e4b13042,9e0a63f5,1c93b3bc,95d98832,d89a9515,2e5c1874,f2c94a53) +,S(237f5f80,4d4c50eb,d611b079,5cbc6567,101ec8ba,1a265976,64472f7f,5a725ed3,b558d31b,7647c4c9,1367d696,a67e5d88,76454900,f340cd,5b8d7490,9fdd5993) +,S(e962e9c7,7c97cf36,32bf0a88,d6e939d2,68af9fc6,ebca96b8,6fb679a2,d953eb20,931395ff,a50a854f,5aa29314,c50c253c,c3175739,9c2eb20,600b0217,9f8ef48a) +,S(890514d2,14b57796,85c0cd66,818d182c,3d285af9,771c7c48,92ea2ac,115a8c3a,47c5a,a4d76cfb,2a62993b,b499df86,fbe7e130,d4758235,7decd72c,b61aee8) +,S(8b058976,295a316e,65da1774,da78722d,8d729f88,5ea4402b,f20dc67b,bab7f815,aeed497f,57d52480,23b94a3b,5fbe9c0,e34d0039,2d57b34b,377bda9e,b8703335) +,S(6a4685e0,7d96a793,d55a6416,6b089623,755fe549,3a879fbf,fc9a5a74,7ee7991f,313ffb6d,98044c92,f37b3f66,81f1b4b2,d9b2e42a,7c34a5bb,db45b9c,6063aad) +,S(65157530,e4ffeeda,41064bf1,f8d85174,2b9b8f64,87a05ea9,3d2198bb,3f33fc26,5b0e76a,8f96facf,9d492232,95a0c6f5,6a609504,b9b07c38,a72b6f15,4cb8c9f1) +,S(9f6c288c,1e04703,46b02d47,8fc0a40c,dfc0229d,928639cc,6ad2ac88,96e55085,2af7c1c1,7210b552,4ae2083b,b45e9749,c9452776,c12d5e83,ce265c98,51266c8c) +,S(c566e04f,e5ef7062,7d914a04,40731caf,3a7dccbd,5415cc1a,a2d81328,b8a6da75,a3fa5263,a7f66158,67f43270,77d3b2df,8db1befd,552249ad,e96db0d2,8c439282) +,S(6963ffcc,cb62ca7e,565fa9e7,99db54c3,dcaad601,95bd2dd8,df70d447,c443ba4f,96c715c6,84bed531,27c28e3d,6d6a0214,883aa214,25c4626b,4c11cf17,36b8f134) +,S(50db27a9,8e0328e2,81139df7,5376bec6,37e9272c,f7c23333,510bf5cc,c4f46b2a,b5221242,9eec82,1e9143fe,af9e7813,c135be82,bfc153f5,2ac061dc,c1302d92) +,S(7badba3,8f23f854,2404e636,b96e86a6,84557310,2bceb7c0,241e71c6,1ae22ad5,bd000395,b5d0ba4c,a76ac682,5191fbeb,f6066d8a,81c4a210,56ceda82,e13459e4) +,S(147667bd,5591aa83,26fa497f,c60f8e7,a5ceda47,9d4b2f7d,93bdab3d,81bcbd0e,bcdbbbc4,2adac6ea,413fc3f3,6cd2089f,420a6183,a918bf98,fff27aee,3e870849) +,S(ee576c33,e8404e1e,11e1b5d8,6ea52335,cf8b0ade,49dd16a3,7a61fc10,cd3eefd8,722bad17,6e083868,b3c14ee9,a70013d9,89c01b5f,44188ec6,7db7bc3d,ca26fe2a) +,S(8e3cfa71,f3b7d3cb,fe59d8e0,b579b76e,d33d318f,41d3b76,121b02d3,2acdec80,86be156d,b76429cb,ff2c67e0,c015b7d,d0007c7e,33f6041a,d817ae9d,ed5dc4fc) +,S(e220362f,2df8a485,51dbb7ad,634c4bb3,714151fc,db3cc2f8,e483aac,50d88768,acb8e001,a81eb6ac,99dca40,2d62fed3,8891fe2,eeb8e023,6d8f2447,6f4fd200) +,S(1777fc26,9bd7aebf,c014c785,25dcd40c,f93db012,31541cac,448c44f4,89628808,641bdcb2,b87e04ad,3ea3a3d4,c364e93,1171b2a2,cf3c0205,77552b7e,594c649f) +,S(ddfb5269,fcbac0bf,a855d2c4,c9062c77,836af1d1,145b4df5,688b6a5,24c11651,c353674b,9520ea9e,eac3bbce,a85b0709,d0284c37,a7faf78,8b573ebd,67bac8be) +,S(b01ea11,d4704bb4,24cb11d8,b42411a7,3f227c84,dc10eb13,c2b20a1b,bf23258a,240844e,9ea3edfd,948d2df4,51538cba,ed57f157,d0632f2b,8b644570,5f9ccaf9) +,S(934e20a,46fbb416,fbe829d1,46bebdf5,2220c0db,958c2a9c,64244713,4509cabe,76b7a1cf,79ebb5fa,58f77e64,4395d33e,bf90c0be,37e7439,c3d29013,25b0dd76) +,S(15bfe959,5ee58bec,791981dd,13ac5380,6615ff53,95dd4661,28c23f59,ea236967,d6dd460b,d3d36bdc,eb7d3ba7,745fe6c2,fddba241,fadcbdee,44f377f,bd43ee00) +,S(5e1a723f,403cf56f,8019797e,6f8191f6,6e7ccf15,dfb1965e,590490b6,224ecd24,97342532,36c48696,645a7e60,552eeacd,4cba990d,6d73117a,dc6f2967,a6a0fdbd) +,S(1485fddc,85c819da,8894c1b3,8be82eee,762a052f,3830dbb3,7d21ee74,868c778c,d779373d,d503731b,52f9e689,805988c0,b916a579,921c637b,286c580,93343d5d) +,S(6f4b7385,f881c9ed,202ab6ec,c8302626,668a1296,36274f3c,ac4296e9,1eece7db,fcf6f192,c6c80fff,3f5c2bbc,7c6c4a5b,b0ea2e3,70799827,440e998,cf6b26a4) +,S(bc27cb29,33ca44d3,b56280d7,7d69af2f,9220f4aa,49aa0fab,685c7c54,62adaf76,7607d5b7,a02c5e21,cfafccc1,26e8439,88c10942,aae6333d,b5262426,1ed4da98) +,S(76f86b25,2530d87a,b04e64c2,4cd1e05a,e8324bf0,a717280d,3845cc5f,a6a1a733,2db7ce38,33bd24b3,55e95b89,ae6d8a54,19124761,e382745f,2a7347ce,fd7c382c) +,S(5615175d,2ec968f8,81dacc1d,1bd6c06b,df87c9ab,53fdef11,335818f,bafa918b,5f755638,6154cee9,e71d21b9,cee3971c,7d41e3e0,ca2c1ff,f66982b4,d66fec25) +,S(6390f1af,1ef24aae,20e2ce29,dfe9a0d1,50b2826b,f5cb3629,8e0dc16d,ee2bdf8,cf3e2b98,4f120d10,16f82e1b,8916928c,263f3323,52bbedb3,c29ae1ed,b0d49b1d) +,S(bc5df46b,4fbcb83f,7aa53579,ac8d5c3e,8482941e,cf848810,f9239138,b57e9378,d4d15516,624e72d5,9002dca8,3c8b5914,b224d4c3,75260dbd,cda88f9f,2f772627) +,S(3d069f1d,dd52177f,cd802195,c7c8b2ef,1e43c34,9bd88b41,43bc2d54,6a2b8d33,2ba48861,14218d67,1b1fa4e4,2aae97fd,66164e94,af1e3026,8dfe9dfa,7155fde9) +,S(fa657492,fab9ab23,f1a49c17,40079d7e,abafd7a8,72e481b8,7b30cb63,8a47757c,89d2c7b9,2f1ad11b,d2808968,c426a00f,e584ad83,86dff03c,1a047804,a2e98630) +,S(e2318d84,61f85ac0,7db07d08,aacbed7c,5f5a45fd,7e505bb7,ac86b417,6b3eb46d,3b0170a3,b6f466e0,380ab984,e5bf4b34,89cbc479,cb2808cb,445614bd,8ab012e9) +,S(defa0810,91d1db16,fc2f86b4,fa5a7331,f0c15682,55855134,10f41a6d,a2bfa6a5,8429db90,fbb25354,3e77ca0f,e7a731d7,f1a481bb,f1c997e8,5f585844,423ace4a) +,S(fbaa7567,7306fdd4,8c85514c,bcb78e04,ef4d693a,dc7c356e,f95ad34a,cc880db0,45c4972a,161f4a23,cd71f726,d5617b71,421b68f,b0611097,3edf11b3,8a391909) +,S(5dd76e24,e3cc0c5b,ded55d15,858f1c19,dfff7e43,b299df43,3ee77b46,2122205e,992de68b,87bd6760,a75d6b90,89dcb2b5,5f0b39c8,eb079ba0,e4451fb,dee8f2d3) +,S(890c7a78,d0f1db95,75b53e98,a0a63d81,8096422a,3ee18403,ede8ffa6,3af9418f,7a362df8,7430b479,11e8d310,558195c8,fed28b05,531b68a9,1631ef97,ac008085) +,S(4914f692,f88e858c,b6174e6a,9d4bbdf9,87f0e373,1bf6e69b,8bf3531a,43a37e6c,8751e02b,fa9e0384,2ff3e4aa,307cb7c5,fe4f7941,1069249b,c8b19866,b6169cf5) +,S(a5f97745,ddc25117,81693df1,bd15203f,9d23bc93,9015be73,c6b4e256,d1d05416,57a99674,cf64bff9,7b9ba0c5,69d253dd,52aa188e,3ec645aa,89466c79,5d0f0370) +,S(62da0bf9,8d32519c,16fac809,95869f09,b570b953,e0a7bd83,9623a9c9,bebbdf84,9b9ec74a,c960fa8c,2ea8bd4d,93ff624a,9ce54fa2,4a1822a2,37d962d5,64e9121d) +,S(5caa2062,c25d7df2,23718f9d,ff29a403,e5200d22,bf064b44,c9519742,4c448a5f,6063bf93,1f72f65b,9ca76400,de5f5204,a8a0bdc4,b19cfd12,2664aa33,79a7a27b) +,S(4a81083c,c18dcec3,5825415b,2854250c,9dc651fd,5d897610,2ceb7691,576ebe60,850f48f8,7ffbf26d,eaad1f8b,2c0b8272,5f7c313f,55811b98,408f8f34,8421f241) +,S(ba8baaf4,9d0c194a,4814070c,786fd9f,4b8dc012,c42ed667,7b39f67d,da7fccaa,ceaa8874,10bbe854,9e87af6a,15ae1326,d85bb995,19a8c4d5,dd3a8599,d9ae0ff2) +,S(4c780a0b,886fdcbc,a30f239e,21495f9d,5ea38a6a,7960ecb,ea4dd2dc,9266103e,7e50e1d5,b6c811fc,f86ee651,5d64e06b,26827ba3,656dfd51,1fa64124,224e182a) +,S(50a433f7,f528d66a,961d7123,7e6d2bf6,7321896,5ec6599d,b1f34b0c,db21524c,6bca1083,9ef8d450,e56829d0,cb23ddcc,81e2e7df,e79b53f3,2f8aab9f,e2eec15b) +,S(b98e05de,573e37c2,80d6de1b,fd479bf9,bd23a6b7,2f6ab34f,caf03236,c67ec5fa,d86f07e0,8a4c3d61,f087dff3,a2af2d98,58787d2f,424b49da,de0c584f,4d8756b3) +,S(d0cb5279,e76b8be9,b2e9cdd7,b0c841b3,33398541,24923224,db54a91a,81995433,11fcafb7,28a3307d,2d87f2ae,d107b0b,d64f6030,b89e845e,1f67ce7,4cf7ee6d) +,S(90c89963,619b1593,d5fd7eb6,751ef03f,aa7c6802,46e36bcc,5d0bbae6,25376720,6e8f2a86,75b803f2,c3c87f9a,98318cbc,61b99073,2b8b33b6,62197ec5,73f64a71) +,S(bd3ad39b,989c3a08,e45007d9,116b0d4e,2dcb6a14,26a44dc2,29bff230,6c1a89be,7e633d7,de03e6d6,a7a4a833,f338160b,cb914997,6dc2080,28c3e2dd,b1c1b11a) +,S(1da5082d,a6e4721a,499d5559,91e8d216,f26167b7,d6de224d,17bc4e5b,ac94093f,5f864511,4b89eb63,60ef865e,6eb887c2,bb0b97e3,9a0b7078,888049c1,29f63c77) +,S(19320416,52e24197,d195a0f1,99818925,35c19790,99d15992,8999073b,4028d659,2cf34c91,2d1666fe,1abd3b0,49b12dcc,f7086e58,b7700b23,497bec18,e057059) +,S(79a7b5e0,482523d0,85bf574f,2e6e431d,b3bd6ae8,4e921b87,fff0f683,976efa9a,f713e011,70de0de8,a8cbe229,b147cf82,efc7fe3c,d7171785,c85bbbfa,ef935755) +,S(c2e16cc6,8559a160,9fe16d0a,9be4016d,55fccdc4,2d22ee62,895e0eea,a64436b,22399345,d40c11bb,79b9f036,5fdf6a91,4e1f43e9,bb1f0a87,81d2ede9,fdb6a118) +,S(f76c0f67,bd3c648d,c320125,5c34a93f,ed656378,8c9f61a9,c60933d4,e2d55d7,205c9c5b,83bbf922,8e99191d,e7ef0feb,429050e8,2b9fb3ca,1dbd2d5,cd35f612) +,S(24a3af8f,ee393ae3,2c30230d,ed6f96f2,9797d591,1cc3d934,b16e1304,de7bd75a,302041e9,2ce00cb5,d4a667ea,90df7f90,576865d3,7f462126,400c77a0,a44259b9) +,S(2e8bf897,5f29a6ba,636e6ddc,1e2dcd6a,1373f123,c6f155b3,3c8f46dd,b18baf7c,a93f0c91,258ec64b,d6e18761,872cf0e2,c89f9713,b9008605,b0378f8,1ec867ae) +,S(a5d35483,7f90d71c,8d829897,b3a8fa36,7c38b41c,879a3e6d,52f2988a,b88dcf68,853a586d,9661cd50,12d1ae6a,1501b874,739405c4,c7e32bd4,23ab7c1,62382bfa) +,S(51a6c879,ba6f75d9,4480aa71,2a343be1,bb9aebc6,bb4ca3be,de16d33e,992659c7,3e636d28,f8b0a4fa,a3ecd585,80d46253,61f496b0,344382b3,5742fcc9,403e7e05) +,S(a1d34e3c,aba45bf,1772d2f4,bcacd17e,342b66ec,97dadbd6,780cc453,ff2449d5,6c3a3b8e,9717365d,2f21e2ef,d72308b3,45008ebb,10ca02e,969d14c9,1aaf677c) +,S(fce0f1a1,69034370,33de7e6d,b2364b0d,4441c5f2,ee405e68,5dc546c2,58adc2ad,c018bc7c,fc5ad1f1,36103729,e1a177a7,495a6195,915ca5ae,c086804b,8c107865) +,S(e380e6af,c47b11c5,1ba0c8c3,9b796179,39b07cd9,988896c,38011e73,a4f98a81,60ecd299,c22fbed9,132bd455,1f44022e,151927e4,7ad93f1a,a0539c37,2680f6cc) +,S(6382fb8b,2f4179e3,191d863b,a0ec4cd,94b52103,f24a0377,8f6ee27c,7c81115c,6e8d4181,9621bf4e,3c04c5ea,2b4c0146,dd0ed973,bd4530df,d671f39a,e54db63a) +,S(c488650f,d66629fb,927dcb0b,9f5d0771,1caaa3f7,ad6df39f,7d8f98d9,65490aed,b395d9fa,46475b16,6beed01e,90c9cfd7,83e6138a,7bbc6d5d,f919d41f,3e512c) +,S(5cf1f5be,462dd02d,f8d1e9b,6cb1540a,4f1e5be,de9c8d29,954bfb0,217e494a,5e8727bc,2429c9a7,5123967b,b598207c,46105822,5402bfcd,c3d070b9,b2351d20) +,S(9644ace5,9dba2b1a,f3f3a4af,da130ba3,c3bdefd9,39c3b52e,670ead47,54407b9c,5e83dd4a,e338fc0b,8c501f98,72295400,4b2465f8,4f1c272d,20e3a2bf,300b1b79) +,S(728e6659,f0bb9bd5,916846ff,3aab6f10,85517ad2,c17254e4,c2ce908,c7934781,7df32327,354020,319e9cb7,696b0384,6b8e5bf6,691cc73f,829abd42,44e674b9) +,S(80e68c8a,31d715a7,5068091a,142d4a60,ff30d2c9,42f625c5,d234bb78,31009e8e,fe04addb,b9c47f69,3dc0b126,67b0960c,1b4a7bf2,882aa626,b1888e5e,e4157fd9) +,S(e655129e,90211425,558cbf1a,4eeeb630,df68a4e4,f96a176b,db55500a,89f5af02,d5e3a471,ba698897,9f747ae1,a1aa87e,e10c5069,3df12ed3,ed52307d,a0202a69) +,S(30a9e289,f6ab5edd,7b56f48c,e7373a6a,97dc698b,511343c2,8c5c217c,de67ab6a,f4016c18,c4f75d52,927127bf,c403a83d,4ce304d2,8a4fb965,beef9fda,4e9d3f4e) +,S(8a6a4557,2c1dba29,c9499ecf,d59ea43b,1ebec5a8,78a3e2c5,2de09aa7,c0288e69,56e4aceb,e8315c2f,b9271519,80a21d,c17ebad,63223380,b24a7237,33ec205b) +,S(647d3443,9f4e4f50,cee5b0d6,8047f130,965f8abf,482f6166,8859c86e,326c1bd1,f951b5a0,b180894c,f74c5235,cc625888,fb830382,3b0d085a,dbe857ad,dbc22088) +,S(6d143d17,9f0a42a6,85031c6c,f62ef32,2cde46b3,978b04ba,bc37bd3,34de5634,925d0fd9,11c7863d,b0ed42c1,76591307,72b456fe,83bb8063,3afe5340,cab4b5a7) +,S(f21cebe2,7ce8dd3e,fa30428a,cee881b4,d65eddd1,30f9fa62,9d78291c,a4f4b0bb,4a6d7f43,f2ed3d26,330e58c9,27a87c55,850620fe,1edc6e36,c9a3978,8f922ea9) +,S(37883073,e227a5de,452c7706,a4a06594,5a891c06,e594fd4e,191d36f6,79117c35,224bb4cb,389f3d25,42411fd6,594ad6ec,bf4f1c9,11f723e1,53dbb420,33ae8ec5) +,S(c21520ae,e6cb0358,53a7da78,919c88ec,84c17d10,3ac13ec8,6a412d9b,96e57c54,56720dfc,f748ca09,e27e8aa6,e29ea591,c0205290,3d38bc35,3b0b0155,113a5bbd) +,S(96cdb3f0,d6194675,7346b2a2,1767fc01,2e6d1ca6,f5e788d2,f89e2fd8,89a57924,9f5fda94,e0455b28,1cccc531,7118b175,edd6c93,c212e7c9,fe845f0b,cac5a592) +,S(7b5e5f5e,564606bb,a71b8f1a,7d410b1e,6482f508,879e1bd,38ecdc44,b7effee4,92a3f1b4,84ddc60b,4b005282,89984241,4f91b9bb,fd55eaba,37dddd0a,dcc1c6e) +,S(541fd344,c9d553fa,1e87c9cb,72150cae,a69a9a10,771ac96d,fb292be7,261912f5,80ef7a00,6ce5ac0e,975ecd69,601fd059,a9860e07,77f6f31f,365187b1,f6c9b392) +,S(2b2b3929,50b07da0,5c20b72e,4101e36a,bdfccb6a,2a7f36d5,b57f58dd,1403035c,ff6c1ba2,caee889c,14414086,456f096f,d065a7d,d2f9c7b0,9ed4eb71,3b4002a0) +,S(23acbca3,4754dffa,8cb3176f,d1435d6,4cba0deb,84e12ae7,adaafe88,497aa60c,5d95b3de,26f703a4,fe9efaf,cb273921,56a49687,a71433f6,9a2813ab,5fdb35d2) +,S(5fdfa393,6bf9c699,24417a2a,f36054d5,95640b6e,3ae30807,5ef51bb6,cd63fe34,97fdd994,bf74c959,2a5435fe,f1baea41,8a79c5fc,1243fedb,5fbb0466,4d599d04) +,S(177cf8ef,58aeefed,2832d53,417c7025,c6b56fb3,8122ccc5,2b33f79c,71c461fd,d8a12d8c,69da9b31,832cc10b,55b57a60,b900c19d,f8f38c92,f6bccfdb,98d3acf8) +,S(14f90282,e5a3121d,a59e919a,fcd146a1,9251cf5d,c0d805bb,bd013eef,4ab78bd3,74a504be,928ed13c,f29032e,5c3dcb3,a18a1df8,aad26b4c,a64ebabe,6afb4244) +,S(31099221,e6ceaf16,81b22b33,dd8ee3ef,1c2a95f7,2bed88e8,15333f69,f91867b3,772e45f0,930ebd2b,7f5b7ca0,640467a0,8ab5472b,f6bd347c,903cfecf,8f80176a) +,S(a6a0a416,d8eb22be,49036f4b,dfc79c6e,6cd167cb,38813269,70e199ad,c5d1b5de,54d036de,6b84f308,84faebee,4f944375,fed61a6e,7763bb40,a283ab52,3335af10) +,S(c7c5cb1d,ce484477,82e7da9b,55bb8482,4f715a80,d844294a,3c05dfd8,3dde77cb,bb66731,1bb0c2a4,e493e257,d289a42d,3630ee24,ba0f7f86,134a7c6a,72dbc3df) +,S(f1bdcb49,43267948,fe1c9b7b,51afcc79,7027e4fe,f98c2175,d7d1b8de,770328b,271f57bb,a9249cd7,dc510173,5a2168c6,ea97b341,b44cacc5,4083d115,6de8e728) +,S(2815f09a,8f0e2dfa,d21f50c4,60b8f69d,3aad54d8,aaa99226,86050582,b954d912,dec68871,752d862b,32ffdf2b,482ce1c0,6a659bcd,3a2931a6,29bda260,cb3cbf35) +,S(622619ba,8b74a0d0,5f8fa899,aaddd272,c9e6d43c,49bb6708,367155ec,4907d0c2,aab9b1ad,10201d50,7bea05bb,5b20453b,6474154d,ebe3ddc0,c86535ad,7c701954) +,S(a0390604,a40611cc,6e36c81d,30cc3e75,d162e695,1ae0515c,75417744,c093b997,60428c28,8d32d229,7417b6d9,b1003522,8190a83,66cae58,f7887037,9fb99641) +,S(422c7d1e,b0498cc4,dbba0135,ababc80e,5416f187,11f0dff3,80f1e1dc,23bedf0e,9c47d3b7,eb5713dd,cbb9ec8a,60d931c6,3382452,a4c0861a,847a354b,ba57d9f1) +,S(982844d4,7f572298,afd6734d,98064369,d81e4851,4b176059,6d3a1e85,6f043f5d,9b86f6a7,678cb5f9,a4304f1a,a8d3458d,fa85e65a,ffc79da3,faa1fc8e,a2b7ed2f) +,S(993385f,a76b9373,422e4411,b9e8a85d,3ac0e09a,f9598570,63d50a8,67b67ed2,3e7a9a3b,222a66d2,f55fce7f,e33effbb,bce8cfc2,8991d8aa,376a8ce2,4e9b8460) +,S(15b05ee3,179d1dfa,61bfb0d0,1903f93a,f7e04f98,cfd40be3,2ec094d,1bd5a4a1,ed1301a1,451cecad,30e8fadd,801c9db5,5acfd697,3ed36621,2f2e3032,adddd939) +,S(6062aed5,7d6312fc,433bf7f4,9c10772e,829e294f,e7ad07db,177c75cc,9fe5e52e,96aa4495,c6eb07da,9a5a0e19,8771dce5,23a5d7ff,de314562,3b704f44,c4ffcd24) +,S(ef45dd6c,1213ac0a,5df18426,9491cb3e,bb5312d3,fb55c7f2,8351c98a,1ba564e3,91541d32,43e032f9,450f3605,cab238f2,703a9eea,8e429824,7a6ef63a,45540e68) +,S(a1e32dcb,c3a13a46,166ebb73,7e09041c,3487120a,6ec46987,6befb2a9,94f4a69a,ba88b7b1,8cdb2088,b5998b34,461b8a5,d85a57c6,31aa10f8,6ff808e6,3186e5ed) +,S(817e6c2,6d4ae706,f43ddd7a,cfa4eeed,6498ea2b,86aa661,9a0b45f4,e22ea33d,8aeed38,bccea5e3,4923b959,53bc9629,d9348442,4f33b06b,b02c882,25e47bf6) +,S(e734f5a7,736014fe,2ac9137f,d025f914,7574d67b,3696596,9f89b5e1,aeebf88d,74fe8220,7c83d3ba,ec54f032,f11f9309,9be25f53,565f0d60,5f2ab406,5287c997) +,S(87b2d307,414c314f,184eef07,6e9809d8,ea19c002,390b5047,38eb7bbe,ba1ae7d1,37f5c369,f5dd54b6,87729036,b88dbf37,45f33da,8c2bc9b2,64213468,f1c56841) +,S(dda23ad9,6c51604e,602b8e6e,9f08a67f,981bfa98,93194369,269c56b7,7986b772,6de02623,5ef973da,13e2577a,bbcde720,aa8fbe12,23c5288c,5724bbc0,228074a2) +,S(8d56a723,6adfe6a1,46182431,da5ff846,aee78931,27564954,f14172f5,27048fb9,c7cd6bfb,fdc51a83,252d4e4a,2c978cd7,67fa3809,521678cf,7dc5e514,eaf0b418) +,S(9da30ccf,f147de11,de528d14,863a4fcb,a2ef228f,506aee98,eabee895,eb618def,a4ab41eb,a16b4733,34a818f4,b6bd3c43,de4a9392,c15c9e19,a8b4e961,7fd4bbe7) +,S(e3339c3a,b14145e5,40c08544,eaa631c4,7be6c09e,563ec93d,2a05f219,f4afdf2e,fd586d7f,3a668a0b,f888083a,9ea84f48,43598417,f55dfea9,790ee89a,c412fed7) +,S(a6e08d07,66274337,f3b139a8,d6fc3f61,4dde9ef7,2e03fc52,45f7dfcb,1c0ab41e,d9620b61,116af945,708a610,c78f0b52,8abd97c0,21ee34fa,10d289cb,f3c06d4b) +,S(f8ffa0d3,b463fc5d,44e6eaad,caecaa85,8515bc4,69fe76e1,4ecdb25d,e503a040,e80dd6f8,934fa405,fd4d74b1,1da0d09c,dd723df,daf46221,796cd7e2,4bb83f1c) +,S(22a212a4,3c00408c,b4b94e2a,45a6a999,917c0fc7,aaa565d,c6f982cc,64b0d0d4,663d8ed0,3128ada4,f421853d,8ffd8201,1ec8b997,4b0d827c,ed318551,ff9930de) +,S(8d33b62,f162963a,f6636f18,ef33a83c,e9a17fb6,b1fc58de,6d271d,472a9d82,cf0092e6,60311726,e0856ff7,1893555b,625b117d,4698e4f3,f31611eb,21a56f5e) +,S(3bbf59cc,5b4aa31d,dfa0ce94,1853ff69,9db29cc7,a0021cb2,11ba28d0,1dc61d3f,d54beb79,d1edb94c,d6bd5ae7,11a3ff22,9f2baa0b,efaa139a,e4724ae3,624d8318) +,S(4cc9c2ed,3a7266ca,faffb517,d3ad4aea,2d4d877,d9b08433,a4fca2a3,691aec68,70ac52d6,1094da70,5f714f60,854a5656,8c25cb13,1502171,7bd4085e,8b489756) +,S(a997cf82,50d7ec36,125189bf,eb6b8631,cec31fdc,f156d34b,186f29c6,5d0b30cb,ca73d95b,93b43983,b2c51518,b4e419f8,415f14fc,b6356287,cd65d49f,92929d5e) +,S(5fae92aa,7c43ac60,b4bb4f90,ae2ac462,a6f88681,9aeada99,4d0694a3,a6dc1722,6b7ebdc4,dbe15dd0,9c1e4587,c7f297c1,74d5c933,6bc91511,f31e0cae,2e51b280) +,S(cf541216,323a9591,13561470,2b187b35,fffaff7d,8cf1993a,5144c7d4,aa836308,9d955733,feaab81c,4b03fe4d,25fe36a2,5075357c,b6ebf8dc,1822cee9,7f585f80) +,S(9c2c8607,bad80760,efb4ba73,442a359a,c1cb9b45,f81e54be,28f3f6f4,4699773e,7848812f,f3101eed,137b4dd1,4f503a42,9d71c157,449767c6,a5850204,869a9817) +,S(2f3bca36,fe504b7e,93f70176,2e65dacd,250b3789,541076ac,86352481,c896f77e,5af55f5d,b2e84dfa,38bdd0eb,fde7ea68,33471d28,add88dd2,a7e7c63f,dfe513a) +,S(f2fa3afc,fe4e5da,385f26d8,1848f801,7401b06f,652121d6,9468d2ee,f640260f,54cea12a,b4ced3ee,2ca351df,4310e96a,d3ca0d80,c3a3c86b,267c4620,bd0f69a2) +,S(82559cc9,ead1465f,a910b781,cb2a50ed,9a2b6ff5,d8513182,425b7dfd,983afa50,db5dd99e,242287bb,c94cd149,6e4aff70,7232e2bc,1fa4c440,5cd9f22c,fc4d239d) +,S(954079af,1494e324,fb707e7c,e9f1fc2a,751e194e,4ee058a6,e55e26d8,34901f5,2f90eb0f,43bfff96,c3b0f3a1,bd48c00b,85d3650e,52d1f614,ed65ce70,4fa19e99) +,S(c913a980,b1aca09a,19654428,6edfed20,dce31676,1fbff05c,1c05fa70,7eced342,17d2864e,df39460f,99b5b51c,91752c57,10ca7af9,a6e10c4e,c2b3e9e1,7317d3c1) +,S(815b7dfd,3b97ad9f,cf6ce427,ffe4a91f,2b541e2a,11305b17,2fd7b63b,82272db0,f0b958eb,fbf32959,dbc407bd,5290ca66,6f28bcec,2fa69d1a,7108a2ea,19d58484) +,S(7f7c1689,e93b7c77,20ab5b74,572e87b5,d2a907bd,624fb6ff,d5f29f3f,c64795d5,691a2f46,430c53c,375829fb,46ed4030,b5bc4dd6,70646523,45fbadbe,e6f8a1f9) +,S(8911275c,106e5a48,1c3dc5be,b9b42e2,3be8cf2a,5a76198e,e6749b24,bd9c5e7,747cb0c2,16d899c0,da5a8ed8,f279a650,f4537e7d,ca51bf56,b3ca8c43,92b5e99d) +,S(24cc2552,c907e757,9e85bf7f,fc868ebe,53e44b97,102b31f2,38678bb7,ad8c244a,a152808f,7d615060,ba9e78ae,720c2fca,a67772b7,fd99ed6,ffd5fbe7,ed114567) +,S(b0fc5873,68795dc8,55e3e19d,9236244a,812d1920,afef4c9,7f1e6c79,25395f85,f8b46879,5a0e40ba,2029538a,fb7cef58,9bde7b3f,fcc010a4,4ac962b0,afb8d7e4) +,S(cd6f4558,d634fc66,6dce566d,f94397f,d3ab9178,affd3707,55852679,adc6565f,d34d7be0,ea40586e,4f9007d7,4aca55e9,edb4b31d,8ad4f344,1f611a9d,94161b8a) +,S(fc5e8a3b,ada62f0b,6453f445,7dd4aff3,993005d6,de7b94d7,19fd487e,b88fb7a4,46041321,f7fed84d,2266d4a4,d86d836f,12f12296,d62ed296,6a7d5507,d6717130) +,S(dc72a540,55c962ed,90e64916,bdfaf6ea,aaaacbe2,fc180a7b,7e7bda98,f45488d9,e3b46394,41a2063e,59c4cb06,1a0a7e5a,a171fe39,812922f8,c04df63f,41c8e588) +,S(7d135c33,88bd5896,47f4cc3d,67fc7809,a7a4c530,e96fb5c,7dabe3b4,32a4fd90,79dd3834,8a61b642,9eb7a837,4e9c2176,95cff14a,3596a18d,19f84360,8aa0922e) +,S(7a56712d,b72ac3a6,353dad9a,15cfc9d2,7d9ff67e,9a35936a,e38e1c01,5980980f,6eda856b,9b5d4019,d0efb2f4,9f1af933,8969872c,126b2682,f56a8b08,97a83696) +,S(d3495480,25c7f966,d59b40d9,6ccb9831,2948c992,fcbe2f6a,7a7feb6a,946125a9,b346f8bb,532da4de,96908618,b0f85a10,fe9a87a8,d612e4ac,53bdbaf,9dfdb3c) +,S(22175a8b,d0a51763,d1818054,60951698,14af196c,df8648f5,29d27a9a,825e60b3,756d5713,81b5ce71,e23c0190,a1062fd0,645eddd1,7dc84c9b,b1c7d810,c13db63d) +,S(f557e381,37a1c6e0,a19e4207,4a1dd59b,17c5137d,97a58fc2,55d18be1,bf63877f,6cf0bb41,577ea3bb,7c9945d5,db33a862,3c1cce5e,d6fc13b9,b0739ea9,9af10381) +,S(8ddbadb9,c6a78978,2540d3e1,9ada3ed0,5ef35f45,a38be470,7083dff,75d501cd,75b4c5f9,51f70fb8,a89fec5,d52ea0b1,dbfc5709,3c1ee5eb,ff2ab0bf,f5854644) +,S(53f0892,cac79f48,2194dd9f,fc076305,a8ecdd4,977ac278,92e2d454,965a2aee,b39f7a9c,ecdd4ed6,d0fb1608,3b86d1af,68aa85b8,c733617e,5e97ecda,269ef97e) +,S(2712110,8fe28f55,c746525d,e7cfd4c2,f3a11b8e,3c6329db,a57a7b32,5a7edb40,cf6732b3,74681ab7,3448bad0,ae54b953,ee5d7bb2,5a8658d,3b366a78,dae5fa69) +,S(e7627b26,ff0448bb,cb45a538,2ff8ec9f,9376127a,b8425213,46e899b4,41cb5660,79842f72,e02820b1,e6b6843f,3a0c23dd,c0941ac2,b6fd30a4,39397ede,c78bc40d) +,S(37c48874,f07ce0c6,cf5be181,9ba31bfd,9a19aac,97b27011,1de59fcf,559fcb57,34dcc405,6a6dfa3f,283e0dd1,8b1722e,bad0e367,c30d9f1a,d552f394,9ce19b22) +,S(316868fa,33cf5544,1e9b9bc0,9f74fa1f,8daa9058,3fb8b3cf,8d339971,311eddfc,89fa5c82,9d9f4687,f7cb6b8f,ae20d6a8,cf872ded,a7f9b6e0,6e168c1e,45db4e73) +,S(d34a83f3,7b7673b9,6c8695f1,81ce837f,ce2f15b8,72664d3b,1a045c7a,bceadd44,e4f2cefd,59198808,15692950,19b9120b,495a44d3,4862323f,808b11b3,a8698081) +,S(687a48cd,4142060a,171a1efd,c41dce8f,8127ab64,ebd7c22c,7803f077,19168799,c082e152,41f7db05,ae6c1e15,e4ccc340,f4a7c8c2,cfd8bfb1,6bcd04e7,e635726f) +,S(70d2cd79,1d2d1418,9cf67e48,519aecb4,d58be2af,164d0605,2132517e,87f444e5,73b4c12b,edda1a70,89ae9db8,f105059a,2a558475,f5cf4796,1042c470,c9e190a7) +,S(2a6f2786,a191130e,dba1307f,f1bb0f61,c3d7b8ad,c02286f6,44871cc,170dd2c1,28a0c85b,8ec93fcd,1b9a0617,780da654,e5448475,a02a6222,f7065132,5ad64b2a) +,S(3f482e12,8d5bfc4e,d2f359cd,b4244db7,ec7edf92,f3fc5dde,5367d125,dde8c772,d41be140,cc4b4217,cdfaed4e,b09ce5d4,d3e95b52,ed6689ed,3f6dfde7,3c581cd4) +,S(96673e27,fb0f8a46,8fcc53de,12876045,77786d93,5afbca99,35545363,6614a5d7,f6a4eee7,1c4249c6,ef850090,59c12f6a,44adb8a9,cefe7a8c,ff2ac0a0,da28884f) +,S(be7a886e,499a9c2b,c05e5f64,77bcbb4f,26772e58,4565897,408eb36a,e25a9c58,24457eb7,802810f4,de64516f,24718b06,d61b0adc,bcf0d279,d883b2bb,45363a40) +,S(123985af,a3253837,e51f933f,8f25591a,823b2442,88cf8ba5,a0247ec9,94eecee4,a952096,21f7a9a4,3867c6a1,987dd661,1d3cf996,2aebfadc,dee0a5b8,6df196b7) +,S(75887ee8,c28bd2f6,a96086d9,aef71b7b,5a5fce50,80c3963,787089ed,e39b0214,47386fd9,a9216193,3bb500d9,a1ee8207,dc3edbc,17d3ccc7,32d9c90b,8995eb48) +,S(4f7642fb,12376864,29104657,2a2fffe5,2322df39,7cc097e8,f7a57816,e6709fe2,4f2ff70f,2e99354a,60cc5b2b,c3ef33d3,7e3e9ee7,16766018,e3a0ba39,efe5f971) +,S(8117d4fd,551c9ae7,4c9fdac4,5d87bb66,9bc7dc35,4b08de03,7c4a1378,734653b,13633743,d1ee8fd7,8482e3a,3a9e39e9,75b0f6a7,efb227fa,84feb897,693c5c10) +,S(8afabdf9,acd49723,d73c0deb,1016ddce,571abaa1,a71ae3e9,a20bcecc,ade5782b,2b66e3fa,ee86dde2,23dcc7b6,10ea8ed2,dd42124a,247b7937,9e190098,2580c71e) +,S(c4819cb5,b5af7aa2,895b81c9,31dc6bd1,de4a1434,daaa4fbf,abfca6d9,28c9965c,ae4db5d5,e1a09a03,67df8c9f,fbd2ae07,9f79ff96,410a9a5c,17229fe,5575c22d) +,S(dae02e8f,5d106f77,c8a1e1f5,4366daee,d312da83,1f86dce2,3e846e30,737d49f7,6d666cf4,73d269bf,aa7c3eac,4e5a2868,57df3661,c949b5ea,7f9a7a0d,11206bb8) +,S(a8762d34,c6f8317f,cba5c64c,68e25d55,e5bf7e4,5caadb65,a5468d2e,f9d779f0,6accd443,bb181cd4,591f8fca,210f9996,86460bcc,89dc06a0,2edd7bf3,d4b75533) +,S(bf503c35,fc8a0c55,fdf4149e,96b2d218,d29e4b9,1f703e7a,9b0d4da5,4153d99,7e1c09ab,a1437e02,a2be3d4d,7a444753,e475acd6,e3a42056,94e68ea3,cb7d1847) +,S(7898067,48cc0ad5,ab3a3449,ac82a1c7,d51f2b96,791ee038,dfceae58,ea0c5cc0,66b59634,96eb4a69,b87aa0da,2905449f,ffd2ae3f,ba1555f6,5c9b8ec0,e94ad922) +,S(25833d28,addd8172,c2a323d7,cf498482,732a0be2,c10d1895,8d097cc0,ff4c9a19,74708306,d01258d9,bac99a69,58ce1117,f245d6f1,4a1f92d0,dd48ca9a,4c7b7da6) +,S(6800bb8a,9dffe170,9ceac95d,7d066461,88c2cb65,6c09cd2e,717ec674,87ce1be3,d5228e3a,1e0bce22,c2d85b44,e670e78e,ffb1ec69,6c01a722,2cd1e62a,dc4e63d4) +,S(3d7d5874,42e4816d,af2f0897,dbb06cea,f6c673da,445a5342,c61a8793,420d107b,422b212c,93ab83e5,d6323ad0,35a55321,b7441835,b83f180f,c3803ccb,46fa4ba4) +,S(3c44084f,aeee2803,34db27ea,63339db3,9e8359b5,c9cc9a85,7ea49740,32d063e,36493b7f,1a732a87,db4703bd,61a76825,4a82846f,31d8920f,2cba7ecc,1d744491) +,S(cefffb5e,d26cf721,a51bfb2d,460b91a,a0b40a81,52073da2,cb75050d,f7fe8d19,b4e40e1,1eac7572,efefac2f,a97e5cb2,a0d042c,3ae8c541,e51be4bc,f6d33f4e) +,S(63add0db,5f5099a3,2f274c38,780cc215,bfd58753,144bd464,e75b0da2,dde97938,bbed5231,fe6d5b4,9679a13c,c3c6c382,5c300fb8,42b5eafb,13355c41,120c6848) +,S(ba5d1f34,63130cfc,425cc6db,dfe08329,4d7aef4d,cb207e3f,d1cefebc,7c791920,70df29d7,8030a8ba,56514df4,b6ecbd2f,ebfaa1b3,df7b23ea,ed16458f,f2f18786) +,S(7d363dd1,c6dd28da,94a7f850,ee753327,8b735dbf,f43e9456,67fc26e7,af75d6e1,46026468,2bd00bad,a5be02aa,5034e762,fe50d02d,6cb8dcdc,5aafa21e,423267da) +,S(e2dc0164,c9060646,904206ff,37f912ce,2d50458a,3ca186ee,fdda8d53,4184070,de5267d1,354d12ad,8d9a5930,443dbef9,65947f2a,5efa206e,146e7b1e,df7f5a2d) +,S(2e53caa6,35f0ad1c,7bc4c2ee,1e29b39a,972edbd0,7d3c0feb,9ab0d945,45815ee5,1bb33d23,ad85b572,130e93d2,fe366e49,8371c49b,b47ceebe,de3c1286,3f443b23) +,S(5dbefdc4,9fabdf50,e6bc1464,13d59940,cb36551e,5a6607bb,13213ffe,b56eba1,893fd0a6,1797abe2,fceb4054,c4f540a4,ed644ed3,13a2200b,e1d532db,44d0374) +,S(5ff207e4,2b52b004,6ab8bede,6bd26f5,316ae52c,d148965d,8a21e8d9,63374a2b,1b778704,daa94eb7,a36ad0e7,22a6d56e,c0b43c7b,a739985a,538bcc22,b9181bb4) +,S(da260b,ff4bfb8c,a54261ed,c96493d3,ffa90273,a55538dc,c9b237ec,e775fb3c,c7c744c1,dbe1cd19,20edbe3,c13f7631,1378140d,9ee64c3e,ab072401,86c067dc) +,S(b1985ca2,e7103268,f18d1063,c59d8d78,2250f450,c467d7b2,f4e41c28,1714421,16357630,3970159a,99a34c0f,e114b95c,f115d9d7,dc9b09ad,7c81d769,aeee6898) +,S(bf98e773,fe93f15a,ced03ac8,368e4276,1cf3821b,461cd844,2426d2d,cd1f7d7c,f4fe02f5,f45a9cbb,b67ef626,f239bad6,e5108c28,d783d70f,6bd889b8,6331185a) +,S(5dd657a9,ff99f15b,56c5143e,86ba7bc4,b0f34957,71d91805,71a3d003,ff008fa0,8da0b780,f644b14d,2b661b9b,484225b9,86b13038,a8a9bdf6,6999144a,4f5c212e) +,S(53b42d75,bccf2203,7252ee9d,25830f3e,36e7ed8d,8e1b6d4c,b2371e14,fd4fdba9,7791453a,dda2ca19,a775d684,9ee60c18,ca495808,6f8b56e5,1bf2b216,9690cd73) +,S(a3f43f6d,eb178109,cf4aaeed,a0666bec,481a1894,c25a4fc7,f4a87e82,680d63b2,d0331e73,7dc25db7,35625621,85073240,3a69a474,d5f78e54,93486b5b,3d1c067a) +,S(b83bea86,b07b217d,ddac9cde,9b42b334,c994cd1f,92beaa87,57a7e7cd,2c71b1eb,b68f8fd,66b45aa0,dd568458,73eb7829,1e613569,58345fba,7dcef9ee,dab957ca) +,S(16ce1de,573b3654,a0c00212,e878811b,25832f36,373da91b,9d9d7c89,d06ff12,264031fc,7441fe5d,4ce8ebc9,232d1837,7fa810a0,a0e19ba7,5ab16ae5,e93d5763) +,S(18fdf98e,93a7e380,8762e819,2b6e634e,f255b2ee,51c65b58,1ab799ff,52409e15,2d71afd6,c6298868,52ea0a1,943dbcc8,ff844ba3,80b177e8,62f92852,97868dad) +,S(3d5f8af4,ff89de18,866f596b,91300a32,a7aedcb2,a9423f4f,e364cf26,e2f53e96,46e9bc8c,ddc56d4d,ba25a2f6,e77a6a70,2e712496,7591725f,1d240e7f,9836548) +,S(69dc1e7c,11516a15,9edfa4bb,1afe0ea3,5be5b7a4,7695df8e,728a8dac,e2997db2,71be8ddd,d4c51c1d,5c13704,3aee6129,9541e929,799f7b6f,da08aee4,52f4ce8f) +,S(4e8278ed,ce9b340,1ddb1c3c,6b208539,164e1ad0,3adc082a,8d9dd5a0,9c63f737,13e6a5ea,7b2e8ebe,babd812f,2579b8bf,56b476ce,dd23c418,9be7b85a,940c5d79) +,S(91157569,7aed20df,771c1f4e,78b73dea,c89b2781,9b8a5ae7,5e2dc12,e6e7d148,e7114d60,218eb1bd,73074957,5b96fd10,50fa2d09,f37c0fe6,2887042,24ca1a28) +,S(3a37e743,bd2fe2f1,3f667abc,b6c03077,fd82722b,859d7bcc,ebeaf1bb,a6087d93,4192a6b7,eef51034,64040fb2,6b8d9928,21e321b8,cd611b4c,8d3e0186,646f5dad) +,S(d45b5787,9e4732ad,ad0996d5,879980a1,fc8dda5c,b628435e,96c3b44b,faf98f09,e4d4f5ac,1e4b039e,731143d7,60e2ef35,dc243097,d2e2382d,b86dc82d,eba0554a) +,S(ae5ff450,aa607a9b,bf4549d8,4d96adbc,6041cb0d,719793f9,2ec53b96,14522a00,2f061b20,e9bca3af,358e8d14,a04f1d82,97d1e1dd,a406d60a,d15727d0,66b2b8fa) +,S(befd3684,32785d19,7709ec42,e3b6407c,7a539b55,d97c8fe7,afd4f96f,d2050e17,65691153,b2efb4af,ebd2dae1,a50fd3aa,b648c7af,f5804d99,5270cc22,c02e151f) +,S(d13626c,bc00cd,36c776c7,8bdb17c8,18a2bc14,9612e0fc,7ab7888b,eab48382,ea4c3fc9,fe2238f7,1023ab83,fe0e09a1,dc167c0e,6aa05933,8f177cbd,241bdd45) +,S(9730fd42,fa9ffdc,414f90dd,ac790110,9619c01b,f43bfcab,e65a341e,2434435e,de61024,6152fb04,c997fd62,961209f9,44badeb3,6ea7774e,30e8c8a0,8bb0b496) +,S(a27e09ee,9dd4e34c,6a92f4be,aa1b8c0b,2a60b33e,99fa981d,afaac623,9f616d15,33e6d8f7,bcaaa24,b6008e44,377b4892,5f88e884,5fe73807,8cd4f405,a2747f14) +,S(d2dc7884,31e5a497,3905876d,bd6ceac7,8246c9d0,73d68872,f54685eb,5970763c,85f96d40,e31ecc47,dc07fea4,4856068d,15d2a999,735aeb3a,4959e4f9,9ecf5fc8) +,S(38fe7a6c,c401daba,981875a0,f0c2f528,30ce31d8,816a1d3d,47a3d96a,664a02f7,e9893a1a,87034596,9d95e644,313d9b65,5896a931,81d36f6c,7e390102,3cb28c74) +,S(f2d38ff,14100172,d117dff6,1522c61c,3a590eb7,ee9fca77,dc264e60,32291d78,94eb4046,ab31eda3,7593e705,792fdfee,2e3df8f3,655befa9,ef0ef392,4b02dab) +,S(9e23c290,94b6b8e7,4e112b11,69c5c775,4b690d0e,141b74f8,2988bd84,78d42021,e2528717,28fc8d9a,283bdfa3,a011d28a,f531f392,b5da6da7,1834a29f,203e747f) +,S(3054117c,33c15a,504156e0,97e9a0f7,d76be8a9,c1c88fba,e1d9d2c5,4e1c9185,998844e2,b73e9468,1b0b09d7,4ca48dc2,f29c6df5,f3c38f7f,b6846178,d4ccae2e) +,S(65d1e830,3421444b,7d5f8600,2c6de12c,16f15a88,504c6876,b9e94cfd,a206810a,71c9cca1,6e066545,b11e2c29,edbac8f4,8533ec41,1e331e15,a2bed53f,1b1878db) +,S(124b78b8,948c4374,7c5b32de,50cbb055,ebf9fe7c,56437573,40723180,131ec0dd,c0fefa74,970829d9,4c1314b3,64a8516e,3a3c7fb8,e1d49f06,b1b9c19f,be18ddd6) +,S(f6d81a5c,395ab698,28e5f1f7,84edc6f6,a55137b1,411baa28,615abdfc,36c18567,3a759acd,4b758dbe,79e22f4b,26774b88,40121768,f655664f,c3f9bbbc,91f564cd) +,S(e76bd19b,fe13dc17,ddd14619,da6b12c9,f2819514,6acef71a,9e7bc32a,7abbea8a,68cee27f,152177e3,afa7d47,903801cb,b20ba02a,c48fefd6,e23fc102,e6456bc7) +,S(7356c0d,ff8f26eb,7df215c5,cf923c4e,237fd7ad,cbe58f7f,d5c745be,6451a830,16a0d86f,ebcf42d2,e89e9a1a,803838d3,1dd7debc,527d49e4,a7db799c,e1eeee6) +,S(b8d00a56,43fdc57b,dd949193,c5df30d,8ecf5b4d,8b3a13e2,64ba3ef7,c8bfacc9,f05acf53,9343641c,3feac336,28e9b08b,9a4e3c49,94c029aa,470fde03,d5d8cf8a) +,S(f555e29d,4dd3e0eb,d03f3866,596be43c,677d1ac4,1a1a3a8,1936ca6c,89618880,171d88d1,9abf05a6,981eddea,8f030e53,117a2e2a,97c2f352,255038fe,32ecf95a) +,S(172e6167,6e7755f3,c6a59c40,97a8a870,cdc09d73,2064d24c,3db8ada,7ca50ec1,7c1e58e0,38f322d3,e147b3db,e9b8f311,135d688a,98458da9,f6f8a6d5,4d4e2a96) +,S(f8f5fee7,d4e8eb51,92cb7ad3,9ee26cfb,44724b7b,f9c74fcd,61f95e3a,f33fabc5,607fd05e,361bfd66,519b5e11,d00d22af,8b0ce85c,11b16cd8,eaba71e1,2ebe6bbf) +,S(6fc770f3,f6169350,bb8b247d,16088031,4348ef73,cee49e5,c0f56a19,d2d66491,47708f10,80e755f1,2b1b0d9b,3439312b,dca07d85,fe94fda8,414dbdc6,ed9353de) +,S(2b8c0b49,94d3f78,79776d8f,bd2980c8,7840df15,82427cc4,f07ac806,eb7f7e3,3a335552,ccb38312,92a71376,9c7994e4,19a7919d,b776ce6c,db2ff092,92e4d798) +,S(e473c99b,dffad22b,72b6fcb0,d741179e,afb78aa0,de4b5d42,dd19d7d7,72ab1a60,2d0f795c,61ed1ac8,b5691d5e,9d52b19a,42c368fb,9d0787fa,8ef3b275,2a3d9d26) +,S(f389dc2d,b76a47af,f9d7a380,ab49274b,1a40c4f7,970bfa63,729da698,b4afdc4e,b15c2100,b63f7f5f,911a6474,25866d79,5a57dd97,74c21cd1,4907dec0,f5f3afab) +,S(df6e3625,8fdefe31,dffa19ff,2416f8b4,9fbc09c5,e86569e4,4b7330fa,56cb6e1c,4b5fedbe,835f0b8f,ae20f627,c8e74f41,a5443c1,a764c466,65f673f9,f62dfc7b) +,S(27e40da1,a5d7cabc,ce586e33,a4ace757,da972cf6,17c3781f,3fb0e0c4,e6f0a70e,ffc4b339,9cc0b701,36d871ea,a7c3a6ab,fa9dc92,72625fb5,b8bde8d8,be55904d) +,S(71b6f20e,e558ac12,829362ae,53900a59,ae29cc70,77dd1001,d9d7eae,36b95618,e765adc,1125219b,316beb88,4c0434eb,a6f62499,b8b2d217,c209c7cd,622d0597) +,S(535d5fc6,1eef1a92,50ceaef8,e09e1797,8debd360,8b03f72c,bfe265a2,633332e2,f8453dc2,4ad1ef7b,819d4329,a4752757,26c98e55,65440cc5,b5d509d8,61c98a38) +,S(d1e2222a,26817cd3,a537f2fb,7437ce06,ce9fa651,9d3c1967,71aac21b,97de68bd,a131cb69,cbd27e62,cb65ab48,a7f3035f,a78ef40c,6c42e94e,da326ccd,2b452849) +,S(5aba9590,2b5062c1,59b9639e,f08912b8,e7eacda9,759a4e98,b0e21d96,c2597b07,896a74fe,e2596e46,1e93f4ca,178646cb,4bc5454,227a2dce,1bb5d532,e558b334) +,S(9f07bed8,4449bf9a,815a546e,ffcbd0af,f22c9016,188d15ad,7c353e2e,5cf84343,6fa14d01,ba16dd07,15f3e68,d57738f7,1cb56d95,61eb84cb,ad63bbd2,d9ba439b) +,S(80a1920b,14723439,cc2090b7,189f96e0,20e6eba5,5f8964ad,2f0be013,b4925515,fdb63791,6d074376,8e32f983,f2ff1754,43136323,50b98674,2ccb9ae2,7997a020) +,S(dbb37c16,202dfd9e,914f2922,e8930789,a70d4de0,9fe7eb25,7d9a2b83,aec2b4c2,f6bcb8a,2c7bfa20,491d3fff,bd36e82d,91a7228,9e4fb6f8,9e167803,a17b7932) +,S(f03035f2,f0ad31ac,59e64a6c,f46e9ee2,a2243ee7,de5ccb0d,cb30083,97551b4c,1a1aacb9,798651c1,2bdc6ce7,4146e259,4263474e,d7b9d42d,78026331,60748722) +,S(1886fa45,e7447e89,b0873362,605beafc,4e05965e,53fabe41,41e1c42,4fb234d5,eb5374d,a4a198cd,d9027311,6b4331ed,f0f6a7a2,fc52aa44,8a9274b9,ee3d7743) +,S(46a262a2,5b76baf8,ae0ba3f4,ed8f86fe,e4854272,cbd0ed41,313c4e0a,357471b4,c08ee494,66d7dc12,a8e08880,732574e6,f6fedbf2,71d6dc37,eec3c324,33d8070e) +,S(d521c6c4,a0db2668,5a36b61c,b73d3504,ea7b7488,e3d75410,494e89e4,ab404d37,41f334e7,6a28cb9e,25e6efd4,fe3eee2d,17480189,b921d726,aa027b3f,75f94bfa) +,S(8f44a4e3,c18d714f,62054e54,6e9ca86e,818fcf39,fdde40c8,3044ddbe,be3b951f,210ec152,f8c90d7b,8486d1f9,c5c49a48,68249795,bf7d0171,34d9573a,d5b22aaf) +,S(d5a74098,eb20aaf7,b664fb8d,63e08b0,430733f1,466552db,417ec648,36a31dd7,7eedeaca,97f1c85a,98496159,eb024564,1c8ef0dc,21c31ff8,9d06012a,3387647e) +,S(d2a63a99,d6ab9e57,a2a6d39d,3738c3bc,94505332,2a34d3d2,4cabd1ce,5111bb08,e50f6c3e,796ac830,e276fac9,ab6738b4,722fc87,880f2e93,7417198d,9c6c1323) +,S(a1b826f2,1f7abe38,c622b93a,7510114d,dffe4cb6,d3fe0627,dcc0465c,bc82ad9a,c9cec051,a253ab24,a8507b07,d24ee4a,c1d5a5c7,33f0c3d5,611e8a9a,e4aa9667) +,S(40719ba6,89926b5b,ca99a4,161a1bc,d999d40,2311fc5b,e2f5260a,c3c10208,9edb353a,73e9fdad,96ca6b77,b467dd9,c7d6d2c8,e041d8f2,19448ea4,c603bcd0) +,S(c0ee8dda,80fed10,721e7cd8,9dbd237,216f4e84,bb8f7138,11f8ca16,1e3a0977,6a786e53,2a0f49cf,eabf0338,1d64de56,1a1973c9,36d6a5ca,4aaf4cba,b8fbe1e7) +,S(9c75860,ecdeaf1b,c598a530,48a22158,8099afbe,20cb08c1,3afbb133,b2681809,d7019eb3,5fb61aee,56a1afaf,2675a028,b8735dcc,b3f5d93b,c3e29672,9203321b) +,S(e39df640,6dbf2584,fecea5bf,aae78b5d,bca93ef0,9054c754,d8b235c2,c5463657,33ab2fce,3a2e3e7d,e2ab230b,e69bcb7a,4d71c87e,a1ff5d34,eb8b78f2,d5c61a55) +,S(22480e,4a7cadd0,d17a418a,78074f80,c4731ce5,d9f1268b,1ca50204,1ff8282a,993591da,11ea4445,8ccf8bc,2cd55fae,69e96a77,89d006dd,b85a22ae,85316200) +,S(c613fa66,231d38b3,359c3b94,132a2337,e2a8c608,3c88b41e,58434c19,48a6a1ca,8087377b,c3d6ca30,8c932dc6,ff82430f,3fce21c0,1a8b8b6,c28bab78,d3ddab43) +,S(c0a94837,c2fb86ad,ca791fb,bb0838c1,3bb0c981,e23c4ff7,94dfa5fa,c663e5,1f81050e,d21fcd5a,471657fe,abe6fccf,a391f1e1,9a88c143,4644bfb5,e1f69f9e) +,S(87ab257a,cc2296af,d921bebc,8e52fab1,c9c21f08,ae09faab,18858a06,1e408ccf,d5dd88e7,89d2f2d4,3773854f,ca980411,3dd69475,a56864d,3c869205,d682027c) +,S(10d14c28,cf44c5d8,fbf5caf6,b307f6f,ee203968,eea1be3e,b3697515,2edf45b6,46926a1e,dd4f79ad,74fd506e,4443375,23ec76fa,e09d216d,3ef3ed4c,73b635fa) +,S(2eb78fea,63035a3d,db64149b,612832b0,c9ab7880,539c67e9,d722e252,f7e23166,4f72ef76,d3dd59c0,a4e1be46,6ca5a3ce,fd84d207,f7d671b,240fd41b,20e72af3) +,S(14d8ab11,402af341,dc5cbb6e,1116b858,14decf11,e6761b09,31b449b0,20b6f56d,91bf8c4d,cc717657,990e0e3b,3558a01f,ebbe534e,897d1204,8a7d978c,3a1d735d) +,S(cebc042f,2e7bd361,934da5e6,dd2dc8a,9e73537f,5d5e3e46,3a88bcc3,ff6d5552,baa841c8,5e0a7287,b1f16c89,8ef03f22,3097e92c,44952c32,45f2fab1,dcd988c5) +,S(4f28e546,ef539c7e,8f33191b,897b7245,8f48a01d,79f65b8e,a8f672f7,d0ab027b,b1c1db0d,55be796d,2b415259,89088a7,d86c41f8,cd8ccdff,2bda49f2,407123d5) +,S(c4d31178,b73cf9ab,b0e1d554,a2cf93db,ed9a7b9e,8f49c9c5,4d63c815,6e111505,f5e4528,7089cd96,3118e279,bfc6661c,1e77ab67,b81a71bb,4ec14fe0,ef0c13f) +,S(8e260505,bf045c43,f3fd972e,d4189725,a4db0774,52f94eb9,51e42eb5,6131f0f0,4afee681,c6069893,5ce21991,208457b0,11548d97,9a33a0be,cf3c840f,77c4b4d8) +,S(982818ce,69b4c6f7,631daac,868af6a6,79fa6631,8c9da2c4,bac994ba,f9c95d81,f5b13c91,e7593e5b,69c85957,6398b186,8c503b6c,25179270,7e602f52,f30ca9c9) +,S(75c2f2b3,53720779,8737488d,16a5ca6e,dade382b,78f2b2b3,226fd5ed,6ac6c855,95aec19f,b97734cb,8426e530,afda15e4,c3c3dedb,2aaa24f,7ca73b4b,af475960) +,S(606ed5f1,8e4dc1e5,3b6f5ae3,896433c2,a904cb84,1ea021fb,84537f6a,9dd45ed,3165cf75,26f277f5,b9bf22e7,36291513,10158d63,b97b7c88,d49d88d2,d63dde9d) +,S(a33e07b,c2934f5e,f02ae143,6b3ef5ae,d2d633f4,2b40e35b,d365fe2e,b8c72d51,e93cfd7d,f2e98817,9eb9c348,73530504,bc5cd8e5,d8393f0e,844073ee,df6d6511) +,S(5ee1d077,735a4a18,533b36d1,eb484f14,98b220eb,cd41746,b0947403,d6b4644e,7d4e1233,46a6ba1d,8a862514,4d4bc5be,72e23d,f25287c7,3512817d,e632f8ef) +,S(7485b837,2bb28a8f,d496f6a0,33b92ba5,96202661,8adef933,d6aadc56,55765b0b,a58defb8,deb4445d,80016c9f,5c04c2f6,e06986c8,cc95da94,3105d8fb,d0fe84ed) +,S(3a321f94,2268584c,cac5d8ce,5d6011b1,22169e73,d9093b2c,e3e0bdf9,ad680d21,99fb13c0,ecb6c544,1347a4fb,842a7269,1492219,f9bb7c25,1916f837,7d4e2cc0) +,S(c115a2e8,265c6005,10bf7108,ee30bee1,77893d5b,ab0a8cc1,754810c3,3f112585,e2f0a636,5836a24c,7a5c6997,45022e8d,e0b88afd,37737c84,d1ae437d,eaf0b3d3) +,S(d8895b97,cd390ca2,cf8e6093,c125541,1602fd98,97074a8e,aa11bd3f,5b0f3c1e,af8c594b,bd2308e0,12a632b3,1d05a25e,23247f75,6d7a22f6,fcf48cde,28056ad) +,S(4ad1fd48,e77fe497,b4a15e7e,869377bb,163d760e,105e46a9,a5477d69,fa944eb5,a96cce4f,e2f5f590,17af2359,1dcbda3,b640271e,95290d59,1fdcbd8d,ecf39703) +,S(62ffcf4b,7ce6c5cb,76766893,bd0a6f2a,e33ef821,d953c001,51c4be3e,67f2cd8b,d6b1d025,152db954,968ea1bb,dd2a89db,16103f55,47cdd042,9b7380f7,c4c985f8) +,S(e71343c3,cec5e49f,60fea970,6d256a4d,ba499e86,6f9ab33d,6045a1be,cac40a,ee1fe3df,df226027,78228bba,91afd126,a96fc10b,f5d2cad1,26091119,3a92b426) +,S(31766ef2,f3531ead,2c7bbaa3,279e81e0,b040182,ab78065f,d193061,2792035b,87b93ca8,91151ee9,775669bd,df2e5bf7,9f728d52,efabf584,352ba4db,8cd6f6d7) +,S(1e8764f1,982a97d8,b65a0a60,53a2fb5d,39f1221e,dd4f532,b007b2c8,c52d39f,8ed84e0a,de68b789,5ecf8c07,80ba0b26,53faeb49,3d23a453,cc23987a,b51f3a18) +,S(e249cd91,4e35f97c,92a07f4d,6f9961bc,d7f6efe5,ccdfd44,cb3bb698,9939fe43,9ee2fb47,4abdac66,5bb0178f,d8ff3bef,6381a90d,bfab05e4,a9e5566c,cc362ffd) +,S(b9a28764,d21db971,f7cb0c1e,87c9db64,ee6a1acc,485a02e4,5d5ffafe,ea1012b9,1b55a989,43ff4fb,25db6aa1,12d5c459,b1ee0fa3,aea913cc,54878682,f625e882) +,S(5d042803,9f8c37b4,dc92a9ba,43bf7213,971488df,be699901,31820bda,c0b6ff03,1ffd5348,88796c6c,a631c3a1,4773f89a,ea6d5914,bcdf27c,38949147,cab8ac1d) +,S(6d817b42,52986e2e,8ecb908e,99011265,df0cff59,61a82b2c,baf0c61e,c8b22326,55cac99a,d6a70b96,5559af1f,c5b67469,5d653662,bce7594e,22916fa,7c4b826c) +,S(9b069431,297f0d35,91451039,df8a382c,1eba93c2,f62f4e98,90e54559,39916ae8,70bf9138,a04b9f14,2841a2e6,bdc3600f,1b22c81c,ba27f308,19a763b6,e64fef71) +,S(dbf5e41e,d83110a0,5dce4bbb,bee05f0b,f9700ef8,273b4bbd,57099bc9,460050f6,e3e8f5e1,697b05b1,23632b89,28c3b34a,6cf1e6f,327b4252,c3009046,c8406404) +,S(c8ef12ee,22aaefbe,9ca024bf,ba8fd744,d7c5d489,663cde66,a3ff1dee,8174ef33,db64c2c,db21415,fc552968,fbef01ed,131db2f0,1ec8372d,1b9da98f,4792e8e5) +,S(3d086c8f,af84b66d,bb9212f1,512663b1,793d6893,23f45af,9bdd17ba,fed8d7ce,2d6a47fa,9e1b6c20,a2cf30dd,a99547a,b9ab9c13,5ef86ebc,280ac62d,2ce7847c) +,S(e173d58,714db8bc,cfff3ab8,8cf1be0b,547e03f9,db60c97b,ba5a6735,cbf4bf4a,44b8f991,6764f393,68b36b56,9033e304,7fe90662,70758fb6,85cc3f6d,e31b2fc) +,S(31ef8faa,90826125,66e739cf,299de928,68c6027,b882978e,f72d014c,4aa4f379,9fb9e021,fafac237,8d21caf,f1262d7f,bd9b8333,eaab0fe8,8a3499b3,d153a2e5) +,S(5e112e52,2997b67e,146b998d,781bc528,7e2ad47c,b2c5863d,eccb0873,fa088b3b,19cf3f06,d3c1fdeb,8147e074,a42fe178,c0b14135,2dda5274,50a7d5ce,58d3d441) +,S(9ba2cddb,c1a5153f,89e9144,e862acfe,c624095b,8cf8b7a5,b15edd6e,c7b70eae,f032469b,9527911a,92dcff6b,5847fbb8,9f4ce42e,f20b40d4,80b3a58c,72fc805b) +,S(9ff7e46a,4e2c6e9a,d5843f4c,c5e112c6,557babe,723203de,d75be7eb,179e814,ec890ac0,2ece651a,6614bab2,1e4944a7,d248c886,bebb33c3,36c28df0,69be91ff) +,S(2a13752a,1aea6e21,d25ea21d,b644ab0b,fb84b130,8d3f2083,be26098f,fc4978f1,18f4936e,65ab66db,11bf53e5,7eb7d114,4820fd01,ed827f96,652514fc,d8ce910f) +,S(a0647c4f,2b4f271,97f3fbc3,bd81bc7f,f72d964c,1bcc131e,caf9bda6,57b356d7,5e023102,9a8eafe8,9466181a,80440196,e850390f,d42dfbc2,1d3fbf6d,6373a56c) +,S(6abaff96,aeaca928,ba9a0503,dcff7a51,420feffc,33b1ad53,b1a7bd57,8c641ede,ab59c03f,7ad47f73,df424882,dc3ac2bc,dc2ae6ed,3eaae48e,b807b010,98dc0de2) +,S(442abb18,54161ba2,47fd366e,52d40d56,65293573,c339aa2b,28dc67c6,70f4ee99,c3f44b44,d13ee3ed,4ffe5188,c5134d60,a28806b0,687b5652,99924655,342a5898) +,S(9f54f23b,45f632c1,f05245f6,c5d1c433,9e18671f,da494eb4,3bd22be7,b1610096,25c9e532,1a5563f1,f47a1e4c,99d6def8,541601ac,8420de96,190157ed,aa17445) +,S(50296c0c,185abbc4,1c86f578,8dad10f2,7f76074e,24e931db,53944b48,6ddee613,81a02b32,b1edd539,37ee1c78,ab630f2b,45336e16,cfc560f0,adeb464,fb71b9f8) +,S(39c2d099,e2892b2b,1b6abb1,a198305c,ed59d94,f7022cd6,d521b510,9a8fc219,8900f6e6,3fe1a7c7,27728b92,aea4d70c,1316570f,edba940c,e626e94e,f03dddff) +,S(3581e30b,17067e44,664201ba,d7a6ada3,e0648516,260b760f,b406dc48,11c9d0f4,c8bac129,83e49250,bc478ee5,fcfc0660,37d68f9f,fda1acc3,6861743e,d7a794b5) +,S(72b67dfe,d341824b,9fa09057,b8362d1,38287eac,7292610,1169e41f,19dce477,be527b0e,52ce07a6,99065bbd,ebd360fb,72c6dc77,88030aa9,45fbbabe,7f038524) +,S(805af91,4a973e36,43712cd4,4a1da4a8,3d1237e5,9c991387,17175aec,4a8667c4,f6a7beea,205810ff,5d1f0e8f,5818854a,bb730c7a,1ddf02c0,968b1b05,92ed8a15) +,S(44794289,4b297a87,e3cdeead,5cb2dc42,9fdeeed5,b8038189,331874ac,88e67536,d67efdbe,8d7ab8e8,1e25c340,77687b94,d22d8ec,b89d7f5d,46ca212f,abcc1b5) +,S(b73347c9,baa967a7,5e5c8ac3,14f3c6cf,275cc893,72b26bee,731693cb,48d36df4,307f8fa1,98f1ba57,7ba330d5,816cb8de,d9ec3f13,6bec0586,53c64675,753f1542) +,S(ec6d499a,efd540e9,357f100,4a136049,d1f7df5a,d99c44c4,6e3ed416,9e40acb6,21e8082c,df4fa2a8,38327e80,aac15ee4,40549109,aaf6ea01,ccbfb95d,3f7a47c4) +,S(7607b7ff,8bd8369a,67d22545,c40a1588,aa2e50c1,b5be6115,cbb8794e,2085f283,6c4a9aa2,1dd2ad4f,7d6c4f02,23885803,ac3b06fa,6c0772ec,bfb610b6,a1d25ea5) +,S(dec4b7ae,42e8a25,2c414458,d4e0d7fa,4bf4d0,c9432754,13d3b770,8fb53839,bc54d902,6d035b64,35796475,67805bdf,af6cdda4,d0177206,384c4ca9,8edb5898) +,S(a7be1017,82bf48e8,37c2e0ec,821e37b3,eab03607,36561152,a95a06a7,fbb7ae2b,dfd27057,dfaae0a9,b9523a9e,dc28a2bc,3631e84d,5fdf8c3d,e1e65055,805fe0bb) +,S(cb398b20,29e55994,741b87cb,592e9099,926229a,aea60bd6,30eaa528,726a04a7,263e89b5,85475a8a,50723568,d3328fdf,56c8fa8a,f0f796fe,7b4d2fc5,9aafe2fc) +,S(438a6d60,c289dab2,e8933153,5c2e09b7,a677cfcc,a605ea72,8815bdd2,615c852c,109ed19a,51e01f3b,a9dbea30,f652676b,b3a8afd3,5ab5178c,ae557793,13025f) +,S(4db8d4d,882fe513,e5738be2,347a05e9,2c97816c,b39339b,adeef99,7b682e50,88280370,d13551a8,a9803a28,c56bac47,70feb07f,56a1a0eb,d132262a,f1ea574f) +,S(ae2ad953,bf13c4c5,c3fd5ba3,389323fc,260de722,e36bdbae,6db77b2,1c0df210,a5866bb1,7580958,df07c171,80606be1,25b3ee73,9c3bae92,8fa35e9d,8efc7364) +,S(85b3809a,3f772b20,dc526b9c,19de8cd4,9c2d9814,df4a9b60,1aadd016,64c66c9d,984a8061,2ce95364,b9819440,551ab1b6,4028f61d,3028b725,74dfbeb6,8c174cd8) +,S(7e2ddaec,e443396a,7c7eede7,ad96c2b,63faaef1,66109949,e7431b06,309259e4,3aeb7f92,14fd37f2,aeec1921,e64e7a8f,e6a4c704,dfbbaf62,779d0eb3,3b1e81cd) +,S(4565a74,6cd1d26e,962bebb4,447985ed,7b1622f3,faade84,1291d694,17c3ea84,7215d7b9,6362fcd2,320c0c29,e0b304d0,ab174103,bfd372ef,e6e4534c,64ff3708) +,S(aa8c5a11,712aa04d,a870bad1,606c9549,bbf676d3,1ea5b260,27bd1055,ed56f996,11ec28a5,a7435436,3d302f23,24eba092,68028664,f0ebd323,cb7bc587,7d92aac5) +,S(d9d5c0d4,b5a3305c,9f057dc9,8ecf7482,f6d825e4,69a641f2,caff9180,b7096e0d,d2b0eae9,cdf57651,bd296ad2,f4403e77,d643db66,fadd7a84,27a150f3,6d547ec) +,S(2ab2e7ea,1e1bf61a,8bedaa4f,e8fe3a7a,db66c25,ed1b7ebc,536efc7f,8de22777,28806bd1,fc7dca1b,a0cdc177,908e0588,605f8c1e,e76cbc07,ea05b6ad,80c0e5) +,S(2da97d42,a9d064d7,38bc7fc2,f2db39a9,588d57f9,8094903d,cdaf5054,238c1568,fff93946,e789b902,8694ff95,a68a7fb2,981ca0d5,d2b6de3a,b3112381,b8360f1a) +,S(470fd28f,31418f2d,70367e4e,961da5cd,af8d0255,5bf6bcf5,e7db8967,6dbb174c,59a49444,2a250264,3faf843a,cd242640,e3622df9,da6bb1cc,6c956b7e,5a26078b) +,S(e41bbdd4,6b78fad7,ee62c33,9664fbc7,e884f88e,dc184e12,715e8368,160a7ef5,40252593,7979b92c,f72bfa7d,b3f378f0,cb4de758,a6348c7b,2b1d73d,57ac9faf) +,S(9761799a,7e155a4d,e6aefab,963b23fb,1f17d8a9,cc5f8c64,6d4dd638,2359c553,493bb00,3ab38aab,cb4d4491,b6b9e8ec,ef068c9b,933fbb32,6e0e1c75,ca44bf1c) +,S(d59fe2e0,5fcdcc2f,dcc22cb,b9220051,2c936bc8,2205f5df,75267a5d,b45b1245,68af556f,949df3fb,d8299f05,f5e85874,57d109bb,4d395634,89d3ac77,3d4b7b2e) +,S(f8bf168b,8a03f3c4,8e7568ab,ef613bf9,3f515f71,93a24b62,827455a6,c6bdf142,434f350e,8eeba6f6,d8f07137,a33199b8,88907744,eb547384,dcd96aad,5f9f3911) +,S(65298ff,636b442c,8c45e748,c3cd2d1b,94770ff3,3bde1d63,21135bc0,89ed81d9,d0aca445,cf460f5f,47090202,2c84fe1d,ac0a81e0,b7458e4c,9b21dc34,8c223ceb) +,S(d1ac0d0e,25dd02d6,fea02b6c,c98f4b17,38046416,93258208,f04a81d3,450aeaa5,be491f07,1833efce,56197dd4,d3471eba,2a23491d,f09a87f9,8a4ff14,257d1dda) +,S(be876d37,fc1605e9,ea0923c4,e53497a3,8d51190b,dfc3dbbb,3191a483,949cae1a,8499ad31,ca5acd99,4a98caa9,2a91a321,5fd1f1f6,cd70c463,afb91673,ab6b3a72) +,S(7c440cd,aff0d8da,6fb5e2c8,fe27a301,c2906a63,7d9b1bf2,db848f13,175de738,7dd6cf71,cb013a8e,9494cca6,b418fb,e99e9c80,3ff34d35,e586fe25,8ffc4fef) +,S(25086ee5,f0037c83,e38abbaa,e0e3356f,c49020d6,f9006edb,235937a0,4d7074fb,35c21eff,8cb888db,d3271a5c,4dc1db52,2072e58d,974af68b,4d6cecd5,d13e582c) +,S(b1a7584b,6f43a593,363d6e62,edade636,55ffc711,48e6c9b4,2915d0d5,ebf4dbe9,f418f23a,9dde8808,59816098,ea06d2e4,dbad3385,737b7bff,a1b339e,1b556718) +,S(87e1c0c6,aece59e9,1118829d,ba8e0271,db30409f,c08dd790,4296b91,43fb7aae,4694c5cc,176cf309,e4bd4935,b88e2fb0,e7e1b63c,28c5bab5,d3356733,184ef152) +,S(19f43d3f,4bf0f2b1,9a157f3,3f71c5a1,20e2135,3187b508,e568dc5d,8131a2ea,3ff130d9,835e0eab,2744cdb2,5607fa63,edcf9648,d910e25f,b885ba9f,b340860) +,S(a7f9239c,5e8e371d,7d175c8b,120816be,2e543d89,a22c3f7c,5478ae1a,14f8f6b8,75711a87,561fc767,93510d5,47abe6f1,678d0cd7,335e7bbf,b87abbc2,cc3089e4) +,S(9f3598e8,f80cee53,969a79a6,d3b655c0,66283a8e,f2c5d7b7,8ce89e67,5d06446d,d9cbf50d,c2aedfd4,51fcd93a,46245bc0,772e9f9d,fe5a25f6,3af027b2,ea1edf79) +,S(cc00a72a,66dfc8a9,e7a4edd6,699764ca,c15140e7,216daa59,cadf0edf,d1e3267f,91b10836,c8ebd031,2f72cf2c,cf26c89e,1489c100,c72a04cc,71c0d08,45c27d94) +,S(2dc7758d,b176a48f,f3117aa9,671f7b6b,f0b2128a,4bc60fc3,f907eb1f,d20ff347,afc82704,39787ab6,bec0d4f0,7b7f2896,43073cfb,65e9d3ce,db8ff7b,791f2f59) +,S(2502f7f5,8dba7c37,bc4637ab,8c77c047,700dea3f,5b760ec7,9b68121,9cee008e,f6fea3d6,4e776f5c,cd293dd9,4109d6f0,1e55c039,c30438eb,6e626489,c92f078b) +,S(70d39d43,d7f2092,53967479,de620ed2,bcf963de,6ceae3b1,a80fd275,1801382,fef8bea6,45807be0,e1c5c3e2,4d391d8,bf0a6b33,564749d1,4fcf4ef,a8aa7133) +,S(a09962fe,9a934004,bc31f92f,526ff444,da7889e1,79453a55,b0fee769,34c69c2,dd717079,8cf19b8,1f55fdcf,86cd3755,f708256e,694fdaf5,f929c967,eff687b5) +,S(355a2555,4590dcf2,84ca548f,9ec9f40b,22482773,cf122a40,25ed416b,9d29c692,549ed0bf,db861bb7,4684ebef,7d70ac56,3703997e,c59b1f86,bb4b5dfa,574a2f64) +,S(4c145d2c,a165a5a8,b66f7fdf,c16bcd5c,c22304f2,f0ec3145,9b9fb0fc,797c9b9a,7cc14054,948caa4f,be04b54f,1b60a51d,cc482fc8,c94825f7,8de4f4a9,a63f8d5e) +,S(b5ac199b,fa591300,6d635fc6,86d87cb2,52c5c67a,6b897a09,bee578f4,9c57f8f3,41e164ae,d3d967da,94f0cd06,91cb3ec0,79c5712c,279b3a8a,d75affda,2879b234) +,S(ad619913,f00f620,38321c3,59931a9e,fd26941a,aa02a812,8d9f3bf4,8818185,d7b5a033,9e4b8ab2,bf66a597,45c0b496,b5825886,9084d306,660670f3,a9de912) +,S(f8314cdf,d7659ce,e8377abe,f4c80b00,9c99c1b2,f2bee37d,a726c6d2,a1deea90,db5a45c9,a7ea22cb,dba3a784,131ee81c,2a1d9edf,d9ccb9f9,6fc93d35,a332eab7) +,S(1fe1bfca,5df9c482,68e88661,89e238e3,7915957b,aa1e0c3e,af317d12,c2f84650,dbe03060,745396b6,fb22d6cf,a6b27329,3b3ed08b,a24ddb38,8942199a,765d7414) +,S(c414da43,814bcc43,31269d58,1c0a8c14,9e304f5c,13614a89,7f414725,9ed39070,ca194f90,dac3f722,6090b94a,3b94db7c,5c68931c,7461619d,8b912692,4fd90a4c) +,S(81a098c3,d1ebf427,69f621b8,3eced558,9dc0faaf,24206f97,480e40d1,25faba3,fffac91a,3b729698,b0b26f8a,e6391b1c,8f8327f4,7978b011,d7d1cebb,6b0ad8bc) +,S(f99441dd,e4332003,b6421463,b4bf6595,172121d3,f000763b,a40cccdf,be2cf439,231fa7c3,fffcee74,bd111f18,3689062e,1b6b366b,2fe14440,2061de8e,4688b3b9) +,S(2f930e6d,e3586768,792e565c,211e1abf,99e05fe8,79c01083,3e6e5121,7abdcc60,2d51a776,209a3da9,ca4dda22,7beea48,a93a90db,b51f0721,2864f36,a56424e7) +,S(9f8e96d5,99fd07bb,e9e0010f,90802d25,4b30e359,bf0fdcaa,d6e782da,62c6d25e,baeaf150,de04c7ae,d8d34278,aba6eeb4,9b3f213b,fd56585d,41890632,d6b64e02) +,S(57f186f6,fa5f4aee,e3e8b44a,d775301b,66d7fedc,4ab8c827,cb138386,64727f10,5a65c0c4,a69b16e0,1c32a95e,77c8f99d,53bc15af,5c168457,19bc8220,d7baf849) +,S(d344361d,dd0b764c,be16f46f,5efe166c,10a88bfe,bf532a8f,a1fe138a,78e0e1ac,dc1afcbb,a84b8524,a5d985ac,5506f15f,d0b92f85,875c2c4a,4144a93e,e455792) +,S(444163a7,58095900,e5c8fda4,88ecae95,24fe54ae,2592ae53,7e6db41e,8019344f,bae54b91,e69ddcb2,c1bf22e0,bdd721b7,a9ca51b,dad93b28,59e09509,77c26488) +,S(5ce2e1d6,46f10fe7,e4196414,37fa2c16,48029fd5,5340d2e5,f32d467,e0c4e222,6e95f538,cadb1b56,8313429f,35fb925d,d9ba571d,bc6f3970,ff4fd276,4228e82b) +,S(8b7226b0,8525a07a,84ee858b,58c418d3,1d4acdaf,9b081761,56b83a8b,fde6d773,684e6dc,37a2ba2d,89c0b01a,b4e1fcc2,1734eed8,2f7b1509,6724acab,5e276006) +,S(6aa5e306,36046384,ac8e3da3,f2f00713,8acaa0b,b0d12ee2,1e69018a,4d0554a3,2144dece,31a7453d,3a07e290,cef1b694,f393e5d3,f6cb07b7,a8c991b5,2a788029) +,S(8537990b,dd59836d,da16ccee,3871a232,3bd841f,6128f845,b0369857,66c7e0e2,beda6acb,946a6e08,43ec2890,c2d11ee2,404cadec,afb3f1c0,37cfb9fb,7b733fb) +,S(85a8cf21,1de57c,9c0ba88d,2f9a773,61041619,639c9de3,e2f2bc71,cb9e66d6,80d1d1cc,3c757338,f5a6aecd,815cd5aa,1d772aeb,5c1efa05,d5b64886,97ff6de7) +,S(d4f18d05,cb183c54,7594ea93,9330c174,37870e7d,48a613ab,4a920e38,18068267,32fc3b50,394bfc8f,a2a3f912,b35ebb69,d388c87b,198c3619,b04b6b3c,36b6190a) +,S(123e8bc5,65ceba86,d4c1726d,5e7e2a32,ac6f628e,940aa97f,c96ff72c,ec79e637,e54b4332,975774e0,748fb58f,3ddc5a14,8c3eb1cd,824bab83,edc76c28,e991d2c5) +,S(ac26cf03,c5a95e3,9a975746,a26bde6,8eddd6b1,6c83a3c5,81fa0a79,e93d0cdb,73ebeeed,b96d879b,882ae503,2f400142,5c8ed97f,98daa225,346a5b7e,9abc4832) +,S(54f2cc5a,a4d81daf,6600e921,441f5aa1,5bb51a42,7479e123,b9561d0c,8c71299e,3ff4e7f0,83f85039,d238a740,b7fd16a1,e313cbb5,b0c6fe5d,ad99f221,da4aa27e) +,S(8bd785,b73cca1c,6c405ca9,1ed4833b,428b7ddc,1a61c8d9,b0d1dea8,ef133586,fc5b65e2,5c3fde0f,3239ab96,625a9751,27a30cbe,f98e1ee,735c1f71,c86cf292) +,S(bd4218be,af5f92dd,f96a54fa,fe873cf2,171c2e30,a13c866e,e830bb2f,abb17d5c,86097c6f,91024f4f,8900853b,d17dbede,e2674e36,9f3fc69f,a2578eab,174e783f) +,S(a4006630,1b63e757,fce2f5d2,a7444e5a,1f2d7509,b7f59476,6951f38c,1755b497,87aef8b3,eb160df9,4b46a56a,337b6400,c724658c,a49c1162,c418e900,29efde08) +,S(5c5af5f5,65b2870d,6fd08f95,b4146379,15cda056,e18ef682,4cbbbcf8,adca740a,c7c6de6c,e679f0dc,84e28027,86ea726b,8eb0ad04,af4b9a5e,de516f11,583607cc) +,S(b5c3629,b86e9235,478aa7e2,d2e5b539,b70765b7,79ace9ec,ae76a659,80f0ebd3,86a8a06,84fef80,7a081bf0,3f08c078,7ad04420,76f5e1d4,521cffec,8b2dc96d) +,S(1784e06a,cd25fa66,72d1fc08,9219cdb4,54f5c711,4237bfe4,a2143eb3,20a0bedc,11feb0a7,d8d43ebd,5bfde5fd,21fcaa5e,7f091da6,3acf4b91,956172b3,5d3af378) +,S(39266c28,48f58af4,47e5ce4f,61cb3ba6,9c3bfdad,7e5742fb,ba4ca3f4,f175a291,7be4b872,9d1e2fa8,fee16e5,bfcdf4ef,2cff2872,e9c7fea2,c1997d6c,5d7f1efe) +,S(d6fbeb8c,72214cee,58b33bbf,2eb04924,f96e9b63,d104aa92,fbb09c8f,c2e4b1a7,cd9bbb10,a800d777,9d4cda4,561a2b8,759b4dde,45dfa2c,319e4e59,39938c8) +,S(42ee0a83,85464cbf,cd4a9ac2,73001bb8,592f2a74,b28ab7c,2eb7055e,2a471b76,d22c6ec9,d5499b4f,26947233,a5589aeb,14c94376,9a6166c2,af9d323b,e1adea4f) +,S(8cd2a043,4de9b238,f4dbc3b7,e56ffbea,4f025e2d,6c73a68a,4aa62bb4,9e9057f2,abfe69a9,986ae1db,52a807c7,c08a1116,a2dc7aa2,ec3b649d,7326bafa,ca74d21e) +,S(14c35089,62dcb50,d01750a9,441eda38,1a95abe3,72c501bf,a99f953a,5c94da3b,bc57dbf6,bba79503,f33be20f,96a54fda,fcd7be9,cb064410,3db11e3e,2034a3ae) +,S(2cddb646,76717e44,86fbe0a7,f7d6d853,7c3fff9,465e31e6,8da22abd,b3eedee6,136346f0,cf5fd102,932036c,3605179d,1429a706,71d95524,a14869a3,d1cae8f4) +,S(d806ee3,b5702d23,50c3f179,a00c3701,9c055103,318594c5,8f10b100,1b705aeb,79201749,21e69cac,a0ad5902,42e39a04,c3af8cc4,c665587c,cc0c89b8,3744b9b2) +,S(534f24,715e9b8f,f5f76a4f,a617839f,6fe2f175,3cbc3d80,331d12e,98f6ec30,e26ebaf6,4affe9d7,1ba2cd55,421c33ef,2e4a3fb1,c59a72b5,93ececec,65a40e1c) +,S(f33af0ef,4e23c8ae,7f3de5c5,22e8bd9a,6e527c8a,23242c8,4ae6677e,ec90b8f5,8510bee6,bacb5633,45f38075,8d85dd0f,493d179c,b9250d25,fe88134a,6055aefe) +,S(3cad4725,12a745f6,7e36fb92,1a2926d6,ae294278,8004386b,272d8520,f5a9aa61,d12ccf97,27da84fd,317116e4,9d45d741,776c8278,4b2c9f1a,e3773e1f,57b8934a) +,S(4b7fcc39,5f50944d,5cf3b3f6,2b1bbc3e,3aca20e6,d259e931,d3398d08,cb6fcdf1,99acfb05,a106a389,b7ad644c,cd275396,d76b046e,9992e573,dcead5c6,c7da96ff) +,S(9b5c0e8b,22a62110,bca2770b,778f0a2d,6d67e908,c57f806d,7470f5c6,abbb27f6,da52c77f,ea3056fa,dae674e6,daff8b21,100d007d,8bdefb12,fd56efe8,13c15a02) +,S(ee7b7f5c,e79eac13,d9b500ed,ee0b65d8,e7c93203,aaad71a6,9a935e31,20722361,e77ccd78,bf6380e0,5e5e8de2,20448a00,cabe7d6c,6b7ac318,56c09e2a,9a390778) +,S(b4774237,d36a59f0,e39a133,756bebf7,4df43365,2a4505c8,b0b84833,dd5b3a1d,5a5a03a9,e3463ce2,fa8bbfc9,afde9c25,763f4874,3cf0b2ca,7dc42c3f,9bf3accb) +,S(5827142,c69944cb,a066a985,79acdc02,83e1df82,8935ba82,5aa55047,5a52271e,c05c5805,6bcb6cce,ed5e8c8a,beac78b9,69c3b482,7ef5b402,c94fe1fa,f7fc81a7) +,S(ba06eb6c,a54fe697,9be9e9c0,f8c77be5,ada7bd7f,43894d1d,1705cc18,9c9b0ed,176be0,b5d3db28,7f235e2f,a9531fba,65f5ff8d,55b784dc,bf7271bf,864e3d5) +,S(ed84c2b6,11c1208f,2f059d37,a3d2ddc9,c3a0196c,9b9dee3a,5f2cbb0d,9383625b,6dff970e,b08bb4c5,4dd6ad6e,df25bbb4,621a5ea9,3869de76,2524dd2c,af1c6f6b) +,S(158b136,86fbdcb6,ad8ea001,9005405,b5cfc0d8,f614592b,d9e76b1d,8cdd568a,8c576136,634af4e7,9034b450,1bae33e0,9b5712f8,642cbeb,2b7c8910,cb28fab2) +,S(687d52da,10df8013,7232821a,990adf74,c54711de,110027f0,68464c9d,162c2410,dad3819f,8071b3cd,dd84fde,550d24e6,31785e1c,e137e115,8b5cc687,8cd09f10) +,S(32e8617d,de77c33c,a1d317db,d350298,50dc7fb7,148913cf,413e04b,384dc81c,9cb2fdd5,15231e83,21a3feef,804d62e9,2b8b9c0f,dfb73dd9,c3323017,b29f2ff7) +,S(a53a659f,7cc90421,21d96a90,3801753c,ea43b363,405af6,16d50b4e,fff054df,96734742,ecb3c201,742f8f64,df22569c,92212928,ca0d5453,d706f905,33c345cf) +,S(8a9e4990,b9b1a2b1,32ca9507,16170713,bcbf5719,2dca9d71,7fc9c4fd,a3993fe5,9542de81,f66098dc,c0bb0f89,44ea56bb,bb7e86f,9c63222c,80620c7d,2fac20d) +,S(5966c5b0,f92c5906,b9bda0a,7b3f10f8,e4c29796,f953db1d,35976175,dcb431d4,539665b9,90bc3810,4b7938f3,47ac94dd,7b9228cf,7270284,a825a202,ac62d135) +,S(2170d9c7,4ca5e85,305d159e,697fd1d,d32d6f6c,a2806992,f082ce00,9139c34f,b5cbf529,66f71e55,8015c90b,ea2b95fb,4a0fed8d,ef1f9af4,518789e7,39076c64) +,S(86e9b03c,2497519d,615f83f9,d0f9bf9b,101b75cc,50059e19,4d7b58a2,9b6fdf76,215d042d,7976ea35,a3dd586c,f5b286ba,a30e013,966fbb45,99845111,db8b56ed) +,S(2cc7d91,ba630172,ae56cf60,9a5d3c05,e27c2e68,7d607c85,ffcbf6c9,a467028a,9404f869,32385290,dff3f8fa,1a085661,5855aa6d,e9742d8f,9e2777f9,472ab5c5) +,S(84a89b0b,304ed760,c3a3d972,5a65764a,11d59ebc,25249f69,1d3b8711,10d3cc73,b7200408,fb1ab866,53b61321,10b6bc53,c8a0805e,568f8a0a,80a65678,c54c5829) +,S(4e9c88e,d10be9ea,a34bae15,8ba3093b,42ad9cb7,356f34dd,33eada3b,1937b4a7,b92050dc,95423a8c,759222ea,c09593c1,342c2dde,5fe382d5,6838df0a,877dbd9b) +,S(fe2883e6,6db454d5,31f2aaec,96f4f3f2,868ef393,d09c7685,a65d476,c6c97a99,1ac28015,1bc7c0a1,cc4be80,c6eff3a2,b8ae70b1,180c6a15,7c89dd3e,3e78568d) +,S(c74df902,ba66c205,e49f25c5,62d1eb18,f4f4f697,3cf49135,16000924,80f3f68f,17f7bbc9,59dd7e6d,9043ad38,7c0097b,403c8d1f,e676b8db,d7f2c63,1fa1ecd9) +,S(e7e7a72a,41f95b51,2ea42d1c,76da24bf,67059e,c27d5313,55c30e60,69a72c16,a20c2f51,6e9ba9b1,fd3a8473,8309ace7,da6006bf,bc42d4ed,657da6eb,6efedb8c) +,S(5a93859e,dc4ee632,9d36536e,1bf1008b,603d6a8,859ac6c3,a098748b,d6e18bce,489326a0,1e05c331,d97db6cb,68f098c4,6712d7d2,994e6c8d,be892138,e2106220) +,S(6161b293,71353343,a46d0917,4f6467ea,25a0f77f,fe614133,7fd3bf77,71062de8,57c439d9,a1682d4f,773c8260,6ee65e88,473544ae,64194ab2,3fafc2dd,7612b385) +,S(c35b16b5,a3808dd9,553c7644,400d6fe8,ca48c8ae,49c78018,4a71eff6,b94ce4ee,6c3baede,4925766f,3a7c59e6,d6c1c966,c3348b1f,5883498e,9956f3e6,6d8fe13f) +,S(fbdae49,32baf904,1d295378,2d227dce,4e2af60a,86796a69,86b777ce,bd2cd134,9ed9b5fb,df42e755,a9cd761a,cbb92877,6c66d299,35dc526c,f6950ba3,d63d0c95) +,S(6c5bdede,17ce2007,a3a1c18f,af8a846a,ce67b751,3d8bd602,23610ae4,b01b720b,6492873c,26a22bc6,39d4614a,202cbb2f,2a08b78a,753592f4,10c855d8,12f8d39b) +,S(eba4e62a,bf52b379,9305bfc0,eecc63c0,5221a0b8,b554432c,15e460d4,21dddeb1,e378e6c8,d6ddc7a6,72d83c3c,9d863c53,32b1cdc8,21ed458c,b817c49b,6dbdc519) +,S(5a79ee4a,1aab7803,23ced132,f9c67d5a,c740900e,cf71a0b0,ddb1d6c9,794cd90e,9f608713,47b3a231,548909fc,812624ef,26eb26fa,98630512,2b1466f2,665176cd) +,S(78b702ed,6d816c15,eb31dc27,619d5bf0,6ad646b2,e39750f0,73c31d03,e50d9385,9f1cc224,91befaa4,fbe9721f,86bebcb0,11024a08,4380e46d,bf11ce99,f157fd24) +,S(494e82e4,1c24936e,c291f69e,791979ae,3e2a6696,c8f68601,b57942a8,fe6b98eb,59f3af2f,c720847c,19fceea6,e3d2a918,ff7f564b,2e3bd7a4,beda6415,65bf5da2) +,S(28b3ff40,467a8c68,69fdc61c,33f002f9,73705468,4fc707ab,c0b495e9,a5c0b401,46a44995,b2c8f0ca,a32d8e33,b8e38465,4cfbaf1d,addc4d1b,852b2a04,58f84e34) +,S(4e4cf4f4,38a40e8a,aea162d9,dac13531,f5730d96,59c436fe,d8acd06a,c4c46be,4fb4bf3f,bc394c7b,57f81a59,2ea14c30,1e9ca990,5f48ee7a,5db08ea5,eb6dfd7f) +,S(e2ace7b1,3a9e3e22,a9b8ee66,c56e80f1,9370cda9,eb3ffb6,2d20805c,7f4c34be,1c8fcde1,2a653492,6428319a,981e1602,44aa823e,a82831b4,d0eafd9a,2159318e) +,S(e090ff27,e42469c9,91dab9a8,dc9a3a41,d46b7482,a59ba9b,cf4de93b,c95c7e78,d070752,c5679b45,4e1b617e,8315a48,1cd9d24e,eb53a671,3b4160ac,64e6f824) +,S(705c8790,7b976b8d,c8ccd3aa,897b2ed9,ea091c37,e285c37b,aa321c89,15ce089e,edccb405,5ae9f933,973950f7,eb79657f,e94fe286,27f6cb2e,784d667c,21ad4d3c) +,S(4aefb3df,663a28f0,d531e390,339a56a0,4da1c64d,4692c086,de232740,6d386d57,167af97b,43a36a18,1dfde22e,633547e0,eaac2f16,84e8753e,1ba1741c,2a18fe3f) +,S(ea909685,ee8c283d,1d7dfc4d,6ec8910b,b8d821d3,3997f24c,db5f5ee3,bb7bd72b,685b64,d3e02ee2,be2045ba,c3bb428,636258db,33177da3,17f6de0c,f8c805f8) +,S(5987cd59,ecccc129,b3498331,f20cbfef,f377cacb,dea76ce,2e221aac,d3aace8c,3427cdb4,f7367d60,44ba21b8,adfd5863,bae2981b,340c9bff,d0d7e93b,ee4d6140) +,S(e23845ea,e6ed3d33,14fd6f6e,f6d6e9f5,92f921c9,f448eb93,edb49869,97837eb2,89eb22d6,455cc139,e42c6263,b65233c5,4b1a3b45,34ec3d7e,58b788f2,6b11b131) +,S(cac7dbd9,7dcd353f,fbf60696,d325bf14,2e3920ce,26570b59,ff9aa65a,a6993199,6e81a4e,cd60a26c,90f890fd,6de2d159,50bb70e8,92eed375,25a48f3,31307620) +,S(9dab063,3a5952fe,f168d6c0,3ebb226d,de3e591b,4ad0c9dc,96b247ae,49a317de,846d87d2,7662b958,b3422b3c,a3410ffd,1ae549d0,c6757bf4,f96d2d77,168cc83c) +,S(bce277d9,ed439b09,f255cee8,af5363a1,12ec2d5e,b111196d,be30fb21,43f501e4,63f472d5,2649843c,42e8f900,5adfa50,d6a938ef,8f4f04d8,897a68d8,8c213328) +,S(df9f8700,2a6baec7,8b79cded,bb501dfd,54f376f4,5756501e,f03a6c7e,ac5f1d7a,2a1c5c92,789fa6e2,84105f4c,74b0a108,27ea2f05,5560bec0,5d0000be,b9b6c4d5) +,S(6211dcc9,307c40ac,3c7be1c7,5553511c,15d3224e,3b305c5a,39653d83,f134dbb8,545c00d9,f02b8833,5fe4851a,88cbde99,f7f02d05,ac674f5a,6559ac9b,d03febb1) +,S(d739aa30,8d9022fc,45735eed,3ff92f38,545f6c9b,b70994fc,b5f41f78,772c9378,d3c3fbb,9077dd53,d023838a,5c35b728,af4a90c0,1f16739d,12870e1b,15e1e6ac) +,S(9d85e55e,8ed84471,b6822c68,3268c35b,fa314b72,470e51c1,a7ac9f25,f8bceb6,8b01f444,e84436ee,ae159a32,7026d279,5c4116b3,b2e78f90,99f1035,1511ac88) +,S(25d39bff,22c40a94,b194c38f,be9d001d,4a632407,237fb091,163e463d,7c5c70f,33381905,11368982,445ad7f6,608be022,209466c7,98b9abe4,f4fca781,2c0c398e) +,S(67553ed3,f14c28d5,2abc36c9,3f15d0c4,7f6fe1dd,628b652f,36b29225,ef8ff51c,da5d42d5,9d41893d,10ed28d,569c0cbe,1cc077e3,36bb5c21,e3712bbb,9c480383) +,S(ea3e80f8,c800b52c,a6dcbd2d,399ec5db,65057477,8852a73d,68af22d6,f1abbefb,5cd8f55d,b5330919,377b48d0,8ac1bce0,dfb8c3ea,2b97a5bf,547b7beb,ea64a4d7) +,S(7cf11aaf,638b1fe7,3b8c5753,48bcc01a,41c61ee8,f2eb3279,c2ad21b7,f6f60780,579d9a90,3a8a77a5,6bef3ce0,53ffb3c3,cf969f9a,39ea5bad,b1fa075b,e918f048) +,S(ed377aa8,42897f6d,1092caa7,42c29285,2349bd7c,a0e0cbce,d3cda58e,ffaf5e17,44d1e8bb,6491dfea,cde53662,5e5d7b52,1ca11a47,1eeda260,647f6f0,f0c5f917) +,S(fcafcd82,dfc87415,6e0db5ab,2fa2b56f,dd488032,d22ddc1a,b7a0ec8,1f1c4083,42f88e6a,cf851a7e,ca3fc28d,f771cce2,bef0d7ce,3d26da45,a2d9c307,e9e7e040) +,S(4d372865,7fde43e1,68744112,26b34713,9c1ca4ac,c2905858,de50def8,5515339c,5dc438eb,7091eecd,a4868c48,a7933b71,7ba99d8d,5e8a946d,ca9605a4,7421df39) +,S(aea6fc55,47faaa10,a898f21a,f63249ac,a0625f78,ea819629,8bca035d,7639e470,4d20c80f,173980d2,8e6bf433,bd1dacc3,1882e283,35fa9993,ef808464,a5568d42) +,S(f0ce04bd,bfa81a58,e157a49a,11695baf,7233470e,baa7ae76,3a07f0b7,f71cfce,f9e4d701,baa6f197,d9912b57,d9df016a,b789e60e,d731afeb,f2e5f920,b4eef9f6) +,S(cc476e63,130a950b,b8284c8f,fe74a059,8d9d44d4,c0372a9d,bbabca17,517523f6,d2cd50d2,e2cae10c,df744ff6,61a6c96b,64e17368,5f81027a,c937a292,3ad7476e) +,S(90e0477e,8dacfda2,7a563448,65947a05,d0afe9ea,60634473,143508fc,6abfc73a,d117be49,166bb010,afb0b82,a46a4204,c18ffa42,e3c89764,3eaae0f3,303dcd9b) +,S(522a6781,951f6ec7,76b6cf9f,cd20287d,6977764c,517d4ebc,7209d55,5714b5d4,a109c149,6318d481,4cb22199,3567e5f4,5147b64f,c1f9216b,922d653,7637031) +,S(b0a4c701,725326e5,611ea140,325b0536,b22406bc,c1e7eef2,1f874ff4,e02ec2a5,df44faa2,8a60eb90,3974649d,54cf340e,293fbd09,66b7b7d8,884e4c8d,dc1ec875) +,S(9e874924,90f8d4ca,2ada28a3,2bccfdaa,51ead138,3421d7d3,482af7f6,6df47c51,a58a577d,d03a719d,1bbb64,6ec3051b,44535da0,5e7e04d9,fca42716,2e335fd7) +,S(650a307,7b8007ed,f0441dfb,b7103d3c,d5146ecb,b949f9d9,c8c99e2f,25df7324,aa05b394,8c909957,ed1bd7e2,720286d7,56c7e413,8aa202be,b08bc446,2fdf86e8) +,S(f891ea99,2a3ef255,6feafa4d,7dd3f7eb,1f1401c2,b75d65d2,6ab81372,bab6f932,f7002bf5,821837f5,8df109f7,2ba5eea5,6c767a4e,198a7594,21467d64,df5e0bd3) +,S(d35e82bd,44fe54b,5d2c0543,91260c04,a5ce8d47,32e83ccc,2f3035e5,56bf2626,b002495,99705173,e0a45f97,196b9e41,1a7f5d1e,33f1b39,100b511c,e51f6953) +,S(7dd56d5,1f139070,a382af7a,2db135bf,854c8e98,2a325b41,ed869de4,349323bc,a23a473a,7f263bf4,944ab5bc,2d82e20e,8e9256fd,b11dbc17,bc0e6bfa,a8325f5e) +,S(afed2eb3,c5a95b4a,e88ee73d,b57594c4,7013cf13,a48431b0,f7930d5c,27f5c3f2,26b49096,da666097,3403eabe,342ab065,78c8ec6f,bc3ac7d7,2b3c95dd,54735dbd) +,S(13826776,74f36fe9,ca81cea,ac65c2b5,51e9fad3,af246f,4cdc65cb,cec534c5,a78e8139,760a94e8,3b3f5ff2,a65fbc7b,6b2b55fc,978b8399,df2d7947,18b496f1) +,S(99200c12,6fed5ec,1fc849f7,e9769a7b,aae3178,bd6b59ef,2563ed6c,5342b80f,7a7f1713,38a84536,e73f358f,91eb80b1,6ce8ef27,ea55795d,16aa7f05,577fc13f) +,S(159febb0,27e04f1c,321b852a,3cca550,28aac30a,8bc27caa,73a069e4,df7029cb,6bc7e080,8834b880,c590d249,241b709,e7280a05,7cbc1897,9b8cc9b3,cc21a821) +,S(2add9be1,a3acdd9f,efebdc0d,a4272ca9,311567e4,61db8eb7,3519c1c,6473bbc4,357ae640,a88c55e0,d3559faf,b0775d78,2373537c,c25e595f,f21ed1ff,b36b5925) +,S(8e2d4265,1742837b,b077fcd1,488e73e,5dccd6ba,6401c6c1,8d36fe9c,c428b664,ee9a5b1e,a04ab8d9,6430ef39,7756f62f,a1dcf35f,fff314a1,c3eb1dc8,d9a1e5e7) +,S(79dd7d76,5b4d7db0,537a69d9,b94210e3,8e7a11f8,cb9cdd8c,6aed6a15,748a3ac9,868c4b6,26dc49fd,de693201,3b89cf13,e1dfa1eb,56fb4de8,9e5467dd,86e449d9) +,S(552c2ba9,96a13b57,32c3b2fe,d4e9579d,365e03d9,2bcb231d,f14d1d1c,288a963,118e11e8,646a0335,6834379c,bc93c1d1,3ad80145,dee0a51c,49b10e17,f6952f79) +,S(fcfde18,a53b5a68,9d33bbf7,79d0b699,2faee8ec,243e72c0,7ca09185,d997e581,6709b56f,43013d47,23f15969,ee01b0b9,ff0d9d95,5e2b98eb,7e78e1ad,49cf3d80) +,S(e9e9d7a7,4ad279c5,691367dc,9c4b7bda,b27451b6,a8e4ed47,afae1883,96d8d82c,292bca82,e6d1c88e,8869f33a,7a6df2ec,ad812dca,4c46eab4,5c56c3b9,15f79497) +,S(514054e1,3e7ceee9,3a19dce9,96256b5b,5876a55c,6cab3c48,74b15547,4a58f285,f9ea80de,80403f34,2866dc40,cb0a9aa,4b38b98c,c4c38e3b,37f4da03,fdf7f5e7) +,S(ac0364,eeb9e7b9,b9589051,635de6c9,447b327e,8c820272,f04a4750,6cc5f290,ccde3ebf,13b5a291,a73b0c8b,9a69414,4b217661,7b0a7735,3a6e92eb,4af21b7e) +,S(cf558594,4a73a11a,ef500dc9,60cde799,ffb4983d,ae76826a,a027fd77,811058ba,369ed987,eac1683c,4e8874c6,40049a33,867fa0a,520e5204,df328d89,f197bfaf) +,S(ee216b85,62eaf12c,9189055e,32cc55c8,2ba5e3e0,237de083,a6e77878,63c56291,2a8bad1d,a697832c,856f6adb,e1cc5058,77e543c3,429b090a,1d3cf0,d2df6248) +,S(89903a70,55dfcb5d,175acd28,f7161862,c9fe22dc,ab752d88,3f52801f,92ab1892,e89c4f9b,7954c2b8,cd3b4868,ae171331,871a2693,9355d88b,8d37d4f6,b90c143f) +,S(f9830f50,66b1b44a,89231a81,1192a284,9ac94ec4,13f5223d,51d1e75c,a7727884,18ac8170,58795d51,cb9a5c2c,c249bcfb,ff3fe3b9,1506b721,763c8fcd,7e2ae44c) +,S(326be8c8,55c9f742,19228eae,f7d79c48,b02c2e04,3bc28e9f,275d6754,31afa8e0,293647f8,76b00450,b223e715,5faefac5,990322bd,eef964c7,185acec7,7c105d06) +,S(6117b67e,bbd6b120,906da047,88ad7dde,3549bc5f,c4f80e04,9b216b00,d441dc9,7ebe5576,17dabcd9,f41aa34e,1443e12e,715c9a7,ccfa04f7,ec6a9a25,74c1e540) +,S(1fa858e8,aed841c0,902db240,aa0e4c80,f26927dd,94e0e404,7e8ecc25,216dafce,26566614,2111086b,caff0e12,e4b38940,ecf05a5b,58f3e705,d7011b49,413a52fc) +,S(dd77d202,96a15eda,eef79ced,9b59e77c,1483b936,6e9949ef,ba3298a0,efac4886,b1914a11,80cb154a,f791a934,8c89bb0,70f2ac9b,acc50c5,f75b425a,df6bf125) +,S(e5fdfb45,1e7ac947,ece4e8c0,5b87b9a9,2d49aae3,5ef95f5d,1d18bcad,18053337,841d054a,47b4998d,d3ad8dd3,d2a1ee68,406a195b,1975bd1a,d4194417,fdc4cad5) +,S(decd87d4,6fb74380,56a83258,bee67d9b,1a49e170,bb1b549a,a5c2a2bd,cbc050ef,5ccd1cd3,614fad6f,601a4ad6,e964ee69,a1e06e8a,2e29edbc,7d19562,a4aebc5a) +,S(1a94991b,939bf699,468c465b,5aa4b064,520222,c0ccfcff,193a8484,6f6e4b8e,31b1e6f5,30147e1d,ec0199ae,1830a36c,bcf4fce1,e1258441,3e89eed6,889b9d1) +,S(f32874f,d0f18d03,7f0ae5f2,ddba8f16,fe7ca4f0,d694e803,b9216c59,91bb456a,1dd8f5ed,f228a9d,53cf881e,a4e3c479,6017be43,e613ac30,690435b7,84a4056) +,S(1c5991ef,154b79dc,df2ceafb,3f7fd7b0,7ce7563a,9312ee6f,1dbe5960,f91ba569,497d2a93,28ddb18,221b0075,3432f510,bbf042a5,ebc44cf9,3090d064,4a252a7b) +,S(3c88095e,dce54996,3bf6e312,4dfc14ff,4ed4ecc9,d6240af1,6ecd5984,5f01de9a,499a17ee,e13c81b9,bb7b297,5e7ed1a1,231d9094,348d22fb,9254c520,a65be01c) +,S(c849c359,1c4fdb68,55971840,c0b78bd3,59d1de02,130adf7,e277cb4e,f6eb7748,6add7151,b2640b78,b8fcfdc,fee4310a,4c4c97c8,bb0cdc2e,3bbdf802,750a7920) +,S(f53017aa,a5f79e34,5a0cc318,f40115f2,52ba5401,614b9eb8,ac9245cb,3ca5680d,2d8b8c24,ad89361b,6d77bc72,fb0c7da8,ff129a5f,2bc00e26,e635483e,c4c44b1f) +,S(b3657e9f,84975313,640b7302,a288ef4d,2dbf36ca,651c0189,b39fc10c,87d7c4b0,d821329c,a2f18f94,7a71f5f7,51ac1b2c,e56aa432,992e7a3d,ef84e631,db61fa14) +,S(79942dcf,a834e013,77bb3eec,b7fa31a7,b4eabe7a,578c46d9,3a0dd17c,b3455f61,4c08fe53,c3afcbd1,7fa0a809,bd4ff7af,88713a3e,d7713f82,18c4d4d5,2a757ac4) +,S(e5f14474,619e3acf,905da5c2,3d1bc311,7f1d58ff,8c63ed2e,fe939a22,5fd9d9a8,d4d225b5,85b6b319,431939a6,8e2dafbf,8ed90a6e,5fb559c0,70779d67,7c03028c) +,S(bc5ca503,3ca4398d,5f3c6240,946c5d7,c9102996,e302b9bb,640aaeed,8c9b54d2,ac15cc8,51e59843,fbb2956f,55d39f24,200922bb,6cbf1e86,68ed3ecd,6fae2627) +,S(2f3abe56,d63a2afd,35e35d4f,9e964c61,a5483402,5fea8cfa,66ba9aed,f75947b2,7adeb38c,e14ebe73,8dceae8c,77903b24,3066aed9,bc4886c1,356449a8,27496d5b) +,S(704bf0b5,f564ccef,4d6e5f8b,eb2e90c2,4b46d581,93cc0a41,5bfee2fe,95021b75,44618d17,c54684e,ea1ffe1,53892090,b74201d8,ab3f9312,e7359ed6,5ca94c27) +,S(a898e473,d4b59956,2a905ede,afc78bcc,9f374c6a,f524fc37,86a91375,83d749dd,5452e556,7d72dab5,e085ab72,1168b5e9,c96a0fce,f9d5862b,9c5a0daf,3769395b) +,S(fc4f83da,817b1648,a8a1be3f,dbd0f309,db712225,2988ac8f,64774c29,e8d9d573,57876e31,6a0ea473,3e34f34c,b0df75b1,1194017b,258cc944,7ccded35,19edd00b) +,S(63e97e30,82c36634,d151f0a8,837956d6,16d5d4,64c66373,253bb94,ed5c8236,af68f06a,e045e5be,88242af4,2e314ecc,d719f76e,33092e6d,8b69f791,446c2acf) +,S(4c06073,5107e9fe,f27dfbfd,5df447c,16f1c911,8ec5cfc,8083a588,9dd82b23,8c8508d4,b86e9eac,2058a912,f2581ae7,fe81647e,e27075d4,fd01b051,fe0ab636) +,S(667f609,7b6af1f,cff58520,83175f85,ea01a1d3,c508b12d,a2e19281,c8d8e443,ff9fd0d7,4a0cb42f,3d7ff6d1,67e5a65f,23c34679,caf3f94,ed5d1073,af31607c) +,S(e01e169e,7fbb4365,58e07dce,8f8dead,e2ec2e27,7d18db95,ef8e9f85,ce800fd7,f49f594b,9d60c59d,155ea702,a1b5e3a7,b26aeec6,71b275e7,10d0139a,21041960) +,S(ed10fbe2,565f80a7,65fc90ef,224c7893,cf9df84d,aa0a3b2,9089f7f1,c014ca50,ffc44137,c3ac6fc6,fddc65d1,87d6b456,819ab1b2,df461ecf,899c70fc,59387031) +,S(4563833d,d0052218,5a43bfaf,7e55c2d2,62a12feb,b76254bb,e8310687,e917cc36,fac05d5c,c781d49e,9bab4cbe,384b511d,1c8c1fe4,f68cdc2c,8c576be0,1c669e63) +,S(bf5907b0,1d05136c,b0a1b514,73682fa1,68772a1b,9f5db994,3bdacb3a,1e8c47db,fc69b036,4559f5d3,f9e0c1a3,e4da38ac,b9968e9,17311288,69da2158,2e334cbd) +,S(be106d73,d01ce0fc,5555d4f2,379c906,1ea6ca18,ef8ef8fa,754ecf64,cfc27fd5,9c84f04,947687e,f7d641ba,ff89a11b,da9e9769,8f8ceefe,54e2a4ca,267956e) +,S(5bceda4,2e94ac3e,68f6a3e4,e4509872,4724e9fa,59ee0918,859884e2,2c98f15f,4b19d70b,e1471e3c,7907f797,7311f5e2,ba78c6f5,6f2ccaf1,cb6b684f,7d048934) +,S(e0831b14,fcb2d4f7,3d17b6c7,f6d16803,304cbb32,2bffcd6c,84bdb891,9d7cc9d7,b474a715,5520cd3f,65b64d08,b8e92ca2,4b2238b3,11d91db2,48720a6b,65444038) +,S(df818b88,2300aaf8,41cb3962,2f0c9166,468c1ad1,3aa284f5,89dc354f,bb1fe97f,40f571f9,f63fb358,231c204b,3b9707f0,c5cf11c6,d7ffb93c,991cf7f8,dcfb3895) +,S(d9fdd569,bfc89237,4bc56a1e,e56bab5a,cb5e0ce9,85939b85,c929fde5,82a07bcb,5c56b150,4cf3767e,e22e4b00,fa467b75,4c9ccec4,c1364216,d34ee210,aa5b56ce) +,S(11a93998,d031bc3e,d55e74c9,ab327945,cbace727,647bfcd7,5ed04a2e,4836ba,4aa311b0,6fc8fc86,b67e8eb2,1e75d997,189fa22b,a33e7e99,b07d610b,1c94655) +,S(7c4fc747,7319464e,2d71f787,80aeb385,aebb0420,d8f8588,9652d5de,aaad580d,31d6d7fc,2cae58f7,b3e4804e,f615d7e1,edf9d06c,d1035b30,ee9b55b,21b06eae) +,S(83704a5f,4ef8ca9e,a3d5b163,2bb3df98,acd774d6,4e07b219,b9a36a9,ce88e1b7,52976995,faeb6179,bde4c123,1437dc73,b53b6f90,f0cce08,1e3e1644,e1ebeb18) +,S(5de15f19,21258b5c,f12f240d,147bd38e,fd5e3c3d,dbf148c5,9e541c01,ca7d724c,c0e18562,1500f0,e3fbbdef,45550e16,5fc2a2a,adc72558,e49f1e3b,f5f4fb00) +,S(f5d1fb46,e3288419,1f2cc8e8,2ba81ba7,5bf1d7b5,97ff82ae,8731d27b,7f059938,3d5118fc,9acc8394,9e0bcba5,c7c79fec,2f0cad64,7910976b,e4e8f9ff,43d8baa0) +,S(8ebe619a,985f720b,9381a99c,db63d089,6a787dc9,7d007354,fa83b931,223f8596,7968b6fd,e3dcc13c,512aae25,d9a8127f,313e2d9c,34489606,864732b4,c3b5ca1f) +,S(5b14482d,f96cb0a0,5664bcdf,e4ff7b87,6169db9e,8107b0b5,78baba9e,b1f8fcdf,19a4ed84,cd2ab376,b1e0c2c9,ecded5cf,2e874f09,6d84d946,22be5806,9f8a5e82) +,S(ae810d52,7f94dad0,d140877e,ddc5e0e6,cb636325,f4c926a,1a263f1f,beb9a8b8,c94f0c8a,f5ceca8f,ea29dbe6,c8afa649,f813744d,39e303b,c1f0c135,867658f) +,S(38853d15,d74060fc,7eb2a56a,b8772f6,855aaf83,b731d853,b99fde93,e7c06e7b,ade73ce5,4f513c89,531b5bad,7f47ce7e,a498da85,e378639a,5ae0507e,1f27fa7d) +,S(837a1d99,db477c6c,da832700,37f111f6,eec5402,2bf74773,4c18bbab,35b503b4,ce852762,ed9b36cf,65602da,cfd3a250,c547a971,1977ba86,64f72cb3,89ac1f8c) +,S(3136acd5,a1460d8d,717e452b,a2069b88,4eb6fa81,756f8768,932c210e,df08173f,42ad61fb,edf97b53,f59ed7b6,afaeaadb,831134ef,73e33b1e,26b2816c,99fc330) +,S(a9609269,c3ef7f09,2a43e394,e482483c,119d94df,10bcce43,6691230b,b77d3201,8c580df7,9147069a,5c84abb,73e28b6b,ab9c7c0f,7803d6f1,d9fa86c8,f324be1f) +,S(3cb613e1,1ce19ea4,a8a90eda,cb182c09,5b1601c4,92822974,6ec22fda,be699e08,f05a18f5,aef9dfe6,87e69a9f,287fd868,4c975765,284f578,50294598,51538b05) +,S(b41c56a7,47232950,7777847e,178eaa67,ce61f561,21c7f21,2c525bd3,e7adc359,b0026b4b,6f9dc954,7efedd80,d914a3e9,65b17378,e6e0055e,527f6754,c5c589fb) +,S(f44724a1,3cdcf9fe,5b4a8f3a,f0d3e076,4559c14d,87eb8ea3,803a41da,9ee9dbf5,355b54b0,7ae7c477,9eaa314c,953340f2,f5583ae2,ba730339,acd231e5,c3d64627) +,S(6fceab96,d5851eea,b5db9caa,9a0ff7e7,86c2e097,5c2207d4,67f343e3,cb36ae1a,83f2b505,20094ad6,cb8443aa,69b8af96,b531341b,81cadc21,565d28e7,43bf2c47) +,S(2acc57ff,ff168361,9275273e,9a821fae,54947539,7f6b1936,13917af0,ef83cab5,764b04bc,9068fae5,75a202c1,f01f87,f3650358,3f5d3042,1e246020,9fdcb94e) +,S(2ac302a,28126e57,5e6aee8b,2b12ad19,f5e1c056,2d63d73e,80204b1d,1d4227d2,74494cb4,1e7828f6,9d2dd529,a70f2e52,9bf4b524,26a2a3c1,ab10a974,99624589) +,S(c5de085e,4dcf8dab,497a645,c7abd513,4054b225,32ce8405,f6e5134c,515d9de3,d1da7171,31a859a,a2c90816,386f0318,9759326a,6cef86f9,f3425bf2,390bed7c) +,S(54729254,5f78e410,db85d01a,182bc5ed,84bf6843,3b5784cc,852d3e70,acbfe90b,618b0f0a,7919751f,46c0ec61,1dddd798,cd89d4dd,32d1acac,31432308,d1a615ba) +,S(c6fc6b5d,84bd05b1,ec8b0ed8,fd4eceb9,dda38669,3859d90a,a0853c3,7f75e8a6,d3d8ffb4,988f7e47,2c26bd4b,83f95453,149d1534,bfafa97c,39a1e8d2,70c53582) +,S(1e325c1,ef4a976e,77d6e76e,f9a6dc51,175175bf,23e2c46d,7203d6bf,86ea05ca,60f35511,510aad52,e156e265,6e7ec137,c319b8c1,a1591258,590186ee,be4c1471) +,S(bbca6232,ed8c6093,7ad123f6,87af56db,28947e01,99340510,95850d38,6ac1d89c,d1257327,269836af,2793a1ea,21106bb7,ec95885f,de541f66,1a4a7c38,39c222a1) +,S(c55b1ec1,1f7aff98,710c3b80,34021aa1,83645a14,edfc6926,cd56eeb,f1e5332b,e541bc98,7ecd2b66,d10ce29c,572272ec,28c26b1b,1703919f,d0b28e76,4ffa87df) +,S(f026dc49,feb91051,68f76b0e,7abcb9a3,cc78a5c4,e520c2,57d2f688,5f1c49df,2471f06b,5dc74f9f,6cca7d72,86571c1b,54ab3813,d30bfb57,53274a4b,4257f5c5) +,S(3f721c3c,605169fe,dee4a4f2,b07865be,e1f0838c,669f7eb0,f234e700,f2fb16f5,9691b1cc,ead5fba9,9d9f1feb,fae6baa3,cc7717ab,c5a671f3,8def1556,e27e100) +,S(65bccdce,bb7e968c,a1c5dd12,2d5440b,97b07014,9838f4ae,95962044,b822b0ae,bd594952,f8424625,91375009,3cc6716f,cf7bae14,a6fbab35,4a962282,ee0b3fdb) +,S(6c155658,7020a902,c225d721,7b1a5f2c,5646179,df5613d9,b95826ff,7723f42f,1ee346cb,5841939e,42aa41ed,84bd24b,33075490,68de1809,8e5f8605,59e9c073) +,S(d2c9f745,8f75b42f,b48dea34,13b2bf9b,dc045542,8c5a3dd4,2a08716b,bfc4367,e2a9be5c,8f06a432,6f148cb3,cf58f767,cfc8f8ea,1ff4656e,ec19a64b,183f650e) +,S(aa11c12f,5fda607,aeb4af7f,8430cae,3f5df00a,43910ff9,e413b3a4,7295a38,e506e63c,a0568d96,2c489851,489fbb62,acb60d9a,fb9dcf1c,7aba7be2,2e02c67e) +,S(a355e383,43937932,21affe2f,843d2541,3faf807a,900bc299,5a201f10,d5748f99,22ce77fc,c627019a,ff0245d3,ef2b31fa,55687ea7,69a4948c,5656945c,c5a5c74) +,S(d8f4e393,8b93f252,da68e1b0,16fe8889,d837ea8e,61e5d3f6,8928bf32,22643cfc,c895006,61003ee5,3d8f739,d6fb7cea,e2f7b414,28a65ca1,bf493a3e,27a2e826) +,S(f69ff0ca,3aa0ee7,122a00a9,4b6ef41e,13945263,96e8c590,84ab2b37,6b899cfe,a5211104,271a3020,d65ca305,c0daa6ac,cbbdb1b1,d349a2ba,1abcfad9,bf63a7d5) +,S(64b1b59d,7415d433,7f5b9a3d,98f06d10,7e647525,b347011d,6d3b423b,2a377592,12ea2814,ac8e0bf,1da8e617,c8f051ad,5799593d,f9ffc1f8,abc963b0,faf202b9) +,S(bac6a7ef,9a3de971,51044204,ddc3a2d3,4668613e,101a7e6a,5f93c25a,6b20dca9,7bc2b764,57620478,321de1fd,8ae8afe9,6047d087,b95390c5,bc69b972,654b97cf) +,S(fddae798,dad79951,a4c3b803,11ced882,903c9dcb,4d4dacca,c4cadceb,b837f688,2e21e1f9,f45ded15,76829823,4892d2ca,26ad5b6d,7b0baa77,c2dfbba,b1dbca19) +,S(3dc783eb,40779120,25b7dfe8,f493f073,b3a8520c,ef0c94b2,1c3a5388,b0a9a01a,b3fd9020,2ca16d20,fbe8cee8,fb8bcbcc,821696c1,15545aae,84c414a0,c4401bb1) +,S(299a187d,299c61cb,6893a5d9,cc8831e3,df92ab13,da2f0048,555d1358,e55e866d,ef0b105e,52a18751,56080cc,cefde2b2,848d43ba,6d650068,2b71fb9d,d34b819c) +,S(b690b4aa,fde43b5b,362de597,100c74d8,97cbc750,688a46b4,cb1093e2,e253dc4b,affd5af2,30e4de4f,9971627e,dac86808,c97bfa30,f051af29,bf91e36f,c3edf0f7) +,S(7217384c,1596318c,2a98db2b,7264c909,f823de21,702f5e64,b19af937,cbb8be39,b125b7aa,1bd67232,df7d2d3a,a671bbc1,bace159f,3ba2fad5,e82a1ae3,965d5c01) +,S(4bb4a86a,58f1248a,11f61599,f420fc69,bc77b7c6,86d2838,f4368971,67013852,29909cb1,3bce655e,88300d78,4f7984de,352c9b9a,960148e,a5b65acd,99b62d4b) +,S(4b3a9328,2e473993,9d7722a,7de44fcd,51658eff,93c3711d,3a8f0193,9a54902f,9a012a8e,7df3b988,204fe0e0,50cc197f,a27618ca,d8d712cf,520c7be4,cf4e0f02) +,S(5488985b,26978af,50099d93,8d7b1aa,c545b07,44938190,e0b880c2,11782b26,b51f749a,76b998c0,83dcdbe7,21d5fa0b,c4aa4392,f81821ab,3436fbf0,37d37bd7) +,S(7f2ff4bc,f270b566,d2d26cbd,ffeb1b9b,31b2cd7,b647d89a,2c86c003,b23f644b,f48749b6,21ed28ae,47223281,fe8e633f,35580bf4,8eea29f,d6aae487,ee8e0588) +,S(3305c475,1d63baa8,18f5bdc0,b4e46c9,acdf1c42,9ff5d177,bdfc214a,b838efbc,491d45be,85ae9675,310ae85d,258c6c9c,8e28d7fc,5239363c,911eb12d,ee68a435) +,S(4195dd13,ae5ea569,179dc64,b07f66dd,4a2e2878,d81a222,304d6a88,4da60b86,bbdb99ff,8d4ce150,543b48ee,9109f127,5234c69e,52293758,d0171ae4,ecd49677) +,S(8dca7466,8ffbf319,7dd9826,cfc7f450,fed841ed,83e1d466,e92470ca,1e2582e0,2b19be5f,69fae0e2,563a3f80,2f9450e0,fc48ebe5,973f542c,4c12fbea,97627e57) +,S(e235d150,3449667e,ba23d119,9b5225db,1b26220f,60f84476,70c6bdaa,f5eb7aa9,3d4d8dd6,b0c8c2e0,c8f54f6b,dffe8dd0,5ae22d5a,b4f9dc18,f17acafb,3fab327) +,S(aa214fc7,23c3c458,8bbfd962,b86cc3b3,e1ed52a,25524ed3,ee5c4933,1748ddf3,9b54e29f,63240e30,434f7a22,2679006c,24593e26,90254978,35a60897,d3578e18) +,S(1c468a51,cc9d2632,860bffba,9ed83e5a,e97dc1d8,c8bc3577,5dfef223,b3ffcc73,fc569e94,8eb20528,98b4cea3,86486afa,cec0188e,44dc4e0,25b34855,f1466e87) +,S(c663e752,ce62dec0,81f8ad57,3e4f5c92,138e6a8b,e6c9d015,d5cd2cf0,ccd1a203,ffc249a7,554fb97,c0f9d96f,4cb06fb7,ce6e868c,e7e60b30,f67a2b9e,919f6f98) +,S(949a84d8,5f68f70,81f379e1,9d673748,bed14bb8,dba2458c,34327c03,c893067f,1b9fe41c,f474e57f,8497f6f6,76472a28,fba6b259,91297f81,474cb6fc,f31380f0) +,S(6a4bf3ea,5798c8ed,4b35c629,c6cfdc0e,d16d0d27,39f8bcb8,c34a9105,fa35fed,6f69e357,d5123305,56d04946,f9265353,77610fee,20667815,e7f3cb01,e8196b24) +,S(d0a99a37,d1df89c0,99b0dc1c,16f325b9,b2ec1455,21d4f80e,ad67da85,4f2a5357,7a75846d,eaf7c4e3,5c0c87f,83732eaa,7f6903f7,b721648a,87e1909b,53d3e9c) +,S(e2a45683,f3781309,b6223a7a,5ca64c4c,cbc5d45f,29c66082,912568ca,3ec6d3c0,8e386acb,63c52ed6,5aaacecb,fab458b9,9585951e,cd0e35a6,19c0fc39,5ce1c0ab) +,S(9527ae80,10ddd443,7237c2b3,c8f3afb9,f31e1696,5b10fedf,f150c296,3cb8e60,6e0843a,87833be4,f882c417,7198d985,5af8b144,11e78c3c,497fc49f,5f728479) +,S(15f15c4a,2cc43062,d4360a8d,dcf8e0f,52bc4741,c7924f6d,e1dd9f12,a06b9b2,66a127e7,2c55db1b,57050f4c,a0d8abf3,9ccb455d,9785a4f3,2ee67a42,3bfe5ccd) +,S(558648bd,64c52dd1,189912b2,67078e8b,d3c68952,47e6c848,d7dc529a,7a24a75b,12332187,62872867,5bc88378,88deadf9,3a8f2c5c,864371dc,6be0be63,44fad7ed) +,S(1e87928a,b6e10b59,6b231b08,87a823f1,3c6b3ff3,2852d35c,d1167244,fea2db0b,4cf60a4,767783a9,1c9747c5,7abbade1,3d7fc02f,e833b474,648038c3,b68d96f5) +,S(7a169de9,1d4c3f0,3296279,2c3ebfe7,f2eb4410,f7b9a34d,c402ae64,ce9231fb,1ca2e8be,7a7603b7,d95820ab,86487a04,c91ab3fc,c88e2f0b,514a1589,3908e463) +,S(65185a2f,bbc8c96f,cf9a6df4,d002128,afff1f2e,5c0182a2,95639a7d,9fecaafb,10b6902e,e83c5683,3d796b99,665cf365,c1e41d63,41fe72a4,72e5ea6e,39dbb9e9) +,S(61c45212,4664432e,8fbcd950,1dbbcd9f,1fb8842d,c8e61758,439b6d5d,bf8dd626,2a9c7c57,48509dca,ebfc5062,4d7a0b0c,21c9f5a,45733f8d,e0441bf7,f2b359c0) +,S(f61aff9e,267b6d91,e3d4ab45,73457987,b1af9a9,38b659f4,1ad5cf57,8cc59d62,51d0b694,e5692be0,6841a3eb,160474cc,6c248213,19c9648,c32ea444,29cb2553) +,S(29f27a51,8fd448cd,73aee0dd,7316e566,c655ca44,afc5daa3,ee359ae5,b96f8bef,d5957a97,a6447a8e,a8301219,5fd53c1b,63784a8,14c29c80,d0061fac,2c6cc1a7) +,S(c656d66a,efc3597a,2ee977ba,bdb7357,a2485a6c,d654c56c,bc58a0ad,598f202d,f8267b3f,f293a5b5,11f4e466,dce0fa88,a37f1603,a3a8092c,934fb824,1427a59f) +,S(f28477cb,efe654fb,ccd3a9ab,e816f950,3749e183,3b1faebd,418c85c9,112a5135,9df0f505,6ad98099,ac0dc723,34af973d,9c98c597,ee26e22f,a0a7a60a,a3b76cb7) +,S(d007a1a8,b6f05046,a66fe0f0,9a02e510,3ca7555a,277c40a8,87a71920,5a429e79,d9a68c51,f17fd51e,b19e4946,694e90f5,2cf664ed,d2d45489,5f880400,b410b8ce) +,S(348f74ca,7e5b1ff9,e6ccf3d9,90ff1f7a,4e3a8296,725075e0,33a85b2f,5ba0f338,1648c7f,32a206a4,e21e7309,f1a68a4b,b2ee116a,f3fab3f5,7455da93,7c4afc7a) +,S(1f54e125,7ff3dbcb,f1b55720,564f0c72,d322b8e1,f14d2b9c,1f6244d9,c85f6f70,34c23405,4a970b58,2cbbcdce,e67cc564,6e187cd9,b3024dfc,731a212c,c53c2861) +,S(a984f8be,33360b3f,a012cb99,65ed10e6,43a8df49,26f8188f,24719a7c,ad6b5238,79a592f9,15c925a0,98406d08,75ec4fa,90b5015c,4001addf,1cab32f7,9f06f213) +,S(2ca5e948,76db7877,fb828609,68e39c8e,a413a057,1a39e20e,a7b98f93,f4cc4887,b1ce7c2f,8380eaff,57299cef,e840c552,53629691,7ed367a3,5c59c3b4,ae67a02d) +,S(65bc7a84,15cdd07,5f493310,de05b7a4,ae7c874d,5b5221d4,7ee556ef,4c21a0d5,ad20620,aa39a14f,dfad58b7,9f1ad70d,2c637119,d9eb33b7,ca9abca1,f5dc3db3) +,S(a0b6b293,a9e25a97,18fa0db1,16362757,6e39cd43,83140822,b2241fa8,c432f276,2cbd88cf,29570778,8a6d79a3,b451833d,c596fa08,8b26c6a9,962880bc,48ae2b19) +,S(b4d308f5,74f7832f,4f402626,5ff81788,91a86724,9df74486,f241baf2,28e130a3,ca82dfe7,4c5768aa,46927fe,70c93227,cc7c30ed,c2fb6303,9a1552db,534019f9) +,S(819b48da,f19c48c1,f6efd0b7,c4ff5996,dcd5e99e,7146bde4,1c83e333,ac891b3e,c15bcf4,c9a630f4,e1489585,e5719746,ac55210e,c9b82da3,898a0d88,4eab0459) +,S(66528e21,adf8c447,526d616c,777dde1,fa7469ec,175facb8,3ac9ed2f,db773f85,c5d38c7,c13449ad,4f346498,1eb7abbc,a98de561,d94f46bc,edf3dd10,1839d91e) +,S(a26e3a0b,6f61c611,28c2afc9,15ddf48b,8d3d3901,df93a2b2,aeb82579,4822e605,41f4e806,787884ec,84716647,ed72f331,126f141,6837a232,e1612ac9,99c7d115) +,S(56623040,c198fbcb,9aa32066,90da22a5,a0496a82,5313a2fd,529fc9b,26647d22,35867158,42a4c950,e67b9033,23c55fe0,3ba3bf92,a9ecc5f8,39708869,7e2e1e98) +,S(acb401f1,b535f181,75ba9cc5,8e32514b,be8b6d19,1401248f,20500dba,23ad4f,f57fbfc7,9bb94ec0,eac7d09e,52b699e6,d8407335,e6dda706,f7d1bfe0,71e09f6a) +,S(9e02a873,fbbeddcf,b760d48e,6e29e6a0,b37cae8d,6348a8d5,bd651be0,59ecdb33,9f926735,cb2f46eb,71005600,56dea853,9fd6d140,2a57d05a,e884e8f1,1a293c39) +,S(3e88f76b,ec410c46,ca20cf7,2d90c66f,476fb966,c46f20b7,facb7f50,17f71617,bbbb4d9,a453277f,a7bb83d2,eb8b2950,3fe51b0,7d4b93fd,5e993663,9b78438b) +,S(cd39870c,a6484a9f,e6d30e47,3a6f5e8b,3ecc1702,e191b5de,3d4d6cbf,dade08e6,234240c2,8f2b2233,9369298e,f22cf32a,7663edb4,2524f02d,6879b4c9,f4ab442d) +,S(5de275c2,69799058,3348c4cf,8c039b44,daf431d2,b7b1f862,98ae24ea,271644c9,adcf9fc3,10ce2d93,8459db47,30273255,cc483342,3f6bd4dc,56593f06,6466b8a9) +,S(2d986200,bd9dbe51,eee40ec1,2730701c,621333db,9e71c232,1a6463e1,f26cb76b,57433deb,d9149b32,37315114,e9747758,228d17be,5f7c54d4,f552e730,1e094329) +,S(654868b7,39d6a72e,75223cac,d0f827d1,789c410c,fe0d5ab7,24cdbc2a,c9bcb269,3d8d4270,63cfe,6724f8d4,77ddbd10,b24899a,3ab0a33d,87683646,9f4806ba) +,S(d97cf5c8,e1a40197,75312099,fb1a2d62,2b3354d0,e524cbe7,bbd3187,506f909d,53c8784c,cfc900a2,f159e98b,76481239,3d883d70,8a953905,44691b5,1c8c97d4) +,S(697707cc,9c74c828,7396d53b,9e5d436b,24b861d0,2fcd9208,dcdcfb54,8ad2d903,bd203dfe,7f4a3484,1f5ec966,f063d251,a89b7da5,468bb2f7,32775a1f,3a62412f) +,S(36b4329f,fbbbd80b,e8eecd1,358c05f3,6616b456,588571da,c23d7752,edf15d65,7c42145,d8774827,a0cbe9e,b9ca7b90,2353c6f6,118291ad,950dfee6,124fef3f) +,S(dad2b02d,a182ef28,5b00b0e3,2af77064,ca6b3c1,41766194,7fae0663,4861e144,ece34dc3,704d0561,f6029366,aa45f192,a2b55b1a,1786e8a2,d84b2361,eb2c2af1) +,S(4cdf386a,c0e7cbc6,e19c5f85,1edb009a,59b0526,f3f4d0ca,3c82f280,dd33531,3f8b3eda,4ae484e0,95916efb,ecf1ed3a,27bcb034,6cbae87c,6a388488,331ddc86) +,S(d4b65a7a,eb74d38f,2a8e9383,2ad27a7,2e2a89f2,2ccb5c24,9e4e55d4,da7a0cf1,a080a32c,ac9e0ee2,6e6538a0,233f2374,3428b2ad,821852fa,bbad2a23,63a7d7e3) +,S(c41cd230,d99c5f66,7d7ea000,53945fed,70a2a807,4893d488,5be2ee46,cadff9bf,4a7faa2,3ea4ab42,5f21e12d,dea7530d,429c64fb,c05e1b24,adc24f55,c34af43) +,S(4c67ce59,9a841ecf,ec147a89,c120619a,227100ab,c5dd0ba8,da6d362,6f687824,aec0ecc4,b65694f,150da4f8,fd514d37,52f4c6d1,aebd8b5c,19846ea3,bf4b13b2) +,S(e765b00d,a067b5cf,a40bf02,dc8ed6bd,4e59b470,ed6eebad,c02b49eb,1d20c37,23e0df00,9ca95773,a91c0805,40b024b8,34c0d7de,4dfd6c43,76c979fd,2665f21d) +,S(18a8cbe4,d7585fe2,3b958cab,a9303d9,505928a5,7ca1058,21a9f192,ea52298c,9d00506,4a1f3406,c3864d73,2ebf3e1d,b6f20234,d0f5a99c,3623ed9d,530d71cc) +,S(2dc043ea,a53c27b6,50e2f1c,b6fb7fd8,26c4fccb,9572bbf5,103356bf,87b3d649,2695f192,af96b031,a41b72e7,a61593cc,30672c07,cedb0908,35ee207a,5cf18271) +,S(71699cbd,e1efa1f2,914bd0ac,9b28111,8053f7ec,d51e79c0,44daa4ac,ded9c9e9,8519592f,a3b05922,86797110,b222231c,fef973bc,d51ea4c4,34998999,63637c05) +,S(23f4668e,40761e37,235dc0cd,41b6c7ff,1951678f,131763b8,7d394e12,6be4c370,1cce4181,2279761d,8753dfaf,8bdd206c,e4cbfc5f,ccfa8826,9d2d4327,431fa689) +,S(92366959,9a173d3e,826233c7,8062863c,2a92b525,106c1159,4885058e,4a7797a6,d1c9f57c,d03c0042,38f898bd,cb45c064,a1f2cc56,222bbc03,a61997fc,877b23d4) +,S(a2dd03bb,a75a7bb2,fc9915df,c66c0b22,76a7347e,6cca3d32,e5727cb8,b54bfb70,9ba4266d,b9c66907,b25c41bd,b96f8a94,a9559830,f171a878,66372067,51c7126e) +,S(79174d3e,2379484a,d3191db7,26073dff,d69a31c8,94314f7b,282ed68e,71395ad7,1cada148,7ded181b,f1a9cd30,21afb04f,4402a171,3a570d7e,9f4928c1,2069315) +,S(874597e3,80449235,af5c10e3,7af7eeb8,f755ebe0,6784d5e3,ba0d1021,fcd3b12c,2ebbde83,58c4f2ed,cc89bd52,e6cd61df,a251bcf5,713858d3,d247750e,266a6129) +,S(f23c1888,c22a764,c85c6328,387e9126,f4ad772c,fa0a6034,914d5f60,7efcddc1,6cd5bdba,cb3c6cd7,4c2c5cf8,1c62e774,560211ac,f1ee8096,be9eee5e,b716881e) +,S(a4c2054c,3a834498,6dcca592,db5fbe06,7f80d32f,8c492436,79c57b76,ae13b96,7ca515b7,8a3d5590,6100ecda,f7066459,db9db34,3bec1b4c,6a57626e,1f560444) +,S(d6880dbf,50d3faa9,835404e5,d723eec8,b1bae88e,b8ca22bb,a85fda5b,6a8cb669,a08c4200,718edd4e,42b775b1,1beb9a6f,eb3bb93,b54c57af,5218eeb9,7aa9fa09) +,S(2dfcf2b0,babd3990,c305cdbf,cae7795b,a2fb3cb6,3ea0cd17,787122ab,5af86bb8,e0e921a,15882601,c151fd93,d7b7c607,cf033633,e6498004,d29cbf76,7fb19f6d) +,S(d1dc82f9,aae7e02e,177680f1,e5d73ae,8a178207,7b5ebddf,45b56bac,fa1f11b1,4c9294c,e3ad0fa0,ceefde5f,fd80905f,ce57a5c7,c6807da4,186c9b4a,7c9d6237) +,S(ff111200,4231109b,d131e7e0,f6434461,ff699d8c,6be3e6bb,7eb9e827,9af4a4b3,2c30b8db,bbe56de5,3d8b3307,9dd741ca,8c7aa596,78a3c75b,a781a77a,e470620e) +,S(9fc4e1ac,28a8f268,c66aec12,f5e795d,f3dc23d5,c515c5ec,11c394c5,e6f2a11b,188bc037,ab114fd6,508627db,12317d0d,fa194cd1,bfd56c1a,4ba25d07,206aaaa9) +,S(bdb0b373,5bcad639,386579e2,aa78fc40,ec2f4700,4b3174b0,1bc2cfdf,f4164f95,45d65b9f,eb1f60f3,29195060,78d5c016,8c6b1820,6afcab34,a2623e1,d2bc70a9) +,S(1386e11f,3950b8d9,e87589da,c3dc9a47,bf36b0c7,8378d2fb,253e5bdf,9f704465,415f50f4,f048413c,7eec4c2d,122a4f7d,f4908265,31f9dec2,313bc7b,b1b2402e) +,S(be246169,75b321a2,edd491be,90b7a11d,75a36c12,ca782d20,732a285c,5a6a1572,ca9109cd,5b041864,5026977,9490edc9,d239778c,25609736,7b52d82d,97f588cc) +,S(baa5965a,c352a017,80b1359,3945030b,32c83b60,805bff01,476ece26,cf89384,c83a9515,dee6663b,b5688d5b,483f0a2e,51c8180e,a130e0ea,48f7a4f0,1d3d06e6) +,S(17dfb33b,957bd5d3,36c918f2,cd1fdc95,23e2980f,20a7666d,bd5e8a7f,8ab1f83e,32ffdb3,db6dfa31,ca67a5b0,27a648be,b978b6cb,7ace4241,a0b6a7d8,ceedda20) +,S(ec5dce25,af07a01d,9dc43a9,e92dfb51,29146307,cef69b48,cb7b6e85,d9cbd91f,1018c449,949bb2cc,e185a9,4a9a06b6,bca4c8b0,1a3079b5,3f86d830,21d46de) +,S(a56b5b4e,d4e4e3a6,29701889,2cf21f67,868ebf37,b8696ebc,83afd980,b5c63817,1cea139e,521c70e3,f0a4b02c,c20345df,90a579b1,20ea5dce,bc1385bd,162adfd7) +,S(2ff27783,681d264b,540df574,b478e3a6,2b919e0a,c4ab1b66,3e279083,25a707b7,3a477dcf,65b233e1,34ddae74,7fa5971c,cc0498e7,be9f17cd,5e34bb0b,480d360) +,S(aea30054,dcc9f7eb,c9dbbd45,cbcea779,49780d59,11edcc19,937e6352,a726b3c0,7ba5e2d8,9f681e00,bb74a353,f37c36c0,7264acc,d6a31529,cd5275ee,94a631fc) +,S(78531772,142432df,81802ec2,84884682,5ae2bc93,aed1fa8b,e345c106,7e23d059,6b8d514c,a0a13c1c,6425e5ad,f808aeff,f88fc6be,dbdfc788,1d174868,efd21063) +,S(c104c683,8448cda2,c94b0303,7b5ddcca,d4db1d7e,e744e70f,5f9275b3,244b8405,ac9e6545,3722e2c9,d7d97aa,767c3235,2a213391,aa2e327d,3884ecd,93f4b133) +,S(d4b02b47,3f851a30,604356c0,e9310d4d,7bd0f9a1,17db0c90,54862b58,969887c5,d451896a,5eba571d,4e55d26,9c3c8082,55c5cf18,f1f2d033,b8d30788,224a68f2) +,S(93d2f6a3,e97e4aa4,10fb6006,f3853f85,65bd14d,aec87192,e61b8f97,93f29b32,a0a840bd,336034f1,a98a0239,c6ab3ecb,eadd69c2,51b2e03c,339dd4bd,7a407308) +,S(7d7d7357,467e23a1,2022788b,2ada9a69,1243fbae,486cc61b,56458e2e,781f8f3b,59d5566d,97bb583b,940de406,44e19530,b1bc7ced,2a00c50,f4bbef30,d899e7e6) +,S(ea80f7b5,8c72080f,f2d83604,ccf6e4d3,28a71914,abf94888,8dc87c42,15fd4a6b,ecc6e626,f01f73b2,5d7e92e0,d1220b82,8f2f8ef3,3cc92111,3d15bfab,179ad8ef) +,S(c74366e7,26949fa0,6913e6ab,c41cb17e,c3837659,253c3038,30d543f6,ac0e4aa6,671ed272,2626ab33,14b6b1d8,1cda24d2,9fc132f9,51f97b95,8e72bc0b,9eb42d3) +,S(6170ed4d,c3dc2218,2b45c1c6,fcee9fc1,3897ac17,fc32fb25,aaf2880f,4cbd11bd,cb40f34e,7e8faa89,71338834,21cb247a,4c938f3e,f6a97cd3,1711f803,c872621) +,S(7dacf9ad,5775fa62,f99e093,5e948526,b94ef22e,912ae95d,8dd4e5ba,744a2ebd,69931690,6c73045,d8530a39,d33a8e21,d5912969,9f7b721c,1dd0c616,725d5778) +,S(b1d113f2,ad7b487,908767a0,b6faa413,6a8b3dad,41dad9d2,b6e8e7c,9f294639,7c802cbf,4596903a,90b1de93,649bff3a,6f63ab85,a9e3529a,7d907b41,7f973b61) +,S(d09d8d8a,17a1b113,aaafc270,db36ed63,4342d90c,64b6ae97,9733391d,eb67f3a4,c48701eb,738c3edc,a4f78313,a56660f5,3da8ebaa,3cd8d469,d1dd5910,c618851f) +,S(c264ffb3,c223e60f,fa34faf9,feb18668,4b05b7e0,6770db1f,9561ed5a,ea0bfef7,e4df501e,ebb4cdce,bbe6c4cc,b966de77,18ac5479,3e403e79,389ac330,92928e6e) +,S(55505edd,605e4299,afb5a69d,81f6df34,c7c2133e,dbc7bb10,ebc49187,857d7c49,ddc19610,7c3bee6d,ad955e1f,76afb31e,93a88e4b,de8aee59,aba50864,c295a487) +,S(9d61801b,a07c358c,f9942bd,d3614d3f,74904b8f,8f8aa8e6,a957eadf,79fe99ef,7d9d5980,2fb5dacd,93ec6c6a,92ef86bb,6079076f,7d964d31,70e3ad3b,7bb854a5) +,S(f1a6cc66,3dbf46da,e1ca98af,610f09e5,e9251a44,f6b9915c,b68c58f7,9038645d,e41bc6cd,747c0390,6d29e29c,4cbc2dec,6817114e,daedf220,b7fce48e,7e6f42ee) +,S(df247558,50b523d6,de15c3ec,38537a3c,af9a90fa,2c0e8b25,35696289,10517a79,bb567ba,e42e9899,85fc478a,4303188c,2da741fe,bbd1742c,818ec1c,e64818a5) +,S(4dc30b60,b174bb78,1f339277,ce3996f7,fe102e13,d80873b1,1a9e6b4d,54247cef,b13e5069,a7344a99,4f9cd284,1d9291a6,50e1d969,dd3061dd,ef34f037,7c85e20f) +,S(e77aac3e,946f7715,b9d0999b,1f3aadfe,de9c31dc,f8eab336,c5bcaa51,f16f64a,9d78c14d,90cb37a3,835d23,fd8d5a37,2b8fa160,1274e5f0,2bae50f1,587a11bd) +,S(24f29bd3,51e62864,3a7d2fa,6c47ab78,a6d0c6f2,c73bdf00,864e8bd0,c3f038d7,4a34c7f0,22e43220,f6d30d59,3d3ccb54,dbbcc50b,4b845712,e72636da,d0cecff3) +,S(ad4b9b47,b9cac9f8,a5f3728c,ec610000,163ac2ec,6a18cc34,b630134d,9fcc9364,afc8726e,e0f988f0,53247177,1efb25ae,e07b70ba,ec7c425c,50e3eae,2898c077) +,S(1d38128d,ce7ede1b,265a4f8c,4e6b911c,d0e28087,87244a60,dd9f646e,2932e509,857a6c8,e4f43cfe,129e11bb,462101d7,9c76e99e,c7b4aed4,efc029be,b1b9c1c5) +,S(c171b7a2,7badcf84,c3c61afd,7568d23,5a14f0f4,fec777b,4a91c92c,61358677,cde264a0,48d2cd4c,d53d7371,8546802f,1ab67815,d6ebb3cf,b6415f4d,5cf4057e) +,S(d50f20d6,f4781aeb,eeca2a8e,85e8b75c,187c6d34,a940266,daa16876,96acef4d,9aa99671,35a1dae1,af29ed05,9fa15eb2,a4aaca27,99d98c64,5ae0ed03,7f08f37a) +,S(6b83cb07,7bfd33d,181fc835,63eabdd3,a50be6d4,abb64a16,e338f18c,c098a977,3e04e660,cfe61fd8,1ec67b2,d20ca9fb,f9c6e038,71f7c838,b261ade0,51b564e9) +,S(2e75abad,dc0501f3,afa90484,e85972b2,679d1d04,62d6d206,42c73830,15213b19,4754077d,a6868edb,a0943397,3c60a581,88a55ced,dee38351,93ce045a,e93517de) +,S(8a322085,d749f63a,38dcfbba,624d0c87,b9bcb66c,e4e3d84a,e97f7781,a0e9a164,3b592b8f,9d8cc10b,58fbdc7e,982e3fa6,7aa67c90,e9ca884a,e1f57291,6d7e2076) +,S(b890b7f9,ba1f1945,2a7bf1bf,944f9949,36bb4ad,5e2e0fb8,15ddc1e,2f30d72b,c1b652c4,f8e9d91c,8a92f76e,f6f72ed3,3357b35a,5ac00d63,a039df78,eb778a46) +,S(cdf33d41,c54c8a0e,dd3a0b1a,12290d13,715de82b,21af5306,a1197444,acfdd5c9,2d7b78f,31d08fc8,afdb3940,ef1afaf7,3bf37029,1e1be3c9,5acdc673,ee2150d) +,S(20b24e10,c0f85631,fb891ae5,c0b0b36e,5a3829df,a5018c1d,8b59fe87,b051b55d,b5b9204,67394039,df0a34f1,308b086a,454c7957,40d31fd8,960f6ab8,33998c41) +,S(61976c23,257b9adc,48147038,ff5ace08,39d88274,9810bc9,25590555,b0e1c709,2b31a4c2,a712edd6,6b2da3f,84447c73,f2e3f652,d22b81d,d37ac4a9,def5390f) +,S(4ff22758,a2a25681,d28fbf09,e4cea5f4,74c00681,d9b4fe6d,ef3227e3,6092b52e,4b0f517a,4e56697b,37341ab0,6fbc92e2,4ae3d03d,392c33d2,377f7432,10a89fdc) +,S(46145b19,639938dd,9c6c84eb,d4180cf9,752cf9fe,a77ca609,5ffc8f7e,ead61f35,5b7b55dd,8a5e7d00,a3b62d20,2f371d42,8eeacc9e,7556547d,f2396c85,9503f6f8) +,S(32464689,a5d7626c,fd02b5fc,da68a8f8,dec32eba,887b523c,4b4e379b,c40bee7,6e9cb8c5,3fb716c0,b583b356,7ba6890d,2cdccd39,646a49c8,132ef061,d89f6710) +,S(56438894,2c9aa575,efbaec77,cbecd9fe,79fb4461,c61ac051,195ae384,dc0d6ddb,663528a4,29696073,f9d47d2c,bb2c256,9bf6c452,c171ca43,7cd3480f,95b69a05) +,S(f04fa37b,9c510bea,ec12fd4a,307b1b0e,d934fa1c,78cbfbe3,bf904b00,91491e4e,19b7da4d,826a314f,586c4c78,457a3075,76f3ada4,61af5bb6,c374178c,23a79326) +,S(36fe4596,b1ca6409,741f7a0c,b899f89f,a727207e,eedc8e57,504847d,2cb304cd,78f11f,4473b124,5772a101,564b6468,43d4bf76,afacf02c,bc45ab39,c7221e19) +,S(ce3e6d1b,f2deae03,8ea4333b,ebfa026,d1954ffd,f50df66,e2899b05,1ee87b0d,4cd4635f,10af69c7,50e96ede,e4f38591,2a14b104,ed9023af,60ac6e93,a9b9bcb0) +,S(33ad3a7f,a6008875,74bd735c,b2ec5dff,10ffc5dc,3163d8d1,62644086,888d29,8c959ba3,2f7b8ed0,4cb2bf2f,2b5e5f56,b29a851c,8d1f6bff,b48fab31,5335b3e0) +,S(7101a2b2,36aa7903,6348006e,cb8f81f6,b481ed8d,8a3081aa,40ed475f,13fde43d,d0a93654,51471aca,80a05745,57b4a24,9d627dd5,c1428ed5,79feac02,5fd2cd2e) +,S(ba3b4042,9c0bb526,c31cf602,3f9abe17,69974344,5e66566c,851501a5,d125471f,7db3e93b,e9944c42,b1654407,6d5bc6a0,99806c67,6cc7415a,9d110661,f4c644e6) +,S(57c6a582,1da61528,dc291aec,3a9f1a86,229594a2,27767583,5687ee91,15acd72,a9e4750b,5580b225,7768ce7a,b2909466,589a1a12,2e54a7af,35f44de,44cd5dce) +,S(c8353ee5,847efb7a,ec03d949,633132b3,9ad898e8,9a367c77,7b4a2ece,c47a7c10,dfce02ff,71060be,5e12d377,524c798e,97bafd6,e9aa9e10,27c07a8d,6f7d3a55) +,S(b0f6ef67,78b4ee99,6d7807ca,9f1f6f44,203eed8e,62584c6d,666e3698,e41c0eb1,b92763af,c9ea095,f757e921,ac0bdb02,605eb66e,d3e1735f,f8f17e63,dee5460e) +,S(f2e4015e,62645bd4,6f858b25,cb636f97,6ccfe5f8,da065b65,1ec170c,ecf5c411,8c05cf9b,19459597,7c1d1b6,4ff6e902,5d78a175,6416e0a,ebf33c21,7b3d5dda) +,S(ffcde722,ad4a2223,24396b52,5a95a233,31dab41d,95a4e19c,1a23c2e3,db7460f9,f7282903,525ac2ed,3f9db21a,92d3fe4e,b1635a8c,77dcbf8b,e671146c,8eca8115) +,S(81dc05b5,2d9a210c,4904bbde,cfb4eacd,8b3f08f1,d667e9f0,a27345a9,7d37b37a,747aad1d,bd0003a6,d89f9d9c,fc00977,719d24a5,b8ebb807,98d1b644,87105f5e) +,S(5b92318d,a267772d,94656087,8d698aaa,7d2c721b,28dfbc20,9e4a3e8d,1b0eef1c,b2d274ec,7aade417,4f2f8766,1b5018bb,47c83d32,b2fed50c,437348a7,93041906) +,S(3eabd0fd,6b5bc51b,c187c943,511c3005,8f86e474,8547fcd6,49595070,26fb805c,95e8bbe,8187398f,fa4ea4cb,b50bae2,19f8cc5a,5f09503b,3edd115f,729b2101) +,S(a64d3807,f92b91e0,717c310,ec799908,43e3a394,a5ece3c8,7c3bb209,8d3123ae,50fbacf8,be11f6b0,ea0e36b3,5c46bdb0,8fb79064,59b52901,9af59b1c,e80ad239) +,S(db9ce153,7cd47f3f,4b08858a,d429c975,9ce6738c,2e6d56f0,fca12e70,777b83a1,a91b2016,9fb1e2f,fd52192d,7030d86f,66358516,5ba32829,6c9aac95,192afbf6) +,S(bea03f49,76ee0a86,e00bfddc,79e52173,1baef841,d751ee47,9a46cfe7,89de2399,feec1fb0,3901a923,862054e6,7024ba7f,4c485c70,2ff22aa4,1620e857,6dcc863) +,S(cda308eb,6975d59,db439e23,32505d29,4ebdca67,5373ed79,25b52a6e,f60a33c9,7d2053c5,414c9bcc,5155f17a,6fc206d8,81cc882,54341778,1c5db51f,3ce4c224) +,S(430bfb3a,802988b3,a68d5595,c989cbe,75d409d2,68dd84b9,a1d4a5b9,42360174,3de4c6e1,3c87338c,8bef6195,6559335e,bec503fa,2025529b,b015cac6,6d8060fc) +,S(b4b1b7c9,932be243,6b06b2c1,e5de312e,4a409498,11a226d8,5bb30c5e,1487c36d,e169a70c,b95988dd,fe1a98df,527fc172,61cc3103,88d41ed3,4bff23bb,31da4dc0) +,S(7a954055,d2d6acda,8dbe81e7,46310113,e26af09b,91cd59dc,92a479c6,d6079ef4,83c6d3ff,4582eea7,becaf8bd,422c0558,a2bc8d6f,cb615c59,7c46982,47cabcb3) +,S(aedd36fa,91a7f95f,2b2f32c9,1be77860,75783bcf,8fcb20b5,f20ca664,dd89474b,c747f32a,174ec6a7,936f13a4,7e80a2e9,324b7f5,e163b396,218c4c35,9391e565) +,S(41052d48,54402d09,a813492a,2f9362ee,9799ffa,3d270200,45a0ae07,9f913f60,97cbdcf9,b60518c9,74ddd987,386d60d1,3d10defc,8fe64511,843d5bf7,13774178) +,S(886e5afb,69f6debc,c1c5be6f,b636eea8,7314ff1f,975cd96,9070e376,c1a9973c,6a8ec4b7,98fec5e,b4a8d645,c7b72663,d6bf4aff,8f4f4b36,c064bf3b,f6e7b5ef) +,S(c93adec2,ddf85ba8,d9147c91,82ee4fbb,5727081e,a6938c0,a4bcfbfe,6856dee8,9ebef5d,2b2253e9,4474331d,b52739c1,71214093,aeab11e4,e51a2be4,e201dfb1) +,S(d97166fa,94a4e51b,ad21e1d9,76e01011,655ce24f,5f5afdb8,feda67bf,8ae65a83,815ac894,57f83bf9,5579fed2,ea470ad2,ac1c83f8,546ef3f8,bc383701,1bc62a48) +,S(c23cf94f,c5a93aa1,719ea8d4,4f426fd3,d48220cc,10ea558e,e4680c1a,dc91b18a,64a4dd89,8f36efa6,efce9354,fa30f506,be3766f3,a31839e,1fba56b,5a07ebd3) +,S(7236b1df,88751e98,2689e049,c5084b71,b8d7979c,2c412a3c,995e61c7,2440929a,67155955,bf5d1916,9e36636e,ba56fe44,f7cef6d1,b0afd3c2,beb59b26,5e3b67a6) +,S(d1890a85,df4f7933,ff72fad6,5b95f5c,c9fd8683,3c1bd2fd,56a3b7c3,e90428d,8b4896ad,4b4469d8,af074eba,ac38563a,ca68888c,5411ce0e,b3701ced,75d4f87e) +,S(41ae85b1,9fcaf4a6,13901d2,3cd2376,62f299c9,7cb306ee,8ffc13fc,75d54e15,20d99cc3,215f0b1c,20922ffc,6e111b53,e88ffb39,bb6e118c,61b9e3ee,fa7d01f1) +,S(d125489c,4e07c44f,35d39008,e4e29c43,c28ca505,3e370570,a7bd34c7,57e673f5,d142e19e,825ff93e,b6661160,b60d4e06,b4393388,43500b29,2d4d62a9,28db2bd2) +,S(8c50b3d3,667b2aa1,a60c425d,1128d389,f2786b3d,656ee126,dd57af96,ebaad9e4,55eb7ca1,c2bb5881,7f82cfc,c8b5ca35,5c2aec5c,68dd479d,948261ee,d342fce1) +,S(3e77a3c8,a2e995b7,582f502f,9bb1230b,35311af4,dc8d0744,9211a13b,444fd42,99c427f5,8365ca18,75272508,7dc57985,d59d72ed,aedfd5f9,d61517c6,1fb8679d) +,S(73ffde64,80547448,658ae5a8,529755d7,2ad7ec84,5711f0b3,20acc53e,a15ab609,786de118,c6a0daee,48f3f585,d10b9f2c,b4947661,b844ed51,59903ce5,f2cc8d18) +,S(8f2ec78b,47c61a39,c2ed1110,902b3a43,4fc9ddfc,b11b1ed,75c675be,5b8a172c,441686b5,c1327f0f,d2bee35c,5d8f2aef,b6da72ac,e6206982,6d6812a0,5b937346) +,S(c36c0376,d360f87d,28069511,7eddf1fc,75ae7118,5fd5a82b,b47d8fcf,519ae4d4,44c31c56,cda1c2d4,41161ab7,45f3c0,25c4ada3,72396658,cca23f93,bdb6a303) +,S(1ff06490,3cc7e686,d408909,4812a7d8,531c4188,ab8aaf4f,f10bcc5a,9cac352c,87af78d5,3122ad89,9a6a1297,fcc87c1f,252bbf9c,d8cfbf57,f64cb6ad,fe77f3a8) +,S(1265a4c0,6e1f1a6,126a9e37,a6e4f90b,290fe449,49b82bca,8ea73759,451e0b25,4f0f7a6c,9bc7f00c,42b90d95,95871176,d723941e,38335581,8f7aacdd,f830d15d) +,S(2595358e,4d45d362,5fa1c89d,a3249cc5,a26ec3d1,e554a863,51b79fc3,4eeea90c,d9b8d147,e4e00450,1baeeb5a,8440235a,88913063,bb1ffa78,9402c3f7,2c603899) +,S(3f432621,7a5f415c,b028f338,40fc226e,5906a09b,d054eb55,45609fee,90135082,a572303a,131fb0f9,c63d88e6,3520ef2e,77bcfea5,1031fa60,fada909,a610c830) +,S(9ee85c9b,4cb0102a,6b21c517,947d798c,c26dd853,7bb5d6c0,46a50144,f3297f45,85b798ab,c2e4fcdd,bf3e17b0,49e2a495,6239ba16,9917ed08,ebe109e0,4ac8016d) +,S(479c2ec0,28e8c83f,d7946f43,8d802ed3,d728179,55d94c55,bdef5050,67774934,c262229e,23eacd99,f9d3fb37,b7b9040,47cdd5a6,6872f4ac,800dbb3,d87fc3fd) +,S(2a52f4d,821cf4ae,758ed477,6cdc3bc9,2d3924fd,97a12f1f,4dd5a646,24766b4b,28500754,6ca8f142,6f3a4a6f,6ccf8437,37c6a917,7ab59b92,728f588,f11509aa) +,S(d89159a6,d5447ab1,bd03d44a,a8db3410,c86305b4,4f06b25,b88c4244,5ab1e929,c539ee3a,e7dec645,810c4a02,e1777977,d98ddba2,281d5701,2ed2a4c5,85057013) +,S(c91267af,4c303e07,ad82c1e6,2ddd45d7,cfae00a8,d27a34f1,eea8d15c,1add920,975967db,347415ae,24b427a1,b8f7229f,8db0758a,7ea13f7c,582c260,c0711b85) +,S(c860be31,18ce92b0,39b27a50,960d3caf,88e24bae,6e45fd8c,5a253a78,e3d0e6cb,15b8374,922f44f3,adaa213d,5e3facdc,9de1ff6,4da677d3,d89f6e0a,a800413f) +,S(eb8b5f4,2fa90313,b3dd7d4b,d47338e2,9861e52c,b492e9dd,6a1897ec,4da14c14,9d1c4d0d,56c570b,8835e188,517fe7db,490aa6b2,bfbe1564,579e7af9,c0647bf) +,S(151e39fd,d5961da7,44ac5871,94081a88,666d3dda,6507404b,607d449f,1b3c005f,476bca6d,6bfc5e2b,2c183794,563d35ac,aa8d38bd,ec3846b0,22831bda,38fa28fe) +,S(b46d2d52,b764f922,7ead0399,c391a9db,1737c9ab,35394951,5a57c76c,c3c05c59,8aeb78db,db1e52bb,a8030a3f,b9f57f6,644332be,6d0ad41c,34b7fbd3,13c6eccf) +,S(a89e77d,30c66dba,a27a2dfd,5af0684f,f6ccc84e,49b8d98,f402a88b,20e5bf7,af45b2da,cffcc49d,4f6db574,29f13971,c74f5321,4dd4af49,2bc7ae5f,10abe1ec) +,S(8d774c5b,eaa0cc57,7479873f,9bf5ff6c,808afa4c,6fa6f2be,88b53841,4cd088c5,6b9461a6,600ae1ac,4e617149,73fa8b48,74dd7cc,9f331eb6,e15bfcc3,2e26eb63) +,S(34ecc029,105f5e19,d6c2471e,eae5b671,cd55f2c1,bfba7dc8,46787c92,ba7de2a3,13e3cd9a,db98a6b2,433dba08,ec7d40c9,c2467878,f6f4bcd0,ce60397,67aca327) +,S(41b10298,6889f83e,e89d4f8,fa50898b,c9bbf650,2d153c36,85064c9b,f3dc3c43,559f5bf4,fb827bc,dd068d3,cdb14d6c,ace08a47,c30e3fc7,8972ceb8,9f88c21f) +,S(4a77505,79ae33e4,55228533,b8856da2,b14f70a8,d13ac2f4,f6bdc5eb,4f5c9aba,d365922e,3a487635,3ee1b02b,511c7926,e5c5edfd,aac153e2,686ce4df,b623ed2f) +,S(173af9bc,efacadf6,c107748f,278adc1b,d42174e6,8fe06d9d,f84fe278,70eda280,7b120d62,2463b94a,57303cfb,2c477f95,49d41a66,d6ee7c2a,4c652284,b8535faa) +,S(f0fa5cfd,ba53a5ba,df707983,134c3459,5ba232b5,7fb67a94,5c5c0f25,a0539be9,ccbc91a9,c0a2efd2,3bffec87,cadd16dd,f4292aef,a59b3d31,6e9c7082,742edb6d) +,S(a5df803f,751c4846,10799c60,db405439,9b1d5bfc,c99fb316,fe884468,e57ab77b,27f8f706,a2f08ff3,249f8b62,ac0d59b6,31fe52fa,7ab08ad5,2d09ff2c,4138dcd4) +,S(d165fa7e,d61c251e,a93e8f16,c9291b09,1f258720,fd303a3d,c573131b,d98628cb,cc0dee9,f01f0dce,aba94461,1e48f9c5,282a7480,eded0794,81d0b8c,a9819a73) +,S(87703371,46a8694e,2bb5cb10,76ffcd94,309c9c8c,be6e8cf6,5a77f4ca,4d31efb1,ee64af6a,5569a205,2cd98c10,871b2ba0,6addae3b,3cec463f,6002d86f,b16e5e9) +,S(1c7e4ec7,c090906,3d98f786,dc22db53,da4d258d,6e75cbae,30d4b99e,f4ca47d4,d2001df7,3297e6ec,c0aec17,e72cfa6f,5951e2bc,f03e4aa5,5f329c77,47cd92d8) +,S(d485ec0a,1a0abc6a,69f308d4,c7f8b8bd,fff5ac6f,ad4ae4ee,271a87ce,973b58fb,68f51764,ee705265,3e2f7d7b,7415847c,3856e3e,1a7f4932,6fbfc9c6,5976cd48) +,S(ae5ab510,48215ea2,3be55d93,4e0dce0b,ff88f09d,10c8953e,390b79f2,da26e43f,9f80d71,36a5da61,7f90d0c8,a6d9aecc,5cf88abf,6bbc2181,5f8320a7,2fa8929f) +,S(cb879f42,4613487c,24aa73a7,36f211ea,96541877,33fd7091,40a824ae,7641a708,d46a4ad5,7f607301,f61648b6,e99891d9,ccc41af1,af29a66b,b894575a,a6b3d5a2) +,S(1e8d6ac8,ec0b543d,1e0aea66,7f35b556,87e30be0,72841fc9,3f599c81,4a750d7e,8965853e,6519ae5d,c523cb52,720b004f,ad2f03e7,aa3e0413,bc68efcc,c0617f85) +,S(dd8e5b0f,be63df6f,5c20e447,778f923,2e1b2c22,4d28cfda,b2c672c6,66d05f8c,d8b75f77,f955219b,d4d95e65,35d5cb0d,23c2a1d1,671b9416,2da9c4c9,b2d4a94a) +,S(78ac44e9,938bf51a,691132e,93ec3a42,22be3185,35209054,a76b87c6,645e0252,c0f66cf0,3c20dd,d136d1f1,cc00eb17,efdf2a4e,72d373a3,99c20da8,8342299d) +,S(d53110b9,5034e916,d904cd15,1170761d,4f3492ad,9e257265,3ef37739,df9bb035,c091177d,796d199e,5c05abeb,29d0df1e,e5ceb93,d272e6d,d254b6d9,a6dd35d8) +,S(868b2732,3debb9aa,60942498,3be71d0b,451ea44b,64c22225,2af3d63c,3eb512b,8951dd34,39774c8d,89cf4b4c,485889e3,df2503a,102ae568,c63fa74d,23ee659f) +,S(672de7f2,34e96153,d83da7fe,3e199099,52ee988d,961620ac,b8c6b4c3,520fc50d,ab02a8b5,2a2d9306,8a83a0dd,23ff882f,b1052f22,72a0ad11,cea13c63,4efa33a2) +,S(4887f473,af8189d9,c46ae22f,c86ba6e0,f03c81a1,490de032,72b07937,b63a7527,a2e7a713,e1e6691a,ce09dc0f,a86c92b0,a0097899,7fbf26d3,98581731,a577a21d) +,S(f97ddd77,38bb419d,ec051fcf,a93753ff,e3dfa122,6cf02e1f,23afb376,7a121440,2fa9c241,f747fcda,dd09139,437eafc8,94e7a47c,ec8a7ffa,1e054ce9,21d73243) +,S(ebe75f9b,2c92af9f,11eefb04,3456f6ef,f616d1ec,b616a9e9,9e7f8960,4f1d62fe,40b5cf37,b06cfb0f,294da3c0,f756c867,af06449f,e2a916c8,a327117e,9a47f74b) +,S(10d376b1,1f0138b3,238deefa,b57dc84,7ef66849,14e9f120,1a9619c6,b1715a13,a216f393,1f398b67,d68a2888,1d5a31f6,e5e0da82,e2b5060,4c6f6322,9cd21748) +,S(69e26679,f103a1f9,8a9a4d88,c973874e,db7c82ca,99e48554,37284445,b55517b,cab62aa5,13b41a9c,56ea455b,6a880b95,9d400bba,74e7a203,7b60ccb0,4a89b8c8) +,S(3acf827d,81e39933,64e99fa5,63f89305,dcc60b62,44ecc0a6,b101c6f6,ecd5bdab,77e3bd28,40a99c45,30ab7767,4d8ed17f,f57a4f1a,4ab91732,7059114c,c06fadbf) +,S(2e5125bf,9e263d80,7a220063,434f928,d9a4907f,68601eb9,829041e1,a7b89bc4,9810022a,d7d3c333,d7c022d9,d0779b9b,5807226c,9fd41e65,c3fc8e1a,a7a0b51f) +,S(7b68da4a,197f6bdf,56948023,d2baf10c,9449d6b0,b18addc,49385125,e62506bf,85a92b7a,190aec87,bdcb9df8,42e93917,9254ae6f,b45e6764,32e410ef,4b28434b) +,S(60d4b53,9a29562e,8fab8ad7,3b699550,3fe7d6c1,e2ba1465,f05c92b1,61dc829f,2c2ad439,8fc7c836,5b2efcf2,1e4d0156,1a753f5e,d945ef2,bb1a3394,203d07eb) +,S(5a3a1bd,30250a40,d22aed42,71892b88,3c03ea0a,baba458,6b65cc50,4c79b107,9bf3bf42,df1637cb,80c1fef2,cb9bfaef,dcbff761,89cf9f5e,d00f0f4a,e551e31b) +,S(9b9d93b5,6b70fc67,5476c6a,6913e173,11ed1ade,6ea7b810,b9c90977,a8f3707,ae01a481,7a9ce6ef,5584a48b,fb96a9c5,21d5bb7e,2bf73cb4,b71f4dfe,aa7da298) +,S(44bdd82,86a3a4d7,6ecad7f1,ef66022c,6a49b916,3d7a8ccd,e54bb017,814d2f70,26d345a0,52034ce8,b4382905,f60f8885,e20afd4c,54df6d6c,ccd1c2e2,5d06adaa) +,S(8de8205f,e44946c8,582dcbe7,152dfe3a,7eb85e7,bc070282,3c972727,54463869,1dd97d78,e12a92f0,cc2145ee,db4ef561,af21d3db,f3cb123,ce0bb582,6791a30b) +,S(c36a713e,3d88ae25,f79b4add,90c6a724,77be7d9e,a62ca0ab,2d5a800d,41f9321f,2df57da8,6cf17f7d,63ebb85e,e7570869,cf90b462,e76af48b,641c07c9,45a638f6) +,S(1ce37a88,f25b8b81,941db8a6,13a7d952,c2cf868f,e979bc0d,5f35410d,147207a8,7fab8cb5,f6611850,e541dce2,315a7833,3999041,5c18ab0a,718dfe32,e0ebe992) +,S(e489744b,dbb11e61,a7e827ca,ad18ba55,41f4c02a,b50b75a0,353f4a2d,f504d575,6abad3b5,3ad97e6d,a301ff7c,7931f37e,55246ab4,c7560,363ff214,2cb9a398) +,S(cb4ec0aa,c1cddaf1,c7a67507,5cad6762,cf8ffce7,6a06f76a,38bb88c4,5181ca3d,7f15e726,5092287c,d2ccf3c5,dfcda0c1,8c63f2ad,21c06a2b,469bba5a,d9e4ff36) +,S(aee1c436,6b923847,40127dc4,150c6dcc,ea62864f,394415ed,9a39d539,adda44e6,2496d2da,97990e6f,5fb1526d,b93e92e7,8a011c33,61218d,c3d3c56d,952f8666) +,S(a099ce61,d950fa1f,19abc21a,79c74021,472c46ab,d8f67798,34df0429,ba785491,c4dc483d,6d61ab1d,7578ee0d,7548e0b4,295891a1,39774c22,7d073232,f2f3ecfb) +,S(6c57db5f,b194dde1,b8cc9686,fdb65fd4,eaf8aba1,84434344,7a770ddc,9055e429,2dfb48f1,58663b3,6a7747e8,4b5a9001,163ea20e,f07649f7,1d7a21b9,b11995e2) +,S(f6efa15f,20b2e91b,cd7323a6,51e5d7b7,a8b323df,924c616f,21a7d6e0,e34d3c76,ed48a439,2bb4d596,58e75757,95a0a4d2,7443415d,7662a535,a6246d64,3804fc1e) +,S(e7983476,a900be4,e9dfed94,42f575e6,4d9af362,1e874a99,576e06e5,d31485f8,9d21080a,8b0534f,6b2dfff8,9eb8172b,cb5388ff,d910fdfa,405ead29,9df779be) +,S(88ffff0d,7b415f76,8c515d80,9c607949,b469b07f,3978caff,1ba64e,ce198ba1,6816bd9,ab0e773c,38b73787,2881e96b,8eaf381,b155b205,79b24a39,eb9e0fad) +,S(e5fd2c3c,a1c85b03,3d93a3c1,261a5c1e,c4adb72a,7700405e,7c0bb108,d8fec1fe,97bdee17,50801ab9,a96e3fd4,ec4860,e59034e5,c02f9168,79b1e654,5a65fd39) +,S(fb010f18,146336ff,30dee37,b25aa384,9588b83a,bf943125,613d2c72,c2f5b3c4,4b0ff7e,7a6f15c4,d377e92e,73c8935b,d2d9f7b3,5be91cec,da891f61,c7631bbb) +,S(9be574b2,c28b1460,a1d67d94,43e4bb85,c46a6bcd,a957499a,179cc8f9,7ed33c2a,16aada1a,367def6e,d4f34409,e0ff5d41,f3854494,6a764040,e1109574,109bb310) +,S(358e97b7,6799ae09,b80b6797,90e34630,3d61fd4e,71733d6b,3c90fdee,2ad44bf1,3eeb5209,175677af,c16a3869,5ff7d3a5,e9704201,b802ec33,50c6c2ba,c0ff4144) +,S(2ed930c1,c941b209,b6e7cf3e,83971e70,9e36bed7,a4d3884a,faaf013d,5b589b59,ff6a5a5,e601377b,9dd974bc,4fe71e36,403f2cc,90b16834,b1beb6a0,98553d2e) +,S(d86110c0,6e8b20a2,e6da1930,fbda70a0,d8c022e3,e68255f7,262168f3,2bd58986,34dd600f,9b7157cb,2ec545e5,c50b3f95,2f422b21,4afe255,b7337815,1f3dc048) +,S(4e7ffdde,305ea002,f7dfadbe,e2da926e,6d2c2714,596fb052,7eddfe92,81d4fefd,fb4dc1e9,476cb2d1,3bef4548,9ab7ca86,6ccbdd71,4cfc937d,bf024f12,ff04eaef) +,S(6ba04fe,47c4c99f,849fbd68,7e1ca6f6,3e00179,3ba3a08f,86acf668,df0afdfd,dad78b7a,9d34c738,31112801,91476b92,b8eff31f,fcaa6d,a0704244,5fe32e37) +,S(bda2c2c4,86029d0d,b804f1ea,e9215150,34276a88,179154dd,d5d9f176,cd7f50ba,a70291fa,47b98bf1,fecd9aa5,b53ca619,41d62c9e,c8b02ea7,91c79482,afc8f1c3) +,S(99801a16,4da92a6b,de6ec7a2,69c2798c,b421af01,5ec24c8f,1b090169,18980a5,3af209c7,de27a683,56f242e3,8805a368,66cf7780,60c2806d,76f9eb06,35c18358) +,S(67fcf955,dba84390,638517f9,5792d09b,64c056aa,ba98acf9,d63c2bbd,df5f021f,96f96080,b5758233,ee15e8c4,7ffdc3ae,bbc752a9,d7697e1c,3ec3d479,4f912d2b) +,S(c15990a0,50c2946a,e4518cf6,84ac9cae,1022a29a,bd88f8c2,c8e724c2,89b954c6,611bc99c,e4ad5b6e,3ac932cd,e2e70e0b,a3690ec,758bdead,5edb3b0f,b5b95d56) +,S(c5261ad4,f6d03a0b,c15ace20,aaf95bf,94d9ab5a,95a45d90,6ce7a622,3b09d59c,5fd1b7a3,b22732c7,4b5dc1ca,fac99882,467bd80,53f2f606,ca5af8fe,6d741448) +,S(b0bec3f4,eae81fd7,2b70027,72a49acf,46a5c50f,48358df5,e174eea3,c0da88a4,13a4cf63,fca873d6,cf1b8c35,ce25f439,4d74a5d2,f2fa2799,d4c3bb98,8b50ab67) +,S(e3d32fa8,9218a38a,c503780b,dfe23dcc,e6a7138,d84668b3,f71b3fdf,891b6256,246ebe20,7ab7c536,8f7c9795,9e7aa1fe,69909d50,f4b24263,c32b8bea,7674b85b) +,S(ebf3bd9c,1920f625,4c32467b,7c1c138d,3ac6a4c2,b185557f,6eeffd7b,2aae0d63,58ed82e1,25fa2241,2bc4397e,73009692,af1d5feb,f640a422,f52e5cb6,42d4bccf) +,S(d062e72b,3dc76d03,5827786d,a9cbcb03,b710ea61,2eac883d,b7f50df3,fc6f7175,cc56b076,dc3cf1b9,e544858c,1a31723,33ba9848,a8c463f2,abf2c6d0,dae14a6a) +,S(97444eb2,32b09240,fc596530,374da035,f5ebd37e,6c74b51c,8158eab7,8ae30f89,fa06190f,d2072bad,b9144f72,db18819,ba76399e,d171d4bb,1293c20d,63d70391) +,S(3e1ffac8,15f68300,4714f302,1ed39460,d5e4d63f,6fdc445f,12d8470f,b273c242,86f0839f,8610c4cc,6ae85d54,b951441e,efb700e9,9ce54aa9,fb6c7988,a8494c25) +,S(deef1e7c,12e498e8,6542acf2,3782ece5,2a02b13e,3b4e71cf,e39e79ba,541d2679,e039a94,f4b169fe,a13ed182,f9e541e5,2b117536,d90024e6,9f3bcc7c,988714cb) +,S(69ed1a62,b3de5c,c5785b27,c7926e52,4ca1527,9f8a00eb,b5e1c247,a6c8265,9c5fce7a,84b79a67,9f3030cf,a179a682,cc22c464,11ffc8b1,ceb885ab,4753de36) +,S(cdb36419,5c3be45a,bc9f58e,e5a499a6,ef58ff2d,296ff989,9fa987c6,b753f82c,34a1a6fb,7a6b6c95,2a604340,d2c30c15,69c46123,e5cc5318,833f3a3f,bd622e47) +,S(c5749ad9,f4583689,f2ed313f,dc35fe8,acb6a85e,dd0498c5,ddcd4842,fa21c555,f22ea47,ba61044b,54ef967e,c8c82167,3d14d710,334784f6,a7b46d48,19f99cf6) +,S(fc86862f,b2fac126,e4341121,c82a9e14,d7a48b9c,988b8458,300dc3a,ba10dffb,42339dc,e304641,f814327b,ca5a611f,3638d610,85826d70,3d94c76b,8297f6f9) +,S(66dd174e,446ae0c6,3ded267a,faa20ba5,62131459,5576d10a,1e44ef18,69e36ca9,d93a449f,6d3fef4e,435f6fa6,3191b625,b883c303,1dd8b380,777b556e,acee9df0) +,S(736a80e9,15b39c21,5e5efbe8,ed6f8fff,7aa826f8,5c940110,3c7ce372,86d952c6,4a9e17d8,9066ecb2,95447058,4dc58c36,c84b3d9a,30ea45cc,e62454fc,ae13e0ba) +,S(7b747f80,f4a324af,e6042edb,d8682d3,1b8fe12e,19936844,b44c3e73,f6b7075e,c2684490,56e7633d,2add97c9,75079594,b9c0d038,cb864331,aebddd3e,18830199) +,S(dfd54b47,e4d2abe1,c40e0a1c,2916469a,7e8a61b3,bd95a1ea,8b5fa182,903d8339,c705b4a6,761d2ca,49f87fa9,ebb4b39,35c3c633,4f6b7643,417c8a29,95515fa9) +,S(992a5fca,521a86e3,dce0ccc5,fd1b2ca3,656f44c1,f4967931,8ccb7a28,7879213d,ca2836c0,496c75b6,4c56c13,641d0402,b64cb2c7,617c9fbb,d820245a,9321217) +,S(38e59093,acc26364,de9cc5f4,de398799,54774d68,ed4b0283,2bde2a26,cfcd23bd,953c21c3,14ad2e0d,511d3f05,678358f9,eec2fa48,d6b24c9,6ed4efd5,da3b3719) +,S(889ea31a,5969b77a,c41c0a39,cc5d006f,6ff14f22,a62a5f26,d736ebcc,f5df8239,4c2fa5d9,c2f0316f,dcd6462b,e7571f4,92aaee96,c3c888e5,21cfabcf,78d2c3f4) +,S(f70e24a1,6807d5a1,8e15fdd,f31301e8,bd210ed,5d3d614d,82eec8b0,326d7b6e,dcf95677,b29a5ae6,15e2e7b6,c370cf69,ccec71e8,9569f0b0,5715963e,da6a34a1) +,S(d6eb7425,9c17d292,e1b1a4ea,624e6876,a78aa774,2b14e94,d3fd1b43,562e35e3,c05013d1,4056ea0f,e5f1fca4,b0c74b5f,776a8564,ac973973,c929707b,b3f078bb) +,S(df7cc5f2,69faf306,6050409a,6a03cdeb,8f33d1d7,4e30658e,e871de09,59701b16,3d8a28f5,f604c765,5f28dcf,b2f3407e,6a63db14,6b879fb5,bc785e65,59319147) +,S(e6bfa4b5,85f6df59,7840119b,6a31d0e,4ad800ea,239bbbbf,a8a1a36c,f8c6b5ba,312b5d55,35402ae1,37f9a02c,aba859a0,22a8ba00,88a2305e,4afe8283,98844dba) +,S(3c762a8b,acb68a13,2e3e022b,35634b3c,1907cdbb,261ff639,9520352d,fd94b3af,2ad358b9,65555cf1,e0027e3a,b93d46c5,b104324e,2c62f9b2,5f70930e,bf49f385) +,S(b4d94e26,9955b213,8025e5a5,bc5ea171,c2ea6d04,9ab60184,88f47f7b,f6a6d3f5,197b20a8,81e9280d,96b5b4d6,ceb3fa20,38a28654,63e76ff,d0b5b401,8b59bd1c) +,S(406e616d,907a0f72,12acdf3f,d5341a79,9b482697,88976615,388064c9,74cd8ed1,72730d26,b2698e29,7f62fd98,2a3955c,da516ebd,642d6619,2d33a915,ba39d0ac) +,S(1762d974,37705ae8,37603446,c8c11568,c7878053,f25baf9e,e3bd23f9,5babdaf1,1db8fe6c,77f41656,1fa4df40,23662039,66a8f891,e5467b55,3a2593a5,1ba796ba) +,S(f5fbeece,aa5386c4,d75c92a9,88ce6bf0,f957a0ed,3f0caff9,42f1f29c,7ad765ee,fa45a4e5,85ccc691,88426bd2,8ae561d,a2f59d10,e4bd63b0,4f8a53ef,1cc3ab28) +,S(7e0d92d0,d12bb892,b87b8bc0,993b4422,cd1e9d95,144602c3,a2aa3c06,bc945ecd,601b1019,746bbd4,ba9bf00b,4ffaccd0,b1bf885f,57ec49d2,9fc91744,8aa70761) +,S(64cfeaa1,4d4e0cda,db6b6a2d,9e2c2820,d2fa7817,43d7b2c2,8211b1fa,e17ee0db,f0b199a6,1a1856b3,360f519a,a6056900,7a0ee623,69e0aece,ea64f0d0,8cf568f8) +,S(c90f70e6,99ba1a75,86073eb4,5540b3e0,80bc78a4,e811069e,f861b048,5f11c88b,7a8257ca,cdc7538a,13b55285,939c614c,14d6a94f,70509900,44b286d6,7eb84e14) +,S(3edbcf0e,b4e5e640,f40afec9,ad370813,426b5488,3090f8d4,b72b1680,6694f42a,ede4512c,c4baf93d,f05c14c9,cb17b1c1,fec46052,c7087306,2214a05d,60743c80) +,S(77adf15b,ae449ae2,f63d7c44,3c56cf9d,64d43840,5154473a,5948cc79,160b64d0,a1bf9aaf,7804cae2,c377f98e,86b75e90,6886d293,21aed43c,77e330dc,df9113d0) +,S(350632ea,23e39962,3daa53d6,5a916f31,b2ca02bb,5bca1f58,35b85165,b430398c,41931339,48282550,bfa1cef9,94c28873,ee0165e2,fa970d04,e51f8ee2,b87916be) +,S(3d6aae93,5ee4ab6d,46de768a,d6938703,262e9fdb,13bade31,d38fbd0,9fade000,62674fcc,6eaddef7,b971e964,5a688e32,14186605,615982ed,a09de4ba,13eaab23) +,S(856e564,a155a29d,c1b739e6,309fbbe8,5ea4debf,f12a9249,347a5435,af674993,a0e6deeb,3777ceb4,6017ee63,caeda231,e616fda3,c105f0cd,6174a3b3,dea84256) +,S(95f8b405,c1ca86fe,d56727ea,eecbcce7,32d2c521,415eff95,b3cb42dc,5230cc7f,c8c66b1f,2637df4e,2a5375e,3a2e5e4a,a89404c,810322ce,c4b2bd1c,91163ccf) +,S(b51de213,54aa18ed,6ea589fa,e3b92d90,732dad07,6c80b842,579d53bd,2089e0e0,8f069737,1baca2db,208f7db4,c43a85fe,d816eca4,e35fe95b,780e2c4,a3f1b948) +,S(e36ac0b2,c4b73783,7a96b372,b8d0779f,41605e99,2a0013a5,3c8eb4eb,d5e2a988,d41ea6e,ef06bd62,7c2acd2f,645acd8a,75e353c2,448aba53,452787b6,670eedd7) +,S(4d08e46b,a3e812b0,67071dc8,b76cbbb2,4effce48,cf4a4c5b,ff4e15af,71c51635,fcbf2dd0,ba055845,b70cc545,5a8658f,39ef2176,9802fbda,2d3ab98,ba914c3d) +,S(31421774,5b1a6b68,918e8afa,4e8dda05,6094a6cb,6024c3e0,c10fdd99,245d7501,7ea6ac19,1c0db139,eafdc961,e8f91f1d,79269f69,cce275f7,abe9598c,2916fbd5) +,S(79bb2dbd,f9afbc9c,f605ad45,4768cad3,14d48241,724b301,7b5abd51,6f8dd4f9,d1c9dce0,30fe1a72,5d100c07,d842a78d,beb689a,606a933,ca865051,49007b8c) +,S(112abf7c,1d5d66d0,cbcbf42,1874bcb8,88d3b3b7,5c2cf36b,1399fc04,17525731,b3d3ee4a,f44b5372,8d0957c5,e388094c,34fe0f5d,c51abfc5,76c1e18a,c920dabb) +,S(f6257a3a,60365e63,471fe77f,893a8ae3,174d30a1,9aa495cf,251812d4,c5040400,293ef8f3,91804cdb,34845404,996a24a9,5554fd24,185ec85c,3a27ef8e,c89938cf) +,S(ee7c8ee8,bec75bae,db32c6f4,3b3b7a04,2c10e903,de9e7d21,5ca08135,d59a682e,e68a0137,398fb186,d5168e64,4421ac4b,30a635fd,c15527f3,e56b21b7,c0008ff6) +,S(e292a4c0,fd63ec7c,c661ee1b,25c9d5c7,dd805a97,fc6e64ce,5d3d18ad,ddc92aa8,ede226,7fa6fe51,1d4a510f,e7f5e14d,8fa29fc8,b77d61ea,2e140739,29644745) +,S(cf914327,85a05d41,2ad06146,6df68649,d3b8e0f6,86a83a70,d32c2fdc,978d8124,f74c1223,7b0899dd,53afaad1,b9b06704,c61c6e97,81456e86,ea55e65,96b0b13d) +,S(88e58d21,95376fcf,b3f0c44c,b013f2ba,3379ba55,2ceca46c,38ed48f1,263fe894,f2f38177,bc673cbd,70853432,6ece1090,5863ad84,1140c59a,2a782af6,ccbaa71a) +,S(90ada18b,df0c62d9,dfa35e14,d1eab9b3,48d09579,f4e82cb3,65dad65b,62ba53c5,2c4e704b,fc9a9b97,7d330d92,602c677a,4a06040,74517775,d441d0ce,6c5e5e2f) +,S(3bdc1eca,a939c8b8,c164e5f3,1a02a6dc,9d2712a4,6c30f54f,e2159934,d492d1e5,e53acd26,28f6e646,edb5f53a,d9e1639e,43b4ee9d,b61a3545,a9874609,9b3c1e94) +,S(54a206cc,48c7d529,c8bd2ca3,91501ca2,1b58f5ed,921ba11a,95eadfab,3a720bf,83f4f820,b9a07ae2,8c5e137b,c9ec4f0c,31c875a4,b055b0bc,8de38f74,c54c06fd) +,S(2754b021,13885a9a,f44cacd5,2999a03b,d16c90e,4e3a7a67,cb3426df,f6abe546,f8969b1e,e955f8e2,dc0d3090,167c0116,66beaa68,35bbb1dd,e721c4cf,768ef566) +,S(ae438153,4cf07fc9,1dd14a40,68b3cfe3,aa6e608a,bf1d1c1e,13ac54ee,e0759165,e7807ae7,395fd072,6f77d7dc,956c58a0,69243b63,32bad336,72d2eebd,662fb99) +,S(cb9d28c5,357165dd,fe18010e,4263e626,65fd6315,60ec8126,c7b60603,6ec067a1,86879039,f3264d1e,511fa8e2,4298c9ed,6f1e7625,897666ad,4db9a43,3338f5c4) +,S(763534f5,52317771,551524ae,7ce33579,41da627f,db77d4e1,a9cf72a5,f182d276,9fd8ae13,b1706cce,ad190066,9b1d2f46,8c177970,b5173f76,55efee54,ec5cd8de) +,S(3990fb8b,39d529d0,b2d38432,3c60ffdd,3b32f7c,278aca88,f49f1523,fa16ded5,e43c977f,427570b5,b238edd0,77db9df8,b1b82e20,b73b8d56,84a2ee37,886edb83) +,S(6b76502a,22280e31,d0b6375d,6dffef0a,94dad7bf,e640a406,2ad696fc,2744cbf6,e667122c,b6861cfc,97fc4ed0,e6193883,c79a896c,79e31603,a67063d2,421845a) +,S(7ac03be7,2ff15233,5ec9c349,98e77ff7,79e5f348,a49fda4a,e52a69cc,6b02c02a,74a9e36f,af0ef72d,b493617e,9474b112,593de375,c845c8dc,c1028ee7,9fd17599) +,S(31a83e18,c03c570f,31c3ecbe,bb787aad,6492cdc2,3e07d3a4,43b56ca2,51c0888f,3cbddf10,9bf08e81,830dfa49,d4d3cf95,224b7a4e,fd6d9997,9dceb64a,a8d7e440) +,S(ec13f2e8,53935ae0,705c2644,d1512bfb,8ea4adaa,d45a454e,f761dc68,c7ace561,54139641,97e2f5c5,5b4b7f5c,5267ea7a,bf36b01d,cbd62765,ff56322,c107f321) +,S(ce8e23cc,aa38e603,70defdd9,37803f02,18ae79a7,3679c363,4dab15a,bd46004a,1ddcf92,92ea77c8,4a1346a,a5f79f13,26c9092f,14ce1992,dfc24bf1,a2da35d5) +,S(77d80689,f7cd8585,fc03cb20,14d02425,3b547962,a282beff,17aee956,88292ee2,466283f6,429248fe,301e18ef,61a89784,47142fd7,fcc5c496,36dca83e,ae8e9f03) +,S(6eed61a1,4e7e7ea5,54a4e43a,61fa7eb8,b8e7fd0d,52de9ad8,e4e9b130,78178a5f,2cb4d228,90af9cb,a3c050ab,12a3dd53,1f1c6d6a,e4393449,219d86e2,6465bbab) +,S(10cb3737,a7916d84,12c955d4,32d1ad46,d8c7a60a,e44936ba,f62b2a26,b698e4f9,35499a5d,11e356ad,fc5960d5,8d6842e8,ea0615f5,e8bf39c1,8c217cc6,7a1faa97) +,S(e866ac84,6040f92b,c52d298a,6ae110da,e16bc797,d6958858,1f63c00f,6cc68211,257803b9,ef7bb5ac,59c6b59d,32a49d53,64c6659a,cb0482e,a9d57530,4e244f90) +,S(5e75ce15,aeb91c2c,e4ce06a2,decf02a1,db85ef5a,a43c42b6,179d4a,2eb4e404,a08d537e,529a6654,a785969c,8d8b0b86,e3a76f91,d9b72d92,992f8215,1b61bd1f) +,S(fa80c52a,12afecf4,7a5b48fd,60fa35b5,ffd122d,8616ca07,1c1271a9,bfe2c104,74487acc,dbe2e60e,e054643c,37cd624b,3dbbc3d3,4aaa6009,9c97cfe4,b3d69e81) +,S(ddec1720,dca13ec0,2eee97cb,445044e8,d6b049f5,694ce5a,efa664d9,d89b6dc,122b68af,feed4f56,b72a4a7e,e20a7f8a,8daa9883,9a797857,8dac0851,1b843872) +,S(85116566,57b70a1a,96c5da0e,fa5d3025,49fcd00d,104a4989,442ff143,a08b5a59,2c96bdcc,430c6c28,9d54806c,9c17961a,8121b10c,5168cfed,a0dc8edc,9f4f551) +,S(7de80b36,89b9dfe9,de2f4fd3,4dbcedba,9ad39842,f105f580,d8d5f6f7,e1eb3e58,43d20653,db727ee6,155998cd,f7bb70b0,9be15c7c,a04593b1,398b4586,baa3c417) +,S(e66179d,366fa7af,a982c480,9578d469,91731ce8,c669d8e6,bdc399c2,a2484b1a,9371d856,28bfb10e,d07c3390,b9f08222,98793229,ca2cf2ee,75d53d2d,e8144441) +,S(1d435048,d7b8bfa9,6df91fa8,f8f6d1ce,913bce85,c2c7a1ad,cc199afa,5da012f1,4e389f26,4f36b2c9,296934ad,5f567eed,30f3179d,6538ef70,f4205219,2c3eac82) +,S(5866c91b,619f53ee,3256772f,56191a35,23696c7e,2b5140a2,89f36c11,c1cdfca7,67090999,33ade86e,3a5d384c,840fc584,2a85087,10085798,913c41b0,e2dc1737) +,S(1e06d768,20c95907,405fc2c6,bd75e1c2,fb9c4d0e,4cee156,94e1a4d7,65a77a01,4aea359f,bd26d7a6,1b1e9f75,5544363,27eea590,fd2d5eb8,87ece7c,41759674) +,S(ee415cb8,5e1ef106,28c149bb,2d2f9e1b,a8083367,60a7b56a,f122cf4c,9b59e5c9,f52aeac6,e2fb8a7e,ca5a629f,b431736a,eec16a06,c1a4b876,94ad8bed,bad88ae0) +,S(42da5368,b60f85c0,9f52c3c,9aa82e66,4868ee37,4b1851e,d37ba6a3,fb717e6d,71f65b16,a3937a5e,b535da,ec530798,d1c91c88,722fadb6,580510bc,5f27ed65) +,S(10bf9254,6300aa51,bb08f849,5acf4e53,b1eb4e57,1328fef8,304189e9,7acb81e5,9b519bf3,482c9516,132388c6,dabced4d,971d033c,52bb5607,6c788a37,a9eb49cb) +,S(2f6456be,5c2c184a,1dbdde7c,2dff16ac,8f504a9b,d86de1a7,d9d3c1b2,bb0688d8,6bcdc62d,4e6184ef,1fd39720,55da6e7d,45cca6d9,4d15c052,8ddfa715,4aa68336) +,S(e68e8fb9,beec6d15,207e7017,c3574e34,102fd7f6,5e5f18f1,e533487e,5bb2fae5,13624e45,da0b6edb,df4ae938,82148590,63094aac,1b25d534,f80ca56c,814a944c) +,S(7d314f19,4b776d00,b946825d,f634f763,e0b5aba9,b1fb0424,833301bc,ab1e94ab,80d402d6,a8dca19e,709b9e23,4dfda4f3,9f9f758c,928c1b9d,842b2d5d,aea3fa54) +,S(fd78e68e,5b5b9522,14b35d5f,a0951f4c,4d5df056,28c5bafb,9c6144e5,c2c33a49,49c62b9,aa91e5f4,be13a209,7f941c9d,cefbb300,eeed9fc4,a12c1e45,37f4535b) +,S(e751f61a,11e0b68b,205fd306,9f4abab0,b2576131,3ac3ffc4,eb4c525b,f2b28f6d,aafd8f6,2fe20722,b180ba67,f9c3b6e8,8ab2b96,956d603c,868a8867,c09ddba5) +,S(6db64d2e,281e6734,a8908de8,554dfa93,d7811f01,2852a306,9e6ed59e,c09a4823,1c1276a9,1de36164,309d83a2,d9fdd003,d889612c,6026817a,cda97f8b,d2cec77a) +,S(4de91b17,fc227eca,652f8d15,8cf0c696,c6902df2,b44a02ea,d05dfd68,e408a17e,130fd485,d59456b1,48458cba,922e9ce7,79968340,d7e5267,b2f288d9,6df924ae) +,S(356ceb61,8c57db92,931a305,4537ddbf,8bad8cb0,c13f447c,1c3fa485,5c0ba01b,6f52d242,ec189e41,d8ca010,cdd645a0,8889206a,4df81651,1e820e0a,74bbaa7) +,S(595d8d68,1ccf61b0,456ec03c,53cc5a93,85e553b5,36033f8,ec56c575,db49cce3,773b50cf,f0718e6a,6a269cd9,65b5001d,f5613238,3e279bc8,fb937580,a76ad035) +,S(b076afb7,234e8fd4,4107caee,8d31338a,5122d785,4707605c,2e5dae93,2e6c935b,a18e661,1921080a,84a74df6,15006847,981b552a,4c3021fc,93967c64,b19d629f) +,S(834a4467,bada612e,2705b0ae,19fc9f1c,b80e6e9f,7c4c01e,5899fba0,1f60cfe9,9215b4e5,f8194645,813f00a8,58f77324,e28522de,16e93e80,93197310,38ed9af8) +,S(d00093b1,ba6eea04,c08df30c,90b2f7de,6e13b42,c645b01b,127003b,5642aae0,87739294,746ec547,4497a951,c26ca6e9,12ae4638,1d0e2804,5363fe26,de088434) +,S(66a33bcc,71bb2f0b,ea36e5d0,f1446ce5,f3d44a9c,b715e6ba,ed00cf70,4c4ce1d1,27d0f5b1,a40fb2f1,e1f9440b,c1c15731,50efa23d,b8997928,cbdc0e03,2824a6bf) +,S(ac65226c,dc40fb92,a9632724,20983b87,9e1a7615,fcbde26,ac9754ab,408211f0,ae633790,687f1c02,52115aff,3a7d5c92,9064bbff,616b5eb0,87d5c1ee,57cf8d3f) +,S(a4b98213,78cb0e23,d46b1359,43b354da,3825e27a,76f33334,147a3ee7,52a81913,2786a9fc,3701a6e7,caf07030,3bb382b2,ce6d7c52,42496130,13382f59,92fec4e5) +,S(6f58e6ad,e4af1dcf,633d3f35,8ac86836,cf0968a,49c2e85f,2434ffb4,2475a34f,70e30dbc,dd567c8d,a6aa970d,3131009a,f5297a36,f80750be,6462f1e8,336db9ee) +,S(9bc7ace7,d55fcd7e,e67a0484,7d0d6902,f053288,ef17b3c2,64072dc0,ae0e94d9,7f57fd70,93f3d09e,53a82818,e5ca4cc1,6b46f73d,2c00e50c,698d5963,8a8f3f7) +,S(248195de,ab1ad52d,fe739d17,a03ab762,927e058b,ae666f2a,4f7e220,3173bb3d,1b1914d,3dc9f584,51ac3346,d05f033a,b793277b,dd80262e,d2ffc219,6965b96) +,S(f6008de0,21c5cd46,d9d811d4,4070a7d6,46105a55,2a68c389,a11161ce,9baaae2d,962cd254,e5b0d724,5ddf7114,32ab2800,16f5583a,b8fa02a8,61b7c3db,eed77d91) +,S(f6dce5a3,a919eab8,c1d850b,4643dd3b,96e5c7e2,a1923b58,202543e5,4ece5b40,c1b88f2a,b3d516e4,7d289ecb,b16b9bb7,4082a6c0,8ccafee1,21abf691,73734c08) +,S(23fd6281,b4958fb3,b94ac9cf,851561ca,415cc979,7ed619bd,15192ca7,7ad39a71,fac12f70,ee38f19,b2dbbd5c,3cfe02e1,b69bbde8,7a45f8d0,bdfc909b,640622b0) +,S(da3a5c2d,7cdeffda,1ff2085f,fcda0ded,eb40bd40,3591395,e4b20b0a,25a1aa8e,e0d90d58,a6cf6038,10bf2891,d51da508,77d3aaad,5ccc971d,944ea960,c943e3be) +,S(22113f6b,8015b2f5,bbff28c2,cd5dc253,c495cc62,88361c27,3e788aa3,58a94554,7b6f7bac,2db4f198,20ca6e90,bab75cd0,983536bb,80051e6b,7da589ee,dd2ae962) +,S(3b59d8f,d59a2e6,89c9d1c8,a4e2515e,73317cf7,41e38108,eaad880a,e3417c72,bb96d412,50614b50,8903c28e,b5d39ed5,b4e735f2,ea10bfa,1265aba7,f21ded5) +,S(3407e5a2,4831b572,abc0eeaf,c587b20e,9339dd05,ebf395d5,378cb151,e0dfe661,49214182,78e4d0be,31cd4e1b,9b0458b7,7e028840,4a0745f0,40960dff,b9022926) +,S(9540e180,47717f7e,f6ce71a8,31368919,e4acbfb6,18c1582d,cb4093f7,caad2601,6fe0f64c,3f0aec37,5b36758a,7f65c7b8,e9329f62,3309900,efdd58f0,7bcf244) +,S(bd02f758,513ef045,af72344,f5d790cc,1c549a23,147a2743,b8c0cb30,891af3a1,3c605d60,13a560d0,d792c5a7,6ae2f739,7631ea13,7347864,4c6bbae6,dde96079) +,S(43b10d72,cf1ba39b,17abb149,884fd00e,56525f61,594f9654,48683c16,88f3e69a,cbce7dc6,1bf71def,95bbf6f2,fb03751b,8a0c6350,9eb9ead3,713366d,8cb71407) +,S(32900344,9ad58567,6ba2607d,c873a8f0,80d9c0eb,2f7314cd,9746008f,3c569642,8c6560c6,9a037d5a,3b2e740c,270ff543,54abb60e,b32ce5cb,4d18ecf8,1ab7ef60) +,S(a1495bc1,91188644,4991e097,5334c9eb,cc277640,f568a7b3,1350e4b7,222b885a,c5a1c341,67cbed14,7f28f794,d9d2867a,9019948e,56f986a0,e69a0d6d,6ae7dd1d) +,S(4640f683,f180cf5a,4929c2ab,5169de2,85861055,67c7c2a3,3db2d01b,c3c8d726,7d6ced33,7e752ab5,c87fb211,903c3a91,e5b0ee78,361a43,b716754f,d0daad8) +,S(91b3f9d2,7e989062,ced571ec,f373ff66,f8775213,95e625db,7d1b5168,e895473a,d7efd35f,56ffd001,bcf0191e,2692e832,99d0715a,edc1a19,2b74d8f3,c0b23b80) +,S(437cb866,aedcc0d5,8d89a41f,95cf5dd0,b355f244,7885843f,c163d54,a3839db3,9d644bce,31992f2f,302c5daf,67e42b78,74bf3f9a,a944e936,aef17203,5ac2bddf) +,S(be8cd347,572e0e46,5c745c83,26799611,a5ebb1ad,3ae74bf,474a6386,6f4a3705,6d39457f,c1010837,eac6bd41,bd4a245e,10bb39f1,77c5633b,92bda8a2,c50a3dd0) +,S(f40a76f2,130d31a8,c560795b,54fa119b,153a9a75,bfe7dd28,cc00ca35,2d258331,f92558a4,69f1055e,251c8814,7a94dd08,44bb2048,31f2d33f,d95858bf,dffd695) +,S(17e01809,b94d294f,c4438a92,6f90a295,5a9ed96f,a201df62,b96b19d1,7e837876,c9506f35,8efcf330,35603c30,880d5625,db15175c,486f3c5,841a14e8,8e5f4e72) +,S(7dbc457d,7ad4752f,8d57a09e,d4e8cf02,6c8b009c,bc29afe5,ce2ee745,61630da9,fea9908b,ca852ed8,3c1b44da,207e8bc9,221b8dbc,7e8b61ba,ab8d29b4,14eb29de) +,S(89fe19a7,6fe2208b,ee4de72,249a503b,88c63e22,71794bcb,9484fd11,1df7902d,8a4853de,c3cd9e1a,713e46eb,e771ee97,b88defe4,7e1106d,88ccd713,4e3a6779) +,S(3753a13f,531da9e3,5569ba37,7db76dcf,b43b5483,1e65fd50,a6ea560e,e70f3eb2,ace8aec3,867312f4,f095b4e0,d08ad314,2005cae8,b1369223,d1301e29,8e51d4c8) +,S(30d76056,384beb45,4c54b4bc,fcdcfe0b,1c1ad5b0,5e693384,8794846e,c93a144f,f79b9c96,8eee678d,b899f349,412bf193,5da9cd,c0ccdec8,2e45ac5e,58f3d3f) +,S(d9864700,7c74872b,40ec273c,59aa149f,8059a1fa,95e5b47e,378ec515,841eb2fe,782a39eb,ea47da96,9361a337,c5e2cc0e,49d43dc,6c6f9da6,6952f347,ca51845d) +,S(40d665ec,53720f95,42ffaf3c,30e8602b,53c52123,e9dd3b91,6a2e9099,8d534fb2,cc420012,490afedb,d840a466,bc27f66d,526a965a,ee653886,8cee46a0,6a58ee30) +,S(f31507a5,516719bb,f07438a8,7b6d6d93,d02a88ca,c18fcec3,9190f358,bab3647c,dbec3898,f884cb2,aedfcdff,402ca4ec,8c8f8727,485060c6,8da0d2e4,edb46eec) +,S(62573f5f,75db743e,7939137b,6b5e1d0d,41468ed6,28d2b76f,ca26ed2d,22532c03,9a4da6c0,d7966d8b,138497df,af25b0cf,2d14215f,ff039065,d42897f0,df33be40) +,S(d0887924,f15c5069,1d7ace01,7eeda410,e8d0a10e,f6091a4a,7b5f368a,42c54416,b2fdc385,527d34f7,a434c1a4,1f9fddc5,add3b1e6,82b63838,da0ecd91,16571c4) +,S(f7585b4b,5f3318b2,2307f34d,3e4bcedb,d4b91eb,180be664,4d031bbe,9b5e3d90,b6fd16dd,49993bd6,4d05398b,9ba7714e,798d3ffe,95393231,395c03da,b3ccc819) +,S(c9cdc99c,198ca8e4,458e5473,3e5cc0c8,100fb0b2,2dc6f07e,b1e99d2f,6a4cdc42,c4c21204,67198733,a845efda,33a5c1b7,67cd8ad3,47a16b6d,4a6f5ac,995dd680) +,S(1a054d1,5c4fcf45,384ead78,e1260eda,dee9e907,84021c99,179a9fc1,c7a3ac49,50ac5d54,d4fad7d1,5fbff150,d70a3ce2,9825e79e,206f4279,f1030d29,2de89a07) +,S(b0796a05,52245e66,56b3ce51,99864d40,aed71b62,3b9d55b0,d99163de,7a8e3455,a061fa65,63a84b15,1ef666d,9f99abcb,f1611e3f,6e26dae2,6be7ac56,c0f2768d) +,S(66fcf877,6ea02717,aca92a3b,5c19387e,72658125,f6e20da0,7595e376,804c3738,9fc66cf2,3195dcdd,7a72225d,96a8c5fd,1c84287d,2189e414,d0deb6b6,76e67518) +,S(3c7caf6e,d3da8c0a,effd832c,f5356114,55646982,3a62dabf,2ccb3de3,452ac96c,e44ca4ee,bb290527,4cf8f554,40c92ad9,6055fe3e,1bb344ab,ace5c4f,80e3b984) +,S(edf616b1,1e7fd6c5,96df3fa,77bfbde,f3f82e7f,93e5addc,53c83933,844e4b73,879982bb,b89ac019,e83f5c,dac1fcf4,fb918e2f,53a5ec35,45be03e1,89bfe152) +,S(7e9af2ac,b3044985,181de5aa,9908259e,77207ab,933c7915,9dcd7aaa,90527eec,e4cc83d9,d29778a5,eb83936d,97bad637,370e74a4,3254eca7,65d0a449,106ee3a5) +,S(32dad830,3bfb015b,6aa6759b,c2e8d4bc,2a9e356d,92d97286,c92dbcf4,53591aaa,ee27e7fa,b36a2450,f04962f2,ee60f9bb,68a1147c,9ecabaf7,e0981564,c1164fd7) +,S(d20720f5,73f1db82,c1a2dc61,d3684d7b,a3943186,cd513a5a,9eecd59a,c9225a82,3b29448e,cac88f13,7dcddeb9,36f02724,6819c6c3,3f03a2f8,cc40a6e6,f8704570) +,S(3a732b5f,5dd6dc77,1d215321,f8cd223d,22f2195,9d45c708,5b000129,94d5f03b,3fc75d80,ea7a0663,c90cc7e8,8a6096f1,b3a8c9c6,9849ea50,f1fd5c94,7928cfc7) +,S(201961f5,412beebb,7e190d75,70977b50,230810bc,b3b69e3a,dfb5e259,d811333c,eaa3f681,3816ca15,dfb9aebc,8888b578,e592825,82dd1b47,ea50cad4,f59b0101) +,S(cb184267,70cd3b68,151f7d82,cf7a12c,dae332,868663ab,4546c119,fe26f4ad,6c395538,eb09c00a,3e973def,8272eed4,27a3ca9b,a77d1a0e,c4e206f8,74591a40) +,S(2c13d3ca,9ddbe3b4,2920f0ed,28622260,2cbc0493,e5156655,30b53da4,7ae3ba59,f7d9f8f0,c58510b2,db28e723,6d9af034,658599dc,fae14274,efbff408,dfd18613) +,S(3ae7b7a3,86ae6c41,90b3a0e1,e5f1a7ce,4fffc405,84f05043,93e716a4,3ec83d41,643043a8,55603964,c46e3ba0,999c73e6,ab34703d,9dcdf9de,1743db7,71591bd9) +,S(b5eea0d4,ac4d0a9d,e37fb1d9,6825233d,a00f26be,86c0b640,f0fb34c3,465bc441,9cb5b93a,56d35b2f,2d921c4f,15b4ce0f,fbb9240d,30754ace,f16b3019,54732e1c) +,S(dc049453,9b8d5200,d513eeed,edc2afdf,e76146db,358a86b4,12ae9e28,e8501e3,6f6f2d25,b331a4b3,686adc14,c26814,96004900,34524b53,8418fe5b,9776a3bd) +,S(821e937d,a6fae1b8,3b6aeb4c,f5315bcf,77b2fb07,d0081889,80478765,cea7f398,41405d00,33224982,2acfc2e7,87be9658,7baca419,14b70315,c1a57843,3f85aa21) +,S(818bdf95,f55a8e51,c0d08d83,29574c28,1ae3397c,f6ac5224,4d82ea53,8f465c60,bfd41438,46dbbf6e,3fc442c9,7a66e8b5,32445d39,fae8c473,51e0ee9,9a9a53f2) +,S(e3bb3262,36533fd7,84fc6d9,84cc5590,2b03a19b,6c956665,322c0bb6,264b6d72,bbe4844e,2be51197,d8d84c75,ab83cee7,c9ed7dff,51eac125,1161e09c,c1078aae) +,S(36e3355b,5f946199,b33dad7f,b42d1245,4cf8126c,568c4be2,cb2abe4a,b83decd2,fbd5d87a,8c012064,3ed3441e,ec686237,1759ccdb,4a7f564e,c2ff9584,ab824833) +,S(bd7fc193,1b06bd7b,c6c274ea,73d33e71,1e1e57f1,e6bf7a8b,6452d979,777aaccc,95b84e3,d8c41224,c74451c5,ec8a23ca,35436798,c2f34ad1,b1cd095,2f0170ce) +,S(b82cb5d5,2e026caf,bc075968,6e1c6c18,206231e4,f25c956c,b3a05690,8c72034a,6417cb0e,f1a18ad5,e1a2a5c6,945f3b38,b0522ac8,70188640,80a0f33e,2796b042) +,S(47d70d51,e97fad87,fa0b1c10,43246c0b,32108c36,734c90ec,9de5a2cb,c6227682,6d5a2cdf,e916fe8e,8b45d5fe,14ce650b,79a3cc9c,e4f99aae,2e9c449a,a79a4a08) +,S(13fa7ee2,5ea49c25,200b40e6,b9232eca,16dc6840,4f76b43f,510c8a12,d520dead,2722287e,35c9f98c,6041cb15,845d515c,870f5943,74a1ebd7,36f973e7,5e6dc30d) +,S(c1350b7b,2a4e73bb,90d36674,771d5537,1fa647ff,c490726a,3748e7d2,e72fa7a,2370f4c9,403ba7,8e950274,bc1f87a7,bc80c1fe,7618169d,5c9bc5c4,81e1badf) +,S(dfe512c6,f884588c,80c1ea7e,1da4b3db,ab8d4beb,60749f40,9402d583,ac793e05,b52da5f0,333b904f,678dcd37,a890b79,e985dbfa,b501e61c,89930678,5a0bdf09) +,S(88da191,2face14,e6f5ded2,30d303fc,867f9b26,d85c2299,bfac1a23,9757b34f,4236025e,f82eab9a,f1fd3c12,42a73cb7,fa305e5c,ef6ad5ab,ea62cb8a,4d74bbc8) +,S(b7a82133,7cad0eb6,c1de7b3c,8aff8798,8ee936c,921a7dee,1434156c,c6505abe,d03b693b,4fbce189,a552a66c,3ef4586,35454006,308c40ed,c7dbbc29,75361b7f) +,S(44971116,c14d80b2,f0f88829,fa1fac44,ac44124,11ac6e92,fb898e72,a0aa7ed3,9171395b,3cac83ba,18e9a0a0,34fec786,986534d,667b0521,801638ec,e19343f9) +,S(95f0aa61,8bd8573c,81b2dc3c,aa16b577,6ee636a5,a8f9c963,b8a45370,7f35a618,7f2300b3,90006ec7,37365423,2b488d72,edf5192a,a1d5afc9,4bc95a18,edf5532f) +,S(e1bd29e8,778a30e7,d9d91da2,3db2da23,bc2e8d08,d5cd170e,8e753e3e,917b728b,592894f2,114c11d5,f04dd5fa,6b341cb8,29c58e1d,a7adb51a,19d881be,39f87eee) +,S(f6110619,208f64ea,8f0e8164,1ffe9f32,8e706427,87dcf8c9,28ca8629,adb99e7e,cff63452,a596744a,75c5e8a6,badc4937,e6f2c860,39196251,30784499,733651a4) +,S(4a3f7c9f,1ba0f01f,d6d42aa4,284e4481,ed1433c9,3248da63,76f25b62,d2d2348b,dcd4c18b,2ee4e447,3515c727,1467e6b3,86b6e640,834598e1,4ce3f679,47f5c2b3) +,S(50fc4d78,3964a68,b26689df,34d996cb,6f229f2a,ed017a98,4e027407,5fd730a,7ccd6964,c6c5ab52,5d31db1b,ccefc3e2,7a0882b5,8586a955,b76c754,9698a7c6) +,S(1bdc6b52,e92022,229cb15a,6436d601,26c640da,bd9697d8,bd0c49bf,606ce554,1ddb0cbd,e7b0816e,b65d7ea3,98da0744,b3ff390b,d2e13cbb,f8fe85eb,8f3d2059) +,S(62dac912,48f29712,c3126524,90db807a,af92d3fb,36117f6a,f5c7f5f,de317000,b3bc4dd8,97a2fcf7,483c0015,f793810,29bf6f01,7be37530,18b55e35,4250ee0d) +,S(ea552caf,1d0810ff,24eb5089,31b57573,d8eca976,2b314f9f,38301b04,ff5e2193,68181368,108c4fab,7c58bcdb,5bac3a3e,31eb1b3b,837c7ead,e691b56d,e24aa832) +,S(7d6132a0,9e2c0af4,9e3359de,a750551d,7addad6,8bdc602f,e65af48b,bc1127a9,5bf6234c,903e5f72,45b46187,9d780ffd,72aef438,c0b65c7c,d0b5fc2f,8ad29d16) +,S(916d0d6a,3d08a94c,604c34ae,8c930edb,5ad57532,4dd5fadf,7a4841b2,775c475d,e3cd9b7f,79572001,a1ad9c19,2921ede7,64b12210,4d4d8796,a435eb13,d883d391) +,S(804128a3,d982b50d,203135a9,c59449ec,c43ebb35,b2bf5266,6b710975,a3847524,bcebda70,4364414,dc269d2,6214968b,95ad5bce,239ca9be,f10fa1bc,d6f31757) +,S(850314b3,4898b572,5898dd9e,f39196f3,cabf4026,8248844b,1c3d2f55,a3346f2a,eb8d17e0,3c9f7fde,29276d95,c20b657f,af2173e3,7c620a0f,d2ea7ab5,f4706b33) +,S(fd879539,8c0ee90b,89aa731,a4ab60b7,be0375fb,59932879,7bd73390,58d7aa8,3fd62aa8,35d10f6f,8bf3338b,b48bbc33,8f235cb0,6bcccbe7,56716129,abe8159e) +,S(51536953,12e7c4db,bb18ecbc,26c51224,8f841792,e557e879,8eda9db2,c9840357,175d3e7f,92ddce9e,5595fc26,725f2c09,fc322b2a,251fc323,ad3c6f08,44badaca) +,S(8783f2c5,f7325f73,e5941ec3,5f91449d,558e31f,28af335b,2fde477,86aa2808,dc602736,ccef3e41,60b100a5,ef99c6e5,c59734c3,42b545e6,21d9b03,daf0030c) +,S(c871ab31,4afd8d5a,a58a0cc1,a5eb49aa,f25b4b3b,6e0ffcf5,38851576,27c0726c,d06b7e2b,f44d36aa,fcf653df,a675bbe1,36a18938,60864df1,fbc9e604,5a3707fc) +,S(40efd5c2,1a9807bc,b34a44,71066619,a2bba48f,c306293a,ab59d9c4,b30e9b23,85cf348,4df34dad,2f7aaee7,b8a6f585,4de1314c,215f6f0f,e5a38e61,f3decad1) +,S(7feb5d9,844798a0,2413cae7,cd791e6f,54250fb8,12f998ed,e0ea6eb1,435986e,d90ca7e,8e800e6f,fd0ea027,b8a379b3,9030a03c,7b111d68,465d2a05,99dd358d) +,S(1b2da7e6,f9fa412c,ec873512,7328f1e9,ea77501,5741a284,12018290,76a79b2d,9fe58682,ba3f6ee0,c7b73933,d14ce656,e3fe49dc,ec7a5643,efa07a3f,1a4f26dc) +,S(d7fc1f3f,7a6bcaed,1a84e8e5,7127a6f6,37d935a4,35500e21,47e8fe03,d3b06066,29938603,d89fb118,14d33850,451f5c1e,bc5a5943,70c2d8f0,1d9bed34,f0b2e940) +,S(45352264,1cd962bf,35d8ab65,3d8d6c97,75782706,1454a2ba,3d957152,e177ee5f,de5005a4,3989b6c0,cee0a71,b534137f,b946b262,bfe353c9,6a217c06,c23826b9) +,S(91733546,dedbbc4,c7c32af7,760e0a4b,c2bdf82a,73e2a91c,2d70afb1,100b84ab,e60a6ca6,f2a5b12a,307cab41,8793b7c8,b7ecbaf5,18166c61,acee16ea,83071a3e) +,S(26bcacdb,bd4cabe3,e7adc5b9,27465ac9,616725b7,dce240e6,37117a5d,80a9ffb,172208e7,6603837e,4a9cfeea,22bc6002,a5cb8f1,36d73dd7,ce30d010,acc05db5) +,S(18b520f3,e997b5d5,46a1d81,ad95c52e,7841f14e,11e9d677,de918fae,7bd408d6,51b0cc1d,4c6ec5ba,e6c587d0,d6489663,dcf74bbc,d93c4839,6e4203a9,caae57e8) +,S(e25c2492,b7b25c37,cb88da91,cd76021f,de8511cd,27188b0f,d4bb4fe3,dd845e8a,244facfc,a7dfe65d,6e1d1d84,9bec4e4d,17af0d6d,2611333d,b8b7498f,96c88bd6) +,S(97e572bd,300d9649,b9de3c8a,b02d4ce3,bfbe4ba2,68844329,85971951,5c34a535,324a34a9,39004c24,b2e55e66,83577259,6c9cb2f,84378bd7,e77806eb,75e77070) +,S(4d31f4b9,42526f1e,769bcf70,85f39523,60475a0c,3f8d0a4b,c1fd6a07,a4765fda,27815d6f,3b083965,8fcbb540,925986d2,bc6d1fed,d1c254e2,9580f413,99afa899) +,S(7344c521,23968b7f,7ee12500,e9efa4c3,859a72fb,cb1cc9d7,af91e6b3,b5bbe152,4794848b,1541a965,b7527533,a6d43398,d619df34,2608021,a26bf9a8,76e0e4f7) +,S(1d099181,8da474dc,38e08fc6,d97ac823,be34f4a9,81adee58,806f68cc,ffe1ce9,f5449d7,c69816bb,6f04b32e,69e46771,c7910f3d,77cee6e2,af75c293,119f729d) +,S(84607e2f,ab205637,4b708486,51e84966,9c386eb7,c6855a1a,837c8fb8,5da8e7c3,975b5227,26e4625d,cc5c55ee,22dc667f,1fff7c4e,417cb4b1,45bcb3a4,53180ac3) +,S(3d2ad8dc,11a9103b,2f03b3b6,24d93114,83f4faee,c4b9bc22,f4f8f559,16bae70c,b4f79cd7,27d433f3,72735afd,64ef4da7,de9ac35f,98b3b6fe,5de956a5,ba93f9c0) +,S(2ad5f6ad,c7fe8540,8b9bf547,a564727f,374e9194,460f6037,ee299f83,e842c883,f613f0b0,8e306fa9,fbf39919,e3040d16,ede4dc6f,9d45ce42,e63f4b02,70832f9) +,S(ca92aa9b,e8893819,e49fc29c,dc98a42f,e23084d1,fcc37d19,3e9c638c,db0f2f93,462a5ee3,2bcdca5e,c6bf6819,32ded511,12ca847f,7e110405,a893b011,874a66a2) +,S(4e435dd7,ce2783f1,5bbded75,e832665,e4b4cb00,b50e2a69,d986d2b6,d3d893af,cddec0e7,1615f7f5,769cf2d,ee649723,1218fd34,91a07fa1,fe619f2,26673042) +,S(b1d936c3,fa1fea01,e3e28332,51f3790e,1e0f0038,58656e8,af53a72,118cbd6b,183b67ca,8039f372,d04b685e,c515466e,8ca1fdc3,7b2ae8c1,ebc5fb02,9c0ced9a) +,S(77282290,d994b6db,10b06247,1b86caab,e4524850,22a1e63a,682f92a1,ae65019c,feff37f,1fee0cb5,569db439,a7697327,1a2e4254,a9125ce6,cd94fbae,110f6363) +,S(acd0184f,18bb7c72,f7b6ac5a,7ba3f617,c40e159b,a3dea242,ed8e6c23,ad89dc82,3ab71793,fdf23305,aaebfb52,982a2603,e56d7b3a,5430585b,557d3406,42fddfba) +,S(933e3401,91e41c37,69b60410,fc0ac56a,e5bb44a2,413921b3,d25a52a7,14015cf4,ad3aa53c,76c106db,6187f4ab,755d077d,c6d878c7,64181565,77bd5d3b,affad12d) +,S(6e02abec,969eb027,bcea0303,6648fe60,da6a7c67,d1e4df3f,a34c1225,36de6fa1,c0283bd0,9fb2bc2b,19bf5086,f1eb5c6a,a7dfa258,64c73647,8a6cf0cf,c5ed5c14) +,S(2b86559e,82e5ea58,423163f4,448327f4,2429f1e3,14097621,667cf1d4,f0af1ab3,35bcfa55,9e2a71aa,4ea25edf,f9e1c59e,2274ade5,9354e22a,9cff37e9,31258107) +,S(1c02f45e,5787587b,9d68df04,66df67c9,552301d1,3b32f50b,8c9a2d5b,c826606,5f5de968,b39e9263,c1624aa8,811a4391,35150e,f8167698,c381388b,18a232f7) +,S(d0a65374,7fdd0c5a,68c55060,dd4ed734,34956730,1997d07e,d333b5a8,79894eed,272fe0be,bb192ec8,9f2f64fb,43f3a3,cceff7d2,cf92cbf4,4ddd8fd7,b104b85f) +,S(bb48b81e,e0dffe05,b6b8d05,5e1d2e5,37481eb8,2ce2bb81,cfdfbcef,bca5c6de,717b99e9,63d59e1d,66c0737b,9843231c,9c5e1bfb,26820215,78e8e01f,9e5a3fa8) +,S(23901c4c,625d77bb,1d390891,6befda04,522c698d,3c4e82c5,227c3975,3d7bc3fc,2434bb8d,98ebf9bc,42459328,464c4a7b,b26f258,2d454209,af66edb7,e84effbf) +,S(2a150d7a,961b5c28,434cf4de,ab9bdd3c,d019f667,67437158,c0f3fc38,54de70ab,e0d4756,9cec0eff,b155d7e7,37ee49d9,863374b2,4c6f4ac,876a80f3,7fdf7461) +,S(d42bd53b,1de9e41d,6e5ada81,3b86370f,ec1cfe1e,cc8ace39,edeccdf4,e16e7111,e3d4de0e,e5cb0d3,e3dcfed5,a09dcc,28c9f1ec,969d70cc,ffbd34fd,d0ceca5c) +,S(2a865f60,413764f0,d50adde6,4825eed1,134c6875,d1712396,938cd8ff,784b743d,4b628cf4,8e2a56b0,2142bf67,8829a388,929a0c0,5784426c,ed114f21,ca1dfade) +,S(2189b2e2,e88054d9,c71c2321,8cd229f8,a0165a15,650d1557,3eccc450,671817fe,6b9e0fbc,f9b9c354,644dd8df,3ec14217,66fb6783,5c698a1f,d598d074,aae79d19) +,S(e619a8d8,d63ce9ec,7f11cde4,1cfd33e9,62884fd7,471a4e67,9b9fd1c6,8537fefd,d819f364,5438c886,915f46b,40fb5c6d,6932077d,6f9726d8,86b9ddc4,d5a552a0) +,S(80c0df21,91bd2fa,2fa21bc7,ea86e54b,ee25d9ad,43893869,1cee20a9,b5792763,b27d7eed,198a695b,405cc3a,9204242e,45833ab,3b9feaea,f81db33f,938dde53) +,S(cb3926e1,eaee7f44,6f2eb390,64d4ced3,cf8bfda7,9c54a25f,6894be15,61c2d02e,35d9e098,6612e1c6,fbc2dcf3,54022f34,5b2220de,139d1ca7,5dbaabe,46c69160) +,S(82e82221,5dae0056,917680ba,a3233d29,23a2a0d0,68939d9d,2e2fe013,9aa2a8b8,f28975c9,b27352f3,f6a2972e,ef33eaf8,5d0d0a4c,673e3495,afb71869,e768bcfe) +,S(6b48f2d2,d756c7f1,77d5d33,cf62e419,b32fe0e7,352e84d4,d3056571,fd837e52,d4741717,3212dad1,b476b8fb,7ace774d,fdd545fd,6f99ba1e,b701018d,f762ad14) +,S(6cc8e1cf,ca1a026d,c1db0d97,46029b6e,b9895d7,61f66549,4f29cafc,1243b56,429b0dfb,ca05d077,d4d87022,d5ab333f,d9068170,5e246fbb,6861bd07,7e85b500) +,S(fe3de551,3fc157b6,e5bfbe45,d88f9339,71ff5ad3,c436ca5f,21794899,33f01e9,a50a9cfd,8aee1546,c422c5e1,494dd42a,db36bf43,89bac501,38211c21,803be0db) +,S(25140d46,a9453d6c,9370c901,6cb163a5,a5faf371,50152526,b01c7454,56b995de,6e00dcdd,82ee197a,3d5ca028,86fd7fee,56319f7a,925a39b3,becba6b4,c806cc11) +,S(4b9c4d2f,bbd879a7,de69e578,a2ffc7c8,8a0c700,f27f2e7d,cb8e0c2,ba3654f2,4c876a6d,7778cd81,bb02c450,5867d448,c78e9884,c72af037,55a66d7b,848e248e) +,S(2c11d305,3eb4b59d,8e8319bc,2b62624d,b97244a4,47326f24,6b83e959,5797c2f8,41e096b6,a1d2082b,c852782c,74a02cea,55dc09c,64b9d19,1265c1ed,9c306340) +,S(9a515c26,394d56b8,77c2b70e,ba1745df,9322810e,63c379ac,1c2320bc,48baa2f7,5ccafbd5,d1dc3d86,4a7ac805,adab05bb,5eb27f8f,dfabfb1f,708b2e8d,42e097e6) +,S(791a6bbc,91321ca3,6e017798,1a611cc0,db9d2600,34d2c26f,5f6fa5c2,ef7a5fcb,4cc5b203,db4459a1,f396cb31,acbaf9ca,18446f1c,cfded245,a3b32100,38417ba4) +,S(ad40b691,d3eb6ee0,e22e6d7e,1e0eafff,7afffe6f,2e0e3b75,103001f2,3a9653ec,ff7b436,47c2e09e,84f90910,2b2abe7c,2d38dc2b,151abd2,4f92d214,5607cdb0) +,S(52eeb361,405a56a1,331e3fa4,b854156e,7c403961,240f6003,135df1fa,8f3e475d,128e88f9,1f089e60,61d3df85,fcb2c50a,b0e67ec3,a7e5b3c7,ef1f53a4,5d5336c3) +,S(fe1a5ff5,162731b9,7b4423d,ad1b5169,5401920a,6b1a07c3,6ae9a25,ec3fbd18,22076aaf,ee720a1d,96e0987a,c7bb8756,b04a6b25,ddf5823e,e2f93ac9,e54c85f9) +,S(4c64f48c,fa628f72,b2897c28,4411684f,c0795753,60b8633a,188a89eb,e7fe1ea0,2eeabfd7,1b976ac2,acff49fb,bd029ef1,a42344c5,489334fd,393cc4a9,c305b4d2) +,S(44cbb9b1,7ec26b5e,3489c17d,1da0776d,539d2efe,d9317987,b86225e8,77b4eef4,f5c58a8,6ef02531,bcffcd80,ce788f5c,e43f5ad0,37e940bc,70d8411d,27c32673) +,S(2a5a456a,99eeea58,761c8802,7a86a310,63cdc681,b4ba0e2d,e5bce690,db8f3e84,7c3a47de,ce538330,49e998b3,4415c46a,2ac5c633,1a074e8a,8b4cdcc2,c6d1770e) +,S(566c0ddf,ebb82deb,bc867f76,e2fc5ce4,71249a9d,1b659237,2bfbf9ed,4eb6bf04,76989cd0,e0ffe1fb,a5992e71,50272abe,8a483f5c,6bff023f,3e5e1265,3598bc80) +,S(6fe42288,6d5d8232,4b229084,b1b2924c,b6c45080,3aa095ba,aeb2dd14,7b6def9f,b3b394b3,fc2682be,6e8c1e5a,ef2c87ce,eebe8d98,31aa60d9,ead74896,d7d9a38) +,S(35b45332,b65703f0,4feeaccc,39e04e1,72e58555,db94f04b,1899d835,9abf996b,6643809e,ae897680,5e37891d,3a241094,27ad6dc5,48429a07,64e2e12f,e89c2d29) +,S(17288055,5c0c5643,bd740b89,bbe47949,58ddb0e0,786cbc80,84d64ff7,838930da,f60cda88,7f85da2,3fa719f1,29aab43b,8b9a1578,53f91836,3fee5bd4,fcd16a2d) +,S(76eb57a6,c2d7bb45,d6faee14,4ba7c798,2d8ab2f0,5240862,aaf32c22,77dbc985,ef7cd7e4,d10ab9ce,4551c6ad,18a3ac6a,bc851768,18fe0805,f1c6107a,5c8c291e) +,S(1e5b38b5,81ad0859,454370f5,2f636726,5987e7b3,981af60f,a987c4c0,2440040b,d9817e99,89af200b,da690446,df5d8681,92808bee,91ba077b,400e8de2,712c2ade) +,S(ee17e98e,12a9efb7,c27aee78,15da31e2,af0d3294,40e7dbe1,9783caa0,2bef5709,a78346df,4d7dded6,9146931b,f1ce1b6f,1aae295,50a877ad,5f2dd0e6,adb43e42) +,S(bd574652,1eec6a76,7c2a14fb,15c85590,f7a19e12,342d09ec,67dd98e1,7739a81e,f26894f2,b8eca34,493bf871,dd6a133f,efbf1ab7,687a15fc,336d885c,6f5698a9) +,S(63852cb9,391a1ee0,23947718,b27c51a,8f9a5d0f,2f707f2,d0afd728,6596aaed,9d7c8c01,102abe28,43a7cff5,a1b15fa8,b56f50ed,1a034963,2e867007,e946d639) +,S(6c3fb2c2,d49c1c29,4eff674,158a3971,f65010ce,93f53614,ac9e0497,e31c296a,ffccd06b,98cb8021,589e833c,9c8b3b38,67850545,7e8dcf2e,775bbc71,47243707) +,S(3c29a60,103f7f0d,6f9a186e,48ac242e,46a525e2,380c4430,609f26d,6c3559bd,9381e8a8,7b4bdf9b,361acf28,cbe43e1f,a8fb073,ae2d1d09,6df7813f,bbdcfe22) +,S(bb76e94f,6f9ceffc,53ee4b3b,e27d99f2,d02eac69,8a4865f,9cb0293,a68c5eff,9ae48507,33f5984f,21726a37,c6ed7a79,e832af6,83afa20c,ee5d117f,63ab7472) +,S(422fcd5e,d2774d45,6d5f6312,c716582b,c142fcd1,342b71a3,d729643a,d022b492,b6d75412,aa9d6ff8,9be3a0b0,17384764,35ad4408,b544b53,acb5ba63,119b6bc1) +,S(328db4a7,9fff0037,c79aedeb,e8895e37,75b1e6b0,4d0a7a32,e2fcabe3,29c60dcb,40a2fab2,622ca3f6,39711923,812d8687,9d92b15e,ceaf5855,a970cf32,854b8970) +,S(4269bd58,abcd5e92,c62b0895,1c5ae948,efa1c96f,39ad3601,5e28d809,74da818f,1d1412ac,57ae762a,c3918ee5,33577c29,a8e63afd,c33b69d5,e6758416,6ff87b65) +,S(6c08ab40,97320e51,f3c571d,3beb7d7e,cfb690b7,af3d449b,50bfd276,290b8830,aba73078,edbed082,2164c850,5ca4bc58,6e53b174,83675f9a,26734cb0,747320b8) +,S(f4929f5d,99d0a5a7,3d20a223,c84261c4,6a085af9,fae2fa8c,4a025489,30174c22,afc89b10,7a38c32c,a24e947a,d8efd761,cad69f7f,ce0d595d,d4cfa849,201f6178) +,S(5cf5baf8,726c125b,e1499cb5,3f33bc0,37c983e3,b03f37af,6b48f3c6,29827611,17bd2e3c,d12adb0,5502a9a3,aa418cb8,c3809868,56d00c5f,319c34e,66074a65) +,S(c4639023,b41d90eb,2b275a2d,b7ab632a,592535ff,b439491c,f0e4e692,8188904f,738e1a93,5ace46a8,fb4f6ee0,b9026314,d8c243a,8fe08f37,b23b9c11,11763de2) +,S(a21b2fc0,2a60cae4,e694f206,1bd083be,5ed681e6,53af9271,a8ef9983,5807ce92,7f80d5e5,5a684392,939d6d1d,537919c4,99e799e3,4bdbb27c,b3d79587,f08d5194) +,S(7841ddd5,80f9f3a6,e702b0f9,3e1a4158,5e2c10c8,fcf98add,2a0f6286,c5d285b9,4dabb8e6,2aef6506,392b0fa9,4e2005a5,ad03c4fa,5fb6de65,2e89b31f,6e5ed166) +,S(5d5fccd1,378e4983,8d8b05d,41f89660,1b3a7c0,58df493e,2a74b55f,d8210356,a7e7b0ad,fba08a37,6fa3cbe2,75dcfbfa,bd0629ec,e8a5830d,d6993ec5,15ccf447) +,S(7fbd50a7,360c09ff,fe55369b,fbf6be2f,70cc5965,340e0489,77e01b68,2ab6c9ea,17ff93bf,4fc95325,26caac54,89e22f4b,265f63c2,cf46ff6e,a5b1d387,98a9b72) +,S(d6c8bc1a,479ea533,e99afda5,95365a32,cb1f3a26,72b4b960,2e039494,5b379061,cbfadb4,a6039cad,67ded1e8,8513dbf4,bb1dd3e3,437c989a,1df98b31,d234975f) +,S(5753de48,683d633c,11103cc5,b1bb04e1,5a935e99,297c73f2,fe851d91,5d5ea18a,10ef5d7e,ca1580b7,31ed4fc,3cd606b9,e6af8b1e,dea8bcc9,b91d522a,af361376) +,S(fc0d0265,b6cfdd0f,6b755a8a,c87f0ad5,b5a19894,5348c719,e9593566,91a638f,c5f31483,3c166c18,8c62415c,e58297fe,157fc6e4,b8e36b16,ce28cc75,df9017a6) +,S(61570f72,5b030b63,def84933,d0d25039,cabc8853,e5185302,d3f2d3ed,2611eea3,b3edb685,379c0068,9e9f522b,a5ad9163,9df723b6,b5c3eb96,3b05e5e0,a4b8fa15) +,S(5fa72a54,36b2b7eb,c15b34a,fefbb908,acbada63,23809159,66785d12,fbb3d6e1,1c027ed3,a34e892d,4b3d56fa,7a93ac18,663e475,a16a3d2,fac0ec90,be6d9ce6) +,S(5296b2b3,9f179516,d3cb85bd,5b86a9fb,274da608,be6e95b6,c44267af,187e2371,728aa26,e5869775,9c392558,34d00992,73eb6986,5db38b3e,df87f394,31c75dbb) +,S(b145c8b4,4c3f3c77,658899f0,a5b97c4b,dc2b195c,aa56b328,e0535217,88c80298,c73d96b6,47c2e764,e36caa26,8ebfe40e,c07b1e0,947e392f,be2a9095,7dba2595) +,S(bb585531,3cd05f8f,7fc96d8b,6e5194fd,2a70ff55,e7a7c067,cfbf54bd,129d87c1,31ed0367,8d24c231,8c4295a7,90d31094,e54ca68e,47b289c8,45b2f638,64812607) +,S(c6ebab34,ab48c0aa,aa5243f,c82a90e1,9a2012ad,74c925f2,e4e22f6b,13d6e5e,8107a95f,28e11f9b,bcef4b22,c4228c0,b530cdac,1c977640,53828b8a,15fc065) +,S(92e6ec9f,83dd27e6,3be3b0bc,8ebc521e,d84219bc,177f15cf,1bc840d5,be2b551b,931aabb1,5b3479bf,994f7eeb,34871b04,81efa404,c40e063e,59aabb77,2553ac79) +,S(280280ef,424f01ec,3fff321a,61dde1c3,4e674a56,7142c8e6,643ad1d7,e2dc4d51,84710eb4,5a88503f,b1078d06,26522501,fc165ebc,ce3b90a2,925ab1be,3c9ebfc4) +,S(6326eb72,abc4017e,c3f55af7,6a50a4a8,d0074ce1,2f5c9e08,146682ea,e406d047,53dcc346,7b61d08a,204a70b8,7658e4b3,c4016c8d,b5f03004,af6b545a,60223871) +,S(6e59dc29,408efda3,1bcd7b05,276b9f8e,bd9caffc,7f22c207,61f9fd0,a281ecb8,81c60999,45a6a834,8f2bc7e8,4ee002af,ec5729dc,aeed8187,87060c68,c2763887) +,S(100b0cdb,ed05ba0a,fcfbedde,94ecb25a,5cacfb8f,bbb80fed,1a9d87ab,72e4b5d6,1ac27087,8d6764fc,ce5f036e,ea50294,cf38c4c9,1ca9c3c2,87718505,491e11b5) +,S(95865771,e313a1f8,5629585,7ab9aafc,68a124b,6ae61f1a,a7b6e9f5,fb5de6b4,1c5195a4,338bfee5,9910935a,f5fa6091,7d06a2ff,3908fecb,b3fbe30,b0b52b41) +,S(6962774c,9035ce5e,fbb8e715,9d381004,a1828d67,38082e1f,45307ea2,d1d60eae,e9c36d21,6a2acbe5,5f9f9535,bea4b38e,7b75a149,3a281e4e,11b19064,e282c036) +,S(8e0fb8c0,d2d7977a,23f19efb,aec886a7,5170cd08,6a035386,ac784b15,9fec90eb,1218a3d7,6306cd4a,b3debd20,9bf9238d,ce00984f,47b5fafc,b715e2a,655ca9d9) +,S(6e9ea5e1,127c4c60,a01cd278,ac1dc091,e768acd,41566200,47aaa32a,e9cdf5e4,bfad3214,9a299887,c74bcb20,33e01704,ace7c646,eb00dc71,fd1e0461,af05a6eb) +,S(60fd55,9198e1ce,86c401a1,d31d04a8,fec7da21,4efd01d7,f2081027,1c49206,4f234575,cf4e6150,16ad551c,2f8e7635,3718b626,70ed30c4,a4c15e9a,488e0755) +,S(d413c7fd,2c2bd34e,2ab3e871,38495543,3b5ceb32,cba0e9e5,1e0ce198,cd5ea806,b585f836,7ef44ee1,8e32dd1d,95d6f8eb,555d8e53,451e5d8d,1cfca993,b23e344d) +,S(e26a95ac,c0855b56,b702cba4,abcf2004,c7343cf4,72056bb6,161ac077,bfecf98b,36a4834e,4532fa30,eb1caa21,c1572c46,efe4f7fa,e3c370b8,3f1fc221,632f8c2f) +,S(f0541a0a,d29e3806,e2812aab,ac185a55,687e058a,eb17157,e00a1cae,5a9e3d9a,40e81917,4473fbbb,58d40f1e,ccb2444e,ca4a616d,b0efc710,8f887c09,dd04b4b6) +,S(db1112bb,394f5e1a,b315f575,e2cfb59,4b83b599,6c82365c,c2095bdb,eb7c3cb9,c53249ca,30eb726e,6dfdb792,4db693da,f9740213,d87c410c,afa3ade9,51f9f688) +,S(2ad80407,9fdb7722,c96abd1d,35e76a7d,30948c7d,7b1e62a5,ab0994fd,667103df,5289aade,9f71ef7b,dce049cd,3052f8f9,653a9b69,3876b607,7bb42d77,9829bbe) +,S(7bcd5085,eea0f429,238c23bd,bc14017a,f8dde478,9d99b2de,325503f1,fcf7e738,7338f8a,7980de0f,404764be,7fb22578,ee820c6,16044f18,ad12d4bb,4b35a2a7) +,S(85819e4b,348ef2b6,d141baaf,3297248,7f34b594,8d834249,df465fc8,29a83188,306e8693,e7e718e6,39f48a1f,7dd5d977,9da12288,ef3edc6b,74afb1a2,906f931d) +,S(8d035a4b,5905b0ef,7fd9b050,ac1c006,2c0a8d84,1ab342bd,9444d101,92ed4a79,1ede85ef,aa83c466,4ac1cc71,c2d4027f,632f7ebe,2a097d98,9278cda6,35e2e0a0) +,S(bdc84795,289c3268,628904fd,5d8ef1f1,a89587f6,652aa883,5e83c47d,c008c282,1d8342d9,e330c123,7e232067,6fec10ab,b19c0d76,744915da,9980a9a5,6459a61b) +,S(75dab97b,d9e6571c,afbd8ce5,ffef58b5,72b6d8ff,838777f9,21834b61,1079c079,d048e6d1,fe2598db,31adfa59,8a445f0f,7f97ea3f,dbf8fe92,f2aa495,ff033bdf) +,S(b2a4a872,4a6ccfaa,8b8bde86,64fef1fd,bf9d4edc,215f9f71,738885a9,af19b42a,9bec2c2e,76be8104,f2dc4ea1,3e1ec916,23baf856,a92863cb,33b2781c,35f9060d) +,S(caeb3a77,35824f9a,b24e364c,789fe66,4729fe9,d6577ab3,f9cc857a,e1c2bdaa,ad96c92e,e91cf44e,8f0480cd,106b115f,23f0a30c,fd6ab638,86ee87cb,ba5ed885) +,S(a897e41a,75e6bfb0,78c272d,ec320e70,13afb506,478d984a,b5532b04,6da0502f,136cff6d,896be55b,5da484b6,15a09e9b,13453973,79fe4157,64ac5b5f,35aab82c) +,S(a33679a2,dc5080d4,a77fee11,5de9eab6,d32e6479,bd4fa795,3e4a03e5,3242412,1840b712,9ae52592,d99ee262,a56ae597,37e2202d,2871681c,6625de82,7c57819e) +,S(3183fdb2,b5ad14cf,9e2ee00c,e23b2c42,dfbeab54,acdbf786,622a83f,4db62fd5,7501e003,2ba129c8,50c0f17d,2a16b3c8,602c5225,1bac7212,6d454cd5,fc35a92c) +,S(aa6ac020,42f80323,ca77289c,88dc702e,e354fe1c,eedc720,2b87601d,7641b00,3ef01b0f,8b396221,8c5118e3,2168a6aa,ac901e02,5610db0e,8cf2ab21,bb06995c) +,S(f952d843,386eeef2,64b1078f,d835308d,514bc162,559c8f3f,c8ab5c18,378b40c7,fab32d0e,850f4bac,9a4af6d4,7d15976f,2e6fcf3c,958a72fa,b8db1817,cbc5dedd) +,S(75b58bbe,a5a1d00b,40f2fa2f,9e2ca8c2,eb568bc1,fe5559c,7e40ab8f,a0148e67,7fd6db81,7359736d,26883e35,727f4b21,2813be05,8d5d2477,1563696c,feaaf021) +,S(504e2324,34a12a8f,a96f64e,d39a7c0d,4168bd75,1e0b6249,6b24ab05,eff49d46,3bbb93f8,3d2ee95e,2e2821be,c3d98f4e,1f2def75,b5f8ed09,6947c4a9,1c933ea7) +,S(563fe95,1482826b,38f21deb,207a30d0,21271292,8b53c790,c33080b5,c4fc14d5,9b875a5c,70ee8bac,9e6d7225,1981c9f6,c3b5bb49,c8772243,14c4b287,e990bba3) +,S(91ed3211,161cf1ee,96499e83,7baa574d,1f56b244,56fc1589,d61f4d40,dea01443,f1664cf2,578f5ff5,8d81c281,514c7f95,56bce3d2,2150db9c,6f4a4df,db73d14) +,S(27526d79,f92c2519,838e3e0,a9ebfd02,f66e857b,d49cd8ec,6deaca31,d6064be2,9e4b644c,5bf8d50c,96892f3d,6843c94,f9afb359,55fb10b8,6a2f166a,6fa17f00) +,S(3ad1833b,df1ab0,effb0dd4,d535285a,900060e0,f38555c,ffd3e7f3,392b5c07,5c37afe3,89bf6e88,b88c9a34,6ab5a0f6,2128828a,22b6f907,8f9bc6ff,ed5c311a) +,S(eeda869c,21a8911b,cf713c68,caf261d1,e7fc58b4,3bdb0fb7,e83e677a,ec3ff6d9,f58e7eb2,3a62a9ec,f7a13dd7,b6b6809f,5cf8bc2d,22af477,e002f2c2,9c44d444) +,S(c7a806e7,bfc982b9,342fd4fc,e8f34786,9509fb0c,f0f54522,98162dc8,ec5a398,ba895fb4,f9084463,3eac5226,e91a08c9,e83281db,c406ab37,fa3ffc38,421a3647) +,S(c59586d4,ecde0cfc,3a1f5744,45cea454,aff18703,720fb4b5,1cd7b0de,de79c9b3,1eefa71d,5e67d9aa,15231b20,966951e1,93ebebf7,ae54ea34,e84b7c98,7cd853ff) +,S(3b259287,5283a78c,5aaebc13,5ba13c5d,4e5a1e6c,cfa196ed,6eb7960,e7eed0be,274d3739,5757e482,1ee56c6a,f56c8acd,f58cb337,6bb5096d,2cff4e33,ebb3c1c1) +,S(d062159c,e511418f,ea6e9853,b1e8d769,96c686dd,eef71443,e994a347,3b90e239,95ca957a,b37c702d,c707a3e6,388532cf,26cd3db2,64e4e9cd,fe0aec9e,77ab27e3) +,S(12a2bd87,c4ca2337,7915bd12,3f39e88a,fd7257e9,9587d70c,a9d8fcd3,2aa7ce4b,85562f37,ac813598,cf59e427,106fe886,aa1a078,1170f14d,3968119a,9ed65e61) +,S(9214dd98,2737e4b1,585b3363,c363ef83,b40a3228,53d6c54a,f5b1bf1a,a21e43a8,dbc49c6d,abe985f,d95202b6,bb925094,8b98bbcf,71486065,9b77c447,396e8eb1) +,S(34439200,b0dd5b6c,4fe8cb57,2e26de38,3311a479,ee39ea47,221a179f,fbbc124e,b8c15197,1ea4149c,d2a77b4d,14cea316,6d70b971,a7f9ef3d,315ce741,2ad43e1c) +,S(396b4410,cb5a59ac,15fa6034,7215ac8e,4ce3490,4dd15b41,46e90679,ca3128d3,ad4eef77,94f0c541,e70fd5be,45652364,c43e91aa,34683525,36c8b1ee,c061cba8) +,S(8ee1b02e,3ddb0913,dc781279,6316fde2,4489c98a,4e4c3cfa,c84b4350,34d53d65,9a4686,a5241a7a,cd4295b4,f1c9f094,3f8991a2,b7edeea8,bc4e9c4e,47956cfb) +,S(78f4da51,26b42e21,1d69c640,4e128c71,cd08fb67,efac0157,3bf128c6,73bbf6e2,b3836f1a,e397d7fd,c88d2089,6731fe04,6a46b2e0,b617117b,161e1e7b,3a2958e6) +,S(ff5c1378,c8a233e0,5edeed70,e23bb9e5,a5eb65a8,4b37c6c4,7c0a4952,e00169b8,a7275aab,c73eaa15,22328118,68de268f,189d3adb,da113553,e3f9d36,7664a0ea) +,S(18ff6e74,87ebb21,dc935fdc,265616bd,d3a4bc2b,35037483,c911f185,596a93c0,34209cf1,2710b007,821ba024,f0491e54,bade44da,5980f505,37869b8,b410d0dd) +,S(3ece6ecd,1c52894d,90043c67,59d158e7,143c9806,658e8e65,5fa53867,6609b0b,4b1bbdb7,7ed6deaf,fba0d241,5f2b7993,89cf7df0,7acfb8a7,a22f42d7,7858c622) +,S(a5356c78,6cdabe6,a1c379a4,ca18acb7,b41fd691,c32c31ac,6cd0edcb,9fdc5694,ab8f37e6,d19af264,58ec5b1c,78f54a4b,877c9416,ad76b646,7e91ca4b,24f988f2) +,S(e5dffa5d,961253d7,f99445b8,f8d8aadc,5415c550,da64a987,ee604278,12de570c,401ebeb4,afacec6e,d41006e9,c60e0ec7,a4840c2b,c64527ad,80d640e9,70800186) +,S(12c46133,4aa32bb8,465c1e9f,afe68d91,63a7a9df,e11940f4,593697d5,fd0c9140,e4fdfe80,be2fa183,4c32598c,a096a5d8,15386dc8,67588354,300018ff,5b2e0c2c) +,S(bd8d9bdc,ebfeaaae,691a19ec,c20cca22,af76db4c,ee54f904,ee5aa8cb,2010ccd8,cd5fca87,4a6cc17,79658266,158066a2,840e61d2,28bdd4cd,f2697e19,7c6c994d) +,S(597d8ca,babc10d5,5402f3a7,48987270,7cd5d3b8,3356ea13,6c8c5135,cefe3fc8,bb21d384,a48ed346,eadc6ba0,2b1e2231,7b2014bc,62d17fa0,9196213,6e12ab88) +,S(3d91a096,24fe1048,dafae0e8,c693226,cb89157b,980aa490,a9a12598,e77d7c19,738fee86,ab5a6e43,753b22cc,d6a28732,65db5dcd,38a6be5a,6635e8f0,136340e9) +,S(44addcb,55d0870a,19682075,116c8fc,d8f49b5c,5ef767ea,aec513fd,8d71841e,5e126cb7,8d13c0d0,55c3363,b236bba1,21cc5618,40e3cc3c,e100722f,1cdbdb63) +,S(5bc89297,4447eb3f,54b7b451,6da3d1a8,f23d6d42,54ec7268,f3e9b2f4,78d88467,6d708655,6b679453,253df54f,68541560,b5e542ea,8f1a4a9d,a023d8bc,6baf9559) +,S(8fe4f040,553ba9ef,47a0086f,a8dbb75a,2362af22,a58e0739,7c62d2dd,2ed2fc40,b2d0c561,5afbbe3a,18fcd594,a8e91e14,ac714af9,e34938f1,74a2c7d4,2028f65d) +,S(e36702c,2af02461,4d5f65a6,b855848c,6d72709b,b3ffbb5d,f08206c0,9c481a27,c5558c45,9cc186be,665a54f,19ed5f67,983bc004,c1c196fe,80c57310,59f1505) +,S(45b0165,d5eb9c2f,22c6f2e6,3f2cfaf3,5d4a71e7,460a41a3,9d3708c3,111387d4,8fcc8dcf,9eba288,f0183ba8,345c4b08,1b44cf73,b9df77cf,3e94c089,1e53cbae) +,S(ad02f6e7,378d62e8,87d651a4,eaec6d75,9b15f4f3,b7e999e5,2e9e493f,7d765205,25090d49,2164feca,33270e1b,3b08ead0,fcbc7ee4,aca4b4b7,7e06d865,5259a63f) +,S(5684c664,de3844ae,90bc93ad,426bbf69,5f349b97,6080193a,710b6125,3d6fcb0a,c5138172,4fb53812,9dffe038,7029b209,946a913a,cbc06370,b3b58f1c,759ac8f2) +,S(cb36c4a0,f6d2beae,282e9783,2148704f,aea7bea8,af0abca,ac670a7b,3808a2d6,d0aaf774,d65b7eff,589afcca,746b02e1,edbd10b3,e2938d6,5a0bd17c,f71de58d) +,S(143e1741,5da8c61a,959643cd,bcbd1eba,169257,2a935eda,1d0e2495,6eeee4d3,c12840f7,7a9fb642,50d19be1,5f35199e,1da83a3a,54fda063,99a6908f,87c9beb2) +,S(b6292192,d471ab52,fee206cb,64bb526e,6b8519c4,3df9ae85,4e4aafca,d53c1509,3d6fb4ea,45ae494a,e2c4c776,29047e33,f73af147,4fd217c9,856d5d1,3b837c56) +,S(d490352c,70551c78,9951a057,cb02eb17,fd710a0f,27dceaa2,ff224ec5,3c566a14,15ef3825,97ee6d88,ed8840f5,9d496c0e,6685349a,f1c62c27,a32eb7b2,bb193fb3) +,S(4797be1f,7ae122c9,2193fda3,80dac3a0,fdc14361,110a2a3f,5beb9f26,f3d85449,9377f25c,591ca377,2ffcdd37,65ef9a3d,6fa7c2,79d18e45,83901795,2e5fa3af) +,S(fcf5b790,98cff1c3,b02be521,76e1c6c6,ac10bcf,f083ae4,5d26ead9,82839614,8d94f596,5b075d45,a8f732dc,9fbe679,dffaf0ea,d2c90d16,b2c7ace1,1de05c45) +,S(d7153203,1e8cf246,683ee529,b2dcf54,1a731397,89e5c354,3bffbf4d,f95f76f6,740af4a,40e7849b,a41c4dea,4b7e0479,ca377fc2,69db00f8,b484c7a8,c4c745bc) +,S(27946ccb,dba75dc2,23663d14,2b56bd9f,2e63cbfa,73290de1,8fb7e988,31b44330,52c0ed5e,abb069e0,84fd8363,dcdb9134,364dcd4d,87b46025,9c3460ed,63e04ad5) +,S(cf3ea523,751eff3c,a785884a,b019199d,2a0ccf3c,1d90679e,141d4e75,74e41f61,b38d0808,936a2920,ece323ac,a707e1e4,914b51e5,e54843c9,63abf292,88ef17af) +,S(d06327e7,917280c5,d8a5c516,7e0d0c1b,e5fd9e25,4c877e9b,9ae6b264,6d9a126f,c3cc3913,9d0d7b8b,6a6b0c7d,b48213ba,eade2202,544dab7f,9ae42e08,fc7c781e) +,S(acfc233f,28f98688,2ac5ea8e,61478f62,505b8b48,38833499,1ccad1ed,5ee2a871,244a188a,64a6aa7,9f74e940,8681b45f,88b5c65f,d120650b,1a25674,eabb338a) +,S(87fb09cd,b3b8a514,f6a02da6,1d9b160b,798fdf7f,3f05d7ed,25c1c4fb,84b19253,586effe8,c4252dd8,c225a6a2,8e515abc,e36568af,107f8c75,a941e936,acbf6e38) +,S(77225acb,8ae251d2,be2f48a3,2eff0c6e,4f558287,13dc8a6d,3c6b7bb5,de9538de,d6eb8501,2aa7fe12,285e28dc,3efe9cf5,b0cc8e91,6fd63f71,c28c3f5,60259a8d) +,S(b03074f3,f2effb45,5caf88ef,e0eca7d5,6f901b18,fd04c01a,f0425c58,1f13dd5a,c8e8c915,fe06d774,8ceb2da1,78816b8a,4db1d082,6df3064e,7a4b0f85,ae99d461) +,S(992278e5,229bad50,82c8c346,8542f91,e2761305,62a34627,b1d97aad,a5999908,56ef7d8,d360d7b8,5af0f210,161ad17d,dacebd13,c45b9c8b,34f1ac73,bd6a1ac4) +,S(b73a2eca,5e9d0e4a,ef4f6ac3,e9610f3,1c72c67b,6a152fb4,82681595,8d44be12,c621ee64,b03b17e1,a25f27c2,aaea43d5,eb2918d9,e0949306,d2ef720e,8975c00c) +,S(7f6dba94,39e3302b,e4f7e0b6,f2363609,eedb30e,dc0b135d,e4aef970,cbcbc607,61685e2a,eb8e8244,175deb0,a006b5c,4292bd73,40b2fa1,3548262a,db98a3d7) +,S(88f0e36d,345aaeab,e8af18a2,d14191c3,8330c5e0,d4e32c5f,c562e549,cfad763c,bd062c83,13e44ed1,891b8048,2ee93ac9,95a0142e,e0543a92,a215735d,1e94ac05) +,S(da3a270a,bc03e6e5,3f572a27,94c8075c,8ce4590,b1b626e0,8a83fba,45dab386,884b46e2,3ab44b4b,c3d09f5b,97994e4b,109f2db4,ee04bc77,6752fdc2,6f0df055) +,S(df346699,77cd82a4,8e3e1b11,6311a5fa,3bb0389c,1c500fd5,15573af6,da0b2cfd,2ecf1fe5,fcec27d6,35c28d58,5fdb01ec,2192c8a3,848a72db,f53b7759,7b8b3735) +,S(11a4dfcb,3a443c3e,259c9f27,e24ca426,6e08fbdf,e4bbedb7,2e6cae42,569b0116,7fc6c4cd,1e3a0e22,d0ee0249,d6940def,bd776bac,9da5a98e,23cb6025,42b3de9e) +,S(2ffd148c,132eba23,e235bbd8,f09be1af,dcfd6e4e,5f2f0b49,6e4fadec,b931706e,6a4def93,52d875c8,31794fb3,6cf0448a,8c9ab5ae,804c6397,cec41b0f,24583acf) +,S(109e1f3b,7043c5d6,fb822b8a,54c6949f,117e829b,4065c0fc,c3ba5e05,a79142f5,c976793,6c034671,e5aceabb,9b08f5fb,af3cea75,a7a4485e,6c08f7fd,a63786fc) +,S(bfeea71a,8bb8ebbd,ca6135c6,26b739bc,eb2ada11,9babf946,6db9f4be,c7406610,44ff78f4,76074ac8,fd7ef860,cab01522,750fec0e,4b86f11d,831eecb5,22d1f682) +,S(4d2b7cd4,6cb01842,46e7846e,d0572489,e306b370,81515cb1,8a7c6cd1,dfb51665,60ebb290,44169e56,1d10a8e0,a2971b69,82276f1c,e7d11f60,ad7decde,e1fe9c95) +,S(66f2068c,e65a1a61,ad95ff3c,a2f15f55,29e0ce3,ad522dd3,d6083d5f,793e0e5c,a95bef60,2bb89e00,98723b4d,7fb421a5,b2cc751c,e8862ed7,439c1b36,efba2f72) +,S(4908ff3a,27aebeca,8697ec,dd7d5483,c6e56427,9d78f013,129e26ae,2ff459df,4c5def88,b60cbb2c,a3430911,aa84e4fa,1055fe1d,921c8fb7,bbb83b45,62b0f5bf) +,S(f9a90175,3a0f4236,dcb612cb,fcbf3f31,d97a8e6c,cc4f9e74,3887407,5d19ecb6,ed3c6f61,259943d0,310208e3,dd8d5a40,a5bfa646,35fca871,a6df79c0,830e24d6) +,S(ffed50c1,2434484c,ae866c1,86b88550,b0bd02e9,db04657f,aa81a672,8e321850,f16e95db,d44bc7c5,66fa0a23,669827e9,9cdf4372,6fba5f4e,a3e28d86,33edaa77) +,S(8061e9b6,2dd9d027,d43d13bd,1361ef3d,ccb4e599,c8d3d015,1d3adccb,6c762eb9,d33a9196,419b283e,5579ac98,8c1b6e60,378fc692,69b18da,a38f362d,20ca6895) +,S(ef8d0e44,e8b6b5e4,857d3d87,c82b01d8,f254c516,fdd139ff,7b8d034b,45698162,8325ccfb,6da9438c,e99dffa2,92afddbc,e1a101a1,20955945,cfb1608c,d35e7065) +,S(a31af5aa,cbc4f6ac,aebb9abf,de164046,1b631b2b,8cc43eb3,edb53185,fc1822e4,c3dbc990,691987e6,a8c318d,e381202e,a0c2297c,f06668c7,a2f027de,e5118a2c) +,S(81e47ea6,b60a3819,2094e7f8,f7bb3f48,a839b26e,d2aee7e3,e159bb39,798cac0f,186a8c4,97ba163e,aa779f6d,a8cf88a2,9f5d79f0,43e6f195,9c14bb1c,b1a53967) +,S(e15af4c7,8c61227,ffbf080b,a3b1dc2a,4966639b,926aae67,f2bec480,5c1fd232,76fd417f,4fe9e7c0,96db39ea,180d38ad,2360eac4,2730186a,b1da32c7,33fe9a63) +,S(3a185818,fb47ffff,640f265d,a2c712eb,f7e022ff,67a21a22,a2e941b3,f72639e0,8d370a41,1f133f43,34534b15,655717f0,73293f59,3bd34c5a,fc5c933e,120e76f1) +,S(18e05d9,2f227564,b572069e,18a271fe,2fef9d81,14eaee28,adb0fd2f,5f078e07,75f390d4,6e8f464a,d71067bf,b0d6596d,a945ea44,c7ede2f8,a9082440,d7e9a263) +,S(7bb788b2,4f4e5d49,2af81fdc,2f3a0274,6eedc5a8,cc74d1cf,ad17c2d5,4e80a107,5b28450f,1cd8c61,2b73038,ae889c39,d33cd64f,d452ab5d,28810177,dbb6a28f) +,S(a156cb3f,e4425b79,3334e19d,2b1208ce,5e6e8fdd,78748c0b,a1116031,912fb9d8,b2571319,c644e959,ba401415,3cba9b3f,cd8ac2f0,f8fa1f04,2d59ecce,5de14d21) +,S(eba23049,f5228794,1651a922,f60bc406,aa15acd1,59eaaf37,d1f2cb31,e7d20b25,ac8f8df,155b2703,d65b33a9,af581a02,8afdbe06,f4927a4c,5546ab7f,b5b2cada) +,S(8203a1da,56c4fb7c,96816507,f99a9a2c,950da51d,af7d21bf,123402ee,a95954a8,913884dc,10a53ab4,6b2be70f,5e2d201b,4c6bb23e,b6644817,b4257664,ed2ece88) +,S(d46609e3,ec19ef57,97ef86b4,ec51b8e5,7a854643,f817e7a0,9be4bc7f,291e7795,e1b3a8fe,3cda0479,11ab8c09,ecbbabd3,ce96974d,8a309ba8,c38c1d04,ef730830) +,S(1ffa9ab5,8eea8682,76849108,9e12ee5a,cb0ea4fc,e6f68436,377e985f,fabe919b,302140c0,7d64e9eb,6ea74636,f9efff59,e907a16f,5c876658,2f4a242c,b52f1236) +,S(4032bf99,32057d1c,8b6a8923,1575d3bc,6e2d6d0e,e1c7aaeb,ffa9ebe3,bcd9a0e3,13ae5217,f9f70a4,5f626295,b30eba49,e9f7c697,e3ed7cde,95442a03,b7916a54) +,S(8d32845a,14575fa5,ea061425,5e48e37b,f3a55bd3,9d924648,209d26ec,b94a20cd,e0416169,8f1e1626,18ce160b,e8b502b0,20a5ab81,7853903d,ad7ea792,b76266fd) +,S(403754d8,1a0dbcb7,1ff4893c,a5551387,b73d64b0,25bb612d,5e2187e6,7acea8b4,134dd3d6,8d642070,cb7778c,7ecc8d78,5c1deeb7,2582e25f,5c58b19f,2f59256e) +,S(4fbe9818,60e5f281,cb1afa62,8e8787d3,28afae7c,fcb73637,e2d64337,bd6e08fc,31a10b4d,78155900,7cec4099,3b5c59f,4bbb2328,b00a7550,572a604e,8d55b6c) +,S(a5414064,747b2ac1,e8868074,3a0fb05e,7ef510a2,a48d4f44,4647663c,b5c48b39,4b3ba626,56cbe6ce,2f228f8e,88d00ddf,135d6b81,979286d9,ec41c81a,f74ef7e2) +,S(5af99ffd,9f27830e,6ba54e05,63b3bd39,4bd8cdb5,764f78ea,b103405a,dbf3a01d,f625b35c,f510f9c3,db948363,3b2951e4,b2209b37,1397bdbf,1d899a7,400a4318) +,S(7fa7dbf0,1b2fd3f9,3ff4ee6e,17115c19,1f663d95,ff446dc9,d53d3e31,c98026af,f8aa82d5,28f2ee61,1a71b432,d553eff,ff1aafcd,8bf18e3d,b6dfa38a,f33eff7c) +,S(4838c0c,ed78e7c1,e3707d85,7311b2ca,6c7a4396,5be4e363,d4a374d3,36324640,4404fc6f,1a6c1751,3354d364,ffd43bdd,61b874f0,714430be,8a5571a1,808b5150) +,S(309c59a9,b42b374d,5c88136b,43310fbd,fccd6ba,e439e7ce,3a9c5e7c,ccb8dda1,fdded8d0,661b8ccd,834e4762,db87640a,fb1e9636,b894dd48,e1b4fb54,863863d0) +,S(1cc76e1d,788111f8,eeaed575,43afecba,548785d,3d66296,223142a4,7be59190,560e4685,6204121e,402c977e,76fac50c,446560a4,9bd2be30,c6dd2c58,62ef357a) +,S(188e8999,b9de6190,a65cc051,f936585,9e7a0498,4452402a,3093b4cb,24116589,aca3c642,dec398db,81fab67c,d05ffa2d,948a430a,e26eaa0b,ec3b2cd1,20b01666) +,S(2fca76ef,b917fadd,88e30d06,d6f398e7,6803307a,b8ac9817,4baa2945,9e9517eb,186c092d,95755005,4292ee1b,986b55c8,ee3be8ad,8adb6387,5e4dc582,c1105078) +,S(41d690fd,b5eb4f10,8aac4bff,26eaf866,86489227,b6e59b89,25440780,10e3eba3,251f34b9,d69611a4,31fe9605,7be2e10,6d058db4,34e0c814,b0b8a0c5,f2e50b63) +,S(282f850d,344e63bd,abc4542c,66cf1f1,a6807b1a,19ed7864,82d06a6f,a03b1e05,de82333,48fc960e,b22f5641,5265c1bc,be290ed9,4ee81fae,248d4676,d38a1a5c) +,S(bdba09b1,c1810ad1,ab2f5da1,b628a44d,a8512221,993c83ee,4a9484fe,6416bd2f,7049aac,e507d6f8,d77587eb,b8759f51,1b7bb2c6,5de0481b,d82a2f82,246d229b) +,S(e7e238af,4639d3f7,e5ec4298,65aade7c,c1127f41,d04b3d11,477456c2,b155a79f,da29edf,1e3c0ede,5546ed8d,cf8fa801,b5bf0dc,720a02dc,d9d706c9,a9c6bdaa) +,S(53a635cc,4e24790f,3ec5c17f,f854e2a1,800b2529,fa882945,50a0d237,58d622f7,ae6bf987,2d3a31a7,4f97299d,2fbae146,58c32dfe,418ee242,2029fff8,166656f8) +,S(10750fa7,df634f7c,7d8bd73d,e056e48a,50c413fc,282748d9,f4d0b485,d0ac5c1b,fdc72a01,883f0ed0,52d97ffa,8e6935b2,3f684f58,5e6c29b3,702f5147,dc645e04) +,S(881e3e57,ed8f639c,5023e45c,4e843bf8,e7d13323,289f92c7,143faf66,a65c3fcd,12f991ee,3390b45b,af1aefa9,dcd20da2,5891ac5d,35073750,47836a0d,e75b4dc) +,S(6be50501,4d72c612,bc0d5df9,13beac50,bafefaf0,aac7d032,824a102f,25bb45f7,4a0e0d0f,f2477287,ebd8c221,5bbf3e33,fff7194b,4217f9c7,57efa361,1b3abfb4) +,S(2ca955ef,23ed3481,615d1f0,db0fe5b3,f0fe5f1f,1b7f96a4,bdf814af,c4a58987,2dffc8f1,ce4ceeaa,d09a7610,7ee08e48,a591a177,9de2c84a,765a53e1,808e3c78) +,S(250da25d,5be3561a,92b56f0a,a7ab8fc2,bf7398d7,aca09237,3d416615,6991a05a,b0e62549,ca492ef2,9ab753e2,62b9c3a0,10df946a,99a982ab,812aa48c,def60c81) +,S(57606839,4791a29f,b66f2314,73b6bc6a,ff383623,c889695a,910c1894,d9c060b3,bac9ea05,7285d6b2,7911b19,b32fec7c,1b25db58,ae39eede,f4aedf09,46c04ae1) +,S(46edba34,d53e958c,c3e4e74a,ba8bb4d7,c6266aa8,9fe804fc,e27bb8eb,cba98e2e,2b85a88f,136b201f,9a1747a6,dc55f59b,41049a69,f824e3e2,f7f00787,f687aa6e) +,S(5d4f6ce9,ac52d698,1a13e73c,3156dff3,918d5b72,5e42f415,a503e573,bd6611fa,4c633703,1de35eed,dfc5e646,e8b0f812,2b951fa5,343d7b59,ceaa5c85,e1ce5c08) +,S(c77db927,f7e637fc,24a38bd7,f605383e,91e4e2de,8ba5b1ca,baed4376,8ae120c7,347f43e9,47b5d13c,c7cb6fc9,fc2caa5,2991a0e1,bbd4bc96,d98ff26f,1a81bc5e) +,S(ebe2ccfd,ce91b78c,95cdd34d,79fc9a28,478c406a,224bfb4,668dd5f,197934f4,d7866df2,d346bd30,84ad837a,a0c65cb4,62cad5cf,3d23b0e4,bd260fbb,f4666ec9) +,S(ddc5f94a,d4420ae4,8ece780e,26940338,294b8929,549fb897,82c06e09,b7935549,25802633,a0127d73,21ef0a12,a2a6eb32,692f2d30,5e7d3cee,f137eac5,8896ff71) +,S(e4000918,46f79f21,71b299ae,6b93108a,9377708a,e7d3f5c3,147a98d0,95e876b4,c8d8c4db,8fdecd8e,fda047f,b92bd9b7,3c999493,27c491ce,df19718b,6152c434) +,S(4add9850,90e16b5c,525de57f,a15a9c38,97527b6d,8683e407,3a978cac,53b29b66,dfa1601,d36d2021,6efe432f,8a335e2f,42b6d645,7fd6f032,d727157,32a85dbf) +,S(8a5536ff,ff9c9dc7,b2a67823,5d60ad10,834c9029,bc243f3a,f10d7e14,4ca0a78f,72ee78e4,e0a618ee,191dc7fb,c1143e4d,70ffd570,bd50ce8f,d368ec29,c22bc926) +,S(9f708795,6233a0e,59757e17,5a87e34b,f7a7485c,94f9aa62,61854b4b,3ac62c05,ff9902b9,6a6cd1cb,6ea35965,3527decc,7827318,97b5c8dc,c24e2399,fb16ff15) +,S(bfa5d3b,e3fd56da,d8e70330,dccb79f5,bcc46cfc,220f4921,4cb8e700,e7cd0ae1,2a4870ce,aa2e001f,567ac21a,79eefe94,8763b5ab,c63fa649,8a5cffa4,126c6d0f) +,S(a965e34,47f07286,b91df55,3e4211af,e6b837ad,a9cc10a4,905975f,1983f2fe,393bb45c,3f6eded,b6de1e70,5a706501,cdd10ea0,2548279e,c75e4dd9,15f0da2b) +,S(e5e38677,c1e4a659,51358301,dbba1e3f,c44f5c23,af7011aa,5ab93ad3,c69b18c1,7939d32,de371524,c3b14f5c,745ea023,34f9222,31f29d8f,c8294802,b334821d) +,S(473453e1,80511622,cbe6df28,46f479c3,b8638efe,9af11beb,21dd093a,24d243e,e2b897f,eec79c08,5afb9daf,c9ead107,57d21019,c655d0a4,e5254a69,941962c7) +,S(fff734d0,e5f24c63,dfbc061b,bac37c88,ec5aeead,4974cefd,77f1eb5e,86219772,ef8a22bb,c29c9756,37c600eb,82ee5873,778d539c,a289a50c,5490b5cd,8ee0bfe2) +,S(d0508f53,85f92779,809a1892,43a58f71,47f643a2,a8f5876,510b191a,fa292dd2,329eae7a,2ee52766,a5a2874c,3912d777,e23c4aee,390aca18,140ced23,b8e82d8) +,S(93170604,98fb43a8,41d09d53,98807f99,23405879,be9f224d,52d21971,130fba89,e84fe72a,cd89fd4f,f7db1817,edab493,5f809b78,6d0c3448,f19505e5,a79e60a) +,S(63634cc3,ce570dfd,8bf90307,f4543528,e26f2637,ce32d690,75cecd2f,63dd127,bd12dd78,7ebe0ea6,661dc389,5bdb6478,7435e9da,5812d06d,d9188b47,e1a31939) +,S(30c7e2a7,925a47a1,5aa1e2a9,6f564e31,61b7a559,3af1a696,91088dc8,9ee64431,5ef4f2d9,cfefe53f,3dc76f96,1a04bd71,6aeca894,73553a0,1faeed0f,6bd2d506) +,S(f7b7e1e,d56b7caa,74f60145,98c18126,d8bf10ad,c37cf1bb,5e6c88ae,f9f6e6e4,a019d45a,7e091a62,8b7125e,d3720f95,dcc091e4,2ff17050,da596fdb,58ebc508) +,S(c6e9b0e1,177dedb1,2e19a0c0,d1167a8d,8095b2fa,1f2dc402,adef0cad,d5d87d3a,64440da5,2b3ec64,4565ad12,6f732ae3,c81276df,5ef15605,3318693c,91c12b43) +,S(653d41dc,e6ae6cb9,45533e54,63b50a4b,72f6efa9,7884d878,52c32eac,fa0f59e,693da28a,13a9cde,d1b7597a,c199e00f,fac2f6f0,6bb0dc58,940b6734,e5eb934a) +,S(b9830b38,f0f8d466,e363fe57,38124fd1,8c9f60f8,cdaf6fd1,a10205b9,5c7212ce,a3e31906,6ace61e4,ad861027,7a12d498,5c35969f,62e5573a,5bf4ac35,277cf444) +,S(94d9457b,eb2bf3db,cd38a667,adda8750,f449af92,6a92fc93,f1dbaa85,457182ec,ff1bd647,8f00626d,1b203da6,992a2366,2ca2b39e,f6c1528e,956d7d81,7e2497c5) +,S(816f295f,1648ccd4,360b1807,bfb9b05e,4a84af7a,140a1f2a,f4016527,1d4b5b80,98217f98,6ff6f38,1987db34,7c6d432b,f24b664a,bb47124e,641d0677,aa4ec143) +,S(3b830637,17254b06,16c1a5e8,999dcdc7,cf3cac91,67284981,75c6909,92e2b2d8,dc2d471c,5323eeeb,611495f9,cb37840c,905eaeac,a85cca33,76d24705,d152acce) +,S(33282bad,f48bba9b,3db3cab7,c3b46c83,867a63b0,db393ed1,2a4bf49f,cd2f7c5b,78733604,b1c94144,ab9a4886,80bc53ec,9d67c4cf,dc77af88,40bc3535,f2c42309) +,S(58e15e93,95c3abc5,2ea68f94,6e3f7943,b1ddcc8c,e258aca2,8cd9f5e3,14b257ca,d7c15bc8,53dedf6b,f7dfad87,bcac6e37,f90d32b8,344d95a6,44879ba1,e170070f) +,S(c9ee3e27,54e8c8a1,e99c39ee,cd3d0b50,f8fcd03f,ccdab94b,e503a1ef,b66d900f,a1ce86c4,7f78400,51c87612,1b26922f,2b4b2358,e302c568,da6310f5,14909db5) +,S(6e2621bf,dcab8898,7d50b5ac,b27eb94,b52cfd9d,29e80d2e,befb5478,a3c5a514,ec4c657f,ebbe25bd,9d6b172,68ada77c,5bc4f32f,57f325db,9556ae0b,4d1adda2) +,S(6e3c35cb,9c86216a,250ae256,f8ab076a,76264ca9,97b1a6e7,41ee96da,5cfb2c9a,d45f0082,46489230,268e5c99,56dcff9c,bf6a0621,f8978be8,f2183920,eef3dd74) +,S(f3b5baab,882e20ae,b0f444e7,47688392,37acdb60,e7c878ff,40ec0aab,7896c278,7d8d6b2f,92addfcf,a248aa96,e8a87e92,4c821c1c,cf7b343a,f588ce7e,93e37260) +,S(b89b2380,110087ce,8c8bfded,7dc98e40,3cada8dd,77b2e68d,120361dd,6beeca0a,616e00aa,4aba8494,9835b0a1,eb0ff955,6268d2cc,91b7672,d0164693,848389b8) +,S(6659b720,1db6e160,58854e12,dd78b89d,40d91a17,b7eac836,ab8453c9,ee3cdbe5,5ac9db66,325b000,1983df0b,6693d93b,adf7e35a,a18f76ea,e2053e34,b1b8908d) +,S(6fc76d79,bf3c34ce,afe73e9d,7a77af23,bcc7e894,dc555f63,8b9d53c6,c15803e6,c366b411,1d6ee57d,52d3938e,f2c0c620,746d636c,92ab73f0,bc812888,ef0b5ac0) +,S(a06b2395,238326ea,20545cd7,b021a5cc,9e21e9e3,26c28b1c,fb50f3d5,e0f6e069,8560335b,a5c16aec,a297f185,ab09e976,dc57934,61170b35,b8a3b6b7,4ff622f1) +,S(bb8064ee,177f3753,19e45c8c,4dcdda70,ddc4bfff,1a866b7a,ae7922e3,13d1515a,a3be84ad,274704ff,e7a76277,d87687ff,572633b,2fb46b4b,40f601a1,ccb98d7d) +,S(27f08788,6a2c0ab,8f26ef15,a85d2d38,f6fb8cba,622acf21,77ac20f2,f05962be,ab2f2929,45163b83,c9cda8e9,4f6d8f7f,167bb589,50d4226f,827c5b5f,a782f8d2) +,S(f51d558,dfd8f74b,7c9c3768,65f82932,65c1bbad,d8aa64d1,ebbc09df,b7f6de1,101c88a8,170355ec,ac23ac98,ab5aac67,7a68a94b,9343012f,74cccfe9,308c039b) +,S(60fed665,a3ba26d,eccd1ab6,c956ed2f,e33da384,dc687f41,6c37b550,123a5441,4bc061b9,b2d7c63a,ac042a7c,efb2b5c6,a43260f6,8bd0f843,fa218cc2,3fc9b5bd) +,S(fdb04aaa,f2958755,ed65f968,ce4fbb81,ccd8c616,32e9494d,510a7b3e,d2564256,afbcece8,c52725ce,c0ef2aaf,a094385a,831afaa6,7c4cdc9,57712bf6,1073990a) +,S(7f45848c,cac04d5a,d9caa28c,e60628c,aea7f076,262689e8,27fc7084,d6b94dbb,51e16503,e044b101,a0d12d73,3a57d8c1,546c1f04,386721d7,a6f9fb15,458e41c9) +,S(b4091018,4c556249,30ec006,95f02723,b9cef749,57996d50,72642d8a,b492c9be,1b3c221c,235e721e,95bdd451,f0f0fc8d,a6a18260,d47b0c09,5f3e1b1e,f6135e5d) +,S(4d5b1a50,d00b83fa,93ab4746,3f84dc21,d0ff4559,2e697fa0,bf8e8f68,5e1c9713,da52a118,24ed00e,6a2434d1,ab383f0f,1e495dac,d08c6a2d,2425e25,a9434af2) +,S(63fb80ea,cb68910f,69700533,8a1769f0,69acdc85,da71618a,9cc03557,1d4bdca4,7f2e51d0,4446763,9cfdc2fb,247c7cb9,5b8e01a5,e27e6bda,6713ba98,1936573e) +,S(f5035d5e,12313edd,b0c31851,266f7e92,6f16c1f5,a6031aae,bd5e14fc,18304faf,7381fc4b,cfb33c18,7bb59e22,be95081c,6f52cefe,dd84bf6c,799f419,453f61fd) +,S(f62c9afc,5a2cfec6,afd54b78,375a73b0,eb5a73b6,f53e24a0,6d1e9111,ff20e835,a5d386e,211845ce,9ffeb917,76a8b91e,27f0773,b2d53fb8,2ac44b8e,83198350) +,S(7477749f,3824c134,c1a91bfd,d1b646f6,43f8109,c2f46887,22799f6d,53e6280b,232b459,2259cff5,99e4af77,1e03c94a,11fc32bf,f2598beb,2316d3aa,d9461c55) +,S(2e2c5f43,5fcf4fcf,72f9629e,ef6ac5f4,31073f2e,7034d6a7,64af194b,1e84b6ca,cb94ef61,c794f44f,2c7d1115,b9dca665,7fd1c184,e30f6f60,caf40e75,142ee26a) +,S(8f7e4f94,fd2a651,86e4624a,93272af8,2d362587,62a0baae,f65cf47a,bcd8214a,9edada6a,d23cf1c0,dd98b1f9,d9a83879,4c21654d,239f1a9b,dbace84e,de6145a2) +,S(e184ae37,4704eed2,b054b667,33544ff5,6ce55a9f,bcd7625f,740b6a67,621c75c3,ea773744,2212bf1d,a26fd119,248b0c51,c413ebaf,75e52de8,97b4383d,b397e144) +,S(fa47fd9b,94cb72b2,60fe208b,c022dfe3,a2bce2f9,ec776313,a497cd91,4166850e,9a12bbf8,a6e0ff91,5176f71b,16327c7,ea5d928d,816de31f,c8de2be4,57b0c185) +,S(98d36e76,a4caf051,e848fa49,64e09bfa,815109f8,63cd5e99,405e64ec,d526c67,706b36aa,6e67352,8fed83b6,8118ae7,1e043964,f444c477,590430aa,8d80d19e) +,S(e7722849,c00c5875,44751cf9,a88fe964,9efc05a3,4d810788,f30a2057,cc1d0c72,d64ba14f,978e1769,51951a4e,8431af78,57e6d97a,f5fc5ba0,2a1fd46b,1c215e7e) +,S(93374edb,547efea,e5f22d56,acd80ce2,80e4d47a,bddd1d9c,9d85afe4,aa6fe6e,e9c40824,cdedb038,9b42e2e7,2e15009b,215d9080,7df6316e,6e81ec9d,40dbbee3) +,S(840eb546,a076bf81,e4954196,6eb8c437,3a055239,8dc4deb8,62a73b76,8b380e28,97b69f93,ac1009d,a3f47ff1,b62ea845,f2900d7c,84e8a1d1,48d96f,df6fdb98) +,S(fdc4ef19,59ca06ae,92587249,e45d456f,d7484278,6f4b3381,676094ab,446c3e8d,c832aa3f,f0ce9f79,1fbe89e1,5511e25c,6a7a4230,401471c3,7b9ab011,1b304366) +,S(42abeb49,83403d4b,5f529eff,16bb991c,ce705250,5a61fd6b,96467a51,f661651e,d815247a,f807af52,b454e83c,9d46327e,d80d3ec3,60f84a3c,dc88b9b2,59efb05e) +,S(176fc9a0,b44a34ff,fd652cc8,bf715a12,a9d5f40b,adef6032,24536660,5e0680af,a47100b7,e0fc557a,f5ca7dc1,c220b5a,770231ac,184f14f,57e554d6,11daba35) +,S(11fa2a03,aba7cdd3,1940923d,37045c99,ff531ba2,a1266fc,26ce7a26,c6495e63,360c9e1c,54fbc823,9878d725,30254bfa,70453c3b,934915e9,5ea4542c,1026b272) +,S(b2dda11e,db5f668b,8d90dc96,9d10f8dc,6c95a16a,a3e2cbb,3a1ccc03,d9acec22,f4d44dc4,8c260995,4fc1316a,2d5bfe6a,18ea754,43bd9a55,2b2f2f08,aa0652c5) +,S(baa1d433,e2adc426,5f87f407,1c8c35ca,423f3e76,5a835a70,2d804593,cfc3f7b,3f55a493,9e25a77,8a9d3ad5,4ccccebb,8a45486e,1aeb817c,dc0a2799,6e70e996) +,S(478f18c,30470c65,b578a6c5,df9c71ac,934e3439,ee5d5d23,21f8f5a1,7adfe55c,c43dccf1,9a9e48c4,41ebdc12,f2876cbe,32852cbf,d3bebc9b,a3708fe,6cfa450e) +,S(18223de3,d62283f6,c440102a,a1769ac6,f5e1a0a2,cf3fdb2d,ec62563f,4e149ebb,57fc95f7,f8e3151b,80fa4e68,45349b7,961fe72a,d6ffe725,e3a0a0f8,907a4555) +,S(2c8c523e,179bc8d2,1e3faa5f,5db5dcf2,cfcb0426,3f138cde,428746d9,94a17276,c3f00baa,69061521,5d512c97,aac1b858,40842fa0,d8bdc773,4e11d370,4f6330f3) +,S(a001d77,af44959f,f1e83be7,d6b16496,2aecd428,3ae2c38d,f3ed3fb6,a0f12460,e68a305b,6f60a1ae,5a01eaa6,7675f0d9,8e6c5baf,75d725bd,d0e2a499,1c323770) +,S(cd8a1d36,2ba4a2db,255ebbab,ede7ab7d,383b641c,515250a5,cf52a2b6,a5b2ea9,20716fe1,e0857b5b,55b836d9,39d3175,188a6f9d,d3cc42ba,8c61a7a8,d9a7a1d1) +,S(7796adbb,7949b234,6df5147e,c3d7e0c2,5b61a874,43fea9f4,b4e742fe,6c1218a5,fc338089,c80c6415,dbb32994,cf5e2af6,b5c3342d,d291d7da,def80628,a904edfb) +,S(3c345146,27eb74dd,88ecbb47,aa9933ba,b7fc8cfc,bd80654a,f96aad51,5c1a7017,cf4318c4,1c021c06,5c100913,dc84259d,2b8d6ee8,102e5c6d,c3f809a5,7f8f2beb) +,S(cb4470d2,d5715339,acf391e6,5e3cc397,eac932d5,5acb65cd,a94538fd,eb684f67,15e6e6f3,383b8bd,1b674497,589ed7cb,e0f41394,e366ec61,b7e1b927,daa6434b) +,S(954a527f,c4496d02,915f0b11,4e95f104,c500be4d,a61eca3,2fadde9d,c1f118f2,96acbc82,d0dd6226,5652b61e,226b7ef1,c6f00491,91bce5cc,fecaebd2,fdd28ed0) +,S(d3be92f5,697a11cb,b8374938,9fe89418,97707ffb,24fcce90,16debabb,a4faa4ec,23d04ff1,e309abd2,aeac3159,ed9acffb,9c5336f5,517531c9,f1cc2dc3,a2d300bb) +,S(7490df7d,5a7ca290,fe029f3e,d92f530a,23a7c983,654bf19d,5c9ee21d,b4f57586,3d7f28c8,81b259e9,f5f735fb,be608154,b80f38d9,b5131bd9,a6e2dabe,7ab2bd54) +,S(992c4a82,1176a784,ba2767ae,a3d39697,5f96ea50,b7bc8947,2356fd98,20aa666f,519d9792,458fd39,7050829b,6ef7449d,da4ebdcf,fecb2a3,8ca0f057,f051c851) +,S(f070e211,b384b497,3d2dac23,3373a3cf,6dc7b9a6,2529af9c,b2fb1e84,b40901e1,175cb1d4,f8339521,26d4b41d,9fe27781,92a2a1d4,7d5faa48,1e96f51,beaad506) +,S(108f6113,c2795472,244db9f2,3a1002b9,349bd34e,f9c9d70f,e146df96,be198ede,2bb9d195,d087015c,253af145,bdd6134a,1845dd92,45d7d8c7,c12ad2ba,2027ba2f) +,S(ceea04f7,9b611056,ed7043f9,707bb318,e3ad332,1da82104,9790b1d9,d264349e,5380e9f,1c52e5ba,6ce18afd,289f49bb,c358bb90,9db23d67,a851dcf,9ba5ec9) +,S(1c74297b,14a4fbf1,2a6421f7,561c549,414147c3,2a683391,c4cc5eb0,79948cd7,581c9642,98232591,bd5469eb,c1a01be8,37bd5d43,cb63e21e,8540ee84,52b12ab1) +,S(14bd0f2a,ebcbdc9,22fe8660,c63bf12,c6db8521,f1f0acf,7406e982,a103bdc2,46c3002b,1e5f25e3,98c8d7af,e340aab7,23ccb0d2,7e24bec4,55d547ff,1df59c96) +,S(32c923a1,526240db,b234ab72,565d6880,b260e7a4,33747aa2,802da713,c30ae9a3,b79bdd74,6ce4ecd4,a554d66e,b787e312,a1ed53e9,c77cd6fc,73b1bfee,8b13d620) +,S(af0ec2cf,21ecdfc6,a71c6edf,6f73ab6c,76600a89,86b62006,8b246008,7cdf168,d229f3c2,7db8019a,eeb8f25d,84f3e341,681de4ab,2173f510,51ef4249,7a9dbb0a) +,S(1d648075,8273a9a9,c970cb10,5ae7e537,b017aadc,8be5044c,a1f6a3ef,4d2cb275,3faae8a6,87925e3c,e9c3482,d34c76a5,702c9bea,a307aa45,f2ee992,efd86387) +,S(160ebccd,b4d5561b,488037ac,25224afd,91c66584,660af970,672d9514,87376568,f510b49c,b58b09f9,46001627,2fe744cf,e6e7abef,8f54552b,41b6158c,2ce2db5) +,S(50867128,704795c1,a190077d,49a87c99,8b10601b,c37b7aa9,908ce92f,28969c30,106fc462,a115f2b3,e83a5474,7a692101,8c73853d,83d8a1b2,2b0bb785,bda8a896) +,S(3ff4aa26,7e8d344c,ac75a46f,7b17af59,5d056078,fe860a96,573a8f0c,164c54ee,2632d1fe,f4b34a45,ac38a80d,236b51ae,de92fb72,47b81f6d,af1b9554,4d426d82) +,S(739f875c,ebe795f0,cbb846c5,88c2b809,21468ec6,4ae09034,6032a97d,fda93c1c,8393a2b0,f3e68c9e,a57d5c8b,f8355d8e,71f4699f,201636da,5451023c,92a1b98f) +,S(717bbfa2,b2c4818,ae620498,3506a421,8cdff59f,2e040521,764b8013,b688c7bf,9229cafb,e99cbcd5,3f73938e,82723d2f,e7187ca2,13d9e0a,57c12254,dbc7f63d) +,S(cc0a808f,2618d1f4,27f165df,4412739a,6ad9af38,e8c25a2b,14bc97aa,1c5b0f7b,3b83d5f2,3d94aa87,9769c3d0,5e921731,17c345a1,3418ec3,2f92d4b2,c1e275ad) +,S(4a0b31f8,8f82abc5,6867fffa,6deb20d2,d8e7613b,aff466db,b260734d,1ef8b1c9,375d7c69,83784dbe,a5bfa8c5,8f8baead,8e94b9b5,95c01d9b,2747a06c,5fb7272e) +,S(52149a1c,53b2da97,f39e9dd0,23443cd2,b21e404e,b6235014,ce04c616,9f5d05a8,a9f9a4cb,ea6d202a,c6b5aa93,28f583c4,45db83e5,8ba7fc25,3eb43e3,df7f542a) +,S(6e294aff,9e9fe4df,9345bd93,1229a7b0,955a3b63,fd19d1ac,57bbed72,50262b8b,abe6fad1,5fe423b,e1a55867,137c485f,85639823,beb6ab2,81dd9e1e,ed447123) +,S(e9a70c2,c5e962c4,dffe24f3,8930e095,c2b0b540,cca2d891,2f6f5b4f,e4592e9d,8d115293,95051750,ccc9369,63b987f3,96bd05a1,49915103,1e47baab,358decf8) +,S(e6c934a,57ec5422,5d42dbca,715e62fc,ae957590,52849f8c,b5f282a9,b82d4adf,6da738b2,40ff3070,bf0c4ac5,50ca5a77,31db8a07,20312e2f,f9de572d,d7b67d4f) +,S(89b46ad7,cbcf1b6e,8741e422,ef53beea,49662d96,bcebbffb,57baf0d2,1441a0a2,b7205431,1798624a,3a1708a8,986ca47e,374d9704,22f7d3fc,57ca7f22,94913e8) +,S(5b949cc2,69f0b0a0,c3b85fd9,e45b737e,7379a4bc,70d926cd,cad87ae3,4e7a686,7e54863,c1efbe6a,a98d6466,65057347,7291b068,a43f1783,9d02b190,9327bac9) +,S(787baad8,9882587a,97b049cb,9906db7d,b909239,aa50e073,d476081b,4a73d7eb,8e3bb416,b57585f9,8b337b72,b23c2b9e,c790ef6c,bd397b18,ab78f8a8,cb662425) +,S(58460ae1,5a204740,c375cef9,e447edc1,2fb6a0ae,2f8d18b2,8e82ba60,729c82be,1bdf3641,d16d89ee,378e83ea,302efb0e,2a9471ac,9bcbf1e1,662885a0,81c7780d) +,S(c9bc29a2,1f7383a3,a90ed3d3,fc5f6d32,1697e354,a77173fd,77899d17,2012f63f,1c850132,db81d86e,e866d9e5,75c4f7b6,270599f,2e48c0b4,94317dc3,97d1043b) +,S(d4c54b66,a1ff77b7,63f8c520,181e4ae2,6b82643d,758f872d,cddef933,36cb84b7,23e64d9b,f7456086,ce8b778a,194f8b8d,f1f0bf38,fbb8454f,d271d062,ddb9b9ce) +,S(a947a90b,b27db3eb,8b4ca4cf,f947e587,54fe6a48,7b922ab1,9ef4b5c2,99eabe3f,c83e7022,f6e12dbb,f95e95dd,2bde8b94,3d72cbb6,5b222f57,94d13251,c9fb975c) +,S(d83f6040,4099d448,8ec6785,131524f7,3e58727e,829b3d58,7d445197,cb367746,6d50285f,831e1173,cfd7de2d,d1c7c29,532a391c,3f450b7,f25e758b,f412a8a7) +,S(75d60448,78902615,467175b4,bc16c936,14bb10e7,c9fae9f4,57d4a210,2d506a0b,885237bd,b4277447,fc7970c2,4e3e7240,ca24a07c,e46b8bac,7a91272c,ad9c5854) +,S(1f96a542,2ea4726b,b639d270,17eadf33,43bfbb7f,f1fe9307,a20fb5c5,f1c4fda,5f80a9b3,ec8b0fde,ee914ae8,e6052100,77701a73,57829803,4cac5d44,91ce0a22) +,S(3c0159ab,4f27b61e,c2599ad0,a79b4228,9000fcb9,ceadb440,24e1527a,f5ebb9b1,77df26bb,659283a,37abc70f,9f465794,ef3fb178,107ccaa7,a5404c88,a67a12ef) +,S(5b250c4a,25293ab5,34f287a4,9f9f966b,7ebc1c93,e5a774f7,c98980fa,7980e07a,dd6c9c36,5c015685,9e1ec5fd,3a740d1d,7eaea301,2311d1,a9cf505e,7e594613) +,S(20a6dfe3,71696c50,c3a7abf9,3341c41d,9d6d2111,729fe45e,f3ceb49e,977151fb,bfdd0224,fff97fd7,ac3eda1e,ec0e6f02,8bf7a3b8,23cb49d1,52d643e8,fef3d820) +,S(915fe7ad,5840d789,b94d1bd3,2d555340,3c9152f0,340a5f87,6862ca40,19825b79,8d2f0ba,3459615a,2036a07,ca57d0e0,f3a4290b,f5fa7327,2431e3e7,bc44255) +,S(d6aefb63,618e2fd0,34e4f17c,eb766d5b,c27c9a15,d796b16b,7cf8ba71,31a2404,f0abb6a6,e862f6e5,d71b062d,e9bb7b9,dfb2e4be,1c5a85a6,dd3e0c25,3617e8cb) +,S(4c804837,7d65a97e,f65a342b,c4549e16,5cb1c50c,cd1549e4,d2d2ec10,c663882d,e1ec6bee,d0bb7243,a384e6ef,100e5180,4de6ac00,b06d7b67,3e445dc5,7b76dc8c) +,S(3a6df802,f372b56,1ebed30b,a4740d03,d257d256,4931422d,fd3c8c1c,619847f4,d168c60c,9a86bea7,e48e58db,d8e6bdcf,b6ea7d31,d57f8996,70f79e33,241bc439) +,S(423eedec,169fa4aa,52588642,a62ec6d3,8acf2ca1,c8098c24,4a56a6b3,169f9932,4887b475,7f27b4b8,d288c05d,3efc1d98,c0428b5d,e4db1cb0,6dcc4782,10cc6f52) +,S(2864f372,8f8c5ca7,5dc56dad,8b968c71,a008eaab,80b8bf28,16bba436,78465be6,14f5e2c3,423f863,64962871,b786c840,50cc07b9,f537ddfe,cf81b95a,a276b813) +,S(cb96234a,985e2ada,d8130ec5,472efca5,7ed7331d,ae7570c4,dd42f4db,9597ff08,69722bbe,5b367ce,5868b30b,31f67c8c,a5f047ba,a7f65202,48041458,66b88d5a) +,S(3be93dc2,99b7e701,ddf0f239,286ac598,bea1ce42,f1e21ae8,1cdf07a7,66c1123e,8a9c69a6,6a475e40,d81b5d0c,7734cec3,40f528f7,4fa0073c,ee92161e,cbb92d00) +,S(9022c43c,7acf3552,fed52d25,d25dd3f2,9aa61fa6,988a5499,6aa3626b,88b7f497,c514a46,f328c9a5,dc2fd03f,81ce3fda,915f1e8f,127348ff,55e4b5ca,2eba0e53) +,S(a24cade9,47a24abc,a050ef7,f62d138b,85c96d0d,2edac403,dad58ff7,8a2a9d3b,a209613b,c05a7b52,41697e24,73fa7fc,412f8fc5,b2fd0447,a2e20e71,949cbc0a) +,S(cb2010d3,94259307,ee3491c5,58efbaaa,203cef1f,8a0a1e99,67a4ff3e,719495f7,1bc5b6a5,b5acd447,baec221,141b601b,a5a3a640,7f84b8f4,319a760a,6226b0c) +,S(fda8c6d7,c6302b27,76172f01,5e59da8e,4af1e96c,3bd05f2e,a393fb7e,1dc1ecbd,87ce1baa,ef24102e,19c7a17e,b267acee,7681d40d,705f7058,c514c9c1,f615e666) +,S(b459fb13,5b9902e1,760286b,b37ffa03,ceabb618,e684823c,17ba97dd,c95ebdf5,6e35fbaf,b5175d3f,ac60f2db,97447cc4,a79c212d,5496ab7e,4b536ddd,797a19d7) +,S(ec137d8f,23b119eb,a286af6c,583ef011,5d21f335,8a1a2df,ba6af216,d03b4a36,344fd1e4,869d68a0,87a1974a,d48b9704,5db2940c,dec017fd,a0605c11,8e5c7bfa) +,S(8e0be401,9f2d3cb8,9ab07348,cae295c5,eb7fd7aa,fa5a83e9,3d68d994,af68e14f,542fcba8,51510baf,6f962401,e8a607c5,34a32971,22645ebe,2dd51867,b26c80d4) +,S(b1dc8611,3cc18708,338542ac,698a6981,a6192261,7c1f71d4,3b72baeb,1c0dab03,f3e61423,5b683727,f1cca8e8,41de0474,e8c4da8,d2bef431,3cc2da5c,c4ccf38d) +,S(d438b027,7f6c7048,c1eba2c,c1d7e554,888a7025,3f513261,3bccad8f,a5a0a9d5,fc419852,23f6ba14,adda0abc,389d2d16,4a910dab,b464232,298c2a1c,50ae64be) +,S(5484d618,5cdf3f21,42235130,62ddf251,1f53a84f,f0fada86,602c4b13,3dea0f70,6e697180,33860802,6ff41cec,cea79f48,b695aa37,2a76d046,47603a67,ccf9615c) +,S(8c1856e7,6842f5ce,82c09a82,4d343a6b,ac67ff27,f6d32de6,7117dd75,59df362c,70f78515,c4bd17c,23f61049,d6ccded4,100234ba,b7e1b9be,16925635,a9aeea2a) +,S(48052022,94350095,8c904f57,54285e1a,7a17ff81,dde1f50,8586273e,40bd531d,7f1ad451,38b44b15,33327a0b,15fba2a3,f70989e9,1c271b1,461750c1,5044294b) +,S(4adae425,86b0b95c,fc26159c,6aa0b1ee,dbbc936c,83fd6056,f2b730ec,14dc17e1,e6d0f9d0,bfec452e,3f2f9b39,4d73c72b,990f9683,b6004fa3,8e8831b4,f46f9d4a) +,S(d296fd2,926eab53,db70b1d8,d5c999c5,7eb36987,62537954,2074ae12,af5844f0,b4472b2,c33661db,50b4370,e0ae7811,b16646bd,3f4771a3,113d677c,7f1c0cba) +,S(1dbf607f,5d1ea26f,ee8e416a,52c8475e,a8363cde,6bebcbb9,bc04cf4d,cd19cd54,832c9d78,60c8acc4,5d00a568,2d28fe07,4952a897,619f8b23,42dee2b5,e20482d3) +,S(12321adb,c5997830,8689b103,ec1552eb,679a3ae9,70ccfc46,f4adab54,f8dcb2b2,92dd316c,bef2864c,bd5002f5,ba052712,3f920db9,44992ccf,1b2f967c,b70d1f1f) +,S(fa2c024b,76460eb7,a64d1e1e,fe059496,c28372c8,1d00cbec,9ea76f62,546642ee,5a848904,a654469b,dc3eec26,736d7677,ceae5fd6,d6f30adf,8c3fb95a,bd8e5d8f) +,S(a77dcc2b,218b5acc,d6172931,91e8ac19,fa4d74ab,4c88b84,775d2f35,3f51e7c3,de872263,4e2ff356,7d9e419f,26ff51b6,c41fbbf,48124d01,8409a516,9735a950) +,S(83d740a8,52a6139b,53b60796,50d64902,9f9fe35f,87689977,66246b2f,91e038a,1c630f32,722468ea,72bfa970,8a27bd9a,97b68e53,12b7799f,66ede01e,9c75b57) +,S(d894b986,d74580bd,84b24a68,eba87e8,32a9c34d,bafc5717,cdc03c22,8758c9a9,f0d68c3d,284574ea,21a357e8,cad5fecb,90a57b52,62f6ee06,1868d970,458d502e) +,S(67b4473b,3f1420f5,a8fcb39c,8671d583,cc1b9f48,e288f311,2af6241c,4190a786,14fb410e,e33f4a6a,3fe5dd9d,c30d581d,a350c756,6b513290,7f3ce97,29310b55) +,S(24522965,87039934,a6927d0b,782988cc,b126b61e,db154f07,18d97d41,6dc8f0c6,538c4e2,a7e180e2,14e36785,6dedb105,f688f1c5,9bf81d30,d92a8a93,d3c5a82) +,S(b47bdb89,b087a27a,663f9884,7ab44a64,43fc43df,bb61f4d2,bc5b7ff9,234644cc,ee508868,402613fa,1a200032,afacf672,9bb3f7f2,43b2f415,383f4067,d0212483) +,S(92eb31b5,79ac7b0f,d32ac278,4f3d2c63,93c285c9,567bf912,584c00af,3be97d8e,518e379b,ea24a823,e725a3a3,3608e62a,7a40aaf5,318c2c,41afefe8,ec9afe7) +,S(a5e06969,cd69f1b6,c30ab55,1028e1c6,1bef12b4,b2c2d1a2,572c3648,fc739332,378a3b33,3db8d289,667bcd98,9a3cbe9f,f20b08de,4047164c,7f4bf9fe,5d1f93b5) +,S(604823c2,f1ab2bf7,eba63c65,610fe0eb,c958e8c4,7f509c8b,42b79934,7fbd9bc6,29f532aa,3707e872,2169a02c,210fa9f6,100c6b1f,926c73e,a3bd0427,a1844733) +,S(1b4bde22,bfef0cb0,ec9e84fc,e3af2e8d,ce7f381c,e9766b1c,c1d5fd90,9a1bc891,ab20347e,3f4c7ba3,2bb773d1,50868756,69865df1,18297657,6c283704,49451f49) +,S(10caa116,2067d668,5371a20d,97313b54,4d79b61b,3bb41a87,980eac97,e82f58ee,7ee4f118,32d9c2bb,1f849731,d779d12,571a084a,4ecbf4d6,128f33f,6af477e4) +,S(71e7f07,513d42fd,5c0ad06c,c96ce17d,3542a4a1,a101e581,f7394c2f,d89e2072,e214ca42,1033650f,e420e574,e2266c23,3897de25,90dc3999,bee41181,db0a81e4) +,S(fcbe392d,82b4859a,2424ecec,dd8cd47d,bbb89d15,ea2b9591,f5ff1067,e2cbadaf,9b06334f,6ae45d74,44b5f09a,995fd91c,a2712ac8,b159126c,8cc0120c,513f0bcf) +,S(a64d9e9b,5c583eed,aa7934ef,a7ad036,8dc9adc1,9437f97a,7a16b645,cf46e262,9357dd,1aef4b07,a376b468,99692754,9ddfe9d6,7982a7fc,d607f02b,8a7158a2) +,S(e634938c,aaa4010f,f4a1e760,d87a253d,5fd645a2,4f85a75f,8eba78bd,d876fcd7,84be5fa9,c11d8c3f,54f757ca,d9ec4e18,86e52db1,4b3cd0d3,97f666fb,f347d24e) +,S(4640245e,23e6eb75,6e0a44f7,698c1faa,33ea4f87,7a52f850,3477ad4f,8ae2f4bc,ca2a72a4,1348d3f2,6a7fb977,d3106710,2494a982,a96c6514,7fbfcca9,1ed2225b) +,S(c2a175c7,badbfe95,cf7db594,626a42d0,1247ebe5,160c58a0,2437fcd5,eed8c59,94814fe3,7692ad4f,ef0f4fd3,41c63f84,b282324e,faafbc59,38d88f4f,eff210e) +,S(b1296159,d0651519,d76bffdd,98013d1a,bb17de49,111e3035,5f7a1d40,3d8d9148,ae3c442c,2dac0847,bd8d9052,a5470b9c,80536fd9,feb5f820,e4c54ac1,78aa44e) +,S(d30b1976,b0867b57,84d5e619,a5a63516,13980093,5a9458ed,59e4a3bc,ab69b7c8,1b1eee49,690de06d,7a71c334,4fc0a647,133f2fc2,99a8f096,a8a445bb,27f5b96f) +,S(fb1c3b4,5b0f6f0e,35b93a5e,ea157e60,134b00c5,38a6e429,301962f8,38fe51ae,cf79bafa,d7c3fb08,49e1c2cd,48a90ae4,af507bba,5a42f3fe,bb1e101d,7f5fb818) +,S(2bc4d2c1,d34c6d41,9d97ddc0,c758fac9,ff6489fd,786065a3,61ef442a,fe37199f,5b932f15,9500ef4e,a331be88,7022f42f,5148c54b,30957b0,424a168c,c6d76ceb) +,S(2744c1af,3459c35f,d8e1b27,668ac653,eb25f017,e4fa15d,6c1a6bae,e50f3a99,12f95a25,a87e482c,c647b1a9,f22286cf,3297a354,4c7b575e,aa888dd5,6db2844a) +,S(6429f3ff,d37b53d4,88024393,d3a9dabf,f84e3974,ef60f446,61ec9da5,efc736ee,e8426421,f15768f0,caf020ec,3999e8d3,a1aafcb8,24339574,fe119500,a168016a) +,S(33c132ef,437e9dd8,ee9c028a,2ad51c9e,5a836eb5,4bd97e5b,4b5b6bcf,38d006af,e2527602,e5e74d67,5a5115cb,9a89c579,c760445c,c70d95f1,9ac82a1e,6ca16c6d) +,S(3ac856f3,7d53e19f,f6ab49e3,94da6ed2,c8645e65,f4666bfb,163778ce,7cd910ab,ef40efa2,55d7a5bf,99e39055,8993f753,8fd203d6,7fdfb7d0,81cf8bc7,947cafcc) +,S(5ec9648d,b58770e0,314217e,f090c776,396f47e8,ba27c30b,98c35955,aab03247,3d3402e0,8fb71448,6ee97fd9,15293e53,b095fe03,9cc3100f,21240a24,d70819b6) +,S(54955c84,3c5dddd,89f60de3,828fe4f7,1666d807,ff88006f,b46c37bb,8a822645,c8745950,64b3c721,9eda8253,633deb6e,ac9a7825,8d1de2e6,c2dee05c,f167405d) +,S(e0e845f9,35054008,fa44cc4f,1f2e538,33b58e73,bc6a04fd,c16faa76,c1a92d3c,edc48f46,2a41dc1b,bc604e0c,82d993,edc2990d,f59fa034,11702d86,46dd1c1d) +,S(bdb43235,19acce9f,b95f83fa,485940c5,69108af1,376cd09c,884e6419,718ed14e,5669c5ac,84bacd6,eb6fa8e7,39da1196,dde69170,f5d4e5c6,2ad528,66b6d9a5) +,S(d208bcfd,f9754dc6,7e099754,983fb58d,e5679bda,96d8404f,266c0e65,9e4160ee,c602f6f,f0f586f6,7ac771d1,fbf9d807,c2edf68c,a2c10cc2,314221fc,cd3007ee) +,S(3cce9096,450e620f,29b2446,39e8809a,39000315,a887d6e3,da141ed3,32b1c30a,db0ee91,b8447860,18289da1,11b3bb62,289d21f5,2aa8f436,562e982d,bab44be1) +,S(6c351350,d0fa9ae6,e1723848,33e654a3,f3f655de,7530d9bb,59d92462,1dcf8253,2e5ea374,7a368904,e4cc663,feaf6f92,4060dd70,95bab9,ca2e0773,4c48df83) +,S(c64b42da,d63cff5a,ec1eb168,41fead6b,3dbcbd97,f6786efb,5336da16,35950d2f,73706863,cfee031e,3fee4be1,9241cd94,42c24f4c,c57faf70,f8ff8b81,f094ccef) +,S(c4b99a41,7b2277a4,159bf3b4,859e36de,399862ac,70ffb482,b92e1b11,99c748d4,6ae88f86,1ff14b38,b545ec86,1a808c5c,cc78c3e7,91b48f29,350afe20,9efdc33f) +,S(eecf955a,f1ae50dc,44b57715,5ea67ae,1ae39cf3,fd306eee,e943908b,a7a42a56,26c9e114,22cd3db4,b278adb0,8e4c16a2,1a4c0a9f,b837a493,6cbdb70c,65fc5be) +,S(454ef33b,402e3a59,d437925a,b62100d0,974abf69,8803c04,436b4d2d,5a5819c9,4a38e398,1e1d9809,72df7faa,b06bfa96,20fe213a,36ca0227,c7c20ca9,2ef31563) +,S(50f11935,c20dd410,7a2cfb65,2c94e39,8df7d985,c183259a,70f6a04c,6ac5734a,aed27454,75f207b5,dc1e9f4d,f8cf1108,c9507b03,d0e889d8,d33ebfb7,3b10e670) +,S(43bfd366,10b67773,a254a077,624c2b53,4d8ded30,bf53e918,4f10e597,e2edd980,fd0655e2,e6b257ee,a249a5d4,299146d0,e08653cc,cef19a88,5ad6b33b,ae8f345c) +,S(7ad3c8d8,85cacf19,ed6aca96,4607f344,91448d7a,651fda8f,2446686e,bd06a9f3,9cb921c2,3e338436,73fa1bd,101dc4f8,a9a714ad,7fb91057,dd5af779,835000a0) +,S(874346d6,9cfbfc7a,2e13c605,baa69c5b,d39bd69,36841594,1cc50cd3,18c17380,35326549,dcc29eba,4d35a559,e8f2f0ba,b4d94ada,f2c18612,a45c9c90,8d99ef4f) +,S(1001f64a,23afdd92,789390a2,bfde9ae1,d85737ce,3e5087cb,b1bf2d5c,fd0e6943,184b6a2d,ebd086eb,6e04db54,2146059,e6ee341d,1c8854e6,e57345fd,5dd237dc) +,S(659607d2,68695906,fe752434,a229c309,60b33825,a41589d8,6e663230,c1610fe3,77005570,df191869,38a56d95,4643d991,486c70cd,3d5c336e,11a9667f,fd8f7862) +,S(eab041d9,67f89c37,c04bc6f5,a9059d69,a53e5fbf,ef7c17e1,7cef48d7,e346abbf,a2c2fe6e,63e38c06,477d2821,d22b4a0e,4edb0b55,cb1d9fdd,6cd01ebb,d8fa51c9) +,S(4ff2394f,377db94f,e96f51da,d7364407,ed6bc1d9,3822f24,91630c3c,abacda99,4a77b936,a42493f0,d739afce,b769c7ec,cc0d4720,93e839a4,330054db,22e93b31) +,S(7952c74d,e0576ddc,c85f42e6,24937e98,1502b2c0,105b69bd,4e35f59f,1c2847b2,e7159304,dbd9183f,3abde60d,5ad65ab,5a4972ba,19739b65,1d50c056,ebdd5b81) +,S(b3149a8e,f602b6a3,c69a769d,893d561d,c7438a74,bf47c2f8,ba07941d,b0dd214c,99e591f2,2f8da0b0,c9d7024b,c82d1031,cc4336e6,bf1436a6,bf03bc11,3f041979) +,S(ac3bf353,ce672165,a7e736dd,632c7018,1e454200,77471380,7b875d3e,c81ead58,78def098,2f0f5936,5f5c6519,1857463f,7376ec93,f15c01c6,980d352d,17a40195) +,S(9edcef9e,d26ac408,61d3fdc6,66e09068,a9b1e05,cc23202e,1d0b6e03,faf546de,b1387281,71de9aeb,b02b5290,d3d56d63,b6c98c00,cecf8b0b,540f70a3,79556f2b) +,S(fd48622e,8dc91972,7ac21c30,c0fb8d02,d8cfdead,dfc39a22,59853e17,5d8e6d26,4bf26514,204912d6,8bca0ce6,71a967d9,921bb882,33099b76,7a056967,3fd42bcf) +,S(e6dc2ea,c28def67,78b0a351,6ef0f4b,104fc7c9,88a03a46,8cfbf207,ca0ae0e8,d1892329,e77d5770,d9a84e59,c2d6f6e1,db6de419,87c5e3a0,ea508ea4,a11b3762) +,S(e8ff8f65,559128fb,3fc52650,ba063717,cd2d140e,ed3fc4a9,10dccaad,bb0503db,f35c361a,8ea9b3a8,139676c,3ff31cdf,5511535,7859e5f9,3590302d,bd21e21d) +,S(2e18c597,d4e4a4c7,d54bee9,215a1ee3,d149dce3,25cdc4af,f62a3da4,1922c2bd,3e8595ae,4b6cd57b,7f685a75,87ed61a3,281b52ff,d76e9126,4a0f0666,701c5354) +,S(589924a1,2cc867c5,b2289f81,2d93f324,c2df420e,3c948bbc,e74b6bb4,6d30f262,f9bf3d02,cd0001c0,bb9558ff,515ee86f,e39d4357,fd39cc3c,8ce73c75,72850466) +,S(ef55eae6,4a07199f,1a3f3463,5007a8c3,8d39db17,48af39cb,584d4471,d3d32e18,9d31abdf,91bfedda,3c1f02a,aceea672,21d347f3,5d355042,75452c91,5f4b19b5) +,S(7a8f75a9,41182eee,49883295,56588c86,3021548,70ecc05b,31b83a1d,74be05d0,bda4d0ac,ac72ccc0,c07270fd,1c2bba00,4cc9ce5a,fc927f,6d4bc0a9,b2fb4a64) +,S(330f8a4a,582dad9c,159e0f9,a47101b9,223fed7f,896679e4,f764b02b,3d1d9eeb,50695f30,f9dc9c75,6df20cd9,aca3a06d,7199c138,4b3ede52,2dfa0816,31fea2f7) +,S(6dd34c6f,b89722cd,182cd5b6,a0d83132,56814bc,7ff147ae,668618e0,30bceab1,8998216e,8ccfeee2,78e5c0dd,e206d3b,1fe058c3,990159f,be3beb2a,2a97cd60) +,S(66c2d4bc,1e1ee63e,75481e23,1e6df60b,82c73758,36d4c9e9,fa99a576,304ceb8,f6871e84,fcb56780,682bb226,a8d2f46b,89cf516a,7aa0de01,2ccd981a,b739244c) +,S(560ac5cb,b9a55c0c,8bd6a36e,9dc90922,9297a452,b83f8db0,e0899577,cdb8d04d,b6255568,4574e609,ab7dff47,938008da,5b11adaa,480becaf,287f2216,cf1c7891) +,S(a2377a79,e597dffe,224988b1,63ca63c6,67827b81,ccc645ea,cc23ddb2,2a1503e8,7663e301,4dcdbd71,620ff660,426581cb,7e723605,72b651a7,103faf36,480834bd) +,S(fac987,e1c77065,bb1eeec0,fdd92f05,5d10e738,befbb155,152bde06,87c7fadb,c6fd2faf,683f4e87,77a6166b,59c4b93,e7f5d803,fec49ef3,29e1a4ee,9981e803) +,S(81ee9f52,9b5c6b11,8fc6ec23,88f3ecac,4120f8ec,d134d22c,f809e2cb,1e88a490,e8bba906,3a3ba848,7bdf4a82,c5014493,40da0e2b,fda93fc2,b6440b50,d24536d8) +,S(e6439a0d,545c7431,cd8321ea,420dd3d1,9932427d,475df712,529bfd17,99dbc4aa,6c86e739,b6d0f23c,d3570bc1,86fd9e1f,e617fc41,8089f2a9,d42d0b91,2b4c8d39) +,S(e08169e0,f7362908,a0d207f,bf49a44f,5839c76e,7ad80a74,44e7d24b,573f0bfd,948ce18f,15ef6e2a,23f2db47,db402d38,2a4a3cc3,a8a3756a,c382cba4,f608283f) +,S(5687e6f5,7b2bacda,eafe58b5,94bc322e,70c7afe7,884ab4fa,4d46467a,7a8ba729,994d9091,e432b4f6,72e7f711,b5e0a7bc,b07fae10,b6e05ca0,5a088cc6,e4d89d80) +,S(6edfc830,82a178b0,d9160f4c,f0b01004,65c29bea,e3c29d31,e3826aad,9fa1979,5f4c6676,3df8ac3c,4490ec9,fcb0695b,e9c0532f,df526e83,f27ad47b,5bfff2d9) +,S(28128135,a17d0e29,4871831d,2542c2e6,80dcd79f,6b4fafc2,722b7db8,4ed449ef,4f7e515e,b5c7eb7e,415d7b02,83ff11c4,8f3f3ce,a724c476,71d02d1,50835702) +,S(f55371f4,2d617023,dd5542fa,db9a9127,c16ac04,1545db5a,a18cdbb0,cca4cacc,d0c795cc,54057d47,5bd080a1,acbe6881,3263f593,917e012c,dc1bdafb,920b3ec2) +,S(10fffd7d,a62de848,c07b50b9,64e3b31,ee6a13ed,996fe92d,565cc54,fd0b7c1b,92107e28,5319ce07,61e5f212,5724f2eb,fc61498,f838717c,6637c7af,8f0fee23) +,S(a6a73f68,bcb103c0,523c8f28,f14fafd7,5b8d399d,617a68d4,6ad0a1c8,6f12a46c,d18efb60,37f40a9f,6567c993,24f3a7a7,543fbc30,feec0252,87dc862e,b22fa279) +,S(2984cd0d,5c4f1c06,3854d233,6cdfdca6,50c94275,975feb2d,1b0b5bb1,c7dda582,41b0a86,8064dfd6,5c2653b0,27dfcc75,50eb755d,7c1f5c78,b0c13493,acbb4db0) +,S(a701d075,7be9ff89,67c67622,dfa8ff9f,82f7d5d7,814f6c29,c73045d0,c5b16589,ada61af5,62851c60,66501019,70953ba6,fca0d99f,42378b8a,5059ceb,2a0835f) +,S(f07463c9,c37479e8,259a32a,a2e8f283,27cc267b,95aec8c1,1242a092,bf4c47b,1ae9bb16,e538ff69,1e9ecc98,838e112a,a2016657,c7af104c,ee92471c,df6cc136) +,S(fdec5a71,21a17f37,b4c2e93f,56d910a1,788d2da,b3cce509,b3e2f3cc,f141043b,a62e32d9,336fcfd1,4bab6cf3,26ee3f31,4d2ad023,430768ae,8f093408,e3505d90) +,S(be32f9cf,9a13d4d2,652d122c,c0ce07b,da21fc85,52c0808c,23dd5a5a,9ffb3599,a4a73b26,2b5f8239,e8c279b,20f79c71,7ea47a64,1c084f52,f1bd4f3d,dbcf9c43) +,S(735a1f6e,2575ee01,9ebee00f,a4acbcc5,93bb6572,c4db9505,bf96a2f,43b66f38,20b1c7a,99c6cfcd,58b3f00a,3f9d7739,f9cb682d,946b33c8,879f041e,15e198f8) +,S(a0b840b0,6d92eb95,4f029204,1229b9f0,f1838bdb,4ead7432,4d8facd,70f7447c,383fa2d6,47d88c1b,fc9b04a8,a27b3a99,1a22b82f,7c99fce5,5cf30855,ed1c22f7) +,S(3e54abd4,36a9763e,52b7f46f,4955a339,6db284cc,77d0b351,fee7a568,e4774c83,1c64ede4,fb372325,dd435f71,e4dc914,391da9f1,ee08a21e,2eb5ec18,2834b0ab) +,S(24675c97,67f69242,4e1d43e3,1c46ecf,b418fe9b,3fcdb495,822362b,2a8adcb8,9e38e08a,4359dd9a,a9ddf4c0,8fd1147e,c70ccf1f,8855cdbd,49f44dcf,1edcc36d) +,S(16e0176,9f5a5c0d,f6db88e7,fc95419a,96f836f4,f8255a96,77ca2710,2330e317,30641d0b,fbf7a1de,24c72692,b7032355,6996bf3f,1b541dae,d6ccfe8a,f847646e) +,S(a2e30015,a53829d7,c95d5704,3d6dac44,bca932b7,d4115826,c602aae6,8e4ef847,33ecf0cf,e81236c4,e8fb76e9,645e4827,9bfa617,f6d2760f,dde2b110,77da6ce3) +,S(cd9bcbcf,b7338c75,3fe393d2,2e2e44f8,45a09b83,fe4ce29e,546f2a58,7d7422c5,7683e5e7,f990e09a,e15902e6,c57b8db9,e2b1d29e,8d3bf33a,f90291a4,616c794d) +,S(77a00bb9,6abb918d,774a2a4c,3828fa5d,c7d40bfe,aee10091,f5d92cae,cdfca277,f3febab5,3310a2dd,5dd7a5e1,33572b3a,83950172,be7e4cd6,fec7575d,10142e02) +,S(be2f342c,ca1f161,d15f98cb,ccac9f2c,806c6d1b,f34656b5,c671c730,bdae8efa,c9c7a70a,88ed250d,6a7c0307,d3dd907f,ca8b399d,4affce18,e988ce5c,e0efb5f8) +,S(538bc08,c3c775bd,33edee48,c96c6fbc,1435b0c,f00aa42c,6c15fc7c,5540dd6e,9d8b1293,14283325,8d676a92,d479ebb2,c5ca171d,a43fefae,74c7740c,7e956eb9) +,S(d5e26827,fc0d8283,ee020376,56e83ae1,3ee306db,92d0bba1,6b3fd99c,7af15578,b41d4816,b9643a41,c4f8c5f,4121cddd,d7eceeea,9f2156ff,676d6d2b,61b7d210) +,S(7d18f6e9,95f9077f,c371fcce,729835bf,aa903ef6,682404da,bff6949,4b7faac,1423bd83,89410b9,a2cd8c3d,3d13b495,d856b103,eeb96e64,8c258ecb,a77d581f) +,S(fcb3cd95,fb0b4940,bdf0bd4c,ff534d94,26489c72,953b19d0,cedce320,6e3eb556,46043aaa,3d1ce85a,3009911f,763f49bf,df3d7fa6,347f5573,4c6c36cf,97f15702) +,S(a0e8413e,f66527ff,12f6de1d,2ed4eca4,6617064c,afcc4e98,495f2694,34492800,ac640fc,e3d5d094,54ee6811,81f8bc5f,3fb1bac6,84c8c572,b24fe3a8,66234d13) +,S(fbf60da6,aecd3cd,9137b28c,f7bfe541,efe60e65,52470f80,e301884c,1e9cf33f,aab83f4c,9d9e5ed9,ee35be7d,33a02bec,ebca4f40,8f6fafaa,6f385a89,8f7d846b) +,S(771c8d7f,73bf2b9f,4f032e7c,daf17c39,c375ce1d,2e180758,fcffd82b,26fe206c,af22f29,ac2ec5a8,ecb69e2,aa954f49,63d4a58c,2d6769b2,5255e9ae,2689f756) +,S(a30bea5b,4a911ae8,de11a310,a9cd3616,54143337,30aa182e,ba75601,3d12ab80,aad0f1fb,a9a8d6a5,71301b1b,dd11f4bb,161c26e5,3d3d5143,ad2678f8,9960029a) +,S(55d93940,b0a76283,6aac5bb8,c04f490d,e7ad8da0,4cee090a,e1f381e8,5c13fd27,f1c58d73,b90819b,bab9933d,60f54370,7a625449,d637f01d,bfcd6b44,bb467937) +,S(f6b03260,ae0373f5,b2ebaf15,1a74369c,22535844,13ec4356,ea4a9a32,f2132f81,4fd750b3,7f377f97,7b62580b,6ee7176e,a720a434,8df7aa86,642cc6b3,963cfdaa) +,S(80f7aad4,3deccf41,cf4540db,97150bd4,f4665ef7,72bf6c4e,e551c566,d11d13c6,20a9b836,67cbb397,aadb1211,fbc9a78e,2e998354,6f263403,1d844e7,b95766aa) +,S(4f574d76,130e2eac,16bd6b64,85bdd2fc,88855c3c,68a232b0,29560509,463f0c90,33dabadd,62ec0192,9fc3ad15,587150e8,ead8518,327207c8,7ad2a7ec,c712d268) +,S(41b6872f,f47a0d4a,764ab086,764e1844,a8b4c775,cb2bb06f,643a7c13,5a633e6c,301d54fd,d55c9204,4d337b83,ff17dec3,3faf0bf7,ddf7b5c0,afc8934f,65d54e17) +,S(9f4c75f0,cb44460,ad14d416,76c8b60a,1ae979cb,1ff6a506,b5523cee,8acb1bbd,253d8a0e,985fdeba,1ced50c7,aa3724ae,79c75c6d,7c82315e,65f3b579,5fcf70ec) +,S(25db3430,667796c3,b5f3ec0a,cf4f11e4,73518ce9,aec19932,3f0c5adf,e32f4a87,cce88dd2,ec02e348,ba569fec,15a3c527,ba580e44,c32f25cb,fa6f99f2,a1eb4250) +,S(fa71cf1c,2312c228,c706a7a0,2dc3b9e2,f571b468,913b9cb,3fc5ed1a,faf730d,156df61d,752533f7,afee2781,30763eb9,45a6198b,a78a8288,f30e381b,a809eb61) +,S(f5d3adb5,6d77855d,8e0d0b71,300e620c,f96a45f1,5948d97b,affc3ad1,7226294b,95fea642,5be2e987,968f54f8,f3fb30f1,e9a1ba5f,57b68b1,101a5981,a47f9f4c) +,S(907eec9,6db952f0,eb7d0436,c47f5980,dcae53fa,ebabe57c,aaca00e0,10361460,1cefe286,19dfb7f1,969c7618,e0ed4775,e23527df,6a214754,4cd066a4,65f92468) +,S(abbcec4,36e06bc7,bb92dd79,bcc5d9d7,73189ef9,2546dfc4,54b5d624,2c96e8cc,d1546a38,1f335077,ef40473d,baac9c37,66aba23b,8040c4c0,60778d13,8603be7d) +,S(42f1594f,b1e088f7,2020b68f,7fdd9027,b9638619,b0320410,fc4bec4f,4fbdda76,9a417cab,515a08fc,9e7a7c64,7029a457,9881caeb,df8430bd,c1712af1,3c6b02ba) +,S(a4aace90,751aafa1,fe3e14b9,ead1d460,e1cf029d,cc82afb2,4d169248,e63f83f,97ec83af,dbf32c34,df9cafe7,de0b6ee0,67460d5a,607e1ea,fd13a96d,51999d54) +,S(ac7ef2c9,56b41a0d,824999ca,550ddce0,83f2aba4,8f2bce5,644a579,c0e248c4,d97b0ee7,f3a109bc,bd308b3,e4d4ce2e,c1a65878,e7e5939a,76c9d8f3,6959c5f1) +,S(e9cb9aa0,ab09aa1c,18daf08f,bbdd0457,25d4ac95,8607a88e,5bb14c1d,61d826bf,a1cc215a,124e31c2,e426e337,89736101,b739a56,b6d4e139,ce65272e,2e4b9a5b) +,S(885de0dc,e9700b34,9e10dc17,68f9fe12,2672ed3b,ff9d20cd,93b98e38,ebcc67a4,f66a36d3,75272f66,cad46fcc,cc5d3df6,8c023da0,1ebcf766,f4dfbb0,60e1eae) +,S(8ad4ade1,ff9a19a4,fdc89e75,e4cb61c9,1485ebce,b1e4c063,ccb8001a,c5038e6b,e02acfc2,19c22881,d38a8232,fae54d82,e0b1fb77,e6b8b741,890357c5,be261ff0) +,S(5b395388,a62979a2,b931f243,7f3f65ab,292ddad7,728e67c0,e753565e,578fa354,7e77c8a9,7c274030,b22e802f,f0fd69f4,da65e54a,b50953f8,b9945b79,20fb89f5) +,S(271982cf,eb593e95,17a8fa5,6f62fd23,ddb6c7b3,8e5a87e3,712793b6,f10a2d14,6661cb55,543414dc,e02b3650,8660d54f,48086cbe,4b517092,564188d,6815d2ad) +,S(458be91f,a61f477e,47d7b997,931c992,86281efd,21445349,af820000,58b2a93f,48725c06,e7dbe303,f0c73d43,a5a62b6e,131d004,2bae9dd9,ec12cf97,8df04c49) +,S(763f00b,348c1cb9,e922c6dd,a7e72e22,8624fae0,158af602,457fffc4,cb0bf3c1,8119c3e5,b190c6d8,7f3d7066,72136a3b,d0f1b198,d9f304b4,cfb383ec,e075de74) +,S(4fd5e9e2,77fdf260,8ece7268,10343542,312773f3,2518b363,7075fe98,dcf7719b,c234141c,d3e83309,539aa906,2b17ee35,99a3246d,86ad20d6,2885cfaf,5a88162f) +,S(c578afee,a7e492e6,30ca55ff,8923d9d0,9a6d0583,5553c61d,fe871b6d,e1d956b0,bc2d5e2f,add48f2a,50e357cd,4d4c120e,e744fd96,dca0a959,c0bf482e,2e081ce5) +,S(df02c64e,7a60b87f,73b4add8,5ad93b40,bb6a862c,18e0fba4,3f722650,c0439107,d86dc018,525efc69,cc7b282,cd145650,3b9bddae,607e14ef,3e380d53,c266fe29) +,S(9471f488,84cff3a9,2a99dcb9,4cad96f9,d4761570,c0bda860,bf1b0a9c,32a27a4f,23471d9f,6b3905a2,6d9481ec,dfa10a2e,7c7a5405,119dc8db,de839140,2e063e13) +,S(6d1b5784,f58e5393,fec90c50,a674278a,cb841f46,97da9eda,12013447,a2e0b863,d052c806,2905ef3f,6302892f,48b20497,e89cf7d4,3c345ba5,94233cf8,2586a17a) +,S(94eef4c8,be627560,17e13634,53f733a7,fd590dc1,294cefb6,4d8965fb,3d2ed1d7,49a1e5e4,d72e6a21,14e7c4d0,eb9c9240,b3b988d3,21d2999b,46a562e6,1a203c97) +,S(3206fc87,582d1267,92c2a68a,7400a29f,61097fdd,3ecf4cda,fe495993,87ec15f7,c9a7af2b,88df18f4,fe453bf,fc4af355,519fdf21,9251bf6f,879f291c,32a38eb2) +,S(fcd215,45f8a36a,a5a81bd7,1fb1804d,b3fa112c,c21542de,27cd34e7,f7309a1,191c6b9a,42b0adda,bacffaa9,89bbebea,3424a3bf,11345ff5,2af9c3fb,6193ad0) +,S(4432309a,40f6c71f,cb7fbe26,d6390778,fe6f816,3ee50264,2b2027c4,86fee04b,550981ec,b4d2f6df,fd25f26e,6d65f62e,5e549c1d,79639c4c,d07b6282,2d075847) +,S(7cbff748,7bed64ba,7d6346f9,18e23992,a3712ed,1b7cb89d,a6c0540a,335b582a,ddf155a2,bfb25607,ee6bca12,f6df2a01,98513445,9b353c60,9806fbbe,2d9fbdef) +,S(f8cd164b,ad3e65e3,63368645,76c49035,a95f7928,350c855c,fa534f6,80709789,25412c86,23bca2e9,8d5531ee,d57c80c3,ab01abfc,498cbef3,deeff0e,ae6912a) +,S(6fad2644,990a231f,c27bd678,36ff84c0,11fdec01,120dcc0d,f114b032,1d60648d,6beaeb65,ddd28481,a23af85a,5a417323,350d057e,1a574b0f,5d994816,844d9d98) +,S(1fbf086e,d0adb5d1,9c49947f,d019046b,289c5703,1cf876d0,8cba81e3,7739dd6,86e3511,3d4593f7,a8142c45,8e915fcd,685efd0b,f8cca8a0,79ebded3,f4453acc) +,S(30cc2cab,fd0a2244,2c8a6e00,5b6220e5,4061dbb1,4f8ceabb,6215bce,f5f5b312,b5a1f70d,4a05fff9,9716ac44,57a4342e,7d4bdef2,6cd07fee,b515c56b,19fe72b2) +,S(156efdd1,901ebad9,70eb167a,bb99ac5c,676a0929,3feb0b37,8ba19ba3,6c2a3935,b1d39453,32f0e107,15d06df2,d784b1c3,bac221a7,f184bfe2,4824a368,9ff33051) +,S(48682e29,6b8e8123,c9fb6246,5e8480d5,54350734,bc763757,f319d40c,87f2ddfe,efa5e5e2,be832508,e71b15f5,3a7f1d77,773129e2,e57b2b86,9545cfc9,a20360f8) +,S(d188747c,968b67b1,88958f37,b9990bb3,1a54e3d3,e3fe9e06,7aa9b1a0,87f5e3d4,6d60a049,25660c21,81efbbd5,6a436409,6bbdfa39,b37f70e6,4d13f3ca,6bc76b92) +,S(d7cfeac2,7fdb5922,a5f534c2,b1d325a2,903217f2,ff41b6ea,1e5d2264,8095d3,19618c66,87bb0d92,52133c84,26fb8aa6,4fe1355c,86aaea97,b9ef49fb,de063e75) +,S(dd795951,27b0ff86,94dd131c,e85ca6ef,9aa2022d,d0c7f053,4c83735c,43096c02,caeb4cdc,2633b01f,1b51f7e6,103ede8c,a0ccef5d,e33a8ece,5ddfba8f,736e2adc) +,S(5b2bf207,9a319707,52496851,68aad1e9,5582408,7e5d361e,87b77900,d9c63939,728df41e,69c939fb,59803668,6c44d0b6,f102dc4d,ee146a33,42e1c04c,9b6e30cc) +,S(d2a26a5c,313aef0d,6ac190cb,11c84771,abf97d8e,c7e6e67,bd3313fd,15c2ba11,84a1fb57,1507d012,9d98ebf5,34fac803,5de7a43e,48868269,d5e9656a,773fe768) +,S(22c22c99,860b2b6c,630487f2,5263e77,91b62450,290e9df,379efa7,1edadb52,d2b227b3,dc85c1a1,ed64a7e5,6dd6b178,ce0ab5e,68647b50,1178ac78,4b7d1c93) +,S(b811b039,d2cf5f3b,95e38e2e,14da67bc,417cfd8,623593ee,1f2e924f,d9a064c4,a860653d,ca39030e,8c1ed7bf,aeab73f2,a68cb8a0,5263aaf2,431b6f8d,9c862a28) +,S(59ee23c9,26b38d6d,d6c091a1,d4adcdca,b3a5a548,a5cdaf92,fee9fe2b,c3cc2957,67462318,96e4f107,67e39d47,b03268af,5b54edb0,9f9e8e0c,3f3f89a3,e9d204cb) +,S(cc79ede7,ca5a9ba5,a7c5114,d2039d5e,c6a54db8,fee6c102,577a20d9,18ba857a,2cdc980,3a06af30,c19b262a,12f54132,933ec985,afbd1598,45c40be3,2e24861a) +,S(1319c7a6,2f3959b4,cfee1223,b225c6e9,9070753,a1ad33d8,8f3a8b78,a886f7da,d8a75f9d,b8266ea4,2b650265,6b6c0ee9,7f3598d6,3d149ad6,9a5829e2,f3c29085) +,S(e4ae90fd,74e9b229,b9100cef,1da59b80,753b4f0a,cd7790f6,34930a92,b1eea356,370f1c98,f72e698,73c8d0a4,e76fb117,d7e5a9a4,d13521f,f4902a1b,ed3688e5) +,S(286a98b7,b0b0527c,310afd37,717b5061,467be24f,8a0b5528,52ff26ee,d658988b,d10699be,f79e800a,519b964a,163cffb9,722c3ba5,b56694a5,c1a9b883,b32965d8) +,S(9b8544b3,79746ba1,8524e084,2d15b853,46577b81,7084e02f,7d0cb820,7448f5d6,8421c0f2,ba15f648,246f9cb7,3b10d6db,1de7aefb,fafd9b52,16234dab,8e70218e) +,S(81efaf7b,50a18c8c,2481299,bbd2adba,f3510ac4,f871c3c0,f849ef6d,4550681a,ea8567a2,9c871ba7,fccea923,fe07e8ba,2071d7db,25d33ce7,a6125c0c,2afacd17) +,S(6680fbdb,dab850c9,115d5765,344f1466,b88cc5dc,8de9fab,549f281e,974ed7b,c7871b4b,2690f4ad,1e67ea81,e2cefac2,988082d8,b1c70e67,4389c79a,bc880368) +,S(4c38ce7b,a8e3d317,6f615d6e,27578edc,746fb80e,4701efae,f7557469,a1dce4bc,f6e73d73,61ff5407,10dc9f1a,4bd5c1eb,a7d8c8d6,45f0427e,a4fc3e45,3990b88c) +,S(767146d6,bc1d5bb9,c73321b5,4cf6bc61,e8209703,fe4dddf7,2b3d6089,da60be69,86df7dc3,6894f88e,fe24a4ee,fc78b1e0,fbb5138d,31666be7,97b8934f,d0b9a37) +,S(bffd4856,360c02ac,ee741a65,486d5a7,44e2a005,9db5ef5f,f87b9e18,3adbed20,c11246aa,3bd4ec3f,71f88d2,cb3b96ba,2c210f90,d8234c21,99bf7781,f96ad781) +,S(ad19b5f7,45556650,eb496450,968d056a,fbcb55b6,8852f510,ac96df54,cdc677c0,f78295f8,59445c52,d6ea285,3fe9baa0,5e453bf0,9b3f4d28,6c99e858,62a04bbe) +,S(5924f679,bb94f6db,d8232b01,ca8dfbcb,37a83d24,d0e7026f,b526162d,c82aaac7,baee6567,6a526460,ec7563ad,42482d37,a42f2fcb,f4a5eb7,b37b515,a6c3f1b9) +,S(dee240ea,c90d5399,89d3b3f5,764e0680,1e601a4d,f2c09226,21eb0b7f,bb53ccc6,12668b,72cc139f,5f9fff4c,ef24b5ec,d0648e03,64c17417,f35bfca8,b819316a) +,S(e288a00b,e18b0987,9765940e,caf8972b,1a09f67b,fdc455c8,8e3b4ed9,dc0dad81,fd81e0a5,adf1df8f,42c64825,6b107d44,887d01da,f4cf89c9,11529124,16a1e4e0) +,S(e747d6c7,3f5366ed,241501a0,ca6dc04a,aca7241d,8effbd94,7d3e6a0d,bb6eadb,9954822b,15f44840,9c9e73d,97722194,1eb6a218,ef1ef4f,269ab118,8f9c773c) +,S(57b8865b,ac78b9a1,c244452e,8057be3b,4fe2c6de,9ca9a295,ded04377,2b61aefa,d0e46172,8828f0d3,f1fa808b,1dea8516,b0c30d93,4acc8c90,6ca2bcad,303f06b7) +,S(abda4b38,47ed5cee,7ace4e8e,e652336f,26a8f4bf,4bd610f6,e87e5936,e4e8339b,8860963b,8f266c30,9c6a00c6,cdb44048,a9a1b76,d0a5a652,b4453f7d,330bdd9f) +,S(7f05f2d9,5621d06a,d344bf91,7fa8b9c4,2ceafa3d,fabd0620,bf7086fd,9539e089,298ec6d,8d5a9506,8d916678,dc8e62b3,7b6fb9ef,7967da8a,8419433f,79922f29) +,S(99e4f06b,b8845bb2,12638573,63f7cfbf,3f15570,44256dab,21b5a8fb,c43e2453,5d76066a,86d5c498,323af928,2c3bf419,acb758c9,7883d236,7d9d9e3f,eb8e1417) +,S(ff994b1f,6447ae81,8bbbf97b,8b6d655d,900b04ad,eec06fc1,f57eab70,95375094,6a63980d,3a9324a1,9339a073,977130de,d0fddc50,5b86ff73,464dae04,c3004a68) +,S(3e9af52,f00d1993,8b6205dc,7b6f8ef3,31d624da,fdb2f09d,fd701b78,ed8b0471,a674914c,ac86037b,f0585de4,d867424a,ab9841dc,83c0ca8f,347e16dc,1407167f) +,S(eece935a,e5cd4afe,baca6998,63c5e8c2,e0b338a3,e2ae7dbf,e34102f6,f1c613f8,be70c210,b925dc66,c8546e65,ae9600b4,21a9f668,c3a09a01,8bc5b88b,91cf4d74) +,S(bf10e625,7d336eb4,a962bd97,4cbd9f10,76787b8b,90575250,7f0cfc2e,121d1276,1d93f629,8ddbce2f,1f670326,265c4ba0,f7f5256b,472412f7,a24f999e,f4e1c64c) +,S(73e43284,c80d4ea5,c992ffe3,cdce4149,d490843e,bbac444b,f47ed5a7,3d6e0bb4,82cab83b,c7d2d2bc,87881618,54034d7b,dab132b0,6340b316,964854b7,f2ee3e6b) +,S(5410340,b614b676,63173725,ecf0b8e1,67c2de61,ce999639,be2051dd,2695f8b8,f191ec95,9d6fd8f4,eca243b7,8d844214,976d97e0,65218487,3366ca25,f2e6a091) +,S(203d28e2,694df7a5,6c9b9d42,907c1e02,192e8030,77ead781,8198b2a9,69b127fe,c06fb7ff,2361ac16,a884f0a7,9e4f5a19,b0b5b207,9901e634,be237643,ba93852c) +,S(f9a1e3dd,f53e41b8,84f7c4e2,c2b47131,8d14705a,4e7362df,3221222e,6b2c1921,cd150a1a,abe8ea0d,853245eb,509c1d4f,e26c54b6,98cf9aad,26849a7d,e63b6264) +,S(e82e5e89,db35aedd,4d63b7e,4d55d637,cd2eafcf,f16ffbd5,b0fd1444,c7c783bb,6701a95d,ccae2272,2a834957,e0a4a3b8,3cf5ff19,2f41e8,1619dc46,b8238cda) +,S(9fb768b7,16032fd7,f21315b7,79776882,767d5d64,c9141267,a0ddedb1,55d4ae08,13474a8f,90fda6a3,43e3ea23,e858327,dc2f4c40,4a445f77,4b39b92d,a312574a) +,S(d0793463,ca7cdb50,3622f1cf,90032794,52af3fa8,1866e536,159fd23e,ba6082d7,35301f6b,66858d6a,3e97480b,ec3d2a53,8dee8465,ff5c15a9,1144ede,a208bd0c) +,S(cf8fc191,273383df,f1d703f7,bb237ea6,cb5d1307,8ce8ae62,67fd20da,4d845e05,efce641,3bb676e5,5c0b64d7,589ad771,23900e0d,60feb71f,93270390,ec66ecc1) +,S(f12aeec7,55a7138e,4e91024a,3006db3d,eff6ec84,ffa73d96,da21ef00,452064fd,f0f0660a,22cd7cda,25206f10,e82ca005,3a40d539,472cf41c,b86ed8ae,3d29abd9) +,S(3c40f94d,ab460ccf,c8e47a1e,d015b074,ebfb6142,fbbf5b4d,e77aca70,be67c57a,998efa4e,26df60a6,f1a466f4,c27b2dce,ce6367b2,e05a5ad9,dd71ed8b,482ce55c) +,S(f2fc6db0,49861d3c,a01a6778,22299264,88184967,3802ed49,503857d2,2860f00c,79f0f245,1cc6c5b8,d36c330a,ef8c9c84,95619911,1d4a01a3,d9363382,8b609576) +,S(35d3e3c0,29fdc9e3,88da1cf3,d52df6bd,9ac0ec9e,e591adde,26d3e414,f4fb92f5,62ba2346,6d19ec1b,64d2a6cc,9822feb8,e03df178,3f526a9a,13d10fa7,72de3219) +,S(5628da0b,cc2c0583,902a56ae,711a2217,455bba47,c7222dfe,d60580c6,461b4ae3,1cee8f17,8ce4c7f9,8cf2a2c5,92bf39aa,57616913,bb66f232,a813904e,7b574ed9) +,S(7ec54044,c3fe53ac,8437a540,968e0b,b725e794,a8c240c6,5dac1f12,4ce21be3,f6290891,af9af62d,5dfe10b,d567af1d,6b4b22f2,8177a14b,44edcd0a,be811c0d) +,S(eef7a7c2,a0224a78,aff7c61b,d2379259,7b307a20,bf1c253d,6f03d57f,a8a84203,5c7d6875,905e26dd,2fa4e5,24f73b00,6f4bd0b6,786639af,5d222411,bf69daf0) +,S(3f1e6459,38e4285d,ed30be98,1d149f68,24b264c7,df920f0c,c5d776df,83228cc3,a6a5df53,856be619,25e42d58,2f705567,39c3d7c7,a6e222b8,6385b63e,d1316916) +,S(c83ff186,ae3f42d5,a2c39b43,7712d607,92b9006a,d8bbcc89,97bb9b35,d1663cc6,2380aa52,44674eae,3d96d65,f484e7a7,62cbfa10,96c5a313,9eb4628e,77b72d40) +,S(41d20761,160125ae,c669b1cd,395110bc,94e09a,ffb52ef4,e7e86e,1f4a61a5,c8509f71,2c20aeef,7399d11e,7c438d0e,9b4dec72,76c1013e,a4c76d31,ee5c7496) +,S(cd358f38,d2cb11f2,9fb54431,dc5adee6,721c444a,8fab5743,1149e504,8ba0dab8,e6ab91a8,79a51f40,cf75e405,e508cad8,ec54dbd8,2dd4115c,fda7b255,b1a6fe1b) +,S(d1e1851d,cc95a94c,a8c77b42,5b4430a1,ac10e526,e3f4c6dc,f20267dd,7c5f2d2f,889de789,43c6674e,6bf28470,3ef8867c,8d827681,d2df8bd7,75384ad7,15730ecb) +,S(89268637,1febc520,14709cc6,b2aeb5dc,32e06b14,cdae3d76,b1bc04e7,b9b5dc8e,46823e42,9c0815e,ff99cd7d,f3712f78,9c102af,173b61f,8de08519,f19a3783) +,S(c7341942,420d4e63,263a144c,8a10d22a,fecb1bef,64f926a7,83951e0f,6490caee,925019a5,212e9de7,2e6e2336,c3e2aa75,9511396c,a171412b,53c8f9ff,3743dcd2) +,S(fdede5f,38d83f9f,a4ba3218,fac6f0aa,7c9f464e,33dc59f9,8a3444e,fc0ed7e7,26e4cd3f,3dcd6a6a,211bc8d0,65564250,49c6db2e,9946dcaf,43cb42f3,b0f20449) +,S(b2b5364a,eaedfe4c,f046193a,6777ec1a,1841436e,3cb17c34,9d27f42e,8e536618,32b886d0,f0f94a7f,1b1d87e7,4f2c7dcb,ba4a5dde,8e93c864,f8f48bb4,50d08ffa) +,S(4c3693f4,52a95b79,85e39982,f316897,93d289cf,66b3326f,3e1cc77e,457f64bc,48d7bdfe,fb8c3abb,584db0b,d3407ed3,3e543715,d4ede995,df0e1b8,52e12123) +,S(5cea23d4,927f0385,57f6bc1f,b926e594,93250b3d,6d934a16,9265ae08,24a35e60,5806886e,b01ca724,8434f2f8,be33287b,d9cb3c3e,b927bc4b,4fefbd51,ba98b5b6) +,S(db0a50f6,b4558c10,61a3ff88,1da60f9a,77b42469,a9713c8f,8339b8a7,b903d93,7afa6cd2,57685f49,9635d15c,bb7defac,d6f94c17,aa19be02,4e2efc70,d84c45be) +,S(b0029adb,25f32b75,8023ced1,632de91b,3e3e55a6,1abb56d5,aada032,f2c01ab5,baadabe2,2ebc5fc6,d5dee65b,262e96c,63c99fc9,13277d84,9ec8a730,e1bbfe91) +,S(c336b077,3ce16975,bc204169,8126a40e,f8cad886,6a52c50,c5081ba7,b878af5,6f46f5e7,b82aec01,ad499340,fb90b81,420b4a3f,977579af,d3eb0ce9,c7d752bb) +,S(f403fde4,7232a9db,9efda1c0,5df49636,2137f5c,aacdfc93,1346dacb,d2501451,ba30815c,197de8f2,258c83d8,dd7ed0cc,cbb5388a,415b8629,2cf5c271,2e75bcbf) +,S(85cd71a2,20beec1,3edd0133,6b0b85e2,da056a1c,4a48a328,f371af1a,ee502c30,d6accbba,491c915e,88474b92,bf23c740,2648085f,88a62d51,b26954b3,f6d2d4c6) +,S(324d65,b3c2bc55,d3b2a125,1b673ecc,d26d2b23,e333849b,7549339f,7f0d9a42,83750e95,32086164,e9aaec58,b6a2f00a,3838d76a,208d6453,14042334,b4af616a) +,S(322033a5,c90d7a31,9439c368,b1301f1b,d088974c,91560063,793b6f2,63b401f3,a61f4714,488bd2bc,84bdb122,c615ac94,a7d05157,e6d961df,4f873f5a,582e4606) +,S(a414ed01,691f2a43,b18dbda2,2d3d009f,f94f8b02,672e49f0,58dc2323,b71f5836,2fa3e483,a12ba874,12d709a9,47cdf22,6b96523a,ac7f4afe,c93f98be,f97ec01f) +,S(774310b1,7752d7bc,d8b3059,f7f4cac9,e661a841,9dcb20fe,355bc7be,3a4c65e9,b3333227,469ec87f,19e14e3c,98148b4b,45bde0f6,698829e9,3bbc9313,56e18b12) +,S(fbb23c7b,5c15bbcc,7ad0118b,6826e385,3f6c4078,5342ea57,11109f8a,27dd11e,b12ec70c,9b4c908e,2538f4c6,b0b3d548,ee199f9a,1e9b6535,f1c78081,41664ad5) +,S(4bf836d7,fa7308c,89b075df,1f336fc8,af3c6ce0,64e1253f,853f623d,c483b400,8b368da,424e5a83,48cfe987,93d47a1e,1e9bbeb7,3f5282af,82e12e4a,c7eac850) +,S(91b4a84a,e521232d,71e3d202,49dd1b3b,d134509f,e3e1ed1a,4e8b5062,a438bdd2,52d30545,4972471e,6900afbe,2471e1c9,16c82ce2,2f955ab8,454f9b65,b70ed759) +,S(9751092f,62147caf,f3953cf4,8a117082,37a78b6,5bf0de56,848da1e9,4c3c3a42,57fd0a15,fe069db5,5fbe870c,96d4280,7b9ebd87,33908bd7,49ba0121,a900b08e) +,S(54439284,6f6d46c9,8ac10a58,ac3c34b7,3cc5569f,8f9fd7f3,4e7ad2be,826bf293,1aff0b85,e5b9033d,7c44e877,57513317,a17734d1,13043cd0,780da032,2dc3ed03) +,S(172704b7,fd7f5560,f17cb6ff,ff9a0144,9a05a113,29b86df0,a8d3256,ce139a9f,a416c0af,b170cdfe,169f894a,b10aa97f,2c068a4f,d70a6878,ec9f359f,e8323bea) +,S(2236799a,a82d4b64,5f412aef,eae944b5,e28e0996,8a243ce5,b8986861,6f735dfb,7f20b2cd,af70cbdc,6aeec02a,dae1535d,4bd919c2,631ed69b,9913771c,2f482c1) +,S(6a52af7f,c6f75636,c33047b8,9f0eec31,66bd97d,8df6579d,2e2a441,6ec4fe8b,4eb0813d,220849bc,e0b948e9,a6efcafd,339f8861,eacb9885,40ff8e1,acf1efdb) +,S(8696e0b4,ae3f0dea,bf6d8dd3,854faa5d,d07b01a8,86f710ad,9b4cd84a,5d61a617,67633be1,a662024f,77931f06,38884175,d2c234cd,c4709637,4711c79f,42a897df) +,S(6c4b727e,3bf9af50,fcae1ed6,163ecb00,142d9a53,b6d3f54c,8aa14064,1358ce7e,c4f2665f,395af262,b30561d1,48bb0f4a,f5603102,80f57f40,1506ec37,2bde79a3) +,S(a51d2296,98aa29a9,6d0e5510,f3e815f9,cfc6d492,dd0b2fd5,bbfdefa4,984a6934,861f0848,7658d4a0,141e9d38,aa0e268f,40bad7c9,e2615a37,7a4b974a,6828d525) +,S(1afc4051,cfb5635f,9c2a8477,7dee5fd9,fc4d40a8,3ebe2f89,f36c0b9d,8327288,61ac4eb9,16567e13,d1b03ae7,ad5c3d8d,ef85bf6f,387c511e,bba6c237,96e95f7a) +,S(f8fcde05,5a2a92de,c65d1842,6607a939,b3475abe,2437c5d3,88387fd4,afdff590,4cb8f7e2,825625ba,e3f179bd,4ef94560,6e186346,61edbf48,8ce51ea8,ce1b0404) +,S(cb3dad82,7e7464cb,5fed0cbf,7e29e6ec,112ea411,706d10e5,c1fe6fbc,a04a3e9,a33abaa7,6c9afe3a,a8ce5add,7a2a056,b396cdda,2a002161,3de97556,a0364629) +,S(39d2cea0,acf8059b,a6275a08,ec3a3664,f09cfc43,f143c317,bed8d751,33d4ba0d,6beb4ca3,d3009ac8,881d6d15,e0a29eda,6738befe,e31707d7,f95eacc5,fbd77192) +,S(90bfc4da,3be2d74b,ff9b5539,d0787bf4,4a1b6d7c,2baa14a1,dc6801d4,42187f96,1254e7ee,c8acb35c,fa0695c5,85f61b69,def3ef5a,6219fa97,e3b09dbb,351152f) +,S(50772bcd,454ae992,f97ac3f8,9d8193d5,ed50b69a,b2e62e04,d6a115a6,6e71c977,f199a8f6,f78b0b97,cc20316f,66177383,64338fda,3eee7f0,f36eb0ff,64accdcc) +,S(afe51284,f033bb43,ac6feaea,9520e83e,f2cc1e42,9e273bc3,1b087161,52ea6926,77ecc481,9ffe6efd,33592907,17d22ceb,f4344c9d,f5f5ea4e,4d443d17,25c8aa1e) +,S(b0caf67c,151b838e,4ecaee09,c7908c95,bd3ef86c,797a5a8d,71cb3bf0,3a46ab17,10ae756,7bd2f6d6,712c448b,34636eea,2c7c3d99,98901308,14825b4e,423284bb) +,S(f2766b4,8cac8f6a,80a7cf39,81725834,d186e88d,735fc7f1,5135ce58,43b3dc8c,63590fcc,a4e21c39,50cd78a0,569c0d2e,959254e1,4bf2ff22,8d8fb216,b53601bb) +,S(80d50e7d,28269280,f8ce0dd3,6afb9f43,38df0403,d5661c99,27ff817a,46f60a0e,22fec5b9,7472824a,9b2ff25a,68d947a5,a8952ae,b763f37f,70228978,514cd22) +,S(18114ad0,7097b5f3,7d788165,e45ca1b8,462da0b5,78e5d37b,e4be3632,35d2fff6,87c5f261,39cb366f,25fb6bfa,fcc8408b,f4c69c81,29df3cfe,9190213f,8c15a66f) +,S(3bd52737,68294cd8,73a48831,8f958e45,85871165,c82cf6a3,9126e378,43975444,8c92d391,e39a50f3,4388510f,c8dbb686,27f29251,92ae8edb,b2613948,c01281ac) +,S(acf47eeb,526208ba,8a3de26e,481a86ac,f17f5f88,81d89d43,ab8a5a26,e00db5a5,b451b4cc,8be8339e,4203c913,98b9a29e,de86a91d,3e347688,53442446,429ace0a) +,S(5e39f375,87a07536,86bcd792,1183c424,20159044,a9f66ecc,2bdd552c,62ec35c2,b7131328,297c6995,7df6783b,d9bc550d,5c553e1,30bfc3e,fffedbd7,5e2d003b) +,S(315b67c3,d980796f,6f0a5505,ff2d25f2,8551615d,12bd73de,b10c4897,580371ba,dfaf812f,7525e087,2d11e10d,612004cb,3e2a7024,8c40416e,5020ef66,82d3bc1f) +,S(8f6764f7,73810396,62537cc5,aed6a8e0,318654cd,a95d8695,89fa471a,edd0d7a0,b91cf5db,2994d207,135c1dbf,b9d9d78f,7e3adea5,8c176630,c09140b7,f5c67e84) +,S(e844b948,118fc6a7,eb2f96e,ece3cab6,def55940,75c7b7af,fcc5603,f2012f96,707668d8,89db03d1,561596da,a831aa92,771a0fb9,e1b21273,d11a3415,82292314) +,S(fbbedfd8,4144785e,fa71e234,59973cb8,87deda88,971eb62a,3007f350,1fd0ae4e,51d23941,cf84f121,ff1e6a5d,651d9528,6ef1d803,819ce64,3aba8d16,67ba7dd9) +,S(a0190399,c692b9a,db172ba8,348b404f,19442b60,4df60142,f6330f36,ca6bf352,6ce7491a,b5329042,25556069,71502da1,601e3a04,f38601d0,80b31654,20fb527f) +,S(d240e135,4b9e6dc9,110a6b25,afcf35e0,74fb02fa,f3dbe484,4f46818a,89bca65a,d704be81,e2597460,6014ffcc,ef12563b,45faf24,3e070727,64f341b8,7dfcdb7d) +,S(39bd84aa,f8a15b0b,809888f,133871f3,c40ea5f,2825582,a35fa9a7,808e5e87,94ad6588,658752fc,ce45ea1b,752ecd02,2b621c5a,26908cf8,69c44584,1d831d33) +,S(2172be6e,dccfd021,a56a553e,53f814c7,c7cdd55f,d181d671,4ade45e7,72093142,b21439df,f7229e61,cd3b7c77,fa750a94,660f60a7,53da96ba,d8ca7e20,69abf76d) +,S(57db209d,a40f30ae,fcca7838,2ba525e2,231343b9,250a1b1f,67fad7f4,d4079594,34ce9bac,bd35557e,2f73c718,4287b493,c524a3a,d6b403f4,ae777026,42fd37e3) +,S(845c2bc3,3683d899,8b90a2d5,ff299064,5214b272,a056ed93,63621406,d3a4cc11,44a46738,839b2e3e,1b6b19bc,56a1ff06,7754126b,20654e51,3a1f13c6,de4c6535) +,S(705af30b,251cc64a,26edc929,e3e9ff3e,32ada2e,69c2cfd0,eefce4cb,a37329d1,c0e693eb,94c0c1f6,cf1a0ed4,8c9b13ae,faba8ebd,926c4fe3,ec9071be,2db463dc) +,S(9b2a64df,9b1f8e,34844e3d,920b1af3,14df1b7,78b863d6,f1a6b94a,869061be,5ff03134,722faad1,ab6f87f0,bc3c6abe,8406bdf3,6506b662,6d066ce1,fa6a7cf7) +,S(494967f0,1a0c07df,e7d9a8b3,e6a4ad13,893a894c,2619238,7384e38a,d514cff3,11ba0803,72bc4ffe,b86e25c8,b69ea450,5f6e3b24,504b5e38,210beff8,5d82e1af) +,S(fd547247,812e4233,55c4a977,4dfecfae,812ef2f8,f3fd832d,a3af2ac9,257d50a4,65ed23c4,d776baf4,53faf3d,d3edf65a,5d9935ef,9e22fef2,53319e22,ca4bf51) +,S(4aa16ea2,68ae95b3,2f405fd9,6fa78478,7c369015,4c124733,a07c1953,874b6246,4306725f,579fc013,2cb8c640,7361c7c4,685a2a49,532fa14a,36010779,7f5104e7) +,S(de6fdd33,8b6eaad1,bec84d55,992a5b74,aaca294a,5f804015,796d69c2,cfe67add,e58564e9,d2cc10e7,184d65b1,7e0271a7,f2e59073,bdca05f,ae664f82,7e6fba13) +,S(c8290adf,d0da5f1d,1805f36f,288a8709,eae0b93b,1a7490da,5ffc29fa,bf834592,ff161787,f096e022,f513afc4,e0b84d73,e7f9f347,798e1026,931271b0,8f1c8a87) +,S(1b95c512,815603a6,19750d6e,463d5a33,55f09c22,56484ae9,8f1c76c1,10ed8fec,93b3750c,3a1272d8,bc9e4c52,b5efb6bc,d794c2c3,939bbea6,1848c9ed,423bb39b) +,S(ac0d9939,104bbaf4,d2eb2560,356f2bd4,f1037ee8,397f0703,b7ebfb49,463a22e3,c6e6d039,d6acc470,c1ee1013,722c4a00,4c59e472,11da3025,49351216,f0bb8985) +,S(d8c8f5b6,366c1d29,b2f28f53,8645b17c,f001ae59,71a19f05,fb6ebb3e,9e36faec,5db24ba,6d78e76b,42262b65,e631390c,8540b72a,746cc5b,edc1b681,8b1a113b) +,S(d42ccf6e,6d1c663a,3dd95fd3,c016d535,c50e394,fd63b353,2949716c,49315737,e7337f22,2d353eda,651087c5,13cfea43,96e9cc5e,22aefb4a,5fb3ea8b,579c7298) +,S(53417fa2,4871adb7,6d875c05,8c46065,681f6372,95d221db,ea76d88d,f687b817,d014e6ea,e00c4ec8,ad931dd2,5cf569d2,efb3068f,7aaf5ded,d4978546,1bb31d76) +,S(202e9476,53b677a8,d7aca305,c52af8b9,d33b1ec4,c5ec94fc,5f7775aa,c478f150,539a24fb,211da532,b378f3e5,cdd688b5,c57343c8,2e03a637,39544c8b,34e3087f) +,S(434f1027,72aa0555,8bcb2f6b,1f64bc8d,72bf1bb2,8b972c3a,f6f342d5,f1493f93,a9db9031,f2d1b8b0,e5840fc2,b4534970,90aee2af,5bbd83d2,c14a5ad8,acbf8c14) +,S(a0e54d1a,f09c47f7,cf56d3a5,725d6777,9fdf920d,3c1dd566,caf71666,de7d5d17,87f5db7f,197185b4,73cfc293,7b0661ce,1ea92099,fbb51151,63c2b26d,47ba97f0) +,S(2d43cada,5455b682,f6430cbd,96a2e316,ac0b4b27,e9fb8777,a94dd2c5,81c0e350,bcf18180,1c1722db,1bd9b8f1,8a1989c0,fb372acf,fecbf9f2,c37ec4b3,b459c916) +,S(e5e6dd12,6340f04,431552e9,903ff4a3,c309ea1e,c498e483,e19b9cc1,37418d4d,58d35fe2,24ab47d,93cd53,fba32252,4a3ea9b6,d96390df,25935a1b,dd12126e) +,S(b112e4d3,ff9adc6f,706cac35,195843cf,302324e5,6aa7305,9c8b5f3a,6dd7dbc7,4fe76714,6529e6f6,b0379366,334595be,efcc7cde,d3596ed8,83e3b30e,780dbccc) +,S(d26b5261,ca7be739,95de1bd4,d75991ef,4d357fa2,5c8d513a,e209ac6f,64ad960,5f3b8e07,74e78bb7,5c395bcc,8512f2c0,1b6c451b,5c8d6ff4,18f9ef35,30c6d046) +,S(e2e4f568,eaf2807e,cf43ce08,3146e961,92271bb8,d6d9b24c,e7315b00,1cf04fbd,56894a02,58093a34,22f2ad5e,548158fa,c55ce47e,d00ede05,40434424,4e204b93) +,S(a62080a4,2d8aa307,32255b2b,a239d9fc,19729eec,1dc24bca,67652705,9b1182cb,ae848a12,893c34f2,260c33c8,ce2bcb7,14fb1438,8e6f3f06,d9192549,6a9ec13e) +,S(684c1647,7771de55,ddea8aec,290c1e25,65120fcb,fc8ce0db,4316dde3,f5ae8d91,ba85dda9,44dcfdf8,cfca86dc,ba902675,3d99e751,5719e579,64e0fa0c,3be1f06) +,S(3d730e7a,afa97950,bee35934,da18648c,d0bd62e6,9a49281c,b63589d0,5efbd2fd,c28545f2,3dceca1a,ad0a9c77,23b61519,44a3c984,d57517a7,cf6702ce,f4dbb630) +,S(337c9584,b49a49d9,29b1212d,dee7ecb6,39f007b8,9ba94180,80c9548,459c48b7,b26db317,3e996893,fe1e0797,f75cd05a,2eb23ddf,4806407e,1f173d29,48bb0bde) +,S(7013edd6,f49ba92f,9c9757d1,d3374229,706078df,c2e9c64c,c2e84cbe,85c6b5b7,e850419,7975353b,2863b577,d6f0c392,a8c5bdb4,2dd557e9,8e971114,5e078de4) +,S(9877cf36,bde592fb,5f4a4581,2bc3c39c,68ac9956,23b3487a,635d6e45,89e26e1c,6207d384,737a0d80,fa9f42e0,57684584,efe1fa4,5cd73eb7,bd50abc3,2722f159) +,S(6d35bf57,1c91a2ca,1765ed62,f9b2f680,cbd0955,bc76332c,c83a7378,4bf3eafd,47a589b5,15a88d78,6f94f64d,674182e9,7dd12450,ab3ec375,a9a31d8a,375e5f7d) +,S(40ebcc0f,be3a2a59,968bf6cb,4d638873,5468b532,80a9c96b,639dede3,171db2b8,c2181816,ab9f0d72,c5cb167c,5bbf7e57,9f17d7f4,484996e6,3a23e0dd,5f5d3a8f) +,S(90de4b6c,3a5ccf14,cb033478,577461af,8c347731,9857ff40,79e6ef27,5e557b87,c534bd97,a4af903b,f307c1ce,549a9976,70edb69b,c76ae827,f277ffe8,133cf394) +,S(54e89b59,b73c76b6,cac52433,305c41b6,8f50df66,9b99f47f,599504ee,93ddb110,d307e828,1e89cba4,86ac125c,1c5d8bc,943394ee,222b4b06,f4e3e5c7,b5da176b) +,S(f2ef67ad,60858ac9,fb03ad25,f75f85e2,e5ac151d,95c96967,93ca080,58756f2d,92c0dfa9,372e1e7b,7363f229,2776c059,56742f60,7b100be3,56dffefb,bcda8cf0) +,S(65b7d935,a71dcb6d,eac70b64,91b9fc50,35c63f21,655a856b,afd00a33,52f5be39,b0773657,cbdd3813,8f50813c,558ddbe0,3f8ad81d,e420401f,175bade7,1429927d) +,S(6e950ff,6471cf66,72ea542f,cf05aea8,2c2e1e0a,c2247021,4c78895e,e291ee22,c0ca0886,f0ac828e,21a5c60,776494fc,a6f19e71,741de92e,c11323e7,e874788) +,S(c3b15f8f,96c0079b,471896ac,89d7d11,8ea1607f,18a20627,fb18e1ff,24ee3c1b,33a033c6,68e3cff6,414835a6,ae3f89f6,643326cc,7e149f56,99ab4fbe,d5f506b9) +,S(9e333d9e,1c022776,da901c19,e6936c3c,1af45491,a93e9405,ae343c54,775f36b4,c6734e91,3d013610,6c77a1d3,ced1babb,a6c6723e,316c3fd,34a7911f,cef616d7) +,S(398d2109,4c0baf8a,ab63ceb,6aa6b64c,678bbe86,f7e01b3b,8c0ff291,450244bd,f1ffb185,112ee219,24a1702,183f9075,471611e9,54fafb4e,36f6acc8,4ac7acf7) +,S(8f99c7d,553ca4ea,b160a07b,6d457058,90634086,80c709c,530aef44,bce43c8a,52a15e23,2e90d233,211d707d,5849e214,1f56e8d,189783ab,3c09f37d,b86a776c) +,S(8d798338,b2774399,487fe227,e2d883c8,39698301,5f01bf00,d154f4f9,296512a9,7cb53de9,9303a6be,9aee01eb,3a5c115d,eff0e18b,2cb5e852,75e9b7ff,53e35666) +,S(c9d6aa,ff6b648d,69416bfc,6e4688c5,cf13b711,29c785e7,3ad1e04f,ba02be57,9fa83446,5405aa0f,332a6aa1,922e3fcb,90de108a,db01796d,9045d423,ca0c2632) +,S(f736cad3,f1264671,f2e79bc9,c21551c4,aaa5da0f,befc1928,b9e7fab1,f59c8c5c,2ceae81d,16206893,b3810abf,d2aedb5c,55b79222,1346cc9c,908346e7,cd3e661a) +,S(7748965,7c1fcd79,60fa4a8,36feef6d,835f960a,d3b85009,7462a71e,8320a34d,cfacdaa1,2906f705,d83212b1,55475160,e02cde20,71fc5c9f,6a6d59b6,8e100aa7) +,S(279f43f1,e26ebe73,34924bae,563a0e34,e5cea7f0,eb9f5702,129fa6cf,8b0c67a5,eb5a49af,bada9830,7ceec508,70a49027,7d1cd6f7,6f332249,b2cf2505,82a2a828) +,S(cfccc083,9bbcc7d3,5ceca575,3b9148e4,ddd4464,5727cf47,26f33d62,d83a6a03,e3cc09a0,9d26889e,c969c734,a3361dcc,d638b17,608baa1c,e7cbb99d,a5bc23fa) +,S(e60b0451,70c2e3bf,dd627fcc,5eab1218,d3d598fe,a41f6bf1,dace1a35,2daeb287,a493847f,4f1d3bf,9e90c022,851bb652,691af15c,f4c6c539,bf2831ae,9cf8f2c8) +,S(11875535,ebc90fb1,eb7a08ce,90dede09,fa8cce24,b3911fa6,44ce8111,8848b433,2fb1757e,38148919,bb197d43,48aa536f,c0f06f9a,859ef737,ea50b1fd,82968ce) +,S(c69559b3,75cdaea3,56003ad2,3edd8ca6,c415868c,a13a30d9,11d4c694,f5822179,a39427b4,914b58fb,dd35408a,67ace872,8c299a39,278335da,9228ac85,24652906) +,S(625ff5c3,1e951b28,40f431fb,4842f510,8b738722,cdd52c4e,fdb495ed,e42f1f7d,a3eb00d7,4eb30337,d3f61ae9,d595996e,c7d5a3f0,ceb39f23,3df0f5ff,43298d7a) +,S(1e2fb107,bbb46666,8c31a927,3ce57baf,fd1df905,3fa28286,196a03da,74327c2a,aa882338,5261bb03,a8d8793b,c8f98330,97c22731,46ded3d8,966b16f,337643e2) +,S(d0cbd747,970ab0f6,19e5e4e7,78709399,b65b3f14,24a084b4,a2dca8ab,10d76ebe,7b5f778a,94d3d75d,57b5e979,3de246bb,f36669df,b7dcc24a,ecf4e153,2025b73b) +,S(ab4c057c,a40b84f9,10142209,a5c173ad,6ef31616,db80bd13,61959f11,b739f9e1,598f12b3,4695bb27,ccb2fdfe,a0911ece,eecf2cc3,1063a3bd,42dd100f,e93c7ced) +,S(f9c11e91,2cd3cf06,d31e4795,40c703a7,4f5f3100,8e6ce299,30d5f08c,7307276d,f873ce74,bab3785,156468ce,3d6a8cbf,c532db23,2a0a92fe,91d290cb,ad08713) +,S(2d95744a,79c4d234,40e2f40c,a83cd89e,61576686,21293dab,6716072b,2089b77f,a25249bb,9dd8a94d,44576a4d,7ed800c1,9adc5e26,82874ea0,5d63bcff,2f6b2704) +,S(3bec0dff,e9a96bb1,f3cbccf,cc96ecf7,e1335b1b,86f13b63,6467fd31,5cc33abb,e31f8a49,dee2408a,2d0b9288,4e381379,9fe404ec,1d8b96ab,39413f82,52b85b5f) +,S(23721d31,616051ab,60287a0c,2b4ada42,1bf00825,127ea0eb,1341beaf,a207fedb,8cafc4b5,40e6f3a8,6fd1b546,87ff8c3a,fa2372e0,24696071,59b6e195,f633b169) +,S(ff8e494c,446cf1c4,bd557615,a4a1ce2,b8d25bac,62a89929,993cfd,51d45099,113e1b98,555ddb77,b8680eff,c57eeb96,4038de04,26a05289,8744f8ca,4f3ef028) +,S(f170cfff,f158e368,81cb677a,c9d9512a,3c1705c4,850d5a85,17a66636,7b0cdf21,49512fe4,3ff0f91d,b9ab918b,808ac11c,b5eeb4cb,ed905f21,adce5e4e,42ebbf7f) +,S(e9ff6261,d6c05d6e,4e35e373,57fca0cd,3c3ea884,4a33e504,df3dfa2b,a524d158,4969683b,9af581c1,963525b4,e8244e5e,6b7e7e48,f85c1fe0,1e9f0dc2,c66e591d) +,S(c1c4879a,b614ad86,cb64d15e,cba92aaf,4d1c7742,76d6aec3,4b59f731,addf6cde,6d7185b8,fc1b99be,383a7a5f,385a08f,d7125e3e,f72f93c,25063bfa,d44abeda) +,S(deb0c036,3818a101,ba38a657,5c0db8e4,a65f824d,57014dea,1c110387,7bf2d9ca,f658d43b,f0c106cf,6b45e552,3fcd066e,e754180e,8510b58,43708b5a,b40dbe32) +,S(c4d4164d,f782df0,f5366667,83e5aa9a,8b05c7c6,91c47a49,14798685,1da3fc9b,6c394d4c,3118c8a1,30bea2,2396562f,6dfcf8cb,8f0a91ec,20a43bd1,548bd80b) +,S(94d83b82,f6db0da3,f1bc24ac,8c5bdd0f,6e89cf2a,bafd33bd,2fb3ca87,9cf63a84,9e8658be,59d64a28,7cc0cfde,1f35b83f,e3e098dc,6212afac,ea234437,2591f2ab) +,S(9de3fae6,e6934304,a84eed5a,58e077b3,76da7310,61859847,d6abecfa,fa650dba,7e4cd395,ea8b90fc,20850be2,4ba8dd83,e79dbc4f,4efed68f,504eec04,f9bcb212) +,S(251869eb,7a567c9b,7866c9b5,a829206d,867f2092,8f3a6fe6,46ebc3d5,2df7d99e,bd87d706,c49690a1,9e0ad77e,4b3b8f0c,5efba7e1,2a448a3b,b4ad3c7d,44e35e7e) +,S(e92e5aef,818b2980,43227673,3d15021d,c84192d5,bc9307fa,1add63a2,8e888a9d,ba3a3157,96ab2051,ad53b5e7,a058f700,ea90e40c,c5855712,d2176a0a,c232f94f) +,S(b6a8a783,c2716ba8,9a37c7,d7022dbc,25fef8f6,76c676b8,267038ae,64a33258,93b09e15,8bf081ab,9e69c4c1,6d965743,cc08ad85,a8eb248c,9c67043f,fe61ebbf) +,S(26e95f26,7ee205ad,50dcc75d,82330877,394c56c,84546cb3,72fecda5,f57c2556,dfc935f8,63840ca4,71bed804,d0c2d14e,c9528a9b,ba1e6f25,6545311e,5cae673a) +,S(6c1ed40d,dd086dd8,2fb00bbe,d969ea90,7e363496,97c350e3,2d0074d3,3e05bc13,854d177b,5593cdc3,ab1e4903,c64be02,2b6b0cb2,25c71390,9316faae,a235b269) +,S(a9286b2e,81030401,c37d69cb,1e73caa,b1c68a4f,4ce1538b,11ed850e,67d11aa9,64ab5453,c3a1166c,18f35115,1f031117,e29b1a31,237cb2ba,51f1a873,529766fb) +,S(a2b862c0,ca02cc3a,e1bc5737,876f81ed,83dffeb2,4e6954c7,3cf97bb2,50050cc0,db3a03cf,d704f98d,dad8f48c,5861988a,1caf439d,b50c196a,32289622,b9a49b3d) +,S(19259392,58c25edd,953117d1,fc7a74a4,a9cc2fad,892255e4,fefdac84,4784c917,b86a1bfc,b7bc8844,abe424a5,b7409abf,26e8ac62,7983fafa,70dbdaef,43a88eba) +,S(6b85864b,194b2cfd,af1d6550,4960370,306ee34f,87c91187,230de0de,42fafd09,54a9ddf3,87458a54,cd305e06,61dd43f8,3911e88a,db6f0256,d19cdf15,3ab4b388) +,S(407cbd77,b88e6d47,60b07e26,f53fefd1,2b98bed3,5403c693,e7ea33b4,cd74b5c3,eb73a1d0,fd122265,dc880cb2,920b4eda,610ff1cd,a74660aa,7cb91323,e5485d60) +,S(f65cd6a4,594299a9,6cdb5f9a,7889cf44,62cca331,d3329f7c,43ecb224,d58c817e,8c906c4a,11925697,9f84722a,9440d2e5,f97e483,542658b6,8538aa0b,f10f5572) +,S(2ea38854,775422db,43eb69b7,bbd47a6a,b8ef1694,28753fa8,8cf49c8,9efc6e63,bf6f2d21,2b21c740,a25dfacb,bd22436b,5118f1a,2004bb90,adf580c9,6f21f1e6) +,S(f2bb4814,94677f3b,6af8aa4e,6a3b1100,c2e0e99e,289536e7,eca3e61,a20793ee,a3a788bb,2a810267,9a3d98f2,6a9a2740,91a3a29c,234043ae,aacc488a,67849762) +,S(e157c4a2,84354b8a,73d5e5ec,58dc1ceb,2396ca3d,7f651e6f,4547aa78,99899daf,f06970d9,5bef3e0b,e2bd4597,a1c96581,275c9719,605f63f,9618816d,669a0bc3) +,S(25aa7f3a,3a14731f,c7fa3b81,31a569e7,4bf32c9e,3492e626,aa4a4316,f263cf12,e5c2e210,a8a75180,31778f4f,4737a0dc,bd1a1312,1dfb40c5,5c435803,4bc3eeee) +,S(73ba2208,8cb96b2a,c23dd2a9,7b3cfd2d,c504ccb6,24c2dfd,5062f8e2,bcc442ee,ab9d3a1c,6bd762b,9cd866ab,7abc0e1,f898c567,61c7071a,d64d5233,caec0ca5) +,S(da94893b,3e73246f,6a72041a,44c7279e,dd8d4d3d,55b20db2,eb0e08df,4c5837f2,6949f652,8601b0fe,e572ac03,89fc3530,6b2d09d7,b59c40c7,a1a607cf,51684006) +,S(908480b2,35c49b11,12bd6504,5b3a8e13,7cbd4820,3046880,1688ed05,abb8b7b5,8a887f57,622a7482,3fd40b26,f58ae7a0,18d2d03c,d5ed31cb,93a529e3,387fec7b) +,S(682d7401,31c966e3,2a8bd150,27fae9f5,4452fce1,360c449b,1b20bbd0,257d58d1,ee7f773f,9d074436,685a2fe7,21b1b829,9369f543,dcac37e9,9adf43b6,4525c19d) +,S(c8661c4e,dbe125bc,a31e7a22,83aa0f9a,b4b3ae70,8512fab2,21bdb4d3,8c89fcb,30299a17,16d3fe04,7f48627e,36195b21,e6800d4d,a26dcc63,96c7fea5,8f25a2a) +,S(5112b1c6,2b88e704,f0d2c731,834019aa,d51a108e,1a8614e4,f6e62f68,d7372b4,1bfb5f8a,ee37bb82,5494c9ce,651d32d8,d47e5a29,4b9123e0,7311f260,9ab4053d) +,S(b9214d34,49e16aac,b90f6704,ee589f6d,8fa45126,be235e9b,61ef3ebf,2150eb99,c9465341,2dbb107b,965d177f,de11bb25,53e8795,69814d17,34ee9ae5,267529bb) +,S(94185601,f959999,1999c919,82e5042f,b7e68583,533f9569,73788d5c,3a087b2,5e51c755,de79b6d2,eb640039,a4268d3a,601750c8,dcd0a942,eafc9339,6fa36c98) +,S(3cdad3b2,2a707d9,90fe4228,adefc934,e8c69a9a,8a4cbd87,844a6ff5,a073f511,f6de425f,26e17045,5589e22e,7824dacc,f8cb8561,832db31a,e8fd2910,558ff9f3) +,S(ca986704,a0d1935e,1611e176,60394d00,7d2aa1cd,cb17357b,b4a557e4,f5a4b5ce,8d527934,a73f2b0d,b3cf571a,ac53b3de,11ac99d4,6ba995b7,5a09195e,b10bb5f0) +,S(f5920156,3ec396c5,82fd6090,2d98ac,2d5dcf5a,cd37e651,a1e80c43,f76940e0,2e821f19,7e27f927,20230f1d,9e26dff,5b3d977e,4b4a6cc6,7482f3ec,3cd5523) +,S(9ced8c1e,bbe0d213,b396fb89,8aa8c24d,870d305d,e9346239,b2cb0315,c883cdc,79367b21,4a2e21fb,1e9b24d9,fed6a0dd,b377534d,4da2b501,6999ebf7,f77de2c) +,S(5b07b283,ca262751,4a10817e,bdfc8044,883f4de3,38cae14f,de955f18,9713dac5,b8d6d9f6,8a71aec6,3b7bb44d,1d2b678c,75ff83c6,37c254c8,3a14be30,a5957b5e) +,S(4c2eb4cf,3fe64ba0,21297b8e,321cac6f,a8245614,45848933,19453052,69337386,35ee2473,1830eea9,85171af0,96b6bc0a,72f3e83c,6d83f8af,8ef1131d,c8b52c8a) +,S(5f24fcf5,f8c0bf43,43b8a0e,b3b6d8f7,2901c902,6d43f8de,4bcb1cdc,6d5019cc,87c2a306,138265bb,59b2b2b5,6992fb37,b2ab28d4,ff4909f,d6067e2b,4f312cfa) +,S(e26bda51,c385a875,5083faf5,6a915944,3eb351a7,88e1597b,f17649b9,b23ab8f5,35d66322,ba25896d,2a14a0a8,a3f5bf91,d3ceab49,9b2683f5,db7f58e,68ca1071) +,S(ae5be06a,b1ae531e,5d2338ca,d929b5a3,4c283035,95282aee,7c3ac259,8196bbd6,f4f486a5,bf11191c,9134d522,62ccd692,cc5c6686,c9013ed2,782b816c,da416d25) +,S(d143463b,4661a173,6b88f274,6b3c20c6,d054683f,9efa5221,ffd3badd,14804880,77b28055,7aa11d3d,b2ac8de2,c9c5757e,d0c9b0cb,af6fca3d,bb295bcb,c3ff8afa) +,S(54804f7,28ff88d0,bf6fb4a8,a24d4eb0,ee5379f9,30f890f7,8e31afca,87f23343,79288e99,a38accc2,c59ff29d,9da5df60,42d63089,45900378,c40dd765,2f0f5626) +,S(68c21fc9,93d41345,484cf5c9,8aa93bf2,25fc2c01,922a0151,cb3e247c,f130ba0d,9c435478,23b9d8bc,2e8ba0f3,8f2b60dc,ca5b6030,eef51c6,cdd20eb5,a02c6245) +,S(2f50b870,96b2e15d,6fb35001,cd8f95a,875cea3a,edf21a2b,c433b254,7798b856,44b09dfc,e0b8d522,17e7d9f2,9bbc5d6f,9886fe9e,3e360688,8d7c4e70,c3bea0ff) +,S(9d054954,f0c22da5,f330b3e0,69310a93,66b72129,2fd3c98e,76464796,847d16df,45962d48,143c94b3,57400130,d3e050a7,4defd464,223ad599,e6aa947b,12679a85) +,S(31980b95,9f51a6bd,4cfd9a11,b86dda39,af66ffb,97713ba7,3edf8c10,462d5685,d0a02979,5b45ba4e,7464fc47,7a09a90b,7265f5aa,e6b0d655,fca5828a,837c2840) +,S(e9c0615,f0444234,1f522d93,eda33b29,8951a267,7c4cdcbd,fa02a63c,a57d1ed9,7aef87dc,7095f483,5ebf2b3,156be9dd,ecedf54b,1b0c739f,c513ebda,5c5f296e) +,S(fec8bd3f,f19fa6fd,17523af6,27384c7c,6c92fa85,aeab8bf,bbdd2178,89b12650,d01a278,6ee8f9db,38b1ceb1,a3fb1df6,b631c0a5,23e92460,d0d51367,1098e414) +,S(2094133c,86322dd7,ee1abf80,2ddde826,e6385342,6bc87510,dff63f3a,b94f54eb,efb2ecd2,13bfda3a,227b791e,c24ff627,17ab559f,1bd289b7,e7db992f,d941e850) +,S(a34c3385,ee882646,b44bfbf0,f64225b2,fb86df27,c616a2ba,6cabbb68,cf36f3bc,e99bbaac,57c9f5ef,c64c6687,6f2bd6d3,b9ec8eb5,f9227c98,9a768f34,23e91422) +,S(df09dbfb,564515f3,a6d86e05,dca59a0a,c353746f,b291d9c,add27d68,6810cbec,90738e50,6bead3aa,c0cc4a2d,cdfb8529,5e752945,a7b2e357,1a99c901,49017c47) +,S(df9817de,89526a26,c61e4294,f245ce06,8b5e22a6,4937d5f9,6898b9ed,74078989,c4db6e86,c6a44091,23227adc,345d6eb7,d2f12acb,f2df3b44,978a1743,94072f15) +,S(2e713387,7a0419b3,7bf77874,b24fd0,7cae9fb1,59919a50,223437b,7746eada,5dcc4c1e,12502573,b0520817,16fa46d1,8ba43ff7,e7f8c8cc,e3c141ca,6176f805) +,S(99826364,f0061305,1ba033ad,63b95884,97158ee6,9542d06a,f2f86d91,3bea7a2,5f109254,24af4592,2ab30701,464d504d,6006969e,30a9ce5d,76a3b115,6158c6ea) +,S(19222e8b,5fec6d2f,33a35fca,83c3b9eb,effb9e3a,f2ca9c53,929fe5f2,a43bcd32,c79b4f98,4621b2c1,d627dade,f01fe761,8af239e6,b80c23ed,a2dd1b1b,e750549b) +,S(e0ea59f8,6b7925d3,ad511280,8b1ae5ed,c0acf6c6,d4ed0846,d870a663,5573970,bbfa69be,ef531b32,5272ee02,8c880178,57ab2a32,65b5a6b5,38ef81db,83b5de52) +,S(7df189b7,c29c06ab,83f7d849,58ba3d1e,7da3ebcb,feeb9dc4,64b60420,3631fdd0,88e00d45,8287fbea,5c14ab33,6a879948,e81d9798,cb82054b,772728a4,4b69e56) +,S(42b9867e,7cde3ef2,b4b73f3,e4df7504,b7f06cb0,67aedabc,16edb276,97bbca58,eab47aa1,df9af0f5,40d1c6d2,ba7edcc6,fd436f56,c944c872,1e1f4958,63144390) +,S(9ffd9a,5535bd30,a697f61e,e6fd0ffe,b1a7e5c1,9459bd3a,708a7112,3a3da54b,79fb0a7a,8334fe38,64fef8a7,60610920,af2741c1,fa41f582,37e92acc,29644011) +,S(13ea8e5d,1116a57f,8b223a5f,79c750de,6c25511d,558e6878,e92cb134,7b81e393,a41efd37,d35ea994,8175d989,cde449d0,e325b40e,a247edd9,e8f4eef,e6a4d283) +,S(110d401b,d7a1a0c,e484fdb2,34cd839d,5e40cad8,6244cdee,5c4f2ba3,ee1e2eb3,cdd91a5,4dfa47d2,98a46f15,c021a38,975ca108,f2653019,46013427,349d7ca) +,S(48a9f1a2,fe29b05e,d419a14e,8ed288de,46affeb2,296522a1,f2407b76,a8f6b040,f1c5ea7,887c029f,67202b41,198113cc,f1ba5617,79afc1eb,db0e10ec,5b5d2a91) +,S(d8c4d9a,feb94e7f,7b831464,77aa4e3e,a48b6af5,35015941,4047cd01,1beb7176,fb8af9c8,da06c2b8,8787793,bd19d7ca,6cc64508,7713af45,4f5fb4c7,eeda3c2a) +,S(34e84417,2f5ff4a2,70a9064c,d5994327,9cefde94,d295f424,2c491efa,bc1f0839,2da40cc0,5120e4e7,8e84435f,895a3ed7,6c507bda,4d16cd14,b602deb4,366ff9fa) +,S(ea802ca2,f07a4348,791b7df8,99639d06,c6db8d15,74ae8441,b29c2d18,18b7a6c8,ea475a0f,5f74e6fe,ccfca44b,ddc38a4e,3cc19c49,e2bffa49,a9572146,6338a155) +,S(d80542c7,a7be8da6,6346d867,4154f65a,b1cc8e94,19299d81,6a5c874,f25ee43f,5e85d69f,b5c72ae,bd94b1e4,67e0d30,df8da61e,4150f4ec,e3efcfae,78d88d25) +,S(bdb35e49,7c1c0d1d,7a120366,cd259e7,31cb253,1bf804ae,f0c82cdf,561d0c0c,2675a4ee,aea6dfed,8597c08a,69fc251b,7bad9869,e83f485a,73dd1638,605915b0) +,S(5174e27a,9a1eeafe,6411f3af,b627223c,db0da11,6bca0ac3,d39a3080,815e22a7,b1223046,5f58d183,fcda2603,e4593398,51ed87ed,6839d9b0,4c845459,daa3d5bb) +,S(c8b1299b,1b2880ee,7720ad03,62588349,44bcc309,6a7081eb,ce10ef20,ab1f6731,ead86be8,85584e4d,34ac18e3,d787031f,72feb217,694a32a0,76f2f88d,a04f3440) +,S(fc1378cb,c42fd6e2,f61be9bf,e60bb2c9,b36c5a0a,4aefef09,c8287a3c,f1310d31,ae4ff85e,5b22d2fc,914192d6,28324d12,51ffc469,1ba8ca13,f8347edb,5a9170d4) +,S(7c0bf943,23e7c1a,8004b23c,c05327a4,d4127c7b,eed27e3c,4a825e41,5f3c3a6e,30ad62ec,bd19f80a,a9dcbb5b,145d18af,3248eeb2,1d14e648,d7fd7217,f1089728) +,S(2ede5f01,232c0409,34b07b70,1ccce3d8,27f85ad,2a56c987,e29cd6ee,d841efdf,24cbe9f4,69f036a7,6e140720,f65817dc,847e9562,4820dbdf,b8a1384c,8d39bdfc) +,S(decd1afe,faf01eee,d2dd89c,bdb9711c,4f1899fd,437d0371,55cf74f5,9aa0858,899d1c8c,49b0b3a1,89a24445,568becb1,d3b1420d,ffb2c7a3,8fc291b,258f8ebd) +,S(1dacbc1,4be6e70c,4043f5be,3f972d36,3cb456a2,2ee1b1ce,3e207578,8233a79f,fc3b04b4,f502affd,37d71c58,d6f1a61e,b126cda0,e156608d,7f2ab786,e0734486) +,S(12ad0f7f,cc7cddd7,60cc6a3,3fd3de83,b1ab0e3d,cca013a5,68d5978b,a176cc19,b4e0cf97,335b374,661f6c21,46aa7315,a2c4f6f2,b839f88d,5376e256,99e6e216) +,S(f649bb96,e477a5f3,f852dd31,65496c07,5e14a85d,fa929794,64f1297b,d56fd1c8,46e37dfa,7eddec82,88fd18eb,9ac200e6,79337296,e2cad24e,d67f98a6,2e61d040) +,S(34f5e5a1,248db96f,a165950,a9b74392,acda22d9,95496808,82760daf,642c600e,a8a6637d,a1cad7d2,f72fe1a,df67eff8,49d0ab0d,7e06d7c1,a11078aa,de9dc733) +,S(26e940f9,ab45caba,adb1e4d3,23e5cf70,575c44dc,dd2f0b10,1540174d,d2aa715a,972aeeed,c5fd01ff,3b04f236,c799039a,9c7fe6f0,db1348e8,b97dc885,c57926e5) +,S(e3ad36a5,132f1067,503498e1,ed4b315d,4d06cc67,3a9207ce,47224497,12f51a4a,4fa719b7,37cdf1b1,cd5b963f,16a47e6a,e43dbe0d,490423de,fe5deecc,5baf9e8f) +,S(413fd0f9,4e231525,1aae9d6f,61aa0038,dbf7cc03,10c81185,394c8cc4,8b721a9d,9281c5b9,ac1f56f1,50776cf4,69e57118,8cc6989c,ae41b950,f72ff25a,d6de836e) +,S(9841a473,600446a5,5ce0ab4f,2e77ad12,bc2abc34,1e607241,c0c61d2a,d87148d5,7d1bb113,ee4b5199,95231834,1e05d87f,f9bb355f,df958410,3d161969,1d786f4c) +,S(1d4cdc2e,3e06c052,69958eba,f00484b3,36594f9b,be1ea98c,2382e608,cf78272d,6cf5d126,766fe5f7,75bfef7d,c2d91b48,66d4bff4,c8eb4e59,230d1903,16ac6bb4) +,S(da74f388,86de9c6e,36227258,758111ce,3b9414cf,cf8d5cfa,bcd9b3f5,44f1262a,d9231255,e3d9189e,a8d0344a,80978b83,3f1afb57,5c799f01,8b4ab73e,866a38fa) +,S(b2ebf119,46e37704,e1e12345,c68f70a9,a031c0b1,e85c0833,c5df9c0a,b836a6b5,c1652832,1666f0f4,19806a4a,86f4aa8e,46fccb4c,f7b6493e,26d9699a,9db2bde4) +,S(9fd899da,eb6f84ac,edfdeb4b,fbf8b521,6b5757e8,10d22d4e,56afc38e,da747cf,2daef35c,7ef36b82,d6158256,2466895b,9656970b,4beee8cc,2e0b12da,83d7af64) +,S(eda65e56,9cf07e84,19d07f6f,4aedd24,3c46df2c,bac92772,bca7edc6,ba17b217,1f394c99,b48348e6,fb709e5c,b4b4b77d,41eac2aa,bea2a4a6,353d1982,a9985281) +,S(78567d1a,1a96df56,299c9ee2,1d916472,303178b6,9b18fb00,a23c10e4,f093ed5b,9321fb0,6c5d2dc8,52e64d6e,453d9923,bff7c626,efaf5e50,245b4ff2,64158f23) +,S(c639e1a5,90f5973f,148e96f9,15c94d8d,7c7ec36c,bdf15150,83503aa9,9ef5636e,3620e7fe,faaf7581,886776e4,f7391599,94ae3e2f,2a59d4e1,ad6d508e,f4db90d4) +,S(73ef6655,c49894,7aa2b63b,89b77f14,3ac096a1,d7333494,d9774ada,5467b60e,c04509b6,2135fa8f,816436e,6ec0f513,ccbb23f8,782e2ca4,d5eebfea,6a5297af) +,S(bfa4506c,dca70a3b,a8fb0188,e0384bf7,3afbaa0,6818d503,df5015f4,f10cf341,9fc7388e,2edd63f7,9a5d328d,1b949a2c,a364075e,f94c8de8,37cda5e1,7d566ba1) +,S(2d594b,814a9e92,7ac9433f,3400c5e5,1a58457,6f47b8f7,f5f0b8d8,f48b2cb2,fa9a1577,d565b906,1acb9efb,4bf415ed,f264b662,594d1ccd,51baf83f,101183a7) +,S(401ae44c,a4039850,4d57390f,66044f6b,cf1e9fe9,f0f2b057,3f64f026,b6d5f3e6,ed947768,36ce65ec,f947b81,9dedd31e,c8ceacd0,16a40a35,78a592bd,4c2626f) +,S(43f9397e,a000ac26,8a315406,fc9cd047,b9cad513,8a7dab38,2717744c,ec6662b9,14d5bbe0,52dd8635,29c0b0b2,dff7379f,3e2ae95,6c5b4920,b36452d9,56085bca) +,S(25036a12,d8eca48a,78cb5e84,41aa5a53,16376e83,e2ac7819,db9895c4,dcf2a22e,14c421de,dcfdf9ec,b69a24fe,1c289ec9,f4d0f9ca,6f4b9409,35ac9815,a4154209) +,S(30e9c9a0,d9b9c92e,65794acf,a2cea34a,8d56e3db,d5b56205,59100128,26bf8991,999e4729,bca75c06,18f0bf9e,8ebf0455,3460031d,4ae47623,5e4ba182,2f62550b) +,S(a8fb641,fe27c40a,8e410831,fe1b0d2,cf74072a,bb626b19,2fa51341,e99ca538,f3832ab3,4eb6917,3e2f3755,366b2bf2,4dbe257e,eb516e39,4bfb91e0,a63cff8) +,S(5e09a349,98a824e2,f3ffe2ae,34a835ce,6b2f0d28,43b765fa,8dee010,49df7867,20ea03e8,4817593b,931d1612,2d01dc7e,52715fb9,36838de9,d2c9fb69,9c935025) +,S(e62a12e9,d02a5a7a,475dbcc8,79850ba8,340b638b,a5c3b505,8d3c7ffb,c90f0dcd,b075d21b,40e5897c,7e849529,bceec7f1,d5f87881,318c115f,acc99680,31d17f55) +,S(45aa5534,530265c1,c358b529,de15487c,b6bef551,5125e835,e027b0a,a69a9cb6,2e56d88c,acb32ed3,24068fc4,4c03ed2b,1b70392c,9facfc2c,2fafc696,fdb8d397) +,S(7fe3d940,50e2f358,31b410ce,e54c7c82,5eb05553,981f1c45,b136a24c,4d4a4b57,97b0cfad,4f6669f6,efb2d35c,42302e10,87c03b3b,1c22e23,24050399,345165a5) +,S(110dd614,85bedfa6,c09a2e5d,5737ab2,4a5b35aa,40129388,c6ce876f,bd3d9c30,7972ec2c,621155fd,12f0a1cc,30927669,13a9165a,7dab66aa,8f8fca53,7411041c) +,S(7427d28c,aecb7a35,a4100c42,9fe03d5e,6d3f2f91,a5067866,c618c4c4,5fc53547,8cf74ed7,1324616d,bf4135d,8f442ba8,b473ebab,fe981f2,3a426eed,bbbcff16) +,S(9779c811,98040c8e,754b9df4,b547c09a,a9f25410,1ca1fdde,365b0ef8,34ed95aa,148280a1,d26c8ff9,51774c55,7590081e,36030a10,a148c322,3c7379,67d036b8) +,S(41113833,f7da3a4a,4736fa62,ad7b4508,74ef5b9a,b0961665,e30f3081,7d861adf,98399ec3,485a984,cdbb6817,783223b6,59884450,881d2f41,3f4e59f0,ed5fbc65) +,S(f9830e6b,9a9a9dbe,50abcae1,d44d4856,3a92e505,aefd52d9,2259c41f,4b8b14bd,12061be8,5a0042ea,1baa46df,b36d6f78,62c11cb5,b8a070aa,6c6a8991,62ea1c0d) +,S(71284b2b,36a4c8a4,40fdd713,6b647482,bc73d680,3d6d0142,833d34bd,f2794077,6e54f5fe,8cff4ebe,bad1b47c,4e5d6407,44be9171,b391492c,df48bc35,10e195df) +,S(524a04d,a1b7ba04,34377531,99178ceb,7ea18f36,2c300aeb,a8daefe8,6e63e9d5,1c71ed93,861c3b1e,41a7fcd6,57225e92,b2ddc507,4d54652e,3898683,8c3688a2) +,S(e1fb70fd,2057dc3b,c545fb80,eb91cc9,479cada2,93c3492e,260b0a75,4bdc0222,aa799a9c,25786c64,d5138ba2,1f801e5e,88fc2602,d4e288f1,96c8d79d,7bad2278) +,S(2bf126e9,8302e8cb,407570f8,c3fe1206,3c91bf2f,63cdd9a9,3dcc403f,a8592d29,6452a6a2,20edbb86,3ed65ed6,cddd70d2,6b4975bc,e843a41a,10ce6ed3,d38591f2) +,S(faa217d0,1d9f0517,5950dd5d,e02972c8,b2c88076,36090d2a,6f17e7df,2a70cd7,73077022,dc1cb45a,f9e9d056,19635760,66ba7b07,bc79601d,ae7dca1c,a6cdc033) +,S(3d184ee0,ed45af08,6a7263b3,47b12449,a7270887,b8460b7c,6428ae4a,6dc4836e,d002efdf,1259dd8e,ab5bb606,97e8892b,4cb5376d,c26d08e,52b7c9a,760e8826) +,S(3c825a76,29890675,bfdcdb73,27f37c4e,43214a91,c6ddb6d0,f31e13d3,cd26eae,45bc7ae4,649d70ba,99df5d07,92e89130,87a272b1,bb2d6043,dcad0fda,a5444fac) +,S(3a8822a8,d5b230ef,62f657ed,31a12d63,2862f22d,eff16f08,8065981b,ed3e926e,ddca63dc,57ea2ecd,b25e8d03,2868b12d,abe8f7ba,8125a4c5,56d80a9f,9784a04) +,S(d0042da6,aa3b60a2,463e3396,98229067,c80f8924,12d8323e,7482ff2c,53ad86cd,40697e7c,4c5d6c,4ba11cee,fdbae25c,e234ece6,7db446df,daa03025,5f8adf35) +,S(a06e32ee,93d70c5f,a45a68e,2a180be4,7d8a7f60,17d035e,47c94d47,6f3838df,f4bc98ee,c7f50d34,4e88ee87,d8705b50,4cc0fd5a,5bfba498,5fe0699a,df811bdd) +,S(21426073,9f41da95,2dcfa74e,dbcc2f22,375fb359,93f83842,99e3735b,e39b45a5,697f2d88,74cd2249,cb84c9aa,16d20956,f5c40358,9d5b7965,ea4b46d1,9cd61249) +,S(84d52769,327646d6,13e3e1ec,2d20791d,76b765eb,fc5fafaa,20097164,dc9cda7e,d87be4b4,2e2e55fc,8f87dab5,c8c64493,f09b3996,87ef8fb,3a6c653a,a2250cf8) +,S(ca48382b,49283747,d433be3f,ee0569ac,7d3714fc,bbd76157,ac5229ee,ee25dd0,b67165e7,60894bf4,3cc80df5,6e3109,db7e370a,bebc7503,ce20836d,3f0ebb2d) +,S(8a6a751f,816c206b,91e67608,58fd7def,8ea70956,598b1c61,8e0699ce,602cda79,617ea6f1,c7f98cb6,41f01862,1f4c8cf,12a556e5,675765cc,c7bb1283,cc8ed073) +,S(1d035f81,fdc7c483,9936692,9bebc7d9,15fd3c0a,380f3348,13c65527,d82344ba,e4203070,f687298d,af8f6d66,6030f3a0,5826b0b9,31f0e55,8c356aea,b3464712) +,S(d28f1a4a,1198f572,a8130bbe,3f25e585,348a33c,2d73053c,ee7e29de,8a3ce79c,2841bd4b,c46c772a,57018c74,8510fc7a,dab16644,f157d51,9c38391c,4470f7b7) +,S(41c71a1e,eafbd926,4a49ba4d,e976e72c,691026a2,b1773d4a,88670b4f,d9c57fb8,c2b198e2,e4557f8,41203c16,b511d61d,b39e8a67,21b776e9,865158e1,91ea5ac) +,S(3f0ae72f,b1a06f84,803ff8ad,fa0e5c76,ed0b596e,d52568e2,6fe4aacf,6cdbc3ee,69a9dc3e,a0ae93b0,6c4650f2,941ebe38,fcd4eba2,fc9cc0b2,3fb9c127,81c53f78) +,S(b59e2f6,2f01449e,d6728b04,e9334f10,54c4c8e2,db4a422f,70566b55,ba4d2e5f,1b6b73a5,7444de3f,4137f2ba,722e70ab,e6a785fe,1ead6fae,9f2ec5db,299f00d3) +,S(42145fda,e72df9aa,fa3c20ff,cbf11a0a,d357515e,ec6846a6,5cc6ffd8,8fcb1347,4a34e518,c9d39736,3c88ad65,62ecc0ea,2652c6f,48955852,99a0de0b,5f42b6) +,S(17a085d7,8d8013f9,b98a8509,aad7553f,bda81df3,33aa6f7b,2457a74b,c83f6739,412d9b80,efeca81b,29619ca6,8bdcdebf,7cd253c5,88793675,6a379655,d10df76a) +,S(f5ec770b,2e0d0afc,7b155abe,bf310270,28bdff39,a08d113f,b0409624,e7049ae0,e9ce5d46,2dc5d255,a09ba37a,a7a5edcc,aad29ce8,6f9c6b58,d2781e81,5d88a25) +,S(45e3976b,749279e4,486d2db6,fbbc7731,168e7311,d7d75f62,b754839c,2fd17918,84f0c079,c0127eb,d1064724,927459d9,ebc22eb3,502a99a0,e5876e15,29c8845e) +,S(df15c304,378da361,7f821d07,d00d1bdc,189fae9b,7aabbc71,51c2117d,8fe0c21a,589daf,cad5cc54,58544b9d,a69dc510,9f8f1e82,866b1076,ff1d229,5942deb4) +,S(c5798ca4,547cea39,75e3b613,911434e4,e5f503bc,9ec6e9a4,8dfe8386,a371494c,2864334d,fb2bff0a,4690f2ce,d1a1d1cd,e3b13f96,325f295a,8e0d4f1b,b13413f6) +,S(773ba0e2,e1a80ca3,9060556e,2fa8d15f,83dfd018,dd226751,9262651c,9765c915,e59a686a,3fd13284,e380188,fa40e9e8,28991374,20c906b9,ae882512,7dc7dc60) +,S(6ed4cac2,e1685eec,16c12251,db5dbceb,90f542e3,854177d9,83ee6024,d6e7a740,2558db33,ab598118,1802a84,e6ed32ae,49c25379,606a3150,6ad03ec0,a5308b98) +,S(21cfc6ee,d98915cc,1bb52da8,e83aae9a,64970d4f,ca3e70d1,6536043e,bfb60fef,8154f487,290cb8ea,73cd147,c1286d5b,9f471665,d9e0ee24,c2be264a,2f1fbc36) +,S(f8db764e,bb8f031c,88921a73,92f75323,7d1f4a22,7bc8cc64,8bcfa9a1,235cdc11,82c25fea,2d0a1e37,e16dc4e1,b6737ee2,281693b0,b48911db,c79c1470,c4e6274f) +,S(d52f4eef,14a5a860,983eb0ac,8e02def9,53f2ba03,604cc60c,80882e56,ad6b3dfa,b34b3131,7e37b973,9559bc2,6f85226e,705bf06e,1fcd818f,d5b88eed,f2d6b7ed) +,S(3e9d0688,b9b67517,e25b526a,4e46be08,4e95a171,f9d99ae3,4cca6c14,66adaf6e,e1938d76,c4349375,1d5b9876,4ada7b7f,57144878,78805540,70b7c27c,9bfa312e) +,S(c74f8dab,54590ad1,3fff217f,b62f43ed,7f42ffe3,6c8fddac,fb6315f4,a3406094,1bd8025b,57dd382,5b5b6896,e90ab5ba,fd31ef46,8f02846f,29f1b1fb,f90302d9) +,S(71f88089,a8e0ac,6cd92e03,b1dafb04,76c0f489,f16def9,75985abd,5dcd02ed,839bb263,7827e6ab,f6941b53,67c9aa09,835c588,3956733c,267fb52b,6be767a9) +,S(983d1cde,7d75d70e,328a8a62,ec82a96d,5174ed4f,c9676e10,7c282be7,bd408b07,5fe2426f,287fd353,173c699a,39407e36,c365c413,76986640,7c12f11c,5dc436a) +,S(3cf9defa,a067fd0f,6b012fe9,8b05aea2,83c332e8,cbc8296d,c777951,9e62519a,3fbffaec,c77d872,7dad2011,aa314690,2806f763,b73b780e,375508a5,c77a613) +,S(f415897a,cf653c3c,26fc5231,f375e28f,c23041aa,af05455a,e81419dc,25546e30,3a9d5669,806ef66b,7a0661dc,cb941531,d81fa7f3,e08fec72,ee6312fc,4a7f59e7) +,S(5bfb64c9,cacbd09,244f3a96,d5a6800c,4a012297,95962fbe,a429b659,8e085eb1,e5c4ecb4,9cc4c685,a4fadc80,77889298,b94e779f,7f462aa2,130ed8b,ccc0604) +,S(61a5a78,a086ccfe,9f54cb0b,750b7c8c,5c8dc4b0,e32f3c69,c65ce4f8,9009587d,50193c13,affe3a34,1ff3b8a0,b37f07f4,b49667c9,f8940311,9ecec58f,a76d8c60) +,S(e74514ed,93784bda,ca6e30e4,da2a9a78,c7c70bf9,42cb4ba6,afdc357a,c694ed1d,ee4a8c9f,7d55dd09,c51117d0,754d301a,cc36dcb,49d437dd,ca46a920,7088440b) +,S(dd9aa58,f2cc4c0a,8d2bf548,6dea653c,b4671e40,c0073df5,352b2a9b,95637617,6478aca1,582a65d2,6c0f42e7,48f06e60,ab85a494,d0129b85,5b5fdc62,7dc7f580) +,S(fd7f2622,665c2005,9bdb8c46,d140ecda,ce013ada,6dcf3503,e28eae44,c2dcd83e,536c948e,5db2978,31e2ab3f,fee860d5,dd7fdd16,645cf561,67e484,f4a62c61) +,S(9635dbcb,b2595930,835598a7,149a8a37,be64f607,c227b307,4d8e8184,c2ae99fe,1b2cb226,bd9f23d,bd243ea3,eb57baac,163f4e49,6272d220,9f436f81,7b6d9442) +,S(642ead1c,c24db5c4,77d798b1,515083a7,7777476b,c3a03993,883a7ab5,e1abf814,185293e9,6e6dcd7c,209fc891,d96f9dfc,4012f756,7d3e2f1c,282eb0fa,5de46eff) +,S(3c5be7eb,3aeab34a,2d982ebf,3a766962,822ddb39,527ab79b,83540818,a4e2931c,a161ecfd,2b906280,46d6d1de,c149eee0,e6c92ccc,5f936a51,e2a4c3,82e555a9) +,S(c1a90946,6c0ea8e4,b60611fd,6c61733a,6d90b0f9,d1b7a761,1f9e3e84,6423bde9,f928d301,b6c27eed,79b8a8a,ba388ef5,24b17220,7ebd7396,5623e60f,f650dcf4) +,S(e49d97c4,2ec1b8f1,43180188,382b265e,4216bdcd,82824a15,3a0e1d73,83207541,8e521e4b,95a1f4b0,934753af,cc3b73b4,7b3eb00a,a9c7af48,7e4e5a02,6234b733) +,S(49f71f26,f0d828be,9e9a70c1,bf768117,ad2fe6b4,6e9f416d,eaf17695,80dccfc1,86f4404a,67e8e6a6,9a901589,d7c09873,eb553aca,41b0cb66,f4767621,76ff0d79) +,S(487d806f,67635c8f,b66afe46,3754a5b4,64afa469,2ca69541,5d91a6cc,8903e853,b610d414,26951e55,46bb7216,6dfb62fc,602b3d20,18c38670,760f55a3,6c45c688) +,S(47af5aaf,cc7b69e4,bc536d57,8f57b958,3fa17666,2d302141,54e3e35b,57357e38,b79a4c34,709d215e,dd3b0fe4,9cde9de5,b45ccdd2,af25bbd3,602a0c90,9834dbee) +,S(84f79cc1,a257fcad,546d8218,5caae7da,8a8d523e,7feabb79,16ad7d8f,5421575,cc84b844,55ef03ea,59913a0a,1919c0d,cde9fd92,ce872029,57a998d3,80ec1986) +,S(550b7e54,3d3accfc,eb488b6f,b2b48d0b,9017a5d4,ed54d55a,72b8ac6f,c83f6d14,91f318dc,ea83ec1f,f43d5172,bba5ab1,7891f3e1,2e162b6b,8c512589,5f2e5141) +,S(f691885b,eece383f,1f56593f,92de0b34,1627cd58,389afaba,f442663,88aa6a32,1e6c920d,2eb76656,63c7586f,7907471f,79e5faa1,b6fbf4a6,c905e422,9a441638) +,S(4e3c52a,96889e52,b99aa469,b5f07dc6,f6720e49,29f3961,fae2c59a,98ffacf9,ba3a3d9f,dccc36fd,a8642167,7f54de2d,4c079b2c,e70b46cc,926d7d9c,ef1978c4) +,S(66720c8e,c638367c,c934347b,d8768338,54eaaa01,a81a876b,d2321e41,40381224,eb595ebd,67c5a08b,24482042,5035ecad,f20fcfe8,9a84a60a,93f3c05,a926d574) +,S(4b01f86f,f9feb661,eb33d7eb,87f940b,74302cb7,449b0bc4,84e97af9,56b79d2c,2680db84,1b233e25,16b74190,fd3a0cdd,b8fce285,ed8577b1,e13c2205,9af0d3a) +,S(dea430d,6a4b5e18,fa04f77b,55f85d36,df9dcd47,87ad5899,c16d2533,74494867,46b1f5b6,307a1c05,f3b42ff,e7a272c8,c63c2a92,19bd2971,d70ea793,5bd508e8) +,S(3f987bbe,d7fe896b,8a8067a6,de49de63,670e7260,f255e5c8,a926b9d1,fb62945b,373b2f51,86d7d9eb,18570d3b,9e48756b,663cab9,df388899,7af923c9,bd79971d) +,S(6cbcf291,56e3cb2a,b0d3c03f,3f4c0283,d953a641,9f7e8655,d8c46566,e3990b70,535c1017,fb40108b,24de2a8,358d217,8e47961,e5f4cca2,aa7e7c2b,339c60b0) +,S(d253488a,5610a541,e4ce2cac,bf4d4901,5fe63dec,94615e80,d795b39d,9885201c,c58ac205,e7323ca8,9bfd284e,9c9bcf3b,89b05571,b84d3afc,d69a9a96,9ae4fcc6) +,S(bb77470d,cf0851b2,29494d6b,e69aeabb,dac44010,17200af6,391cc2d2,352bd9e7,187cc653,b6b56e6e,6c9969ea,705a6d9d,3539d4b8,b8777371,b64deff6,45307942) +,S(438c5a3e,1ede7063,eb928da9,693d7602,809b9e08,e49951f2,6a600eb3,e929ad1d,d2918af0,67d34eeb,d8f179ad,2f3f105e,a5cbfc9e,1f416cec,372a5175,8ae797c5) +,S(35db0905,e28b3e7b,b8c4425b,8d9151b9,9cce6a6f,b6e11561,65b7e356,9191e69c,25963fe,ba45cdbf,5472c046,3da3279a,60a3f1ca,9ace47d0,4c4648b1,52d2e560) +,S(6ef2e9b,79e48447,7532ba0,1b658af1,e27b13b1,f1635317,6b47d994,cf3c6bce,88cc8a3a,aa1f2040,7976ae7a,9bfe09f4,f0c1fb85,72f122f8,4aeee871,b87867ca) +,S(c85fa35,4c064f00,ac39d455,7884f8a6,420c4192,aef2d6af,8afd61ec,2b977b33,3d17f849,6ba4a79a,bcdaf502,87fa5fe6,15d2c24e,58f27ab2,7cfb2d86,140a5f0c) +,S(7f47028b,4e84f4a4,21909f01,85df2743,e3f18f1e,134f90ae,166c4089,a9d44803,4c025c2a,c2a1af49,fd7e1e3d,2ddab9ed,104a0e21,17895fc,36eaf9c,7a550e9d) +,S(6ecc57c0,5c7f6b98,6cad9c94,435664e,3b036ae7,325ea091,234ac216,3dd0e324,67086288,9346eaf7,e6bc8ac5,25d60d5c,41bd9701,f5cc5f58,7995fd6,1c75def6) +,S(46a2a28f,61fbbf15,c3afacaa,e181f527,2b957bb4,7f127465,fc03d021,76359328,88b36e79,2c071ec4,adf1a34f,a3d1114f,f9813f91,39b2db5,83320bef,134ace83) +,S(a2072cb2,e25bc045,fe40dead,8fd3f7d6,449f8d7b,57adeb47,b6ae9b7f,7d6a5b2a,fc019c0d,8c9263f3,aed518e4,44c1e5bd,dcf796fc,7d16cc6e,c90c4c59,7877e36a) +,S(fec203e9,60d4ead8,e3510545,3e73999,1ce5234d,a92a20f1,813414a3,599874c5,118cddc6,fe918be8,d2c5483e,c985aaa8,4d708767,4af70444,1fc0692c,b92a540e) +,S(fd166bf7,a69d80da,6e03c740,2ce6f4,a05f1df4,e2a131a,daef89a5,86f73681,1e3f6791,7f2d3824,ba4ef07,86ed8f08,c65860a7,e6913fd6,8cdd759a,2deabf29) +,S(a479787d,b514baf5,b46a578,6a221d72,2eda896a,a7fc1e43,4817f125,2bbe0d6e,1a6f7857,92bc5fc4,e2fcd87c,6b82ed34,20426f30,a9c6fde,4f09ae14,9ce426a1) +,S(7aeeb17d,f75e9c7,2dab575d,2ad1cf87,b3eedf99,8df4b14d,d42b50e3,7895f041,8060c0fd,5f903934,d47f3886,8731ddfd,a6fc1355,53be9a44,38418174,37b79fbf) +,S(6dd254bb,63c3fcc9,a5d1758e,90c0c6d2,bb1a19ae,788b351d,191d0261,cba75c76,b00b5cff,f3246b0f,ec835345,1d9df948,4fd903d2,e278ac2e,59d8ca20,647c2ba0) +,S(d9e76bea,acd64f55,9a9c2888,5834317f,c24fe5f6,7e540d27,6233c187,76cd7323,4d079fbd,15ab81b4,f3aed0d,663178c4,33f976d4,f69af7dd,ecf61a13,b831e71c) +,S(b57b26a0,55c4f224,865b22,287c9402,4c801618,c50b00df,33ef8509,a94a0f57,5abc4303,1701260a,f41a0e49,a100da19,8d033179,8b26026d,6401654d,39d53670) +,S(e03c71c7,9d902be8,5caf4df6,aa401a6d,18592725,2f10be1,f4190b67,bee3bb8f,e5f16a54,ce5772cb,1390e49f,966a00e6,893ceadd,5a753c7f,9d82a2ec,7324240) +,S(b7f3b64c,980f19f4,e4f46083,c1ca758,70f4313b,3c23c5b8,6acd6c8d,57ec0de4,5fd0d8f9,2a70c9aa,bcc1523f,91fa603b,e17fa73,fce73899,2c1d720d,3d55b1ca) +,S(27b24868,2a1b9186,3a1f5c9b,a5010a37,2349c417,e1d7acaf,dd94c7db,c5e12733,c54c23bc,4e17418b,deface22,b8e527e1,4de1aee9,71c921fa,fb3f58eb,e4778125) +,S(5d4b2b1b,5f9e640,bad96aec,6d3bc5b6,169411e9,5dac7346,d1f7f885,50679a14,80f0e3e7,7e8d6c48,62b1f6c9,c0ee37a3,3b98be7d,e1c6c8ef,12759b73,c20a2e3) +,S(790a4189,63c3ec0,ba6babae,18ddb717,463d3ec7,c0b01852,5e760e96,ac5fc2c1,6db8b456,9f2fed97,783a6e80,413d8ff,cd0ac6e,d512f712,4cdacad4,4845242f) +,S(38dd209d,705c3f63,9cbdb0b4,22160943,4ddf1366,56f2cc8b,22d27479,c5446f99,8b793f60,3621f6b0,1b1ac36b,cfd92c3a,7dffb7fb,fcbf831b,1db077ff,7482c25a) +,S(29c6b2a9,24f95c8,58857951,cea2baa0,bee9866d,77b3f7d6,3cf9debb,16437528,c408f565,cc78e5,15a6e0c1,7a96392d,2952e25b,d067a0f2,d2f10eff,b54c2ce3) +,S(19f1ab5,b54c80a5,a32a1fb8,1bb3f389,ebb53641,6c8a844d,3846c2cd,350420c0,38a56a7d,7eaf4155,4f5b8090,c06fcbba,9f516a23,340617e4,dc5951d3,35b75de0) +,S(fa3d2b8e,d73ab5c3,24980054,27830806,3715c17c,7981db6a,61757048,1e1d780a,7bc0b4e2,4cde1ca3,e30ec601,73121a43,f87f679d,cfac6db5,a9bd132b,d6a89454) +,S(908e538d,730377d9,d3585ae,59b0949,c46a6aca,bb04e725,70b189d5,57c26825,5e108800,6cddf00,39f7d855,64252cfa,d4a37761,2b58b6b,5fb2942,7e274af6) +,S(e57bfd8,f38d456f,2e977090,d9f81673,db11a195,568a85b8,dd8bb725,a30d22ec,b5965e5e,e680e791,e87ceab7,156a3e03,dda7e9a0,9a9dcd76,a72dc838,d9e2e6a1) +,S(aabc514c,b88112c4,6e6e1221,d61e2abf,dd7a3bcb,a2c7cb78,4d57dea6,1950534b,96e3d9b3,f3a4c3cb,1473f61c,e224dcbc,a535c90a,7d993409,ed079d32,3c8facc1) +,S(94a800a4,6eb9506a,8f6dd737,ba45c697,4e563c3e,1df40959,4198d1fc,e499d2d8,627ef26,d39e19d,ab4d6bfd,9d4fcc0f,4bb4d97e,b0886426,40b7ca31,952be814) +,S(1022de3d,6caa7542,ddeb47d2,1f82cc3b,6e04170,ed9d4ef6,81b58b81,efd6c3a9,2317f1e8,37716a0d,842884b,cd77cc3e,d6235dae,9fad5661,9f20a883,af459b5e) +,S(9509f343,17c15f7,a54cafc7,3d4275bb,41e39183,53858724,4031baaf,97bed951,dec71a0c,7f8108b2,5e296361,2d6623b6,7b2f6d9c,69d7b6cf,d7273503,fc72b4ba) +,S(bbf19e9a,efbee2db,fbd5eef8,492f52be,2e2f9072,6b3adc1,d16f0627,f4f19d25,d9e691de,f2ce976,c66d806b,f35a2b13,56f9fc07,7b7bb239,30668081,4b52cea0) +,S(b5997bb4,5b359516,b28ee935,e4d59c39,ae434c29,5e5d98e2,2ddeff57,4afabc5,fb6d36a6,fb2e1aaf,d9b5d89c,39a854f4,a3cec053,1e1a776c,b4267b4a,d2bd8ac7) +,S(fb746cf0,cbf2f56f,6a3a99dc,71e84cc5,af76899a,3a7d02c,fb272391,b77c8384,d1e4cf27,57373ab2,d1ba3f2d,d5bf8b26,a74d6814,23a5b16c,9621b788,a51e9796) +,S(644facf9,e6290462,1a5278c3,f4a2ff8,84600c23,69eeb557,bc412540,c4966655,5b5ee0cb,449423fb,67c9b542,3868f7b7,6d1968b,9d7dd751,75e7dd5,2f994b88) +,S(c41931cc,9c311617,f77faa3f,6b6f6e21,bd030c2d,9778b065,6ca105f,cdb8658c,8a759dda,8db8a8ed,eb1f2972,12858879,bb2f49c7,468d8edd,14d28525,ca3c0746) +,S(e8dd9063,48691527,e4f4fc96,2a0e5608,d151aa68,53257e2b,1acb7d94,56f66aa2,470d108a,4180fbd1,2a377517,c5e472d4,680ec468,52bfa472,cc400ac6,91541a0) +,S(6b48efeb,ea6d0d17,346fba31,8fa33deb,301062d5,94b254bb,db6dd28b,ffe27451,94cbae78,eff2064c,cf91bcc4,fe1ae3ef,3d767b63,6eb4720e,35f2340e,87c1e941) +,S(1cb08c2b,72f069c0,e1e4afb,7ea73e48,a33f23cc,cb89fb08,db1b0919,62bedbd4,64d3500d,5b6577e6,6c18d3be,fc0a7dd0,833d3245,1ad03257,b45a31a4,67c14095) +,S(2150558d,bc64dcb6,55224045,6d943208,7b7c7182,3901f78d,9702a736,998906fc,b49e2adb,321e0c49,ddeaa152,9bf83095,762ea96f,6c1290dd,b6ad29b3,c84b8657) +,S(530f4c16,58284100,55a67001,eebf528c,f9286825,fbb60ae5,da4ecac,e3d7f4c1,80b147ab,1eae8922,50bf82fe,1a9263bb,41573617,7dc02e91,fe7e07b9,66bc6af9) +,S(c5158947,8266dd62,fa495d4f,94bbe77,b1230f44,685ac488,7642576c,8d92e6b8,1705fd37,da813af6,2a799e41,3a45a4e2,4d2121e0,1065e692,ec1de149,43be7c90) +,S(e6963d21,b576da6e,6aa6f1ec,da7674d0,d827d533,31e19d85,83ba0e7,31553f86,d3560d2f,91c7219c,76962a5e,3b2aea76,604b5ad4,82da8f8c,419cf2c8,7cfdbe61) +,S(c5aa5963,a249a9a5,9445c0da,9537d482,dcb6ed9c,8372e455,4d440931,3c3f169,7e7f9c15,4ba213f5,981389d6,22af8694,b1efbdc8,18998923,92c9d654,92ae7fa6) +,S(bd04e3d8,5bffa429,81310c7b,2c885f04,69f01977,2819f6f2,5e69621e,5a32752,dc4da51f,b88ed097,b17358d3,da4fb755,254d8ceb,5b0df72c,9dc995b3,8e145d9d) +,S(f8f55476,4418c668,3390b604,c9f9f452,1ef63756,58000c49,d3b8b1da,80261dd4,9943a6e4,1b928da0,fad12667,cc997ea5,6af49db3,8c499a2f,a2343efb,52ea450f) +,S(77dc24bc,5f32159e,7c3b6a3d,168a6698,43b12253,e403299f,b4fa3db8,74350dec,240d860e,c38457ab,6d741edc,e4fd8c51,67f75733,f12fe892,aece4f9a,578c6bd5) +,S(9f238f7d,588d53f1,52da8118,2691194d,99a56fee,373745c9,aa2a3a7e,58d18825,dff57ffa,c2012315,ad6516d6,92902476,cdb2d3f1,58803c3b,4dc854ed,8ba9b756) +,S(92f95782,a59da5c3,a12401da,34c24ae3,fbf3822e,355ec948,6020ac04,3ebbbb6e,1c6231c4,e09c414c,e0d3cbf,9be73bbe,4f1fdd,b3d65a41,c716f0f9,a39788db) +,S(1b40dd47,f435579,1474b560,66a0efb9,88271a1c,19186bcb,b1715196,84f3130d,9fe6dcec,991d652,c9e13099,66b0aeb3,53869f99,28ebc955,6c64973a,4d983b5a) +,S(473f6b8e,d4162f9a,2f40d48a,8827f79d,180052e1,7b28b240,4772fe1d,64cd82d3,743450df,fc8315db,72c01f1b,21c4eea,9c0a39e4,c1e92e33,91096576,37e97fe2) +,S(40cfc629,a550b437,9e0941ae,fa8abc6c,8b492155,2045a8b7,560262a4,86954932,e627bc57,9c84859b,d2a9ba9c,9d7a69d3,8c8f06d7,ccd9e68e,fbaa0697,655a8a23) +,S(4c91dbc9,8d2d2891,a7861599,ab55fce,943755f,5f7c909b,3f0f85a2,bbb75c95,5e541495,ecf13109,6ac3aeda,5324fe5f,6f761ddd,d2972fe,812242ce,12fd23d5) +,S(1fe3c538,ac185172,44461f82,63961364,c3c74bc6,9a91bb4e,69973971,8e729d23,974c02cb,d7d97c,65f89b90,327e6dde,e627d96a,275c869f,22c14bf9,6be05389) +,S(fbe873db,56579349,4ca9c844,8a6e0dde,226d4e4a,2f210661,30fe1075,bb11dd6e,c91061e4,d03f9f09,21f56d76,eb78640d,4df80464,459fc41d,4ca33d4b,5ebbc5fe) +,S(b58277a8,3a6d6779,82af314f,7a41a69a,b1744e6b,1cfb4803,f52a25e9,8200957d,c8faf7cd,59e43256,33403b90,7abb1b83,d3f0cade,ddb9884d,77c5fa54,b55fc51a) +,S(3949cb,e84b7790,a7a110d7,9c41d548,d379604f,ec567cea,e3aaf0f6,fd0d9b49,cdfe904e,56a9c88a,76292c3a,5da21100,57795a76,fddc1610,e7efab84,750617b3) +,S(6ee9ab2b,537aeea0,bd8332dc,d810cb7d,36f8f7f3,57be2bb3,5d84e236,f1bca531,d75518a4,d975b0d1,e2780851,4b726626,dfc182a3,885900f0,4d82c839,1c64722b) +,S(c2875d78,3e15f959,33bbbd48,8a24c65d,2001f599,3536fa83,8a3e056c,20a2eabe,e5870c25,20adee27,83cbeaaa,cfae7283,538446b,7cfd7ded,12e68ffd,3f66de8b) +,S(88e26c2f,dd475547,8795e8dd,8285f73a,dd9eb9b2,68c1b16,65f1a701,cb3c81e9,d00344e1,9d14b3f,1dcf5c7e,8269237d,a2af90ea,93a9e24f,3a0040ee,d3f171f1) +,S(ca8e8c50,660f3928,3cb72105,43710f56,9a1518a,7948689d,3d7e2ce7,a038bc55,57600213,1892bc9b,5afede4f,e71f5ec1,a1516039,ace088f,9a851278,c52b2487) +,S(ecb6e53f,4330d0ec,b9aa3605,b6e6d209,222d611,72858b1f,d2663797,772e0249,b054af9,4c535d01,bcbd955,61770aa2,e08678ea,cd8de0db,d8efcdf8,623e9eb7) +,S(a011ad64,55123316,9916b20d,ca6efe7d,e78c6b58,feee97fa,7f9e3fc6,8d889cfe,f53b71eb,63f87651,aa0de66e,a51f56f7,c5e3ee26,ed4ccdf4,1978d7b6,f0191277) +,S(3ddda2f4,ec1b4020,31a73abf,ae69dd42,8d801bb3,fc96fd1e,b06334d3,cd7dc27f,eb1b6b4,137ca36f,5b160112,38fba958,32c5e5b0,aa5560dc,39600db0,624b6c1a) +,S(13f5b643,e908dc91,415ff856,76357687,bb777f21,3972cebe,e8157828,53982d8e,bc2d3402,f3af6ee7,bef0ec2b,73c75e53,b70309ec,633d97af,b9ababc0,62d20ec2) +,S(ed9fc1ba,60a7db8,93db8148,48790e52,4a246279,d938a04b,cf168ae5,71618e2e,b241c920,ab995cf9,4ab1b707,b06bbc7e,1cf7b8eb,80325934,d57e9e9c,6ba08459) +,S(89d4f6fa,f6252ba0,d036dcb4,54fa5f1d,311ee828,1cc5ca85,73fe7607,7b16fadc,5f441ff0,56fd4e24,ca4c9efb,859d6e16,2e4daa4b,a7f3fc58,e42a540c,23b6075f) +,S(4acfd390,e8a1b430,9af0c28c,87f51308,a1ec5741,8c194072,45c96c79,30498a3b,dde7b57e,5e5ab271,78f2ae5b,6494a578,2757f508,bafbbe64,30b96bc4,96728d2f) +,S(8320cbe,fa7483dc,4f5e7b7d,d74cf492,b95b7e31,b1bdc651,6595b605,eecc134d,e766291d,13959f5,805de8f2,aa59cd66,8376d93e,4b775010,426db24e,b2ff41f7) +,S(fbfa6a21,deb1d183,cfeda065,687a0b96,6d8e50fe,475a17a,7b690019,6e7c696c,f5901c10,5f30f5d9,75530b0,3f943caf,8de85a12,f54e4c7e,5685184e,8bacae2f) +,S(70695a81,45fad213,aa14a7ec,d3c84f51,53e3906d,5483db4a,c6e8c229,ecd2c3b,febf34ba,9744a37d,6b91335f,c735c426,1208595b,3b8d048a,3fb48e76,2008e90) +,S(89fd8cfa,8fd5bdda,b6a80bb9,96ebcc92,6074a15d,371622b6,1cd772f6,ae1ae9a9,85c2cddd,a8065ee2,244b3d35,61e9e057,87c6cc4e,d4b1ff59,53b736cd,d3876108) +,S(342256b4,cfd8e5b7,5f5d088e,3a919d64,ccf38827,b18bdd00,2ee9a6c3,fb4dad,c54f4704,f3512e55,4d96ef92,3005e4aa,34a157e5,8bd6b180,e219dd51,16c4be16) +,S(cbd38ba1,189a152e,bf78ea23,3eccebc7,16f4c28f,273f5c8b,ec9df397,9dba0dd1,d3df2ea,fa52ad52,9089c7c9,581dccbd,a2a0e060,7fd4b902,cc915f28,717c2d29) +,S(5f7ae38f,61dcf176,45affec8,7514c624,85b880ad,38df28ae,b695cac0,fd1d27ed,9b955855,f74cc040,63cfa4d1,fd098e5d,e0030c4c,6dedee41,71bb5e7b,c0939226) +,S(72e72eac,aef492f2,f3c5ce7d,dca58f40,c919a194,3662adb4,3d855a8b,532d194c,d7b5e558,a0cb091d,3b39407e,1dd58b95,30fe7561,6b4c3352,bfa51320,509d2d7f) +,S(925a19f0,c73d85d5,674a62b0,2d5496c0,5868fd41,a43696ce,eb153a0a,2e5b8051,2ff229b9,6c23cdd8,2bdc56da,37495c29,78fae40c,b429a1c7,3111d392,3c5505c3) +,S(baca4fb3,33bf98dc,165cb9e4,3bec920e,bbded256,e990820c,8f902e84,3f6e02bf,af304697,137728d4,e96a38d7,95b830c0,6c18579a,9b46f4da,a94a13e8,d3a0341) +,S(fbe24c7a,53b90f3f,918b92ea,e58ef633,bb72e695,2eee6c6c,2210f6d8,8da9e0df,1febd844,af3d057e,c9ace544,d5fd57f0,c125c55f,1d9df636,4f6be8fc,bc53e3b5) +,S(73b7de54,ae8a38c6,ccde88c9,3f526c2e,54d823de,a6415488,5e864a2a,1b0574,2cfa6943,634201d8,9438e6c6,fbb7224b,c2e6b313,538523f3,305c75c3,5c68aeb0) +,S(84960402,31a60cd4,cd623d4b,80bc69aa,7cfa7c0b,52cd88b4,2f22ca66,17151dfa,b5324b5c,af293ece,38deafd0,76835e10,469997af,7dcccd89,172ad20e,f36162a6) +,S(b6de647b,98585f7c,61f0712,76c6f62a,40926888,b1bab4fe,ad64098b,4b9434dc,f7180d81,be634f34,d878a645,2c662e8a,db9c18e0,ca7e7c13,8bc51e1c,1a5f5c0a) +,S(e062011f,da416281,bc296718,300a080e,fe7ab89d,8469e8dc,fd50680e,12dd9348,c33030e4,1ec1b1c5,4ad01bb9,8c4e2c48,32b2516b,1b2b3b22,adc4add8,1b690787) +,S(f7c7545,649b4659,49618dea,7fd15a06,1e7ee032,5d955649,b76b66f0,534a5501,2a929b2,a68342c1,81b2f55d,6b543584,ac06077,d95ad8f3,fd3f3ffc,24f56a3f) +,S(bd90ad48,1694f297,6506e2bd,e97d5803,b810f9ab,7479ae90,dc1fb146,38d4d5a0,f973b70d,8dca64e0,c9384b7,ad3b4ab6,4d3c74aa,722f9284,a9da82d5,5c6d02e2) +,S(cb5d91e6,68b3c202,b72a38c2,f98e6e4f,14bb566c,f7996d9c,c08aaa07,210b1b1a,68e9920c,597b633f,9bfdfb8,72814422,4ad69ec1,e435e843,73a9255d,79f52d7e) +,S(d251bb9,83bf849b,8f058ff6,32ac6bea,bcd12649,4fea947a,f943cdf0,6e0c240b,5098026d,b8ec5c54,8e3ae103,f0d172bf,e84281aa,b8c0b131,16295587,ed4500f6) +,S(27235299,c1f8d73c,268bca88,62d2b6d6,635f151a,d148c662,6c0cd5cc,1a3d2234,5b03cc60,f9224aa3,10d8193c,74e70cbb,6513ba73,d6d98ad3,2e1c2d,7f78ad52) +,S(1cf437b,aef8e007,ba02a24e,735d8444,698e5edf,2f9d41d3,cdb28cf3,3dd53851,e3fcdb74,b580b8ce,8f6edfe1,c276c478,da11323b,4e96862b,926ca4c7,f739a8f3) +,S(aa872c85,70e9449d,6cf020c6,77669c8a,7ad408e4,d9fa194,99867c6a,f77df918,572579ea,3d1d9575,e60a79a0,7a2aed83,4fdfba52,61b962ed,42e59322,c02fd873) +,S(b3224a2e,80c3a174,66a9994b,717b4c37,424f12bf,9dd3f17f,6eecd801,3ee2ed56,7ad1cea1,128c1605,552b8be2,a5fb6bb8,907e4290,d76bc82b,e17ecc32,1be6fa43) +,S(29b8f73a,7fdf6032,4c907022,b0107c72,ed951eef,29687feb,a8de56ab,4e47b8ad,19b849d9,bbdcf00,a6bba6b2,f1058695,4f286884,9b5be608,d6b4c357,1098f54c) +,S(3c2f5680,96f946ce,3d048364,dce939b4,a05ae9a7,c31c2a11,d2a29a1a,3fed06e2,47701685,b698de43,ac515062,9c40a15a,bb952a0e,bdd96,ba4a1b4c,5f61658b) +,S(b80f00c1,ec0d059,c9f5c69c,10cfcb26,651716d9,3d0b5702,b2c7b295,85af4c55,aac197db,ab42141d,31f63425,5df908fd,fd026d10,1263aa7,63d99414,adfdd02e) +,S(66af071,6b78b854,16572c86,fb3e51e9,b6d66ebb,bfc2a2f8,dd664010,83c83435,b8b2ce8e,fe794b13,4fcaad05,821dd884,9a8318db,614d858,8dfd4d2d,65314398) +,S(7ce8342a,6ea85f61,559cd2ab,e82debe,82eb5aca,142153e5,320562a7,6ba155c0,8a930243,5ebf4269,d75363c6,93ad4255,59f493e0,e492150a,9f110c90,8d7750a) +,S(cfbc37c5,184fe206,7f7b5c6f,c5e50adc,ed58ae61,d9059bb,4ff64a19,f48483eb,bd567b19,3da2b2fd,bb8941a5,be9fc72f,11d9cfa2,4c4438c6,a4db3091,9c8867cb) +,S(728c27be,52c5a742,859774d3,2d33fbcd,41e997d7,25d6be46,af480c8c,f9ec436c,745c7738,2a833cee,19808d12,9768c213,7500e8b0,b140e3b2,94abe97c,9a7c73e7) +,S(4553277,fbb30c09,a1ac1ac6,cb7d38f5,88cd5f3e,d4ebf6bf,5b5f6e78,12d47d5c,3ea80bc9,dac9f1a5,ac4beedb,d254cc15,728f0ee1,6949ce97,53f1bfbf,98e3c78a) +,S(7b752d90,9fd6d063,f1ac0f22,d8cf1e6c,78a335c6,ed11743,88192fe3,cba54cef,a252376f,e482ec59,2ac440e7,3aac3b46,a149e35,1aac2d51,244ffd93,f51d11ec) +,S(e78e796c,eaba974d,89d344f2,b610e84b,d51443bd,1fea5422,d2bea957,5467a376,13f0797,376bcf76,b6ade4c6,a95b6446,962ff925,b32fef9f,4549aa1d,e64e2b1a) +,S(1b7a8c02,83f25ac4,cd4a841f,4045035f,92a39bd2,c1903c90,4071eb44,5e8d702a,1843f757,7d03b6b2,22bdc28f,47c7fe6,fb83b25a,8d795b46,9e3ee9d1,ccf7623d) +,S(90d06a90,6ad81dae,20cfc2fc,6be85b2d,41dd9f23,63e13423,c557c4c4,bf3e5e4f,6ba7a127,58861784,2d7ee3d5,9b71ec99,86a72ae7,71312739,79544095,1e5237dd) +,S(d7bb4e18,ab61d8f1,de4b5bd9,9a5d03ef,1e0185ca,55ef14fb,be1f0b5,4cc4803f,311f268f,a672975b,acabcab5,1dec5754,48eb5a82,685e339e,e23b41fa,112873e6) +,S(6d5f1808,f17e0b81,a6bf12aa,34032644,b708882,96e99861,fe5ba4c5,5546c44f,8eb304c8,92cee7e0,70649d73,ae76893a,610504d3,fdf37af0,92d5dc7a,9eab1094) +,S(e4f62cf,9835a4e5,c2b7a456,596498df,2973192a,af2c80ef,c036c71,69df470b,874a48df,1a25a003,ada8939b,f727e0ec,b7d2e4d7,1efbec4,7193a2b0,50ecaf28) +,S(7fb31d8d,b3d5b77d,4aa9d0d2,692013ce,c82ccd6,83a2235d,848037b,dc6bf8ee,ed5cfa61,9fb4e350,dc37e2a5,2bb67104,90dcb484,b19af368,8101e59c,f9f0f0a) +,S(8887db9c,e3eddeef,ece414a4,f46ff048,3c4fd25b,14354869,6c60871c,5eaa9ffc,50294d61,1040a466,f826e654,3fb93f94,b4d60b11,d589287d,6ea33df5,a8dcf366) +,S(9d9d224a,595c843d,1f70297c,13b3645f,385eec97,80fa9e50,d27115f7,b677aae7,af9d5f61,24594cd9,a3aa7100,ae6f169d,dfd467c4,1affefe9,c9a0a5e6,6d7f2802) +,S(743d9b40,527b23b8,f165b6fb,9d5c14ef,450e1ce6,94439354,ab501eaa,2f34137c,6aad08c3,bf602b52,7d43e3a6,e7efcfd7,f24222fb,f8213f25,e8195501,9c8f0885) +,S(63c850eb,f0cd6fc3,3bb7a4f5,6d43c389,1f93b11b,5f67e3d2,f9b7537e,e5a951e3,29d214e8,bde33612,a5a160e0,f7cf3acc,3b83686c,ec5d7c36,dd90ebb1,d97c7ab5) +,S(b95608d9,84c13243,63809f82,b42cd16,fcf3c6be,5b19ccd2,249016eb,d93b4a54,41aabb2f,e7083dfb,ea380fff,2467a843,c88ef6b4,9740e73b,33a088a7,649fb0ef) +,S(8361b632,5eeafafa,f01e3624,6bd8f0c7,aab461ef,cb3484e6,c1ee871a,7ef95114,34ac956e,791cef3a,baed24de,7f0f59e0,bf34dc75,edd10159,b3870248,255eef36) +,S(807109d4,931731c0,a94127af,cc98e487,1fb44467,6d8cde89,88dfc252,868bc853,363e3944,be00a734,4c50afc9,cbb43183,f56eb20a,c0a5d9ec,74857484,ed9e1d61) +,S(25ef876e,d1654570,244ec258,e7ebda09,35b11784,bf5afb7c,8652e5f8,bdb34055,63459bb2,b8affcb4,1f6ad9b,9437f3cc,6d8082ac,d400928a,29f11fdf,503c8553) +,S(1aa87b1b,54eb6bd3,5fefb162,b27ad9dc,eee4b5ec,c1b69d4f,1fc6e230,d1848435,e5cd86ac,23c3790,369d7fcb,2189098b,a4fb3007,f82e5090,22e8ce5a,b44258d) +,S(cce2b0fd,9497190d,e6ea068c,98bba7de,a8f50aa,12930b4d,9060808c,b1ce6152,b6aea7ee,becee274,2bd8146,d792a6e9,ae75fd79,bb8882c8,11135d0f,8d5e68c3) +,S(fe421506,955b7cf6,f6a84228,30f7c6fa,95e4576c,da711415,5a49c238,e0bdcd4b,4e4a31d5,9b70b51,f73a4d02,eb09e4cb,7dc74a29,bef959ed,86558fc7,d4c8f401) +,S(cb26c118,264778ef,512f8acc,385e5ac3,10b489dc,88991e15,13665b7d,587d713e,7375bbd0,9fb3051f,a907fee6,80683f93,54403c76,85ca7eb,97a711eb,69033c6) +,S(8f286ae6,171d88d7,d82cdc28,93960bcf,53768c8,9cf1f149,fba0acc6,f5056014,6852d427,a888c5a2,4e748f2e,e482d38a,42879db2,2e824d1c,d72cf15b,8e32b085) +,S(b7af4b6d,7eb4eb03,e827f099,fb8b02f4,bdca366d,811d031b,ae827941,235e75a0,7cea697a,e8cc53ff,8c738ec2,55a64e4,4a499643,4bc5e16,422ebb9c,17d3dd12) +,S(c8471c9f,53eaa3fc,850ae514,dfa1109d,e89c500b,e965682c,6a4bc2f9,105be1e0,7d5f32ce,d1e758ff,e38325b4,778e68b6,f0ae5509,fcf9195,c1a79d41,57dc519) +,S(8d192ced,73629184,ff6db80e,b2c6df4c,a8ad77f6,dfc98c52,9406e7aa,dd506536,3b01ec04,ff45b037,c1444255,9cb2f629,7b4f8cff,e4c3eed6,3b95d4a8,88fb2137) +,S(318aa156,f4912dd9,7b90ae6d,c29b0f8a,99f616a2,5b023f08,ad35a8c5,10ec5015,b398cdd9,5ad52ba1,d7038cdc,67e36c74,5625fb94,f62b1b9f,aa2eb5dd,be6ce52f) +,S(b7fcf98a,6a385f68,a1c6f9ee,c6f069c1,81b0c94,df8c05ef,b59b49e3,aad66f54,912e2098,e3b6e44f,46eb6382,83f554e1,80af035b,16c0eb3a,4e000cb8,d4ea2da7) +,S(599b7a5b,e7a7cc6,3e0b66,38171c0d,41d78efb,92a9bc8a,1d0e8f48,b2b92fc2,afb3343a,1983a867,c8e196c5,92f745c,9060330c,1f0c0509,375e30de,3a214b7c) +,S(c3578705,3221f18f,69dbc241,f927ec48,3280ade6,44c70129,2b30a11,a296db9c,2b75b2e9,fdef6060,29633ae,481ba7dc,8ca52847,d4d0a201,9da74056,40a980bd) +,S(9e2020e7,cc4153b0,adc2b1ef,3cf607ac,305a480e,3a8854d1,1907fca0,4811fa7,19153a83,2c9a0612,dfea182f,a855a039,33035757,2e98e5ef,43f26699,3b8bc6b5) +,S(1e0c4c68,6e5242c0,6645f4ac,6ccb18c0,82c5d5e6,c89322b4,3b6079b6,ccb5a5f3,63c4a4d7,3ab71f2f,c49f5532,b543e381,83ce223a,c8609be9,d6b72981,8b5dedfc) +,S(44b11683,5f922e88,e7ed4328,cfb212f6,aabb6199,64fbdf3a,87dc7f24,faa761e0,a9181b5c,341cd78f,2e1446a9,e99acfee,7aa5b91d,4c7da20a,b7cf200c,f470ffbd) +,S(940baf24,717ccfda,e539064d,f6e4b670,2ad8b60a,c32e38cb,fa4eadf2,6a7bd3e2,bf5ab95d,2cd9b68f,cdf535bb,84b967a3,f4fc44d5,5e6d21af,d09e1de,f5f13ad5) +,S(4191f800,85767106,a9e5fa6,8521366e,a3adbd79,ea315b93,9e63f797,2995e7c5,662791d3,407f50b3,7a68e15f,5ee71991,2e893099,a907db3e,f818938f,9c3bb2cb) +,S(1bb8ec05,76ce9cad,f96b418d,cb5c7d46,9b49ca81,7f253b15,8b26cca1,cb9a472d,762e9c6b,2335769,72396f,36a56efc,f2618754,f1c30923,30b521bc,4e0198b7) +,S(c5216da7,91635b83,e55ec5a2,d9f3f8be,b1a2b0e3,cb097528,654c50a3,315be78,2536358,e58ffcbe,789d34e3,25d9f59a,2210c247,a80eac8,c716214b,9d5e520e) +,S(7b1488fc,83a02d7f,d12b9eea,555922d3,f4a9c42b,52f030d9,bdd39156,f0890225,ae7dba7a,d95420f2,8c8185cf,5aa2b777,b9fc5c14,b6c47048,d8ef071a,77dd4397) +,S(e245e4f9,7d6c69d1,5e244f4a,668afd07,d57fea2c,f8401b2d,8cfb6ada,f01f8891,88a0648a,ed5eab1,d57226e4,63411b9d,3632537d,699f39dc,7d7cbe5,49e76900) +,S(ed78f3d5,1f4fb987,5918a0cd,d6e5280d,6516f5a5,acdee916,d3e7c7a1,d757d188,ebc569ce,9b3cd325,528cde0f,9a2ef54c,d9f920a2,1ba7785f,62ef40dd,9463a81d) +,S(3e8d870f,bf768b41,8264ad34,89026fe7,8870e201,3f98696c,81dc3b7b,c0b1b599,28558e59,a6a6c255,a352cc9a,c20508eb,55af7449,8d75ded,c94fe414,fadeb218) +,S(96125a01,8f901790,fe25b41c,f2f7fc98,50cd30c8,cbd05ffa,cb76bc45,94d5f5a8,125db476,3fc8ccde,492e7eb4,45873147,8f8ddc5b,6c2b588a,b72d9b1b,fcd4c43f) +,S(779d9847,6fd72d41,937fe1e3,e12d4076,5cc61f41,19b37437,3919782,18a3dfa0,75a3aa4b,95523e05,42f38dab,b2d80895,cf3738fe,5152c8d0,96a587d5,90442891) +,S(681e390c,323224a0,7ccd9520,23c9d89f,4069100d,3b275c5a,e773efe6,170f4e4a,a9bff0ee,334bcf6e,a3bc44e7,5d85acc,f753a471,ac008e0d,47b19ac2,476b184a) +,S(d7b8530f,3fa18d18,ed94b938,2906e431,44ad5994,5eef1d53,e3290887,5c4af2b9,2efa5bd1,acc4ce6,73b8c76a,beab2e87,6399f84,94a1450,bd6833dd,debddb92) +,S(1277ad75,6e965ecb,c8c04ea6,c22042a3,ca3e71e0,74334012,7063d3b2,da257a5f,38c90310,ee2bd94e,5f3149f1,f38d065f,8df110f,92f126f1,3a69013c,515134ed) +,S(4e66e596,94c521a1,8114b232,427dfb97,8c7f14ec,7b5e18e8,9c11cb5e,6a2f6f65,47d553c1,8a858b59,f1aa8f4a,51803450,c237fd2e,60b137f6,d13647e7,6683caea) +,S(1fc1e8bf,3eae2dfc,b141be5e,ea612378,209ab1bd,7ccce45c,d51fcfb2,8f192aa3,5632d350,ab6b3da1,599779c9,9cd8d7b5,e317ca9d,ef3245a8,eb62af95,ef769c20) +,S(7eca2d92,8d2bf4fc,ed1a8336,eb87c5f7,b864b842,b3057c8f,97d5dfd3,76771d7f,969da039,7a37997c,c243d448,90d8110e,fa580359,bfb35342,bf69dec7,4bb17337) +,S(2531025f,8fddd665,cf34baec,52733303,28e47e4d,827248ad,9a1e6c4e,be3db9a7,e404fbcd,d180b2ad,931b4f61,5902eb06,cf00f66,6f1323f7,bf0652fa,94dff64d) +,S(dd28941c,bf6e4bd,76b4bad7,88f700a6,8c4937a,67958c3,bf6388a9,d5e26441,cc45f07b,9ea1a81c,8d89af84,8883ad1d,53ee8a52,2416c445,c4963791,7a366909) +,S(d3af9e12,53ffb85,ec7829a,4d41d704,1ea62952,4d7452a8,d9ab6ef0,1d6b509b,9c115e78,91b383ec,20739d37,6450a2e6,6f332e5e,c7a3a97b,2eca8c0,ae819bbf) +,S(2c59063f,13ac98a5,ed196aec,4f2aba11,c8647d78,42be85f4,ab87a007,2b49001,e9738418,cbb6e31c,f588a3b8,70883f90,ed3bd8e4,86e3c77a,37fd1152,c22637d2) +,S(6c0ace3,f182c963,45deeee3,c41c5e51,8dce984d,3d409a89,6d766ea1,b1ff0e0c,17e09dc8,dfc53cb4,952fec4c,92782ce4,3515544f,6181bde1,1d1ba1a,bda709ee) +,S(f161125f,3a229d29,2053fb9f,6f118550,43d80e33,9bd45af8,c1519043,2098c9d9,1b442ffe,a186cf2c,343b90b3,66a3a008,e08edf90,f073e740,abd5d20b,8dfa1327) +,S(fd081f05,6b219fef,56a3fc1b,6dc7873a,fb054b40,1b3ae0b2,414384e0,9080827a,9711912f,4ceb0036,3e5921b5,c2f7ca49,387b78cb,f1b9c2ac,9c5d5d1d,1bd8203) +,S(72c6eecd,d87657bb,ffc3a03d,b6e1f9dc,83252d2d,c73ba3f5,8642fc08,fee42b4e,282180c1,7737b51e,d047cc50,64d53cec,6340eefb,d969525e,a1524f0c,a305e39f) +,S(10df231d,4582143f,1ad7fe00,508cbbfb,3d49775d,f13dcee1,d6155768,c14bfc51,b7743bf4,e7cd49f8,88cd0d26,ac196037,e1da9402,26518e07,407bad1d,20af7dc6) +,S(354e8b0b,e40bd9a0,36620006,744c0913,5bd4bcea,34ab3371,9561e36e,f465956a,3e7407a2,2b9d71eb,a04239fa,600834d7,5f643c8,b4ca6308,475f6c9e,8d35fd4) +,S(2ae99ec0,6a4e080e,879a60fd,a93a47df,9ba7e0f3,b87a6772,be6d7e23,9bf2c42f,3fdfcc57,6a36adbd,52467e01,f3490fbd,82766cea,b956f80c,7b1d29b0,5066c31d) +,S(f47ff09d,5e93e827,72e73c7a,8f1623e0,823b09bf,86ba3023,a223a680,fd849bd9,379ad3a3,cd546d27,35fbe5d9,97c3dd8b,8c45a3d1,ce8e9c49,b23bbaea,e93a08ea) +,S(252c0934,acc3a624,c4d8b409,111b248a,2242dba4,7d57718a,aedc9cfd,20647cdf,17b7a015,a2ea993e,89a7161b,f50124ad,561ef131,609981ac,fc92e495,cd2ec91d) +,S(b7f6bde6,7cdbbf9,4a3e06b7,dc1bea75,d6247197,a8617a6e,a1f65f44,a7459006,6d6ad596,fd3472c,9d7eff56,943c1a03,ee4f540f,29782f77,afe999e6,14f5e316) +,S(210c956f,e0a741a7,edad58d5,d47a2a34,fface7c,5edad0f8,f4953b72,28350b2f,4d4498a0,892a9a9a,4e87ccdf,424d7910,bf90fe95,186653c7,6e6966a5,e7a816b8) +,S(7ab93adf,b8f35eef,8af99e5e,e37aaeee,401a1936,fc0b8c88,518065d,12f4a74,4f0782b1,c78954b,8ce37bdc,7e533145,3b885d92,da1dbf85,940da9a9,b7f0dd8d) +,S(bbe1b787,9c93e7cd,891f628b,c9a655e6,f4c7cde4,fa799596,74978224,9fd05fd0,493d3dd7,be33acf1,38ef5b73,8eb8f8f5,4e270323,8f70078d,5f7bd9e7,177088cd) +,S(61f42d35,ffcc6151,f8c93b21,5df0cab1,fb804cde,f9c68818,fc4f413,b804942d,46ef1e12,d6add082,3917a758,9c137d45,c38ae2ed,eadd847d,aa574e06,18708396) +,S(18542b75,3e78191c,b3dabcf,f9c64a8e,5e4b075d,d600fe60,b830e732,7fbc7b40,6a816e01,41b17e86,65ec280b,f6da9dbf,8061329b,6db9d13a,a9f10c0f,41340118) +,S(ef83d0f4,a3d2963e,d14e708c,6d22017e,aa97b2f5,23b06f1,140b4105,459781d0,5587e5,13725819,1b10bd40,e616e06d,16a50392,7a8b1394,a562c396,973d98b6) +,S(fe73429a,7714dac6,ed0db327,d6949d43,30d2b16e,a513d3b6,7b74452d,78a82a4d,7079088d,fd828815,ae087319,c232817a,4928f743,843a4966,e9411276,d16214b3) +,S(2e8b8a63,3048900c,4b82ff8d,fd86a971,86e3f1b4,6206b252,f06a8c85,82555130,74e10dbd,ca84d796,b3b37ae,b32624c5,2c5aabc5,d4fcc5d2,21c1aed4,71c940b) +,S(9f4164f5,4f34a59f,3a7be378,66a8204,def2fd98,8dae6dbf,5d471e0b,caab7017,4b662fde,bf2615c0,8c7b53d0,b2915d50,ddd2916f,a3599d81,bb2eab6d,80e93f57) +,S(c6f3a26b,adab6699,aa08fcf4,6f0ac900,2be3597c,16133225,6a5e6577,11b16ecc,f29db1d6,579d0e36,4528c297,36019f4b,6e8f060d,ad5effe6,d357d709,882a250a) +,S(76a4f5ef,6a869e28,e6494cbc,ffc6eec0,1ca983ad,1b8219cb,d2b84eca,96f8b910,e1d8bd7d,55a297df,32ee185c,c60db286,a2e46cb1,312a8995,5923a068,cd3318d5) +,S(d2c25c8a,cfaa0b2b,3f6e70d5,bf095700,68102f8b,24867970,ef3c8000,b2212d1a,bc907681,9c7926dc,bf81278f,7dbfc4cb,292a8071,177ce8a4,f4e9346b,a2d9e500) +,S(b2fc2ca,5a30c678,61b0bd22,5bf2c088,26d799a5,9c9a680d,dabac9aa,5cb624fe,d4abc7c9,fab915d0,fe9dcf59,a0f83ca,56b27566,6e9841cb,b5b14874,5f6732ee) +,S(110ef531,7824c321,ba7fa94f,ac98de3a,c6cf44af,db92b7be,1006c751,9b425065,cc3daa20,6c0eb83,6bdfe640,1f7461a,261e7233,c70e615f,db82a991,77b83cb7) +,S(fe21a607,7419ed88,12d16ba7,5485e01e,3c063359,f95a8634,3aab1c84,ba6ac00b,d6e08c98,4b7a5282,bc1857b8,82604fc0,692a2fa6,40cf5a5c,d298f344,54c836b7) +,S(c5e45275,ec85bb32,edd32702,7d7d87ac,8394bc51,722e0bd9,58281e61,c454fcef,9b158ee7,89034035,fec4f06f,2fc81755,59f9f762,38742715,92ca6ff9,e5712a8e) +,S(cc68f3f3,36360481,5583d65,7da51968,a4a44a69,1264bac8,289791aa,dc7a4ef4,9db5cab6,7b31f3fb,f3b5fde2,273496f7,93316358,6d14e80b,bbca4613,319df9aa) +,S(6d33be85,5fe8bade,89109a3a,8c089aa3,f7e9d178,969100b7,eee7a693,d83ace80,9312736,87c08455,c43b4cab,afe71408,333fbd69,d330315a,3fc9a52,a9d473d0) +,S(5aa581c2,fc48c38c,2aa2e176,c12f12b5,4810ff6f,862fa17a,196c06e4,812b9e3c,adbff08b,bf6fd5e9,9f91f9f0,9881cfcc,a7b5c2af,709bf838,6055079b,2f75f3c4) +,S(12eb2dde,dc6ea4e8,dfd43067,9d45052b,b882e4d9,bf516b,61edaf00,305fe883,8f948ee0,f8514f9a,1bd8a71f,20c95e4d,e30caa5b,bb3a383d,9561f027,34bb1950) +,S(3d0d7eda,43045e9f,62dc680a,be47e933,74a95d59,945b69cc,60acb89d,e40dcded,45c53d35,e369af07,eb223a79,1d148ea7,1875cd1,8ca066d3,399743f9,65e184b4) +,S(173d4741,5803d266,7ea94abf,319c5917,204256ca,e217647c,c024a9b3,be7b70c,2da6c348,cb066462,eddfe8bd,3dd00ec1,34a0a060,4b7e17d7,e6cda389,dd4d5463) +,S(10659655,e2f1ba5d,db390184,c2d6d1df,1cd2abfa,4cd4bc18,c89decc9,5b5d6319,5ac2793,3a88870e,d5c7752a,459ced45,69435a09,7cd0e030,25608cf4,ac2ae267) +,S(e462be7c,380d7bbe,cd45c6dd,8fe60219,404b0c9,4c5e0e4d,31a23064,2b5b95,872183ec,1ba5b854,1f3f99d8,ceac80c5,9e84756d,cae2e694,9b43ea7e,d1cf752e) +,S(8200badd,1df41faa,19b20cb8,efa424d2,2f39b1f9,26b692c0,2a0ef6e7,feeed67c,8402fa9a,6ef0f83f,42546b05,360296d3,74db551a,d89be995,f2c11866,5be528b3) +,S(760e2457,a3e1a165,526e9fe2,2b5bcad6,e8107581,337cecac,e2ae87dd,a3c54592,c5111ec3,24158a21,56b897a3,82bee2bd,de0f9df,af9ef611,a7fd3fc7,4a635b3e) +,S(ba6229c7,1729cae6,5275719d,9a35691c,f260a003,168f1a25,1ac00b09,aa17872,7d281600,6bd8981,82126d21,70fa0ab1,d5dd0c7b,cc377a88,c43cbf61,70a633c3) +,S(a2cf1392,571e758e,6ec74708,dc45f70f,90833ad4,135e7a34,9d2810a1,8efb5216,2420ffdd,afe96506,9e6f9266,1e3839ba,c9b1db40,d40149ae,3acc8683,86acd175) +,S(f8822204,27cc4b37,33268925,fb80beb5,a52e5391,b2c8e31e,f6e99592,1775af20,6cf6eb9e,b19825da,6edc5d2a,66f3987d,c9eb01e2,b70e6395,abe2903,d43acee) +,S(eea28950,fb676991,444f96c5,7e42ea16,aa380e3d,dde63111,fac35708,a4e45b3c,34d30722,98a686ec,7e1a8095,4e2911f1,5e11d426,ecacf11c,eb45a5cc,7204114c) +,S(7f252a72,6f9a1497,f61bc4ee,7b194a31,432c0178,2f40b16f,2d36e9c3,7279e25f,8edf25c5,f50c6f0d,f8a17f92,611bf024,14e02d0c,de38aced,e96d5a7f,4467c449) +,S(d3da23fa,56881cf3,a42a50a7,42e1067f,54ec24f,2de19921,b1ae7f15,fb90509f,b4ec4b17,8e555cbd,15210f09,bd1ab43,28e458fe,6aa3e800,44bf0093,ea08f90c) +,S(6752f294,f8ad85e9,60b6a88c,cfca7874,5c80ed7a,93f6f05,3782ac73,d96e31e3,976222ef,a6f6358d,42d6289a,4f11bd65,e7e755a3,845ed49e,3c972b5c,5fdb2418) +,S(4fe21b06,24a45b69,7f42aa54,10e6385d,645a8d49,2a61ece5,c8d5b2ad,1fe74efe,f7666c09,7caeea3a,c4b2993b,64f4c0cb,ac934099,8870ade,b7cee48a,c3c2c413) +,S(15af87cf,6dc1acc5,1d323a36,b2daf163,ccc8c201,a92f0677,6a26ae27,7fb9d766,53fe4566,6a975d35,ed20a5a,7bbe63c4,4cf8011d,45e7a171,d5d72e57,5debefbb) +,S(656f3686,c60039b4,4c39a5d3,ee82cd08,e8aa8ed4,b9a943e,42281407,4ab6821b,9f277baf,2da730b3,dacc2a43,512411c0,13ffca65,7092e695,d49c8d24,a4cda4d5) +,S(a13286fd,2c17a61e,6bf8d209,d64f5879,2534b037,cd854470,a09c8c8d,95aa0564,9322d3d4,c735a485,5d76e5d1,fd27fdbb,a8af2fcf,ddf7bdf3,f9e26f97,7f4cd1df) +,S(3b355928,4ddb285a,1eab73c5,6e6bc554,9f40d83a,2b859e01,a30032f3,a5a7109c,780670b5,67755fa5,10fc3385,7745a69c,bbe73e3f,8186b3c1,8a82c51d,5e1d9be0) +,S(b0b15be8,6c2dbfed,6da6e7c6,51c10b17,504070,7d1747c3,ff2dddbb,256fa495,8d2c438a,42750adf,345332d,f02f6c4,55a07fce,afcc51e4,96c270ff,913546e3) +,S(c754130,bd717ab0,fc17e14d,dd6ec50d,aa6bc02c,a338cd9a,798ee62e,72d517db,fddf938b,28500dd,c9f1fe0e,70104564,d1bad398,d3bee900,ff609c8d,f56d3b26) +,S(ee615579,33d877e4,9bb228e3,62766ada,8615d382,c022c333,39f78ff6,5e5d9ceb,3dd38b15,5ce01a1b,3d5434f1,b2e04a26,6a830f47,fe89263c,b0ad1b5e,18bd8b76) +,S(f830dd7,4d03a39,d7f5ba3d,132b40bf,130b33cb,9b6609e2,12b6479a,14287c9,9183a68c,33c2d25d,c237f8ed,b5a63d44,4dd2bffb,d1255631,221edb9a,4c9e9e91) +,S(544fa477,3aa3589d,9e63c8f0,f30cd189,a8b6658e,ba908212,cb1b4caf,2d5f64ca,bbf57d7d,b5c6b8d6,e202a7b9,8ed06edf,e1a9ad01,381da1d8,11405fcb,8ef717c3) +,S(9b270440,132f5b09,6fec6214,dac1e27f,3e6c6f7f,25eb2cab,680c3fea,e0b41b1e,a7e591d,eb990617,6bc87263,6ea19e04,c9a3aea9,59059078,2a757fd7,6d99c6dd) +,S(bbd69c5f,f0b9228b,cfeebb97,32b3c316,c14d9a54,d5a3e9ca,ebb337e1,e33525e4,78cc6c84,8c246e7b,7636949d,4e3f2b94,989c77c4,812b8189,cb857cd1,3457c403) +,S(a920edc1,4ddf5bda,56719c0c,2adaea7c,9aa8aab9,25a5d6fd,41172725,bc65341d,b8afac74,46e560ce,bcaaf438,69dc9287,2805fc14,122cb19a,bb59e51,8336ff80) +,S(3c6e9595,a201956d,ed27e83,41b22822,445148e6,d00b2fcd,ecfdd66b,2405ae3f,2b8ef9a7,d7c37d0,d2b77309,74718eba,16f221a5,f3074678,317f0b6b,7b0841b1) +,S(c35c9e45,3f487f8f,ae5b6010,e1bc1ac3,ebe4ee53,33666876,13cc4b35,5162ed91,7a8e64d4,9f827631,579421ad,3c7f7ea1,f4866432,a341f955,6741c521,c757addf) +,S(8fc84331,a8f8dffe,28f30d71,b39c105a,ec09aca,4876241c,1c81a223,a1953637,aac7257a,cf0fce3a,ff8fc7ea,e8d19606,2ba6d7ad,9b7987bc,35a92b9b,20360174) +,S(b43ca4ce,f1b4a2d0,1a20fc64,2f3e1456,317f729a,1ee69798,4ed88bfc,1c5a2908,39ae1e51,f352c0c9,8a79cca6,cc859eb7,92bad6ae,5318f99d,d62d3bd4,d8fedad5) +,S(7f29c501,75628aee,5d39db41,cc4d89a6,9f133f00,47500f6b,aa7a90cf,e13159d2,cf17c6f2,f6072b50,257f722b,5756d8ad,c7486cc1,d21a925e,8cd29a15,4b514cd1) +,S(3fb93959,55ea2522,61b0488,212e15d6,b28e975e,5ff5f357,15337538,247f2a54,7c3db409,e06d6980,d834639f,e9e357bf,e6a4e9b0,ae6b4fb8,f5e45143,ff625ddd) +,S(945ad871,18199665,a4078a46,a9596bd3,ec7cab84,b6323a0,7ceefc63,d7ba29f5,6eb6d896,a24d02c0,630c909e,65d13d4c,2eacf1ef,6e600b89,1b171594,aa28c206) +,S(513bfa93,57c827c1,b3c0289b,c4ce443b,cadfbef0,b28b32a9,265ab85e,67efaf4d,645c5b3f,d45030f,1aaea514,baba7069,91def89b,56fdc292,4b684241,6653b6d2) +,S(d41b35bd,421ef7bb,1c03c794,477c2851,dee92831,714180e6,6e57e735,caba5835,beea2116,9cf971a5,ffd83596,d9bd77eb,cb1e0c7d,506a45ae,be8c0c7c,22738f9d) +,S(96006d64,fac8f0de,88f93e05,da8e76e6,40afc1b2,8ee09a7d,5633643b,d89ee3e7,1404173d,e96a97e9,ae9bcad5,c9093d05,cba96479,30bfe6d1,96664d0b,13c93618) +,S(ad528227,12257f87,d1ef82c4,4af5f046,648c2a72,497651bc,2327e971,1170e7bb,2ea908a6,c742f542,324be959,4746ee48,4229d497,cc8bd535,e7989525,aa36f079) +,S(b4709a81,c067f6e3,93ef97ab,c26675da,6f01a2f7,e3f35275,e7089ea8,ad5644d6,f655b89b,d6a83838,ffd23f6a,fb944bc0,57fe7f1,1d321a0d,2152568d,91751d99) +,S(3b7bc8ac,5ba85b40,2080612a,84e0226f,3b43c8de,c0e54b6e,ea779b76,812782f0,8405dedc,a02825f3,5a60333f,190001fd,98ea3995,9dc6e61,c28c5e2e,5213fb0e) +,S(2a76b67,d197e7a3,7a38bb10,d49d523d,c4beb4a3,75336974,7e22e407,9e0310ca,6331389f,b9cf9fee,e89b089a,95abca6b,a3c2aba5,38725c1a,6848fa46,997d0e87) +,S(9938e808,77c2baa4,53e0256e,d250439d,b11732de,1abf7555,949a7574,f62819e3,250b061f,bba0faa4,468a080a,fee8264c,f72fc12f,2ac91dd7,13ed92a1,1b281124) +,S(7366eac0,7e5e4573,333291,3e42f111,e53a78a6,5069898,52db2355,de089230,b8dfda33,31646343,bfb60b2f,25050967,e735861e,1654f0f7,ff42ed9,5dd652a4) +,S(10fc632c,cab22fd3,2583599a,a2efaaf1,6e1b01e6,a5a96c59,50871012,33022152,cf53d9ec,c74aef44,7019150f,ddfde494,c2382a07,b2dfd73b,c628478f,7fbae0eb) +,S(785f4da0,240de52d,bb50b1bd,bc53994a,47318076,9a1fe06e,5a40a8e,e677ce63,9b5759d2,f77bbb9,e40ac169,a01500ca,6dd6bd70,6a003871,e7ba4d66,b32db9e6) +,S(a7f20615,593850c3,27aaa06f,c03e0d46,d3ff20a0,9b849810,1759638d,8cbb9cf,13b9ebb6,f0cd59ef,54e0f935,87a14fe1,2337e346,94f5e8f1,10323fbd,d7604d3c) +,S(cf083e4f,e0ed4444,85dbd99d,8e6823bb,483eb749,b94ce672,8671de8,6105aa4a,36eaa305,37378494,17050dc2,8290c74d,d9ff9df4,cbfa434a,2b89de00,e06f3099) +,S(9fb8c370,bca485d1,dcadc251,ee906f58,6f3e177,be37baec,6912e535,f5c7ab0a,df5cf77e,1ad07532,7150136e,7ebe7f35,1db47415,74444b24,e9cf2f4f,31ec683c) +,S(ff9e2f29,170dd456,2c94d48c,eeb0390d,db783702,c13574f,8a8c6a79,6427adca,784c7b68,3c824603,5077911f,957aa33b,47534180,d70a60d9,f248b860,736a24c2) +,S(802343c3,e07f9f9d,ed2ca436,3e455427,367b852c,d23ffd7f,fd690eab,90b4162a,b093f0c5,f0fc7d01,a5dfb7f6,bf9d90d8,8595140a,a13fbfc0,f7d6af2f,54ff5ce0) +,S(ae74ed87,11a1a684,9e558e05,47ff8f9b,f6337551,1dd3d272,ee0597fb,fc2d6914,c304897c,e5afb5b9,a383cb64,e85071a3,cfbb2981,93ea6ce0,55257ba4,cf15bec6) +,S(c099b05a,dceb601a,14892c97,7b267152,f29ea71e,fed6090e,7267249e,43c2390f,6c3ad3eb,8c95c72f,e0030a7d,34329945,fd1eb71d,8c4aa1f9,8fa4656c,6bef067f) +,S(97c6949,a25581f5,945814e9,9d590dff,67d936d5,94101005,4cac33d0,fb3658a5,cdc7faad,5bc387ce,a16a10f6,6971e5ee,6d32756b,596adc14,57081ad4,1dbd2e4e) +,S(14a19edc,a1ec89e9,524548ef,cf3dbc03,81b14b46,928f7425,87b11df1,7aa721f7,f83c4d0,aca08709,63a017b6,8db3434d,6088015c,2ff1d8bd,739fd620,35d1a19e) +,S(4742af63,c7597424,e6d04a8c,cb43142c,54c5b350,175bf5a7,27c39820,2187d00e,bb1f2f72,b21e15f,ec17af32,2147edfe,1ca80ac8,3e030dfe,8be39fdd,f340c56d) +,S(a6597869,4d168b00,d9df41de,fcd48ae9,68313394,db683407,330ffae9,f2559a11,6bf65c42,13317a5d,fb561e8c,872c8b1b,90bdabc8,8a8d2e1e,39919f8e,5043ced3) +,S(9e62e468,1e22abde,4d7a2fa1,2f7867f6,ecbfc15b,54990e26,821a8cde,fed76985,4877297b,a64fa8ed,c039ab1a,e62ac72d,8d7bbf05,7513d1,4237b8dd,9f1acd37) +,S(d24333b4,de55b0f5,d47c72e4,88cee8ee,8c960903,260a64d2,c89bca45,db7352c5,688b20b0,617ac12d,5be38fa2,ab52e785,69766a83,2d8b44d5,cfd6ee88,b19b9f1d) +,S(d203301a,13d1c8ae,a8c79007,1ef8116c,3916bb3e,dd5110a7,304b9145,465be838,a606dcea,398dc313,e61c8fbb,dbbc3874,3c103297,164e66a1,4412a21a,5319e55c) +,S(d1aa98ab,7010146f,16a9d6b,cd911535,2595bfa5,1bccb3d5,5e3a4a87,62666610,3abafa4,999294e8,80e3fae9,edb4206b,9b9786d,bddcaec,e2d01cf1,ab715690) +,S(1e20823e,81051b2,65535085,9aefed6,3631dbe,23b4e79,abd3c17c,21f053f4,e238adb6,86592008,f7fe34b9,9b934060,15c323ec,55981b27,85feae6e,5fde7186) +,S(d878afb8,8527a861,4b4276d8,fba39300,72196017,6f437014,980b7bbf,d4320ffc,7403107b,fca8ac64,baa94a4b,128e72ee,4a015675,845519ba,d5609331,1680e7) +,S(53f86d45,61deef96,ca88a685,38fd35ec,a95740a4,3a52c601,faaad0c2,aa3ab72f,667a6ece,bfb97682,c5e9e5df,b6d29156,9604f63,d9ab00ab,8cb10000,e6b01514) +,S(20990660,f1055420,b885fb0a,38824740,3b141c37,5aa20dce,8a29191a,e77bbb16,7d434476,9e302e38,9e14c02e,f5fd8a5c,64cfcf3d,e9813f1c,f53bc6d3,4da93559) +,S(1e70619c,381a6adc,e5d925e0,c9c74f97,3c02ff64,ff2662d7,34efc485,d2bce895,c923f771,f543ffed,42935c28,8474aaaf,80a46ad4,3c579ce0,bb5e663d,668b24b3) +#endif +}; +const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)] = { + S(8f68b9d2,f63b5f33,9239c1ad,981f162e,e88c5678,723ea335,1b7b444c,9ec4c0da,662a9f2d,ba063986,de1d90c2,b6be215d,bbea2cfe,95510bfd,f23cbf79,501fff82) +#if WINDOW_G > 2 +,S(38381dbe,2e509f22,8ba93363,f2451f08,fd845cb3,51d954be,18e2b8ed,d23809fa,e4a32d0a,fb917dc,b09405a5,520eb1cc,3681fccb,32d8f24d,bd707518,331fed52) +#endif +#if WINDOW_G > 3 +,S(49262724,e4372ae6,f6921b82,aa4699a1,f186aea5,40122630,3ea42648,97c2a310,1337e773,bca7abf9,5a2cfa56,9714303b,6d163612,a75ff8ce,c41b681,5e27ded0) +,S(e306568c,1a240c90,d5e253b3,e477e2f8,4dcc1a56,ff06db8d,1384b079,cebd2d31,eac6fe3,78934260,888f2b10,7f7d0db6,ffbc8042,be373826,692b4083,92546e44) +#endif +#if WINDOW_G > 4 +,S(3b9e100e,2428cefc,271b0e76,23fbd633,74ebf8d9,aab41dd9,c530c39e,363136b0,fafb9815,2d16bb71,df1533eb,8f475b26,a2ae28a3,3ad31f81,953ec16f,6cdbbc8a) +,S(bb0aad49,712ac9a9,2b76ca80,f5dedef7,17ca0768,8107beee,9608f047,2f485d3f,ea699c53,c5835479,8ecd201f,7297da34,895a5afa,31670bff,e7939250,3ca2f975) +,S(79090ac8,e4eefcc0,d4e8eb19,7afe0113,e1e58b4d,b01123de,4aeed33a,36718dc9,eaab722b,91905b8f,13d816cb,cd9aaa56,dd36afb7,ba9008b,963322b1,1cfae7c5) +,S(e77c81ad,e9f97b55,1c03dbbc,e549ba66,8dd71de7,cd775ad2,a269694c,7f60c7d1,3acf1478,eef81321,c5fc3b32,3ea81543,631470f7,1c2986d3,4ec581f2,82d72449) +#endif +#if WINDOW_G > 5 +,S(de2b5ce9,dbce511c,f2d8878e,3ded87cc,3d633dae,a2d45341,501fb3a4,55ccf6b0,f10576f3,d3c3e0e1,bbf717e9,8b1a3744,65b8c45a,c66318bb,34829eb7,11100666) +,S(d07bddff,d491a2fe,1ea59fbd,7c121217,29659ca5,de46658b,26b1460b,13c03c56,b2ad4708,cd3c97dd,f9c40e2,a1de04d5,61d963ff,8cc2eea7,6be3f60c,2b405ce7) +,S(82403e7c,5d3016af,3765ec4c,396ce8e1,f8da45c,434b8257,10edab41,bb6a4d51,d09661b,e27cb767,4456badd,b3e84051,99ab6ccc,4ec67c1b,11e92ead,7b463b19) +,S(eadc3131,fbd626f5,263faa58,c4caf4d9,930f933d,9541c23f,438cb486,750680cf,d3c977b1,c9b4a897,5c64b36c,972d5d01,a388fb9d,c3791a74,36094ff1,2c87a914) +,S(3903ee5f,6758ff24,c518a4b3,86748f4f,36bdd65c,b77e78ac,609f2909,fc7987d9,e92194e,a15241d6,40915934,bd234749,8d222a18,4927a8da,b0cfe2ae,182be83b) +,S(d0803b78,39ab48a3,8475bdcc,f9a9f219,5759c343,dbbf8e93,23e1f882,5be6a5d9,2cc3b180,ff29c97e,a12ec15f,b38bafa4,4ecf06c,e51d1d24,2894a926,64582f0b) +,S(1f56f096,b18a7499,a153a5ae,acf8be05,8496dd23,da8e6c19,215628fb,c0567ed0,fef22b8a,3b52f490,83004436,b65cd69,c94189f4,1a93c0d5,1fc13cb4,379dff58) +,S(1d9f69b1,a4a47432,e386f525,234aa30,79e947cf,cf203297,4e0fc05b,638e213b,d898ec17,949c0761,b38500c3,a2b1da24,5438d5b3,d3f6f720,41f15d6e,e4d4ccbb) +#endif +#if WINDOW_G > 6 +,S(128c913,4d9dcb78,12fc4361,5c67ad0,55213354,dc8008b1,aeb5a9dc,fb629efd,fee3e54a,dd152610,d9725936,99d662,c160c8e4,ec6f76e4,5ff41818,be67c96) +,S(21ec012f,5a95b94d,244b8d51,9756075c,301f2854,8e2c51fc,49c0e3d9,d1a9685,2def2105,77af497f,4c7fef71,6949f28e,7418eda6,fd5fc162,d128de19,3cde08ae) +,S(688f5202,fb9d8bc0,9e480e89,4c7cfc74,761c3be7,7dafb11c,58422836,3e331cc5,96ba7d59,63b541a7,2ec7cabd,92403434,1a393eaf,89eebd94,62d9c218,c7302cd3) +,S(fb5c9eea,1cb9a8f5,b3314c30,a50d35,744d0ef,e8bbf68,2e4d3ab4,f7f02baf,29fb8844,e18fc551,fb28bd26,95c5e95c,6868e0cc,7e526af0,91157e9d,fb630418) +,S(f1479fe2,2eedae3f,2f5f6a5d,84a9de1d,593168ec,7b52380d,e0b3625c,cac03421,1a642d5d,2fd88b82,13b50d1a,3fbd3419,c0b4630c,48352131,cb856b2e,22764606) +,S(2273edc5,e8199774,93c5b0e0,9fe0effa,f60f7b,2898565a,69f5c7b2,bf1a7950,b3aea238,8fd978d9,29f1a1df,98495358,b64691fc,4f50b530,906ae39e,fe7bda12) +,S(99f8480c,30504378,b47d10b3,2b39da2f,496d59f4,b1462856,56f05ad7,9bef5214,e001d55d,8e224286,8d8bd397,cb5aa99e,d930e437,e4e62151,71da7ae6,6264b2cd) +,S(382257f,e4751280,d74fdfc6,993c8642,9c000d5,87f57635,bc9656ba,996a6f1f,c2dc733d,fe52cb06,265a4f1d,a6b5f1f9,30dbfa39,e3659973,1c672aad,8b51d474) +,S(23a13632,9125386b,e45f4e1b,2acc847a,62e5eaf9,f6d5f452,6e145e7f,ecefb24b,9129777e,643ba22,2bf817a1,af7155f1,413cc370,3734ba6f,49f15f55,996854c0) +,S(6659ea60,58a664de,a35791a1,8c5cded4,8cf5593d,c440b9d4,8a30ac35,79149f0b,2adcc705,a85d836f,b347b69e,742fc6c3,5300d1d8,e534f1ff,c820c6d6,b2f2199d) +,S(52dc3bc6,e1acd3b4,7ece6f6c,89fd2a3e,2899b487,41421033,37a67dd,1ba939fc,5daeb346,32ad107f,bd83d9da,15a3c4ff,1e8f6ba3,ee5193e2,709e89c3,43d05746) +,S(524b2a97,93cd5745,bd9189ba,9c947bc1,693fbceb,75f074f6,17376b10,d5573551,9e8099d6,cb23fb1a,9deb92cc,3e8a2fb5,a6865ac6,3dececa0,2d146e1b,bcc80b71) +,S(732181a8,e2bc5953,923e6c3d,d960e9b7,525b7b95,e5906997,6fe79156,1782756e,2516c6b3,5592eb0a,42ba193c,bae98ab,e3c42d96,148f1d84,edac621a,722e4823) +,S(b8e8942d,926e38fd,f338496a,c2ef6fca,49a7ae3d,f76eb15d,8d570111,e502664b,7990d56e,7dea588e,4d670ba2,2031e6c7,97248641,69e51d77,f792f5ed,befaf8eb) +,S(144e88f6,3e73abff,72cac11e,7ddccf79,19e744e6,278941ae,18d1b797,e098e4e5,63cdbf3,5df3c655,c58197f,ea54633d,158705cf,7dc2eb3b,4e09f83c,3021837c) +,S(9436e3dc,489ecd8e,2d16a739,c9c73e3d,60e5bc93,68157039,75b8efbd,5c3a9081,1460531f,50cb6ebf,d1aa7806,ea84e7f7,8e8d76b2,b3a66d5e,3a0bf60,39a7e59c) +#endif +#if WINDOW_G > 7 +,S(9d3c2561,7a56d10b,46d9b01a,1710d193,e840e005,df669e76,1936c275,20890db9,6bbdc0bc,4c4ae9bc,c2dfee9b,82da9b94,1f89ffcd,e8af2aca,4467ce3,78521ea3) +,S(29f98e50,f51b7f8b,e18c6ae0,b453c4f2,d0aca5a8,b0e61d2d,dda8506,3fdb76c8,daf3bcdc,ae8e031c,73eb8b21,14058063,58a6ec30,ad379186,df80e3c7,f0e5d28f) +,S(d67d30c2,c71daa36,1805e31,1dd6046e,17a89752,94d76e1a,538af074,4dc22c94,48b9b0e7,12c807b0,b92e690a,a2e068cc,e87ebbbe,aaf4bd96,9c1114bb,a54f670c) +,S(f22c2ba8,8ce9c2e4,b772c9b7,6d03a017,59aa7b9,97a78334,83566027,2fc81649,6aa9e710,f190be16,243a4e0f,1570270a,2d92dca9,8cf99a3,cbc06fdd,f9b7028f) +,S(c5e718d,6b94c83,e52533c9,ef3234f,36b722ed,cfc074a5,eff30969,9ac5f894,24961051,ccfc6619,dd64e810,fa9c504b,f7f8ce9e,cc445d7e,642b3166,eeef436) +,S(26a8bcaa,c836eb7d,57618999,ef87ee4e,c291dc8b,333554a2,c1f66f73,7944d611,c20051ba,7236663,ace2da29,c1e0763c,e57192d0,e199e7a6,c69cc65d,bbbcecc9) +,S(388e3570,fb7b1545,9bf01ba1,7a6496d5,6bcf65e1,764e7aa,2c083346,2dfa098c,2d4e0d22,a2eb0ff0,545561e5,ae344be6,99120d12,45db6bde,a9500f5f,a07be798) +,S(68189bab,b5a0783e,23227efa,4eab2c6e,da2d1c,2ea57fca,7a7f8f72,15250709,bd30bd83,3694d3fa,a14954f6,251445f8,3e42d517,30d30855,a0eb834d,3c7ae856) +,S(642e0823,bb347795,967b7aa9,418a25,ea6ff683,fd7b3d42,b88d90d1,292190ab,db73dea7,86ec052f,e3674892,639daf39,286b4690,63b68903,210639c7,f3b4000f) +,S(9ab6ea81,e5bf5505,751addea,5896afab,7f4eff2f,d3986027,f916835c,64924afa,38c06aa7,4870a5e7,2ff29efc,bce4b3e7,dd951c9b,29966f2b,47d007ac,7629bb6c) +,S(b09805ae,e567f69c,71a98248,e89e64f9,e059e015,bde01a62,dd18158e,e94a8ee7,62aea16a,7ec912ef,cc5382eb,6d220ac3,dea885a8,e3da12c,8147b28e,1983d221) +,S(3d632a5b,636ed5a3,4a58bfbc,9831691a,91d6b5f0,975bfb5a,82b4c1bc,107e6e5,577a449e,75bf16d9,2eb6ba0f,9cb4d496,7a7ee09c,f1605aef,682cfa31,cf395a1c) +,S(6b821bf0,f70d5ff2,ceedb69d,d96ac8bb,b51e3635,3a36d50a,b1c1a697,40cef707,5212ce11,993fc120,88028674,5cddea94,6371b4,dfa2f47a,6d83b789,c6d12e5d) +,S(bf294951,4496fe0b,8527740b,5cd9394e,dc33b330,c91d996c,789db854,45728b23,790aede5,da35ce7a,343f745c,410de38f,4c53bc2a,bb41bbae,c13272b1,e912782c) +,S(a55354c3,82bf968a,16668267,c4498946,4906f69b,114f6f06,742b6035,1d75ec80,2809bddc,45661a5f,28b31967,6cdfb5b1,9dd6d296,d1828c88,179a630c,ca5962e8) +,S(fc015036,abcd8311,bbfa1574,ffb4980f,b893f8af,84f519f4,5a6fa344,2649a693,d0f6a278,1946e04b,385cd004,29acd3f6,f5542aca,3e7c789,657f676b,f19db819) +,S(6164410d,9f81f352,272a799f,b4afbe24,59caea6c,511fa4ea,b7578980,d9a7aae,92bc1480,ba19fcd,3cbee69c,95b9396f,4982fff5,d4e7dac0,abec7153,ee5a7966) +,S(ef816535,8de9d737,728f9a9b,3182b4f5,6e25917d,1ec05fc6,faa0fc85,170b5f2d,dc372426,403ca9c4,50649df8,8b6fd32d,f1721dc,cb1c7d7e,155c83ea,747ec595) +,S(428c34b9,89a436dd,dc704e68,170d2c40,178c5646,841eb2e2,642c0a48,8987a8ed,b1f24158,251c4646,ca04dc3e,64369634,3836f97e,71945f4f,51237abd,3aeebe06) +,S(6eb61782,f909157b,415e6243,7bebbd6a,5f19da73,7eda64a5,5acfe206,65417a9e,4fe7c546,baedf2b1,6c92f168,f99c42f6,af03edee,290ecc39,4c4efff,e8577b72) +,S(992e0af1,466d4fec,5ef83009,98ce31df,cb6f9573,d14c1646,e4371c62,a376fa4b,d0e3da69,1e4396b2,eb01e3a9,964365,50d000e6,31d79ae3,871690d5,29f9e825) +,S(fedb564b,adc70078,f20f31d1,12496934,513e9903,8cf5b9c3,1084383,5721d11,1a8e2a49,57e8420c,f2d5d97d,657f1602,ba26ae87,d5408b2f,a9448def,38157a39) +,S(f3f2068a,4dd89d18,1247088d,3c424916,3e683226,6274b575,e54430d0,73b24bd,f2aabd19,a7f462,1426ab1e,e0aa7e33,12381c5f,e1f1cf0e,75c1a7f7,7ba2bfa8) +,S(32b9225e,4217a359,8de4e7c1,476a8581,5b6aa458,d93dae02,b3d30772,3ca13680,7466e804,26856340,12985683,dd071e97,53246214,733808a3,96f35d0e,5a133802) +,S(85008a87,385ed6b0,4ff89979,2eb592f9,ee6c6b93,fa24dc7f,c6299b9f,dae64a8a,1f279e2b,8a5b0576,fb9569f6,c0825876,84b5b38f,a250e362,2ae6e284,a504a2df) +,S(4dac7833,ebbeab0b,ec8edac7,cfc49bfd,b835362,f0130e9,e44452f6,a82effd4,fc9d1970,f230aa68,6114ada5,7b4237dd,133dc3b5,db8ec1f0,ccd09aa,23c740a) +,S(9b755881,45a65d54,19b40226,e535df5b,4b44de41,1b93d71,31f3102,d56dbeeb,d0324171,d6937b7,c9b38290,7dbba3b5,c1516061,59e7ce1f,a1ed9d11,e089a02d) +,S(1bd6ceb9,2592a7d7,a66e6e8b,1b645db5,98b525ca,461dc4bd,b583ed9a,cbbc8bdd,9a59de87,84a98bea,48b7abb1,a5b7055,5a1c4ce5,551cde4e,7b790ac4,9a29944c) +,S(25a8b2b9,3b360941,6525b08a,7fe786e9,6b3a3c7d,8b444637,268f5355,bd5b56ee,3c58ccf7,5734687f,dbd027e6,3ec6c550,45f131ae,df71a40a,c45e4e8b,965f22ec) +,S(244b2833,27c33efb,221a5767,15225d6a,bf5a1caa,8da543c0,d88b21e5,17ed9f5f,220036ac,e48d8953,5aecec92,a29f5012,37f83ce6,44380db,c229f0bf,c1f53d7d) +,S(6f97ac0f,27b87905,6b442d13,e566978e,91f0cc1d,d6ac1e64,e9764a35,325dd1b7,83c6e70c,fac6c707,226ce1cc,691b38a0,7e937f5a,5f2d9c81,4dd0d3ff,9f433d32) +,S(72c5d60f,eb014e2d,ba8265ca,d454f261,2d6abcd4,b2236bad,c94c4801,561dce1f,e3119a19,7ef91963,b3b28216,3c5d3acb,97b281b6,d246cbf0,690b40da,63978fe2) +#endif +#if WINDOW_G > 8 +,S(a96d2da0,1b10186,6998659d,f441a1b0,2af32b94,aae8c6ea,707d9ed0,d5f33825,660d7d83,5da5235,9f7cfd41,28c370aa,5659ea71,16a91690,6c0e8108,a513f9f) +,S(2cce6f63,4d815ecc,1981d200,87616677,d906aa27,990c4875,17314dc5,5be3c4fa,615210dd,bd599e91,1b6f997a,fd05475,b33cb274,c9ecb6e5,d3c23323,beba4b50) +,S(992b0084,525dd399,d98602d9,8b8d53b2,4558fafc,758a2f46,60e89bd6,a645f0c4,83ca98d2,26545a29,8c45f40b,11420602,f5a5c70e,595eea57,2da64d61,a4e2f98d) +,S(434efb45,3089619f,cc761ee4,3fd4b77d,c6b0c69e,b45eb88e,44ef766e,9beb7357,3dbb0d6d,1c0b92e,5965586d,236c0be9,26967ac8,830b9bd0,1e9efc2,2a9291ea) +,S(a2179ad,2c683306,a2e4735,93efe304,f0dbf589,c4dc2b88,4bddc5c7,e3fbc156,ee4539f8,ab980176,a18e6dfa,bdb609d2,88a2d223,86dcb20,19207afa,f6033c1f) +,S(3934081e,d3e1e147,aa52bb40,9221ef6,a445f22a,66718f14,6d63907a,ef05a2e1,bc370656,31391b7a,209e79d4,9f1e959b,d3a9fefe,752c6062,14fab290,a7b5b3c7) +,S(35bc24e1,59a2b939,438354,6cc4255f,f1f3f7e2,105293db,39688e07,df95d8ef,dee1fc70,a9698da,f7abeb5c,56724f8,e87e0cd3,8849edfa,246ed0a8,9223ae15) +,S(f5d1e75c,251fb473,8552a0ee,f05d8e65,63aa14e1,bcae5b48,bc7e5258,b948127d,e260c1bc,7044f058,8f409134,d298528b,e7d586f4,bf7b6fe,92d212a8,6f7170fe) +,S(ee0a76d3,6fed282f,a1170dd,6acb7743,f9617bb3,60350f54,d12da1cc,7eb121c,f8cfc2db,eba6960f,e6135ef,ff9e10ca,4e56c458,4b42b516,6dbf7af1,420ba5b1) +,S(9e3b87cf,78927664,15cab377,f1774d14,4d1879f6,16da5676,f94790d1,9ca689d8,f8f34522,da3ca2ac,b273b0c2,b1b1f26a,7a9c2d96,b4547482,266a8e6d,bab3b577) +,S(e26f256f,d08942c0,3c85b89e,e66b8b50,12f409c7,4f625152,86e5b310,eb4868f0,bab3c4d9,6fea49fa,6d08c656,23c9b127,3552c23f,3c4f12f2,1bbe8bfb,56f210f9) +,S(8ac74046,a5d38398,d14b6763,4f07abc5,a3f5c852,ea8c421c,f0858980,11da6c2,d20ca793,f56e3198,854f5916,35402c2,4a71af95,c84288e,1495d324,7229b3dc) +,S(5b00e095,634694cc,93d531a8,6e81d29e,753928bf,b2c83a83,ac677a92,55932bd0,8d2f267a,8071c48c,616daf18,d587e,42882b33,748032d6,4bc3efd6,60a99656) +,S(162190c4,80c5d7b,ab1ae4ba,7b2a6611,546ffb9a,b4e9ea87,2c0357f8,9e11f0b1,db5e2104,12448a9c,e586d7a3,13bdcc6d,bb84192e,98c5d9d8,79693030,92423525) +,S(f6a84421,b4b383e8,87f8520,e06017db,476774dc,9aff636c,f26a676c,85b145b1,504c71a9,596770ed,7a2da8,2e8fe1ee,93717215,bf88e0a8,ed74a80,4037a3b3) +,S(1f02d142,f0b5d3d8,b3f8937d,a49f908d,83e5919e,55c9c134,55a759a9,932dd6e5,e6a5cb33,8ed36df7,50ec2eae,5db7c9ff,fbc9035f,48ae0348,fb3882da,39863e65) +,S(61f4d96b,c326a1fe,a2ae38c3,73484a56,68e29bf5,12d77a04,34a62278,1d78899f,651ef738,62005ac7,64f97021,6180c25e,2172724b,375e6b38,b3a37ad2,d7b4aab8) +,S(ba7d5c0d,623c5e79,8088a71f,8d2916e0,7c7ebe2b,1afa19c1,9c917cae,31c11616,da409f40,d7e3f6c,78655153,fb35595,a1ec37e7,e66c8958,ce45b07d,bd5f5a51) +,S(8b90a590,eacb977c,6e6a68ee,6dbc3e19,fe5a92a6,9abc43c3,bb16f9d1,925bdb09,a5cf5f42,ef655d59,ae734e1,f746a752,4d01ef75,d829b9a9,2a035180,fb5df718) +,S(87f35227,21914cfd,ce8294a3,cb5ae171,f0d994ff,f55b25b7,1c9e9aac,dff4fe4c,cc71d1af,530bc5e1,eae7c1ef,b9a91335,f26b283f,222a3552,dda24c28,64babb2f) +,S(aeea4d36,ba405159,bf0ffe8a,5530f1f3,83d5509f,187ef58b,6c1eee4a,cb77a15d,db563dea,e7403df8,7d3031c2,48aaa28d,96958f7d,ce36b3f7,8d55607a,60d3ac1a) +,S(300fe98d,3996eb9d,57c6f1ef,8058d4c,d8dda436,5774edb6,2a338a59,afcc7111,d148a017,8fdda40c,f937913c,143b76fd,d2e6e226,d27225e3,a49658b2,38c40e77) +,S(c700af5e,22cd146e,839095a1,f6743e4f,d01e9c1b,76d4c73a,a5005f42,99c19fdb,3fe00181,b1f01c27,27ab1fc6,bb6ea569,d4a3092,c2d511d2,8b5546aa,194b32c0) +,S(d03d08e1,17b94138,1aa147af,38448539,94228f75,f96bb4a5,941c3748,cf50bc60,5b119ffd,2785bcc5,2e0bfbfd,c541da8d,f47dd076,e91440fa,10e071b3,a896e31d) +,S(6c6710fa,17a520b8,56d7fadb,6af81a5f,ea9c983e,c94cf832,b395da5f,c22bd361,db4efd26,36e281ea,419964f3,c0897b05,b036a408,25ed4ad6,4fba393c,f2804941) +,S(d7b5c239,9df47a16,6b6cb900,d08a5d9a,5ea3bfe9,94f861d9,b46f3fbd,a3d91bbb,ed791f4e,4ab1c25e,9c83494d,794ffe1f,a3c8a065,29c0b710,cffd597d,64efe8ba) +,S(90f699ab,8f728152,e2deb8dc,ceaaa3ee,53ff2f23,2341a952,4aba9e8e,50f66c06,8bd0c3a7,7f5312bb,9d46d80e,c36921f8,561558ce,6e63c08e,641c82c9,fefce91d) +,S(4d0eae3e,3d7adc34,c91eaead,6a16f569,37557dce,2b68744a,bb9ae71a,8dfb65cc,816b0806,a9508731,ba99a685,142aa52e,6e874c99,5096a53,52c6e2f2,1fa3de5a) +,S(46cd9edd,ec318498,dfb4f815,3315185d,689a2399,8e06b1d0,2438f7c9,b2f7de62,3b5bc1a3,d5fd7874,8c964a8b,b813388b,e0d5d168,1247d008,10a846fa,561f29bc) +,S(4aac80e,3f6eaab7,1c576297,b4552e40,653748fe,21a580ae,bce4eb83,2ff730b,3d42a00d,8014f46a,80fe2dd5,bac6a046,40d331a9,4f1de050,9e435398,6c8c7954) +,S(59bea661,b73d9c09,131e4573,199937a,e03e96f6,2ecbc637,4bb681a5,582a4114,31a20be8,ee8a2c2e,81d062e7,8e891504,d9f2639a,bd5db5c1,30be3d2c,b1afa47d) +,S(7fe9065,88b2ee92,2b19acd3,fec7a4de,9ee089a4,a4e1c338,5e293567,90ca6037,dfb45d90,c5f43eeb,1f5eb326,20763ff4,2659b763,e7ec72a7,c69e9369,35e5c128) +,S(db390f91,32277889,784b5e4a,cf8f2fd1,f3a5fc47,f2c8262f,19dc9518,95322157,4364955b,241c831f,94fd7d4,da63db19,2aaeb5c0,ade82dc8,d5d61cac,d690bbad) +,S(34dd0266,e5fc19ac,7daa9e61,5ae8f78c,985732a6,1c53c29,e6e5d407,7391ebc8,c2d6b6d8,e73fe00,e6013b1d,2c2b48bc,77a5db6b,45232ddb,6611ea1f,c5dd797b) +,S(eea7f72b,7e31608d,d3dfcfbe,16e2ef95,5e6c7ec5,328f84db,336e3df1,9d1772ab,9662c8f1,ccdea4c3,48ea6d94,739aa747,17219556,c6be9b8,8af0d30d,514004bb) +,S(c6af087a,f1b10eb3,93de412d,de856129,9376d264,36d907fc,10d3e7a3,88c391f2,ba99d62e,31856457,8ad8847a,9cfeaba5,e5ff9824,2c614959,eeeb4ae7,50825144) +,S(eae34735,6c715740,ab73d034,bcb43f5a,aff37fbf,50d35518,1364c999,feccefc7,b9386c75,da8bf645,cd6f15d8,4944f74b,9685256d,b61fda98,79fe6639,92fe4703) +,S(4a548c25,f4d8f54,4f9a27e,64e49626,41b68ae3,1d90461,65c24ff7,fb40438f,ae9f2c85,bd608cf6,ef5e40c6,7e29a63d,4c274215,c2a0d578,38252f28,196f6d10) +,S(61925679,dd6545a8,ea19743d,7cb3c0bf,453318d9,e180da53,f43af2b0,ecf744af,a0682d84,d7215372,e9ec062c,a3e4aa1f,47fc551d,44e3d1a1,7260a44f,2bcb184d) +,S(e1db5e86,9574ab76,d4fa260d,2425ef62,50267ab8,52ff04fe,25f0150,9137ea2a,c8eaf421,9fd5f7a3,6c1a99a1,d0c61250,836e204b,fb496774,83f43c81,511905a8) +,S(3062cbca,73923842,2a0ab862,a1fd84f0,38e63691,cfc204a7,d2f9d263,d248c7f1,8f112e57,e3f2970,dce89eee,1e184310,721a85f1,cc9feb2c,f55c047f,dd9670cb) +,S(67c393cc,aa9736fc,eec7a861,eb53f953,9da74ff2,97764f4e,4e814004,4da4f739,93d329d0,9a165fe2,2f8009d5,ad59b524,33ac24d5,46c7d394,2d147c4d,49853203) +,S(c67471f2,36cf2187,ee5a5619,d581cc7d,ac5bc5b1,e8bb728,f943084f,e899bf5e,75c90c9c,787b318d,943c3247,74cbbcc8,3a533f37,fb684aea,62fe6848,8de2c513) +,S(d5015fef,d5938dd9,2133d7a4,25aaac5,12143acc,6547070,1827e98a,e4ed1b52,44305616,a02236f1,5c37c0d6,51d845dc,e9966860,b798f79f,4006c25d,7cf03d6b) +,S(aebcbf65,aaa89615,cb48ed56,4002ed9a,243ca309,1cf503b7,3c1929ce,8164f2d2,4fc1f25d,1a30ee2b,4220305b,a9c88e86,a6ee7f55,55399ee5,35e7d37f,e4b3f019) +,S(15cb1617,1727deef,49ad6821,932a39d1,bb8f980b,b5370d81,5ef00ff,ebb30e43,64ad8c82,87fc053f,ee35c1b9,9734b34d,2dfff86b,490ead93,b1fe7d2b,f80ebd7a) +,S(d404209e,8530d674,9bb88a5,525211a1,19fb2523,63e2698,6bd03080,4c49c123,3763fd68,fdb85d19,e8506275,3b5a327c,46ef87be,8a3432c5,62bcc622,40a7a128) +,S(f3abf8cf,c232849,58e330c2,fc327ac4,d40b4497,f422aa4e,d42e9381,9bffdd96,50861f05,d831327c,3e907643,2d7a7621,d1dfe9ec,7ccf2061,cc720e9a,7d5b0d5d) +,S(78a32893,2ee9dbfb,3f84755a,651b9d23,5cf92b46,c3e4bb4e,57b7ff6f,7c874dea,925b783a,966721f4,6eaccd87,495eab7d,b3c36eb2,92c1a473,b4617f6b,9ac85895) +,S(8165210f,5d146f8a,1ac1ed91,a7bb678d,1b7d15e4,3ed55e8d,f6503209,a750cd4a,fe390d3a,19e22bdc,cbd45875,e396c713,85954166,a1edb63a,384b8587,915d260d) +,S(75269de8,6c2f3d34,cdf17dd6,f3efa198,ba73431f,cf0072f3,633ca57f,7dfe3f09,b162a65f,d19927ec,4446e3db,d5ee8850,f463f39f,1df1a0b1,f5ed153e,704805bd) +,S(5e36ce8f,b393949e,5b9c4e10,44fb2ff7,c520a7b7,a9016b38,9544e512,427145b0,7c40e718,292f96a4,1d9822ce,d54aea90,22074c5c,c82ba4e,7d39a4e0,7811614c) +,S(c8cc7129,fdebbfc6,c0576edc,6ac983e5,c249d360,76da7d25,b05c0b6b,16632746,48a8cce3,a77e4498,76d1a332,c539feba,2653fbaf,d4f75e68,e4674d78,4c716fb1) +,S(9fe1db36,f1ee3e6d,3924d2a9,ae3ddcaf,fa85798b,7383a1dd,2d6c0c14,ea46973f,1d35b6a8,607045c0,95ed9658,80212b63,43dc55ec,beb3223e,7c2e76ce,2c74f6d2) +,S(4ca8ab8a,3d45748e,6e19e02d,dc351279,e23648db,d26d2465,7c9713f5,bc8ecda2,8a5866ad,9bb7db92,273c9f23,c0876c95,13b8a68d,bb20c5cf,164a9a39,4e3e73da) +,S(c8d0150,e4a989ec,5cdbc724,21b1e29f,f1f30818,1d8117b1,3d376f58,b72060c0,5c5880a4,c5a73a4a,1ae42a9d,f0b20032,7ac4a732,cb26e717,49e63365,5082ebd1) +,S(3d61557b,b4b9fde6,49fe1b7c,981c9883,9e368444,f130bfea,fc1e1a0c,12f2aa31,933167ff,62cd840b,3a960c90,e6b1c37e,1e233695,318ea286,71c87992,de5b56f9) +,S(67569f9f,fd44ca09,5b478dbb,85c3ed1f,feaadaed,cb624552,ccfaf169,24e69e2a,62bb2948,230fbd2c,aa941288,7adfb24b,d16619de,af0fc102,feb1b26d,67eb7fcc) +,S(6313d13e,debf1401,eb7d279,2c66daa8,6e3075d0,3cf0daf7,f3b753e,7372fbc2,44621230,50eb1245,86975455,63e06e2f,2839f874,beaff9c2,f65e26ad,d3573ef3) +,S(6f8ec9e7,fbbe6e8c,d0e3085b,47c6cb2b,88529f2,15f13195,5e2fde24,4dd23968,1fb61e14,523b3fae,b543b215,dc46eeeb,23e1950a,8301c78d,c510c76f,ed36cd79) +,S(56613dac,3c5aa1ac,bd9a0ec2,f839b4c3,36f0ae58,e0e02244,7bec0546,710b7f6c,247263ab,86c398f9,3b23319,4434af8b,530908bd,dd7f716c,f7b73aa9,8eca79e8) +,S(c9de15e7,b4147219,137e6e57,c5a7ddd6,17e91ab0,6859dda0,41eb3c21,87aee08c,c7178ea5,cfa056d0,dfd11c87,715591cc,40cc5db1,f5e4b70f,d8ffbfc4,3f8b0009) +,S(7590a4a,627d5e90,e42a4b0f,6be6497a,f906182d,d2dddc48,a8b6bbfd,f56c0504,d611e21a,b5498760,5c97e878,baa464bc,cc5bd875,353b69f8,1f93ce2a,a6c38587) +,S(94b1da0f,b310e056,db0dff72,81db3362,1fcc555d,bf3c973b,76097908,7fe19d6a,8318893d,d5b41a56,33a2ab4,ae4b953c,45c42e9c,8f2fd159,85286de3,fd4fc217) +#endif +#if WINDOW_G > 9 +,S(b5af4299,bcdacef1,e07d081,daec2cfa,d6f8f821,38e151a5,f20e6d52,84c9a6cb,c0984407,8a7db82d,f572987e,b137dc09,c8cf65fd,aedcb20,43b2479b,ab95448d) +,S(5f49ad43,70744587,3980a153,c851829b,f8ef6141,9889bb0c,3c476847,6939c3e3,5c40d385,20f56c3d,ba08ae1,b40fc24a,2ae25c94,45cae0f7,d01d1800,747e04eb) +,S(f6bb067f,88ccc11c,64e30d1a,e6893942,16bea3bf,26ec9c64,5cde1b9e,487da385,315a476d,7268978c,d89d4ec8,adde4a83,28dbfdd9,f2bf44fe,ad4ed721,78288f55) +,S(7b47cede,c02b19e0,94daea0e,ec000455,52690b49,44b3f10,beeed2bf,f9df6950,1bcda5f4,9beedec9,6ebac5a7,957918af,53b7ccd8,c211330,280ed93b,e0efe9a6) +,S(ba69d7f3,82d56d9,eb65e1ab,2d70f52d,18223621,c0029035,a78fd660,9940876d,5f44a2fd,56d5289c,f36bdb9,50ee2538,1d1cf935,ae1aec76,84b6d11f,975d393d) +,S(a3b70894,d226c195,223713bf,330ba39,fe7ec35f,9743347d,1d3dfdb9,7bd929ff,5d0cbdf,42755aa0,355ad2e1,ab39479,495edf2c,20bb0aa5,93cc04cd,56ae6135) +,S(c756e23e,bb2d81fd,91fe73b5,20eb3bfe,5ae602b3,448cf84f,e8da37d,d1c804e5,89f4b6fa,edf86b9b,ca9f52b2,9864a982,5a4faba9,d4fb35f8,98511210,34df49ff) +,S(36327c35,6fab94ab,f791c234,1c39049c,65410e9c,6cdfaa00,d172ee84,3671822c,fe3588a4,698c8d35,f0e01f04,e94f7039,eb745631,8c25927a,be7d061f,d3ed4c6d) +,S(3b75bfbe,8e372311,f46ecf6f,c5eb2af4,b66051b1,874b0c32,1189e106,37dd21bb,b9144a33,e3c3339a,4595e248,87940b4e,2e42a095,d7d1bc2a,ea50aa29,5a879908) +,S(44a61f10,57b4e88a,c55ed72,1f8f4477,5f0272bd,379a97b4,d92a7f75,f0d3c5e2,e870ea65,80340464,9716ec1f,5b79392,18162306,6dc14086,111de144,82d80141) +,S(11ae02f7,663c0a,24c6fe5,ce9206ed,1ebed2e6,ca294acb,74c9a227,97fefd,635a1b87,a262fb30,5008737a,e70422cd,a4e35766,940e424b,d697d28c,dfd6a36f) +,S(c751310a,dfb25d14,2e6ab1b0,ab31b37c,8e987af2,105d5981,69085ca,3e142f5c,a4630dd8,ed2717a9,f10485a4,be685c5a,ccca851d,4bcc1886,4df943ba,ee821014) +,S(fff4d7c6,4009f39c,41757b17,3eb2536c,a639b72b,e15af7f,790bddb7,efefe46a,694a798e,ffe22d1,1030697a,292a4bb1,4c110d6b,dad7edc6,e8976450,ce5080e5) +,S(7d76ea39,c13c9f46,e931e8bc,1cd43707,932b1a,31254d18,c06c8ce9,c3f90534,bc14b2ba,8f0a3d8f,34c7cf7c,3458c916,4cee438b,39a5a6d4,d2a1c9fe,8be415bb) +,S(b6efcad2,ca6ae4f3,6f080707,530aaaad,625fda5e,825f77e8,a6730e95,5e07ad39,4868d8ef,8a56d327,3f6f4a3,23ea6ad6,4694301a,1f6405f0,a421939,bdb1c765) +,S(1a04b12a,a889c4a6,d37f9050,e75406d3,48e38faa,c0d2ab4a,e30caa6e,3633a32e,f43a0c8f,fad38d90,6c817dca,3e7ea09e,21e1c801,7af86966,c246ebc8,dc75911d) +,S(adaeb0fe,9b345190,4e878b12,6c8edddf,b70e2500,5a4d6a6c,531aad51,83209b7e,2b26b16d,dd4d29a7,8cc6b4e,198e6ede,b1c59def,c6793173,f33cb039,d37522ad) +,S(4e4ca02,3931f3fc,b512121d,2d632764,d97fa125,8460d0d1,9a94eb88,2c6e0679,ef90eecd,3704a6c9,454c6860,928eb332,cc917b17,f2594348,515822d1,84537467) +,S(a1f3c279,df69c13a,711b5ee4,139f603b,5654ecac,adc02a22,a7c2087,c11e2971,57249794,54cb78dd,7ef69916,5efe2326,e8aafad7,a8a923b2,252523ad,b6a16b2d) +,S(aac76f81,488668e6,f4b0c911,bc9675ff,c19424c8,6a6903c4,f4b13e0c,e798c7a5,24ae16df,dd6c7d6c,1391df3f,73609bc2,c3759536,eb277189,588a72d1,84dd2978) +,S(70e94171,e59622f0,de360166,6498e6c9,ddce496,a15e30a2,a5bdb701,d0034769,d6d7c0a7,75a9cbef,2b84d4e8,200f92a,446111bb,cf46a57d,5e244f1a,1103b757) +,S(ca17e5e7,11d44492,496fa849,c6ab1c47,3426706b,5b8282b6,f288e096,8ec78890,b3ddd632,2ce577b8,ddb9f501,e17d32cc,e6c58fee,4e283410,5e32f3e8,8bce2c2e) +,S(1a16a58d,8d70fde8,6ac0700f,3a43ab9c,255ec001,8d5fe571,7ec6324a,2faa62e8,f2cb2eba,65aff0a3,dd7bc137,257c1d30,dc2eb6f3,7a3897e1,16c0eb1d,1a710c27) +,S(8f2dde65,b4ddf10,c29c6bbf,5ab2ac11,2dd3357a,e3e5f01e,98190e32,94b9d4f2,e06b8cf7,e5a736d5,4e954bd,8591f7cd,79df335b,d3279f5d,80493fe4,df4c6afb) +,S(3314b553,f8213e7c,80d4562e,cdb3564,ba1d7285,6c88d8c5,a3adda90,4950162,33e83c5e,e3f7c550,f94a7434,e3cad51e,b4dab462,13acc24,fc4aa1f9,fc43532d) +,S(7c107ef4,65ac0c2f,fc5b11a3,348a7cc3,fa589554,ee2b6606,2af3c5ba,25304000,6b5bcf12,2e8a0705,d067fe78,e56d365e,89b5a979,c23f124b,508e63ee,975702c5) +,S(e918a829,325adf67,511e257e,e5596d08,19be4605,36b20cb9,7b76a54a,5be4f8b3,1a92f0a0,b46152c3,e1ba8f0d,12119c15,b70af0ef,3ff0ebf,a9dc9207,cf2fa8ae) +,S(8770da03,d4f3a4b9,e92dd2e3,be309c81,c346c97d,2cea15d1,e3fc94cf,41b9b079,d025430f,dc633d57,18d372fe,64f57fac,53f96461,1fb5005a,10ce842d,ab123c03) +,S(c6b4ad3f,ae2b2557,b126a57f,6bbc039d,a6589f70,c6283ea1,7314aad5,acd8b22b,e8523dcd,2c1c3412,35df278d,e49c38df,85f2888e,cf3c76fb,46e1affa,d8d29bfe) +,S(9aced948,6ffbf984,373b1e91,ff871619,4622741b,1e1ab968,9c88cb70,37a86e14,d7a7eb1f,1b4c31df,ff43cc32,1949c1d3,16e1e7ec,a6a852cd,e8e7f592,8b352d9) +,S(af51536f,fccbdab4,c4f4015b,1e8aca69,b08bf055,e038b22b,87c54f5f,1b9007f3,b6bb0b4c,95c07ecf,49ffa85b,abb1d308,cbe813b7,703a27ef,cf849e,47130f7b) +,S(ec5306df,3ea0abb5,6fc45a09,25c1c925,56e02ffa,18238c3e,5bb2ee53,11823ce2,c950cdb6,720f65f4,18065352,43c90bd8,9457f4bf,d941c9f6,89812840,2dee8b99) +,S(293b1ca5,be127bc6,1a397ecd,59164363,587f468c,81de4d87,6c5d9bae,e72d90a0,4821030f,238e9f05,e93d81d9,1764863d,443a524,3d18e61b,ae26f74d,ba35d821) +,S(ebe54b7d,99876ab6,b2951f0e,e68bfc10,16877142,22ef83c1,2561f486,b4865488,2a1d651c,caf8802f,fa699d91,b8242f51,58d84fa0,d481bc47,9246eeb8,6d381c07) +,S(88f77523,3ab0d69b,ed220109,b29d0d99,33ac8325,445d19df,d38d9c69,3464acdc,8f915122,fbd95ef5,31ea2cb1,aec6bebf,8e059059,459c0d5b,79a282cb,cb276702) +,S(1d84753d,e7210dd8,9db6cfa0,8ebe9797,c7fa40b9,6e94439f,b8117359,a2b3bb01,f7360b5a,ba53a4d8,7440b6d6,f540c485,2e889c33,9f34260d,abfa7861,f1f41ad6) +,S(19e69df5,176f82c1,cf1ae032,cb388ce3,36f82a3e,5e741e1c,27fcefb5,311d4b2f,c401f4fe,c9ba53be,be175dc8,cc1d17b3,9d9f7af,5bb496e0,b95bba6,cbd5c143) +,S(73189e02,c1f125ff,df1a9399,57f29aa5,19b04f5e,42adf729,53d354cc,aee3f2c9,52b8e88f,1c6e7cf8,621d21b0,1e406038,d901de1c,4101d424,1009c01,a537f704) +,S(c5ebe082,8ff1a8bf,52f8956c,b747f1d3,278fd2b0,a5ae7669,1c256e9,2887a74f,ce58cb9,62e74b98,1ab97dc9,2d736b5e,c506e51d,6c09b382,3eff1cdb,cd259860) +,S(783c1621,f7990e01,4296feed,3bc883d5,1a780867,c83b9166,435a0562,4982da76,370b3e2,c9a189c6,9c565c3e,8eb8019d,f5224574,bd5ffbc6,22f563e1,8a36da30) +,S(555e7e80,ccc6a46,1724cbd6,4a53721d,fad66fcb,2c71d579,4d799f6f,fa2b3305,67bbf165,d39d7042,18f5ed31,28fe6dd6,db9b4809,b3270eb,63bda603,f44e9e41) +,S(40c49a26,ab1cd46c,f1e8467e,242c6b1b,faa40a4,cacdd50a,4b0213a5,40243471,16950b00,5002622f,e0b9fdb4,c34224c3,ad55bf30,67f4e96b,dc2813f6,2fdadf86) +,S(eb6b3be5,db098d18,9c810b9f,5593c746,47306226,d77e162,7c8b62f6,d7935298,3d295584,3f356f5c,1f990231,701cedc8,c84e9671,44be22fb,9bd74f0e,15c5bc8) +,S(177218a4,2b55c169,1ca0a073,4d061b53,a0683536,9a04fca9,3f670ce,5eb26091,9611661a,a8a3bc73,7717f243,e5e8b97a,57e0e72,759f0f4e,cedb690c,b3a5fa42) +,S(841a8fa2,f3bc5f8a,7d028c00,127c267a,ea0c3762,8b07ebe3,7f883a67,8fd2a680,579bf37d,b2fd1f77,a0057712,88dbbdcc,526938c,4f9ba89d,9a42d4f3,452cf1b0) +,S(b01ef554,3a377f1e,c801421d,a399c53c,3585789c,d7e51691,32250a61,6edea82d,28f30ce9,7e29b2f1,3af626a0,7a37f14,82e119d1,e66389eb,9620200b,25a90265) +,S(b93e014e,8e3cc643,17ee70d6,ef8c9918,ba344e7c,b38a9a6,2591b0ac,4f38904,129c185,5bdfd10c,6bf152e1,2ff89b4,d0b368ed,c0ae01f7,2b29fc95,240ac3d3) +,S(e0f426f2,43c50d9a,ff80a1dd,26d63189,a00601c6,8ac81373,5fbf548,7acd522,96d883e0,951adc5e,304bd848,ccf39c2a,1c19382a,eb24ad1e,1430d705,deb749fc) +,S(e11e9c74,40e897ad,2870adda,63b9ec04,d5379f14,b3bbbdf2,147ea9b7,9c73233c,49d6e54b,29197532,3f5a9df0,3e22e359,e125e34d,d9f3d6c5,cb9f0a20,6dc1f019) +,S(91ad584b,c5ef145,3b796eca,20027cc2,ae38ee70,9ac4591c,79cf67a7,a96b2c2b,d815a213,a620c531,11f79e5d,b5d9c3c5,565dfd97,ece841e2,3e9c1ca7,530bac2a) +,S(3e725392,f4fa34f2,7413785,cb322f35,1032971c,2303f3da,bfe40461,4299f8d2,8e323a51,5addeed5,f3548217,6907efa5,4e0c1d57,7895839e,42223e5,7708ae85) +,S(5e87bec2,1a589ab,483c00ac,fa863f35,91d9119b,9a0239bc,ed4f5790,45a98160,a88a3b84,33c75c1f,9eaf3c15,9fc39a6e,33625f1c,d0cd7263,3a825023,f2e7d47b) +,S(c2e08613,2cb93b35,749cb652,44e99909,da18260e,d252cf32,489fa1c8,d268a0ed,d3f2e3ad,1f16365d,d47038d6,854e0773,28e02e64,d05a4764,4ed0d82a,8c8a5761) +,S(99304c5e,ccf09869,7b2193c2,31dd9432,3b9053d0,e4b9025c,74517ba7,f1978af,ee77fa7b,638b1396,6f7e77e3,43dd04a0,ba1324f3,1e0da111,338019aa,209dc789) +,S(40e108c5,59adfb37,651f04f7,9ef895b,25a79f03,650d6b1d,1c21322a,b4c5c6bc,8980ab38,5733e648,84aff3f8,c47fef44,210eb2ab,a094eb2c,fc5e464b,679db653) +,S(98c88257,2d190721,20c31528,7f508df4,6d6276dd,c9711aca,5bbeacdc,88c6a78a,5d1aa976,1f5c5ffb,d12ea7f4,8d0510e8,b57f270e,e08c3256,f3ee676b,41a61c92) +,S(389aba7a,25e92306,b84eeab7,a16c37ae,d7b4cf09,806ff740,c05dab20,60af6fed,673ab0c9,ec48e2e8,d372ed60,812b2990,49c32637,35f61c13,d6f0ecf6,d065707e) +,S(9dc64fba,832c956e,93efda62,e5f11b3a,6619eaaa,e539b732,61453eea,ca53df17,180b38a9,3c56ab10,a4267ad8,d8a358ef,8f60a9c9,9483889f,956bafda,f45990ac) +,S(71118e18,e758c2c3,6203528b,8b6707ab,b3439b0c,d3d508a9,6759c155,fe4921f7,c2f61af1,2c1b4e9c,64908719,f11b52d1,76bf22f7,e1cc800b,5ec79e28,aa104ee0) +,S(33bcedee,11b9f3c4,924e0990,9adc5fd1,46218b23,6531a242,45cbb2a8,3ec3d096,15f4bd1a,6c22c673,941a71f6,f4694fdb,f83b3e8d,5e317e9d,655057d5,acfbad0a) +,S(4b599b3a,4ab5e9f1,f161e5cb,62fdba55,fbd97740,759871d0,e66b20dc,4e13ccb4,635039da,9035272b,8b706411,9b342144,6c96019a,2c6df423,2b18299d,4a3fb523) +,S(19f6bf4c,dae54ca9,41b8f642,95136026,decb8dda,35e97627,5694365b,21269d10,a24c3fdc,90b06dc,264bca48,db27502f,6cb31a6b,609d3f3d,a1c92c64,cf3c95d7) +,S(bc3df1a9,8027d14d,f6629adf,7ad073ae,8a270875,b177a67a,58dd46f,1b01314c,99dd3a91,54f51d07,2ee33e89,8d915189,93445065,770745e7,b6bb30ab,808d1f76) +,S(977a4264,521a70e8,4d25f5b5,ac1ae5f6,c34ef31e,4dda285e,1ea4a9e5,7dd72c3c,f1bfc819,7aab2fe4,d0425b61,cd403fc9,dbf44f68,32e1c41b,4fce9b2a,2b9f5a0c) +,S(5fdfde4a,85fc5a53,3ed4a7f5,8adc7b1c,98b2611,3e271b47,a1c12c69,dc9b339,3edf2baf,bd6a94e6,951bad5,26fb24b9,731c2588,b2f6eb1c,e9744f49,16c6555a) +,S(b8bcd72c,dcd28afc,eeac1ac5,fb7db8c,afc17abf,82268747,6ce01423,e9e9c50d,82633c5,2e6dc057,9bbd9f2f,3771a53f,9cb6d0e3,6a7566db,f2c45125,3c55e9d) +,S(6c20b999,133bc37b,c65d01eb,6e946565,721bc2e9,da735c72,8be8a41c,1f75c77,20caf674,d8ad036e,25f42aa4,7a5ae475,5e36f44a,79c5ff20,cf6df115,40b71e53) +,S(bbe49141,69655f15,39ce4bf2,f2e919df,f877b5fa,163b7a70,22bc91ad,315adb07,8cd3e025,6618d23c,8c6b5ff6,db8fc0a5,a77b847f,ec876ac,40f76e9c,cbf93a1e) +,S(748b3078,e38374bf,7f39bbb,c5641737,bf6dfeae,d3980c75,2fe14c68,65e73786,7f7cae0a,61a7dfa2,471f2c80,217fc847,ea86b6b0,6297aeb2,8f3c94cf,2a811ac8) +,S(fa63c7c5,b89a2559,4615728b,2272cf68,5d39d592,d052c0bc,d23d48be,c764e4b4,c4c32ba2,77519d60,e1e38a50,6d67d041,804724d6,5cb4dd31,fbe7d692,8ca47c8a) +,S(c2ed7197,d014e380,a365ea13,d948314b,86978eb0,70e3e444,6c953871,cc56c91c,5c73c293,e7c1cd18,f7854a09,d8b9b0fb,3404bdb7,737dc070,9bdc01e,466a595e) +,S(2514c1ef,cb1e0bd6,c2f34e84,6f3e8006,6c2b3a04,c0d9fab5,f22fe872,6fc266be,c5a0ac6c,7bbb2d9,ff844346,65f66ec6,507c35dd,8ccf9ad0,69a1ec94,c64e3eb3) +,S(5bc07f05,11647f2,58dd2e28,9a3843c8,e2318bff,c96a081d,f6b6ef94,4e286350,213ce093,1217ef04,8d87d059,f2584db5,7a91c465,1e112c66,a41f85ab,ebbcbea4) +,S(edb56e42,97375b03,8a573f70,67ae464f,db9c1335,f6a03dd8,862a1731,9a3cad8a,d3e61a70,16f8d546,61b8414a,426f3be4,35862053,1d981f2e,5314447f,15ef5fa7) +,S(2925276e,78266481,3bf60998,2e028646,6849088e,d0d77d55,817c8d9d,73d5d732,f53157a6,a97c989d,ceb2d755,dbb0cee1,84b33213,20dd6d22,62213fe4,9a87296f) +,S(2c4579d5,bda0f4a5,37209882,937019e9,91286379,c3afb37f,a69e409e,9bc0a034,e150bf4d,d889c3c4,655acd23,f3107bca,a319d467,b1b9b15c,336ca934,5ef7d99c) +,S(5f260a00,11f9f876,bbe29587,af31832,25f21b8,42698b3d,5688545,a8808904,6ad33a32,164caa1f,7a4d2ce0,6eac3d,736fe64e,d83a3a9b,53473a89,8ee02350) +,S(3bbbbcc6,12095ec9,52fd430,f3fb3d6a,9d1f2c69,e8885100,d65a4d7,b6ac4b8b,328e828,3846a6e7,db5b090f,8c9581da,40d244cb,aa3b5948,7e4f9faa,550b0c97) +,S(4985027b,dd0fd8ef,fec9af44,bc222f4a,343e80ca,662d917d,affb9d81,956acff0,58befd2e,37a36e41,305561b5,f2716a23,460b1014,fe814654,68c16c22,3b8affda) +,S(214638e8,d2e30891,9b5eb2d8,803b3dcc,6e826ecc,e1b59b,92e263d5,67959de7,9dd8921,6f131e29,35ae0454,ff5fc9c2,dc22c0f1,c8de7dd8,ad9d41e4,f632342a) +,S(6ced8705,5ced2d6a,f3e3532b,965e0a31,6876c110,69155f35,444004f6,e6f3cfdd,f51b1aab,c86f556f,8b7ba4e2,a1e6aee7,55b17c01,997fcac0,a83eb56f,7e546ec6) +,S(95016e67,876c936c,e3263498,7859d1ad,7fc3ade4,4219727,30a1c886,c9dcfacb,299e78c4,e6e266ee,ffbd284b,81005bab,4df7232f,2e43f160,742bb392,6af4f660) +,S(4bec66c8,30401c39,c42a8019,fc398cf0,c513d20f,9db30763,51315319,ee6f23f2,f1dffe92,3b7d4609,871aa916,28929c63,4fcdeda1,543fc3d5,8e8b2735,938514fc) +,S(b50513d1,40513b97,6ac0015a,60e53ae5,9088c4ef,5ab27bb2,7f3eda78,848a59c7,9c41cae5,1182e6c2,3fb254c5,1b786ccd,dc9282c9,a6674841,29a5894b,99c36399) +,S(59792653,3989a039,6a69bda3,8a920ac9,d1df3845,26f30c00,3e415593,b690708d,7f2c14b7,274887db,5e656192,19ee6737,4c750cb3,97ae4bab,3a3ed02f,1aba648f) +,S(7ba2b766,cf012a93,478fe2b3,e916d665,251cc7f9,3ec16dd3,4db37056,5eacf6f,14fd8938,f950798c,37121286,5e8bdd14,3dcc7e8c,2c84aa69,3fb311f,856404bb) +,S(3062f2fe,f69c90d9,fc947af8,a9e839cd,7f9e9d22,566bd3a7,1c43df9b,eab5d6bb,db84a833,49916d41,7fde7b71,9d92a716,64047d4,21a36bba,ad9972bc,6f5ee58) +,S(ed5f949d,69dbec8a,77f4d695,cb446700,f6fae687,e327cce3,db38c2fd,54b06e74,4724e060,57b3d50,65104ff9,29950bcb,2a690723,f15999fd,ee62febf,2d8930e3) +,S(4d655e03,30028276,e9312fe,a6acc010,30e12950,9ebd68d3,d7170e46,61b7cdc,90efc122,6c27549b,2f5e046b,69e97f04,4399579e,278ccd0b,7bcee523,10ea99bb) +,S(f6b60756,b888efec,d0a9edf4,a483f95b,68e05e80,c351a60d,bf166faa,eaf1b35d,27bedebd,aa781584,6a896b24,1afaf9b0,cb57e98f,bce5df6,bfd22a3d,38a5fb8c) +,S(cc592caa,942ba237,72c4db94,58d6ea2c,8c81c538,8fc7cb51,6ca30188,a3c55748,36e2f7cd,358e5608,36e77d10,361c3f1,bb6bd2b1,d640307c,63d512d1,db288158) +,S(4acba9dc,a5bb4698,21a3acb8,cedf4304,f9372161,976d0edf,6a7a032f,f6c1a456,b36e983a,b2ab47f3,3e72287e,9bbd02cd,d6fb302a,972f2166,9cae4e85,52262437) +,S(c8a5185e,42279d3,2b50e0c6,1b9ce961,7be3633d,84a9472d,97446ddb,eb061f91,cfaa50b7,445e189b,d64c1df7,4668eeb1,cdb7cbd1,ff65c0ff,3c38d22d,9bd4b5cb) +,S(c1c95567,7f4f611,365168a8,89de10ad,535faf08,65f8d20e,52b1041,d35f18f9,34f7bc3b,3d956b63,9afc1eb,956f4472,543919e1,3708e7eb,537ab941,48033749) +,S(8df4fbb7,36f6736e,b4a09370,33f7d256,8bb68d68,f3e1f8fa,8df1ae51,d236a8f3,3d7185fe,8e9a2d00,3987af26,71bb3850,cef6b0f7,70770c81,22977764,5d02122c) +,S(d635f0,e35c7cb8,f2aa1ec0,c475011d,c2c8bbb6,d1ebc297,c2baa5e6,aa5af3dd,926ebd,c588e8b3,1a990a5b,5907ae5f,441e5a99,1853c643,5e36803c,7ba51a2f) +,S(b58d12d,5f865375,7514ea38,30e38e05,3678b525,e8b51923,d6460720,b46a4bc,f7b59183,5b0ebab3,935d587c,e995c0b4,d77c9e40,ea4837f6,48e44841,7438d3e) +,S(bb7c6a8c,b4013640,ecfad075,578e89ae,12cb4253,6461d780,11ba76db,da9a7f36,7dda0258,3774d618,68995b83,5708295a,3c2f5c40,306dcba7,d1c20da1,4836581c) +,S(14f6f0f7,92cc8cef,9dca990a,7fa5b7aa,f116b819,722cfb91,9683b298,3514a9e6,88c35f92,7a07598c,90ce5aac,4b3fecb5,2261045f,f23800b9,7b96f210,3a4d7055) +,S(4b95e5f4,eb9fa118,5ddad896,457f4aa2,fb60f4d0,496ad4fa,76bbbce7,77448541,1e100787,513acb31,ba087f51,201201ed,502d1f08,f7e2b8f4,d27706d1,45e71d21) +,S(e9a17fc0,67f75b2c,6384aa31,223355a3,a7af5366,4d85dc16,dcecbd2a,364b63ae,420a2388,ad674523,62f8fcf0,12b601ab,a40e06a,1b4dac1,9560c085,de7fb8c7) +,S(39d8536,f320ec81,4ee3d066,c0834130,96d4ff43,8331a81c,f10ad544,43ff9169,70ee89e9,1478e898,60d66a55,6054abd0,c7434535,13a7a3be,7a76e367,c28ca248) +,S(9779a0c8,8624d6c,beb1dc72,f371ce26,9f95b993,c49ff20e,1daa3c,2fb636e8,9d9e27cc,67296c50,9da4b0e,6037920b,369684d8,a64cb907,d230a4ab,a0c2712e) +,S(cd4c584a,1dabb48f,6a5c09de,9caf36ff,4a97471f,d1565586,bd78b4fb,66f0b401,95902ab1,eff06e2,b3e104b0,cad2c28e,6fd60eed,c47657f0,bc433411,273446f1) +,S(46ca11f4,142362cb,513164f7,c72b776e,dbeb3f65,5d527196,88eabeea,2561aba4,8060431a,2a2ad442,dfb6d3cb,d6263c61,bcfd0946,6204e2f5,e832c4d5,a434c9ff) +,S(dfebd179,1ffb63f5,76f5c753,50031a21,eb712de5,7e8f83b4,75ac39d8,8a94a513,cfed6c7e,39b2b54c,206aa0e2,2f7c610c,6576af2d,ecb28f0a,a71cb1ad,c7be75de) +,S(c71c6532,82fd063b,44633d9d,7a3b94f9,43daf1a1,7967ffcf,e1238087,5d2c2469,62fcd7cd,e006a10,38df8aed,33abe940,f18a4736,52adeba8,620d1b54,a9d376d0) +,S(63ebbb4d,dc8ba09a,4e2640fb,f48fb75a,6864ec41,fc1647b1,e9f8aef7,34c0ff37,e59d034b,fe16f4b,41d090e1,97360a85,dbf1ae4f,719c62df,77261205,da4ae28e) +,S(650498c8,cb51bf16,58eeac61,61b5892d,ce6e5c1c,271d40bc,eea14db9,dd12814a,e7e66785,5d8e0193,24457769,bbd5d14a,7a614585,70ad5e6e,e3058af9,64a65279) +,S(14a1e03f,14c00863,81599c07,b816df44,90815a8,40c1032a,c41225a8,47c43fd5,35244a59,bc6ba88f,46f66bac,9bb8ef5e,4926da38,50532ddb,6d6d606f,35fe98de) +,S(1c9f6eb2,f6a8a1e8,ecf9a16,71154fff,a4f14c15,bbd50f08,4d6f5315,b6903c5c,e6bde1f5,2ca4ff63,9b66fc51,150eee99,5386383e,402f987d,d266065d,2a03a033) +,S(1de71eed,bade7b1,7c80966,4b00d56c,b43ea61a,c0e069d9,7cff0218,f970f8bf,8d4b2de,77edeeae,d78d42e1,6b7bc94d,ea99d65d,985769bb,5c67da66,18ee1434) +,S(f4432a80,ce954d2e,baa2f062,8bbab706,479f7a39,838d8c3,5a96eaab,5f5cb4b1,96fe6ead,ac34a40c,3cabf47,6fc09382,91f3d077,29c6302c,c67a189c,bed579bf) +,S(8f71e74d,17964af4,5623d3f9,68424119,cb37e1ca,c1524737,4828b5e9,2519fb21,6990f0df,d7f0ca4b,a77678e4,ebf6946e,5b6b1720,869c91c,ec07854d,604865ab) +,S(22293157,5e3dc25e,665546e2,96a83a0,5a09d052,cef701a1,20019c49,c6a6745e,aad8f887,42585607,c792bfae,8a941caa,83d05082,defea859,86a6ead8,e5c423b0) +,S(6585fe63,2ef3a69a,816bf5f2,9e627650,cc57d069,3ac217c6,3b73aa2a,f248a096,820aa3bb,20281afe,edd9ca57,76ecc55f,dc8a893f,de11f7cc,12f37a83,6cfd9f8b) +,S(22232479,e55c51ca,b2963ce5,abf06281,aaec472f,e610d339,1951e41f,93f67bf8,e192fab,2cf22d7f,e67f0514,bc1329a2,888a8f18,a8d6504b,b7c5a9bb,ebf927d2) +,S(da8d02fd,e4ba069e,bccaba08,2b396c94,4460148b,70e98f60,8267db02,5ddf16fc,1a30213d,e337084a,47d67e7c,17a2e64d,579756d0,8b66f4d0,59a76021,e63fa2bb) +,S(a6f72c62,854e82de,f1b8a006,64c4e8b9,ad49e092,78ee6501,708a9f18,92202ebf,8355972d,b08c8104,b7c56ab,c2318ef4,2e270989,1a83837e,daa35537,1d03ba4) +,S(2074fd3a,309e85a0,5c6f8c35,937dcc56,a15077ce,99f5a8ee,8d55ae2a,3bc7db68,e11c02ea,cb783c94,2e58fc0e,806a9816,3061a4e9,aea9582e,53ae1f08,322cff97) +,S(49ed5666,fae9aa2b,70cd316f,62a4b62e,29aa59f3,1826106c,8611c50c,79a1a5e3,5ca7e49a,ae144e2b,dcc0b19e,f986967a,1477c209,2a8368b6,324bac6c,807643f7) +,S(2289ec7e,a1f7e4e9,85f472a7,13722335,b582c4e9,8e191468,3ed13622,5d6c1b1f,11e2b18,689a0867,517bff6,77fe40f7,b03f898b,d70e8902,61a512ca,d9cbbeb1) +,S(ea852ebe,23f1efbe,d8ac64a5,58ba2ba3,fbed0e52,ffc70635,bc49cebf,85859164,bde2ef41,fe97a639,73266583,c7a4e415,25ef1351,5b25cfaf,c97aa635,41cbb824) +,S(5718f0e6,7cc07d3f,1ac1a954,8fef08a4,290b257d,a4179855,3fe9be1b,d302f0ea,98ec4d5b,fca65d7e,e72d8bd5,3645a6af,a6ffcaa0,a2eb894f,d4e40ecf,69acbe90) +,S(df62a2ab,d77afd7d,ee8f0650,b75458e3,10269c3f,780cdad5,50bebd92,4b810a4c,6a6606cc,e384d27b,80bea2e9,588663e0,8d39fe8e,9fc8a8cd,54c4829b,8e4c034) +,S(1010fc45,4b0c268b,c339bd19,809508e7,9ea7dc0e,efd779aa,4974cdae,805e6668,686a3adb,681b597,2b30a323,c6b6bd2a,d51194f1,9d3d801c,3fa65fab,e96410e1) +,S(8ac79852,75673818,69fe93c9,6141493e,72ca344,790487b,d5425ed6,9f5c5c18,bb314248,fcbfc867,d1972e04,b9ef1f90,775375f9,9d25bcec,684c72c9,bdd1c08e) +,S(560e9711,88cbc7ce,c61f3bf4,45f0ade3,6f3f174d,219a160,5f9c8692,3f848b9d,9e92dace,6775cc67,bfbbf21f,c64e6e9d,4d133f8a,c18ee277,bc80ef6d,d1b9cd2f) +#endif +#if WINDOW_G > 10 +,S(8c464204,4b95eb66,cc95ca08,8469a1c0,28eea52f,7f709fe,e6d90700,f5fb943a,bf10fc5d,7bc25181,301b3a61,5ebea597,a3492025,953c3aa5,1a11271e,689d0223) +,S(d293f74c,f3578b71,35377247,cd8b0367,7f2245da,f87453cb,4d8d1cc2,871eb5aa,86c2013a,61dfea14,63e45931,eb09050f,f080e3d4,ae357423,ba7afbed,a64a6f26) +,S(35997241,ae757b1f,c767611e,c76eb935,fefbf7a7,33666aff,4c6bd744,d7687d35,bcbea61f,246bcd4c,c3c7fd35,7bd393da,2f36e0ef,cca0df9c,5994f96f,c44b2aa0) +,S(d096097,7467197d,3c1a0ef8,44ee35dc,285a17c5,bd9e06de,15f36025,7f6464eb,342af6a5,1e06db96,692954bf,c79cde9e,3dd44869,9e88b03c,d144b70b,bd3e8783) +,S(8e875c99,2aeaead6,7033a375,521b0f85,62125797,23a25470,bfdf898c,ae41a777,24aa273d,2d2f19bb,4e0ba10,13127ad2,a5ee6686,1ec6d0c6,53f7a989,73c0bbd8) +,S(bf51d1f3,2703a4c,d1ef47d8,172c5bb8,d622f444,8569aee,d2de1b9,ae541855,8f81e352,b6c60acf,bbde6e40,99353d84,5918d931,4433c30f,3c60a710,cf9aa484) +,S(6fb6b462,9726856,22b2d141,5083ef56,2ebb115b,6cdcbaee,696a8d4c,8341c26f,9c08f7bf,f9cfcd9e,cca923b3,e578ba45,468f2530,baca2032,a899f060,b83c9c73) +,S(75583ac1,8b5cf78d,7de6a21f,aff045fb,1db56f68,6b2cf89d,678df62,93617438,8259a22c,b08546ff,e237c7d,9c669c96,71fe014,9840082d,f6790340,9b69f900) +,S(42611933,a5d759ac,7ec51c89,31b76e95,4aabc2e3,61010f36,cdd8ff9c,b4c0ef92,88a644ce,6b8acbce,a378e2bd,54eb84c5,58cde403,f99cbf8,7830151d,21ed4261) +,S(243a6dbf,6128f964,bdae776c,a716bdc5,6dff9c95,24baf845,8a43ade3,af520d2,262a2e8a,5ce4db48,d0401850,e92bdfa8,3dda744d,a3d9025d,6091f1a5,201b7e50) +,S(212bd175,1548c6d2,41e9307,a7df15bc,46e57e2c,5a76bd58,82b1291,d8c2ac76,82461bc7,6cc97273,267cc788,a8b24082,57f04ef4,719a9aaa,e33cbd77,79391bc) +,S(da6d030b,21f96d2a,aa0b3e56,28ae0ec8,8ca8a546,10bd61fb,c1a7c16b,4d61177b,5b5bc635,8fab0287,4a2b8596,1b49ec29,2c2aad1e,1eabbd0a,1cebdbe7,2e3f9fde) +,S(dc230af0,55a243b0,a581e101,2eea48fc,4a43137e,cfe80108,86a9f4e3,f6c1f01f,d0f98e1b,e70a458d,7030120d,a3d7feed,2eb5a9ab,601718bb,950fa03e,568180ca) +,S(82c2de3a,c815c686,98ce73b5,6f232684,ee9c5972,f0a44797,dc16d04b,a9089df1,1c847065,c6c2cc18,fa253b8e,c1fe178d,c859844,2c1fa432,54462d97,93b8573d) +,S(6ca2de88,74e4916e,e1965dfa,200af89a,cc439f20,6a4077f6,67076149,e20494a3,6ef0b344,97aa85dd,a43cc1aa,57dc7ce6,cd51119d,ae96ae06,99b5119a,9a662043) +,S(ba2687c4,1728fb65,206448f8,28400efb,cf1149a4,90bd31f8,8d33af53,7851d97f,96ad25f1,1f2ce7aa,e8b803bb,3c62cd32,3345500,243b1de5,d61f20b1,86b4c0c4) +,S(ac362040,1947f301,16032d5a,4b303323,d311f533,e46a1aa5,f1ea2f08,d553e0d,53839f95,fef32884,5a75881f,a17db91c,1d5b981b,7b20937f,df171c3f,2cb30a22) +,S(6780ecee,5b1b7205,68d4241e,c3b35c9e,4158c7c2,2dbba46b,ac769476,79049e13,9ac115f0,31e0888d,2dc90b9f,3562e732,46520d57,ecc7ae4e,e0fbf401,3057d9a8) +,S(95377a47,e7a2d5d5,30510d62,2bbd3439,c0f7653a,ab294254,cbb10390,d2a63732,57ac9110,9dafb62c,fe1abe4d,fc64557b,bb01f76a,36649d7b,91be523,f8195fc0) +,S(4f195bf,98fd83bf,7ee97c5,9bd42af5,486a8507,3327415e,85f17a17,2add8921,a56acf25,1c82323,6327cae3,6b1cadd,1a057bbc,f1ef3b59,a865c7b8,691cf3dc) +,S(eccd1fd1,efe8299f,d2208240,adbaabce,cc0510d2,d7b6f6ba,d9e291b1,4cbcb53f,ec2ff321,6da50fa5,c57d6f2d,3198e019,2d9b6f8b,ffc26b29,13580447,a42c667c) +,S(c757444a,f2c3425c,728ff41c,f7cb7475,502e7601,c1edf2b,1eec84e1,b058f438,e1d481b6,169f143e,29701105,bc8b6657,9cd267fc,685014b8,fd070283,6362e53a) +,S(3562837e,bff50776,58d99662,7a11a367,aef3255c,1c470ac6,36f1b57c,645250b8,cdcf4a0d,97aa58fc,ccd374bb,bcafc00,fa1d0d35,ca7fab9c,f4d72d66,299234d8) +,S(ce9dc245,f62e97ab,d2d339e9,7fac18b7,b1f2f07d,fb654a82,b113317c,86d4a3a1,f6e1e325,342afb8e,64fe8520,ec37abde,fcaf1b30,be6ecb79,27ba5615,f0d184d5) +,S(ac022f3b,48ee44ba,9d271a8c,1a01fa8a,aab4818c,e5383dd5,42d9d6e3,2c858a12,1e0563a8,91f8d11f,1989e091,739611de,191e497e,66055aaf,45db9ba9,72ca76fa) +,S(d1d4f682,cb12cfaa,e46e57e6,db6f2277,55a83782,88cca4ff,3a999c0b,a651d9f9,1b19bfe5,870e1931,4c23b4b0,71672233,1607264,acb8e960,488598e7,85e71a36) +,S(79962171,bbddaf94,45fbacd4,f9bdd1a8,892e754b,2d0052ee,2435303a,ff1c8a37,b8ac27de,2a952beb,45472f77,b34c1354,fe47b6a9,daf0720a,b8515be3,7bb98a7d) +,S(445a17c4,2390b604,bb3c3573,b061a2f1,20ecb3b1,83a0f8d8,cf032e3c,509d3b90,b75f4088,7c07fe5c,a0c057c8,7eff4966,4ea76941,e409a6aa,e34ad4b1,693f97b1) +,S(6166b5f9,63a9f47f,5fac49a7,8d175763,8c39cd49,11d16ccf,b0e83bc3,f402051,ba337661,8302aeb2,213e4620,4ec57492,933d6df5,5a045d7e,5317ddf,e92430b3) +,S(cd666e74,28901afe,8e67d0e4,48de7e3,30b6dbdb,a34db4a9,29315d3f,8b251531,af72d8b9,43cba540,e42398e7,49fc89ed,44095951,f11b24f9,e5451810,3802304b) +,S(c833be8c,fd2f6fe0,46d837a1,1d990355,5a6285bc,d7b8814e,e839cbad,523ac72,7ea8f90b,44112363,a8d75153,150c3b4e,b6c07dbe,fe8c8ed6,3a24984,c9a6af03) +,S(cc185f36,3036d385,d890ac1f,5e95b162,e40e4a4f,e8427613,98200369,f25ea477,e0768836,146d9c98,98aaabe5,a9ce12ef,f66d0775,4055eb42,832eeb9f,26338236) +,S(148e0863,24bbc2ba,b67c9be7,407b809,77ccd910,e92c9770,47943c29,8c9c4a5a,89e83c85,9cddfc80,9de733ae,6138e97d,b706a331,fb7176ee,55dfe3ba,c2408797) +,S(9b1539c1,aba5b583,5c88d9b1,92a3761d,cf8b649,54f53a7e,460e0122,bec95c76,391cde19,45be59da,d4c895f1,3aa1ce24,d8472e42,a232795b,967f21d5,acefdc18) +,S(68a2e6c1,75fb01d3,76a9e575,ff427cc7,a6032774,a974bdd3,e93b8a73,e4495cd,153e6484,c8c30dde,5f269b74,1c599647,666cab7,e273d4f2,5573dc4e,78e00752) +,S(58fe9049,35a5a40c,3b633440,533cccac,7669e9a2,e7c2f0b6,6c36c228,61dfb04e,b36905c5,92450e2d,71d06e2a,2d599a77,71ac1e27,15a79555,b39fbb60,5536e1bb) +,S(823c0f96,dcbdd9b0,bfdaff2a,19b6027d,3e9bca6,e298378,3375a783,5eac7080,d91546cc,f34d9a58,babeb6d5,43bf3c36,8831a2b0,d9043db8,895cd208,f2ad0a7f) +,S(4a56aeae,e908f908,55fe7b71,3013ee7,d6812152,4f7decaf,533cde20,2d14537,7e60c801,33b718d2,119995b3,3790eb9a,3129a7fb,2e030d8d,21af90a,c622b7a2) +,S(6c0f3855,e6c4f5f2,c4594e2b,8881319b,82a64bf4,9fe0968a,71f6ca3b,f9240334,5c8e7b6d,a9efbba8,4b5ade85,305aead3,e1478ad1,b4d56fc8,3acfe34d,23b5203c) +,S(d9cf8f2c,d1704907,15dde21c,f172e648,496e40b,5248f331,3aeba2a3,35ac9632,92a7c251,b440f930,bd98299,c35d57f7,15867e90,b6c3e8e6,b073815c,3c934344) +,S(4bfcb492,8b91dc7b,afa7ed43,d9af3039,77592728,fcf1b9e2,7c6767f7,b993d898,276a06f1,ecd9d410,b34c9a4a,e3aa33b8,1854a4e9,e4703dda,7bfca949,a45d14f7) +,S(abde5893,ac4032f4,4ed93dee,8156596e,7cdcc575,e5928792,944019ac,23c434e8,5e03a809,2b9e6044,e942af7a,7cef02fb,46162cb2,4c19916e,d774b00d,8195c40a) +,S(205d6307,7a98a8e1,178814b4,9281da20,4482f1ae,31be20a8,3b3b0fd,526e1cc5,4bbe295c,943e3560,6b95cb19,d6e64bfc,b9cab7d2,55657614,7a79ff50,6fe4d780) +,S(cb4c4c83,e6673a1c,6c228a42,36e6031d,b59653bc,45bf4b7c,3b98cdd2,441c43bd,142e0276,39267ea0,f7c2ff39,75afe714,62f3340c,1fea5149,cfe4e8ea,e31a2769) +,S(25a1f4b2,7ff5bdfb,3af54a4b,493356ef,92ccf0b2,dec7c4f2,b5abb225,2cca77a7,1b25dd93,153f8341,7df3b3af,c991f2d9,36c32e8b,288a7fe9,3e9ff97b,335c3c38) +,S(222f76a7,7eeca0d6,a511c863,a657cb89,5a1b7154,957b66dc,89ca77aa,2a54237b,a8f2bee0,64eff88d,87a598a,8665d295,a205c884,2f6a3492,7945a02f,2cb0b289) +,S(32d4328d,1ad2651b,41bf1015,6936b406,379f5c26,99f1c2da,ec3cbd8f,3b4dfa8d,9f6de6e2,3294a33b,5f4d4062,3e478096,df5de0a1,d069290d,204ce930,7988261d) +,S(cde9ecbe,6948cd70,3b193790,6662b7d,187d0830,cf991b14,e8265691,81f1d3f0,84887b32,e1218d2,9b77794c,e8ad56c5,f5abe8ff,f95515e2,4bce81b1,5b029720) +,S(bc89f45c,3baaef4c,a8343582,6506a006,509f4e7e,265e4b80,11d53d3,a748947d,eff5bca2,714db146,7a272fce,534f79be,9fa15af,7226ba49,51129f5e,6fe68475) +,S(62678cc0,eea2bbfe,2bd4ba65,5434a9ad,39b409b9,b57efdf0,9940f748,ddb51d4f,8d384f4f,d234d31d,1c161245,ef6dd54e,a5cc8ab9,e7bcc883,6735051c,37a74acf) +,S(15e01d39,c63ae225,63dc89cf,3dfa2736,df7c0ac3,4fe86f8a,f219f933,86bc93d0,1f563532,314fcb81,c1725133,49769861,e7efb999,fa317ef4,2bc75588,10cfb13b) +,S(4f8d2b49,3493258d,ff98e813,e428ae9c,52c60103,1bdbeb9,7b8f364b,2bac10e3,8c7d117b,67955db6,c0058028,3f919f57,1e8c58e4,216ca1bc,d66b264e,169b73f) +,S(d14ce31a,2bf16b60,983e397c,ddd3588c,3b0d77b4,f449136f,1a789276,b56f1d61,9a15f620,b227d83a,3722ca6e,4dd7bbf5,833f24c7,2584f356,11ef3734,ad3f0910) +,S(35221b4e,b8c275f5,c10d656c,9bfea000,24c1aa2,c4130841,9c3e8e3b,66f780f1,3d1c5a02,5274afcb,bd78382b,b2778657,6888d46,1b5dffa0,f8ec5dd9,3bf8e808) +,S(82ed9c3b,1c76c1b8,f44ff6f2,9f443b20,83f68617,7270843c,49eac0aa,34a8ddc8,262e9e6b,c2ab2b86,7342081d,90002690,e81f5a58,aefd6fc4,8a91dc5d,e95f1340) +,S(919e960e,acf2aa36,e86342f7,742e97c4,9c49b64a,ff5c6118,d181e349,10717b85,4b51a94e,a3ea1679,cd9ce9d5,ac329f13,ef530d42,c7821650,5a082fe4,d945b861) +,S(cdacae3e,20ce551a,beeabcaf,a643ce62,edca3de1,acf06c30,65ffd366,5bc3ec7d,aaacbb13,872b076a,e28c326d,fa54f4ee,235df4a4,b341c9b1,3d322071,6eb95bb6) +,S(1a4508e2,1bd05c09,f3d80f82,90726f08,de3a62ff,b663d5a8,f949ce26,92a5f2ab,52780ff0,976eb033,760459bf,4bf02994,c6e672c5,6d25d3e6,2b320f5,2cca97ba) +,S(8e46eeed,5686f25c,a94f73d1,3f26c98a,e9129f77,f3aa18dd,d5214262,803a0b45,ee56d38d,7041eea7,c87f2ed1,e7f0aeb6,7253d556,610e8200,782c9af6,1dedcf4d) +,S(782910fa,3bd6b309,dad797c1,5b618469,68d6171e,7a0a0532,a92e5bb3,697e4031,ff178365,c44c2a28,e84c31b8,946b0a80,717914ff,6d3f22dd,ee409753,44e4b3f4) +,S(2ab9e8c,c5a710ca,6cc2d0a2,94f1d7d2,65c50aa8,f9069041,ae93c91a,e5f64e8a,aabcd0f,a2254bad,67cf23d,a5934947,18536602,a13d81c9,db23afc9,a7f89b9b) +,S(d04667c4,4fb25b22,8320cc53,35252937,a094ddc2,4610f7a5,fcb1bd1d,6382c9e5,7c93613f,8bf048e7,86af436e,cac4fa86,6e5a91d8,3064f5c,e31d4794,b2b0f74e) +,S(b9c476f9,799cdda4,a51b0476,c5838994,f157bd29,c9361252,def4af83,6e86b0f7,2ec7619b,c77948b3,f25cefbc,46845527,d1a9b0da,a90529ef,f13aab4a,ca97932e) +,S(90bdedab,f13f9940,4b9d8c56,5d64739c,4ef765ff,dee2ae0d,64fda841,286eee85,a9f47882,d9a848ab,4be812a4,8187d26c,7f8bb8dd,b94f7725,5c628104,e0cf21f5) +,S(a0c394a8,2177734,c02b8310,74ebf0ff,ff4208cd,dcd59e7b,a680737a,fc485c84,c4f08932,b4c62f34,fc82434f,e9b7b164,e835cab6,2f34ee3f,d640e5d7,d09364b) +,S(1b0319bd,3896e8c6,284f949c,72e7694e,bd3c2923,ebeac273,b9aab50d,30294c3e,15dbfe9b,17c3aae7,e5f8233d,703b7b1a,1401b672,1da32080,53ed52f,a2ee339d) +,S(9914ef0f,e92f16be,a27a9354,518dcc0,1210eb3b,3a90f2ab,6992e3d9,bfdc719d,7a0bd065,cea0b11,e8df3629,faf65a30,5e671d2c,86332b83,98ddc2b1,b3c4086b) +,S(3a68fa19,5599f638,7dafa176,395c9615,5798ad6d,7ace7810,daaedd13,ddf60d3e,74575ae6,a3f569db,394faef1,e0641ca4,de158eee,9a8ac54f,5cd96bf7,d4e71a89) +,S(b7361d41,e2b67e31,f1872b1,b1bffc8e,41193dec,7f012385,9da69c60,5e88b2e5,fa9d6b95,66d49bca,73cf5890,f6e7acd0,315347bd,f10be9c2,9b0907e1,80668344) +,S(341e9987,42d84640,f6fd1354,3fb7ff9e,aa93a4d3,12e99bc6,37b85b83,25174e81,c49608dc,91b46187,611cbcff,762e5fc1,e95b4e9a,6ed747ac,8612b6b9,8bfcfc95) +,S(83d6a445,de34f557,40084909,402c9718,1f6420bf,af87426e,2a0f75da,c483e6f6,7a86db44,58c8fb53,5edcf48a,14a94dd8,e9fbed09,277db0fd,787c121b,a1dddfc1) +,S(4f11235a,14bcae9,89082bf1,c6a499d8,32d17686,2fcffbdd,a40b84b9,26ac351b,b50624f1,5f31269d,168021c8,37739cb7,8678ded,be59e288,6e963339,e94a2acf) +,S(8fbb5727,21cfe12c,ea685907,ab6e3d7e,eafb3892,c082115b,998e9a9c,d3ee2b89,da7fe685,c8148e1a,5cd8de8e,2a5b5aa4,ef1bb1a5,af8bfab7,91c923a3,66906680) +,S(804ca63c,b9243f5f,76605b1f,53f5989d,286023f2,fc672bd6,3f52c59f,5496c3de,372912,eedb1156,a1b8300e,eaeb44f8,865fab6d,49c89fd8,43170b05,d75233c6) +,S(b2795c6a,b83ca824,6b18de87,5660d04,60b48ed7,1de9bbf5,8cc1769c,2d2a5365,66e8c2b5,88530b6b,4d351044,186a8a01,db684157,9bdc041f,90d0935b,2a49d820) +,S(deb5304d,b61bd914,c0939d07,c0464eb4,caf3903b,1903a588,208c5e05,36d9dad3,18d54f43,e7e45e76,6a4b6249,1e48073c,40507dd8,3f7b3b27,762a06a9,4d5777ca) +,S(111bf502,d177ec34,b6c61d69,63366901,eb79d5e8,5749f5cf,7743cebb,9b7714c4,be80d52a,bc38bbcc,f036bad4,5e47a0f1,7d8ba20,fe6780f0,bf8c38d7,696a4e54) +,S(94b10f43,c15c5393,e8d4e71f,db863865,daceeb50,674d0f8b,161bd38,dcbe92a5,ec55af2e,a34e8c36,5b3f7729,110586cf,8d087dd7,f1a0ae9b,d25b9b77,f5be6dc7) +,S(4627abf2,2d447784,c53e529d,62d3036b,fb4a422d,10146248,d3b1f188,e895593,8b341d8d,6110b59b,738172d5,6651e948,cbea9ef4,c7e8dc48,3a560503,eb7b3e4a) +,S(19ce15cf,dfeadcc3,7375727b,5ddc5327,585dcabe,c172aa80,757ba468,297c355f,506555e,ce829141,736ca9ec,886cef26,83853e7e,5b3ba66,25cccfd8,4de60f81) +,S(75a40681,8293fcae,8c3e97d8,e1f916d,2950682e,16d3def0,fe6dcfd0,ab9a3e55,5292d5c0,e02ee24d,8139f2af,495298b7,4526780b,f39f5f22,a047d155,dc8c7930) +,S(a7eb8b8d,ef4b7686,b47a341d,4f4a7333,88cb82ce,8f3226f1,cbbf79bc,1f3bf578,85d98b6f,e238577c,b3b52bf3,94a72589,24407ca2,86865cc8,80cfc93f,bd8199a1) +,S(a5b9a2b5,dcc91d67,b352d14,3c19f6b9,6c9f8344,50e16c00,e8a938de,b3da647a,f12d4fa8,39850471,64335aba,1260cff1,26fc4e13,fd16cc29,63472f28,7b9571c1) +,S(7999c6ed,48d589a6,5df7c20e,e9b0fdf5,df58d831,78ad6171,57c09cc8,44015cca,156f4505,3706c3a1,c54b3fec,bd3f12c8,aaacaf0d,22755014,5bcb731d,418f5756) +,S(88fe81f3,b708edd1,b85baade,6c05c7ad,42202058,6dc2e8e2,fead379,c49829b1,cd62e24f,b04b7d2b,b1434150,260a052c,8972a8cd,daa1db10,d99d40d7,df727c01) +,S(18fb0eb0,cfcc61fe,423192be,b694a77d,91216537,5087a64e,89557d5f,4fe86763,3cf72b1f,dfe8b565,38e88e23,ed871d7,80f4a6e3,55229922,b1f28c5d,38169785) +,S(dadb3231,2be4f2cc,cff171d5,baf18e76,4719fa,eb5fcb66,d919c86,efd38aac,8d67945d,752de8bc,b0740e42,3a154449,50e0b330,c6a73981,3d9f4b30,f98bc0d7) +,S(f0b9a086,7cdd9f64,6b3aa0cb,e3105ba,7b17e09c,6c1c39c2,d8057f06,a39e5c8e,2b534e56,25e6d180,40dcf431,9821cbbc,3ff91303,c14bdc81,370c9e0b,5ef4e9de) +,S(dc0e0b05,2e49c3a7,e5d0e253,672e8d43,1cd60166,648b932d,406fbe8a,c2fcb7e0,ff919786,8e1c651a,4cd39cb5,6921e24a,223e7af3,821fdbea,86547e1,c7b791d9) +,S(e71cae98,fb6ddd47,35ec365b,515c6ca5,6bea748f,11811038,b74aa5a2,32eb91ee,804ae818,396c20f6,e2fc5bc7,5dbd1f41,9ed731a7,2801d06c,e6682bcf,1d600266) +,S(50d1b5b2,f7b2e4ff,3b594d48,6bd2ca6c,6b5d5368,2079bb9f,88d792b4,d4ddfd8c,556cf4c5,18fa0660,86b9b03f,aba18fd,5c554fe7,4020df5b,6e34bc88,4d5cc744) +,S(c087403e,2bd5d954,df8c5e86,f23f6cb4,96634886,b4709747,325321d1,bc2701aa,9db44987,d8517300,6e3a549,eed87e06,258bc14b,e2b00679,3a2252,a3507712) +,S(dd1037f7,f3843422,de8988fd,3f68a299,4d45f8f5,1e9242b3,7980f517,bd6d6894,ca8e6d61,5cfbbcdd,8b1ab8b7,673093a6,1a9c08ce,56b065f2,54fc191b,25cccce1) +,S(de229a19,67ca589b,f4a840c3,d18f764c,424dfda5,6c099d14,73a9cc7d,34b5ceb4,958fc9ca,84ca63a9,4323f4b2,ae46ff44,a1d352c1,1b8e8be7,2d5115b,54122b22) +,S(15e33c9,cc9d84fa,16225f48,70a35a42,f8a3a3dd,67a8dcb1,143c7ee2,4cdfd9c,413c0206,ed48cd5d,36205836,45e4ad6a,a59a1e15,c7f36256,2f89b9b3,660e920) +,S(53422561,ca3c4d87,2d23e317,3b21ae38,dc010b99,b7ab0fc4,394e408c,a3d6bee0,6ee906e5,e505909f,6507c7ab,779ce1c8,20f2c50b,a71bb8b7,8debb3fb,6103048e) +,S(829dcf4f,9b2c4f37,32800bbf,f5cb71ca,308bf0a,9176a74,a031d972,9a82b2fc,47378200,429e538a,4e249d3c,9f58873d,abe3f8c4,615c5d3,3525f6ae,5f8483c4) +,S(ed6f6eb7,3769b1b1,4923b989,acff97f1,c05594ba,1d5f4ebe,450e65c3,8ae911e5,dfee6f2f,3fe584db,8b98cd0b,69ff6219,d52e2d9d,a372ffbe,18e500e1,a2c38eb4) +,S(47e52398,1fbe720e,8fcd1982,df2b184b,70616ebe,cb4913da,30327205,c0455503,afd2dceb,f360c30f,6820cfbd,1de0de70,179f4cb8,6c461251,5eae2f4a,baf3e900) +,S(b02937d5,8f48e1f8,6f3f1170,f5e880e4,ba10e2a8,c13dd0df,49fde04b,a9037312,dcb0a4f,3e4c8456,316de580,5355e17f,8a6c7924,f68cbcf5,347d3c7a,28c18c4f) +,S(9f993cf5,3578c1c3,25c10c2d,c3c066eb,878486eb,dfdc65d4,4ee57fd0,ec1989f8,c6b8d40b,16b8811c,d666ea43,2e61baf9,e83eda6f,d38275d,9143b386,31c8bb52) +,S(943b6cc2,5913ec1d,f12730ed,bdfd1d0d,ce431784,f36fe84e,599f9b89,dd3240e6,e58102ba,cac2ff3f,d42d7ca3,254ef55a,9604d3ff,fab5b16d,9f77482,4fed3fd0) +,S(9b0e67e,69b3f9ec,51843da4,f7b5a7c8,59511dcf,47f58a64,81fbf2f0,19acfe0a,6a4ddc28,17a4ecb4,ce2defc7,d7333ca6,2e074c36,f7e49c67,4a009d30,edc54dd8) +,S(97dcee33,9cd8d18f,8c3b0fd4,48ca6e6,c8246b4,136bacc,72ae8673,a4571651,6163a205,cc20bf39,8aae36cf,c8933dc6,29b95246,48823d51,d82d2d2,74e693e4) +,S(a1e5e6f9,26961eda,7cea9c26,f4a1ba02,798c940f,2b7dc267,2999ff7a,d2292ced,50274b7a,6a710f74,ed138401,36d97657,cfc07af9,3b9e8fbe,ca18d31b,8d5f19d) +,S(473d5fcf,7cdfddfc,52fc9bdc,6fc77180,1c21bdb1,840821a6,1a984296,5b4884a9,348836a7,ad7f550,feb2d703,6c82d95b,89ff95eb,e8be6250,eba7c5b1,8fd856af) +,S(9c187442,7384b2d0,4fcc33b2,70544c98,db8c1e13,2bb149d4,54c51ea1,4796f613,2d6dec43,970f0079,3da12e47,595cefba,c1825d36,c71342b,7913f7f5,fcae0a19) +,S(11ce1c46,9150e2bf,b742d826,be740e4a,ed63c729,5f5bf51e,c7a6aa6,562b154,6e86514f,ea38280f,abdf8b93,be8b7d92,67f3b28c,af2a4271,aa3b6a62,1f4fa33d) +,S(1e037904,e4e2de6f,2893c354,18d1cc6f,dde2fd71,4bacf1cd,4d9a5c56,79656042,1bb759c9,34c26821,2a28aa38,a0af035e,3c81ac85,3c01e21b,462e81a5,8c960755) +,S(52fc9467,23f899aa,f1a94f24,f9e3620,3f8d505e,31cc6800,9951d9a7,c0071d82,4632ae0,75430820,20cdfb99,270b47ba,39c909b3,4b3a39db,92419697,d0bd6dbb) +,S(cb585905,997519cb,214f9e39,496f5386,35069eb4,d78dea4f,f9e9d803,642b20d,1b9f42e7,a5b475a1,e42a0f51,ce2d5e50,7131b2f3,5990ed45,64e3913,ec93ac7d) +,S(382c2857,29f14558,75727584,5d37bcd3,e7ab180d,a11c7a12,cecae00f,b4a69c46,cb27e912,20a70fb3,6e258684,3f128693,495907a3,e0b248e4,a25c1e7e,54039440) +,S(16f086c6,c2850e49,8f8456dc,eb33a692,a4dd613f,b2f9564b,6dcecb88,4f4e5024,2e152a08,88eb1188,3448ca68,25a65034,73cb5ece,c9ad5df3,12deefed,279339a9) +,S(7589bd1b,1f0a3577,5530f0ae,446ea275,4439a51f,66730950,6eed6177,65a02492,2d840e12,d3758153,1e5771bb,14d3634,4076fc3,630c389c,ad9765,98462d49) +,S(18b9ae40,cce63a51,3dedbd2b,c3beee9,a80cc5f5,a26b4446,9a0326f4,d4930890,24b86a4d,d5ed3c44,71b57138,2b270d0b,9e0032d7,8e0ad18a,cf6a4eb9,2a2690e4) +,S(8c1f74a4,acc71ef6,4030db5d,14be8627,94e9ba6e,102c89a4,ccfe8a8a,d3ebb48a,a79f0119,98aea529,1e3ba735,c8b26c86,1af1c119,92d5dc94,16eb1673,9245677a) +,S(8d80592d,36bfaab7,5b557ba0,d03825b4,2c0fca08,8ec7d046,5cd2c203,c2bfb080,3e479487,91f27453,4d0a1bd4,a533fd2a,7671a654,10cd7a51,859b466f,151d3f6) +,S(eab0bb19,f477e158,ec85046c,f2c56777,f36782e9,e0452770,f7125765,670ca248,a27d7081,23093af4,daf55e56,32ba071f,37f0bd64,3f189ebd,70074cca,7cc04640) +,S(ff0d0dc9,ebbb2fa2,6d3b249f,d5260ce9,9647e1d,db48799b,db532c6a,2a0a039c,12b0f6ae,7f161f8b,ce1c3505,5d9b760a,fad5b0f5,66211023,3c43942e,fab31fa9) +,S(d89a3235,71dbbd1b,92340346,8b08b7be,be22b320,3ee6b0ad,42a2aa96,3837d526,25da35b9,9988f167,3108124d,9e6f6f1f,db4a0490,5546fb62,146b7421,36e3cf27) +,S(f150023b,f01cab2c,433cdafa,86751f7f,13ffb315,55d34a22,9ec4c012,925b43fd,31f70e21,26ac896,6dc966b7,17a9e483,8ac37a6a,2072bf34,1a9c3d33,3ac7a9cc) +,S(d98ebd3b,2d580978,72ae9d5e,2c2cd0da,76f442c8,e0b4470d,9b3ee019,c83af2a8,9ed5b6a9,5a061970,34bf9873,da6c7224,930fb358,a514c823,e0017c92,75dba3f5) +,S(55b62d85,833a94ee,dfc2e313,df3ca816,8173533b,fa77d827,583fb01b,cbc3c746,9f848773,cb95af7,b79eb921,19a7a139,1f4dbbbf,44c81897,15bad111,364a835c) +,S(dfaf4d76,fef73f93,44c69de8,f6c1c3fc,ec759c49,a2a7a1ca,2860fecf,bd718de6,ac4af693,44e2c287,f6409f94,c36d93ed,7fba1f15,195bd971,357d3142,725a0671) +,S(84a444a3,4510922c,37420f29,a16ee22b,a7839f3c,5810cbf8,38b7f3e6,c5fe29da,ef733d80,2215c12e,143f420a,673069fe,6e89af70,cbf975f,a1898550,1114f06a) +,S(d7c84e11,46c87008,3ddd24d1,296811a3,2c337749,83892548,6291aa53,a72212af,b187dd58,a3be40bd,c3d357e5,480aec61,9579b2d1,4d79745,f84cd406,10844ac4) +,S(fdedc27f,a70b08be,f3a9f616,575072cc,c7fca4b5,71a2ea06,9ffea788,5598051d,fe9b7b1a,1c575a9e,354d279,ba7f4de2,53f6f54d,e7245fbb,3ec462a4,7b9bf9a) +,S(cfa7478a,d3f2cc6a,92022b35,58437b3,f950c250,4d96b9a5,c2d5c795,ef122e77,f3e48dca,e9592835,354f8eed,ffdd4c2e,2ad7800a,3da863bb,158945b2,261409c4) +,S(8e9157f8,3fd62097,70fb7493,d7678fce,aa1584bc,d8dde3f8,337dce8,ee0eefe2,6079ba89,8c05dfb6,ba4f91df,4b4b229c,3322fb5a,44fa988a,c8d9f3a5,3a05351b) +,S(7bf5efb6,103eac30,ec4eb80a,9bddff22,9d422ffc,6a7f9dfd,bea8b928,3116f75,efadb659,64791edf,e5935554,25796141,2cba4b4c,3553fe67,ba138931,3ba71a3b) +,S(f5ba02b7,b7b2c2d2,68c7b1b5,37697079,690a13fc,89d1d53e,85f27820,d0e8df0b,66316d26,b2640e41,bfc329d1,9d2d4430,a9266b64,c3c793a3,af7f1515,9e465485) +,S(5eaacdf3,dceca4c9,6d2bc3db,f22951fb,87c10da5,f1250828,4a1498bf,ff004475,cb3db3ed,9721ce09,16985d40,4831cd04,b38f5810,977ea106,c8c25194,ad1f122d) +,S(1cfe5c17,b8d61134,53552ba6,ad513371,d1320abf,4fa2de41,77c5a768,a64a5554,53837cf6,4846b887,1e64a2f7,e319f740,99bcabe6,7a0894,5edea46b,fd1dcd5d) +,S(92a83f47,8a2ccc86,1cc91dd2,a1210fbe,286f47bb,44e46880,5e21f0a3,7a5dbc10,fee35c65,fcd45b02,f8270b8b,c198132c,cb69ff9,ec35043,684f54f5,c999de94) +,S(172285ba,d5d539b0,f4d86ea1,35bdb79,73c07ad3,24bf5dd1,4f74ab69,cad277d3,45abf940,cf356364,e0bafa15,cee3e20e,cfc29040,288b4897,314c22f9,aaada654) +,S(ad17bd53,92e19bab,8554ae08,bf9158dd,3126ce81,3a05c32c,7646eb73,cb164762,a129819,1c833987,775d4f47,d9d70d4f,8139c651,896f9b94,e164574c,8d065586) +,S(10421b3e,91a4a89c,1f6ce9e9,13e511c3,c23fd307,c4064a12,5267cb31,2ebdeb1c,539bb5d0,9e49f0fd,186b8a51,73118cb,98569700,dac77cc1,92359286,3aa53319) +,S(c43adcfa,78152a3d,dcb9eba6,6632aa5,2e8476de,1e0e30ff,39735b06,21de5bfd,6ddd09ca,2122580b,847d04f0,5dacbb7b,1e81c6e2,6057d880,1a911a55,9cabdebf) +,S(f7a99ccb,603a58d0,4c6b9e50,d9e7d988,14434f1d,92aae27b,5c8d9006,98bf9a73,ccdfc244,76f4393a,e96d6809,1cb74130,5e62934c,cafc9b08,78a3a77d,a71a7ccb) +,S(9abc95bf,70174ea3,5038f44f,4a2ca9be,f602d516,9d249aac,b3175be7,e09c826,6cfbceed,3e71f8a3,d427d2c9,f8cedaca,22a9fedb,4cab7763,617198e0,d7adfe0c) +,S(8a7ca893,35c84873,ecb4af06,b493c9cf,d7bd08fc,d0535c5,546bb9ed,5c5d8d82,2518b372,90d3c08,72f1ee4e,54144799,209ae3fe,d2f285ba,7b00193,21e31bc1) +,S(70c8e379,8649628d,969182fd,862f8d4a,b39fdbdc,c246fb79,ff1c9227,a64d1c3e,c7931ad5,27ec0a4a,ec297d9e,fd56208f,936c9517,4efdb86f,7f50e321,26ea3cbb) +,S(d783f6b4,6121ee0,71ddcf61,b4808fdc,934a82e7,c185876b,9572d628,31002121,aa92bd84,14226949,9e107c82,b9a64898,28b3ed15,694ba62c,a031d98b,5e9c7fbb) +,S(c1f06a1c,29abb43a,cadffbb8,7ea8e4c6,b7592795,9c778758,1a17e4e7,7b654c18,1dae0de2,f1db42cf,ab9b0e7d,9e5a098f,bc102470,aa418547,6cd1925e,fbecdbf0) +,S(2ad74e11,3205b587,866633ea,32172662,d1498a27,48698724,87b7e62e,52cc5105,c70c7507,de1fa1fd,625aa7d3,755c83a,b5c85159,4b8bee10,5de45da0,d0ff779e) +,S(f490e9ad,72246a46,6eb74e23,371c4f57,a9e32b57,74ac9ac0,3d800978,d77408b6,546f367f,8fdd1687,ba6ef15e,4c258507,77e49a1a,8b449fb9,63a0f01a,a9dc3d6a) +,S(20502891,8357b697,e05788b0,55f8bb32,80c431c5,de07055,3f123373,981d6149,39d040e5,44110e22,58da6771,2852fd09,9489ee5b,5c77a777,7966abd0,468e3b0d) +,S(6e91bb8e,c169a3a3,eef59915,d4de9296,e4b78299,e038c5d1,bb001eb2,f86eae95,d2c21297,88f8c9f1,16434063,a89fac48,45305dd5,d208c887,2ae94ba2,80877dfd) +,S(cf2947c8,39fc40b0,610d0d2f,e1e5ad53,39e7d0ba,9e7dea01,90678bb1,6ba34905,6145a70f,7f0cd53f,d758d7b,172e875d,8db00f6a,131ec7ba,aec140b2,3f37c63d) +,S(b48f8387,ea93a6c8,561c9b01,ad32a28,1c8db1c1,ac3c6864,ad161874,fa2366f1,2cab333,cbe07d3e,26fd971b,3609cfc8,9f46bd81,df84276b,375315d2,7a2d253c) +,S(7c4b5f66,c572d34,e4cae58c,696fd43c,30f6054e,8145715e,f391eda1,42a1f827,3cbe264f,be125af0,3907c5fc,c61232c2,d0adc2ad,5f94f3b0,8ed32ad,99843d97) +,S(e5796368,d4649e19,6227f989,78758d9,8fe24e51,f5d5a567,378a85e0,850d86e8,74bb343,c9a69128,9ae880bf,67a7e4be,1fa111b8,d6608896,46ec354e,f6c9d4a7) +,S(dfa1065e,fe83e9ef,c19b8841,6e3ca5d9,67c1ab26,53c7d650,9f02ba58,fc4d637f,22d2567,eb0237ba,2f270e04,685e5352,e23fdf19,a2aa0a23,1ec83eed,ca5042d) +,S(2ea1d8aa,d436c332,8fda3ce9,8e710b80,8f463844,cf131f2f,2347b37a,928af132,33fa7e0f,b8c2ad10,580a243c,ccf2a4b2,13ff9620,7a034432,8fc61f31,e98dc4c) +,S(12ae1451,8122af3f,a788298b,5e59df37,ab6a976c,f8a931b4,c0a51de5,d567253f,85ff1dd2,b3271d2e,de2fa732,9e3f0a5a,1c3ff9ae,b55555a7,926d31a0,1d24877d) +,S(fd46e1ef,b588af1a,a72b84fe,dec75a3b,125579ef,55ef8270,85645930,95bf6619,d06adc6e,ceb6292f,60c7d477,c73a2aff,342e6b7a,e81c5ea4,f57cb7b,27a51b17) +,S(ed7d93e,b8c0d1ef,1c49e1bf,be22acd,c7a17946,b172de61,4a290d0b,7f32b52b,4d0ec30a,39a81c3a,f8f6668a,742abeb2,b5552284,a68ce246,f368ce9f,b2303ada) +,S(fccfdfa5,cd0e79a6,9febda81,475c06dd,58517913,3624f4dc,9d808b6d,e9619ef,79b9040d,11d09bed,f89959c6,992a9636,ec62324a,d60e1513,9bd2441a,dd0adf49) +,S(831762b8,6a9b9afe,d2a044b2,7bc714cb,16823ea7,22b44010,a57a5564,4b4ac477,147ae062,8ef3bfdc,b48b3f77,f84dfd77,2754c1dc,a626aff6,9c3169e4,9956c708) +,S(33448c01,a84d5303,c8f70adb,bfe0ccf9,f92cc461,f2656fb3,4903b99d,4ef26b01,e5727349,ae8ba61,c8ca8284,ee7f906,208ad03c,6fd7c95f,736ea541,ffb8f2ff) +,S(920a1261,6ddf1304,157ccb8c,50ebaf6d,60df85da,b19b24a2,48254cc2,7d215a6,19e4d4f9,cc91e890,3d2f7a11,ca8c0b97,e2cb671c,e0c4ee36,9f1a3ca0,f28d0f4e) +,S(1df8ce1d,3e370b9c,3f60ac00,cbac25c5,458385a5,c4b926b7,fcafe62e,536b1ba4,344df46e,e3635079,52af6160,2729094e,3fcbabf5,bc701083,533e7e60,5099a92b) +,S(7227847d,abfe26b8,13c18175,c37a0526,2e2243c8,d80d93b6,286b2881,d38b7b72,bede79eb,33da3cdd,95289c93,46165cf9,28b5aa41,c46b364,622988b8,a7973d24) +,S(6defba59,e1218bfa,b02571f8,ccc84104,3caff74f,26d8d995,9729f292,eff7fb8d,4d7baa8e,21f2fbc5,96f770d1,bd34e77c,2c188c05,5921c1a6,95696a8d,4c340a04) +,S(c667f4ef,f5127d24,6b31ae02,2adf53be,8302e1a,b631a0f9,90b16051,e02d6bd3,3d7bce76,ce11bdf6,fd4d822c,37d746a2,f8de283d,527af237,3e80c4a4,dad34cf5) +,S(ed9e8674,441620f5,990dcc24,23a2ab00,6fbca1b8,e6bb3d23,55c2c72f,ce29d866,64d5ed9b,b4289a2b,b81a12f3,30930dee,7c03dd71,1ec361a5,8297c22a,5806ad30) +,S(86a36c57,e6b0cee0,33c00b25,66344ef3,219e57ee,ac452ea0,b0eeb98c,3176fb24,b4f4bdda,9e9b58df,4e103874,89592b5d,b147b43e,79a1af25,135e8db3,eafff739) +,S(2e237784,45396ff3,a0e105ac,ba151e3d,fd02bf82,1de70e04,33792280,bccca913,f736539c,e77983f0,610464c4,3bbcc904,f43726dc,a336304f,c0b716c3,67148551) +,S(ccd3c14c,7790d936,5226dbcf,11a0bc00,9db88a87,ac2d68c1,6899f980,20a1390f,b240b35f,bd6d5dd9,f33bac2a,f1899320,f8a9cba8,7df0a67,81cdfdd7,1c3af907) +,S(7713be7f,988d7b1,c6c6566d,558978d,eba4efad,b82761b2,17bccd87,3637b018,8fb91a6f,a9d62baa,2eeef7c5,15fab341,c75f31e6,64ee7d94,70db34c2,74475781) +,S(5485ad60,35dcb3b,9520acf5,6b0855cd,34c739ff,1c59798b,1ab667ba,a4982b02,1dec6c7b,1e7c14ca,743df62e,589311bf,57cbd455,e7dcbf9f,cd439962,96a90f0f) +,S(a597503a,d3be484d,1d2d1cf,c4e8540c,411bd201,f2b05ed1,89c9a3dc,b0ee0f19,35113e7d,38001199,1e2cee66,4dbcf490,becbd6f0,765c94dc,e2855ee3,b01113cd) +,S(ba91b251,abb130b1,57dd07a3,dbd2fd91,1ae24937,80c8046c,b94de57c,dd91ce4a,cfcc2080,500aedfb,a69f33f5,4f642fbb,8377420f,e1799dcf,e1dc3593,d3e1f6c) +,S(adfb5a58,83cc7bd3,c6fd3386,95c86414,5c6d2f4a,603fb2e2,fb045bff,86d324a4,16574ed7,45d82dfd,c50415a1,8c30da91,3a525753,cc975722,22a5553f,7b0cdc5c) +,S(1084914d,dd710a5c,ac854b14,10a4be35,ba1f13a4,e0fba3e2,9d94edcf,a3561ae8,653ca135,3240ef60,412ac6cd,adf8e664,2f2b74a3,5908c3ba,be6dcf85,49c25e99) +,S(704aa271,9af38b14,17a8abe5,b881efe,81876a6a,f807833f,133cdcd1,6e6c6f7b,a6fee2b3,48c1180b,c48726c9,be2a1a41,11395af4,42ba7b92,63f4f66e,a3769e54) +,S(46048cc1,7f5d2a86,5c1f5734,893c6683,fe68b0e8,942c9080,51d7b836,a8aec289,d85cec30,89a8f77d,75bf9c6,bb4f8a33,2e766834,3841b277,a461a079,8b288efd) +,S(50f1e6be,315d3b21,636781ba,8598d2f9,7d04ccf,5ba1fc76,3d547657,77fce9e9,f7dcb7d6,2057b9f2,8cc24975,9dc9621f,25dd0ce1,47e00db7,d095fb0e,ee6b0b00) +,S(7ed0a244,676655ad,10efa03,7748d49e,944df1f3,5bd46d0,3b7ffcd0,a63501c,a8377a65,593f227b,446eb266,936ae475,e9b3ae65,a60768d8,2690d0f0,5c18c21) +,S(d039ca1,ee66c2cf,611c431d,cff1bd2e,19b29d3b,b1f37342,c29f4632,4febccc7,db0d0d82,14f4c661,629ff5e2,4cfdcc84,6e652ee1,15a6476e,7813104e,696d736f) +,S(c27973a,cc55fe2f,4531768d,94cd4a0e,8e36729c,aad61579,7beed810,a7b092b7,cdc310ea,b36ab246,c56d5402,9b9e3314,878e1f1,ff7520db,43917a14,1f41c99) +,S(36842942,cce3c683,25472e48,de202d15,ac14a180,3a2dd84,6de0c33c,6446e945,5000b3f8,19ab82fa,3589db9a,eed5609b,208d95fa,ddaebcb,57403b96,7b8f2f7) +,S(d1aa195c,338621b5,19ff3a8c,55abb454,74865ef7,85e0fd7b,c4554ae,6d62d0e9,e7e1dd33,dc293859,b4634576,d8840630,832ce773,a9a8bc88,c2e67251,a7b737a8) +,S(4f423d32,607439ec,366bd6ff,5766ec13,a59b2c2a,8cd008b0,489f267f,5c0f00f0,5e3c7e9d,7ee94c15,c048e6aa,272c888c,b6c3e058,4b4f4ee,f5e1d787,a4e7a9f4) +,S(6bb1c680,ff8991ef,17c0859a,9b5fa9b8,ebcb9afa,af7398c5,9101bb99,7f06c4a,318da775,d912ae5,d17c242c,97615c5f,217005fd,535b839f,189ff3c9,8669a253) +,S(14095d4,4713a46a,5fcb251c,9fbee2e6,bc393423,30303b8b,d0f2d09a,c0096f68,647e000b,3660b374,959e632f,6867c7fc,1c7aa4fb,b7f5593,22dcb2ba,e604a2b1) +,S(12112bf0,346e9c6e,4a8f831f,6c087876,8943191a,38e9fb83,8b2613b0,4b5e5323,e4149ac2,cb4533d9,4c3abf62,aee4dab9,faf64065,89cfe10e,30a42986,9657a3d0) +,S(f99360cc,c2ed4810,d80974eb,eaeb59fd,4f2197a7,8459729b,4f75c370,8bca5738,b92a2f5e,86d77a8a,c2c1b9f8,6e1971db,a06e4414,935020db,c0c83a92,ee6f1cb3) +,S(2dee5a4e,c81a3ecc,4872112b,be53f51e,64ae779c,49488567,a654e806,ea809ca4,1e2ea8a1,df6d47c1,c0aa1bcf,ffcf260e,bdea4d63,934ff3b1,bcb1e1a4,c73d4954) +,S(5baa6a2,139eeb78,f49638f7,b0dc5010,b73688d1,bbd746a5,f2382c7b,d461229,72677383,10a352f1,9f2a75cd,9e42509f,b08a0ca9,60154693,cc01d595,25dca81d) +,S(a3f77eb9,321d44d6,b774a6f3,b1319e46,f60d102c,d96e983c,8f8568ba,82913d70,f93d75df,8271e70f,1aa38630,26bec1d0,f6db1765,77470077,d3fceb8e,5c613a05) +,S(46ba66b5,fa1f9274,378fd62d,68ae9f38,8588d766,ebbe97db,72f9084d,c7f2cf08,5473e24,3078b8df,92df9b55,52ad5055,f44bf7e2,ecf0785b,72db5dd9,238897f9) +,S(db6a0246,ddcf0260,b2b415b6,f551fad0,bccb15c,ca196af4,291d21ce,ce80dbf2,396cd446,f93e1c97,a56c6f6f,63cd0966,5f88856f,e75e1c7e,a985917f,28591d3c) +,S(b82f8d1c,a7a298da,3992c4e5,8dba1b0b,38187eb8,66992e8c,5cc1c834,6e6c8fa1,4b0ae76a,f9b0413c,8d4fdbdd,db767c6a,b1b80589,533e3ee0,28eb6036,1483461) +,S(446e96a4,dc9264af,e9cc6348,aa612861,d106fdd7,b7ff94a1,82e0f018,c485f000,32dfe3d9,21593a58,1fe23b7e,ccf677bd,2771c40c,a612a507,c8e33df0,99568440) +,S(c86f10,7bfa6dcc,b9f00ca3,465049de,5c8a3e6c,d85bdfb8,1ada1d39,303a2eb9,e64f7066,7e910814,ae18c6a,7323474d,9dcb277e,4aaa7ed8,88bae4ae,7c34219d) +,S(bed8eb6e,cda14299,e4cd94cc,202be7b8,9201c2ab,302a5cdb,83e5f5ba,db6cd710,15736cfa,b375a40c,5d367b9f,6692746d,16a1f03c,20941256,708489a5,5d411aac) +,S(b3efa7f2,c5f6ad10,41f171b5,ad759480,665e0a52,de82a881,da1926e0,8f64d38f,3df63c84,32761a24,eb0dfa,ae98e034,b6dbd361,3fb53ff,c535fac8,ff1677e6) +,S(b0460da0,cd869b5f,235213a8,49e143e1,8fa9afc1,651ee921,ebdc525d,2715cbd2,c11a3ead,f3541877,ce73b4c0,2b57b299,46b4725e,cf630eee,865bb121,b86fd7ee) +,S(28b09517,a17452be,b2c19187,12d600d4,b4969253,a7d0d52a,49cec3ce,d73bc071,36696708,73c7591,11163518,40af594,40ffd6d0,690ddae7,fce7a43d,e920a326) +,S(521becd8,192acb58,7ae76b7,c0bf17fa,ad86afc,47157753,6b1a51b0,fbb5f136,648a54c6,d7aff13e,cccf399e,15451682,ee06710e,edf32669,1dc7fe83,75ac858d) +,S(b7bc19d0,b7fd9d65,26c9bca1,b587d84e,a2a200a7,76d39082,368b761f,79f6cf67,5adefabe,e0d0c8cf,4252c29a,773163b6,4a1e9ffe,ffbfe3ad,2f796e8d,1f70acae) +,S(e48e3be5,1b6ca8d5,41f0c241,21558cec,66db7b6d,c13e7114,dc931f0d,397aea8b,dbcf6357,5b16e2f1,30f064bf,ff12b465,f6cb3a3e,f9f74431,4bf41e7e,e0f28ac) +,S(395c6de,71c692a6,a3247596,8e28f2a5,4ec795b5,9759e890,9b2f4290,9f455751,ee5e0118,3c7dda2,c1eed4e1,5aca155f,b5b097e4,499bc3c3,fcfc2c85,a669a13d) +,S(28938ac3,b1184399,22741291,9c0fec36,663da3aa,8a4e89a8,1a66052b,ca808d99,4ae8de7a,b1ebc1be,a2beadb1,80cb9a10,da168295,ba1ea5f8,310b986,4f174603) +,S(5c0f618,95e88cf6,205472f2,3e27e853,be3af64f,d0a376f5,8523ee6b,5248f5a4,be5c3c55,cd09ebb3,b7363456,9fdb50fb,8473e3d8,3441e624,b41b1c3d,e44be51b) +,S(abe1f7bf,22d0f733,ed28e125,f7ed05ba,ae2e8f13,1eba2ec0,1554dac,5e3ca1d7,2a5a48db,3de31f6a,9708ffe4,b996cb33,e553e6b5,95aeaffc,918aa2c4,1ab0ab4e) +,S(c3042427,57d370b3,79124907,ea609129,5f1dbeec,442a6349,bccfd29c,e08d8be7,67a64eb3,3e0fda75,535b35e2,f8c9811d,528959c1,29e8f144,8bb75ce9,b1868934) +,S(65a59946,356f219d,77af0b6a,9e1a43f7,3152746,6af41c21,c81532fe,3140f5b8,64e7128d,5d3e4fa0,518cf27f,c070da20,1692b059,3d84641f,2463a61c,74f35918) +,S(6c7d2e3b,48428c87,46b066f2,bb99da10,60311cb7,d4dae19e,de2eb53f,141413e2,4ba47bf,c2e7c670,4de2864d,1ed7b383,286292fe,28f7c7ab,2a664bcb,6cb7e3a1) +,S(dd257bd,b99c89c2,b47798a9,bc93ff57,5655797f,a45399cf,44acf58e,93fdcdd9,f8d670f2,a9207f25,52e7e0d7,14289103,e8194f81,6390e0cc,1af2ae36,c1b3e4af) +,S(2516034e,b8ddc424,42952b8f,acd47c62,6827b87c,b08f263e,b2aab5e6,ecc23d7b,ad8e8879,f5feea07,ad3545bc,a731dd30,bd2ab534,4b486826,433c75a1,6216ac9e) +,S(7e723054,27b591e3,b19834b3,8211edc1,7f075215,6591980b,907dce0a,d934246d,5c91fcbb,d8c184a6,f21671df,1098760b,2506bee8,e32474e3,3b080147,4e63a71f) +,S(1b1f9d16,ac3c0d2a,4b87691,45a6f6bb,8d4fb57f,ef9df33e,72b5d399,6dd1898b,6442bf1e,5ffe450,b14a399e,16241a5a,15e94453,94519bd1,24d0a67,f35b4b1b) +,S(e0f1fa4e,57cdea43,a3b9f671,596631c6,65b5144d,93c51a23,e9006c63,fc872f2b,c83851fb,54890d14,2f605617,151dd47,74f9a3de,cd27d864,a49c176,af32e564) +,S(ae95bbb,697c820a,251a3667,b2a0a078,40efa027,99d7bd0b,3e9a12eb,32728c3a,e0dbba97,280096d,86ea4da9,45ae509d,1140e0dc,7b803f10,e685b148,6baebb41) +,S(fc8ff885,d52ef42c,1fe529ea,853ff8c3,afad1ae,6e7f1b30,69e34076,682aed31,525eced4,b26e8f62,7b904f1b,3356d01a,9cced71,432ac850,433e0a64,b1e3dd14) +,S(6613136a,459d625a,d5b5753,3a965a0c,ed68d63c,13652546,c629cab3,32c8e810,10f29ff8,24d30a94,b3d732b4,3b168bd2,28b4cb01,4012469b,93a9853b,655b65cb) +,S(45085915,7b683327,c76309b3,96ef3b63,19dda841,f6be1b91,f24f5a37,ddea56f0,b9a71446,584a88e4,6a155e34,f08d5a6b,2b6ebbbf,b4b1aa12,bbc7654f,91956821) +,S(168ee3bd,8f10ba0d,deb82576,cd5e1711,be58af4c,2274464f,e32f3f7,7c8a4325,6eef1e63,43ff409f,a916891c,982f8700,465fb184,5820b886,68b74202,6678b34c) +,S(b3191d97,763c2341,4eb4db8d,eb2003e4,fdd86b4c,6077931b,71802714,ef048c04,b4ac3085,59f975ca,be7d53d8,3ebdd5c3,ce6860d6,37710a04,f885a83c,c2152edd) +,S(da9d5c5b,4e73dc93,3c72acca,1e93f4bb,3ec477fc,f201096a,51ea0226,3a2f8738,7fb6a2da,65f966c3,689b93b0,d6366511,400c05d0,8b0a15b5,b4b3209,a812f8aa) +,S(140e55d2,a7e75678,1791730f,c526470,8d1cfaa0,954e215c,1e65bcc,e4b0dd66,4bfba0d8,63ea2597,91e470d8,1ef36318,87e2d5e5,c897918b,ce805941,953d5b3) +,S(15a9ccf6,4b95cc87,cee9bd01,bfe3d8bf,b438f7f8,66344a1c,f3f399eb,16b173d8,4f5472cd,bdebed25,605e51fb,f0b31a93,5d0ba59a,6e51bf90,e0363c8d,9bb33f3b) +,S(e86e364b,6776701d,b7b3d3d8,fad181bc,c7ed5e91,2d0a888f,814caa3d,88af6e06,22fd460,afc040d,3e995518,c6286989,24a466d1,4a624915,f834c357,4dea7b92) +,S(3c261a98,cd25f0db,2321134c,723ebce7,b1f81d3a,a6d5bddb,fc282fae,5a500eb6,2b8d2145,5e498211,8a4b6ed7,ec96a66c,4027a506,deaeecbc,45535fc5,77abd9c1) +,S(49b6a811,4d55b517,6cbb1f6c,177aacfc,368c3b5d,238300b,d66546ed,f4c955c8,d1b124a4,9f0e7c1,6b8e001,7f1b0b2a,ab94411,391d5bca,5b535838,a3815b94) +,S(6ec8e861,f0d3e5a5,3f9deab6,20cc4b81,6cee801f,f7a43f71,f34a8dac,c525f6b9,42e0545b,68ccafbd,3309c4f7,eb6b5eb1,1e01a871,c63fae27,782001ab,a6dcfd6a) +,S(7342b341,59aca5cf,d305a2e2,a8f14da4,4b527e57,4640fe1a,c08898aa,4595b9ac,b5261302,d2442ee2,363969a8,4ea61281,27f64f40,ac86dac1,21b5d234,53160124) +,S(842b30bd,54ef350b,65dcfc43,df26967c,b2747757,a609c54b,687d30b9,5a686fa9,4ffa9e92,2caa36b9,ecf31f63,f5c8de57,7d594f7c,71e7e77b,9cc5ac83,f336ead6) +,S(2dba435d,d589a7c7,bc3fb60d,495757ef,7c13bb0a,3e91a153,9998e04c,19f94862,c440720e,a4b23cb9,d238eca1,6775e500,931d3e5c,7df853ed,55cd4889,5e8cc0a1) +,S(9d1e8524,8f84ce5b,2a75a457,819390be,bb284fbd,3d035c07,998d3c45,c73bec02,8e40ee4c,c935ccac,2338bbc8,4a8063f3,6d62e8cf,849bff40,1298074c,94eb9ead) +,S(d2735ac5,d1fba75b,d4f63912,11549755,9a7f8623,62e25cf4,e76562d2,d8b441af,bd2ac36,19f9f339,77b7cb0e,5b52f3e5,b4ade86d,1c9fb31d,a1d8fb36,7dafc081) +,S(b0130e38,f46cff13,ad1a68d3,15729395,b27c2b96,e0a957cd,ca63adfe,b0a3e11a,3d9f697f,4a61401c,87eff844,3b11776a,610f1516,4366c1b5,535599a0,c6aa3c4) +,S(e0aa062f,15306af8,b662d8f3,3b89de8b,f59faa78,29942caa,ed82e668,35ec76a7,c5f5f0b5,6ea77304,a5dffb8a,cac98387,34305b54,25fc6181,79a4457e,c15e6f2e) +,S(ed1626c1,a8e6d1c9,187e15c4,ae9875ec,2156d685,997ac413,9f44bd0b,19432d5,3c0d895b,9dcb4a3f,4235e531,ee7373f7,7f0fad46,c5938d7e,69d50429,71f0c35d) +,S(a2cccc31,4e18fdaf,8cc25aa6,74c974f8,664744db,86e04be8,431d2ed0,4dc92833,b6410e49,d6d471ee,d20e5536,8672f5e4,2e1b9c88,c06438a8,46c3a74f,c759d71c) +,S(5bfc192f,db15f62c,4af19119,b2d96a88,b3b24e06,3d54b31f,a35f675b,f668bf27,46774374,acb4e140,90431bb3,9f62a38a,dbe0dc62,4021e23b,6099e198,47d99051) +,S(66842a89,da73c404,32a2e553,97efb009,61eb2155,886ac90e,97dab5f0,9227028,3a8e83c3,511ea048,88d2dc9d,f1016cd9,da171bc6,89c9af4e,90b18091,21941de9) +,S(ec823197,3ba95f98,d45f8991,3ee8b92b,e3a4a84d,d59342f7,1810766b,cdc516e8,532d3c79,f5113f4e,1973bc88,2a953b5d,77d5476d,ac9972ae,f1d25e19,ab7206fe) +,S(3b65fe78,bc516176,aed5e5b6,5f3ed39f,e8e8e26c,32ab07ad,1ac2519f,72fc140b,856d36de,5190eb9c,13f7f976,466f95de,566a1fd7,314cec1b,9c9f7adf,98208d98) +,S(3ac0eca,51c43525,e9e545ce,83fdd009,f9f31eb3,2722b945,18262036,d18cc346,dc72018b,c3b2a4cf,3244ef31,340e0944,325bebc8,b134de50,9ab3024a,a213a7e6) +,S(4929658d,6c50ece6,edd2db7c,217d9be0,bcdac8b9,bb50972f,fbe53a04,2ee23508,e5aca42c,61aabbd4,b8555980,a2328741,6dfc8df8,d7a10c3a,7284bd90,aacec38a) +,S(9d16e76f,4bc96492,f0e9e748,8c6d2297,7830e2ab,491a6278,1d60ab5b,153a6291,e6590f00,e4ac6922,5436318,9770aef5,5eaa988a,44e9711,da7266ec,895ac7ab) +,S(b0649c4a,1327e7fa,f52a9bbe,7ff97add,4e13b36a,27c0676d,5e09b2b8,1f5df94d,991c8316,a6f36848,e072a080,77f75a8a,d79fdd08,1a606d12,b355c3c,3891acdd) +,S(8f194a21,f6303ded,2c9ce51c,44a4a16b,eb39a8f6,5fe13c9,6b7c12bd,b052235d,bd1df3d0,c9af82e2,545afb23,e9a2dc85,c635172c,edfe70f1,bd755d26,9730739e) +,S(1da71a97,cc7a4cd9,4777f6c3,dd5e665b,3872b721,c6c2262a,60e87f1d,efe21ff0,78d17a41,39036e1a,7af2b9af,1273afeb,a4d30e8,66a3e6e8,7f0d0468,4be6a06) +,S(9fed363,e493f262,d3efabb1,c52291c7,e04e401b,b181290f,7a37af3c,df86aa45,130cc33e,e164adff,bedb1827,6a5c965f,53a54f36,90dfcd6c,b3fff836,703de729) +,S(d166eccd,221c3568,199ebc38,fcbb6140,7a601a3a,c1e7a98f,ebb75a87,a7a1e49f,262222b7,e7c200bd,5dcec562,85485434,b0628c7c,ce5483c9,93795f76,a072f06e) +,S(e7853cbd,3e3770c1,cc307839,294a2e8e,b998a56e,393435cc,2930920a,8ddbe0fd,7977e6ca,67147cc4,965d2918,1023c3bc,cff1e7b1,8fa4850b,80a140f6,980e5a8e) +,S(a8b0feb1,cb140201,2bea3cd5,6b1a1f02,51036ce7,423f511,480f49c5,6227a17f,ccd7c3db,9d3ab6db,6cceedd6,d3801c8f,67afe792,c8977b5,27c9dcfa,75ba8a9f) +,S(57ce5dd9,e1815755,31e90579,74f58b98,6d02e406,a846ab26,c9059f6c,56d617d7,cc34c090,4399f316,269598f8,aa8f9aed,829f61f2,5efc9bc4,e851ac63,fe142d14) +,S(479790b6,4f60fc6d,befbbc1d,365ab3e4,8077b6c6,cbf02f2d,6c8b986f,d0f9c858,157f4982,e3581925,dd25382a,e3e48fa6,5cff911a,95e9bf43,5df8b356,87f2f9b) +,S(55abc7b,1ffe0a41,2181b622,813be76c,8ee0a0ca,3cb37b1c,cb265087,fff17c68,bd134249,23e94c53,4cf9e603,a1dd259,606272bf,8283f2d6,69bedd4c,a971d99f) +,S(6ca7e032,8bf5d67a,b804d431,e5f709e,bd3156e0,1d4511da,1dc67394,24d2e659,c428b133,f3683909,6551c2ff,2f870d80,d80aaaf4,6d2b1a69,7722057,5eca2647) +,S(60df19a9,83e9086c,4cbd20ba,fbafa8b2,346ae4ee,9c1ad4dd,99959e91,2df530d3,dae7b854,29f817a0,421c2f1e,e4e8e4d,a09d60f8,84701e31,d7a8b7b0,3b79cc48) +#endif +#if WINDOW_G > 11 +,S(6f18d50e,5ef5f2ad,bad80ea1,c59a3847,5c22ff05,6ba52c7,e1d26d6d,d3686bce,d1d7ea0f,a166efd0,facf5c83,bc3786e0,d3f3405d,5b4578f5,13a336ad,f0d7d7a9) +,S(b634dc9d,5ed51336,4ac9569a,8ddee9d9,fcdfe00e,65e59233,b3be8a07,2fd949e0,d72e46e2,c61b2575,f25a505c,bdc3456e,fdf18976,6562a1a7,e86d036,eb31db69) +,S(5a37fcf0,2dba24f3,e6646171,43dbc5ab,40d91983,69f5cf0e,4fc566fd,97445910,a960d1d8,13f8746c,662a9582,614c7847,33e6153d,2975cb59,c3342463,75c69d1e) +,S(8aaf16a7,37318032,c60201b6,b196d8fd,eeeb8f8f,1aab29e1,1b83ae1b,f112661c,c461ef56,66a3a4a7,563cc0c2,845f2ae7,6d03a795,987c615d,611bab48,ab9a8e44) +,S(456f0ba5,a05f15ef,d93e7f49,e0729c45,1d85a693,42c2804d,9cd4b8ae,af5e3434,a680f4a9,99221a8b,7f46da13,13041e16,13f616bd,84b9135b,b0f7ecb2,7311cad5) +,S(f89c36a1,f1905409,75f146d9,31e12cb9,4bfdc90f,a178970a,9d0b34cb,38f5c741,3b562c80,58e31b92,a1186615,9c1ffa3b,4b1df38c,eb4a1646,579d2375,9c44099b) +,S(7f6beb11,2e1d8600,d8c4903,1d69cfb4,e23876e6,32f30428,9d2c2503,41f3f76a,a1937407,c0925afc,be994b9b,51627b98,8d98ed6,e8cf6fb9,cddd0ec,a4ff4a9b) +,S(905ad0aa,b585c7c3,78b7130b,ad1d5001,1010f543,194f40d3,827dc606,12d73511,bfce0701,c3ddcd38,150130ae,e91d16d4,a447821f,a2e098aa,b83b8025,b7177a9) +,S(f559c2d1,62122fca,7201e7a3,b6033d1,e54187f4,7550b2ae,f1d51521,f7408b6c,3f10d622,dfd0eb14,7f6f04dc,43108273,7695ea42,38ced7f2,5dc167ad,34154481) +,S(19b328a4,fa17149c,ccae5830,a8bedf53,7c0d8a0c,c3616345,6f4d91d0,718ce8b4,9a1ce80a,2a4e6923,69925883,8e786779,fdff7f09,25d68855,12644d04,9e582f64) +,S(afab98a0,e75619bc,ebcabc24,c1a6a0bf,2743d4f4,921fe53,3a393648,adad5d4a,bf1b3a87,759139a5,79741c09,21f29a10,7c8e5be3,13d75715,7dfd39be,923a32db) +,S(c2cabf7c,1d86a34d,addb36d9,c83a8ec9,b2dfe0ee,8176d085,cca91fd8,ee4181c7,5b32b724,53f1335c,724465bd,6eceb8f5,159ab150,e9c972ac,f51d27aa,4d91070f) +,S(92839424,8e847452,29a8c534,7c14355e,4f6e9cfa,2c1a2be4,f5ad6cfc,2a89f593,bb9c585d,fd41ee06,99ca7b4a,146faf68,51983b15,d652e996,c888a171,7c8c3a07) +,S(bca2853c,389ef184,208cba64,617bd7ad,55e55f12,d0c9fb4a,a8dc30d0,c73c7dfa,9f41289e,f32aeded,3d45952b,16a62fba,fe9a142e,1e65340,17588d79,e1df63a2) +,S(a4ea7bda,94b565a8,ebf53aea,5ce672c5,5745b7bd,37ca77e4,a0e4f281,71bf56fd,c9507485,1405ea90,9b9e1a28,42c5953e,629eef31,37bb0fb0,970cce6a,893e96bc) +,S(71707d45,af71139e,d7327ced,89a2403,da57c18a,8527bb1f,f754e78c,60d5e169,24b36484,fe4da6f3,a3f4e4a8,55a477dd,3eef0f39,fd3c585f,1b9de9d7,10223ef9) +,S(52c1de03,296f591,9d5cf4d2,36b8ff51,5b1f5ff6,d73228c0,7dda706e,4fdf9a05,db958d59,d73d574,384066e4,fda3b785,c9509714,90607c51,35d1d34d,5a344d0e) +,S(7b09c0b0,7852e845,30691989,cbccbb87,74dc2007,df827120,d8b1ea62,2368912f,4edf5717,ffc52817,d0eebeeb,782ba4d,9545a5c,da979f3b,e9c09e84,f82bd263) +,S(e99870ce,b29ad1a8,2bc08834,3e3b3c03,f26e7062,66b32540,681c689d,ffb8300a,8080ad92,78947d65,bcc12dbc,614d17a8,8ff75e3d,91230fad,c6f785a8,cd597f9f) +,S(c7e2326d,e28b8139,85db4cb9,c3d4c5ee,2dd2c2bd,2b912444,adc3a434,205c38e7,5f2863f9,cdc0cc95,1fb87000,e177cf05,d31adf8c,543d899d,195bf5e1,c6ad940e) +,S(883596c8,4ca7bd78,3c586bfd,28fba489,4c6bb66b,5ea52244,1199b55d,3e3f7965,fb114be8,59255f10,c96d6d4a,72945ac9,47a22f5b,68ecfac6,9406bce2,58e9282e) +,S(7f73a648,a19640f5,b0f029dd,37e56e7f,5cf61659,5e532dcf,7ffeb7e3,f20b42cc,4f76248a,f931aedf,b4e2df3e,ba3b426d,8ef191b,9d59507f,4a94ffa8,80ff4feb) +,S(c89ee34a,3660d03a,ce3b5604,1196a66,18c8739a,8a4795bd,db9c382a,9741aa3d,a4a3b888,35fbac57,f2f79ac9,d0ef292f,6838764,b99de084,684d1b95,12923884) +,S(24be4c56,d7dc0c4e,50050cf4,31d81f19,b5c46889,430563fd,566c4ed3,d941d5bc,e07236e2,4936315d,5f0714a2,af1ad769,f6a5fc7,a56fc1cb,ac09a085,f29e6213) +,S(6c31e71e,caa91c00,798ee5c5,3237a9f2,2866a91d,26936852,c4eb9853,e40b94f5,65aff323,2b5f2cd1,c1117e0a,c30b94e9,34543cd9,480f7922,5723c385,9ccf8cd7) +,S(506c373c,8479693d,3e03c022,9b61839f,e470a574,d31fa286,92601ed7,8e58b7e7,4fd0bfd3,a57c5035,268bd4ae,707fee83,e24f8676,e0ffe3ca,1673faca,1b7ab65) +,S(59d9a5f3,ea1a6cc6,16e7b097,871f731c,57571a09,1dc01b45,b48c5332,c98349a4,94ad373e,ee6496c3,263c348f,a7ee539,53aadf13,1aa6b638,21c16e0d,55fc8447) +,S(a524cfab,65371648,f641912f,a6ce67d5,c6f8929d,366448d6,4de381b3,22d75c69,14c26ff9,87fbd599,17a6ae90,bbe7c79a,ac1b6158,c3f46144,71aa36a9,45782823) +,S(126c986d,f83c6307,87c0d3ac,6a6b2393,8aa3fdd4,df26e76a,92af2c65,7f48c550,808539d3,a56a6f8f,3bcf04dd,31ac72e0,3f74ab1d,5e9afd39,7741656b,3d4c5c5c) +,S(32cabbc0,1aebcfb2,7e1a9d5b,4cd05550,d8ff25d7,b9a81db7,3188474a,ce39722,7d30120a,e08031c4,12c070f,6ee6b52a,be191021,faa9f5bb,9576feb1,8fbccee9) +,S(3fde1cba,f7ded6f8,a98975ab,ad5a64aa,8a9f0864,16dc25da,359e1cf8,22f42c64,e50fcac,61f0f174,b0e93cae,691212cc,44ffeda1,60dcff91,9ee3c960,2f5ac075) +,S(9cad22ca,d6c3dfbc,1d3a08d,6b102727,36e9db37,1ee1f26b,3ce932c7,11462e24,5ae84f1d,873dcd04,7f0781cb,aabbb53,422bb119,4e59d5a6,8824db95,50461c6b) +,S(9859020,aa807626,3a8ca18e,91c1afad,c20cf9f,9249c24e,1c652d19,7d5872ef,454323fd,21ab7d6e,470976f7,2d85fa39,a084e7eb,b332edd6,a3d054b8,d3c73e69) +,S(821699a3,e7cbcbd5,a2b093b6,c825281c,ac00bc53,c44b33a9,d8c31b9e,464eb2b6,f7d59c17,2400cb9b,72b44cbc,bbbd3e9f,e62cf451,bce6f840,23b073ab,66a9726a) +,S(bd06d4be,36423862,795fc7a5,5c48ceb8,440b3cc3,fc286dad,74ea7f6d,8cd370d9,3b09193a,fdcec88,ca4a5663,2cbb808f,61bb1253,fbcd1714,accd508,6183b90e) +,S(2c7112e7,9c8cc78d,f04a4ed0,e043c6ca,bb4b734d,9177f822,5bc41123,4bbdf4d2,c81ccfad,d42e2248,7612884a,d900f61e,bae242ef,65ff1afd,6e03ec42,38391243) +,S(51ae390f,a65d772c,833cbb8c,9ddf9ceb,b7f5236e,f1983905,762b7aaf,e122131e,3d7c9f80,80406b06,282f2a88,87dbb714,f1e96e1,e84eaec8,1256e1a8,ed7ba06e) +,S(c59de112,de237a43,2bcb8348,e3b31356,c7432672,6b9167a1,77d826e4,dacc59ea,36109f16,7c5eb66d,9f09c1d9,c5e1676c,aa33e403,a8e052b0,2854c689,d5903b25) +,S(8b99f23a,b7509d9b,151cb89a,45753026,77ca1e6,9219f0f7,57d01823,f556d978,86a31aad,f53afe44,f533cf0e,4bcd573c,d338e12f,904c8e9a,dc8e0080,f56a4164) +,S(4c670f65,7d6fa9bd,9ee4135a,1ef1882e,61f5fb7c,9deea717,39fe0ab9,78369dd5,531a8226,5d4b5363,12875dc1,7f891d1,b54e0435,1b539dd3,c100b797,efe65417) +,S(8e967e35,9daa0f95,fd7024e6,e57f0640,36aed9dc,9df0f33d,9388cedd,e0f38548,36f8055b,a59afaa5,8c88b833,ba110381,45fa0ab1,f0160d2f,1f1a1765,190d218f) +,S(3f611915,9c45a37d,5c7bfaa,cf0cc959,5e2e097c,8c7bc3e,c82e9e33,3b2ac9e1,c80134a,b7437dc5,23e08757,8eeada53,b9d2f3ee,25b754fa,f6c32e02,d597d7d6) +,S(3f59e49d,7c61412b,53fb203a,c7ebdedf,66bba683,87070745,9f85000c,f47641d9,bedd7088,4243dfe3,d238f101,f5dcd4e,64cd0978,986d50f2,ae3e2563,a43ad5b0) +,S(5b7d84c9,b64836a4,3bc44b5b,fcf170e9,ad46d4da,197a2781,bbbcaf87,5bf6d490,9f55b29c,c7d6b0ff,facb8975,507df04b,f2164e5b,9928156a,7c73fec2,b34d984f) +,S(e1ee74ae,ac3e83c,f73bf1f9,aafc3eab,90decf0d,a071aa88,962c29ea,51744b1c,9e86d2f8,b34e8525,568d674,8839839d,eefbe15b,80c66216,50acc508,f1277030) +,S(fa1ccd5b,8d489448,e3196c22,e96ca7ed,eba721ac,beee200e,5ddc496b,6beea871,e2b7f59a,326a6654,9d6479a8,a7a56d7e,8513504b,fd2a9829,d25e5855,2f9bc469) +,S(ef1e1cd7,f386096,1f6199d1,ab4a63ac,b292316b,f7a5e7a0,4c9f0c3a,7bfdc8bf,4cef9c01,a9de111d,8395dadc,e411e532,5783d377,559dc687,eeb510c2,ba98ef05) +,S(db714eb9,3e75d3ba,dfa5cc4e,d4813db2,fe9c395,95a1ee8e,9b3e468a,e1326120,3dc49a86,b81278f4,84d30311,c8816840,fa3cb701,665c067f,618295aa,6a71a206) +,S(5997f38d,bd572858,43ccf936,ee9d3feb,d70c79c7,9ad1c452,29af32fe,e6ea5d5a,adf7d862,b716011b,b9749e08,965c1ddf,1f44b678,df548eec,45a69a56,97e4a224) +,S(97d6f6d9,a920577,7b08ae66,6fc1fc7a,956654bd,3bc6c039,ea4eec3d,3bbaeb92,b450dc47,ff219854,dad5ab97,13dfbbf7,ce03fedf,4e7ffc68,4bdf1b5c,c20068b9) +,S(4f453fcd,5ec8b72b,69549ae3,c4eef99c,40232bca,1d6b10ab,c4b00d00,5ad307c4,aaded568,c4a8bc87,c7a442ba,f960d9e8,bd61f15e,d668f816,b94c0d2,9683f7f) +,S(5a604a3,50593035,c71c0a6a,caa7946c,ae4c4490,c0db71e6,49972705,949424d6,e578fc12,6d8701a7,a02b92b9,3fa89d09,ae82779e,2f78586a,8937a6f4,133be9c8) +,S(3f3071a2,916832fa,1b64cf0d,5b5fe8ee,2de601c9,34e08498,5d118696,7c635b3,e915b199,baeb233,b22adb6f,69df0e43,8712f25c,1be4470d,53851e4,451ad3a3) +,S(745bc1cd,643189ac,fcf02c5f,bf99c222,f7476a6c,2ede6c45,31849491,901c06e5,59a2bb4a,8703775d,e9a519bd,10e59db4,be16cb41,d0275d21,87291d06,d29933f0) +,S(bbd06e8c,adb3959d,853591a6,6387989,ab396736,8a6c1942,17580911,2637238e,ae0d8296,b484e5f3,dc46cb88,90b86a4,d562b003,a65a0c2a,2b4eded,38b8b690) +,S(fcda8db6,128dbe66,850b7e43,63a3b35e,9f3eb569,b7af97a3,85e53fd4,922cf07c,4bf3ddfc,37a0f9a8,5f758ee1,4c4d5c86,cd11f1e8,2a05ff28,3a0f535f,f9551974) +,S(6325dfdf,fc9c7ded,2a65e113,27210ccb,4ed2da97,4eded570,5ca1add9,9873cce2,89fe4c99,683e6fc7,170ada7e,26179fea,7ce1930f,af1a7358,4d7d56d3,4cf222e1) +,S(77594ca6,93495096,3ab5797a,5279d0a7,513df59b,41a3ad59,245e3f29,22ee0d7f,195eb112,2ccfbfc8,fdeddf45,ef2ef58f,631df03b,ca66a4a9,5818dd83,e5faabb2) +,S(f356ec67,ea9b242f,4f1348fd,c6592772,e2defd7e,308427b,ede15452,baa67867,3d2265b9,e23f8ea4,9a2b7145,9c98b03f,d75a2110,8f104121,e4a2fb4c,d633ba7a) +,S(3360ae12,9b0fa48e,c78e3091,4f8ae6f9,86149f0b,590a12ff,cadfdd2e,f8a205c9,79b37bf2,720d5a11,3ec09872,22b0a626,3d7a2051,e337cb83,dcb52df7,25d18a34) +,S(44e90f52,c703c50d,b331a4c5,fc47613f,b29040ab,9ff0f282,3fc15ad3,f9e8727b,62dfb341,92653e6f,636d013a,718932f6,95c2491e,26d16feb,4009ec05,e2f55f17) +,S(e5d367a9,b5c3ae22,31195876,4b28fe35,c9e04289,518aa09e,e7902b5e,4ec84047,ea1b257f,1abf0fa,6fb37c06,907052e7,fbbc06b4,c2382ace,9c9a98bc,e6f8bcf0) +,S(8478e8fd,7910e5ad,3c061e6d,422806a5,559baab,e083b8de,1005413b,59a63957,4f793418,5193499,13fe38c4,514bd4bf,2f3f1ebd,b492fd5c,fd8c1bc3,1a2df1d6) +,S(c38327c8,587731b,f5b5e224,79c9274,10c97dff,f6855b6d,c2ccf761,2a84b42d,eb03afac,cb1b102e,7e87d61f,5012ce74,a213fefa,b855db22,bc657d52,4dabfcd6) +,S(b9e8a812,5348a672,558f48c9,d17f28a2,4662b4b6,604ee14c,d622b521,bc51f10a,35c2780d,65fcd07b,51ea0224,1771b523,3813e7bb,97a1744c,e3dad732,ef1ccfee) +,S(a54aa2d5,95cfa325,38d2e483,70ba86af,d3c3b53d,2141b0fd,cc68a729,a5cc713e,bf74dc6e,63c02b2e,e676b9c8,6a851a48,7e9552b9,a32eabaf,4e1faa06,8bb8a159) +,S(d45fec3c,e2df54eb,844ad145,fb8884ac,420ce2ad,85cd55ea,4cc19e1f,da9fd956,ed8cfb00,65aecb6a,6901dbf9,b8c208d4,bf6be1e7,ee74a08d,205c48bf,8cb81bd6) +,S(f4b44e98,f728b318,ca959829,d4cd836c,5c0136ab,8e433101,87be24ad,53192172,ef5521b3,960bce49,2c841fd8,8cf7b8dd,2febdd8b,f0aa64e8,4d3c2a09,89ea9fa1) +,S(dec6d1bf,d349110,faa0cd40,e8533078,dcec40c6,e260b9e2,8412d424,353d67e3,73a16f81,3609c901,71efe44f,32ffc90f,9451b0b3,24107b72,54ca2fba,65095895) +,S(1fbcdd53,72e17c41,9310b9c0,2273534d,265f1c24,bc1a6039,238b5b7a,b3ff013e,9cf4ff4a,6a61c11,20c4d14b,97275547,b2358f75,8a2a774f,22bc77f2,4c6c27ca) +,S(d9cef0cb,38c6ed7,7aed53f4,93a31daa,50ea1ff9,aa43b890,357012fb,e2ab593b,32a416fe,246872d5,b68e6654,7f19dda5,e161cd13,ed041486,4d0c2dd,3653303f) +,S(1641b549,88e22a18,45e2135f,88d2386,4e2f607c,ce33fcce,de174a60,1ff03da3,edd3f0d9,ed718767,3664e1b9,540f816d,48e3ffd1,cfad86fb,5b68dfbd,7d94922f) +,S(99ef6c16,3c5d9ffb,1b638b21,1ef60166,37938f83,ac4ef76f,96c5366c,3a243cdd,6b6eef62,d819581d,e1dd7796,df043e02,7f912bbe,6ba1e499,a311769e,d6f66b48) +,S(49358d2d,c24c2e8b,80ff79b0,9c53645e,b9c47fb2,8ea4ffe4,e2f4679f,5b5bc97c,512a14a7,f9df40eb,ef7c1cbf,f8e1caf7,b8c80748,7bee3865,37837cae,dc1cf5b4) +,S(e31d3fcf,b1dedfe9,2549c5e1,a14cf383,c8c122a5,a430aee8,a4eec846,7ceb206b,7bc3c266,69db747b,a3ad1dd,e83464f9,effc4dad,b4de7687,e6c3ae56,a5b0449b) +,S(a82ec9d6,ac86bcad,fbb32e66,a28d7483,ad1fbb7f,979a15d4,4e324ce1,86c64adf,bac87d2b,c28b1ae5,f4ab46f1,ac779936,3a9efad0,b1e1f81,6c4ec6d3,cf74c89) +,S(21650994,2bffa2e2,479ab82b,18cd3aba,dc370c3,18c71c08,1bfb53d4,c8ea113d,97a8246a,2f653450,be513b6f,62419f90,f84511be,9a5f3103,feca77c9,c81fcae3) +,S(735050d8,208d9688,7fdf8070,e448e905,e4e666c6,3db5857f,63ceb362,c6dd4b84,2e3fb438,563661c9,e6fe23f0,7c8219ac,216887cb,ad307918,90001f9e,2ab9e2e9) +,S(1d021861,e679dc08,a34c3813,bb9c3e9b,65f87800,79dc08ba,197b3b66,47afe506,14b6d0b9,2303483d,9e92cd0,e295bf08,4a10e84c,ee0b7c50,ceaa6ba7,a6fd2f1f) +,S(7a7eee74,86ca8973,a858c15d,54eff96f,f91c5577,4985433c,1bdc4f4e,46d7810b,5e83a07f,5d9150e7,a7f5057d,87d19ccf,448fed1b,bc1e2297,c7012cbb,77b498cf) +,S(811c3d4,fe0a3061,47c05cce,32a32ada,48593802,32f24b51,f50e726d,a702beec,a6fcc16c,6c9cf4f9,2e84214e,35ad8577,b28e599d,31ed74ef,c95eb2bc,833d9f0a) +,S(2ca14438,89ea9e8f,24d5b1e,e44b26d3,ca25ed08,30ae950b,4357da49,21ad606c,7b48a6c6,92d8a29f,a82c656,f8e6213,c5e90be3,7413d86f,42e10e63,1026c551) +,S(a980ffe1,61041afc,339566d2,957e6624,5dd3e0a5,deee9c80,d57b1f1f,390277bf,3276f7a2,a139343b,87744079,7a174d99,457d5005,71ce47fd,10e41456,7a1c64c) +,S(e570a3d9,cbccb74f,c582954a,998d9371,fde41d98,e65de6bc,9579d6ea,d9cd80bd,5a749177,6658398e,99d3035,12c168bd,9400bc6b,c7dea2df,2739abe4,16973a52) +,S(f5fbaab8,952cf50e,66d3d985,d9280bad,71bd25fb,662358c9,72b954c3,7bce1110,1aca2123,6179f821,a4f097c9,b48a744f,8010818d,3ac6cf,b02f57f3,1fd77175) +,S(2e5942fb,ecbda8ac,15408d25,84ab7c75,6f9e525e,c4dbf375,5559dea1,718d89be,95106507,d14199a7,8f123d6c,f6b59262,30e12a1a,8c0ca016,40c556fb,14bc790b) +,S(92bd04a9,891c99e9,6c9e7f64,a9bab705,a9fc83f,a739413e,a2f33001,b55dd296,cf5e3733,659bfd9c,e5417ba6,817b6a0f,5cc71c34,22165fbf,13019fad,822ba587) +,S(30ddfd9f,a50feae1,e3cc5426,93ddcd62,4d0e52b0,867248ff,ed7d3041,a7b11083,ff15d0fe,2bb183ef,a18389e3,df4269ca,21bdfa0f,87ac641b,14bdaf66,26eb42ed) +,S(8cf5150b,df8ac68a,af319688,245719e4,67ddddb,72fa7f1c,baf39de7,252a9f4f,4c28497b,a299bb19,83b18bc2,508c98d8,2a9963ab,4145807a,2130fc05,4186cfd5) +,S(1f4b4efd,50974efb,3caed9f7,4f6dd979,4a8e3c09,8decc1b8,69032885,265e46c7,6c4b04c7,f7c6b00d,c38adeb8,a47c7c0a,68535229,26500a76,ee1c6feb,179fd399) +,S(9d524900,979afa33,8d5883ba,d13d038c,3f915cb9,f2e29a2,2a028b18,d091af81,409a113c,37c732d,1104453d,6b161d33,db3257c7,b9a73e1,e0f1679e,6802be38) +,S(52e1e4e4,46eed9d0,fd5c124c,1c23403c,5b03984c,f3fb0734,c627f34b,dda2e3a1,674a5731,7375ffa8,c3c4104f,12c1713a,e2dbc630,75a77e5b,26243217,88320a7) +,S(827b171a,8eef4e31,e6ca8b6e,7c6e36fa,e0a6c93,a77d7148,fd22f7a8,16401c8b,65cd85fd,d9b801cf,7de6d14c,b78ba114,1d58c7fa,129f9f08,8275f364,f7ca7540) +,S(124f45e9,61d89642,6a1abc32,e582e246,3db29954,1bea0383,c83f917b,6cdf2f9b,734e2fe4,110b65b1,2d60626f,c6288f87,e48e7a7d,213a4f83,58bb4d67,978d6c62) +,S(3b71298,18b2b324,10e4f002,899204c4,fb4ac9d6,c08d1169,5f5f5699,9a4d67e2,28b6f78b,cee16b5,5c010c51,ec465609,54ba6368,a18ae218,5607c1fb,42c27c3b) +,S(d271d87e,63b5363,e664485,ea6ae70e,e2b887a1,c7f7e0a4,290033b5,512d8a00,65d43804,7865e280,273122ba,8d8644d0,60ef5927,34971c9b,510238eb,9d6da847) +,S(1d1c6d85,2db35160,67cd2d82,e2ba552c,c5ca0c9,ae7bd661,e8494b25,cdc03a7,bc31f4c5,673a0256,ee9b6840,7aeea035,e19f874c,bdd7aebb,ae8b1005,4e691f62) +,S(8fee89b4,71e394c0,ddad274c,ba07de4,bf8d2ecc,695647fb,1d3756fd,46efdd9d,5d5ed0c3,8479578f,d17ae148,7198f9cf,4ba5cf71,46a9b4c4,34ca62f1,bd2b8c6c) +,S(681fcf09,55a0f351,6026302c,ce3ee475,8ef9385f,908dace5,5d7fbd30,8810a6ec,4307f75b,99927624,80187edb,c4c6575c,aa54e8f4,190f0885,e6d358ca,2a38faa) +,S(717fd6dd,fcb5a71b,6a584a28,904cd3e2,6f6c1a89,7fc32918,90792937,b3a6971b,b403f829,71d4ad04,dfc40553,27f6da8e,1b05e25d,341d6511,d7cd859f,58b17992) +,S(f2b95723,94eb9786,dc1f4998,6ad8c340,d2983279,c7323a34,227013e3,754f2ff6,b553d381,3efdcd41,7189645d,d9917b73,bb69e705,e7a6520d,dbaa497e,7766763b) +,S(58714be6,d7d86c89,65309b52,414135c1,9ab6fed0,1d56d7b1,4237485d,96730b1b,c011f34,3e38ce5b,deab84ab,f0e31537,4039845c,5fa4fcf8,1c9a4d5e,6fe3e533) +,S(d33ce5ab,c828f8c1,b9700d49,e9c6b4fa,b30819fb,b2bea23b,7f915bc0,7a6ff3c3,739b6222,39134988,22372ba6,3fbe22f1,ef59394f,37db956f,caca4c11,75a23395) +,S(82202e32,fc7d0128,4eba58ff,42f7d94a,24904808,d6f920d5,9837b26d,63b55479,fde63954,50aa55e4,fcc4fb0a,8ac2c880,63aa3202,9a00004d,edd033b6,2563b4c8) +,S(25e63218,5bfb4c88,fa300e37,c8b64a,941e6487,a34262b7,419fa7c,2dea7781,ae696b07,4802ab99,4df2d84c,c6731d7e,9caa124,548c2a11,42ddcdbe,f716e640) +,S(e0336a05,b9254e1a,f2468a36,343a0dff,9da8773a,1efdc487,53c1a95b,605c114e,41d75960,377ada38,79b97455,346266c5,5ba05915,9ddad050,d96d9d8b,afb12a18) +,S(843363af,7fd2b1bd,1c9a9253,e42489c1,34ee875a,db57b752,62d731aa,9a996662,e5c0a2d1,dbfcf013,ed4bda36,f153a328,12c4b3b1,66e48473,4d2d3562,ffcde6ca) +,S(adb210b8,1cdb7f18,f97955cf,fa7e5763,abb9f202,9d283c05,26df6332,951178de,2c211f05,d8182aa6,d784721,948afa11,364db5ec,2e1becf0,68eb91a5,74ea0e35) +,S(ab0c5fa1,a2fe2235,ee93854f,59a13792,2034604e,5857b6e0,88b65142,f24d7491,e54725cb,e36d6e15,71ca7384,7383553,b9dc48cd,eca6932b,8d92f785,b80124d2) +,S(3e5de77a,1d2163e4,3f3124b0,af4f5473,868a080b,67acd835,f9cbc88d,7885deda,a6ed34a4,2f9503b8,b83e66b8,377f514a,e1927dc4,c37ef6d2,254e651d,15746630) +,S(60c68b3d,31d1d326,5b71f068,8f32f671,32184815,f83a9ceb,50eaef6,4991ec05,977acc61,9f7d24c8,a95aecbe,987737a5,89886729,500ed32a,9d760fca,7c00d498) +,S(21b052e9,b646e595,b6c04a76,a66b9b25,4a126729,6bea0654,64fc5b31,69c135e2,1029e4cd,2fb3d717,6e87292c,4b0dfd7f,18db6ed4,59aa9285,38f0989c,540779e7) +,S(700caf3,7c664515,ee501e66,60be4cca,f58bb2ef,5b11f79d,c027dba3,7b523d68,7df76b88,f1c346f3,2e32487c,19957830,8eac9b7e,56edc948,e1a934c7,6fa08be1) +,S(c5ab9bd2,1293844a,ce5f1c9f,56458315,5d34aeaf,565a5696,29969664,49541e8d,2d2081c6,c61d6c8a,a0df4467,8ec53a7e,9b34d90c,57db2f29,c0361304,1c422d8) +,S(8afc3f2e,d53f5dc1,448d15af,8c2151d8,5713fbdd,5d46a3df,a4ad376a,16d75a3,11f6393,2627bed9,e015a99d,42193e6b,6767c513,f3457897,64db1a4e,4b9b6c8f) +,S(414ad9c6,bb55eadf,cf4cf729,27ae3682,c0d69867,ede9f4d8,6e173c50,3a5007a7,c4bcd0f8,f4de9b1d,1102306b,667a546d,dafb6f82,edbdffd6,181dd3a0,8f603585) +,S(8211e240,b84b7317,a9c5ec88,fdc426d1,a163a2d3,aaf088fd,b2317247,cb04a1e3,ca76a59b,b268bf51,4f06c4f6,d5961b33,a74f10b1,70a9e9be,4e7942ad,26722bbb) +,S(a54dfd32,363add3c,75ec4452,3094b27a,3f7cd291,43ee52f4,29e59daf,22ba700e,f160822c,59510098,3e38d130,49b44865,3639ac74,6a93ebbb,2798d92e,bad4490b) +,S(77d64c55,52b29b18,a7aee1a8,1e1e9d3f,e2921a43,cfbd95e9,a3ba7cb9,498860f7,e97bb8f9,5ea9c8f4,440ad9d7,36d9a06a,fed03a9,cc96597,8d06f2e7,8208ff10) +,S(485b3814,b33e6bf1,1f47f0f5,f0e5a189,1b57c103,60f13d61,ba7947e1,6e309ca9,e6bb7870,ce607c62,a6050dd0,946c8653,f998576f,2c781b5f,15282632,4e38bdb) +,S(ed2381ec,a90a78c2,def618be,1b6edc51,7ced2ac8,14aee9aa,b0a7068f,72739c,cb0873e0,ba326452,380c291e,c635381e,d6859916,2ca10fbc,3de45ffb,134954c7) +,S(e444af79,d36bc127,c83c7369,a4cba0fe,955b6a66,8f2e7a68,4a65e57c,44ed971d,a7876f03,27b6823a,aaf55ca1,6a48998a,ec50e5de,10d34e9,dd7c554f,d3785fff) +,S(af8c34d7,7de75a2d,5f64296c,152fea4f,b8677b8a,96cb278c,7ed7e50,69fc1fca,48ce5862,ab6ec1a8,ce55899f,24632be2,f3c451cb,8b81ca8c,f9ecc3b2,2984d673) +,S(e999d466,243a44ed,18e745a8,1da04a31,8940c88,760480cb,e315436c,f67efe13,f41e8e70,63a84661,c22ac0e7,5cdedbd0,ef55d3eb,7fa813cb,2f7d1fb0,237fe36) +,S(c40ef8aa,7d8964ff,a3cc923a,2fdebec,72cafaa,58b72d66,e209b644,604bcc72,480e35b5,6549a1e6,f112c3b6,176f3378,ff50ebc7,b3efac2f,696f0627,b7238ce5) +,S(482ee41d,e3f9499c,8992b546,e209aa5d,679e4b8a,22a26615,1bd1b0f3,9a52982f,510e6070,d2131815,2d52eff0,ee10ec6f,563f92ec,a0e549f8,32efee81,dcd3de3d) +,S(4660a468,25a3c1d6,67003c69,4d36f8b7,6df7ca32,c6029fd4,65dcf726,5c58fae5,3d982bf5,46b5c296,988acc72,2dade97,791de8e0,150397c0,700bfa10,ba23f618) +,S(b85e624c,92ba6f0b,3fb1dc03,37589994,d8a3aee1,76314d87,3c8bef0,eb5d8f8d,88936b33,20a55ba4,24bff93e,fb36ef77,e2cdff26,866cd486,88c61868,ad75679b) +,S(a41920b5,361a26bf,bd187eba,b62fd5b3,b3be282f,94ef94c6,b1698754,902683e3,7790a196,29d93b4d,3d27201b,32053e02,c95a8f9f,260647d1,491c7a4a,e15ea98a) +,S(93882da9,79262a60,3252f01b,bf101d89,ed1abf8b,15507937,55979f4,fbb7f86e,938884d,f0a716ef,137450b,ad5f022e,23e570f1,3ed37e02,15a40910,189d7e44) +,S(a10509f8,3efeda60,acf56b64,3709b197,ebfa6a59,e66efb06,79c23225,c8952e00,759083d5,559bde4d,9a37df5,24cae4f8,5a06e7a4,7c0e15fe,830f0677,c24d1ddb) +,S(2b945a97,6ea74278,73d7e587,dfe75eaf,c55de704,8aa26d29,4b3b1ef9,2beb3651,423c07ed,27ccbf6b,9d1cbabc,e00b451b,cb488d10,e5daf752,6980ef65,6893c65) +,S(86f9d9bb,c1a0bfe4,e03da0,13f17017,f6951691,28d51073,b594457b,fcc37f0,f370c624,2e303796,9339cd4b,fbc19e8f,62388f02,649247ed,df3c6c67,464c32bb) +,S(f8995af9,555e044e,6238d895,8bdb4e13,3aa9cc0f,90a9206c,16d0f83,dd61ed91,b2d4d2e3,1bee12c8,3b8bdab8,34fa2e63,1febdb93,4af194bc,d0825921,4ea8a060) +,S(ab55a27f,69eb352d,455eee7f,bbc1c74,fdea2621,63d09dbe,2f554417,819394ce,8ac56493,60f585b5,72373bc1,74a930e2,4d54674a,89789353,4a166200,e31b801a) +,S(4fc106c9,c428df98,916a8906,95e98353,ce84723f,fadae522,e8a89916,a23b9fa6,90d732e8,3d54341e,4f4c88be,3392687d,fdebbc4a,7c19afd1,92531688,9eb92031) +,S(c9c85980,8831cccb,77d87b25,73a894e3,874080db,ba076b2,4626bc82,3149a91,9fad4ccd,8c0949f9,be9a6355,f0bdfa36,c5f99268,780566e6,a6f302e3,b2abf0b8) +,S(c0cb5b7e,2293abba,5ff78c46,aa1422fd,a278eb5c,ddd58cb7,aee77149,1c5209e7,8101f42e,36648586,5db6b572,d0df4ca3,cc72789e,ed8d27d5,1330d733,4e10c47b) +,S(dbfc03c5,16d93f83,472ab60c,391bdd69,af2f70ce,fbce15d,140f1590,d8ce0b63,f838e14d,7228ca2e,9a33ecfe,c376aa4e,4811fa24,debc7b46,4658c153,fed26564) +,S(de260685,eea13ff1,1571d891,35607b0,435140b9,62e3baf3,7cc3f3d3,484f59c8,6bc23ec9,a6025865,e6363335,bb66f1e6,c1f5f54c,aa5f8acc,d7f8fae5,99cfbbcc) +,S(58d78d60,b8cb8fdb,1b62f79,f6c17ebb,1ed8129f,c7819e5f,6f73c58b,faa2e71e,7cbbe4f2,fd6bc671,8c222f5e,16391133,b04d6d3d,bb263531,40aa4053,b44bccc1) +,S(e72b9b1a,eed54fe5,ab0869aa,90014e3b,fde1af12,f646d738,211ebefe,2c00a490,cd92d14d,8f595833,842af020,a2cc82a0,d9465969,77d25d34,8cff3273,90af4fc2) +,S(6a86bae,d55a5be1,8b7cef97,c9dff8a8,b725f614,2221485b,3b9f348d,570fd658,138a2691,4c3b3015,10312140,7709fa87,60a14f14,571a9d40,81c06d67,ef2c5724) +,S(1ca08cf6,7240f244,d6cb0059,564fc283,b17c39e1,b624716e,e100aee,bb0a1fc5,22e24fce,655d09ec,34a36317,c66adf07,deec2743,4e9c016a,b3447b3f,d9ef0a55) +,S(d95dc128,feba49c4,73e1ee30,bcddf76e,b7cf628a,fd495607,f558201,824a0b0f,d5340ab8,fea3e137,d1061274,c69b68e3,633e98ba,ae2fe116,1612c4d6,c7c7e8a1) +,S(2cccd22a,7f4fd501,6c3a14e4,769a88bb,ae7e288b,d9987afc,f3c073f8,ccd83857,ae82663c,aea89fdb,4710f849,ff8e4fb8,c2a7b614,4edb5f3b,f2564dd,73b389e) +,S(ec17b5f6,c8e4de23,937bc003,7dd7b411,ae4a9ac8,1f2801d1,c5eebeb0,95628a43,b3e0d51d,fd5815b0,631fa298,968fe70f,74319620,f0798734,8e66e6e9,6658df83) +,S(a63aaf7e,62907f4e,1a613cdd,ccf1cc98,cee8e12c,8bace3ca,95685889,6c96b6f4,2f953ebc,dc5f9973,e9d44ab1,23255a21,f8bc1a7d,e800cdee,ef754031,aee8216e) +,S(8eb4ff30,318d8d0d,6b45636c,b296d137,90e345af,19a14b2c,550e0169,87ad32f3,4b8e238b,ae7ffc7e,7d600151,c5ebb776,cc01d51,827f171,8f28af77,ca4a3e3) +,S(ab1420af,bb5b4397,f578a6e5,74a63aec,2432fa8c,b4712341,4374add9,8276b8d2,faf6328e,a197e927,65b9df90,a79558b,8f264acd,7f75b574,90ce657f,64b94396) +,S(daa1890e,6b2ba1aa,dcc16f1c,c1d5999d,5102aa6b,348ffb5e,9630bd1a,886f680a,19facb69,5a63eb94,cb6f6005,cf2bbd23,8744f05c,2c220510,94bf6dfa,352fa209) +,S(f199f52e,5398d1b4,899a1b0e,df8ebb73,cb08a642,bd22ff2e,b1cf647,7f2a28e3,3619abab,a5e2131d,4ccf8747,67ef9b75,2d5278ac,5549bd9e,5c1b5985,9ec2f454) +,S(182a9e93,a5f9ecf3,6bf20bc1,497a4a35,e75c86f5,9c9fc046,e2752223,f046ad6a,c6095e88,c39dee18,ca867693,d85617c7,e0924dca,34af07a5,c731e488,ffb8bcfd) +,S(8a4cb53,636fe66,b660a701,64277fb2,5ac21eae,906327c,3b509954,b214abbb,693e5851,4cc6a941,23ee707f,ad25d638,8efcb85c,25500bbf,63fd6926,a1d0ed1c) +,S(4901335a,3b40c33e,115e3105,82c55972,f495178c,813bd8d4,2b208916,5c8c1282,47007176,429d740d,dcac70eb,9e1f0e94,f26a9a0e,4dde0166,24d9d801,c84214e3) +,S(8180e5a7,7c34362b,461b49e1,4b9f2e05,df64f55d,cad82b8f,cdf41232,984e01dd,34cf5621,d4b9f100,aa34b0fd,5ac91d,cb3fb49c,130f3e65,de742ac,af05040b) +,S(8f71227e,fea9f4a8,9dcaeee3,58eaa5d5,a90e1d7c,b7d232a4,b1085fe1,3651ee9f,a4da15bc,bb2b79a0,a27c344f,3b914c7f,e272676a,bc045aae,e90daf4e,9655ad73) +,S(dbeb9b74,cdc9bacb,83592a2,a3cc19a6,d1ea8eaa,5a086a3c,cc68d423,cfb58264,be668792,83f07fb5,830732eb,79e16bbc,18e86df9,b659e2d4,5b1009a3,40576161) +,S(f328e93f,a7f52cac,3c7b09b6,280528dd,7d9ea4df,8317a958,ab0a617d,71591933,41ce8c59,811f9e90,61dc3f3a,7d85d394,2f780c17,d7ebca60,fc042311,f2405547) +,S(56d4f403,416b1bec,49c5f44c,2021c245,d4ca4181,5131cb7d,8fb0cf08,30fea051,cc5f6133,948f77be,934cb637,3d5dce8c,51ae1a92,e3d802a8,d35a3ad8,50bd39ce) +,S(8e22e04b,8bb476b7,ccebecf2,a327fd41,dd90c9fa,67cfc49,e9cf4ebc,39022b8,1f8fa60,3204696d,34d03c02,31d3ef58,934e7992,c2c81d6d,3e4193b3,8286b8b) +,S(341b22e4,b9a77c68,f93624dc,1cfefade,b396eb72,bf9fce1a,51867d7a,ef064f6,95839f87,7bc36957,59562bcf,dbcb2db,af11ed72,7d329e27,cfc8ff8b,92d9441a) +,S(3ea42e93,9f234112,879e8680,94fb8a8c,e6af9799,c000b050,45eb2026,3b324763,44324167,6f5aa6f0,4fe4d51f,fecfa8fd,60a5c0a3,38b16f59,1866bd51,2e01a623) +,S(afe7b44c,ef10514e,f94faa1b,b8cde91c,23d8a660,a71c3173,42f927bf,535d625b,7617a788,51218772,bcd51f18,54b063ee,6cfcdd77,7a388427,51cacfc8,7c8b4b65) +,S(a360ca02,abb40d4c,6e0ac725,f2c035d1,12f69ee3,ff0e1dda,37a3fbe6,a2034d2b,161e7178,3fec3ea0,305d0f72,3a60846f,9d8bbe79,255a3814,fab83269,916b646d) +,S(10484e5f,f7d9fe7d,9b65d989,9b2ecdf7,5984d18c,1199f61e,c914a85b,78011b88,12d1c0e2,1e137357,9ede1086,c2c1449f,e7f4e03d,78f7b184,4f744d6f,9576cdc9) +,S(76c2dce1,5dad9ddc,24276c40,eda7de6a,b11245e6,5b051ba6,7eec39c6,d256b138,d9a601ce,585b0839,92e3fca2,a43739a3,61a8967d,3eb0f605,ed4cef15,fc64ce82) +,S(671a31d4,c3e6ed98,b044fcb1,83dc60c7,d1d83988,3a547356,27b99b75,11d4d2e1,6fdd8d15,2005ef3f,7ef3762f,bf43a849,281f185e,a52c1b3b,8ad371b,e053088) +,S(91d0f565,a2da6903,12b72998,57f71c18,c2343a5b,a6f17243,1bee12b6,6e898a37,9d6a55b9,1956a288,d56906a1,1f7cddd,e6393ad6,7249147a,41eb209d,7f32f681) +,S(7e59f058,1953a2c3,cbd4d0cd,8f4df7b8,6b90d8de,7240b2d4,de9ee9ab,628512ba,33b0d1eb,74cc7d60,ef419b0a,f9f03714,35a012fe,328fbdbd,9d9b69bb,9a42a173) +,S(ef78b65e,b791bed,212652ad,ab1f32ff,f43a285b,e040380d,d3492afe,1f788a26,9f3e2538,96d5afc2,3ea7ab1b,24ffac00,f156cdef,93957910,abb1cd1b,6508d306) +,S(78b978d0,199833ee,417ce2f5,fc12cb01,cb0c0e4c,ee752e1f,50a8cdf9,b56b7cd3,9f9c7dd7,372606bb,e3170141,31591f5d,dd631f91,71460cd0,19709478,c1560dd9) +,S(5f785b31,f9945a20,e992f5e8,80abab72,906ffdfa,7ba7ccef,f1b3d26d,70bfe64a,a3cc480e,b3cb386a,ffa1988d,3227911d,57522413,e5d0846e,a6d0a17,2b881c1c) +,S(9fee7999,7cbb492f,cf3aadfa,44484d71,2c3887d,6375c887,fcee9fe5,7806b3d1,43114327,7e94c760,1fbef25a,60e7d448,c0f0b8f0,c6c64437,a129d4ac,fe24c22e) +,S(12f2dd5d,b75d8885,7b7befd7,cdbd7c76,c0f46213,f9a53102,acd8b0c,4ee3f30b,ce27598b,e85049e,9ad3ecfa,d3864070,f8510570,742dd021,6dcb4aa5,334097d8) +,S(c694aeb4,3ee2b51c,3f0e2bef,bc1b718e,fbb86f9f,1d2a84d5,3178325d,cf997bd7,41481f3e,b6a69311,2cac3e5c,c85a6f83,6fc5190e,ae71f226,bdc887a8,ed050977) +,S(fe266a46,14c5c05c,baf3493f,5af3befa,9bd16100,860bab1,49ad78ca,81047ae9,e2e18ebe,c44694d4,b7c614ad,a772a5c4,f58ca087,4957f20b,741b954,18471e6b) +,S(7975e1dc,926b07c,487abfa5,8c183f21,daff04e7,f67a7250,d2152699,356118dd,c984b97,44e2b300,ca54b779,da94dae5,f943468d,9b9729d8,21cfc709,351409e5) +,S(93573cdb,50183589,a0909e8e,6186d700,7022848e,b7fd6951,a137cf16,a18a2b06,7a957c66,3047f6ae,d9490039,d136cace,caae2d8a,fc9f50f0,26590e62,18bf47d5) +,S(c0bd2e1e,a60f6feb,8e0ac7dd,485fc4fe,6771d80e,e29b4829,fa37faf8,81d77660,685b74fd,9edde1c7,69076267,d9f247e8,2effc83f,e25af065,56aff25b,335bacd) +,S(56bac0e1,93192207,906e5f45,d55d5919,b676852b,daa43253,8c4c6984,9c24bf3e,e3bf51d3,9856b812,d2e480bb,c8b118e5,f5c0ae9,f8d09096,a5d207ec,2fc18ebf) +,S(53b41b13,fe7cddd2,ebfec7c4,a985fded,5225fa0a,b93dfc65,2314d1e5,9142c06c,90fcba57,44e4f565,5d2e038d,ccd2bdff,cb4ecf20,48f2ba98,8f62fe9b,c3b69c4b) +,S(bda05e31,ccc0edb9,47ebaa26,9182ca2c,b1136400,674ce5f5,d55fcf2a,c2e765bb,97275979,31236982,a7459356,7308ea97,2fff08da,ae8f707b,447dc6ba,7acf75e8) +,S(48dd1c6a,8a900820,1fe09f19,a8f65f82,91196e95,1c57189b,21aede15,4b0413d8,79a1f6fb,1a943dca,6517e287,80e72f85,c5a6150d,9c50d7af,78c8b63a,c09b98f5) +,S(75406269,e28c428c,8eeff4e2,ce9a2d48,2be8346f,3446451c,13c04380,292f1f2c,4743b097,211c807e,23cd13d7,692efc44,202c44cd,dde5a89f,9e7cdc5a,133e996a) +,S(1aa55d93,bf318133,8840ae4d,24314ffc,74420002,4ddab165,4018604a,2192ee5f,babac354,92d59e8a,656ac7e9,9b6cb2cd,7a6a8e88,1361118f,41e38f1,2cbc3bfc) +,S(75be4c50,db7bc629,e64fa850,3d89f722,34d214f4,9b176fba,b937120c,477dcf03,b5520bba,8c606db2,833d934,3c860c6b,ed2e5e2a,41a6c3fb,51154c82,94b6f819) +,S(f3604822,e4ed8b2d,d4b2486,b611b95b,6508e10a,1c725c7d,8d638254,3cef6c8c,f405ac79,7404bc6a,25a1a412,f2cbd698,75d99d2c,b23ac105,f9839446,222dc0f5) +,S(6c9216e6,6f9326be,fad5f727,ae0326b1,da54ee91,f041d2bf,2d87dff0,e77cefe8,64a021b9,bc1947c8,df546f92,2f5230df,1ec2f372,50651704,557377fb,39d16517) +,S(ae479bbd,ce97732d,df313861,76807678,988346e2,5b12bb09,e74d474d,6905668a,a3ce0355,c5996087,89936336,64d9bdd2,b33a6f97,ea3f28b3,f4b7c0ac,92612929) +,S(ce92c179,66f74db2,1c6abcf8,36cfd2f7,9ccc05a7,aaaf74ff,4807052d,754898be,f3e3d3f3,530f38c4,ca59cec9,c8e3456b,8adebf80,3f10927c,e44e79ca,601bb978) +,S(8a0bbeb6,815275c1,77553d87,5988c4dd,a96f5ae2,378a3b9f,477cf162,6e6ea68d,958b795e,46f45412,acaa9f77,85a4e34,a7c74eac,228476d6,4e917983,5fe77f4e) +,S(c2a44ee9,975400e2,912a033c,5ed1e7a,7f0e97a7,1c86e8d0,c2e5136,8dd9ccfe,956435ef,7d24a507,dbfb69b2,93b51369,70cd17b8,ebf6bc60,596a9545,3675668f) +,S(b615f625,534ddf61,47b78520,85443bcd,3d3bbe91,c815dc29,3cc891c7,199ea1e1,4cabf4f1,99e21468,62a90876,4f65c624,fe3afd1c,6b399e12,267dc1e7,6ec3ea25) +,S(afccaf8d,fdcf272a,cf56dde9,3980bee7,b64a0c54,f80830b5,5fd0b93b,e8a75a0e,8d8ec5d,6f6fc44f,89f6d9ba,735861af,e7d6a660,7d88e95,54f2c141,1042a63e) +,S(534176a8,c5311b26,1f39395d,f78300b,559d072a,cb3873ac,32833c8a,9b135f53,ab84f84b,5eeea7b4,87ef6639,8fa756fa,b16155d,683ef643,b03c7e6c,8ab2f436) +,S(5f7aa173,97ef95cd,f47651ac,6220f3f2,8705abbc,6531b93e,a65fcd14,1b91f34c,72f7d898,3cddb34f,2ed1b28f,17a77d8e,70cffcbb,e0462ab8,b7548561,9881da22) +,S(d4fb4a4c,c1e2fb72,b301db19,335afd7a,b6a95258,6903f449,aa287fc,ac8f3d3b,76b572e8,4a9db287,19d098cd,5dee787e,f213adf7,9ae90306,8881894,e14154f9) +,S(3dc67563,843b2f3a,f793116c,23db0dd0,dad0975c,5abbf569,4c6d454c,9f7a9ff4,ddf65b9e,4db83b7f,43d0ccf8,49a8088,4894b277,4fb39fbf,78076a60,356753ae) +,S(657912bd,1edd014d,1386c449,50cd1667,9c3e415d,b36e36b1,3bb5c82c,a2f897d6,4e2fdfdb,11bbe240,8fc7fb3a,acd06c69,78205e48,c9f5a143,4300927e,fed505cf) +,S(5a453b3,5f82585c,f64473e5,f3fe937,6f412b5f,c4ade7b8,f9081717,3fd69f99,fc169e11,3448b590,4e1dbf06,f4aba1a3,ec2fb4b5,7f2b4c4f,a29b6617,58097ebe) +,S(c3adf45a,c24b4bc8,69acfaf1,f96a3043,d01c68b2,f4ff689,93b37b3,a4052679,3d923207,cd374b49,d3a85bea,972b8d09,4f0d4b83,cedc97d7,edc2ac68,10ae19cc) +,S(1a32edc8,905ddc84,2756420b,e1f25daf,5bd84f0f,acb046b6,e9040fe9,5e1e1d56,7f467d9d,113a77f8,c1cb73ad,16a62f4f,f1612c80,f8cf859c,ca42164,68eb4c51) +,S(70957d98,62e5977a,c328b7da,2e51024a,f925c142,eb1a46b7,b4a3bf20,a74d6c98,269b56c6,2e42cc34,a0951348,881d2c53,7d7ee231,f2327ec1,441fd273,bef09381) +,S(7e69416,5a02b16c,107ae454,b6cdf25,bf6dd256,d976ab44,bd7edc84,837537a7,ffb874db,38360c11,e2d0d2ce,3e47363,a6aac21d,78a37b24,3e66826b,445185f5) +,S(4f81a159,7b42e9b5,24be7ac6,ff4405d8,3b9d8a75,e37b58b6,eed5525,6ddf9678,b2531207,18676065,ad8ffbe1,6d27df4c,3558eed7,992538b3,77cb8497,86e0a78c) +,S(fa250368,577065af,b60be8d,e9381334,9be6fdd6,1bdd02d9,3591a35d,294fd547,f0b991e3,96c77cbf,5d642f0d,cf5ee10b,3b0a1fa7,7b696f06,d4d61cd4,48e81625) +,S(f4df5ebd,67162bfc,3e3da517,23fec6d8,6b61d6c4,a5876c4d,440f025a,272ba3d4,b23ba279,8bc75fb2,d590e384,c9e375ce,6380dc5b,90970d44,674e32a1,8052212b) +,S(ab5b6b1d,b3725b65,fae28e5c,44460d6c,51b8971a,655541c,4a587076,a1ac5015,16d2c457,ecdc1718,3a9d7876,d785adf0,424f72b8,d08b6a9e,286ea5cb,26ee2ece) +,S(a8a4ec7e,13db5370,40680dcc,470d38a4,2e08d99,3c30f981,ac877ce0,28869e55,4a9ded9c,2cdfee53,897d0874,965878a4,754025d5,babb07bb,2d248151,cb7f60a4) +,S(337f54f6,33bd60db,583d08,165c1011,6f914dd9,e2abcfaa,5f1b1410,b8245f48,9453eb28,696afc4a,40b5452b,d3abae4c,679b58e5,408b0a94,ea456771,8176dbfc) +,S(eee337ab,dc2baaf1,544c767,41a5054c,f6db480d,529d20e4,33b642b5,fd901b53,65ad5b88,2cc00d4,a4ba1d8b,a6956f88,825616cd,5f6c9830,87264247,869c27be) +,S(59f52e18,57cb000a,ec1aaf0c,b43f1274,f56e477c,50f010b8,4513fcef,752f1548,d8ca8f6e,8db03b19,8047006b,a6ec1e29,4f225461,9978ce70,a1ae0f53,9e1698be) +,S(6c200a0c,25fadb2a,8a9618d9,d7d86287,8583ab10,f2b4915e,8f5a5f05,406f3e12,14d4984e,374cf35c,145af24d,a5c0d0f8,504649d,b1793a61,7d6ed949,ef8081f8) +,S(1654a2fd,51dfb6f8,71aad878,239b657a,f8144ff8,98a3c2a0,32cffbc3,8aac07fa,8b6965c3,82d98569,b6cdcc1d,4c71705c,e36d46c5,fa5df714,8d59043d,161a839c) +,S(c48033c9,ab473556,c9982f33,953f96d6,7b3ed1c0,7e98efae,8de232f7,67556d77,af3f48a8,7bc43168,10787382,8dcffaad,abe4a54,828b02b6,f897ab4b,ed968bac) +,S(5dd977fa,a9d228d5,1885aaea,557f7a98,1a95771f,212c3ba,f1a4e428,3c3c6032,3bff9d4a,ba178f6c,d2ce5204,3daa06f2,abb06acd,274beb45,49e72a37,8f2eb656) +,S(2a76dc25,dd9a96c4,bcff1d8a,f3c9aaeb,261e4c69,a5d832ab,efefdf29,ce42a564,493452f2,3ad5cae7,de8c972a,af5c3883,7ff82aa,df616c5b,2fcab4c6,d5244806) +,S(cdbd3506,4c0e7923,822bab4d,b4662b2a,fd3935a9,a49e6d6f,f2db8f4b,d29a4b8d,b2126f2e,b61e274f,a688a84c,386fdb5f,58b84515,1543f143,a8ce0a3c,557a90ce) +,S(983f249b,2cb9d4f6,34d82d6c,e713aff9,2bcfd525,a4146a75,bf6f725d,2b54d978,79cd2406,850be02d,a6c4d25f,5a02dabe,af302e77,238833ef,cff0484,8a8abca2) +,S(88c765b4,a5a0a9f3,a257e21e,ffb23e51,9e128489,fade1383,96fdc18c,38afd4f4,f4d5fe64,729995a3,e505cc03,1d144682,e3336ae3,45c28697,1cf89b7d,595f46c2) +,S(197505ec,d603cb0a,199c7d08,b88d0e63,1d147d07,45603692,6b67a582,b7d52c31,947ec13b,f2d75fc5,af5a746,15a75aec,2f212adf,a234e08f,49a561e4,f9057f15) +,S(98184232,e10f605f,58a700c3,d6bc04d,9a19790f,eb638fec,668320b6,3b2eaaf8,ef3076ed,c0e2fa39,30ea837e,36c31f59,dbbdf192,ab18bd7f,39578e1c,eff9c85b) +,S(50f0db35,cba0134b,790f47a9,e322670e,f0c7d081,6869a764,892f8e23,6c0bc002,1c1b1c13,d98a84ea,e77260f6,58e265d8,9e466b44,b8604edd,83233fcb,68396072) +,S(d9e340ea,1a44bb50,ae4bb19f,3f4228f4,99ac8516,cd6bfa86,80c1dc31,d5665502,128a1688,335a2193,ff805251,b83baee9,341445ad,25048f75,355f4b35,5b4aaad8) +,S(15aa8133,1b84ddd,8c706702,555dc19,d42cb4a9,a9474c9,1e33c0f8,e87c539c,79530720,96586400,ebdd2ba1,7762ccbb,2a14bf47,45f63b1d,e22c6a6d,8942dbc1) +,S(6f708704,53d19a4d,b910d169,c7c7be23,d489dd18,23604242,55e182f8,7a5d34d2,e0531956,7c1c2bf4,a0a9beab,d7c4dbb9,c15246fd,5a6de101,35578aa9,99c7dde2) +,S(31e920df,cddca3a4,89ad97e9,168854f7,867f9a58,fe2d3f1b,f33f8dc3,c7167674,52712c3d,b0c6e58,15157660,ebe27dd,244a9c5f,b12cb8af,dbe82900,c3706f39) +,S(93300e11,708ff01d,96f81fbc,f1888c96,8258dec2,86a315ab,8d01f2da,4c8d51d8,15368647,3b6a208c,8449b53,66584e4c,9e0b7636,1256df46,4c93d4a0,e26c33ff) +,S(8f7ad50b,f62d6702,616cfdf,3712c1ca,30c94632,720797dc,ecd54f65,cfacb3db,5ac10a32,7dc52bc,33290080,a1a194c8,1eff0d71,65f9d34,7e4f8b44,8443c637) +,S(6ed80b82,76270d71,c468f5d7,350c608a,7f5cf51d,c8efbdd7,4458a487,2989f4a9,bcba2bf7,38f6e77b,465e47b7,c687c7e1,77fd3cf2,163b5a2,e00923d0,89826dc0) +,S(ec6c1d7d,b94989e2,962cb85f,777eada2,7c2b11b2,86949e38,eea2bb4b,7ce3714c,add9f9af,6042dfdb,1d4089d0,ebca5755,8ef2664d,52fce516,df3b030e,9ed08fdd) +,S(8f77cb2c,24dcc192,593a82d3,510859b9,c59bca8e,9546735c,1fe26084,4a37f093,51674986,fbf499fa,70b55bd4,f0a70cb8,423fdebd,587e6213,83199b3c,4fe07202) +,S(e2addf74,dae831af,aa4c4ed6,2f4a32dd,1122f2d6,243d049f,1fd78c1d,64b6aca,7dbcb394,1eadfb0b,8a56022,4da66128,a73a1aa0,20a5b23c,cf58118f,e28b2297) +,S(bf7af1bc,614d31c9,9afb7c6d,b8cd45b3,3a22b151,34ba872d,3e845da3,2b1e3eb,108d39e7,8cf88a22,fba9e255,23267bd5,2b850464,f1277239,7542ec2c,50125a21) +,S(88ffc7f,cec6580,5b92c5f6,952d82cc,35b4f068,a7581987,93ebc59,8efe50e4,382dacca,94b42c3e,ba1558c7,82394564,d39193c9,8b9e8cf4,a63dc4da,4d378a4c) +,S(b114a384,ef4ae60,b9c569ae,636eab27,9070e207,34cf83b7,a28353d4,7d3a152b,37c7673c,e58ee20a,6076438c,9bbe5cbf,bb826076,6d8a7001,b188c477,cca3fa70) +,S(e411a42f,e20d23b6,fa768fa1,e310192c,cfb0cd2b,1914c9da,627db3a8,c7e801b0,feb1b79b,43ee7980,7252bbc1,728af29a,8f6828ae,8aec480b,91c85008,959b1039) +,S(191f687e,46432313,c085182a,ede5e7c4,31057ad7,f1f48fd7,cb814fcd,74ee1999,5464b42b,3f77ce2d,59a39efb,83808cd8,43e5c540,3d5081e6,e4f4b1e,926dbc72) +,S(63ff4977,33b0a49e,f618c4ff,1aef537,9837744c,85a19bf0,b2208eb9,506bcd81,6ccaef97,ca835931,f3a87b50,a93f2a4,39535d8c,87e26090,3ae49b29,30593d3b) +,S(efe36425,c37705ba,69e7056c,2e8c628,f4ce72a4,68d85556,4c57e5ad,b7fc2c1c,392b9b5f,27ac49c5,831a5f52,c2e55bb2,8faa7f12,521732d0,8dd910c0,51970ad5) +,S(6d2126b,dd7cc08d,1bd41910,21704a1e,841d4737,4e5a0a99,9880051d,f77e94a5,2e9b823a,cda1be97,52f72ce6,ead42127,efb4d4b0,8daf55f5,5da6f956,84e6e806) +,S(cf7b9ff4,297d9c5b,91c6340d,c1cca93c,6d453ac9,86b4ef54,b20df6a5,4933743,8a57808a,2c07002b,111efec2,bf751b54,c20613c4,1e3612ca,83baa3f,eb670c15) +,S(b160242b,4cbe5ee1,d1dba4e8,e2d55a0,27f5a5bf,f7c023f2,c1524fe6,5f7e83e,ac35795,6cf31260,7ee9f54,fb39d3e,4f1faaf4,67d09567,6075b8c6,3c0fb5a0) +,S(7a86452c,4f8918d9,86d3dce0,22619a72,1744d9c6,dfd0e733,c02cdaa5,6abb050e,30d30b1c,b558b0e0,fbaa1fb3,596cf454,542370fa,43d8a85a,91eb6bc5,c90de179) +,S(a279bc1a,64d206ef,ea96d3a,b97c6770,af41ba40,9381d372,408052ff,582323b9,aefc853d,701ebc44,679a7ab1,fe033182,e96199d3,4b58261d,a1b4a6bc,6ce42046) +,S(e8e28570,5c16016b,608c301a,ac59f868,f7691886,261eb01a,d4e6ec6,a9e5cc76,92350315,f8e78051,b703b7a,49427272,c988ea66,27699eb8,f2fb3eac,9f0a983d) +,S(1fd9cef8,14f3fc81,8055f300,a734f9cc,46da1585,b939be73,459e0ce1,8a9f2bbd,dcc4f73f,a50fcc8e,6ec3c71b,c045f020,c26d79a9,794a25cd,26488c0d,9cabb55e) +,S(321b1afc,70275fd6,fd48942,df364f6f,c609d4b6,cf4e574d,39f1ad06,927e5f11,1368ecef,808bb311,ae9ad36f,8a4c81fb,725a80f8,ed029680,c5b54463,80add33d) +,S(4dff29fb,6518e393,dad0cad9,b0dec257,f9ef1e9c,c50cd741,8108c42e,f6d7bf72,4159786e,5aa4e82,4d7bfd06,713ec8f6,d92f8f8b,48304efd,e4d0f4c2,30dfb70c) +,S(937a84a5,eb63055c,65b162e1,1a3f2e54,c839b972,95a8c1b9,274373f7,5ced1e0b,a03078bb,bf11a351,da7fb3b5,2e3e7a2d,62c122b1,a9cf9954,53294f37,7966afc6) +,S(be3faa9b,7cab73b8,4fb2a87d,25db7fc5,56f07393,b3177c7a,56df0447,e96cc3d2,e7051ee0,1ad794af,571dacc4,4e91f7f6,9276446a,7e348ee1,2998968,afaf77f) +,S(58b39c6b,cc36d506,765d24da,6058d7dd,36928d13,b0fbe1f8,c680df15,756c9b41,449e9691,aaa846d9,a7412b77,73f7ae6f,b4ecd99e,c57863d,ad72d3f0,423d74ff) +,S(9b18a971,b1660b46,720e2100,865742c,8c91282b,1c72c7b2,8192bdc9,c3765798,2812e522,98adf83d,2cc07a93,4a065016,2be28d37,59cfd50,6c792e31,32e0f49f) +,S(a6c44c03,dbacd4bd,7a35e207,61778826,c86740c5,c92942d7,f73a1b3e,dec0f59e,73316b7c,d1fa3410,76b73727,8aaf39c6,2258d29e,c40c80e0,797493cc,7056077f) +,S(1ffb2755,628ff8d5,d837495b,94ad78a0,5dde2043,bbfa3aaa,21a05a3a,21682ee3,4a0478f7,6b8b6c,ffd9962d,f70e2a83,a71243ad,c690efec,5f95aff8,dbb5943b) +,S(aea4c48e,36051144,482538a8,8ee5f72,b67a21e7,8fb425c,3d6f1e78,419b8283,4517cab8,c28eb397,bd89d216,ce711332,82c7b530,6b64499b,2216bba9,41a80b27) +,S(ddc59bfa,5f8c0270,8436fabb,5003ca6f,b972f14,382bf127,f5297990,b4ed3eb,f6c3f19f,b80e75b6,53c370b6,742045e9,ad7dbc80,3a996696,99605345,ebd995c1) +,S(22184fe7,ed301b2d,62bf83ed,64742f6f,94d204c9,866a637d,d03c58b,54c80a8,9db27528,1073a3d5,617a389d,c5698255,3bc55d6a,3b80cab4,ace36140,8179b442) +,S(e58617f4,74e46f4a,74b0ed2d,6bafc3cb,6488c510,87136eea,f98aa37a,f201cef3,cc6a7375,52dde05e,71bf2047,d49a41b0,c6b141e2,e4f519d4,36d4f8e4,f2aa2220) +,S(c1aa4092,5addc5fe,de6c2c5a,ba73b3f2,b7394a0f,1d02846c,5b2a0379,824f8e41,9713af07,e30af560,9516ce73,5083ab53,2475bf26,5713570,28b586c1,d28c687b) +,S(4aa5d88d,89576459,1ccd1c2,3064c718,69e4d320,b0b71b5a,c08d291a,c1df6168,1d0ea41b,915c288e,c6b36cc3,f7806481,c048482,dce586ad,f240d32a,c913e6e6) +,S(93876d91,73137834,dca5e192,fa869a02,738d4171,391df1e7,43296f93,a2a8a977,7948463d,32bad450,24e63d9d,d5786a69,73fc6c8f,9d2a7c3d,e2d6fbad,7a6457a4) +,S(c80cd7d,30268025,b233dd13,f2f2af37,5d18080a,54c406ee,50e4890f,a91b7b28,9f73b58b,1f1d11f9,1648f904,ac7ad275,9e6260c9,27870292,278fe521,b718bc4b) +,S(d2bd24d9,7dd4a345,a8c4e857,97a9c30c,e8e7e7c4,3ce79bb8,fba4250e,a0c8c5cb,330f0cb8,15cb1931,90331055,809eb028,55ae895,ee1a30f7,665166b9,6494b9e) +,S(d4e4a3a2,90deea18,fb15457d,f3ab9815,5d722589,515a38b8,dc303307,5dd7e9f4,4854493e,77d0ecb1,742bdc9b,a5219e9a,71c57a6c,b914b8a5,6eec21dd,3e7d1c21) +,S(f0fb6cf4,810de399,fcd1b246,f0e76e2b,d318f82e,1601ebea,2779be6d,47236d19,e3ad5160,66480239,88b0b197,3eb2a41e,2cc9b4d3,7cf58d07,ad0edde7,ac595daf) +,S(dd4ec58e,3f4c470c,36991740,d02b0fc7,9a4f9df1,98647ab0,ebf73b10,34858939,3a6ecc86,a3b058ce,f278c839,541e92dc,737a6390,94ffa464,17e37da0,40a3bfe3) +,S(ec56910,1d7ed954,d4efe1b6,c4f6ade1,2af12f3a,ddc75a8b,8fdaebb7,ab904e51,3497c67f,5d594f71,4327111a,e22f2621,be7cbaad,b2cc1d6d,be0b7e50,d450c54a) +,S(ca45def8,51856a5,7ca5e1aa,64edc3cb,e25ef6b0,e28abda5,a85d9a19,dbaa35c5,db8b2357,268db9eb,e013fcde,111372c2,6eb4ed69,5a7a3df0,4d1d33db,703521b2) +,S(b44c5388,964521e2,4803c8b6,3dc8a494,40f8ba15,435ce2e6,5f6dc092,15b49a47,2e16435d,f30c4b80,cf125e04,b85166b9,509890a9,c1daf1f5,72462a83,de198d00) +,S(95b735e2,35862f14,e9291a5,4b46d977,33a20ce1,b59b4603,666cfeca,e05dea26,e1281705,5f38be19,9bc9977,b6e80c08,f22ab5b1,286ea553,21145675,264aabb9) +,S(83d9d867,8fbb0263,6ce8d231,3ee4716c,a15c71b2,66c1a7ce,e56928ed,73e5bdfc,e0494c2f,be92f132,effe7d78,499f4a00,c35027c2,37df8545,9918687b,6b949246) +,S(98b7c85,a04c546d,bbf6bad1,6914e247,1d3b478c,f30dd6f0,2e843770,49bbae03,769c3b95,3733dfd9,d9027da4,a10b0a65,ce4106f9,44364972,e569c63d,3b2ace57) +,S(3ce7b677,852d34ec,34358a8f,4da66d53,75019cb1,19a45dfe,864062a,a3b12e45,68d2790f,1838b86,96272c4b,d5e418a9,2cf03d9,de44f218,e42562dd,467e409a) +,S(a0bc28f4,d4da7101,41d0dca7,51542b83,6b50bdc8,997b291,e074727e,cad7836f,6ed7e149,40f2781c,d685a581,99f163d2,177eecbc,ca785224,2a8b4859,97e47c88) +,S(9a571ba3,52b1d62b,4e5d290a,c0d41983,97750fc4,9a18cb68,18fe11ab,1e185c0b,1a91cccd,b2b1f58f,9cfc0dfe,d3464917,f6c2870,9bdd8128,ff61e295,ad1b4ad1) +,S(fba0544f,cdd2de73,d24eca5,55a8c4b0,4e135c1d,8348cb93,d53f647e,2a21b9bf,7a11a425,a4ec6acf,2eafe631,ff83be6a,f71a6cc9,f7dbe3f7,aed57e04,2774568a) +,S(d96b253a,1edbf662,3902bdd7,1c3bad9,ecad1115,45614b48,5f7abca1,d4920a9b,2bc88998,f951b831,2f27d09f,2f331536,1499f1c8,b172f1f2,408d0660,3b18c2e8) +,S(2b3c17ce,1081b825,94ae14da,f9723f9,9823382e,947c1356,13a4b8a6,42267c2b,a4cd589f,2ebd245b,88c7f1fa,427a2ab6,e77205c2,dbbcc74f,dbbdfa69,336048ff) +,S(69698780,fdac522c,69313ea7,2e244d9d,3f6bc5c9,4fd86125,2eb56369,c96439f9,e8eeb3c6,460f475f,c06b5943,9bb9994d,8d6e4314,fe20020e,c1001f77,25a03154) +,S(1e344611,4cb4dc4c,963e172c,9bfc2f4a,d1577efc,ae2ffc6d,76395ef9,a0848c68,debbb8df,e6f59a0e,b96d464,3bbc6d51,a2bb4621,6059de1d,a473436c,404f5b19) +,S(6ccfae02,4c7f2a9a,ba12c191,bd35e287,d5c30284,c4273a1f,c558ae8d,286aa61a,c2014174,c78a2fd,d342ade2,51e4588d,94c4cdf1,ee83ade8,54e48388,b6e7cb11) +,S(5b5fd487,69b6a133,35bf0a2e,61a2128a,db43153f,9497c77e,c32b16e2,ca4c728e,9954353f,b23c9d44,eadf2632,168711b5,5a54c9da,53c41088,50fe77cd,8cf00c77) +,S(6b74a257,27af44dd,61fbbbd2,7323b63f,e6a41d9d,f5412215,65a6a9bc,35d069e,a4e1214,f17b8dff,b5bd689c,5f004c98,39b87a46,15245756,48099d33,f432a34c) +,S(5171a187,8ae9ed01,837408b9,fe08f317,8688606c,aae04b2,63cbf143,b8e372a2,b5e7de6b,964153cc,fe64a472,8a8f20a4,44da8e15,c593b7e8,68140276,b172d06) +,S(df9e86a,4337ef32,3518568c,e52958ab,dbce8a92,840b756c,279e96cd,43c8e80d,5442baee,c72f460a,110e8ff6,1e938132,50b2ccdf,61941df,5f591bb4,73027da7) +,S(ce070279,eb6f1f71,af876ab7,3903fbd0,ac9e4693,7b6d3307,2ec80182,3887c850,de83ddf9,88f9d345,e1ff2a79,e91f8ad9,6ea23097,538dde84,aea0ded4,b6a155eb) +,S(a0255c62,44afc84c,58238936,c9d08d36,96e5789b,ed28c40,7667f348,4c2f35fd,93e2d407,aef898d7,c898293,fb20f222,6cd5017,cd62669f,17ee0d16,773c6f7a) +,S(ae82dead,b76d5dd7,140e1197,a383ff62,138e1840,dc2f7ef0,d5126dca,86f0d86b,239dbbac,caaa0779,a9f6d8ec,2e30b590,72d36b58,199a27c6,5f5815ca,5720964a) +,S(cf0999ce,bee65e2e,d596441e,a8942461,97c597ac,9c090884,44c375d9,16332393,6620cbd2,f074edd5,1ff8cd5,45adcdbd,1c664ad2,6935880,8655ffb3,3a748ca4) +,S(5fb4af74,6404b01b,63bff1b4,1bacbb36,9ec06801,9454622a,76258033,9cd3965c,464cb2e1,2cce697c,d409529f,a48e7448,916a51b4,5954fe93,d99ce392,272abff5) +,S(15af3c0a,46b5232e,55e5687,a2bc4acc,2c7a350f,8114e3a0,1993a0f3,1b3216b4,ae03739b,bdce38b0,4735acd9,3a3ff7ba,86c8189e,56a5bb37,ad83a574,cdd45a83) +,S(5d0035d1,d008ccc5,42cb8b5d,32d973da,32c88787,640d0465,76d33e36,540b4b10,448ed8e5,bffa9f28,6689061f,73a74f17,76db8a8c,d5b4af39,6173e7be,6e54c465) +,S(944c70f3,9cf749df,edb9d322,ffc69e3a,a40b0704,fc4af915,e027bad4,83c95527,b0ac0c3b,bf489332,64a6e95c,e49a669a,df10acfd,48e22fc2,1a18ecbd,b86c6f0c) +,S(fa5219f0,82ec3c4a,3f246754,dad62f04,52e26225,6cd28acc,846bc5d6,151e4402,32ce81e9,d6403132,d7b64f26,a0289031,eb730d2b,dcd0065a,1b4e3f3,a7afae9) +,S(c9f4aa30,ddbee263,509455a,858b8518,85c6a16b,5d9bf032,70443928,38a30ede,5ef717c6,b438af31,9a892799,46b73ba7,add20334,c2fa5bae,a15b7632,34ad7b7c) +,S(2f4cf3ca,7454d569,5b0dd2fd,c72d4ffe,529b362,deeea120,162c178e,7b770319,dcda920e,3566ebcb,f47c1ce0,fb767092,fe7c87c5,ff146042,d5a0ceb7,a2f7d487) +,S(2417f576,2e0cd74a,f07a41a7,51f91b3e,a1cb0a42,2246af4,a0a96b8,79969945,6a96d755,f8dc71bc,adad0a3f,61cb44ed,741ef96d,96baacee,fcfba7ff,1e7807d9) +,S(9ab22f84,305a1c1f,675ca5ba,cbb3dba4,d43d060a,ee9148c6,6cfb61b8,5888852c,af0506fa,a2588e3a,7aeac12a,7acdda3b,b51d996b,2cca9c18,e23b517a,a428a03e) +,S(f7421ea2,24627926,28ed878,7e154724,77a91726,5a162f52,87501d1d,24a72b6c,db0ae665,e4484132,f372ca6d,8cd46115,fe1c72cc,885804dd,8f508900,5743fcf6) +,S(35756af3,548d57e8,dc0bb791,8b9875b1,10a912bb,7d971e35,4963bd7f,df5c6f75,1ca46dba,78a2b4fd,d4ed69ae,bd4e1961,86d94b8e,20b1660f,c517098d,e077a1d2) +,S(a7e9f00c,494cfaf2,16449d9a,b0dae7ff,de4041c2,fe031bc0,241c44db,1bf01837,f2aeb9ae,480b406a,9753d009,3b5fbb74,5a7760de,4ef508b7,d10804c0,161a0280) +,S(69451dba,92872879,7737755b,7655ce70,64838aa2,9084fc1a,c88f5e6f,ca62adb7,26218fa8,d40df091,31d845d4,96c7b950,1071537b,51a3143c,c73f1a7,b02b1cd9) +,S(c49c3b30,15cca66f,ce986a37,588205fc,89a92d0f,c520ad3,5eb6cce3,daabf06d,7afde84a,665b02b0,e0cf9ca9,9d2ad097,6242919c,53e31b5e,6216d67c,580e354c) +,S(e9e181bf,b68e6e38,c5b6ee1d,f11c14f8,90c0c744,8570387,1ab6b624,6b9dae8f,b0bcfedb,3f394317,907e260,c3651aa4,d1af5ca5,e1a34018,fc6c26a2,d5ef5e1b) +,S(a428586f,adf41cf,5b5c9e52,e0d6e1f9,2e7d8738,ab99e8bc,4062e302,de392324,77c3e18b,fe71c937,65b911e8,b49cdee9,a2a7413f,4de831c8,3f967f08,95b8d142) +,S(f5c92ed2,de1d1a25,4b4a4830,b656a674,38077be7,5efed94d,785dd0d9,72712cf,7ee98d3a,497849cd,5b5f6dcb,c51c5119,228fdf7e,1a67f1e,d7c670b9,eb3958fb) +,S(a85707ca,6c85f506,311b6930,767b5571,e18c19c7,ff2574bd,f268f018,b49c3f66,1785fe71,cde2e189,aaf67d10,337b8fb8,53654335,4d5ba73d,77518d9f,5e8aa050) +,S(8866f5f,a4c8d1c2,f2de0cf8,19eca5c4,d084ab60,67a7d97c,f9942fe,c0a7468d,3014226c,3f33907a,2f6c49ad,c762be6e,2915288b,a7ec009a,fe693048,3588336e) +,S(425f6d73,37eb2d68,e17d07c8,bda406cf,92af22b5,6461bd66,f40be14c,ae0688cc,e865526f,7c42e391,1ab73290,e80bd9fc,9643659,5871bdbd,ef8d698f,d04d4980) +,S(f70fc3e,1de3b3fd,55418441,43deb4be,36bfe6af,3bc9d9a2,f8ac823d,68323139,8b47994b,1febb309,e3774a82,d6b18d78,8ae5750b,40aa944a,dae404b5,da24ce03) +,S(1be960f3,38d2a16,703b10c,eafa121c,d59c66d9,439e9067,58a0b363,2a83116c,7fa4ca2f,8218ee04,351549cc,3b0100fb,647e0db,19eea010,62f1c0de,3de29aef) +,S(1f2a2d3,bc5c80a3,8af51e9f,5694a80e,e915eb89,4831ea7e,48472d53,320cf385,a18cea39,174b4c49,f9bcb945,5e6701f9,47053f07,6782ce9f,f55653be,6d3940e5) +,S(61d6b60,70846b0b,b7790861,17cafaa9,9aa67c37,fe77140e,88477f3e,44d04766,c7f4be90,86849ae1,632eb59a,6c96de66,b7c4b1ea,caf724d2,5338c11c,a8f2688f) +,S(2b37093,2d9a6451,79508daf,4be7f26,6d540538,9276fc4f,e6ccf0d4,1ee6cc9c,c002a3f4,2c8998b1,ee16a1d8,616ce0b7,91cdfc44,61839d9f,5ca0090e,295beca7) +,S(48f5c3ef,aba8b7a3,4d7fd136,fe9b01f,64af0e95,6a27663a,87cd6629,f2708858,8cc38cb7,fce46724,7c2f09cc,52f973be,90aefdbf,b52895e2,b88f03e8,fe32b5ab) +,S(e609b597,2e5ec227,6f5cfc87,67b6d534,adfbe9e9,9e60b86,e981dd9b,3e62cfa0,6be9c1ee,ff205fd3,e3b85e3d,bbf1b27a,335ca616,9ae189f,a433e65,f2b43081) +,S(ebe40b1a,5b2c9cc8,46eb8ea8,1ef0c1ce,f19a767b,2da6ab0b,2ab66a01,b16d205a,2f7710e8,e4fecbd1,39899bd,1964f5da,967d6920,d70b2f4,45d6f914,97c67058) +,S(97cd4c39,9391b1ef,653d32f3,9b062bcf,dbc72d45,83d81b3f,f70df659,358e3abd,a05a6184,a175b6de,f9bc35c5,6e9f5cae,263acf2b,a233bfe8,13dd98a7,fbf37968) +,S(826928aa,1d3fd0e8,53cd99fc,e6559ae7,257343aa,378100e,bf64a3c1,bea7e6d9,bc4a2db1,a3bde90a,ff50fddf,cf6f844a,faad7f8a,89bb399b,20b07b2,2e1efc79) +,S(3e754097,f3ac95dd,176e9181,410bae7a,83bd1431,6772e398,967ed39a,5fa19121,746cce99,c6a2cff8,a0907ea1,5cf9436c,ca7f94,7f3f1801,135fe675,a518df32) +,S(ce539464,b49b9947,808a236c,8a027066,82991f46,3bb828fa,44653266,329365db,3578fec2,b8bc4763,61f2fda,29c2c38b,a7bda79c,11b2cd41,a74d4c02,762e5dd9) +,S(c933d9d9,cda615ad,7ac41d6a,e64a77cb,44a2b669,21533669,2c90c3af,53e349dd,4a6da24f,83baebbb,8f2a8ede,298babce,a25b054a,a1c4cc11,f9f0b0db,572c610) +,S(459aa43b,1aa9815f,e9116f2e,78ddddef,a78e2def,28027d51,d081a3bc,800b2ac4,1acedbc3,de995e30,b16900d4,cddcd1f2,5c615156,fc29645,4bd5fc7c,63e993d5) +,S(5f2aa5d9,9862ad29,eb467564,639abfc,ff445334,9a30c4d4,3b27f913,1e3b0a5e,571eca2b,e61d0bf2,d9def9ba,445b39b2,5acfbbb7,dd4e2cfb,ce7541c9,61ace144) +,S(ec66ea1d,e6cc5d59,8c393e68,1a338549,fc2c3d7f,947b40f5,75681e60,88f4fd1d,d711ffdb,3b378435,5894dfa9,d0a5497a,5540739f,a3706597,8ab7dbea,a9280f52) +,S(6ac53df5,aa097f2d,9983f018,bd1cab39,69ad0638,c78547ab,1a481682,ad6105fe,95f69a81,5127b919,9488f224,24307969,3cd51796,bba08578,abfc8e05,6618a598) +,S(a8a3e9e2,9e4ad0fd,c466dcb8,fdc02cf4,16fb5c85,b3454fd,3842f129,9f96c0b0,df86eb3e,3006dea5,ed6d152,f394d7c3,169b8d09,bde3685,ce138a55,6716dc2b) +,S(50a764d2,a0d8741b,95ec84a2,feda6df8,1dbe987c,31861166,32c40c3d,e6db251c,b28203f0,233917c1,4b67632a,ce9b512d,76a8c7e2,430a4a40,85cfb422,7fe41055) +,S(c2c314b1,5ef9df1d,26856c9f,a6e39cf9,1bd9c584,582893a9,423746ca,1ab51ef9,a27f9286,ff7fdfaa,b949a9f5,d59f08b7,a22f1e31,e7175d44,93e219a4,e92ab759) +,S(ba655585,da44c8d1,2b3ce375,e220a4c3,64868b75,370fdb75,dbf6bb92,76a9d3df,3d64e16b,a03a385b,def18f61,432cc49c,bdd9d04e,6fc8873b,e51663bb,ca4fda50) +,S(3d45fa49,d4d100a4,b5a76a65,1a5100e,56bd0d13,b9e141c2,aca5cfef,a46e600e,92953c,38eeee42,e1da93b1,3c75ba48,da30390e,731801ec,ed5bdc2b,58059176) +,S(e464c346,e40dc3e2,40e5d96e,1fb2c10c,83e5ab7f,45138596,4ca46b04,bc8c3a8c,63f14b46,182950bd,282205aa,374cd67b,ca364a4,f57cf90f,c7ac90d6,5204cf4e) +,S(14a7e12f,e235b307,5b0d218,bd3dc720,d56f3fe4,c73841e3,fdf42dd5,aea42688,d79683cc,40cef482,ed6a22d4,8137a4f0,eac31249,9ae13809,9eebf3a3,15e9ff2a) +,S(8e7afbb8,21af73b2,25b34ffa,bb2ff6f4,61d2ee2b,85d5d936,a99fb078,963828be,40e4776,5aa0768c,f055bea0,e20e1062,bb528470,dee61ec1,6cc9ce7d,ae6b1853) +,S(9d641162,3227bd0f,4bcf9f1f,9e5ce829,7d844055,8a7ec246,5b160690,53297573,ed0d83a0,68001be5,70067ea4,70fec09e,1f8630d5,da5d1b2c,126c35c3,9b07fc8d) +,S(6758c6d6,d9e49d9f,4125b52b,e3da74e7,52bb40f1,44af0f0b,7bd80589,7fc83eaf,749ae08e,c2aa2c36,3a229b3d,e9577dbc,5f7d22cc,d46826e3,6a1cb434,184fd292) +,S(b3e11a0,45702d8b,14d93df6,3a4c11f5,32632719,b4a33fb8,da11514,bc61d73a,c6e152b1,2b267ec2,1a23892,8cb97044,9660c6b6,34b22d18,9a86fbd9,a9d562eb) +,S(50a325ea,3b309911,1371b0f,e0b9e276,137bf43c,22108b98,994ed5a0,d66fa5f1,946dad1f,d39e0aa5,8a758527,9b39efea,8a99399c,2750739,dfeae140,3745b70e) +,S(f7c8f249,3befd5a2,cf6802ce,8ac508ee,a97341a6,a46efe39,1214e322,e95e9661,3c072cc4,eec1f370,144b7ec0,598e4d96,573883e7,fa3f3f5d,4e33d88d,1e34cb67) +,S(302d3b50,c1543386,f0b0b94e,9c49ea68,38c7e7bb,86c28cc3,c8965dc8,38f85b6,988047d0,d891aa2f,60b66e5a,96c78c91,3588d128,d4e7f720,5672d25a,88310744) +,S(cb8ee728,2e7e5ba6,d0e8ecb,55ede89a,1d3810fc,b0d8f86a,fbf53b7d,219f0eb7,4b04ea2b,efad1099,8c9a4e3,cf0491c2,bc10bd60,e06a118e,75fe0163,ab8094cd) +,S(645caa2b,4a0cd8aa,20cf6f04,ac73a49d,74f92035,f90bd31b,211572d4,cfd5fd42,793f2996,35f9d7c1,de62b64e,afe516db,b0aa1323,7f51d0a6,b6fc8346,fb7ef5b9) +,S(4d37342f,6148b5e7,5434b8df,6617d64c,f00b1c73,3d85f4f3,e69c4a27,395f5a21,6400092b,d4c5c705,464a7db2,b1b6b667,4eebd7dd,38d05cde,d1577d8a,53a708bd) +,S(e634bf17,24e07b2,b4ac6285,ed28bd39,747a2134,36e76d3d,bd693170,18c0e0d8,cccbcade,4b82a51e,c31d9d8b,6b113876,5e9660fb,e897ca53,20db873,13e9f021) +,S(80a00de6,2767c513,d5bff535,431d259a,64c49006,3bbf992b,a5111005,360cef38,7dceb589,e8d73366,c467e23e,8fdc7e03,b2620df7,9530b6b2,3fcdcdf,628ef572) +,S(606d50e6,d23d50ed,9a5b8409,f11d5c76,baf5b765,f719625d,5b2e2dd,9e8f8a0f,19f55492,45b1b4c2,fcc1d220,6c171200,4cbb41e8,bb7c8cc7,48c4366b,3fb32788) +,S(9c8a0a14,f7d44fb7,4a7ea835,ae4a1932,266c3083,38d66a24,7fdd60ee,e4f0420,42c6c237,31578dd2,31eda621,81aedd29,8737fc7a,3b2be8b4,d0187459,e5d9169a) +,S(d6ccfcf7,81a46f58,ff9a0154,8a417924,1a32d3ca,43a8e59,cebc33db,1e35da1c,a1caba1a,ce846b8d,8b4824e6,1570f832,87cbcfbc,910256d5,68bdf223,861d084f) +,S(8cfaf36a,3e4c3ff2,4556f446,4947c8d0,6eed5ded,a40ec0da,4596bad9,f5f2e3c4,991b6ecc,ede6cdfd,e33f81d1,c1067f22,6b72373b,96ca31fc,c80e0692,d8f3c4d7) +,S(d46c3d81,5b0f3a0b,bcef3973,8c6a6cc7,189849b0,4917fda0,541c08eb,b7e664a0,35524bb6,d053e5d7,c8adc9b6,3a84ed81,58cffe99,4041e642,1fece58a,d967c159) +,S(8ed7f0a5,2f1f8df7,f82dce33,e4637dcf,e2ce9b75,ca02ef04,90c23fec,2b7adfff,f02460c7,b418d10c,96c27225,3dee3b66,4be1aa5d,427759a5,5d90c223,628d99ff) +,S(433ecadc,a8a351bd,52ba4d6c,aeea3ff0,825c46b2,8abd2c2b,cea85f6,6daaa2ca,4d3b71bc,c2d7d177,45cd03c4,86f390e3,f6d396fc,83d0438f,983a142f,162977e5) +,S(c0771ef3,10377f83,7a9bbddd,81f6642b,ba04493b,15c054eb,249b3f9c,bba006e6,3e53ddab,1d816a02,7898c6b4,778d4c48,e1ea2b33,a63955b0,784df258,ef4ccb1e) +,S(dc2e0226,4a6a87b9,53997383,e35c6cd8,92072ba8,a741fd23,8ff3a9c5,f597ad7,898ee746,ecd5f723,440ac0ff,6f597e85,8ddbacc9,cbc80e01,d8a3c1f1,7c12c74d) +,S(16bace34,59ad8cbf,1fc5f781,19cd9e31,d043d7b2,ed839f03,11f0b760,6adab771,f64532,6ec697e3,2ca23979,72b2b834,66e835b1,2bd49243,e896c1df,c02fb1c4) +,S(afb94d8f,3a271439,146539a8,68f00346,9af55eda,839c81a4,725f3a5,7d69c736,afdb294e,a455031d,a70a4eff,7563d764,bdf37fa7,5594c9cb,386e8bd1,a35201d8) +,S(bb31d236,4a98f7f4,1edb0ae7,6018e5ea,ecc33780,5f781dc7,6b15aa9,d0e89b74,1a064c03,1f47cc7e,cd49f032,f4dcd95e,87cbc28a,7b9d9c27,a92a4c1f,da031a9a) +,S(f73b1b6c,4bbf5da8,16604ee3,ef6e83b,241e486e,d727e700,1c3c115,3c4318b8,9a28ad6e,9d64cba,b58ac225,5c01b261,25ba08ef,3b7d5ffb,476f9b8a,6c8c9b17) +,S(63bd212,d0ddc5a0,84f8ea7b,69605b2b,708c8766,f0d3313,b236e921,91afa8a4,ee6f4f6,4824032,afbb0b3,a9fd342d,2fbca8e,ccecdb0f,a3307698,c56c3e67) +,S(6367d22b,36068022,30a416b7,8c689078,967b955d,875fd629,9e007f86,1abc6465,c3ee1f2d,14e6793f,17e444ad,5595f9b3,118d1647,9259e0bb,ec628897,f69417eb) +,S(64e2e543,fbb7f52e,57901e3a,448394c6,c922d0f,b632c4f,2df061a8,9485976e,641a602e,336a68b4,fc447e5a,5863a4e6,89511942,4fce011b,48f937df,fcab2a4c) +,S(2e290afd,18c835c8,d1d79e86,9d9c1322,e16e824a,60e67f38,d6bf3031,e3fee1c6,7f85628e,d2fa6b67,7686b0e,c29a3626,da18ccac,5e373874,96266458,79390f21) +,S(859a208a,c475d3d,f5f22907,988c7774,c0ba2dcc,d80ba42b,17ef1087,2cee401e,a667c645,778e743a,d62ed1e3,cfa12fcf,84b982a5,f1349e31,33627ffa,8b19f5d8) +,S(c9291908,ccc50aae,f19c0b86,829fdc63,b608d3db,d92b0939,b92ac02a,2bcaf21,e5c52bb7,47111f58,c71352c8,b2fc89fb,20cb7d45,77c6231a,17d8d01b,6cd2599) +,S(50359490,42b5b620,78ab0141,1f1a1d4b,64bc42c7,58da4459,b04d41c4,61cefb26,f61e823d,b68c064f,f80d9bd8,f272f817,347c132a,f7bd2af1,e5b451ea,bf4f04e0) +,S(f9bcfae7,d6a3f1fb,612787c3,53b535ec,39f29a01,9f45f43e,7b61f2de,c4a4cbf3,f4d86e6f,273ad7e7,902d5a99,50fc846a,a6565862,aeddc67b,28fc07a1,232ff883) +,S(1c8fe8b,901cf050,e93c0004,b0764715,602ac4e9,7f8d5dba,d7747039,f14a9152,b25ddb34,7c452942,92143b6e,cb19f87f,b42a0f27,f6f74c4c,99d7b80c,7d36769c) +,S(3c50be1,4cbe3a87,d363947c,6eb534e0,8ff676cf,412bc4dd,2c543131,e786f552,4434471c,6e03f600,d8a27775,4466cad0,194f553d,bb653238,8a0ee4a3,9b05a74d) +,S(64cd71b2,555472f8,fa968b4b,4f8c8b24,5b3e91ad,6d9dd409,fe72702e,e70522f5,f1b1cb3a,e9fa4855,2d7fc2a,819bd629,40350a3c,168782af,5bff16d8,89ede304) +,S(c1c00444,c584c346,d1bdded8,7cc40b0e,fd8f69e7,d2ec8bcc,c41e3414,619af7a8,d631b494,3e3febb0,87bb391a,d5810b61,f78dbccc,bc6de38e,ee09005d,3d879436) +,S(fa509582,dad5bb61,c7450fd0,3b7e4ba0,2fbd0c28,af971b96,cbef5956,3fa2a7ed,267c2764,617c2f78,9ab890d7,56be2195,2acdff5b,3490b816,165e2b36,2f3df4e5) +,S(655dcee6,864e926a,a6e05f04,b604c2da,35175e0c,f7d264d0,50920d46,c1a2386c,da2eaeda,bf062cb4,ba2d36c4,67965baa,5f1dc238,b5e22df7,2bbe14f2,cfee19c8) +,S(6ab5e1ac,1b7be624,97c8fbe,fec5c4d4,2cc1de06,d15a1beb,7606fc0a,df3c213e,26f983b2,4eb319c,7443e024,7fecdf58,f833928d,4e809d3c,f36231e4,d0a9e466) +,S(c7da869e,39caa2d,e9f73a0d,3f73ab73,6224e2a5,47ef5af3,5f5a9d51,60c25f3b,e99b1102,49a607d8,12af4cf6,76ae4c4a,cfdc0f89,9ec2175d,c7942b6b,40da579f) +,S(2a6d4ca1,5f1c3ced,ed68091f,af4d149b,e20b6854,bf015084,a9cc0d21,4944ef99,dfc27688,ae9295e9,ab8d9284,6a703ac5,5cb44bf3,13f179b4,ced6b638,e661ae0) +,S(447260b3,bba7224c,aa659f70,b1e7716a,92600a27,18129575,2de62cda,11c846c0,f17e3e0f,33ef2ede,8980c922,613947,8331e2a6,40260996,db8da1e0,dc8999bf) +,S(8cdb1cad,baba7003,8d4b0f44,1b312aed,5a8788a6,6e5356fd,5b994f6f,a7781969,b3a5bd0e,262e673a,ae7be06d,8d56c203,b88750e4,ba06cfa1,7c177edd,74536977) +,S(28be0f50,fb60f905,18323e6c,dcf46c0c,bc3e2c0f,175d8576,85126a85,d5caaefe,5cc058f7,fb188c4c,e1140429,568c3176,8d986fc3,e96409de,21bf9ba3,862b7320) +,S(b6dccba,dd2dfad4,8b69218a,d9cf839e,837e2262,7f8f0eb6,f23484a2,994673a0,e1c14ad7,297f1626,774aa2ab,5dcc730a,49623176,ae81eeaf,b52cfd4c,fa2de992) +,S(e45ebec8,8813f7e5,7a7ecec9,dc5fcda6,b9cbb0f9,19bae1d,be770955,e3766a87,3a62a0bb,4ccf3783,7c384885,7acbaa9f,f915cc7f,13a46856,3ff135eb,dfbb07a) +,S(de926f77,26f39d48,1e0b9e55,22b7c874,59bc9d07,df65f0eb,7b21fea,e8dccdbb,9d190ea9,263d4240,24b618ce,1239f6e1,115be2b1,d721aba0,f5f367f6,304d8e05) +,S(f7621384,20669c04,6d794807,569722b4,91e4272e,1305f091,b54a03f2,ecf2caf0,d0c7e8e5,a227f2a9,5c594528,4590caa3,3088c92b,b4c7cf6d,12d293d0,4b9e4914) +,S(4e795e86,44ffee08,f44d472e,8ba0eb9d,a5cdb1d1,619a437d,4a8bbfe8,565ce751,5292d8e5,478268f9,bb9b4be3,c751e587,65038c55,99cb3549,749e83e2,1590a4e0) +,S(70e64689,a944b03f,32b33a97,c8923531,cdf75e8d,e8577559,bf45d2d2,ddb50b3d,a675c6e5,460b89a4,a2dae263,c71e6edf,925a93bb,a916951a,5364d252,c225586) +,S(21637c2e,682b247e,cb8c1c,8b4bff1f,477ef390,3b9da0fa,b08b5cf2,5b67056b,e357165e,3e761a55,7e4c2b6c,727d8387,c5716b58,e24d0e04,8314979e,4e92d882) +,S(7691a399,8dad2e1,741a4135,18bdbb,d8ae5bb1,7466a949,a40560a3,9c1d1964,225f1404,b05b5bb6,cdbf2296,f76e7f27,257280e,28c68be4,d8c81c47,a422b74) +,S(748316a4,f3950849,9af5a14b,27eabf9,b0d11e91,d8752cb,69899af8,79af9302,cdcdd4d2,6bd709d8,c3d87c12,6dd8a2c4,f600fc1b,9e84461f,1793047b,5bfd7ee2) +,S(af588dab,3839e85c,6dc84aa6,c1e05294,a9708951,8006b390,c2ffe0ef,f6ed9b8a,a3d37640,1b06548f,2794131f,5e002aad,616ca135,8cf0c81d,87015416,37d9cff0) +,S(bd91dc60,31706ffb,19b61796,995728b0,5f869d07,6f0b6537,35c46e10,d9b42dc6,3c963ed1,5a74f5c6,1a28db8e,de070870,cdce2cf7,d6525a6d,16171076,44f153b2) +,S(e625c4a5,91460bbf,5c3aa583,c4cb1e1f,c202c82,7debb82d,985732ed,ede98f47,d026c5f9,a9035396,1de50534,8e4ac600,812a461,c913299d,7fddccc1,5970b72e) +,S(6bd227fe,d4b193af,8b94553c,718357e4,122cd057,d95980e8,ebc8fe5c,7fdaac1c,5f3fe540,a98b044,9ed835d3,b0a2b4e7,c66a0549,e4b7b9f0,22fd5249,c621a9f9) +,S(27707a25,895e6f38,523d3872,c5b34e7c,68a0f0f9,54c6ef49,5cff6664,1edb2609,ef6f4f8e,c893d697,69f34b38,f7f677e9,e5de5c91,48cdf35e,3a18022,3ea777ee) +,S(6052248e,3359414e,bb7770ea,4284d7c,c01770c0,e75466db,1f314e0f,cff0ebde,3d982058,5cf0d546,9fa62e02,aa556fb,1a1ac7d3,1cb9712c,8b118e2a,e3f7b7a2) +,S(f2cb5b53,4fa6124c,16d82506,8b229857,4d4fc666,9b45550e,6c75a114,f370f6bc,5cde5707,63a5cad2,13952def,43cc779f,8ec9dcbb,c5fac8a0,ad7a740b,7241112e) +,S(77ad8215,9fe6b9f9,e08030c7,a75c601f,4989b51,4ef6db20,aa9d0b23,e87a502e,9268a1ee,ffc24932,74856add,2ba1ebb3,c13678,99af932a,87fc680d,ea9b703d) +,S(4418748d,171cf80f,a7f80fd7,c2d7891b,5cc9aa0f,ba4ec1c8,a114cbc9,4a8fd29d,5130285,79f01b7f,72f18322,b279fe7a,9916c16a,a67c6aee,babbb418,fb1835c1) +,S(16af4960,6f89c87b,7e5901b4,d11a826d,126e59ff,df7d0883,1d37d7e6,367355e0,1a138440,537223c9,e8e131ca,8ea3b38c,12c8e8ea,50ee09f6,8ca4c2cd,4cb04c2e) +,S(22d2043c,ab4431b8,cf77ba0c,ad81848c,730a730,35277e4a,ae6392f9,de120f9d,d7795dad,5e5b46d0,9c36520a,c7fccf9f,4d71f9c9,8ed3d45a,432f4f6b,991b8acd) +,S(57e7a8b,34826533,7e203360,2f6244b6,41d92c8b,b2419734,9fbb3271,57676302,4d9238e8,ba4bc8b2,c3abd2eb,6bb2e545,5146afdd,3d1ce2a0,9752803b,4599b83a) +,S(45567f60,2755027e,282b39ed,5ddab1c,7ea19a82,4c0609da,9ab455b0,26acc359,db55ed5a,77a354ed,e4229161,141392dd,82c1ccf7,f726fd4c,2fbba48d,4134f5a7) +,S(968fb554,91059347,9dc1933c,a8453201,798a0be7,1a284c38,3e8fa5a0,f67fa80f,63586b1,6853f550,c36d8394,56718376,1c14101,dd03cbd0,b164cca1,24e8920e) +,S(f366c649,f633cd7,f1fef522,b78f7b85,3d640acd,11af2d17,14c14251,ad873107,5fc396af,38f4988d,82c4cfab,59d415ef,25b260d5,711ad546,e56fb65c,7482c6b9) +,S(aa0c4fd4,4a2e68b2,edc16eff,d2b3c29c,59b19289,1503e6e9,ad068743,fc201d06,614e3224,2fba7977,464b5c4d,b76270d0,2763aca2,54aa5b82,b5ddf8b7,ff3fee33) +,S(6c886cee,19b2cec6,91c57abb,da830e45,da4cbdcf,37484ad2,b4444948,8f2cc876,24cfcbbd,9ab4df87,87eb384,fec64e5a,a197e897,bcf2dcf5,def4b94e,afc16a1) +,S(4d600199,c33f76ee,c81d1686,f116d4e0,fbe5e4ca,df3bee43,9a81785b,c6095554,cb414cce,b769f70e,115d4321,fdfed743,2bf73dc4,9f1628e9,dad15f32,5fae614a) +,S(377dd0a0,196d59e0,e71e8472,4b65bb16,12c3caca,d2f2230a,a675a25a,5d0a4fc2,2c727e7d,8c8e27dc,a5ff7c27,b349752,1159c736,2b51f38f,e0343c74,acfeb560) +,S(9cc0cf8a,23afdf35,1bb1826f,9d900b8a,e8aa5019,8cf36552,9ca928a5,9c820f46,b572f15b,e2aac0a8,c8142c53,ea43a0a0,693e5446,5d5531f8,b068d347,f7e67256) +,S(d55dfaa6,41492b1e,981d154a,2be0441e,4cfb01ea,a51c40ea,d4a4d8ed,19fa3050,2e795dcb,408c74c2,a9898f31,523a1e72,da0c4c77,c2dd2eb,45fb2e51,8f238ac1) +,S(46bf63d7,2d113152,3075efb3,fac6c07e,e3d27e87,279724e8,46306dee,7d210fd5,771bb1f2,30fa3253,7e3b433a,2905c4a2,dc4a2e37,32e282fc,94cb2c88,33b0b199) +,S(4bcfe388,3e77c17,8c6f1826,f75e7c3b,594ef8b8,c1a9ba3a,13f00597,50ca3aad,b5562e93,9dcf4672,fa283cf5,6c05389c,ec5ea923,b47d09b6,2ddaaf54,8a1b0129) +,S(c9681af4,715e69ee,d7cce802,34bb2a49,6255ba39,1df76c57,df9747b8,d8c241db,c8b175cb,b03d5206,5f2bb846,81bdcb04,da530e81,31082e08,28c21f7e,cde038e6) +,S(9fa0a1b,56bd6ac7,f4a2671a,3b4f6ae9,bd5538bd,4c6b4101,790b16bc,c2fbc33c,27f9eabe,785c7cce,e4859959,348b4864,16056f68,6d445fb5,c08fd8b6,33129e63) +,S(15042df0,ca178aac,723e7b9,8677964f,a87203f2,bc0e1fea,a56ec6a4,73d0381e,445db657,dac86b0d,f8f9eb59,a143e75f,e271cbfd,2420b3a1,677ee3bd,8d0183f2) +,S(354f6a63,d4c1877,e0e7da3e,921db767,6b7f9dd0,eaf8b65,eb08b032,1f37e9b2,1000503b,d65b80be,eb72f480,a43efd65,2eb784d8,650bffea,5559aa2b,104ea8fc) +,S(19c36161,7a448fc0,49cd8864,d2707d6e,9e4ba74e,79ae3d8a,c11430c5,99de065c,2f9f9fd8,fd38ee81,94ef570c,1b7299ee,75742d18,1610a2fa,4dd06f30,989acff5) +,S(3739848a,d2ab8a66,b6a7a2d4,add9fa8f,5a50807b,56ce5d39,5bd4c146,7083f88e,6fd71820,611102bd,f4dd2056,92e188cd,68a5409,1036951e,6f58162c,65f0cbc9) +,S(9c22cb45,261c2336,7dce66f1,f84b84f5,2dd7e58f,8ac6dba9,50062eac,1c10aa35,ff84e3f5,8c25be72,910bead6,286dcb9f,605b0017,1996d46e,c8dbee64,52a1116) +,S(572145c8,7f311732,7ecc71e4,5e37c555,5a412785,7513fabb,d0fbdd49,6db4538e,163e63ac,5e3908da,2aed5166,c121548d,5338c6ac,4ea7550,242c7910,8a38871f) +,S(c9f07954,d8413eb5,8ef213b7,51a966c7,4c641ed9,8db8685b,d931e321,2de940ef,9e6844bc,804f3d3c,a065fe7c,b09bcecc,92cf5af3,ede9041d,792c184c,cde17fd0) +,S(ac297f46,b07c8a29,d664a24d,f05a8a51,f7b0e4aa,e8800c3,f9291a13,787f25e3,686e3b7f,78e45ad7,fd1bbca0,54a5d182,b1556c77,753c1858,75e98de8,29b66cbb) +,S(6c5913b,b383a688,390274df,121eda23,5ad55dbc,80bc198c,21897934,98b3e1b5,54b9b83a,e3649f4a,2f11ebf4,61e24a55,53e5b4b5,d0f78dc9,1c35aade,2cb9ccf1) +,S(b9926fa3,f503356b,eca59ee9,2163cbf9,846e3efd,c793db45,cf7ea8e5,af2495df,d6dd7c5,33d4e7a1,ed415c51,1fc15e05,54fd00c,100bf047,bb8f9054,42e2a512) +,S(4325d1d2,f2cabe77,fe0ac758,f6073057,cb36adcc,5357fd5a,31473ad8,74e69556,de437968,2ff6315f,8870562d,560cc48f,818c8fb5,c45ad932,ed5a7d4f,534904a9) +,S(a183e95f,fd84bfca,4afc9059,ce1c40f4,eed924dc,d1bfff11,d38a8c1,14164917,11c57610,c7ffca41,145046d,4cdf95ec,c38d695d,bef057f0,a0d01bb4,41d64b95) +,S(b340d0d9,ad6528f0,d9651414,f48fdbc2,ab7af5fd,3baa8091,84d5e881,6cd07114,85ed726a,9ecd70f7,f964dfbd,40e4b68e,ae2671a9,b6c3d384,919d040e,120dd4e1) +,S(b52daa88,35992fa4,1595f0a4,c9e075d0,b146fae3,6c0d640e,8e6f34c2,16719377,6088b139,9fa83889,a6cb5cba,d478c7a0,4f42f082,24b169df,85ec90e4,7a4ad7ad) +,S(90bbd15,42b0f88e,9f7f82bf,7c2b5fe5,f269ba36,4523a18d,5dc5709a,2ab9d8ad,c9df924a,51af344c,a71461d2,bd3743df,c6958490,caa68743,e06e7348,528fc4e5) +,S(f72ee5a8,1696194f,ed3d4603,f2c9312e,b31c54fb,438b1fd2,2788ea6a,a3aa8365,e2963d82,b6ca0f4b,8ffc1078,cd45a72d,e66f4cc,78567074,4fc1721,e50fde8a) +,S(108aeb71,5bc70525,42f5d6dd,dfd348f3,66a10f4d,d99f9298,c35a8397,e6b9fb53,8388b339,75a58e04,a0f6df47,23728986,97b8d970,ac6bd45b,49b9cf1c,3209f1ce) +,S(dc3daeed,87345ebf,824a5ff5,c7f46268,fe54c901,493e2e86,e2667fb6,ff61d5b0,b5a7e641,238e0467,196c1683,bab47f66,cf001079,932a5d56,da20f89d,d93411e5) +,S(3f96a83c,2be16120,e81e1d26,e3853ef3,a82c5f32,f8d6bef9,38179c06,4265c589,eb8d370e,797cf20f,d5a0d734,9fbd027d,630ba1fa,bafffa0f,2ea37131,6b5c64b3) +,S(27caf86c,e1f423e3,1cca2278,244fbe3,b358357f,af1b7866,1de13b96,eff5c4f3,e8f77718,647acfb4,633ddbc2,3dbdca0f,2187e24a,2f2d45a1,39bfa1b8,a2b30f61) +,S(6681cfb9,e2418786,1887f964,84819645,2d301a1c,7c082361,67a24c62,f74d04f,9c89eb3a,7849e944,2f5f521c,c08d11ef,f1ce4869,98d4d760,8dcb4a37,b815151d) +,S(6711b849,48664639,67274709,2fbbafa2,fcac45dc,1795e80e,67fb0e65,beba8da5,ca12c83f,1c8f5ed9,222d8cec,bbcaa51d,6b986a5f,60d2c118,b812b259,294cfcc6) +,S(5ee9cfd0,b1102cdb,a0fd22b0,569875c5,fdd73467,22769011,8b7843e2,b71dd94d,1dd7a4e5,bd7f9ee4,e17c518f,19b60332,60d2294,8b5f463a,ed9021de,87d7d86) +,S(586dad7b,13390be6,f3d95a46,6d0224de,d7538f1d,2d2d9785,e38a3f2a,edf4924c,c777eda5,a68a3582,1735bd33,7119e58c,bc2fb101,c995f986,7bed9786,cc2b64d0) +,S(5a752d2,fa012c7,1924b6e6,90ddc7e8,867f6ee0,ad8eed91,84f7250d,665091ec,57f2232b,32b36429,f15029fc,5789042f,ec1ace97,5f2cad27,d53ae819,47b95db6) +,S(f93cbeff,22bc577e,a9cfef22,378eb142,426372e0,7be72e60,2a8064,a53e638e,abc772bb,401bdb42,94b16670,2279e4f3,eeadb75d,57190a59,96f34237,83afe50f) +,S(8c272c9e,96130972,2efc34c3,6a6e63ac,76052cfb,856eb8cc,3dd014e9,d2608a9,9987d168,13c57162,3ba7d226,18b54003,731e3716,3495edfd,e85e927e,6e4607b3) +,S(bf78a0d6,1519542b,a54226c4,d386ddc0,38dfd84c,9f9555e2,3e187c11,4d769bc5,6094e1e4,d84ec081,e6014b59,d42959ef,e160587d,315bcfe5,5d26ec98,b1910280) +,S(5b264b76,cd092a1b,ffbab651,f42485fd,497aaa5a,e311eb28,ee1fdb99,32e65caa,944f9359,4b68d7c3,6610fdc8,85695b06,1dd84722,d5d88c84,c8c188e0,69d70d78) +,S(a2473cea,8075a0d1,33bc1459,8d147705,322f7151,274e797,4b7e042a,c082b559,64de830d,b6557b06,d9b09d79,4f6c905b,5168d32a,708484b5,d2c68a89,a2575a18) +,S(3e18d5e6,3dd0c514,4341535d,a7087bd5,f14b0708,a292350,6528a803,609efa45,6e9c71b9,7d007382,f82fd041,be53470c,26dc2f16,26a9f0a6,e1d9ff67,54288c5b) +,S(d1acdbcd,b91e6315,bce96eb0,9c229086,6a767441,4285984b,71af6156,8294dfa5,5e3b0cd8,9872375c,3f807201,73e29d3c,accb67e9,66b99452,2c9e9f88,613da5a4) +,S(3aa999e2,9344e0f2,b5ecc880,a35ecf75,25ddb028,c40f64e1,a210aeb7,d850c90d,cd2ce25c,fbe3a1be,dd2e6fcb,e9e9a881,28c454e,c7ca1951,5673aabf,a543d42b) +,S(98a2361d,7c3815cb,ecd0aa4c,8a3a6ca3,3e1b31e2,5a4b6398,146d6709,61a5017d,1f33df78,3040c13,be821395,8d78e039,516df25d,4d9d0de6,d397128a,2c09f2bc) +,S(528b9d8c,907ab870,6d7a5562,84cb69cb,ff348247,be1b7cc4,61351674,53d98d0,f91eb836,d6665778,7c6d67bb,800a1141,29700d53,194c5051,aba7ead3,ddeafabd) +,S(f1adec8d,3d1b0d20,8bda6a86,6b8cf730,f4be50e6,2c8d993a,3556c1ce,625029b6,478324aa,c3bf6182,25bfb61b,32d47956,57e4a754,e08a978f,964741d4,1bcc7224) +,S(ab2ef133,b1b115ac,41870cf8,d75d4aa0,e0181ca,742a8f10,f74d50a7,3924a099,a2c47b74,c584eeab,57949ef5,38c0af69,2f2baace,70a730a5,75629ab0,566a91ea) +,S(9d4eb41a,f6da6f83,b1d20e2b,f9370868,539a617d,111b8c72,348c9b27,e0576f85,c1c7b00d,b786c84f,a8adfe90,4353305f,73acc3c7,1c2580d7,cc5d6b33,c5f30eea) +,S(30edd57f,7b1b2c81,c886dff0,5d9e9062,a553638f,9e4311d0,18a42229,3fb916d9,6bc4774b,16d257a1,81e20b48,5acfce30,f7449e64,aa288502,d44e7c4a,44842ee7) +,S(28e3eb9d,9a2b855,65c58fc6,a492014c,f10969a7,1e81066a,41d1c574,31306583,fc653b87,80734067,e5245c,8c150ae3,59ad3c15,df4a8e7d,dc93c8fc,dfbb6c2c) +,S(cb984735,e3c842d0,a2fbe578,ff3e8263,5a3a8bb6,749d8e08,c91571a6,9aac75a3,e935a0cc,7181c3f5,3013f977,ad714af4,4c3e257b,e9936268,b481429b,7bea8367) +,S(36186672,7e8307ea,eea83b10,6850dfcd,5e4d665b,20aa37a3,ed0051ab,a40fe170,ec626ed3,2ae6dc01,f5d4c710,ce2cb349,ab27cbf2,da5d924b,e32ef8d1,707a6d) +,S(b1a40d5e,69e9f365,c2accd54,dc8267bf,4260abb2,3b503136,2183b17,4c6b7d2e,76619dab,2a7b41f5,2401ff89,4ef632eb,31eddea8,bae27c3,af04730a,3dc186ec) +,S(abd488b3,dff60a23,e83f0ccb,22620064,b32a8f35,d4c22be2,42eb1427,15660825,6eff80f2,17dae3af,96c7a463,d1848bab,fa994904,91a1105b,e1bf7f23,840b3a89) +,S(ac0cfb04,d91ceb48,2f497974,321bdb10,2a572115,73fe4598,c92510ca,4dd6aa22,6b5f6d87,4a90d0a9,658ae4a,64474d9a,3950314a,4662ade8,1c5e5605,274582d5) +,S(1fa8be0f,476c4b67,697c7541,dd1d8be,a3a0bff3,552948e6,87baf11,afc34432,c6b25084,8038461e,32961d20,181c7187,fe79df6b,8f5c5e54,96ddb5ab,80788d33) +,S(281b43c0,d3738989,a817d313,755c5f0f,f336a4d5,7e8d0ec9,b29fb425,c1f90e56,26b5070e,ba1059c9,b73e3db3,1227a6a7,68683044,7f823689,921a9bbc,bc9f4a9c) +,S(d64e69e9,54e81ec4,7446327f,55e5a82d,3b83eb46,2a92af12,f0b2694,c88f4052,aa7ed55f,284c3ca2,9be75565,f66ea54a,27a8f00d,afaff0d5,8f394797,3dc8622a) +,S(f4cdbaee,d4b01db1,f0b5b0c9,d6178235,483fb58c,5421ba54,17bbcd4f,e4e7b028,66d590eb,29d69904,deb9f48c,5a250089,b2b92447,8ea91302,1ddbab19,6c63b47) +,S(8ff94c4a,6c46e334,feca809,79d21a0,761fc1cd,1de76f4c,7243ff0a,93c9dca5,123ddc33,5f3c68e3,29f42d4f,187fdcc5,77207134,a8bb777c,2ab08dae,f149abf7) +,S(c7869b4,6e34186b,7e87c0e6,23b64fb0,efed70c4,f2af5e70,5c33ecd1,27cf267a,66295439,36620898,2f17d95d,7da2bbd7,29aefa4,69005a59,629720a7,5c11f48a) +,S(e0ea76c6,ad5dc87,bd26ba9e,25b5041b,9836f72,6eec0142,351b2431,6cce1a4,8bd724e6,632049ab,88aa620a,78922b65,6a3a4417,c8af7dbc,5a03d4b8,d4eff928) +,S(2fa63ac7,3e5f8982,36419f1f,4883f52c,e8e357d2,4b4aa7bf,c6aa7eb1,29e30159,57e1601c,d6323fa8,f5a5b314,6b5e5c44,7251db28,6f79d51,7d0b038e,b8d8c3fd) +,S(74ed4038,d4c50930,22e783fc,1bb7a671,49d00877,b202012f,6aa6d32d,c73026a1,5b74f70e,65d009e8,8cc618e4,9f7bfda6,58234f80,38e9835e,80e6fd42,6b28476f) +,S(71d6aca6,e38713dc,6ded1f93,4fdf20fa,16ce75dc,dc405148,eaefd2d8,f0025f97,b4314533,7d48dfc8,278c6c4f,b19f69d2,72ffd4d,a22dabae,dd3e60a,7067e302) +,S(28fb47f1,6e91bc9f,9a2d5720,f40297ae,ee617ec6,897044ac,8a174acc,5bed5292,d04b6961,d72472be,4fcdb605,9943c1b4,ef8e7aed,2ba7859e,bdb84a4,f8b498f7) +,S(68fcd5f5,c8655b5f,5d2fca79,59a7b32f,828c5a5d,e262f6f8,94270ee2,1f47a37a,57480650,33627166,c372bc4e,7a710275,7aa1ad4e,5460dfb6,d3d27f32,778d74ab) +,S(c7617ad2,f423abc4,7ed7f8a8,a7a6002d,17c9744d,1ac6be97,49110685,95aa36da,d9904b67,fba96cad,cbe7a9db,833c614a,69e330fc,a06ca2e8,d597f657,b7121d9d) +,S(a7ef4e9d,2396fe16,c0e78b95,5259a9d1,474fdc21,8b24e8c8,df566192,a6487cdd,d6782604,91c6be04,98c3f7e6,86f22f37,23c1e4dd,4f7655c1,f40509ef,5af67f28) +,S(f3be7846,7ff03676,4ace420f,4091bb2e,71856d18,9e24890,eab6b436,771e2578,f3027657,45cbf3e5,67a6966f,6b27ffc1,dc58f3a,6811f309,434662bb,636dbc5) +,S(5c947f95,5bd9ce29,5214c30,3ebf4f35,6c8d9e2a,4e173470,94d3f755,36f0259c,b6b7b775,3e7552a3,d2dfdf49,8578a24d,90a81d8d,68ef39c4,68fb5ca7,b75e76cc) +,S(236fd960,c3b1735e,279b8702,8c25a074,2c54c189,d1040c13,4e4cf40b,bd8b2c68,9ab59bf7,c0bac18d,d0d9360e,b79a76cd,b44bacbe,b425d181,873ac390,59bbc279) +,S(c92c9f26,17cce2f7,659d0243,8b9d8932,c1a9e9ff,ca8b0d99,cd7613b3,b1947b31,abdea94c,1a5e64eb,65e70769,51ace2b2,e4804ddf,1539d50b,725fe09b,52357a51) +,S(986087c9,142c608c,33783a12,4d22c316,733c2ae8,bc1fbd2,8bd1a142,6da94fc0,14925bf5,fd76b51d,6be82c65,4562cdf,8f5baddc,eb26c68d,3fa6113f,ab42a1cd) +,S(465a1f74,f4f6baad,7c644e21,f35650b6,22424e93,83b421bf,91478621,a48a1d43,26da71e4,179430bd,ee6698d5,7db01553,d41c147b,83247157,9f2fe923,c788cb48) +,S(dd7658cd,f28117c4,4ff3c88b,d0b46adb,c7aa2ed9,1590ca00,785cee6f,5c9796b4,32317c0d,1e10e997,a74935a,8e45d27f,9a9b8ac0,f77dcf37,c1c7b340,cfcc43be) +,S(55bd2abf,a803c49e,b4548b17,725f52fc,6222af8b,dd9aed09,715ceb87,57c72033,34ad33b3,9d7344b3,abfc603b,8dcf2a54,96b991b8,41564e35,53adfc85,3d3ebf43) +,S(77be5c06,d10c226c,8c9616d3,15b1e1c,44006876,4189fc36,db0c88a5,ec12fcde,ccf2cbca,5c474949,88f27ae1,b0361b9c,20e8b55e,d965f7f6,ec8fd9e0,429ba01b) +,S(fab72486,3eb6f261,f0460b19,bea7dbdd,80b890ee,d4bb5618,30db6af2,f52ab21c,914f03a,408a2e2e,aa9174ed,99d80e68,b67f6afa,fa9da5c1,5d22f74c,8876d0b0) +,S(232a2039,fafe8b86,50a671f8,de78314a,510db65d,5cf105a1,9db8082,2a0b2f66,14ca7082,510bc1e3,533b9f6e,e216ec13,3be3a6e2,64d2e218,d95f3ec2,ad78576a) +,S(b3482839,612a4ff7,a0584752,68f13e69,deee9fa2,894a8cfc,64e39054,1b7f58e7,722d02ed,df30025b,eb4e9fa,f7c58de1,653b8224,66b1193a,3f2fb71d,5d26ae44) +,S(d3873a57,b0a7587,cab10871,a9322712,cf6fd84a,226dd7b2,85823996,5a353210,3b7e4984,59c7e706,cdff95b1,c55e3351,f1f45d0c,c9fc11d6,60e5e27f,5160f186) +,S(8828788c,eeebb2b7,71d289a7,147c0a7a,26a049c3,26dcb281,cc9b2dba,162c20ad,e428a195,87425f22,3d798922,b4971c26,5da2fa2d,de4a364c,c8c65f48,c07b71a7) +,S(79fee531,26d0c00d,74986c18,993fa174,52f8dbb4,ea75680a,37f0b3f4,ea7e537d,fde50071,3143f994,b4d7b4a1,43ab3abd,525cebbe,93d5b5a4,560017a8,802cb5b6) +,S(f44f39f0,5a9f5f79,5f0f3a8c,e03ab50b,3672429c,bf699cba,ac1e58a8,66814e91,b95e45d1,e4de1300,950a27af,bab28bba,ff75a246,46ac70e3,fc09da30,d59a1dd4) +,S(1138e209,baf9c9b7,b89d7d78,832cf7be,da45afbf,3c2fa148,50426ec2,80aa9abb,15c28d6a,3965b2af,ea28520,7e67f2eb,ac7d5917,9672f88,3727e499,f06a0d6e) +,S(29d3e942,1b98d78c,60e4685a,aa503130,dcd3d3f1,5afc2620,472b83f9,34912c1e,90a514f8,49680969,215d46b6,db7c53b9,411c8c67,c88bace1,a6d45ca7,d2bf5825) +,S(a8a36a94,5fdd33e0,4f0c18d7,cd2d4709,d6efeb88,a53fa0c7,e90969c0,84ff3eb8,1dd7f905,edbfcd70,26aedbe,1cee1cae,23db1fcd,479f02a9,bb596af5,f56ab564) +,S(5a048ece,b3fa944f,90eab4f0,c3e7a06c,3c35f2ca,81263fd5,3670c212,6a981eff,124f1bae,b70fed65,d53caf7b,5e88077c,8e330d05,692199b2,4b3d6d4b,b7c886ff) +,S(32070282,c5ebc2f,665ee579,c645fac4,fd1eb4ec,d7297158,3dc81288,e932b8ba,8f69662d,d68407e,dafb11ee,8842707,c17eda9a,803cbd55,b86dadf2,85bdaa17) +,S(7c22865b,fb04d3f1,bb988a7b,80a49fe,c7810593,27a19786,db77a47e,57afe787,a02eb26e,30f599d7,d5599734,439f19cb,d0830b72,60e70d53,97f06e1,d036bd3b) +,S(a0ba4c13,30ad8252,c06c8269,a3dcc365,fd842e5a,aaf33a4,22de13cb,b9385cc,58ecab13,5cfdbbf7,f3b6d2ce,277b9e84,940fdb14,47568960,c13290e5,fe239bc8) +,S(42ae6042,c8a2ba5d,c8fe47a4,12e2c0cf,7be448,70e67819,4e31ec23,44f76309,72ad69ac,7ba38bf2,2210a6e7,53c64467,36ea3a23,cbc96c3c,e19f209b,dea1542e) +,S(8f3ae8b6,45507a2e,3ea5d82f,47020739,d8f35f0c,8fc11e7c,6e802d5b,87b2a19,61bb8e35,3028ed54,1b83420e,fb9b1473,60425927,d3f9b6a5,d1d2b80,ee5b4cfe) +,S(3a84ba4b,1e151920,a0e4fb4f,30953e6c,a7ba1e12,62ae44c0,d91b437,b05df32f,b20f6579,43525f14,7b23abe9,c90e1d0f,32c44eeb,cddc6ce7,d3cbad9e,7d3e20c0) +,S(6481fe6c,b04a503,3ecc102b,de462e7d,7b87d181,2bc145b6,2d25fd88,e7316210,bcc1b4ab,f5f32ad0,9176538b,808c9187,d4e88b0e,aef31075,b26e5c27,8f64560d) +,S(5340174,722c583f,af9cd365,1f73b33f,8e4bd1ca,cac0af4d,1ff13064,d551a094,e4902135,448a616d,e435180,f85d0a95,d9e4655b,aebf8a41,a3bbe221,1a66a8e) +,S(c0693eae,a5825c4d,6c24e08b,d57bc32d,6c9ee2a7,90dcb49b,b350f852,4e2867cc,da20fb4b,7627411e,5c6c601,bcb8fb55,f4f6178a,efe0ca04,62c85d86,33b9a05e) +,S(c51d0f73,72fd0502,d17f9200,ca189821,e63e581a,8356735c,a91b6e93,3cfa0d9d,8d10e6b2,7ed7edd,2cfff134,54eb979b,a2797a7d,3c6fb413,b3bad4c2,2e352655) +,S(16811856,4d2d99ae,2daf79f8,58b52ad3,3666008e,d9d2c59d,be3160df,bec3290c,2bebf1a1,45617848,e81dbac3,4522cd0b,3e9cc84a,3c08602d,1adf77ba,292e7460) +,S(7ae94933,e1438525,b2ce1622,5654aa6f,b15999a,57835a09,20a49748,7c0afeb5,91912e37,830a645a,138282a5,1e3331bd,a13b87b6,f443f901,95a2f4f5,bd9b95f5) +,S(e7792d97,d02b76ab,2414c5f6,c2d1bf0a,c27709b0,55b2c36b,179599a1,3019d4ac,9f4d9689,5fceb179,b98c75a0,d5d56cc1,dd274614,a2816e8d,16fb98e0,ed3f2b52) +,S(2ffb9d4,946fd63f,24cff64f,4ac79450,3d97d706,eea6c4f7,69d9e34d,3247bde1,66b1c74,34881531,2bd6907a,6e3608ea,cff18832,5576fa9f,f32257b7,eb81014f) +,S(4544ba32,f90ceeb1,1412aafa,b4ae7351,aeb6f4ba,12e00ea3,c165c8b1,ecbb2fbe,62fbd7b4,c2a5cee8,bfb9ede9,b02dbbfc,2bba538b,834797b3,948887cb,9f8f6736) +,S(250b01b9,25d9ffa2,75eb156d,d8c67b5e,5d981ce7,8824d37a,1b09e3e6,7918980f,ba1d924a,32f0da86,e532bcbe,6766259f,eb185161,4042c0ff,261eb81d,3e09c481) +,S(9cf30e54,1f2a5fdc,73046807,32e962ee,62e0b813,901e30f5,ecbe1fee,abeb4d2,7cb246cd,1281b77b,19601d14,baa8ff62,848259eb,6567c741,c6bd54a3,b5510723) +,S(edc9e8b1,3c61a1e0,8f93be12,495084ed,b5a90eca,4f11dc03,cd217b1a,56285a2c,66c2fd21,7e8fac7,4fd43b1b,58c80661,b0e8df85,a2fddfda,5e9f99fe,621e1f3d) +,S(dd94295f,8388a498,2aaa4164,927b81ba,cae9d002,b3ddb6b6,97082c70,f1e2c66e,838c060c,d409c1ea,9bcd9e8c,b1fac83f,3b08c2b2,482d8f4b,fd3ebc18,8d6706b) +#endif +#if WINDOW_G > 12 +,S(7e068e04,dfc0be48,e5c0d3b3,5bfc734e,96e96ddd,d0ac4876,92f74535,685ab7e,df2cd146,90d225c8,d04052e6,93f14bf,69351e08,79883646,2c88401e,4ec70d0a) +,S(73a9bfcf,d10aac9b,46e659f,76c439a0,b7c2a073,7dec217a,21f43f39,949a5052,73b91529,3ea7b052,682062c,8f86cbf,bf379df6,91a9cec2,4a1424a9,b3be10dd) +,S(efddff84,c8cc754,e6e34678,d85809bc,55cc224b,f69be05a,daa847ec,d408c55b,65dd8f41,8264aab2,efe6ed7e,c45b4ac,8aac218a,3b6713fc,1736dd6d,c2f188d5) +,S(46a94585,7118384d,8d23d6df,a4386dd9,dc264f5b,171a7585,7565688e,bfd73f4b,3de5af7e,a298c18f,4dbf16cb,38e7f617,1e684ee8,e8df2a6d,256c011a,65aaf35c) +,S(6890edb2,7ce3c265,d4afa17b,be160a94,45dd0c8c,9ad6d93b,910ea47f,3821cd3f,60f47c5b,10ef5494,cd8810a7,ca8802ab,7c24beea,eb67b852,dd22040f,77cbd1ab) +,S(8cc9eb6,340b886a,81ec4b32,87a251c1,e33e68c2,1f55688d,952b44b4,2a05f5ae,9b176b0d,90e38290,8911981a,3bc475b9,f0323870,150c9c95,5078bf02,307fb6eb) +,S(2b062f5a,da48de0b,58001cca,e96cde15,227875e0,26c94e0b,fd1fe2a,495b0475,537f1c68,3d5170c5,8097bad,4bf17276,da9de994,8eff6805,48b35390,2f1eab0d) +,S(dd55b91a,84b3d53f,4332ff7f,224e9231,cd358bdf,27f30082,52d7a8be,bb7240f9,e6f1a08,a40b6530,ed737609,4deef969,774d2173,a3ac158b,ff681908,192a5c94) +,S(ac5127e0,40b1a979,46c0cdb1,c782ee2c,8986fd80,d7151e75,16fc964a,f2c59c70,849e2249,323d0539,dda0a82e,1764593f,8afbb097,880af8e2,4765ea01,b7ae5db9) +,S(df2f2eda,f0b6ce9a,3784e9ce,1e1ddae7,9d136423,153174bf,f72212c1,b5311123,b9d98f8e,bd78bc20,316da64f,46644026,fde6ab44,162027be,dbac75f6,e86d46a5) +,S(fd83b387,d630c176,23b85e21,62113610,97bdc5f4,3fb08027,73ff93d7,a373e5f9,9a962a7d,375f35a5,9d7503d4,c0fddc9,115805bc,38438837,d3c670b6,ab6cd2ee) +,S(d8fbdfc1,155ec8ac,8bead443,ba3feaa8,d565ca1e,4206cc95,5feb8e1,32cac4df,f9453c0f,ccb99cb4,739258ed,febf7642,7fb1fcd6,1f963abc,9cb9a5ea,751f73ac) +,S(9fc9749a,20a3e8c0,1b309389,16aaf3d6,85f00872,b82350dd,c89110c0,dfbf86d6,a2f679a7,6c92ac59,5773bca7,8f0f18,75c85cba,e75a6379,1094a799,863e19df) +,S(29e0e346,71a91ce9,bdabcf25,2e2196bb,65b81092,d3728f62,b58c815f,2f476a3f,2f440c61,b82e0ae4,798a35fb,9c66b261,1ce5ad0a,ab42f9d4,174bd698,d4d0c0e6) +,S(e4068a15,398955a0,f27e6f92,9cc3dfb8,7fbee70b,a86ee78f,8736b519,ae102d7,a3f2f2ad,550f9cb6,aed99943,84a9a350,16b91143,747d4e7,7d69e698,8f165086) +,S(51b45e10,bb1bd989,8bb156c8,a4c81978,10f16364,d3d55092,48a42028,726c9f2c,e30719d0,4225de63,281ac479,70010cc0,8a1f1d51,48c57f6b,b478c95b,e3e141a2) +,S(14cd5d29,7b8ab6b5,e92ec2e6,6c63b3d,64dc492f,d5a0c5ac,f6fcbfa5,aaa0b83e,5bf307d7,7cdcc866,349ad1fa,fb1c7d8d,5be19270,2a46b327,9b72bd77,e3666805) +,S(a5a8a711,49d6d146,c32254ca,e9c18288,45e9f2df,419ed68f,8c3cddb5,d22c4da6,9f47d887,7bc3d345,af4ae693,35639bf0,b003f481,7833d2d5,49c0bbad,3cbf6c2e) +,S(359328d2,4baa4232,d75b13dd,d146624d,bda494e5,2cc778f9,99a4c0c4,1f9372cb,d31556b5,71df399e,99084afe,c8f680b,b6695d7d,648f7050,a7881acf,241af6d8) +,S(c9eb81ca,4f2a5a2c,17268a12,d901edb0,c8fdacc1,d26c5e8,91af95bd,e673e7fd,6d4a512f,c974fe9a,711ae19c,d9bfbd6b,5acb73e5,355608df,76ed2942,488adb66) +,S(e26631f8,16f3b308,ac4c9f90,eb6102e2,48e55730,24f41f38,6ccde5e6,c2ca8e2c,16e0b2a8,823aecd0,165e2f10,20518253,96cfb814,bd5a248,58a4615f,eb9306bd) +,S(f76e9af3,65c0e7e5,7807b24,269c4732,677e5af9,a3b0a965,8db8355f,f99110ba,80cbf439,d26f164e,bdaf2542,385f9d65,9d174c62,96ada102,8a0cb013,bd2a9407) +,S(dcc8145b,af891483,295d6ab6,9a88fce0,bc333d54,841e7421,e65f6270,852c5dd9,cedb3770,a620e7a9,b40d6cd1,60363bb0,296155cd,80d89480,ccac619a,f31e2a19) +,S(7645e13a,6a1c4d0f,a56a199e,cae93018,7660bc40,41edb847,ed33fad3,c603e4fd,7c8ea51b,7990e5d5,125eccbb,5da890d2,bcfc5353,b22c42ee,1864c22c,be91e713) +,S(ba26886e,d74cbcef,afe7210d,51c1b6bd,4658225d,45e20fb4,4222b318,9e2f3f25,fd885db2,23ddadee,9e65fa64,abba326d,e0b89627,7359e893,bdf50db8,a2b3409d) +,S(68b500e1,31005b1d,901bda65,4a525e80,fc6578d,5e792c92,299d21a5,19050fe1,71ef7d7a,b3544a94,f3dac8e8,77da5468,8df9b127,83e02022,7e05d5f,6b12f96b) +,S(2ccca7e2,613fa83c,27ff851f,12c6fa07,5b19f7c9,940a5064,b84ea75a,da7996ff,5ab70a22,22dd1ad0,d0db2d2f,c59390b,cf37af8f,bed4570,3c6ae0f3,27d7707f) +,S(6d797d2d,6a56a45a,1b5af718,3cb6dca4,383ad9c0,4d5cf3c1,827f4da6,f7179f14,aae34e5,d203d18d,99e84bee,7d6f5a8b,b80e541e,15a3aea6,7b162551,e80edf3f) +,S(aa6997c4,37be76b1,9553751a,d96a53e4,9a565a58,55f67b5,11605996,e98ee327,6034a421,9cdb40e0,9698a15b,2e2f5f1b,6532e277,a1f4f4cb,3cc0c33c,c684835) +,S(56c40fbf,fb8e1d70,a345d53a,7b0f897e,1e62484,dc01adea,d010c5be,ba2a0f48,e9d06789,78b9290,27ba0e09,173d8ca9,676a4a78,7e299f4c,458cb6aa,46f0bd01) +,S(db6ff6a8,3963ed7b,dc262be0,8b52c3dd,b6e1e237,2a535073,1d2903d5,17918d89,a40112fa,f30fd44,b42f6b18,c144ca0f,e248d65,d757bdc,162b7118,7d951769) +,S(8df55701,a46f63e2,338e730d,4a543013,dcdd1173,754e5de4,151ca180,63402c6d,64cf9c9a,64b63ff0,1396ddaf,b48bbf62,b3e69665,bc89ea93,b9dd12dd,57a1c3df) +,S(9d10bc2c,51018f57,407ae460,e5dd5e45,66485cce,de258af3,7bef48a0,1b0588a1,38ea3c08,b2a4e171,7edebe44,e03dfeb9,726b302e,aea0eac2,fcbc9389,84922c04) +,S(13bbc875,cc07a787,2ca7a706,8201606e,560257b,fce7e66,2e4b9807,37640367,b4cd971a,47c82a66,d8ca19ac,baaf1b1e,d2ea3daf,d6f54769,7fe474b1,c0c2c708) +,S(8f26dc37,f617b174,dc947630,d0da6dc9,1857d9a3,13c92b1e,24ec9cc9,5ea9c3e1,3848a303,1d96bf27,4e423877,6591ac44,f887f2fc,1553375b,d5cf76e0,e73f15ef) +,S(2e1e543d,f290916f,5e55236f,660dbe13,a23e0d9b,11065041,ad3a579a,4c7b5f21,885a4527,626e05da,c10cd9f3,218434b7,947bc083,28fe2d28,ff10ad2f,b5473846) +,S(c83c2ca3,e0509ea8,bb876936,e3eb69b5,8bed8f50,e8c7b85a,1238082c,ee3f3109,2b9602a9,bc808de2,b0b0da10,d09da554,74b75e75,5301cc0e,3b07c331,329cd5ed) +,S(8c7903b4,e2c114e5,3264111a,ee385311,afee8b1c,90606700,578d1fab,d3d29607,dd02dad1,964df94d,1eebea9,a2a343e8,b488c401,88299b25,28d47376,f1025731) +,S(48263c54,dd7575cc,b30adfc6,c1c1eb85,b5185786,654c89bd,a38a681d,a6569cc0,e6f107bd,dacdb528,ed98e49,a25936ea,e223ac5f,55cb7955,ddadfb88,1213167f) +,S(6a7c050a,ea7d1f58,7918644c,63cd5d98,accb7127,c54ee274,95fb2546,16f0d2d3,fad19261,27a2646e,34bf733d,c089b0ca,f80f7383,b4bb1546,28d7256e,d821e232) +,S(e1f0a53f,62fbc202,df9147dc,c31cb09f,ece879a,ccc5a3b,f105a198,7f5c3ea8,3930a10f,b0eea30,c314848,94037780,3968f692,fe2e5d8d,cfe920f1,e5706277) +,S(bc0fb113,cb0fca5b,fd66efca,e8a4c866,da9b6a0a,6d4e613b,48526675,d3182b7b,e11e725e,6993eebb,d2715f69,13ecb148,37892c56,745c601,31ca1c6c,bf090f31) +,S(1fe5a0f4,9c438f48,64bf9ebf,89eae7b7,ee7e6a1,74a134fe,266b0329,cb42f908,db8095ce,f912641c,92b3878b,cfa7b596,694514a,ce9b779b,35ad6109,c675f66c) +,S(5de3fdb4,90167002,fa6e61aa,eabfa53c,ade6ea83,3f3c8f6d,e434320a,aa524cd4,b5cbde88,862ad6ce,b344a1dd,88d1ac29,6d7e9ca3,d5e98535,dc158579,147e08f0) +,S(93b06993,a913dfcf,5eeb0be6,294a645a,b2964f2d,e2196073,8adbfcbc,23da54f,7836782f,856cb744,4187330e,fca3c7e2,9c151ad8,1e8b507c,4d14a14d,492ae0b8) +,S(705740d,27d90741,e685a044,f6b055e0,9c33369b,e3815851,886b7860,8e762f0c,c4a58fbb,738d46c6,9e93193b,529f12ac,b2142b32,1fbb3c55,d3f5dc99,173d956e) +,S(7619a000,fc485526,734a20e1,99530f0a,e5b78767,61040864,34a1a1e1,1d93e296,7f300de1,182f479c,f6fa0afe,a2ceb59,ab26f675,77203201,4f8be86d,46ebed6) +,S(fe20f5a8,ddbb5201,6cd346fc,d281413d,cc0d54b6,384e460d,bec5428a,599ff2fe,5b488ae6,e2604871,afebe551,f9957b0d,338cf47a,b4ecae0b,ae7a92b9,242d879c) +,S(995b9727,ba7e52cf,2dd29e07,73c751f9,70768121,8ab88b84,422e1e3f,42ad11e2,c3c9ddc9,7ee41468,c4ec5e5f,529bd8b8,49c8d585,f905b91f,42af5c6d,2f7fd26e) +,S(cb4f2e4d,2ca94d7c,79e91344,55161921,636d26a0,d84c2a16,e267c242,702b3136,215eb6ee,394940e6,cf00df48,f7e2b8b,1b9b2f71,7a68ee49,bbb879de,803ddb9b) +,S(ca0a2a56,34b49144,bacb1070,7668eb67,4572b69d,5e1a4e6f,c722c256,b9fce397,92079cc9,74ab2fbb,a5098c85,56ada7a7,6e2562a7,bdb5ebf,e958eb82,d3f4841b) +,S(fb82332d,c6c0c0af,d72f27a0,24ef163a,bfadde89,67b4c246,acd6b922,e3af7c7b,1a697119,f21cb690,338beaa5,2e2c4b1b,2b90d399,19ccf0c6,60dc540c,a934c7ee) +,S(d056ee05,d9258def,20e184a4,e2018bd6,d07550a0,63db4673,6afec42a,5c513dd2,af2c1d0,d222e356,67e7cfb6,201ad727,89ab0fc4,d68dc31c,276d998c,bc15bffb) +,S(3fadb222,c6584262,c4046c59,4b778635,c6325712,cd828726,7aea1253,42526f12,da5c8c07,fa6811d3,84ca7e8b,fa1d74b7,d181e0e1,eab86717,58666b7e,c199ae96) +,S(d27ac969,e222e50e,5dd915dd,39d3e453,214b818e,fb67e924,8ab4263b,1d9c4b61,c4857694,baead305,6e6709a3,28403236,9a7c55a,d81e7f6f,9b494a76,cb3a1c7f) +,S(412379b4,8b981ae6,a5fa4324,bffd69ef,99cd3a01,91a1acbc,d9340f01,72c565d4,f24036c9,c7dbe4f0,2ca523e7,ebe6ab57,c755053b,245523ab,ac9d3e87,fcfa280e) +,S(d8234eaa,99374c13,b9a8cc3b,663d00a5,bef7909f,b21243ea,ce9dfaa3,f79336f1,b8cbe8e,c4b465f6,6a3c1593,292babc,1845d8f9,1dc80e5c,b1ff904b,6e755c27) +,S(426f8b35,68c5ff9c,bac0ea34,9d8d3c00,427d323a,3d877bbe,47fbaf2a,5d189009,4e02293d,ce023c7b,9c7a1ba7,27cb82b9,9931f57f,78853bfd,7dc4399c,bd00586d) +,S(f1c706f9,2ee5f2c,2412a7fd,c9ca5c79,8717576e,c780f6cc,fe72760a,4497dfa5,c5e1a1a1,727f55c3,b3978700,51a09b84,9ef75895,d6b9c4d5,9f85cfac,2bb7e740) +,S(84e2e07e,cc1d5987,968d6682,525356b7,5982001e,67598b67,608f1869,36c2c679,41ab1343,8ab5ecdc,cbe75a8a,b7fceba5,2903f4f6,f5b43bb6,28173866,cc28555a) +,S(7935eec2,fe535823,44abb699,3a18cf6a,3d599b0b,ef0f6068,9c689b40,76ad2b54,ce2fc96a,ab978861,b6ced574,fe4f5c85,b77480ad,e3d75b40,6c4cfbd5,53371910) +,S(d542a4a8,319f6d56,b79abbef,9da3a009,3e8c2689,421e3839,27aa6a30,b0dbd9a0,5104a162,65d285ea,8f99f3e9,c1951a06,6badb70c,985877a4,f1979aec,7b8173e1) +,S(bc692619,42289890,4af0157,a038126c,41011b9,26fb232f,d3c27d9a,44ece2be,8e2f10c1,47e2a630,9372e854,3cb8ef77,11e2022e,db25f4f9,847369c7,fe52f3bc) +,S(ebe1b736,bb178c08,deacdd80,b48ab650,ae079a90,95f43e51,f4521bf5,d18d8d03,ad81c659,b1450de,45f78ef4,b2a8126b,782f2061,fc8eebbb,cd0a2ea,cddb7514) +,S(e626b908,49e1853e,4fdf887a,df8f0562,666d094a,9382be7b,de152dec,b9e2774c,90cf55da,a4192a27,caab406,2cfb8758,2dca7342,c59627c3,f513ff9,f4834ea) +,S(fba7a057,ba048792,2313b8b5,ba4514f0,d8f571c,bc7ac0b6,1a987a9c,e4381e67,7d2af7fc,142653ba,bf05133f,958a57eb,7cea5b90,ee5300f7,18cee7ae,d69ec44a) +,S(144cdb95,5b5d5181,5a2e5bdb,57033e67,239735a,456579ea,1e3be689,94c35a54,e6016f89,e896fc59,80150d2b,8135b4b,ed0a108f,8a2eaa83,91987a77,6253f1e6) +,S(538de6e,e7ab1b5e,cd74a2d1,a9599d9f,ad28cd8f,2679eb6,81c25e1f,183c0a24,36c0a747,79611193,5bdbac87,d5b38a05,2482b973,213d0960,1de8404b,14121004) +,S(76914f0f,d28f73ee,20ca3806,263b757c,7876eba7,54bef2e,9d10615a,ebc03794,6de24dca,e16855bf,22355786,1626c62c,59330752,f9f8808e,c3930680,33a12642) +,S(69915e6c,f675f7da,f595f7f9,6c912f29,86bee7bb,aa5800af,27e32baa,9e34e4a7,6094fbc0,2f109855,77b53c91,8dd2da3b,139bc31b,77674d56,df72cf22,2b9513c9) +,S(4ee6c20c,900bd4fd,be942dcf,db91182e,2c37eb35,e4287e5d,859ba847,18ce3015,84ac9769,863d618c,4b738e66,8c293d3d,42e2a9c6,4c47cf75,90ed50f3,2062cd64) +,S(a6813c1a,f57bf8a3,8ece11dc,a4c8c581,aa598211,af9ec6a,d2271796,88a0fa61,6420274d,f4e29631,5b7e2335,e98fb2f1,d415c99b,dc5a00e1,d182e809,5b8edca4) +,S(421003b7,107b2897,24dfc743,275db49e,69d91077,6ee53d6c,fdfe6ab,710fce84,cb955569,7b924395,c31cb149,88bcfea6,a932087,3aa8002a,c218f33c,76f9427f) +,S(9cb19e1,cb8c4fc,4009d362,eacf5f25,5e125298,5b546df8,fc60bdc6,48c8c522,227015d3,2c6ee68b,63e20e70,ed7cff86,8fd286e0,905bf623,1b7e894e,c7d70d12) +,S(c7413596,8193588f,38f412d6,4e2ce0cb,c4a7ac4b,75e33704,36236362,8bb953c2,7bee7fa0,1b7cc4d6,d22dd4c9,ec16b39,5e1d70f2,52778801,9ae75ef4,a908aa6b) +,S(2a8e8a05,321f4926,e8fac1ea,8a97cc64,c2f8e398,e86ecec,9dc2e676,61df22cc,63b86507,4e4fdcaa,acb60c21,c0d3f813,64f0c007,faff7780,9c81fbdb,981fae42) +,S(f3ef2e60,7d403594,48aab014,ea8e2dca,5af1d8c7,c6f66127,3552293e,d497a14d,dfcd5334,214b9f44,bc5d1d96,49d78c15,9e9ce44b,f43dbca9,c637c31d,622cccc9) +,S(6d5c41c8,169c33a5,d1111b36,1b1d6713,a9396424,bbfeb65a,80e40280,4857ead9,4c1f74c4,9f01bc2a,27a91d37,f59bde,3d674220,a521aa4a,6a0c548a,a45e84c8) +,S(5d812a61,c6a986b0,2c5982ce,34fd478d,60822322,47e07c73,488c71f4,4afff85c,37083f7b,16018fc4,25749e16,4c923484,680b1517,8bed41fd,cc8da253,ffa960b8) +,S(e01596ec,b82ff347,c3ba9710,82911855,720177a6,9efa7d5,dc6aa847,7f73093e,a674c832,849884b9,d38da5d0,6a58e4a7,a17acac1,8776577e,5547eb3b,b45b3bdd) +,S(67a5a900,313ff2e,7b32fcae,adcff7f0,ad52b960,ef6b0d0b,8344402c,9980f55,e77efddb,5e8e8865,eb807575,37c41e0c,9fdf928a,eb8b6a03,f41703c9,3c0a4a02) +,S(2b96879c,2e2d0ad8,281c1647,7de62583,53d77db3,57281c21,7df0d7c3,6466b277,dd5d3473,43bac32b,cc72408f,64a9fe7e,7e0dae06,786a7074,3cbbc846,80b62b25) +,S(ab94378d,f08748d7,2df137ae,a3e3e123,639b054b,fb726bad,825e2d9c,310367e9,5785ce24,40037d11,a8331865,c78ddaf5,7f9d769f,f2df11c9,9e3dd018,43a10f03) +,S(70782556,fd6fde3,8c93def6,ca3b6c8d,2f3fd4db,87be4985,fa3aabb0,43e7439f,7913bf65,ecf15020,cc5274b4,8eaf5351,51894bd8,fa236af,8f9b3fb8,178ebec7) +,S(3025d070,138bd507,b338c72c,1024a3f7,6b4d5e80,efcedeb3,e71a018b,77ca3942,3a8a6a0e,175eff95,a94172b5,f2a4ee53,8d503295,63a5b096,f83dd669,eb470ae) +,S(3fe372d0,65e97abb,94069e7b,2a8d01e6,576081a1,93897ac9,901a3d18,b9ab0b6,2efcee92,3154dcc0,377315e4,1d67b5a4,82403552,ce260c2d,4c1020a2,54842e5a) +,S(368c7011,3a9133ee,97ebe8f9,cc06bd7f,c3c373e0,da810164,bce5a30,2af55636,21bd40fa,4870a8e1,6f28b942,bc169712,eb7d70e5,a6faa4a1,35bf86b4,d06162a8) +,S(7df8ffd8,beb45e4e,1e440f23,ad6d713,57682f68,e54fd003,87eeac94,ecd96810,3d9e4cf9,908e5a99,44857d78,94c7ffe7,dc55550d,a07d3c9,ec07667d,982ed0df) +,S(cb6ad939,eb49c7ee,7c216262,49b11276,88269172,504fb8bb,dd2dbf7d,b6f23d4,ec8604db,18f27367,de1319c4,59f8e668,5480ca65,e1789cb3,45e0018e,ea98346d) +,S(5ae526c8,fc319e6,e054e6a7,59d9b205,d8a1e042,e684c53d,39098f28,70f4265a,da1e1281,14c25a90,cff3ef80,d5577c08,a03f4bab,d9e33850,f2488617,d50a9a63) +,S(868d7889,6ddbacc,1bbf2b10,e00456d6,17477767,5b8d3323,a8786ae7,25ff7661,d92d681d,189b0df8,e2be57ba,a9c146f6,46e6ce48,342a0ef2,96fc3093,af22ca1d) +,S(9f2f0b4d,e7b881b6,c4dd1f8a,74106a32,23bd3298,47c325a4,8341d899,d7686b74,6fbbd511,c2974af8,b5729ca6,658562f2,deca285c,b47f16e3,c444fc14,8e440088) +,S(faaf222b,813b0df1,5bf2da98,3ee2eaf6,c522f5eb,e8c08b4f,e6950376,d3fca8a3,bec53e69,2e98dac6,8fb2ae87,44f12abd,47f00e6c,5d6d1469,b2cdb41d,440b472e) +,S(7f5209b9,db4ab9fa,2c2a7ab7,6c5c62f,13c81c80,a4ec4008,fd67d229,a7161475,a13d6cda,f9e8699f,f397d1c7,6f191cd8,a58be40b,9acc4ce4,e69cea0b,4a48d193) +,S(f436156e,80b136f0,8065f395,e2700a14,50c7b492,405a0c04,6834bf4f,12c84c2a,cdd957b0,5684e01b,a760807d,39b007e8,e7aa890b,8882a0e5,9118951b,bd7e60c4) +,S(ef9aa749,5c5b37d8,2060c2bb,3454fa6,88216754,2b24d69f,201f1c31,3cf1d06e,f840da4d,f1d84a8f,ac125750,e4e6cd7c,50003aef,d1f77666,54ccf4ca,f27a4aa9) +,S(7deedc43,e96eb93a,c290809c,25e7936d,6d9e1cc8,a5971d40,b122896f,fb5de05a,e65c0e66,27b9d0e4,e7b349,ccf12fcd,de6683fb,6bc93381,22026b65,26a8e0ce) +,S(5a1bef15,6669795c,47be7495,582f361d,878384f4,f283e15c,e74b3ce,986d6459,ce985a81,1fdb02b2,9e35b97e,1833e380,69b28b81,ddf8cd61,b1179c47,2ccf39ff) +,S(d8123d39,233413c2,b14eeb78,983c6fad,73b8fdcf,84b2383b,fa453558,e525fa8e,ea9d399d,905b7200,46ff78a5,abb3cb56,835e35a3,c958095,ea226947,a633ef73) +,S(62f43dd4,f1f4c310,266a36c3,909afb5f,10d3dfd1,a7a6b5d8,93931334,e4d4bc8,bb7589f1,f83bd647,2e34fe22,53a101f2,75525829,daa2e8ef,89fa1dcb,b590f3ed) +,S(6cf371,d549c045,1415aa75,cf594d4,865f6e44,6f62df4f,cc1cf312,f79d72f7,f8ceb62b,5c979bd2,82a4ce20,682b45a0,2b3dee9d,68ce16a,7581adc5,c9e93af4) +,S(5bd7b780,770be9c3,7c1638dd,8f954086,49aeb371,516bdf3c,509efc5b,47cdd7e7,d46c7848,8a87aaf4,f606b91c,5add0c25,efc12c03,2a28b1e3,2190999,286ba9ff) +,S(c7704954,a319bd4a,e5a08665,3b959ba0,81eecd7f,f15681af,e6bf3db,c36b6a62,373543e8,24784ba8,3f53b9c6,189ccc4b,e508f600,b15c7378,36e3b3ca,516d0fe7) +,S(2b4f27fe,41533a9d,d807da70,7102c1ee,d6e92c8d,9e43958,8fedc6d0,39b19cda,98ba8310,ecd7cb1,c11fadd4,a92f4c30,49ba2180,24015d6b,89e2ad9,f81fb424) +,S(e7d4171,b3dc34d,2600c581,d6931f97,2c920c81,3d7c3db5,4d306c8a,5d4c0e5a,b29581ba,9a825387,99fa97ef,b5a6c4a3,3e75b71,d1cd51f7,5b6144f2,4a9a409a) +,S(6203022c,18f43577,5270043,56a2717f,2face761,e806e84b,2b5660d5,f1c5d52e,18a52f25,5d0a4d75,275fe97,3542b97e,212efd6,aa8864eb,6c80865,136a720d) +,S(bd81c7a2,8c1c80db,a0e327fe,3b0fccca,48987679,791e6630,e81c004,92e43b2b,ca50a84e,a14bbc64,9e0831f0,7f185536,416064ac,e93a8678,db1e2347,803871c0) +,S(9bc43e1a,d3c1390f,cd1385cd,603a6e0d,b875eb4e,6f3a554a,626a9b4,fc4bc29a,857a58bf,9aa54bb5,7acd8b34,b79717b2,64ea39bd,d8f4a22e,6b12e6a6,e0cb2cd4) +,S(3055a68d,194de3c7,9ef0117c,b98bfaa1,5e5bfb71,c656f908,2c8769cc,a7e40f33,183f9ea,dfebe1c4,bf0218cf,b6aba6bc,acbd8c72,a7fe086c,1c9233e4,340d1d10) +,S(4adbf984,ad1fd188,c9271072,43583b80,2cec1231,7d8bbe1b,71079fbb,734b08ac,14527188,9560ceff,3d950766,8e3f2d0b,2192ceb6,f79f5954,7094d5e3,d7ec04e6) +,S(38f72dcc,27e041d9,c7bae397,9cf16d22,83fc6a36,aa074b0c,d00651d1,a56487cc,5238c97c,33a106e4,1370d6f2,c0b6ffc6,49610444,2e51988d,f7160c3a,933dc0bf) +,S(de55bd8a,7bdffde0,a1413828,ac59ff2a,4560647,47c27813,322188c6,655be2d3,477861b0,df5b25f3,75f9d097,97b0afb7,67bf9d51,b996d51c,e65d3bb5,42d9da) +,S(c617bcfd,c47e02b8,918edf98,666fe912,e19340ea,6c567893,8739b89e,5e3bcc66,b90ba117,357e7683,2ae0f4e8,644cfc49,a6e04672,b5b08d47,3b826349,65117072) +,S(4655c196,1b5188c9,4b6402f1,e92b3033,c455f4db,ecadb672,4adab3bb,f1c84758,3ceecc93,a2575f4d,fb202df4,f4bc05ea,714600c0,28389b5c,f2c1c6dd,e6fbc4a0) +,S(fca90f40,dc05e5ad,3693c503,fab43da0,110df431,9c1dc4c9,e5f86e8d,d7726a45,f5822f9b,be3e6604,1af37aeb,19a70a6e,7478edec,68c8e1c3,e6cc86fc,5f5771ca) +,S(3176cc4a,dcb28258,779e88d7,f90d3b3e,a31cbe05,78c7cafb,93ff151b,d27f61e9,3863f2cc,148a0a43,c94fe7bb,afb5ab5b,6a18ce44,56cd06aa,c340c231,42cc0135) +,S(63269f73,d124210a,d070db15,14f82cc5,51d9c19c,d31a54e0,b811e650,ebb2ddc4,bf8ec7dd,8a787a42,4a74114e,5088c387,38246bc,3f6aa188,e300f0db,d85cd0ac) +,S(679a1d32,8d0f53b6,1ae7f544,541326a8,f07e749,34dd2708,dee3ce54,632003d0,83ca1348,8f21eca3,11be341d,5f6ee9a6,c9b3eb55,c9a3485c,349018a,725c350f) +,S(69a27d79,29982c84,d3948568,a54d8933,f7172f9d,e80276fb,846cf399,e0b38b28,f411d207,cb0f0bb8,574b16a1,22f39bd7,69c8b7f5,ac2db4f3,a02163e4,3bb26168) +,S(298d5057,1af5042,cbff2171,6029cef2,abfdabb9,cafebc7f,9dd56c8f,6773ee4d,f4343e71,d271844e,412e62c4,bf6dc36f,4271bda7,9ccfa220,75e3c055,aa97e9e1) +,S(3f2983da,46d1f101,8f8eb984,5bcf3930,e26f66e4,544f63b1,f8f8b979,200c4653,4973a914,c4ad33b1,36d57e6,b326d380,9b2c38bc,79d81b53,b26c5995,9d71db0) +,S(f836fd3e,30ceb88d,942d64b2,a1d2a6f9,54412ea1,ef6a3b13,59faa8bf,7e3538dd,720a3081,53476b5a,709fd29c,158b7720,c8161ee3,6e6aba3,b28e0282,cf7f9367) +,S(dd72eb9b,911e38a2,63bc8ee4,fe991fe9,295ed522,1eef930,b3ae2df2,ef583a,2a0da5a5,688bf7f9,79285d9b,360b53b2,398e86b1,43f10b86,83cb40c9,40c1b2ef) +,S(551e2650,46ab255c,c427bd81,8258b7f3,7cef92a4,496119be,283f033,4968a619,317c33d2,4cd8f35b,9b86a5ec,d1582a6e,e5ca16aa,3c6ea23b,2007a370,e7bc4f30) +,S(6683de92,131de3d0,ecb19a30,47825591,ab28cb61,5c852a90,fbd3ad78,5336c650,49eea58e,7fd95523,f8a9556e,c46fa0e4,b3c3b2c2,8e5d9e4,d636d089,282225f8) +,S(b5b3b1e2,84a6ea65,e0a9b146,e8f895e9,ca99ef3d,31a4bac7,bea49c89,3cf97805,a1720a94,f333e296,f2b91437,e19500be,3cf16cc3,547e9667,ffa4ee88,e5b6fe0d) +,S(a5019773,7c337684,9709a232,9718d463,ccdde43a,55350d10,11a2401f,9bcbf466,9cc069e,ffefc5dd,e8fa5e09,b6b751eb,c51fff8c,fbf3c27e,12efad87,a9d429e2) +,S(9ec3498f,eb2bd861,42841b66,3b1c58b2,e5cb7224,88e2f849,e1236b63,ec1588fb,e00c91a5,e14b97f0,362719bf,2150dfed,e517e585,a807333b,a000652f,c1f5f12) +,S(e10b6cb4,adc13185,750b446b,ab926667,581f97bc,5aaf04b1,f4731abe,f3c5b6b2,53a51213,7db20477,f3a87bba,5b65c01d,d5520b42,f2660ed3,c1f5fdc8,35e2b9c3) +,S(b754a967,e36ea7c7,98c93691,e02b6043,60ace927,13b18d0d,3ff61ce1,dd3ae314,8a9a3963,9aa7ee59,a42f8d5f,bab01e50,d83ee029,933cf59b,e12b82a1,5473d849) +,S(5fefcb61,c10cbf3e,6f8a51e,6bea569d,7999a275,6340ac8d,489183ff,32efa869,d81b3093,cbc4835c,1d88c093,28c20541,dfe49950,9b349207,15bbe1bf,4e881e83) +,S(fe51a3bb,4ac97e1,96009400,b27c8995,f0ed6f0a,b29b9184,70aa442f,27d2d848,8568fce0,a4c39e44,f2b8aaf,59f0b183,d306254f,83cbd6,ec5fd568,c9116a58) +,S(6a3e4629,9fccfedb,c58d5d38,aeb2a420,391df798,e447558d,7b591466,fab7dee3,1bed8fba,7bb15d9d,d42e7b5a,3ab1d9e6,89873eb9,e3161a91,aec3ee9b,22a5e548) +,S(adfdbcb8,3c40d4de,f7d62d97,e16bd32,33db304d,392492ee,7457ffc8,97450c37,7b082bdc,163549ec,2a8b588c,4156ac23,8fde7819,2e1cc195,6be85b87,f4138e0e) +,S(96850fcc,9c202c54,83654c27,2d17011,509ed7dc,6ecc6cb9,f06c3dd5,113bf61,10404432,7f966c49,af0c05da,c7ec18b5,b9fcc455,a01c3b6c,88b8b0,d281aaf7) +,S(2ae21197,8f78ca14,d88151ca,804379a7,1703f514,166f3ac4,f09409b5,5c458bbe,4de74cd9,576035fd,451c7dde,387961ce,2328e327,fa0312c8,6cbc9dc4,19ecf7b1) +,S(edc18742,e1b5c996,2661a332,cd62c426,7e5816e3,c52746cf,b79eac61,1a987e57,80003b3f,c63309bf,3f9d484f,ebabe579,29ba9032,30311bc0,2c021a34,5b4fe5e) +,S(7802aa2a,5fa0f0ae,29a90885,c8b94368,38b35d49,843765aa,1d6a640c,fe43a244,c7f329f,e63239a8,407297e0,416c49bb,7e3dda11,85baa5dd,7f5f7167,9192a803) +,S(fb774579,b124475a,c36ede71,2e3fc5aa,c2173de8,35e72386,bf67bf7f,992335cf,c0e66b51,63c17b7a,e43ebf0e,31a8d641,b6f413a6,b763ac01,cdfcbcc0,47a82c94) +,S(d81a3d8a,43abae9e,32f94881,fe9c1200,695a9c24,a31b6982,51e21b3,fcbc2852,630dd811,e8a8cb6d,7bf51de7,e0a98db5,a693e3a3,c9064dbf,2ccf6bf2,dd12673f) +,S(519fcfd4,97cf068b,804da0c7,e2268cda,7cb2eda0,4be5249f,9bf776b7,c7324cf0,bec6f4cd,198ab3eb,be691646,6e44ab9f,a357c8ec,3bca391d,c20e6ffc,9562fdb9) +,S(cc4ad3e4,8fd66073,5e193853,e0f9b1c2,3e31b284,e2770441,24f9296f,868ef592,88af158d,8583c474,7d5520ac,67b03c75,9b12151e,db25af68,996263ad,d783c27b) +,S(add950ae,6f5186a5,98b40cf9,64ded6ea,c06a57a1,4b85de33,8f709034,78d24117,c59ca4bd,2d69285c,debd6853,a0bec744,111f6dfc,7004d65b,c047bff4,a3affa7d) +,S(dc071b45,43097de7,12bc8173,cb358af,ef0437c6,7c4927dd,d0bc3f6d,bab383e4,793912a9,899b304c,173b2adf,c187dfbf,f28fcaa0,fb11b85f,9e410b40,e95ca8ed) +,S(5dce337e,6db6099d,a9c37da4,a96b7a72,fd97a672,47f6babe,94d79b1a,aec167c7,1b887fba,1f098a43,b6482991,f16ba2a0,eb35bf56,64eb21d5,7549dbd6,4e4377f6) +,S(516eb6ad,8493a662,6d22ead8,e808982,900a83f4,3e6109e5,ba284cf9,e1f5cfcb,ca350ab3,8085b46f,48d8308c,61d3f947,ef6a8511,bb36fe3c,68d30fef,ece05042) +,S(f767c150,3b1f2da1,e5b91211,4e917c87,732b3fb8,8c860a3,35af1c7c,f00e5e75,3ecef8c8,cdbe467b,888f64a2,655ddab5,9ec610e,153cd657,95bb473d,a1aaab54) +,S(f9bbebcf,f792c8c,a7bbc5d8,f177de7a,4185582c,2cc65e75,31f3ac26,73c977f0,290ab4fe,fecb3a26,256f767b,8a19e55f,ac751eaa,acecaf52,b8c99657,49614a85) +,S(c6bfe1fe,be5c8db1,f55bff42,c123df61,6ec3adbc,c9b08e8e,af477fcf,4d47c45f,c595f882,d6d6a2ff,d832eddc,95679890,41c27101,347ea995,c79ad56c,d641792f) +,S(56c2d771,808fb4c8,71dcfe6e,5170bb47,c5559521,8b872425,761829e5,e0d3ce1e,6de72ae6,9e03e626,fdca9188,9e721c61,12ec15af,7163629f,5ee0fc9f,540468ba) +,S(20218b05,ec9f5be5,87a96d8c,3c0cf7d2,da9ecffe,fc604fb5,66a3667,5109d663,2ec1a7c2,c5357e24,1f2ea0aa,7a7321ae,b41bfa3a,88b42e12,e79283bb,ef8f6993) +,S(3a089269,a04ccd9,5bfdb4f3,3494aff3,519035f4,bb3a4f09,e2afcaff,976be4ee,e5680e25,fb0ba1fe,91693757,b3404b32,bbeba22,640da757,ed91ad85,6842d1a2) +,S(8f9f2296,a0cd8b53,db0fd0f2,59860496,dfd3e101,b2975a2e,2856523a,f45b3f07,61c15907,2cacdf31,b229015c,d6290d77,8ab3be0a,57785920,a3fb5722,b5c625b5) +,S(86580be8,695bda97,cd1599b2,6d4b6328,97e2b90,d1ea106c,836f474c,fe88070e,abae68a1,7e19ac58,38a2fe5f,d07dc7ee,2bb220a8,9dba4ac6,166c51ab,b17d7d21) +,S(fb6ac38a,1e69d589,ecc5b4f0,e57aa1e5,eb1f9458,fb187d04,8c72dd29,72b4d762,d601dd16,bec271f3,16f1d3af,2b82b5cb,e5d1806f,b960014,7fb01301,86ac32c1) +,S(7c10606b,c54fea81,bf3aec94,72bb09ce,c5bb7d31,b66e27b4,242b8dbe,7ea5f0b0,12215180,d3d65643,76583987,240b445a,2ea522a,3e0250ab,d14d77db,bdf68f54) +,S(85e6ab94,833593bc,74c7822b,1d9f384a,740a5be6,3b846495,2042b017,2d52a1a6,f5c160d0,68d6f86a,8f651213,8cd28e3e,d6e69fcc,dc75f0f9,81fe5ebe,1fae93a) +,S(7e1e2d3a,99cd1ba0,51b74ea0,e5471f50,5e626aec,b880ca27,f02113ad,ff51cfe5,413ec82e,e9d4fe37,8c232229,136f1ade,c1eb96ce,c0062997,81f4b009,9dad89bc) +,S(589640ad,813735f2,ed7a08dd,6931c61d,6a9490ac,729c2bd2,928ebd01,e87aaacd,89d6b10b,8a89fb4b,3679fc33,96c4cd5,7a1e909b,e343ee15,c1a02719,20485429) +,S(7080cf4f,f3465ce8,fdcdb0ef,3741c19d,91fdd7d4,44118c5d,7b7ad040,5e6e6608,7a3f0da9,5cbc0ba0,b5c6d334,f80db1d8,3033489d,34143d34,7dfad89f,8e2441fe) +,S(bb660b4c,2d400269,2dd96bd4,d7737c31,91deb03,6553e61c,7d59a876,26917c55,b494ad13,a7560497,6068403,15e8b86f,f150af11,18dc02fa,f5ea3f40,c0983c24) +,S(73a241ec,7ebf15b2,4408161c,5d8a5c65,3f4f4fb0,8cddae0c,1e2c506d,9f221b27,80534bb4,33a0a56f,78486504,1d480d8f,64bbe192,a2f6f32b,5e1bc175,d463640a) +,S(fdc1ef51,f08bfdbc,7705741e,6a2b58bf,9e45f202,c3d7ba6f,89a15aaa,78b1fe07,7e9d00dc,dc1e4878,647ac05b,55832540,1684f714,755f4e36,880e5a0e,996c0586) +,S(204842cb,a0ce5cc1,3ab44736,ea0e33df,a15ab13a,912687bc,6d6733d3,a33618af,afc92205,a6e991cb,fad18741,818a94f2,9e1804dc,2145ba35,896f92ac,c96bd521) +,S(a03a9c1e,f82c3151,81009567,50486869,a47c4a99,83bad93e,b2bcb60,157ed768,786f9164,fb9c6980,eef3e5ee,d9a43b8b,2158ba2,dcd8663c,a26cf19f,f6090a65) +,S(5e3b6e5f,6cb41784,6355e3ff,7da813cd,fa18bd42,c54565ba,ee19b15b,dbc00ed2,b9c3a553,42bf2284,fc3b8f9f,88d3e4d9,9d6f358a,c5c8acfd,e340036c,42ee603f) +,S(19b0960e,82d1280,663dfbd6,efb2746c,abf76476,1029a54b,154385c,a05dbc70,f8b28bbc,440112a9,45f35645,135d041d,33df5ded,92116f31,2d2664f4,e5504773) +,S(1061e900,7597bafe,74b9b274,ba1a22cc,6f1c2d1d,b6be8d05,9876638,dff3677e,707ac922,dec592ec,44d7b59e,be2518a5,fe2ffff1,4cf4cfa9,8155c781,21444b21) +,S(c9184c11,60fc7d87,5439b567,69a0e501,cc0e221e,3b155f57,9a71cf1,f3030b85,880b69e3,7c04689f,d6dd30f8,75f23899,8e83e594,9fb1ee30,8c43e982,28327805) +,S(a35fb304,4dec52cd,8fc5af94,e6c26ba5,c8fa2364,2622af12,d37559ff,4374cf04,1544f375,692a3584,ac7adcb9,a3422dcf,8b360471,85326840,42dd755c,112242fd) +,S(ba8c03ad,60ffebe8,118efbe8,eb130f6a,1b2c501a,78000a8c,1b204bd1,b90929ca,e95ef729,a3f341e0,faf73211,2f7800ab,65b88d47,ae137722,f11369c6,e3aaafbe) +,S(d2ba5755,842d8a77,97fba189,f49a010a,fe08495f,5e64bba3,361d1b52,8f30ddb9,da3669b1,cad179f,784bc5f0,c3a55d60,549e72c,390b7d47,7c030bfa,53df7957) +,S(3e04eb58,7ec988b2,77b1d2b2,880ccb24,d3de1579,54ac994a,86db9ae,6c8703f2,fa412113,e6dc85d9,eeb1d650,3df96fbc,ff3c6089,cc5c207b,b98cdb4f,e728dd9c) +,S(efe5bb42,4339a49d,3e19aefa,91f466d6,60c9f120,5df91ca1,7a0da3c2,699fe7f6,98c6212f,fb39640f,cea21db2,97cf9fc5,e3576b0a,7cb4408f,f9e3e9d3,245156e9) +,S(a29442e5,a330336d,eefe6591,5c4e0ea7,bca2dc2d,9816c8a3,2bd66a4,baa0908b,a1bf8829,7320e47c,3b774c13,a6fb9e6,dc5e7789,44666311,2db427a9,dea135e6) +,S(454bccba,6f7225f6,a91f632d,1c9218b1,48e877ff,8018d371,4da8aa88,f08bb792,da0ded31,2d532b01,60a1106b,202ea0dd,8157753d,a07e0e3e,918958b7,45ec713c) +,S(3163940,32c39566,cb0631af,a2505404,56573782,e940dfce,d425834c,dcc2dca9,18c561c4,1b15b0d1,a477464c,6f4d668a,67f0895f,a55544dd,8445a8db,cfcc5fc7) +,S(54b5375f,53f07bf2,f15fced,ffc7132d,5240893a,3bce0a92,bc4fc884,49b07703,31be2b3f,a944251,e52922bd,fa2ea218,f5df11c6,d67226a7,b3f163ee,61abdee7) +,S(283ce31b,745d067,2bfb9b6a,694da3cc,de9033c4,639e8328,d2b7ee6,58b3bd,f6a948a4,d452bb56,e3dc24e7,6e81d2c9,dc1c7aa,67aab38f,f9d20044,d8c0245a) +,S(b5e74f53,117ba754,7b12419c,b0494579,48d5f831,624bb3e3,a60167f2,10e99967,5f635754,d635f9aa,a83c22e8,9f383008,3da8331f,4cfd9b5e,10d48280,718dd3e6) +,S(681e5f32,cfa33183,170dc776,fcd51daf,d587c34b,1cd27134,a856713,cbf83080,c587d8b8,d144e4dd,7b4361d9,b7fcf30a,76f646ef,fbe390e3,8f241a54,7279266a) +,S(1fba5eb7,722f289f,2521ec17,d05df56d,2f28b221,5ff8c621,b925a5fd,29f1d0c,df1140d9,97ecfd4d,fa7f287e,fcacb66a,34283b63,5b2bb7d1,524dcbe9,eb11f5ba) +,S(38bff4b0,df378b3c,ed38fc5a,733f1bce,17855b64,cc254f20,31e1300a,6a0d0a77,6d4f065d,f634296e,64c485ee,32537475,f35a5065,e73bfdc2,520dca1c,6606b1be) +,S(707013c3,59a9264b,be4050d5,27b5798f,779df8a0,77cc95ed,6e08f74e,e57de831,b9f379a0,315386c0,657b8dcc,53cd98ae,582313a7,632e4c3f,da9c9157,14ea422) +,S(ad94ed2f,70282484,e490abbb,320905ab,fc5b8c91,9de6535a,73da3f63,45642ef5,9dbe8813,a554e1f3,e98011fe,c6545216,fdf4973,6d026bd6,cb8702c2,aac88457) +,S(47b56de4,e991876a,499ad155,2443785c,fd174f87,58b881f5,4f545584,ff62612e,a140537,5855beb7,7c56117a,5f753777,383d92d2,d4912d9,86bd59a5,7cefdced) +,S(51bce64e,9291a693,1f24643a,f11f2813,f31f624d,cf336af,3cf7b48,15f431e8,8f743d9,a3012247,ee35d28,4120394f,f40c4c69,d75ae13,a063aaba,ed07e552) +,S(76287cfe,b52c5a0f,ce98e56b,49b4ebe0,83b80bee,3bc7447,a0cb9542,e7f7a43f,736b7e56,fa5744bb,d39d064a,50d98b07,e9e3399b,dc5847ff,13e33eb6,e2a7a7bc) +,S(614d739e,ad01010c,3191aaa2,c1b7771a,8dc29bcc,f1c4d55b,181acdc0,df6b8f5e,5ccd4e8f,e8607b76,c8a96c2c,5000464e,5591efdb,aaf07166,4f4db66d,c2f8085) +,S(c38444c8,ee8c35f2,b339404d,90d53ed0,35cd5889,89663808,3e2d33a,5e4e1bc9,8b4408cd,de5452eb,dc222109,287fa9ab,1d2ffc9a,16b93f44,1f4bfaf6,6ccd29f2) +,S(8a9c9649,c6016f35,d819bf02,852bfde6,56a1c197,2dbb6539,2391df7a,99c8f349,b2dcd957,be2c19fa,6c4a6030,a4cb500b,1797aa5a,339181af,dc6e974a,d769a8ed) +,S(a0f5cd1b,e4449709,25d0ea0a,6cd28d75,96292ab4,1d1766bc,ed6b3311,bea04b03,d270b1e9,291b29b0,ce045d92,3e449ce0,c8d7931a,71cf4b8,68af9594,927ff95b) +,S(a78f2336,87675987,7afbdbaf,28e2590,25c64ddc,a9543a64,709d4c11,1f3a9614,1365fac9,a5d245be,e5245b3a,b1f50d19,de34aa9a,439f5e7e,e241f042,32a6de83) +,S(3bfd37e3,ae482c5b,92baa6f5,a413a46b,af6cae30,9ee3fb51,4a9fc3e4,b391769,2d930818,34bbb0dc,66e424a0,7778c9cf,d0219c06,4dc7fd66,bdc554f0,396d1c59) +,S(92cac49a,261d23,e776ea75,7e796d2a,d426f23d,602ece5d,1b41cd71,d13881a2,8c76ec13,8e0f37c8,99a3e587,a8c0c5d8,c7a43ac8,187a35da,c0d8492e,571521c1) +,S(cf6ede0,ea7dc67,cc370894,1493567b,718944de,7a96dd6b,82940214,b56842a,e2b717d4,e939608b,7ad6128a,53dc8c52,fa070d0,f591842c,a76e8d0f,54627cb7) +,S(6204c998,ba512945,26ecb92b,bb06e218,968c8c2d,11e0435e,3dd1bf82,fa91e17a,1690a15f,e78365c9,c8fae21e,f0af2a3f,d1ed18c7,9a607939,d12d8add,94cd0ea4) +,S(a2c4fb48,cc5500e1,35268d13,a6ac2e16,d8ce0707,f2237f12,ef71affd,e4c0aa5d,3809440e,e608c897,cb7e3906,c58123ab,c403f57a,8d59b950,9e5f2d70,3c0cd839) +,S(d8af7fa1,cc303e4b,c5da36a6,d3b2e309,6acc8ec4,d73224f2,b667873d,eb656f60,9fc7f2bd,5a5533c5,dfb39f9,7045b135,5e14d81b,9edeae5d,dd4ccfff,f0c6de0d) +,S(3e9a00ad,b873291a,604e6bbd,b05304bd,3770733e,d1daf90a,864d775d,76dea0e7,deb49457,f6d1c4ef,53524e37,f19a8d77,20a5cb9b,321b4630,51f8eeb4,901ded0) +,S(bef5ae9,30aa620c,9854346a,ac1b2ac9,760ca8d5,ea189368,9de50e5,d3dc3d7f,20d80c42,f7925f59,b0212b9c,7d4041e5,5da98a3,fe373034,c0fdfad6,48dfc48f) +,S(cd4169fb,cd28d507,6c174308,8f39645a,38215e47,888a435d,5922b490,9155f67f,f9e62ca2,1a5564dd,5a65f274,356c1b68,a170dac6,4b5aa5b9,29dc2f26,35e74674) +,S(a4b691ed,34cd2624,fdda2504,797d76cd,4bd37b11,4cf3921d,538b6042,ed5a4c28,c65374b1,6781b4c1,15b0ca54,53e3397e,5c045a77,72c72d12,c336c205,d26af55d) +,S(5e4e916a,4226b788,197cf68f,aa850c0f,c2b3a615,bf9e847d,c9e55dbd,88aa4818,3f3c3ea2,5c7c52e6,5c9991f4,464f4b2f,f3395d05,3eb27280,8d984a31,b798951e) +,S(dd4782cf,f4d69f72,c951b3ad,50a4c601,f743e6ba,2194d05c,a5f474d5,eba74a7c,97a7bb5e,9854ef7c,5e3dd6ae,8628d8c2,5d3a791,d4db281d,6c7c12c8,20977b99) +,S(a1530ad5,4ab405ec,ddb94543,2669c07c,281aff41,13e4af0b,cc080991,c1adce36,f3d25221,2732842e,5dddda78,1e2aa5b1,b18550b6,fdbb968a,77444958,4a63e756) +,S(51924ef7,b438e4f0,614523f,232af64b,e5ee0d32,ad8e5323,4a2d76ca,9e64719e,87c115a8,11f94db5,6736e82b,8b644bfb,fdfe6e55,8ead8176,26858c77,128a8095) +,S(82cfee68,e137d874,107625d4,be20a9d5,6ac9055c,6b97563,a3bd5568,53fada6e,dd49aa46,c4f5c51c,72a804d7,6dee7a72,a363e978,502a5cc0,6ff67987,30733b7a) +,S(a3738876,f7f1ef44,5a1346b,36c7da6,e02b70fd,2cc3bf30,a4efd7e5,5f2e623a,6596f52b,e1ea52b2,be0de46e,5480331a,b1204d36,581b2edf,368d9611,ea04a21a) +,S(ae4ca6f7,aec818d7,2b624fd6,b2ccf24a,8d8382b3,18b0dd7d,d8203658,2980bcbc,6a7ada03,35ad7c57,1e2a29f2,554c8bbb,34815596,1aa995e9,2378c97a,dd8f1ae2) +,S(be33562b,fa9d762f,9b18d198,4dccb9c8,4d6ac894,2d8506b1,400f7dfa,89d12732,b666efb8,77c666a7,35336cc2,14e874a5,c4f5c956,903048fe,473d2e6e,9475d442) +,S(9d7da6d9,815b3db8,5303b288,8a60ff6b,f382891f,5c45ecf,37cb92da,37c74446,46c29073,72ba5be0,e61f6d73,4b413d44,df3d2c0d,89fcc1ac,5402b68d,755b12a8) +,S(39233d31,e513c2bc,c0602849,8bb7b3be,b5981fb,7c99a366,b62a9df4,3b0d4d3f,fc27857c,92e0ea4f,4d8ac3e1,c61fa774,1ec57d4b,a9affc81,f97e384d,b916dfd8) +,S(5be2d788,db90e83b,58d02dd,7b58f41a,547e6f33,a82d84b4,3f7e5143,db7768be,b8cf3a8,6b2dfa33,e71396f2,e84fb6cf,d585ef6b,9a264875,b9049f2f,6fde1026) +,S(3ff59de8,191fa14c,113600c2,5700479e,7c53a0be,3827f5d6,82f7861e,88f162ac,25d5985,6ab0b6e7,beff5f60,c279a11f,8ae4efb,5e79a4df,d815cc32,2dc77ba2) +,S(81dc9c30,ed221920,98ad9475,da00f8d8,b61a18a4,e6305b58,75f75bc1,719a256f,2970745e,5c44cb27,a6f8f9c9,869a25f8,9cccf024,4d40ffc2,ca678d28,f54682a5) +,S(ba3e1e16,579c4099,1576121b,230d4f4a,ea386943,bb7a8d24,f765a3e4,9b70e9da,a1eeb808,653cfa67,8a9d8d9c,7d30e7b1,54eb0de6,55abaabd,90f82236,32c72f4e) +,S(35ffe81,50faaee1,141f52a5,1b7d1e69,fa66d194,3b96f04c,a0589c48,83f854f8,d66a1822,e83f6dd3,fcca09b8,df1105c0,b4ad3163,6070dc9,b7dd08a8,c9366fad) +,S(398ebc22,1435f972,1c214c0a,e38b9817,8b50d7e3,e5724f68,5b950aad,60763a06,c2df549d,eb2eeab,fccd4da7,fc2c8ce9,15551b87,14903011,6825b804,80811f46) +,S(2ba27f33,e7d0a75d,1d18511a,84e5ce1e,9ca89d2a,a44fda0d,6cfa1389,ca89e96,5023684b,832375c3,8f39946c,c91ca114,45c2ac54,fcc12f19,c6bb662b,997cf4a7) +,S(4257063e,7ec51f92,4ecd485,653182eb,2b54973e,f1ff0144,65cd151e,f9e829c2,47351f41,16dd0515,11c9ab35,b69abd64,919f8b5a,812ad5d7,47c5462b,55232c1c) +,S(77e737c1,b5b3ca56,94218582,d2e56519,80da8195,88ee46eb,e3ef172d,9b4063a8,f7cb5c5,e66798ad,37c8d4f1,1cb912e3,651ae45c,4d7b07b5,e0e20c2,89d1587a) +,S(dfcbb64d,71018c1f,bdef98b8,2a4cb72d,ef027d43,47b5e8c4,4a7eec7a,34cdaa4f,dfc0cdbc,c7207588,8af379e8,751c4f09,bc2f4e58,2dca9a92,e06b0c5d,97972a23) +,S(8eb686d0,a7871e8e,32ac5256,746d7189,b39855e2,2a52ce78,ce6962ad,d355ae8a,ea8b3611,fec52837,fd0afe42,4c22c5fb,89b79675,6e8a6a5e,d71e331c,6ccc30da) +,S(d17d8713,ebaf2dd5,316703ff,8c4c20fe,ee56522d,bea7a987,85a96b1d,36cc3e54,ea70b7e8,6d7862ca,9d8a7a19,bf8941d0,e9fdb872,4e46f8b5,6821d85b,ddc10b54) +,S(7d4c77e6,ae050a1c,856d28e9,c14eeeda,249c471f,82cd6cfa,3ec037e2,30b3ba89,c5a07653,f5fbdf93,4b180f39,327d102d,900ad68c,3da1a7bc,ea773fe9,6265fe60) +,S(96381109,451e5e68,6d61d51b,3b250bcc,3721dced,de39e88,f4f50c1b,4d7ebcab,9498f419,b088ca54,7f17642b,dd6f0fe6,9f06514,a7228394,7f15d165,64801b64) +,S(7400b550,54353d73,7b2da8f2,f8f4e953,85f44e83,fda3cd20,8afaf90a,978c2ba7,9933aca3,ce503677,e2129a04,cdb1d5ca,e36bed1d,275048be,6b18aae7,fd909771) +,S(3d7b0c11,fff7bfd2,71ef5963,9f12ebd8,d1de3bc3,93b51be2,a011e4ba,66ff59f,b6397431,7f7ca0e5,ce1eb57d,8a886144,8bddb12f,75469789,b791c4cf,32404b9d) +,S(4944d9ec,7ebf7f14,e6312545,5c8dd996,45d128dd,fde3743c,5cd6f4cf,65c46328,f0655193,13baaec1,329cd408,c9d1f3d3,5c2f49d9,126c9d1f,5bf271bf,2c589996) +,S(9960432b,4764b1d0,f8607d6d,8e08b355,f37b9933,69bacb51,89ce46d2,79bdecf1,304ebb4c,921d2fa,29200ea9,ec214adf,f7e1a9f8,debab865,78fac56b,7160ebd) +,S(313f535b,63585658,fc3409cc,726b5ded,9196cc59,6331681d,9ca84aa3,bb3de4d6,e511a48a,a55fe0eb,e5f23bcf,d01ff4f1,59b049ff,8c999fb3,dd64092f,c56c9716) +,S(85c4586f,8cd36dc0,db9b9006,ef4f74ec,c99478d6,5c011bcb,3ccf034c,548ed7b2,cd6953c0,45c5d6c,dc632592,3f9b0070,144c8c5a,67639f63,a75b4d10,5b434229) +,S(968bc6d2,a7fc359d,1edb668d,b7381eeb,d489b20d,b64d651d,21d706f9,94671af8,fb0ad6a3,723d707c,c1b2f330,4e59517e,de88bcfc,b52f3ce,d0bdb7c,f0725186) +,S(2325aceb,3722e77e,e6cc7221,56ec0e87,26d343cd,cff6a420,e58c563,bf28985d,601a7f53,dd295978,f2a59683,6f3e9eec,19b9c8fd,e81bba5a,21acc8ff,878d39e1) +,S(8c6e76ab,b2313bea,dc0667f9,9aaf32a6,4b1c9335,87c31dff,5407fdd,67acd2e4,27e3b850,d422df3a,c93b19c4,229b390e,3d7bb92e,340daa46,b3f5112d,1e50c29f) +,S(e31fee31,34468d3e,4d6b2c72,8d538a14,352e7a8,8b9837af,9d8d4230,5e36748f,89b096e1,2d1948f8,937974f6,b9a101e2,37f9df3e,280d4139,e419a1b2,6d0309be) +,S(596b586e,849404b4,7c742fdd,7e5a3398,da748ab0,67ae2981,215c17d4,b0d306c6,e96c5cc5,912cc711,5e4e8f05,edadf219,2ac27760,2b2ce791,ff6e18f8,62a0a16b) +,S(200cc167,5cf500cb,a199c3b7,1195270f,d453d5a3,8313f317,71452486,15aa1c02,780aacc8,7e34429c,6445c133,49240371,1905e24e,c17de4b3,e7b79cf5,5320ce61) +,S(7e4d5432,e10e1fcf,79148f8,77a4f247,70f0e96f,81331767,dfb5e9dd,2ad2025f,35f5dbb2,6ee82837,f37f5fd7,d417982d,fa58f0ca,13e3136e,ec0b5251,63aa432a) +,S(c1ed7508,95c97e6e,7a78f800,b6eb10c0,ff21f879,352870e5,776bb7bd,9c0237b7,90723a06,8dc0aa89,9c31e89f,64ffec3d,a38e8095,97209bb1,d8b1418f,eb418fb9) +,S(e5fd4ae8,a53e809f,83d239b2,a15d8dd2,9948ddae,6956d8de,fc7ce730,b2104770,6a4dda9c,1cbb2197,208e8ebd,35f2ddbb,50c7bf5,df4c112a,de02f0de,f71c4fa2) +,S(3ce75f2,4b33bd88,7ab72cdb,42f9ecef,e3534d15,f6733f2c,a766eac1,da51f30d,9eda315b,51ddf6e2,62ce9b5d,828af559,a43eb48c,d3dc9362,13bf04cb,1a838ed7) +,S(98c04c4f,33a81cd4,e498d8ce,77edf598,527fb9a8,8e19dd34,ad8cef3b,8813391c,fd2bcd67,f853f812,f4371c46,30560957,acb4843a,8ff21949,483f0617,ff8bd3a7) +,S(50e9c88,2906cb06,cbce62f8,413ce43d,f3d2dd28,6e4141b1,fc8a079,a87bbf3,43c713b,b05f19cc,685eefb2,ba04474a,479a615a,2f3c8a9c,e1c6243c,d82fa3fb) +,S(5d41ba17,458bde3b,64faa66,3f21b76c,71bf6564,2a73e3a2,eeb8a831,43adf2d1,17effc54,b3082159,2b39e22b,7ab058f,7f64fa7,68763510,87cc445f,57b6cec5) +,S(4e332cbf,2a02593b,6e83cb8e,1d92e076,6b34cc60,646fe3e7,89d38f9d,24d5b077,50fa745c,3ab90300,95b69985,99e391e1,744ad03d,decd1955,c8b2a859,e79e1f95) +,S(1bbf629d,27ee825b,c357455e,43410507,c83cd47c,dddb53f8,34716ebb,35a2dae9,850908c1,e99753f3,4f40070e,c0bd85e5,8fb72f69,601d3709,71ffa894,3de9bb75) +,S(a9149aef,f9dbd62a,ad0cb3f5,debdcb30,23aece9b,dc79db8a,a25f5b01,b5cde650,a7bb4b46,e6db111f,468a16d0,9df686d6,ae3c148c,61d99a79,918f0bf6,b4c327bd) +,S(801009ee,185d642,19de5b40,6b21dacb,b98ffcdd,75f8037f,fc5e1721,fdb72a71,e8216609,57c7ad6c,1dd36f70,645c75f1,38283905,898650f2,daf2e5af,37e26441) +,S(c070e99a,e466f67a,b234584,66f132ec,96c6b639,3900468a,b7368a86,c0ba6770,883fabdf,358d4f56,8a56f77e,3b291fff,be6f8fcf,9c0f0171,a1544905,50769362) +,S(6be89639,cf612761,78f549a9,ed0af9a1,8e028c53,1dff79da,71c5ff1f,54109f4a,777aed7d,dd379131,26a92f38,ff9970c4,ff2dd6f1,6d766e0d,8215fdb3,9604cf14) +,S(d1fd31d4,1ce71e4a,2052e79,6dbb1a87,10094505,2b9d9009,2195afc5,9624ce8c,f357abd3,78a8029d,eaa796d9,1860e5e5,36d5f2aa,ea2bda2e,5b510949,253fded1) +,S(1c85382d,66fef14b,3cde617c,a426996,614c328a,ead99033,7aed469b,8f169d9e,58c5af1c,b236e6a8,4f58702a,b727d9a5,e2406a4d,fdbf9113,a8f895ef,78a71f9) +,S(2d8fa9ed,d5fd67b7,42e5c2d5,2c128ad7,eec32cb7,43cba12e,272edfd9,4f36b5ea,71b15f39,37eb2a09,f9533af4,bc964c32,23145340,f780731f,aa9ad1d,8f2cd37d) +,S(4f512379,d9f6c596,700d0a15,950ddbde,40ceb1c6,87030c95,4c538122,dfdbafb4,54de9b05,f864df5e,ba861980,c7dd8567,4b320afb,e0381674,c7f7c083,4248c05b) +,S(9a5f91ba,48562c21,58e60949,6d43eca3,2c69995c,ed93e834,168d22c,d9e7cd1c,9f88a3ec,c668eca2,e01b1126,6acf9c51,29bfa33e,e12f7638,2d40d2a9,b722b86b) +,S(dda30502,d417fae4,c4ccc6b6,e833b75d,d84d54fe,d58fcf0,6577dd8,52f9f610,fbb88dda,2e74641e,6d45468d,102e2a42,7f4c57a,6c7fab0c,5d4dbfc1,155469a1) +,S(8d2e9e7c,5586141d,848e50cc,631ce5f4,600dfb1,618d65e8,e88da5e3,5b26e117,989c39ec,ffd67c54,d55ab4fd,85c2a556,bb72fabc,f763c9a9,e33a1ed0,251aa86) +,S(726ce076,e6b63d6c,b071cee1,c3d1da27,10c911cd,e3d59bbf,a27a7ca9,641ee995,4e41baa0,c91ff8d3,4d2d01ac,d8ab5d36,6ea5e81,d489595,1c49622e,610af9c1) +,S(debc91fe,183503d3,fbac0dc2,c9e95062,c0d42971,ed2e97aa,27dbacd9,bea43a1a,13593715,a6fece9a,f33b2ab8,d5f26e6,6dfdf3c8,ff688100,d497a333,be2d2f11) +,S(c5394335,77914ab8,e7039e8c,472ff2d7,237c794e,d6b24f41,c585e910,f0fd4b28,2805359b,628a9c4e,7b304112,80aa2a0d,23c26cf6,9a47310d,1fc6fc54,cd26087b) +,S(9a2892fd,33c300b1,802bf1fb,e8a8faec,72b81810,4bee4e1c,c998bc79,a05f29b0,997f123b,c2fa0136,522ebc53,a5ce37cc,5538705d,f5fa8beb,b37f72ff,45186e33) +,S(d4a22cac,f224fbe,7ed7fe42,7e0bf180,1503bbbf,d73de79f,4c558104,b39a351a,8268fe97,30622e09,2a513349,548e346a,23260311,a82e860,341af6b8,3ace752b) +,S(4a4cf3ff,15adbe1d,8d414963,b0709fb9,11d4d2bb,877dc03c,77594fb,9cc11659,57c84583,36f1952a,62441810,ea64ad3,5109a30b,c39ff36f,c2dedd60,d1ced874) +,S(58c0eced,b580d530,98c836cf,42ca2648,e85e0b27,871caf44,1f69bf0c,158e1539,eaf79c49,1e1dbc94,4e63d36f,702cd1aa,92e54a09,fa11ffd7,4121783e,e842467e) +,S(b0fbd0e8,a60c7e89,38a154f3,fe586a33,26132302,7f4e416f,634cc9bf,724892bb,27ba767d,6757f40d,b54fcb50,104998ba,6dd83f93,137c3d07,9a0330c7,82a5d3c3) +,S(a94ae12a,26b0135a,125fecf3,e4ef1844,ee90c2f7,84cb4081,8c16d8c2,d992f0d3,a37447ba,665e7595,c7816a6f,6bba3d66,e046fe36,8877c95,bbc8a760,218e2050) +,S(8cbdb09b,3eb74fae,32b6c484,4f9004dc,c540e240,7305aeeb,9adbe308,8cdcbeb5,2b863a2,91f6efd2,ff07b14c,4e5a169,912df745,1b49e3b8,10e72cf4,34c932fe) +,S(3f8cfac3,b70eebe1,cc6fb89e,d508abd6,ab3131c,40d37afc,f8f39c87,34cdbac8,dbb02111,846ef25d,794b303d,b48964b5,a68b5287,b443d321,f0c493a1,2d58b65e) +,S(b61604e0,cea3e79c,12fe9a4e,1816630b,31fcaf4d,b3ac84b9,547da60,df15b25b,1aaf2bad,9ea0fa5b,56665b41,ba1264a4,317d5388,9018d92c,ea2e9d98,29b86801) +,S(eb0e7410,3c6ab38e,1c26630a,7fbd68b6,fa51bda3,64d1ca3f,7c86ef0,451327d7,dfa05017,57c4d3c1,9541c9c7,d9fb7438,45cdaacc,2ee377d4,4c36817a,e0e82e6d) +,S(636fc503,be51e64c,8dad2812,6762c04b,1fcfdd7e,4b25544f,4bcd0bf6,9556b7ae,57b83b0f,5104149,7f3b6735,a8b7d886,b633c8dd,5052d1e6,9848703a,313f4cd9) +,S(2fcc70ec,4d42235b,c6afc2bd,1d2de19c,5ba9dc65,4ea3e288,c15c7358,e52ab330,6a356018,2bfa1e22,db64cbbf,cfcdb695,35bde8e8,2519d069,39577e65,256a30ce) +,S(115006c3,8d38b8bf,db8969eb,d6bdfa95,83be81e5,bd5bc7d0,1cd10e22,7ea94b54,6043ad02,16eb3fba,9af39e83,f6e87802,3fac023a,73252780,2505a1d4,2080e08a) +,S(17d565a,15ba1c29,60ca2da8,2fe54d01,3756a986,bedc19a5,15b653f2,8db3aaf1,917bb9dd,42040b3e,4b8b05aa,b9d31252,7a633819,33534c35,f274ad7a,9bc7399c) +,S(dcc2489,88501c43,b8598f7,a3e5bca9,d2af8f8a,b482f30e,2374c6d,6b221ef2,a859757d,d5c6ec52,b1f102a6,ef00decd,cd14cab5,99f1eb0a,57864646,4f652e72) +,S(a68b2b9f,4e9430b7,cdd919db,6e808a7f,ae2cf9c3,d43cba03,d833fa8f,351f0b0f,e34b8a32,d3ad0923,8e95614d,92778021,7f45b14d,f2f9cf66,d6525bc5,94786526) +,S(2f954e5a,938e1198,5d2d11e9,ead59539,fe7e2f17,4702d3c2,3190829f,8d0e9462,b2f0d379,fa8b7d40,ba2fecc8,46a393b1,f6aaa6bf,9f89ac61,e55ab1e7,bb16dd5) +,S(223d3d13,6bca94fd,9b3fcae8,6bb2ddeb,3cc33c8d,3ccff556,fa93938c,c27ffe4f,87e19106,e317187c,c256f7dd,83d6219b,27f6cd8a,53bb4ec0,9c74ca58,51512915) +,S(5591d8e8,291161b6,43df3a3e,9b4f495c,b614432b,a0f3aabf,517834ad,9e8f7b2e,2c8d6a35,f6267e52,d9bd454e,bba4719d,30b3fe7e,c40a1416,673ef594,e6d07c2) +,S(eb2cfc4a,d15d1a14,870cbaec,b9e9aefb,4141841e,2e4e6252,c8e93751,45f29a29,78810e08,10bfd992,b7b04c79,c7650150,e62f210d,6d35cb95,5bc67215,7052e5ac) +,S(6112c3f9,9680a818,5e4b1d4c,539cc436,bdcdb47d,2e19f927,d5e3e9,eca3f74b,6e860bdd,723c8bfa,dac8f9d4,1f6ca96,f2579d7c,6a690f35,3b8da52b,98da4403) +,S(892120d8,d552d8b0,c42c23b,9a0f17c3,b9b32914,d7e31579,7b391ded,a7d58b16,e62523ac,b3c778f2,f913d1f6,4bdcc037,cc4a9496,ccf0cedf,32502316,b5cf7941) +,S(4758b456,217ad3be,2315583,963044a5,60ca4a49,168461c5,ecbd1e91,1fc4dc0a,99e4255a,4f30973f,57eec6a,1c30ac1b,bb74987b,3c4e7ca,9604878c,d9d83679) +,S(ab0422a6,9a207a87,97fa0c6f,978479af,a3b95dc7,d962e143,b99e7575,6e5629da,73398d0f,fc9855,ebc280c3,2b8dfced,84af0f70,4994edfa,7a06e2e3,a5823faa) +,S(1980432a,ccb90b14,30d0b4c3,5829374d,852cc7a6,f0a1b20,ee7ad43e,d545d227,96ae3873,bfbc8ceb,2afd1a0e,9b989bd0,69c919f8,f2e51546,7668da5b,9e8b05c5) +,S(4288137f,e2dffb3a,ca761cd7,2abbef3e,93b8a015,743d50cb,b716252e,e0e93f17,c02c333e,36c366a6,fbd855f1,4da07672,71fddb04,59e788de,456086dd,aa238825) +,S(d65fac35,5bc89da,afc4d16,aa73fa4,77e43276,e0db7d3d,52d9281a,d6b6cde2,e6f4c975,a6c5f337,b4500545,603862d3,8e9f07e4,18886b13,5678478,c007383f) +,S(7029b144,e62dd27a,4fe8b54e,1607936e,beb96784,d1b294c8,43e19978,b98f6ca7,8b10ed66,58056c6e,3a2c90c3,855444f0,9a1af347,c73dd14a,a478f2a6,7140a25c) +,S(4f2760eb,df969bdd,e80ea87d,a5da0c19,fa343e4e,44715711,50295b43,cf9183b2,43e2c17b,f3f9ef09,fa01fd39,b8f69b69,15d8625d,4daff425,d4629677,83e28167) +,S(cc996aad,db4196a8,f355f0d2,3b9fa539,b573ce57,f2ee7e52,14372615,c374a5fc,b1c40f87,18782935,c30a9cb6,6be85d11,44284bad,bfff9923,2c09f2dc,a8ef28d) +,S(c7818ad3,f3e3d905,b2c38e39,85eb7091,cd9b3285,3bdac631,3cf4303c,d54ade42,55574c4e,7bbb850b,14763fb0,fc1443cf,3403a5fd,d1f5f937,8007fbaf,94339eee) +,S(6cd03584,6fc48ebf,f4344d1f,3ae5d258,9a45dbc9,e779445e,52a75737,2589c4fd,afa85b7d,b165e371,adf67dda,8e4d1fa9,4d811c92,8d2d4723,a44e8cc8,93416e34) +,S(d652a205,f716b1ae,632b7235,91152314,f5231b92,474dcfd3,bfaebbad,443b2e0a,d2198421,b78240f7,cb82f0d8,5de03d8b,c4646a23,ec166dcb,a458a06e,b93bedcf) +,S(a807d04d,cd844a1d,f99b3e4f,e3400459,81ff0baf,d34e2d73,a6a052f8,dc52fb54,188a78bb,73939835,3bbe5079,ffbbc718,c385c047,97cfb151,af019e9f,a2e2cd9a) +,S(1efd2bbc,a5d6ad48,e93acd07,d6cb02b9,b8c3a95e,9f4cede2,24efdc17,cc9eb2d7,f951ef88,1b98c7e6,357e191a,1bb357f6,2a9d2ae,a8af1a05,63eef3,66745b39) +,S(5bc5e54,d27d3db5,982bcd04,497fe0e3,ea0ff13,7c3bdf66,6ed0b9ac,2395888f,3555bc02,d4f4eb01,661f8b85,7321b36a,5a22d975,2710375,4c1f65f2,82ec3300) +,S(f600a8d,26b08d0d,e6e2ea80,e8ad2f1e,158cca71,15be6f22,1f5b808f,746a3247,23be5a13,4bc3fa5b,7ef75b2,8e8e11ba,76c753dc,6516caa3,cd5b3ab1,8bca3523) +,S(fc7e4e0b,2ab2a7a8,cc5712a8,be590135,f5119bc3,6c73f81a,e492bd26,90ccaf7b,4bd612f4,1f274690,6ea862b8,a6dd8929,e4a682b5,aa835cdd,b31c90ab,381151a6) +,S(51325f3c,fe12d00b,fac67eec,d79b63e5,41641d58,76aa9700,bcd3b3b5,89442655,d6a894ad,7b7ae6e2,db962360,579657ff,982a35e5,91cc3b33,a4437a4b,133ef941) +,S(2db3ac27,1a55f608,f21bd2d5,717f003a,afee9a6d,b8fefa09,5626e4a,c598aec8,c526bf33,a0c01c60,c1cc9fc9,d66609f5,3c662168,b47cfdd6,e0de0c88,9bf9533e) +,S(9080772,93deb01b,5eb05b55,47de4321,35fbd436,3f391be5,1e1d205d,d5fa7dcc,fe961eac,17243337,653d318,b5c62159,64dfef84,d3cc3f23,e034c102,5ed7442d) +,S(32a1ad81,e5a64fc8,2dacc03f,6790cd4f,45557ad,3d3597cc,e2ec37bc,339ed9d6,87abcf68,18010022,7097b63c,a795cec6,79cb55d8,a9076cf3,d1371062,627cb07a) +,S(f7cba8fa,58689c51,a0f1af76,971d17a9,8c5849d,55b396e9,a3771d17,4d9246f9,f4b0aba9,10d5a9ca,eda4d733,35d5fba2,5309a0c2,fc83072c,ac37b9ec,af58ee45) +,S(cda6b104,2da900d9,d65b6b7b,c0579a43,fab75f55,ae7046d5,8ee8af82,6329ea81,70c86c0e,acfd7401,5a1171a0,1e3601e1,a8ee20e2,9ac7c0fc,68d6f1d,cd1771e3) +,S(a261a640,9c5b1ce,9a8f27b0,544ca0bd,a46f3bca,d11b7f2a,c23878f0,f67ee58b,1e26a71d,4c42dae9,b4e9cda8,fd33d725,85da67c3,52594d4,20c6e410,f3fff888) +,S(bc70c967,fd7f842c,c018e885,d1fb6d34,9435aa3c,682f6884,6b394ba6,e9f4db57,a2b99d3a,837e2de0,c40a0784,7865701,3032efc4,87c47e57,18d84e11,f8bd9468) +,S(364152f7,5dc43149,4cbfdba3,ffaf234a,c7a26567,1051e026,9c60389a,7077a9c2,ac3ac7d9,f4ec8543,3038ae4e,7ede71d5,3c8fa601,25bcd8ea,e084c32a,546d265) +,S(52fea4be,d57d5d58,d92f59d8,e4022df9,d82ca42f,a3d89326,cc36dd96,94f3043d,b7e98328,52f98a75,f738f9a3,7a67b39c,5708c608,5b6ab99b,2495428d,8c4feb35) +,S(34fee910,c8bac880,f973a096,a9ac3ffb,9c32ecc3,d2be3ce6,7b8d6822,863e1a4d,e0f01096,9c9dc446,c78db14b,122e260c,2231f6a0,971d08b2,24355620,689c7a17) +,S(6af28f0b,f4c9d2e8,192424ec,31f076f7,f815ab0,f476a4bb,4019b3bd,db49c65b,2c55fd2f,bb663b31,1a9aa346,917f6064,17d1e1dd,bca45d3,f1350feb,6ea45248) +,S(70b6ab66,39e4b41e,644f1b6b,6ac5d36f,a4f0ad81,3baec03b,8bc74f72,4d320e46,ec6409e6,4f4e4fcc,d19ad5f1,96d3cdd,96f7135d,dfcdec95,23780c18,8a913a14) +,S(ede56f11,4ab975ae,adbeff50,ff7dbbe3,614196a,138600bc,15508481,a065724d,9e7fae4c,11f421ed,26d839dc,61b0684b,71906b63,6efdd73c,2dadfc9,5336ecfc) +,S(83c34c3c,840a7310,3d819d74,66648e66,5de54af9,f1683efe,6857c3e4,556df8a4,9c238041,562dd6c0,eecd9771,9ce2eed2,90aa8137,f109840f,d31d70a4,c86cd10) +,S(aa2afc90,89b98,5228cf03,205e87a4,52cbdb45,24d377c6,1020593d,a0c7e200,3443196a,b382ac19,d3d3bc4f,a3161e00,6d812924,fe8a86af,2db5cc27,96be01f4) +,S(e42ec7dc,4310cc8b,9f2956a0,2fbf71fb,e90eb045,881ee800,e3a75730,4155c520,939ef2cf,a52d91cf,e20324bb,e8da54d9,2d000945,58abe7b6,93c2679c,d625336c) +,S(bc0bdd24,937c5200,fd78de47,a16ef9f4,181617ab,267fddd3,4a3c5606,32ec2b21,db04a4c,10b521f7,986e0e1d,192b0870,4a028511,205d7ac9,df6d2993,52b63035) +,S(dc88c9d8,9b43a733,5e310fbb,3f760e29,55c005d5,640df990,6264ebae,adadc8e7,2d6779e4,6f984794,65bfc677,79feb7b7,3fe37b32,cc23d636,25a3c8d4,fc2fc512) +,S(a7ae0d8a,b0c932c6,2ff0cb02,e05d76ef,5ee3dc50,88c57210,f6f9e349,80111c20,d632abc9,d63162c8,98b9dc94,b321de53,ac8dcc45,69233cdd,1d07da1,92e553a2) +,S(4620236e,e7bd6eab,db203af7,57da6e64,d631ac9b,a5f03215,592a5acc,5cbe0e97,5df4244f,69ea1e2a,6cf30cdf,4fae66a2,707851bc,7028d8c8,8fa97690,28627c6e) +,S(804cb84a,3d8bd930,51f50aca,cf932301,5cd35fff,349d8a38,e2bd991f,27d8f671,4b77b812,9ee0f835,96ab2f19,20362128,cdc39552,bbe6d267,bbc9a8e4,70ae8d3f) +,S(6ea5370f,5382b2f2,b801fcbe,ea463912,b4f6fb4d,e207237,8e71dbbd,b91c2ed2,f5b4f909,d8f3ff08,e92a002,f1959ec8,8b513ee2,d37825b1,a8bbe141,90b2d88d) +,S(d8b8de1c,4ff575a6,12bb0852,af61c6b3,1ee56403,b81a1f47,69fc7072,a2e22ba6,1e3c4190,d37abf89,896ad827,55c256e5,f23cbdcb,47b05892,8d538df4,e2468c0e) +,S(66ac1864,4a0bd6e,9c73f3ea,43a00d6c,80d38467,5080a9e,475c8291,edf1b147,2cc60c0f,7db6b776,1503efd,551e1a36,9be98ec6,73dab0bc,a61881cc,4fa1260e) +,S(47194a2c,4ed223e7,7663cf9,38b5a5ca,f2784435,c375d85b,ef3c5367,3f60e942,b0fde11b,5a64dc13,7bf2738c,75027d57,5808a3ce,abdf7604,5f4484c0,d3d9f920) +,S(1141c859,9af2d983,88274742,88dd768c,9fdc1b2a,c5f06290,10bd3cf4,2a4c6186,7a431f47,61ed4613,3317555a,578d0f8,5392a0d2,ba98ec64,d6b508d3,eef0226e) +,S(f905bdd8,e80afe9e,d65da689,bfb8e549,487002d6,16ac651d,4ba300c3,e7496f79,1ec7bf7f,3bfb5045,d461b03b,a7f05067,cd999fc5,f9f4c0fc,a7e25b19,77bfcf72) +,S(ba54b8e4,fba452ee,23c4faad,b14f0af8,232ea62f,ad47a3e5,573f1fac,f15e9e0,af556ae9,efcabbcd,bbd8e48a,82ac80f3,9c96ed0b,11370b8,da1bd4a0,60f5cda8) +,S(59d3ead0,561f6e24,30e87f3c,f361a2b4,1494a042,3a775e9,c08a28b4,a26a80a,9b26f47d,50a92229,c28a278d,427c7306,f5f1ba1c,c2d095d9,ac51e18f,a9bc8) +,S(2a6e5a3f,ab4cc928,d8f2924b,e7e0f3cf,15520a08,eff00f5b,129d9070,ac865d47,55c0350,58727023,86d19196,4609351c,919913de,e93800cb,38b77183,5ca625a5) +,S(898f50d1,c35bee41,88afe91,842cf659,fff1fb1c,5aaebd84,6828b002,a8907502,b2456e80,c97c2ad0,1ae02e49,6b84c02,fc9bd0f1,4a3c5a79,dafb8f8f,62f3267b) +,S(d1854ab8,b49bf0cb,1f9d2304,e9ee3cd3,bda5d9a3,ac04fbf9,422c4671,d6af85a,4e2500f,d8818180,5b16a077,53eddf34,d7bdeb02,17df7fab,d0afebe9,47155c20) +,S(861fb88a,394db6e1,f03cc787,d968ef7e,4a417df4,2856d303,a3edfc66,feaf4680,a5d7e95a,ab8b0b13,23fff11b,638ce02,68f3c38b,dbc018dd,dc6d2362,a135da6) +,S(9544f768,b9fa9dfc,3c155d90,b676cf7b,ea526903,39fc111c,b0ccf62d,813403d6,cec4d92f,cbde624f,851ed21,bbf5154b,28d87603,5e302902,53e99670,806e047f) +,S(f7722192,f80a66be,23cd7b07,89f3a094,311cd40d,3b7149ba,2cb5cca8,d1db68e9,41d0e9f,3243d64e,73e26661,cc851e5,1c11e320,277f7462,d40efe0f,c81b516e) +,S(876b4c65,1f88729b,dbf9927a,89ea91e5,b6bd8e7c,439f6fc1,be9e07ad,698e14ed,ece2cf81,1cfae9dd,cf787b88,f62f2537,7b573084,86ab84e1,6ad31ddc,f96b49da) +,S(706af4e4,62249924,88461427,8917899c,721be8f6,3353b127,b7ecb03c,7b70b10,c972d972,c65d200,e695bd29,813deb74,cdcf0ee0,e612f545,aa6506e9,7e58a5f3) +,S(ce97a218,c9c96262,b5cdde0b,a27e5f4a,4301b75b,f9d17dde,f1495b7d,f3863c9d,e9398e1a,20fd1426,88916410,d7af68f1,c12900b2,72b03f55,c5770aca,2a1ef10) +,S(fb625b9a,92cf831e,886a1f01,c2db3d53,7dae0feb,e9b3d9bc,a8fe6449,d53be895,7f783e74,ba569e04,a29d68f,12cbf223,1fe2a8c2,a651f44c,30d597de,82599a37) +,S(81ffbf69,7a7d2b8b,51b9098a,8833244a,f126c6f3,b42ddbc4,c6b2c5a5,55f4747d,e2c67357,982eefb7,3213d530,3cdaaa7d,90b4d1de,d0fd4d0a,8b002162,f006f33b) +,S(6dfc0f66,8c30ab7c,af16d4d6,309ca2ec,679d6b77,be695ba8,c0f31b55,6a0ed0e4,a41ed2b2,d9a0aa74,3182d7a6,20f441e9,36772438,bfddfd90,5aeff87d,b15a563c) +,S(1c6bf1d1,b953e56a,ba1a9b5b,f63c328,1d5715df,88bcc23f,e77f94c3,3b501b44,c667214d,b4ca1782,19c368b,f7c2ba4a,8f1e74df,91a22d3a,8e336089,e4e4b0ef) +,S(b69112df,5d999f60,5d863231,9144d2f3,5417b9f0,d1e78ba6,b2afd247,fadef93d,2163cf7a,302886e7,70fafeb,8acaddec,464f115c,89422020,9a034c63,558df4ae) +,S(bc038732,ac230f91,7c58b8fc,f9ef9229,9737a2cd,8e01687c,da464bde,4976b6e0,3392601,796373,603e1d6f,a7e23385,7a7ae0d9,df638ab3,7191c046,a25682d2) +,S(96df3295,1047ad4c,6aa4d9ae,e59bb00c,7489c20c,aded01ae,1833ebda,27e32d81,418f6c2d,74ce633c,181189bb,f5d0f066,cbfaa8f1,e6674466,1818c4ef,e2e2034b) +,S(a3c53227,939e40ab,ec6fcefd,eb6193c1,cb6a65fa,2f3501d2,63cd2fa7,6a304979,4468caa5,498ea6f1,92f29ade,37a2f667,f46798,dc600de8,cafa0ed6,dbc967e4) +,S(93fd8207,3dfd6d6d,6b85f1b3,1e172a61,7a0c7d46,b91d5a92,601af0ad,2545eb2b,601beac1,9a8a6a41,1bfca863,6acfebb3,9611559b,20b8a866,88397d47,d563a847) +,S(ba7d3bef,2e2c63f1,f9acef,2468ad8d,a5bc0d9e,b45e4a2b,ee87a0ba,86ca0a9b,ffff9a67,33129e31,10d33ed0,bc5b6bd9,376f29b1,7bbf2e09,7c6efcae,a55114dc) +,S(e0d955c0,2a4f9c35,97597258,2964d7a4,218898fa,97ef3011,1904290e,36157a8,176fdf9e,7d420bb9,a0782f0f,8707789,b28cbc69,d5a6797b,aa2bb985,1c617f0) +,S(16b2c140,8320cb93,112da689,c690d6ab,6cd226fd,e1752dcd,a444750,bff81ac9,2a2face3,dafd3932,f2617488,faa17b6e,5025f792,53c65edd,2abc7790,d98bb281) +,S(2fbb0432,9c823e2f,645d61d9,795a414e,220db4b8,eb4da0c7,fc22bc10,e9f502da,1adf66ef,15eaddfb,abbcda69,c87068ab,cbfe58e,69f58246,a0ab6259,90ebc31d) +,S(649134da,f42d2579,b6522f2f,404d6456,c178f883,8c9ddccc,e132de4e,67208ebf,4385abfc,3c554bc2,78844648,a9aea5a,e7709b51,fe644e8a,4a756c3b,f09355cb) +,S(b95544b1,dcb81f9c,e0601c17,29c7fdef,128d62b0,b8993023,dbcedf8b,d3991cd,f871fadc,ffbade32,d51f2d45,4f0726f,206fe760,93c0ab0f,33cc5383,769dcd2a) +,S(cd403bfc,5034d0c0,a23df5b4,a4b1b096,ace1ea17,288f89f,d063c0ca,5dd668de,c1296131,aa56f46f,49f59760,f3a4bf0e,3fa92e54,a5d8f160,54ee1fd4,26717742) +,S(a4aaf37,d7f8bdc9,90202074,c9a8f56a,1ad78479,95b4d939,4b6ea478,3c04c581,4cb3b6f2,dc02b61c,fd2594f9,40773d73,1a8cb9cb,388af431,9348d3,af16da34) +,S(57102ff8,ebdf048e,85edd3c5,2864578e,97478fc7,e6e7b937,6c37d9f8,abf438c4,c84f1d9b,eaec1962,e79e308c,251b2f31,915aef16,90ab5128,8331d8ee,f8161d4f) +,S(68fe98e9,3c5c5fe1,108c08c5,8fafc701,12424685,c6809774,832b0623,a3c9b6ac,492ac417,fd956b87,ee8078e2,c46f21e3,cb5ea58f,ee871cd4,d6480cf9,c4df273) +,S(d4bbb6,9ef5e23a,f0932cef,2eea4ab,d97baea2,b0893d43,ec08be40,2a4a5e77,5818e60,9c1dae31,f65e223d,f0cd08c5,9e74884c,2a2dc166,607fa4b0,47c7c98c) +,S(e9627957,a8eb8b72,7f0d872f,28acc53d,23a5c53f,763f3b5d,68c7e690,5a83192a,5da92e7d,dc291696,d9466d17,d4ca6cca,cab1057,4f5a08d6,6e59ba87,cd0d984f) +,S(49f21cad,a83bf2eb,7c508ffb,70f9fe84,1cd547f2,df83f207,6dd2382f,1711caf5,1c7d8129,5f834ed8,ac73afc2,132e6eff,2447611a,4fed8114,ca18925f,39f31931) +,S(58282a9,40f61d53,14d1d110,c18713d4,6c34a8cc,5b0ff64d,fd6d0182,aefa792e,7855e155,d3e0f2d6,52370145,7d83d7dd,2a96ee49,3eac091e,677f0a34,105f6ddd) +,S(c9c97a32,4b07027a,7b5db6f1,d70bec7d,dc3a14e7,43d492e5,f5569199,23ca118d,f601f40f,894ddfe1,c2b1e99f,7c2032b9,15d600d9,e2ec41e8,747d74c6,9664b56d) +,S(9e4dc175,8ed67501,86a7bcdd,a11f9273,9bbbe0cc,aa72862b,8d515a21,159e054e,ca11c31f,2bb866a6,be0736aa,19b7e36f,fcf4f4c8,715ebd3b,c9483813,cfc6c0ab) +,S(fd063789,3ae0030b,cd8c1e5e,8cdfbdda,8e5af1f6,268f552f,7a7f0c6b,8aafe2b5,8c09eb0b,68d744a,20468a8e,4326dc01,f4a35480,df1a0435,b2e21d53,dc8e676) +,S(37dfdf3b,6e7a7651,9ba81c3e,c1377580,d85360b5,b466ec77,b3f2b272,fd4af04e,cc3137b2,7b732758,d78f3b07,80129e77,43dcd85,ec941727,ea3b4f8e,d0fb7844) +,S(45ef106a,c8a5e25c,771a2f18,bd2be0c9,a69cb49,de16d8ff,e72a45d4,6c1dbae0,cad6a40d,742e7db7,3f7bd452,e0163490,60e5681b,31918bf4,2ad8b698,220ab158) +,S(258c52f9,88b9ca25,73cde71,472bf58,99648cdb,c1052d14,be02469c,11fdfca4,4491d88b,26ea5c7c,6a66c9e2,1a5b61fd,d60d0b8,8394cffc,359af9ec,29939dfd) +,S(bc92a4a7,727c4e36,3d0cddb9,d36f1d9,d4f8ff67,de881c83,afd51193,a9e65217,76ff6a08,b18b4795,61f1c024,d464e9c0,331c22b4,ba3779d7,9dd13122,63aa5120) +,S(8a19e8c2,58c04834,f11ceccb,c156bbe,23e4e837,fb5ff353,249c12d1,45f27ebd,15fc6c70,bff48ea2,c56caca,2b978fe1,8f50a9cb,85c19f06,5d65e507,e4e92c1a) +,S(e59b82d1,ab90344d,b113c1a7,a39968bf,e6f3b1a8,c2a44572,d9c911ea,55d70eea,91e33d8c,d58c6a1b,e4df0bc0,12eaa76f,6634d699,814b80,cc22afc8,313b91be) +,S(f994ee5f,88244cd6,bc417db7,2f941bea,f3456d2,5dacbeb3,330031b0,7371a7d0,9026f86a,ecc299b3,302bf9c0,4dae48f7,d9c2689f,42707d40,51440a05,ad9c62e2) +,S(776c4c8c,32d1fa50,27b17bc7,9803d121,8000cccd,565d95ff,c1e3a693,7800410f,40ece234,438e7738,6f8201d5,3d3e319,988b64a6,38413803,165f0bad,c8785149) +,S(393675a5,dd13b001,29caea3d,8bf25730,32c1968a,c5e02620,fb83fae5,b5c9b12e,39e6cfc4,793400ce,ed16ff4c,4b0ebcc3,2e5dc773,4e742dc0,3784a69f,a75a8b00) +,S(d7cdd294,22edc7b6,2cdde130,e90be1fc,94dcfdf2,7bf38eaa,2f09fa8c,c3401b1e,dcb9cb28,73cd18b,b74ca141,dc79eb46,728bdd9,8bf14302,db5c7065,354fb184) +,S(bce3f127,2726449e,3f620671,824949d1,9026137a,9885a1b9,9cb67dcf,6e56bc2c,a4240017,ee92dda4,be968f04,ad125ad,1c33c37d,c52a497d,296d5786,e6e76217) +,S(9df098cd,efe9414a,79adaf44,21e35faf,70080137,74399eb9,738dee97,ff5d6e52,6bf9235f,ef36943c,d0f17bb8,6917d97,f04bf4b4,dbef1baf,3b788eba,51abf15d) +,S(9958582e,e561dc4a,9a4839a8,292713a0,5d88ab4,72222522,e8dcc94d,b3d43f1d,e0958a14,b63af23e,86f76cba,2259b37a,850008b3,43b5cdc7,8cb4e88d,68c226a) +,S(3e7fb8ce,7d7b279e,7d292447,c88c048b,dda93379,5233a871,bad933c4,6dfb1f24,4279d08,34108239,2d77a5dd,906ba4be,e36352aa,9385f09d,2296ecad,648806e5) +,S(1cd05450,f7405a11,cec93ee,7826cf58,97611d69,fcb681c7,1ac0a6a3,75e8ed62,85bbc70,bb52b040,d620a3a0,20b9536e,5759d35c,9931936b,39a203b,af34d0f0) +,S(5047776,32145a3d,f6f87bd0,1b81032f,93cf99ca,fb4c5e3,c76adbf7,d7c9b367,7badf59,919c7771,89eb97ce,6c71f418,a0e67b23,884cbf7a,1ed60804,57d1d2c3) +,S(1ea912c9,49b64ba8,309b8d87,ad1498a4,79fd302b,f7f2f0be,636f7a0e,4470e6ea,9b279fdd,b1211de,8414896d,3502ae8d,4acd50e6,cf83ab4d,29086d0,42b7650) +,S(9b3fa0d3,4b00076b,cb4e0b00,95f03c4b,e1ed329b,d2f4c7ac,8c03028f,21a01628,10117a48,b2a58ef5,2e0d5dcb,cec661f,8cef81d5,50efdf41,26e9527c,27d420de) +,S(65fef7b8,1d39dc4,b3ac7f7f,5bad14c3,6200d128,d0257e22,ff678fc0,824c94eb,3021e1ee,680c4fc2,77373b9b,36ef276e,f2dcd6ec,7a02b2fe,3259af09,2708b475) +,S(3e77b23d,af763a55,644c0f2,bc2bef5b,6ef5e1bb,8fdedd46,c5a2917f,7f85f9ac,55b278e9,5bb07879,9c7f0766,a2db2c79,8d4fc785,10fd021b,415b3e4c,2a4f3221) +,S(2ac4dabf,2fec922b,c4615fba,1cd7d352,f69fbf8a,3232f783,96f8c08b,21de2965,2c33c017,76238bcf,2be6018,7f85a518,6d649425,1eff089f,a92f3eac,219f957f) +,S(febc8a20,67da04d0,855feac7,42b2cebb,748be0f1,97e31558,68d54285,4d62c66e,aee39287,3d45e63f,f9a9d583,e105a771,e3db346d,a262bbd1,a554a8d2,65d96083) +,S(a41174b4,a5982751,88c2d10b,d5c5401a,2654202,dc4e38d3,e1c8f689,8606a569,bc6b63b9,9fb5f85e,c6965337,e82b651d,6b589f2f,8d90f67e,3bd087e9,1f732a00) +,S(122196cf,5d10a3af,3bb97fc6,d12f749a,907c194d,3caf2ae9,3a3a464e,5a5de220,ccf46742,b3c1e213,544e2c7c,59423fdd,674697c5,d405b2b9,46fc6e92,9304e533) +,S(77bad5cb,104dcc7,e1bbfaa0,8c867761,9f93ec61,e8e3b73e,799b663c,2e1eadb3,889747b,ad8bdebf,48e1214d,df2522ed,4023fd8c,5ef08fea,411e8609,c6faa3cc) +,S(1e8d4075,8c49ad41,6ad45163,73327e6e,4e3f6c89,695e15d2,f5517ebb,12d4a98b,1d16ccb0,730a619,c9b379a2,ecbc4f83,98d94aa0,d4881cd1,25968160,e3b09f4) +,S(c87a656b,240241dd,487f4974,afb5b535,880ff2ac,f4a028cf,b1869fa5,fbb6ee42,16f25f3a,6fac9538,5ed74412,fa6a790d,34f694a8,b4c99cb7,6ddaff70,be757beb) +,S(96b01407,482c6e88,e9769944,cce16a05,669adf16,e7393b80,71fbd9c2,4b55a4eb,b32be280,590384f0,e08d68de,38688018,82b786e2,1b178ca4,578bfffb,94b50223) +,S(120f68b3,739562e6,81e72fb7,46d08f54,b2afd162,22e1deff,7ebbf884,6dae4af5,7c1eb74f,2b2376f9,477c6729,bd90e14d,2f4da9d,615c8743,dedc1690,300bcc78) +,S(e64871ec,2789b455,8608be2c,f248fee8,49a4411d,285c0989,b65c5dc4,e6acd157,2980b2d1,4999b0b5,5b79ecfd,45ef91fe,f3dbfae5,d02f2145,84376294,58e10a6b) +,S(608b1009,b20d3e2c,25324adf,c73e5c86,43daa1e2,53a8d266,eb43863,aa6798ad,826e5a03,ad5c9638,51181c68,ccf0e663,a021e13c,43efc38b,3b4fe2c8,8d0e13df) +,S(8c978155,8132e45f,60a61435,36f4c1a8,cdc4dc2b,6850b3e5,7c65f841,a1bb152a,ca3b3098,394d81ef,a9083c5,3864f194,1875d63d,9c31b44b,a6ed4137,db7460fc) +,S(353591a,c73b2482,f8d8e731,ce01106f,10072757,68210627,f80c8f8d,9821bf3e,2b7e3d1a,501ab469,ac6306db,2608eab,70ae8981,9f44bdf9,d4f84c7b,41eb6412) +,S(eb2dfd88,ec357372,ece70a67,178fce32,3c387b7d,a9fda978,b05dc430,9cd78857,6f2bb6ed,1f5a5521,c441a8cf,9852372e,3dd7aa7f,ca0a1f63,18c47ef1,a24b88e4) +,S(a41c0ff6,5db1050e,6998f3b0,7eef66dc,abd72ae9,8672c487,b29ff732,992eb279,56fa7b20,5616ff9d,f619d7f8,65210727,bc0786eb,2aacc244,ba951eee,99a99cd4) +,S(8e748b35,f5bb1500,ca45917e,859df11,615d85ad,861bcea9,41524e57,a2217e92,55413362,e226c6a7,84bf8604,3973bc50,825515a3,96cfe66c,9ef75e3e,fca46df8) +,S(a83f6007,cce70624,73cde2c7,b7ec7bfe,bc506c27,ccce7708,f35d535c,26dd17e5,ad48ed2d,af217e5c,63397a37,9d50d615,5a1ac614,887a2cbb,26c3b74c,626af268) +,S(f9ed7a92,7e451624,9380246e,bfd397de,5cf208dd,b47573ab,f118afed,1282d2fa,c1574616,3a6f30f7,80d5d53c,670d380f,3c84407,b4be5324,87bbb5d,c8237b70) +,S(a2bde78a,175ec7a6,7f917707,8f09f812,c7dff012,46c5255a,f0112672,6c2ea08e,7125698f,e82d4c0b,6d7d2741,9dc503f9,3b5dd62a,a5db9e20,b091323d,c9ca12ec) +,S(ca8c05c7,9dcb6736,905cc0e9,b8e1690b,6b37da42,e1875a56,e62ea231,bf9899b2,504c51ca,1e19adba,66560c1e,3fba9caa,2751259d,71389996,41d0f19f,1487534c) +,S(fc106ee,61db13ac,4137ecdd,15018278,61fd4b21,c979f97c,617b019,54eca02b,6da55a28,4fc26638,2afce9c2,cdc5a2c2,971f2cd7,5c92f08e,6bc99651,7bbef3ee) +,S(2cb21839,f47b1068,5419a321,7ac7846f,504f674b,c2f8f90b,8b9b6a71,6492a8ab,1feb332,ae75044a,f6807feb,965e2fc8,63726433,45a97af,f1081249,f00a5757) +,S(678c50ee,759c07ff,fca2963e,fba55edb,56ba3572,79970224,5d4f2132,5561f3ae,1989b787,abbf04c1,c93afce2,d389e1f9,780b1657,daa77107,c498bff4,aecba96c) +,S(ab63e1ce,aa2e34d9,8215097c,30b2f266,75d407ca,41f3dda4,1b21c910,824aa6fc,ec65be61,1150ff72,715d3da2,c4541ad6,812eb7e5,7d0f4d82,4792556a,6ce2363c) +,S(a69399ca,fad59597,5a639a2a,31264983,ec567279,b052bcc9,f5c919ae,903dd336,b525c659,c30c4f4d,a7a799dc,c93ae348,1c87304b,63491755,1c43e12e,c50d97dd) +,S(32bf4282,507bcf5e,d25cb5ed,439c82d0,bd7a48af,d3be41fb,e13753bd,c0fc5f3e,cd92017a,4336d9fd,25682f90,be347e82,6773c598,1e80033a,c20bb695,e79bff2) +,S(a1fcc983,7e720096,7203e2cc,11450716,f2fe6484,f681b2ec,5e42e9b8,eedfd862,1e16b6c3,17e8fb89,dfffa79a,722de49e,a419affd,bc17fa96,4ba6c316,31ed4fd7) +,S(d85a314e,69617e50,18df1e82,21cf738b,60485cf3,3abe8838,472b32b9,7f0ceae0,71a0ffee,e92dde66,66b4b5da,a88a79b4,fbbcbacf,3308a4e8,6e1aa367,e00a52f1) +,S(189226fa,688c70e,415b20e3,1356eac2,f5a53b5e,8043e24e,4ee03faa,f20c2e7f,d9bfd8ac,40c7d53e,7bcbe575,9987cf62,fc2bba7f,952e4eaa,1a0587de,f1515aa6) +,S(d3542e0a,6a931162,d7a674e6,32cf2135,32465d25,4d2d9241,ff70709a,559e1330,25e8f51,e2664234,34cbe5ed,622bbd83,dbd42784,4b1f2bf,9a079917,4b57c369) +,S(514d9e86,fb2cb612,1ec6e6b8,25875856,9a8c0a5a,adbfe45f,2876be18,753a2bc5,700785c0,be5423c4,341918d9,f65f79d9,1b8370bc,48629791,45ca8418,57cbf261) +,S(c9f86365,12e9ccfd,e1f1db33,5ae606ab,43f9aa62,2d723f6a,d6d684a3,ea3fe495,30d3a631,3868a01c,9c6f9445,ddcbe3b9,b7b80b58,f31f5db3,a3b3beb2,1e30270b) +,S(226f20c,8fc089fe,98cd96f,a0e790db,641200a7,2b908768,357d206f,2c2deb93,2e23fbb8,b43e9362,3fc2045,24b43da9,5e02626f,ee180cff,1c03b95a,aa5f66bc) +,S(a1b27668,d4b6f94c,7219bd9e,6b8a7e61,9fcc79fd,88d9bda0,a38496b6,cb5350bd,3933fc5e,b6e1c16a,e7aa62bc,200fd5ed,c96b5f74,b72b9b94,2644f32d,d6d68a32) +,S(10f13657,87bc31,1f7b7181,808eb0b,57dd4e7c,1590dae3,8c40df7e,afe28887,1a52e487,9bdc3ec,4e6c570d,91d4edce,291338b4,a79a3995,db5c6e85,e3366d84) +,S(8aaa0ee,a984f583,f9f55861,500dc5ec,f613b3d8,8f989884,273e1841,cdbe3e46,52962154,f85277d,c02c46ab,c2f246ed,24e56458,156d97b8,f2197d22,a133260d) +,S(32805a71,24b1b7,9b397ce5,f7a93a98,dc9472ef,a5b8b4aa,3bd66643,f1c89d2e,af525c7c,b7c139f5,cd2d0a85,82a74ed6,9e23c765,c0b882a2,f4d50e58,843091fd) +,S(c72f10cc,909ad449,7fb0835a,4f3a520d,58db0c2,87f6ab12,cde50749,a9412451,a5666e7d,5197ba9e,37d5ff15,b64b60f3,b8e2ca32,67467030,a7a112d6,f2c7c65a) +,S(6ec768c7,870211b2,415a74ad,c203bd41,72c0fa5a,d4c05f97,c0320865,77fc9a22,18394a22,aa2dbb0,925e6710,549c8c3,b51cbf42,db67d4d0,5da260ce,af1b09fb) +,S(de36ebbb,ff99d156,60506143,87045fc9,a846e7d0,eef91e61,dc93a71c,3ca64737,c5817652,f3cb37b,40647dcd,a476c4e0,488208ba,1b4d0c81,b39a4b4e,900f4270) +,S(f534155d,5538fc68,5ac01ef8,6dea6f4c,19bea322,b46a297b,c0c20ab7,3cc00218,4fab7df2,979d98ca,eeeb38a4,9a2d1253,f9d0924f,14dda603,d3d5706,b3b9523c) +,S(dafdb850,a1db9025,80ecb98,155b687c,8db2088,d0dab521,bc7fcc1,3286129d,43965ffc,ae6c4c14,3febe601,f36fbbd2,7d0ccc50,60ffe91a,a2ef2fef,651ada22) +,S(ac9a0a21,1dcabc85,1816893e,e33cc69e,2efe4069,680b3721,2999f9f4,99d705ce,16ebfe40,8281d2bd,ffa1e02c,2d00d712,acf64eb1,39f5ba88,79c3971b,98c728ef) +,S(afb37bd4,b48cf6e9,5e1eb8b9,7b8b69fd,31ae2b2f,3b7aceb,1db81ebe,98503030,1ccf4164,f8d9cdd9,6f231af3,e5fa313d,c47c06de,ce44dd84,d3fcdb16,a4b7929) +,S(1b902ef,6c294f83,3ab18e7f,21d6470c,f553682d,2b1287d5,1a602925,3888e709,7735c5ff,34e49fe7,2385e9fe,40d66a4c,66ca0102,46c724aa,24b1ecee,dcd69ebe) +,S(6e4e5b10,8a202958,7c5b4ec3,d33220fc,c61b41c5,8c3bf0b2,55e4e28b,7c3133e2,b49f8306,5c336af4,469ea410,648915a4,b55ae504,6cea2f66,f14a99d,9a8fcfbe) +,S(87ce3f7f,bb800210,5b853276,d3931b9,12342d98,7d81e80b,5b10d1ab,1b7e9714,56c6a847,79dbf39c,293c386,9c1e3385,6b71f898,dd46ee16,d1e1973a,4cf0f635) +,S(8724329b,b7ba649c,9c019372,45a1e946,d368a706,2747dd0c,9f6667aa,c9426b2d,44458e8,48d7d44b,5dba5a5b,b0fa0479,55b109d5,21d170d8,9d090ff9,650b944c) +,S(b91befa6,4735c091,32db18b6,b64d7d7f,c6338dcc,cec845cd,7d297f62,b6a1a4bc,bb3961ef,8c9b79c6,867f16cf,be4766a0,15e7ca0c,8f9f340b,14cf701d,e0138467) +,S(4321ea59,332e97ea,3bcfbb89,68a3489c,9ae3d6b8,65cd696c,d8de3200,a0d08fb3,97e480d4,c5149d53,d7582e3f,c73a35ea,3f6b023,5ce50f7e,e31cb600,84cd538e) +,S(dc4597b2,836d96a6,431051d2,5a98d421,7950a8d5,e88c2069,5752ca6,f6f1bc6d,c712580d,16ba30ca,e84e3a83,c35725ab,362bb4fd,e4c42ad7,f9b73f20,53df36ff) +,S(ce644ef0,85ff3009,b261750,8de007bb,c5f19b65,2d9f8992,9972d39c,159a009,9a41d0,58db965,baa00c92,f6409ab0,c9402a69,20a66c17,c089906c,d73cc8f7) +,S(ba1e35c,b6c7b4ba,b81aecf4,23cb8ef2,2ec439c2,584682b4,a7444e01,9936b41a,f3b3c652,f91dde46,3e178d6f,7b17a8e4,1098b33,1cead28a,d2fce694,35bd6272) +,S(b9f98ea0,2a331bbf,60fc839f,845d8f43,6988c747,1902d14d,72ed1360,86e3920f,9fb2501,a7f23a16,cc726f5e,8aa17c12,35d9b04f,a94bb27d,318fb292,c60d03d3) +,S(70591746,55f90f81,c478e702,ffcff930,dc10dbf1,16d7aed0,9c1a369e,807e886f,8267a0a4,b9d6f0ca,db1ec92,560aa3f7,d09d3f41,d1f36f8c,64b95509,b205a59f) +,S(efda78bc,c43ca063,a7b6469f,84012161,14cc5a6e,4e31c31e,b76221ac,c25434bf,7b436ff6,ef45f859,f521b13,53193d13,4cdf8064,449af2aa,92be3781,56fa2864) +,S(229a4b0f,5d62095e,3a630988,c8056aeb,35fbd874,1a2f0e,4306d094,750ccc34,170d33af,491c74e3,d2d694ce,f6a519bc,741acf35,dc6a3428,8bea3595,e234de6e) +,S(c770f48e,20a02132,189d44b8,3acd0f93,f91860b4,81a6bf17,8ce8e2ec,6af07100,7e1120d3,8b2a191f,9ed43aca,3325beae,a6d8dbbf,7e0bf8c9,610f8621,c0266eec) +,S(a5db2c63,3901d52,8b60a48a,20b189a9,e89b8998,3d424af8,eb74869a,f286aa44,b9961d92,6a93d5b0,1a74e6ab,d9c37eed,384e186,8051ba14,46fe1a37,24af1e50) +,S(3ec7169e,9f330288,a63897b7,c168db9a,4b447e48,cea2c5ff,77b298,da41db1c,c3fe974d,e8e60eda,22c4aa34,ed34a4d6,4b3be268,12e58b49,e4477835,f3053fb2) +,S(b733de17,c3311184,d5860d4c,f99e48eb,810cff93,ce92eb77,7cf2c114,fb5bf3b3,c75c0dd,72d20ad3,2000d537,ebb61571,57fc4ace,9f26a90a,d28e1a43,480c11b0) +,S(57d6e208,d555bc24,15d49616,a158075c,27db59e,6a821df2,8b450161,6c2ed278,83870a79,d130da5a,3528e353,353b34f6,74b5d02e,6cf2a891,fca34c6c,3746eba8) +,S(9e4234f1,aa69a478,3bf2fd3c,3208f6f2,6f069409,fdb2faab,8d792588,6ad3673d,5f9a4773,7725ebc3,e8bed041,47a05841,9fb42b16,affec29b,d753733e,288d0653) +,S(6fe3ff9d,9fc12ffd,bd896202,fd8ae913,22e4fcf2,76068a75,8d43f1f3,9ab68173,ef0d5682,1d414608,273ef7b5,9208c59,bf94e16,3e7faa3c,2ab3da22,b509fa1b) +,S(2c31e54f,d2586e19,efaaf415,e54cb499,54c49257,d11b161f,ff2aae5b,b45c4631,bedfb0ad,364ab1ac,e7f53c0e,9fb825e4,39af354,1a70708b,d8e0e423,13311346) +,S(51597259,23148c3,478ea2ee,2b933858,4d745b89,49c2f782,3b8660e7,78203ebc,329f6153,f688b743,c4fdc470,25790503,b81ff7ce,5a613362,8a59f3bf,66aa1817) +,S(188b3324,58f7d7b8,dc3fcb3b,df51ccfa,d394684,cde37d60,70d41e46,cdcaf1f4,4dea5da,d112a117,31a6b04c,8999c6a8,3d1ddec2,88aaf104,487656a4,d3901910) +,S(92058e41,a503e158,8ceb0a49,4e13e2a8,85f804cf,7f13c90e,307372d5,cfa6e471,368072d4,449e685e,17e5a230,e2177e95,bcbe177a,58cd1510,68e7255d,84ec108a) +,S(6a6f5226,44e06506,f27a7a68,96eac537,726f79e8,9e83105d,5b647883,34099fcf,cf3edd4b,d8ced83e,b167b664,574987f4,7104e79a,5a4b5321,4c19a32d,a5132586) +,S(7e37cea2,340cdcc3,ca21e0ef,ad548f37,c77c3402,34f0148d,89cf926f,2376bb26,c72d829b,42a27c6a,b062938e,5cbc22a,6b02d42b,d31cb69e,83b9fe9a,cc9a0016) +,S(1e6c2069,cf0f6cf7,bafb4b39,bc97a8dc,800d010c,52c3cc5a,d848fb82,d8d0b667,c181e76,bca1d846,86ecfbdc,2cb09140,49146986,630b7e81,f86c7238,8e60196f) +,S(5566600f,e6eea4f7,b06336c8,d44b47ea,f36ba43c,ca404be3,5203ef5b,6f07e16,6bbbd08f,7adc1979,ed4acb4c,f372eda,69e5ac16,7695a78b,5a7fe1ce,1057e55) +,S(435c634d,ed451c5c,21c5adc,45d94f8c,69045016,d529ba76,19ad07d9,31c791b5,31ede268,8252a50f,2206f959,1953c0ca,85009876,2b6f6c14,24b4e47,c74d4cc1) +,S(6fb8cce6,a66071c7,395c0612,252a414d,f19a0d2a,f855e7e9,dd142342,9c57b9b6,17f94249,e2f05314,d4799fad,68232626,183dadee,abfe34c5,b845d89f,2768e052) +,S(866f3e99,20fc4c94,9496a695,f54ee634,11c711a2,99e05890,148de8c3,2980dc36,e99c55af,4f8dc3c1,d38a11e1,3c00db2d,f5211f02,e837909b,ae188786,d18d62f7) +,S(80c13410,b7164899,a724f723,4dcbe505,62404f0b,7c027c79,4616f618,80468b2d,8631942e,71a01e4f,d7b59281,9dc69d39,bd6e8fe1,c2c41621,6d8df895,280b91aa) +,S(8f85bdee,ef4e9d88,53e68be,c17bb6ec,bf37abc0,a4ba44d2,c3815dc1,82a7da99,36d45bdf,8ae9342c,af0f8ce7,8aa591a3,4e8c295e,49ee6962,b4a9fb7e,ee17897e) +,S(9cd0b2b,3393cda6,ccedaf4,ee8a1b3,17a920e4,826da2aa,4404a01a,49600749,3831d35a,51d9650b,b1901e34,8f0c4ea2,3a00c492,a4960463,414e5dee,aafc5a5a) +,S(a0c5f1af,15c67ffd,6cf832f7,974c779a,3ab7ca,dffa32d3,bdbe0377,d49f33b0,6aff40d4,42de6262,41734412,3620c5ff,3079392b,b8843c57,80029682,1cb91ec) +,S(af396f40,13e217,d7e1fbf0,2ec4039e,c0111370,37cb2d78,90a82313,58edfacc,aaaeb9e2,5a57534a,2dc35d16,705f0e5d,6754c599,e85864bc,936e94f5,9acfb936) +,S(fdac3c57,e3e0ecc5,e7e871b0,dbe35979,87d4c071,f2f89307,cf1e71c4,91ed0eaf,3028a0cc,a22ef096,73c877af,ccfe36d6,b14d14ff,5da10b18,cdee6068,3ca09fc7) +,S(e3aeb123,9587baa9,ae12b6a9,68efaedc,ae745fd6,aac5103e,14a471d9,eefa88b7,7ed1c786,52c1544b,e306833f,bb27d1a5,7b460305,a2c8f6cd,2d33397b,caf769c7) +,S(96baede3,382a0162,fb4cc663,c91acb94,eb83d7a,3e3e0a0e,6055a50c,d78352f5,78722e97,b3ad2824,388c3a80,fb930089,5100d61,ea58f997,2adae059,f0c50cbc) +,S(68704956,16975637,f35e1eda,4db546fe,ba93d122,446a3e40,8de04ee2,3bf5f5b5,6247d2fe,b5f7471f,3a06c7a2,4c4261a,934bd226,772405ff,46e361bc,614ca494) +,S(71ccc634,2ca1f858,8ae02d72,eb0dd2b3,62eaf652,f83edad7,94095e09,f4bcf749,487aebd9,23b10e69,4a8e3f22,2703e5a1,aee17794,42a96c68,6cb9f983,dd2a45fb) +,S(6fda1dd0,65739a2e,58cd183,1e8b6109,713844ba,f249cdff,25d0b3ec,f635d3f0,a2ee44f4,8afccb72,4f8a96c3,2a88a8b0,a232a93d,553713df,60a965f5,2078108e) +,S(d3f27709,ff5ad97b,45e395c1,39947115,65cbfcf5,838e7b64,b1016cc6,d5147f45,f96cac16,cdc8e1c3,54e026ed,29bbd6c7,29006ee1,51d9d61a,4391567,93265077) +,S(27ba1944,a28a6eff,78a7d064,bb8292c6,68f82793,8e2be786,41ee366e,a4a011d6,24bef875,9d216430,e7312fc9,458f0571,fcbe305d,574694d0,a77f7a98,4e7bdcab) +,S(fd37b812,5fd87ce0,82fca9ff,7872e0e9,772f4c44,1870748e,e35e7d00,944fe190,9450a525,d9ae198d,db9b8c43,fb337df2,8ec68a44,60106951,1847b9a0,27dcb453) +,S(d9967cca,92583e0d,8d329b63,f32a8017,4467518a,595d8b80,2c24cc8a,8e071c69,6aca3673,c2c39d69,3bc86dbb,92e5af27,28361cd3,2179eab9,7ed64ae9,73376c25) +,S(8ee82d3c,4a8d01eb,d22798ef,bfd95c16,f53cd45f,e3d044f,3d89ed40,b94a0a3c,e0b0ab7e,9167fb9d,aa71c3a,fd5b9c0b,79c8b6a0,db3ae2f0,36c626c7,791e1b2d) +,S(461ec3d2,817cb549,a9fea029,15029707,8d709ccd,bf22da47,64c8a1db,c562caa,661b2d7d,cb5c9790,510f6e12,61650401,26cdf80d,b086259a,db16af47,af6684af) +,S(3155885c,935caed,469bb7ff,b53ff6b8,59f51780,f3de5890,673101bd,41f5793e,603594e9,92ac108f,8d0bbdfe,8f3576e,8ca6ac2,69c7581e,28d434ce,2043dfff) +,S(5cac93b0,ad9199c1,906267a0,ad8874e4,c68a60a2,b9fb6f0d,cad42758,2a4ea9eb,836faa98,a116dab9,69961fe7,ad7483eb,c48e7295,37e6634a,e423b99,880032ab) +,S(1fb6d3ac,afd5ef56,8b6eea1c,4a8f0179,54d05274,24487904,7e3ec56c,6956cc42,b8ef91f2,f89e4f32,6df6a1ec,50c6362,7431be48,1183c839,3133dafd,2e2a5411) +,S(89c0b1e1,52f0005d,a30618f0,3fdee7b3,69fe0157,f7bb2bdc,d31fc773,d82b28f2,61d6e357,bbf46816,acd05de5,b26c67b5,ad8223d8,ac9f47a9,25477ab1,80b4a507) +,S(7c5d18b,1f9d1afc,d663875a,34193240,7cb968be,f31d751,807ab1b,b79a211e,45fbe7ea,985bda0f,bd23b449,5d4e945f,d136b5b1,296c9b3b,6dcb9c37,bc779ff3) +,S(c827cfc1,9393108c,9b31ad4d,b5eb7f00,b6afdad3,a5e2f792,ddf9dd13,f159f85c,5c5fe07a,3025d401,54fe12fc,89951e2c,330ea3d,d6335a12,9c31aaa6,753a1cb1) +,S(6347b32b,b1f3f7dc,205e2fa4,6b201b4,2e0dfa80,550741e6,57117875,57cc5d9b,f8f30e10,9508d34c,a48d7255,3f8ac26d,a455d3f3,b170ee52,e22be1a3,ae8c3ba4) +,S(d489f595,e822101d,5f6e4283,7db032ae,bfa21f3a,94998130,e0a1d226,67ae1014,8b112e89,8dc4a146,8f64c33d,1261f8c9,2bfa98df,eb9500c2,2b4a66d9,227c66a9) +,S(90cb9c63,fb4afbce,adeb8f98,1e76a645,2200d73,d43bc0b2,76f058dc,b8a6205b,894afdc0,f6ba7f1a,bbaf19c6,720471d8,2611a77b,5bf6c87b,a02324ce,52e74645) +,S(40df68bb,19f121f4,e566a1be,f0a98954,869bb06c,699e818b,bc49a795,6a196af4,70d41c09,d0cedf7c,31c9f830,3610f6b6,e1d6b3d2,a431e69d,a31bdd63,220cec90) +,S(4936fd74,a0ac5045,91c962b6,431f17fc,a888dd1e,b35549d7,8b41143a,83da41bf,33a8e1dd,6517853e,d7c68af8,5b3f1cf5,3fc5b72b,5dd0f392,c5ab5ff2,1bff4f92) +,S(17177538,811075b8,f5baad59,2958074b,c1a0c6e7,b2a3f594,288e82b0,da023557,583d4814,efd8742c,5e7a0c5f,734da121,b163fe28,239a8775,4bbb072,c1b10837) +,S(a126b7fb,ad5145ea,b414c82d,8f21f208,6abb118f,3692bab,586770cf,4f8926a2,79b4ac17,b601b4d2,1a2bfdb7,41f7fec2,88d46594,699e4394,452cb2d1,ae2ec669) +,S(51eccf61,f8840048,d55de51,2d865a52,3485db8d,869844fd,ba30e703,ae871163,594ad253,97bdc9f0,82c0c46a,200ea090,12b2c6a9,57a53dce,e87caed3,2ea8d50f) +,S(97781633,6f1b7131,f55966cc,a79d25af,d8984438,8b516882,5105ba3b,52b3c7a9,f1df3541,b4b08fe0,cdda20e0,a5275eb6,105011ee,f4355516,e47e89d9,3b214c60) +,S(8bc2c43a,72248dab,5c78cf6d,b1a35ce8,64231d3a,870bbf01,cdb79be0,2c93f7fe,d52e2e76,173e9dbf,9e8106a,ffbb9d7b,b428f07,80269b2e,f49bbe0e,14cbb425) +,S(59ed7881,6c7ca119,ca4abd03,34b90b37,6c327175,e899e0d9,79953e50,5aef9f2,239fc027,690c0feb,e4db46a2,8669e0da,20779425,34bc6133,152a606a,16449910) +,S(bec399d1,76714995,d4192390,72a39c59,c8ff8e9a,2cab6520,ca0cf6b,2fc70fda,ffc4bdef,7831208d,23a1ab9a,de52f346,a21a2f7c,efc5ffbf,70999bfd,ad0ba8e7) +,S(93bd25ee,f4cef1db,fa5f9951,7d22a77d,9e3b87db,58c63076,68a35885,9e0c4d34,dd7d1412,97361b84,9a43b1f9,4f89970d,fa008c63,3404860,794e6a87,6735b4dc) +,S(b203a657,fb4e4d51,158b2e70,87455a57,44e553c5,bdea4f8e,3e8e6c92,eddcf58,98246948,c63e182,61f0d4c7,543fba7b,c74ae5a7,a19afa6a,ac80359,5ed8c99c) +,S(af38b53c,1dcd27b5,8118a28d,11da8aaa,3e20ac21,4cff64e7,be683dd,80f6aa69,91e38936,ba8b2b42,34686723,7a3fac67,5ec10179,18f8ac16,acdc32f9,c09fd919) +,S(55e4da5b,b99d805,e2058756,20ab4cee,988ed472,f5e6d86,2f8c574f,6bfd8518,7368be34,75179d32,e15b5976,c34c366e,e7713b25,8f179309,40b16117,aceb2d35) +,S(d3d7e82a,a7ebe240,83e1a15e,1d817d91,a3608c6d,d25a35d9,183a0c9,e42133f5,a5245cc,e89537c6,895080b0,6c5e2772,4b1c6d69,6c1bfbfc,ae6a7d4f,fc5d504b) +,S(8bd14f9f,e6b54437,9761e803,1dcc9907,beab754b,68c6c3f2,2316e5a6,6ee48799,f89dc150,a3876257,51663a26,35633868,ecb2eb27,d9ae8603,89110aff,6978fe19) +,S(b1d72365,3f50f42,cfeb0858,972a5a22,3a7dbc5b,4823704,85c88fd2,22212932,40597dd8,594ee1f9,b74aa52d,385b21dd,6279864e,7d0255,70bf3716,c02143ac) +,S(44d303e1,cb7d920c,93be4763,e045cef5,c22d4403,5e1d3a8,593f4f72,679d3023,79fbdefc,5ed6da2f,31bd6fcc,83e3cee3,e77e41a9,a01b2004,76912c61,5d89a70c) +,S(1655ec54,447aaae9,727bd4b9,60eb996,92558999,83d4aed,3dfeba12,3b0cb3ca,8e90e578,cf96e31e,988f7bf8,a9f06d94,6ea28fa6,b1dad744,3b9ece50,6626fcdf) +,S(b02ae3fb,530566bf,66da9326,18990e6e,7902b104,800cacb1,9717bb7d,845a3f29,c6d32713,f4483031,19bb7631,1b397427,d8c05232,92a61051,62a0307d,7b006876) +,S(13c46566,53a0042b,8755e140,2b12b9ad,8e123699,a153ec6e,65e49cd,10c5bcd3,70f3672c,498f603e,3c521ea4,3ac3e10,7bab13a8,a78b02b0,4492c51,6d41c88) +,S(e7c7562b,3fc37b8,2e9c7bff,c5e97b39,dee483f,141df4c6,361eda3c,4f1483f,734be460,3d2b4958,c1bdce51,57a16d0e,1a937298,1dbb2833,1b12f8e6,c3454066) +,S(de025d2d,fb6cfc75,342b2ed1,ebc7b27f,332f3921,c304b8d2,263d7fba,2959aefc,46c609b1,6ab6f3d0,2dafc30c,38373a30,1a88c31d,80694598,5e676f1c,16de12f1) +,S(21e788b4,fed21c3d,25ddb714,abaf053a,25730af4,83817e4b,6a42c323,3eca2e01,1fe716bd,a7d07592,b66af9b8,32335b9d,b249b1f9,cd413c58,ddd29fda,e5c1c4c6) +,S(a7db27ca,7481d50b,1a458242,c75b28e6,d1bc1a9d,da97e012,e39cff10,7b79edce,c4f8686d,cabde6c1,d3455fc1,795a7cc4,84239d2,3b11e238,85136183,71ae73f8) +,S(c5205173,2790f240,e2161627,5ac894cd,e80a7d3e,bd5bdccf,41af64b6,5e2d477a,e9aa295b,209410a0,f0e8e216,deadc3f8,af87700a,40543cda,463beac9,f62ba20b) +,S(487bf4ad,99d1daeb,f1c25f86,d36ebcd9,38e91eea,8b855d05,ea9371c4,9572846d,81293837,ac6ded0b,ee04b2a5,4c18ae0,32f72970,86de0ffe,791a9576,fcfebf70) +,S(bd6dd2a6,bfcf688b,84fe2d55,e56025d,35567574,20edfcb1,3cd14483,e08cb53,c86a45e1,84c83806,38ea1501,c2851598,c467d2c,d1c51a1a,1b037324,d9ab0fca) +,S(94a417fd,fbf188e4,1334fbb6,906731e8,70dbca18,672bece7,936a4c7c,235ec737,e03c6607,343ec14b,81eaf124,bcfb7d97,564e9f93,546f9765,299a443,d9be8e34) +,S(2a57dac3,3fa13b26,a96d9b73,317a23c0,2ac597d3,3968fa8,ebd88d94,66aba51e,1754a6bf,1db7b3b8,b0a7996e,545f34fd,3b05bfd9,805b50c4,42db2937,e8c13b61) +,S(ba2e4a71,6142a39,67c613e9,93083c32,d1c66da1,2c3f9742,eae90b7f,ec7e7df7,c262f8c1,a704e83b,ed7fc60c,5adec65e,ccc6de35,8247cc97,1da7acfe,834cb07e) +,S(4ae19743,b3132512,d28a12b1,1fbbd824,8bb0b9a,730d5a8,a862ea8,ecc01ca9,67b7267d,48fa3ea1,d1c1ec7c,a6a8ba0,cb27883c,3f9d4193,20b4c8f7,a017eece) +,S(4cfb26c,81823667,f18e6ff9,d77493f0,778b9bf,411b63ad,61850ea7,7706ddcb,10df8a3e,3a8c93df,4d7af16,407c3211,aa6c6079,c397a0c7,78e1e277,24e4028e) +,S(9f9e4566,a014b66f,fbc3ef,b3c05062,15f06102,6f7d6561,934d3db9,5d130349,492b8ba2,76d526bb,98fd0c17,c5a0aa7a,ab6e5c9c,ccfc95fb,a417d25,9396c592) +,S(e36c0513,3641b560,b0f9f4c1,1159e2f,ecf2a194,b55f3bd2,22ecf1f6,ac239301,c7fd74ba,48e7fc40,6322aea8,e9f83a82,20e9a113,ac2b0c7f,aa05a5bd,bb43736c) +,S(91b013b3,b94d4568,78737580,bf1da11a,a0bbe0a4,e3ec65e0,33e9f824,d8480bbf,15e3707e,c13a2529,22a6f824,7e33d172,948790ac,3d367f00,6472f22b,e8cfc5b4) +,S(254d1788,8c676d52,236782de,2d539f2c,41f667a,d75d0107,7d43f723,ea324f56,f7042d2e,93511e5d,13f4aa03,bb2dbf27,9bec3df,97974275,5fd25133,c814094a) +,S(452d6b7e,ce7d0f71,2afabe44,2a22f16e,34fce662,99697f0b,6135678,56f4079a,21ea8ba1,28cffe76,3400d69f,ce13204a,9a39ee59,14132d23,db3315a4,7f776998) +,S(1580b9d0,7888f41,81b86b85,5b1982d2,81783185,5f28c163,1f151479,cc4c508b,4d9d1e9c,78b3d9dd,73bcbbe8,778c1b7f,65b69faa,f6576dc3,ecdd00f5,c1d689ff) +,S(79dda23f,c31694c9,16d1470c,2cf25a02,45a5aa7e,d084af45,c43960a,a2fc2700,7c7bc169,a58b8d8c,c4b74e0f,377031ce,d7158c21,a156fc03,c34f25a3,a95bc978) +,S(866da7a9,bf80cdc2,13e500af,b5f4aa0e,419b4905,44653b5,fe2daee1,4149dbe6,626d38b3,b45d57aa,6867e8ad,c8abc49a,81a282c,6bc6524b,239819ab,766bd3d7) +,S(432bc912,bed271e9,321624cf,c6062b96,cdb502ca,f990522e,1024b80b,9411d374,e645449e,dd7c4d41,41e0cc5a,cc5d45df,4cb341c2,baebb605,bcdce6a3,e411cf01) +,S(ac3d3b28,83ec385a,15297086,525d937b,717f5ad,83a5be4,77b3ec9f,6410518e,d126eefc,c9ed7e75,c10d01b2,c0e790e7,3dde58f9,54185a12,5fcc7268,84b9b8db) +,S(4570834b,2a82385d,6db696d9,56ae2667,fa18b262,960d064a,5c13da43,abd6aa37,1e9d6083,b249bf88,7ba2eb59,a9597e7,d9d15c64,ad6404e1,21a486b0,61236f28) +,S(88e9a6a0,ffaae05b,7c29bf79,2163c0aa,b224b051,36aeffd3,341355d4,b983ef15,ed382a2d,fa2f63ea,dc4ef5e2,579abafc,fe457475,d1ae8413,99969324,718d1e5a) +,S(16810eb4,de3327c6,a505663d,cad7f618,b397033b,d6c9748c,4fd8748,2adff706,352ebd8,91326c9d,2159e84c,40dc29ae,30693b7e,5a9ed119,1fbc2cf,ee60c81b) +,S(d7d03a92,95064981,1cdc6503,588d157c,88c861d9,43fa9cab,e2e3301c,994adf7b,8c820bfe,933c2c05,1ca3042d,5ce781e6,ef419c8f,d9aa83ef,2a915e36,382f9627) +,S(5b2c9504,f645ac90,24e25c4a,e880ce7b,f33aed77,e45518d9,1c6f2652,ddcf11b0,500b37bc,c7764f32,11d681e5,e8f2a407,440e1da2,4eaec354,fc289c76,29296449) +,S(d18e26ed,d2c78bbc,16982675,9d59eec3,bab1a64d,f579dc2d,6284add4,8cfbd761,1a1e0172,37a3e78,8fd8989a,a5bb6944,685915da,1392e1a4,4a6c7ef5,7d0770c3) +,S(5f6b1416,9bbc4795,8ca21e88,df252546,dc9e46bf,85d64772,24f34ce2,8e58222d,3a8e7616,4d5a0501,947ca0bf,163e64bb,3a57918d,e383c600,e02aadaf,4b7fd6a6) +,S(d7a625e8,dcc8b456,69802023,8fe85691,ec2e050a,25421373,39bdbc8a,f762bc7,8f1f9935,a8ce2607,abd7bcbc,fec1fd8c,208683a7,10000806,20d50b4d,36ea3643) +,S(a56a5419,72aea4f7,15dc891b,3a1b34ea,7ffb42c9,5e02a771,6bac663e,8d5913f9,47b3dfcd,ad785671,180f7bbf,a7f5d144,59b44023,640e3897,1e999a90,6bc3f994) +,S(1ebb89d7,e574cbd1,37b1a3cd,4a306b44,30325db3,361b7c3a,d93116fa,baade31e,2039c52f,bd30c84b,4983d118,5422a342,ee020c33,49357e6c,b9550075,38da4dc7) +,S(b5728208,931a6575,4b5cd1a4,a798ec27,e189effa,3ee4f0c5,ad493a88,b49706fe,aba785e7,2da3d301,cb29a612,562078bf,358f680a,317836c2,14ddf7d1,bede9ee) +,S(56661670,d67b7c77,202a00de,effc1ef6,f5162a97,47afca8a,a2457c85,85a775c9,adaf08e1,83bc5107,4c55122,e549d3c1,4de8a893,39f199b2,ea044a25,4d8803f6) +,S(18ab56e1,ecc86b69,77104243,35737b51,c18521d1,b170a3e9,3fd068f0,ddf2704d,cc694c3f,43bfba9b,20c9572c,acb30563,df74f07e,ce1ff9ff,46b8259e,8119e94a) +,S(bc12a874,48270360,1575b754,bf5f50f,6e945185,2e0f27c3,c1aa0f1b,ce0ac357,9c6ce76b,ac175ce1,d667783c,7204ace4,abe12d56,62ff36f9,5de017c6,f1ada1e9) +,S(a4494c26,99b2da0d,6edbdd6c,353eca75,75666796,5ddbe457,2c27ac46,79054584,589804d5,8360a9e7,d3e2a914,61d5b1ba,e8f0cf69,3b8add03,5545386d,5082d621) +,S(1ff846f9,6d0e4e7e,be34de77,d036a027,f1baf9e2,ea3dc9c7,8284ac9c,ce3aea6e,8a0a336b,9f0e3560,31f5d1a8,d4c0b68f,27ba3eef,a52dc974,8d03e12d,653f2e6a) +,S(33181aae,91573ddc,728839e0,4173f716,6862d724,35744099,ffa8f1f2,9510b374,1252129a,8cc8ce4c,1ddaaa0a,4c34c4a5,f01ee26b,3e1a9fed,ad0e7c9f,bdc5223e) +,S(e687832d,fb0e44ae,f7649b15,77274a94,64426406,fe4c6ae5,7028c9e5,78012594,5e5b3897,6b734b7,b65caec8,c77ffb7f,c5de4f98,eecab002,8cac0c4a,a513b7c0) +,S(354bbec3,ed9371ac,58174b5e,2a18c76c,c22951,df4c6aa5,755c72f3,94b37def,40d0c876,9283416d,b3613ac7,37401e3f,3c2f4def,bbaba44b,5c2a83fc,c614c29a) +,S(fa46ac6c,5205b81f,3c9e8aa6,8b5ebef2,a8bc68bf,fa2f4511,ae36f726,7439a485,3853f9fa,b016d2a8,1cde37b,13f91185,f25657a,765fbb35,c1b4d52e,3f67d180) +,S(426f86b7,33255f8e,1e85263c,923fb86e,56a53d77,945f6688,5627ed43,3024328c,92ec0168,5301c89d,5b13c4c4,57b22215,658c6341,6aff9148,6a2efbcd,4e8c4fdf) +,S(5c8d1c9b,f9a72d5b,e15d3f4d,17d48cf1,7685dfec,b5ae1ede,b47b6e58,80bc64e3,6205550e,286c8150,6638a3c7,c20f0dec,b6a26b53,641d2dc4,e18d0f7d,29bda7e5) +,S(3a021dbc,7bf7501f,ddc31356,26a9cb01,be673373,fa663c80,271be570,e683422f,64a89c54,ddadf89,784e508a,d056492a,a7a71b82,485fcfff,54c7b0de,4c1bfa53) +,S(8d82aa49,1d719f00,75d2dd9,11d642da,7c0062c3,2296726f,a504af27,23ba47bb,6e616f50,6d1478f6,988ed10d,6c6d3c50,7c2ae8fd,4760e699,1ff5c62c,53e4e77a) +,S(6feee988,fe488e1a,6ed5d60e,fcac1b3d,bbe5451,6e7aad76,f27f08e5,3c5e536f,ee9f95,839fba96,ba26d848,425b68a0,73dcee61,35e04eef,f482998c,b044c502) +,S(36240979,bafd0d57,72fcadc7,314093c6,3063880a,e895ce5d,2df3e59c,ae16fa1b,619d0376,58ef3d85,a7afe326,77d832cb,eb20820c,157836ca,65f17c61,c84afa48) +,S(4c2b8847,4da56053,c2046fc3,26e81704,b78494c,91877407,9984a3,cf6a18f4,459a9e69,17a4d711,61ca0b43,85c5a823,734286e3,d0cab398,dda1fe21,3b28142c) +,S(f921c9fd,b33211ba,a7f4eb5b,15044c34,d6e54f50,af7b85ad,84e12fba,b1478ac2,38cda9b8,c850483e,48c6b16a,5f7f624d,e31faec3,5cd594f9,3171490f,ae016973) +,S(a57769e6,6181d68f,8f86c8a7,da3fdb4e,850ae07d,f41e78b8,ca42c6b2,1b19b257,212a987e,644bc42b,f757e00d,54d50ba5,1dcd6698,280f8eb3,8829dafc,527cfc6c) +,S(95a78104,37abecad,888c9195,23c9b16b,375a2714,fed74639,1ea949a,c7c11d9f,eae320aa,227b056b,242723df,1f11a494,ec642876,91a22748,9e1ecb2,a2cfdf78) +,S(76a7e034,f7ef3e14,2ada9a64,ce984008,9f034a5d,8584a0e5,d10d40f4,29cfa42a,999dc0e4,9633eb3c,2a4ec931,9bc2eedc,9f2e4996,522a2404,79c9468b,668effa2) +,S(eba89396,47567805,1cddf92,9db7d82d,427010cd,5e94247d,f4e8cd1e,eb5881d6,b92ae1f1,c0885214,3f37d8be,616cc5d6,aebe0f8a,8da4a6a5,d4a69b5,dbbca552) +,S(a53a48d8,59fe156,6b14f872,aaed4735,dc0b7589,713ce8ad,dd3f3e1d,6e23704f,9e738da0,7e85a3a8,3d89403f,3ee7d564,4f463418,676cea0d,2528b515,39387fb6) +,S(8326590b,dba5f8a3,8e39b148,105063a7,c831cdf9,98288fb5,95b4fd5e,a707d3bc,a02cf88,a2a1dd25,2d00d62e,cfa4130f,61b7d4f,297e6b06,cb4661b2,bf768982) +,S(6a492194,ba8c10bf,e31714a2,17a74b2f,b0c35a2c,95c54af,7f5ac6df,17916030,3cf0bd65,8e0c937a,92ee8b4f,b4fc3289,c531cd00,6febd45d,b6b6c522,f8c77b87) +,S(b4ac71c6,ff797eed,61d80c49,46ba221d,3b34bf13,7e3d4747,4b6c3068,33c52a57,46acb2e4,8fb6fefc,ef3d2343,4624e0d6,14ae3b60,df813683,90503506,d52820f7) +,S(8b11711e,65bc29e1,16bf05b4,e557b211,13b19b93,a1c1ef9b,49a19316,c286e0bc,79c4a0cf,cf383538,21ad695e,5b4eae58,faa6bcf5,c722c491,aa9078c,8aaf0dde) +,S(b8b00a76,e86b2579,97603f82,e80fde24,727362c3,6d7a192d,8974f643,4408e098,5db6718,8b0108dd,7cc6fa1c,fead7b2e,9e0b9ffb,78487d0a,5851b6f8,513e56c6) +,S(884c3a1b,fb6b968,53427a8f,69b713c6,bebe8f69,645fa52,c50e2d2d,61d89814,3dacc0e5,94b2eef,3743f821,df54dec0,ff28aa4b,d5b18fbf,14d658ce,7a3749b) +,S(3d0c1dcf,51aabf63,fe04100d,cbf6fb4e,c004dd1a,aeb637d8,496a47f9,74637596,576ebd5b,bf5de2cd,6242a6f,599fbb76,883fe013,3e2ef05d,22843236,a5df51c) +,S(56b3edaf,61539adc,25c57f79,a277b77f,1ae972b6,3d5328fa,13f811e2,dabca8c7,40383900,a2b28602,71ab3d2b,5dda95d0,96bdfbab,79b3d347,dbdac66d,2d2e98eb) +,S(426e29bf,50f34c9f,434eacfa,845485fe,5fbb11d8,319f9457,a74905fb,2bcfd3e2,eac47ee8,eeff40c6,20d10cd5,c3b9df40,eeb60b88,df1f57a3,5d613198,33cb117a) +,S(955737c9,f4e24d7e,c6d419ba,a2edadc7,cf0a91fb,5bfc3ea6,7ed50ca7,62929308,97bbb89d,18fd9040,2fa78314,359bf645,b69831b5,bb82e608,67baceed,481675dd) +,S(5d72a813,d46427a0,f2fae639,fd7e7ad0,704e74a0,83a784a1,cbb85017,e8b3e514,c92f410e,851fc61e,559d6839,a99eb95a,2e8c2636,f51c45ac,9bc1613c,b8876c2f) +,S(c7da9359,e9bc8890,620876d9,170495c2,dda7849c,7852406,22551bb7,e769b6ef,12278168,71508d00,95d90787,24a0c7d9,cb41f6c5,c82f01c6,d3794c3f,5c10653) +,S(67080a26,da7af0fd,c2fee080,f20ae516,d92697d7,fe1adace,9729064f,569ac683,ad9a07ac,fbba708b,30944107,e510eac0,8e08c5ce,79f77714,aa522cfc,2316d94d) +,S(210d5a39,d61428f7,6f878ddc,82e3afae,3947f404,5c155a41,63a00570,5bfc0dbf,617effe6,b0a629c2,ed14cc29,67a9193c,2efa804c,93e997ac,96eb1803,2e8c511c) +,S(5d0b9231,ca1511b9,c53242a9,37837d13,9b8e461c,6ff655fc,59021d04,e334ed98,c8070121,f4794eda,713ae1b4,a9e7d6cd,1a2f58e1,f6f8d986,bd13a66e,bfe924ae) +,S(687bb82c,42101161,ed0c8bd5,44c71975,9013fe2a,fcd10ab6,3ce78a67,e2907392,eaf63d87,758aa3a6,f9fc721c,f8b209cf,fafc8e81,10397e35,6a25e966,100d9eeb) +,S(51a44157,b8048f68,1a2a3931,ff2c3ff3,c63527d1,f4bccda4,e66a6d1,ce5f5d33,6ffc8d16,519c2940,14fdc8f4,20a63890,1a0c5667,2db96a1e,c5127fe9,e847dd31) +,S(b2862572,56f515a3,5624786a,478c3bfc,a5dd7b2,2bd7c4f9,89f70bcb,8de86775,22ae96a8,a5a5396,b7a67e5b,29292ffa,f53b64de,45f17692,abcd932d,4664f3a3) +,S(f76b721e,201078ca,eebd89a5,ca396213,6ee129bc,fb92ae58,4bb7c7fe,835bc30,599c6ab1,8419840,3d6b3d17,161bafff,223a0a38,1e96a4b7,a062f4a3,e6c0d561) +,S(12f24a87,63adee06,e82f20b7,ff696911,d9a3b88b,36dedb97,93b07c34,c4178e9c,59fd7b9f,96f01fb7,b265d939,c2827bee,b2427fdf,8c2e1b7,35178d58,e055b7f1) +,S(9e1b8a90,de6c6bbe,2a082d47,758240cc,bcfaf145,c48f90ce,fa0221e3,1922260a,fa5e86a5,b54bd9e0,7c2a54f4,2097d004,8a71eb06,ea48c0a6,6cda5981,b390f9f) +,S(63f05903,20b73eb7,b01b6a66,e28e31f1,ed4117f8,6c4d20a3,8c109031,2fbaae9c,24b8c9d2,d34a81fe,6e88967,a263877f,40bd68ca,baf5d9c5,1abe8b1,9501d8eb) +,S(447c7409,f5402a3d,a1f569a4,ad9f2855,e5c89b6e,99c743a8,e27992b4,63905999,d44e8d9a,b34a7a09,47b37723,be016c08,716baa73,8b93f28d,b7790370,ad49e154) +,S(74a4406a,4c5340af,ab77db0c,20f197e4,25eed4f4,a3f986df,1bbf10df,f8793254,162d678a,a4ba712,8cd36907,d1c46b16,dc4c07bc,52aa46d,fc7987eb,67742023) +,S(f7035171,31872637,ab0e63cc,841cc7b6,2bf5e076,53a45ff,3a23246e,8f047c07,c84b0391,4f470785,721762a9,5972b59e,b3c7eec9,66718936,ccaee9c1,da1097ef) +,S(ec4fe07b,57b23581,2c53bd70,6b0a4152,2194d168,dca164f6,ac999f6f,72eaae11,af495291,45deb29f,ec2b1dc4,e9b76051,b2f9df79,bdd304d7,b5528f5c,a2fff789) +,S(17156de8,fa96174f,7a0b274e,e168d0d4,c6552047,11f36388,78dbab4a,cdd2ac9d,2ae3ec4,36c1460c,984e37ed,6decb88f,c2de9f84,79e28ca6,abb6803f,1461ac3d) +,S(e41b462b,9c5a47fa,cfa9be56,dd30cd,549cb90c,9506a6a,abfca643,9a1b2ede,108fe2b2,8bda60a,c68fb353,38c6958f,e1b3604c,22215311,d380bf11,17507f4) +,S(ba6c0159,20a67883,d7880051,51a8038f,f357ea78,c53b95ad,38a6f437,7744aa38,da49c0e7,deb6b746,83366aa5,c0e8e710,cda1441b,6686f680,4579b5b9,16002cf3) +,S(26f0186e,883a4b6b,87102ab7,f7e52663,7e8a9553,8495729c,ee283568,f8cbf1ae,eef8de4,bb2197ca,ccd51980,995a18a0,aad78823,75702d3,98b245db,4bd5f47a) +,S(10b93de,80c0cebc,351b5588,c0140e63,e00874e3,da663cdd,c4501ca5,b40c9d22,ed3189dd,f79af36b,e7986b02,7ec495ec,1dfef7f2,14358284,2d05b4d0,1c903258) +,S(e79ec274,337a82c1,c97b32da,8f5a8c55,7a159540,76c94255,8bc9a3e7,77769dde,9f23079f,22dafce3,54a4c175,d888f3ee,e527dad9,83d7502c,3b651762,628a06f6) +,S(fda0175,44f0ad3f,c8b9915e,8e0caa4,2be265e3,92041b0c,1b7d31a1,6fc101e1,424e9a27,85d59c6e,bc7e4298,1a505733,e4d49a76,b84a030d,db2f5c1,858902e7) +,S(681f01cb,5380cdfe,50314725,88bc830c,8327d8a3,cbcfdb31,577cf11b,a099c6bd,bf9d2117,cdc3b05f,9c06cef0,6fc9e757,59c02fad,8e0d98cd,794918,f39002bc) +,S(70c25a6b,2a2d2cc2,dd251f4d,9aca250b,d6fe9f8d,b9eff961,1de2095c,dbd12f64,c9eeaf68,a386b2cf,cd3f4dc4,793ea5b7,134dae04,d991e1f4,6b299a4d,1a966126) +,S(464ded2c,404b42d4,fefd5ea4,5f408666,3b466e85,fe8b304,3b121b8,9fccbb9d,ac113904,6ad3f613,23ad2d3e,a568367,610bb47b,e41a5260,79627122,105d910b) +,S(a32df72,48e79198,5d455109,a8c5dfc1,b7ff8990,1b5ce3f0,2ad2f134,13a103db,6db4b4fb,9d60906b,9aea2d1d,876296c8,cf9ad8d3,3e65e173,8212134a,4b160e72) +,S(fe49ce9e,7ee5d39c,97029774,64ec4fea,3ccb74dc,2a5c7fe9,a7695315,165179a,653f553a,35925dce,eefb9866,26155723,90bfc582,b4c426e6,3f58f0fa,3fe7dc8c) +,S(868b2e55,c895a7c2,4da24750,c126b10d,ec0f1a0a,2add5a87,8aa7316e,3354ad14,5e288874,cdea19fd,71f03594,1a6291bc,776bca82,804324,efb61f24,7ac299ef) +,S(fe0790da,90ae34c6,8ad3f1c0,80fc486b,d267ff7e,fd32d1ae,c63d08b5,8c098461,ad331393,de35b283,471a0244,422c6132,cdbfccdb,5680bef4,16f3beaf,6cf7177e) +,S(fe7fca8d,f4f80dc,ff16b196,167dfefa,42a23bf5,66837955,7f6d8279,6fe9a9d9,bbc4dd8a,d7ee925,dd80cb3d,681476ae,ccc5729c,e1815b1e,71c8f1cb,d8d4eb3b) +,S(a236c270,aa4ce20b,eb51b11b,511cf4c2,ae797598,e9f03fd2,3aa36858,9434cfc2,593599c5,75a7bdeb,41cc3ade,608c210a,8bc37040,fbb69f4c,4863a31f,2088f29b) +,S(d6a04a5,6bb8c27f,3ea8a348,538364e2,800472ea,d9e1f644,565546fc,76519248,4b95470d,50b97629,22b099ab,a5761243,dbf6e466,226e8e07,9b77069a,b542deb9) +,S(d09cd377,d64a045f,e1a76f97,4d701a24,67773228,3261aebd,74e02ea9,f8a30e7f,9f0942b9,2b702b3,d76ed2d0,1caf880d,41a342ea,ee06ae57,b90a924d,6588ffea) +,S(d030c72c,16d01a9d,6c2e5245,61c7e3fd,b9a469bf,ff0a7440,b2ed0ea5,e5d98b8b,c6b1308,dba4f981,16b60ff,eaea843b,fddeee67,ca1406f4,73db0f11,531f2c8e) +,S(56c456c6,d2c04a7d,441980ab,80b39a55,57d0c6f7,5706bba1,100c6bb1,e345a691,c5b2f0dc,2c735d0f,8ef10ffc,2753c2b2,825ce525,a0613189,fae34e64,26084819) +,S(aad5adf3,b505d1f4,28dd1b98,dd4fdde5,29d911c5,e0e5837d,75e51bac,308400c9,e94adf67,4f7994c1,123aa411,b790c68c,f55569f2,1df4b6e4,6afab87e,2777acc6) +,S(ac8cd8b4,dd76b8f7,4886b089,f18b4cb2,ca1d43c3,19ed034e,6b1867a3,5e6a0ef0,71d70894,f9daab15,7413f827,1cadcfc6,ffb71db4,9bcc81f3,c759d4f7,137ba96d) +,S(3964006d,f110fa45,409d7a4d,5996b44,93eb4150,f4217948,41dc5357,dc47ca1d,e4a11c6d,21dbd93a,f922a2bd,23f057e5,c2f24474,36bfd7d6,395a46df,3ad7cdb) +,S(2be10b92,27a312bb,74ea37b1,9bf910b7,723a1ff8,fb43dd55,1a0e1fbf,7bca56ec,19aa8afb,c886dc0d,293ecca9,4290b24b,755b2de8,c1dbc0b4,59052edc,c6df59ab) +,S(379c1556,2bd7f51a,1d219a34,dffc8bab,ccc1e417,1c38d342,a4c6325a,b5ad6ae5,47a1f28f,a6371df5,66dce223,10d95535,e7bc6734,7f20748d,b983fac4,2f185907) +,S(24054dc2,e675459d,2af584a7,d78110e9,30a36290,989dd4f9,914cf7a8,1fce9809,6572ae1d,3e05d0a7,1c4e06d4,820d16a5,3553dc81,a6f02a76,12b584a2,e57ae592) +,S(9812e6a6,f46ca979,ab7cd879,1023b32,913199c8,b850298f,a3bb4c8e,a02420a4,468f6eed,dfecd933,1bbaf36,986f9377,3afd963b,56577151,52a12b9c,88f937f0) +,S(46058644,6a348e4a,d84c928d,62c9de2a,9f6c14fb,95c83c6b,96203a5a,7f13c700,9dc55ee3,ca3d701f,e6759c20,3b18840f,4c873f11,57b21ad,90401e77,622d57ab) +,S(a8dbaf97,2d5b05f2,a44d862f,e4aed0fa,1cb877ca,639ac322,8e909507,bcbe006a,3db54c03,f082937c,4f98d38c,6141d0bf,253e6729,b83c9902,51ac4a97,176fa4bc) +,S(9b8b39f4,f4d91329,13324bcd,44f9846a,8b3019,22671128,74178009,391149fe,490a4f72,1c452e5a,88ffc693,90b0d1b3,4e4cae7f,2e0ab097,6b396a99,1c52c1d3) +,S(334681d5,a7ef46db,196404ea,9e501f81,7406ce24,27a64597,73e358ad,314615eb,2b23603a,1d80cd6a,9f04775a,52069de2,e328fdc1,37fe6b6d,6c165442,53ad6c0d) +,S(feb8e310,c63c6ebd,294639b4,a4cce42,bd5f8372,b7aeaa88,2023f0e0,29c32529,cb6e42ad,6a0cd780,aa57934b,86682260,68a45c63,bdf7e617,fbcbf86d,db43b213) +,S(f4a17bc2,c7334e92,dc923252,3b910a55,a8ca5cb6,2b3d93b3,fcf0f2c4,8705cb67,812b7795,1b24729,4b3d55a3,2f45260a,e7f4a9e3,d5cfa304,bb0471b0,da6e9dfe) +,S(8ec2ac7b,85514349,5496d596,bfcaaf4e,c330a995,f082324c,7e0479ba,4ccf181b,ea1588b6,7811d263,7bcb3bcf,5cf0bc4,70e92797,27b1c258,ce4ebba9,35250130) +,S(b1e6d61b,d9aecdbc,c9c4b6d,9e48c6f7,e4aa9eb7,7da3c001,53443c6c,4d4f19a,43af7b55,b2e2c976,8b1fdb34,48d6f339,1bc20aba,eccb1a3,5aef98af,b28cbf4a) +,S(4d83d2e8,210d47dc,3904a397,4db35433,1a951963,2d4e2e4,b69f2049,2f13b2be,7ed96c83,3874fc97,be45f1d8,8e5842b9,7a0e3bac,95400036,7c8572f6,3d37a6b3) +,S(1448e92e,fd51fc21,d6f5d514,35527f67,25f5c5ee,b0b29c36,b9eb6e8f,2bb20b84,248a338f,c8be83e5,2f91c9a2,2868973c,13336aa6,39e43f4c,ea8bbeb9,96e344ad) +,S(e23b03d6,9c2250ac,2cdcc7d4,4e0a218e,39d928b0,2585fe63,dcf7093c,924e4ead,8c69c7d0,4a8a4b7c,1997ef44,fadb04d7,80b91cba,13dee454,2effb8ae,71b9aea9) +,S(4cd1e35e,21fb3fe6,946a929b,9aebfcb8,78663224,da66af94,e5a722b4,32b5d7cb,6b1112dc,5e865b10,ba688780,32978617,eca892d7,730ca984,cba4ab07,7167e3bc) +,S(f3cebaf8,92cb7b0,27cb9212,3596ece0,bf25c6b0,d8f1dbf5,f2efb204,a0db647,a615ddeb,8418c013,91923b88,7bba5d3e,cf3c7172,efbdaab7,e12582bc,a968d8e0) +,S(4b8acd28,500bf88d,68337c81,33181706,dfe341de,7b1d5736,a3a85a2c,6d655e7d,be93d7c3,825a5675,84d6f76e,52f3b06,7b7c5d87,844f18ac,624c96e0,fd219bb8) +,S(8dc7ac81,d04e0088,63fd2de6,2cc68de8,3e567d81,85aebc53,d4771950,7ceb9fe1,62d4b64a,be7b1931,c47a7755,e25c803f,1eb14c89,2ee100e8,214b94c4,11fa9198) +,S(aa63343f,3078d48d,942bbbe,df4f2c19,a817c257,9003e033,7104e530,c1b89a23,277ef834,23a6730f,69c20f4d,9de94758,13befc6d,ce389bb,fe7958e6,6ea7b524) +,S(37de5061,9f301e40,8e9096c0,1a37df3a,dadeba61,bc217495,5d04d7a1,5121d30,7e7049c,33e40b96,6a136516,c005597c,e3f6aa70,d6db4c31,f5732fbc,e538898a) +,S(6d18cf55,506d59ce,a3e8cd44,f347481c,3ebc6682,2f91445e,11f2c0c,45eb83b4,e930e9c1,ca8b73f4,7fb9818e,5d4db8a0,220f7ba7,ce807854,c8ff2af7,b8a30cdb) +,S(77d85660,6de7dac5,dd4203c4,90152c9c,f70243fd,eb1d1c0a,5b797b39,16caa7d3,3f57cfe3,9b37d550,c9db0fc9,4b3c0e3b,1a2722ec,f920522e,8c37d848,f59c659c) +,S(5c2e69a6,c44b5bb1,c55dc8b5,6f9d4fb8,ea56450b,d69d9229,670e635d,f381bf16,f082049d,a69ca9b,a2821a8c,2fd0b46c,9ec21af2,4c34b049,f1af0126,75a3588d) +,S(329c01f5,66d925b,251944ed,92beb06a,aaacb98d,89b2aaf1,918ce400,b5a393ee,7e29b038,427a0fff,6ad50c80,aa49252e,e21c2c45,3d4c72a9,c3cafedf,faa57abf) +,S(4c2e631f,18b2dfa4,37ebb401,771d7b0e,b670f4fc,8546499d,f62b49bd,629525da,8a95ebfb,87423fa7,4c131432,6b7c204c,50c6c2d,a3f85370,1f789ca3,fe9a6f9c) +,S(fe121b93,d254465,c7f7cf02,ce10a575,d3808ce4,c6133fd9,392fbf1b,63d03fdc,33129b07,7bda4311,94fb997f,9443a0ff,e59438a,f360b635,2a80cbce,a49e0ba6) +,S(323ac27b,1cdbf3f7,74e20521,f1e74b8b,2cf8c5d4,4180316d,a532ae61,2f784c23,21156108,f6a64ac5,888b15fe,834ba9a5,c8489e16,f3d31197,bb296b2d,3fc3dc18) +,S(11478f62,fdfcb1e0,3a5f0ed5,ce0c2101,eeccbca1,e5934d37,41b1a8d2,7afd533,a9f79673,2fd3ecc8,644cdb17,6d11527a,aba8d0b2,985366c,70d96999,ec5f9153) +,S(9f0909b6,c9d3c1ad,eb88acf3,aed5a6a6,bc8d82b5,767896e5,e7343efc,20b9d078,a5161ca6,c5c95d64,dc663e30,b8f65234,61a579d7,b99a57a3,3b0f3844,e47db181) +,S(4960a875,32a9ad42,299d8cd1,a1af80bb,2807acb1,b52f1711,c55957d3,a64a6b9f,578e51f3,f1b46628,eb48f54a,93f82f24,4bfc6202,eef77dd8,cd6b90b4,de976625) +,S(675c29c2,bdb265e,5490951c,bfc9f73d,d142d536,4b5ec668,54b582f0,5d310354,22d1f669,3d82de84,202d4f9a,186bdfa6,8cb8ad5f,9da33a49,83229047,e08bd6d1) +,S(c4096cbd,6c75d0e2,6a922177,916ab32d,a9053adf,ad849d36,f65b7c9b,107ce605,5f236b47,2ae3c979,2ff61efb,9633ae05,b2b97e51,24a3c2,94f5be53,95c2bb46) +,S(9ea0d341,ddd05401,f01205ec,2c754155,b1ddd460,1fa3789,dd80ed9b,3b905c0b,3bf48101,97e7d0b7,6f3692cd,53989764,ba7ce059,953f7b71,7e615c20,da28e69) +,S(bdebbed7,84bffa33,72a6edd2,d9815b0d,637367f2,de3768c7,b4dd75a4,32fb92e4,5ff3437e,b62a9b62,dc16af10,5a20941d,297a431f,ca2b0067,6734c4ae,cfd0b9c0) +,S(a486fa44,b46e34f2,d6aea82c,8f554210,cbfe674,77b560c7,bccc7d6c,9e910932,1ab7e36d,8a15e284,8a3caa0,f54ca555,b8ad5baa,7f47fca8,3231c822,f897317a) +,S(4463a0a5,57a1a926,aa204376,a20aefab,66e7abb1,18c7f769,fbd1a7d1,29cbba08,4a823aa5,ab7b602a,704f01de,20b8ad13,7dc08152,25ceace0,9a9dab69,d034af0d) +,S(d6e08a4f,c45e8dfb,ab713584,d91d1d8,8cbdc5c6,2eeb4b4c,593a73df,4d825ac4,2cd85bb4,77c0d0ba,5071ae8f,c0fe2dbd,8be98d9,622fe506,c59800cb,5eb4c55f) +,S(b626e299,2a69cad4,e6076dca,29bbfd34,546d31d0,a4f8b656,a433fa87,f96a10f1,6df4b2ce,ba919268,f1568632,55e27655,62ac5e3b,8cbbfd34,3c656f43,43cb5bc6) +,S(3619e6eb,74645070,b2dd6196,5fe4d25e,25a4dfeb,619e3b05,7e31a566,947139a5,964b8989,ba156121,9d36c3bf,29467c7b,79940c3b,450c1431,1aa0d725,1282093f) +,S(b3529b5e,6718843f,c40a3a65,d5330961,41e5c060,e326aa84,7ccf7f48,c8bda2e9,49e6e0d3,7ce1bf45,e9c595ac,285becf5,31111e7b,2a67b057,9d4fc552,59c1b935) +,S(e51f0067,5bd7145f,fcf85527,dd247ef1,4a199778,94035598,d42afdf1,2fa9e05b,d59aaf3e,8b4d72eb,4523d5fc,69b047e5,7d2e175f,30eb6c8c,ec729cbf,c1b32666) +,S(8a87f066,f64bc468,d225eb6a,a0a7b54b,91c930e4,d4520720,1705f831,cde79b28,a92a5d95,e0057c95,b219062f,5d0e4277,249c34ac,6255113b,b5eebea5,66800227) +,S(d8a81015,aa878ee5,a69c771e,bf88daad,3a926afb,b8aef632,cd7d987b,fd310b06,af77f7e8,f276ed4e,963e3a26,2f3942c7,ec9f31da,199ead3,d5e5f53f,e20acbdd) +,S(88c3fa19,4f3f4d93,dbe5b8a3,865d28d6,51c9abd,519af4d2,c3b743d4,ce0cc5c1,104caf7a,f9ff822,7b3671a7,e7745bee,26b5deda,9982b9d9,a9d648e0,760d8f8d) +,S(f8738725,3434b0ea,f05e9c76,3c729a8a,22070111,6c5a6484,5532c3d9,41ce648e,a8b5eed1,d4ee7913,b69f6627,d3e1be,4c286e15,78167201,46fc9e21,786f7bd7) +,S(5fca538,5afb021f,94cca826,5689605c,7b35c8f8,dc8fef60,6b18420f,909acc33,1d7fa51,f5c28bfd,eb1f9a52,723eb2bf,c5b4d078,d5d4b639,2b791af5,d5b2b3a8) +,S(47484548,d4b2acd9,bb2cef9d,bed4bd0f,f1fddf4f,e1561a51,891464fa,cf5007db,ea61e154,f011cfe0,46fa2539,7fb444fd,b93e223b,ed882bce,3ddaa3c8,328f44a8) +,S(331f17ff,b14d43f,ec69a6fe,b41a8021,dd8ef56d,2540234a,b466ac85,e6c5b8f1,ba20bca1,8d774731,b6b64a0f,8a19311f,37d8c061,2c4699b,68d569b0,9eec144b) +,S(6aba62d,200bd2c6,4ab88ce9,80530e56,5b8971c,f9c427f1,5e9b146d,dbdc68ce,e4c936d7,d7d98919,acd26ef0,cf071f2d,fcf65fd7,78dd8c5b,ab026,e9f832c8) +,S(c76b6c35,e72fa19c,621022b4,d9ec6ece,c0cfee8d,c73254fc,f52cbc69,23ca19c5,5b0ffa7a,48ee8599,9b74d0a1,d7fa0289,b49dba85,7b21bfb1,ee7ba831,fa13efc9) +,S(c056ea3d,43f33df9,b01590fa,429c14a6,aaa438ed,415254a4,4a93854,ce1bb77a,d5b194e3,2337a9f1,2c479e7f,576a571e,58355a02,8ba0231c,c337b8c7,eb3dca7b) +,S(3d688ccc,8ddf0ef1,137bb897,e6b8f3b7,7df652c4,93cac3a1,47e88b3d,bdac938a,bca94788,4d7ae1f2,960daead,111558f7,38b6bc9a,7af3bb4a,691af22d,4d5879fc) +,S(4faffaf6,69ce1180,a9145f0c,df6fd834,c59d7a9f,5f2e49cf,3924b33d,8d2a179,9e015cac,2dca2ec2,5580c16d,8c910abb,dcbad872,79bcc485,b71f5561,60159d2) +,S(47578e3,7cd7eb78,6b5a44eb,3decc7c4,e8ba0c7,6699ef61,4ac30579,a24aecad,948ac817,a6bee00b,c68eab83,fb628ed8,7fd0066,9ebc8569,45eef8c9,67171651) +,S(9aade275,3eaa646a,24ad1a35,f74887db,8c72fda7,77b59dfe,103e1a95,dc618836,b651c384,8f4625f3,1e6e7a05,c94483f,ceef2fed,dc7f4256,87e0373d,d02bca96) +,S(b1b0c3e0,b1c6ee75,55a81852,447b2bcf,321c9b9f,629caf9a,276133af,63aed711,493accfd,624e6ff3,dfc1d0dc,aff17113,c2c74167,58cbd571,759bab24,300ac827) +,S(c557758f,b192a058,eaec5762,ff391a9b,2a0ce462,7bae01c,156dcf3e,bf2a8ff6,1d4e9b53,d209e195,9f10f671,b1bfdbf3,98921284,a7719766,39947969,6d1bd3b3) +,S(73522ded,5120ed4f,b49b5ca6,df5a1b6,edcc082,48df4d07,cc9ad923,2b7b5e0e,47569d94,cdf0270e,d1d299ce,d5bcfdc7,7f87db4e,c9725a96,e4388cf8,dee08d74) +,S(16571c0d,66328963,2a3ae46d,fc2bee50,fd6fbc0c,f0ec73ad,72bb9c2f,e8323506,65de9d86,9e001c60,ced57911,e7ce6150,a936d684,d759f143,d2224448,4bec68d2) +,S(f5fe5564,2eb630a5,c860cc8d,7c9ef86d,b1810d2e,82dcb343,dbe2f958,98e5f090,5cee7a1f,bea9dac8,ca340dcd,fc2c097a,eec2dabd,d7ed7504,e20c913e,9fadfa87) +,S(ef09db32,70d09043,43da67a0,b87cedaf,7aece017,58d78591,8814e3ca,396e3592,5934f805,ba246e9f,965c6161,cefdf4e3,7df14271,2ae076ea,80ca239a,c7b675e2) +,S(886cdbd7,27d2f099,9852b102,bf201ed2,5e174622,f974b0c1,3edfe523,373a54e8,dacb328a,7fca6e5a,e5351825,564e4f89,5166f687,38d46142,6eea7b09,dca73b2b) +,S(b7d86bcd,4f7bf2e,8529ff84,88d9f3e9,62071308,9bbd91f9,6e4ef82a,ce237cff,c6b0aff1,375a547e,a8546dc4,17574843,3acf2a4,ed0d002e,e32fd88f,3b702f0e) +,S(d7d171b2,8132ab85,30791059,395d94ec,c24f5e99,67bc6c4d,22bfc7ba,eb388c67,983770e0,2421e2b6,55d3c135,1bb39bf7,7be39682,97088744,bfe6543d,dc1a8f8f) +,S(ffe712fd,881e30e7,229f1cfa,833dad90,f01a1896,c1493502,a429080a,9794b1be,f4299e03,75d084a,10b11ae5,8f2fa2be,f18b037a,53165586,cdac18ce,54505da8) +,S(563c92b3,3226951,cd7cd10b,3f7b35c7,dff3f0de,6f03d66,9f664655,57d13f7c,dca1eef4,85bef41,80b0ccfb,2416f948,9bb21094,854f5f43,769cb37,33ec10c1) +,S(b8e76ef3,3a2cebce,614056d7,efa47c15,dd52c228,66a7d3dd,9a0d4d64,68f32437,4454e79d,652ae799,a3a539ba,42619a1c,3076ccc2,109dc4a2,2aa41a28,918651c2) +,S(36db2304,f60703a2,df2e429f,b8a99841,7b4a4f3,e08642d2,c5675460,aaf1c971,a0536e8f,5cc30aa3,d9b859ee,e26b1abb,ecf7f9b4,8c8fef0,f842fc9,a684b5cc) +,S(c5d4e51d,1521637d,d6055e52,9e9ae2a4,d537c1a1,b7c6a314,f9d558a1,88d9a5ab,c841eeed,6a13782c,fbf65b08,c6570994,aaf7093c,4b48ad0d,e04db33a,6feb3f6d) +,S(50c03dc2,985859f6,ffb79ed3,f635e17a,b0561533,600af220,7cd98f9f,71c4bffd,c68c8797,a7ed229a,f59a2bd7,451c748a,5c425528,8b7f6b0a,68b64a77,d7137720) +,S(2806d84b,3e7e6f9a,2e10ae5d,cf5bb0ef,98560691,71d31ff3,3645346d,f08333ef,72f23443,38e34ccb,4ccb5ddb,f3a6b58e,bf8cac26,4243785e,54a9b503,c87b429d) +,S(40d70ddd,1ef58dd1,c43e33c6,29840fee,82bb9c1b,e222b53f,4c58952f,388790a4,9b1a9d57,b6dd9932,338d170e,af4d5516,e654685b,3946930d,96b2a1d7,f70770d5) +,S(8850ec32,4e71213,bd77b193,ee21da82,ac733804,17983905,d0156608,8b87c835,aafff7a0,a9160b91,92df58ea,a65c0716,961480b2,b0cb4d3a,7d637f77,ddc160e2) +,S(54951509,bd7c29f4,77f9d4a6,2be485d7,de291b0,6a308bd2,c240cf71,50ad6e8b,2fdb347c,f2a23b9f,a3a45c76,44cc1fa9,b1d8f79f,77c02f27,f136c732,c7ef2722) +,S(9f5ec355,cdf8eb4f,be5af1ab,70a3e7cf,1c3d3e8b,e643621f,acf8f69f,af7e5d44,b203dd5f,b38b3550,6fda94b,ada1c4bb,12b8be5e,92bf8a58,4886f2ca,19d3c06e) +,S(812e4a9c,1bba9e52,8cb5e606,c8b326fe,8b72f0e2,3062837b,bdf371a2,2ec0b3da,2ba7b5b7,14a9ae39,c62bd36a,1ed00135,5d98d248,9ef90f24,d10d1c58,f8e222a1) +,S(e6035ddb,cf85616b,540ff16e,cd5d7fd1,af52c6f6,2a26ec36,c5c1ca86,2a3d924a,a945389e,f687fcac,6f918718,a1f29f19,173d3104,69c5954a,d6cfb5df,f01eec86) +,S(d788a5e8,d771d471,b7169693,86b2339b,2643f129,a6b50bc6,321e752,6a033446,34b85622,5095783e,fa57fe32,a7d91b65,c0c9a42f,79fe30e0,b2598967,e97d3990) +,S(663733dd,29374f9f,1db5f11,6fa32b56,c8ef42f,706bd802,5615d4a4,77c6f41c,3585d45,3ae0fc59,1614e916,a1400b79,85b59f66,6e2553c1,394ec26d,d078676d) +,S(5ec6e728,5ae1413,3dbad4d1,19e2e3d5,6affda33,356146f0,a5ab023d,b323ad9c,3dd241bf,cfc6301e,29cd609d,b1a0fca3,d35a56e4,668de9f6,45c23d69,c0884579) +,S(f18fc442,1fbb66a2,7c336647,1459717c,87532be5,d4416cee,e4a674a3,2cf8f3c5,d38a0881,3bb33df1,fb4e83,6686c0fa,26847e5,f7580de9,b4f229cd,1359d560) +,S(818f549e,d9bcfe1f,14b8d336,21342465,7dec0dfe,eea1d719,20622442,39f5345a,37ce611f,cca2f448,45c1a8e9,d7f4b3f8,48b24c5c,2b9f5368,8cc2c8df,846602ee) +,S(75e2c791,f98e3fc8,2a74ee3a,532e8796,4f4fa8eb,6421aa64,17a5b00b,1edce942,51f2373b,a4951362,68aa17c7,1160855c,7c4d37be,222a8b26,f2d54cd5,37e5f6b4) +,S(711f8db6,4c0c6d31,daff4ec1,f9937730,9b44de59,9f4b9119,9ca6836e,1e3954d3,485955e3,432ac82d,f3170fcf,7b3519cd,6e4dfbba,170bbeb5,b75e3e7d,70caa4b0) +,S(63502c26,6f755a1e,4be2104e,e8ca9c2c,5216f50f,e21e003a,16071bc8,df3ba6a5,a5c829ea,c8fc3f4a,f55075bd,afe77977,3954b88a,f1f3a8dd,90f28aa1,49bea942) +,S(2a677459,ccfee070,1b5bb82f,d2ee57e6,13f5c3d6,3927938c,92d10954,c2850872,ff6e9798,5c5db0b2,9bb1cbf5,db03e0c4,401bbf28,eb39e053,714d5c5e,ef7cbe71) +,S(68f85f87,78fb69a7,9db4a22,3d7faf95,5b359bd0,5f230d99,f051b008,32b52cbe,dc2e949,f4fc3189,c4f7b771,f8b56b85,ef9c65c0,b3bdf89e,405d5f3c,ffc92210) +,S(7ee9d5b7,3b542036,509fd8b9,de590b24,9e9883c8,6f4bb90e,1c2904f3,d2b74ade,98122413,241cf205,f91c6977,b925ddd7,4920636a,9dd67828,2c30ee,7343e62) +,S(8447b090,cdb19271,db368023,d40e520,102b5d04,79eaf391,3817553e,24aa33c8,25b43fe6,55a27481,c02eacd3,9025a523,121d02a5,78896a78,c14a8c21,f7c0bdb0) +,S(316073b9,3f1550e6,b7951f56,90c5ef3b,e45e622e,77a2f268,c89a8b6f,2816a645,557ca5ac,2fc70ce8,c3e54a4d,b31d5c77,a1a6f38a,18646caf,6a52db31,947624be) +,S(fae2312d,a2ef21ac,358fe949,5c011b18,cdaa8ef1,c99284ae,5fc1eb77,4836d6ac,6f3bf661,2d99e865,b0cee7cb,3fccbf08,aa948ad9,b29b4b8b,54eee8d6,3f0b76c7) +,S(280a2bef,5588dfdf,b1e1691,d3162aec,7d4c72c6,b76f23e1,2f8ce783,54f839f0,f00ded1b,c31a9774,a87be1bc,7e440585,b2b4ba63,cc0d9c73,ca7b4873,93683f72) +,S(3f43e77a,9b7b92c9,92b7e5d2,8c75444f,4d0609b2,8aa65ddb,86bf6ac0,bf7ccdcd,b3117903,bb3c0a54,bc6bd6b9,92b8d85c,ac267855,50075536,6cf70a84,4c72a2d6) +,S(3a0afdc8,387bfa34,87e53929,51e10e,9535500d,f6506296,46df162d,d469f2de,75697cc8,f0f690b6,e1f86dff,3f2ca53d,907d4cf7,c8ff324e,8b4187ac,c9bb29c7) +,S(3f972b64,209f723e,99a6e7c4,a72072a0,2789d0aa,8a23d660,949ea417,7970809d,7a482428,7a6bfd9c,afc26e76,9a02c5ff,9a7c053e,e63f2342,b32a4f84,42e47d15) +,S(938ac0f,fa73364d,11df1ecc,4b84e3d1,c21ff85d,71f404df,e8daf4a,e889b0b4,a1c09ed3,d526b381,dee8820,eda06a10,4e968995,64cb604a,63fba74a,45be0312) +,S(5355ed75,2993e74c,275eb9ed,3bd34575,631c9b5a,64e99071,8311ec8a,f4e28bcc,bbb1007d,680aaaaf,ac10279f,600f1851,c8188547,3091a40,ddf7253c,fc6ad088) +,S(880e32ed,70ba76c6,d83bda46,a4340646,b033696f,ab62e457,4e989311,fbf277b7,76feb2cb,8d10d5e2,406763d5,f696686b,8dcdaaf,330e4e7c,623cc7a8,6e0410bc) +,S(daf778aa,a2755b68,2b8beec1,14b74e9c,857ac503,daad6bee,bd6d11f1,8f11aa8,1ed85c62,710d3017,9f0f3024,d6ed6976,e38325f0,92981c88,fd4982ee,98a5f428) +,S(e5c3e9dd,75633d27,d19c0a4f,f3533f80,9a60b95a,42c8c464,1cf7abda,8fb474dd,f1e56af6,5c5c087e,ab303699,f20bc9f,71b7b7fe,16332afb,2517b241,8dfb0dfc) +,S(5d403f34,ecdfd870,977f3bf2,ffb274c9,6859c20c,8cd7afd,d116837d,c0096973,6b5be47c,70246cc5,9781ba70,71764d72,2335c334,443e5e4a,5ba12939,d8f6aeb1) +,S(50ba053c,25511f71,b35b4caa,c990ab27,993bf034,f3e55f81,3896458b,5e246b12,d2f12a45,5c7a3170,67690399,3063dab0,9f8a22a2,bccbe5b8,8a7fa2bb,f2291f63) +,S(385a80ea,ee4aa9ed,a07898f0,b3658793,9f290622,399c3a00,b38bf02f,66629cf,a543320b,d72ac6e5,d750806d,6a90b8fb,8cfe4902,46991eb1,6e6a6974,befcd50) +,S(98610b9,904ede38,6e69de6c,3d40518e,eaa669a5,23620a9b,276e1996,bdedbef,907755a2,eb6aa100,d0cd0c89,25b5ff8f,b88f72d3,61d83315,c4ad0d94,8a06b581) +,S(83f10807,d9640d3b,dfc7b0d3,dcbbf6a2,19ae215b,4754f29e,d4579999,191b7fe8,f62d231b,5095d6d2,860e69c6,509de2c6,fe719e4a,fbc2b5e2,489a6f9a,7293364) +,S(51d22293,927335c6,2f82b028,52759fd1,e3f287fc,67b6059e,74dca17d,4fb1c246,b9b803a3,b5145b4d,188b909e,23c8b126,f7184bdd,3128587b,e05219df,6c63745d) +,S(be6a6342,e5783d43,d2691945,826c37c5,3e8cc24c,5a09fc70,3689def1,4f465006,81c718fc,3fc15279,da9efc14,13ddcfd8,81bc7e4b,1c36004c,2008dba2,7c7ef000) +,S(f21334d9,c36f1284,a4bb043b,58b27070,448681d9,a82ae81,a4e8f226,bc790036,44851,3a87fd30,453dcc1e,b21e293b,f5f143b8,2cf2708e,428f4753,8816eff2) +,S(1558c4e5,af34463f,810cb1f1,b73bd27e,932a832,9253e2cb,419eafae,c9730508,cb8cc650,25e14132,3663f3f4,1a75085c,6921bb37,428a149e,2dd1fe4d,f4c917f8) +,S(1853a32c,8f6020d8,1b4d3596,a88e3825,b575a4ed,99072e64,2e090a1a,665d71e2,8da2a31c,b170aea0,e364aedb,b1861fff,eaf26888,b29405e8,9e3ed982,a03a8367) +,S(ef585cbc,f0f03bec,21df60db,cfafa9dc,2da679b4,3bdd590b,8cc35388,cccd323d,2bc5e203,aff91f6d,38592e07,82813905,f02ccdba,1daa7acd,d93f6d80,78c2f296) +,S(3f4c2e37,e1ea68eb,befd9971,424b3c7b,1fa45864,e0d13471,a1476808,b2fd5c14,678990ab,3d283b3f,aaa665b0,4f329b51,51b9c17,b54385e3,30de36a4,7e0eeaa5) +,S(2b001b8a,d557ac4a,181cb20a,b3abf2ac,59fc9b10,20b5533b,621b4119,e421693a,fe4f3007,f8d19db1,73e6f8c3,48b2525,310a328d,2ca0c675,8fa29723,82c6b94a) +,S(6589d1dd,7d5a08ff,8deb5b10,81fb0ca3,79c90d27,58ba0bb9,8d05bc93,452cd229,82409480,ed842993,4bc8dca2,3e000fd5,fdc5475b,192bc7fa,a1179165,9a8149a9) +,S(c233fd0d,f5d3835b,8e855316,276a6a90,ab4377e5,a3a3a8a8,3b89f0f5,27950a6f,8fe8e0a8,775a9a43,12cfbac0,85aefe06,31468031,86b8b84f,49422392,b4f6f3e5) +,S(82731a85,2a848eee,d6ee3f57,f75a2bfa,a388670f,89f6f6e7,b65b13d0,764cc14a,c00c509a,307c5e87,f1b09688,38e34a21,1ffacc9b,8a7504c1,2080e4cd,39117583) +,S(e21387a0,e5d8b1b0,5aab5150,122942ec,c9dde3b5,53eac977,7eea6d0,6d2a50d,c74de509,f90d93df,343c920,74ac5dfc,fc81c95,93354349,bb2810dc,8db0ff83) +,S(180871fd,2fa443d9,c5b5c341,4d635b8e,92780fc1,6d04236a,bc9a49,5b9fdc25,d66c7150,6008f37a,422014a8,bbe025c6,1f25e636,e2778146,59985003,ab14d120) +,S(b5a9de7e,ed112a8c,1ef29a9a,31156b90,d64dff93,4d83fab4,b44d30e0,bccb2c42,5675a679,a81c3faf,3b0afe66,ef85721,30315ccf,b0ff3d91,130a71f4,3539db38) +,S(9acce472,61f1e50d,f42baf78,c05a5cf9,8ce5697b,6d3b4d,40d011fd,aee7d6,fb7c413c,40464c69,e5756830,4325a79e,6cb8c831,add29e0a,95f88feb,9507a05c) +,S(f80ab79b,7bef7712,2fc7bc4b,2193deed,916796e3,67d85100,a02cc0eb,8b574e5c,c6d4d03f,842d8b25,d9b5834e,d6cdcacc,3a1ac585,b5d22aa,c77019dd,1d5c8f6d) +,S(b431e355,cdb4230c,3005845e,f60b24d9,25d81448,ec161aee,faea1f98,bc9366a1,ebcdadd4,ae230a14,382ddb98,552b6e69,7aebace5,5cc7390e,f69d176d,da41c1cd) +,S(7aa60b9e,8c93a63,51eb686f,46dca4e6,efe56edf,6c2089c5,93f6a800,6e75f1fb,4c81e2,17700bf1,e053e389,2e33e694,cb424800,b4068c98,328f00ef,5fa0347e) +,S(1a88250b,3aa4243b,7441d1a4,da37b4dd,d304fbef,272f696b,a72e7610,1286b30b,625b9d05,57d3815b,e06d8cb0,f056a9be,b33b7658,f459b3fe,3fd5f4ab,69b7a473) +,S(5b524eeb,49fd558a,2d34db23,cb5dcee1,6c4ca47,1eba9966,82dedbc3,aa2b57c7,2d5c2c97,56b7ce1d,735b163d,56e02bdc,25c8b227,2bca2d5d,bf252906,bb8ae50c) +,S(ae60e777,6d9fbe79,d24cb8b1,f756098,191550d8,433bc7d1,8920584e,7676d2c5,430fe986,73772472,ca11be83,eefc8678,b76c36d4,346a311f,fff926fb,158d7784) +,S(323a5e3d,9e29f668,d460b081,a5dce6fb,53e8d730,9c42f105,ab4f812a,62efb9d4,2b457b3,69483f42,16656d1d,3b5ea9af,da6216a4,47661830,c2fa56be,804776ba) +,S(acd1b5b6,591e552c,864e612e,d69429b2,b3db8649,7a5962a2,a8b36511,7a7c1c9d,e6131fff,56f6900,926ba772,92526348,67544d25,1ebc4fa3,26562190,8e6e88b8) +,S(6b4e2c70,817852e0,2a26286b,155248ce,f2e61e60,84742cf1,14ebf74f,785b36f4,8400951c,7a529bdc,2007130d,1cd5297,7398f7fc,d66e5a1a,1e4e8644,e5b893df) +,S(c2b2c727,d67b0a46,1f44cb91,48c34744,4e6a375f,80a817c7,1517969f,8084ab31,fed64359,ebf37b0f,998aa251,9c281fd3,a52c47d4,89051718,82481fae,c36d5f59) +,S(3385eeda,b5b2bd94,f794609d,978a0f86,2ec56422,bda0ef71,2207ca1b,904f202e,2808d2af,1db8a8ee,1c5975aa,31a9f441,b12a2186,746a474b,4907bb71,603d7443) +,S(800f6cd7,f2cb437b,8470c292,3fab4786,edce15f0,d4c52a82,33519c07,14c803f2,981f2e3e,ad11aa0,cde06ca5,9b26028c,23e0a88c,ec397734,ad0152f4,d4a37056) +,S(73aa0bff,3a9f286f,d3c103c6,d7bb6caa,ebfaf4b7,614f1f32,4741c600,eeaa2f3b,30bc529,81a9b983,cb89fe73,dd8bce7c,a54a2e3c,4fde6846,701f1da5,18c6f7b1) +,S(9280fce6,ab5c13f6,80bfdfa9,c3e7612f,86380498,9bcf29ca,789169fb,a178f2c5,4b96ecdb,c5bc2e3b,2fd397b1,8f7f5bb7,aeb6a7bd,db0a3b23,3e74f7cd,ccae36bb) +,S(72055c4b,bb50b9ef,b589be16,270d12ea,9f438780,e5eccb81,7dbf69d,a66e03ca,aeaa257f,c30a77dd,58574693,51a8623d,985ad705,aa1fe3f9,8915a6c6,f6bc7cb) +,S(f0f3cfd0,c771e3db,ba687c7,3fa827cc,eb8e887,12abc8e0,3085d047,e7c1879f,2c612e7d,8b744c54,f8f0c4b3,24fe10a3,1bf8aa5c,cf6e2e20,eff98153,a4936b33) +,S(97c78b65,70b0f270,6fac8fe8,ea4376ac,d8b61177,e5e7b3ec,67a7af9b,e6f5dcfa,1aeb950c,fea95858,a97da765,c3cb5941,1334609b,347c4daa,1279d58f,3be14c3d) +,S(b39ffa1e,967e6fc3,d493a9de,48b077fa,4b7908f5,33a73eeb,9b5c9efe,9e509e69,f55f3951,81ac72cc,d618c00,71c817e3,f76c302f,11219e16,f3b40e75,ea65dc05) +,S(159b9f7a,5ff27c4d,1bc3fcc4,d91b160a,1b2a972,8b1e7fd1,7351c663,f8e7baaa,b0aaef6d,86c54ffa,eba1c7f0,d789fd41,5e60127d,578c2697,a8380b7c,a4c4360a) +,S(25810fd1,8d4a4b16,c7d07a62,b626fc45,6dff76ab,3c1361aa,f729f7f3,cb85e44c,f4052325,7794bd70,ad295526,ab4b8b00,9252dd5f,33578f44,2fcd2219,2f6a2d9b) +,S(27e20a4d,5860a328,c499864c,9075881,eab36291,2da641d,6e1934df,473352b2,c1598cf2,888cb50f,e270b490,503c11a7,d3822a2b,e86a7b,65cb9499,3b45203) +,S(483f454e,517a94e6,6708f465,ba217b60,6d684a68,4d9472dd,685f3bd1,341448a2,c13b3144,d93b9a36,45d23346,c5dcb70d,d338d06f,f0c22aa8,2ba68a61,7f9ad11f) +,S(4f47b2f6,31734aa6,5ae4c9a3,c1532f2,67ef068f,83a4f266,e2e0a59e,be04e6e5,58f1f34c,f11b9cb4,5d33ebcf,3edab72d,6824392e,dd547a27,c0134d66,58d99d2b) +,S(aa78eb7e,835ce84,b4f1774b,8e810cc0,d6f42a2b,11c44574,24fb6341,7797db07,39640139,d957d47c,59cc7541,d3f72e33,ee9ffc63,2171311b,cf493ea,185e743b) +,S(d2598985,83c00560,11dc0655,c37580b0,31a3f1f6,aa5f5944,17eb0ce8,cc033d49,3641c973,9de8818b,a294622a,2dabe172,b6a83006,4d04ed8b,c841d11a,5af24b08) +,S(4f023ba0,ecccb74f,56f38f87,7435907b,f2d2b85d,59f7ffaf,48712a48,55e26634,f80efc33,b15d5125,b8fc35ea,393b6c3f,a2ae094b,86a6ee95,bc48295f,b1a6a456) +,S(9c86f08b,48abd097,7bfe13cf,a15ac8be,8eda4128,f7c143c6,70bf7e2d,763a1589,11511f87,e9ecb88,39eff453,d29d4db2,17d4eeda,c8468a17,1a152f15,c1c2df45) +,S(3808718b,72e95cc8,fffaffce,cd57e269,c5e6ac77,69d8120e,9130d8b8,ee137576,f40ebdeb,cf5eb722,4dae59cf,8ed8b58c,c614a61a,9e3ccee,db789fd3,31ea728f) +,S(8defd15e,399492fc,71c80a1,3eda0244,eb349f47,5c7dfb42,55dfa752,fcdda3df,d3dfa778,4353d0c3,b4fb0d19,ffc39631,a01786ce,e3b0cc7f,f9e4c5f6,7bf7a771) +,S(8dac8d42,5ac1d07e,3a805248,798fade7,ed99f9d0,c324bd46,6eaa8aa7,dc24bf8a,f232fdb7,923234fc,d8b2f097,d354dd6e,62e9d926,20d28087,d6410b72,aaef8009) +,S(87ce6443,f3bce6de,287178b4,f243c3d1,e45d26fc,6f811d35,329cac04,7fa90e1b,a897019,62414ab4,c582799d,77edf3b0,f0af0d4,8f70e875,fac33e95,39724138) +,S(bfee6bfa,bf2fb77e,9eb60a3f,8b7775ba,124a21c8,741af3b,d22966c6,a8fdf08d,29a1c399,541e4bf1,7f26f215,52fc83ee,cd2e8be8,40b83fa6,9c9ce5d5,fbba76f7) +,S(c30fda5,b553a800,2341a553,7aff72b8,44873af,8381b41d,aef9af2b,5cc2bec1,5ce3eab5,87d88d64,fa44aafc,ce34046,8a96f76e,65dd562e,7d14153b,439fea6d) +,S(5e7151fd,594119d7,c5cadbf,e1b419f5,4d922607,728d70a0,f1dd4d8,3400ed97,6a8ceea5,a51d4a7d,62d36816,ecbdd75e,4c64ec96,6257820d,73bd9531,ea108917) +,S(a9c8eb0a,66cdd5f0,f33d0620,8525225b,e974af7a,b50d47c0,4bf690db,ec86100b,f209cb9d,898731f3,b02a24bc,ff290cd4,a4371e88,f3aeebf3,29c9e1b2,8b8e0a2f) +,S(955e79d7,93669150,471b1659,52ee6121,cb804373,5faf653b,9468511a,e3a2e439,68daafe3,2a9b67a0,10ea3bcc,1a56c7a0,2e82cddf,120e6826,1de0700b,cf930d06) +,S(22d27293,d3c1cc6a,5b3bc70b,3bb7e1d6,bef24805,3c8685fa,c192b409,dfa34a71,c74b44e3,4fc855b7,53c4e42e,740dbb59,4d5d76df,b39de389,e6c837e9,639b3357) +,S(d19fcece,f74b1767,4e9d91f7,1487aebf,70d46e8b,3a037835,b2f4e8c4,2137abc0,5b904bf6,3dca0981,3ce224f7,494ccba3,34ca9fe5,f365ca83,fe9adb6c,4adb7580) +,S(6aa1722a,adc74800,d6609113,6bc6a6a8,1723c36c,524a873f,2a437c91,c2336899,8e97004c,df495b4c,63164058,321549ce,3d9709d9,ed667c36,9a4f1ee2,d6319d07) +,S(79bd3623,9ee4d220,12d07262,e96ad186,b16e3b6b,720d052,f736f851,b0ea6efc,a4b43db,f568cda4,1dc972c7,1c7c92c3,6a31166f,ad6b80fe,42df4dbe,f418729e) +,S(b5e02b2c,146337b5,67583c5d,3690c0cf,a1c7d820,14028c9,e401182f,a4f16ce9,4b9646be,3facaa70,e793516f,a0e8a142,1a819ba6,718d26fb,938e2795,9069e0b2) +,S(8e33e271,de2deb4d,6444d64,387f790d,14a2b685,4b38857d,d05af743,7a7403a,d82d53a2,c7a4a1dc,eaa011bd,3e0ceb0,e08d73ff,fe9d71f,c913d6e2,89ecc429) +,S(4ffef442,77dba780,e5769b73,feda37da,abd6ef6,2f5ec36b,74593ca,4c19c2f5,a8a30857,378aa0ab,9ef6162c,fbb09f9b,796755bd,67bf9d69,4a186813,d392f854) +,S(878b652a,633805c8,b58b0334,11b9246f,f7e42ed6,ecba6bde,fb737126,e9f57368,2cfbeb3e,d691158c,d3ae71f0,b4a41d42,148c9711,d274820a,d541efc1,56e85836) +,S(ef9a6a15,aee2aed1,46b99ee6,a79acbc1,a0aa0b2f,1b082783,dd40b106,9deb415e,9909e2ba,7fd53514,a1bc4480,2b49c7aa,cffd9cda,19c54d82,6d9bd08e,49e97240) +,S(d5c248d4,1551d230,60835885,5db0ce8e,c7814e18,c2d548fc,dcfac207,645bf37,f9c5e89e,7bf01f82,8cb78c88,c14d50a8,3cbeb45f,82daa9cb,3c3804c1,15a36f05) +,S(edbf25cc,a526157d,9676e614,81455682,6dad0c0f,96ec289,f2c5919f,57227d1a,6845488,be056456,4a833c13,70d37257,d0ca701e,f6e574c7,409dae02,ee99554d) +,S(5c12026f,b8e2e376,2521f5cf,cf9286b,14be80b0,dfcf378b,26fe6ea5,4ccf09bb,3d98d5ef,4e2c6528,7950154d,581c9a44,94b81a50,40ba9047,1bfa6758,66daa596) +,S(c27e6243,5056055d,614dcef7,f67338c7,ae728bd4,af3970a0,b434d2b2,e48e2d6d,76b586fc,703cf946,f78839ee,bcd28c56,9e372d97,856333ce,d82137aa,7d8525c9) +,S(a298c704,5140186b,4d424e8a,f98ee604,7f67603f,ab14a7e7,b96daede,51abaf8a,4dc70158,2a1b1935,4a5b430d,b4a0c21c,463b779e,ba72f108,5d7d638d,68108fda) +,S(e1fce957,82dae8b0,ac204fb1,9496a332,fdf40014,88ebaf07,3a62f33e,192013c4,40517ee5,d5786ff9,6aa2b50a,a77a10d5,e8ca6439,44f308a4,a264e367,1dd02f4c) +,S(e719bfc,5f06b800,8e4e49bb,62361544,1a2b0c42,f673f3a2,1e139bfc,b097d6d,f0c83c1d,83f5df68,a1e3929e,e18c4945,d14e2c33,4f9165e1,a0a462c2,aefd7822) +,S(77766a4b,a9d8cd62,840b1127,7e697dba,dc27c50,d9c8e35a,17f4c38b,50ad0a4e,5b3a2ad9,448327ba,22265ac,86c190bc,60b7586e,6f6e4554,b26b69ce,231b6431) +,S(f237721f,6215a855,f8660cda,41063690,4f2c9dd7,6260c292,597f28e4,348514b4,109daa1c,187b9f9c,ecae8c6d,33cb9874,46f5ade9,d57b3651,bccb9338,1acfef79) +,S(9408f5d5,e8891a1a,3cc4e7a8,a50dbc83,97517b3b,6c5af3b9,f1953f09,a67b3e08,1b82f212,c32f1ae9,c95f87b9,5ced2bf,ca33e954,32d9eb90,ed879ec9,59691555) +,S(b2837655,11707926,c9f214f1,3e90675f,883649c8,8f1660f4,c4f9f6c1,552a7064,89553739,15be8962,e6f03ca4,5bd5516f,be6ee041,519c4131,829b0bd7,6d1abfcf) +,S(ce42ba00,36b5f54a,4ed2a9dc,b6c0d29f,98641331,3f92f9c1,43767bfe,4b78f4a9,6e547292,cf35baf4,768c9179,2f706bfb,39b757d8,2452a802,4a7bd37f,e3a048d4) +,S(bb3da2a0,1a063a97,bec9325e,8d4af420,d3942bbc,42f0807d,8e9edce2,eccbcc59,7c28e7aa,bc39907f,ef58a19e,cd6e7b2e,25d6eb00,8da14d9d,5c559d27,fad70b32) +,S(25d84c3c,97f3a074,ea76f620,d6fb2691,dd3e9592,6de8eacf,5392c0de,36c490ee,5e0e7745,88c8a9b,7b91ffb,1ad6fd27,4153096c,9e759540,16f73a43,16d5651a) +,S(8baa3bfd,ca256f18,2e55a01d,e7c07617,7649942b,e743b4a7,faf39446,84d5765b,6147e897,8bbe15cd,171c2816,4730b211,587bfe7d,7e71811,7f308b80,d30506f1) +,S(507d6a0a,5b7d0385,11c65dea,8024c706,4d3b6b9b,287c7192,74c69797,21f5170,139f1647,70ea83ae,47ea8141,c3ae32bb,c12793d0,ce30fb37,2dc3adad,7f7bf5d3) +,S(7c6992f7,a059c5be,99b7354b,10fc217c,e45620f3,b4ff30d6,d640fd3a,26bbd846,964474e,fa63641c,2aa7062d,7139fbec,1f64e6a0,50e1ad03,2741a0e3,b5e0bee6) +,S(f62832b0,1bf65b23,14850750,9ea6f157,3d5e3317,bfb0a38f,cfcc6692,5a698bf2,d7314810,7b8fdfd7,3f6ce6f8,84f375bd,1546cc3b,8c75840d,3668c2a6,54c1ec95) +,S(aed21cab,d8e4ec36,2b4e2091,3be3c7c4,594f628a,cccca657,deff8b9c,6bd1ebad,f800ef3,833c7ffa,a8ade1ac,2f41d456,b880a205,60251dfd,f9cdd672,bb7100f8) +,S(46de78a9,343a9a41,6b91b877,aca94252,9e0ba8ca,b6c01f66,e06cdfdb,714bf405,c1441252,4f3ea73e,e12809c6,f19184d9,81f30b87,8df8bf6,6c89d98b,ed4d2bcf) +,S(2832b5b8,ab82e932,5356ae19,3043b99b,ba4b6591,a750a174,a6303b42,54bd41bc,c0363e03,3f59f149,23ece534,cb86695,a8275224,f490849e,249e63f7,34aba440) +,S(5b57c502,4b5c1621,77cabe39,b0f36bda,d85bd04,2736c7ff,9395f0c4,cbe43f9a,842407,dc0c0473,f1bf57b9,b35d84ed,b282ed4c,7adccc06,8530c8c1,bd20766c) +,S(b384da70,8063758e,825bf821,196b4a9c,814c45d8,a9edbaf3,dac4cbb1,c1c2f103,e6e661df,6400cc40,74f92596,590757fb,aa237515,af30ed13,df30befd,230fa325) +,S(36ffd991,563e448a,9b0a5da9,61a5466a,82a5b672,15ec8f8,e7300c5a,5c9a5e1c,97067835,fc17d47e,94187320,84d722a5,d1a742d6,4b513b6,32aed897,bb961c) +,S(8367e452,57c20367,e4e60ecc,33adcd87,5b9d142c,c6c362e7,f5aab34a,ed89d81c,fc7ff090,3ffab26e,d38a9e74,df43819e,b77ce2d5,bbdcf27a,f1f3bf19,948be121) +,S(f6ce47e4,8cc9296f,b40539e2,41238658,4719fb9,d4b1ad17,9c98969b,dcb0564b,368d2b6a,fe5edc0b,6f159017,5cd192ae,b524a606,7800aa60,930d60a,87950e1c) +,S(438c23e4,bedaa6f0,527d20c2,a725645f,194ccb58,8ff9eac6,5091da7b,f9fae013,54620a30,c7218257,dbdc93b5,3722a213,e28dc6bf,f8e48b45,6d6131a6,92ff15f8) +,S(1cf672f8,cc9434bf,7ace8722,85db5017,a1fa1dab,2eec7fbc,84e8492d,86bee7bd,d6d23d25,8bb4dda5,957ccced,b767cefd,8932b511,e2479018,16734bc5,b5cafdcc) +,S(47464e12,b0fa29b6,6e9cd157,4f7155fd,94305263,8af28bf4,4325a23f,3e1a2861,209a41d5,3bcdf566,5e966e80,84869a83,a2468db0,a1b19e56,81da864d,a2b05141) +,S(a9adfba1,c884c904,e6877a0a,9bbf73ae,c4ee223,e0b02ff8,717c075a,6aa964a2,ab16101d,a7bbc35c,73f371d4,afeb527e,b2d809a0,8487a36c,6cfae404,83f79dc8) +,S(2932fede,10600312,5ac983dd,659ecf95,824421ae,5f417f97,d3101c6f,c58edcbe,8601a743,e666156b,f2e34fe0,6f4cb11d,2df54fe1,7c842176,e1075423,dd76d727) +,S(5abf5528,2f87ad04,202b62c5,8ff7440c,64f9ba39,e6989df3,e31d665a,73a50216,71dc4e16,f2705c02,2ca1b37,edc5ce0,610b6f57,282d69c5,d3269295,5a1fabf) +,S(419495d,9a121cad,41887fc2,82c2c7e6,f359cbc,d24093ec,57399c3d,a801843a,9152e197,40295094,11afefc7,83990732,d5e6617c,d8e389d2,956536aa,f73e0c31) +,S(fca38482,ea2be49c,3c27979a,5acbb158,a902bc4e,226f7eae,4165ab7a,29fbc3af,1260735e,5fe62664,90a35f0f,7296c441,bad50a75,7b00e34f,28856a6d,cf46f5f4) +,S(bcf05123,3d703688,aca13530,55bc3ab2,d499ec40,8c912de1,4b7af456,55065d06,f32657f1,645690b,35484e63,a3456885,c16d4991,7670e71d,5f5cb65f,a5fb8bf9) +,S(4e70b42f,6391b424,b159cf74,f5fc96b2,68bf6cc4,a26658e4,79dd8a4b,8e9a92e1,8ba78811,1af31c06,77b24fa4,4b6ce356,66c595b2,3fe4fd36,591b33f7,e53b3688) +,S(3fe853d7,331c60ea,c213703c,a7628dc1,3cdb83f3,8a25ce6e,1be84f0d,e921742f,fb7dbb77,c2c6dc13,6f596154,f24dd3,f27b5125,9b60476d,b230e54,5ddca5d6) +,S(d803377f,c3cadd40,a2aa810,4e97641,ca42f582,3ccf65f5,ee726349,f648b9be,6357b84f,281a8080,54ab7fbf,ecc113ac,aeed2118,5ad12900,d824719e,8fd6fe99) +,S(5ddfdc7b,6f9e7162,2b7128e,77fa5ed2,90a05114,d6d8b845,94106c9e,70bebe1,23eaced,fa1efb7b,fae74c81,a1d03066,714b6dd9,1198e1e9,d5911ee4,55cd76ad) +,S(5f150243,c964948f,e91353e6,b12d167b,7913b46e,d7214411,5bc4cd4a,3b6f7dd5,36abc949,7a2fd102,14991e2,ba360c4f,b18147cd,955754e5,71cdd4d9,b8af903f) +,S(24b4fc97,5b0c4429,7a4cc89c,2b127eff,539f022,61544e14,97969bac,50942647,bd3e3fdf,54ad07d8,5faf8881,9014a77b,11d96f2c,a43cb8f9,a823a257,9eb5c207) +,S(a020eb35,5556b5fc,9de5ba2b,28644187,f11b18ea,ae61e76e,1dcce55c,e42202e0,9a71ea1f,1ad2f457,16b667c0,a982e2b,9765ac6e,beb71880,27e9059d,56639f66) +,S(60b79064,f7173eac,60531de5,961c47e3,8a224c78,ccd58a0f,86f6afda,e1f37a68,3ad04a4c,f6a47d6d,6b9fcbae,d8b54a7d,3437e4e3,627256de,cfc5f38c,490786b7) +,S(835cf1f2,b57d1e54,4ac2d915,9c8e3fdf,d2e233b5,d1109685,1777b7e3,a1f7d60b,7d23dd35,136edb13,bbbf7733,9e1c6e01,a7112f95,7c929b16,1665ca07,f6a84b31) +,S(faf74350,1f1edad5,2e1d8ad,e4b319bb,606cd7de,3188cdca,b1d39527,837f77ed,dbbeb0bd,bffb580e,4b9a0fa0,39b7acff,fbcd11b,85751476,16d48bdf,fe21bcc9) +,S(396c6fc3,e072bae2,3e7f74ed,f121271d,44091a5,d3b2a762,a39dd77,d2de938,5de522f8,a143544d,4cc49940,96b8f54e,9fb0e076,f46aa479,9e99d162,de6fa667) +,S(f8ab940,ad8df2ca,1c2622f8,8ef20c,ae8e605c,1e43b684,881147ee,d44ab88,99fe5281,fa7427ce,c9857163,f804c429,630d28f5,33e451e0,4063e70d,ddbff796) +,S(a6202868,af6dfffc,1e122219,a829c374,8197af4c,95901e78,75841b46,bd772367,2607a20b,c82a49c1,4fa54eb6,f8d68d8f,fe9c4fc4,d83b0e4d,145f7bab,5e9af45) +,S(b12d1993,49a98616,90764484,23a4fdbc,cfbced5f,b76a2bda,4d7c4984,7067e41e,a66dd4e0,ac6c8ab1,29045eb3,f7014449,73fdd555,7001b7ec,99c33d,c2d75e31) +,S(8dc8f55,b4990f5f,c6cd3b97,b1938304,9ae0a734,5cdc9c64,fd67bdc2,15eb3b3c,1be7457d,62cc8fd8,cbb54cc3,88722f4a,c00ce438,c847c2f5,fa641119,e5435d83) +,S(2c0b7337,d1db9e4b,7d521c4b,36351f65,f128643d,add0c53b,1b6d619c,658feeec,e8a27b9c,eb7c1219,f7bdae62,c07cee15,ef765b95,3b082d9a,d8b99005,b39bad53) +,S(891fb4a2,50100689,a48a0d1d,22414ab2,b17ad692,bb5f0d0e,66d06c93,da3bab35,41685166,cdf43c13,be93c03b,c347f3c8,52d06c0e,661a4c7c,cb53e24,e7260f6) +,S(4a3379b1,511c440f,e7213729,de668ef0,39fbccb6,1f5bbb02,ed99ed3b,69ca1738,b12a3dc2,39e9191d,a89d75ee,db44ce88,17b3bf03,d4172b00,39d1464c,a3ac0f6f) +,S(b8b2a7c8,54936bfa,62da360f,83bf8d65,7dc58e3c,1c8780d2,2c57061a,5f815521,8f922c0b,7719362c,25ac7001,252a89ba,1cd4412c,17c2b021,c065a3d5,f6a2d15b) +,S(9066fe19,d1dc52e5,7a9341d,77cf73a8,2fb56ab6,22c97a7f,f0191247,db9624fb,23d19b43,6ec3c575,d81d4929,eb6789a4,c281f5bc,abbc896,2153e7d4,711baf50) +,S(bf9ab14c,19c9e9b1,ca1a18df,2b5b73ee,9f32c8de,6e6757c2,b0534d75,7cced8ec,ec969923,3c3863de,aa72418,837a3af7,85e79375,d5bc91dd,481f174,e9759c0) +,S(68b2686f,9c654a02,225b7e69,e8eb7aaf,78c65686,e885b1af,10265e35,316f9d03,1d3d7504,846826bd,8554d407,739272ab,b6b407d6,f4f7419a,f284b81b,f14da9c3) +,S(20dc8385,5251a21a,94c989d3,92c9f36a,4d3bf669,bf7bda7d,e0427003,710bf2fa,217e6ff,713d329f,f9080c4b,3608c877,975d6794,5623e24a,974760f0,95aa749f) +,S(f0beb49b,555d998c,a39859bf,8c59184a,5c822e46,9a875568,1689a1ca,b5fd0368,e0e05ae7,a23ddf94,ba33b3b3,a75d3f4,2e8ff7f0,160c32f5,3bd08b40,72664aac) +,S(8f1aa973,270ff9eb,a41ad8ab,f2cf4c44,16ddc1ca,dc8a62cf,aab5a3b5,c4a0ee57,90aa3660,e3409b17,a86a441f,12f6eba0,2bd6bbb0,2b9a0a87,71e30a6,595920ec) +,S(c71eb135,278dc147,60cca847,a934b880,fecd43a8,aac9dfb,41382283,928a9957,41667f77,485281b8,89307ad5,decc7f6f,51d23ac4,7e71b299,a9d8715e,b6003804) +,S(e900726e,50d66a9f,37d09df5,d4965c5c,fa904d3d,bba1d180,b0fed651,bec41c81,d520aa30,db036f40,b34e64f2,cdc7d7b3,117f7725,786e9d5a,921c5f09,71028e39) +,S(940ab0af,a15952a9,ba3a6d6b,720efde6,58d72dd7,4f87cc3b,edae63b6,123fa38,fec6d747,6f788a19,b85e443a,a49116e1,6e5061f0,53c40702,f8765d28,f3bfcbcd) +,S(9a13de6d,643e9866,4df3ce9d,412c5ce6,a03ba46a,640c6be,8b62e70c,a8c76949,42388296,6c2d8d87,8b4c914d,4bc6cbc9,a4601630,2eb6a499,6103953,6926dd5e) +,S(438429b2,b31129d9,4a86b149,7d7f62e9,b76d6a5d,bde09d6f,256f83ba,76c577c3,e4360186,a7229be1,b33cb600,be833bdb,b2398e98,7c46c6cd,2e44f932,5cbc1c7d) +,S(3f63b25d,66d472e5,fac7b524,e4300e97,c8bb59be,6a3a8f01,8c1677c6,96d02605,4587042,158e19cd,2bd19bbe,5cff2c69,d9971aa2,fbdf649d,44c95f3b,50ca39dd) +,S(661fdf7,17c7a520,a384f90b,98dedef0,47afe5ed,6cfbd3d1,e1735c5a,bb8cc0c5,bd9a243a,b43c0e19,2592f00e,a52f820f,b83b7433,b1d96549,d9970293,7da80abd) +,S(b9c1bb26,daac6af7,d0c27c36,7ea2d4c8,c999d7c,75bc58cc,279c5f89,5ab951ce,a4d3bf34,a42b86bb,7c66c5b2,eed5d7f1,b872d17b,b58c938a,767b87eb,1b140f4e) +,S(cf5ac4a0,fc6cd9d8,50aaf473,3efd2bb9,7d9b23ec,bab5d099,9b11bfa0,b127e8fa,44926316,c37f1718,7fa94fe,3a62caf5,ad465d77,fd484287,2caf1605,f91070ec) +,S(aa52b2af,ab8da32e,3b882c57,ff0a34fb,749caaa1,b3c29b74,13c86471,beb3b422,4b562728,4a7be595,1b68df35,e320252f,73326084,16c60244,ac4e3ecc,c0859ce) +,S(610f22e,b3aa08d0,a9f2909c,546896bc,7926b056,7987217a,d347f183,4868211c,a52e190d,f35fc4b3,19571e6,166eda3d,2dbf637b,c27746ea,c1bc3552,4819e6bb) +,S(13f24c3,a485a58c,e0454330,79512796,db65f15a,4265fb44,acc3cc34,c51a6d80,faccbfb6,18e069ff,3cdc4327,cf807366,f07976d,b24fae61,1a44984c,7f3bc3b) +,S(15cebea8,49279b29,cb0112e6,922c5a85,caeb18fb,415cebdf,92285d9d,a0eb0f24,23e5ccfe,158ff9bd,539af7ed,4a77b1c1,c36de452,8d0c0d05,821e89f8,e075d833) +,S(2605a18e,fb7d5367,dc41b1d6,24d61a,cf92e0c8,96f29a5,5f2dc872,4d97f6,8d6a6774,f111b7ec,dc58ae51,80ad6fd2,fd6d674c,9402e2f4,f944bd50,5e66d375) +,S(e588e272,a78756f3,7fa36d6c,d35b362a,25cd0513,3694b56c,33d0b05c,be7f9995,15beb983,20b84296,9b8715c6,ad23e53e,115425c0,d071917,66e56ffd,5472fbb7) +,S(80032522,f264edc5,b6b205cb,f79ca7e,3a02cc39,93458b6c,cb98750d,bd6b46a5,479c92f4,fb4e1eba,98f8b93b,5aa9725e,fd2c1de8,d4c3d043,bca7183b,851a44a8) +,S(950c040e,e1a581b5,70501308,a21287e7,94b525b7,f916d3f3,c166a2fa,1641bfaa,e43db20e,911d70a6,9f171725,f760237a,52441a88,dc385a75,1e4ef1db,b738ea71) +,S(e899ff36,423fee57,2e70aeca,db8bc0f5,a634b9be,282dd875,9db5500a,86c391fa,7ed97b0,dfe6b68e,26710034,f87a911,88611790,cb18a790,a0248c7c,b43a9bd1) +,S(d236688f,c206b7a,8f8ce5c7,66e19fb8,6a7415d2,9c57845e,8332a5cb,d8a1a51b,72f2359f,e3d54a60,fe6d6508,5183b525,d5098887,55219113,adb05c2c,656ec9e9) +,S(8d3d7c71,da4b2f24,83e458c5,85c628f5,430eab5f,ddc2686a,e94e2fa2,119dcccf,33c408e4,7948f20c,bd79c22a,d647ff1e,1f435c03,1f594aad,82778f58,1f61178f) +,S(320f137a,e8918199,51a542ba,5d1063fb,fee4b750,c56168a5,87d7fd9b,b72651a9,b840546a,e2a4e1ef,32275a02,153bf003,8603698,a8c5e232,6795bcf3,d3c402c5) +,S(9e8affce,3fe6b259,f4568607,2d46401a,7546c87f,9a46e0de,8ce577c6,1881352c,d0ea3701,d83b7f7c,260ebaf0,97236525,af8639f6,c53ecf92,73e77bd4,c29d02f1) +,S(5df465b8,1d353987,293c915e,a24121ef,daf70ff4,9ad2bf53,9bec72b3,c61eef64,3206c5ff,5ae4c841,58c193d,40f46083,8b38047c,f33c3e54,38541a7a,d5e690af) +,S(999cd326,a18c350b,f4861d48,826ba3c5,1312bb39,886a064d,6e1465d4,8ef28f58,2cd8ab2a,d6dccdf6,7998e662,99551608,a9fceab0,be884b0d,d418911d,c8b1ef12) +,S(81d8fcee,574d9c16,fa2ba6f4,255460cb,479a6667,4761b4cd,c0ab026b,6bce163b,594e7f34,f5897a6a,3b79a996,f5a69814,3cf771fc,fd7c8ca6,38cb4ac5,98673143) +,S(9e83d724,b9ac73be,f932b42d,56f85183,85839c9e,c953a0dd,4da6d843,d096d278,f8b18cab,fed05acb,89efda95,ac496ec5,d3a000,a4a1d689,a1afa5e2,30c88869) +,S(98ba38b1,3b443c08,aecb1f64,73b2d901,908ec33b,35baa317,64f91144,3e320c3e,343f61d7,fc2232fb,f5d2f972,e6f42f49,d8ece7a,3434a0a4,4df1d602,3f99b84f) +,S(2092ea5a,9adf5eec,5a7a9488,6e970671,5822447b,e6c35285,de704806,52a875ec,ddfb72eb,52382722,a94facc8,e2616661,95a7e9c2,6594228f,304adc7b,ea4e7f35) +,S(f9ee909a,8f45a05e,ac77bce4,ebc97410,c044c639,95a1de76,5b9304c2,2eeb75a,861031ba,93f5b0e8,473e50fd,2aeaf13e,3a39c0d3,7e2e9d51,a41ee4ee,1301705e) +,S(a13878e2,3bc55a7c,b342dfc0,2eea9bf9,5c676e27,c63e8603,c75ce535,35df101c,35c0ced0,3d4bb091,92a2f83,3d3e81a6,233f0585,35c72ed0,1bfff82,7b108427) +,S(e8ec81d2,cd32dfd8,7284cfce,9d80c03,b863a7f8,3a71865d,34f7b1b6,104ae3e4,60be9b77,ee12dd7f,f532b01a,f517bfc9,1d24c4e8,b0865e4e,c6e27227,417648b) +,S(f07cb255,1529dc43,3470b18f,e4e06390,d48e9898,69b9a97a,6642b898,1cf35b60,bd46eb77,6d74633d,59b4b941,2e2355a9,c6e85421,59513d2b,a3297a6,c223b550) +,S(39bce423,dcfda9f0,a97189ae,a60b836,42becd3f,2f2cbdd8,2fe884da,baaf7f51,c1599caa,4b71219e,74490312,7303ec91,f3430be8,14979a2b,2db78bb1,ea2c8e4d) +,S(6da611cb,d51db814,18b3de21,13c9e4ff,58142f67,cf2d8ec8,e0fd105,1e9ad3cf,6bc2f048,3250f654,fdbd494e,bb03480e,f7fe5568,2e19cd70,4d178ff3,41e4b7f) +,S(cedb9c03,8d2e0eb9,8a4a5e8e,fa7e95c5,f4e13a47,79470c70,9a3c9fbb,8b1aed8a,79a2fd31,de42d8bc,820d5d56,ed084f40,46804fa5,f7f5e8fe,eca6ad4d,859a0d40) +,S(7d895498,6d1106d0,32f40458,f6c41fe6,25393f84,d00ded8a,3a07a107,5ae3d82,5d4fb6cf,ff1c594b,61aa117c,7e0ade0e,edd110c2,b2109866,ee7d586a,1a6d0d61) +,S(a4f29162,737043af,eb1e2606,93ecec60,851aaf50,c6e9daa1,75a00c43,d7dc3df7,beebfce8,fb764b15,38fabb20,145aaed3,92265d7b,c4628846,b2726821,c79c4439) +,S(b6389dac,de4ccb08,ec0ce964,e689bbcc,e0ba8165,6680c0a2,9cb162f0,f91cab70,e440c7db,d2d02474,17b2826d,28e31fe7,9ee836a7,eefdacdd,679040ca,50303529) +,S(72ce6dac,f752c36f,978ac2d6,aeef37f5,ae4ee016,999ccb49,27b8aefb,f6fcc9e1,ce6ac297,bbd84403,d60c6d4d,5e01027e,8ad38acd,e796bbc6,7c45f10e,d79bbca6) +,S(efad336f,cfd7425a,560931fa,a6bc50c1,4fb3e5ad,f8ad175,31b13846,6c255f06,3fb784f4,eeee9a11,ec7ab559,71817163,9eab6b09,4419203b,2b422e8f,e15a82c0) +,S(f98d4a2d,4bb2166,7c74bd1f,393ca57,22002c6c,f382b49c,2895deb2,34eaae3,9875e31f,7e3778a8,34750763,c6147cba,97a26f8a,d669e69e,9a36cc45,b56fd148) +,S(768cf74d,2bc24233,2c5eea34,2ac13ed1,2b0d161e,65876eaf,b0b89460,c934183f,42337607,e55b4d7a,f86e9f72,dd06a550,af083b32,e72e6265,4ba00fa7,a2fdc34e) +,S(ac26f3b0,1d05c625,915ec27a,aa916d0b,d34cfb6e,22525c59,9791274d,a5beff7b,e36760ac,89b61681,d1913bcb,1ebeb199,a3005576,b8bde54a,42fcecdf,e94f4045) +,S(dadd4181,741a0be2,e665045e,1b042a3a,fcd9050d,a08d1285,21298f34,1f74fbac,6cf46fe0,da78dd04,261e4e2c,863574e7,f6a4dfbc,a902802b,8056e00c,e4a84f60) +,S(e5651598,ce9e6a86,2fb139ed,143f1b73,2c4e1eea,91a88f82,a6fd0ab9,1a86a3e8,bb421336,69ab6c10,109723d8,ff4d5f6c,770fd8a,d569a21a,9e9efdb2,f1f1ac98) +,S(f26f791e,b4f0f596,39b69b45,401ee3ab,2d47a2b7,dcc3d65,de9e48ae,270f5b02,22e34b25,1fe5bbf2,5183c799,ea45757c,2693c591,633a84fb,e1a9bc0b,470ff699) +,S(a50cf10b,95612f48,7a9da048,a84dd8a3,2d2bec22,9db798ac,19fde68e,623da9da,50107d3c,a76a264,1db9f9f4,7cd60598,ce345ecd,cc3de888,e4c81553,bdcc576) +,S(c74883b9,2736c1b,d5f86a5c,1817cb9b,e917e5ab,5ec5cc10,a1197f1b,a45c13c,e03c43bc,e7393cff,d53e73b,60ea2759,d1c2bd55,c2b7a32e,847f4bd1,2c8beedc) +,S(a3437d0,1741ed88,bb05c00f,629e2c8d,be7cada4,dd002e9c,98dfe800,9e1c0a9,a627e05a,257fcabd,1fda00af,a4d3eef8,fc268e67,bb41c9e,d2160713,847bca1c) +,S(a6cc4988,f179bab4,de98ba89,530686fc,90c00c77,4a3f093,8329ffa3,99c8312d,f4eba473,7db25a79,29bcad7c,11346471,bbba86ef,4f611643,712ff475,9d70b6df) +,S(efb34a8,f5778d57,b3333077,6ca1abe3,9e680183,13936f24,da1aca,70b84dbe,a94a216e,fc53fa98,320878e7,167536ba,7e5845ca,149b2595,2f029878,7f428d3f) +,S(139846d8,1385e6bb,b23914ef,487fb9ab,19ec3b8,3fa45a94,a2c5fbd6,fcdfa07a,4fb7cc4e,599b10cd,a99f6aff,28dfda0b,62d837b2,e8c96aa0,9c34cbc6,acfce099) +,S(660923af,98ba567a,83df6eea,ab53ea62,49c2090a,13299bb7,a538cdab,adf2a101,b28b58ca,b1a29722,699890ee,8462f440,ee2a5686,9715478d,4460f0d8,8c94bd29) +,S(f18092b5,8c7517de,3f389d31,f1a6345a,d2f86bd0,c1dc9a98,d3e03890,f52be3c6,a83e7a04,91484ed7,7dc27697,33b0321c,440ca763,2a36c6d0,7e8a9afd,68f9c906) +,S(e8d0aa0d,1b2c540f,38a6a6e2,5b5fb295,7b700467,648cff74,bfee1138,81d0ab75,a324cbbe,52055c1b,d0cc3f29,88a80982,1abfc0cb,feaa56e9,f19bb8ab,d314409a) +,S(2586a0c0,230a0743,f9613df,51f7463e,1d8ee72d,503025f3,c7d2dfc4,6f526c1a,a29735a1,eb2b470d,43c7b469,4850f5c3,ce9b1da2,47406653,ede03ac0,9816c735) +,S(217cfa88,8d826d46,c31bb2d2,7dd7c8f5,8be68254,e42c0e48,a12cab42,677dffd8,4d5d9c30,9ff0fb15,35f9901,7af91ded,34179c57,f48131a0,6d96b6a,c01ac4ce) +,S(4ea65934,71aa3b8f,9e6791eb,37cfd67,943af3bf,100d7ccb,8203a353,1aedf4c0,feed9ac4,19a302c4,58047403,5c95e997,ded8a534,c88beca5,6c12984,84b7b4c5) +,S(974b828b,51026aa4,ea522150,c497eebc,7d7759f2,c9645f7d,4faac24d,18c7a1ae,c0369da0,c3087336,2566f344,ca81f261,65cd3a03,fcb05093,96d18fed,4faa9d26) +,S(d9815b79,d572d7a5,94dc8ae9,3cf45b36,99bb4544,ed1d5755,529c7096,9c978186,9fcebacb,f5181954,ac4ea24f,508fa67f,5b6c20d8,64ed53ec,d67e358a,e75241fa) +,S(52712597,d9bd4e7,cbd506f1,bd65aac1,478208bd,f9f6ad38,efd2b30e,b8368837,52eca996,ba2cecad,9a0911d1,65368010,68bbf0c1,12d6dd79,aef23262,8b3df18e) +,S(d94231af,d890f5f9,ef70e1fe,e8a8f4e8,ed2fc89e,2b8ad818,6af55de8,449abf6d,26592b6e,f0789218,273475fc,32d865cb,84278ff4,8cd0de27,e0646549,219e2867) +,S(64851231,7a69d956,3b3a99d4,b763eb9a,b661f7b0,714d34bf,e5328a4d,a99a7d90,eb20ba33,515040e3,6fa02088,5a3e9216,1e06d3b3,78122fb4,af4920a3,51d46bc6) +,S(d0a4b11b,ef662f17,98f413a5,fc062567,70df9edf,ee00217,79c3811c,ef68a8c2,d4bb9920,18e16945,c38ef5c9,9ab39eeb,748b7a63,ff4d4dbe,8b329f74,dd70b9cd) +,S(1d89b886,c4b24868,1fbe103d,dcbd76b1,dcf54637,3bd5249b,3dc07f06,985802b6,a339ccca,aacd1057,7e36056b,a3a70c6a,a7885a45,42bcdf30,30d0939f,6369535d) +,S(b6cecdd5,936343e4,f136682f,a38ba0b7,9dbab223,beb0b6c0,10a75cb2,e4dbb256,2935c053,87dd87a2,5bda5d1f,ed813666,5f77d12e,8242dd58,3ba8db03,319f7be8) +,S(84b244e0,a0cad847,35ca6c5f,bf581968,40f1b491,98682c4,28aea50,bf2f8e24,62e28e8c,7df80b11,f5713087,ee3a5d8b,148c8e62,da0de1ba,d8289ac8,861f7a71) +,S(f95eccff,2a908028,39436610,2e377c41,66433159,43feb6d1,638df6c1,cc114d1a,bd0da83f,1a0306cd,b8d1b9ea,189856ee,56d16e81,61b4f9ca,7de38d2b,e558eba2) +,S(7c4cedfd,3e613de4,af2ccd25,59a2dd23,2a1e6335,e410d327,27fef321,d10f55e3,331f2109,d9d00536,c697f73c,672a660d,11d4827d,41306696,cdc224e,e7d7b1d8) +,S(235c2e38,1bf2d829,e4b918de,435e276,f88af866,ed31a1c3,4b9f7203,a0269713,50dcdf0d,2671092e,e7c48614,44eaa87a,815a1304,4600fd0f,f26104ef,a0dbf929) +,S(2a961cd0,9ab50975,517ca488,d1c4a388,cdf2686,c5dde923,76128683,ea07cd73,85c91076,b2ee46d2,3cc0f7fd,e7654723,84f84c2e,edd7552d,d7f93be9,2398abe5) +,S(958bc491,f0afb8cb,8713f591,cbf183f7,e00c4775,93d1b51,a628f40e,4cfd65e3,bf5be339,fa21dfe4,9113e026,af0761a1,b2a09a7a,ae8f6eef,92d50c6a,89a65b3) +,S(6e960ca3,7b5b7abf,99f5a2e2,46b7e953,adb5ccc,6424e73d,dc865bd8,3d5f78fd,53ad4bd1,d5e9643f,5f2df612,ea16fcc8,dcc4b0b2,9ccd5a81,bd659b35,6a5e0e15) +,S(d7ac920e,9272bbad,dd961525,7d91d6a8,e747e4a7,a48ddb5a,8b2ece8f,f0d05871,6381b9fc,c37bac5e,38c0b96d,c098c3,9d4c7620,61b66dc4,adf66e24,f0c87ed8) +,S(9b0803b,1de95706,ec123844,ebe941ae,4481c12f,f2d9c078,b6c1d531,5d730609,160cf3d6,b12afdfc,eac2ed01,fe4b801c,5a5ff0bb,13cc3ef2,f5f0962a,6b3fb1b0) +,S(5d50746e,5b74e006,9dce0153,aba04216,991bd509,f022f3ea,689553bc,a4c5fd88,b0fb205f,d2a14b1b,bdba2e48,429c92b6,99cb336f,b6ed0e58,9276118b,6b259ff8) +,S(e1bc2669,fa27629c,92708748,36008c2d,ef4483ab,c686ecf0,bbd01a85,fcbe04ff,6fb7af71,83c0921,6173fd43,5b3a1b2b,15e8b149,3bed8e78,3d409f84,cd95ecf) +,S(cfc9081c,b5a893db,40c51979,7dfa1cf2,f36ac620,cf7017a2,fe90dccb,d8bfbf78,26a88d23,50772fc3,2f377c15,a9bf817c,db321d1a,55c4d659,b5f29ae6,96a69ac2) +,S(54d9c9d,12bd68c5,3961246d,b98ed78c,cd8ad158,8458d4b0,5fad9df4,2229bb9b,b5e97c31,1dec2259,630c961f,ed33d7d4,f8de7005,849225eb,a4549d76,de1cbff6) +,S(8a914ee6,7e9d6619,d00f1924,8735c7b2,bfb11eaa,61fe42e8,d64b5a53,43057dff,1b91e1da,3374da49,8bc2f018,c2a6fa51,99c51846,a2f59b05,a6311ac3,1bc040c8) +,S(d4b81177,3e641dfa,bc704fba,e9ab0ab8,aa2f4c42,fbd23b03,a0b0595,d0240522,ac30ce3b,1ea4a14f,4a5bd364,20f40df1,cf2e6835,17107b8,ce6fbe05,665cc726) +,S(b810a787,c232357c,bb82c351,79249f64,6f3c8e2e,72e0e004,36226670,14780ba9,54364034,1078dd7f,216bac76,9abc8467,4a422c30,f1b7aef7,6a2dbbb0,158319e2) +,S(d71f88ce,dc738ef7,1ad691ea,c3a7eed0,d29c762d,8ec7ce0d,14e72d3f,f534a833,a47cce83,1aaaadae,a2d9d0d9,7b4c5125,97c1b514,95c3aad9,d2a4e716,cfbcd99) +,S(170cf31d,4cac628e,139d9d89,662ce5e1,1ad7092c,cc6c6174,96c99d71,6d147ffc,4fb3b894,e741f585,15e8baa,addf3119,adf6c4ee,695253a4,6f9a5dec,cc6d77a5) +,S(8e7692a3,b1275e80,38ccbf66,ecb9a55b,bfd48d49,4085b4d3,1729a644,ecc316af,f339c1d3,af07525e,26500665,ce66a91a,4fc0bfa6,b8a46411,34cab540,68c504b1) +,S(5d1ff338,3dda5e81,32c47002,ee2b77ce,a07ca869,e7684d40,a27cbefa,4aca891a,a1adb3ac,b0decbdb,6772e62e,74c4516,fe843833,8d2979cf,5b091801,bf5fbb8b) +,S(d566cfdd,a9dec66b,ddf2605d,a37ad558,375e1c5c,5f5403eb,d75ff6ec,3c2b8af7,13e2232c,78586da9,741598bb,25a90a4c,b6007bd7,bfb75ed8,427ade0e,619c78bd) +,S(cbd708f9,cc713af1,999ae74b,2b9ee3db,3cb85bce,249c5e33,764997d0,2fd96493,f01a1d6c,4ca9b0b8,9337a5af,889d8dd9,c264f4bf,6b8066d6,55cf9267,684cb2cb) +,S(fee1ece4,e8ac73c8,8220bea2,153800f3,e8d049b8,f89053f4,ad4b5ba3,f0ed0fe2,9b5208ea,17c80640,a353354a,7cf42f6a,f9763db0,bdb0954f,53d56a2e,ea26aad6) +,S(c6aafa66,de444853,8d7a6c3a,fcb35a8d,db916f33,14c15dbb,79c48bc9,46ee843f,8a61c6b6,7fc590f7,bc81a761,7a6e24fa,34c49d5b,30b11bfa,7cdaf3bf,d1505b1b) +,S(ac351560,83d91f7e,4898551e,7666bbce,dcbe21ff,f005ef1e,a866781,d9aac415,d709d997,77109afb,28c318fb,eeec8a27,5577410b,8da6d494,5ac7d660,1334483d) +,S(a89c2616,7c024b4,81455d19,93ac04f5,7a212e34,95066ef9,21968f72,3d914e18,551d3662,6127866c,77df092f,5ed8dab1,3569ce68,433de199,ac8219ee,13a3c1ab) +,S(9951831d,b58499ea,e94018d8,cfb9162e,b045b95a,fd246a3a,72e8808d,1ca3f06b,fe39aeec,b9d5f867,d5827146,fb384808,81696ea1,5b0d1188,fd487b16,d9e4d773) +,S(b71e17e0,14564447,955be26c,61ecebc6,8615e2e9,37cd2e8c,78d26922,681fba96,ebcfddf1,d21fb8cb,95e3cb22,4efe9553,1a6c5ba9,cc92bdc4,3011c50b,63b9e3bf) +,S(e170f81e,dbdd9ff6,d460ef6a,1c3d4bcb,2fe89fed,4e6742c2,2d683ffc,15914074,93f110ee,f971cac,8ce206e3,df6f9caf,801fa7eb,c7df14d2,d6f67e72,ab96e67f) +,S(431a5547,318d05c5,5ecf04ed,a1fabbb1,4ac8dd8a,47dccc73,acf5d5c8,1ec104f2,3e3188ad,7b141a36,4afa1f04,57ca827a,7a6f1f70,75ca8dea,6fd08bf2,bfa779e7) +,S(299e6a6e,e1587523,2be26ce4,a1f80cb1,3c193291,7f0b5eec,383ffec2,62203394,5dbb70ed,3ad4a211,bfc8e8bf,4c00a055,23c9b3e4,ed3790c9,3bb2a77e,5301575) +,S(66db488f,f2b58869,b2fb5f78,61e7f825,bc99ac9b,ea02b59f,b0978c9c,c38934ee,ab76e112,b51c83f8,b10e997,2f6866c4,6040e7ef,eb14817f,c316b730,e8ae6a5f) +,S(1259856b,66980d52,bb3912fa,78ad5b70,54c812b5,fed402a1,c3c8247d,26274932,ead7cd3f,c67895c7,edfe0557,d5681bc2,d70dfcbb,870c7c22,45d458c7,f2150383) +,S(502c8614,cbb0f3dc,caa5272f,dd252c7c,4269968c,efebecf9,102745df,fdf1cf00,711bc688,7e4e356,fd9d0695,16af0a38,1b2f4500,6487154c,10b90995,3bc53c3c) +,S(e051193c,323c6403,f69c1073,47b6b7fd,f43acdec,17c00c42,2249bcc7,aa8d6fd,2102c271,ce428ee6,16d1d2bc,f25c2630,c574d9b1,87f8b9f1,c85117e3,8a560455) +,S(c9187bae,d768d32,29fd90c1,5c3b37e7,abe7c58,b538acb8,ae0741,adf1dc46,c130d443,f9ebba4a,197d0252,615ac29d,5714f6dc,f27fc0f8,d7547335,89c92c0f) +,S(5b08567e,b9f3b3ee,2b03ae70,1c6b0641,23dba4d4,4e8297a1,6eaec8d9,e90fe897,ad071c15,9079c91a,cdee9c72,6e8f4cbb,914d4b4b,750fed92,aa81a987,a90c27c9) +,S(ae5b648a,c5817a86,cfb06a26,d62691ab,8a9cc554,d0eaa86f,839f4a51,b43ba7cc,1ea8ab0d,b665c22a,ab0a48c3,da17c629,66e75212,a6fe9983,d5e925d,432db311) +,S(3b9bacd0,a092856d,98eea5c5,ccc9abb4,4f2e0d3,27e578f0,42102148,890178d2,b681e88e,9603ba1c,57b628d7,ea929ae0,b79be447,f181a491,1fdc65df,21bd5052) +,S(524df580,a74066da,d522f827,95e415ab,f6dfbf7a,1c1f6d7e,e8d05a86,4659fef4,3facc728,5f3bc1e1,a6fc210c,ad302ef1,9c72c5f9,e358b9c1,ed2aba72,2652f35f) +,S(2e0637f2,ade775c4,87d09a38,3480b875,599a34ea,7fc70cdf,f6ed309d,450e4363,e3c6eb08,7e2f4e49,cc78e903,e4ad55f3,1aafb7ee,ada72369,6da8a0a0,f764738e) +,S(f7fec6ad,beafbd3b,e413fb33,587b9427,3f785728,226f764b,bda6130b,aa0cc483,f646a974,8eb457c7,fc8fefd8,e63b976b,dd42093a,e59fc544,c66531d1,9e08c68d) +,S(75f94ce0,6af64c43,2b6c95b1,2d892dc8,cd6eb497,4d826299,29ad8bc4,8a3608be,bf8716d0,a2b7906a,69316b32,21ec0076,6e32c892,2c7be6c6,22e8877b,b1958a29) +,S(410296de,5e0df3cb,c4f039f,cc869090,f62e07e9,d3011043,31bdc1cc,f3fb4d85,e963579c,a314dd96,ab8a82ff,86265b82,da74267f,c861f96c,383f72ed,3ffecfa0) +,S(cc824eac,5f5e16b,2f7c1703,d97da67b,69b4e698,16cfbb23,cbdffe00,d73ffa05,17c30da6,9f414ef9,5dc58218,27c7880f,d18c6f1a,92afaaa8,b8cf10a3,353e8abb) +,S(acc1b0ef,4d26ed8c,d78f0b3f,d3177077,d2074b64,fa5d8d03,a83ff113,7e6e5820,6cce44c6,8519ae91,19d2a80,4f8fbeed,4fcd24d0,169e8000,11150c8d,9c3ce6c3) +,S(1cb3076e,ccce1d9b,774bccf,4318b921,583c2b8e,31877825,7c2fc71b,c90da922,2a2f276c,58605d,82a17dfd,3ecdc5a2,a6372df2,cf25bb04,c628748e,4ce373cc) +,S(6efda451,2a22f49b,587ea975,9e5a400,8cb3a521,7a38b978,3d5825aa,84fe13f2,11d44ed5,6dfe2fb3,1ff2a54a,de5a2a5b,60673cfd,bcbd5039,54a94758,878e2424) +,S(47f69619,aef4378b,5cc931ec,da8fd996,e2fcf1cd,17de9cdd,51b30c3b,9dbf0858,149556a1,9776e3d6,da457af2,a4d70d66,d2fa28a,c33abee9,bf890894,7cb5e274) +,S(dd3d8e1e,97f5dd5d,539032c5,13a19e26,8b2eaebc,1a47cd4f,8ff48335,794d28e4,7968bc00,20f6a83a,a973d7c6,382ebf33,c2233bb,34be9c2,e0ff9eaa,4c467e83) +,S(2bd454ee,a19d3a6c,be55737c,d3cb4b32,7de2a2b7,50535f91,97aad2b6,65e16d78,a70b0f0,d6a1278f,34271c66,7ad40feb,9f7c6248,87e3f754,9c1f1fd7,129f7f99) +,S(8cfe75bb,2a7e74b4,4da035b2,9a26784e,915462df,13ac2d91,4733184,f5a5ee0,648ffc56,bdc87c86,4f6226d1,c9245540,b65c2da2,7fdadca1,eeff2e24,6607cd1e) +,S(5eff34ae,19c462cb,c2fdab83,24b57bc8,5e046a68,4f112f6e,665b3255,65724d36,198fb5bb,9db347ff,c2289629,d2e01051,d551e783,47c6a6b0,ccfcde15,a04d68a4) +,S(9aa54554,f3673b08,e36db624,47631774,a2c51bb8,1f18aa61,426639f,78f92b91,8744a3ad,4a6e7404,d2e22faf,272b50bd,1d167b46,5f25c6fa,75c8d784,61384806) +,S(4b837575,8cfb5970,dfc7463c,5df06ebb,ac88a2a8,b9d7565a,955cb53a,5ff259e0,87591d42,bda1a53f,6e474396,a1233df6,ed70766a,ab7aaaa9,9171a5e4,fa8df208) +,S(5d4b74b4,9134f90e,673f5a57,959c7cef,c49dc725,85734428,226cc5ef,76428bb1,1b2a8910,f466ee15,abe6bf3f,100d8da0,cdc2f6bb,f19c3cfc,b1f07a0f,bed89425) +,S(d50be2c0,c55244ce,5d93bafa,f62ee680,2d475441,7ab9c2b2,5702a309,57cad2d8,fe207e4c,6ee89ab4,c0185461,7eaa5de4,5a4dc0f2,bc4544e,f241cd5c,162f583) +,S(bb0f61ce,8e0eb384,64e48915,5bf985aa,f93bbff1,416db2e9,a1da034e,1075bff1,13a715,2ddeb0df,30ea1032,cbcb08ef,4e6b0561,31474412,631f6fbf,b77b7d0e) +,S(3ce6bddb,473f01b2,170e41fb,22fc5efa,63e22b9e,14d9bd22,88632bf8,4ddcb2f5,43086057,f4b3d298,426b7308,110dc52e,9a84268f,1bac1edf,8d47a25a,ace0922e) +,S(ffdfb14a,ef1680bf,c90b5490,c7cdb75e,bbcbbff1,a56c3c85,bd37460b,b38f81aa,f3045def,2f1f19e,232880d0,e948b5a5,24f228c7,3bbcca54,7c216ee1,eaf4af0d) +,S(1ac1f2e1,9ab4264d,8126eb60,a2330aee,c828d102,507ac0fe,d59fa4c0,8223172c,7636a4bc,339486af,b215e3a8,f80d8f02,d8fae063,81b4e7f5,133f1936,d8e18bf8) +,S(52534c0a,740e89a,6142957a,a20f2339,b1a1a6b6,7e6c9a2,2d6661ec,adec228e,cf6fe6ba,fe41c899,c1ec2fa5,d884fafa,e1a31835,ae8022f1,365a97cf,3261b669) +,S(40920285,7cd22c2c,78cdccd6,137d32b1,4f36f2c,964a278d,5b9f6462,651b09eb,40c94f73,a5fa3e3f,66dfef1b,f4f16091,f6b7738e,b8a865fb,3bde12c4,2d031d0d) +,S(8b1d3c33,4b9ccdb2,14aac6e4,e840db16,25a5b3c2,4069d9e7,c81bc51,9b029289,114fd464,2acf9599,1fd65898,57822277,8020769f,145f86e5,630d6db5,5e23e853) +,S(ae14de60,b7c7f13a,59c6bbd2,64162dc,8a6055e6,3d3460fd,7e473979,f4a242bd,8b960489,cdb5a333,a14463e2,376f2113,afccfee7,afa00ef1,6cac6a3e,4c65a412) +,S(f37f1c40,99c95e6c,3e8d4e39,5dfddbaf,b8153948,137de420,788386e,2ed3e3d7,1f290080,82f6ad34,b2283d76,9cf76577,a564411,4f51af5,310c0a3,b3fb3606) +,S(1fb07fae,9636889c,34441c1d,3c2496bc,a13f8933,666d05df,aa53ecb2,1b017a84,128189c9,3931576a,c4b68934,b7ff551b,58e6da46,fa97fcb7,b8df8c9c,637753c0) +,S(44d1eb54,e112eced,480ea2b5,1ba22ba7,2afb0721,d0d6b715,52bd9728,4815f3cc,a6e13b28,574c526f,12673e02,ed7938fa,ea1855b7,d5b6e88e,3c3a9b2a,f2ed7043) +,S(6980972e,5732b875,7fe311cf,f76f7bd0,ec94918a,759a7cbf,d8795645,a103238e,7b9fe832,4ffb9143,21776b24,a92fa09a,ac4a0fce,17c5bc26,2d2eb063,63d26a5e) +,S(6a3a8c9d,405bb1e4,de59639c,4f6406a1,a8566a62,9d85b79b,f7030255,50efcfa3,3e8abae8,7b22d04a,8fdb408e,196b47a4,2e0f59eb,9d51924d,ce8de66,cac038ba) +,S(ff3108d4,1598464a,bf5844c4,dbcfa027,bfb6804c,946c3683,1da390b6,4412ed0b,805565e3,3ee1d089,5c6abe85,77054648,11f5d4d0,219cb515,dc072d47,cbd0a317) +,S(ee4f76a,2f8549ab,3e134e53,335dcb5b,49972750,180491bb,2139324e,95517d73,6bd90167,22402b11,68989e89,9c942767,8307367d,8a29075c,8fe81049,7071a838) +,S(c21175cb,1ca958f,36a3b720,5cbaba0c,230c6305,8cd09966,ac78f51a,4c53e0a4,6a2183a6,7a7ca0af,256a0ecd,2c085d81,585a02eb,2ffe6a44,ea923688,cc72bf51) +,S(2d5e4c08,a9a0b398,34e46e39,e7cab91b,953141c0,c5f2d292,c409cbf3,9a37d6fc,7569b9c5,31a331fa,9234f37,e9005ed0,4b512721,dc4ef054,d6164046,75c6e15e) +,S(6302c041,bfbbeb09,cc012408,631765f1,5d573b67,6b799c26,ef7c2a4c,bb15dbc3,32a8f20f,67ce42a0,ac4ddfed,d0932e91,a1e51488,49e463f,915af082,7e491025) +,S(3e61516c,198de08e,f7dc9cfb,89ef9b94,5b6c67cc,2deab08c,a3b36612,5934e2d,1effbbf7,4d5f7104,f7784944,70f62784,5692f3ed,48e4dbe,e956e063,37520d9) +,S(a008bab2,d7d134d2,4ab35a37,8f330521,b8989219,108b05a7,d8aab0ae,e542fe30,77a377ec,903c06e5,463ec2fd,e9c05e43,f5454aea,82b99de6,be09fe31,51b475a1) +,S(7782ff48,b928962a,950f42b8,2e43017,28711467,16f22f8,c389917e,a624005f,78f23e49,38a03e0c,ad1b766d,b9bafe30,8ad2c9cf,5b22bc18,c78c8898,fb608c15) +,S(233b4a78,c26ab44f,d1019d64,8c896eea,f6ffbe71,8cfefc20,d20676f8,27ddcfc2,de508436,d976df90,487ddc1a,48284cdd,f553d342,2e0977b5,18f3ed9e,773b655c) +,S(8014aa29,6eed493,d83d7aed,2d8c3342,3f7a4623,295f2a07,92c5de0c,71b8bb0e,dc58729d,f2a5bc9b,1170caba,4856a9e1,695f39af,81a1e444,f3e6dd55,f583d92) +,S(8a01e90b,233dae71,1bb050ce,7bc61c8c,60882aea,ebead2c1,b284ab59,dbbbdfce,580ed75d,c9e3693e,92c06cc4,12c95a77,b34b72ef,20a51cf4,ca4ddbad,7691fdb0) +,S(50a2349,24a29158,70e6372d,582ba07f,a569881a,96bd1a4,4cbb9232,1ae733b4,6943c220,a97701d4,a79d8e2f,a446fce3,aa21d00e,2f7cfcde,3edabcda,678cc751) +,S(cbf49357,8c96744f,7ab07bd6,182640ee,b51b8f6d,a8a655ce,cbd2087a,eeaa6d83,4d1b36f4,5711db99,404bdb1c,9484a04d,29e79fa5,87d051d5,e75f07c4,ee8d4bf0) +,S(737b3d75,e4edd296,8d164c2e,828b31d8,7c63d11f,fa4ebd89,ad59ba71,8a8efe38,ec7f7ba1,8aa8e515,4527002e,edc8327a,ff1ebf6d,d3877439,e7c822b5,35f31586) +,S(29cb2864,251939ae,6c7f46d6,9d7b4416,8812e0c5,9aaa8b8b,b7e22ffc,ac38813a,c3ec280a,7c98b2c5,c96d77c8,b410ff1b,b5f1eb51,debd38f0,528bb73a,eca2e6e9) +,S(1858aa59,24282fbd,e44dffa2,5197954f,f3668954,24741d35,2c9594fc,5e28fe9d,a0e891d6,b0a69fab,9fbd7879,a7e4ab4c,be50b1d4,4be76485,96fec281,d2d4bd46) +,S(72ce7c58,1a420eaf,67bae314,d4f092e9,26c1378d,d346c4fc,2a9e9174,862eb75c,2329177a,5a9c3e0c,f6e236ae,30858bbb,8bec121f,f7462ff3,6284bde0,7425ae1c) +,S(34c1ca5e,5dfab6d2,4abdcb83,9ddf9bc,a3f9dcbd,ecc315,17bd6f46,af112903,93f6fead,c931cc97,37c4aeb,6a589a08,80088a24,eb49a1a2,7aca807b,22a1f803) +,S(7c5ac4a,80af5867,f803100c,cee3d676,8d348b47,9ce26243,284ba0dd,24392c36,a4468964,903be647,31fdb23d,1ea7ab84,a3201cfe,ab585b86,3370ea40,66fc5828) +,S(be2ddd13,244c7728,1a98851c,8683ff7d,b57bf3d,a746cb35,e594b7ec,4c363caa,adb75939,af8a2cf,1cf3e5b9,2bc7ba65,8c45ea85,47959f25,7dfe4592,3e580fa2) +,S(6dee1f6a,3b3befdc,a4a44471,d62dfd9f,7f7b222b,819979b7,901a1764,8ec13806,5d9e8501,4fa5f6ff,f8c0356c,eb013122,1a9a2431,f641ab6,af3b9999,5c2e5651) +,S(15f264e6,8e2c8ed7,490355b3,a7b11512,c764386b,f6bafc31,80ee6fe7,9de68c19,90574d26,302bf408,ef9053fd,371cf29b,c41291ab,a76ab74e,ddf3f8c5,70326aba) +,S(3d7cfbe9,4cc890c,ea592b78,5a984c8d,6d4c5e7b,183f3666,df9805e,be9c91a3,d55cddd4,4ea7065a,f8f51694,f6a84b54,42b30b48,e7630d12,6827dfe5,e7f62808) +,S(54388bf9,d7951dc,7ab5dd3e,74971201,1ec637b0,7febee14,45b1dcd9,9c3a1e10,17b36788,25dc2a5f,9bc8738b,3f560d23,725f99c2,a9d6fdcf,6fbeff54,aae5a547) +,S(3c229fdd,9a0080a5,948a0d2c,c9281794,425327c5,52063c94,be5f0197,6a088313,34975795,a84f83b4,af883d12,c373c505,192f0a71,fed21d8d,3a8dbb8d,2a926a1c) +,S(b612bb6e,e14659a6,e1691f36,8fa8d7ad,1974e74e,36f1ab26,15705271,27c63210,5948c5d,d623cdf1,f9477733,dd5e8eaa,5240817,e8e08dc2,23b6072c,a4df5bb4) +,S(ec56e585,54470dd4,28341ed3,e900e33b,ae381e42,2efb3d64,d2edefe0,7b05f613,ecd7f151,acf6e308,dfff2bd6,578bce76,86effe0c,d3b156d9,df8f66cf,295e9c45) +,S(1bef3ca,85ff9f8f,bd80c8ba,f9b15b26,a565eeaf,e4d4f08f,25ee748f,fc11f80d,fe0260bb,96be497b,a194b892,71bc8989,125f0a0a,de88b135,272c5683,f92914f9) +,S(1bdbac4a,522b68e2,a90e4265,3d2bf4ad,c4b27e5,a2ebb251,68a083e9,9107c20a,4d60e326,3ede7fa0,10467b9,d2e8b206,5b09e127,e3fba9e,3d228439,50d63ea1) +,S(e9032f9a,567ab8da,551e0f8b,1b2c2c22,6e601b7f,e894b837,3bd9eaad,3662fc84,ac563e6,47d21af3,a0cb0a49,dafde0f1,21d60994,8dcb4000,64e3196d,74eb70e9) +,S(7ce746ec,44af748,a5508044,f56e3467,a9608deb,c8a051a9,fda907c3,8f79c75,8f0879c1,3166bd23,be7bbb80,46f3c019,2c6b8fa0,52fad7d5,40640fd5,f2aa426a) +,S(e0d52789,19de6d1c,a0929856,46cd3200,68862dcb,ef369fc9,6c6de4c,bb59eecd,98f4679d,b4ebdd90,a4f54791,29740bd5,f46680f1,d3ebfce8,8cda2946,ca886b20) +,S(c6a245cd,cf1f4b58,4400a4d4,82f2088a,e28c8b85,641c1f18,a13aea,7e5ca397,d306dbb9,f8f2cb09,958ff944,ab5e6cd1,cb11eca8,33021bf3,605e6768,961ac628) +,S(ff956c8d,9710f082,a1f34ace,c99987fe,4ade0919,4a0deb06,a1b286e7,3695c910,fabec52b,866afd46,1fe8c832,fd8a9375,a8086aec,b0e2e39f,b7823d0c,13bcc306) +,S(549dda4a,d1a604c,d0f44fe4,5c4dc276,5cef1216,6f4accc7,3ff12152,26c23af0,71e3afc0,e05ba826,36eede7,1abb15e1,166fec97,562c4381,a33f765e,100631ef) +,S(66d3df09,21573cc,e69896e8,2dd91f9d,6070dd12,edc21723,2077e644,9e776416,93981613,59a2ee3e,d9429dd3,eaf058bc,9ccf1c9,ea931ebc,25ff279d,5bb46d5d) +,S(61bd3dbc,9426386,9c53ede5,a5c4f186,8a4d7a82,fae1be7,37b702f5,79e4f8d9,8c056a47,e27d4f49,2c9ddf54,efa48c,502aee81,e2336caa,c1b572b4,e082e780) +,S(8a6d8b46,4a31daa9,2702f784,9148db1c,4ef20c76,fa67c006,47d6f3b9,80178f4e,d1f406ee,e4087601,96c82f9e,38205147,c31309a1,93bf4d8c,cfe67cba,ae8f7407) +,S(e2b60e93,99eb8441,700aa90e,1edd981d,37893b42,5acf6b1b,809fd1e4,922e573e,68a0c65f,e394829a,8ae09dc0,ab35d789,bd8a38ad,800e9ed,63513eea,4e19f7af) +,S(4c76030f,e85cfc92,64f16cad,99dfa541,fc23b8c7,2b558574,ac6f26cd,d4f55e85,44b352d8,9a31b4ec,c8f9a574,51855f7d,e98c63aa,98aec090,2d959be8,a12b7bb6) +,S(dcba96a3,59103c35,aa2c9ef,538c13a0,2f0e8997,3663d580,fe454762,5fbaed2e,af9e205f,727698a,de9f91bd,75bfb73c,b13053d2,db2d83de,b4d14c22,176544b4) +,S(fd0497d8,f75fff9a,cbfd3e03,6c9edc73,e682427f,e9b66a43,3b5b2b31,f2dc7883,d23014b6,9c8d1077,ab3fb2fc,c0bde4a9,44576289,896de135,9c0badf,fcd62d79) +,S(5bb401bb,b38e413,43d1b779,54e83f9e,e705009a,eb8a1077,542cc6ed,edf48040,431fccb5,acec1391,f68ea628,378e3ca8,ca944573,ecfa5e,e7a82bf8,82599c14) +,S(1fa96a4f,f9cc6ad8,b2741c38,b35c377e,3acac704,67bc5d20,a262db5b,48bb283b,c3448c92,ffc65afc,f1eaf7f1,f9e149eb,6404dcc7,1b222ac8,bfca8feb,eeb963eb) +,S(9534aef,1ae551d2,7a638453,171d0a63,697ea420,2fec8f11,61432291,642f86ea,cd0c943c,38837dd0,33d48a4e,ca13e96f,46fd7f21,2cbff849,6432aac0,ef729591) +,S(ea72afed,43300390,bc98d08f,3aa4ff4a,138440bf,1a8f8b7,b57032a0,d01b8ceb,e174dd8c,3692cc2,9ca856a4,4eae7e94,af4fb044,85172809,25ea66d2,d858663e) +,S(39593534,3ca2523a,603801f2,abf3a1d3,16569862,35d79fa9,a01f86d4,5c122327,acd3e3e9,2cd76dc8,551cbf0e,94475125,42a5b887,ac6c975b,45d2e000,9953dd96) +,S(d57b2a2a,375e5a0f,6967d4b5,3dfbb51b,4f74eff8,72742a3f,246e3e09,ec2d4721,12d6f848,4d107ec3,10ec2091,3482781d,c0aeeb94,71ae7b03,6a0d2551,d3ed306) +,S(9f2dfc5,1b99eef6,e6c781a,fe0135d5,fc5def8f,d520119c,59bbaaf6,442f1082,8f20962,fd273048,fa3ca6e4,ea96fe0d,7ad1d758,99e25a77,e0f8b56e,5b20dd0d) +,S(b1c30bc6,f030c913,49b36c1f,9c0deda1,afa58776,58c5a16a,9352c1bd,229884b,f8a459d1,6e77888d,cd5c63d1,8a2e28cb,5563e727,f53b59f1,939390c6,1eecdfc3) +,S(8a663e7,40cad237,12dad6f9,1bb5d266,30542933,853e02eb,665e198d,a5c6e53b,e206b399,51175d15,daccf711,63b0918c,786a8fe,2077812,c0c1eee6,bb5c1e99) +,S(2b0956cb,e0ca91ee,f44fac0a,76cc0b00,5f4a5ae8,27e63696,fe1aa8b4,a92941a1,a31e6fa8,dd454eaf,90ee1e11,62627e3,3f84b8fe,da29f423,ddf2a962,386cffd2) +#endif +#if WINDOW_G > 13 +,S(e0144151,7a2ac970,eb6381df,7e11fb4c,6b009980,6a0d330,d5429126,e662c3bd,8238ce9b,a691c80c,21563934,18d18dbf,aeb3fd34,48863a1e,7f4ba360,408dfcee) +,S(be3213e,8b062f33,caf16c53,5a0b666,f344e0d7,1e28aeba,8b215a3,7ec86c37,552523ba,eaca38a4,cd795683,852a2643,550fb83d,d1db0adc,3f1b29c9,7d51cd1f) +,S(623393b6,bfbfbd64,fc7aa1db,9e58e274,1c18eb6d,b5eb30ab,c4fe167e,a9e8ff2b,7c0e4174,f0fd5bf2,a025e316,fa3b7b97,1339a197,b52b0b50,bad4dfe,34e42cd3) +,S(dadeb702,dd0a1e87,669eb624,b8cf40bd,bffe79aa,8afab26f,bc6215b1,dcfe97a,930890ca,e4c29b41,2d660acb,8cd39bca,5a522599,a1ab0bb4,8fbc38df,17253490) +,S(b528d3b7,83179b82,bb1c9cfe,c26184cd,ac98ad5,8e253c13,627fb778,c9362f33,63203af,1545122a,63940676,ba2d18a1,aa902e08,8bb444f0,47c2bd52,db8babab) +,S(2ff223e0,93986e22,ae418a5c,804e9e81,7a4de562,d7436e0,2d025ab7,11734a6a,c5c8d188,ec9cda19,bda76d8a,97838ab7,81990475,d4a00096,5efa79c0,100f678) +,S(cb8731d5,e1e53c9,ccfd2c39,3c8ab1cd,9ec839f6,99fc712f,f946e74b,99eb1742,cd2f9df8,38fec504,dd125248,92ce8a4,a9db3848,e487076d,8c18e53c,f6d19fb5) +,S(1377ac45,d776a5cb,76ec265a,af272690,6dac52dd,be987799,36bb1271,e0cf4a2e,a4b3330d,d5954932,d5a7a818,7d9493e0,25ab2155,d4ed0d4,f34aca1e,c2a04670) +,S(984b9bf2,f140c75f,e03489bd,88041faa,22fbac73,7ac10724,c511a253,641a5ccd,c474f639,9733eecb,a750ea82,ac4d50c7,d82f4c9a,942a2bb5,90b1431f,c8d14ff3) +,S(4b8fd000,74f57cf9,b135d56a,c002bf99,d5050479,7298cc4d,857960d7,afbdcb06,7c044103,1df0f6f7,721937a4,c60cf76c,95560ee9,4c6d097e,3a8e37b3,34c703bf) +,S(57316653,68412236,619250b2,58bd0ddb,34fc751b,8becc0b6,60585683,218b6079,d1d56e4f,30f01c57,48972898,b8afe142,16f8335b,e3a39c37,da64050a,91652904) +,S(c9a00197,a0ff16f2,fbf2cb59,767d43f4,60737367,4f2bbbd2,53c7220f,db69f286,177c6783,d739117c,1de074b0,c605cabc,6b4dfeed,a531f4e4,9cc518,40142f0b) +,S(e23416da,91df23a9,db161618,579b3008,c87b9ef5,7ee8bff6,45eec6ce,a61881cb,e556417f,84043691,e7ec82e0,e1718296,e42fbcf4,a3de0137,93772dd5,70b8da15) +,S(9f96e3f2,369d753c,e6614c45,77bd8a9,14293eee,8a749c1e,3b0e2955,638e9ad8,f5cd1268,1567a4da,71650d10,e413e0eb,9b01a396,e529cff6,b494b2b9,a21ddff1) +,S(48657ba4,b24b0123,cd54317d,de6a3245,ae488078,5ba43d5f,1d94fbf6,b9301fd2,191edec0,6eb53781,2813ca77,2a9021b0,dd4931a0,929a7e36,a4a8c66f,aef0d890) +,S(67b322e9,d72e864d,8cb15511,11402d7a,c6c858c8,77832d4,e0187e69,6a36f24a,cfeb12c2,6b58bf15,3bf87058,c5faa833,e15c867,f7f9a208,c3dfdf3a,c7f6946a) +,S(42e8068,542bdd98,fcce8925,52002db,c545ba13,16082d40,fbde06f0,a44ded15,1645a9b0,c1f33cf5,27364915,8c4f261d,a1ee814e,7aac6402,bf644451,bfc4aae5) +,S(8ee7dce1,339c50dd,55619107,9bbac005,3e058cca,4a8c8e30,7588c105,fe90d4c7,ffbd0af4,8aae8279,2cda6170,5dbe9fe0,98e102ff,1e6f11d2,b4669a81,6ec9d5f9) +,S(abc9504,12926a71,6adaaaf2,7b209216,37a935f0,cc66eece,55978a82,1fa368e6,72e54935,e9b461e7,9fb75c48,4dae4fd2,155a4a48,d3a467c9,624c5f6d,71f79203) +,S(bd250320,81e0e9b5,3b00568d,40378fcc,fd72fd8d,783f2f3b,433ddd1b,a6976ba8,5adb8bdb,85855498,994ca879,717b8e7a,e8c4c87d,29d6a1ca,4c3c6395,6c3ceb39) +,S(b4fb262,fbeee84e,49ae9167,7e7aa0d9,b31609e0,48888740,c018a5e1,8ae25f71,34df3f86,dc091d51,258ecbe4,1cf616e9,265d6d36,8ea3403b,24cdc7f8,e176e5fc) +,S(d1ba9b67,66f24eaf,a145ad14,81063b5f,e4604817,21b361c4,95de8833,be605c01,e80a6cbd,17de2f1e,663ce7f2,8917e3a9,f871943c,a4b8ba75,68476a3,d9e8400a) +,S(5c98b6b0,3a3e5a8d,2d46652d,5eb9e2ab,a80c6702,69dc5ba8,3732752e,922639b3,81e2f9a,145d0cdd,2c51bd13,f907a04,6a35efb6,635292e0,6b8f6513,c50f4a54) +,S(c1fa4688,f75fb86f,61cb7071,4fb25f2e,908abf0e,a87aa84,c8db5dd,4c2618f8,f2f74a77,6d4bf26d,17f55d0b,1aa913cb,9db869e5,ab861d9b,2043ccb9,ca8397ea) +,S(5e806e9,a644eb32,51c62ba2,f09a755b,96aec78b,4405df76,dc22ba6c,f7227ec1,b88c8118,d6a1829d,6aecaa05,742313a,b871d2eb,72f31bba,9d84f87f,a73e614b) +,S(f9d147fe,fd2c1a7b,f623d965,bc7901bd,968636d,eff54c14,34c6326e,d1c8de9a,c7887249,ab6686c7,93a7d77b,41173060,40de44cb,84980c33,cd548d72,d29caffd) +,S(b98cc956,85f6d11f,a8d38a1f,50799634,9f7020ae,3171023b,abea0fec,a70ccdb1,f074d495,3689e8a3,6ee4cc0d,40882355,3dcbdf21,70975f49,5712adbc,990ecf7f) +,S(f161cad4,100817e7,ef9091dc,714bcba6,18458493,f3bb6b03,4648a649,6817b474,b7eeb92e,396af324,22881eb2,45e62515,c4410af9,fa519ffd,61289f6d,9b740904) +,S(7c8b6c89,2ea4061e,456abac2,46edc08b,fb54aff6,8a2678fb,1b7b1c08,5326914c,f08e1f02,6ea1d2c2,9ff5eacd,2b34682,2960723d,cdab95b1,d69c8af,5e7692f8) +,S(4668c29f,16334658,195b93cc,ef71a076,3ab2078f,724dde5d,d3635eed,24f28729,5db228c9,8391ec52,324c723,39d99514,8fd22f7c,2f61cfa1,29ee7400,4c74ea4f) +,S(3443d0f3,9dd6da5c,19a39f8c,f3672652,96fa6729,c9290b2f,4e21c7e5,3167b65e,4b6db639,9a088ddc,8ed31f63,7c079451,14a4320b,b7ed94b9,2a87c0e8,97429234) +,S(d3ce3501,17a04e95,58281e69,3574c096,458dbca9,afac20e8,ffec7810,8bc227b4,bcfc77b9,628f6ee9,3541e47f,8d556ad0,7696ee6e,90ce384a,9b77fcab,6eb9908) +,S(c4dc6363,ad772452,221f8640,9de0ac28,f2bc1ac3,cd2d7080,23301560,f95127af,78c9ba8f,d789a666,439bc949,38345250,38a79c5,97f6a71b,3e096b8b,752d3038) +,S(c771f94,221a47ec,fcd78d7a,123d2e0e,1bf4edcc,bbcdd075,b23d29da,6d5ac666,4dee3b30,829f5aae,f4471924,65de293f,f2ec526f,5b8f5980,d9155f71,ce8d6091) +,S(bff88ce8,96338f7f,5b6516e6,448a1f25,36a1e9bf,275afd50,e772517d,79e6e199,8f3f0c7a,b62010a4,eb0b6211,7e9761d9,c1552629,bb55bf68,53274158,a788c206) +,S(4afcd064,5d57bf24,e850e7e3,d3cac224,6a467e76,f2ce02da,576a1f2a,9a3b97a,52f23b54,87b2af93,6cc692f6,1876d6c0,ef927d3b,c06df93,984ae54e,4d10f0a2) +,S(c4bc122c,b9bf0e20,57f933fd,94db012f,79e23c34,98007abd,f8a8ba21,32b1f373,e40c47b6,a31d81ba,dc45d427,3ab56d77,1daf76bd,7bdf8ce1,a8778861,66fbfc6d) +,S(487a19b1,d1be7791,ce223d27,bab11aca,837a0f8a,7d34d9dd,b4c68f18,51f821a8,a53cd743,16ff4e9a,8633554,45415e35,5552403,7b25ce67,f519e44a,a5d0ef98) +,S(274a3cec,be06c748,7603516,588ccffd,f4ac3d80,a85887f8,10632cb8,4301a326,17a24be3,afbe8b45,9a72cab,5385cb6f,5d06b47a,63bf19b3,ff4989c4,85a9f40d) +,S(32b31f77,b0cb99ac,3bfc34e,7558f9d3,e82fcc6a,be2c4,8a079106,33afa9e8,447b44c,c191da90,e0eb3f71,db804472,17f422d5,b1732a8,993da80a,5d8f5bc2) +,S(78c39dcf,55561468,dc339d46,ffd09337,945285e1,66dfc29,25d8b85a,24a2752,d691ddbb,4e41ca85,eebdf63d,5c023e62,a6680931,5e1109ce,89088467,7ba3ac55) +,S(5fc75911,a4920777,c4502116,deefc1a8,d2f21f96,2b1e725f,a04d6fb3,9d34e5ff,59f36f7f,18f5885c,dff524d9,6a139749,f3fe1662,4b728d50,7a460bb3,497512f2) +,S(ca1590e9,152b2b49,a6d0fc16,4e346e19,fa62dde6,f693b64a,e38289d3,ad08fa8a,46a7bb3c,1174ed75,49e9eae1,7126455d,535ea744,936947f5,24a8ff30,8046dc8c) +,S(5c715266,5ff0bdeb,a7f6e660,bf66d5ad,743d94bc,5ba9b7f1,f3d50cdd,9d11fa1f,7da23b15,56e995c3,a21ee9dd,ccccca4e,e41684a4,f208c39,b31ffe9c,4473a03e) +,S(c7f71da3,6361c73a,55dc3877,4f2e1033,fa0c09ce,1c9557c8,c29d8684,e4177e82,8d6e47f,b5c2cecb,6b22dbf9,a04f0f95,77c6f50c,3429df92,78edb85,59b0dedf) +,S(6e91bd9f,5264a13e,37925900,433b7536,4130b4cc,e6fa716d,a0101c2b,dc58afab,5baa7455,506b5849,5d820c20,f209aa01,ee0f9434,1df5b449,9ed23a51,b4fd604f) +,S(1f00de8e,69ac7cbf,c75c789d,f3322813,244907a0,35059072,68954196,baef0d33,2892ce90,f32330ed,2800c30b,4482b67a,e65fec8,41ba6fea,b2e83703,dae040f4) +,S(c00133f5,7d8c469,421efa3a,d71d8d58,1a2f5b0b,2324de10,91d79145,7d300638,3c76b182,d3ee982,dd05ea45,59e8e31b,1aa3dc12,fdcb67a2,f86434ed,34f18895) +,S(af639e7,95e8269e,12cef756,4bbf970,cdb172e0,66cde48d,2f8e9083,c60cad49,1bd01179,ce92cd29,e414a74,cd1de487,c479daf,5673b219,8082c474,2426abb4) +,S(e6dbd27d,5447c044,18fa0a5d,8ebcb9a0,ede58538,8b73ccd5,4e979797,31f4c9a1,77f38524,f2848320,3d4c780a,d0cf8bd,a2071037,348db8ee,6b5deabe,3d242153) +,S(f51a8d23,c95b70aa,d02dd904,ec1119ea,8d1e3e1e,e405646e,4c2dfd53,336360a9,426b2c9a,1d703cf6,c748871,4959acda,ae5c6aab,51945138,73e4b1a9,c0f46c57) +,S(e12f11e7,fe437b7,f578d8fc,33ae3a60,a3e4d1ac,1ee45863,42944d50,a0f6bcf4,22d15d58,35fa89ab,563985b1,4114c957,8bfec8d6,6dc7d253,e3c6d900,4419f5d2) +,S(e758860a,8ec762d0,62f51e56,d958a14f,ac619351,9d890bb9,bf6bc7ed,e988e14c,42d9e0ef,10b84f21,fb88d780,dcb4750f,10438682,3b003b23,ec41c297,567ecd78) +,S(3c933fe9,ba21e5c,d822b90c,78a54b7a,d4799882,ef91f2c6,e423a398,20a64163,c1eaa0be,531922e2,ca5b23a5,6700b4ad,7fc16135,11f67f96,b672ddf3,669080df) +,S(4757576a,83c9066c,b6eb6b08,e91a79c0,df828e4e,3c09ce07,939134fd,ea857872,13f22fb2,62d77f15,de3e8388,d9270c45,818248e8,9d950d7b,58ee6c6,c38277a) +,S(35e63903,70085140,b19df903,9a7fff42,46570fcd,8661caa8,129d6b4,31045c7,2855f4bc,aa9d60d8,6a44f022,b3c28e84,53cfb3ad,a58691f1,b0e9cae5,e5b9e8c9) +,S(ad446e01,1f118207,3565f031,6d0a85f6,ad5330dc,6a8be4fe,82be632e,32126fa3,240382f1,decee3f5,1f92b2f8,1ac0eab2,1d8acb54,2f730d43,15c194f6,28e83e39) +,S(fbe9e5f3,eb01ac37,820af752,9c4221a6,89164ef5,d77461af,f82d6400,6a718815,f2f30cad,d85a2e0c,e393e088,44de9215,ba207384,2abf8468,47801ff6,12d088e6) +,S(1e675320,d81ff430,a0549aa2,482cc9b8,b9b585f6,32d32916,6e952f13,3b038135,ca0f1276,c9c7d995,c5baa5de,2988700c,2e2c7f1b,366d1db1,b44b4c9a,f0686aa7) +,S(176dc770,23b0e52b,a2eb8068,ad27924b,94c3f643,30e0e85f,3593917c,d6267718,d2dc6288,5df75b06,f450686f,df660950,548d4f6,85d1a701,d510f3fe,297ca8d9) +,S(3c8536c2,32a02b3a,b36feadb,ccc7c541,7ac83942,3cfc8dd,99a0ab7b,41a9c938,a684eea5,249cd12a,d24dd8f1,73022ad1,8ebc7f52,d6a3bd9d,bdc4f5ad,a25186b5) +,S(48aa73ab,c61a76b6,e54c446f,ba881198,ec6ea003,d63c54a5,605a322d,7af006fd,c28c5eee,ffb20882,2d018506,5cf3ddf3,5977fab7,40e4d4e,cdbf9935,8e403a64) +,S(74732762,abd028d,9dad2b36,38baca49,263d170d,ca7e4cb,d83a3a1b,53cc1ff1,ca11df0c,e8dfa09f,3f2ef7ce,5c023b6c,927a88fe,60ba9f3f,ddfbd69d,e536c2c6) +,S(eb71ab09,520e5915,767dc918,814fe901,a4042725,5247c02e,b8672c5b,95698522,5fad7ae0,a7e95b38,ed6563cb,2023b2a9,c81b6901,c007f1eb,8749f56e,4d48e995) +,S(2b101bf6,c7763df5,72eda74b,eb179cc6,af5e8695,965761ce,f8444371,7ef5be6b,dd16c8,4e1d1a3d,98d4629f,ef258421,f6664719,7f89a597,67fe862,3f140ce9) +,S(a099efa8,2c666552,5332b050,75e81ba2,13976afe,8f3b33eb,ca2a4436,6e0ab337,f883957b,5cf1f2b3,ddd6c7fa,a126acca,fb1e33b5,e5b753ab,dc0a99bd,5d136c07) +,S(f4396856,a61c3ce9,5b72ab6d,470bdeb1,8cc107cd,2f58f15,3d5bc99f,8b62f95d,6e3ead1a,a8edb0b0,67240ca,f3274e63,df81c2f3,e1ef2567,cfd76c01,6e9f6133) +,S(da732197,26aabb18,4a0aabe5,a493d803,53215b7c,49458008,bd5e387f,694050c0,e2075f29,17724b68,6bcb987d,85e954e1,9489af4c,e7ce1b46,66d84604,e9a0eeb6) +,S(99171a1e,19596183,f4259c09,b9740201,8fea44d1,4d0f2f45,75f4d66f,980a6792,522b840c,83e1eef3,e7f2cbd8,e07bec0,66af1bd2,e7607f5f,27a767b1,75219a4f) +,S(353cc684,8a2c4f36,2408997a,944889c0,1db7bcf6,9133323f,8f0d34ca,758cf08f,1865bc62,f4ba0156,7e2b283f,702834c8,97effd14,6e0e5fa2,43d5124d,ce67ebe7) +,S(8b16983b,5053d3d3,8e67c77f,1b6fccc1,b9ed7e3d,d57a26d5,deb242dd,7a312852,49d93f92,fa5953d3,956adeed,cff49ac8,caeb3d2,c72a0e9f,be6c85e5,d85d47c6) +,S(68f5dea4,b1da327c,227b2513,83fb622,efb36730,3bac02ef,505e0464,750cabc9,26740f9c,5d624b9d,aed25774,46c9c742,146de045,71cb750c,4356898f,e3d31782) +,S(faf5207f,c3acf00c,8e19d8bd,7208a6d7,cc936706,98559244,e74bb202,20c699b,fab7b446,17a6c6e5,4ac186ac,971de8e7,d42c1527,8607eeb,b8564a0b,cef1936c) +,S(c3d1aa91,b541c5bd,3da04707,a2f01a16,917c0420,a26604a2,bcaf5081,e8d17630,5b57806e,5a58c405,f06d7ce5,4e5f7b45,c9b631a3,44c92c64,d8cd1435,fcd9ce27) +,S(23278a35,4970b920,450db526,391b30f2,54b5bd5a,fe2c1455,623c99fa,8ac8db1a,864d81da,e8df9e47,1ac93b74,660542df,3570486b,fbd2144d,55dee441,90e1888b) +,S(602f6181,33cbca4d,74de4ab,29dcd101,7c12c32b,ecaed25,485765c5,478c0146,4c42cfb7,279ec350,f77d2da1,599b9c85,9ffab342,ce6a011f,91c9e460,27aa968) +,S(1dc4cfc7,126c3b2,5d82aa46,3dcc8cff,c545a9ab,c7962690,fd4ecaad,25843ee9,a9357982,5c535575,35820f17,25e32afb,6002b1b9,2a9b43ac,18225e61,b3fedeb1) +,S(3694f121,6e02bc79,14cd9910,8ca65fc5,887a95df,8b04e8b3,3c6c23cf,ce35af82,7ffee291,b1c41976,d456e742,88458b9e,c61e57c9,9b8386d1,d1c36424,38555d88) +,S(743ada75,a9596420,7b8725e0,af06c2c4,457be03b,a920c3b4,b65922b2,1df1bdbf,8f2b81b5,5ac4c5d8,9cc23ed,92dc1b43,5629b9f9,39b126c0,b16d7175,b40f908f) +,S(bfe9397,7c7cc4a7,b9cc42d7,f044607c,f047cf2e,26d6f94f,210af7d6,b2420085,625d6059,8f80dc83,1ef2b51,dee53d5,666c3dfe,a02e1d92,1260906f,ae373d64) +,S(86c02c0e,6ee646c8,c2944751,7867a1ad,cb56ebff,c8795f83,73e6d8b9,1b240eb9,659b5e9f,da4b1098,b76af529,f56f809,59d39f48,916477b4,bfa66af,c85be4ed) +,S(3b281045,857f01e9,995d357d,3a84dc66,6c4f8f47,4b82ace5,dc3a9229,387bfda4,9948272c,cdeb1542,47c7c42f,1f313dad,e318a123,3f500f8a,16d80e7f,d2e9fd4c) +,S(cddccdd3,b54d979f,504d33d,46d6ff2a,9859038e,33087a3,da9a5284,fefc47c0,9f2a13f8,369313c1,44d91e5e,807ddd65,196c991,a7eb0321,2133aeb4,56683b8) +,S(98100502,a6023ddb,ee34462b,d0232711,8f8c2e9f,33708088,40352c34,870e16d7,1a8bfef4,69af3b3b,1e381c08,454a84ec,4cf8fb66,bd721a57,47a94e90,1969b9cb) +,S(8b76757d,b2fc179b,9016847,9b82124b,c26092f9,b35de316,c90223e5,99978179,47eaf326,588e65ca,541a71a6,a1167321,ee449268,1e8b4960,6eaf9a73,42b16f05) +,S(e66ed7dc,897fb660,6f44d8a9,46b0c61c,45c83bb2,d55ea771,bf2571d6,7ecc3b43,e536f79b,8a9fff4e,c6cffd47,8a405bd,7f1745f9,9374d810,518cc5a9,f214dcbe) +,S(e0600592,cc9c0b9f,8cead065,6ef5c115,ead63209,6a0a0d2,2626aa13,f2bc88c8,628d94b7,8b84705d,16e55254,4c138416,e7f75f5d,d549ff7c,a42d51cb,7f5a584f) +,S(1b0af242,a9cf25d4,cc758fc7,63e2f07,62db2e42,6b392cfb,ffc5ac07,19152767,33ae8aa5,eec30559,a3d28da0,d9354048,592dec4b,2f975a0,ed043fc3,c856a2be) +,S(e204ffaa,142f7eda,3505beee,db0bcbf0,9b80924d,ce5bced5,439aa4d6,af5acb7d,a2804d9b,98e11519,adeacdd1,aef2c22b,a02f7030,479a559e,6924db49,5d8911ba) +,S(afc40e67,651531f6,214ea1fc,13173d4c,a35431f4,92845964,69cf099a,d515ed5,57ef6ef4,1e480de9,32ae8596,3b04d267,5e629707,cd3bdb45,5896d333,b648e0) +,S(59538bdb,747b641f,800588b0,45c0e3c9,72963406,5ca601d4,690dee22,abe8d226,a030486a,3c919c35,4c26547a,3de96087,52ca7a28,5d378e28,652031dc,ec2d4438) +,S(6a91d34f,c38d4028,c63a4bae,bedb2a76,b964cf44,1804a6f1,efbe469a,a997ed8f,32500c83,6a0b5274,2d2ead10,dd3e73eb,45f221d1,ca6cea00,f2b01d75,d9073260) +,S(9260e687,b11d97ee,97dc44ab,5e21c344,332ae39d,c85c2ee8,f7760cc2,8ac28d61,f47df3d,e8d8654e,f7124f5e,2dcd9d95,c1d13e83,a33e5d18,92ce9851,6223e778) +,S(3490e733,7a66f301,f678561f,4b4f293c,b48820c3,dcf9be06,a0390410,4cfe3cba,49591a79,7edb70ac,74f87636,85bbb22a,a8169536,532886f1,f5ea0721,5e9bbd6c) +,S(9729f4fe,1f47a9a3,7dcb1311,ea9548a1,d71d7a81,27803c8a,6ec0a680,8d07b4a0,56e1a5d4,ccc4fd72,8e7ee569,e22efea5,c8f03d73,fe8ab86c,2dcb8af2,eb17f896) +,S(af63904f,6da423d,1cfd77a6,680044f0,5e694eb5,80ccb4b1,c37d8d83,ae9c2caf,6decdc2f,5fe2b948,d15fa10b,4a7e2edd,b8cfaf0f,7c79a400,f3d1b306,dbe110b2) +,S(96271f72,1f4a1f21,a2274edf,87c294fd,403cf0e0,c7b7b1f2,f242fb7a,2c435a3f,66ffbc73,1fc8cfd5,2bfbbca4,49f6e949,71940077,ae411e79,51cf5b21,ca5adddf) +,S(a42ef215,1f0cc5a0,15827287,eba8d960,dfa5a13c,7ee2696a,95bd94ca,4b717c7d,5e491ed4,5f08a591,32296929,814608ee,e3243172,b523a1b,a4995f6b,50046fec) +,S(193b3ded,e770a757,d859c289,68be2780,fc4ce92b,135bec2f,7fb2c07b,b862e5e4,192c4bba,ffbb735e,a1d5cd1,38de0556,d1d1d740,980c5775,22d19b5e,f0716700) +,S(ccf9a075,da6f44e4,cf3b4fc8,26feef3e,54084b0,e2756029,e290a7ce,8c1e8dc7,d04f844d,ccf2c30b,9020f0a2,308219c6,a5d6491,ffe9ba67,bf6b20c9,9a35a183) +,S(7ebea25b,1d69bb43,f60ec69e,f9853208,d3ddffb9,6dce3831,873e7ace,d25b0140,24540af2,bf87d637,54f1a47d,13a3f38,2a948375,8955dd16,fc83e7ca,4fec3d65) +,S(c9eb4a,c2a31b01,9b7ff038,38478b6,674662eb,d729ae45,d7111c63,84a038c7,7e2ee03d,caed3f4e,bef2b90d,78ae42a3,12f6e8b3,29d116a6,e26bdded,81f32240) +,S(45756e0c,8c84e9e,a7b23bc5,cfd87b4a,cd0b290d,86c547b8,7fed946f,e5acd867,9c3f522c,e577c017,3db984c3,d7dc16d0,31326e2c,85b08413,4611da0a,70acdd1f) +,S(1bd58481,21bed636,c789e341,665e2477,59438de7,10aba25c,e4a0db7f,13e3c0da,cb0eb897,bf905399,63a8a7b7,50787430,ffd4d6d7,9589c8e7,350f4351,4786a90b) +,S(f199562c,8e809ba5,84aa80a9,759dd98c,32eda7e0,ccfa4063,547ced9,d9324dc1,33519ead,76430498,949dbcea,33ca14de,2f7ea811,cdd38f32,4009ac7a,b408d1d0) +,S(7fb4e910,e9e37dc1,f56ac3b9,30589522,975319e9,84dcb559,6743d3d4,f45ea6f3,b74a03c,cdbec9c,f36b59bc,fe3203dc,5f4d94a7,bd54c628,55f0d04e,67c960ee) +,S(503d08fd,19839d78,aca27020,54dc4233,c1a1d68a,6b9cf136,4c6fa9fe,886c03e6,84ad95db,9a09eb87,bd905914,473d23de,698459d5,7c436f77,58937bd1,8e448e0a) +,S(335c9204,e6aed3e2,586d0dea,c87158a5,62db42c8,e42fac25,9196083,51e1e713,15b359bb,10f8bee2,940849d4,212fdd84,49b60c5d,d3419ce6,7ef9f0ac,f4c1c2f9) +,S(ba68e5cb,e0f7159f,821117df,5720bb50,f218c298,9ce3f5ef,30c44134,2834bc9f,2ac25bdd,ff34e4e,ff45a2ed,e412a287,101ff447,71c657f3,ca57bc94,40fa5d72) +,S(93d6e713,311d8430,58c20267,739c494b,446d7943,a1e47a0a,2a5ec20,877e6baa,5997c19c,99a2fd26,e0471041,b509f9d,e10bf615,7cd4f24f,db56a65d,201a0856) +,S(7a94bc1b,5cc77a0a,73a84fbe,c5d1b68,cb8f4626,8ecc0c22,ac7500a4,5f397172,128c1c6e,82a4d52a,719c9f8c,1bedf4d3,32d3695,16decef,34af6b4d,578bee5) +,S(f031eda7,c19383d9,45eec848,f6f3e467,75fbe52d,bacadc54,c213c596,c821b809,b4a78d0d,1c17e4f5,db81e2e7,ee52f195,eb505d36,af96bea0,5170c776,23cabab8) +,S(86ef1acd,5c17e082,dd4cb924,c74d0195,ce9f375,60ca7608,57ab7d70,2039907c,6936a13d,b9078ac9,426d34b1,6d5673d,36c3105c,9cc77de1,ef7e0ec2,4cf3bb3c) +,S(fceb6cc9,c78e3a35,49b9beeb,62a14fb8,6d24eec9,2ab10bc9,40916b60,cbc6d720,7c2e6024,5f561f1c,e0b69701,512ca518,9f8d9292,ea75562f,8b17873,77f7583d) +,S(a1d9ed1b,9a36f348,1f426d83,7afe4380,d475e36e,3b140f3e,cd2213ee,dfa5c8d9,3683c97c,a1273f29,ec02cb77,9e9fee54,78bd5e3b,e6aa8c60,7d5bf07,dfa558a0) +,S(d98de999,6311ed55,e15bbdc7,58affca1,3e8f629a,77eb3dac,844f90e0,51bd48c7,8af6194d,272a8ee7,68d1b810,778e5c2,69394353,969d77cc,7d449f2,84ef2a22) +,S(78328db7,cd6afa29,b6f1ba80,d65f8050,60f4d223,9897a3ed,bee8ba3f,a99aac60,e37e496f,1d143ac4,8123377f,4e136442,629f8185,c4996f01,f35c7a9e,76fc5efb) +,S(3d701493,31faf0b,37c1e1c0,9b29ee6c,5d9747cf,cdb26117,223d1f66,e336db5e,d1e99140,8311b20a,b41f7ce0,ab4e9dd3,414ea3c5,b87f88b6,648cd1d3,e77600ad) +,S(f619acc0,47e0d4ab,bd5ba2a,7a54ecc4,e223986,fdbf7a96,e90f762a,ce288628,f24eb63d,e1545d10,fc96a2d7,e7fc1ee,f9cdccdf,cefb5de6,8fa4eca6,781564f2) +,S(cca809b8,71f85a00,3344a851,4f797fce,91718f35,9e2fb489,a1dbc00c,aad0a2d2,b7d72ab8,35658359,2258f260,a1f62f97,aba642ed,382992f7,12b11c11,6890b037) +,S(bbd19766,ee2c501d,afb4eec0,30fba145,aa26c45b,51c1beea,a7d3ed1c,7dc81958,bc709dff,70b3612e,7cf0a6e8,9724442f,6c1ca4ce,c32efcfe,b98f1acf,df5250fa) +,S(6a6fdca0,e4a58197,267a1938,1644aa5d,ca8f0ee8,3a68a5f7,9c34d4af,ec1cfadd,c28b1236,76585255,cc104298,d7ebcc70,6bd7ff6f,cadb0c36,db6517e9,d2732081) +,S(922e3e1,fd401a22,ee7d693d,e52f0ade,9564af2b,17a4be0,2c553216,df5c8006,a7b10065,aae84a40,b9b79e0c,5ca8a227,696841c7,20b944aa,3b9eb1c4,1488f757) +,S(53ffae4e,3526b553,f92bd9da,e3cbd3b3,aff8a6da,d4895490,38382f98,a676eac8,81fdfcae,b51f80b8,3d23b222,8ce860ec,9e665292,c456fd23,cfde43ed,99f8c6f4) +,S(14a0ddd1,c94596f8,9d3e7028,929cfe4a,7c2e70c6,b55d15b9,77227862,a03d119,2b5dc071,febe1d1d,df7e1483,53dc6558,7e8c94ef,b598ee83,806f1fbe,976dd086) +,S(7368240d,fb74f35b,b51a2542,8caf3b90,bebe272a,739eff4d,c0150f1e,3d68c8f9,95392b17,b4c5e82e,774c7168,7c46469f,21801a72,b15cbcd8,fd2ba85e,e4a7a27f) +,S(4c0a8053,b9eab39d,2396825e,2416885f,5fbdb610,7bc5879e,6400d010,20580560,85a222a7,5b7de532,617f67f6,5408b79e,f5a6f826,6083c2f0,93ca97bb,d7db5427) +,S(ca0d66a8,24a6f8ac,bd9447a4,933dfcb2,6751a26a,f5790a1e,91e32053,3ddabbf8,61cc898d,4f8b0845,11dfd49b,1ef01e43,6f7d7d08,a5f16b2,1550f329,79395d18) +,S(646a0775,e62f6a36,d520763b,5c7fb081,a3d7dff7,355cba76,45358a6e,55e9d6d4,3e528844,e7380a64,20db2366,22c936f9,b1100046,e17c66f7,a6b1a01f,7b7dbbb4) +,S(435565ec,f3d6bc13,142d7c47,7052da71,bac77f3e,a81107f2,30303003,6455d070,4ed52896,89fd8d96,343ca8f6,c9f0c70f,ab6edc5c,1ae96d15,9fa9eb4d,a4c9f6bd) +,S(d8b01896,9328544a,a51f22fe,e605c693,7a014aac,37316f,ff6a760b,93aa8f9d,63f51e42,a2b879ad,36d60719,c1497b5d,dd412782,e4c620ac,989f7259,3a06edf3) +,S(b9475950,4a9b3052,94af6f2b,6f182e5e,83a30abb,47f0799a,21ee5446,d63d48d7,cbc74028,37a899bf,79b89676,9e358ad6,9680277c,34ae1018,4290689,c2fb876) +,S(14317c49,2972d5be,c5a01b5e,34842135,d521b467,1b262f0f,c3e6a271,ff8e0ef0,cc4d2235,d1cecfd2,2e6a476a,7db483d9,d318e79e,4c3486cf,c2090651,c2069381) +,S(8bbdb357,5b6867f4,4f062ab3,38928d52,78c4b873,4e95c5f8,fcddd4e4,9d44f8c6,d38d3387,32424054,c05a67e6,c7d00e62,1279eca2,ee1b59fa,90b97f33,5173a778) +,S(7775fef6,36ecbe78,9279786,b996c0d7,380b00f9,4ed31476,1ab0b190,f06aa685,53152a73,162dd659,dce57d7f,cb885c44,34243153,2b8318e1,2a996ebf,2f55407b) +,S(db5e4bd1,39ebe377,bca64950,29e72fb4,bc9b0ea5,5450e42b,a7491c0c,39693b48,a6468113,a5a796ad,a337ceb3,238827dc,416ca20e,bdbe4e62,14194e66,cc5a0abb) +,S(eab057b0,578c52e2,eac11be3,9f069cf1,6ebf0631,709560fc,2414ff11,f1c619eb,5422023f,cf69b8a8,458e5c6c,3c2de1e8,6fb041ce,180c5f75,cddb455,fd023f67) +,S(e955fcd3,c657d611,7e2d43cc,651333e,c231ba32,418e6fe6,d021183f,e7f5e44c,dd0eaa98,65212f27,2454953a,4c46c5da,973095fc,b2e36369,cfe228f4,828e6b57) +,S(5f5a3c57,58eafc30,c311f596,f1d6605f,ec0f5e73,eafb27a7,2a07f91b,42d8e49,3cde0b0,1d1fb2ea,9d85a04a,aa4536f5,c6d9f55e,84ca890c,cf23ef2a,5dcdf1a2) +,S(fb7a31e4,ff0ade1e,efffbd7a,e04af118,49c82cf2,6ad219c0,7572d924,8b99bab,ea87aa0c,431de57e,ee86bc4e,be463dd7,9e69102c,736345a,5502b07f,31df2a01) +,S(d57b1d6a,a3e87779,4b9f8dd9,683ee3a3,6ec18d3d,e6b22b44,e411778d,4bae1ffb,256ffed6,b85bd2f0,9dadb0e,43ccbaec,9fcb9e57,22d88ca,73f8d7ab,dc0f62ee) +,S(9326fc52,d3a24a38,ef0fc90e,183697b3,f726832,c70bcb5b,bd6ac548,cbb8f1a6,863bd0a0,cc0a2bea,d21176f5,c99fafa8,d7d766c2,54d57308,1a58a6f,12889a2b) +,S(58362cd5,abc9b5e6,57617e94,620ad087,d5d310d5,313ef6da,36079b4b,a93caff4,5f2a404,4e86bbd8,d73b673b,2e432233,d6923cf3,c262e1c0,3da48d42,f62fc52f) +,S(7dd488b9,cd06e68f,e01b3a9,6b318d61,b8c4cd69,7e9a3681,34fce81,841738ee,fd7aa5ed,130c897,cb770846,a3d292a0,d963ded0,5266010f,34a99ebe,99782cf) +,S(9bf78b02,524c1554,3330d7d5,a3b41705,1fa2a324,6ba8061d,f9550640,cfe798d,59f537d6,6d2e6801,d79d5a70,3b4219c8,c7d06385,76964f48,10427548,90cf5a83) +,S(4c816973,743ad5cb,18db4f87,9bbd6d1c,e71513b6,eeebfc39,3663dc36,eb3fc47,1a6dc6ac,37a49400,a933ef09,f00f9650,44c6f8eb,d516c254,ab142d89,d41105f) +,S(60636bc2,c7486343,59296408,40f3a26c,173f4e5a,7f0031a8,35c1c56f,b1051be8,71a78b7a,3aed2bc9,70a4190b,d1be56e,efc2e6b,7cf81b08,541dd8f5,dbe88e8b) +,S(a6e772de,c3e90a70,6c663fc9,4d5e6cd3,12211537,40ca4a2f,47a0f3,7f8d00a,25b8fe1f,5c727181,4a6175a8,10aa1eb8,f1090221,d78c32ca,76ba7c73,d0eed520) +,S(79c6653c,60307215,fabb4b2a,aa8bfbaf,1692f613,166326c9,19324e5,7cb89262,36d5ed12,b6b49496,e2b79da4,c0955cbf,c24eaa3c,204e28f8,db1e7ed2,d2197bcb) +,S(3f556b2e,4530fade,d4774af4,ce4454c3,4a2bdb4e,aabda42e,d4ba8546,d646cb15,bab1d321,1ce84331,3be8996b,f5c5c4e2,c9fd04d8,397cf9e0,58829389,ecfd25c3) +,S(eda59a23,8d21fe9f,5e11e0fb,cf731fe2,d645c52a,f3861dd9,3b7273b7,3fb3913a,22f22f01,4ba320b8,2cc29c06,d75b7eb7,d3cea857,40cb2562,4161b9a8,712bbfee) +,S(7a1ea77,323dfb4f,36958adf,71d4f03,3a2bea2b,a9f62cb0,c42a4279,7de68548,4866ce25,ee7a2b5d,a276f976,6261318c,6d2d7f51,f6f41940,f6cc3f20,264825a0) +,S(ad0fd3a,ad62d6d0,bae7c51d,590876e2,33d1028f,62d5c178,a0ecc3d9,a323de2a,88e024c5,9672469f,54f4a64e,b792d761,d163157d,ed982787,a6d40382,83b0601) +,S(1bf19432,f4044a69,56d6e9d6,7b84a5cb,ee743771,8d634dfd,20706cdc,602729d3,4114b200,afb6a1a0,75ef8e3e,16c37e9b,4f2acd9c,3fa4e922,63d1c430,7c516aa9) +,S(514616f2,bc2dafa,8be3b9d5,f00b694d,2fb1af5f,12d219af,c35204c2,e121d93b,3e5cee53,608a299c,f67f4e0a,65adbf2,57ba8eb7,450058a,74072ccf,922eaf9c) +,S(8e3fece8,5338ed31,93721d18,1cff34e4,fdc42330,6a8e1a1c,3b002da1,6921a661,b095734b,6736486b,676dfc24,9cac99ef,12894543,8b333b2e,77664f8,20f686d2) +,S(46c06820,df101ed2,92842186,7d8a20b9,6db1eb9a,ae63355,916d438c,a7ad4447,fcaa10f4,59bb73f,c48d1b60,1147b535,d7d43958,1bcfe26f,9acc7abc,ddf1afa9) +,S(56334df7,1f9b390a,b001e406,ab37af71,3fff8c69,1c2eedba,fec7dbf,cf722b31,22d04394,340dc156,a73c4b0b,f49a6c93,8a3724c4,4744690,4af420bc,726707dc) +,S(202e246d,89045f8c,9dbe3dc9,7ca52d23,b2fd55fa,1b5cbd37,cb882663,ca67c4f,f4e6cf89,9cbcf023,1c9f661e,c4588072,7a6241e3,513cb365,9a2e7b20,a17a62b1) +,S(c8054ee0,10211c2c,f5bc1ff9,43552eff,c56b635c,d65e409d,ece239e9,9b9bd4d5,f50515af,51601cbc,de6842b4,3b854b05,bf1ebd1,678c46b,46e22827,17f31057) +,S(9c29788c,235eb61a,d2940708,4b9701a1,ea3282ae,56f984f5,1c625538,14438383,32111eec,efdbef2e,236469db,4ad30e30,c116cc42,99dd286c,2ab70ec4,9759ead7) +,S(5854e8d0,b7b5c394,7068dc86,f94c3cd6,72999023,367509e7,4bc1745c,19a57ef8,7e7901c5,c06bebd,f50c4113,4e0d2d3c,edafec05,417d45f2,345b75cb,a63eb98d) +,S(8bb2fff0,f45be789,a0446e1b,3547a44d,1104a5dd,9c8e50b7,4d0fa891,f73fef34,c332e365,a5343ea6,6c571e2b,c383f767,efb979df,72223a79,35da9173,73b182c1) +,S(ea88e65,6ee43387,86165faa,cb643cda,992f5656,dc7333c4,5ad8b561,8ccd209e,c38c40d6,4a7a343d,8ab357ab,845725c6,af9f4f4a,843986f1,fd0a83a2,5df0f909) +,S(c0c1d4df,857c7ea6,13322c2e,e0d4ba2a,a3b18ab8,cc8d9ff6,6981d6a9,4446295a,247115d1,e8eef7d,ce6ae1db,ec9be46a,9a284648,ebb7a918,7292fe05,9d72b981) +,S(91e6a4f9,407d3600,2a808d8d,db723ebe,67b8e212,792ba65d,b74e028c,ec7fc72a,ef6ae560,35f58be8,5cce98f7,b2106e0a,12e57dbb,47a4a995,47ee5041,3c5721ba) +,S(cd749618,9a8c1d36,2995cf61,380d0366,24a7a402,e21cf078,18794e08,fb208454,f3dc92be,15d1f912,a03debcf,88afcaba,2dd6ba2f,1d23a4f6,ba02c5ed,cbaf0bd9) +,S(99f5d12d,2e68e70,c304f3fa,44eb24a6,85f63065,af0a15e9,f71752ff,82943018,59f1921a,d97ebf33,68f962c9,c0a297b1,dff9f980,246d5dfb,61168dc1,da0b8a9e) +,S(63c6cd30,f9c07096,11656b1e,75d17191,a6ac02db,9debadff,7b3d602b,b9f7608f,2e439373,70a41b8f,e0e5f0a1,3ab75be4,6d8b1ef4,ee71723,4b73ffef,461083f0) +,S(b7407f26,90a5ea11,d9b7fc55,17e6c1b1,9e04fe47,180b1e93,94cd5e97,5d184d92,1b953929,47dd4984,7420f727,7a6796e7,828ee880,3e0d701a,aed8cf7d,513de6d2) +,S(24979116,161c8840,dd521e96,27a50056,c29ce48d,d86b6297,150f9a6d,e383fd40,13dd71ab,3dd69cf7,384d3e32,5fb16648,76f99943,f7ba3649,143e09b0,28b9a70b) +,S(f109b6c3,6122b278,8656c80d,4c84150b,b419919,4650d96b,6f2de8f7,f9d73b7d,a7457369,bef8d54d,c0a91d4a,39496f85,bd971f6b,4a13dc77,142ead5d,791c96ac) +,S(59b303f8,2031c370,4f17c929,7fbd0ac1,36be9900,a26b5516,9f0e3b6d,69118df9,30c7c4dd,1666271a,5ac8c936,b35068c1,9830306d,c695e02,d6c65ebd,2fd678c3) +,S(6627359a,eb3910db,4ba54cd6,c7b884c9,a678621a,d2bf6cd6,6023974e,d462fc52,bcbcf9ba,d2de78a7,fc486734,79379778,feab83dd,ea4f50b2,555c457d,a910d487) +,S(76fdad80,c4fb507d,9c9d2305,90e818ac,ec7efc04,1184281e,9212785a,dd51f1d9,cc8cc7cc,349cf307,f34adf7e,f559855b,9b88b70d,7fc9d19a,18cecddb,e3a8c346) +,S(7893406,e99cf08a,52fed9cc,4a9bafdb,7f2380cb,4c288700,b983b791,e1313330,ec15e1af,39eafe5a,d081acd3,fbd5b8ec,d0c2e83b,7a5b8074,50ef80af,2511d149) +,S(c454aa4,e8d02133,ed93c229,d0e834f5,18f16cd,d83a39ff,3bbb1ba0,838c81d5,a98e61cf,89c43808,f4895924,529a6e59,8af57be6,debf5f5c,67e3b3a8,73ac51f0) +,S(ff0bc21c,cbe5c122,dd2ba8f9,64239010,97dac1ee,3957b27b,f990b611,72402880,c34089c,1f7b2181,8d4cd5f8,9e445ec1,ecd634f7,52960da,467cd396,77bca50a) +,S(8e4486e3,49a0423b,d8132e39,812b78f0,3a0e61e9,d3eb7735,86f1e279,3731c301,897b24d4,37cc260d,52e1866f,4dc222ed,16bbf084,c108883c,a8a7b9b2,9a2053a1) +,S(4f4ca57f,84f5c4e9,6aca30d2,351089d,bf7fb6c,13847584,590fa5b4,4dc579e7,d53db7dc,1691556c,36f1cb1f,8a1b91a9,33634975,8f28d0b7,17d250e5,ade63a9e) +,S(fe8924b2,d7a24fa9,5c61830,aed8fba,79b3a96f,388b6423,c760aad8,cfc203bb,bd303e29,c6be0e2b,f4e79df9,cb17e0ac,e92c3784,fa8c26a,7e3cea32,d0b056be) +,S(3099f75c,f6a8c72f,8685895d,152f99b3,8ed9a3,320f3fc5,dcdcd14d,c46abb5d,fbb5bc2a,ec76529c,a278a32c,2a95c2a7,4a939c4,c0e2c0bc,6fc20b2e,a6fc9f1c) +,S(3b939f83,f84126f3,b6632de0,12405c9f,43244322,2ac384b9,7415c2dc,9c72f4eb,843b7353,ec454380,e9d4cc20,23a138b5,c1e602c7,f48be55f,1d3c24ca,f05607fb) +,S(dc7506a0,4a50e345,dca3cbc0,6384a938,b032f197,d6d30932,7b0c646d,95c732d8,fe942311,f6d49d62,99f9559a,3d16f43d,c6a39d4e,b623f9ea,e8dde39d,9bd5772a) +,S(f5a4c596,c6996a35,172fb61a,2721d75c,3dde68fb,4abc9433,f84d20ea,83b30dea,175e0d3e,77d2f63b,bb2ef922,d30b962,fd783b30,ef7dd8e3,5ae680bb,9df26572) +,S(7e9038e2,c499049f,e5d222ae,2f79f4b1,373c2f69,262f133,cb9be1f9,aea4029e,3592e66a,343335bc,e016276,6550a363,1d7dc64b,2223bdfe,7146f32b,8025c737) +,S(80f22f73,d16bfc6f,d6c28e92,1f990eb6,e2cb803a,d920850f,af489ff,f62b1f41,8714a5d3,c5ee74bc,73e11fd,24cf4d80,370e6711,c726ed68,2a1bd77e,7b503b28) +,S(498a2ae9,e86e53f8,43470a58,ab96fe0b,7c3107,d9d23535,fc887bfa,fe0c897d,47aa9eb3,73e841e1,4260f651,6ab3081f,7ec3809d,53b8609e,c3cced3a,6401bb53) +,S(601af64c,d14ce184,ca52c542,7a78c746,8e9c069a,80277b6d,960ddf30,3b3a010e,2900a63f,ca1576d0,11b46c27,32c87ef5,56dd579b,3bcd59,9161cd20,ceb7fa18) +,S(8fb2e0f0,7b2fcbc4,ad58b06a,822aa683,957f2bf1,5dd5984,9a1341ff,2d74a25b,7cd82350,8d797cea,b1b386f7,5d5f82af,6137dc9,9f6d6e6,b7c68cb4,75070aa4) +,S(336d780f,e9d14e8,b55a1498,72c63bc,83468eaf,aef3282c,9bde58af,6a69e6d9,92d1004,be45bee6,b8eeba68,2fd0187a,ac3e6679,f4fe0fb0,b723214,a63d2261) +,S(507ac721,f4d58704,4f8d2cbd,fb03aaea,b0634303,cce3e1a5,e4e47efa,90d5872d,b89a398d,e7db05d7,a1055093,97b83d60,9ba53c95,39caaf0e,917d22c8,307174d9) +,S(c42dcec1,3bb7fb96,29171026,f66c012c,992c604c,bea189a0,46e688a9,473ba343,8aa37731,a53223cb,a021bfe7,c413929d,8fe010ec,353464b,e3c1ce02,e54f7bb5) +,S(b02ea2c3,cd6093a2,d5e6b5c4,5c510848,857eedb6,50038417,d9f41947,2a866a2c,ebb45c50,cea190c6,1bb7c505,8cfce93b,ed1d8ee8,c75a5bf8,6ac9c127,2fa5527c) +,S(f4d193d2,9f20ed2e,273dc2c9,aeab43b5,85626d41,59b7edb1,51e17c45,ef70d84b,bda19a3f,19b834a2,c493f8cf,14cda579,1f84b6c,611ea7e7,280e5196,1add0974) +,S(8740dceb,19eac62b,75859b9e,4d0302d3,cc84f6bb,1ff6e857,eef7fb64,fe5f1bb0,a729eb0,4783205a,2e1d5b6e,7eb5221c,f2f151de,1489d1b,1d98fb68,e7c6ca49) +,S(79ec464a,85a29f08,d910bc94,449ce88,50aec626,3693bf6c,92a5ea23,84fcc9cb,77d170f5,b52ed0b2,9aad476d,85abae3,a1d7c544,c625ba2c,d44e68ea,ef53b39) +,S(4f1018d5,dd54bb71,cbc0e29b,255eafd4,6fb3aac0,45889238,847efcce,3207fceb,c32819e5,d23cc2e7,73a9b2a0,271fbe3b,a64531d9,2d416222,24a2f64e,3be7dd8c) +,S(dfbf1936,2094e85f,ddb25de6,8ca85cd4,e53768ab,81780eb0,33a0607b,fbe969a1,25ea0b59,33ba21c3,2ac5f1e4,932debcc,a2ca3aba,e0b7c671,93d97e1d,af80e563) +,S(184c66c0,2c36883,2c1805f1,8612449,940a371,54174f9,b67bb41a,85226649,cf63fe44,f1cfc791,4fb4a24c,1e0530e4,736f815b,a910b487,ec4fec7d,f8662eaf) +,S(daab3606,d386e04e,e39a8a51,a8242e43,ede9de09,f50322e0,a0f410f5,f043686,c0ba1c4,ebe7d10,6fd0d0ac,4e8f6e8c,fbb2b682,3a9d55e5,dbb7718e,d411718a) +,S(a887f4a,5311f252,ba0219d1,f848d334,26b0e216,69020dfa,89dcc339,7e04530f,5a7c04bd,8c37cac7,f429bff3,eda01dce,a5b4fa44,eecd3195,2878f79f,9dedeace) +,S(1b315664,409feb98,4d5dbfd5,a85afbce,4784a907,b284958d,28123f61,7c2d207a,2972cc7c,ba348e5a,5841d463,4597fd57,84eea5ba,a99bdc37,3119c568,aba205bb) +,S(154adfd4,27c30d56,d5f5de1e,d7e8465,6727e69f,82ec8d1f,19dfa16,b1fe4984,5ba86e8a,324b279e,449f61ba,a7fa52df,882477c4,921f2079,98199775,3e0372b5) +,S(debd69f9,fe55c15f,b28df417,cb1af3c2,585fe89f,b44c2f94,94fec0d5,88480994,98d8cc21,55c16d24,e8b1b831,4fcf616b,2564ff,9345fc9e,f8de3cd7,57f9708d) +,S(9fcd3490,2a7c54f9,a2855fc0,9558c465,e0316c3d,fb72c66b,71d4492a,efbaf9e2,a7ac4160,c2b5a416,89e9e49c,8d5aba67,143e1de8,26498be5,1cfa691f,f7f5d14c) +,S(59cacdf6,fe4bae99,598fb1d2,df3de7e0,586fd792,eee0d9bb,fdabfa73,8943a727,7c730d34,7b3ead16,c74d349e,191c484f,624599c4,d379acf,ed8d2341,160df035) +,S(5ce1abd1,fb291d97,db3a4c9e,c4ace635,34e6b373,407a8821,67722fec,7fb226c,abc24634,b4070973,d8a11025,5ff7a81b,a39de6f,5275d3f,7630de8f,23b7526) +,S(f783628e,bd0a0b4f,6ee68001,5b3014f5,e70897d0,ce159baf,3afb1aa3,207d73c,d06438fd,5b96b88c,94a68b6b,1f5fbf32,6c7a6efb,83b2f1df,2849f809,cc39af61) +,S(7830fabc,cc7229ee,35c7130d,b441d2ea,9a988d47,72ebe00c,6c159658,537ba0b3,49e8b58e,6aead178,3d5c901f,a803a33f,78acc889,27f2d57e,835aaadd,1b38fa7f) +,S(c930390e,a8901286,21a4399e,ef9a4a90,6416d549,c28f7482,6252fab,5fcba9e1,fa0e87da,3d0618a2,f54e8fd,d14b4bca,3bab137c,daab0197,4d110ef,b161cfce) +,S(2a0da867,20571917,6f949876,e5f00ec3,ba0924b0,a5e758b5,2d0c23dc,da9cd28a,96cd04fc,69350959,595b4870,f6df11cf,90c1fa1e,cd04ddd1,975d0bf0,fc907647) +,S(f64881e2,60da581a,f576e92e,3968e24,f2bef6ce,dc1c9c53,256374b3,1446fc83,808a945b,660b67f4,43ef833d,b491fa56,2aacec09,f8a2dac3,863b72f5,e7c8b94) +,S(970bd933,5ec5f0d,3a3cea17,5090f1e0,c181e488,1565c341,33017f99,ab81f052,4d1d270f,e284774a,fcbb6658,d5cc019b,8eb30bdb,39464a79,6ca1431f,1ae9fc48) +,S(dfe94b31,24c4541f,4723ecfd,f5cad197,2c058886,9283073,35415bce,e4c4779a,cc283e53,d547606a,a0fafe8c,5d3403c5,d047aff6,8b194b1c,1855a7ab,9540e23b) +,S(f1813379,673ae594,8fa30bba,d8737d0e,16c8bdd1,8f7047e3,bf33a39e,858df800,acd2c1a6,139a2dbf,9b008d50,d0b4d1f2,20bfb9d8,c24855d2,ed54440b,a87d294a) +,S(f4fbc156,fb631bdf,51192bd0,1c0db0c8,8890ec97,9c368f3e,c2106043,6d423740,3cb08cf0,5b07deff,431faf91,e1874baf,9cfccd3a,df487f4b,4f69026c,1fb7149f) +,S(124da4e8,3b079d72,4a7a9a72,5cc45a80,cb92675e,74541bbe,d36224e2,793de6d,3e700066,f12e0cba,4d6200fb,2a759554,1cd15531,ea065e6a,c6fb4986,548d00e7) +,S(749721c4,455e7826,1de045bb,266b97d0,6c2b112d,2ac8c16,428ce961,b78d1138,27556aed,a3f331c2,fe95b237,d3326c7d,25bc594,39f07b87,86559fc,55a3032) +,S(62cdca49,aa58f55,21c60dfe,d50fbf58,257676bb,fd4c4e97,9ff9a91b,7627a028,8bd49b9a,e16d10ea,7ee1528b,4f433e8f,17c4a688,a7148fbb,d10ed605,595c37b5) +,S(64d650f1,39b13aa6,16d3b227,5ed164b1,1cd3a1e8,81759344,7895a4b1,686478c6,deeee52a,f7572d87,f339595b,79643402,f9e2a065,7b95ba42,6b83d87f,3dfa5c2f) +,S(d08a3e55,66c636ef,3417c17c,d8526df6,37cb935e,db00365a,1ecc9f4a,9ab59d,2db049c7,5eec5176,3fcd3502,33856da4,e9ed32fd,24242a54,9c9ae462,240dc103) +,S(8761705a,35bcc509,afa20d62,61859afe,97154782,49ba47c6,f4b8df0e,30f20d89,b34c25ee,bb029622,4929c3db,78046a09,fd43b9e,be2dbf64,436f0df8,adb726ae) +,S(e3453933,4ce22643,146cc317,54e7ce7e,e35f6f4,e37b307,c4e9e11a,3c6f5f85,73ee178a,941e81be,ff22a0ca,f2bb4513,1afdde7b,336a3bf7,ad05c1,d465d97d) +,S(8389192f,6609a7e7,ac8e6f11,fdbfce8e,246b36bf,95e0de27,fac36082,34ca917b,957073a5,50448ec2,9d67b681,ccfb1aa2,67c88976,e53c99be,c68c378c,f2b636f) +,S(8bfd70c0,67bbe25f,e2e78029,a97fd863,bbf287fb,7a24eb8d,e5a61af4,c3c5d387,e2e6c66b,ee7265cd,5a1b1d64,4f24fcec,8b59001a,6edbb1fd,5d894740,f3f952fb) +,S(a5d0999a,a05f0bb1,59a1582d,980520b,eaf82015,68875269,fdb593e0,e6ff257d,e34d9720,5ef05766,676b62b3,62ce4b34,fe6d27d1,a644050b,f9c65c34,c423635a) +,S(44e479a7,b949c88b,507942e3,89ffd9d,17645185,92d4e544,2827baaa,5d5043ce,7b86ec29,8c12c463,b0a71416,24a570a9,e2b10d77,ae12ee23,2504edde,213a7087) +,S(60dec943,d9797811,706e0251,e0abd0ca,3f37bb8d,559213c4,3176ce3d,352aa558,2dc689f4,a31c59f6,c5181448,d6985335,16b0764f,8cc6fd50,8bc109d6,69fcaab8) +,S(5ca58d38,5b5449e6,f93c5c5,35941b98,d4ab829f,e641bb24,af7e7ab3,1f7709b,82afbae9,80eb6f48,110ce090,7f39ddc0,945d9d84,d5d3feb7,4d96581e,c17cd575) +,S(b775967e,a1b1d60c,9b09cf3d,26bf86c3,b9a23ea3,cd329138,10099048,d18b031c,d2b7169b,ecfa1055,70d885c4,adcfadcf,66f12d8c,846f70b7,12004097,840fef1) +,S(73d8d4f6,7d602f61,3c3595f,b9aa05d7,a23bc4c1,1fa3844e,92e6b79a,40220f96,bf722a2c,ffc9fee5,bea18530,9ecd14ec,bb17fb3d,568fe85d,331575ab,2400ce3d) +,S(e8104df9,f49f7822,152bcce,79c6df0c,8b1e9745,448c24d6,1e7b1180,99182b75,dc2fd539,ec8f2beb,1bfb0da0,f95ffbb,e14fc682,1c5d5023,96b1253f,82137361) +,S(ecd72ef6,fb6c432c,8e1449b6,d16180e5,777e5524,4900f209,e89e995c,546113e6,1671715d,358fba99,e509f518,e1458600,4252913e,268129e0,e00d64eb,7a26e135) +,S(e3b5ccf,be829bd1,6f1fc6b5,fa6d7c35,464bfe10,7e9d6455,a9907050,a4fc36cc,ce7abb9b,5471c1a6,de17a2c9,b5b671fa,296cb5f0,10b5ffa3,31e7a87d,a28044f5) +,S(f3591a02,ffab91d4,eb7e75f7,f4ebd22c,41c1ce4f,25f89c5e,d7ca1ab9,27107734,345a2e11,f2bab926,487c7d53,5314bb6b,cf04746b,be2edc10,18a57c2b,94fa4b3d) +,S(ca4b045d,ae54ad95,37d184f9,ffc5a950,c61349d3,227ae1a6,5501ad97,cb45c635,e30f817e,255ebeca,352f3c24,b441d1e9,4660f456,ce9cd72,eaf4c4b4,d7c1d806) +,S(f7cc5740,54a9ea61,fb8ebdb7,b76a95f6,30094720,675aaa72,dfd29bb6,6f41ea38,9d463d8c,fc5424d9,18275aeb,5e046be3,b3dd7fbf,f52d4990,f52c81e,b2556eac) +,S(f75b5f79,fba3e3f8,ee64bbef,7d34e8a9,b4fd9bfb,27b6a9f8,76b1f70d,ed6ab6c2,220b40bc,5c3fb77b,72c48e36,2745677f,7e0e8266,f85a14f9,d4030ec0,90a43faa) +,S(2aa367a2,5060236a,627d89b6,ad0a398d,89d86a64,735a4fde,e88fa4c,d9cd450,2bfedc25,2491b1a,764a802b,c4d77d86,1e70ecff,e9aef8f6,e829448c,d841fc32) +,S(ff7f49c1,11783cf6,e7da1e22,15827b07,a1078ce7,b1eb3257,65a37c38,a141620f,69550c9e,2e48058e,8bca8b54,21251dfb,a488c585,df644bea,d519acf6,54702733) +,S(31d05358,1164f4ec,a45f7338,fd3ebb90,76d017b4,5e679601,6fd02a0b,5c3aa39f,f124319b,72177ff1,462fa90,2e1f8d23,d4d3ea0e,d1bfd1fe,6bccd92a,9963f575) +,S(6eaf0edd,fd1203ec,a2cbf2f3,8da9ad7,c8a02d3,ab5f06ea,bb88fb5f,7e6a3bd0,d9336d01,2d8e9474,49c521a0,10a3b83a,815a0c74,a31596d4,125909c6,73e05f08) +,S(b95a519,77991ab7,fc3943ac,ff5fa88d,68e759c8,11cb91b9,e9a1ba97,7eda1347,8cf2cb5f,446d448a,5a98fbfe,75a2ffa6,9758bd15,36eea87f,533822bf,6de5ef23) +,S(4e5301d4,8ce5edba,f3b1dc21,2e804e7e,1fd386f5,6b90eeea,da6c1c58,211427e8,f503ec3d,e169fdb2,e1d2f684,cbd9d684,dcabaad9,376d96b7,6fb0a5d8,1b9f0d9) +,S(4fd1a9e5,9031b43,715f92cd,c49c2d0a,fc7c2b54,ad61d7a3,9142033c,3cf49cd2,73ecc11c,ab0165bc,3ab4b43b,ecef694a,2d99c9be,8b877160,2c885a6c,8e4adcb1) +,S(67406865,b32543fa,5ebb7fa4,a8d8fae0,384070fa,2e8a4b86,74510099,20257c84,3fdd9ad5,93a4e0b9,4f4451f5,e3227df7,e829a45c,ef3d271f,3fd85896,bbc62008) +,S(14b955ae,d6ee5be6,ef3dcfa0,edac40a0,de7e8dad,19c8dcb4,e4992a65,a46569e4,d4b920b6,21823f81,8481eff6,761353dd,7d9f31c2,5ea9d1eb,ed60a5d5,fa2daf70) +,S(14f283bc,5608d5fa,dfaa0b3f,fe42fd20,4003e434,c6368fb7,22ca5f22,3339ae42,b2415e3d,c3aefd3f,c644d4bf,b0a87fdb,bf0ba630,2baec8c3,7c1577cf,9edb7397) +,S(3fde0c67,7d3ce20a,6e6275be,7f80cba8,5416a55c,58dfd09,8e733a32,1fbd1c1f,9b8ef7dc,610f192c,949782f9,bea1f08,9a018b25,8926389a,1155d033,1adaaac6) +,S(9c55e669,df5f3d05,f15c74dd,48290540,b993bf4c,41dd9247,df5332a2,ed17267,23db0ce9,30c97665,175abd78,33757fc1,8c6b3c32,2d260810,981b4e0a,6e4979f6) +,S(bde84df,ae141a0d,6e8da60b,30f41746,506d2dc3,4b3faee7,d8568a92,82968d16,45a33214,ff1361df,e724697b,99a6c686,900374f3,6c298dcb,468f38c4,4ab3ab04) +,S(1940294a,b8f3c2ca,45f68f45,4c60c5a1,e5d97085,946b30c0,54939daf,c99546a3,563f9f99,3816c62a,1e60ea76,77c61bb0,848bc926,e76e386a,bfd96bb4,ece3b81e) +,S(dd6ea1e0,d0d13e64,7d0df92e,ad22d838,757a34d6,373ccad6,6829fcce,b32ccb0e,c018e9e3,6bf4e8b2,853ad27f,a49e5ff8,384b557c,aa00c3fd,d8e008f0,ee33c313) +,S(657847e8,c7844562,e26656bf,bbc27b84,dc104737,42c4dffe,c0669616,5b7fbf19,dd90dfb6,58b6ada4,901beda9,a4a9a8a,42c6a4b4,e79a4172,5b5f6ab6,95f2df5) +,S(fb7024b1,40be9d6e,906d26c2,edb781cb,49b8e71f,396b8d3e,352506b3,fe3dea6b,de408ff4,e50b2328,b6ad961e,9dd1ac46,fea36005,1407061c,5a0fca32,eb08efdf) +,S(2d29c008,65a7b279,d3a80179,cd3e8944,b3f2be0c,49a398df,a3113350,d1d8e8e0,caaf127a,ee704a4a,65802748,59649e45,25c55005,f2667ee9,92e9d923,daefcf8f) +,S(db690474,79b7209f,4de8d42b,a3c1be3a,39268589,a7c33632,6d87c1cc,53d5662d,90de8be9,5c3587aa,9913ce32,c83e24e9,c58c1fbf,2922c63c,b777770,fbaa4e00) +,S(9806506f,922e4f0a,afd54ada,258d6fc1,723c7087,ccf13f0a,df247356,c941697b,c07e2018,a8cab841,37698eef,3d31cad1,b97fef49,77b277c9,25245a12,f16bc237) +,S(ab868d3f,e6da25ac,5b11c112,28f14621,661e0ad1,e33d25ea,ae1ae7af,60e40187,ee24b698,334a9850,1a1195ce,d57a7fd9,4b12c488,bbd301d4,d47d5f13,3cbf54ad) +,S(e7561fd1,9d2a8ee6,12056be1,74257e28,3122f366,abf66f49,31fd89ee,fd8dcda2,2052e74b,e3656d8c,5c766ea7,3227b75b,85bcb190,8a07918d,5a8a8001,3e166d5a) +,S(5f19523d,84bbe307,be08f2e0,fa844cb5,7b562f01,39950820,83c2df9b,e8f21e6c,3a96fe16,28ee1dde,2ae9ad2d,5724eb88,33377542,6e91acb9,d9be7c41,7265d7fa) +,S(c9fa4668,3c949b11,2422ec1d,c5501efe,2fdcad17,255c7545,69837d28,d9c10cc1,1aaae75d,18f691ac,cf1dcd8d,9e8e0348,b5b6e734,76d47ffa,b5e23ede,c7fd1dba) +,S(1da90e2a,1e911879,ccfa084c,393b8205,1799b2d4,15a42401,b1ab793b,beb8d8c,3d3f7c69,11ea4d38,46cbae1,53b3fc32,74994ee5,1f4fd332,2da4d28e,c89c0b63) +,S(c6fcf10f,3851e432,6bd504ac,b7847f7,707e4098,d8f66915,3e6f89ad,f31b3186,d0ac89f4,a16a63d8,6e36ea10,8f8ee5c8,4e2705af,a9c98bff,3ea5253,93a50ced) +,S(15057a2e,eb56c67c,cb6b7d4e,f1257ae0,3cf236b,1f9b6588,fefd7f46,16378233,4dbab530,ccc0a7a8,c49543ef,5e3d0a87,6f205a62,2f9a90cf,5054bb0f,dc4930c2) +,S(37eeaee0,72d5ac0e,6ea7337d,d07ddebd,45bf1cb7,8c02dea3,6d1e419f,308b20f,b0c64496,5d9daa14,19c77249,a32a3a3d,a5761adb,bf5a394a,ebb91630,f361d506) +,S(5a207bf8,3a8bd0e3,3c71cd96,d928bdc5,f1d6ce8b,7ad9bebe,61a27362,2557745c,3accb757,fadc9b6a,2a5494ac,15744113,ee878901,323c6138,19ec7666,60f54dad) +,S(fe08dd6a,1a0fe325,5a391271,e81befb6,f6b2ee08,907046d1,642d39bb,fbabd139,42c342d1,3535822e,e4ef1b43,69f204c3,665d2326,1379b0d6,c520c64e,181ef40) +,S(b7d262c9,8dfdbba,6483edcf,38044cad,d6d859e0,3d1ddac,a39cb999,78706111,96086350,b308b397,6a007c8f,5181b5ba,30bb4c11,653d689,ee97fe47,28d798e8) +,S(4b12ab2e,23b33775,3ae97d7c,1badf5a,7d354b57,dcc78407,6836f802,34130c86,419d4e0d,9f708bf4,2e11e73,a1fe5815,2bc9649e,49ae45c0,f52fb8f0,f23c450e) +,S(fc6d2682,a96eccda,4b49570c,8bcc47c4,8f362bab,7750b4f7,4f30cc49,d8e88dac,1af56527,30264580,d1f22612,e90597f8,694aff0,96001848,8a243ac,f4beedbb) +,S(c7b9c3a9,a189eba0,54742c40,c4afdb9e,5e07e6c0,e442cf06,32e9b655,1e607e8b,5bb68277,2f2274db,62084cd1,9c1a545e,ef6b38b8,d4dc3e30,fc58042f,f01822ab) +,S(eba4d342,30dea72f,29a339ba,3ed4306a,46c761c2,bb6f9627,3406fa7,50dfd956,fce17a0f,23d278b2,e3da1747,706840cd,d31b01a5,8793506d,2155cbf5,dd237cee) +,S(a4d36dc0,2177d471,35b4358c,6adec285,3595dcf4,6cd9acc8,944a569f,82c04155,85a29779,63b21be0,e378fd0f,b5a60fdf,65f3e45d,c2fafad1,13377f4,81f00281) +,S(4916d063,ae8bfae1,e3f5bf56,fde73abe,eb165aa,4e6d4a16,9060ac95,76109ba2,a7916703,4a0b40d5,f967a08c,a536b7c8,3b2b0b4f,67638656,4ae9b4d4,4c3f22ee) +,S(761cdb10,b2966030,85f8f1a4,404ab49c,9de01979,85817f97,ecbae412,eedd046,1d115720,763b545d,72f8f50a,b881e7fb,9789f0ea,8dda90cf,2ee2f3a2,2e193db7) +,S(d7a2570,4d718e92,df85541b,490bc13e,860ff014,e8ddd9d2,e05fca2b,8dc64ea3,5e454b9d,21346767,71c0e035,fbc6dec6,6102db85,aa3acace,c158f43e,534cb90c) +,S(2af6004f,7962c52b,b0ebcb06,32975bbe,a6b9a99,4dc5a5df,eb20a43f,3d4d3bbe,6988a9e2,26f8cc15,3108e3e,b68c6596,be1deb1b,53239933,d91e095d,d81a14f3) +,S(a92740e5,3bab0860,1127571e,5d33184f,ca805d18,75ba4959,74108f5c,a9504255,5df2851e,2eb76b71,66dfd3d,3aa84e0,96d49c85,10daa44e,68d75eb6,c6d2379f) +,S(90d0961a,510d8a6b,60a87c44,93a0c8ea,76856770,d076057,bcc7ed98,70014939,74d4753c,1c913088,66b6f7a8,a2386ad3,7c13dc2f,85b4b4d3,f8d7603a,ccaa545d) +,S(ce52bea,f2e3a604,f62bfa27,92e2e083,8dd5c6a6,ca338ded,249be611,4ecd12b,a869de73,738a0a2b,7c824444,925f3d9b,dd08670a,8f8ff1a1,a4988008,2d5c009e) +,S(99ca8dc2,10e3fcd2,ffd39a47,1c06ac49,12215441,6cf16be7,cc3e350f,f3cd05c4,78087a80,131adc2c,6bf26309,ef0720be,4550fbe8,912142,c6ce496a,dfbc4982) +,S(be442cc2,9f5a7bc5,d07ff1f4,322deb90,cbfcc6a1,7d8e611a,b51ec610,a202d1c6,6250f2c4,680ed934,8028f2c0,1acf5bb2,fb3d1f25,e324b734,11156128,77c084a2) +,S(53f5f5f4,37fb010,2130346b,51b9b14f,e75d95f9,b8f80e65,67770bb0,e4ec8e54,8da52b53,c6e733f5,aa0dd2ef,23e2e1c2,24c0d571,328520f9,cb1cc5dd,28c62f93) +,S(206ce565,e90ebff,7d799e3a,134a56f6,a897ab19,186ed554,11de6daa,5c8c4d6c,c2ff5d22,bd2d6dca,7dfec5c2,e79d5320,aaa5d53c,38ae0675,4dca9a96,a6a75804) +,S(d1dcbfbb,87ee2fab,811f2a72,726d2b54,2176a20,cc23f744,faadf2ac,7073f443,106c63b,41800bb7,bcafc27e,3f8337d8,f71da693,e1f4350c,1870f968,edd17db9) +,S(d21aa173,c54376ba,1eb9d432,26ffc9aa,a516fd0,ef17c2f6,db117392,db749328,37cf5df4,e01480d6,604f79de,63a754b0,2326f9a4,ed74cb24,7724c682,6074e424) +,S(5234b024,a22c69a7,569acfbe,2cbb7ce6,15e56383,f8e1e031,78dd54eb,7d1fa3d2,2beae442,651db52d,62bc3b04,2a5b343a,b4103895,a74aeddf,d9189630,8bc000cb) +,S(9e6e9875,9f3e21ab,a709dbd4,f598894d,f5048dcf,5ee6cb6a,50941c13,35412f64,2b670199,e38f2e5a,424dd169,e047189,43111033,a7e4f4a9,2dc26906,31757ea8) +,S(8416e295,9a718e77,10df8a92,72de9bb2,89232c73,832597fc,d28f2928,8743ae45,6ef49202,801b408e,d81b7904,4cd1f002,20732a74,764c44db,4c77121f,1133d139) +,S(852a4fa7,48a3b2f,326405eb,e52ba2dc,27462f72,9ea3429b,b108e27a,d53561a5,3e06c046,ee0d9c23,6b0e441c,2cbeb672,770b99f7,8d062ac6,a81ccaf3,a562e520) +,S(2880dda0,2dbe56be,b93b876d,3c083ced,fa6097a1,cb234c5d,3282942e,3677c1bd,dfb0ea10,92d46bb4,fe95366c,5370dfa2,3d371f78,40e919d3,bf966441,f1bb43a) +,S(cb6fbc02,9e828d7f,c03dbf86,99a676a0,37b53555,275c86f0,7709ff89,f1819c65,fc4e2d9a,36577399,15cd50c2,1cb76cb8,ce9161fb,e05babda,ce516277,86062266) +,S(8087bb5b,ff1c3438,21b24106,606d0ec3,abc76a5,8a872161,5f6305ef,f81afebe,578b287a,a602c02b,8f5c5030,ae9a4632,23a4437e,944f4353,d9bc17de,824ce72) +,S(369f54bc,30f2c90c,7af0def2,2517ce58,f8ae829d,124ed482,653a28fb,42d3a33a,b8f2eaf,35af7e32,c63c97ae,f5962143,61f466bd,c4cc1b40,b4526157,b9b59d16) +,S(87be4c4c,1b2f871,53bb2448,ffdb6ac7,df294628,6be49eb6,edd3d533,1fed8f7d,7ef474bc,6386c0a1,5771ec54,21cd51d0,71fdc8a8,66938a2a,dfe6f4eb,ca0effb1) +,S(7b6678f0,18f75bea,8c310eeb,239edbe2,80393f1b,5eed1cfb,c013fa29,1e14715e,78e8b8e2,666ee69a,7388275d,2aa1bbf3,d985707d,3dd52890,c181a8b1,f38b1fd7) +,S(89ec641,96729e02,2a9608f5,8fba388b,77d2826d,6b37caed,90d27394,b160f135,5def3142,108d7387,19ee5a7,41deb18b,5e3030b0,d919a1f8,ac94157,a4786cff) +,S(2cbec739,3769090b,3aa2acba,b78c3fac,8b83749d,641f9311,99e6d1a6,36177f8e,3140e7e7,57ad2d5a,cb34a007,f4f26aeb,67fea7cc,8902fbad,2ca92083,f3de8886) +,S(678cefcd,a2d6a58b,53e7b116,d03020ae,29d57618,4663fcf0,2ebcf0ee,bd946908,f45be9e0,13298eef,37cd56ee,932b2a41,18834fc4,331c1713,314bd028,e6a3491) +,S(8ddbd278,adcc4ece,4692305a,94cdf011,5073b073,c88c1524,b43f1822,c73ec0df,90510edd,3c52c6c8,caa9ea1a,e28c7784,5d2d675b,a33b1022,68b93b17,80fc5b0c) +,S(972bf082,b162ff5f,22b149c3,d238260c,607d7878,aaf70739,3041d0c0,d7e36626,4685b3ba,f61cbca4,d99b64f4,3e90a442,6eca9f24,d0235324,797505be,4c4087dc) +,S(42af0d52,66604ab9,7de801c5,4514d23d,d8c1f760,bc86280f,540cc57c,bbc97230,5649b89,8c9029ed,4357160b,d97b74d5,cced0668,98de3b89,77192bec,1699ce38) +,S(5366770,87296d1d,8e6138bc,a9a1a0c6,1748ee21,4c0410a9,fa5623f3,d7bb30ac,e0683a60,786ba0d3,52619c2f,672d90ba,7c297b2e,59591f31,fd8b8fd8,ed5cac1d) +,S(a03b6284,e85bb18f,f04308d6,bce40e91,7d5d0ab4,ad920255,9de55c11,fc39fc24,2739ee82,c22cc348,23fe7235,a939db8a,c073005b,e014b564,4cad5a8f,e8785493) +,S(2f394ed7,268a53a6,bd998055,a24f7dd,f5801dc9,99233a63,7332e24f,26b66e97,b52b4f3e,e934ba86,d1bd3714,a26bc4c0,e49d09f,5d055413,8d3f4cdd,73918d88) +,S(91773010,527e537e,3aa0c19a,611ef5fe,7740bced,ef0b56eb,bb35a12c,7133f8ab,68f937b3,28b64809,27e1063a,bbbc36b5,b097ae5c,ccfbb965,f4814f,ea9fb5b6) +,S(2851bdbf,cddc8af1,7a20c1ae,bd529df8,28486bc5,50a00b24,763600d6,904af615,d302c085,702e27ae,6d46c376,33035d6,ee2acfc8,3b731758,5d15b2d6,dccb1356) +,S(e986d7ab,25499f1,45610b79,1b47e597,8be3d363,5a6f29c2,5d34da48,314bdfef,d0638dc,b3b3c150,10ec63b9,61104559,cfdb182d,31c41c16,5f53c331,47de35a6) +,S(bc45db2c,5639b2ce,2dc1c5e0,d831d824,ab44daca,7fbfa099,b2e648e2,8f8bfc03,5d93e3b1,27b289ad,49e32740,a9f53e0,79a80580,82606884,2c1f9b52,7213e32) +,S(4145d67e,47d9809d,2c67b4c8,49e29101,849ef512,ca7b22fd,667498cb,50a8dfc6,5471f4fc,2a4f7f82,9708604d,90daa64f,daeae007,d6290ea9,4922173a,4513f096) +,S(2d157f7f,4cd79d56,bb15314a,a738dcea,427e3087,e7a5afa3,c1ad740f,5c686825,c1c4f318,76159f4b,94e7a29a,2766bb46,962a4e21,3a7234ee,eabf1ea2,296fc1c0) +,S(2f426284,77040b2e,5dfe26cb,c12a81b,d6e89696,8226987b,361d7961,a73933ba,bdce120d,141b2879,effcf601,c75532f8,a384f942,879f24bd,45e483d1,8144075e) +,S(b419cfa7,6cc91302,e683c9c0,eef23ca7,bf9f8f44,37ea220a,b8a1fffc,3bbf527f,bb86954e,290f2419,e4891a70,b48806b4,a911e956,e3cd0dba,3c0251e3,aa929517) +,S(cdb4a6f9,5734164f,c7af2913,f0ded939,2b17bd09,b03698dc,ae2d72d5,4925236f,89eda236,bd1bf5d7,e500c47,d4996451,d57c963c,4f125ff,c9ef8e6e,aac8e7aa) +,S(ed4ea751,a45ac44a,33e6f2f1,50392fe8,a12a8c4c,2233ca3e,321800f8,f408c256,9c7e9da7,4a2b349a,ae9266d4,d04d912c,a296d963,98ace64a,caf40634,970ffef2) +,S(9b06fd38,fdf963c2,830ccfcd,1df08a73,84a74b02,fa79a87c,96decd0a,3cfbf5d3,e866461c,e7ee6015,aec4ba3c,d4dad0d6,3ede27a3,2a1b20d4,eb29de00,6b226416) +,S(df11481e,efc1cd1a,97e13f1e,e0702056,c2b7894b,de1a44ef,5166e521,1af6ae75,a1411856,35429fa1,ebee1f24,de73e2cd,80c76661,717abad4,a8354aba,222b7e02) +,S(f8328d01,b1f3fb3,d07bc65d,e807c619,46e4df15,a518a845,23da032d,12a3c9f5,e29dbc74,7746d478,9ca9a6d0,b5ca9ebe,de174914,7a709df0,d5e0f100,cdca6216) +,S(3e3afbbd,b7fc2301,f9a13590,acc4fb5,ff0d1b7a,92e09e46,1fcf0093,4d3fff86,1fc7f7e1,b9821c51,bd44c8d0,9619aeb1,a5c2af1c,3ec28742,f0f26212,6eb6ebd6) +,S(aad17eea,68348015,9cc19f8b,69d335b4,78ede880,4c551660,74d1ea9b,1ff86125,e993b8c,ebab89db,67cf45bf,361ee910,dfa1749d,26b488e8,ed6cf9df,9d365257) +,S(213fbb19,5515c686,fe8f44b6,fe26a178,286442b8,fb29072d,37ce9972,910ea35c,497b951b,7df7f4bb,2d0ee577,19876203,d68c3958,62781362,18e8969d,ed52a852) +,S(cd7f72a5,78ed819e,3e93321e,c8b8c7a7,eba91b47,92821a2,92493790,370120fa,a3d51c70,99280f2c,fa2c537d,991077e6,ca4eac91,93e97ce2,d8ff5fcf,45bb1148) +,S(70a360c7,a72939,f9a3a28a,1d1a9e2f,8240aec1,878f9b19,68923e0,b67f3b51,a1d9c07c,53a4dbc2,2ea4ae36,b6a0bb8c,dd175c98,6d2f61b7,3eb05552,ad710259) +,S(544a615b,4f8e2b66,fa1dd19,99e9cbe8,eedc35fd,9cda6d33,7a076601,21b5e46a,75d26db9,c76fc8d7,65286aec,bdd9c97f,d7ba7a9a,7308e6bd,75150b35,ba8451e5) +,S(4218d79f,76a073d7,af19b265,74d5b5c8,f8b779f7,36c23c92,a01c3467,8ec8acef,6815f631,49073b5f,e65c05f4,eb284c21,87e60355,e207cbda,f2c01eb9,becfb28e) +,S(6ada2638,1a82acc1,8a333759,8635f83a,3deca5d,9e4dbb38,64a2fc1a,a269b0a9,53d356da,65f7526f,60d05f32,b8b5f841,2e77b6f8,b61533ba,e8ace229,5eda6c08) +,S(5fa99d01,d9f29a59,75518e98,7c382c41,8bd46ea4,7813f579,3366618e,e118b09e,d479d238,38deb81b,dcce381e,4982652a,f15f6602,dbec34cd,6fc0e82d,33fc3b39) +,S(cc6ed576,34cc67ab,6ea676d7,2fef96d3,bbb4a00,b2b7fe44,12d0195b,44d76f6e,b15c15a,d50999b8,aac9e5f1,5834284f,dd801b0d,da4be94,f520af62,f7bf820c) +,S(e4cd0fdb,5323ea3f,deb10bf8,90a26b6d,ff447679,d8747ddf,ec32ee3a,40ffceb4,fbdb40c8,ba9c4357,656af718,db7629c4,e2caa87b,c41f8c48,d5d86a30,d220e1f5) +,S(77fd722a,ba51b929,ac1e3ca1,a2346833,b3c1fec,7a756568,6afb7cd8,9b88a8af,d02519e1,d6e9cb4,4f378ee3,1df4bb74,6b5b555b,2c7b0691,9cf90f5b,3de98505) +,S(4d391fbc,a9dd3d47,9d3ca57b,f299f4f8,6291e523,95ff73e2,665418c2,997a41dd,5cc9ec33,b55e606b,b93e9fcd,593c43f3,e5d4a3c4,39ec6fce,1a9ebf25,b4ce899e) +,S(740bc446,17b17b84,5c99d63c,3c92fe81,2eb232f8,8161a2ba,83f3a445,73084e97,fd8ec6e,f4f9567,71717481,c1301876,fb10742a,99028c67,883254af,f8355464) +,S(c258c21c,adeb8453,5bafd8d6,cced030,c6aa12c4,1bdcc392,b2d10e5b,1b46e5c,7cdf037f,3e60bd7f,739d08af,a20de5f2,b73646a7,5ec3e2af,4cb62139,5d171d31) +,S(8fc88069,733a4d5d,bd80261,c0c9ca65,fac22a5e,1bffd768,dbeffb83,24130d44,4211a94b,f88c042d,54d37ba7,41cee691,ca5bf0a6,38f0ca95,954f4aa0,12fc946e) +,S(cf62ee1a,40321c24,7fbb0e0b,ce99d314,f5152de3,32b827c9,67a61bb9,c96ad4c,6284a7c3,e64f7b8d,4bd978c0,77dc0d22,e6137336,6410d5a1,9bb09640,1ec4a3fe) +,S(53351f8a,4d447760,ecc88443,19b69160,bb00b3ca,fd6fd9d0,6c0040e4,549f8ba7,83844e19,3816e6ff,755c148f,d5488384,c7c1cbb8,8c09ea0a,16352bcd,377f6b83) +,S(a02063ce,ee2c9191,94d0e1f6,2ace9407,baa0157a,d2e600a9,e173348a,1d06bb0c,630461b5,55653f52,da9b40ea,c4448a8b,fcdaeeb0,1007dde0,5f4c186e,9f146339) +,S(70bcbdcc,25de1764,7274f374,196608aa,c360c09e,951b9857,5a6a8d6f,e1d35660,3bd5bd9b,716359ce,80b5e719,a9e1d40c,3a1c7430,94a82b64,a90b0f4e,db461d74) +,S(df8ad77,83cfc3c0,6fbb1fe5,2a515de0,54b161c1,74155fff,13812d19,aadc8fc7,bc4090f6,416db0c,9d34ff20,a0b7cb99,af38401b,1264c604,44ec7355,80069569) +,S(2504e9cc,ef399800,5f2fff3a,452d56fa,8788df47,e05509ed,777a9d9e,540a30f9,73c506a2,c6f48efc,af7f4d2f,ab5fd833,6fd6514e,db690a51,11659f79,7390612a) +,S(24ee0724,1c920334,3a6a6fa5,68979fce,18a9ce0c,819e3a61,571141a3,5bc97025,ee642ecd,605b84e8,68940a6c,cd7f4d93,fa0c6816,2fb0bf6,ba22427c,b0bd7b8a) +,S(1ead5ce0,9665c05a,63cd8eb1,12097f35,4961e12b,25c03093,e1c6d919,7a3929b3,1800df5d,a1abcc4a,b1c32fbe,a1dd7120,7284b5f5,dee7009d,c2f4aa6d,7156fcc3) +,S(47cf2ff2,26084f8f,9020b0dc,d838874b,160c69ef,2e5e89c0,98e7891e,ea05d507,a340d3df,129b5aff,1044d0d2,c3866464,bca2efdc,8dc83516,cf8fa522,d5fb7d48) +,S(4064fb9b,8e2e4952,a218bb8e,ae474a4d,51f050a8,3f9a7e75,b04e39c4,42d6cbdd,ff9cec76,a2ef1930,92d3e02a,aaddce0d,18ea66c0,d1adfd2b,9c7886dd,b835de10) +,S(838ac8d6,e58e20d0,321e0150,ba6d401f,cdd70a40,69d980d2,22de3353,fb81904e,993a6f96,2909dbbf,7b9a6b25,14153331,b1ef24fc,e892710,5f95488a,d95614bc) +,S(a5e36d83,189d43d2,34d6ea26,ecf5943,5aedee72,bc4cf385,5fce9b5e,e202f266,78c02c3c,e25c3b89,9dd2933f,b41435a3,dfc2d1b5,e7ebbfe9,54ab1c94,79822c55) +,S(9e240cbc,d357c4d3,34f31209,58d6f7ad,5ad79e7a,9b51f572,5ddc8fe3,1fba72c9,aea34a5c,ed60a062,ec1476b7,b30b3c9c,68cc5e10,cef9f0eb,6729172c,b511f06b) +,S(ad1b0646,bb315380,5c22b91d,1ee47a26,dfc9ed5a,860be0c7,ea8daec3,b6dc2eba,ee2e61a2,2499c509,1a910c9e,ea159873,a298daa9,6d30d8bb,353b9955,92dd2083) +,S(4f7b0889,11d8f64a,550d8c7f,11ecaa6,fa12df74,a236a0cc,35cb7cd3,5b0ec72b,931af41b,d297e18,b4d9ffac,8d7f8691,29b94250,f1de1d99,3e31525c,4dbb21e3) +,S(dab2a170,e4108f3c,93fba874,70bb12fa,834d0274,35695870,d2d3523c,93d3a7ee,262f12cf,c37f010d,deaecb24,d08ce35b,293a5c6f,1746651e,7bb0b2fb,c573ae4d) +,S(3437257b,784d72e,419e5082,311b5a66,d499f687,c4bcfa31,7abc7484,a3cf39be,ce9bcf07,6da8d68e,8453fa14,3b06d7c0,f38bd0a0,76f1cec2,a49b3bda,a5c398d3) +,S(4594ae9f,82611ab5,bf786024,ea34bfaf,939fa409,34ad155c,9ed5e736,899545b,2255c7f5,62b0ba72,c3834e72,e77b478d,77d3f15e,3ee0cda4,c4b3f928,ead450f5) +,S(7337705,12db06fb,36b21fc,26b585a7,3aebb036,b22743c2,f13212dd,81898819,753ddd59,725fb0a2,561cf461,c587f3f8,848b53ed,29283c51,5150c57f,50307887) +,S(bd915814,4d2afef3,552d81c1,8c74abc,a53f4c2d,654f72e,3f2abd66,d69790ff,1af609e1,7f27e373,b42b3277,a5f4714a,31ae895b,95e0c5b9,50e7ed2d,1827763e) +,S(8a11cd4c,a51dfee2,28c1ced9,3d8870d,67782740,1f49fc73,d4ce56db,915bb557,d30ad7ee,ae9f9c97,eec27822,9f47100e,ca46b3f0,27339719,6be0f619,56f5cf23) +,S(7929b5f0,2802bfeb,6c23e688,65b0272b,cfd058d7,c0a45ea6,97d46d87,6f9bfcfd,f9bbae21,8039783d,4d1e366c,32a890c1,8c80d1cd,41f08b36,963b54e2,f4fde5d0) +,S(80df06ac,1d5b966f,8080e79b,cc9f01f3,d55f8855,9b1a58bc,f6e4c526,3bd89d01,346926d0,a59558a9,2625614b,ac010f36,5ee5c337,2660fa7e,be41aac9,41136538) +,S(74545478,9ff383f2,94a92b4f,383ad13b,ed4b01da,d20f4ac6,efc83315,be5ccaf7,36489f77,81ee77fe,de1ea165,c4cf2b5f,e8217361,9e760cea,fae777cb,c160fa9a) +,S(2c6d35bc,b213a8a0,95c11fdb,42828b7f,e562d7d5,f877de67,de62bcd8,5af8fe85,aa30e370,34094f9f,4502206c,72f23298,2e60139c,2bd35631,44dbe6b4,c75d159b) +,S(8353657a,9d934eb0,2811846a,728cd162,4b43429d,304aa7be,830da70f,b2e338db,f8400438,20ffa5d,28189c5a,ce693c8a,ed4a4caf,3aff83b1,66a9d404,74e02b71) +,S(f216e93a,54ce56d7,c7ef6336,561a6299,2177ca73,4ed867f6,fd1a8ddf,aaae494f,db0a3f13,a0fe8326,63e8fad,b11cc347,8da296b7,2f1b672,3f43ea44,acd30611) +,S(dc371221,9b5d73f9,6562baa4,b62ec7f4,2e9a3dc8,de6e7112,273d0811,a88324fb,eecc9092,ec563e96,3720acaa,929f9bb4,4f1c9015,7c3300fb,581b154f,df57c004) +,S(db34736d,48f0b4f1,e1ef6029,6ef534ae,b10f047b,4256516d,d4499072,36649475,1c29cd6c,f7a8c786,952c34c9,b93e5188,1a116966,164d0fdf,dd1be4fe,ac586bec) +,S(a248457,20468424,f355af53,62f5bcf1,971b09ed,358fbd33,78fc7297,3696add,9a703d61,37d0deb8,a3767a56,c2e24573,baffc931,bc850694,8c9a3776,26547803) +,S(bb7b806f,a9ac753b,bbeaa429,31f68d0e,3eba38b9,8fb25ed2,40c9faa3,124436c4,8f812574,a1a8bbe8,d9b682e3,d9b0150c,7c6ff9c,f9b42e64,6e5836a8,12426752) +,S(6703c476,fc28a023,f6619427,69e0f068,489344aa,74495ad5,17b096ff,c3ecf446,8b48023f,7c9ba723,584211a3,6731e14,f42699ab,522e15e,ed3ac43d,28e2a38c) +,S(bcaaf8e4,bfa4b448,fe23f3b7,a1612b82,14cf0daa,349463b7,1b44ba61,e2dbf6a2,bdff2700,e2cc953f,e9d08835,dbe8793b,b07498ec,68ccd736,d6fe1710,d5c7f404) +,S(906b4fda,1a557220,1dd5b446,d726a2e6,21794517,3ec74f7b,bfed8791,9310cd49,d753f2db,cd2c4d28,d0304bc4,78690871,cf838490,2d7f4f93,441a74d3,892653cf) +,S(9ec09783,18f7d95,5180e326,e1bfdd04,fa5369cd,eb786905,8d726ac3,9ef93d5f,9cca8057,994b1641,53ac6842,4d28fb70,ad22baf8,f894a049,d1794add,97acf205) +,S(53347906,b75440ec,28362a96,f114d2f3,6f823cbe,bb0030f3,a2de3314,12b8209d,ccb38e0,471f8abe,47ef1bf0,29550ec5,59581680,3e19034a,b06a090c,ca0c1fa0) +,S(27c53f29,61b70480,93e24b18,eb357807,a33e5411,15215337,3b98f80d,d23a4870,5a3f4b8d,e18636c4,71fc70e5,9ac8c4e4,703fa5fa,880594fe,2f3b888b,da575601) +,S(921927e3,7a115f9a,12a616ba,cf55c213,22ed51a3,e75caa5b,eaccce75,de59b68f,bdbb7c7b,c1e4c5b5,98afb590,6263d779,55884e71,17864ae2,e0636c4d,727b141) +,S(973b3c87,6eb81ffd,677c692c,ae432751,efb3e609,1a3d9ff8,dde6cd6e,3f3ea8c2,340df771,129510b,a4112c5d,adbcecd9,8684b0ae,3a9683b8,49aebdd9,57bbb0ed) +,S(20b817de,f0533767,9938ef03,69204700,d5972c32,12656ce4,205e9ac,1b01ae71,2ae2fe5b,e2daa016,1c65c352,94a0abc5,c6b1ce64,fea99c12,34a14aa8,8395707b) +,S(63e2544f,7a7e9181,7a347b7,f72eb43d,ca9fc5d6,3d931402,aa6889b4,a3c95876,e62aee6d,20d714ce,5cdf52,18bd5fae,adf49cb1,f86e6067,f91cad71,280d16b1) +,S(2f90de10,71508cf0,b3583abf,c47d762d,a69dd472,e4183421,6ac39753,e22aeb80,5371bebd,4a0dd74,625e5e02,5a118488,880f3a89,9c23e64b,76193abd,3788d389) +,S(8d423ce8,faa96d05,45e37cf7,5e5a351f,7c9359c2,ad1c48a,c9adcf29,d2ed7209,83d4b83d,ee76c401,a18df794,8a655c3f,bb9d23c1,5ac0bd6e,ea80b129,bab40f2) +,S(12fa4142,5e028aff,303111a2,9144242,a9c91d88,55b3ea3,becec110,80181efd,6b95b370,8e792b57,ac10eddb,362eb10f,ee5c3b8b,b2e37d4d,c4d2ac40,e8c3ff57) +,S(923ca95f,2a3bdd7c,d7505632,cdf2d730,ce70196f,ffd0cbbf,f8347882,8a706f73,f8b0c866,c39b6173,b383983b,210cfff3,1903afdb,cad0b2ee,3e541ab5,2746abbc) +,S(844d53e,878240e9,63e3875a,728f4704,64ce3aa1,66209776,a869e0d6,88893646,c60cd291,92bf8c1f,f98c47b4,a713bc75,1c84f9c7,19fb32b2,5b855e73,6feeaca1) +,S(43786fd6,c5471d8d,ba277ff8,1005a5df,8838299f,66636b2a,65e7ac21,f1dc98f3,d292a2c2,9c8c5bbd,8f79109c,b8706fe7,745ff884,f98c127e,9142f52a,56091b51) +,S(6d1bc28d,f5e9ecf6,38783f71,fb98a2ce,bb0dec45,8b07257c,e94736dc,ae36d7ab,c2c54192,bfd80447,86214cf7,a28108dc,e2c00e07,2321638d,a0e80023,88d549e6) +,S(6bc4ef34,7f74ce3c,2ef3f89c,c3e265d5,6c742ccc,ff84b7f6,7d8956ab,16ff86c6,eb4492fd,2d2ab04f,1276be35,c6bde62d,be26a6e4,60c5c66b,8b0fccf1,79b46408) +,S(6af45075,fa810958,d42a756e,d08d5c,d67a62b,cb33cddc,b35fa99b,bf678b38,adbb724f,e7682c7,678ffc3f,ab738666,886c7b93,84960bfd,5287ff9f,ba5bff28) +,S(eb6d8b76,36466365,a96f49cd,355b7460,939f340f,905ad1ca,a24e8a66,55260600,7ae9cefd,aea30b7f,b9ba11ff,603b81d2,41f7a187,33f95c3,3c2bae0d,7fbea3cd) +,S(bd0c2233,2fef7d3f,6738dd69,4bad4cf5,b34d5e9b,ad6500af,11e4575e,91795068,eaba5c4e,2ea0b21c,a9100b6,66823a4d,a91c4d57,3aa9d136,76f820be,9d1cf209) +,S(c5e23bbd,c5049419,3483e083,14249157,aa56d9f,804374b5,54c9879,52b7e392,4caeb8cb,f684217f,bfdcd02e,3aa4ae3f,8d59e766,855b4fe2,f7f8ac7a,6e597751) +,S(b5717631,f3aaab92,5543edb0,3d21c604,17178e98,dea38bd8,10867cf8,8c92d2a3,e74209cc,324a9ef,8b31874,524dbab4,d2bdf0ac,8f1d20e9,a02409f2,8c11942a) +,S(9c456099,49601f2f,caca85d5,d30a07e1,b2d17b7c,7b838cca,2fe4b5e9,5d305cfc,2d7a1540,a109dc7c,2841b61b,31e50078,329273c3,585c8674,674ee06e,ff04eeb6) +,S(52ae2946,c0ab36c4,a8aff175,73b6604b,e33dae5d,73228d54,98c77a51,8aa82f63,70e23d9b,66061bfa,4d03f899,b65493f2,7179f5c8,643104d,24dd771c,777f87b4) +,S(149ec3bf,55ff462d,dc1ba490,384081e9,89db9ac2,c29efdce,f4f59f0a,394adf9,59c1d88,b91db942,2ae8fbc7,ce6951c8,49642b5c,df949801,341a8bc1,789dd7af) +,S(aff89294,d66718dd,dff83534,61538da3,dbe14a09,c14d0576,8a163810,42ea7ea7,71866beb,cf5887a5,ece2352a,cbc256dd,7b615491,2a88cbb9,a924e764,4d59266b) +,S(de44f478,2cb30472,ad52d49b,303e2b41,33887eb7,38e2ab78,da7bb406,584e76fc,6798ad84,25bad82c,57c630d,7ac8ef21,b13d08fa,830edda7,eefd23c9,ce482bf5) +,S(e0bc7a73,76169366,c172c88b,e1ba02c6,b3a380eb,2894e134,5a2ec7c7,39682e61,bd147eb9,33b18fe8,dfe7c0ec,87b7e993,5ad1f7c2,ab5424d3,c23609cd,262cb2e0) +,S(5ee34f27,2af69f33,9473cfa7,a536a22,ed26139a,71cfbb11,27c7a476,32f0e6d,c1df8f96,dc0d4d82,f6a57de9,85cdefc5,1316bf10,dc3636cb,80762aea,c4e13b8c) +,S(4dca3bc1,77fa7a63,9b8c274d,fe157d7b,67296846,bed5d13a,68bce5e8,e599a0f2,8fd2b558,36fb9aeb,fdb3fd75,8f59c8e9,2fb48968,52eff2a1,d01c32c5,3d2fb234) +,S(554f6bc1,87560290,ef9ed937,3e993f54,98081034,a03484f5,bc184751,f8b48136,b454c3b7,dfd512a3,517834e0,e8c3f50f,de80863a,1e0fd83d,2064a6bc,a172b26a) +,S(95a81b50,a6c0879a,6a960b2e,162dc22e,955af87c,b539eba4,20b2825b,85592ad4,be55e8c4,dfed22d1,f5872b75,f38aa4c3,7c7d5086,f67011af,2651ab0c,c45c712) +,S(907b6d53,9e496a6e,358d14d3,431f5582,44a4f8a6,ea291d85,3efb8be7,477e5c4d,b3d3d694,3853bb9e,67817fad,1dd7d1d5,ff33e200,2922665c,21f872e4,77150eac) +,S(8527c81b,b342576f,67737cb2,33f17605,c8884c64,6b7a8357,5bcccc09,c7f17aa6,b6d675bc,db8d5249,57b1930c,145777f1,9cd47b9d,33386a64,5044e8f5,877604fc) +,S(8e1e3a7d,5a320d92,4ea13436,f906e9b,bc6bf83a,819b9e9f,913974e2,efab00ec,d94f03ab,d81d5f25,c323dad4,ea792c50,792e07c,79281c4a,ff309e0f,f418b0b9) +,S(fc02cb93,be1f4a8d,9acbd86,bc68cb6a,dd0d8949,5cc7434d,72cfab75,519a8d76,71f7a532,729e45c5,98a6ceb0,885a256e,ffe4cd9d,967e84e9,8b73c772,7e4d4f94) +,S(cf981302,a2858b3b,b1ac44db,4f08751b,ff76357f,9b2ed6af,80a289b1,be6e7b8,237e9c12,bf23666e,70205ded,984f1fa2,f1a8a828,b88847ba,d3a1be88,8d73b528) +,S(3e6e45dc,1408e920,3ca74cbb,ac8d50cf,71718d1e,ba05228,e97dc4be,a8231d82,2e3fdb7a,2ad3a805,f61f287c,a7ef86df,961009e1,f0fde8a3,14774677,3b1ef848) +,S(bb047795,7581471,10809088,8119b0ee,3ce1b2b2,df2668b3,749b9eda,707d4657,95a72efc,5f95f3a6,af5ad697,7dbeeed2,8d6ee55b,fce29bc1,bc439168,75c67587) +,S(4e015d42,b8b02c10,4aba3103,4ce04cb5,fe356d,81291939,3f5d1b9,68dd6748,d35b20e7,dfbf6d71,d94e96ff,c9267422,746419fa,811bcd2d,d3942c00,70a870fb) +,S(609a4c57,90c8b210,9eb7391b,d68d078e,70850af2,410df867,92a37459,24a49daf,f3a6327e,bc965b3a,581cb14e,78a4390b,14431d00,d1f34e8a,e35502f,bad0e98) +,S(ccbe0736,2a955ac0,4e1b7558,a17ecf61,b9ea0761,305b4aa1,780bab03,a27fc730,f96b7c16,6c98a1d7,65ea4e3a,e0643298,d981a012,4b03fabb,71fc47f9,1c92cd3b) +,S(6ed60282,85df2302,e6b10ef9,4e11ce0,9143c569,a84388c3,e2151c69,c3ccab14,675ea3b0,687a3b78,e8fc7564,9665e62f,e91b0d1c,25852608,1d591ea5,1ad196e7) +,S(bdff05cb,a0cca14c,55b3c592,38515532,70806177,443dac7f,4c07ff69,cb49d8e0,5149ad04,86cd8ecc,274a7239,833910f,f09d7993,aaac9798,1dd106da,6e0c9a50) +,S(64ce68c,cc70325b,22be5366,579aed1c,af9f6e55,c2c7386e,ed579911,4e2bff2b,f8c89976,3c8a9a0e,ef61dddf,2213cbba,11bf1be1,eab6506b,d596aede,45cb1cae) +,S(cd42e46f,489150f3,dcaf3c06,e1e5a2f6,b40de7f5,626107ed,af01471a,18ab2bb4,d9c250dd,d2026967,b4c921f4,e253a788,17f11f89,f679e5c2,81dfda0a,1bcfada) +,S(f7c29007,e7145420,e2da7e8e,3ec4daea,5e9b121c,35c4ec43,59d55f01,89619735,66451406,4dbda93e,637735a5,6a06ddb0,5ea2933a,36cfa3dd,c2ba4a33,eba493b7) +,S(6339c1e1,d4944856,26b3d221,4715835c,377609d2,d91150f2,c5c1f679,5e93b7a8,efbe6dea,47b4e8f7,ff55a20d,8facb8c1,d10a6960,98762d95,be532fc7,3ed59b28) +,S(fccf1f13,7d22ed06,5f4bbcf1,e9f4eb86,7b1ec78,d9f40b4d,aaf58014,3489b37b,a5a77c2f,ef9facc3,881559d9,d9756b4d,6646beaf,21b3511c,64a4b550,7dbf3e10) +,S(da97ff10,6f284ec,f123b554,17bc8f5c,a13434d7,58ec3d4e,935c1600,404f62d2,65c2168b,4900330d,f2f1e3d1,cd8ab92a,4f308222,881a493c,f8b301cc,af12e168) +,S(6676a4d5,428a24ce,36957556,c1b44593,343ab6f2,21f0b9bd,dce2d898,333e4fd8,45bddca4,b9332535,f5f4d3d8,3467d793,b7afcf58,45a19593,854b1c5f,3daf7b41) +,S(791e6abe,cf461420,54a22c7c,d3deea41,53396e7a,2a619ccd,30212ade,e57859ca,e4033bfd,8c55c93,ec732990,aff43ecb,e2ec07dd,17e4ec92,68a7b0cc,fadd37a1) +,S(3a7c7bb2,d5181550,a78985aa,84b73246,c66dd947,4bd7c5ae,20717f31,af0018a1,2388eb17,e03cedc5,221f732a,9e505f8a,b6c38d25,184afd14,37b52d45,fe9d7459) +,S(249a2db1,86801c96,9cbca936,101381d7,62b74017,2b454c3b,ef720bc5,413ab999,da185c41,76aa91c1,d783cf9c,85c075e8,2f708e0b,3ec930cf,f71897b5,d1d5e7a3) +,S(b25e0d53,b4e0cc09,985f21e0,c5655e50,32c0857f,b792b136,14da6885,6b4f8590,1bd17aff,6b02e3ac,e1cfac42,fd28d837,ac5b80,42b21055,d6b84e67,5d83eda2) +,S(73605368,5e83388,a869db66,f110243e,bd1073f7,517fecd6,1359eab,b7862fcd,e9c7a02d,842c5a6,fa43407,6e12d41f,e767fae5,5a75e913,d6912536,6d5f9d56) +,S(ec2f0b56,71392e97,2f8a0c9,af259d42,2e5b52da,5e70fff9,7115c961,77f1b1d9,47f7debb,adb24e59,c8571fa,98e56d32,d49e072b,4fdec818,2049498e,908183a8) +,S(7d7a8fa8,250dd43a,91a2ad2f,320e18c1,afc25595,213778e5,cbfa6058,4be2d378,6b48ba16,89627d77,2700f11,9bc20d7,fab2b07a,413f752e,2a0e111,60fea3be) +,S(316a71ce,52b6723b,a67aaa01,e26082c6,6e59490,cff4c366,5c695ff,aa6713d7,d6f1c1a0,7820c612,12b44cf6,e5cb4ba1,84152ffd,cf82e020,e95af73,d6a1cb9e) +,S(21a2a8c3,ade89ff,c32e5fc6,ead97a22,9ace8857,11db9930,ade6e72a,9fbcca51,95fd3d04,38df517b,5712aafb,432f0e35,726fd438,a2b941e4,7c56c1cf,8882e4d0) +,S(3f181867,b3ad8170,dad46c68,f513afae,1ad2cfde,41f9535,5369ec32,728f94d5,a51a94e4,e9f20eaa,d5599189,4222ab0d,91abb8f0,38b00a91,5f09df10,a2317527) +,S(e9673139,11be39bc,f11ecb9b,690ecfb4,79b7aa6d,3158ea69,7d0092f0,89f63c1e,c100cf7,6f8783e3,8de2017c,32022a0,da9be6e8,61307546,1f98142d,4903abc2) +,S(61ea8ab0,1407ac7e,547e94b0,6f3986c6,d3096d43,2bd08cd8,61554fae,9008b122,e5c55bcc,a6f713a9,76490488,e69f1cee,150167f4,283fa792,a105ca8f,f4a4d182) +,S(ad8fae7a,17457fdd,9f481554,239a3f1,49673df7,24a3a402,cab73f93,bedab9fe,53b7dfef,7966c4bb,bb01d037,12563f79,48517220,2ed375d4,d777efef,50f03e6b) +,S(8605cedf,bf7f2e54,d3f62f27,44d9d436,cdf9974c,9190020c,586818bd,b6a829d3,5af8a55f,ca2aa1a,6209fe4d,a7708ff6,e7a33df0,50e85873,d786f54b,7d946b88) +,S(bdde544b,465b9ef4,7dcffa5a,7a794cf9,6e83253c,2f22d4c8,cbcd2d6c,ff921d87,6c536367,7ba867f5,5ede7d23,81be6ab,ec97c8d,f88a1a74,14ebd6ce,8caadcd8) +,S(31882a45,e8b088dc,93eeafca,85c28f49,62a47bd2,bad916bb,fe3e7346,32fe1cdb,b3588f0,c5f86e1e,12ab833c,12e028c9,d03557a9,e02aa1a6,fd11d693,55f176bc) +,S(17be4052,45800f9e,db510b72,603b8e63,e49fadbd,62798883,b0d04f76,a5dc1202,1504ebdc,df8855ae,28f7738,e40d277d,81667e55,a2f59cb9,c9e33a4b,8d32fc54) +,S(c633bd33,bb697d2a,6bfc4e69,707f2b28,a303eaf5,a601b08c,9c56afad,cb629537,86e3f413,2d4764db,f2c06b92,461c64f3,9f3b7f78,33139eac,2b4d59b7,ba18cef8) +,S(f39e208a,f4c710f7,190881f3,a33cd113,633434b6,3b460062,570618f5,8260bb52,90c56805,807b36f6,272e2b66,4d943c33,d0171ee3,ba5cd4e2,bfe52f92,b9e2e62c) +,S(ce984394,14f29607,a54ddfb3,72db8ac5,ee4e5414,f59f73db,89360232,f4a16c54,1a4805a1,d1057b13,c72f7835,4d40ae96,bb80542d,ba5ebd7f,627cfbae,ba24e0d7) +,S(5266e79f,81107a4f,ba571af1,885d755,94504122,a15a673f,6257f633,bb0a76bb,5e7ad1d0,9cc85f12,8773ca39,77b55c20,18d38200,fb739918,d3b0fc96,a559b457) +,S(4fb9de57,63f47aa3,bf370113,c778bc8b,67507009,5126f5c1,1ffc158f,be7056e4,2cd97636,8eec7197,aa2fa34,72fe3db2,29fe0275,8789d75e,52e87553,1486f7ef) +,S(ad168024,a99eddbd,aabec840,6158cb92,4ae7bba8,d233745b,ded57407,23cc0226,ab105015,968e4673,8ede230b,b53c4be6,9ee6386b,91ee03cb,a21f7040,f14095de) +,S(55829ae,f7cc555b,733aea9b,f1b307d,277923ba,148ba8d5,5a7c8001,73719cb8,6a7b2eeb,9c9b9585,5403b47d,6c60a7bc,382969f6,c4bafd3d,3c4f09a7,63267689) +,S(2119f233,8efa4e0e,2204bbe7,84e9de01,4e1e4c43,450d5910,960ebc38,6b78b935,9f219dc3,778544c6,7a337db9,69c513a8,52acb469,34a71957,11c36913,b8e7bb93) +,S(11fc3e1b,9491be9,d7de53ca,a2558d36,c5227498,3f5c1b32,57f0fe5b,b1295bbf,1c69c74d,ecb05933,6aa6b6c0,231105ad,91b8d188,d109ced6,2198c528,844cf6f5) +,S(34b6ce6f,ea6e5143,95091bc8,67e606ad,5e64ac18,99085821,80abea3b,dfd2a908,5b6ed904,f4bdbef3,fb9e41a1,32c7a313,28e9f325,4e180694,40339642,2bccad6d) +,S(6c225dca,b45768ab,3b1c567d,97ef745c,b326fb3d,2db6ae2e,22a40c95,3610a84c,7e85d752,2180fd8c,ebf63cfa,2d843bdb,912fe042,d00ea29c,d72fd768,402a1084) +,S(5f776e5,41dd95c2,32fcc757,14b688b,cbfd2020,e7043e3,2a707144,5a8ed7d7,3b8c5c78,fc6d8354,3a09de0b,9a64d529,c116803f,6d0d62ff,2a20b369,8b273c0e) +,S(3e26d8c5,531543ef,5e37eaa6,3244faa5,d5371e48,16fd94e9,b8bbd932,891b0e23,30a09d1b,43a4a036,ee1a53bc,6c3ebfa,a5b4c70f,6d8af4b0,c70faabe,b79bb65) +,S(c634da91,c17a3568,aaa970ac,26553e45,6be8afb,ee12c85e,8aa0dabf,f18b36af,649681ba,e1390a7b,d05d34bd,98d87ed4,16eb9f99,c606f46d,6d522019,f1a925f0) +,S(ed335d6,4d643598,c6eab4ee,fc242d7e,4e8361b3,ac8d747e,806962df,2e7e9a7e,f0e7c3f8,19c97aa7,2334b690,98f28bee,5a1552e7,f578d5e1,eb56b600,fcaa93e7) +,S(d37f8c09,411359ec,3f63dbf2,2870ffb2,d10be164,7553f28e,d72d9585,1e521581,da7cbfb9,ba3ae036,72df1be7,56d3c9be,831467d4,cbe3b51a,191e47b4,9d1f1922) +,S(ee3121d7,c7475ea5,c3aae061,1c6b420c,5b32d05,ee86f919,43c3352e,7515c360,703b2e37,97bea3b2,9b447411,dad7b12d,b809164a,ba690281,b76f245b,bc4c1686) +,S(7b42c9bc,5c2b114e,a0ef1a59,492a6132,3f5c7290,427572b5,fe98017d,1987a12b,5cf76382,e85b73d7,56fcd92a,99242725,dd57edde,30ddd9c9,dc7dcd95,260d27da) +,S(9af5ff9a,b13a53a2,93f9b6b9,a0f925d4,7c8f9b84,5f6933c3,ad074922,f8a555cd,ca93ec9e,89954734,c8aa13fa,5908c855,13a9ec19,6417042c,a336f1fa,be5d4153) +,S(5ebfa274,1a2df1b,6e1d591,f70983dc,a5b2b850,856bd7b6,59c81877,3848dacc,b0adcb9,6ac23c64,2904c15e,822991e8,46e12411,f472e0fb,5fb69fc7,a0f7ad18) +,S(93b58d08,465e5eac,8518382b,c1f6ebec,daeb486,7da65dd3,ac125e6c,fcc81e6f,54be8918,c3151784,d74646c3,6bca9c8b,8a50b8d8,63b1db8c,f4fb3ef5,1a24a4e7) +,S(a28a579b,4fb46474,ffc943ee,32b40664,5bc86899,edaa111,32c31f1d,cb6fc858,40ee91a3,d5625648,196605f,f650ab7,6e059b14,faef6396,46c9b153,9af14670) +,S(e987909,781d5560,b71f6029,750d20ad,add7cb47,f90c9078,e8de5f2a,d606ac9a,7121ac3,4c80dacf,ffea346f,5c5e1a81,c55318de,ac8cc907,10274f18,ee9819d2) +,S(291ff11d,158780d7,fc0ee62a,e395456e,5c84bca9,75e84a7d,1d2b3bf4,61e1dcef,c5c8cbe8,abb6854b,670298ce,8224a945,71e79e37,9335acee,c230366a,53ec2616) +,S(4adb1390,9e28b53e,42bd9e57,373aa131,efda7d16,b8dffd82,4bd9803e,fde315b4,66d7eb12,b827ae7c,970a796e,5c0c99b1,24eb7002,4fde63ee,fa2ecdf5,d4b1456a) +,S(55e25f4b,95240efd,e3c7e47b,2254601e,1707a8d,e40bf384,6b3a7024,da7591ff,e9f2257b,7e98606d,743000b3,72dcba0b,e4491ae3,22e82266,4b1e2b5b,78c830c2) +,S(d24e7493,e41dfc32,be7a6d8d,5463834d,388ddd01,8c213ad8,aa3005b1,fa747eca,e73a8216,a51b4b16,5e9f5bee,414d49f2,6d7feba0,982b9e93,fc4b7863,48c26cac) +,S(a510b252,6d015da1,cb7e4600,3ed61af7,caa03562,19227d9,ed8eea13,61fd8b2a,3d98c2a0,9015abba,63eb15a2,80c6c479,eaa2b2f2,a0011adc,3565d2f3,8abea726) +,S(c04d04d8,127500d5,15bac63c,ca55d76c,8404cde6,fe681f4f,6b8c2b48,87b314d1,cb3fcd77,9fb80eba,99cdb937,31bc0814,e3cd4458,df7fee1b,98c4067a,db4d9d59) +,S(ec9c7c61,146c3357,ba851e69,18ffa770,6b5dd2ff,a789245a,df70f90,eebd0649,9a09d3fa,10ca6923,c068803c,e9161923,b36b0709,b12627a4,dafd0e3d,3d186170) +,S(95df5d3f,5d504c45,f4b7e840,3805e54b,b2598511,2ca53064,baced58,a0488cc,a43dcd85,89b85305,b07d1ef3,23eb305a,35079cdb,743dcc21,c7a6ad48,4ce8ecc6) +,S(b8eece0c,3a950c52,c46bf50e,b5dff949,2fc8ec4d,6bb19651,c72d447,633a6d16,74e942a3,1b75bf83,ba6c1460,d969a2c2,4a49572c,ce3fb84b,8d0b08e1,d5583744) +,S(599ece16,d1f69c22,53deac51,75121ea0,c82b2d77,c5e2c0ba,520bf1c,72dd09a2,48a10c3,25af3d0e,dd8e2e72,5d7baf48,b2fdb672,66423859,9f73d231,a911bb14) +,S(b8ba5a06,8d9458a9,6e2fdfaa,961acd80,7fff711b,bba4e3bc,35a5fcdf,e82ab32,8035ab22,7554582e,9038845,44d32a53,c2d82417,6e2ac7e3,2d44cecc,50f8ca4d) +,S(b6846be1,cccd7865,e56d3d7a,f1b1fff3,ae806380,a1710c50,8c35ed17,227e65f4,bbdb7025,32945f0a,de989f52,68230763,361ee9d4,9c0e6241,77fe6fb6,cbc7201) +,S(a1ffa65e,69872bbe,ed009e53,f846d9a1,20dd31b3,a11932ff,c3580ff8,da9d0fe,aa32e580,d5763bf9,dd054999,68b6ba6f,31c210cb,26846ada,dc0045b1,ceda215b) +,S(9b38176d,67091c7d,f448c707,80cef08a,2ad73cd6,de65eebe,b62f9a21,730d0fa2,22d26b19,c0fb9b7e,f1ec86ba,b8ff5996,64a45988,190499d2,6fb604ed,4e609207) +,S(bc2ccc9e,209dc64f,bb132553,bdab43fa,accfa4d,7deac898,1fa52841,35fd0cd2,47366adc,176ff88b,674931b,a8791fbd,350d1d13,71891343,74d58305,a55ccfa6) +,S(1ce000a1,65452a62,5d036f51,4fbd2a30,d4518734,e7f93aa6,7a7dcd7,24730f6a,e09103fb,5b90f0ed,54b34baf,3e3d5bf3,fa288acd,b6b0ec19,ee3062af,35c6811d) +,S(846c569a,887d64c0,e8fb26a4,49c62447,4cc63d68,4da0909d,63dcdd0a,dde0031f,547753,132c9f98,d7facf93,d4ff0416,7dcbe44,77987be4,7df408c6,fa12c07e) +,S(6365a8f7,28656e23,c9c58518,5686b18b,701f7b1f,54c84b82,f5c81ea5,74fe59e9,8c7cddfd,a992e53c,ad151d46,c9cc0b3d,be27f2b5,7ffcc23f,c8d9cfa7,eb16c2eb) +,S(ed425f3c,89ae3d8d,97972619,55e8fd17,71dc5bf5,98c5237f,bd267f80,7d2939fc,4226abdc,14f7a03b,cd7285fd,19cf14f6,10c98d0,6e3c1d74,daffd602,99a3590b) +,S(cda5246c,2e1b7ebe,8d667f23,5ae310be,85a0bd7a,2e903d56,62a6dca3,971f00c7,791ef296,f8ea9b34,918534ba,318a4fea,96b2c2f3,21e6d3f6,eae8248b,29247f56) +,S(b42a84e6,ce79c1e1,bedd3f7e,596a11c2,f5017d98,386fbbc6,f906a5a3,f4eaf99e,2e722cc9,60bb3718,36ffad5e,47509fcb,cc3d0601,70b02610,823fa40e,d407e6ac) +,S(358be08c,e1e2e9bc,b43149df,58700875,be23cad0,ba8524c1,6d46a01f,ab0bcf90,f3c4fef0,70baaccc,f64fe0bf,b6f5111b,462318a6,36489b00,34f05c44,1f9d1308) +,S(3ed6435d,e5b36230,a4f74bfe,14571041,427d16f7,9b433ac9,85c9e135,6016a789,1c72e85e,142743d2,b5be677e,352d3dff,ee0dc56d,5aa56d91,4b92762,6041f26f) +,S(249f7e2c,580dda16,5940d7e2,672176f4,afb7e50,b9250610,c253d9e6,2416c910,6fc16311,49e9916e,8f70f842,3dcde36e,1630f508,79e96e48,6dc7147b,3aa9f50c) +,S(97b3b144,e8381ba3,1b0f6f0b,752cbf91,14d2d76f,6f418d4c,69f0de6e,c89cc85f,67c9bd30,33b720b5,a1449257,f1de85a,f7282260,9e411dc2,1820444d,c988724f) +,S(3b38459e,868b2912,51d0fcaf,41245087,80610d0e,395e9b68,cfaeef1a,5f395a85,be5180dd,bfde7454,c78cc9a2,b77245eb,91ec4c25,9b17e3a3,c3e8e49d,5225ce6f) +,S(4e6f1790,9f33e08a,914974f4,48270fd0,74fb35d1,49a017ef,c54fe21c,96163ebf,fb6578f,6f47156,5b6d3491,3a9a5e4c,dcd2880,d774e6a3,e56cd078,e6b9fd15) +,S(9141ac63,e408937d,7425a0a6,70a2565e,72e301b7,75619a92,18db32da,315c75de,d35e290a,56bec3e1,3cc55e72,12aa57db,f10b34df,bd7847a0,5de91c4f,546d6045) +,S(ec9b73ca,72052751,565c006a,4fc9200,337c9162,88eddaa2,e212c611,395ba578,37e11ef5,c1a22e77,38d5f3ab,4c74e2f1,ba192275,4c4e7905,1b15010f,3c224887) +,S(56fc14e1,bb1a928f,ce0430b1,feaac6e5,aef50208,be530d7e,f0f5b81a,ce1caca3,4e5a6084,f8680d07,9f3101d7,a80f452b,b05e597c,c38d9865,f6d7f307,90209001) +,S(aecd741b,2cebd4cc,82b7c362,70f1b22c,cf3997c3,f180e1e4,d803a89a,657df731,5f104b33,6c0df49f,1936356e,8dd09b3a,256bd317,afffd4d,8ccc57e7,f90b8e21) +,S(516267af,54f83d52,24a22b9a,4309e9eb,9b5c1072,31c3ff0d,418f8bd4,15836cb8,4187389b,9e062c17,f4ef6fd5,4b6b8439,cc37e85d,8a3db13d,86592098,7befe4fc) +,S(68bbeabd,8d3f4473,f91a0368,7383b4ff,6e7658dc,6e1287e7,f258f543,2466fed5,cf63c80f,ac99b42,7a67f7cc,d978d5b0,8656fc7a,6a383c27,48635ad,97049c4) +,S(20ce22ab,69467e9b,51d59213,8b52c1e4,49ba908f,909658a2,b90dbeb5,b07b67be,562da07d,9f4173f6,9232d17e,49ba2c17,31649ff1,4a9dcc3e,68f20dd2,de97ce2d) +,S(b5b7d6d3,a4a59f92,3afc1ec6,a5215786,9c86cd90,7ff80b07,d04160ac,6e798f78,d05e32c9,775125ee,dbc55af,4d1597b4,45b5eaba,5bbf6dbc,b8ef3e79,fe9d4de5) +,S(955bd489,7a4280b1,5de3d848,f75f6dba,3967e593,6b077d4a,cdc4c30a,33f45df4,4bbeb7cb,5d79991c,ef3b9fe5,bf25dc01,6448261b,44b156b2,749f9734,3d453a02) +,S(9f60e951,98e7370e,b3c02fe1,8bf53735,50fee849,9c876211,201e47f8,660a5a98,6395aaa9,33ed5866,a02570f5,9321d89b,c865a7ea,62e28a6a,3a62c4fa,4cd613cc) +,S(7081f0b6,f5923d0d,be4041c7,589a7100,9c2b6459,a255468,999f2d4e,50d776ee,9cb60005,e067019e,93aec9c9,1bf28b4a,27f3f0a3,288c4758,403a9ff7,668f9fc9) +,S(e290180,d8d5a7c,1b0e982a,bd63ef9a,b607d605,87e663ff,fb0ab73b,3369561f,462776fe,77289a4a,250ccc7b,80b54e51,993f741a,14299f78,61b88d17,d4d924f7) +,S(8aea7328,b285bd5e,b63d5939,c5c8c6b4,ac254cdf,c42cb521,2f4c5643,58598bfb,b682da77,4fc55ff,eb4a559a,8ca0580a,13819aee,990d9e22,8e0192f8,9568ec2) +,S(e9d108b2,54b24b57,ea4fc287,45865c09,27302d7a,1dfe90fe,b3a17906,2f256e68,fff7274,6d29d9fb,e7b0fc0b,1af14365,8d0ba69a,a45a72c4,8f67b939,aba128d0) +,S(9ea1f93d,1f317e61,786d4909,429e4cc8,b81f2914,17d28913,6d886b86,adba0fee,231dff25,d3b0b351,6e63ba6a,afdee115,975a5c00,b95936e4,5d9c6be4,6980ec0a) +,S(e8a12415,e5fabbee,7cd687c,43e8d530,80701d01,85980c5,7181b68d,481e7a0d,dd69839c,e263e746,99462f18,58745727,ac53bf2,2e0385dd,5d6a21b9,922f62c6) +,S(e287f3ba,ae486145,a1c2e04c,7f6d5c1a,ed796840,27636cef,b4446ff3,6c3def2,9395413d,401db0ea,4ec53bae,ff215580,5bcfbe8e,7e6bd6e0,be5b9fbf,9d968c63) +,S(8f99f79c,ec205ab0,e79756eb,a14c8e7d,fb23e232,6ab77927,641960dd,56ad1194,805953e6,15cc6d6e,2f61b0da,389b24bc,89cbff4f,c9f0ade8,c5dfff99,e819a2ea) +,S(9c87ab6a,8cb723ad,e0cdfb59,e5a1ff6d,3adb63d4,7af33e14,c6b3c343,c766f586,74798122,7a3bd79e,7d5012cb,bc81cff7,6a3699e3,75874200,4edc6e8a,a965bb19) +,S(c52c8608,6f245de4,baa10b7,fb512ff4,6042bd50,7d88bc3e,c75ec75d,d99dc00a,e8c2813a,bae8b8bd,9c8762d8,37d42fe7,85e5406c,5fb5cc2,ca05ae03,4ab3f844) +,S(b6286e1,94d5be25,9a79c6b6,ebd634ac,dd7c3fd,66ab0de,d8d4e160,ba8dafb2,72ec2ea8,ee0bf270,777cdf7b,47991524,27eaaf24,2a0334aa,18b3855a,899b5910) +,S(df7b56f2,45f2f8b,7213792e,370ca89a,45c648a0,5f3ba4ce,8c5d6d34,2f086b6d,386ced48,3850bdcf,4209fc90,d039b96d,39ac18cd,5d97ecb4,3df23ae6,1596ab4a) +,S(2acf4c9f,4cd42357,3e9110ed,a64aab59,459b2b37,675e420f,48ecd068,6d46a3b0,5f1a5829,aea5e981,cddff9bb,d2521ffa,58b37baf,9544c0cf,f622857d,5a2cc579) +,S(bfaf95aa,eb55d378,7210033d,b352372e,6a64f2ac,a420b877,586b684d,9cd33f36,7d22bb13,bb61e76e,2a2fce3e,bbf9ec83,78c6ed2e,5f143b0f,60803cda,b0a3d8ee) +,S(78cdd360,4eaba890,da793c9e,f589cca5,faacb6a9,14a29f6a,6add7d8d,74f31421,ed7e9c15,5b801d1,16b0d60e,fb5e2287,76430c8e,faff4bfd,327a38dc,ea19a634) +,S(f2ebcfa9,50a391f,c7b97713,566a8a49,edb8944c,7cb68276,d9843c22,8d213d2e,b1c7630d,956f9f13,c53a180c,569d534f,9513d16,4f3dd900,bb3f5e78,b0fa4eaa) +,S(43cd60d,83bfcbb3,cc19943,34552eae,857593aa,e8158adf,ca850b9d,1aaf4c2b,ff64bab1,f721e6b,9e23d659,224998cd,996230c,4fccd302,47e9e110,607e8f62) +,S(41925ce0,c01a49dd,7be0c3a3,b27f13b7,2168dfb,a5ec1315,f9209709,f38ea93c,5346b95e,cb6a0ac0,1a2f49c1,9b02d9a9,a725a676,f144ac26,c48f0d8b,94f77110) +,S(fd231210,6c762d82,a851bb47,8d0ee0d8,fa1c232,7e26feee,3e6ece5b,323877e5,39763316,f5a6ece8,baf748d6,234eedc1,4bf33462,1db3e66e,7eb2fab4,f96fa162) +,S(fe3e8a98,cb7abe1f,36a54a0a,a3d1c9f,d5ad684b,d05cb2,6ea683d8,f4556ef7,7d220677,34d80663,a1ff05f9,bad5a648,837b4475,abe0746c,3fa940e0,4f1223bf) +,S(e602a764,ae0d1bdc,4c3f9b1d,271717db,38232e94,84181ab6,9ba8eb73,4f5ec5dd,ad1038aa,26268b10,2c1f951,6b77b482,8bc9bef5,7b483450,d513e6f4,cc916fdb) +,S(871895cf,adb772d9,719cd962,5dd391b,3218142d,364764e,eb0bc6ff,8d81e086,49a09064,f7916421,9d51ef56,53861350,dda2c9ca,4e6269cb,555c8996,3f37722e) +,S(e229d56e,77755805,c814ec27,8fbcc56e,8ed4ec4f,4c14907f,4ab3a0e0,fa7e4b4,cdb07ebd,66d68055,bed7a46b,63ceaea8,6d42659a,ae6ebce5,795ab908,14e48af2) +,S(5535f85,6b0cc868,88ca3118,9d20d68f,471066af,a70addd6,ca4a9537,68bbf8ed,8655c844,245e2a67,8427822f,ac3206a1,f6f52953,4f7a6c29,6ab4825b,770ac5e8) +,S(10657905,4b37ce9a,e240d78e,3d1066c,b8c48d21,fb7130c,dd35ee5,24767ad6,52836b7a,508a6190,28eb013,c0355f70,4393a5af,e133abe2,e8b81dd4,83e125f5) +,S(3366b207,2521d023,99e9e311,e3447778,e796db0c,87428e4b,e6cb0ff3,a0868c1c,ec6022a4,22a8dd2c,a7f2f15d,39998394,ac908c64,74a34ae3,255a28d,4311638c) +,S(4a789396,339be46c,73608a1f,59fdb41e,91bd0164,66417332,f2630316,b5953ca,d45b657f,615aad45,809c0af8,4eb8618d,6e6e0346,ae1ba101,3a123ef9,e5b4c442) +,S(ee4f2484,fa0a9c7f,dc0c64ad,4df60628,d75d70b5,7ab9f0fc,ae9947e3,89f1302e,52b77894,d8ecdfae,df7dbd0d,8dab74a3,4092073f,47a543cb,f81ebf42,9f80170) +,S(4095b5c,163f226f,7937fbb8,3035f6a3,9aa9b760,c5086c0e,af9959fe,25f30a1f,1ce180ac,65554d4e,e9b14595,5c059f64,6a15d032,930465aa,d5547c58,5dff7ab) +,S(6a225d3b,67d9d42,412ecd9f,d018bfbb,7a36a59c,d2f53494,3d6cc62f,b0436a24,29b3d63d,9352e0cc,aa23c91e,e300592f,cc698abc,c73c48da,6a384f99,ea7c2701) +,S(23efaa41,e5f9bbbf,c6953a89,e3f4b9e2,17249254,94f2057c,f46d0c8d,71d36e93,cc89a7b1,7f2671a2,5bd7075,5c269219,88cea3a1,1315b86e,f218e493,7cdb789d) +,S(e30c1e97,f7f99957,58d591bd,6a398ae2,f972176b,f637c66a,258ad081,4f3ae55f,1a70cb6c,3e66e925,fc1edb4d,4d29bd89,3e8e4755,6825adf3,11e64b01,866509e1) +,S(be64d782,acd416d5,2b612f53,4601876b,f05aac91,13c8d265,b57ca32b,df08e278,7a41844a,43e837c9,293b81c8,73cb504f,bff8f15f,5a21e61f,9466acd5,87ad7e4a) +,S(caac02be,e009a61c,672b4c2,82fdf2f0,73ada0b8,d4a45450,76d24c38,f23822ac,7d93e4bb,a040f4e2,23acc304,75c455e5,72a9a64f,c66108ea,500ca62f,9216d06f) +,S(da2539b0,3a9cea94,9209321e,e1719b3,c1ef94c3,86d0e860,fc0ec1e7,684ccb3,e85e1387,bef1cea2,f67f601f,8067e9a4,b1b1306f,6a33df15,7795cbf0,ce3cf9f5) +,S(bf2ee552,5c965248,64bc1bd8,ad9cfba6,4ce4fe7b,be9b4198,700e936,799cc0ed,889dea1d,b1298a24,a11529bc,30339023,5df42398,e760304f,6343030f,6058f18e) +,S(b3e4b141,cb0c3662,9fe4c9ff,7a42c635,1130602a,720a6264,30b967c1,47abde36,f66f7118,c38a828d,8c4ff83e,5d6affeb,eff979bb,2e419f56,a7d7c8aa,52865657) +,S(451eb24f,fad7211a,11181826,5a223649,24a25593,63c33e01,4967ba58,889475a0,889ff940,49f6c3b7,9a5bd321,1c1f33e3,4cb2f8c5,bfb141a2,1fe5419e,44565bb6) +,S(29ab658a,6a754778,2127a0b0,c4b8af33,ea4c77bf,4bc0fc53,b5d65d07,38f5984c,aab1bda9,c77d6c3b,a619f9a,d72da6be,947b8baa,b80b16d2,15ee01a2,2bf0f2c1) +,S(9b59c407,d815c224,5bbb9c0,d1da59fa,9d9e79a,c654f8ac,2879b341,297b24db,a4ef058e,e6300114,c2827811,abacc0a9,17bb35b6,9b1b76c,c761ab8d,a676d190) +,S(87d27b65,82aeb975,8b9b970e,76c3ac77,78e69a7a,52ac620f,c0564e74,a66c9fd0,3ff3b3cc,dec29337,41c83e08,7f07f41c,4d03d5c,93268b1a,cd9098e1,37511e03) +,S(fbb3684d,38958163,bd85a0ab,36bcb93b,7fe7d383,b70d8bf4,d9bba6f6,989701dc,7b07cdc6,c9c5b3bd,10dc2af7,b2606d09,759e7342,68a5d4c0,301be264,87b94504) +,S(82022ae4,ccc42b9d,223cc1ad,c66e58a5,a3ef1494,f95274ea,cc7cf79f,4314a453,c2424250,9ddf2da1,6f0481a,9b4db450,3a81805e,9a8eaa3b,b5cd0e49,15d2b695) +,S(ba5cd45b,3b51cb37,bbe475fa,e91f8975,ab4e657c,57d0801a,1dbec958,be20f901,2e0d4fc0,f8b4f58e,3407eddd,298e5324,7f9eb718,b58e4164,78e3a01e,cf41b0a5) +,S(1293c841,b316d1be,76ab4444,53e72e22,cfadaf3a,df5b6d27,7cd065d8,8a6703fc,98f58f37,40fb4988,b844ab52,3420709c,2488f144,88049749,28670aad,5133c2fa) +,S(ec9fb3c8,54bf1bda,dbb972de,a8ae36c7,987d77e4,8d8437c2,c69aa988,df5015c6,d5f35bfd,ea59e974,961d6b36,4832560c,fe425d54,bfceccb2,a00411cc,a5486d3f) +,S(2ecce03f,4cd55b69,6cbd4466,2e7d58f6,9950eaec,6adaed62,7694dcb7,2544d244,e14f30a9,7f1cf747,ead403ca,e07cc4cc,d1bc793f,de79082f,f6615e6,43f68879) +,S(ed8faf7f,a63ee520,7825e7fa,56f6ef8a,4c6ad5af,ac507c3d,77c025cf,566fb3b2,df120b8,ab21273c,a5af1040,7fa3e54d,cb0636c4,8ebf88f2,c9b046d8,83684a9d) +,S(47cb8f7b,8780dabe,c1eb456a,f30fd917,bf3fd9f,3c28e3a5,bc078c5f,14c32e4f,f8607a02,1f16aa6c,68afc948,f21ee2de,c5889d19,8978e9af,66931bd2,b4aa3203) +,S(76365ac1,fdebab2f,3b9a3ee3,8afe70ea,d4962047,1e38e5ca,cf215a24,3d762009,2cacaf72,8b4bb600,ff37d3a6,97d45fa6,5d778334,dcddc32,11fc51b5,4e53aa28) +,S(c9dd5de0,99b8e552,e1375055,63edc83,9f09311e,11868ea8,a233309e,cc27b424,4bd4d238,4e615eb7,c68f134a,eafe7d2b,38163a8b,b117f9e4,b382236b,b8f8c1a5) +,S(22b6a7ad,cc406ebc,7c1c2f96,bdbcb6f8,9a1e08b7,822e2a31,83e5932d,ad0a8961,52b86095,bab24f4f,d2ebe9a9,534af2d6,87b553e2,77536d5e,22c1eddf,ae0ac794) +,S(3ee808a7,49fa7df0,c37017fe,cab7f6be,96f06c04,b2de4d24,a331a9b6,9f81a158,3e954cef,5f1f9ecd,887dc174,64cffe5,6c4b1356,d841ed0c,1e23c1c,2439cb4a) +,S(2938bc58,8a7a4896,de69ae4,4d5b6240,aa97d302,7043048f,3e49c222,b8fa4803,f26bbe61,9fad1d90,de74826c,ba6ea02a,9ea59a1c,59cb4818,65b054d0,39ada03e) +,S(682558ec,da97c9de,4cbea34f,5df43274,94962e5c,df72b0b1,2c3977d7,e1a15451,c4c2e765,22c7013f,19253c4c,c8ec6cc6,8b543f33,5aeb620f,112824af,b9fedc6c) +,S(720d8c68,fc520da5,79f6811d,e1f3d045,cbfad09,f7f7d8c,8ba68b4,6493620,b867e8a8,4f7a6d06,4d6fd4b,8bbb31a9,7ac26c3,b485fa29,50d545e2,644c9cb5) +,S(967fb3e7,1bdf658d,356153ec,6c0463a9,994d5d2f,b3aca9e0,2a17f5eb,f4b84831,b84a65f8,861724b3,2f5d0926,ec9a84d7,e3cddfc9,c7887a09,4cf602eb,547cc83f) +,S(1d9fd25c,77ecc3de,8e5fc113,1ef13b9a,73f6ebd4,f8673d88,db2a418e,8bcedc85,54a06301,d9720fb4,bfbff58e,23fa4233,33012c9,d62bf0e4,aa6adc4e,ae8035d7) +,S(80138158,a1137af3,114dff5f,f346e339,7d04029f,9050d44a,b4cea89,f1311c0a,16f49876,e6d6ac18,c25cc712,da3afe70,bc5e9489,7c55dc36,bdd234aa,6a5a6b31) +,S(aab4021,77fa5844,e3a0906b,3107df22,33aa3418,222a8c55,c6c37933,c3ef632f,9b83208f,3ad0dced,382d5876,7a089711,9a062039,9a7fbd2f,7034e5e0,3201b092) +,S(8f3fd14c,7670f464,d9ef1e3b,3014be60,3c523237,14bbcfe1,d3612f13,fa72f10,84cb7094,7901b81f,bbfa593a,5c8606e6,862ef6f5,d71c30a4,b546c08b,4205c68e) +,S(3ba9c91c,aba3c06f,eaf4578a,33979ec8,df69a903,30cb8d88,e49953ed,4a1f4933,7048a74c,3eb66231,e8410799,591bbef,fdcff65b,b492072f,582ee47b,7a6f99cc) +,S(2f8c37d2,89dab0e0,d5152468,29f6cb61,7344c21c,29860645,5f29a9ca,dcf36a7c,37f0b64e,9d02710e,bfaf145e,69c79965,4223d093,7a834201,d2f74d40,eb508396) +,S(45e6eba2,c9209d27,b87f6050,a656fca,73fc6128,cedbd2d3,ec40ca,76dce846,a3e28d44,ba1882bb,d1c91a63,5ee22582,81386757,4e66ad90,8a062c93,bf5f16ec) +,S(a5ecd3d3,80a0cd23,4467143f,fe842d9d,82ea7d9b,98ad23cc,605fb8b1,fd767ee9,22f12823,8ea84269,3fb31fe5,b5015cf2,c9ab6c33,d167b95,9bea6e29,4f11353f) +,S(f7f45a71,c4663b0d,44369821,318374e8,51eb66a9,ff6034a2,c943ff90,174be83,3a1633cd,4ec197f5,40d3d6e3,e6a3281d,7fbdf46c,f52fa149,8acc0a43,5b46fce5) +,S(92582286,6b314e17,5af03b7d,e5717d42,52bf6c82,a55ec832,a94b274b,487cb59c,fc8e9584,736809dc,65234670,495bbc7,d6c2f52c,ddfac4a0,369f0527,4a811f68) +,S(c15fe8d3,2303d00a,2f57fa96,6ae6fa75,1d7849f1,4dd527b5,a7f76cc1,e556da4,36242bd0,4685dff1,a67c445c,50cd348b,e017c06a,e2e9cd06,7b5fb109,81c10951) +,S(49ef826,152aa60e,310372df,270bf0d4,4dd7136,7d72be5c,a464f60c,c62b5355,7cad4ba2,dc4480b,9a1c572c,77a93e16,4e369d2e,b565e165,d9c7d2cb,20c4c645) +,S(c8de09e7,538ff94f,e12c876e,163133e3,629b2f1d,ed6686a3,be4ae122,9c91a18f,b5a7f31f,e58088a1,5f1e872,d6096562,9cecb10f,1a76fe88,5eab6247,697c2635) +,S(d86b9fa4,616f43af,1d7a6cd3,d9af24a9,6b3d5119,ef764576,9461ffeb,96abb344,2388ce8e,8f931b49,9481b660,669cb8e8,56df6f72,e392e539,fb570e19,f003bcab) +,S(a2cd7618,f351e2b1,3fa7b719,30fe3041,87c4969e,4f3ec55a,7433ae6f,cbbf88,3e0b5c62,436a363b,1455711a,b310c362,29870cd3,a096324a,a8dd36b8,5d19d685) +,S(b7283cd4,e33e4a3d,7836e4f6,b39b5576,ad6c213b,ed2fab87,ab442ccf,2100b2ca,918006fb,111c2307,1821e7e3,25eab3f,9083367,4248fc,2733173e,8eabc9ea) +,S(b1fd2d2e,9707ba8d,355b123b,9ca31365,d12e1854,6efccd9a,cda40f6,48b9a769,8c37cc16,8e8f55de,f604d222,62818bfe,1a40cf3d,62dae94b,58c9ef4b,475e674e) +,S(1b0997e7,4242e85e,cb4be32,885b5a6e,cf6077c7,395d262e,7c0d2b82,cb39f90f,55b4d8d4,27cd1d8a,ed8c2d2e,f3bcf8ce,f30fae12,4c14b183,fa36923b,6b7760b3) +,S(56ffbbbc,94ac925,dea36258,8ee1bbb3,4f1dc9b8,1bfd7e69,8e055065,d98d78d6,aa73208f,46d72bdb,20af3d23,5bf1c5ba,a517fcb7,b8036208,9f8a7198,d8edc65f) +,S(c125fab0,7ddb7f9c,3426cd36,812611e8,e3908191,67228685,3533e0d9,3ad7045e,2806703f,622f654a,f6c3f118,92c1dd8f,1f235ef4,4df464b6,8ccd30f1,9b77e5ae) +,S(e7ede9db,e4e0c742,8b1fa6fe,e81e80ae,dbab85fb,f259d301,48a51423,fe7f4a17,93ab277a,9fbc5cfa,c80d32e6,5e7f50d2,e236925b,c2dba1d9,e635a56c,d33fc066) +,S(74701763,f1bd6bcc,470c3da9,d853f967,a47c1628,c48b1cc8,aa395159,a3df93f3,ab2c011c,7c5510f3,37393dd5,f05547ba,bd22237b,28ed69d8,a4b6ed55,5d8ac8ee) +,S(8d27f97,55baf71f,e6dffb8d,83784e32,a65541c,5c656576,89c900d5,e79081b8,a7176e68,f3c89601,4ae1f837,bd52227f,f308f90c,b7f31386,e5586125,1ac250ad) +,S(63e06afe,9040b531,eac0a0ff,1ac25db8,71b0db01,8e9828c1,f5798ce,accc7ea9,aaa11884,a9dbe08b,6b28fcf9,9049aed5,c911244,b2a6a13e,9300c007,f4910aa5) +,S(dc7ea1ae,27d60ab3,42d617d0,23e4b1ab,6bf8bac2,882084b5,dde95894,744ed50f,93c7d76e,2b95c5ff,bbfe97fc,754a5a3,b63efba6,e111540e,48a0291c,142f3dfa) +,S(f3aeef6d,f69cef4a,3d7dfb69,1b5aea99,36e40239,bb976253,2213bd1b,f6e842d7,57d37dda,339c7002,f87bde03,1cb1e8ae,72e5628e,f493c115,1fbd0f46,2208de5d) +,S(825bd84c,316e64ea,dc5d081,23d7272e,ae87dafb,28f69b67,816a1aca,76bec3ce,61e3a7fd,ba8370a8,6a3e3f69,d62f87f0,849a2564,97658f1d,c28ca11b,40a52251) +,S(310a2cd7,4dec5370,9d2988cd,8e9426a1,edb63b9,50ec3ba7,f5aeeb93,3856a75d,5d6d86ae,dfa5e57f,7f2b4ab3,aaec250f,e3ff1eee,3e18c228,ffa3b81f,17122c97) +,S(3471d475,62a512d0,f82355ae,f9bb6c3f,69f04db8,977ee4d8,5af582c0,1b425217,272dde70,2fe0b69e,bf86d68c,5037b425,ccd444a9,45040358,aed399eb,db9cba31) +,S(bf6d2563,bfafaf24,20a2b3df,6829aec8,aaeee4eb,ea3538d,8086807e,4c257a2f,e8077a00,7e7b496b,64f847ef,755746b8,3a2738c4,4c1e7ff1,a920ee2b,40b496d) +,S(eb33cfc4,a883f718,52fce42a,3cd876e6,d6f4d465,327223fb,bdbed425,2b9cddc4,9bd400f2,ef608bd9,904f03ad,27de86fb,eaab9137,e25de8d2,a7dada4a,1ee5453f) +,S(1317e0d0,3e5df319,fb383edf,7de95645,6b123d3d,a0d8d08f,82091d6,ecc2279f,3bf6424d,5c6f9d56,b0d22b60,706a5471,dcae4297,eacbbb25,2a9d2292,33675afd) +,S(81b09f2e,99dc43eb,eb22cf5d,c5406f30,7e00f8e4,267bb456,c99bce34,309aeb56,9d4856a4,b300eeac,42f5b1df,92e331c9,1dbc5f6f,ebf17d7c,49580180,a3361932) +,S(deea567,a32ff19,722626ba,ef4ea337,ed436d32,d23df7e,98b86644,855a62f2,5c912697,c61a17fe,8557ab3,40c1792d,4a8310ef,69e785a6,dfe66d43,9d032414) +,S(ce4ad083,5746d173,e68e02ff,a7a91b9e,96ae44b1,cee86755,ef3dc4e8,e43444e5,be86cb89,5238d4c,b553e289,1545fe84,df7cc81a,ff1c2a20,d3406f62,7f03aa7d) +,S(9a993e3d,407f1af6,e4d19a32,48a0715f,2e36384c,7d8184f6,fbbce7ff,530b077e,e4a1a52d,80a267ee,99a7bd6f,e6d96ffa,3f87001d,c543f4e2,481eebc1,301a7a7e) +,S(1f10df2d,7c7f05c8,1717ae6a,1267aa63,9247c7ef,45aafccc,6b36112,fb9bd0d8,670b265b,71e2db79,32683b0e,c967e9af,e45ad643,27cc29af,fdc783b0,58760410) +,S(70ceb257,29c9208e,7db17633,dca775de,d57d1dff,9d914a5a,bad5711,86621b53,6e016e91,b3f3455f,cde11c0e,c6d1d75a,ee9825,7e9d64a,ce7c1ec3,49df0c62) +,S(ba46e5e6,4dc882fb,dfb7921,a106060,43fb6c4,ace9f2fd,46693f7e,74694e3e,eaeb4eb9,79381ff,8a208e06,9d8c436,5868d0b3,dea049cb,f342c88,7d789acc) +,S(bba3badf,d233ad20,e4179bea,f3d7579e,a631d154,e048f7a9,e320d388,3c30d81,f2a7c70d,69dd44c7,317a0af4,e765693e,2bdfce6,8c8a51e8,ed3f9003,5e1b961d) +,S(6df6a769,d300ba68,17e58f1b,f41e0af2,57d491f,38e59283,d93750a6,36d3f8a5,63a083b3,aa51c772,eced1f31,ccdfb4d9,ebf0f492,99f12819,dad9a36d,a73a4a6f) +,S(affd131a,4b8c9a98,294c7ea8,793a5173,4fab1953,1d2fe236,1ada5c14,a7174f2c,4c3de4d9,ec4a3698,3feed322,58a9788f,3426891c,b3205708,73429671,3411be6d) +,S(2da31049,9e54b18a,19dba546,4c7c708d,d42ccac6,bc2196ee,2f0a2453,3b0abc7e,f354ac91,20ad9f8b,56d09d44,51c4d052,426981a3,f7b47e7c,bb0549f,232db974) +,S(3882ec53,cbe3f82a,e8d381ac,edb4c31f,23cdd201,eec93f2b,2dc7d0cf,92e57b61,1d34315d,e5a7bfcc,492b0046,b2740646,71a43d53,2fb0bc78,6cd80ca2,ef7e6e3a) +,S(fcab8635,6a08ab26,39bc8e4e,8e9eb5e3,46825975,2a65cb28,d559bb48,7387f9f1,af4080c0,d08f07ce,57566753,ad3570ae,bef2b38d,4ef7f54,d7b2054,c8fceb94) +,S(fd34b8bb,8a897e12,a29dcd5a,57540caa,847bf011,a1548ebe,5dd89d75,9d36bb58,51a66aac,6a56f973,57927eaa,723106e4,d19b603b,d0d5a55b,76235197,7910b2f3) +,S(1e89bd20,c0d85bf0,76c7a167,87c7d817,1d3b4660,99dd82fa,808d98e5,87d4b469,4f53a9d0,e5768760,3dedae47,574f3123,dcf11590,fbc4d353,eafc8629,3cfe882a) +,S(8a1ea7ba,66909ace,c8d7d93e,aefbaba9,ddca459e,548c448f,5fb3a957,7baa05ed,d58059e9,64f37a4,39f7655b,25018031,ea1f1fcf,8ae94f99,e09c04cf,8b7be091) +,S(e0c3780d,80d59926,96886549,af2961b0,e4451f0c,b5572cb,d7ff76d6,1d1331a1,99d9d2e6,a13c3b1f,c2fe6f1e,5230e7b3,d827ddae,bbeda551,1144f68e,4945491d) +,S(964354e6,ed23ac12,16fed36c,5daade18,8e7e1bdc,ff20e60e,f7cc8c0e,83996035,f748a09a,8563c6e8,72253198,4e6f0622,7e6a408d,3c633529,aa8bd326,3428998a) +,S(9809e729,5125c862,fc6eab86,969861c7,8bd09415,585414a1,ab1dbc3c,1afe3f9b,d8536228,bbf55568,833909f8,6fc84a58,ab0fc089,432fc05e,fd46bf63,987b9fd7) +,S(195f4d02,305e4c42,28d83bf9,4025fc7d,1d8d7173,da14bb34,abbecc4c,f01ed17,957db8b4,97aeb9cd,68152e0,23cb4467,ce13845d,3a88e21a,726b8766,7c9d637f) +,S(562eaaba,3eb17e34,efa3f726,d02490ea,b0203fe6,81b836c0,f2c44a1a,854e0b37,b4e658ed,9e664804,2d3a35a7,70ef4253,97093ba4,d7b32da5,9db56a6f,8552b1e8) +,S(84a2c5eb,1efa9014,80c57969,3302f34f,de3a602c,a4b1a28,8d79f28e,dec8282,700d51c7,88cfeed8,587261db,adcac440,c703313f,5f0da023,bdf62b36,46207cf1) +,S(83d12fcf,dbd9168,b14e7340,6c6d4b84,b93e2bad,77d4c7fb,8ba00973,3672f913,e4856e26,bf2532cf,bafc78b3,682ce9cd,3c0dd6fd,861218ee,523b5131,e7279a7b) +,S(9988a6f2,bbd9320e,fbe73bf,9f4643f8,ce64d522,9ed4b701,dfb0068e,dd5451cf,bbb352fc,bd3b2650,d0a44e4d,892f89a4,d2f431c,2abe9910,ed5a1dd1,8a882d5b) +,S(3e92183d,cfa615c7,33721d1e,2a2116b1,83017d4c,2aa70b51,60f80a10,afff0724,c7888251,f4bcbe62,f0dfe545,3a73f3d2,76a2f30a,74e57d7f,22680b39,142dc945) +,S(d9175300,fa1efe3a,4cb130fa,fb36275d,e5f85b98,5ea5844d,e7763d6c,8239492f,59138c65,e9592a0c,d9a36220,d165abfc,fbad38d8,85eeb521,c5566702,9b678b4b) +,S(6ff5825f,7c12bee6,5d17f7b4,7766e677,ed74c5b8,7a95d068,b4741129,36d933dc,661ae9de,cb7974b,2304be0a,4d2b8d80,2ea9aca8,40cd0381,31f80248,378c0edf) +,S(ed6cbeb1,a8761064,3067d580,ac024f7b,9560366b,bae875ab,15ceb116,50b1c31d,9140687e,d1e889c1,6564d60f,702e8101,1269c476,f19d7f45,19a7d66a,8617dede) +,S(5f8ccceb,32d75aa3,1096b56e,eb132230,853bf6e,38643ca4,43abe04a,8bd69164,35f72a3d,d0c81dcd,4b6ac0fa,c4f5834a,4f6576f0,21cd2d45,6bde5b7e,7995da3a) +,S(81e02085,9bb23977,522896c6,7ed66751,86580d62,f015af7c,479a6e23,982d0b7b,8791fa9e,4159f26f,b42ddc08,85d562b2,fce84a38,e2af9960,1ebdbc64,cffbb669) +,S(de226b16,dd1e5c26,9b7aba7a,d63badc8,3eb435e8,7aca85f1,41d42712,95d8f721,62e1e399,fa2ce72c,3f87dc03,de33d913,3428416a,434dd20d,84156470,1ac8423a) +,S(60a46f42,3fcd3295,fd058be5,9f7ff164,fa762995,27cbd2b1,d13a0bdd,97d140f3,9571d2de,7b789e17,e46bc31e,1a03cab5,912cb854,ccbfec8e,f4d370e,df7f1219) +,S(6fef445c,e1b4bd91,fbd3a77a,ba0c6364,80d7e759,3f42a7f5,ce089fcb,c32249c0,115fbcfb,af46db83,9ae0cae2,e581796f,f82e73d8,7d4c9a91,9a92c5e9,f4fa347d) +,S(6d37f51c,a8d2f953,a3e5f7c2,6edebe57,a9892b5c,14482a30,9145c4fe,4293522f,78e511f3,6718ad4b,de6897c,d3b90e08,cbefae5b,a884bdda,a967eee,9d5309af) +,S(c0ac827,5bd0701f,5c9cb035,eddbe996,738aa155,fe74acea,a76b0351,3d46098,e7f32a2a,188fa708,6a968490,60ce26a4,31d76231,6a65a6b7,c3e83201,f8e3cd97) +,S(9000dba8,6f895023,1fc507df,85faf4a5,822a648d,4b256b93,5d012060,50cde108,9b7ae836,94b2e9e8,bbd8383c,2f4cb03c,32331902,2f58cff1,779d83cb,654ef3fd) +,S(f1109bf4,b490bc8f,36609253,26c2a2e1,ad58dea7,463e1d9a,28aae8d6,969098a1,87431a27,9fd72c10,80230514,1c8c17ec,6e3382c2,c325b022,4a800509,5d2f24c5) +,S(4de871e5,4e9cc6f0,8c4aac8b,36d61f83,929adc8d,4f6e18b0,d1dc855,6e8c0003,25d1fcf,ca98e8a6,c75d7fce,19de16bc,805f4b70,e9a3e9c7,f0187f07,70d3bba6) +,S(a23cb675,92972bbf,3a6e89ff,94e10010,8f47b467,fd8cdc80,b66013d8,62766ece,8dc70b84,ed05c23d,a1681126,77d23aaf,cbca18cd,fd7e9dc7,cae5aeb9,47cf548c) +,S(295d0cc,e96d8f8b,91ba9dd3,be703cc5,79d3c938,a5b7c32b,bb40e149,584244e5,a6d45a06,a16bd4bf,6af0fe37,6538ae5e,745e078c,12b3ac95,2653f7ee,2b03c926) +,S(7c683b91,9d5376a6,d40b13d5,1fbd1769,6cb40bcd,efd248af,9e102545,eebabbce,3da0c9d0,3608856f,5b7ed30b,8d9f1562,197d4e5a,7c23ae39,332b1ada,adfd3f73) +,S(30f7512e,d27e249a,95e0e21f,fe22ec23,8505f39e,ca9f41ec,df5e7ef8,1c0c3189,2f5fd85e,25ea3a3a,15928651,4b473197,9e4e7f7f,56e88164,fad41e42,e4875169) +,S(9377bf8c,96584f27,324a41c7,78d6314b,1c7f842f,b4910835,431f5a76,2f514961,d599cc55,e2eddb2a,e7d7fe92,aed830d0,3cfa892d,3a89cad4,335fd6d3,69f3df42) +,S(3589ffe8,67f20495,ba3530b8,5f83c54f,28a66e78,6bff4ca2,40ac1d55,6d31e9be,98822eaa,983089e1,209c22a8,9f133dc4,d75b3a67,8fdd385b,581a9274,6d224c89) +,S(39c1b1f4,b2dadc4c,e58e0f84,1fcc6415,2c79e77a,11d53f85,999db8b8,ea3f8935,e785271a,d9df3389,6436991d,eff9da83,50bb8a42,616cd31e,6289aa84,d4256721) +,S(dcf11459,d3d62c2d,99879918,8b6118e4,b103f9da,2453b72c,ad5eeded,8b25be33,dc038c1a,af3270e6,345a92fe,7c7dddc6,a190f6c8,fae7d7b3,30a3cc72,f3a1c074) +,S(614929dd,1de9b0c1,3f4d82e5,5bd8050c,a32ff05e,6eb238f0,eed635b3,6623d1d,afe8517,c9e7f17b,a1918e3b,e8180ff6,afafdc43,1acbea6a,e0eaa75e,c4d8a24b) +,S(f4a72228,cff6da94,a45da35,5ec8adbf,ef81609f,b59a8296,a7c1b0ba,9cce743c,545200fb,de095aae,9de90f1,569c6bf,2fbcd025,3cca1e50,a25a81a6,e19cdacb) +,S(63cc4273,6caa5597,46e62fbf,5371b943,57aa164c,fc8fda65,b5fe524,e2c93f7,1fa4ef5b,c5a6413a,d6ad2bd3,4b08289,e7d8224e,450f04fe,9b47c45,ace5665) +,S(ac175228,118438a6,d2cf761,f345cb04,aa7f9d89,9678c201,6b84be2b,8eab8889,dd7df8ae,29643dac,27ab01b6,8f7765f0,832f2989,99a13396,3435a982,aa4af2b1) +,S(9dbb5eb9,637c41b6,c4a5a2f,72efab5b,823e8622,f3786c03,dd678816,9e4a0e48,772d6ba,13f4d61f,42dcde34,b8519aa2,5aa0107,89c625cd,1ba38d4e,b7d924d7) +,S(717095dd,d2fcc135,1015b586,65a0d888,4e88f599,b8c32fb1,73d5731c,3ef7dddc,1de0f109,52b470bc,fb23da3f,3c7b640b,4727326d,d18e020e,581fdfb4,7e4fa5af) +,S(5ac230d3,f829b1ea,401e3964,c14d6e9d,a32c4a68,2ccdbb2a,3319a964,265872ca,fac3c3a6,27dbf66b,c5e06a16,e319ca43,423484d8,3217ae81,51bdcfae,c9c026ea) +,S(d27ecaaf,a39f415,e1457537,b2e74e1d,382496a1,51118100,8577cf76,1f8752ef,fc480b67,46cbaf31,e3d8eb6,4121b68,d5938e84,face3ae3,5dcdfa4b,71c6c037) +,S(e08777dd,f92d99b7,c4f87d53,9fada8c5,703af619,3a088d64,77f1e20b,f2ac6cda,25a4f88a,c6cb18b2,4e96ecc5,3ce10d5c,1202c4e7,edbdc070,db05a501,29ccfee9) +,S(45ae7ab7,afe9580f,bdaa6a13,8896ab97,63bbe3e6,88054776,753a1180,699ba6ed,dc1af7ed,127fe06e,4d0d440e,3d96f43e,502f797e,fefcff1,6c46e6a8,a156f322) +,S(fd28cb3b,71c50453,b3cf509a,768b4c2e,6ae26514,5801c045,327e1de4,f4d00590,b0684f95,4867cf44,aa5081f0,8174ce21,3298a22b,257f6159,c2666518,5ce5a7b6) +,S(f226f00d,ac6f49f0,a195e4e2,23b9fba7,95681660,7671dd7a,158b3260,1c1d850d,d05d5c4f,6925a38a,b4630e53,a1986fe9,d823a08a,3691550f,10f71b65,a109ef86) +,S(3cc61613,a80d8480,87ce23a7,2b3038f8,a994e1ec,8c9c740f,f0e44e90,760337a3,8474f96a,24093af6,94221f09,f95ab010,90377f1e,52a173f5,a11dbbda,cd3c3956) +,S(721ecd89,8cd99712,bd3be233,1f57d686,633e7ed5,c95e6223,e5cdace0,ce60e736,31d294d8,6fc07cae,4a09450b,fec633c6,21dc34a1,2f7668ad,532ac192,a0ffd69f) +,S(dcbaca58,1144d9b1,b2586271,5e58fa8c,d5b1062c,ffabaa2,db0fcffa,2b2eff38,9cf7621d,339f6cff,90efbdca,5e2c6174,708b53e6,1af38689,e6d3b257,21ec7d34) +,S(ed314e93,e649ec2b,ce491938,2c7a256e,b9300b99,528e7878,3421f337,15db8b92,70a81aaf,229fef2,e2922355,e1f15465,53ea0348,e3dfb18b,c837ddcb,60744a11) +,S(6bd19bcc,7a59bc8d,19a97768,95f65ae8,5f5c7eb6,429c09,85436b8c,29c036ee,51346de3,f4f65681,bdbea28f,843545c5,31803ce7,78b5732c,bc42735,4999090) +,S(99ed1e15,6ac8dfb3,604228bb,5be088bf,ebe9d640,7ad8be15,5777c6b1,d43d9acf,75b159a4,478b4cca,80ea0ac0,472436ad,69f57e9a,f447c61,e19910c3,9d2c922) +,S(3e166f8c,793addf0,84add90f,b0303970,f00c3c3,8c36171c,c7fe0877,b2452045,91659a63,b0cd2a65,ec330f6f,b9a6cc6d,9f07e382,7b94b8da,1921aa8,1d5bbd59) +,S(fc1baad9,a3a95f38,bf8d1b16,8409d09d,a1b1a432,841f656,cf8559cd,176df936,31f7a7bd,b013b89d,5045f248,982b5b4e,e0b4d791,21b6e638,84a563f1,a08af43d) +,S(80b3ad3d,4b371eca,c903c879,53386884,3bd31843,4e9c925a,5a5a819c,ff7ff340,fb1ca8bd,aac96d84,c67ed7d3,b65fac69,108ae28,7347abfd,f20e4cdb,712af178) +,S(bad065ab,2901f727,d76c6c36,48ef7aac,2a87d49,4d727422,73cc2e4,68616af2,ae9d7902,16b5eead,4d9d69a2,eaba2972,fa925a34,13f15d92,236329c7,470a37ed) +,S(d1f046d9,d700ca6,995beb99,cc8781e5,a2fb758f,7e81bca9,bce435f9,129b8fe7,274ede5d,7eb815af,34716718,84433143,3090fc0a,46575017,fca345a0,6111a4df) +,S(db535f55,e3dca80a,58dea798,d29aa0f6,99df1761,473a7ea1,751a047a,33f0a22f,e7d8015d,931a3bca,1193df83,7e7a8f10,e61b86d6,477a37cc,ed3528ad,5b53ff6b) +,S(da1dba06,a56ef0fa,f98b1a5d,b9a4f184,8635b7e5,164cdd50,82ae691c,ca42a80,86a8383c,a69531bc,ae806621,5cb4160,8807e265,b2179508,d928e312,a210c9ff) +,S(267c26b4,d980066c,7dd4f29f,f7b54277,3b176b77,9b3588ae,ff5ec28a,9aa42e7,3390c03f,f4e5eb25,5d230053,1d93daa9,d584658c,7fa30341,42ff20b5,827161d) +,S(8024af52,4e6ff955,70c7915,208491aa,5561fd29,fee5c27d,4f3483ff,c1cbea0a,c9de78d0,498f726b,8078fc0,609e76ff,df7a8a71,7345ca16,dff1d7cb,b2dd86b0) +,S(11ff6a68,c7beb420,7f0d7dd,371cf000,dc3dc195,406882d2,77953445,6208f661,b53ddc25,254781b5,1e7cac25,c1f7e3bb,916b75ba,97a7fdbd,658c1bc0,a7b4092c) +,S(562a1083,f9a68203,39a32d7a,65a9982a,b70d6596,b00751f6,aa88c27f,36e3c929,a380ec7f,908808b,950e7d25,510ad741,66ec2061,50923364,55744acb,b1e05b51) +,S(4efe70fd,327c0d69,3b6a7598,7ef64573,e097fa5,4cf077af,68d082e2,d341c413,10d47b9b,92e0b62d,d9a8befc,3ed1db10,b110a346,8cec98a,4a1abef2,c8ce3dc7) +,S(4d64bf0c,d7f128b0,bde8576c,91e01c27,354abd98,2cd3034f,f9ac09c0,23a51f20,159e741a,f57fdffa,de7bf38e,14dbc2e7,da3c524f,3d4c8d6e,b9dc32e5,e8a5e28f) +,S(9a41634a,ff3278d6,b3ef0064,ceecefa3,466de2ac,372ae43b,c48f30b3,a187bf,eefee0f,aebb77cf,8447a193,6564498a,f409e530,f4053c3c,ad27eaa0,6aeae2a) +,S(e1804fb,9a6bde08,8efec2d,2e5c6774,2c85cffc,e78254cf,4fc4ded2,9102418b,e9cab1eb,9c1664b9,c2fe81c9,b3a665ae,447e93c3,183cde7b,fa56ab34,7efcdda7) +,S(a603744,c0247b0a,f821705a,dff44d2c,717611f0,25f9fb41,1eb62f1b,64593212,820fd32b,706a7638,4335c0a2,f8713b9a,6dcdb015,a96b9d9c,e5c19bb8,ca603b61) +,S(a6f1d9b6,895b1298,34972a2f,ec96064d,a1108ab3,aae276cb,66a620a0,495f20b0,9a95dcd0,df038394,63ff5ea8,18679c3f,7f55d7ef,83a06880,29c9d543,6dc8273c) +,S(4ac51432,7822b63,e00f920a,b6e22142,f09f30f3,bd74c418,93baf126,cdac5c48,abf5d148,77e94a46,45fda161,f9455bbe,7ff037c7,720f6a6a,d7e4bc31,a0f43885) +,S(5a2cf55b,a16eeae5,8cec588e,1b339422,48af6e37,33604475,2dabbf7a,f7fb7a9b,8f27be2d,32ff72cd,4fc5aeca,5de55a21,a45f8c1f,7163dc4f,e0c00040,e69322e2) +,S(e16f23e8,ef48c1f6,4012b27,f6ffc4ea,a876053e,30cb388f,232b3d8,db011c99,195ffd52,b0afa5c0,da95bb97,7bda614e,47ffe3ea,13429799,e8c390f,b8c56000) +,S(65367cd7,ac109f71,50de4263,cdd86e92,28923a3a,ff96945a,c1bbd163,8524fb84,cf0b9ba,fbe67dd6,4d09b170,beb4fe8c,a7687c95,68086b6,8a7834a5,1747d731) +,S(10a8840b,39443b8d,7a44228b,d6dd6647,89da489c,8e954d54,a5cef366,6bd6eac2,7ff6f76e,e4aa58de,185163ac,ef7fad13,d8cc4055,c4e10a60,7987e034,c661eff2) +,S(3fefe8a6,c01b8202,6bb9d038,c577f16,7b1db5ea,91ae80e1,528b1327,5245d6a0,a96df5a9,37e6144a,454a0b54,39d68eff,a959757a,7c9fe350,ecd58c3a,3b637b5e) +,S(ef93d77c,e4162e9,6bffb908,f5d654d0,58595fd5,d6184c62,6c3ada21,c4052b61,40088b85,c18d97c7,f59a23a8,645d169d,e535261f,6cd7466b,953fbf40,f3cd0bf5) +,S(f1789f5e,b0fa903d,485edbd8,4971b7c4,9224a2cd,519bdd40,d627bd82,b0ca4872,4c845cb6,5456457e,a2f570f4,77b1f4a1,9e36a905,adaaa8d0,5830161f,a71a9da8) +,S(d0bb1788,ebc75ed0,20c0d15b,ad4e41f0,64193890,8a8704bf,ff3cc4d4,cc9b3274,3a120ca8,95a327f4,8e687796,30666649,43ac5524,44df62fd,8f7abbff,222a7641) +,S(164ac10c,f7807ae6,4d6aab31,72110d42,2f05e461,aeb9805a,3facdf7c,dce8963a,8dcf43d4,40f1dd90,bb1d6f85,849f98fc,9b6dca26,301f3209,3f9dc59b,ea549b69) +,S(f122d965,a8e40e3a,b857dcf8,92949f0c,cd3aca29,739a2e40,9876c782,941fbe5f,4d994b9d,d9e68983,78a192d0,bb670bec,71504372,d218e257,f50d0268,da447371) +,S(ac971547,75e5a92a,1aee2cdb,f5781f09,b975fc21,816e7829,662143a4,e48870a8,249fb603,795b1742,96767945,278dc97a,53fff7dc,f8bbfede,f8943c71,43c9aa71) +,S(959ec91e,dfd5fdcc,90d3da81,1e9c870e,fb0add6e,144b3fbd,d48c485d,2d330906,1e5ec128,b707c761,b61b5ebc,653585fe,29f48975,2a4724b9,aed90a22,6257ebdc) +,S(590795d8,ed7d8232,457b2d15,76de09f0,3c6abd8d,23b5e8b7,c59ba93e,1e982859,5edd2a86,1a3c8841,60e16490,a47ab42d,a09cb123,a9d803c0,6835292d,34576708) +,S(c5372b98,7439245b,eda17853,5cad1507,48fdb4b5,bf1ba555,89714dce,a3e0ba9e,f82d0b61,7159db8c,35536a5,46b69c4c,767afc43,8b64b5a0,22e899b1,60bca987) +,S(f3d959fc,ae39cbd3,ec8d2016,630f26c4,10161128,7dcbdee1,6534f96c,e35bd38a,e1e55c1f,87602783,2ffe2f97,fe460147,da586a03,ed0ad6ce,1603cf17,ac9b3562) +,S(922bc76e,be3ce378,2be3d960,489b064d,3a28043,f8a92cf8,dd5cec2e,537fad9e,b3199f57,2508efda,230b9ea7,51a95218,116fbf5b,d1032b54,352c0995,f5122109) +,S(45c7dd40,7a6d2c95,79ab1df0,8070acca,2c461d88,dbafca12,99a38734,d9f0360d,3a17855b,5f2469ed,6c3c4e04,4dd96f4a,d076eba6,a60e8e73,2644d25e,67e85ac4) +,S(6422d998,dfd4b00a,3dd89a5b,74411c14,f1af5c9e,1f090d5b,33ee2d26,b959bacb,e2358f34,491218a1,93d8cea2,276f5b3f,376f597c,703bba09,cdbf7d89,37a3bb7) +,S(8e048214,33196d15,1a4640f1,92bf6c1e,95b1a3cf,5365a6f,535cc82c,c4b0535c,d6d2d73a,1f652c55,9f282ee5,35f55aa0,20012195,8ba94e65,b638ef50,e97c34ce) +,S(5a2b3da8,b5eb2f0f,8a25a9e1,7124613e,b8a7080f,15d42c4,a1c0709f,e64a79bb,607c791d,eb54aafe,6dc95f8e,6ef9d8a5,a6435a82,6b824cd4,4227f188,bf86e6b7) +,S(143587a3,5cf614a6,750f3d91,220abf49,c5296e00,3cdde13e,1a0d2d5c,f6cd7ccf,49bc85fa,de6cc58b,49a1af49,46c340b,15f14c7c,2e83201b,6622f2df,86a653d7) +,S(f0080c42,8737c74c,c3b2c4bc,8c9d8505,ba357b7c,ff25f1a3,ac81be19,dca93193,bdd0119f,57bf674a,7d7cfe32,7027d1c,1c6a5ad9,2ca24f0b,5cf25c39,4a3951f1) +,S(877ae373,e547fef4,36cb26b6,85d7c426,3e162dae,ac0749ce,f7748d50,5d130034,1f0af495,b750341a,ed956b79,8f268ca3,e1275e15,32e5ca8e,6f9f6df0,d4dfcf5f) +,S(a418df6f,635ca18,8c96a071,469a272f,e55f0706,b73aca0,d1df2ab9,e8e619d4,2b06cdbb,5bbb24e0,fe499a6d,aa5b5918,2e755818,694b8856,525ffcd6,2f754e3) +,S(4c213d74,bb6fbad2,25edce4f,44c7b0b4,114dc209,4eb52967,1d907637,a2aedeab,741bef9f,ccc65c15,8752c7d5,48afa9cd,402fb5fb,206c5be0,e480df73,9f970b51) +,S(a37906fd,3f94e51b,1a94073a,4890011b,2cf93bc3,bb4cdbff,ecb7056,20deb13a,60a3b0b1,c14a9b1d,184d5e55,23314b70,8a8a16dd,894aa332,f01a2d67,30e6030a) +,S(2c677eed,639eaf51,64b8ae3d,26bb4652,d6d6528e,5b85225c,5e84ec4d,4de72301,df0e4c06,d3bb7cba,17f89240,cac07c24,5fe63931,3b2d278e,aca1b9ff,7ee832a) +,S(b551f814,eaf86be5,335fc3c,5b01c001,684473b0,cfac8939,5d61df4b,7d7e77b4,a979cb35,469715f8,3033f923,b4ae1e7f,8818b6e6,11a4cbb1,bd399ce3,646664b) +,S(98d5c718,5c8c04ea,f1f61ad7,40df0c71,2cd47ba8,74141984,fba82146,ddf45c39,aca52591,5c737ec2,eaf88f5,f1ecea89,9d4a8e2c,428f5bc5,b36d2ba4,a0050804) +,S(5148e2f7,260fb652,68c10485,4fbccc62,ed1e1386,ef8fbbc9,a0b23e2b,94cefc7c,65b4dd2d,35dea498,5ba4a8cc,b1a08dbb,9e9b2716,7ca96e1,29672452,a7ca2500) +,S(12c699c1,8c9d6410,b8a40ccc,bbeb4514,a08a227c,982df1da,f91e9131,8e0e753c,7d953c42,89b55724,3469a197,50516e88,4889e968,4ed28e1,20b022d8,932fcc99) +,S(4d0d3ff8,a7734011,b36ecac3,7ebb2312,134e4479,5039ac63,9dc69d48,120a8d20,edff17a0,e0984c60,3c4f1026,197f2173,960b3d29,f0b0ea57,3979605b,144ec64) +,S(ce90b70b,3e7b7a71,a91b0985,a668336f,ccb069d9,81a9fbe4,48125061,5536e42d,8cde9d56,12e0ead7,524640ca,2875606c,d3af73e6,457f1e67,2e63a478,5569000) +,S(28c79327,6bb1879d,99fbf985,1d2fa908,d197f5b1,c83be97e,360c4931,563b2d8,c8944e40,e2f3b546,5b6b10f6,ae1cfbe3,bc0f3e3e,33d91085,7c18496c,ec643868) +,S(6e2dad06,2413cf01,804c2b6b,55b707f3,864d4c80,87d30665,9a1fea53,e7442443,9da67c64,e05d6914,30a1fba7,39c0fe36,497bc028,43441f7d,c4c035df,129430e0) +,S(bef94ac8,3763946,c434d03d,fdf437f9,19f26188,923ee54f,8715b724,8c4d20fe,d2324534,e5fc1dc6,6fb83032,e95e1406,38648473,ce7e38aa,ee7ced54,31e25db) +,S(53548c57,f1b45c1d,ca166a24,c0f2653c,9b7d8664,3d45d125,918cedaf,818e433d,cc138946,f0c207f9,c01307e2,130b13a9,c36aec5c,3cad640d,b6a93804,f10c3b44) +,S(7fd4f784,7f25c901,4e8b0e09,b8b723ed,2aee71ab,fd47988f,90f6ff40,4b5867e,ffc3debc,901f12ad,96605805,a6e402db,58eec18d,375fa976,41b5d226,74a1bd9d) +,S(444a8a7e,499789b4,49c62424,cd9046ef,d4251bf6,9cb883cc,d3dc79fa,5397dd9d,4cc5f03b,3356b020,ae8c775,708d56c2,abbe8e41,bf393f82,8f7c45e4,dbb30282) +,S(ff05c877,84d8625d,20694bd0,a4201c7a,4af8c67,8e62abc1,acb0cea8,5726bd8b,7cf0e8ce,6ac26253,cfa5a0b5,cbe984ee,a55f6aa0,90bd12d9,6ec2de7,a996eeb3) +,S(80fdf7ae,6aa31b6b,ce894ea0,83fd9274,e29f4704,88f0a7c6,79b8339a,de7e4ab2,77d7317b,16962745,6344a8b4,bd4575c6,49e066bf,bde58fe,3f46e60a,3952fb75) +,S(ac38a4c8,10a307ca,d5020a74,f0d772d7,ef20227b,7eb49589,6854aead,41879214,f49c4cbb,3c675858,416f77ca,92e229ec,d75ecfab,3415d213,c7cd2cea,1f5016ac) +,S(b3736edd,f1e10262,fd562f40,8f502f19,3a90a435,de9ab6fe,a2691155,a5f75514,818cefaf,f190353c,f01cb068,2a15ae0c,eafa2de,657ee751,4e483057,ad5a78c8) +,S(66d67e12,d100c116,b57f6d5e,ac6a85ab,e698d4f5,cfb6722f,12738b33,310dc295,9cd4fa1f,3a0c9a54,d3608ea7,9bbd7ea,685faec6,32d7318f,d4e25fea,14a05dd3) +,S(b856d75f,756ae484,daaeb651,46ecdf0a,9fa10c6b,a7b9b33e,b8747135,3eb59043,5c8542b1,2f249649,4b3a177d,8df246f2,6566da1c,727284c4,b041a7db,89cb0a38) +,S(683bfd7,3202393,458142cd,661a6543,c736b15f,b8595548,afc52951,f9c47d27,90f52a40,f5dbdf26,51429f84,ac68cd96,420387a2,8d94d746,b4163411,762de166) +,S(2feaa1f0,811e1e65,13895934,533a0941,41ee1ca7,f8975896,3d00f8a9,1b2923c2,9dd80976,b884d401,5d7701c3,5e6ee1ef,690d1820,7d06e02b,7e3a10f,e8499c1a) +,S(ce652937,da9ebaf3,a9765e9b,144d20cd,847070aa,1a968097,80e07b58,2287cda4,c1c46ffb,5f152dbe,5a9db378,29e7ae84,454e1736,eb7a1b68,1b321f3,41ba572) +,S(9a695bd9,170163fb,ab3f9738,a750bdc7,556087b6,b04dc8a8,4fd5fe68,78976211,f40ba1f3,75accd85,9a42b133,294868d9,dce262d,64d6bc27,d0c9cf12,3eaeda70) +,S(e5baaf68,bd3083ec,bfabd6d0,9e4da4c3,5908b0a1,75578ec7,18cd3223,bd34ba44,ab8651f0,365cc3c1,50476d0e,da3e86a4,5feb7f46,a9afbdbc,e4defb99,ba27fb0) +,S(2c26cea2,b507fe77,d8f3530b,b7ee1fdb,dd0c4dc8,bf63d04c,e06376d8,ffe59cc7,b344e3af,54d03eb9,b0b67151,b5845297,c30a1cc2,aefc004a,5000b69c,e630d62e) +,S(7c67539f,52af2e61,88deadaf,a07e2f6,4d53339c,7fca7a3,c2a149f5,c8bbd0e4,3f9872fd,c21c9136,4ecc97e,c6642ec7,df7a2cbe,61b63038,96ee73e9,309067c9) +,S(4b5ddd2d,ec8b0bc9,3b6e1d17,e1da71c8,3345614f,74201aab,8f9adc1c,aa249574,cfada2dc,aa3eefdb,434d18b3,d2a85a6b,6e16e755,6e55fd69,5dfb36a8,aac5460b) +,S(d775c2f2,ccfc0835,86a66edb,873a84f8,f9bb6680,2eb0be59,216bc35b,88d80e4b,c8a5d9b7,988a2231,cf6aa0b5,19640a86,ff56ca57,91135ea7,65bb3a4c,fc53ddbb) +,S(71a3cf09,78810f9d,fb01d984,43dc3da4,b005b07b,36ad4dc,d3c803a9,bcd9bb4a,8aab8e21,7db0301b,9640c5b3,9617ad55,bd4a3c4d,8989df5a,1ad31040,bcaaa55) +,S(bc71a054,92b696e6,200596ae,3d778ef6,a82f7d05,825c0d3f,ddee8bb1,991f53b7,15789125,9785b8d8,b1374460,630a908,d1125536,e400fb52,b07aaf61,729a2a15) +,S(9d220919,ee62bfdc,fb81ec81,a0f60e58,e8d94a0b,c6b79f7e,6f891c64,fc847abc,8149379b,1a073c2b,8dffe886,59f4e94c,75f3a7c8,a7bfaa16,e530bc7e,6ed0c675) +,S(8369766a,d30bbd19,a330c6c9,1e3ad594,d25bff1b,4e3696e5,c6c8c33e,eff33425,a27f7682,b3f4575c,858970d9,c21f7daf,8ed5d28d,8617c8a4,e4b958b9,72e79e4a) +,S(4e277875,e4aeaab,1a8d36b5,487fb427,e91f51ad,1cd68ab4,57db2e8b,20542451,9faeff65,5bbc4b81,f96bf1d2,a152a546,d138fd0d,a8f8523e,7635020e,a26566e0) +,S(27f907b5,1b9dfff3,e68d202,72605a91,825046c1,b21336b1,8b91023,39a0d2fa,115225c3,6cb13600,fb84bf3d,dd5c49d8,105f459,ffc4068a,cbfd7b0c,52d4a15) +,S(6d9feb20,650674c4,437ff42d,41f70f16,ef0900a8,f3cd6818,64b42eed,56b1fab3,82cd97ec,d82b3c1c,2e55f857,653afa3b,5f7f7b00,39aa2444,f60574d2,fa02065) +,S(8981d2b4,3360669d,361c3b36,3284e729,ecb9cdbd,3bd17558,857f2cf7,8187bfac,1b9aeb27,d5a45d1d,8791bf73,614ecd5c,216b263,6c27645a,3e86d781,70d48498) +,S(84a67518,e47ad1fe,25540d55,77e92ce2,81691685,6d3c10ce,9c5985a7,72e1d72e,d3cb93af,85072ea2,e6c11777,dc4b73fc,16ca04e2,699ef356,dc8a5341,c5631658) +,S(d3e66756,72a6cf77,50c111e2,e65a6674,7e666cdd,b9dfb418,d50c28d1,aca8c683,7776ecaa,20e5c6c3,ab5aca5d,8233f83f,4e2e815b,dd1063f0,7359fae3,a6556dd9) +,S(ede97def,71d45688,804e76b5,ee52563e,522a7684,a68efc4a,f7b2db38,65b87bba,92e6d20f,c9c1276,60a279f9,5758a80e,85bafb8f,b77eb513,7587b692,fdae702f) +,S(3359e142,e000484e,cf7db3ae,2312e703,6ff84f84,247ac6ed,25a0b9c,eae8c871,67b039f2,3c845fa1,f38c98bf,739dbf28,d00ada09,36e4377f,87166f9d,d21cdf66) +,S(e0d0a972,c0502fd,2654a3dc,40914a55,96f675ae,cf0d958f,8fd62c7e,122b44a1,cbeb1bc,34575a7e,bbfd916e,dda11903,3ee29e2d,1b11e171,8db7bd47,576b0312) +,S(50b89367,5df77704,64031ac7,a1f5d5ed,4f332019,d8da2605,9397df84,21a4c987,c4765d81,63ec9eb,a089c3f2,56d6ff0c,45c38253,3d9ed204,cb04f335,d292f293) +,S(5dc62d8e,66775ff6,f21e84e9,9f8e8123,7f80cbbe,41ce9113,91ce432d,cd6d446a,4b456b7d,e27045a5,76e1cdab,d163fd5c,b020cabf,125f5de9,9ad6eb14,1773a9c2) +,S(8ba1778f,c7921845,d2632e18,790710c0,4e56ba7e,22efdb03,fdcd4f96,22c10971,1f31fcff,a8359658,b39d7d43,59707268,48ffebe8,8f418c53,f48c7af6,3e3e3854) +,S(a3a14614,7d1ea7bb,e6bad055,fbf9810a,999a102b,ba8b694b,e7ada06c,8db9fc7,c9827731,d4321284,23ccd6eb,3531ffcc,b3bdb87b,1a727d57,a697eac3,886ac294) +,S(9620a847,bd2034aa,c81671c4,436682c5,f6ce1af6,4d8df286,21ad1c2f,e0af78f5,e1cc6d08,a7e3dffe,cb47e32f,4156bcdd,6168a205,e8959f0d,99e1555,4d826e1c) +,S(a40d86a0,aa7d6a79,3f0b6a52,c48d8fff,95b2c57c,584996ee,bc9d98e2,796016b,ec54d4e2,d453466d,ad94c15c,b25617d8,62911b4,45f44873,96ecd950,a351ea2) +,S(71ef35a6,f60f268a,57573b97,9745986f,7e5f40e9,ba64efbd,5ed90779,b3484c80,eabffa1e,9ff3590a,c577df7f,6f5a6ad7,2f3693c,be475669,8751637b,4f8a1ba3) +,S(bbd1a408,c742a3b2,e49ffa52,c5f70958,5308abbe,f103e674,86fc76d7,a4f68de2,4941cbec,9d07e13e,1b0fbe96,c7328459,ee6e1e08,50a079a,2ac0b61b,5d246124) +,S(169ebf38,92116df5,3e09c92f,f2c89b5f,805d60ff,9584d2ab,433f1f9e,84ba9009,914f5516,e7667ee1,581b5ade,bf1de48e,c997d149,1e932a08,34503599,7c6228d) +,S(8f157abc,4c5ec7fb,eac11545,890d8e45,d71c8d9e,4c4e0c3,9777502c,f8666acc,d41576ba,1e78a9fb,9899883e,602bca3e,14dc709,8982e1bc,63518138,3ff25908) +,S(8cd338d5,694b26dc,4ebcd8,39a006da,84f71f93,94fb8100,91ed8cb5,b4ec9a8d,40318c10,dd88d9b9,c080eccf,45464ab3,3fd9d34,c2027d95,2a6ecd21,d0002578) +,S(20e47e2f,7ba5ba2a,d36171a,f4ad760f,a64748c2,94892e28,cbf0ee3e,293272f2,b96ad220,56b89821,5c052089,789e4267,162ddaf8,76c720a7,71b15254,67be00bd) +,S(582ed8a5,a0d38f9c,db6942d1,1f411dee,f9c31ec6,ffbf1579,3f3cb5e6,5f2bb880,14928c0e,4f9d9d3d,ec4a8db5,64baf4be,948ea892,34a6e352,a4cf4796,3ce8486) +,S(f4a6f59a,6e76c11d,3f7daf30,b8c046eb,b0bcab8b,6d1f5e7b,877eb1b4,601896d6,2d39c6e9,e5d84156,559a05d4,a9b148e5,ccde4641,e4bd9abe,edc8a648,b070f0c5) +,S(2a820c60,f71cf5c,76e66bf0,15623f06,fc8564b8,c763a52d,2c329af7,30957b24,b38c0703,d7429599,e6c9a1d7,250078d2,36f77f7d,b9956d37,fd92646,77ff3ca2) +,S(8c2d9c4e,9fccbf64,871d4802,6077a3a9,33634d3b,c1d7f872,6231848a,6e2799e,ad50136c,ae43bb6d,8c49c534,e80985a7,cf032d77,604c2db8,d5954858,a9351a7d) +,S(b18e9053,744b3ed,d0b991e,23927593,db00d25f,adfc4490,6eb0d19b,74061ba9,90f5ca44,c829b2c6,771edd73,998034d3,43a8aab8,442302a7,2ffea92,b33877b6) +,S(cf1d157,b03d435b,905d2f58,cc53bfa1,d124827c,f4ac4109,33078dcd,1ce835be,ee37a9a1,5547c7d6,a0f03cf2,1451cd64,3ea656df,61eeb1ab,1196d959,ca71b459) +,S(8d8b9d8a,d91a840f,b2e1ac36,a6f4bce5,92fc13d1,f22f84c1,562d63f7,e54a6007,9528be43,93ca8f2d,dae0ec3b,439abded,ee9227e1,47ce6ee1,ce61b46b,b842dba) +,S(604b5544,bbc5b0d5,716c936f,b0d9a4cb,7ae04a8e,1d5a506f,2561b463,fc87fc9d,33fe2f9c,4fb9a6e7,41c1e5fe,7d3d9edb,ee3cde6f,106a1d8a,3e319254,a16ac8eb) +,S(3e7ed414,1058ee44,6057aab7,49e14ca2,cbd16d64,7959fe53,9ec0916,fbaed8f6,fc15b241,86dec6e0,c91aa697,10a015d1,f66bd361,82f18648,1ba24568,952e79fc) +,S(d0ae7435,86c17b8a,c9524243,16cf42c1,26e46f69,4c69cf26,736d0527,7943f326,bfa02de8,b983588a,d4398865,abf6b69c,fbaca03e,8bb5f04b,1971ce1b,f74e0757) +,S(ef5c05ce,d4f343e3,7e6ce2f9,45380ade,3627bc65,9de0597f,5f851eb9,88be1441,d9267c1b,379f19e,3bd0e40b,74ae8e21,b681e7c2,ad49f635,d60c619,74103281) +,S(176b8feb,d7998ad9,7c73015c,3b09d9af,d7cf4265,c7bf38ca,8dc64864,5c8f49ae,b4bcbe4c,8267c9a3,69cda190,5676c781,7f989f5e,a014f4c5,fc821bf3,8522f1b4) +,S(88f683db,cffc14e,ebb58d69,fb6da62f,b20771dd,3542fa00,97b3a766,bd16c3dd,bbef3de,812103c5,266797ca,252b74e,cf80096,b2972219,f52ff718,1d1cb601) +,S(a65d438f,1247ec44,fd8c4121,c3d67891,8488b082,31fb8854,dd1fe238,f637abaa,5f65c84e,551e433f,dfdcf3c0,b4c771af,4bb50095,dd0fc986,d4d4a82f,9a3f36a3) +,S(bd6a7e51,c5028bb7,f7e08148,af1597c6,d5cddab9,2883d2f,f6a5a6a0,6398cc27,3f2280c4,247cdd22,e8b97979,b9a98e93,c1ed14d,a76eef66,2ddb70f6,7859d885) +,S(a672436c,2896a0dc,54b1814e,c5101451,58f7a3ac,74d36202,34411a09,909d274b,dee80293,468178d9,5baacea6,badade56,c81f3d9d,95642654,a7afcece,bfc2ec3f) +,S(ca0f55fe,d3a1d0cf,1adb0993,d7d2daa6,57891ba9,321104bc,8d9e0379,f03a24b0,dc01b8e4,63462dcd,91588baa,ebca8d8f,52016683,9671399d,b5843e6f,5a3cfa6f) +,S(610ff08d,9bff021e,544961c,cb2fe206,211843a7,ea0c74cc,b91f0b5c,4b6429a1,4be3b18a,ee965fa7,dabdaee6,8fcd3e12,d889bc36,35f160dd,9b0760be,d1d46b28) +,S(2d6f8215,a70aeccb,78cf006c,ddf8f0a2,6b695dc9,622dd622,38fcc638,a9ff42ae,3fc0964,e2a3c969,e61e4e5b,ed50f337,7a988715,246c50fd,3ff45487,95a3927b) +,S(8c0e99b4,868e39c5,b610b132,de1a09ae,99846826,a42fc4ea,70b0c630,88a1bbbb,32b8ca42,f0a240cb,2876a41d,e61b8c17,6ead992e,8785a95,c384c536,141cfe52) +,S(1528ba8f,9000ae75,e3062af7,74ef6d77,658c6d1d,65af87e4,dbac9eb0,8fc96ed7,a8dd278d,54df6bcd,1d4e6466,5753a8bd,2d39f0d5,c731a53a,5faeca64,513b5651) +,S(c1466ea5,d9256a7a,f13a040e,29515858,104394bf,ac5af7d2,fa09ef7a,6ff1d7a4,cab6fec6,fb36d879,f0684b54,6003df0,d8bab3b6,e1050a7b,c05457b2,75be5128) +,S(ce8bb093,e051089d,2a297a87,cf90c3f2,2ea946ba,87a76b56,c6f11812,d3e98cb4,a8dbba51,b90684fe,6dff556f,bd13baac,679cbcad,90b0e888,4c252e95,e03a0470) +,S(76f3a73,7c9d9e15,8d30ddd9,b092a94e,7c426763,a17a96ea,9186582e,6d6c86d,5b1ca07c,4f345e6c,778ad27e,c6ce3f05,b29c5302,7e40443,b202a022,e5d16c8a) +,S(f757dfc3,23390b21,3bb98872,5dd7d43b,2ed997fe,af7681ad,ee1572d5,a74017f,d0b4e4ea,67879726,700b63d9,88eb3957,74ec4f67,ca1a56be,461d244b,a5b83cf8) +,S(59bf6198,a2deaefd,f080ec6d,3dbe3c67,f27a5769,d91c65c,1492a87b,9ed5f5d0,bf5eb739,9011a282,3110834c,4d467855,6e02f2ed,601529b3,a2f3d70f,8410f8b2) +,S(b1d02f0a,c86d8757,48685790,918c15a,a7b0e85c,f12cc52d,53f8082e,549ba16,7925e03,99926b76,8a80878d,63f3852b,97297725,96d3d06b,85437fc2,571a19d0) +,S(cd27372f,41d8e07d,1bd2ec1,27c41842,7e5267ef,14f3a908,882e4e40,381d1905,cce36e03,661b9f33,ccf810f3,b411693a,c3329617,52098352,2acaf0c9,5dc77297) +,S(112644fc,26ca3599,3b68940f,5cbaab4f,ad2258cf,bbc81695,b01db49b,dd9d3ace,8685f790,7b5ab95f,2f7a49b3,bedf09d3,7ff1362b,3be9db90,4e74d049,15c0bf60) +,S(918df72a,99ce4a16,20e84575,935a24d9,92fb51ea,eb8498bb,3a606e2c,d97d3ce,88b339ec,9ebbff98,f1b8b0d3,c90794cd,bb6b7918,2749b065,602ccfeb,bb8a8461) +,S(9b8f18f2,65c4ffc8,9425b51,d48a770,436e6424,f34a1af2,a7dacfab,fcdcb83b,bfb95e8,6a34c1b9,2c2e8c78,fc628139,476c4af9,3f63d247,5e454a9a,d585ba55) +,S(ad02f2a,c396626a,42abe52a,1ea1d8e4,3821740a,d8b3340c,9b9c78ff,bc24ce30,fcc738e6,cf8a7872,ff827cfe,1b7bb7a7,ad8c97e5,e254db13,255c2d07,1a2885fb) +,S(359afbd,5e60dac9,8ee34f3,f5acf126,9b5c1928,8f54476c,84bfb9ad,da6d85a3,2e2aa1e7,9cd3fed6,71272155,3932ce17,44358636,a18230f6,b501579f,b3088955) +,S(5639aa3e,230f2f1c,e10c34a3,1cd6c78f,c3c15c0,2061f3ca,55e09116,68b279de,e0b6e95c,15de7f0b,3fa3bc26,3a9e83e2,e3a7d51b,462709c,8ed6c2ec,b511bef1) +,S(309cffcc,7b2f959d,85cef3d0,c25efc2b,693d3b6c,ad42ce4a,d8657652,d669ec44,3abb62f,d917b1be,79809520,5521d522,32f949a6,7999274b,cf7965b7,a950077d) +,S(51f3d5d2,dac1d7c0,5d8eab6,375c9130,534a026a,48abf3ca,ce91af6e,533b86b2,50b1e7f,4bdc48ed,9f3fbfe0,ca05bdda,34f9cf2a,ad04235a,ba998a8f,a3e99f74) +,S(8f563d18,33aa4100,4540e0c6,f501d327,4158b0f4,8b3e4e1f,a3fe25ee,29c2a244,4d4c71d8,5ea93371,57f5248d,a012898f,3d031d93,c1803589,2875928,67432193) +,S(36ca2909,d68fdab9,cbc45b39,fb096ac0,3c4853c0,ee19d108,ee7c72c8,a77177a9,64f511df,c8252960,85f3d095,31467a5e,69cbf363,30e12ed6,90516208,d24301b0) +,S(f628b8d5,1f3ffd7c,c201ca9c,2db26f0f,58dd918e,b4d70cf3,80734702,8ea306e0,bd6bce3,ea82e9b,2e8d6eb2,7f557def,b7c2d77d,e6329c1e,a2d360bb,d8adc2e8) +,S(fb7a6bf5,a82c0b,b2a6922c,9d0350d4,b44fa7d7,61002f25,86e41152,c0e67c1b,c12a1c37,f1c9c703,1f1406,efe8f3e9,8419fc33,23a1acfb,345ebc9,4a702da1) +,S(c2091919,5c3e2af2,df14080f,400c8c75,bf8ec01d,a5a5b033,75391fbc,fe78d092,b307b56f,cbebdab3,ef87b1fa,3b66c327,7aec3818,e880de6c,3826b632,f1adeb9) +,S(7627df89,3d1727fa,a06d7c4c,93774a48,73c3bef8,d19bc03e,8d1bfe28,bd3192d1,35d2676c,36f455f7,aa29a865,f0776c52,1326dacf,f6d366f4,bcf726b1,b68451e1) +,S(26666518,7c9f33a9,6d25df65,8dbfe035,a3df6f73,cb059639,ed54b296,2c62b9,bb30bbc7,d34a5e26,a51fe757,8356a876,c4e7fcae,f4a977ba,468025a4,c686630d) +,S(3bda9185,fa9802e7,7dc6a02e,8f2a6f71,ef8b125f,735837bb,c7abf3a4,c62ac683,202edf2b,c11d1784,d7875a76,a0ae3876,22b3475c,bb0ca118,9362e54c,a05b85) +,S(2f90bcde,4486b64d,81313c71,48570d22,3be1978b,7f524097,bc033d6b,983a5c4d,63864e50,2028d475,365b2e30,cca99dd,f4aa759e,cf579705,270fda71,bc384f89) +,S(8893f5d4,e9b00e6f,dc992e65,4c9fcd71,7083edc2,6c71dcb6,562bcfbc,c8becda7,1faf3055,8e631074,fbf566a1,fe0c6996,a80fa29d,6cdb8313,fe313b4,b238ab50) +,S(acfc4ae6,86be5de3,eda4fac5,4da73510,f482fc25,309ce37d,855c3495,8555abba,387f4597,d1878a6a,d37a5b99,8ec291fd,76423f7c,f9bd037c,b9071685,2ac52d87) +,S(2ac4d090,a4c5e988,2f3a892d,d28a5229,d5fe35e7,d74660d9,5422a55e,2017a469,6058f516,2aa3ec45,47a79f2d,7d8e6869,927d172b,f75a1914,a3bc2571,df086c09) +,S(137ed3f,fc13c572,e5bc235c,d13c7e62,c9b1a3ec,250c024e,9c9f584e,7ebadef6,c1e95cc,3a464f51,b43ff02,3c8758f1,319e7c2,f37acbf5,4fb8536a,8ec6fdba) +,S(28a037a,72148a3d,2c89f606,81152b94,6cfb16f7,58f0a002,cfe4d857,ef3ecfe4,b2f4b650,135cde9b,8d3788cf,5c6e7a3a,ec595124,fa903aa8,a1bb3984,fb973d10) +,S(303ecd51,8fd433fb,ce9d426e,8761a76f,78ad6d5b,5f34c0ae,3bbaddcf,1a7a9eeb,6a7fca44,3b73b19e,967a5945,a275cb1a,cbd8dc3e,89d85385,ea956339,99abb602) +,S(cf63042e,5680f71c,2641defd,9d6569ba,c69cf079,f8b3140a,50923381,51533202,39f3376d,fb17fdc5,719a2052,5e1aa428,176643a,f50dc9b6,b8ff3401,eceb4ee8) +,S(cfafbbef,b4a49fb6,96923b6f,2e56c493,34a229a8,e2dd968c,44f485aa,1b1fe4b7,dc0ed34d,4a9c17e1,ddfafbc7,1d76f71,f3950698,18faa16,b5d25c6,c69f9007) +,S(ec0e3de1,fd527ea,6a493ff7,b3c6aa40,4a7ffd76,9a08953d,785d2f31,390d363e,94bddbce,300234c1,82f3c6a,717f53cd,723129c0,ff353528,fc5c285f,8e7a35dd) +,S(f07d3cd1,914422cf,d4b9c0c3,501916bd,13e9cd84,eeb02f7f,84be2a40,4b2bcde0,cf0c96fa,cb393218,37c48de5,16d1f705,dfe91206,8ae2d810,3aa1f77b,39637320) +,S(4a4254b6,6f2e204e,a3264ac0,a00c7a63,8a6fab7d,e67643e2,8217099f,3648db10,b5510e29,be93fc35,efbef989,15f7df95,b187ab08,bacb157a,c26ab2bc,2ee5023a) +,S(56f3bcf,b38eaf1d,35e62582,9f671945,910285b0,3805c1d9,b5d813e8,e87774a8,a9b964e7,9e6b7f9a,9abf3e5c,a147f773,8a1e8270,8677e6ba,c57a7a75,d1ed9dc6) +,S(f89d8f4e,7d32efc,c2d95bf,feaa4c9d,af6b9886,51fe7561,ace561be,6b081295,ca632f11,56a33867,63a65691,17186994,75e48f51,48d770d1,449ec719,8dbacc69) +,S(5c3791a0,d3e716eb,50ae4a07,51f0e92b,2890b933,c6d9aaf9,758e5205,27c5530b,44ef13c6,2de52d11,179e30da,e913493a,c4ed861c,336ae1c3,ca1f8bab,a7b34616) +,S(2748765a,e6baa4ae,62cd7156,16ceeadb,8ab94ef0,d3a3e331,15fa0132,aba38d27,71d4d19d,de63770d,60905bbe,6c7ae92a,f36b333,a93b3359,cd4f1f2,77f69e48) +,S(964f1fa2,f8ecd778,2ce4ee1,87ee3e78,d2c41a0,45a95453,22e363be,bb27e254,c744bbca,de64a883,e9481a5f,a2cce621,5137ae00,3b9822e6,77556610,d4138a2e) +,S(8bf60775,8709c9fa,8503594f,e6c379ff,ee758a07,4f7d2754,58985e25,79b8ca3b,3e638992,b3fbdd72,ff51cfb8,fb118d0e,ccc193ee,718a7715,a5ae6188,87dd51a4) +,S(fa107123,9189239c,2bfc5a95,ddbee798,fbff70d8,ee0d5f5,a10238dd,2e06612,a60cd5e,1a4eb0a5,99133ea9,71d5ec1e,315a6be1,2d773936,c624c468,f968e7f1) +,S(5b48c6d0,9f6f97fe,c03d145e,f797cb8b,3fe2503c,a8944593,83c34e51,44975588,44d86689,352611bc,c1291762,d965f136,173d6c45,28077d83,c6410a3a,906e30a0) +,S(80e153e8,23aa7e3f,2865d1ea,1e5e88c8,5d4e854d,54bca5b1,ae8f1bca,eeb94fd0,edd3fe29,e435c11b,13a92d8,ef4f6413,c888a12c,71823f7,3ed7acba,a06b9728) +,S(16e225d9,77bf7526,c2590dd1,54c6e29b,cd25de9f,7b1fe3d,ae7ed6d0,79ccf2c4,e0702d23,b9b57554,6d2db82a,fcdc22b7,40088c52,e0fa274d,d85188ac,9710768) +,S(a3440a09,15a16c74,8221b65e,7825ebcb,bb064aa2,de3593ce,7a691efc,d9456938,ff7c7aa0,3a582a8f,5641323a,7f437a67,26fa5d3d,e7c3e26b,be970904,d4dbf40c) +,S(8154334c,d1164468,2320401,f2d59385,8d607203,93eb37c8,a030e9e,cdaa2b5f,bba4094e,5f97e4e7,b0f0676f,4a091488,17126ad8,7d573d54,150139c6,5b3d5142) +,S(c91348ca,27b5baca,3a092b25,74e09976,fe7f2361,3e1b5efa,329e6a5b,7d4d93c7,ce241d0d,e9d49a2c,5060e62d,c01bfb59,e7c37295,4095f639,9d61e73c,5976b44a) +,S(9408b5a8,79fead4c,67635e99,59ca9649,cf362940,737e6436,3ba2590d,7e6e8a88,e10b410a,26c710c1,bf2858d5,21f46094,e02155d2,84b80fdf,cbf17645,7f994fc0) +,S(b851d158,eefe48b8,79e0a159,f8582aae,f80ddf90,d9021b92,e7d3e7e5,d6bdd2ce,290ae2e1,792421,c1cc53f0,69c7d580,60facfd8,e537693f,6abdaa2,c6d85469) +,S(9d320b4d,4a7c2007,65805387,5e536093,87e7a5b8,54da05eb,1b971e6a,e53d10fc,4f6acb7b,6a1f190d,6822acd0,ae783b0c,9b44be61,ca68306e,79603f47,25d7c456) +,S(6d779810,7b29ec65,4ff86799,d13a4d89,eaa49114,d00744c2,2f30a9e8,358ac7b5,8f7993cc,105c4f09,ba060a2a,ce265cc5,77b2a334,3ba3880,4b0a3e79,db823950) +,S(bdb2d2ce,77e14fb6,9a17d62d,b8056d28,680c9607,2c82772d,73c91da9,e57f6489,9c1ef71,d43c3b19,dcf8eced,ea6f5648,8a3bc00,3c2b0c1,84c9e42e,5baa590d) +,S(49a8ccff,1ab70a94,a4db4787,f73bb058,1f7897a8,d0a1adea,741ffda3,f055b3fa,f298d277,2049ebd1,ee2414ed,6e053ad5,15b41914,fd6de43d,8bd9282a,6c6ba426) +,S(ca3f7d6e,b466b7b0,56267992,d317a02d,3b3d5652,b51040d7,7f1a173a,769d2236,a26d6225,9dcf384e,f78e6f2b,f96a42c0,90e538ad,f6f1a1b7,126dbb12,8e145c37) +,S(b672ce14,f1c427d1,b478469c,b0d08b99,902e9cad,a66bc65b,c00ea630,737176e4,176c0979,15176,27a0f1af,f3c5a56c,83f4f550,b8c4bedd,b818bf76,68865efa) +,S(bdcbab57,d4ad621b,d6db6866,f43778aa,2c26dd78,8f2e968b,da3c913a,ee9c199b,79868872,9bb213fd,7dc75a33,8d6168da,1cee9f0e,e93c7c11,24055232,88df5603) +,S(f5f25f1e,382f7df5,74c64aa9,6c5f423e,d5beed0,82d80196,1cb384b2,55fbf9f5,ea388f0b,5ad84aae,58393a82,9a50a4d0,f54bc068,e12724c,98a9dffa,f2210221) +,S(d2a10464,f9f8ab9e,1ca6e280,b2747c43,60372049,85a2650a,a730b894,16ae09c3,d19719ed,8dc46533,28d8dca,f2c902eb,2c9ffaeb,ab3c1b45,4fdcf68b,229c5962) +,S(89255afe,e6724c4b,c5522105,8e5e6aa5,19058c3f,f3ff691c,c5f81a00,20410038,8d626dd,9560c934,11b52ffb,4fbab500,c833c3b4,671713e6,9147d8af,da3fd7bd) +,S(5e468c42,c5eceeee,2a67d73f,57819019,5165e3f2,6c93f94,beb12fbd,556e3952,af83e24a,467f97e2,ab8b6a8c,330e400f,ce1fdeb4,3a4ae1ed,c3866505,8cf240de) +,S(70c2bfac,9eca198b,f606850e,8f54ab03,552caf8e,9385036d,7fc85007,e99c4e2c,60322365,f5ffae57,8a8f9939,20cf7596,3b45d940,d2c4591,544feb6c,d6ea37b3) +,S(16143d3a,fe5f6b42,500f86d,7c79630f,bbb0db1a,64e901ee,ab641c0c,b9c2f318,7078e814,bdf81d7,81109561,d4d1cd37,9fd74924,4cad1e68,ecb8b247,d76a8a94) +,S(8ac33ead,a9341644,db25b034,60ff60ab,e1326eb7,73a0bed0,29f6e966,16b62bce,6d07756,6f0d18b4,bd055d0e,d99bda50,ea9e614f,da46005d,c6d9dbfd,18945cc6) +,S(476b98b8,9e7feafd,ef5f0116,6e0c8eb6,70cb3325,a10fbce7,71ea9e06,2566e22a,38dbf041,83252b86,7e138483,c012f220,fd98bd5d,b80fbf47,30c5d0e1,d6a91050) +,S(e4d262ef,f0de9c3b,d3302bcb,321adfa1,2e383a7f,19297058,a19c453e,ed497f11,a1f830fc,2fd6120c,8f2070c4,9ea49001,953d0c0e,7c02050b,fec7cf7b,ce2781d3) +,S(67bc850f,48f0be1b,f18c4f7c,b9f33e67,e2e09279,4196d987,1bec0fcf,f0b5cbf8,e2560470,334aa4b2,4693e927,1d2f20cd,b7e6fabc,92e0f355,526dceb8,5f52d32f) +,S(50dcb2c5,c0dd4942,2564be02,2ab274e,b543a6a5,a2712b8d,58f51e12,72ef2797,2cbc036f,b69c44c9,9c7854b4,9705dccb,8d2ea16a,2f77fca8,90d89f8d,4ab04ea0) +,S(6c9bc577,784948f4,1e8a57f1,bddf5665,f860804e,89912876,44ba7b76,8758bd6e,84a671f3,5998ac84,7329ca3d,1224901b,a0401915,c9280260,cd40ff44,ebb3ff20) +,S(5dac93c6,d27cdbb9,9f3ceb36,18c6ead1,28b44146,467390e7,a337c494,8382a868,86572065,1805082e,7434578a,a97704f8,8a91c2b8,e315ed8b,ac2a4bf8,342df508) +,S(207903c6,5e1c57e1,7a6e9484,d3073c0f,f6b2a40a,b46b996f,2ed2be7c,85780c86,4b568420,29564d4f,6c4fd310,73e17a3a,bbdcb83,115a6c14,854633c1,47f6a442) +,S(da025f63,9be593e9,3ab35113,2282830f,6ffbc94c,829111dd,29546221,2edc2f90,9b4acdeb,a315e576,f0edea9a,21acf5c8,714defa6,5ef4ae68,eb694383,916d2723) +,S(327faacd,1b489c8,2126ffa6,b87cf191,2a0f61f5,ee47eea5,6030a50f,b2823cb1,634ab42,6010009b,144c5ac2,903e5f8b,14c00c67,5fe177e9,6b7f9ecf,b8c33b9b) +,S(44cffbee,1619f462,a853478b,a9d1bfd8,6c9cab17,f5bf50cc,79a24558,7b7e8084,b08983db,62079e28,7eaf8c28,81079a45,76442a1c,fe35f64,563c714d,748e7da4) +,S(c5d945ca,13730ce2,c21ad679,734d1deb,beb19785,480f93a,43a2170e,6a6fe3a,a3aad11b,4d8b7140,f67f7287,8e4a9c1f,74102ffb,ca3ef04,46e7bf1b,ae3cc3fb) +,S(f4d8cf19,84dfe935,11b2694b,8f1db0ed,d4bf22f6,435359e6,77fa42e1,cec0de31,83d02d22,3aae1880,d7ad76bf,c7e3bfde,5b48a55d,4fb0ff02,c0ba5c2,e9a30845) +,S(13d721dc,8e7b0bc8,90c6380a,fd0f0ee7,a2dce0e1,e153ae70,7e50ae7c,1837c4cd,c620c1e3,e1575411,7eb9e823,70af7e4c,9309c412,d5f14d28,e976112e,88841116) +,S(e5f9efa6,66fc6728,207eb55d,94c1daf2,5164824c,e27b1783,92862e11,6265ce1a,500a9fe6,18302bb5,22ff9fbe,163d79b6,1f0f3cf,53e0956c,7712f23d,5c0d9975) +,S(73ee3cbd,a1ba137,65a7abb9,827b1b32,a48ea0e0,a43e9698,8da603c3,c319c9ec,d96832b4,4093689c,beb30bd5,a2e825f3,bbc909d0,20e18744,b0a5ec5a,1ab38f58) +,S(11b92fc5,94046bba,813285e7,122750a4,3e028501,f027a55d,f101d2cf,c5990d91,e08b24aa,e20fcfe0,40dcfcd0,80949b2c,23b324cd,1d957b63,9fe91716,a4315417) +,S(3043669c,22be0dc5,fb14442a,22a625d,b1bf4952,362f06a0,623ca1cf,9160935b,dc4834b0,4bf47d6b,fad52c04,4d26e21b,41eeadb2,5c92ca22,6dd2c86,24d0eb34) +,S(490c39aa,c290d144,2b87622b,407dec4a,3f92aa61,6a9c8495,132b5c7d,3d5f9a0c,5c76c0fd,57844aa6,fe81361f,73cb314f,110f87de,6773e1ea,b3d68dae,2926b986) +,S(fdd5cd58,67d73347,ca1fb212,772b0c42,3a4caf94,a3e0bf2d,2bbb2433,9002d03a,efe5f407,d1d26bc7,6fb5bcc0,6bc94da5,bd69f84c,85d89172,10bce909,77411995) +,S(bc8a108e,b0830fce,443db272,2655ac40,e2d35989,cad192d8,e9c5017,14435ea9,924c0258,cbc3da74,a708a384,b93196c0,76bd3af6,2907cd60,22069b93,e3c979f9) +,S(ed809b6e,41f4b6cb,86ae431a,718989cd,2c706ea4,10152e3b,3395df8e,ae924b44,135d805c,3295589,c8d42ffe,947aa88,bede6699,b119f8a,324c9bfc,64315da8) +,S(26b50ac7,5d871e07,4147d2f1,ee42d6a8,4398212,79e9f276,7978517b,6cda52d8,26599c63,86426e9f,b14b4c8,3494f0e,1fe37ea0,521e4518,e346bad,545dd7a0) +,S(cced88de,27d0ccd4,7f6746ff,98907cf1,679f6b10,67785dd7,25ab94d4,9fe8efd5,5b0ede2b,4dc584ac,b4b6adc2,c52b4268,e2beba67,ce2bc825,fe4df43d,73f5729a) +,S(d8edf7cb,31526332,308429c1,178886ce,bf3fe516,18f472bb,52da883d,d83c6249,a56abc3e,c155eef6,d43427e1,30ba691d,8c71b80,6b487343,7f3daf07,17984be3) +,S(ed82c3c9,f8db3a75,50949aa5,cd6c8fce,52648910,53f66515,c2fb71c4,7564b4ef,5ee59949,6d9d3c7,6fa9a26d,444a8a45,41ddccc8,15fccf39,b06e8fe5,20b2f0b4) +,S(6e277bae,e89aeb54,5e6249d,56d50848,5853b3ad,8588365e,7771ae44,3d8ca937,84871bd8,1e6f94a7,c31a3fe6,63a1170c,8f9623dc,4e24a5b4,3f7d023,39f40b8e) +,S(aeb67ac8,67271210,565b1229,3e1aff94,f2f8b642,76768967,f702afb9,48a03c5c,fcd3c588,94259c03,cde7898d,66ff5ac6,747100bf,3707e89b,6980d21d,78bde197) +,S(9f07ff4b,aa20c756,94c967d1,e38633e8,45753193,a3d13af2,3ba7ce07,5283da79,ae8b7f0d,49d06168,ff3c5f36,3aca3f1c,14308cf7,d95bae36,3975fb7f,dff2136b) +,S(24046d14,a026daba,1644b3ef,7bc5501b,baafc3c9,76acfdf7,243395d5,713e1520,265485e9,6dc40a31,ba93cd0e,915534b4,37fd5380,bad0d6cd,321867cc,aa029ae6) +,S(1376926,bf8fd1c6,80344f48,c574e6b9,1806afab,7d9f90c9,13bbc233,2b3de519,a34100e7,c4b44c26,f86b2198,e7d3696d,8aed9051,a1755ced,56ebe795,d5a61fa5) +,S(943c6d4e,816cc668,87f7c85f,b116ae82,5e4c38a6,581cd5f1,1efc9a3e,ef5a7d6e,d93d4724,f618da6d,29e35165,7883ee36,74112f70,3169eb24,eca31a60,969de8dd) +,S(adf8041f,159260fd,cafc9e61,d5f4f867,a0f46e94,af60bf53,d4d0808e,885432d9,c4eaba1f,99d2516f,3d731bcb,be90b36e,c055ff5d,e6c3ed95,2b95a037,1be57958) +,S(15c17f13,a404ae08,11ddefb6,707a9fa9,dc0d9461,8325dbb8,d96537c0,6e2dcc44,8740d352,21f95e8,36842b48,2512d79d,a799fb62,60d65dc6,79df383a,e9b6898e) +,S(87bbbb35,62365994,9c5bd575,86b813dc,966ec9ed,1ac31435,80e4b7cd,cacb8ca0,159992c,1bfc3c24,95e14ccb,e24a3e9b,6a28f4e9,1cad4a36,f83624a8,d22a48c4) +,S(39bd144a,96454c1,9e082b5f,eae9c433,564da73c,d5d44daf,95b5c176,9f1fa105,ffe8a11c,30b5d4d6,f8abe12e,bc3ca8f9,dadf1527,330319bc,fa277b13,256fb207) +,S(c4e4eb4f,9bcec0c6,6bb99bfe,265b2f4c,a1c69676,ee970a9a,b78bbd64,a83bca7a,1bb9a83d,316cb9c4,bce4be2b,d05e6381,2ecb493b,44fc3cb7,c2248a0e,96bfc286) +,S(c183e783,1c80d334,f0ddd2f4,48ca035e,8b53f034,f53c1801,488e4aec,cf244e69,f998feaa,c7711d48,3db38926,8ddc080c,8ff2f95,494e60b1,59330d8b,d9a8b820) +,S(99d1d7ac,22a2e108,f093b630,f374d9d2,7ac812d9,5753bb6b,e39c2401,fed47d92,a67d334,88dfe341,e8dca3d9,b36a897b,52080a3d,c366c8b0,39cc4de3,52d0e1f0) +,S(e0700a5d,16cd89bb,df3d6f18,76909082,985a3339,e7f5d2bc,5c3ccc92,ad61cea5,26f6abe0,38953fa8,40bec97b,c9d59c20,1fd08b29,4a7ac7e3,bd994e07,70a0b0f0) +,S(b19bf6e8,cf36d839,51b813b5,67aa62ee,5415e95c,d3fa668b,55487a3e,61a7e721,630e78a5,ca2cdb2e,cd59f59e,4c10e712,46c1055b,a7709041,fc03f8b9,1970153d) +,S(25009156,e90dd0ec,88027adf,a9701474,39abaf72,1c333943,c6fe6e19,ff71fd44,324047dc,86477632,214ed74,cb933859,b7825500,2d19ddec,9c466e1f,573afc11) +,S(45ce7fe8,bbe45d1c,9bb0c98d,9d4c500a,aca5011f,96238681,771b8538,61a3e4ae,8cbc22af,d1adb8f0,a5c72570,2b6c7f65,9e41b176,1358832,7ca062e4,2392f8b1) +,S(73255507,d3a27fc6,7df39212,a286ef6,b939e953,43b12683,4e38148b,619ec059,3174d6e6,e941020d,db0f3ded,aed6c8cc,eeba10ed,1344ce28,a354e93f,25c35b63) +,S(96b2cef4,1c6c39e,1ec9a945,8c8bad3f,6025962d,a1207885,97800ac1,c811df58,ed85ed21,41b4ad26,3adab5b7,c0c0035c,2fbf9e2d,983dda99,7d1249c6,8a7fa8cd) +,S(5764181c,d941b28a,a307bebb,912ae87,57f23cc9,37025cdb,b983eef6,42b9c772,e8173b4f,c23908fd,db5f6437,5457a43d,2495764c,f3ce1b8e,f2c8d2be,e0ac7089) +,S(38ec7839,7e965056,2b1e314,5d5b2782,ea16d2a3,82bb6c60,efd29edc,93ec1b61,acf04ea4,c7b6de2c,d8acaa3b,a4bf2656,f522e631,1cd51089,744d4c96,318ec96e) +,S(6ec4ef80,13d01c79,758439fa,108f7389,79c9f7dd,4b285eb8,b7aed579,76c0b572,2328e642,e618ecdf,3a6560e,3eb6af15,7a6d266a,f5f3c4df,13c1ba2f,c898be7e) +,S(d8da1f6b,30c27b1a,5000fc14,9a768683,4c40a581,c4ed67ba,88492449,ef77141b,ccb532d6,876d92cf,2b8c310,839387d7,d92464e1,727287dc,49a3b348,2d519758) +,S(84f25402,734970ec,966aa9f0,eca84a1e,6894d36c,338722b4,e5fed162,8f7ccb90,f2d7fd09,f07e6302,cc97d283,d9f06319,9bee137,d3946944,983c2192,335cd8b1) +,S(ef6752b5,58874372,859190e3,91d86ff7,3adabfd4,cf008038,136b2ddc,ce9503e3,23d9ca50,13cb479,7cbaa675,98dcf98e,73f949e4,614390f9,1e6159f8,3f131c56) +,S(f88d8590,3b3fe67c,f641cb52,c77c776c,fe198f74,fe116a46,602bc2c0,1085ba6d,58af2abd,2178ad68,a3695714,cddf14e4,21da61a2,8e6cfa32,40507fb7,ba08742d) +,S(93b739bd,d366b95c,675daaa8,c5ded7d2,18cde6d5,d15d354,645de017,2db9c01c,24ec535,6c2f8eaa,633af5b9,6ae0fcad,7afea5f1,c7c8bfb4,748b886e,25cf3627) +,S(732cf404,da7ae5a2,dbf82f80,180c1154,6d313b92,58980f95,d413f223,443394,858e8326,1758b90a,902eae58,a777b56,e8820084,153c9e43,1b7d789a,4d596953) +,S(efde0719,2c40002d,3f82e024,a1b838b7,65fc252b,5be4af75,28ea5994,a9d36e32,89c1d35c,3a153576,91a63585,183a9c6f,b8dd69b5,69d45483,f0c2f80d,3dd9107b) +,S(9eedaaf2,80693392,76420c1c,da950bda,f114e65b,9b1a74a6,b42dd90c,1ec90a15,1399dc24,7fa540cd,3249728d,a4d28c52,26f427e1,ac3b533,7de8ba07,d3164de2) +,S(23f0ea8d,342aa214,69deaafe,bfdb487f,775805c7,d4ba17dd,877d3d42,19433195,dc1c6e31,d2a481c5,5d32ca8d,1d4e93c1,63444dc3,9e7c306e,4fcbfd46,b699b03) +,S(d85270,58c29e60,58916e82,76a305d2,edd47c0d,4e33052c,74cb76e,abe060b8,9a0e4904,e4db5bb9,5ec9e510,59ea4993,84d497b6,8a9a1258,3a2fda6e,bd0cfac8) +,S(1b34c95c,ccf91204,5922d2d1,90cf3860,f7d36b37,7ab3763a,d4d9046b,309f28b8,70c2320c,3f5f663a,b6478c3d,2607cb4d,f7080de8,91bb408f,6f14a11e,2951e948) +,S(32558fdc,ae5e596b,b756d4e2,f10707a,89569d36,1498e8c2,8fca1473,4b84b228,7759a8b7,5ed5755b,b23978c4,3d5aacd9,fe63f6e0,74b6fcfb,501906f9,16038d86) +,S(64818b77,37d2bc57,391a3820,2040afbd,6028d7ec,fa3d6bf8,577cb1e8,dd984acd,4202b934,6ae9554d,9227b891,4a6304bd,2cf895ec,a7267e1f,5707489,71ca2300) +,S(c6af6ac6,ec2d7cb5,42aa2373,24288551,bcd33705,72e1b1aa,e572d87d,8d77b333,fffe5559,4ae5a2df,18e393bc,dd0407ed,5d5af18b,85f22352,9fcc7cda,dec78cbf) +,S(91f8fc44,94ea12f8,fa2a031,7f32fd44,2e7a9e34,28eeaf13,a8b0de3e,a4f1cef0,6a0a47a,d81b1dd0,ac6765f4,20cc26af,e76c2225,eaea2a42,481ff6d9,a554dbcf) +,S(e159a9fa,6a26f57c,879b081f,dc015b46,dc610a61,2335d6c8,e353fc42,11c1c017,c209c643,445ae009,a75656f9,b4c1df2c,f1c181c7,ca81d0b6,bd749afa,a93e8851) +,S(e8e9fc5e,135f3a97,1211eda9,c06d283f,1a705169,b89e5813,556beba5,a4f9330b,e8b96899,3b73e8f6,da7b55fa,6f1e44b5,c88423b9,f3fc5553,fe0b10d4,e9af0abb) +,S(f3f5d529,d5ae4c0c,36c27ec6,e13384b4,11aa9818,aeefb5b1,64243536,bc0edead,3f740643,1e40c133,345abbc4,ffc5e0aa,1dd1e306,43e52ae5,33f5be61,db3d34b9) +,S(c5b76430,f5d8bb9a,e1b9acff,e1417602,9eae65c,9ca1606a,2e4f6d7,6cc81159,80689f09,70089098,24087591,6915380a,29b13933,9a000fad,d2e86d8,cf2429c1) +,S(954aa4b4,34f59074,45ed30c9,ffb6db50,ff275564,72894261,e935109c,cfc09b0,8023ca86,1bad2c25,6cd76be8,b3b0fcf3,a808b76e,80a70ec5,83265d3d,c72e4ad) +,S(55da8bb,4803f339,3020c9b9,30a58336,1b96ee54,4bbb4249,d6df1335,6e3d528b,dcc44b88,ca06e9f5,86cbb209,da01785c,2387b14d,355a2575,799ef7ce,32e5b64c) +,S(8084e800,d810b286,b0ad48d3,d262b4e1,db59eabc,a176e368,77a7f8bb,a3a1de03,d8beea9c,59f865fc,9f09c12,9bc5f980,70d60ac,eb348f85,e0888fc4,63dc1480) +,S(1b2bb6c2,36c87f88,748f49a1,5094949b,d15e0217,b00c0bd7,f85efa41,5718b39b,2164b195,6aadf36e,f1bdd018,6bea9a4,c3c3f42c,b0e81dc,8101ad14,51029c74) +,S(fba687e8,125c372,e5dc65ce,3d2febed,de9139d9,9f91ad84,830da38a,54377872,8944eadf,3b89501,ca4a7a82,105a9613,55aabbf2,57f4bf83,923ec12,73e001c9) +,S(b58e4b80,a5f1c16f,f9c699c9,75a2d797,d21e155e,f091ba94,8aae2dfe,fd560cbd,fff9caba,1429bfa6,e571b7f4,12d6aa97,4606f7d,9025efec,937a5128,52cec3ec) +,S(8ebcd526,da5d6c21,55222551,e05c6be4,114fdb7c,9d43a900,fcef17ce,3426edec,73a0fb98,6b3301b6,3eaaafb1,a52f5467,de11f034,aeedc21e,ae97df86,513aa97e) +,S(fba4540b,924b29e8,95dc68f0,e971549b,7354e032,64040d2d,bb956691,1bee325e,529088c3,3b9857ae,342ba0d0,7e52843a,290f3c27,16f5321b,6c9e6f51,9105ebd4) +,S(8b7a2c97,a1a7d324,6d86301a,66f3f36e,ce014c97,651b25b0,ab46f4e8,bf9c44de,b82854ab,699c35b3,6786c1f4,71ea7536,7c88a684,43fc17b9,4cb328fd,a4b247c7) +,S(9df11743,5adb7154,e7003bbb,a1ba909b,93179677,4bd4896f,40c39a58,ead2279c,a7922f4e,a216cc36,c36913d6,e7ab8641,d4566865,dd7a2f83,77ef219b,41b884eb) +,S(5beb7b84,749b444c,82efd9e7,37314892,c54b6215,c1f9be9e,414adae4,56931cd8,99e425f,32cd0a7c,28e753fb,ff308eff,d32b7cfc,eb51df7b,64f60e9b,2fabb95c) +,S(2a830c43,ff204ba,78c5114f,4a3b7b09,c9f8ed5d,17066f43,cd512af6,4c788879,12523a4,e8882652,eba827fe,d207eb00,9ba14809,9ee42865,61e96230,62666c84) +,S(f71a46a1,4c1f2a18,e68ab408,bcd32d94,985a7714,19c1419,1b69221e,1c57486a,adf19b3e,ea79a53,4fcce36a,4cc0da0f,4fac443f,b281cf0a,ef675b6d,20534875) +,S(2b80e5dc,aa9c2b31,678ae2d9,f7d63c0c,bbad2bab,36c412fd,cb6436a7,c69d193b,bc83e04d,71d60062,b681ce04,c506247b,8f3c9019,c2084ffa,27621d62,22119c3) +,S(49cbdf3b,e521c69c,68375b58,d4449341,75424a0c,3c45d5b,b975235c,e63beece,c5615eea,f0f0e7ce,c3756aba,d3a136ae,91d260f1,563997a8,ae46c49a,5c62de7f) +,S(ce4d4714,b643b115,9215e2f3,1dd070f7,f7aa663b,9ca87739,79c5ba31,ce9ee1b2,b1f35e12,a2fc3aa3,4db59ef5,e62101b0,479745b4,200c10aa,d6f8fddb,1efeac38) +,S(6827b6bb,aa905ac3,8d93bb1b,5d5881c5,a8bef479,ed7c5656,2992d4dd,61e10054,8524a87b,af65020d,91848427,95801f54,30fc3727,7ef2064d,1aff8ecf,296bb869) +,S(e71e4d5,48f4d7f1,c7b7879a,a03a49a0,ab947218,b16dd125,19af4ad1,8056535f,495d0461,7098b3d5,6f7e3bed,ab5c9813,83aeed68,3ded1c09,f0d1bb38,e32f574) +,S(ef683979,7429fb30,d436aa32,a3feda68,65652816,873ce542,6320667c,6e00e032,b4b18e4a,de1197e8,fded846,f188a6ac,2f17506,f014d404,fbba3635,534613f) +,S(c729c1,ac8f7eff,e908007d,e2eed85,dd557e36,c1ec645b,a258b03,e52deaf4,2e83edc2,18584f6a,c5ebade6,a335a087,12365b89,ac38f27,bde7ebf4,561305fe) +,S(cf1d3919,9a716d53,b2bc4f2c,3ae2ded1,290d54c2,2124a88c,c1cc7fb1,115735ab,6b44f5a5,7ec3402c,e8980970,dab8538b,c276c8ee,ad542908,9b7b70d6,dd00e6e6) +,S(6cf3d7a0,266dee28,f3f1f772,ee90da75,a9c28a7f,f82d8f55,cf9d609a,5becdeae,3bd18fb3,1e11cce2,895b9cf9,4d9a99bc,ede5c9b4,c44ede14,34dfaeb,49bc58d4) +,S(da4b5832,ae63eeca,cdee4274,f00ae932,56393cae,cf830be7,f28749c0,7d395542,9aabb23b,d2d940f1,815610c9,d1684b92,106374e3,1b694ec4,dfec8818,cdb2210b) +,S(f91ae350,23210e16,f9c63270,cea2c6bf,407d1a10,e95842d4,b8ad5f7a,4330bbfa,1f161ac,d1962573,5969290e,fd3d1af1,53c91543,33651e16,1b51086b,913aa1c2) +,S(7e1bef52,cc3e2a2e,45847c86,27328526,c72e3f73,fa1c8255,56c874b2,f2f1ac02,be4b0f7e,a706e4d3,db7048fe,e0fc4f50,8ff0523,ee8d97f4,4c4c1787,e6f6e6fe) +,S(dd2695d,30dc2ee3,748e256c,cdc92eb7,706567f1,4be720ec,b27fc814,d3d5998f,9af32c44,f1028013,9ee7cf99,845472b5,bba67740,f0f0b96e,d1a02a19,a32dc74f) +,S(78fae650,714763c8,d12602ba,33b76da,125fe395,43fb37c9,4d20b337,649dbb9d,78dc4c0f,726cce6,f65826e5,eaf1fea4,c3b92532,6624ce1,21de2351,bfce3aa6) +,S(1edf521e,510e5dd2,aa1d3e00,d016b45a,1b6fb6b8,591d98df,ee692636,8dc98bd5,9a0d016d,9b2e9b8d,d0f4d817,71ab0f20,aeafd8d3,63beca59,7518da41,55311f86) +,S(8607bb0c,5e53b60b,9153272c,d3cc69e4,7ce28694,37562b4d,4166aa18,d0101d39,15ca31e,c83c6541,c35a294a,a648af8e,38870757,27924e98,8ef566d5,96eb519a) +,S(65fd300d,9a0503f7,80a0dbb7,c42b9bb7,37f9607,912f2df7,166b65f7,96d02eab,fcd15350,84fba852,11f94540,1f6b43f2,904caf3c,d44ecaa5,335b928b,4ea3b5d9) +,S(c918b3a7,6c847ce1,c01845f0,34ccbeb3,36d031a9,33093f99,f47f1458,cc02d148,f256f403,dbbb2e20,32063270,faa6e62,596329d,ca85ceb5,3ed3adfd,7f728568) +,S(6ac2dcfd,2f0b879,becb429,140ade0d,532e54d4,dbe0bbb5,c1352ace,5661817,f2c26310,abf9396c,5af23074,e72251c3,784c3de3,60466dc,ccaaae16,4a9e2af3) +,S(8d71c4ee,54acf389,cee39b94,b5feb2b2,cf8e95a9,45f6a95f,5b0bff2f,cb3f3d19,98442bd9,5a02c1c4,7dba3881,e3306103,f0bc8857,89b44cb6,54875847,f1ce52d) +,S(e8bd24d3,fd557118,f2c0abbb,511e874,2e5d7368,a909b072,b3dee124,44f583c3,e1d2c3a6,e28622db,65b7992a,6716459e,2380285a,cd60f43a,4d4b1bf0,8bce6538) +,S(62dc2975,5cf8cf89,e52c8c51,6311e3b4,483fd024,ab2ad1d0,32d7255a,3c075217,799e132,d80d22d8,e0f01e9c,d0954251,8b3fc8a9,48f3cd1e,9391f8f,5c0e2a97) +,S(37db13aa,cf727e60,cb102709,9c7d3c07,4d43234f,66a95451,a6050496,d44c0e13,c383bbe,8f8ceff4,196e9d07,e013a1f6,d3402a6d,d09eafb0,62924334,89b1066b) +,S(37bfb765,eab7719e,c858e17c,472f1df1,be9dc439,2699ec39,37875b30,fb2aa1ab,72718bfd,865dc4c2,2f935f4a,98af8ca6,5cf44b5d,66f0eea,23b53563,d1721364) +,S(433ede12,87fcbf35,5fdba6e1,f62148a7,b5d5c3fe,1200d456,6dba452,a85d1b94,b27c5613,ad6e513b,28f0c959,13e30781,137a4c7c,7aee6e60,5715d949,4757c20e) +,S(e582d9f,c5ed0de6,92a1917f,6ab7df46,d23295d0,b8b27b32,3af9a57d,3e671861,33ee8785,e2770dbd,7e79faa5,386cb1d1,d1c9e073,1b78dfd6,5571deff,d4073154) +,S(60b07b40,634bf15a,ee2d4e5d,a0f06ade,ad8fae01,4a6a189e,4e428600,4c9442c2,fee087cd,d243ba,62b4a2cd,68d8aac5,1557f29c,a57b0f37,ff2119b1,bc4b283d) +,S(4b167276,1e5f7ca,a245e35,b6e88fba,643e6da7,ce37c9b2,10265ad3,2de03100,28aacf02,476887e0,90d26c1d,cd51f15c,cacda02b,b6314a64,73b90c93,8ed8dde7) +,S(5d56113d,6d797e74,c4803e63,89a88ae2,fab97de1,4ed4e7b2,a17d2f9b,fe2a3170,94ef2a8,534eb2ff,a62462a2,7eb2b34e,c6545992,e2d973ab,ee42b1e7,d9cd524f) +,S(a9d03fae,75111ad8,d1157287,8e8c4473,f4a06cd8,f28dfa7e,e38b3d06,3a34f828,a0733c0c,c7319879,2ca665bf,968f6bab,480c94b4,c7de262e,4d9d1f95,33517881) +,S(74199571,2b1abce9,ed4db3b7,7b3f7e70,58fd3716,1666c522,50855f25,660e1ad5,710caea8,97f7589,cfd3b8a3,22726000,ea3ef2c1,8aac385f,22b67bd9,da44db) +,S(9f16990d,bf81a5b1,eeba1e5f,84673e16,ba0106f2,acc68be7,cabab96f,25918dc8,d60d47b,62321042,34c49d39,c03806ab,135d46f1,ea6587b0,f0b6588c,50ebc4f5) +,S(3b5069bc,4f12b9a7,ad91c888,fabd15a7,c99143f4,c8b24619,b6a70c0b,2301d57d,dbb87cd1,ae59a944,9fb4ddfd,4b311d66,da18544e,a86b75a8,979828c7,fddd1a79) +,S(9dea63a9,67b5a36e,bbbf9af,bbfabb31,f90cdcd7,9b75c68,1159b946,dabaee90,b14bb99b,11bab958,e31a605c,e9180d23,5c7d2eb,94d4de57,b8a66627,c6bc4464) +,S(d0b23392,1da36a84,2565cb53,4411e63b,9fe6b2c,c33c3a18,8e0ddf48,55e31e79,80ed93ea,1a6e5492,dcaf1cfc,c350b3b2,99117276,43fb6a75,15c435e5,f74f8e9) +,S(8adc9655,966ae44b,f98ca7a4,9f441e3f,acfe85c8,f7111da5,52c817b3,90b03d20,ce72054c,6a717312,180c80ea,c9337430,5dd1d566,db1b93b4,eed1a6e5,73c0021e) +,S(f6f76bf8,cf6d3dea,700800b6,d018a4a6,141ac610,e2e13fe3,ec916726,1e0c1670,b2c478af,e1ea9876,98e5e2a1,6b3a4ee,63e4fef7,6644da54,e241c395,3f9a302c) +,S(d58287d,38b7da30,174fcaa1,873b3913,2176388d,6da5f9fe,f873d86f,14b898e5,785fc934,69ed085e,8318f91d,114ad0cf,da2b8ff5,61e545ee,3502e9ec,6afc8402) +,S(7772ca23,50c5ee55,9ffe810c,6d8702c1,538e3d11,f4b8354a,2fbf674,39a3661c,5a2312de,853fda14,5b48aefb,23e98e4f,fe3dd3a8,ae1fcd6c,931d9a43,686edddb) +,S(a2f9f976,c50f3687,7ad0ac95,efc3fb2c,46ce903e,76ade308,69705df,72433ad5,ec565311,24c289f3,35e11b22,bf8d7445,f201dd4b,68afa38a,22af056f,c8c285f3) +,S(e20d9765,85f8c567,24d0ec16,5ad27110,26fce166,b52ce11b,cb221a80,4f8b15f7,63b61933,c7f63862,98b48b6b,c6abb54b,21d08220,166ac31b,fc85d4dd,998f33fb) +,S(8868b59d,ca1de2,cbe98d94,506db1df,659ba688,b2bf093e,42dcec03,acecc18f,f02e9b07,96b98fb0,51dbfe8,4524ebf6,dea56251,afb53076,e2215d83,fcf2fd0e) +,S(1099f82f,e32a1361,a785f86b,9a6bf0e8,99c83226,7826d6a4,3f8581b8,89fb677c,13fb83f2,9aa7f271,2cf20cd3,592eac46,cd2d3e61,9afe9aac,7fcf37d8,9c44445b) +,S(4af9c696,77ece7b3,5f732969,8ca61b27,deae65ca,ee2d5d31,ef2051f4,35cbeea3,73004596,429da976,f96e3f80,a24408a4,ebfe5196,8130c698,5b210826,664e5ef0) +,S(9680cbca,5aceb8b0,322d4bbe,8713cab9,300d1f8b,d16ee045,edb3b543,57dab473,2f293940,e36ba1d2,ecd4697c,209b33e0,6904ee3c,2798aaec,e9131d9,bd0df58a) +,S(7eefcc3a,fd6347f0,5f9c3720,31480c92,3eb7fdfa,d6e9c0ee,4e2db9ae,27fae7c2,b8e9fa75,4f745c14,7c753e42,17bb1e28,7bb93d9d,aceb357e,9738f10b,fb5cac06) +,S(b823156,d63612b9,3461fbf3,6894955d,65e7805,b025c2fe,98fd46fb,2f9fddb4,f23c517a,826fe91e,45f453eb,fe9eadd4,d0b537c6,a2a8f60c,dab9dc58,10bd465a) +,S(e801d35e,2035fd54,92178706,e2e765a9,bfb9de22,e89182b4,4d5144d3,85bdadd9,1e648234,27dee6f0,818868e0,419e37a9,1c216200,3faa7478,48161809,76956a26) +,S(e9d4610e,56b70969,284369e5,7e890fc,29fd7750,8489a1c,2f348f52,cdc67f3a,8e5f6aac,357d82e1,a29bfca2,2ee4516b,1df0e622,257c2c1f,7d9a84fe,b48e4a0e) +,S(71c3ef0f,51d6ddee,340d7aa0,94680084,b94bae8a,e3528ff,4a481af6,d3b7609b,4d1674dc,2f8087a3,138adc4d,aa615a43,db6886d4,4992fca4,544f57e3,315f6b96) +,S(9567ce43,b6f5c41f,bdf8b44d,938abac5,21aadb83,c157b947,ce999c0e,4a7d6f20,c9d86317,31ea318,a647ca8,945cc35d,1fd0fdd9,b2de4fe3,5e2a0021,33a35538) +,S(34523d4f,81166739,10b3de85,11a1921,4f8fc753,fd8963e,b9db22b7,8edcc141,900fb9fe,268b88eb,9b80a066,277d8ba,877bca84,f277dce7,7d6e90c4,8422ac90) +,S(69fd1f7e,5f1c43df,a2f4350b,f20e5cf1,f2993dfc,b61cd278,1590ad79,e3c1bd98,633726cf,8b74940a,edb15665,a9277973,2d1c923,2bcdd615,43c9f3a,6c51d7f3) +,S(e4c2c424,c28cb8f7,3146dd39,bb4fc6ba,411b2a75,e317faa2,a9f878af,e94a3de7,fb8d17e8,468e5ef4,8da60739,820515cd,c861378e,9b3bd158,fcc8a949,eb21ae89) +,S(5710459a,ada916d0,9c1feb59,c494863,98e44513,226119ea,5ded7b1e,34e32773,89deedbd,d2d83a58,4e56b409,30a8355e,905bf12a,f33f49f0,7383eca4,e63871bc) +,S(d56faed4,171806e1,5ac17f91,37101b27,59a3a8a9,90b85bc1,89b217a0,6fd48e64,fa871ec3,3408b2d6,b62f513f,5368f549,ebe43977,a48878c7,6d731447,34a6652c) +,S(e7416eeb,da0b805b,68b47be8,eedf87dc,cb5cf012,804d03f7,604525db,aa599bcb,8610c716,f11c567e,313eb4c7,77e4314b,533d4f37,13b11185,bbcf5442,b9a56c19) +,S(8ca59862,ebdd3541,91c60608,13ce32c6,a4fbfca4,6e60175f,2d5f1607,d5fa997d,aaf3480f,b132feac,6adfa195,2b14d0d,113dd6ee,faad71c6,980d5691,e37698f4) +,S(6496dc45,1fd43b45,1915867a,846c5203,6eb8e4c5,28c2a181,72fba6f1,53243413,44fdc41,f85c99e,e00a281b,9292cf1b,153fe2bc,5c8b3e87,cb14d624,e44da1f2) +,S(3a424463,aa82416a,a38bc248,dcaccd20,67d20721,d4e8f5d6,c9cb2fc1,91925a5d,71a56463,fd242591,434775cb,37c81bf0,d4857abf,aa527ca9,c3178464,8afa9fb2) +,S(6a945b05,51d55194,adbf7985,aa85fe63,8811781e,6b787418,1574d109,d178c2e6,186d343a,1ca3a836,32421fc0,d267ca27,80df9af1,32625d31,924e99ff,9b57ac44) +,S(13f1f692,682d04b7,b7e7381b,8c5c13b1,32baac0e,b7f8c8aa,c9ffd77d,3aadd47f,572a05e4,9622ff88,9eb36852,85d1400f,43372533,38c47ce2,282aa4ae,26e99f0e) +,S(79fa13c1,4f0de8f1,ed98e7b3,3edb77f5,a2700707,e54ce522,a516634b,d2804330,a094bd88,e1969ee7,3f41e40e,60f7198,cf2484ab,5a2efaa0,96e891ee,d5987c65) +,S(df1ff6db,d2c61bf7,c273f735,a6dab3d,fb08377d,bb3dd101,9dda03db,e533130a,2fdc7ad,68c58689,92e5c969,d8d14a94,cd0061b7,5ab0e824,fd19611d,923f886e) +,S(a8223280,5f5939ad,180f8776,810cc7,2bff651b,df7972ec,51d86d2a,1acbdb34,9681590f,982e3632,b2aea9b4,40043751,e7f2ef2a,d4b125b5,2784ffb5,17c2dfba) +,S(406b0cc0,49f3bf58,6990ada1,63c73932,b3780fad,ba3fd8c4,79e6a688,484c7c44,aab0e4ef,f2508e54,79074fe0,218aee7e,8b217932,859192d3,1bb20817,df6503dd) +,S(4e7043fd,5783479c,3dcf103d,bc4d9bc8,523c81ea,dbac9460,4b73300c,f516bcc8,196287b7,3ed01bd1,e8033ead,66c92625,77c859b6,73a4c7fa,98f53d69,e82d1133) +,S(a9a2a671,b945a5f5,90575c0e,ff24c070,a7d55b00,e9d2f44e,43cf400f,f3e9997,6cd45e20,cb972715,167f957c,af7f2f3f,9ae22ce4,3b46d4ca,5b2a58db,6e0c6285) +,S(692a1394,75ffae88,fba47ae4,9315a6ef,12b2dec7,6807608b,22ba3ff2,883d3c01,74dd5b4a,3c14a54,c0a86732,1a77d160,c834773f,8063406,85a65c16,6ee46131) +,S(36f915fd,156638bb,88928e75,d00fcd49,63b44ac,f5d016e7,7ddaa8c8,d62cfad8,3f11eb6,16edd183,5ee17d02,722cf6de,991dc8b0,e37fce3c,cf7f5db,e842e8b9) +,S(3f0f6f5a,7e010c0b,5442fd6c,a3643144,a5202a7e,bb3ac8f,99aa38d6,4aa53b31,2574d7cf,5b33e29a,950099ac,db0ffb3f,ab1f9ed7,f13cdf9a,b869fd07,c35c649) +,S(8c58faff,71f661d,b21d4258,a92aacf3,508a9dfa,bfc00cfd,26b95673,34b7b067,38d1e894,ea1d4ee2,843d08a8,80b11325,e9a8a171,59de273f,694a14d6,73944893) +,S(d806731a,205c1a3c,64b91864,2d940b12,dbc6f580,866b7a9c,f287fb7,c5da78de,870a8430,2ff57abb,735da831,863525fb,70402006,d241eba8,d43c2ebe,cdd0e05e) +,S(7dbda37e,195db041,a4dde151,5a7cdd97,416bde09,12b9a741,3354204e,2b848648,83c89c7a,649d0070,fde84ff1,32f60a9f,e1c0261a,87a8ccf3,885fb003,10715e71) +,S(8afc23c0,c803b0e2,df78ee09,3b776cfb,410a1b52,7d4be45e,58d8cee8,3ec54a1,b041eece,4f4ae4a0,b3a52957,386394be,bf7b11a2,b97eb5b4,1bee89c,352ed76b) +,S(4e4424c2,2c50fab0,4b803b4b,2562114b,1b2531cd,e5786112,36fb9021,3652207b,22bf6181,51187118,fb421e4,fb0cf243,889d5ca5,c14b6ab5,7e7b9d0d,d9796e6f) +,S(60717788,5a230af8,a0816e39,6e39b34a,f394b1ee,c93ba382,8fd92941,e6e97453,a84df29f,2b9da41b,14f24762,df6db87,fc0a18fa,89e356f4,9f8f4017,dc4b26) +,S(c9f73d20,384e56ec,37bbbf8d,facf70e4,a271f169,2dc22ac,6022ca24,8caf3213,7622e7f4,c77f9581,b73c9bfa,8bf5b578,89070e8b,97616cb0,69ea25f8,8dfb5437) +,S(19ea5dfb,dab5a1d8,c3c2bfea,48d90f6d,a8b9959c,630bfc4a,81ea5eda,ee45282a,c21295d,14bd81,7c3a4d62,af307b1c,870a959d,7d6e4c65,3b8e1db8,fdf1d56c) +,S(564bdb1e,30b2c292,cdf0e149,1bfaf852,4780669,717de5cb,290cbe6d,c1617b58,9a8da0e8,6fc0b95f,99e84198,877f5ddf,32508c1c,ebb9984,7004f74e,7e2b1c0d) +,S(5bc93842,4f3ee6cc,926e2123,7bee0739,50b39d1d,e0dda3b5,4bf46953,7d0bf06b,d4e9c3a9,662778be,b7f4bd4,cd753a50,32bb003b,694b5e00,c119dea4,20fd5d16) +,S(19432e94,829e8b57,3eef4fc3,181c7d7f,5b2a5f2d,a2e8c3a5,980db9bc,5cb7f99e,f75c999e,5c5b8567,bb69316e,36e01acf,2e860781,5c5703f7,a4be72bb,9abcbcf6) +,S(d399281e,6196ce19,a2ec28bf,a0b1b559,8d0235d1,beef1672,ea230cda,20080b8d,1ca7e95,20ffce3a,33e94931,95eba433,d5483cf0,d5edbea9,6384d1a3,5168aa19) +,S(6c84e35a,b220fa9f,e55f5556,302f6656,39372e97,74ae26ba,e21ca8ea,10e73c88,98a11b2a,bd442c0a,d49711e7,b0e8b234,1d15465,71efe9b8,9a7b4c02,1101b2b3) +,S(7814cd8a,b1b045ed,a1797f14,c83bd807,ec4205b6,e9df4858,1180a80c,a0f8f64b,ef917e40,edc8b8ff,f53e8b70,4de63adf,6bf17730,41af2284,1b0e38d3,b515f33b) +,S(7a01ee83,1c8e22a8,bfdaccfc,cd280532,444e710d,7138b993,fb6e06c7,996235f,fe512d09,19895c2a,b62f2e08,90dc3bc,dcb06198,18160b41,4527e7c,281a5519) +,S(655ee6bc,df86c9ef,918b5660,5d4a5e79,512e856f,3f3e40ce,72e8217c,1f9bd908,cbeba5a6,91fcb085,f3996ea9,d081e69b,7dfdefba,123df5c3,cae94f63,12f87721) +,S(ebd68009,fb0372e8,eb0be25f,e78117bc,3d4d4814,440f1d9e,1cf87ee1,de5219bb,8efb7e38,6f96df55,bf0aed2d,6bdb75f3,6da8cdb6,ff65868b,d8ce79b4,ba58814b) +,S(87340818,9ac05bbb,4e95cf05,17d5abd6,8b7834cf,1168f914,9f1d63b6,19a3865b,9f1fbd27,72ce0f15,c91d4dee,dfae0a3e,7d24c0fa,de2bf30c,df63f93c,14480838) +,S(61b6b213,b02a7bb6,4de62e92,515690cb,5dda3a4d,aa96f68b,a12f2c63,30513df3,cc71b8f2,4eff8194,36ad2962,8c003a1b,c42c6ce6,53997d56,e0162508,c2b6144e) +,S(4ba7ee4d,77171ae2,e39c9e66,3849841a,ed5e02e2,182d872,98f0a064,3925fe37,5cdbd5b4,fe344f16,cb72158e,b80a726f,5a9da4f7,751bc4f1,f1fdc734,8e96dbd6) +,S(d5827a7f,c4d5dcd4,32e5bd7a,46892e9a,6f9a3971,fe9e1de2,ee247e6f,208badb7,f790fadc,9d0e0c0f,61efb534,9b23c60c,2fb667a6,3b52cf18,ca0f0a1a,6098e1fa) +,S(81ec5159,7f950cf7,c0d44d4a,89efe691,e9086dfd,ca25098d,411cb9b2,93237633,885b27dd,c9eff80c,94653f28,ef92fb60,741d3a2,aa828065,5fa60b73,eb9a1e7f) +,S(28fc41f4,a0d4f680,76a3e06d,af0aff1e,6e723779,d8ac9e68,4cdba2fd,6ab6dec7,b1e4af1e,7affabc7,3eab9415,c15b235d,482c6a8d,b1085f54,d80ca2aa,49657225) +,S(d5e753d6,c5bf75c7,cb0f5b85,77fa2f9f,6341a88c,cf59b5d1,328b18a8,f7ae4f47,d1aa54b9,8eb01a32,2518a10c,8ecd66ea,fc2f380d,d97953cf,faf0c540,c4a1bff9) +,S(1682355d,89094297,e6008fac,44c1a5a9,257d413d,7589286d,8bad4873,1476e836,4f69c762,e29f90c9,e8459b11,d53ed84c,2ec9c2d9,ded4ea02,78d04546,eb09cf4a) +,S(9ef7a85f,b64cae73,2eb511a7,8cc46e22,73425d1a,d02272e7,9030240b,23e781db,c720356f,6f6a5a47,3f35e2f2,f5e92e2,78a50c9f,3a77604b,3eb3987,d09ce73c) +,S(4f6aebb3,6f429a52,4cb1be48,ace0eaaa,2174468,c13cf612,dd7ec70a,2e915ec,406ad94d,a8b6d790,2ad3609,252b6d7d,b28f96e,8780f6c6,39620b11,cf8e761f) +,S(4cac3e0e,5ac02e66,66710dae,5c0d7e8b,7a3cc7f1,a42b1f8e,88561bb,223f8232,9396ec8e,aa96f3c8,4ffcb9c,d8c29d27,dca65556,c2fe5931,8ba05a08,cb263142) +,S(86f3463,3aa2ac57,2c4a9dd1,64c7606,f61fbd78,60619937,38ea0a60,f79367b8,c802fd2b,556179db,5f776c9f,db4c38af,cfb2aa61,b5ae712a,3f23e58,25824f05) +,S(5323f145,7685e123,e7a5ab4c,d1d39fa8,bcd6f23,ba3d74da,318dc7ff,347103a9,3092fb79,ecccb29e,12dec977,cbbf38fb,94cab4f1,fee1e8e3,46100378,88691cb1) +,S(d3d70d46,402711c7,e680c45f,3a0e1c5f,f85cf106,983ff0e7,1a7f1178,33ea74fd,91982773,d9b90f31,16893b9e,eea7fb9,e4f722f3,e1577c90,fdf6f625,a8d07bad) +,S(df63b937,28a87613,2db5d71,43654f1d,f8cb89fa,1ab1efdd,6fd864bb,db6d4359,7c3b79ca,191a3ecb,6c793034,832fa5b2,a2c7bed4,84b792a7,91bacb7b,62ce5510) +,S(f1fe9222,8cc334d9,5f303169,a4e2262b,28a99494,c7decec3,9746be85,71b70c74,5588f3b8,4e65fa72,a2b35f60,f99af1e3,b67a2435,8c28eb64,69de5136,e751a10e) +,S(9030e75d,918ca330,edfec14c,b7cb28d0,fb0adbb5,fa29fc7d,cb3c9085,ba74fd95,7df20128,61698984,c0928821,c38aded7,5a452dc1,3bbdc4cd,71ad99da,38b427f7) +,S(1cd3c139,35bedb87,134f628c,576411eb,dfa0b586,2c3cc7d5,ddd7cf5c,77ad641a,2154edf2,5488bb08,be93a25e,c847b26,88264cf1,30fabcf,5924bde1,4b9a324d) +,S(e56e0737,a19fec7c,78b9f462,1ec0d5bb,bd6e91ff,ac995f42,202f127d,2446ad96,8830d827,368c760e,40a8d9bb,b693e975,1e69b42f,4b2ed776,98f889aa,3ead70d7) +,S(1b0a6ac4,58abe5e3,63e6dfeb,24ad8a65,56fd0886,78086657,587e63f1,5fb6b101,d2df6fda,e64263a2,b133e5aa,bdddee5e,9a35e86b,2e1f5926,5212cc49,335178dc) +,S(10a14146,8fd4618e,4ed390a6,246d62a2,50bb1676,45cfc679,d80cc081,23ea22b2,3383b868,dd7fdd1a,ecd13dba,f4ebb151,f9a09b25,bc30d562,b033800,fd40185f) +,S(9dc4ab51,5378a351,6db8837e,568afa72,e357f7d7,95d546ac,8a73e419,a43f5e35,8ddaa2d,9bcecfbf,e2a422be,1ea591ee,bfe05ce1,90439a06,cc68d66a,6305903f) +,S(aa93175d,e7a4e1fb,c538eb19,e89b20ae,13539e99,362035de,1aaac76e,3ced7196,edcedb04,c1344568,9f3e133a,d8b48004,c18d146b,ece3da05,effb864a,c2afb9ad) +,S(8171f3e4,da02d9a0,8bb6fcbc,6d06cc6a,94f3cefa,35d4ce27,536ef6fb,222edf7b,e91be5fc,aae62aba,1c02b55f,73c1a64f,c32038b7,a658f189,7499ca59,e9e6dd6b) +,S(51f6c983,c89128e6,635888c9,3c79cf79,893fe627,437464b1,11b08058,1aa19ab6,5d2ef149,4bb164f5,20c1dbf4,1a8dc650,b8cee400,d5e37252,a3d0f059,3881a067) +,S(c0a1f184,766b30dc,6a5016b1,9db0dda7,ec34dfac,74dae580,9500ab8f,6fd7d38a,bdcad3e2,c7b6daf1,29d41051,624d26a9,b27f361e,c695d490,52893597,eac6f01e) +,S(b1bb1ecc,95435169,4ab6fe0,7341efba,fde9279b,1eb78a22,2bd39472,33a0eb02,df523f5b,525342e2,c0cdbf0a,671e0c95,4b149084,de4c61d5,5a7bfab4,c81689a8) +,S(b5cc30dc,86d04ed5,88539ea7,e437391e,3b0891e7,6818c470,1803de7d,640b5dce,f1cc0d9e,45c7312d,fb1acc8,62e03f28,9f55561d,fffe4b65,ca41e62f,42d4ec14) +,S(de2b49e7,5f0ff53,28155b3e,a7d5941c,8cacee23,51fe16b0,da8e940f,9263ccb6,34d7a42b,b12dbf67,b0d7c680,178154ae,4690d5b5,703572ab,74b4d93f,6d8de99f) +,S(8b18f4e7,c129e117,e898404,65870cfc,ea5c0db0,ef2ef11a,d515f3ce,57cc8f51,6b1e1086,c8674a59,3c5e9d6c,dc8edcb3,72281c27,e6b2caff,8842e008,99111f37) +,S(727162c0,27cec888,918e46f1,762a830d,822ce424,b6a5f442,f9e582a9,17c86889,de348296,1452a369,e6fde5af,693e5247,24865623,cc516e7e,8416f38a,2f223cca) +,S(4ae4fc1f,4dd17483,f18eb9b8,1c2494be,946a75fc,a3f61605,6d0856b7,3505058c,d87e7812,e901fc17,da034a05,bd878470,59999b36,e2c617a3,9ae46921,f2563e7) +,S(e90bc9ac,e9e873fe,91826f01,66affd02,72007bba,4ef690bf,58b15206,5ff43cd1,4bc820e8,9acdfd68,51c9b0c0,65b9bfd,47f0762c,d2e56d58,905e6360,4564fa87) +,S(ba0ae6a1,db432fb6,f7a1af7d,be9ef746,8340ba5,7f051020,9af4076d,f51450ba,7d3839b7,4099420,1729894c,51a2c30b,51019a18,c32ea908,c58876af,912be720) +,S(70661b81,f77c6531,1d98b403,ed7b97d7,4f9682bf,2981fa5d,ef882022,d3accfeb,9022b973,18959f4d,9ae4bd7c,fb06fe66,7b4eeb92,5f46677e,4e5bc4e4,a6d06387) +,S(fe1b7b47,28153a07,11f81b81,7d9efa38,29451c15,8d1f11d8,e5e0922,fc471a47,95a075cc,68cfb7c6,fb115dc0,5e4c31aa,85725bdf,2344dfae,19c8a034,d2b0f847) +,S(8acf3bd2,bbaea907,28013d04,f27e3a5c,4325bc37,ec5c5e86,7ab70f7e,9acc3fc0,f679e3fb,36da27d4,f29c06a2,5951f80d,b3e2e0ef,dbe2c785,ee148657,3e16174e) +,S(1d855d37,25fc7d5a,b87fc6a4,7f62ba7c,d2db01d1,ca0f14f,1d6ea8d8,4af395e3,ceb263ac,2d41654e,d4655183,f6268c5d,9b0a9ad0,da8912a5,815dc8d3,20b1b90) +,S(1abb4566,30c24ce3,c84ec6f6,d70d19b7,9934498,451f02e,3926d70,592a8cba,4627706f,6be87fd7,2ad886ef,73245452,1778d293,41229863,f4b19548,74525885) +,S(1b4790fa,672c12ff,965d07e2,44a3f30b,620e5c66,4b098a5f,b86f2bea,93eac036,eed050fc,a758e2d1,f2a2a9a0,6b8391fd,7c19fd70,9c9e1283,1b018d24,e7edd60e) +,S(61878b2c,fc9cc88e,30ddcfc1,2561367b,44c106a0,21e3dc98,a433732a,68de3dd3,fa2454a0,37c279d,1b54cb77,498a9efb,afc6f50b,6b13e29d,436000df,1eaed78e) +,S(84048df0,2767feb1,7bcc21ec,f4502238,abc7271a,931730b5,3354010a,8544308a,d4712e4a,39d608e5,d47f9814,f7763c6e,605accaa,438ccb7c,838c88ec,e993c32f) +,S(eb7ac4e5,6c96175e,c3f1e1e0,37e89f95,8ba37d0c,a88055cf,889bac33,ca683a94,4941e267,2ccc274b,6d8bfe07,513dfc6f,cc07de33,2f517011,2bc3814f,5e85da8a) +,S(48a36ac9,877d4bda,b62b452b,a0288dc1,4cbce455,3809feaf,1a4195af,22142e91,e24d6d8a,1256288,6c6d8848,4e950d8,27eec39c,21ff6e25,30b50eba,ab69659c) +,S(9c3125d0,5a62a25d,7869af3b,1b23a00e,e817b664,c82d2a91,2522ce16,bccca1b5,c6ecda10,f6707168,18417277,4e18f5f5,38566361,5506b450,a189b6bd,39e5afe3) +,S(33e81e21,dcc7670d,c7f3843e,4dc8be3,10160bed,49af116b,c2ca91e6,90f80d68,e694c1d3,a0a386d2,e6df1167,8efe38ae,9ce417e8,9ec05bb8,fa592906,55757b6f) +,S(9543769e,6899e0fc,bfeb1071,50959827,5c1d0d4b,8a68f056,d8e1c033,1b6a1ad2,700cffd,afc58410,7635f148,72ed1ceb,1c4be86,7f668b16,3f579534,ec9b0d7e) +,S(4f41ccd1,73e62c39,7d481e6e,5b50807e,6ca9b163,e21dc203,a0d50826,7439efdd,fbf98ed6,aa8c1972,d88b309b,ab74b254,8fea56bf,e158d1ee,d95ce77d,c69f79d) +,S(4cfb6a45,584b00df,be3fd9c3,38eebc28,a667fe6a,4651bbd9,64ecf20,645f12e5,2ddfd6da,fe080e87,470fac21,d1255900,219638a2,5e72b12f,5501921a,f614652b) +,S(9efb8bec,d9bba33c,a5e217fd,8fae533b,8e536bc9,1817f982,1f217757,75eca626,661300ed,529c15e,918bcf9c,1a7dc3e1,8e3573b8,875e2f8e,9440f8ca,b0658fb4) +,S(c2a80952,5be7e4c0,b85ab953,ebe6dc5c,f5d3c0f9,e850e470,da9e61da,e430e441,1d2ded36,bf72697c,7da6fa22,1c09fbc3,6be06363,d50d277b,4839c4ef,809d9d2d) +,S(42b7ff6b,49ae822b,f5a16276,4c620b13,2501a1b4,1bf830c,a242e02,3bbaa707,e41fe058,83f0e400,712de994,dcbb5a38,fb2c7595,c5ea8b0,eb90a236,82b71d6d) +,S(ee0bb129,d420b641,2afe1518,55f78f39,e00cc3b4,7ee3b86d,f781f0e2,abb0c28c,f71d0e7a,5a4fa247,67c6204b,60edbadd,54b17455,54ae9099,258343eb,5c0aec61) +,S(1f1d8a07,9cdb3bf5,2671a716,26c503c,77546ce4,2a252e78,9ca487c0,78ef5b9a,c611130d,ae55512d,ea8e8e6f,9fbc3064,180ee4aa,63d1dcfc,5c39e98d,97571c20) +,S(5bda9c06,ecdc9fb1,5926ebe5,5418f016,7cf3136e,5f9317b8,b2912fec,d2a31310,358ffb70,dce1260c,80fe59d5,b72eadb3,89076168,a17b63fe,b728dc28,45ecad7) +,S(c32f6503,fa50c727,66652dec,8e0efd71,edc78973,48061be9,1f847544,df866ea6,67234a26,7a13ecc4,7b09443,cb13f0b0,6a34af2a,20b80856,6deb9c71,1fca304) +,S(5483d511,b71feb06,70e6c83f,29612640,849bb673,896bb069,941cdea8,9489caed,a09a6a62,d3233437,40adf0f3,8d8e4ddf,494d5350,7944becf,bfed3927,d88c1148) +,S(3d2d8f5f,f0b86ab9,1ecb9342,5a6cc246,d5e3c6fd,9c43d047,2d518958,ea322ef,4188348b,4c23ce05,1879cf4a,b71d7608,fb45d7ec,a184c509,c739f364,d955b830) +,S(3a5c3939,29ed6780,5fdffa9d,f936bc10,735ddf03,aab89e9e,40b47574,21af1dc0,760b1919,76752916,2ac2a7de,22975c83,44dcd52b,a945c81e,dd8224e,90a7011d) +,S(a3d522ac,7c1cc06e,3ef9272e,fe24a0c4,64886948,3373df90,e5dd484,d4590a83,6f53ba2c,b739dd61,219684a9,50001697,28c377c6,93054795,5661f2c4,ee1b6be2) +,S(ef0b0931,13992018,44078583,62e02aa2,c1437d87,ddb95d42,36751445,d8e8180f,73bf4407,8d184772,7d0408cd,f92f8c74,2173520a,41971980,1b9c842b,9486c634) +,S(8140effd,1498ceb9,c2211899,161185a6,a770c15c,d1ca3e07,f26f40c,6d15da20,4c74f3df,6d2db7f1,be68b7eb,2162f03b,51c1102,a02dc3e,45fc49fd,22a474) +,S(3445d720,8e089f1f,93d32f4d,3fd6fd65,7603c7f0,378b74,215a59bc,ebe122f0,6d41035d,fdb54ef3,3a3c8626,f036e1a2,38da0637,e82953d4,b63e23a4,890b6d5b) +,S(e14b2a5a,6235369a,1d1933f9,7124cde1,789a366d,5fe6ab9c,72c23d43,f7a58cd7,216f06c5,2f63c102,6cafe6ce,58a9e589,d67a9f19,625513be,44744d0b,f9fc8f8f) +,S(6d9640bc,8389bc44,fcd0b2b3,3c088170,eec93106,67348dea,f8f3e92e,2d891e0b,4b4c1485,6e42db64,9fe04759,a42887fc,68b5d4b0,8161b31a,1852bc41,7d04227d) +,S(272f1404,5c461f21,3f67cc60,d7c03b1a,fd028a05,b9e06324,62a0afce,fd9b2916,98635ec0,c0b23538,a63f78d,800eb0df,fd6b7583,31544b1e,825cd433,ab348416) +,S(a8c99928,eaae745a,631250be,cde1ce3a,4152334e,de916257,681329ee,1f3a07e3,4ccc2686,abdf3f7e,8e1149aa,5162fed1,24ae51b7,e61e4620,9f5cd611,e7351621) +,S(fb024b33,7f93d565,899be686,9b1e4c81,1c660d50,fd31cef,fac38600,d8975409,339686b7,8bff3c95,7e8730c3,9457966f,ee562ca2,89d95e12,7b072f47,c4c7fdb0) +,S(e0e48547,aa613549,773ecfe3,691b84d8,a6cb14f9,ce4494f2,35187057,28562f9c,60b6dd8b,56407580,52748838,9396004b,778609f8,69f47676,a6d76eef,dca7b307) +,S(bd6c402d,378b8b53,9f74d29,605e1b0b,ed9e383d,dfec2169,8076ef59,125d16e4,cc3aac9c,bb761c7b,3776a8f8,c8c6d2c2,a276924b,79510f10,75521b22,9def2c24) +,S(e6919231,eefa4f44,144e2c55,4f695235,d5886cbd,e150aef5,52c217ac,5e451c0,e74ee1d4,d34d2612,b4d56133,c2a11cfd,73a888fc,6927f46b,c2aba9ac,63b1cfa7) +,S(1a9acc6a,2a487874,4d92ac5a,328bdb3a,37c481e,8c145463,f9cba4a1,a03d03a9,ba6069a,960e3628,fae22422,47fe1f5e,df71fc81,b49b5ca1,26a7c588,fdf0fb10) +,S(5b52bba9,2e5fe301,f2c4e939,52db99b8,abfde642,3d6da8d5,36ccef4c,f6070910,108ddbdd,901e227d,118c68f0,a71aed0a,cc1ab1b0,2fe74341,f546ede5,b747ae29) +,S(92c13760,1ebe82a9,b11a096a,73be2828,652b0a4,d7f9a286,f1338a6,b1e05242,2e3e93fc,2dc6d0fa,5d43dd57,85f6c79a,51a588bd,d14e0275,59fac06c,a449d7c) +,S(3cb6f8da,79964c17,73a1c749,e89542bd,94b4f279,f6061d69,a12ffe5f,1d4318b8,42e4c1a8,b4f45ad8,dc23bd02,faee2956,72a77771,6e6b1d54,d05ba413,6bb11956) +,S(5fed6351,d34518dd,111a5110,50de0e5,3c60a14d,9a80183f,66415145,bdbf5db,6b79a590,de07a4d0,b74140b6,49bd8375,da77e01e,295e76cd,56a6588,7746c3f6) +,S(2b88f0a7,81c384f2,b7c245d3,7c061128,a14132b1,fd0fb56e,7d3193e3,d95d3840,f787e7a2,11446e57,655b6453,c2244974,c1632bb9,4838a981,bd4873f8,89a0e10e) +,S(c7b247b1,5a3f55fb,35b0ac3e,1da36719,18507f94,e988efd2,47bb02d,83293443,4ab40437,34c65f11,236b6ac8,bc27c548,c3c8e5f6,64f3cb67,99e7b8d0,6db85f4f) +,S(ddfda933,8dcb9481,5c08a20,12c137e0,45df69d2,121d4534,4c6aa375,e03647dd,e95f79fd,2a116bd,5972e93a,c58712d0,95f91255,a46fa091,bbcbfe5b,57795c1b) +,S(dc8da645,5084b105,6c7e3233,b247e87e,9d15a6b6,677f8c29,da04fefa,371da7db,c2a345a3,fde3ec03,f6a07fea,8bd7685,8fc66d28,6637cc80,93132048,441449c3) +,S(f53f3b26,c5fcbfa8,f1263bc7,a6439056,a31547cd,3a8c795b,8e355482,d1ff5333,113ed45,e664b9ca,98d88f1d,a17c4fb3,5249e8ec,7998b1d1,bb68be3a,e6716ac1) +,S(648d23fd,c6d4b5e,4ee1d647,7d969df6,7d754686,9313ba39,1d89dc90,b646cae9,d035e045,239375d3,4e6ffbd4,bae0697c,9b336454,3261206,15edbe28,3e18962) +,S(92e6dd0e,5dbe580f,82473f3e,dd70b343,bd51bde2,b1ca91cb,1c483fe1,3c2839b1,cd90dffe,a5447bd2,592d1a46,5a09b391,a61ab01e,a10c9201,5ddf4614,b39577a5) +,S(1315e58a,7616ef8c,fa223ec5,49415a54,eaec0583,6be6fb78,2ef4ee60,f49f687b,729e0100,802d60cb,c54e1fa4,5dac72aa,2fe189a1,737da80f,1ac58426,d7e1431c) +,S(3c8a9799,9857fd85,e26b284,a3554e51,86b001d5,e6d075e6,c9402148,ab3e2a3b,464f0492,acc720a5,59487b3d,60502067,a722e915,a10412f6,d6c69dbd,28b25977) +,S(ea417230,cc94c5f4,436b37ca,e6f9ace1,bf3c7f8,ff03c879,f862ea76,127591c8,961238cb,8d95d50b,baccff1e,b9cd4040,6f4ec475,7026b3ac,e916067d,85a4faa6) +,S(8eccf9c2,f271079e,329a8c81,62c98af7,48496ca0,b0c5840b,ceb19a15,361a6ceb,3e259a19,165bf1aa,630c6a7c,52f37b29,c8ac5239,a132fa5b,b53d687,b17e56af) +,S(32f0fc83,b3503a59,6873c34a,b54eb6aa,7bf3d913,842cd556,77f398b5,4f0f296d,d4736d6d,906f78b7,62eda345,9cb5f7b0,311e50ad,cc9a1e26,655d8ca2,fb81a811) +,S(b7d63110,77c83a8f,a43c171d,a5ff7cbf,e4fa4cc0,b2614a9f,63831836,e0d7accb,6095f640,56441552,a8ac27ef,9c1eba64,8b84a5b4,c19237e3,5e285ebd,796be9de) +,S(ef6c904a,22df4fb0,a54cd74e,6563e56d,588b4f8,d6926cf0,6c32694b,be536954,308910b1,44cd37a4,e5bc3d3c,43715e22,aa7a0492,e0e9cc9f,b1095a22,65dbaa4) +,S(19e13bd1,e62825bc,acceebf0,b48e17fa,b375241e,6eaaae27,672d7ab,22941a6a,6f22c329,7005bc1,155308bb,dbf8ccc2,855ea666,e4af3bba,d3e3c90c,28b613f7) +,S(57d9bcdf,10f2f790,79349ae4,5f2980b0,9a98a7ab,d792a5df,967b7b11,1c8e9420,bf665de1,d9b7854d,e34f8fcb,1cc027b1,42ebfdf5,bfe4e65e,b5068a72,9a65db68) +,S(37bc6685,7c3d5e8b,878874e,3d1ed324,bb530a21,f13d057e,4e3f87ae,3df06b2,15419bdc,764db12e,f12abbea,c1ca7bbf,77764abd,72f5eec8,3a81c452,4c998539) +,S(1b30c5d9,9ca59151,33c012a5,96512c2c,b572e11c,a7412138,7f3658a9,f9c2cec2,dc42320b,2a0dcd0c,5404d842,17af8c9c,2344f751,16a5d691,1db0590,5ef39697) +,S(96831db3,50c55ac,dd329f4f,85ad4a5d,e6e89f21,85b93e65,b8db4e1f,c1efd0bf,86f43820,fd03739a,d0e75ef6,17072f2c,82bd8bd5,a1f8cef4,55e49ed9,cfd47837) +,S(cd2f500f,aa1f04a5,58309f28,f7acd542,bce7999e,a17cb792,66b93cd5,44e3d8ad,1f977080,ddfceaee,97c743c2,4815f795,27dd1b05,63ef009e,92994046,c8dd8c29) +,S(60392a7d,237c9e27,a3318ff9,d3552928,802f519e,60a783e8,ff32be17,4ad01c08,eb7f3147,df91d1f8,d8994afb,df297c44,88ae9e1c,539fe065,663d856f,22893fdc) +,S(f6cf77ad,df6ab73,20d68fb,9f3c1d7f,d8abb679,179b3c90,d22574f9,fa37ee9a,8ffa29c3,3587f716,6b5d513b,7df76311,77e81eba,1cf9b523,280c778e,2442ebd1) +,S(57c8015a,f542c514,595b6f4f,f11be2fc,944a0ea2,d26a4abd,1807142,da7cdf7a,b67c779e,80153cc6,7b6b32d3,3a3754dc,ffb692bf,d16e3e3d,2c9c673e,a8b05da9) +,S(7fe08558,ac184922,ffbd5c51,cae99931,2f58a17f,bb643b4b,fa1e419e,6b4fe462,7600477d,8bbf58b5,36e7e9e4,cd595858,7268cb5d,1599079e,5a88fbe7,79ec7a11) +,S(2e16f56e,73b39bef,d729b87a,d8e7c4e,3d81095f,58be177d,87bd9f3e,dd517b75,4ce271ef,57323a0d,baac950e,668f0981,77aa59f0,7a0211aa,69b4e417,375fcb7a) +,S(a4d4700d,456d7802,be781f66,6ca24a68,49200de6,d2dd97ad,9c2eba62,18ffdedb,c099f86d,e7ba0f0,e8f0e762,8864a4d8,9124aae5,af12f6d5,efed434f,c66e4532) +,S(b4764d50,50119e3e,a316c921,91e57ae5,a2327e74,187f145d,c048c199,db3fc059,e39be8fa,cc272129,3ec831ea,9016a188,4f127070,4fa4f092,c2f3d56a,4798653c) +,S(3e686ba7,d291abf0,ced5b352,e84fc696,c29fe123,aeb82235,5031931b,e7e2d0e,7b35c0ab,7cc3c81,f84caf9a,9321b9b8,5a889b07,98c9eed8,8c7dc4c1,a985d266) +,S(d7886f2d,1d4c70ef,c5961e56,33122317,58400105,288d3346,db49407c,d24a46c5,da645ee6,17c46024,b2e25903,d4d7dbab,c5ef503f,814f23e8,68d94040,54b9efc8) +,S(7cbd23cc,14654d40,5aa57ba7,1e375466,cea867f2,325db475,d3a7990f,ba17a40,eddce5af,96e66db4,b985541e,e638ecea,88d327f,edd37039,54ce5a1d,d2dcbc51) +,S(54626185,c279e1da,eecea0a9,233c2190,18f877bb,58614a5c,5d2b9894,17eb9795,6507ed85,dc8f8454,bf96730,5cfc7919,8cfb07f0,dc64b09d,928d0b86,e0e9b6f8) +,S(edcef155,1cbec2ce,2bedb20a,addabefa,59e68cf9,e2200681,89285c08,563c32e,ade67143,75592853,c296ab45,bcba4db4,bed59efd,9df68b33,b03d7a3d,be753179) +,S(e027a953,ff6ef9d3,f27db47f,bc91db7f,6a30bc5c,c834add9,9cf8d086,23380cd,1e6b244d,e18ad020,8e52d174,ac452a81,62eafc80,975872e4,c7e362da,cba2bbf5) +,S(a5006d68,db980242,54ea251f,3787d527,66dbf92c,aaa20960,e17ac6f6,72e2b2d6,a1938d7e,e854dd5b,94d98766,c0f74723,72d1e6df,5cd6dbab,fa63faa5,6a0b2b9c) +,S(327075f2,1a1fd9e,da69adf7,32995919,dbb02025,ee504e0,3d5e5066,8427be11,41a57eb1,c32e94be,948ee335,6d855fa2,611a4ec2,4519adf3,2deab381,6bc4debb) +,S(97e1a5c6,66694bca,6b10cdcd,7e95f74b,9c87ac04,c623799a,c1c7959f,1a3363bd,3cc9a48d,1ec7561f,7b72bb6c,4d671c25,56689498,42546a9,48c9b927,c8ab5e88) +,S(450fa640,a7374dcf,d11bce28,f4eeb4ab,d0a2d868,9f6fda04,7f790ed3,b0c07a21,eae88298,dc17cfa1,d482a1f1,70d1dd36,aa35a56c,7eba231f,c4c3ca16,efa77f4c) +,S(f5aa7340,fc0a66a1,2da09ce1,f4094240,d81fad91,87e944a8,a7a1ef4b,9e0a6559,1255b3da,9ef992f1,c62e7738,f84dba74,899d9810,9db522e3,49ad9fc7,2aeb5017) +,S(6900965,55197836,a7b23841,97fbd75a,8857ac8a,8b14ec8c,90cc94a7,8a42f1b4,1dc181d2,38c976d,b4627107,2be05f32,952b5bb4,e9ef4710,f1bad8c,171b027b) +,S(2b1aa05a,8ed84136,7e99f377,bc3760c3,bc3bc0f9,33555e87,8ff2d212,c3f290aa,47b25af4,1eb8bc31,915f5896,57f368bc,35e9000a,cbdd0a41,7b267e58,cc13e280) +,S(a4e6b69c,a18caff0,d993540d,3005e5db,454b1e39,d4c81a7a,b5315d25,d052d81d,7cff2103,9c587904,a42d78ed,c2e7a6ec,df4fcb21,17c89822,36fadc01,a15d70c5) +,S(ab44bb96,c74fca4b,3e39cb0f,d9dd7795,f728e1b2,80a7cfa1,7a36916f,b39d2582,59d91ba4,519fd8cc,9e773feb,b1915967,7edc0dd8,1e794ab7,cb76a2c9,9026f5c1) +,S(83b0c85b,3fb9c3e4,8c96a31a,e5442288,93472975,5d42fcc7,715dbc23,9de332a2,e99f5640,fb620582,fd833b34,2f086800,9652d739,2d6494b1,e36d301f,35a6da6e) +,S(ea45313e,624ecf81,676911ee,500bc0f,e5bd10f4,40e04788,41eb215a,ef954537,4ab8b00c,e2359cce,203bde53,b9e8a454,d5afb101,4d0b644e,81ad1313,6c0c7445) +,S(936c10e4,af823d96,9f7f7a26,98c927cb,ae6d609e,37cf7412,ac4cea1f,51a3cd4e,46f72bbb,10dd850b,8e3e5bdc,f0359f6c,bdb9067b,13d2b60,bf68e8df,b17b7213) +,S(436a5d5b,61aac3db,392cf8e1,36a89b31,847bb116,5d1e296b,36c90d60,f2e9bfd6,f81e688d,ae67cacc,1978559c,84a90f9e,5e342bda,e73647e,33655686,2f36d68d) +,S(9eb95427,3fe789a1,3a24b929,e54f6262,d931a442,2e61867a,abd84d80,4b315d7,38bfc192,7dc0e640,820fba,8effa82a,d29f204a,fec11c60,768f95a3,4d2ef59c) +,S(3826b6f5,87ecbc0a,cb6b4328,a00f63e6,ecb77a0d,bda277a,e6e4ba5,fa280d8a,d9435fe,dcefe69b,213e6eb9,eda63f89,db35e293,8ba3d6e6,57232f04,3a4ef271) +,S(a348cd11,ae0ea1be,3f993bcf,84364b9f,4dbdceb8,db3cca21,cd0f8ca2,4a1dde2,1fc851d3,db7cfaf2,6a1c202f,212b68a0,7078ebd,6d6441e9,1d1d4884,1c83ac75) +,S(bfe15639,237fdf3c,4e67646d,724264e,5d70d1e7,3cb70205,3c4e9a06,2bdf7329,902b37e6,1ec5e59d,9c3c09d1,d7767483,345488dc,e492e3ad,f12d04f9,2b5f88e4) +,S(e2fdb14d,81a1b6f4,d40dc346,c8205821,2642ae10,2707e944,14413cc9,c03dfa5e,3011b4ed,846e8551,6c66925a,e7676062,131e37b2,9b00c408,6c60a3e2,3488fceb) +,S(bbc659c6,8f476748,17663659,db4ac222,cf1119ea,ac27c38a,535ddec6,913c7416,1f8b6ee1,9fdb512a,fadd13a4,d3fe13b,48250120,975b8c7a,47798267,7954b954) +,S(65bd2a02,9866789b,dbd6f743,af85a789,ce9141b6,fd9ee056,cef4de8d,a2505521,32dbe030,1cedb7bc,5d5644a4,6c3e6c56,990b184d,710a770c,6b65f39d,3378f5a5) +,S(1ec0e6eb,8382cf7c,24d75a49,fc0f3724,e9318d90,9e05d406,a3a5916b,2278e981,e50e129c,f486bcaf,eac8ade3,c697debe,fa56ac06,337cd9fc,240cfc2b,3415715a) +,S(7390af1c,203da259,9e1aceb1,ea101628,c0399c92,33658d9e,10dcb10f,63a9eb8c,7d215496,60647b09,d7bcad45,1debe7d8,2c3adaa3,39bce418,320e0df0,977c3126) +,S(99a51469,7b913764,783ff7f3,7099cc45,127baf1e,d8931eb2,b4b71e81,6a1a533b,49c0d00f,7503770b,fcbd57d,bae748fc,809d21f0,8ea38d4c,8a288063,a7e2e8e4) +,S(e4d6e0b1,3b4804cc,cfb7dbf,ef1b7026,320ba2e0,c4fc98cb,f12fad65,8a0394d9,aeb0eaac,73a006fe,6a75ad20,3e0ce2fb,af5fc3dd,81865b6c,75075d36,3b761a41) +,S(488a4141,507ce5ea,cb3e1c46,ad23fb3,1a9aa058,2b553459,d885116e,19fe1a04,6bd6a066,43ef8c7,4cdeaf25,ead63b04,e82f8073,a5fd904f,d7235f4,cf12bd12) +,S(c0ffe24d,ed0ca54d,1ad1c2ff,d2dfbac3,2cb65b47,ca42e8c5,5d2c15d9,67babaa1,d15cc63e,29c54df2,19dbbba8,8df7011f,a0a330e1,6756567d,bbd7c6bd,7e7e9289) +,S(336d9b02,6c74e25,9dedd36d,d8fc5ef1,31b05d0f,f20bffb2,8305b923,767780b1,4aedacfc,9886a707,aebe6510,e1bdb89f,2b1b6461,1471fd1,b055e7f5,414e647b) +,S(98353eb9,8973a7be,3bbd3711,dc7b86e5,9a2a175a,ce8464a7,6aece2d,2dcf04f,a877fac2,27894a43,8f610887,305e1c12,8e45b4a4,3d6c596d,9807461f,aaee767e) +,S(cdc35e1c,17fff9df,63639cec,b54fcb0a,71c9fb77,c38eb905,3f37c361,36da1e61,a8ccb6ba,fe917260,df64f0cc,dc14a31c,87ae559d,7d629778,2bb9b668,9494eace) +,S(912cb1c1,5e62a0b2,71458409,39c06f15,5d7407ec,526ccb5b,5159a934,80111941,584c14d5,1723c447,cd0cecc8,6c70dda6,6fa710b9,8348f5ad,bf4bd587,37049bf6) +,S(2145e17c,7c1e8acd,99eec6e2,cff40341,ffd19568,9800d02b,5ddce693,c3bff3bc,3b8a71a2,40c0b373,95b0e9b8,99da7bac,a5c43088,afafeb68,957bff4f,7636356f) +,S(e4a09336,7e877272,2224f7e1,d03cdc85,43e0910a,20bfc4ab,3aa2ea94,8d0b1692,24b1ec31,33146f03,8eeb8315,afa6e34e,898f48dc,af7d0f80,328155f7,c2cf846e) +,S(fdf526dd,464d459b,b7f387ed,46402875,2b1390d8,4006ebb0,f579b36c,d328db40,4396e6c5,679216d1,dd2cf776,61264ec5,9373269a,a745c963,14147c0d,e53a3987) +,S(6c85c16,b3e37273,509933eb,caddf3f6,52ca4c49,4e751da4,fab5bfb4,ec729f86,9b530fc8,520b807e,5e649040,c5de9929,e592ce99,1b9f9cf1,21766f16,eb648d6f) +,S(4fbfae3c,596ee2c0,10c98ce4,bde00cfb,4e7da2,25583203,feb0c791,2ce28e58,fecf0504,ed0e364b,95edcfdc,ff50fd62,396b8a65,83bc1799,3e73557e,da6ff099) +,S(9bcc3b7b,80171179,3b683c2b,90e9c811,97c1d7bb,d3c281fa,1503513e,778bab8,da2eac92,878289d1,a77825ab,9859baa3,a887f009,d7d8be9f,3b70b917,41bc0b43) +,S(4415a040,e70a3b3,f5a95695,672d1314,855b0a26,3b5e3c8a,24e02f9,6b635150,d8a53b8f,cf55a9f8,81e92160,39afd5c5,6843ac56,39f3223e,c58a5869,da3986be) +,S(55e759c9,cdafbcf6,a38988fc,be203839,b617b536,2d537092,4d2084b7,45b2341,4a6933ea,ca8a3405,89952483,4a231585,3c1191b7,42eb95d6,cf7f82af,f931bb95) +,S(21021f25,bee23c2f,a57e072,bdc83e09,8d115358,adbde4b9,5ed63488,5540e9c8,9aef5691,a7700eff,7c42c98f,8dc822a3,4ed8dc1c,7f8648d4,ba5bfe3c,f9a8c9f0) +,S(2b4e311d,dded1aff,edff3c64,10d40b8a,c70771ef,6904e4a7,a28c7982,cdb376d1,145c30f5,6b255b07,fe43d02,b57f5b96,48b25dd3,6c792575,d20ac730,d709b05c) +,S(5190b21c,7e166100,c90dbf5b,e05d25b6,5ed91caf,904b091e,8b98b5f4,5d5378b3,b83cce47,1fbdc5f8,b50e3f26,8be0d540,1826d26c,216c1166,4040b4a,66650073) +,S(2b211ee4,54c65c0b,3647c7b2,87608189,88b1b009,77d016ae,1f2f4030,545b56f7,75743959,17d8fc1d,571a2563,47a61288,fff74669,b863f506,f9b70ddd,76854f5c) +,S(cb30b792,b41e0aee,3478ec37,ff6ba66f,a3caad4f,9418e1b6,d4af94ae,e64134d4,45571ade,cb3a9f4b,922b8b4e,c0d1c728,9142300d,daeb08e7,71b1aab6,228358c5) +,S(f4e437a8,d2fcaa16,e9749d07,89be67b,e4687952,7eea12e0,65c3cd32,4e4bc6c,fb52d28b,7e81ae8a,30de51f8,bdd0ee28,8e7647fc,392249c4,3449e62a,77ba97c4) +,S(a0a676a7,6a2a19b3,bc6a726c,193d9df8,ce85a94b,cb678080,545c53cd,df50d518,647fe8c6,b1b7bd21,b9816e5,aae40700,41198d68,a3c9bfe8,e437fc88,8f190a71) +,S(15dd4fea,d7f39428,b10544ab,1eaeeee6,75a2ba5d,15d8971c,7860a5bb,b7ff7b7e,89955ddd,5fab2154,7d231342,7b7322d2,53924d1f,1b1fa961,8442c471,9c38445c) +,S(a806b800,40294b47,6377a188,ed74dd9f,1bdea3f,f72cd2b8,850f6321,930ca522,4b6d7365,47d8b1af,697f1fa8,8ab3bb86,53e49aac,618910db,9c6bedc8,deb97213) +,S(41e3723d,ca086487,7a36ff9f,6e431ee8,58a983ac,f3c0406d,f31ba3f5,5b9f148b,8ab166ca,f27c58d0,1a80b136,dcda9fd2,2753c52c,dffca007,9139481d,3b8392e4) +,S(63b8a0f2,78558c89,d9ba3e58,70946615,690e0447,f8d4c953,ea00bca8,65bba3c4,321fad41,85eb8b49,53a95da0,f004c80,8c09b297,728b3a0c,2d300b32,43cf787f) +,S(62beb7f,aa8b0d3a,505cae5f,82229a61,c1ca21da,d2ff856c,8942a9a9,b14c5963,e3d9ccbd,7120c27f,5cd88655,3efdc43,a36f4c02,2f5b7045,1ac9d7bf,56bffd4b) +,S(b75a180a,f524b89e,be5d79a9,92f0313,bc133fcf,3cb2d99a,c65f2c48,1bd20427,e7855056,b11cc054,d37094b4,1e62dfb3,6a636964,633eed48,c39b8225,4a1d2747) +,S(4e5bbf6d,5298fc76,97ddf9cb,e4d063a2,6b51f93c,eef032f2,f03eed04,fe4949e9,66702686,40cd9dc6,54514a19,ecd80930,1871fbbe,99254119,476e44e3,16a12188) +,S(a9778c3d,f509f069,3baedb83,6d5fc1aa,b78e86e6,dcb61200,74bf6df,c173237,33a9c991,86a0f913,95fa0e50,d0a85d65,9230a41c,8c0be5d6,90ee013f,29d0cab7) +,S(f1b3aaad,16664be7,c49790bc,1a4936ac,757fb3e7,26ccbc95,cdb7bb63,cf570449,d1dfe1cb,ea3fdc10,3f218398,14626782,643426,24d3aa3a,52b0fb4a,7460cc06) +,S(d66cfd3a,b015d585,6a436ad6,a4cf019d,9563a05c,af4ce2d0,6988a4c5,9349f598,5ea179b6,d097d9e5,663b7305,6db940f8,d8e91bbe,fb951756,d07cf6fa,111efc4d) +,S(a532a4f0,924b5d13,bef0f30a,a982edfd,5d87a16f,2c0d8470,ea8fe3bc,da0ac7aa,c2e62c19,ca4e3481,3cc3de70,df50386f,74fd1efa,ac6217ad,5532a927,1f8d5c1c) +,S(a9ab2512,5df78835,ffbd08c0,9e07b632,81ebb3ef,3fe2fb3e,1a3e5ff6,28439b70,58ff55db,56e015aa,9aa43698,acc35df1,f2eaadb5,4e950c7e,3501a5b5,85877514) +,S(ce058f84,90813dec,c184dc83,915c6d5,53df174a,41ed6521,f2cff46c,460466eb,414d38c4,58817414,5a815a7,84f4f71a,28237741,97b37d47,c7646b2f,8af3e745) +,S(991fab65,30a2b36a,ab385c7f,31644de9,afe9253,9db603d4,737beaa9,6e406299,2a29b576,77c544bd,f156dc9d,44da01f4,5d373cfb,7ada94df,4f82af9f,e48eed57) +,S(ee6cc81f,bd034eef,cc841921,5ab4817,ddfdd2fe,a13f1e14,e91c3f2,af715d8e,b8f79ffe,48c3e965,21c7358d,ea5cbc04,df8fd847,a97bca3f,6893af3b,e386d8be) +,S(66a2d372,d6426657,5544d5cc,5141e003,16ff2dfe,813357a3,c5daccda,159c5ef2,b57d2d6b,91c6f48d,389423b9,af265e04,780000d0,598229a0,5bada3f7,4dbc8929) +,S(20a02dd9,f697de3a,15043e73,fc7f36a3,7a5798e5,acb4cac6,adf5c692,3a421da9,1e6cf100,d162361e,aa6ab61e,711e3dca,ab4ab538,2fcc6b97,33836c30,cdcf34f7) +,S(a0b8ca43,7818e81f,6be98b15,4da25331,9f92b79a,1ceda110,92e3a303,cb7bf552,4541bceb,f447d990,50663ca1,10fce2da,218508e6,48b630ba,a1abfe5a,3d543be6) +,S(51714ead,73dce488,7e15c25f,b5cba9cd,e0d5018d,db5b8ffb,9e4174eb,1cc52c63,47b794a0,82ef561e,bee272c7,d66dd201,a5c24831,99977097,73b9141f,9bdafebf) +,S(18ea2763,1fe4de07,3e7c41f6,a9921e91,7da195a4,13417a2f,ba74ac2c,d6451c59,398a0b37,fff6bba9,b33e0428,e8d7c93c,d31b3b83,2e955e6b,106aed50,d64df316) +,S(e1d58b4f,c39e1834,a61ec341,acfa985f,c3d1f0a5,9d75b0cd,e8b9057,17c5a87e,1b62ee02,15fdfdec,8fe2ab3,bb7f99e5,af82153a,dd9c7f2,cf299225,9c6b3c47) +,S(39793917,30d3c125,7dff5ba8,eb253dc3,2c19c541,11caf9a3,bbdec3e7,716c5a84,d6a1fb50,189f36d9,912cded5,c851da8c,be7b4ebd,41c2a1e3,f78aa4a7,f5f18015) +,S(49b49e4b,601b406d,381dbf88,8b02519e,1d57360b,24f2aef1,5520f17a,5b9ede88,fcf3ccca,2f2d7b3,59be7be1,9e45a3,a0a76e9c,d0e42fad,bff7e772,f969a38d) +,S(2cd8190d,b42f36d,20d88548,f0ff17a1,d64e38a1,2241e4c3,2bfdaa45,28bdc871,f729c369,22141490,5aa84f45,e5abfeae,2fff780d,2b16aa67,77ef59b,68259187) +,S(1fd0fb11,17385466,2da0cb2c,f1f9d19a,b5b642ea,45d1c6f2,30808626,5e41025a,3136a688,fec60820,abc7825d,1c7012da,94e928d6,dbb6c08f,5579181e,469ce0e9) +,S(f08e5f3b,d7f8b5be,18648a0f,5bd844e5,3f93d5bb,120d3871,7de4440,7af3a141,3dd8725,9067eae1,cab61bdf,cc94ea0d,bf7ea1bc,df1d289f,a526e15f,d9902fac) +,S(a0033c06,b997fa96,373a046b,b5c6bdd7,a0584cf0,1feec5a5,d3f5cab1,1c5ee207,eed61931,aacbe48d,708c2cda,2208d40c,39a577b6,3d4ffa17,d140a8db,c3e268b4) +,S(77deec08,68bea671,df01e29b,117791a7,83ff8f70,4426bb1e,1ea91b6e,62c16f70,b908a228,ba8f73f6,3271ae7e,f19f5e9c,fcc1fe27,c0a224b5,dc426b00,5664861d) +,S(2fcded5f,fe2f10ed,1a1bd1fc,63506b3d,994a03c1,c188d960,5fd5aa1b,a9aa72b1,155bebf6,f09a86f1,d20d7c12,e12a0c66,b4df6628,4ff9d45d,3fab7d76,6bbefc6) +,S(1f0c0b2d,fdf5e733,abcadd0c,9ba47c09,8667f8ff,77c2a904,c8310e20,995db3ad,bd711bcb,84cef55f,5139b761,33268489,70f63182,85ccbe44,8efd7566,577bc566) +,S(b4a8544,e7162c44,60dbdf3c,5edf654f,d603fded,4aa885ef,465ea8f9,a37dcf8,53c04391,b3f2e8b2,32e27b,2292cb38,99f8ee6e,dbe1934c,13938a3d,203c62b2) +,S(df0ebe82,dcdeb735,38f31cdf,ad307397,d00a900c,6d94221a,9d85b0b7,2c5bd68c,c3299639,e7fe2e55,447b869e,3a4acf8b,4a1d07e2,d70701c6,8a2f4733,88decfb2) +,S(eb04b9b6,d1c38c33,e1eed101,fd28f89e,f9fd460e,5b379576,ec7c9267,3c101c0,4f26d849,7f47f80b,2b13cab5,782d6e9c,f5ee7548,3974a4eb,8d8f28,f5e0ee9e) +,S(7bc9efe2,197cc6ce,ac94b37a,cab9865,7db4ee0e,ea7b9cfa,ce9f71d0,d3294334,d931bcad,52347906,a941d940,4b5b3a51,ad8fb493,1c15c9a3,7ff782da,5da72013) +,S(8922d1e8,f4bd52c6,4bd0c10c,66a3e8b5,1321dc50,cc964844,e0a41ad3,b73e0b9b,2b643cf1,7d23e21e,890e6abd,3337dc52,61c9eec6,d5edc318,2a02a7a3,4a41c431) +,S(42f2ede3,3a9312ed,22f6a842,ac46801f,139a7da,77ca0e9a,cdc19d1a,f2ddcc72,50d45bcc,715c985c,b9260edf,fdc8e342,ab95360a,6bf4776a,c70e3497,8f26f99b) +,S(7bdc9720,1862feb2,58879255,726b5e4,627549f2,92936ea2,f3b27051,4d6761c6,700eb72b,7f77adf5,76e6f0bf,f8406660,65372ee4,cad6269,f1ca8541,2da4fa8c) +,S(b9b527a6,4bf549bf,5e42e0d8,5228e1a1,f79d1647,d2102306,6b6d98e1,746314cf,8e1b3464,2a721f5b,93a2a2b6,802f30ea,e35b1539,c6d84eb7,499299aa,aa0cd93f) +,S(b65de529,34d47765,1c29192,93ce1177,d187c431,590d2d74,978ac258,75e3dda9,3d6fcbe7,4ab9b5ce,b3dc5535,13036457,f0755509,ecbd94ef,324e36d6,3b9fa529) +,S(18eab632,608751e,af3604f6,a3f05611,a036edea,3405aca5,c2e66366,ce7c6b9b,89eb07bc,94671119,36e11f05,79f91e6e,ccd42605,24bd7dd9,9d12b365,95074c5) +,S(a2611066,4a479643,909a1606,596d39db,c7502ee4,a31b40a1,4eb1c60e,ead360d5,4b45d74d,88025576,3262d9fe,38198218,85721a81,f323cac0,3e87f372,75814901) +,S(789454b1,2c108537,a019dc58,35cf25c9,c77ac0fa,f6001959,5da9435d,3c08a8a7,6bee870f,ed2859fa,cbef4337,8a0bd760,8841da03,252687a2,591ae0bf,a5829041) +,S(1977c206,fb4f65f0,11b683b9,c2e0df95,f81570f9,9f6625ed,7cfe25d4,62791569,de76dda3,c22244aa,95ff435e,5a9ebe05,9dcc79b2,75d91de4,67de435e,bf698479) +,S(891f0df7,d259d536,40fe6086,1ac34d7d,ec3b5ad4,c3f56585,189ac986,65f4222f,cc5e0bf7,f538a2a,1ee7a601,1a8d6b0e,5c3293ab,404257d,ba90ace9,1b2de219) +,S(8534bbf6,9262f81e,5926c282,f412b4d3,50169de0,3c5c5e55,c80a937f,fe99530b,fbeee581,e0bb0737,4cc764c0,be5451e8,f70cfc23,4d415cf9,fb08e7eb,557423b5) +,S(e5b6f564,4e7dfd3,7474eafa,354598d5,58fc897c,f010198,9e44b07e,a86f63fb,4368bbfa,68a83a8b,76de7d98,38880780,8e153cc9,b380ad0,b2c6ce26,6118da79) +,S(f9591a8b,11c3e514,983dc5e5,507247a8,46e184f3,b4e38e29,f7c90d4e,6c2b850,423b6436,2361f587,cca4e288,a366a1fa,957de393,f29ff2a5,1fe97a0a,d90ff6b5) +,S(3d3239d3,252f5e9e,ef9eb617,c9646379,7c995059,57bc7821,2f2920b1,ff72384c,1c3e37b6,fc9bafac,e52798bf,695eb4df,ef860ee1,a9b67df7,8f73ca9f,22a2e57a) +,S(f4089723,4b574d76,86a8e855,408612a2,a0a6ce61,c1f14055,201d5c67,bcc5dfb8,6b8283b7,3e72fc91,54aaac24,2565a79f,c3a62fa7,602ffaf3,c7453209,c0a56a4) +,S(ace076e7,aea9c745,f6be65f8,498b8b47,95058ed2,b0413c64,bc4b462a,2e267ccf,b62c617,377fa9e5,eb72ed6d,caf353e2,dc58f362,a994520a,31f1dac1,168b97aa) +,S(70ccbba7,408c6069,3230b848,eadb1d1d,b4e63f33,b4fdf6af,29d6fc2d,86ec161,fc1cd9a0,46d30e60,e4128677,654a80ca,5a4ff338,71fbeec4,d7782c7b,a14d6959) +,S(e6e7a8b2,7c0c5b0c,5ea58d3a,4af5abc5,9e33fcb3,9970aede,7a8de629,e758d372,d40d11c4,c8c8b5a5,d511fee2,793e2c80,b40df3a5,c98bd704,9a8db3e5,c98d4a66) +,S(cdc495c7,e0a02e68,329495b7,19e2c424,7910e9a5,cff6739,117b1d32,23216346,63664f6e,9306c0ac,f29ddcd8,7f1df6ec,d51fc68c,6ce422f0,559205b1,681583d4) +,S(2784e89c,2fd721e0,22ba33,3b824dc1,d0142f19,6f35ae4f,825975d0,7a2fc5cc,ba58a66,bdfa661d,354232b9,b25628f4,5a391e44,f00841db,4a335ef5,dc3b8cf4) +,S(ab699b62,ebcb7380,2141dd83,184ba3cf,c9118bf,f6af4d0b,9b98ecde,b01a2390,5e548210,b71420f6,c5d42547,da0a7ccd,2be0117b,79847e71,a609044a,34766905) +,S(781ea7a5,67ffe37f,b9fad6d3,96dd1eaa,2209552a,9835ae08,dda3d4f0,b75756ec,3c76d87b,46f63b97,e4d48174,4ba664cc,403a507,dacdf4b2,af9505a0,f2637256) +,S(75ab2d30,dd5c0a82,a5c04fe7,b8fee5a3,a0e1ce3b,e20b33fd,39d0bd3e,e374029c,aaf46147,fdb1393a,cb9f6f8e,694c1cf7,30536efa,b5ef921a,72215fcd,61914b9f) +,S(294b6698,37303da9,6d23caea,684ad56d,8712433,d11c7ced,85a10cf8,8ddaff0,af4d7ef7,feb73e9e,a9407fa8,b38bf1f1,e5861bfc,82f9cb42,22fa64f7,9b46f7c1) +,S(d8676aea,7433639f,c9683b06,bd97011c,f290f6e9,1257ee55,ea3c6e34,b824c8d6,710c8876,35d45545,90f3e5c,d6aac133,9017b2a,de71e30f,d71a5b71,97a7456d) +,S(5e4eca03,d90f5ac,2ac4771c,6d86a458,cee71427,a93b7544,fd8bee74,161270d0,44fe0143,b970f8bf,affa6d60,33628894,a93bb4a4,f48cbb9f,f0caf0b7,40c97351) +,S(90152daa,244fba85,fe708f21,29b55485,265c3a3d,dbc761dc,157f125b,8580097e,1694d2c9,200b8690,b59fa3b2,8fc2f613,8a6d392c,48357939,b9435739,83ef2cf7) +,S(67dd54f0,96f171c4,53fa953f,acbf2b9c,daf3a199,732ee0f1,91fb3c90,8c5637b5,5327db43,2d33676d,b6502236,5a338c62,5fd6c4a4,536645df,b36279bc,4ede74b1) +,S(c6496a83,8f95ff57,65a0f144,774cf543,2e770457,55efc790,142df95f,bb6c51ef,cc0041d6,604d1d73,92d86f01,d8b05b53,1177b51e,3a38b8ca,ca8267fc,bcd752a2) +,S(e799d70a,b163bfd,475e5e72,8810d9d2,425bf4b6,9461e9ad,933fdb6f,68c11c74,fc34745f,e29bee3f,9b0adcf7,618c6d13,e504449d,1a272b21,5ef9fc18,14ba8600) +,S(6d3c97b0,151a9011,5032aa22,1183d82e,820c8774,c3dcd75a,cb6f45ac,5d489d3b,5aa8bd01,3d15d77b,8f695d43,8cedd9ee,64b57df9,ee672323,1c2cd5b1,4ad4749f) +,S(86e53e00,1c1e7de7,419cf2d9,a4c6a39b,b96d8ec3,a82f8165,45658eff,a517539,f8b1b70,f2efecc0,cedda525,40663114,c24491ac,266df520,ce475f01,ab44ad86) +,S(a641c339,ac877cce,a9a3267a,78edb33f,75feb90,1f3c8743,47c50843,52a9880a,d88a6d4f,2b275ac5,3c7dc101,b7d69ca5,407559c6,afdc9009,c34a7256,f982163) +,S(3a0153a9,4d778266,4581de43,6de31754,b925aad5,4090cceb,9e013568,9d82511a,f6ca48,94935c5a,7a252df3,8ff06cf9,11154b0d,9f0ac55e,35a33d7a,58802035) +,S(e78024e8,a131c9ad,40526b31,d26e96f4,2c2e51d7,c63f458c,5bec2a61,472b170f,c540a14b,1ad7b18f,23493d9c,edab65dd,3a309204,976408ea,f197f658,9f4e0c53) +,S(7858c85e,8351f0ec,740380fa,b1924668,7f05a161,e2dd87cc,7df13338,a86a5162,cad94344,5313a06f,c382897e,7c444d53,7e658e06,5a76fa60,928d7e5b,36a6de1c) +,S(6643e28,1c5bddd4,35a68c17,965f334,ddb9da8a,d599a4b8,2f37147a,cb0263e6,9f9f9e36,8ee1aa0b,9bc8f928,284968d5,6f2dc8fa,6944ff36,d728b588,a72cf79b) +,S(5f36d937,a286f14c,96fe8f9e,3ea05d56,b3132523,e9a135e7,106592d6,b9b2254b,9d6377c,c8265ff2,dcebf753,ef2fd39e,9adb0e1c,3c86acfc,2e54648b,9056310a) +,S(212eb1ae,93d3a0aa,5f626f26,628503c2,310f9172,461ea12f,b17677eb,c63e2224,51e57e33,347f2016,c738d9fd,cf528269,bbc5afe,f5fd6fa5,1dfcfd47,4b6d1b67) +,S(526952c8,940b9f93,32848145,203ce261,dedb3b93,8e6f277e,9a085d77,35e9eab4,8657cfa3,56df2aaf,9a5fe2fd,81804ff8,1d9aa58f,143fa109,52e4f4cd,85a42918) +,S(20f1750d,ef762812,e4ba8778,c953a2d1,419e03c,b97ab6ef,8f98be07,4c1c099f,d2fee9f5,3e7ad2a7,fb20bf88,16a1ec2d,d9d97b4e,5abc060e,bd8e8b31,bacd485e) +,S(e231a3b7,ea011665,c223cfb2,7f13c691,dbc7f5e5,efb66496,da2936dc,d67ee910,aa645c2e,18e80131,f3e7316c,7cdf13c3,45e4f602,fb17011e,96eb5fc0,bf65d53f) +,S(7a4e4d52,3fd026dd,3daeac35,552e7299,d01aa962,687a02cb,ed7174b6,25c702ad,351c12b6,a7398e5a,ae461204,4cd7c9a4,7d2bdfc1,1f941b84,71eb3304,fdb965d2) +,S(fd2f707e,76965670,67ca5a5c,a0010c6f,9a858967,19a23eaa,5574d1c6,cbf137b3,c45a430c,1d5ae473,31f9b161,3ce55f41,df00e287,9e3bf8aa,1ae75306,f8315408) +,S(c506cc1e,8cf2f4fc,e1011d67,6d304877,6c2ac2a4,f8265373,f3f918d3,f02bb89d,8de6dfb3,74029b33,2fa47f6d,1f7ba609,bea33d6e,2f58ef0c,58641e2,a5d3118a) +,S(2ea7ad02,d9ccf999,86ab901c,3c9cde3c,ad1bb4d7,d8f86eeb,b8204b75,ab5c0369,11222bd8,6d750302,763648dd,daf76947,2b213562,494ebd9c,e4003195,eb0ed43) +,S(ab8cc192,3555e4e5,2f84b421,ba2ac134,f8a6023a,ddfd279c,4c338cd1,9e159c5c,2c48e3bd,cc268dbc,23e9fbda,6c449079,5a5b54eb,54ca8ff5,14d1f23f,8751ee1a) +,S(88fec2e1,cc7c41fa,91b48e1c,2a71089a,c3778427,f2cfce04,c54af407,f5dad430,ccb45e88,4f696653,5fac7a04,9b035c26,dce30666,fb1fecf3,c4b89deb,8b3ed80b) +,S(404587ae,1accf5d1,b42c3127,2ea0cdce,940522a1,c64c757c,11d3768,774b0d41,e8dcf25b,25ae61f4,f7368c36,9b351b35,63401deb,5ce55325,f96a393f,ef0e787b) +,S(8a701eb9,cadea8c0,8d0cf20a,b2750915,28a377cf,bc4d9097,51424d1a,7eb9ab8a,4f045982,82a9ac70,c3c76154,ca98b5a1,265e8b26,6f02d43a,4549cdea,caba5a45) +,S(c2812978,194009c2,9da141fd,b108a4c3,66e15e06,c6d64389,29b2aa78,89ad3d56,85409efb,6670e969,a2834255,dcb1e546,9c9db5e7,6e549afa,974936c8,b75db5c1) +,S(9ffd36b1,c810c843,92bb04d1,90b82be0,f8ea4b4,2baa6129,8adfb810,71d72fe,11e27a4b,a11f0df8,1a42955e,bfa9fe1a,6f25fda4,6a65fd87,1caa3d6a,1b38404) +,S(ac4a0044,bc92b017,cad07210,750eec62,39e43147,5e3feb25,f1c6f879,a5a48b96,41c7c3ba,731002ff,1e749853,344c1f53,f526bbbf,457b4de2,d5f88ce4,1eb8dfe1) +,S(c78b101c,157ca920,b3fc83bf,9d19fc5f,57d8086c,d764e142,24ae4e86,7b06eb5a,1a8d2c6e,b9d660ff,faf5f533,b4f3b8f6,b7a9d7cd,5c29c1d2,deb37f19,d38126c8) +,S(d08f3b05,572348b9,5f3c1c2d,baedd921,c24b0db8,e6d17d13,578e5ae8,77147cd2,27b5fcde,a067cbb,69ae3e5c,90a38523,4987dfaf,5dfe0696,91461e26,762713cb) +,S(40ea043d,5060f61e,b81db0f1,c7c5c1fc,1091cf51,c5808489,3d08c4b2,a5e312f5,2ef11ec4,2836302f,e02719be,259f1536,43de03e,fb659f30,84816a00,1d66b27c) +,S(f9d104bd,fb53b4b2,de8827b2,8242eba5,17db73f9,dbb1eec3,9f184ad0,358362e7,d7644a0b,6c371948,2ba707b6,d7d43f0a,68f4e3c1,4af6f167,296ccfcf,4d771877) +,S(dd276aee,14c34829,4e6132b4,9a05dac,fea5f8a2,41712b6e,5703778d,eff9ddc9,9be617d,5d92eec9,7fede655,39690d0f,4803f760,2b74066b,7bc98353,a5ceb7ef) +,S(8522f839,d5f17bd0,c67d11f6,7f0db8db,2104c7d7,785252f4,c8be84f0,61155d49,b7791951,80311f8f,6cb9b59c,ddca495a,e01f3edd,599f8777,3163a959,5a3ea117) +,S(732802bd,b4f3be8e,fc02a62,4614672a,51049166,4bfce64e,eb2030d8,b6b5b225,7bd4cdec,590eee1d,6a505f92,cc0b25ce,d9022d62,d1155f8e,35a6ab72,46a3c6f3) +,S(1b3641a1,2c4f8352,21e73276,b8bdea15,f5ffcbaf,c4496fc6,8fbdb573,5967af62,3d50ef5,e5d12b7b,2ede2e15,3b4cd01c,b824c32,7a8e1ce,f0fd866d,99664048) +,S(d3034e18,4e9284ff,ed6cbe60,cb66d391,c897255,dbbe8c85,2c79525d,3f01a7ce,b3666304,16ce50e7,2a094b05,85f1ba1e,11172ac4,eeb353b4,8c4f8f99,f9d09e25) +,S(8e7a8200,bd22f5ef,18fa4461,8f4f85a,61c6db2a,a3ad176d,65c3270a,69e9db17,841fe3b5,1cce979b,f87536ed,c71f4cd4,4a482475,19b35cea,dee4b3b1,f3530568) +,S(fcccb4de,29ab8671,d1aaee27,61421ae1,c4af5f3d,839009e8,5dab0b65,60a4027e,a0229f96,203b89af,d5b6ac06,9e977e71,a6e269d4,bea29c47,fa6bd22e,f7f993b) +,S(e68cfd7f,44358180,84c681f0,aead705b,9e74a476,1f99e576,9252c007,e44c8a26,add9c0a7,b027e2ae,42378d50,cf0d0eb5,71229161,8e9f13c1,672121d2,c428f82e) +,S(8b6f0fad,4b81ac16,4866de7a,c8bb3252,63bfe008,b726e9a8,72e0461,2c6891d8,9bad6508,a8d604b7,8088d328,ca27fe13,91493e8f,a6291288,92ecaed,ba4bc9ca) +,S(108a0caa,37ac1949,263178cf,20674616,470f8943,57a921ba,8cfd499b,d64b78b1,68150d22,be05956f,5ffe302e,1ff517c7,9b7c0452,6112b2a7,5a819f64,a265bf55) +,S(fed18333,844c579,1d32daa8,3370a5c6,ab8e13a5,2654a08b,42940284,c757edb6,67bddf37,8395ab84,eba29a97,6952ea34,b1b52c2e,d3f89e56,f839c1ff,36457fe5) +,S(bebfb39d,ecd56cf3,50bed6f1,a4cde24,848b2d84,23518da5,1fb2ee0,90170a2f,1302b4b3,bb86f887,22925fbd,e146d948,5acb2db,a61e751,97dd40ca,2ba11573) +,S(67135aed,2a58d3b6,c4470d3c,b4da7b56,af8d5057,9d28a86c,9c67bf28,181e716c,97c40aab,2786e3ef,dc8f3e77,8f374446,30fa2f3f,53eb040,194809c,8efd6664) +,S(b00eb5bb,9566e5a,cdb09dd4,14d6df03,c3dea75e,90db8b9,c37928e5,4354f90e,6d120e41,1cb6e674,e9973aa6,3999af3a,ccc3a670,112c964d,8aef93ee,e69b1258) +,S(721b1a6c,be8d2022,f09db6d3,ba39b2d9,23337592,de9efbb8,ecdf3384,f3bb73a2,cdb41b62,631a0f47,75ae1f2,e94f8075,4acbb2e7,950be088,5b458c8e,4a05310f) +,S(cb8d78ac,15b12ca,8dd47cde,190c420e,42f60b83,9489bf71,d10a3e44,df8a0837,80be31a6,a3073675,e8cd3846,cfb2e127,abdc448b,1081a2d5,d177ccff,ea96dbc2) +,S(491cfbcc,4919d884,d23f3ae6,6d143e55,37e5c52b,e2ee017a,afec785,6c781920,76321b50,26283088,d344d29c,c4d9f2ec,3ba714d4,edc1bee6,2b17ecc4,56874189) +,S(6ca33ee,48992263,23aed33f,f822303b,8145d146,c5ebc27c,fb3700b3,6ab507b4,96b73ab3,f189d064,1e0a20cf,d09522bf,8c376a0a,9c9dbec6,44e3e8d2,c0b11f4e) +,S(6d1fdfcb,3c48971b,6cbb33d3,822cfa68,1bf602ef,98160f89,97ccaba8,19d842c7,82bc7c4,66088262,5e57c062,96f04600,fa555ac4,5596b769,9c6d29c,cfb1713f) +,S(a3e81699,1cf92f41,a69ac3ca,36b23796,daeb533c,3e1e9b55,c88e3fa9,fea43554,87a6fa9b,e802467a,fa206b0b,45405309,65887df5,786d20fa,25e94832,312855f1) +,S(fc84abd7,cbfbc329,4eac7438,d50b2ac4,7f570e4f,3f2ffab5,71f8c3e8,7dd49c70,7447b269,71356b0,e59b3f1c,d99b6416,589f6c3b,a566c75b,6915377d,a7f73dd9) +,S(beb23240,8fc515ba,180d3125,2eca15a1,af4e02a8,73a69769,53982408,355d1b1,12fa480d,6fa8a9aa,e5edeba9,31b765b0,e2bbe6a1,5eb9e95,b3bc343f,519c1459) +,S(68891679,cffad7f3,19a373d7,1bc02529,a50e63b,60434f13,df760364,1a99eb8e,40b78db7,6db28aa2,d2ea7c1e,86d01503,7736ce96,2e6ec524,da07b5b7,68772fb8) +,S(ec435ad,1ae7b040,fde2f736,e8fb5d53,b42e2fcd,428e9d96,ed401ee2,bb068817,13bf6eaa,1283436f,4a828a85,66c4f795,26860c45,d650fac2,44bbec8e,fc96f9f2) +,S(679f5afa,661f688b,7dfb7ce7,f77e4904,60a75576,6216a49f,374594d0,6bde3033,ff3fffd9,6c254fda,558f14bf,c8f05cb6,c8fddd32,a487d709,4e0fb35c,6f617ca1) +,S(9febd8ea,5dc26e5,fbf48aeb,64307b21,1aa2fc02,eceb6d68,ba89a652,f633be60,c0867bc8,ea6238a4,ad36e785,cbbc5e0f,3fc5dc96,2c778992,72be4364,8e630bee) +,S(d886b154,c534b48e,db6bed69,6dd8f9f1,347b381,1b593acf,e2137c93,600b1601,a4cbc118,aa07daa9,c4e246c8,efeaa3f7,d74028c1,93b77964,f10ab5d6,f75d077) +,S(af8ccbef,c187a3a6,83f6ab6,8ff217a1,96a8e27,dcec349a,b7ee4a74,446e9d47,3ee327c,99880392,7da5b625,be554e6f,1662a733,25a8fdc4,990716cf,6be941f0) +,S(1e9800e7,891c261c,a3451d22,44a54a84,42d33458,a997b365,4a6198bc,7dd3d26a,322f8986,bd6ffc0d,d5f1a321,e82e6b37,978120c9,66f753bd,5669a773,65a215d4) +,S(115c62f2,9f008009,5840dc97,f3a90f30,aae4ffa6,a2d255e4,15d64c56,77150044,4d944c12,7e37ce5e,fd7660e0,1e4fdf0a,cceef95e,8bc2da14,a8fd7e32,ead8af95) +,S(1cb9f9d,acbf79dd,b34d78e8,e51225bf,3f53135f,f4282ba2,59855968,2ae0178c,8fd3a4e3,7a189bc9,421595e2,bcf234e,d7b602d0,855de84a,50c68cb4,bd1a4bf5) +,S(62a15bc4,63e4c167,4bab2a5b,dc991e39,af86d258,f9de770b,66a79ee5,2fbfe357,b78fca9f,d9467e4d,256da69f,e6f45522,d376fe41,e8ebde9f,9f7bde4b,8ef52749) +,S(574a6ce0,5bf31948,31570914,a73bed4e,6bd2c82a,5a19dec4,54b11e93,5edf505e,e7b2e2cc,cbd6f338,f0ea60b8,c1a9a50e,d02dbaba,8bb5cb78,9b281a97,5c001318) +,S(64c6e37c,a3a361a4,baf9ceda,d9ed24fd,c5ae50ab,560e6319,4adad1d5,264084e6,e6e42f56,56b6b404,9c54a07,f35ae004,4b7a480e,8271c8d3,f7996ed6,68116067) +,S(49065a97,fe4a8de5,55646af8,475607a7,71b27746,ade7fb11,55308107,4900fd84,985d689f,67a03090,9ab8eb43,c7b2767c,94e7217b,fbb43342,83485f1a,d70ae7f9) +,S(6fd32ff9,185790bd,876a683b,7e889f32,8500c91e,7e5889aa,44394caa,330999cb,12fe8084,1be1f25d,7a93784e,9c6bf01f,efbd6493,8f1a678c,64497a8c,85d2de3b) +,S(4a67d4da,48189c8e,6ff34812,f7094851,2d6d12c4,26fdc98b,4ebb92b6,62d3b185,58ea83f2,f6e5b777,737c668e,efa71b8f,3e50095d,389a5540,684cea51,7f8150f5) +,S(ea1ac931,d3a92770,5d20752d,b9adb464,edecf4c5,95c20c85,987e1beb,a79f4db2,cf689b0e,25aa9601,58316597,b06fd91b,426b5753,68a48830,9c3f6f34,6722b83e) +,S(8cb35a6e,248a0527,d572663f,7abc99c9,61414af3,f196c6c1,2de4dbf4,dd545c5a,4b32e4e0,47dacdb6,66edfc3f,a08d500d,c43292ab,f36bea7c,4a3952e6,680cfcfa) +,S(247c800c,f150c2ea,cfef8dfb,f4581560,84318684,430788e3,c8d99ccd,d27f21c8,cc82d8dc,914fd1a0,e626462f,5829eb7e,a708395d,db3e70a7,57942e85,1f1d0db6) +,S(6543d7c4,7fb927c,fb0f3566,6103708e,5e0c4a4c,ed202482,c9f48647,33426673,e252b29a,69b4ad75,814ae0d1,631ea750,20bbc730,3fdc819c,88d8f3d4,7907ebab) +,S(c4f11255,d81c33a3,a09da4ac,af5c9c16,d5e759db,2e1026c2,9b3556b4,c388e6d0,e2e636a8,1af48ab5,814e5530,e48f518d,95379eab,186e94f2,4fcd551d,1ca8fd49) +,S(cf186a9d,85da39b7,7383d92a,14af5a05,b082848f,c9e60598,1bad8ef9,5e019eec,cabde21b,c860fe08,53f672a1,64010968,6b49f37e,61cc642,48f455bc,b079e3fc) +,S(e6c3e353,ad69dc13,e595c2c7,a88b8fd8,fe9d1d47,3d45f7f6,be9ae903,86ea8f32,7d3becc9,4f455c1d,21610800,a4985f33,96b5a920,d5ed2b57,2107c28,ac690be1) +,S(3827b3a3,9bcb554d,54695dc6,bcf22911,d1ba01f7,730d1c11,8d6a7b2e,c1060988,32413047,b7c9ee83,1b818c5e,cb8f4c10,c800a362,419227bf,d9f50aff,ca25a211) +,S(ff37cd38,a4b149a2,a8dae898,c40b0ef4,4b55ed85,11b5413e,48f5608d,cc6d24fa,5e615919,8f4c6665,7c3a489b,86853a95,f3ffded5,20433cec,a6832cac,b9c49048) +,S(bdff4fc8,5b492fae,1ef34322,9e83b751,d9e53c7c,455141de,f68d3e8a,320ce509,e8fd9864,9dcc5d66,6155088a,29959e12,531f8a4e,44d70b8a,43b4fde0,8bde3d20) +,S(fd6ba29c,313ff2d5,7fb2719d,9018f11e,e59d1007,24146aef,625a9b3c,3bbcd0af,187daf5e,913310c3,39f584b,3196b877,5018dbe8,1e38abf6,de73e97d,f5c1079d) +,S(ea3c422d,48606929,ef72ae1c,3ac30178,4f4b5f78,1405fb62,1d0b710b,1b29ff28,e458b41e,c6c3e06f,c37637ee,fa316e25,d10b377c,ef99aaf2,564fef92,33bf208c) +,S(46537133,4982d600,8d228924,f0b459b8,2ba8aed,af1b3c39,f87053f,487b3978,fd96654c,13189def,f243bb29,e2143dca,3b2444da,3b895700,6bbff65a,4dadf3f0) +,S(fda493f1,1226069a,ac76227f,9f9e1051,b5b29b4a,a2d0f9dd,99637176,8578d8f5,5a33593d,f63d136d,f43a69d7,f9803a62,e04e55b5,25633a06,d8eb86c7,e1d46fa3) +,S(74fc42e9,5f09018a,5468e283,5ea36fee,7ab5e757,c57200cd,966174f,39f3e4c1,ccaa0b40,3802c914,da86204d,45f8f5d7,3760e075,4bfd10b3,2a8b2521,218751f0) +,S(98cec4a,997b79a0,cb818da,58e41477,d98f8c2,8140fbaf,e118bb1a,ec483d53,2fce6058,14945cd5,367b82fa,182c19d5,ac422d9e,840eae4,d81689ac,7eaaec08) +,S(c742ddb7,89a5cbdc,2055119f,697fd575,e4fa1540,96cc5fc1,3c2374b1,13cba60f,9b0af128,34a990e1,d402474b,e6dbaa1,b32248f4,f2b1d680,13fa0dea,46f3532d) +,S(dba2e04f,9a78066a,b5897913,6c4c7224,5b5973d8,3b13819b,77409fd1,e791eb89,34747922,3adb5f74,168240e7,a178f077,aa0e90e0,870456a8,89dfca5e,633baf43) +,S(6d4cae43,6e598586,7b984dcb,6c2472b3,6cc47f86,eb69fbf,1069c69c,42f6538d,c7fb58c9,f0c4f7ce,dd7c53c9,23efef52,125c2b67,d67f1ced,b98bb1f3,d5e0a84f) +,S(4c457f6e,d5b67b05,5b664ed4,3bae291a,9ec5b539,6fd9410f,9cc16a03,b8523982,492e5bcf,20aae19f,5462ed68,2a72827a,a435f47f,ec218e98,8e91fed5,20f344eb) +,S(4d7e6922,34778a41,f58033bf,d74ae295,51fd8ac3,64cd817,9cdd441f,cb46eb3f,756ec0b2,ff5c9d3c,3a453879,17ada4bb,6d7bbd07,bd10d2ad,c092f46,c62750c4) +,S(ac5be50,69bad479,bdbc565e,ab74ef94,4a48399c,a4af915c,fefc47e3,7d464b2,3246e3fe,bc5810b6,37722c54,69ce45d8,8bad5daa,529b4381,928b7cfa,de874345) +,S(7da88d41,21350139,bfe6a481,2534b25a,24f91e0b,60d882d1,5d69e840,da3995b2,9888ad8d,62a7a4f8,700bb03c,f9772432,6a2d092c,98adbeb5,cbc20348,f0b9c587) +,S(389ff31a,63239cd2,c9aa3eb,4d3ceb49,5d3b922b,5d137d4,e8b52be3,b1abf149,b0ec2a2f,bc840bf2,8a22ab22,b76c1485,42f54ed,5515ad49,dc3c0037,38fe7c93) +,S(c1cc1acf,5fb128b2,ea65afaa,d3d5736e,a94b2e49,8dfcf6f8,f3c27a5d,596c4370,8903584d,1986ad31,6cc6bf2d,aa2a88cc,ecfec6a9,c1bb153b,27c409e6,934fd38e) +,S(399ace52,b92768a2,a4740be8,31c96c04,2a34957,e91b3cf9,8b3518b4,87c9aa3a,908314b3,abdb3a47,a117ae09,5d609fa3,fd9af1c3,ca04a869,786eb134,48800005) +,S(69543fd,8c9d01a5,702d9859,305a52b9,470cc606,cadbc76,d8283ba9,ba06d0a2,e998e7d9,a0c372ed,2e348f17,b3298088,404eb1c3,8a901d1b,6f4e8a19,731057df) +,S(2172d54f,df9b46ef,5a1289a5,872b1c28,911e553c,f703ad6d,400b6af7,e8200100,2121b47d,3b790e5e,c820df5,772b226f,34a8fbeb,f642b5d9,edc18971,1b687a8c) +,S(f606f7e9,37a324e5,d0e6847d,24923965,cc27133a,10e43f28,6d45f7ce,9d5e8b56,70013fb8,622a21e2,d1337944,89324a13,f5b80580,91ca08d1,a30e7571,3e86e007) +,S(9f1520c2,dfceb64f,1f432013,b342af35,2f95bb2d,d49aa14e,dfcd8e71,7c40fc99,fe8fca26,feb1f004,8fa4fe3b,764a907e,d53dc0a4,10308199,6cad54d3,898e863d) +,S(6670af6e,7587676e,eb0674eb,75c93d38,53afe418,cb286605,18a9370a,231eaa08,2993ff5e,dfc071ee,97fcee9,bb12fd8,fb59fccc,524d8537,34ba4cee,4beb09f3) +,S(15c6d58b,345cc4bc,e4ca4e2f,ee954c2d,40650a4e,ad6c9524,65f59a94,b3898350,894c53b,47276196,65a0f3ad,f528d2c0,221b12aa,73df2cf3,a6b0e778,a363cf7f) +,S(bc4ab6bf,60dbde42,c9293ef1,75f85a48,adfffd20,960ea454,8a919977,75389621,fe28a0ba,24a4e2a7,45d6bb68,ecd71931,791a74,61549a44,37a34761,19040e42) +,S(5dab1c63,23fbf2f6,e495e87f,1c703ba8,64f20e50,4007dc80,54ef2e11,d3e6ee1,1fd0c200,cf4460bd,ae6db415,3e68bffb,e7f01ac1,6b30e305,9c134a86,52695d93) +,S(2df1cd57,d7357c44,7be28dbb,c339ceb,5cea0bd8,e702fbb2,dd67c189,6a8acaf2,33192011,20cbc8dd,c3b9c031,94db76f5,86eefa67,995dd741,492f425a,e2f1b9e8) +,S(2d81ac17,5a02daf0,83100585,ed2bac76,3d9f9764,15356fea,584ddef,60d9ab8d,f9908cd1,3b1785f5,78297fd4,9e6c26e4,21052e2c,ce9f51c9,cd58183c,2df9a0b7) +,S(1fac1762,fb732e73,2440d40a,5356eb17,67b1e7f4,f11e8db5,9ef90702,437dc097,edd5784c,a58d5113,2b5a08ac,e75cb30d,5ae7ce27,129f158,4df5d95a,7b9b8729) +,S(d06a0b5b,4694b90b,80c93e88,4aa9086e,45cabaf0,99b15a9c,c2b19678,38c8c98e,4cad46ba,2777b24f,cd1b391b,222ff3b1,14fcc814,5f78ada4,98620cfb,747def3) +,S(4928df27,590240f9,9907928a,cb6f0695,870059b8,cf9b1d69,29b152b1,7de53445,b773e60b,655b3b0e,7b0c400f,37dc336b,240b83cc,286a8ac5,3dba751a,3300d505) +,S(a61bcdf9,cd541811,4ba99261,7322827f,f945d450,c331ddda,1b8639ff,87a28390,3e771d6e,d6fdbb28,54601b2b,301fe24d,8e61b370,ebe644ee,b40fe807,b8d93a68) +,S(535a35b9,3e2fb7ab,b3b1228c,a7977,fb8e34c,107f093f,9f641b15,11db93c3,2471ff35,5657cc8c,38283fba,27c2e3c2,92475fb5,e8d52e96,f0c9fec9,b2ff786f) +,S(e68a652c,e0140f29,376888bb,c6be70b0,f23ad42a,d10b8acf,a5f790b4,c465d4d0,49d7390c,c368060b,3134ecb6,dad52120,ea6e0c7e,b80c94c,6cf9c1d,3c1a7385) +,S(e8939e7a,74dfccd3,ef17855c,3ea20e99,f5f05f6f,8bc4757,6b4f0e99,37e25fde,6b48a73e,ff0a55b7,c90c0fdf,449e4c2b,3773f454,da2c388b,3e0829fe,d661b173) +,S(496013ea,31451874,800fa293,a6e70ac,7fe16483,67c31daf,bfd00faf,48751543,b5715111,8790556f,8a4001cb,282b3312,581e1508,b8537f65,6142e2f1,ab8c4332) +,S(444735b0,b1efc3a9,56957a07,22604d09,bb0f6c29,e7cc5201,89ddc3c1,804b1e1f,b1ad60a3,461abab3,a9732a85,7050e55a,3e9a439f,32a5b21f,9aebe400,7e59d6e4) +,S(5805ac8,4acd7d5c,f85a40e7,4b9c98c3,e8882189,e77aa475,da3b4114,3ed9511c,c952923b,fbba533f,7bd70dcf,d8d69b7,1ad0022,aeae363,bb48134d,6a3c07c0) +,S(8ac11518,30fdc785,5e1c53a1,2b690202,c12619bd,c46c8898,dcab77ef,279a9501,29fb7cc7,7867fa0e,1d015493,abfb2000,d5deb3b8,ddb3053a,d59d6bd4,a9ca4fa4) +,S(aa47add3,e42998cb,68fc8a7c,cc7beff5,4d70226f,22f41ec6,7bd7b444,aab542d,cfa5ac81,ebefd98c,3af4f9e3,9f67459a,4f8e8c4f,c1959816,f771e75c,c43683e9) +,S(f3504127,a27a14ee,92133f75,364922b7,d3984898,e433d3e4,19e88db9,e599889a,f1af9f7e,9f9868a8,84ecdae5,47bcb886,56c6d423,a066b313,c09cdf08,601b45df) +,S(33730f44,edcbe688,35887076,69a989a6,272d3ce5,9261b98c,7c6eeeed,7e4bf08d,3f833928,d87716d0,4b2a32d8,1bd2d789,b6fd057e,cc70a794,8605cbe6,e1775a6b) +,S(3169d6dc,8c06f584,880bdf07,29249cc0,a33d417f,be137478,6e5b4a14,3edfb0d6,2a91422d,ec563839,ba782f59,68f428c8,a311600c,2fde77fc,ea163e86,aa74ce5f) +,S(d8c64582,13aae81,cf07a64d,5a8dc3eb,c8c43a45,d57f8e9,80cfccc6,f02a4429,c4873051,968863ae,8c92f195,c9fee3b2,c4773d47,849e2a7b,e7f48c4a,93822aea) +,S(ae67101f,307e246f,7a7cb039,5631b884,7e59c8d8,14da3fe1,7891f69f,402b6f11,f5f2dbb4,a90b09e8,b96767af,a9f9a357,1d3900f9,7d8222ae,e411e1c7,11ed44cb) +,S(a9e87231,83ba8338,1c0a7dc9,c81a2c5e,b4e2ff43,82574f0c,1a9d7f14,81dbd8ee,96810599,90d90e33,d69fb59b,ee68344f,333153ac,3d73a335,4b7ddd6f,96468901) +,S(616bf21c,ae7d40b,2694f43a,a33e6848,694ef879,fb5bc48d,ad141e34,e43376f2,bec18f83,2aa8a0ba,83245115,3b5a4faa,4a27725a,a3d9e799,bf05dc94,9880fc77) +,S(121e8335,601f33d4,78a882b1,1e9be5bb,39be47cf,701a695f,8d351098,af3f5c2d,2e992933,18faa04b,7d85fdfd,cbff81df,10dd070,4485b659,f682a298,4d03b3e8) +,S(bf884797,3025ca9c,9413948,fef1bc48,3a83cc28,4a909933,25c8c97b,b89f1141,1953a326,3d26d1d7,86d5ae3a,7838d125,6de24760,6abbb63f,e2713f6,6ead5386) +,S(7c28e9a6,5a3800f9,85c94d4b,ddc75cd0,dd1b06e0,faeda124,e86600a5,6af811f0,a3756db7,e339f03,8914cedb,707427b4,2d396fd6,f2e43863,13414863,8ab5c277) +,S(e5ec6dad,45e62cf4,1ccb5bf6,bb92387b,46be0791,31bc2b9c,b8b93172,90a66077,d0045ecc,775703ca,f854bea4,be3c4d21,2bacd092,7a210eda,67c33aba,e44f0e19) +,S(6fc96e1f,92039545,fb31c352,544a5974,7036263e,34d8e043,58336169,118c2fed,d032de87,1571de8d,96b0457f,84397e36,6ca7c20d,d90d089d,9aababad,8b8a9a51) +,S(89e3d351,1c219c47,42e79091,47c13146,1db684dc,e1a1149a,cf49115a,746e4133,aabd970b,672e8468,d84b53d2,303d57eb,52fde5bb,bb224b03,6892f918,630c5c90) +,S(2b7a60f0,b2136453,878eb44e,aadb8da8,c043e947,fea1de8,4ff8e18a,390d5890,c829b16,1ba032a0,59340709,1b38b365,b806686d,19026f41,ae8bbab7,d04a5244) +,S(464b9f1a,c2c2aeb7,e6f7c3df,a8782f25,bfeb9879,9263a9d4,2f872050,6c9627e7,7c260bf4,59e1bcc2,df7761db,e503875e,9a23a107,6cb4e8aa,dac5b5b5,b6f7502c) +,S(79253e30,43572295,e331519,e774b670,b25141a,986eb5ab,268b63a2,759b616f,da609d7a,55b62353,b20f5bae,969665ca,ed6467d8,f2577f69,10003586,e27f88e1) +,S(634287c,e900c0cb,5c2b1967,f55190f9,19acb09,43596773,87642d16,dd399556,a2350909,8cf01601,30c042db,253334ac,223c473e,312bf758,1fcb461a,c3debead) +,S(761121c3,8bd8fd5b,a3418557,f6a75b42,d7ef2f4b,91620223,3587f183,421bee98,4014715f,f9c17435,10e6eeb0,1bb29226,76070e34,afaed040,5c897bdb,52dd530f) +,S(2618c8c1,bfbbdf1a,59da3078,4e50a2b0,77990fe1,c2f074b3,e63dd606,6d453413,ae539a37,20f5b6ab,18ce584b,4ea3cb46,4bdaf35b,326fdab0,58169ddd,32a48da0) +,S(d429fccc,10c6f025,fc7a57e1,949308b4,d91699b5,c099820d,ab31f1db,90f685be,da2b15c1,ee155918,de414ae9,1be51688,a8df043d,6fb6c964,689bd4e,5a648edf) +,S(6a18e3c7,c04b8cab,36e07625,ba2daef5,bf1e0cf6,36650b6d,56dda8d8,e4e8b705,66291330,f56c96db,ebf9c9da,bc52541d,20e75440,25fcc49e,d6215d8b,c0e94eec) +,S(985b6846,d1c9f3fe,5482fa4a,d6a21c65,d7ca3eff,a41b3220,1a37a122,f8f97756,3e2b23dd,98e18f6b,76a2f2c3,2c543f8b,bb9dc6c0,8d391592,d56f5440,aaa3a92e) +,S(948a0ddb,4ba838a4,63eee339,5c7bcca2,96fba8e3,9654ff33,55c9296c,9e6e8c64,c5b34c25,da19d83e,b67b69b5,2e527d61,c7b705ed,2f794d2e,12c4325c,3cf5c1d8) +,S(4332d02c,1332b03f,b7a46b47,e82617b2,a437fcc,694868c4,256aa40f,a8a3de2e,e6e5196f,5f9c555d,a94327c0,39411780,393985ab,73765de1,e1bbe0dd,8aaa5289) +,S(5dc977b9,2ac1c895,f3150b68,a8d69f5a,f7e12dc5,6b211d96,a67cc3fb,722a5aa3,45888ca7,4bf1ec9e,1cbd2912,3cc696d2,83260c34,3410217d,10fd0b95,9d07844d) +,S(5b9cf534,ca94f124,a9b0cb6d,f0003924,605e3bd7,d063a2b0,c6e1a81e,3fd15764,44e98dc3,b0516ffe,bda48790,fa0b2d67,f9ba4b48,ce88bd1d,d81bcbc,897458) +,S(84353007,3a63714c,7d26baf9,c895e2de,e2feb4b0,9746ca66,97fd7ff6,d5372f59,d7373a9e,37689d44,4cb7361c,f2f3452,3f9fea7c,826c62d2,3ca3f368,b0c7a175) +,S(9cf0000e,3eef9b5c,89c8485f,c3826e78,8f1a28df,f8746619,804030fa,c21e6a61,2b3dab3a,d8684b2d,94e1fcb9,d2005c20,2764cd76,aa91e0a1,ac2612f7,fe91543c) +,S(bb292fdc,5897188e,20888b25,b491a757,8ee02853,83aff5e9,99671a24,4ce1235c,d3b6d9c3,50ba7863,bcb83990,95893348,d5e9b8f7,27e1a3a0,9e02f59a,412507e5) +,S(95d6d1d8,9835ed57,6a88a21a,9239b623,efd2bc6b,f27c5ced,2d770c90,fb7d680,c91535ad,39db65ce,fab4ac72,f3ce692,b39e7d38,c72ce468,e40bfe06,6cbaf048) +,S(cbe3f20f,a164ec20,9c2c3fb9,ca0c95,15ea3787,df2c8fd8,9ee50a3a,85d09a46,cd589754,faea165b,48e22280,4186e6ed,734a2251,a6588e8b,8252eff9,afb9a28) +,S(3e01dab9,9bab9e20,59b1c215,ba67835d,2942f4,487d6094,9f39e293,b39f604a,b41ddc32,33365044,ee350979,8679f3e8,d0a556f9,e8b6a267,bd5cb5e,8523d481) +,S(298974c0,5543dc96,15f1cfd2,e4b6331d,c798918e,15e3f350,97213a64,76afef7a,68018355,55f2d8be,a74e02e8,747f60b2,22354ea3,62cb657d,e5cd8060,7a99da2f) +,S(1d70674d,54763c96,ea3764b4,641d14f6,2aabdec8,a093c3df,d936793f,511fdc61,9674adac,697e44bc,6324378e,59753f42,80774101,623dc10e,8a4eb4be,38dfe632) +,S(75220107,b43ab970,6261875e,c8f8b634,73c47aaf,91ab8fba,cc0b1c4f,40fece1,29094e7c,c3bf07d0,12aebf2b,fb56efb8,41bc9ad5,9c350b7b,885602e,a3aeaffb) +,S(cfadb9ff,b3474ec3,27db31aa,b0bac83b,fc7f4c8c,9d0efdf9,2e7e7922,f779720,ffb7657f,6f7b8cc5,78f22ee0,2a99fa82,97d41806,cd2b8b06,ab00b993,d9a09b2) +,S(24ee919d,be3c5603,adee46e1,39d84aa7,34a7b4f4,d7b826f4,64ce8b6b,c1cb828f,44039756,794b547b,9360b63c,539b8f11,ca651476,ed57fe29,364a5ea6,17ff1506) +,S(5995e246,2f755256,f4d6b8f1,a5cbeec,c50ddb53,fe4391dd,1b530eff,7cb100f4,77ddda7c,7da05165,c46d7ba2,40127ff,fe78ac6b,13dd018c,e08161d6,d81dc64a) +,S(a7233471,97dd478c,e129fa20,59193c08,364f8c37,1cf19c2,9dbd51c3,234d54dd,2c4e695e,ec2b2ccb,384a5fa0,1a96664,9cfdd711,1a1d19ad,92f2eef1,31796e68) +,S(6466ab69,d5bc21cb,d7e75fcc,5de9fcc9,a57cfed6,3ad41c23,4ed56cd0,132251a5,76e7ef89,6dbb16e2,76622f5e,5f6894da,2e0c1ecf,c4af05d2,990dfa4,25294dc9) +,S(a5eccf90,a29388ab,de6fca2a,bf216145,7fab8bb5,1e33d4f1,1e0acda0,f5c28e60,afd75916,468a11f3,73e88643,56690adf,110e74e2,c81123f7,94805b26,620e3ac3) +,S(4251bac7,493678d9,f26e52a1,e3ed9e58,6a15d060,4d1c9cdf,89ed5871,ee9c2779,fa1df27d,92e6716d,76990c60,e6603bcc,4bb023c9,dff938d,3a15ad8b,72987aa5) +,S(77a9e6a2,4c3cc21,d8cf6b97,3181e283,f40c9d0,26a81903,f042c2a4,fa7db30e,a1ef4fef,23f25ccd,bddb757f,aaa10ccf,e78d9310,72b2f180,b6e3de5d,18155aa0) +,S(33fe7961,c40d4e1b,d6ade73c,4577fa2a,e9c0d20e,999f639d,e751ff7e,6fdbea6b,91b7d5cd,4eeb306c,e316e7c1,464c30cf,9a591994,7232b037,5840b8c,d5f54849) +,S(43f66b2e,5ee52211,a48a9d8c,b485be2f,39535701,5249c311,5b682170,f9179564,5370b55f,fec0ebbf,c30cf7f,e63f5f88,3555e699,728e6892,1dbf7874,2da46a45) +,S(4ad36614,97ef1074,d74c7f6b,446ea87b,ad2f0b43,73f5970e,1a745b6c,38b19bfc,8f5dc1aa,769a5bfd,5eada00d,436f850f,6f9eea82,329ebcfc,cd4cd60,ef5cfd39) +,S(9799aaef,95204d54,f3734dc9,75b797aa,59336866,9b2f12f9,155d5953,c012754d,4b6b34a3,d31fe173,43a5b476,bc492d54,44c256ec,ea236f3a,9845a875,e83e6353) +,S(c86249f0,c6e4635c,2d03f252,50e35d67,c1c22f51,6f9a8dca,fbc9d41,15d828a1,e21770b,37dc4d0d,f4d260b3,94bc76b2,46523893,469f1025,86d99467,ee95ec73) +,S(b48dfcc5,de5687ef,c7282c84,cfd4060,61a08fe6,92fb08e,3accdc2e,6656038d,87e3e1f,ec737074,71f69c7b,c7147665,c0b52a95,37ad1566,277b6d19,fce8927c) +,S(77dceb6c,62d65535,c625c828,fd3836a3,146fa4d,36732da8,58503fcd,4e357fca,d90b2600,5a139713,525b8521,3d370ed2,4304d08c,87fbb67e,9091d1ea,18228bd4) +,S(5b588cbf,4cda0184,4df1cd63,3cc70ac8,69cfb43e,332f5c17,47364750,3175e49a,1424ef1d,f9e69e4a,84eb823b,2f95fce5,a52e1978,474697c0,d47890ca,fad55cda) +,S(c087bbba,83934208,8c70251,8c9ddd93,2c50cea5,11c443b7,da107685,9320b20c,77f26a69,717555f3,b030e345,5cbe4b30,f637c23c,7ebc2b5f,6ec2207b,9209d996) +,S(8d16057b,68f8082f,208b3e7c,fc2c558c,247d7d60,f117ea38,35e474c1,3031ed94,3d305db6,62ffd13d,100f6e0d,19c439e1,6ffb8ca7,eec6b14f,ed551091,d6ba3eca) +,S(75fee0a6,3d32bc8,6dbb8cd2,af7371ff,d17daa96,5e1e19d9,242fdcc1,edc184b7,c2b1e4ff,abc30975,fe7c992f,f8091795,61ee89e,9a040409,10bfdc64,93efa2f8) +,S(65da3959,b147093d,7d092599,a87710a,dda7fb75,460e47a1,10d5c1e2,6f368abb,3599e1f5,2f92c1e1,c3f2b463,d9a30230,a6f53028,cbae3ce9,5e345c5c,21862844) +,S(6561fc10,94632125,d76b787c,a7539870,5dda1a5b,f4407f4d,f8140b6f,967933d3,4c06c7ce,a88e2828,3eae8aec,ab6e8802,cd083f37,6d3a1ad6,29fa9b55,920e6337) +,S(c9a53f80,70493701,523041a6,a9d23343,c8a3fc30,6664d6a3,5ca5e7a4,80c4410e,9af470a9,b2e30d45,ebef0dd0,6e3b2736,369d4dad,f2366d42,18344a22,b6e4bf9) +,S(5c1525f3,443e56dd,b009f45a,1b9a1540,c203f814,5f577bf0,3c734597,33b89158,967892f7,cb3ed91a,d74f4c80,3625707b,58574afa,cb99fc02,f5b3493b,eb4f4f18) +,S(3565ccda,d87c171d,714add6d,472fee0e,69bb6ea9,75f61454,d69939cb,541648ed,9f7d87bf,ec2b6358,5dbd09bb,d008b197,4f02d3a7,6a8d54ed,d486a2d9,3462aef8) +,S(4003ef34,c0f5e1a8,afcf29df,42a14a5c,4527d3dd,138b5eda,bd8de661,1d0e3614,67203152,44894cef,cc3d0a76,35839c2f,3d3ead0f,36174e2c,d3c4c682,4c3048c4) +,S(f5c4df5b,37965079,3ebb7de3,9b495a26,13886422,929393,1cf55d1d,912ea57f,b0b93c3e,12a98cc4,5a3672c7,4a3610d3,aca34da5,7d31a968,f30047e0,31eb3482) +,S(bc9f680,e21186cd,ba63533e,56580289,cbe8698e,69ced0b3,97a96793,569e213a,6adffb78,8105518d,50fb94ff,87d204dd,7bf54ef5,b91e1d72,713fa9,b32e06a3) +,S(4dce8797,f1fe8811,453e15d3,7a3e2621,549e8347,4e7046b0,55f99d2a,c9a16516,ea5e6b77,cca7825a,95cfd9f3,7d70d7b2,fc8a8aa8,749a9d43,37ce0754,abe668ea) +,S(f49b5aba,1ef29570,bd72a0c0,40009382,af2a4f85,26511eee,81869d3e,9759b16b,2e496c20,b996e8d2,696125d0,f60abc66,1d2fb343,b4181202,8658e459,d57c7f7d) +,S(26917d4a,7573e1d2,7b4ff765,72bf2948,a2d02f07,7d7d7fa0,54a1bee4,92125ec,b8e47f7e,ae9b66a0,2a6fd2d5,cf8c88c9,7eb12530,a618678,ad5ce83,7cd8f97) +,S(1b4948d6,285a2fe4,98cb71da,f213e6d8,7ead776e,cf8bbcb1,cd7faad4,fb29d290,1ab4081f,ef87d925,9b736c7a,92d28618,d5698499,b2f5e27b,dd30c1b4,24d3bfd8) +,S(14d712ec,8179baf7,9dd9676f,ea99653c,f8b20ff4,a69636c7,7258bd57,99ae64ca,2e1db8a6,424650ec,32b0df37,d72ce3f0,6f38538,53bafad6,d366e04e,380c6ef0) +,S(7675220,41747684,9e1967e1,54445913,a1111988,8b5bf813,4d9694f7,1d952453,3f1fb063,6457b603,3a155a90,6a722de4,de1a5c3d,6094dc27,37776843,ed82fd31) +,S(5ac8e534,a8828b67,40016d02,80bb1e26,a53b16f,96b24937,fc84ba34,dd49fc63,193d020f,68f5fb7b,2c5a429,6909ce70,18568f87,115e987a,8e5e206e,b8a1fc73) +,S(87cddeb2,8d16562a,531135b6,193449e,d618d0dd,6acf6c43,3372202d,ab4a14b8,5c1de4e6,7c958ad9,9411cecb,de2e9129,cd709425,135c84b,e5b68cba,9f846e2e) +,S(c431ca25,a39ed09f,48e1dfe7,afa86630,4d4f8b7e,eb0d6d52,f8c778a0,424c84cb,450607d6,5b2dbe6d,35cf2d11,d3129330,489eded6,e35ff429,2aeae0a6,7100d825) +,S(8c5021e8,985c1a11,4bfaf3d4,40edc4a3,aaa93002,5c2f2c1d,9bff3683,88a3dd5a,4cb960aa,8077d81c,71d74ba,6096fd4a,b6d31fae,d4315db1,3c2b60aa,a12fb108) +,S(338e54bb,38a47485,8c17c07a,177dbbf,6e7a14b,26781bb7,70b9d717,6e513d4f,7876ae4e,84cacfa4,c22951de,f67763ba,c44a6ad5,52ee66fb,92f80cf8,c4420548) +,S(87f3bca9,efbb3a21,917683ab,ccd268ad,3c7b0fe1,7eff461b,cb06ee8d,2f1f3c5a,a7a1d2a1,ecccfc54,4881f258,bf5fbbc8,e5cc11f1,a117c7f8,361a33ed,55229b61) +,S(f4023df,8ed85856,8e56a037,5a6a78d8,de27d6dc,467c9aad,52407bbb,413a3e40,b2499142,fc4e3a11,6aa30e56,6d59f373,d5e2c545,3e274161,5cff9f6a,1fe178cc) +,S(cfb51fc6,d55a8a22,89d3d282,fe63b2fb,453b512f,374e01a8,92708564,9c6f2d3a,8d4a3223,283811ed,28ec120e,761e61d3,e4ea5312,1cb2525e,b567fe9c,9070635d) +,S(59a44a0b,97050147,bf219db,22249635,c45f77b1,1721c486,8937ce96,ae43c539,31e1ca6,6a910f3f,1de1d0cd,55eb8a76,400ff959,13774efd,158d931e,7039afa) +,S(b99cee56,ec277a37,6ab44628,14bb3a8e,d8e26d73,19fd786f,8ab570e8,28a8ee7e,46e0f398,dda05d4d,7253b16a,b4d80c14,b6be5d31,d1dce230,62ab1135,c23494ad) +,S(a39e136a,d96b1a22,6d039872,5da75b38,1c6b922b,52947cb0,25207ad0,d172bd2,7a5c0758,74de08e,3d10fa71,79639fa8,7dbfc977,8af1a3a2,d910a1b9,b6abb532) +,S(6e8b4125,3b2eb74e,626dd59a,eb7512b7,2c23c855,35f479c4,5b48d974,57001976,cc0b88e1,e4e8c045,5e804068,acb85aa2,715bc82,ec21ab47,873999e8,cd2bc88e) +,S(9942b6f5,681e4189,f7fb6ec9,8efd1343,cd1fb66f,1c98e418,9c44478a,51abb019,200d0ebb,b0cc2d52,90a11e6f,f7c989e2,d2fe986b,ed266430,56951679,8d0e7a9a) +,S(7fdce1ec,3c57b949,44166918,b48af352,759636f7,2eafd744,642e0f7e,5078506d,d7785aef,c19a76e3,73b786ed,1e2d2ce7,53cfb979,65d3d46b,2e313a2a,d7baabd2) +,S(6f13205c,958c83f0,f170906b,d77c79ab,5f51654d,88195b04,a70d4e06,93989c57,8ac9a15b,b386e483,b268d4f1,c950da35,33deb99,55116c99,e848f13f,73b55ee0) +,S(f955a35d,833c69be,40a0665,f4dffbfb,cd405f4f,5b4247e6,e50cd4b6,3697654e,89f4fbce,22468389,a4af2407,f40eb37c,f56e80b2,7da1983e,4e2fa4f5,8bc9ee44) +,S(dbcd152d,619646a3,42a25743,1df9798d,b58b8d1,89238132,e65fb6a8,26248007,66fa717e,c1948fd3,e4425e9e,2e6830f7,e57d23e3,d0219dce,c02b4d36,32d8ba13) +,S(f1aebce8,e57b909f,ac7cfb1d,a2e7953f,99f713b2,8b35b5cc,71eea153,5e6e8ebe,8755fa14,3e77e5aa,60dc24d0,92e4f596,88b0bfd9,585fd57e,1b7f610b,e5d9d516) +,S(a202164d,941f84bf,f89ceab6,50430905,c002bc5a,91d505f5,fef6e48a,4b55187,e0cd42b,2bc268b5,1e572e97,8b9bce4d,b6d4b095,ade884c1,bee3b3ef,c2f057ff) +,S(572e1657,46fde7de,9480eccb,287f8b9a,b1344da5,8026861,e784047d,ca8ad68a,c174ade7,c066abb4,8d2461eb,405dad76,39eda86b,a0fd170,47569617,31eb5d9f) +,S(f4e2c907,fee4d753,c08b1052,b76e49e8,b67047ca,59e64dac,58acce9a,5beba31d,b243aa2d,3a92d2d8,e48b8317,ca8fe897,2b76d134,248070f8,f41bf871,2c11c42c) +,S(a6fc6aec,84455716,f5e9e436,d68809b2,26698781,f24d0463,e06963a5,fdf06dd5,dc16a615,548efd18,6ae135fd,f748d9f0,a96b7f4e,918513d5,73900aa,1818ca8d) +,S(bd806817,5fde9652,9ccd8eec,937f2cbc,c4ffb3ce,b04cc9bc,c00cde2d,5a05f026,b2791ae7,8e014328,e0fe6a0d,8b6bddc6,db048274,5152bf76,bce228b3,64a26216) +,S(f888a667,6f8c3d20,b9d5e810,ecae6b8f,2d8614b2,3a5da51e,16386dd3,5c0165ef,fb4ee20f,e429f3ef,f6f4bfe3,9c7b1ebb,57978853,de242239,42a3dadc,909a0dea) +,S(7c8d1e05,5adbaa71,ec9023a4,8d160fcd,c3182ee6,bda76fd2,3ba8877c,409ae200,8a3b820b,ec595523,d96936f4,fce83779,c489b9a4,f2c8c524,f16e1764,2f907ceb) +,S(18886ea4,ee257120,610ccd71,593baf72,6dfd9bb7,5229959e,75c14e76,26fabf43,266c6695,f57068b0,d33ad3f,7d02b7a,898a3184,39889d31,ffa98d86,e091531d) +,S(fea70f1e,38c8adbd,3339a44e,cac036b9,1242a099,506789a3,184fdcfa,6be52cba,9dff6df5,ba8c1b9,ddc58093,a36670b6,76c0e2f,d745c468,83e26ece,3b9e7915) +,S(4de30389,45aa3c90,76d99142,e79451b8,96dcbf7b,fe420c8f,b1dc4b4a,37d1365a,cee74e9e,9093de64,2401eb2e,201b3377,992ac0a2,13b0b16d,35664ed8,d287cba4) +,S(67d09dd1,eafebe79,c63b8c40,1c102982,8c2d8e6b,6b5bfda3,73988830,1a104fb2,10eb5508,92660d96,8e99049e,818f89bc,d4f03558,d9f2c984,61ffaa5b,bd360a5f) +,S(2b5d70fe,186834f8,d3b96d4d,87031cd5,325e55f4,ffa31b5a,f5ffdd77,40e6010f,646e7e53,24d2a373,78b1f54a,fb2081b4,38439890,c9f53b1f,7bda4d47,a895ed02) +,S(cb426299,8700a76c,193f7b44,6aed0ad0,5d600b23,ca24c752,527f62df,e17be248,92843e13,f3eb60c9,e5f74eb,8cce7723,bcfd0250,4c2186e6,5ace939e,5819a8b6) +,S(3ee6ab7e,75b3bc57,135ce4d0,1e6de88b,22d0b853,fd8e0d25,f9b04ded,418e4e41,69c83f98,4e52519b,931b6afc,933f5200,6ee1ab4f,680ee768,9ad55368,1b4bcc87) +,S(583774b0,a95a5143,17232df6,f17d7829,6918acc7,2a385724,e904085f,c887e7be,33bb1e66,ee8cf17,30c16073,665c353,f8f047fe,150b4424,18c736aa,807c3e7b) +,S(af32e1ef,39822787,79082b77,2a643ea3,eb334100,9a7a3fcb,a8838e0,7079dc1a,6985e28d,c660123e,73aee7e8,b1a36697,16938331,e4b4b7f8,b3a9ecb7,4e95fd4c) +,S(6edf7fdd,32667551,9b60c740,efbfc3f5,50f7249c,deabbf9c,948adc16,e034d0c4,f08c5f18,5def7da7,5fb0de81,9b092691,64534f14,bb7d96d4,bb4513d,ef46026) +,S(3b9a6645,5d268f94,6c504120,a81821e0,86257a60,b3fd9f00,72a0a4f0,1f16b42,ed583a15,aedf6c08,95f60109,6190106,3dfa4848,645b0117,e2e1bddd,2cfe7c7b) +,S(bd035b08,2b5cfdb0,d17cbdf0,7a012b0f,27b52943,82e8bae2,d683ad0a,747a1039,6494cbad,ed4ad7e8,aa135ccd,572be8ac,e94a23c3,8b62bf61,ac90f9a3,9bb2ef54) +,S(e25fbf19,fe9b180b,ae3316ef,89e0382,4dda59b1,41022ff7,a8c45b44,f15338c3,45ec47f6,58a3dd52,34241258,1852e694,7c2c8f11,9f4fbbe6,f6388363,174c7cf2) +,S(2e231dcd,8ffd7356,52ebea7,50165405,f30f595c,3871ee6c,7c072e64,ecffc9b8,c664452,db15961a,8458f3d3,ea24ade2,7610d4cb,ee51927d,29cf3164,6f59317a) +,S(7c0f29c9,3932626f,1b1ae126,316e065,fd2a4174,a66a6048,3b458660,f5338fc8,27ef533d,df6f1272,c0255d7a,587f56a9,b76e2c4f,98c98162,350233ba,75cd037f) +,S(e702d61c,ea6f9fef,fb43e014,4794fb32,7bd857e1,70b299ba,31bb6a20,7cd5bb48,c4779881,c924ee3e,7f228a71,2de07794,ee5e28af,ca63af21,12ec0eb3,1a3f79c9) +,S(f1780044,eadec1b5,bee75c11,7c1647ed,c362c5a4,35a66d8,cc2ae45f,66c852a8,5f8de9f0,f31b3977,f08f63ac,1380310d,e8b7a304,85c9f0f8,9a677572,329e1c18) +,S(7a41b37f,22ec5b18,d4952c53,326665a5,1582ccb7,1660b69f,8d00701f,1f12dd9e,8440be13,2c57259c,80cd74d,2a2f1e01,3448865e,2429c2b9,db750951,607fc443) +,S(94fff7d,8111d69e,198f4e16,57c3551a,a5ce6316,d520a779,ca4ccd0b,282db6d3,482c9270,26c0c05,578a75d3,8b1d8ed7,42541d30,3a933b90,9c3249bc,505c6fc0) +,S(d6a6d44e,8a3ffaa9,56cac76b,1b05a4a9,d3775989,2f70e560,a54c9440,17f4e9d1,48c3bb22,cd839de9,9163bbe7,83a8a057,c7b93e87,de388b6c,dc57ba57,90863e1a) +,S(cc0e25c0,8e24edab,1e5dbc47,71543b92,c47c0993,95b93d53,699204f9,50cdf80c,20c52cb3,7170cf3b,43b76ab2,cb4a6d3b,1a977c55,2431b8c8,220282bd,51fb70b) +,S(cf953f68,4cb7d1af,a125d0ea,cfb83cb5,efddb6a4,41079be3,db72573b,62f8d827,70cfe366,a45d11b1,a847a7b,8e3e50a3,b302fa50,1afc89ac,b89eddb,30909c0c) +,S(1ac22694,2b34ab06,ff16b711,2fd5fe1e,f8ce6975,143ab19f,bff99d6b,6815d5dc,a43d457e,2bd0975,4e9b7fdd,d9e16681,1bd823d2,24476615,4d9e3fa5,ab6539fc) +,S(d02bbbff,1153804a,f0f800bc,f959406c,496349fd,a412e9e9,bb9f7232,7a4d65c2,5de80de,3c7832f7,1d744f9b,9ef08b56,d41e682,1c20f2f2,876fffc1,b802a384) +,S(3ccad347,8d464ee3,42e1cc2b,2c4b299e,d8a60326,4837a040,25a8525b,4f1831a7,35ea2a4c,a59b55b6,ac79fdd,6ceb3401,47492f3e,49b5035a,f3036b26,d02691c0) +,S(eac4d554,3e69c3ce,d762e90,fff84b3d,b3a758b3,419d06b,80f7ba43,36033688,aa64fada,c54374bb,fe8449aa,ddaa1846,ee00fb6d,c9435dbf,17f6a12f,d1deacbe) +,S(3d2879b1,73d93713,3326d0c6,133be281,5df62465,d3dbb7a9,a028e0cc,63fca753,576ce64d,9b95b5e8,a9e3eecb,34cdb8d1,fd38a08c,2a6a8c9d,8f0a7296,68d6e0f0) +,S(3f58ab8d,56a9682e,25137087,ca8c766a,72358a56,99ebbce4,cf74e304,6976ca14,3c9053d1,1a2a8a8,1f30f45f,1b480dad,f6bce20a,15e6315,447405a7,b321f29d) +,S(4f5f1289,b48dcd19,41a9df0f,a8aeae42,2a4ed913,58845b97,3145ddb1,13fd12d7,b5c3e32c,c40c6577,3e286ed,a233ddf,42ac0d6a,5a3c3e86,77f8256,e0dc1428) +,S(a64a29e2,a52dc6fa,e74e70dd,da2bacd7,e4a9dcdf,f9a0bbc5,ad0392dc,93376a76,ade2f8a6,faa9b1b7,7baefe87,33ddc365,c776f2cc,b0e5730b,4ebb0166,418a9590) +,S(dee0aa12,c4d6f88a,d1d86f94,e1c6d3e0,b8694b5d,e234af04,994cc7db,c8480e70,cbd9acd4,cbda37cf,a9d368df,332d30d6,413ae1c8,d34219,3d4651f8,62f93389) +,S(8677a99d,c8af6ae1,b653e294,80eb66fd,772b958c,882fdf74,f9c0f188,d5796936,31c668c8,348c048e,4b7a24f3,a0861f44,6621151d,4dc3e9ed,783eaf81,ff97232e) +,S(51117d3a,cb73a7cc,2b229bc7,9bd6d676,f44aedc1,98cedd80,ed6178c1,f6997fee,5c638c04,123f85c1,170651d3,96343e,78f20770,321c1a4d,174e568c,39110cd6) +,S(48d8af64,69670828,e87585d4,52ea1242,a83c9f8,3423e468,9c3ca383,9f141b12,558a8f42,f07f49a7,c6a9843b,9055ed05,1998dd35,9406c40f,dc4d64e3,5265e9de) +,S(62ba9ac1,b0fdeee5,a143d457,41c164e9,d4060c7d,f5bbb17a,ecbe80f5,f6966d2c,65a0653f,2290416c,5fc96494,b70b3b99,9329fe67,3b034aed,b586c118,a5d9450e) +,S(be4df7cb,679da56b,50ef2058,3c79310,508d8d05,43f3004a,486297d2,49febf0d,c1b56550,dd5f3e7f,a898cb8b,aca88694,ca697306,fa3fa09,95f6c43c,d5f3ba9b) +,S(e49c036c,cca2e068,5acdf34,8473316,424eac2c,ce1550c3,a0c435b0,28c9979d,456bc25f,457fde5,5bd0d273,d27afd7d,21186b1e,3b42bbca,b168992e,61609a1b) +,S(ae6845ed,a81d5d90,b3fddfc9,cb774c2a,976e701a,ad5c1302,7057a6f8,97fd58e3,529bdc55,322ae360,9926194e,7539a534,4501126c,e69b3e11,e5b4a675,7ed755bc) +,S(52a1d8f8,bcc2b772,cc8717e0,2d713864,4c274499,4a19ed18,3fbeae31,bea25e1b,da2a0b2c,e7f17894,848e77f9,53b7528b,dbb80673,c70341dc,9f869e60,4189011b) +,S(ffbbaf01,d89a7804,d5d19f50,dd5a4abd,cc5529c,90d26918,425f3805,96a2250a,88b5f7b7,eba662bd,5aa47a6,c2fe1322,2d514410,f6b1a145,38c37ed9,9a9880e2) +,S(6ffa438,aab51ab7,afb840ee,d4f85725,4473fbc8,ff6051f9,fe5a59e0,ff8c942e,5b0226dd,3b88a040,33860dc6,69613bcb,50a0e95a,2ac7df8e,66884c7e,e602d775) +,S(9c895658,f92ac47e,318f5ee5,91d26a10,c2c1b77a,c8bc8cb5,a45ec943,8a2fc79,708071e2,665ebd58,f1655e28,6de258ec,ef4b0115,ff74f38e,516acfa9,c01045f9) +,S(532e6e0d,efba35b1,3fdbffd1,8ebece3c,a59bb3ce,54fbbb5,df1df6f0,c1861ba9,1af465da,d326bbc3,eb732ed2,464b4593,36f04b0f,a50ba7ff,f61b4754,aebc5b8a) +,S(99043321,e3f27092,cdadd8e,b50cb4a3,8a8a9f80,83da6ea1,38d48e00,e5fff425,11be8597,325c250f,d9e5b1be,8e52c336,404ecb24,df29b786,ef9d1f04,8f77ea6f) +,S(96799080,3a0934a9,9a0a6e94,120c22bd,7d79085c,c331e172,87daf46e,7c4084f9,ea90012d,18450bfe,6a520b5c,9b2812ee,574903aa,d75cad04,7dc46c23,98005e03) +,S(74f5d157,915ffe10,cf6d9981,9eff7616,1f36f71b,4fc386ab,729dac37,3aa0afb9,54a0011e,4922bc74,12ae225c,dcc8c447,4e4ce4a4,941a409a,2c49d421,19b29eb5) +,S(12692753,81c63955,5700ddeb,e8d7a751,76e5f3d7,2aa0631e,3e7cd6a8,c1927855,b92e5076,811002d5,44c554fa,1e1d10b5,3eefeffd,513357b7,2c5e0cc1,c39ae553) +,S(84ef81b,1d143d73,5b6ae35,af18d810,d7cdcfbc,dd1c68e1,1aae007b,80230d9f,cae39a2b,a5b4ce8c,21ebcf2c,638a2e5a,b0dda645,aa6e01bb,33ca2edc,b575d42a) +,S(1c22ada3,326e6ac7,6647af5e,ed62a85,c8d89dd2,a733ea62,dd71512d,ec9037ad,f5a598c6,1562a6af,99e46283,cb9e6fd4,bc4142dc,99600b64,49304981,16aab458) +,S(6b91ca4f,f08eabd5,aa8dd35f,e9e04153,c00f1f48,50bbff4e,73671cc1,fa4aff1b,c6cdaada,85adf99d,4fb68c8b,6104f585,b3c9551a,7dd87977,8cb250fe,11b31852) +,S(57bb4999,6d2e2157,613f0321,983736e4,b99063b5,e8f7188e,23f7895c,edf85bc2,93b46dc6,72eea90e,9274b9b2,73a82da,d0a1ad14,55b550e,94fdb765,ab47cc3a) +,S(75790b27,ebf7566e,1056d9f2,463df8f0,67c38a2,78af81cc,b40f5260,4a33ba6e,ca0c8ca3,d99b0a5d,b065decf,346eadd4,3af8dc71,9ae06dac,6be99c5c,b89d2045) +,S(ca7a75ad,a90b590b,f7f2b6fd,e3004a1e,8dd7b4f4,db8c4a08,f32bcbb5,474ebe9,b3278d9c,5c9351e7,bf4e8a08,e0f1dc00,51273259,acdcba1e,fd3ded69,83fc69e3) +,S(a6dc68b9,3bf46294,392a8d6c,e52bb365,47b65a5a,f318765c,7a4f5d5,2f90b2d1,41ba6d67,fc575561,a0f3c76a,931dc62,37f53348,819224de,8f925c33,c90ad45b) +,S(da2139f3,f8afc90a,c7f5a025,20c36110,2fafed4c,3f525b56,fe0dae1f,6bb6bba5,95adcb88,fa9ed816,dc097522,de5a394e,71e92c1d,f5bac36,9ad06067,1b6349db) +,S(a32b2475,2f0e0063,acb4194b,faba9ccb,2159357b,23f102cd,f5a8e24f,413da4de,57df4143,bd8b27fc,c7716ffd,8c35036f,e09f8ab8,34f053db,ddfd3161,ebe576cc) +,S(aaea491d,33824ff3,c7319d8b,a233c73a,741718f2,2c921392,b893894c,ade9bedc,c8fb291,84d8dc65,93a6a3a1,a5aed86d,a7ad0d32,d5f8ef4e,b24b6154,4c1a63a7) +,S(2935e0e2,7a8409bd,224f3eb3,d68fb639,ccf75d5c,2b0315e7,ed388acd,887f2c75,c4ff024,62c9ae40,983d0068,180d4c3,977e900d,fdfc164,c89a938,c568aad4) +,S(7fca8076,9e2e7253,5834259a,abeafecb,fdebbd96,5066181,63d244ce,770fe577,a3ddc3ab,f04ded22,cac3b8f6,ffd14ffb,69cfecba,7dbaeed9,9a5e13cd,55bc3542) +,S(c5b5f1c6,1caa4a7,fa5e665f,57b45134,bc129ec7,131642a9,6a7b4191,5e8b483e,26cb3816,da5098cd,a3f58fd0,c26011e9,73dabb66,d8cc9257,6d37bfbb,9cb538e4) +,S(410da274,df436772,64decf4b,f790035b,d7d5b174,cffdb4f4,56bfb6a0,79a50d88,71c81968,188eb349,6dc2ef1e,841979fa,254a1939,5bbf00f8,8e1d2bbe,ef9a6abf) +,S(3d9928ca,334dc800,abb6c5a2,43a2681b,6f7976ac,50abf387,54058d05,cf67769a,cfcc01dc,766127b5,3e183cdd,80a0a1e4,62bf01ab,c4df115b,2e4f4e9f,95d2beb7) +,S(65a8f57b,c523e4a6,4777ce31,2000a322,d858eae1,f39fc919,2e4f436c,c8040cec,820698b9,9e953745,b1ff7b0e,a22bff63,c9df69fc,c2055b32,3f07fdc0,61192432) +,S(84e553cc,baa606c2,ffd3ef5c,a62725a4,55f4e539,24a72153,1ac3e66a,5d92fb79,34d6af32,4aaa9465,fd9f7731,1c01221d,4c0b5f75,1902dd67,4dcfd0f3,9cc5f8d2) +,S(3b4a7558,28851226,f391578d,5d146da8,dda3d4b4,f79a36ac,5f8c166a,773783,e37c96fc,4de83cc2,eb4b3cc1,44d4d35a,1a4249bc,4cd7c787,7d0084c1,b1a59e53) +,S(6dbbd12c,6164e8d,ea489819,37fcd12e,74339578,6482ddb8,9226d9ef,50cee6b0,89e48f49,b3f5d154,52e47c17,e1a68ace,eed3bc6,8002a70,33316116,ade02b90) +,S(b64180db,3b926481,74a0b743,1f84af72,f1118e9d,6cc1fe02,f0bfb72a,97c441f6,b394f997,83d00816,267a4f0f,8c95a05c,33cc19db,eac704d9,9e1f0c2c,4fb25fd2) +,S(2173f38c,f47377c6,d977fc08,ebb67f29,37e96fbe,e46b2115,b260f03a,216b5c56,bda02a78,3c4a684,fd88c6df,6becf56,3bd1c61a,4e79d36f,27e22fb3,212e2abf) +,S(9dd9ecd3,f3732f0d,864df0b4,8cf35e06,ea2b89a6,a8a2756a,222e266d,fc5c5214,e42ea720,2ba68242,ed9256a,57db94ad,dcf00b1a,50ded06f,a70d712e,17e921fe) +,S(705f9fed,5cebb62e,dd549526,af729092,9d398232,604d136b,2a121cf,e7af71a9,bb2cb17d,aa4472eb,12e69a4a,57a7863c,2b32c100,a1601d2c,44d2cc29,750d30a8) +,S(f1a908d1,807169bd,7fb7fcd8,cfc125e3,3fbcdaa2,8d8df1a2,17b84c2b,2cef4410,e86cc08,804c6c56,f81cfa75,9851e67a,d792bbe4,87812cc1,4e7aa468,b8911512) +,S(db0c5d79,35693c81,c752a475,6852260c,5625e434,5247cd5f,d40cdc24,e1355f57,120c5ea9,fb00d295,37721f1e,2539ebe5,d0de9bd5,354ce629,fe8c2e8d,c683daea) +,S(5e4d5935,56007e92,1b158f68,3411da86,e979d470,7b53caf5,9a2ed94b,ca423ec6,71588b00,1a0e9ed3,27862fb3,7ce6aefd,c309b5a0,928766dc,b947773e,6272d935) +,S(1a79ee08,3c46e5f8,8e97fd11,22410164,a264d106,7ecfabcd,4872af40,4fec7f28,f928dbfc,49bf7553,356289f,18a5c8fe,54f94bd4,d9406aac,c4df7a32,32349111) +,S(e693f88b,e3be0c46,cb40a2d7,f3a0a435,1c3a1812,4abdf46e,86ca3af3,6cac5468,55f0b7bd,24ab2a2b,aef2db89,d8aec5af,fb4f354d,66538efb,78f094a6,dd649cc4) +,S(6d15e8b1,f3c73c76,f73b12d4,f5e96e28,43bb6157,5d0d7e58,1bcc551a,329ca25e,f21f3ee1,84386427,32a0d05e,419f8a59,173f8cbe,6e3b765d,b74c3588,2d7f069d) +,S(48b8f127,b2614af4,95303f2c,f6593d16,20dd98e4,ff536dc4,8a5aaade,3bddb682,8ed1b9ba,ec137c62,5127e23b,55d786d6,a50d191d,6803ae99,c7ce57ec,2f546e3f) +,S(2ec32631,ee1e4510,94719f29,1a32e0a0,8c29fca4,8ff7e3d4,170a7c0f,5aeb3028,eb861d9f,e21b536e,58d0ee35,9d07d09a,491572f8,13eaac91,6105785c,697aa945) +,S(f7960ecb,3b35d4d4,5ed2c13f,b55cc944,7ab72f66,ea1857b6,776b8ca0,afafce3a,90245cf8,d40f6b40,a7140334,da02eea7,d8f7cf7f,8f87c510,cd6d9ae7,8410f08a) +,S(a94ccc3e,4b22f7e6,ef385780,d58f3aa1,139b29b8,c7dcb5af,7a247125,ba613ef2,ef7050fa,dd6afa0d,a89ba357,cbc6a66e,782471cb,8cfa4c45,e94d445d,a2845409) +,S(e48a7ff8,6d80f430,d3d6f57,6c56f026,8c42b3ed,17086399,56d62f54,f5485c38,b1695229,b4997b0b,229e3c65,c7ffb42b,e429b702,47b98231,a7bd9c5a,5e9a6255) +,S(df99488c,7d46c83a,cda5b422,b2a633d6,cccb09bb,f6488d9e,ac79e9bb,7f22d2ae,89490280,a958f45c,4501a878,5bd3c72b,aaf83a45,d91a38c3,e0477562,f345fd4b) +,S(a150c6c0,4db9f9f4,6f64368e,bba348ef,2bb4e43e,29b27770,553ef41a,ef22fd84,61dfaa74,e1525a0e,c3922ab0,20e3ed1c,e7b5397e,b4485cca,e1f64f29,19c5c201) +,S(9b7dedfa,452ec6f9,1d7aa167,bc984a28,937392ff,d856a4e1,204aa541,f3aa0edd,a37f4912,2f5168de,bca0ef6e,7c9b31ab,b4262c09,ccadbe79,10a4a844,ffd2c74a) +,S(c7d77a51,6d0cea71,b20f75c5,579a5906,ad1aa83c,f9209a23,d38ed358,28e51904,399a7c7d,9e1a3660,37b0a7a1,49b0dae9,8e5a288,cb5ece7f,56de4d8d,74a44bd6) +,S(d313a829,8e4de5b9,a166c2b0,f73d9812,fc1d1dec,b3b86e8d,8062794b,42fe73fd,6524463a,7eb26e2f,34f062c5,dbbdb4db,b8514c9c,60af6a16,fc9a8830,1f708fe4) +,S(4bbf363b,4d66c693,6469b8e,83c4f18e,2e6c2a3c,498f38b9,787607fe,97211e5f,9e42ca4b,243872c5,8c7b6406,11817743,82bb0d59,c0de2562,9f26e8c0,7d1c60c3) +,S(3be10ed,23a0ce86,d4a7ef1d,a667cf19,d471bd37,7467403e,3f84535f,861e9cf2,bb959378,cb317c0,6534748a,49bb9fa8,edfd2090,cb95cead,a7b0433,4066d885) +,S(fcd1f880,d723963c,829074ec,8d29eec4,946da198,cba5d96,b169cdb3,5dca2076,9489bce3,a31362e1,c4cec275,5fa5fc86,d3b105ae,25bed346,7c0919d3,b2a87b01) +,S(b5fb358,993d3662,b2e7114c,d8ea0681,f39f42a8,52cd217c,f0ec0271,fab317c4,89d88eb8,ee622cbc,f0dbfa82,8b04ac27,80a653c5,14df734a,791b3bbb,f3a71b43) +,S(a86bbad1,7fca460a,4740f39b,d2ccab3f,30fc137f,604e77c9,55624815,8fe274e7,c26dc259,ba969ac7,8d294742,e4962c07,1394ede1,263f5a0b,d03b7a29,30753fb) +,S(ed321f6,348cbc96,7e34bc7b,a935d129,9dd3fc94,c27d1467,88792180,1330d29a,b4078360,832b5de1,c77b44d6,cf07bdc8,fc5ac402,15002135,1be0d251,a3f7c3b5) +,S(c8179275,e4ddb936,f55e827e,de094c4a,2c425b8f,701fc979,96ed7194,1ad17dea,d99f1c5b,e241d165,eb49b0b9,266486af,8ce5e963,c52b2622,e16fe99d,d82553a7) +,S(6f08f13f,23b9b383,49274328,3f8dfcfd,eeaf82e,1d91e512,df1d0d7d,de84985b,96b6a829,f99f433a,6ee58ed0,50370ac5,665d61e,22cc7a76,a4a3fe08,d8bd602e) +,S(9443a7e3,410f9d4f,ef9f8b60,9eac3e5f,e6ab5d6c,a11855e4,b35c7e67,9f8f9d5a,d8c507b5,78188c3f,31bc93e6,d07abc22,ac9b2add,5a11db53,8fa0f936,3beded57) +,S(432ea8ca,3ed53681,ad3afcfa,570056ed,d38c8848,de293d2,e37703f5,133c502b,9e19228b,70b52bb0,8e66a49,826c6a61,965dddc,64270118,faa3389b,6bedff71) +,S(1d17589a,42f82fd8,c5a584a3,d3c7fed8,5e22ffea,e2b732c1,30f903fe,1982403b,9f7bcfb4,8f18d208,26564ed0,245f0c6b,511e965f,be5e0e94,54e0f552,78c39ceb) +,S(743399b5,cd84846f,65e778ea,790412ce,1ab8c6ff,ff7c098b,55436a1f,e18e6b2d,dc6cc81a,82801be4,e6566d3f,c01b6fd1,e84ff49c,e5ccf145,fb1f49b2,d8b784bc) +,S(e4378558,3b2848c1,62e3e80e,3b5f9242,5330d232,e05f871f,a279a0da,7910b2a7,c39b4171,aa4978e4,7d3f99f,8179a189,d5e2421b,d076d1f0,80cdacf0,55624b68) +,S(eef768a3,1b1639a8,f1755ac7,d00a6463,8f8a99ce,f5f42a10,664026b3,6718d63e,2a9005f4,cbf4e686,1af0043a,fe97b065,878efcb8,8be29ef5,ee648473,1e24a991) +,S(15db4687,2504612c,f40dce1b,d601d848,fc2afa9f,b2de929a,1800caa1,bfc91fe9,a8b6e64e,7d508d9a,504678a9,d90b82ca,1e72360b,95a2f515,f17710cc,4e7eded8) +,S(ad45facf,2529a84b,9d28d2a0,456a1fd9,d2b3303e,fc78e2a0,c7757bad,d4a4191,1a78e571,473f3035,16ef5867,8f77d5ad,bf8d8109,60f9925a,a6b4a88d,3654f069) +,S(41a03744,6e027b4c,eb775050,a892bac2,1c19b66d,5fa4bd89,58c949b5,b9151824,ed7c44dd,fa96d38f,a721cb2e,60e07a84,27c53acd,6435ce74,bb45437d,95140317) +,S(2020b869,58f4c7ff,2cf64589,f1043d,5a70d5d6,dac0740,56011f1d,27217ae0,111959e2,2757f431,a1994617,124eb1c6,b37f5961,29d52aa0,490b94f7,e1c4e9e0) +,S(2f99a946,859f74a9,50f3bf27,d85a169e,99c5f755,71000180,283383a9,eabd4ba1,3e622182,d3caeaa2,47a4ed24,6e608592,36ecba9d,4e8d79fa,12854f74,df89fc53) +,S(ddcf3989,57f65390,167688c,2e227f29,e7c5675,d4a83a3c,177ebdd1,9e369baa,a700c63f,3fa6833a,239a3cee,a90dd021,c3c3428c,f2b11b87,3da1dc01,2f4b2431) +,S(9863a7b8,4252360,19e2fa9e,9319c5b,92df1eaa,c0b7917b,73bd1042,191ace4f,49a499a9,281dab21,4bf09f8c,724a30ea,3a1fa7ae,4f1b2b6a,3bf63562,e03b69e6) +,S(6c5465f9,ea2c5917,34f3734a,64b8e92e,19cb4def,3c6d5d2e,467a8f58,dd733886,57e22bb,179df35d,15aa2616,a319ab3f,768f655f,a1c07c8d,3dafc443,1e0e733c) +,S(ab375513,360b3beb,d0ca387,fb0a0690,25acb654,fe703a53,d979f14,50f3fcdd,3e9c1149,309a2de5,9b7842f4,3c37a6ed,57f0f776,503ee7c5,46445c2f,6c41be4a) +,S(6acbe3ea,4a72eeb0,b23aee37,905b22d0,ff0878a9,e9143111,4821207a,4c2603d2,1ecefcbe,9f934d96,a163dad7,6c9e6806,ac2ca23c,e495a533,aecb19d,df0d32b9) +,S(7955d144,58fd0c42,5e4ac9f9,c766e253,b4ddd105,7f1c8c3,653f95cf,3a955d89,8fa9c5f7,304387f0,94a89225,53a20287,40c6723b,d25245,84735024,9650aaca) +,S(b5972d0c,90433f,702b25a2,27bd3da2,d488ebbf,e5782132,28c20cd8,35ace377,235470bf,7fbc3de5,279ef70e,d174b2fc,e3e78f84,5c0bf212,cf3d64cb,42b008fa) +,S(a266a810,33a5fa68,a204f3bc,53cc79f2,cc500d7e,4495f8e4,d9cb48bd,4bcf886,31a8b1a1,958d15b7,664390e6,a46f3e37,d52b7824,5b0b91ec,b568b7bd,f55949f8) +,S(1c6412ec,21191b63,5bbbf47e,1e9f7c21,ae7f4f3f,7de0f123,451e421d,44b9cc15,833f8a2c,1111c4f3,f5973851,d0256309,6e7fec1b,22ff969d,82a62284,c42c685a) +,S(ee3532ab,17575b57,9c19ccbe,fee04ff3,8172677c,5e625f68,a7462107,3e0b7fda,f12e10c8,b2fd987b,83dff04d,cc48ee6b,4b704b4,92b2cf53,a9af4510,6e7e8718) +,S(5ed10fbe,4867937,2ed2765a,f7f5b4bd,52ef9a4b,96515e,37944d9f,ee1a3838,8c4eb9b4,9fbe3924,ed8ac641,25dce66,a4bffd7b,5fbc68af,2a8c8633,b4080573) +,S(fe348a21,f04c85ed,69fe7345,f73420e1,b8f6b859,7082152a,15a1d535,d01378d2,d595d446,c9f5abf4,5ceabd10,3e38e423,5069473d,7d9f9911,7fa9cfd2,81f2b7b) +,S(7140369,b7b64ba0,861e1c0,b5ba3973,b573679c,c091623d,bda88745,fb2436e9,f0770350,f9799607,28c3bc21,30c6672e,40dfa362,72c50ad,1f376a54,83a12b2d) +,S(6d14c4e4,8e981e3a,e7ec6b88,b1230096,a7465db,a8381bd4,aa82157,99dad15d,25e4d2aa,a5f2d12a,a4e635f6,db58b2d5,f9c6de8f,b5bea99a,50e5b050,e7e0f841) +,S(7931b9c6,a6837d7e,3620558e,55504e88,4dffe071,5bb628d,aeadb0af,1a4383da,586caa73,320925c6,ddd12128,bf3bd38d,96b7a904,8422c2ff,9d5cfede,fbe80c0b) +,S(149e9d6a,35b83d43,5d0e1f32,a1518b88,88dca145,27aabd95,b0ecd0bd,e5cec834,45807aa0,fd84cc65,e91d49b3,8d012fb4,f87b11cc,1906e1f,cbc74c5a,ce5606f5) +,S(656b276e,b4b351a8,222f2b59,d7949010,1bf6e696,c284bff7,b809bd27,d297394,8746f309,5f8643a2,928ebfa9,a0e35893,905eb6d3,faa8e5d9,b6473281,7b763291) +,S(60f399e3,68086989,ee62370f,f7852e1f,3656a720,539880a6,9884b60a,f1eb02e,55dca05a,8347be14,85251676,d20b779f,9e5976fe,4def267d,4f1b2b6f,d444ad59) +,S(4dbda303,a67a41c,a46f417,54f9bdc1,34a305a,9018ce0d,4cadbe41,886eaa13,e062cc86,fec33458,d65f9fe6,4433b745,909a3b95,d23d7970,c22585b8,3fa48fc4) +,S(816ae1ca,4d64cd9,5a7c10c8,fd819c6b,f8c8b1c4,f495b111,d07f2a00,dd0363d1,c09f6bff,c331d6fd,56ea5520,8e9d13bb,b12187f2,d49366b,2dfd1c18,66526009) +,S(45839f9c,983fe0a7,c3b2b8fa,e5e288ad,87202944,c16d60a0,f18daf,8081b52b,f9368e07,4de74eb4,81f7beb,30835af9,aff40c6b,cda104db,2a785a6a,65dd8649) +,S(50ae4a48,3a49203b,1e04c482,ec2454f2,44b7157d,b23bcd50,63c5b6e8,d4223465,e1b8cfd7,e7bd2e1f,65f2031e,c583bda5,a619028,5c364658,36dba37e,7d5f3008) +,S(df77b231,60395089,19edde15,b21ace77,c5d8bb4b,ed26f9db,a694195f,616b72d6,8a4b75b8,9ecebfbc,b88cff82,2673665c,c99e270c,b33f3037,17dc9500,8b4344a4) +,S(ec6c0e19,978e2f18,b74419d6,70274075,6d2d238d,63b2d345,437b0b8e,f233277d,f90dab9a,2dfc4cc,62571dc1,35bfe4c6,96bd3968,173ced8a,4a363f0b,2636e553) +,S(2874416f,90e7fce6,a6d4eacb,1a722218,5af2a885,4852be4b,a4619011,617b3329,1f323675,f6ced648,8ba4c9af,7912ad7f,b8628e49,5b4da82d,448dd265,eaeb4466) +,S(872367ec,586d3a80,f8c87f3e,83b6dd3e,529de5cb,897c9d2b,e7dacf3f,70ff4247,e5bb60e0,fae0843b,788768b5,e427e009,7dc571c9,e4b62eec,eef68512,a6a3ac05) +,S(c10f2004,baffd30,ae430ce9,40c4af34,4339a0b2,13bf1f48,91b8da3e,424713cc,37be9055,f0c39b36,c546d456,b3f82edf,bf6dbf79,6343ee59,c3537fbd,8631c7ee) +,S(14e12ee1,91c83005,6bdf0f15,3353e80,733b8bb3,b93bc59d,a356dd94,70d847c5,e9707b8e,e00c1781,12b32ba7,c66d7245,d487f032,18d20da,b1550e3a,9befcfb2) +,S(dac3ba1e,2583379d,d2cdd89f,6ad053e4,3687eab4,ae804305,7b57823c,489fdf36,45e3da4d,88211519,55c20ab1,c2d1ec4e,d13a6942,fd37bfa4,7614745c,6fe2c041) +,S(d9bfc67a,5c086ae,e879fad0,b03a5a2c,a2507dbb,fdd2cb09,2644dcfe,bf800bf4,e015dd4b,5a39f5bd,1536c8b1,e93490f6,e5bb4e8e,b23e6ca4,2fc14634,2be6730) +,S(de6f3452,2f04ca0f,170d7e58,1d965982,8a9a981c,12f6cb34,761873,7996c61e,1ec16f3b,28d74fa9,43b9c251,f34e15f1,2fc6d814,ff024e3b,826054ee,f72a0cc7) +,S(432ab355,338e17ae,884a15ef,2365283e,b35c873a,4fa8cd93,f54bf828,a0e30eaf,f56066a1,a130dbf,8a3e076,720c10a5,caa9af0a,7d86ab9e,8703dcff,95447807) +,S(3d2e3507,cfa127c3,a350f546,d95431d4,8d96990d,b5beaafa,35a408d6,7f7c4d99,da60885f,4711c373,145655ca,b0f8a235,7f4a0508,2bbd2ac5,1b255593,a35f74f2) +,S(7f3f431c,b96dd4be,37c29d0a,55f3b71b,f781c7c6,191983f,4576e518,24ba87ef,f4df4345,7649d24c,2b8259f6,f7177b96,cfdb08c2,4e9161c1,695c8027,60b8bfec) +,S(4270bf59,f2c87000,44b6cdd8,b558e6ae,6f7b67d5,f128d716,3d604a7f,2f687143,358cef,2e8ff919,6865da0a,15a25524,6c4a180d,ed25174e,d08eabd,4da99315) +,S(c663722b,9930fc9c,4113af50,d51c6539,b7931cab,ebe2ebd,46f95b8c,7f603852,3443e7b3,2cdf23d8,eb532a31,3ca4b32,b94768c,78f8f13f,719708de,925ecfab) +,S(b0014864,e396ff02,cebd7b65,c66e57f9,168e8f3,95ae614f,21f8f162,c86c4e14,3f6c99d7,e2ec94de,ee65007d,ab501230,4a80b69e,a0e0672c,b7dbe4ba,182eb876) +,S(64c9cd93,98fe9da3,5d3329f0,ccb82e43,c2d735f4,d2467b2e,1250c410,da84f41a,d24b50ab,71bf6033,d1206fc6,dcedf049,c223ef78,ff50905e,c8d95115,564372e9) +,S(ffe0841d,51e05862,4f759706,b27db960,ecccfad4,cf326736,ab4fd9db,cd29b766,6bd1f1c9,f6956c10,4fec1595,24d8064f,eb5d8391,30b34a01,77c07491,79cf2562) +,S(d1dd0c0,c053c597,bad38d63,c40d1e7,4b451861,cf0f20fa,47fd3f9b,77ca7432,34aa97fd,b59495f0,3e7b5628,daaaf66b,5c9dc5ad,de929032,80ba23bd,6c55976f) +,S(87a436e8,c76bd7f7,a3e49cd3,af996f1d,9153f704,1b185d8d,f99eca45,ae8e5779,8d2cf3f9,12553844,ff905d5b,2a1fc36c,369ea4ff,6a89a027,b6dbe797,f11006f3) +,S(a54500a7,4899c440,384f707d,a8fd62ec,1801070d,cd5396e4,b59e9ecb,df27c379,e216444a,6d26bb06,5f5b5e5,72c927f8,5315df3f,11da2cae,2f334572,33cb2668) +,S(937ea4f7,99a319f4,fa5aea85,b48d6323,28417b72,8690a9c,88fbd51a,57d8187b,2931a7fc,9eb4aec8,b7dce4af,d14438ac,fce77bda,a7d3e7bb,b24c8554,cfdc9d9d) +,S(50793c76,bb914aa3,204dbc96,cb04ff26,c7060863,8d497f07,a1eb05d9,b7fa6f36,afaafc78,b5e30762,b68940df,41de9ef3,d963b603,6bb1ffbd,eb13fd67,4bdab21) +,S(8b600630,fadae564,dcd1c570,9bfe1ad5,f8da5282,61d55bf1,3a29766f,6d8bb5a,fbf1b64a,3bd0439a,ec45a7c3,859374c1,7885389b,9c201f4d,c1142120,6b2916c0) +,S(14e88bdd,e32a15ed,a37c9650,ffc18ba,1fc61643,22b167bd,635f3d02,e78c8458,82c1ec3,dc240faa,5fa355be,475afe0b,5cc2cd13,760249d7,35b1efe9,976f02c9) +,S(c201e4a3,24b68472,d453dc02,8c78b1c9,975a3d92,efc70a30,a912fcf4,991c6c06,263a954,41d6e6d0,8ebf3e50,3c786a12,a82f5f8c,d38dccee,62469e9c,f0e2dc08) +,S(4097665d,319a8b3f,71861b1e,11828cdd,4094182e,611b35a7,c5d10ee,99db4fb,ca0d7ceb,b1aa2b1f,576cd1ef,56ffee03,322a6b95,505727a8,5dcb70d5,27a506a) +,S(173d287a,eff9293e,dd2021a0,4be052d9,3713341f,37a537a4,45deab49,b427fa92,9626e204,f03a1886,c27c37b5,85725465,72e5302c,d3f9ce54,1fb9a46c,16432548) +,S(c923c74d,1b114f,30d4b03c,92629bed,227fb8c6,8f1f39e7,8f121a44,694d4256,58edbe6b,dd5e1382,108d1e08,ef022788,c9f91803,d8ad4273,1f413440,5b5b3d29) +,S(92fa7906,b1f25c2d,3df104c5,196cf31f,93e5a8be,6cb91a57,c88c4ab7,cb92d46,a12162bd,79341fc1,e8f74db6,2bcd0d9c,ae99a75e,ce588240,79a61751,c887f307) +,S(37477df6,f51f78c2,a9c8e17e,ed30d5dc,976a9c91,4aea94c,691aa3c4,8639140,6a6a26ed,1955656c,64c6e15d,e50b0453,25c3da66,f5067730,5c2d5fc2,a8089872) +,S(b5b2ee59,1195f38d,f834e78c,abf00fb0,be9bc724,36c5f596,67ada098,dd0521bf,10f36f85,95233008,46dd276d,951abe90,cc8baeb0,fd8fe44,314706e2,15ddd5e4) +,S(b05d1b8,443f1bfe,36a415e9,d307ef2,56039335,76ecb630,94845b03,d2a137bb,99fece4b,ddc90b2c,3102a415,6f0d63f8,54098f48,3e1ef64,65f7f062,7d066cbc) +,S(e5d711bd,4778b3bd,cefd703a,e9525b5b,d69dcd86,6cd0b179,de76ae8a,5d918fd,8af014ae,5aa05b29,a0c88e21,8fef5690,9685d524,af389327,5421c35c,6db64248) +,S(7703cab8,377a482f,bff1c6fc,4d137998,1e217d11,c424beb9,f4f1f786,86fa4f30,3323edd1,3c80b8db,c7e247fd,5568c92c,8dd329ed,420aff0a,8e903571,e884e8b3) +,S(f834af29,c18bb488,366cf722,52a44357,2c87da2c,c14b3085,5405f626,154f3cc8,2e8a0ac0,ca5441a2,9e27dc09,4fd5bcc6,6bd8f7c4,717615c2,82001fed,bd5ab248) +,S(783b093d,13f33c60,1db8ee84,51d852ae,13bbcd7d,1d03a79,4c774336,4bbbaee0,3aa90b01,cfde6abf,fa0dbfb2,ec2cefb,6b5fb1c7,41701ab,66ec9b82,74ae5b4b) +,S(be3cc435,a7770b99,14a243b,48ef2c77,3ae42e82,1c18a266,6f92da59,e01c3391,f0d3bd36,9118c58,159fc64d,e61ebc58,a560f705,25dd5c51,e6aa9276,5ce4a701) +,S(3e980bd7,adac00ee,fe362454,5fee1ae1,97f89e06,84576a08,fc909285,783b606d,c64f0e41,204c946c,74473434,7e091147,67455e30,53fd488a,34d333fe,e9c5c228) +,S(a6b04140,aa621e6a,34959bf1,29790d72,91d7b154,5dd5e7c3,35bbcfb2,d582b442,9cb2c9e2,9cc05d97,5e61d151,542af6e7,a997f8d8,ee42d37f,8041c169,abcce830) +,S(7ea7a83f,c133cb8f,a109a6a1,b29b2c3a,29ba432d,222382e5,1f280e2a,47fa721b,cbe384e8,8a1f7731,831c5562,ad1430a6,6aabab75,e38571b4,5bb7dd8e,a699d7e8) +,S(8525e87e,f0fc9ebe,2f82b5fc,a14ba6d4,8189f9ee,146aa6c8,d842aca6,90fa042,dcf06a78,f311a3cf,182a393f,2a34a570,192873e4,7dfe22a6,86c70e75,6b32c86f) +,S(7555a77d,fa050d0c,9ed29c33,765fe967,16dafff3,6cd04fc0,952a7b41,bbd56dce,9854c0a7,bdc3dc1f,d8bd0a3c,d0af3111,18dc0392,830699cf,d0bd6f1f,17152177) +,S(9ed142a0,7a0adac1,14e6f026,133e00c4,972bb3bb,bee62f71,beee17d,9aac296b,c1eaea41,6c80e3b8,d24d4006,f699af50,9f4dca85,11c27f6a,39150a20,2b7a9d08) +,S(a3fd2cb3,784d8ccd,92aa67c,8118fd80,c9d761c4,2e0169d5,fb13b1a8,dfc56b79,75cd9b41,55db55f2,d50fcdd4,8c90d58a,b0d13df2,7a09df6d,659bfd5b,f87ea755) +,S(2ab4be05,217e7ee8,799ad598,b9c0e211,554338e2,8bb6d42f,c9952203,605ad251,2c2a1a58,da066d4a,7fc8c8eb,83e1e47b,b788afc8,3c8c5dc7,bd8f5e31,5476d853) +,S(4afc2888,af8c1aae,af6268af,566ecceb,8c95d09,d9f8f359,2cea567b,8648c383,b1e26b82,5e69e92e,98902579,7e99c7eb,cf3f284b,e1de0054,58b59336,a84f5eed) +,S(dd800faa,92319d2e,48038600,aac1c2b2,f63f5fc8,dafd988b,548021b5,2d8e3d4a,59fe8092,6e0468d7,60e522ac,91881bc6,8fdbc192,14fee60c,e8e1a977,1039ed7d) +,S(84aaf3d1,daa3a5f8,89b9bc88,6afb07f8,7bb5182,6df9d7e2,af5a74f3,c6378c91,f4164ab8,45eadd6f,a6331218,ecce096b,a04fd586,b744f0e8,11c2a48,3835afbb) +,S(b770f2c3,9e2e9db8,a92823a3,adffb690,d2ffc180,b88cefcc,8adad3a8,27c40b2b,f7c6e37,9894982,5d1b90a9,16ea564f,7e319c97,ca6cd22e,79f599e8,dc0d53e6) +,S(a60608a8,a0d7e556,70145c5f,bb107cc9,7cb1db87,2493f362,36a21e7e,babb2b29,3423527c,4e414548,96406f90,6d4a3819,a289c91f,b580ce19,6f25c57,7b54de5f) +,S(80f470f9,7b7f393a,5e6b4e5f,cc911a73,20f6b0f7,fcabf2d9,21eb649b,53414597,57d8f2f9,6e1bbe0c,1328faea,13c3f3b,770fa14e,4b5b7e4a,fa1ce9f1,2bd9adc3) +,S(4e111bf2,1f5248cc,3fff0096,c64a7b58,72e4a3db,1f0397fe,261cb33a,995abb6f,249cf172,102733bf,5fd829c1,d60bd930,c03af614,31faab0f,6d5acbb6,96eb2b9f) +,S(7d8c0cb5,47fa1d8c,10254660,a20e85ec,960cb70d,f38174f0,18416c68,c62844c9,2d79ba3c,17ec4d79,a157335b,f358cfd3,72b0f1ae,1f6bc743,40400571,5f35a271) +,S(bc0d4cbd,95896fa5,7f23d48f,a5a9f2f0,14b132b8,9b5953aa,f612aaf9,670a0034,f5d06670,7b316581,7a641091,55773bcb,83d7563f,28ea5412,480a0f48,2fa0639d) +,S(b154a2ae,ad08d115,95eddbe1,c9321e15,5cceb0a6,a7e646a4,2dfe70fa,b6d37a40,9abade21,674dd12b,d01e586f,695c896e,17120d8d,9e3c756,c8b5e53f,3216592a) +,S(ef603c34,a6ce06f2,7053bc31,841fe2e6,314be756,7e477325,5315ca58,5772e1e4,f9ebbe28,96f3b0b9,923a7e57,d819a231,15fced8f,3bd08f51,64aae597,c49ad65d) +,S(a601176c,2d901ebb,ad5a05d9,1adc0041,14f7bda,1ac496e2,c04e23fe,82aa9376,f781ddb7,ce0c3649,3772fb84,9e914377,d59abcf9,d3eade68,f8c8a303,1ae88ab8) +,S(abc41547,b6b3104e,fab968b9,bc9a9027,b1c7f0ef,3a9007eb,27331539,5c31e6a7,cd2858a2,28f21d6f,bd8a1821,dd78399b,594c5bd3,52628dce,879b8a37,d97e0ec9) +,S(92890105,c9c721,b2e4c430,26e413a,941d1da6,d31b48a9,2f2e3a17,d87f5a81,c1cad87b,1bdcc617,1e432e17,c13b47c4,15c22399,a7cbfe2b,b3097f28,da60a5da) +,S(e520dea6,9f4b35ca,46a46831,9947690c,500a7a80,6bd64228,ad144a7d,c37ca563,6c00d766,ac3f8fbe,90355dda,6ad4e2d9,e2330b0a,db673356,638b0d3c,8a2a82de) +,S(c0337a23,e2b3f1c1,a57d18a7,9d6ef25e,ac2e9315,18f0ffb3,7502d701,c57fadc4,fcea5873,be22df35,4729c3d5,b07a570d,7ac7e938,f6e061ec,cdd2146f,50808b65) +,S(276c62bb,6a8e2c07,6b5fb6a7,62d1d624,1b796a96,f53593c,fa51279b,2981ac04,5c53a65a,bb6b01d2,3f9284d7,d696236c,773c4578,88f692b,73e2ea17,6e1afc1a) +,S(604e1e87,e5051dc2,b837ccdd,43c8ede4,c4a2de6f,67a9ded4,fad1ddbe,8d663a5f,f70fe23c,e3511973,93d4d675,9444d862,ace4c473,99c34349,2d06b27,8b429bee) +,S(f2fc151f,470d9106,d58b05be,5e9039ba,4aba16ae,f7e4ceec,3b6e3887,5c41f6fa,f49bd2c7,f1aa5c63,d8e7f2d6,e0769060,d4188773,9c16b7b8,5d2a9216,e1e98de0) +,S(8e031346,e9f34ef,3b81d9cd,7e46eaf8,7ee0b294,d66b0315,eb0902e1,340ac560,ff00c8bd,a5e21e1e,5127441c,ee0504e,6b028c,ec0dca,450145f9,2c394296) +,S(a8680f1a,d75b7a8f,27a1cbe1,6b2954eb,d4e26eb3,a85d1a0a,96b9f40f,e5a9970b,60c6bf41,a55bdac6,397281f2,a3f52896,757401be,c42964c6,9501973b,e6070c01) +,S(4d68a1e7,f4d82ea1,e03407c0,5085c794,9ca8c00,d4dcb066,128e6c6f,504f4658,85c5de11,e5dd3691,2aa95d2d,2c36dd6d,26a9550a,3a672af4,d36265e7,a3d1ce76) +,S(3708f41c,2a6d8649,6983cdc1,bd02eb39,758c0bc1,ae78a483,5c6a20ae,e6c2a7a9,310b799e,79b7f5dd,5c9ae0f8,7aab193e,3c2b7145,c70af9e7,f4553faf,abec4152) +,S(8c883967,45028c5f,f1b96181,43f5b732,2d1a18cd,3abb1a92,f6ce3780,a115f059,24563ad4,e4ae484a,c344180,66dd87c,40128e42,5c8dce10,b008a7e7,620725d8) +,S(c445e76a,7b377ad3,bdd0fd1a,94a7263b,652e83c2,6342305d,a0e1ff4,d58f8fb0,4bf5a41a,dc8ddb61,3afbd3c1,3aae7dc6,f60ae2e7,23065b8c,c94cea61,cbacc89d) +,S(4ad9613a,c8a635fe,60d9f1d4,da4b9fd6,36949d5e,edaaee8d,eb2f65da,8e419f16,5a9b5b06,8f67a0fb,3ad31c83,ef1a81b9,38745877,b4b07316,42ab4951,68b0d7c4) +,S(beb3eae1,958bfe6c,9ab49d77,648aa662,2e397fbc,58e90b0c,20d1d29f,d760c943,d5a46be,f43a67ab,225dc6fb,5aa68daf,ec76f27b,6a822678,dbaeff88,382c9b8) +,S(aaa9aab0,bc0e21b3,be3f1dae,ad4a076b,4623fc14,3e4018ab,9df9a19f,d134f397,9c7d7fe,19642c65,a6c0347e,8fa2dad2,d3f094f8,bab6790e,d3c703ba,2742e40b) +,S(553c1e89,99d6f446,2fd7ae86,f1cf9d24,d4011661,9fd5d356,604d6a55,ad99dc52,26b40d3b,8410ac5a,6d2ba776,f7c5f0dd,3f6fe494,379344ed,6460bd6f,f550cebc) +,S(859885ea,36378fc4,398dae9c,4725d604,c3d56509,559ed28a,b47ebf82,5aa1abc8,fae5aef9,fc74b963,bb2fd930,5b2d1636,e6e84aa,3c40b066,9e531fcf,f00687f5) +,S(5fb0a118,679c5d48,554bf7c1,63b82345,89e51032,a70c654b,bb7bdee,f0368f93,e8d55f0,4a6816d3,bfb02111,eb95d868,5b9966ad,39d94c70,a4cf1826,6bc2a2d0) +,S(a424347,86f3e153,c9bd737c,1e70ddae,bbed445d,77ce4302,194be82f,94f91dfa,27d1cad6,abd9fda9,c1012f4d,f25b69fd,a54239a5,8ec12496,97116548,e7beed46) +,S(5d007508,63fc1f3,a0a8213c,c729310c,39465945,72b083ee,f571b921,a0c821e7,e538fbc4,5d055a07,b2cc2605,61238486,d99bfa81,6b0407f9,39f1d12b,feb2df3a) +,S(a3eb25b8,97b10286,934605a0,e4aab7f9,e80393aa,71cdea52,5f82f5e8,282e3db9,e2b354c2,1430c45e,4236baaf,128967c7,6beec58b,e6890c6f,303d83f,71e7f77d) +,S(73f63220,8a133202,96f3f51c,d10fc816,1e309e51,4ea35f0f,ff72e09c,e897981b,43412959,cc78f32e,d6df7ded,349a92e,3095257a,8a1b5dc4,15ed073,a420179) +,S(5f0825d1,c21bb5f3,8f0d9628,f6046648,7760512d,f1bb9bb4,ccfec4e7,48da41af,debac60e,1d95de12,84f1abd5,b6592824,5becd4b8,c2496323,b374239f,fe5c0cab) +,S(cc42a6f2,b4a8e9f2,fae3f624,cd12294e,efc26dff,c66a676d,a10259fe,f7d84294,91b26600,f92cbd05,f13f2adb,2b5fb17f,118a7ae1,6a011690,1bae0e14,3b230519) +,S(7d56e0e7,6eebe13f,a81aad7a,8efbcd1f,4de0c5d6,bd136261,8f0002ec,6f635a17,95462707,fe55e3ee,46dca813,eea5de7c,51122ec,55a91754,f7d13ac2,43fa1ad8) +,S(7972b61b,4fe85ec4,acb605b3,aadb56b6,fba8cafc,3c764dc6,add54c06,f7a5be61,ba186670,2642fa6e,a7cf5141,c46a8e92,4764c4ce,5d45b7dd,9f4926c9,32b8c7d8) +,S(edc8a440,347b1500,899f6360,9674f90f,4344c87f,361fae0b,bbe08235,d5025626,2f812740,9a14bf59,9bcc7cef,ad140b2e,7bf84122,9a51e486,4d01ecc4,1b2cd77b) +,S(bd9b65c9,7a8cf4d5,2f727b57,19f99986,d4ea1bbf,25560d18,d54877cd,3db16899,59cf7127,4e878e5c,bf0d9e02,dbe4f861,ee9c8e3f,5dfe99af,7db98e2b,c2fe432d) +,S(27635e38,1191e8cc,d3756571,44c5d8d8,72d91802,5950a106,f3be2acc,4cf35782,c359fe47,a019870d,7fa3ab,8f51bad4,eb5251f3,7e6b8ce9,db1992f7,cd1ab7d) +,S(4492dcc3,16c05300,a96abad1,47a00e98,359950f4,95dfb261,839ddf21,3b21d85c,edf1371,a4e81e42,dbfb8c6d,2229dc5a,fafed4bf,a58c2433,18934ed7,dc9ad35b) +,S(f8124c40,409e01e5,8de8a386,9bd88f8f,25887fc6,cee37c01,279aa606,edf9c67b,e0071d1,d31fee0a,8a26269c,3d7f3662,2b0f008c,61e749d3,65560c21,a26fa6bc) +,S(cc597b67,66eccdf,a2c0716a,dd5e51c2,ce3aed33,8f55f0b1,b5784bc3,9a05a2b5,12e031fc,394a43d9,d1e12ec4,28e8d5b,df52dae7,f3ef22da,74e3a418,74682865) +,S(142cb2c6,bc1283fb,d2164270,7d525dd3,d4a45f71,a63222ee,6fdd31e2,805aeda2,bde93d12,c72c422a,e4d5b718,bec6458,ed082bfb,7c686f2e,1815edc6,5ed66ec0) +,S(fbf4d602,dd765941,e696704a,1a8977a9,c3327375,e3f0d479,68fd9148,c01d2d3c,65b46df7,99e895cb,a6d4cae8,e68f6160,c7b96fb2,9af7d18d,8ef1396,c06afa8d) +,S(efdb5d57,bb5fe8cc,e3300ea5,ec14c50d,f09436db,cc58ebc7,c6d123e1,8dbfffb8,39083803,d9a90c62,6219ce93,167bd89d,d444e47e,ddd60deb,8137b8a4,203fe01) +,S(5bca4334,faa30557,b4b36c7,b6bf2d4e,921f59f1,eadebd74,97690742,2c3f35ad,3c97baf5,e2a663f7,22bf2fe1,cd646db5,79d27f2a,353fb45b,520d227b,c21206e3) +,S(9aa1dbbc,e90cf065,5ad8a0f0,54aa6641,ff921e97,1a73cd4c,49ff1f3f,51156632,cbf6e81d,8bf1e85d,b802f0f0,b9cc1125,6e0b337a,b90112dc,6513bf40,2b1a4200) +,S(2fc7fc55,86ed7676,4d5d4d23,ddec2827,5386e56f,eff09b86,abaa9562,73c2d408,5bff69e4,773c34ae,e477b0c3,e0310b5d,6019a558,5d4c7f3f,54f9c810,69d6285f) +,S(8e5fb941,c3ac6f2c,43195487,80df9116,6ef3b210,f2fff34,764cccbb,d34190b2,dbe2c1b1,5f6668e2,c63ae154,ce7b32fb,8d29b59e,dcf1ac4b,1df9baeb,fd10d2ce) +,S(7a5bbb59,4748d6dd,5d3389e,aa95b8da,dcfbaa07,26693690,4801bd61,b3d49c6,c2d28043,a42d33fe,8d8b755c,61235c68,ca13861c,effe3fa7,fd4edeac,634187c0) +,S(95beb8bd,f0d33531,ae73ee1b,1b631ce0,917c2fe2,22534745,f87faf21,bfb76753,c6cf8600,d9c55975,527e269f,b4a0e4cb,b9bd7783,7e230ada,a43c2f0b,c64f45b) +,S(f44ecb0c,6d896dc0,304fa480,90ab9793,576dbbd9,76b8fa32,540d223,e2968d25,545064f6,29644329,76a03c62,9ea46a09,e20e470f,5e76f810,6d19f353,c321086a) +,S(8dd32cd3,3dbd936e,6173ef50,1f7ae265,d56d68c2,77061e07,4fb49d26,538109de,6b110e5c,80daac20,5392bca8,a47d6d90,ad158c25,a10c0851,ae985f70,7c3f1e76) +,S(3d4afd30,b0f0f578,d4fbc77e,b71d044d,fea5e3f,891cda8c,77075dda,6237997b,2816e0e8,664df57e,c793d442,49c23ada,ae286ab,e748493e,d83b1efc,58bb9ce) +,S(a9b739fb,beaa3b22,b295ccac,86a07ba2,b8391381,2d2be020,a5ffd17,85d95ff1,a1d08230,21d6a6ae,f696d732,3c43fdec,d3c5d42b,8ed7ad40,1a55b2ae,bfb84f1b) +,S(e9009747,e51251eb,fc2cc754,c8b55966,a37e5d67,acf9b632,bb77f46b,9203715a,34258967,9ea8f997,71b476f2,5571a588,756f277a,17ce3907,d9cdab4f,cef9df72) +,S(7e348ced,55aad74c,c24d09b9,6b332084,2108fe41,3ac4c6c1,a8376439,f21a3f2e,39874f8e,3b722795,d8465706,e439e4f5,c884c22f,365920f9,1edcf83e,b4389e5f) +,S(a7dd6676,5ec2d701,56f2cdab,f0fcc0d3,8e340fb6,8a0d1220,aaaa74a6,fbb1f55a,b7091bf2,ab00a63d,292ded9b,b00bbe9,63710dad,445e8e73,760a50e7,2f41d447) +,S(b8579e9,a8cccbf6,dc033a48,16d8934c,51c0852a,4693fa96,a308d51e,3f57025,e696ecdf,4d79151b,2f164a3e,bc11bda,42c88833,6f694fec,a8bcdcc5,7158268b) +,S(7b29c45,9de0080c,bf8c8c72,e7b59a7f,184f1c1d,46787cda,bb42c2c2,bff57af8,40de8367,a6d8d13d,41901ca5,60376ede,817578b7,25f4e614,5dc46de9,5f801799) +,S(1ceffa6f,89b65be7,ac20e34e,f0b7e503,d1c4e9d,b31fe14e,179afdd,96f00f9f,6fdee8b1,f05930bd,ed98feb7,81790e10,8e293bf5,bcaa6da9,79a744b5,1a76f179) +,S(556e2d6d,11d301c5,6d5d01e9,a01e2ec6,80ba4efe,a004de47,ca2d97d9,15e58d74,9588349b,b633d7b6,b55ba7ee,feecbc99,3d66e6c7,2f4d8961,8a2c5d7,5249d711) +,S(b3506e88,73b93dc8,ed04518a,42b62ea2,b97f7bf4,e9ee66ba,6a7ab917,a1e51586,474f8100,1230fb7b,fe693eaa,7acba9fe,5917a39f,1f8fe3fd,5823ae4c,1b0b3b38) +,S(d186af3,89cb4908,db01a886,f90ee67c,1ba7ff3a,19994504,e9774b96,bd2628f3,3b39782b,c6567cdc,b4778c75,a862ef36,d01d746f,f411821d,5d08f7ee,f2a2db7d) +,S(f951d921,e1065ac2,3fa45900,62c639d,19e8c980,2a810d55,d6788572,ef987bb7,dcf7ddc1,87f8e975,27db239,7f553b5d,51abc66,bb76a070,55d098c7,f9d7d950) +,S(8dce8e16,7bac6fc6,1161b75e,8f340e0b,8bcbf874,fc82a42e,bb53e0fa,c4d915ec,11ce53a1,4a9eb9eb,9b4b410b,34d26ed7,9c0287f4,9032f674,e3212617,e0ae940c) +,S(ce2d3cdd,a0a7a43c,d7d2ed15,ec12a7aa,755dfc5a,ed5a85dc,4f439eea,99e26e2b,6a96aebb,e7ca2740,ea75c285,3c582207,6a8eed64,7e21809a,36b97c60,7a5a145) +,S(239466fc,dcc2d4c5,cef367b5,c8339248,f712c40a,558c80f0,5ea390a8,dcd92092,f2ce223c,9b49f08b,ca63ee8e,98e01736,65d176ab,3b7d718e,d0e855e1,27ac28cd) +,S(220ab764,341d3c08,d9c5bcd8,331e0973,4a2f3c64,4766395e,f6a5fee,3563e033,ec1e4460,d03013ef,467dc7a4,2b520c03,aa51a9a3,57817f4c,f9dcd837,56df5011) +,S(d5455dfe,16406a6c,70fffd81,f3c4d10e,845f0b12,64fa3db4,ee2ffe80,904b469f,a0f93b8d,257e1e62,265d99e4,9158497c,28a20af0,2af959b8,8810a10,60aaf9a) +,S(52367377,a1f6f05d,df054665,f1eec0d2,f5039cf9,cfc1d37e,1a9d89f2,88e60c72,78d89f55,430fc352,cd58d047,7e2497a0,d05e7016,d98f9ce6,a039fc5d,9ec7bb41) +,S(5b996113,3ecc9422,26a3dc88,67364125,a8e569f1,912e6c9f,4c1ddea5,5fa56395,bb9d7764,12076caf,5d8ac902,c5e2fd5f,f7a0bcaa,10898f19,10142af6,4e436d0a) +,S(f36cdb5c,bfbed1e6,58c7fa4a,5b0a6773,eecd1a43,db96cf0c,7c24f32,b84c13fb,cfc6d2f0,5ee9eda2,9156aee1,81b62659,993744e7,479379b9,3156c919,18c394c) +,S(3208c58e,25107af2,b38bf754,5531266f,842ce33,10ec7e44,595fb91,7079a6f9,831c6dcb,5346b6c9,605d9ab5,895ec2cb,653599a2,c88801c6,45a4758a,32c785d7) +,S(a6073a07,1f8510e2,aa021b80,b44d7356,47253583,6501a5a8,c5253918,8c9927a7,e93a9fc5,4c8a7612,16718baa,dcfc9bba,6fefa30d,85803246,2a9f191a,6364fec9) +,S(3350b462,f79eaf7f,260f2147,6aa7ffe8,f7ec1a7e,35624713,9e335758,b9f0d913,1f0c9db3,fce1222,fbd2341,ba8d2e93,20f33bc,482a4d4e,80571711,21152959) +,S(a54d5b17,bc82a74,9207c89b,5a1650cc,1773913e,66f6744c,11de24ce,3073caa,3c243b5f,5309dd11,83c7fe5d,49222c9e,fe62dc26,f92b73af,cdb7b7b1,32cd3ab8) +,S(6590a2bf,676a7a34,a1424f7b,1c7863e,8a7d346d,563905ca,e5b25729,4a04cf8,11cd5803,490419a,1382d972,eea2f734,4f8d0cec,42466f09,39650645,a3e781e7) +,S(b3c09c02,9fc7f48b,d2f461a2,a367011,8840393d,fb5b9592,89e96ec9,c7cba9a5,e7b5aa6c,bce54ad0,197bb1bd,ac030e2b,c6a3e6d6,af2db60a,b97cc92b,8f5cfa9) +,S(d7968ea8,44a137a,7db36143,98b29972,cdc693ef,8fdd4644,26a92939,18fa8bc0,82402589,2901434e,cbd5dd29,410ce2e5,56dd3174,d74da2e5,28326ec8,ad57a75c) +,S(8a57bc6c,2f98f9cc,d1eca172,b2501adb,3bf6edc8,4b50365c,6d959f00,838e8304,2ebf5462,a0f85985,438b5d67,cbfa68c1,bf643410,11a478b9,92cbfe0d,87e7d14e) +,S(51886841,684750a8,c3cb8d18,f8c863cd,1a555dd3,7f0efb4e,551d0d50,6073fd22,eb05f09b,9e983ad0,a6ce0f15,c2f5983c,6a28ce50,6c52f691,f30517da,36f3f192) +,S(fea8c35f,27e4794f,a9eab856,615d55d2,d3a02616,9b9eb7b0,ab7493e2,f67c85f3,c325de97,cf0a6e3a,98512337,8e2ba2e7,b24158f5,4aa97c88,9b54a502,8c148864) +,S(6612cccc,d7bc25e4,f8dab955,d5c1c9cd,d79d5f69,7ef4c510,77b5027e,d1f94b63,615512c1,7a378d0a,e7aabab5,253df9b,e9bd6a80,15c3b200,73d0499a,3457860b) +,S(c998b07a,499859db,4c9d698,33199956,f8a7ae67,9f6d3533,cbdbd7e4,a86f8746,d9e01371,919e775e,a259d81b,ea206e9,37d6b5e9,113838a6,6af11bf0,8dd17138) +,S(5c0e4669,c5cf965f,854fcd0d,23ddc908,c32e3915,460d44bb,520fb0c,3a4cc1e1,cfebbbaf,7e0f9a4d,d2f35ffa,cd0f7cb9,89f5eded,c8b3c554,64fb909c,675adea1) +,S(d0fdda48,30385167,f06f6433,c6a9d3fb,7ab3195b,64f9750b,cb2dbfb8,7158c0fd,4cde5577,6a34f61f,c82e1359,8618336b,f5c6e315,d10abc35,8f0020e3,ef1283db) +,S(d925570f,d78bf65a,5d48265,6222ce74,7cab153,19b7cfd3,7bc70185,fa4a3e81,3c399a,c448ba90,1a21a5c7,b9c6575c,ff52bee0,cdd00ed1,673d8370,87c1924c) +,S(45d2b56d,81f84bac,2077d607,484b0802,a023cc4f,d7818f9a,1d0c2187,98374c8,14ca18d1,92a9cb37,ad50506e,a25663cc,9829411f,848bbf05,3064041,9c19d7f4) +,S(6ad3ac11,8588c5bb,f793404d,df9a10f8,ea8c1978,65a93fba,5b7170b7,9e157400,fa25741f,1e242c3f,edf20e80,fd76292e,382eb5ad,1731ec97,a8762fe9,811686d7) +,S(5da24445,b6dc960b,793ea9e3,912b21d8,26d54028,2ddcbf5,28e1ebf,4a595f52,bc18ff8c,ad1dca69,8995063b,ff8a2fd2,fabfa0d9,8c8885fd,1b401f3,65f16026) +,S(ddff6468,11ce86d2,93b9b89f,865d7133,d7b5f189,d527cf44,5ed15efc,ad32b346,7260e994,cb22016b,e121ae08,12b01c3,4d236b67,13ea510d,b1aeda36,567f5737) +,S(a8b9ff3b,9120fa93,d0f2f50b,c8509846,c1030d98,dc9d5243,6ad9e69b,f897f029,5cbfa29a,4e516872,ea9a4c2c,a3b07efc,c866aaf6,a2b1d7b2,3597e332,8466c591) +,S(943077fb,177b9d6a,723c18ed,ac8deeb2,62875264,868eceb7,a2fc1a01,51dbcafd,219a9fc,41ad01c9,d3f8248d,ac7df93f,ccb6e312,fa5fd442,e48f4a95,18e7eb4e) +,S(75cb61ac,9c9817a,fdf60f52,4245ebbf,82b33f9f,a564d74e,9e810f36,6458b8e3,aa8135bd,f66f0843,460986f5,f9df6b9e,66441477,cd58cfb8,5b3adfde,ec03c367) +,S(1bb7e177,27cb8e85,4bc922b2,28e7f0ae,c34fdcf3,b9bad0c5,750e7c8,e31fccc8,bbf72886,1e855e70,bd9e322c,2425cdea,855ea00c,3e6263d5,2380da38,c0221ca3) +,S(9443384b,39e9dbf3,45b4b41c,f05d0f30,87f02471,c98e2a2e,afda94da,8bee8dbb,e3661173,ccb211f6,38cac6e2,27e3939f,e7b5da57,f6f7a504,abae01c8,fa4544ee) +,S(49bd15d5,a68caab2,8d51638a,ec1a9668,b4c27d54,d6691839,61ccea76,ef740d25,648fc868,8760e47d,fbfb9f0b,d995cc0f,77563b60,eacf3e57,9db7439f,3f18c6e4) +,S(d0c7b78e,92809e85,84d3684f,d078907e,c151aa78,a5832f90,73f945fd,7acfed85,a80d95ab,be494a40,b5529046,bc305203,be91e475,22ad9d57,7ab95b3,8e970c89) +,S(debddd46,3ab22232,5e98f9c7,5cdc875a,7c4c28d8,79748bf0,cd96bd7d,92eb9275,d103c8d,c3fffcb0,5ffb3dd7,a73af259,50d02064,b12bc754,ab594c71,ab9799c) +,S(1d79b17c,192a6a15,8ea2d6bf,9da07312,9f9ebcc8,54b02dc3,3f64012f,1bf33998,6ec818b3,dbc1c8a8,50d986f,bcf64702,c787682,bc408a12,b78e6bbd,4cf60a5e) +,S(2feb76eb,ff5d47e9,7289c38d,7d1535ff,74bd3b57,264c5844,9edfd36e,6e81ca1b,45bd4e4a,7ba3a823,dfae18cd,1f9cabc7,bb462e74,7899c899,378c33bb,89f93b74) +,S(14d0d90,faef5a77,f5372ab6,2e4f5efd,3eef1b39,498653c0,6372fe0b,b0682573,517f169a,80c2b930,4f530f51,d7196831,601a4f97,72ba1312,36ba92f6,36081453) +,S(7306a7a5,728f91c3,384bd9ad,b10b39b2,ad094137,46d2e476,fd522abf,ff313321,215e22ab,a5b9e87b,35bbd4e4,f492f1b1,574c85ed,25b86a85,a8e17b81,b7a915a2) +,S(85d8454f,870cdb8c,b32873a0,698fad20,fd24067a,737e9719,76d4d362,6a55aaba,36d63c0a,36eb9e8e,522a0715,cb9c833d,539fe7ee,111af3bb,951434b1,3117e4a2) +,S(c68f6782,993067aa,259b21cb,9e19122a,2f7da28,96d8cdff,c1f0a0e4,b34384c3,74e6e96a,331c3387,7ea484fb,995d6a3,8dcd493,6b2994ff,b7dc3681,3079e94a) +,S(81448111,5dbe5550,846d5c9c,3351c89c,e29cd850,6870a17f,e18e3184,4214dd3,75dd78b3,d4cdc29c,697740e9,2478689d,540ea33e,5edd6785,210abcb1,670d19a8) +,S(310b5b19,de24d478,f5f25993,a706f21f,24214e1b,cf614ebe,3e204815,60c945f5,8b42c6ca,f01d205,e09d017e,2e840d69,bf04cc53,f02a21a1,47e33327,104318c3) +,S(cf8a47c7,4bafe2b9,dfde4bca,b2e6d451,b0a90f11,c684f420,a025974c,bc4bc3e,f0b7b264,a9a78699,786331e6,2c8762be,614d8a69,c0a65c3d,1cc201bb,e34c97d1) +,S(a0fc6226,7352a904,e70100ec,63d3b60b,ab553388,69b982d3,3d747af9,8b8650fc,ba3ae54c,16b24eb4,64b88c39,521c399f,cd162eb3,f9966497,e2b96f2b,3b85865f) +,S(aae5dbe2,535edd47,584d0339,10045333,2e1eaf70,a4e1bfb0,7dce3c23,6cff8bdb,7cfaa5f6,e55806b7,bb278439,2473732e,a51d85c5,a3558321,91195533,b7a7449b) +,S(8a4e9311,5b897550,cbc0792f,b2705a18,5c317226,86da5bd5,b0a17bb,503ae39,1623adc8,d85f08c7,1751b976,daa17572,2442aed8,a9dc1692,2dde923f,d17cef2c) +,S(cbcef535,eca90b09,5295cd61,29010259,8627e1a0,ccbaff26,a51cdac6,87066463,651c2ffa,c2a2c99c,3fcafb9d,8c50e156,498fee17,3462fc25,9d87fb8d,6b212653) +,S(25971559,4d6a2bd0,baa90e33,62b9c841,bf12c4d,2ead6609,9902eac1,ed0f8c99,49e01b6c,c97404cb,8144002b,c33e8bb1,d974dd22,d0a26a82,94bad2bf,2875245e) +,S(b754d68b,2b049f6b,ac389044,c80f0364,a707da5e,3e9b2a89,1672cd29,b6f1445f,1b29b7c1,625e23d1,67092e3e,ddfc2f4e,bea55542,5f4ddda1,af2aec5e,4de37740) +,S(20aea5a8,50e68f39,cc7ca2fe,2f38b5a2,ab0bde8b,d294c40a,afa898ff,4f084037,6ed576b3,f17666ec,6aafd6a5,6fe7e1b2,ab1e883c,31230fc2,b4e1df0,3f59444) +,S(26844e02,919de923,3288cba9,a97eb85a,c6939fd0,7cd01e7b,f0d5e1db,e31979a6,3df9a8e,6a5fad1,266f11e,518fb60c,cc08a6c2,832c45a1,6c7c5520,5c9ebfb7) +,S(11afca61,33a69aaf,27cfd413,becdf9b4,efbe0a6b,1a38b3fd,485dca95,dc28414c,8d4b8790,c0677fe6,22847bbf,8e47b400,9e4678fb,b9c9377b,2121f5ac,db737b1c) +,S(c46e14d5,2fe25d65,37bbe09f,ce7e95e0,4986337b,23e7160d,f3d78dee,e8d2a63d,a200fdab,4211e9ff,2d008dd7,7ddf67a5,1f04b9ef,43fa1758,9b175d58,f5d2b723) +,S(570aa12,578afe09,245f598a,210a7605,2412283c,8f58e142,d31d9cd8,d455e4d7,c28fdb61,f8e90de1,d43439e0,8512a071,9a2beda9,5d0a5601,b932c0f1,2cc50ac8) +,S(d312db5e,88a1cea0,28570b84,e3854e16,224236ac,cfb14d1f,3a33108d,fbc3fa64,ca5e5089,1843383c,845fa0aa,e031c930,64b8aa4a,ea72e6cf,36b617f6,cf97e1de) +,S(1ee22876,9981670e,14da9ad9,9279f001,c9be5eb8,76224a6d,1fe4ec08,aa398087,62101114,e303e37a,dfe42c65,54460d4,b68603a2,580c7452,6ff31c9f,2176dcc) +,S(1fb9cacd,e2b84ff4,ae85511d,1c964c01,1700b9d7,2d4c04a9,4afa9aa5,57bb81a0,430b73c1,295c5f2a,d6d9f59f,74201435,15b1306b,2cfa038e,e0456752,5f737fcb) +,S(d04cc82d,d3cf0b47,69f2934a,9807e743,4a998bb9,fa44d145,f191a176,611c085b,7a4a19af,b551d151,c42cf1ca,ce123dd5,8f4c13ac,c865b92d,15520169,1be5fa9) +,S(1e4cb208,8bd4d17e,ba8b97f1,f27df5df,8a544f8a,548dde15,712e8704,cfe7e9aa,d805c61e,b72933ec,e799930a,53fda3f3,db066396,5c71be51,5e8466cd,a59b828d) +,S(520aa398,707a85a0,d672bbad,cbcfdab8,8f769f69,df3de8c7,17d6dc48,de51590d,98d344e4,a9047a22,c09095e2,f1176aad,3b54724d,998e052a,39a52554,4ee9ada8) +,S(3a9fe3de,165bef7c,2e0d45a0,60693fc8,e7080ac9,783245d7,a79cac6e,7b614ef2,5189446,fd3fdeef,c7a895f5,2934c888,7607ff49,aa6d798e,151061ef,73038d4a) +,S(9c929dcc,c26c0805,e4289a3a,2b6d68c9,8e3c6806,43730056,65fd8e73,da149938,6dfbf940,b4c29209,3f39f6ba,b102762a,c81edf2d,aabe6dd9,56aa140d,396ba2fa) +,S(355b60ce,f4e00651,8baf1e42,e5e7a08b,ee22abab,c69aca66,d117748,89be419e,7f478a3b,b277fb10,5fe0eaaa,cb53fb73,4fc01dae,bb44f1b1,ed146f43,fc2604e2) +,S(76bff14f,21ad4442,e1389bb1,c11e1019,ea966091,97439705,dfce7bf3,d7f7f37f,3855a291,376aab12,b5f4da79,bc22e02e,a29a34f8,9223f07b,93f6a549,8289d763) +,S(91bb9cdf,10577a3b,7e23aadd,35883396,becbb4bf,fa22e1db,fa08f8b6,6156b454,ec6cbb9e,4f149b02,edc53e93,d1611b5c,a3edea42,c2ca9a1e,f2cccf25,94edbb91) +,S(9e56b10f,1ba86c61,36481204,f0c45b09,a7dde7d,4eb32537,f8c310a5,a8865562,cdf3453d,8552c16c,48bca1a3,79ee8c6a,8b523eaf,d1862d5,16f4361d,5a8aa67c) +,S(4e73594d,af286bde,4e6e28a4,23930571,a11dcb75,4e9a4af5,f4972d,988e09f9,a59f23d0,70c042ce,e03d812c,ea274035,af0d8e53,828a418,cd1b51f1,458a36e7) +,S(156fdff7,e92d89fa,691d3c55,7cb2c614,393d5973,4b11bb1,d9fac953,3923d860,4e929637,c448760c,ef6d68f6,4665023c,bff653cd,23132ee,620eb013,a13b360b) +,S(f2c8b650,eb372336,5d57a905,23d34db9,70d23d52,1f893569,98b0a7e7,ae8ea03b,bd9ac314,84a99bf6,973422a5,60bde9ec,204488c7,6739583d,72f42a87,181a7881) +,S(27dd3657,a4a37430,5f5bb92b,a7b816ba,88d526a2,1ae316c,d4a4e67a,c751e3e3,880cfdd3,c0faa401,6afaf3d5,1fe975e4,8a756b01,f7d84e8c,226424b,83be3304) +,S(f6c25e0c,19f7357c,3cc5d98,1cc4b7f3,7a390182,c2673708,1c64f163,ebb3d1bc,8c80b3ea,7c05a0fa,39944d66,643b3589,29534152,adf37c2f,183e7c22,8e89e43d) +,S(c678800c,71305ea1,ea2847d3,d9d37612,ae280305,716fdf45,87ac7f4,a7fad4f2,be5ffbf4,d2fb2b8c,ddb49a42,ebeaf5d8,55d41d39,f106e2d9,2d549e88,6c0b63c6) +,S(f35db221,e66b7786,fc9e2d3a,68f0d1ee,f98177df,a05bfd30,931912e8,13f6d560,4899a808,e6b2040,89974ca5,afe5b1ee,9eccb15,36a7c7c7,bb67cc00,e43f29fa) +,S(2b93e37d,a915633e,db9843d6,c33888c3,5d944f04,c4074deb,d021c639,93e69de9,eb3d1095,c6ffa1cc,93f72a58,f1320efc,366a4a5f,c7250167,6f2d3c88,4b0522f0) +,S(818023b3,90454716,f51913ab,fdb406f,e4875b94,8b14a331,60901d1,66091b69,b3f5718a,6224e447,c5af3e1,f38e4f2e,6fe57389,fa7d8990,f98e44c2,a227e7b1) +,S(1676e6a,244ca69d,b2ae565b,65b14184,6645ce7b,213dc1fb,db33f060,3c662bb6,88e1cba5,deef5dc1,26b20830,d2c7c0d,aeb9689b,16ecc1fd,cf4a31fb,822e0298) +,S(2f931a1,a92537de,38629d73,323e2f21,d9657454,30e32e4c,3912cb21,dc298d54,93292d08,6fbc0fae,eef6fe43,f5626711,95a5b2d1,bdbbccc,52e1dfae,a30ef904) +,S(7ba4d612,f0dd8c91,8bff20d9,b4f45486,be8a32c1,122601af,2d1730c8,a1fd0279,8aad7aa1,f5b06431,b2e20af1,4cd049a9,3018e3c5,bc4c4310,d0234e78,d2401179) +,S(e8dfab0,85fe7a91,6a79b2be,723799eb,d6974d08,ccc8e3d8,5286aa61,c81d5e78,2121686e,519db556,e6595d47,a5487bb8,fbaec53b,b18dd81c,37dbab40,6e3f926c) +,S(7d5623bc,b1597ef4,6f907106,17eb2e6a,ea751da1,5535a64c,94c90c9a,d84ab5e,dc639f31,8004c4de,31514b70,ebe2e8b8,701b3cd4,5d66b7e4,204dcbc2,a0ce7575) +,S(8e81e2d,8074bec7,48986194,b3b82200,1e4ac916,81de2ad5,7b9c84fb,88a7ffa3,4085ec1d,f4a34480,ca56f6cf,762d03f7,fa94e99a,8df93e6c,dc781499,59fa890) +,S(a9d5a3e7,8290ee62,5e18affd,169c6829,73e68ac9,2b5cc52b,53ed3a85,a68da71e,1cdaad6b,f9eb5889,5189ed29,8793388a,8d6e8b20,ce47a536,ee89be4a,b4805fd6) +,S(4f7c17ca,bcda7c0e,3b7b313,4312f848,984985f0,e46ac497,d64b123c,57dba2cd,860bedd9,5f470c3b,f3cbe7c1,d5070cd0,c877010a,9baa8f5e,888b5ca8,a34a25d7) +,S(478f3d7a,9234a7b9,a91bd016,f55734e9,34b8c3c,535725b5,b4fbb0ab,9fa64921,db97a394,f0253f18,ebabca05,c21e9a7c,3f253054,d83f2101,8ffb4d93,b8051a1f) +,S(ace7e57b,73d96e7d,69f7cc01,b1da179f,3ea09aab,61fba329,f2552eb1,fe7963d5,fa0251f2,2b8dbd04,ec90f824,be025965,7e213e4c,1030611b,796efb89,26908918) +,S(cd56e867,f5170771,8253757c,dcdf69ef,4401f2f8,a1d09f24,374040e7,a908d1fd,878f7216,52cf0ba4,8a2b29a2,2f620c7d,83e4bd84,277b7b90,a454bba2,7f338fe1) +,S(3042ea5c,d9d2f89a,64b1dd24,97b25da5,67a2c672,ba067e33,e923e513,ee4d5329,b84c144,d5516a14,a0a8568c,d6d227a2,d3fa1d86,8e05e612,81ce41b3,5a68b1fb) +,S(55e088d,a094ed26,82b042,bafa0345,30a2e291,57af3f1b,ce351ec9,9e712ec0,c6f8297f,64398324,96091933,514c5449,cacadf,82d51db2,82c9d2e,c66b33e9) +,S(bd2db13a,69dd93bc,a37f9181,7a57a0e9,e0e0da83,eed71875,e63b4691,3b408966,46e12660,f9489b2f,123c25d5,f65b3f8,187ee6e4,405b8cf8,78a742a,9b0da2d) +,S(7d7a5110,cdbb8455,5fe678e6,24ed1a14,ef7c5219,986a7ecb,6095624e,7fd3d210,c9578dc3,c0a54524,f819d640,abaa4a04,626a46da,15c0867,72774a59,6ac6c37c) +,S(1ef12317,513b1354,2a966981,34edabc6,fd4e6d29,1bd7782,5bdb30f4,937a3fa7,e0e4b688,a391bcef,3451cee3,36a8c9f9,12319899,4684c039,909489db,590e1ade) +,S(effa0403,766fb976,dbec6b2e,332d2f12,9f463b86,8b9a1d19,49d30cea,1606baaf,8c5b1c83,bf3efa64,f38de1b7,da03de17,b0cbfdc4,5b4a03c2,38221def,bc1cb082) +,S(dc9271e9,76a9a042,5565f022,273af5bf,20bf780d,9d0ea069,df5da661,a087d65c,dc8679e7,b27bd30c,986f11bb,1c73b76c,55ce7c7c,621490c1,944cd8a6,b63d6063) +,S(ae1ddc2,1e1ca02c,218f6946,275501d6,a1336b93,ddb1b2,384ab414,b8264619,21c6b39d,300b6125,ec8e5c8e,19aa76d7,32466bc9,a887c76a,1ff4220,7db26b48) +,S(aea2c00f,fe5835c9,2b892480,83164635,33dd989,bf2bca12,85cce3ab,4e82cf5b,615598cf,935a6112,42a20e84,e670b193,9aad65d4,53ba967,3e8193b2,93dfa97f) +,S(913d0e16,34b43a86,f55b30b6,5914767d,b45e723e,636c866b,6348c8be,8aebf696,e14c6607,51affda4,d02574af,43172024,39c0c10e,148d4305,1487a5c4,39971a9f) +,S(4f0b3354,775cac80,5e0d6191,6bb0f9c8,40fc163d,8878c05a,301252d2,3bc26fc0,b0b75486,3aedfdf8,3a6eb2eb,5f3e25f1,6c0e1077,6e855ac3,fa8fc3f3,bd8da1e3) +,S(5da21940,73cc978f,7673b2f7,5c65ead2,f469df96,f80883b,181a3da4,f316129d,8516d080,743d2670,570d5e63,e19eb543,237b1db,6285b1ea,f3bc1459,8ef311d1) +,S(76e1b330,ca7af91a,ccb92fb4,63404d36,a8fbc132,269d163d,d4beeed1,6be74a23,10b39253,c5908ef3,ec96f2e5,2ffa0dec,2ce2800,31a791,bcaae0de,1e7f5326) +,S(c4be488b,2f210ee1,82f91263,78b23359,8fe8ef57,671ddbe1,d76975d0,ee393e64,bec1392f,a1a09a54,480beadc,b98ca024,b910cd70,f807eaee,10d4e270,bb79f449) +,S(546918d,a141fd77,b1f13848,d3d608c0,25f5be00,4d36a542,56d0ca5c,9333ff37,3d1d4c7,9684be1a,5cf00d71,6cf9a1bf,b0b82ba4,833704dc,c2d23e8f,39914ac7) +,S(cdfc6fc4,2c51ebd1,2df368b0,98ff0f40,2e6df8b1,9c67e10a,320c1960,266078de,5985e930,23e5264,547bef45,6b3774f3,c2689411,b6f7463c,febe068,fd89cb0d) +,S(7730fccc,593b14a0,6f21eec6,2408e146,36f0e4b,4718ce99,c99bbcd4,7cf03034,f17d0fe2,736e412,9c30151b,492aa7dd,52beacb7,6f97001c,cc28f991,3e016b72) +,S(8aa4c3de,474308f4,674c7b55,9f895bc5,d855a7a9,5fadf090,5726b354,7941b3ea,f275c44a,eac2623,1bf4ae9a,df403ed2,78d9da42,150c98be,7dbd5f71,5cb8594d) +,S(15926da4,97a4e925,8976f87f,f8940491,f32d33dd,7855b13c,5cb54d10,d325bb79,15ac60b6,5b1ebfa8,e871bf67,ec9f71b8,1aa03c78,82880d40,d35f16d8,67ce8e51) +,S(55f4f4fe,aa741574,79462b48,f001688e,fc99f545,d4566dbb,35faeebd,f5b1710d,80ecea05,63f24c84,e767b894,57dfec3f,d015a4ad,b6e3fe0f,662521b4,bb02d15f) +,S(95a56acf,402f7f33,fa357c4a,e4db337e,f04a60d7,4cd73e0d,b137f68,e0e93cee,e72405bf,b7c9ba84,16f4e72c,a30c9ae5,d21c89e3,ce5b61a4,bd521b4e,ef6501fd) +,S(28a9fd90,b50d7bb5,13034b7b,c36a9783,c2a697ff,499bcd6,4b0881ab,8e7a2aac,76b151b0,5c7e7ea4,9a263596,81508781,a37cfaf5,14fa1720,b583faa3,9794a788) +,S(6406dd13,6d6462c4,a4116b93,eac38eb0,b571e2d3,99cdb93c,b36fa5ef,e734b672,3974c77b,92b8e614,52d9c9d0,62a911f9,b4c5eb1a,977da74f,defea358,5dd7fd1e) +,S(8fd8f23f,cb62e1c0,94fef903,9933747e,9d40c37e,376703c2,e3c8b666,f1066529,8b0b2f9b,de10175b,24a9099d,75926296,5ba19013,20912baf,3100e057,d4ab5c8) +,S(51780a2b,d4457368,9c0679bd,c8c94e43,cc525bab,2d2723cc,3e0eec15,63a1a24b,5026cd9b,e178d1e,c746e5db,29391c4d,4b6b08a3,3530fdfc,64603fa2,f0e01109) +,S(aa01493a,e7c7f9bf,3d2fe0e5,cd939dca,5b8c8534,6848d065,beeb42a9,8c283561,a08f0b45,4a42b5e3,6463af14,5199e3d2,1783e908,b3e130f0,e9e88110,2cda82d9) +,S(cd8ab749,d4bbe6d4,ac81c4fa,d6a27e81,e4456d4,196cdafb,97fa6053,18ceab70,fc6c7739,bd68a20d,e01c9249,3cd7ad3d,ca862183,b0529231,da32f1b8,5df59beb) +,S(e69cdef2,e824501e,7a17bc54,e0bb4886,379f56e1,c59a27ea,e00bec5c,55fe3e32,e80ed10,40375398,10125338,f6291791,3fe735e6,6c4bbc80,f41d858d,8ac41cd4) +,S(5a4e72d9,182b1f7e,efb08af1,9e3181cc,f6b6ec69,790184a2,f30188e0,dbff8a8d,2d1cf7f2,d5a857d8,3b31c588,5ac33a5d,7b62ea62,7b5b0bee,2d912502,2df9da19) +,S(9e000859,48bd6211,410416b0,3920a79e,d78f154,5dd0330a,8f23d1b5,f8984a2b,36ae0492,412fd3c,c230680c,edb0dfc8,151ab85a,d8d3338,db611674,c88e3f62) +,S(7e0b97ae,b12f8734,ecad35d4,aea425c7,99f88485,f0bc8d18,ac82f213,258bc6ff,e76f4e24,a4be1b6a,3fc3b0b8,ab0b6e5c,ab95fb40,4692f7bc,cc7640b5,69f3946e) +,S(62285cfb,1bdfc495,dca81ff2,867878fa,b3064be5,81be0c86,b9336c6,61038ee2,f2c91be4,5f60e9f3,40e85ea0,8f159dd4,a65ca8d8,21a6e4f7,71f4dc17,849b5161) +,S(70234e81,2de1b5cd,699870ef,36d5c19c,cd3765ba,eef3cac8,6f126a,a6c82623,e2dbf98a,f92a777,263f3c92,4738ba,3140f769,fd5b6ec,7139bb8,41330736) +,S(ae770461,8f31d5cd,ede40ef5,7434b0a7,7dc1b4e6,7f4be5e6,136978a7,cd5db07d,a4e25164,65584487,3f520e42,74037c,5cc43e12,95167b01,d46d3e93,d93d16e6) +,S(cec7ac8f,e4db698b,48ab78fb,768e6094,5b7f4ce7,d643e604,9e349b6f,246f2b53,491bb545,99330685,433bfd2a,7a4fc831,7f5d3cf4,80d6bc32,5ca6d001,b65fadfb) +,S(80276e96,b051e49f,276f62e8,35622979,852e4cf,c2ff8665,8db4d5c7,7c5eee36,f510d696,882589f0,870d526e,5f7513a4,2c4d4ce5,3733f30c,f06d7dc4,f42f6d9d) +,S(b19027d4,9d85faae,e6163934,ef8f8508,e9e351c9,82bda741,b8944317,da85b27d,c12461cb,dec0e69c,b378443a,f2eb042e,8439f812,205742d6,dbabb372,ea47a824) +,S(57599d4a,cf07c001,d3d3fc78,aae147f1,989c656f,fbc43081,29e05b2e,570c792c,5cf8ea0f,d215ba16,e18e181b,1b4b4f02,38b57af3,9010ba23,f13bbdc4,18514b0) +,S(5ab76283,fa110b82,c53cda2b,653e763c,306e6f8c,2b07d490,bad6e418,eae6e4b7,ff365643,cc2a78e3,17a7de95,b37b3f83,aebe8272,4162a884,f7437aba,b55e8ea0) +,S(7b93d9e4,8602d7b7,ea52dd45,fa0031de,66ea88e4,4250c898,64903e7f,959d4a85,99ccb201,5ab91fe9,a0f50a0,fefad6c3,f6dd060,1f2ad099,a4851d33,162b52f0) +,S(2d5878b6,af642776,41101be7,2b37b4b9,1de26a21,b9610a93,7ee2ce2,fb96ebb6,138ee05d,df4b004e,820815d9,46716f2c,a887066b,b7d218f5,47d4bd7c,2cfc585a) +,S(1d637068,eebc32da,24a0fce,2e41cb57,cf1ccff5,38cfbee7,ac13269c,e560af3b,6a932df1,a2896445,6685ce54,2ddca0ae,d589a494,b7ee89ed,1b4ccfd2,c276eadb) +,S(82babb6b,460e1235,f3187a68,912b057,26a478ef,fe929a3,9479cf04,467de64c,3a9f4e33,603d0396,1f3c11c,94d58369,5de43a1a,327d0faf,f51089e1,1345647f) +,S(ae86e71d,4e715bfd,b63d899a,9daae610,a01c5134,c1b9262,c276dcaa,b48090a,3564b48b,fcae8f7b,feac4df9,3b458678,6f2f9e83,9c9c6126,a301de29,4cfd7b5e) +,S(35a5c2fb,fc661cc3,f4ad6ad7,f1eb32b6,664c50bc,91f4000e,f5774364,2aa413e8,4a5029a2,887f6648,3e072782,68a81c85,b901d692,4ccae752,7111bcce,cad6cde5) +,S(386bf07f,4dd508a7,61e7c29a,dd251d9a,76324496,6c6d760e,cbc6b069,5858e2dc,d4f14804,9c1fa038,1d903e19,68fb14b2,f07c621,15a81f41,e811ad87,de407696) +,S(dfec381c,9bd6f4cc,50ac445e,c9104d87,f9c46c7c,cbd70909,fabde6aa,12346f96,5e7344f8,25b6649b,df97ef3c,ad96945b,d1ce0f76,a48b7f2e,56ccff02,797553f1) +,S(3606dcc6,4db04cc,5493e0b7,ea0bfc2,f8a24302,d2358aaa,7c1ea8,842abbb2,a5c8743b,bc4d9b74,b8b569a1,feca3667,87eea8b1,be2025ed,bb547e78,5687301d) +,S(3441e737,e19096e2,9a3025a4,71d192a0,db086038,8e76d2b6,66052825,e52b0016,6d10f7e,d5cac98e,73c3ad47,bb233a39,5eb9bd4a,37861b9e,7dbb60f7,81eef0da) +,S(b2c97c2e,460d8c34,b5ea7a5c,456a9cf5,b1d902bf,5cdff030,25410a,26636e99,67133081,a8c8ef30,753417b3,cf6973e2,1f151e1f,27216bfa,23289ea3,e2057b7c) +,S(2740bd8b,59a43ddc,f8ffdabe,d59027b5,9b7932b7,3db45a97,3b6c1501,57e045fd,8106f2b1,f69f1ad4,2c0787a6,3c137753,987aabe4,b0ebd82e,1ea7807e,93b02a85) +,S(a1acffd9,bdbd94c0,cd8b4f40,3f9400c,aaa8e269,d8cc49a6,9ee565e1,89b6c21b,62ec7d7e,733f518,974acfbd,4f4e4f44,bcc4fdc0,cc194a66,df7c16bf,ef0235b) +,S(50bb2ad6,8d524acc,3278c0f1,538d3aad,9a5357bd,332d8cff,6301f417,57349847,d8fc33d5,d03526bd,b97d4c6e,1ef018ba,ba4b33e5,9677f139,b8535287,fbacfb32) +,S(ebdfb262,6031b4fa,d675e860,12288101,948e2ca0,8fd0d32e,c9fd0838,5f4fdbd9,b078066c,c470113d,db3964e4,466e319b,4f853a42,8951aa0a,9c4629a7,a40dbf2e) +,S(5daf4c23,65482a2f,bdef73e8,208fd5ad,d57b35f8,171541f6,3a48b742,e98bd48f,9015bfcb,5a248607,f5ffc83c,4fa3dfec,9cbd11f2,c230327d,b2cc75ca,2e87f967) +,S(22db9c20,5d840814,67a19517,f353f825,238c905f,2b12a77d,8551cc9,ee8533c7,680a1bc8,23432a28,a3219264,2b9acf0e,7ad19e29,b604631c,85f7038b,386dcdf8) +,S(404435d1,2e8be51,92625213,f86e6e55,9fb44658,44694d4f,4db72861,d4c100ae,9ebce682,b321eefa,e8e04776,8f82491a,dd734e5a,941e0f4c,b6284f78,6d1586d1) +,S(dcc36eff,6831a6de,f8600d1a,3d52da1c,fe59df9c,cc69c9f2,60c26532,e837530f,8609b5e6,7360b7e8,5ea98c13,578566cb,b6b385ff,6990d4d6,5b795acc,1f77a893) +,S(ef0dfb94,1a1c383e,4a44cd04,c633cb48,e991d140,45e2d9a8,b4353e79,9c1a1514,2685d60,f2a75f9a,b733afab,f693ed05,9c3599bc,3e3346d4,61e5c86a,f76f6f42) +,S(24884cfd,c6c3efd6,b4d2e18f,2ca66b06,410b0fba,d9d61b30,86abc537,1d766b8a,7c1cdc85,66f3daa7,d395c6bf,8a23c130,86a78619,aa68519e,4657b17d,ace2267d) +,S(541b6691,c7004a81,2c607756,f81b6f05,485b0708,678d9a45,de74632,4acd8b20,ddccf301,8a3c429a,c749f0d5,2383784,cefff3df,ae98517f,c7f5e764,c5c609d7) +,S(5462969,67262e3f,a905eea4,ff1f8296,f792cfc8,bb9dbb9a,138242c1,a1fa822d,63012289,8e429527,4fad8e7f,9865659f,da2d7370,10f6e185,70dadbfe,21e6880e) +,S(94070912,ad2c129d,cd122bb9,704616fc,3ddfd949,6ce9f6d,6e18020c,ec848e83,9c3b38e5,6bfac9f1,4c901080,b5a732a4,b5d261f8,2b571536,d1fba6d9,b714017b) +,S(2a6330e4,8ddc661e,afa8071c,c1417b92,ea73b060,3653a017,3edb92a5,6e3ca6c9,b38c51cd,4754c350,ba2d56a3,fbf4fbab,5802bc38,6b5516f3,d8b761e3,c3fc7d79) +,S(9142e493,5f95da17,5ae4078c,5ff5a7d4,8c418c1c,7efc4c39,dacb047a,d3f7424d,15165a74,c47133a9,e8684ea5,5a4f9b05,37d0ab7f,58a7eac0,e698adcc,b885cd05) +,S(2e198b29,5cac4dee,dba63ef3,888d47e8,bb8d372,7fcbd69a,d1eea656,ca85804d,31dd5db3,e700ffbe,152b0c2b,1b1c830c,eb382468,1c522e63,676b9ec,6780fd52) +,S(b44e35e9,b2efcafa,f123e52a,7bd9bc58,32a671e2,fbf0264e,5a3f536c,b272f72d,8d489fe3,beb39fd4,2632b80a,1243e64b,f80c81c1,3934ab08,71c16a5a,5aa43423) +,S(dc99ad01,e1324b6d,b5ecf365,c22463dc,f609f0b5,90e6d3be,efddf641,b83a3cd7,b4b422ca,2feabeaf,32c0ad6a,4393c087,a4c1e794,47a043de,cf0fe486,ed11b682) +,S(e174838e,eb991c2d,cfaaf89b,b868f4d1,3029ebfc,ea286376,48fc51ba,f962a359,f80dcc87,27cbddc9,4bb1b60a,4da5cc74,238dc62,821a9ec7,c05ad2a,a0e7570b) +,S(6240358b,15bd16d4,42cd79a4,8b739eb5,4ca21d18,b568b497,65d10dfa,a2583d33,6acb054d,724e7550,ed6d8caa,8a436d51,fc546116,df33413f,a613c0dd,6cec2d00) +,S(a757fceb,560aac0f,543a29b4,bfd3af7a,aa61c077,2c1c07b2,e6268342,e63f8d70,5864ceef,f80855d0,fb4713e2,7bc6a202,b4c07450,6749457b,39d0c40c,f40352da) +,S(f36e1073,57c3149d,902e9416,2e509d19,d4b1f498,bc74814,3a1bd411,2f777bba,d4d7da2d,139a2693,e40d9396,76c3fe48,45f74b43,78f0c25a,14aa9698,3bd1993e) +,S(84ef2d4b,55a40ff7,13934949,b6277ef0,4a8e0e4f,cc49420b,17269d59,224af99a,57affcb7,1d3508f,65ff2b7a,b1d6752,60465e76,754efe3e,80a83085,85ea73a6) +,S(138ef64b,274ff66d,7defdca3,4ff28bae,96b046df,408b3f47,84f78784,3fce7576,ebdd04e5,1d517c43,412010cb,d03252ed,dfe97912,ee4a7d4c,ed98551b,fee1ecf1) +,S(e82f03fe,2ba05692,212a1145,550d3057,2d454728,e2d9989b,435cb608,3d1f318c,191a6fb9,cf295881,92aaaf1f,ea34e123,613b2937,602650f2,eb25f63f,5812dcda) +,S(56a68400,676b6fac,7eb5fb3e,7f345ec0,11117098,c0d1a96b,e44bd2c8,5aafb317,3a41827a,5ae1b7cc,5b9dcb5f,4c41819e,f49ff2fc,ce1d1949,3f5b0ce,9f1dfb4e) +,S(82f5747f,1b353db4,f3afe255,e1f2660a,8f735b1a,e40a5008,4efa3c32,dc1309f5,42e8b903,f4ccc01f,7e87e4c6,71572bbf,d05f9ea2,a4cf7bd7,dd5a9906,264a0144) +,S(89136941,c47b1964,a4b89e0c,376b3136,80ef76c1,19e02bb,bfad594,76e0cf13,b3a2a785,fb6a564f,f4871bc5,177c635,d722e659,77f621a,f6f7537a,2c2d3f3b) +,S(c6250969,c98f580,f0cb51,eef5d8a1,b9954bb,97671df1,c7360a5f,42238909,83d0324c,915eab22,4dd3f935,e197e0e9,552d5bd9,6b1ed240,219731a3,58ec724) +,S(e2399ad9,63913200,4664a481,dea99d85,ad12938d,dd0e4184,27411fd4,8fc7e3b4,60fffd62,beae28e2,2ea836ed,389c3780,5d8b1fa1,fb10f298,f9b54df8,93c69d47) +,S(4d00b1c,186d2992,9a6383d6,cc8d1796,a59c5d7,c27cc7b8,5a1f821c,3003d959,8752ead1,27eb19fd,49dc8ce7,a0b7c7e6,dd4aa3dd,6f8d5cb4,687327e8,ce487640) +,S(344663ef,8b8b52c9,1aa548e9,8b7e1c48,933cbfa3,59644318,5ea973ae,9264121e,73d099c8,9dfe8eec,b957e624,bea5673,6fe3885c,e2f72b06,dfeae760,514d9efd) +,S(37ff484d,dbd22a98,333038d4,7949b4f3,f411d3d5,7ca319e3,5c788bbd,a0de6648,55a5394b,51618d81,d2fb1455,4ec1f5c3,a45cf086,83980bfb,a9aae6a9,20547c67) +,S(cf3bcddb,ad5066b,909339d1,4cc6d3d8,d2881f70,d6f12e1,4d795b06,17556ca5,e12686bc,99e20f20,6220e402,32760224,b61b90f7,8b7c0b1,3c197a47,11678a6f) +,S(961d02e7,db8fd1ac,a38f9110,13d74a5b,d35e47a1,49818d41,49f02edf,5da73402,9462eaac,d698677c,16515ca3,bff217e9,765dc8ad,fe2fa82a,1db05158,71fed240) +,S(43e62f90,574a8e65,25d22ca6,74814ac,3648b724,45a535c,5e1af97e,b46ec3ba,6def0a56,17c1cf17,9369e20e,d18d0503,e141dc85,9edc73a3,18f6a35b,3d939734) +,S(9e682b79,9d79018c,352113cf,98de93b2,457e4b4,a962d160,33b80052,57dfdbb7,9db9cb16,bfe96343,89c468a0,6405d2c9,b2983354,ee9a81e9,3f23ec5d,5049041b) +,S(790187a7,8079b59d,b2a22d13,8520192,5f9682e4,2002c8f9,436876e4,d5a1a8b4,25c8b46,f6b43180,3654381e,56a8e6aa,ade0ad1d,6a6044de,17e9592c,affa456e) +,S(928a4b8a,6c744b33,99e22d65,35a21ffd,662a0dc3,d5bab1d,683ce555,f0169583,251fee84,c064954b,e1daf7e4,5fec87a9,323d55f6,687fdeaa,75d4dcc9,9a6fcf84) +,S(684e88da,81182f2c,ac5872de,8c98b86f,a6ffb73e,9bbfbfde,6c16c3f4,be084c88,c451b59d,fc9d62d5,921ae45f,f7557ab3,ad179eb0,6afb8bb6,bff0645,cf6383fe) +,S(8bdd2e83,a403b0cd,7a8ebfa8,6949bceb,8e8166ce,a8596f6c,ad7b7bfa,4d174343,7220c147,97f682f8,7d707b2f,eec937c3,643bb359,e9effbad,8ccbc8f,a8177172) +,S(c3fa3b21,6e3c4952,85258ef5,f921f6b,b7195869,e46948b4,b69e80b0,be399543,eb2044ed,21f6661b,77088050,3026c2c5,5a519ca1,748bb10f,c8eed953,aec1796) +,S(1c063c13,eb2d2959,379fb0df,50d355e0,195a8bd2,e642ab48,3d6a38a7,af7e63a2,20538f92,d14c9ff6,75c5005c,8c40e26a,b0042874,7f446ed7,cfcf5737,870f2abb) +,S(60c06797,7b54c18f,4b82dc6c,227cb539,6c6086de,107e3999,81f1b5e0,f31d452,3f4546c4,e3eb11b2,e6fd2617,b57afafe,ce0e8bf7,aacc13b,73755f18,dc98429a) +,S(fc15cf99,92256abb,cf263e90,a231ed8b,421cdc2b,af185722,c0af008b,fea36856,abe346a4,d9c40853,70dd46e4,69a3bf24,c01dbd97,f5c9997e,27634dd7,c635d798) +,S(f6143985,18173bb7,428da262,bc8b07b8,1a92b06a,65926ee5,c6f8fe44,27249454,b1d832ef,3a2558c2,d41f06d,4be8e5e8,11fcede9,9cc784aa,b9f3ce18,d701cf84) +,S(579458a9,62218442,41e68542,76a116ab,1f1fd43,109d4bc7,ad5216dc,ee61b5f5,33e56474,68c157c6,15cc8d46,135bed70,21274a4d,97aebe23,7bdd4b61,2c53e2d8) +,S(637553dc,b0804132,b5562678,fe355e8f,abab2001,fe17e3bd,8c051e7a,41fe62e7,28bd6dc2,ad586e1f,f1a6a951,167ba14f,6989b296,874e0d3c,31917920,9b572dce) +,S(eebbd70f,6f64855b,e21ddb92,3e54f583,89e99ddb,577fa8ea,66c3722e,b580e2a3,3d1b6979,15b50345,4a55606e,ad3ac4ec,7c986698,3df60e1d,edc86827,32fd4d68) +,S(4ec8931f,2bf4b1da,6891135f,37791236,3a6e888b,6e5c5ddb,2e350e42,686c56fb,d5f6c679,4c2b306a,bd719770,48dc3e28,3cbab910,556919f5,35d9df23,56a09bc7) +,S(6b5a7f76,fc5b7e7a,7d84deab,ffd5c771,8f49375c,cc4dc1a7,35bc253a,bee9730e,1e935dc4,8fbf5f6a,b12562df,11855757,9eafb8ab,f6ad8b7a,f8f9df64,43b58af8) +,S(2a3129eb,f620958a,4264c759,17e29807,5f5b73f3,21d4cf27,683e4788,9e013af7,e940f5e4,c1fc28b3,fa346ede,fdb8ac7d,4066732f,a6c276c6,89a1921f,d1020da4) +,S(8bfe81c,e99443f3,78307f34,5bf2c826,94a8723b,c4836d12,4c6f5163,bb28b5ab,58b16e27,857e5faf,9768edc2,68d177a4,87de9848,52e65348,36464ac3,f0433c71) +,S(47820cd9,449c566d,2d39daf3,ee4d356d,5423692,a050cf83,1c1337bd,8ad61be3,48dfae03,2988a810,6d069d,22f27445,1200d38c,a9aea665,5e5f28cc,9952c2e4) +,S(2d7f03ce,8e453605,89d221d8,84c3ef28,f9e8dc52,41d7d131,cd6e9921,55a934e2,8414b3c0,5a39f38e,1f14d55f,e28604f9,16a7b272,6d6c843a,57a2b8e8,b7ee9c72) +,S(83887cec,919d8c86,c2150d4e,e842505b,f5a5b06c,b3b1e67f,1dc2005e,99d8e37b,fee0e7cd,f5c9eae2,78d34fe1,2e58845f,fcea9de7,f9883e32,7a2ee941,92b4c009) +,S(519f9e1,138bbab2,da8c03f,565c3fe0,a9d0b709,1a7b50f3,f37df191,d1ca1e24,64d6bafe,2bffce42,3f631ec0,781e96f5,ef6cd6a9,ade6b9eb,367c036a,1a61ba9e) +,S(8091f78f,84bc74ea,69ade208,72936152,3946ffe6,63edee6c,3cd13ad9,4a8fba61,1aaaa58b,af84688c,1cba5d90,d700aaac,6765faec,39e7a212,fe13a9cc,b0bda1a) +,S(50abc00d,d3fe5748,7c2a5343,4a36f10d,8388cf20,56cd5bb4,9ed8e97e,7adb3afc,ab8bad95,14b6040f,b1c64f01,d9b9db01,670fe0d9,3add5d6,8a80e41d,8ded25ea) +,S(a9a428bb,4da01f44,a9e4f253,3436ae75,20e5722e,6d12931f,aa20772b,36a2f110,ba05121a,1830a26c,440f0582,2fa53e20,f8c226b6,85b437a0,557c8450,774c0c5f) +,S(d7afdbd4,6314d677,727fa11b,211e99a1,d6948be5,b7753ecf,64e9b1d0,ac7a83ce,b5f8b97d,748a4abb,a390ed9d,79cb42ab,ee9b2afa,517288f4,80aba1cd,34e21d04) +,S(2b6b834c,d2b54466,a3d41694,b672ac55,13f19b1a,d518ba99,d622abfd,9b6de265,c1922593,ddc0b3d2,ad1d52dd,3cbeb2e5,74ec849b,892d9df1,87ccec50,7ab9b0d6) +,S(f393cf4a,d7f93fa3,1596ef7e,a9c11c6b,f29c344b,1a3ee5a2,51360c9b,a96ac8ea,4e811ca9,de67ceeb,90e48016,30d06125,fbfa56b3,35e3a7ec,41bedbaa,7a8133e1) +,S(bc3b9250,4e14b254,81305012,a248a94,bbc546bd,52fbc0e,848d75e,9c8f418a,9a52afc6,f8b487c1,7653a911,f11d78c5,8f5eca38,c761a2d9,af0ef2ad,a6a58223) +,S(2f5a0e73,c601fb8a,7321e170,4abdb1f7,e71edc3b,bf6f9cec,1467eef,5f6055c0,d8bb1d0d,142d2cb1,3b9d97f8,f807212,b79a5ecf,13d942eb,c5a3f442,6553e393) +,S(b83e51e3,b4fc69ac,84d099b9,6916c11d,8d8d8d7b,f5cbe15b,fa13ed34,73a54ae8,232e0f88,69c53923,22018084,a7cfc251,daeb7a84,6e1daa78,f3f365c2,ca3dda5b) +,S(10971993,50b07a32,1532b372,2ee89058,e90e9b30,5908cc0e,a249a40b,e7516377,69a0b67c,7bd55a04,9be3a3a5,e308799d,dc735f9,ce56ff67,2c796b6e,5a0a1055) +,S(dbeef75c,c95d5018,f3d71711,a0299dd2,62250814,c1469647,dcb27a23,e85c4477,dd4712cd,16334f8e,2baa6855,6c5237f8,676311e3,1cbf9753,35e76a90,88d66413) +,S(28cb1199,2bdee938,f3405f18,537b410f,2723888,e4ca0d29,d96806d5,6baf114f,e6c63fe,bbe5dd81,e3a9fc1e,83a5ce89,c3e2ef6c,c2a57fea,695ebf4b,e81e5aa3) +,S(f0a2df0b,64efe99e,65f9f176,89cec5d4,caef385a,e4676da3,790ba2e2,4e9f60ba,a7ca7e08,b900f664,14498c12,aaa77da6,6a2520,7bcf1a85,713b6d14,807a4519) +,S(d1bb46eb,38e54396,dc7ad4f,f553106,54fe9b06,9abb1410,799dffe5,482b0f00,14b0619f,e08830b6,d0a5463,96826b6c,d03bbd2c,af930b14,a031f922,eace4214) +,S(27bd2e56,7705126a,5f5adb31,ac1d09a1,85d74002,c548a84,15c0cce0,1f69517a,12203dd7,cba21cd2,9f9ce428,a8e302d7,202690ad,8734c08f,65578192,a5468d32) +,S(6b2cc790,1c72e201,693835ef,ab2b676f,55441add,b8dbc3bd,61d43201,bfd21d9c,59973406,deea0493,daff90d4,b62ff38c,6690bb05,18e75560,1bd5b3a3,4add7456) +,S(75e85c3f,32f953c5,632a8bcc,6bfcd6bd,c63c3b93,e607d267,5df09fb5,94840f27,22f5a376,8714c73d,96b24f89,d426e668,bc59aca0,cbf6dc47,723f01ed,6cb6bb30) +,S(d37a3071,969e152f,41c0eed5,7e28f1e6,f26e1752,68c52683,15e200b9,f86d56a7,53d52726,98751d1d,dc4b1fb,d9621723,70e296c3,b47436d3,abe20356,76ff6181) +,S(715bb304,7f5e6973,36546640,8e183bb2,67693198,94e341d2,37d5101e,a7414976,28440f5f,9e82d5e8,7a5ea672,2e95c3d6,a89dd1fb,3d81aca,db7609ee,a1a968d4) +,S(f72d142a,4f5b1595,a7b4a52c,c6812ec2,8e4924a4,b087c139,68d8adf7,dac642e8,501b644b,b5d8042c,f16ab9bb,bc594c14,585486cc,fbaf47a6,5378f97a,761087dd) +,S(7b3eff8f,b4ca8a3a,5fc3cf02,a469f34,3840846c,d8fbff28,243b962,c1284c26,be2588fd,15396124,a50bc555,5e161022,3bbf636e,fd510522,811902b5,b1748579) +,S(2441a8d7,71fbeca4,cd365225,7974e4cf,ec2a7035,ff2b58a5,9cc5fc37,8a113dd8,54b0776,5316713,4bbf4c6a,7ac23360,fe035d2d,9316cfcc,ae129893,82447981) +,S(c20fca4e,d05467ca,45b916b1,2f4ab386,512d097c,b64b824d,e78e9a2a,14cf7591,8851acc7,96ee4072,ca87e69c,9dad10e7,931fc48b,238cf46d,2b2355a,e4eecc02) +,S(2f6b0e8d,1375263,b74e415a,ad758130,a34c6c6d,690ddd67,63492eb2,49ec8e7,d0c791f8,438cf6a7,976cb614,eb4c9f67,adc72275,f6236868,e384d538,daf25dbe) +,S(bfafc1be,426f056d,6f8b3ed1,1374db21,fc00373c,3dd8c762,c5ab91ea,b2b665dd,9c41f297,a4cf003a,7fa7b071,a106da4,6dc40050,a7592781,68436115,150e2a2e) +,S(cf711dca,90560273,6d776f86,759d74f,895980f7,1728dbe9,1df93076,cdcb4e8c,52a379bf,cf25216f,e3556def,e889b23e,2f91f6a6,47ece012,4e140aa7,734f1cd5) +,S(b9be95de,27aaf198,c3001ec3,63690f2f,f516fd75,1864794e,1c3516c9,abd1384b,68875f97,dca1dc43,3e9b614,488cb8f8,1ff85d58,2ba853cd,27fc1227,1ecb6df9) +,S(f5f257e6,c4d06a8c,53442b37,7519ae03,7bec31b3,c257f331,fff53773,28e9638e,b6a1e60a,48d03213,bb52e3ed,d20d0ca,c80beaec,bb40169e,35ff2165,43e986dd) +,S(fc35c74c,17e38aa1,15803603,30af7d92,a5281b3f,cb6cebf9,df09155e,64099ce7,6e2f984d,41e8693b,5a4c1c58,9814d131,8421fbbb,2ec8e45a,c6239227,db79dae9) +,S(ac135e01,49d97363,7405e5a9,89ffaca6,c1bc18a1,cce34aa7,4732fcce,d54384dd,3e38bacd,ff954a6b,6bccbf63,9f8d709,d8e54553,6113dcb1,c471a162,af021d0) +,S(60a013fb,efb3c5d7,802400c4,e791a019,bfd8f657,cf4c1055,f3674f92,9f5f345d,7e763c48,3582fe3e,2a0a5138,ca320013,9907e364,5468b5b2,711205f3,38a1bd97) +,S(a099a106,5d907a8a,43a3d027,3a789992,ceb3a659,bef93a9,6ed04ea,19a7acb7,137f9ffb,fe3c22ff,c034bb57,9f0c9b46,d5cca4a0,db1407db,6fe3d7b,5bc5a50d) +,S(9ba1da86,d02763d6,187ea5a8,c11c9da4,c6ed7017,49f107b,9ef4fc3,94a792ab,f19e22d8,ab5459c5,5bf87908,90175184,8716aea6,5c2d9650,c472199d,6663f741) +,S(3642701a,d30d1430,17be9363,3f28d90d,b5e02238,9350934f,63a514c9,a677ada0,2fdf9ab9,c76bbbc6,c4e79f48,7a8bbd86,6432fa98,4f52ac22,3440de3b,f1aba970) +,S(29f79c58,100b7098,d8d53012,e2c98719,6188c0d,54712c31,c2ea3a52,d6941a5b,be9edd99,eaa6c1bb,d0ec42f,586a2806,919d5bb7,2d59bf3,7216890b,9a2d524b) +,S(e011aadf,bc35284f,816d5030,c3feb350,4b470d0,ac5ff061,e5ed2c47,89ba1bbc,e0a98f93,4f2b591a,36e6ee97,f293be77,21ec1a9,3f4b2700,55a0c01a,3cc979e3) +,S(a5c8816b,fe5356,37eb54b6,88b9221e,ee06a51,77ffedfb,3ed96ee0,4fd78585,3f86637b,9d63b11a,44897792,9a6aed53,7d65951d,aed6476f,e03be5a8,c9ff8e5f) +,S(3b952c23,7e44350b,95207798,e708fce6,2e6d49e0,912a2509,abef16c9,c7194707,f784972a,419e6c8a,c9d41a38,57912e66,e6ebb631,6bcdeeda,ff49b59d,bdd68936) +,S(8d9796bc,d9d8152f,80c7982a,187a4aaa,b75dd611,99f86632,72502f24,dd57af04,fb9b1479,94a31e3a,28d5695f,2d689951,317c2d2,98e9892c,89c98202,b7e611bd) +,S(96b2bc5b,2f4e6445,1536f689,d7889669,4fde4d7b,6ef67f51,84517704,6a02de40,e0b76d26,f91982db,5039bbf5,afbfce51,914eee9b,352c178b,2145c4a1,88e89cc) +,S(9bf7cf10,9f129500,e2a8f54d,8658ef97,4e3ab2b9,a1d0d036,25bef5d2,432e2d79,2113d7ad,f77e1c68,51b8bb52,188ebd25,dd6373a7,19bcc20b,e32d0f19,496e8582) +,S(10d3ffa7,20375b5e,afc8c741,4d9aa184,c91f853d,61d58dab,11a04f2a,f3d4f1b7,c1f84b2a,8a96f43c,b215c704,6f8c3f02,c98d750a,d416f21b,eeb10ea3,f298c90) +,S(56d64e2b,6adf1cd0,b8d63692,1b68733,e92577e,88430e92,c0e679e8,c3a5eb6,1370e,fbe98423,488427c2,57d5e696,5d4b687e,25e4b824,51b1a6eb,7ef71cc0) +,S(fec4a03e,1c83cf20,75deddbd,20c24792,6dbfa352,a56821c1,420adc34,731528bf,a152b2af,8670e42d,3bba0d98,f387e9bf,1bab788e,fd7bcb2a,a787e6a8,bda95509) +,S(580a7517,7ccea9ac,63ae6d53,e8959e5a,a45d11db,29a87001,779c260f,2fee92eb,793be69c,3263c64c,2048c411,115375a4,86733a90,d8c12a06,862f4f9c,669e8edd) +,S(9286bfe5,78931ceb,cf97431b,1137a19a,991b46d2,d0dec2f5,35edb976,6af636f6,7e774d30,e962db42,83cb38fb,2053b780,c55fce80,51edd5f2,8cb1b5a5,d329f516) +,S(606d55a9,9b702652,5382cf2e,efeec65a,803e3851,da60a041,e5422c1c,28f4890d,dc895a6e,3c2a6411,4a04a1e0,31b8aa17,79ae2c05,1f4eee54,7f8a54c,50eda1a7) +,S(a16a0d40,833ec1cd,dcfef2f1,bcfc8ed8,11387dc6,4e4df6,6e807f69,75f917f5,548d7d37,13de4a53,151f32a8,2880d087,7fd281d9,63011388,ba991bd8,822d6527) +,S(5949d2,be574e23,9a3e3e7a,ae20726c,4a687a15,edf5a62d,9b79d0c3,4f9f0329,71dcb25a,167ab25c,311d9427,5480f78e,f7f4e777,9723e55f,337a9121,445288a9) +,S(841f4e4a,e67b0d8a,49d7b295,e9c1ff4f,cd1e2333,82101536,cef7c4e5,7968b240,1f561c9c,265fa4ed,eb979f4,a8dbe679,ccae8037,8cd73d5c,b56671d0,571f4161) +,S(22623df8,c748e9f2,88bd4b83,142788ff,faf680ae,a2640d,dd43ec1e,46cb7442,380ef00a,dfcdb592,f964381d,ce9f787,17d5827b,494c3aaa,d5e0e013,87a55da3) +,S(816067c3,6438301e,ea07a21e,5a60a17e,670083de,b3b66e2d,c88c6548,f45185e4,5afa391b,9a95e9f1,f04f4e8e,236fc39e,2eeedcec,45026647,f5982aee,4dc4cbf7) +,S(f8f23561,4745c531,24cf6431,ba8e0425,7d28af9c,2c196485,3546924d,ce085c1f,a165067,e3b41b55,a548c1b9,3fe76b5e,bd101275,acd29e75,7f66753,6734750f) +,S(21325584,e25b8a15,c25537d4,c70853b2,28bb933d,de04be23,7753b933,57f2f57a,3708c8f2,78ef57a,f0b00d5,17f21a6f,f627b5f1,59ba1f53,d20b727e,86e873e2) +,S(b2f4f7fc,f48519b2,c00c24b3,7ffac141,88b0baac,bc915c77,845cd6a6,3fdfbda3,b206b59e,6f52ee43,3e7196bb,5f4cf3c7,de49723a,cd5b3e17,1c94e28c,7d57702c) +,S(b4e65d4f,5f420006,b7c70fd3,9564f9c3,fd9c5c53,dacae064,62212fec,ee7f7265,307b6ef2,e3993bf4,f321723e,a83ec2c4,3c75b8d,684665bf,fc073506,816bee0e) +,S(4f104593,9ac609ad,25f3968e,9798ee93,aa58b61d,43f4bab,8f2352b1,de3a7240,ed8d87bb,988395fa,581698f5,c55a5093,ed9d0a89,3f4aa4bd,186221ee,7f8179ae) +,S(9b5e74ff,e515c125,9fa6b215,7ad7529f,90018e85,23888738,d097c016,494672fa,1d55866d,4c4e30f1,7bdbf70c,43fb3b9d,fe2df3d8,41e18bc4,3db3e3af,21fece15) +,S(77bf442,ac8cf718,102968f9,49387b1b,30f8a2c2,c76a2cf5,10d817c8,7e17e302,bb0f9e61,1d90046b,1d3b1103,e6c5beed,e4daaa85,f6eee1f2,6a6e756f,d32af0e9) +,S(27de125c,d49f2049,6b028f34,b16a9988,d2f5d469,30834fe6,4bcd388b,78c266a9,f43d86a8,483dd92a,2ad9dac2,4039ad2b,84cdfc2d,323979b8,1a43de25,5cb54bfe) +,S(21bf7178,ae1d75e1,94bb60ae,4efb5a8d,7f026cf0,7f845b13,2250989c,4be9c116,6caa82ad,bc21df15,d1744466,4d3b58f8,76b52291,5696481d,434f689a,edb8d967) +,S(249254,93ee016a,41b65b7f,8289da2,dc9100f9,9c0b956a,66d245b0,5632e234,bca30194,1cb51f98,1504c536,74f6f904,d883ff46,7aec96f8,2ed5ce31,7c45b3d) +,S(d3f644c1,e3472b4c,d46d89b9,6b937108,ea8e9425,9b9316fe,230e7538,7d867f76,91822603,fd629732,a3b37ed9,d5227942,2e536ae,316bfb7c,597b2da5,d8cade5) +,S(c8461f4b,e2bd14c,a88e52c8,147f656d,915c2675,46252e89,d0337f7a,e325b261,18971181,97ac799b,3f632868,e46efdf5,fa3b615a,a8a92b07,e38ceeda,9cdcae06) +,S(b6e5f590,be20a938,c1b57e1d,a7bd6ca1,a8c2406a,aaa5860d,9133342a,c395a380,a6728cf1,a2f2eade,72d86569,ab5a6305,cf01eec9,6a6de026,ff146d5e,7d8a04b6) +,S(3d25179d,465701d0,56d4eee4,b5efc10d,8b70138d,f14908c0,3124ec95,59eb5d6c,158b7bfe,1d61d7ec,633e88e2,b3c5897a,3b56f7a2,ac557c8c,3e032a71,8b95980f) +,S(abb5d54,c7171499,95893425,bda27f10,d8515511,91af6927,9849a597,46f94d99,4cdfebcc,3be28dea,36d06e89,ff4209c3,7012ff0a,d93d7ad0,4e454422,c4b9a161) +,S(989d0125,115ef9c2,900dedaa,4e31cbb2,f1243386,73ec624c,52352907,b325c73e,d3699ee9,945de070,fc1f28ee,14279750,d553df63,2951c0c8,d1668206,94c6c8df) +,S(c4c5c5d4,29c3d1ff,628bbe4,e0edf70d,5e05db13,c82a2af8,2d0e4232,5e013884,c2c76cb8,825188a9,fc29da67,70ade97f,ccee860d,d13323ee,f2ba7e7,efa97eea) +,S(8662d850,c623b65c,8db5080a,900a0e83,be947111,ec0b9edc,3601549e,26c0807b,a71d677,b0c9e7a4,f66a72b3,2918083b,f91e724c,cf8c9526,b3df0f6e,35da840b) +,S(d26fef49,7e7359bf,33309b38,93abbd44,543b73c7,c0eaa626,cbdedb17,1d083898,ad8bb209,bb090b39,6b501ea9,a5070f90,4d60c20,d48dbad9,56d381f8,79851395) +,S(569be8e8,c584b682,7d742ff8,5b402112,5b4560f5,f173c983,8f8785d2,229d8d0f,b09381a4,a8267d89,a8d5581b,f9a49d52,47c74a33,5e26e354,22edafc7,d41b8559) +,S(de34acc3,4d1787b3,ad967bc6,c5960d8f,842f82bb,c95aa255,d4a9e794,d30116d4,2fddb41c,b2b6b52a,57cf4d3e,883d3f0,e322c40b,ef098505,b6cb3d77,a21816d3) +,S(47430b48,76dbb762,6d549b86,1742a5b3,ece85240,70dd83d5,5446fa99,c5c50b1a,d75592ba,7004573,58c6a0ea,dc8ec772,b53dd048,8ddc73e8,5af357a4,af200df1) +,S(f1d1e0b5,e6687266,ba17339b,76bbab6d,8c2d8ffe,f6c68fd7,9140b097,d6e9fe13,a56226,fc233385,349c5483,72300f97,a1d8494d,a67db50b,b96543d5,bf24e580) +,S(22a6f735,76140de1,3dbd0426,e968c374,6e8132ff,383f44c3,c0515b85,f8cdbcd0,9dcd89a8,90270e3e,358dc004,40f95a43,430a399d,a8405e48,e69e3455,fbd18d1b) +,S(2ddc5328,afd8ca0,9bb0c6ea,57442e8e,fc307b30,c29e2867,b46654e3,e1a9ada2,7b9ab90e,db84e6e8,7bedaa6e,31ff90e1,7d07793,19977393,b5fedb73,c087dee4) +,S(60b6f839,a60af52f,d30a116c,58b9c65,1fb1c854,546dfa9e,1a01e2c1,95da0fca,5e77f69f,28cfb414,be39b07b,2469d8eb,b0e74306,1d856bcd,ca54d83e,20d26c40) +,S(2790c19b,9b9092e5,cb06bfd,f95ea43a,2a1f1f28,57c96776,dcd26a7d,ddee53c,fdeea120,d04e6e78,b2387afa,a0217098,de067759,8b2bc5b6,2715d9f3,714e7f64) +,S(e544320f,9ee8bc8b,127576b1,6fad9782,db181ea3,4514f7c0,d7f9046,f5113803,b93762fb,2397444,e69b63dd,9dce7c32,3c73680a,e26b5e0f,95211972,c0510741) +,S(6c7f25ae,73e428d5,860a236c,bbd4d74f,8e2706cd,69bb4cee,39f9aafa,db55313d,d8cb8fc9,e33f9b18,e9a0864b,e58ea921,8db30c4b,d5dff091,6a44b581,c8dc9121) +,S(289d1b28,ff710d47,4d1e9c3e,f3952f27,dd9eaa3a,30ef499,121ea53b,9b93d4e8,f36af80a,aebc2dd5,84cd5cb7,245b3cba,64285932,77f4be38,cf2b394a,ee880667) +,S(f02ab597,ac01d673,25e87b5d,29130c18,2a6f4a8a,d4ef7476,b9fa1da7,5910b5aa,ae88c02a,ecf28b13,ecec5379,5c34633d,d3262d1f,65ecaaaf,fe89640a,cce38adb) +,S(a9a974f,71a73106,57732c82,d6d4c6d3,c625bb70,4ec29a8d,2d8f8418,dca0413a,c20df433,eed4e96f,d5ef222d,860ed1e5,af1497ac,cfd1dc21,26e8925b,91b372cd) +,S(7866190d,728e0899,19a0e9c7,8634b55e,4cc392fc,1650471f,4a21cf40,8d77496a,1bb5fcd9,540422ef,caa8e265,c35a1e64,29d79de3,a9369b23,3512913,ac0cfd22) +,S(c8a7ffe3,44b3b8eb,f00e4e2d,e63d9540,25cc115a,9110c773,ce0130a4,8333b9ac,ca1ffbe5,10c63b5,674141aa,5ca87246,ca91280f,da97e806,dbb523fe,5ee67b6e) +,S(6cbba6a,13ff6ad3,83419e84,e4da6871,9cc1e633,d4cf3347,2f9966e6,4f9208ba,35122582,c7893f4,4fb92c34,e9c4661b,5859889,62a7d1fc,fac8a2a6,1e214a88) +,S(e07f8dbd,691a8611,eb5450c8,2c765dac,ffe9aa81,49ba3e12,87b23fda,fd9de719,932e35f0,8e39cfee,a2593799,4e118c7f,acb0c6e,5b526bc6,894b061d,8cfbc509) +,S(62136898,32fd9416,cde720d7,1d3f32a5,51f3e238,fccc69b8,4b633a2c,86d2c5d4,137e9a4d,62247e41,8596d968,4f1e5997,791f3b6d,69cbcf68,206f715d,be784e9c) +,S(8b010588,62de6706,253eb2fa,f710c086,40a318ba,1ea684f2,3254e8c0,dba7b9eb,54a48862,dcc56c60,cccbf43c,f7a33f9f,dbd7e419,56f0f48e,2ce2371a,19bfd264) +,S(12d3908c,14af8346,fefbbbac,e56bcbae,3fb2ed87,dc30b1cf,eaf480ea,84f213d8,fc4615fb,df7ddac9,84676421,2c4d99,fef41e5d,98e5824e,cb181a98,9a67fdfc) +,S(219d05e2,a7b8cc69,bbce368f,62922992,b474286e,df7c13dc,8da62d16,1784cd2,8aee4f73,9a7eb1e7,8ee9407d,e8fbabef,dd28203b,2161ede2,761e178,a34c7f5c) +,S(d7d0cd59,9a76fa91,f691fa23,ad265f38,49bbe213,c38cb074,852005b6,d85de204,f349572c,60750dae,5ea1330e,a725a0ef,ed1a2d60,c0b1d9d1,e938f37c,911ce2fa) +,S(a3fa69f5,a04c9023,83d8b73f,6fa8fc3c,9f65cfbb,2c77042d,635f4978,eabb6c6d,c798a1a8,9994aab1,4af95b18,f389a2f1,accb2d7,59997e83,72c1ca5a,c3cbdea2) +,S(902e881a,825c457d,79872e71,e5d94170,8540734c,1d050e92,cc5c8afb,13b2d1cd,ff075132,63bf6fb9,11163ccc,f62f8246,de099f07,ccfc9e33,8ac82c30,bda62d43) +,S(325f19f2,4c470556,d361aa2b,3f1932bb,6923ea5a,4f8cb505,d34cc60e,729c144,f4a9aeb8,29a6a0cd,f981bf35,81bf8f9d,73e3e9c1,61996178,2a57c46b,9e94bec4) +,S(6994f3b4,41a6cf61,53e5f860,2cfffacc,bcdf7245,eb078247,63bb07c6,fa1edd4b,ec2fc5ea,892da897,29c479d8,d3f05152,198ee4ab,87f73bd9,27db1160,1874c174) +,S(21855832,4e8f796f,fd51bd2f,8c1f6a8,5663c5a2,b5bad37f,3b7a1052,6acb2d8c,e77ceecb,33cec03c,99690d44,b0343bf7,3b93c495,5d67ccf4,b15d1d76,a1897c2d) +,S(905daa3b,32f2a801,a567c312,ae4772b5,3196933f,487aa1b0,a5674cef,9d91b099,bf6285c3,6d271719,13691d5d,767fdc17,82b64843,5b2ca1d6,b695871c,41cf369f) +,S(df7cfb84,34b60524,75fe5161,3dbe0e7f,1b685376,315397f5,b39951ee,b65339f1,e725cd7e,1419e455,2d953393,dd9651d5,d1beb3c,6fa44d2e,e580ccf4,df558243) +,S(e7fb9efc,88842b9e,a3c96b82,1ca5eb80,385cb276,28cf64a5,d8c5bcb4,e5732491,c8e676bc,a6f9e037,263b8390,675a97d,1353c128,eddabd5f,5e928153,78f22331) +,S(d1a35f0c,272ba216,1e6ac0a3,fa440f59,bad79715,d71e12fe,cc12369d,cd24285b,1f5b70f7,d475716d,b9ef2f21,bb156400,49dc41a8,96102ec1,806b949a,c99edb3c) +,S(66ba6e8,5f2ddd4c,e17da74a,c7ae629e,4f420429,45932e5,55110da5,2a7b079f,d8ebac5b,eb8eefbc,f4da4f35,79bdffbe,21967904,36487733,263089e7,7a80402) +,S(6f7f69a,26881052,b4bcf806,575f9c50,c36e7c22,1d7b9e48,7b1f39a0,b4f3a749,11d06b84,d89b88b,ab4352b9,cc160e50,bc183558,25bb602b,89235aa6,7331a4c4) +,S(4be16d6f,571d503b,26169906,75c01ac5,41c23afe,84cadb90,eda0c21c,926c0abd,1041ede,ffa1f2dd,61a116c5,dd33fed5,d9ede78f,cb2311bd,9a04fe32,9ec1d06d) +,S(8af88c5d,b55eacb6,760abbc7,91698c57,19160335,ee569bd,33bf050b,1e75886,4f5b850b,6bf2b4b1,29aeeb24,596007c0,ca203eb5,d2be6bea,f61bf596,bdd9a12c) +,S(ad33e77a,3316eb8e,1a764849,13915e81,edb69518,8ce7507,2e2b6088,4cef8672,fa0161e2,4bc88bd9,da5157fd,7950c75d,6c4f4f89,f158f13f,16ca5e4c,af7ccd90) +,S(444a81ef,7620afe7,91d96ee9,b1c34485,cdb51e1f,6022dba0,69ededb3,d9d8c2bc,a88017d9,a49d4ebc,2ee811c7,fbfcd9ba,bd268329,1efafb52,e641af11,9751e2fd) +,S(5b1e07a3,9530f8b6,60787e9d,26503a2f,77af3ad1,24ac8aa5,1d10b663,ceaa5c51,fcf4c0d3,8d55e0fb,2731e59b,686a806a,e87cb510,7bbd013b,4500c470,f77810b9) +,S(3e8c17,e986a86,57b4c403,3317e67d,b1d42e7d,9625e844,ba533ed1,73174309,deebe49f,f4f5a35d,ea0f396,63c7ee0e,9db702f5,c296fe5e,696f5521,94cd6caa) +,S(a1096eee,5e9bcb19,9d24c078,b46b528b,6432af90,7f1d57e5,746e83d8,4d112c1,bd13e4fe,699436cd,656b3019,acd54f3c,97eace0f,e1e92fc1,3f08a76d,d2e7c6d4) +,S(54758579,4218de75,db40a6d8,99a75ee8,36861093,4ded0938,98c071b7,6665f2f0,3bd55642,13e1c689,70cdcd94,fddaa656,6bcde4bf,29c761b5,c6f613f6,19174548) +,S(4eb32992,fcb4bc44,bff56604,f4f74586,a4400290,5ee9adf7,f7bbc694,45456057,8576a8f2,68349f01,ada77c67,30510030,e0cc9d8c,66db7609,21661540,ba45c3d4) +,S(350b2def,d2eb4933,c6d428e7,5990a7c0,f291723,f92e5ea2,69c5b4c8,b661a22d,61acdb00,add9f34b,f36126d8,380ef5bf,70f807a8,1320d59e,3540fb25,90de6943) +,S(914ea8be,ce7f8819,5337341e,eaca129b,2da3c96b,306b017,d7afd984,75f360ff,f2aa5548,ebef80a7,483b563c,e8b242db,582948a4,9fc89213,d3272a63,85ac7b53) +,S(f656e17,38da25f4,baabaa6b,d70e3f5f,ad6d44f9,c53e1a33,4596246b,83dc0fef,40a8b4fc,34639287,a65f53c,f373c2c4,c742ce4b,2040fef5,4c31dac9,59fd83e5) +,S(a47c8af0,334e3ce5,464310bb,c0daa66e,d77e1023,a2124182,ce3e6771,933b618f,6dbccb54,56d7c75,5e71694f,fa1713eb,41ec5b2e,8715ec4b,52295294,c0c7f08) +,S(a8a2862,5e1d04a6,5e87947f,82178d5c,3b5fde31,1eace688,6766ee9d,30753ca9,f82ad6f7,483aa04d,a79e672,efa109be,1feb3f75,d73923ba,94df2f1e,2efc2169) +,S(a01ff54e,5f8eb855,e26903cb,3fd407ef,4fe06208,a0f44837,1e83f7a2,31c017d0,2247c6f9,c52f1a68,84c18ec0,77d92514,9fd59b00,27663ee2,f0e5b2ee,f2edf92) +,S(e7b09c3a,626ac89b,6caadbd6,99a320c,61ef4fe3,11f6072f,f2d7c875,8d42aed1,8ed996d3,6a7b50e9,8e5c64ac,e03cf5a3,37c3c5a1,6d99c5e2,c0faefcd,38609fdc) +,S(3bba9e53,336c2a06,ca89fb52,26059041,96307c97,373cb717,3f35a45b,863ff2fd,f2fe9109,3faffc16,f58ccaea,e54e9b8c,419d5123,6e8c960d,52ae8341,27d24799) +,S(f61d22b6,dc660174,22122400,432f533,11950c21,b6240acd,af905f9c,2c0630a3,6068f5a,1a662cf3,93eb7e86,5cdfab18,692bb250,15de2796,1421a457,49ffb05) +,S(a5b60855,6b1aa22d,8bc38dcb,8f3e4721,891c45dc,2702d13,7189be70,e8a80962,f77f97d2,d5e305ca,1fe20b99,e6c182ae,3a9b3a69,7cd5e34a,7199032,fcb1ddb6) +,S(70c3aaf9,eb2562,e1cae950,be6f592e,f030301b,28022ac1,be3aa5cc,85e1a259,3f2cb7cd,31a8d319,ce4626f7,213aaef7,3f91f2be,a17addeb,61f217b9,4c587583) +,S(1dd70dd1,a8755e37,28dfcc4d,443e7911,a67952af,c33e7d93,b975d136,8d06e530,4684f974,1f5894ef,47040074,2ecc73dd,240e677d,b6bee0c4,141dfcd,7190d084) +,S(d44d698d,7aacfd4b,d8d6bb7f,2d0dca82,f5d37c3d,46573546,2b180cc6,9083fcf9,a18d803d,4232965,90c67b0f,4c415bd7,c0c94041,3740be47,2819bebf,87dc407) +,S(84589ae1,30455742,85522ae7,4b1bc3bb,62730a10,6154d9f9,4109c010,51b34ca5,b979fa08,f2a9af49,bf6ffce9,b2fa707f,de14fcba,3de3b903,49bf6235,37b3606c) +,S(3dec8fdf,89118996,bed31c1e,fff15c1d,bc84e73f,fd04c6f5,469d2f04,8b724627,b143f3c1,e20b5bcf,dbd1a555,f4ff88df,dacccaa2,bfd4310c,16ae2710,1beb2c8c) +,S(367a5fc5,519dd9c6,39bfcc4,70ce465e,23a8dde,417b412a,2f0f4374,8cac160,5b8fbddf,2c6bfc90,e291b136,a3e0f8f3,faa64820,97a87cc2,dbafac5c,a7f021a6) +,S(8aa5587e,7777606f,60bab6b3,20d88e93,1e7c2efd,487bacce,5fa3256c,9463efc1,ac5ba76c,98bfa132,c16921ec,aad52289,50beeb34,449e0c18,88a39fd1,d3f091dc) +,S(79c00191,ea632ea,30fd9e6,b0d11c6,af3aa441,eca678c6,a5d6bf3c,c84cae0,3f954070,3b19a941,3ac0b659,bf401c2d,ae9c8bdf,2bd19e85,472d2d82,39dfb899) +,S(c84de722,21a59e95,cdd951a0,66483255,e858aaa4,ada498b3,d4ef8bf8,3a04fc8,73cde958,915abf28,df811109,a6220449,548fcd2,f639102,158bc451,4af0a0b9) +,S(8b1b8c50,c6327d61,e063822b,2a3c5935,fedf74dc,fe694c21,8cb6b892,b5a9d6d5,57bd8952,9f156435,f47dfc47,9ff4314c,c036766b,5b6437f8,41f60cb0,fe168b) +,S(b45eec8a,3ae82f98,52117c4a,341f8184,33a31ce7,719d7650,e783fd52,48702c52,cd556b5c,c7086b4f,905d0fc,ea01497b,25411785,9ee9046d,c988c6e1,9e0a1c90) +,S(a2d5dcdd,d93096c7,67b4871e,ac58cbdc,31ab7013,865a9cd2,c5707780,80757319,7aa406b4,b130b23e,9e6b5978,b1e0b537,227ae8a8,af62c1a6,a6d46ae,4b064547) +,S(712036b4,e5d35950,a7564ea8,3509bec1,e97f6e19,121ae5db,3d314c19,b9ed2b2d,25862ff3,8d0560ea,4698d2f,425342c8,e3a32232,f9c9572a,21d7414e,68a93616) +,S(5bcef0f7,d70fc8ba,942e58c8,79afc973,dca402e3,795adf0,7562b552,f0bfb392,7cc85a4c,ecb45bfd,3efb0e12,c3fc56f9,1a444ce4,73256474,54ccb089,baf1919) +,S(dcd5702f,9d508a1b,afab9f0,af5c4e9b,b9e5f214,6767ab0e,b5c1d859,39741ada,f7eaead7,ea13e3a7,dccd40a4,a2526501,3369d558,6f0c735f,9eb2518e,ddcc1fa1) +,S(2cea30d0,4f629d,91c3ade,1b8b7176,363bfcb9,25d3eec9,784b91bb,e6cb3d9f,a83f4bad,a42ab171,cfc9a76a,a3dde34b,c48ba454,b39b36e3,44446096,a1c42624) +,S(858b41f2,767b191e,df15fcb1,3a41934d,150e54d6,e95035d0,9c6dfc7,a1c32f8d,8180b97d,76dc95f5,478a2172,4802a28,b34d6e9d,f65d5358,e5cecf82,9fde8dd7) +,S(d5c98002,bee359b8,6d1234e5,ff418013,3eb9a668,d2f1294,245fd020,c30e81e6,4e522da4,cd2bc795,65a2e4e,e2fc87b7,a0b6bce9,1d90376d,921aeb49,5b3781de) +,S(ebf9162,2f9cea9f,71a4ddf5,82de4b7d,34002d76,da8acfb7,d4d6c3a1,9520c1ed,eee75322,3e1881cd,8e3fb483,318c75aa,7e43d049,8e53536e,cd481d18,5ad4e251) +,S(387f6a9,d08756f3,8c2e111,af74be68,acc4504,f3669ff6,b406f6c8,a61db4d,288595e3,ea1d5f91,26df96d5,dcf5cf4d,ed0bbba2,37224c4a,59db552e,87cdd28a) +,S(897ff1c0,989bd52e,383a2d70,e5920144,9aa409ee,9fef20df,25574956,dfe46714,3cfbc0c9,308c6529,f4e95a00,644a873a,de094069,36dfd6c6,bcaecfa5,9adc9d1) +,S(3255a8a6,8e0484c7,8b6bbf21,e2d8b24f,bbcbb337,6f84feef,b577ef1a,b5a395af,17b3c002,f9204b84,e6d4a426,d2d74893,79ef3fd5,441e881f,d8122599,2912aeb3) +,S(2ca4a952,d4d9e3b0,3943eeaf,b1eda225,1fbca101,e7071b7e,2778ef9f,ddc55599,bfacbacc,df02c18d,f81a2c04,4748c7eb,e98631cb,63ca16a0,9892e163,23891e00) +,S(c3e8289c,478c334a,d47b0410,e1b6ecb6,46ee5f8,8a4dbd73,10505f6a,de4383b2,5792c2ce,b0431238,647f4309,cb4ed220,229bee,2727b91f,de4004b3,d6f0f55f) +,S(2bbdef60,a86292f9,867ad63c,67f98420,86fb968d,db92d9d5,f87bd27c,15119049,f4a4b762,3536c479,29099d19,3d40d4d0,e75dac62,54f03538,80286756,60a85362) +,S(77a6e090,9e7dacb3,18014ef0,714a4be1,fe3ee47b,e22afd2c,e0333cb9,ff2496a9,54f0e475,b1a9906c,d1d915d1,81961492,34461e27,e163c384,3815d188,5251065f) +,S(d195b96b,78719254,deb4f413,979f64d6,ea94d5e4,79350b11,45c39e45,4f40ff0,238a4440,613c846e,9472d4b2,b0a4db88,b8245cad,a5af469b,d997f729,c0e0636c) +,S(c39aa336,208aa65d,75bb0f3c,6084f414,ad024d15,48da5bd8,113a619b,4815b1f,7aab1ed6,32741dd4,14883b22,6e573ee6,455a0053,6d849200,4b233153,1126fe5a) +,S(e80ca23d,baf82db,cbe0bd27,24cbb31,d6661c70,44d8a8d2,2967764c,fde31f30,a153d1d4,73187878,bcbc583a,5eb83e5d,f67e8142,46861713,8c484744,a597451b) +,S(395b7a65,a5a9c23a,f96723a,4d595a7d,f3e8505f,e0aec120,711cb7b0,2e72ef80,59020dd5,47476e39,36ad37b1,9a256543,4f88cf03,2992f4b6,2229a5e7,e49bf990) +,S(67a7e8db,b83e23d2,7b57e2cd,9512a5da,e8b49545,ffef2577,644fda22,910b495c,7c01499d,3791b9f4,100a89f7,8e80b410,41fd34ee,68ce1f15,a8753032,e8965735) +,S(c4038e7d,76d2e7b0,86986395,2cbe2ce3,ecfb4b08,61423892,ac9b3b3f,6dc0c7e7,61bb3b0d,9efc9b7d,326a27ba,bc34fc8c,129460b,6642629e,72f20351,65e92f3b) +,S(7705a5e2,26a4d3ae,ee69c52f,5fc3f575,b9bdda08,70a19a8,8a525698,c3a25e5a,458e096c,f01906f8,c2426973,d1c6a982,44be9e02,22406207,3a883e4b,53c7a1b7) +,S(f3ce8bc3,5958b5e6,16a994fa,1fe0396,68a5f1f1,b464a875,9e4a3475,34ff48d0,9c1a1d97,be3ad78b,67c8c441,f7aec63f,8dc92aa0,87500d6b,222a2473,e10058fe) +,S(905ec120,de69cebd,b9a9d764,e01d6f88,3ebb94ad,af5685d7,6649e7f3,3ca4e0d0,92617e99,3974aa3a,774a75d0,e51c00ca,4d42ce12,d79ab0e9,3a8e449e,9ca9d554) +,S(b1b74a4d,a3578592,8bad0edc,3664c1e1,27d48447,fdb246b4,f15ada68,9b21eeed,c43539c7,b84e9e8f,bcce3823,1322c4d0,c14e4d90,33c4e132,8f5b26ea,9d3206d9) +,S(d440165,c72f2d46,b2fa2a47,1c42dab7,8dcf814d,12d3e025,bd5fb963,3d8bcf1,e0864950,261f5fac,e97ad9cf,fc7683df,fabab749,1d80422a,ca30721f,5343ae3e) +,S(ff524c4f,722c19a7,f7b910be,6d573a57,fe08d5af,6580aed1,de03f939,5053b303,fd4ad4e,5b25aa8b,b3a62dea,b320335b,5b9f1368,62f5f913,98fbaa61,b753bf0d) +,S(effde0bd,331c1083,e4b76a53,c9c1ba43,8fafa2b0,4a3ada44,63a5fef1,8d8d091e,fd7a869c,a75c2105,e6ae5420,86ccef0e,c563bddf,2b41ab9a,ee0e14c3,1d947dde) +,S(a5e746c0,99c8d99e,88b4a304,b583adb2,1115ba64,e409d278,f40c4571,2f3875e8,7f832112,c2af3830,2c4baba4,f073f7fe,84170939,dd9e8c07,fd2c1eef,2e934a68) +,S(6accb9e3,af5ee943,9d8daa72,2fe45513,7df5e274,486fa46a,1ba19093,32ccb431,f0de1658,842d6580,507c26a9,b68f92e5,a3faf108,1fcf5dc4,43ec9dc9,9f28dcae) +,S(c813d055,e40d32bf,6e8e782b,3ef85698,b86f3d31,ed0123ba,1ec8978a,f72b6d4e,baf6d757,2f924631,c4da4191,684c6280,47d37ef4,2bb9528d,28879011,8d068ca6) +,S(8b882012,2cadfc62,44fbaeb5,8be4d587,599dfae6,2fdf1177,38a844d,97c7aaf9,f5e6c293,ac900da4,f716e131,fa5a42a8,7867c8a4,76808b2d,4093c782,6f7a6a3) +,S(8f075050,f49ee582,b54a5acc,4ffaa443,bc02ff34,4d0717ee,9619d83,2d7310ce,13b901bb,7ab3d325,7cc555c4,a4799a3d,f1f9f9a8,6b7021c9,b99a1315,b5f7fd3f) +,S(bbc852f8,cf643e54,3c65fb1d,f2f72c97,89a456db,21c81f66,921d411f,b0374c58,ad08eabb,e7971e24,b2bf604c,fb248b3f,a27e1c2f,84f032cd,4c14bba2,b30a590b) +,S(2d77dc4b,662b55bb,878edddc,9dcc2dcb,9278cc,b1e549fc,ffa02503,1a80bc1f,288bb0d8,4fa7f2a1,ad1a62f4,e76ef6ee,c07707a0,89caffff,a8e60870,ecd058eb) +,S(bc83f71f,f3b4a86e,b9bdf7d9,94bba6c8,c90945ab,9c858b4f,fea7914a,d7ccbdf9,18e91fa3,e5067d23,809ed455,3d119541,fa3c2563,a3a88b30,20d3e49,4b232292) +,S(7d5b9657,8d9b88e6,b0e11b7e,847d0524,45f83dc0,e2bbb7b3,205db435,2c200919,1e689f7b,8830c10d,c28e7230,c569af4c,b1c9e672,aafd4d35,2faf5570,90515ba9) +,S(85e9f364,8d758688,31dbab4c,7460c4a1,51614887,cacc3cdc,1baf928a,200cdc80,7f4ce518,d5045c0,5865224c,c07f7fc3,5ba5e4f4,c03ffa9d,d5f8e5a1,31369e27) +,S(425390df,c1c094bd,34855816,dbbdb71a,9c1d1077,45b1c65d,a101d974,4acd0810,81f14cdd,20ef4d70,69026d94,f09de176,707547c3,8c0f27d,1e277d4f,1f49bc00) +,S(3cc7cf0b,66dc93ac,250d00bb,60a0f75a,dbb59409,bf8e4419,4cedaff6,413549d7,331a632f,c3dbd899,f688bcf9,9df70e66,ae17b719,a2beb23a,664c1d6,1c204a58) +,S(fd72088d,b8a1bce8,8fc923b,cff789d8,9d6a0b2a,2be3b5f0,17e2b3eb,ce70853d,d3912b23,a38819ba,eb329638,3a0bedd9,93db4aa8,df647494,b710dec9,9eaf599) +,S(3e558f8d,5e0096da,4d8940af,9a0baa25,c7318541,c7dd37a6,b72b35ac,efe65060,2a403d7f,69d805c,3ebbdb3e,fba95b87,f78f6431,7fec0dde,7695053d,e660e90a) +,S(70708223,f525f222,16c00149,fe1b745f,721ec32a,90fd0b01,e82f2049,d8694a7e,ef4ad787,f0b4d53f,19d86ac9,7d943b5,fce17d88,6366354b,410dabeb,efd12569) +,S(eca29625,eabffaf6,4b9eddb7,11e4cf76,440b4a94,def9d2fc,6e5e9114,aa414f72,f1f83875,75afa3fc,b23bb227,4c5890cf,f798b628,283989dc,d3538b8e,237618cf) +,S(5b7c4750,542df0c4,c4606db4,6861925a,da7423a5,66d6c108,77838f65,5f297695,42811366,1ae1889f,d6ccb1a2,4cd9a6a5,de04db2d,5e805079,5f922b9e,791f784d) +,S(af1a5fe6,40cb2ee,d36982dd,1e7882fe,bd5da168,8005838c,b379b986,bc012042,71570549,305fa634,a63d12ed,1fcfc8a2,5768778e,863d4778,b7e41215,ad3e6224) +,S(727443a2,46787e70,f83cd1be,1189c4cb,e1e8b18b,1d57746a,9a319676,9366b1d2,86357826,9bba3e89,a12565cc,1770e5b4,4df56ac0,d202fdea,d68928d0,6d16d540) +,S(967979,db34e62a,149e6835,213991f7,ae2c9a2b,abf3d255,6c5e198a,12640b8d,99dc1d4f,52445651,3cee44ac,3bf3d1ed,8547b827,251b3b01,4d4c07c1,fd9edcc4) +,S(794009db,8f3491e,27ef9d73,905b06b2,be56937d,be57b8b1,59dfb883,af203601,5a6ad64d,7ee5e1cd,15a6a087,289d86b4,5db60d24,243917e7,50eca61e,2ada40b6) +,S(87cbda39,6f90b090,dba9470b,1fb0dd1f,d2f4212f,50791511,cf6297e,a9851d10,9ca095f3,a2a4f997,501fb4c9,c5585dc7,fb8f7952,e11cd3e7,73a92005,a41b63f0) +,S(9ed57b03,475d1752,58c20772,1be7e12,cd1f3ada,5b95fa8,4b245b01,b910acb0,d58c9054,43bd81af,85c58a7b,d0cb3e8b,25310644,8e1ef50d,324eea36,a3bbd5eb) +,S(ef8d0a22,92ca4498,2dac77e3,86113363,35fd9521,fd266be7,d5d354e6,28b0402,e55c4b4a,556881da,a4a23e5b,677c1a9a,f2f547d2,e2b4037f,f9758a74,3cb58b6b) +,S(6dba21f5,a274f29d,502d369f,4fa4ed08,2299f6e1,b12f5c75,abd01597,d127e3d9,7685f72f,a0ce41e,8c4302de,3e6e9c81,c951f69d,d2df0f3c,930da77a,51a39d94) +,S(8cdc3ebf,857ac235,7dc1b0f4,26ed2a52,7841969b,7fb332aa,6ba44693,c8399a3d,234dd3c1,915ac714,6cd8724,9b68a19b,df250dab,2748abec,a5876fa4,b7f910ca) +,S(a00829c8,caa665b4,7e3391b6,f4706898,a9c790fa,29344de1,e88fd882,b5eca2da,b7c8fcc7,1e834cce,5884b129,98318254,23486297,6068eaa8,184b5316,fd424110) +,S(5872f762,446cbeb1,4a12e54a,1d4f22d6,a4ed5b2e,eff7c5f5,640801dd,2149ce6a,8aacd3e8,862757fa,1a70c29e,24364ef4,4c37d5d8,bbacde2a,c75a0c1c,28ee198f) +,S(b70ed5c0,5dba7150,f22677d2,e5b532cf,53e7ceac,919d3b2f,ec4cc6b9,2fd34f2,7e43f528,cc74171c,a2fcee0b,18d8fcb,76c3d69b,8560831,26bd4482,a4d28cf8) +,S(4beaa213,3c6161d0,c7da6d7c,8eb09cba,2e8ca505,a790a7d3,9d0c16b,8053bb52,da4c083c,9cbdda2e,c6626d8f,e4b2ee13,703496c,c298bffa,db1acdca,99d4f6d5) +,S(a8d31ec6,53ce1834,a78de363,c5f9abd1,8594b34,4d34f5fc,8a10e81f,5804831,b4d6a9cd,7cbbe370,9edb5601,cb7c8ba4,8c462c18,594a4bce,64f4c286,dac5cff9) +#endif +#if WINDOW_G > 14 +,S(a8f11586,f3df4945,a753c485,ee0fd4d,e410771d,bddc1b26,c9ff10e0,77b915b7,a4ad6f16,dbd741bc,71b2dfd2,dd2d340,3816bf73,4e73cc10,abcfa6bb,d0f161a4) +,S(13e697c3,812d4772,254082da,372892d4,e1a66e1a,eb16bbd4,f7a0d531,c979cb2,87fa7baa,f6def12d,31e42c14,f672c0d6,a9d0e2e1,ceee2546,d65bd01,c18df57f) +,S(3cae4590,821a9697,a5963269,b44f0222,98f60021,b6048b3f,49c6fd4d,8650c7a,e03f8745,60418449,ad97f28,41664745,349329d,268c1c43,86e25147,6e44b234) +,S(6f42f6b1,cb6bbe13,cf081480,766cbb36,9d2e63e,e691722e,ac81621c,66e0fccd,e5d8f8eb,67702ed9,e33c7b71,e3cd7b25,cc9cd315,314815b0,b67e8622,fd35f022) +,S(43d24bc8,469cfdb7,51ca7d82,98727059,6fac14e2,11d37041,370f3bec,90e411eb,2129d618,fb1f7030,9715b2ee,d8e70aad,8b172b74,425cd747,3a3fe40,d7c50dea) +,S(259170e1,d48b6f36,6a281592,3474f0de,434f4ccc,e45126e4,a15c503e,c1f8b97c,9ec06188,dc194bc2,be131217,bb862943,aa9cf36b,7703c45f,b1ffd282,c3c12549) +,S(18d547f0,426139b8,7837d1c1,ca0f5f06,883581b2,c001e8e7,2565c9fa,80fa2719,26d9dc3,e1145ccd,23ae36e0,5c133f6a,5ebaa9fd,bb954792,3e762a8a,9fb60260) +,S(23b5936b,f2dc961f,2fc93814,4c96232d,dceb477a,753253cf,1bf05713,1b9e58be,9b678070,1bd976e8,8d66e740,2c00bec8,e4fbdaf4,976289a4,4391b28d,45519b07) +,S(46de46fc,209df62,6185387,938724fb,702c3239,fcf29113,2807894d,148774f6,cdc2ab0b,5d37a348,1b44de55,d9c50ce5,4322f8be,6f284ed1,ee49f04b,65f4f2d8) +,S(d3b78208,f5876faa,c4d3c970,3a87a586,e897c11f,dca9a7cb,6573c814,9b5d5da9,112ecaec,9f4451ae,23485579,9cfee804,ee053df7,8e65713a,cd43d953,471863e1) +,S(52d51f46,ac86afc,391e6a1d,8ab1d862,2492ae18,b3e86f13,5e42fed9,4cf3735a,cea47627,e7eefa90,7b8bfd12,f3212ea0,bfaf9e00,f407bb4,8a86039,d4815215) +,S(46451d04,48f3f959,e133723e,b9138a73,b3877adf,f294ff15,6303a845,65a4c39a,fd1c4a00,bbd9aa06,afb14790,5c0530e1,d6c3b5da,c9001b9f,8ec76df3,c7bf3c76) +,S(a12f5e51,16c58aae,90d8532a,9182d54,f539014e,e2d8357e,5ac7854,26fc78db,3db94e9b,f37ced91,7c9f466d,2a6db2bb,21725e9f,f4dc1482,3e6e384a,265e0cad) +,S(98999fcc,38fe6b71,97ebfd61,fe8942dd,be944f98,6f139c4b,7bd6bd3,28ac250c,48adfd3e,c348281d,c23335bb,8702cf8,acbdfc84,9ee34a3a,14bf36ca,b7dd0ae8) +,S(8ac22420,f9b9aa05,705b31f,bdb57d05,218ad72,ce09b489,4d0b515b,4e5940a8,37a7e2ca,442b2446,686f91da,db6975b,6f63454,e3a96df3,de8c62a4,364d30b6) +,S(cd0804d7,b1aea00c,13a94a33,f75f3736,f5759080,96a2d418,c5b54c72,de31d619,c7f68576,10df1c38,6e677bb,dd6dc121,b3d9e9ca,e54d22bc,a5ce1184,a3dc755e) +,S(b6c4bde6,2f8fe3d7,3c32e641,573098c1,c559e847,e40f60c3,49d40050,49b0411e,62c691f1,68510458,3e5191b3,758d7e3a,b2cfa31e,7a00d7b,97e39f88,786f9a9) +,S(c20990dc,70134917,42cec766,8b725c26,d918cb46,6cbf7ebe,7b1f37bd,63d5df0a,6f1e71ce,e28b22e1,9c6f180a,4d7a48be,9fc696f4,cfd418d,134c1196,6e285d1f) +,S(ebf16672,45ac7f7,385b5356,dbf977a9,3602a11,40ada114,7face805,dd93f9fb,24b15faf,3b3ac9f9,833882db,b81a976,9a37e6ad,1a4228c9,a4f7d0aa,fcca3400) +,S(1c620657,63199ded,804deefc,c33822f9,cf3d4c1d,72f2022f,37714eb3,83367621,600221e1,48f74ad4,dae118d1,b6dca782,e00117d4,92881c23,b5a7cb79,86cad767) +,S(40b300d0,7520348,38bec63e,f155b527,286db841,754702d1,d512c183,345d492d,29305ffb,31b1feba,abe027b5,f432679c,e265a57a,3960b8b5,a66e6de9,5a10fee6) +,S(5768ffa5,c8b56772,1e10c2ea,421afef5,dfd84120,a8d40e13,751a895a,fccc6c2d,52ee5ce2,e60ec485,7ee62e81,fb2eb118,4d2a6ecf,d8ab7e09,dd728d16,5e508d30) +,S(d906e71a,b6bc6697,858c66d6,82aa85af,e8d80ced,5f470ac0,8158b5aa,4cabf2b7,c75ace8c,74552756,8cad89e2,201dd954,bc6f4ae6,3a671d2c,9bed78f6,40b7e70c) +,S(f71937e,f4553a81,a3f155d2,2f81a5b6,e080c0ac,bd8f5c5a,fd437960,6a63460d,d6e4e57d,422df901,e6292a28,c83c3bf4,136b5700,f6da0351,33099feb,f1228b19) +,S(3c498699,da858f1b,364c464f,b4317b76,5d085393,1c187888,83072cfb,39ee337c,cf3033a8,9749a0f4,fd4ad867,67b919a1,c946dc67,cc46524b,af5c0015,833daa0c) +,S(c416570e,cbc5576f,97090660,438dc3ec,be269c42,6e36fc44,45d53b0e,b2c5d54d,cf6380d8,76e20ce9,5cc181ac,4fdd42c4,b91d7132,d1b1c19c,4cc0db01,4ed782e) +,S(8f97b2bd,344fcf8,62846992,e826f5b6,7fe7d103,28f34231,8a9f7de9,20d71110,e296632,fe41f8cd,b3da3ca,e1c356a4,2424c649,11dcdd58,c21aa1f8,cee07ec0) +,S(6283f371,8e67e917,5b8c1bf,28e66bd8,470dc4a0,1a720a8f,cf1df325,fcb0e10f,5e80225c,87c0d6fe,3432db79,e8cf4365,8640ad4f,21efd2a4,333eb6ae,a46bd342) +,S(9e29c616,ba66db06,bb71e56a,2a049727,e07b83ff,cdbff6ab,898a73a2,f2f9d58d,b5997133,bdfa29e4,431494f2,8444f186,7c4fcc1a,516ca195,c8eb6fe3,f5693dfe) +,S(7a0db51d,56a2b33b,8ab33329,a1d41454,a30e34fc,3db33a31,45c1cb07,923ca061,334164ab,64cdd8fe,9a106f2d,156a16c1,5da4f07,fbd7f1ad,e9d1fd7a,c8630fc9) +,S(5994233c,13ba74ea,19c1c65a,c3653a6c,cef79c4b,bbb827af,e736545e,33ac05bc,2175bea7,3090437c,9af6f994,b33023b0,5fdb278d,c0c59063,eb3b805e,a6b6bf6e) +,S(11e13de,2371f715,4d15373d,d52c504e,50811146,10ebeaa3,f47a3335,ee4e17de,fa961827,b81e71fd,60696d97,17820d67,ec86e8b8,74d3d4bb,f50df644,61f738b2) +,S(787099cb,c8896328,dad08bca,4e682e4,90461574,29aaf740,23795a1a,47f25ccc,1ea5755,bd653ed,ee7ee8d0,b3e6214,df2e31d7,731a1c9e,47a95f46,8c3c8ac5) +,S(c644c88a,fa42bae1,27bec7d9,528cd695,7bf7d906,942baa4e,14ac960f,46469cd,9d7b39cd,22007b04,f61c5905,3a3b7614,81dd45a1,532d395c,baf8ffff,377f2644) +,S(79d1abe5,cdc8b0c4,9508a87d,46163d1f,ada43640,ca1a5e89,d2f1c07,8c58820a,465cdc,983f1be8,948b850e,a9a4d9bd,f3898781,65d5a186,1c94d3d0,3fb9289) +,S(e8d4fa8e,db2a1612,d7b6fd8c,d6aa2f1e,a8f1ba1,32572d6e,dd0826ce,bede0e55,92aa3d43,e944d032,afa03d23,dcdb4604,56cb0363,1fe2f8fc,404dd9f3,f832f065) +,S(6f99e75e,b09110e7,3d5e304f,bf569037,577554e,51861356,40c2c69f,4a92e88e,63b5bf05,c554aa30,261a09e3,b292b9ce,8f1bcbf0,ad91c35,aed04f31,567757bd) +,S(cb089170,d912f8ae,e59f21f8,8860c0d5,182b5252,3b2cdf35,b9795d1f,20c37815,4e8c5b3b,6d79cab9,9f2570de,8c58c34e,6b6f5e19,b285bc4,6988ac86,20e645b5) +,S(5c248793,51e487d3,af1b6d16,b25367fd,9d2b7185,9923c565,5d7567d8,ffd621f0,5806bb36,ac3cca86,2624401c,27c54e90,c76fc747,7e83e6f6,ac89f22,35c84211) +,S(f1d10f0a,2ce54b90,ee71ccdd,eb6dc4d4,c2cab0c9,5cd35bea,5f20d3b3,51d15896,7bdb4d3e,cc613f8a,8fb84d25,541970e0,6c7385e3,c04022d5,82e2efb8,4998eead) +,S(536a5966,b594b460,bd27b4f3,aea6b555,95940f06,311970a0,36dc0fa2,3a274519,c44b0b54,cdb4eb87,b5d70d9f,bfd4a601,5c34182a,31a882c9,880878,7910b3d4) +,S(7f8165ce,ed27a393,41d542e,ba9ae875,554265f6,1c1c56c6,cc0bbd66,2ff88686,6993724,26c18b1b,dd1207e2,f3bcc0b8,673f481a,e7638d5d,45134835,9b4e39d6) +,S(12214607,c610d012,83b9265b,c59d7458,4e0a79f6,8a4e8535,a72809fe,11a6830a,5d26e498,9e3edaf6,27cc4bb7,105ba8de,3344e506,d9bc9a33,8f1e3219,e473e609) +,S(9ad7f097,1d1c326b,8ac468ef,706f53a1,9e8fff25,8e599f0e,72acaa15,b21d58b7,2e7c0921,2199c7cb,da8d3645,a5bd7831,4234849c,41a238c2,a3dd7fad,fdb8a880) +,S(355f75a4,9df69d8e,4ccad41b,1fb0445f,619ba9aa,34697a5e,24ec8e92,f5b41068,9ca83421,4622ad8a,90a09469,d155bbec,717295ec,c071894c,6c91a7b6,e1345f24) +,S(bcde8058,8336a996,fa6af5bb,5ebf7441,ed3bda73,4802ab5d,5c0eac31,8017c706,49e40844,78cf1912,ddc91907,26411814,a782a3c1,452117c9,993d9e8b,4f247563) +,S(372cbbc3,3417320e,21ac4ba5,f286a9ed,273b6425,e8ed22b,d0c352e4,f0a97270,6e05363c,bbbd6b11,8f2842d1,243dd629,247e90d8,4e7c9d02,c3677f93,d1d01bca) +,S(a1122e8d,82e97ff6,ce9fd024,cd4ff32c,76aa0aac,c1c2849d,887240a7,a368e064,ef97035e,1df99943,1139cb88,e03bdcf0,8b3a5c86,d4b42d13,9b3acb12,e4e7df3d) +,S(e0101d71,1d0c7b60,8093997c,229bbbed,63b05224,53c0079a,518826f9,2bfc9d5c,a0acb9e9,c3d3d384,7f2d38bf,29da71c9,af0b5a41,5bf738fc,be24e367,c8db2fcc) +,S(6df3e575,4b62c92,41f8aba4,12804ddb,74ec864a,12076a34,d9cdf9ce,be336e8b,bc66fbf9,276fc85d,767c2155,ef481295,963cf371,c0ae6b48,50140d1f,c32f80d6) +,S(e5794801,97d3eb68,fd859d0a,a616912f,a2a52a7e,f3881969,626f43ae,4ac20586,3ba69743,176c43f7,7afdabef,a06eabf5,94b9d0ec,1114f352,7cb1b127,697a5275) +,S(7b290c31,de7dcb10,177313f1,9a15d751,c128bb2,16823c5d,69298baf,575657cc,9d3b3707,d8f2b17f,e14b6b1d,80c55d14,b747c3e0,8c79d55a,bb54809f,d96f99e2) +,S(4ce2adcc,18632b7a,560bfc3,beb7138d,8ab210de,6cc7f6cb,47171b45,13e991f7,5aa8204b,689d8f69,a42e08d,5ecd2936,97ba76b2,1bae122c,e9252659,25a874c6) +,S(dd798cc9,97530af7,d7ce96d1,a6a93aba,c29056db,c69eebca,f4649648,4942bcb3,e9ed537e,7b679852,88bab4bf,36ed677c,14db982c,9ce8714,b4f3a32b,56609e49) +,S(356f4414,9da655e7,c9ea5a3a,5c4847a9,f908c608,aa492efb,15e7cb00,8b065b79,2adb4e6a,ce059ee,44ee8962,b4aa8c71,a4d55f31,28f56877,6c70c4c7,19fa6332) +,S(b607a62b,c16ffea9,b30f61d9,c711adb1,d110c6b4,357b1e0b,dc71c8e9,4d06668b,6b933ae0,9ba42b06,96419a90,e6579a33,8f4f3fc7,5134abf,70cef838,efc5270e) +,S(77fec5c9,24fbca2f,f564bdc2,96ebbfdf,d52f0dfb,15011792,57085c0a,8fec498e,6c7729a7,c92a6626,44f33fd3,1ad5142a,b521720,24e31308,dc11f73c,ee29d69) +,S(804dd2d9,8014a95b,7fea2651,195585ac,acab7a46,1f3134ad,f2c4403b,3de98461,66fae33c,458de63b,dd04fce8,1c425938,dc13194c,ac03205a,c278c071,918a4e84) +,S(65866c36,90a6cf74,95ef54a4,f222bf9e,3ea803a8,98eebc19,2214133e,9ad35234,8cecbc5f,4a152864,6350711f,c4df57dd,8a2c44d,4133ec17,c95e00d8,b49c62ee) +,S(eaccdd6f,2a9616ed,d6f8c3dd,bcb04c1d,49f0c4c3,8d8c34fa,d47174f9,2323e15d,15a435eb,e23d23fb,2313b59e,2fe0367b,17b6d9d,e900332a,20430362,19c4591b) +,S(860d382,8ccde42e,b27652d1,c159d9db,57a0b9de,f290b071,e93e36aa,f730c53e,b4688879,ef616c7b,87bd37,641e0381,115dd487,d5fa3e87,99257afd,26906aeb) +,S(fe446d0e,8d174570,49394416,9c332f9c,eb47e70,3f214d83,2777398a,dc8189bd,d4cb299e,760ef11e,a3846dd3,9a49f34,4d5c10bd,ba66dccb,a43e3647,718e598d) +,S(e4e6bb03,528f913b,bc34d910,2a96385e,bd0b8aa9,a07a863f,9d5d41c7,b982a578,46ed6885,471b4806,aca3c265,d0c40535,4bd63da0,af35a89c,e8a86896,63d38690) +,S(12d69042,a5515732,8b729ba4,4fc3bac1,95c419f8,ec71f438,e676d722,4509bc56,80d7fe55,52e88a74,a87d24ea,de1f9e35,de5c45ea,b8a9b48,9e7a0b8,4bcf5d31) +,S(d3ab5380,1f1b1f7,36d94c4f,2af00a81,ee1815ed,83dafdb6,ef5189e4,13a32552,691c4594,657c0809,f7b6335f,fa4fddcf,8af5b729,9262f790,2ef12e34,f546a401) +,S(50bd549c,2da95051,7b4c72c3,67074539,412f3b4c,45ec69cf,aed0fe61,25b50d7b,147f8768,515cb545,2f291d4f,5a627f36,5c88b2b,d19457b0,1fa711fd,9bc71abc) +,S(a36bfbc2,330165f0,728578b9,ec81d14,c0417090,e6ed73ac,e8aff550,2ad9c62a,acb88155,5251f37e,f31aca05,bf33f9af,9ccc57df,58692067,4f11b787,8c7c9337) +,S(2be3d416,ca9627d5,9f259f0,1d52d915,9972f50,c391531d,70a6b79f,735e7413,fc0eaf6c,97d11c6b,cbc2722a,b3e821d5,363b04b8,edf2b700,15ce37f2,f70e51de) +,S(7ca7ca3,393a9884,c94430ad,20731f2b,7629203e,9c892d22,ae6df1a9,fa66aecb,c05c74b4,e2580f6b,9be6efd4,379b7631,26d3e0d6,d4e9925d,1a7f874c,fd620f43) +,S(6805c83e,19aad851,6fd7a4b7,e9bbb82e,28d9d0e7,1f1608f9,dcf37a71,3b434893,2313791b,8fc68b18,444cb309,9cadde98,f4c95ff9,88ddf601,ea3eacb5,bf1c1512) +,S(7540f073,3a358a90,80d2b07b,64e179e6,5de8010,6eed4eec,dc8c879a,87d007ab,998820f3,bac2fc51,48b0823a,d20b5f77,eb7acf5c,fb2e968d,2b98711,a1ef778c) +,S(6eb9b5ac,960407e4,465a0c22,8d98621e,47f169f7,61189aa8,f7de2fe8,79daa64a,6a32f21d,379c38e9,229ed85b,33b4a35b,9999281d,f96ecdc0,18d2482,67d85d54) +,S(e32d3fe0,80d92f46,58331d25,f0f2bbdd,43671885,98cda416,7b4920ff,afd5cae,61a8a2bc,aa82c5d1,1e958a0,fbfae374,138efec6,84ea8e18,af1d13b3,5388d1b4) +,S(22a0ca56,c95c5221,3ca126b,65e5382a,5f14d17c,976da5df,54942495,43415d70,4cfbb8e7,7e3f04c8,69e62ffc,edf23907,e8b17a48,13fc95d3,cf307e2,978e0bc6) +,S(ce3aeaf2,dceb0f4c,50120b90,fc027d7b,b5a4cddd,fc337e05,14298873,e3ff340d,49f2b65c,4a64b462,69e93c2f,ca6cdf14,b0c81982,b095ed3,644805c,cf333021) +,S(75251b27,b360b236,9c0cb297,c5f6ec1b,70f6afbd,5af1acfc,38bd765,9c9dd5bf,cd0559b3,9b18ceef,85c15189,fbd7a93,1ceb3f7f,6cc93d3d,7681f564,17f3f891) +,S(9d69e5b3,32a9ba92,17884f7,e7a1ab91,53a65c43,917c566a,c2969f50,accb9047,9ef330b9,d347c93d,a9441706,a502491d,55d27723,ac1138dc,751308ee,fc6b3a37) +,S(783ccac1,f7d6409f,758849b6,f7c4d5bc,401fe5f5,b08c2f84,1e0e3fc4,fd7a2d47,e5c62a27,65ea5ab8,6aa1aa00,9297d1fe,57248127,a5d3c36b,9665cd93,b6255f83) +,S(dffbb444,8362773f,e45e0272,eeb1a8b8,fefee1b5,59a6bb12,b9613fe,55ef33d4,fd539cf6,aacc930d,2ff104dd,405ae6e,e4a6b3ad,1a9a0038,f4ffb4ba,1a6115c5) +,S(cfc948b3,c14d06fd,c528d299,22305663,d7a427f2,fe08cc2d,942528d,dac8ebe3,81ab799e,5be02ce0,d3aece6f,c6ce84ae,988872fc,ab640d96,c3ea6bbf,3e2e709f) +,S(d9fb08fe,6a7cb6ce,721cca32,74e20732,5933595a,e59aa0d8,811008f5,cee83490,2c7f1287,8b6ad3b5,88cf9483,f08a92ca,ccc18ece,93c68297,4d80ae31,54965938) +,S(4272b558,49ef0ac2,d7830183,bfe3cc45,65ab9d9f,32b9366a,b0477d1,ae93956a,caa07aa5,d117616d,9f442b94,40549bd0,f64e7a2e,3cf96053,bd14faab,196c698b) +,S(69536c0d,6404b026,61598e11,1e6eaa4f,e50a2cfe,879b0f74,4df57727,933367fa,aeed065,2c5325a9,53913334,7e4fc4b0,d2583608,c2086bf6,b2e5ad25,261c6bfd) +,S(199589ed,5c4b6e24,65d58257,2fcfc194,60f7643b,7019c02f,8038d04,70368268,c48567e7,ef7a3507,14d1b479,1a70e7b0,5c1d4351,eabacd9a,1d8d5e80,a5da23c2) +,S(ef3c4f9e,53ed652b,f48feb4d,1c7b711f,5526dfaf,6588007d,1c2ce942,86db1f4,128e416d,570c3eff,d45da6a6,31246fc4,f45b7d2b,8cf85a93,22b5f65b,361fc49) +,S(6bc3a126,11ca8f8,3d0790c9,f5b5b137,4ce51c66,6c553ff6,9d103370,3b3d7cc4,b20988c9,4b882f50,a0ba8194,2f168bc8,f29eb6fc,4c3d0149,571968e4,81b76ab4) +,S(a0100574,5ea131b1,4c180c17,f26bd3c8,1bd48ca6,c2310c4d,34bad277,6bf51aab,177551d,299c9ca9,92de3e9e,f82b115e,6d3cea9c,fb276955,5509795e,4870a546) +,S(15553b6b,defdbee,532599ab,9e0de23,b4954dcc,912f49e8,f084ebb5,af6088e5,8dbaf203,351a1119,16e8aeb2,e5eeaade,b0ee5d9c,2f5020,62b9f5cc,ca40cbf5) +,S(ae84a42d,49dad25f,f0a5320b,d6a33f8d,79c9f2c7,2871f41e,f8b02cc2,c469452a,9b23f07a,234782b1,cfa524b1,ad539ea7,b8fac3cd,e9bfb867,799a2587,95a48ca8) +,S(eecfc7a7,a41f75dd,43e2b85b,5af33ad5,f017e0d4,8f9b9bee,f0cf4499,a3c762d0,65526d26,73b9e5b2,8ec256bc,a524e376,f0e40f62,2db6e492,e1c53820,a3180d11) +,S(35e427f6,d0be7dc1,2d306ecf,be9fd8ff,107a044f,81c38c8c,5b9a181d,f4565440,de09eefd,27a8bb89,d8fc38e8,d32aecb,5c6bdc57,5cdf91ca,2f18e926,dfcca94e) +,S(d27cec9d,11130024,7f71fadd,4ace1139,cbe3168d,174c93d,4c756c42,89cef3da,5747fbf8,c4040895,fded5c00,e1f60403,40e07827,8924ca96,2f83b3f,e50ed701) +,S(df30926a,ca9062bd,7bbef9d9,e312a1cc,49442ebd,9994b93f,dc652e68,25efe5b9,8d1ffe08,de113447,5c3adb77,ee5aa58c,593486f9,c3f27c32,a20df570,6ff5c572) +,S(c2602b7b,56d0eb73,ab494934,5eb77e88,787e54c,79558ea3,dafe3f50,84f96682,45885bf4,65996b12,993efe44,39861b39,84d5fa89,5242ea8,f498695,57391182) +,S(d6d606e6,28c55e08,61a37803,72c17b1,6a2fe04b,e68a0cc7,60fdf7ac,85c8816c,76b299fb,9e716eed,7f09c879,ea8256bc,a953454e,490edabe,c90a2e5,dd277da8) +,S(d1bb671a,10ec5393,9d67f6aa,3b09e1b,57bb6414,e1f707dc,b832ff67,56289c4,47559cac,311f20cd,55760ed6,2e1e87ac,cd8603e4,c1d0cba9,79f6802,6b294a94) +,S(739ab4bd,6b6132f8,2659fcda,5fb46836,7adf2133,37f897fd,70a9552e,786dcb91,b562e798,2bf508ba,1b932deb,3e6b5962,70bba4ca,402db3b4,d806da6e,fbf6670d) +,S(a710cd7b,2aef0005,6d8db954,2abe6cba,2a6c6132,a48a6670,c501fa82,4de21388,4a6037d1,87db5b52,2996bb0e,47fc7509,1ad9eda8,e15faa56,92d56006,e72fb220) +,S(cdbf59c9,b38e40cc,d63b36b8,b6e894a,c6baa22a,93a1382c,9d7fd070,58e69b7a,3e836c78,6954d509,348314df,8ce08f0b,59967aef,4e5f0136,9c6d0f91,2682d77) +,S(1d32e93f,6e5e138e,7d226636,d5e0946b,8117f91b,bd59efb1,560a15bc,657e4dd3,82c43daa,bc1e23d6,3632e167,6bbca422,9797551f,f729cb5d,c8ac1460,46ed20f7) +,S(2730066,cbe72e84,304e3563,a18689a1,c6c8e0b3,e92d8c0,d63a96c7,e3573337,8804d5cc,6aa91f7a,1ae23506,17332f7d,811b8f1f,752fea43,5208b770,94e67c58) +,S(44624ea,a1607e8b,8bcbd736,9c67f86e,6b0f5226,4cc76a3d,b40042cd,bc621cc4,95867a99,d110d9d9,e382d3d8,a5dff78c,d8db012a,972a87ae,ac24bb42,b2747e53) +,S(8ba805d8,864774eb,4494ca5b,f8257bf6,980466f8,30028340,8aafd665,7f1ef49e,1a1164e3,c1b243cc,57507b07,7348495,95cf67c7,b40d4d7f,f10ad096,3f3866b4) +,S(297d0130,25bdd2d3,f4a008d0,d8c51a3c,7b16b605,95958d9e,93e427a8,7ac01267,56361e70,22138026,683b7bf3,1a6bedaa,988d3938,cf8399aa,e0f3175e,61d7e2bc) +,S(d866bb84,23527208,e66f34bc,e26a8ac0,daea9d03,27c9dccd,cdf0e2a,a0588f52,5e16262d,3564736f,30f26e68,1c5ea26a,b6f63429,f0b25dd2,5635a3b3,1fc45584) +,S(ab1e9d8e,b18e016c,d8ec49e4,388636d,5dd2ab55,8b3dbaa2,433a976a,ad8f16a2,a14cbcec,6327451b,15d47fac,d3f3cbbe,fef828c4,6ea07a0a,9c7155cf,2a2f291c) +,S(cf2f035a,ce393efd,3032cb05,4f4e92ae,5311dd04,bf8f3653,5197748d,2094cd30,75b38e90,9f02bb50,7a778243,35a1c97d,75bc653f,c6dcffcf,615bf8c2,ec6b32f5) +,S(a801d552,e63ba120,2c3ff08b,8fb025df,e545ed35,1adf00f,1a08d982,9e8bf9bd,bdb9274d,f5298fab,4cb08f42,252639e4,a24b553e,892cd1ea,93499c47,41c23165) +,S(f7ad7a63,eb2b90aa,3de2a80e,844e5336,287984f0,6075d9f1,26f24108,f4a5869b,d151e7d,9766a81,1db45134,7cc22654,c5ac40f4,a1d82d96,2de02c58,d46cda31) +,S(732541be,26fcc3e8,c824d539,28282611,96717b00,2af01bc8,57f4c0ac,cded0a80,d44adf28,f26370a8,3c9eee24,4e870dab,3fa7a508,bd14a56f,17c9a845,5055f8ca) +,S(892ee5f2,a5266a86,5bf2094,14c31225,b92dffda,7a3ec00c,ee53dc0b,8c3a3367,21bef833,3b983665,7d243b85,c0b4e2cb,6a5b339d,831cfef5,d676c7d8,87a0df00) +,S(1a4597e3,77569fed,70875f9b,f8f5531e,6bd3b363,b96a345f,9275365c,e1e64424,bd142738,fff7b9db,cbff1c,93a968b1,f0ef3e63,8279b745,21aa53a7,6e611f7a) +,S(c7306404,4b4a3a00,6a584193,e915a174,631c8a2e,ac45973,c815a2f4,aee82f35,280adb29,4f9642cc,cbcc4345,28bacdc5,74beb7df,84c06216,68cc2fec,d78731e6) +,S(c06d9d55,264e4ea9,e160fa78,78a7e4fb,1757f6db,fe610966,503ae03,b4723f2e,c0d82600,ae072564,b29373a1,ff1a036a,45f68f22,9d1594ad,1c9584cc,ab732743) +,S(e878c0b2,bf38b500,6c309a51,5121a3c4,5b13440d,74ff6e27,5bfe71d7,51e6926a,4b8be149,11432ff6,c5169731,1c1db30b,c921cc95,b4c98a39,5228c08,b99b6229) +,S(d1f6621f,89ac4421,7ef39a54,a0922c77,dc7addf4,78b15796,2558ae72,9b24f65e,657556fe,e02492c1,97c9c97a,67bf1d6c,eb689415,80a1ce6a,1e4d98d9,64902f3a) +,S(f9199ae3,ae51f441,d88d72d6,9c1ff64a,d5cc4979,b5fd6a23,c514e9b4,66ea0a5a,3c484bb8,8ec31009,eb95b971,69c7ae03,c20dd833,eef53cdf,fdab8cd5,7a82d4eb) +,S(4e059bc7,516d5fe2,510ae63,d3ca9543,f840bff5,710a744d,62de3965,af6a657f,222309ca,242c5858,5a792045,bbfb3e55,b61daa3c,afedd1ee,19a0038b,f929a47) +,S(c1673413,d8b4298f,6ca04741,a3c32d79,83a7d5b3,dd39ada2,53013d3c,9750ac65,333b1660,7b998e8e,fa7e3d32,2d51c052,1de24d3e,9e389f0e,9a00015d,6cc32d54) +,S(c078723d,8abfbc03,63f12766,cf9c6261,9c31173,5f3a9654,b653a8f9,e08f551c,880fa5d0,be09cb8e,4f145749,1c7f54e1,ceef1477,ba7ed718,5f27013e,32deb89) +,S(c77f3351,4b44b047,3835e3ff,abe8d7ac,ae5f912d,aea4e6e0,4ed03feb,78c41ce5,cade531d,26ee668b,5e2fc7ce,421de2f,d9a14dfb,87286c22,c840144e,1290e910) +,S(90e14c45,4ba40739,10f800b2,bcc7b017,ec58660,bdb1e72,16cc6afb,8320277e,61dfb75d,f5f74d47,287f828d,c4ff46d7,fa351a1f,66da99da,40e74758,2c6bd4b2) +,S(34c65f34,23f2474b,7e2f294c,ed4da6b5,c05d19ef,a2b5a792,103b681a,be1a3f68,d0fba1a3,b12d3e4e,f18acdbc,68fc285b,8ef1365,6aa900c8,c86ae191,37f028ee) +,S(fdcc63b0,aa5017ce,215735cc,2802eee6,aa5ef53a,6a258dd7,a128ed7b,9a5df38d,217ea863,5c9b88c7,19c7f9e6,1286844b,d4f4b758,81535954,7b24df0,1fd5bf03) +,S(10624260,58bb9f6,a5e83740,59595ffd,e7013492,4392c753,15853f4d,9c7070f8,84a92509,e809874f,86e60bdf,85c75d7f,2cab596e,185f56d9,262b06e4,e79cf785) +,S(e21f29c6,70cfc7e8,b104921,bb524414,53acdc5f,fd80066,39417966,ca235c9d,41be8bdb,969ddd53,9093dc1,b85dbd4c,a78f7e68,67fa916c,36136d24,b6c4af38) +,S(154a85d8,60b532cc,16bfdcb2,2769fdf3,6dac818e,cd2daeb0,864eee0c,f78a5c5b,15f2dfc9,3e5e08e4,9d340ce4,bb805afd,79f940dc,f97456eb,c73b47ea,5098e429) +,S(ae6f8b12,d52907e8,4ae5063a,114f8e2a,da7be317,454ea505,571f2132,5e4acf42,49376af9,1aea68bd,cdcd637a,909b639c,b7ff8800,ee003fe6,540d6797,f0f296d1) +,S(de42ac26,47fece4e,69341582,7e3c5b7d,a19dbbd6,22da9fa8,58a3be29,8a47bb65,e57cc346,b83b33cb,79a34805,42811d1d,4178805b,a2b88de6,d90b4fe0,ba8e2740) +,S(14c2030a,c65ec50d,2f7c176c,45256587,59cae0d6,55cd57c2,c1ea970a,11d7bd0e,f3d9f0f0,5881801c,ad4df439,3a3bd2df,1a045181,af7ccbe6,7500b02f,61edece) +,S(32fd40e4,7a94e51b,e4c927c1,42b5f470,b2abd2b6,2773934c,a29a5ff3,924b2e8,b3d74958,f17147e5,1da38ded,7cb09c27,96b7e36c,3149d85c,9b7db85,acd89bbd) +,S(fe468154,cef5383,4820fa33,ad85c158,33635cb4,a55870fb,f588fa6,b8d2918c,96650453,25235606,7bcbc214,b0a04021,bc71c9c5,4617b1be,dd34e6cb,dbb42873) +,S(57826e08,8fa3841d,a33ad3da,e5b5a688,1ee770f5,bfe45f5d,507b4801,ccb511d9,6cb01dc4,4da6d83e,77a6e8a6,d374275e,7d8484fb,4863b5f0,34bace60,30e6b3be) +,S(61bf08fb,1d537624,1dca6119,19f0dfcc,7787090a,6747cdff,8757b037,a1ea59ae,6bcc632a,f4f43c6b,547e6ac5,5854268f,1801614e,5bc9d4e6,ea0dcd99,79f7adb1) +,S(f54dac2c,b5521855,9dc274ce,25b77645,6525e91b,c011e657,5ff812e8,d846ea4a,bb9734dd,af492c18,82bd36fb,f365009,bd41b8bf,1378d9c6,a18477b9,ed627f11) +,S(640ebea4,b85cafa0,d5a38ef7,7373bfb1,36b9571e,f9694724,680e92fb,13efe03e,eaf8d756,c70ee813,60dadfd9,702f660b,516fe3a8,4c50043,92bc7c1b,892a43ac) +,S(6c4814d1,e3c6c16c,366c8776,93b6df4e,266b45a4,26fb0d5b,a2d8fef3,a3803975,d9330c82,8fb02d63,33d57990,b6bedffa,ccd143d5,1b5eac78,5c7f058f,af77a37c) +,S(8dca10b5,95293452,7bd2f264,6170b6fd,59d636a1,f2578b6f,cbde0c96,8bb2db30,50da6972,64516689,57d2273e,55dd046f,1c398d1b,9e5e864d,ae6746fb,825ec83b) +,S(1409a8cc,34389c3d,3fd1b482,fefdb25,3ba32070,dc23b7ae,6b8a1ac0,2f00b776,f8f1c0c6,3bef8011,27ffaf53,d5c07c,430566e2,6c4a9591,f92d694f,82d7a9f8) +,S(1c752b3a,2cdb6257,fe8bb102,e7560b8c,6f86e7ca,e809892f,58df3b16,728c0999,9f1341ca,61dd07f8,882596fd,12531577,d09fcb45,5a086b0d,17dd5390,8326c741) +,S(ae8bb1ae,a4341bf4,c18e7d99,7bc3ebb3,d9f13c9f,b01b93f,885cb32f,d0586999,92eaf2f5,c4e231a6,851a2324,a146400e,6b9eaf63,8eca473b,9d4e034a,3d5c8e6b) +,S(e3d2429b,ba45b4c,2d9c9bed,45f384a1,7d74cd28,56c87772,6d9a98fe,67bcef97,729da85f,927c04e2,c1db1458,c133bdef,c454d0d8,88262b1f,418f3420,5df2380c) +,S(858ee23b,e5166c66,b99d48dd,24cb5078,fcad23e4,a8df9f91,53ffcab2,fb8624b,c5088132,3af436fd,c4f63b91,b06061d4,b26fadd4,6bccaf05,bbe1a8b7,338cdbf2) +,S(7c6a82f0,e2d6c5a3,ba37be0e,1bd8d4e1,99f9aa3e,c9c58054,a66099b9,a4938a1e,881916a7,87e1f9eb,b38906c,c101b0e6,5d245fb7,733c0093,9a7f6f0a,9b4d113b) +,S(4c980c4c,144e4060,c00e7476,c782cb83,42ae8b02,6a155904,c29837b9,fc25caf2,fbc05490,a62e49f5,6daac9dd,5c730f90,183ee565,d62ca949,5bc7ce56,61c2e8c1) +,S(c9b66a8f,6c163037,f5bbc7b9,889e9cfc,357ed5f7,a5e5cd17,6a7e4bd9,6da2fa3e,4eb8b3e5,365a6a44,4b277b4e,89b89e04,2b44cbf8,b73f183d,42c9d8b6,547885d3) +,S(f2f8fb3e,2bd3cd82,99e2faaf,bd5809f0,12190658,b1efa389,f58ffe28,c1056fbe,db6c4cac,35f78015,8fed40c4,341a93b5,64af02c0,12d4817c,478726fe,4faf8273) +,S(8556c286,895b9402,283b5d2,f90ec950,f91c4dbd,6c1c8a0d,6b27cb8c,3bc7da8f,f2979daa,81ea79b5,d3ee2718,4aff3805,9bce1bb7,fa36cc53,4d139b83,c176badf) +,S(4d4c2752,5f24a7d3,ec3673b6,a3c8f110,f5bb5c5f,e9675776,3d81620,90579267,43ee95e6,5834075a,83675a88,15babeb9,824d4703,763b5b09,8c3aff78,837b353c) +,S(cc6689e1,d08b243c,a49a7020,b08ce4ad,817193c7,456fbf4a,97fca02d,f1ccf2e6,32f00dd1,1080c238,cc7e8c9c,60a1b7dd,7503417,2ad0464e,1cdb4221,35ea580d) +,S(966525b9,26bb6596,584cbb3,5da78cec,e6709134,700974f2,6cff34a1,23fba535,b5c18347,52894cc5,26336590,d961af5d,2453d9a3,40bd151d,259d8be7,6c5a9e7b) +,S(df7f51dd,b0e6c595,c8f3de9e,eed5da8b,b05e2cf9,a4555001,760888e6,38b11c4d,19759148,2d4f49cc,b69ef50c,a1cbf3a2,49e3958a,aa9af2c7,becbb72b,8d53f8e2) +,S(4ac2754f,93745ef5,61d6d213,7fd2339a,81cfb619,b6699d9d,21897ed,975f6fea,854a0153,17ce38ef,e070da13,c07829f2,1bf50d40,6458109b,5700a3ec,ed6a3c0) +,S(7c062917,2c59c7ef,2d488806,b1131193,b6b6f0e0,221d1ebb,eca1b358,43959694,77f73272,291c1c73,5d79857d,60cc9db6,b6128e86,4613b3dc,92dd970b,d5dba9ff) +,S(c80152f1,e4b7728a,36acf22,158b8215,d8ce0ea7,401274a2,1139dd71,59d81557,dc0c54e9,88d2ee7d,e8a56eab,d358aaaa,4542a45b,a170db58,89d634f1,dae95df5) +,S(9c2352fa,464cd430,31f43578,53feaddf,7d5ee143,c6403ea1,230961b6,377423c6,841277d5,71934bc0,20f71b36,dcba2293,65819fa2,b20c57b3,5774a524,d6fb20d8) +,S(8d7554f5,fcaae19,cbc20c7b,73f22f30,aaeba42c,a22bef77,3d780205,8c8e1d7a,c6bfa4c0,9db5101,d33abd0c,47c4e125,bffab86b,8ed50864,6b6a2b0f,322bf5d2) +,S(1e75acec,28a2ce98,5929479d,e0842826,bd556b56,6961d5db,66c9055f,b1b63635,89cbe475,d2036dbc,9227db67,d62b51e9,ac669a22,76e4e1e9,d0be9b1d,58efca6d) +,S(9fe62187,5e71bed4,7d9f2d79,91e76b41,88b2c8c6,10f20d33,5b38bed2,eee85236,9a3fe290,fbe192f4,8a44177d,4f0d037a,fc6fa8b1,c57032b1,3d5894c8,c426e8cd) +,S(8dc1710f,8869b645,73c361d1,ada3f43f,6f2c175e,b24ec358,6409e978,1687a220,37a4187e,bce1845,9520b60,9317a4b8,f33b371f,1a768ba1,96316f41,373ec87) +,S(71ad2a17,5cf75568,214fbbd1,f177c1a9,9eb75486,c161f1b7,ad47063b,567e8d6a,29d80786,e42d9cd,4c801f96,a7d44eda,5e325acf,3b82e143,2576ff1a,3b334850) +,S(be0eeb11,aaab9c1c,ef7a2004,731e3ca4,435c8a02,548b36b2,db68ea4a,56ad8b7a,cd7ad5,c9b7e867,1a1c7889,95e45cff,bcdfe42a,6222e0c4,1054a0f5,f7bb00f2) +,S(364154a1,3a7d9fa0,b349c6fb,ec36ea43,51cdabfd,8fa79318,88e4ea5d,ee8bf6d4,40b40474,7e8b30a6,a3cdf3ba,f0956fa5,f7f61a2f,89a8cf7e,c2ed7445,504a71ee) +,S(19daf7ab,c9f69a31,8b2cf1c6,69d50532,5bbd7254,c4bc4126,d7b31dcd,e7b558f1,6b740772,606874b6,5b1f819c,c7339ffa,30669d9b,2770506c,e9fb243c,6ee4a925) +,S(5ab3dc00,eb9efd03,ae491844,50fe176b,765c5da7,d95ffe6f,61aa0073,7366c918,2603f1ce,935e3af8,af5e3d1d,d76a3410,200037c,87c17a93,96e11018,260dfa01) +,S(47bc2c3,d7dd83f7,2b2160a2,64640e58,16316d0e,3272abf4,b859dd0f,6c7b27d7,1ceefb1f,23dc61a7,2f663d9c,3cdd6625,441a63f9,f9cae8d5,c4ba88d1,22c0f258) +,S(b220435e,e903f1bf,3b443549,5a01e739,250be2c1,43f08a73,bd7dbfcd,75602ab5,3659abe7,953b817f,fd1c02b6,56da4e54,9df250c0,7c28e9c0,89ba315a,bf25e1dd) +,S(be25604b,d52413fe,2c743031,98aeff78,c27086f8,97fe4b20,be5b6251,52fa2fb4,ebdb5191,aa195ee,a0a39bf7,399bbe03,76073830,fe54cccb,a3194eef,d8d34fe5) +,S(5cedfbfd,633f16f7,8ec8a8f,3dad7cc6,edc1a6bf,3e37cf3,65069731,64aad0e3,70e687a9,d8632ed6,ab188f14,229f2e31,34a3adc8,727c7b0a,d7a16d78,1244c9a9) +,S(8109ca32,a86fa712,690315e2,1bc09265,bb6bae74,588f507,1bedebac,47e54a3a,e7f3342c,6e8a3dd1,f6d02bf7,5610511f,d0cffb40,1c14633d,308c2939,e662cbf2) +,S(54264a0f,dfb894a6,b29b6922,b859d715,77f0359,ef825442,e0d43b79,a0fbfe3e,4884ea59,cb88fb60,4ca4de66,110b7d98,ec529112,d4574cbe,9a2e7a5e,5a4a644d) +,S(f2756955,a6a7db9f,eabaae3c,844cfd37,5d86ad8b,a84dcfba,582bf4a,273f90f3,b24c14a7,d2f60103,a7d3652b,c5e68988,390c0e67,1f0fca22,ed927f6c,96302239) +,S(351da3e,6ab7c98e,840d0dfa,e7231d21,ca21a81b,3638371a,673892d2,e40498b9,e1c5ffeb,43b443ab,d31332bf,aa314fda,5a4c2634,afccfb97,67bceb3f,13ed5f3b) +,S(b5107be0,90f84c7a,e3d89782,c6751b22,f9a7ad2b,3a1810c8,f14bdd8d,52344357,3d5571d2,36a7c9a1,aada0835,9e8ce162,c46a878,5e09265d,bb52b419,144c5b6c) +,S(b6172135,85b2557b,7c253189,9422c428,79825eaf,64d8e8e2,2f7bae12,31c9ceb7,dbfe3609,df9b8e1a,33629219,eb241daf,42d8be2d,b9a20a0d,942f24ce,1a117e3b) +,S(5eeaaf7f,577b445d,13481c9d,a567825c,f0a5a3f2,9ccfbbbf,d8f1f8a5,36e712cf,84a4352d,c40556ff,ab75acd3,b5a63366,39119d8b,f814feb,e55fb3ee,dea5821c) +,S(c1bec874,44b0210a,9a86ca9b,94891d00,e1fee6c7,490aa26a,1af61f97,5dad1c13,14a61af6,d280ea47,433d795,1786351d,f90a9879,7678781a,8d9d8884,e88a06a6) +,S(34787098,f0df9eb5,e4825449,6fd7eb6b,3118dd45,aa0ccea9,f606a794,126b9ad3,85c30ff1,c8dbde4b,88fe9ff8,20c9908a,a35a0c53,c2175524,a5929eea,5566a564) +,S(6599b07b,5d31c19e,ee02e287,ccaa1bce,70890b14,cd739140,6f1d862b,39d794a6,d18396df,27e6fc21,a9c36a1,8d8f73ef,c79e6c56,ecbab9cb,83750220,a816d5ff) +,S(27b50b15,c92c010c,60feb473,5ac6ae0f,9ec0af75,81e41a90,a3a940da,a1a44ee8,31c2c3c8,61e64b7c,df8ca011,bd4002ba,5373ec63,8c3608fd,619bbb92,3552c1b5) +,S(40aed5af,953f3a17,f5d17622,127f16bd,4cc5bbee,33e23443,5f49c4f7,a48e7a32,e47011ee,96c702a1,1eff428d,2940ddab,d17b76cc,6765d5ed,126876ea,2496f6e6) +,S(cb56977d,f69956da,cf40909b,69fe44c1,4a5ad547,a025d684,c9815ff1,b5331ef8,9904de7a,9ce0f656,2f025ffc,79e8b3a4,2e410ad5,8f0caa16,62a13e29,f0b00bd2) +,S(11dc40ff,58c6d2a5,9768a776,41c611a8,2aa651c1,15e9d36c,bd3ebd18,ac7a0df9,4717af95,274f820,28592bc7,4a84e467,9d168dfd,826a292,5789edf4,a06e0e50) +,S(3baee366,3d2033a7,f3170bd0,723eded9,2fad6501,702fa530,b26d0623,8d6992d0,47497025,41900ac2,fb236a26,81ca09db,c34fc84e,98ca289b,63e07d17,2e4671f4) +,S(6b19e8e6,b2010e2b,d461d716,66f691ea,88417df6,773208f5,18ee5fb1,e0fb580,a7c74380,9f744b05,99b6c4e4,709a8b86,241ef931,effd9323,9a6d15f7,22916578) +,S(412a2c52,b31158ab,9d3bf4ac,d4355eab,b7e94e98,6a839681,94a7322c,72bff9f8,c649c493,b19b713c,8b3c4e30,567547ab,472a599e,cc95ea73,d36d373d,c92f7dc1) +,S(b5e0c57b,f79e7364,9826a818,bed1d521,3cb88645,5dc91a4,eb157a8a,dd869c24,752feebe,9614e233,3b876297,175078fe,f9adc63a,4639242,6c88ca94,aa06163c) +,S(f656ab08,9e75bac0,6eaaf373,1cc71347,6a636347,35ab57c0,222589b1,e914160f,d05493f3,52b660e0,4cb00b45,5cede6b1,74337488,dd1650c8,4ddeaeee,b73a6ae9) +,S(bd2465b7,b5af290d,2d1157fa,76e4550c,ddb23922,7d30c255,8f0cc3ad,ae5fa32a,63a28c79,cbb50c21,bcfc85ab,269090ea,d56f6396,1fcc6dfe,b3a000e7,3284880a) +,S(d53c8d24,3dc3600d,fa32dd69,11a87ab,722108e4,192d7cec,4d84eefb,9b32a351,af681092,6afda47a,ef5bc91d,97f273ab,78a21c01,64f59c0c,ed66f7a8,5b67ca24) +,S(4a83ae18,ab379d5e,f6cd2be,77f64abf,8fc23b52,edc88ea4,9efc1bfe,402432c9,e9eef9c2,f595ad74,abf10b85,6ea24ac5,603d46de,c320f9d9,a1453be3,92eef8a6) +,S(d1df4416,dc7cce22,832f9ab0,b74d927b,f9b3b7a5,c52acee5,3d95812f,f26caa82,9e5242f1,163a863a,a5702af3,cdc21f7d,b0143f76,ddba2a2d,d592676c,57c310f) +,S(e6add3b2,583addd7,8299fd2b,14b87155,93dcb13a,3231458d,ab6864ce,87b9c890,384bb2a0,930ecde4,1e9945f6,247a6530,58e26bf6,88226c8f,ee9a1ec7,a1f07740) +,S(7d3f5447,295479f2,96c11443,eb9b1fbd,fe81a258,78ce4195,d2f01290,7e01fe4,d12e4fd7,9f66a45b,2596b066,651d8686,83e62627,95f681a4,12022046,86304ac5) +,S(60636a7,45442fa9,57f21668,7fbdde4e,a6f7f80a,ea2832e,ca3ea43b,d1f12709,395ef963,bec2979c,fb211f8b,da3f4b4f,2c129ce8,26a35367,d955243d,3b40022b) +,S(6bce0837,39c04ba6,b9dbba8c,f668bea9,4d8a8b38,2ac17b87,765bdd52,86e47963,a2d85e2a,7ff5c433,c2c77363,666ddd3f,3fb28f8b,2b7aea1,16a8f42e,384a0a37) +,S(59e4e7e4,438ceba0,cad5f146,bc127c1c,df7f4735,f581a0b2,6a53a366,947d4581,32207f5,95fa4cee,3c8ea269,9578b28b,6290a3c,33eb0ba7,e3bf7267,b2bfa445) +,S(ae2cb18,d4f053ea,3a497162,8c822f6d,72806f79,bd39dcc8,364ea256,f30af032,583d363,b9ac6fd2,709985c5,79603d9,4902da04,1563879d,245433d0,abc54a1) +,S(bc4eb578,630ebde0,f58fb192,377de006,c630e96a,51219379,43e9a240,c30951f7,5224d403,4635eea8,e63b9e87,2875f27a,129de5ff,fae3d516,5f6d0cfb,5bb7e584) +,S(848ca19,6fc34e2c,e484f74d,79565ba6,9685128e,7b2d21fe,8cf0e4b1,edbd3b13,2a41e449,532de110,e0d3fbb2,bb794fb9,32d0d4a6,33aa65f8,ec40e5bd,5c4314ef) +,S(b90e1d09,4257ae30,bd12debe,648d4cea,3f063740,e3f9d3fb,c67eaa4b,8ca0bcfd,5604b475,31b28a6a,e0a13a47,31f6cc70,de91d429,d2204d45,e1423652,5a5a4b43) +,S(430752bc,3e1191f3,6e084f2,5f3e30b,da104f40,1de93267,62dde1cc,39d94c71,e707daaf,841f62f5,6d9c45fd,3304e616,30b6af9c,d6871476,6132e127,40f5ebe0) +,S(ab919243,c8bd75b9,d67f331a,b3b487e0,ee9c97ff,c35de7b7,e29827c1,ab643be2,d4d853b0,3971f1fc,ce365db9,cf4a54f1,5e6059c3,c5138b2e,dd765c51,7bdc0c7d) +,S(adce8be3,2277c2cf,6ee46781,f1da8f30,1cafea51,18322adf,8d6b8a29,fc3f7551,e819a7fe,73311592,bcfda0a7,3609748e,6c039066,feba9e5d,41e125e8,4dd67fb4) +,S(d6ed759d,15f5d47a,146e7fac,423b952a,5eabc238,a0382762,c2a226ed,8c24b601,456caee9,1c212f19,acdc2d82,9eb90cb0,2ac35a72,8d280042,658af65a,b6840e9e) +,S(3583bc8f,c3ca09c6,6f2f4fe2,83da5c47,f0ebcccb,fe8e94ab,fd315173,fd3fb2be,ed60aa95,504e9b31,81225d0c,a4f513c6,6da2a2ce,9fa9afaa,c12e04c4,f1d50b59) +,S(223879b3,b9e50b46,7bceda29,905d09be,1acb206,5b23a61c,686d6f39,bf0744d4,a8326789,ddb38afb,e993ae33,6cb1c3f7,92addfad,e47663fa,52a296a3,b6f2873f) +,S(29329ca6,c6ce20b5,81a90873,7206d44a,95ff382f,1ca0cafb,755a3450,83883d69,5d2aa87f,59e13a0a,8ca4460a,4db7f496,1c118ab9,b4f783e1,305bf43,ed44fe71) +,S(e1c6a08c,593454a4,aa116edf,13345cdf,6dc00b1d,b63b7a64,fdea70bf,e4301ea,e0f9f3ff,5e7e395c,42b3e093,87b8363d,37092335,31c317d8,1b61f20d,f06fa662) +,S(da098bf4,133f656d,f2a09d95,c437eaed,fadb4c9,8102d164,b355c7c9,38e65216,74ffa0cb,1fe7f0af,8a1a6ed0,531f8e98,28be1110,90b580dc,5ff55fe7,b75d9b66) +,S(f3f7c27d,54b40dec,5b3da04,b2cd222e,1507aa70,bd236bd4,2d6e5c95,c71bbe7c,80e17f04,7cb2203c,cc58c364,d77e9a1c,8abb092c,18a9f8d5,6edcdaf6,1ae4062e) +,S(466b6e28,8981fbcc,92c4ec3a,a54eae4e,2e266041,5b242aa5,523579b5,b1fe93cd,9ae0e0c7,d056b2a6,831f540c,67a97732,33bedbd5,bdcd2904,2a8987cf,1fe2a86f) +,S(e15af336,8c59576c,a36b5f80,d9ec0458,d9534bf2,6650cc26,a2079946,ac43fcce,7fe0423,e6ea121b,308d167b,ada98cc2,fb8cd772,f95c3d84,c1907f09,66e5b46c) +,S(c20ab235,6dfe247,d8fd1a9c,d8c4f16d,a5322bff,692efe70,f256521d,1b990492,3c0aae11,e4cf9a17,57feb324,e1a2f0e,48d5978c,6007429d,ab32b2f4,d1a19bd6) +,S(d8b6c190,4a848755,f126651c,d96fe374,7c5a3744,1fb7048f,e15c4693,dbe35e17,fefb5310,e7e38891,70fca6ec,61ffd2d3,72605ed3,4bd22d73,c852a92c,c22fd30f) +,S(a8256823,5416b18,a01d2df0,f47757d0,f42c26e3,780ae6ca,2421aef3,83361f8f,c9192412,77948b80,87d1c45c,a95224ae,5f9c294d,fa74c1ec,42ad6004,f8646540) +,S(28f2a237,c4dcad5b,a6bb5274,1e743020,e90bc598,8ee66b39,cd672ed2,ccac6c33,416c59f6,c1b1b036,f38a5523,722954eb,52848872,8ecfac4b,5bfea63d,cfc181db) +,S(e65d92b7,571bbea5,4e541862,a4dc7890,bd546782,bca886e8,3c1ea17f,33d77e9f,6116ed43,13def2ae,6b0f2b92,ff07c91f,4139982c,12511152,fd7ed5fd,851bd04e) +,S(68adb9ee,c7ae0198,726b0457,91fe52b4,b5c2ec78,4199da86,bceac230,d55914b5,41ff0808,e42aae9f,e93ff704,6f08fb38,4b72d7ec,7b1dc6cc,e0071306,7ee5cfd5) +,S(3f0f7d6e,6bf73a97,40eb842a,35cd4800,85db4766,f7fc374e,1ac915c0,e4d6d6e2,392aecf6,8b446346,2d37a106,8299a09d,9ceeeaa4,f0ee3397,dc54b2f3,5e3332d6) +,S(929aa2ad,48a1f3a0,24fbf7ea,70e9d57b,9ef65afc,b3cb2d8c,5041a933,321359e4,b1cfddf3,4693ff40,ef16d8f1,8fd1fec,a71252cf,ee13ba4a,16094c20,3b4fbf66) +,S(9a9ff691,f16ad46a,d0b753a6,fb09025b,e196b443,839114a9,580eb2e7,fc494e2a,3776f83b,92c135f2,5e5e600,27f65e2d,582fa2cb,f5842c3f,644fb726,1e305c67) +,S(6752b226,65900d81,47ea6b73,25b212a2,9bcf899,799eb1e6,213857dc,6959d32e,fafdac9c,2f791be2,d1cfa78b,7530859d,c1b2ff43,e546de14,1f42baef,3d6d1371) +,S(9fc32749,e636e845,aebfede1,1d0928a1,8cc6e3b4,5a2536a9,fae0a2b,ddca6434,9021fa85,56c5fe05,cc87bdd3,6cebb00b,3d1b77e1,80ce2f8a,a4d155ee,84fc6441) +,S(60ca338f,ff905b58,b1d70d5f,89c4cebe,15600495,698b262b,e1550da,a0054a99,6d57de6b,f7c637ac,4d728090,9960ce01,4b541abe,754b82c,bfc87ad1,5fbe6ede) +,S(91537a09,697d3658,b06b853,d07153da,6d0228f0,786f334,db6151c,64becb87,231a2595,e04dadb4,b3900188,9f34b43d,5cd3c81c,f13fc6df,d432a377,4f53015) +,S(93a85356,195e109d,ddf054d1,2a901d83,b10db692,fc17e878,849eecfa,5d387fff,58f2112c,3df38b46,51e347fa,5aa8569a,48d95b2,670c76ba,d0de339a,72ee87e4) +,S(d5d1f0ac,bc2ed1f,50490030,43fd020d,7a1afb27,cdf78318,6a043bef,b0708eec,c473908d,4d754fe2,a5fdea86,62a6ad21,b711560d,77ad85d4,e3b47175,b5133e52) +,S(afe283d3,8cbb257c,5f2c0dde,2fd1bd56,2ad33e5e,605c24be,51a255ec,5725b1bf,a050f64e,978a9ee6,36885656,5cf22d7c,2fb45e64,6df60abf,6d3f9e1,132311a7) +,S(179667a1,72e0c37f,33e835d9,b5b6f326,3d963f37,1dd07d40,e790e0a1,21765180,da24290e,e38be6aa,ea2e86e6,bf683d4d,90f5fb79,20257b78,aee8be4d,fa65eea1) +,S(9add8ed2,6feeca4c,d3e583f0,88398ecc,f245d30,a888e135,b86ac1a7,e4e42d05,41bcd07c,c2e6acef,bc488d74,8a338c9a,7e6d3e43,85029f75,63dcde83,54d82232) +,S(25ba1237,6bb6e146,5195db78,29f51889,869dc972,fc9805d3,f6dfabb8,bce6b,a39dfc2d,223f924,47ae617d,537a4877,e6a47e0a,7e5fdbca,e1bfc956,a9c42571) +,S(dbd78620,c9a75ddf,55d0a41f,7312ec44,d3108f34,e7d75195,d3d49f99,88e2f986,c184bf06,ef304b72,1637bd3a,d511dc92,297dd5f5,9bd8d053,a048702a,fdbc400f) +,S(f8d67c64,b71d14af,b07d734f,675913cb,7a1bebc1,6e4a4916,44f8f4f4,6eb69448,eda6023e,5df40a5c,89a7bd26,94767a5,f17042ad,f95fb4f2,88bf9fdd,b91b280f) +,S(fd5f3228,56c096d3,4683a672,64ca5d76,58a8b7bd,41c3c1f2,5de2e6b3,164c8fd7,8372223f,3fab4f89,f6604b16,dd66db85,b8a27eaf,30741bd3,7a90d34f,f19c154a) +,S(ea49d0e1,b07948b8,b122d52f,8e8be6c6,e470262e,1c239b40,483a6076,c005136,b81ee77d,3d8489ab,42a9978,48a2ba17,273517fa,604a2abd,f2e1e726,d71b7e19) +,S(bab8ce82,c1210a99,ce17a5cf,3636baa5,52cc793f,89fd25bc,b6f078c3,92149bc8,afe2bb15,d00cf460,953a7c1c,8e466556,136ebd4e,ebf61a76,e49726f1,e3aa8e73) +,S(98802d2e,225bcdc7,9e02e746,891cdf12,ac434154,c08c2e78,589dd9f4,27277e1e,1eeb6b5c,4fc6459f,28e3fc49,6d9a6baa,fc66ede0,85d4b0d7,4af45840,78987514) +,S(5dc54290,2b33fd65,7d37a22c,c669ff21,75825cad,b34e1ee4,7aecf7f5,2dfd750a,41fb96de,60564df7,6c8ec857,d7f0ceda,2b330fda,2195a70f,5f64f973,ec0144d6) +,S(c4894f07,f6679f4e,13369495,dd501aca,73666303,2f7bab6c,fb81d7a9,1495834e,31b7e5c0,35e81c22,89de373f,85d648dd,892021e7,1d120742,e4ac6af2,44a25a8d) +,S(f7c9950c,d5c5afda,ede613bb,8f21ca15,b0e92487,81e16378,c7f2cba,5efd7beb,1746037c,b9211262,f0867180,16f0fed1,75debbb9,5eca39df,ed757c02,aa282d24) +,S(96703c67,4e7e2859,f274e7f8,d458f7a2,89ac0bc4,961ef3bb,b120a1e1,b82b5a55,1f92a15e,5e8b476a,a165823e,59da387f,2f9ab551,4703010c,c35b787d,c7d8ddf) +,S(4e8fa83b,bf9307a7,8b997e49,68227e86,a0402f0,643f98bc,5d13837b,63d08156,81f1f92,bb2a9ca8,14cd212a,6de7ebe9,7a04ed97,4de89e5f,cd8749ba,6e49e4ea) +,S(bc239122,b0cb1f43,2ed0c2ec,bb3c5391,b7eebafc,c4190fc5,8f62d313,7f58c1bd,5b3cd401,d9cf971a,6b9f70a4,b6f8fab2,d0026a24,cceaea2,a86aef0e,a76a3cfa) +,S(90b7138d,5d2e11b2,86d29b78,521aa9d7,205351f0,1451e134,8a593b78,fe5f1778,77cdd3f5,829af7d9,937ac98f,58a78b99,b54fe9d7,593415f2,18dde880,b5039a37) +,S(631d0fd3,27bca9a6,aec8eff9,54fdde7b,df43edb7,b1f602fd,a32c387,825841e7,d6e8af71,273702a3,a2a767af,3c438f0,b07ab614,2fd0f67d,74a9d358,74e29100) +,S(ac2a0153,d810371c,6a7bc097,ed09be67,14ae9935,4a9910ad,7ee77ab9,6d54cdee,39707795,a4f01640,87b5e149,2ec8fc1e,be11d8f7,c43555ac,6f4674fb,8ac5b0b0) +,S(89751ec3,c1aeb288,1953d3d3,f2f634ee,29b1aa18,c55b8b62,59d5cadc,852ac99e,8b4d51e7,e2f94c0e,ef80e16d,9b62c935,2ac91394,902537f1,e93744c9,72f22a3) +,S(849a6cfe,5e3ab81,2e21f491,4c6ec76b,5233d405,7ffd487d,bb0b5091,2ac499d2,a490b967,b5fcea21,d0135ec3,c9ed5efe,ecf7ac6c,81e06648,66cdca60,a1be7037) +,S(4ffa897e,17d760e,41859b6f,3bfc421c,55fa1e31,eb999f72,5028be41,cc8a9ed,87b4b5ab,d9875b94,aebe632c,64ea441c,71ec7353,5ae2c83b,d9b904e3,7f7fd326) +,S(4fda56c3,8bae34b6,55b2ed2b,621e5074,7ed1dc13,a1a815f3,be12a223,d54c43c6,6cfaa7b3,c53a1dfd,a03dc7eb,6086b84f,ac280c55,7c357d16,fa5938cb,c149bb10) +,S(b572c9c7,9ecd2ee3,154c56a5,9c81444c,b16df1f7,82198eb7,40a78c7a,e5c7e99,a1fb603e,42d3ac6a,5ef5dd74,ced31624,fed9086,5b02b3c9,2bbad21a,ffb1b79a) +,S(a77038c8,e79abb7e,a94b4e17,35f0f5fd,a07b1ad3,367047f4,895a5104,dfeaa623,e9bef9db,e8e2078b,346aee0e,efd64657,2210e451,ed2e8d63,b92be059,c577e1ea) +,S(3158f3e1,14de5071,c6e2bff9,32f1c269,7e374dbb,786e960b,7e59df03,26e2e1c9,1d0e950a,9124a626,4553d29,3e5cb8cd,9dd05d45,f48de2ba,f60fcee0,ca42a9cd) +,S(b0825b69,373aad7b,53c256c3,1258169f,2736d47b,1c4aa22d,a052b864,375a807c,23ec01bf,a857fa0,1f3d46f8,7857b211,f7533c9d,611dfdf7,951d190a,d7ef07db) +,S(9578e6e2,1a738f66,ca04647c,ec610da1,afc5602b,1e72e096,bd192ed,f19c205c,fb5da982,7208b4e6,11e6dc5d,dd8b8ba3,569a578f,275e6d21,3417fd37,7e4e6cae) +,S(a0aa979a,5448d27b,e42c39e2,2fcdf40e,d3b64c74,42b2c40e,2f6d38ff,fabb196d,7a9bf938,937be244,38aa212,d9342f98,ab9a35dc,1361fe56,5d04a25f,176eaff9) +,S(f535145c,d57aca97,f4cef68b,ce57d5fb,62ccd1ea,b48dfeb1,3b87b188,4614be82,1323e73b,dcd6b16f,bc481294,198d8235,b98a1885,a336f07d,593e5df3,a21ccc11) +,S(587d9e30,2f9d60ed,eeae03ca,252cd2fb,117bd07,fc91163d,a7cc569d,1b023f9f,7bcd5b42,3c01038c,9d3f7f71,ef52b4ef,a99e4be1,6de4314a,5e517e8a,950f45d5) +,S(b1e3b70,aa8a0cab,ec119ca0,5430396,ed98d9f9,e3e1a650,94cbd985,4cbd0932,3c9496c8,eec7dd92,9718f7a2,8c7a67b5,c4e55d88,5a943cc0,deefbd11,fa4f8de2) +,S(8f7001e2,928200d3,a478ba12,424be4c8,de8f16f2,a932e000,1468d9a0,48d57816,bedb10ab,72eacf26,1ab17a34,e5138686,34995952,545129b5,5bd6c7cd,84b50bc3) +,S(c95bae04,e1c397e1,498822f7,b7910019,922e43de,83119ae4,8517aa9b,aad6f35,8fff7d3c,d8bd7af6,c8523375,84f73aa,2f1b03c6,585c7987,98fe29aa,36620486) +,S(228fba21,ffe5ff9c,e04017e2,7cf04c71,1cc454d4,534d3404,49bbd1c9,60d2230d,825fb4a9,169ab67f,50963731,10f27fc3,f6f7acbc,9f2918f,c6f0bfa8,a92ed32e) +,S(89610875,bb7c5f53,87929e38,22249817,ade80ed2,a69dec5a,eee31a48,6c40e316,f7d5f522,92a53c2a,447f9b6a,5c06b3f,22fcf19e,4a200ef0,9167c255,a373ef47) +,S(9f0542f8,8e7e2b4b,c20b7b5b,87f051af,6650f605,67dca77b,7b6e1ccb,2a63f6e8,2b80c840,5e343203,d0a7d1cc,ccc99736,4bfa10d0,6e71880d,a0955cc0,b1ff98a2) +,S(859b6ce5,b7075222,549b59bd,3de967b2,1655d163,c57e94e5,6c9fae12,e5222061,25b8cf47,baba2000,19036027,fc86f03a,1c4c406c,4a8b2c34,398b7191,bf125aa6) +,S(e6febd1c,91e66c5d,afc7caaf,4150a023,b70c57fe,2a14f84b,c9fabce7,34982ddd,b606e3cc,f997b627,a0a02c4c,e147e0ef,58e3e275,a43940a3,4ac74760,457ae5e5) +,S(956912,ea1f5ce3,52d39e67,a41e4ec5,8c7106e0,4552e1a0,48e4b195,6cff8c01,b1eb2fe7,7419c11f,f7e34dfd,a752064,39fa2e6f,b9f9d34f,70740950,cee3cf40) +,S(1bca39eb,9b6a5d5,3575e510,6955143d,a6fe9d67,999500,ea78cb89,d832ddba,47afc8c9,358e5f7f,e92370d1,44ecac99,4e69afbf,6ef1af7a,32adefb7,9331173f) +,S(2c6db85b,c4d84c2e,61f0b5c6,2f330e7e,dd672c63,a14fa534,9e4d1488,ad462c5c,bb488565,cb2da5c9,be8a6f6,c71555bd,d85b4a53,20ca0753,f524f91e,ca1e331d) +,S(f66c0d73,36bc153c,5f85e297,52845255,8957a08b,603e4d3c,746e0c19,572c9f82,74e32022,faa58df3,1e4a02b6,f00ce5e7,bf34ec93,d8095144,a1af69f9,c637f01a) +,S(774959ef,cf8c126a,67012f8,10217d39,298040ad,da97e973,9fe13f9,927f6757,c33b9f7d,b2901f8f,171151c5,dd8b890b,62c0a1c1,9b7d4691,9c23ed00,cdafdc24) +,S(f59361a5,74b69786,f7ea4abe,44eef2f4,5000328d,dd72c2d5,a6dce9b8,63037ca6,34deb360,ece45bb0,a2417618,e7c67adb,24b33620,80d464af,a1ef20ae,35da05b) +,S(add233d,31c179da,bb62567d,2a5bc5d7,9afc5c50,93dc8196,9767ccf3,8790a5a0,b9ecd675,13d81a64,8ca5ab2f,4d580d3f,7f7d4def,909f2759,af61e497,b6d8f82e) +,S(3d204b0d,1d705714,7e947150,52a531bd,b6749743,5c94c7f4,8f821579,170fa257,ae20862b,cd86c6d8,e8344911,cfa8914d,f40e3a80,b762fd54,e2b7f704,4de86017) +,S(22be58e5,1c5ce0e2,f1ee6f5e,523a2f55,e110c4b7,bd3135d2,39d7a25a,94bc13f4,56894dfd,6c2cb7c8,5689cf04,3c1d4221,a7dfdfd0,d05b1e68,cc41afb6,6a472a04) +,S(6e015fb9,af8ec2d3,9f101509,f8f1fc9c,d95dcf57,82621ead,4651a062,c8487687,c7dc43db,d1d068da,9cb751fe,51251bf8,7f6edbc0,bb19925a,bc02cf6d,d7cf8554) +,S(3baa1e60,42844786,fb720758,67ec526c,2e0f7fab,ac8e0eca,24eff876,47720c2b,909d202a,b40037e,9afe2ef4,d8638491,d27a1d24,98e497a0,908a52c1,52b1f8da) +,S(689cad9b,2cde514,b9c25275,d6a3e68a,ce0b2216,4418a403,a83d88a2,4dc4d25f,53e7be29,165632b1,d1887aab,94c525f7,86166f32,56b44e70,295dd0d8,bb9f22f0) +,S(c1cc4802,101d0251,76875033,ed9fcc07,a66a57a7,71ca1374,63d7c7b,655fdb6b,ffa73601,5dc4ccf6,8afc41e8,e254501,93eb75a1,60a98c,6c800d0c,f10edc5a) +,S(888e34,86eef22e,2a25aaec,9bc9b84d,fec14fa4,c98e9d57,4fb9e08f,5b0f76a2,d2e3ec7c,db9286b4,b0223762,234d771f,a5b6f378,b6a4bbb3,c94c3303,af49b4f3) +,S(ab355f17,a43d24dc,330a9195,c2be2ed5,6894a9d,e38d3dd1,1a31f9d9,9ca88a93,7f8f8748,c07cfbd9,fce0ac7c,b624f2d0,f83bc49a,53276b00,7ca2b821,51988e6e) +,S(12a65c28,aa2020c6,5f56d916,c1cd111,10f68f0c,2408863e,635e05f0,1dbe4141,48bbab23,1be95484,7a0b61d3,89913ff4,5a8b97bc,384a0780,294d97d3,9c9b9be2) +,S(9d96107c,591d95b,42854234,1371290b,370640d4,2dca9fb,5f5397db,84a5577e,183fa1b1,cda4719e,869c8b44,e97cf214,3ab14e5d,e5d0d781,78e5d68a,923b3dc4) +,S(7ad05c26,aa642731,9eded7a,43f72faa,d344ef4,d413d884,67bea154,4459ad55,cbd8ea0,7fcbda54,813f990b,a6eb8450,6faa12d1,cd478a9b,cc278a32,511ba8f9) +,S(d1ddaa71,27959090,65ea358f,b887e4b0,894028bd,457d217,f1ef6b9d,143a2292,e040cd3,d5f19cc0,456a55a3,88ccb81f,787eae9e,51a289cd,d8ae8d25,881e6ed2) +,S(ec3bc5da,a9be90e5,1af0c1a2,bf41adfa,8023bb4f,b40e65d1,c65a0e82,6bdc30a6,d4962737,f9df1f4,48df1d9c,d8f7a140,233c2175,5d8ef5c6,f292b230,9ce263cf) +,S(f3135904,dc55f515,806dbecf,d51b8106,f13dd1d3,43f78e05,91de1f94,86fd193f,c5bd3002,24934faa,2f9ec634,53fcb3a8,20af608e,efbeb963,23871faf,a7dc2246) +,S(fb5f135f,b2f7638f,36bc332e,1bbd2050,335c141a,49db5452,619f266f,df85e8f9,6e71e045,827c3ef1,b75bffd2,ce54361,1e627cca,c94c8d3c,9b8fff62,e10b7b6) +,S(d1dc12ca,62a1285,e3c16125,f71a1b7,7b0dfa9d,c1068ba,2bb56bf3,98864620,6a6bda82,232af467,afaecb2d,f4a7ca53,3c41d63,d8f7093b,f04a2964,6e4f19e0) +,S(52354730,2d24cb39,f9117e35,d9374ea8,f3b6d027,cfcc23b7,58f0bc1d,b4f2d94,83719f2a,ccc79c43,1d8ea584,c78dd5f8,daded80a,fc3341f2,5789181b,7671d586) +,S(fd8247d,d208839f,93eebd97,f6068ae8,a6640a46,48c16b65,6bc992b8,4ccfc5e6,dd560b93,9b530bf9,a8bfd5f9,614f498a,49e54061,61107517,e9ab0104,54e42f3f) +,S(da5d83a1,9254990a,c14af844,df04bcb9,accab655,5468d08f,3b5d93b8,425f1600,9e5a8786,6be51fe3,54bc2412,6315f8de,1f0113cb,ae78b72f,cc70572c,d978fba6) +,S(1205f8ce,b9c89dce,13cd44f4,9ef0b2e8,14b78639,372d9f61,f0543f54,bdef2944,6c820a46,afd1dd98,499636d6,afc34ae8,218a8c90,2f210dbe,530a9211,a058768a) +,S(7d94e0f3,3969c5c8,164739ff,11aa05e0,45b32702,333d947f,8a0cbb80,57dd3c71,7b92b367,33f92723,17948d9c,a1875303,865fd47c,ecab145d,9ac9d4c9,864d62bb) +,S(d7f22ab5,6840dd87,d939c4ae,3bbe5a67,75e7a2c6,dc969a96,40c7f65a,9c18b2d8,bfc60718,2509244,b0ab951b,f4032852,54b73d5,a23a19a0,b4ccff25,1e5dbd6a) +,S(cee33146,2accf4fa,5f06b598,cc36aa06,342c83d7,eb4b6aff,90b9555b,fee0fe61,97583a48,5c323459,ef4b3f02,bf63f9bc,315cdf91,6163b389,c6a48cf7,4127da34) +,S(1e1d2d64,1ec550e1,1a29bc03,cf7c8442,ca13f10a,182783c0,d4ee9bf0,8c3c8a18,1ca8ff62,fadef98a,4d1faa0d,28e75e5f,117cd890,2934e457,e042b870,d8cff1bb) +,S(f10b2e75,8246bf49,1b70ff95,a385e701,dbbf333a,95a94652,6df7cb7a,4b4cb68f,ad15b5a4,d39d6458,55e57a65,3872d9d7,5f4b3168,182bdee0,a6289f68,aa7f99af) +,S(4674dd8f,16ba5557,c9ef32a0,2b6be805,e864e7af,c4fecb8f,666cf396,f7e6b0a7,c9d95120,73388bfd,45f702ac,8851b5b7,531edbe2,df04d855,7bd58b3a,c889f48a) +,S(95bb741,da472f82,8ff1f98,970c2bc9,1dcaa4ff,2cd4c0eb,195978b3,242c66f5,1e097cf6,d47dbdfa,8c3f2ce,90e0ccde,5adbd581,9a6e135,957ce258,805a4130) +,S(9a892056,42e03fae,b24d8fe0,f94e4f6f,d0c72581,604a65a0,99e3d28b,b103d2dd,c6bee4e0,d94c30de,b99c1a21,5d28d7cf,930e89a0,7865ea1c,87d39f5e,1522b33a) +,S(ade39c3b,e9540095,2176bb09,20541076,dac8e68a,a20903b1,5048e5db,4b0539a4,6bec56bd,60596cb5,7ea8a355,a6a6a4bc,90871c81,de902b0,6abd45d2,5802b204) +,S(45f808f8,bab4b4e1,a790240a,f036516f,bf0a8eaa,dd4dede1,eb88bbb0,7d248b8b,3f3bc72f,bced768d,bb90ddef,5b1baa9d,aba634f,1fe19842,c3b4b456,8957794a) +,S(ac9aa903,845a3081,2ddb195d,d79ffb6b,6e8ef0e,d34d0a5,49b577ca,35a116be,368ddbfd,1c5a2fa,c2c183af,19097414,82b272d0,52cec4b1,745fba6b,4a9fba89) +,S(ba26fbbc,ffa6b9f3,584f18ca,255da089,f561c30f,29a378e2,9f76de9e,b756f6b6,55f67b11,81ff78c4,c4c86e7c,931e314f,dffb392,306a7145,5efe875b,fbe39ba3) +,S(d4b1a902,1ebed925,9d53f2e,d76b03d,25b4241e,d5f932d3,a54c4dd5,db3f0423,6f1dda69,9e60053f,d9d2f5c2,c2ed2ae8,ba3337a9,b669ba05,3e48d974,f73c2d93) +,S(bc91d139,b2de4778,458ca891,fa97e413,d4cf32b1,753cfe0e,540726c4,648b451e,b56454c3,4f568840,6d198248,19ba350e,aa291f16,5676d7c9,fbd2d592,169c76e7) +,S(cd7a85ca,a0f408b,26b29306,3e01dee4,acaa8f9b,36f7273f,378290f,a4435450,1d9508b,1e7f5bc7,ba8fe5d4,f44e8c57,2bff9a98,887c3ef5,2fba3057,f132c5c5) +,S(497f8e85,57880856,32edbfec,b0065ac8,3267fc31,da9100ce,c2b99cba,1e7c26f6,e6729428,fabdec3,2db731bb,f33cf45e,5001b890,8f82c0fe,f7cac291,f89c6a46) +,S(68a607,4065c372,a95e7a6d,fc742e32,e59cc4b,86f9127f,f9465474,a466e30d,58e59131,1cfff974,e9e9162e,e974de92,904ffaf6,ffb97f49,d9dbb1ca,bfd927e) +,S(79d2dba1,67b93ef8,82ca60ef,b803e1a6,eadb4406,7f9dbf6b,d45c1a72,23da19b2,a59f1b7d,9ca146bf,93b89f2e,244dbf00,31511075,4dc03050,aabf0d20,41230ad0) +,S(5a2802ac,f4b92bf8,1c98c431,28ebe1f9,c921c211,910b6648,6391ca0e,4c6ad50c,5a0d7b4d,49b5835,dc3b395c,83031571,f7c361dd,840b41d0,405db351,14d86eaf) +,S(87b8a84b,1fd98b53,e9eede06,74555c7d,806d5b7f,4cfced4,16203280,18c398d5,a38c4d7d,549bd5d,28fa39e9,805e81bb,975cd137,64aa8c7c,a7055d63,bdec52f2) +,S(f7ca4d9e,7ac11395,70db6a06,c7f00833,5982181a,6642846,5d0899bd,907a9223,2c3dcce1,2ee6a995,52a72eee,e0968552,919502,5d4962c5,a33035d4,501badda) +,S(15bf39e1,5a11ff6d,216c0f7f,f1597f7e,ceeeda34,91b450f5,3b3407cc,bf7ced7d,325462a,6591d018,e495c6f3,fedb3abd,75d5a4f,15e9ab99,e43418cc,4aef1ecc) +,S(2755adc5,e69db19d,7caf52ee,117c6907,5b342e73,4af64a4c,77b369d4,269897b0,199bbefa,7e0b1c10,bd78ead,d5e65a6c,e6b3ee49,1400b9ad,a7874bcc,be580d5) +,S(96ef0e89,80602225,1d8bb9e8,693f3a67,5152cc9c,43c4e953,5310b9f2,c4338d8c,2414e799,14b2d6e2,a9be60ed,52508d6c,15765c0a,7fc1746,8820fb99,a9feed56) +,S(c1642d67,339fa6dc,c553233f,116f8086,2edbfc24,5512c2bd,4ca6e348,712bfb19,65e9a14,c7356a36,625022cf,873161b8,ef43ce38,a99586cb,9b5c8189,f3c6b8dc) +,S(54c536b3,cb6da9b7,e4483ce5,d5c9e660,bf973ef2,f4c8b095,f52dfbed,ffdfb96e,777f16c3,b026b75a,c9863f38,d015f04d,e1067f2a,a9cbd15f,9ee27475,ad46a4b7) +,S(706041aa,63dee9bd,4a441238,bd343bef,14e69929,f6e007e,181ae87a,68362926,36e15a44,57b86f4d,9b233dd3,37fab91f,67e4c811,3340463f,8f443b50,5a0ba014) +,S(49acc336,116c91af,6f90a6a2,d69b9d3d,c0be0a16,afb9830c,c1af0b5e,749b2765,bc4f0f6c,725e037e,3a9d9be6,c5d4f80d,67b3e28b,92e5d3a8,fbc8f66d,9ba97d52) +,S(96bee384,ff79ed86,a9d816cf,32f3d569,d1ae03d2,d154c65e,a117707d,74c818b1,848e45ec,27eaad75,5328d84c,a76a7235,ef4f492f,5be115a,a622171b,51dbac8e) +,S(3b2b0810,c4052498,189affe0,4c7ebce7,b9050aa4,6a702d0f,72c5c770,4ca4d1ec,f782ad72,1bec3b8d,b1df97d4,7765434f,e4145c81,27acece3,9dbba604,4df2543f) +,S(54c3547d,e4873721,df6215fb,ef7bcb4b,b9acce42,7b0381cf,2de151f7,c69549f0,5e7ce1b,728a3b21,e94b4138,bcb89af,f4778dba,fd21aa42,16d83a7c,9ae81edf) +,S(9f1c53de,e7b895d5,6081585a,c6eb3821,d89bfa61,55cc96d2,e8b6c472,edf57f27,38369e41,ecbdb4ac,619aa7da,4d708eaf,4c572ed7,f1f2c079,d0bd17d5,3ba8288f) +,S(e79f75e,a1a224c2,a0533936,65a5f705,15eb0aed,b924dfbb,5aa30055,d1d82b44,30c65139,f6a6f5ee,5304334b,1ce9dd15,27ba6031,2ff2697b,8eebbdab,67105171) +,S(7f95a1da,79cf25cd,a904b7f3,11674d02,fc6dbf34,ae8ba7e0,b179b48a,d942821a,3d3dd8bb,31cbafd3,247ddceb,be1faeb3,b00e057f,7e90bd1a,78f89cdf,648f7c8e) +,S(41e83f7b,9067a7c3,bb6ec755,ab7c83a4,dff74c93,65d0259c,cb635bea,718a416a,a54a4b56,5286b26b,d0bec338,2053c349,2de80062,2189e2ef,ed10e3c3,9457a34e) +,S(81599046,453d0a96,2c5f3b47,fee7f827,537c7c58,c5ad068e,e5e6ae6f,7a9c6848,4a83b015,3abd0df4,177ef3f7,e8a7ac7a,e8e5afb9,a2fd359a,c30c13ee,321f943e) +,S(11c9aa76,2cc334f0,a3274f15,17a1e60f,2f0eedfa,d603f83a,120162bb,e87830d0,7c73d374,26f648fe,4a9978c6,a64ac787,f4c8d79f,b58b0f58,70e373e4,d317136a) +,S(2b41f344,b285a31a,ebf4f4fd,f0c4f463,49fcc794,e5762e04,dc39efc7,936735c9,7eb708ba,3f683d48,db8e0c25,ac8a6f8e,5c340749,c3d6ed5,7936d515,7f3d6e73) +,S(dc063e66,38098e8c,6ff55a73,faa20099,c10d0258,87c19850,43d1011b,ab211b93,4abdfdf1,285ca3ad,65bb9a85,7ad647f7,fff01782,79fc6df1,6179e1d,495d212e) +,S(7cb514e8,b6361aee,f9a7abe1,f84ef401,97de721b,609c3151,a056eb03,71ccdf8a,4d359c89,7d03a633,369bddcd,52a67387,fd4d1e00,2406502d,9ba6e967,a5efd0be) +,S(103a6644,ee731721,bf29f036,97641fde,9775a642,9ce8d97a,26b06ceb,f9066693,127b6948,6db0d230,6ae90a1,4b8c8ecc,1e9293eb,cf154371,5ecbd579,e886a726) +,S(adfaf771,662d719e,532ba045,72a50f12,144fafd0,afe93f7e,1d8edd13,99226e5b,b4d0335e,8b600a4f,84d919ba,514bc249,e3048cc4,281db3b9,a7c62013,4f00bbca) +,S(609d9352,30f3c6ed,bf64275a,23a9a258,33fb8c3,9c25dde,4b55ce22,e64b50fc,cbbae84,c57f9c52,67278c4d,3b0cc5de,9327ba71,ca1a1bb1,8aec9a97,bce17552) +,S(5ea5aa20,1b958a8c,49b70510,b7c6a29f,86d9ded9,afd4e833,77c433d0,f62d9ba3,27c5cee9,fe3c0bc2,af8d0e30,57eb0f57,b1fa4237,996bf8ef,5ccd25ef,e1b87ecc) +,S(3f801115,3603a689,800c04d2,7d3b3fe5,c415ea29,c6e11951,7a56712f,20a10862,4280ab61,65b122e1,85abf4d4,14a31961,ac6595cb,421db183,34e57cb3,fe9bd059) +,S(54981ffb,5b692a3d,6d9ec7ce,f027fff3,c5dafb7,aaab4c5,572522b9,e1157e5,893183bb,554c81de,21c84134,e395b9fe,80a5a9ee,b06e3b67,2ef93127,24c307ae) +,S(97c18e92,d499ef62,77585c6b,28f36fec,e9a2e118,f793260e,32750861,a1aeb813,38a87702,7f1df077,d6e734fe,18a023ff,36c6d4bf,4a7bc7ce,d3a3d38f,c3069f33) +,S(d5507aae,97bb6e17,410bc87,26d9eb2d,11558b96,6c54e7db,6428b44a,3589820c,e78d0140,7468dda6,d9c4af92,1984460c,e523c101,79f7aa15,d8004dbc,4fc63cb9) +,S(220d6c2e,6c500d01,9ded2aa6,5de205f7,cdbb15e5,69038ba5,7bb1700f,1182ca70,64b68506,c387ec2d,9e030448,797bc28c,5e09e8a9,95f5f80e,70c26a1f,db7b16b3) +,S(c1a45038,da6aaf1e,396595c,3ab404eb,9584ec90,d894985c,18e779de,793d20ba,1a443da1,72e281aa,4393e1de,6f1e4f89,4fe5d1ec,b3a5bcd9,607cf79e,6f20b533) +,S(9a66f9b7,f3162c80,d22d0b5d,2a659bc6,ac01c74f,46804ca6,c908b6cb,90fb419e,3465357b,209c2b,a7c766b6,9c17abdc,69205c54,787fd0ef,e744692,16b95d3) +,S(8b305bcb,1b6156e3,22f0f0df,28265cc8,79e5909b,b76b546e,eb223d62,89883387,929a341d,dfa05574,90cf5293,244d924e,852b00d0,d328ffe4,7ccc5356,623a31a) +,S(4e36ee67,b5398169,8ed9460a,cb450023,7198f249,4dded391,4c2ae003,63c8f664,a784c95a,9a443b7,5859a1b1,373eb750,150e1ac9,d5120ca6,f273578b,73df77a6) +,S(167275aa,38d02988,c53e0a36,d8312e32,369bc677,6d7143df,cc6fb83f,66747caf,f26b9851,31abcf45,369a6415,84b2956a,7122a51f,b909bc30,5427eff3,916e6e14) +,S(c93d0b74,c99358d6,d24a962a,15adafcc,8a4e57ca,df0afeb4,9d46ef53,cf619797,f93b324a,b144c6df,336e34e1,beef5c13,b931668e,54ab34a5,eee1a8f5,5acc683) +,S(8bcaa2d4,671bb4b6,8a924109,32128551,fbf6d924,d4854027,7c1dff57,3bc4a8f2,88be3e1,6482477e,62255fb3,24512abe,27cbb4df,f63c6d8c,93c3c923,47e519d2) +,S(69d186de,f9a7ea8,be833f2,590db08c,fc0acfbc,64a648b6,8ca412d6,88c03808,d776b644,43a81bf7,527f658e,45d92324,a08ce171,6db6c259,898fab8c,f3d6d41d) +,S(4a53595e,e2cfbc6,7bdc9f07,308f57c,7ff5afc8,a35e27ec,e22cdbdf,6efde161,e55913de,d481077a,ea36c502,494b3b72,b1691786,335b0278,3e40fa1c,1a1b0876) +,S(90856f9a,5f7bbc14,557dd419,516ce5c9,aa451bce,13c17ce5,5c9fb1b5,f2924995,ca083d2e,b5a3a067,4a2534fe,e03bd99d,976b96bd,2b7f16ea,6e2552ee,648e934) +,S(2eed315e,d863298c,aa374ca6,2bf8313a,a0ca07e1,9a94bc4d,58eb235b,52d36dfc,afa36c8f,90d7adeb,ec33ec69,40c08d1f,2a4044a7,477da88a,6653d90b,880856a7) +,S(345a7f2,ab7ef064,eccdbe6a,ebd11dc5,3c7ede0,b62ab3de,f8e409e6,258e84c4,c0c0dce5,93cf9647,c0228d8,42b78407,c3b634ac,799fae19,f0e685d2,6ccfd73f) +,S(5a669d7c,209b222b,47843a5a,633e0b53,48442258,663a58cf,f6ee3cc4,1b893d3d,7067be1d,8636698,2b808b16,3c05e57f,2be77d1a,2bf78038,e242f5c7,4ce10523) +,S(3f0b0f3c,30a991bf,927f5119,6fb4af39,e1399d01,1766b1ff,1f0ff2d8,a3199062,be8f8781,4c06a75,97d062c2,196a49ef,93a73923,f43d16ac,82c015e5,4789d472) +,S(9d7f2c64,98e78982,8492b8c9,2e0e49c7,b5c9d4b2,e86c409d,828447fe,4a2f5a13,95ccc540,8202dbc,78323d6c,7ef66d51,4af34699,5be50b56,98a5864d,34e502cb) +,S(9f741436,55b3cfb5,39917a7c,79fec4ba,164503a8,3958aee1,f6e8f34b,3d861b78,345738c,ff8f3c64,f5cda5a7,a1aee7ef,f3a33141,a5139c3f,b891c6aa,feaaa7ad) +,S(cf1d3136,11d4b6ec,5f1a9728,c9a7b037,d9c16d65,bad95fdb,17376200,b1a9a97a,51c72169,bf7b1ad8,6159fead,dcf3b0a7,a7fc13cf,7bf12d98,409dc3b4,fcb7a9a2) +,S(7e04c6ef,c7433f3f,fa2bb827,3fdcb3a,e0470abb,cc7c8dc5,414ff77a,915868a0,781125c,2184eeb8,87019f7,c5c0b4a5,5922d11c,53c3db9e,d5795bc6,e7539cc4) +,S(fa6d73b2,a97801b6,16697ac6,102b002a,53d29d33,289708f,d8f73964,77f3d57d,543db558,25c67a4,cd010413,9f8a093,7ea7ac2a,380799f1,c2249569,3cf557dd) +,S(d0fd7208,8deac18b,1bd63fbd,6d5be0ef,5dcd34c5,538a9b64,ef43daea,ef321d1a,7a5e1e2a,1b290241,7879f223,8cc8928a,65988130,81366846,69841b93,3ddc3a1f) +,S(e856e67,e28330ed,77d8687f,bfdce5d9,ab8ec155,4c94ae0f,491d1e43,9361cb99,c51585a1,9da7c26a,4fc07c6a,f17999e7,a6718542,d7500fc9,1bd21fc3,8acf1eea) +,S(389cff20,9f240748,b9beba0,34d36e0,5e758a3c,95c678e,28cb0226,37db1bcc,ae5a0d3,db1e17fe,30daa2af,1e1f759e,905811c8,95706b7c,e5741051,2b7ac4c) +,S(28ce0f42,ff79cdb8,16b666c9,c3014051,d46e8df2,e2377c3b,619b78d5,17f21a1a,4e835188,f742237c,fe581edd,937b7294,e06fb295,d401b35f,5b7b293c,6d57f875) +,S(3d955bfe,5b27beb9,68400d11,3b8666e2,63af6ef0,ac6ee49e,8628e2ac,4d1e69c4,1fbd2aa9,b6913655,e00f1384,a15a7215,d3d7340e,4891893a,a67faf39,88801e9e) +,S(53dcaec1,2dd48ad9,ee65c9bb,ef21a023,58cac930,316263d4,9d607074,8aceb771,5b976f2,411d7624,d4659e5f,db624b05,9dd5e06e,f0b65740,ba394020,b9d279dd) +,S(ab822568,f7e9da8d,3f1220e3,24752c80,b02a8124,f8d9f65b,3b4532ec,3740881f,6c2152dd,34451ab5,b47b7c08,f7edada8,f9f230c3,5fdc2de3,35cd93d9,e25703c8) +,S(36719c40,1518b976,684bbdd9,2a923485,ce92b321,dc26534f,e5a0473e,4c873c30,d5d58a83,d493cccd,d16a1282,68aa93e4,94ce8638,41ec947,930c72e0,887564fd) +,S(360c82e6,18a53dc2,e44677b,a0bb8c2e,2a08f6d7,afbe8498,15d605c3,2e5fa969,ade18222,e1d0fbe0,a31c55b8,d2cb947f,1fcdea11,1e08ea3a,4f3dff02,e3e38b70) +,S(ecf50737,25a3b81e,dc621bb8,6c98fd59,f805d6b8,2f08380c,64270df1,95f020f,f5431b8a,cba5d27,1da26cb4,fc3412fb,14ccf088,6e0e08ff,ce0db47c,6b4172aa) +,S(3b751389,e6dadda0,85298860,76076249,46df960c,e030caf6,91f91d46,4d05be4c,244b0028,48829fc3,824dbe61,168fa1c0,3e4d3835,d3da3a53,7c729f0a,191e92cf) +,S(ee6e33ee,7fd9d7e7,aab10b8d,2c58f2a7,26ed307b,6fa69b3b,f1f08a74,f1b04ffc,4233398d,6ee49505,c5f21525,6cc9112f,5dfdd7e3,4bfb9a8a,476b3cd8,2645b8f) +,S(e7141075,e20f0903,f39fa384,f91a5708,7f24deb3,68571939,572caf0d,2fb543f9,5265e24a,bd84336c,26b4607,dfa25c44,49c4693f,adddca01,599d814c,21787cee) +,S(d401b043,ee9944dd,7429a8c9,4291dc55,7e5827d5,88375dbf,1513d394,a778826a,9ac9b417,5ac3666d,7c6327be,5172b8b8,1dbdc96,eaf8578b,76f01128,4434b937) +,S(d48c45cb,b90394d8,23574c16,60898091,75d503b5,99d936f1,f60246d1,79c9cac5,4e6b2bad,a67ebb7,a0743cf8,52298052,2737f0fc,6cbef646,fb270d44,2a285612) +,S(19f6446,fabe1899,ec4476ee,1d61f6af,961da42,ada1f77d,2ab41cc4,28791c64,7a0aa5b1,4f2ae030,d9711963,bbe160ca,424f6a7f,17b6a709,b5f0dce5,af1d0498) +,S(2db1d56e,f19a848f,6d6747c6,82cffa47,78444b3a,d57ea076,b0560b1c,4e57c83e,701a5894,d1d6b6cc,b421b168,fd34aeaa,e85262ab,44f70c65,b8ff61ac,ee541cf6) +,S(443597f7,9da3df8b,5fddf8da,3bc3a060,83f2cb6f,affbb1ab,8a12db92,59661adf,31b2c4ea,362a0cbe,2b9b1488,719b7ac4,3a85f7c9,63e9f2bb,b46ee055,71e2ac2) +,S(e49ad52a,7bd2db07,d972def2,d1ce6684,69aaf6b3,3c7e3427,52d79fa0,9d2ee9ad,b2063f37,1ca78c2c,429cd401,c5e46d6b,dcbf373f,5cb77163,5760b8ed,b4f91ba4) +,S(35b3fc0a,4a625cb5,808e1c2e,73c962e1,6ab7dfb3,28109ef,fdf81e15,841afd0a,cb558481,145a5f75,b639133e,8ce42c98,d36d8fa8,5348c815,d92a2c8e,cc993bf1) +,S(1cc238ef,3f64a075,c3c264b,ed42a0ac,aa6de195,7db40d52,86c482cf,f62f609a,d3382317,2b8a1450,bd918aa3,c57de76d,3012887c,98452f7b,c1f58610,f528af49) +,S(f5a2794f,48885192,dec727c7,79fb0b6f,c2cdf399,4ef7cacb,94e35791,4d138e84,d3ed4f1b,912f5dce,5a0842ff,d2e671b7,f3ae8448,b1a73f43,249a1acf,915b9c34) +,S(21b41016,a8eb7c6f,5519d94b,adb0fa7a,5c553822,6d080e3d,6d2956e8,8a9579e9,802570ed,b9b01b1b,ed79b6f1,76ebc4b3,55dfdd16,f43e82e8,7803be0,fc44e274) +,S(9b5611b7,938ac10a,9818bda7,3615a47c,1ee0f072,75aa3dcc,b8919dcb,e7beaa88,89787c01,d088e3b3,603047e5,2f49981f,7f007c8c,a88502c1,3bd9c327,e3c83b1f) +,S(28163c9a,b08a7ad9,38c7b35d,b19e700b,3865800a,55a3103d,2213c9ef,2c03858e,661e089b,df356bd4,afcd0604,fa5ade9e,74c5663e,77ab57f4,a069bcf9,b8b227bb) +,S(bae9ac08,aecc06f0,ffb8540e,2589a32f,11d34a7f,6d899e5,7a8f5ec5,bcf1601d,f5b63d9f,8a5d23b0,80d0bb6c,b8df736,aa660a3b,6f987683,cc0a54e5,f7d1b4d4) +,S(19f48542,3ed01783,cb83d2d,2efd7264,a10c6c23,1f5a242b,112eccb6,31d91f7c,79ce383f,f011ce13,87537ebc,3e70dcfe,2cc2764a,3d180fdc,74a21062,a5b75f50) +,S(cf459ca,cc8c4ff2,c827efae,6593a52,838658ec,bf1a78f4,75965856,a8ad007e,786781e3,3279964e,da5e6374,bf088fa7,5d18901,df01a0d3,6c87b62e,b419dca0) +,S(c19f2008,e6945d10,471a13e4,8b16f3a6,381de3e2,b24f2d92,77ded25e,930d1f47,7179aaf5,322b51d8,7758219f,cc30e9d6,bad5ab77,b35dced9,6a513b4b,fa7fe147) +,S(3fc1b649,3b6cbecb,1767d0e5,6202c84f,39a6b41,87f05ac0,d659c45f,5bc565c,db9edee1,1768e29b,4eefddae,c6234622,55d06e0f,1979c8c3,5c366f4b,5cac3f5b) +,S(502f74d2,cf589c65,e63b2a8d,b2b1e4ba,5f851715,bbb27e8f,165fd34f,29cff7c5,755e6c73,765bc45a,c2f9d4da,499198a7,36743571,40846ce3,6afd8063,981a96b1) +,S(b9eb62bd,7cc6d1d8,b0eca2b6,1920be5,9227534e,7fb581c6,4dcec4f8,f1ec44ca,ac567b37,891e3eb5,c40fecf2,d4c5b106,bd222c8b,64ab491,f7a028a6,a02178e8) +,S(2e5280c7,25a109f4,c5de565b,9fe5357c,718f9fea,db53aa9c,b07a0f3b,f5030ad4,4783be94,1b162e,79f58d4c,448756bb,8ea18c4b,692e236b,4b2b3ffa,24a456b4) +,S(bd59ac74,92d24606,9b233efc,1b68c371,bbc9713a,284f7f0c,699a1d5e,ccca64ab,1abc71f2,fce8372a,a4a16abf,1d75bd87,a19c08ed,c8843f44,fb71bb7c,a74ec4e3) +,S(6acd12ba,4623582d,d769c8bd,3d6adabc,2c13ba3f,bb67e4ed,ee0fe70f,3f832f5b,982fce11,ff1e6c05,2f21be20,ce1710d8,5cc043dd,eca9bc43,5d100d9f,f68150b0) +,S(601f4285,8b0cbce9,90500c64,e7eb77e1,c433dca5,55e6ddff,5264a98,d688decc,56110eb5,d5b3ed79,5906ed4,c0275827,79cff7fc,ddecbe7c,74d2bf10,ab2beac1) +,S(4d393daf,c47391d8,8208263d,b8132156,e9fdd6b7,da48eae,90489d12,832dc938,a14180a7,898a5a00,6ae5b8c8,d034c233,93ed2ef4,faf6a4fc,42c4df1d,62d0ea7a) +,S(4ea24f6c,3c164285,166bf2b,1918b3ee,3cac8631,5a1175d5,4104506f,68b7171c,87da621a,a18d1a18,b1dc222f,af37b5a0,b149714a,e755ef03,ee3af91d,f2a7f5ea) +,S(eb1f6f2c,a5749f80,b88a7359,f0b67230,b2b844a2,4fb72dba,f5604e73,cf6e432a,6f58093a,55e3cb37,8830e58b,10612b24,56a35fa4,b8e60409,1b9b8304,e35cca51) +,S(2361315a,3d41b82,98a9d768,be7f453c,eeb977af,bf1db132,c831bc00,aaccc9ab,90df3be,336d4b58,7965778d,9300cc1b,3d954d4a,89abf173,a9bfd99c,29492dbd) +,S(44f432f0,46c7defb,630d5535,aca1bd47,10505012,6b2454b3,4591b079,7f8e9b28,1fdfbcb7,25eee981,c19f98b4,6bd19dff,9b6cbdab,730ca2e3,1643d415,e3aa0489) +,S(d563a475,4c130e71,81b60a66,a3f2ee52,7040f9f0,eac9e26,866fb226,f93db593,49fab7c9,6e320961,6f4610dd,532d547b,b24f7f07,f916f10e,630ae5cd,b40d3b11) +,S(2fac4651,f0ac9876,4a74c066,16e7f1b8,aa6d2bb2,99ef9f0f,43bca81e,7a4089b,fff2b7b8,c330e1f9,86a69324,a63bf10f,fad8e78f,dfbb6062,c96a67b9,eb460d5f) +,S(b6f60ef3,d8b793d6,5794aa89,12e8e1a0,9ef7604a,5c9eaede,b803fb31,e8195dde,b9b17946,4057de11,9d0bf993,fe92e4a8,bb633d6c,d03ce8b5,10200166,467e6bbb) +,S(d08c6813,65789ba2,4e580637,2eaa1ad1,d1254462,3cb64d83,5ea2e1d8,6e34620a,e94875ca,f5beb1cc,f88fa3c5,e2776203,a6f3cb5e,b4803618,52215d0a,9076b185) +,S(dfda222c,a4ddbb56,661f56d,b9b74be9,a5a7c34c,4761483d,928aa48,9bfabf52,bfac4ed0,ab4ccfa7,caf64d8e,ffdf1aab,6aad50db,595b1b49,7fab28d7,656b6475) +,S(3f72e4cc,ef5c0bbf,995bf8b4,67759969,d93ee40,8e738a4d,41f55896,17f241ed,c42ad857,3f49218,c7daca7c,8ebc5c7d,f9ac301a,2aea209c,ab6648f9,8ea16f5c) +,S(6e85f587,91431b6e,dd848aa4,70101103,f63881d3,2fa9f1c1,e3324161,e9ebf0ee,f7f00d38,31e09d69,f0684107,59dcf837,eed3d833,90efa352,40a9ac5b,2daa2a57) +,S(d991fc76,2f75235a,5268a32d,64dbeac1,b2333a34,5ad552a4,cedfab54,9b191f14,90d58a07,794983c8,3f6edcfb,55ed0b68,8f43d9f5,eb7678d,29610299,63c748b) +,S(24cd7922,7ef207bb,6b9b678,5156bf76,77101e6d,f5fb5576,a9d33175,8d7c00,44608974,5f1157bf,9c9f45a1,b212a978,8e348a0f,55129935,b038940f,84e91468) +,S(5c053ed8,367806a2,8545692a,47314850,66910d02,3373b89d,e85bc7a1,c25bf6bd,9a3e45f8,dde03e64,6d6c546c,cf4c8fc5,a253054a,2d6df43b,d8c4afb6,385311f2) +,S(4f3a4d88,20948d82,b598f118,1d350719,ffaa5ce9,9a7f614f,a9e3cbf2,e021a6cc,149c6722,980a41ce,5d4c0b94,9cbe3c99,4d94f2d7,c36ef45c,d7b9084a,79f451a2) +,S(badbce64,8d55b579,cf8d6dc6,74580211,a6bff856,10804077,adad7c2d,238aa542,567d75d7,1570d7e5,184f4f4c,a53fb92d,654b67d1,f6bff96d,fddcc3fb,932f0343) +,S(d2eda540,5f828eb2,cd3bc5c1,9f9a838f,8a1186eb,3cbe9575,5cf6642d,13601942,ecb3dc3,655ea992,4773cb57,f4f4c8d,6380c665,69f08184,f521dada,c108629c) +,S(191ad0df,31c7f3b8,258e5bfc,ec9d1ff1,2143b240,24d93a17,893da095,97304f1e,4ad4991,6bd2296f,b6f6b697,dbf5a3cc,4c3ba136,6f6dfade,c859b190,48fb523f) +,S(f108bdc4,a1874aff,35bd1fac,b8e81b5a,7a7ed597,e78dfb7a,c716bf7e,7a15dcac,b88e4fa0,d630d92d,bbdeda05,4a6c6624,e7bb1d5b,a6dded85,347e5275,e08c9414) +,S(30fb7605,7e2a6cdd,59fa279b,3574cf1f,db9d5159,19d0e523,990be02b,da1ebffc,5743e72a,752b558,1b959a48,3b6229c2,33fa1b3b,2719ad3c,a6f8f9ba,1702ae8d) +,S(6facb1e2,6d1ef1cf,ff413145,63f3b2e4,e762ee7,3e43378,c4c15f85,1cd948bb,92000e2e,a3a5bdbf,f6eaeae8,8619f2a,48b649c9,19972b7b,83cbac22,62d484d7) +,S(741c1253,8cd4da52,c596840f,e6233558,fb480a0d,43232756,2a9e2d59,a574b981,79040b6d,580efd7d,84356117,a93941f6,b47e6c0,a53627e1,bb80fcbc,e6881234) +,S(2b86fe60,2b2e87f,59498185,4af1f986,7debc5a,84ae8bf,94d2d6ab,4ec8be09,cf4c27b6,b33b5020,2ff7fdd3,ff0743e8,f28ca75d,3cb74d21,ecf21dab,ad7ae079) +,S(e6e7b676,9f0ed86,4163e9d3,66a7e2a7,a37f1ee8,e827b105,3119b8b,d36e7b84,c2e5b9b1,d82b4504,454062de,6c24430f,53e03bd1,819eb1e3,2f24606,73d09be2) +,S(86600d22,e7bec946,5b0afe05,5e733b03,f8f81548,ea44e008,740ac807,ddaabbe1,abb367d0,5e6d2fd0,a2c1d0af,5ded2926,1439c985,ef287860,80614bf9,8e8e33fd) +,S(67171261,5cbe2da0,b252a773,58f81c91,fbe561f4,87df09e6,cedc8a55,cb3414b2,bf02d81d,10a47287,2b7e65e4,93d97cfa,e3bd6ba4,39977371,8cde674,8829b0a3) +,S(97db468e,7f3a25c4,c34e202c,e9b2480a,4344aa9e,1b76a147,4bd375ed,6d10c0da,c58ceb67,a28f99de,2eca70ef,e8af24fb,c381f962,d5db6e3c,481cca6c,469c4c27) +,S(f3ac0267,ef19ae9d,762c4023,4ba97e33,a88b015a,e6a83f4b,cf730d84,405aed26,cfb8a3ef,d1104873,8c1c927,b31ebd05,105bcce1,d57c7fad,1972a5fd,cbe84f06) +,S(fa44128c,3c258fd,5a99c85e,775fca63,4e8a46d8,4fbff953,b373bd50,6ca3da85,f3196e74,d17cae3e,3c9958cd,ca591374,ddffcba,7e362139,17e5e119,a5538b1b) +,S(95244462,1eda0b2d,acdc1a57,41725c1f,a7c5660c,feafe18d,ff8789ba,164e7dbd,214bb6b1,7af1584b,76a9e5a6,2c32eefb,497324d5,7b00f71d,24b162e7,1383bff9) +,S(11de80de,c03a732d,6769e52c,64be4d2f,fb1d696b,2a658721,94aa384,392dff9,e1eb8932,42386216,f543eea,a2d1099e,531d8e27,7cb2e5fd,ec76b3af,e9e9c7b7) +,S(7318b452,a2b9d23a,eeb30bb1,3883dff5,b373be94,94451c72,36a2c02d,a4c37e75,26713361,aaedfdbc,2966fd1a,ecfa705,772012b2,564b077c,7f5db7b2,c810861c) +,S(82d189ad,e5610825,1b03cae0,4b138ff7,dd2d77b5,422535c5,cef9be7c,1899cf75,3634267b,1b3c3de0,d2dba36b,924949b6,7e05d790,29c9452c,18c6ff70,252d570) +,S(e5dfe995,82152513,80859865,f16fd0fd,e4d60c7,be0e2aa2,d9b2af4f,3714f8f7,e1d87d8f,fdef889,52918e62,5bcc90e6,83f337a6,103cd000,1cfd01d1,eef4b9bf) +,S(54cdeddc,9fda5fe4,63240f72,8ca66c34,ec05394,899f2472,d82d2378,28a06a3f,27bab620,cc373ed,10a71c18,345ff27f,e20e1bef,98052afc,bb45fdc1,80b94a2c) +,S(7f96757b,8b473785,e1359cd5,bffbce2d,5b26e8fb,579d7833,607d58,a791c47a,d4b43e2e,20a43fa3,5a96d1ff,93109aa0,b7831fdc,2d2c016e,181beac9,c1cfcc4c) +,S(eaed18ba,83238fa5,ce4e6c82,edaef108,b1f9929,3148f3e6,2d3a6d4b,535455be,1017291b,805f7b1f,eba367f5,9a1a10b5,f7501355,7e6eb921,20838c50,aab0d29b) +,S(91ca8ba1,da9c2625,66a135ad,81f57b10,65ea4632,5bec5d42,ca1ad62b,826f04fe,2d5d619e,84fac3c1,e30343ba,a61d3bfd,e1c4a9a9,8d968e92,d560956e,138e34ee) +,S(8a31ad57,12e32254,7d0d2907,cb73adfb,a9a1ed5f,fe98d645,22082e6f,1cdb1364,8ecc3fea,886737f4,f94a2984,e6edba9,8128b2d3,bc79a209,2b2c1a7b,b00bff9e) +,S(123acd6b,ca673170,400bfc4,1071cca5,4e03daf3,e1ed1458,88470c04,568b972e,e97dc60e,cfec2d5,c6a6e173,9d60f7e9,838ad723,ad0fc7e1,52b5e70d,b48b853b) +,S(d7c26043,ad647f0f,d056c10b,4ac932c6,6a545bbd,509de346,d4391942,52e69df7,6bbf2f04,2c9459cb,c72e6aa3,1b6d8e4d,e606eeb7,d5d4e0f5,7f729a79,ab1f5e9e) +,S(67c4eb00,548e2cdf,50626c8b,1aec1173,8370da41,9280c9b0,1c8783ee,91e018d0,ffff201d,91a4538a,97ceb50b,c9aac646,bedda1d1,3f22a121,c709bfc6,23b95a67) +,S(7e1264ea,486b08c5,19c7d8e6,5c80e1d4,d2994bb0,95185c72,63172b1f,ead93428,1797609c,816f10a2,e82afe39,65112a35,798b0874,b24503a8,f57c983b,6ce7ef6) +,S(912cb164,5f7d7bfe,5ea443af,1c458500,a95ff22b,212109e3,12fa01c2,41319cf8,bab658b0,111c48f8,a2f620a5,fd130d53,e1c70e7,62e33dec,55b22d87,38c1eb99) +,S(1d60694f,15577a40,f6b9f299,be5eb62d,251f62ad,b9b5651b,df804e27,df919fb7,3799eb92,e18335b0,bdbc29b1,f8ce07ff,3f7cd409,5840d5,dd324bca,2f902a14) +,S(8166b50b,811bf53,4a94af10,7672ab4a,4e154b2f,c5cebee8,c8ef6ebc,18cc3906,6dea31f3,343e5b45,f5b08c19,903491f9,349f4ca,29818fa9,16f5e02d,85e09ef) +,S(4852393,e42d0821,6664d5d,f85eee60,9660eaf9,54ccc6d,fb1c31f9,da17923,e4cadcab,17f64d8a,f5dd74da,eaeab7f7,13be1de9,600d4db1,a781a058,5ed2006d) +,S(f40031b5,ba171b26,e02be47a,c34173aa,18ec3850,1b1d529e,a922a418,1c3491c9,c2db89ec,2e50105c,4074b729,a53ef0a7,9371d2a3,354d2d23,8fb39bf4,bcb5028c) +,S(8926d233,3c842f9a,213547a2,fc5ef5de,b0bbd603,e69d347c,41e7d49e,aad76cb2,8459bc10,b7b2617,b0d434f4,b62a4452,80bb951e,b4ada14c,fa800389,b3ff892a) +,S(7f362b16,9d9bd514,c6289cdc,70ea4b77,e7518db6,a2e33acb,8acefcd3,d8c5726d,dd1e69e2,71d77dc,2629cded,72869345,7c63ea2c,8636c712,e45e6af0,4c15fe35) +,S(261b8037,98ca780b,50dfd56b,81093f32,d7c348e,4f093b91,70470ccc,4516ee1c,5723ca6a,5959d589,4a24c12b,5f87a5af,84c7a6a6,89304000,344bf5d4,81c7752a) +,S(d137c0e8,edb32642,12f6b958,8b527a9e,9e57f3fc,c358a2b,68f11d61,89fbd900,d1043b3,5f809513,ae370588,4adf90c1,9d164c3a,8166027,92ca55df,74c71466) +,S(96274665,253f4479,753de9ff,ac94af8c,943b8231,b1302040,bee72240,2ccc445e,8ef6f9fc,f1e21c2b,d913f877,98c6ac9,f53445f3,6c2b1678,a301a4f5,17867296) +,S(bc6ea584,b1f9b006,5f39226b,e31a866f,7f90229e,12aade70,136dc747,b37f70c3,23f1c4eb,99dfbcbf,66539762,4d20c4dd,4414bf15,172cde8a,b7652ad6,f87ad5e0) +,S(3e968741,5adc1afa,696e3222,fe351939,1d3f19b6,feb1de83,f4f1aec4,d25e2387,e3f4de27,67ea84c7,8baf1382,4b7917dd,477bdc87,cf1cf38f,8f5da1,e096b528) +,S(b5973535,c9c9d4bc,2b2a9b38,57cdfdf6,4995d64b,81c9e68b,abe4d4eb,4eee489,907cff05,5eded925,770280de,9ee0e025,1629796e,8ca05a47,48ddaf98,72bfdc3e) +,S(d616bde5,acd5f345,d23e8b2c,3d95038a,a1d7a354,a7613cac,57ec3e8,d07e11e,6c88c62d,d795d065,c6c86478,cacc56d3,2282b4f8,f3059aaa,55388555,449879df) +,S(540345c6,5869d3cb,cf4099c3,ba7422e0,feb87ab6,ad67429c,2dc99840,e6bc82b5,9f424998,bceafc7a,a58e5f16,c58e53d0,c0d51f64,285b0afe,e84ec9f6,b22f8f37) +,S(6b7893d0,ace6ab5f,c93f2e80,65a3de57,4d552e5d,4a89d660,714113c5,a256fb84,81a016a3,7be94a2a,f45b1bfb,968006a3,58398fab,424811f7,6765fe75,d4438d5d) +,S(357ea5e1,7a0795ca,cac47e4b,9e59bb24,45d1b6cb,2c713f04,7029f6de,2be57734,571de7e0,27dd05af,90bebc29,bd7345f5,77babdd2,75498bb6,d43a668a,8a4d6206) +,S(7baa2739,1db2a0c8,679d0e18,8c5e7c8f,ef1814ad,b7bb3955,519b4189,1a63ec40,73b56168,20fddbb5,749e8dfe,ef834f74,e266df86,e34510cc,f5eebb52,a868075d) +,S(4d5251b2,dd778e04,5143169f,8cab93b,9a9b7428,1a0ea1ff,964225a8,10b1e578,9376395f,2091036,16a95686,4e55382b,39b6934,2b2964d8,34face11,a44f491b) +,S(3c0fb553,b0c6330a,3cc06bb3,b0cb4c2b,31be7582,55264b29,98bbc166,ff57f7ca,f1f409bb,cc227824,4dc08c3,147e0b83,3522da9,6859400f,8d19272,e33ef1d9) +,S(6dcc7ba0,4b3b0827,e3bcb462,7b7db8d0,e0997c7f,900d27de,2d6c87d9,aab2c373,f2dcb11e,87b69faf,4400e9b3,186eeb6a,4fb48cad,6d6da276,3943772a,4e18b450) +,S(a5271e35,ca54c1b3,16d6113a,40414ed9,26bade46,c3258c6e,82a63e9d,927ce06a,e2d6051f,bf42dd9b,e0b2e00,1fa4e308,66232871,313f9c82,fd6ee37,6e8e376b) +,S(574d1ffd,976c616f,60371e4a,76b2712e,84b0a231,8d3c1c0d,3b56b10c,e978efe0,13733a17,a956efa5,733dc130,cc4c848c,19ecd6f8,7fae5ac,82c73de5,6d1bfa0) +,S(ccccd911,ea84c247,262a6e61,8028b2c1,a147f55f,b637b570,97400472,fe3e27ce,cc4b4f5e,491f32aa,eb6d0404,5965a97a,e4119e73,33bd1b39,f2ea9873,7d8f33ef) +,S(df1e4fa5,410f1438,9a41ca26,31eef376,4f10868a,f2f05a1,50e2c7f,8c3a2643,8185a88e,2b4a343d,bbc10da,723d4cb8,29014cd6,3211a82a,63627b01,1b01e87e) +,S(2ca6b7e,b53516c7,2e216263,213c0d60,fbb02f,dd227f6e,4ad29069,f6da9213,81d5fd1f,5264af85,53a8227b,7500d82b,84ca1fb5,87ea30bd,ab30fae3,67e3d7b3) +,S(df4bd790,ac3a0db,1663a8fd,aec1cdb5,b30c7a67,99ac2ed0,16f1c474,5bea92a1,db80f378,f33f920a,d0f4fad9,595b0655,44ffc36c,ebc3f294,3db13b83,cf609bbe) +,S(792648ad,8c053cb2,102dde19,789d3782,79e0e0ca,c500f40,d46bce68,97af2839,3c2d9b55,afa4ba1e,1ce3d142,5e17ca6f,191b4013,7b7d8162,8de35e8,801f72f4) +,S(dc6fe845,50fc1136,1f648fab,deb9b3f8,e7fee837,ea545228,b2fbd432,e53a8aab,2a4bf746,19fc5408,b4bc6421,f4a570aa,172ef263,c890c853,d7b06aa0,65960dff) +,S(10d4786e,9151f2de,89f368f8,9502b7fa,74b7b9e5,7a1485ab,f82fccb4,9c2deca8,15da7f51,bc84f421,2ce948cc,28663e57,8b4b851a,f6533f2a,b548adc8,147d2243) +,S(67c7c0ae,e82dfd5a,194dc416,41388947,29ddce96,5b7d50f3,ca922512,6e730bf7,a8bf40e5,666ba93f,1f723414,24d8a7a1,6a2aed83,7f022fdf,557e6082,e3e515fe) +,S(602c3df0,8a2efee8,329f391c,a9f7b2f8,31ab6d32,bc4623c8,92272934,1f78a4f0,ac17903b,3808ee52,c0208342,696f5250,5789206d,515421ee,8b1ab28f,5b788eb6) +,S(c3441893,e78910c8,3cf917fa,44b608b6,671ea508,37a7d2e0,4e658c6e,2a91d9ef,b5388381,17c264a4,a0876c3b,7c261bea,229c2d0,a7399c05,114f520b,a7185dcd) +,S(49dc68b4,412dc3c6,c4b265c1,6cde755d,bcd49f0f,394d552b,76f67ff5,33c7fddf,f1490a38,cdbb6c88,d270eead,7de6358,132cff29,ddb6aea0,1baf6353,4c0cdae9) +,S(89080197,4a95beff,da864c28,36997c7d,3a4c0fc0,4ad59eb1,5ba4b124,702d0f04,86e165a3,b2e7eb55,9a7996ad,63265609,aa6e3385,30b51d22,4ae4f16c,d30be3c0) +,S(c9671a3d,f749d635,5684de03,1764cf19,1087bd06,965d23bc,4ea0555d,29ee0804,33cc0d4b,b02a1910,c158db0,ad2bcd66,c9585f9b,456321d7,61752148,e6224d85) +,S(f3c1a76e,1d4ce622,dc667a4f,dc0f4ede,7eb7111a,1539ce5a,bca71d2,fd48a26c,269ebdcc,e1d42428,4e0dd49a,73968676,58857998,7a062320,6251ccd0,ac9f9e2) +,S(12002fa6,68924900,8a540429,50ba2901,5870a70f,7fe95ae3,dba4b07f,aa6fa460,51543d34,34568008,74e8b1f6,6ec72fd8,e2936b6a,6022401c,d13d50bf,931996ca) +,S(a59df11d,d3fcf1d3,264028b3,6e26dcf5,62083e44,f91f3d27,f23acdcd,f1392a9a,4dbda718,48afff3f,faffaab0,5c5376e5,5fd15ced,68b03ac4,4785ab2,201cbe70) +,S(89f738a9,802d7deb,5cf2895f,60916fa3,d6d74bf9,e740d2f3,13ba393a,b40cacaf,293aa5b5,b03557a,e7288066,5ade09cd,ae6abc71,8e7d445b,cbf85a44,a035b73e) +,S(d0414978,6252c5fb,b4bfdae7,56092769,dfcdc2f2,ae38a5fd,92ba9df7,f91a9ee,53ffb526,a24df2b3,d6e8faf5,ee6d79dd,7f427d8c,14d2d5b5,880f1863,e7e95099) +,S(4a638f24,ef3528c7,a4e42cdf,3f5bb946,81e6435,ba2c99d3,625dc282,b941d341,39d97ef2,949f1338,bc016ec7,89585780,832043ff,33777357,9ecefac0,ae40620b) +,S(70a25f6,34d32af1,47c4dd06,5d52f78c,eb5e53fd,64bb151e,18e8629d,f4f8088,1b6bf3d8,15a0f919,68dfd6a7,7ab7417,d4aed9c0,a52b93b9,9b4e4e41,d1e558ce) +,S(59ea9490,24765add,f99fd908,11c65ac1,d0f9ee8f,27e459b9,b5851765,8e96ab82,b38bc716,896e0337,e4a1b361,59e2b5b4,e1680ef5,beb4b47e,c5934b4c,8d6675b3) +,S(874a6ecc,6260617f,c6d4f334,40c8e080,3d993594,ccc2d47f,be2869af,9881f2aa,f509e39,6663327f,7d768a67,aa0d2ef8,353b613c,bb60fc38,bd2715cf,349c02e) +,S(dbf3567a,1e634ab1,63a860ce,244f3046,c7f486f1,b12928d3,1c44624a,48bb5df0,bcdfcc85,38e4702f,99f9d55,eaa55216,730405a5,66fbdf07,4c62b310,6baf7ce3) +,S(a534bcb1,96450965,5593155d,2da069a8,4800e4e,eca0b504,62d844eb,d179ac50,f86b38e2,d558be4a,b0a216a2,906099dd,f3cc16b7,30e784e8,745f39cd,829ff3de) +,S(e11bb840,b79063c,4e090771,29d2bce7,8f291f10,120b57ad,63594780,fd1f1905,7fcac0ad,e0cdc573,67c9d74,1c6c9928,15b7c3fd,3a19b266,e0e5a94a,9a9ef9cd) +,S(d79bf0b6,552c5b6e,6e9192b9,765e687f,ea226d86,c6f83f44,b427ea9f,14b404f8,54e7a54d,583e2cac,129f17d6,835597aa,934b4732,6ffecbfe,deb503a9,eb9660ad) +,S(103396a6,57856b61,5507969d,958de14c,251bbbd4,9851a5e9,ea64e0ae,2f87817a,9d66ba9f,cf3e0c2a,655cabd3,91774015,e209d771,334c461e,d27b683f,f83b477b) +,S(9b49e25d,ae607f4f,fd876837,5ffc0fb7,142f9cb1,f0fde836,537f320a,9636723a,3472462f,f9fa5ab3,1fd1279e,7953dbc9,85623021,e714c951,bf00f632,e9f72ab9) +,S(a017d4f8,8e757556,b7ee81b9,d4c9b260,ba2f7f8e,5e1b69a5,fff94abf,723cc438,5f2819cf,53fcc35f,c9c15d2f,13dd51e5,2c8dd134,f012aed3,4b4383f4,8b00cd95) +,S(aff1db2d,3fa6dc00,51a8723a,7127d57f,69ed0b49,ccbca35e,25f72bd,19076211,7cccb7c9,4adc2075,9c7f8870,fbeb1a1e,9f95d644,af0411be,a6b12d3,aa6f00d7) +,S(21ccbdab,f6902a86,d368d445,dfba0f31,4f80de6c,c7f05f7e,9fd1818d,45a174de,eda0b8b8,7f40e9f1,bdd5ded,e65bd72b,6cbe049c,bb1575c9,6b779818,a67251d4) +,S(c3e58ebe,36b0e5b7,2e15c47e,cca6848f,5312369d,d270dd18,93b589b0,56ff7082,212df92d,d724e3aa,c42e293e,b1a2de5,3c340712,7ebba791,b901ff87,9fce94b0) +,S(f19961ea,da1d77df,2fb9d976,7d7c664e,c0400066,2ecd7244,12b72dc3,c5de133,74f321a9,1287943a,8ed14d02,96b05ada,1a24fb52,a09d467e,8e8175ef,8f04a2c9) +,S(3aecbe48,2aaf6af,35e63dda,fc919adc,f974e89e,765c4437,69ef535e,cdc05e01,92b854b9,30e5e4a8,85397592,fde89d3a,601c733f,d88d230a,a1168e36,ee367273) +,S(55fdd639,b87de7c3,9acb95ed,33222935,bd4217c0,fee1c924,f1060f54,fd22055d,81f4ef46,16e51585,cb443bce,f16ad8e2,36d6ed18,87ddfa60,ddba2089,f4b83c4d) +,S(b86a6272,ceed47d2,4ef4cc67,bef0b117,c0761b4c,29548c8a,367d8ae7,bf90744,1c0de18c,d5f3331c,5439020c,5964404,be582f88,3feec4c3,112396ce,b657c4fb) +,S(d141a7ae,9d92913a,26deec5d,d2acb7a2,115da997,63be5a76,c5a0a415,8b5b8170,de784bc0,9308c82b,ce3be9c8,9abe41a,4ed9b9dd,cf817aab,3785e344,dfdc2ecb) +,S(af340559,6902ad5b,e3fe3464,3cbcea5e,7a478a32,b1bde828,ec966837,192344e4,3f65050d,13e7b969,35b013c4,9df385d9,833d419f,aac0f754,5c395ca3,75ae8965) +,S(b70dce7f,870d3d12,472d3c5,481a1288,cccfdb2d,12637a9d,973f4e12,b026cefd,4b4f733d,e5322132,80a36e4,ba57894d,a563f4ac,b1a55a9c,83c8dbc8,96a7fdf5) +,S(14fa3dee,44dafb00,d2e71c91,5d217cd7,a9c2b50a,edcd0025,f7aad2d5,b6c62ce4,67c3a65a,65bd4292,d271fe13,9a8c9d84,343bdf68,cc16e50,11676580,6bc30d8f) +,S(baaa6a53,26a7fc36,e519d9a2,48dd3aca,f6f0628d,a6406021,caf0d0c,56d9bb3d,4fe9c638,c1078c39,a0fc39cb,e9a81bc3,4b15840b,631ecbd3,8ca4a2bc,10d1f3a) +,S(ffe2afcb,5e53bc7c,9ee07740,c8094a3a,32c8e627,4dec7eb8,cf2673a2,dba11725,68d7092e,2b8b56da,1653dfd6,42de49c1,799d3ad5,864e052c,8829815d,b2ad952a) +,S(a25d7c5e,83a0659c,5ead610e,b581d325,adfdd3b8,af03736e,4039ee1f,40612431,679ecfcb,b1da355f,d73d02e8,b79fc949,bdc9fb5b,5a4e28c,5e68c244,7599c806) +,S(1c5d082b,3121c4b0,2e0e2244,88e53b8d,ac5500b,bd396f0,7fc218dc,7311b299,a2a435af,4838d028,4d459216,f3955427,59f1f51e,9a15f28e,d83987dd,9c09e5b1) +,S(d8d21200,2cf2ceae,6c9a90db,89f7d0e0,42a2e97c,458b9024,437e28ed,a775ca26,b31b6a02,4b01de6b,6159ee51,3c118921,f61a536d,c1442525,cc613290,364b9df2) +,S(b5265664,54579771,947bee20,f8e7bc48,1e15d07,2adcecbc,3aae7b91,a4d0f3b3,170ad05a,da7f67ee,f7c611ba,3c55c835,f054bcf2,445e5c1a,399c7cd7,640ba8be) +,S(1d0d2a24,8982635,18a28203,b78cb089,acd5c296,98b86b7b,48fd4db6,3c80812b,71e2e1a2,7bff3bf,9e85e145,7f446048,7643f154,1cbe829e,f600d861,dbb752e0) +,S(cbbd4ee6,33aec586,ec7ba712,c3bbffaf,a0e6497b,8618a476,b64c660b,340046da,d792753f,c73090ac,177ec5e3,40aada73,3b31dcf3,a1f46952,625dab85,7e9b9795) +,S(73cfd295,99b6b80f,8757a873,ce9166ea,b1960f77,fa8f1d55,ddcdc90,9420a751,17832aab,c1083af5,683f8cf7,23c6376c,c22d190,241e1e37,6b1ef2dd,7333c873) +,S(20572bf8,abe50ea,37a064f,738dd18f,531b9404,e7e4d693,2c9fc34f,ef6dede3,41c79375,11c8911f,3146bb2f,63750887,c663d2d6,f3fbbd53,30af73c6,9d332191) +,S(ac208805,2f1518d0,3724ef5d,cb149f36,1ed713a2,94392f92,96173857,94794f70,1820bb1a,e843255,9025f3ac,977d9f59,4e812cd7,e27c390b,b2fe905,ae2b7017) +,S(33467f95,60aae872,b5c9afba,7f29cd32,a213f197,47745d8d,945d06e8,295afacc,44040bd8,138d9bb2,76181e21,79f4bf98,4b0c3965,a1a47d34,be8f47ff,52e15af2) +,S(1a77910,75bd3497,cbaff6a5,d5e8bd6f,439f5bb7,ca3eeb98,68033ef1,cff83f03,d8af802b,daeebe88,f823c43d,447f1906,63ede3d4,c4b9dbd5,caf82a3d,b4f1cecd) +,S(dfacafe8,cc15f85c,f829d913,9a9aedc8,6a98e010,5308572f,94c183b5,533f5bb2,c076b6d,c708d2c9,895e22f3,2fe42f4,33ad38c2,a0c55aaa,5c551fac,fe601916) +,S(3cd975ea,9eb5fc56,14955bb2,db0ca413,b83116e3,a09454dc,7fe973c5,7ee33ca9,261e5544,2fd503f7,7c1c7a49,de96fb50,aeac56d,30cf3ae4,8b2e1cb,1b9fcb6a) +,S(168ac250,d23cbce6,23eeda,1389e261,c56bc718,4234bebe,6b108bf9,bf6df45d,add3ffb7,b0a9a860,21ca51e2,f3d2e2d,19206bad,78d9e661,2895068a,c880fcb2) +,S(47bae439,31966a6,984241b2,2afc8b86,94db88c2,abdb1737,728e1af0,e3803968,a7cb7d64,a07cd13d,2c8dc7a7,8a7a144f,8edf915,5cec20af,102260b2,d8d355a4) +,S(76e73a26,730b1444,8ecf60e1,3489de8b,93355af6,8943669f,20da17f1,4f04d517,41f75520,3d5d528b,2e81bab1,9ce8031b,bf9c73ce,7927645d,178ad762,669b99fb) +,S(f6f08712,d85f9219,bb475122,1ada6a75,1a8d4758,f5dd72f,f5231d56,e634c19f,d72cfc42,379ee25,eb0fb134,338109a3,7752fdd8,1ad102b5,f365a276,1d133f10) +,S(1acac95c,9b0ed53b,e6c37d03,7d47a796,2a371caf,cede380e,799d0110,b0634f7f,658c6b74,44846952,93a5215c,63695a5b,fc80f818,633e0278,f6a1193c,6d441bc1) +,S(5759a8bd,ab76d449,13258631,68773369,5b76d2da,7b1e4004,1bf99198,bb25f218,15c1dc97,8ecff6f7,cfd6cbb5,44ab8666,83127b41,951c247a,f44855,4afde3cd) +,S(cae1e14e,c28ddbfa,379a97d0,5f3ae379,3771750f,5a9ec743,2039f440,8fa7e2f5,eef09268,6b9f60da,8e64ae64,8f13d01,8f7b9ef6,aa849f9f,72df2f9d,f80fbf60) +,S(9aaa132b,947da7e4,9c1de2ea,ce06e3f9,ccdc37d7,6d2081a,be5f3a37,9b0756a0,e9bee628,d6a64476,af601737,68829c11,e8646e8c,beba7174,806d800f,56f6676) +,S(f38b62b2,4d609d01,70cbe85a,cedde44b,7a766a30,d8b7db6,8d935735,c4d0d204,8b61a5f7,e3caa2f9,17ef9ce2,c5eb2499,667558f,7c4e4e84,2644dfdf,a57666c6) +,S(25c121fc,74c57f34,29a143,8ff3c47a,f06b5de,74c4dcef,4a093b87,3a2ab659,69254121,eadbd76f,289cbf3c,21cc96fc,436ea33,9ccbc8e6,fed92b2d,331246da) +,S(95666156,c40929aa,8a7ca656,c42c64d0,e24c3789,ad3781f7,9e2a0ea,c7ab9c1f,116f5750,7e07b846,92106d6b,6976741a,59bf7cf7,909733e8,e1fb54f3,fd77e783) +,S(cdf1c010,7c48b65b,c001df94,c6e84d12,d8885af5,820d65a5,4e7ffea1,ef4c0081,8f3d1be4,206bd313,e1c498e1,5e7a9995,64312ea5,aa823196,9c566349,9c3a04b8) +,S(955269f2,be0d5e20,5382b2c1,959103fd,fa2c2386,9bbdd33e,a09487fc,294dd1ee,6306a092,4ce63798,41b2d773,8cf97ca5,e259f81a,a67b1e0d,42903f1,beaa869e) +,S(78013976,449ddc23,4d32a793,5ea525d5,9afa3617,47e0a8f9,c8141d9c,2b231e14,8d28142c,bb88abfa,1a72d583,4e509d69,3cdee0d3,bdff4788,83618ce7,a1ace69a) +,S(e6d67a8d,fe513147,2c0fe227,bb08a8f2,25e2606e,23672969,ad3acd65,155f972e,46c8695a,5b9d931b,adb568c9,d3f9a8a9,dd501508,fed00c99,5159f518,bed035ae) +,S(1779ea78,eed6d974,563cac2b,b3e72693,409b7029,789e0188,d061a182,3f18e962,82590ffa,6b9e0e13,d2e72bef,96d555df,9f7d2b81,2423a947,e0dae41f,91cc0722) +,S(28ec208a,6e929f8e,a815fc17,7b927086,7d482547,53ba5c3d,3b56fa91,acbb67d8,b4453dd2,eb964348,94cc1cfa,25616a2e,2f0803e2,8796206c,dd31ccd2,dc69aff6) +,S(c218c6d8,3124c9d1,c988981f,d4614af7,ff85a572,dd89e4ef,6209e80f,e7656de6,7259c421,45ef6e9b,d4f451e6,e2dd226c,2e750650,8ff7834a,965cca4b,cdbfede8) +,S(4c9891e7,5559d993,536fec73,a433006f,4f0e4e42,f427300f,7a3825df,85b1cd9a,7463ce1b,9f9af66d,7a5d2d43,ab0f09ed,186eb132,92c75431,ccee645,4280aa2a) +,S(a89fcff0,694ed82d,537399eb,b59a054f,f43eb74,f8e1fc95,be0c03c5,9889c931,3ef3c627,e3011b2f,38d596d0,8ded759f,fe30ffc,9db95356,4e01c8a0,2949ea1e) +,S(a8b3ef89,561da88d,ca9890d,5e4be652,8a4b8fe1,691d1522,54bcca43,1e7ed801,c86fc397,52254f61,88ee5128,4bd54347,8abe7390,c784b51b,6d41c947,5d58bada) +,S(6a2fd5db,da9093c,2f7c7ed8,9eeeec7e,efd7e759,eacc2946,5d1f3a15,baef5b42,8b71ac63,3886ef25,74e212a0,499c34e2,d2c7c1ee,b70fe7f4,38e08914,48395e4a) +,S(d33dada5,30626dc9,1d23d16a,620dbeb4,7551ca44,dd6c8b18,fbf136b3,1ae4e097,4161f6a7,8273ead4,443c93f8,2562a29,1dea1adc,d84ba0d3,75a997d0,f07d4ed0) +,S(53ef9ef5,731d9473,93e70829,bcac3396,3b7a597a,1f3c861d,401af7f7,fb1559d0,8654f8c3,63e53905,a4d1e2c4,378fc3b5,fd5ffe3d,e7fd3adb,399d883b,3d1b9e18) +,S(5f13c5af,6979832,da1bd43c,4b7df970,1ad837cd,e59d8f15,381858d6,6263b0a1,3b0ec16a,1024c902,666dca02,4649c110,2a17205b,e4ac20df,26ce5b92,8baf90c1) +,S(674b7de7,f65337a8,c66dbf23,2f86d6a4,feedabbb,b71e83dc,fd854926,86f14f86,e3961790,a662c6b3,70460e16,18ce3b6f,42bb6142,78fe9e2e,6bb1179,181c2aae) +,S(291eed8b,47c3e2f6,b3c2967f,76743708,5c460c5d,d5d6a75c,489dcf0b,4d98b8eb,e19a9d2a,72fa37e1,e10ec853,9c772565,c53e36e9,160651d,c2a8e364,db408ef8) +,S(e737a407,1bf4fbe4,ee5d3d74,7df3cb54,cca38f48,f977919,907deccc,7090ee3a,ac66d422,79441d73,2809d695,68f700a0,3fc5be05,8241da39,9be3a63f,8da16069) +,S(67fb1676,7c3231f3,428b39e7,bdd082d7,1194a51,ae99a7a3,6c113e87,d338712f,38c2ae1f,afb521f2,279aae5b,6ba5c636,1dd34c04,a7726555,acb9265d,31c996f8) +,S(9b3b4788,71bc413c,5e9d2b9c,61e0cda7,f2fb908b,805f3370,45639,5e616230,7028b68e,af818a13,d32f116a,aeb0bf45,215d3d62,6e6ccb1e,a901544,ef1d696e) +,S(63193415,59bb1e39,2f92dad6,e5f8576f,7f49d4d1,439f4f61,a6f2be0a,75bd99e6,259d5f21,6c780a8a,5bba3e66,2242f26f,1adef829,a535dd97,11f8e786,f0a57932) +,S(4163082b,7720a8eb,e881b398,dae059ff,3a65fba7,f8b93afb,6e3dae6,6a969c79,3939395,d8e90807,e77e87a7,4c89f861,c689de81,a37caf6c,32788310,7b938ffc) +,S(b3a6baad,15c01677,ad6bed54,ea5ee415,4d0bcb7e,3ce59f17,7ff26,ef23b82b,711681f2,1e56c0c5,f2c2b011,dcf75716,300e305c,110f4071,51d11890,25bc4760) +,S(9011d111,fcebd882,b9a228da,fdee1297,824c4007,7d5ad9bd,59e603b,43be8f52,d530102e,aac87930,eff135f2,e55b5310,7c03ea00,d24f1201,6653e3e5,5d778246) +,S(d50adaf1,d68a746,e1e7b148,7660e90c,f268450b,df460d52,e1f761ab,bf7018df,4ed454c4,5eb30cd6,e6f1c4d8,7df2bea,e15ebc07,e4b4e50a,e4dea733,93abcf8c) +,S(cf886295,d1eca9f3,4c95acfa,b86a5061,82e30324,ba5b495c,70318cf7,9e910d70,59bb7068,3147c26e,45c76e7b,e018e467,1f47f488,2c044484,62a5053,8023fd40) +,S(38723d58,ffc69ea0,9a8f2655,dc225da3,78b9224a,f8d81e7a,bf8f29ee,292ddd24,c41d67bb,e699e504,3198adb8,ff11a5e0,4033b66,98d3ec18,256bab11,93db5535) +,S(5b41d5f8,1e2443db,d13521e6,e7b7fdf2,4a226cce,f369279,22b353ef,107f759d,8ad730a5,bfb9f01f,853434b,24866a49,912fc756,e086e781,a07ff2e7,98ef38d3) +,S(4f3c24c7,7dc7e41,843e9018,400d3bc7,5d1dc958,2895c11d,3855b80f,4709373d,a485adae,c547a5a4,e0695913,c4c2fb5d,ea16a3c,5211c162,4819d704,5b0d8d6b) +,S(f603e0c2,8b40c8b0,a6a0378b,c4289059,5a4cf4c9,2b74199a,4e4e231f,a6b458a6,a73aa12d,76572041,f01c33ea,ca599a30,9ba0b838,f1d67fd,67a9a5d5,c3ffe258) +,S(84ef0a98,229c7af,9404cc25,60f4fe1b,4c8e66d9,1aa96118,53fc4f25,eac78a61,653df937,3640b28b,2c2c4061,1d79c4c4,a2d577af,b572f5f9,e50cf3fd,2b2dbcd5) +,S(e675d998,6b3bcd4a,d098ec95,c386be9b,4e96e448,ce6c9371,15c5dedf,d97941b6,4319799e,c4103d65,18590091,e333cd58,9901b020,a62565b7,f84219bf,e31003fb) +,S(10837b33,3603f33b,e528f391,b5b672c8,93fbd813,99c5dfea,f6126e6c,2a2633bd,cdee9534,2456a261,8a293b49,d91ed2ae,f620addb,ed83fc66,d169da3a,a6d0e2f6) +,S(4cb1ddb6,6ad3c1b,68c6b0ea,408ba1d7,dafdbe54,89c22d47,7a62dcc7,77a8e013,6c005484,29e789f7,5c34d8cd,a473270d,75eb8f1c,3db13856,87cda96e,5cd4b370) +,S(db72d671,ff3e0102,b1c52481,b66ea142,8f7fcd43,15e2792,eae234a9,291926e6,71c55f71,68a088f9,980bdb6b,79b052d7,4edd0b19,7ab7359d,9a2f9ce9,f1c5a5d9) +,S(99f92125,162e18ce,7493e6e3,91cd06fd,681371b3,2e147ab0,24ae3799,15f586d3,9286b3de,12ee578a,12ded341,75bdb712,d939b7e5,555e86c1,82f1f283,3c1b1d40) +,S(a2b8b63c,8984a666,2b09c18d,b2d7f263,796660f4,3bd78eaf,af7c63b,986c92d9,2003787b,2af02879,642b0a2c,f716f4d5,85dac86f,e58c7d41,d1959763,310a67e1) +,S(9292ef40,21bbe6dd,8c26a862,c9b7da54,4292e479,a9e89264,618e3a47,9773b446,d1a51e4,65bdfdd0,dbf74fd3,d449f6bb,ea862eed,ad369c52,34a695f1,d229ead2) +,S(8d5a920,547d838f,90159068,ceeab220,cc6aa126,d423edd0,2e136cc0,1cea5d4,c3334a69,f7694e9,43ccb182,2caf2abf,f4caa83b,a006af52,bc010bab,8710b596) +,S(7b62f4a7,7b79c09,76dd2f74,4ec08d9d,21511fa0,7891ff5c,52b8dfa4,ae3430bc,70ab2073,cb3a7cea,350e6aed,dd0c9a6c,ff8e02eb,69bd14a8,a09e9b8e,ccb19a0a) +,S(e18a9c02,5829b47,cdd34c11,f97f2edb,a7fb9b9d,fa4777a6,dbdc3cd6,85245b12,7386fa51,881fe49a,adbd5327,8d6cd0c5,1063dab0,aa830b7d,88c7a4d7,9998e743) +,S(ab9b68ad,61335dea,767c763e,3294d414,74a6d4ce,e4ab9a78,7fbb6749,7307d0f,aab48fbf,53f365ad,bf94f823,ea973a25,f6ddd341,397bd81f,8e825f60,c916852b) +,S(3412531e,8423364d,8d8bac05,bb78973d,7b8d375a,9e52d81e,bed48027,2abdedeb,1b9f5eae,59ea3385,9de752f5,db973a86,4c735e69,fa8882ec,e1ca8350,77d77335) +,S(6a6425bb,af9f65d0,1a401330,46053b50,7ac8d45a,77b30de3,69eed52b,956799b0,7cbdae81,93368c60,5671ae9,faead4ca,2887bd8,9a06062b,dd6707fe,f849f484) +,S(87860648,af9ffbad,50871c2f,29bce0b3,e9693835,8a067201,5c1156a6,7107a4cf,8660c0d8,f1aea58a,c613f6f3,5b27baf5,53835493,fbc0e203,f024ee36,27bbfa53) +,S(35733610,71c55057,5392c685,3cadd8a3,6618443,d80b3625,53a2f197,d3c52539,42935628,adab5bd4,e0aad0dd,a7d76627,58524b2f,34ded1cc,d3e44249,6d213630) +,S(82d21949,2fd48d51,65bea027,6ac15cf5,d27bd736,45e03271,24f0f689,8a2f4a25,f13d9063,fed02a94,1b4e5c67,f42d82b5,33f18ff9,ca4622f6,79c6aabc,ea454c21) +,S(ba1a1c83,6dabf825,e517ff65,549e1d5e,729944a1,d7b17cea,aa4466ac,39ec6eba,f01dd751,3557249,d2fb224b,40ea19e0,57b4052e,adc46787,af587ad1,458bb4f0) +,S(5cfeac36,6bbe58d8,45a36cd7,de6601c8,56943a07,522364b2,23a1718e,6df8de8a,6651d3d5,a344af69,25fe039,c9e29e77,95544b96,66752f4f,c9a3bb57,c5586c32) +,S(e5e314fa,2b2bb630,6fc235ba,cfd356ae,bbf88bf7,eb039629,165d8651,c0c7d5ff,c727787b,a63cddb8,feef96b0,2f6c8d0c,9722fb4c,6274e034,32d9016a,eb4d8cb6) +,S(f84d8db4,b745cfc0,bad4844c,b5a28d7c,80ed5fe,6baefda4,1d9cff9c,158c7ec1,cbd7bc36,a8313a27,feb8121f,a8847bd7,937fa53a,d56ea066,fa600411,d87dcad8) +,S(8806a2b9,d72156ee,4948e86d,43f4b3ac,cb24529,e1b2b2f3,5ff94812,e9534513,aff42464,773f6535,b4dc5eb7,76a3f7b0,7bc2fdce,1413587f,c4055cc5,afca3129) +,S(e2ddb5ef,a1105437,b6107305,bc715e55,ec0266aa,a0ba1bcb,e12ab801,45af7eb2,43e4d056,804f229d,da5a1efa,8f429189,6c9edf94,fba505f3,1f22b511,8b698ba9) +,S(636f32ff,ea843368,c0cb708f,43841ef3,20151e39,35683ebd,bb1f476e,af2f8c5d,7fd53321,517616c,c7d24b51,851bede6,b03c50d9,82269773,dd51e36e,4898365d) +,S(bbcdd1f,f5b47391,d728a06d,b4783d5,b0e279cc,107488de,44446e36,9d11d143,6ac7dfc6,47d25b37,7281abf9,ead782a,b5f815d7,b2c9f6a8,46a8a6eb,9253014e) +,S(af0ed949,22336a4,337e9c01,53357e02,3d7a2728,3c649712,3e117944,39ed3577,d8b9c03,958dfa89,ec2105b1,d9542d68,568797e3,7df16cc3,861627f,298f3359) +,S(11ba75ae,db365552,b0d3f938,f03a115a,544a0818,b2f54f50,e4873249,6f80ce13,a6bce69c,f9838317,70f70370,7073e87c,61b65c0d,bfd34dea,f0c549f9,c58e674f) +,S(e7560fb5,79e5ca35,f45881db,b05383f4,c5536ea8,a5438fc4,ec198ba8,7543d3ad,ff48d1a0,bcf5e510,9ed50a0d,ed8e5b83,44da25e1,a1a3d421,606d19f7,e28fe79d) +,S(ce7e289c,61f4927b,bf933eb5,193fd2a3,a0686435,80c8f235,1e24c33c,e418cf10,17246f2e,e87f4ce,f1c8596a,ecdb1f95,1407ee7f,dd839c9,98102344,2f4dcbcf) +,S(b765b875,32ba4db1,211c612f,b833ba18,156fa0dd,875aa61,df1ba9b4,7d1c405d,862d28f6,d85a8ad3,bebfbc82,437404f5,2e0abafc,64369b51,b75364cd,c827171) +,S(400560bf,d2863ea,2bd9e246,4eafab2c,2798cb95,b976c022,bb9d2153,e5978a0,92ca9a1d,938e53d5,d10f1f83,54abe43c,e8f8c2c9,d4e851cc,a363ed59,71e2681) +,S(7859190b,8e619c98,76af21e9,64f323e5,221cd4c8,83dd9fdd,e56f691e,e3db91a2,e1874376,755165c3,72abd73e,415f2663,bd94cf28,2009492a,e5034da8,6f6bf949) +,S(87d90b40,bb472b84,f9d24caf,ba7a6437,b50febd9,5c643aaf,e235750b,12527ef6,e6a0f719,25697425,23517ea6,183faa64,dee1ef63,183ab1e8,3a603b98,20452c4e) +,S(dbae1ee5,a1b6affd,f9b41ff6,a1f2790b,2c492ce7,53865690,ce5281e,a7f08177,f6a2be90,a2c3cf,8e14bf87,4cc52648,b60f9a26,2930f6e8,9fadad4f,d919db6a) +,S(943a79cd,88260475,10d90c99,4d8d784b,32c03d1f,f2478102,96125f7b,28576216,48d4477b,f97c4cbb,4a96ff99,e427d4ac,cda9a367,2ae66930,88d8cc57,3bb3e2d7) +,S(699911a3,81ff3c7e,71b3a458,14133f3c,ec644378,e3244d66,6d083c55,7b6c040d,3eec684,3190d6f3,85b07116,b3b1ba15,4ecacec0,63e02933,9b83afad,5598b22a) +,S(f002302d,9ca256e5,cc38ad82,e529b461,efb69f28,52513917,fb8d63df,45e602ba,78455ea9,708b750a,97dc74ec,8939c880,d76010d6,78e0c112,3616483b,fb4e788f) +,S(5f701ce9,65a20314,a65e2c0e,1cedded9,ddfc9d01,41a1e095,e91b9915,cd2aacb1,57e770f2,d04e33ff,c9d7807a,4c3d1edb,3f9ed2,c19771d6,7e85e618,463e5663) +,S(454c122a,ff85c42e,49d6f033,87744462,8acfed31,90c41255,e8e34928,83563fcb,9d9d6435,a2c4d146,d92f34cc,40b32a7e,55584885,82143a,52039fd7,129fa6f6) +,S(d9abd19e,81f392d8,8382918d,6ab3f89d,de793abe,2eba3aa7,b58b0ca3,1e614e51,8c1a0f80,8b8d9e56,aed21554,95f8902e,a390505e,15cafbc4,2b71cf05,575abeec) +,S(20779414,b5ed6524,b3613a8c,d0b6e9c7,ff3b14b7,7264cb8d,7b266ef6,cbb224b7,c1437dd7,71f46cc4,3cfa52a1,28c70367,d6682553,28942150,c4068da4,8c218d66) +,S(141739f8,503f2225,feb40431,21f0a5ee,844a7707,62e37d1b,3e43fad0,81c631b5,a0a13de0,10566ee3,1af8c6e6,38411c1c,a3df6c63,c8ed67da,8ef7bd19,5fd6e73f) +,S(de8d06ae,dd58b148,91184145,fcd9bc64,634725fa,e4a77d35,70b21c8b,77890b60,a046f351,eccab99,1d3d1c1c,642387fb,fb9c3f92,75bbb93,46688555,f7aa9460) +,S(312c7ad1,53f7280a,9bb86cab,ac573944,d271bcfe,bd59291,c6f05fe4,ec003a81,3c6428db,5eea01c6,9fa2556b,1f20c1e7,4e65629b,e73e6429,81b971ad,b6563866) +,S(2eafa04b,d276e33,75b8d063,b206785c,ed69f763,7a5a8b99,ef7d3de,bbcaf35,f06464db,56ccf55a,1f41efe4,d1cedf81,a642da24,3cbe68eb,6ddf7ace,f67dac6d) +,S(5873091e,dcc8a95c,a0a47570,3d88e54e,1381c2d7,a418f615,eea97470,2c2c6fbb,5a91598,b8e47d2b,2fee6cdd,c33aa309,9bec74dd,21688542,9b76543a,c233ccdd) +,S(e713bd84,ca505ad3,aa022577,c0cac85b,466874a5,b02f4ab9,e8d14bba,c131fcb,706dab4a,fe49e6cf,d290913d,358d1dcf,62e8b4d5,b9bd46a,322ee4a6,5a660849) +,S(aacaa633,6fe86d41,b05feec1,cf4866d,340fd268,f869f912,c2373e10,bcd95340,d933cc5e,c01024e4,77d1e80e,c533f293,e4fd0dcf,7d1156b8,7ebd9d81,b9489c57) +,S(cbe0ce9c,77649031,25590e03,cd9643b5,dc45ecc,604d51fa,d5bcb8a,196b65ee,d2287fed,c331d56f,e585bf1b,793fd957,ce425492,df41d8b3,4faf84de,c3bf4d22) +,S(f9990413,deca9f9a,4ea6bb8,fd9b8732,57d15ec3,70e98187,f4170103,dd416dfd,b0593cb5,dbce573c,f0a75f2b,c4756781,963e1a2,e988e0cb,23efbe26,c215ace7) +,S(2ee21d79,bf3e82a6,2bcaef34,85276c5,3b51bfd8,becbc9f9,6ad316f3,a74bab97,fe3cfa79,b208de80,f659cb81,bed12184,ea2c2524,dc0bea05,64acefab,1acd8fb1) +,S(af5c91d3,44fccd3e,70345a2b,ccefc0d2,19287be5,aca40ebe,e61de522,56f25faf,bb58da83,bebb5346,9b345695,fc23853c,bc0221b8,5d75ced1,da107fc5,c106875c) +,S(2cf50e13,477d628d,117e0bb6,1d3ff9e6,1108fe94,bf82a6f2,4138a743,6077e0af,339c0a53,77a6465b,29377e1b,dc344464,875687e2,7d1f392d,96a275a,e259793) +,S(c51a6610,1522f63b,84b98ec9,31984865,eb3b29ce,fe115b28,a87f89c,67bc441a,240b9717,6af4beb4,b0502d7b,2caf8c7f,47a9362a,9f9610c5,826762ea,a2a2be5a) +,S(27478eb7,b14d84b0,80426792,b0e2e510,8a4804e3,a15e80b9,c430d7df,c09d05ce,eaa0a072,86fac65f,3da47bfb,4010fed0,fe8a9e17,ae42ece9,233c2078,2b36422d) +,S(531ca72,e21caa6a,43f0c9bd,d0bbca5a,b12dfb9f,70f045b2,f0865077,cdde192b,c4ed88b1,a0397589,3cb14ed0,897d6bd,783dc647,ba59772,16c308eb,630367e8) +,S(295775cd,950d0702,602278a1,56c1d05e,4343474,a4b3ae87,63f4a686,7688e42a,907fa8f,1269cb64,41591004,f6e62b14,4d6c54b5,f6ed424d,6b0a8a75,26935b49) +,S(e88425d8,bf6e89a0,f9c9f525,97eedd4,3c331058,10936c23,4da69d21,9a86f82,56d53ae5,e7a354d0,d65cf742,d603da2b,199e147,3d42bf3d,639f83a1,cf91cb65) +,S(4d20a032,c44453f7,b374a82f,f088d816,c1fa9338,57dae8c7,b87295,98869a4e,a7ad5993,af43cd42,1620e87f,fa0b3305,e7da39ef,704319f,ae5faf55,5e3fb43c) +,S(b98e9728,e9288607,a7ed6df9,c68749e3,9d7efa1c,4f964428,5e9bf81e,246e936c,1620c470,19b9cef8,7c1f0612,cf56adfb,5526573c,f7746a98,48a0d40a,3a92d38b) +,S(562eb109,e9988778,bed85413,2fa7d086,6b37a8b,fa2d2d3,470da3c6,97996a48,29f4f0da,e554e380,613156e3,34207e6,fe8fa678,4c08f2be,c3d6a59d,1e0941b1) +,S(b189e864,8dc0ee06,b09ea73a,9a01cc06,b6fa74dc,f626e41c,ffad926b,901ae851,4e42c870,3d04838a,9f0682fb,bc13c849,a515d5f2,f248f393,e2caf0c9,b6d61d0c) +,S(3894cdb3,425c618e,1da2c6bd,1177109c,49362a4f,24030692,244bb0dc,27af6913,20c0021,5c72939a,497f08f0,bdb03493,8d04ddd4,8fe8f3f2,97dfef19,ec9397c5) +,S(394f74a9,9146fd43,9035266b,ccee72e9,36ff59cb,eab7bf4e,925c6363,fce7d4f0,c7da15cb,c1cdcea3,21efb1fd,c56bb3d1,2bda06b9,993b6f5b,2293e493,5aa3e5a) +,S(44fc66ca,d6e67f97,be95c667,fd5dfdfe,dc82edba,35df2bf4,737b3ba4,14d15c27,9c485757,351825c5,245c6eab,2ec4a51b,ac60c9db,fff7988d,8f28728e,60f418d) +,S(fa355672,d9f7a1c5,30b2d76,f183720f,e50840cc,ba413b64,e449d2a,8b0518dc,63fe1c7f,d97c7744,35613167,660926e3,b7377fd5,97dad03c,9debba5c,a5a76e3) +,S(7325c269,50f1bf21,2f9cff6a,170e446e,62dafc2c,f05dc50,4eb951d2,6322eefa,5f8fa04f,ac5232b6,cb553630,5a48b647,263a57d1,2c485363,6c930497,40965f00) +,S(7004b364,c89ac7ba,ad03a03c,c8e2972,e5fc52c,bc656165,e08df216,afa216c2,971a4284,80556797,ebea8b1c,b37de6a4,1aa11abb,df9b28b7,7f50d362,b6554974) +,S(ffd45087,eb9308fe,e7644817,9406d9b9,77364732,f3570ebe,80a4710d,a0ef292f,f4ae4df0,5af2ee0e,456cca0a,2c9d93a0,83eb9751,a09c2f8c,5bcefce7,83764ffc) +,S(ad899e8b,a7aedce9,e53d86ac,5ca15408,140c8f1d,be3ba4a4,275f332f,b0320572,a914795,bfd9850a,24251eda,98bced8f,2e2627a7,8a1bf6e2,8b66ffec,f11ea105) +,S(7078718d,e94255ff,ae25f1df,4ec2ad90,e59ada11,5ad4a6dc,8b305fcb,93a1114f,ee736453,927cd7ed,bbb55010,32eaa95c,c0f6bb42,be77db4d,62b77650,1094ed7e) +,S(30858d4c,d39abb36,51b8d35,58800c18,5495bf31,bf23dc8b,176c1f04,171e304b,3aad8415,4abdfbb9,1eb95aa8,4e7ace9b,fd8b5f6f,cc8ea08b,e094c874,8161f85a) +,S(c06d6d2e,5637fd7f,df08b41e,5573478b,eb19dded,ead1f0c2,9309fd59,9551c787,78cb2514,37d4ca62,91bab9c5,57e88244,edb9dc30,fb1a6441,78217039,628e1db2) +,S(2f93455c,279d2a26,1cc7b724,4c32c853,459e5d99,32692fd8,ffe7ff0e,493de2c2,455f0902,74d698dd,a1a97586,fe797421,899f7c22,60ef0bbd,db0664e8,fa323156) +,S(c00c345b,b4b53f5a,5dbc5f10,597dbad0,75e28162,32e0ac71,fd778c50,20b663d5,c30f78de,3495063e,ab98f001,83fb4bb5,5cbf58a9,1bd52ea5,36a4a38b,cfe89288) +,S(7d78faed,f86a22b0,14e86e1d,f98d425c,fe2e65a2,39b37994,ab25a4d8,5c863382,cffee7d6,5181e361,679c9d51,feff7a36,e8d84282,32e752b9,62689eef,a1ff4441) +,S(ab492cb1,da2e8463,a2536c0c,7cf143a5,9626497b,23d4c179,d2af4cc7,f2b55866,11d4205f,55a74f81,e9512496,becb61c4,6363c42d,baede671,9bd7f2f9,3e00b14d) +,S(d1a3790b,478bf657,360b3459,555e1dc4,ece339d6,93b5b51c,8a3af121,79578688,c6028991,3ea89956,802f8b8e,cfc8dbc3,5894846d,1aba2074,9a55153b,83f73891) +,S(6fbb6fcd,36fe0388,a4bb648c,95a004f9,b3c64e4f,9aad672b,42d8c649,4c0cef3e,51be473c,74ca2609,c3b79c60,2fe90d98,62eb9d14,b9e52aa9,ddde106f,7253da44) +,S(db150ec5,680299af,681ce826,794e4818,c0d6d3d,e3c392e2,79ecb408,aa55b243,15e47cbc,1c4689bf,fbf7ef42,1db5c57b,e3ab8c16,b69bb518,2ed8a1cf,20067de8) +,S(51ffc919,afe67f04,a889323f,4438da99,72d2161a,54f9e81f,aa1e644e,9cb88835,e4b579b7,e985b38b,486d0600,3f825538,52a9d0ca,b8fc98d4,371a7e33,4898742b) +,S(fc86c54a,48052ae8,d8480235,e4dbb7a7,6d05d830,d2c0cbbd,297db0cf,3d2d6cea,6cd61522,e2a22531,da973c1f,9cca1c77,98ff66a3,8f568935,e378f73f,9f1d7dc3) +,S(d440de01,20d619b0,6add3d7f,66184864,5754a424,f4b1054,479a83bc,7df0db9f,3f09b245,91124175,89071c56,84215cde,a6999b17,b5b2f664,6074e7ec,6c38f68e) +,S(f3310bc7,7556f234,e7c83d69,48afebf0,5bd91a25,b516cf84,60d0d6ec,8483fefa,1d10f23c,e0e35816,6b817553,cbae0792,9e34a4a6,ebb47186,1d401341,1ef2b3e3) +,S(ea770a59,e88b598d,493fc75c,62eaa9e7,485271dc,edeb1d2f,76df983e,54cbb51c,e2a4baac,96c9538,3de82a29,5bf3cf30,53bfe2e4,6fb0861d,65c60c09,978601f) +,S(2cd56ef8,6fd04d2a,ed4f8520,951798c2,a1c69a38,8e635a2c,edfeb08e,3af0e331,3b9de80c,42e0c683,85aecbd9,c8775b56,86a8a376,39efd24,98664343,e712707f) +,S(37bb0206,c96d8fd4,5315e96c,860f5cb4,a44d2b6d,af17844,bc305b4b,59c9c649,c77b4a05,373c42e4,e071090a,7da9b4a,4ccbbeaf,d399496d,f6fea1d1,a83808b1) +,S(55fa08fb,f83dab6e,ea7034db,15bbddc0,ab2b472a,b29861af,543a970e,d16033ff,73c8a90a,86542970,4e25f370,a5caa4b,a68eb72f,5ede1edc,5549105,491858cd) +,S(4eafb675,281fe8,98593817,efe128ca,c59fb775,82f6006f,339631e0,6e7d2e7f,41347946,6630f6d3,9fa97404,6808067f,fca9e173,3e1c4149,6567eacf,47a0bc6) +,S(857587d8,375f24f9,e6924793,9ddf3a60,e0469f38,6ea0d55,d990f1e8,4ba5c7dc,1913a118,9d867c57,2f947fb4,3e062cec,3df37c3,e8edc6b1,927b315d,10c37be3) +,S(89e334d8,f71eacef,6cdd0a87,b1e03352,1078a1fd,20dff144,10108202,93143815,8b49aebe,71b60eca,c9256794,3cf74d9,80bb3e47,161b2730,9ed15872,7accd84c) +,S(69902d6,8a4ecb1,d2e496e8,cdaebf94,58f71f94,8f4341a4,11fbc2dc,524f694a,19a54c4a,5de17930,6c50cc03,b0b8d54,b613cd31,6f0bdfb7,851db63a,9c605896) +,S(52f8a3bc,832de46,1bade518,50121b5d,2ff475ab,5eb0e71b,a91ede46,41f0d576,2a946bc4,42f24ef9,469b8121,31021186,5b22f3a,adf93648,5b7907e4,791236e2) +,S(146fc341,4ca1c497,73734f6b,b78ee9e,56fedee4,9487ea01,a31d3e4c,152d2bf,82e21722,e415f5a4,1a076f3a,8324db4,2436da5,a3776f60,b5c6f53d,e5419db9) +,S(9e22043,8458e463,b1bd7399,28200a4f,ef7c3760,a7b6357e,afc29a5e,36b37b94,b1f5fd78,c1c40d98,1473fd4e,72af64d7,7387c28b,7f005191,5ed2587,674877a1) +,S(53190555,8d044a1b,94caad4,526cbed1,82807c65,2bb053d7,61301ab9,68323f1d,ce591f2d,61b47a8f,8707d8f6,a8717139,68ad569a,667ba4ac,f2d18356,ab6d326f) +,S(b93b3c6b,1297cadc,392b0cab,da322a1f,69791a68,b48b0ce7,4352ba3b,b8a3cc8a,136ec007,24fd378a,53d5c573,3aa7a06,15b2fb20,4fed82ea,934bc131,7e7ef22) +,S(62e6af72,a9fcc956,4367d44,c0699897,3674e3f7,b79c67bb,8c8a82f1,6d3f744,4c1e4e33,2e9316ff,24a7b38d,13ed1b30,a659a8d1,8423db6a,af6324f9,4e7d5475) +,S(c91facca,aad0790,886c4421,d28f3ce2,9d64dc87,514f06d,cfe95063,dbbd0e3b,e7a0c83a,18d655d9,7a555c51,4bf8f117,59ce866c,61a7e691,8ecb1cfc,21e50710) +,S(72b3b928,bea91ce8,767b2f22,958458ab,9a23f455,78f836,65c89717,7e7ea502,773235f2,c9ec74e1,c06e4e7f,89247d12,27f303ff,2fa354a0,663791a6,ffa40e49) +,S(1b014ac2,7213cc08,67877fa3,c0c07b1d,91529259,23f6164c,f1d204d9,addd6f4e,e0dec57a,c1ec264e,380909bc,c62394c7,413cfd48,180b1de1,c5440d08,99c67f2a) +,S(985e8845,97e2831c,4ba48888,ac219b3,bd891dc,63176953,4e0d8a96,bf583a83,5afa0b31,1e909594,4b228958,657b95dc,a198b008,6f5cda96,c3e4da6d,e444a418) +,S(ec3cded4,cce88ac6,22315a51,ec99ed3,1ba2cb32,74a43e6,98e033d4,e490bae,1c2a2236,2704a765,252b2a57,aa1ecaa5,4f1c21a5,2d67c050,a3dba077,ad4b4480) +,S(f882c4f7,7911f6e8,64da7cb0,5f09da54,b9cf7125,21504815,e6fdb9e5,73f24be6,9ba4a4c1,e0978ee6,1f83aedc,b1db2193,518a71d0,c112b9fa,59c629cd,d42ebde2) +,S(f06c3a4a,9f1e80cb,e2ee6b06,ff50e447,13d8eddd,5857243c,cd02c5d2,7996eac6,6b38bddf,fccb4888,da20ce7e,495bac5e,7b9ec8b2,2feaff5,8d4329c3,c546e839) +,S(dd1c366d,5be82883,eb86da5a,f9b5d5b2,89de6b9,1165b91c,20ad7b73,ab4de421,19bb181,70b31a81,45232ba7,ed0fa93c,273751f4,838633f3,c94647e2,93c06bc0) +,S(e965c1f6,89b3f7a5,97d23d9f,378b9a03,fb1c6e29,5354de36,a5bfed53,3338372e,d98295bd,890e98a5,9d6dd93d,bd9eca2e,e79b028c,7459779c,2d3fb665,46692242) +,S(4f9148b6,cf21f5fd,911d7fb0,e92132d4,686d3e10,12da444b,f5a89040,69c2fcaf,60e9b3ef,924260db,ad68793a,d684c316,6889b0d0,38474c70,6ca25978,4a5fa7ad) +,S(d9341e6,6a505a91,dcefd533,90abbd54,52b39594,42deef9f,6a67dac0,8faa5e00,eafdc1b5,2b7c97f2,21ba8635,d49b58fd,17cc7983,92e09d13,8c41d679,6fda331) +,S(b948bed3,4f426bbc,e6c24ca1,fd1d2092,1de6f9d9,f561c32f,877a4104,afe81ae6,5cacf40d,f6fba19d,763c5b0b,83aaa284,f9485705,ad882b6,d51bd46c,b12f532e) +,S(73011c97,dbeaca8,8bf04371,311e9558,1e494b73,1778a2f3,cf906cdf,64dd781f,2b5abb31,c2e56a38,e8236f7f,b28a93ec,1bef3fc8,9be46d92,c2fc476c,42ff4ed9) +,S(44835043,1373a095,13f756e7,36ac8342,24004348,70d6cc5d,ba31f74d,565056ce,748f041b,a9c990b7,70c36f68,5667109a,acdad74d,4569b107,c968e517,143499ae) +,S(3463b029,e9dd1907,bba2b582,c9ff1f26,4a5ef4b,40f5af28,2a00c136,97145ffd,9e30bb18,fbb70c1c,edff9065,968523af,33665b53,3f14457f,59d7edbb,d5f07c5c) +,S(5d95aa9a,9fc67758,56e6655c,21a62670,c567e236,a41b523,436beb2c,18e69c97,d6478496,4220cd62,b4651e8f,965bbde3,22aeacc0,6557f656,764a20e4,649a1ea5) +,S(48c65239,d03715f5,71ddc36f,313a1723,b014c047,30cbbd8b,ca9617b,e8fb3874,c0bd39e6,3cc00fde,74c991cf,f6d711a5,356b029,5b6eb9c0,28c445af,21de8325) +,S(67c610ba,fda8dfe6,c7977b70,7a57ebd3,9654c7d4,c9a0aef2,80c896e0,e8134078,c3d4ffc9,891a4267,612aefe9,6c1093f7,8e1b9a58,746c986,c5265381,3ba46aef) +,S(4605213f,4a21b15a,4a471e10,f157d0c3,faebaf0a,f7cd05c5,a27c56c1,88b6d430,9853c145,5f4b3d38,200aebf9,d08f87ae,3eb4a99a,3d94ace2,94331e03,876fb751) +,S(6277ce5d,fb56c2fe,3d32e28d,6754255a,ecece179,70615443,b0d33e5e,b54e475e,dc7a742f,92160074,69d53e73,da526102,a6f68e7f,e8f07a91,98614f0c,17daf06c) +,S(7fbc032a,fdb50898,3270249c,f1a7d27d,198432c1,6815b7d2,c929ab67,bf12f01a,dd696a37,fbc4f852,6db85ca0,6bb498e8,6dc33480,a4f84564,2b49775a,6bf20ae) +,S(dc849e28,6b934ef,30cab6c0,1cffaed6,9ea74ab6,96578027,4c88845b,8ac264f1,6d7f94ae,347b9b18,bfa2bc0,d6b9a8c1,13ef1a70,78e317a2,53f21590,667f4b5d) +,S(e29e0833,7da9e0b6,b6886c7d,fe010cd8,9a4b10c6,f5e4ce38,c1202f59,94a69016,de082f4a,9c21db41,573dde9,d2ca8256,57c67173,207d43ef,e42ea81a,ee812dbe) +,S(407f0e21,ddccb63b,5672eb15,742d72f7,1a522f9,20d04247,3e1438e3,7bdecd35,28d6f39c,cfb36986,351d7619,daba6271,3c9869f9,357504d3,25c112bb,74ad336e) +,S(653286df,15bf657f,1685bb92,98462383,7c819def,84a8c332,77f6d777,4c8dd3b3,c5ea3d4e,f7a97324,96a98abe,f999c25,9a8c622c,944a099e,146c0708,d108eb34) +,S(47613ca6,ca7fe67f,4286f12d,3b4bcd86,455a1863,94f2bfca,e162f991,3bf6ed7f,4409a6d6,2ae63ffa,a3f2be74,e7d0e5e,3ad4704,76282b0,c2919750,72be1386) +,S(8f9bf4cb,4aee791,12162fff,75f35393,509fcd4d,aada298,655bd58f,567e6adb,893c8b52,c2c25f8,e2ea051e,d1a35a3c,8ddbbf9f,508ac792,37e53143,7818102f) +,S(4b25cee4,2f955db9,79c85682,4dae806a,3925a33c,42e6b6b6,ab4997bd,884f68b1,ebe38f45,bfa13922,d3112af9,1324f526,1c5f864f,4d722576,24e3afe9,9eb7ebd8) +,S(a8a40ca0,56b5e168,6fb9a348,ae26b15b,cf812cc5,b9c5abc3,44f86021,69958e81,a55421a9,4f1fda1a,f6d64e48,cee3e4a3,434293d6,b49a5cde,b521c0de,49cd31cd) +,S(1f7e97c6,198e27a6,48ffebcb,55c001f0,d591ca64,77c7c1f9,43928e2d,dbe88dfe,2dcf0a3f,f296f744,dd402fd2,48d29c96,49abc871,28624da,28134cf7,6242e6d2) +,S(7ee29348,7d6520a5,586b3ba7,4a0a660a,a4392e5b,77529e8b,890a5927,aad1ab71,a51d3123,b4faabc3,77bcc565,d66d4c40,92decf92,f63f81d2,ba3a4f06,2a8ea485) +,S(30880ed,b4f5f2d0,95c34730,d10a8c02,11efdf6,784b4886,4afff98c,407734fe,4ca4b106,41c55905,9a19cbaa,bc6837b5,300aa1c9,8b0d8a72,8caf5cd2,914ea693) +,S(bb7ffe45,b725038b,597a20e2,6f67d0fa,c77730e2,4ebadc9a,23afb4ef,a01b4d50,dcfbe717,46bc35b9,81357857,c0b4564e,1ea11852,c5ed8372,bd15eb69,e674e14c) +,S(ddb59e25,20a5842c,62607d4c,6d31f2ed,b79e387,527dc12,5d96fd04,84385e51,2a167f97,85ee4285,7471c45,2c38639e,69940f77,b3fcd54c,a697100,37d9e5ef) +,S(3c405df1,36b1c6f9,99fe0b3,2bf5a305,bfa4a6e9,994a1506,9c5fcfc,318dacf5,ba5ab8fe,43a2de82,ce289cf1,2255f554,d7881d08,a54017f1,e0c84180,d963f3b8) +,S(ed4e6e9c,9d4eb277,73f2249c,13d6fc1c,5c07be47,9ca48e35,913f6fe8,384851a0,8242617e,36b3c298,b13aab58,b7383dd7,93ccd4d1,7787062e,195456ec,43fc4198) +,S(60fb7766,9f312be7,11d0a269,a72a85c,e06b70c8,1d34416f,f7ce1a28,41d50895,ba2097a9,772a616c,82cd5dc7,84585c80,65206913,474f49ef,71579a3f,8cc0d825) +,S(1336a678,bd5d495d,c688c039,a60b256,a09fc946,830fa80b,1622890d,9c8f0881,6d57f261,b1073b42,f6eeb514,58e994f4,7406b3f2,7245a0e7,528748fc,65a4937a) +,S(adb7e6dc,72c02a9,fb99645e,a3695824,db60df0b,f9b6a420,75cf02bc,4e3713ee,96325866,2a062180,20f8b86e,e5ef1e04,57d01fd6,d5541d6e,50798883,9f03b3c) +,S(674d6e5a,6501f824,87efd592,c37bc14a,ab596cec,4d5e6e8f,1be44a53,a9d2f416,e6ca1153,76af0429,1bc2dd6b,2c47a816,c17e0ad7,c252c1d,cdede8fd,c9a18630) +,S(ed73f5a7,93dd0359,68e253ba,8ac4f2ae,83d7f290,24eea4b6,fdc418e2,4b63dcdb,bf687b81,4691d48,5296e192,d5371ec,daa831ea,ce2d502,4e321add,b62f0faa) +,S(601cc630,47ce63d2,c1fbbc49,f3b2dbe5,6edbca09,17ac41e9,b39f7ac4,5cb3ff8,a773b9b6,d98c7b35,458e956f,f9cc71e0,8539b118,bc2529f0,fd496e54,efc2b25f) +,S(a31ffa07,e16fd36d,2edd7d1d,944ecdb8,2da2641e,cc6ccfe1,88219a67,5677a740,c2253d87,59ab43d7,c919710,9e9ecdae,df1f2d82,d34c5d82,d113958f,cbf1e3f) +,S(131060f1,ba302b06,b26360ad,de531db3,422a6bc9,6ca1e9e2,98b5da8a,c8266249,4dae16bd,40159bfc,96665d6a,d64c6c5,3ce90fe0,95a316a6,8cb84844,ec183cf9) +,S(f4a29fd7,90f35f1f,4b3240d6,c0cbb983,3e701a9b,ca241d3d,bb7630a6,da2de25a,b2ecd794,5afa51e0,1caf3c21,5334dd9e,9f9a1f6b,8f35767f,c63a3f00,69c01382) +,S(b30546b7,c5e45266,854b90ba,53afdab8,be115251,5ae22f1b,5e0c472b,a3b44042,f14a6b95,178fbb85,5aeb9cc3,a4e65560,3e8b18c1,4cc54cb4,1e059597,faad7f4) +,S(b6cbbb5,10ff83fb,c8bdd55f,cfafeae8,947f5e83,4cc78eef,dce45dee,2014e175,d0e29276,a14cfda6,f518a3fc,ac6a4163,13666f91,ce5ae7b9,7abfdff4,925cd415) +,S(fcaed74f,19199482,564ce4b0,7e1033ca,c17bd418,769981bb,6547caa3,b61bafd1,c52c08e,f5331ccc,271b108d,5e7794ee,4a493ce4,f6665773,f97902d6,ffcf40e0) +,S(c6d1ed83,29ade032,c9924945,189ff23a,c6b1befa,e4a33794,8b1b4126,6d14344d,6e1c0e9f,da231092,86d23cb3,2c588799,507368b8,8c0628de,b8a79c97,e4ba817f) +,S(ac7d0edb,a7b86cdb,60963277,cac43674,19dc5d85,ccd9a649,bd335dd5,eea2a9e2,61790bc0,ddf5307a,56fce870,4bc9eed6,9d61d857,f4d2fd34,d53a97f2,4c4c5206) +,S(fd9d0c61,d3dc3ff9,bc3735e2,b2c7d5d6,4a740b1a,bcd46a7a,860816f9,84a64645,701e082a,5e59460e,c3e3ca21,40137ed1,5bf9ef49,fb4673c7,4fa5e4ff,2ad8b762) +,S(82ce7d44,87101716,6ee31310,11bdf02b,336fe44c,88572c37,930a33ff,5bdcea1c,d7fdb097,3961ba18,b53b421b,21c0424b,7b4807ae,256d883e,2e3a6f22,9bc44c0b) +,S(5e507c80,bbd32e0b,efc31714,b464580e,f7ccd3a5,2004f2f1,9fb9b0f6,dad1a767,95facec8,a3b5c996,e0bc9d5f,77c11407,d0ee071b,9cf5af3d,ed625025,3aecc75b) +,S(640d6b4e,bde998b4,1bc86fbe,2e981683,a83789d,b71bca76,76715a29,143c9b55,61334a92,358ae235,104aca00,a632006b,769475a,da8789f4,f7047f75,c8b1123d) +,S(e951dbb6,96ceb16b,6059c3ec,9d84ae8b,8adb146f,fd79a323,59c04677,aff990e,d3443900,ea47be0e,10ea9178,3f1524f2,fe5c5720,efb62458,987dea0f,1612a94e) +,S(2b601b8a,550333aa,2a0e98c9,a4b28043,aa38f20b,13a72cb8,7a8cf212,cd0a2a92,2f3f309d,ff296fbb,a406602b,be72d9bb,c3ca0578,f5f0aa08,6e65ec0d,8989f670) +,S(d803b242,9814658d,df7cb378,bb9708ed,6ddd7270,ffb7d712,b64da007,158a5add,bffd353d,c4d664f8,6d7f150f,30e44ace,fef4abe3,83f30369,15b4d5d6,5ba3c131) +,S(d5a8348d,fbb9f9d5,798d7d1f,3515e25d,a2707869,26ae598d,500186d8,a284e86d,ce31c62,19960c61,f2a8a7bd,2fa36f0d,6ea7838,5463a4a2,9dc1ee95,2f37905) +,S(250dd67,781128de,65f0529a,11b2405b,eab01ee0,1e9bde06,cabcc9d3,cd038065,524aa9b5,8dc5c6e0,6951aa70,c4bfdffe,a2dae26c,1e8341a,5f63a180,731a0dcb) +,S(f3a2017,127dab2a,917dfaba,5eabb6da,bebe554,431e796f,a3b09771,66cd47ec,69d1de46,2e63beeb,1334fccd,ce147b96,23683942,21c4865c,d50fd687,5c1659c1) +,S(15626140,5aabf9f9,d7dfd218,3d7fe2c,900ee051,784537b8,deab8bcf,20c6e0e,863d8797,f2b20b0d,ca1a5b93,9a43a712,4d5f0725,8ae7caba,4b76d308,65f9a98b) +,S(3261fb49,2c55978b,20d2c5b2,3e6ac5d9,5e3b40a9,462b748c,62a41035,2efd227a,4072fb7e,3fafe456,8f62f4c9,83d0988f,f9096c14,317f7584,9fc1aed1,3e39708) +,S(2a5e6aaa,f5cd7466,b851802b,80305dff,3e655dd9,b0456bfc,fe704eb8,582836ac,2e3894d5,762e70d0,4d3595f8,83dbec7d,5125720,c516fcd,f361ab22,be67062d) +,S(e85a7e08,13294e2a,6eebb00d,2e3fdd76,318b7520,dc682705,8b3e923d,536cbcd7,5a936569,77b89e9f,10c4ba6b,7dcb1611,fb6a85fd,af0b1136,b19cf222,a2e9a477) +,S(8e36e66d,2f080ff2,a24ac836,25e50148,e5017b7d,b898820c,b7d73214,bc198b28,edf99b43,c2b976b1,6eda2a75,f8bf5aa8,6945d700,9965b528,bb78b530,3888c56d) +,S(99ead62e,11cc613f,2290332b,9d5ddb98,8c121ed5,21a0147,589bbfe7,db0f0c58,6e73b10d,bac646ab,44f3a062,4150da41,d666523f,ed55fdc1,c1146fd8,c4a262a7) +,S(15e233c4,783fced,39c74cb4,34e77491,83004e2,6e16c372,f6f7f23a,e30efb13,c9954660,eedf09c3,af8e1642,3b57af59,227ee5fc,e1885837,5ac5a853,34fc5034) +,S(3b33e0a1,254d310d,efbf526a,8a2314bf,18bb490f,e592e36f,6763b174,96f57a67,e4e6a395,a6e6c730,67fb2e0e,2c5dba63,9745daf8,bb9d6aab,e96f59d0,8eb24c83) +,S(8be3fe6,f3e45fda,270d54e6,49bdfa8c,1dbbecf6,35922aca,2d605c66,6933e859,10269847,15eddf7f,b7b23972,ed1f6fd6,882481f9,1a12eed7,f8fabad9,da0917c5) +,S(ae6863ae,e6d519be,773edc77,8e7bb5a7,5e0d30ca,91dd0920,aee35870,5bf6effc,d104a8c4,1939444a,1a5843e3,92fc5fa8,d2dd864c,1f442938,9dbdb543,415988b3) +,S(58a06c8c,658430fe,e03b3218,6ec051c1,18174f8b,ade2cfb4,a98cd9b8,13e12dc,17f4ba3,da575c84,81cdfc04,25567dd5,1d2b5e94,a8ed37cb,346f88fa,e6f3553c) +,S(cf0b0d64,3843e10f,142ff912,720373e7,2fd18576,1f3d6c71,52647afc,1ebae367,8ed9b909,f4b622d8,cf5d5b19,fa2e1cc4,bdb42133,c4dd9261,22f1aef4,6dac4c64) +,S(8be41872,15902e71,8f75558e,4b1a5ba7,9d3522d2,e8a2d723,f863c4d7,3c4713a9,f7be5a77,6b8ea8ee,1e59765,ecc6a33d,210eadbf,df4c5586,aba43710,49c715f3) +,S(1e6bfed2,36a10a7d,9efd88cf,af1dc1f1,9649197f,785b4a30,c68391ce,808f713b,90200be1,29c5235f,41a79bc7,2d4d10a9,b00911cf,b9f27b5c,6d47eba9,8530b8c8) +,S(97176463,8cee344b,1ebd8c67,17782c6a,86108b76,e1eb74a0,791527dd,b18e14b5,ccb128c5,2295ca09,626ccd39,b5827ffc,3168a628,6633843e,96184aed,d7bf898a) +,S(2fd20134,8e0b7259,415cc828,c3e4f79b,2184735c,86e534dd,77f1c5b9,9d8cbacb,41fc80ab,25ca1a82,67582a89,f901ac61,2237b942,9d724a2b,8cd0dcb6,c96564b2) +,S(5ba918f6,6bdb4013,481bee06,6aaafa88,f741c362,b5c3a4b,28dd4555,3c1aadd2,230f6c20,f39849af,9de4ff99,8e39ebcd,818d5d6d,8056ca67,8f04f33a,c4fafac5) +,S(69b5676d,b8e2a30a,8870c86c,4a859ba0,dee25a28,493909f0,9ac88af6,83b70797,4831db1,98c1b4dc,69942571,e4908ac7,41ec4568,e27089a4,682ee7c9,8ee905d2) +,S(faab5a9a,c530f7a3,343c71a4,273935bc,fb280258,24a63ce,8f8da6e2,a60135ab,1443a23e,793eb339,f4353371,34937bbe,9bda0eb8,c2fa2d50,bcd85757,68c79797) +,S(c70ef20,284cf135,7c437093,10451a9e,5ef10cbf,e3a0ebfd,b90f487b,8ca62d9,8970b394,35c29dc2,b8254d1c,9c4cdf54,6df52979,ca70ff8a,7dc171b0,5a176ce5) +,S(acb67abb,fa6dfd52,e9829767,182f5ea5,66dfaeab,42a2f2d9,aaa545e1,2e9cc68e,4a097150,2367b1eb,4f51f6c,a394d351,b734b30f,fb36dba0,9e53b4ea,3f6ebfce) +,S(2da4ea09,315e0f1b,f5b6e0c5,b8af330c,c27e26ef,54affcdb,fda834bc,cd578a3,a4097d6,ad006cca,53ea3391,10c80150,f63694be,c5ea7728,f77ebb83,2362a407) +,S(70cb8427,c2d5ee86,59b26055,3499374,63e7a482,6731ab85,6b3fd10b,be3dfdf,f44efbf9,a914063,3e8378c2,6e9676b8,351b6ddb,33f7e7db,5ced5208,e4cb7361) +,S(b14283ed,9a9db980,b135557d,97190066,60e4e1cd,3ab288b8,dccba9b1,67b24934,95fccfb3,827332be,a813457f,28a63a89,87dc8c5,340a8f88,76788a60,f03b2606) +,S(ca24774c,727efbb1,15bbbf12,20e59841,891dfd50,9f99744d,de815f5f,3e959555,2519e414,a9703de5,60f7412d,8949f509,bacecf3a,e672e7ac,58c5f98e,33162bb2) +,S(5a5c1b07,ddc79f18,26bb95e1,13e03894,bb63b593,c808f0a4,2bd44b36,dcd3765,a11bc328,2f672c9e,60846826,521add7,57b891b5,d4fde6c9,738c6329,dabf67b4) +,S(2caf2545,1daf272a,b169a4e9,b0eb9c0d,26888c18,ae7d8357,b8dd2b73,ee4cf7dc,bf8d8ea3,afc9d56d,9799083,c79f1289,7d20d7ed,48ba38a1,acb039b1,2292a3c5) +,S(af6650e3,4022d1a1,b66e8c3a,b0a8e9f3,baf44318,f6946a0d,d1c65aa1,e3f9c9ce,1b0222c1,a5f3691a,248154bc,bc9e5e9c,6b2c96c1,ca468feb,97a7c01f,2551bd5) +,S(3653e476,4215cd7f,83ff59e2,f63f2a7f,dafb8795,95006bd0,182e0e,78ca5b39,c91824ee,6ba3c685,2eeb2695,9a3b136b,371c9bac,4141344c,a1eb3051,8a6d8ab9) +,S(7826902b,cdd4e7b5,463452e1,baf88534,64723588,86643d49,cc89b482,298f6394,dd5bf1b6,91647ce2,86c745eb,6246d087,35cba4f,22c26a37,e326ed1c,4e3d968b) +,S(da19c301,4e77f987,abb00fda,8a5dc50f,d2777850,1fafec84,2ce7e5f6,37edd1da,757fb28b,366104a8,cbd26981,3697d8c7,821c6e0e,5acbb33f,9cbd5fed,25cce98a) +,S(efa31697,2a61cf86,df713186,c1bc61f7,63a618a0,8034c26c,462a2457,907436a,74f17527,e6c7aebb,ed6b28c6,26e612bf,82d61ad,cd1ca156,b971abfe,2efb15b0) +,S(379d460d,12fc351,4c46567a,ce05cc9e,ded3cc35,fb416bfb,76d14f3b,c5164f7e,f548ad44,a5c87313,aeb52885,5ac3a955,178c8992,2415837d,d3e7863d,685004fe) +,S(e3b66f05,ed217cb1,6e3f8ce3,56704f70,36b97104,e39c5649,83bc204c,5b112de4,8a2ee4f3,ab9c8cd4,40afe707,d8dc0fed,473db9c1,be2b6e7,b14de905,ba38ae2c) +,S(b14ebf0c,ccda021d,8db1fd20,a4108c48,750d10a7,e0659cca,64f3e6e,ee8c7a4d,c94ca9d4,d2ba47e4,576aaaad,c15f9019,f335ebc5,763cf232,f56f215d,ce42322c) +,S(1ffb2e29,df24e7a7,6a71f607,f4f03608,43d3715f,c3e468b9,92b684bf,1352cee1,27c39636,54ab505,4b008e5b,4598d025,ade823c3,df6aa7c8,18d4d4fd,32442990) +,S(63e13d75,38f1eb8b,7276ee28,acd56bf0,448f026c,f98c77fd,5f743c24,4872b70,845d65c0,a6cd8b30,7c7ea0c9,8024773,86a50daa,3f361539,57cf995a,43705cc4) +,S(169b95d5,417e6173,b4393c6f,1ace153c,21c83c7c,971418f1,27e1abf3,aaa04673,bcd1ca4e,5618a183,420b34d2,52d25dfa,e7cf699,3e936450,ffaae3d4,61a50c50) +,S(3dde4fce,54d27794,29b6f6a5,8c5315ff,ed682bc4,5601c623,948faa88,2309ed27,2b22dfb2,dc46f625,4f29f8a1,4cb4496a,dcef6806,26d4f499,a17c4751,4a1802a7) +,S(6b37e3b0,2422eccb,299e2b89,1a150be9,ef56a628,62c78c11,f3411614,9fd37802,a9c347b1,fa5105c5,a27ed367,261a1cb5,5d54a071,7a2927ed,29d45eca,6e958295) +,S(7bd6703,ef78de4d,f32f0d7a,274f6371,2d0b0a9b,fafc3f6f,5c03b654,599b443a,33d9b1b6,8254d47d,6aabb7b0,b66298d,8447d674,4612a2b1,f722a597,857fda25) +,S(2e9a4aa0,a2062c8a,63b18e5f,91a609de,b60ae126,93d7f1fa,757057e9,ce169b61,65a55523,e34dd131,3597b250,acd11763,62df6b07,1d3f0f1b,907fe0bf,46ff87ca) +,S(f90c1316,9524f407,8c7328a7,126c48f4,eadd6d65,8baccd1f,403a0b68,ff95e7e1,1d6a1b16,6f5b4f7,9f51b046,42306f53,bd84b7df,2a58457a,a8869,4111cb38) +,S(a7bf0bfa,8e84b448,9ee29801,a5d06f66,a17d2374,a6d91eea,2482354d,66c60074,e60ec871,7ea63cc0,e4785455,478848c0,363f6717,748ee9f0,1c928370,df0905cf) +,S(dc4ac1a8,372c06fb,ea7a44cd,11a352e6,fd204df6,f6868cb,5230e420,9ab36e6b,f3a1b986,c86134c7,40c0ac9f,8f2780,82a103aa,e9e4269,84516e09,659f668f) +,S(538086b2,aba47aa4,dae137a4,4bc747ce,9bb225c0,6aa015db,e9478da5,e2c9cdb3,42ed59f0,fb831257,84b15d27,b9086eff,9aec4d8b,9ac36f87,10f93bbb,2ce7d971) +,S(92eaffc8,955f3f06,fca49a8b,881734e8,6750b34a,d253f160,183388af,f18b8106,fdb45519,36f9e291,9e2e2e6f,7e5d2dfe,16e14da8,b5704a27,60e92d9b,13758767) +,S(63fda46a,4350fdea,fba277c6,190c5f37,c4cf7c88,ab1b2ba5,7b0ce9ec,60249c46,b64fd169,403a2687,f5f41038,91e811f,6dbb344f,2c3a1492,fc408f74,433c65e) +,S(f9f7568f,d2e444a8,14b03934,72564798,5c16424c,1ea6fa80,79f96df2,ff3c73d2,8ae3a292,fbef875d,ca18fd89,8e1e882c,ef7bc222,64140183,1cc2d268,ae795a14) +,S(43a5ef22,93462849,ecbf95d,3c92eb63,ea89a39d,2e0a5da1,eb261c1f,2e8e4bdd,896699cd,e580ef97,64ef1860,19317dd,f7c17ccc,34d340dd,b23621fd,5e5ea5aa) +,S(1fc26dd2,9a3ad966,4206f233,82e54363,6ec9d95e,a58e7af8,a4bc8aa4,736c155d,5f6c4cd9,c6f954f3,f0f3bc54,8bfc4a58,faec99d5,9f3466c0,bcc09053,346bab63) +,S(9a63cdf2,84ee5189,34b73c8f,d8b3932a,50ff88f4,8ecf9b40,c0056c7e,168956b3,e52e7902,6a8d4e95,c7f473e3,84b9966e,16347c60,8b6fb6c8,484335c1,2872f4ad) +,S(aabebcd6,8050337b,1e6caa45,13d279cc,ddc4c218,f849afff,8c1302f7,6b728bb5,808fc6b3,90c2f001,bff1993,346a55b3,663378d6,e457c639,b9a73f87,78ee8d09) +,S(9fd45b70,59cd26ff,2188167,ecdb5ad7,62efbcf2,b668830b,475df22a,bf526239,6fa79fa0,e76536af,92eeace7,77c1b735,19092fd4,870ead71,35634768,700a1241) +,S(ebb3ab2d,e71844f5,b6ff8baf,637cc0f1,1004611a,e8a3b570,1afeebb,a7a4edd4,30eed3cb,55a23613,3bec9aec,b620f1fb,1f39a067,8a44622e,84b9e271,62294133) +,S(a0e7ea2e,33c6a3eb,423138d,8faa7ae1,d7802a73,507d48c1,bb38bcf9,29838ca,31158fe7,ad132036,62449ed9,76c4aa17,67382a8a,cd42c842,ed22badc,882d7d26) +,S(a19abdde,db579ade,1dba9264,9d58b15f,1bf3b87c,eae44520,2ae758ad,f2164fa0,508d24fe,f53d8f4c,77e43ef8,eabecf3a,ddd04eeb,acfbecc9,637b6c07,fbe88084) +,S(e86ea1ab,95e23d10,f086c91f,289e2f80,d10ea0bc,aa9d8f3,1873158d,19166976,4b6bc016,6d95e08a,72c4dac7,9eeb405f,938346d2,ae45ea0f,ab76ba98,8c4e910a) +,S(aad23857,d8d835f8,e3785020,6b1cf1f1,efd9c9b6,ea15d42c,70444ed8,81710ca1,a550855c,381bca50,44be47c1,42d52259,af2f486f,622699a6,aec28138,554cf06f) +,S(b5c04c3b,436fe2ac,97bf2043,3ba57e9b,897816bc,eb8383be,ab11d488,e231a138,b1ee4b56,1965ab9a,9fa87112,57a250a2,d7f06de,7759918d,85c69d66,5546a6c0) +,S(eccf5dee,9b6e3fe3,1e3c02da,a2d5c408,72766edc,29da88b0,cdb01f4f,524b0ad9,7770c7e5,d97ca3f8,cdda858f,ed5976f7,cf2bdcc6,60459a64,daa495e9,28f4cc37) +,S(4c34b06f,6d02467c,9e667ceb,630d9865,4540b18b,8832292a,17e74d9a,d0cabc6f,57671dd,326be6d0,2ada8789,b5f27c7,b052c8c7,d300b2b3,ef881a24,53bcb6eb) +,S(9493f9c3,98a50b50,4db602ed,ef50cfce,5bcc9f0a,bcf80ffd,d5f65d1b,d030ca31,fb45d7d3,fc1216ac,6b948369,42d33e82,932af020,fd7c29f0,f2959eef,a41dcb30) +,S(b0ca3c54,153d435,b9d6427a,20ac3456,ab980b67,ee92c6f7,605aa934,faee0bbc,2e2a47e6,8b959402,1ed83edb,d4968c6a,2eb4be8e,2cf128e3,a3778751,20f27b16) +,S(d5632117,2e9b97eb,4b282d8e,1e303cbc,d50656df,2a99c9fa,bad35909,1888ee8b,30157215,efad51b8,20c03f8,2e4c9c93,11d15bc8,3dc75bea,e44e1e52,7f1ced7) +,S(3a0f593b,69396a6f,62655efd,97c103db,5e209554,8d45de93,8963cbc0,dbb9b4b4,66ba5298,590d027b,30dcd9cc,e4605e4a,73adf43c,6e377bcc,cd19eb92,e20e267c) +,S(10eb3c4c,cccd5ca,e15bcc7b,92d108a6,de762cec,b71bd78e,1917752f,b3f6cf86,6d65809c,79395f45,153d7650,74597eb7,edff81bb,598ed20b,f9780e45,bd91d077) +,S(40ae7e81,e33791bd,154945a5,105be36f,57477fdd,d36f83f9,d31fb73c,862e70f9,71511daf,e9cde10a,7e4ff05b,948a0454,e5fcd355,d98b2bf5,8ed3ca54,1a568498) +,S(994dac9f,3c047519,823c007c,57851a8d,41be0480,7c6ba5bb,88e19869,261fd12f,913e96eb,bcef4fe7,60469aed,51e9dbd8,4910d606,9646255c,9cb3bb7d,55b1e342) +,S(f0d9a17d,112e91df,63c106a0,5df3cf41,6471b817,a3ede631,d845b604,3c04d0a5,3ab43cb6,cefaa228,5c84a42a,8f1f41b5,631bab61,1d006946,f06be576,bc817f18) +,S(20919d38,ef12de1a,64992396,f7b265e6,2ab8267c,bb988d1a,6771d8e,724d16e5,81f79a2d,b629ce97,47f146d6,b16cdfd7,90fccd71,c46cf9f7,fe526e58,8ed1eafd) +,S(b92087f7,43494d53,71978b1d,63e11ae8,a1595239,33b87a44,704ca3d5,30f1b02e,6eef6ac2,49a8550a,135072c2,9bb42afe,5d27c8f7,fec88aee,6274d27,36dc0eb) +,S(f69dedef,a8894583,c05b1fd1,ae205fba,3ba11a37,ca628150,d287f01b,b6920b34,a9f88097,66d18287,9d97e01,5544c7ab,ca0cf8fc,c5b9f305,ed0bd9e5,58fa5b3d) +,S(8bd8b3c9,a301a76,9f5607a3,e116edab,9d87bf79,e4099d62,a328c1c5,f8b8b6a2,167117ec,ce6e15da,47a076c7,afd851a0,cb5dd1c3,d8187f4a,9aa5abca,cc0af771) +,S(d7e2bc76,e2a87357,82611,2619513c,10a2eff8,857fe6fe,a2e2c00,c6f8ef4f,85e1891f,531481a5,e935e80c,448d8da7,32f1d061,dd234e39,d55c58ee,df8cb93b) +,S(2701bed3,778a857e,c7a9095e,6487e92c,555ecc9,32ad8e0f,b1b59d70,4131768c,9e38370a,8d30d5d6,6aac5302,efc7496b,cd5734a2,20d2e76e,fae3c72c,a793d991) +,S(3662a916,a05a80a9,13bfc287,c81cf28b,7295dd1f,aa52badf,5ea1c83f,e1b90521,b14bfdf0,a33c9286,eac83a4c,b982f5ae,82e2e134,99bcb3de,3ac930e,2ed0c931) +,S(d778d74e,317063ff,6556388e,2d2ac429,410337a,d62917,a94b7654,6a04787e,f7d92bac,c92600b4,e8184960,11f135fd,adef70da,b72c1bb,9da26bcf,7a81f0b7) +,S(7b05001e,388f9197,ff3504fd,402a5291,d1257621,c8eb202b,dba87b56,154b6f8c,8c9c1c9b,5c151be,39f2875d,b31797ba,2899047b,6e5c491a,56f7fd28,1b897f2f) +,S(603546d0,1fe46be0,eaa9f00f,c99b2a6f,c38fc225,6553bef4,9ff47442,ffa7626c,1f86de50,aa457ed,ea306251,91cc3cd5,61cbd8f3,2b41145f,139110f0,64b73b74) +,S(80f9318a,ca3b7aca,65cb1965,a36981d0,86ba3b32,8a95cfd2,9c6bb718,1f662c25,c195025d,794abeff,49c9b1f6,724f72ca,70b0bada,d06ae11f,2101b49d,d592ae18) +,S(61182e02,a877565b,1209dce1,bc84c62,f3b1007c,48332c56,6dd6e697,664cf64f,d21f9259,517656d1,3efe7166,750c341b,6c064b0,542bac29,28424a30,ce4b51cd) +,S(21cd4f22,ec3a190c,77073680,58562d82,36d463c,f7706f10,fbebd283,c19378ff,2e04af2b,155beea,daace708,c510555b,467727fd,145426bd,680d1964,fc1b03b) +,S(2d3f6c78,94479443,6004ac92,554a507c,5a20ffd6,f275f715,b176b3b5,3d2000b0,72e0e16f,9d9ceaa,2ffc5a1a,71a2cee0,eea64e44,7f716eec,1fc417be,ba16d92f) +,S(a9f45433,c040d1ac,6bd36d33,5b655fd8,eec0d3a0,bf1a622b,df422039,239de17b,264ed6a,8da4a169,a66869a0,a846229e,81d52517,22fa4c2a,4c775322,f33b1184) +,S(16e052be,bb65657c,309d67e5,b68ea441,4179ace2,38315c8f,df88626e,84281ce,91c007f,fcd4633e,597ee06e,b28296bf,2837f30,8cb21be5,9bdbd52c,4ae0422a) +,S(ff6d96b6,f633beea,1de80512,73c06bbe,181a1098,db737c8,41a48d44,cfab935a,cd9a8011,c22b643a,90f1d9c7,54b7330f,1c1970fe,5ac04225,c2720054,fa6a8444) +,S(dc2e3b1b,a2619ea0,6e4ddc09,99630c4a,7b94c78e,ed13517,25b8b8da,137fa467,f97e82ad,49bb4389,84cd752e,820aac43,bc6cccc3,f9b0d9eb,c2337bdd,89cb83c9) +,S(d53b97c5,8e23d50a,3b855c43,80a992c9,2d667afa,bba4b028,20031f58,dd6947c9,24a54f43,bb9a04c0,8b93aa96,9dc61f92,e705ab75,e644a3c4,40391af0,ad375ec7) +,S(b598a510,beb9cbc1,c4e03f8c,1ff610e0,7123ddc6,ad69dd6e,f9fa7810,f79c8ab3,b895b8f7,68a80a37,77d8b5bd,46754473,c9590768,a56fd586,58ce97a,366dcdbd) +,S(cc2296b9,ee9726c,17b0cc6c,745a038e,38b5535,5e19fc49,e89f4ec3,372b2a05,6a466fd2,f9a5c412,9f5b2faf,aaef4cf2,be71406,590ae031,d68c482c,86e3f89f) +,S(3e84c76e,254c858d,51cd4e74,72c22ec8,364ce28c,de81ddbf,b7b3093f,44acf9b3,ce8ae6f5,f56814dd,21186370,f70196d1,339c264b,c78a502e,bd57e771,b438c81c) +,S(976f67c8,c626f8de,9de43f8b,39585d7f,d4cb35c6,e4211b00,68669ca9,a973a3db,ae4f1f6d,25af4ccc,3eca4b2f,6cda0cad,dcc28f78,c8e881c4,eaca9131,2f0b057) +,S(b28bc958,aed50ba7,6d5293f9,7c419828,53bec43c,21ef0f96,9000fa47,49ee95e3,e7d4cc8f,f68182a2,15dee707,4df2c351,906d5527,c47e6414,54e97c1c,b57525b2) +,S(e54dd5d2,16bc5903,9a630bba,7cccf5e6,81a3113e,be8fb57f,83c51209,965cddb2,86352dbf,5f2b2327,ca50458,b3b2cdd1,8d403629,a2e2a776,5562240,7e8407db) +,S(58379e1a,10115a0,8f2b93a2,3f2f4e2,2787aaec,cf129910,b1911b43,c209f379,a526d32c,abd99175,e63b4493,7a0dc96e,e0feb99c,bbe00c91,1e606537,c871c6c2) +,S(7858a68a,cb34cfd3,e1cb7d06,4d233322,ceefa6a7,a2de391f,991b94b4,da9ebd63,f54490f5,ede73b49,946ffe19,d5ae6f7f,ca026c07,b1dc0138,b1409383,5d792db0) +,S(3c8c636e,d20d58c2,f03c26ac,bbbfed70,3fd13304,74bdf2ea,7526f16b,4fe6f7f7,550069d1,cec630e8,6d22af01,5981f20c,ffdfabdd,6416bb00,f2dd8c6a,44401759) +,S(d03fc7ec,eb716cbd,f033d76e,8db97314,858674db,48ede8dc,1a1c7dd0,82ae7f93,16f7a717,a197fede,dadc25b5,a20b0486,1cfaa63e,3157e5ce,ff0c81d5,bba296d) +,S(6d6c983e,d60601d4,ae5ef4ab,c73914c9,b9546964,a6a3d2a5,681b09cd,afee2c22,13f5af59,61877fb9,2a2ac09a,eb691a88,20ca8361,81359fa3,96558ad7,b2276b1b) +,S(92a9f5d2,149065eb,1241d82,fd06ac2e,f1f48003,3bffb06b,ae3a9d88,a1d05f8d,f0be5964,75545835,f64b0985,1baad682,b84d7a39,91ea0f49,1d19b7ad,77ad75d) +,S(222aac7d,c2fe0066,b766e1fd,179c1912,5f289e98,33cce93c,749afe38,ce0aa74a,bd6c4d8,43e5923,b5944e40,8d309733,dc0cd9c8,b266dd8c,2df162de,fde5bf5b) +,S(28b14628,3a7e1785,1c9d1831,6c9ca17e,56a13c25,7877ca3f,49ab2369,ba2898f1,292856f9,572ecc,5f000e0b,1e7ebdc2,3ec72619,3c97542e,8ccb10cf,d608eac7) +,S(5031a6da,df8d12ff,9eb19209,b844b008,dcc26de,c4a6f9f1,bbaa45c9,daf909a6,ef31dc6e,3cb5c39c,64011c0c,89cddb04,7ef9a881,a0d718b,5057bdfa,3f5e1ffa) +,S(925835ee,ce55e98f,130008fd,a6f01768,aee2de4a,f96f239a,430d408d,95a627c3,cac1b7d7,60362e24,f3b5f277,e370ba70,f0f8c6dc,a338c15c,46c5fb4d,f9f1bba7) +,S(6b7253e6,9dd65781,8214fa04,67f59e92,a4671648,c465ea4,9c993bf3,de8d9e77,50a9cbd6,b429c3d7,32bc3b68,ec581327,1c2b0a4d,2d8587bc,7b26ee15,ee7e92bd) +,S(f82d660d,cd5df408,714213aa,a7406a3c,868a8d05,1fe37689,baa6fbc3,effb3e33,affe0a1a,b7bf498c,83b331fa,f3e7b723,2a2dbc66,3b93da28,e12f0d56,260677a1) +,S(990954a5,5342c5a8,db3fef46,da2b31ba,32b6d597,c67c8290,9329a90,c39845fc,d764f091,40891e20,a2130696,216049d0,b3eb1af5,7dcb9797,4c42abc,5298977b) +,S(d6b8e341,f8bad7e6,ff434dce,fcae81a4,1946f237,e0467120,fd420,f3dafc0b,a8ba941e,81677d32,140666f3,55fc28fa,7233ec8f,8fd13703,214bdf8f,340c389d) +,S(fabf5120,8632ee4c,81ad6d34,cc84de68,728197b0,fcf07971,326d4c04,7017b905,79c781e4,aa7dedda,4663b8db,7fff3cad,f9752cf7,ef2382e4,b0254489,7c6c04b2) +,S(e62db266,d9b208b1,83016754,c871a8d7,4b6848de,e496ee7,e2c1447c,2029b0d5,ef7410f4,f44d7414,53b9c1c6,8e5689bf,37cfecf2,1602e95f,3fe053dd,aea24f77) +,S(4bd90928,14753ea0,1025ea2b,86ae2310,5b581b48,98359481,d1b7d36e,d9c6e478,2f12e4b7,b825c858,5362afc0,d0029880,45fd638d,65f1865c,6ffb31ce,424baa50) +,S(3e397cfb,cc5c9fa1,15519366,c6e814ec,4b0ed9a5,dd093321,219e4028,28126ed,31c352e4,d4bef7cd,8929d3f0,aeecf9b,1d577ef0,e8086a28,40d46966,c1165dd) +,S(24bee951,54baf31c,f5322941,ffc01fda,9e89f80f,2662f5b4,edb751b6,5b372ee8,9568a4f3,a34ce5c9,8f591550,b75f2a84,be5cf67f,1fd7713c,c126f46e,1c3b6883) +,S(d242bb09,e4c6cc42,a2bdcdc6,bad2a02,8e4bfa21,430acb16,3f0e8a70,2ad2f0d7,2eede9ec,799b9e5a,13c40c4e,4cf6dc0f,9640d472,2a78cc6c,d920b610,d070b913) +,S(a57b5fd8,f50de3c5,98073cef,bc6fa56d,20dbacc0,72dbbf81,347bf0e8,7a36ebef,a99f123f,a45b1369,32394f8c,1f7ea2b3,563ca2ba,9c0da00d,b2c9c119,e6f20287) +,S(82a43e2c,a533abf0,6aab1199,fdd20f9e,1616a79b,859c6467,ffca4b27,989da9e,19cd40f5,8c997e78,311e5ba0,c0b3328a,b845da97,91dc8ef,a6cf7e5d,efd51c6a) +,S(95bf3b4d,b8ef8bab,16e00f5e,7dbe9907,b54c98f9,2331c4fe,688129a5,5cd021c9,2b4c46e5,b9d9f915,d5d020a3,3c63fe49,eeb32931,9373bf9b,e359c40a,19328c47) +,S(791ea768,4d333125,893356ed,dd8ebe4b,3f98ae58,e25a2d1,67006a4b,5c05799,5f72cf68,7827ce2,6bebd598,539f6519,a50788c,9d093766,9c3b9c29,f52d5422) +,S(85138ec5,a5d3f0a7,881ce23f,e34fbb80,fc3038e,bb7c2a24,ccfeb2ae,5ef07b74,8eb9e80d,8664b11b,d24753f2,bba612bf,c06bf9f2,a4bd061e,82ce9037,895b084d) +,S(3b4c1149,1d98483,9ff33b31,39da0341,f430175a,d5800c80,37e35dfc,a68ec256,574d6475,e225aeea,dace647a,1489b2ea,873175ea,83cff3f2,fec684b3,fd2ad143) +,S(2ea17f9c,6a028f58,396474bc,8c51b1e3,cb9ac0c6,7f73f533,a428281d,4101b04a,19d1f021,8b8cc0c1,bbfb8925,77087caf,ebed3409,69dc2281,3a1dd6eb,9d6c44a8) +,S(67839592,2fcc7ffb,627486db,e1d98a45,25ee1338,5a98c01d,6b3b9f8d,f64c507a,e13ed82a,a1adf761,7cce3760,d049a72c,7572508a,5ecd0615,1bbb589f,17e10a7a) +,S(54a0d2ed,39778fc1,237ab423,1e4384e6,4156c1a7,d5e999fb,2c92ba42,ef40ee68,3d879ff8,c25ed54d,df848e5c,49e3eeda,e8eccf33,afcb1c1f,67440810,8b3e979f) +,S(263ff1ed,726d0ff3,8b47b398,c713455a,3030d499,3a77ffac,b9cde4a2,cd12f7f3,a5f3fb33,c739bc93,c442508b,ac70884f,d90c3699,34fd698d,bc27f7b0,ca48a0ac) +,S(43b2fae4,a431beba,598b3ccf,caa1e034,91e7099f,c19508fb,8e693de6,dac9e3ac,3e43aac3,379c321a,5313b412,7cd00a1,bd8cd177,49c4240e,7cef1e97,22daf69c) +,S(a73e77a8,5733a296,2da7fe71,f4c16166,cf0acdc8,2d5288e1,8cb9479a,2a31f362,12b393ee,e323fd52,e44a9ab4,3e19256a,f7a8c892,76e9e6c,9052f0c5,3ecbc031) +,S(f007a9f2,bd3d0d4a,8cb9524e,a5aae499,6b2d0c1a,19aaa56d,4038a21c,6dabdd86,517a6a7b,3b75b68,bb04bdbd,d6f93414,c97b4b75,47b8fe22,c5828d6,7e979702) +,S(bc64853f,111371d0,8381c082,c72d2528,823e18b9,99de4303,c85a5fb8,87250833,51e7dc7,23256176,62a9f6f2,70bde4c7,94020e61,9e8dd87f,3f266d99,71596146) +,S(144dc699,a063c473,4b9bfd22,845317da,c4b55e92,a232b92f,965967b9,9c8e21df,a20a7982,7d57de38,85e573d1,6d22025b,648b9ed4,c656c48,bd6f4902,2b67c681) +,S(834ed659,98d49650,c3f525a1,b34ec725,89d167f7,a3cc6e86,8e4cdce3,b2ba3179,6bc2b06,c97a108b,2abf4033,152065f5,24c1bf1a,e79adbd,b7eeec17,9e598cbd) +,S(efce9278,6052c989,adc9595d,cd1500c9,8e93eaa,dafe2b87,2011bf55,3488b1a6,48ca33d4,cc89b486,c0930829,91f23147,d910f29c,c9d13787,7bebf55e,a3dc92ab) +,S(5b150240,c3563354,39adc9fd,23e9f94c,369a6cf9,27f45bc0,f0110cc1,b7321f4c,629b62e3,1a85fb44,b448c7e8,e76ec423,b059c9a,c8144c64,9d77a4da,eb044aa0) +,S(cec8cb02,3f166bd6,9fe04f66,8ef6e949,f4e3d26b,d748c30f,53a9b9f0,9ef3f9dd,997f9fdf,dee5cd89,352e6c38,760c4cd0,a7bb2696,94916567,ae60fc5f,39b908ca) +,S(58427cc8,edc5e616,3726519c,7522980c,30443eef,7e72cdbf,b135ede1,f15c0890,d2fe9c00,7eeb0be0,8295e972,e69db2e6,a54193d3,ec9a3ea9,f2515e59,6e34e88) +,S(a7d0a30c,1787b9f5,8ebff502,e4e38000,6bf896a,2feaefa4,4670dee,6030bee1,774eabaa,863fd4f1,63b3a16e,4c17078a,fd0a1761,b39ab05c,3c6b1d36,5e487592) +,S(9d70eeed,55ed86a1,ba17e817,4c400cb8,ab0e5da7,b568ca81,60b585df,d1a84e74,f4c1fde7,f11b329e,f3c3e196,bd78a3ce,5387662b,859f99c7,d61f7962,2d01b5f2) +,S(e0715fee,9639817b,8501de6d,6561e623,628de7ff,d0dbab5f,bf58ee4b,a365f684,e34ba5d,acb60318,c6ccc001,871800cd,98ba2c5d,529a42a2,fd145336,7b10c22c) +,S(594612b2,4cb1912f,fb945465,1036bfb2,79be0bbd,e718ca26,973552b6,93d20143,d68338a0,d03fd0c5,e6c6e3dc,7070c78,72eef1c8,cc2154db,cbdad699,b594b142) +,S(f4f41087,1dbd5394,5fde2583,b08ba65c,6729dc05,b32ec3ac,c8aadb72,a6c0d8,8e948ba3,853102b2,99f2f558,ffc66181,310bc676,4b82dd7e,85fd075d,70d92fbb) +,S(efca7b38,69f2981c,406cfa40,2bbdd00f,15ba56cf,c6e9f66,9bdfa14e,aa9b1d21,458fd928,a07fa32f,d6a0ffd6,64a16b21,2bdad00f,a4534093,209b0c92,f507f9b9) +,S(25b2384e,d9e09e70,8098971f,153ada48,f3f4a9ae,fb946225,77d213c1,e7b326cd,ef50fa0b,4cd30cdf,2667bb4f,7dff0287,df666dfe,7d5bdb9c,ab567af4,b77c7535) +,S(ed12b20f,aa2ac5de,db62c17,2bc67cdc,f0534a33,6a32e26d,b325321b,81901268,9245a6b1,35df02d9,3db1224b,1a0a296b,a39f07ac,ce7ccee8,eda552b9,748eca9a) +,S(5dfa472b,b84ada50,da3ede14,8bca4f0d,aa885d2c,61633336,b2a8a37c,76b200b0,f314a5d8,2d20fd30,ee237487,7a922a54,f4c10468,656a5432,974cc3db,c2c7fbb7) +,S(a9e5c0d6,5b6d4b4d,b242d87f,57c805a0,5b7f243a,515c5d34,a037ddc6,afcc4470,d90fa599,de5fc8d9,87a42c57,f3bf9dac,d5b766a,fdfa07db,4c56c0d,3d71324f) +,S(4e9ccc2,c0e3169e,e25a6701,a82e7f02,2663d3cf,585100c8,2c6b5da4,d8c42e8c,854aa160,d48d241d,f5bdd1da,2c74d1f9,a00fad7,effa29fa,5ecedc42,3ba43484) +,S(2122c569,da05f145,48d42f9c,5ce3a96b,bbcb49fd,fc5b2dbe,1a7ab0ea,84aec76d,40796418,39879018,93bac618,8a7286a8,f8745709,58a40cd6,1202ac,dba5867b) +,S(aa8cceb3,415df249,b5069899,75a853fd,eb409729,331b1807,ca2242e2,a75c6968,5362b581,fb676eb9,9f125fd,5f674be4,800d89f0,133a1363,f1cb30ec,1fa5b468) +,S(beaea0f0,1fd8e442,50648032,530e41cd,7e3c8271,f4b83b4f,7493039b,b21013aa,e21f7d1,53e5d411,794fb472,47897cc6,a86396f6,3f6291bb,fe2f0f12,a263873f) +,S(8eaa225e,63bb92b9,666bb318,22c166e0,3843ff47,482cec9a,69ff584e,d1a750a6,aa26b32,e69c5d94,19663e05,6c9f7a60,1274aec8,a839ff1b,b5a43c2e,136ffd64) +,S(bcba926,40d8b4cf,8d73c0e3,7867f5dd,81eef91,70e904e0,15f05f3e,1bf6591c,8913cf87,e33aae4c,a16b1391,75d60106,ac7d05f4,a8f10db2,b0569a6d,ec121260) +,S(2d03aaf,6828d0c5,9ffadaa7,5d1b7e95,b3c4a547,46faa5c7,c428fe45,1a9f3332,68468e2d,597e7534,37b3865b,3c968e4f,e3f6b1fa,996e6b4d,296a12c3,20e61cf2) +,S(b39b4de5,be757b36,b1e88773,47cdaebf,11f8d6b8,ab59d780,fbaf2263,a823b5b9,1b609d2,de73faa,d613c4dc,6ac3c2e0,33d62b22,7ca3fcfe,4aca992f,eef90b0e) +,S(eabf705f,b6996148,170b23,9fb8998e,df6214a2,cac27fe2,9c66a899,63d2f0f0,e1867fd2,98603f79,d17876f4,7aea4437,cb39ee7c,bdafbf0c,5452b024,86182d17) +,S(a4ce885a,ebe9335c,6ef43c6f,395e1644,201f578a,4caa7f74,65c12542,27f1bc80,bde32eef,f7fdc498,1c50942c,efb38cf3,c3f1a8a7,5addfe7c,f11723e,f57d0c41) +,S(db8ee69,b0e00ff7,6a094251,a53c61f2,e00dc65e,a11e00e5,553ae121,ea958361,24e7ba71,22742e09,728108ac,59c5f46,aba40d1d,c308edd2,9d494f39,d156b2d) +,S(88a5b43a,d6cdc2b5,aa3d58db,9a9a2e1a,6d70afa,808efa87,1d7f3cbc,509cf064,88483c55,e5bc8717,8114605c,1febc726,e14345d4,4211b670,6b6185d8,ea6b7103) +,S(e3cb24cd,2130716f,10a4d432,d4e59229,2e11a2f5,3190bffd,4f478da2,216b0051,df432db5,caabb417,f8252d37,dd23e117,38066c87,101cd934,73a2883a,1b7e8de0) +,S(d9c88471,97f04254,731794ec,e29ba74,f1d72f19,8f424beb,8309e1ad,e09e1301,12037266,331f04b6,db4264df,ae6d934e,5f753828,35a646f5,cfa4ae8b,e6defdc1) +,S(80bb740c,3510574d,10afa586,a6e541fe,b5368797,231d2a63,67d2890,8877dc58,24ff9389,bb268f42,b04f1702,f7b7c6c1,7194c7bc,c5f4f63,bbcd4ca8,ef476fca) +,S(4b8b08fc,400d6fae,da05cb19,65c9c785,8f93452e,d1be8f29,28c83e6b,4d2b06a1,70a6612,2549ec2f,6cde4a4a,9ae8a528,1b05081f,8eefa8cc,1111271a,1beea7ae) +,S(d2708078,4d19552b,13ec8473,1eafd2fb,bc0ae927,dd746a8c,be1dfced,d072ddc8,9362bac1,806dfc84,e736758f,22f1039d,57a5e44c,40586195,885abb78,f75d3355) +,S(7345d1a2,7b9dc922,f51a0466,57721451,cea5b54f,6673a484,7a210b4c,339d1f18,293053e8,c180ee0e,d81bc4fd,658fcd5b,99bad329,9e62aedb,74867df2,3ac12d98) +,S(3b3a6baf,b9003f37,ca27889b,a2be2a02,748ba52f,6c6dc719,afcacf2d,578b1e24,a9749973,c49ebecc,501f9b18,83056505,6c88c286,2747496b,951892c6,8a61ffcb) +,S(b2d1a3e9,15b02709,1abb5ba7,206ad2c,5d07079f,8d4c7fae,3e6837be,34159226,90007202,78d4188e,b8efc45e,8306ab47,be1c6a16,d88284dd,fb627b1d,92959898) +,S(298019e5,5de972ae,fd0b4c94,9a9d4eb,46689fa0,9b849947,bbe27805,4a3f4a5d,5b7a4298,be50ee99,363b5f9a,1ef103fe,4fec0034,fd8a2364,5cc76f8,ff804f0) +,S(604f1e62,7f503661,5b55fe74,4540df91,67fe575,e0aafe13,8af68214,f1080eb0,2ade0355,b373ddce,2353669e,6af5575,cc6b01ae,58b2a581,2b63f36b,58effd5d) +,S(ddcbadcf,63ffbfce,326db7e9,2df0d483,9a35df32,fc576070,9f2422f2,6e07b8be,7a3bf369,dc3a5ae0,c91cea62,1429ad45,76f7110,b654a1f0,edda9b57,3076306e) +,S(160a19ff,10c8b334,7683b21a,880226da,81d536de,d9dcd357,d4f2283,18853837,91dd522c,f6d1d276,e88287a5,a37afefc,ba010111,82b93eee,1483cf56,e6cf5218) +,S(bc1210ff,d75737ab,51300e3e,ea48a264,5f363793,1f4c6f95,e8507034,84834819,8acc70b,363e52ee,779e6342,ea7dcb7c,d7d09946,5b0eec60,e35ea360,e8baa7f4) +,S(c2da24ff,f2c5419c,3d2ab241,e55cbfff,5f41b9ae,4efaa105,abcc173,a81fa1ec,3fed4d9a,4eabf3bf,6b913bd9,279761f1,4aa630c,e278d0d8,4bc82ac7,af77481) +,S(73a495ab,b26d4be1,bd99935f,f5583f6c,f5c86d79,fc86a4ed,48f87f40,2f12259b,f4126c3b,3e9b8dc7,ead63ddb,5749fe5e,6cb0bb3e,3c85426b,950326ef,9092301a) +,S(599baa65,fdf949f0,f54c44bd,ff605ef6,2f53d68a,f0e44bf8,274f0b73,ce251227,297ec5da,e3893363,617f5448,b13237a1,91fb5a20,e52ee897,a124daff,9f1eaa9c) +,S(9a032a50,6786e1fb,bd9ecd25,243ea67d,57f9e4bf,d1083879,e309690c,fb07f253,a073c6cd,15445d6d,80c51af2,4e7f540d,f1b75fa0,89a4849a,ea14ea09,ededdb0a) +,S(792160b3,eda1d493,48ea96d6,857d8631,ed1e198c,c7f185d6,b9d2c75,2b1cae63,d12d76d8,bd73a681,9bc581e,cdb84efa,dd143704,5554984f,8f1132c5,fe1bc32f) +,S(8fc4cc45,9639aec0,2c337f16,589c09a7,e787dffb,69ba2907,37b6c465,db9f12d8,b2ce3c2,57ccb79a,b677a9d8,49ce1833,2a97fca7,28bf3e83,6dbefd23,5343571a) +,S(fc06a9a,5857b2e6,df0c3be8,b5840946,ca77f690,4ba114be,44e760e,267eeda5,6662078e,f0de0e94,5a770654,b8281a74,f82168c4,49455250,136dadf6,87c5bd2a) +,S(345da4f,e1e89eb,eb27b353,4352c5a8,32d3c9ee,456c01e4,657c2885,733b5f69,3db274c6,b89e7400,cec4e2a9,9995ece7,be8b98da,39a2fa48,bbec96a4,5c758be0) +,S(309850db,36d8c2b4,610cf8f3,e1c12431,3931aebe,1a9d2099,cb3bc7b6,fbd8b0d8,edb3a9bc,f6417672,af9b1379,9bd8aab2,f953391b,27cdf167,320005d2,3fb3e4d1) +,S(8a35d7fd,8c7c75f4,e22ba36d,d84533cb,f314a54a,2e17a43f,d250c941,5025b0aa,97ae015f,fe364a2b,6c12cc42,fe526eea,7250092f,79c40b94,ab7102c6,fde1fa5a) +,S(982d9d66,dbe6b738,2cf2820f,c72ed491,d6a61add,f1eff091,de30fcb4,96ca4161,b4a7b42,2e9cd74b,10cde7a8,12b4d88,f3621324,acdcc911,b39d0952,3cb3b501) +,S(1396bea9,57d47670,735ed20d,e2ecaf6b,afe7e067,5f2a0f65,6b3e719f,573cd1a2,cd77e7d5,a49d6cac,5e7871c4,58df45d8,821d77e,f3ad3db3,56989c1c,700cf484) +,S(6857993,76774ed8,a08da47a,9323241,71d09fdc,964893d2,aa5e783c,b8030057,640c986e,befd426,8fbfb131,8133ca77,879ced3b,56ec251d,12d0a650,28bc9d3e) +,S(801865ee,fecd50cf,4970e6ba,efeed453,769b3e14,c103db6b,2632e241,2405fb6c,b3d3f23c,8f75e475,8784016e,6ce1b91,8db76599,8c7c1aaf,af047282,ebd7a636) +,S(f09220f7,27e57fd3,209eac13,1ed93f96,142c400d,b9bd708c,9e716686,20f1793f,8280375b,1b2f4915,cb82a72c,43c9fc6c,f3a7de5c,32762b69,43187a8f,13510eb) +,S(1c814b69,6104f8e6,5a51b98c,e6b0c4f9,f26b5633,8ce24ee2,24a5aef2,967ab705,1cc2bbfc,61828277,90502c11,bcaa1f1c,b5e34891,a7c669f4,dbbb604b,df2e3135) +,S(22fff436,de961dd2,a7ef38c2,f588aade,320d0721,55e6a42a,3201bc6b,c7d24a54,6f13476a,f48f9197,3845af18,ce68ba91,77a0d4f,a835acce,76814c81,f6aaef5a) +,S(39da98ed,a85b2de3,c9bba6d4,1af633d5,5a392dac,b1d4fb9b,654fde5,a3343a65,29b89534,35045e6f,2ca41bfc,9e5c9ad2,55eee426,95f41744,b239659d,460fbdaf) +,S(6fb84bb6,3be24203,6e067346,1a5c1fbf,7d89a0b0,c98ad2e2,25cc3ba2,191fbdc8,21a37f8f,e4f821bb,3886333,c554d6ea,cb8924f2,bfdd7ebb,339a8a92,ec9bf8a4) +,S(29080a3b,7c1d33e1,13b70c4c,8388fd4f,59118a86,c4bf697d,25346368,8f60766b,745ea31c,e9731f68,89aaf5d8,1e7f686f,b345c9d7,3af728c6,7ac2b8d7,60ffecc9) +,S(a54f7e6b,aaf05de6,77e7d98c,5385d9e9,57f68d2a,8e3c24bc,11b6435f,50cfd955,f7d61099,22ff9c98,ee79998a,597dac10,be885d5a,e7b53158,fb671e38,470b5c69) +,S(7472bc8d,c109d56d,a5f150c0,bc41edce,7e378335,15e17267,62f50cce,e8845b2e,3c59290,820b997d,3c9109ac,7319048d,e37c5280,88e671fe,9cd85487,f03917fe) +,S(6f4cbc32,ff1805da,6cf83c64,b0d0eefc,6bae76d0,586de80f,df2317b0,a4e68267,29e492e5,89bf6c68,17731a29,76577124,c9bc9e32,1856bba8,8a060bf1,6a6c9d9a) +,S(1a93eff,b60cb865,8538cb27,d8c12490,483e6886,16320327,e2689591,c5413a12,d96609d9,251ea2b8,f150664f,efe6bf6f,a0634cda,b8846cc6,5f6c8a8e,97697c9a) +,S(79b82e7b,bb23efda,cd79c0f0,87f2d0d0,e2d3db59,97696c73,e6e94ea,8cb72027,bf16f23,47e594ec,fd087189,48d531e9,8306b173,88546493,d620218,b25e3758) +,S(a806c902,28fbc405,ef56057a,aee9993,ef177261,74d456fd,818126f2,5d93f986,fc49c640,7d9d26f2,f043a1b8,8a41bbc1,3ced6a93,bd669ddf,3186dab2,9eb7c5b7) +,S(227d9094,69eab478,9da2fe7b,3cb618d8,d781e0a6,54892f86,92eccce2,f41e9a1,81cbb45e,adfe3fc1,de5975cc,f87f0a44,e9f106d7,19cfe796,f33b5c60,85de7691) +,S(14f8dba6,4bb5aba,f7f58e8,1c9b0425,2c357f3f,fa8aeee9,fa4ac700,8c49e060,26b19dbc,52b913f3,b6aafb31,3de99445,b49d64ef,2503d28b,bf2f9e2f,4614609c) +,S(f22646cd,553c5008,aa3c4cf9,f01a05e9,20cee021,4e9b0553,38a75c1f,23e5fe4e,52cdb77b,7502794,ac16003e,2f4e859d,ec3e68d8,c84a3365,a307ac80,53d3089e) +,S(515de841,814df2fc,7cd43689,8780686e,f3bdbfff,83eed568,af19c75b,5ee93a2a,7395bd22,705a81a3,d62f3130,ad416db9,268961c7,facf81a4,44d2ed8f,e4df1282) +,S(59f4aed0,38f07bd7,b2aa6600,ca6f15f2,d396310f,e4ffe212,4e6a89e7,3c7c4ed3,47a048be,5d6e45c2,4fa69329,86b86edb,b990eae2,f5dc6524,3eadc69f,43b2ed3a) +,S(7492492a,d7f94293,4287c7e2,5f05203c,4c70b8f5,80d23b4d,4822d1ce,fa3450a1,19523158,2fa06da5,eb5368b0,f0b19971,1a1bdba7,50d1c6ab,80ca1b4a,d649eed6) +,S(2e12d13d,464de937,372a69be,b90dac92,78977cd0,e7b954d9,30360d6e,a51cc3af,35a900c5,6c7cf352,8c4a5af1,56dbebaf,32d2a128,8a58e3a2,ddbcb539,bc3e3505) +,S(ce4c4b4f,a52f06d1,11dce52c,402395e2,a6ffd186,dd8275b7,bd43e941,9f4699d7,957b994d,c5bcd5e0,179a67e7,94a40ac5,cfc074da,6d23d178,969fd8b9,2d9dc455) +,S(c51f1cac,5814de82,f4bd5d2f,a8e4950c,38fe78bb,8d09bc5b,628ec13c,e3084592,721122a2,f63289c1,f8925ce,34d810a4,be52f7bc,9bfea232,47617f95,8db1cc95) +,S(9fbaba14,8293f578,46c717c8,718a3a9b,9dc5df98,63ae10e8,9c3649a3,e26128b1,4917061f,ad964c4c,5d79780,7914b2f4,b6c3e730,3bd440b7,bc00f15d,bed2b497) +,S(a4a9ed86,ed3a1dce,5423c1e,1bb5fb9d,fbc1ed41,66a4219e,bd343922,8542ea9d,fcf6821e,46386764,c61eec0,19b1a84f,6a8851d,89be0da7,9d2768af,6eba9d89) +,S(a6fa3567,9a732aa7,b58582b1,5f3e95d1,f702ab16,5249e9e7,89a5a395,3858d1eb,3bd67e4e,c0dae02c,43d32cfb,d25a4b2a,75898bad,eb2986b5,6cf61825,ed2830ab) +,S(3b3992be,8f7e1b1b,4d8f5710,6feb825d,568b176d,af0e41f5,9c2fd59f,f67d9b7b,ddf2751,ac17a413,2ffc5c08,3e8c7728,a74b0063,377228bb,a60cdb87,1b5db297) +,S(e9ccb20a,8a279cef,2a15de57,e34f510a,f60ce397,3fa2ec2c,4558f166,7ad20201,b70a11bd,1b5414de,1b30035b,3dcd1dbf,17558bad,368c78c9,d5d9136,6592fa53) +,S(98083dcb,1356be80,b324aa95,e38217f7,c437f421,5a7f3e98,ba803fd8,5cc04445,bc0d9ebf,ade6c640,d16b82b6,5328a2,d5ef2f8b,52aeadca,e406ae25,e9b756a1) +,S(6a0f3b01,9e3b2a9d,453cc36d,275fae6a,b94aa14e,e0b4103d,137b1741,8b446ba3,ef30c9f8,46c54902,c10a4ee6,c5013b25,709e7109,fc004b6,e291b1bb,a021facb) +,S(83a62b60,6a1c4d03,1a18473c,f2230088,1d767332,9513b7a9,4f402f18,3dd45640,b23888d9,98bb9c00,ea57c9b9,517080de,95e6491d,cba0d7a5,729ab99b,12a1246) +,S(d2781bf,4b059449,75da8b83,cf82b43d,b5ee89fc,168186bf,74f22321,30678492,76fe1955,18e00974,6af44fb3,6e623f4b,fd0ae8b6,474e91c3,3ec364a3,91049d49) +,S(e4445252,dc6acf3c,f7b3663d,7176d46b,efe95e40,3063d1a1,68fd5742,2795a986,cf7613dd,eb200aef,e665bcf5,a6dd7fe3,cab6ede3,877f6a28,22b6620d,1eecda68) +,S(51f59cbe,68f523b5,b435633c,ce11c0fc,ed2129f3,5d392b2a,ef789044,722052f5,10403f8b,e7024887,3c4f0aa8,e4d0fe46,11f34268,178368e9,1eba8e4,d9b318fa) +,S(7d1806b8,410ec629,77fc41c8,8c86ebcc,74da9a0f,c6b35c43,68d069a2,c8c974f4,efe8890f,5aab9bd,c2da2956,bc089b58,b67ffd79,957ce0dd,9a53da,b26d68b5) +,S(add67544,8cb87ade,f8cfc3c1,85fbce12,e0d1525b,812fb5d0,2420481d,b22dde96,bb80527c,b22a3bf6,728ba305,bbff36ce,c6b44d68,9cf79ffb,93030460,8f461174) +,S(ceb2968f,fcc7b751,f9b560bf,b08f40ec,ba1395fc,9a3f63f1,65a1be1,862c3dae,67727357,b2dc8d2a,47606c1e,ae61ce54,1d79ba49,4a5e310,e0435b,383cf088) +,S(3a03b03a,1348cf01,afc60665,26b6fcbf,b3977ecd,7c17725c,a9f0c494,f31223d0,3e71c6e0,7da0635a,a2fadf5b,78c892c4,c95f794a,88594b72,183a9b2,4dcbe7a6) +,S(42ac22a8,c708f2fa,559f9b9c,fc7ca705,4356d18a,95a69137,bb8b8b17,2b771aa,ef669b2,85ed6abb,477dc2f2,bf0517f3,794c371,9ba5b267,8f622eb4,aa4ce374) +,S(b2ded9ee,ab06f1c4,19c5aad,5163e731,722c4923,818185c0,d99d6a8b,dc603a06,23bb4786,f84e6c75,e565a708,2600585c,e1fd60a2,b935bb4d,390d07ee,5e8646dc) +,S(ea1faab0,bb0b6cd5,454e63a3,d1546747,cf9707c6,48e4837f,3fc6b6f,a2ccc5a8,8fddc23e,651ebf4d,89e54148,2043fc34,7c26b66c,b2ad2d80,1fd2fb7e,77d4058a) +,S(487920c5,14ce0cf0,9d939ce5,81e13409,9fcad06d,3e6974f0,a3b5925,12cb3a86,db447217,8a92e9f8,65a1b022,3baf54fd,618a87a1,15887f02,11cddbe,986dc927) +,S(6828652,aa506655,60349cdf,132ca8c8,9a6f9a1b,8baf6adf,64e10c12,9ef9217b,9615f563,20db2860,9062aca4,7a136e85,40ebab0,3f8b5f7f,93bf0369,aeee0cc4) +,S(b66a66f1,9c94868b,3e45139c,ef9d7586,1a6d06db,72027814,83dbefbb,41157a94,5c0763d8,8aa90b2f,ee04eab9,fb96b280,5ed5f7e0,58c9805b,64fb17ae,9a0f224a) +,S(5318b13d,a824dbec,eced642d,d742ca30,479874e,31c1013d,d770a0b3,c9ddcd9f,13093540,9b5d56cc,d5004948,3bb22009,4b7d5a5b,6d357bd,76b79117,458e60ef) +,S(6bef6b9,555f29fe,b5277c48,863c990,8f1fe2c9,5b4b45fd,8c5eb482,3ef4964c,36c00eed,4281871,fc5e15d7,7acfe3c2,6793455b,9b3607dd,71f3e163,9790e3a2) +,S(7972f783,4c010837,89b92a08,d21b8b8a,b6ff6ef7,92eabe32,fa1c92da,4c8dba6,2c3352f3,f458a538,f8228321,c1adf9d4,a2df9f8b,bd22675b,afbdf041,9538f1e3) +,S(7f03f087,168dfd24,7a93e840,e68cd221,f02735d3,93d777ec,c9d2c9ff,7cb0228b,663dc741,fc8e98d0,7dece960,5b506b5d,a5f2af72,1b64480b,1dd3e7b5,a0ee7743) +,S(d06ffe61,973be011,2f17bec,6f4dedda,9b9d310,4ed22ed7,d4c2f009,843d2c04,175f409c,edd739dc,5adea16a,187a951b,d42df4de,d1aabfae,d56f1ac5,26cda8f5) +,S(9094c510,3a34209b,45f7062e,ec65c14b,72fa75f4,13999117,38cd7f6b,792119d9,da541e51,7211db66,272f8f8d,413e1717,13cf499f,6c9cd694,b98e53df,45e9d501) +,S(22bb9cee,8a5b99fc,d7ac7d67,5e232183,3f71a72d,55248a3b,451699f4,9f151eba,841e7292,93a98297,ebf2e9a6,6d106325,265d91cf,f7e4c245,845e5a40,522b94a0) +,S(b548dacc,944b013e,d50dfadd,fb84173f,d5829b2f,69a2242b,c152684e,7b8a3ecc,6c7b70fb,9ae39eaf,583939b1,1a1b8aad,673b18f2,7568d2e0,b2680b19,8c662a88) +,S(34f46e0a,2281a617,f8ab78c3,86ed27d,f837f23e,e986dd20,bf705daa,1b0188d,4ce4df08,bbf1e735,6760e05c,6e5d3f3e,664fea9d,6e1a72d6,bad17bbf,a3c089d5) +,S(3063ee2e,3834842b,84cce6d9,50ba5afa,1d645c5d,e0acdb00,a9cc4ce3,c266f649,b08247a,f79c2be1,a0e4e021,7c9ccfde,f76d1e46,65f3185e,8623aaf8,63bff9b6) +,S(d7232b55,3740b2fd,464a919c,46168ef1,e09638e3,65117eea,979130aa,d40fc525,f842c256,38e84dbf,47d13fcb,1763a296,47b72908,1b522623,4e307dc0,1a402ded) +,S(6025e82,e2ec643c,32b10e6f,62ef310a,11576957,96c10f8d,b099dd4e,1dd8cffa,1e5aeacc,cc5c5455,d542dc51,b12fa3d1,75061cc9,45931548,7467d09d,945e2596) +,S(141d07cc,256c4d2d,44ddb7f2,ef720aa8,4bef767b,3597ba32,3b39915c,1d84f175,a842c439,9366b2a1,91e850df,333c9cd4,6c983158,cc57989c,588c305a,1144ead8) +,S(ba4ad105,6ffde493,54d13149,31846519,86fee8b2,728917ec,bd1a0112,b986a90c,97ac53,f84e995d,92d14f0b,b156f47c,be5b6506,2a7f8b07,7e235da2,808029c2) +,S(5a6ed894,bae212f3,eb44304d,98ffba1,4a944cde,ccd12517,5e52d767,5e0f801d,d8160707,d43053e1,e5806d7a,bc17563c,ffaf92da,ac51deee,55fcb9ef,715b08d5) +,S(d82a95b6,56bd1abe,50933a3f,e291526,7b257807,c8cde42e,5f1648c7,f35c4f3b,748904dd,3157bb07,65f94c18,7528c74f,ac639a36,be18963b,676b9b37,83f54591) +,S(df7c9de9,8e748188,74967340,34a76645,c1e55bed,3a90fc65,dfd9726d,a2bd3826,3bd77fe3,e4a4018f,3e256ca0,2bb5c8b1,b783b729,21ce329a,fff9caf6,b530b1fe) +,S(d3ae1d68,4614c95b,51cc4af5,a9e8a05c,4ad7eb4a,ba4a65a8,9a151b96,d91bdb68,a24cad0c,ad0ba98a,860d6d74,aea57c3c,23780812,5fb2356b,b55f0bf2,95e25e67) +,S(ca85c924,48a27be2,2b68c9f4,c9ab431a,b380ccec,2439c8b1,944c234c,bd865758,c53177d7,6b16e0a4,389e1e32,7072d460,90e92f48,22043bea,924fab46,4023038c) +,S(34309aa3,4e9fda0d,f2c20da2,3e8f8f31,eebea096,1e769c92,6c4251bd,5440bb04,f655cca9,d5811164,577d0525,2f5605d1,b4e2b6d4,dd5540be,aefed4ae,84caf3e6) +,S(40212a4a,b2bfcac9,62442617,8a807655,185d2929,7e26c437,4879903b,41307b3e,26624605,6ceb4509,b481df00,79e25f1c,4dfea60e,a3768e8a,462ac273,8166dfea) +,S(2e441425,d121e140,5d2118b9,7a3b305a,fcf62e91,4f24bb72,46e92aeb,1ebdd152,c3c7a567,51dfd709,9535d07,23778131,692dfdb1,7584d9c0,c8fed42e,5eb662f5) +,S(31539912,9e59668b,49d9b8bd,5ee66b2f,aa727ff4,96f457f4,33400a20,b5242b5d,5e90a20f,a700c59c,fb0ca2cc,ae3f2837,6dde44c0,3cf6af64,365e4cd3,b4e6b3b4) +,S(3b586e2c,30eb1959,bd5171ad,54b81c36,cda6b0ec,b5e77b41,a7b5b0d3,e1ed4ba,6782aac,d675436c,d969f413,c471edf8,ff7d89a,d0a07575,16bb695b,19ef40fc) +,S(f4299c9e,b3453201,375b972f,fa39f01d,90c68625,a63c9d06,513fc9c,8c623fc3,cbd0e2a5,f9b9ebd3,f482a5bb,c5c17894,d5c320e0,28744292,31c94fe5,55ecf68e) +,S(96d35f35,eee50b32,32371acd,99d6db8e,d2b7c4df,1f62b867,5559543b,785503d2,c0e8bce8,8bee1e02,29a5d2ac,113c9f2a,feff0260,869ecde0,7cdb1cd6,3ba5f73f) +,S(ad3036ec,e2bcae0d,1fc34680,be2d293f,b40d9133,905af375,1ff89c49,2c183e1f,2c0773d4,bd30833d,24222f89,3a4f5e8,cd6abe06,63d66d63,2d5fb832,4c260f9a) +,S(a0f340da,909f04df,70a33195,1c48901f,6353f4d0,4d22f99b,3763f567,be9d207f,caa1d9de,46a37b8d,623a39a8,6792475c,bf3bd694,597351ac,515ecc8b,1a4fe78b) +,S(2adc4874,af0b3cfc,675421b9,5369ff0f,950b55d1,331aeee3,dcd0adf3,859be4d,6ad9fd3f,a840d02e,ddc01fa0,ffa61bf9,4dc1db4c,ec733976,bf1c6e41,bdd92b79) +,S(b9222a37,c14456a1,cf931410,d96cd84f,a304b9f8,5a96edd7,6e67f928,43536175,4002a875,dfc4cda7,4ff7145e,ca46aab8,8cfc5ed4,53b34eeb,1e5dd859,4793e3d3) +,S(530bae23,c3796fbf,76f86f6a,d8b59b80,801328b7,6c46e8f1,cba6398b,270919f8,d4d3b34c,6701f07,bc47d1d9,fb868fc2,b46ff397,2086cbc0,517e29d7,38a7964c) +,S(a7f2ce51,5b932506,c740e84,40f254d0,e0da57bf,4d9199f6,acfa3664,ec36b823,4946fc41,3ef1b3f1,86a2c781,6c05ce7f,803fc7de,a00fbc2e,7e6c4688,fcddadae) +,S(8ff613d1,1c81c4c9,fda3860,cbaa71f8,eab9ac3,d9263f31,55317949,d6ac1d53,54f683d1,fd382305,b2193554,bd3a6d2f,bfbb99b7,5d9c3e1b,876c3b52,e2bdef49) +,S(6fb3bc81,5ef3d8a0,d7aa1a69,dccbdfb6,3f7a58c4,7a12f98d,b09cc105,4306422d,798fe7ac,f9fc71ad,7023a8e2,c9376161,8fa632cb,ec607109,d28a63a3,9a4228f9) +,S(c32aa38e,bf0ec0ac,61bbea0d,d2c633c0,bd49ddae,d77179c7,e0098c8f,4488da8,e01f5fa5,1107cf4c,f4c1c5,78c3b5f3,a1baa059,90bb8913,9e2abb30,2e9e5042) +,S(ef5e1efb,d1ede40a,810434ae,833a4681,5f9021f9,41ef1d82,fb8c1399,16c4933a,94a9cd1,5f160c1f,4f85ec8,16fd1834,9cf19f8e,96ac9247,695ca37a,dbad6ef9) +,S(8e3aacf5,33de35e,4f923b36,c378ea57,7a5aa477,70ea6390,f92c73d,50fbfed2,49cd7650,ff69ed12,b96ac3b1,420784,7677497,b731e0ce,316eed65,7e40e014) +,S(84521790,204c64cb,e026152f,474b0da2,25703d93,25943821,7d66f20e,3ae0d06b,c1da2f7e,438fbc82,57f7fe4c,7e49b73a,446a19ae,775e7f1d,20c8fa31,edc3bd20) +,S(604cd900,97fe538d,b27cc2cf,a2d6c79,692f2e2b,c1b1b23d,1f0eb949,df560697,914d5288,29765538,d77f8e04,182c50f,d2d9aecb,2412ce47,4888d666,46b2258d) +,S(c13a44bc,9a27e241,5531b8a0,5570e66e,6763b3bf,a80e00bf,59d6124f,b3d67858,71557bf0,4c261c2b,19196d0e,9e459f3a,f629cc19,84f411,31835400,3a60563) +,S(14f3399d,5204b654,23d9318e,4adf3af9,dc43099,eb43b719,eb4644a4,897ffbff,13808cff,4c096655,72329034,d489433d,976cc011,d1a30ced,702ba4e9,5892422f) +,S(bd84d712,43dea7fe,f151b207,5d03d2ee,170488ab,4175965b,128411f3,f592a36d,57a1c602,408fee75,ea9e683f,43d7a984,bf03d66a,37513c50,5cbec6c6,6d286fc0) +,S(f319d4a9,b5f2c1ed,6619ae06,e5aaabe4,13a2a6c,265283fe,4a51c7ca,6c49b572,bd9d90c2,2a369a03,1856ca9c,86426171,db952537,edbb1ba8,93fd16ea,35aa43b2) +,S(9649689a,424ec9f5,aa4cf4c8,45588046,c50eaf9f,700d0412,83e02640,9a80c61b,5cba8567,95b0440a,53e0d1c6,ad560364,c398dda9,d2e97a1f,e594355e,1402fa33) +,S(45fe12f5,a340034f,381764b0,adf503b3,8026374,70eb26e9,6f4181e2,68cb1c38,ab7715c4,52e5581b,ed940fde,355892f2,b8a16a3d,d322123c,14a57a23,72f244c1) +,S(98bcd24c,3222401a,a4683213,5a378790,6c9812ee,989b8f52,fa522c6,d39adcc7,14c7cd38,7bb5191c,f49bbe41,52af8b03,7135a6a,bc7e4697,35a72a38,e44433a4) +,S(6dc56512,7be34196,a7653057,f79b854,83c275ab,65c05c2e,83663da5,31d7d652,a6839fcc,ba7db053,affaf5a9,4c95676f,9d65eba3,c2474472,cadbde17,2ad3692b) +,S(7a7f66de,b04492d1,fd2fb9aa,dbc4ea7b,ae5a3801,47b86e68,60513a57,eb6b10f,fffe4f2,b722f36f,1e555671,90d84d9a,39b819e,fb7a3436,29b83adf,f6045f05) +,S(aaf9f188,3865e2f7,eb500794,3888b4ec,9013371,f7162947,2cf52adb,bb5288b,df634c19,e7496b4b,478bc10c,7c00ac8a,5fc24dc6,4f193355,f0fa9c62,d6048243) +,S(6304b1d7,56988ca,25afb747,476acbad,2e5afa5c,86136090,c86a82a0,e52b373,91a2d829,2357463b,ea1a7cb,33d79be5,8bd71732,f1d2cc13,ba4b2724,6fd39f05) +,S(6eb17147,2aad3d80,bf4e06af,a36e37ee,5fed9c18,bbaa1c4f,5cd871dd,c526515b,6afd615a,e2512fa,70c9670f,b56682d0,f304a0c,6a23d1ab,fe958a7c,2a4173fe) +,S(9113b613,ba815ca6,43e7bf66,27dd71d9,8c2d40ea,5c00f596,6216ca9d,d32b1ce,8790dac5,bce4100b,8e4e5135,66a104ac,b55d3ca4,3d6ea083,d23716d3,3894de2d) +,S(5c7af38b,8821169e,2f7e2edf,18b3b73a,c387e6f6,a8ef1cdb,441f5a13,284f365,e12619ea,e2a07b8b,c55dda85,6cd37927,d448cf2a,f4028459,2e371e10,8e91358b) +,S(becf19e9,23fa7b4,1cca0efd,937a5b11,e227fd18,22743fff,80c42692,6631ff0,3213c209,9f255eee,93323d1f,b440cbb7,64e86f1a,4021b82c,485517b0,3440ed4a) +,S(f22954be,430be6ab,34dfbf92,264c2406,df3a0a7,19ed45a4,d09cb161,4abb0c91,a60397e3,ef3308a8,12527744,311673b,c18bc43f,352dba00,4dcd4124,7b84846b) +,S(c50ae8c7,61776e62,5156f9fe,7d863c36,79d43126,c5f3fee7,5b837a38,1803e770,be966bf5,99b67e6c,ffc421a5,e6d12e4b,cbde12,4d84eadd,781ea562,aac7dab8) +,S(c6c3a65f,e849c113,748e9b6b,c9a9419c,1a919503,36201a6d,f989bc5f,fa07d359,fc205b83,b4764ded,ef58082,11eef120,4d9fa959,4d5b7086,c2fa2c9c,3e56f37c) +,S(73466c27,8d5f13ad,dc7da10c,b8855c23,9069f57b,6ec5e80c,e27191aa,196d9b1a,7e7e2cfb,533cfe9b,24243cd6,7680ade2,35abddc3,d8d00faa,c8adae39,15ddf6a1) +,S(6315ac10,35eaf884,8919bb56,759f7013,92fe442c,771a42dd,dab88ab0,2fb0df2d,a49d2c97,6e0e66b4,50e8511f,d91f0f71,a7516fcb,70ca61a0,98f135ed,8e19396e) +,S(fa195146,fdb7ddbc,41daa8c5,98e1f811,36c33eb3,bf23dfc2,3f20b36,1c8e7bca,324fc70b,38677dd4,c8e7bd82,4b836d0e,738dd757,ca408ff1,95bdd5d2,bcb5cef2) +,S(ac40bc48,87734bd,51247e91,43e5e188,e5e2bfa4,2e3c0392,f39755f7,3952bcad,75904ebf,603c2f07,4eef9435,eb22c663,1279afad,94d3bbca,d5349881,7dc4a472) +,S(15b7e1ef,d2c41c6d,416b6dd2,5f6612f0,a0acb0c4,1b161b4b,c40c5ad2,a92604f6,a13da672,17501833,4c4057d8,85be8fb1,ceb6d369,6979b805,83fc0a37,bc27a0a3) +,S(adf4aea6,6fff705d,5bff3c84,93e8870,4ba4019f,ed550cc5,c203439,ff8512b3,53ad2122,30528e1f,4fee43c9,2369dca4,3d071177,3ccfff26,aa16a502,6206a3d1) +,S(da0d5286,fc261d92,1095e1cf,f67e729b,501f21b9,45e8d84f,ba2c80ff,335d105c,5632ce7a,e8d9ce7d,aac7cf26,2ef7bd27,418613c,b288e793,35a0a638,6abd83f9) +,S(463fd081,daf02794,18b95a48,bcb8dfef,3a9dc67c,2237d2e5,dded1522,f714d6d6,3de4cc76,7126750e,4038fb43,bf6af17,63ebc0b2,ef56ba8c,a376b815,6b4f28b0) +,S(15e37b9f,58ce033c,2f0ad85,d49f8207,2e2547c7,91c7ec52,a8606974,2badb586,38816873,5e37c957,c18ad56a,e7ab81ca,8fd89a2d,1710f032,54393ae,a046490d) +,S(2e121b79,765d4f4e,8e7aa8df,5c70e4b3,716b976e,9e4536c0,dbb3b5ae,4044a345,d7ba59fa,97a7d6b3,8b70ecea,312cb01,f9016b33,c160d1e8,d33fdf50,ffcbc928) +,S(8d4c7aa3,c59dede0,bc146b10,38f8f823,8182c4a7,1cde0d8,e17005e8,64ad29db,78aa343a,28a48f90,edd7fb31,849d6d3e,fdb4c677,73cb523f,82c0b187,2c17f44e) +,S(1ae12a1a,19a5d1,3b2f42c,35a385,f8302721,86a67801,c22818f6,94438c58,5cb421bd,990ddad8,16de9439,87bd96e7,e1ddfc5a,8d0f86f7,b30e3483,897815d3) +,S(7a6f584c,d48be9eb,a7b73377,8a173d5e,3833aed3,a603a226,741ae1f3,a1c21bbc,5995b840,bcb6cc28,b83d048,9faa5dbb,c6a93190,46b11b13,59827266,d177d27c) +,S(2dc5ccb4,8f78db2,3f0933f0,ef67bea0,53c7f2a6,80788bad,b71526a4,f55fe758,9e4743f9,ddb46206,a5449942,71743b44,713522f5,f358ab47,34c9afcd,f528736a) +,S(f7a5219c,75dc4426,4322bda0,3b603127,26a6b3aa,c471f42,a33072b4,a44fc9bb,9e1feda5,5da277d5,cb18381a,4471939b,a12c692a,a40ab965,fd03949c,d8124ab3) +,S(a1bc311a,e29e3926,5b3be1ba,23d7ffee,df0de8af,fba089c,fad797dd,8ba67c68,9abf66cf,109821c7,68c98164,b0598068,c4590d7e,b9ff4c53,594af6e8,e0ceee8d) +,S(2c2ffba2,e3fee930,fe8d061,3bbb8290,22429fc6,654d5ed3,61eb8720,1d6b92c5,ed89f28a,bad9510b,acf44d05,5934cc64,ac7e94e,2dbc72c9,986e6cb0,acbe434c) +,S(1d157e13,97f6b22c,3dbfe448,d1168b8a,bc963f86,bb3bda29,a8011f07,d2cb5ffc,bc7cfad1,e1633419,cef1c82c,d0249ee8,4c38b3f9,d628337b,aacf0449,4ca3c0b4) +,S(1b9e9723,56f8a4c9,5e8d5fbc,8e2f2cc5,99c77d62,90b2fd44,2e63b3e6,dc33c772,59db6eef,988386fd,21e8a772,a1fe048f,95ba77a5,122253c0,1a52830a,bc12742d) +,S(80460a3b,16fd9ba2,250b07fb,c77f2526,bec5488d,7d6c45ae,6f480308,39af48fb,bc7648a7,744347ad,e17da2e0,5cd1ce10,db704acd,26c81fbc,db251ff1,c6fdef10) +,S(c6903a0d,d8c26c8c,cdb675b5,972aa050,6912813c,a6f0c8b0,2edfb792,491222e7,f4759b4e,9db7f1db,7c8a1c38,dfe76d86,c3778423,29280aec,12b1be06,d8e49ff5) +,S(95ab78f3,a4268c8b,39aa645d,8c9fbfd5,b92469b0,809d6369,3d57d076,d305a241,8df4c8d0,ed85ac01,a965d580,78f36a5f,690aaa03,d9479d1,b2297a52,53e3c6) +,S(bafa3ae4,40a4b8d0,40862a18,cca806fe,8cd0e780,483b396e,41543486,db91d9b0,d7bd60f0,c0ee0b8e,38aad85a,85a42ede,56c66d54,ee73d371,a3bb7cdc,e93df670) +,S(7cbf5d9e,3bea6864,b87ae157,fee6e352,dc3a4f32,6e7cfc68,377fd199,a6dbb71b,42d082e7,5d55eb62,9771942e,3801c27a,fd80b502,a997ccc5,9f5a95f7,d7276999) +,S(9108db63,751b8a9e,f4870524,f1198f9c,c4d3ec20,af54119d,6011f263,de13ca29,8c1d6c47,aa016e83,d2c8f76c,df0935b1,b6f909b5,bf5c90b,f4203493,22c711d2) +,S(a705e7eb,c20ac4d7,43be660b,d61340c,9629d069,1b08ef01,a59e78e8,2d8b347,1ed8ec9,13ba19e0,851e1912,5854433a,f71b21d8,df64958c,afc5d7aa,cd29ccfd) +,S(b75483e1,60144d46,78af9a3d,701c4ffc,fe154c49,fad45ece,3945289d,c3781c3,a4c0455,13cfa7fb,ba2931cf,722fc569,87b2c79b,c4b94313,5a458d34,5ee16d57) +,S(c59aff26,bd4fdb9,37468989,763376f5,64abce,c00d54e3,45b6dc2d,9b7b76cc,c396c194,db446fb1,a22e86e1,8a37981e,d114e675,474bd24c,784daa96,91eb15b3) +,S(2f6701c7,815ba7c6,37c4649d,d05a31d3,e909d8ba,931e7136,1e0662e,3ea19985,937eb67b,9262bbd5,12a21e90,393f9e65,66e03203,55c77afe,cb98d1f4,bd25e8c3) +,S(170d1e33,f0862542,dc72b1b2,950ba98a,812cc308,74ecd0c9,23ce7c09,ed7cf9b3,5148ef39,68ff35f7,a633ba7,dab6cdaa,54dc6f87,510f1a7d,4d3019f0,c00bc868) +,S(743b02d,b02301db,453f8694,cd517c6b,433f609c,e205cac,6f6a49b8,55890708,7af6350d,56130339,1a9ddce5,f566b9b2,9c10d535,d5183850,6c743124,8dcd707c) +,S(ba6df8bc,f9d83988,4991c6fb,e0aa0ecb,d0b6cdc4,d0e372f,3ec83b51,da6a6570,7d27b176,3a01a8bd,fb7dbe0b,226dee6a,73ed3644,807ca33a,1f5fee61,cc161fcd) +,S(d3b63a2c,364f01db,6a6f384b,4bba6c2f,2fa46a02,86090826,1c8b5045,4b92ca5f,df6b9cfe,fe7aa14,a38bc44b,8b627b6,e0ceeca7,1720d630,cc4fabf7,b020e2d2) +,S(638c2b1e,374ff6b3,4b634f4c,bf363bbb,55d66c8c,af4d3fed,43cf436f,a1daa7f3,9854873,37b48f32,4feda3a1,f267dbe8,8831aedf,d7bd36c8,6cc8d862,857507d7) +,S(1749ab4a,607d7864,5c4cbd30,4bc34c06,94a7a636,9c8c8f8c,be4602bd,16c4b4b8,465bff86,b459b842,dfae4df6,99be1758,8b1aca97,f9802827,d892792c,748ac92) +,S(9071a5ff,ff23ae4e,2d81b2fe,d341bfa9,cb86ae6e,ed32870d,d549af20,a1db9feb,c0e3d4e8,277d099a,9801ddf3,3e513aa9,1761218a,967d530f,21d70894,ea7d38ab) +,S(91bc0055,28e2d857,ac644954,242fe0c7,bbaadcf2,9119837e,898244e3,a305ba6b,6fb63758,3aefe600,46997b88,315d5a24,683ff955,94398694,be304dcd,8b588f67) +,S(9663913d,48c865f6,312fe51b,6e8e7c6c,51ae397b,d141aaf2,df3d6ff5,edebbe68,c6251751,7e24d81d,b1da26a6,6627fbb3,28b5f818,6477b34,43f7c36a,918753bb) +,S(e88e8702,7843b941,61c71887,9a0a9a90,cc0d6dd3,8329c73c,a18acca4,3f44ffc9,7e31ae63,1f9c927f,bd055f58,e682935a,3225e778,9221a062,f2826d86,97143a61) +,S(5ad27e79,dee03a52,be771a9c,ded6a02a,58337f26,be810d1a,f8cc5ddc,f1eeb917,91c18e01,dbee34e9,a5302a7a,11bfa7fd,ac852e1b,e53aec2d,3138259b,bb53e6f6) +,S(bb7f4694,f2935a5e,8711ae47,bccca550,cee2632,4347b468,58e40c74,49111ead,d9f94c14,332ad75a,59dc784b,d674e8c6,146a2b74,566ac1ef,b0ca17dd,9eec8d74) +,S(ff77ae06,e0624cf5,f6d905ee,b0de7281,5377c026,3e01b6c4,a139e4ac,3304e82c,1f27acf9,933d08b6,f0892199,11805d14,1611a318,661e6e7c,75014b84,cc35c395) +,S(84c15fb3,1b12d39e,ae59ce0d,f8646e9a,67c85492,8d6c498b,4b836be2,eb19a060,6aea0d78,d54090e3,2216c3ae,be0dd433,a666e67b,44cce0ec,1609804f,fde33f74) +,S(9a48086a,8bb9b150,a6ccb966,3978f555,41db6d48,1b3d5266,e958cbd1,df9ee7ab,d8eb2109,13ee09e7,b5767661,13157905,b3cafed4,641903b6,da0ebc08,a0ce2f58) +,S(db32ad19,45f4d9f7,eff1b8c6,b87c5545,1b0c74d9,8f1c4ffc,6ff1e79a,21ab3033,2d56e65,a70bd23,617f85f1,4a5d0e4d,52aa6a70,a8594158,36d02d87,309c7eef) +,S(4de7f1aa,b9089f5c,b6d95b67,a04952b0,d4696cc7,6640e1da,f4bbf7d1,da985851,96f2cd33,5fd4b816,4499ddc5,5e81f5ea,c4db4399,17f2151a,f86d2ad1,e2b3612e) +,S(74bcfa73,5aa43e8d,1fb540fc,9922362b,21878c09,666bf541,a0e739b9,dcbfd1c6,84b26fc2,8b2a05cf,a67947d4,99c1ffe8,f94ed4d4,6ba583b7,cf26ee81,ba60bca8) +,S(9c596bcf,3d2e1df7,cd8d9807,8a1ab17b,f16e27d8,66cfb582,ef58498c,48ee0fc4,14dfc093,48f72d7d,af9e3599,8b5f18bd,5287f3f8,381308e0,63666028,dda9ac56) +,S(8e2a0d3b,2786d67c,a15cd72,4f2cc6dc,16cddfc5,cf080ef8,d9576b2e,e5b0ff9b,2ec4853c,c83c72d2,68555129,ce30c836,50fb59b5,17a3d61d,56ac4273,1b33ad06) +,S(25ec4838,5fee8fab,773498dd,85a23ec9,46c59839,14fb8a9f,d1239ea8,ade3f829,123bded6,5312030e,d4760047,1867aa4d,b7537239,b363b6cb,58ecff98,44986924) +,S(a1cd9872,7551e2c5,db7985b5,1698b97a,31b90d3d,32fbe60d,34f8ec2e,398df76e,40858565,aef814bb,8bd91fe1,410f9556,3f1bd170,345c1283,b64fb268,4980c398) +,S(bf7d3973,aae2cc31,e831390e,f2458e85,9ed6847,e9eefd6e,cf91e3d,4a4924ef,c2829fc4,2127b303,c801605f,35602b84,32357564,d9333ba8,d962d639,ef21a6aa) +,S(5a5299ef,e0d394ef,f4b510ba,96dc73bf,6332d358,e276bddd,527ec290,b73e3313,9ccd4618,17e18104,d324e1e8,1597eba0,cb6b475f,4e5f2e02,9cfd2d63,b613de79) +,S(90efd8cf,9e4b9d74,5cb36c13,20a8bb0d,b5cb8578,de49ea4b,c289043,e2ea810e,87a73339,aaceed7b,af47b5eb,97aca554,d80a4f78,d439ee14,4b2d0fb,f8df5e3a) +,S(3a174294,4db7f2d7,2498e2fc,e2026d5c,f8600ed6,958db97c,24ac0de8,417f6def,e60c566f,f3fd14e2,2ff0cdee,45c4c2,31797951,7aa0ca68,af91a5,e41f5f60) +,S(2213e0a1,3679040f,73e4d68c,bb941665,6ea83640,33abac76,2e64d509,48a97656,2b87ce0f,bec2728a,aae6586c,bc6d9a89,a4bb9b9a,211de522,cc909279,5860791c) +,S(382412a1,ab396523,8b06c47b,e941051a,bef3b215,16efb280,3ff3a1c4,824954c6,7cae8b14,1938312f,ba482980,ab9073da,c66c1ca0,d746231e,8ba8f331,4cfd9cea) +,S(3d76bfac,89c1269d,53b6ded6,bf13c785,361b1fa3,84be2ea0,d582ee43,f06de56a,18b1cdbf,96d12859,bf887b89,6d8f2e6c,a08b892c,688c7687,8294974d,af6d6284) +,S(715b18a0,68d86cfd,41a20541,847b36a3,ed7814c1,b5528751,927042f9,85e7ab70,2b8e0228,b0a4d39b,85a3d3d4,f5a10db,c6825659,f4b967c,361da449,24890911) +,S(a31a10ea,e38e6a00,ab4f004,8b45c8a3,e57856b0,d0b64e47,fa90e234,e17943f9,5d4b5150,7d3f3a82,87e5d51,6bb30b89,2cb9f540,96aa5962,1f77e028,480e594c) +,S(b397f965,1dbbb6db,34708066,a1743511,d4a16332,95f53772,72c43a6d,6e21c1b0,673fd327,45bea2fa,748a759,30679b2,471e4004,423dc8b3,f34f95ea,f88d2b8d) +,S(2e4b865b,c1245325,1ad8b3f6,e8776bd1,a5878b93,ec34f847,65af84fc,146d9919,b3e7d479,661ce034,50094432,c538f55f,c8be8693,73a91fd0,350c8089,ec0d76f) +,S(9a38c790,7c0751e5,ba750bc3,485b4a4,72b661c3,63a3980e,feeaf59a,98533a43,dad7ac3b,65493036,d30068ca,72808000,d54b42d6,d263de93,a1ced3d8,fa82ca71) +,S(5599d251,3b3c8337,f8af18ea,70d1d2e1,83f3e363,63735357,2b3f6cba,b4371d9b,7ccddd9e,ec8dd507,69f6f633,cc70488a,6a4e322a,2716218c,5de50fae,45398dfe) +,S(610c472,4699e983,530e8a32,b60a8077,c7f60226,cc3b2010,e49b2e30,f2a98afd,42157de0,fe6d8e53,17a3f565,fa450f53,8755679,6d98c7a7,ba0b3e96,844d25d1) +,S(89c082e1,1438e2b5,6a4bff8b,cadaf804,c9d11fa0,8f47bff5,39cd0741,76f24a59,f4dad4e6,19ccf814,e899d48a,904a88e0,6db6ab19,a2e06a7,b359db9d,cd0ad0ec) +,S(bf810fed,48d1ec4f,77cf3732,ed10a44,df9e4540,2e1a1e1,6b29c82e,32537565,6657fd30,337e294,fa31d30b,409b426d,546a47cf,38cd23bd,75aafaa0,b527d66e) +,S(3b1317b8,bb3c9c91,964ce369,19ea811b,90a8bd5d,ebadabc2,d4d1af3b,50fb3524,cfd5988a,78aa555b,595531f6,5fb0e3f1,e756c1db,626cf60b,4c1b17e6,caca603f) +,S(88520439,61558d79,7b084143,783d9e03,791e6183,c932d1a4,17eed30e,bcec0bd1,271097c4,4c723ab1,c1d13e9,93b7b232,235957ef,f21a13b1,2b3d302a,ed46ba1) +,S(6c420c30,343cf500,da0cc05a,c315d3c3,45ed8aa8,e0551bb0,32fbc512,732f34d7,fb3c0808,698d38f8,3310fe1c,15587cf7,137bef2f,666229b5,bc789dff,1b2f1111) +,S(b12e21e0,e060fcf5,580d75ef,22e8a800,33e2c19,487d0660,615f7d51,ba00e430,3931d63c,a6e0da2b,295bd22a,4bbb27f5,fb52d89a,3c4ac36,795747e6,e74ce944) +,S(4fb9da54,4da95655,c0de5654,f68c2820,a7884734,4bad6934,e671d56,e7bfe11d,16586701,9bc89b28,f5fdec40,78a2a51d,6e087ee4,29456cf3,d258b97c,209d44fb) +,S(18f8f6ef,23bf75f7,a7811025,5babbeff,792109ca,5a550472,245552e4,35588e7a,e712abe6,3a374f25,fd4b18c8,4b1451fd,ea77692a,43c0e3b1,cf3469fc,7a9acd55) +,S(d730d167,1bd36654,7188c07f,78d82ed5,6775d7ef,bd0967e6,1abddea7,7ed6073f,49c4bf3c,ad4e31df,d840045c,aa8be15e,43f90196,818e30f7,b379c74c,1d866553) +,S(a915fb72,7d4c40ab,547c983c,24a4f019,1f5e89ce,7ab0636,e903aef7,592208a6,fdf28a3f,6557f27,5813ccf3,8d927f40,b910c5a9,ddc3c83,14a48eb1,6a5956be) +,S(7abe8d85,bd95c580,cd9d532c,c1295f5a,ad5168d7,e3dcaf28,b19f5e76,95107157,694abe9b,9a6ed0d4,c3ac1db8,79b49038,6fe9d2f9,443647d1,91533fbf,aae3cc02) +,S(93a83e8d,c80c7cd7,64dafff1,edd148b2,9c336de7,cf978b14,fbd35625,c965942c,91ea5775,db50bf9,a7e3f79b,77c7d5b2,deddfa08,a1d455e6,fa21e547,356c634f) +,S(a334ed87,dfd2e1fd,699ce1f0,a09fe921,487f8321,6cdcf75d,fc8d7e5d,cbbd1af1,42a0874e,d148bd32,ba4324ae,eb0260cc,7f0d20f3,f43388,38904640,8f7ae7e0) +,S(811597c1,f4129ac6,e150c231,bfd8e4b8,4ad441ff,2c698486,affd4ac4,c22bf8b5,5f7fb47e,11b476cd,acce1552,95ac000f,3acb3838,6ad3c6ac,191dc12b,d1e299dd) +,S(cf754ed2,47c9eb9d,24f3129c,4b4cefd8,94b5e58b,832f158e,2e82911f,8177a59f,262cb605,2991777e,bd1ed5de,d2e7ce29,76dd73d1,ad4c9bf4,9fb5d8fc,fbe4a3d1) +,S(290ec604,a6b4d816,ffe75715,419b0f33,452530dc,94f48883,b3982161,4592b229,4235db3d,df2e3f1,b61ac412,a90f543a,ddcd519,4f4a315e,d889b32c,ec8f76e9) +,S(1f90b869,4bf9ffb5,7697ee72,29b7f20b,52b47997,35efd7f4,1e4b9102,51886858,dc3d7a68,abaf70b3,c84d533c,48ef38f6,9be7d26a,13c4e834,5a7bee29,c6d3c87a) +,S(ea20b4c0,931087a3,44d5642f,6c018aea,2da5f189,a4d25968,96110281,88545ba4,f9adfa96,f945e745,88d2ab41,e32ef5a,76b370f3,f0362e57,129c3998,e32cedeb) +,S(b8bb88c1,21948c01,3a61fbf9,bae86eda,28e9bb4c,6870b0f1,7109e5b7,c00cf4e1,90685129,8607d7ac,25bea5c6,1cc4feb4,4148e07d,2fc3fe7e,449773d4,8245019b) +,S(2345a244,f2f411f6,ef091904,81eb9083,9128f7d8,67e8b910,124d1e44,d116c529,a8eaf530,c69b792,d6595967,4f23b9,b0e239bf,b69d05ea,466f9f5c,9bd5affb) +,S(75aee824,38bb03a9,b9208cc9,b725f13a,1fee1aca,20ed129e,e5ecdd59,b92c89cc,fb6bc8a0,fe0f684,ce4cf153,2053312f,b97aa1e3,739fab8d,407db39a,737ee51b) +,S(ca46d3eb,c981eb1,764867,c99cd7fc,c414bdf0,31b2c9a8,96829ebd,f31e2e36,46363355,862a64b,97541f7a,7fc5cf51,ecae168c,c6530db5,3a7f2394,2e87bb96) +,S(4fc1d258,575c4830,bc7a03d7,6a259406,7d633e9a,da2c734f,45ce4d9f,99dbbe7d,cbdc616d,fed2bae2,9312c5bd,9e195bb,bfdeb2c8,d1aee5e8,cae8fa0a,4bd6baac) +,S(4edae08,54365c27,f6ad83b3,8f68c7d3,f0a09c6c,153791d4,df98b5f2,3f0b9be,cdc8a485,8ac66847,c732a2c5,4be86af8,d6d637f3,e62c7802,dd71c7b9,2eb18223) +,S(624dca60,16beeb28,c35bef5f,e97d320d,d725619c,3faa7ca5,ed79d491,72b12469,cc33b49a,6fd125cc,98d65a81,c0713cb6,2a7e687,276e7fb,641e2f76,52646c12) +,S(6738d38e,760e50b0,6a18a9eb,b5e3676e,c38f3487,e34461bf,2e5d52c,5bbd6b4a,c3ce0343,9b9f624e,a92eecc9,860ff680,63a907d5,b57c43e,465ead5b,bef5e709) +,S(bcb74527,10f178a9,eb48655e,3d373b56,8f02036c,e9ab826,4ab7cee8,52f7f9c0,4e928392,52ee05de,587c91d4,6eaf5e5,92ef41e1,5a2b5c2a,da9e4512,c25bb416) +,S(3375c7ca,1b5fb4d1,1838ffa0,c21d7e03,de34ca5c,92bb4592,bb4598c4,2b490382,8c284e32,f016d186,875b87d3,3bf4271,4b9013c8,ea159634,b39b7365,7ea837de) +,S(c347409b,336c0677,ee95de61,f93fad4,738268d5,6f31059d,380af075,60e496bf,37dfcc4c,c13bbfa,5df43c69,eda0c68c,42de70d6,ab64a9db,a4ed22f,1cec3fdb) +,S(305ea4ad,ce72ff73,976544d7,a3deb346,452ce997,f280c3a6,106b7c9e,3b9bf5d6,bfc33cd4,ca178310,c4caba86,5b87477,77e9e572,4278f0f0,56b86a86,1f2e13ea) +,S(8333f714,70e57841,312a33bb,4f1463df,d237651d,fec4e1a6,40c0ebe7,478c5a9f,d39b03d1,11657c2e,19ad78d,3e1208ef,f8505695,1bc67098,b891c42e,b427bcb7) +,S(500af03f,eba3b646,a0690f0,74cac255,804c8f8a,c2aaa1f5,f5cee4e4,41913e7,5e67542e,8a8f0411,e9985a76,97ba626d,f0607f66,9f9c11da,826b47b1,a52cfa2a) +,S(e440385,c16bc15,5023cab3,3e7a48e0,5e7e0c57,e0fe848f,26b146ab,237a3abc,dd8ac982,b627fc9d,7fd83c26,51805de3,d7369ef9,2e970664,8744badb,3db060aa) +,S(83eef59b,b0a26fa6,60c94e45,c097bcfc,8622c37,cec46eb3,f9e93aab,d0fa6438,8b51311c,ff685570,d9aa7a66,5b47a3ee,b6bc05c0,a2709421,c73ef814,bc703723) +,S(930cdc95,f723a7eb,d698c1f2,46692f39,e1add95e,f8cf84ca,171d4700,2a7d759c,ff161a2,31fc8964,5bb6dbb9,f595daf4,86cf01c1,944021ff,6ff793fc,2613bfbc) +,S(4f7cb0a2,c83f3520,86085b19,a6e5ccc1,b0beb700,35637e6e,8a79fd78,337c2616,aa32192b,82831ed,a9412f4d,6ac6d148,f68ef492,5b438cca,12a73b37,b4a8fb74) +,S(c7238fe3,17590be1,d8403ca1,3eacc6b1,71cccad7,e2e8f659,f11357ad,70590424,59079180,90bdc74d,aa06abf0,940519fd,d09f24b8,88c15cb,a632b814,fe8910fd) +,S(c6afda17,e6582427,95cd34e3,edefb600,70c73737,2d99f6c,b2b8dd3c,99874880,d805463d,15d185e8,b4461293,b6e6f6fc,a0b58a49,eefd4d0,11ef48cd,da5a16a4) +,S(4a14de26,ab18ebc3,414c6856,1a77d62a,221821f,8c216496,700bfbb8,21d95b2d,8037ef39,d1f190b1,a24078e3,e554ad1,cf86d5cd,f731478d,b34b6b5c,c9174314) +,S(cbcd6696,547fc496,8c6e7ba5,4caa4a74,43764852,43f479e5,558e2be5,77bbad00,8e0099e8,559db5d,dba0bc72,21505ef,d42c1c95,876539ab,19dedb2e,8e561482) +,S(37f168b6,4b41be85,46abd1a4,7a5ab3dd,5d690661,e41b16c3,87025106,caa4e2ae,8c617348,bce3bbf7,54a121b2,37342794,5d734e38,da08066,c4de59da,e60b5c89) +,S(3aba7081,55dbb35e,dc4a3fd1,1db54446,a7501ea0,d67b0286,8d2e6d77,99162697,829502c4,2dd1105c,cb046e0d,41cd68b4,38437394,b93f17de,5534f014,270c4602) +,S(84842bf5,fb46c697,44eca720,7b1be6b4,e5f5809e,eaeb3e9b,1058eca5,4498cafe,f4210fd5,b49f6484,2efe3089,327673d7,95642ad1,73b6840c,7323b7c4,16d61fb5) +,S(88383dee,ee0db44b,959edd96,feec2bdc,73d6ab56,9333fb3c,d4b18b01,ed8af5e3,8f0cf362,7aba3ceb,104009f0,baf84ed1,f57402e,fc330f10,6e0b45d5,4e0626ed) +,S(ad0a97ec,2197c5d7,4e8eb9bf,9798a24b,aa7c3e5f,ad6ac263,1acd5109,5178d8f9,72b352a7,445db832,2e33c93,5619e7d3,266f254,64a4c4f0,96051ebb,1e37065d) +,S(9b727e4,d107418e,1f62b499,99c1f8ec,55ef6e91,a9a10ec6,8905be97,33903d85,27d6456f,5ea52aee,a190dc81,647ce31d,15ac8c36,de65685b,4784eaad,4a32e41c) +,S(e86bbef3,8d740a44,7a2cb0d0,a89c2106,d85299f8,c38fa540,a7075efd,3a02fe03,8a9f75db,ecc532b6,ade5be9,b855a27e,185895ca,d6a6549c,f6c4c1c8,7e151b04) +,S(b72ac468,9209207,2cb735e7,d424a18c,5ef097c9,3a9b96ef,1ab7e29,d0f379de,89111544,27b03712,e2236fcb,12cbad35,98ef794f,b8141913,aeb1ad8d,ed9e6467) +,S(f8f5819b,203b2bfd,ab2dc532,53277103,2f9caf34,c53c7ec7,7253b314,2e731ff3,433fa831,3dab76fc,aad5bafb,12362126,6d8d7c09,9d513ee1,1b633c6e,e3f1e96e) +,S(8e4a8890,a15da3a6,c14d2df7,d09f6157,d5dc95f7,4f9518de,8aecbc4d,c0ac62f2,c06063ce,1d3c2a24,2494a1cd,db381513,6200827b,78ed080e,3cd14f4,5e545acc) +,S(b1f6dbe2,ad730748,f906d1d9,160996cb,f3f2450c,fa656856,e34f2481,40767081,ee6b2a03,3f3245da,76d01bc6,e61afcc6,94a9e64a,4f0256bc,62acb5a1,82e45ae2) +,S(2139dedc,a8365bce,b9c49cfe,3834e4d4,27a46750,d6b0f0a3,4e7672d3,d12509b4,b20a9101,b63be2a5,28340f58,893e10d9,d3c63fc7,77b5c6e6,a9a67193,13725870) +,S(da3aa585,85c00e41,87db0240,547ff665,376aebea,a24e5aa6,67d477f3,c4d3b914,92405390,d255ccfe,a6bc7dad,4fb1676b,c741e530,cebdaa3e,669bfabb,d1c4780a) +,S(89c47de6,84e1eb9f,a5828e65,dd17a852,7226a75c,3d113102,97f5b8f6,5b67b210,970bc229,d60b00a7,c2354a70,37ec8569,ad615faf,ac77ddab,f5847a09,c1fa57ea) +,S(48ea67ce,db716a95,6b6066f1,e5e9fc71,5994a4f6,f4e2cedc,bf0c09f,4f8c8fd1,513e45eb,159f9865,5ac821d0,e18f4e06,fa3cb8e0,9d45c3f1,8d3c3bfc,48ff3da) +,S(c5ae6651,ded2c479,a3b6c9b2,44fa35f1,2eb1eaf3,fc78b529,42ffab7c,4e33a1cf,ae6ad807,435d4a9e,e8bedcb6,3bc804e7,e67e9418,6494bc8e,384b29e2,31af8cb2) +,S(24e485b6,7c27af76,e18ed116,90c9dc90,73a0b80b,e93f5381,6669e2d,3c0175c9,fcb183d8,696805be,789d83fb,a197fd24,996d3542,b2f3eb5a,c207950d,f9c079b9) +,S(3bb47a19,b1bdc527,a8fe262a,ecee2d7f,1e772627,e5cd5c70,eb2a8c39,f1977628,2d10cdb9,91fb5042,905f822b,68846390,a922da1a,7b7b313c,47edaa6,85217fa3) +,S(7d4233a,cd50bad8,71e0587d,e10204f,6013a784,b65b6540,73307364,5f3078da,be85d3d,dca838a,1f35ca11,1333e943,fb498cdc,63258ac8,74bd6acf,2b934b77) +,S(b5d0d791,b6685aee,2f599505,d01bd3,d41d5a1c,531ac7fc,e6c33b97,cb0ed264,47fbad30,413084aa,619d7bd6,62502cfb,9648e64b,e757d6eb,24fd5e2d,6b1629) +,S(bd6178e5,b1c558ba,432a89a0,482585ca,40ea9922,7c94ce,23f5b081,d606c7f0,9cdc6bf9,d32b98cc,73bad7b8,c08914dd,b9a8c937,913eecca,fff72dae,fa1cddfd) +,S(13ca834c,a5f41671,ce7f0978,a310420d,6a82fc38,fcbd997b,88a1e79a,66fb9375,ae32a0df,7f269c8a,744e409e,16ec3d8a,eaac151a,99bdd7e5,50287005,6f48f6a) +,S(96322802,87add117,4040f802,ed5c71c8,5f924398,1ee78480,4f16e5f3,f0fecb6,2d07de71,cfda4b43,44baf838,7933a372,3d536411,7e4c0f84,2b402156,3f9b56b4) +,S(961efbd2,ae687808,bbe275a2,cba1769d,4ca537a4,1046c5ab,ff269c1f,b9477ad1,9d22a10a,294666eb,5c816bf3,c4dc2c44,d7836202,e15bed89,e3d28822,8193251d) +,S(4e7162a3,8926282,84ac4df5,88301fc8,5d91c869,2fb854a3,ffd34c47,7b216ee4,6e6dc88c,d91b9702,cb38cff,2d6a38e1,d512fb46,9d85f878,8510ed97,2704ba27) +,S(6c1f707d,51b1d3f4,ab261d52,6d0106e4,3e0a5b1c,76a59868,62e9d97c,bc6e3e38,d2563843,5dc8b102,c8f4ee13,dc345f85,289cd499,9bcfbe20,1bf3dc7e,7dae1f74) +,S(3ae98e6f,49d363fc,8416f965,4e57beeb,d37635fa,4e78d8eb,77caae69,f2201798,ffd95480,fcef0686,9ee781ef,cd2693f0,e6be2e27,f207411c,39a18465,4d2c3cae) +,S(eaf94fc3,fae4eed6,35382e91,2cf963da,2bbbda8c,3197e522,e0054cf1,4cdcd5b8,a838a439,3d4bc0ee,a57e6235,5dacfd97,7d70afc9,16e61209,10d13fad,7c1c22ec) +,S(7eb52e7f,bbf5b802,2fa6d66d,801c3632,2c195b6a,4eae4050,5295612a,a184e2c8,b4591e5c,c66521e1,b991f63f,456306ce,cb2e7568,5227788f,a2e9a75a,bd58b384) +,S(d22b8dd1,6ff24603,5fda0ebc,77129644,a8469373,99b2c7a2,60d8e985,d4f2a215,7a9a092,e8473776,6718e2b3,9068e163,e06618b1,6d6bc046,b33e2d76,8649611f) +,S(8f6eff05,f746f0e0,9b328ec6,2089e575,ca64175e,d950ae4b,c67a7ce0,83afa1b2,3681243f,ca51a6c5,7ac92100,f38df1fa,d1093fd6,ecd53231,bfc01fcd,89e38305) +,S(ac9ba060,ff520335,9a4111f5,c8c536e8,e27a79d7,33528ef7,9da7b21,36243a07,2ba3cf76,3dfc0860,ff3333bc,e660ebb9,c4e5a988,909880d4,1ceb4219,89f23f77) +,S(d6896830,62bec27c,815191b3,4addf36a,cee1cfe7,475d34d4,d83a83cc,6dce3992,9f038f46,529fb86,30b19b08,db11c630,70593570,70bc51b4,fc1ced24,f43fbd00) +,S(e815019a,f6923eb7,cf963f2d,476db569,bb04cc7d,78a0bbf5,3b422ee1,caf43b70,984c16e6,593d8642,de871694,800ca14a,a103a61,20b91c17,4e06567e,2d731c95) +,S(3670e86e,e9aaf036,40136ef7,3344152d,c792c8d5,a064c0eb,a511e14c,41d6f7b9,eac7dcca,e491cbb7,cd27a522,a7db96cc,7d300c35,7413433b,9bcd430e,152fcd33) +,S(3d03f819,4802149c,c6428aad,851bd879,189c557d,cc9ab1ff,8e2e4cdf,f0723308,1f56ada,27f2c923,27ed2fe5,88d8736a,fb68259a,1d5b1c14,7f85669a,eaf47615) +,S(bf2ac011,9e417837,d4815c9f,74351869,4395ae40,77429013,7aab32,980748c2,17a47bb9,6f7a3e7a,31b5a8ab,2adc9fe8,98fd94d2,9ea7c3b4,a5b6c5bc,9c367ac9) +,S(c72eea14,ef09c0e6,85c22840,95e73e0b,6aafa64f,9410eb0c,97f6ad4f,64dea571,9a46c93d,256f67e4,1ccb609f,4ce94390,df9c91,38a9d2db,9b993456,13346031) +,S(25463446,6da168cb,2d816bdc,3c9e3a43,7ca3463f,8c8a83f3,62704996,c1bb5b96,3d69cc73,6aca2a,cb97e1a3,cd57be14,243e458b,305df59b,3e3a67f9,fdc17b6e) +,S(b40dbb03,7062dfd7,7151013e,7cb0a921,15096a04,c39f7e2e,66188aaa,368c49d2,34923fac,7b1a4570,e824c3c5,2edd775f,ecf93573,2198f801,8f617db6,474fb519) +,S(23fba417,ff084b42,afddc4a5,c070305b,553ed7ce,1311e5d,4c1f7b2,772c9aeb,af4a342d,f9346ead,89b3caa6,6a3f187f,96f2b470,c0a26752,76e895cf,c5ca4adf) +,S(2e7ecc9e,d4f21af3,a3118799,d1ab7e3,a30d011,edc53e33,93dfdc5,6e80927b,b3959fdc,f6c4876,36813bfd,e7e83b4d,7ee0f1c3,54e0491,f3195b4b,aee2df72) +,S(1c68c34c,8aaa0f2c,7daa215a,961180af,3938599b,1324aec8,7a1b3841,710db2c3,d8d68179,71acb598,5cceec45,fc5a754e,e002d09d,4be45e8,ab6d2bdc,ad094b24) +,S(fc0ff082,ca6708eb,9b9294b6,fabef142,2cddb5a3,611dffc6,f06c05e7,f1eeddea,6f67fbb2,df22611,e2f1e796,c67d6c3d,14b17f98,2b6e39a2,7bef257a,d6955b70) +,S(fa683ae5,8dc85748,1a7ddedc,708865b9,267e9fe2,e485a243,1d005e47,64130548,4d9759ed,76326207,891a9649,3b4d2307,b9694fe2,c15e2327,a79dced,db8277e2) +,S(3cfead76,5ef36c3,fa9903bf,6d43cdd2,46ee8fb3,3fa1d13e,42fe9818,6d299009,85a18ee1,da24ebc7,3dd87aa3,ca1e7565,8f868fec,50225e2c,d5b5480e,cc0ccd49) +,S(487fdda7,364dacf6,2fcec7a3,fc2dfd27,c38079ef,d48f0220,85c62746,2c8ac658,1479200c,b06440a7,186a946f,83a137d5,7e5368b6,7ef8a66a,9540a131,e4bc9b8f) +,S(f3e413ff,81c2ee72,74c079f3,451f41c4,bbe1e51,f7c3a1ca,513392bc,9edd487e,46544553,79a33a0b,13fe5904,504cce47,55d0e2e5,6c4163a5,14d5b902,906caf54) +,S(d93692b0,53ad5194,b70b9be0,1dd80926,e2c93754,328b3eb7,bc85c45c,63e6258d,7221837b,3276bd2f,9ba0981d,883cd68d,97d2ce77,9dfa1073,d59b01e5,df311ec6) +,S(e85af4c7,42fd5424,2964eb26,b531fd77,550d3b2,eb64bf39,e97de203,ffe2d28,8368322c,e40ffca8,49ff1a53,76cacb17,98fbf4c4,38f58690,54dcb642,f805b9f1) +,S(9e4e35a2,d913a2e3,bc931c59,298ef6bb,3893b086,ee40c978,430d8436,49fce4ab,ccca94d7,d4bad95e,c15b19e7,9555579,d47cec60,9f42112d,3d992035,6d31f7be) +,S(7d72793c,dcd78afe,23e8b000,41d67983,6528b1f2,6978e262,4d022416,7ac5e741,1189804a,2558ff1f,63a7ee1f,ad5f8ab7,50a412ff,a83a9783,996e5f26,637100fa) +,S(3b8dd2bd,ca65d7de,6a7c55bb,47dd5ef1,5ce6f533,96ab335c,84c0c9a8,4e06a7da,2ac78cf3,e1baa981,b27dfc9f,e1b7cd2b,1ed4c37,f96af6e4,99bca1f7,de62aac) +,S(128aa84b,3d920356,db64bc95,b52d4c8f,3054cf5b,22c6039d,1d21ea60,b2274c44,5a748932,6a98019,824a9d7e,cbea2de0,5ccbd9f5,a2cc5dd3,ee0b3dcd,a92e8758) +,S(de8b04b2,c761b876,4c41c344,a3b57c41,fb62e6b4,ba25ab19,8fc2ded,2849e151,134ae148,d89de734,a222b656,b878fedc,886d5928,fc6bfab7,bdd0a74c,3753f1fb) +,S(f643025f,9fc3824a,6ce70677,23475aa8,8df24d59,682f5a6c,b18b1c0d,5e297017,24eb7c8b,e3de50a7,cb473bd8,81db3515,8f9484f8,8574af66,a15f920d,3986a049) +,S(ce2e5454,54324680,7035594b,1aabcf6d,5d8cad20,729a787a,7e01b61b,106fdf19,f3a2e5d6,745a16cb,3403a768,c1de8f73,cd26388c,c10f296f,f00cf9f5,209b1555) +,S(bafd293,dd071a21,25a857c2,6acc5afb,ea79093d,3c9771c3,cd3b875e,b74b3280,2d56802f,b8f26950,4adb2a51,a91ad2f0,d1ee6501,f8c9279c,6a27b524,8dddbb70) +,S(10e0909,5dc7ae30,9f1afbfe,1bcad71f,c66489ad,56256c3c,a648f554,c000f414,47a5a7cd,968dd158,e8436399,40c30179,3807713b,c09fb0d,83c6c851,c6b7029e) +,S(73b8149b,4e7bf050,b6cd9f4,93c85bf7,61062329,2dec76a3,2d7054b0,c794da63,44cb915f,b6813c71,dff3830b,ebb6888b,76312778,897903f1,d9988c37,3c362bbb) +,S(59a5dcce,9773617e,73c529da,6015ca40,bf923956,339a366b,84a69e23,d0a60fd4,4c62abdb,c4453ffa,2b806a6b,b823fbc1,59f57f23,2234c8da,a471192d,3081ee09) +,S(1ad2aae4,f571c6ff,1abfd45,35b3d085,1aeabdbd,b3a340f6,7bef0f78,f7afa954,1c394b1c,94539758,85d72498,b36a3be5,56b4f80,8ef52977,b0157885,649549b5) +,S(2403f66c,a6a7d60a,254b51e9,32cfb700,f37ad73d,193f25df,6024bd51,d0f337dc,9ad75d44,24517aff,7df86c,9bf4f315,cb40199d,4a2a5d5c,74044c4a,9c79d69f) +,S(f3139f4b,50dba596,87080a7e,b19bcc34,2b58df9,26576bc7,dfdc8e7,4914c524,fbaad228,ab34e8d4,451cf6b3,a1dbe225,bd46bfc4,8a4bcd94,10c150fc,5636c687) +,S(ec415f8a,81b1f559,714dd790,2441eb9b,c5c7bcbd,e87190c,c109ca04,a3e75149,9b90bd46,d27e0200,369fe995,3b50752f,d00b9472,fd31383a,f01bb88f,b223bc5b) +,S(5e336f17,264a53e7,d0899bf8,6f676440,f83ea0c1,5d53fae4,f19a71f6,998a3ca2,2a86fd9a,8358daac,828d42e7,9c6c0fa5,bf977cfe,56899db3,27ea32fc,cdf09f3d) +,S(98828ad8,a6ee9ca1,37f9ec2f,f0cac84f,5e664e09,68455773,3f8fbab3,ec38570d,ae7ba3cb,e617e9e1,6e67f34,f69af863,3e69c9ca,1f46b182,88126f16,9ec0e548) +,S(d6a7c2b7,169348d5,1d98f0c,27464732,6f67ad5a,4809acb1,6b783fae,36808436,698cc098,ebe430c5,4dc74fe5,dc300f64,7ac0a002,4109e002,d2f43ffe,89fb3d9e) +,S(9bf4a4ea,9fc4b731,5391b653,1d3ad3a0,f0fbaf59,b99f76aa,7807c442,f8e63bef,e69fbade,598fccf4,6f1f0931,f37f3c55,900dcc50,64e54ae4,191796fd,a4791068) +,S(38a09628,aa450076,3826f384,7e63121c,d6e9e645,f6ee0f,8cffb106,508021d0,5460c8df,56fb7d67,992928c7,fd969f95,d29de37c,14c2c9a2,2d60d661,6cb7c383) +,S(dcf8afd8,ee73bc87,c17c97c6,807fd3e6,a9c57a1b,cca058a1,ad24f2c2,6e9728b6,efee9612,3e78cfcf,1dc3132a,fa4ef492,12369710,fa2e8e99,3cc70b48,6ba78709) +,S(9c26ca1b,f52eb7b3,a0d40dc,cf546591,38945c43,41e0c611,40d0662d,1033420f,4bfbeeaa,ece9f2e,e11cc672,24749c3d,e12be6d2,d3d21d90,ed742d,31541ec) +,S(2209194a,6a3b76,1ddb2b1,3bca12f,3697248,4bec29e3,102d7734,9832ae6d,7dde1b85,cd00a08d,38035f68,fdef0576,c458476a,93eddfc7,4bd4927a,cbd64543) +,S(6ffff27c,ce5efa3,a8f8af72,edcfc736,9874abf8,5d15e1f4,cc71a186,9a7a29f0,27a0e163,bcdea297,1abe52a8,a92fe191,38b839f4,67772c83,81504328,fad94a2e) +,S(34e91b7e,e2c5f407,8a9d1ec4,7e2b2c02,1b8480b4,8c3b6e47,19cacc36,b4250382,8d60947a,42d88728,e0d67d2e,e9a0559b,55cf3887,92c733a7,3ed50b25,3706cb82) +,S(3b2de979,9106333a,98504128,e2135e5d,7deae86c,1c921c58,529aff14,12fd62ff,4ba40985,8c5b594d,f4bf5e81,bd7eccc6,3a7bbbaf,fb32926e,9a47503e,f031d86a) +,S(fbd44acd,9e593ac2,12fd1f64,c4e18d31,c3b3fffc,ae1c88c4,6aebaddd,ac608b2e,9f4feb5f,2ab68e29,ca64f458,d162dabc,7a05c552,2e38c4cb,74529e3e,41d805d6) +,S(d21c3321,bb6ba2aa,dc0cd52b,be68716,864ce1f8,44107374,c0481c0d,91729b39,2b51f18,7b95725e,f74deb00,8e9d96f4,f1a9bbb5,c9aa28fb,275f700,bd964566) +,S(ea2d29,f85855db,78808749,9ed79c2c,614406c3,adf64663,8756b60f,16166578,33971e79,39faeedf,15b14607,37fa7112,7d6f49aa,fc423f63,783e808d,1fd10369) +,S(2a1a6709,301ba6ef,c5ad4958,e29fa73a,caea18e9,e01214a9,65291977,8bec874a,56c971a8,d29d6641,9c05fcc9,9b0c0156,a1ebd007,bcab2cec,b9e920fc,85f796b9) +,S(aa870dd5,6434af8a,36d89551,a7109cac,c1d0c5d9,f5e43630,17bba88c,579cfb6e,d1fab1ea,cb5652f3,cd4d5836,82aa3cb,3b1b6854,c0ec1157,41486028,73625dd5) +,S(e979a3bc,5165f53a,60042a1b,11e8062a,e74f35f2,d70aab2d,b250a4a6,f4507507,4de86928,b9dfb2d,8509a1c4,8efdfbd7,a5432933,e3f12789,cd51ed9b,b967ff1e) +,S(620979cd,f37b1cc5,b1fe3e01,f761b8a2,ffc29bfe,8afb7cae,7ded5cd,37f97829,cc971616,6ad43824,4c6be489,7cac0b95,afe5ed6b,11be673f,d67f0d89,6d58f7d8) +,S(90a5df7d,986198fa,70152c7f,e2abc14e,2c80d5e,6b75b42b,aa042e03,f3aa00b3,77e0ad,2f3e1eed,472a543c,3852925b,327e3eb7,aae59030,2d7e12a7,862201d5) +,S(17802140,e10d8be8,ef210b69,b7fa1afc,16a85d9f,ea1150a6,c6e5e234,cf638446,af4982e7,fdcb7a8d,b6478b54,a5bd7cd7,c48d1dbd,2a3d003,7e87b6e,13c9f5f0) +,S(1f2b8d3c,fe515cd2,53f66b0d,59fc51b1,4cf75ac5,d9c7b4e8,4c75d92b,f0380b8,6902b31,19f38b04,5b979f94,cc140481,d4e6f7ad,b3efe12c,4de1bfcb,c71be72a) +,S(aee51eec,9e5dedb2,1619d114,5594ea7b,27e21a4b,37accccc,d5fe522d,2e46d29e,d40ef18,86725504,fca42c2c,b8b80dc2,c1028b71,1bf3fb18,9fdd579d,f7f0ff8a) +,S(40fe6d08,b714ee12,a4d643b4,21b331c4,fbac165b,d7cd88fc,ce35a873,875bed7f,c32f1cd6,3083a976,6b7dd8ee,7133831e,6796709a,c67953d3,4ec5d8df,922d2743) +,S(5425c555,8a6f9068,946f7075,db347e6f,cb6c723f,c5ff829f,1634fb2,13b3c820,c218eba,db4e3ad6,e41a28ba,129a0c1f,8626ae2a,16839b77,ba12257a,a6aa2318) +,S(83663c0e,f024207e,16ba74c5,ca534d37,733a7dfb,b2d531bb,21a28243,d0572a00,2699a48b,dc9af87e,bf18c9a0,929359cc,d7f2f137,b84fc070,2bc3497f,69c83d45) +,S(bf931d61,e72f217c,3b820b63,282f5d4a,c929134,efa06fff,88480f86,f6247535,82553f48,bc40dc42,cb8bb098,ecb84af6,5cb3956a,aae7bd0d,cfa9e181,de93c21a) +,S(1c6e0876,3c2242ab,17e2885a,537bef4,e8920782,9c573d00,64fb83e4,910312c1,b7c14efb,bea753a7,5d8a597c,7f1a716f,8ae4298f,379aa64e,d070ab2c,28e66185) +,S(9a2cf62f,9eb5810c,31b27614,1592f201,1eb158a,3d123610,99af0b77,7d42c0be,159ac59d,728d1c49,843a0207,e47d1cec,7b9b773a,9ddaad52,3ff27d78,d2767d7f) +,S(3596950b,393a56e3,443c3b93,b4f8288a,7faa8d74,d26cab37,dd7a5b4f,6a9e183f,f99bbbdf,c566b3e4,e65dd63a,15c727a4,403cbe85,202e45f4,ea5d3462,173babb7) +,S(6f556cb8,f5da812,24bbe628,6dc4e379,ec12b124,21cd95d8,6bb1d580,a13b5c37,eeee3133,1dc89e57,48fdf10a,1fc0693f,1c09aece,aa27dcbe,919d60f7,4748d656) +,S(b952070f,fe60bf94,cb14bf68,b37e3e54,bd9b8063,ec8cd4d5,20408756,bd318bff,57996eae,d38f066e,cb3f8113,aab5e4f7,f322859e,1fc075cd,69ad1ce4,3fc48ff9) +,S(dbecc166,8d94b2b4,8d37c133,26fffedc,3e690b76,87563677,23352ac,1eddc2a5,f124cd3c,e42f56d8,a7588145,e53931e0,ce8b79ca,ba5195f7,3dd861c9,9027823f) +,S(12dde570,aae95b1c,7cbc2da1,ed2d936,bbfa5155,f61979b3,e67057d1,5fe5e1db,328711a9,c30e4455,e2716e60,3bedf4d9,8fa25d1b,e892ac72,b5be17c2,b25ca311) +,S(64bb18aa,fbfb7def,3493c920,d2faf9c5,57856710,766b0bea,275db46f,f8271282,717c28ed,e9284844,49cd0db7,180cc5fa,20ba79d9,41c979bc,c0a8f274,3e2e2901) +,S(a798f4c9,bb3ef48f,d2ba3df5,2b040611,d0d5532b,9134aa28,e21b5585,d2379ee7,91f903cc,a4628477,b208bdba,59ecd246,bc50be70,34620a44,b55e0e9c,214e563e) +,S(7bfc5902,58f80000,82946c5f,a1a352aa,808fcc59,4bf2ed7f,bc6dad3d,8bab00ed,17b5dde0,3bf6a814,efbed180,3e5f1950,59499cc7,13e727d2,405e0748,2f912cd6) +,S(23bda819,978c9a09,864a1c53,e0fed0d6,ddc18777,b614780a,1c6fe08e,c35a820f,aab57ee2,7d226f88,6e55b8a7,c4d7a245,7badf96c,9312906a,3efe2cfd,3292af5a) +,S(8f649152,54696b2c,1804467b,e1619ba9,d37cd874,88db9418,1259d69e,135e1455,b05b39ff,241ac0c7,7e2fad78,da585b09,c98815e1,b368040,d493bbf1,3ab54ac1) +,S(177ea3c9,e592ca96,e9e0ef4c,87cb00a1,cd51ccb5,1e1d5252,963cfd08,77f30331,57185496,db5e5971,24e55b14,1042ef30,99f206c4,67415318,ccbefdb3,b18cacff) +,S(16042996,9ab25db9,e4ee4231,7497a607,360bb1fc,96e74d66,cd87cab4,44af2f36,1dfa3d9c,c3acaa95,1f7ad037,bea4c20f,c311a8d4,c2ce9cb0,bd30078e,b0ff64ce) +,S(10210453,fae1b545,de76c4a1,4b6ea5b6,172ea157,1fa60696,25753231,2630e29b,ec8aa759,5708f292,72e2ebab,eed6bdaf,955b27a1,469758b8,44c2668c,42acf576) +,S(659574c0,39345165,e35deee5,ab4c3b09,5b873ba1,fa14283d,6bced3f1,d562abc1,1a8b17c1,bbd83037,b20fc2ed,495b890e,526461c7,8f0b8d61,e94a35f1,bac9520a) +,S(a8a00f02,174b4d3b,9ca825ba,88cb1ec4,4c188343,5478a00f,38025a5d,1e2cfe58,fdac00d9,55b6872a,62a36dd1,cf666423,b4dd6b4f,4558cca6,d931a1b1,1e42561f) +,S(3ac8f67e,b4c2c3a8,2cd90fce,f612ec7e,7daa1072,6e4f8da3,57d9ab96,56e30414,15f71b5d,17dece22,a696fbf0,2e360226,bfaf685b,6575fb99,68fd52fe,7a21f9d1) +,S(87c56593,9fc7bce5,650e57d9,37e77642,a1ef510b,dadd117d,2732d316,a4f2ce19,59908fd3,e2b646ea,210606ed,c790851b,4077142c,ec7733f8,613dce61,3431570b) +,S(6531e4a7,f9cbc2f3,f0448bb7,f8250542,6cf5c7b9,d4a1ec6b,80098799,d5e43101,622a2201,f3c0f766,6e81be2f,22f1ea60,f4b45807,6800fae8,c353c283,b6ec3d7) +,S(e2a5b419,cf421b15,859aac6c,9beaefe6,29293f39,3beada53,e1ae567d,9bb7cb34,3c20b681,578aef9b,138f852e,90f49526,6d30f3b1,6ea2d3,23dee943,1af4a5af) +,S(d4e9df61,35cf81d2,21003bc6,e167b6c7,9e912c1c,2dcac775,f7d9d07d,6ffc7334,c8f54f41,513d7bde,3055c7f4,8436c812,898770da,754ed9ac,d6eaddfc,a80f6c21) +,S(b83ec734,10a1989b,988e2bfb,a46a421e,dc3ce47,d549d838,8970102f,98a6943e,4e0274ef,ea2966c5,200dbca,d8090f78,98bc66ea,44164fdb,31507ad1,e7e5db5b) +,S(ec57668e,12f0590b,e99a75c7,82c02ef9,88354f47,522c114d,bbdb9591,238d3eb,2b3c508e,81a3f696,389a5ec5,974a1bac,a572c042,69ad2709,25001215,c58ad7e) +,S(5acca76e,7578cb86,8d5ba7f0,aadfcf40,5ca4cc52,d778712b,785764a1,2afa01bc,7b0df4a4,5e048fae,65a0683b,ea0185ff,f867a578,179c153,5fa93561,54138359) +,S(bd563b91,6419f92c,43a7c2d,7042fa71,fd88e5e8,41115b5e,36a673cc,93de4e07,4ec5b773,b35a5579,b7c729fe,1cde3b32,ca34f97e,83b989b6,fe756597,3cbc840a) +,S(a070b055,839d93be,2b4ca25c,a4a6b133,5ef7d09a,268bce7a,fb1406c6,42e71025,d3fe8577,1241be24,ed209e8e,b5b28ec6,e3a0bf52,27f36036,3a7325c7,5eeb6acb) +,S(9c50323f,c758663,346c5863,84d5aef1,123b4338,eae00ec6,86aef2ed,e19b2f06,1dd9442c,cf588e6,6a3cebd7,bc68f2f,6f270d7b,bf01f088,a49a5ce6,da430229) +,S(90fe8f78,166e3f6c,2d19bd0,685fa2d0,1f6bf06c,2ea220ba,cedb0f22,ac9c558f,826d63c1,60fe3875,9c5887c9,cabe8f93,905fa1a5,e87a8272,670cfaa,ffeeba13) +,S(d2f44fa9,b704491e,69488c44,cc8ccd29,6addc630,2fc66900,1703afd9,a2a5d3b9,2de1d619,247636dd,ce1de2d9,75f14515,ec5807a8,c7c0cc4,5c7d03dc,fc19352b) +,S(17f1ce71,9e3dfefa,106e95e6,62786729,e8ec2bf6,25421ede,ca71ca14,5782b23a,62b51d27,74f514cb,5452cd29,e3907a7b,b39a9b9e,400d78bb,f6cca78f,cfc1aec5) +,S(5b1dcad4,5974f0ee,e99d7c23,83e48585,24428c94,daa956af,cd692c4d,5a63213f,6958ca48,f13e31aa,c52e531f,886da246,5ba713d4,748cf6e0,de16e0a0,366c33b4) +,S(ad284e67,a0682585,f18be40f,e966b605,8cc787be,c265606d,12f202e9,31f3067,c86ce860,ac3c3955,28321cb2,508e4da5,abb4dcfd,2844b95b,ede54ce5,b17e45b9) +,S(9ba71712,dee6f0a2,7352cfad,59f6c0ff,f133b1b1,37ecf884,a537b672,a4275c8c,b910f036,f906a419,21fd37d5,5e0273a5,332edf68,43dd8afa,43070542,b0849b40) +,S(cfc757d5,171c9d6a,ed8b9123,a2b4a405,d8e869fe,e80aebd,75255454,ee6319a9,43dc370a,c2eb8fb4,4f78940e,b41d614c,ccf2cd7c,c4f324a7,92ba37bc,7e48144e) +,S(b8288ec3,2e4a569,27df3e13,6e81498a,bc9a52af,80d74bd6,c85eead8,85e0c49d,a0d53c40,d2234ac2,df69605b,1422bd1e,4a1d77db,fb0d7269,13de63bc,a2f96078) +,S(3808cddc,497c9065,cec574e1,3b82a10,fe2323f6,65a99df,1e724221,3eeb9a79,eb046225,eb6aeac9,5659f1fe,75dd910d,2932cab6,9b4b810a,d83e7681,e0c32907) +,S(a1620bae,cc99c311,7b3889b4,7bca5d99,4ecfd67a,ad5a7461,646e55a5,19e46398,5cc4b5d2,edc5f7a8,54cc3054,1c7ec571,e06c59a,52bb5cf5,5882ec18,1b07c0fb) +,S(f1d942b2,bff74aa7,1f9cb411,91ee85d,e6955802,4a4d46eb,53ac02d1,32fefa93,19a564a2,8352bc48,a8dcd932,50274bd6,496cf488,6e2ba390,3cf91631,453f57ad) +,S(1a4e3836,a34db30,c47ed6d5,9ba6fb83,fcb7a5a,a0002ad7,1b93b154,a5fd566a,745e195f,d94900b0,aee3c5f8,7c6fc62e,fdddc18b,984900c4,20c77ba5,4141cff5) +,S(af37075f,866d7aa5,9371a08c,1e7aaa5c,d23ee51f,54428fb6,84c09b27,93b432,b32e8869,fbe53ef5,4250e803,facc93ff,a100a84,becaec5f,872d0548,da4ae9ad) +,S(88e39f4e,83a0d6ad,a1e01ac8,9021a7ea,fdd1f9de,740bc10a,4d572c46,fcee9330,a14f6881,bfaf691a,96249322,37522174,e8a17920,52da7bec,a6c77d4,5fb8a357) +,S(8e406574,a46e56a4,dd4cf780,9a7ecfad,5a1f9225,cfc2fbdc,6b7bfc84,a5ce14fd,bdc6108e,d5616bc2,3ed52c5a,1314642e,a9272707,20f00be9,62e48945,3550f167) +,S(aa31e1fc,118e00c9,8b8f561c,479c6427,8676356c,640304a8,3b687a34,8ad4a091,31c95ccc,2520c0db,7c7440ac,7e640be0,7a8ba4d9,c0020b1b,f31418fc,98d9eb17) +,S(ef278702,becf4f15,ad43fb6d,d0114077,d9f8bdc3,ff4c78d4,d0a2a15,8fe160b,377dcf3a,774d6416,58bf108a,87201b9f,f28c70fd,449a77f3,966ff441,d89246e1) +,S(d1903199,b9762761,fd02c4da,99fcc503,ac15332f,4be01b7f,a044c5c3,f848ebc7,662ca3d5,9ff2c5fe,a75ad64a,f7044a94,60abbc25,defd0a3,aa6b0e6f,2c7f4f3d) +,S(682ffe36,6838fa12,827ae055,7e38c12a,bb571227,47643f26,9cb9f1bc,922b07ab,4531b021,2e8fad86,6f6f67fb,d8eac752,1a360968,f0f9792c,a4568a55,855924e5) +,S(418fa3e0,b32be1f3,f06b96d9,728aeac3,3294ea8f,16f35139,76b30801,81d8e833,dc1608cb,68bb0480,859c9983,6baf9558,9451022e,b9966e0f,498245e0,2183ef80) +,S(e3f7dd7c,f5898b7b,174cd809,5c7c0890,4188bce4,bd6487ab,e974d979,f7faec2d,5ed5ca26,77d3bce0,15a6cb51,9922a55e,9ac1adc0,61bb0774,503e79e8,204441ea) +,S(810ecbe4,f43814f4,e658ce9,234d71b3,946556d7,2ba9c3f3,6fa04b,4dc25cf9,5fc57520,81397434,e395a752,560a8a76,252e6eea,b9ec067a,16befea4,1f1bf1ca) +,S(6dc50f0d,7e9518ab,fa16bcdb,f43ecb2f,745d5ee4,7269225e,36811819,6542b7ff,dfd5e416,2d596f5,b44602c2,20a87cfb,77473aca,6dde260f,856b3295,527bb87c) +,S(d39c9858,5ba2a859,a6fac25d,602c8e1,fb205a88,7aaf628f,5d1a210c,bc648fb5,6e92fc09,9df932e5,1bd0c6bd,5b6567f,61a1e8c3,93d69add,111e9320,661ad724) +,S(d7fd8580,59c1a86f,1b81c05b,ee63bda6,8ca93c4e,5ec99e91,88d9c7f4,40dae0d6,ceb56f19,cb3e5b39,64a4c58b,5cbeddcb,c736f0a1,8a2f8f3f,f0758f24,525a8fda) +,S(2e269d93,319a79d7,513e6f73,918638df,c4b1b7c,4c19ec83,b254d780,dc45fa87,650b6846,4e8537af,583cfc48,caaff61d,f31dc67d,5a48e0f8,5857d7c0,9bea1d70) +,S(19f396b7,7147937e,bef30096,44b292,2a6e3c6,5b5c929,22b73118,7120224,4751cc23,4d49e926,651a9a29,c2a8a55a,f7e4b25d,9cb4bd2e,83530bdf,494b131d) +,S(88f843b4,e3689ba0,264d6d4b,4d310afd,85de2ea1,6fbe7275,d33112c7,538a7c02,5dba8024,30d31ef1,412f2310,3ccc5951,66e903a,55bb2a35,8be1e715,27fe45eb) +,S(b1301f5e,1474083b,3828ba5a,837efc44,21990da5,275f6b1e,bf773b52,5ef14a1b,f9fa0af5,b508ca7f,2345d06c,5bf1e5e4,907f2b19,3681837a,802259e7,7208864) +,S(63bb3295,b57ac21c,4b96ae49,92b8f3c5,7c23743d,44ba348,195c5f58,d5360bb,f5e6a98,96683293,af6b9ded,f9f163ba,15b44017,120c61bc,c9e51758,f3ac793) +,S(dac9f722,7d0c012e,e3e1ce88,a99cddeb,9a23979,14c1cf1b,915dd41b,8ce27687,85bd90b7,7f2917c,cf1ebd47,3bfe04df,386d37de,69893cc6,9e79ae89,2255a12b) +,S(ef05aacc,a8082759,33719aa0,e0958f6e,4be6a6c2,3458f243,f84fb2df,9aa422f0,d6006b80,bf611afd,3f1ed523,988b3e8f,d44be73d,565ef30d,911e4226,ae546f23) +,S(dedf3d9c,807065ad,8c1e3714,f682ff86,4f6ae08d,6bc15773,53f27677,ff86783e,7bf6f3f,1f3e5ca6,6902639c,a0b071d9,50dc2331,52f1b47b,5c68923,9a1cccc6) +,S(3db2b461,d18b367f,cbb4aae0,7a73ce9,6c1b4cbe,140099f4,d3839764,7414b5da,515ead0b,a8ba7b25,9f04484a,4c55b532,5686b882,77562b99,21827706,a036a142) +,S(5516a03,3da8cc3e,28170010,5e8d57f3,daf5bb84,596c040a,3d2ae05b,41cecd4f,6bf44084,f0ad14a1,f129a267,e13b0717,6d2fd274,2d4be75a,2192e54,7ceeebf1) +,S(7bd86d5e,6fa18e26,cb0b6e2d,faf2a4d6,a784e831,2e7168bb,8e660e3d,92514c3c,9b634094,dcf4ade0,eb49eabb,a26334f1,7770bb94,b776de46,64d847fb,f1574afc) +,S(a24a8b40,d63c242c,3dcd2513,fbee3c04,cc15117e,aae40daf,b39c3373,e6a83bfe,49163714,afef59b3,b503eb73,ee091349,e599c563,bac4aa37,13d7a6d,6f5271a3) +,S(acbbcaec,8b01374b,454208a5,19051ebd,e5128307,785f7b25,706642f7,775a932b,102283d8,1bd1e9e7,e5641b8d,a701f51c,86047d76,51becfba,89478d8a,a6226572) +,S(efd5654,8f37a094,19f9fc11,6d818523,c4d76725,860d49e4,a1cd8434,a0cfda99,d521204b,da2b9db5,dfa47c9c,6ae4616a,52b3caad,5440e4f7,f1fc41ba,766bc180) +,S(15600bf3,ffca622,a163244f,47789725,b4c112b6,e3d7652f,fe829a6e,386041c3,b1a1ddb3,e2b0e170,8cc9e6db,13c7b111,93673cc8,397d9b59,5b4e8dea,a39cc5f7) +,S(8d14cebc,62f7cd8d,fc60c2de,d144c76f,55d9d6c1,be5380ca,1e1ecefc,5a85cc53,244bdd67,5030a8ec,af876f5,99a34f98,ef7388cf,e6705734,540f57f4,15641220) +,S(e3cb7328,29c6d09f,6ee940f6,5f30c79,7dbbc26b,b8b8c860,f6e07088,a485ebaa,e50a5c44,6768827d,ddd57e18,68064e61,51c8951e,e4cd920b,b664ca06,67096db0) +,S(9a18212d,45364ebd,3ecf4d76,3efcc66a,ebd17b7a,f8bb7f65,8679664e,16888e47,85297209,abebf492,ebeca275,bdf3bd2f,987d1e29,6bcee299,9d6e59e9,2b890143) +,S(43366191,859bb3bd,5b44f1a,d9076ec9,5439c082,c99f70d7,4363117,8020521b,9dd6d890,16666a3e,6bd8c0dc,76cc9792,fe5d76b8,c49cf9e3,75e031c8,bfae2556) +,S(1b77e51c,b11e514,29955ae2,37659c5b,a8050ddb,685e5b74,fbe38506,33bf9358,f198ea65,1ed4a743,a14fb905,fd0bfefd,843bb00d,675781de,5fb1552f,c7f382cd) +,S(7cc6fcc5,558cc6b7,156a62d2,e823631,e0b95e8c,57fb79d4,b4aa3ff4,9cb718cb,526becaa,c0c84e61,b3fc85f,60d028d2,eb90567e,319bd6f4,12b1a36b,9c3d30ac) +,S(18c1e51e,10a7dc5f,7783d511,6f2c0457,664ca2eb,6541ff29,591ee59b,f9f958cf,7f72840e,ccf4d03f,29ce01a6,725f6b97,d701a935,bce8a2b3,c1e44904,cf98a300) +,S(3b9335fb,b191bc9d,17efec98,77960307,2648edb7,2c427521,34df37b6,f1620c44,ca526125,8239c80a,1ae893b,268d28c2,b02d56f2,d03a8a7b,aca25def,34d6d694) +,S(f39660c7,ba9bf800,381b8ddb,d783dc6,acf8c183,95f9144f,688db8c9,9d7874f4,c5037625,2abd41f9,7574a607,52be4c31,e5ef2874,5e9d80a8,da2ea676,4bce5cc1) +,S(d1d2872e,ee06a4b5,d3b735b1,9db1d88e,cbbf9ba6,89c1e411,980b2cde,e70c86d6,dc5cd630,859fb9da,70f25023,5b7bf2ec,938743a,a9f04fd0,69d1d746,e3ebbfef) +,S(aa4f71b4,720f6470,8b6261a1,ee97bc7c,ee85b274,caf71a6a,1f7f000a,b06a1948,958fa65f,acdc42f6,c1e98f7d,f67ccc39,14dc5e8,d20bb872,32d7c898,e451c017) +,S(85904824,63e69633,42cd1e89,1502c309,d74e1722,fad8e766,d7e8f566,49bb732e,585601b5,5bfef406,ec5f71bb,6bae29c3,c5e77247,befbb549,5ced52a6,da64a2ff) +,S(dc899ab4,89a12ac4,4152ef63,48553ed8,29855449,c204327b,bcce6418,75df4d99,6791a965,65fb749c,44f133d4,b3c9c8d,77488831,c8a99ba9,7b66c9b,43deddb2) +,S(2fd60f25,3e0b4f1f,2589a096,f9a0ea3a,405906c2,690fce35,ac7df791,f106020d,872d52b0,1cbfc3b0,ff699950,5be33b51,64a7054,bb00e22a,9a87d692,dccbe782) +,S(a74830c1,7f816549,cd617b94,c0360b8c,9206b382,6782d351,650785a7,fb71212c,fa928b97,75b28be7,4e340cac,eabf866c,fe7e7299,7c276680,2d211b1b,389823b6) +,S(fd450d48,c59fc4db,e3366b43,caf00c2,bd10045,842311ab,20f8e24c,6a9a10b7,512d1998,db747e39,34451fb7,9aaed7af,48801051,dc8ef756,4580db9f,bad910d) +,S(c0816923,9f2bbbc7,34d52def,79f9f4bd,cbd8c435,d90561ba,fb23f12,f1fcb93,fa00c81a,8c5cc2d3,5f78f0d2,475851f1,73f70cbd,cf2c950,8ebad1ee,b35a0852) +,S(247c4075,9a0e7098,25a5d82,4fad3419,55103052,bcdc7ab,fe4e559c,84a04a66,8da3cae,878260ba,1b95a5db,900f20c,12597187,4191cf21,939ab6c7,fe378067) +,S(fbe3b30f,16ad6608,32f9ab15,2f44076,2f7a09a0,b07b12b6,4375db15,37fa4e9c,98cf3e68,2a914c3a,ee54971a,793a9309,8c63aab3,e2db5389,3f05450d,61b9080f) +,S(79f71ab6,fce86bad,be02055c,520e6e0d,88e98def,d37f2d2e,488bf455,3ec954c1,b5de6a0b,c1745341,3023a650,45262a31,e9264089,8a655b0a,4b3042d3,a9114330) +,S(d190f258,e2e3bb8e,6812da59,606f2f4a,2e3fd1ec,34e2c80a,9d280f5e,e1e9c4cd,98997b49,afec7d7a,26a26f50,9d4948c9,b5ebf9b4,3eef6183,3a2b7a8,6183c267) +,S(24f355ca,c0e00545,f47e199c,3818e76f,534eca88,776ff6e2,54244686,24f0b636,37710da6,5c3afbb4,308d5906,7ad044c1,4df30f03,427ac83c,23b829f5,37d25b46) +,S(bd221461,ae73e639,6b23d269,ed6907ba,330544d0,80342de3,a769d3cc,668cf536,a5f25513,3967fa67,b22dbe31,917d9d1b,ae11a1d9,dc7ab731,26e8f0e2,fbc8deda) +,S(cf0371e7,22194be7,ac5d19c1,1b447978,b38f8a1b,dc1dc3e2,471d4a8f,75d0f6cc,4bb04426,94fe9d55,cc49dd4e,e168b604,564b95f5,99566f3b,9fe2fbdf,16084f1e) +,S(ce21a5e0,287752fd,ae9e04ef,363540ed,f6736c34,266a2d77,b5d0bb5a,868fc32a,fc30fc93,bb5a2731,8b81b942,4fe330d1,878e710e,b9a44fa7,bf4cbfa7,10c7d0dd) +,S(7c95d800,da4720a4,102de774,d585f230,2b849e57,1f42982f,a785bd15,334b4b12,244deb56,fa5b4367,2c39693a,f09083f9,2b153a9d,4829ab3f,ff604fed,a266b30b) +,S(40bce9b4,f90489f4,d392fb93,3f98f71,e9281976,164b25b1,982cfcfe,338d93e2,5a9ebed7,25bf11e8,7bbec766,c52309d5,e2036454,447b8ee6,6dc79dac,7a2a9b4) +,S(f15a2ed8,2c00ed9b,9e7a9338,2d08c46b,33ba7bb5,dc15f5df,4cc29fdb,86f11c4,d02ce92c,e556287a,3acd4115,a190767d,2979dd7c,7a32dfde,cb6d806f,6e7d0205) +,S(4230d263,d5a4a915,cfd863c0,e38514b0,4929d352,d8a90c00,c0ab9ee0,56215932,4b134eb0,51699656,dedc7704,3d5586c1,62134b00,e21ab1b4,517bdc54,5f05fd69) +,S(6cd6bfa9,63327c26,fd2c7aa4,fc159956,1a90096c,dc88f414,d5cc9c64,df6a9e84,6741fda,1f774c52,20b04db1,9ba7402d,9b77eaf5,b8e9e2bd,a000d2df,2022565c) +,S(118face3,ab188a36,581cd1ce,1d434fdb,f1d06f50,1e9a64be,bfed2ea4,ba3f477b,a263037e,c8d5a9eb,be1a8b97,bbfa5624,ce00e852,44828af9,8cfc38ee,1da9052d) +,S(6be81e79,5fd1229a,fb24a395,fccfbb6a,ae4fda11,28f93faa,f74bfb76,c39794c7,edd0f9ae,bbbaaf0e,bd1c01f,af128730,5d5fc5c7,732885eb,327eb21f,62683869) +,S(b9a0023b,6fcbb06a,48f97684,509b8b9b,937f990e,4c3f1a61,27a8a18e,e4c96c3c,e1b25ce1,3e8bda89,ea631d71,4c07adfd,c31fc6b7,304b5e7f,1cc7221a,6597df11) +,S(4e384b06,ee4007e8,e70f22a6,1af73d89,4528722b,cf58bfa1,16eaa29f,e1f2334,2fa6ecd4,8faeedb6,240db0d1,14c7eb3e,63540e31,788f5f55,98c52fd2,538ef0d) +,S(14c8267b,6462dbfb,6ad45cff,58d9b22e,9fb0de4e,3d026999,9357acc4,d254ea52,86da149d,e14de86a,20becddd,e33e99cd,158a50aa,2da085c3,cf675eac,224b292d) +,S(42d0c7fc,21129bdc,97318985,73b6d111,568005b5,cbabcf55,c1828340,4f5de376,8f83e957,92880a3f,dac6738,e65ea463,1399daa4,defbd1e9,41a5586d,a42f652) +,S(bfb03349,2fc28eb,82bdf9b4,417f02ee,f93588a5,b138c520,77250499,23e9f135,c65872e6,9438a5e7,a20c3492,7a3de7d,85c690c8,b20af801,915585d1,98184882) +,S(1a111410,d04e1278,3cded32,b3602007,7dedfa32,6493a780,999c68a1,dee18047,874723b4,c6b63cbd,d957098f,d0124779,3e711a56,fcb8499a,a046f5d6,36d5be75) +,S(a47aa995,3a999aed,9c1d1f77,da8b736e,6d045d3f,9b32ecf,a6bd4225,fa66cf6e,c4ae1566,4da8e033,f0e3fbbe,472e16e0,70a4b40d,f210f7,3d0a6fe9,3dea782d) +,S(52ccf2b4,5cd2555d,5a0a5765,92b5ca7f,5ffa329b,6bb12979,8f2c10d4,bdf34119,92abe502,d23e9f61,f420e4a5,44e42864,2462dd0d,7d7f386f,ff7cf2b0,b3a5043f) +,S(5d2af6df,77107953,e6221a4a,ccecadf0,a2a8d676,5e720d2e,38c386a3,e6b48e4,5a44be69,80ca8082,5d435aec,34db8be4,6dbd05e9,9b8fa176,45888bd4,2260cfaf) +,S(e0f9b457,e184de7e,7484ad3a,dff4adbc,4dfe508c,14341dd9,d2c4f584,807e3fba,d0712e1,3bc4ad8c,78261681,3d00a237,36383731,7de79d0b,1f52264b,6ea70526) +,S(6797c2e1,d1c2643e,a831372a,abf36ab5,fcf88804,9a01f052,a7930792,acd2a7a4,ab005587,69f8d361,2217de,8d4bf205,925bde,7817e97f,d155fa94,8f084167) +,S(f302e07a,8953b3c1,f0b3796b,55bdf133,84809aa7,3dfe4fde,a0d56ae7,a04c2f26,339d529a,a6c0c8cf,f46682b9,c36390d8,28b2861d,6f4906dd,a4659028,c74d780a) +,S(aa4c04f,b8261965,9254f9b3,2d9e25cc,ec651f79,b710cc3d,bdf4eb3c,dfc207d8,520cbe2a,c8c0382a,23d2cea6,6a18f28,bb87e773,6bf60dc1,cca64a58,9fda48db) +,S(cc4bbc6e,7f4b02b5,ebe6d484,6352257,4651fed1,a079767b,fa53d1e0,dc38b5b9,4be5e0de,c97683d4,939077d1,edffcf6,dee4a88f,f7d42894,c3d50302,70c9554d) +,S(6a4bada6,cf1e123c,e80fcf83,2d6934f5,486901f1,6d3ad0af,cc87a4cf,205e6e79,b79145f8,24d693b3,832c6676,e35a73b8,d8acddf1,681720f6,c8d5ac7,f81752fb) +,S(d7ec4d61,1d440625,367b2c5f,a6904b8d,cf6f0d81,39cc3bc,16299e1b,50c9024c,18c402c6,3e818647,7f15bdb6,d514373c,89d1f7ff,bdab83f3,5267eb0c,daa81d89) +,S(4e21e4fa,4b570b40,77ff6876,a1d7e4ed,1db77d0f,56d35445,178ff508,5b197169,dab19080,ef84f0c8,4919d869,36de1aa3,ca85a1c0,aabe902f,b46b31b0,3b350580) +,S(32aa04b7,53752059,7b4ef603,62aa208a,effa6891,240a587c,e1cae58a,28a6075f,ca649475,a58a3ebd,c3802c13,f006335a,7d203ddc,88bbd1fa,f0787839,b9452f21) +,S(306bcc2b,94214994,e86c7fed,4f510ad7,9eb1af11,b824d897,a1cc7564,9eaafe0a,820c2986,abf17343,35089773,5b4da35c,56265a25,4a768346,5dc084aa,ecae6dcf) +,S(37d23716,1044ed4,b395b044,5d70eaaf,864530a7,fd8490c1,fe2d1ea5,61f4bc19,a6a9da7,70558993,ce38d5d4,c69dd25d,134f37f,c28dddef,2e7edc0,c1343b83) +,S(1f324230,886ef594,aecbe39,2d7a4434,fbb9fefa,fe22573e,9302d3c,dc81490f,39e53099,f25e977e,da860f77,6d09338b,c0e75446,42557c8c,b05761a7,c18537fa) +,S(256d4808,d6dd018d,392a6716,2af909f0,51bfeea0,9ce22a76,6266d1e7,61df967,d5643938,c7d9163b,38fc8072,609bcbf3,e063d78e,10cb8cee,32c00abc,6341df09) +,S(58a91493,ff7aa600,1f457506,624ce8ee,b1c142ca,d49f67f1,be099c58,3a7934f4,bde8d64a,79d5722d,6a96d240,897a7f48,8e20f19f,259fc6a1,e4483448,e0290122) +,S(b4a80e5d,eec9391,8f146b4b,e0d91630,606a5c79,1c4b7b87,d4363de6,e2691f2e,a6ff5b82,ca6fa424,efc00b20,7ea90991,fcd5af15,d23140ab,96da6cc8,bd532297) +,S(41bca570,b4981232,f21ba765,4f23d5ac,27f3bab6,9f1107fa,e3dc5102,6f8dafad,5a14cd59,9b0bb884,10ed1475,8445c49,3af3b7c9,2cc6435c,5560c4d7,832709db) +,S(bcff28e0,bb6c242,a7805142,122848ec,6951940,bb4a2e3,5ae05137,d73e8264,43661933,9ff9f2e8,278ef17,329682be,aa801596,e4a12b0e,615fbe7c,4b24e1aa) +,S(8aaa2f44,fbf66c2b,809180,bdbb4e2b,e25ff178,232fcaa5,a2c2563,8c1ea21c,69dc0de1,686bffad,1ceee711,95831b90,c57900a9,baf57ac,2f34a917,6d33e21f) +,S(930a3df,f84583b0,ced82f81,96c39c16,b9318f2b,44efde12,2be6c10c,70b33dc9,ae802936,2b10029a,a81cfc47,1251ffc3,6b586de,da9c1754,4a96d3ec,31cd6d1) +,S(907cf1c1,92b98461,8021a33d,1c9d22e3,22dc83ab,d5768a39,c04444bf,d4e76df2,527eb629,ca0a2e2,7da96361,ee727a34,97edb8c8,68694871,6a7dcca5,13b6f901) +,S(f9d32e84,76c666f6,29e86e0d,3804eee8,abe1ab26,ae2eb396,b584e4eb,e9583b88,d92f265e,9e6c5f4b,bc05a432,6fafeace,1516f823,3e5dc280,b239fa6c,bfdf7fb3) +,S(94772c31,70e50bbd,9952bc69,44e0007f,3d928cb2,c86465b2,ef040fa1,b4f90d9e,29021913,9326e358,2cfa8ee2,428c4307,86cb2de9,6ea2c735,eb71f759,bab14637) +,S(2b49cd38,8cec8c30,e984d40b,f1409c6f,df7ff24d,36cb699b,5f3c24c0,fcc872fb,9e65a427,ce5dcc20,db83a96b,720f29fd,df643b2b,a192736d,c621d92a,6583aa8) +,S(454f174d,8c344479,9bb58158,423d8413,ce87def9,2fd25a,5164807c,982d84e9,bf324810,d9894da6,1eb1e3cc,5a30639d,6500a453,c14e8a40,78353d42,7ac67ee1) +,S(df4461b1,dc1eaae8,5b4b7fe1,e87753e5,546f48f,e39da02f,f1012b24,58a79a17,ac4fd2bc,af8e0b51,48cc5a5d,46373209,8993b377,becd718,732fa339,95412fda) +,S(32973a0,d1be4c6d,1342b2a1,44ffb36b,81fd9b38,c0b7411a,65b8ccab,cda9161e,558b278b,f507b498,fdbbf73b,524c4652,53a0082b,d53a87f0,75d5a49a,bb601b69) +,S(cb63a9f2,d1a11b08,479275f,e1f0bc64,37126875,5bcd8a21,3481be2c,818c69d6,4949d3dd,a31db2b7,b2d42f2b,4709a870,5094d470,1e742f07,b6f86670,e43bfaa6) +,S(543ae5d,a0c271b8,41542353,277e1651,b7b0f587,a5b18ed2,856c2e07,41c28914,22c999cf,aba6f95b,21f87ab8,2f2edb2a,3dbb43a6,ff413506,83835ae8,bbcd0a37) +,S(7ffa63ef,3df62097,a3b61289,4eaf5bf7,4fb39ad2,9ec63f02,2c6f310e,77268c7e,9d26cd72,8fcbfe54,6eda19db,5ac61978,1b456699,59a21628,2500e5f5,389679ca) +,S(72cc6606,b02943a,5bd9a476,6b24caf4,e0e2f83,ae3bf671,5f05b39e,3436122b,f35ff21a,39503637,d05b744a,77797565,1e290541,326d920b,d5bcbb6f,74b56c3a) +,S(f5f21182,de67c3eb,396055f6,a8f64f5e,54043376,cdce9f3,3cffa601,4a348a4c,1fe09f94,8ad7f78,6c184675,3105cbd2,e0f8be91,f9160e81,9201fed3,3208b3c7) +,S(1cfa62a3,70171431,52fe149f,db07b00f,bd8d7928,e5eb145f,b4ff7343,fc19437a,1efe47f,e41677bd,337451b3,92eddb1c,ecfc19d0,5ef04727,12927d4c,77b2a742) +,S(b6609139,733864d3,abbdb6bf,4b827b2,3861594f,ce9e996,4637ef14,f0fb6849,2e807df,ae409cef,b7be1ffe,63351d8d,8de5fbeb,f3be5069,31befc97,d479c006) +,S(13da7c85,bffeaa0f,e295ce6,38de0b05,1b4aaf9b,d888f5c5,5f74fd60,abf2e016,c0477fad,fba6531e,f6369aaa,be663871,3bd6954a,d1e5df1,269c7208,31cd5bc3) +,S(2abda634,547a86aa,1188b2f6,ffaffb36,dd126d94,18406bed,8b81e29f,596526a0,7db36141,2e96e02c,34c0e39e,1201617f,2a7f2100,d5c3cf64,6dcbe563,e2b25524) +,S(4e161f2e,22785c68,3ac494d4,1e3cc2d5,e6b87be8,bd65e85,8aa255dc,8ea8fba0,c81a4e95,a2cfa101,fcb62112,b60c574c,623b5df6,5a1fcf51,e6bf2936,45d5f17b) +,S(586be2b5,740b0ed6,6f5c5f6f,217766e,ad5543eb,8e983ffb,928fc40,9e76397a,f11acf99,8bc2a25,48799529,9c7ea84d,98c6a525,6cbca56c,3ad534f9,26c6b08e) +,S(a76c4f91,1d0dcd58,9417fca9,8124f62e,789e0b05,91a9ce94,13e0b7d,e7d5986f,6a49fc1e,2b32aeaf,6f291184,3995602f,903c8d76,858fc532,9b3a1940,2c2c9b7c) +,S(15f11b1e,804a6d54,a496ee4f,f3030167,eb510e9c,c1754bd1,d46beace,1211a68c,f8968e8d,21bca271,75a79de5,31ad810,ca6c6da7,72ff96f9,937ef824,8f4fec45) +,S(f0169f41,685292bb,4ac93afd,58b2c239,3985ecd5,16acc8ed,ce46f325,74b23e58,6fbd711e,fd488c8b,43151ecf,e3a42ad6,25697053,1df18afb,68f8ad71,ee9aa05e) +,S(2f241e5e,2596d32b,6cdedc4e,b6de5f53,374e358d,8db78d08,9e772b37,6250f359,fe79f0a0,cdbef5a2,7287c86f,afbe917e,4c26c4ca,512f57e4,ab066d3a,3f7e71e) +,S(a14743eb,92bdf49f,5f404a54,ab193100,26f3fbd6,fc5a06e3,e8c6b33d,1f7a5559,3e7e5f24,b1d0425c,ee5c56ef,1e38098c,6d67fd12,f57eb2fb,1ee76c57,41d57c54) +,S(2d097299,db14ce88,8da72472,da686f67,b8ecc812,5618cae9,2acf6457,a011d2a9,e9cf7195,32f71130,5bae1fd4,ce3a8fb3,c8d71088,df35b49d,ad9c16d8,8734a187) +,S(aa7257f0,d7e51fbd,95598b7a,a994fac1,41aa76d6,318cbda0,20d30471,73317f2b,15e00f94,f684c30b,5cd4a978,c6245e6,8d30d959,a30fb39,834e97d8,c18a1b27) +,S(ae524618,e2877095,d52ffc94,67a081e8,b27b4b16,566e2b37,c8d11b1f,1f7416a0,d0275a1f,6d49a7c9,44a07a6b,ee5d5095,7b22b698,2607f822,8ad15253,a546ccb0) +,S(e7a85ef,ff8b0443,eace4cd8,81d768ba,ef4d93b9,79b17eae,fd237e8f,c9ff660f,4b53f073,8f07b360,7d66f720,b1222df3,eee2dd,ca20f40c,630a7911,a0fe2aa6) +,S(daa96eca,b8412eba,75f58a80,84a302a6,37dd7d77,bc9dc502,a2d083f8,35bf242e,ac3dfd97,a01557af,cd1f199c,afea0cce,52c8e3d4,975cb331,1c817c9,fab0815e) +,S(34dec21a,965b7027,44fa7881,4ff6f782,790d551b,7be35c,18cd46b2,e189baca,ee825c5c,5cc289b9,d7f01b43,4de4f0d,d250f9cf,c22c8d20,a1e54175,9bd23694) +,S(dc2178c1,2f015bee,829f0567,566d15e4,d607c8f3,b2992801,4b6a5607,1e61247d,fc86780e,31cf57ff,5da387d1,c3c25a19,36a263d,f6571de1,d098153a,97b41db8) +,S(6faee1e9,354bebe0,1fb65158,20b7e992,9517cb40,23d49d19,2a002ba4,e4782db4,a4915992,ceb8813b,e2778fb0,47766b6d,3958cf72,f18e9172,3f74cef0,1d2276a) +,S(a2bcc012,4112818e,571c8dae,3cb724dd,e45faa06,d04d7128,e9a71dce,22f300ca,1f594d9c,64ba43bc,11764c61,f8fef5c2,e31fda39,3447e7d2,10d004bb,c13870e3) +,S(b8cba39a,c51d86e7,d83a50af,f5370240,cd7b20f3,81aeb799,f951883f,458ead76,3a8bfe74,2b3a05be,27ef835,39988cc4,616365fa,e3738d35,29f9c0d1,c15eed4d) +,S(56e532dd,295792a6,ede9da94,c43e0b2a,25b72725,333f8205,7a352ac9,7a1991d3,a617e234,18bfdccc,8facb454,649a4914,2f0abd64,f30e06dc,838fd80d,7a141fc3) +,S(4803406c,e4049575,19f5306d,6daa003d,2aeddc1f,c1d4db45,15a8d35c,aa39a6d6,7add51c,12412f4,49d7b0e4,b7df38a4,83151126,49660956,da6273ef,8b53fd5e) +,S(bd61ad65,2e44effe,ca39620,2f84e4d5,d81cc579,2a2390f6,52409852,cd79c459,f3d7071b,8bb18928,1d827f71,ab7b1ad,5289033,ab28d20d,643af02f,a2b4ce5c) +,S(1b543175,e5b6f271,58048588,f81a791b,3ab216a3,578e2f79,354da6c9,5e4ea9bf,67a2e60b,321456b8,5b5499ca,e33cd6a6,d5445f91,eadb5a5a,f0e2164f,324417d7) +,S(2035953d,3319ffa5,9f75d86a,8d1b52c0,e8118ec4,d830d15e,d9616215,cb82d080,302cc0d8,5bc1e667,b160bc8a,64cc3bb8,763066a5,6652a0bc,c12691be,c41d7aa4) +,S(bf2a9739,f65bebbc,90413f9f,d311e095,e7628dcd,d76d25a9,8a4681ef,f4f84035,83932d07,cc950bcf,380cea81,28e04322,26b9a4bf,8536122b,fd055517,e7d3b2b7) +,S(a915504a,bb62b4a8,1288c44,8605e8ab,bafb4f0a,ffbcef23,c9c2a26f,f2cb8557,2fec1059,abe1bf4a,834c50c1,edf0e5a6,2ef21f7f,9da2fda,20989bae,18acd442) +,S(318939cc,fb2eb0f8,30d30079,7e209f00,6e28b899,8aecb548,b3b97900,9ea6aab7,5308df9d,10c7d151,cbcbe417,91b627ad,b7204db4,dbd2e01a,c5698e61,bdbda375) +,S(ff9e4851,d3f0c9cd,818facdf,4781cecb,7f622039,c23e236a,7e4b7368,64af1a8b,fd69f241,bac1c6b9,a52d6dd0,6e7bcb6,4a4a79a4,9c3881be,6ef8c83d,3f462c5e) +,S(497113be,a88d4888,2c98ac14,ba0bd0aa,d3c75c8a,58d374cc,86a7fd0a,b6259cc5,9029d9bb,96076d69,a264d2bb,6fea2f15,423ff1f6,ff47c02d,4699943c,9cbfbc4e) +,S(2b2cdb82,6653f563,dfc4c373,96d738e8,3d1dcc5a,ec5f4886,2d5ca84c,2ba69103,d1985cb3,f42e4ae1,7da33b7f,f8563236,6e2f5c89,b849ac73,afc3a7a8,1d049d85) +,S(c55dcffe,fe63e948,af77c8c8,32cb6c0a,c09ced5,5c338bef,fc27fd21,dc63b6c8,edef9fcd,b00fb62f,cc97c03f,26253069,de6f8d00,c13a5666,f574feb7,fabcab6a) +,S(52a0dbfd,371bcfb0,e2c69160,c9cca2b7,8dcf679f,774c9d99,706d306a,30eeb3c8,fe01f320,781275bc,a6c031e6,d71df467,56473d8a,780fc54a,6f8eb1ae,5640bf65) +,S(75c4ace7,6bb32bac,13141f21,615e11e,7608fda9,cba4723,9eb6bb8f,349a9e86,7fde50af,19506ba4,65d49b93,c8884478,dc34ec91,9bd5e22,be6bf71e,a870a70d) +,S(69cd7caa,b220abe7,8f36f7a4,633802b4,85969ac0,e9c4a244,7b0ad782,29daa879,4140a70b,8d9025d1,7fb3402d,2ac8afda,e9e0269,b29d488c,2266c1bd,58accc9c) +,S(b6cf3a30,d2a5ec8f,4480df82,ec6104ff,37355ca6,f16418ab,cad3a0c7,bd8da064,f12006b7,5d406558,51fde0eb,c68113b8,50441595,dfe3dddf,86c17a58,94a6d923) +,S(65c4a081,656d9b7,445131e8,6081b306,3a6e0c02,5339d3d7,cf48e9ec,4e8f59f1,51f4ebb9,4b63b8bd,2cdd6d88,c84c8608,bb380e38,c748ddb3,3dabff1c,f50197fa) +,S(c243570d,e74a1fbd,938bea43,bb17a929,47a228b1,ae47a6cd,15c37524,b034fa66,ca57366f,e3886510,903970ca,e1a5dc5e,bb857007,cd4cc56a,37fc7fca,8aa4cd40) +,S(9290d033,1c95584d,e2bace9b,788c50b2,f7fda83d,d45a4a37,5705400,45339d7,dcb3032f,c4a41076,8b8e442e,46cfb16,b63f4fe9,f94a7d5c,f932d0d4,95e699e6) +,S(295df203,cfa65b66,6afc86cf,b879d650,7075f75b,d1eb753c,709760f6,6ae9df94,2cf505f8,8220196f,9e5478e3,6bd82501,671c6b91,a404fc0f,b1fe00cf,12085934) +,S(1631e6c1,3f89dbca,36cc78db,1056a461,6ce2dcca,62f90b0c,5fcbf232,77d41116,acbcbff3,2c164cd3,b57d3b89,a326b5d1,46b5769f,a5b35df1,efabd2f4,407759d0) +,S(db0b2c5b,eec9f06a,9bb43e4c,de18d978,59a95cfb,9b319d2,5ba619ee,abc49e31,d647147,d8330315,1446a405,85bd857f,ebaef109,22ddd0e,3ac62231,8ee91abc) +,S(2581d046,9e8bdc16,e535c787,1a37c48f,929aad34,b694ac2e,5d264962,11e744f,7bf3c684,3d953b2,dbead1f4,8614646c,d18b0f2a,cdf6fbfd,3ca68498,ab25bc60) +,S(9db20da4,d576f564,372aeed6,eae78eed,f512d13b,13d4e9e2,eb3133c6,13c4b80,40f8b2b6,fa113b6,ed7dce55,d62587d8,a86a43b2,9e0b4876,c5607b89,9144d255) +,S(849b193c,e490990b,e2aa48a1,c31694c5,fa041f96,7086a83,cd1a06b6,ccb5e3c3,353b49a,6ac0c705,5a3d5e31,fa428e2,391165ce,402291b2,5e1b0496,bda41e1e) +,S(ae83dff6,5a1dcb6f,e2f56437,c83162a4,a388a16a,bd387d62,f5c5ed,ea08fe7e,e9c57ed6,5404a00b,a2f87613,4d484842,4a32246b,def6c31b,533caafe,7029eabb) +,S(24724eab,46175b4,efe51d4a,5993da48,1a62c6e5,f05d16a5,17e4f58c,fdb103,94465b42,e4e378c2,1ef0d1d1,8b25d140,fb17f51a,fa4d37e3,450c73c4,72468b04) +,S(c2e2f802,4ac48fcf,41a3790e,e9916018,5a301859,3cc3fa77,c7840552,6700659e,b1fe219,1563f9bd,20c4dd45,615d8cc,400911d,20cfb7a7,672b06,20d32a2a) +,S(8b889bc3,e2d1405b,47a1a05f,fd0c17ef,9b4dd75,4d30640b,e3c4de7d,f70791b5,e2d459ca,285629d,956d5046,54c5e907,6ed92fa6,c95643c0,7d746b78,e03a044a) +,S(336c0585,8f5ee169,fc09fc73,a181ccd1,3bd62dd7,c454837e,1a5d7676,abb2faad,5c29a656,e8f2804,6e855c6c,eb0d908e,38f1b62a,69c67948,9d6a03ce,64a90c2e) +,S(c9a6df46,411961d,a703ab23,605fce16,fe021576,92a9b80e,65b9e4ab,efc9ee93,8b63a4ab,18a4b190,89dbc53c,ef0b0dc9,20c0ec7e,1fcf075,195bccca,58d52f6d) +,S(6cea35c8,b3a45063,75456a6,2c95e8b3,7d84a6d3,e909c5a9,cc4800eb,5bc28367,68198888,eacc9380,4a3233ba,1801d586,e5bcb2b2,78efc7da,6764bd5d,edf0ee90) +,S(f13d4ee6,ea31999d,d8d1220a,13ce8353,7c350046,319a0412,e562cb8d,3e4ee80a,5f7afcc4,37f0b29a,ab11a8b2,14947521,bbb4b622,261b9e73,f989e1b9,9f43a2ab) +,S(7385b644,2e43ab56,f4df8a57,4d0a32ac,6e5a7114,13dcd992,f86c0b04,33830307,6d27608a,8ea00e22,4197c8a1,9e9511fc,7ecd7083,86e94ab9,6aaa35f9,c8c2c5f3) +,S(35923ab9,a784ee6e,5a4e911a,7552fa16,ccefa4e3,dcc90083,e5a19e31,4dfeb06b,c900475d,980cce8,7d5cc091,7a28c18c,2fecd5f5,cd2cc66d,e26deb61,1c5acb89) +,S(d88b6907,3abccb02,2e235e60,4f3e2877,ef979f85,a5b3fc4d,fdb166b,a4155d9a,1eefcc82,69a20b9b,48d30d00,e7ffd021,a9b7b171,378a299,819d6e6d,19d5ed24) +,S(b86c5281,cfb9f3b8,4be4f83b,1d13d33e,1f6abfae,bbedcac1,63362a76,8740a827,c1a32696,fc1f8507,289f111c,85483b23,23d228a6,773030e8,dcf30f6d,57857dbe) +,S(d2813221,9c730094,97c257f3,1fbeaee9,1afa001c,84e4b813,d7ee2452,6454c640,75d722d9,7111d6f6,b6324598,8720ce39,66fae55c,3d81e4d,ade294d6,1269b4ea) +,S(445addf5,bf941ace,6b4aad55,6f174ba1,ee793bf4,9f46295d,19fd8e2,807f8d3b,cbe249f1,fbb39f8d,93079d0c,e84302dd,52212b6c,828a1626,b7446f91,4f6727e) +,S(a2dfad8d,66fd47fd,38fbcb74,b983d366,c57a08d1,b04f1acc,4fdf047f,100552f2,63011d2b,43822a21,ddcdb1cf,ef4dc0d2,5f595165,26939761,953fb738,77586c9d) +,S(c4e84511,6644466b,8c573b8e,c7dd3788,ecf1c6c2,63ecfabb,b13f697f,2b2e3a7c,1e53964,a70e83a8,ed9f5d8a,b6b79629,7368bc5d,cc90e6fc,4e8e6f65,542f63cc) +,S(63c4cc2c,cf368a04,be814d1d,81fa4250,653ebeea,ccdffea7,944801f6,efee1aba,6fc2bb4,a7e573f5,fea2cabf,abd9a145,c7c36d62,11928341,e9553e8a,b38fa90c) +,S(51eb8782,a3445ef6,43f01634,caad6fe2,29585dd6,f073acf3,62cfaa3e,960343c6,56d20f56,8e6d868f,491b6e1b,80fa5c88,e3d625d1,433b1dcb,5ae2d35e,b40a960) +,S(d89ea50d,ab6c4c39,48fc4d4b,73d7812e,a6b59ee1,8e7a51e8,bf6249bd,ec59d068,a1ae85aa,e842ab60,95feec2a,d6ce6206,e81a6e76,7f0b7b20,d41cd28b,6a8c4258) +,S(d121a6a8,11f953fe,a90d8f3,4487d654,fb48e4f3,c5ac4db8,3e3f50a5,cd7bac9c,a5b9e6da,e07a0f1,dc1695e0,20502f55,5fbf136,df11b586,4ecc63e2,d7061a6e) +,S(83f7dd06,e5afbb3f,7b2563f0,faaaa3cb,20c32db1,5bdaeeb5,73219814,caa599b3,c452f49,1e4482c1,1cd4bf46,75d74c5,ab054163,b6d1b837,dd10aa05,950f199a) +,S(1f5ba7d9,b4cf8684,cd073892,4aee1919,1f611d78,a943d49b,509fffa6,31fdc19,a017e13,7a8a199a,e361dc18,527f0135,51e48b02,c2f7f102,a6c1ffbf,fdd0baba) +,S(d25fc73e,a83ef669,c2e127c7,1615df3b,ec61ee38,4a6b3396,cc52066e,c3b70b8b,9b5d55e1,c8dd008f,19b5e989,363ea737,e7d7bea3,f7b0d9b6,951dd78e,be6c5334) +,S(d749373f,ecc1814b,dc8ce6d1,2ebe84c9,e09806a,9cbec814,cf98dab2,4a46ddba,88012af1,84f7ce23,730a3a4f,191d0687,4d5652dc,2be47214,61e9ad31,b39ee397) +,S(8e05da99,971ba37d,38e7642b,693856af,a90d7206,2d360611,6c8f506d,68316b9c,73de534b,5833287b,61f3f985,2723be7b,e8e22ee3,1d1ef4fb,f45d6931,827e3db4) +,S(e71e83f1,c6b285db,157f4a14,825aa540,558a7853,673900aa,fdb84556,ae5c891e,e37980b,c180e3d2,481d81f,f9aa33cb,b297ffad,7dbbdd79,4fc013f5,43ee679f) +,S(bc66d644,dd9da12a,299557d5,fd35993b,ab05ac8f,bdd3802f,25b35890,db8eed32,5fa8c7e4,bdf77750,573a4ac7,1681ca04,4f796ea9,c8379cd5,ed55631d,bfdb8405) +,S(537f194e,efe43985,8dbe1eb2,8e27448f,fd1b554a,b12805fb,3af43538,fe0e37f7,e82018eb,447b2810,1502453f,db4c1cb6,666330d2,ea3331d3,f79d5652,a1d64af7) +,S(4af2a9f2,e0fa4b4e,731dbdf3,676538c1,110f3232,7b8f2766,a7f489de,8aec3b4b,cf2e0ca5,dc830856,43151cc0,1507af4f,d84b253,2f0fdcc9,6489baf8,6c1bd4ab) +,S(81369bd2,a4945c15,389aaea3,4e2855d7,6343e200,a9407ed,d05ae927,5585aa36,a9b4ba4,e26950c6,6648b573,3c0c4e5a,22a51e71,ac3c1fdc,78403eaf,3a667161) +,S(1c0813d7,ef91aa73,9e3a6f0c,e3c7edcb,2b7117a7,2ad1dad6,1aed130f,c61cdd3d,e3390572,67ac3bfc,5373cc31,14bd0f38,ccc3cb25,862b243c,912c0aeb,98bb86d) +,S(8a651923,d2622057,59e5f82,b38bfae7,dc922488,749ea56c,e43f0f74,c268f9ab,f3df434f,14f67030,fe888ba0,185e25c8,38520bf6,6e85023e,e4ff4f04,b056d9d1) +,S(89d98548,30a2a572,dbe91018,e66b28de,835dd02b,f793a469,2de3d720,d70e8f43,629868e9,9e434bfa,98bdc4,f191a08,72e68768,ce8a918c,7c2da42,75e5cb3b) +,S(97d0c83c,5d83d399,c567ecd5,dae551fb,7f1838de,1967e84c,7f053b81,62965fe9,fd716683,73347fbc,407543b6,70734733,df623a55,1766f55,8a02059a,2ce55c4d) +,S(20807bb2,650e6d82,38a66ed4,b239b59e,fe073a5f,9cbf0d6f,e3d9a16d,be427de9,46a25a29,c104c56d,8436155f,64b1d84a,b974fb2c,951470df,17a9704a,be5c1f9a) +,S(3cbb1786,945bedb5,c8ac2d0e,dda1b0bd,ee314cc5,faf56b75,fa878bf2,b218a8f3,ddcec0c0,d05403e8,ea2094a9,6ea910f8,3261932d,701a2ea0,4e93581a,7e4b7275) +,S(961d0144,1618561d,c3504859,7e1701bf,35412ad3,2d04486,704e5593,b9278734,7e137d6b,2060572b,ef66f8b4,c8ce535f,b858327e,26dc2295,6ee6c94b,c83859bc) +,S(2814918a,115ca2d,688f4358,9010b7d8,b8b560f3,6a3dce2,8fcc05e,acd4845b,dbf76f51,ef80e324,8820cb0b,bc7f0c2,4d50ae48,6387d206,c333222c,5f959dd1) +,S(6c4f3b00,c02c19a5,ddb0ab1,798929ca,222a9538,b641cb3c,dd61736,77c9442f,a91d13a4,d3888b82,eaba5173,3ff76fae,8022fb10,8cd61f19,206cd78,7d1c99cc) +,S(8f48304c,ac37d495,fa1a2ff,2178f442,4af030ca,70662a1d,c750bde,5f5d8dd4,ccff6176,47cbdd3c,3d0c588c,37a98723,c2b2aa14,fd17cf9f,ea45ec72,eda8defc) +,S(ae3da559,e3fce253,f5c1fbad,8e12a52d,ee989ea9,8552a192,93f7db0,eaac9405,430b86d1,322191c7,9aed5bb,12eece79,f2519bab,17998346,8aa13b69,94032ef7) +,S(90c093fc,27fa9de,66a1fdc4,d921e5da,6f4fa049,81cb6f91,e085f89b,96561471,1bdad536,4ae198ae,bbb0ff88,3bd5dd2e,dfbaa91d,e989f45a,30befa9,76f2db23) +,S(730a1c4,5ca28743,538fcacf,a65b7d90,b6f4b1c6,87364cd,53dd6585,328eeabf,7420e8da,cc64a059,b46221c6,c3adb4b3,46eceeb8,8effca39,1a1e36d0,d665257b) +,S(341eabe9,66c6ce4,65ac18ca,1eda053d,4e6137c,ac0796d4,36a942e5,99ef897a,d298003d,fdd9f529,c1977b3,ed426d6e,2df46098,539b20ef,c2011a36,b7e49cde) +,S(8f7e1b2,cb538fce,4b4a7775,90d1a95c,2fef8331,9792c0bc,8d5f3493,54fca169,71b0849f,cec62c5d,fdce37a2,61e2a06d,32b3e0de,87c8aebe,e5a95cab,b0c3f798) +,S(c7ea6b43,ce1e0e83,819bee9a,31fba823,3ee03a6b,14988b98,e80aef2c,eace0d56,e9f1328f,dca6a16e,2100ad40,138f9810,17e37e67,7e7ca747,c3a57ad9,24b8891e) +,S(b16ea5c3,b03e58b0,e6c217c8,6eacc4b9,3032add4,30acfd7a,e50eacb9,a0e5c1fb,507fed89,5c14380f,ab9e54e,a3624e5a,cbdaed64,b2712f88,48018b90,7a88f47c) +,S(15cf4de,7c36b72d,f7b98c00,8e928731,a2e71c69,cd0427f3,ac9264b1,5a5fd487,3865beea,6b36732c,5ecfd21a,562ab253,d618546b,c1c24745,8881b20,643d7e2f) +,S(394efbbb,fa740f53,b1e70eb9,d12671e7,55337357,b982921a,79915acf,ddd18218,8f1f1980,6c1d631e,6519aadf,b563dbf2,37b75db1,54baf06f,6fde8218,a0a68eb6) +,S(e6c3e152,27453d32,cd4449d1,ab1ad78d,58f5bb6,f29d813c,e7c6628f,b284399f,89d87957,4b640a87,abadc6a,dc51a533,838a83f,53de4448,9ff0640a,502dfd62) +,S(e2480000,9db30642,f925ef8a,e31c54fb,1340e88d,b6d633f8,415ceac5,f583cee6,39ad28f1,8ecd8302,5cc1fa72,ae4e9897,81318cea,9e506794,50abd959,f19758c0) +,S(1c134120,3c2e7e21,f5b10ecf,402d52bd,33db3278,70cdfcec,f3b277e4,78f551f4,cd6907b,57cfad79,5e14e7c3,b2a06a46,17b7a27c,ff476bfe,38d68d0f,1470dd63) +,S(6b2fbbb1,515c261c,954a0be0,279a1cd6,63daa083,1fbd58c9,c69b7be7,ee6047dd,d38ef59b,4e276fe5,6f1f2fe6,74b6974d,5ef1f4a9,74abb2c8,17cc68cf,78a164a) +,S(dd5098a,8cc8ccf0,7db82096,b52d1fa3,6bd26c2b,57f0cbe6,2ca954db,1773e9cb,a198ec1e,71c53d73,5b50000d,678d7d93,de64a72e,8ad018bb,f515b4f7,c7840aff) +,S(f6dc494,3baa0613,59a000ab,3aed3456,1972d425,34df86ae,3eb8e5e7,cae23c22,7150f3bc,5a968248,d8c71ea8,32b116db,73ff34e5,35ec1e6b,64b2474a,947174dc) +,S(e115c926,5930dc67,bda89798,e267dc48,12c06d2a,a05e4a5a,6519b0bc,7096f84c,5b0dc7bc,82b61275,2aa17a13,c1fe2cd7,6b60cf1e,ceaa9234,ec9e6609,7b2018ec) +,S(6687f498,98a22d8,58ef88a1,bcbfb446,33d51eb2,6c1fc2ec,eeecdae9,e0960c56,fd1912f5,7c0e691,23977524,ba58ea04,5757aeb9,309a5b94,3c993a93,57475ff) +,S(366ea4df,3aa8da52,763b513c,efa3c739,af61a497,6fc4c884,e879ddde,c2457d1c,876520ba,cca3c711,a23186a4,833db7c7,14b3de4f,fc86e8e4,cbd61cc0,9a48f34a) +,S(f7951805,eaddd012,2bed030,f3013e15,6fec02b9,80ba8ff1,1a0b978a,3fbeb778,b255b5c2,db866de0,a145a108,f5eb4b69,271c13aa,8db75fc9,f467843e,a59549a3) +,S(c77d217c,5c7b8fbb,f7bfd244,b2a2d2db,372d8217,43eb4a03,47858678,471d8be7,55573d9b,dd16bda6,ad916820,874d64d4,b260a489,b4a93427,1ea5a79a,f57dc5c3) +,S(c803dc3c,1432ac63,19db169,6d7ebc16,58021b8c,b92c0fe6,a59d1efc,2056f214,ce8e23ae,c7dca471,8666f61d,d7d8bc10,e06d1929,7fbad7b7,7d45526,9e207b09) +,S(676c4c3f,617b661,2affb2c2,dcfe072c,ddee8b29,dad9124f,dd24e87b,52a80b88,6df8c35,be6818bc,b6857f47,f59a11b,e05cebae,ee6c53ed,8cb93fa8,92c49e0b) +,S(8b0c8502,bfa15f59,335cc34,20e04c90,becc2308,12d40c7e,14fc3e30,88b8f34f,eb75d312,9fa4db28,27d20c93,de9c5cc9,4237bbb,a9710371,f767f686,e5ddbbbd) +,S(6ea07148,5594bd90,2d0d526c,28918bb2,cdb7d1cf,d3ad0b1f,a3ebbf76,71a2f90f,3a30be2c,2058cb43,c6f8ae98,1ce8986a,8b4dfc3d,81d49a80,4e40c81a,a1fc8220) +,S(aba7df4,8bcaa5e4,c4fd9a21,6b4bb3fa,27617205,693763bf,71b8b214,9cf83c48,6b1b719f,a0633abc,4580a9cb,9c1210a3,3e5e3bfd,177bc76,39057e51,3fb9b3fe) +,S(ccfca0f,ee5bebb7,26e2062e,2b5cd592,847031d3,5edc7767,414af809,9b3ac2ad,135b2ff2,4e40f04c,adef93ed,ceededb7,380c1e9a,e32a499,467af149,cfb532cd) +,S(9af36417,f3076595,42ea54b1,4671d2db,f7582ff9,b7e659a7,6465ee2d,4db88e35,dc5d07a2,58d4f5d5,ae649b63,e07a4253,8b8b3e42,c65a6ba3,44900028,c84df8aa) +,S(e2f308a3,e4d99e74,d6b37cc1,dc41d9fd,e98a4472,6e86764a,89fe959d,deaf922e,f5f8eebc,d9252e1c,74b9040b,569c9d5e,11d12af5,aa21051,8f87043c,7b47776a) +,S(a62581d4,c4fa4b6,aee11db0,8fb698e9,864cf336,578c536a,8a887d1a,89b43e35,b530ce21,bba9d034,d53dd490,2b76f25b,4391914a,5f87b6d8,2526f7c3,def132ba) +,S(11ef91f5,dfeaceaa,52f434b0,fc03085f,60c12ea9,4441574a,5725aa86,52c259b4,a2c81e79,cb5ad0d6,bf0221ce,2bf7497e,bc91026e,adf0e25e,6269dfb3,2ced7d8) +,S(ff549a04,fb86bf9e,3ad207b5,ac76a74c,2532a1a6,516327bc,96353baf,66269c5c,ef1088fc,633f639f,f0061bef,4c1e4c64,5897ba0e,ee229d44,d99be0d6,95e494db) +,S(11c9ebb8,893b6534,b323909,961bb8ee,4c90c854,52848ad4,18fcf223,c80eb7cd,4b0229e0,89a1ca0e,d60ce2ee,590211a8,769d333,5f4ef32f,4460f8be,940a0dd2) +,S(e86b3691,f8ae48c4,12a6216c,c3633f1e,88667299,f828d6b1,3ff88cac,e060b1b4,14d95d6a,61298fb5,1fc974fe,f3957db5,4aac7130,a1ed873c,cee5cada,6eec0c6a) +,S(e5b9550e,eaeed973,5d8068b2,2c48bd2a,608fdabb,563c0e5a,6c2b2351,24c49d19,506ff679,2ea7c37c,254d7ae1,a459204d,aca23016,93c1598c,2449b758,6d437de4) +,S(cab58ba0,cb15982a,c1ae5b51,ad65574f,55540820,d057e11e,f9c9f9b,a1388335,ae1c9e22,74958b33,2ce0f0c7,ef621a49,4d5b0ad,b04748c6,539dbcbd,6bd4ef18) +,S(715e4568,9bd663cf,e9c83006,82fc7c90,5ae2da55,42b0ea4,40cbe2eb,36e1eb43,58ccbf96,8860cbfc,6b03f6a,a5fe05db,14be0e3f,3d6224bd,ce6eb54f,7372aa85) +,S(df92f1de,4d22a7ee,6d2bf45a,5728745e,f59b6b07,29614536,722c7de7,965c0648,59e18767,f0e22894,be586a13,46950c03,88f1529e,cced0d18,50439dd0,e5bc192c) +,S(885dd01e,dc8ffd40,c5f26d7a,bcecf670,7a791ac0,b2332b91,12e69cbf,11399808,4ad58276,6e763ddc,3f4ff718,569f600d,8c764659,87ebd74c,d506c2,ba886ac8) +,S(d3fe74b6,17a1ab46,c773549b,af4bcbff,917c7ecc,fbedb63b,651b2197,89c1ff9e,b2e6bbee,5d84b593,d43467db,7372f40e,493a9fdc,c5d88fe6,5767f45c,837acf93) +,S(c3730836,74b97237,66d9e9de,f7b6d792,93faedf4,f7d86301,75862d62,d4ada8e3,b669a24,a31f8277,8686d2aa,6b2acd16,872570f0,8e6f06b8,394f498a,dc29f099) +,S(4ef2ace6,422be7ab,6a614e2b,fc43360a,2fdfcdde,51cb31c8,372a2042,2df4e100,86868f5c,37366665,fc6121e0,a8ab3a86,92ba1714,f5b8506f,9a3c3025,eaf9fbc8) +,S(51110764,573c540b,813ebc4e,79d59277,67e30ed1,70a951b7,9ed05f8e,8d142cf8,ea8890e4,9668304b,63fad75e,33f42601,f2649a21,724fc495,61110e79,d7ddfea9) +,S(36cbfeec,5491e1c2,f853d98a,275c1baa,e74dca33,2bd3d830,7d896607,c1cb651c,f67659d6,677b44cd,33c0cedc,d5886ad8,90eac77f,5b393fa5,6cba1077,54489eee) +,S(d1ff3875,e1ef071,eef96f05,bc19d356,aeee18a7,f3892f02,4d07b43b,c3f09dbf,ba825e43,72b4a644,dcb5b8f9,62e0099,ab75ef9e,34b54874,f8d68197,ecbe8eae) +,S(45e7bec6,75819b22,f2761ae7,575ebd6a,8ef87727,a15e33b,3edc7ead,dd58fa5d,3482080e,edaea330,240b539c,7d6a2e42,2cbaf40,f93d5052,28c773f9,6d80fa86) +,S(8ca5d7e4,bd79aebb,bcc5250d,c86ac1df,373eb3ce,1d8cf2ff,5916cbb7,1e8e016e,1af3f417,afa5c1c7,89474f79,a0755bbf,a9a268bf,fdf242f4,c1599dc7,b7cb1e55) +,S(56bf2e78,e7c43841,6324e581,7330a6bd,208edee5,3b5d61cb,a141f9cd,ec3002c4,e8f91e4b,3984a946,29060a4e,534bb4de,f345879a,f4884214,63dd0299,2bfc2fde) +,S(af152859,31540f00,1be4a65c,e3f55437,f7be7d8c,db0283bd,f96bf71c,c004455f,1f58be49,77cf9b8,b7ddf7fb,74f7356d,62b8fe33,6bf798de,3dc435b1,86122b40) +,S(2f4d8117,bcffeaab,7db186c5,7aedcb00,80d67b36,a560c5f0,e323b7d7,79be70b3,e0a50d82,80677ee9,caafcaaa,5d7d1747,3f4980c,73831f43,29b15452,94e71829) +,S(bd96815c,e6b6d0f1,3688cc26,777c42bf,50fb8cd8,cd0aa082,94ad498c,620d1f4d,8a882c49,6592b186,b0a4071c,b0b556ca,27f2ec82,417aa246,ae24b415,8e4ddb23) +,S(cf64bc04,e0796fec,112a5ef1,2c3cd909,5c041b46,2772b818,3e6656ea,16d046c2,6a05162a,eddf163a,fc2cc91f,34f7a7bf,41660b4e,a8ac7af5,698c259e,47e77e86) +,S(3dc4bd0c,2c8253e2,4ed942a0,7f45c2c6,390a9d07,6d334f3c,80dfabe9,282a86c5,e0994668,7cc9c6ca,e2d04840,6d34cd22,e4f8e271,da4416dc,77e59af1,7057c43c) +,S(40e00b89,e58de390,6a56133a,fa574019,51be1efa,6156baa0,45fb3987,94f7ff11,cf675e01,1f20efc4,24b882fb,b7bb9ca5,5a1134f,b628acd9,a597fb97,968641d) +,S(5626496f,1f49190a,48929e9a,403f9f54,319a6b1d,301cf256,692cadc0,41301c27,21702c7e,2ee0efcd,b98a0170,110e3495,e23fe5b9,9674bb0d,b6f09e57,fe76b48f) +,S(2a2c8f2c,a580145b,a9593b87,dfe0dcdd,caa3cef0,20b0e2cd,3792da6e,2f989a11,4aad23a0,e01f6a43,3f6c2a40,f480f945,d45c89b1,df42d67,acf6b0da,3f46bba8) +,S(68a74703,a88b88d9,ee974a87,af7b1be5,1866ea40,ab4cae9d,90a4c2c6,5822b565,3660b266,c74b8be1,c98d3b9,b1f14dd7,e039b476,733a1322,d2d7d2f6,9ad59700) +,S(b50ad45a,4898f77b,c5544dc1,cc8c0515,3b1e15ae,d043d2f1,40bf9dd7,29e413e1,1a59e623,3bea3be0,5713c06,b18badce,69b84693,636be68a,532adfa8,c617a773) +,S(df18b016,3ad015e8,da7e87ad,e6fa5312,d665c696,e42e466a,5e9e2a82,18337c22,532d4260,eb34306e,691f42dd,c215ffdf,2f6cf3ef,cc1363c6,46b8921,ccf277b0) +,S(405bc408,446bb0bd,49eb838a,eaadbf1b,27d413ef,a15fdec9,86e8446e,2c799391,1293bad0,ca26e4a9,f80dcdbf,1ccb70d3,fca9f403,89bcc331,e917d7e4,bf4d0b3e) +,S(1230acd2,75b02450,255fdebe,dd0ae807,38f081bc,5faaeebe,4542664b,ec57bb15,aa31d16d,b145414d,acc29c11,b0ed9fe4,fad90a7c,451d9706,4f7ec6fd,75b15703) +,S(4015c1de,3e09dc64,9ec990be,898db42d,1193e1cb,81956b08,da1c15c4,b9a2af48,d58b2d0e,553dd49f,ab07e5dc,c5a66543,b7dd351d,84375fdf,2ce1db56,8185e67c) +,S(f3da2f12,7f47b9a7,192f00a1,5576aeb0,8bc36211,7fe1246,ad61421,85f79009,865ca0c6,4aa629af,b84f761f,b26a4938,25fdec29,ce1d4a66,9dbcd138,41bb83c0) +,S(15f1e896,f7c7cc94,f3f921e7,6dc1e30c,f0d43b99,e9fa0352,42e56a4b,90a0c736,61e85195,215b864a,6f5bd52c,d0274526,dbc80af1,4395f9d1,ce60bf74,27c18b33) +,S(3fad3455,470a113a,2f773ed1,258111ff,da926643,f7fa1cf2,8e9f7b80,dfd2105b,ffbe436f,a1975bcd,ee4eae51,8dece7d0,cb34aeae,ade738d1,b39f4c6,6ca08a05) +,S(62bbb9ac,282329dc,65ae7b4f,bd15dca7,70a088e5,45850aaa,bc4c09b1,9177f92a,9c000eb7,f6104a03,51e1bd8c,d8ac8f7e,22578291,35eea222,866f2632,2573dd72) +,S(9bf86604,a46cf253,324f5608,b7bc87c8,72939597,131f12c0,eae3482d,b1935e42,e9f2dd2,15cce5af,16149d3f,1116d79,74f51267,1b575f8f,6ab6367f,fede26e9) +,S(a2ec976c,b5e72001,a25f95e,bbd7d354,2f3b174e,80ee3752,db082910,895f723,dbcb75c8,365c6248,c52a83fe,1c79d7b9,37ca8ebc,5060ba7f,60b881c1,964105d5) +,S(dd91f713,ee212c4d,f94b1fc8,c7f246b9,cd162a9c,5c8988b8,f3adff0f,fdb0aded,efd02821,c4eb853b,bb8c55ef,c54f41fe,7e53582a,230d52fa,c18a53d,ca40c81e) +,S(504e6ab0,c47fb3f4,b6b74a7b,1e67f6e8,c28ef108,62c2db35,f16f31cc,e71d423f,e7adb424,3200ab4e,71e50453,2d849315,1eae2247,50ff7a59,52bf2656,65b3ded1) +,S(1a9ea377,27fad3be,155f7ed5,1caf01ab,1d30195b,1629fba0,dd04b7af,c1a4b8c7,2140f144,e531dab2,22cd4137,921b4720,59efbd57,c1c97367,ff2083e7,f2420206) +,S(d76324e8,31920463,d5d94ce8,f9654393,89d97ba3,eb5e91ac,56898343,397b34aa,189631be,df5d46fe,fa8f60fc,a8b22fc2,ac987d23,b21ff267,560863,6ef3a72b) +,S(de87a315,50a6f146,e681d8a9,f9a7cde6,7da28c7b,5cd7a70b,703695e2,3c9bddfe,d33a05e7,77ba9e6d,155bab56,2b8cbba,27f4cc63,13038f7e,d193137f,d14b8502) +,S(d8381e05,7fbc1910,8b5a304,fa984e0c,cc0f5d27,303a3287,9ecfbf73,a1137974,1dc513d5,ac96238c,79d8f740,c855e045,e5c4e567,b3f44744,abb3bf46,ca394e8) +,S(69da86a3,b355f0d8,138bf809,79e314ab,7cb34e64,45be4842,b8f3810f,11b2ad66,7db776df,68bcac9a,c0f8f55e,8ee6a7e1,771d4148,1f5d953e,e9bf832e,cf713cfe) +,S(698f8b8,66093996,e2e357d4,d671d21b,230726a8,84079fbd,766332a5,4e7f18f3,5925e34e,dcab3458,ed959aa,3903ac93,c39b8ebd,1c562691,3f844150,d41ad20a) +,S(37274120,6cb7047d,aa97274f,b12aa8d2,e5eabca2,f3ab0b4b,daa3fd7a,3d5365df,30d36bad,c10337a2,db6c30f2,e8876226,5ccc6a1,7104460a,6f438a9d,3e8e9300) +,S(4e8c8df7,30f5d411,77355739,84a530b3,8ca4012d,3d4c8ce,f6c00689,b72cbeca,d9f7aed1,f5073c8a,8d2948d7,86ce6dd9,93a405ba,393a20a8,719287ce,797163) +,S(1e62c3c7,16e4f6ca,77b6d325,8553a5fd,59f67df,f7295115,cd6e4bb1,19b4b5aa,7df17da2,a7397df9,e314fd8b,6b03d293,ff7325e2,769d7477,ef3802a5,7d8010a0) +,S(c79f25a4,664cae13,d0971832,fee6a316,ff338f15,40c1f3e5,95c707c0,6e035db,5ef7879,c46266ca,7b342264,1594e81,5c189ce0,f057f187,e43a61fa,10330e85) +,S(768a47a3,64304a44,34b097e5,132edab2,b9840584,6e543dd4,755038da,e355cb9b,79896b63,eed7e866,32c33041,d037554e,551f2a73,6f2c2b35,4dd7d7ac,f6562344) +,S(131671bc,604d622,eea3f06f,200edb52,f7223fc9,3fc8d4e5,496af1a9,f72e56ad,5a6614d3,7985f503,2ad7a53,9b99ccf7,7c453f94,3975983c,e948dfe0,ffb867d6) +,S(3b9e6127,48d11bfc,1d2d0081,24e79a9c,604bdb94,6b25ac57,749ca6ef,302d7a58,379e7cc0,fecf689c,f905e84e,8516388f,3e1cb41a,aab8192c,aa024de0,3332cc70) +,S(4f9fdecd,10e8cc9c,f5f2573e,a2fd231f,b1313468,f516af1f,76af0eac,9ad51d76,26d6731b,71382ea2,1172142,fc5e0f5d,d0f7afa2,c9409fdc,62bced0,e8246194) +,S(25f313d7,ad044b0,538bff0a,ead5c689,d5fafec5,7cddd9a8,31b9a4f,59b848e0,f28c77b8,9202c9fe,e64c0580,75a972cc,a4839e20,42c32b66,517605d5,87470c40) +,S(24a8d407,e26c4cae,3f8dbc18,5820f345,81bf4355,7ad036a5,200b9b7a,68bb8d6e,fc6a5d96,4fa25fad,4d09a1a1,a4ec4697,818e46b0,8cdefb70,367e3453,2462b98b) +,S(ef4df8ea,5cc100e2,768aeab3,112c7ac0,6077b754,75cab97,df3ed51d,6d397f4c,fbf555d2,27eb051f,54965eb3,fac1e21b,82d216ec,807b1485,5074ee56,1ad70883) +,S(80c9d594,578f6e4,e8462dc,228cd99,9b621493,63d55cf5,80e1c524,627055e3,b6d5bf04,97b44e3a,7c7e52e3,28f63214,5eedda41,f80c44df,c7ca6d29,77436f24) +,S(35961cd1,57bc1774,40dd41b1,6a81e31e,52349a5a,e4085248,fe4a19c3,b10f7a45,b999ee7c,b32f1051,f0e7eb9d,4689fb30,fac7af1e,b410d53a,85e79f27,70a7566f) +,S(4aa49d09,32a7fc5f,77a76a12,16240142,596a82d6,6b59d388,24f0d8a1,e7f70948,adb5b12a,5e40bd0,a14c174b,13c242c6,c5f25ee0,642a6265,60d293d9,64a4671) +,S(110d8320,a9b2c5d6,5b06f0c0,cddd243d,c83cfe4f,671db970,d1213780,f6c4af0a,a97c2689,5c7b6ea,a3a02564,d2af735c,9b43ceeb,9f6f2557,3fc468b0,467b12a1) +,S(d01abcdc,a363b065,d8d2bb08,388c3545,cc8ee88e,90ee66c6,18a9f575,c0caee80,317409e4,a70e30ac,279914d7,135f9d18,e19fe520,4c83c472,5f86a614,1863b4f9) +,S(cea07679,64506753,8dc24b68,19bc3332,f320f16c,61eb7b85,96e25bc4,1499796,edff87c0,67e97ced,4aa330e4,e9dbec3f,d800934e,ed7238f7,8e97a46c,a6ad9ea3) +,S(d4463e7e,da5fcdd8,8ef0133,a5dbb1ca,c93aefb5,64581da1,3acc3871,cb94ce1f,bb1efe84,81dff341,dc7a4a8a,c2e44ca1,b071bcc3,81e7ecdf,4d4b7edb,6996547d) +,S(89cb575,5e9323b8,7771a2d0,58dc78ab,ad8bba70,6f845a8e,9a45a16e,ffbca1bb,f7e743f8,a24a6728,f8e8051f,5a303d71,f1f47059,202d332c,23f3a293,9ab97e37) +,S(d035032f,8e8e955b,b71006d5,a3b098eb,7dedb73f,a15d0d36,7e01c390,18bdea9e,1ba4cc2,fbabc437,a9d17ff4,f3c59f2d,2a416d2d,c07c0c81,c3e0a180,260bf2c0) +,S(fec9ff6a,e37da167,208b1247,b754cda4,6c6eb072,8d6b65b1,3754e2e2,eb3223e9,305400aa,27a59f3f,f19d1513,3c5a3655,464c6f39,94fd2ec4,562d7f85,fccfb767) +,S(3cfcc8e6,9e872314,5853743f,efd2802d,bb1a05dd,a03a731,77daf6ca,da9007f0,42b23158,fd0c1401,29298d42,a6cce708,743924fa,624d582a,94b682ee,4beb222e) +,S(4438bc8c,f41b7916,dfcdb038,5c9b6806,83362409,69ce8869,c294990b,cd340e45,78154e51,a4dd31d5,14885a18,b7185fc6,84c699de,2862f480,937c9697,6155ae70) +,S(d2ed1c29,faf76c12,fb15b514,6a31cc2f,c799cc4,5fb226bd,c38d3b0,176b5d52,54984b30,96d0c2ac,763654b3,32666baf,82c04562,d0d92310,cce6db16,216bb219) +,S(37f21b9c,d1243170,5ee6db23,eb578ab7,31f4b470,ab07e1e1,68e69bc7,539b170a,afdc95dd,6379244d,cbcfc811,54aa1917,e8093b54,8ec2be73,5867574a,82ec10cd) +,S(73fe29dd,54c8584a,7d25641e,c62f257d,400f013f,763c504f,f0a3ec02,d1ff8067,197ada53,ba57463e,e23b9831,ef8a6a69,d3d2f84d,c7225782,e7569603,fe1d1c83) +,S(56b27676,f0e88c45,3db1819d,36a73d03,95aae3b6,59f612a9,fe28714e,20bc73c,98660256,fb7d7d75,aca14107,dda9e7c2,28459341,ee6de72,9e463c2c,17367149) +,S(fd898f2f,e7f918a4,61f8e57e,f30380bc,5192a5d5,e1f520a0,5b99658e,8d57bf54,6861b3c3,5b0f6943,48bc4886,15eab8b1,36630618,592ac04f,80cdd632,aa63b620) +,S(fef75974,2911ca2,8057e141,6288b351,ccf2d490,634c98a7,a80153f,e9dc6929,9d5d0031,3417797a,83f0ecb5,d4f45890,d679660f,b1b19686,ffbe060e,deff716e) +,S(2c4338aa,18a27e60,d1daaa92,3d837414,f199f585,8d33b66b,471c6562,c8324bb1,13c28f36,25f2b273,8646cda3,5a2a729e,eac1de3d,80430cd1,6a0f3a9a,cb859fe7) +,S(53d6a5c1,deb56159,34416235,c2f597af,f6e10ed5,444d15c5,d9ca82b6,8e1820f8,26a5d559,cc04f53c,6b1ff3c2,4d5a62f,f63e50f4,b7c1b619,9dc54c20,628364c9) +,S(e432c338,e550a635,79ab747c,f01f3ffa,9e39d066,b221fbae,8b44429b,873decd5,297e10af,3006b09b,80d0ae19,3c1e8b3a,80ae9051,3dd9944a,444b2c7c,42d0066e) +,S(a61c5ac2,60f3048f,92cc2af1,6d3f6a4d,696e543,f044192c,9d840962,493f5cf0,1249d4f,83608025,331ab42f,bbe338b4,727a5ccf,b086aeb3,f1d9c96,26859158) +,S(a2f37e43,c3c2ffba,c45ad316,e912b586,2a9ac698,f85ea54e,98fe9a6c,e1fa038d,93e95000,6bd329ea,57397b25,71dc2e78,a466c4f8,76ace5fb,36d945b,a6e9b24c) +,S(b2257994,44c2ed2f,3114185a,6ca617b4,bf4ac15d,40d73b62,44a81852,d30260c2,fd4607f1,3d4ee761,adb6b139,3f87bf8,e8b05156,5561d650,a47efacc,5ef01dc3) +,S(d0607bf1,5317662c,73df9f40,805c9b3e,208ca1e,7fa8c04d,ab9766a2,8c7fffc2,f06da1e2,7e721799,41a9e128,e25ec992,eb030ca3,6161c02c,8ee31d22,388bd999) +,S(596aa391,d4831e61,55d80829,35a85bed,a1ea3190,a499ec6,374389cd,1bd5d8c9,cd9240b2,9845911e,47ad147e,ae55a0c8,639b994,8d72d2f2,72e89fdb,578d4ff9) +,S(433ec09e,19b7543f,a460de41,e70f63f6,6097ece6,dad9b5fb,f4030c7d,bc5862c1,dce03718,a609efe7,1858f6db,184708d1,9275ec2c,76d5e93f,e55a13e7,927cba95) +,S(343b03eb,c285418f,ad522784,f91707e4,f268451a,394e85d2,824c837e,fa48900a,e6595234,643667c4,bb885b8c,1ced3a29,a71212df,f2904549,ccb91de3,75787922) +,S(6094f67e,41b23bbf,4d594e97,b53391af,f10a978a,19244189,63814efa,ccd6488e,ea874289,dd943f7a,c109939b,8fa545f7,58359804,ad81ed0d,26cef135,cd138954) +,S(cd0c3700,bba5677c,8d0ff53d,f06bdbf5,c5adce29,64921c9f,a1591c91,ae0a375,720b88ac,9374709d,1919854c,237cc5fe,dc53b14,3897e4f,3502af17,d7510c63) +,S(d37ef1ea,95ae727e,5166dd59,bf5ee82a,1f215720,79d82e25,6369464e,d9a87cc4,59c5321a,d700c559,c92e500b,1d3a4589,15a88575,df9774e1,4bee7b2,ccf9bad8) +,S(238158e3,d58e7618,95f7a0b1,cdad8a24,3e19bfb6,d1c65929,ff08e766,e62c2b12,1f65fb1,8969ccb7,27d50e46,39c7551c,5b3f25b4,90b7d70c,cc5e4ae8,7293a0b) +,S(260a340a,5245a039,4a2f0908,f2912f0f,63ed68b6,aba66fb1,951128dc,9d542512,d30646c1,e8aabbd5,e758adbe,980715d2,b0b169c6,fe09c502,3beb7f5d,b5422be) +,S(7333eee5,d111e138,f6e0b2d,4b476ba3,6df4357d,b28c8e7d,f232c61a,6c3067bb,d427a423,a4de1e60,e8b73098,b8582e0e,18923637,c44c52ef,fa0b5f90,8ccf786) +,S(c411f215,dfb87aed,be2530c2,82a61e5b,37a0df71,1ce61fd1,25624b44,b7673eaf,ca3d89d7,d136fd46,161fdbd6,3f0b075a,afe90855,51e075d2,391f3206,382a0441) +,S(275b0a1,9dd09495,78298aa1,c4b62ff,11e715fb,6c3740fd,80d7ec03,3f2635e,30dcc412,faf3f389,c9919b6a,f96e7b28,6eb8abb4,ada80525,b9ca7eaa,f3ce74cc) +,S(9f774052,6818bbcc,b068c11c,b400eecb,da60c4dd,22353a3,4145e3e0,91f81617,a9e56fde,8f38116f,cafaea93,35ee3688,50da5107,a5a3e571,92f2bfc,1b55033) +,S(60fb35ce,f1098201,353bd7e6,89b42fc8,9f86dbc6,3eb400e5,3b8d16f6,28ae4358,1906ce1c,6a6f41a5,2f45424e,86633937,8ed56578,ffd94174,f4f85960,ee0f5c2e) +,S(1390a621,f999c3d,1737c72c,3235e542,99ce4796,d65c1ec5,45f60b71,19f4ae25,8f1cb557,b101a876,296881fd,5d30556f,55d739da,5122c0f1,43c04add,3485dbad) +,S(15f372d6,9be09ee3,8d43c453,dc488f17,42f53a7a,7923439,66946210,60f1cfcf,c6007ae8,a836a1fc,b5a4c0f5,e584fb7f,2c468d68,9efaefa,6303bd6a,beecb05d) +,S(bc2b2a76,17dd9fb9,e6d60931,ef2d5755,d33c7174,7e8e28e4,be151b42,14537d80,2582a69,b6e9b9a8,c5bb4b79,4ffeef15,96f383cd,670eb524,2ac4e7ba,375509e0) +,S(5f8e0957,61e307de,26ffd39c,92410937,5dac9c83,7a5a62f0,b0864cd8,a37f2686,d342dc84,7657354d,d524b32b,62f5f69d,5b2ecbfd,71831b28,565cae36,777534c7) +,S(5451cd91,9e849ec,b8dc75c7,9f939957,69a39234,38159544,dea98155,cb001c5c,e00d1d37,f9ec02d1,ae8222a,744381,4f16220,800f84d9,17cea9d5,9a9e2a60) +,S(737b89ae,9d9951da,d2b489bf,f2ff714b,dcfb13fd,829160c1,39875a46,7343adc7,ef9e2ab9,f8246113,726e5be3,5c1da48c,a6b4fca0,53d35dfa,8a3d826e,e48c5ced) +,S(8b80e227,9b0a91a7,6af48413,71ae6fdc,68f4f5c5,58de6efc,1ec0034a,36a26000,909b49ed,6ce8c555,25441ab5,1046956f,d25a3a73,5d979c04,43ae5891,fbd43df6) +,S(9db9379d,346cd59e,ed0c0d44,abc4baa0,3b7af170,9f034c79,151aaf54,69296780,1a8f9e50,918a104d,b525c439,bb16b64,179dc4d5,452c86fa,e87ab757,61e97031) +,S(3aa7c8c0,293e5c9d,fb50b63d,340851a3,88b1641b,b864cc08,fe776500,76f98d0d,974dde95,7c958b70,e0ff9399,d2d03da3,4dfc3437,c1ca557d,2240fdfb,3ae1d36d) +,S(26cfaf0,d27825e1,6014e5c3,19bb907b,7a3b777f,b6bc69da,5cdafec8,40d5b4b5,2eabc11,73729fdb,d31fabb1,722be99,e5b4355e,8c2b4bef,53b21dd8,3cf81ba4) +,S(ee495a13,bd1ba28d,cc26fc72,4cbfee95,3aa72852,57c883f0,cb09d6aa,1bdf3b20,b340a2f9,978013ce,8275b7cb,3fad5c1e,857bc6d7,b43782f2,1e737681,fb39b619) +,S(2e04dc81,831bb465,59d6c354,c4c6105f,41f61301,769d6006,adb290b1,b75540c9,d086cbba,4d221cc3,7cc96b20,adceff4a,6157ab9e,686d1fd5,5d56801,dcf4b779) +,S(557b5b41,b2b2e4c,598460ef,22888da0,aa2ec3a4,7980247a,e8bd465,a6e64c22,6a3c62ef,f80832ab,83a9d698,f61f7903,b7f64e41,9900950e,c7d79369,403d57b5) +,S(a0ea9ddc,e2797fbb,d384a1a,2c26d7c0,edf866f6,9addb763,dc44b112,dc1cdc5d,a085725e,d947778b,40a2baee,98dcf460,b084aeb0,3f96658,4f990895,b15e3378) +,S(1acb89f7,55a51f58,d8ed16e6,99a2294a,b2f4bff9,2fa2d1de,9883061,4ed4b5fd,5b243df,31c3bc95,79c47c57,58eef875,c18bb896,424c0293,22d729a8,b7a32a21) +,S(fbced690,b601e450,2f0ed32b,8c2ac448,31c4b327,a4ad9648,97637b08,2f3d3912,3235804b,549210ae,8cb5bdae,e5b1b474,e682cdfd,8af4acd9,8c0c19a3,cb5c017a) +,S(75339a0,82043d85,54ff592c,186a183e,4597a0ff,48f280ac,d760d134,9dfc6b5a,dbf1aaa6,8bd5db0d,8cdcfee7,de6635b4,b7877ef3,6da38418,5688fefd,dc584b18) +,S(d83caf1b,2994a763,77a2bba0,3c644e48,7f170d5,845a7d17,b8be8bb9,84b0ad1e,e479d930,6d2a405e,f0be6418,3d4f8dfc,a7f58ff,95df1e38,c92a401f,17745879) +,S(35fbbe06,39d9fc5e,d595a67f,442d7adc,ae6f566f,4641fb76,149d6c74,42af49b8,5eaf204e,6217ef53,1ab09a53,e6cf4d12,46d6c4e6,b71ae8ca,4e821474,94d00680) +,S(d5563a62,bd6fba1d,e252a5a5,9c03bdfa,6c570145,71cd1a31,bba43700,2a7c1251,2f83b6a3,2efa7b70,1b4d3262,9e7a8755,8b681d17,cff0b992,1e102b7b,f851f543) +,S(8f2a2a14,a834ec79,107153f0,ffaf8f46,5cbb46c7,5a72d07d,5e2af498,f3359b75,30ac7456,5c946e21,73bdbd9c,dc999e79,260445e0,dad2467b,97234789,a4de1184) +,S(74482ce2,45605bdf,f7d586f3,c2e343a6,8f9579f2,543f7f7,22a4b352,24361b4,b2cae040,9ae59ee9,bff4fb5a,34847ca3,e4acd880,e35e4d5a,5ce47b70,3cc565c7) +,S(ca0c158f,cd362d9e,3724bb2b,f07305a9,5adc440d,24270efa,2a8f208d,7f540295,9e1daa26,5a5effd1,29f62b,bf0f5c60,c0c2b73a,58ddbd99,c832125d,3927e7ae) +,S(9c5403ab,b8b04f47,5eb4ac6b,5d526784,8d237d3d,c36e8698,d59172c8,a9d9e268,89cd0c87,9d02beeb,ffb6dc2f,fa882711,2071cde4,ee71a7cf,669f64b7,d463fbb5) +,S(e6bf2997,5eb88332,64169169,62f49080,29072e85,797fb699,df05526c,c4ee0de9,ae9de06a,1952c472,6047bbb7,b967e6ac,db33a123,24b07165,d2caf737,3fa40068) +,S(ae4ec439,e4392deb,5e1b1565,2310d52e,9cf5c0a9,8753a95d,d7b51e1e,5889a744,1400b900,c3159d2,25ceac35,4e566d2f,4e6f057,f4664b8f,465b0f53,2ba61852) +,S(c6351ec4,27d1d6c5,64c05959,ccee21d9,b086a881,3f4d7406,ba8d0ec8,6cd139dd,b7173d5f,bec7a8da,89c4cfbc,a911687,f39a455a,9293640e,7d473bd3,ef2dba3f) +,S(fe44937d,a54556c2,a50d9538,98abc367,6da5d722,6c6d3379,20092042,d1219cbf,c5c2e2a3,174fffd5,74761486,669b0cab,5a5eb21e,be669ba,c5c5a4a8,46e404b) +,S(760dd500,b18aa066,19a3977f,ddbb6947,d092649e,485f2b6a,d26d01aa,445588a8,cac47a22,6da2825,38126d62,38751a4d,93daf13a,420be353,3fc0f7ad,db68c20) +,S(8bdd111c,e271b136,45d00636,f2d33c92,df570cbf,6bbdc156,69fd898c,ce4ea8ff,884f1430,8ab84796,d61e557d,abb4d15d,15114c0b,dc770388,6ca3ff0c,622df5ad) +,S(406c6d3e,79fed3cd,16d616e6,7fe004b5,4f589594,ecb7ca6e,24210224,c5b4eeb5,aeffee19,f82cee83,d4796668,8545f0b3,b8e61877,f34a0b23,c6a3573c,b98c9b7f) +,S(c645ea95,2580652e,8e05df6a,3d208df0,83e00eaf,50cd7d4d,a7c51458,324a41f5,8b4b9cc9,d3f00fce,332d2ae8,2874787a,6c6c8008,a7577ad5,d225f951,82e8bd2d) +,S(813cd833,dacd8916,76af5b48,5d1ff72b,df03f2ce,c7657e6d,249e79f1,f12d7476,c364d1ee,f5f1d5f2,7438c58d,ee926c18,7162cc71,383e9524,b80cbae,3cea17bb) +,S(fef2337,cf88e025,d70e2a44,e68c22bd,95371f36,14ad9009,f2ba8286,290495e5,b622fc00,8b0a0f9a,9a36ddeb,ce10d871,e5dcd7e9,65ed2784,21ab5891,6aaf7404) +,S(8505810f,22888b4c,c8bb708e,c1e4df79,a3a361d9,5ac2b259,acc18d68,e50b0952,b80fd8aa,b7196e00,3fe24ed,fc6742d3,e7b2115,967f838a,2ef00345,3dbd4d34) +,S(b7aa2500,c77effba,3e93a4e0,b09a0f52,92240fef,4282cae,4c8036ab,2e5e5561,85823a06,1fcf2328,2dde378,8802d211,fb2cda3c,316dbba,d30048be,1295d7c) +,S(6dd2e626,181f0007,6ed53763,32493f55,a77cf5,3c268524,2be805c,7da06c95,2a6a76bc,b3f96c70,78920303,c5ed3208,170fa969,6c5264e0,c3cb1d86,ca322da6) +,S(ff5181a7,ab79b40,a3afdd39,8ac729cf,e49a6a23,2fa46f9e,4ce0bdc4,696e9f9a,99c20ca8,b11b6a05,47e81074,8a34c606,140eb3c7,ce5c843f,60203249,62858aad) +,S(a5dfb758,32aa580a,790fce58,b4c04a1c,9de648f4,19ec33f0,92491275,e8243ef7,78a66f07,e1466785,edfd5523,99fd1935,1ccadfb,e3b25bf9,d5279ed4,1d0b9fd9) +,S(fc5e4688,ea6e4553,610946a7,dd3497e,a5f698b,82d6b439,6a21e082,a9aabfce,d1b32a9d,761df7cc,3d69b5be,d7aac28f,976be204,7b2aff0f,2824fb00,b70d697a) +,S(179fb126,a3cd9931,f135cbe7,2604d3bc,83cd986a,d9a7900a,17436875,d3507016,dc2a57cb,b0bd39d6,c8daf32f,fbe6b300,52cff0d3,12e84b72,c00a7d76,3578e749) +,S(af37b7e,cac16810,9c51fe45,b2d6da7c,3505c1e4,bdc88b10,5a386fcf,e30a6c1b,4dc24b79,61e9199a,f594974,32c9352b,4ca9d735,84dde4f7,a4c0127f,21cc17f1) +,S(62d66f6,b534cd8a,66236ca8,5b7de9a1,eeb49aa6,e65e5298,edd1a99f,96fb1dd1,83c05dc7,e69dcb3c,86dab3d1,153d93f3,e9861239,6e25d3f6,6a6d637,248f237e) +,S(6a40f396,1587f5ab,89280eb0,568ec9c8,6958b4d,d8a379ec,2ce2489b,7e451ece,74972d6,1100a0bf,7751a400,6093ec78,1fe16c82,baaf0e69,74142a17,a405da36) +,S(2838f8f0,c6e20e53,9ecba383,c6e07a2c,5022d436,904e5da2,b91b283e,40bbd6bb,6bbbf962,2b7c41a4,6b72a30b,d051551e,e1227362,b0664dc2,509404c2,819b4985) +,S(21e927c2,82cd4635,c9c19c00,f18ddfe8,7aa9b60f,f3000c3,2019871e,a443333a,6834c23d,e05bc59c,f6fc64a3,af61f049,7c247d86,f76a2ada,7771dd16,999febb1) +,S(d9817ec8,f88f9cef,92cf9df,1fa9099f,3f10ac61,fa641ddc,9f36e854,98822571,53c57b49,4d84c3e7,679060b7,c7c8d4ad,f2db0c4c,c8cabbc7,5c29ad15,80b963a9) +,S(6eaafe92,1994519c,1c61bbcc,c1ad6ac6,f7a2d0b4,fd88354a,6a458e78,17503e30,f29a7f85,f3e91dbd,9e011055,f47a5079,7f55fa4f,46a6b188,ea4694d5,a086b4e) +,S(2bd45f,1625722,2352b5bd,a6d8e2b8,e7d23c3,f8497fe7,348a8d59,97b5cdbb,b5f9d5a9,8ed6387a,41397e54,6b3ff76c,4c6bf446,3093e979,2d1f8748,7a6b725c) +,S(176d02ae,cf4f1313,ff804e22,326d6a13,8b641e2a,3fd4d38f,2c27a35d,f1f456de,5ac13641,d2f19a4f,77097a4e,8eaae498,2afe9494,9188e411,e03ed031,fed9eb40) +,S(6d0bfca8,6296255c,1fede5ef,8d04dad1,2b6625fd,7bc127f7,3f6b82d8,b257ca8c,3c5c434a,81c17be8,8101b5d5,ead55e60,9d9dfb10,c5ce1b41,484d5fb6,f595fc10) +,S(b67d3fe4,f6617324,a4063fc1,142ff4b8,2a605a26,8b8fa146,697db96d,570ecca8,63ed93c7,a95a0ea2,9ffd6090,5c096042,b5562997,4957f47b,2d5bca14,21114bf5) +,S(c171bc24,fd80dd05,4eb3e3a5,5f50c9a5,322989c8,a1213179,be4503d0,2fb1f1a,2ead84ac,7528e7ba,982fec81,4b68ff7f,7aecf675,281f126f,9f41a7c4,5deb2e03) +,S(c4936f57,96269373,21abb8d7,df07e4ae,48ae1f18,ee1f8ea5,6682ced8,ec911593,52ea3664,1b441154,81805582,dcddf216,80eaadf7,4fb324dc,67439b03,aaccb1b2) +,S(b0a38c84,ecc73fce,200658d3,cb43cbe8,e0df114b,5d1ff7a9,33158b67,b404dae0,40c381dd,fc600cfd,ff24d7c,988cd4ce,74c18fe,130f4248,2ced320b,b91f2ff3) +,S(1610da0b,300d59db,d8746d5e,17d71ab2,e7e9c1d,2b43b688,656e570c,60336b82,8923b2e2,fa3fd34f,eff4ad22,7f9f6638,745167d8,fb769b34,b3bb7e12,a25c892e) +,S(f6723495,10cb5b38,da909d65,333adb86,d22ed855,74d24d35,83294cfe,ac88d999,6f726bb3,891187c6,3c74392f,a1e3ffea,f55b9a9e,76e3b584,1d13dac2,e888c740) +,S(3cda21c1,d048a768,d2863f4d,1028459b,c9a91c31,2626940c,f762c074,23d85796,af05c34b,4a15e00b,b6ce97cf,501316a0,85ba33f2,cb536f27,324f5506,54a8f03a) +,S(24e1bc3c,84c0ce3f,52e1443c,1ce82330,b69bbdca,f09724d7,e616135a,d9f99c0c,61385dc5,e5c36e42,275109b7,9c22940d,3ee4c679,99802e67,3163c114,be7fb0eb) +,S(f9511548,94dc4fd6,e2907990,7da4a5d8,ffff1eba,4fe12201,a3ebadec,2620a2fa,d40669dc,1eee21c8,ee1110c2,def5de0d,4f08ca55,6758dd14,b6f3ce64,46b2fe4d) +,S(c6808c80,61dd7e3,f6fb5ae,d129d23b,c2101af0,130537d5,4bb99baa,1b8ee268,2fb3e2aa,77870909,993f9d91,bf670cf9,bcd5abfe,26ea9990,6f9805db,c8707f84) +,S(ca952b81,f79a35bc,effc9f2c,c66c9928,cda6330f,42c44f9a,3191ea5b,5f473c3c,aa53ac41,f34fee5a,2028f7fa,8ffd5106,23cf2dfc,cfe5a1f0,99ef3649,d7f846b2) +,S(679c1de6,521c29f1,9b0d3c5b,ab481e53,d01ec2ca,c719fbe4,16054bae,593c0592,61d4eff3,5daff1f,a4bb875e,bbb42722,9cc996d0,405c74d0,6ef0c6f1,31ade7c7) +,S(6f7ac468,d33618d7,8c59d849,3571abb5,1d445a43,af10fbed,c5d25b13,58170f76,9187ac46,f2076aa,5cf4de93,52e5437c,4cbd2220,d8070172,807e84c8,10a05090) +,S(f4ce85c0,86a4fb78,2f081fe5,379984c3,1a7aab89,ef9ac386,a6a8a11e,596278dc,89d6d9d6,75983a6a,d1dc4c45,a3dafc1,cf951dde,2a038261,b414eb94,f9899886) +,S(18b0b225,19360c19,739623b1,7850107c,32ca6b61,295a8161,fc9d2e1f,8d1e60d4,4d8fd58,98ba10a7,3aadae04,a9ed18a7,8c48bd94,7825f0f3,b42685e0,d391dcc9) +,S(3f75a866,537d022,f6b9b18a,330ecdc0,bdfa7aa7,5b213f4a,876705ff,635d8eb,fd0f335b,b4f41615,7ea2752,2b8aa40e,dcdcacbc,1beaa051,97ecc250,f0782cc9) +,S(58310e74,290245af,c4acb91f,20b29db0,f5195039,24b9f76f,16952141,875d0124,f79e457c,364b374b,43c8d6ee,b408cbb2,94fe8eae,c6914427,83a74757,c8b27f98) +,S(90692ace,4fd3c4cd,3c808952,d5ea0781,2192c807,4619b8aa,4274426e,feb7f6d4,3147db2e,7b3b8506,625c21bf,8803c5f4,e7250b0c,4523a6bd,e25e874f,76d1622e) +,S(154d18c9,6c441173,ba7b8d2b,5099d9d3,92ae7e0d,57419144,229697cf,52384f73,1c196518,31ad8cc5,ea72b3f0,ed0d30f,78b773a8,1f54fc37,29043a35,6fde93a5) +,S(311ebd4f,5f52bdca,290dc97c,73102ecc,421a0b07,4c53c052,11b0bfc7,3b6eb94,69d17492,eca55f53,72b04c34,6696454,ab779ddd,8c7eb07a,34c8971c,b5168019) +,S(f62a716,6976f82d,b62e48a5,1eb45464,c845b71,6436d639,a9aa0a06,feb57d0c,a0b93a32,3fc8c047,3c4198e1,5ab5f499,e3eaa4f1,4bf99a69,b3ac303f,34839448) +,S(c23e0cdd,5e39eec0,d3ad195b,19294bc4,30c11eaa,67c6e87b,a4e2a88c,60998ed4,a521d1b8,8e409682,bf7b7daf,ff45f697,6254b8ce,6c63985a,ad2d9cfa,559208fe) +,S(742ca7fa,a8b4a98f,28040f8c,15db6045,70353954,b862c223,c7979eb2,3443ebfc,251ef412,e97a7e21,292ad45e,46c40774,b97a78cc,7826e45b,cef481f4,a64b838f) +,S(622a14f9,7bd04407,63eb5d52,c15c2f3a,ae185395,e89dda70,3cc4c439,60c5592f,e5db52cb,ee60b303,69da59eb,87ce10c3,c485c239,ae1c849d,32e0e239,df4d4d46) +,S(3d6dbb7b,4e28da6,b731c67a,6c038107,c2ec325b,6b10e31d,9b7d5273,fc81e20c,f0b619ac,febe82f,8c4caf5e,6d4710b0,caf89c2e,1a20073d,66ebe05d,69fc2c9f) +,S(d450d441,bc191b5f,9c2556c5,a56d20c4,48afec13,c7e4b9be,320ddb90,b4c320e3,661be65,b5eef8e8,b357f521,d360379c,585c9e71,c27bd038,f2d63f72,6f6606af) +,S(82f9dd1e,ddb046b2,2b33bf19,2970e41f,c5df0c45,f1375133,fe1b365c,eed1ec7d,cde9eef5,554476e5,e775e829,1d38a572,1d055c4a,925c7eff,35a389b1,388e18d8) +,S(5227c547,834a79e2,d6fb0c3d,720661ac,7ec0e2ff,5a1480bf,3f31ac82,cfb2650d,dca309ff,621c591d,aea1bada,bb1be76d,2fa30a0e,1c83b4b0,d66cbd59,7612c0b2) +,S(3eac813d,7e2c8034,f1d58217,c4372a96,a1fcae27,b29ed9c4,e870034f,7faa78ba,94005cc8,7b8f7aba,143573b1,79aef942,c1519b3,9c63b58e,e420a875,7c4c8b80) +,S(9373c48b,50fb0243,b42762e,3b80994d,61986116,ba2c0677,a38daeac,7dcb21a0,295f694d,70f8295b,cddc1c76,141ed17c,a1cd8e5b,79909785,dad43e92,9247b250) +,S(14019457,db851046,42b51ece,50fb8d94,201a80e0,f29d52ad,1af35e4b,8d82c6a8,c47d97c9,df2816f9,a6147dba,7658b5da,f9588dab,8aa393c5,8f721786,9c498b9a) +,S(1b01f484,ce98064b,f60333d3,65d926fe,ee1cead3,c1497c88,8409be91,2288890b,6817b86a,86c98512,634bf90b,564ce109,13fad61f,c807a256,36a5d6aa,7f2d6005) +,S(5bad5660,f615f36f,6bb9ff3b,19c07b74,9519caab,fffd98a0,4520802c,88b6cb22,4d23780a,e6796a72,324c369b,1987465d,90540788,88987513,13dea0cd,69f90dc0) +,S(7044bd7c,29d2a7cd,d662bf16,90d5ee35,93175691,b62d68e3,f8f66ef5,8304c509,f263888d,52d74133,60ddfb1e,d1c09b9c,871d6eb1,e5833949,13d24973,5721ce12) +,S(186411c2,f90c5402,6445dc4a,4764318a,f3acd811,52c01dcf,d11d13cb,a8c02afc,462b9556,1bf18dff,8a4211d8,89f420d2,122c4ea9,7fda3d23,558b6304,d25b7aa3) +,S(62ea528c,185fd551,745c1512,6fbfd40e,5f8933de,4e1e3b95,92a93b0e,b762ec3f,276da42e,3c8a6755,6be49e00,2e42522b,e3b95e15,39a4708b,36429a94,4f6a86a3) +,S(5e2c7621,efa587ce,bd3c2392,a1b8dac8,50b15316,c42570ed,7270b521,a65d6cc0,c7faa23f,eafb70ce,723338d8,19bebd10,bae703d2,1e72b496,f2f95b6,e83d7d22) +,S(7e27207a,b80f124f,9694f143,9a0cd895,2c67a719,4075d9fd,1bb7c9a5,a22dfa3e,322b729f,e19d75f5,89749527,80f3ae04,48edf9e9,d8c24267,18812dc6,bef5e602) +,S(3de40b43,9077ea26,8d94aaa1,93e9c7cb,98e362a1,551b9b10,d5eb64ce,15986582,ba36c2b,e0f9d3d0,220eb47f,4ea66d01,59236411,2898172,8582d3c5,19576943) +,S(81e94808,7e89846e,6c7e5ad4,feb8f0da,4553e460,e3e4620,d87a206c,9d3232b,e216962e,4068a44,920e6a9e,f03efd5e,afae7f96,3497ecaa,dc741c37,7e9943b3) +,S(3056eeb0,d00a19cc,bb5a2ac7,f320ea3a,4e931187,498ec23c,daadc820,a34f49da,c6803559,271b265c,80257585,1f0a78e9,85abeaac,cb570787,f398766c,aa21fed3) +,S(9b1e1189,752fb763,7a61246a,7134145f,86b973b1,e44a5e7c,c59998a2,77ed64f2,f6793c87,9b8c380e,65296c8b,eaeb98c6,b66e0be0,d03865f4,4a09177,5dcfd332) +,S(807179ba,f1f9ce93,bb1f7dc6,e3c6514,99077419,472b9d8a,1a8cc4e2,f35c0c5,36807219,9966eb7,f18dfb7,d3316eec,54f1a9a7,7214d4fb,ce3f3ff2,935e2ced) +,S(60dd7b7c,cbcab93b,8ecfa461,8cfef03f,a74bdd47,9cb90a1,5e46ca7c,c1bafcc8,1d24d147,9987f779,90cde228,22ea0cd4,4236875d,943eda25,fa25096f,e16b8ce6) +,S(19daeb26,23383b3d,d15b0075,77a5e92f,bcedee4c,91996546,a7c52200,d243e4f8,12676559,3d67fe33,b1c01d4f,cae44be1,5f5f5e31,1149962,83ce8f92,f6485e3) +,S(f42f8e1a,813dab8,9e4db5de,27445215,c0fb1cd8,91c9a96f,ca5ae1db,14e84361,3cd2ab35,55705994,42070743,d01fe633,34819d2a,af95e97,6dbee1b4,e3ba2ae) +,S(1a2b774c,d5d0dd28,26d7c4e5,886d65b7,a219952c,6a413d2b,9fa8f765,73fe2bd8,4e2d0ecb,384a158e,e57da809,d065e39a,27830625,400c51ab,dffdf615,5d88032b) +,S(e9fa7d8,94c55075,1ad1731a,b322fab,fd3d17a,889bccc3,73e44e37,b4c2c880,67528cad,e7987d12,77c61681,36abe0c9,5dfdce09,33129f27,ffa9d36,53673bd2) +,S(5347f349,e54c301b,abcfd8cc,50f6fe6d,8fcd0fcd,861757d2,bc36cbfe,39f460b8,16d08dcc,2a837b6d,f9fe2ffa,b188a966,9d39181a,ed2aeb40,9ed17c8b,554e9d27) +,S(e20e8cea,4450bf03,149bdf60,e95f7ed3,69fd79d0,aff9fb8c,ef6e5287,830c7ddc,fa256932,fcc569e2,613bc0af,5f90263e,6db633f3,6cebfe46,4c70b043,9b886058) +,S(69132e10,b3a919a9,8a7188b3,e9afcf6c,2d53859a,5955e114,a41f1310,55ef8441,e6c339cd,ddd26e0e,ac4a1c2b,39e19cae,2d67e726,8518b750,94cb5e6c,b525d84e) +,S(11e10c95,9bd9f79d,c2819a87,e17c0de7,9105af6b,fdbe3f6b,88d198a7,106c861a,27c29227,4a3677c7,381fe385,8382ca38,d4b98e91,af4250fb,40540828,246d5c16) +,S(785934d,e1b1827a,471d7e59,2a4c3475,3054b00e,b8aae372,444b00ef,d9d894b1,7b8dd2e,a038d4e6,23f0f1f5,a2f75dbc,fe34e76f,6d106ae3,33d88a07,56dc4a60) +,S(f09c814e,8e66b8e5,930f1a49,28b28e5d,206f4108,fe99f04f,ead93096,1cc17605,469bf934,b4059a4c,4a942214,e1d86fe6,dc900426,c7d0eddb,8d89e86c,76d60f24) +,S(732901c7,26982b9f,ff1229a,3e8f7c83,2f47437b,412d0b3e,274a73e4,24ad6480,6b82e2d3,d4830086,cf416593,9b04ff7a,89b835bd,81cccd8a,7a29d47c,b70da3b7) +,S(b8369a11,d23ff4ea,99ce166a,4708ab9d,389cefed,b1843d8d,6fc11f74,7260faea,f4346c36,63ec0ab3,6ac12df7,f61e9848,c2d4cbd8,c8e6e173,2d104d0b,aecaef9) +,S(5499e409,3df85dad,411b8675,c09d0c0,c25bfefc,2afb0228,b94f834a,34ff83bb,7775c877,8fc6e8d0,519a67a8,7d2fe9c,c8abd8c1,15ae1700,ad1a94d7,925a4c78) +,S(fa5bc8e6,fa9b13e8,ad787ba1,497a6b97,5c34a64d,a0da5b5c,836bd71b,88c93740,8c919cc1,19e45de1,54f6d0d8,f22d3b51,169b3f0d,181bb40a,56213cfa,a4ad126a) +,S(a871c481,a84f4447,89ecded1,e2b1f525,9b1d4ab2,b16af331,199f89f5,730cdb0b,c478609,30b85d69,1ae45d62,7aeca01c,9f10a119,500d5d4a,c317fdd7,8de4a103) +,S(63d3be27,66d33bf8,f7a38577,aadd5d9b,234bb77f,d206b056,379e023b,ecd25616,9509d09a,6dad6da0,aa5151f8,dd8e3800,abd8a799,2276ea0d,3c958f76,498ada87) +,S(413ab945,c133d383,d70e81d3,34bda75c,be7bacf5,e49d71e3,7a884489,adb28f8f,c3d49f0d,6c65f6d6,1c9c84df,a4138076,f0168916,393612b,837c1df5,df710a02) +,S(df070f4d,ce208b39,e2614db,77c6aa32,2a50bb26,2ec7141a,b1e26835,911b85c2,b0b1f453,1815fa7,83609235,da7bec0e,f1bf2ad3,b0e71f7f,7c18de8f,83f55a3b) +,S(1ae86e7f,300efbe7,8cc933c,f8cda339,1f0f8f7e,411e6c0e,708a0d75,a1ab1815,d322b34f,f0778782,7d2da5c1,4d6bf17f,f8afc8a1,8051a724,bbd719e0,f5f31a2b) +,S(2a38dfd9,ee86308b,e0c76ca1,8dbb9ec0,fbaa86fb,51075887,9283c070,f31106a9,69cb45,94832b55,abd6b686,f67d493a,9d45e4a1,7d557723,fbbbbb83,7ab30cc4) +,S(2c6d7ab3,b1c3301d,65c79d40,583b566d,3ee39014,345a4553,a77a8e46,95b779e7,eb392dde,318bd27d,446b814e,73f9cbf1,380e38d,fed25022,bd584585,d671e470) +,S(758739e8,2aa2e25e,b1d8e027,b0e401b2,c82db2ca,549ebb9c,e1560ec4,531c5c77,d3792987,c3da2cc5,5760e52d,a19ea1b4,d0c2cce5,3f612760,bfc28414,37090975) +,S(7ef11cac,99fcb66b,71de229b,b34e82c6,e3149f85,ba1ffbf7,f22db64c,6a72588,64d7c546,28892864,1db41465,a134cfab,bc08ea64,11f5b2d5,b1de9f0f,7ae41b70) +,S(a7d48b06,c66ef847,f17b4b3d,ec40eb97,cb91bff1,c06d4a6,5d6db8c3,5561e4c7,2f22aae0,d6eb7221,d24f025d,ad1768a9,a619d6d9,db9d8e74,948d9263,3d0676f) +,S(a14d7354,1bb93625,d80f654,af67febb,d774e42b,6430a14,a907c52f,84088ab,adfe7f75,2b080bb6,89c031fe,c7c11d1a,bc303b7,f1a0ec2,38a4dac4,afbb2a5c) +,S(16076f95,b067381c,9d71cc9a,928f10db,43553332,f747e33e,367cc7ca,ffaa5f88,5c05040e,43a29d4d,e16b5e42,b672f618,8f0496ef,f307c269,13df7c79,ed2b1502) +,S(973450b4,a297ebf1,70630a71,fa74ae2c,8f3f8e39,18ff73fe,41bd1e65,5a5acd29,ba04c21f,e92ea639,99d5d87f,77181c31,ae8ed87c,dca22054,2f746fad,61f63039) +,S(aa29f7ef,d2f06187,108ab23e,16d9f3a7,74ab6459,550048cf,e1ddca0b,45fb5942,431cbd5,c77b31b4,d8b8568d,b092e721,a02d643a,75621eb6,1016b363,9728e2e8) +,S(bba61b3e,52614d14,358dc227,e0c0ea6c,e4dce364,fb7e0500,72d0d780,14642d9b,f33e0e72,6e9ee195,21fb4a80,2510156b,230a7ff,6e4c6b38,cd38b3cf,65336d6e) +,S(911443a6,979ede22,f23df6af,e4b1ab,73867dd7,a47e9268,3e3cd83f,241bfacc,a0e5be1d,31cf0375,7c2469a5,90f3493b,e43a99e2,755af9d8,b87aac67,ee7a6488) +,S(ff2126cc,5698e6c1,2da7f441,b031ea11,30132b86,23994f64,b332a8f2,87616d41,c616d5b3,79eeaae2,b072a11a,d2b316c1,b2c851d6,698b6d86,7fae1abd,482e91d4) +,S(2fe68e9d,de151731,12e1653a,2a6abce7,615062fe,a5375ef6,a2be1e90,67f6d8ed,c24e4b95,718acdfc,cd9f39f5,eca6f2fe,74fe7f9b,ae6aa352,e3651bbe,5d81c9b8) +,S(dc08aedd,90e96f6b,892ee62b,1f719619,6af44975,58d70f1e,7294863e,271ddb99,7250d846,1ac24a2e,e74bc5a7,53d5361f,8c012986,4364d84b,4afe22cf,c94aad99) +,S(e9c21052,f350d1dd,caa82594,b6eefb5b,f8f01ec4,1a423278,fba3951b,fcc7eaae,6992071d,becaac44,a5cd1537,cd066f2f,c432f198,621b70ab,360ea8d1,35757784) +,S(110d5ac,7838b9d2,d33bdf5e,8aed8529,5ceb9334,d409074f,3c26e3f9,f0cb792c,7879e339,427d8425,b597e76f,56a7a6e7,9a8cb00b,374ac98e,9cbec66a,47bceac) +,S(92982af9,ab48532f,cf2ece2c,9ab346b8,7def4729,8ebcc03b,91869aeb,42f9bbda,c6bf5a6e,8639e2ca,772e8c36,5f824b3d,331c7be9,4c13e9a8,ae6a779e,208a157e) +,S(c3f07f47,5246bb78,eac4e9cb,263c774a,3447acce,993a9707,14c1b553,79013162,f1931fa5,d6fd228a,a5781b35,45faba70,df6bca90,936acf17,f81a1155,4897e136) +,S(37640e7a,eef3f326,a598d363,df4f46dc,8f0decb5,ab6e368e,62294c53,ef3fdc7b,54fe19ac,83a074aa,796feef6,8d39358c,7be8848b,433e1eaf,9982701a,3eca7a1d) +,S(e903363b,6c90bd,2bf15176,83411d1d,aa9f0bb4,a22b5f03,ebbee32f,8f0cdf4d,fa44eae0,78b4b6fc,63abac71,ce0a6e0e,16b42d80,94179f1a,657eabd8,7eea2480) +,S(3c5fdd9f,7313d178,312bc477,849ce90b,a22770df,867a815b,2bd1d1a0,600afb6f,d81524ea,9e23ad00,bd7197ee,63457745,75795d6a,63b8b15,a19cf606,72159a05) +,S(40b540cf,43713ef5,c8b919af,6c991632,e60c198a,677887be,33b84c70,7c0ede8f,54586256,7352c824,49ebecbe,6eaae259,8e1cf694,fbb296bd,c14a4a59,240798e9) +,S(67da332f,f57adb72,8eb8b926,5a650e23,bfe5271e,396d74f3,9878c22,6f912053,91aec263,d7b74e09,b4fcffa4,87cee236,356e4fdd,bfa257c8,f3e3be0f,3a3b16f6) +,S(40cea066,fa029178,5662c994,db5b1153,e59fa121,c9133c2,fe1c6d20,91d44d98,61475cc7,a5ff5251,558f258b,aa8d69a1,52ed6497,c8ffcd55,2b66baa5,534df64c) +,S(c4eed050,248cf186,f8e2c079,870a139,c0cb13ed,2cec040e,d98a18ca,9b67ed0,50e9997e,263c7441,9e71405a,4d342e76,c5548e,1a7a3cc2,97e4e00e,91fc476c) +,S(676b60d2,14e309a6,8c7a8470,70d5bf62,8b71b7fd,322ae568,56fd4a48,9f3ee83,16e0d8d,371ad6bd,4713e9f,7c5f329c,72215cf,21a48527,35a0df71,205b733d) +,S(af268996,29117c69,c3beb193,c5cf7944,d4d3cc1b,7481d08e,1a190b45,c03e1fe7,359e17db,bdbe179c,8cb75ead,8a0e3c86,2b1d7d28,4aafd2c,e45e7b9a,c6d83ebf) +,S(62e15cc5,a30d1388,2b3c3890,4e1d11db,97b0a7b7,c658175d,e438591c,ed1ed489,fab66c6b,ab7b5ed5,815c81ca,65cf364,f4cdf8fd,7a6fe8e9,ab5ceb66,3bb4e8f5) +,S(6c7af496,df980977,41f5068,f34d0477,7da16397,c853539c,1b0c1263,2e43ccaa,4eb0e461,5c6fd9e4,3aa05201,88bb264b,d55b3a05,fc2b6c8c,d6f5f51a,4314f6b) +,S(757a45d4,4c662311,289be914,4ccca5ae,6ef89f51,52d66a2a,9be64096,cfc8fba3,732ddb9f,62fdf217,44d7daa6,35ca3e92,c3b84061,bae4c220,13339e06,fd4da7e0) +,S(14978c08,f1eaa9ce,4d878db3,29f0bc94,43301fdb,24b525e5,4f9f27d5,7fc114f9,439d8e8b,2b9fdc0d,85914620,9c883731,26e961f6,82407867,b10bdbb5,3074e5b7) +,S(3f231c93,760d9198,4a8d9adc,abd83c1b,3ae620c8,f067d103,6d1e5e02,2a72bcf9,95eb3a0,a928d3f7,dff3426d,763cf6ed,20d6df2f,c5dfb17f,c53ce0b7,90412bc7) +,S(c90268ee,75cc8e7d,7fe84298,b1db4255,80c3c45d,3643a280,e3d5d0f6,7337b616,f566fecd,1158d49c,c12a1dde,d0b1fd7d,d9cafbb6,ed3fd09b,48689f85,b01cb59) +,S(6457f0e,4d6cee8,7a2c0aee,85306a02,42c017d0,1e1c9807,5b460732,5c1d82f,67bf2f81,262de4e2,ba9d29aa,aecc9315,ff56c3ed,2e73d438,2a3dfa6d,faf9808a) +,S(ddc591c,1abcbb88,3de13bc4,490a66d5,3d96c97c,f1e21ae5,6a430c1c,39b1b629,80ae50f7,b81f043b,e3db78c4,da7b6078,871d4813,1e076ad9,de59fb27,b942f72e) +,S(22b19bf0,5efeb280,44b43bfd,7a6b3427,2e8b3c1,f6635ec8,d6966a,6667a252,47f504fb,ef2cea6c,8692d0a5,1f492560,151429c3,e522c23,2914e880,9ffdeef0) +,S(d5883bd6,c13d93ed,50371ce6,ed6c4263,395c5d28,f589c84e,cb9fbfc7,2dca651e,acde7b79,969cde2b,9a580387,d8e3a99c,45f15d38,f2e2ed79,688a3a95,80aa9a8) +,S(9615736a,4804dbbe,439f2f82,ca576623,a1675aeb,9ea9e40e,f6b910b6,c84af16b,a0967216,67f9dce6,25ce5331,62d45477,31be7427,74eeb1ec,4e3fe578,343c46be) +,S(ea36bced,959bc461,95e730f2,26224652,2472c2c5,70df6832,befa40aa,5c600e32,dd52094,82eb08c4,bc233090,2aa54333,87d06885,a9357f40,246348b4,4d97fbf9) +,S(44814860,ddf61b77,77cad443,18c21686,85c614b0,1c5830b3,b178a52,d85539bd,f3e5fd15,c71050b7,280643dd,bd2c55b9,219e7fda,cfbd2e98,94fa9a4c,9cc7ce75) +,S(814454b,cde86996,56b44c39,69bf0a8f,31b6d032,40098f9e,43d52266,cee66f49,8baf21a6,601db25f,2e18f5fe,decb9f31,9a6378c,adbff6ec,99bfa2ff,8d26b5c6) +,S(1ff790f1,11f7bbb5,b6db5f83,22ac696,c1de09d8,e50b9f4d,641ef76f,d43fdad,145d0aae,c218d6c0,219ce9c2,313b4962,f873c5c3,5424d3b,536c1543,14fa9517) +,S(275cc6c0,6a8faf20,c3c1e88b,87e27d35,661c6401,d3a1bd96,18cb016e,fdbc6d0c,45cc522e,97b61ff7,696c5780,638054cb,5e97b6d4,fc4a813c,7000a633,4e9f2a7c) +,S(9c78cd3f,874afab,23874f0c,8a84fbc8,a6d032f6,7fef6c6f,29c90513,bb6926f5,818a2406,fedf958f,7efafc4a,584ff6b1,7bae1b65,f67d1086,c3e013a2,cc318b1a) +,S(3c060395,f2cfe9f9,e3bb4afd,e5a71e03,c5a92491,323de27a,c9ebe1b,170153eb,344d08c3,8021fea2,6f55c0c5,85af3954,afda21e7,14cdedc6,8ffa3771,43b2ca27) +,S(f4b61a9f,7392b960,752bafd0,ce521e4e,57bcb898,cbb2dd9a,b0f7db8a,3ce5ff2,e412589e,f3678029,15813dfd,acfe8056,2a59894a,4c87640c,6044656c,e8998d5c) +,S(418698b7,6230acce,49505275,a0c01e9,4eb356a2,e3c242ff,470b64be,fa91ce85,cb9dfaf5,4c64ed94,f97e03d,30e07876,9e5a3142,d0fc0902,5e20ac2c,21c4ceeb) +,S(809cbcd7,91c1f309,864ca343,3d9a11dd,2db3d9c4,5350ac5b,27f55e19,b9941ce2,8161347a,92fdcb92,263f1d85,2923a15c,42d5012e,30d7d9b8,623cefa6,12b06bf2) +,S(6410c007,1d1025c9,8ce11509,5359e962,58c6a115,5e7f34fd,30fc8862,f9569f23,d76363d6,2661a55c,6c211bc4,13b1dd7d,63fa6964,a03d9461,e2870f2e,54c87d29) +,S(8394abff,22ef6051,7517e352,12a4dca,103a19ab,4091c7e8,fd417a,98fcfd2e,20d0ad3e,bc0fd15,fd405417,61bfbb40,8e37975d,a77321b,67ad2ef8,35732c0b) +,S(dbec1fa7,765386c1,d7558cb1,f19788bf,ce0e9fa4,7ca41edb,2f2d9ef8,78a04308,5d7c918e,335ef23a,934fc963,48dfd8f6,ce79885e,f4c463c5,b2645c8,48083ea0) +,S(9d6fe17f,3f53f921,893a422f,c9f675d4,652cbe09,a870c81d,8b2ab9ee,9a591cc2,fae9ccd0,b22ce7e3,2e7faed,2d47c36f,25cac5b1,e56ea936,a6811f11,8d485a2f) +,S(622f8f9d,65c4270b,1479e4d6,6f82fbc4,cf23e7a4,d09a6537,22c20d9c,54f85f55,e87650ee,4d9ac5d9,c6566612,1b6e4679,7e52953a,d7c3aedc,2fecc22f,d5b76591) +,S(cb1db853,b615cb5a,b92d0340,7ad7891f,2e7b1d4d,120ba3fd,a1ea3565,ee1d1436,8362a39d,9d425eae,2451d601,27ac2824,3819da08,856d0db2,18f339d6,fcf20046) +,S(5cbc6a63,59d9d6a5,2ceb093f,ca5cae,f32892f7,c9d04091,8245d9ae,ebd594cc,c4c18f88,7436575f,39b9e7c3,27c4efdc,6a3490b1,23c50743,ef03b1bc,34566bd) +,S(37a3cb08,3a9b7561,78ff2128,e7a5b9a1,19577af6,61974869,cf555dac,ee2d11d8,1a8a6297,4d0b6c5a,12155e9b,cf895c95,f6fd2b1a,2776c32,8d6b56f8,32f114ca) +,S(8e0611d7,ae0914d0,5d39e06b,9b359400,f21c3beb,73ede92d,bcaa6d96,8a995b95,ddd4f522,d1c6a964,9629727f,52740664,43e80ac9,7d9c68e1,225e60c5,38129bd7) +,S(9ec34a91,8a4648f0,1c1d726b,51b1874f,36410180,8bee25ac,c159c251,fc115510,bc5ee2aa,b5e43b01,b34ab989,5f4cd71d,1d3e6288,915daa2,e84ed531,4b388b8b) +,S(dc19ec7d,c901e215,f6d0603e,bb5494ca,aa9b5409,67a5a339,8915c4cd,84000654,b55b9596,a18e53c4,b82c669b,92defe5f,bb5e58b0,3cd227b6,3b439b4,ef13bf13) +,S(51bc3804,bda51e9,d0c45087,13599f12,b9a8599d,6e8ce949,5a3f595c,7d38dc8f,ef0d6522,fe3a3c4e,64ee1092,b9ae8f6,e7847bf,94044693,a3ac7cf0,f4aaa37) +,S(13463b32,dff393d3,dfddbe3f,bd6ade13,190e0bb5,83e3f126,344b5e01,3105e234,ea3df1a8,b8270f70,24910f40,a519cef4,9944fcf4,d82a4300,63b2026f,8f019ff4) +,S(c49b3261,2e286adb,606686d9,67dbf4b9,57819dac,9bb75f44,8f1416ec,f900fa5f,ffe45b6d,8c19de7e,c08256e2,96667d89,f290f5d2,25a9e380,c106972d,79551b1f) +,S(10fe7aff,36a8f4ef,79e2d8ac,619ca92e,2300878b,cf21a271,70f89e9b,6294dd28,f67da70f,623fe6fd,2c7113eb,fe6458fe,d0d5471,ab639050,685a0fd9,33afd6a3) +,S(d56037f6,efec78c6,e31e633c,570c5e46,96f96276,b86d0b89,e993f014,53592300,2499b92,4fd99b5e,a56f9649,bd8e53c4,b2f20dab,9fc1de83,dc199022,1f606b37) +,S(a3c1d0c8,939cd4b7,5cce8ce2,f3be0226,589fb32e,55457fde,8e700a77,a60bf003,b9054f66,bf6450cb,782533b9,33190084,d6f5944f,cf4e06f,de72d483,144c941c) +,S(85d0c4ca,e1cfe42f,b5f73f31,42e97e6b,c0855f7e,db19b1a,8668e413,4efcd249,d8372bc,937fa754,b81631aa,33a8ecbc,a25f86d3,d5e0627,d6964ee,5c08e68b) +,S(3092eae2,d41d0ccc,10af9d81,fe8c80f6,9ae27c9b,74b5f696,7a69211c,8d6ef98d,153f0882,f6b720bc,c8ae5924,923e0608,d6163c3b,32d36742,68718d6,e7f35e4e) +,S(4aeb6ac7,fe874a0f,1c24681d,884d5497,3486f293,9b01ebd9,74c34ea3,429be71a,d7077161,c508a7d9,63006566,f652afdd,df87d0b2,8daf3fba,21f206ec,a94a53e4) +,S(729bb0f7,be975284,a68363ef,40003a6e,c770fa4,5d6e6b99,ab0c5042,da563f32,1e0435d5,ea85370a,7293396b,407da43f,c540aa04,24f21de6,a002f555,cccd4480) +,S(96164ac5,1074dce1,3b973689,a39b6795,9bf5756c,4de94829,66bbdd23,9e665fdd,5cf13b8f,56c92710,80c11626,6bce26c2,14a39237,9aa68ed1,b7a05d65,7bbea247) +,S(6d45d79d,9297bb8a,326b889,391b18d7,31af609c,67b31be2,9b4273cc,405e3f80,2d99909a,7b6969fe,148111fa,1b9c9326,97fb465,494a8225,a6c62626,555ed02a) +,S(70091076,b5b81f33,42170f0,4881c941,d2fe9b0e,ff156221,66f0c92b,4f9e8e71,7c676c5a,4fb434d6,58f635a8,20b454f3,4c9795e8,b8860d27,4d0fecbc,ce7824a2) +,S(d04c0a77,c8fcb3a9,a02df253,b8819853,63dd47ca,bc1f8881,88d5e56,87a7db74,302d1b96,c35a2626,22bbc6e2,841b5cf8,efb77374,af428f9e,d69b2b11,6993db09) +,S(3c93d2bb,7ee61cb0,7a25ef65,f3e22eda,6e74d2eb,f3ede111,b4f2a28b,b4f206d5,65ed4db2,b1647b39,7225741e,241310e6,7a47f0ee,4f459ab1,3d29689e,cef70336) +,S(8efd5a54,a4c7567f,bd971cce,7ce3006e,3524dd81,cb7a4ee1,a5c61e12,62961037,6b9688d7,d73db9a7,1410738c,80430ea6,ea329145,718b4177,71e542a6,93b494cf) +,S(e7aa8121,34fa1f75,efd2ff02,273becca,18bf1ea9,47d168e2,cadd6e9a,6c448425,8af9da38,e2471dad,128e004a,d7b03932,2976d84b,7c91f91a,af471546,dfa5acdd) +,S(e4335a32,b3218d51,9c582689,85138591,4b7cd8fd,4e4eabc3,b5f9e0b4,c3212b84,ccfbfb0f,50b5fe75,c849510a,bac5870c,3016573a,53eda160,b14602c2,42ca02c7) +,S(aeff696f,e98cf587,745adbee,3fca1ae2,3f8f5768,56bbad5f,4a26afe,904a17c4,55dfb880,250b9a5b,7eb971a1,fbe0cd6,ad2d375b,88d98e52,6afcafeb,7ac4617) +,S(72fdb2e1,eb120244,4b20bd6d,afd6d49f,46a56f25,63e679c5,2de98cb5,bc999a5d,e29f2,34ad3637,7b4a9cf6,c307b8a3,a779cc22,ae472aac,eb519c10,8137162d) +,S(eda9f183,f89750bc,8c12ce7a,fee54145,42edd9ae,9fefd508,ab588bf1,6c7da0e3,a9328c5,81b0cb02,fc09fcfd,2a57d2c8,fa313ef5,4e205902,9bcf0846,811be308) +,S(744683c1,2a0150be,1d7655e,b5a3fc97,4303387b,e53bcdeb,41dfbabf,ff12f6be,df2e4b05,a459aa27,2d3de8dd,4c211dec,e35eb798,67050285,57dd53e3,5b9950f6) +,S(9f3cabfc,106653e4,65daeb52,e86d99ff,e3ac6df4,5eef90f0,61226cc0,32592ef5,9f20d174,1b78c8ec,d7425d19,fc0a4c9b,1f1cac8d,b97514b5,8585901c,41862306) +,S(9dc15715,9f59c338,d56a7d9d,ce63579e,9e95424d,e6db6927,418b024f,ed95936a,278716bc,3e131fa4,75b9ac00,6e868d88,ce17e6ba,d7ecd202,33fbba0,fb34f0f9) +,S(b6c91d90,b1bf3b46,4b526186,69e1c118,dcf8d6f9,c8ca7473,5a361a28,b53c823e,15132dc7,69e59b7b,fe5e9966,1b82e47b,3ee4c3a3,1c0b8201,517dc567,ff90a4bd) +,S(56604a9,ab972c4a,f18d5f8a,d5cb6d94,2d0c841,a7defd1b,b94b1b25,c31df400,3d2f2a27,adc2eb70,336b4b44,5229e09,a74a113a,f1b21bd9,1e3f2351,15f6a85b) +,S(a5b57de,fcd3016a,917ababf,171c3c31,ed62957b,cd8d233d,c551fd9,6216561d,3731d822,155afc28,8bd7ed39,30c3f6e3,58a46f5d,d9fb3ed2,6d7c7da2,a8dee233) +,S(da179b61,81e27ecd,d545af40,ea5967ab,7c0ea9ad,68a8c0e7,4d4a5aa6,4aafa549,c5c97c42,e74f4991,55191cf3,3118f05e,19633eac,ff5ea8d0,7ec866a0,7fbbef29) +,S(42a0e864,1b594b98,90357e4e,8c32422a,19f368e8,190170bc,6d8abca0,9cf12f1a,bac7a5e5,baf7ddf4,934aaeb9,5078e0a9,c449de0a,cb932b13,a93f474f,52312d85) +,S(74c85e38,944e2003,435bf345,124656a,6a409bdf,fd1c16dd,d1246d45,cadcaaf7,bc18315d,caf237d5,5f3ffc65,41bf9ca9,f39af9f0,cdde6fab,f602e888,dc51bb7a) +,S(8ceda42,698e5995,40091f6d,f50388e2,7c229b0e,76e7def7,f8986b6c,af975e79,a8915f5e,7c524e55,5743c392,2b31c426,71fa938f,84679389,b3738af7,59e92430) +,S(f44e2dd3,ffe43da2,66fbaa1,990d1f19,e3e4e44f,bb565ec8,74af57d5,feeac498,c307b3c1,a90da318,bf928a1a,a8894080,29874639,ece7700d,4f4dddee,d005f6f3) +,S(7e30bb38,c9a603f9,d5fe78f7,453d1c81,30c140b2,1ad7706b,601d6b77,5c703984,49c9de1d,1d057fa6,b135ebdc,f0b5ad9c,f9f51cef,95a4cb7c,ebc11d4a,3bbb6d7) +,S(8e1e53c7,4f7e1595,b4a5f7b4,5b324f0e,435473b0,a61cdd8b,1607c0ef,d11e3c56,584781c3,ae8a8beb,f6cd1bb8,3938fb12,35994977,2d1facc4,240fa43,7bc241d2) +,S(63d0cd75,54bf2c18,bb180269,2d19b4a5,4acd77c,d2eccb7f,360dfd5d,4b9f22bf,ed79b7af,eee5ec82,e498ebeb,467380b6,1369802c,3dd995ae,c844d3d2,91ddd756) +,S(feef5d30,b382dd6d,a0ec0d81,b18ae45a,8dbe12c3,dd695648,cea27c14,7d075be4,20ba81b6,b48ebc6,b185d6bb,2fb7bea5,c6a011a1,24f49550,415eb8f3,cde3aec7) +,S(21bb575f,db07a152,5ff0a7a2,d7d2c189,742df276,9306bc7a,30c2c3df,f2125b94,8ea74299,b7b40a93,3db6afb6,6577ce64,dd10d24a,89bc3907,1f656f5a,71c56953) +,S(dee2dc59,44cad7f2,310afc94,403067fc,5c1c3d2a,dde88ae0,55ba8bec,d6e5cb08,606542e4,5301a6ac,86c5c794,444006d,d77e2bda,11c8af0,6d883689,7a6b6dd7) +,S(4768a2e4,98ca0472,67cef4b4,18e6398c,81289c73,e617a2e8,ca021155,edc576d8,f8c574bf,beea93d7,1a2a331b,cee494f3,75c1bc3b,ea918106,9f1665fd,589dbc3a) +,S(53d75697,160c2b90,aaea7f95,ad24bd66,b5fd7681,f2802bef,d2a71080,74f66b40,4b04d94b,416a8098,144dccab,bcd8742b,13e85b2e,ec8817c7,7b7e5821,2e8b56c0) +,S(832f268d,ad5f3bb2,dafef9dc,f94bacec,b369d4a1,ffbdfdae,bd4fcd9d,77404e99,a6495805,c9b439b3,26e32f78,8b06765e,8d984a37,86ccb4e3,88b36bfc,c9cc582b) +,S(657acf28,15b8cc12,83265bcc,9c826be2,c6d5329b,351fee50,2ed96f4f,bb1a6333,171a0a97,b2809b24,a89b337a,cbeab96e,7d1d850d,dc577a10,ef3c757a,9c2da9fe) +,S(7e3d0a00,a3378c89,741184cf,36e41bb8,758fd131,eccd970,638f60d9,31b8348b,6f2cc777,31f94565,2a3b4c42,29be627e,bb70d5c1,67648d16,df5470f8,90512517) +,S(649a30aa,4fac6630,c7bab764,19f9a34c,6676f17c,2458fb1d,ac48317a,734242cc,fb3f07e2,5737d6b1,a28b074b,880db818,c9623c12,80268b02,dad90da1,c8d246d6) +,S(6b65264f,537fa580,9d21588,fd86b246,4d1818e1,ec7fc43b,94af9211,c835c986,537365ae,4e61460d,c2c1caf0,62ac870c,9536d8b9,436a0ef0,dee6a39e,2bf25611) +,S(dc1a5599,d5cba6b0,2d692eac,304b642b,db32afe2,59e2e8fc,3bdc8f40,72c66c51,bd18d5f8,f99c6070,b7bc06af,568e28b9,2b39dc31,ad49a842,4bff4a55,d11ff42e) +,S(726d39f4,86401794,9e7a5498,8e8fbb53,b8b13ec1,cd5fa3c2,88f0d933,894e193d,f23e9fc5,68c9e0cc,b258dba2,58b3dd65,7aca0dd4,d9cb7bf,274e62d4,f65543aa) +,S(78d76006,857c2f36,889c14ee,90a8f993,79c1e0f3,5344cafd,592c961f,75aa8ee5,76dfacfc,994f3985,70d98c75,4f5e6d00,ae3ed428,49cb75d1,580e81f6,3d7427c5) +,S(d69c3e30,88874c19,71bf077c,89247826,b464d3d5,292196f,88ef0ad6,892375a9,cc7b98de,86017934,c472bc7b,e56f14c8,7494cf5,6f2791a5,d3132c07,26315cf5) +,S(9b4022c,907c4aa6,87631f88,8d47bde4,faeab1c9,23e125f9,280dcf86,7920ae84,c7468b6a,a7b4db67,a9b4a23e,11fff527,19e454ee,65ed88eb,3b89e231,e504c284) +,S(e638a253,84e985a3,5dca200a,5e3786de,52617824,7ed0c9f7,9c9d598b,8bcf8447,69211bb0,be8fcd6f,cdb0ebdd,a8782be8,a47d8852,7bb74b3c,d98c41d5,6aae614c) +,S(e46758ab,e2838a28,42baafad,12376137,7cf72960,d6a93105,3270330a,203134b4,2c7ca1c4,73d0c3a5,8f5ca754,6604ac75,8c460c82,64f5ab4c,832893c3,fcbfc7c) +,S(c8c8083c,3bd1b84,9b9402bb,9472263e,37e7d2bc,53a77b4c,b0ae9b3d,bc70342a,9085d285,6ebd4446,127ab4c2,fe7e5c84,d5c5c114,8ee76a1c,da72933,9ca6578d) +,S(cf21f3d5,75f194a9,3133a382,514ca64a,f998b099,eb307655,46e2959,f71f838f,657df357,aa09b443,c4763432,45d3eae,4fedfd1f,7fa86896,2ffc5174,d61fc4ba) +,S(684aa68,d4aabda9,65adbb29,1056db00,1c41b900,e11770c,c77c687d,ebcd702f,c6f0c4bd,f6f6193b,928d81b2,812c4303,7e6b90eb,598a50b0,742dd21,8d82bf3f) +,S(b9a4ef5c,acf4a82,77b81803,6bcf2672,945ec080,e16e8c3b,19f7b612,c408c884,1cca67ba,9e98e737,b4a55145,7f254d4f,5d793d4e,22b81b35,f4ab48d0,92b9c745) +,S(ff439f87,d4784ca7,490da489,e2757106,e59836ba,f3fe2e4d,f6700c08,cdb2327e,98f21471,84659fa9,a9cdb709,f894236f,18ecdac9,f5834dfb,b91a7bf5,8edb7461) +,S(e1750c62,9c35027a,c1a5f1aa,c9fb4076,badfd925,f5915b11,a267672b,15945ed8,e17610ce,a0b8d837,d1038d7d,9300edfb,5832fa84,c4e630f5,2b01ac64,a79c0e17) +,S(2b7057dc,1c59ed7c,e64f187b,86adbbb7,1d228e5d,eea347c,75c73d2d,a73b3a28,1b136a49,713b433f,f2c79de6,77b5a322,8003e614,2b845470,5ce884ba,329e20a1) +,S(711c07c9,ae61ac68,f1041b58,c0f2ed07,1106c2b1,bc47e104,527d540f,53690434,e9199a45,2f5a3a39,9506473f,be6bb46a,3105aa70,2c517051,7b4c810a,5a194c09) +,S(54dc7650,68c38627,4619d9a1,faadc0d8,c2ad8296,dd0d00a5,f2e53c5e,1a1a0d4b,2e9b7179,3af2f752,c111fd71,c00f4bd0,8fa646a0,428b4813,885d4e4b,ab7e3fd9) +,S(9c5aecba,3f8b3507,db7cc231,c2c1674c,3c3e27be,84757fc,4f1521f9,c3d9323c,413455e1,9e157ddd,17f51c1e,618dd726,d300c023,f0a0d24b,518c93e3,f2954630) +,S(c22c2972,5f67e23,a369342d,9a4e1f6d,dc1bf6f5,88d63086,fb54718c,f5183a,a26ca30b,d97ad611,4ea4ece4,cfdd3928,23c02838,9723d53f,32c3b38,320eb707) +,S(8f87ac94,a29dd2c9,d37aa130,f8b4e67b,da595ca,a22803d1,e2d8cd4,eba4f2a9,551fab10,16227763,6d7ad2c,bb055439,21743078,e02fe0e1,b7dffd6,8749b04) +,S(bc486976,76c0f638,a116bcce,d7ee781b,876ef486,111fd680,4dedb176,8125dbd8,16d7c6d0,19708ccb,510ddcd8,698c2fdd,bc6978b8,7b0639d7,a1c8ec6e,ee3ea383) +,S(5a6ec844,201d9b39,92a46fe5,ad4f05db,6e8cf251,24ecae84,3a28da7d,46e75ae8,9e1538ef,f27344ae,8f9c1049,c12b49d0,2d5341fe,33652a8a,9f2eb512,c74ef224) +,S(dd6b2c56,b13f0ab5,4e0a75ec,526219e1,4d43ad78,7deae379,1dfb387c,541f4d6f,7379c5ff,1b793b97,c8acba99,97a3c079,f1c147a0,f63a2ec1,a0a771fb,fc3d432b) +,S(74e27534,4d7d8cab,e4995d08,6d61d27e,942e2514,3c6e3040,8402a5ff,12a63ebb,7b5914d7,fefb7b3d,2fdeb49,359878b8,355eecef,65ac589b,dd31ccb4,c270d854) +,S(bea186e4,b5e3663a,fb00230e,d8ac1660,67b022b9,b69b6e75,aaecb88d,d750d34d,35807d83,5b75e3ae,670bf35c,d415d37,6fbc86e7,4f99afbd,c60a0b46,9153a0d7) +,S(17ef6838,a07f65f7,cc094d4f,77743c6b,fde12ae3,b81625c,23826228,650f30f0,9d696a8e,a5356fa2,10626ce2,cf312fb7,198b0937,493c9dde,4711dba1,333eba5c) +,S(b3e1bfcb,38c89fac,af3baf39,80b21e47,d6465473,c9d6a29c,8a08cb18,141bcb7,aa33ab83,2a9d4eaf,2a50f9f8,ba55d0b,c5e3b120,69a8330c,23120928,5f6b90) +,S(689d499d,c754f099,83372631,2f307f0d,807f4f6,d67df40a,318aadd5,5776202a,dd4f9012,8a19dfbd,8f5f96ed,df2c7d79,d451f84f,fa63b1a5,9845f84b,759377eb) +,S(4bfb2e58,9df27505,91a73a4c,6ce88397,a2f68f6e,8f866e1f,d3af9df1,f3c96bb4,a9d94c07,29948553,6433f0ec,b4618d1d,af309c6b,73fa4749,aa949e6f,bdc24b7e) +,S(97a3004f,26461f5f,b6cbbca3,13eecbe7,5026d958,a1804c34,6e661722,c67f91d,8b8e9bfd,b9b704d5,13bb5a50,a725bae2,c7ceb6a1,ffcf8c49,8e87c6ff,e47844f9) +,S(a07a76e2,48f87384,48e607ee,7f30aed1,db657b9f,b159ac9a,3d38e8ad,61050c28,7d7749b7,aa6dcd68,931c3c0d,87eb73d9,6bd5f43a,b633e7b8,f77406a9,23fdd47f) +,S(9bcff8ce,3a280998,fe077cb7,a6e4854c,4c834e21,af118937,9a133986,320b8e25,da3214eb,5cfea248,f1f8a1c1,e8b0dfcd,4171b2fa,5e133854,84a6c99b,215c9ca1) +,S(8f1d2dd,bab8242e,fad20574,c0f28976,d2e98df7,5e144d27,e558b9c9,8d75a036,8bd117cb,294db5d6,a39097e9,8976c701,1042af41,680637d1,c8a1d56d,30800bab) +,S(73910449,2a44d0fa,d27b97b8,df75ca46,caefe44c,741848f5,36b78986,8d966991,d31b7807,e1db48a3,380608e6,5f865cf4,445c47f6,c6094819,da2450e4,6b78168b) +,S(e024cfa9,4fdae1e1,2895590f,222b167d,8a41a87b,b1a6b720,61ccac0c,4caf9dc3,d62f1129,cd84f36f,bd1b9439,6f5ce037,fbdafe41,fbebd066,110549fd,50b0ba05) +,S(a378ab39,e3dce826,6805bcec,b8123eb3,ffada53d,883c752e,e46ce4f8,5bf093fc,db9d124e,4c0a8d1f,14cfc406,4498a7a6,513261f3,300ebe0,99a41f0e,701c7dd3) +,S(bea5d211,b808e4bc,5aaa1a96,a9b8842b,5204b60e,24d5e518,4b4e92aa,12d8968f,caf8b92f,87c4b8fc,4692efb,889ccd64,610fd604,b9669dca,e033ae9a,453bbca9) +,S(7ec06291,40b6bfd4,cc4bd45a,8a953fc2,653d73c5,d366b5e8,b732dd8d,5d30428,e96c9515,da8dfae3,a2f4e01f,f02ebad9,8499a318,8905c0f0,fcbcbb58,87360a08) +,S(9f9698a7,6ccc8bc5,31dcd9a5,b21f3f8c,9d143194,8902312c,b5ab89cf,554c3b26,e08acb08,2ab0eb8f,fc31f7a3,1ca8dfbc,d4b1863e,29d155f,4abb8d54,6c59a221) +,S(ad955b37,a45f2bfa,1779e8c8,e6786af0,dc49dc9d,d692281c,da10b25d,7517214f,b2048fe,ee71c152,8c8f5dbb,cedde340,284af2c7,71ee86e1,8d565285,5de918ef) +,S(e7e56815,9412123b,7737b006,f48b3f32,513023a0,70c595af,1749c564,8222e21d,3ff11313,c2992218,cb3a1c01,e333f2fc,ffdd05a0,c381f8e2,24de6add,85aad0b0) +,S(4afab50b,55c2a433,488adadc,ca5d11,2e225f81,9ab817bb,116109ce,71dd3439,d232e25a,e5a8f6d5,68344997,442bdc54,de9cc597,cc474555,5f64cbfb,6252808d) +,S(2f739ca4,6559727c,cc2fdfa7,c66da19,b7d2660f,cc63b74,155057be,d55313bb,c39350a6,10a844f,80730a2f,27bbee8b,a06d7ae4,a279f490,f975111f,eada018b) +,S(f3596671,79f9343b,bc3238e7,bab4686b,5b7aaadc,95848f20,52adfc33,d15a990e,8b5759c8,e0bfb8ff,e298e824,ef18c042,65d7f886,1af8252f,8c9d9d92,c1822849) +,S(b3feced5,8d79e1c4,d0a210dc,de416353,404f533f,5a1295bd,4d888d59,b43725c3,b07089f0,871f7c3e,440ea905,cebf66de,52c68c04,a6aae237,e23c3272,26d99826) +,S(85c74622,bb28186b,5f1bffc9,74d51ea1,8bd7e6f9,1a02285d,6d8818df,b87d2f9c,8eb95100,63263c67,976fda8a,18910459,df0755b9,307e4145,cfdd18,15b799ff) +,S(3823d01,5b240e83,44c936a,c9a5f7f0,fbbe3059,1c20f39c,ca51be63,98ea7a7d,6e6539ac,8f404753,dda08dbe,f7ad4e48,69a67a93,f0efd0b7,b53c14be,130435fb) +,S(b73ae7aa,e97af1d1,b6ae34b5,f6188c62,33ac811e,1ce5818a,a9f20703,7deaa539,cf495bd7,2df163b1,f6908b7,23042bf1,137a325f,bb8ebd78,c0d12086,e7b76005) +,S(f6724463,faac9880,41dc4918,5e27b97e,889e74a1,81f35b58,2601328b,143688a2,a290e04a,f10a477c,7c0269ff,42285277,f1faced9,eff88272,45f2d069,58897554) +,S(9eff8038,1d546c1e,e1b5d562,947f3a98,427e17f4,84d0007f,eebd71c8,261ff959,bca422aa,d4748c66,6aa99f76,eb8e75b8,55f89b0,917ec29f,401caf83,cec111c9) +,S(93384df7,33d0fece,931587d3,410f2520,6bbbd992,5e6fce75,5432252d,8bc1bcc5,9e3beba1,b9a92647,c630cb4a,69b9bbf,80e301be,fb8eeafb,fa0021c3,ae27c38c) +,S(ca85653f,975882c3,71902d14,6f50b3ec,1dfe1fa4,b6e6d5a9,e5068685,632074bf,a64fdea1,66808f60,736f7d84,850f841f,588879e9,5d1adcf8,ccbdc4bf,4f743bba) +,S(b80a52f6,951aa063,1094a2e2,866d3a29,b95cf239,48753ea5,cf5c6f6e,8e082f90,61c95d57,d6fc3ca7,5f92771,61ca211,1f20a67,9a85f4f,2b8b0fbd,494d55dd) +,S(3d5d3037,3a97dd67,fe45b273,2ce21e19,b29587dd,301f3dd9,b411432,e642a3c8,5c8e3a19,896ef1a5,5cf1ad28,41e47dd6,1f207f22,3388c6aa,23d011d8,fd95929a) +,S(b274f8ca,29a87fe2,8a3a1269,ddc35b5b,44f9e4d9,81af118a,187a7c36,acb155c8,410d9c55,bc34c21a,6368155b,c282e449,c5317dd1,c4e5758e,27493fa0,4f028ea8) +,S(f1557792,8cac518,66f59814,a70c14f7,beeaefa5,33d3b535,df19d31b,ce1cacf8,113dbebd,9fef9cfb,93b5606a,e4b48aca,5b7e9c00,a59832e9,6865282b,80b70ecb) +,S(fbe3f262,18fcb657,7fe56753,42765926,59ff099e,f36252f4,cb5af101,622c40e6,4c872d52,f1202df3,e905a0d,3f9c89f,b347723c,99b1b273,8f3dbb83,df0fa2ff) +,S(ef7d13fa,25ef46c5,3663eddb,a677f6e3,b24c7e7c,6895e731,2c6993da,3d9384a2,cda2cc35,114e06d2,1f6f896,666c16db,78fef74d,2ee46fb6,a4a34e09,8546935f) +,S(8e34b93e,afb7f027,cdf8696f,a6407213,91860119,cae17b66,d4f16175,fd7118cc,3198f5fa,27ee190a,e56813e,910d917e,3bb8c850,20b0376e,e55e88ea,eb56397b) +,S(a8291a3b,8e544240,a0f0dcaf,6369b2cd,98ab80bb,4dcbc2fe,e023cea,1fa52399,f8305f7a,b1993569,82b8f2a0,1fa0e808,46a506ef,5cf0ccf4,fcba9211,284e15a8) +,S(bd36854f,90dcd6ac,978c2545,7800489,35c4cca,79a0f9b6,bf461da6,5522c88e,631a3d75,7c05e2cf,4a445b22,73cf663a,332610a,8461dff3,846503fa,12e65ae2) +,S(fad86e9a,ae78aaf2,e55e93f4,b8ee049c,73b86524,e942ab93,f05f9dfe,8b783116,657988b7,20822c63,dadaef15,a5cb3d49,be52946d,53b62ed7,1814ef3,b5aa4b7c) +,S(e1235938,db5e1f30,fa0b4d4e,a9e1925c,6308917c,23efde51,47fb818d,a39bcb2,7641244a,7384acbc,3133fd6e,9ed61af4,40e3b951,751f9d0c,384328f8,b87bb2bb) +,S(40ec62d9,7c9bf05a,cd4bd50c,137cb143,8e3331ac,554098a,57b6a92,afb137da,8b1468fa,f334dcfd,5a43d405,aacd3f31,7e868af2,73498367,4d0e5a06,67186a8e) +,S(f6f5c9e1,c7d94d25,9abe1a8d,745dabfe,59e911cb,c917fefc,e2da2a63,cacb26a0,7f2454a8,550b385e,f49c26fe,bac89a9f,33bd6c9c,2eb05c98,4303a16,6b21ca51) +,S(be4dd8db,c703a834,9e24773a,acefd0d5,70dd2ec,ef07bc70,ea8156bf,d5b516ab,46a7dc2,5d56052e,dc64a0d1,b414da49,dbb218d8,5abe14e5,c753eaa3,84b958ee) +,S(273f227d,448ee218,1e43f2a9,89d5942,54eae85e,54fe9f76,fb67ce81,169e1be1,67cf461a,a6c7ac60,1ccdd925,b4b38e84,1998cbec,cabf9441,29575438,a855f35f) +,S(94ca507b,96c063b5,bfa9d74a,c92e656e,db186570,9a017ce0,e5270bfc,8a8c4a31,98daf409,49c48c6b,8c674361,17aeb669,36c76169,8d39eda8,9922490b,4fa6a25d) +,S(91d6f747,c1c7e012,440cf7c1,34ba64f8,9ef67b54,3a57196b,d2bd6ae8,f5ef4356,e2117eb0,4d4d29cb,5b13f628,f69e5eaf,2befc095,2fa361fd,f757430a,168c19d6) +,S(8e2c4d62,c17835b0,97ba07b,37947515,e710e825,15bc614,75a66ed2,ac4cfb84,7b7f7e56,22bbca12,2863c230,5271ad25,b5e4195f,cb96e5a5,ca2be6d5,273d6532) +,S(55738482,d32c4248,1bb0d1a0,666adab3,8bd2441b,9436b690,77925e15,2d8c948f,93a6705b,ba5e5b36,e73fe83e,e0ea81b,3de393c9,1c209e89,af90c539,9af5ea2d) +,S(7faa0f45,45fa7d68,918396f6,19beb941,43d93f86,c5a26539,5016d386,b3e85086,cde251a8,3de1f2c7,11b884b5,33226baf,cac36791,1ff30e19,25f499ef,27da9c06) +,S(61a766a7,7bf6f8f3,a07ed7c6,6648606c,69134c6f,4ab4931,9033f9a5,e8b7d191,7dfa24d7,6bba181d,7bd77606,c73b1635,46f41751,c05c34dc,ec54773b,4abea4a) +,S(64317c72,4f1207dd,a6009736,6fd2d189,8b702e71,8cf84fcc,7c50427d,7eee171,d1d45f23,b1c5fda9,ee05652,dd30f898,c75923d8,293d6eb4,18a0e892,ae400895) +,S(4c328f82,5923e7c8,9cdba421,92ad7a37,5a328323,71242c4a,e108c771,fc47356,322421bd,92c5142c,efe89e59,4689a7a2,e8e5507e,be8b505f,9dc9ac86,9d90ae6) +,S(360aa32,797804f1,649c44aa,b38fa9a3,5d011301,708ac7cd,a4135c13,d86a6758,ce4b0fb6,6957f5a9,7e4ef923,ebfbd850,4f6d4098,5333db66,1152f1c,ac6eef59) +,S(5b110b6b,d9ec8ab6,635f5016,bc597f31,ec22f7ce,cfeedd2a,1e6f883f,64d2379e,9472fb70,87ab6f91,2b10c6ff,995af03c,5086c034,f0f69860,ead562a6,e409c8b2) +,S(be27b39b,5a657cf2,9ebb1b16,45f5e1d6,bb6e32bf,e3a52b08,a916e091,9affa38c,93fbf27b,5d03ae3f,471ad91b,69e74fd5,a8f2f925,2bd16473,62c4feac,d26d1dbe) +,S(8ec65d75,c599fe6a,bddf3cf4,6ddcb4d6,1e9b5324,f5e7b7be,5407cb5e,28a9df4f,3d52541d,49ce4b07,7b543747,3a219db8,29680777,3cdcbf80,e4b47786,14ca082) +,S(6edaa1b9,ea8c2c45,6c6a34c6,13ad60ed,aed18a04,32e96030,ac7305e3,2dbbf94c,c64c8279,40cbabbf,fcdd4db5,1719c53e,f8cdb650,67af48cf,fd731618,bd304b7f) +,S(3fb5f6f6,60847e2d,e04341e0,26c4102,68d5a1fe,880602de,c07be98c,22640a29,ddd43c38,95e663fa,5aee3227,4a16f532,df3a180f,e0813ba,3ba113d6,f6fbd9cb) +,S(2d740009,d7addda8,a802b263,35d41284,b3b9a119,248a3b,29b4a532,654e84c2,cbe1e2d8,1bffb79a,6f9292f,43ccbbad,e763a56d,6d68cde3,d946f310,dba8f28b) +,S(15bf4abc,1d74793f,6ebf2fe4,aa74e34d,b359ad76,3d5624d8,19c24386,33517436,5efdcb90,259b5dca,39054a98,b6702fb0,f2fd4b61,235ed4c6,cd1f3dc,dab15f12) +,S(feabbebf,3c6ee0ab,9b584162,476c8e9b,f7523c30,7874d7cc,c4a6b88c,b118d423,c51d328d,276502fa,f79168f7,3787d3ac,b4e7bb7e,1f65b421,64ad6e93,2d405460) +,S(e3664247,929c3455,e98de868,60010f47,4258c686,4d4a7c0e,4bec28d1,b9af3188,7cb4bd55,ba579fd4,a3066f83,710a3606,2fab9f87,34311609,902407a5,88454bc7) +,S(d570f391,365aa2ee,29b6db92,2a96e4db,f1820a6b,94fbb8b4,aec45ae2,f97a21af,c0841986,2b0adbae,1cb192e7,bf80dba1,830520e2,35e1e42,569a31cd,fc0c1543) +,S(9cfce5e3,5119ca91,38629b08,c75b77f0,db3cb593,b2bf8dbc,b7d6fe3c,d1eba55c,33891655,226885b4,cd74d8ce,f29e978f,60a71bea,be99a2c1,d2071f53,239e4f12) +,S(186ecba5,f9998439,f6a3dca1,a179608d,a15adf9f,f4d2f386,4268ec3e,e62e4407,ec7eaeb9,bec50709,e8dd761f,6253248b,2fd064a9,638953bf,510a38ae,c7c6d24) +,S(ad52f2f6,fe0b72ed,2a0fe483,3745aebf,acfae58b,b40a0291,21767058,3e0f6b83,b0cae754,85e3038e,c6dc8d,b4e95a54,63e3e6f2,1b99d991,2f521663,3eea0c71) +,S(aa06c0be,7d72350e,6b094df,f4dec4c1,993588f8,5bd82a1c,158f92cd,eaa7804,ed628163,29369fde,f0fac2f1,a533fcb2,a704637d,6dfaa1f4,a3b57f74,4efbeed0) +,S(5f7a102c,4bdf0a06,76e1bd4a,4df17a3f,124bfee6,312b3972,c49fc4a7,14b3e867,85f153db,ab40a9e6,747aef3b,cd30f59b,fc9776c3,93293222,8f534d59,9efb30e3) +,S(31a4309a,64c225e,69567574,e05bb994,3fe01679,6f09a0d9,358b1237,96cd3fe0,9b9862a2,916ad0f4,1e588567,5a1e357d,19ec82c5,b31f967d,af058e1f,da7cab16) +,S(8906bd2a,505e8401,cc89e32,b9362c84,3443b4f,bafb7c03,75bc883b,11c3e59c,ca78e1d0,1c6fca33,b39d690f,5b85c764,ee15dbfc,48fa78dc,5f7d7cc4,5323d187) +,S(41cc93ec,a27c4fc4,19fc1c8e,4568744e,dab8917d,d8936cd3,2723737e,e36b4f9d,c11d8299,bdb95efb,842ba828,a6d89120,1fc6a28a,9f208430,c1e2f748,bce6b7ae) +,S(6e1b0bc6,199c3b84,220020e1,1a698e74,2fa97a58,c498254c,d3af1e8b,23ef34ed,25e0ed2,3f04706,6b4134fa,b6252276,b2205bd0,7a8ba64c,636e0b0e,1d6d0217) +,S(b55741a5,7b9c7270,dd1e5115,995ecc55,8729832d,9f4e373a,6824d9a2,83490eb5,9adffc91,52eca815,465e533e,c82bab6,ec6b37a0,dbb3b6f8,c3bce25f,6e3d944b) +,S(fde1167e,67f0e084,251d50fb,bafb538c,9c375e4c,fd6441bc,59a46104,46ff090f,662451a2,444d39f9,58593a02,e9a94ec1,4a1b8d87,9dc80c5a,73bb68fb,67af754) +,S(bbc374da,188df5c6,5a633621,804d22e6,f7474faa,47a8af94,a1cb78fa,aee68040,c2c74abd,17acf272,6c03bbfe,7dbe06ce,eb1f4e0a,b0001aef,4d8f342c,aef50186) +,S(bde6680d,414ce86,548504d5,55c83b18,c9f94e45,f55b6683,166cc81f,583e0eb,2b1ce8a2,6b5bbd8e,a087eaa6,49f49a48,2891abda,87c2037b,a73409a2,69b5e2e8) +,S(8f9ba006,faf50323,b9637f00,9aa29cb,8e402219,75d329ce,15796428,6c84e5d3,1bb33199,e5c30e98,5f5eaa1d,65879a3c,703b7a50,cb04c7ec,a6c7512c,94180e16) +,S(19f03bc4,3b61d7a8,62bb81e0,f4b84c02,7359a170,de0108f0,e9b9e9d3,95b63481,8239d21c,f31ae885,ae10c62b,8be0ee1a,95db0368,cf0488c9,4a110a76,7d22dd73) +,S(667c2647,2261828f,2653a0eb,e70de204,29231fd8,132961dd,ba3e4853,8e332941,5758f0ef,4362f75b,c4356b3f,cd8cb2fc,3c77cb25,b7d65c8f,ef7b4096,e0d879e5) +,S(86558922,618551b5,c4c66c50,9b81a622,ca376318,7c558ca1,8a00a00d,cf100ca8,32cd16ef,955deafe,e3fedb4e,55fd2071,8e35c1e3,736dba12,9f3c3287,4413739b) +,S(255bfbc3,d0b0d6e,385905b4,af6ee2a0,18109db9,73788509,2d5fb275,f1b47b45,b1b1078c,afe453b9,a35fbc30,c5f605b8,4a1f61a3,1104b406,ab5014db,57e2b167) +,S(acdae8d2,eeab48c1,9507f575,6ba60b0c,e9d5b6be,e2ac15ba,d31e8932,fe89e14e,b077540,ab137999,7e7dfb3f,5e3fff46,10c2a369,2306ac0a,418d5026,caee0466) +,S(162b0c77,da3bc13,a62753f2,b7b19c9f,3fe864ca,66fa2dc4,226c5cd8,ca8d7112,377956e8,59c2f465,2af5159,bdfc86c,df0bd742,ec7f9eca,6e675b47,d6eda222) +,S(9453c9ef,afb6a23e,40ebf013,eb1af363,c28a6e14,d235c7eb,58d3d142,9d1b498b,65e3b737,ede3c00b,5f322b38,9b09a68c,2ff44f30,c7737932,4e9c94c9,bdd78961) +,S(8409ed29,38a5bec8,669e24db,88c1b6fb,b397ba64,d8a1826a,f011e2e8,32e85506,573a0053,1be979e,1ae3f2bc,3d28ce2b,7a3ec55a,bd00242e,73523a2,582500dd) +,S(3b55d457,b1878898,9c486cf5,3d1ef107,4161330c,64fc2250,81096148,f5ea2c45,24780fa0,3e83919b,9e3491a3,7e0b76d0,f5d32f2f,a4c3aaf0,d2e7c955,43476fc6) +,S(d3fa2c21,f4704812,a5b582f,9096fc87,422af325,5c5d006c,63e1e9ff,d2d9ebb6,a6aea607,9ed334eb,9355fbff,27650096,ab19a007,191d57b9,4a8fc12b,a59bbab9) +,S(a938a4a9,9dc45307,29f3bac7,4fcd7241,1e56cff6,f53fb048,c727087a,9a54b374,3949a589,388ef8cf,aee8fe82,fde39e01,41ad91c5,2beaea97,e7494659,1a27bebd) +,S(792220fa,aaf49862,479a6de2,35be75f7,e811d12,7420571f,e46213a3,e77aa93b,5f274791,31fc7585,8b82b021,52057cc4,f1686543,3eb6e22a,de56bea5,8823131e) +,S(b1bcdf1d,57699459,1bc11d27,cb15d84e,75eb3d5b,2f9b4bd6,1c848c14,e9b7f2d1,a2115735,8c35ac77,e116a0c7,77917e62,e1d09897,316e2389,41d8e170,90adeb50) +,S(735b746f,6f0d453a,c45cf288,6941cf13,c63899e1,a41ff3b4,cc1a4c74,a9b2ab33,e4c2b67a,c6bd7917,2478b52a,994dccd4,475cb24a,ed1eb77d,a39fbcda,9c02771f) +,S(1640d0cd,ba4b4fc2,f3670b35,2485027e,2724ea4f,df918b72,3807870a,39fbcb2e,a0a71f4b,ba481eab,999dfc3c,15275eb6,b06d129,48000828,be4754b2,749bae30) +,S(bff651f6,df72e476,a097231e,b496618f,6e7d621d,dfd45356,8b08c718,e138caa7,10dbc188,2d0a17fa,d769f855,bffe1a81,14183445,5d9ae144,e6eddb52,8e67f99d) +,S(1a3fa743,cf429f3b,49e122c4,5c6d6e8d,18c633b3,f9903c9a,207f0405,c2716b69,b1b2c87e,65faf1fd,debc377a,bd9648cc,24abeb81,75efa4cb,5f0a0b06,aa2f1e28) +,S(bc2a9ae8,e2940908,ef5420f0,9ef4c2b2,ae988e5c,c0c0efbf,62f8ea05,b305ff21,ede884fe,6b48627c,84c96869,5944be60,df3ed5c6,66f16b56,188a9e1d,6bb14e80) +,S(8cee080c,e9204a62,502ae88a,15965abc,b2a8f18c,80f6c461,24b073f7,63990ec,3adc08be,7bea0bc2,b2c5ca91,963f4c40,bdfdaaea,318fe3c7,866229e7,e53c8fb5) +,S(2fc784eb,f79f916f,7f57dfc5,8fc62e8d,bcdc7dc6,70d6a444,c13f397d,ed528e2c,56c58a3c,be510393,90a88028,12d03658,20141c,b1b24241,241dba91,74d6eb37) +,S(fcd83e1c,ec7a6db9,1aef0894,cfb2e1e0,d2b48fe4,88bcd28d,c14e7824,6e62aa35,a86c9321,e2dd113b,cb7ec78a,d9d4db68,b5ddbc01,70aa0f67,5586b08d,6694a853) +,S(4e4fc5b9,65584dc3,40cec4ed,87ab0610,d674e1c0,9d76d28f,e28888df,7f9be562,d2344fc3,de7e5372,ebd87d0c,ea5431d3,2364249c,f6c350b6,d7aa2353,26e9ac7c) +,S(8df04fe6,e93afc18,b0508831,320caa9d,b21fb740,46bcc364,aa80564f,6f89270e,d7b37dd,2463e50c,583dde08,ca253215,4d52bd8e,a4252c55,6749641b,71ee7214) +,S(f662c961,3102fc4f,afd27352,cc697de0,1f4a1406,f99a0656,6597b96e,cbc99305,43783b26,759a2eb7,8ba4a3cd,e865d1f6,474b1ae,26eeaa2a,15220353,f6bce384) +,S(2052f92,b66998ca,f172ce,15cde941,484c5ee3,d3ae329c,87f339df,ae944439,3e9ef8c,9f4257d,c563509,6df8efa8,ffd2312f,60684baf,bb9e5d,9cbd04ff) +,S(730aa6c8,9c8abb08,855bc551,1938bc46,bad8f226,4b162386,9f2e1ef7,c2d6702c,7523fb97,799e2bb2,f13ba1d,59510bec,ee682f98,f865aefa,cf3c6578,bf46ff81) +,S(c5773c0,7d65fcb9,7cefd396,b07dfa58,1ab237a6,be3c1739,e6db944b,c7991c59,6afea6af,44ea94f3,ee67d071,4b6654a2,b1b335cb,e914d305,1a60b05d,44cb81dc) +,S(3ef9a63a,5bdce751,48d7c585,5e3e9aec,90d34ca5,1a3b4829,979d67be,c38c83f9,145e65ae,635acb42,e7949060,fe44f350,3535d417,f3ce9e42,4c3b3d0f,b02f2c73) +,S(a1632263,42b900e5,887b1800,196c5be5,11065746,52cb88c1,4011aae4,6d14bdc8,beda5e2c,40b55506,31aae0d3,fd9997c5,3f37169a,2d810b5b,402210c7,7c372cdc) +,S(8c1f5646,65449ca1,f16015a,a876bdb4,4d965993,7ca6936d,5bbb80cd,c2da6d65,7cbacf98,f6f7363,8940358b,60beec4d,1cd1a1d,900f84bb,9db5f784,d4565034) +,S(693ab562,230c1ddd,3493c64c,6f7e2bb3,a74cc535,2b7efc30,630904,e700d5a6,db890cb6,d09d5be7,ddaeec01,299880a1,2e68acdb,dd950118,3c8f5f07,739cf4e7) +,S(d761653f,f7979336,f833ca51,b91b9e90,b2bc04f,7b7407eb,be3c8462,95d59df2,f81a5d74,446e9762,2391368a,ed154b2f,4faefa60,af93d727,8357fd6d,98537c5f) +,S(41de1c8c,a1315711,3435ce37,c2d2efef,24a67cae,59347d23,44bebf0f,a2cecc64,77629b7f,46cf1d57,a03898fb,cc9f4e37,937daac8,12c4df74,846d8c89,60095559) +,S(21f89207,4e3a00c9,39862265,c1762dd3,2662d182,397c1127,4ef144b7,f598b650,e6e30e11,566dce23,b7a6a06a,11e12bcc,978a6b7a,fa9297b,8c978f56,40f8b4f1) +,S(6163f61c,628b4800,dc49f30d,dff19310,369012a8,f31d4a25,27c790b4,c51f068,4e87a17a,12055cd0,4c4bc19,e052a219,7dc5847f,ec984f9c,aebb8f81,7a7065ec) +,S(a68ebde6,43ab3c15,72f5ab0f,85d683f2,6e6eaada,550e2425,f85596db,8e2dd200,487604ed,38a6387a,27e3cf1e,9d4865fe,7fc67e7c,ee26ab11,1f03e0a3,316de778) +,S(9b9fd342,4e065ff5,b82e0c4e,e5efa0b1,d0991087,684c46d5,7885adcf,b352d06c,b11a7a46,570eb251,6562ae87,90eeb403,823380c4,aae99329,de713677,5b5b5e0d) +,S(d80c347e,98db32bd,57ba5728,20c7322b,b295cc3a,ae326fd9,49e7557d,27151fc2,6d734eee,40229d19,465a0e2b,a011af39,62ff5c08,f83a2e17,e5c2783c,a430cb42) +,S(c8aba983,5f814895,e5d05139,7b23988c,7fefedd9,aed9dd20,a9bb0025,49e63ef9,3811b18d,8310a67,532be770,45461d82,e40c0ff5,6af355a7,55ed4708,f1ab0c7b) +,S(1bad15b0,a186d418,bb84a87d,d2fb9255,9aa64547,cf47a93f,73d23953,86b0e301,e432c50f,662da1ae,f7ee8f73,f5d7ac4b,4a4da6ee,5a943d17,7557e64b,5eeab1d2) +,S(720fcf05,dcbb0609,e5b45efa,e055811a,66d84384,16f7091d,7ea66186,922779e1,9045fb14,37d2086e,ae7d6a64,49effaae,17e3a559,571ab010,57f20fb5,80535906) +,S(96a540e7,8fb6647,63d3b129,8a1100b0,88a2c3e6,6da3ebe1,4b6c39cb,f01c4b2c,4debf0e5,c95b9a1,7bec7f14,12018197,88a1c325,12f60973,9d5b4909,f087b5c2) +,S(2f068148,d385bcd9,6fd6b60,b7e331b5,88419085,3942ed16,18b464c5,9c3ca99,596f3fb9,2fa7377f,a9ecc8e5,be8421cc,77339f62,c6f1572d,7a28266e,eb66ae52) +,S(466e9733,ef167fb7,233363de,16d9d510,74d8e5b6,35abaf38,20a037d4,f6b3e45c,73548e1b,d4d5b78b,821fb1d9,94919bac,a9d4e12e,13a2e8f2,d4c5df51,2553410e) +,S(f8a841c,a8c7fb3c,9a334f12,cfed9ddd,d1dbd4ac,764f3c6e,87a42818,a4a8e51d,57ebf669,72e9c4fc,7c435cc6,a85d381,6a969d02,ea85edc5,63c57187,34f0f926) +,S(d8c7d6e9,6719e74b,2eb7ae7,59d82ad2,6aa003ee,58e3d9df,ea97c7ae,6d6b887f,f1bec88e,5e8df038,b069692b,9e44245d,a11feed4,c89ff45f,17bbb6b7,1b0e43ca) +,S(afd5e13c,cabf51c,19c39c4c,815618a6,14a4f461,5fbaab69,624d366d,540ab638,9ced3d42,5c361706,16cdba99,653c00aa,e5212c5e,939c0bf0,3e5a1cb0,a05cba0a) +,S(fb491696,a4a1b9a1,572b462,f4628f66,b8368f3,3ce957d0,6ec29a0,92ce994e,b4fa2340,68741570,a56182bf,4f1c71eb,2c80d6a0,cffa42bf,a3e9d9da,59507de8) +,S(96e301b1,efd54091,80e3aa96,6652a253,78ce4bd3,cf587238,f0367a58,ec45b0a2,1bcdfe49,5ed90efe,7eb853f6,6fdc5b7,365ca2ae,e1d9b787,afd41b9f,c00f308c) +,S(9cde8d26,40d197a0,9ac00167,9b93092a,6eb8b13a,4d9fe2e5,6365a5f5,fc38d809,c86345d9,cf95fe50,40b2b2e6,2bf4267,72cdf10c,988a4f27,836d960d,c98501ef) +,S(d33ba473,10c37342,43e2219c,f3cf4881,2e843be3,c7492d01,80239bdd,20a829f2,ac774707,a5b0888e,b2ffa131,b71035d3,6af5be1d,3a3605b5,751b92c9,9e58a45a) +,S(6b364a32,1b5aecb3,749093e0,1b5229d6,5576e65e,1bea096c,29065a87,e26cf2aa,668ba97c,a01f659b,3687cef8,ac87dcd4,7a8a4f85,4a434f49,9592151c,b8f96152) +,S(d0009cbf,1d0d0673,5f66c16f,5cd4747b,d33b3347,fd7f096b,a026355e,917b5015,41c10a72,3e82bec0,b92e560d,3bf1e0d8,15a22e50,3afb4bf0,e5caf771,569a7dee) +,S(e618f641,a5b443d0,704102b5,40efb697,c470955a,8375e6b,a845c299,f377b701,9d615e53,edf6463,9b3b2d0,8684f8b6,15cf4122,33991a4b,5b7c85bb,f5698825) +,S(789c55f5,d393228c,7cc7920,9e705d29,867a6e9e,750d05da,9bc6dbdd,36c5c49f,8f38e43a,338058c9,39c64ff4,3f8f7bf0,2a7910bf,dc2f9af9,532049df,ca236de3) +,S(8fa4f0a8,1bacc20c,5d402478,23401597,bfbcc47b,973abe3d,71d33e2d,fee792f7,7dfac188,c5d6c17d,9e7430ed,d9038a6,e6fcf47,174347d8,7a68aa4e,cdc46c38) +,S(4d5f8d87,9377b056,afd4c8df,54a48673,c43fce03,d05be56a,56c42a23,356c34a2,b064c60f,a3b75513,577c171d,68acbef6,ac96f665,6a899d54,29e9427b,533b8e36) +,S(7a409ee0,8299930e,ddfc1e4a,db8475ca,9a99bf4f,a178a8b2,540ae448,ac87a3b1,5c4873af,c8a079cc,38a385c7,2ca039d4,4363425e,67de4cd4,15d09514,50f28e17) +,S(ac327275,44973221,dfb8b577,e33bd935,76407a86,77a1a842,bb04832f,68304e88,2b41b0de,3e406560,a57978e6,3359a911,6f993a91,9dd1c2ca,79c9a36a,6a4c8815) +,S(f9168fd3,973728c1,30dda9c6,907912d3,2e6cf9fb,b1c7a058,cc948f4e,44282720,c7005217,a6adf515,d8d3a87a,7e8a8b2e,aeb470db,c014824c,733e9a7b,17111677) +,S(818b9a9a,295d8f3b,bfb69d3a,f4749e5e,b0c1c04c,838ac3b2,9e74f6e5,dc73281a,141d14ab,64b3023c,597e96c9,3fdf393a,b53f45f4,56cd17a2,bd917af5,dca8daa5) +,S(90a416a9,dba0e05,bdd25dce,2dd0b0d9,200aef56,a6c0e16c,748e7d4c,99cac1c7,bc871391,95a2f128,af9c9c0d,56bff605,2fc27648,4e0a855d,6472f0e9,a779e0dc) +,S(678248e3,d48fd800,8e694890,b442d3f8,4f851881,9b152a6f,da24a6ea,88e1efb8,fa5d302b,51a36e66,98477693,9ba9c095,eb8b78c1,8f1bb114,53cb1904,a2185615) +,S(c2333e2e,742bb244,b7dac90a,18c2e65c,1dcb447b,11f8596c,bb3fcb8a,1e85195d,d15b8771,a31ff36d,b46b9ca1,b0ba345e,b877b7ec,48de20d4,71792a78,17ee826f) +,S(7d562291,9c72b694,d81bd71a,e78204af,995a63bf,3e8ecb3c,d9b3f589,c75ef8d8,aa554f52,67d9d3a5,8d35cf02,191b533d,ffdebf32,dde4cf07,252ef949,ec7df6bc) +,S(c5023f92,698f955e,4fcf7fda,288673ba,97b4d275,7f26f25a,c63ccfe9,155232b4,7d9dbce,def550c4,ee4c881f,69010859,c7a09ea5,36a8f7d7,17c1573d,c5db971f) +,S(37dc82b2,ed0e9533,e87867e8,d1eb57ed,707f335,b081d14d,d57aa247,645bb1d5,ff0c021a,d28649f2,3f000ae1,123f909f,1c803a9d,98ef2487,bf5d44bd,a97068dc) +,S(ceae1d30,2bf19dd3,a952ac79,8426244d,968b6ddf,25e16357,553f7636,a15ba8ed,c5a3a752,4d05206,39ecb8b,bf4282df,a1f9c795,ea74410a,ed9e064f,9a37c70) +,S(8bd49da5,fdb92648,f321bfc4,2d8145c5,20b8dea1,46b2bbf2,7a054698,3eb6574f,f769854c,5b5c9058,20ab0765,1a6d8104,e9a9dd1c,7aea6425,2b239ba9,7b0609f4) +,S(d1553a8,9a5226bb,3c5b6296,9f094b2c,1b761aaf,2605b0ba,b3793f6c,6959e8ee,d7b11159,d289d42b,8ca2889,f3dd7d01,e1cd0e5a,745b9f12,ab98b823,3211b2fc) +,S(ccf443ea,d8b17d4c,ec59ab81,74f1b1b4,8b6c3934,6e64a955,c617336e,aa6abc89,5cdbd39c,64510cdd,b342cce2,62915966,f8cef7cd,e10f4a7c,41a0d495,e5bdccd1) +,S(f95ad24e,7accb2b4,ce6afabf,6c1a40a0,172cf2b8,42871778,881ad94e,3f3d8d57,f3142d40,377543bb,6dee8195,743a6d73,e60dc5ef,4b0756eb,68d09d6e,326caf5b) +,S(464189d2,52726cd2,6f5ad4ca,5184503f,c546144a,ce7dfb32,5e4b4147,da7bcaba,910f8aae,acb04646,3c6a2a31,6174510d,8ae8bac9,fdce4c47,6c0dbd62,5196e2f9) +,S(637d373a,7355334e,70c78ae4,99429ce2,a5d97257,c0f407b8,1cb41704,d1b36415,469fa81,5dba5bd8,bb53a5fa,aff5b4c,18e7c28e,fbf21f52,14359d6c,7114c818) +,S(b489330e,2a4a4a6e,a99091aa,4e5aebaf,dcdba016,2bbc38df,5a49d4e4,7eee62b6,e1fed3d,93333ae9,2198b85e,fd68582a,35f6fb60,ff268494,720b387b,b3a7543e) +,S(8f2fbd92,70781f54,9d32ca01,2479438,2ec9cad6,2151c893,64c1cefb,c2324b12,2ae5c8a,2e018e74,2089a4b,12082c73,ba466dc9,851e7226,388e48ae,b1270a1d) +,S(a1871963,e9a65bd3,9e1b667c,55fe1a1b,87fe4215,8273c6c,f338f8cd,9119a828,e6881210,adb32d79,10dfe9da,c46c728b,20bca3e1,ad130240,f0dac7b9,fcc0cbc7) +,S(4a91a506,e8b32ca,13cbad7,99c4e3d7,21fd64c9,7ac8a1b1,e7f4bf2b,cc0ffa1e,66a0ee78,cb63bdd0,1a7c4bed,7bb565fe,832eb2c2,d32f2032,c33935f3,f16a40ca) +,S(61c960ef,2a3a6244,e8e7ee79,d4f5e98,88539c0a,b8be739b,314a100a,375ab66f,13b94913,ac8f600d,dbe9a82e,8987a061,3672629e,45d7d887,822faff2,60fb9e08) +,S(10325f87,f797c48b,2e6c7acb,bc0aa0e0,537fbf59,e74ab9fa,a7630c9b,86a04b72,685c5ae7,26b5c9c0,31e1c830,d513db4,b7fda140,14f8b723,7a9da11c,7ce9403f) +,S(71bca019,c15a3534,e5bebab0,6e1e1821,1ab01e97,dd24e1f9,1f89f834,b2cfde74,102387d9,a8da4f7,a483480b,316f0303,2178e668,f7a72719,2ae7e54d,27314a8e) +,S(7d30b01c,5c93abf8,9a50d14a,535a88f6,7cbb535b,1e58540,661fd7ea,91121fe6,e3d7e70d,1a9c0cb,2d6c86df,53709d18,b1989a5e,7642c1b7,cb381338,f6ed96d2) +,S(6f0322af,c1617968,b2550b3a,cafc8d0b,9445fd7a,4692f933,3ae9146e,fa2d3a4e,ba402962,d311b424,d05f199d,31b07d5c,8534ccff,caf817e0,88712bb4,2e6496a1) +,S(a3719ef2,c34bce90,feb7668c,a07d1a23,e2e6fbbe,1eef4b93,d2995e84,2c74688a,7164f77b,67aadb53,30b4127c,2d71dc46,f11e2d72,25968163,f4ea7358,134e5d56) +,S(3cb0007a,d2f1fb76,aa9752f0,218e2498,b7217440,a6a5136,68e95a78,4f71a72a,2f498749,12e8f469,e511b7a2,5a5046c0,f922a343,24620b51,3f6f0160,6de6b308) +,S(26b62d6e,f46929fd,88f00ca5,a699ac87,e090ab0c,8f02a078,393fb3ad,ae18c055,4fb9e53d,1b643585,4f2c78ed,1a818a80,1ff62c5d,fb0f8f23,d5e4d096,29886fbc) +,S(55e9ad69,68f490d,bfc2e17b,4e90dc5f,58335c1f,7bf30d44,79679acc,8cd7442,d4df7806,f74d9701,378ea804,be9a6270,85767e0f,b816ddec,4dbe34d9,536fe892) +,S(74a87add,723320ea,f1f9c35c,eddb6133,79835723,c74bc043,af36aeb3,5e1cbc45,5c79ef91,bccc2579,eea907ac,85ff8c0a,57fb48a7,c273f9af,6113e177,588fb14c) +,S(d4f1a9e0,2189ffca,c1d9914c,177fd66e,9d9a41cf,d1a38626,aed6b82f,70ba8020,923bf669,6ad7c71b,bfd696f3,9d68373b,9d0cbad,f367363e,2f70a93,4a0dea5c) +,S(593c7afd,c178edf,9eae7fb0,85984992,bc5ca489,16a2a155,a0314d8e,31fed706,ef39bd47,64f3b3b4,cd505e3a,628197df,5aa74126,30d83793,75c85b27,76a1073f) +,S(6622a6ea,569856b4,23e9f68a,78bab680,759a0089,3f6f645b,2e0eae60,f5dc9d3d,e84d491a,1bfc3127,3cfecf5b,65621213,bdf1af30,2dd39d26,d756e75c,4f9bc86d) +,S(d7149e32,fb34d956,1f5b25d0,650409f7,33a28fc1,fa4ad822,eabe98c6,74b3437d,2c249dbd,a1a82561,51b6eca8,a44bad96,1b2d37c6,d01c1d1a,70ceaa38,9b3f5039) +,S(64058ff8,7cadb65,8efbf32f,a68b7b3f,19915f5f,b434830f,bd5ca208,a4a09b6f,71c6dc90,f4d8082f,72d5697e,48fb380b,8486d7e1,5f113cc,28365ef7,d3ee9999) +,S(6a6cbb7f,5b571865,d70ec29d,425115a0,82d1fc1,f0209e8d,47be5e5,a9965dfc,fbf10d18,f3af0e94,b2a6ed30,c610f17f,5bd571a,41d073c4,2b2a4dce,c98ced0c) +,S(3f9a9be2,9a72cf7f,2086d9ff,3701a35a,94a7f81d,4b34a364,916a45e0,d8652874,25b12751,5ff033c1,70feaee1,189a35d8,ba0b8da,d4c943bb,4fdcebd2,1cffdf72) +,S(873be5e6,3cca17ca,95980167,9568b487,3d34c5ce,68abd305,169917a7,30dd206f,6ea148c1,280396a0,7ea5c5a4,17980f48,d076bdab,3df1628a,89da4c45,14bcbd4c) +,S(17865995,f28d4c4f,43e2e9f5,9b20edfd,830a65cd,d632cf9e,e7024ec3,4da0834a,6773c06d,478f3822,86c749c,5ae09a10,910b5666,5b6df747,36d20adc,af58332c) +,S(efe91146,fdfc4865,bd784853,ef79b8d4,d2f020db,3f901f45,38c74c80,bef49172,a81a34a8,dc3a229,8348109c,14d367c8,7abe6753,50d013e0,b1b0372d,2a6ee5ba) +,S(7ee6fb63,36cc88be,3b3c2821,1552031f,d017aa4e,192bc122,973545bf,924e8a8e,a656fe25,846e8173,327ab11b,d8ecd2ed,9d1909fb,21d1f789,588b4fa9,a8ceb0d8) +,S(449677d0,2a78e9a,ce374016,e19e7fae,46efd0d6,4839680a,4d5cbc42,173ee605,47017ad3,3357db8b,ceca2513,c6477157,f3daa99,9cccb709,bbe88340,29312013) +,S(ca9db080,12b9fd4a,cef2255e,83f35fb,e20806f3,9839c2a1,699c5d03,d7b5762,6a1a811,3d82a60b,677d61c0,af995bd1,4c598f08,f915e971,d9f17e9f,8398487b) +,S(d040da2,8dd69fc,67414651,714d4e94,5a27c4a2,9fb44612,d6d87f4f,80e2ba45,a1a72b85,957a01ca,8c8d5d3e,d9ae6a2b,31d2d192,cd7afb9a,4d1e4629,aeb9f356) +,S(27eeb708,fd2d52a9,47f69872,3706b67a,1d6e29b,cc0c86e8,111057f1,e3655608,7f67db4c,25b2e88e,275e53c1,c52eb47f,c2dab668,64b91236,522229d3,1b001a94) +,S(3bc82484,daab22ad,6d887a01,ea9f4b38,bb70e272,b15a7b4d,ab5e3dd2,439d8a23,b0ec952e,6cfe3ed7,4e6246d1,46c9c354,dacbc024,45b1af9a,6a668f0f,6fd52ded) +,S(d0a00060,13596198,8f070ff6,7ea731be,7f97a51f,68faf899,95eb0ad7,746aec69,dde4a735,d6dd08cc,28e2588e,9af0eed7,57017b38,790d381f,74748f30,9717a989) +,S(8efc4c50,51c65e10,56f5ccb6,a4be2014,a9dd043b,641b7690,cae2a8a9,1bbe8ecb,26fd1112,e1aa603c,91eb458e,3874d010,db58efab,5dd9ed20,e156886a,5f39fc13) +,S(e42271b8,881306ce,f166138,7d14f0d,da0db64a,b379368e,fa79969f,432cb110,d2b9999e,7ce9f3c5,8a6c77ce,a97cb9f5,f2860299,9bacdc7a,b7d5487f,8b5c9f5b) +,S(bb068f3f,8e7fbd31,f3aaf96f,de53d134,e3a88b63,9d8d43c6,4b3a2b45,2f8de740,574410bf,903c173e,23d88fb1,3f7534fe,566984c1,aa10f0d0,f54eea9e,7883819b) +,S(a3d0bd11,d728bee1,b166dff1,81c3682d,650fde7f,285ed5ef,b2ac5033,5327cd66,3e290c2a,42afb4ed,8b5a685f,69bdd379,44215104,17a61d8d,bd3dd2cd,805c5f44) +,S(9884434,78bfd51b,d27d04df,b5282a72,4cf82c21,487a8733,9347e560,994debdc,545574c4,359fe553,b694803c,5a07339b,b4e1a95a,b9fc72c7,5d4c8f5d,ec6ce4df) +,S(8cc104b8,58b8fb94,e0771dce,a103a7ae,adfc50cc,dea4cf93,a5f4ec9a,d44acea3,ad73883f,57c470cf,d477f228,8badab99,938b6723,516f97b1,22578f2b,f893b506) +,S(1627b08d,a822d244,ec8fe2e7,d8f02094,111fa362,e7190cbc,11229a4c,2043c626,41f6b029,80fb1370,c1e800de,39507798,8b6f315c,f910bb00,423ff727,e9e04c3c) +,S(459d4b1f,2676fd9c,2aac5937,376dc18c,fd4244d9,dc937407,d641e0d5,491df69,6f22ce37,a6ea6a5d,c9823197,22b0085a,e61fe140,d7558fcf,7bb44976,5de7aae6) +,S(cdfc7b3a,b755c181,72882e37,ff641e2a,94fa4e5e,b1b2947,4cd6e94b,f4f9387,76a11dae,107bced7,c2870dd,62ef183a,d45a02be,ce33e333,dea061fb,d89e787) +,S(5e189861,b1615f76,ac416236,e84b0961,b2639845,ecf6e6ee,8dc33217,b0952afd,1cfc65b0,9194d1f9,71136626,a2c3896f,5a3de705,ff1009c3,49a09c86,ea1667e1) +,S(84749eb3,3d482c59,81cc08bb,8634bad,fe0572d1,42367cc8,57a3c399,821d12c2,146a4fa2,3fecc0de,f00299c0,19406b30,dfbd9ad0,975717c8,7630e726,6e96022e) +,S(d73a1958,e9aa29b3,b1ab0807,2165c06f,daa38c90,6be76384,1851fa3,5711bca3,41f13f90,20633dac,3a5eca40,229ad15b,434c4f8d,4ea570ff,76d15d4f,63ea882e) +,S(1d77616e,1ccf1fda,bd4f0beb,6b60c1b3,1b94576e,bf2b61b8,c085cd79,caf8c018,7d3e5813,cf181271,55f3d084,df1077eb,2bfc9d6b,8ab6ede9,55c0ba4e,5095f23c) +,S(bac936d3,63887dab,cf27ea02,50bd550e,db37cb71,a2a8351f,fabcb1d,6d6ca9c4,7aa18819,8bd513e6,b45d6633,aa1af70d,b1a9c432,ffd1be4f,8a8fda79,a38c47f6) +,S(4d18c5c7,51639d86,b21712fe,b2333d52,5f4bd3f5,e4208537,e1e3bf7a,9343475f,2a60352a,4d8fcb6a,ce01b4c7,63619f16,156868c2,d85e882e,a2e7fb80,16f6500d) +,S(8e473caf,d74fb06,b483d955,ba3e35ec,e99a4495,cc86485,a8b6fada,c4c8eb4f,41708d5d,ae2de832,c7c38389,d0ae46c4,46add069,8e83990f,52a545f1,6ef66942) +,S(91366f76,48ed27a9,2ab639ac,f37aba5c,44e8bea6,1402e075,e307c4fa,ea2cefa8,868fe0f5,565092ad,677eb1c9,8959affe,5af504a0,c929bb58,2f5c3263,114ea371) +,S(1eab20f6,51b63685,a0a8489b,4e3247ce,1592c4db,40cb2f90,7eff1c58,c6609915,c142e9f4,b9522b0f,1db90912,c6f83c7,add6d8a,6bd1de4b,c54503a8,4e873cce) +,S(a0652eda,796ff72a,eaf8cfef,371594fb,e1528929,1320230d,2bc6a252,f4b49484,67e6d40e,8aaca7cd,f2a2047a,fc0a59c3,b4eddc1f,d3d5662f,45bb5792,9e4dc9a3) +,S(83915afa,c936886a,3deb8958,70e926e9,7ee4a6ab,1a5c66b,a1602c13,c4f959f1,86dad7b8,e870dba7,712ca968,1ab63524,2ed55fe0,36a148fe,25b1bdb1,1ac2da4c) +,S(293f0bc4,11454959,86b19fb8,6f738d2c,814523f8,b75b280,f8f9021f,95db6061,12d98ddc,894669fa,86b073e6,5855a0a1,760733e7,b7c5bf5e,868dd977,82a4fdbd) +,S(a829b1c0,d6780732,321871da,2d28ecdf,18d13311,4ddc33aa,8ff4caf0,58fb9ad,c5375298,501294a4,dc38d1f,a8c96f9b,789ee9c5,6533643e,1142bce6,8e1ef5ef) +,S(48133900,866a344,68309fc0,cc18f79,c0e01dfd,ed6a7bb4,e5a4697d,4b9cd462,335b7188,ccea4687,50fcdfc9,a6fa6034,c239fe6b,27cf6460,182a1c0e,c8c96707) +,S(7fe9d310,bbdaa101,b28c1e71,137a7ab5,181dca39,aa8d1469,bc06c856,3c7a70ec,18006c39,538a5141,2371828a,4d73e02,f4699a34,7e887318,57e394fe,75c8143c) +,S(1bd5b65b,d79c3eb,54ee1ce2,541b4352,1b7d6c37,d2a26f21,b51d2c07,103ebd8b,66e81b90,a120f04b,340adb2c,42143ef6,5d8a383,46e71856,673090ef,291d7bf2) +,S(237374f9,306e5714,5f37a1ce,1418a238,73938fa0,8bb971ab,fb5d97e8,e5fa0206,d8410815,fd4049e,f54abd51,fe2053a9,bde7f3ac,f40fe992,21bdcf8d,4b9808a5) +,S(33279bf7,38cee621,c17f75eb,bf78af4,58c1a4ef,a7197456,b57ee679,f2c34bfd,d63a21a4,5dc29462,13750d88,ea5e12c9,900b110b,ce433c49,e9b37382,7de327ac) +,S(ee274c71,b1f43251,11d7e100,5d7e9d97,ed1590d8,95cc6504,3e8ed6e5,5a87a9b,73f2bd1b,1baec4f8,ebbcf9ec,f613869e,8a262d99,7bdee49c,c5b2fb22,b652e9dd) +,S(2f49f0ab,c24536a3,3bb0857d,57c35846,f5dd036,3851a873,46f93d0e,53ab8de2,66b3dcd,d367958f,fd06121b,e42237a0,a9edaf21,79ded853,e8bf3c5,b6a81531) +,S(2d122193,ea92ca9b,46eec10e,2a23268e,9b1f972e,91821489,8cb12571,1e3094b0,b54d4b85,a02f77a1,57a48001,c0a26c81,2c038d0f,b91575cd,835183ff,3a0b7071) +,S(9047eae7,841f346a,374131ee,d4299fef,970f59e1,e4bb1fab,819fecb7,3026ad44,d59d3d2a,2c03be1e,553a54d,2dc61c9,e13364bf,3338a5f0,4e4466b6,86695061) +,S(f689480d,c0ddd61c,ba5aefe3,17aaa497,c2d051ed,d527cc20,16877986,12d7c8f,dac41495,a948d83e,37a9f310,18cd7abf,6d5608f2,213aa5cb,7a2b8f90,98d87398) +,S(4a01c418,be472958,5bae0c45,cf6233b9,ad0177ef,eb6e74ca,ded59788,a22d083a,8a12550b,83de095f,22411b16,937a85b5,a079c7ea,b8137f80,ffa66116,2a1c53f2) +,S(a6c715ad,cdc77020,febc4ae7,c6caf5a1,107147ba,8281d3f3,7945682e,72a5da7c,69b4ce46,2634da4e,e9e43559,72f87511,a26718d1,d232f726,577f0d5,6b49d165) +,S(68ecec4f,aa19ac3d,dd8b928e,8362ed53,3be24406,15f5ddf8,4b8a376b,cbff327d,f725f978,f6129f28,49a1c9fe,b07bc2b2,78fcdf4a,96a6ee3a,70b9b943,98a89f3d) +,S(5701d52e,2cdb7b71,a9ed91e6,95396487,1b656bc7,271299b,62ce0a4a,78dc69ee,eb8e4539,be99cbf0,ad730fa5,fcf785b7,35e1f5ad,f5c16c72,85abfeee,4058ea1b) +,S(8210f0c4,4b2f54b0,62de4761,b7c62d87,42424b13,ca0448ca,ba999eab,73b26409,1c79890,e4149248,b9dcd496,1da563f1,517275ec,79949969,8c6b864f,c03f8050) +,S(64cb2793,4ee57641,9d52cd81,6144543b,e4319d16,fdde7a7e,2bd824c,113bc1b7,c3144c3a,518eaebb,51a55bba,d87aba0a,12d3add5,5a5e00c0,94a2e227,80f0f6b7) +,S(37eb1010,acb889,932d8536,b86648e7,c124a8f5,1005c0fd,ec40bdd3,6369c82a,1da5703f,b387312d,d5a337c2,2d3f63b7,33dcc994,38109c2c,4807fc45,c02a2717) +,S(84bbf980,b54d60e1,ccfacb7,e861aded,b4cd7bd1,a3f7baa0,9a1898fa,22144d2b,3820c4d2,7b545166,2515064c,dc9b4cf,813c2435,e84a4a67,ba47068a,e6e09045) +,S(29e74c02,6b43add6,939ae05b,dc0a5e0e,b7d05bc0,536e23f8,8fed55e0,6f93f1f7,f0f6fd9c,798732c2,1dd1c550,3cfbd56a,71b335d3,aaa22359,75fb0c89,9571186c) +,S(98f3530,1122a0d2,629e5adc,579acbf8,8c0aea34,c3450ea6,784c4ce5,ee9672f1,427b899e,74e0c5cc,c289304d,b9a874c5,1d401369,55dc5b03,e0713bb0,8c3ec3ac) +,S(16af2e5c,4c37b50f,5f2b6e94,341e365c,90548d68,2bd9af37,1d849126,ad2c6c6b,1dd1bef1,6077f6df,32054335,c81ff474,33b7c1c7,d6243dbf,6a2564b0,fb9d8502) +,S(56998d6,bd5b2da6,d452f951,5343a9bc,4ed64463,adc6b8df,6a3edd64,e75e1cbc,ccd52462,9dbda3a3,10f3beac,7b3d3bb2,f1bf3c50,bca242ba,224861c8,1f26760f) +,S(f1732044,ec59c52,86273115,3c53aee0,c7f1c4df,e6e55cb0,e7e37d62,c1e11ce9,16a547b9,a61a6c10,4df1d1a9,de99f54,b42e0ad1,104a6a30,e6e616c4,dcadb2a2) +,S(6e5fcc4d,2df77b2b,8d2f95dc,56ddb885,6030f9af,aa51d86e,20d4772a,854b8973,11939a24,26c1ad6f,90db151e,c5c9f036,3f0b6898,2464fe92,c33aeedc,77347660) +,S(74a3ff02,98c3cbde,ba066554,d6def895,3954af05,f0f72365,680b7b8,4c5e9fc8,23b5f011,e50dd2b6,9c5ad6b,b4dad524,9c6a8abd,f134c232,f40de18c,3c65206) +,S(12a40a59,169e806c,8e32deb6,7e64c615,77a3ca,5c56723d,ebc98ed3,11983bc1,9d97709a,9c644c8e,3fcda745,a70cf3be,c405d230,eedac78f,96792bce,a715c081) +,S(f25dcc0c,5ae3f442,7fc17acc,bf888557,82673050,c3594abf,cea7eec4,7a4662af,52a20297,bb9213cd,d1b4f1f3,4f6168aa,ec2d326e,d9aef5eb,5b497c39,e0642e0b) +,S(fe31ac7b,ee45ffd7,99941eb1,8d65cb2d,38618938,c6278e45,4b87e41b,3c7d0f90,a5f1be4b,e0373cea,c3137a8a,c5b5cab3,e1209c93,2d49b245,eb99a0c6,469c3e64) +,S(c0ff7403,2855c2c9,ba06c2fc,6c9a8fc5,29b4ebb8,be082951,475196b0,ca4d6711,2c53707e,540e0c03,27a10980,25e356a,81fa6a48,b1e41d78,b7fe5515,b022173f) +,S(5b23e392,b87bef43,a3c08956,e1930c10,cae049e,b6f041f9,1bf3de75,4a84f984,c905adbc,337b9e7d,78781dd5,deaa0590,18e20bc3,5114c842,72343879,7a37987e) +,S(2100a6c5,b6b96ad6,37e13430,8d92e2cd,97902da4,7a016ccb,63a20cef,e72ac25c,a1fdc3cf,93560ea3,8418c470,679c5389,7bcc12aa,dc87ee6c,3429c68f,690f7e11) +,S(d57874e,509198e9,ee6ac826,b101ab2d,fe952895,ab288184,55f2d85a,eb2c3387,1c7bd36b,cdb6debc,99228b,341abac2,94dfd768,c9e00e73,8aa58339,d226f940) +,S(ff91057a,e46817be,b3874656,42afecb2,a290d31d,f18c6da3,d6313565,99657c4d,a2bb1559,96ca6cbe,2a375c3e,510df603,69d0cd8,f66d6571,9f9866f8,c6e73675) +,S(7f20e461,ee306c4d,7db625b3,49906235,14aca551,21b7890f,244de5e5,84d18b7f,8cc69fd1,eeb89a9f,9e126be4,3983ed45,d88c22fc,89f47006,ecd57431,4eb5d1c5) +,S(7ca32320,75421226,257670e4,5f277f4d,32cc7b4d,53588423,317203cc,b787696d,1e940799,8f25b7da,8f1212ba,c1dceaae,ca7b1952,26655535,6a98769c,b3da15fd) +,S(bcb7060e,f2685623,9aac249b,f603ce7d,b5c253a2,c998e44c,4ed60db6,730d5450,e03df58e,6d279025,955a4f52,dfce586b,f427e376,ca72e09,36d80c31,5047f57) +,S(30387990,3157ac6,fed71113,a004284e,82fdfc7a,3e08c0ff,1ff5dbc5,dbdfc04c,7132084a,1230ecfb,200ded60,9a1666a5,2f574014,d29475e1,6a061330,fbe19e7f) +,S(c5b3aa24,1147d664,a0b80f33,5dfefed8,a8f7c1a8,c6258686,cb16e3c,c365a249,fb5143c6,5f8907b9,a44f10fd,27064fef,93ee588f,9e77a65b,1cf64e4f,956f5748) +,S(11d8bdb2,b750146d,d78d8c55,6e6ac45f,4d34f1ae,35332673,cbb46bdd,3d76d9a9,1ea28ad5,c92761b8,7df96987,6e5b3243,9fe97661,87b5978a,d7515288,f30a5970) +,S(d6db4c60,742914e,c9c7bfa0,7a716cc5,f5492aa8,5381f31d,f76d089d,a773814d,b0ca5fa3,bc5d1fa2,c62a657d,77215b49,82f72e89,b138552d,bdea8166,359b6a3d) +,S(d28a6123,3b4e073,f1242c4f,5292bf70,9e1ae15e,a654bae3,4239133c,4a8a86e8,89519c8,8c44b38e,ad5c2ace,52d01de1,d74ee0de,5365567,cf1b21b2,2ae8b95) +,S(ff32042b,6a943772,d6f5794a,43420218,2ed31ac2,447167ba,ec82d19b,86751337,16961368,e20f2550,383268c3,9fe62fe3,b5d356b1,da2e4231,8f9618e3,13655f0e) +,S(f2c6177,30a9870f,5999ed69,d34efac3,589baa96,9f660cf9,ac839eee,a10e374c,fbb2480e,b6f191c0,15ee3c58,bd950aa6,7bee7569,1681250e,502e1d76,b6ec9069) +,S(dca14b70,e5e33022,eb559d90,1cf3a533,4c40bd45,7a43df85,e87acd40,90342539,7d038e51,30f77ec7,efe84748,4145594f,87d613bb,85a95715,9d0cd377,91678d23) +,S(9cbb407d,acc7c2df,2d86a258,d5ab2b43,31a18bea,9480f5e3,7727aef7,644416cf,7ab9fb64,c5f54f6a,4e5529b6,eb7834ae,80283bcd,c3f6b24a,8a014d02,b3b80b57) +,S(4552c48f,2d96ef41,aaf27778,a7ab4945,e4f2a2fb,7e1564ee,c375e50e,3516f555,e63da54e,28b70a99,5f35a1ac,3a25e384,6efafcbe,4e8f73fe,d84e095f,126524ac) +,S(b4cfb90b,168dc850,36559181,3d2d084a,9866512,9396f76,879280f2,38e4af3f,cfca0080,37006c35,7fd89c5a,1d444d19,5fd72d4,17fee670,e7b743dd,57f71b00) +,S(8e264996,e4e8a858,a1e32c59,b0df640b,a096401c,e77be6ee,ccd228d9,67dada3f,c9f5a8bc,89322e56,838c6d8d,859b6012,6d0a40f2,8377aca6,b5b4dacd,44931d0e) +,S(34ea02ae,49a4dce2,5ec2dc07,c71e3400,390b3054,83b8f30a,81021eef,5761ed99,b4b6f9ea,c41bf9d6,c4bba143,4639fd57,b8735d27,6098e374,d9324319,3def4c1b) +,S(bd391dfd,8569db85,b567c36c,5e6c378c,c152ad9b,c23d1fd6,1af23e29,543a56c3,9bf167d2,77e6bca3,a8d3cce7,61a36abe,91fcad0d,8d6ce398,877d3748,f2f13bf) +,S(67b295aa,440c8807,95369b98,c67d1d5c,1b9265af,58541994,7353c0bc,47ea8483,c94a0287,f2983c42,14f3baca,a8c5c791,d4d88fb7,30eb5b3d,4309f5cb,c5706f23) +,S(755e0335,284ad31b,5afb5775,fa191486,32b29c84,f38cafce,1b0b3b4f,2d073a42,c4506c75,c8cc96d2,8e31766e,a8ed1cf,531f4f7c,73888831,65f825d2,2b74c47d) +,S(e4b0cb3a,6149079b,5e47ccd,bfc4f351,64e575c9,20cd9827,a83f68e7,e5ba0a97,1604e71a,afa83b19,61bdd7ae,e4be5113,f9e9ddc2,29957255,cfe40341,9e45e5f4) +,S(3baca490,3147531c,905a2c73,277e4f39,c27ff6e5,41f6f2b,3ed4f730,3af0c4a,cf36fade,87b988ee,a4ccec6b,6b70ec01,d057173f,3aa7c79a,6bf4d412,d4bcafbc) +,S(229519e8,2a4dd2e7,ae77d713,21fbc8ff,f31191ee,6604823c,a6aefe03,19d06d95,a70e9af6,14ae7a1f,76224b8f,f5d1fc26,2e34707e,a6bfd26c,8cd7fba9,b5627e15) +,S(59364b22,4a53ed1a,7dbe9753,1b3a2600,2f700045,b0576733,8ee87a9b,2559dd54,b08cc507,70f5f3d8,851908b7,ed79ebc9,7f4f7342,61de0752,e14237c2,14eb5f6) +,S(d4b681cb,f3467c9c,649fd640,7991b4ac,3c66bf50,26ae93f9,e9b0238,9fb7c1f2,6df1a03f,4a5f00f4,8356bb9f,b23f1621,bb18a8e0,5afac4ce,4edbb01f,99a27000) +,S(49784426,fb036d23,a289f4f5,b3b92535,76da111f,ffcefdb6,a4163e55,2c56bc,76de5ca2,16ce703c,6a62ea4c,a0f7ae07,3744a22d,6db67389,9b0e93ff,a69e2a9d) +,S(5b213b9d,3f84b248,a98fe326,929b94a9,7bf78521,106a83fc,adba632c,8ed4892f,8eec203e,d015749f,f01402b1,722214d2,b58af86a,95384ae1,c39a7780,5623a204) +,S(6bb55cfb,9e3f5468,966711b8,6343e4af,6e372d04,ee7f570c,6a12005d,628959ef,75359562,9d633c9f,c2432ad5,f4c9f00,c6f54005,cdffaf82,438e3e58,70d14154) +,S(d760efaa,3a9e5c7a,967174a4,705baafe,d230dadb,4c957cf0,c025ab55,4b2eeb43,c019790a,b1b8498b,58daa784,ba02b7b5,672ba2b6,13d312cb,b4563f6f,e26675ce) +,S(f8be7bdc,6a361b6b,2844c60b,af7fec1a,216d75f6,96418734,337f9ccb,ae9117c0,df66b665,21e3dccf,639a323,5d773c21,4364062f,c5260323,3007e2cc,457d783a) +,S(6bbd2558,84348c88,c75a8155,6529be50,93b06a4,885c5d32,f1047357,a11434a2,842f9093,fd41b2a2,153727ae,ca2cbf00,a494ab7b,eef1a2cd,8696e972,1b1491d1) +,S(e692623d,cda3bde3,d32c1c01,f480d21f,9ccf8f1c,416a7dd5,17f1aab,12d3f3c6,30dab6f8,71f4c6d4,c768e086,fd6287ad,3fd000bc,3b04aa70,35cf441d,44764b89) +,S(86dbfe13,5db905ef,9ec7483c,6f51b75a,71726a1a,27e5131,8d6c0b2c,b0b933c2,371f23bd,45c46d3c,18056f23,10ab6afa,1259c88a,3a55f8ce,cecaea71,aea083a0) +,S(7ee329d5,9c625a92,594e620,4cb48559,458514f8,da94c7ba,fd2a4835,a4f10239,80a58a2b,e17f32da,dc80038c,7ed57de4,c7c561c6,69bf6786,57ee72ae,dd2bef04) +,S(e16a922b,8255d2c9,6ef776b,cda14285,b1cad5f7,62f75465,f8c82695,cf1065c2,44bc0e38,df9ce403,a927cb01,849e166e,6838468d,c7a8bd4e,6ec3fbbe,1f3465bd) +,S(5311e064,23145aa3,10737d38,41adf49b,988c1ca8,e8a705ca,3ca67f98,f756fe87,21c3f6ef,73bcca3a,c376e20f,dec775af,e22e708e,7e500c24,23114b4c,84ea8678) +,S(c09eda1d,dad1ca36,a9aaefdc,d16c5f50,a6ae499f,2cdefa2e,e5b61ab6,69f7fdf3,2220cbe5,bc279362,c5506404,e1df076,52624966,e3222b7a,62a1f7f9,faf00500) +,S(8888e104,18fb5c16,fc3c2b7e,b9ea06c1,da2df71f,c647b989,e71662a1,731628b4,7444a776,fa8f5bbe,959c71e2,c919b761,a2f8fdcb,5e66e5b,65e561e0,928e2d73) +,S(5c70258c,c1030231,d897c9a9,199df5b5,8b920f59,18141ece,d84bbcb8,b9b6c243,d627669a,e3dbb6d8,57d65a42,ec53bdf1,c688492,d189b1b8,67b75c3,f003ff90) +,S(eb58739b,878ea9f6,74b16f8a,406e7135,1ef06377,d9be32e8,1f657648,60e35ae0,752ae84c,8db0c7f4,e956d2b4,5750a5ef,24ea454,8f275f0,52b59ead,e3405ab5) +,S(996af698,ef26245e,35e4845a,dbf9c45d,6fec5564,c1fab0b4,8ac78f06,9840e0e7,a86b564c,ee788008,bbb04ee,e3d66c42,3c6910e7,7988aa54,420f3a4d,3137a1b5) +,S(bd03f2ea,a505bdd,7f39915,23f3e3b7,7532335a,6b5a11a1,4e303542,c00b8f4b,345f765f,cad902c4,56211eb0,bbe520ad,aacf55d9,e9c67787,aa02f18d,ccd88ea) +,S(8480c77f,3dd59c6,329c221b,ed8473e0,8cb0446d,c4e9bc6b,f2dba8d1,7ddf0f1,b055a135,a224f1e2,965cff1,a4f0d764,fed265bb,c644c696,2f3570d1,9af6e360) +,S(f46b6845,fa45e8c4,576b7c74,cd1a308e,f1adeedc,1d539d21,1158318c,ebd4c584,e1ed2665,34a14e05,c1ecf136,8cf8d6bf,fd9f0258,a5f0a53c,8abb00a3,e953c425) +,S(596db19c,38d91452,ad238f05,453bb773,9883df63,a0b545e2,47e5947c,d9f52a2e,bcb35b45,b172aeff,9e4fc5d1,714d6743,46bb4073,6f571291,e6575d34,f8b0d929) +,S(4cfbd998,f9544921,e5f1658d,e3ee95c6,df85b3f9,309f7a85,f6e4d08b,7e535497,ccd54e2e,437e4aff,7fc2ef17,3bed5ce6,b7d6e34b,4b386f36,72140d72,ceba71e9) +,S(c3f056d2,357ffe13,4403cee,6dd5ba3a,a7d2d0d,91d83f25,cb2cee44,34e57f94,1c31cee1,595b3682,fd85840e,312a61e4,40cbbf68,55418b30,bd6b24ab,c3bbf7b) +,S(e272370b,82ffc486,53274eb8,898409c5,9338e024,202be5e7,e18b5ec5,7f824680,d2f4e6c,619f0d,71e38990,f4e52881,de27ee31,ff7ad9cb,11a7f735,80a546cb) +,S(81537bc4,6a5fe897,827aeba4,6e66d576,6cd05a35,cd3fe1cd,9c06a2d7,194be59f,6706c254,125be3c5,92ad55f,6fa6289,4298f23f,2f4f397f,3bc84f50,79bcb8ae) +,S(50e161e2,6bc89d2c,816030ad,45559a3b,49c8606c,b28b6307,6ac6a051,9226d2b2,98478bc6,3f8d6be9,2db02910,67e5e359,e865d046,a5dd853a,fccb7592,72985c67) +,S(76ce7272,fcff02f9,bfc355eb,24286fab,88ba08ad,b15e099,22724b84,315be56,88f98fe7,62e37fdb,b72c1526,59528cdc,fc4c4203,c465e772,38dc8618,78a5a14d) +,S(77935c1,3a7f5f47,13098101,6e10ec54,d5ca10eb,492d4025,365d5265,ef7e6ebb,3c15e7c9,cf230340,44444126,5e74456a,4f3b72dd,7aff0ac1,aa76c67b,ce77dd0a) +,S(b37c3ecf,5813b5a5,2f52fc4,42049653,991d9241,e8677d2a,f9779fda,43c7a255,4361c742,c070b356,387fef42,1a9cdf79,58dd47a0,b7c9add5,57fa425d,626a1786) +,S(90c64aa3,28d43534,271e2f37,3460d8af,d17f9585,516b909a,6a7bea2f,1b12d2c6,79394191,a37a451f,e439e538,5e876c2d,ac397f0e,dfe29114,d14b9363,b76823c4) +,S(a314f637,2362ef7c,c4bec6a7,9396c318,568d9f05,9b6ca38a,c5f56090,c33e5e5e,b3a401e4,f7741130,95179507,2ce3b0e,53d2f51,f2dcaa9,d289e25a,8de01519) +,S(15c25f4e,80a7de90,8c49fc7b,649afd24,4c5a4be4,dfc15b2f,70099f73,6ad003dd,4aa9fb98,39855fca,c9f8bb26,b6322c95,e5d7adae,5aca9bf6,de073949,eb364b86) +,S(445e6d34,90f4ce76,22b6713f,584065a5,e0998d47,1b7603a,2527ed85,5d67d7a0,ecf994bd,7ba618b7,6eaca0,b852e0eb,be7b7f86,70d028e3,f52d1b2,846ce8ea) +,S(def695be,1ded66c3,650e9918,e942e4c,bd420fab,3a4708c2,43ab4e3f,1bf2101b,63569e13,532bf299,a0cf8d0e,a4addffc,1e782a1e,98a2f7c0,e0b64f50,8dd0afc5) +,S(eb364f1b,89938b48,2d32271,551f9529,5013185e,3ee2b534,bf01a288,9a534a88,9e6091fa,b439d0,d96f6a9d,cb468573,881234c1,6bbf4c50,32a6c950,99e6e6c1) +,S(7efe80e6,5c0134b8,49b6c58c,7d4c54ac,873e43fd,1b47f9d2,1d33f9c8,ee26646b,5411262d,63357cc8,d8280243,41d1767f,c25a0972,4c8c7a7f,3ddf6701,d12478e7) +,S(5f412876,3774e9de,6f2f25d8,a1d98de9,edf959a8,884643a4,fa18ac7a,26d6308,d3f6eff0,e336d4f5,abe35a12,4c47ed4e,5dbbe6d8,7d563fb1,8ea89242,aa454411) +,S(c63e3b34,bafd384b,2b60328b,4aee3a28,c7b3ed30,8a7cde45,87aa6c75,6c49c2dd,724fbbfc,11d05623,a5cb449e,a2f9f65f,a3de167a,a811bfcb,6ab9c3d0,3b123ad7) +,S(cc92795e,a0be5e79,757a86b5,147429eb,ca7a7c7,d51a8d3c,93650178,4f6ba5b5,92053ab3,db369d61,3af1093f,50829c73,4618c1d3,610ebc57,420d2824,935ae2ff) +,S(ba73d310,b5170cd1,57bbe14,63bfe944,ce7cea80,1b1aedb2,da3db11d,f1c7ea5c,4114e55,15806ca6,323edc6b,f0b75a92,834c72ff,9579d1f2,27fdadd6,d773c577) +,S(6047bc6,fd3a1c7b,9a36036a,94139542,7d9432c0,f652259e,1d52d709,e5088b22,bb119bf4,5d8ac9bb,1a918e6b,95cdf23e,6e2ccbf0,171579f7,ecfc9126,6d236b8a) +,S(a0600a7c,484559cf,3da255c4,935d2d97,1628fe8a,e75b88bb,1f3c4eca,e68f78d5,a439ac58,42bc6ee8,be096973,d87598da,349929c6,92e37852,e57ac941,eedef402) +,S(bfdef77e,1efac235,c1c49f04,290f89aa,c2e4632c,85f40481,dfdf5c59,d479e2a,e6e451cf,d76433ab,1de85511,9abaa5c7,8e4499a5,fa48ad77,f098c825,206dc7fc) +,S(81ff778c,373975,fb041cf8,ce4bc337,e2c977f2,d6bb2c61,9122240b,8e21234,3fc02add,e92c9928,e94e0ad0,218d6204,d71ef295,4c32227d,96b30b5b,9a61f640) +,S(84c4653c,d1af54f3,fc59dab4,5bbaa470,48f8eb13,4afc8f5b,60a8974a,cbf03933,98ff808b,a4682139,68b73ecb,67fe0a32,85dace7a,19d300dd,bd517e3d,b04ddba9) +,S(9d7ed86a,69f39ecd,c448de07,55197029,f81ee886,7c9a61b9,62d13eb3,abce35ae,d9b27e39,41c6bd1d,87dab6e9,32e8ba57,1dcd2c58,67177ce8,e7ef0fdc,668fccd5) +,S(540b7fe1,ee263e6b,3610bb96,1071d817,b9cdd162,77aaf28,87e7e5fd,df72f5b5,6638015d,591305c1,7a598a44,ba6871cb,8d1d3628,3ea25c5c,846bab2b,cd910340) +,S(4799c5ec,f1fb2112,f479abab,217ed0dc,e936c6bd,14215eee,6bbbb34f,d811cbe0,abfdeb73,4ac738cf,f607cd93,de58c0a3,237201eb,da47a808,3bccaee6,da5c5515) +,S(70a58362,b360c280,626a8698,7e4f2aa1,abdc9f8,f0b8c216,bb88b0cc,133c2312,5e37daac,d2835f3,1d924659,e51858ab,68e3a874,947360eb,c520767f,ce4d46d0) +,S(f345a0ca,857102b6,e225dfc5,7ae1cbbb,dd5c2737,116adbd8,b3d1f74,7d132b01,16fcaf2d,f7cae2ec,ef25da7b,3d51afd2,8f5e9920,5c0d74f0,c1e7b360,17eb2fb8) +,S(c3f4282b,29f253d4,fae8deb7,941484e3,9d2555d3,f96889b4,551e7d8a,eb2a209d,fc562248,8a6e83f1,6bb1530d,2a35629d,b25c8280,2eea7057,d22d109d,4263ac1d) +,S(5542218f,606e7cf3,9cf646a1,3677b0ed,4ff61aac,1dcea3f5,da5dd4a7,d4727632,f1bce63e,a11d5176,f47e576f,66817f45,4b51840b,a79695e6,3a1a1cd6,fb6c07db) +,S(65e81ed2,7d6b839e,5c3829f9,24beda63,98264de8,b2223479,43881582,4d124b35,2a17e09c,e4dd6e6a,32d85d71,e6cc2378,b53b9356,ee5790f6,8fc3040c,e6b6179f) +,S(5066b022,e43a5f83,c4290064,9e2b611e,750a5ded,7c89b8f5,892126f1,e112edf3,381e92b3,e407c6c5,d1c0ab40,6fbe1a99,57643da9,a2118cb1,3b8c6243,9328d9e8) +,S(8df78ac5,c5ff1cc6,df1e1dfb,58ef889b,17886433,61bea73b,a805c3ae,a83e2373,dc668ddf,5b39eebb,7b692997,f22140c1,8347e14b,edb6d343,96017e09,d37ca4d3) +,S(426c1767,7d7b00ee,af8d7d30,1bb11cea,1cebfa58,fc54bf0f,de719937,fb484434,4fcfa5b9,ab7b71fd,560ecbfa,985db2f2,418465f7,cbf8acd8,fdd71af5,7f9519d8) +,S(4f7f0061,bb90e396,63f6aadf,70dd3312,f781b2a2,3867df3c,566e18f9,b4a511e1,1308473f,d8956b35,97d904c6,cf73c05c,fd7c075d,c83848b8,571e666d,dc44b3df) +,S(7393002d,d2e85925,3b23db69,6c140258,8272a847,d834982c,5b22b256,93685107,b61532fc,6706f7ad,78548e76,b334a836,c899a49c,46afa1f4,4579b5cd,27641528) +,S(c41dff65,e88e5c6f,fca3b0ab,6ae69bde,c4215194,cd7c57ca,fd9b38be,feab4e05,9a9ba27b,a0b7e217,d31340cb,acd8506,7f052d8b,f92a4be1,cf59fbe9,6241f0c9) +,S(f619dc9d,6dcc39d2,9155082c,2ed9bc60,99296a8a,982327f0,60fd6208,5765c518,87961d3e,2b850ffd,f080d5aa,cceb1912,120ddbc3,4e0ad8d7,96e74afc,aa4871fd) +,S(6becdd5d,f02a7bbc,d1cc811c,fb83901c,46aa8207,35e81c29,a8d4d4ea,3f5cf99a,a45f7dd1,8949f842,2905c7ee,836004a6,5bb106d2,fb623d68,c2690c14,f181e39d) +,S(cd2390,db1e7c53,f424a893,c2529660,69a8f151,6f60722a,524578e3,e5427196,b817ed1b,457633ab,a3439454,6ed410cd,8140b9d2,e7e679b6,3322eae5,f3466e90) +,S(96cd9608,7f1cbcc9,b017ad2b,c7824285,4047dc3d,f98e7951,2fc09fbc,e3cd33ab,dfdb9090,c8a5ae70,13b8faa7,855554d7,3df381d7,88fd5569,d3a7ef7d,f729d625) +,S(99cd7508,5e9abb74,5fe03e3d,b100f2c5,2a43acc9,4127bd8f,83314baf,70d72b4a,19c98b68,2ded269a,57e50e3a,28b9cd65,344000ed,dac3d3e9,d8ac8370,662ee1c5) +,S(f53c2afa,647496ac,6c1220e1,4627c138,186286ef,b776449,55f9238,b39fdb20,1598c495,106a200,58fe1fd9,b29140e6,a93996d4,fe4cfdd6,74ec10f0,75badbd7) +,S(c127dad5,3b9457b9,51192c79,5793734a,d0a84671,ff6ba236,f53cc40f,769585f8,688e6264,da4e9d1e,fe66f5ab,db078c56,98696ef3,53b3bd42,c344b3f1,3d3ad744) +,S(882bc4c7,651634c,930384d1,3daf5a91,41508df3,2d34818a,e61bb65,40e92bd7,5c456414,430eece2,fc6e95b3,7700f608,9815f5cb,12a09ebe,8a87e370,85bcf255) +,S(4cbc141f,55c0b001,cfd934e4,dbbc2c2e,4b5dc68,72e3388f,2388e54c,e2a91bdc,1749d8e5,30d21894,221b2aa5,96541f1d,e700bbc1,e3427140,24f0a9b,9c0766b0) +,S(bff11777,6bb9bfd6,bbf872a1,3b9b6a62,32465cef,f16c3c75,441c39ea,2975528e,9e7412e4,ae492669,58dbdc9a,b7b1f4c5,d2edefc1,d4f0a483,27f2fd69,f992eb34) +,S(251416e5,887b294f,c752a1e2,3e991f11,90b8798b,11c97033,e470bfb5,b7bb6328,e6981dcf,15fb4b98,ac8a37da,267f1bb6,a2a38b86,3919d20f,72b5bc34,cb5e329c) +,S(bfe2490,569255d1,a62318c8,416e9114,66dec59a,bcca5df4,e64c2f48,46d050d4,f78bf673,577508c8,3846bd5a,312b9284,2283c47e,d4df7651,79d33bda,ba6eea54) +,S(e50d0a78,40779b75,fa121def,456865d9,3d7bb9c5,d566d790,58b1b56c,3fdc7b15,2f2688ee,4abcfa52,9424d4cd,eb40a8a6,a6de26b1,be8946f1,e4ba429b,5b32a6c8) +,S(b3a9d7ef,235df6ef,262e177d,19bd1121,167a056a,3957ffd2,a3d22d00,9a199bab,6a7adf,40ab5386,21fc3447,77c97416,66537460,44113c5b,a73455bd,9658753b) +,S(ec7277c4,20af5d48,3a6247d3,a1da7243,31c0e35a,85d6057d,55a3e526,bb7962bf,2dcd3e8c,5abc47d4,56bfcf,a8086889,89354e10,8188fb0b,c9ab4578,7b91d69d) +,S(91ed86a2,330ef91d,e085df2,a947c9de,f1284b8c,76d9b432,8dee9342,bd297242,fcc226b0,c46a36f3,ac56ec31,bf297360,8375f0f7,d248c669,f8b31ca9,9d056713) +,S(e2a09eb6,6e76b287,36c5824f,829afff2,439d973,e5be5b4,f3c55cea,e83bbda4,6b217b22,123bf3db,f35845f,315264c0,4a67ba18,a49abd08,6b2acc76,ca0b016c) +,S(78501449,bd76ff1f,58cdf2e9,203de4d8,3325ce45,1bf106d,2f474e91,bb0545c1,d0bbcc92,acbad044,218a830d,5f461332,cf488003,4b6f89fa,2f58b708,63aaa585) +,S(c3626c48,95df6e93,2c79d5d7,eac22ef1,d7679f1b,1df1259d,2be08aaf,7217d978,a594df74,250bcb50,dd9f294d,e7322b25,f72cf935,700856e3,c31fc5f,35e61b67) +,S(5c6e0358,ec09945a,c4240f22,3304f744,63269e16,c4f87dbb,99bbb744,bb4afaae,e6168dcb,d719ad05,8020dbc5,b03ec4c0,61b1fd87,d530913e,6df5d498,69e340d7) +,S(4a3fb364,d55fca64,4cc03c40,5a5956b8,a794718a,5b43cdf0,795e5d5d,5f79e7c0,4c4e0c11,5f88ef66,545280de,af9e3d59,3ff7d1ec,d8f20779,70ed84a7,8d660d28) +,S(fdc828e6,e305427d,c925de61,6f57e13f,5d0c8777,b538e511,49cdd304,1b022d05,de9e1037,db0dab0c,fedd8544,3b926a36,88e8bc54,7420b27,c65e2c6d,bbcb1662) +,S(6d70ad6c,375119a0,f4b2b65f,51257d7b,e73a8d69,ab944dcb,232b8fd8,e7021583,31de3a22,c8e8034a,d812a7d,234cad97,978aba7a,1c2996b7,aee623f5,858770e2) +,S(faa9dff,68f63fc5,7ca8c39d,8d950c2f,78a90317,c5d7f787,6ffa035,fcce8dc6,419b6c29,a7c02ea6,c8b7ed5b,c9b6fe89,1b3c705d,2ed2707f,3ef7995c,81a17de0) +,S(53d9472b,eb9a020,e84e10f0,1d5ed8c2,6219d24a,eab4cd67,dd30f084,8fa47a12,624f4c9c,64c02832,9b6ad395,dd51f960,41eeffc3,b3238764,57d21f85,d8c674ce) +,S(598daff5,aac2831e,21d5eff6,319e563e,3208ea18,e3ffe13f,2bf19444,73292f02,3db66869,2538e2f,e3689a41,dbb05504,bc86dabd,e033fc1,dbd7f84d,dd4e18c2) +,S(eefd321d,41fe6468,a7766276,5932449a,d3956209,c4c6a548,c4392db9,b4e39a97,6a372971,d5515d4e,c691b3cf,e73ccf6a,a491df97,570c9f52,3f29b108,c626c319) +,S(5a3a8225,49ecb78a,9c5aa12a,49e02c5e,10c168ac,e053f85f,30921724,96177ee4,482a65fb,f57726d9,d4ad61c6,75cdd5c3,25b6e59,899366a5,3ddbf239,96016448) +,S(e21f7d4d,b2343eb0,1d23d1c,5ec76db9,89e1e624,2fabc41a,b204ca64,838eee55,fb64c87d,ba7c54d6,f1d68d7f,a49d50b1,bd79d699,a75227e8,4363ed30,430b2605) +,S(fd688c92,f80983b8,496689ae,fcc0820a,a3d91fb2,aa4d599a,f48de5b0,98ed491e,7f946da9,9169612b,dd6ad8b5,d686052e,3ff25610,21432c92,f8728187,29e860e7) +,S(65594f34,947f182,bcd1703c,dbb1ddbc,4bf59b2c,2fff23f4,1d363631,cd54af0f,e8d98a21,a603eabe,cc1a1b83,9ccd553e,fa5eb258,5dc94e10,d134f40a,63b5bb1b) +,S(4f47f3b9,8bcf3917,464c07cd,be99d2ea,adf31166,8199324e,d120d087,e14789e7,279da4fb,d718e578,b10d316b,9994dd05,ffa05431,f85db2d6,6d4327d3,68aac28a) +,S(32cd8b52,c027e4e1,7991ccf5,6460f3dc,1d2ea6be,6434067d,bd4880e8,a09196dc,1d3066d3,76961716,1882da20,e467e035,4ad84041,f391a042,9e94d8a0,5d89807) +,S(c454b400,c7946f9b,b35003a7,c51e8037,dd03fcda,f0a19b14,f8daba3f,310d8bec,dffa7652,86aecb65,2744c9e0,21229687,1c305d91,6279b414,1ca1a,acc021b9) +,S(151b7159,4fce7438,2ac83025,6d98abbb,6ca309b6,64ef0235,53495342,34f7b4f6,fc61aa0d,722156b5,dd7ffd24,38100589,1bf236be,a41aff71,c3f1964f,15978a28) +,S(59716aa9,6b60ebde,848783d1,a686e9ab,e337b87d,104aa3f9,4cc7af46,ea8b8710,2e3062d4,a7d290eb,f53ee38,31dd8e80,354fd671,62a01a4c,73c57fb3,4582d345) +,S(81838542,7622429e,832e7a50,b1a670e1,2a626c3b,97cc69f7,abaadd5a,44a92395,18a88d63,d42e3ba2,af4b6c36,9971b0b9,35363e5d,77417116,b58de2d,8b6afb42) +,S(c95cf1fc,af7dd741,479a54ca,40a0e264,a989f0da,99b3a1b3,c4f67284,c8ae2a75,14b32e26,99662bee,51ad8534,fca1925a,a835cd00,9807c5e6,915b8283,63872f76) +,S(9362c939,ea51a649,2ae2dc2b,c01e4bfe,ccdf4612,97932668,2435bf44,e9c6ea1f,944684c5,2cb534b1,4871f48,41e889ad,933299bb,474b392d,a1e85ffc,5763c2e0) +,S(8852fd51,1e5f5e93,c6c3c7b8,4b0544af,cdb7d0b8,497d4bfc,90cb7322,28a77040,b0ea5bb9,c338a6de,7333b4cf,ac29f997,36c248,405facd2,6ce438f9,cb997a13) +,S(59105318,491ab266,2fb94506,532ed81b,74c8f82e,a13581ae,ef6c0c77,80696ad9,3417191f,bdcc1dd1,43323ff8,6e6051ee,921dcf69,9eda369a,afec66ff,a06097ec) +,S(c78bb701,8e96901d,3f13681e,ecc24df9,65b124b6,43f72904,ddf00ce8,bd28a127,ef07ce8,1b9c1cf1,26108dd5,f96ff86b,e0d49bdf,ad3d518b,1004b3c9,4c79bea0) +,S(9eb55ba5,2b5d11ae,3d419ede,5a5480b6,c2aee921,6f9aeb4a,96e51934,e8e4c11d,50094963,25b94022,2642ca89,1fb4697a,5e643e50,19670934,99937432,f020eaf) +,S(79ca2986,d40c7786,dc4d3e6f,71c33233,ad0b65fd,96822383,c11949f1,ab42f5e1,275db48a,fab1f0db,188e1298,4b391ce,6872e216,85c04c0f,3e62d42,d1e6d310) +,S(a2cf65b8,fe2a7abc,b78bcdf3,f25db18f,432ada89,1ce7d99f,faccefe8,e9673463,418e9be4,f6a1dce9,200823f0,5a6a0e31,7924a0f9,44c18b2f,1602a2fd,1ef13a72) +,S(7f6881f3,9f4684d1,3bf35c4b,c350b64b,28eb3c44,2adf05fb,c5e2c1e0,307fef19,20ac47a9,b954e805,db6fa20a,4e1a04f3,36c058f2,1946aff4,d4c24f63,6bd608eb) +,S(abf40dcf,72704e6c,65502d17,aa384bca,5834a802,62ec0de2,fd46ca2d,d9316ef,f605192b,a8c56b66,f3bdb35d,9c1df4d9,94662b41,85e8e6c2,9fde9d27,45039564) +,S(4fbb0d5d,ada948f6,2877c665,9cfe5f57,c6d5be5c,8cbb7bee,71cc575a,f4c92989,d2290911,45c718d5,243e1ef,92b8f7bc,2c77af95,f8666ce8,15900462,35d1c3dc) +,S(6c62710d,d0ce5eb9,5196e202,7c3c1d12,5a25f329,878b1f38,fa883146,b8ccffa4,c70ee1dc,174a6a4b,908b54d,69c94ec,5829bc8d,f6513c82,b0fc02ce,f566dde7) +,S(83ac175e,e220c800,a40adc87,df8450a3,963015a5,2c9e9497,602f930c,37af6c12,b7dd932,95601178,f6db7b5f,98046d7c,e42371ab,34e5f11,31f7cb31,59d37994) +,S(c823727a,348e275b,f52c18b1,43653c3f,8f0a5c0a,e8f48432,a8016486,ec3674b5,760237f6,2222cf21,fe1813da,4cfe9437,edca8286,cf3be63b,5bb05560,fa71235f) +,S(388b02ce,506784cf,2ec7e315,e765f126,23f764a,7d1ef836,fe360355,cb3f0517,ed0998cc,9069f336,c938b639,d6a74e8c,672a7d2a,2fe1dd1a,d7e18969,e7e57b20) +,S(517d4da9,e25f9eaf,7ab6efcd,cc00e6eb,7bfb975d,e8287b2b,d7d15914,4b7a981a,2ea7196b,a14b60c0,78444a20,2b67fedf,8fd119a3,7a39738b,17694cd4,c0dd712d) +,S(eac89275,54b0f71c,4ee80260,4945c5e5,578fdd50,ad68c478,2295670a,80432bee,dfe1ac53,dc9e18b7,1a930e73,cea36af2,8c8326eb,3615f858,fa1d3884,446f59a7) +,S(f77a0877,e7ffd2e2,cba9f0b2,c419e886,73711125,7cee4480,f6529851,6013ce29,fb245db7,29acfa2c,145011f4,42c9d480,5fcb0be8,b7f27dd9,9d532f6,aee2d57c) +,S(747d96af,94b3ae3,4cbcec25,fe8f4b74,e8d2077e,31ca2520,6d0d5613,3a49bd7e,b13d780b,8d322848,de5463af,3dc9c6fb,4cee70e0,da4731db,14916252,4b6d8d4f) +,S(9bf6ae06,6db68c50,4ef9b1cd,6d123efe,1d8608c5,3a1a2276,f1f44493,f8b5bf72,5b0080f7,694a756,f306714,aa9d8b3e,617b7c5e,84d862be,470df13d,e79c8994) +,S(91d0275d,e99c876b,d6de2cd,481fd72,13d9f6f0,e41c3444,4790dd80,cbc72e72,b12126c0,8b03b040,60183216,d1468246,d32d834c,57e687a8,9ce42ae4,d4eba7bf) +,S(e3cd4480,6585252c,8eb09442,74222016,5ed4cb90,462310ac,ddc769b1,b9a111e2,d8821a94,f1bd3def,434557ed,4739d625,c74548d1,44bd370b,180fc4d9,ee04afa0) +,S(3502269d,e8a68ef1,a0d74a0e,1423de94,99b84d3a,1fbef636,d9f38801,ed00d64a,9c4b6259,8c1bb627,449800ba,d9e93c7a,265114eb,99f9b5,7bca5b6a,72e3b302) +,S(244e51da,a54a3c4d,69f7a53e,6ef82bf4,7907bb40,7713f5e8,84694641,1daa2ec3,61f00ad5,f30928ca,a20cd38e,5af6b3fa,afd4def2,f8433609,4f08e82e,d46a0320) +,S(4f00186b,5d6f0420,88ac1221,a13e3aa4,60190cc2,2bd8fc26,4df81f44,1e508032,fcf58149,b8ab94c,67b30d73,4a3a5835,c7f89e44,6aa8d2d9,291c5f6c,b17b2e3c) +,S(10a96b69,2f522f4d,58d1c9af,463ae371,73e6f72d,93aaf756,6267b3d2,f62a579c,fcc7a656,c9d72dcc,1540a638,51328135,85d3a0f4,ba5242f,f5aa35f1,88ee3070) +,S(ee66c2c,2b19242f,4d7a22bd,df36fe3b,b5c151f7,1dd8a81,93fbae52,23064f9d,9d4f46db,7639d9a6,95d51d1e,44b08d6b,4791e443,744042e5,cc9e3933,cc27aefc) +,S(872337c4,e34a3dbb,f4b274a0,a47c1398,f78ce842,fb11b994,b550e9e2,e21934c2,aa8a7840,d6dbf62e,d91577c8,8b8c6baa,69e01f94,5294e3fe,4ccbadc4,c1d64221) +,S(e2eeb213,bfeb413a,9093be1a,7f75820e,5f48dc34,8515ef1c,7026c116,9be224a6,a49c846e,9132e039,9d66da39,57cebf1d,2e673831,3a89f682,c28d2230,1792d36b) +,S(fe264a9d,63932bdd,5cd4629a,dda37c9a,8d2bbb1f,5809d333,80a561a9,66af74c5,543b7920,c6c27b7a,515b5adc,b8d144ae,64118447,dee21638,1d6cfd2,5627fc53) +,S(13806a30,2d32152f,a1ee8060,67b07cc8,fce1e67f,16f21859,e7b60de1,37debf51,ffcb1150,7be5c2a8,90237923,5335b575,4cd83460,423ece53,18be988,c7e5e978) +,S(db67e361,f9d91cff,1d8b99db,b7bd2584,f1b91cfd,77473802,f603ee9d,debf4dfe,6407a133,7604fbb9,35fbdfb,9fd6e2a4,ea6d8f28,a63e7524,172cebfb,d3331e2b) +,S(606d4f47,d1d4cc58,3e30f214,e1ee57cd,98e68b6c,91c852ad,cad6c32c,989d8bd8,81911891,8a074dd6,ebfb95b1,c97b4fd8,5ef0887c,15ae5e88,ec6e97b9,cba46701) +,S(51d60942,e93fbcf7,e230c116,77528c0d,3b63f7ee,64c1da65,692aa91c,af482ecc,b82db22e,3f104807,6338369f,d77dc11,d982296d,e630af66,36cedecc,108ae433) +,S(2553006b,b8474473,29108ffd,cfd9c91d,22b7ad2b,6a0e7bb,72f98a0b,770da376,6173583e,e6b238be,ff3cd6cc,9bba1b48,d89dcf6f,481868dc,773eea98,59ffa871) +,S(52e35836,fb0a1c1f,efb092fe,3c95bb32,26bf9aaf,50fd1ddf,29ef0ba4,b100d794,639078d1,cd1cd22d,135ca950,d754d3f2,bcd11a95,91abb6c7,c4a5177c,53adc86f) +,S(332e02e5,5c089c84,82ee9863,a4dff4ea,b01a7a83,4747ff83,512fb567,7a8ee3d,b1edbfc7,9c1f9264,10c4cc3b,8919b4f4,e89bad8f,34135af5,f16b1c66,9a28b87c) +,S(d9113a61,7d5a4a75,2080931a,84bad37b,ce2f907b,cc05adf4,16750e8b,8951435a,ab1f66e5,8d3a5887,2f664b56,6c2468df,f9d4d76c,a73111bf,57e10d1a,f7df7aab) +,S(71999a85,799030fa,b0575523,fab4111c,f4b60351,e03f8703,1f5a852a,f22131d4,eb171070,d6124255,9adbd82,565c8dd3,fba6b8c0,df939501,4223b2e6,148668f4) +,S(a9436d74,a39c7193,368ccbf0,d24098be,41309668,87ebb8d8,4213e0b3,436c23cd,7b93ba5d,e2ad9b42,ac45ac85,43f7ae59,7300e745,8fed1359,bc392015,540e7a19) +,S(f6288f25,57359179,cd3659c6,1cceef6d,c5a69631,174f63ac,115633ef,83530b2a,d54f0f2d,51a365dc,7ba8b630,67ae663c,b4102e2c,59cfa616,b8878483,6ca85722) +,S(bf685c41,863c9fee,dff2fdd4,ba47d726,1f0fcb6f,b0432a8a,3b7c4f6d,6f52700a,336b1d57,43ca6d28,52e20cd6,ab276441,61b2ed82,ea4e0051,d88ea92c,a66828c7) +,S(672eaa18,1009f3da,3fe74eb7,4b479e24,4b73b54f,206f7342,eaa865ee,f945b00f,3f056594,a113cd63,810adf1d,b76efaad,babcd42d,347282c2,ce66ad54,37cb89d0) +,S(299deede,3b6722e4,4c5e7600,214f85aa,4dd70ac9,df75cfe6,c020ec58,c8c859f7,92ecac9e,4a6326a7,8b01c0e3,6466723a,3d00593b,6597b6e,e16924cd,60105137) +,S(e4268a68,7e6c26b9,2cec18b6,8581bf03,8b25544e,2040d505,7b9823b8,b01c07d5,35d1c370,95a9cc03,f91db5d4,250a904f,b9f9daed,9388b5cf,d6a3699e,b03c30c0) +,S(7164e9,bfa6ade,a42bcc27,db38cf5b,fe908499,eda21bf2,27063fb6,369b1ae1,a2367f94,fe683e07,1cb7ffb4,287cce88,b11336ca,98e6769e,178262a6,b9103d9b) +,S(84d8d32,a4be7402,1c94d3b6,c0913724,b2db26fd,862fee1b,c467a37f,b98b299a,46b92145,46603cb9,1cd5ff05,a237079a,e290b496,19d868f2,8143d660,94e61cf5) +,S(60372ba5,d0eaaacb,c1445979,74a0553a,6e63c4d,15001b76,39f5d05b,84f626dc,8fab368b,c4d011aa,edf7d98c,2e6a0359,5737b1bd,bf701060,d30c9f0e,a8e8c847) +,S(453c17f5,5364f812,a7da0f75,d7c074b1,81cc0901,a938447c,df55ba92,a7decfbc,53d465f2,6d3d86b,a76ad1e6,f147d208,474989a4,64ceb6ce,79972cc9,3e2e2c3a) +,S(cf1f79b4,b765a894,2b967271,85d0c2c4,dfab4c4d,d679693a,4b35b343,c411cdc4,b89916ea,4ea34abc,63b9292f,591b5c8d,5ce802df,9d4f2be,275ef244,7e1ece) +,S(74b07994,b7fe3a27,eff2f9aa,72f8746a,299f9eb7,81f09b15,f3ae595f,a0c4ac37,5464345,f4873a6e,9f4cb569,acc8e551,a9acff9e,5e0a92ca,e2c3f800,1888f905) +,S(f9de1544,89b7a06e,40115de1,fcb7897a,f6bb2b91,5a1e8971,8d5d5ee8,68bab74f,789b5c55,2b352db3,4345ca30,328f542b,ad22e5cf,d98e5b8b,e85646e8,d47a0e6e) +,S(c011f3d1,897cfe72,827d2cc7,c04a6aa7,496273ac,11f0df10,27ab4d69,aa745c5d,8e31fcd8,3842ffbb,a600e771,feb0cc2b,1fb257ab,7c19fe61,67802313,cdec95ad) +,S(16567ed2,4ea1cb2a,15418d66,c70c0587,386201f3,4dde86b,82f687f,95229648,fc4aa805,45366f8c,3ee336f4,51397e3,7f78188e,b6dff3ce,d80c7e7b,6d9f7cf2) +,S(8cd33d56,9acd3607,979b3c17,bf5c2175,ef6f3428,7a25c18e,89a1b38c,979d50e,f4312cbf,f301e942,61b7da0e,cadda424,336b1201,82ad73c3,c907be8d,840f8614) +,S(646e22ba,39927176,4e1df1b3,16767718,79d7a16d,587b9e47,5232a331,42ea2a5b,55378afe,5f29feb3,2a3152ba,4d83305e,f77b1025,79154aeb,7bb8b8ef,c5958576) +,S(2699d984,462e1fa6,208a833b,8af2e32f,58cf2d02,7707b4fe,2e3f888d,82e8e2fc,ed6c46a5,c5121755,5f236a62,21399a40,5fd87fca,f4cc6603,fffb440d,54b888c4) +,S(be4b6631,3fd3e2fb,163530c7,2fa4a41b,e36d04b2,638315a9,1d07de72,c4ced54c,a7a71077,83a27b72,4e8aa644,a88ea181,c770cf6f,489829c6,6660c44d,45fd2ddd) +,S(1f2ad69d,a1438b51,fe02a47,9cf865e2,18bdbe01,259b0818,1b6e7e6b,762a72a6,d4da99d5,7aa328df,3c587a45,2d756bae,fc09c626,fa5516bb,c8781b9e,b1ecd29b) +,S(b1adb241,721a1622,35540622,f8e84291,e1c2702d,70cad33a,89aa3806,f7acda43,e6cd9324,12542fc4,25b8f16c,c0820f3f,26f33e11,1ba0ca5c,b5aeaa54,1fa3d9c6) +,S(b604e2,f06df266,1163604f,2a1941ff,4d6991fb,84796c40,ccbe74e4,cf68e207,306936ee,e887427e,6005b265,38af5ca,53b3cab9,a3aebaaa,96556c46,7db96e88) +,S(afb935fa,1e30617a,9b4f26b2,e7b150b3,f33566b4,7b5b4a7d,6223fe3,9c0dced3,83624f43,66dd82d6,8e4cd94c,464b6322,db0b1774,9fa1125b,a0944503,b0c63b0d) +,S(5cc7252,a08ff892,93022eca,b56a5e9,cd2eb4c4,71161d15,5d7a5113,8b12d235,c272b6cc,42461529,b31943fd,fcb51a59,7a0eaec3,ae8c2754,827fe1ce,a182bcc4) +,S(6c17c206,7c72a1ba,410f2446,e4ae2012,6eccaf88,aa4fea14,522a7607,143c1122,7172af08,2adea428,2f6a3cbc,7946db2f,c0170975,50ad8ee7,f4c514e5,dcd693eb) +,S(fd82afcf,c55d226b,274cd62f,385e882f,716210f,9a14be15,baf7e17f,b98eac8,4aeac666,a1153851,6d66390e,6c7818d3,3de26fa9,3d234eb8,5e4d5b42,853eb3c1) +,S(3d0121e6,c758dc91,8ce3bbca,1884788b,20717075,1e80742c,49b202d3,c2f8012,ca6b47b,306cef6c,662bf21f,77bae3c4,25009561,72dfc630,e2b1a6da,e733413d) +,S(488306dd,3bf3bb5f,24160f1d,67b8c053,bceb8da3,cb1b05ae,7ae9fa72,e3f7b0c2,2356a8e6,77ae2f06,6135bd88,1fab5b4c,6aa57769,3e2d476a,1b2a4db7,fc6c27be) +,S(d7e91488,6786009e,eaf12d14,a23ec6e7,fe41e406,aca5a5b7,47010ee8,8441d6b2,c98389a9,143a8fdb,df4a67d8,7c05cd4d,fff75fae,845e7e62,26c61aff,3dc4dde6) +,S(873a2877,9c45280e,3d196725,5da756d0,ee5ac567,cbb7c52d,c8e654a7,ed78a1f1,9bb9672e,e76feae0,d52be301,983c182d,ec99b228,defb2166,5310a4ab,cae7eccd) +,S(410a7c98,85f531ab,46d99b26,b6fc2576,97723e4,bd9b9c57,6544542e,2cad2ff3,8bc9e686,4f139032,cd443148,4f43abd4,3234e3eb,3825a0a7,db8176be,cb5207cb) +,S(39269060,b38b4abb,107c2230,6f541353,d8627901,3399b368,8b650ad4,cbf99144,780c2949,aad303f,ef8fff3f,b9734551,b45639cd,9437935f,d93f7d95,bc9d1aa4) +,S(bbc52d26,36e861e1,3e593d4a,c6ad573a,e4698ede,f101b3e4,f4aaca54,325b9f9,4a311f44,9f16bfb6,4c5c554,5ba373e9,fc41b7ec,beadb4a6,a929cf0d,79f37922) +,S(bb74e659,5ed6d931,9716b8e6,120f0cb0,57dcce87,150cb26a,cbdf5b1c,f86ccbcd,9f2385a3,bb460cdb,8ec74db8,fc5e6014,f4310665,c5b69e1b,cf96203,1afe085) +,S(67e64d65,badbd97a,bb204cb4,f9009f5a,973700d8,34f6b6a5,395fbaa2,c6eb0672,a122f76f,67490b28,9977d730,df544f7,d725dfd0,93135ba4,4bb348c9,e4dd3303) +,S(dbd294ba,e0775f43,f58ee677,6240eaca,b9b29ceb,92fc3354,de4d4b20,95548050,1987ba2e,3ce8ef0,5b71acbf,4c69f706,e2cb4d6f,354f0fc6,53a7a9b9,5dd1c115) +,S(45c946f3,93658d3e,589fdcbb,6895c97d,60352342,3a3676df,680b6bad,de6cee1,629c7238,db2cd3e5,29e5b30f,a8ba5629,dcbb1ccd,ada1eb22,294f98f0,4cae2d00) +,S(33ad0e14,44be7775,3fe47875,2688e384,2be7ae06,7d38e473,6b7dbe0,c106e14f,d89eed78,6518775e,1ef441d5,fe51c4d4,b2a1e377,eb1a4cf7,804c2e1a,5175f1ef) +,S(f9f78161,4cd463fb,6e358274,e47812b,4b0113d8,3f426aa7,85756c6f,b9e7853e,5eab09ab,51247c76,f87f592d,77e0870,238877dc,a47cf6b4,5fe72940,ff4469a2) +,S(ed3015a6,7a1fec82,f0f7a59c,45cb69ae,8aa0d883,39a05f,f6959c9d,b7d761c5,b7c94a9c,28389f1d,17bdf197,307411fe,1c395483,da8a097a,fb3b5fcf,e392e16d) +,S(301af330,de741ec5,61b71fc3,c5048a42,6b55d58f,800934f5,c59aa8f5,914092b0,3d3137d8,262d196d,872fe1f9,8acba295,fec02ee1,30aa4c19,8c888765,357b67e4) +,S(21e197a7,85953a90,226c1ab0,441e35a0,fd8444b1,92c0e5ad,65588063,f40c1246,6811f94f,18a9569d,4df2ffa7,fd8d75ff,5f66ad1e,62da2a60,c0084381,4437a2c4) +,S(325fcc8c,27804b7c,e73d6687,70db7f5d,3ed4b6ac,feb04003,c61d6262,8fd41385,2110e8d7,24e3a03f,46183536,b208b595,8586202c,2e69b954,d3ee1500,21ae7d8) +,S(48597aad,ec69eb0d,90f60e6a,abf83129,1de759f5,eff24d81,8677248b,ea87d945,c3fd850a,cddc2597,499be90c,24e249b,328728ff,5443fbd5,6515a6f0,4111775d) +,S(58648599,8ac44bd2,e937796,d8dfa60d,c56d94c4,d53cfb77,ee0e380a,53ab8f76,2f47f278,6a285454,475d3c9,ffe9ee44,a93e15cb,b17772ec,67a30943,d3191110) +,S(bd2761c5,722288b1,409aa7a5,db7690d2,73dba76a,3847d94e,3e3d3a7f,2dd35597,42590713,6ab6745d,5e573412,663d4d93,29c4a284,4430899d,68e5ca64,197ad58c) +,S(fac9260f,1d420371,7e468769,1af8c270,dada5d97,5ceda9f2,64deffe9,1990b52a,9ce17c1,ebe94ab4,e092d1d5,850194d1,7e6a87e6,7b283ba4,ba68640a,94193314) +,S(82e65b52,e4585ec1,4bc03591,249cf4bc,e5391f69,7b813175,b3b4b403,a64d6877,627e196b,42d327be,48526318,2dafb37e,222578a0,ccbcc443,7941eca4,a82ac893) +,S(b9473eb4,dd002597,464965e5,b6d95842,543cd14,e18c95d5,b45bb654,eedbd6da,1b6e80a5,377ba31f,b5b6fcac,633321e7,f6e5b2ad,4a54e143,e963effd,6805c3a9) +,S(31113d99,4caaea40,40182db0,17a880ac,64b183af,1746b820,2f29fbd0,d1bcc524,3f476b72,eeeb7c27,f9d04cba,71ac54aa,a25ec4ab,15d77e17,8544a651,653e83ad) +,S(d04adc5e,73e21fc1,8c3b047,4d34f8cd,1cdcebdc,5dabf14,e258af57,860157d2,b21150d6,ad94a07c,d11a81c7,b741a2f0,5cd6a5ae,aba194ce,b874bd19,bfb6c326) +,S(4e59356b,f280f51a,c492751b,3b3c7c2e,3fd1fb58,679b4fb5,5abeeb65,bce6ac2b,33a1ed9a,1d9c34c8,42b95e4a,108c7985,21c1f06,91f3716a,68fa5c5f,89dc73f) +,S(53d76685,9ddc778c,b4f719ad,55f74fa7,85d52300,65c06b1e,4aafc560,39ba3547,168b5451,29170fe2,c53abea9,68a25dcc,2719090b,e0814635,a1dc7267,9d83a01) +,S(7e9107a0,d2830362,7e53e06d,6e82efa8,b1a037a,328df546,a6d04c30,3037a63f,222d8b81,2a99860e,87fa24e0,aaab4ddb,b903cbe6,39c46cb6,3f2144d7,f8856489) +,S(6775b2d7,b23dc08a,beb65049,db8552f5,565a092f,fad86865,c17347e2,a744106b,a6f23c87,fb639e66,9830ed33,34c6dd42,6bab0e23,aadcff44,1d4c73d1,a61efda4) +,S(559885b6,a54fd0dc,b275662e,f66566e2,87a17219,e9c02f68,8c1cc8f5,6f814673,2ec87df5,917d1d7b,f217621e,82c31844,d2bb138b,bc35f873,5b52309a,baf800c1) +,S(6fb774c1,2971b620,b40a17ec,74dccc9a,8c711844,a44a3e4d,e8310d47,bda53428,68ab0f6,57b823e3,35df55d1,ed9632a8,f0825f67,8a05d5eb,9e115ea3,e43ff4e7) +,S(623c155c,2787396e,815ecfdb,5f03bdb7,282aeda1,7c9298f5,306ec10e,21dd0b90,69382be3,a4bae926,47252910,ad1ec62f,f4bbcde5,6259cb52,10ff2158,6b111f66) +,S(c42c41e0,63db66dc,9b32c21c,af94a158,14fd5b62,aaa975d,3ca06925,f6d6ecc2,e93159a3,ad6fbcb6,38f7b09d,40601189,cafbe5c5,90c70103,b56fbd47,d36ccfba) +,S(1103e98e,7a1659ac,4242ad9d,6fb012d9,21696e58,413f71aa,e19fff6f,1c334fbf,9f2d4667,ce5a1285,524d91d9,265d7a5d,da9f5ea6,cd508cf5,90076d57,a975bc62) +,S(9e113cd5,9e7177b9,19859144,598263cd,630f72f3,4da00ad9,84964043,9d82878a,6a09bef7,6e13f2f6,8e70ee90,5dd5af4,495f5965,859a1d83,ef149f67,2643c9f7) +,S(c03c5ebc,d04bf8a2,bdec182b,32d8c726,1913652f,e4547892,3e0dba7a,1fe275ed,f567e3c7,4b9313c4,11ac9411,11f1b62f,74a16f79,e7d90817,b54d4d89,958cda21) +,S(205c4c44,7b84661b,cc8ab2f0,221343f4,140c9efa,fb107c59,b5095b48,25f54b24,94a10344,ac5f48a3,600309ef,8ef94242,a8050865,3c018e57,a7734d9e,da18a55c) +,S(e393821a,58c9e9c5,6e45cda0,334bebc4,359c4b3c,1a60bab3,f1dce2de,c1da81b6,5469cb0f,4edf5f47,80df616,3a6b7074,7b26291e,8830d113,79d84aa2,15814e6d) +,S(38fc36b7,a866b165,a424f0ae,74ca34bb,b05922d5,1bdb447,5df797ad,4d042e2f,a9279b50,4b3edff3,aa8fe039,3415c21a,556609bd,8089383f,f5dbdd34,291c2b1b) +,S(1c4a1aac,3c3247d9,99a75a00,305a4092,c5f34321,d3a33b66,b110331c,85be2b27,a10e4138,a835e3b1,16d7b6c9,46c752e8,dc92c39b,21677968,147a3cab,fa5a0f1) +,S(41d70c82,207c3b7b,716a2d4f,784302e7,e1034555,a79965b7,d951ebac,b7d62c00,7311a36f,cf3de546,37013e84,b2162c35,3eba0387,3d296427,220e5942,af398bac) +,S(bada1cce,dcf3dfc,9834c49d,200fb82a,b13cf2d3,d5da9ee5,c9c35448,352e660a,42e0d3db,511cbbe7,942ff10d,a7d49805,972d9373,a75545b7,206e490b,6c5dc651) +,S(233c0c68,4b9fe726,baf2b7d7,a0503e,7aba8b1b,3c4f28d9,4d095107,2b429bc2,a7bc02a6,2b81154,c3bce0f1,6a0b4f77,d412d162,1c713372,11ac1c61,a8f6fa28) +,S(a675f208,a0d48078,93525e1f,b6c5be3b,ef24ade,8d3ab14a,afac550a,fa6362cd,3f8edef0,3e0600fd,1fdf10e7,c5562ddb,af4266a1,52bfca59,e1235d7,c9e8223b) +,S(4adffdf7,a8a92b65,6f747fe2,92e6bfd2,cd3deb68,ccfd7f01,5639d779,7d21e48c,4d4079af,a6e89720,3a50015,92e43c6e,97fa1e57,11f21bef,c9df4274,441f7d81) +,S(c786e96d,fa658a6f,a9f1fbfb,a15d7021,835ebbb4,3e8ed3a2,c7ea573,c2944dba,81130470,7a10b1e8,74f5b856,b7223346,eef3c562,8959454b,d536494a,f075393f) +,S(10df82c4,64b75895,2c54f335,6fc24ace,cda4578f,d34ae82a,8a1eb2e3,d0830349,dae5c271,86031dd9,2eff2db9,6af91689,2a131cb2,44534495,c3562cb8,dbc5e1b0) +,S(55532c4c,c4483aac,26b049d7,df1da7e1,ef281c7d,bd99d21b,72626443,f2c748c4,58160e32,da446337,d0642596,c17500f7,b0e64081,1017bc1f,4452c4a6,8d2c2789) +,S(fe994c5,d63149e0,d31f6cdb,fce5b941,239c4adf,8d5e6866,37990411,d88ead47,200532b8,4ee2fb18,b2c27cd5,9c3940f3,58c6a2c1,d96ad043,4d826c8c,2a457dce) +,S(c7690e5b,3148cd96,592e654f,2eed33ec,a69d2684,545cbadc,6f6a7e8b,4d3cfbdd,98e0018c,36423854,6dede771,b78bc4b8,c52d956,d26eb22a,e447ab3a,144cd394) +,S(8f1f0986,d273476f,b31d4ddc,de949584,97ec74c9,acc6b0eb,900e4cc,2c98cac3,31f420f4,b9209657,1656b663,a06804fb,78597071,6c138106,119ef214,43aa765b) +,S(bee7ab1c,c23f6101,be01ed60,574ffca,70fbd4db,ae73e5c7,128da065,9f78c042,9187835b,66b2b634,a87d1baa,7666bda3,57dd5ed,26871976,8e0ea9a6,ed102dfc) +,S(8093581b,3205e5c1,90e9d38b,5b5ac422,b48fb5a3,9176bf7a,e1d377,c764f74b,3a3e06f3,4c00cf7f,6216e67f,2d55236d,db54640f,192897e9,fd68820c,bf22ce39) +,S(fc018da2,70dfe007,871e0be7,f5edfb7c,30fc30bd,bed5052c,78a7701b,50954702,9483d20d,af9fb123,723e0c17,7905e94f,462831c7,dceb0238,6f0942e5,188f3a90) +,S(f4ca4cab,7f06af06,d0a8bd7,97d6eed1,7354420d,65d80e09,32f6eaf1,ca12a39c,76770553,69f93094,3f368b0f,2ef6e412,f3d5a45d,1c7edc3d,9550fdd4,ebb1950) +,S(fb03fae2,87265749,787de276,84bfdab0,4993112d,f384113f,1dd41e6a,b438bdf3,ae8829f6,80f60534,50113930,2aba238b,1dc295bc,6598c060,af8393b5,1153b479) +,S(b76268c2,6b873f54,9438a569,5e2d5e24,a92da29a,ca26f18e,143e3290,69638a45,bb4543e,23abdead,c3377320,dd8ffb6a,d38967ac,ea90afd3,23c69373,eeb2407a) +,S(87db8064,9a5a31a6,487893d,f487c00b,143c09c8,fe878621,b592b25a,6c3d8646,872a4547,520d307b,a537d42a,ffbc8e9c,e04d1c80,e3d4f506,b001b0f4,79e92972) +,S(fb9295d5,a7c2cda9,c08b0f39,1fcdea4d,b768b086,dd170d8a,966516fa,bd476acf,62496929,a85c828c,cda71d2a,ae70c429,7bc12f03,5a99ff75,7d66cedd,5fb5135c) +,S(96f749ed,a1fc306,6d133829,774293e0,b179a598,327c3bde,a2e94200,770d12ba,c16915b8,af011de7,614fda0,ce1c4a3,ffeabc2e,2e891e4c,a2d9c277,247fc8c1) +,S(1564d7b9,77b4eb29,e7b23ba7,a3cf453a,8eaadc50,87448fb0,fd9310ec,653ec66d,6d8935ef,a7d41cb7,5c5dad07,c3ca864d,89e49f0,f74d4474,af85bf05,c408009f) +,S(93db7b68,9ed6ad1d,bb61223c,dcca7280,9cf4a49a,14d94f3c,7cae77c8,f1298340,9088165,7b4979f7,26b156c9,d34430db,4a0af993,eeb996c,d091ad5c,4f7bbaff) +,S(2656af7e,d8a2e718,9849cd,793baf93,1c23374a,a3b5596,d8c88841,2b6a5ad9,dca0f4b2,7c7f1547,97346dfc,589374d6,1224048b,ead5442c,9f8950f1,63689045) +,S(a7dc8558,c0adf996,b7f57c08,1b509e34,7819131d,42647498,ba819c12,6d26cbf7,9fc494c9,2bbf6116,14527eaa,1de4708a,f0c19847,3ee9164b,6b9de909,f6a4497d) +,S(1f6d4701,effe09fa,17ecc014,a7a0033c,143fbfac,ba4861cd,d7ee2fe8,5bcb2cda,84c5b017,81ce481a,e610bd8d,96ffa58b,b7a158e9,d1cccd79,7e6436dd,b1308de6) +,S(eefe37c5,d547b779,d905849e,dd1038b,f054233b,f2d1af47,1684e5c2,a1e69960,b5f00dee,8b1f7960,aa068db6,78b6b41a,f8c3e14b,27c1f43e,10f9b34c,fe8eefef) +,S(8d4e8462,60602ee0,948ba5c9,f0506046,d0bf3fd5,e1b93073,bcc8a6b3,30af96d0,62d0e36b,bdffa309,f1257b23,6327506,5a5e7999,b314dbed,edc75800,b35534ba) +,S(da22079d,352d3527,5a80b95f,80b7b8b1,3eb6d178,310b6889,a94cbf2b,9a9a898,e8b06b65,37aae428,cd25fae,d0c1af8b,827b296,886de122,c6690a19,fe94df72) +,S(beb411ff,67cdbb5e,58da6353,172813fe,e386c7,95550395,1ddc23e5,d4e579a4,919f8f30,41f53020,4d3620bc,b0bc80e5,9d87ab73,355c046d,cf2986d3,c9995866) +,S(b0a5732b,76b4a526,e8e742e3,528891c7,3a1febb5,c7657a90,4bc1f95b,96d462b6,a5e4f134,93f9e24,75ac7dab,479092cd,fb59a931,dd042add,3d875e22,76965a9e) +,S(5a87a782,13130193,4ce6180b,714e99c7,30fc8bd4,fd4e8c59,f5b6aae2,f3622561,a929d120,68a64953,90c559f1,ed8ff0d9,bef92431,66117208,d0e8a08a,de9a3d0b) +,S(777ba7aa,6c50e927,64ed93ac,daf56285,9909b031,7c3c5ab9,38ebba26,d62a1748,27a32172,d7ff61ea,b6a26d00,c252f99d,bcf614af,1434641d,cdbd5f4,10e6657e) +,S(ad0f9f5c,8fa07d5d,3c18d4a5,7dc16bc6,3be0dac5,9166fb42,6bfca8f0,65b76720,d2c9c778,3caf2c93,f6c3980e,60ec0fcc,1f1d5ffc,8aff6af,a912b5b4,245fff6e) +,S(8904706f,17aad850,7a71f0c0,94f981e0,5e5a42d9,7f5cc3ed,99b4f635,660e227b,371d5f58,a63ec71b,3cd8b601,ee622586,2822a2c3,99ac70f4,ce293846,23ad8198) +,S(ce32a220,2e276dd,3f5b0a10,38a70f21,3c29ba7,58934c4e,27ee3bc3,c9dadf00,e43d28,80486b34,65e545d7,6618d80c,56874afd,29ea4ee1,e79dbe5b,b1ec1f42) +,S(3d031c0,c717447e,19266420,cef08d59,ac2aed4,7e84c84f,8980e8ed,ee59c7c1,86eabd82,d6a5f57e,cdb52825,a8c726d5,4a9faba3,6272441b,22627c4,a321d970) +,S(9dc08947,fa3983dd,44730aee,d8e94f2c,78eefc44,df126804,281f740,53330b43,58838246,3fc02261,c0e771b9,3d4a90cc,c2c19f7,2893ffb,22fe6d5c,6c5e7318) +,S(f9fb51c7,29646acf,94ecadf7,30989d5e,669ca4fb,3b4dfe66,dad9838a,f239057e,d4a04a8f,f44b86c3,17ce4350,1a2325cd,46b5decf,5f4e14e7,17ef0c30,1241f8e7) +,S(d4a1c33e,816419c1,884c2838,abc7148,c61f05d3,71fe3de8,9f06b580,cc5e1006,28d8f049,a1daec88,5d186da2,66e2b8a2,893d90c8,5e720d03,a53cf8bb,f8a10208) +,S(1b1c6ab,74436126,203ffd8d,8e9c58b3,e18f2767,3a72bfb4,ae4c9e25,ce17c570,ad28aaa5,eaf7128,fc8788e5,b9c1c13b,a4cf16e9,f651da6b,6c43fd1c,cf2903dd) +,S(3d791154,b2c062fb,e1f6ad1,dcc17bd6,b648aadf,cd573cb7,d29f9e47,e089e1c3,a578f2d,a568b0b,e95e1189,7bad8311,3098787d,62756c99,7dc3d795,8e0d3745) +,S(6daac2f7,ee7b01f7,277b3a5a,44785b4b,c6b6adf9,b112dd6a,227b2b46,9f27940a,fe9504e5,75c1e349,9267624f,2b2e603,55befd7e,d66d7fe6,80c521b5,e0d1aaab) +,S(ea6343d7,73a5966c,2ea66806,ed59079e,8b216a9f,4fcbe8f6,744808b3,2478c26f,15ab94e5,cc1f4a5a,33955f6,b30571e2,5104c615,c0aef2bb,6a8f6693,64639f6f) +,S(ffc78cf2,4b436203,dcc1b892,c77fb336,463a8070,332783c6,1824acb3,f5cc55c,7bfe0b6d,666b28c2,3259c4f9,2c0dd94b,fcf53921,91d617df,da1c651a,1fcb81a3) +,S(db38103d,5156c309,67189677,9317879a,f31dcfa6,b8d0f5d9,1f2bc691,6090e6b0,b5b3e45d,9bd41082,cd3115ff,824ff027,78f47a0b,d0ae71fb,32c48d72,cd540c84) +,S(4c08de87,abf89885,2791b455,126e7e54,d660903,f407b842,7b4fcd70,53e0b000,a9f83c6f,dcea99fb,fcb301dd,c31146c8,25c02978,6e5019e8,7b1b6db0,731b9189) +,S(53b6a23b,8f93200c,41bf45b2,bd0d20a5,e6fa5db9,a3686a7c,c669815b,993604c5,31bbf5d2,21023fc2,fef75f0a,f7bc33e,b4d38323,cbdaa511,c40ed497,ef42a850) +,S(b39ebc0e,53b74f35,6f573a40,1df6f8d6,fe1e4fed,f7d976e9,949da398,a45b464e,9d58ae16,a633ea0e,86bad1de,39f0b203,c1ef0b24,b5f1d824,48fc606c,a97fdff1) +,S(182e4920,f4a60741,a0b94fc3,e3ff0bef,39f1d459,cd6c18fb,16b072b8,de0bd416,6d048d0e,ffdf4e60,8097cde5,46955541,491721a3,d6e051ef,9279c5c0,22a32fb6) +,S(7a39e7e0,a2da209d,8cbb9797,5f12acce,840dddfc,5acf7c5f,fe778a11,829e1003,c24aa083,20e6a786,1c161e14,f37b1c7a,65117e55,2c252445,20b47b67,66fb410) +,S(62e6173f,2273d3ff,d9fb640b,87d5cb15,e5df841e,3462bc5f,6b94575d,a110914e,7c424010,4ba37e57,48404997,689a01cb,851343f1,ea8259fc,938483dd,d70ac5d4) +,S(3960d4cd,96de0126,5c2cc88,68e94d66,40e9ac8a,f2abfcd5,2108848c,ad62467,fb24aaf2,85a54405,f75db03a,464bbc29,3bcaaa44,344c763f,dd44656,fa7faeed) +,S(463437ab,42694ce9,98ac17cb,fd4d9034,ab7a1be0,35f911e2,864441a3,eff8e3e3,370056b1,24b894d6,3631087b,194dc5ca,fcd2475c,a95402b8,418f1954,d47599e8) +,S(65774018,fd428788,e4234b36,42c8a354,770ddafa,c38040e9,49f194c0,ff7ad3a4,462ec7,cb17abb6,5200a88a,9874c7f9,40469a51,c48c1fdd,6c0938ad,67741467) +,S(738feb40,e7f16fc3,19ed6649,2507406e,6501308e,5112dff4,db9d12d3,bc0f138a,4923678b,84470212,cc5472de,2163ac3c,51ed5419,dc1b1b1e,78dc0946,f730b940) +,S(546841d9,7985d80b,a0eb3448,3dc5d17c,441b7eb5,d24b6216,ab98b14a,d320cf36,719434a4,952ee43a,b1006ce6,f7785734,c6a5c018,383eed75,e3660f7,94eb6829) +,S(31143de9,1a4b96eb,be7efe31,56b6688,5d39ce66,fa8ce202,57626dc2,8557ece4,d8d8bd18,36e5c388,2273143e,721bef10,b0c3005a,5e2fd3a7,e471ae33,ebfae7be) +,S(ad8076d9,29feddae,a52c009,f3967726,a0a94301,dfc12d59,da63c47b,df6566fe,39eedd66,13fb7141,796c0353,9f560ac,e23f844f,d0d3d422,5b36e41c,b6707602) +,S(b01a4f7b,9362be2e,78f5cdbf,d9e35f21,4d296a3f,3e233d93,2cf33c71,95b3f613,245b535f,c58254a2,157caa87,38e855ac,fa9b071c,1b6182f3,5260da9d,18e385cb) +,S(50f3458f,a781d513,a944ebd9,6f6b791a,1b0cedec,1421f9a0,16a7f350,2d5f429a,4972c646,c1ad5958,18766bab,5bf54ea9,e9c4fe3,19810f1e,27f46cc9,41594045) +,S(d7b606ed,e8fc3a20,925e0a59,5c9462d9,4e04b5c2,b64d13cc,19a47d1,ccf10b0a,dc39a8dd,d5447a0,f07b5e7a,6ea35286,ec01679d,ffb6eaea,6222711a,d57cc63f) +,S(7629836b,73691a1f,f3ae6c99,7e06f597,34fb9625,2d1ec88f,2af15cac,f89c199d,296e4034,8eacfd71,7f64beb5,76736398,62114296,5fc818a3,ea89ba52,1b1a410e) +,S(88f6a162,7baea31,3a2a5d5d,aeda2f4b,4becca6b,812a60d,4b5b4e22,6c822a1,d3acfe53,d6189ab8,31106ca8,2388fc28,5b567e5a,5172050,5be56bf0,187534eb) +,S(8e93c72f,cfeae58d,fecd373e,dd3f31ab,3e4fa28c,f53681dd,ebf37d40,c376283a,e9c82571,2d0cfc0d,e6f35e77,acf0597a,7e2437e2,80f13420,cbe93acc,52901d71) +,S(b2264df0,eaead63,111d7b05,8767cc7f,36d386c7,edf21792,e8aef135,9958b2bd,242eccda,5e4324a5,40e8d098,cad23ecb,88955bb1,126314fc,5da973ee,b1d83313) +,S(9f1c9e90,7a6813a8,da520f6,84553a4c,aab650a6,7eaf4f0e,f2ec212b,95a885ce,416dae6b,f47aeb47,453fd0f4,7da6375d,136b6ee2,450bfe75,504f3619,84a0f355) +,S(dcc7585,132b95e6,a4a24450,d557a0fc,3ec93506,fd1f5f02,17bd0f7a,6943fa1a,c62ca95e,d976d1e7,2bcad48d,9bc3a316,a35e8496,952a7a07,760ecbc,8903b001) +,S(e3c674b1,eeb380f3,f08b1d64,32f4dddd,77cb602,915ac478,4f3c769b,dc2a30fd,fa8b08f9,8bb4a1b7,568c9d3e,754292b,1a35cede,1b377c99,fcee16ff,a16bbe5e) +,S(1152da70,2b7341ff,69e8d3e,6f5ce8d3,bdcd3a03,27df54bb,846ac8e9,18e747e4,7c139d20,1e2ea5db,984cc8d2,4b66c64,8adbd0c9,48c0b085,d59c73ce,b4d7a91c) +,S(3449cac4,abbd3ae5,e09dbc5,c89258a3,df93ead9,1f62fad3,a5add3f9,87a2f83b,197ecb64,5dc998fe,eb9b0df8,6267c7c3,f7af9647,96fea60d,88d4de89,33171e2a) +,S(ad5cc468,11c5a39d,ffa313f6,578acb00,cdda9ce,b3757479,9f2afd6,a8df7a19,4fdf6093,c8fa8a92,7702982e,7e638948,b982d84f,ae6658bc,fa839354,6d6e76f4) +,S(acad447c,b57e8f5,f528a113,347e5c5a,2097766a,b4664c70,3f496635,759a7799,88e1b4ff,3bf3e967,d2c6c948,4bb727a1,d13231cd,acc45463,d421431a,b6fc46ad) +,S(b74286a7,e2699aee,9802563a,4da514cc,d74fd001,48534822,9214395b,36158246,8df2b491,ea018b23,b1c7fb54,b7a05db,b79b0ebe,1117e2d9,ce73e70d,d097bf90) +,S(86bc560b,19d583b3,62c1634a,139bbd16,db30e823,75913cd6,fb688e4,38ceca4d,2126168,75c3adc6,c2aa16ee,2e028052,9e6612b,fe4b1aee,e4961feb,f530423c) +,S(dd79faa2,e97dd468,5f3ff8b8,d5e55598,73736de3,9493a3f4,4e679516,f51e495a,2cb89020,efaae785,5376d901,4d1bc374,21e0ee60,29ac70c4,65bdcdd1,e240e57d) +,S(caf6318f,825ca3d8,6d45c681,60d897d1,76875e26,bcd36d00,82b4e1ea,e6d8c142,d7abc304,55a5fab2,68c6d17c,3763e586,5b9e266b,bc6211b9,48b5ff3d,19f5df72) +,S(c49dbf15,70c3f0ce,1afd166f,884af550,1f26905d,2f726185,7c026405,efe9a2bd,54eaad70,8bdb7b2a,59f5d69b,5be6ed79,5fbc4137,945be17c,b4736649,6e8cd3c0) +,S(a87447c2,83c88db2,15630cb7,6029132f,47dadd57,5ea6f9bc,10d1b36d,8317a91a,8489d3c3,6334d65,fdf6089b,df19c3e8,7eecd697,516e1756,5fc8b977,be82c363) +,S(7467b357,7d21b028,dab4100b,ebfa734d,36345024,adc60b1,10b8f96b,c7860889,b2978a5d,dea9765f,7877d8ff,fba66c0d,f7c8e0f4,6854deab,21908da2,8572b1a2) +,S(6af133d9,bf2d6b57,ef69e0e7,5eef6d,eeb82d31,af490320,bd26f4eb,38ffd42d,7f4a4d1e,ce23c530,a4d64c23,cf0bf8,a46c59aa,74dce4ac,2854c6bc,d11b056f) +,S(faff2662,5a41c80f,c0889d4,83eaf50c,596aa571,6807b118,1e94ce5b,581b0a7d,32f3d057,4afc487b,43b129af,f83bc7dc,d495402b,90fdc30f,736e87a5,469e8aa7) +,S(8c6983d2,8047ab24,ddb292cf,1c8836af,7e75d7ad,6ce23149,e022cb64,2439ba2f,70a10314,447eaa73,924fdf58,fc607dc1,c69a69aa,29b84dcb,156fec4e,568a5bb9) +,S(bfdda2aa,b23a37b2,bc129bb4,280a2c45,926360c3,2719872c,ae1e81b3,1b3d3d02,e8319769,b7d21199,9e5de1ae,76021c9c,2bf75ed0,4c9a6c2a,c52da4f4,88cf78a5) +,S(80e24bf,3559d05e,c0cf63af,21dd7adf,237c23e7,ed930c7b,4124ad4,46871de8,c8f37f91,4e78e037,602ae9bf,ea3511fd,2c95ad3,6665117d,64f9fbbd,ecd10063) +,S(7f56d940,2d6fb0ed,dc6ce187,2ee8e55f,45db30f9,8defa84d,f7fb76ca,aef5e800,f43b9e6c,b60ce85f,44682fae,d8a48e5,3d9599d4,f19b4757,74f7d6fe,2fb2554f) +,S(437e7a08,900216be,72f14ef7,33127d49,9130309a,73369d2e,58fd4187,a0d428bd,3f0a4c4c,63dc779d,69dea37f,786a5157,43b3560c,16d4e56,4a1d7802,f40dec83) +,S(3bb8db7e,8cb3534e,d7f70f8d,eeb1cb81,3ab21dd0,552c311f,f98f38e3,63321626,9ffd98a4,b3c271e7,83ec8c72,98ba83b3,f4f0a5bb,61ce1edd,5c1095ee,eb16a569) +,S(21de8ce4,6aaebc6b,4ac51620,e2c78904,f9300b6,2930fa79,699e2782,5dc2310f,12a21855,50ceab27,aeb2e7cf,14710b7c,b3dc837a,67a1e4d2,6950e2b8,1942b9c1) +,S(6c24ddca,e4245972,5268369c,545bc910,ffddd8c3,49d83fec,eb27af78,cfc0c965,6263abc6,ed17a124,c8b2c5e5,c91b157a,13512939,b9d60e48,929fe6d8,4d032338) +,S(ddc0dfb0,49f7b6b1,cd1d03c6,f8ed2470,ae320f04,bc6f13f5,a88ba89,7bd1f91b,57c5f0df,8fd22e02,da44cd05,74fbcc1,c8b4a903,a909f906,aef9208a,89eeddd0) +,S(6fc5fdee,78c61421,a3ec2284,583a56d8,f18e66eb,58c54dde,e5209a1f,3e3761eb,baeac905,6101b825,8b08a807,72c977bf,60956b2e,d98d1b25,e71b2b7e,10e3d25e) +,S(1b6735d6,ac2f1db0,1c3781d0,cf42e2cc,3ccbf030,2e3837f1,3f6655eb,ba0dfddc,621e8c0e,cedfd28e,608c3da5,135d63fb,93dc6919,2a6154db,bf63e315,2f7db68e) +,S(1a875a0c,ecae6600,4bbdab3c,4fa5a57f,925079dd,671bd9aa,e8ac5c51,b21a5e83,2317a0c0,81c17bed,a15e1148,f44beb72,d4e65fa4,96408778,8216f85b,3924d9fa) +,S(51635c0c,ce51684d,9631c8ad,f6c9c4a9,3f66dc04,a372c891,294c42ae,2be5a84a,5c6cf3f1,bbc9c21b,124e78cf,ba05b2f9,ffb9c902,3895d584,48622259,635d3517) +,S(c548df8c,b685f457,71c564ed,a3e9a77e,a4734faf,7cef877c,b0bd70ff,d85afe0d,2675d6b8,24f99a19,8825f1ee,19510492,9eb633d0,367c01f7,c922bfb,c2cd6dc2) +,S(121592ee,aa39a310,3c02502d,72e360f,f500853a,7d2e449b,16c5e443,f42e700c,b5cfa2c6,689d973d,e0578a39,bc687720,acc0305d,6ad3b678,1d36941b,7f0cb435) +,S(c2a8b66d,cce99233,b3d83699,b20f0c60,21a83ee1,46a491e6,d7e69ebc,92a3e046,e0f3aff2,64228803,d8c1d729,88780d2,ae8c344d,f9571b86,70254b39,b4243705) +,S(b2b703c2,56ab219e,528886a4,4d6b7772,5cfc1b5b,17865ecc,c46e2d2,2420514d,b6aff027,b4408177,8c6cfaa0,123590a7,4615394c,aa83891d,15013d35,ba28a9cf) +,S(d249c36d,fbf43f5d,c6ddb196,d78d4cbe,898d64cb,3b239f89,1e8c4245,ab647afb,4e58c9e9,4199e0b7,8a0179c2,c82b6442,17eb3fe7,80c687e5,166f56ec,f812d092) +,S(ac3519a1,92c13eb,b37cd560,1a141d80,817226ec,7c86a053,42655c1,997b476,3522765a,afc2fe6b,2af9b489,27809189,74c2bc57,58ce502,13777ce1,a569083a) +,S(e9b69596,8983ee86,340b96ce,efd9a289,e86e6d49,3f057962,77b99067,af83c70f,983a83a,e1b08fee,392e51e1,c12a8e12,731d592a,517e240e,ea508f7d,b34059d5) +,S(e11e982f,10e65120,ca357106,f273c5b2,9900454f,81456781,36f52871,65444dd6,e961b155,81ee9ec5,1e6a3616,b7182da1,bd2e5db4,d08dad5b,46bee558,44c21850) +,S(f63f4434,bb0c17dd,3a17c75d,2d179e41,10a7810a,847bd4eb,37827997,94e57b14,480bff24,69c2e268,a51b2147,3d6cf7ca,23a3c61b,513267f7,c25b092,7dcc8549) +,S(cd8ea46,d65bb2da,7234508e,fb48a828,27678525,d102fa85,6d26475,eadc1a69,ba231ab9,513f90be,9cc8260a,fc63b05a,5aaa0280,3502532c,916d99c7,20b7b2d0) +,S(af9a2285,ec491b56,9cf53c8,6ec188e0,5bf18d1c,d7e898c3,c881a5de,481bbe13,a0cca7f3,714f8d00,92af7bc9,62abbe5,4d106dd0,a6089607,35a6d9b4,73d9ed58) +,S(5d90a039,55f41998,62e5cef1,af05ddd9,114632eb,abf27d6b,9b92c6c8,cfed8640,a0025e54,482aa49,11d8a556,2205c2ae,2a0f75c4,6f3faa55,7463b9b9,cce1281d) +,S(aa1f071c,55541753,3a47b490,c5603aed,2d2e5282,71acd0de,6ea7c5bc,ba66a348,195d8b00,fd90b1ad,15e46620,22d78bb2,47c1e9a7,8ab3b018,f341a005,6267a167) +,S(4225728f,ee2495d6,73f64d5a,cee2e372,2713a3b4,dbd2f098,d20415c9,3ab513e6,76c17939,461504e6,e1420d53,c5b07449,ce7f976a,e4de178e,69552755,75e92412) +,S(669c2815,b3357084,bf7bab89,63753b0b,ebbea33e,5b731ba7,5f969890,3a281eb6,23fcf486,e2839e2d,91fb08a9,11ed7361,81de7406,54c13306,575c576c,d0459c28) +,S(7b29749b,393869b0,d7f0977b,340b9e07,76a20ceb,ff6d8f8e,f4650348,11773665,a0d68cd,b6033ab6,a4c92113,c8f07110,aa5cf600,2335d2d5,2ca9b956,2874832b) +,S(6f096ed8,56f38c26,25200774,77ef7ade,19fb616e,30ed560a,ee5b4987,5f43a7db,54453b3d,1ffce3dc,b5e72ec9,3f15b57c,6725b271,d3fe8b7d,8f30ed00,35845b6d) +,S(1354de01,ef040d5c,681318c5,a6dfe7af,5c8eba0e,ab581674,acd5335c,e33c4bec,4002513f,ed215b53,c65686ad,8366cd7e,38711fd9,98d27750,bfce7e24,dda317b) +,S(5f8afb0b,3800c535,47cdf93d,61ae5c67,233c2525,17f99c38,8e97e7a9,1a90b561,7dad53b7,a64b7068,967fc0dc,e7178a43,a06e56f7,7aab1a57,7910d69c,23540671) +,S(901d50d9,b88abad7,84e75135,85a81d9f,a1d167f2,c9f377b8,e2598cc7,b249f3d8,7242b591,3c80db3e,748c63ae,47ee6229,2c1bc29b,e9f9088d,fb882259,405c3dd0) +,S(2f5e27e7,4c7e00df,c0bf6401,7d1a888d,1bb7a3e1,3ff66874,f7c306e3,806a48d3,87c3836c,7fb767f,4b5ac585,62c48a18,21dede2a,7d63fe40,da75d967,cf9191d0) +,S(8b2277a1,70464589,1d8b54cc,43bd5fc3,54fa6f1b,e7a062e6,6349ac2c,40eef8ba,ac3a007d,6b3278de,1c043476,13b254b7,69c9e14a,c2f50f9d,5f025046,2e06081f) +,S(4a6273a4,e9f28e9a,82c3532b,e7d3e564,66e87273,ad1fcfad,7ecace6c,54890de4,6d8b0fb2,1cb99844,610a325c,9592cc1d,e7c8b32,d70e19b7,ab7df472,8fd1aa51) +,S(f07330e,2ab0150e,435fe3a6,8c703091,4e7fb52c,307d58d5,d5120bfb,891f84d5,25b6ebc5,4c1d9206,33891a8e,39aadebd,988bd98b,a29b04bf,6ce4c283,a4438b08) +,S(3a30b22d,6f1fd617,9fff2c21,d6635828,8c21fc8a,94a274b8,993ecb91,eaab54eb,94035c56,6ea179ac,d58eb0f9,d12cb41d,67b94fbe,65805110,61cd9806,890946b) +,S(8c4f39cb,87d7f65e,591fa10,fd46d08f,fc5de3e1,67d8c9e7,718bff95,b112a5a,726c4bb,c64373f1,9399db5,18b5f823,3faef361,3e363b84,ad76052e,bdc8f2e6) +,S(38118e59,63a1929e,74f6d98b,c80e44e4,d9b32254,6a0f1eb0,690d08f4,f3bd4bfb,23167e00,c29513e8,e82d1140,bef5bf02,b806a652,fee592fb,1dad0811,604a4b50) +,S(75d4246b,db065274,550e9784,f3c9437f,3aec0fde,3af54a0d,61430cdf,2626bf5c,8392f570,3896cc62,d66f8485,9f7f269,4ff40a81,9505447b,7d79bb98,77f8f621) +,S(ab3bb0ae,c1f390fc,8d1bd3fb,4ecdad66,3db868c7,c4fbe0ba,6cf4f059,7068ed87,91382a2,2dcfe0c1,b51148ce,bad2140,24cf099c,e3e5e3ee,867db7ee,d070c7e4) +,S(d1453e12,383386e1,1976cae0,8a448b63,1a977dd8,47c19d2f,d7a212ad,5090011c,7044d595,fa8f68c2,4a972658,590d7ab6,dfc06ace,b9d8c320,205b858e,ba0402c5) +,S(894afc53,b0d1bb6a,c948d117,7e83c42,b4ff4084,e593fd75,d0660680,2ec0a4eb,5c5eb493,73e74fc7,39ca4fba,1940ebe4,6912d896,7cfc036c,7402e8ff,8d071d7c) +,S(f1dbde60,43133dc6,8699e89a,3dcaddc1,fbcb5ea5,e815eb5,8e7a6b87,dea2e6e9,96a7b1a5,b36e5492,68168c91,775d6107,a3f87f9,fb5c8b3b,acb75dad,5dc544fa) +,S(ad9126ba,6d35d780,dd2841cb,2ba817d3,f0267446,ee99abd0,ee2b4910,a4450b8,f77eaa1e,66c0f3f6,88268d92,9c9ee53d,6dbbc20b,b74e864f,d7831cc9,3d47280b) +,S(70d5638f,d3fc43c7,6f321157,f9715994,3b797d8b,1d366f5a,a5a7f1e4,ff1ff7a6,ba6f2d41,7af1c5af,dac8c83d,dcc289e9,4d6f29b4,2631ab7b,19414bdf,4a9ece36) +,S(e43bb23e,1f82bcd2,708730b9,3d3ed915,e3b4ad84,61904f68,bd91a065,80a4ebad,3b528db,117cfb49,99941b0b,63f51ef3,926a6230,dadbfcdc,28fd1d6,2bd44147) +,S(9daf3516,a015bd59,b648fd9d,9143e76,46b2e3fa,df5e446a,c57f2e22,9c9dad2b,5ec57ad4,808a9f2,ed297f7d,a7794e2e,3f1bb14c,bef58047,e0bddfb1,8ff11149) +,S(13970b21,3115c499,5eac245b,33633c53,1f2be101,a541f129,7403a727,67df16f8,3444e05a,7e49ecfd,633c96dc,99a0fc81,cc3c359c,440ffcd4,5df61c5d,1c027e97) +,S(12aef793,66978a2d,3fab4377,7debd5c7,4315b002,829b49df,c80fbb4e,1eaa94c1,e3f5c1d6,ea42b741,8bb3446d,c23679f8,e7a96d02,a8f33d1d,3404126f,71f9e37b) +,S(62a2ef7b,887de5a6,19c753f5,e0bc45c1,7c47b8b1,ffbb0ce4,8b93caf1,d1ab4b02,7d00482c,20c25e01,ad6ae35e,89c263a3,5d0fc816,952a96b0,9f2c2fa4,b8fc9bef) +,S(e6b03f17,92df5b1e,ec324ea0,898c031b,d745221e,791d2406,2aa917fc,de6f8a87,b4ee4b18,41153d22,1ec0ffe0,ec05b1c3,408d71c,5d2ca29e,a01ef9c2,e669b205) +,S(dbc02e03,e03e2f14,53ff6410,afded1f4,f0d51461,5ee00f75,d041ee33,c4f35783,6a3a332d,99ffedd3,d442b44b,aaa9d12,9d93e372,36dad034,9c47bd83,7c7674c4) +,S(f11be23d,6884890f,78ccbcaa,c1759ceb,5e7f98dc,19073aba,b85d85be,5fd23ef0,9afda170,dc1270d2,e43989a,4ffac7d5,c848ee6a,51e03b58,c308a4fa,39e2cfe9) +,S(16ec4f95,1db5c83a,c2c26209,f2577650,e9c48c44,224b221c,c09b0b19,1c1c5552,e3959034,d259e9f5,163a44da,f87ffd63,7a35b220,eea5ec6c,301cba9,eb09dc54) +,S(3cf701ab,8991e981,e9cbfe30,7b3aced5,c2147c47,f76bc2a0,733ee544,3fef3f99,1e6a3069,d4d0bb8c,def98d49,cd303b51,c45617ed,833be051,ca2836bc,13b8e1ac) +,S(96d093fd,1a8efbe,4f93c544,d0d7e397,cc83e114,4574f804,570fa3ec,58d5669c,2a29438,a05fe50d,b980db60,b343b06d,1796ddff,7e7fe39a,356cb608,69c05ccb) +,S(a6457eee,21025732,5094d3eb,6f6ea05,21e83184,adeabfa7,b6cd1206,9a9dc9ee,83e436a8,b234778d,9c7be0db,88639177,1d7a48df,19c29c47,682fa2cc,30b5e7f2) +,S(1b366505,1c858ac3,5890e7dd,b4aa7984,dbacbbe1,f4d2b62d,5337b530,da9bb0a5,39d3c2d,42c5d292,40b474e7,2e94a64b,4612f5a,68f5b6bc,586db5fc,a41025d6) +,S(e09325f4,68328cc4,d69a71d4,8ffe0380,bc118cb3,b8f390d3,4c1e56fd,27f4589a,16cbf183,78946fb8,3ff9763,41c6cc3c,9b2f451d,7661bc3f,3811f7e6,ea89a01d) +,S(6a8ea7a9,ddfa0f9a,8473c47e,f5667e44,3e64e03c,5c33a9a1,f0f1257b,40e1ce62,92806471,56238c84,9c0aadaa,2e9efdcd,e5a56a2a,78803f7b,66210333,88f525db) +,S(480b30ca,dc57c623,9ede2763,f113b46e,599076ae,ec687c49,33343178,c620f2ea,b5aa1b8a,ffe1e5ed,de587df3,341dd34b,57180cd4,752a1bfd,d06e4c2c,273b4433) +,S(134be6f0,b03ea43e,98e2364,46a45253,ea5822df,46227aec,b24b09d5,b25a34b2,d4841d54,b7fc1736,b293d314,bf6352f2,c7b08ece,4de652d4,2c1b985,d1fd78a2) +,S(7c84e23f,c54de6a1,a4ff6c9a,c7c88ac6,732d019f,a53b1a9a,a6eb2ab8,a3101f31,4ca88bac,a8d52f44,3703fa27,4fddde3d,ae5924bd,26b062fc,6f7fd0d,43ddf5ad) +,S(7c6a349,911f02ef,2aebdc3b,ce77f639,94c4dd2a,a842b567,141c023f,4f2d92d5,9b4f2f9,6215aad9,c7e0edf6,efcd8aa8,74dbbcd5,4a0c4cd0,fb7e01e8,ba6884af) +,S(9e1dffc6,a919c9b8,4e3d818a,5ec60f7d,5a2baba7,7d2dd65e,137d2ba2,8a1aed3c,cf26f543,bb7ef705,e2d3c429,f0ea27,84e3daae,1a71c556,38d281fd,aa3b1738) +,S(e24f6abe,c7519588,33ecc765,7446ae36,937e310b,d5754c5c,343eecf3,6e140079,c38a0399,774ff24d,90f8e599,183bf011,aa3c911b,9a66bbe6,920522a6,7510e62d) +,S(517505bd,1fe28c21,2fa85f18,99823b01,bcc3bd1,748169ea,54f35ab7,870f0e1,da94c34a,5de41881,1184fe92,8b3f08fc,362aadf7,5e7abf87,5d5f4798,fa712f3f) +,S(a02217de,4ec87155,b877b7c9,dd7425b9,79627f0d,ebe127ce,27d4f3ef,fb988a8b,cdbd866d,7b69e8eb,9321d07b,2a5c9d8f,6eec8be2,f19a6d24,4c987a1a,12752bd5) +,S(2e595023,c8ba084c,1cbb2d05,96ec35b2,7c366bf,cde27666,35d7e820,8fcb0ae9,ac08f27e,b8fd5ac4,deb1f46b,23ac1c5c,aa02b918,9761e6ba,d7c1ebb0,f412d8cf) +,S(ce384358,fba557d3,b76df62e,d2264cf1,e0bc7b43,bab30be9,fd6f65e1,a82b6c2f,a3cbf24a,e067ad85,ae0fc86a,6e8490b6,1e44980b,52f29a75,4a3f7e4b,a79ad119) +,S(9715da8,79cb1c5c,4291e00,fd2822c1,7f067d63,664170fe,463e86c2,d25e46,c5179ad3,a4846fb8,d6f290b9,2f957e14,cee99f6e,12fc8066,ec4dfaaf,a82edb99) +,S(19f61bb0,4cedc19e,5054eeff,8d0bc384,6cf62a35,1af3ab95,e03e45d0,786e1aef,aaacadc8,db84d7c3,f869931b,bd33d295,45fb37cb,7e474fa1,7a69a683,117c05b8) +,S(2a69afa7,581777ad,38882f6c,659ff4da,33fcdc17,a5355583,d1f8ae37,7dcbd718,878eb429,d42dfbd6,435df1fa,c5e0ed4d,e7b2fe4b,6f7dd6f2,6a3150a2,213fa619) +,S(c3da1980,cdf257db,f2a5eda9,94267691,a5e1e679,79d4908c,c06f7f50,71002381,2cdf4de1,90ef2995,a984d882,598c24cc,35cfc47e,5cbd2d53,53d880cf,a944bfb6) +,S(19294eba,9d19c03b,497551cb,7cc8d8ad,3e3b2130,942ca8dd,c8bc5579,1c424d2d,5523ac45,e676daaf,2d8da00f,5e9240e3,d904a536,63e6b704,735889c8,84b680ba) +,S(d8b3b307,41ee7ff8,2306615f,2d2ef361,6e3f7cd7,fed9d56e,69300fb8,5eab6bd3,7d57c12d,e65bf3c4,6dde736c,373ea374,d090b240,6e1d97fc,8049e21e,aa10a74c) +,S(e2fa1bd1,164528f0,87c72a18,e9843e33,43b376d9,b5616b74,5e0c3d00,eca95fd1,72dcfc41,15b35406,8bd3057d,506d592,771eb3fd,60a2c2c3,dfc2645f,86b249e5) +,S(ac587775,bee32b7e,90031ad8,9786df14,8e4d9662,55a06399,e43c0441,883fd6b4,b6d3eaa,6f6a50ef,ef84c578,b241591e,4a718eef,fb40ac34,99a57079,b74c45b5) +,S(74976cb0,77d481f5,e6bf700,6db57a13,f362fabb,e6aaf25b,6e956452,9d093bbc,bb40be31,7cfde25c,75ea859,2b622e4,9d42a0a7,30602241,219bcc84,a5f4bfe1) +,S(e71e6967,f32647fc,2c13a94d,4bc1410a,cf9728d,1f543522,681d750b,2620a668,33c4fc82,720210d9,afb9f1fd,51671f3f,fc1df5f4,e61a5ff8,c59f06c7,91f996de) +,S(bc36cf57,161e9b17,828e4557,74204c59,805b35e3,abdf4ba4,daa9a5c3,fafad6d2,df34c492,3018e879,bf459cb4,528d2983,340444f5,a85efc29,71e260df,29cd8a20) +,S(925251b3,9c8761c6,317c2066,717a2e8d,89e43acf,89527ddd,6078fa49,2d040f95,aa7a084,8b2633ac,ce551f1c,63312895,f4ece420,5e224665,2c486beb,b8131f10) +,S(4ec27df3,d9e755ce,b93e1ca0,e0e43f44,595b529f,6460e3f4,e6cc3765,3a2bbb21,eee3fa06,257b4be9,387ac7b6,6cc1ff6a,aae43583,37d6ed71,27ff753f,1fb179ac) +,S(6f733e9c,b86c3a17,5bce6c08,347577eb,69cceb17,3c19abef,c94b6646,92859812,2a895d6f,c4a7a4f5,610e8b8,9e7361bb,db728625,ee31e6de,927c74f5,b10ad0fe) +,S(c631f4ec,f205b1b4,6bc0fce5,3680e6a7,27f9e64d,5ee3fe24,c37291a0,d3a69b53,f0de9e0,e4bea2a9,cc01a5d,2f9aad2,f5af7ab2,7c2ff98b,983dd2b6,38dced4c) +,S(9326d449,4fcb3049,8badc221,6d3a90c0,131d31ea,cbca74f7,2cf7da2c,bb6aa2b8,c3f268ba,4c9a9ab5,3f9edb88,74f2786c,4e4c065e,ab58487e,cd8101b,7132511a) +,S(538c52d4,8fa6c492,cf546349,675d6a2c,ba10b442,8827dfeb,69f0303b,1b7ac774,c1b1db4f,d6d50f3e,c7533ee8,cea0d47,883b57e6,dd4137c8,2132f846,3b81ebf9) +,S(5e58a25d,8bdb4576,d178fdb7,23158d26,508f8486,ad553727,907901d5,6e99a680,97c1f814,8880cd85,51c9f1e4,9ae58eb3,d1a01285,bfa8248,44bc794b,7d83ec62) +,S(1e9830ee,b75d6c6d,c70989d4,ccb85e62,34a1cf94,ef81b65a,49b25753,cb6c13c4,d0780a7f,9607e530,d80dc068,68b1cf8b,82d3047a,2977d204,65187ed3,13c94c6c) +,S(c5b441c2,f7e97a03,dd690cbc,ac605772,1524dce7,fb5068f3,f73d78ce,50fe0183,9bdd2242,e35008dd,4f907600,64eb3b29,427ee9b2,bbeeb548,62878688,a916e410) +,S(a5f56816,e9448d0a,aaa7593e,e3145678,3be74521,b129f13,f11a276e,d419492,8406662,65c275da,76ef289e,d36f8af6,6ead9be1,48cec081,7c21987e,9e8af9fc) +,S(c5e85955,44004f79,2260d553,25628858,ce50c95b,9362d868,90fdfd20,8d1184c4,6a5f02f1,c0f381f2,7fd21eb,928f03a,c8524dc5,9bfc1bca,d025a290,7cf939d1) +,S(d5dd810,9e691f5,8694c87b,59907ed5,ec18d37b,8554799c,1481ac78,825d2ac9,ffbaef54,fd35a5ab,a49f9946,a11e5ad9,2f29590c,20e28180,9f4be3e4,b156dbe0) +,S(ee5d42a2,c705bae5,a11d9d09,af3217d,2ec16588,64a60a56,d8e4a1cd,4313c61a,f08f0e08,89c015f5,3a2a74c3,3dd625da,b329181d,1d0f4fa0,14ec01e9,5d113d88) +,S(90409eee,78af819e,249f62ea,3b4d70a9,26557f8,731e50ed,532c0b30,4616d615,17aa7a7f,8af635c9,c4ea353c,56c89da9,70df599a,faec8916,ec9a6d82,cdf957f2) +,S(5f19aa1b,a6d6e3d6,9445e8cd,71c95e3f,a3ddad6c,ff0dcb4b,9e09aee5,65ba9e46,f82b3170,c2953397,a6cd29fc,9c87bcd9,76cbc7a3,5f953948,5a57a940,63c2e570) +,S(5081942d,1039bfcd,96a759c9,27583c45,8dd4c013,59fea307,40c65fad,d020606b,f6f204b0,97cecd15,b2619aef,c25328fb,226598b,fc9384bd,de99a4d6,567e9b8e) +,S(43eea7b1,acbb1450,c9a49b0,262639f,702612b1,b184ac15,675d6496,a5df1a54,a31636f9,ceecfbd6,60f78f,f6cee471,d4366d7f,ff863db4,9a5a652c,71b94797) +,S(f2860e98,a30a6c14,ac43dc9c,61bbae1f,b8ecb294,36c8f0a8,7dd43c01,486706a1,bc83bfae,9a4effeb,4beb025e,962108e5,4a5d7979,cb9ae2a0,7cc44295,b95a2e9c) +,S(6b4a8c28,7d5c7af,63ad8d34,9751116b,60a613f5,7cac229d,7ef0d9c8,166d69c9,48333ada,f4810cf,94c78d43,88f8842d,fdc9fd7c,d391e456,a592d8b2,200bd6c6) +,S(d1efc808,393d4498,50837323,9b791d0d,a814e888,2958da8a,87136d93,bf1b7d74,13247e74,3c323631,9e557476,4ad4dcf2,b91dbc97,2d38244a,fabe4c0c,d08a9924) +,S(d3fd7a6a,fdc7332d,f2e6683b,a05ab787,e3c48262,ce837f9e,d8ebae1c,1f6f7ab2,3d25bfd3,3ddd4f74,8ff395a6,b4f36d19,cdb28ce6,b56aaa55,e783e9f6,3d74e70b) +,S(816f76c4,c5ea8733,5f220c54,28b31cc6,89fd8267,e498a675,4d6a2620,a60d9aac,d3b61647,f6624bb3,9fbb672f,51b66613,8a441a3b,660bb223,1f255488,806e79c4) +,S(1e344f97,98f11372,aef5c6c7,6b32a568,16198e18,8e611026,1dc78338,2522cc93,474e0218,9bb4f698,15e304d4,8166e3cd,717a1bc,a9cf4e4b,1f5c5d23,a36e392c) +,S(4d3bcef1,d6cff8a0,e0582d11,22eb7f67,28aae077,e9ef7960,ec519ab,3c6d6087,29f1b01f,a70e6812,3dade19e,d5d2689,6c491389,27a2da1d,3c628965,bccf38e2) +,S(6d5d596e,467ce203,297cdfe6,ce4807a6,1686a8c9,f0606283,5e0fa194,894d027b,ef58ab41,1d6a002c,12f469e2,e9f8ded4,4291b270,4b7490c5,4c70c94a,cb7b24ce) +,S(86f6ebc9,c25f6866,f14af018,88486b22,6c89b1fb,64bd9ac6,e523e503,e2cc6819,b0725647,4d9f3b4,8d4055d,e15b72ca,ce599bfc,247ce9a8,4b0d5e72,16b30425) +,S(520115e9,a47c3df7,23f81df,8422c03a,ea0084df,b122759a,8d6a5b75,540cb339,93b12878,44f22aec,9d5ed727,3d204d85,d3bddaad,73e3545e,5725b171,2b8417bb) +,S(19c9ff30,e5e50038,7e9be1f8,efddca98,7a72de0,d5cad8ce,7569d4e7,2b381009,b43b0c98,402748ee,16b362c8,b68ae79f,8493a7ef,293b149e,3faf7247,83ee3661) +,S(bdf0f8e0,928affd0,87566820,3c95b3b4,e6baf9f,f1da25c9,73814c27,551ee4cf,5f701bb6,8f8a6795,cb4ad675,e00b5ca5,761a0eff,32a1d3f0,9b29d5b6,3885163b) +,S(5c609591,37a48dfb,f778dc26,80de17ce,390ec33c,ea5cace2,a969ee9d,1e413e1a,670078d8,59a2c138,93946d1,e052552d,fd92c380,5fdf2ed7,8aad7795,2ddf2f51) +,S(98f22ef1,b9a62928,c5ddbdf,70e71c08,eb910ff1,fa6a6a1,56de82bf,bed8fae,f87be19a,9433d279,8088c882,5d122e31,bec9102f,c580fa2,24d40f32,2a2db1e8) +,S(d1842bec,2bfc5fc0,d5208d7b,40e04b76,88f26add,9b5a6845,751147e4,b4524615,f0405ace,6dc9bc88,48d18586,b713ca3d,67b76ad9,4f2f794c,55fbe9d2,f72ffa56) +,S(732cdad8,e0aaee77,473c0140,9702cb39,555ee048,357fa448,33ce8e3f,5f50bea5,24666502,448268a5,bc2c693a,85a1fea9,dc5f010b,a9b0cce7,6bf36124,bca1cb0c) +,S(6c86ebd9,5200b1ff,dbb6ce6d,e9fff6b7,1b6100e3,1144239d,77e7201c,db2e8af5,39c687d5,abff0ec7,c7ccc4b2,a4a16ba9,7324430e,a1ef209d,5ea126d2,cef24539) +,S(655d63c1,47441ab0,e65f9893,dd38f3ca,22d2d8a,a7b2c87d,a2e2293,b24ffe0f,d19ede94,b25ca138,94ab8fe9,842cae29,92cb58da,592c19eb,57c4184a,45121281) +,S(8efc14d2,d5845886,ec264438,449ff49d,ddab7567,69999bd3,6191cb39,efa41b72,9f1052fc,416db1a1,d9797e66,a816b403,475ac091,ded4dfdc,e262d527,3c535293) +,S(31a7f0b9,1686e695,d1fae6e3,8fcdbeb4,246fde30,f2ca80d5,2d9fde31,c728eef2,9661bf7d,46248da3,8ae1ff52,a8aba654,351a1f58,4f3bbfed,1875d439,3612190d) +,S(9dd959a9,8c862275,93dcc957,e369b2fe,5cc1d411,d4162ad7,d8e22b64,633adb85,78ccfeef,d95ede71,32a7011d,bd39b9dd,f77e38bc,47f7432c,f90d6583,5a6e665e) +,S(51beca99,fe3cedfd,1ba44caf,58c0fe4,8b926e72,50e5ca7f,8a187cb4,909b1892,12f38fea,aa9de148,7c14eff6,96cccf6b,c7cb23a8,6f2b7e0f,10fa971f,3545a0b2) +,S(1a84e21,3ef9b9a5,9f9a4fe9,d21dc1cd,1ec7a102,fd91557c,1129921b,781e6b51,aefbd931,17a42a75,13db0e04,782aa0b6,9cd79d36,b074f026,bfb7682,983cb78c) +,S(9eb14847,2d02a287,cd197450,78d81963,3943183d,c76c2090,9f68b94,12eeeaf0,6fe4b5a2,d18ac52f,9a129a91,1db00993,ca505380,2054b5c5,48f35380,c6d467d) +,S(9ecb3cc8,da5475cf,1a66ef54,3286f07,f5be1196,2c1fd420,b394bae6,c4256441,b4160952,e3701895,6f25c5d2,98ce90c7,91797571,267902a0,bba53d2c,2fe2cde0) +,S(541e567c,b2160fe2,75e9d479,1beb8ad0,4c07d6b5,12b43d49,888963f6,d6696ce,2444e184,66cc09d6,aec704c6,ea8ef670,4ed1488c,dd8107c0,c625b783,6534d6f4) +,S(8c061b6b,b6b55fc3,7c6d805c,808fb3e1,6fab1cb3,a05853bc,4933eb39,ca7b3580,20430304,c3780c29,a977f8d3,54424539,67924c2e,9a1353da,40716ef5,a0a0d37d) +,S(b9b674ab,361aacec,bbb69f7f,7c2b1361,44e55da6,1566ed97,cd58152e,4d391033,7841975a,4cf0b5b7,3bad8433,10866275,8a8eb93c,3b5db58a,15346083,f3d10386) +,S(3453c3d2,27e1dfc5,3e22487d,cce25ab6,18a3d25a,48f6fd1f,8e9158ec,dd6bfa1c,aeef1768,b754d998,fcbc75db,7a750396,930d169d,bf933c1c,15dfe041,17ff63a6) +,S(f36f7b9f,28463b22,d2c43e29,6b96846c,1b3401ec,53490c5c,35ec197d,da2c440c,9876476d,e2cfb7eb,b1cdef50,a39d20c,4ba5000f,9edef22e,ab7b96c6,f0cb5585) +,S(77c64190,33ef6119,ac3edefe,ed519632,ef5dccf3,f46066bf,6d5204e0,66788b5d,980cc59e,a103486a,9c8cfccd,213cf704,3e6aacb6,abbf3293,c833de88,e5b2716a) +,S(818911ee,6051c4d5,19fb7785,d52c6f27,a82e2d79,a4a55623,909f3d6d,b549e851,5d031307,a2d66fce,4b607967,f662bc0,af855112,11cc209d,8457ff41,968fa325) +,S(bf5900a7,7c211a75,231ebe58,17f91748,c957f5ae,b98377b1,9554fe90,d11ff226,d910b2e3,1760f0de,838cc159,7da6915d,e6c3fb29,80bc0e65,e87a36f7,749cf1f1) +,S(654b4257,11f03dbe,75b7d60d,b578d75,20e7cb6f,4923f774,8799b4a1,df06fa16,12c9e75e,26d3ab4d,645a7a64,d97eb6c9,356a3951,fb715bbe,9e42f500,a0c3f44c) +,S(33a425f4,f178af6d,48b78873,cf70da66,aabbaae0,397e6673,7a9c6074,15ab3d2f,1e5aaddf,d76b1b91,14016f02,1812d7ea,18decd14,ca3e3925,89894151,92178cb0) +,S(cb088930,f0ba3995,d7542d48,92ce47e5,5d8fdd5d,7adf60d9,3651240b,12fe7636,aad156ed,f0b25c30,e4bc3784,a1b7857a,4cabbe5d,2ceffb72,ca2cb7d2,45ddb024) +,S(ffa9e81,afb11dee,83a54b47,fe9b41e4,de4191af,7279d19e,90e1c528,7c205c0a,405233e,b20a4848,80210b40,18c098ff,a0a17203,c5a13b12,5ec0fe92,1d1c3567) +,S(92ce3be2,8fd6c9db,be1cd4d1,f58005b2,af0c136,89181c52,a67c2503,2649a6af,cdb840c7,7e0fc2c3,d4b959c6,6fc47142,622c8a16,b30168a6,c62ef368,8bd23932) +,S(46079065,b64bd3d3,3e3efc91,374e1443,69adc4a,bcd2bcfd,91ebed0d,88f78cff,b09653a1,1c0710bd,b737611d,e5d80e67,a516dcc6,2ee3f63f,e2d6a7,f3794ae4) +,S(5cf961ff,de982138,958471b4,b316cae3,6246ae74,e1309400,a3acd118,e4736c93,ab8e425c,ab39325b,b94925d7,795d8799,18efc449,e44c9f03,cf7bf487,fc32b185) +,S(d8fa1009,27c1aad9,6ba97005,f8a24013,bc29082b,ada0e0ae,f6f72ec9,8abc4240,38d88e5e,183b2c09,d53adeb5,8d0525f0,83a512c4,1dd64cfb,a7024602,f39e484c) +,S(cdabe8c6,7d0d4627,54cdd3d5,3e70bcba,e2ec925c,a46a4536,ce3be9ae,e0b37d8a,c2032dac,527cd15a,a1d812ce,1c658cc2,a0a379a5,2a30613c,2737812a,6e683830) +,S(394fbdd6,7069d83,8fdf87f7,b1c179d9,1a491ca3,680f0103,46de3299,37e92374,5ceac741,828ac862,7fcd587c,69844243,d17ba038,901cdb42,36e96685,d589a693) +,S(84eb6d44,103f56df,96617c7,11c79dc7,a6161189,157a0782,74fec78,fc5f6c37,57a16660,4d1fa3d9,cb358e7a,47984a00,6926df57,4e06a313,7b3c7524,2e882320) +,S(295dca03,657995e5,d432a606,da12bec9,fec8f4f0,582d75dc,5657c973,7cf1051d,c4df0ad7,b1e3a29d,cca4120f,478a2d63,f18fc67f,bd201be4,e2fe05fa,66ba2d6c) +,S(b42d81ca,1bdfb038,d7888194,deda7307,eb846bf1,738d8b7d,89663bf2,8097fa7e,2d913cc9,93ed5118,1082c85a,42495133,ace8bc6c,65530309,c6e15794,aceff5cb) +,S(48484186,4f6d8f3e,94977a3,45bc0db3,1330910d,4c555032,da8da876,912df644,7a78a8c7,68c9d9ef,b5242fcd,b7a5946c,5fbedaa3,2914339f,8b0c0ac0,eb8a3146) +,S(7376d600,9a7a76b9,dfb7e225,c0da3186,b683fb13,daed9fdd,25ac6606,7e7d2316,fc733036,dabd7c4a,719b699c,da115547,8a52d69f,387b8a94,28744144,c0502901) +,S(9be9c65f,5fd6cbcf,522eb9ca,91427f68,152caa2,a152051e,3919307c,9f67ab8f,14da6642,fa3b7c37,41c9f953,d1e01c09,267b7885,8414fe5f,24f47c4,b44c413e) +,S(7d0ae5e4,18d6c6df,45f6d26a,7e962335,4ea1a338,8f183eac,85b1eac9,1962e2f5,551eedf8,264763b0,913307a5,14fd9e09,479f43a8,87983e69,509a3688,d09308be) +,S(d91d965,d3b85441,acec7257,d444cba0,6243b34,14e9665,9cc62cbd,89aea7db,54e26ec,9c82bf54,f06cce16,2cfb924,2a354c83,fe530937,9bbe733,6010f44f) +,S(44c8fe95,aa48f8bb,6c0a32da,a6263918,fc2df7b8,6a68f277,6bf405cd,1bf0566,87fc1fa8,3fea76e5,52f53612,45e54053,9d70377,cd865915,b6b78acb,f73a6e03) +,S(c7f8e825,5f2ddcfd,f21c5c20,ea84a527,2c5f6c59,99843c96,3bce9e0a,aa7ef398,5c1cf086,9c1f790,b1e59ddd,ec9729dc,2b73c6a1,be333dd7,e423a0be,bee50243) +,S(3a8ebd85,a2bd4b1e,6c0373d0,63e9cc4e,a91e6e1a,f4bd7af7,501e0160,8fb7f4d9,4d9351b7,3c3f6f36,1b86ae94,ccecd211,ee3b13a9,522d799f,e78c87df,4473f23c) +,S(bb01a4cf,ad90f3e0,5355f0b6,d1b28420,786c09dd,9db0ed5b,38a56506,4da77e9e,1742b511,43bc276f,273afb9,8473ee3d,3d962050,7462cdf4,a8c641ef,cc2eccde) +,S(eee45594,1a04bdec,a02e7e85,1d86987e,798c27df,adcfd5d8,2979960a,3983f4b9,3cc75025,9b5d215,37570928,1abca8a9,29f5609d,56c8dca4,3d1b23d3,cba3fedc) +,S(d2290ec5,120d591d,2e4e2796,3d10c0eb,e73d8b9b,600587ca,84173ce6,796123ba,c4760011,4c68baf7,b4053666,d8bd494b,b4ef1786,c1d7a522,8a656f10,1c837304) +,S(21e359ca,9b7326bc,b3380282,b9017df0,3cdfb7f0,af95f326,701bd8bc,25dc047a,68b866e8,555206e9,7cc43461,34c3a61d,ce2a50ab,2b514935,a05f8e04,ad95c70) +,S(b4acba20,94b35033,5095b208,9126367f,3203efc3,35caa43a,51857181,f4987e42,fa0f72af,77db4913,af6d906e,54eb33f0,a3e9d20e,d366c878,3b7c513c,c5165c16) +,S(5ac6b2da,18754c30,9ae46ac8,3592d673,ac5d61e0,35ef1b4,512aa9b6,7551862a,e93b1d74,105974cd,b6bd3043,c0dedb8c,b4eaa81,c949999e,68d52fa,4a3941a8) +,S(4a53cad7,2a894cab,9b761157,38ae78b0,c36c293,c60ba8d4,b87300aa,792c51d,4b0dcfda,b890ffdd,cf8a6a71,15f2a351,d883ad8,fe3d15a9,118f3e04,43f840c8) +,S(5edec48f,7d8c9b4c,af3371c2,6e054392,755fa073,1e660971,4e089b04,2a07bc36,b18b8d1e,407f934f,e526fa5d,38b3a408,76bab92a,2bc192b5,b7c206ed,6ad040e0) +,S(986b120,618abe6a,d965f9d9,6f50fd7b,29f1b897,8276ff8c,562519ab,8aa92890,2c981569,23ff1809,1cb47459,bafc0d51,699740b,ca59dd7a,14e07b9,432f681) +,S(8c61517b,397d36a6,b30f0894,98d525ff,bbda959a,126e9be6,f67b9831,e5e7372d,f7608f24,130ce8cf,56a7b762,c1563519,a4be88d1,79e90f1d,b432ac05,d472d771) +,S(d6abe67b,e30fa40,b642483e,a6ae7ecb,4217a07f,35546f97,469aae99,a286b8f6,b5e5675c,91aa08d2,a5a77349,5f1ad2bf,8b6b9dbf,4b35dc6c,262ff1c9,8eaa70ed) +,S(26be12b4,ae013009,45c8ec05,58edb030,e19a75ad,872104f6,8642bf5b,c30f7934,1086891b,3ce97d8a,a568fe54,28164f25,4fc15953,c97d40c8,f32c0ec6,6ed49fcd) +,S(3f0281e9,1dfdf1de,69d5112b,1b86ea89,d737d09f,1cbbb71d,2400d0e7,719987fb,27451e9a,2cb336a2,998d55ca,ac12e16c,fffbbd5a,3703897d,5f566ab4,5f4aba92) +,S(b84b8115,7b1782f1,e4b641c2,a001daac,ac7d53f5,b3f1fa5a,d0a5ddc2,732af3b0,a0c8f7f4,8fa49815,7a6c590d,4ea18dc2,c586b332,2a303061,c19edf44,ebba25ae) +,S(790ab328,fd86da4c,66f0989,296229fb,609de28e,cc8cc6d3,d315eb89,fdf31e38,cdcf83d3,44d103c6,736bb5c6,375bc2e4,3fcc46f5,777d6e5d,cc407700,15d29aa0) +,S(d5fee68a,f9b7f182,20ea6525,6a591f24,da79a642,4ea0fe31,88a0b658,9006fb51,87b8608b,1b3d0d71,c9ab2c9b,84654408,af6551c7,1e8ec6d4,a8f26cb3,20577532) +,S(410f9801,4622b22d,62eef39a,3c5350c9,e80ecef8,48c4295e,2ae279ca,9623e777,53dbc737,5766d9f8,ac0b8b7c,e4b852b0,3214fe70,24386915,84856c83,6376821) +,S(6cbfa6f,fc7a6009,75edf0b,c260bd2d,258bec55,382e650d,c464b16b,e5f34eeb,de72cf4e,33028bb9,18ed3a41,d885faf7,e1d5901a,ad7a325f,801f1a36,2ed730c5) +,S(2a75c02b,3325ec0b,ffa42250,e224a4de,e0c4c12b,69b71039,4bc3040d,80e5c504,ed666a2d,8ac26964,f0445d21,f1719ada,fbaea128,9edd69bc,94ae6123,a2e6b8bd) +,S(ea2bbd57,6c0b20a5,6790ad87,29f25475,24ef97e3,86663aba,2473994e,fab39134,d98d55fc,daedbd5c,3aab619e,1288634d,f526f873,19743f81,149ba85d,535172cc) +,S(893e9899,fe1b8a92,439c1594,634ff44d,1d0a60cd,8a0183a,b810bb8e,f80d0400,c680717b,aa2ff029,7baa807,d7290190,37c73d0f,a5a1878c,9fa2a6dd,d17cbb2) +,S(d75b0a2d,1e9a20c5,398fc3b7,cacc79ba,fd53a14e,ebe23196,e4bdf4a8,f8546422,37a8efdd,618bcff3,3dd0c0c9,f8bf3192,2e131764,305b610c,88a2b74e,44672981) +,S(96c84a8d,5dd2ec9b,44a5b2d7,af3b65e4,9c07786,969452c2,5e8e64f5,a264c14e,292ed1a0,dafdf3f4,83a2a419,6e1b6b28,4d7daf88,88c7268d,70e556fc,ff55341e) +,S(458895f0,77782a62,43abb775,7daec5af,264a71e0,6eccaf8a,3b23baaf,fbd7343f,809eb056,87bb618c,a0f4e1e7,c8d05e48,95f18393,2e949b22,b9ddab0c,55d32b93) +,S(59dba4a8,d7956515,7f639316,75fecc7b,58a0e91a,6c9c3d50,7dae6d40,2e67a9df,718094a2,83e47265,1ef52d4e,db25b0b9,9e069f,391ddfb0,d9987596,d2f4ee2f) +,S(a5f92445,b7cd75c3,9a4b3199,96baf00b,f855ebf,ab3e19bb,71d4346c,878b4bb,9bb1bdb5,baa4d56,5b9c5077,c86b96ec,953ce381,17cc8d53,7b0f3957,a582ddd1) +,S(f146eff,2a9ee1ec,a3f26d6a,17c89639,a1f3505d,2776e340,ae89449b,99c8b198,1674daf7,a66f1a89,7b5378e4,add6a196,fd27795d,88969a07,a210d33d,646a64af) +,S(e67f5967,d98c1d3c,3a4d0872,12d3b65f,6f8df216,5dc14633,92c23ecf,ffc17e1a,c3dbbcab,d1971eb7,a8b088c8,c71d65a8,328bf43,58f0e685,9025db87,e5391380) +,S(32e8d775,ed37cc2e,6f69c85b,71c95d65,d40f033c,b5eef362,86d4499b,fb6071f,2fbb1d8d,a6364791,95ecaf52,6f63eb86,e4604973,edebbf82,b796d88b,ade44334) +,S(b98c7cac,475ee4a3,c1815a17,e460f76e,e5334b27,e1ea319f,be8924b5,819a473b,d7f1bb1b,a653f20d,c7145420,d8c8c339,d789ee60,9b9ff0ce,73910b94,3deeb88f) +,S(d9830fd5,545dcca0,ee37a402,9f406cd7,50bbaf59,e60a80fe,da976bbe,ff9027d0,cffab795,e45a2833,75e7b861,728421d5,f9e22d03,44f835a4,c55207bc,6479b947) +,S(399fbb5e,4f4e27ab,3e737a32,d065fdd8,c003ecaa,84a2430b,4a7b4d40,eb6f9721,93f7b541,121d13bc,480f7868,ac9d8302,6706d2f1,a46955de,a3912735,c5f02e0) +,S(64e067fe,17127128,6ef0fbdb,b2adb4c3,395a1ddd,f2ea76e6,261e6cf0,112c6227,8ef6afa,4bac7536,a23f08ed,eb8656a3,47a13f25,2dfacd37,c215cc3f,473687ab) +,S(57eb5e46,40721263,97f0d12a,532aa1ff,abef7822,4ba9b10e,8fc95e1c,6075a071,8a700d2c,80df0b4d,7e2c9291,9a51e565,8dd6ba5e,59bf1503,7bf7a0a,935545a1) +,S(b83adb94,ba1874cc,c61ade9e,43093cae,5bd86ff5,e86615c1,abca14cb,6eb81877,93417bf2,1fe01c85,5c6f7782,a5cdb01,a5d13b29,d719f0fb,a2373ba2,8bada7f1) +,S(7a90bb49,71537bc9,3d1bed23,891e43c6,e350fa37,ef8e73a2,3fd46ea0,5ed879bf,ee0fa59,3a51af19,70a6d8b7,22d42bf7,ca253572,2324a59f,c041b3e7,305fa3d4) +,S(195e4afc,6c95d6d0,8273cb0d,fda2da3b,4696b569,650d4230,4d396fb,3e653831,44075199,9dce9d6c,f10ef736,7888dbb3,a713423c,f2881cd5,76a681ce,6fee2c8a) +,S(28ec566a,29bd09e2,f8b228b9,ff2ec49d,56660734,f2ea864e,856be0ff,fd6f60ee,5b4f5e34,298b5a56,a6826143,8ba59d25,4922078d,f36dfdfe,d4e8972c,647fe031) +,S(1e005b72,be1bb77c,80512581,58e940e3,544cc133,a76ddf49,b681422c,1815cd22,9c523adf,4ba5d753,93e432f,491f8e1a,435165b2,f40f79d7,889d82f,8951a25a) +,S(f54ae39a,d074c399,636f0dca,682b9405,4e87e87,3132d7f9,cf79ad85,fa82586d,db2e9b90,1c2dac2f,f4851f4e,b0ffae7a,4c0cdf34,ae9f964b,841c539d,84040667) +,S(bc8dafb8,d385cfca,3643fc75,c8a93f9,792d2b9a,715269b9,ec40d581,5936e6c6,dda791ce,186ff28c,db7636ad,4073996c,4a2e2875,80da17e8,90d03886,1c14aec9) +,S(60b6ea82,627f5414,16978e7d,3c9d911d,9d9de92f,3baa0975,a8de4e3a,8ed3ab2d,64693ab,fd095109,ef89cdb2,204f2f3,89dae035,f451fe28,58fcb4f1,dbff0999) +,S(9c8d1352,bf291803,22730718,5ee65aa8,b14211de,6d73dace,2937cc6a,1ee79134,3c6e0d66,48f3fb6b,23e6e4a9,5df3911d,797afb50,9c12e90d,7eac557c,7b1a9505) +,S(bb2a8344,2997babd,6cefa2a6,1c9d2fc7,a42db3d5,bfb19334,c7535bd5,630be896,20de4f27,69596e65,edcd695f,61a0d8,3c8925a0,c8707470,9e84bd41,615ac75f) +,S(ba8bca72,496a6046,7b250a38,cbb536e3,b9fb9ab1,43800655,8ef5d186,2b66d50a,81abbb33,e835f864,3d075858,7ce59671,7e08c1c6,75af4c5b,eb80429b,9dc46aec) +,S(529fde52,c4d1c978,405107ba,d862f7b1,995ffef5,cba4a59e,d71b366c,28e17b46,ed7c2521,d39ca130,60d5f509,d0a8b0b3,40eb78c0,d4e4fc4a,83318a65,226d0a05) +,S(6e0e10c9,4445acc3,593efdd5,4b8ea1f9,db4a45a1,4c2d0a27,edbe3fc0,7a90e91d,43537a25,d2091290,f753460d,8816ff10,41308e6d,fb04b7e7,d5a108d5,c9fd83a) +,S(b2f90714,6fe2e01c,5cbd73a0,c0a358c7,a05aa730,97a060ff,491f362c,75c20e90,d0e680d8,f7d27eff,12b332e8,a92b846b,4242a746,9b31740,6c6af499,5ab51948) +,S(bf631a7,933e3ab5,f7b8707e,55a9498e,31ec3f36,970bb9b3,f5efa0cd,1a3f28a0,1030146a,387d4fd9,c12544dd,a448133a,49b5a6e0,d4b96933,cd47e89c,608dd5b9) +,S(cd7ec470,e9d5e3fc,a4c344f2,9edcd4df,4b7033ef,5e7ee99,de0db6a8,43926034,3aae77b3,bb008cb6,e982d673,7f78e920,f3a587db,bc106c0a,25c65d45,df8a4f6e) +,S(b3ac95ff,8365813e,e71199eb,946b5888,7dd34b1b,a214482f,dd3b7fa,3b8ce6b6,e3d9bbdd,aaba7887,8e763360,abd370d5,9d941ba5,cf758d33,3b480f00,ec5e7672) +,S(7fdc21a8,6962fced,e6f9fbdd,77e60a00,4dfb858b,5b149362,dae4b4f4,a4ab84fa,2ec0f21c,3d1c6d60,f22817a2,954d02b1,ce6e8b91,d826c11e,f8e542c4,245a55f3) +,S(6f019691,def39afb,103e524a,598bca92,3c99e44d,7dff4866,f76fb6c4,47e6b40b,a225b484,cda916f3,559e5782,3b519827,8bd7300a,c31dace1,7a797582,2a2e2a31) +,S(cb9a979f,c4e8d887,f03956da,9ac89637,579813b0,c3b27874,82961a54,e54c16a5,ff42bdc3,1a837d98,b7d37a38,db3c74ee,6109e868,d06b7c33,d5562dde,b11ddbf2) +,S(2ccee51c,9d63f3e8,99314da1,656cbb15,635928bd,309cde4b,69699860,c0e28736,dff9a128,adb8b4fb,7bcaa1eb,6bfb390f,226b2ae0,b72443a4,5982d559,91d379eb) +,S(a239538c,c5e0b53e,879f484f,7202a52b,d52d1cdb,ca7ae7d0,639850cd,b2c4f57c,6cc1f9c5,8998e347,2c6db0b8,6b1d9092,d3cd0c84,267bea8e,75a172f9,f4879dd5) +,S(e77796ac,c619974a,63476635,7bb3bf33,6ad1e87e,8496bac3,378db956,7beaee90,3eaa4b63,c9679050,59d8cf67,7b7095c,4064534,1c592ccd,ddb7626c,10586f0c) +,S(52c332cf,37646a2c,c1bf25cd,26a6131c,3b243688,9c44d804,d2762fae,618250c6,2279bab0,a19f78a9,43e695d4,53a0dc3c,f0312987,6ccbb70b,1d61eae1,e92729bb) +,S(d68826da,36e5f78c,bf728468,88bbe6ef,f6e55d34,f8b47a9c,8296e662,4ad9bbb3,88ffeb15,5f70c6ab,9b83f9e8,30e2f449,7e661dac,889803a6,d30a2ddb,11bfca5f) +,S(af92bd8a,2a5b0034,ea074d69,a1d7a517,808d3b61,58f5f7c2,d3fb08e4,eb825cf3,2fef9245,a4a3c837,d4b57ded,52009294,c077a801,8f633313,b6db2d4c,92c724b7) +,S(df86fa3f,63d95d73,98872011,c7545b3c,f5f27fc6,a821bff4,5d09afd1,bf76d895,a891e766,12953c4f,37a463c5,ce449574,b1906c63,c192ba4c,67f4f78e,d1e93a35) +,S(a049a35e,119e27f6,e272774e,f470ca50,9a1da9b,a4e5d781,6e64a13a,23383c24,4cb8e2eb,ccc82ca4,a2f82841,34eb3a05,f85a2335,a3b1b117,92886029,96fb3fd6) +,S(b3193cbb,f3c8f3b0,b47b1a0e,5689461a,8da801c2,4c8d51ab,fc2e67b,1d9f331,2032a290,3f0cf0ad,21b63de1,565170a3,edee470,a4dbbabe,5f3d459a,3827c7ff) +,S(ff3cd387,554fb3a,89142ff7,3e97fdd8,884964bb,2f457283,e45b79ae,ef1d692d,24475b62,c1ade1b0,ba36ad93,27916e19,637071c,22fb59c1,f2108fb8,d38ec5b2) +,S(c095d24c,42b058d,c2f77e2b,463a2c7f,1ddd1dae,dd6f6111,11ba78db,26763204,d2648519,61974d6c,cf66de22,1028943d,ceccb181,ae03cd38,fb5aec22,fae54326) +,S(5365a446,389f54dd,8279826c,e1e7df5d,b4a9699d,b8208efe,80d1eff,2d883ee,74625a49,b7856c1f,b157776c,cd79270a,2957862c,a437bfc8,75986264,401e714e) +,S(4c073085,e96134b7,75248412,c36b3b33,77afa275,24c83369,a2477b8c,9851f15e,fed40d9f,a44f64b1,59c290e1,63d1add6,92bd2782,51de71db,e302cbfa,67e508aa) +,S(71edf152,ab95a066,2b7e5190,8af75f38,d03d27b0,3a3b6607,4f472b7,706a3114,c3e6f145,dad44a3d,5cf056d6,2c608b4c,840608bb,aa15a101,c9bd3cca,e511741d) +,S(1b7d41a9,3cba67ad,c145962e,7b2c6353,bfbc8eed,34eb4c27,bfc181d3,1ac0a802,b165e7e4,23c5d880,1bc3bd1,ee0c6778,50986b35,9dbad06e,aabb2f57,dbe553bf) +,S(ce997626,cb41ab98,58f591ca,c89f7a73,bc1df836,716ee74c,45c4c781,eef4ccc9,be76f81f,a8e4b053,f63be23a,5e72ad6b,7aa359aa,e9407b60,98bdcadf,e367b167) +,S(5b0cfa70,aeccd544,cd634d10,a2bcccdc,33e4525a,54259ba9,92c40100,698bbf2f,ec50e655,163994b6,4881369f,b3aab550,65df1a5b,dc6037a7,7c01e56,904660d2) +,S(a03873b9,695ee82a,42b72a90,f0cdfc68,dbedbd2e,a50d5ff6,e120d811,ce8d5097,5947c8e3,56e64f71,b36fc1f7,7ecfc7f,a31c0f0b,cbb05102,775648bc,f2435758) +,S(d6b91cc6,6dd31e59,f04c6e58,bd7448a3,fac62753,68579214,11a8b42c,66084ed1,fec7fa6d,778c0b63,e7dfd72f,ef044da0,903ccfc7,1786f0b1,85edd004,f691a0f2) +,S(896a1313,e0a96d35,9fd42841,7790baef,a40647cc,f56264a,ac3b72df,687b5692,831d4b47,52f5fcd3,4942ca26,95dc86d8,4fe49c73,7c2bd46a,f892eef7,304117e6) +,S(779e7400,8e564167,56795a4f,9d2021b7,94aa9689,eaa37780,8e3a6061,b5bdc04d,739ea3a9,4f38be31,df57c052,362d1872,333d2777,c6704c2,e69271d2,9f78b123) +,S(f20988a9,3a3273a5,a015866a,c4de930e,507b5b48,cc5ba52f,a2a71e9c,185e72a5,6c861907,8fadd612,c0535163,dfa4cf39,648b59d6,4b056bb0,4e06695b,3b51213a) +,S(7e8520e2,3151c78f,9f48bd10,5aff4087,dd90f9c4,2ac33e24,19499ab6,8e5b21aa,995827b,43c276dd,61403388,27b2fb9d,9fbb46ec,af10b65a,a8025971,608f38c9) +,S(98f0e4b0,9e72ec0f,d80ce3ad,eab29913,fe84fa49,1786bd79,7f6832cd,7ed4dc6a,58c42bdd,7ca43579,b45df8f,b2a6db3d,41f75a3f,89dfab0e,e000383,c9e04a54) +,S(31cf38d3,dec1162e,e75eeac6,6827aad,22fa3ee9,abfda002,b6956600,6fe596ec,ceeb4b04,fc6c31e7,7a6260ca,bdf92569,92841221,d60ca74e,81309472,8fff4442) +,S(60766d5b,50cc4d46,a1234c92,1baeec1d,29900e23,4493f174,2f06ada3,ed9dfbea,13debdc8,9795f421,6f796a53,74b87aaa,bca4f73e,fda2ecf,7d151870,179c44a4) +,S(1b0ebbaa,35e8ecb5,a76d9c30,ab88fa10,b211ce3,e7c2b428,117645b6,881c7895,a312adef,e1c4a34c,d9f75d10,bb2ceb29,79184181,bb955439,e317cde4,202b2f83) +,S(b3129f71,c3438602,c9c24ee3,2f997341,26dbd76c,60cf7713,200ffb68,e486fc94,bd4beeb5,70966285,6a15002e,a25046cf,996a1cc7,9a570549,467ac179,b4f145f9) +,S(2925ca17,662f0905,3927d40f,f2fdee1f,66cc5c13,c3587e78,fe48effc,40cc075f,6d37757e,64f0438d,7bfb3658,5df58dbe,a8ab8cdd,89871670,dbe221b7,4c416185) +,S(8d55b85e,fce6bd0f,ff8906d1,6497d35e,4b69e701,da7845f2,aec1a049,39c9ec45,435416dd,9fd01388,b717ba9a,df574456,785cc0fa,c115dc04,8a242270,4a3c77dd) +,S(a660a9bd,b419e19b,16823b5e,dc3fcdde,f1021b71,4debd17a,9a0619a3,aabc23c9,ef6d4bbc,e963bb1c,2edffa5c,ef70e330,bddccb4b,3b23cc52,d5b4a689,e0c76c32) +,S(8896427f,c92bdbfd,59699ec2,222b4bbf,2198e160,94945c77,1f207bbe,4cdd6b0b,bc6081fa,abd2df26,b087acbd,a2c67c63,2eb1a8dd,6fae2454,6f3fa747,be421ff1) +,S(47e5d9b2,3f429484,61ee9f38,2f14babb,f93e318f,32d67063,ed20e917,9894e993,bd17f8b5,6084d3f6,62facae,24e93e3e,29205f21,68903ade,4f7476a5,ba70e8b1) +,S(ff352870,69bf1131,6f530ef3,b32a487b,3f11e6e,f8518c15,b1202a18,4e6d5487,8920338,ccf36f98,4afde38e,1a74528e,86fddfc7,8d7a6964,cad4286f,231462b6) +,S(2a713d8f,eca88def,b5fda7f8,8de9c6cf,9b97bf0,4c070173,aa47dad9,197bae2d,5ba64900,f7d18ec6,8887bd26,d2769b0,26d22e96,1007b58c,b27b8983,a6e7adb1) +,S(853d813d,3133ed7d,a85065a5,755ca0c5,3f32f156,154853b4,b018668c,b165ace1,fda8017,e00d20db,6ee4c0a,5790b504,afc376ad,170d74bc,1261abcd,241ea020) +,S(d5c4dc15,37b048d8,6631fd14,7d896d6f,f403ceda,7de8883e,1ccc006b,6d9ccd99,9ea2829e,64213434,eaaaadc,43ed10b8,28e706a,5001d7df,47146058,8bffa8ed) +,S(f649da82,d50fa298,8c598d5c,caf1e7f7,2bde2cc8,8073b55a,2e43b6e7,5d44905e,4438f4cb,d3e1938a,b461b1e7,b94d8f6a,c6e287e2,50d06da6,67aacb1c,609bb6cb) +,S(adc3515d,4fb7776c,b1592a69,13254d7,afcb20bb,8a4d7529,7ddba70a,c35a7193,49b7bd8b,3f280916,c6024e46,afb45e6b,da5bb15f,3d3497fc,85e9a46f,acec3d80) +,S(d78c46f2,603a00df,b45d0495,c1e2b346,963dc82b,84512cac,c2227acb,383f75ed,76b02870,2e7a3da8,79272759,1e2f81ef,54ed02f,debde8b5,38f9ff1e,4335a21f) +,S(13904467,59e0fc27,c2a499ec,384e0906,bf293dcf,c13ca16f,d3bedfda,d320e466,5320c884,b74bcdc8,6e0c21f5,40c16f65,dc61f19e,9ec5e8ef,385fb637,ee7a3701) +,S(93700603,543ec558,3fe48141,310b184,aa8faa04,6058467c,389c10f3,b98c42f0,8e0acf55,bfc585df,4f8cae06,131753ee,23a7bcca,68354182,61450e1d,e1a136ce) +,S(bdcb9434,4c556618,a247c935,29c5ba74,c68f25ea,a5507148,1431c00d,6926884a,c29b7b1b,ad6ec5a8,e7046cf7,cdf99c6d,15f6a3e4,3c6ce718,9ae2acbd,531bb17a) +,S(839ac85a,9337818a,b07b5611,f67eb16,6342c1a6,8aadefc4,6842c023,336afb08,88b30690,e79fb157,3e424c80,75bc810a,fb9d57de,5464a253,79d06222,ea656b69) +,S(2959c32e,bcf9289,9882e003,c8a28e71,3d491402,4d24d878,ba8bed88,47b949c,ba2643c3,95fac027,6b7c55e4,d2d2f530,318665f1,ec2065d6,eaf32c05,123e04c0) +,S(71116eb0,5def3abf,bff3e235,a0306605,b18aa465,b47167b4,4eb3486c,c442f3aa,2652a726,35be8336,f9b51607,76b3af84,26a23716,871fa64c,898520eb,822d6630) +,S(400c1bcb,dd3e3978,3ca06e8c,2abe8b0b,9b45034,a1655cde,fb748ef4,e2a477af,1471c86c,c8b27b48,1d4c45d,1533a5c8,d46fc3cb,ea4788d6,c48dbdad,6f7670e3) +,S(2a4abe28,5cf94456,aa92216a,dd635abe,71a7e825,712d775f,d61fdc98,a4c9288f,3c0d2483,3d6ffcad,b471d234,4ee8d07,15c09719,b18cb581,8ede730,35d89c15) +,S(cb0113a,1832843f,7e32ce25,15b0b23b,8a803ea7,50b500b6,3fb89f6c,e7bb1884,816d7056,b775f13a,cfd94a6,f88f442e,519495a3,6e74d8f8,359a8a03,16583bda) +,S(4d7be7ae,5c4271f6,c1adeb7f,4dac8467,beae22bf,ae00a71b,1e353be9,5ef172fd,cd7e6415,5708d20a,9fc3b0e9,85517642,f677281b,49490439,14845a36,afe6ca56) +,S(bc285658,fd724cfe,e6ec8c7e,35f9197f,e9083bf5,439fd4d8,d9b262bb,7a3c38f3,80c10d7,59f76b4b,8330c96f,38a1af24,1d1b0db7,4e6befc4,4f085180,c1c33729) +,S(a829ee43,221d9955,38ce8aef,e80c49ac,dc6e71f,4293750c,c0585c1,69963f04,144f6b56,d996a18e,627d4c8b,8115b2c1,c369f410,ec8924c1,73382302,3758ba33) +,S(f5450bd7,efc9227b,e7d28ad6,75ee14df,1b2378fd,308e6c5e,68945ac9,a47d82d1,20201fb5,cba463af,cc46e6da,caac8417,63356e64,5cdcfa5d,9d810c48,272cf8e0) +,S(7dcbdb69,46dcf79d,454095f0,b61341e4,45243bc7,c2262817,374fea5,37a1a380,bd2cee4d,c7ebc71b,46fb3bec,bd6787eb,d2be3128,703a884d,98359c5a,43875977) +,S(f1d6c1db,cc8d33d4,fbff821c,8c788d06,2d906063,2f44a786,585a6526,20ce776a,3696a3c,8473bd07,76e77226,8cd09f96,3dbcd143,e631c32d,5d83254,ada29340) +,S(f1688e1a,d5df4e43,67caec6,f2234534,f65aac3b,79a94ca,32a786bb,9fee4b49,efb620b8,e2164685,c9a3837b,5c6eb70d,759824,96541aed,eb80aebe,4193e34e) +,S(b639e284,3ecffb0f,66c2819c,73787e10,527086e2,5d3da074,e037a915,e06a5813,61fde1dd,63ff304c,8ec99d4,67ffbabe,e8000637,b9856bec,344b825a,4f198407) +,S(11a4ff89,d5e63ec8,6a0ce18,53dde8a8,875c9a9b,f563526b,cd25b830,6e3314dd,9f7ec77c,9a3f88cb,7f64b1ca,f2b5c7cb,d70d65d6,dbdba9f2,68832f3c,a2e117a4) +,S(323db783,26abfd99,2b13d67f,3ae01415,77162203,c50322c5,7a7933e8,7d687d3a,92c8a67c,ec834653,d0f1a50e,a7834b38,631d83ec,ee38e50,33ed927f,7e14253b) +,S(2907fe12,c8433ab6,2e6283ec,85b93342,ecf14d16,6d90cfdb,b4061968,aa35170f,160f9790,66291ed7,d51962d4,be02d85f,8a92ff8f,258a9a07,55b8a5ca,2d57c2c2) +,S(67cef7bf,a58519cb,6c5cd8c4,f69d5cc8,84cc77a7,854a4b6e,a40b6dcd,57e43e17,e8071d35,e590dfa7,4d4f4da2,82033f1b,590b9383,70b571ac,ebb3bc11,b9b48482) +,S(81e40522,3d4ccb14,3952867b,b8398cd4,e5ab92c5,d91066b0,d1fdeaed,55c71165,55357564,af12b507,b2e24e6a,425697b9,e6356b82,da36f111,2b5c3394,183c0d10) +,S(4880abe1,47bcc598,a3743304,1afabe99,fc525daa,564c4b05,2aa60c27,5c814628,b6d944f1,ec69e7bf,2cdcf621,864ba76,a1df44a7,ed15ae15,290ddbe5,b91f585e) +,S(fa2bc507,19131dc7,d5f23fe6,9e60377e,2d2f11c7,f8a9a451,82aa69e6,24eef53e,9b0f2017,5f287d80,41f58930,6cd022e5,9b63bab5,1b26abfe,1a295ac3,46a2e9fc) +,S(aaa18fe1,25e781a8,901ac351,38d2bffa,83cf7c3c,99a4c7d8,54b30c70,c9483e8,6a8f9e1e,a40f6383,6008a0c3,596f7644,c044bf53,9700a142,ec5e3c97,c075b03c) +,S(d473950a,8465711f,71a6f1f0,22f4bfcc,1c16ba81,4bf73c2c,1eca244a,da4999f1,6eccf9c8,aafb09df,46ca0d36,ee9028dd,1df62bdc,6ade77b8,a5d410d1,a69bc775) +,S(d7e2b17c,f8e1895c,cf9fb163,b56f4be8,ad99133f,f00f2ce8,8ce911d3,3b8e36cc,b6557693,ed9371ce,69bf397b,56c0b566,21d38958,ebdc0b96,ca488570,1561e6bc) +,S(3f1e73f2,a2192809,acaecea1,71d175af,683e796,e1337db2,11b6b34,8ba924f0,a593bd94,96308bb7,76b63703,bc11e30a,c5f01c17,c8b9748f,3b4c8015,56f52c3f) +,S(4cbb68b4,27899c92,1c0d969c,94341d8d,161f3b8b,3fe4cfca,2b583a63,eb383dd2,6b3c29d4,97728ac7,b45cf7ce,ea618789,95935bea,bd146e1,6c756f61,4698b6cb) +,S(e41b826b,52ff9bea,354af41e,3004b7b9,edd01e13,8cbd466c,ba4cbab8,d63bb4e0,75d5b642,47388aa1,51d4d8d5,2568a804,fcf66ba2,42b3f56b,dee0350d,ecc527ed) +,S(d508dd5b,ec38f795,88bf2d9b,6bcc9f8,aa96689e,91c1381b,9f8db311,94588028,9b144547,1a2ee559,6584c927,2d779fa3,123a760d,9faeabfa,1e39d3b5,ddac2595) +,S(5276f127,3bad7149,ee5ff022,2769dd6e,973018e2,a9948070,fdc82148,ac637de0,73f778c2,caca737f,acd3d877,14e24d83,964dd47c,f22915e6,212bfb09,8e804e21) +,S(2e9ebbb5,9d108d21,71d28c27,32af659d,b534cd10,c5457cea,3fcef018,4d7761a,229d20ba,cbf0104f,b385621f,dfe386df,4f40c287,7d956046,60eb3923,46937bff) +,S(ad819539,5b94bb1f,4e60ab85,932b24cf,2c79c20b,79a972bd,db1e4201,c49f1d1f,9226c45f,4d161a1a,c5c3c0ba,a0536def,3c6052a4,ec22dd24,cc803a37,b5d791a1) +,S(f5d4baf3,93ee5acd,944b2057,78cae170,8a622f30,68d3147b,62bef05a,88fee96f,9a187396,9eeba528,9f5fca32,6bbb922,2eeff5f6,6d205a0c,78b77dea,ee17d1db) +,S(1a0f5e1c,b2fb5d01,fbcbfddc,da83693e,9619ea60,1669c728,7710733a,e6ca778c,3074e8d1,61da2d34,38be57cc,fc437742,533e415e,5f0c888b,834a2fe5,5d4fd6bf) +,S(a78f6f7a,110cd16f,99fbe16e,9be52782,248518d8,e621f478,2167887,f81cdae4,e3f78e8d,507f9af8,11653ab8,5f2286dc,db34d9dc,8106e9f0,57610267,411f02a0) +,S(c53e4243,b26ebe40,a1abffdf,3c42129c,47e92cb7,32bd66c0,3d4a4290,c68b1c25,bd4f96b5,b5801b82,300b2132,2c39fd2c,65b2d084,e657ba2d,7db5df15,ab960e34) +,S(a3a1ddc8,56957468,2e9b8a57,50bbc738,f72dc60a,1c09c95e,a6559b2a,736535e4,94887a0f,a4381d9e,dcc4faf5,1525ce98,fc43116d,29f68c99,236e4940,6842a741) +,S(8160ee7f,738f54a0,698806b8,35ed4bca,113bb568,b23fd331,ef5f1cc2,80b6230b,382ff30b,f13f1e28,95a38af3,13fcd099,249b195c,96ac42a6,6a929fc7,a907b17b) +,S(68552ddc,6b219554,dbabd276,e0f2a5d9,33610bcc,776bc40d,7efdc1c6,1b992e35,eee09352,c82dec92,b0ae8d8c,d6918ac6,df620dec,86a0e4ac,abfe8025,52a0ab5e) +,S(919fef57,f308255e,1fa802cb,5acab880,c1810c62,c79a4ecf,c2251a2c,cc02ef51,cb38c163,8f7890f2,d61a980f,ed712ca8,97296366,7927ff7,39de824d,207ab566) +,S(d7e493e2,e2c33635,ee8d22f3,76fa8de9,31ed4eb0,9771746,f48ba201,307e04d1,ff7e6d72,f712f2be,2bfffb43,2764f677,62917509,3cf6bfe5,eb5cb7ce,85c1a8b4) +,S(6b642a8d,f4131ddf,7f31dc9f,c26b96c9,286e1f80,de2af96d,52e383d1,ffa73a41,1e55e667,5f0ee13e,76818c02,ce424d8f,48cbc930,b25dbb85,363019c5,fc29979c) +,S(7ade4aa8,1df8c53d,1e64655f,bfe0ad88,4057e0b2,1c88bb2b,4c8d5f19,34794191,cb0e9802,fbf1027f,dd8d2167,f4f4680c,f9e18f4c,3bc3310a,c4014745,530a06fa) +,S(6d578cb3,1ed19dc,812fd360,a367996b,91a7ba42,7d2f74c3,e2a1721d,72e1c017,4ac9ad2e,aab987ed,dc994b74,733fc710,19301e1,f691999a,5161cb15,ba11e9b4) +,S(df95b5f7,7bb79814,21892d72,743abe4e,828a7544,f9f0e774,b1f5ada7,a054978c,4ccd011f,a966604b,32f70bd6,1a3c1515,c6d1b261,a3ce5c59,7078cc9d,f723b32) +,S(d7392d17,1cf72e1e,ddea0be,a242edf2,c418e9eb,7dcbe1b3,aa07ae7f,a11ef08c,4b696f78,20a9ac8d,a5f52c8e,9d1a39c,bbb3d3d9,fb5b38c8,1b46bcfc,90e869ef) +,S(f01f2aa9,82842315,98f414ae,f87c9d7b,6eaf21be,c4dddea1,3967677f,5d2a1032,7c3be753,da5485bf,13a4cd72,a9e3fbe2,28fc6a22,c502b19d,1b6f7d18,149e2b3e) +,S(cee8f811,4b1829ab,a47e9b5a,54de7cba,1f6edfe,624f30e2,ec4979f8,3145242,4b01f7b4,cebb1125,20bb0ab2,7013af9d,11d19c4,14b0c29f,d142c7d,5b903a09) +,S(f4215bb,973b5586,ec051388,203b1c99,cf69b555,6b1591d2,fc711842,759e9832,5d8a5ce3,ece7c011,df3d414d,e62ecd4,2d716c73,cab02e29,621307e0,658e6fe5) +,S(e39ecc23,90c9464c,32b08759,9a44586a,da09af95,ba8a3b30,2cb015d6,4a49b18a,bd7957c6,e1feb061,f5535231,4f5c5e5e,c8245f28,4638f390,d079cffe,bd2eea7a) +,S(9e6bbe6c,402e4cbf,e298e789,458fa9a6,68cfd407,3efb3d25,4699278,760589,989bf3f,9912b242,419c848c,f82c3fb6,8690ab05,bc23372f,eb9a850f,b4dd44ba) +,S(67504bbf,57824cd9,8a3bd82d,34fcb59,3d20590c,a90b5652,c4ea4695,1f48905d,93ebbf6d,3678478f,56ae5a54,cde812f7,d8d40928,21b5e82,71669dd3,f0b263d3) +,S(4e5bee50,503a28c0,9252b9bc,dd28af66,cecae127,2128e88e,fc431373,7324657d,d6891df5,3a4cdf2a,d7ab610b,817b0f60,c2502442,2e40269,a7da80dd,2672e0f3) +,S(7481d5a5,bef3d397,533e01b3,640b0809,fd6ff946,a1e5481f,b90f0b3d,dd05c21,21ee7275,9c217d19,3999df2b,e3cddff6,fe59f26a,e570e0ae,58868441,f37e342b) +,S(778dff4f,dd32f251,6defcd94,188f2440,26b9f789,ff4eefd5,84b2c15e,2bc61d62,996a2edc,f43e10d6,93cc2d00,c6f4506f,45be1dc5,c762fe20,3dce124e,34e320e0) +,S(cf531271,3d65d471,929f6108,12db63ac,b1c52203,eb879ca4,a8ee9f62,774580,38e28f4c,881391e0,55fa7148,2c92c097,c842dd,74a58d6b,5753d6e1,2f773b19) +,S(99702d01,9420286e,723625b5,62c8152a,2dd5f1a,eff84437,8a182cf4,25582031,8c4af2b2,654f1631,82d08bd6,e7f8b6ca,d5365b9e,d869fd23,e5a3c4d4,7e5990c) +,S(68614c88,6b59c198,c49245c1,e1232cb0,b4bcce31,e0a2aa15,9fb2331d,ff1dce66,49c870bc,7ac78e22,b635c2b9,6f29e641,3b29c6ec,8ec8b3b7,8fa6597c,90180c7c) +,S(f497a9bd,3c0e923d,5d622ab6,afeb9e8b,d9b4525f,d1f30cae,2a44d0b3,e13256b,af4d0273,e088adb0,b7de7724,b387e109,d49d20a6,eceb369c,12e07eb4,f28c9e32) +,S(50a764f7,f5e29cba,ed7ababb,97d2ace2,22c06c65,9ce87d77,83b5bd0d,d165bbbe,4abc57c5,4c9f1d54,e73cead6,d77a85a0,8be25ba0,ce96b8a5,1b4fb460,5eca949c) +,S(fccfe1e1,e312e6a3,92e83cb,97274576,56415255,b127ad54,432c93cf,4ae29bc0,e681795f,d8340902,da0018a0,dbb8a424,870e4bcf,7de95f0e,b2c7e98f,47a46c58) +,S(66de61ba,48c1fd44,80d5c78c,3f06c3e2,45ecaf25,e4c235d5,8408c90,e1b62ed1,bf3bf086,a90221ba,711819d0,d80194c,c45177e2,57b1408e,7e649f15,a92aa6a0) +,S(4373e7ff,e3995503,97bdee9,c9d3d70b,39f47446,45fd3c1,63b2012d,58e148d6,440a1376,16096124,42c7bff3,5f9a8aa2,3ac64e8b,bd5ca839,bd3c5a39,b84e6fe) +,S(c8774ea8,7d83fc06,c36ab357,b1fa76b6,c647cc9c,ebf2e125,3f3ab303,9306ef1d,ccbde78d,2e4d2c0d,ace4e660,efdc4d1f,a1dbb44,4cabb0df,bfe29de3,191f7249) +,S(748cb6cd,c57d89d7,8842fae7,731b1e28,3b59ed18,cb761c88,a4d2e4c1,c3359fc,62f5b6c4,11c72d4d,a412148b,8b038b32,8f98aecf,ece537a7,237b9f87,646b9a3b) +,S(35a83610,30fc10f3,53d2fdbf,cf67655a,91b86555,cd3d9eba,f962996f,ecf55cbf,6fd79f5c,df8093db,5c7f3a94,52dbe6ae,bd1ca410,199deb04,761ffffc,77ec9fec) +,S(cd05bbae,d0a8d78a,2e05e9d4,1c33cbd2,8d59d384,75d42389,43f9cc35,3a8a30c7,9f7336dc,8e77fd55,bd0b9e8f,23eedf1f,d0c16f69,921994db,dc2588dd,ff72a8f8) +,S(da3fe760,2547c831,2d4f515a,5ce530be,29379325,41c6de36,364c4b5d,ead43c58,df60bf1a,d2fca43f,6d482df4,61fc180e,5e3cf692,995bf8c1,7d32a263,730b3ddd) +,S(bbd7996c,25ba5c24,a14742a9,745dd2,8c18a598,8279581b,f8b5958a,8092051,896a39f1,310be1c5,9de4b86c,7c9bde10,8035ba39,864a45a3,69573d16,4afbc2d) +,S(bf7c20dd,64ba5f51,2a996bd,428fdbaa,df1853fb,f814e6c7,a415fb64,a3e16070,afaec0ea,2b18c89,93a1a565,f3db58dc,748df9eb,4d9f8a04,a18cdc23,4710d5c6) +,S(919d0aa8,10928129,cad99b09,85bea5ba,7d4ea114,9f9d5d65,2b6c0e0f,20464903,60d9352b,d053b01c,83caa121,63e8c9a3,e2153cbf,b335943,7a2a788b,7aa02dfb) +,S(5e7c2a9c,6ab8251e,8f8749ab,e0ef107c,aee593e1,a8632a6e,1e0e0c4e,d3cace9c,74186f42,6f03f806,36d79258,e9edf593,6e21e0b2,d882d933,c0241ae9,7d761582) +,S(2815184d,af1e838d,86d63a32,db5339df,24731743,aee62add,21e3a6c2,c2b0b1c0,2a4951e8,3ec61221,b1035c6b,a7d2cbed,f6ef93e8,cff69e01,295e09d9,20e05919) +,S(e3086e36,91432a20,8602458a,87d82955,c8920ca9,fe1c079,3eed878b,282ec3b0,13db4219,50388269,cd591c5c,d8e07ba1,b532f01b,485829e2,aae4f55,f05e4362) +,S(8264d534,2db3261c,d7e294c6,eba040f5,461fb9e7,e3fa13fb,dfcec29c,20f2fa7c,4dc311ff,10b92db6,b67f47ad,86fd74be,24e3dbe0,d6a74842,92f35d9f,6e95eac1) +,S(9edbed6,3c4b66ce,a8c2ac6d,89622d61,6838e1fd,9b93c363,c2bde528,a629b2b,c1706a02,5b1f9419,2dde89fc,63ae2a81,ea015ab2,964beb58,d5ca7ffe,84266644) +,S(68006753,672e9ae0,79fcdee7,9814a904,80c170a7,f644302d,e5de7982,7684e12e,fc1209de,88ca7c3a,614252e3,153df13a,6d0e8db0,4c82d83a,fcbe65a4,5c084398) +,S(acdfba80,9e519114,a11b1634,1835d7e4,5b93a6d4,7094846a,e1ecec00,18bc4531,a4e57d02,51511f2e,5b729309,4c50ebef,4f8d3cb0,d930ff48,20d0623b,d636d664) +,S(978304cb,e99eb899,5ef43f94,c67c471d,6d42ec19,f83f9323,3a44b9f2,e2d13896,ab26782d,2c1dbf16,a90f90c,8e49d250,1e1172f1,3e1bd20a,3deba979,85fcb110) +,S(8c8b561f,9c857510,88478c03,866b347f,46e06801,82482343,923d7e27,c67f49e8,e7908d27,79cc5b19,dd00f2f0,4ab52474,5c35cd6d,4b85932c,99614fdc,64048cc4) +,S(d4a7ebc1,987b1abb,5d02e598,190f73a,36d1176,d7f0f7a8,cb9491c1,b86a3c55,4f321dec,9c1832e3,b0d0c974,798834ab,6a410bfb,398ebf58,177f39a2,22ba4e50) +,S(14bbfb6e,7910f522,69e544f2,ad3175d2,3a36b7aa,8209c24d,1fbb4277,9508c261,d16147c7,2a1df442,d8e831e5,aecd54c6,8bc3f225,4d0f51e4,9a375053,73e8d08) +,S(d24ad71e,81de43d5,7096e101,6bd4d99a,46e52e56,782d99ee,838217a0,dfea0f5b,ae574f68,e07cead9,f214976,67a18c2f,fbbcbddf,2bfb6c95,3b7ba673,7d08903b) +,S(ac96889a,f0b46b7,6896b763,8e1a13f3,dd24459e,8601f892,c3367c7d,8b52931a,b68a8631,8672c378,d99b0b20,44b06190,876ab100,eadb12e6,c16c2ba7,c1ee2381) +,S(36b4da52,4f4ad5da,d7396445,1e79bd5c,20973df0,efa82bb2,da4bf68c,55afeeb7,5cb7598b,576f0db4,db1093c5,e6c9723c,f493bb91,450a0017,9f79c8e9,92dd6136) +,S(98c7bc3a,7054f928,d062ae65,b4140dd6,293f2fb6,cd16fbba,e00d39d0,b11befd2,82d134ac,3e614e4e,62b1b475,bbb5fd80,a5e6d3e4,e4572dc5,7cb666c9,a06131da) +,S(95bb18cd,991cdf72,1c627d62,aee4655e,aaed0b6a,b1e64537,fa89a0ac,f60b4a52,c37e37ee,5b87a5a5,e61824a3,ea519f03,dc3b0a77,f755485,d337ac79,f1f9e8c9) +,S(41e45ca2,b88a4679,6df9106b,c8b53180,81674c34,9646545,e5ad9b6d,e5f6cdc6,151ba666,b0fdb7a7,18110f62,83e3cb8f,8e40fb8b,fa1a1854,75958a3b,ec10d197) +,S(32d15f16,dda923d5,c2f1bf5c,9c003b33,b77d2450,95e5ad31,2ec62956,ae092805,58d64c72,96ba6976,d61774f,f37a0d1,6316cd19,3ac0d930,bdcf4924,cd904095) +,S(41c4e029,817de516,8dc04b2a,9bde3850,7ae48602,dab08db0,3272c694,6cf099eb,303738a8,7b888601,2f9e2053,5bb8b610,92f6222e,96968afb,98940d85,98181458) +,S(28b8ccf,b14a86a1,84fc3c3c,a6a7dbd8,763415,91a67d8b,4109f026,1dd964c5,899f98fd,5e0c59be,69150d8c,5a917d6e,864fa15c,63072769,f75f6353,8cb276e6) +,S(f2776367,762d6468,c9cc0e38,d3921813,16dd394c,eaeea519,786b4353,a5044586,1a873421,1b170183,a117e420,c41d2725,84acf219,a415778a,4eb0c34b,bee9a68c) +,S(7a1a5f53,6e96ee57,e10b1337,6bb1e895,d0703c6,5adfa4bd,f24937da,98bd7144,860921d5,67fbdd1f,11aa3ced,103453af,8c3f5037,b92ff10b,ee70ddc,e4323206) +,S(d82e79dc,5d6de6ff,8863e039,60401bd1,610500f1,57fd2b41,f20689d8,889c3f76,f1947dc2,ca625df3,af5ec97d,32e62c09,2139d108,948795ba,5cb164b9,351bbf34) +,S(6a2e184c,23ee235f,93f036c4,3875db01,22416a6d,26ef54bd,85a2b465,defd0351,6c44297d,724eb2d3,2f58a197,2f52a7ad,ee49d30f,c8f8424d,7f26c6e1,73dc6868) +,S(ea0d5281,bd1417c7,2dbedbd4,dff37c49,bf143417,d2a40dc2,573b4b3b,2ccddcde,c7a35ef7,685faf18,c5a4cfcb,2eca27b7,46b21d65,ed71aae9,15185cc2,6d2b54ee) +,S(d5432c9f,8ed0b4a4,c3e42dd8,28098f13,11d2cdf3,94672331,51fddbf2,a6030974,1e047ebb,8cc01a43,2ee6ea04,578513aa,17ad2bef,7fc7653e,936b2d22,bf8f6c3) +,S(c99ee053,655c9d53,1fdd2298,3cc03756,299f47bb,5e1d0a4,d7b861fa,c3b5e332,61c5187e,4e12f8fc,617a5fd8,746f28c3,368b6b19,1189172d,8c56e2f4,679f6b7a) +,S(f41ee431,170be2d7,fd488c3f,5f21f3f3,aae5e501,1a3c4ebe,d0f6db8f,63e11e55,f767b289,118391c4,4d27c1e0,76b7c70d,110cb938,e9c5c62f,1af200ad,7e9976cc) +,S(505a65a4,29388bcd,55561f5e,fb3090b2,2d553bac,2f8cee97,6c0685da,40006e41,c72c9e86,6b4de925,3d463d7,e7bcf7d3,d6e7c351,1fe6c4b4,7fc436f6,d793e0ae) +,S(ca34be0d,48bc2931,cabe71d7,9cd2bc23,ffa928a,5d532d67,f3665acd,375dc01e,263008ca,4dcf002f,8fdd580a,65701694,bf4530e8,baa0438d,b77ec246,75b4db4c) +,S(d52c25e,9a76600,b16dfa93,cf9c2df3,38c806a7,d8cff18a,1d262662,5fed6d7,80309810,6055c3a4,d5d1e5ac,945aa815,bb8ca3ed,10b5d54f,156e4336,39c4ac77) +,S(83e43bbe,62e39426,a0a74ef3,831cb4d2,776d7ea3,d5a2d57a,8280bae6,ae0bd8d7,a1c2c1b4,ea1140c8,cb4ec2a6,98a3f727,666eaf81,1ae9b89a,9e09db39,d1a257d2) +,S(12326a97,ad8dbe89,3181d76c,6d7507e2,74d62cca,1f0a3517,30e9ddd7,198de84f,79e7823e,7cfa4df0,bb31e9dc,ac415297,edc6e061,4fca2f18,1ac7fd46,d27fff48) +,S(1ad3375e,c82aa917,88bd787c,37fef8a0,2071509e,aef62e8a,dd5c5e4c,b096cea4,f9f9f10e,efc1fa79,454c6d55,b894d65b,ff5c445b,f4e9e46b,8c82a4c2,a94d5a71) +,S(8e8bf9c3,a752258c,278bcf19,7aeebae6,fcc198f9,2310b13d,d114c1a7,d10fd2c9,e2f41d5,b7d94378,5f61f572,763e6e88,df7b321e,9baf0445,482d9f22,f1160195) +,S(c44cd33a,144e2926,b7ebfb93,d7d9ab56,3888f6d2,694efbbf,a5665e10,f6e0ff7,c2d4afed,f77c22d2,88f9cf38,a057df90,baae8ca3,1e074d11,bb8f89f4,e9e1bf4b) +,S(b960f0cc,bd7d3431,4138accd,aadc2efa,d5b60071,7c69f1c5,92900a40,ea68b24a,e0cbda14,801794eb,19401935,3f8ab80a,f525b8eb,2b64e5ee,62afaa5a,da4680b1) +,S(f7104560,8fe120fe,5d036260,5bc3de58,76e24b6,20684413,a440cf56,6520559b,2e208f0f,fea3f78a,9a283f9a,6b601ce,db4df4b,b2fda7b6,306dc8b7,3d514f35) +,S(83a31aa2,cb10fc14,ca8cb2cd,b21cc163,41cc9862,67a5f1cb,75f3f90e,1a92c59c,be18918,400a6e32,b4fa3469,ea6e3613,251ceabb,29cbbfaf,2c16af07,fc5413ac) +,S(3d7b800f,8802e521,341f83a5,efdb355a,b60669d0,adc15531,72c62097,8106f6ab,f9b179a3,aae98427,e02d4f00,89b3cee7,250e30e5,ed72d59c,198d5ae7,1d639e72) +,S(7bef4e27,9064400c,48d4f27a,a754deaf,8af74b10,d5dfc497,98c38216,803f50e8,bab0d71f,d02c67e6,b274693f,6a4f402f,831aa4a3,5fd83014,fb07c5c2,e62d561d) +,S(e6b2c83f,2a6ea201,f56a024c,482a8076,2f2053b4,2e4d2901,4a5178d2,3361bcc,75d1f7b5,209cafe4,f98e63ac,53052a40,487b3390,e4ab73eb,ac63acb5,cc3dc88c) +,S(eb4f3b95,f12c16a8,e5e13446,d9b8ca7e,92c56bdf,565aa4f9,bc1c47af,914fd145,e3776908,e3f3228b,ba0c0523,7eaf1963,1835797b,ffd7eff5,61b30fb3,9fcd6307) +,S(e2926c0a,858b9732,82c1b34b,4c4ba4b0,3099797d,d29c5fb7,4447f28d,ff962e54,2730f3b,e59e862b,37ac50,e5375d08,920cb62,b87ee8d2,f5ec9975,886359e2) +,S(8bf4efd6,c11d7251,b06a5e08,99ff2e80,349f8022,387f3200,6d9de060,bfbf3f68,5514395,457848e,a79ba6c4,39a7c151,b497751a,a4a1784f,114686e,e351afb) +,S(4ea97c1b,920d2ec5,3c2182ce,d6f7e1f3,df49e673,1a14ecd7,d67aba0f,fd077c78,5e958afc,d3894757,e0aa89ed,ba26e035,f06e4b11,da13675e,29d382c7,b21fa9e) +,S(1b12e81,3c7c19be,18576f93,69d938f4,bc81bbfd,7e9eb443,cf2b9ef2,b8e2b3ee,47220a1f,718c36af,8eb8a9e7,ecee3899,ddc49127,91421438,8760d6d1,699a5ad1) +,S(7c6c144d,4f839904,ba40fba8,b739913,54f40bf0,f5810329,c4e3b961,ee6a101d,6eebb976,3ceae5f4,f1ef2473,a50b795b,a6375c72,df67d15,f310b5ca,9706b5eb) +,S(ec637ec6,bea71803,2bae7631,9227ae58,9581d3a7,131323ec,35f0d9fa,27a3e285,c12b830f,f273fe72,4f3bfdef,4279ce4a,8ae6d0a6,de5cbad2,b0a7b4ab,643c79db) +,S(33c8d6fc,d2b37103,2426910,6b9adb76,6c76f788,9627a9,6807572,e0af0f84,b3f01db0,7ed82f45,252d494c,af735e6d,3934ff78,c89c57e6,6c42a663,e5d6a792) +,S(35ee32e5,f7204f0d,d48b1a80,cea0a418,1d71205e,c373827b,2afc25eb,e3ab7e20,d57bc815,684adacc,756291c6,87d0eab1,63067976,a7c3a2a1,98ef1d8e,bad12935) +,S(97362395,200d807e,623826e8,3bdfa37b,e98793fd,6d7057f6,370720b7,5089a6b0,c908e9de,cd1d54a,172973b9,1706fc6c,c3367d75,2216c2d8,1085dffa,5627f06b) +,S(bd37e01,eb944b32,b379b195,16256ad7,4061760e,4eb44361,5e8e5fd4,34eae9a,dadb545e,2a613e54,6067cb6c,179fbdf6,d94b7b8b,c799adef,391b2957,2b93f57) +,S(b332b57a,4f070d20,35986e86,d82cc6f,7180293,53bd360f,d3f883fd,68e9c5ef,eebd3a05,933526ab,ba9e63f8,cb24ffa8,550e50d6,8cc7a4bf,215c551,ab89832b) +,S(fe5bf27f,9459e640,7489bb32,2012d1d1,69d40635,74dc05bd,6bdd6c38,cffb61a3,72c6318a,3775b8fc,5c790d6e,31bbfddc,7ee07a71,93e5f137,e3c3e098,bae25da9) +,S(f27cbe27,ed93086b,517c5859,9929310c,ad0e05fd,482f1fc3,af041852,c63a2a23,cce74e61,4e14bd09,8f11674f,23e30be6,b3276f4c,f85dedea,b3cbfa49,5a716e4) +,S(b328535,1a1b22cc,51b7a590,3582dc27,518bbfa7,410dc36c,e63da663,daa8693a,1b260487,7d3ad6e3,db75a0b5,d6b89df,df507809,c203b4c4,cb0712ce,ae2e3d2f) +,S(bb47bb09,70dae4b5,4f4c3aa4,ad4c966,ae42691e,ae39f1ea,a6711d6b,5f04b81e,2edfe19b,b52b7b0,2b4cf349,aeeeab0f,67524375,7f35b6e7,b920d343,e71561d2) +,S(fb6c9735,d4333142,5bf6ad83,50c7241d,b82e35a2,9cbafa37,d822304a,c1b3dd02,946a7ec7,1e0e6dd,a4d4c315,2a6e7489,8671dcb6,8a219781,3e2491a7,6a9e3357) +,S(c711f224,40cb6e74,a60509ec,23daa2d9,fbca44aa,9a093475,524e31e5,43575a3b,e4259800,352d0d79,c5e22d3e,2bf59f4d,e4b42484,68d15c47,ab5a9cbf,854294b2) +,S(9c748d45,a07e141c,639ef97e,8887ccc3,aa84bdc,ca0618ff,4f43b1bc,7496c83f,3dab775e,c3001657,e71a9d46,bf8cc120,9a74b9d5,1025f97c,4dbb9457,e932b5b4) +,S(9d5e6479,81a9278,6db60938,4a462621,23070938,d50e1bed,8df9474d,bee12513,30f2517c,6ff04eb8,9a6ef21,e4ff33b8,e14567ef,e38871bd,b9dba6d5,584c8b0e) +,S(4d24d6e8,91644ed6,ac1aa619,f9eb2b58,a9932c5b,3e8c82cb,589694d0,14b1d472,6ef1a21a,9dcba4d6,850e6593,3ee1a259,91203278,2f478fae,cda13d6e,5abdab22) +,S(fa226c4,36b389c4,50143041,da93c906,70258092,a8de85cb,d20a0dcd,284bc808,524d2992,655c77bb,59258257,5db3d663,a7a345f2,85572ff6,e9dd1dd3,21bebf6a) +,S(d4e659a8,e9af7543,2d9ec769,5dda0371,7bd79ff1,9ba73f07,ad0bf13a,45ad3b77,5f4a2de8,db9814f9,9b73ec63,6c77f847,1aa48356,ff67c8f8,3f0b6aaf,1ac7ba9e) +,S(157b6da0,1556b23f,b6c46b06,145727c0,21d6e573,782bcded,d594ae46,598df23,737d45d5,2c247718,e720fed0,56352768,ce111425,72730890,5a84a545,c53c560b) +,S(d97a6087,19c8572a,78b73938,5479e4bc,9a2b249e,a4f064a4,550ce127,fc4bd45e,f11e233a,75ba1651,144368b9,55bd4dd0,f4ba1f2d,2d0bce2e,82315e5b,78e0d76e) +,S(d2fdeec2,9b5f4ef6,374c2b87,57e4867b,d2e036d8,964a2ae,15632ca4,6f79a294,2d2c1502,a935f5b5,960abbda,9db42aea,c9f58f0a,bfaccddd,f8d59881,e2953872) +,S(fbc6a2b1,b3c0b039,9abc55fa,835bbeba,b0461db,41f3d9f3,160d0154,72861b3d,54421d5e,a5ed3abe,f22df1a7,26a2b5da,a298b41d,acc69bd5,a72952a2,13f928c4) +,S(7ac224b,cf7efd8d,b214db6,a6601d51,829d57d7,28c4c3cc,398ba57f,5079bf99,edf12fdb,9e281367,5e7df40b,1cc3c572,55213edd,c0fa07b,4e3f750d,36d6935c) +,S(f2bc4452,4af39f04,afb480c2,f7addb57,a04db86c,3691b26a,922b6ce5,a1724d9a,63c372e2,4a659127,ace8f54d,33969635,1d890dbf,7e2a31c4,251352ed,53c3a0bf) +,S(5ac48ffd,bf27b452,ca37dbdf,83f2fe6d,8f704040,f3a56180,ab991228,a74ad88c,c7ccab4a,e859e7bd,982310ff,2b7eb408,678b6f21,f52ebea8,41021f3d,fab6f091) +,S(daa3d659,a4defb4d,3291a16a,d669a43e,b6891e90,dbe0147f,568b650d,1213750a,af36d811,9ce1ff85,5dd637a3,bd475b10,50216093,aedf5f24,2c98da62,29bdcdbf) +,S(381d3791,30d4beaf,aed138d1,4072bbcc,b8d71d6,dbb13226,ff168f64,3bf55d37,fbfd7b62,3ce32a4,4335682c,d5ccd4b4,aa4430ce,d8fe3d34,9582bba,fedaf9c) +,S(757c7b23,ff6b6ecc,51ac84e6,26ed70ce,4e6e5c74,e4b65f3c,fd17c304,e19b1ccf,56848ab7,f814a047,2bd286f6,b386af5d,34b27c4e,a3ece71,f153dcc7,7e4027b8) +,S(ea498d11,ca35804c,d6103185,ae468bec,6c2f4f6d,ab025173,b1de4027,551b913,ee939bff,8d30bf5,9e3341e3,58acab90,17de8fb6,e2977847,f4322ceb,ca8829c6) +,S(9d119046,59ea5dff,30105d1b,5ee3f8dc,c9291bef,15844057,66e07d44,72ee1418,45355041,4d4715d,e8c087d4,f05b5f8b,a424ac3,49b3ceba,bf806b9c,e657e139) +,S(97bce776,90f8790f,e7d82b68,b7dc1b38,f3baded3,f7c67655,1894fc4f,cd1b834c,fcc18c2b,4f743ca0,e00f4b34,509fc237,c030b689,83451d5f,e7407b81,ed04f7b4) +,S(5339f056,abeb4926,f46dce7,3b8d735e,c6e9c4a3,2057c22a,49c86400,f15d7ed9,5be6a0b9,37e26dd9,f6db74a7,74fa10d2,cbae30f6,bdfafb,dfa2922c,58a8e37e) +,S(27f22d01,4dc5d3,162f39c9,7de3ef62,f2275b5e,cc6d5e32,6ab064ad,f762a446,6aebbb58,d671179,d712926e,d56cd280,8393fd85,dee45558,300a0f8a,a2986f09) +,S(94af2fff,61741cf2,5f158308,e7333e3f,678bf1ee,56adfd56,629312e2,2435f9d5,33a7269,79df6672,b13198f7,e674330,806f2dd9,50d8e82,1774f381,d9ec24d6) +,S(ae8a0e18,486273a5,36d526ee,3974031f,f3ed095b,a6835a68,2e943dc7,e19b37e4,23c2a51f,69df1826,9b21413e,505c0785,576fbc84,acbb2812,fda146c7,f5e8c8c) +,S(623fb527,d3d99023,9f720cbc,64478e0e,a0b84b28,5c0c3f3f,107b3e3d,7dc430aa,3ea48a8,d1eb543e,ade4a55a,f909e62,14e47d26,9471dbf,4d98a3e0,39c72849) +,S(1ff42295,d85e98be,f7aa84c4,47ec854,29f01b4e,c87371f2,b2025ba7,1e31a768,d9500f9,6e8c697,7ecc51d5,7bb7dfd1,3cc97017,58bb4196,b0b11d1b,3c24937) +,S(bc808b0b,67bedaeb,2e7a4bc0,d328efbb,1ff35dc3,b51716ca,3e501a3f,956aed3f,6af0de4b,26a6378e,6d86378d,d1f54243,929c37ee,d5c10bbd,86b80c3,ead8e545) +,S(e8ab92e0,17a9e956,354203b5,5d7b15fb,acc666a2,79158016,33a91865,b5bb46af,3e87cbd3,66926e66,3f5faa,426a9db9,811a9db4,de3a4bd8,79073b7f,c1e3197e) +,S(a7bf0061,c383040b,6e89ba95,b57102ae,2c291ad6,72bb5027,3c27fcd,f90613ec,79ac8ff2,4bbc79cf,431f4159,4852ad4e,2f0a9f86,ca72ac11,9d4e3fdf,8746539f) +,S(6841bcc7,22b705e2,759ba4e6,83d6b83a,19ee6b4a,375b38f4,5722474c,ca41894c,dac48021,5c168519,d147a966,451dd63,7838d236,5667803e,80658faa,1029a7e) +,S(d67e6d5e,a1606817,512f1db3,9033829f,69089a41,902189c5,20f0202b,8511479f,9cb4a747,7224f93a,8447152a,9fdf4c92,36a1b698,2e9196b5,a4355715,b9fd6ee9) +,S(61b3a7a0,53c477b9,e03d0a96,8ba38de0,b02e42df,162a13fe,8ad538c2,840eed06,94c07520,fa19457e,8d98fdbd,d9a9bf93,57642cd8,1b48fa58,b4b14a89,cb6142ce) +,S(cbd26d0e,a00f7dd,4b0b26ba,7358b2c7,587e233c,3a13c86a,d5022ecf,c865e4ba,50e832c9,d84ff55b,7ba79035,559bc889,53700622,59dec3cd,8b3eda3f,1f2b6e67) +,S(17a6f57e,d3d729d,c5ec018e,1b69394b,1ed78e59,6c7a5e31,bfe5dc43,f9c67e56,34f16cdb,c23e46e6,bda5db2,7538d7e1,f66751de,3eb05543,96c66a54,36bdfe9b) +,S(eaeb62d,93fa13e1,ff9d9a4,9eda40ce,dd6006e5,ced0e8b8,c02f7ab9,98f06f31,7e225365,b4b39204,b01c8890,4476c141,1c166f75,1726718,8ad917c4,9a719ad3) +,S(d09999b6,c35d5d71,55605a17,e7f82d3c,dd8d68ce,9be252e6,99493031,a39c7487,9165e761,8dfec3d7,cf733fcc,e548f672,362637aa,8687f47c,b1eb5c18,a780b061) +,S(2b4cf8d,7fb166d8,a6931bce,e67f580,870c61c7,635632a0,71166fc7,4a11c693,7974e2d5,164771d5,2e7a121e,2b015565,b3a874d,d6313721,ec69d3aa,b44d473e) +,S(d5c0045f,a411cdea,470d85a6,66aafa44,49ed682f,a1903c5b,c9594d19,5cbebea6,ffeebc77,5b24e736,8a8b46a3,64837466,85df5c8c,b40bf2b2,291f370e,94c6eca4) +,S(1eed08dd,d9569712,6c0a4039,c6aa5ae5,ab4aabe2,a88142c3,b9aa763c,632b5e38,d180547e,c4640035,ca86d925,10a70a64,5dcbf2b5,d3add4b0,3f6d0fba,5f4c2f8a) +,S(9591b04e,3de43104,3a6982e1,29a2e79f,f525888,846689f0,44e50b18,ce14413e,cc4cc696,73279c51,4aa4fd63,474050b1,930e627e,a1bd9d55,867d700e,fccf8155) +,S(690a17c1,b2dc7ff,520aecaa,380b19d6,d4a28669,83dc5df5,8ab2bfb7,6c7b0600,bdd8a858,e2d989ca,79fbfd46,60ffdc0b,e0231562,711b13d3,47cfd37b,7a53d4d) +,S(800a632a,aca6b505,f9fddc22,14efe53e,4e7ad2a1,a6c07d90,27d8109d,893851ab,bf242683,e0c1a24c,9220c6ab,deae8baa,12c6203c,a0080856,bc5e5ac6,4c3f3261) +,S(6dceb824,c48159d8,57a92334,4c72b4e5,cf2005c5,6fadedaf,5a8b780d,3ceeeab7,e6b961f7,6162ab6a,d44f3fb4,5aefc843,bf0d714a,1a50d13c,68036f42,30a1ad10) +,S(3ef5eff1,2b76432c,4bdfd1f8,23bdfdee,f60b5d0f,5d0b4051,2a3e22bb,665f2b0,8741e43e,9f78066e,d57d317b,d50252fb,11d8d235,3c2c9d57,76191c21,8798b0a9) +,S(4ce8d33f,a53f2e1d,aa696e9a,2de694df,2192db5f,8e6fe88e,b5d51340,83791c17,a023ff40,69587bb9,49ebb15a,d047f141,9985b521,ae915f54,bebc6dbf,5320558f) +,S(da030efd,a3f6363,926abcd1,182f183c,43c4a6d8,8bcb0519,3d137827,6dcd3fbe,c14f27d3,2251248e,3c4b8613,481e7c48,f1493b6e,5c0716c7,8d5e3b97,876ccf3a) +,S(65c12034,87b729bc,3709759d,beabdd79,ee7f50d7,ed2cedfe,f2c2b7e9,97192f40,f440d69e,d59adfbe,e087ef70,9b75b95d,13ac0e06,20683d3c,6d49762,ddf68a01) +,S(82c052fd,dbd6aceb,1f429f21,eed34d44,f915e949,7190aa6a,d487bd6e,68d91c20,90dfd944,c7c20ec4,4ce35d2d,4036eb97,894f5b93,6bef62a0,f2f65082,b0f7678d) +,S(43e2f20e,cab47065,e71abd8b,aa511163,e17e3efd,3e17d790,ba924de5,ab402255,6b1ff657,e37b65e0,bf2c5e60,47e36c8a,2b7ba965,79bdc711,c3ae5935,d2c47bed) +,S(27f177cc,6722e5a7,70200e2e,a9198bb9,f227251f,8efa1988,ac7342b0,985a3853,a76767a5,3743db5a,1062ccb,64452ad1,606d5065,9df8c0a5,64f049f7,764d6a99) +,S(6b1ce20d,d15cf54e,59aec7fa,c1919791,c40c926c,55801801,75c09ac0,dcce0147,c90a76f2,627d2510,8b89df25,23f069a3,6b102201,c2fb7e9c,932ae678,4a28906e) +,S(f9df6109,27b5ff70,d55d2a46,ebc6a734,df165bab,3bd27398,24a60727,5410f62b,4da454cf,7a381056,581fb115,d36161a4,4beeef74,26724d,d4f5500e,3a6c1612) +,S(16bd87e8,2f87778f,6b3f1da1,a04bc048,3b14de01,420b0074,81aab07d,ad806cbd,13a50b5d,886047b7,6898c85d,cd1bfb4,87642f95,8304d54d,12c03b25,9429170b) +,S(f35175c6,2244f0c3,ddb104fa,3ae57557,424c2d0e,f6a20246,e2fa48d3,2908dae7,dfc1ef36,8ffb4e8,2076ae27,7788444b,33880ee5,b6d5bd0a,9a2ba79f,30c4d1ff) +,S(6a9ec43a,b8a6cb70,465ba668,5e15fe2f,9e714c0e,31f1f227,186d95ad,2faeccd9,ee752bfe,4da4feb5,e4c0266a,57929e56,62483704,6e927e73,9edec593,8d538708) +,S(92e3b0b1,3df6dea4,371601ba,3d92f507,2388a23e,302edf74,6da973b4,613d2292,9442966a,dff82878,f6e0b8d9,9e56f99c,68eea310,79b365cc,5f057eed,ec38496a) +,S(35427db7,f03afb34,d13ba232,420e5d9c,4a8d16c7,924a2043,a217fbd,4287230b,5cfc1908,108fa47c,95ff8e02,634351d2,523dd990,aee1700c,7cda57c1,b106a734) +,S(a61be939,d3a33b8f,65b8fb5b,897598a7,ee25e71,5797014c,fdb087f1,90895825,fa6b7a9c,f2a4a71a,857bb126,44fdcf27,c9f4ccf2,7bf6a0d0,dcf8179e,af1a3396) +,S(659868b8,2a9422d7,1da877f8,59956376,b999dc3a,657278f0,89e1b7,a3014222,9ecb6c01,fb97f691,92402a76,13f7932,d8a82252,e6b97c66,5c727d9d,e6b2ac62) +,S(12667366,d27bbe3a,d75f00c7,b28fcf20,86e9caf6,e8b5615e,eee0f180,526602ec,dbac0f9c,32895bf1,21c90190,d5bfea81,84289a4f,a0cf498c,3a3084db,1d4a833f) +,S(74af3ac2,60461898,c502229a,8eb4e7e0,962c8f38,897e43f,6e421ca3,3240b7db,72f03ec2,7c24abdc,dbc9af25,41e10f51,5e470c7b,19ab9680,24eecce0,954c84cb) +,S(9aefb23,d88c5745,da9606e7,ce81d4f4,5a39c8d0,4f5d5f07,62653594,d3a34732,f797796e,5c1c0a56,9886af6b,fd8a8299,29ae1897,ca43314b,cb6ed78c,6c0b0572) +,S(93a3da8b,1f686078,1849ca06,24c2cec1,796f64f8,4f46da9d,34766eb9,dfc1f018,e5c50d0,fe7d2f53,fe1053a2,985d2b15,25125981,30de3cce,2ebf300b,4b944c0) +,S(ed8d18c3,f526a062,bd6095cc,249b7d10,ee09d072,435218be,f2ab6c90,c5ed66a6,42084909,f4bfb751,5ec6da47,2cba7678,7870a9fd,bfc86fba,669e31ff,233a72a2) +,S(dba838ae,b57fad4a,6ecfae8a,acb50123,decb0f60,b702a9cf,7af7d78d,814845df,c3213cec,8f225c2b,fc02519f,dce1f67,5ad59b20,91381f0e,feef93b0,3c6536b8) +,S(f1a033b8,64caff57,21857094,e1038fec,7879765a,3b977a4a,c6616162,68c1d8fe,9592b8b9,e4cc6a7,ce173980,e68fc405,88a83788,a08c6027,8623ef61,ba81b652) +,S(53967cf9,7058ad43,1222e9a,46caeba2,d8fa447a,6b0295ab,f40b8aa1,af1f0097,e8e86c76,cef5299a,9a15a6d3,4985411f,2a71b8fc,99f7a76e,230052fd,d5309017) +,S(2477d3a2,bc3fd88,6daba319,8c6fa6c9,5206bc1e,955e9d4a,c6e5916e,5883eae3,baddd174,ce70e285,1e7ed788,cb81cb7a,3402276e,d94e6e72,f20789bc,ec4f5257) +,S(b483c05e,22824454,52f44e9e,287bc21a,634018f7,babd1252,d7a6bc70,24d9cdc7,5d7cd9d,23ad04b3,3a7ccdb0,38676342,5b2338bf,48d4f910,853e9100,e1f3aadb) +,S(6ae41ce9,6c8f0a33,674f74a4,587db25f,7c368fa8,83abe414,a3f6bf13,840d46f8,d52f2dc7,d4fd791b,36e6448f,5c8f746,759e68ba,994de0d6,48c6b1b3,58476871) +,S(bd1a4d61,e19ce013,d06740be,c3ad88fe,bc3b2391,45563be4,41768f01,45f4c450,88c18e77,c5313848,bd19bf27,374deffb,1f40e479,9687791e,675af225,1141fda3) +,S(1d2fccee,47b4553b,215dd2c7,f26412d6,73319507,43136454,35426bc1,29b358d9,93e52147,c13791f6,aceab8dc,95df1637,83d985d8,3a4426d2,f825d126,e7b8c564) +,S(322cdebe,5aef9ab,957b355c,e8e4fa7c,23f23f83,bf311785,f0fc40be,ce0f7453,2eb8c80e,561e419e,f898f772,12eccab6,e6c4ffc2,5daf67b8,47853a6e,8475d19e) +,S(c7474f42,5491fe9d,51a9e00a,a42bc188,50d4fa36,c19d9869,6939962e,61e207b9,8dd394ad,799a69c8,da550741,7352e7a7,92a941d2,10b3f65,f634cdc3,1f42a875) +,S(ac33b339,1bddf66a,6d04c62c,da618bc4,1ad217c9,7d37526a,38d12e28,9fa9dd30,602267b,59fe438f,ac57d14a,8dd3451f,acde0be6,c8984b58,7cfc1b24,34ed9688) +,S(158e2a30,36f71701,2020f476,dd869974,66f157a2,27548e65,688ae79c,3bf8141b,fac16be0,6033e61,d34d1d,1e2c95ca,6109dfa3,64232edc,8f8f62d7,19ce6303) +,S(88384c6,42d1bdcb,af5b472c,2f7a54b2,11ae4947,433d5d35,add21374,33ec4b78,3c3a484d,5b8793ae,203f90bb,476b4d25,773b268a,8e89dfb5,dcb17576,166b3e7c) +,S(21e3c1d6,32299e3b,5da75f6e,7ffa2958,e5d686c2,6322491a,2597dd44,f6973d2,9866fc69,7b9399b7,4307b1ea,e27eda12,590bb138,b22485b9,de6e3cfd,8d23bba6) +,S(abc484c2,6d06ec8,bba4170f,727055de,2611145c,8e4a33ea,56507b60,3477d319,4f92a638,17f6b635,d2d944a6,b9194d40,c4ab7041,2a8ccf05,e2fee038,58d87592) +,S(7a98d6d0,202f4230,a12fe9d2,e321bc55,a3a3b35c,92443731,cc8112f0,579b08fa,bad00e1b,578de9d3,73f0ea77,85502035,c5a04c98,8904923b,f0059a3a,a8ec6285) +,S(282e401f,57ef51d9,f9a10959,d272e0da,e9898f32,d2a3e059,4a65c901,cb1ae10f,6bb8b543,e9461164,a66d55a0,adc51ada,4ac311be,c6625276,5b2c1639,c803037b) +,S(5259a2f8,3dacac1c,18a9a64,d9834c82,e862169c,7a1b9d24,2b521c4a,d7ec4274,196fac52,458c7d1c,3dfae8b8,2ca130ba,99d43a40,8bf41da7,d2e9d040,291f165b) +,S(cbc4fdda,9ed1707b,59db2171,38e9bc1d,eda499c0,78f22c28,4309e184,cf906081,2929df0b,24074d42,75e8a861,8f064466,9ca0dd45,752c7d5c,8cf32661,f8a1ebe8) +,S(96b294a7,ed8d4916,21f10b04,3c2a5ad8,88b92c76,3c93f375,f6d31d99,64b9cef8,f5502e33,f1416c8,77cf06f2,5752998d,a30ed434,365b8239,617ab3e1,65948a96) +,S(287e1f0a,a510c8f6,273362d4,ff8d96f0,dd27113a,b45d0bf0,1af5d5,d24f5038,4b5ddc1d,6c9c4423,1f27ebde,bf4afa29,df337f18,2a2559b0,33de6830,cd7b9e14) +,S(eed0e323,3475ee14,5160d4b7,49210f47,c58d7b26,95dc8036,eae0e6aa,91a545bf,22407aa5,430aa089,3f7218f,2ca23ea0,16eb04b3,3c967e6c,d4c68ad7,16e4378d) +,S(1417cc87,72c932b2,b1116b4d,ab4e86a6,e7d80fc7,b082a6a4,c148c50d,177299a8,66e06245,56f09207,ab2d944d,167590d6,44afa2b7,b598b92b,65706271,d7b50e30) +,S(af6029b8,93c549c7,3544e849,b01ff2d7,b991fb98,2b8a3baa,b9f1b8ed,2b24bc89,dea2973,a97bcb6d,3257121e,9233956d,43ea9155,8105559d,ae17db09,fbc14f2c) +,S(dbb5544d,d28d2510,8a91dfa5,9a3c7538,1b4173c5,eecc8e18,b5065fd8,fa4fa570,4f84feee,755215e9,15abfbb,ff46eb6,9148efbf,39f69261,a9d2a345,3aaf1bd2) +,S(50ee1b42,be9598e6,3fcb0467,18786633,18b550ec,16645f70,869b231b,674a1878,8f4fafc5,fb1e714d,f52c0a10,55016f9f,3ca57c9e,48fca138,68464b8d,70c6b2fe) +,S(77b88613,4bcf9ab7,a1a6e0bc,82137906,d5c24607,a6d4812b,a6d1c8d9,55a5669f,2ffe0de,c5426e8c,92fc247f,a024f1e2,86668e7e,d7a24c33,2c887946,4cbfdfcf) +,S(2bf83837,74a9b9d4,7acfa6cb,6010fd44,620f51c4,e076d5b7,e798edba,21d7fb8c,5f336533,5203a820,a9f75f58,61bf2d0b,fcad07ae,9e297433,79d22b3e,a75f40f7) +,S(207b1218,9a6c2653,69f66738,b2e61d3a,c43cfedc,bd9f94fa,2b883991,ae69e350,c43b15c8,c08b4592,70c887dd,d15cbe95,d627a3e1,4a1c7afe,da2b0c69,549649c2) +,S(5ec76ba9,63dbe3e1,d054ad89,7a00c7af,f60f043,d2472f6,d3369e87,45637cbc,b66d383a,c4ec579b,8350a1b0,b2751fdb,f2ab329f,6ad63cdb,d6d46e35,944009ae) +,S(d010ddeb,3959bd8a,7a7ac178,ca573326,b578e940,b46f5808,12398722,42e13c94,2343d4e2,a380fc9f,617ed8b0,903b722b,a707c53d,a2140021,403ac617,d71fe37) +,S(49157637,c5c47498,5590bdd0,e4a8cdb9,f9bfd422,99812950,9ed25a49,7dad0da4,2564d49e,5c53c818,770c8a36,6e92532b,59fb90ef,e7ff4dba,c6baedc6,b792eefa) +,S(7e39cef2,8285f9ad,1b5ea712,78720954,f4933546,bcd7f9a,b4c7bcc7,54147a9f,6bbe4096,c4c107d1,c361befc,75916c87,6a2a0da5,dde637bf,1f125a21,5408e78c) +,S(45457311,84171f1d,aa931d3c,16b9926,59357877,84a4655c,54822c9c,1685761a,a13710ad,597e7da8,f4b12c17,9afdc5e0,5fc4f05b,e204567,9314149,9c73b421) +,S(c0bbe693,23e256fc,f69f0427,74c59091,287bc0be,82f0b5a5,6ea8f957,6d647d8b,c22981fc,6a015c20,525a0bf7,a9ba8ac6,dab6256d,d763614e,ea250c5f,fb433231) +,S(bb224b39,ff7d27f8,1ba86e92,a6897776,85074fa5,48b5515,987df332,15dca58,73bbcc60,c3adbb94,651cb73b,b311f690,6995d611,8b8238c0,4519de94,1e6bd47a) +,S(94489617,8b4bb641,9cdce312,5d863395,7ea54002,7f759e39,a8846551,ad3a0866,4a16c110,7730cd80,55fb7ddf,93c6deab,e3282da3,8a35d79b,3238e8ee,c8917935) +,S(9ae267ae,a964e8de,68398609,d6351619,4019778b,2341696c,7e44f446,dc8fac38,6d175dce,e589920,851c02cc,3fe3dfee,e9398e53,7742249c,e2745713,fee236c3) +,S(9e237d91,a6ce503a,65dafb47,a9fc5f7f,6dbcf3cb,b026ea73,68403187,d95afd67,64d491e6,df79eadc,74c198f6,fbdc481a,330d030f,851c7fc9,63974047,ddf2d12f) +,S(a5c5e0d4,920f0e3e,6973b71b,90ae2b32,2fa16960,b850eefa,1e516b4c,37252d6c,1aae183c,52ba9f14,f06c57dc,b483ba6f,740d6bfa,7ebb72e8,266895c,e6f6551a) +,S(a6d0cd83,9a198c9f,62bbefc4,b91b696b,57a4f876,6a16fac8,1131a9b1,1b36bc1,97981c96,9f758543,2c810b09,460c07f8,8520e78,3e68529d,7a1d3bbb,e0a86e85) +,S(4a75be64,16d6a87d,49e393c8,a26467b9,4b43887f,a90a25bb,139626e8,58b122b6,ace3e92a,c693f8d4,210932c3,89d4275d,75a46c6f,a9a76358,39c26288,1b8f83ba) +,S(1559a339,7f1e1195,51d8b4c0,fa53b5af,c693ab8f,843e6b00,1a6fc435,5967d7ee,8e450f28,78b2e9ea,829e965f,ae4484be,7e98f39b,a7b0ecaa,b777914b,848f324c) +,S(33565a48,44d9b25c,109eb9f2,9546fd5a,3f30d4a6,157a4e69,6029420a,21f74deb,c8141513,c4e370e2,400b8df6,208e867d,9bcacdd,d87cd975,8f91913,3ba97557) +,S(b49c8814,23db909f,c68c73ee,3995a7db,89e919f2,dc697855,357053a5,7ce26988,65878108,879801bb,ae412aff,72e83051,bb13c415,60499b94,8e0831d3,c2e11fb7) +,S(3a9635b0,b82585d2,37068f72,76291c4f,cd3d211f,80fa7256,58e28dfe,920e3e93,a1711c74,ba4e1a1f,f0a9b6d2,12c8b995,7b6c8c0f,f71da246,154f13f4,719f0713) +,S(ce6dc56e,6f5c496,71a900c1,ae531e3a,a8246877,98044497,fc543013,2572bff8,1af98ef7,3703f8a7,6fc88e9e,c9134aa8,a9e24326,314bf4d8,2a0c85ed,af291f8) +,S(a945a79f,1627e79c,9ce1cc5b,79ad02b7,c07263a9,11f8f78a,ad314049,92bea11f,f41aa315,4049b7c8,c9bef95,f3462336,ccfadf0e,16c1f129,26a5c9e3,7a443bf5) +,S(3debe447,a5f793d4,210e1607,642abdc3,c3a8d446,5a553a45,d73ede0f,20819dae,c0463782,dc5383b4,f7f81557,efddb90d,30138670,858c4197,5a47e6a5,565e339e) +,S(dba32245,a37b5636,9d7120fb,a99880a5,aa590299,601c6cff,d33238a0,395f8d2f,d589ab1f,ff442551,12aa1283,3deb9b43,947059bc,9cb1b32,4d8a29e1,1da82b2e) +,S(9c52bd5d,1fd61e1f,8e75f23f,f6e8baea,a8b7b5e1,5e780870,ea9f8dea,2b75cd56,e6d0a620,c116a7d2,2b2f797c,da7119be,556cd834,caab1007,e9a8ac02,f8945859) +,S(1ec28a0f,24e8910a,85f3c583,415afad6,dc5e10be,cc600749,8cbb40ea,b80fd383,c616ac82,bc6aa8b7,1a3cf89c,b82d7e9d,ddb95761,dd64da13,290f6bd4,a4ff907c) +,S(4fcefc4f,134d223b,994c1274,bd39655,878a35fc,2f50e405,ce11c76,1a6833c6,50c62036,fa49f62f,ab1781da,ec17a13c,4ec82c57,7993fd20,c5c56d70,145c2a54) +,S(85481ce2,90bb32a6,eb0fcfb6,9cb9fdda,580d8808,5b09611d,2d8747f6,ca657e20,ad2f9361,85aea05b,6a0d20db,9b6620ee,ee718c2b,2ae1810,42f6bf1a,2b3a2453) +,S(11aa1424,7760f682,3c11cf4f,12c013f9,7b1c9eaa,5ff0a504,334d2e41,f5daebfe,dda53fb7,b09620c8,fbcdf9b6,605710aa,f807dad5,c7ee4e9f,c7dc9c34,23302646) +,S(908c4f4a,15c58b2c,a0512eb6,b07c67d6,5b08b99c,13d22358,a52bbe24,b3823dc0,5e708db1,d4b37459,e33db06e,21a45fa6,5dd5c959,22ee7b60,7162a77,d89fc674) +,S(d192c334,65630164,2edf01aa,d974fb7d,af13ce8b,2c8975c6,ddde145c,1a2784c9,96bf7877,ced69d6a,a71f0908,86e2dc9c,f6529297,a2f8500d,d683b6a7,ebe4504b) +,S(8fa0f7a1,97138152,75f6c886,245902ef,b6e57515,c28732fe,d49b7f57,c19c6b9b,c09b428a,e54fe6d2,effdb332,4b1fc1e1,11aaf4dc,965b72c5,f97a8a97,18fdb68b) +,S(e53249d5,4d80b59,31d40779,4c550ff5,d6cfc715,13e0f419,4d7b42e0,62e74681,face5c4e,f404cf9a,275846b,11339448,d9133e1b,470489ba,64c190e0,b73735d0) +,S(9a1c943e,7f7178dc,c4453de2,d578c4e6,ab80d538,70c03001,a7a4d5d6,fabca0de,6ae6fb2a,1a7d87c0,99f6eef5,dea6a53b,a296824b,d8ab0848,b44d1216,c2c0789c) +,S(f0d4f862,dd60a74b,e06c9478,1b14b9db,af5847f0,baa00a97,72b61857,bb3d192c,6f48f413,90f9cdb9,edffe12,859b82ff,f8f7b32b,b655f3af,f28175c0,8f1efd8) +,S(1f474fc9,f6ee1699,7a7f37b5,f10f1d02,f2445e12,ae17324e,cd31d2e,c6fb8e1,cbb396e0,4b754b24,3dd587a7,d71eb673,c41b0fb6,329013a6,8ba95dff,c6d0d9c4) +,S(dd871b68,1cf78706,61bd7b4d,1ab259a2,1636cedf,39ac276d,5d36f086,fc9ad4d3,89456fa8,cce6295e,56cd18f5,9d9b83a6,4e4983ca,b55d425d,730726ef,12958dc7) +,S(5223e3b8,3809df92,8db9f4fc,d2b81408,96ed1b89,e6480fe,8a6b815b,bc7a33a5,95b640ed,128da08e,a10148d9,6f53b9ce,e53077e4,64eac3ca,1f604225,75b12182) +,S(65f26a8c,88fed562,12f11676,e2f237d,b4c500e4,a4ee0715,ae2e332d,74c48815,78df921c,545b864d,7ebe6c36,bedd987c,51ac9d73,795b3c8a,2a125d2f,2fb8cbd2) +,S(b62376f4,bd858d69,dc5d2757,b67dfdf7,1d3f770f,e96a0dce,3c61fcad,ed0e2586,c58d5af0,d669832f,4ff38f98,298e9240,c6202343,4e829b0d,145093ac,9ef023f0) +,S(a3297102,6001a6ab,ac0e84c,bfc4c829,4c607d6,c2147833,b1f726,752ddf07,b2c820e9,35502858,eea3b657,c15173fb,d1d45454,3c4fa17a,591a20d1,802d5c65) +,S(3b6e214,94773849,46056d4a,dec9e5c6,86f9873d,76accfa4,b4a377ec,84081339,d7e8ac79,e03d1cd1,7c83ad60,6a140b26,dfe67ed1,254a46e2,9c527cfd,c6afdf96) +,S(ff6aaeab,11cd4c80,ea69c3c,a10f09a4,40b3e51,abf56ee7,2c337414,f3220264,71d8a65d,7a605e01,852f0fcb,1bccfef9,147007f5,7c6b83d0,ef127b0,fe90bdf9) +,S(a0800062,64942e,b9bc70b9,f40bcc7b,52c0d43a,b4d608b4,ff65d73d,75fd4a87,de229122,80c1d66b,364fc250,5b3020dd,1482e43e,c4e67ad2,f2e49ca7,df9659b7) +,S(7c2b8b50,7e2256da,15afa166,84dcb7e7,c437b925,6c042450,6025a551,cafadd5c,747b5b36,e247939,7dd719aa,6ce55c0a,218312b7,26adf84d,eb7e3820,57a0b375) +,S(631c89e9,ee8a3192,c593ef08,baf3fc1e,d30a47e4,6a4ee9b7,e1c6cf5f,d6a0a5e5,8d49bbec,85a5245d,ecf6b084,fc65c697,190f8220,cbb84525,a344263c,ae10e2af) +,S(7ee8cbf4,a0b12cb9,d598835,bcf13fed,72e441e3,bc4b515,4182cf7b,f2818b3c,ea3b208e,70542467,a1e09248,8f34b44c,3821f0dc,169c6037,a7299ecb,25111774) +,S(69c085e5,86fad3f9,7b94d5b4,63b937be,5a95905f,eb33b25e,11ef9e8d,6b5ab3c4,5badd881,779a04f1,3a7333f2,dfcd0fb3,6167d168,b86b6a8,27640559,6e5510c2) +,S(951c09f5,563288a4,e25284a5,a694aebc,1e4b3d45,db0f0ef5,86ce87ed,237aa05f,a0c2704a,fddd2f24,462ac715,cca72894,7de034a9,2c958111,3f55c58d,83911c24) +,S(ba30b632,6ad18aae,6d87a1c4,6af749e4,6d639106,76f25f8a,673d0249,5e813e42,6c174bd6,3def5d0,2ce342b,1d0f895c,ef792f42,a97768b0,d091a92b,14f5192e) +,S(53a1d69b,77ee7d09,f9530860,31e93038,42daf062,c1ec9f19,1328b346,559fea0a,baea6eed,b33605f7,4bdac4e,749650a7,256bf215,737d1081,2c805ed5,298de5b6) +,S(23635f56,f8122da0,91d7e3a0,1125b99,a0f87e98,a717dbe1,f6d9528e,82f9b4ae,1a326517,904ad591,43f0f733,8c98f11c,2ea0fc9b,54e9eeb8,c41e469d,ef0ed297) +,S(c574946f,79574d9a,32c588bb,5cd8fee5,dc60403e,81b11fad,cafc69be,67c0eb67,d2598c1a,8568e4bd,a477d9d9,909b083d,f55a7116,9ccddf5b,666a8b61,96e2f73c) +,S(966bbcbb,4d397eb1,91ea2ecc,871fb24,b0c47469,33df7b03,124408fe,583db143,11741ab6,a38217c,e55bba9f,1c7f41cb,2e69e54a,8a78cf02,60bd3d2b,22789b8f) +,S(6ebbecdf,69e6e137,ad70cfd1,741ed404,4b3620ff,15a07f8a,769edc8f,c1aa1667,2ac87d70,baa106f3,a3490b56,a5960f64,fd80160,d0c14d64,ca1d40c5,f244c57) +,S(815f7f47,8609fee,733b7239,b272afdd,89c2f984,5da8186f,4ee8be2e,2e3e73ce,a972e06b,388be908,86c1e324,e1d2b953,18e99ef3,c0120906,f1508732,f839b930) +,S(24799358,53364be7,4675e3e3,c141e64a,febf3a04,386fa41e,f19696bc,5d3253bb,d6233c69,ec254367,673bedc7,1319641b,f9c029a7,2523f8ba,39dc375a,df245804) +,S(db32eded,dc803ff,d5a1f3e7,8437efbe,8c098fd8,e05f2aaa,c03e0daf,50ba5622,30ceea35,22ba7bbf,2ffe9c1f,bb817fb0,748efb45,65d01eda,9f9cff5c,b5afdad9) +,S(c5fb9cd8,8408cd00,33592de0,e602ad35,74e873be,4442d0bf,fe3bf837,51601689,a604a6eb,85233ccf,ef57fe7f,8a73c430,10e94b8c,4189225b,fe97637f,e7b97935) +,S(7b74932c,71dc26be,429f53eb,efc29905,bdf088a3,f2cf4bb,9828b701,11798163,e07d2133,c628a82e,4a22f58d,710b7d88,892cb999,2f921c28,3772310,c72909ff) +,S(308a025,4f659ac0,7c4e0850,738a2f16,df89ca15,fd64b35f,8f968413,b00b2819,4b4758f4,1eab6491,a8b50fc5,17f7767b,add40ea1,7b1272d4,1b1adf09,5d33c990) +,S(26a78f16,95b595f,63ff1b4c,cd52acca,ae650319,e67554b3,a77f85a3,637fa8ec,3db38db3,ca1e5dec,c73f2192,c4af6ff,66842a38,c76d62c7,c5958fcb,67f38097) +,S(bc440e62,f8524e7b,aef0af7,38e60a61,b213ab6e,713fa9c7,66d28785,891f15ec,175add64,8d472b3f,1547970c,6de2a57b,d2d3833d,2e847810,253b3712,f4d740aa) +,S(f2300d54,ebe04aeb,7a9409c4,3f2bce46,72d9937f,cf7e2a86,c4e8d55a,ef2a4e26,59e0e44b,9e090bfa,5291f436,6a3a5336,a56dbc96,65ae1aeb,e71e8c7d,e2fe77af) +,S(4d34ac85,c64d7d4d,97d40331,3fc19118,ddf31d19,18196594,d2f7a08c,db951c1a,551b6581,e6a1949a,4bbc211f,30fea215,5da8389,a69f6681,96f947e5,f7c8f7f4) +,S(53c3e6f0,fa2795a,adab1a45,a0f30f00,5f0310e,2f989d7f,d1f4504e,d03f2c04,12b382e9,b867a8c8,55461627,b7996676,880784b0,19690280,e709e91d,93048a32) +,S(259b0a65,79eced6b,2dcaa804,ff86122a,24e0d338,165a3013,9ab59f30,343f9ed3,27195af8,5217e109,33e2e1ba,57ebe333,9910c84,9b4e8f6c,af5700bf,93395635) +,S(fe07b39c,f9bd07e7,980b45c2,bd791e14,450eadeb,f6c41206,e73c101d,51093908,a8e47a5e,7a7cd98f,4f5e0afb,b5cccf03,56491271,c85fe0e4,9ae12558,721c66fe) +,S(7f38bd5a,87e2ebd4,526bfa35,5ced4f47,87c404c7,74e7f481,85d40d10,894210a1,4073ed4,cc499ca9,e7f8ff5c,f91f9c4b,782b6e6,f6225edd,d6f69fa8,b0b7fdd2) +,S(8796a424,9a251ecc,c0b3b44a,37edd05b,e34efda1,20926343,3a099e7b,8ae40a82,c02ec680,2860ecd8,f6ac62e2,845e8470,ff60cc55,10bf0179,49f95517,c1dd25d5) +,S(cadcc04b,9d4d8e5,22c153bb,def50fc,941cf94f,bb3b254,61422a4,7e6891b0,4ea1718a,53d64935,ff01f0c3,37ed2b7e,a31f9a15,edbbb60d,bceef362,8a454259) +,S(f2e614fb,346faa61,ec752d79,f9518b1f,e8f535bf,75496cca,513fa961,77f571a,1831227a,b5a35867,82b30fe4,720d2467,68f8c358,8472100e,fea76526,4581fa0) +,S(cb10686b,d361e64e,d82d6aab,5373f62d,b165d3a1,30bc7022,cb3f37ab,d61adff1,d969d37d,9c3db8d4,2c60a24f,44abdf65,b19fc6f7,56a452d6,7ef1b099,613019d2) +,S(6e903855,15042422,cc16d104,962352f0,2e86847c,f816468d,5754c70,fbc6d3cd,cc49058,80b7c15f,6f718ff0,ec2d8544,62e636c4,3e20dbdc,ee318a87,2d52d9fa) +,S(2c0a40ca,38f70b73,ef4da636,185c8260,e50643ff,9b5a83a0,fc0d410f,5526ac12,3f1eda92,8c32cf57,64d768ef,7a6afeb3,89dba8b7,e5bbe5d5,29b50410,5136ab15) +,S(1da89240,4f7ac31,136097f3,ed3055ea,d700aac5,a87ad4c5,49246211,f0ab0d0,e20f1baa,6ca3514e,ed4ceba5,9afe1875,c717597a,b7dd3c37,6d638e,287bd49b) +,S(5113fec4,172e4cf4,4eb27c6e,932e1d93,f16b3ec5,8c791b3c,e22c9bb3,634f76cb,7b129bae,b450023b,ebf81c01,bcd486a9,b494884f,b005b2e9,48eceeae,a6911760) +,S(a8d236b7,bff53a1a,fe23dd5d,63433dd0,a267e05f,31bce172,f80c5d65,c24373c9,698101e4,33e8a6cc,45b07552,7aa4ffae,3714324f,d5da0ff6,4fbc7123,773dde9a) +,S(79b2cfbc,b5a0c79b,d2ba680f,a1b594ef,4b2869da,3baba7b2,81cbf373,9d6f89b6,df45bb38,a21f4838,9e9eec46,f34eb6a9,78967e6c,5d181a92,e989e275,45756aaf) +,S(ba0eca95,4ec16133,1245f4fe,d70b725b,97393053,84fb962b,d1a0a014,cc403bdd,7bb5626d,2ee7d5fb,ad9cb623,7ba48440,26cbc27d,651811f3,92682622,2df76258) +,S(69609368,c01a1920,d3f62310,311cb7d9,cfca4659,1f53fc31,1f0af251,1f99fcc7,73ee24fd,32b08bef,f4254bf4,51614b2b,c0269e59,c6caf25b,bedb4919,76186894) +,S(c0b4d69b,d2344ab6,df9d8427,d480296f,5e0333a6,4a447302,5eac698b,e916f676,817dd44c,49b24aaf,627620c,ff7bb843,a84c7eb3,cc7e77c4,f65ba06a,14abd07a) +,S(80fd0f21,435d42a3,5ba377d4,e2401afc,dec30b21,db770277,fbab9841,3c5d9f9c,502f305a,a3350f4f,50d418d4,9b19768e,4976020d,8e158f2a,6cada628,e79953fe) +,S(7e18fb26,a881189,e3862fe0,9006e1a5,e07aa6b,39a5ef66,4f52547e,1cd7ebcb,dac9006,d99e8a47,d3c5539a,508f3f41,c649d475,4a53fc43,2dace107,1112ca84) +,S(a5b8503e,3f7c067e,628e5f5a,e65a0891,74385de9,69049aaa,26df1906,ed85af56,e9cc7458,fda4c95b,6b502498,95f4bdfa,ad9ed7d,346609ee,6549fa16,6e98dd1d) +,S(d93f866,450f7693,689bc9a4,644b52a9,3d006ced,d284332,4dac7fc0,bc6ff548,94c7526a,14b30b8c,b5a2b33f,c6508dce,fa141bbe,b6aba116,cf3cc169,ca094b08) +,S(424ec330,e4f5dff4,31ce33ed,1ef8293b,b8cdd070,12b5b18a,67b3f4c4,d766bae3,94f29933,fc5ee8a9,27295c4d,8d28b3a3,67c60d6b,13247616,a4dcab96,b58e2dd0) +,S(58805d5b,10cf81e5,b114c372,69dd5dff,cdf7e153,370a8305,bcba9d3b,7ebfe952,15e7b2cc,3ab0ab9e,a36df4bd,ce66bf72,8c45e295,d4a6c94b,e366f86a,ab39df5d) +,S(dab0c80c,a05aa70a,e626f81d,7b85c06f,b418ca69,8067b9fd,83cc6e0d,6a3949e8,4c728c4c,527f9839,498aff2b,91e8a344,aedb11cf,7ab9486c,ab3c7014,3dde8e3) +,S(55b54261,cd493b2d,7dd46f1c,78ad3983,787a37e7,ad8092d8,5cd6a55a,b870e09b,bee36be0,1168a67c,13faf147,6a614b6c,bf7b149b,4600c93e,4ec199e0,9f7fc63a) +,S(ea4f2da7,a5cec770,d986ba06,b1f18ec2,b3907a44,47fa2bef,4c9fbc10,d92afd4e,18f9565a,41583c3b,f7015986,ca7c94c7,4222b81a,9ac26eec,e7954baf,cb470072) +,S(5d835d26,54e489c3,d726f54,bc06ee3f,11390023,fb8d16,61f76b2c,29cfb78e,83091f39,9d1bfaf5,216add5f,dd4d60a3,469aaf82,ca6bf5e4,1070c03f,792dcb2e) +,S(f5efa7d1,484fe717,428e9f54,88c12db1,c775073e,27d028bf,7def8c3f,4f558774,1139d67,793faccc,70c7f48f,c892c314,988d4767,b9d6fa2a,2f2b632f,367453a4) +,S(132950c1,6f24a24f,a907cc59,704692ed,b6a5d254,79dea8d8,38cd71a2,a5d6542,b1e87d14,db8725f4,e2c2522e,c2f3f290,11d664f0,e6e85368,6c142c3,bfefd736) +,S(e479b0c5,478e49b2,c9e211c0,8e610b4c,1f1917fe,5960ba35,9af83c9b,4640d05,66ab2af5,3ffbfca,fdceb064,452c8ab4,b112ed68,8bafed44,1b66ef80,92144364) +,S(41b8288c,19cfecba,562b30e4,93a4c796,dc3adc21,f0c7a9d1,6adf4459,375edc5a,3ae93bec,6f438174,b3956d57,d9dcf29a,d673f6ca,74c96120,c22018dc,fea42398) +,S(56696d31,6d3cb87a,a3eb312e,1cd41768,2d0183f3,b91f605b,c4389d59,d86052e4,5e96c041,e495e90e,2812c09e,81d431c4,eca7274a,2204cb,a3a00a0e,650c6b21) +,S(ea36425,bc35c1f2,f0d96a49,ce4f4446,72848c5b,ec47d7df,6ac5cc30,d3968ebe,b00381cd,a5c19740,a266e63d,d59fea3b,d3d3d3eb,c899bf9b,da8090f8,1eea766b) +,S(84463c57,b01dd5c9,b98e0e4,38e221af,58c0e077,20540b7,da0b4d89,b3c36502,deb3a24f,9a0305e8,812fbaa2,f81e5fea,fd24c375,6a529c3c,c2bf4aa3,8d87b30b) +,S(13a22d5b,d23428f9,912df3be,eb82f4b,411fb39b,1604fa7d,4db63862,293c2310,99a19b77,c6912900,1047d70b,7e84ed80,a8427709,67384cbc,da11a158,6ddfb1db) +,S(de017231,52bdadcd,21b028b,4cee806b,89e98728,f91784d3,a418d7b1,22aaeb57,7ac0a9cf,15ff4a0c,f7d8a0e9,d2fe1469,1a08d526,7e3475a9,381be3bc,64771e65) +,S(1fc63549,9d462327,afc13d0c,eecddb5e,e99bb085,55076d88,7c064e8e,e40396dc,841f309,e47fb335,d2691c43,248a151b,426f1205,ccba170c,7c644615,54258a55) +,S(323e5acb,f821f131,7ff1dddc,822cba0a,b3b2380c,ea2f1b76,903c906d,83491dda,afc25ce3,b13cad24,6f6d9a2f,71e97d1e,e31bd2b5,967a5cc,7ebb1caa,adc7ee) +,S(57b1ec40,5c187317,ff9e70dd,2fd0eca8,cf2b94f0,3d7737ac,dd1468ab,61f56384,247e6f6d,7e2e70ab,a8d50794,36b1f6a0,b27865ac,791d1f08,c334013a,4ed93386) +,S(d6f5f80f,80586e87,5cd322f5,7836327e,225aceb5,6d8a83b1,6cf3bd12,4b581074,e925199,b597c7a0,a179cf34,519ca3a,f35b6d9b,24d76118,ace70f99,f1932979) +,S(2fef6c2f,eaa8c4e7,1cd31179,e0bfaa85,95d26471,fc36be60,1df75cd9,94e73c02,eedc9575,5bbca159,2271bcdf,d9ec8bc3,466e4b77,36d28abd,e6d68ff9,b9820f06) +,S(e488b041,358bf98b,11cd31a7,77a7d93d,e9cb3a61,c49fbafc,4bdabcdd,7b895964,755147d5,ba8f1d44,4ed0eeb3,d072c11d,f448c132,b9e06f4d,66f92ab3,7114a1b5) +,S(ba2591b6,35e7747f,20553589,11e7165e,618b6150,222a70ab,afa66bc9,a931cf35,3c60585,b16b1d07,7bd578f1,85e76bf6,77ff788e,a9b2caee,6c64ef9b,143ef487) +,S(ff4b12b3,cb0ec8d1,750c648d,6ed2695e,a41f8e82,58ba8b16,bf4727ba,6120ccf4,e2cbc52b,f0031efa,74c1fc8d,25466888,41c695d2,393e19e7,287bb34f,afb689ec) +,S(9e42cb1c,aaac0c62,47e4028d,501c84ba,6279b39,dd17424,73c2cd10,9bd36063,c9d0d646,381ca19d,528d2ff2,b04aaefd,9f8095a6,8811f8e3,e85b5ff1,5a5da5f) +,S(610e8f14,eb180ac5,ee435530,812941e3,ed7dad5f,c7bc7924,10f296e2,449fe005,67632a19,b1567d77,b0b5f013,77c6a05e,9261ca50,d010340a,968d8507,877fd4d4) +,S(f4c4230,443f3324,7be7bd5e,5cc12a0,27f0ff23,ede41c44,beacedd0,64789752,55d7b7c6,866f6bfd,29a410e9,8d5d5e21,98719d60,93e2bafa,697a8b5f,734d8bb8) +,S(66221ff,1d344797,1f308b89,a26e993e,c4d1c05,2c2fa436,3729c9aa,8c9dad0d,c0c78a0f,be8ba04a,932a7d6d,604f0fac,4ee01452,fef801d,36d3ca93,c4b7a965) +,S(c3ea4e8d,f8ac15b2,1dd251f9,7ebd19ca,2d91e97e,b13085fa,98294915,6aecfcf3,a7286bd0,3bc8f0bb,a3d28b6f,c513c4d0,472225b7,aab70f62,18c1a735,b31f1547) +,S(762ea616,8b3056b9,da318ef7,53ae0cb4,ff57eb15,8fff58ec,7e4fca2c,b605a49b,195d761e,9caa7603,ff1b5ab9,85d4bdb9,d128ba93,33d6cd94,f00c62f2,9452c8e1) +,S(50cbfa1c,f9a07c2b,42783077,8cae738c,3c3a0d5,617b8c6b,81914720,25712a6a,40a37fbf,97da5646,a653ec25,eeef583e,15cc1db,5bee9ebf,addf9706,cb14e689) +,S(bb8b806c,6798d001,f0d6b31d,1b17cf31,7a5422d4,3a906a79,294e5243,e22ae3ba,46b763df,b7a7a967,75b6b3ac,d21cfa37,a187ab39,99506c99,31623acb,841d4dd3) +,S(5491fa1d,88f0c9f3,6d87e074,331a9a6d,c17a5f63,b1e3326,500a5bba,1f0081d2,6c206f15,7dfb29d0,3b0e5878,57d1abb3,5f18b260,45c58da,87e8c128,7f699a83) +,S(c9d2726f,5ce823a3,ce02ee66,262d0673,f04ee272,dbc16cc0,27068850,cf472435,ff62f77e,60de3ae1,52c7f943,c3eed295,fe6a7aaf,8e6ba0df,bb60a8a2,b6081aef) +,S(a0d934b4,68151a34,cea5ff0b,d002dfb0,ec51df7d,ca5afd35,56acd53e,39515256,2f27f413,ac43711d,fc69e5af,785546f5,8e0da1d0,c9e89271,c8933b21,5998a999) +,S(342b7a8d,a3664884,1d8198dc,5e17b669,f4e602bd,5dfb28f0,95b7751e,4ce8602e,cf36fd4b,24cc36a2,806f8926,db6951a4,4c545076,70ee674e,8e2fefb7,e33f65f0) +,S(1f0993db,1084fdf2,6b2fbcfc,cf0c8a24,124c2474,92acbcb9,6221b788,18542b87,fbf92437,f6feeffa,4e04267a,c8dc57d0,c6d521b0,2631c20f,876fd9f8,b00793a8) +,S(f8f4034b,d7fcc9b4,256433c0,c2b40f9b,2f45a117,3a371707,f6ebec47,e456d9aa,cd895dbe,d97ab95c,b3c98512,c46a538f,385b9b26,5438f7f9,8caa245c,c680f54c) +,S(c80f3bbe,d409d5a8,cc0502ec,d7d95d8b,69067e61,fd2e8f7d,45f06ba6,7db89a33,dc803aae,6b936dc7,27773f6e,17c5d2d,af87a1f9,464320c5,4fd0cdd6,d7ef5c1a) +,S(b19fd3c7,8ee32a3e,dba4d6db,bb1464b8,5b3a5865,7f0c06f8,31af5b39,de2b436e,242c72a1,91f17614,8ee25c12,e0f8d4ad,52837a48,9b94b16c,27c8053,43c8e523) +,S(c88c52f8,a658160c,b10614bf,c744f668,ac46b774,94592a1b,99562a6e,e6482099,5a2f3a43,bfa6873e,7a198ad5,4fc0e3cb,2047f268,6396231a,a158a5eb,f4aa3170) +,S(b5f02d99,8f8f1c5a,8c8995b0,6879c804,1dca6f17,3666613c,efdbb82,820164e0,8e39ef2,207f5d31,2e36ce55,3569d2d7,2204a9f2,500ccff8,50bb67d0,a0802585) +,S(4d4e728b,5da0713c,18fdde5b,290d24ae,f7150d42,f9e5625e,f05bd17b,124f8302,be413caa,b7c77064,91110243,a20545f,8f9e5357,49ce98d5,cdb41384,5471bb5c) +,S(92832d03,32f7ebae,b67701ca,a0a2bfc2,b36b6403,742f4ff5,ff2ae46c,242dd226,cacf8955,92bc2fd2,90dc5b5f,b4185159,3e4a6a0,709a51f7,32e8c554,7cdc4114) +,S(2807a982,b4fc3fc0,8908fc5e,b3734a83,b2e2035d,8c6e3036,b16f9ac2,f4bba58a,ddbb9f8,3a9a6ae0,9945ebfa,9cb7e7a8,49798032,8545379,df582f93,72cea69e) +,S(e755ddd9,139cc4fc,b266477d,645b4efb,b02088da,752d10af,aee5ff8a,45df9659,fa7daf3d,605846c6,35e2534d,746873ab,cd502ee4,27e62c45,ef66401b,c816beae) +,S(93c33dc5,152a9bf8,31c3cf7e,ea833ca0,485f852d,52a255f3,55d7e67a,c1964f63,4a3a36df,13c8cde5,48feb589,dc56eb16,9a874272,c7a0becd,d40554db,cf4d8f63) +,S(70d66e2c,8f934356,d6720d9b,4809b984,6c7ab1c4,f8604990,d2e559b,a59c24c,24e8b668,4ee0062d,7bd79b3a,c96e0316,dcbffe2c,973ff6bf,e99590fa,192603e8) +,S(c165111e,fc2d7105,f6bde2aa,7f682287,2d803fa2,ec904380,27195cc,147904d2,c71184de,f408b79f,32086d4b,2b0e5d95,aed6e0e0,eb99bfb2,7e917abb,8d3a5e74) +,S(12144a63,67cc355e,e75486,357b0c79,ff4fe703,57a2f89f,3e3f7e20,ef860204,f2bb05e6,e55171c,c839fdb1,2b49ba11,dfd53af1,7a5a9602,4327f93,940b8491) +,S(3179dfa8,bd134725,3988033e,70f806de,fde9c6c7,aa4a6d43,a5cf110d,6fda7828,3133a35a,ffd1f24f,579fb314,2e72590e,475e931e,8766d462,842972cd,70e49344) +,S(51fe3e70,e5f21b21,1cae97a9,d0fa49bd,166dac17,5087ac3,a93219bf,d17ee77f,f3309396,5677c691,2a987cc1,5b3f016a,4efc22c7,6f89f562,4830f09,a9fc9bd1) +,S(2d7c98c,a224ebd2,a5167017,88018bf2,1f29444b,6eeead79,dfd9e503,7fe1680e,abae552b,bbeb09d9,dc82af6a,eea16d50,613c9314,be23eb79,d254a16c,decdc02a) +,S(c356823a,37dc335a,918a5553,bb0dfb9c,704ba647,d6cef22c,1e71bc9b,dedaa333,d8715c0c,a0ebf8be,d79ea3d0,85a70d2b,b40efecf,7dded60e,13d0577,cc235e3d) +,S(91af0d4a,56a75616,e9cb1351,4ca27ef1,b7411d9e,5991be14,c1658450,71a2b3f,f6c845a8,76657a63,ed37bd33,46ca60ef,a8fd151c,24a9e35c,5893f969,2580e26) +,S(6a32ae36,93ee1e7b,77fe8418,7266e6c5,cb41c7a7,37351cea,987a4f80,a26cbe00,2816504,dc3efca2,67e4bba2,5d4c9dbb,e8622e99,4a712503,37320925,ed5f64db) +,S(5851d327,5e18fb4d,79292e6e,2bd6bf29,b6301e08,7b418ac1,43afdf70,7d880901,1e17a9c3,dfa8c3e6,c1e9c34a,785321a6,e58d8024,c61cd02a,8b83ad41,a2366211) +,S(233a98a8,9fec3399,f74d99cd,7d5d4894,1be8274d,8f7ecfa1,f4f3693a,fb26a654,e9d5a9ee,fa5e6cbf,9ffe590,bd7db1fb,b9e08125,93f42238,65298e9,eb42d7fd) +,S(8751bf4a,9676e2f9,5036c3ea,97749d8f,f452f67,cd1259c8,4c39e8de,9cf796c9,4f883d63,bfb0a01b,e26b31b,53ed8755,49ed6c1e,4b67a160,7fb68be1,7b845711) +,S(a21126cf,7330697d,714be16f,27986c9d,cca4a0f0,3a12b6a,d54ef31e,d7a3dc23,3b0e984f,565d9825,2c523913,d2d90a26,b47973a4,8d8669f6,8dcb4c62,399b9777) +,S(8123c441,96d17ce1,c6c1a9d6,2aaecfb4,cdde74b9,317599ea,450e62f1,5639c3e4,406c585b,c9aee3ea,dedc117e,d58b1c3f,db5846cb,6eb11592,469bf958,6872b068) +,S(6f8e1a45,c18ebfce,2e2f710,efbd7ffb,4f107a32,fa6a46a4,caaf8ee2,37a22805,b36a7c4d,712315f9,a89b5ac2,8d1a5d55,5ead81,d7c43b8,8155eee2,b3ba8d3b) +,S(51db2e94,7e75c9d5,4ea07ea3,35942071,5987090d,b81c3b99,40b85684,2b0f0bcf,70967acd,454e6ce8,ad015f45,e0578940,c95dd818,70268d0b,9782a595,9a1462d4) +,S(84e0b0fd,b16e03c2,cae53675,4eb3452c,86ef07a1,ba278abc,d5aeed37,f71a3151,5a8e435b,53a4b51e,2ea659b7,1f3371ea,dfb28579,8b062eda,300664b6,d3b204ed) +,S(ced68408,c2b01401,fc039059,5140ab68,14142b7e,d69a64bb,e6ec5d85,be833367,76ce2478,28d2581f,6779f723,327fa83c,8cb10451,fc34625b,d069885,3cfad07c) +,S(8d860f70,a32921af,6376c310,bf5093e0,572e9b3,44e9204d,f5487554,c4f5484c,6dd24078,cb9f8ea0,eeaa4f4,3f3cf99c,890966c,5da8fe0f,9cd70128,88907cfa) +,S(6223ee77,4e56b9e3,da6e008a,eb3ba06a,40bafa1e,84383ff5,65f98286,d9095d37,ebcec7ec,f750cde,9ff7972d,172340c3,c324d843,f31db269,c3f35a62,c5f15f36) +,S(326943a5,5e7b7ca6,951a78dd,afd00e10,c8ca7f6f,3c01a038,ffc4fc7a,20fe2c63,b3bc5a8b,c87ba023,ee22bb4d,3f92cd81,787f2af2,4ecaebe2,67fe0a86,21c5d201) +,S(f69b5d4a,eb0b550f,851f601c,92698789,f9f94821,47a0ade8,c8a19fe0,5742731f,2a74e8bd,94469645,c8a328b4,24975dc4,93adc83e,4baddba,6c41e10,3b58e90c) +,S(f69a5a88,b8f13bef,a987194d,6b00a79b,7e576749,3d180fe0,32a1868a,26d853ba,6eb589cc,9c51900e,a6d99110,206f60dd,cbdc368f,5ae8dd48,cea05218,3415cbfa) +,S(c00ffc9d,8a57cfcf,9624a812,dd2181f7,195f459c,3b858a19,864393bb,1d1a269e,3097e10a,d6abfc0a,3fa039fe,952034e7,6bda4fc5,c5614092,b124ee3b,bf55f87a) +,S(9c021c49,d6671103,cfddcc3d,8e54848a,addfefa1,d6de5455,e5bda021,126dd183,4fa1ad18,81362f4f,f0587b52,a7a1b483,2d14127,434ffc4,c5bb90e4,fce50834) +,S(59aae0a2,923bc36a,1a5bc8cb,ea5bbbc8,b34f1504,4671a046,eb3090ed,3f4b2345,659f89e0,faa1577e,36175240,2cf1736,a18b070e,4d4b0fae,9ed08297,362cb246) +,S(7ba1ee89,479254b1,f32e9e53,517f0961,79d17d81,3ab3666a,75d4bf7a,7113f252,6530b40b,7e66a084,97168778,61cffd96,5eb71e62,e8b0ad7a,7d2851aa,15a26dd8) +,S(4b0e5728,cef356a5,c6d08616,47c268b4,c8a12d8e,89c2da7b,78e9db87,7b606719,235ec085,a1f3651,11b5f03d,7237dcf3,d70e851a,6dab8446,10e45fa,2996e70b) +,S(54285c70,315d9a43,a040bd05,70c35713,68504efb,fd103098,79067d6e,765d4499,de233654,e7c05b5e,f144d25c,6d539157,51e83ce,7f88dedb,7fbef11f,d6acadb6) +,S(ae15f764,d20e4eba,b95c3463,402a2159,fcd21daf,fa831b3c,e47bec08,9bd43da8,474c4cb8,afeba9e9,3f1d0a2d,28911298,939328e,5e364d44,68c64cf4,fec2eb78) +,S(6de8743a,68c42b81,ad069f2b,fc1482c0,204640f7,74515924,441ebd9c,917e3974,7ed602bc,16300648,86ed0369,21936ee,aa5e9764,ffc294e0,bcded12b,bcc86f55) +,S(7e4951,dfae38e6,f9869fd9,6d058847,2a38b0f8,827052f8,46195e21,44213a47,6fa2e60,a3883383,f8efebc,f39329a3,b7aec31,2958510a,dbdd5a72,728035be) +,S(1f7eb5f4,47d53537,3d29770d,5d7ed36c,a2d2a4a5,550d8bc1,849382fe,3847df55,5a351374,da5a804e,3b995d43,49560f7b,aa417dab,936860c5,baa252cd,1753f25f) +,S(dcc1272e,b31560ec,64a4b53d,24727bde,da576493,b571b5b0,aa7bb3ad,e8b2dfb6,567e08e7,bde60e6d,a614f321,a9cdba4,1b860f41,387b3854,603a8740,f93039b2) +,S(3f4e219f,5014414a,3c757cd,28120043,3cc199b,fa843c40,b344b32b,87dc7e7d,dba2099d,839e9c1e,7d7d4c0c,9444e956,168e2bc,4df1dc52,bb5b4da6,3a8283f3) +,S(dac6f264,74fee94e,dfbe9de,cb2fb88e,272ff622,4d7f8b86,3076337d,6d37acec,1bfc6855,5af0f07a,c9329ed7,5549560e,8d3e0c67,753d2673,eb6706b5,27a0de10) +,S(82ac1fb6,5a975de1,4bbd5709,9e2574d5,ebf883c7,7f38a7c6,1408dd3d,5e49b33f,a6d9dde8,b43656b7,9ab5d880,f3af2ca8,b70da7dc,251a7299,cb236b1d,75276c56) +,S(19a59ade,a0da1340,36a533b8,ff202a58,55b9182f,b19e8b79,caea80b0,9e263706,58030bb4,b17da5b,1879a67a,12c1d929,88cee2a5,d8915528,26456762,9a99f256) +,S(27e8a699,eca192b6,7a66b1be,5b290e37,1ff8e912,5afef253,134af2c6,ae709ead,54ae6059,58d036ec,959d789a,5316c70,a09db19b,179e5d4f,effbb057,abd87eeb) +,S(25e6cdbe,5d7e37ea,fe2b51f1,95cac707,a2aaa70,57fd5e78,8fc926cf,76e65466,576b2c22,cb6ba6bd,6acf0eae,79b52ee4,1fdebde,25293347,d624973f,e9b66be1) +,S(a0114d87,cc03bfbf,97e96821,2b69c53f,12910c87,e87e7a79,109f83c1,7042dbb0,869c33a4,cec89d65,633bbe60,a3cf7b70,1e5c83eb,e7c229ea,a4c279a0,4203a9f9) +,S(e8017e4e,806557e4,61ea997,f5f46e72,9fb668d1,e8faacc3,5804c35b,6d5cbad3,eca21b4c,294ed18d,d0df0dbb,771b8bd1,659c2eae,2c843f8b,bfd3aad,f44a4070) +,S(948209cc,528dc6d6,a406c996,7d7c191,19ab5142,679ac9ba,afc5098d,4d7c83e,3cc37cf5,1aecaa1d,ef14a2bd,cb6a1084,f3e60da0,9fdc4fb0,9d9f9fa5,84f14b25) +,S(10f4d6e1,c141dc53,fecfbdb0,b39e3e8a,c7f5279b,dc231fdb,55b25551,df90fca0,4f5e59b0,9c6daad5,80adde67,1583af4d,fae40d52,6017d5b2,9e798bca,6917e735) +,S(66361888,5d081bf3,9e9fc4bf,a0922dbf,dbbe8eae,451c199f,9aa844f0,71a327e4,f31b98f6,48940706,13a086df,12416779,a5c16ad3,7cf885d,5f1fdb37,1be94cce) +,S(6afc24bb,ae6cbfca,b34fd467,f23a31a4,4a0a35f6,203dd7b,a881ee5f,f340db5,7ab76f2f,6bada7ac,1e01c930,90c741fd,90c41fa6,943aa804,ff960b17,3ab28cf8) +,S(3551d572,2eff7d0b,275e310,d1466a70,2b828d8c,fec039aa,ce629aa1,2a9c23a6,b58af71e,1f9a6cce,c48d1fd1,18902a21,7f1e7f35,3ee9d794,8133d41e,2d2d61eb) +,S(e6e8cceb,f6096fcb,8f21cd9e,d428260d,c3867e0d,9c4cacc8,b8900fff,7bd4c1aa,d1b12068,f85e64f,7c9de5ca,f1490bd8,6dabf18b,4b78b5ef,531d9bd4,f64f13a8) +,S(5cd74a22,d46e7769,15b3c84a,492fad11,8790534e,dd8d9bb1,e117a6a4,78f566cf,397b2429,f978404f,ec96a4b5,28db5a,1b0cf9ef,61f2fc7d,470f0554,eed5ee08) +,S(abeeb656,151fc7a0,fdfca1ae,fef91a7,ae156db7,c433178f,be6fd700,991e8b86,e2a10216,3a8bdd0e,8254f459,b573d182,eb55f2b4,969a3f80,267b060,9f208a8c) +,S(3f9702ac,3b96bd4,ac9412cc,8f40d5c,99f4d7b9,d211bd2b,18c6f96a,ebd2f958,e077e28d,8f171626,9488fa5b,67a54800,b0d5a519,4384ca56,f9836b87,68e9821a) +,S(3c8e54a0,d094d63d,60aecab8,675349e9,f229995,587cefde,eaa1f50,cf3032ac,e77aa94a,fd252860,3bff0189,f11d5f93,fb26fe86,dec719b2,f8bbeda1,3cf38ba8) +,S(8e88168f,41689167,ead8ca79,5ef784c9,8e3cdc41,43a0ff8f,2891d476,98387bee,fb4bf21f,343fc6eb,ca6fe337,ccb7a7a6,899bb29f,d2f60480,ffb0a187,e875b00e) +,S(d5c7df6f,31001177,f2e88aa5,43276617,7a598335,cf6ad98a,e55a6d66,1b75c1ec,2edb20b5,47b7c233,23d5c4e3,295921d9,9d98854,e780f4c1,e756021d,79f1b035) +,S(262b9c58,75087b02,490291f3,963160c,c1f5a3a0,fd6a905c,25c98bb9,f7268514,c7e4ec06,b4cc77a4,ee551a5f,6c90ea97,4a0b2193,f1b828c,305a0fc1,b22e5b81) +,S(cc94ea5b,a4fdaa06,93976b76,893dbd92,f602bcce,822ff271,7a13bc2d,6b31e7b1,c81c01ad,f2ff92f,5c2cc42,f3c30091,11e6901d,36c9af9f,9b408df5,c7460932) +,S(b21abb23,4c435197,5b73471e,3b2eebe2,f537b95d,1b19361d,31ca4e63,336b0066,db02da36,73e62e9d,e96e1bc7,b79ef4ed,49449c29,7f4f0330,227dabdd,5b4c3d9e) +,S(ed130512,5af211bb,28118dc7,fc22b8e,8bc2554a,a19a8c7,16f69f11,a03df1dc,fa146b3c,2e0eab2,bba69407,9ee3b6f4,2f64dab3,9c19a1a4,256283f5,bc0886ec) +,S(42b829a,96989e82,37e48200,20eca1d9,61e487d,a9c6f9ee,60586dad,8fcd0e83,c2e164f0,29b6cab0,14fe76ad,82ee7372,78124cf6,5f251c9c,c260e239,50ec4014) +,S(15f09133,fe57a223,e2c9ad79,dadbbc7d,ec85df2c,6af39fd4,a156eb0b,1602a13c,563206ac,b190bc2f,c7b24d2e,ff376cb8,64102efa,12f7be73,84898cc8,76a12b4f) +,S(b8446387,4262c03e,312eb0cb,e562f460,8cd4f65a,75b099d0,b45e0de7,8398f5bd,da730acf,79fa0282,a3a29b99,7a0ea45,ba0896e7,598be8fb,8298aaa6,9b94640d) +,S(6a926c00,ef4c32f2,52d9f336,29fc708b,e21f571f,1f320ae8,6e6c46b8,9511fb95,9106e0c8,2eb9fa36,4a84a2e8,8eadc9aa,9113927d,99adeb61,a2ac5527,5de9a9ba) +,S(fd6cbc21,9ec03dff,8f3d00e6,9de0c64d,30ca5a04,1556d0d5,87339b0a,925d064,742ce8ed,a4b47eeb,29883606,211c453f,fc15ae40,174e1c74,656a78ee,f3a85e8e) +,S(6fd7f1b7,61116218,68e1038f,d5f341,c43b61bc,b6ec53c2,8d84b321,ac664274,f681256b,947a9492,5b8402e4,26ef8d53,20c65a29,3a7758de,6b7e3f45,a9d635d) +,S(c28c2cff,1e418550,f73fb839,58c1ca6d,4c616c3,74a67978,d4dd71c1,99902ac5,537d774,83b1ca9,50174ee,381023de,cc210f91,3a66615c,b242829e,e3285285) +,S(89458f8b,7db2cd74,346b8b74,759088,fbf81591,5fa1e97a,3f34ff90,908cb183,9b5b21fa,378f50f,dff2e276,353179a,c0a6e43b,13373940,c2e73e20,106742bd) +,S(e66ed94e,793b894,552b3893,88a657d8,55ccbb2d,f9ae0061,2cc07244,bfd434a3,8a6a17f5,da95e907,7b03192b,eba324a3,5595b6d0,660851a4,7f9e2259,2f093275) +,S(8c7e4ce,f5dca16e,620d6690,ce3b9337,8000ca08,e73eac21,deb5deae,83359160,29a44639,f9a6b8ef,990b72c1,5ca6f539,31000a2f,394b59c9,36542992,7959c505) +,S(a0d1611a,807750a2,45c68132,2f7adab1,9b81de3,809a9a82,ac038294,b732bdb,c6e35357,246fec0b,ed0c5491,24f13f9a,a01fe39d,e7630357,110a5878,90d9bf95) +,S(c1cc130c,474f5ebf,e4b4e26e,a444d5d,7542609a,2bc65a68,9c6453f7,9dcf6ab5,deaba85c,f0f7f9fa,cac2415d,9f82c62e,9caf457e,fc9149fb,55bd8f2c,32f74ea7) +,S(d6dd2a36,763b77e6,259f1305,43c8262b,784a268e,45adcd26,efbd6d54,afeabd68,2987d048,9549cdd4,c27222a1,9562b005,56dac521,1e67d052,e76266bf,fbab179e) +,S(885cf8e4,ee0498f,29a7f3b6,a2420629,4a941f56,f3d852e1,4641a604,9415c49d,b1002bf3,e34ce44d,54a18be5,3737d98b,28ad0f7f,31d9bc37,ce31279c,fc039b2e) +,S(8f0c57d0,3d85979d,5bec7346,1f0a3b7d,540fd0c3,8d8a6775,fde2ca35,ec8a0d91,86a3f4a2,cc4f934a,8b833cfb,dbb96eaf,159e00ee,caa0871b,235e4f8f,97bf542f) +,S(53456583,d2f4d9fe,1a13883b,7775b363,3993c9ce,6bca547f,d05021a2,d36cd366,92cec0bd,cd83312c,455690fd,d715e41e,c29cc70d,f5eb2e17,7f0b2caa,f3b5214b) +,S(a5ac3a28,fad5cda9,200bef2c,454b73ee,bbc853a3,e8b2ff77,111ea25e,5f3b5359,4951843f,6e23b9ba,60f326b5,d6b13f1f,f49e8b3d,b399be4e,46cb3ab5,7ef10bec) +,S(2ec53b3e,6d91835e,d236898f,8857a64c,4d898098,9af6ba60,392b774,6eb99ad,e21f4abb,cc05952,eec3fe34,f02d64c7,e7a91658,b0b11b14,118c3489,7bb2a2ee) +,S(5863f940,a45c8f5e,a2361500,84c588b8,a7f99d26,84121d59,9073d38a,69494c38,db422c38,41a2bb32,98390c98,e9f4c23c,da27c64e,a5481870,b33a2bc,866852d4) +,S(3492772e,d177b4a2,5f9eed03,7094c52b,aa72dee7,1c5b315b,70948dcf,a1975a64,c5a26844,26418929,b5bd1488,49b3241b,d0eb5243,61106911,1fc32cdb,29087562) +,S(4405762c,ba4f63b4,2401ce63,120c3599,af37ac13,d2de044d,26d830,9e664a4b,3143da5a,8319bf4d,32941d58,e9bda807,74c58380,ad8c3a33,460bfd85,36d9baa2) +,S(4894f457,1324691,8f32111,e1bd94e8,a43f717d,74e8c465,550e864b,9ae2a16e,9c89818e,6f09fdc5,b36c65f7,12f26be6,40598712,fefda799,4b200967,7de01ea) +,S(620abc9d,4efdc1a,55edc41f,29834528,ca87b333,a8678e8c,205d6817,cb7ec3cc,f524cc99,9e911d67,dd0e8bd4,3e003ec1,64af288f,3135a602,4e93856f,8110f867) +,S(d69800fb,9fe61ca8,97f77226,d42749b,1274176e,29bb85a6,226f91e1,e8c62a7b,43baaafa,e10649d3,ff2bb0cf,10c58f8a,f01fd3f4,1a06c245,a4e9c483,8bc9e3f9) +,S(87a12e5e,d002cacf,f55901c0,d374f81c,ab9da24b,80e1fa9b,25f038c9,38344721,36586bc,17aaf4d2,5d02ae3e,e9f98235,f9d605fc,1954be4a,dbbcb917,1f736d72) +,S(a0af0d5c,bfdf4fa8,98a3ea89,867721d6,3178341b,ba30f091,946c72af,bb876624,100f795b,18dd85c0,9af012b2,5d7d5d1d,5118d02d,3837fabc,ceab0b23,99f98e43) +,S(ac94b41,7becf857,1248a94b,a853f4f9,dd47284,157e0b9b,1756c4ca,fb692086,cf94bf3d,d0c7f89f,acf8f678,5508e510,faf27a33,10915d99,80b9fcd9,62f75c92) +,S(649654d2,966fb2df,b917367,e2ea4034,fe886725,3711bc40,8520d5d,579a3481,bf8ac886,a7550c40,29279fe1,c4d330d0,89935427,d6967412,66d79ec1,f1a2780a) +,S(5f7776ad,e73826a7,fd2969a6,1511141f,cbf6fb11,23c8d7e4,3ff93835,ee1860c1,9faebe0,2140468d,4564f7c8,bfe4f097,dd0ba493,8656fb43,ea9f0f8d,22089e5b) +,S(f5dfe7be,f4c42f3c,e91fea18,10402c5a,9072b001,286a7371,35a00fd5,c71e2f17,9787d33f,821a0633,ab1982a4,f9240b53,38a5644a,4d203b1c,6b5cb212,3c837b4e) +,S(d3432817,3f33fa7,e517d6f0,408bfcb4,6a882c0a,6d78feb7,44f731e7,4e1bed23,bc1e6ff7,cbdaca91,edd419f2,e80e617c,506bf8d,8acd4548,8267938b,813a281) +,S(a4420846,95528dde,2c52d5ec,cd67266e,3024865a,c6e812e5,1ef4f780,505f9d2c,4a721caa,63d62b9a,c23ac717,7a27e27d,d54e5ff8,aa204bf7,3e6b3131,3ccc31ac) +,S(b3818c70,ea29c1bf,db63ba44,1e42c842,11f9d2e,4d6b07cc,79938d3b,b294b820,1b2c711,a98418b8,15abf79,44fa75b7,db8965c3,1779d4e6,1967f009,8c005d2a) +,S(3854b55b,def18a47,7e87f62e,d7607c6d,aa2e737d,e0e5015d,de7e90e4,570d43b0,2865de79,552c68ce,4841ad3a,69376a36,9d74d55a,98c35d25,f97656a2,fa22785b) +,S(e2e805af,78bf592,6a37fac8,7429f6ad,88c45522,e58e5c9,2bd2ddcb,e893ff33,c2206185,254ef80d,fcc7365f,1dee9a3a,cdac0ebc,d0ce6a5d,4c9a6875,f07a46f6) +,S(37510b86,df2d8e60,10d40e34,77af6c24,47f2a41a,fa35ed49,224bee62,eb0b77c1,1f30b802,6a3288d9,714b33b3,7a09cf20,cb754f09,730888d2,a09869ac,1e905ff9) +,S(14b2bcad,c5272c56,8930c574,d745fac7,d190558c,121df6e0,c2c9cc1a,f9662fcf,baaf56ed,f70fc0b6,520bea13,a8794d2,d397e935,65841028,6dafdc16,96caaf3b) +,S(2984937c,e3d6a155,7a185609,9e44bfb7,28dc6d0c,bd8c628a,23a383ca,3f38082a,637c5e4,9b0943d8,e09960fd,2375770c,5d4dc4b1,3ea460df,d5ba49ab,fd6339c0) +,S(e64f46da,d9b9e7ee,3d2878b2,f604728b,8203a591,d02e7d23,721fc436,165918c0,f7ec0e4c,9f66adf9,98b8e41a,d43fe3e4,7cb9be23,6356ef3,ef5b9a23,711e1140) +,S(3f587c9f,1b88ca37,d32af584,e510609e,ae113e54,8d07fbb9,a34f6916,908f686e,37712f53,41485518,241835aa,d31c45b6,f5370c6b,238380a4,ddbd0755,17b2b49e) +,S(8218250d,b1ee7484,b8892bdd,53be130b,4b5d3db4,7c3c9e36,5a17baac,5d8654a1,f19955f2,a7f954b9,2050c815,8e801222,8e77405f,c9f0676e,76ec2e4a,f3b93bf) +,S(5ad1a4a2,55a22c56,e8d17acf,786356f1,7ffd6453,262980f7,188879be,9e1eaac5,fec5d2b7,ac26e4f2,d4d7af01,b49295c3,3a969fd5,28e3aeb3,90e86bf9,85093dc4) +,S(1c92ee58,c5226166,c313b491,5c731d34,739068b8,f0241dde,6f0d7151,243304c6,5dff29a6,1197aab4,c1ac8a25,625c4dc1,11729680,15f03488,b8a4baaa,d541bcdc) +,S(fe622f9b,fd9c4ba8,8c80c82d,d1a07bac,c1c9da11,996240cd,50b6a41,f6f8fdc3,666e59ff,e9efb9a9,b7c36539,ac948438,f1de235b,fbed8fe7,3a084076,39f6b901) +,S(b2e8301d,ee34bbc1,d95de73f,b947bbd0,325bb3a5,555738a2,8fbe4e3,601a40d,6953963d,3496413c,53ef500,6def0fda,607d9a9a,319cb93e,22d9bfd,a0c3b807) +,S(1505e140,4644537b,56da7114,5efd34d1,566ee38f,dd4b549a,34ff312d,5cb9bb96,d6440284,c1ba972b,413f8c12,7fc40001,39954fd2,5ee4993b,4dcd5e3d,a2b843a6) +,S(7a524409,67918e47,53b451e5,243c6996,c053fce6,1f492995,8d2bb84,9fd1088d,e089d973,19788a2e,853a3067,c4a98c59,4fce75cc,a9ba908f,37780e1e,567b7284) +,S(69eff8da,8efa75c2,ab052d71,e898a975,c58a074f,c46fc6b3,2b385e41,93ff5a30,30e873ca,f0e7d1d,e58713db,cf7c5c9,6c9f068f,e0e3d1d6,c3863d44,8da1cca4) +,S(64a5649f,2da4eb15,1be3fb68,b1210cca,61b32492,60225ef5,53426992,95e6d6ec,8c53c12e,8fbd7c,811d4a85,95787105,4719c5fc,368845a1,6b8babba,1d92f56f) +,S(ca23d56f,46ce3458,d95a5b24,d998188c,3ed76a22,2034b337,933c4298,8c804fdb,efcbc7c7,d0d11fd3,ef1c0ac1,38d1a2bf,d0e94a85,a0700cb3,630dcaa,426a4c43) +,S(630b2d2e,62bf28a2,ebf80f2c,2bb10cc,82014ee0,c48e15a6,4cd691db,dfe8a55,908eba92,e889f132,4da0f927,9c1bfb74,dcf16786,c9c8a964,79757a79,d4443e9e) +,S(29b5c3d2,57674ebb,1cab5fd0,56534261,5a059eae,c8002aac,c000a857,a7b7c840,e7724381,f3f1cd4d,198a06aa,33b7fb9a,d6acdd57,45f900d7,be34fd6d,4f6dd41) +,S(f4b9c47a,2454985f,e732c151,3216f7aa,f5de769,89344c0a,4b8b46fa,c15508db,9c51095a,c45d901a,75229288,fe5d49c1,1dbab43b,9a030cc7,c6d71bf8,9d097378) +,S(af0dbf55,79f3f1f,91847143,99a09fff,75c8922b,48213c42,1cb17d11,2ab7ac71,56e7f5fe,e96e464d,50cf98b2,90a04917,430bc2c6,72a411a0,842149,8fe23d66) +,S(7ddbb2fb,f5d68e,6acf574f,1fba12e8,323e06d0,b6b80cb,1b9e9368,5543a8e9,888670aa,f057a051,1738d69d,162ac2f4,9074e5ae,d28cd6a3,a30edf9e,e874d7ed) +,S(43612257,2c25dce0,4a0273a8,a83890da,3a27848b,103d5ee9,1f0bb33f,ddf131c8,62cf1a80,7bdfeaf7,7b9d90bb,ec403b7a,b4261e04,62a16c58,5c9e1435,afb177d3) +,S(8691a20c,6df3b947,e173735b,d764ce9a,4a7773b4,4b4276a,873786a8,8e5b0932,974ca0c,6644983f,e4288afa,a80c03de,fa8d9215,c148a63f,1a1d4aef,365d9e81) +,S(7376518a,528c1190,b95cfdb,ef241485,c84f34d9,3690041a,e4d8b0db,295fe87,fcd56fa1,3d5cbebc,ea197636,ad3e7bb,f9faf472,56d44489,e7cbad3b,ca9e01e) +,S(9c5e491d,838b7471,87eeff8,f44ebd70,d6087ba7,fa2b957,8302e46a,3e5113ed,3e312d47,a32d61ee,f88dcb4d,aa38b024,7327ba59,cd377798,75bcd10c,2aa13278) +,S(884a9710,9e6e95f9,9a52d8a3,7b91480,d33a95e2,4f385ecb,d9666bc7,ddad4c63,f39408bf,4f27f2f4,ef65b195,b231edc6,c50aca83,60d23ff3,32b1c3e7,149e8d6a) +,S(f99760ec,771c8f39,d349fa7d,19b0ff65,bfd2ebbb,f2d4707,eff2d646,4beca7fd,d71a5750,a9737ff1,bdd2fbbb,9674905,5508c2eb,ad22aee3,6aff09f0,1fc9d996) +,S(f2cbe279,98214502,77f79ae5,22da1671,452c8e94,27562e3e,5d78fc17,9e758e2f,8334d592,9b50b714,a50ead97,6fcd8b12,f9806edc,5da45d8a,a226e029,282ab52d) +,S(df67bf7b,861d0636,30784bd7,f9a472df,6c2db3a4,7af8d06b,ea3665,cceb76fb,e939458e,513e55b8,7e4b90d4,3f073e47,620dbdec,d7ceb425,1353f4cf,a8d20624) +,S(e3f17365,4bb1e860,d1812852,c67c0095,50f82b34,434c5326,d5864884,bf64fcb3,9f07baf6,ae6b8c28,e8a9d807,22a97f51,bae7c98b,daa09578,5a2d1fae,3f359139) +,S(1cc073f8,ac4fe62f,e311eb31,42bd357e,45ea17,a844528c,7261bfb8,24642103,52303125,ef059a48,142036a1,ab6353cf,90a021d8,30a936ee,9cc4ffc4,91f514b3) +,S(f6b037a4,9394a077,7483c0ef,326e694c,be4b01a0,3accec75,629f7224,7fce7f0,f922659,25e4434c,4054ea7d,d4bdebc4,d3801c39,be53b037,715c6ec2,88b34db3) +,S(74966556,eb8c4cbf,cd364f06,b2bac116,5b914c76,d394dbf6,b5f2f7ca,14e54207,8ef7ffba,85b9eb27,f444de36,86ce67f7,75c8eb30,5bae0c6d,1962c839,a88202df) +,S(44d3ad0a,bd1f2ad,30957e00,594f7738,18777896,9b4237cc,d61931fb,a564ff35,af69cb36,28168fbc,f194f55e,e7691ca1,88178a44,2e6bb250,84c6ea77,a3d41748) +,S(7914f911,b6956f5,cb0fa063,bff4ee00,cb67058,3dd4eeba,daa4e445,97f816a1,a61b333a,e72fef24,a47f48df,90b5384b,b25b5f8d,5530a5e5,117a4f45,43948fc6) +,S(65a31bd4,10c97121,dcf656fb,55a71c94,ac34ba43,c3219b1c,86f19f56,bda94c38,a2e19092,35d8b549,b1926524,132a5220,e26beb5,f9d87ddf,f46aae23,dd8834c7) +,S(eb092b73,5b789bfe,9a466b70,3801b511,aaa33260,407b8750,cad24563,abaafb49,ee29705,18088ea6,132314c,999ee924,5f50346f,c7a9d114,169fc20a,2e6b6a42) +,S(38574e2e,8ff7d427,3870b6ae,d859322b,deac3824,bdc1ec6c,e34d88a,8d92196f,a0a6691b,4d770ffe,e5503d61,bba954d2,f4185860,19aa60f9,303f3e89,9fbbc7d6) +,S(5e555cf3,adf0d5fb,530f87cb,6fa753bd,e2c09d9b,d703a899,f27d2a15,a051a64e,41bba138,c76d1e98,90ce88be,1053bd3d,559e7118,4b900aff,c048a494,24e1768a) +,S(4e8518ed,92b06242,b0f28b2c,e02582db,e5f908ee,fc660c63,964f5e88,95b509c9,9e4fa860,cd07c071,fea0ccdb,f1b9284e,393d9f61,45dc4ddd,5ded2dad,b8897e5d) +,S(507d72be,dc881de7,86103317,77afe208,69619a4c,f6cd3012,e04c8cfd,2029b562,2f2ec47a,963f7c86,de8497cf,fa70846f,22dad843,29643444,706487c7,d9999da6) +,S(c87295fb,299c6f1b,410f1128,a1c88eb3,4467d0b3,df7dfcd2,18fa3819,58df06f6,2977ab13,5abd0c43,ef791c18,5cdd6b59,443ad076,5f190cd4,77620227,dc38c479) +,S(5f9fcb3e,2d7f842e,22ae0d41,48d74b9b,66b8d98f,fb66e4d0,1f279be7,931731ef,523a9ed2,a911ec36,87619cd3,f7ffde07,e11a2b19,e90771b1,8ff86170,a747193) +,S(42d833f2,b9717832,1b9174ee,75127d0f,5a850a63,52452942,56fc4257,f90f74e7,fcb299b0,ed234bb5,4f0c9ad3,e9a87bd3,f4a83bd9,916c9050,6952df68,f39dbda8) +,S(cb173f92,400cf477,47ec4ce9,f9852778,6636247d,55279b52,81388daf,99b77f68,f9d99960,1e669f8a,d8283ced,317eb2bd,5aebe201,ab97a62c,25573a0,65b28e0e) +,S(a73a52d,a2ed0dad,e9943a25,8e6a1f0b,6b2b772,b010d81f,a6eb3bb1,61877d65,71f7bd19,7e9d575e,25a4c592,92061743,2cf69ecd,f33705d0,3429966d,956a2e58) +,S(209411b0,398bdbaa,7412b2b1,49162c31,da88d9c1,5dd4db67,8ab3e19,c90a8415,1392e77d,af6bcf59,3162c8b2,2e8ff0b5,4ecf8e01,4fbdc743,dda8f061,ba8a24dd) +,S(74590b3f,a03daf8d,537d9eaf,410b6c61,780f4146,44e7360f,7d6e2710,3c8a6d9,d40fb53a,1f6768ae,b4918201,54dc85bb,62c5ee68,614f1e3,b6cbbdb8,e182d9f4) +,S(cd77abfc,78148f0e,1acc919d,e3afeee4,2cb6fae7,5f68ce7e,cd31e3a5,adb54544,a46dc809,f9b1d0ee,4ba8872f,95166de3,87b08a0,b68b3622,492841d3,f4c8ee1e) +,S(ad1d5f2f,ef4890e3,5d1916e5,2dc6bac2,612d3b0a,3511ce92,94262b7e,fe2da353,6aff87fe,3778f197,ca8b1a67,9b8f89f9,69fcaaa5,4ef0a629,c0dd311e,ae83e568) +,S(de45c27f,fdb38ff3,a91c0dda,56076875,be8a1369,23ef5a55,26af8829,c9a17705,43564551,83b6ec8c,48c1daf8,d8f0cacc,4b3bd932,5d6e5adb,89368834,2ef5ee90) +,S(deba00f,aa0d172,a6bf1c71,6d280e2c,8c8e35ba,9c15f0cb,ae574940,fb78883f,2b282f66,c9499232,dbe30521,da2298c9,7a0dfc43,562ac5af,74eaac20,1d2dd708) +,S(eb95be9c,eb4d5db2,ae9071,e5dca616,dcdffd15,762dda32,5d13b576,f6532b04,c21f9054,d504aeac,79f98cda,de167ee,60e8cd52,bd44e4e9,3d66e2be,a9867741) +,S(a2849585,a2d9d78b,9da83fa0,cdf7f4b2,62c29e29,876297fe,3ad3bcc3,691acca9,a165f5d5,9ba43cba,816ddc9c,b33c4d14,e4f768e7,96ce32ed,2f711127,7bb8c720) +,S(e5a492b8,cae88b61,c72c8772,eaf6de20,40c89597,a4c4c703,85c28e29,62bdad2d,a0dd4bd,8cc5136a,184fd7e3,aa025c2f,62f85693,163e726f,cffa37e,2be168c) +,S(875a7369,7940cc11,b00b28fd,c72b31f6,19c9018d,5c261af,f1cef7e1,be71b61f,93718642,241a4e8b,22760240,2b4f4e1,fef54882,1af31e69,cd45afb3,427fe8c0) +,S(39a301a4,69836ad3,f98d7086,24b53106,fd9d9aff,c1253059,f45617d6,ad6c0c7b,a7f00229,6ff382a6,4bcb9dd1,fd9afb5,4dfdc2f2,bac962c4,8bb76603,7224a403) +,S(8bc53451,922203aa,caae8513,4deadac8,10c585c9,f9fb44bc,57113a31,9474f090,a4bc9c8e,8ea5d122,54a6cecf,aa46b791,68cf14a2,280c86ca,177871b2,abc65b8e) +,S(796eec76,37c1fc11,3ef31366,dbefc78d,ba5735a9,28505c0c,e2a22ad8,b447b1bc,11e91c1c,f9195b5c,b8948081,7d8ca5e5,f0fa07e0,19ee5566,90da195b,c5eda060) +,S(ac52e134,1b531c25,60efb2eb,1c0c79b0,d1f3cb6f,3bcc4b16,6a7f701d,7d5a60df,4415cb74,b2ca5b76,985a1386,2278f53f,871813e2,905e51a,cad23265,64efe34f) +,S(c231c57a,ed49f271,2d571e10,fea59a11,c4d427c3,4a67b024,b4713af7,d2288d69,bb4ec242,6026ce7b,56471afb,c4ed8772,dada1335,61d07981,907d278e,70ce398c) +,S(1a1b76ef,11f3d64c,5670f06e,7354fc4f,a7c17129,75ed3094,b5a6df78,c8c03034,600c7a61,188e6ea8,76b8bd21,b121ee22,ba9d50a2,d2ce0fc3,d836829d,1f829430) +,S(82b4e49f,2d9d49c0,f409ce6,13b65a5,c031c8fa,adb3ec8b,62885760,c69bc5,67b8cfb9,56b80bee,5e5ec168,6cbad5f5,cddf38ae,3bffcafe,17d242ab,896fca10) +,S(bb3201,8ebb358d,575cf58f,c08426b2,f7116d40,8cd2d779,9acf6c4f,55de461f,8f3205b3,291c8da0,b0ebab8b,ac292913,12ad3a7a,83ac3ff1,6e6f55d0,445f22bf) +,S(fab9cc75,60a02c8a,e916bfe9,b61cce9e,32d37203,8b42b58,150db6a7,cdd40a22,132d8021,8e3b6ced,e6b3060,5812823b,80c7f0ba,f369caab,8b3b7cb3,bbb477d1) +,S(9f96535a,bbd2b21a,bf41bd19,549528fe,1353724e,cfa3870b,3df3256a,661c7e47,b8acdf49,a9783748,40232e1c,9a0f6854,1547b7d6,d1d60bb5,c321a1b6,54fee431) +,S(60d4754a,2faf463d,f7b0cc2b,ff4e6495,ea9fa9a2,e2f1f4e9,d773301b,3d406daa,43d16225,6bddfb93,3588da3e,511ec648,5599ef3f,7db3a1c8,899c21ea,2fc91936) +,S(3850610e,10a40ef1,5aaf4d4d,b11ce214,7c82a449,ea965cb2,5cd9ad46,45ba44d8,c10cdca4,aa919f20,4ab148c7,2eb4e6f3,7939c70e,e134433f,5c70e45c,fc30be3f) +,S(68089586,3a26181,a6966055,1ad8d431,9d325533,70839d17,fbfed5c7,fb84fab4,a0cee277,97d2ff7f,fb7a6805,604eec37,4ef4182f,a163c53,15924f,287bd447) +,S(aee5d57d,17a9167e,9d3ff19e,8eebeb09,7675b709,e3a89ec7,38280b9f,ab9404da,154f14e4,f991644d,aad6d858,940a6126,5a8f1c1e,ef6071db,5e138081,5e2d34c9) +,S(8f3362fa,659c58a8,2376ab88,c921fe2f,2c8a5de,f36c057b,3154800f,bd493950,5f88cf3c,3fc1ccc2,2105f3c7,8ba7b8c5,525a9fa7,7cf76976,8906d0e8,caa64408) +,S(2bfce32a,9d69a14d,324d8f94,15b42f87,25f5befd,ba3cc6ac,2a5c7778,f23187a3,f7e88e0,51ea8e3b,788e18e2,95355b2a,75fc3c3c,e62f7797,d3b02681,d6a3b63c) +,S(62984e62,5d026f0a,c6c82fb0,46dbc152,a05c9a22,3f55663d,5cdd87d1,e094022,1dadce42,d6b68fcb,19439f33,2d2db167,f33861de,28cd303d,c94e3a8b,7b26964e) +,S(15502824,b02a10a1,d7b13137,4175bcb5,6b70f796,fd3d0713,42bdee98,99d8a057,b391d51b,b2b89dae,5b687e16,e2ce1351,2296130b,e86a7d21,c1d3c6b7,b20eca57) +,S(1bd98bca,c0ed80d4,f23422d,c32c5922,1164ce33,55526ea1,61e1d9fe,518c0e11,6b0afff3,b0fa5029,b4e9731a,fe772fca,c0e30c84,e6c652e0,f22dfd41,a9cf0ef1) +,S(4dc9e532,d5543e88,a59872fa,24b99968,e649977f,9ea08bdc,303ca4e,d574bf40,7c05536,d9181687,133dec90,43cae3af,42dbe034,af05a746,b6de1ef8,20276947) +,S(3e92be78,d7c7db61,1049827,42b0d213,672cc543,c27628cb,f5985c19,5685f3a0,171c3afe,c69648e,7bb7912f,fdfecc4a,78cfd246,a4fe1263,e5eeedd5,330f84e4) +,S(57b6c4f4,75bb9ce2,2086a5a,dfd5473b,73b0f6d6,278afc7a,16854e6d,32b2842b,4fb4aff6,738f05ce,31ec7934,3638a717,3806d347,c11afd82,e39d492f,b961ebb) +,S(571ac8b,835c5f4,a7457344,e8572910,309f0d3a,26b849a1,b3bca2a5,28771b59,317ae805,3aa2855d,aaec95e1,72f4005a,6ae09ce7,187590b6,41fc13c4,9bb4cf9f) +,S(534c2141,e38a7880,bf146951,7d4ceaf2,a25bf5d6,a538eb1d,4161461a,ae54c4be,59dc6548,1b056dc8,c3e98364,ce6b76f5,fbc9c501,6ff24e0c,1c7bfffd,306b03e2) +,S(7a761f86,3a224193,157d3d1f,8fff8a05,e5c13366,a7ef7604,2cd3a1ff,f9f936f1,20e86bd4,5e93b784,f433d6a5,8056c6a8,e8d1fdd9,e924fd37,bd5b16fe,fa0ece9) +,S(c1497e7a,b9373d32,4bfe813c,32aa9dae,f1351351,c86ed382,fd3d4c5,6a54f62c,9401bb9,1621a327,2c233004,d6a8093d,f812ee66,604eaa86,32085b3e,482eccf8) +,S(2dd83787,e31e7237,f49a570d,adc675bb,147b91e1,3910f22c,e41bd16f,edf3c0bc,10148349,6883687b,7ee844f6,d60ee90f,1aeb7c0e,c9f83293,be96eb2f,5cd6d46d) +,S(938f1399,18a0fe3,55ddc7ec,d6dacd34,1d9c996f,9ab4f9d6,90b435e1,fbc0a74c,30c71b30,e7a3c244,b8a576be,9e527e6e,60d1834d,17908e6f,a0771daa,92517448) +,S(e71217df,430dc65a,d188f6,861b00ac,c3214125,447d8e26,7dc5473f,9471284,8f27019f,114e542e,96eb5121,b7c3e094,f18f6287,f2cefd9e,6a5290e8,5e1dbac0) +,S(ca2ba87e,4c040efd,c06ca7fa,50cbe414,b66bb2e3,ded2bfdf,7744f81a,91b102fc,24848b82,4019bae7,4cd7604d,101c4819,6e808ecc,79db885d,bed68354,ba3f138) +,S(c267ce5b,633c7f12,1be2b297,45b4dab9,ff488b02,c8f89ba8,706948c7,77167ad7,16184a77,954c3b5,f9e330f8,e8b308de,1489ebe4,bb9ffe59,f3f545da,e7748385) +,S(1eb9af42,96d58c44,bd6fe2ff,db05e0ba,1b5f581a,af842883,5a47a050,468f8b33,f88a1128,95e53e05,4e514117,5a2c54f6,a235cb08,3494a7a,991fba4a,fd0bf1b2) +,S(ba342b95,76bea3ec,15aafca6,2f4f505f,c35bc2ca,64e2f4be,22323b77,1ee39062,91be5746,1fb662f6,cc28e73d,f0dd61e5,20cd3ceb,2d6fb0b3,39a76e5a,39114afb) +,S(f3a8c7f2,86117118,a4714895,eda7f401,dce4be87,dab4d4fe,b55068b4,c948b350,1dd2f669,31f0ec62,74e8bd53,97cb6b50,d97f9238,2603c931,8ff1c6b,18893bf0) +,S(3cc304a4,3aa02bc5,25437a89,977b8ee0,9f5f997c,56c4d317,f531d22e,4a60f55b,9ce121dc,cce749b4,78823adc,c9a613b8,aaf78f5d,c2eac8b5,d5ee6aed,592c7bae) +,S(e5be6c29,b9f12f42,1f499fb1,13e54bf4,4a577fa6,d8d0dcd9,6b509f65,1b4f3587,7755eecc,721bdd9c,c6e8c96a,d398cff3,c03e77c7,9e34dfac,1f51873b,8771d40) +,S(f933bc46,f296b780,4284de6d,5bbeed68,bae90bdc,cd731cb,b9519c05,278c7fda,b6ec0484,faa4c53a,630a8b81,e1d567dd,543a4e55,4e89ba69,d72646c5,7ab3740) +,S(e1d21ebc,297edcc2,b595976b,2f65b2a7,a6797cfa,3e5abd27,34e2a962,dd2f507e,aa31ee8f,4c80a0fb,9e52f32,c7e4a69d,fbe8d297,8dba479e,b0c9f4d0,350012fc) +,S(c3cf0aa1,8e45aa16,343c52ac,41b12278,f9899b46,e17ef9d,d7b67f75,84a1eb72,174cf510,70418a6e,f83b3db4,97102ca9,5bd99985,f2554e5f,c32cdefb,ba47e411) +,S(e6a90aff,6e1f0311,34f93967,538040e4,92120644,8e8e2106,dbba6f5c,701700f8,93895ef2,1d3513e1,19228b95,86289c26,f3efc024,1ac2c963,b394cb87,265638c8) +,S(e2b695fc,8f1856c6,131761e0,9f75a558,94a4a7a9,2837dd29,f8e8a474,7a9b9a91,b580a2e4,240724d,5c5381df,27a17d72,4d0e638d,958c0a27,fcbba34d,da5361d5) +,S(c0660a14,6db599e2,15f813a9,f267d6db,4542a696,9b08334c,6bc80558,ae518063,6a901346,6bee774a,54ec2f97,47d7a8d1,e157a13,fcde8cfc,57e48d84,374f6ee6) +,S(5c41cced,2b091fa7,df1f8e30,3d78b117,842511eb,41717b59,f776e05e,39daacb5,dc4964e4,d91fc985,af5c0f87,f0026a6e,290bb1c0,b181fe2e,195f7001,52509f40) +,S(6abe8574,49cbaffd,d0e5fdf6,450484b5,f8636170,5c8a0a59,a3612dc0,8d0d52a1,c669b059,3a5fadf6,86b9583e,7fecc9f2,c5eae967,9eb5be36,a2018337,64703bdb) +,S(560dc0ec,2d407e81,4b5034cb,8d26c8bc,7c86487c,f74e2fb9,a076b521,f68e22de,faa241bb,ee929015,b4183152,5aff5062,3a270bfd,6026d94e,c3106e3a,e66783da) +,S(f3ef40ed,8d82c02,a141b953,e8593f06,b74b244a,b85edb18,eda3e693,3c8f90a3,aeaa6d25,6db6b12c,d9a6ab5b,d6d0d854,62c0d298,5a772648,db46b614,3050d4a7) +,S(413e0fff,df030385,248b1fe2,1bebedfa,77c1cb86,d665790b,21914da4,58a4479d,6fa9db70,80ab1736,ee7d54dc,e5d1b545,dd17e3f4,45b39038,595fe180,2b34b443) +,S(ed3c5ee2,cf1cc502,37e5c654,d903083c,6fce29e,cda0f427,5a6e1ac,940b8183,fd265e79,3474e60,109cac37,a867bb81,d8ba8b8f,94b13f08,c409ad5,362492c2) +,S(b98e14a2,3f5e5d6a,a99ef39f,18e234d4,42102e72,2e330d2e,e654b328,e2f3bf49,67a60b41,8e820ef9,72ffa57b,1e383b1,35585920,20434df0,e443c318,89734499) +,S(31bb6293,28793b42,dbafdc9e,6a418c51,f0a0cf0b,6da96879,11a6f046,c146e475,1bdb131c,b14a3d85,a532f889,89112231,341a546e,c88e8a25,8bfa341a,7826512) +,S(79b2d26f,f257ac80,ca67a639,9be17ff1,8ea0c10d,739b106a,a9310754,6ba0b252,e09448ea,b102b1cd,654b6e1e,7e4754e1,c63d11c2,46b0ec5d,31df6175,6b99e850) +,S(ab8cbf8b,c3a740d3,c1bfc2e6,efbd7ac,f444795,cf2e311d,edfd5c2d,124d55da,70599847,895f335,a8bd33f1,811201b9,a860555e,8cde2a27,4c348b4c,6ab449a5) +,S(f6b7c2ba,c5468fb1,cfa0785b,f67972b5,36367ef4,d3dc9ef9,25e88085,524e6021,663be56d,c325b2e2,3753bf15,1f6b2ea0,2d6a62b3,a3d5f565,2734401c,9c661a3b) +,S(f5d2e04d,229d784,d7af5af3,ea65a35d,637b404b,c431ca72,1bec7fa4,dee33377,16c90231,e570a434,700fd8e7,cae5f8d,fbfda2e0,e234ef23,a2e82452,a0a953e9) +,S(4df218c9,4277fac3,3ca43921,e29fba57,6f183e74,fa2ea781,88b8245d,eddab853,7828e929,6c589e6b,1d80b036,2c9bb0c9,2c2a79aa,378c597e,8a64b985,d6e4d108) +,S(60e1cbc2,78d4a0bc,b7973b32,964da674,9e2b3448,24075a0d,1db93e51,ee3414c1,cec0aaa2,3db6c3e,6d6c3189,c2dca9de,8ce91791,a721ecbc,1f09c7ad,468ee8c5) +,S(1e7a9c4d,a6cf3251,559d58eb,bafd1a7f,ee686c72,8b1ad271,d9da3b15,6a9f3737,794e3bbb,cdc0df3e,b9669a10,8a32d7b7,f3fb843,388cc55e,aa893f64,ce1b960e) +,S(e8984316,5ee703c2,a413c7,2a5c8ea0,605c0b4b,58cb844c,85df83c3,b4f361b0,69fd6f89,5cac1716,f0bacdd,5a880f12,f964c2cf,1cd402ee,27ccdbcb,5188b64d) +,S(2b95eaae,6078c535,32a23225,eb9821e,c7bf864b,75187df3,2736459,f0797e4e,aa6e1922,b5102e69,77fc23b5,ac2de98c,edcbcc37,54c928b1,7c7d124d,980666fa) +,S(403c1933,59ac9027,7aed0f41,f9ebc507,8ae553a6,ec3b8a4e,4f66a841,19d221a0,edab5156,8667e7b2,c7793e17,839e46e7,85a6c7a0,8af7295,8e25b411,13829ead) +,S(fb182399,c535de2d,556ecded,54e42f29,8c0054a6,1dea2477,9df1c7c3,bb53e1b5,7bed179b,73268027,4fa6b227,d13763d8,4fa62dec,2e351ac2,d3aa59d8,8961123e) +,S(9375a9d3,ecfff9b4,b672d90,45aa4872,f61c3b8e,4cf86a38,7daf74cd,affaa521,41c7bd13,f4e491db,77a42bb8,d65ba77d,f03acc6c,cd789759,37486d08,c3f691d4) +,S(abb9554e,1b68c554,81d8bb12,5b426a4c,433cb110,79254f8a,ddebabd2,9f5be0c7,946d680c,1bee958d,32089353,41ceb7ee,5b4a8168,a6368a92,e1ab1050,5d0e76d4) +,S(56e8aa51,37b38531,1e5e1097,4df857ea,b4f7e53d,11102021,6463c212,ebcb873d,b51e1981,7eee5672,afe7f688,92ada73,abe703ac,4e19770c,97dac300,8d3b1632) +,S(ac487fb0,4b00962b,2b098cfc,4f22eb28,e5007944,d32a136e,5988dd47,d9828f5,bd305529,5f4200e4,c5e6238d,76665bc7,67ad8402,dad13d8,6c6fb316,a214a5c) +,S(1dd7562a,ce273114,660ccde4,5f41d690,11621bce,56cc49c7,2016f19f,d94e9e9f,a8e8861b,ef664d9a,c19391b6,5bb97715,ef677199,a373f255,876aa9ad,d8a93043) +,S(c198019,cda66df3,2bd528db,e3869d6,1d1d7cae,57ced846,eebcf1e2,bcceb8c3,b0a9c52,ae2b2625,7699d3b1,861474,4d66f09f,8b795d81,acd3e5de,902b247a) +,S(950f54ab,3cb421f6,95404b53,9b1f4936,6b43e61c,7bf9879d,168027bd,f58dc386,e14586c,7f005f5f,21e122bb,2a35194,d5d2fcfa,4898c279,cc296b24,9b48b2a0) +,S(5b20af8a,31b69820,a56d0df0,c7374c8a,37805449,81e0c017,83b4ff49,2bd40ed9,7e49b8a1,c5bbcb32,55991da7,99613598,cfab9d8a,82f731d0,dc2f52a1,6ec39c55) +,S(eb8a10cf,3777670f,437f55c0,2ddd8681,63da41ff,5b534c63,ffb23ac9,ecaed755,99c18d8d,df2ba9a0,d46ea92d,8b983f50,c16f14b9,86b955e,a577f332,10533df2) +,S(12977f3f,d75a9c72,81358c91,73664b40,8d8ccc98,45153ede,c62b189d,8da2b176,f24f505a,75761c5d,939ad836,17f0c6,dfd8a2f3,fea04721,9078e2b2,1aa317df) +,S(7a591539,ff4fc3ce,2e2936d3,50d753fb,131ba419,8d034c65,e76d0744,c159096f,c95d8b25,52b3920a,6341ef43,5e3e797a,446565e0,652a562,7e0674c7,ca243425) +,S(993061ac,819fde52,ae500ed7,3277ecb,fd08930f,8adff61d,f5f9c3c6,cca49640,d54444ce,748f6058,10051838,52f0073a,8a5d1477,f14111d8,b623a316,a67ad06a) +,S(cf807c40,c5664fbd,910a31bd,ed3cb7e5,2e54d1ff,ffcb4b43,7a579931,6f803051,a5d21e6,6fa9b5a8,2882b77b,ca66b6e4,163d579a,d245d089,602274f4,55ca9881) +,S(9c0119ba,461d003e,c6fb7a01,2bb32b89,ec819d97,8fd4cfec,ca1c3b2f,1f14f0bd,b41c5fa,ce1e9a54,f1605e84,61b5e6ce,c11590c0,15838059,2c511360,f4b537c4) +,S(56ea3259,5d97b7f,d7f9fe51,b525d73d,3d77d483,f8bf8460,8d874d25,aed3da3c,f764a40,2cc9278a,f1ae6369,e1723bf5,f0a15a47,992f8fe0,ae33752e,473c3058) +,S(2851e3cc,2fa6752b,e0a65326,46aa8445,71736e1,d22a01fa,ab3becd6,50460acd,ad778ace,631584df,da4730a4,20242779,81f9f829,cb18b20f,8ce727b,d62d64b7) +,S(1674559a,528fe0ad,5aef46f4,eeb4e0ba,34b8c2e8,c23d3409,5ec1e164,ef351979,afaef98e,ee2ada75,7be9675f,fee76686,d2350972,a9d1b80d,fbbc0719,efc38b21) +,S(ede70ea,37946f71,848d72fc,7a98102b,f9c167f3,219671ab,1843b5c6,8ba6d7c0,920d6108,6929e5b8,30c4fa,eb155b4c,9d324001,59d748c9,d7e74980,d54be37b) +,S(fd3b1f22,c5037c8e,93f4f9ac,27ea723b,3d3e861e,694ef349,dfe51f83,50ac9fa5,cc02effd,6df18244,fcbd177,a624ff17,b0da8fec,fd60624a,3d066be0,9c466cdd) +,S(72f037df,352a4619,729bc550,e23ad7bb,6f2d7977,7d39ae36,bbc1d45d,d6e864c2,c4bfcde1,2a5cbba3,7e047070,5937c2c9,da702040,bf49cb5,c762d60c,e8fca76b) +,S(f17a9b25,601ec8ef,e320558f,ca832789,d0d8d558,76ff7c53,6af0f84b,ca799a61,c90583c6,2a863567,b0d8c41,e47c3d8e,7e196a1,9269a409,31a1eab8,f1402837) +,S(ea9fdf49,9e201fbb,b0a26a71,1b9be2e,dd17b2d2,b96390c,4aa2dd00,83bf5c86,64322654,c8bb2a83,ab0cb743,eb907234,d8503fe7,381e17be,c17bad5c,d33b4df1) +,S(8d5d6f0a,24aa6e3e,7dff42b9,ab8b22aa,656788b1,1e18ca35,b4ca6f19,1d50de6f,d509a2b5,e9800d5e,a7d1d047,e945e693,2e5c1923,59bb0210,1b2e8956,33e0257e) +,S(25ebcc4e,84a1d22c,f0a8c980,8252d96,7dfd528a,808ea293,ffcae94,50e1fb81,3127af8e,4012c2b5,c92e428,2e455de1,681eb1b2,6e660fcb,4ee8fef,b64c6101) +,S(c55c17a1,dcd8fa41,8a3edb5e,c2da8678,4fed0840,522b24ed,4bcb85c8,cc45c20,7d583091,25261489,44b56fed,17b07906,9d156fa2,e9bdc462,eeddeebe,68f4f463) +,S(f4297f59,21a867ba,1e58b9e1,def633f1,18e058d5,a7889721,f0e4814b,7e63ecce,a39f359e,35a123eb,5fb66d81,f117858f,b0557859,aa2c388,a8298d11,43f137a9) +,S(626b0a,cbcf0e7,daf7d218,74f72be4,8d824883,4428bfee,f82ea516,c2d1b98d,74ae6867,1c27a642,53a36590,5247cbeb,77173b07,2e429de2,3ce09730,8d54ddc4) +,S(8ed35ae3,c02c5db2,acb516f3,2d3b6823,61964f2e,701889ab,26dc9512,ed40172c,aef4c71c,e241be56,63a091d9,e230463d,237e0717,78b7b6ba,a63688c7,6c694334) +,S(5b082ab8,963510de,46c1cc49,4ac6d3c6,dfa25f33,8627a00b,6b98121c,73899ed,cd8b2b84,185718a1,c4686ff0,7cad18ec,fe3d4532,9537910d,31458086,c280bb32) +,S(deaf505d,b08a282,d5274de6,43c5719d,f51827e6,2ed035f1,74279276,7ddc1158,c1067344,5e4c0d47,ad1ca85d,713a5916,1aef6960,9294d738,103b945a,e99ed1c4) +,S(eb62dcb4,d820019c,e865129a,28b98b5,be6c6e16,a80f7c76,db3a15ee,31ba7aea,e78eec22,be4a175d,68b2257f,c5adbe46,fbe31c3d,5eed4736,2304d80,ae4577a7) +,S(6c58cb64,7ef638c2,337cfedc,a9345837,597ac142,577b2230,7d231a3e,5a9173cf,563008a5,7b823427,60bbc400,5f604024,92f0bcf0,2ab2430a,5d7accc5,b62cbcd0) +,S(106d8978,775a41b1,12f07815,7c3bc5db,bb5980d9,c745806a,b5ca5ede,8b468d51,bf960349,6f7d7906,141bc4fd,b1766102,e8dfc49f,decb469f,75dbc54f,21338dab) +,S(cd6124f4,21796b6f,44c34982,8b536ef7,44bf30ec,6ca08142,e959a35e,c0385224,97ccdb9f,2896e815,19bbe9e8,ae491e61,e83417c6,6db8b6a9,bede3aca,f6608ea1) +,S(2918b2d9,b0bd83d0,b8d02815,59219c6,bd708e2f,2139ad0,1815b1ff,ae60e03c,f322596e,c56984f2,e7b2ee90,8a9bb56a,d213f84f,3088aefa,67e372f2,76e2a233) +,S(6d3fe999,acc04d13,2462f14d,680a90c9,89b747f2,3601d779,507c36ce,8c2acc7d,a6c7413c,36b6399e,58a443b4,e4137ea5,551a9fb2,c5397457,9d55b48a,5df0e30b) +,S(bd74ac79,8b320aaa,e3e51123,9354d4e9,280c99c2,809e88be,13980305,62d55d52,73477881,9b9067a0,78b40108,38ae59f4,3f6ef064,ba35209c,46a9f0dc,aaf84597) +,S(303f6cbe,866b4574,9d282217,1f571fb7,8c54dbfe,901f2f43,681ebb0c,76e5700d,b13dea58,d3dfe08,7fd043f5,8e63e565,85230d6c,273d9e3b,22145e39,afd6ea4a) +,S(3bbb0824,16a2e3bd,e328f013,154f18c1,4e840030,707057cc,f4fa0fae,ff56181a,18b214c7,823b0cb1,76375146,7a49bb8c,ddc0047f,782e3802,be12a119,ecf0f480) +,S(ef42fcbc,999a3f80,b4e7319b,1fafc2c6,49f51845,2e423c55,f57e5e1e,f8338adf,786ffec5,60464882,48641155,38aac187,ced4678a,cee2b9ea,eab6ae61,ab2061e2) +,S(afb21e4e,c095bf31,34276f4e,f1a4883a,6038c20b,a7a87ba6,6288bb1a,3bc6f77d,cda832eb,73dc0e9,fb77315f,6cc7a313,2212c7b4,1075a290,d5917033,62363bad) +,S(329c98f5,a40b81bd,7d121b90,78b50bdf,bc16c9bc,47744368,34a5208f,20d39d63,dc14f7d8,4bd2a1e7,22fdab98,1044d6e5,98515df1,7da5536c,7a95866d,8231a) +,S(6929a4df,e15e7ac8,e8a9c5a9,3544af51,aa621dc7,ca04038a,9c9cf603,8e081754,e1333f46,e4d1f151,f2b8c341,d2ff90cf,d36cf73c,6f441b4c,5c0ae272,6a25fbf3) +,S(f40fbdb4,27d2d68e,854cbae0,24ea5980,5948ca40,e3fdfcc3,3efea0a4,57e2bc24,33493d84,41c8945a,9e291b58,5e12789,34990a7f,5fec49db,ea1ff605,4bf8802f) +,S(220417f3,d9fb32c0,1439e473,d638856,9b169c38,1057b780,c9de7d12,e30dd796,4cd93672,5abc4e39,89e64ed1,af9b3d4b,4732ac76,a6c34d6b,23274573,8d765a1a) +,S(dcbe3dcf,2c0120d9,4d6336ae,6158bdf2,859cdb03,8c76ea3c,cad4ed11,13ed216,670823d9,73c74725,ce929318,c2ea650d,5feb7c33,c7831a26,821f2614,7db7d8ee) +,S(34de2319,c535a31a,87fd9b70,33c363e2,8ff754a7,9e0669a6,37230443,228ab3b8,31c65b12,cf6f4a9d,662238b0,c8ab52af,ceb96acc,35b90b2b,81667b8b,dfd9895) +,S(f0fb2bde,a5626729,720ff432,542c5e41,abf0fbc4,772aca7a,75b882ab,2b364acd,114edca0,74520c9e,2f5b8059,59c5273f,25d2e621,d2f55709,b42d187c,932b6bb8) +,S(90477ee6,a00742ef,78662c11,f3725077,dbda7b66,7ba55b55,f9bfea1a,4c5f88f4,467196ec,638d137,33971505,f291dc0b,b9d0f3f8,f284e3ab,9035273e,d9c7279) +,S(ecdef6b7,455a41ff,96cf943d,e489858c,b7abc526,e41d463e,b24a56f9,dd6eeada,1116e7da,9fe72782,e8c656b,9f677c5b,dfb3e46c,98957c30,49efd7b6,dd5d3258) +,S(58d30bd1,d8dbf5d9,885b6e7e,4f28ceb8,381415eb,3851a031,ef04b073,65e16598,9cb96ab0,546246fb,f5cc0878,7b99db0b,26c9bdac,184a0eba,728fbd26,bc880480) +,S(a7587d1b,771b3421,f56e342a,cca98e7d,82c7dc60,765a481,53379da6,fd341c10,9499ba9d,8351d194,213ba35,43d4b563,aa28bba0,9a6d8811,9b55f389,90742929) +,S(8aa99d89,9db3c7e1,c28bfc5e,18abdfbf,d9fff46c,560e4fc0,cff65ce,e18ae6b0,aacbc2e2,bcc4ae58,1e354d29,617afee6,20ced0ff,859c62b6,669cf2e0,565a9bef) +,S(45d81a7a,b4158aa4,2e45fe7f,3966d278,75f8647b,defa0c8d,a761ebef,894ef249,93a76905,d0e785f2,db52e09f,573a461f,183f672f,9f10005a,eeed6e0c,d40d31bb) +,S(de19bc8,6fddeed9,909eff4,80b0760b,66a1a245,82e33be4,55b8061b,225942f9,6eb2c1f6,f604056a,15c4e91f,789e35b6,1a787abe,aded0f30,abd2525f,19486d00) +,S(653f0e92,977b7830,fa546dec,44f05549,80f5a9f6,61f2cecb,7e360efc,41d16380,58ba9f7a,eb7aed3,40b54d7a,6f9ad0aa,ab5eaa2a,7715d8ec,48d52ce3,c3c57128) +,S(c05441fe,2ddce6b6,64270b69,83d44d5c,251efcb8,2bce4665,9388eb3d,537acce,cc82b7bd,3a049b06,98feacc8,11a1c9fa,e95181d2,50c0c62a,55a6d662,c9587d65) +,S(7a569bc6,a089fbd,294dd5d0,b10f3a7a,31b6bf39,42ee97d0,49c9259f,7adf0a7c,2399d17a,f6207b8f,20286fc4,78896af4,5e596b09,7c97f662,9bff0c03,14db53e5) +,S(1c4c7a37,4e14ce88,fd08a1b3,10025711,7d96878a,e173d29e,1ac53a57,1d6ae794,919f9b82,e827cc78,7352f0ab,99770e97,bfe1b600,40cf1034,b7c5178b,3d1104fe) +,S(fd4ef218,a09baf70,57b53f65,2ca1e2e5,8386e867,521dc998,1bd4ffdc,619c31c1,b1d2e716,64fec6d9,3cc8bf17,70ab5f10,a49a0497,ac1586b7,b8299f7a,e92354ce) +,S(f012612c,1f933373,ac30413c,1b2cfb9b,6582957e,b74e4de5,29c0267a,e7552a41,a38b2418,e7ace7bf,3a15035b,a68f82b5,aae49192,5783066e,f0f0263d,6dbc86fa) +,S(8e0d504b,c9598eac,c4bd2726,8b3ad24c,a22b7534,32eb5a31,d7e54948,d57f6f4b,50f59455,ba1ea3a,5a0cc105,a1c40c4b,72637a31,44bf9438,a1e3b52e,7b30911c) +,S(8635604b,89ec22bb,b3b4e266,3e76cb3a,976cc78e,c7db31fa,fc16a7ab,411ed197,8a11d457,6868d117,4f41c40d,4c82d27e,3960d57d,4b1309a4,531c2617,b1d90227) +,S(aba7addf,c234513b,3e861382,654959c9,984628df,72b2a896,6459b3c4,86bdbd2b,ddec8263,bfdb4c38,c9e7fd,e4693b0d,962c6e5f,a4f9eb9b,9561e81a,f04a3a3c) +,S(12aa3b40,44f699c4,8ff6c598,8a7ce56,84f3af85,8cf2ebd3,4d59ca7f,f7501895,76397e3f,3c42935b,6a42222a,525c2166,7662ea00,25decbf7,8a856391,a03956db) +,S(e01136bd,da38f328,af447a50,43a48606,a1ab5a86,b3bca98,b13a53aa,c7061098,76f3fc47,c1aedcc,bf26ec5c,4f6ad56c,fa163212,65844d01,8d2f2b94,184b64df) +,S(639cb266,f0672340,d0a789a9,41eec287,b60c380e,f2f62f96,41b67137,4b286aa6,d381e7bd,5dffffd9,50645e56,63c36d91,83210038,d70df2ca,4bbb837,e8eff508) +,S(eb12f18c,89a6d2e6,5e07d20f,f7acf3c4,b903ce68,5237aca4,5692c0e0,f6a4714e,d26860ab,e6f97745,dfb01cf,f6225c36,bf62e5dd,24088d54,a6d44384,e9eed86a) +,S(8fd06b6d,96f37c6f,8e69187c,c5ace64a,6e36b45e,37de82b4,872731cc,8781e941,e7dc3254,3b40599e,852d4e9b,e35a5438,ff68b063,3b81c8ff,c2f3298e,931e9e98) +,S(d248d914,4ca3f10b,3fb66763,713492ac,93b42781,9119683f,bf0e0f08,1bb6b241,e7a2ca15,f1867e9a,d19ffdc3,f1a20d0f,2469fa6a,e04f94be,a289d019,c405318c) +,S(ba2150dc,15884df0,34a64e20,89023947,687d1322,475dd073,b163a4bf,4eaf0740,af92a566,a320a0a4,34095dc6,f02f765f,4ebdf04e,d81e2c04,a86e6e2e,923f8c94) +,S(fb12f487,225a6843,31e39309,3133f377,a6f841a7,f6f90ccb,18ce3d39,48b56616,e3358a9,406905b7,d6bc0a33,6a89a5ba,e62136a5,4135c3db,bb32f115,4cf92b9b) +,S(bdeb3e38,7c36bb9f,c45a1d62,f7128217,20e6d0a6,55a285dc,da87af3f,f59e0644,b23fb389,3cdb280a,43275691,3c1de5fa,6da12909,c0ebece7,12c9da49,69a3cb29) +,S(32f3ecc5,925ccc13,f753ddc7,d5c0c576,e80402ab,ffc6dc77,6e8bf74d,15735007,f950add3,926bebef,9d8e3a5e,4d0ebbef,24b54dfa,ae7c12d1,32b6e973,dc67c050) +,S(94a725ed,e57e5162,817d95b0,54e2732a,3afe3a6,52ae3e46,ca9de38f,6dd9f0fd,805f6634,f8ba79b8,ecd5f46f,74b741a4,de5f9678,d29b8cba,eec73498,27671f67) +,S(22197e54,d35357fc,ad20f6cc,986216e7,f24e6dc,cfd9bb89,3e5c1ee6,9a99b3a4,b3e7edac,abb1d1c3,d375f361,1f04a927,9d2995c9,3e18e7fc,4b5dca90,a2a3fe17) +,S(a51664bc,5a1edd2a,ee8ea644,7beef61b,419e20ad,ac955847,5e1d666b,1b4dd52d,b8a95fad,e3aeac7,bcd8670c,78dd1b2b,5dcad225,277ca5bd,f24f131d,94405c39) +,S(896a11cf,f9db64a1,aef51088,baec42d0,16dd5a99,98262f71,a005cdc8,ae8cab78,7a7263ea,f64962db,bd09a278,a3958708,e61c4858,1a759726,c225471b,20899077) +,S(fff75552,46da269a,2124d03c,677f59a2,18b995aa,e69c85d4,3b29f81e,5201a757,dbbf1558,6670c191,9da69467,6e8906f3,80eb3f61,34c656b2,a4ccfc71,4b3223f5) +,S(89da8ea8,56f946d6,6e9b07f3,db5b2ca7,49a07e5f,78b59c1b,e52e46b1,3793e198,25889e02,d2013d86,6653cad2,7b3504d1,4e547343,fec74a37,a3ee71a9,646a36b3) +,S(d260dbae,6ac3e8a1,442ca7b9,8f7118c5,7d6cef72,783c0b3b,a4ad7e7c,3a8836fc,e00ee7fc,95131cd3,3a446bf4,c21b85cc,45a8e61d,2d9d6cf0,287996e2,77b7cb6b) +,S(bacf90ec,75ff002b,c1a259f0,3c9debe5,9f5f9dd5,cc0cbff9,e8fd62c,4552a619,82dedfc1,42202786,a7a12a29,22937c0c,23bddd23,4418979e,78723ff2,6a9e5e88) +,S(1ec23fa,995a22ef,53a91dec,a5b2faa9,514b5ef8,faf125ad,da61f84c,5b13a397,1568ab1c,cf75692c,b7d41c53,2dd4427b,ed7043e6,cdfe01a6,2f9bcb47,cb97435d) +,S(48225de5,eb07155b,dd86e759,9e172a3b,b96f69bc,ddcdb051,af2dc769,f4450b1b,856ce939,b81d976c,6a6c249e,c0d087cb,36e28082,ba050de5,4948d92c,6693f4aa) +,S(e9ac9963,16c1ff8e,a7d2bbf4,148c8b3b,a869d4e1,290168f,b3831d6b,3bbd164f,2b1ac664,6bc87e3a,e6914792,d0bda8b8,5cfe1107,3d0447ef,e4a65acc,6eac846d) +,S(8af31ba2,af0b68c9,4290bdf4,b4b80345,5f52ee89,f4ddbc98,1dda1000,9c1a2ec2,a37cbc1,a5efc09c,dc944f42,a66a305a,b302eb17,21ce5088,a7deb46b,5223f0b6) +,S(1d211de7,d75d4389,4cdac235,9b0b9e40,6b71b8a9,8c0583a5,7d7a0056,b3e88779,3ae4bfde,20f83eae,96982e96,62d65443,4359b2bb,df249a85,c7c83b95,56d7679f) +,S(be6beeec,18aa8d77,20100975,3dc7d745,c6d49f9b,ea64ebfe,b8fdafc0,92a192ac,c9e14aa2,4bce41e0,f444030f,ddbf035d,e808bc06,63a70593,454ba287,4ebe50cf) +,S(b126dd86,555491a8,e2ab601b,2f133960,d86a7f9e,bcd2c88a,cbd8764f,1afee3b2,d22ae79f,fbc60439,baaf2c2e,418edb77,70837ebc,a909322d,b5580c30,27c20821) +,S(857b9c62,6350cec4,f928d456,7d30cad8,6f1cfad,142b338d,74a137ec,61212791,9d3dc070,f610ee55,cfb9cfaa,4bffda56,52f7fd18,7f354634,ed4f2dc,d27f9ca9) +,S(bbb7d30,3e242e87,2e94e3b4,27197ebe,5252c363,43ccd8ca,940202ff,fe5775ac,f2b5b210,a40d1fe,140f8638,3a5b0f9c,96885d5,d9857a3d,252523b8,d59d33f5) +,S(3e90a10c,a61bd12a,fe9caabd,e52dafbe,8bcd332c,e0ff8bd,7718b685,89e26447,3a4d342d,fec7d557,7cc52bf9,d7c60537,50150146,8a05baae,7b562dbe,b626a952) +,S(dc1f2531,d5e0d304,66b963fd,7d09524f,c66e6bbb,3855b6d3,141db170,9af05fa4,f1644b11,e8291f92,4884d3ea,cf89d857,fc98c3fc,e49fef96,7986e8e9,d67c9b0e) +,S(2b4714d1,fd0aa7ab,6c103ae9,19493efe,4a503d5f,beba56dd,93a8c9db,485c1dad,d65bb3c,47efcc3f,7484b6c0,9f51605,30542a81,d1192ac7,5d506c43,16f41220) +,S(c9ffd7fa,3b14fce7,c2946111,e940ab3c,8199b7e5,40bface2,5d8e3b0d,d1a15176,3b40f328,a4539bd0,a0b71e5d,91a881c8,87b31e11,453d9f5,82066f44,ead8d5a5) +,S(e019b0e7,6b4221c0,e45d387c,6ee41bdd,ed5e219e,a7069b73,d92b6339,2657c39e,792691b8,4c8748a,cf10475a,955aaf5a,77328c6,f03c2e9,bd1b20be,f363f368) +,S(51e07e1f,e8dc56df,f6394d1d,7f2887a6,9e7959bc,ca10af77,cd54064e,6268929d,c09b86d6,6837e473,574bdf95,f0b99851,b97a821f,6dc622d0,d9c6cfbf,18db5ceb) +,S(c5c19c69,9a9b6908,4625d3b9,5c6598cc,d1bba7a0,6d4e2f91,88f1b77b,4aab720c,af066357,107d856a,51c699a0,259774b3,352f8c12,988201c3,c71bfe3,c5d8280c) +,S(7b51ad32,ec4a6df5,f9c952e1,fcabd8dc,7661ec53,2631331e,5205d231,533f8d77,e1346672,ebbb97d8,569a12ae,fea65246,e1902f0a,9cd91894,a4b8aaad,5a02ad35) +,S(be3059dc,3789e16f,5ca8f6e2,c469f834,bcd3fa73,5d84377f,907cadf9,e7eb895a,5a6fa277,ee5d317e,81819fb1,11f40778,ab437567,48eed726,238ab5c7,f4d6ef06) +,S(cf75a66e,810f3284,52e09fa3,15451289,e1cba33a,ff1013e,4702ff1b,92b6f587,a0658bc5,8c894702,ec5c366c,5a6b18fd,86269d5a,8117dee3,601dc40f,cc93f17b) +,S(6356c70,7d5228e5,253f09b7,7020681a,fa64dfd6,3cabd703,91d7f892,d9822737,3241ba88,cef88e8f,98d19fda,717904fc,737a9c77,45838ba3,97141964,946ac7b5) +,S(90d7f09f,7b8a1232,236b4459,b031b0ff,d5e8c903,36a35f04,94a89615,3baf8554,4a612ce4,b18b7ae0,f3c557e,c4ab51bd,7c32f26b,24d0ca7e,accc748b,3a2db676) +,S(170265f9,5a3f936f,57a39e1f,a748a3cc,902b1b20,4306c49e,f4485b15,555f80af,d2f813a4,b329da9c,68104a55,301eb7cd,3ff6dfe1,c4aab9d9,d2fb03c9,e7ae2bee) +,S(2d6316de,37598fe8,ed6e3e52,ac47d442,636a6553,64274692,5a468f08,54377eea,e064f40,7f0d3b32,74a61d82,d7b75006,6fab6447,e66f2d4b,20439303,cdb3a107) +,S(8c89678e,73f3085a,1a766e14,f566625a,cc29dda6,3eb7bc9,ed1195b8,5fa2092b,12b42d8e,91c9640,b8b2509a,157229bc,a66d28b8,157742fb,a12d7405,eec110f5) +,S(ddeb928,de6424c,f9ea76f0,abc208f1,16731596,29fdb2c5,c8e6ed28,38ab6b11,b1395663,9ac1f06d,74aef36b,61916872,7709eaff,d8b76905,ca404459,325839b6) +,S(485e8e44,35c46bd1,d0c2a4db,19b958fd,4a87511a,ad4aae65,eec4f5ba,6cbb38ee,e621d1d8,736d6df5,df2db5d2,36887c27,a93733b8,d3232dc0,95d0b2b6,d0be516a) +,S(bc527a44,2547aca1,91fd98fb,84ce7b3b,6210378c,46f7bd46,bfd375a8,1b61206f,ff7c1cfb,d3c21616,85d6f405,e6f19e8b,6785e6be,ce374189,4efc149b,b3031707) +,S(9911194a,7a75269d,2fda7214,21e4e2e,3666ad12,3e76004,b5ff9afe,9ea89ca8,b1f350ab,c87d942f,1aea75fe,6c144ea2,fc5cc040,5c38af56,9ee45413,17c7bd4) +,S(93226535,e27a96af,7953597,4db1d4d5,4a65d3e9,331fc3df,7f028fa3,288c3189,98007e66,60fc6673,5e8e864,afc62171,49168a86,27d35eea,2d02d90f,e6f15331) +,S(752d352b,2459fb97,d5a0c46c,3fef99ed,50ebfe74,ceb1c881,b2fa518f,3aa59e72,c6e99a8a,2544731e,d932a164,ca0def49,dbfe4f29,f8894133,ff5eed02,66c4fbcc) +,S(ab37b416,dd06a595,ae6fe33d,717c4ff1,fd1de2ad,6c58e2b3,660e872e,aac7aeb5,182f07fd,61ba43fd,e11ad355,d7027fef,714c9b9c,364c0b72,1838ef7c,f85d9470) +,S(d2fa3ff2,b1cd8909,52a0d380,d43233f4,1eef04da,aeac6ceb,46dd8e6e,572d170a,85f3c854,3eea0e64,b8a9eabf,18057700,6c3a6f70,a790cce6,24a3f6f9,5752c520) +,S(e256c5b7,99ae8dd7,1daf5a7f,3dd94f94,e040d98,291a2d6e,9b398889,addff0c,b4375e5c,82517974,b515ae28,54c83443,e8bf9391,cb975013,727e3bc5,1473b133) +,S(30056648,afaac00,c1d77bd7,e7b5235a,fea2bc8c,58b34a6b,83e630d2,3036db6c,16ca5c30,6882fd6e,f7d82f93,b25ad01c,eb3e9e69,b8280f0e,e3aef2e2,ec204600) +,S(8602fe69,d4b1f32b,e8422928,200c5b5,816f08a1,759faafb,29861e07,c5dccef7,59a5ca0,35490ebe,66409e2a,283f4c9d,f6e0a7c7,9dd1ec82,f31f7e4e,4f23ead0) +,S(53bb9f5,ed205516,36ab170,7afc75b5,6ab3a75a,3d360c15,3b0b74c2,d7d9d64c,77c6c1ec,c7a53dc3,8c6540d4,461757c8,b5f7b66,654fd754,fbfa8f5a,a5318cbf) +,S(badc41b2,86982d76,e5374b3,dcf023e,dbc1e187,70cd0b2e,2916d436,108a4328,b1694651,a69dfad,924fdf5d,526c25cd,e732078f,31128556,3d42ebb1,3329e2fb) +,S(15b43026,f5134b3f,1ad441c9,793b9e57,a318d455,fd6f10df,e4b0bb91,5d36600,43568550,60fb010a,6d5123e8,b446a1e7,cfddb6b4,6e4fb18f,245a4be8,f9975a1a) +,S(fcc64bd,c9df17,4d4e8e18,cad6116,a48780e2,a180f7c7,57f532da,9fdf37e7,ede37062,35eca482,b935410b,6d495f53,12b133cc,238eeb6d,e8e5f593,65601951) +,S(f394fa79,254fbdc2,7a1b31df,1f868c48,9b48b6d5,1afab542,2da5b1f5,6f3edd2,f56d3d7d,e7f8d9c5,fd45d6e2,cc2af300,fdce3293,9be5b975,9d81cead,e2000e7d) +,S(3c7c8c54,6b853a5f,97f92932,5558793a,e1debf3,3f680d5,6a79bdef,d4608d91,575771ed,f26feb38,a728354a,6c4023ce,4b019d65,3f7adfee,3c83cf58,9f2fe4a) +,S(51d61258,43b8d621,6c0880d,f04f34d,9acbb422,d8194a98,dcbf222d,cf27fc4e,2d0bbd0e,ae299afb,93980894,bfbdbdf8,6edf9509,ea408286,ef602cf0,ce3b33a2) +,S(14b17f35,ac7b5914,e08babb5,5aa37cb4,26d3bd34,f2c1e4f,45acb493,8ef51a65,a9090e25,cd8273c3,15d1ac6a,15eab027,7981f6bd,a85fb082,2b24cc88,2918fbc1) +,S(59ceb93d,d78ff6a5,f45c5fcc,7c1ecd72,43f2d8af,e4ba8a3f,fb03053a,586387dc,28f4d0e6,38ac1fc1,98aa3548,56f4f19b,479ff825,5d150f29,871630ae,f82f3777) +,S(273bc0a7,eb63a0df,eea8d7ac,b24a5200,a7086078,388db5bb,37a0a6f6,acf24656,a971405,a287160e,22909b67,357fb63d,10af5ece,f725b1ac,17c7fc73,759936f3) +,S(c9b5b690,3a45e529,3a298219,cca93e0,52a2719c,25cf2f50,c4ff7f04,5f346475,7db09fca,ff1aeae2,dad001ff,1fca6166,a607eaff,bdfc327b,9b63e2a8,e97f665d) +,S(90044bea,c8459e34,edf7c40d,2a101b45,66728d1,cf0055ee,c8ea07ab,e39307f0,19763d08,77d4a896,ca9ecbc0,56d405b,5a6ebcce,1ff6ac26,593be19f,63caf6cf) +,S(6e0898bf,bf6baaef,d085f41,da7e6b93,6b6c9a88,3728dc7,8ce7d71b,fd597b2e,4769146,91587abc,c2f21e05,4542280a,f7260a72,e822edca,1e63c089,3bea3dd9) +,S(e94563b6,e0156145,ca2ef19f,58de9727,7b806969,a249629a,4f024b99,8a023792,c8949547,a4d25901,f3980cf5,333f65f5,8e1797d8,b42ccb0b,dc550e6d,5909927f) +,S(3cd027e4,173c2799,54d06c3c,ec05c0d,161a3b73,348db0d2,8c03d097,8921ad64,f0d1a3e8,ebc3387a,ee88189e,c1fb3f6d,5e73e895,7b7372d9,32b00144,248271ba) +,S(4c96f51,2b4f0758,38335d47,db599db9,a2dfe1d1,6783960c,dedda119,693d5686,4e840262,66897288,9bd54c15,219ae871,e6426b67,afa949c5,e1226bbe,1204dfe1) +,S(8b03ca2e,458873,963ba6b,c9dcd14b,59fb1190,3f2330cb,22997bb4,19002fbd,2b29df15,c6be49d8,27981ffe,aae26930,7a461f84,8285f561,4f910508,eb865781) +,S(f4217bd2,32229dbf,39066a17,c2524838,38098362,f0891b69,275dede1,f8e64f0d,7581350a,957f480c,89246800,86c2803e,99ff5037,938e3e19,22e3f9a6,7098dd96) +,S(247274b3,d5095d63,132673ca,dbf0e418,898468d3,9a30c538,a46a2719,42846bf8,4265a1b7,7d1dbc68,956f2441,9c4d2b70,9e71f6e4,6e24e336,a978285c,22a84f11) +,S(19c25b9b,97f40ddb,23d62bd4,a298ce7d,befdf39d,327aca47,61815c0a,28d4af9a,a9b5d705,94cf4c7e,b7e947e2,101b18bd,fb9f2f20,fc3bf89d,f5a63d7f,61d3b3ce) +,S(fb69718c,baf0c5f8,e20ca98c,2fdb18f5,59df27e5,c2a064fd,ffb2785a,73bf27d6,b612c590,4e0b1c54,7beb4e07,82ad2716,84eb895a,862b59b5,cf6476b8,af52107) +,S(9fe6e793,ed1aed77,d8381352,84890e3c,f817ca60,37ee80df,6646a3ce,9c316a6b,17214a01,99370a88,41717ae5,41d35a4,96f8f041,e9b3fe88,4188f6f4,e30b0657) +,S(c7f7ab4a,394f17c8,47010e9d,f1764fae,6159b140,578f70c9,fe50703b,aaba62cc,9673f262,c875953b,90558dec,8ddd04a2,6d7d3ac1,672e3d10,c1a3c656,b0318c19) +,S(cc2e30bc,2d63d4d2,bd0f5bca,8faac99e,a6add123,82d014c1,d7bf8285,7ede2297,cb87a21c,f1efe789,fe72ca0a,b6acc5be,63e6973,2ca899e6,fb9e05e7,72d4d8ff) +,S(6fe7070d,a78205ea,1f12661b,4538d0fb,60b4bb4,9c1709c9,e53de22e,c3c25d6b,2f6b773d,492a82f7,f9609cbe,e1af3c9b,2940a12f,1e615c1a,801c02b2,19e6b8cb) +,S(1affe9da,ab5da7f7,9b331e9f,91eb7e3a,f4dad51,2317ca45,3ae13528,66013d8f,2706d2aa,d3139097,73a0febc,191c7a0a,df2ef168,c65e759d,7c034bac,49c8a92b) +,S(13566dd2,d0cdb199,20a1f9c,aa1ab581,c3ddf2ad,125c13cf,efe199d5,bc338231,b403ab04,67df46b,2efa5b8a,4cfa8bd,97399c87,12ffc55e,cae8de52,d4f6f28c) +,S(135fae69,9a969720,b1c0d899,790afa99,83074584,da3ee8dc,1e011336,dbc3636e,b4260b88,2dc79423,8cd0fbe6,5242147b,c96690da,c391e3cf,d2c53ecd,2ae9fc60) +,S(1b05d97,744364a0,5432de4a,7d840834,3ffe211f,a543bccf,71a4b210,3bb0489,d61c9d21,671b2481,a4ca0c36,7d4ea919,ae1b331f,a8aedb87,cc6b6c98,85616a9a) +,S(2877f026,83a5cb48,7014da9d,419c8b9c,920f0940,718e2d06,d7252de5,5b46a84d,849f9fb2,88d3fdee,de734aaa,3592ef01,483e02d3,62a5e0ca,2ead6c0b,42628038) +,S(8a7024ce,6348d2fd,84be71ab,b363bdb8,86ec6a2d,29d9cd83,1934270a,27370b78,8f520972,9e4e1325,363a68f4,ad53737b,688c63dd,1cec6cfc,bf9da51a,98b29c0) +,S(5ac77dfb,2309c061,8f68b320,bb6eb76e,4b0f0792,b8235fc1,ed768c57,44fabb1d,fab11baa,beafeab4,43a14a82,f8d70228,57752732,7b016b56,32b924c9,ccbb1db6) +,S(aee4edc,93413d53,45e0df68,99fc2193,be318a8b,f279f0e0,56c0ac42,a60759d2,b6a87499,1dc68ba8,503beb0b,8a6c09df,cb9efb6b,a44aed6a,3cd7befb,506119b9) +,S(b51d3e77,741d0d44,3a67b5d5,67b45aac,2008c25b,5196c71d,c9f910e7,b76dd2d1,431c7ea3,cf4f577f,950d22e2,74b7cfdf,2c2934af,ad0215f9,459a802d,ddee4c21) +,S(803a2ff,c59c2a94,65d8935d,93d47653,86e5beb9,c8e702a,12d7b565,98a09841,d5e02ccc,5d8ccf6e,29a7fb76,5a257dc9,c902c900,a4fe16d1,53e9187e,290efbeb) +,S(22c17725,44eef514,5636a398,23e874df,8c58bc6b,6935598a,440ae9aa,5b738075,a67f431c,688d4426,c519be32,9b1dd50e,2c64648,4d3612f,35d52089,c98dbcfd) +,S(ed67feaa,5aab50a9,ff71c434,855bafb0,5191f036,c691c8c5,563395,d2053b86,b2d13cb6,4ea821df,f8829ee1,57cb5fca,81dcce75,d091719c,73cc7785,c443f0a8) +,S(f8cc5ae2,3b670b9,3c27ab8c,7d8055c8,4654b427,f9e6b733,b083fecc,c7c5d375,7dc996,7bc3a2f2,f516aab3,682f8d6a,32b84173,ecc742d5,c8a15c5c,72eb261b) +,S(838891a1,fa46e300,a20fa3d0,cba3fe09,3326ffd7,bcdd7c73,b6e96da,5d591332,d46717e2,c5fa3d52,a268aa9e,a85922e4,547ea986,3a37b1ae,b77d75b0,d48a8fea) +,S(92caeb7f,400d043,6d36656c,8ffd5d45,6097cb51,cf512c00,1fe613e,8dcd5544,2096bc03,dfd088ca,25cb9aef,29b24b99,2b2aa00b,e3429cad,c0976a3f,162e47e2) +,S(2e6226d,574b687c,20dcd4a9,683697f8,afce56a3,1e11cdef,6f0ba6f0,dceb89b4,d9c4d7a7,a7aa5f8b,f30f0930,d6c3bbdd,b1963b1d,8cf24796,141bddb1,ba8ffcf7) +,S(33aab3f4,17d936de,b8c1f07a,9fd5024f,802fa5b3,a593a6b0,9fd42871,75f4ee7d,4c13dc95,7311dfaf,932eb4cc,68c82550,3b185530,13008dc6,878dd092,50edca9c) +,S(ed74a882,a947da53,fd62a242,b67dcd04,50896a43,e9882c84,ada77f47,691e5fc4,454a18f,a8fc6d8d,e673410b,213875ee,35190221,9f7cf88e,f363be08,571030d8) +,S(b5d3f084,56db930a,7d8b4728,2caaf807,be7bca65,bddf9738,67a56224,39723ebd,a89e0271,28d5872a,f4d6b4d7,c5a7efa3,b0339a32,89a12918,2077c106,b61e1a4a) +,S(5e40e90c,1a01e008,d5fde186,283919ef,eb859921,c3ec07ca,e34eedc2,b0f07967,e4be6ef4,26eb3c94,70ee3084,f431c68d,82b2df48,5286082,82cc1b2,afe77900) +,S(2f4b14a2,674a743a,4aefd302,7fb214f1,a7678336,3c9e7c8f,8ebee72d,c5f29830,11b13461,b6578710,677bc733,3d28e773,c78dec4b,27ca1aac,a17121b0,de9868e6) +,S(71909162,35890bbe,6a8f7a99,5b1cc3c,a68b3ff9,7551d09,59a97835,5b7167c7,f9aa3992,124fa99f,167f1351,865a1456,8ed9eb92,c7cb2050,5082d228,4b1532de) +,S(8df50d7d,d3cf99c7,b0269ae5,e70546dd,bed3f05e,260bd834,575d56e,e65f7f0,835405bf,3c84c4ba,5e253fef,f306bd1c,c1240ef,8c03da98,d7c092db,3a2606ca) +,S(5e0f6a7c,e9bc1e0b,852841ad,52045b02,b4fd545b,f2106c82,17a76bcb,441173ee,ad70f065,4d75c88f,e6654d56,fe65c57b,857d91e8,ad6abff,148f3577,7afa2aa7) +,S(27880a25,21a78fca,cddd0b78,5a3da1f4,2e832641,8f804a2a,42fe3c0e,f69b43b7,ac9f930,12402aad,c55c12bd,e450700,b0208d85,a6784586,d04f1c93,6df8624a) +,S(6578c4a0,dc25e068,97482b12,3f38cef3,39cfd6b2,ec06c89f,6da11449,de5e43a5,8a249d9a,41e6c1a5,a776ddfd,ea93ba78,15f2e908,b8b854c2,3a7e3ff2,cb99bf70) +,S(c66e890a,71beeba3,301bbbef,2bcf4cdd,def8e634,dcf476f4,6907a280,df3dd33e,f3510cb8,9c46f493,c4a70976,34a9c502,11532929,ddc883ab,d43bd360,1b028dff) +,S(393f0dcd,24b47380,81197794,58bf5e48,b2f5479c,8efd8925,a1f78bef,6bd16665,9898d880,e24f840f,f1b4662d,3d444c29,6527cfe8,2b6f1b4f,f0e5928c,bf09de74) +,S(337fc469,43942ce4,f1601877,874366fc,a8726f4a,65a9bb26,c6c2c013,856a3adb,95df242b,2d4446de,b2b792a4,d36ceb2c,add17365,380d78c6,3b23b101,1b3be914) +,S(b7edfbe5,118cfeb1,4c1aa23b,48154dbf,5e9d1057,a2758516,7fb8e030,a457874,bc1e5723,dabdfd76,c98f408d,1d8c13e5,7dee979e,83b3d610,981b9718,f1e61eee) +,S(4dffac46,6a507b9c,2e2ee5b6,ca81d8e4,d4e8aae6,3d73395b,dd29b024,51436e5b,af227fa8,ad0bfc48,eb469596,b9b2759b,f41eb169,1fb8f896,1451489,ebe0d5d7) +,S(553ab99,3448879,b42c72e2,97d597a6,24416a45,f5b35720,c93a303b,c6dd0e88,5ba2d3fb,222a03dd,c5302b25,ffce74cd,58de90a1,c3e41928,19717c28,52ad1b39) +,S(b351ad4e,4c7df853,8f6f71d4,e95554ca,3a07932e,7a812309,b0b0c807,f98cea2a,5ba5141d,b3d4ff44,7efe06c9,c624d447,1aa3c3f3,47af74af,49929de8,d8558c70) +,S(844b9bc0,ae73df50,e5b80fe2,fb24a35c,dbc91c61,2753c2e8,e3765e1e,47d44263,80eeb80c,414c3a08,a42d89b8,87883d48,84b38bd1,40f7bbee,e977ff5b,c4c57b90) +,S(f64b4ef6,8fc11491,38ed4ef8,ab2d6336,3d494b37,b56649d1,5d15777a,8cd315b9,c6f83010,5dcfc707,f435cfa0,b6bc32f3,8ce8afb6,28bf9139,dfc47279,cafa56a5) +,S(969ceb7a,441f8be1,f16c94bd,6065db17,942f88dd,e5506742,7cd30dee,cf9ba5c7,a08ae62c,6e6758f9,724baa45,d35f3e03,9f636265,d841b61a,f1b31d20,bc8d65f8) +,S(e465041b,78c33311,d4397b30,9a8ba4de,6b312d10,ec2ca906,583162ca,1c599102,3f21d5d4,416f1954,7af1ba97,6687dea3,520ac304,43c180ad,3892d46b,86618f55) +,S(87b2e548,b019224f,b1021a06,522073dd,46892847,308fffe9,910ffc28,5b702bd0,6e641d35,9e7ff12b,20123b72,f0e5ef16,338c3418,38c2f4ea,6dab94c,7c3f6940) +,S(f832d7b3,590a59d7,ec2c8a63,7ca0347a,893fe461,4eaba097,8707c353,8296ee14,3fb3e845,4624fe35,326062b4,a6f30c85,f0e7101b,a3532455,7687812e,412233e) +,S(52aff21f,fe1819f3,7f8b5974,ab004393,6e99d8cd,8342b7bb,ad46d333,5e4d6651,66d79c3c,c7d08828,d8646e4a,6a44853b,4a49df0e,85c95e85,d9c995c2,d09b427c) +,S(aae62778,8069bcdb,fc91bdb,946cedab,63896817,575a471b,315a47cc,d567c678,f254c548,832d95f8,4f20215e,ca4805fe,356e806d,9b3b7338,7dd36e85,214b70bf) +,S(fc15d494,b6580e0d,e1c769c3,95c5d047,202e8d07,ba94bd1a,f96064b8,d1a4bfbc,f9327fc8,75319184,c1876748,bdbbdd3c,bfee8baa,bf46844b,af465d4e,ec6be335) +,S(aacec857,fa4bc62c,82790a4a,496206f2,d79a31dd,e17d2db2,d99619d8,c3d880d9,6dd1e4a2,adc502ac,150293d9,42a1cbea,a576da49,f1de7d15,de70bd67,d95c5fb0) +,S(c7ba3155,bf34fb9a,2441832a,27396e1,99836557,9c9cb856,44c3ace2,9ade66bc,afccc814,243a1fa1,345fa46f,ee4b4190,96082bf0,7866fa8a,2a887d84,d24192f4) +,S(cf7a0525,3bee95d7,711d8f7b,7b301f5d,8036a487,a55e3860,900b25b1,c4599115,e8a4a9be,7b9cf99a,5dcb4db9,8249350b,7a71a12f,a9582620,eda5a35,1a8a0484) +,S(a4336248,6b999ad1,623c4c32,c79ebb3,4e8d6f3b,484f808b,9a088ffb,2885a11c,edf8eef9,74d3e5ae,2a991a28,6323597f,5a161f9,2eeb9256,207be548,f9b38d16) +,S(d3cdbd98,8cefc8ac,3a442587,51364a10,649243a8,d4a63927,f4fa3b10,b1a7dcc8,f10e26c8,11f4a219,da4f948c,51e8b81b,d8bb357a,182031cf,40ffb464,d5f7d7c4) +,S(fa038534,28dd093,26977fc,da344269,fe3c61fe,35567eef,909a2309,8e5ceaef,f31c5d30,9e234b3b,44fbb52b,8c973aa2,bd85afac,1f9f0798,788721a9,380d8606) +,S(718c2bc,26dba98f,24f34af5,18e18870,5510c0a7,4e228cd6,9d4e39d8,a00a577f,c41d0d81,8f093246,5675a326,d0615b0,294b8455,909af0c6,e557195e,11225152) +,S(378ade51,463d949,1ed22ab1,834cd7bd,6b99a123,52c65e18,70d5005b,e97e602f,76469796,d7758ba4,b3bed1eb,9f8389a2,2a421f5a,20f8df71,72821a8a,508e4c1) +,S(40bd7df9,1255680b,b50d3d08,fead6815,5f807759,87e9cf80,15e6359c,9f138b8b,ec0417d4,2eb1ab50,a469a853,edc65ca5,2fe00ee7,53b30b9c,56536e3b,36144e8a) +,S(f01b30bb,985dfb53,7bb4cd62,18cb0b00,b5a77215,4d84a802,8a4969,260d963f,3cf483df,d6b58eb8,46e8ba1b,f06c2e9,6784255a,2afbf68,613f39f1,44b82417) +,S(2392d86a,1bf9a636,38eaa5dd,76a7c6c9,eabd50bc,9f2ba568,183c0995,f7195900,806cd3da,ac23f93c,3b11cb5d,a3bc4482,ea49ed2b,444c6e64,dc557e46,3ac5c033) +,S(b0e7747e,c9496fb,aa7798db,e616fa42,5b0b7acb,7409265d,c989b8e9,20087133,32fa615e,d0286b64,b83cbfb1,e8c4b133,85527655,48071401,89f42d93,330491e1) +,S(8d1342f4,2f6dc3cb,9bb741c1,9daa08e2,25fb6352,ffe860e1,76a26fda,a0601624,82d35ed7,57cb6f31,81af31fc,36f53817,191fb9b,c9338a97,3757d0bf,50d79d77) +,S(ad09dcc1,d3ebbbd6,ecd7be45,d7eec5d,ef743851,2ce076e3,cfc4f8b9,449a2ccb,26bde63a,e1f7fbd8,46260a64,372d015a,fd3d5ae6,125dd801,523a94fc,8421d04f) +,S(128f5199,68435c1,a27591a3,2edff533,d12a725c,f0c7e121,260cbb74,925cc292,dd8945f7,42f1d013,92152dbd,1e4dd8e,53277da8,bab68acd,8c7c8d73,f5d7e190) +,S(118c1167,196e8eac,e519d83d,17ae1e30,36ff1fa0,cbd1cc58,41cc3763,d1d8a931,eea348d,54f47b73,d5d8c2b4,7eb7604b,53beb345,c82ceca3,4f8639e1,45b2e3b2) +,S(81ee4bba,6a84edb1,83e1f2b7,5103e453,2ba9613a,b612e0f1,27009ee7,7be3bfb,e58208,d152059b,73b42039,e0a7a489,df067fab,1d1c2c04,9eed00cf,893f4847) +,S(494a821f,6f4b2d75,7e5be34c,fb9949ba,b9271599,3e060005,dd807c83,adf04f2f,8ab15e9f,c37d368,3586a1ed,ef9ddc59,8dae7206,499cf53c,31a8cc4b,d7ba15e0) +,S(3749271a,da87c292,724a3ad7,2861a7df,9757e31,3c3156a1,72cd3735,608c865a,aeffa1c1,aaab4f09,3998b4ef,e046aaf0,f404d590,d6cd762f,1aea5745,1f8aa3f5) +,S(103c8721,321ddfbb,cc3ef6af,1ea8fab1,3de6aca0,294dbc79,3a1e4216,563dc1f5,fe9cca2d,b459596c,462fb268,a8115880,16c2894e,e8839caa,362e4813,e8e827cf) +,S(ddbfc655,6aff403b,10a643fb,f62a60ed,656baa39,b10febe6,92140bf6,7b78f2f9,1cd4169e,cc8ac589,de57b5a6,e02e03df,f3cc7bb3,45993d5c,4ea57e6,852a8417) +,S(d025f583,3e51a9c6,a1c785c5,1c579528,5af0c297,c0fdb82a,f555fd59,88dbb28,5170614c,110f31ce,d88424fc,7d569f4e,e93d5017,a8c676af,c7261ed3,340d22ef) +,S(3f349cbd,8ebac9e,c570b0ca,29fe8ce8,dbd98eba,103f131d,daaf193,4fe78516,ec9641f3,175ed56b,d0c8f26d,188f9fa4,b38d069f,cef8f4cf,71acf66f,1ef7dbc9) +,S(7624599c,61e71532,a177e838,ba92d789,5160e43f,ad798fe2,9170e6d9,bbcc11ce,409e8cbf,6aea70b8,21533902,150148a0,7e45dd61,c9c8d24a,b8cc3da3,f03c49a3) +,S(8a1e1b47,3c699dea,aa418ba2,85cf7467,51af1cb0,8bf78228,932dc6ed,845403f4,1bd300a2,7a9a8da,6ed2bce3,73b9d39e,661d02bd,b4605740,20934bc6,abf3c483) +,S(eeb91c38,d9b834bb,5e3945b0,9655b988,96efff11,1e3dde8c,add6ef2c,7ea51b09,899d841,24f83b43,e2ea82ad,3a6411dc,cf36fa86,17bdab35,d83829d1,456c56be) +,S(46360f69,8c023375,6f050969,60b3defc,2a1897dd,44e0e159,d185ac04,3315ef47,ec02a6d3,828246f0,684d2059,23ba73ee,10cc88c9,575fc005,6271fb8c,67e0a4a0) +,S(16e5cccc,b410c20,e8de1e76,e5b71649,64cabc26,f629f8be,36eff4da,66f875ad,a80de48e,e079d9c,bac312e0,70f10d6f,fb875c90,7dd3ff57,c9bf8b90,57c0fe14) +,S(c315230,c8ee5bd8,429efc06,bd089f49,5f4c5a1e,2fb188bd,81e41bfb,85acc82f,71430e8e,cee9c6f5,eb91eb14,20e07b5d,736217e5,4bc25cac,9767a749,a477599b) +,S(7731eb8c,1684092a,d9d2ec69,b50339d1,19436082,c9116366,8ce2bda7,ee80c0c9,e6636efc,22a4c339,f8100dea,a227a709,42d18222,8cc58d13,ae4d613c,a879de8d) +,S(2c1c200,4a5f04c0,b83d143f,ede81755,67d4d54e,b2dc4ffb,de00b83d,9802f68b,b3e2e434,30d409cd,26490c1c,818b24ed,b10e835b,d6292422,45c529f7,6e299159) +,S(2d984bc6,a2031a3e,1a57d0ae,d13d798d,fab45382,d29e4a7e,8e029fdf,2a9d95c2,b169c34f,9932f02,8320ed87,4a74da8b,5cba81bd,f20a9454,feb315fe,a0926720) +,S(f61abdda,f7673f75,74e966f1,c77096c7,7f6e8659,746e45e7,2c9fbf3d,5e0db5f6,1717dd6f,86edd17a,b242212c,91878ef8,9ff1b865,b32b4e24,cfdab7de,de90937f) +,S(a68f5871,bfbce14a,1097eced,68a9e906,c94599cf,b6dd4176,ef946fa7,e5552c3b,cbc07a08,86faa82e,d231eb0,739a24e3,62a717ed,30b0512b,96ac8dd9,56ab05f2) +,S(52035076,1af3e786,60906105,36a2ced0,6f8209d,a0eb2757,cba705a3,467ccbe2,7a01b944,5f63cf43,cba95191,262b1b53,ae0af9b,4b172b78,3970f84f,f8ace09c) +,S(bc8f1537,9d4b9862,a437065b,10f6c28c,8c3323f4,51f2847c,63251000,c9f144d6,894826ed,61d85e90,58c00e74,cc731dd5,d62684b1,ca996c07,ab176df0,e4b951f7) +,S(536b0cb5,81dbf6,ab3b364,64a397d7,2a513bd8,a7bb8237,70a725d2,2eb12a98,85bc95fe,6e160f2f,9a31b7e2,74c09023,90cb2f4a,22f15ac3,3d0ee72a,b666f5bb) +,S(267840ea,e2f49fe8,9889bac7,40eb797e,ee42f922,c1821a66,163a580a,a0df90d0,2c7fe7f3,4e06f09d,a1a2b1ba,79906a0b,18c3d51b,d9b6011f,688c69e9,1504a00) +,S(d8fd79cf,6beed8c,fa57bedc,ca06e367,e0667e9d,a057222b,81fba682,979808ec,39cab613,9cef186a,248562d4,fa581384,d6c81de5,a0f7fc49,140d0822,f6126034) +,S(601407de,9ecff4d0,836228ae,eeaa612f,2b659706,576e2eca,74bc32a1,d3d14b7b,6cfde694,2f0e4495,1e25ff02,2f2501e6,7101828f,8088c7bc,a8ef2b25,88036ec3) +,S(f518c5c,bc0e8541,48c40253,d500a2d,1ea1d25f,d31dc777,d6365050,d3b26804,8dcc6378,2b1ce6fb,9f15c8fb,70c5fd0e,53e4d80a,cf38261f,49a558e1,de637b6b) +,S(16a9bcff,334e35e2,80258378,b2e25d9a,56ce58c3,b3426bd,da82978f,370ee6f6,c7b6656e,baa3864e,bfbc5294,fe9836a9,9fdc095d,ceac6a32,642e6911,a6f3e933) +,S(9d940fce,5ecdc659,30c945db,7151b823,a9259d0a,2a3991c9,f71e8b00,bbe35d4f,32f533d,d96f2e36,2109a96,48ef55b2,e5887387,80de97ad,c7974227,b23fe647) +,S(19e973f7,69c2d02a,8bed34dd,b7591828,5036e724,22227a81,850f3d31,3128f586,f2f5fab4,fe79c177,752ee60b,cd85e625,e459b50e,de702010,a6fbcbd1,5b31aa6f) +,S(ff07bc26,473271d6,4371a4d2,9b59f858,b1b01e40,472bb4e0,1769ed2b,66bf2097,3eba7660,492ae09a,abd7bb8,c5d80e33,44539ab7,276edfd5,b599b02f,27c60b8a) +,S(175f786c,93d89acb,8959d846,934c21df,5dc4f6ce,a9c1e150,e7da469f,d27e6605,343366e5,7f5b9f7a,407cd566,7ef1f0f2,464a2938,61fd5f2c,b0363a5b,dc9c2f9a) +,S(a9027f8e,b662a7e0,d70aa1ac,d3e0b9ba,d4e0bd8e,8bf8c883,40b0a7f5,cbafa761,2f9dfc2c,57bfd835,271d63ac,e3cecdfe,f6e19e0a,fc19ac0f,71ef9ec2,7fac30e3) +,S(677daf40,728a6c89,6804ed3,1df283e,19b41c2d,36a3a98f,d4b93fa6,6699983,1affbe57,3a561872,37dafd1b,bdcaa594,e499b298,6af58591,c6a2ea3a,2016c039) +,S(1105aff4,d4761b77,68db74ca,d9fc7aa0,14c5417e,de1fe641,ed1dcdb1,9b5a3690,bfabb1aa,76906ada,4a1ea463,f4caff44,a41afa71,b82e2457,d2756ddd,14946ff0) +,S(3221d033,16be670b,e05ecc94,8b537ca7,9318eb65,f93ab3e7,32e7f36c,bd06249e,92f7b5c9,85ba3fd8,7b14a093,74d4ef94,130d3642,517369e8,f9de5fa1,c8ccb803) +,S(ac10037c,ad83fcbe,6aa7acf2,3043ed,831dcdb5,66921f16,246488de,6e012fc8,d530eaa8,ebe1d47c,8e57892d,9301c4a4,29b223b2,7344e433,f2bf77c4,d9a20205) +,S(b3ea670b,f5001657,913d5d49,ee1005ea,65fdd33c,4ad81987,efa0331d,b29a3e53,6d758db6,df4275e3,fc148e91,6536505f,6393daef,c54c3b0,b708e0d0,8de3f1bc) +,S(42762d8,bf60f678,924b7cf5,4e8c513b,fa1223cf,98e124d9,18d88cd9,a54c8d88,96be42a1,f0dadc84,64a3522d,e13f10ad,3272505,f7d4fc54,e6dc1a33,ef6b2eed) +,S(7b9e0117,167c51ed,c3f7d2b9,edb61bde,aa90efd,88349510,c4b1cf1a,43a9ae6e,c43e0d1d,8a673cb,1f0d9d1a,e3a4c985,bd47a068,2528ac36,67976881,1ead7a4) +,S(1e807fdf,c69acac4,ba5be7fc,9c617005,d34ff896,dae25e6c,428abb96,3255239e,7db7d6e8,8bf3b869,fe4f7c11,65d85faf,55bd677f,5670ebdd,89d2f8b9,f56d972c) +,S(9aadd434,75384190,a6289f2,32cc6491,fb7a1d86,b04ae9ea,94dfd2c8,449c3961,fc491907,3ffe94d1,3b945382,eb9c482e,9da5a764,d9aa1d1c,c3d973aa,5edcd3f3) +,S(5012b7eb,481fd85,db13c3fe,2bdd06a,720eb4c9,805193d2,b99b4bf7,39802f26,db8555d7,e2cc1858,21920564,3c288352,22086161,1a611dcb,d1e98518,7c46cd4e) +,S(78f9e5ba,91071270,5160654e,2393cd73,85e4681f,8efb4a45,cdce5ef3,d73cc7b1,24c4512f,911101c9,d3a4fe24,b7468585,36cb8137,e13578e,95cc016b,96d86e20) +,S(91a7d927,4de2c0fe,84a10579,891ea8cd,f87fcf5b,a0939411,4612efd4,6bb9f826,d5a5e511,b85436b,89e46211,ec69dfa8,d0ee87eb,7c0daa31,24d48462,10e6c40) +,S(3940b4e9,4626f86d,4592b96a,4f27f874,c37c6cbf,5940de,37dafc1f,35350b69,ecc6176c,43df3f71,cbf0160b,697afeec,1a9a0d69,5ebdb7bc,34b0efe9,2cc68b39) +,S(76e7ab54,8c63ee6a,30c736ff,11762061,283af0e5,5a7dbbd2,23fe467b,85c95d8b,f266c922,fc5e61f1,65bf521c,33235e05,113140db,6a481b0e,e4f9976d,2696fdce) +,S(ecdc2e5d,b8d5028f,f93de09,c9f5a6b3,c439b14b,3c322c53,94622a13,80f04067,e70df9f2,bf6b0a35,9029f937,5e74aa93,4014e78d,e68e29b0,9d96da05,5ff78112) +,S(ccfe93db,de087d5b,9194b286,99243dc0,91d4dd5d,7189a5e0,d5621311,9dee9a94,2b0a0a20,cfef0c73,addd2dc6,d9b4ba7e,9e44f2c,26d9f376,8ef90241,b2d907da) +,S(4e82a200,e64f5b3b,3e473e50,e437c224,e21bf875,ec8ac364,7e599ba7,84f02574,ff696d9d,2d9cc0be,217394da,85201a1d,208e4309,9b9372a8,19f6d069,88839c0a) +,S(a292e105,6f3f0a1e,e816a49f,51ef4760,91324316,2e3c734e,802550a2,c942c17f,479a2e95,7a05a686,1c08df3b,221ed2c6,5d192181,189269fe,9ef42a8,e71fd6ef) +,S(47279a82,8311aa4c,b6138c9b,ccb2fc6c,c4b9d27e,2e334389,1773fc1,ee09f461,2480a805,496e8bd3,e02b36cf,8081bc5a,254f821e,40c0ef48,291ecbb1,6699a10b) +,S(b903b4f8,2126fe06,44976643,5f0982f4,394db57f,b473401,9536740,595562fc,e8c97572,bfae91fd,61cfee63,3b24bece,e587291,f65a6aff,b71c6a3b,615e1361) +,S(16b9e3eb,eadf469d,368ab368,431afb79,214bc728,5df165e6,c3bf98a4,701b05a5,26e74ff0,64cf5de9,ec3d084f,8d75337d,c04918eb,f783c65e,b50b948,d48eb003) +,S(4927fd2b,c17b92c1,3b3ca52e,759324ca,353e8505,ba81ac24,9003091d,1cebbfa9,95a6c16d,c4c52f20,2883ab4c,a9c050c2,b2849b71,e19e0df0,8ff495cd,f62d73ac) +,S(70c503d,93e47,10262c8b,b1630409,979b673a,79ad08b0,8d855365,f51ffcaa,2ad207aa,5fe05144,95baf3f0,b0807efb,d10265f0,5de63d6b,563e4ac5,e70b89ff) +,S(cf598642,32972f7a,a6cf12ce,dc5aa95d,4bd0f96e,38ed546b,9ba9040a,e25a9e6e,67f2f83a,f5f09b52,caed83e5,1b9d6de0,58a6e9b8,96d1a6ed,d7ab4d40,30332027) +,S(617b9e5a,8d0b8c44,b186aa60,281cee51,dc224e2c,9e1c4f07,c342a180,78b271f0,b64d8d5f,bc2907bf,90b983cb,a6126586,dbb7e7f3,d95993e2,2bc1b8f8,9472d200) +,S(d52e0c90,c69cd94e,3c849ea7,dbba79d8,6aed2a3e,3ca3f106,d2baa2a3,59c50534,36c8390c,fe400769,fd2b2fe1,b6af62d0,7fbd667c,fcd9a132,b6b4f974,a7e454f7) +,S(ea474a01,36d16bc2,fae6f568,9ea3c035,aa6580e6,b238f42f,e2ab19be,81330a46,d09379ce,aa89765e,1164f438,4b0f0ef0,c1e8be86,427c7455,af98e4b5,c9ee8145) +,S(4e5dd22c,b6a4b205,97f71375,cc49ee10,ba6b82cf,b06cf065,a25d6f5d,bef51d70,d4ff2ed0,55279f96,344dc16e,10e3410,40378ff8,b8d912c3,a17cbfb0,70588cf0) +,S(774587f7,f3038136,131fa9eb,f1eb3407,9e473a8b,b9e5acb7,317ff5c9,17447878,9d3779a1,2b067b00,d2a2a3e9,46f8078b,e6279024,d94c83c6,28c0cd48,145f510e) +,S(ab807569,d1a3630c,e5447b36,c205e601,a6a23069,4d2c0786,19d9b97c,e0ba6611,2b9eef15,54f8ee6,e11af6b,6a1d045e,d47b8821,ec84c6da,366afe10,2730e9ea) +,S(91602928,ed3cea8f,4faa254c,28962b68,c4437602,3076a5c1,6bad95ff,3e328049,764faf56,2d8de3c1,89b7fef7,62012be8,112db4,a3201692,95c7e76d,fcbd3be9) +,S(6c1ecc2a,258a44b1,ca1d964b,c86c5600,49fdfd98,b362c35e,3c830647,cf1266d4,1f9d3edf,5e0e8550,e4534c33,5b07d731,19c49c4e,29397f6a,938fc1bc,ebf8fcef) +,S(e176821a,4006b429,999de3a4,ada09166,f6e5deaa,f09fa613,60bd3733,db8f7084,7d07d1a5,390325d0,27b05e18,d90e7659,f5ef4c8c,c7c6dd00,c7a5427,4ec91842) +,S(2ae0b70e,53536893,8a7faee5,da5d8dbe,e5af4873,32caf51d,7bade79f,eea50df2,e70be2e8,c8110c31,c3eb5e36,31dc5a5e,bebeb184,e6b9f081,bb7236dd,cadf903a) +,S(1c686fcb,d7a751b2,d420614b,56d37c8f,81c9a600,335fa911,835dad8a,7c663e24,4fe2eeae,7ea1b639,b893329a,a65bbfcd,b9fd8f07,28614bd8,6a5b0712,76aa576) +,S(b369d7e5,c31c9a56,f480b44b,3354be,84145c3,97dbed68,d87a4c3c,be31dc5c,50800690,17d31473,59bab021,c876d152,c17ea8e8,b5c95762,c749a2d,29adf3cb) +,S(522d3ac3,42a0ff3a,9a8eb5ba,54ed4dad,fbcdb48f,53bc6e1f,2c0c12a5,61cb1e9d,32ed883e,1e1f562a,50063d79,45075ad9,9ab55ba6,fdff0d58,9d2b4a4d,10df82fa) +,S(7d001803,7b722a7a,17d74696,fed9bbb5,f3d5f6f,d8a623b6,9c952a2e,f2be939e,81ee30e6,deb893d6,274c4b46,8533d845,38073ed8,68b101e9,515ebd84,70e368de) +,S(c76b074b,b228dc24,1dc9b704,75fcc52d,a3f3bf0a,5e954910,ca4e6f16,bd298983,4fcc807b,4c1e37cb,6a6c42da,b939a7bb,6f1d5ec2,87320d74,408622fa,ece22266) +,S(8497f267,99c7f525,83c620f6,e284a9a0,35130556,9d7caa1a,f118de41,c51b05e4,3b861f56,16ce6234,c6847273,16bfa629,7cac9d5,ff562f66,24b26146,413960d1) +,S(ddb10ff0,a217ab76,241a587a,8cd46cdf,ce6ff5ae,e39d2d85,7f47eeb7,6d2bd68e,a4110196,fd0813ea,19846dc7,12537cb6,8faf9333,19e7e49b,553e523,f07b004f) +,S(47eb53da,455cbbb9,a8330e12,e0210d80,cc565661,348fec72,529390e2,a75b812e,88e4a8f,91ada187,5734dcf,42b85e2b,a3f5fc53,1f1c1df1,300c3d5f,e811fb70) +,S(eb0a8903,42fb2710,a4c7811e,78384918,dedea7a2,9bb7da46,e49211bd,95da1426,8d69a88b,d85e2edc,d8264cb6,c44d8218,1ce8946a,818c9d4a,6f757bf8,5817ac56) +,S(d400c8ef,655d3879,579ba4c,488c3e55,af5af95c,1701bd15,482b2549,9334906d,e7bafda2,5a9f5934,6bcec6e2,a9408f18,e81b76f9,7a9d721f,496c27f6,42725e5c) +,S(bae81c3d,1772e104,66625f8b,ef08d4a4,5f07892c,72bcee05,fb7e382,2a6261fc,4ce5f14f,74f28b03,34a6cc64,452b9049,8460493f,3b64d9be,2ecf98ef,c0270377) +,S(7f575b9b,46bd0f74,555a363c,d80122c4,232e8c53,a6624d8,e13b5c06,74986961,edc0ffd5,952fd4d3,c752271b,7cdfaf3b,4cefecd8,66d722f0,3da1e97b,49aaa080) +,S(a86871d9,1292f7fa,7249ee8,e77270fe,e7bddafd,3255b4a1,16851ae,411293f3,c21ee1b0,bd897d82,566cf438,b66439dd,3dfab0ec,3c7a4038,ccb86039,3b0b0187) +,S(c320cfdf,9cbc6579,8c8b33c4,d97d690b,64ae90c9,a5070646,8c8791e9,1ee4a18a,8f1a295b,2a3c8c5c,3b5bd8ce,e3380a04,819a8658,7be87d03,73a0194c,fafac74b) +,S(169a1b4,f2eacec2,be263ced,2e0576b4,ae77b863,525b2a9f,f8fc05d2,c07a8fc4,7703f867,d997a2ca,bb697f87,b97ea986,78777183,aea81417,1dd0946,309e77c) +,S(218de686,ed51588b,1307d8b6,54f7f6fc,e673cb37,553d23b7,b8c23367,d6b7ea5f,98325ea9,150a100a,f5d2af49,2fa25b23,40ee9606,1553c3d7,edd4d870,5288b8cf) +,S(c7c2e438,d12ed0ac,6363564,8bf2899c,d1b39b1b,200ffeda,4ef9cae0,5d8381e5,93a36085,fd09ff08,b83d50a8,3b140edd,a63e2442,e4bf4d1c,7ae44963,c1646f41) +,S(12e834e5,605d6e35,8cbe550b,8fe917dc,59194c58,66b265cc,50b00e3c,38fe058,6a44ecf2,17f46865,2e0991b7,df3b3565,444e7e29,3a2d6378,61a8f3c1,5ec1517e) +,S(30f33c39,af77735c,749fd328,e228ed67,bd625fbe,79dc3b06,ab31c173,777308fe,29a00f66,1c998f1d,bd62935e,44794420,7ffd7b1c,24f63806,9206e1c6,5c3d9604) +,S(c5bd81b6,b057e687,19c47964,d55ab996,6c7ea99b,25c1c2cb,50d6fbd9,af492358,5a6b1332,8562599e,e87c475a,1e7da886,c460ec67,ad81372a,7ed39498,41225e5e) +,S(1fd0e769,9d931a80,dbcfaf1,46b5cebe,b9547f8b,b7fa75fd,b2bac9ae,ac0908ab,11770838,88607506,bad87ba6,38c9ae26,d79a9dc6,6746816a,b9f21d64,fea96838) +,S(ac14a06a,4679e9af,b2ea3aea,15f2749,bc9610a3,b576a506,f96fa41a,76df97de,5aafae08,5b8a0a7d,48ebb339,f4dec906,21bf5162,dcb85100,eb7524e3,a65a4921) +,S(ad583074,13a4eba9,ceecba6b,c568bfbb,30566031,c06e8e97,5c5d992b,9ed2bd33,c2bda9bf,d5c87e0f,a663a40,34162dcb,29b61800,c1dcf02a,c11fe615,25af1772) +,S(5a8bd45d,6fd468dd,41ecafd5,aa072227,6d0176be,81b92061,b4277b73,32acfaab,878a8d5f,7903d74f,6abe28f8,d94d4767,3698a7e,6acbc32d,9e92f9d6,bf31c2d5) +,S(6690c9c1,d9666be4,56d3540a,6a2ed706,372256f0,43265478,7b54e56d,f28df74a,7ad591,23772578,999c90c1,24704c13,a7193b62,64240aef,63d12d88,340762a4) +,S(3c051303,c113779a,6137f46d,38d1175d,8778e460,8b1e0abb,f7bc4539,80b64a2f,9d4d04a0,ad1c772b,4a523c13,cc48990,c733eb87,993cdbaf,61dbf75c,4f6a96c2) +,S(1fdff503,66319168,f5dc381e,8085ac92,223b3484,a8b362c2,26d1f00c,976f9f04,5cb328e8,56aaeb05,62017bf8,65da44b2,94ad7404,df11e117,8426b79c,25a49fa6) +,S(ae83da7,52ec2098,a4a593ac,f99dd58f,cd48da14,361feaae,6cd992d3,96b4fd8e,6dc92b41,f1e1474b,a259e96b,ec4f2b36,108745b9,a500ad9a,edd9c828,4c3d129) +,S(c0f86e7a,6c0fee54,a2f73d2b,6b1522e9,fee994cb,d5089886,d98a4748,161811d7,4aea0b92,2441c184,c347243e,5ad5a064,ba00768d,52d7153,a5e0838f,f497d551) +,S(8e5b23f8,85d683a6,a6a657ed,d2d2f403,1320d4c0,83340126,d2958dc2,4c5f5ba2,25c6db80,477f37e0,ed6c6e3c,c96b1c7c,f9a7ca16,8e940e8a,b2946c7,3b02e61f) +,S(6672b4db,bb16c672,2592c239,7d9ea25e,f081d48d,aeb42c89,ae6c42bb,af09b3c5,a3778252,e239ae3a,f64e3b91,7f646181,4f71753d,b4bc958c,b5bcd3ba,4b5b1a4e) +,S(e0af1a1,b894fe1c,1f7de814,1a393a3f,b12b31e3,fcbd8f2a,356e61f4,402d76d0,37913973,b4de9a2d,23f4f795,709fe825,8eee8aee,afec5996,83d924e7,21fb9b0e) +,S(94355dd3,c3d73a1,cabdbe7a,295cb015,335a5a79,dd301718,10c245b3,d0c840ff,31e96abe,22a16033,56681d3e,e5e8330,628d8090,bfdcb925,79074cb6,82845475) +,S(fc340c8d,1e3e2849,1470dfcd,1c2fb445,e807e1a3,9c525ce8,141b292c,596d2e36,738e7213,7580eb3,615b7eed,9b069cd2,b644447,24696a,7cd22257,7a931464) +,S(c0c4e03,61d923fc,4201872a,1ff525c6,1697412a,7bea7a92,596e9204,f1af90c3,25c4c2c6,d6593ef7,ff5f04fa,a5b0b2ca,736ab33f,5c36dc63,433821b5,382fc4b2) +,S(81afd4a8,d666b97f,dcdf0d36,f2dfdf7,bf7c3322,69728b75,26dcb3aa,df51365c,b7fe7653,2c8d48fb,8c3d0382,68d57839,edf80cb5,732ae303,5c1b51c7,cb8d3efc) +,S(140b32fa,62130c2f,1d49e39d,15f9c64,f5cf54af,3a0c65b2,298e91e3,21b9477d,bac2aca4,c96d4363,12107b2d,8996875e,6772eaea,a5070920,39c1171b,9113b516) +,S(17418ab7,46f1eaa,b98725ab,68bca72b,9cc645d9,cbe0835e,4bf91a7b,3939b98,dc964031,b1292c03,117a4ce8,b3341e23,da54a539,fdd31126,41706257,bb9382b6) +,S(8f0222bb,6cbf7491,12b95780,b50077d7,be2a27ec,5bb6dab4,923cf36d,3a12618d,8df2a149,abcd276,31265890,471094cc,fe6bd8ed,b75c2364,6f7dd54e,30c4c6fb) +,S(e3965324,1c543ba1,2d0ca0ad,88c26ace,b265f42a,41d2b7d4,f252ecf0,a48275d0,44467da5,18786654,5722fa15,36c187a6,f67f2e8f,5a424336,b0ce8bbc,a53f9cca) +,S(6a4b614c,41c4a6d4,ba4f8c53,26d08bc4,ecbc72cd,d2415c3,b7caf285,acb07c1d,76dd92d6,3f85e1dd,685faa18,283f8667,2425de4c,95a7985a,cf5f74c2,7b29b576) +,S(afdd252f,82037cb1,928d896,74f3ff64,57b94412,b563a4e0,1a32cf2d,1afde412,d57f319,300a6f93,1155b0b8,3dd83a5e,d2b4a0e0,5d58786a,8024627b,73360609) +,S(65adaf88,4297a087,6ec0d433,ea82bd5b,9e3590c4,921fc2ef,d1fa0b12,cc74808,30e4ac9,77b97c4d,b7516c02,df65de7c,d9e8ae08,6146716c,3da4b26b,eca17033) +,S(eba0dd63,c667395a,9e9eda33,93f5d101,8462b957,1aae6a09,cb723e2d,a45704e7,8314c569,49b7c144,197647da,baf857ca,a164e385,62c1cf46,bb30e7a7,a8dcb680) +,S(d3341d4f,1f967f0f,10932a5,351c6c22,c748af09,1d547cc,2766e6f3,1a9f570c,9694fb83,74177e3d,80775206,f58b2e12,32b87c9a,21f060ec,19152435,45502951) +,S(1596b717,8dceadc1,b5f3a5de,89c089f,62506b6e,2c6e49a7,f1cc4a11,e502079f,97157538,2aba92cd,8f009de0,9dc143c8,51b0f3ea,31067381,48a34858,8c085d49) +,S(138c0bbb,17c63e1a,a3e65b50,3c602d8c,74178847,8dc2bcce,65b84cfc,95f7ec41,bdf88a3e,34f69fc2,415fb95d,a4b6d3b7,f159651f,36a2d4e0,b4063e5a,ee86dafb) +,S(7d99662d,e6274432,65ab2842,a4ed79be,480404b3,1b847c01,c557e277,ee073176,e2ceda2,bada9b63,ff2fc022,44124d3c,b83dd4d1,f3fb74b2,763ecdb6,46e4cbf0) +,S(9e3f4ea0,b1db451b,7d713eae,35802229,fabbbfd,6f6d0ab0,af7483a5,37992e63,a9023199,10301c3d,78933143,b54e87d4,1419524b,16c9c00c,5550fafd,e6be8b65) +,S(108c8cda,d6ffc3d,b0863a66,43f0a4bb,efcdb0c7,202f630f,f971a7ce,dec3ff40,847ab4b9,8fba1fbd,15f6bb2a,4b3d1038,726c2d66,f4c9b8e9,f740af8f,5067d95f) +,S(5258a6a,7c85d4f3,e650f0e5,1e2d8254,8a768c0a,f276da55,27ab0050,6e97e710,e5605a14,31c8941e,4f2aa3c7,9ab94e3f,ffed156e,ba2159a2,7fde377e,e2ea7e26) +,S(c40820e7,f46acad2,5bffcc6d,745aa3e,7036f26a,b6ae85f0,e3cb8f95,29dc3f3,6ddf9217,88249ac7,6ac2c9b0,1dc5e62e,91587d15,c76fe26d,6d7c3b2f,feaf3b12) +,S(c135f50f,160d04e,43148abf,d76509c4,e55aadc7,554e4ea5,823e013e,a0490da7,f9a597a6,b26a1485,a7d5a91d,486d099,93de9a4,6484edc8,72f8f4be,710aae69) +,S(484be5a8,b903230f,991c3118,38d3ebdd,9759f5cb,11a9d0a3,9bb11a03,3924268,18f80a36,a3d70e67,5bd65253,a1ad3e40,a3152d55,c1141315,57f8585e,315ba462) +,S(af67562e,998a4032,77fc5827,cf222258,cb2f23a7,4dcd0d4b,315564c3,eb66da9c,dd5bf89e,c9b2c178,6adea201,d36f3a66,771b3f2a,cfba7acb,c30024fb,fa73ad6f) +,S(38dd6cd,475f2808,938d92be,8ad0c955,f3cf3255,c3602b99,3c177e06,553af411,1abcdd02,d82cc0f,680362bb,f898bf89,304d681b,6bc3afcf,65454ab5,8d44214) +,S(ee37f0ab,3db1f9b3,2da0031d,48f53766,3530b68a,f47bdb87,679426b0,d90fa6d5,6cdb12d8,136fc9c6,2f025cbe,7882ef21,4e7b09dc,9fba4cf9,b021c4d6,610c0397) +,S(670684dd,fcc19f15,ba9201b,ca36d143,47dabf31,bad07e8d,68e6fbd,2630a98e,77bd28ff,a9699737,1304d4f,82d29d1f,a69dc123,6f2ee438,cffe3f2d,358ce706) +,S(1654f447,78026345,64e3608,bb29004a,812ea39a,d96830f6,66a92f5c,54a79359,11d91962,3f81fda0,36d2d021,607d9750,cbd30359,83c4f47a,21fc8116,ca93cbe9) +,S(ccf0a89d,429a0274,7b000326,d62825ec,6978f24e,8f92f490,e8cab1ab,ff90bfa1,5f047694,375222bd,5968dbcf,a331db73,85b4df25,72791c53,42c62467,3d84400d) +,S(45d36700,32ab11c7,897d648,67ed4d03,a9504461,bf28f3df,7e1276fe,4c1de796,67e837fb,37108844,2338086a,d1506453,ed1f37ff,fb14e617,93908c7c,2a8e6fa4) +,S(9af3b6e1,627a2ffb,c18ddf33,b668fece,bbe7ebe0,986df82f,1b2fdfa1,56dbc565,55e9562e,882f6629,1eae4c6b,5a82b0b,b5bc2cb2,b8f884bc,3e45a126,aeee19e0) +,S(ecfe9d5e,d3b9fe15,c320e05c,7e0f3b1a,5fdaa9a4,5e1ff99f,88012642,a5d45b4a,b3cc1fd0,e0117151,f53ec671,e1d207ad,5f2b0755,8956cf28,2be5228d,db5d48bb) +,S(6e482326,6ef64478,dfa30c6c,f3a951f9,fd9d3108,dbe80e5d,3cbf2217,70f5483c,97a3f599,906b1738,372212da,80309562,d3d4179d,d2abc2b6,41ef2f4e,6561095e) +,S(3de89149,f6c939cc,5419e4ba,f0baa93a,390f01a3,4ad0fb7b,3b170e54,60a380c6,e9a07758,1c4617c0,b996ae3f,b250b723,874b66fb,85a6d826,cc5826e5,bb068491) +,S(d4d28193,53ace188,703643d3,84622505,d9020459,a600349e,69016cf4,faed2e25,9a494bcf,e15bcdb0,97513682,ef09890a,424d6bc1,ad1cb73f,123ff5f6,7babb364) +,S(f694a819,fd0f2035,1193eba,c18e2db7,9c219191,2bfcc60b,6af8e067,2281095a,d80d1652,1e43f18a,4b663898,bfce8670,6f53436d,a30b0663,9ee6f99e,ca87e667) +,S(af8595b8,8de7c459,7d1d1614,ac897de0,5dd9ff05,593dd3b6,cbac81ce,d2e1fb5d,e9dcce9c,83ee7217,857d5ca5,a48bb720,69d467b6,897be9ac,658dfbef,3d40e6a6) +,S(df4177f6,a7deccf4,c618b710,b096bb4e,b310e4e2,470b5795,6a633154,8ae8123e,3638e20,5d42ebc6,7184e567,c177f479,18fbf9b1,e4f69435,487b289c,35c7fedf) +,S(ef50482,30344ae2,70ec6d30,f4daea23,ce7b64bd,b101638b,5a52ff3d,6dbe9fd3,a6eec78f,e38a2e6f,a9c062bd,4ce28dde,c5d25fd5,a3204281,ae30d79d,99a2658d) +,S(f89596f3,ddd57abe,3344080c,a6d85d0c,492261ca,7a698aad,ae00dafc,75615954,f8d7d2eb,45dc2b9e,a0979550,8d9da016,20b53a19,b4150ca6,36bf0f86,ab3dc0dc) +,S(a7c2ffd7,50b99bde,92ac1419,57d8df27,56ca49e9,3f4c7434,b24899f1,24fb3cc5,a1672ade,aadad853,47d1440,d573e3dc,91987d6d,ce55c67d,665402d5,f8b0a289) +,S(463f5f25,b5c63801,a6b1accc,6662e6de,5256fce7,37e1c875,2b4a880f,19ceeee9,858e4a68,39eb48a7,f1a7de4a,514fdb46,1f4203c2,65e308d0,3fb9770f,1f8f13e5) +,S(4c99bf38,57073c27,cc92314c,f260dbf9,e0f4bb7d,1a5ffadd,a808783d,3bb602b8,aa107422,ac7dbbbb,f6e8064d,22a5526a,96bcbca9,9dbaac33,c1f35b2f,c6df568f) +,S(f6825035,64438569,aa7a5a4b,e2468453,8d8bfb88,f7e983d5,33ebffd,f8588520,84ff2ce6,9d79938d,fd910bf0,25a2fe8d,e6013c03,74784b73,168049e,c851cf15) +,S(62ea02ca,16b2e528,2f913a,36463494,c00df046,8afbeb34,cc9573,b71577fc,36be98bd,2c83e8cf,e0fc1aad,98ffd9e2,9ccbad8f,a25b9da8,23de20fb,fe91f9b3) +,S(ea34600a,7591c57,d0a7e351,de6e6d0,2c72220,62a980cb,bcca8966,356a2984,25eccb4f,a6102f52,60e4c545,57aa960,b427e372,80c35b8,edad5f52,1bc93aca) +,S(5b76cc79,2e78f177,97b32c46,92f2eca5,1ae1b7be,a753ce98,8e58d116,6c667027,2e01ba25,799e1b9b,3416493e,3fe9fff2,c46e634c,2175a30d,7458429,3ea60b5e) +,S(62a52d8c,d8562624,48ce5315,28213ad0,6fc6044,b6490db7,c27b7662,bb66f07a,e8f5e0aa,aaa65c7c,2b51e665,f3b31157,54ab9fdc,ac492ee5,fbb2a348,d8db5376) +,S(a276992a,5e155e29,d091e05a,5f0513d9,ff2dfbee,6ec1ffd9,a91f55b9,bca641c1,3d480cf4,e3f6efda,6cea9cc9,d769b16c,d1f3d64,23aefe9a,abc82b8a,adb22e48) +,S(bdb5fd64,bc99741f,a2a672d4,a895aacc,98886a9a,d38a486d,ed1915f1,f0b515f,d9744595,ae6e1e64,5a52a094,75ad094e,6af9655f,185ab90c,c03262cd,39794f93) +,S(cd6c6829,9d2b1c60,9b70153a,45259261,91b9b9d0,9fcf0682,d312960c,c3f82c04,2178ce3f,1bc21a2f,7accf32a,b20d625a,182f8733,e460e8b9,e1067dfa,fee6b36e) +,S(ebbfa9e1,8a4107a2,475f99a8,672be581,f32426a2,d774acdb,efe501c0,af97a0f1,1845a5fd,d71baefa,64cdf1f,d1211158,a70752b3,adf2b4d4,b5bf1a9f,7a0abdf2) +,S(bd5af866,4d51256f,455a3190,88b754a5,34223135,1491f763,3e090bd6,27414fa6,f8b5bbf2,2154786a,29f75090,fca2e149,60f84b47,50ea8db,d7c309d2,52233f3c) +,S(34ef0b38,5a8e776f,1c3ff95a,5852027a,ab6d1da6,6201548a,fa181c81,55382b77,958180ce,9afc501f,84d4d3b4,eb556ca2,e6ae8dcf,f949db6d,33cca5e2,9b357280) +,S(4b5f6663,11e6956c,e186fe3,85f00069,c0dfbf67,e4130bda,64e0e89,1abaf471,a6cf3571,2e790d5f,b500324,773281c,43f6d008,f6578ab2,b48fe4de,1ce3b545) +,S(cb22489c,bac94ccc,887a1d7d,8836cacc,c8c2a43a,4e09595c,39cc6064,ca04546c,dced75ef,d7ee6ae0,18ff2690,9abc82ca,da74e823,c62e4268,606334e2,969bf94d) +,S(b069007c,4a50bfdd,38ebcbe4,31a952ae,5356d63a,9f4179b5,e4cda3f,fe478c42,bb90d5c8,e66c6194,ec55acc7,6dae5f0b,dd498746,2d24a265,c314e93d,618a0f41) +,S(18722ce2,9d9cf99a,e52a420e,23fd8e85,e1582d02,c520d4f1,16c2b82d,464091f9,9fe257cb,5cd5f644,183c8461,ac2dde6,94cc84e9,76d9c623,584a9d94,40fea12b) +,S(a1562afa,6420b34f,92a78951,e9ab1bd7,8772a181,636df487,81bf4bc0,b16bd196,ce4435e8,7105d006,9b353734,5a503e0f,a692d3a,8571e8b9,66d9a722,48ecbd1c) +,S(f466db58,b4fae060,b12b780b,df11c7e5,ea8a08cb,cc50e68b,f5d85926,b9f3cd97,c86b4153,45515a2c,9a831ff1,d6377a8c,cae62456,f207df2c,42a1e767,684f79a4) +,S(686a1d05,e2bfaac8,e31def35,21876c81,27be2ad1,34ef3dcf,6de52778,37278176,111404e1,7f2153ab,43597a74,be1c278a,998b3695,5f4d465f,271a6a46,8e9e8986) +,S(d8433d5f,e5ec423c,73bb3ec4,95d06cf5,3a77474c,1e97ff97,f72a0457,9a60926e,3df114d5,a9d63dad,ada0ec4f,f98cb8ce,f1ad419a,e2c23dc2,f24048b4,1879be1c) +,S(3a9a0aed,4581937f,fe49392f,488053df,349f0194,9666418f,16e56fcc,533cb73d,c9db1a90,2d6676da,251b4be9,7a643bdd,d55c2b15,95ce51b3,281cc866,40cb558b) +,S(b35a204a,28884708,3091abf3,34be3696,b1082fc7,5caeb0d5,18387aa2,711a4190,65f951c8,78232345,487e8e,376c22bc,e5d9e8d5,ac04ecbf,24cafef9,4de358f8) +,S(81ff6fec,11f48691,59a2d23b,b2a6a9b5,68c5e6c5,1df9905f,ff73e1cc,a2c505a,c7b794cc,d657519,fc05632e,33e23474,654f1344,6ef1b4aa,1a1da18b,4acc1e49) +,S(3588a9e1,7feaaca1,a62fcdfb,3952beba,43116167,bb238f10,a41fdfa9,bc316d8e,acb24c1a,58ed9a0b,9744fa76,df4742b9,b440347a,4b4446ea,a3e55234,102d4789) +,S(7eb13fdc,9588b724,e7cddaec,498a8b15,d57a49af,529c8c9a,cc8303b5,e81f91c0,89f6ac3f,38351f7d,e4b293e,f61a87a4,2c08a4a3,ae0c160a,563ae5af,dc62dcfd) +,S(2f68c6ef,b363459d,862710a0,a0ae67c4,afc3cc00,85f02e21,ca4d764,3c76e00a,f8be9930,3a3aa7e5,c50d3f53,9b88bfad,60f05fb0,1461d7a8,225bb21e,18616cd7) +,S(b11994c2,5e3e6d0d,917ac215,c5f39606,3b9b764b,5dfc2b75,ab8ef880,3b57d802,4a7ae35e,c525d91a,cfbdea6f,cc9afbc9,b3cc8c80,acb4385e,9bc20158,f9f2b55b) +,S(d8e7881a,e1e4d04,c431c097,25dd4cd9,b4efb4c4,3896256b,7de47fc6,3a3b30bf,ccaf57cc,138f0bbf,5dbde16e,91d14875,c0d5ea,3842e864,be8de17d,875fef67) +,S(88e02abf,a37ffc97,f564cf3d,8a086c8a,62c05720,802319a2,30ab7cfe,b448c478,ec2d3169,15dd0c2d,6f03f851,97a96f9a,6c0772ee,df0c4524,c08f58f2,39c89308) +,S(ad258ffc,b42d127e,a875b181,a8883a5,31d18a64,d75a6dd4,4111d697,90752d1f,acf5ad9d,bfbb14cf,a25748e3,96bf23eb,aefe1bab,6550b234,90ca0278,276e9db4) +,S(a2bfdb6d,38159e5a,604d564e,af29cf09,a0a8ac79,1aef5a63,e1c05da5,fb6a0c39,7a45c5c,a7ee7c0e,74c05914,1e3d898f,ab62a8c7,31ca0a66,a937ef55,51dad999) +,S(7c7bb792,ef21cd53,bcf33a82,6a1ebf93,e9f3357,51131f9b,36f659d9,594f453d,bc98b32e,173d91ca,e9daf137,766c5ca5,6e0434f0,e2eb070e,7fa7f8b2,e7364635) +,S(40a2000c,dc0c1c9e,4c037a3f,3113b48,f26730ce,11e03b1f,d2f07217,7816f8c,1966929f,210afe16,9daee99b,7b48eef7,27e1703c,8bf42006,922c0496,888b690a) +,S(6427d169,cfd7e9fc,1b310f68,e3371720,28c17dd7,c6d5a32f,4ed6d41a,634f3f1a,b1a71fdc,6a030ca3,d7dc2ce9,27f3b9b3,ca7169f5,2fdecba4,bc85e32b,4e52fcff) +,S(723013b4,24fd897a,1e8ab77d,ee0618c9,3c832117,94f8b822,9d7a9e51,1ba8194f,21acfca6,e5e0cc31,479e5a97,17494692,9134f2e6,ebcef2ac,c7779251,77e9aede) +,S(1b18b7a5,43a284b8,3165bfa8,ca947da5,376fc4a0,8f4070e0,a20aa905,fd12acb9,713ab4fd,9e0bab6c,aadd2f63,1c5ef168,7cae85e7,6146319e,94b19a1e,f6a69584) +,S(65e5990a,4700f51c,9d3e61d4,26c92f88,5506817c,d4d60c66,a341cf91,9646ff81,2ebdd818,f69cd135,1405c63a,7160ad4f,17a6a7e2,d4353db4,7b554eab,3e737819) +,S(eb131661,eb78d37f,92a851f4,506c43b5,1f2a155a,dac7eee3,b1dbc29b,a0b1250c,45f2f418,47d2258c,3f78a2d2,794e9aa8,eab23395,8debf0e,b1440d56,dc728334) +,S(f20aaa98,ab7d6f1,d6de080e,ecd0bd28,b14cac9e,7f27c931,5576b039,16777203,4d0dc753,84c942d9,347f007d,543bc399,ee01e84,7625d5c1,a57cdd67,79c4dfba) +,S(9994a963,ef21ca0e,9657cbcb,3da57f3f,e28ce389,60ae5dd2,812b2949,96969047,93d75bb1,35572b75,4801509e,5b64858b,c0a415e0,3968efe4,2e558786,8516362b) +,S(4696ef39,95e5818f,d7894737,2fd68c75,fbb455fa,8477863b,b2687fca,fc2cd7b5,1cdc53f1,c52112c2,f58a6f66,7c1e4e9,110d83f9,d765347e,a724c784,d8e5d5ee) +,S(7b052f1f,e1af9537,ab3bb5b,3e0e510f,7e101cf0,999f85be,c403fd62,53e68d25,69c7f158,4b6c36c,f7d881a0,fe4efa5e,3f879753,641ce0f4,3e73bfe4,77ada27c) +,S(99452d74,3311867d,1d86c1b1,decd1ed4,7192a58b,3ef98cf0,7816823b,1296abc9,ffabb50d,a1a0451d,36b811ab,5e0c55d8,751a1851,3ca8bca4,8d6b3ffc,61ba36e3) +,S(40c6fec6,5ded4688,31f72de9,fb5c7f67,32c0c170,29f19b36,b00b0f85,5a12424,17aa0baa,eb3ba6e4,c5000e96,c3eb620d,ce1dfd81,b35a3e79,b27b8246,97dd5741) +,S(b9bd9e2f,c55ce5dc,2e46e4df,56401c72,e01ac3d5,201a3cbb,a6609fef,ae2e827b,f545efa7,f95e9a60,72cb9750,6f929b4c,e0360c8f,a9f058e6,5b87bd55,a72abdcf) +,S(867c0fa9,f885935,2756e3e4,11666eb2,59a416b4,7c2ff329,e30be462,13178921,6fdda875,4a50ee1b,d229d4f0,fa8876d6,9caf9fb2,a6af19fd,dbbd2a81,5dae486b) +,S(1cbe8374,3decb58f,f2fc9668,7ba45c64,812507ec,c2f71d66,eeea12c2,92fb36cb,799533ce,46d2c091,d0b553b5,18c82317,f516049c,4a4f50be,909c875e,b0bbe21b) +,S(c654f9fd,57426248,fd24097,2595d71d,80cf771f,cabed8d4,63bdda8,340398cd,898e9224,c9e94d14,3f96702d,c296bf50,9b2cee37,da574bdf,b7c09cec,18357a18) +,S(49e8e14f,4a9f09ff,48725eda,85ecae6c,3fe3400b,81012e00,991f6a69,2d75083c,815230c9,284924fa,57d08944,2a30c61b,8ce19644,7a8ede69,fb645864,ef35977f) +,S(43a6ecde,ed83f1fa,8946f584,99e71bd9,978f610,b46d1613,c15fcfc0,f79786af,2995f70c,11eb448e,68eb3d10,c84b36cd,7605e249,1df1fa3,2e9eb57c,c0275482) +,S(96861d91,678e5004,7c491950,5bbfc70a,e342c3d2,361729b0,4d0bcb5f,d93eceb5,6845ec37,9bee6269,464b2e9f,156ada30,c518bb8e,105153e1,c3b3e948,d38078e7) +,S(3c72be53,c9f82add,504a1955,7b9560a1,7716a058,26063408,79aca60,c55f4515,e584b72b,cc4744d9,6a00dc44,b03ba61f,c2269731,a8178755,2a6dce8,25d31b81) +,S(ce4b4d07,deae1fad,33192544,448ac5b2,77ba7f70,27b81a08,d7f84581,4f71787b,2013299b,2c744a5b,da6b243c,d04d95b7,e515848c,dc28eb40,892d40c,210bd1b2) +,S(37984db1,6d288866,78e1804b,9c94ebf8,f3a1aa05,1fefce96,65712f98,198ce116,20a25966,8ed14a5f,fc3aac09,6d2351b3,b6cb19ab,da4c833b,4a2a6c68,55d1ce59) +,S(ac01bcf,b02e627b,2c9c931c,f87beb2f,4ad7328f,9caf627a,2bf695ed,b7353acd,be4eacf4,77c92348,fe0feea9,3075e93b,bb3633c6,6747524a,e387df82,176ea252) +,S(d5d6af83,1a81b72f,efe5618b,ea43335,bf1d81f1,73382fda,860260d8,1a2faa83,865f9ee,4ff0fc6b,fa761709,db4c67ee,a3213d07,21b2facd,fcd8fa57,8945698f) +,S(3c16399c,4de35853,a6dac8c1,8eea4b40,92a22a8d,5e69ed0c,13b9c2a4,3cd5e39c,bffc2dbc,c2ce4b04,6a92b967,d1a04b5a,2fe40be0,fd9930d0,45b51f8a,15b53edf) +,S(f67018d4,23e50a73,68045b0d,ce803e35,a26d9a5c,288a3a7c,c25ebb03,dad28187,ee97afc5,1c73531f,ea8998f5,53086a59,cc67c6db,955baaa2,8f57153c,afc4e772) +,S(de67026,529a32fa,b3ae79f6,ef9ece7a,47008d2,46f89053,e9339c4c,dcb53b30,4daa8700,4b055005,90611f78,43d258b9,516f1fe8,61cf06ca,d466e000,d3a68783) +,S(a133627c,af6e7ed3,1d267608,19b69f45,7e75ecae,2169284a,48b5ee16,b5dc8c10,755ef12a,fb5c071a,36dbe2b7,1f858d87,31c93d81,d271c999,8f632982,d7e97ce6) +,S(d255c1e7,ccc88c4c,33887c9c,b9c15a2b,52b08471,90ad1420,5fb5909e,d36059c7,83e3e1ca,99a386e8,4b119391,2c20593c,f9573996,d42cb7c3,6db24a5f,cb413080) +,S(aca6c69b,9ea17803,4af67422,71b8062f,77e6dbe5,1df2a570,65fb3057,ea185b8c,40cb09f2,adef414c,816b22f8,d7a59f8c,f5197fb9,b31614d9,ac172436,d0f54647) +,S(fbc19c84,3b656fcb,21d99c3,5289d3e3,2bc58fdb,c2404309,a9d8831a,f2365f24,cc22999f,203a4fae,59eac72c,28bed6d9,291f204b,707bffca,ca6d8359,1e403124) +,S(ea308c88,c366677d,5e575457,cd3e6978,5b491a02,c542dcae,5dd5e149,2f839c55,c1916831,2f48555f,b80845fc,ba89eee7,a7967807,d10c6f6e,b516c190,94873ac9) +,S(d911d62a,33fefc48,abfd4409,7ee2d32f,d7e85816,2a8a00d1,342646ac,8dda6cd2,f160f933,41bb32f7,401d153b,4a2decf8,b793fb5b,4d5520c9,6d9cb9e,cba79aa3) +,S(bb75b497,7d698442,7b0ac74b,939ab3d8,fb94304f,602e102,1fdacf22,27022a4e,ee3cc171,8e9190df,9b45d8d3,54eeef9e,11639423,dc091128,ae09e451,fffe3468) +,S(358e7639,b4031852,b983b5c0,a6c0d33e,5edb304a,3f8bd15c,35d35794,e2cf90f0,5da4be1d,2e9bef5a,5da3cc59,d3c4f85a,e6624ee3,17395ded,398147a,12c56c45) +,S(e098fb9c,440a5cdf,bc570270,4b57eeed,f3087b7,e196522e,4b194618,f3c874fe,9a5b80e6,b22dd111,1f824c36,4830e723,18b7825e,2f2a0fe6,ca460d0c,34eb6449) +,S(62d607b2,d1a16e4e,cf60480a,be9416a7,15d70b5c,56734e7d,1498ba03,7632528e,70c5f4d1,4f5c900a,96291a4e,d0f795ff,439d35d5,2c5bddd2,ab10571b,1d7d20c2) +,S(a630c5bd,ec76f869,40842391,cba6cdfb,9109940b,e1034b87,c6a1e5e6,9662857c,8f28f55e,beed2883,3e347b10,92ff8938,133558c3,bfeac1f6,a6b938a4,c783b79f) +,S(e2a164aa,e17cb0c4,8ae1e911,872b0b3a,7c0e29f0,93cd5e18,97145211,d72147b,23ccf99c,afd1bfbf,a7ce1ade,1590d609,9a423b26,381f5761,c19ba373,290e6193) +,S(742526f5,b95051cf,2ee34994,8385fa72,425162e7,e46bba3,febe5ce8,595a8b37,d106a3be,638987e6,870acf8d,26d4f78c,e6aa0e9b,63e4eb19,114fc97a,eee3a12f) +,S(ce7837c2,31c32444,10dcc790,de465c06,75404a1a,68d23fe9,b69d887e,9c554f45,2c0be877,20cfdb11,8c37b2de,a2c355,d12279da,58f75570,7e738867,146257a3) +,S(601167cb,2788b146,998f0b91,d582cbd,27f4b866,40db7ec6,7f26214,f3ab9212,50525e40,1f2da57d,1f605f34,8f11ac23,19ad1827,41d7be11,46538e83,e03bbeeb) +,S(d2f657da,6f7c3c80,9d2e5291,b1161d46,393009ce,e2bd22ae,32b99eed,f76fc728,6df58d32,b795b6de,2a9c3b15,f4f1dc9,4e6e6757,e01891e2,79acde59,d13e3e75) +,S(e9fb6b74,f84973fe,7c7a0924,e0133b92,bb4c22d1,ce9a94e8,433f0c72,2a86e00d,f4df6cd9,df43c150,9d4b9580,eb87298a,551ebec5,2438597c,87dd46d4,3a8ad2c4) +,S(98d46b64,e43f3384,88c63da7,35af1141,e8b41981,b706ac5a,7aa1c0ac,1182afd3,3b2ce203,5bbd2cd7,f3206b3b,6aa3ac68,31e0e2d4,7f9e57f2,3e780fc9,cf865733) +,S(b358a4c6,a7130b1e,a00d8403,7164e68f,c6cf96ea,c6580ee5,b1cc2452,8d2bb5b,3bbb25ab,4645c17a,2a6f7e64,2d3952eb,86462564,5647abd1,2e80d965,be1d3854) +,S(fd8807c6,c456582e,d03114a6,2b42316d,4d0d386a,aee634cb,d33f2f82,c1ad6f05,c67d1611,e45c57d6,1f8d721c,437c0ca2,189488bc,f363aab0,f25314b0,14f896) +,S(cd53fa2a,1f989ceb,cedfb7a5,237addfb,2efe9469,8b6509c9,3081710b,f0db107a,47e61ca6,4d26e617,8192e993,411d0540,bf7c37b5,8c748eb7,6c1c197c,87c3f844) +,S(38cfdfb1,1b60a68,b00a4096,8f2da5e4,4a60868b,de9af728,fcb888b4,9a098c66,65f4f191,92667492,d717cfbe,bafd0076,59c08392,30da216c,315f2cfa,d3725184) +,S(cc179d39,1c6ab4f3,7fae6380,35886e2f,82038bca,768d1396,13fae8df,a167a271,a12fff68,84a967e6,fdd6e14b,4083c0ba,2a2bcf49,f7d6071,d708c70,4722b1f3) +,S(cdd61b33,75fd00cf,430d9d54,202c5c61,465fe7c0,a3f51660,ce74a3bc,58068c,46e5334d,bad31f3f,6c4bccbc,6812cf13,5c039a5d,d51c6516,49564f45,45f13ab) +,S(39ecf8d5,4fa9c3b,fef7d5e6,5ebe0e75,288f17df,4b33036b,d034be2d,fa5bdbbd,21991cec,ef62e421,70da3bf9,8b2f9bd7,790d5b13,25159727,a53a0735,5ab1d956) +,S(7b621836,342994d2,3185da8,67d47e69,a67a184e,925a3,524f5e7b,63639263,b08c269a,1569538e,653f2beb,3e6e348d,c61537e0,7afc5f13,f56d1f74,518b274e) +,S(28e5ec3b,38359a6e,7d3a965a,c5713365,44b91ea5,c9f350bc,d315c153,72133bb4,5bdc5a02,62734535,8621c1f1,492b3434,be731c25,f82c1a32,163ecf09,7f548465) +,S(37ac3ac2,3f6b2a1,a3a5a99c,707a6b8d,5f05e80,133ac522,107ae5ff,414d33c7,460c947e,76eb51c8,42bd0e6,6ccc0937,87f61bc3,554538b4,c2065fdd,533d0b02) +,S(275f5ef2,a4546ba0,9d96d138,e698cd32,78cf27f3,2ee297a,5ff8dd41,f16bea50,ca91a3b8,5b0a493c,a49168b4,c9eff873,66212b9a,c030fe6d,a9be42b7,45d0464a) +,S(6c43669f,a69bd51c,63cacca0,21c69bf7,9a94ef9f,3f0aaa92,3be9380,a6702e34,b416195a,1419771d,82fc2ce0,637cf5a,29823d1a,95614642,c93a979e,5ff3fff6) +,S(606c37c1,271b90f7,482e6ba1,81bd956c,44a44189,346bfa67,539c188,ac0eb61f,f6af64cd,3f04e30a,1b4a7019,c6caa84b,823bd00f,587eb58a,e190ef25,322154b0) +,S(e4136e15,b3fdf609,f779d0c0,70ce8521,2babc592,577361d0,47ada13a,2a83d43b,1af23c84,ad240ac8,50da2ec2,721531e7,18776ddc,5847edd8,b4d79d52,26e53125) +,S(a338d942,6ce420ac,c9fb29b9,cf572af0,72c0d144,46dc2c3c,75b9d5c9,f7fa244d,c88a4399,f6e3ef2c,619cd9d5,215d305d,3715b962,b02b29ca,231446cf,8ea7c40f) +,S(c454d1b2,6f77ad27,a168d032,fc1a73ca,fcc4aac3,ace31f2a,433599fa,7107fd9a,989b6091,ba2ec267,380c5139,47059d4d,2773109c,1afc21a4,3be54ea6,ad8f19ee) +,S(bbd7bd30,5bf1b36c,6cd6c180,2f41525d,75675d76,9352dc60,1a727931,ee6f40c8,3c3263d3,75bd412e,1d7f7d5e,72f73216,6415ef3,52d1fcf0,58e6c046,ceb46abc) +,S(acae6fb0,5d5b503,c2e3d841,19ce3bbe,1380b363,e5d8763d,3c520a3f,df39f7b6,6fab4b7b,daba880c,9167ae8f,5feb9aa4,3ca19f28,77ec5021,df36ac7,db730293) +,S(c9d4ba53,a44403b3,b06915f,6bd9bb43,4716a639,453797e,5b8e1cf5,abc78425,749cca45,6abc2a6a,4e970589,42cefba5,a2f55dc5,39bf4f3e,be5088cf,ae04bf70) +,S(3408e460,99f1a176,fd52f70,3c772f1d,a46d32db,246815d,a21826dc,c5657e61,a93bd344,de7afec8,2ea2842d,40fbcf60,732be8fb,738b8364,aaaab796,1e20974f) +,S(5e061a06,f97f61d1,5f66c3ff,17372621,4ce82af,3e606b4e,9f64fb62,e405376c,609064a0,bde996b2,d909e50f,726ed7be,b4698ec7,5e1c9c45,3ba18815,2915cb1) +,S(b12ca67f,739f4284,3a7adf58,d2a2f3ca,fd245ff4,b766793c,c79cdc31,45579113,b1deaf81,34f017f,b2bc20cd,da75fcb7,d219c353,98ee9887,612781a0,e3f3d1e5) +,S(95a72f2f,c241fa0f,c9500cea,d9cf069d,23820078,f61d4492,508d0fc4,34fc223d,832a3979,1fb9fd9b,79748643,64643bcb,b227c39a,e4cb5051,d136263c,293cd453) +,S(ab8ccb01,4b672660,b867e544,926749bf,7172a0f5,ac6317a1,a18b7d15,f039fc94,28471e3c,a2d6e77c,87700c4c,7e3df1e9,2fe91efc,77724df3,2f20ceba,1ba000fb) +,S(26131926,5261c0d3,ecfa9769,fa987347,1b9d4ebf,dccd830a,96bd160b,61b47278,dc9ab665,485133d2,59d7b604,5e1e4f52,9b099e9d,4db9f680,4935e712,f8402f66) +,S(87a4227d,2303f5c0,acace6e,96586b68,178dc65e,2c99583e,8e427ad7,167c4a65,5bce1d82,216355d6,5bbf33e0,9b3baec4,fb0befff,ebe48b24,cc01d454,7de6db8) +,S(a6576ea2,39af87ba,392a225f,bcec3045,8920b494,68c54ff3,92d2f509,519ce85f,deb950bb,6a767b3f,3603be36,6234480c,1851ae4b,1980f902,f8fec863,dfabde82) +,S(ed41c3a2,48285ad9,1642f6a6,feccdbb1,66298fa6,467b0ec0,ea256570,c8e343a4,dccf3578,aafbc34d,8ca5fb6c,b4482de,4b94dc65,a8d22845,ac800947,dc1042b8) +,S(227756ff,800f7eb5,4493181f,83050c32,9f27a35b,891a3bc1,ea5f0e89,b94e77e7,571c9345,e9e95238,3c7dc62,69aa0fff,46455825,a032f33a,154a89ed,e13a09c3) +,S(6f3b91f1,3f2d6787,454bc7a2,2ee780a2,3c251697,c0da9aa0,a03dcc3f,f03e2b0b,432b396f,c2dcd370,647eadde,ec058a01,53fac955,4b3f400c,435c4755,5e61afe8) +,S(aa79f0aa,767db1c0,3893c9c9,c75a1f8f,457f3f36,72c1d2ae,31e58658,a916fe5,4da2c69c,8033860c,14f8438b,8edf290c,5d02f2e5,153b68ed,fb945043,a6e6a1f0) +,S(48f2a720,df970127,2385a961,5a215d8a,3d41e0b4,ad439c9a,9d0453af,4699e527,11669dc9,26f70e96,e76178c5,7d698d05,b6e7da96,eef4e986,c4f6e6be,216f22ac) +,S(561d8010,a81a1191,3bb2436b,bbe0ce2a,6f1af6c6,fc064d57,59edaf45,c7f9781a,bfb2561,bc311bdd,707aee1f,af3d5c9d,faa9d564,a5121bae,9989665,b074f026) +,S(64d0fc68,6369a225,a15cefec,431fe434,1a424c78,85bdf2,51cccf53,9e266fed,694fdfa8,12f6bffd,b1c75baa,3b843d02,1b69cc8,20f2a8b8,69908a00,ac7050c) +,S(2b80d86d,341d05f6,218eb96c,fb227834,44bdcdf3,65cc3809,1bcba0ff,fa8b3d09,152eb516,2794fd0f,abf030cb,1968faa4,100e803c,e5b8046d,c36e3075,9317a8a5) +,S(62652ecc,daf7ff5,3aa255de,ecbcd653,7840a657,dd53e58a,514ec1bb,98c9b5b9,2a05c8cd,bcc4a512,1d2cafd0,6289fa14,178e91b5,b1fa1190,e4c7c13f,f50cef6c) +,S(f23fe7d7,69cd7bd8,5e0d97c5,4163e596,a0e7dce9,488e8f67,4ca6f3ca,81726ce0,eb1355f6,ecac2b79,dd299fce,c0f273fc,3767a3f3,3ac4777d,cb871a1a,99077e1c) +,S(91d4028d,1ea8e320,5718f427,b427c21f,4780a944,55ec46c4,2fb2a1cf,4772af1e,7a529f92,3756a212,24dcd316,bf9a3f6b,f5bfbc54,3b015c10,54ae51be,5c2e6b2) +,S(7a8fdf03,175969a7,80475dad,c43e5c66,fa75846f,63cfd62c,e82d2153,d185670a,b7b58ebb,fa0b2d3e,ec2a2638,accd965e,c7db6cf1,c847c1b7,9f0714b0,c1cf7dde) +,S(9d72d9af,5e9d7b2,7fb2b867,4aa35438,946c4ca9,eb9ea4be,e20b2eb5,e7cdb89,324214ce,d556acd2,3ac00175,f120d59e,50dc95e,96e6fda6,ff348bde,5ff7e701) +,S(33556ab7,bbf601ba,44dcb33e,aa5efc82,3c70f507,550f3d7c,22f4ba62,cf2d6bcb,a21d830f,233a657f,7857560f,c030f053,656aada8,f7812424,f38a2409,7505dcb7) +,S(e002b33d,93022868,60b39e1c,2820ad06,2063c344,bef98dec,3a9a0428,20e2c507,3133f829,1c81d970,f879d1eb,2128f21d,7540e135,31189576,191ac4bb,d83d99b7) +,S(9eeb1972,ffd49c0c,7982671c,59071b20,422a053e,394db993,8ef7b3d8,98795c5d,ae48763e,5ad78988,7a756827,4a17708f,8afdd8be,bc9c0316,73dd9485,319763c0) +,S(60f821e8,ad12907f,e445f049,141c7718,a495d1ea,3e39edbf,f0a73018,a5cb6854,6dc1b291,62b025ae,2a285e59,a5b406dd,927a743b,483454d1,20426fa7,50adb95d) +,S(5b8bcdc6,40f4a217,6d0661ef,f2ca5d6c,b1aa2069,557274c8,287fba59,dfd65a41,42ab52dc,cad04998,63e634db,ebaae018,c999eee4,c3cf05b9,4f18d218,23f21256) +,S(e764e748,4ec2a2ac,6843df3b,5316f29b,701b5191,778bda16,a23a20c1,69ed0cff,e1007e10,4ae52971,875bf7ea,9e9d9431,94c2e9b5,bc7b2844,7b7acded,de7d633c) +,S(37f0d948,48742a8b,e73ef1ad,495b88f,ea95f7ee,b343152d,85f9e442,771a22b4,bf960e80,467cf81,bc22380b,af2f57f0,d5938ccc,55f3f691,784be72,7fa68bb2) +,S(7ff13c43,7f2189a1,18b2095f,be268dfe,e1375a3d,f71e88b8,4cf5b94d,63b04612,10295e49,1f0a882e,aba663f8,f0202223,21c422d5,f3b453f4,8ab8bf4b,4319930a) +,S(74f6853e,f4a2d018,4cf113d7,62fe2a1c,33ff2729,5414a5bf,3f381989,551ceaa4,629f116d,37c1809,f4e2ecfd,19c2627,6deff6c5,b89249fc,d4f6e82e,58eeea79) +,S(d54d88bd,abdcc56,c1bb8cbf,cdaea6ac,16949256,f78d70f6,7a1416ba,b4cf51ce,996afb9c,5b36f588,812bad4,95c368da,f9e96035,4bb7dd1,3f457a6e,da159b59) +,S(a860ca66,3ecd7482,c862fac6,f6a7b0e5,f5f6bb26,ee950db9,2942fc89,4b6fbacf,3445137d,2047c17d,65b3cb88,8e1b0ba3,619db023,bd989a0d,c585a59d,14da7b9f) +,S(d794dc2,4e0e36fc,6f38fc8e,7a68cdac,8d547d42,b9667241,2dd7e6d2,c40f9aab,22a9a90c,10f1b80,e277be34,3c492125,24ebc477,1f838070,f2be48bf,cec3a7f5) +,S(7e28db65,2115f5a4,575293c3,d792fc97,9ea1adf9,dac468e4,60e5526f,6847657f,8025944c,16a12ac9,25e67f13,3835bcbd,33c338d6,824b1fba,f0ee001b,d79d66e3) +,S(d3f13a27,524f0c87,266f3d46,14d965a1,3865df67,5d20c5aa,99a4411c,dc6322c4,9a1025a3,845a4bc1,9f7cc175,9377c7f,e46ecaf7,53263433,baed836f,77e2e841) +,S(d845636c,db18d557,1759f6e6,bad6a60d,3a67141c,b0bfbbf9,33e628bf,8344c053,40de706,ef833427,80e5120b,ec6e61e4,a8a3726,32818317,729e60e6,3ab7e37) +,S(f40f53fb,c672573b,c020338b,71589d53,3709ac32,b38cb943,ed0ca0ff,e592e552,502145c,5f542a77,652a4ab7,d79791cd,e92f3e72,d9d0190a,2724e114,49b64e0b) +,S(2065a8bb,a0d61dde,921a0741,21ae5678,8766f712,bdb3c4c5,776af9e3,774120be,fd12cac4,a85d5b10,1aec6ee1,4b1301a9,950df948,86427be5,55f52736,3ca29847) +,S(a9b1e8dc,410466c2,df97cc8e,bbcb3af5,f981726c,2daf8803,ef06ef2f,a23e038f,b09dd4e2,77b1d10d,bfdd06e1,a42baf37,a5157017,ba026d98,fee13512,4a1c5419) +,S(c54ce1c,bbfa3808,f24b2661,793c3574,a58aeb0d,128d7e5b,ddcd98a6,d8c9bdbb,c1a2291f,d20e8a23,f4012b54,37a7be7d,5af5f776,bdbb2c53,193e07da,bc1a3212) +,S(41ad2d03,31f57724,6476d0c1,f2c46216,6156296d,8bfd3783,eec40892,835ec421,62777bb0,f8b6ba08,128f1727,9c237286,abc5d2a6,492b9c67,3edc903,7b0e3008) +,S(a8eddde5,eb761183,ef5cce4d,a7958b92,db28bab8,2f695fbb,597f6535,50048a3c,7f60d3aa,95ee5ae5,f4cf10ac,cb5729e2,bf89ba7,6b1070c7,ba385f41,a5912685) +,S(f1db8d40,2cee572f,6eb250bd,ed3d978b,1346ce96,d65291da,977b42cd,36bd073,9bdd0bdb,a546ce4d,774f79fc,3561c0fb,ca11f4fd,b46ab1c2,a7520913,f254f42c) +,S(55cee66c,7ebecc0c,7f22d03f,8f166b99,ec7b5e6a,776bcf60,b5f4d452,c861bfc7,772832cd,55b13c5,890c7ba9,96731ced,5a2e1c05,6ac89469,320c08f4,43159d36) +,S(61427868,7710db98,d4347d4c,aae4c70a,9efbfc7e,bfeffe5d,6f33bddc,4aeddedf,fe8b32bb,d0c7a7d3,b93dcb7a,99a5cc8f,e386bf89,7dcdcd86,ffaac641,6550dd85) +,S(9f3ac763,c117bd99,658f5379,119aa025,cd422ed3,b1ed2cc8,545d6f93,39baf4e4,41b2409d,cec0065e,4026e879,84b99d35,4eed93f4,15e8981,256e8734,a4eebb74) +,S(8510bf74,8f5255a1,8f408565,30f909d5,2bed111d,6347da9d,8da2a97e,751d4a98,2ed99b6,6af7cc01,37329730,1b0b63c9,f8732547,fc632eb7,7357e67e,df5549b4) +,S(d81fc0cf,9646ae0,7dad1a3f,e06adaf,1d3508fb,13af2309,c200c2e1,2228807d,cac833d6,c94e674c,a7aec186,42e4a501,ffbfed92,dfa1015e,c95740e6,57978cd5) +,S(32aa5e70,972a899e,e25e6c6d,e43c32ee,df07ebcf,e5ed13e,5095f7c3,3bb55622,38e82901,990a1e42,38639a42,66a93fb5,4368df0e,befe19a,7f234424,a8b68c0d) +,S(68f7b02a,ea38424f,decbbfc3,498c6193,62c732a3,b048800c,85d042d,b284f7d4,bef680d,90660176,f3d3d009,9f6cf818,a277dc5b,3d765a30,b7a4ee9,cf3bd46e) +,S(9437ace9,6b566bb3,87d9946c,2c32c06,f62f1158,dead214f,2b721c6f,b6e8888d,f8dee3bb,331e1e33,9963b7e2,316a1352,c8748f42,44463ffa,5bf2265a,243941d5) +,S(af40e909,85e5ce8d,dfb6d6d4,222d3c57,2ffae40f,53de2c06,55a74cc,70cd8dc5,2f08f237,3fc922c3,f0ed9d6c,b9538f4b,c661ccac,ea2f4975,50f47ec2,17d8e626) +,S(382e5a07,f1f236d5,ca1a68b8,f0fdb813,29e0393c,c375df88,f87914d,cef93c64,e24ee731,c0a88fa4,8ed3dba,87e97096,e0ec2224,dd657411,a9f1a9e8,2b0a6657) +,S(99fce288,c6ef1d18,ad630097,8ba82dd9,1c779a60,b266109a,288d51c3,978fe565,294c9e53,3cd42a54,c071d5c8,acb7edc9,897db8ac,d25b5f10,9eaf8dac,42a9c1a4) +,S(748326fa,c8dc9394,2de0a000,933dc18c,6ef92cfe,bac46939,f4405d89,627e6727,adf2d561,45581b4f,e706ccd1,8dc82bcc,14d76fa6,94ac8a61,a51d06d2,89e36d2d) +,S(43fef689,67074a2b,7e944b76,8f8b1ca,15aac3ad,c8f5590c,f1f02c3,afa82e90,5313cf6e,8cac44d9,fd548032,dbef3ab2,26e93880,644468bc,799c87d4,c0bc3f99) +,S(404341da,829f537a,c425050c,5ba93ca7,baa8a8b7,dfe51c23,e2ce7c72,43d57659,f91a0d59,bc35db64,b250adca,3cfbbaa2,2a82cfb4,d684e8db,e17484ee,af009f9b) +,S(3af33cb6,b4d553e5,50fd35f1,a0b569e3,eae05737,7b7d735b,545f7f00,d9acae67,42aa2cea,deab8cb3,b1ee9c3f,4b1b06df,e157cbfa,3912035b,585980bb,cf85279c) +,S(2e96133a,1da8a378,c138583e,86ba1de2,3450b285,3559a431,654ec9aa,1f64229f,3bfa5a75,4dbd936d,7a41266c,97472020,6cac86b4,d684bc1a,59dd1f27,fed8e76b) +,S(adc4b672,69fbb719,92bd6e22,3cf9ecb3,c9388b5c,45ffadd6,94c72e2f,b355984a,ed177eea,ac8cbd88,2a368fcc,4908ba4c,8a4054ae,3411d75d,b06939cc,72522a7c) +,S(68ac3244,49eac1e3,df997282,65a0176,bf6c6115,64daf79a,135bc6c2,5578b6e,407a75bd,b1e5e6be,a9b815ce,833c0be5,f5c462c5,c71a086e,59fbe0d2,5e7b1fca) +,S(5176afcc,b4235cc5,ea41eaa7,b657a77,bb383bf,aa71ef8d,d33990b9,9c2acab9,cb363792,9d249fc6,1c0931c,8a27dbfa,c8371574,52c40306,c3291814,ceb57095) +,S(4938cd76,e1aa6b28,2a89e883,8671e4e3,82d7bc76,dc4653c8,46323cd2,51d18542,2bfe67eb,6da39ea8,c8160621,158eac48,550c3730,664590a2,731247a1,399bc42f) +,S(9364dddd,dadbaa52,efc81971,75041c81,e7ebb48a,f20b82a8,125d85fb,a7fea192,ee568f7,53513b91,cf6720,2c45c4f4,181e855,ac0300bf,d7de30e7,317a6ea2) +,S(bdbc0937,243e563,df29781d,3b14d4ac,a664fe5e,70f3d9c1,39ef1b69,57839156,2a84b153,549c6d1b,27dd9ac2,1ab86f34,9ace0619,6f814d08,92a1958e,d137bb1f) +,S(b616b635,adf7b64c,43c4e242,32ffb330,bf28ee8e,48918093,9584c26c,28c82f2c,27fddaab,e5d47957,6344022b,68744822,eec7b937,d29b0631,93c7f6c5,6385cc89) +,S(55a3849a,50606886,abf6f0a6,5a3e657f,46031cd7,4c117365,8f27aa14,326f3cac,4a522c0c,17fcd116,61b11d9b,f88e0ad,c7a5761e,e01db8ff,a7bc3dca,a7976b00) +,S(d53e472b,439dc5dd,c8ff479,ff678dae,95b2e207,c92df108,728c3783,f8818542,3f3f7ecf,df3d9f89,1c723161,75a57931,4ebeadab,3c4dccf,bf2b834,c762d30f) +,S(1e27dd,f6186285,41f5d8a1,6587e2a4,ed38c34d,8393a6c9,fc0a7c07,cef36053,280b223,da8d01c2,12315c1c,ba7dd8d9,96d3202b,91c4eb4b,26c802e5,9494378c) +,S(b6d9d97c,64ba01fb,e8a9d29b,806d8a6,42413bfb,fbb4ae0c,10d8fe52,7ae6415d,894875dc,d912f8fa,845614de,a2b09796,d402c738,ca1f3c9e,c0796681,d715b8e4) +,S(2c97985a,5fd96164,e4c4d9d5,9a9fb52e,b2e6df0c,77ed4745,3dca6eac,7550756a,b3526bbd,de58e408,a4f45dd6,61f5c6fe,2f82d2ca,3e2172e1,c99d1fee,93d44c98) +,S(405deafb,528991e2,ef924f55,b7e4dfd8,185de449,cd6f71d6,53025999,4caae657,e959b7e,59cecac7,f813dc1b,a15bb71b,4a4832ca,54026e18,479d71d9,191c3ad) +,S(4276ecae,a14c0556,b4573b26,dba35226,4fff2c3d,12a3e4a8,4937ae9a,3f687bfa,7611836b,d3b335b,66f92914,6df0de13,d6ecd47e,88369ffb,6c9aa493,e67dfc71) +,S(6fd734de,6d2fadcb,d7b19f56,ae7153d9,1ddb396f,e0c1e51f,ae31fe80,8a35556f,aaa647c6,92865772,f31fdc1a,3b430ffb,e1647e10,3cd5d629,19bcc905,ff7ae633) +,S(4f0a22c,ad6ebf6c,e6b444dd,35a54e38,70017bae,eecc14cc,3f7ca88a,6d4e27c9,1386d40e,680060ca,bb46d678,d2be7209,418d6f72,d3917e20,7b833124,29b43ea1) +,S(873ccb39,5c10f57,6e50093d,44879f2,687d9321,441d8a7c,993c1083,ae7b0570,b261d029,dbe15f4,ff70ee42,36f558de,8984db4a,608d45f,4e28d001,e564c5e2) +,S(75d41857,5be3709c,5c732073,24f36089,b87532b8,e91db4e6,70a89117,9d25e039,47e29f54,fa62ef44,139db763,4b1c8f5c,e027b0d7,e1ec3501,1e8c6dfc,dcd1a105) +,S(b325bb90,cea81ac1,c79df75b,e7615ace,9b2a9d4c,fa1f4504,1a47e0d4,30b64b67,3024fffc,2005699d,5351615f,baee8c49,8a319a19,45ac8132,71c609b4,23e14a07) +,S(436c92bd,a6c7e124,5aaffb22,62036329,ddb8984e,624f2469,b30fab18,1269ee2b,2a9f90d,88c01880,62a152d7,e7ed5acd,33f12e92,4e36fab0,bc0602f8,2c1d3e3) +,S(c0105c64,4e51d333,c7ed28b3,c94292d8,6d9c04f1,89b3827d,f1f22fe2,99bc51cc,d73bc012,1233ba52,ef9727b3,1249babe,bf63cacf,ece0192b,5cbd618c,c48a9d35) +,S(9f2a01b0,46109d49,d11ee109,5e94c281,1cb6f76f,7773141f,632b3a9,2e5f3f7e,1e260290,fda1caa9,ea315380,781f633f,21c90765,2815251a,fa70b169,e4b0da58) +,S(4d805499,23dc1905,7fd35a86,feefb937,f2b621e,48946e53,b8390620,3aef584a,2cd9c060,d66be813,12a3fd9f,ebb9cbdd,4fc23431,c3e0531f,4a026f50,a40dbd30) +,S(76779423,b5e5acad,55137380,276c4033,a865ae5f,9ada0f30,dee6986c,444a1526,9a6fc30b,4f4c5093,b343c8d1,aa204ef3,7c2a6d5c,712ad8d6,39ef545d,1eaa9a57) +,S(1ccc1998,33f8b121,18227adc,2f27c3fe,8d328b26,684b271e,85f8368f,40378881,da21e917,94851bd5,a8859173,830ddd0e,988ffdd7,f7dcb263,f6755eab,e2d73f75) +,S(afeea14,e8306fb8,e69689a3,d12efe72,949b6b03,8c4cdc70,c95bc351,1f999030,cafbd04e,79378032,47c71954,d8c2a11f,d60e53b,35045507,8f6701ed,621e7d53) +,S(cefa268b,e551b02f,8fe50481,44920abc,3d03d97,3f2e9368,d2d2cb42,341c11b3,77440b02,64eb1972,91d2d69,ebdc1de7,66915a09,aa01615,e4001d62,7219d491) +,S(8625c163,58bfd43d,888ef97b,e33d9938,c62f7f2a,9e7b9735,26dd14ca,7c76abda,e1351920,59085272,3ea7b55f,49c4045e,2dda5ceb,c1a31841,1b6cf38b,b97bc1c4) +,S(43b8caf5,d4f72519,19630044,13bd459c,f5913edc,ff303fa6,dceb3412,f8e39c2,7d1df179,13186dc0,d7957f61,a3232180,21a6b50f,61a86f33,72623f5f,d3dc1a11) +,S(163fff8b,cece557b,6fd77b4d,e22e5b55,a6ed51a7,76dfe2b1,362040bc,9e7e4fe0,29204f73,5bc6428,3c510e0e,2192299a,7f6ed56d,1a0cc569,aa37f895,c0c4646a) +,S(fdbfcee1,69aa6724,b5839a55,e1c54856,86503b51,d1320b37,dcd9af73,2bfc4497,d7f75ba3,7af2f969,31bfa612,446c6807,a207af9a,17269199,77b0d71b,16b11a0e) +,S(f1981a9,aa585d6d,102b3a7d,e3509e0f,ed002866,b379b4e2,ba9d175e,4e5879ee,bad6366b,71a7cd67,163b6313,3dcd442d,24f9362e,5d0b9791,2a8dbfb5,74517e1a) +,S(dd3de17f,1cffd240,424096cf,effcaeee,87bf4d30,4a41d5db,6953102e,4b91853d,d136d363,1b9b968b,7c7d1a16,b2302e7a,7770e5ce,afae92a3,8f6e1299,6fb04718) +,S(b1d95fc1,4e35f77f,7e64f62a,36b26218,86397228,35ccadb8,39fa7d7b,834bdae3,75611c0a,920e0251,345b3213,422959c5,ac66c495,14d50c35,de7aa7ff,2a330a6d) +,S(1eeb92e6,75f25a35,9ed16c8b,51a5c130,d2210c35,ce954430,ea2cb3a3,af69187,cdefc1ac,40fac4de,e42ba496,eae80bc7,680e214,4117e6da,c2b3bc12,ce9eec45) +,S(aeef491a,fabae168,9d58c2f3,808b22fd,760e8607,c043c10b,591ed211,6fbb5ce9,b0db916,30810159,7e79aa7,82d8b643,d739bda2,c45ee36c,4f328108,4e55a33c) +,S(c56793cf,822c3da5,300c6c2d,cf06b5ef,413d51af,633ec77b,b9b68b1d,d3079e43,a423e25e,1eb466da,f521c5d1,6395805f,a2da609,fcfcffc1,2728add5,61eb2c0c) +,S(2aa824c3,c8c648eb,8bd0c151,b30452aa,c097bc38,a9f53db5,a8375631,25887e06,20aa4bfa,3bb2c5c2,a113299f,6c61102c,7586deaa,938a33f8,4a517dc,4ba78ada) +,S(4a0bb8dc,1833942d,9ae3428,ed493cb9,5716b50e,c96db120,c18ccac4,f6c3dd9,d0526d5d,c8be139f,53427e50,17cedc51,6b4960ac,bb98d4a4,f07fdf26,640b78b) +,S(2808616a,309b64c1,5d061adf,ae65711a,a561f8b8,345132e1,5b18fdb0,e476240,d2190f22,7320a55e,ad2dc736,671db631,9b18d6cc,b4d2bffc,cb4b692f,74eeaa0c) +,S(3dc4b015,13a95221,32ef431d,33435ba,8cf9e6d7,7e4ac75e,54848916,c23e7959,eaa2516b,9b13bc99,1f4b8ba,fa90a6dc,a007fea4,e26fbe0b,a2c5d1da,326d5420) +,S(473f6157,50af1d8,839ee0d0,eb5dfb8a,c14ce65a,e04e5f03,99fe8666,bd6efe6a,18d204d9,1b27527c,50823d5,222c4e4c,e3e193e5,a282daf2,75d2b43c,ffba8412) +,S(3b87175a,db1a5e49,1cf7565a,28250c51,9fff906b,ef0eecb,e8e50a7d,a190aaaf,fc58f2dd,16f1a5cf,1a728117,dcac3dbf,3a3963f,3859a518,2616b65b,59e96403) +,S(12f1b577,1410d1be,d0c4863,360e37d9,d36643d8,e0cf6fe7,8770478f,504174fa,be29140e,6b5a40a1,40559972,7e0727f8,ca904c3b,813897d2,bea089d9,dc2f17bf) +,S(8658f35b,902afb85,408280f2,3b4d98db,9526b57a,1e6cd0e9,37d8c629,ae174a3c,4060349d,47a69720,7d29e83,d8c82197,d32bb9ae,8c83879,1e09a7b7,1c3e7c28) +,S(530545eb,526d9657,2ce6cfc0,22e1c0a7,b9965c7c,3c2db355,cb5d414a,6c1ac8c7,99243b26,17f8ae2,898b96b4,1c3c65f9,96a9f8f5,83ff341c,671a2d5f,2d04637a) +,S(2e808732,bbab8507,e65936f3,fd1d1662,91ada8c4,c0d865ff,849e0a1a,5f08d265,96dbf7c9,53fd2f61,7e149f06,89b66431,88b091d5,1227a1a6,a0ebb140,18a79fdb) +,S(4272e028,b4b9c90c,44526fe6,b25f5e84,4b8baba6,34ceb2e2,33447413,cd5bb35a,6b4a4076,fc3706a7,50b0c824,93f5e363,f9fcdb64,9d683a1f,fc3bc2af,fc8470cc) +,S(78712f3,449d07ac,7f8171d5,42ee8b40,4761e054,eb0362c8,3b30cd52,6f9ac60,c7ff5ae1,38ca3c13,79457619,dd76061b,7b59778,79db2ca1,5b07ea47,7aa41bf7) +,S(be40166a,60ad9af2,d1bdfc7d,9b0660c1,640d4f1b,640ce485,8fb22eda,65d15a21,78c49afc,1d992bdc,b70bab6d,d3619305,a32fe90a,2f2b1b43,38d77c80,b208cf90) +,S(2fd5831e,6bd5a79b,35bc75f,92e83e4c,9acff5cf,61eaad7e,dacb149f,46d5e6ba,82f38222,4b6be0f2,f52318eb,7fe44a4c,4c0c1b05,8eae3f99,dbdea80f,a70ca3d0) +,S(32fc3fb,4574a651,472e0328,c15a71e3,bf9a12ca,15d341f1,c5102dab,2ee6de37,7e9398a6,760df809,e5eb57df,8fdc3234,eff1aa8,bef57008,c36e7953,c07f25a9) +,S(b9018d98,3452e952,7944f2fb,3354487d,a82f8b90,e52689d4,edb2a91a,a8faa6bf,e9cd0e4e,5c5efcbf,9ca25cf9,f271f9c,a2c46b4a,322cc966,e7789607,324348f8) +,S(a74ba662,32afb3e7,d5c22ad1,c792da33,f1bc88dc,244a8ce5,d4d582bb,b16ced23,444c5512,b49c2c63,4cc0328d,20f7321,a88db1ee,6d525be3,5d2de8df,cc381377) +,S(40f6df83,6d5e8c94,332174e2,2fa43556,d06f48a8,f52cfd69,820c2c46,2185dbfa,852c5b98,15ba4ef0,18f5d231,195fb62d,afafc08d,fbf9159a,eb5f6063,ca353424) +,S(e05800f5,f7890a14,6bbbabb1,27924cc2,e33e3c81,eb88606c,6bca020f,1aa71747,ab905ec6,3af1bc11,897a44e,89c2c2a8,3fb7255,c0e7f76e,8378e59f,1289158f) +,S(7b75dff9,a1afde87,be8528f7,9df63d70,e4df925b,a15f01c5,8e8162f0,89ee735e,bc057ff8,bdc9e37f,554a6ad2,3ebfeb2e,5d64adb7,69fa0082,2b2d4902,ca82712e) +,S(2fb81423,3b01e312,7ceabacd,a9ca518e,b1ab993c,bff855a5,20a96f52,afa9a0cf,a7e4bc57,b53affba,9e2cd875,9665cd9,215fcc,35dfc402,4d1db86b,9605c4b7) +,S(f346a33a,ec17d0e6,a10262f2,fd8185eb,f80a1fbb,f6b06bdd,1c04f18d,75dbaaeb,c09caf81,120586fc,33a6a0bc,97ef5cc7,56d20806,1340a1cc,ba9955ff,4a059e10) +,S(d128544f,a5f5dd38,62a759b8,5d538baa,63d112e2,f8c343a1,1bb3b8bb,ebf548d8,7893faee,b73f0530,bb67e8e0,9c2806d7,e303dd5e,116bc9e5,93e4dcdb,eac031f8) +,S(69046ec4,11c06822,59de20b1,a2a8f84c,58c56765,2ddcae,a26f533a,9c706f43,c17a9640,adc07d61,4a264ffe,272cd686,99b9af9f,6890cdc9,ac02c761,637dda8a) +,S(7b50f61a,9dd7b9ef,7af49c17,6ca5555f,eadf3b67,90998365,29379dd2,a3c85b5b,c08e18cc,bea8a970,7bc34d98,6b36475e,e2e24695,2304df65,bbe0347b,6052416) +,S(794a9728,9db4743e,c91a8560,e430b14,a7d8312,1fbacfbd,ec37a9bd,c749d3f,c57a5b9a,f0cb23a3,5e9b092f,386cda86,bf2f8242,1f74dfa1,837047c3,ae0d2235) +,S(fd8d1485,3d2fa064,c4682ee1,1c319a8a,49fa9b23,2cde9d1a,9a44b2dc,93b2f251,8cc4001d,f0121ce0,ad2119d1,7aaba363,ec45345,87fa10b0,c94a5043,f641b91c) +,S(7b5fbad,8105fe06,6962a72e,39a9a4fb,fac27794,e39a6660,133b9ef4,a6877557,b9b4c9c,1200d879,6013de67,958176c6,dc04ef69,b1021057,de8d3b40,564fbcd3) +,S(2c7ffc8b,40eda03e,20e64678,68959141,c66f01e8,b7cb050d,c60e8a48,6f6e41f9,cd0f3510,39aed3c1,56ae2b0d,1a117f78,c14a704c,992db297,60d22700,2f71ff7a) +,S(79533078,d81a6fe8,446dd750,b59ecdc3,8904f13b,48ca89a6,5644aa8c,9233de64,d7c95bff,77fa9894,74634aab,3b8f86e0,ee0bf92a,3a338fb7,f89881e6,e1fd746) +,S(be96c5e5,d3fb03a1,801a7760,16bf3824,aa16010e,884359b,d5e30658,5f13b214,d156346f,158d0c1a,2ef96a95,86cd8d34,20be21de,6997904,8299744,b40a5d9f) +,S(165c53d1,9ac89139,c063d934,511478aa,bc296cb9,7201dbca,fea4cac2,16a4fa02,4b002644,1e6f1369,d3603780,f33f74e8,42a812d8,b4e7ff7a,4aeea468,35f67348) +,S(508fb72e,dbd27f3c,76569185,a18af8bc,6242462e,cecffffb,3352ce3a,da5ccb5e,e1698f3e,1d53607b,4911423a,f2167466,a473a8f1,e2226849,f4dfe551,dfd14652) +,S(e9be0fb7,8e95dc1c,7b79f4eb,7976367,a85034ce,ea8642cb,19106dad,1d10ab92,b7867a7f,51f89779,a32a7b8e,273f9659,fb84367b,90ca3ff6,afc2cdac,7f596c45) +,S(e6ea5e6f,97116554,2de16c66,1f15d6e1,24aa449e,960b393a,e5337de1,d4c94800,bbd62bdd,1c235fea,60be143a,9155ffa8,204a1b11,3f19f4e,6e683c7d,e234ca7e) +,S(ab3f8a0,5b8f5ff4,149a390b,a858092c,9653d159,6d84bbc5,6e4a7a8b,fd54d7e8,41008916,311de07b,16c1b49,c6aa65ed,8baaebf,7a4e75b1,5aa1bc34,37483e53) +,S(515e02e9,52a347e7,5e0c5eed,a266242b,48bf33d0,70048562,c20feb3f,aecea1e3,797b3ef8,f6c35440,58517c56,ef5c6464,fcb63353,2bd6d2e2,83487a1d,8a403b36) +,S(520cf598,b3552fe0,a42438f8,55aefb81,3a3e10d3,f4985998,492e06a2,42ef46e1,c69de50e,2bf9658a,40567066,3cac0e4,8c8d2920,95ac1df9,9535b7e9,209324ed) +,S(26a8e655,4a2cf338,33bd27fb,d96880bc,bcc1d360,2a76920c,37075790,1c50bb1a,ba5a4560,5ddc5236,2a0d09df,3247a507,9c87e652,c4ad35f2,e19ecc9e,ec1ae4af) +,S(bd06a5a2,362ac91a,759dc578,dff3a3f8,102a67ae,a86ac11,5ddb2e14,bc1bba44,e8751dd7,153537ca,eec17988,98337cd2,abdfa554,52c597c8,61c364dd,78f49de7) +,S(ddbccf92,da0ab07a,e99fda1f,4a03927d,66b0bd21,f1e54fc5,afd4f329,35a0cae7,26fc18c1,52755bc5,d68dc3f2,461d60ee,b4dfc02e,a04b4779,6e7725b1,23acf8dd) +,S(650e1616,2a30c776,b54130c9,9fbbf567,32e2bdde,f667b09b,9b7f25ed,93c0737c,14972f76,429eb04c,1ebb0583,8c54fa0d,309fee09,a55d7eb3,700be0df,5801d56b) +,S(2920d280,41ad7365,cc0e33c8,7a3d6f3c,f9fec9c3,b00e5698,55ae3b83,8cf08973,3821fdd1,fe36668e,16f2cbd0,b2704fbc,24354f08,8ba19a1f,67d1b11a,b70c2d68) +,S(3842fb0f,1b26bfe7,535c9f5b,cee85ba5,6cd491dc,346829a2,a178ce65,c5294302,8e02342a,cb0e1233,9e638018,a125622c,5f66ab52,86a74a6c,28982c25,aa3a0fe2) +,S(9c21d89f,f1142d24,1e62c1df,e0481268,c2273d01,f153af5c,d31b3514,5b9b41ac,f5a924a1,d60e1eb3,72837535,4e252740,593c96f4,87328e9e,2a80cae,15fabdb) +,S(59320ba5,c9088701,f354a3a1,93391880,2829ce91,be9b4c14,c9018fe6,4fcd387a,610e48aa,705e2e7f,86a6a12a,817984a1,7bc60f9b,abc0ba9f,775f3446,8e3f3815) +,S(d800691f,83c2903b,1add209b,35d796e7,15b805a0,9bbe6120,3bf68a08,a13c46e5,21d194ed,bcb8bea0,cc35a9f2,328f1689,cdacc58a,73f65a28,56811e54,d96e5576) +,S(865588f8,66c21986,7b9643d8,7f1215fb,90fe186f,46478e8,522a5da6,724f6e8f,91a6b315,a7ddca8d,b4ecfbc3,9b55eb81,393f4c51,f573fef6,e7ca0c9f,cc551e7d) +,S(9dfe808f,cf7f574a,ddb251c0,4b053d00,8915f8fa,5a975479,d43c719a,b67aa4ad,4d40cc00,ea6720db,ff1f1339,7bb26c0b,281686a8,726fa430,bce0e4e4,ff01b01d) +,S(835f1c87,cf8d4420,72728601,ab6aef63,cd0d73a1,80f81f07,f5d57cc6,bab5ef7d,bac2d1d4,c8541f65,be0644c9,40a18f7f,d2c30360,2083a455,4d70a111,1c5bf07c) +,S(9562dc71,33c48e4,b46d73ac,d42db4c0,b0222c4d,dcd0e76e,b4f84969,348fa46,7cfe0965,96f691de,d358c00e,a292975d,465ef064,e9437556,40bc1d4a,33c3a0ba) +,S(21afe3b9,4237473c,dc032588,c4c1b7ec,853987a6,dcd1fce,2c48bbb6,8d0f3b45,1751c5ef,674cf88d,d5385943,b40a20a4,6d20cbd3,9876adc4,a4a4bba8,477e78a7) +,S(89809c4d,572cc5c1,2241ae09,fe1cee6f,71aaa292,c9ff8d6e,c3eb8a92,8e144ebe,462c023e,1710ed77,bd47d22e,e222598c,68cd7c56,b004369,a9356a47,ed6809d) +,S(b7c6164f,b9e175c1,5724c596,988b496a,b9f5b0d9,dd45d0e6,4a0f08cb,9000e3e9,1a13e8e5,a23b40a0,aba44bad,5cb4d37d,a6061157,aeab7a0d,d327242,ab2ad11f) +,S(62088450,24eef2d5,4fabe8f8,fabf519,72908ac3,23596378,c377c458,9719bba8,26216b3,a353295e,a1877547,b826c240,351f227e,293abcd2,e3967fed,30391f5a) +,S(dcfe82df,4049089,f3f8b275,120ca438,998fb22f,e11d40e0,9d09c4ce,c12ad036,388f9754,39b1c412,10014136,c3b58fe3,30ab524d,d7d3524b,37ce9133,5cb3bf3f) +,S(324ec5b0,12de7919,2f27f5ed,166344e1,934b3527,2b197d28,9a634044,5dd4bce1,99944794,579e12e8,c5c0c11f,a8eae5f1,88cb8cdb,3ce7814c,f89e3f1b,a3d3de0f) +,S(b3a70b0f,af96cb56,7dc4245,13ab7c6c,bbc38634,faa0c286,b81b9754,454a363f,b507745b,97843c90,170f8ffb,f731fee8,4532c1d0,6b2a077c,2aba5d94,189545ed) +,S(c4a6ff4e,cdf1ac83,29a1cdb7,b5165d88,2a1f1823,d1c38006,1b53144f,56187fce,6f7d0fc0,c08a7ba7,386f9a59,330996ef,b13d9d21,eb6d3915,4c8fb919,66159919) +,S(61d9ee96,1ef58634,5c4a73e3,a8c3df82,eac28aa2,6d740cbe,1833dcf6,d5a38811,c9e4a482,1700107,f2d4af3d,fcc74e68,8123b589,4da1c2bb,1fd926e7,11330892) +,S(67ecbd0f,4f4fe300,49390655,5289c9a5,cb6ac090,dff38502,75f7751,a84c6172,e422b1dd,10467cfe,921028f6,71cc75cd,2be5d8a6,75e644e5,d3c40b3a,2836726d) +,S(47f6c669,70898fa8,16dcd4d7,4553c644,2ce5bbe9,cda91324,ee3bba7a,868ff0f7,e56b9590,838bdfaa,1c2be1c3,95f775e,4a0b3982,d0eee531,26ec7ddc,9e3f77a6) +,S(e39ec9af,c8dccd35,4b155dd3,1d1750cb,ab096807,f89c8afc,fe61e6d2,e348cfa3,df3fca08,99158319,b93bac62,88c302f8,a59e175a,cda9fbf7,6f0ad59,8358088) +,S(2d1aae84,500037f9,8e08b64,341eab03,e0f1cdf,5a079b46,738746c2,18b3a0,747c23ac,8173adcc,de767d2e,ac156384,ddf40797,131a6167,c32486aa,12c89e5) +,S(ed1bbf04,d4570df5,8f584158,1fc47665,481ebf59,cb88322e,497d128a,678c2b4a,a40765c4,772da2d0,b3c8f107,22ec3931,ab3fc8cc,c28b003c,bea1a0da,279c8fba) +,S(bcbc3e1f,7bd268,93f377b2,eee4b76d,49a8a603,738de309,5353fde3,deff55f3,fb697a08,2f2570bd,1e9e4ec3,fc7f6c81,2a27a7e6,f7b8a53e,30da80ef,f59ef2cc) +,S(4f98b2d9,2f0b5d57,51ed3784,94cf4de5,65cf632e,982a270b,2746a5a6,3da9333d,43857e7e,437bdc02,6dcdbe68,d056784f,a2cc606d,7ce09a0e,12978a74,5b67e529) +,S(9dbb995d,d0667371,1731bf05,c8029035,2b413411,45318de8,2236df5c,87728582,c0a90e4c,6fbc0665,f8cd9fb6,fd59ea3e,f6ae9a16,9bfb71fc,5fe73e3a,4d665f86) +,S(83692208,1d099344,3d979c51,90940e44,5465624d,3a945c05,7885cd00,5ce6b9e,49be5e40,2e1d05e0,67b16279,855bc1de,6f0d8aad,35d8bc0e,142dbe87,33a14e13) +,S(f713e920,7a699b68,12d7ee9d,1475ba85,a6c56af2,8b73ace7,cf67ed6b,55650e97,a5a2c2a2,45012812,29fc71c8,103db717,48a51f88,61765d31,4b9ec278,3d0aab45) +,S(919f2d21,256ae682,fe514320,9c6551cc,d165de1b,8213fdbc,9c06578d,ef705725,9780da96,eeaac4e8,c96f3d6a,89c222cc,9b16b4c2,e8faad4d,96cc0136,a06021d3) +,S(1738093d,197a5ce3,cedd1fa7,e2a8ff03,959a6c23,6aedf9e8,9dbd74c4,d82b6e48,74363112,d16b829,d371a0c,f1b3bcd1,2000254e,196ea80c,a9d46570,1ee4a1d8) +,S(41242a81,35811b36,d4ffc40d,bbdeaa7c,cce36135,3c4fc9f2,d23191a4,b9c46379,7b894326,789f3071,374983c7,cd2a5ad7,e0ee49c5,e740dd33,817a31ed,97c388ba) +,S(894a6ec9,96eaa8e0,9e077b34,7b4f1e1,a387c930,a526c469,aaefc0c5,402d41a,a080fb43,c8e6bc6,388fa766,2398e096,b65032e8,26c5a9a8,47793924,4dcf5e41) +,S(a71f2131,3599cb7e,8c1058c9,52a5712e,661d01d5,79bc7ee5,1fbadd35,34ca5d5f,afe5b47b,663ebd7c,d788e0f,d3f963c9,ac63ee24,b7495e61,4a5d6553,9ab5f859) +,S(8f330e77,82eb62e4,4ea389f5,7f1c58b3,458c5d39,127d9783,6ddef8c1,27fa390,894e6142,bc359171,999489e1,1ed08224,4a46100,136fba84,e2b8732,e9bb626b) +,S(d2f0700d,6124c46f,a64cb709,1181cea9,34fe0406,21267334,c85ace2,cf05fc6f,8dc30ae9,83a95b74,2d800490,fbd8c290,bda64daf,f82d8fa5,e69243cb,43556cb4) +,S(c2478e89,8c075873,ba6cd5e9,6a730e1c,b6ade2f2,7fc9e7ec,93da9201,63f88c32,c6412063,9921d8c5,77dced53,76907410,82b1b4ff,4434bd,9a55b6c,8591ed5c) +,S(c5bc11a3,4e701898,d22e2920,2806c880,b24efa7a,c6d4ee36,cd440386,e4463a10,2c2b89fc,48feefc8,8bcb4ef5,68d16b44,cd7d8c7,485c9703,91c1c243,bf91003e) +,S(4b3930e8,21827b05,8c487bd2,fefa3458,6d0d3f20,5a2236fe,1b735d63,ac8c62b9,c38a29ad,c9b9941d,dc92a0db,4ce5f312,252c1f66,8a3189c5,595a371,19321c6c) +,S(fc646e3c,eab5a96a,1785da2b,1b50f7db,f0515091,76ade1f5,b057d05f,3aa3b8fe,b2014537,dbf2637d,6f683fb1,6af00d5c,63d4ed59,cdbdd673,f3bfbd48,e9574dd5) +,S(c0ada793,e2d9ed24,8ce307da,a6bebffd,3df2fc27,d2001dd4,5dbfc7be,c5f97a0c,6f3a787e,d40f073b,4965d52c,40700f66,da93f679,9efceafb,4894788f,5c9c7fd7) +,S(b1a45f3d,f2d45a,e21e43af,31ec3159,e8877d91,3efea814,b66f6fa4,a227b157,d988122a,eab167b9,f89db9e2,dd82405b,404f8a9c,a9acfd29,81c8bfa4,273ed248) +,S(4e19b9e2,ad3e421f,1b85a174,89d8841f,65672fad,9a17ad70,ca4fcd12,716d7a68,51412d39,59b158c1,3905c267,f5cf66e2,364aeb8,b66a11fd,ea6f5471,35db6dcd) +,S(533ee2b1,379a6ddd,6e5b3a2a,3a197e7d,eece722d,5c5b9c66,5e1be9dc,f3c09adc,b91b7477,fd0eabdd,bdc4047a,9bcad0cd,9da8496e,bd328fa3,a3ab20a6,3508a6d9) +,S(ccdb933a,816ac55e,c8fb97e1,504fa512,67408fd3,77aeeaf9,565ab66c,a2033b94,20299202,99b57beb,5d3817f5,26aae569,b490b24c,d5834dbe,8b05e8bc,89110de4) +,S(770d7c72,2e9964d6,84dead28,328b1925,287184b4,6e3abbdc,534eb87a,e0ea5873,363c73a7,bbb9b2af,3c0cc91,6f8ffe74,837a99c8,58b5464c,9f253764,e4a78285) +,S(d440dafd,b1d0609f,7c2354d5,74e711cf,852b364,8827fd41,88228ca5,98f71eeb,57d438de,c1aa78b7,c872cae5,c6803a2c,9844809c,7bca1a54,1be6f779,893aae1c) +,S(1602ca76,35ee0795,4fed3cea,d3e54470,41033887,2f060e19,990f3cd3,501b951e,1ea7f857,4b72d3e2,bd45fe36,c828f18a,5810812f,ab6e0936,a7854ed7,c7e32bd6) +,S(9c4d2a24,e4ad8226,bccab8ee,96960b1b,4722d2a1,88a429ad,f9d194ca,6687f7e,e3a4b46f,bf608018,ada2383,5c70fbe,cabbd446,78c9e5c1,35e91138,7d66b01b) +,S(fdf84be7,5be40fa8,db537848,e2fc8ba2,b7c58824,74fea4f4,6e8fcf15,f33d3bb1,2af57dd8,60ba0e6c,dc3606a9,a902420f,9283f721,70ce32d8,39c33673,5da1ff77) +,S(6083a785,fc5aedbf,34615139,e2f97964,ef65d254,a38251ba,203f8ea0,26eea81c,bb4d48bb,894fb656,22cd752f,6e3bc6e7,670a4bd2,64675035,8481561a,2c18439c) +,S(e03ad08e,5b4b9e01,5103e028,668f09a2,7d2f5254,25c6a985,6dfee667,6afffb82,f53acd57,1ab23ddb,d6b104b8,71d957c7,f254bc40,c37017ad,f7350e18,7a24865b) +,S(5a382a4c,88656b6c,4a5c8dcf,4052b1c0,a0bbc0a9,86289ab0,e212fd24,b852d9bc,912caa9a,32a10900,eadd0eec,423f710a,3e0aaba7,93f7b675,912223a2,6ba14f31) +,S(37dd526a,b5392b03,3bd05ff9,3952a31c,7bb0cfe1,f02f4f57,3b8d0ef0,c05d5ec0,7e329228,36595c82,14c8a776,15482931,98966225,4d4315c,c236c156,254e3249) +,S(ed4460f9,cd4bc957,aca653a0,5b6f0935,9dd7e19a,6d65c60,ca585ea3,ee2e1263,733af30e,6edd2b2b,317bba97,d24abd7e,41af6256,e7353f97,58357ff4,1a701829) +,S(eb01d9cd,50ff4778,b29e5096,93388ee1,12cfbc35,2c1b1382,7b3195e7,44a3bc3a,24877b7,99b7a2c9,db23047a,3194e9cb,91e5dd50,d0f1e252,b6f3bfca,f5b4d110) +,S(9fcfa274,b180ce82,14624545,22bb9289,1e0a8fc9,71949bfe,7aa25cde,88dc284e,6787be0a,12a76a23,9de45596,2a11f7f4,4051fbbe,3ba7dfb3,996c60ee,97be2b9) +,S(c8a0d869,87a7a854,99bd5663,30a07d67,70265d8e,cd3286ce,c9be4d02,6145bff,a65c64e4,af865e6a,893e902b,b06c43d6,10bb8181,134a4b71,d136b5fd,f42982a8) +,S(374294c5,932d3f74,a6e74731,6c6a84ca,dfda6d35,5edd914b,70b26161,50628735,ac47d048,8433754e,3deb79c6,7056d828,14d73bdd,703b299a,ca910180,e518672f) +,S(baa9e3a6,2b4bf099,1fde27ad,4b043b50,76a184cb,4f9a6da9,9b56ecd8,a2ab99e5,1e8e836f,f76043c2,c187ee45,7138cf3a,270e2d3f,5bc96979,c12c34cf,9205c63d) +,S(72f85ea,784a5ef1,71516c22,13abca1e,8017db34,4e00b397,4cb509de,a124654d,c78ec627,6cbc5072,fd75b28c,8d395f13,e84731f,7767448d,e06c0ba7,372968bf) +,S(c9173d63,bf5a1301,f0750b1d,e3cb7061,bb9cdd36,296b422e,d23513d1,10b61903,d26a6a0a,ceef78eb,73c6b031,a5455d2c,2a9c4ab2,d916b7cc,7b8e627d,6d581c56) +,S(865ff86a,58fb9853,8bcfe496,26c0bb89,e419083d,f21dbf6a,7b13e041,d5cd3f18,f0bdbabb,8118de57,bce9a90c,83529ec8,abfc2812,ab0088d2,8ade4bde,fe2fa383) +,S(3f14eb28,fd9852c9,bf4d4497,4d794ef1,c30f7748,5c7bb766,6f32fcb5,5ad910ad,e982971b,ec014b05,a9b5657c,a0bf45b7,adfe19d,22726075,80b42eeb,f4dc5217) +,S(61dfae27,c7bb68a1,ede331c,6499a7ed,e242457a,77e5a606,cea82e9f,f450d01,973739f2,c1e4ff77,cae3cf59,b481e730,5ebe8196,c5b62b9d,a96ae224,9b83efa7) +,S(e319690b,e944c297,f7c1bc1f,462ac3b5,a74fb913,9b963384,ac11046f,4343883a,3dadda66,538ea9c8,8fa0c02f,208ede8a,b6ef3480,82af4a32,2ddb5fa7,96d2efeb) +,S(f3db5e84,a9015b39,1617fea6,58143553,baa1975a,ab017012,38dc4243,7d9eaf9b,df55628b,c50cb2b1,be2ef193,a7f90e6a,3bfef4ac,63aaeee7,39907906,547d8b62) +,S(83a7dcd,58742725,8d17657c,ec64b5ed,4807db49,911296e7,10cf349d,c4fc709f,e5201a27,c37cca5f,2f7bf74a,fe000c0f,56643a5b,bafe9f91,de181e74,1d327183) +,S(b95b2363,28f51c80,b376dd90,a0f92d08,1e395132,deaa8f42,c142f642,3d3611ee,c111a08c,a6dbccad,2e784498,22816422,f2200f6b,bb24842a,f96c9502,13479f55) +,S(c3ff0645,921f2b9b,2fe590de,dfbac094,8475bdfc,a6446177,6422cca5,6fb549e6,e07ecccb,4b972834,e2711423,c0fba72f,eb0bb7c0,71a9e206,bf7715f2,62f03e04) +,S(96a37acc,527ee163,51c46241,1df94da3,eb0229b8,6a6e34d0,234bdcb0,5313c10a,46014617,fdd3f8b3,a67269d5,20a49680,9e5fa57e,76da4ef3,59ef862a,c58380c) +,S(b135c091,ec98a07d,b624fe48,4d336b85,62facf81,50346e2d,d0be2cfd,618d1e0e,24456a71,e8f2cc29,19f53594,6d7aaa79,e3d7dcfb,4af2feb5,ea0a2ad3,a23ec070) +,S(71d26219,81730b69,b0411b1c,f553c81,6f35a34,e09d086c,4500ba,94812017,c25357f,8915a2c4,98fe0d60,ca979ecd,8bd7ded3,ad6bc9ad,262db1d2,c3d3e7be) +,S(363cae8,ab2259ee,80283084,d98dc16,60c0934,68e3e854,dd86d9a0,d5e97884,756c60f7,c5e113d8,6e92df38,8fc9a1a2,a4889d86,f7440429,7661365a,ccfd8ce8) +,S(aef32d83,81ba3804,6e5b3305,6764ce3a,726c4e5a,ea61a17,ac114599,63f36247,dea5fc8b,d4ceba19,89640462,a957a8a7,44ca42d6,901716a,734e6f87,9aadb81e) +,S(65980f89,e4d0e342,d4b4fcf5,228692c0,9ebfed11,52d951c7,80963e6f,8c81313e,2d594cdd,a1f0b9db,7b3d8815,f7402a06,acba8e31,b9b0c597,8d2118a2,5dffa75d) +,S(f979280d,7e35cce4,8b9372cd,f73cebe3,6ee08388,e98e6069,fbeeb168,52329433,9181e8aa,bf7d4723,4cb851d5,6b3ca08,8c5f31eb,6b1b8c7,2879cfba,bd3ecaac) +,S(3b9f877e,286a13c8,a8463db3,b306ad62,c152065c,6708bbd5,68931e8a,2deb537f,12436d2a,5269a319,4f605dc1,4a34fcb0,445be9f4,5cc2bdc1,b96d86e8,b9465631) +,S(f2c70f82,1f86e94d,426e3e3c,e31ee519,f5a95b6f,38b663ae,9a6aba4e,f7bdc4e5,dc534655,4ba850bc,fef2485d,51e08c3,ab546119,49fee2ee,4dfc4e09,ff203b44) +,S(e2fb481,da8a356a,ab82098a,f622db2d,6f0a4349,2428dbac,922c1350,65801f15,5f735bb5,bb805980,d85ae242,4855bb2d,5de0c1f5,5018e1a8,e65bc2f4,86b7742d) +,S(d99e2001,33cf632a,f66c382e,d8ef862a,17092764,2c8f1f40,bd3d7bb,f0070324,d00f12db,cdb6e1ed,d190a754,fcbefdec,ee459be4,d5a46d69,afd6cbf8,4a4d30f2) +,S(dd765b6b,cb2dd356,f5965a8d,38108610,688fedc,eb3ce48d,352b095b,aa0daa,636258b3,58171669,f0dc68bd,3dff2a6d,bea6e5ef,20060913,66b12082,e2d7fa0) +,S(f549c14,f099a957,6267ad6c,3adc985b,9d0626b7,3f1f5849,d64ceb1e,266a9965,45a17dc8,30118c3d,28e73a3c,3d026afc,29ecf50d,198afdab,dff3d130,8f32f3d3) +,S(20d80860,90a192a8,51eddb84,f79b2882,ad7ce8a0,9374b365,61e6da34,427e8226,b48b6947,9febc104,880aa8b4,17344206,b19dd720,e5392bac,7e1954d4,a341eec1) +,S(b9f383ff,2545078a,c22cf9cb,83fc9e00,e9d37f30,e03ae03,5694437d,c1de2d7f,14f8b209,d1128a44,20dfb93d,3dc9ccb6,7ed22dd8,ecf5a181,2cd687dd,64a2996b) +,S(2ba0e5b,cec7a4f0,c6edd1c8,2d2f5927,2d97f4dc,3ecf353,8d3854aa,8d6f9739,8b10b217,6e56e5e6,5b99a617,eb71da00,3bee99af,b80e5ef7,3ca8c332,5ca7a75f) +,S(28b45a0f,3c308ecd,c0f7beca,c62d42b,500b704a,9af39931,b8debae8,8cef27e,9a3f95d,a17888ac,19eb4e42,1279c400,a60a0c1f,70a11696,4cf6943,9fc858d8) +,S(d8993bb9,e73af10,26ab41f0,9ec5adf7,437ce08a,4295cccb,283657f0,7a9ca3a5,ad8930d7,817534b1,e8407db9,bb8a608f,538b2bc6,9827a234,743382b,4381ddbd) +,S(77cd88a1,76bfed38,d7dd7152,32e2554a,a644b79,64a85f86,dbd6ffc6,69714e82,4394630a,42436802,1d0a0681,87fcc6a4,dfee0fe3,6db3bf2f,dac6fc58,34faccf5) +,S(d2557185,9c0fd15f,1f3666d3,aba99e38,89419099,ce7be94a,81ca1045,158f2da,90e94d6e,ac00b9d9,19832505,75bb2f,3242e7fb,fb429dc2,a90e3231,d1316cf0) +,S(f4e26c7d,4ccd80e2,7620917a,fdc72ca,94178f54,547eb330,77baa95c,d92a981e,c8ff014d,a388dcc4,c634304b,5973b274,785927e6,190c5557,773b9a0b,ef7d7005) +,S(da3a12a9,50dcd18d,c9e531e9,86f85a53,e7ce5bb8,8f2b5869,9830c44d,8c14cba2,7380a5b8,c01209e9,a1face4d,798f63ad,519a67fe,6bc90511,c763ca19,7e8c6b41) +,S(3565fae0,daf5d9ef,609bede3,6e19417a,45d8c0d2,59163f71,b4d9f54,43756fcc,7b1ef713,a88f9965,be7e6799,4a936960,c44f67ae,d5fa798d,8c0286af,e9da257c) +,S(6683fb20,d435a139,bd08c35f,adcc8aa5,8fbb8f48,7f9576d1,6f41d086,3a4e3de6,6a969f08,566afbc,dc98abfc,9d0d4d54,5076ebaf,efc9b966,957f1dd0,af52209f) +,S(900de92c,cbd4528f,57a72013,77dc1b51,7af67416,1013a20b,30d356bf,e011f508,cb55db4c,8799575d,9dea64f6,9fdf081d,959210eb,32b26bee,b903bf0b,80264c60) +,S(9d84bcf8,1be8a9f5,df2c6e80,d1b5679e,476e39c5,c30351ef,dc6b0b41,61c17613,8aa0cee8,cbc22e60,b71d9066,3533c2cc,a02b8d7f,7df93ce9,897154c6,2fae046d) +,S(6280fba,a3c3c8e4,4fcf0f55,a783eea5,2ebda748,501730de,71781be,abadd211,45b74c18,f0c18d3b,76cc1089,8741246b,202fd272,cdd0e866,5e1f4d86,ee527f5a) +,S(a4237add,7a5ea66e,8a1b48cd,7d5ef195,d90f25e5,6f2f148c,6d4eeff1,805b9024,d512d16e,632bd9ce,6cb1b2d4,c9a41e36,f9a2b83e,73fc8631,1e4dfa1b,b3bf71af) +,S(51effda3,e84027a,47afb48e,dc5c1937,9a685a24,ded2998c,c2b74422,b1e83fe0,346a9d82,cc07ed91,d785c6f0,dc32b62,e3e7877a,892007cf,c015444e,46001f19) +,S(87ac6bee,837ce155,29c005a1,6eca4540,de1480b6,91bc0ed8,90fed51c,de923cf4,9a9aa52f,1be1a33b,7280d0a7,3c19f5c5,b6baf99d,3c9c2d54,4a8d9bf3,a25ceb71) +,S(c8fd7df6,a3b0c0e2,5a931146,72a0af1a,1f995f1a,109e6e83,10b0d433,5dc2666a,3a853149,9b28c2ee,b5baf17d,dba8f57,3cf6e269,f4f21b1e,72bf38c7,79d239c4) +,S(890f9eed,47126c8a,355658f9,296b1845,b142eb17,4c2270d2,46293ba2,997e5a54,f294c38a,1c929ba4,2a9234d3,249690d,10a990cc,137bda3c,ada4b3,6d4e4b79) +,S(9329dbcf,45adc298,65c8defb,ee2ce008,a3474855,39826516,b417b9d3,bd47c86a,469a6cde,e1b0c094,f536fa91,f7617890,1be77c00,896efc5d,94cdd787,3886959f) +,S(6fa5326e,7b161c7c,742188d1,c47263a8,2f1f78e1,df83c664,2546c9ac,70660332,86cfd636,11879179,16d51a4,eac57709,5b8abab2,1024ce5d,35d64b4c,78559375) +,S(ece2e23b,8915d7fd,dab9e58e,8489b053,24eb1485,d18eff66,ee5013ac,3e0556aa,6a94e4cb,8fdf0549,a01621b4,438c2757,fe9753f5,13dcbb35,5655f9b2,ebaaea58) +,S(891b613f,413c155b,c2dedaf9,96d75e1b,54a5b5b0,3705808c,f575cdf,1f697ced,11904787,c1fb6f8f,8856aeb9,f7e05bae,f599b78,d7450bf9,13288e95,ff3f871f) +,S(b7bd8742,d1af6cb2,9b55a307,dd3c0318,6923be55,78ba2797,e38a7154,8d6231c,269e9a33,7a9421b4,cf45938,1961b0a4,3e4a0f6d,f6a0f10,2d7a831a,d7d4cd3f) +,S(7c6f5db3,1620a83f,b4388d45,75d244ca,1f38a0d8,611300b5,d4fdc9c4,34a16432,d5c0c35b,e4a371b0,3b85214e,f5e472de,e6c8175a,b140f05f,6e52b766,aa313f7a) +,S(18d303bb,d2bd6f9b,7f941879,6a23fbea,5ece2078,982064a5,e040c95f,c534ad3b,76eaa3dd,b73af546,7b1862c5,7b4385a0,28b03b7c,66729fce,94885373,1ed2dccc) +,S(31c0daf3,31aa6248,de302243,a768aac0,c8e27da2,c2b8e0a8,7fd74214,b49bb78b,e8e1f975,b77550bc,d404631b,12c72d38,55d3bf5e,5477a588,b11d57e0,e71e1ebe) +,S(940aa62e,e3bff798,327e806,b644a972,fae9eb09,dffb8394,61b080b4,708f715d,2853e12d,56898ea6,8e922497,3660a29b,37ec41c7,339b8059,2075c7a,2836c1b5) +,S(66db37fe,3bcfd7bb,25ca4a1f,b2ee09df,5c748061,1c3a6fb5,d0f079dc,cdbf9b7a,a6d37fd5,5d58ee33,73898711,69794421,9cd7a2f3,3becc8fe,761bcf83,ce603b9a) +,S(fb04bfa,a93a8ed9,3d755351,98895c8f,e90d545f,8eb1d08d,5d7282bc,66026e3f,e77f3c9e,afa2791,b4db2f69,3438d051,47edc983,a8541296,a8cae9a2,174e03b5) +,S(5792afeb,7766365d,e6b36beb,aafde8a1,8e556ac4,207965d7,9e18c1ca,63465c78,95fa5ad4,4b93db96,2c26d740,d2aa582d,da19b761,480ecadc,212452ef,cd885b40) +,S(186c0feb,6298e341,a2440465,547ad137,c56593dd,ed82b608,6824097f,3f83f8eb,b3b58cce,8375d9a1,e63500d,141feec1,38778c46,4be1ad43,7c63256f,33ac3b6c) +,S(d39114b7,c22beefe,6796b6ae,3f740a39,9e3c98bb,58b647b3,5cb23ead,76eae678,1df690f,383db8a3,86284ff8,f914925d,c688aa2a,8ec01a2a,243eb309,e79aa071) +,S(6195550f,8ce49ce2,f762011b,2e8feaca,509a0628,eaa93151,4c779616,721b39b3,ee8208f1,6d86fdbb,c75c265e,88090c85,aec112be,a1d803e1,211151d6,cfbeee2c) +,S(a8429368,37b33a8,2d41a26d,e11a0fd8,7af231bf,30d3eb64,73aa064e,acfd8740,18524c63,c0cf7a0a,b4e0eddd,61717f6c,3221a8f6,3522d35d,4eccee30,b6ed82c9) +,S(bf42ae9e,a64351a6,eb1d2c64,57d23481,f913de5a,d3c00359,5eb8cb5b,228fb202,2d74804a,34413cef,8d2cb488,ea780cf5,15faabd2,36a9db67,91549577,70a09d3) +,S(f1bdfcaa,ba133809,f915e0af,1a08fcbb,dd9cb3d8,b62f545d,6b71b44b,b130daa2,51fba8b2,2c7935ed,4241a87,f19c2b76,bc1a288e,3e53855d,c532f0b8,1ee382c9) +,S(7bf32637,4c6adf01,c7796f59,a11e5c3d,103e3339,a0cfbdc2,dec57f5e,69429bcd,8926e57c,a1fe7442,72d2e89,d037feff,df263831,e40e9ac4,8473336a,269f6b44) +,S(95b652a7,7f58b0d3,4c6d25e1,c294907f,a22a3ee0,f8e8478a,4e8458ef,37791c2f,e7dc4caf,b5bfdaa4,7185f0f3,a98876d,b50bfb35,a77a8b11,b522196,9f255845) +,S(d9f8c6ab,693f8058,8c73e2a,9221b0c4,c8f1d1bb,5e1e58e1,8468a48b,c74f50e1,cb38d48a,89c1ecc0,23e0e248,e1991ac4,3fbddf5a,9beeb53b,4cd9c49d,41f42a9e) +,S(43f62528,287e50,5cbf1a68,18bd99c,9f307e95,84e0d73a,f9fefeb5,b6dff92b,85fbb4ea,b81a0409,ce43ca05,3dfd5a1,9756fb5,f4b964bd,dc409efe,696c2ace) +,S(425a68ad,6d20661c,ca7d688,6bb9c66,f37dbf29,30ccc6da,dc34025a,5ea7a92b,7853cbea,d7816579,fa98ab94,875ebd2e,7ceebf73,20b50b2f,7e67f0f6,dfd2eeee) +,S(929ea74f,9b75c327,a7b26127,8828feca,821e4d8f,c5e308da,f3169a2,bf84bc2,f19e6cfe,d8c966da,bb070d42,3c62289a,5193146e,4297fa35,5908663a,a36b0578) +,S(83da36be,b1bedbd9,4a4ee417,f9faae5c,c20a9763,2c1ab2c8,b997f23c,f6d35c31,a91def1d,7871aa84,eed0bce6,12bf6a82,98d0ebb7,536d8e49,f6757a48,aa7a86ea) +,S(a2e1da8b,4318fad3,52c8c285,46f0a8d7,8fd6cf6a,b506f8ac,2d6746c6,75f2d5b3,584489cc,58b08663,1cdd1b7,3e61cac3,52c16814,493b611e,ffb94a71,2cd85699) +,S(5d7c1af4,4b257440,22b82ca2,9923a180,bb7fc209,1990b111,12061b6e,9eec4d2b,b40ca0f6,a974223,3a7b0253,9f0dbefa,1bf23dfc,cd59c747,c290f525,2e960b02) +,S(e2831933,6cce89c9,993bf230,ae4311ed,48fb0913,b5f35da2,b7531418,b512a75b,660aa9d9,8bfea898,810107e1,711abff0,88881efa,4d9d586d,91381b11,67cc2a21) +,S(722c1e28,498d3c21,66fb0f1b,f44e3ba6,181a962,75efeed6,ac83b36c,12426031,27a135d2,3b70006b,480c3aa3,bd057bfa,200da08f,f9eff741,6bff7885,4a1795be) +,S(f3cd71bd,f93f2100,c534d788,ba607845,cf6049e3,b94f5274,84e8608d,7adb9c99,b8e86285,db09b729,dd789293,7cf5fdc,989e00f4,5dcd4916,a6860bf8,d77cecfe) +,S(36341496,d986b096,5e5ad593,de6f88,67aa6130,889714a3,dc0d58b7,19647318,8cbeb984,a3f4bb5d,75cf77ce,14368b9b,77dfeeeb,7313f16a,8a573953,c7b898a2) +,S(a48443b4,3783c58d,4b7b2f27,17efafc5,e5ffe24c,a7c26bbc,dcbf93,538fbdea,33bd2bf6,9a64a742,c461fc0b,b0ae8770,9ed47a9a,26e7d05c,b71e4e2d,20c894a5) +,S(d4364d96,71f2876e,843dede5,9991ac5a,cf92268a,73212ab0,54b1c196,197dddfa,b30038a0,fd9f7387,fb37754e,9b050e80,e0f28596,d251d627,5149149e,880f6d43) +,S(ce277a60,19ac0b41,16b9d863,5a2555cf,30ef3408,f1a15769,91e48d0f,9465d250,5260ee90,65c89bc,7ef55fa3,d5f5d7ed,594fe592,322b7e97,965a9a3a,5654e710) +,S(587ecb1e,7c08da9d,75ed0249,b1281762,e9c71475,5c3ae35a,f7d66b53,c83117be,c6dda341,cb7d88b,b4a1b13e,313dcca6,1ec58063,376d38f2,cf142b56,87bafcb6) +,S(d87f96bc,69510c4f,19b84e93,cd8dd0b2,eee4fbb6,c5c5074f,ea76a209,e059f41d,a9b83947,b557c4b6,41952117,45ddff77,b5952798,66fb4095,6b5361a1,b463d326) +,S(af9f0d3a,78454c,eb8ca65,c9d7a324,312c01e9,dd8a00ad,e923f2f6,41fb0ead,2d3003ef,29a5ad10,20262c54,936411f0,f8082630,8506fcb1,e1848a7d,5d16482b) +,S(efd0467e,f4791ec9,9380be87,394225ac,637f906f,800abf9b,1ad5b3cd,cf9f017f,a14308d6,b0d16772,f36da4fd,d77945f7,1d82276c,ec4dddc0,de24f760,965c5725) +,S(e892235e,39ac312c,f30dfb97,97e88446,dc1f9a3,ef5cb8eb,d540c64f,d6b6129a,5b291ebe,7c055f52,b9fae6ff,cdcc6dbf,f84cad1e,4d35f495,4dc19b3d,64eb992) +,S(3158351a,542ff38b,12f82b5a,daa6ea3e,6e75caae,600b76a1,16ebe3f8,c9bcd66b,2006c258,a327481c,d324acda,b8ddc331,6a6aca81,44dba340,527babd6,4de975e2) +,S(f17bbac8,c0a7d2da,bbc5a5cd,4b28e96,4ab88639,546b2b22,d40c519d,25dd448d,14f9f488,e76663bc,278961f4,a33e11f6,98d6f5fc,1eaac638,79ccfae,1ab40991) +,S(9aa24eb3,44e010c2,d6fd3efd,fa03cfe6,aff67d25,2f08dda9,3d00332d,3065defb,494cc5bf,e60fff11,f42190dc,e607f067,7e355a9,52ccc682,6845111,322ac050) +,S(3f36168d,77711926,deb0f7ea,b6dad80b,8c755db8,e6705fa5,61285f96,84f1ccc5,486d57cd,b46d998a,5d064f9c,68511657,e53e544a,ee8c5521,87a1cd16,4121c6c2) +,S(fad18e89,219c449,87551525,6150e4a8,1fa2b23a,b6c1d90c,2e2f9152,ee8cd054,b285a7de,4eeff44b,751b4e51,f252f3a0,be7c2223,a715e301,23e9bcea,495ea7d4) +,S(1cb1cf55,9c56951f,58147d84,9482dba7,8dc6050e,2897f389,e30aa87c,519dadb6,b9e54a71,93a8e255,b2cf1fe1,80fe54e4,3e17470,60e9128d,bd527abd,c7ef1f97) +,S(74e68afc,9c8d9e0c,92675d9e,2fc12803,4ce7d22f,e31f5332,d18817a3,bd05efda,1d8442db,d55e8abd,aa1de803,f4fb1295,e9a8710a,3f25a242,7af9a5d0,b5dd786a) +,S(10336317,ec82d4e8,543dea2e,b8cb597d,3aec0e70,fb2971f8,7c5699aa,e4576de2,f2ccc066,5eae8645,54816dfe,c82e1162,226ab207,a17c6085,62925f5a,ffa3e021) +,S(b06a55cf,57668bef,6c51bb66,ac8ba7fc,6714c864,ca788279,2c8b759d,290342b3,7311f47e,5b526dbc,e4bc7833,e4c5b45a,190e3517,8f0f8137,2857e7b0,fb1f0528) +,S(af83a357,81306453,e576c819,d1cdacd2,689b0198,4f108d2b,6d9b8148,50df5523,14f52176,909c7e1b,eda13d20,7567f31e,161a80ac,112e4016,ad7c0bd6,20ec0ce7) +,S(f8f56d54,54faf536,3ea98913,827d57f2,a8983112,aa8809dc,594af919,3ae5c4a5,cc9d4182,bcb00a0d,cb73bfcf,da46ced0,ecee167d,fd7bbfc8,899063e8,d659dd7d) +,S(61aa26b7,415001ae,d6b3afd0,1c690177,879cac31,93a2e410,4148df74,733c4ea1,972510d3,697b93ad,60711b39,f3b3c237,771bfbc0,b7238e78,5a786707,dd179f23) +,S(781f196c,dde0f8e5,10ad45ad,6be062aa,1315c246,85d0ca97,21533c65,627ad492,6f3248fb,e7e61cad,1b01ec2c,fdb4dc4a,b1f4dc25,3666d4ae,27a88d50,c566d18b) +,S(c422d61,7f84ddc6,4483d55e,19228dcb,395f16fc,e85b5c93,2778f62f,ce8917bd,2f3cef48,deefbbe9,9477389b,be898cb3,90499b2a,615899bf,1e910e21,ed337652) +,S(c325955e,b56fe9a6,66555a32,72f637d7,3351b65,da5059f2,17748e68,4da4a4a8,3fa27721,2364140b,5b71526f,ad963d01,16889555,bdd42fda,c2b451c,fb70a3b4) +,S(e393cca1,49142f01,9be9a4a6,e8597354,e34f8d55,b400fa4e,8ac6b4c5,7e50b7a7,e40b69bb,44d6d1e5,22cc30f7,26b7a262,3e5b76e,7b190f07,10325a08,a99fb2ac) +,S(33e3686a,e4e69510,e939e53d,62fd669f,f1a39af5,c6179364,a190ae11,a600cbf1,cfe60b76,1306222e,7052b0f1,f799380,ed564d47,1f6418ac,dfb13d98,47f9154) +,S(1c35b5c8,3072f4d9,b3b294b7,69ff1b8a,ed2954cd,a013c7b3,34b53fec,c783b251,1c691a2e,782ff393,b0ac6c31,94f4cb0,f8dbd5f5,b51654a4,3914a458,6b855318) +,S(147255dd,3af5eb26,119e3d86,b2bed206,43579099,742c4ccd,974f7fb9,83e47fa6,5e0a0a01,7497235b,4766b44e,2fbe8902,aa0e2c2,69e7ceb1,d65c0f34,7a97f7f9) +,S(9524d71,57304a13,71d46aa,bc43986a,5ece70cb,ea008aa2,b8c97070,6436b237,a343af97,db30b94b,3d8d366f,1cd27b11,83c9f44a,75f0aa93,8c4932aa,52f6ea55) +,S(8502e7c6,e498d868,3816188,a99d0f35,79058887,dbeb3c03,676b3b91,be7481a0,28bda608,a9e18df9,c304896f,94efa7d2,46ee528a,6061afd0,322e052b,e7cfb68e) +,S(b89a0d8d,a21903a7,200b196e,46714aa5,ad49c5b0,8fc84de7,8e72ca76,2a3ad3b9,953bac1f,85e4f631,38464a99,e6e3be5c,328b3c10,7523701,c60aad8f,d57e6bee) +,S(49bf791d,67125d38,496d8ae6,ffcc25f8,97114f6f,9fcd5541,9876dca,4bdd7d7,6c2976ec,1b9078a9,a90f55eb,510b1a89,17efca39,d2fda494,b9013d07,7f4e05d8) +,S(c63bdf20,1ff5b07c,14273727,ff174322,422b6497,9ca8427f,5f868eb3,a1fcf05e,c4135e1f,1b5a09b5,d628674c,21ead97a,42957d31,92a44de9,b785986b,3269a782) +,S(58c8c84b,e9f85bd,b26f99b3,cde715b4,4b057d56,d5411c3e,a3000829,27ebe551,15de85b2,1467bee0,d4e0b0c5,114fdafd,410cf720,3ab35f1c,1eb2577e,fc2ec620) +,S(5fc5177f,e0b59e31,e4abef85,31f3fbaa,e3399bb4,126b6119,c7acac83,777cf9b8,adf27f69,b613fa62,3cff72eb,4dd10b4c,4009b73f,2cb885d9,57ab8c78,ca705fe9) +,S(1017a9b8,5116ce3a,498888e5,7a408f36,12a6e8b,b18f6961,d6e1d2e4,38902928,24f7a939,5e0d3c0a,579ae611,b733248a,640db7da,929edb24,b11bd617,3e573658) +,S(d9ea68f4,6af94d9d,232a5deb,c485fed0,d719cdf3,2afe4617,524958ed,751a2c47,e59f2193,db2fe578,642a774f,c4fc8515,f638d1c0,ae8081f,e9d3c0a0,fe20410e) +,S(61d975c7,e4d7e262,5b067179,667325c9,a32ef6de,a0bcbcb4,a825d89f,de6f7aea,b7a00d17,5a2d827d,37de6c8,667bebd9,da92ba42,4efeb706,54092342,e644db9f) +,S(2ff5cd3a,fefe0c25,bbb8245f,c9399409,83194bf8,f4599f3,101e9d79,b7f8d9bf,3c154b7,11964aee,5fe9175d,deacabe2,400350e5,3ea1ba23,20d9e675,5aac8fa9) +,S(cb438486,954c4a00,effd88db,29e0e61c,f9fef94,5b42bbca,8939e0a5,dad9e8a9,920ab096,41789957,6c3a8ab7,249ae2cc,73d1443f,5c650ad3,4da9d473,221de71e) +,S(9aaeefc2,889948cd,f59fa4ac,352204ab,46aa399a,c848041f,446be421,e0e4758d,8e4d2899,2ef8d6d7,3e1e118c,70729e7b,4e0bc28,69d7b5da,72df7b46,38fb3365) +,S(ace47cbf,846e95f2,9387dab7,6ed4e272,e32f6215,1e745738,69f2bfbc,720c78f0,a35997f8,37b8e86c,3b4377d9,71098d88,95d6a008,b9d65552,b1385a4b,49c53d3d) +,S(66610f69,1558942f,8285a9df,3081e431,5c946a5f,df958f03,b2ffde5b,c591850f,be93a2f6,53a8630a,ef037f8a,624e623,8f2ad9d7,3ff4624e,f4240cd8,d3495a98) +,S(db4bc8b3,7a12e950,706e148e,4f07df0d,a24d1de,615f2201,2dc1befe,f1ad95ca,fd55628c,c260a1a2,e56b95ee,ebd6b854,f548dfcf,2c4a6b99,7c4e95a0,a52c4894) +,S(a2a7aebf,58a9a58,24d5a996,da18958a,5fc23d8,452d13b2,b254d4fa,bcba959,d6440764,1642f25c,8b31a117,cd7ed90b,dcdc54f9,e652a818,bfa032cd,18bf085) +,S(2d8846f3,fa8a7a0d,408f8ad,bd76366f,4bf7bade,c255e2fe,595e4e22,cfe86684,2c0a7297,228185cd,3b21c10b,5c7f490c,b01bfe72,9513eb63,f2716d27,f0fbe19) +,S(27ba20c,a44821f,d6ebd41c,8c29e584,6237d8bd,13b3eedb,a82b5aaf,10a6fc59,68d65fe7,b511bde2,f922f119,4bb411a0,c000b4fd,268c2c86,e14279ae,9a63e42) +,S(c2f0b611,3a6bebe9,22ec3e97,a3962280,ab0b6713,76a6778e,5ceb73a7,e2894b13,27b90863,65989917,68a9635a,7f6c674e,71a433fa,ce4f1ec4,cd775277,89d290e8) +,S(8420787c,a0df74fc,5c81d19e,64f7ed56,8bc54a2c,ce1c5714,1706888d,bdf377f8,4a94b5e6,ad402877,dc4c0df,38c7fe41,d9e6e085,e70431e9,99c2b724,e35ae74) +,S(29d08c36,c45715f4,1eb5138f,a5c2f002,b4021f2b,bdc49592,e4242443,1f4d5f0a,903d61f7,2e81352f,582ce3b3,ead7b6f9,e0340c23,6925882a,cdb41285,6181bcab) +,S(ccabdbe,f68b6549,2158d4c8,91dd1d23,efa7a84a,a985252a,3a1e895d,757e5f10,94a0e915,2addabd3,d5adad5e,cbcb38ec,e1a045bb,9d7295a,92aee49c,a6f0bb4b) +,S(5bd30e4,9e2ba9a,745c6ebe,434b8d4f,1d8c34c7,6d478ffb,2871466f,a3ff23e4,1067b3c8,5980ea3a,dd1a4cba,8bb0b96f,ad988cc6,4dd8e206,51eee853,915226ae) +,S(eb233898,8f12eb2b,5369d9f1,56d754dc,8733745b,30967e17,697e69c4,4fa80493,c258bfa5,e993ff4a,4a9eb82f,ce1530ce,25fe74ec,2bbc2639,683464f8,a26b5667) +,S(4b44ca53,f01e1c64,8ff41a97,721e7c3,b0d62b4d,b15c5bd5,d84621c,4dee2ace,d8999254,b359a155,99e59761,f42639ad,27caf87f,ed4ddc57,203fef6c,9abbd922) +,S(ce5ef1f7,6cef6b65,35631e65,d4f47924,df370ac8,ce059a19,5455fb1e,b156f7a1,74c9b95a,a4dc212c,3e127bdd,266aa89c,a4773f27,5607dff1,4438647c,f0e50a60) +,S(563d7e99,40325aee,e66557d0,b14b7e8e,14f86643,de2b3300,1bcfa7f1,ef788bc4,ceebeb99,9878a305,1a8bd9df,bd6cb2f7,3ac18776,ea78df41,30fd22d1,bcdf37da) +,S(ff929868,fb5a1b53,6acca702,f5dc1e83,efe8cb96,f96a3303,d107c6ae,ab5dbee3,82828150,fe8fbb3c,f2bfe03a,3c79fa5e,67c33d97,b12faaaf,572b1455,6ae11969) +,S(1004e4ad,487212a5,8af57ea1,49e0edae,6aac884,2f488bc7,1b75a5bd,4a20204c,88d9a6,164cbc21,52d60ee2,7c8003b6,b39e418,b10c72d0,504a6a7,d7b8b2db) +,S(28dca143,206abca7,1c48137f,8bebd26e,6c79666d,ce164fdd,ef1ca7ac,8e141a25,ec1dea42,575e5cc0,804f6da3,21ee739b,ff244cb,2b299413,4b8539e3,88f7ccf7) +,S(cbb81690,a7e511bf,56a5190,b9366345,7b4fe8f9,64b8fb57,36df2067,28e1ca48,c2d2686a,5405dc79,d6a2deef,95a97813,4a434309,c5303985,f173015c,6571e5e) +,S(3e1e663e,378c44b9,b61d04ca,bfaf65fc,df6b59a2,ae83719,11b11582,978f008f,bbf4b3b8,2010fd76,70d23b07,6018708e,8f78d70a,b2da1efd,be668c9b,d5125d51) +,S(7f742a3b,9edf6aaf,cfbbf368,5a622318,1a6c3b5d,588b74de,c2d2c049,91d97784,238a4f6b,5cd25489,1b8aa5bb,41f253e6,6a59a020,bce98966,ed4c75f6,b7939e32) +,S(f073f95f,f6c809d0,9271eb48,abf35b2d,b760caa6,54b0969c,e327cff,f806f43b,6a7eb8ce,9e297e07,170e9287,7fc737cf,bf923cc1,e72efdbe,5b3b4920,6602746f) +,S(855f6451,5b98ef1,67d3a11a,fec74625,cf3801ab,75df42d2,1b33b1bc,c36d074b,6e8cb794,9990748b,f54a9291,e7ec374f,a31bef56,ed1812a7,7b2ef00,149938fd) +,S(f0164c7,f204384,d3235b4c,cc1bb9ed,bb10cabc,d69c02b5,aed1dfa9,56c74d49,872fc547,78580a6f,38792974,a64399b8,cd674622,659ec31a,91fea06e,77e27118) +,S(16e83238,e95e29f3,ebc297e7,fbbc77eb,53431f3,cc90f809,1e540457,aced09bf,3f3c0ff5,754630bf,88ec765c,a5c04da3,f6ca4ad5,e72d9c0,715cddeb,69c4f8b0) +,S(70d371c8,8b2e47a,47982dfc,bc98ffd8,324b6bcf,2f1aa2a8,f4815f66,dd4949bc,34cc039d,3c69b4d1,833375db,e7315340,bab2452b,2a82163b,dec73702,f4c8da46) +,S(db250b65,6848570b,5a59a2f2,d45e99d2,de1b3813,46fa6ce0,8bca0b34,57c27d10,2859a0e8,fde87061,d7ea8786,f5667aa8,b2633e8c,c52926cc,c5427d64,a7ae6494) +,S(d6ecb3fd,b1ef3350,a2a831e2,321cfe9b,6b22b38d,6a8fa0f,b256f2cd,ac73f949,ad83f35b,c1b5c568,49436cfe,6ff17f5e,8abc6891,e24f4a0c,524d88e0,6c3f1028) +,S(ee2059ff,a2c5bef0,646bf76d,ae2f3bfa,193b8a28,bc74cfbf,a96b48,921ac0d0,3a8f4693,15d6a6e2,2e57edb7,e5897039,153e0283,8d66b1ce,1814ac74,195379e7) +,S(6dd7fa4d,bc12da89,1669cf7f,b1024a8a,551d7281,83fd221a,7a0ca9a0,8c2aa725,67fe6a0d,fca0fc02,1fc89584,d2a5f19e,ce890708,490c79e3,cdbd43ad,ad24493e) +,S(15102e09,b966ca25,1a9b4609,16ca1229,7ab64d60,980582e5,e8bf0e4d,80fd6c35,7ebf61f9,956109c4,3cfb52ad,4e60078c,93ea653f,17c7328f,9120545c,48988be7) +,S(a0697816,4a0511f9,3a48efe1,de74992b,54679aaa,a99e328d,6771386,945e9039,92d24154,971add65,c40e6f32,a5b5fd01,765effb6,c8d64676,c9d97e8b,f857d630) +,S(ac925df1,3a9ce7db,18b9071f,f81880f7,c8ec97be,4b78a31b,27917d71,da0defce,6347aee9,abe9b2bb,1f1e3ab2,2792009e,ee009011,337fb184,d3f637f3,186acba6) +,S(74f3c7b4,e237db77,9229cb2f,1fdba8be,9ba990ed,6dd84976,ff92646e,55e21091,44e9a71e,a07e4254,c4dae620,9c437873,7c56187f,23f42224,3167e45,932055f2) +,S(78f0a024,f6a5bbaa,f3eaf550,92a55bae,73348e82,37dc095c,11ee34fc,3194eb00,54e9b6e7,2f758d54,23d5b9bd,b329262d,6745eb32,c93c2571,f86f40cd,1cfeeef9) +,S(83d3e538,92d722a4,8c006910,a22f32ad,2ff7bdec,d9bd2ea3,a2f315cb,550a1bc3,a4f3c8e1,732b23ae,9f21c03e,7c3711ff,687683c3,13455107,68278332,8d9a25d0) +,S(15deb2e3,f0f0b65,5edbb7d1,8d86cedd,7242a693,a271d853,b468d57a,52cbd647,7cb1ea70,8e12acb,6bbec5ac,26f513cf,51460493,9db6cccb,ba712561,a6f4a80) +,S(6fc5c841,eca2637b,67fcd5f1,3c3dbf40,3b00e4e5,270bccad,617c58af,ac54195,afc3fc7d,92f0f77c,5147ae41,8aae93d3,b5cb7785,d65e623a,391d6a06,1f82d4c4) +,S(154dad09,40e83686,d0942998,e220f8b6,bd106af7,beb9bc66,1f1a4c2e,29300f20,9a47095d,b2a357c7,16d8773f,18c953ff,dc0ed270,1cd881f,f3088176,e61bd7ed) +,S(a498ef6b,89b882d6,81ea0647,f83d53aa,d1fb39e6,6bba74bf,8008a43f,197b301a,cf4d289e,f723ad46,27edc96f,5315bc2c,9ad39c04,4e8e6785,222ca142,3f5c2881) +,S(5c01e4d2,465c3326,1828c45d,bbb2cf69,79cdb746,fb659a6b,44f0f2f1,f388fa3f,315dab9e,5e53f939,610e9729,3e686d33,e46f8262,5ddfb45d,46728b03,927a6837) +,S(d058f58b,255164fe,e6d60472,2b32624b,2eb523b,6c7f1e6a,7ce1c248,fb3fe505,21761abe,1bcb844,39645310,7a3dd2ee,28bb4dc9,93dcd0e9,a09d5176,1a7c6536) +,S(eb89dbf1,67c1352e,5ea2a7fb,206663b1,8c95d962,cec35412,3b9be6b3,51799ca1,9566074f,ec54174,a49a5f84,e4965174,408425f2,22d485ec,b020740c,74b08ef1) +,S(19ddc300,84dda580,db5b1230,b0fe9508,5575eb10,680181ff,ee0d521b,17b39cb8,6af18172,bfb03b77,db456836,b9617f05,bbcbcccf,f6ed2dd9,a9c6e734,c01d188f) +,S(66240aec,7e72f707,69560e0c,f31f2c41,9a8efab5,32f17f59,19bd56e2,93c41e13,16fad661,3600a79d,41eba5b2,d0721dca,afe94372,fe83b20f,7178e29a,e6f3949a) +,S(3c75905b,9e7c7751,9f4617ff,6010c39f,92b852fe,89dca73d,cb3f15b0,23f7a286,799ffb8,94fd4f3e,61dd489f,da746fdb,ae955eb1,3c8dd9eb,e4f73d41,2feccec1) +,S(9719a34,e765cca4,68ab3453,3c6dedd1,6247af51,b73295f6,8b936914,c03f10a,4d4e7f2d,ee3aec6f,71fa8978,f532e995,c0e1533c,5cf0b51d,f35d8f8,29cc10ec) +,S(e32f292e,e5c41e2d,bd262c45,eda0b729,713207c0,17fa5c47,c8bce6,ca550814,105716c5,5995ffa6,998f2209,b9d0b37e,f2bd78be,527f6c12,b707faf1,ef73a82c) +,S(76aa4115,595e7656,c76300d0,a60e3316,fd9c1b60,d41920a6,128e59f0,74a9dde5,f3ca0754,b6daef99,acd6e1e6,fb36d93d,e068c0d2,26b843a6,e7e111e9,9df8efda) +,S(215186c7,ba018fee,747c2030,f57d1105,945b021b,be053da,efb1136b,f0d6f0a9,62994ba3,62d9a8a0,7432690,689a859e,ef498860,3d52352b,e27e0f8f,d02e4de7) +,S(62e16f47,4d3ce3d8,a21f0c8c,875eea7c,111ca0f5,21c03f54,6bcee790,ab0d48bd,e9a8c8ab,99f916e0,4141972c,f60843be,72088d1,e044b27c,6a84b21f,c787abb) +,S(372b5966,8b00faaa,a714e7a8,2462107a,3d1226e4,988faafe,988d06a7,dfb27bd0,c6d349aa,6a53d0bb,185e0f59,a4c137c,8622be1c,5df205f3,4b090080,bf4e4035) +,S(b11cb8c,cd6302bd,e6005ed0,9a1ce2ea,a81fbd9c,748a17e8,fe1c139e,d2d1d725,29ec84f8,e8d627a6,b81a63c,4b13abb,88d7e5d4,9e56e2b9,a3f15f40,60efa38d) +,S(652b5427,f45d07c1,8cd9afb6,7d5743e2,836d78f3,528917fe,2a5c6162,c4a06d81,3e93d9e4,25ce53a4,915bd12d,4327e89b,64a7112c,5ebae53,35c631c9,64b2e5f9) +,S(c0812ee9,89fa0531,56847bb4,edd517a6,7d6d7d0,90ab5955,a59326da,f3833afa,2450338a,cf923109,d67b0501,3557f310,f3b0550a,8f1cd5fc,6eef8a5c,14b46c27) +,S(627c169e,fb0d9937,8ddd0fd5,a73afa16,2a317e56,7d957695,41e52a41,d9344ca1,11dfbcf7,75bafe74,eec503cc,22c8b485,90a17079,580acdd9,c51158f5,efd0cd7b) +,S(69916299,5b83ba3a,6bf16e2,97e8031e,74dc9054,c05ab59a,335a8296,d876a66d,39e45d50,aeceb888,8a1d64ab,9cb3b127,71269b7e,a14ca4eb,2179d762,4ee6d953) +,S(6693adae,579636f3,2332a418,7e49ffc6,921aa51d,852b5136,9a96c8e1,cc268574,ae73a660,580a4005,50865060,dbe9ab43,2f304ca5,506b9f4e,7e17f602,1456bfa2) +,S(ccc178c,7168ac1e,e7bf7579,f75f9645,5ca2b558,e1e709ee,de86df5e,5ebe0789,81c63b04,eddbf33b,432e00c5,9e76d319,fd1ef2f7,d6f31349,1f7a3c10,431a2130) +,S(d80687f6,89f7c28b,d6ef1531,c4e4b283,c6e5dabc,ad7fe5d9,6dc20d30,e1feeea2,71e24cd5,9d2c33ac,2b298946,bc90e0fe,d229720d,539a6f5,e128973a,9bd6c5fb) +,S(c53a6911,88f785f3,efc1fe1a,d142a259,cbda5f76,f3e9de36,895a8963,ffefcb74,7a225bd6,a348728d,951d55bf,257de9e9,d88df32c,ff2c4391,f4ddae8e,ce357cc0) +,S(d512c64d,1932fd1,5636740e,2bbd302c,3d8674e6,52a30d40,ce879145,bed9b7c1,52e336dd,3c7eca6a,469bc97e,a330fa03,1cda3c57,a4354ba2,acffcaa,a1e6b424) +,S(384aed3b,531098a1,99312d65,74b1b1bb,e79a8bf0,ea4f7a86,c5114fda,b32061d6,f2290bbb,2bbe7b53,eb64f87b,17a9e1,49356d9e,de3c0be4,28a4dc7d,709ef731) +,S(6db6c2c1,1fbd5b92,31a4e34f,ca2f9315,dde00dee,909b8d53,d7149c6,6e3cecb7,cb2f0b26,e1bcd464,6e6ee074,8efcd499,f535a8ba,f61a38e7,aaae3511,3c781649) +,S(6bc2f0f2,c0118efd,4fbab4c4,90c56da9,d66c0b1b,ec88e8b1,c8da967a,95d1ae60,a568f40f,24e51e2a,d01c13de,4490f34d,5a5bff13,e005ce77,94a59128,f6d871ae) +,S(12e4e92a,aa40ad9d,281316d2,358bb0d6,c69fac28,24114a9b,a96091d1,64ee29cb,f717cba6,b07eac9c,34b8821c,218519c3,886d5cc7,a22be959,54b3eefa,8819bb51) +,S(6dee0e1c,b887e155,e67996de,92716821,7874f9f0,a14c8673,1eaba91d,272705b3,28d9f2fc,23807874,9dd40ac1,8ace2dce,18ac3980,7c7a5922,43260eb8,ededbc3) +,S(f9d667ac,ec2120aa,50c2b6f0,810b54eb,4928bef4,779e2311,7d12eebf,d093f139,29c9458a,52d4cde7,e32a265b,fb537b3e,5a5fdbe6,ece9be95,b645b960,c160166d) +,S(e026f66,af79f4ea,52955b52,bca16e2f,b2cb05f4,38568c06,ebf1ca25,e6f5be17,6319ae60,3e733681,c8caa501,d7715b98,6244c1df,1c42d391,d8d47e15,a681df15) +,S(1ddd29c9,bbb37823,1185f631,23d5e1fd,39c6b03e,44e2a542,318a6f3e,8325ffb8,22d80158,cee2f596,8da360e5,93a2a86,ce1ed25b,77a4d66,a2e7592d,26c2c715) +,S(138f88f5,f9f46b81,2246373,6034958a,d5476a0f,348ca538,f789e980,9c799f30,adac6393,3e2de680,6fc38d7b,23ec5214,43ab505d,cedde216,6accf786,bd4e4aa5) +,S(b516a9a9,4630ba5e,7469d5e5,ee0f03c2,51bfdf5,a1983506,79baca9a,e6de6f6,9c184956,7ad68859,89a2013a,5a902fea,66d398e4,6c85203e,b7a143b1,90b42587) +,S(bb1a5499,548ee5a6,79500a49,a1466b11,9d56918a,735c3e07,31939ed0,2d47abe7,b946e966,2df43be8,6478e809,ac690d4d,b25398e8,de13731e,89867f80,63f8021e) +,S(394ee032,8be13bc3,ffa069f3,92b72070,36ad018b,503ed70b,9bbf9f7b,458faf36,3a494b0,dd538dc,fa3a10e9,70b83c4a,2169b4ea,255c6423,50f7ee72,40a6910d) +,S(a021889,ce4c941,606c0226,2b423afd,f44d6a75,483dc4cf,797b3512,8131e2ed,d8ae98ca,572b5a38,cd10a763,6638c47f,2867710,373af6a1,bfab6cc9,64b26547) +,S(99e2cf77,a0f389ad,a6c21457,d3e94ee5,95fded19,89c326da,3cef2e49,670f2572,8144a88c,a90a7685,ea3155ea,8fa5cc0c,c282fc25,532aa5da,84494b97,94810a1c) +,S(23c4b50e,80278869,b77c62de,8232a70e,52a4a3c3,4d0d6114,78989746,54e57aca,afba6a63,e35b15f3,1a24e5b5,844b0f3c,b247deee,a764b3c1,1075c3b8,c65bb0b5) +,S(ae0ea240,91b09648,6bd06ec7,ab6dd488,fd6669be,58c2e91d,e8486560,47493d5a,63e13a3,aed0b2f5,a11e914a,3617b1ea,abf62d4d,731eda05,62251d76,939aea63) +,S(d9e9ec51,cea0b150,28199afd,70fa86ef,dfa90e86,b9613831,9cbbeb86,c6573bf2,561519ee,f8dd5ebb,df47d4bb,c24eed76,5ff4342d,6ec6e537,8a2952e7,db51354a) +,S(e674a628,7472d602,8c0b888e,1dc86429,207e38a,af61d3e7,60708721,c1a44613,c145e723,eabf1dc7,f09fcef,1ae24116,1bc0d24e,9c96c83a,3c4e76e4,cdbb9e7f) +,S(19a43fb6,ad571142,42644af6,a3ce367d,329f44e5,bbbd8948,9368620d,944f413f,29a616f2,5f2bf4df,e516574,cbe840de,9ab9ee1d,abc86ca9,6413bfb7,a79a4095) +,S(cf1e1a87,32eb52e1,660186f9,6aaa4cac,9248d8ef,2738a6e7,5e600f3b,658825d,379dd9a1,8355ac8a,94a9614b,e3f51540,c17a76dd,3e3f853f,252f0e75,164dd346) +,S(342147b5,8a1ac1d0,baba5b2d,e924e7a3,b804e385,466f5ae8,29138bc9,5c5b386b,9d8792c5,8917aabb,6a3cbc4c,7f18d2b0,768dc9b9,1871bf48,8ebabc00,f51e2bf0) +,S(1c24e35d,35fda6b1,f6ae6b43,7599ec91,dff1fbb3,b3d26976,783c0539,a8b9af32,58591ff1,68290b12,d729c621,f5da504c,e697ef00,7d922152,9a76ed61,2dbe8608) +,S(d0fa4d47,a29e1101,baa08cca,73e00d6,660e2588,6e1b5cce,ee1c2a5a,9fb806da,918cb1f1,608f9e40,37a59bb7,28c25708,db898d76,a8b2e2b9,d4450c64,3606212) +,S(f3307ffb,7e72413e,2207918d,8a93f183,d5cc93e6,ae07d196,a6d22f1d,253b2499,8a44b83b,feffd6d2,78442d72,51929c0d,42b690a2,d91d99bc,c5dff056,d37e1f27) +,S(77e612a6,9931080c,7d910573,fe55582b,30eb4ca4,c7b7fe1c,9c4eeda9,b296097f,cc85c0f3,6f020bb0,9705f560,15268e36,bf61db2b,814b51b7,c958f1a8,656c26b8) +,S(fe3b3fdb,b8d768aa,8248087b,70e6d0de,592c95e9,b9816996,a3b4c88b,21bb9605,23b44ffb,20e8fc95,ad3c035e,3f52fb53,51291965,95fbda63,8a192cf9,43630e0d) +,S(e664460b,253050fd,8814a2,b2bc0f56,fd8d2f53,94673a67,9a76eee3,f7ae6e80,bf0a7515,a0a6351e,62bdf527,6974f06d,be87345b,438eea33,ddb980fc,788eec9c) +,S(b8ab3266,6cb96b06,a363d87a,a7ee820c,695b7372,b9341b,292dd0f1,d5fc35af,720da144,39ac9d53,c480dc25,5eb45ffa,b9e406c,8eb5bae5,1c145058,8120f900) +,S(38242b07,d1904c72,6da9ca1c,f1acced2,96c1c4a9,b37671c2,e529917d,a651b99,3d47a793,688603a,d6ddfc87,1c85a19f,e21ac51b,d292ff7c,69e219e5,7a0dea85) +,S(ae9a9354,e451abb4,454766fb,7eaac21,5982008e,6cd47d7d,df5a6289,27131913,46d291c0,7f99fbb8,2eea4c66,525602f9,6af5c16b,f4c31ca8,c26a831e,a39985f) +,S(59e59fd6,6a89a538,f5277950,816bf2dc,7070f70e,98d04b95,1b83a80,dab205a9,cec6b519,4d1122d6,dd3e39a6,fb3e80a3,2d829158,3ddf0bb0,3dc3086e,9f247f4d) +,S(59aade5,c117e92a,97ba1785,2e1ef3f6,d000620d,a8f82e2c,1d4272d5,34a8e22a,6a6b6ab1,bd9a69cb,181538fd,eb4a9e8b,eda75811,96ef31ae,deaf516c,e68c1cc3) +,S(f29d02a4,5b464774,fbc1bcd7,7caaf22f,12efcc9b,2a569966,b9adbe8,18a9f075,ba87956,5e0a1c56,fd03175b,a781110,3f34542,ded10367,6d44f706,7b8ab418) +,S(db630bf6,e9ff0092,eebeebb8,a5bc72e8,774c083,cafa0519,2e6d913d,112181a8,6b764e8,2213a7de,79b9abe7,edabf502,d9ac04c8,eb5a4b26,9d22b666,f657685f) +,S(45b9f064,71b848c7,48ff3fc3,34d425d2,57a71abc,27c4d002,dda26c77,1b09d2b8,c2119389,e4cecaa9,c0c72e4e,20c95cf9,1acb1698,c0bcfd42,f8620a9e,d781de57) +,S(d4919e2,3a278aa4,25bb55cd,2fdcde2,eac63058,4cd57f50,390c6a9a,1015ffb4,f8e9f461,950f17fd,8c46f04a,3a6f3c52,5318cb93,a0aa3f3b,bf90c02e,80e1c288) +,S(ea000677,2a76378f,3faa3c1f,c7227cc1,4b11764a,3c9a14c0,4f18f9d0,b55acc46,eafaf0b5,9a308182,8e6d07d7,2e16509f,bbf76fbd,e1473e35,18b795c8,87ff84c6) +,S(70b539a4,4750f763,be1145b5,b433e98,847545a2,8fc72986,2c17045b,f0d6fded,d5438ebf,18eb5feb,fcf6edae,4fcca2af,e0208adb,2f82648,2af428cf,bc761464) +,S(10b4a235,99ce2be7,fdc31f8e,ad91523a,47b8162f,8ed9387b,4c208657,25fa88d3,773ef1b3,a3943b86,729661bb,6ce6f4ae,e8c7165f,97a88fe9,5df9e027,3ccf9e7c) +,S(67d7633,499323f7,cc378c5e,2e62cc6a,5f34ff83,e11e6061,9ec4a404,d63b91b7,cd7616ed,60f0f4fc,1006dcf1,850807d7,e8730954,30db6761,cb7cbbf1,a9c2958b) +,S(5744c77f,8371057,61b1c782,1c9d9c53,14219e1c,5df80ea0,f772f9fe,ff157aa7,578459ee,13ec92b8,b685acda,a153f24,f6c844bb,e195ad58,77364ead,7a9e5fa4) +,S(7c6b254d,39ab709c,cd63c2c2,56c43483,183b1b27,25ca49a3,19753f68,6486ad02,5669fcba,d8662be6,2d12cde6,30102f3,70f7ef0b,5b347fa8,6000ae6f,497fad6a) +,S(8ec715c5,bda8f9ef,3b197ea8,a182a3dd,6cbc3b8a,88227e00,53a2eefb,b2006676,e59ecc81,aea7f2a5,4f659bdf,a317bada,3f8ccb7b,134ae21d,733b9710,335e73c9) +,S(fc7eb1e0,95d0b18,58d22b5,ad36fbac,1b513d86,2bb3c9ef,61b55a5e,985e642,7206dfc3,10056bcc,4071e9f8,13495744,dd903d72,2aa0d6b7,3fb35394,4b66c85d) +,S(4954bd00,308e205b,90c191ab,6262daf2,81939084,668c43dd,1ae998d7,e143f1dc,8efa802f,e67f72c2,5b4fc279,4e23608,7b343d89,255272d6,3c3968c8,7f26237) +,S(f27e6c84,f60858e8,2eb53d39,a6860189,9172da9c,e0d1ea70,9225effe,23de6969,90533e33,321f1f5a,ce37ff79,b4dd3109,a1efd6eb,de502aae,4dbdf58b,1e697c74) +,S(166f3aeb,cd040509,85df120,edf55c1b,f6eed0b5,fb24173d,c7d9125d,d0b2b29a,54b8de8b,c24b1cd7,8f89820f,d4b3ac6a,1588ebce,6de99b9c,81773ba,5fd32e20) +,S(c0797522,8dabaaf2,b46108c4,88ebd104,b0bfafdb,b344b5e0,72f6cb6a,f58f3cdb,bae0280c,704e0d0d,2d421b20,828cd00d,9b388f32,fcadb511,ad5ed4de,281a4a29) +,S(81366739,2085f96c,6a39c9f5,ff60b51c,4991a289,7106619d,1ab0de9b,34de87bc,d7b8599,2464c1e1,9f575cfd,de5bec08,987230b6,20d911d5,d6dd3d2a,8a75e079) +,S(335f446a,f3964e77,8f4985a5,c19e371b,876494b4,467ed700,482558a,9cab3c65,6e8fa42,24cd52c4,b78af9de,b7efa726,c26a94d,85bfeb6,fdb1b97f,674cbe6f) +,S(b6a34b42,bf5e4781,df14fe99,1a14b414,fa488da2,29314366,1ba83ecf,1e80d60c,b633c9f3,cd359dc9,2ce47287,670fe80e,131315c1,6fc17811,f319f1e9,82f88e8b) +,S(95f99013,a9e937e6,ff784b07,23287960,5eb4532,e16b3881,25a18012,17ee3ed9,2d0fa2ee,1aed211d,5b90915f,f3b2116a,28528f19,35b6b534,333b102d,177c08a2) +,S(9c0923b0,d681933,bc8bca36,a6af4058,682c5661,95d3a211,a1ef602f,933f6a45,a72df8d,a9a951e5,a63f0424,4974d74f,fb809cf5,fe7c24da,9c1715a7,2419c7d5) +,S(931cd34d,e32188a8,802b6a73,204eadf2,cae8d8de,52423daf,daf042cb,946657f1,d84b7406,d58c53e2,89ca15bb,4ba78db3,6bd2947,34d0ee9d,6939c15a,9f28b856) +,S(24be4b41,f845c43b,5fc594ac,90e3e4aa,b49cc79c,4b0a8408,1803c27b,ce62fe4,c6651cb0,be54ab0,78940179,6dca2448,3d9349ee,e45e78d4,b786a636,83861bb9) +,S(f19a51c2,ebff1d77,81b0e7f0,a29947fc,3ed9dd26,9f0b9cb9,c27c3f7,500c81eb,8e1cfe92,6128173f,556b3ec4,4c394ba0,201a4f93,e2db054f,63934b2,479a301e) +,S(f6e7e4cb,88ecad49,a1653a6c,5510571a,cec77024,2f490774,a8dd62a7,d6e16363,60842dbb,b8ae082e,9538e725,1a3dd7f9,8edabff3,5444719d,97134a3c,236c97b3) +,S(e7b7bb26,af8cc2ba,6e54e923,6af55e40,7ff704c6,1264cacc,74d96b52,81f2ca00,3abaca16,e20f74d7,6d11a942,415987c7,8da5ed50,3d781f2f,aba6d534,cbc3908c) +,S(c8acf1d3,89a29f6d,e0d03835,80a0a562,aefcaa99,b184f910,f2c8370b,bedc4c16,924e9b2e,2c6463ac,e8eda0b3,feee2f82,73050559,1071bbcd,72f6e323,31617359) +,S(1453b2dc,efe09d16,373ffc2d,42e79805,64ff194c,6b9944dc,b12d3cdb,1d84ae27,2d7faeab,7ca11212,a1aa9d4,a462c04b,8dacd2ec,1f7ee3b8,28fcdfb7,a26c6e17) +,S(ae92e090,b3c6ae15,68a12c6c,882d1b4,345f0a46,b9ad364,bc869243,dd533f4d,3f50449b,a3865900,ff63d944,27a0b967,56c00179,5b5f51cd,5996ca2b,19ad7abf) +,S(3086b503,ad8afe4d,fe2795f7,c972e0c0,8d6f040a,1be88309,606fee4d,b977fd06,b8631fad,80689ce2,7f62db6c,d6a56f3c,d3dc110e,610f3732,fa3f2c10,a4d588d9) +,S(7a17def1,e9c2b175,9944eb35,262908e7,c988f602,2440e151,928dfb44,462e2856,42171a1,f71ae8ea,d437a1d7,e1ec3394,b713044d,6c895930,2535787f,b93fcec3) +,S(97975e9e,b0698b70,995411da,37ce2a87,91198b90,e104476e,b86c4a77,dc5ce9c4,b8999b7,69b36de2,13cfc81c,c2fffc3,65e5dbc2,db1906a0,ec88e931,cd05bd41) +,S(839fa603,a2ec722d,1253328e,15f7d187,55ee80fd,b6bc7b09,bbca59eb,316d1b22,4e43cdca,1b33fa9,cf397ef3,91d40b46,fdcfa770,b2be8e9d,9ee22d61,6e12dfa9) +,S(ccfb8b97,7baefebd,eaf49c7c,1ddada20,861e1c0d,acba4caf,4e30f21b,ca3a05a7,7d9bced6,62579237,a348071,3ea1af91,256e9d62,1265fa27,cc80b5fc,cf75f99f) +,S(8f9f369b,3f325823,e8c9b16f,f2142ebc,3c6f7bfd,dd28c4df,63d1c92b,581cb6a4,114c7d9b,3f54f549,c10d93d4,25843477,9c297e2f,3f07b208,12335fe2,5771b12c) +,S(f0deaa5c,324c5ead,6f6f1cb0,cf1dac32,ef342606,3533435,65ac164a,ac8f0f2f,ef6dd597,e2203c03,f0ce0780,bcc1e963,621c1460,7a4ce616,9ee6624d,11c2eee9) +,S(638362c2,18c9e0e8,72dafa8e,fed86fcf,da5641eb,7cd01725,9a85103,f04fa408,3c224389,bff1fd09,338ea28c,7c9a93cb,32be8749,4a6c629,5c1c3dff,2b582877) +,S(49acbef2,64708117,a53f52e6,84bc15e9,d004baa2,fb3a756a,72d35efb,49871759,b678efb3,fa09158f,d1f9c74a,87a56883,b0a8316c,d4848ef5,1f35dfc0,8c4b5bb) +,S(a79d63c7,b718cd66,b393e70a,f032bc50,a90209b2,5f5b07c0,303eb8d1,1db618ee,ecf7f89d,2f6f9877,9b5e390,ce5837ba,49bc2b3,a7c1047b,7a7c852e,89f1551a) +,S(c922d543,f192f654,3445d3f9,c36a05b8,2ee043e0,92afcae5,a21b9b17,a06d0257,cf77d5eb,9e555f90,34ce1c14,63f7c4b6,a0202d81,deb02ddf,a26113ba,292554e7) +,S(dbb8f077,b411a4dd,faf0d89c,3dc20375,1bb20e16,2052ee46,915528e5,1f461387,a6c0d5df,91cc4ba1,cbba0588,774d47e1,7ef97281,63ca8950,7ff6b779,da12b7e6) +,S(dea21a21,eccb1733,14d76fcf,dc6109c8,88a633d9,645f86e4,e59ee237,cb18110c,a1390d1d,69a304f1,a2792ecc,675f2dae,1ddef908,2f2e3929,6b9a068,3933264b) +,S(f088ed85,750dd58a,cd03b3a9,93d88760,34f50780,985f7552,114f957a,ce8904a1,b810e652,f596cb80,c369f61,f632bc3c,fcfb1fc2,b906acaf,c1f39d02,5e3ae4dd) +,S(b85da431,16b898e8,56fe3c18,b60a48b7,c2ba9f65,ad67c31d,f45ac3b6,608b774c,357d324b,474ae7d8,97398506,c550a1fc,5353a00c,7e6f1245,c0f57683,80ac9e1f) +,S(eaac0d2c,276000ff,899dcb3c,61b41663,70123276,14585bea,7704de95,d164514b,aad696cb,1af2f12,1ba915ec,64afc13d,a689719d,8f188424,25d6068e,9bb06a69) +,S(7a3cfc7e,51fbf61f,ffed3430,eb9ac40,c84164b0,21220837,29f20ed8,eacac977,9015b896,e034d2b6,684f7352,185e959b,5c45406f,6187930f,82f62269,d3ba70a) +,S(5a9def12,e06f0ac4,35b9f853,53db864c,77288050,c349ed7d,a8d8b109,b001a856,b63b74ba,868df816,9dfc30a9,1efbae1e,1617a230,3ed20239,9ecf5798,5ec4bf99) +,S(b937b3d4,287a0f84,5323cc72,95b4a201,ba9d97d3,2d968533,7caccbdc,ce8623ed,6f2ad251,a66e5ff0,77384746,9208db13,2a396dc2,17e781ce,9aa8d556,83fc0adf) +,S(d44f7fc2,97e079f4,ba0689de,dc743d4,964c6ab,8c34bbff,f95bf22e,b7d3c209,b5afe3b6,f6b02542,e6ce811b,f4bb0fce,79e7916f,fed8845c,dd83de07,9320a2d1) +,S(5980fbb1,6be7acd7,b090a2b1,c83dbf80,9148cc99,75fd6834,edf564c5,50fdf2f2,72340269,8d22b946,ae51c9c8,33d5b44d,ee884a02,e12a6d4a,23957483,32abac9) +,S(94733aeb,dce57a89,16961f41,3eb04b5e,71f0a055,29baf93f,c9ff178a,12b70511,e591b62e,5cf92ea4,306e16b5,acc5958d,a5516bf5,7a7dab17,db38cef7,44302c47) +,S(1172b006,3d5ae491,8699e756,75ddfc59,fb5cc8d4,f332ce72,f99fb99e,c9799d96,2845be1b,b97830d3,f9d04a3b,36ae381c,5654bef3,f3fa8516,3a7b9738,ed867ef4) +,S(29afd093,5ca567f7,eb4cc1c2,ebbbe8c3,bc405691,b41a2812,b7c71312,81bbe691,77e9a59d,c0aebd28,9cf2960,ebe7fc19,236c1859,7882df0f,a8e6e0c2,6d92b821) +,S(191c7ed6,72c36def,576f645c,6b475eff,793119e3,ebc3a29b,71eee3c9,cb52a635,642bdce7,90d0f104,54ebe4d6,282be83a,443f8f44,faba4c76,5b1491d8,c7c83210) +,S(237eff13,89c20d30,9902a738,fa4543d4,c2a4a2b5,6731603,500997bb,40d28eda,973d696c,ba9eb05d,73ce7491,5c1cf3d1,5a998608,7ce85854,f7bdd157,3d5c7394) +,S(d4985b52,80673074,53ec0edb,f02b9d4c,b1ce9a0c,af7c675,77789b8d,f3b5ab33,ad8fa145,94c510a7,830f3353,4ac94a98,cdf2fa30,b6a1b572,9222969c,e27eb1ea) +,S(3baed9b6,25f5d0b2,6e0132c6,20a9015,f79bd8d1,8e5ce170,20fed78f,a2238914,6ef88df1,3c7a9023,1180edfd,d041b950,3ad89f22,4ec557b7,2e900bc8,fa820c19) +,S(6e2298a6,102268b1,af97bf67,c0aba783,5463165b,1df8a824,530ee5d7,86d354f6,c3864e52,3bb5cfe0,a64adc7a,9e8926e9,876516a4,c83767d8,5ebfc39a,e125c19c) +,S(f9e87f15,2412598d,775131de,abbd0272,4d658849,cb60aac6,92280e63,8e835e9,e843a3dd,a30f9685,70fcf86e,86206c22,af40ce3a,3beb620c,aa167e63,271d95ac) +,S(f9925b7e,80b8b8b1,b5c56f80,74bd5ee1,9e419678,2c5a33d2,c59f8016,56cfbb0e,3e2fda0b,50aa7671,5810a8d2,2d4778d8,66bd2515,acf87b79,7b2f4875,dee19719) +,S(6fc34efd,5d11ae35,2cca3254,c5f8a040,52b81357,556d4d67,dd02d22b,91f4e49b,f14c656,ec946492,a6af3f2f,56fd7355,71e41b2c,dfeda7bd,ed567658,202f6e61) +,S(ab504458,4b38c846,e282038,1f02f55d,fc6a5648,1b1830c1,e4ee94e3,d11af8d9,4ad3821e,3f5219c,aab31787,2a8fbccf,f0f445d7,da30f05,d9523f55,13eee3cc) +,S(2378d11,716b6d34,85bd5a57,5c5b2c96,1b817abe,e21b7d45,38244933,5ce7e7a5,33682ec0,8c59a158,c4ef12bd,d2a46d31,6abc6dd4,f81a1fef,5be40577,4e03fab) +,S(cfa95425,8608d9b,9c568a1c,fd4b078a,ff49150f,a4681324,ac56b6e9,df569016,e200a3ae,2d82ddc2,a71767e5,842ef30c,86cd9b17,7c5e52ff,ac316e50,1e7e2) +,S(585542d9,a3a582a3,bde74fef,112924c4,e00cafcb,61518d87,f524211d,bdb98993,2035bc19,7a0ea2b6,8d1d1333,b5aadc61,c9dff2c1,e4dea034,1539ff15,9a3d18ae) +,S(fab2433,905e5b46,e47103f2,e353d503,cb141e61,2167cb4d,34946a5c,cd2c06b,7097d735,3f17734f,8eff6993,77916c9,884f67db,42f7a96c,62a3e1d9,9e341547) +,S(b10db548,be55521c,de5edc26,fa39716,154e365d,a1b8b7fd,2265d78b,7edee8cd,389efe1c,7fd8b4a5,4a42e651,b5c06a2a,7c153664,e52ef30d,90eda2d5,9e9690c8) +,S(218a8a36,273fce14,85c0c9f7,1910aff8,64910b00,6254af75,e78a6b5b,3d5c7bad,4a1984e8,e90d4695,b8dcf34a,55eaf568,b0fd34cc,528a147c,bebb052a,8e6e8604) +,S(e120bc22,fe6dc81f,dc3ead1b,a2ca966f,c5702ec,479793b1,5f0ebae3,b6c5ff3,9f92f1d5,e8aa56f6,1ef20685,c8085782,be180658,c7d2b9e1,c020c98e,cd425835) +,S(e83373fa,f80d4560,5ac4da9a,c9cfa220,b2a2c656,26857035,a228c93b,495be15f,8b915652,3c532657,7945021,d6c1b1a6,3b1fd090,ea93cf01,90fdb791,a2397a91) +,S(b7d8a393,a10590ea,91d2a495,eec07262,f2f43e29,74f7b2e5,6ba6ee92,17e3e74b,4ad6671f,58b2c7ba,7a940613,5986b3f3,5a6e13ec,8243b0fa,c8bec130,2afbad0f) +,S(75a5ed46,b2103f5f,ee808803,bf419bbc,232cf5d3,84955e8b,1d4fbaee,5194ca35,51b9670c,4c65e969,a5a56e15,25f33dc9,458c317b,6faf484a,186d52d1,757e4857) +,S(6d8d67cb,c309ecc6,3c1e04d4,aa42683c,775d5f32,51111500,9166c574,b0dd66e4,e127b8c,f431cf09,5939712e,c96d299e,efbdeeec,eeca3d2a,9f6b3d29,fb8f72fd) +,S(51a6d684,463065c8,7d3e0fee,ac72e4f3,1e5187a4,dd14d59e,ef71ee93,85fb229,7fe1069c,b384178c,ae2241fa,6886e1fd,286347f0,d2488dbb,f4d6eaf9,e722a90a) +,S(5140ba9e,81a272eb,30ac5c96,a8b054bf,870b1785,9519cdbe,4f2e6573,2a56e6bc,3b6a2c0e,7421eab3,147b61e6,d8252326,1819bd94,9e3c805f,ca2a12b2,e13599a9) +,S(b94c7812,6c60a3b0,48b28f47,f9d461e,27ffdf7f,93a3ee70,ae38962c,8060166b,bab7aa94,385d224f,f20e7c60,7f7f11db,4ec3526a,c226cc96,16af6a3e,356208f2) +,S(45046678,76689fbc,a94ebd79,ddb5d655,3e97b788,c91cee0,b62ee75c,1fd12ff3,635b3d75,a0621530,d7ff26cf,f1878d52,2864a6ea,e82b220f,d35ae5a5,edea1895) +,S(45f4025d,7b88ddaf,e39566e4,27060b7c,ac59ae7a,526ac3d6,a489424b,d677a54d,d732c322,18307ace,354ade14,21d13438,ac4c7c3,5b5021a6,cea9137f,b47465ac) +,S(c6e8912e,a197f39b,817b743d,deb3320b,558af332,96e0ebb,58c258c4,f1c0d5cc,6e0c8ecc,fd97ccd,deb08f4a,73ca13cf,b48d3633,afb74139,36550e0a,c23f04ea) +,S(6fd13fd,c7d3809d,6a3bf6b1,5208d0ab,5f476e99,57a7fc71,29824154,a05a7dd7,95922641,32be31b4,c34ea614,df6b8c1a,c386dbc2,1318868d,b40869a7,17b862e6) +,S(54fc0732,968b0207,ea2c115f,d11bfb57,b9b28164,4644d82f,45af1100,6b63d0b3,318ef9f3,b2173c45,bba5ffdd,8345a08b,66c8e183,80ef9dbb,b5d80c1f,15f95bfb) +,S(9e6ac718,6e09f698,1f384cdc,b9c48703,a8ee3726,d6d8ee3,a10499f5,e17731e1,95b4c37f,ec98faca,b41c628e,12f606e,79829b17,96ef3dce,c4aba99e,3882bc0a) +,S(85732ae2,eb7944a2,6609aea5,607604c4,c30f25ca,c365fb2,e01c7600,40542ce6,928a62fb,b082f38b,52890540,7b20f9ac,1f4841a7,bde217ab,828780ee,94749fcb) +,S(3ea5ace,80e47aa1,9bf1406d,3559fd50,85d38504,93752563,de66393e,37a652a1,db5fa543,142d36f,fcc1cc8,36b1f4c4,e82d4980,f2b277c7,bec53324,fbdc8e9c) +,S(7d40f7ae,f1866d87,8e42f9c8,d5afff76,2a427567,f6130f73,439d67fe,d14be54d,5bee61f5,31e4ebb5,679c9645,d565cf,f93b391b,f48c5504,a5054e23,47859d2a) +,S(3dc80cd7,478ea38e,1d6e1e41,aca892c4,4e4d8339,acd72fb4,c27861ae,3e7d8664,98412c68,68af56ab,19876499,fa30c8b7,8bfa5d19,b4aea0ec,52787690,49b7e3b5) +,S(2dd92155,81bbbcdb,a1900b90,9018ea30,2e40ec35,cf2b74ca,6065e8d1,f3bcc057,cdb59ee3,b5d42deb,5a4ffe56,46f5dec0,218d0e9d,569cdd3f,b96610ab,2a382fe5) +,S(a245a185,ed85c547,3b78a561,76a32e45,b35efe75,36a1fef4,569f4f70,ba510ae5,93b66fc4,6fde9554,1363bdbd,117073cd,f3f5e406,75fc5710,34bef6bc,47a2519c) +,S(5136c2e4,5004c1fd,615fe81a,e4463153,2753c670,86d1bba0,b3a35bdc,47bbec08,1743f5c5,d0a58608,a66fab55,69f7134d,7fe49fad,2dbee1a6,d01c581d,18f97d85) +,S(b65423af,618b242b,71e258e8,c22f975b,621a8900,9e0a3f12,f9f8314d,7fc6ca54,e3c39b1c,e4159306,e730c2ad,4ecec430,720355a2,815b63a9,720ef623,b91e4230) +,S(d6db49c6,4e68f6b0,59cb5a00,3c826a59,bea1e9fe,7622a2e,6eca605e,fe9a7858,cff0a39d,83e246f1,efad5dad,72c5df0d,62e9cf8f,4da81a5a,68586187,3dfd758f) +,S(ff2f739,8e5aaae1,a589a82f,e8e36315,34ff1081,cb083933,d08473b4,bd16f03,1559e2e8,49dc5aeb,50f3de13,1478fa99,e110627,aa0c4c5d,43ab03ca,dde04cdf) +,S(a7c9398c,5938a3ca,e32d2947,d8e3a58,e42a669f,5cd9b219,d8acf6f5,2cef9bf5,43e2a5a3,dae4bd5e,64a30861,7056fce6,cf86d0b7,41c3b46e,3a3ed90e,98d2d51c) +,S(faa9724a,357b6806,7be30aa6,4fb85879,1969191e,346d5d73,8a85b27c,c6608d72,ea1f8a66,8f4881fc,4ecfc556,f0ca4e12,b93ee6ca,54a0fce,b2fe51ca,174d9713) +,S(28301cf8,328171c0,74cd585f,6e5870ac,815de8d0,9c9f15c5,5540de9a,b29a86df,31910e6f,15585710,74e87f41,e5cc9c73,4ddd15bd,4436ec8f,59806afe,7901c2e4) +,S(fbde2380,ae0cccc4,e044ca59,92be8e11,5fc782eb,c1d49bc2,cbdfd1f5,d7908a09,c1a1d67c,74777fbb,68919bf4,11de555a,6485436f,7e34062b,480b7516,8a03dba3) +,S(59d8ba7b,6c71ba1d,191d4cce,662483cb,9784ede7,d1908e81,815d0a48,4b84bf7d,8a32e968,1ecf963b,3c23a9d2,f382490b,1f229b27,a663f4a6,9819c33b,f9f6149f) +,S(6c3a61d7,1c999ae0,604511ad,23f620ad,dfc7891b,925eeed1,6a5ca37f,b41b47e4,f7115905,c696c2b3,e2b82a30,9728923e,b8eba53c,363f1456,73676b59,9b50b9c0) +,S(8e53027f,8e137bfa,73eb5167,35382ba,ab3468f4,d4227b19,a45c51c2,ef3d8339,2b5ea7b9,542a83ab,a1c402ba,be13437b,c621067,96e83b7a,2cdedc52,2bcff513) +,S(113aa35e,6a5f794b,a56b04a3,d639b1e1,64a790b5,8ff310c,fbeab588,f93be16a,227c17e7,d95583e7,fdcc3ab7,b24182b5,1bb11e91,9f28fd7b,3a2e4a40,4f333962) +,S(16c4c83f,5a06b2de,9d3f39e7,1f0a9de7,af6e8fc7,b0fecaf3,2c82f1aa,fe9a5343,b4cbf71e,c3ad4635,87f8e355,cffe1ea,a19f1dc6,d233d617,776a69a9,ab8dec03) +,S(4d97594c,613de84a,e685199a,ac639a56,e5c15a0e,c00282bd,197cc2ea,90f8fbb0,b9f39a44,24cbb1e2,f77afa90,ec7266ee,64ea987e,80a32b34,483c1f2e,b0c5844a) +,S(b679693a,b3fecff0,819e0598,65406521,1f9aee9c,1ea44417,eba86ebe,32414ac3,7bfe1ba0,ae17291d,71aac3f3,66e5a927,56b53312,a6818d1a,78b7d9ef,a5d01b2f) +,S(a97c2730,a78cf5b7,538b518a,87d8fc55,f95a367d,4e021d23,79f163eb,98b6eb9a,aed1e51c,3ce7e35e,ff69e7d9,3fd3a968,59f0f23a,7bbab9d8,3b60cabd,cebd34f) +,S(7dd4e84f,6547d66b,5e0b204c,ed1d0258,4fe92ed8,6b504ae4,eb1b3d66,d43b8ca4,7956148f,de975510,5e3b5126,f82e77b,89a77b68,ffc9364c,bfb596e8,187ea99b) +,S(5e856d1d,25acc306,e8c1a2b7,a9ccea1,beb3008d,c224b38f,e2f31376,65d07c3f,7dccf6b1,55c12be2,f3da02c9,12fdb666,816558b1,11a2a545,9d88aa28,9d855e6c) +,S(c85ee868,7f507429,e5c26af6,7ef1fe45,e782661c,1fa03aa3,ee9dd9c9,302e5dd6,732de6ad,d071a0b0,b77e47bc,14e176d4,c85b39d0,ac5b4ea,55f0d367,dba5ab5d) +,S(a97ba3a5,cc2d5148,3f65c65b,483b3e4f,3c68e46b,87bcfea1,42aeed8,4c42e42b,f4eb1271,3024d1,b7612c3b,7dc3dff8,ca336f23,5db7daf9,3ca6f7d8,1bdb4a21) +,S(3c0396cf,6ff0150c,5b6bd528,4a05d0a5,3b735c85,125bd49c,f62db5b6,4eaf54a7,6ec02c02,f8d9a61e,6bb38d64,daaf3c7d,5324462e,37e2df8d,4ad12bfa,37fd2cb2) +,S(e36fcebc,e406d2a4,ad42f7dd,cc00e9f3,cf385eeb,58cee004,5aab8174,82d84f94,7c98182f,6edd358e,76d66de0,b45ae9f6,5eb75092,1a25194c,1911bd9f,7e6a1a6b) +,S(171ea2ec,b9641746,7d7edcf,ecd6d85,8577322e,6ebac130,5ab57f33,62eb4e37,9f219970,753a7b9c,e4f0c6ce,5745596a,aca8df7b,a73660c9,10add5a9,d4c533d6) +,S(a81d720a,bf8047e8,ef67bf2,71a13f47,636a5f9e,ec425649,1cbdad65,39652f9e,92b37c88,275c022b,635df6b,9246edf5,5dbd8284,eaa4cd7e,3d3ce6d1,c0ca3794) +,S(fa3b6973,4bd9939c,4b6ecd3b,f0a06327,2dc11345,1bddd717,f17b745f,bc3f99b3,f38a4e1a,bcb35097,7acc8f2e,d7f73f75,d406e7f2,22fdeea,2c12d8b9,e5d2dfa3) +,S(c117681e,b55bff67,feda80a1,ae88b4be,c806860d,91916619,288a7ce0,b31aef86,d94ae124,dca678bc,b69c9421,f295405f,d6dc1fac,de96a2b4,58ba5fd2,72faa032) +,S(5ccc0619,92744a57,683de5e3,7b956fa1,fd7287d,b4516fc9,f8635be3,a0db42a9,af1f73ea,4d2168e1,7550ffc,dcbba288,8397931b,e457ce6f,3f8082f8,cfc5f03) +,S(858b019c,8a93524f,6c86738d,cb10b534,d8caaf86,5c0ce75c,fc9b83b0,7c661a0a,7c59d30,1ffc8ce1,b0767ed7,91f84bc5,60bb8ca,ed3464ba,698a53c,160ec570) +,S(e1e217b8,69da0c77,599dcc38,40fa1d8c,a8d08b1a,4ac9a882,da1476cc,cc76fa56,83f0ef77,905f0801,4bd86e17,63b8c2cf,ab2018a8,9586620a,b49a15,9fc314ca) +,S(15a1ae40,b4fc51dc,554b75d4,db0c2bfd,62dfbbfc,dede18e1,4edbb689,91525cff,4f0453b7,e4e0e99d,9663e5c6,bb018007,b52c8e14,d78a28d,c4a888e4,8c4326c2) +,S(1b9a142f,fc4d03ea,4b079f2d,b05fad98,8ddb2d32,b359967f,c173801f,63320825,59bda7ed,5b691c20,4fc8f8ac,f53be298,ae628954,a8134d0f,dd097e67,be9ff9b6) +#endif +}; +#undef S diff --git a/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult.h b/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult.h new file mode 100644 index 0000000000..17df102967 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult.h @@ -0,0 +1,38 @@ +/***************************************************************************************************** + * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *****************************************************************************************************/ + +#ifndef SECP256K1_PRECOMPUTED_ECMULT_H +#define SECP256K1_PRECOMPUTED_ECMULT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ecmult.h" +#include "group.h" +#if defined(EXHAUSTIVE_TEST_ORDER) +# if EXHAUSTIVE_TEST_ORDER == 7 +# define WINDOW_G 3 +# elif EXHAUSTIVE_TEST_ORDER == 13 +# define WINDOW_G 4 +# elif EXHAUSTIVE_TEST_ORDER == 199 +# define WINDOW_G 8 +# else +# error No known generator for the specified exhaustive test group order. +# endif +static secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; +static secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; +#else /* !defined(EXHAUSTIVE_TEST_ORDER) */ +# define WINDOW_G ECMULT_WINDOW_SIZE +extern const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; +extern const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; +#endif /* defined(EXHAUSTIVE_TEST_ORDER) */ + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_PRECOMPUTED_ECMULT_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult_gen.c b/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult_gen.c new file mode 100644 index 0000000000..248fb077e5 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult_gen.c @@ -0,0 +1,1779 @@ +/* This file was automatically generated by precompute_ecmult_gen. */ +/* See ecmult_gen_impl.h for details about the contents of this file. */ +#include "group.h" +#include "ecmult_gen.h" +#include "precomputed_ecmult_gen.h" +#ifdef EXHAUSTIVE_TEST_ORDER +# error Cannot compile precomputed_ecmult_gen.c in exhaustive test mode +#endif /* EXHAUSTIVE_TEST_ORDER */ +#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u) +const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS] = { +#if 0 +#elif (COMB_BLOCKS == 2) && (COMB_TEETH == 5) && (COMB_SPACING == 26) +{S(7081b567,8cb87d01,99c9c76e,d1e0a5e0,1d784be9,27f6b135,161e0fd0,3f39b473,ad5222ac,f062cb39,21b234a7,15b626ae,f780b307,9b5122d1,53210f42,d9369242), +S(228af17e,df90d1cc,a40173e9,478fa445,9780dacd,c3f15b90,fda5d00e,1faa1b51,8ff47c4d,a4ba636a,f656da9,12a81f79,6252496d,1e519886,b2c2b073,25be2b4a), +S(b515ebe0,f48fb34e,9e01824c,d90553af,db116579,96667847,5ebaa700,242fd722,4cf08191,510fbf0,51f9e19a,198f11f6,ea31268c,2a6d384c,60557250,f0553c50), +S(c37581f1,35446ff3,e80cde04,ec987f08,5af3af9f,71d87494,99b03ba,dcb8f78c,9e46324a,8d8754fe,fbda7c34,2446cf72,b7472708,25cfb92f,a22a4e73,4f1e9bc7), +S(768392e3,b2ccbbc,21792f2d,6f43c63d,efcc249,bcd549cb,96abd8ef,4ae59e90,5d061a40,ac3f93d1,82f0f7a9,914fff5d,90bbacb9,1965882c,591e89bf,c49da994), +S(a9db5de9,2d96c715,8ce5ee00,3d186cf1,976f6a76,f1be0714,726594fb,6c1ba564,743df2a8,ee73fb4a,47b3d0f,2f2b8cab,5af5227,f232946a,82676e4e,8bb70c8b), +S(58921d8d,3712f640,657e762a,737ccd0a,cece1459,a2ba8323,20b43903,d4953f93,78c26959,7e422c02,c01fcbef,484a9d44,9f635c82,849bc2a3,2a9bf6ef,3e6f1e7e), +S(bae41760,ade541bb,60028015,f6906b78,aa41515a,d995dc40,afa091da,77ae8b9a,716ff74d,ad6dc24c,77ebe31f,abe19792,41d18b0f,43ff7598,c6ea04c6,6899219f), +S(e836ff6c,6f9e02e2,4e6f6bcc,2f2460b4,9de88730,6d69241f,b22fa574,7e100f80,77c41df1,4d87b6d3,de74deca,ad426635,f85daca0,ab966a4,5a26a972,32105c5), +S(c7f17d19,fbbf28e2,543fceb2,4268ff6f,1b85e189,79b09991,7457fca0,9ba1b5a4,23a6d4aa,83ee15bf,f1655575,3e4162c5,8acedadb,4c4abfc2,54b7018,f477514b), +S(79c337ad,8835046e,572eea35,df76276b,84e99172,7bbc68a6,8c0b743,28619a,af6cf2b3,9c6b51c9,f1f92e42,6598dcbe,39da6196,2abae0da,d5fc8d0a,aa16a875), +S(1e77739b,12d20887,2bfe200b,d202972a,544804f5,2b0969c5,c22fbe1c,b8b23837,880c7490,c0455322,a0f1e67d,34b3fd1e,33c1e7da,83b9b047,5aef7bc1,332ccee5), +S(b1d314c1,74d493f6,c36a893a,830d90b,f1e86d0c,6deceee0,edb77ff4,31e9607f,8a4ba010,ec3e47cb,29d8f056,e056eb73,3b6b35f6,4c742d06,9ab832f4,68bcd3be), +S(2498aea6,471f748a,f14e50e6,bc17e0a3,ee09514d,fccbd174,f8a21d02,dd0fae48,55a3949f,2e4188e2,b3d344ce,6f0276b5,99b121bc,358e8fe6,bc4f03f5,a8219d08), +S(42d0778e,27e87710,dd19285e,d531af1e,7064386d,11b1b3c9,fb788bf2,b0c112dc,37888909,d943825a,9610e37a,362549f,547b7c7d,ae64a27e,c34290f0,b4fc5fcc), +S(af09a9f8,3a21b2fd,69ce14c5,495c680e,df18e426,c1ca5a1c,af56246f,d6ea5bbd,8eae43ca,8e591017,62c4cb02,9e5cacd2,58f0fdb1,ddbef7e2,c5765208,107c96af)}, +{S(4a7f72ed,ebd8df1f,13db15be,3ab296a8,d67edee4,37965f03,eb501205,3518ddea,1f8c4dc1,2d0e59e7,7d30a326,fd4ecbf8,aacd5fb6,7dc7169,898a9708,ac46b972), +S(c4d4f8d4,949d1ff6,559925db,f4d34972,af16062b,d59493b8,b1e0d546,c2870874,cd7f93e6,c0ee3fdc,4267625a,a6620540,4f6d80c3,d0f7210a,ce6b52e,c350706e), +S(773627f7,dcc56184,7eabafa3,42fffade,325b8ee2,a96f2f77,cbe675a6,2942277d,fb0ad731,9bff4c9c,270d93d1,89a4c380,218ec9df,1f564228,641ab35c,46526bd6), +S(ff443101,befd0bd9,e1914864,3eceea06,b9cf711b,1405e3d5,3883a29f,906063ed,aa1b7d9f,59cbddf7,bc1ad03c,44c4295e,efb406ca,7960c683,eca508d1,b2a9a2dd), +S(cbfb6813,a6874b65,9234e866,c2875f70,e45f9f76,3d634752,3f86040c,880a2e56,ed85d1a,6620c1a4,85ba3038,d2ee6590,4e27206b,eaa531ec,1eb5b886,8232cbca), +S(4e85c77b,27788563,aaeba139,975f7125,f3c933b4,8d67ba6a,2e964243,bdd7bb51,200a9d9b,3400c87b,1fb98422,3200aeb8,e6a5af1d,58c061f0,d059c0b8,d431c08a), +S(d58178ed,f0ce32e3,39a524f7,ad389f7d,8817f41f,ed782612,45218816,2a67d4f0,4840df81,5dab9596,93f9284c,54bdee72,f4861d39,3944c648,ecd76ec5,6dd3225e), +S(670f8f7,9b66496d,13692558,d56d4cd7,a1eeb0d6,9e5133ab,4f0a064b,7152fce4,1a72206,6f530586,927c2e39,370d11f3,e251bd9e,eee10303,406b7592,716333d6), +S(10b41abd,ed4de2fe,b7a40050,e61e5982,89a8cf3,6eaa608c,f2a82c63,5788f1d0,532d168d,680e9c74,4d5111da,6aab902a,9a0f5283,7836b9d9,585dbc8b,1a407de4), +S(76abd21b,103aea9a,f04b4040,297894ce,a501474d,9d38d30,8ed02cc7,137bc7c9,b5a432ad,9e92935f,7040897e,3b04152f,693c5f2,cc1e1d53,2c33f70d,185318e1), +S(4335e10d,5e4f02e6,f1b58a0d,ffb473ec,15f735a3,bf96c140,50bae78c,37061db2,1301143b,1f29f122,afcd0230,d46b6b38,b154e589,92b7eeb4,16088968,a7d57485), +S(2b3966f0,7e37e771,ac4c68ad,b8eef3c0,977cb895,2f47676b,e658aa86,76057f67,5382a6c5,bcdd1a01,6d79d817,80faf650,c0a486bc,ea8fb592,1cd3492c,42c91c3e), +S(f7738800,b7fdf237,dc7f03fc,43724011,8b53aea4,4d7953d4,276f3b4d,bf5c0ff8,c1de7924,ef8dfeed,c4fb409,f1a15d4c,5e8ab42c,90ea9c92,867b5b5c,f2921605), +S(5cb07874,ac4ffb86,2da619be,4c8fa38b,e8b261ec,3ec73a12,cd4cf8fc,4f8d5dae,549d1896,4931dabf,ba4553a2,461f2660,87733454,ea8eec6b,f671e3de,60c70340), +S(5cc85d41,7b2ae9ac,dedb1b44,ce78d8a7,8f56b878,1a4b3af6,635a55c1,fead3be7,66a48c79,301e57d4,54cc8644,d2e778a8,45d85762,2c10eb98,d77eb873,e58bbeca), +S(f27211c9,a067b01c,7fe7fbf7,7b5d9b0,eb0f2475,9d541457,6eb24ba4,19fd3db8,e26d28eb,89f7b518,e9ae0b88,fadbfb9b,641d3a44,c59c6f93,ec28a541,486e041e)} +#elif (COMB_BLOCKS == 11) && (COMB_TEETH == 6) && (COMB_SPACING == 4) +{S(629bee58,a391595f,eb20c534,4933937a,cdb2eba1,86d49f8b,845c1b5f,4ca87182,8dae4162,73c6c068,2e2aede4,76efa86b,7612c07e,f72070d0,dc4486f1,47e95085), +S(6fd5e13c,a94b874b,28cd574b,726efdbf,143ab108,1089b846,7b5b2ebe,6c6a3c8f,4a4db306,52c9772a,868b2859,57c5a005,d83f6afa,6e65d87c,700da998,ce651396), +S(609b6576,191514f4,83f5b428,500cfbaf,96871b8b,3348fe5c,1a131768,bb266b6f,90abb9c1,1bf184d2,8dbc424a,bbf74eb8,de4e0582,2ea5dd93,7d1e8b30,e5f695e7), +S(b5ec0263,27cfd922,23a46abf,a755e6fc,547806ea,333666cf,a43865a3,f4ae647,143353c,cc733d02,617f7764,7dc29c65,67a2e245,aed27120,e5fc11b3,95ffb9c9), +S(ac1fff6,cd869ed5,ca920544,1ceb990c,ce304998,10e27587,6536dcd8,1d4cd15,67a7a012,3e5ea292,85dedf0a,9f138b80,58a1d23c,2a233c5d,783bec39,b6482126), +S(c1807552,644130a3,f9b8aea0,29fdccdd,59e03e27,ff2cb1f9,9d13cf0d,42da7b13,85e99587,f77a25b0,bc64b882,bd279fa3,5be0262e,c2f5253c,70a43261,bd1fe361), +S(42919187,2b3c6877,c3b91266,79266e49,9fa37a8d,74d094a8,8c4a3638,89c2717c,1e4bd2df,a9757d42,285cca1d,856b49b0,ad481ad,828d826e,8921f744,7e04d6ad), +S(d4b10124,283afe03,4b278e5a,91daf61b,be608417,fc845e1f,9b9f52a5,43659f2,fd070859,75e2bad6,b34e0396,47b81a87,cab9fb,fdba802f,6ae3cc8b,67cc98cb), +S(ec4c2c4c,722a54ae,edc37acd,cb6ac490,3077bdf6,3f2c145c,7eb25e74,87c046aa,327bfe37,d745283b,a385dfd0,8e30b61e,2b4e5499,4432be41,fd3f0d31,c00e9ed7), +S(559e40a7,e151eeeb,46442b86,aaf4922c,12030adf,7279bb2,2bca24c6,67566a05,5483756f,60d26b97,82033592,cec21681,c5b5496a,c47f600,2013e5e5,f2ea82df), +S(c1d2e92,19c0138a,9f0a34fd,acc92f4,eafe13cf,1c004b6a,3175133d,6cc7bf12,8fa653f2,a20c1262,be59c7db,20f12579,b2adb1ff,54d84ebc,e5ad4116,3d2ebc23), +S(1becc6c0,e4861825,576624e4,fa622c01,139d9cb0,50c12062,9b87ae6b,9622245,d8516472,656ea10f,5b23839d,43f64e,85fc727b,faafcb6c,fc9c6e89,bf9c038d), +S(c483c2b3,8ceefd35,a9fa9e7a,da242c,d618cd6c,8b3bcb62,e39d68e,c1effab2,71964aca,9101863a,d7c865f2,41e814ef,3c20face,f46246b6,4a742026,471b2495), +S(3487162e,40c7efa6,92bc827f,9af9121e,af5ac549,b4ab6585,6353d699,a94a3783,f5b29042,28833bd6,e3ce0deb,dc0396ca,42701752,f930f437,d042cab2,8f135c1a), +S(eb3b21fa,f733f15a,b94ee0e4,3378e9b6,47571aff,d69292ad,a1b107c8,ad511d5f,cd95b4ad,b8768858,cb750cbb,4fa64523,6b6fde59,ceb71dd4,73a7fe48,9e5a2304), +S(21c8dd7c,34d3f333,758d1d1b,72748fe0,8695af46,3d0bd9ad,e4a6498d,1d01e9df,634d8671,7b885f36,a54b6691,35c3c026,667f3cb6,f2577701,beb0d3bb,84f07940), +S(608e33b8,14998177,5d78e286,d5c6436f,99623417,4e887da0,a95274a0,d120b57d,5d094ca1,181f8dca,87d1e043,f798bfaa,f1004edf,a470fce0,7ff8b124,328397a5), +S(f77710b4,dbc5f7fb,ac6b015e,956ed26a,6bbfb540,6a931a30,d4215aed,de610c7,7508a762,a7333ca8,ac244d6,47e47647,c62c82d,387d8df6,175fb563,1de83d54), +S(f37040aa,b0347fe,976d5980,cbd83db5,4d8cb90e,7f2d2118,85159911,af769d61,df228dd7,67fa0d5c,d44c3f6d,b09e662b,99faa5c6,688b088d,949ddab1,6f11e42), +S(7bf929f3,25374a1b,a0cbaa50,db47fea2,a5d1e3f9,3c34bddc,ea5c2250,d8252071,8fe2d2bf,b23a6755,50f16760,a6511ae8,4e4d316c,45d7cd62,4411ad3f,c72805c), +S(261bc0f3,a69d636a,b82248,6132bf91,2ab7ca95,e9a4925,b3f68bb4,745ee63a,68f52f7,df1ec349,77856c74,7b280907,cb3d456f,988ff7a7,225c4ace,8457a804), +S(60ef138d,e7086d09,711defff,68dad211,88d7f878,d616efb6,dbd3d498,5b730243,ca7c3297,3c56b178,b0cfb8a,da98748a,c3d06cc0,7fe050d7,3a6a9695,52500f8e), +S(8bfef3d6,4be90cac,8b83bf20,906b4277,75a6d982,23d5141f,b74e3851,50bc5eec,ea8b6b4c,c7c8d9ba,809ca811,3621c72c,b82006d7,81ff5f25,32010fc9,57858324), +S(9ca85f3d,4ba47ab0,e9fc0a28,74cd10a4,a8ba9aeb,ff319405,6140fea9,6e395ff3,41182ce8,96554f45,93768fc3,a656981e,69719f05,5469f9e4,ba79de22,bcfe8a8e), +S(38cd0c79,437b1299,9567999a,f54d4f8e,82a6354c,8a93a5ef,56ca2ff5,8a1ce180,c96f5ed,d78de5,9f560716,82b60b13,f06de5f9,49206258,80544bfc,73dfa76a), +S(be37e05b,9369b159,6b390290,3eb8fa0f,f221f599,1270c5f0,47edf62e,a1d0e6e2,4fc860a7,1fa69a27,fbefd8c0,906fc68f,4713fa2a,b37aaa2a,7edd3c8c,d100963c), +S(aa640e99,b091512f,85faed73,a3ac8ede,ee120513,b661f812,9a046a74,d624aaaf,dfb48ad1,a01fd508,e5652406,b681cc9e,13d0d600,68411dae,72d68061,6f6b94ff), +S(d08bb931,f008a1a7,38a16200,9fbf1ab3,d3d455dd,47f45cd6,617e81,8b8e0245,18d92218,21c9a2ed,bcaa5d26,2b7aba18,1f7f1e,7f2007a9,ec6f7d18,f038d723), +S(4e6ed1f6,c39c894f,eaa53e1c,e115fda,75fecf8a,55794628,d9a2202a,9dd5c719,1bb97d73,2e0e137c,e9c94d4c,763f9a6d,e1496548,904460d,df1c3a2f,73b66c1e), +S(867e83ae,610a24bf,401119d,8e1af6dd,414a7161,52b2ffdc,50f71f77,2fa8409c,d5d21ad5,ef365994,b3ad0533,92df82a5,6f677cb3,8500781b,a769dd50,1f6d235), +S(6031361c,6dffc505,dc7e1887,bc75c1d9,5a9db023,8b7240e4,c254f855,b35686fa,b9a9a979,c6b8c576,11eeb783,8b4ac2ae,66506bb0,a203fdf6,3efa9b59,98c7643d), +S(8502d0f,34684503,68784822,f4510c5c,562ad30f,be29a792,f0667e83,b6f95773,cd0e6511,763674b5,57fac9f1,bb62f9e2,3163a0a4,cf08cd52,a6d10064,d8b02ade)}, +{S(840e41bf,13203a96,f41ea041,1ec034fd,db0dac3d,53b6bbc9,4f8a3a78,d0371235,71b51550,a79af319,56c9b3de,fcb167d0,c3e318eb,a852eedc,78490dc5,fdaaca85), +S(5678a034,a24a1607,d78036b2,23eaa3c3,845c9f9e,7293f656,7390354,2f714d5f,57f624be,ff5d1774,c6962dd4,d14cc565,acae170c,7aaf8c6d,b0552daf,e3bdf48c), +S(722012a5,57ed9c9f,9d737a87,39954469,ca12ab29,9dedbaca,507c1259,7a27c6f1,6c28881e,a0e62453,80d73a7f,499f05a4,d9a9c04f,c2ba11e6,9fdd0b6,7c5d5ee4), +S(70c638d9,3eeab892,8bccf1e4,82368eac,a03ca8f1,b30f7b2d,34258539,8c95c014,f8635082,3dc2a200,67dfb293,891929cf,18a810f2,5c85c169,159a4b44,b190a029), +S(2ce4a530,b5f6c77d,c0c4d891,6e89b24b,c25c04c2,723842d4,29300f82,5e260458,6f306154,4d1195ea,98b972e,91a962e2,95a2a4eb,9be03949,a789b01c,f61dd705), +S(89e71182,851bb441,c0af4e31,cad89dc7,3947369b,fef12eb6,b1dfa71a,72498c51,20b7ffd5,878718c2,2b5bfdc,ac422794,63aac0da,4bcdec2a,8f3b538e,3a9f574d), +S(f01f06b8,da0ba34c,e1045e83,adb95fbe,b76f134b,35235539,6b07f8de,9dd25869,afa0fb5b,45ad1f24,73460f17,5ff4bfd8,f162262,65c423fd,ebd92bc1,72f3aa7b), +S(f0c217c8,1dda2201,1f46648a,e096906d,71fba006,1b4dfdb9,85dfe59c,9d8f1894,d5ddd6b7,bdf2a6f6,cba166ae,4c01c60,b012c9ee,ad954a46,6f631f9f,928b3fc), +S(bd9acff2,87cc2a2b,396aef61,b0937a49,c43a2366,a2c3c461,c1283987,a7b6f53,828de0ad,b9067b2d,8f8fefe6,ce3a5c94,e7d63ea1,7c891d2c,5f266e8c,a5fac116), +S(ee314d97,2b9c10a4,fec9f8d,ccab0015,d4923e52,d915eae8,b319911c,7a8fe379,82057aef,ff05c496,ba8b4753,c4e57832,aba9a724,adf70a9f,1b3765ef,952ab52), +S(d39fa7b,9b87ee2a,aa32454a,13470406,c8024c39,cf387143,3364de62,cb94c103,5cf1309,530f9e09,c9b38ad9,3a778ec5,533f60f6,4a42e31,1cd97c2f,c984b9cc), +S(5ab1a07e,5f6aff68,16780e5a,23c9faff,b29cd7d7,5bfb8984,4834fb6b,c6b34a14,deac47fd,6567023e,b5ec7a94,a0133bbf,158c0425,c0a6d288,23558986,314d54bd), +S(b1a4ecc6,94bb5212,98e80464,cffacd32,331ebc7c,4d545141,a129b522,a4818830,9772044f,3722ec57,d76a049b,2afce2b6,319f0bbc,b17c7f06,175a288f,3ce3534d), +S(56015e42,81aed744,a0859e29,eb913a7c,b44ebd39,2ed8c0b7,1eb42f9c,9c93c8ba,8f973650,45f7d8a9,24a276ac,20056895,fb2b0aaa,4b35468a,a51f41f,722b9d33), +S(7d99a5c5,21543229,c8f9c7b,50dbaa64,b200bf86,47c71b35,a0105dde,2b3a8e0c,eae09ef,3ffdec8b,9a30291c,244c0a72,6466c26d,fe2c8d30,174f57fd,ec6aba60), +S(ab7d21f9,1e7dac68,afd6e4e4,794551d5,55a9f42,59825109,5b25652e,946ebdae,8805a806,710ed7b0,fb99ff30,130c074c,6a0be3d2,abe6e155,f9c07496,f8b92454), +S(b31a5f85,d65e5200,8f5261cd,fd6d36f6,4b2a1f3a,6f08d7b8,defc7e84,21d0f7db,2e6d46c3,3733b3b5,597a133f,7459ee2b,570ba333,4d1e7648,1980dda,1aa8d2d3), +S(30af789e,850c8ef8,9eeb226b,27786679,442a9a0c,35cb7337,98345400,29220fc5,f6651170,c83e24e1,eb6e8da,ffa0b0bb,a6c53676,72558d44,c5b77176,3d9b5d7f), +S(8d87f808,98fb8007,ffd5093a,bc6bad2d,23e09e90,e6967031,48d5418,4c60e0ae,3d14332c,21df527f,a2e98243,d3ed4bd0,6634d799,9f62efd,e8d6c919,8ed716a3), +S(a961c219,eb9ea127,205af30d,909ef732,8cc599a,b2080966,f615796e,1126dd98,3e235ae0,37b10074,32e5cee5,56778856,1d552e3e,bf40bb82,5b527cac,8e1e5b9c), +S(b9c2de21,40cea728,2aec5293,bb77dc7b,550a72c8,84389c05,310651bc,7570f2ea,74171cd9,4a5683b7,5bc7c5d9,b4c8fc10,1fecc3b1,b7349ce,840b6ca4,877fed21), +S(cd041ff2,e8191946,8fd7ef0,c33021d2,9533cd75,64772252,c686f718,7e33166b,3f54a9af,e8597bb,faccbbd2,9280e60,93d31bc5,b366aff2,2c95e21b,fbca6041), +S(adfce0b5,8a9cef85,e690b84a,c7ccc6,8f5aa4de,ada5e265,3720412b,e1f19ae,8ae2dcdb,c6ce83be,825593d6,87f9afbe,a88af079,564c60d5,c9b88898,897515ea), +S(833a50c2,cb5507c6,60bd450e,cde341c9,64f2809a,e400215,c52dfaa0,9825df96,de85e216,493cdb4c,4541f720,201f4c67,1472b6a,d61cf8ea,3cf54ccd,a4584b77), +S(3475027a,628ea423,2d689d70,d45e975d,39d62303,282b16b,1f94a427,3d7ea746,97c3052d,9270df78,6efbd2e7,beaa58cd,f864e28,905e3ab5,507cb9aa,e3c69160), +S(cbda2707,e61d9e40,124668ef,7ed83973,dd293dfd,221396a8,d27e7aa1,392edcb3,fd5023a8,af8eff08,f0e3c8b9,b6a22a99,b3ec3aeb,7e0104dc,1f8409cc,d83d8a02), +S(963722ec,aced2105,2bf447fe,619a8532,dc78816e,2e17a111,3ffc601d,9bec0381,f31feba,259f7d0e,3c326c69,53aae60c,1e0479da,5ca839ea,77c6f1a4,9419172c), +S(fc531e1d,49d2a984,83c861b2,b299b8fd,b26831e0,3bced6da,5c4449b0,18363be7,9f9cc9b0,8d72ced1,998c6329,a17695d9,c94cfc76,ba9f6943,1c5dab83,60f2942), +S(dab255f5,b47d96d8,ec5272b,5cde4ca4,33070920,84aa4866,d53b674a,330aea2,feeda13b,a544f090,b790514a,42064cea,509bb3f3,9dbd4567,6bd75414,37579d7c), +S(ac5b161c,fcc42998,71b49d1f,8cf35bd4,dd6bf98e,5f84f2f6,420bc363,b9cac257,4511d4d3,1fa26d7f,e56f671d,7467bbd0,41358b36,b60775f8,65f7d491,3d17b685), +S(b62fbfcc,2aca0706,b0fe67f4,ed5d96b,4a65b048,f73e8f4c,9782e1ee,36189e31,6549e8c2,f77bc824,4e1a90b4,e42ca64a,5ade1768,a0996d69,8d7b047,7bfbf862), +S(56938443,5e509000,5cf3dd18,ea629078,e15097e9,da7bb5c5,737cfa0a,a40e8818,f86a1815,4f379054,11016994,9b2eba6b,477c32b8,b68091a4,4b14990a,5e8eaf92)}, +{S(7c028bd1,75367939,74871a6b,cc957d95,3813331c,87ae606c,17aecbdf,a704ebb4,4fea040b,a0ef0319,91ff9b8b,7829c0c3,93895439,d506c5c3,1a1a3fd9,e32e7e59), +S(24e966d0,bf1227ca,11eb8fd7,8dc5369d,2bb9b681,927990b6,dd02b948,fc18a169,72b7fa7c,f929a6b1,c556a372,4149a279,8d57f504,4b50a1a7,922cfddc,17308ca7), +S(a2b7db3a,265b30aa,94823577,6d5ea839,c4fe564b,97a5e3da,313f7fc4,5de617c5,5e895546,a2778162,4a91ea4e,c104c911,85f3e954,f8378fc2,bea41a3,f1cc9e15), +S(e365c695,449c9976,cb67ede3,325d9229,ee526349,e6b255f7,f4e72184,6722580b,eff99cdf,a0920505,ac37e46,b812d47b,31a29113,e491208,a19e3edb,557ac2e), +S(c3d90905,297c3a65,2c6c3d5d,915cd9c2,d741f472,4a47c8cf,35e5cf3,cac9dd11,8e9ebbd,34a7dd02,24fa6e33,193cdd72,4906dc81,a5aa41ee,4a34d3d0,4b2ee5b3), +S(6e4e23cd,ee4388d6,e8b61f8a,af7678d1,a62b3e1a,3385d278,895a02a,de4c9f00,f69b843b,ae39cf41,11fe9b99,a0287057,5695421e,e1ea690e,2e76d937,e7e32c01), +S(92eb38a6,3743088a,39b58cad,4eb4a27e,a8b08c27,444d704,6d2aa5f4,89713217,22af8d6c,d3567a6d,cf7403ef,e0afea02,48ea4266,1577005a,9afb5f2a,19611864), +S(b3c84323,e2d022fd,d2a80d07,203f4a26,f5d32dae,62842072,9663a994,3a829d08,9a899de,82329d94,83b88e1e,1bce53ed,8714cad4,c68cd491,1b71bc0a,e3839821), +S(daae5199,57a6002,8958b22e,6dbbee20,c4bbd8e1,7ed589e,b8528f35,7a4dbb40,afec8a03,321586ec,ac38e941,7fa8e342,f0542193,59decf5e,56479a39,c32f92af), +S(7afb9a56,89fd1344,cdbc5c72,62dff7b,718c2e47,a6e19ec,665af795,86ed0161,d1c2c9cb,60a191a9,a3db7e20,2ebc2eff,444bbaa8,d81ba086,6f8825f3,8c765f53), +S(8d0c4a2a,e72b54c6,236d997d,61a2a24f,ddbd39c7,ee16f1e7,d7c45b22,b4bfdac8,15a58f4f,fdad9e3f,b4d33c7e,170747cc,6a5abfdd,bfbe5814,ef0c3611,6a0a9e91), +S(24d8c0ca,53400126,347e67f3,72f19298,595b6d33,76ba2f19,2fba6dd1,7b57bda1,7c01404f,bd316814,f10734a1,559049ca,d6f20e90,d6b13ed5,f9542630,db77f9ec), +S(4c2b7a58,87a49df4,f98cfc72,22fdd832,362b8cc4,c5f4fff4,d0a20674,c9749bde,c2a1cfcd,e8636288,31a5c450,fb5cf552,c76e581f,9274e5d9,888a3a68,c37ca349), +S(2028e381,f42cc2f7,a8829308,bb72881e,94e5b54e,3331d848,898ccabc,bf971cb,16debea0,203f0709,d9b55b0d,2b8651b5,cb085d8c,8f56708d,c1fe4d33,a616dfab), +S(d11e0753,f72b7c4e,641ed50f,84dfa24d,a0baea77,98fcf062,8b2696ba,a7ec2529,55af37fe,88324646,777387e5,a9b18059,ace20e9,becd7488,5e43fee5,fa6809e2), +S(72309865,b8a1a6f3,9d6d561f,43ddf5b7,f2d022ed,95df130b,2563eaff,9008a95,f3fca0be,3ce7d9eb,e1648964,58eba87e,934d000b,a535f223,868dae11,dd5230e), +S(adca4785,cbf38a0f,28de7b36,daccc761,89b8b918,f3fafa7b,abbbd9b1,4ed5485f,880d76a6,fbcce864,657edb9b,349f124d,1b22c7af,2b0ff833,40d7a0c4,84b49de0), +S(bb43e0c0,93d58c6f,3946e58e,4727d7e2,d223c84d,513c4e2,222406bc,aafb03c2,c00f7dc8,fcbd55b3,6a95f2f4,a3a07b7f,9599736f,af099a69,e2fc2630,a2aef1d5), +S(179eb588,d1c7aa5a,24e51f5e,6d86e4ed,2e6f0f98,bf956b71,ec1caca1,b7f775cf,42f461c8,a784f643,d5a8682a,6ec9b470,455f0ab9,f269140,b1ad2376,95f64afd), +S(9144fc75,b00f8608,714f027,16b30575,be19dc01,d3689e8d,2665d967,6a077d11,b168c324,7dc6c31e,8302b6df,a2e7c053,dd849538,f9d45b87,14d889ec,cc789704), +S(d6cd2a7a,b7253b86,34231eb3,2793f062,bdf103b2,4fade912,6206e745,a3b429a7,9903e507,dc5e3a61,d73fc83c,5c4ba476,6ae92655,9b208369,bee55948,4bfe444a), +S(264845ed,623bd3f3,808ca51e,517def45,1fbc237b,e47e3ded,70c3769b,391a9f83,cb5022fe,3d535f4d,192e73d8,5d9ede23,78e0824c,e560a97,d53aabdd,f8717377), +S(2df9621c,cf3e67da,54c47ddf,81e3ba7e,7b50e713,cc7d08ac,d64f47e9,85c4f334,8058f6e8,139d8e87,cce4a389,c470e3d8,45da3537,ccead4f3,abbccf42,a5fcc49f), +S(ccfd6c4,c5966144,32d2efc4,1ccfa0eb,3e0b44ed,a4558128,c3e4d68d,949a5cac,bc77b87b,5f50d3a9,6b28d5cf,fb371b4a,36cc1360,15c548b3,f98d661a,beda8acf), +S(4e2e6052,cd35d585,6531fcf1,73bf124d,3c569bf6,6cc54ed6,9a520d42,cb836296,6381d100,e5d9ae50,f1821122,b8e91a5e,f365edee,556fee1c,2fdb6d17,3fd29c65), +S(6603d715,ed0f8725,7d9c3f29,cf86ad4c,aa0500ca,fa16a708,3168e265,b87d0255,9d2eda4a,6195e2c4,a4576e4d,5d02383,a3a01b2c,f94ab8fd,fef2f338,15807d31), +S(f09ef30d,fade81df,2fcafe31,387ed34,5a8029cb,e93fec3b,eaaeb8ac,8adc9803,f9f3039e,5b73c7cc,cf841eb8,1c15203f,ba192e,9eb39aeb,36f56c29,44b286bb), +S(ebf4611f,cb3a44a9,f9d5b00a,c559dbb5,394840c8,41a06496,bbd2011a,2508cc34,1e183324,9a610584,5d62ef4b,685152e5,c75c7525,c703f81,51bdd87c,6fda0d43), +S(31fc3226,c19aea7b,4845ff2a,ddeca6a9,36505a49,92102cb3,499d66f8,a6e1a3b5,49babd41,b1e8a6c,a728f971,d8d8cb76,47cdb94b,89767a67,fd975ac6,93f144d1), +S(be1e37d9,dadc4b4b,7a5ba74d,fb7eb55c,2b0a4fdd,81564f8d,51038afe,f716e3d2,de6f0c3d,b6efc974,975a7d6d,3c6e9d44,a712879e,4e95c612,164273bc,5de1f4b), +S(f8034e14,2425cdce,31e82b49,cde33ba8,3630d1ae,283b8b47,73960539,c67f1652,a302e3b1,860252a5,e7114568,748746ad,1e02c2e4,280bc913,dd4b4d2f,92a561af), +S(21e709bf,369cdb2d,b7f51b10,f0ff56c1,2c1938d6,18419d00,34e57d94,7b83d5e2,d7e09ab1,2e7d04f5,aab3a75f,8cf75876,ddc3cf0d,cb4b9526,ea7f755a,dfe1e495)}, +{S(638b6618,c1498946,75a1a943,8755a68,30d7dd3c,9d8a9f20,d65a7161,9c8b477f,e4e66035,e947c73a,c34a48b,b43a3762,d1038e6,893dee23,cf658a12,190d2a56), +S(4b6ce93a,acd4954e,cf0febd1,fc9a965e,ae7fbc1e,e24a12d3,a4b86573,62eb255d,8cea4838,1bdf4e5d,79e25ed0,1aab94b3,5f00267b,3ec7eeb6,63833507,583407b3), +S(e2a42110,3e8e2a80,a6451f71,b348434d,7d508023,beeed16a,d87417b8,5c7b7913,5fc15b62,124014e7,fa8f95cf,78ce8415,d46a1f97,d88be55a,76431786,8de3d605), +S(6949956,91582c2c,2e14576f,5ec0dd37,65133237,a4e43369,633edf69,933d1f75,5ca8c2a6,329882f5,2daf48e2,e291c48d,febbbd29,9ccc9ff,3ad54ed,33ccef43), +S(55d836af,2dd4b8a5,7f20eb57,6886790e,a3ccfcf9,2a2940b3,646f263d,685f62cd,7cc1ffe6,37781c72,d3cc26dd,9d4147c2,183c8e0a,95b87742,52ac47ac,19db266), +S(442a3090,46bbf3ef,503a138,b60ddfa0,ea4a5901,ae801003,f3f18ad9,9703a44e,129d9913,eff78c49,16e67c4c,cb658784,fa47da35,92ea1c98,4054b371,a275639b), +S(76981efa,29944c2d,9463fc94,67a92e1f,9403c287,dd595292,4860aee4,b78626ca,c87cb5c9,ce93ff3c,23189404,cabf8e09,996c4cde,e67935d5,874c705d,6a7f95ae), +S(42ad08fc,2a1eafc3,d793f04e,304831e,c1bae89,c7d00b24,7785d870,904bef5c,c3913fd3,6b8c08c2,553b9c48,5b90221e,ecdc8d02,6d558bc2,5fdd6ba3,df78ed63), +S(4d70ffbe,efc6254d,cee74a89,70244bd3,384b3af5,8510ca61,258fcbf8,f0c82575,ba3e19d,b022a75b,c75cbaea,84ff912b,867124d,a20e0d28,a007fb74,9a9d1c7b), +S(4ec8dca8,7079487c,adfd516,da2df139,5477b524,df4aa6d6,4db5e206,cfb14b9f,e88e5bad,c8654d60,fe1f8f6a,73328209,63bb10cd,31aae381,ea1b4d9c,eaf9cb27), +S(2e5a47c9,a47cbbb5,ef701784,34798a6c,48244df9,dab1e5d8,83c7f732,b89c7d79,7c8202dd,cf7fb6ec,471856d5,830d59e6,99c04377,c553d835,f64cb333,cc405c35), +S(3ca98150,bc5f116a,e7034a07,628d698f,67cbb8d3,74869ab1,534464f5,5e8ed24f,fad702ec,c6b738de,5b653f78,f51c98d2,1e4bad57,4db97730,58324d1e,12b89f9), +S(f414495d,9093ad22,11e001f8,b07b38bd,f5430a11,72899bcc,2c553b55,a9d4a225,bc130e93,998db229,6aef128a,5b8e5b9,9cf67eb7,713aa7d9,9fc4c902,af660f4b), +S(44e794c9,5a28ee80,f9b64193,9c626a78,4a851a4f,84f28887,9eaec508,1b60e508,b219e000,1b07a275,f63dfb3b,e977a40a,f505be1e,d3eb8194,b919b9ea,70d7198a), +S(35024622,bc17bec1,9c352280,297ddf7f,41654c08,61c3744b,13c74ed5,6673b98,64aece4c,3ec0b19c,cdbc06b7,4eb15704,50ff689e,6c5bafb7,6ae99396,12f4cca0), +S(45c4f36c,ac4c4738,ab216363,e12b2475,50b8ef09,7a986ce1,60b0462f,f8725a58,fb944806,dee59834,7d256885,3761e3a,9ae666b,9b0ee095,fea33ec7,bbce9a5f), +S(20a0b4f7,cfb58bd8,d09d008d,70e7f807,b4fa61ff,65f2e15,f00bddeb,55df1124,7961d1de,e98ca40f,4d09e5fc,52ae4916,cafdd6e,2bdb9f9d,2776239c,a3480157), +S(fa10af8c,eb2de4c9,3c0c2cb0,95f95911,755b19d9,90f17e33,69930d6,6002fcd3,68a3bfb4,533bb5f0,54fbf91c,b771b08e,e388a61a,9727bb7f,a3a1f67e,60b2eba7), +S(d417d7dd,30ebe9f1,7d52edd6,c82d91f9,25d5987f,a6f53b0e,d769a34f,e557c11e,ea89c810,619e32f2,369258ae,8ad8a456,cc36d87e,b45a42d3,83956039,62e437c8), +S(349b002d,ecee0e4,1788a3c0,cabb9ff7,c17848e2,78ef8905,63924c55,52d59853,47583a2e,7ff61b9,6fa168b5,1191b363,efa3e0a1,ce825a3c,5bb04e5b,e403b4b0), +S(4b8efc8d,7eeb3554,b5128e8d,ce20c29,697f79cb,29f61b4e,a2f7ac28,57910bb,e3cef657,7b5c0d2f,dee52c96,b6353073,b099fc9c,65688969,24cd744b,981c5ff0), +S(f356e8cf,5785b05e,e99a2b4,d202b64,2b1e98c2,57741e60,7241fb9f,d3f5ea2f,9079fd65,59d5a93f,91370d16,20ba487a,a8c6ad3d,e67f2c83,a1c335,fb5398a2), +S(bfb74aa2,15e5ce36,97cb6156,c2666ef7,1b579a50,56ff60ba,d3d5e10a,7eb2d31f,3def8a80,ddc3f407,e30d11fb,232f0e31,191bba1,d51a7eaf,b86d7f97,45d78dce), +S(658748bc,bbc75ba,30c969fa,371fc1d7,76c32a5c,7e632201,264deb36,b296ad2a,c173fe4b,14ead07c,2c6574c,8887500b,53f6c02e,dbd4048b,e69aab41,9267ef9f), +S(f51a5ca6,fd6dde25,447fa46f,c0984d26,66004c02,8d402624,8886d0d4,604f6ad8,fd4290e1,7b2928aa,f2e03b98,97252b82,d481c4c5,ad4edda6,16dc1cd8,e7ee83b2), +S(20ef1ab3,491b8d0d,a1565e2,8dd92dff,efcb88f,e88c6c2f,6b100b30,b58249b6,6814d32,7b5b94c4,12fb770e,2fc4077f,fa9a336c,9e7db2a4,bc7dffa4,286eee0), +S(d98785a,82dfe5de,343bea0,d91cd8c4,93344b86,7fffe1e6,efd7758a,90cdd899,37ad7f7c,5783d262,5204bac3,4405c207,972b7fb4,cccc3585,ee152f0a,48ee16c4), +S(3885e910,18a66e64,2d3f0c76,bca6dc82,a6916cb,1e46a858,7aff5ea2,d9390689,20765590,83ba89c2,14be9178,46e40553,ea195c49,de203c9,d175296e,a4430819), +S(c88cf650,3b50f5eb,7bac15fe,2097ff76,9c57b983,1b5d05c9,fbd8dc58,d4a9a746,b6443b76,64984192,e7056478,e9f372cb,21a0c7c0,cfcb0e84,850443a0,25ff42b6), +S(2831fddb,2ba2d301,2dedd58,a3f47434,3450985e,80e4e4c1,646745cb,1abc69d4,1b04e1b7,db84b6c4,882f264c,7bba91d5,2256dc97,fdd22e58,483dec32,5020a257), +S(5e492bf,c9d19dcb,c3bcb9a8,b7bec84c,23c359de,a78aa0a1,e0522232,df037abc,614fe5b7,cffedd76,35d371b5,2d89baf0,55af687d,e6c12d80,b221d0b3,9d03d0ac), +S(bbc64d06,681957e9,685c9864,c5f9bfda,34b4dd02,6b749399,a12bd8de,87f311e7,3c525096,dd6b7d11,26c6ca50,5064da63,f7f6a203,87594f4f,e4ae0403,fb4d66b6)}, +{S(2b00c7db,16887372,753ab219,17092563,8c603992,f501b07c,9d8442b3,721addf9,8e7c5f66,4c2493ec,77cc74ef,d9221235,f26bd3bd,6f505347,39f0fe19,c41b9fad), +S(56b9a3eb,d9360224,56267f52,21ade9f9,674863ee,4bacb7c9,ef0155ca,b36b336e,2e2b1a4d,f6c150c8,6dcfe9d2,e2836579,f82ac4d4,2f8fa4d5,d814b952,e92da69e), +S(ff52bbc2,83bd15ad,523e6d08,873a8896,9449a1c1,c5ec8570,ed532000,5a92aa3f,dd9c534b,e59d3845,a1943435,1a20513d,1a829424,e65ed8ad,60342b38,6578b21), +S(84f79356,86b0d45a,13a1ce22,7e7c925e,d80be5d9,9fd7e671,270c4c35,7254e9ce,3dfe2058,1e91dc25,12c16951,c667fbe6,83192bf3,3fc0bdec,c760dff6,730f82be), +S(db14da0a,86bcd275,71cb9348,36268bb,85c306c8,9ee1b78b,83c247a1,71c7355d,66ba535e,81e877b4,71b0b75a,6545970d,6e33cbe0,ff011e3f,d653d026,f4fff395), +S(28bfbd9e,44554371,74a4c24a,cc65ef45,5fd4d39e,b466e94,358cef4b,b0eeaa5,5f5ce6de,2925acc9,e503d731,d46601aa,7e668001,669819cf,fa54b3e3,dbb98f32), +S(a7b21a3f,a07b4049,7f9f5087,c763b431,d5f04cd0,e7b7e0dc,f9c6c664,df7c6ac7,daf23f35,b903ecc,af4f50cf,459deac9,85d0d008,3b5afa73,7131a61d,8591bf9c), +S(12fac42a,40935aa,e881894d,245b9691,cd1f6ad0,e0481e1f,444e0ccb,6ee88781,c519e0b9,e3c19fc8,f67c07e4,f357f43d,589ec23c,7714f7a0,4347be96,4ca572fb), +S(5c2e28bc,94f8639e,50133dba,9b6c8a35,348eefdd,2fdbc18f,2abb792,eb8807dd,c546b3c2,5f2809e2,7977a8e2,3a1c3ddf,36229f31,434c90e9,1386ee84,b64e8fdb), +S(e8e73382,fbe8b94e,58bef90b,aeb28305,d27ea48d,9c5f6e08,ef47e4dd,5fad6b78,d3529a2e,86240f06,a63ba03b,ce419c05,24d22622,fab9107d,aaf3016c,6ff7fe3e), +S(26b93629,ebe68d1e,878e94b7,5babd663,6fe1f6f8,659b155a,e10801eb,c2cc51d9,f4630056,b3e532f7,32238911,555c0ffd,f4951c9a,b2f45119,cb12e774,aaa2666), +S(57b3b642,431f793f,24862328,dbd271ae,19d343eb,c3b0ca7c,affe4fcb,319d8d94,1d7ed35a,5abc7e39,1858a9fd,b90f907e,6a065648,c00f94a7,75f06d2b,1cacef1a), +S(c2123794,d98f0311,c1327522,1767236a,6f45cb14,8fcd65d7,e0be8d13,2a650953,d5a382f,fcc2ffba,3917763d,ebe0549d,66f358b,d727c281,288551f8,4ecd193b), +S(16789662,9208b510,7528efd1,36036980,994d6c3e,5b34c69f,ef3b86a4,3db9e8f2,217105f8,39b0ae0e,932b5207,e8e7c190,3ea463c5,40c043aa,e4f8b106,97ccc84b), +S(3a0b8ffc,83a1702e,214adfc3,79bec5a9,753274ef,9e3271ca,8ec5b067,a5f3b6cf,2c3de01b,f27dd574,4496c2a4,75a07e60,71ee60ef,7eaf1c94,c257418b,744d1338), +S(482e5ac2,6477feb7,6c848d58,40173d87,1687c5b7,3b2970ec,b8dd69e9,3393f923,dfb3995a,ca5b54a3,b48e1dc,107023d4,dbd7a918,6adf2af0,61f92160,76e7f78c), +S(3869373d,638a30cb,63177204,bfb194f0,2c6ff503,3cb4ef1f,b146741a,f3b495ed,f2ac9f3a,ca159c7,c2ce9f48,e895c543,d3f19066,74f335b9,efdc4b47,4ccc23c3), +S(98c16ec8,54b34ea2,f08aa4fd,3ce1877d,4a36f2a6,4e673191,17f74e5d,86e57f4e,3448646f,c9aaab0f,4d9ec298,8f7c07ef,448888e7,6318e0ac,552d7cc,b59820a3), +S(1b3a4ebc,8ad1c200,2847e182,de7c9eba,f0f7a408,e2aa172d,484bb9d3,ab897b73,b93decef,69cf2da4,5c3a2373,ac2abd77,311fc1f9,21e7df8,5f5b3504,a5ecbdb4), +S(57b5b2d2,87bec103,e4aa7b96,16129718,64780441,fb5ef847,19f16d,a1c909fe,2c2d983c,d8c37a7d,653716e6,15756121,9e5ad5ab,25664967,67a0fbd8,e8180c71), +S(cd7e277b,ae1498a1,8e7bc00c,2c299a49,69f6862b,bf96e6d9,f5143db8,7b582115,f9548ddf,c27108bb,38f80025,6ffdc25e,28621c17,c370a40e,5009b968,d40660bc), +S(80615f12,82ed7a8f,bdd70890,77c24f18,c03fa395,3cbea7bd,32a26c7c,260102e7,8d54a3a2,83383d6c,a633d17d,e2f4f756,3bcc3826,10cc1012,3f2f192b,e654c2cb), +S(9b16f5dd,c8c8c8d,53786b49,e2d025a6,838f6322,700fe105,7de6d78e,92281a9e,a36aa3c2,f2034285,76f5c570,63bb1bd7,e6e0410,2e1cd2dd,f100a54e,431ca08f), +S(f1d04075,35ffd40f,2a0b59f9,14ecf368,67700c5,b33e15c5,153fa9b1,c724d36c,22a8b48e,4db1d3d1,28cc735f,99db74d9,ba7457cc,67b8fb39,7b38fcbb,153f7c0a), +S(c252ae6b,cb711704,659c37a6,f425b215,1ac8a4c6,63420eba,899127e8,1d8df3b7,8e9a75ab,c5a2cd8c,d44331ea,b07e5d97,a30c6619,8e382261,642c0e10,8f6d46b3), +S(59f6fadb,4a8a3389,999b93d4,cdf1f8f0,4735b397,9fa5397e,64df420b,85876ed5,c6e8baae,fdeb7019,23a68b71,9c88596f,60742a38,db04d7e5,76bd1b8d,1ae25a6b), +S(3c2e03c9,3f610ffd,db519c7,80c201ce,b58ffed8,ee10e21f,d1610e99,33fd08c7,d339d979,38e1c5de,7492e7d2,d64fe34d,ed889d48,54670345,1c51432f,ec6c829), +S(59d16070,f9147ce5,5bac599e,aaace0ef,24c02ea6,85249cc6,ccfbeecb,a4bba83f,8105bf41,47f22f7b,18c73941,3a85ef06,40bf6805,51c68a10,e16be920,193977f), +S(3aca1182,3f31b2b,a12e628b,604b1010,62c45fce,22e15dd0,8b9b5ef9,a53dc02,bdca8ab2,d2dcab6e,3a98e7f8,7e192c19,cae60952,fc6f54bb,d46acb49,60d51c0a), +S(261e9b93,3648c7d8,d5255219,fd0634eb,112e1dd3,fcce0a04,135b2784,e67b5e32,e0eb5ec4,30b1f9ef,2bd10916,b21f4fe1,4cfc80c,2bc179e0,fceb8678,ff933068), +S(75918e0c,a0f03b34,40cd6239,c108bb72,f293a881,a1f2e9a,73c604b8,8c451c39,7f02a925,80e50aa2,5b786d10,422f1d80,2c42cb37,27f09ff1,1f5e0dd9,bf6a6c1c), +S(42025e76,3c05c64c,311a275d,d6f1fb3f,2da2108a,39ed24be,3de83123,b1c1d1e9,dba2eec,7405b67c,a1915b13,45702062,7bfeebb8,6b90dbd4,87849e5a,756921c6)}, +{S(ef2c5fa8,b23285e3,50d7f05d,bd8c96bc,6e662824,5b10e1cb,4b659bc5,ded5836f,1b37679e,1177b653,8975790a,4d5d2abe,3626d636,1d863e0e,1db5881e,8e0c54a8), +S(a1d5a92c,93df3c75,a06f9c2b,a604789d,fd487513,62d957be,68c033e8,3e202fe7,64c1c00a,3964fd5,b35fb52,b423b285,77c8d269,bb1ffd16,325c5e0f,7be08bdb), +S(ef13ec66,d46813ce,68038fcd,541e5e8,bdbc970d,337d7b5b,9099d0e4,3fa4288,7ad7f4f0,c8345229,96341248,b1455ebb,89aaeb6e,1ae9db25,1b86930c,9f779fd9), +S(aea7cf4c,afc1079e,e61396b6,2df9bac3,bf334745,54af4678,8621e337,4c7486c7,c0538605,5911c893,459b98b0,4be449f1,2e9f98cf,ef4cc292,9975d42a,f460d65), +S(8f082b3b,6476b4e9,ffb317e6,1fec0cbe,8e389041,1fdc87d6,8d4d26f5,44c2e6e3,eafc2bd0,d6570a7a,cf8bb5d1,6cdc1020,456473c9,e7fec1b7,fc6217cd,89d0a2a1), +S(e0d6310d,e5e664b3,164faddf,39c93676,4ddd3f0d,f5e007ef,5293ee35,980ae0cc,de093cfa,ca1033bf,47e88723,4978758a,74b93cc5,2cef48a3,daf4dda9,adc79ccb), +S(2518110d,5d064422,5ead0e2a,5ac8b8b6,b1fb7fe1,55e351c5,1d39673d,dab0f6a7,84f0d6e4,b497043a,95b6af9d,e72cd502,a7b6a68d,ecaa01b0,9e0d8ff9,9d8a16c9), +S(6dc820b8,5db42353,c97453eb,d7d768cc,af9732d7,c261bc6f,8399caab,34cf5b93,30b168c0,2509e2f7,2035f60,8be8b89d,577b6e72,540f521,934fe980,7412459c), +S(bddc1c75,5bca9911,3c9ae05d,c14441e,2c707fe5,8a329f8d,feaa36ff,12771376,8c0087ca,b7688dcf,5a3cf1a3,3c27c7b9,cee36007,3aeb9b9f,d7088623,af20f62a), +S(b6e5ef5a,a84c6d2c,a209d50e,8fa8e1d7,93c61ed9,bfbc22d5,2ecf293c,9489ac13,f76e3adc,a89cb983,b6b670f9,5a7e774a,c015de5,1ba56417,40ac1f68,e3df377a), +S(26699dfe,93788eb8,d91cb601,cae628e5,75e8468e,73f6cefe,588755b8,c396071c,e5f9e00f,bcf6f1cc,cd39ab13,41cd06b0,ef2e789a,17d761f6,6a7a83b1,c036791f), +S(72f7e16f,77f0a4f7,92db2cd0,354382af,34282dc0,7b8cb290,a89a5d60,894e8090,54d32ecc,2cd022c6,c03f1379,657450b0,db9f08e9,6e2be5ab,5233dd84,62733cf), +S(f84ae7f8,a03b60,af9cc359,36f0ae78,96935b2c,534f852,8ad159bb,6c0b44e7,68f4dfc6,20a354d9,d6904bae,67792622,337e3180,ab340828,80bf04fd,f47cc23b), +S(5dea33b1,b5207880,6debbcbf,83ca17db,4617488c,ac5c6997,ad4092a9,8a7bff7b,99976fe5,ae88d36f,597e16bc,6dbbd4b4,547f4dcd,7e85786c,d10af30e,1d81bbaa), +S(31be76bd,4f946e41,7de73037,ceaa0dd7,c6eccedd,74399e14,2ae6fb2f,d2b59def,54ad8748,ef129085,dc3172aa,904cc376,e203fa69,38783007,2af33889,52cc6549), +S(b6124d0b,f603a00a,22662897,8dd0da87,fcaca5c4,fb04ebaa,81a7d13b,39f2e307,34ce08c7,4463b06c,afb03c02,583288eb,7bfa6f2d,3eedfed4,91e31781,dcff10da), +S(6aa4bd60,90bee70a,295c451c,c8af72bd,3665680f,545f46c0,bf5af990,aab5f43d,9c2364d8,25406b76,94ec9db,a0ea2f9d,bb36fb2c,5bda62a2,bec941c6,874e68f7), +S(f72faef0,e268a7b0,a9b00a57,3674d846,c1f0dcab,c9a586da,be318b1c,d2874d8b,16b3cfda,65db0f3d,1b5274cd,20b1329e,61ea0404,1f702e71,cd98708e,28c9307), +S(1d26df15,98a6b9a8,7c0a6171,767539e1,86d51d1d,cef130da,1001226f,87872c5c,f227cd82,becf5493,e2fc7635,6a37bb48,3e681a19,ab4d9dc7,92edb114,3a7b072e), +S(28690cb1,db697840,13e9eec4,d9388723,4c28451c,cf9dd51a,746d1274,b13b4610,d9bc39ef,19228981,a1ead1f8,94deb254,162fed5d,cbb58a76,6d361e04,3d8f62ea), +S(4b0b5258,22dbc31b,1966b004,4d39c5de,f2e16d5,1e032045,f9973b1e,fe83ca12,2db33ff4,3631fdc3,b3608b40,7dd494f6,ae730212,9619ae35,f6ea08eb,51aded12), +S(a5b4e205,462ae419,8fffc1e7,393d366f,c5a9eea4,e98c67ee,1684d63f,cc09aa64,d3c11017,de4ad175,17cd076f,cf6c0ce0,4d3108ed,60eabdf0,935499f9,4226078b), +S(d4f1af69,2a3e9fee,1f92d892,b14eef6a,a0ec1f4e,d4d455f3,c70bcb19,52fa9837,115c7ee,73b90adf,f142191b,eca0be01,7d5a651f,93e2e90,5a36646e,21790294), +S(c275c715,9d6e9757,d2adef47,2ee53856,dcf067db,bd4f380e,892c9832,708d46b6,70da1cdd,853a0dc8,a6a9043,3c319371,25590c9,5807284c,ae168f65,62e4465e), +S(d2e38b27,83156e2a,a8e4eac0,149bf2bd,bc2918af,1cfa2a23,d1c7136e,15dca7b,738a0fe,751ecfa3,459e005f,72b7461f,a4b5e1ed,736420d2,22c5428e,2ec1348c), +S(f8f5b3d,b3659174,e0149fc6,fa747c22,9607c434,8f9eab60,900bfe92,b23f9a4d,d89eff33,94a093fb,549fece1,4e11028a,614cdce2,21d5ac26,1bc25f32,dca3919c), +S(5e266403,e49fb860,e6ed0928,45bc0811,a214a0e,dcd6174b,290ecca9,3539d862,ab300acf,5d8b8a14,2fc9e93f,ea995d2c,d7a2bdb8,6a146f65,2b8bd49c,4e8dac1e), +S(8ff869a7,60230ba6,aa5adf91,1ba61702,17cbfdc,5ffa4018,b8a09b9e,4088d634,db5a5aae,bdb946db,80e4c207,22ce38c9,4921bf41,47eea510,70e5aac5,c592f32a), +S(f3d39b65,95bd5ab9,aeedc43f,f49bdb20,73a211f4,5ec2c1b7,72226a97,a31c059b,ea41abf,9322d733,bb5971ac,194da6a0,a6d41c6c,a0d0acaf,a53e17bd,dabcdc68), +S(18ba0c34,10169914,7f7589f9,179b94f9,daed92c9,287f3468,d283bdcc,d71cc637,b3512d25,c199d2a4,c115bd11,eb53d6a1,6ef16c3d,97be6291,5ff76b76,890ba675), +S(2cf3354d,7f96c58f,3c6336a0,6fa30c83,8da767af,48f89fc5,5ced5b40,e0b86cee,403ac306,f6c3ad55,be1ee5bc,29cdd46e,2e3d83ac,71050909,5f117d21,7ef015cf), +S(5d31d140,f754d6c,5943deb7,6aa4d867,cac81abd,9911618b,82327795,da8d085f,c25f99d0,5bc5d583,a3a72b41,4e5eac5f,c14ced01,98247ded,79ba482c,882bec49)}, +{S(e0ad91c6,6ca95326,d440f44,df91c1cd,cd3ec344,e906d0ef,51fd4a48,31ce293d,3559f3c,e349f7b3,cf66c17b,2c3fe7e6,8ba3804e,438c0816,b68ecfe2,30da18d), +S(d8b8c50c,ae9f285f,d6d9282c,373607d8,5fda59dc,71ba0066,148b378b,37440076,ef83dd08,ddc115cc,24948009,f9eb4afe,dcd65c64,b6ef2194,bb4ddd0f,ece180e6), +S(881fbbf1,a9627bd,369abbc2,edda8026,a61b10f,4161e442,530a5e36,447a0290,6a63cb8f,7e5094d3,c8beba5a,2a1d7b54,bc33005c,efdd5a1b,20d51f74,d00c2fcc), +S(36bc0df,fd1441be,1a4efd6a,43ab9d83,243d44bc,a6e108dc,fa9a79fe,23106f0e,eeec58b7,dc37eedb,4432dcff,4de7f88b,2a0e0721,da2c0a72,eadac4dd,71037ed9), +S(7652c155,c2ca8a23,7680f015,a62c7c31,31682752,a99c4329,77ccfb9d,cb58b03e,5339a51b,36ad4548,197d3018,4bde4428,b38ed983,d624bd18,a5f8c4e7,21871c5), +S(904774bb,fb8b0c12,e2b3f91a,e5a2a0c1,a92971f9,86e29fda,9edc609e,e85b222d,ee843f1,8039e251,9c7b23b3,725ca099,114b4f0,26970111,35ded92b,94445e2d), +S(1c7c82cb,fc14b9b2,cdb3c12c,32df33b6,a08e7af9,df62f310,79fa0710,f28f5f95,93471b5a,17c84eea,a45948df,80c0f56,d8684f35,1aa2ce73,ab84b3c,1b8250a4), +S(bb060f5d,971ce062,427a5630,8f114532,40ec54fe,6479d5e7,9ce81444,27f07927,fcbeaa69,8278eff3,d4dad904,836c0233,40a866b2,d8f66774,70d1159e,201501dd), +S(287c5b8b,8dc168ea,197200ea,97c4f63d,db0b620c,7f30d623,7934f856,a558438a,260630e6,ce310eb0,366acd78,bb58f4ef,27fe4836,edc8ff0f,5d5ff987,b659bd20), +S(7d4c5c6a,d6bb0f0a,47b45a35,1264f4e6,a81ee0b1,65a7e665,4b226c95,feb59dbb,e89691f3,ceb4c57f,5aabc1b7,4acd9aef,41531851,b41ec1c6,608f16a2,2243ab5e), +S(ff806f2b,9eaea4f6,47d85077,d8aa5052,9d4b96d2,1e0b31e0,7c86b14b,73b7ab4f,9acc2f77,a994997c,7a2b1aa0,79c0b5d4,c84f6715,e4a50e33,628b871f,8885ef9), +S(3ce795ba,1d91a9bc,b0260654,3450ced8,c94184dc,8a41ac5,e1b84856,e88927de,3492e696,cd1ab2dd,587d4707,ae34fd67,3ab7902c,d0c0972f,ef419795,1ad88a1), +S(299ad528,afa3f36b,c80a757f,f081a8d,c4a6ddc2,d2b57fbe,1e3d361b,ee5a5d8c,9fe823da,74eda2f,266a8e9b,331d511b,623dcd32,ef9ab7a7,f1d1cb4a,7e6fa65c), +S(bc4b0549,16177aa9,b52b29b7,cb91673c,9ffce4c,7d0066b,e4249383,4467e3b9,55bc6436,7db68687,e699cf6c,f2db9dd8,c2b9a438,8202fef5,11acdce0,ab06f969), +S(a8e8b02c,ff5de02a,9e6652cc,6fbe41cf,6e87ae0a,abb14ac5,a178b3d9,e697d0a1,285d4af9,405b03da,c57c993e,4b40df8e,82c6979,f8de57ce,4543b7ef,3381e0a8), +S(e50aa8b6,d7dcc055,4f406959,b056dac5,21a7842c,ffaf09a1,ac24a3d9,8aef5228,46656395,ee84d061,a9f5788a,cb05975d,5ffa5fae,edced564,1f81b5cd,2491c23f), +S(cb516899,98a214c3,c31e4f2,692cd7d,fad6f1aa,eb8afd1f,b29c23ce,429c224b,2292b8a4,5a89eb80,167238ef,2027f975,98a2aea9,a4460c5,3646d088,82403c63), +S(ded04c06,74c6eb16,557b5bed,4b6703d2,cc37c6aa,bae466e,ee7b5665,6693c3c9,4f3ea70f,8e75b02b,76934cc3,645d2af,eee8e9d0,8d100117,40e8a16c,dbf01113), +S(f3d0a253,edb74436,897e6cc6,621c74e1,30457b41,e0690b6f,7b2a203e,8ccf8ac8,89cb07e0,97495bdf,403490fa,d58eefe3,e79ffa33,1deb5cfd,2c548ec0,8771be67), +S(d4c66267,aa73ed55,bd68fee3,2a166a4a,4ec660fc,4cb13e18,fb6ab0fb,19a5f330,7c2efa2e,4509b221,97589483,40b6c74a,8ee2b5b6,5fbb794,7f838c47,ee03e2f0), +S(dbe9a638,f262f9a4,b3a8955f,22293feb,50ef4b32,20df0184,f363a373,d7110981,4c563e83,5e957756,5e6a8996,97510c67,9561972e,5601c1cb,2f2f789a,c1e0b5dc), +S(70c7c07,1b1e6fd0,a97b55cc,5ee34297,166f4d02,417a796b,eadcfd43,96e1b338,b5c49a6e,2ab03e55,f4755f37,e5211d4b,e23339d9,d464fd28,6781bb29,56db23bb), +S(aabc501c,6d52961a,a613fe66,96f0bacf,fad74fcf,8386cbf8,b18704bc,a1392ffc,cb72ba86,70bc3f7c,85a00d3d,76b11596,6cfa0fc7,44b31e01,9129da9,a5b04b77), +S(47f72ec6,e7820788,f0f7814f,aefd6e2e,af5d90f3,f877677d,ae72569f,c6a2e8f5,6709731b,ef2dd880,4696a6,a0661d13,fe579704,5e0a9bc0,e5fdc0af,789c5830), +S(20026251,d9413e42,47a5884c,209b144c,98e36f7d,8ef3f56a,68efd475,8a2ba8c6,9c5531b6,94ba0d24,a943d0c0,94bb623,75c798ca,c9716181,a9d659af,2acb978c), +S(8dfc6293,9b300c9b,fb617d23,6885f652,424b4f12,d04f8bf1,151d1ccf,935e445d,9a519433,18e94107,5472aa9d,6ec3390,59bd3bcb,bbbf6937,c9290e48,9da25f8f), +S(afef3520,3b558495,6fde0eff,5cfab48d,8fb08806,3c1d7cbe,d7e352c2,9d49176f,a764e6e7,bd0c8fa0,8a6f7f30,aa38d7de,fe71773,fb7ea484,68b3fd9a,8adfd650), +S(354c0a98,1628dfff,8be8ede,ed809db4,bc39c686,39a26828,ff28dd47,90801c46,8ff40299,d607036b,acd7c0ab,66a102ab,38f8d3a8,a271e2a5,20b43cbb,687cce6e), +S(da2e7eb1,1a1e66d9,5001ec4,f7b66c1e,d9f7d0ba,ea3bb326,672b9069,5cf4bebb,cbc1c7da,b9bf7e0c,dea9297c,5f45ad0b,9c4fb093,318b55f6,1e4a8951,726c4021), +S(6f780994,d0662667,8fa74156,4232bafb,b3a7f54b,a5b66507,9df32545,c192c3fb,5f11f0f3,af1a763e,4c9fdcb1,1e5e57a5,6dfe0d0f,f27535b4,4343a312,90e375e3), +S(8e28948c,729c1438,5bd09316,31ed3eb8,7acfc5f4,2a9eb4f8,afa50362,33591cec,2c09fa1c,bf0044eb,a78ae81f,bdbd4271,2a89ffdc,f7d476af,881d29fa,2627f250), +S(4011cf05,a85ef14f,1875cf3f,4f78a51,a52a89bd,a8930a4b,8e13802d,b85f319f,35045b10,45c4f71c,c762fa78,5b8d4daf,aa2a1c07,ba37d82d,ee0592ae,ad807810)}, +{S(9089bcb7,1c1559bf,e17f6c0b,91fc098,c63785fa,18a42d69,798b063f,a0930175,de229175,5e4ebf17,1047f79a,37d81b9f,9004a7cf,df747589,7365e174,ae367969), +S(4d1caeb3,41f25459,3b06f715,9e9418df,e29ee076,76c26e6a,51d8add2,5c70a5d1,bf773e4e,4151d17,650aa7ed,1d6a5505,2d622264,75c50f31,3261aea2,cf68dc37), +S(b0760330,517c0d66,2571cfae,830da7fc,a7e0d86c,1ca7f75f,5150f625,db50ad2,d8d10ef3,9c84bc13,32c2cc01,4d4df0fb,45e5c546,1849fb1b,81b7fdd0,7484d35b), +S(3db731e4,273e5b20,2de984c9,74b4112a,d0feebe3,7bb0d2c7,db38c7a,21bd8c67,b425c1d3,46b6a61f,2893a3aa,a243d60f,5563cba2,40018cca,3f80925f,71f4f1b1), +S(3a74a50d,cfbf2ff2,5c99c4d0,1a13a917,9f510c2d,eca1d5a,7ac8fb69,7eb9795,d2b468b6,714681f4,57bc586f,40585c01,e1dc14a1,a42ce887,9ce044d9,ddb92d82), +S(b9139ad5,4f44fed8,4917ad55,c49c23c7,8d62aadc,e83c9ebd,9efde865,cb1eb298,18068856,c80abc3e,2a02a441,bb7a7609,aae8d2d7,8abf4e2e,378fa3d0,a27aa900), +S(bcf5cf94,5887f183,e58a0128,4ed9a4f9,fcf918dd,4e68d70c,5a54eeff,166cb44c,8235f63b,bb06a1a6,d9ad2ae8,47aeb2b3,4838c962,9608943a,93294c6d,e21a3ab9), +S(4b598ce3,a77680c4,c5f66e90,1b76627a,27f35301,9641520f,53ea3894,dcbbd187,357af043,f77cb9fe,c04ce1f4,dd9b610f,9151d15b,3b7383e4,ecc5384a,8ff7c5cd), +S(b588aec9,2dc045e9,a95abd7e,da929837,28b5a7dc,d637001,ce7f0917,1283b16e,e682f53b,5e94fd84,914b7bed,5afc28a,30ae6f53,e12d948b,3c0d88fd,adc5d0e6), +S(eb8f5080,218ac5c3,cd792042,b59e80ed,e3857a75,a81d67e0,7c2221de,d3b7a677,c5f272cc,3734e0f4,6a5cf40,626973ae,1aa76839,1953f211,eb52693d,254a7fc3), +S(87d119ee,65a60dd9,aac3e784,22049cfb,4123d262,ac9e7473,4c9cc418,fb7ce4f0,5185ac,7bcaee8f,f1334eeb,cdf2c39e,83b8b665,1ef9d8f5,48a029c6,464242da), +S(cfd0438b,186d0f5,c64b5f38,a190baf7,35b67512,a439f486,fb79d501,90294683,985edeea,243e9c6b,d9c57cb5,c7372202,7492156f,e10bd2e5,67edd14,8603daf6), +S(52abfb67,5fa8b12f,1b0cf0d,8e85f402,47696662,64c7252f,69562590,839ce4f8,8483ab43,2d4851d7,4f432c0a,8e3863b9,783cff58,3d4c390a,9865d7f7,d1aed67f), +S(52926df,cf12eebd,3008459d,3c91dc1,73532f1d,ce3c5d0a,874ea4c,67331787,18b48fe6,1bd74ac6,4b34f2d0,e7de8920,2c875625,bcad84bd,cb3c81dc,cc86dd87), +S(695e09db,8c4479cf,4c305005,b5737ca0,63f89d02,aced2010,5600d65f,58e26401,32123a91,8bb23fd8,79715cc7,488184b7,53e0eb00,6dbbc95a,ef9d815f,3833c08d), +S(97c35716,e5aac70c,45dcdd45,a5ca0155,5962f09a,cc22c16b,c79ec272,ce1c12d3,93869464,6470f8e3,c0db18b6,2e4378e6,5caa7203,c4d6a079,a10c8182,b8eaec3a), +S(35197cbb,8da9188a,fc60faf9,71cf08fe,73372e15,f857b93b,6afd77e6,bf4db7ed,4e0efeb5,2db601dc,a539c777,14f4aede,c5ff121d,77dbdeee,7f16fb0c,4cfc19af), +S(afb2f842,e0818237,46c294b5,9ae8afd2,279e834f,100f7d1a,58a9551a,98408d49,5bf5ac43,a3609b4f,f058d6dc,6ae09fec,19a19864,6d12096b,6bd3e06d,95d15ae8), +S(a37f6113,882459,b1dc6335,26253a8d,287c9285,b7862721,f9bee74a,d2c4c09b,9ed3252a,303c6d,e01c9985,c5b3edce,1074d478,db56b961,d91fdaf5,1b1d07cd), +S(4579a503,cb12a345,182b28f6,9a3fb98c,4a80579b,2ff592d1,ab18b32d,212098d8,8c61c503,df79dcf2,6083f15b,c3ee1f99,9e1e0960,8bf6af9f,b3175699,cb0e32d5), +S(545031f7,883a2c8e,bd56a405,52719096,4aa1d40d,b22a1730,242f3064,530ce326,ecb024e8,e762b456,f62072e,5f471180,bbc817e7,54e830ee,7757ed7b,df5c9300), +S(b127fb32,bb3e193c,99d232e,d50dcad0,3b45c072,e0d521dd,de72daa9,e20e97b4,b198428,12a344b9,2e8a8d26,f7964c66,82cb3652,66ab3e28,2ba56197,a159f1a), +S(28cb3582,d312cfcc,75ab637d,66c646f7,5157dc74,7a464e9b,933c0820,2326b6cd,a87042b8,510ef9b3,ecf918d,916128e5,f946f43,6f18fd5f,ad62c46c,5882a23c), +S(8a46cb3,27efbeb6,850e3861,c4845ab1,21414f12,9fb27387,4560826d,c9116886,ab09eda1,9156f1f7,194b7b17,fce15268,ba041c96,24765ce,fd964ede,d1f05b3e), +S(b73af914,10ad56f7,d490dc37,1a2584bb,633de0f5,3f00cd0f,6b8a6019,53c7ef16,3dbf4e52,753e5d33,3fd23cc1,c839f278,38eacb3d,5980cba5,bf1be426,b27641a4), +S(b38c1896,427a0108,3f24a917,2a64314c,d9dc1759,60971135,1b2db6f7,d66ab745,d3a71a74,f80d6919,b65629f9,80c7757a,cc49c2aa,78dc67d3,d6f76d06,91a90d85), +S(6f6ac108,aa819a27,6dae862e,276b3ebd,8ed5a3ad,9b0296e0,4f8b65a7,f6a5ac1a,e3048583,7aa2140e,de381363,788d6d95,25a7ee33,9e3a3ed1,2518619b,30d9f71), +S(72f5809c,7c282ab3,4dd81851,33070d85,53999a6f,14fd753f,2ed8deec,ed7adc5b,112bf5fc,8cfd71e1,84ca1967,d05da765,801f12b4,c852768f,60afa7f1,e9576534), +S(4c348833,10f7dd6f,b385ce25,e2d6eef9,8556a59b,5e79a084,ec83425b,37150085,9c4c97e1,be47b073,5209ecf1,5f05cd8a,58ece74c,1b35a92d,96a70287,11d95add), +S(f16e4513,2291b577,ab360b42,c1babcdd,ac61e623,da85819,e9c4c73d,463204b2,5556d7d3,a2d45955,28781d15,16b59aad,941ea356,1b5c88ec,94d09314,555ea64b), +S(3580d3f7,896fb70e,d48d40f8,1b31a72b,51405574,2c2b4369,e3e7dcb,aca4ca22,e38da3af,f409e459,82098305,87aa0eb3,b2339959,75af2e33,501115ce,648360ee), +S(407e63d2,c0cd6d37,84c27734,f7e517fb,4bdf7847,296dc7c,a8714fab,16199828,2dbe5da7,4b29bcc,fe9adabb,69157830,987ac51f,389c6001,2577f298,710025f1)}, +{S(f61f644b,e2414c07,66c6caf7,5d32683d,efafb133,cb4d341d,7eb565e8,9f6e4158,2848548f,15a6e7d7,2b2eefc1,1b76e318,15ebb4b2,1e3bb938,e0c2e9d4,5ad4f7d1), +S(5b891f8,ec902550,429a5ea8,33fc29c0,bfdddf6b,a6f62c19,87a14050,a9689a9e,77901539,1ef92985,6d3e3b35,4e4ba2db,3bad967c,dedf331a,c0bff08e,f25f2e99), +S(d8c5a617,62655ffa,c943ba35,3b595b46,88012282,af068e52,d918bbec,46bec87b,9263db7f,6f74aa,df0dbdaa,7e7ccd76,cb3a498b,44de2bd5,f9b23029,2ebc6009), +S(2e940645,cd189edd,2d6cc2f4,f9b49e4d,305cfe8a,46f2a596,fbb55200,89fa5b21,4c197028,e89ef8a5,b5b6cbb1,3733e90,408877fe,7425d58,1f4bd063,ce286fb2), +S(396c3bd0,9c6af07d,123a8441,c9f79ab3,a783b8f3,fdd69dba,ba61c7ec,f65e3098,534c8657,aeb8cdc6,ea34b372,68f1c70,70881797,46b8e335,477c8525,cd17aa8b), +S(c34e6be,b079f3e8,d1355754,4246d2b7,a82d551b,740b4b59,b9220bbb,768796fe,57806a7,653ff7f9,3d7cb6,b3acf68e,aed049c5,75988fa5,f03b1ab5,1103aee8), +S(5d2d6aa5,252fc9b2,55d89773,e920891e,7021f233,5f7d0ff8,c6bde5eb,b65c5149,1fdbd2c5,6b8bd095,2d16c304,8d9c588b,2a26379a,17f748d,f1345695,1c5959c4), +S(dec812f5,745fcbed,fc36c635,76874bc5,96dde8ef,68a8724c,201b6af3,be7c6e2c,1715328a,f75f9661,d58c667e,5c5514d4,c99dc881,8cfbe702,e0c3c8cf,662e6906), +S(32499061,83487250,f65684b9,9434489d,3a83ec93,61531dfe,48086b2e,b2bd18fa,53217af1,2a25fc6f,45555d93,98fe46df,4247d38d,7b162e34,945f8928,bfe148ba), +S(d3e9381d,83f31116,ee161490,c9b5d1e5,7e086c6c,1552160,2c913315,af033ddb,97ae863d,34271b26,a4d6577a,32028c12,f092a54,8a18ae1b,a83de384,3b8fb84), +S(1347dca6,d097faa5,7c6583c1,c292c6b3,ed87b31e,9f7afe8f,d0d151ee,50ebdeb0,570a9be,e4806ee3,e30696c9,71b5d905,65d09ee6,8b4fa8e2,8acc54c0,7fabb492), +S(691f9995,af2bccbb,f556f624,b28a1da0,67854c15,4f014e92,a56a8cdd,9a43c25c,81babe0,ae44984c,bfdfa958,4dc5c677,881d1b0f,63993075,a3fc462d,e986866a), +S(cbfb62c0,b91cedb2,5a9d4b3,ada43cac,7839dd18,33174711,24688ca5,5f162cb,77c12161,e8199410,b040dd57,4d90c39c,2f1b499e,6b7c17c7,fb21438d,aff4e674), +S(53627516,8de62d6,2c792f64,f87996af,3ed8ec88,653532a8,ad60942e,cae4a339,d8449a0c,c6ae32ff,45a11652,97b3d3a0,57e67c64,42d3bdb1,ea2cbcbc,cf0655cc), +S(2a81679,7505601c,763e6f6d,f7ed5c0c,14ee7fbf,d75b8755,7bd57f3b,e2d3c7c,99f26af2,10540397,b8423da2,c4809942,63734d99,f0d642d8,96b5f216,767b759e), +S(54b2c03b,7a7ea964,220a255b,bb688767,99ff1b83,f0934e4f,fd03c2bb,51490e22,b3cc56a9,ada9240a,a3730828,26733090,ace3d7e3,91200d08,2cbfacfc,bcdb9c08), +S(aac88c8b,7c96e629,6f023e5e,8f260324,9f4e645,bd701705,8f38e9f3,a034eb57,da03ca87,b98ab6fb,e4869756,7c2db04b,7f9948d9,ea65d93f,d222d52f,6d48c552), +S(bfdd8394,fb49f93d,630f6b8d,469da38b,105529d6,70b9a1ab,e3196816,d2a13978,39a97919,4249f78e,c336b00e,475722e8,7ca734d4,3d1e97d4,d2aed074,abfacbe9), +S(5b5dc3d8,66ba3647,d2aab2ac,3338abbe,4d1ca08c,6cc6fb26,4335f40d,4dfb2331,3432ba31,46a0f15a,beca45e4,1ded8729,e6a0a49e,70315745,bfcb3388,4e1b9e64), +S(77057b28,a1d139a1,91e05ad,a8d72f3a,c7bbd198,7647070a,b6a21355,7bc0c73c,46f32321,4519afd2,f830cf7d,567aacc9,47ae6b8f,8c841adf,988e39ad,e7b9757b), +S(f6c8d1da,e28a3d23,2a388998,1b638b23,f381618f,18dc81ed,67bfa696,4cf1626f,2ad8c92d,43378941,8d298dc8,2cbf288e,86d21467,ac73c0e3,383ef3e0,a03142fe), +S(b75b5cc3,77a55310,a3b97067,34f1929,fc0db732,3265e6da,71405f37,729d5a90,be077940,4dc94ea3,3cff505c,e1aef457,bc120359,521eae05,1de1963d,b1948053), +S(a66d54d4,4b4d06ea,f141307e,27e1c225,41274eef,5c0b1743,e6398b22,fbaa4068,51b6b8a8,48e1c27f,107f82cd,d0554643,b9e16611,fa93b789,a2199b3e,3bdce296), +S(56b2f9,ab707dde,3479d0ea,baeb62a7,6cb9bf03,66278eed,559e027e,a1ea6b3b,27c47e9d,646684dd,2a54db0f,c245fcdd,721416f7,22ed568b,736e3e1b,f195b379), +S(a9642a49,83b19c3f,f5f63ea2,9e76afbf,a25dd0c0,221b32b7,6e67373,36e7f5db,8ada3766,9207c6b6,a6b6006b,5240a4d6,cdb8b807,c0c16a56,91289b7d,62b3a051), +S(18eef8d,f9e64c1c,548db40,ad77d92b,11f3ac43,60c63792,5f7d598d,7d8d5155,806db24,eefc3a64,c84da338,937811e1,20c6d0e6,9cde79ee,9957a4fe,c53d0e12), +S(d11359fe,61861a36,8b3809cc,c727320e,42905036,774d0e83,98453ac0,68d404b9,d4182ce7,2500637c,8e14b977,34fcad09,f061838d,57c555fa,420fbd50,9abf6b81), +S(7ea072e8,f60ff273,9cad1d8f,c560f208,b54149a2,5748900b,50830e3f,738b2db2,af09e54b,d44feb44,b39956af,fdca6894,91c7c6fd,f029e71b,e780f8f6,77a48a0f), +S(f53406ab,9fb1317,b038dc28,f0165abc,115b37fa,77d23bc9,e51993a7,8a15ba00,a293f429,f7fb281,9cb60b53,b2e6f07,afb6537a,39a18be,a5ad4cfa,55aea13a), +S(b1674e5f,9f194a16,94fd12d1,4b64ac8,bba69432,241aefd9,9a1c49d,23287635,83cb0060,1f5c33be,9436d946,22c3b3ce,68d20733,ee1e2392,8c3d6c14,a7cde085), +S(22b72e08,66b96344,ee53b898,ea725f7a,b5832c12,7c0881ce,862ea945,5eafee85,b886e8e9,cba29b15,be5c22d6,ada99b02,1098be69,d1c500fe,6fd2ef8b,f1ecae25), +S(9b7151af,698a85d,2246c88e,8ffb14a0,c762c2e2,64ab70b7,e30e2434,9b8370b7,fd9c3d89,46ee9d90,e7fb6d26,796062eb,4cb6c160,76df4834,eecd2748,c8a7bb4b)}, +{S(5ba26c2d,53b04b63,d260c6cf,392786d9,41a1a7c,b88331c1,149cd3b9,9c207f5c,9c7f6303,bd72850e,d4da618,3427e7f3,eee078,6f67cf9,85d483ef,79c2eab7), +S(f7d26944,6d29f81e,39a44a88,49f12184,b9f42eef,16c5d88f,60c96a28,cf0c3e48,e7ec965e,d0a966a7,45087e09,a058421b,852c8a7c,3790a3ef,7abc6ccc,e17c6084), +S(98590b7d,36bd2ef9,37ce788b,22cab951,d921724b,87c3ad83,8263416f,b5a67dc9,b711c21e,5af72a36,5cc1b220,7ed09ebe,be918555,55e9239a,e9b03d75,c0261d5c), +S(92e1cc4e,5f57514e,9ed13535,5f3e2cda,b0b22f8,8f56a972,a657dba4,7263463d,14d296bd,452f2faa,7d6f42e1,550fe35b,3c47eb2e,fe7636c6,2eef90b2,e7822da8), +S(33de9b1b,e153bdd6,efaf9d1a,30aa9b3d,faf26a32,4486b6aa,ecb1f958,f11c4673,7ef29223,4d3a565b,c0f0e295,deffa3c9,a86a6bf1,933a084f,9334b790,51eb0270), +S(f9fad0b7,e1dfd4b2,47cd2cbe,bd863e1,95b3be25,6cf7a707,5d422b9b,f5631ca6,fd5262f9,e6ca0cee,e1c7e531,83d9f3c0,7ac518b,c024681b,56c06a1d,1826f5ef), +S(455ec5ea,f34c02c6,961469ed,27bc7883,c07c9a18,663e22ca,83830a66,569b2b36,4dbf1b57,a7de2fdd,7c0380c2,b38fa5d3,697a5995,8ca0c0f7,6405244d,bff4c9), +S(940fa05,d96fb400,bac8fa39,e696c536,71a490d7,c98b3851,ef76ed35,c62bac19,b6de17b4,1a045978,5755497f,1c2a953f,17554b4,20f2ccaa,9fcfedf3,5afb9b46), +S(16012402,4ded6478,72374af4,6daf9c2d,a9000841,9a7d4672,98b627c2,420981b,7c2607e0,a4b86f7a,d5df7371,60987d21,35d2ce2d,bc422ab9,b643d080,26f84323), +S(caf887e3,339046ff,42c629ff,c954873,2c629ecf,319c44be,6701a9f7,c81bf842,d253a688,3b3d51c5,a914ffb7,46e7ab68,70c2b1ab,5b7e46c1,7a5119e8,4ab6c878), +S(41a5b720,595bfc66,18406547,d59ec09b,4efba0ec,5bbd3191,9e9256ce,f40a7afb,87ee1be5,2233ba8c,82dc06a3,6fd0a1b,4ee8d7d3,ce89cb56,1dc96c19,dad79613), +S(8bdcbe80,fe8533a,174045a8,3cf9d89a,ca438ef0,8f6393cf,6e24d923,edb02586,8d21379f,c053e8dc,c628f0cb,83a7782c,b4e946e3,ca88d467,36232762,fc6f8fdf), +S(409a4482,6b6f0ff6,36178d65,aedd64cd,2d28b39f,3e9cd93d,a0afe712,b75fcd19,25a3bec4,74216dae,d686825b,bee6aac,487a6d07,606e5aed,7c3032df,f4911eba), +S(b7f414a8,4c0af927,64ed5b52,e96dad38,6995771c,2cd90af1,1986bdc3,cbeb61c0,702b0a68,4e93f0a6,26b807d8,8049db6a,3e65001a,d75a476c,e4be230,89574e8e), +S(58b0cdd7,bed4f327,bcecd493,d835c0f0,e45f6fa4,3687d1d2,f19de285,5bcb5c11,21b0a478,2c1d14db,9c67817d,7b23db21,a96e456e,62a85c3f,2a02c76d,78dcad10), +S(c75cbf00,893447ba,5b3f8462,9d6897ff,64be841a,9a6bb714,54adb849,8df03900,15f68903,ae20ae4b,9b3fc7c4,f8135936,c09de15,18317dde,bcf66190,2db79f72), +S(e6258fd4,b63be23f,38361a16,cf3f81cf,f2d7343e,515b2d0c,ea0bfe38,6d4400a9,aedca212,9b73e49b,9757cd7d,a39a1e92,f885b267,a188521b,32089ae7,6d351eb0), +S(7c61b66d,d76f759f,be92708,8b075147,2ba10db2,eee4f0a4,2eac1ad0,d2dac3a6,c2b79de,70372e1a,6c9449af,2612e34a,8e101cc2,81ef378b,97cd77aa,bff004af), +S(29c71194,bbe41f4e,b2f58bf5,799616c3,7b247283,c993bce4,630929d7,55f7c8c4,c0fb083f,d68f63d3,599c2da,9d0c1f03,b6903545,a47581ff,3caecbf4,359e0235), +S(f1cd983,5bd3eb61,f8207495,48da075b,ff4191ff,d5b1521a,a1f4413f,2173a68e,beac8102,13b643a9,4658cdbc,71713894,39b72abc,f8644697,2fe6310b,4ff0233f), +S(94f2137a,ae170855,3af3dd45,8f8fc9d3,c1bf07e4,35a62798,25d5b93a,37380144,e952d6af,b27f9b2b,80ccbe89,59fb8b15,5fe1b2db,f3ffbf14,cf9c1fe9,b8e8209d), +S(f4f0cd2,e28cb8a1,9b469b18,90033912,4a40a39e,67ae1642,a3a677b9,fa1a9a3c,75412f04,5c41770d,73d7cd77,bce0da96,1e6fc69,cfc6cb9,8f691d43,dce1e548), +S(15ba2fd,b652ea98,f2b326ee,e5e1629b,ec8f8e7a,36078d7,cb8a80c8,c943e98a,db416844,cf757376,cfcd5a9a,9a318b51,184f8c89,fcda3d97,e735c120,43d47c35), +S(5754903c,ffa8cb6a,3ffe3488,e484c498,69163b77,7c07183e,8d2da037,78b8da34,508312e,6c2fd008,fac12bd,afdf8e50,1940a81b,d05efd38,5277a85c,ccf125da), +S(3bc76f6b,8abc155a,dbba76a1,9c0fef85,373bb1bc,9775f431,1b3ccb12,9c7fb29c,48036702,aea467ec,daa8b809,97c41c07,9e38c414,f798bdc3,a531b08b,fb4ae303), +S(2992c410,306d3d40,313ef69c,a2e3383,88f592d4,a9c2bd36,ebd9f51e,883aa33,cdecc5df,41cd193a,ecb26700,baa42486,a0506372,d56de3e2,2fa09156,7b525519), +S(baa7d83d,6d70a528,e6392adb,b2af797c,72772b92,ace96a25,90d65c37,b0ff1bc,9943b555,4e44b480,28815d8b,e50189d3,6617e9b6,c8f07393,8309e04c,9978fad7), +S(935488ea,4c88c2e3,cda6c0ab,5b42d519,e7fabe09,fdd3e36a,7c78c9bd,730612fe,705c8f8b,228be0c5,539eae13,1f4f4bdc,2fecf6ce,6cc567c4,dc692af9,7c1d506d), +S(8edeb68d,e63c35e2,5e36bc8,61445a63,8b0637ab,d14557bc,f0b0648b,db43f86a,d20bd0ec,14ef4f35,68954130,6577ef85,baeeeed1,c1004130,80687a5a,94a9e9a3), +S(9a39617a,27c2ff2d,9869acff,b22fad1e,a7d04271,be154547,43234f54,7f21924b,917bf9f3,fe0563a9,8daacf90,dfdcd8eb,e657f023,3fb15711,79bc5ce6,e6f5dd56), +S(41dcb02d,21137ea3,a179b469,199f9ed7,9b831923,68719a4e,5c727ce0,d42e95d,4669d53,82147266,8327cd6b,31c21b80,d3394bf7,fa29a43c,2ed7441,d866f5e1), +S(d4e3e3cc,387e0364,6688a62d,9390d585,a69ff43e,1060811,431dea8,d868355e,3309af2c,b3d7ca6,55334f2e,c53de6aa,debf5d57,1618ecc2,9dc9830f,ec46144a)}, +{S(90edfd0,61871350,b7f1f029,c4114190,b050065b,2030a400,9a8a7a6f,4b92aae8,872d4f07,5f60ae2d,dcec2f12,98a22da2,53d54de4,fde85560,690dde89,1628db56), +S(27e3ce53,b4258f97,a499f408,ecab24f0,60aabae1,dafe992e,5a34952d,5e6e486,d393fad2,9be684f4,7ecec306,332ad969,75b79d29,b5863d98,5f959c4c,b8ffb442), +S(420f1078,27c75c95,d5bc657b,a46cbe2b,415a7d42,ad62cdf1,6c84ee89,22215379,8b257a28,e0b15fcc,ae0b555a,cdadf4a,be93bbb3,a208ee45,77710a9e,d58da7fa), +S(28859abc,b60a95e6,b26c0996,566bf798,60c1a194,2d3342f7,9655f286,32f9d5df,2a770426,5eeca5d8,87840cab,3923d868,aa7b7b18,f9d19941,738ca006,54ccba6b), +S(c33c317b,490e2266,2649a021,e87f6596,3897633c,90be208a,193f1d52,28614059,af850be0,d18708bf,d0e1f523,c1a4fda8,9a6c156a,55f82518,2bd99bb9,b999a358), +S(2333793d,b961d3d6,740fc725,6cf9d833,81b5dc92,85b6d83c,5c343aa8,5baea83b,accc199a,ced3012f,b6db99c4,7a36c30a,f88e7eee,b62c2ed4,1352b488,ba0167bd), +S(4834aa89,caa9c25,a99ee4da,e4a64c15,25a5d74f,9ce573ab,ff44b63f,c3a578aa,fb189539,448a265b,eb87a268,b71a18db,f12fe8ac,e502720,c83ca156,c1cc7a39), +S(432cc05f,c78b0d56,e605391f,e4708bda,a1ff3edc,96a729ca,aad3cb0,300c4d4d,6675d8ee,ece8c078,e1bad373,247ce383,d4c65519,4a6aed20,a7ca5eca,34a89c30), +S(874fda6c,b284ca2d,a216bbda,28249388,88da3968,7f615ab,52c8e61f,b72a1fd,2d7199e2,b0b88f45,18e6eeb1,240b2ffd,a9bfcee4,6f754a4a,3db7959,dfe857e6), +S(7fe21a0f,3ef67d60,1de05f67,2b163285,a5577948,ee78274b,19fc35cf,2d2f6801,62fb2ade,5e2fffe1,28542038,91a6ea73,aabfa35b,1f7fb000,95190adc,de6663f6), +S(cd0540e9,efe497b6,2beb2227,a2da819,a1ac3bed,8eae24c2,6e2991c0,a707dd69,446c3218,7d0c9229,d65dad2,1392e4a1,66445386,4a5c1620,bf768fad,20a45c06), +S(a533c295,74e78024,52218573,66c30001,6159d772,f5bedcff,28d7f7cc,3051457,b61a106e,e0166d54,5e1b945a,f3e4e285,31a34cb8,56a34dd0,cd21184a,9555eeee), +S(5e144f44,ed88845a,c089331c,eb58811e,4c164e02,5d1758ee,51a7a522,c66deb30,ff95cab7,597cf62f,e1aa8df8,a2cd3844,d71ab4dd,4eb02a9e,6175077d,261e2540), +S(97487a40,9562ee2,7620fc2b,c5bd55ac,6509d487,8ab41257,53884b97,7c5a84be,e52a282,1430c540,5f1143d0,62b69faa,16592f02,cb9b8602,d52c9fc3,70769091), +S(906f9ac1,d3db4690,d74771b7,f1940679,b0de7731,a68d7d35,89caae34,c3760eea,6f2be7,2275dd5,1e77a066,b8d3c303,f565cb97,b8fb0dd3,14445d18,876665a6), +S(4c355a31,d17617f3,5d4066c7,a125b2bf,1d6f77e6,27b585ba,2d271a29,a88c81b1,6a686e69,237b75a1,a1ecb86f,b715e858,35aa0686,e2ef10bb,38b762ca,5646e9db), +S(15aac1a8,9b6b7629,57375d4e,aad87c9d,e1fc2617,89e57d29,731fe96c,1380140c,2968c0b2,2c3dd83f,3286d37a,639bcc14,3d89e75f,cac1da56,7e07799a,62af1008), +S(4642f29b,37b87118,65767998,d00b41b9,fca6718d,bfc55785,1c459efc,2ea15037,a1ded31c,be33cc1,425df851,998ddd11,1518ed13,f84756c1,c7cc46cf,3f5e9a72), +S(9554abe,9e092bd2,c4ff46a0,abd0b7c7,fb73d85f,1c01fd96,83146559,306ea727,89e2c07d,db1fe6b0,9872ce91,66ce9ca8,1124986c,c7e48e09,f80aa3cd,70987711), +S(1c0977a,a773c56,2e36dd15,58b95fff,d35b4dea,ac464011,ad7b79cd,26227238,e04ce4c5,b0b165e9,87dfef97,d32094ea,3e86e6dc,33a4c96f,c9470336,34b0db68), +S(71d44171,60361c39,6295e5cf,b1540ef2,1ca046b5,98645a23,e8c9772,ac21be4f,7122d5b,32a654a0,1476a47f,d3317a25,ed51536,4a21253,f4068dc8,14660c55), +S(d906f59b,4d56bc12,f26d60e6,6fc31733,e5450707,89025ea3,8a6193c8,520ddbc7,cd7f414b,c6cc79aa,4c65b943,ff914234,a9d85cf1,9853be59,2a71fe1d,dbb20163), +S(11b7dfb3,17dd5c23,6b8084d4,f3cc157f,c25c0e70,8248b472,240963dd,9a3fbca7,dd2c8caa,2a2d14d7,fbec267c,9fe87ab2,8b1ddd92,dd100449,f75ef1da,97d4e5e), +S(3ef8274a,fca8fbb3,1894d7a2,d1ad59a9,4951b21,328b1e84,ecaa6df9,cc1ef473,2e4f0c04,f5da671d,4a2b641,46ae749,27bc35b5,98a54190,3883469b,3e7874de), +S(a861fc27,f5e6300d,ec0fbf6c,3315d053,98f90b84,2422992,bdfba11b,1c1c7e34,75a7458,5d98bca4,e3517897,afef848,8e524168,a586d8da,18834171,4b51846b), +S(9537019f,57d7869,2a358758,47e885bd,1594a426,4412c595,62eea9ba,4ab34de8,21bfd84e,a66650dd,79cc8c13,7217a351,57b9c046,938f20b7,246362c8,6637d5f4), +S(71c80c38,b1889d4f,507132a1,87af0c91,79994b84,1b816c8a,6d130a,df1b500f,8de1f76c,100e75b5,1572da6,d08c76b2,10cdc447,cf903e0e,2b00e002,5dee0ce2), +S(2fa9ce2f,59865d10,17880d74,d31cd446,5c28ff56,50f29e6b,d74a810,977ef9ec,6c5a2073,55c0dd3a,b994778a,6bd02b87,80ba8e1a,899330ee,cd8781b7,6e15cddc), +S(96ca6bb4,bf74c748,75703386,ae02dc29,13329d9e,a5395892,df1c6f57,4a84fa4a,fcb510b6,dcfe8da5,690f8fc9,4dea8ac0,e42af209,35c33347,b088cc79,52e98b1d), +S(36a066ae,694f2645,25cba884,956ebd46,ae568acf,11664965,63cee00d,a32f2199,5d1e975a,856ebd1a,cb1fe254,101e89ab,ea089e8a,b38bbd0f,1100e914,709fd965), +S(4922879f,800234c9,63f4b572,d236843,4c4da5c8,ff741982,c3d1e341,841d1309,9b259470,24b5f4cb,97c68d18,f7f8dfca,1e57f7de,63208765,2ce15770,98f35494), +S(ee27e2b,acf95f6d,dbb5ebae,bbf181bb,43322a3d,6db87e78,14e57a3d,41b581e0,3d6a18a,daf69ae4,88ecc9d8,7d6b1bf2,c8d65544,3f4b45b4,c5a0ac51,7b1dc3ca)} +#elif (COMB_BLOCKS == 43) && (COMB_TEETH == 6) && (COMB_SPACING == 1) +{S(e3adcb1a,fe947e6e,7cc4f5a2,df78310a,b235e2c3,bcd75eba,1904de80,c8814c50,e0b27ead,c4bbb9d2,37dad580,6e366674,4a9f9c3d,e024f2bd,1edb11d2,fafc0a22), +S(612c2ec6,f0e9c4ec,c2200d23,ddca77eb,d003be35,61e52b1,890bf846,3bb53ea5,9e944d7b,dfc7a952,c1c5ee15,485d7199,dda19551,2d729628,c215a9e0,285f656a), +S(42053dc0,9f90a7f7,86feca60,d68a5c3c,789e44d2,3479aa13,2d1a427c,621373a3,b338f891,f3930ec7,738669bb,3a29ae2d,637be08a,954f2a8c,acb661af,a660bd22), +S(4d227ea1,5194ed57,10f8ea4d,a639be04,fa68ecb4,f3d2d9c9,43ec32f2,80f74051,28a94075,bda4c195,40c20493,b5391df7,166b1264,b957fef9,683cfbec,4c6e6875), +S(8ec4abf4,d4db3b0,2b0712dc,ef54a405,54b6cac9,3f88fa9d,d8cad4c0,9b94eb1e,4e37e159,517346ee,17e948c4,a17912b0,b29c303e,497cfb38,16796752,99aaf9e8), +S(ab186398,117fb83d,db8b9392,cc888fe2,50d2f604,5a0c3f89,92d8a82c,382175c0,79437224,b3b1604c,fae64902,e3030448,51ef17b8,9af02d7c,54a92c34,7fa2abda), +S(2bd09ae7,1e8d85a2,ba550bf2,9c1787a2,3d2c8985,e2ed07bd,1d39e7b9,8ef8135,ddaebb19,195bfd6c,a44ce82f,b7f3c65a,8af935ae,52e2d2fb,33cc231d,c4b16082), +S(e6da6560,c8265e7c,8f62edca,78dc739b,74bd6543,44a939cd,bac0f489,12b920af,147f5ce4,a98377cb,981dfaf0,1a1e4740,238f1c5d,ee69cfff,a54f3aeb,e53980eb), +S(7df5abfa,d6b46a37,30bd5892,69edb6fa,b70a0d31,936c0787,407d5d6,96506263,bc5cbafd,1f5fee67,1aa449ff,bacefc67,cf7c529f,86100d7c,a8160e4c,376c76d4), +S(ad672823,cfe3ac01,50038d30,81a1a109,d8629b4a,a4e26779,373ee0db,44a466d9,c288397c,f91157e6,770c401e,dc84b328,87b22534,d11e11c,c8415a4b,743fef9b), +S(72032cac,3177c280,ceb3076d,7f510405,2413706c,956ecf38,acf410ad,a12473a6,8bbaf50b,95797824,2994e6d0,a4bf6d07,149792bf,f2a74847,1095f845,bb332036), +S(36a1f78c,3bebf8c7,1fae5e29,cf08485d,d9debdae,348a20,ad84ba5d,4308fec9,842f57e2,e900d07b,eefda7e5,9dc40139,c5deefcf,11c07c42,4629c59d,593e01af), +S(5f418454,72e80d51,1c1b8bc2,b6b89224,9119ed43,5b915809,f7b26d01,8427f579,dfc29fdc,f3c65221,a6615262,cebd9a14,acba91ba,cca22ec5,d84303cc,1fe0085e), +S(5577ced2,f6bf41f9,503aa4a7,c0060fae,6d33cda6,e3c8ec55,1eaec315,bb91fedb,858ded64,6c3d6231,87c0967a,84ee5253,2b21c4e5,b329bdbb,76f6a6d4,93cdcb4b), +S(bc74b56a,c94ef36f,2b356bc5,dfd11d2e,7a371087,653ad607,dbfcfeb8,27abc502,d57d74e7,39e758ee,96a422e2,f1fa61f7,4f6308f5,71e6dca6,3b0b0103,e83cf1f3), +S(727ed91f,be4c5086,50a0d365,b28ae4aa,c9434c0,735fce3c,7b3ebb42,f4be911a,8c595547,5e627c22,6bfa855a,22ebbc56,d3d0b331,9120d8e9,13bed868,7d3bf331), +S(6286bb90,71f8887b,c4fbb3f0,a9ecb19e,fcdd2cf1,5e286da7,1bb60c9b,5ff5e644,73731ec5,ea3e537c,c6060ac5,dde716b7,2aef4117,ba747b12,1c26fc9,eddbda74), +S(3905682b,72282a78,2b8d8dba,72cf147a,de0025dc,a21521e1,ea989040,c248852b,5da3bf52,dceaa14a,a3534068,c05bb015,2cf9c722,cc80c56,cf828ace,d96fc390), +S(561a2ccd,ca12b67f,dad28ee2,c3cee78a,cf811766,9e4a2543,c81b1ca6,eb4bd16e,3b386a9d,553c2746,893477f5,17a05e99,bbc8ddf0,896249e3,85e406d6,a57b9ed9), +S(75bdfa06,6a1a42a7,50f283e8,3ec91cc0,a5b68829,6e6aa24a,28a61e33,65f378e5,c73224ec,797d6736,c1a541ab,34523d91,e1ec3754,fe7fed44,474f9cba,29f305e5), +S(e881a840,847aa2e2,2417cd3d,3e798c56,1e630290,5dff6bf7,754d9419,98d401e3,8816d775,f1555452,f624e45,710a240e,90fc5e23,7536d217,cf555349,b5e31bac), +S(1fb527e9,4e9c70e8,657de745,8b81ef9e,e3c2b4e0,128a675b,f7e28980,e18b201e,bab00a09,1145407e,693d5353,7818bd30,49e1f364,757d228,58b8aac5,416e3e78), +S(1c2bd878,b94169da,722a9de0,c4e317ce,a8802aa9,60458301,11a89d1d,9de4270c,95b7d99,bc3df31e,f0dbf17a,a09ef148,71ae6c5d,870ebe75,1f52aaad,a48dfcc5), +S(41f7fa0a,9a59513a,e221e3b8,4b91995f,c9d40eb5,d120a6d8,e663452a,d92099c8,813dbbe,92ec4b62,25d1cc5e,5820ebb7,dbdc2964,d5dd1ab3,deabceb9,5e793d32), +S(e5cbd627,89c6a843,25a24407,89b88dbb,1dc55afb,9e8296e6,bb8af7de,57a50e60,2cf01cea,ae4f4fed,46c4efd7,86ca5e4d,ef5af524,e9393d74,e9dd224c,604b9408), +S(eb3bc68c,623b1f46,ab905412,c7f2d588,fa25abb7,7a7bd782,ba9bb3aa,c05a70ae,df9f46e0,5dc1d126,2f72ef3e,8db01fbc,11915af6,4aee0c51,da1cfa,b4d15ef0), +S(5702fb8a,2602f41f,52699f68,8d4b005a,128762e1,1dfd13fd,22ea751c,cbedb2ef,a77105b3,7af534e6,46f58c3,b02543fd,9e0666c1,58051952,a61f8389,73f5847), +S(66954eca,5434263,4036fc7,fc0fe33,81f5195e,88433bc3,2c5a8a60,341e2859,d8b1b14,40e9f123,f39c8658,f9d64e7d,fe4071f0,ada879ea,42eebad6,4d37f4fc), +S(592152c3,98d6c719,636a03a6,dad64246,a5a6814a,a62c156b,ce5332f,6759b031,8d22d1e2,d93dcccc,889f3b6e,dd5e2098,2f5586d4,bac06842,d689a37b,4b845c12), +S(5699b93f,c6e1bd29,e09a328d,657a607b,4155b61a,6b5fcbed,d7c12df7,c67df8f5,c147ee87,14325497,6b2e534c,e6902748,2a5c33dc,867732a5,8338f05,73368388), +S(c62c910e,502cb615,a27c5851,2b6cc2c9,4f5742f7,6cb3d12e,c993400a,3695d413,e80c2522,898d8a22,2c4dc0b9,8dc9ce88,740fe252,5144656a,c30f978d,dba83c1f), +S(0,0,3b,78ce563f,89a0ed94,14f5aa28,ad0d96d6,795f9c63,3f3979bf,72ae8202,983dc989,aec7f2ff,2ed91bdd,69ce02fc,700ca10,e59ddf3)}, +{S(efbbec14,ff6d7e18,a8015d68,ba3ceb19,d4cbfbb8,a1bbc09c,ce755a23,e9d4b3f4,a76faa08,2b02b8a4,405573c9,5ac067f3,ab936127,24bfc14e,a27f923d,3adf0133), +S(f02f6744,a0ee7b0c,7bf0abb3,c7ec0a5a,3275d109,92be2893,7e9ef649,23fa932d,955f3630,c5621787,13e6d8f,39efee26,d91a0947,8da36db9,4ab4a89f,aaf9019a), +S(1c6f9f0f,d6ecbca1,fbcfbe9d,1f3d2476,dbd3b6ca,ac8e18a5,949b993d,8c0063e5,e3e3770e,33081dc9,5125d69d,c631450e,5494d21b,2ddf48f1,fbc3169f,3cc1eb91), +S(2062725b,739b793d,c9798397,dfc7b1a7,24ebe8f7,5e5654df,536adff1,25970841,22f3e3e5,c0201265,5e6d8e58,b8ba633d,9a9216b5,445a7f78,a2605688,4a5b6092), +S(57ffda66,e0c29448,7a1570f7,e2f5dc58,ecf9b906,5f374046,5bd1734,841785df,22ae8728,a8800436,1264c380,3beddb65,a9dee575,6f0cfa97,c01dc047,3c806def), +S(4b49fa7d,463cbb43,b14928c6,7b3a85a6,8132ad9c,427d3cc3,bba76d1a,7c9a69dc,7e7e3133,3782b30,5c7c3bd6,94e3c306,b3f9829f,86f76f08,d44b1a76,a207f2c5), +S(411a3b18,c9b638fa,38a0e811,ee370f34,5c9476db,61df1843,863d6d7f,4e803ccf,bb306f97,e97e492d,e74afcd0,a771570a,8210b51,9e61df78,4e6e97e0,ac23e109), +S(c8227510,49de1572,37afdf55,d175196d,5d315001,3670b478,a0255a4c,ebe95075,16be5950,a3f12be9,5905fb52,8d5bd93,23eb5908,211d2e8c,26204b32,556c5c45), +S(e46bdb74,8692d0fa,e6fc9f50,6685487,31d61f8a,5717fb88,4e1f7a41,70e4997e,35398e06,48bea42,cc48fa4f,2805efbe,6bead663,c054eb08,2c15ad46,c0611052), +S(d18293cb,d0902dab,e4c014e1,22969601,84aedbbf,a01526a8,6978e144,88ca794f,3a5b423e,32c1d2f4,bf754f42,9da3c9b6,84bb798c,ea73f637,1777ba77,1aae6086), +S(7b9cbbfa,a53923fd,e9f50845,3130101,3b17548a,8097433,79d3a526,d1c90c31,3fd7b71,5b6801cf,30fe22a9,8b7895d8,1b483f6e,9fdefe7e,6c59fec8,fb9786b4), +S(ab6e185c,be9ee393,5ad6278c,167396fa,aa4d936,80524d16,27ca8e93,48fce67c,7154007d,3f96ce60,d09499a5,1262c7bc,3ab5e9aa,929e0594,994a9671,8f912987), +S(56ffb418,8b9c9c13,4a110c03,8df8636a,71141ff9,8448cb79,eb6dece8,a28b65b4,1d728ed5,23ab821,ac0c40e2,b9348e27,191536c6,79a73835,8bd9b3c,b43dcafe), +S(bdba1eff,bf6af786,dca1da26,cc226102,1f95d56f,245298c0,b87a40e1,fa9a0cbc,fa18673b,41f765b8,25d13f2d,7963f1c6,b3308a14,b033fecd,e1d0d597,583440b2), +S(d9a4a7f5,5b3af93b,1c49ffa7,4f8154e8,23aa1477,16b16441,39fbc86b,2d9346ef,19ca90e7,538ac3d8,a28e1aad,5d8b1dcc,756f8a84,240e5769,a0f561d,f53289b), +S(ee5c17b2,74c78b87,9eda9341,256b1506,25582835,60a0bdcc,c8eba320,32d58638,d7d02f4a,b81215b1,7843e3c6,abb63755,c7e05d20,6c61a4f6,bb08d1b0,256409ee), +S(6953ae81,7ec599fa,5f739bef,dc4cd8b,4670eac6,912bd03a,a3fbe91a,5122ba0b,61bca3fe,36245ced,31cae918,fab6d463,50856947,f64a3be,d0eb62d6,f9f16059), +S(3bd721f7,59f7c3a9,93474472,4ffd3e34,503cbe45,fa7fa5ef,40a5a173,b8bebcea,bd7cbfbb,797034c2,d293aa64,1bf175dc,74a44dba,84b8d99b,8182d2be,6512ef2), +S(ab6e36ae,f5b7ff2f,fd2f42f5,8c408b7f,3ac84253,e1d8a43a,55cac222,678dd38e,ff0dc59e,51e504b2,9a0ba824,3ef26eb1,2446f628,78293da2,d924028c,21f57342), +S(bf1a1f6d,7f73b09d,3efbd73,eb9ea2c6,23e17911,9063489b,42fb1303,7b53fce4,236566ae,5371fc97,b5449b9c,2db32175,90e02412,b44539d3,bda7a814,3cd4a634), +S(fa0c6aa3,4c4825de,304cfece,37a20bbb,f72044e3,94cad202,c9e1edc3,b288ed57,df8e64ba,5f5e8381,4b6891b6,14dd4753,fed5f566,956a6dd,95540bdd,25c73995), +S(d2ea634d,ab56961f,52e39ba8,ebc5c150,ba9eeb1c,6178aef9,64fa97d5,e80581c6,2928f71e,a09a35b9,6fc1976c,f6cd3c1c,7d1fcea0,2142eb80,9666917d,c9a0621b), +S(827d6a36,697cb2f1,cf19e27a,ac30c06d,20d818c9,fe869309,6435f1f2,171c9b75,53237d41,3781a1df,d0d977c2,9690d488,b051dc2a,841ba226,c552cc28,12ae7caf), +S(59dafec5,4df05695,e123004d,38d9aa12,6a06c399,e5215245,5392e5e3,f1a47dd6,ff7d173d,ceda39ec,ca8d2c95,ab1658a8,6ad99618,e3fdb7cb,b07b03c5,2f96a86b), +S(5c4f5b9,2acb30ee,8c7ec4b0,ec577f41,a9502af9,a5a384dd,3386f230,3e62a830,8aea5f7,145de3a3,679c86ce,72e8b36,f3d6ac81,bb1d2043,9d719c32,ca2f8b30), +S(38add3d6,209080c8,efb65551,3d9420aa,457f06ac,d3ec84e8,db84e208,a0664ba9,ad95a891,c60f01a1,5fcddf2c,923790e2,d5596334,4d83a21c,dfe5f6bc,4c2b32b3), +S(9038876f,21c3bc14,111d5f6a,4749d07,34e40a53,7d398c68,809355f,764cf1ba,da030216,5e661aff,53367578,4a4d3447,707f14af,cf0d771a,53e8e687,b9dc29e5), +S(b07d3e8,dbbe686e,5e163725,8402cac3,e1e4f29,fdf154f7,bf008c5f,9969da10,c8b668e0,56bf8173,2d9778e2,eaa069d0,cdfbf826,47f615c3,6d0b311a,b2e14922), +S(8bc89c2,f919ed15,8885c356,844d49,890905c7,9b357322,609c4570,6ce6b514,2cec0c32,283233e9,21889013,c4a76d3e,e8d2cfa9,eed8890f,909c0b30,5736aad8), +S(308913a2,7a52d922,2bc77683,8f73f576,a4d04712,2a9b184b,5ec32ad,51b03f6c,b5a4f6a,bc0141a0,6e1cace0,993fc8a2,57ccc015,7d42e0ed,9f54a102,1701afc8), +S(3f0e80e5,74456d8f,8fa64e04,4b2eb72e,a22eb53f,e1efe3a4,43933aca,7f8cb0e3,34992828,d693436e,16f463f7,b7a2fe4c,6afedac5,59a4ac5b,34fd761c,15a0bbe0), +S(d30199d7,4fb5a22d,47b6e054,e2f378ce,dacffcb8,9904a61d,75d0dbd4,7143e65,6afc7262,f51c2a3c,4c292136,167c7f9a,e089f33c,9b127e69,fa4c00df,dbef9176)}, +{S(983e1ca0,5dd64afe,8d39e15e,43c1cf9f,6badf550,12cdea89,5fd85021,b49f173b,18200e81,d75a745,c1ecfe5a,3ead988e,4327693b,7e3c0e04,329b0c80,3d9934ba), +S(4e1200fe,d3e5048f,f6c9fe53,cdff8ef7,5d78e601,4df471fe,369f3d1e,80e46674,a62aca58,4ecf32bd,cc297b38,c1951c71,a66966f,b9ceb2ad,de411da7,d175df94), +S(82f5f27b,83d49042,63e69f48,b676c9a9,2446955,cbc18ec7,fd4346fe,37e0b0a1,e523d039,d0b8ccae,737bfc11,9b83dfd3,d6878403,862618bd,40ddfc89,9a688557), +S(a8c0fd4e,ab1f0e3a,cab37da6,58fbab3d,949ad9a4,31d6461,b2648308,35762d19,950200a9,63c3dc2e,6d2771e2,eff401d1,f9ce037e,75782943,3fd3c560,a169713a), +S(25c1b464,33068900,bff89a4,ee973937,b03c11a,5b33d16c,4f672fd4,bfaa11f9,471f1f8c,df18e73a,e12cae35,43506cf2,c57894a8,f633ad4c,e1c5330f,eae42b43), +S(497e56ce,8793bfec,4dc6f972,dbaf4a72,aa5d8412,3bcac5d4,2aa9baf8,ccfd6723,1d3d028e,b70105b6,eae66785,5dfe7e0b,7c0a6b3a,b069a475,bd913aa9,c29cf426), +S(68a285b0,d30c2dbb,b543e480,f66824b1,69aa339f,7e2282c1,5dc60f50,8e3f2fa6,87529a0e,1d53588d,21064447,99a8fee8,ffc791a7,cacc9e26,f7a7d94b,25e74cdf), +S(721c92ae,931712f6,15f4d7c,498dda23,e1029dbc,944cea16,9442b22e,d755a100,7ef052e6,a0d2646c,a5dff39f,3b2a1019,de43e3b2,5e51913f,d636281d,cee74a85), +S(aae8418f,1b124d79,ad15f773,1bdcea1b,453493ad,4cb0cd6b,ee5c9a8e,34335ba3,c2558bb1,4a7addab,62d1f308,1a9e6fd5,92a06976,3be877d2,af9ae1e8,b510d98c), +S(b6a06052,b492d74,c68640de,8bd3251d,fbaaeb0,ce1eb997,f2127ead,4bd0b81,7bb4269c,4a9ece8b,e8ea2f0f,d663a193,2a571249,2814eb73,4ae1493a,6a97b39a), +S(42fbe048,38761203,11e43178,6af555ed,d7bea551,d4d5aa18,afaa4c05,2c6d0c19,9ba562c0,a4cdc664,87caf55c,291d8246,65c29f32,2a56360e,90138b06,f109d83b), +S(9d6dcb88,b378e7bd,233464e0,25e97bf9,97768e29,6e4aac31,301fa1c8,bfbcc27b,f434ea54,3f7269cb,1ae1279d,4178dd25,bbc337ad,2f0d5141,610dc061,80daa8c0), +S(fa6fa5c8,1e6713d8,90cd6f29,cc8b7d03,c5f8f2d5,88963652,7c199f6e,8f98e060,726194a,2a5da1b5,85eba1a5,5e06ce36,5aebb89d,ba5f7971,db3c1571,c848c5f9), +S(809167d6,85e432c7,372dc111,8573e620,d9ce7e9b,c3ebc15b,ea7e866a,3a8addf4,bf0cb694,f00fd1b4,b62119b3,9dd6c88a,22ef1fed,a94ac0a0,9cf33225,9298b968), +S(99d28ee0,962c1bd2,fa63109d,f5485653,964059df,bd514206,24117eb4,e582ad46,8cbdbb66,4ee209b3,419c0b80,36affa24,85cdfbc6,e6644429,33908490,f6f6353e), +S(559d0617,e0860cd1,87f1c68,e9a9951b,fef7dba,3a67594a,eade6e25,e2df593f,194595af,721e3b26,786fc25a,cf5b2d77,1fe00649,b0cc4938,7168a9ea,1fd2947e), +S(ab9a7228,f0d533a3,4a95af3a,51021b55,bb324229,8d101a66,eb362c97,eac48b02,80a6d111,e451eb09,cbebdd5,a3ce4fdb,42b3665,f8974df8,912221b0,fc7db6af), +S(42c6680d,18b0f528,274c2eb5,422e4731,560ea862,adcc4419,68bb5f3a,5bbfcf16,c8961934,e5bd6e7d,d64d4b1d,f7867c7b,978d182e,48315ae4,3fe2e082,a9455792), +S(e8bc0f9a,c3687bb,69627de1,df71fb34,21e0252a,e33d15da,3039a200,43ec3374,15de9e9e,2ac74839,5116ef76,1267300d,78c2e583,9286e6b6,366c8a6a,540036cf), +S(604ee928,4ea1c8a9,a0a75bf7,be3a5c02,8f52d71,b5fb6340,53401e8d,8f5d3d6,43bc16af,5875b25d,8e2427b3,3913f6e0,bda886a7,52a3b812,f8f191cf,f7bee54b), +S(7f589067,5b771ce,ac754412,a9984352,4f2a4a6b,a5cecae8,5106bb81,f7e4d9dd,a74f2eee,584696c6,88157a3f,fc27085c,6445c7eb,e363c6ed,7a1f5902,63de2024), +S(80aa63b3,1fdd0d2d,ef602bab,dd88a15,71abd052,270988a4,63abe269,fc489fcb,9a145d0f,6dcf0edb,a4873287,a2f221dc,4be613df,f70f7755,f28879a,6e7d9978), +S(ca9793bd,796ae0c1,d778f3,6445bb8b,aa50d859,4be28fe0,ea1e2d16,30972503,7304af4,4c56106e,f0064436,c09b411b,926c4c56,cd82577f,f8c01ab9,9f7c4c6), +S(4cca305c,baf6615e,8cdc8a58,f3a9e52e,97ee20f3,ef080793,ce105a03,a1f1d3d2,637ea84c,9578321b,b5dcc239,7f6206bd,abdfff2a,128d3645,47d474f4,8a8ae493), +S(cb7813b1,a7227a24,cc53b458,1985592a,a9077113,28fb2a05,1d4972a2,3127a913,208b7263,f8f8193b,76dbfb1a,6c4f9264,dd12f63f,e852aa8f,8375fd00,eef83482), +S(d61676be,a11dd1a5,79164cfb,b2488e54,555d7d55,23ddc8a5,454c49e,4a86d8ea,1875b5d5,6db950bc,60b1eeb8,17a94af6,5a19f690,d48aacb0,e483ad52,61995cd9), +S(7142872,6f59c2c8,b398b22f,2ab5c3ca,e803a34c,ab580947,9b7b4d83,1f8e8c0d,3702510e,324c0911,b3154c61,e064ba23,68eff5fe,6f05353a,34980ec1,87ab9ad), +S(72a73d15,9cf7f79b,950971b7,1c66f362,54d13783,c5ef67b8,4da61dcd,4cf432aa,77d711e5,c1793c36,eabf9b86,bf3a692d,234f02db,e4d5854f,5deef926,b9818d2f), +S(ab3b2de,c0a8f23a,a7d3b9d2,88870969,2e45ef47,37a792a5,d65af92b,e58f6347,ac4e4ac9,1bbb57cc,1437e612,e4d4ce37,3d4f0286,5905b621,56826d80,895cb48f), +S(fe5efdb4,32715fed,f9bbb16f,d65ddf6,4ce9bb13,14a491c3,3bfedeba,cb4704ef,e5dc36f5,5fac6974,eaf9d8e4,232a22c3,8aacc6b9,1225a97c,2e695940,ec795c21), +S(5f94851c,a4149e75,e44a0d8,17e81c75,132eb242,c96ae41f,53f30ab9,c8c828a,d9473c47,505e0117,1a0f8682,777d0ca1,7399208a,b03974fb,4014f5bf,c8cbaeaf), +S(5d1bdb4e,a172fa79,fce4cc29,83d8f8d9,fc318b85,f423de0d,edcb6306,9b920471,d7bc7d98,86c861d1,86b4466b,c75dd9a9,8614e166,693a9184,8fccf998,847cb2c)}, +{S(8cf1437b,d87e7faf,550fcbe8,81b0741c,ae0b48e6,e0b3c3d9,9b1b1924,2a925a26,17b40146,c313b1c5,3bdf52e0,efebda45,80d86783,910996fb,8b2d0acf,9bd253a8), +S(fedc65f0,d622743c,53fa6172,e68d983c,2c9b8fbc,58943f48,ad06a852,c98403e1,ca5dcf28,1a2f20d1,5fed06db,89dfd290,8c9d32a,cf40fe6,817e861f,7f168ea9), +S(846c6a48,e771b90,4ae1e8d9,d3daf1ff,d1cb4c88,bbd1de98,454bc817,954654f0,5a4947a5,8a0ab994,3cd0a90,6c1d1f0c,3fb73d2a,49b9c0d1,a9bd35b2,99475dd7), +S(4998795e,a7d80937,e4abee13,6c14585b,40b2dbbb,3fd3c80f,c8c61b45,cd1d59e8,8c817eab,e210398b,59b31660,267c099,baf29e4c,894e09d9,a50894b4,ebbe97f6), +S(76c29921,eb3f3d12,5c11b906,3d1ac276,a205804b,b3e7484b,72ae0483,e4b3c517,48d8a8a5,fe658e1a,4d736bd1,8f07b5ad,28cbb775,d9388e7c,4fecd837,c8eb964e), +S(78de8fb2,b15ff39a,487135a2,636bdcea,57bb3a14,efc329f5,a06bcefa,7ffeaf09,a55c9e98,5e1f529b,ba7ccb6d,3a5c00ce,28cb14f3,e9012d5f,9f66d8cd,5e45113d), +S(71fb3464,b0600c08,7fe70906,2792a676,27830e50,a0bfb473,ec909530,30799282,fe036726,cb928a8a,8affed30,38977377,2a016e7b,1dbde8f3,6db810d7,cd423f36), +S(f1f23de6,bf779cfc,d864dbc7,b46009cd,d2306b1d,cd0de2c3,65f3006e,565d9e21,84f5a011,74ff8e7c,c9a98f52,3f2980eb,4b013695,f6239016,9cc5a1d2,acd8193), +S(f18909a5,a5db0daa,ece22ac7,12ae04ee,53484793,6fd8355f,9ff5ffcc,ab6ca78d,6306f08d,13ce2b0c,b60b3b8a,b0bd5f46,b3ef2a83,7edce51f,2cb5ce41,79f46344), +S(7598d96b,189f476c,bcb1992d,9a38adcf,9d1b6ce9,6c87058e,24584514,a0df4770,7f288be1,b82da02c,a37f655b,d23643ba,bf3d5cff,3b6c2726,9ece7409,ed78bcd6), +S(1e44193e,8223b57d,8fc68641,924cded8,3a04d806,cf9dc18b,7af06010,4e6216eb,45ea3ada,fd726fbe,2b1d6fd1,858ccc2d,57b237bb,bc2965ca,ebcd1b63,53c2f2e1), +S(80954b78,4872286,8fe38891,2d76dfba,d676b4e7,7901e559,dd5983e4,e908f13b,6fe564cd,a0966639,e0237f29,46e92d29,4aee124f,cb33da53,974e8882,b0acf22f), +S(6dd8a9a9,ad7196c1,3c36464a,5cb9fb41,aad8b0cc,423b99fa,a281c5d5,a6ce6ead,79a51469,8767adcf,ed287aa4,914eedc5,8382af71,5485c2aa,c3a77c4,efe2aafe), +S(1895cc13,f99534a1,187a3d65,d1480669,f0d0c0bf,b42b2a9f,1a6392d8,7e1d2c6e,b7905afa,c0eb9b66,51de3583,2cfb9ac7,ae8d2355,1e334d59,32909de9,ed400a0c), +S(f1efcb8a,86f94997,65b38fa5,8edced68,7737b8e9,49dc05f2,190b359d,9ed2c0a9,79b2c874,22de216b,904572b7,a39f320d,f53e392,8dd8e533,a1a28d93,fdd4945e), +S(2944af80,c207d107,ce89fb90,ea6daa2a,c65c1360,503c36c5,ad798333,90432ce4,44b53d27,fd6730f2,33b8c29,f1256136,c637740,86e001a7,60bc1ff0,f8b6211a), +S(938a1dff,117540c8,f6ee7df6,2d3c2cf3,31b38593,131527c3,9804c6d9,874752fb,4683d049,f096bc21,2e0dc20,a8600b8a,a02133d5,d0ae8d6c,b26e4694,ed6f2aa9), +S(b1b3b2c9,54d1fb6e,98fcf939,efc18803,2f693989,81f19c32,f5e55b30,1f59eb16,423a6754,1a29bb01,95adfe15,c1df1c9d,81394e96,2bd1926c,cc789f5b,eef9ec29), +S(52e23f2b,19048d43,b1725695,e3bdfc7a,f4ebd2bf,594f013b,b80d6d0c,ec10632f,258a6236,67090b8a,73881e39,746906f8,eabb6683,4bc3473e,1c6fa8b6,54641cdc), +S(5799a463,cc817bfa,26bcc543,efe0e00b,ca9d2320,1989e854,620fc9b1,ffc14afe,645238d1,8c69338f,9c9395fa,5ef7c9b0,f62b7dc9,c4c6b9e,c545c850,95b6b7ad), +S(1c493b52,3f5a4467,6268220a,58246228,608a603d,f6edb1c9,1a90b060,70b16069,8d311a45,5af92640,e9fe08f0,2981db57,3b22bf4,8fd5e76f,31c175be,23e24fd4), +S(84f5a9c9,cda291c0,71aa9f8d,d7af5a8b,f2ee0dda,fb9139ed,fee08f0f,3f9cec2,df381327,16527be1,d86991a9,bc28966a,c3c6c081,4fc0def8,85e5d160,f59f4458), +S(712c18a0,ae87e7e,87856c8b,ff6e3f6d,996ae157,970e754f,bba80bee,421fcde7,b2788ba,e69d34ba,eb5dfd62,830396df,3b8934a9,551c6070,ae8203c,ccc50ac9), +S(a5104184,ee996a34,7122a460,cd2eba5a,11d04aaa,a47d2ede,25ea13fa,41ee01f4,f4b5f2b3,f7ec9061,7ab5f3cb,763233d0,afc8d4bf,fc535076,5dc5fd41,cc547ffc), +S(79383075,a46a8eb,559ac95e,7dbeb9ee,51b6e906,27e55b9b,922473fd,5f2eb63a,243f56e9,84fd2673,58754a67,2bac56a7,9ae71a5d,68150740,8eaf8c2d,b55ef1a0), +S(2b22635f,b83ab0d4,9b82edfa,a54d6234,8d3bee6f,edbe3315,9470b18a,96f97821,41d9f3a9,52f17182,ccf02725,b58ebd7a,1f37235,1fbb8f2c,15403890,e8b25b82), +S(272fdefe,148ef7e6,957fb8a1,4a07f0ad,b17c27ea,49532547,5114c1f4,76170a0,789b8eb,5846e50b,d489bf66,cebd873f,7cf05619,3674e7d7,147ea691,6a9b8451), +S(2c2da4c0,8a6e73c0,2efd6e7d,13006135,f09990a1,4c0a0eac,1f286108,f4a2a0e0,8011a521,d7fa0ab2,75765bcf,50dba163,9e89c9,300e8a25,31942cc3,fdade63d), +S(19a9e5f,1c4cae30,797a98db,a24051a4,38ea755c,7b062094,a34ed6e8,8a8ff2cf,e199e398,157a50a1,56f9d6d,afed48cf,f3181411,77b792ca,c5881898,24f1b8dd), +S(f7a4be3d,fc6579fb,43c5a960,890893a,f4026165,ed9e3ab2,e6929378,b63968b6,29221093,17dc39ea,de2d6fcf,c735ad2d,668fd047,2eefefa1,b6b225cc,2f3cb3ad), +S(e5380fe8,575f26ad,b7924ae0,d58138d2,68112776,b11bd34b,3eb5e196,33f0e9aa,4680278c,6f784be2,a496ec9c,6db371fe,9046b1a2,b97ce71,3b45bec8,bf7d8a20), +S(4c1b9866,ed9a7e9b,553973c6,c93b02bf,b62fb01,2edfb59d,d2712a5c,af92c541,3e086d2c,df4175f0,804348ac,31a91963,39ad1528,1bc14e52,8d3b0c01,39701c0f)}, +{S(5a13b9b2,5aa6944,1b0b5fb7,f7665dda,95aff48,e3250b4e,34cf8e28,87406c1c,245f250d,78fd66ef,24745e09,f067f16d,d400c387,66d2a1a9,af51e84f,733d0ba2), +S(617b41c6,8534072f,2302290a,4956171e,902634bb,4356bd27,ab83a377,13d8ef6,c867779b,97383817,dfd0971f,64c09c71,7c468a5d,e1bb8ed0,feb98f5a,305d8e6a), +S(ac118ae,ed46b08b,488202f6,96d9469a,e9af3cc7,ddc8eb71,44903a3c,ee43c654,f992fcea,8268ca6b,79f5ce69,c87dcfa8,42ea0345,d7c85a5e,a1b89f1c,9d0217aa), +S(741dc47d,2e0d1424,3f2bd96d,9033d8c2,9008c1e3,66bfb5a1,1434f1cb,3d85310f,c3135d44,e86f574c,266f97d0,f0279dc7,52aee0ab,8e3ed78b,ee0fc646,c133000e), +S(2e973138,f6cea9c0,5adfbb5f,49a7b928,5ae0c15d,120a8b1f,2d0c76ea,1fdcc7e,a05bc93e,68bc82da,7a7c7e38,95a647d8,7f724f20,c5b312b,738c6dee,90de771a), +S(9d938d6a,cf56104b,5522351a,3c424e01,e4d21c33,771ca94c,f55357fc,fe51f91e,881d05fd,4658b08b,edf87396,be3fbb95,ec9f371d,79ff4586,6ddc803b,65ae763f), +S(37a8ed2b,4085961b,84645ad9,8f2c901d,fe9a9a8b,4de8fc89,2cfbca5,c8909835,b1bdacde,94fdc3a8,78cd0eac,f8865d64,77e2cff5,efef834,97b93835,5b7b401a), +S(da1ba954,899cb05,dae6fea2,dc8ddd7c,5ef9e91c,3455838c,a49d2858,ec217d66,14051c3a,12332d70,f8ad8ffa,567765fb,def69640,4291b81e,d3978bf4,51f788a0), +S(92d2ef44,5a10dbc6,73f8c1e6,af093596,13bd1e3,c1b24705,bad2b3de,e8f11b81,adfed916,800d3e94,91a42c59,dd72e3ea,57d47081,b9afe668,f853cec2,c72cbab7), +S(e62208bd,52620df8,91b3ddbf,e6cf0641,6059ce50,be3b00ce,14e7a53,6d1acb07,1fb71455,53b2f4c,431fd86f,c72d51af,5e2edb41,dd3f69a1,9a971371,d9679dc5), +S(191fec47,a48ee268,35ed37ff,6758a80a,532f7011,ab099048,b024efbf,cde1d0ab,47b6389,b3f5534d,a632924d,5b65918d,f65c9c2a,2904ee95,4f24aeb8,c6a02557), +S(60c822fe,a74d52b7,d5203720,b2c2a361,b7628aea,d2a683bd,80655636,bed15714,5d9a9c0,120211b2,e8285b77,8f8d4bc0,b06240d9,22944248,e1cfce73,826bb67d), +S(f602da1c,788ea65b,cc339a38,c353bc08,1c43c2f2,6e05ea6d,ab52648f,890c9101,21468929,89348f8c,67cfdeda,31ef3429,23b5a450,9fbe9a49,f011d42e,57f998e6), +S(756240c0,5274101b,3059d23c,76d9ecdf,33e1312b,7a36af,ea21e6a6,c52cdbb5,ab24e853,900c7ff1,3e4f813d,a2acdd5f,53ce1710,b785ffbd,e74494ab,43e583ee), +S(8e815b45,7adf482e,e30e475a,4949e5ae,c7ff494a,a918f07f,c39441e2,360d112c,a966f04,2dd9edb9,436b0005,7473aa66,dd19b4d2,cbb3bd95,932ba98e,f1a1f406), +S(216d5970,36c661f2,cf6122c0,a136cc33,9660306f,1c190ee5,5f3bf438,e7189261,5bd23797,c6753eee,6fb934bf,dc897ec1,25b31c9b,9e797ef1,56d8cdda,2ec1d128), +S(a30ed06e,ce34d29,a92fdeef,6954b5ed,4065d592,3af09be4,f0ad4a73,e7c24346,f6aea418,6b38c188,b84fb6f4,2b6559be,f52dc13e,b7ddeccb,6e85a76a,8d4efeaa), +S(aa42d20d,8acf7c47,fe40ac15,3fcaf1ac,6c4ecc37,dfa39c39,fe5c7657,c78444d5,bc3becdf,464ce930,e42a05b2,c52d3589,fd45ff37,c7d1767e,f8462811,89634059), +S(7585f8cb,4812e306,de02393c,c06e9871,1953133c,bcb67ec5,c6a79228,69124ff5,c242853d,1a2c1c9,a1cd1b5b,364888fd,28bb23c1,2b0e169,67961b3,e7c8b95b), +S(b096a1aa,fb969483,185ba1fb,a5fa3f3a,d1da87dc,a10344a4,d74ef471,45cc45ce,edbc9490,23801861,44ee39a5,7bdec0a,230df57a,72649e04,c4c99883,a147f0f), +S(7034d8cf,df226df1,6b310628,35dc02c9,f3e3f91a,635ad93c,46be292d,56c0ec2d,f783b6e8,29447cf2,32769a13,7ff33f82,f9fb166a,aec8c3ad,1679c48,c1a913a0), +S(9f88b01b,b936defd,f61156a,b55ca290,cf282a2f,3718b0cc,2d32dd3c,49248b4f,c24ebc35,27052f77,41087cb0,e772ce12,1035042e,603f1301,e19cee0d,30029230), +S(14443190,51f05d23,343367e9,6add133d,fcb63209,2f218847,59ad81ba,c65e7445,745216d2,d11f2556,7e3b224b,6dce478c,bb988b96,a1240093,964e4ba6,f3b15554), +S(54aa2e02,3038fd83,f17a633f,d9ab441f,e039dd0c,57f9368,3da013f1,751c6813,f4d163ac,a9af3e08,c009b44c,b358ebaf,31aacc5e,e0bdb917,d1b4df5,420d2d34), +S(fd44e742,b04ca4df,693e3109,3ec52ad6,1f67264e,100618e5,88d638d6,d96efa41,7ac09cb1,2134a246,b17ce054,b38f3bb7,7d794f9b,2fca3786,a0ba665d,3eb0f14e), +S(f662f214,10cf6e6b,7f79fca8,7ea3925,6760d83,17478419,ff4671f0,2bd2ab6c,be4ad0b7,a56c87a4,8fbc166b,da8473ba,6518385d,bd004b5d,c85126bf,7b9309bb), +S(520e2755,1cd804d2,67f9b4ca,b3986952,612bb099,cbd3f3be,a54f505e,bba4db64,e3c75cd2,c831c539,b095ac18,3bb13a72,ba7cb152,5b9c214c,288509a3,98a9cc3b), +S(4d16fa3,2d74de13,111b3f22,c4133ea5,377921ba,e54af1d,666d6e9f,b01e117d,a63bdf75,78d73f03,75aed657,fbb8675,67230c3f,868f2cf7,b7275ec8,b02ac46f), +S(ab928c61,ad1c2f68,905b9e95,3c2629ad,9bb7c8cf,ad9f5a4b,35b35fad,69a92568,bf39ec2f,6c1ae222,ff383375,6bd83882,c05be6ae,692539a4,5124b972,e72159ee), +S(8731aaa4,93580732,66b96577,7bc24a46,17fb8363,51c5ad8f,c8bc053e,802dd07d,36957f16,1020430f,69a3b1c3,1a6df993,d9ca8e2a,8f487b7f,b2ccd44c,7f528ce9), +S(3514d41e,8b9388e4,33d1155c,c777c398,22ab36c6,3c2aaad7,ce674831,21231d11,7657cdaf,e9fe8147,10bb2ee1,a97c6100,6c7b0ce2,f5086141,ac2904be,1c7a9e3a), +S(9bb8a13,2dcad2f2,c8731a0b,37cbcafd,b3b2dd82,4f23cd3e,7f64eae,9ad1b1f7,6ba44d4d,50111c46,490622d7,b079c17a,f0ab57bf,b8ad2ac,9becf9d7,3c7edfaf)}, +{S(e60e88f1,dc24f079,f835b687,778307af,83446e,71809086,e6dac0db,9f191de4,25a0b86e,ff05c849,d79a176,1a634d82,29d2a759,fbd003c,b6ca4147,85726362), +S(55a5e6cd,c9e11103,749d469,dae84a88,9e744dd5,d9309762,15050a83,fef66fe,31278ace,a971a41,e2f9fb16,8e80ec03,37009cd5,b0a49938,c28c902c,a7c71fd2), +S(5f25326d,e99a7c5a,d81bf2ea,61a9195d,48832bfa,8caa9777,53e483f2,b5a62580,40b69a1b,baa2d0d1,5cb78a3d,3d184c08,5b4c16d2,90751ec9,bf3eb3c1,d3ec2ab5), +S(1a32cc7a,f88976b6,cbc89865,89e685ac,49381a29,1579bd2a,13f9488,c0333d19,4667a3e2,2048f781,11f009ae,5d7b1b97,850a3a5b,86f77880,b128c8c6,a9720acc), +S(1d78e74c,66247be9,352c9797,5fbc1299,743f9c74,68c64d1,f2d8affd,1b098769,37adf553,fa2a11e2,6913ab02,e59c4f2a,48133fe7,d9aa3c24,a76e9af9,48a29d8f), +S(8bb6f83f,6be5c2e2,b2bb265a,9bb3c931,bd5cce6a,48efccdf,daa040da,535dbc86,eb96a982,23278b81,6284fee7,b5b8a121,7350cdba,d56b6078,89602bba,bc003481), +S(a9f19ca8,1d2ebafc,4bb5d881,76bce19a,d2d2564e,185f905b,8f9eeca5,d6b12d6b,ab23a468,3279a9f8,e2e8f880,e0accbba,844bd4e9,4d3e4b43,74db2b55,d998771e), +S(19680305,c887467a,c3bfe44a,dbe65431,7323d8e5,62271e25,1a794b78,618befcc,48e9303a,3d6371f7,cf0a904c,cf16f606,b0007583,87ae0952,c6119521,dde25532), +S(18b3bd03,ed4696c4,7c3f896e,5df7481d,6f19a5ef,53d62ff8,2948f1b2,154175c,85fb04fd,6573a19f,2c136753,a1ca2585,d39dd64e,6e6e3fa5,fba362b4,ae9dad36), +S(38e3bee1,3cc3e18,a57aef97,4ffee58a,a392c311,14ac8baa,1376b56d,f8ac017e,8596c7f9,8abf3e44,4ab5491b,fe659619,f6defb58,f48e2b7b,57842193,cd48fb5c), +S(dba5da08,8cd17c33,3e892bcc,46261694,d2ff3a22,2a26f92c,17c5e1e2,797b235f,ebc15bfc,5729e986,85a19afb,d7f9a219,e60d2784,e9b283cd,3697f782,630fe222), +S(60456426,caea7fc4,48970eea,fab9c632,3e66fcee,50f92630,7b130937,25b85ee8,dd22df89,c5dae339,49459593,1433f2f6,5f719379,68e56f92,a38d1290,17881924), +S(f1ceac82,15670212,279f36e,f0c8ce28,3a192f66,460e4875,d90b2f51,a38f5712,ec11f026,c76c271e,fabd7d55,c8488d99,3298f6ff,c05ad4a1,26be9447,7d878b9e), +S(2c2fb5de,5dea249a,7bf6b196,8bdec8d6,1838da2c,12147045,18d6494,f09e50e,6c0d020a,d6bfd730,5ee73634,e939ac89,ca2b7d4f,dcbe760c,2d14ade2,659a5b8c), +S(2858ea8c,d40ce264,3c9a305,c0e2c758,af5b0b4d,5c57ed21,60cf7ec4,154ffdc2,33586bf,a61a3cde,4f402bea,123c69e2,2410c0e,590a71d8,9a1e8130,85cbb579), +S(2749a250,4e7cefa3,a3647088,6bec22fa,339fec0d,ec63c02,19e6af39,7fdec3e0,d3415104,a9070af8,b61acdf0,77954d37,57fcf742,a006129a,5c0d3529,3aa95407), +S(8edf3ad8,39e661b5,f7f16a85,dce3caf5,d571acf4,d0c6195c,53b618e,5311ac65,fca0efba,35a14d3a,9944367e,db4ac982,7dcb7aa0,12438c5b,aa5627c4,c4a15ed1), +S(dbb92358,8b083294,5d6d3b62,9cced57d,7085d3e2,d0890bde,95d80400,98c22745,42816661,5515429a,aa023737,5fb77804,624546f2,1f0a34ac,1ed4e4ee,dceddccd), +S(aaca9896,6196ce2,e13df3c7,d058a5e5,10566df0,5fefc04e,51f9dd,85a4349d,be389d02,789548e0,aaf67c57,3b91b389,c7e6ed80,ca3e637a,2a147262,80cd5620), +S(104804ab,e621b098,61fc540f,f4d6be9a,750e3cfb,706170db,e34c06ed,e0a431ea,14b700ed,a465915a,eff84ab9,fa568535,f63e4f44,1387ab4b,d841072d,97739071), +S(b2215070,a8ea71f9,b71f1a73,d6ce366,c322b8ac,4d135b3d,ccea68e5,a51f1c0f,9e415cce,3bcc4e62,6f3c8caf,fd632eea,862a046e,bb45e8bc,84fc05a7,a4b87e00), +S(600c6e28,be5ebd28,d83e6c86,bbbd9b0b,aca22006,42234634,6124133f,3348e6f7,822b1816,79e253db,a47ddd76,c0023991,5c0c0206,8f422415,94ac38b8,ff7994fc), +S(f8b9b45f,c6298dc7,13355bf1,3ee33ca9,c4c1aace,c09776e2,56b3746d,ccae0dc,bf4b7f96,1844aa2c,6ed8c8a5,6626386d,174e77fb,98c0c23e,e2b6de90,3f1f79cd), +S(63987b18,67fe5a17,333eef28,5385a0a6,576163e,2c74cd00,ba87b6fc,96a57faa,23ce6655,51d48ca3,c702a5be,87a05d98,b5aa1097,dd5877e8,11e32d76,4873e6cc), +S(2eb06c4f,5ea9ad2b,124a1202,cb13c1ae,aec4394f,4af7c96,d6a9ecba,540ee04d,b96173dc,77b46ef0,6f4141ec,96ce8d1,4adfcfde,f0bd7ea2,479ba6d7,522d037f), +S(5db39904,153002b3,1498bb01,16efd0b5,838e3495,62d9428c,912987f1,3aae5ae,2115b896,479d0d0f,75ffcb54,ff9e3f73,d1356ff1,4b14292c,6bfe8d54,e9e08861), +S(c0f14110,7f324ffc,f3d3e6c,78d5a628,6000d57d,7e85bc7c,fda15f75,79cef3ed,6eb03650,c8142b12,b330b96b,81214a4d,d01b068a,74827611,53d2c52e,e1315ce5), +S(7e3d1510,ed767345,bbb3515b,6f9819bf,33ed9dea,fab35d01,a7284cc2,371b0e66,4c6b3aca,5159023b,d43ec0b2,57e77e87,e5a6b745,178bb017,9960c89,361fd97), +S(f98b5dbc,3e54c227,b002f458,94850ff4,3b15b2d6,1607851c,50d1e4d1,8b20907d,1d2af742,b0b5ec05,bd6c648f,94563361,be03261f,da56f1ca,7caece63,a336d580), +S(188ef3bf,ab103784,37e1859a,7d53e899,6124c395,ca422c05,d6b21b3c,efc76ac1,19036685,fad04566,2ffa04e7,30c671c7,1b299217,c389c78a,cae9fcd4,ad70fb73), +S(b89070ae,96ead4dc,49be16f6,a1a30bc2,41b4e98b,c18d0227,4c9d9d87,dcbf00eb,90db373d,375d2770,b8dd6b1b,3e3b5899,34f274f9,49469598,e480e431,e4f195e1), +S(381c4ad7,a7a97bfd,a61c6031,c118495f,c4ea4bc0,8f6766d6,76bee908,47d297fd,6c950ac4,dc71111b,70c1a058,f66ea133,fbaefcd,246c63ff,6c531ce6,82b6bc6a)}, +{S(704a26e5,19071bb0,24eb2a16,48b66a6e,157b07a5,52fc4258,381f7d02,e8fd9b9e,d169ea55,8650aa3b,ce52c645,278422a3,69326e74,46039381,920f5857,fa3492fa), +S(705063f5,e481735,60afe9dd,5b2beeda,d6e46391,75ad7fb6,f73350df,51edf53c,32290956,61cacec9,472dd014,bda52364,3399d7cd,9ce2bb31,a5b23590,22c6ee5c), +S(972e7585,f8b1725f,4a7d18e7,77939aa6,3600a7b,a07c4d94,5da9511e,889473f5,aae4382a,49b4c97a,bc3edb7d,26ba7bad,16752047,dc99b434,f306c673,2851310b), +S(260530bb,e338f4a9,71930b12,4f18c82d,e33f22d7,32de9375,81e2b0d5,15e59d97,77c66c36,d6b09205,8ade9c0c,a311b60,a705c8c8,73fd2d4,8e6327cb,71eefd4a), +S(15464351,d21d2513,f792ee32,aca3eca7,a52cdaaf,9862172a,e7224a03,804581dd,d9ee19f4,502f1c44,f656ad4e,add6adbb,d8a04f5e,5344b554,894721eb,8e3e2285), +S(4fcc68a3,caf3ff91,dcce9770,11ad5157,6c844132,321791ca,a652593f,6cafcd04,e8db3aea,a35371bf,9700a9bf,b85e90b3,93cc088,9cd655e3,fb18635b,49fb59eb), +S(301c65ad,567952dc,6b39134e,c361030b,3f5203ed,da89784b,225548ec,45c75eee,95e2c0bc,7b4a7cde,8ce3dace,a691bafb,f78fb03f,3170b347,ee807f42,6b947560), +S(96ca5edd,8047ec6f,b5f8c37c,a734533d,13f0e6e7,f55d28,b8b10b5,121f4abe,1a21f1ba,f6a2e336,247f6ee0,88cca9ff,816b0667,3badc241,d9ed00fc,d2070f1f), +S(c94633f5,783c4e68,12143fc4,6e670978,8e8a526,819afea9,404dfa00,df1bd839,874f8760,33dba9,de463f86,b597219a,c1ea37f3,970bdadf,97c96c48,feec4ec5), +S(963146d4,5bdaa05a,b5115ac2,3ee862a0,2305ba9c,75003f4e,ab838f7,e9adcdfa,d75766de,299e5cf3,c8796234,5db9866c,cf011c5c,f108a794,5642a6b9,dd33eb0f), +S(dde8c870,ec4e9890,2a820a7b,c5784034,19ac261e,de5afd0b,82b8c5a0,7c2863df,e7833936,50d4af7,427158e4,6c753ac1,a5143c9b,c09de97b,3b27065,6f622b82), +S(546c6b00,c5e34a8c,4cc7255c,2edea33,d9f77e7a,c67ee629,bbdf1879,4622265e,5ae149da,f65aba8d,e214fa63,be9bbf11,3dd3c220,12d206bd,d56026e7,4a019897), +S(4340c850,d91b63fd,bdaf41bc,f8d8c010,d3f30eb5,79eeefc9,e67c127a,33324071,dd66033e,eb5ae8b3,3c47a940,2482bcdd,4db5c8e,dda3b422,35627434,dc3bad1f), +S(f796431f,679d9cb5,77bce62d,236d1fe9,b5042a83,fdd1cf94,1a2e00c0,5a261d11,718fffe7,68aa2591,d3fb1fd6,1a00537,3b529f9d,f9c27f79,31ad0df9,9aa74859), +S(f3d17ae9,d5b4cf41,27423894,916318bc,adfb5a9a,6c2ca219,1b918e43,eb5ed129,9da6d033,49c64d79,7ad09a33,bf71cf87,8e0ae6a7,9fa7bc3f,1451126,18415960), +S(23899a73,a4b52d27,29ab52a8,370ceef8,4c7684c,cd535f4a,ec360eab,cfa5a787,f1bcde3c,5c4740c7,37b066b3,8a1a88fa,c43357f7,f3fa23a7,b00815a3,85336320), +S(5805914f,5418971b,106305cf,c397dc12,f63a3b2d,8b451e5d,c1b60c2e,3d9e9208,616e2764,67a5f1b6,46279ee9,6e8645f3,76a80192,31e17a5,c92e26ec,1b76e62b), +S(85ffc326,1991848b,5e918c4a,53f291a8,31796b52,d56a5c38,8bebe625,d78cd07e,95fd6f12,7b155e6f,806c089f,3f5abe95,344e9014,e2c72fdb,e720bb8a,93d864a6), +S(6f1a57d0,6566bf81,f4b16329,19f477ef,aab4f829,e29dda4b,27627b96,1cbfe3eb,de1e8359,7ff20c63,3d28b909,caef273a,a57898f1,a797fd91,e00e2e7,da1872f4), +S(3d28eba0,4d0ae2f6,208adc71,cd6af3b0,e208860c,722903ab,e106feb0,af3185e9,cf8bad18,40d3d2b4,abfb5b28,b50702dc,512527d9,5bcd403d,9713ec7b,ef1dda13), +S(46511979,2b845113,1b32663e,baa14c4,20a5408c,1f53afb2,43cd496e,c4b18118,40bd602b,d740096e,842b40fd,8304ee73,842b074e,415d5ac,c5e2243,28b241f9), +S(393a8bb8,7ffe4265,51678524,8ac940c6,4aa70e71,512ebbc2,3485596c,a6d9da5,25773032,d2c1f80b,3954715a,6e4132a1,74b4468e,658f6cc,4d5f5d63,d458980b), +S(aeb37eed,35274696,2b85a21c,86b9fe34,60433606,9ae4ce6e,3a8235a5,e43c48ad,d94165e1,5372330a,7b5507f0,377a966a,541b6fcb,949398c8,dd6d6f52,2411d86d), +S(b0bbb4d3,100ce417,dec58f46,95ed8b30,4306f21f,ee11f899,585fb37e,a9905c59,89141fcc,9344e617,7742e31c,42c565d0,45c7ccb8,6f88df7c,5c36d23e,45e51d75), +S(49694de7,330b4c3,1431d452,f3e9e562,eddfe029,1cce58c,73b69cdc,b89e0f49,4715ea3,b6fdccf8,e224b93a,ffdfd1ac,ad8baf44,c5bce735,e7c9b4ef,3faa2656), +S(9a7720b3,ff0363dd,7263e1ad,83c32526,67b67d3b,72c2c14c,95f0804a,dd20f7a8,815a769c,494824a,a819ea,54b560ed,e1df9bca,d7df2d63,aae69c4,a02f9f20), +S(b89c399f,cdb3aacf,99796fd0,95c17cc9,786d79b4,9a1a255d,5c9ee510,38d3620e,ee3c4936,d4f9d1f9,d2642043,d25b21a1,aa32fa3e,ef44f409,73db47a,96965cdc), +S(add68bac,d7180ac1,4e9bbc5d,1e0c3911,f2202d90,1f9ba649,46b06507,b86ed5e9,fcffc13e,a9be67be,8d090a77,9fd9107b,f62bc785,3f98e97a,c0358b3b,7719944d), +S(9bf62cdc,cdabe928,c1ab44ce,38cd0611,135971ed,81ce6c6f,dfc5eb5b,d9c3996f,885b2381,e0e785d3,cc3f78c7,f9fd54b,ecdd9d9f,c2979e23,f97e9bd2,a4f10d3c), +S(bb223cee,f11450d5,c5e0b75d,20eb44be,9d44dcff,28574117,12fc5875,3b839339,8bb29985,87eb6f5c,c8cb615,285d9e69,71db8e31,8d81fd5d,6318909b,8311a00b), +S(9ed73f09,2263e84c,d022388e,da82361b,445f573d,b646cc62,fa0bf5c5,1d33fd27,49ce7698,144e1115,118a4b0c,bdb98dab,6b57dc1a,4d1bb6cb,a68d4d20,d8e937d7), +S(e747333f,d75d5175,5a0cc9f0,a7287084,65a02c58,7737a7b8,b8fa1b8b,4bb2629a,d5001fe,baf8f3ee,b33bc9fc,7fb3da7e,377c8955,91e56965,607269e4,96b90559)}, +{S(516ea742,3f956765,a15f856,182f1e7c,18d3e548,b9fdca94,ea46024a,1a8fcbc0,cfddd98f,be500604,28beb901,92c01282,aaf9ed93,76f0e26b,e912ac42,a378d542), +S(8ed072cb,13eb90c9,e5c107f6,ba576a87,ac75a431,53025e6a,86addb95,bba7862f,eece8a5a,f28d356b,f1a84c14,2549ae7f,894f7c07,305194f3,18e30e0c,873fb5b0), +S(3e0e488b,1c8acc24,f81bfa1a,f6761afd,b4fa5f5e,6317ba72,bfba2f07,6c2ff593,2c4ec39b,2f37b948,fdbc9e3b,a3fa82c0,dcfde2e2,57830a04,4c178759,ef5bbc8b), +S(f6b3f19f,cd7eac5a,13630ad1,bbf331b9,5608b7a0,ceaa67e2,4a1e830b,5eed9825,a2a64078,19ba0f7e,7a890df9,523c6736,50ad08d5,c2557cd1,53c6ee65,ef493ce5), +S(e2de599a,879285ad,398b1031,8e1a8387,21a5c4f7,1105469e,affc8e37,189548a,dd977e62,3dc05cd6,3155a71d,d87d91d1,d74d6e31,5f73434b,679b605d,9db264df), +S(bc52359,683840a8,59fc2c8e,22d72ec5,da2493a4,bb5073a7,f658517a,de83f867,76a13651,712ff42e,a0c10f09,45c4ce41,2cc8c4f2,ac3ae446,7cb383c8,656d3186), +S(d87e2b08,154e38c0,13847a5a,2f84c276,dc088b6f,c19a9bf3,90a8a433,fa937fda,d91447f,7c9042e4,6f64a9c6,40a5c294,1a6f08f5,d3eed464,b09b2a1,1c402c0c), +S(4359ac5c,5dd70bf1,d4f24f00,1301b9f6,17d9c69b,63350dad,9a8cd192,655ea801,c9e14f94,d8ec39aa,46092657,5d770426,350794a4,b1ef2410,a9b0118c,ac5d55c1), +S(3ab3f503,29e22bf6,8fe9882b,3b4dc989,36dfd840,be6af588,ab6d61de,48094b9e,4a40c435,9f4dd21b,11664095,4b55e6b9,f0308786,eec32fca,6bcdd5d5,8d055ac6), +S(a0f1ac27,d046d987,b9a98bf3,f770205,931fce93,59b75944,6494d221,dc2752b2,bf1bfdc6,47a15997,97b5b6cf,2d8a2a44,e9c36b9a,20b53abe,58ce9e0a,395fab70), +S(a9aa63ed,3b0260d2,b35b030c,7a5511c8,679b6170,b8a4f386,fae0bfa8,92735905,2f654620,4dba9b31,99bd648c,cb1605f7,62f312d1,67123d98,ed66f02e,4d794e90), +S(e51da157,5e566ef3,bad3fa66,e55432e1,29be6c36,32e390c0,f4d76719,bae34b7b,55930b79,2ffc91de,674820b1,eec290d7,74ecd79d,1ca07d6f,5ea2f817,4759984e), +S(8b69a891,b417ea65,7ba52bae,58920eb7,f101bb92,e150dc1b,c961c37e,73cd18b7,5b824edb,f4a68988,39de0d70,ec16ee1c,a01a4692,f29263e1,1069aec8,6b149214), +S(ee5c1186,77462649,6d37fba,e48e797,dc69f31c,d6ad22cc,937c7224,ef7ce8db,13f7987c,f2cc4551,e058d410,3d5c24d5,13c2d602,ddccadae,fddcab82,d14d5310), +S(b961cb45,5de8b5b6,c4c5c2d5,75303c81,35b5d278,503a15d2,371b0551,5b236b,3ed18486,5ca969ba,31c734a,19055129,1cd664be,576925a3,2a142769,4fc40df2), +S(83effa4,c127b5ad,7a0c53df,5be5596b,d4a42987,2eafd8f1,5498a6d2,47b87314,efa99759,c9360b14,7643de2d,64ad07ea,39cfabe0,2bc94e00,dc9b2e70,c2e2c217), +S(f253fc52,4fb0254e,e772f50e,5d6c16d8,48692455,c855d4be,15ea9f9e,9a5411dc,59bd1f8,2cece609,8a63fa1d,48e4166a,d79174ec,5f8216c3,16c48c1f,e5c9a0d7), +S(6b61024e,e6451d97,1446b55,1476c3ec,eb6b19ec,16155acd,317bc2be,11086411,8de5c6e,37b562da,ca5a203e,ea028b76,e6befaff,e54b49d2,6605f169,592242cd), +S(1691a90b,9cf72621,3680a72d,af59ef24,985448ff,5f35372a,ab6e2aef,df8b33e5,83d2032b,6ca761d1,286c1348,31250054,5a230558,cba391e6,f0db9c9f,97c2d618), +S(42a078dd,cf749f25,aec7a1f2,8e976f79,e268c36,a7b5b0cd,6aaee3e0,925746ea,c60f1846,6f025987,e0ea6ca0,3eb98df6,99389753,b57abbf4,f5739509,bfd09d1e), +S(21bfc1a7,16b09543,5142c31e,5038d4ea,4643d9c3,2fd4728d,1374dba8,1ca1f07a,a991d491,2601ca23,8e289e71,e9d743da,4385aed6,c732f808,6dc21406,74540acb), +S(e75223e8,fe247a98,5220cbfe,52151978,c98d1460,746f8de2,8696d235,71f3336b,dbbb8075,ab489582,52472982,c7b0c3bb,d82a0762,36c07c05,44417ff3,883f6f18), +S(7a756a,72fee88c,7a2758a5,3294da85,6b06129c,1978e217,2bc7952c,92b05265,c4ad3a0d,be72fd27,bfa475d0,fbd16a92,5e939362,bc0748c,c39ba9f0,3ad84133), +S(2bc697fa,d947fd62,63bb2841,1a274520,f5d582f6,7f039114,293438fc,9aad7c82,543109b9,82097efc,cb44d854,11fc5230,6c7a219f,2f58b37e,3dd354a8,2ffb28ad), +S(3862db95,1ed8994b,a8cc0178,f6dc97ef,db6e1380,c18719ab,cd24a88c,87039744,af1e8ac9,2b195d3,6fe1b1be,a68e9215,a453e638,67e65d88,64a8baf3,ff5c1267), +S(7b648cfa,40ce7274,59a6fae2,2836ea1d,b18ada4,9b18a61d,748127f7,7ceee771,f2a30c56,42887135,30124a69,da2c0355,8688bac3,dae6d95f,a252855,a85a9b4f), +S(f803d7c6,1820f980,ebe0b297,87aa688c,ddadefca,229b99b3,a6bde5e9,922f94d2,a5f8b450,34dc7de1,461dfb74,e7ed9c49,80407bf0,4b0d9159,af703a9e,1e0f9c61), +S(2247f630,9be2f3aa,e30c5907,c29095d4,b9198d25,1a17bb34,7cf5cb35,a2ecb1f1,82685964,20d87b07,1c5a4044,b79b069f,7fa6ecf2,cfc0f839,b2161475,5728c2f1), +S(1d770ace,ceb2183,fea7c924,a8fba197,579df37a,908992be,d42c8e80,8bd98ee1,d87077fa,b910a21,8769cfc7,49aad579,c809e35b,f1c2a813,6047e85,e2c6fc65), +S(5d134e5c,5da47f7b,a495f216,b4994d90,4a79057a,3d0076be,34f09013,99f1f366,fc4e10b2,c1f7bafb,d241d5b5,1c57d48c,30fd29e9,df5774c6,1d4f2c15,3b66ed03), +S(a49ed10e,aaab9323,3a5f485d,4bd18c06,28ab2629,f0b8c3db,4d05956d,6c953fa9,338d476b,99f0ac67,1fcb893f,5f202204,a5178acb,6971e7e4,984d42dc,b904afbd), +S(4d000b62,1adb87e1,c53261af,9db2e179,141ecae0,b331a187,aa4040a,ee752b08,95f2a470,e71f2daa,34927daa,7d268d33,34820a0e,e638d6c5,c18d7adf,b7cfcf45)}, +{S(44d42980,eb92b3e3,b16816f5,56858355,e031b88c,99117385,def6599e,f274e56f,6e3de5ba,4f693fdc,747caacd,b2cf0107,f29fa7c,9c6a1a09,a527cd16,4c2c1484), +S(9812d508,d6da303,6f08fa7b,54cae319,232f925d,6af91d71,fe6c2fb3,bc86be5,735081a0,35fc17f6,7547b9b8,f0f91ac7,f0ddb965,19f6f398,dea745a9,81441e2c), +S(5a022ba,a90ddc87,42246783,4f692ecf,dd2c2dcf,b054308f,4afeb17a,7ff6ddcf,6fc2a9a5,4c7a130d,fd26ca48,82406fb9,f67db0ab,7e6a6d95,1675fef,2e2d4256), +S(c181ffeb,a8ea7d69,c524cd42,18af3030,1cac8e97,69eaf6f6,ba73027d,30fb7bd6,e88959e5,b07b7d3e,693756a,f94590bf,997763b,afa7d850,a80dd9fb,88e6e904), +S(e29375b8,21c056c,30954b81,4f9ce795,c1493dfb,ebf06f6f,f32c92c8,c74839f1,a9040ad0,95c9d45b,1527c624,bac86841,a1f28b7,ccf8dd37,b7e950b4,858e6e18), +S(69445948,ebec5ae3,9fcb505d,7efb7902,6bc1e8fd,5d3024ac,2b772439,72142d80,5b6c2694,abac3938,db899396,62635c21,e64fe2aa,40d18678,9c246e9,fe3f4be6), +S(a86f3aad,85d0bbb3,8270956f,58c2fd65,f5425428,27d7a658,da1b111f,64c02c36,dec740b0,ee35208c,dbec5b7f,69bb94f0,7fccd075,7868a37,6ecec7b6,dcbe20e0), +S(ba2bf65f,aac92da5,6c252b50,8dd74e3e,99ace1bc,42b9d2db,9d0ead3d,b6820306,37bcd01a,75027b42,eb0d7b85,564bedf9,67153930,6fc97106,ab6623e9,90b031ba), +S(78419e61,4e8b5eb9,d09e0c09,79ce4eaa,26271696,fcc68269,4cddf1d9,6a4c7fa,a32dbb3b,46f9b6b4,9adf4dde,f1986af9,72662a6,2ed6b6a2,f8b920b6,82b32363), +S(71163271,204207c8,a84b5993,88beb505,640898ab,b24c4c10,42195dd8,15d77985,aab43609,9370f246,7035ddc2,e71d73f3,c0f1aa13,148303bd,840459da,ae307e8d), +S(473f52a1,fb7c3920,f09ba6e0,a3c891c3,3f4a13cd,9dbf51f0,f3d39ef2,d6bc07d0,b2c403d2,4aef71eb,1b834df2,8bc08b67,5130897f,a6d9855a,eb21ccf2,780444cc), +S(581e93b2,99b8c50e,e6338c0f,f426502a,d8699563,f17935dd,abe08a73,6932b71f,46e7c7c5,1e076fd8,9b8aa98c,f0b3933b,8ca82cc4,d21783a4,d74ae1b6,ca9896e6), +S(e65d9e24,e7340122,875a9d86,d6071a48,691ed5e5,a94b315c,76f169f7,f3d69c48,73575103,a70b7a59,90d9b880,8698b651,271c8c0c,ac93122a,66873bf1,fa3c6fab), +S(cceab216,41d0597,f9c7ab64,7f99154c,b22d4827,70395d6f,ddd6db5a,dc752825,4084c57d,5aafc328,e7a250d0,a7c3c0a9,627ddd70,c77c2be7,e5a1af34,359b9b86), +S(4222ee66,5baff421,17f47df5,c1c1df5a,dbafb790,d5c75bb7,2646cf85,7ae85923,43088d6c,a029903f,f5a789f8,16730345,5a5cd0af,cab57e15,12781396,fcc9b6da), +S(391c5d0b,17a8c11,3440cd30,83434841,969b0833,71758b30,27e38a25,e778da6a,69f3d295,be55f859,4bbb2fb4,116de5d0,b24b5a80,ed62c1e2,8fca9b8,3f6d7439), +S(803b7149,f87e86c0,13599898,b0c9050c,d4a6e030,e07e8d7c,a49c46a3,8a6ea6a1,6b367fcc,6d5916e,72f670a6,5ada9c39,54800e90,a8830fad,c9ea17c0,494cd9aa), +S(f7aa1c64,f8f92f20,1319f316,353d89bb,eaa4d65a,e148b01f,ab66aff6,c9deb179,e9b407d9,4c2b385a,74f22eba,93dc35e9,bebca7d5,17401b7b,576b7d2b,e13ff0c0), +S(f1c34d52,2b7493ec,cefd49da,99732e00,85ace2c9,fd14e9b0,69b67dcd,5acd5e23,29460fc7,dd77494e,a5a7764c,7ca6db5d,5d7a5e3f,65e865b9,e5f85d58,e77713e9), +S(db19a1f6,38ef7034,5340e3df,8d384944,7500640d,cdbc3be4,df3b191c,edb9db87,baac873,a76e0b91,c4847770,9dbe88e9,6195e9c4,ac4d7749,71ca204d,4a5e748b), +S(4ad12e00,f384c7f6,ea669c71,3649da6,55e0abec,67551a58,224b9f9d,de6bdaf9,2e0314a,8e3f32da,33a22ecf,ccac4965,1f1f6f5,20baeddf,39a02bd8,423cd40c), +S(c9130b88,cd451d4f,6eafffc8,357ba391,ae920c27,69e7c48b,49881070,fd088ad5,aac7c2f,4f2f8b90,bea9267,897e0079,7d6515e1,937fa4fb,1043111,6b5e1de), +S(88260ca,df81b391,be79bde7,b54f8a98,428aeacf,970cd843,d683e6e9,50686db9,3b9b187a,b998a22b,56b2933c,fcd09333,9c23889d,1180e365,10dc086,9869cf2c), +S(3984fce2,ab73c70f,a5538206,c2a61e60,2f160b1d,2eb61980,fe174cbe,fe464dac,b7e65c1a,46b50c72,621e3fc8,4f4c7cf3,6860567f,abf00743,5fd1b13f,7400326a), +S(e6b48495,c8277598,23b73f35,762c55fd,8cd20420,fe5be6ad,f27f12b0,68bdd63c,ccbb7124,3b0300fd,993dc9d3,4b55534a,12515243,e07ab78a,8d8fd528,46e5a69b), +S(6af5144f,342f492f,3f506ee7,fc515d3d,d3c93d02,27ba841d,74bc6548,97d4830e,b195d9e0,8113eeaf,fab92a2,81ddeaa0,95356053,a51cf84a,b5d60fec,5368f98), +S(14439b7f,e40ca407,374da12e,217edd9a,86c84397,e2fcf6fc,965023,ba984a1f,112ad656,47c47c30,f19ae62,e0c06b35,effd49bf,d5e604d,6d621471,9f088fee), +S(d4a7e4b3,863fece9,660baefc,ee57d09f,6f60cd25,f4aa178c,cb6f8a17,5fda9d4f,4985a973,ab0e8627,f6de7ef4,470de4c7,1adecaf9,f3766197,a86f4e40,14ea474c), +S(facc2a9b,9d3ad0e8,9fa479e0,ba777a0c,90a0c229,59d4b719,a9304df5,f1e96ff0,6e12c914,70c78733,3e5a65b9,8c01d342,827810aa,be3e4e33,cba0b7bf,eb283b91), +S(3d1b3f54,2809a7d7,79ca2416,a7b7d007,4a728599,e4f30cc9,14bbbba8,3daa091f,dccd0d01,e56c7e6b,90829ec1,f0fc733c,8f1cbcb8,79916982,3b466448,cc21674e), +S(a8c1ec56,3cf9596,d761e41a,bd6bc960,562eeaf5,b54eb83e,3d7e7259,f69671d5,a03c9fae,e160ba53,8aaf38cd,96ebe3a6,db59a04c,ce7074e7,dc3757f1,ccc244e9), +S(219b4f9c,ef6c6000,7659c79c,45b0533b,3cc9d916,ce29dbff,133b40ca,a2e96db8,db2639fa,26a61015,a5bbe7f,3fc8d591,c6b0753a,c16fa89a,d820fe57,72c49068)}, +{S(b445babc,55be50ee,bedb8c27,dfc6c37b,492649ef,8a65de02,111b9f74,29b8c3af,6f74c5b9,f9a022b1,8d3a706c,5c608b31,9f7ce25d,8424d893,4cbd2f90,84b78bcb), +S(dbed76fb,7e46e1d4,1b507edd,8994fefc,f94bd651,a9720d9f,8d62dc3e,9f329104,c047fc1a,41689ba6,9855f063,c563bfe8,49bd8b5d,37b3836b,d8bc57ca,fd02ef64), +S(844426e0,860ff2db,f012ed29,ad2919d6,f46eb102,68073862,c1792e99,f1b2b33c,243512c9,c6ca739f,fb181482,a901ecc6,a41893f1,371d6b12,31d5427b,fb486394), +S(1df697b5,9a2f9c91,b2c5d4a7,8035ea2a,351dc000,4e1c3bd5,5973020c,24836aa1,e89f949c,f6af652e,d7e79758,74a994ff,46475df5,4f7b17f2,a5c29cd9,7f722831), +S(cf4ffa86,87d9a39,7b4727ba,a033cd02,7d8a5377,46903db3,34c35f1d,855999a1,d1316b65,e027ed02,b4be11bc,4c21c1a8,585bb247,45cdfa67,5fb9cccc,faf0c546), +S(e3eed1d6,1813e3ec,d1b9fcfe,3e8bd700,bf3412ff,78a0a9b9,724d4dde,ddfd98b,dcb09803,b70d4c34,ee2bd7ae,6444724e,9ab27c20,5c3c736b,172af37f,cc673105), +S(3a202c1d,94a94eef,18fa396e,5cb8a867,8c3ae45a,e4ee64b0,822d207e,6c814fe7,147992e5,ab565bc2,ad1b1355,60f37dc6,b5cbee74,fef8e5ca,4e4f418f,811a0482), +S(6ce8f558,a853dacf,205db4a5,80c4cbab,8ef477a6,47bca6cc,9e676cb6,5f3f696a,e88e3934,b2857ec,6edb911f,acd132fa,f0078971,2805aa59,9afb3d80,942dc23c), +S(7fef9aa5,b2df37ac,99ca488a,ba598b4d,eb222149,55e1cb4d,c3ef1e7e,7bd38945,d4b7cb4a,8f9edfd2,3a0efd1,9882baf,98312b6f,7b5775ca,65e9dbf1,f2c32870), +S(6ec1ce91,d1eff7ed,9beba2b8,2f4a526f,736e717d,6442dd29,b55ae2e5,3371e0a2,28240ee,12e2b1ed,b40698e,ba6f087a,145eb772,caece880,b3e94b97,700dbd58), +S(645b9fba,2cb739ee,9b148b29,8fbe9884,f284893d,968c21d9,50696d2f,efbbf0bd,b06977a1,2d19836f,add50b7,b73399bc,698729fb,fd182026,d918a267,eab4b7c6), +S(7b930561,3a4a7cc5,ce1e7f5f,29314e1b,40bc8b93,40604f81,76578c18,69abf6c5,55a7e3e3,3f19805e,b5056d15,deaaa4f7,aea07a46,f9dc6a09,6ce15392,e146fb3c), +S(bbcc74ca,3697ef46,e7415ec6,b31a0808,1e6ade01,c7e2264c,f9d4d94d,d849ccaf,27bf64e,e1005f13,989639a0,8772c42c,b4249ba6,9d90cae,3f542ee1,78929f26), +S(4a45fd82,af96af67,9e640bbf,561cb385,2585a8e6,1b57df7a,e028ed33,a017c680,4ba76ea1,19a0267a,f019b3b9,89cde9ce,7b1c0b6e,da3c773d,ca31e44,61e048ed), +S(c3efb1ce,ddc6a749,a5db9daf,48032a6f,3f1a848b,aef9e44c,ebd76127,a9c90d0e,3de258cf,e593b489,8f92e8ac,50be894c,3636019b,a9f31f70,28468eac,687b8f89), +S(ec71a2a4,6f24acb2,8fda6bbd,ab9326e9,6590a96f,b9b9a4ef,405949a5,e3d2858d,31a91fa1,71207da3,1b0acc25,cace1e7c,5126ca2b,4c8d9733,4c50a7f5,29bc61d2), +S(65dc268e,cfd191fa,f07421f0,dcb16701,f979ad24,81ac5ddb,1f77d3ab,41a773e0,f8c9ac90,255d6460,15ddd1d3,57b92522,53bb55c7,e2f5d843,d7d9a025,2766d2c0), +S(62152eaf,df564900,4379891,4b53ddd7,3b91fb60,f16f2d18,941caa96,18d8ffd3,3a185ef0,a8d8a35d,112f678a,6a04a654,df565a8f,87e99abd,95fb4977,1b278ce1), +S(f68e6fcd,b2c49661,ae59bff1,f24e97e6,fffe7cfd,f185d0b8,133d58e3,bec1c89b,223dee27,5e9cc518,af12be21,ee7ef3a9,ab39c7d4,4f950fdd,9ce5c78e,b50514a2), +S(5d02e9c4,108860e8,2b1ae04a,4afbe1e2,9e0a8444,89876776,7e5b60d9,3fe5c753,25fdcc35,5f1970c1,43dae96c,a1ef0a7c,f95853e4,102548f3,d869d3d5,8bcf962d), +S(f6217e4d,4e6d06d1,27668a01,8225f88f,a1e0fcd8,e8654fd,ab26c8a5,4c6d4751,65a6acbc,19bb2835,13eea5d2,5fae521d,aeed63ca,50f9aed8,edb74dd9,c43d066b), +S(c18bb768,bae77077,35b4d3d0,e82cac24,fe3d7ee8,dcba20b6,a320ba6b,4695a406,b7a7ded3,a589153f,8ee504cf,fb5b45eb,b2d8e121,40f2f475,186153df,1fcf84d6), +S(36fc443c,1350b40b,881e41c4,d3c15952,31f8da9f,cdcac4be,f1d0c5da,ceb9844b,9843bb7b,fd0ebca1,762785cd,55669233,16c36aa2,d2c37b3f,2b196f78,bfa5830a), +S(ba7b8c09,d5293e6b,a2548e6f,ff3c939b,80d2ac54,34903039,dfb8b661,29e19cfc,54fe2a,9353fc1d,a0d34e07,b6d34d1f,f3a1f67d,f4aafa7e,57919142,95c2a5e3), +S(50a8ddf1,17a91c92,37a48fe8,f1a00e72,a5dff682,7398a4c5,d2f78b4d,d49ee339,f91d9b20,da28e51b,99fa102f,13f5e451,ab22e139,80052384,6b9c66bf,b7da1578), +S(642ece53,832d1859,c6543147,56b618f9,520a5888,2549277f,6b27f16,e08e3d1f,d9963beb,2c6da204,339a49c5,f253498c,48cc3e99,b715ea8f,a5eb00cb,1d6cffbb), +S(a68c0d3c,13d764d0,7b513390,5842c9,a7171e4f,755a9737,609db06e,1a44e5e0,a2c3fdd7,b7938a87,86f3756d,dbc66b29,72469e79,839a1448,b367db5a,2bc52c15), +S(5b33d730,288fde53,b123fdee,177758b1,ec113adf,74e79eac,513eadd4,cef377ac,1bbc10e,9d45cb00,db58fceb,bc4bcf4,a0e2bcd2,a7d3ec12,7d87beb7,a134a20b), +S(aa6dc4d3,ce531af3,e68590fc,acbe7816,c8293af0,d77914a3,c7119e23,e50ce56e,14386670,5dbe1ad6,91e09123,a19a199c,3ee67b25,708ef57,4620c5ca,821224f6), +S(180a4ece,d74ceaab,e0f7db3b,b038034e,5e659c61,3c66a534,8d962d14,efa32402,b675b2a8,b845281d,524403d0,db01417a,59fd3a6c,80232e74,cdfc87f1,3b76b0e1), +S(3a55690d,abb5e00d,c2d0d8a4,96d16c44,76ee767c,a9d0d1d3,694c856e,e5b7ad0d,3c1d71e6,8a5f9a84,4de0453,6810660c,fe353475,353cede7,2936786e,4d173828), +S(33b35baa,195e729d,c350f319,996950df,3bc15b8d,3d0389e7,77d2808b,f13f0351,5a75fe7a,9bf54078,6b9bfc9,db72ad43,559a9f10,4377648f,d43afc32,34728817)}, +{S(52f79560,fdfadd45,6165a204,6bf61bbb,726cd726,3a3ed2d2,45f07631,5b0b6ae8,e6c46e55,5b4a0410,bf38965e,5a7ba381,fd259482,2280482f,877a7ec5,84d14012), +S(29eeb07c,7b27f82a,1b031881,11d324a9,4df77713,a8cadb36,2ce4012f,52cafb19,b7538574,28faf258,f240d4a9,f464797c,dffd0a68,f9f978fc,476f9bf0,1a0a2df5), +S(2191ebbd,a95c29f8,e7062f21,a70cb368,ac67ed59,dc44b167,66e52120,cfe8e742,2812f1fe,557496f8,f21b1f11,2df7bd19,db6aad90,59494ad4,eaed4d77,49f66a4c), +S(3c29d849,e25364d7,576779ec,78755ff1,8aa64e2a,65140a2,bbcf22e3,da33a4f3,3658d9ff,e2e283c,f8973cc0,ede5af6b,69ac4970,3c6b1370,f6a2ba4a,78a28a97), +S(37230e16,e11db299,f54ca0f9,f5423ac6,5f05840a,e166175a,ff0732be,c72ba88d,2a26ac2c,e8f9ebdd,20f1f5f0,f628d3d,d0e02745,6132cbf8,78b614b4,51db28f2), +S(8fbb3be7,98e16bfd,b738a512,ceeea92c,1be8eeb8,5374702b,e927c614,ab1f1baa,8280f387,64a48061,26392be0,c95f0c58,3607343f,d0b24b98,afe3605b,8f7e79f4), +S(fb639ee6,29dd1f03,8e12330c,bf40ec7e,129d7da7,655c1c21,86452fe4,9589c89e,171adbae,2efe213c,8d01e273,ed9c5d47,c4e85503,de3849b4,d909823a,bb1da898), +S(2399064b,876b7584,8c977bf8,e35d6b32,2e45d1a0,c4243fe1,2a31a581,d1d5d826,79c1ef29,c1af9497,f3b3db13,17432d42,86fa014e,17e5d780,a0d39df,b61369c1), +S(dd5663da,63acee49,eb7fde29,6ac1215a,772512ee,6a080f3b,1266c7ef,51da5dd2,d19c7348,3754112e,9cb3a4ce,8986f748,3eba26ab,c415abdc,5effc956,27efb7dc), +S(30862c58,43b161ba,c127bea6,7b23d3cc,46b6c42f,8faaa281,6ae47092,8ae47993,44ea1101,26a7c448,dfed4995,46a0fc8a,3658e540,d7d0c2b4,18f8cba0,accf9537), +S(df7ebbdd,4e416e4d,6b1e67aa,34915da2,cc15bf8f,f6d79ebf,273b63a8,32d6610a,d05fddd7,e9618753,21f473b1,bfb5ff48,65b3c4f7,5cf4ae26,549989a9,e13056d8), +S(13adba8d,2485bda5,1ac7994b,c45a7e4a,1b21aa9e,8188e631,59b217a,29d4237c,6256a795,3f24b25a,c1f59384,aac3eabb,4458e504,af3b99c1,99ae614f,8def4ff4), +S(c160f7ac,9a453a1f,8811d031,9849be43,22d8bbe4,89cad7a9,cb815927,d4b54720,7958b41c,751ef3a1,fb985ea9,c7cc85f6,c16282a4,c374fed,5999d8d6,3227b720), +S(c66af931,82a7a9d6,588e9c7b,3eda3b49,40fdcb99,346aa55e,e6549d4f,f9382228,ffe4d0df,43f00af4,fe885b10,92ae38fb,97d21a8d,26aa5f69,9751d52c,a9ccea4b), +S(d3a4f4d7,d208b43e,c4c2fd00,798d882d,922f302d,a199b707,76a70f36,5ff404aa,8df220d9,63faa827,1c4ee360,67a536ab,25813239,82252483,311616d0,1458e1b), +S(47bdd428,d57ed451,cd8754ea,817c5f5f,9658274c,ef6757b8,70527b4e,96f372f9,fbcf0ee,9fb14de6,3c288dbd,b1888fcf,72f0265d,3fe2209e,12c85841,2c375b53), +S(6e6deb95,7f2eea30,5d625288,3cb311c7,f0365a42,480fb807,36315c4c,62495438,ba0fdd63,9b8678f2,ab0fe3e9,a16512e,ffd9ec23,e691cd4f,86146969,534978aa), +S(dcd2775,7cd691e8,28e21987,d6eb6b54,e8def24d,27238cd5,dfb36a3d,d0f05caf,40bf37e7,bd776a62,ab420209,c71df7df,74d185c,f0d6b038,dea9c8e0,c1dad163), +S(eda569f9,9bccdc21,580da94f,92d89312,cef87d13,f08d8ad5,f1574e12,30a64ce6,4e1da1ac,dd274e3,f9d7def7,746f0652,678e549,ad5476d1,410adbbf,aa3c1e42), +S(5d3d4a29,734fb7ad,2846ae12,4c803364,ea3d57bf,e8d77d9e,6a3b3f8c,9cff26b6,d3e598a7,1a469323,a357df08,319dcd1a,d7337a32,c9894b80,6a30c575,b19756b0), +S(10161fa4,61e87595,f269da7a,ae3ccf01,40e910fa,891276c2,df1bd91a,95e4d046,b36eb5f4,b8291a01,18691f1e,50235d8b,f66e14a7,f0641dd6,18ad7ddd,ea150196), +S(7ba1b276,3df207f3,cfd1d58d,5190eb91,99cf82f4,9d2d0927,f5f260f7,2ea0f178,cb9fcac,4be96ef5,3134f513,5509c178,99af24c6,4eabd650,afc599d8,3927969d), +S(4bd6edd3,aaa1802a,b0f46e05,418ada37,e75728e8,6ea4b293,6619c92f,57674dc3,c9e962d3,de71eafc,7fc9a329,3bfd721f,305e876e,a2a4755a,f9567dca,21aa3c0b), +S(95fa0b32,40b24ba,29a484d7,f8f022eb,b3f30349,9d8abc1,9a69b690,3e885b68,dfe6b88e,56d7b923,dcf8bac6,2241d663,3ac2ae55,c3a01fcb,9f966d62,8f3acadd), +S(d0fd4d10,18c37114,2d5f8a86,617c250e,b6c3d5,210ca465,6ec84e87,d0ae42b3,4e3bf443,290404a9,3af38e72,a54fa06c,3b2d6a81,161fc8de,554edd9b,f3399587), +S(992e1183,d4e7afde,166c45e1,37c71c88,d4039709,4262163,b4ae38e,538293f1,c29534fb,55e47a08,ecee311c,8f0ba4c0,39096edf,b2d7ed63,21a2810,32e85900), +S(9c124ecd,4e6ce167,f60dcf38,25976f33,64cc30ff,61f7dde,966f8c23,4c13a4d9,7ad73bdb,e0afe3c2,c89d9135,d445ba4c,796066eb,1909349,9e6ec14a,f74f664c), +S(b09cdc9b,d102f89f,bcca0ed5,888519b,7c5c02b1,64ccbfa0,3d0fe42,b1b113e4,f409865f,6ab4371d,f52790eb,88df67d,84b3b74,f17edbc1,29b802cb,d5e49a59), +S(6b4f628e,beb6d619,1d616e87,3233ae37,ca4cc3f2,ac881e59,9c2c8e3d,295ccdc0,1140b988,60f4ac7b,659eb012,6fdfb796,c0baa652,2202cce0,bf54b3a4,865f171b), +S(a728c830,10169439,3af3f780,b1ceae3a,6ca08ea,4bdc7554,2ae84564,f542c28b,7b68fde9,8c97db32,eb3cdbd7,15816e51,9aa58458,259dc74f,5d722dc,f48f1933), +S(21ce4401,4ce959de,f16b3912,e88ff48b,d44ef79f,5fed2d35,bdd2dc78,de8f7605,cdc598fd,c5d30508,a2690299,e0e25b91,b1ccb69,97b99fd3,eca1baed,76aae6d0), +S(89912259,11b9132d,28f5c6bc,763ceab7,d18c3706,e8bd1d7,ed44db75,60788c1e,2574b267,83365364,d84789ca,a64ec905,c969637b,21061ee,9ca3bddc,7170ed3e)}, +{S(5914f66e,28c1a0a3,47f461d8,1d7f2c55,845e35eb,3dc39945,584b5efa,8d71a215,cd2ac885,3f681e4d,884e308e,ed3ca185,b47e2d63,3fdfff6e,efb6dc67,4d7de056), +S(519834c0,d16c807a,7867b8fe,c99dc93c,3b9ed218,87a9ca17,9343729d,3ba9e294,b867d57e,fe2dd7c7,8586303,152f02fd,f67b5648,78a7727a,190d304e,64f97203), +S(959eda70,cbabcb05,fa8fae96,7227b6be,876db942,ae38bfea,a9c3d359,977e1c52,86373396,9338053b,b00d206c,5d67abd,f95d35e6,992ad69d,8d8a3322,7370fdc), +S(a40279c8,48dc042b,a3ee929c,2910e326,eded6051,9d9eb1a4,98fdd7e1,fc88a6bd,f2c962a9,f2950d2c,acbfcf29,35bad39e,2709c0e7,36378968,fa04d957,1dadc4ee), +S(650b8181,edcfe46c,eea03ec9,f8ee5af2,c288e618,7d634961,6c95554e,25957334,ce140ddc,c2e2b07,a57e5627,62da3eb5,ca1acba5,463e97,fff7eae3,55b954c0), +S(eb04688d,5f4c8d2e,4ccd509a,3d003b30,8c5539b2,dd160a45,cbe71efe,36fd9005,37d80690,2062bde0,b96fc8ba,7a7f751f,9461f774,a1d6f3e8,8999c676,a2ae76b), +S(f79206b6,7813cd64,9f946313,3bac4aca,3762975e,954e0ef5,a876b78e,4b5a5d24,6033d4ee,936e956a,af117dca,6086eb1f,6466ab18,d503503d,4b011315,365242d8), +S(539c99d7,728cf662,13e024c0,9f1226f5,ca5d09cf,67bac12d,47814b2b,b1e7d611,87efd14e,e58fbff,5491bf85,aafd48ae,6680f37,e0d928f0,13fb6cec,6f417f76), +S(2308281d,e761f602,66fb8228,45eec88b,e32f8fdd,4a06b8b9,3dfad9c3,75d64a8e,933f4071,e4f2a9ae,95f4a299,f4267098,94b661de,c96443c5,f03f6cb,f3be87ed), +S(a93d05ae,fa31c0c1,54c02f68,9184c1ff,344c670b,e13eb304,2de517f2,1f6124ed,b7549c5,4651fa60,61f4103e,27d316a5,db531e3e,d7396a46,e360341e,f53ed274), +S(35717dcb,4feada90,b039aa79,10cf064a,c8c998b5,fcbb037c,22bf9e92,eba560d8,b6ff9371,d98bf532,f82d7fdb,24fffa69,2afeb0e6,59ba30da,602b3399,2bbe5a5), +S(941d37ef,1671d5f5,675be9d0,d5cb1f0a,ab6dffdd,2bd342c5,c5b62be9,88d5a0aa,4834d5ee,a8f9ae8e,ba5cc8b,2fb52260,33e35767,d55b6aa6,d204e0e1,a38b42ed), +S(c22cecb,aff78c61,f6e34c9d,9367c4f4,1acc9c35,29e9d894,7989a874,1d70bccf,38a37fb0,5fd9036e,762e2f0c,fef8fcbd,c04a92a5,4cb72ee2,ba08213c,4b58f1e1), +S(7863ac2f,1704fd,5015f0ed,30edf5d4,33c5ea2c,e150833b,a15c1db8,a5e4d2f4,7468fa15,eeab5653,c9f982b4,ad9e4c99,2f44083f,a7a93e9a,25ff70e5,b8742b4d), +S(f702cfa6,f0cfd275,a2c7af50,b53d0c94,bb965063,c433f4f2,cfd13d99,800da48d,3da4a4e1,bc5f2c6d,2f8daec4,599a9704,7c1b930a,b37d6b2c,f8a586cd,ef7dce1), +S(c3a1da3c,6e6b8f2c,2a8eb81a,1875f2b9,1e9cd286,414862d6,57626b47,a413d7dd,983d0892,5983d42e,bdbce2d8,df116bc2,f5cf8c87,aeb833da,e5e7e9ca,f9699798), +S(df0a4106,d61fc3c6,b2a14ecf,ebea3dcf,7e38069b,8faac576,a0b8a1b,7c8e7b5e,dd97a06b,840d64db,1798cee4,9334b033,e8d3f4a,79da565d,c6130da,f0bea75b), +S(ee9901fd,9312a21c,879d4e1b,24d5a299,b8200a15,6e65e147,4a2055c8,a2363423,1bb2933c,8b10f8e8,ab93ecee,16f861ff,a86781ea,59b891b7,740fdc2d,f6c206d), +S(52890b99,c8dc48c4,b6b1e4ae,5b823fca,ad9495b9,8217fa4a,b4f8e960,77cdaf9,6ca2ba73,72606e82,9c3395fb,dd2e4b74,8c771231,e86fade,5e2d728f,e5e7391e), +S(a372b545,bf56b58,b7c4628d,aca9bc14,e8bc634d,d79d139d,8eb7a2d4,13465c3e,afde23df,fad41c68,df94abdf,90a642b,31d62f84,c6254c4b,4cad2934,376372f2), +S(89d02f41,f88b1f7c,90b01078,d7599a70,a1eb9c23,1059e856,4237b0a3,2c18010a,7e8e810b,b063d75b,c224f41,a842972d,6fe065c2,aa6b16e5,7bf224fe,e44b2275), +S(7ef367d7,23fedacf,86425861,f67c5ba2,2deaf04,69e31988,7a3a3a12,2f39576a,4b81e743,e00bfbc,1d98cbc2,5c98c516,55e574,fc7fa1f5,86f15d9b,1b5b7ac1), +S(2eec37a1,5fdd1caf,b4c0855f,e86c5534,1a78cdc,b3944798,311b1cf4,7df768ac,1c18cf5c,1a98fe9,70d1e635,ab133668,4e0d964b,4df0b16d,7c51ea01,c9a63), +S(72208b8c,fd9840d,76dfa6e0,f36cf57e,502f285b,422f0ba1,9b119500,6b2ddd11,fa09196e,a89ce6a,888415ec,a8eb92f4,149bb39a,50174a85,8a29bf63,65b4e577), +S(9f46479a,69411d57,c3c7ea6a,dfa833f9,1fb2109a,fd30c790,2ce323ae,4b14be0c,6cd6d7e0,8494cb95,9e67c258,1be426f6,4eee4514,83e9a9a1,278b073d,758487c3), +S(a9aaf56b,5016db58,5b8116dd,cbad1169,4b16de8d,9db5ea5a,279ccf4d,91b1d7a,218fed41,389a4abc,44fb2a83,7016eb50,99c40e86,bb419265,7f57714e,194a5900), +S(5f950f20,b610c06b,76949dab,52fc6149,97d254be,a1330a0,493f1ea2,1d608864,d9098481,823b3ff9,d1c0b7d0,bce90856,186b45ec,6f20da26,9b158283,8a4c96df), +S(ed621f77,98add722,b0dc5e52,9c6fec6b,dff60827,b0b12c85,18d798dc,761f1075,a8973e79,a9caf1fc,e3165145,df08b7db,6b7187a5,28b12712,6c62bb5d,4f0c46d7), +S(15b8390d,652d7338,e18ee091,97e0e176,74f8c4ba,fa2e7b85,8f5badc9,9c89240f,87930df3,710172f7,c5422833,385a6066,4cfc9854,a3e5ccca,d1d06106,1cd90be5), +S(ac2acb9b,21999a70,540708ab,68338266,aef650ee,d81c5b30,da1e87d8,a8a923b7,897bbd7a,ee3e8db2,e36505f2,ec2614c,9f4f2f40,ed2d85b0,5d23edb4,2832db89), +S(17c072d5,6bdd1382,a782481b,8aa4d223,2db79438,5870bcad,c3063330,a5cd5379,26fe420b,d7c25f9b,1883edb8,50e2fcb0,76a65389,d9a452f2,8351fad,4ef72f0a), +S(8d262002,50cebdae,120ef31b,4c80cd5,d4cddc8,eadbcf29,fc696d32,c0ade462,1412c44b,8ea40bc8,2ce090d2,3c11c945,e2b504b1,8d9874c5,271f5745,f0d9b523)}, +{S(ad9144f1,bdcc3673,26d51685,a047ea9c,3c4feb3c,da4b9b83,80e1ada6,300ba487,68003744,ab5b2c8a,cca5bcfd,e1c4262e,88ffbc0f,b0ad4206,2d57dcf8,62c93c47), +S(f3b90a0d,7a8cbf1d,9b994b19,7ce215f9,b8ed861d,d526228,59fe1811,68727bab,95f48e8b,c05a7bf1,e47fdc86,87513ae,5a56472a,44f384f6,1153a954,2db68b81), +S(24af6d7a,99122466,45b07a1d,29b4bb1,a68b5b0e,f9422065,b5bb0050,61d43cdb,f9dc7725,f628cc4e,d4e5554e,f0166b22,566d59e0,4d55c28,a4d0e975,8306c31a), +S(f704aa4c,2bf19c9b,128311c7,1bab5f8a,f2a3865b,728f4838,b8ccc7d7,82574cdf,ae7c46ce,c44d54a7,2e3f758a,e855710,dee6b189,1223d120,9e059620,38d12453), +S(f701adf5,a1bd988d,d7e1fadd,9903c453,e6798760,252579c8,b90cdce2,a046d9a7,db39a987,48aa20d0,5d8b8538,fc4b7d77,95e2810b,160198c7,ad98305,96407c31), +S(bfe36081,c492ed7e,3b91059d,bb1af376,47dca509,69be6665,50f94903,d948ca7c,a1fc9468,2c3dc954,764ee858,822b8c1a,5d0184e0,93f12bbe,21e9931,18911f03), +S(e707057a,297a3d7d,904a615d,ac1b8e81,78f52481,32fa166e,afb621e3,af3f4f34,9161a930,bfd583c0,bfd3b121,acf574a3,6eb534ab,5198aa84,ef38253d,9ca19bc1), +S(27a6c7a7,970a9e3a,7cd42b6b,4478be62,31f53ff8,481791c,4394e78a,968fdddb,e4bf1b16,6bd56269,9e2c341b,b1a51c8a,c2ac7d28,807899e1,3ab1f726,90f44108), +S(e65f799a,8fb3b6c,ad088351,614db5c3,d64660ef,8c977ec1,2bbe58fa,a53314d6,5897f680,253a948e,fc260fa2,8ac39377,4e6a445d,d2bde00e,4e01ff03,b4398e2), +S(8406a84c,e9e63204,761dd406,9651f20d,6fc3efe3,f98951d0,d0a2db9b,cf86e0a4,ef81aeb3,eac17e5,676f4455,b4372ccc,e405b786,f11a871b,d781e54c,6307d1f2), +S(c012cad9,4742fd49,8daaedfe,5b847f34,7a45c792,53c8a645,2192e905,e256c7a1,c4866f98,48f31660,8a81da9f,da112a71,34232f9c,75e388,7ff987b6,8404cd42), +S(73795313,e9de1efe,3d91ae5,15c620c4,4f9c6bb3,a21e3097,c8794710,b2032683,548ce754,93817f22,cb96c674,5d67708d,c7b9b133,c71cba5f,fede1316,c55245f7), +S(352b89f4,78a47e86,b5575fbe,ee1373bc,e93ca316,1f594564,9efaf048,a60bfebe,d784e6cd,88d7862a,d82747d9,b23340cd,b50235c7,65f30be2,ab5d313b,edb0624d), +S(8a0b3d0a,80d41abc,4b8a028c,6c523923,7b040445,525dc345,d2d8a319,c4708316,7b7a427a,f0e1f902,dd1b9bb4,65b6b376,ee68b9a3,f495cffa,c52fcb9c,705443e9), +S(b4bf6756,61462829,53f9a44a,ee3b5427,2485b45,951013a2,8d59346d,62f65894,85d0c26d,2987dbd9,e26c9673,71ca86af,3b8cfb4f,cbf97404,c99ef900,5379a1c6), +S(bff69744,3ac23a6e,574bd1ac,d0fea305,2f05ea65,14814f1c,65e86e9d,5b46a2a5,36961462,5b998565,9324f5f,c8714d9d,57ff314b,5d5c2cc6,99a4ab39,69add4f4), +S(ecb09f5d,122adf91,e68e98ea,d39e5790,27e7c4ca,405bcaf2,e086d4a3,e68242ed,aa214cca,8a601fa0,a92633cd,a353ca02,7a7dee71,cf335af8,fc75de56,a3405f60), +S(310d957f,10fb34ef,ca3a2a0b,35c901f5,35c0862c,68310134,10982d7d,e74af8ae,289cda3f,29a489a8,86121f4b,4e75a90d,2bc4ff20,e95aa103,4044ea80,cff56378), +S(3a5f1ad7,c59ee6cf,e090f210,7040b419,4ca15fa7,dc8e9f69,20825fc4,e012ac2e,8ac8986b,48d7bd1f,5ae99535,2505b0ad,78f855e,d8411b03,15725571,dc99c920), +S(725f136d,1b426894,c24f8782,43fdc1d3,79636a23,d682f389,dbaf71de,d4672067,db0ffaac,ec5ffadd,f32396be,3f01fe2f,45bb0cbe,eb0d98bc,2390f3ca,c3dfec84), +S(b28e523e,6fc68192,445180d9,5da3e411,2fe0db1a,5b3bd5e8,e00a1090,39c69d53,7c172a4b,31339fb3,47db74a6,beedf59d,c24e6aea,c71e2a0c,434714b4,d61a2f70), +S(b808db0c,e34b5607,8166b308,1dd4b2ca,cf9d2d51,3079648f,fc3c617b,8e45ba09,d69c4ab2,fc7e490f,6887f2c2,49e0b71a,746e3e2b,97a7415f,34475bd6,f6dee79), +S(5e0b091f,3144d7bd,c7e40dbc,98c716cf,d7e64eda,ee9c1fa4,6838bcd9,e0c6878f,1586cf7c,da66b005,8b2d0d49,f588d444,65eecf42,1d94c004,a078dbd,47e0bd20), +S(1c3e88b3,ba46410d,8e08f9fd,5db8b53f,8dff33c6,4f5314f5,e005442d,10cef1f8,ba365020,5f85aa9f,71a42c0,392345b7,4a17a5ab,9ff91109,4d81252c,d8c8f72f), +S(b4926018,fb0e9c,e80c5614,37c3f22c,cc223412,384321e3,6f408e4c,ec0d81ac,55544f6e,cea3575d,e81649b8,4950f225,8a94e78f,13325ffb,16debe1a,8387173d), +S(f4bfac1c,b0834e1a,e332b7b7,1ab84500,b1c8460d,c8c2efad,6a5efbb8,ae78cd1d,5faab691,59ce9d3f,6bdb1818,676684b1,cc2309af,1401b5d5,137e1c61,5fbe287), +S(220ed3d1,fe028d87,b96e8ad9,37ede03e,ed8f262,ce877c0a,42718ab9,cb2ddfb6,5ee2d60d,f96a1b8b,e11c9139,7abf9b4f,a0671966,34bf37a2,8d26864,31933fb6), +S(dca5fad2,d045526,b6a4c309,de1d95b5,23f9a7db,e669b558,edd75ca9,40c85878,f350337e,877c9c61,98fc912b,5d53876c,78ea94cb,bbf3744b,62a52fa5,f5ae4399), +S(486ba509,3272eb1d,16ece443,861eae7b,2d8604f3,37014bc5,11267485,9872642,688d4585,9fa732c4,f582d65c,45930567,8c27dc6e,5525d47c,3908daff,f0a534fe), +S(96bc1bd3,b4840354,14aa92eb,6db81f5,403e2858,c0552d5a,6b21d33e,c468f31a,83027873,f4066b5e,ba6f413d,6a7d4d18,d57f4a62,25cc9289,b514f153,91ede3b9), +S(9f131ffa,b53e20b4,e9cd9e33,793f4614,922c03df,7d11222c,7fffec33,42fddec6,c4deffeb,3f4cd90b,102cb6b,3f713728,2c5cdcab,bc6e7153,91ea890d,76207bdd), +S(c15c8c23,d90c8e35,c1a214dd,e2d4383c,735ae45,bef61f10,aa1a1c25,5984cf74,d456ab27,d7adddca,372390ba,1da02845,b84088d2,af4fea5d,3b5b7326,c6334c2f)}, +{S(e24b71ae,8fdea24b,2d42a2c6,5cb022a8,2aa9e03a,3067a889,e778caf8,34903fa,f87d5757,cae83263,1233b840,296d6066,52cd1ddc,e8334629,25c992db,7e0ee14a), +S(886a7626,6203c559,807acbf6,7e1631ae,1f6bcacf,3fde277b,ddcd795b,292c38f6,b1f590a1,52d3ecc3,2b699c23,a89b2601,de78be2d,fa11b20a,1ef1235d,93ed9e99), +S(3079f709,3d5270f2,95fee75e,a6c5cd3a,5638ee37,aef535b6,523604d2,eed0d57e,492dd2cf,d76705d7,42187f38,f38982d1,85efa30a,fd1639cb,984a8772,3e912a91), +S(7773469e,c557e3e9,4097bd55,33a87583,a79e3eb4,2e421cd6,592363c2,76641966,f827b0dd,46f4b5fb,4a656731,d827cf21,df1ec610,f36dc2d1,215f33fa,20a08020), +S(ebeec367,eb032a6f,7c421ae6,f8fb56f9,3fcdaa68,f6741e46,1992d019,7567336d,6e78af43,e10c742c,35467149,3323f8c4,a6cff91e,7b1f1c2c,65b21fa1,e63f3a6f), +S(b41658a,3683b512,c751d817,f5d92f8e,5d158632,1f2eb836,b446aebf,d276030,9396ba60,ca61b35e,4e52e879,a457ce5b,fee9121a,b2673c19,15e78236,483e069a), +S(2e2ed965,a926700a,1428af7b,68b7dbf7,61d1bf53,6eb9f75e,d56afa0b,63852cd6,8d77656e,d5f11224,3a94e462,3dcfbbdc,61749930,dfcca6cd,c4303cc4,617e9133), +S(4b54bd22,e5604384,9ff2268e,88c695d6,4766e0c8,4f598f5b,634e1dac,d03063ba,176c68e4,a1f25683,37c14fee,dcf9a64b,17cba4f7,283428c,1514990c,98d29d71), +S(b6cf7c38,2d4c63cf,78557116,55b5de99,1fd32da6,8b8d2dd4,cfcd6f5c,59c45251,c4c190ac,2870142f,2a13d7bd,5d6768b8,fb5ccdfa,b99d0e3f,6bda805f,7741ff52), +S(857b6db4,79177eca,82a6c801,bd763647,c1a49021,e5b4f405,ad02e6ec,7ccc3629,586cde8e,cbf7907f,704a6610,f7a8a910,16599e9a,93bc6a6b,1b70d59e,39c0db4b), +S(a18a23b7,6643d92a,9e1bd2c7,7bfee61d,c5171b33,12f64d7f,821fbe05,6a771ee2,321f460b,b9525303,c159fe3a,6762dd97,60432307,919a2f1d,6120c946,47cd8568), +S(19b91028,cc2e5434,b162cee8,c77351d9,d38d9eb6,8ff9b09b,f26cb25f,4b88510e,cbcf2e52,3335ee5c,56ee2a06,7c565627,a5c60f16,808ea8e9,94250c15,e427c883), +S(657e2f30,b1e0241,82c0e57d,996cccf4,7bdf8eec,5a4da875,1638b3f4,9bcdbd2e,8e0a3117,12da36b2,2d0cd048,a9a99b26,5faadec2,14162083,5210f1bc,bb79fe3), +S(576879e4,f4a8e697,45014bee,36ba4267,cf72038a,f5997d38,cf512f08,f0ccf6b0,3f313f,388c011c,18ba0938,51b0e7e,84627277,2e9da999,b839b58,92ede5c0), +S(ed72d681,6516c2f2,7a9e97c7,1a7c99f2,faeb8e31,a5f29260,faa0bbf8,6475117f,331fb25b,e71c24fe,f4d2133b,f1591f3f,e5f8830b,15615134,36fc47fc,522ad4b), +S(e4ed422d,9152f00b,96bce64b,bc3ddaee,6089e1a4,1ffbb58a,109c688e,ba44699f,6dae6420,2dc6cec2,e4a49203,6b16c9f5,9c517436,bf3b9d9b,7e8f458f,7fcba8e9), +S(fc3b8afc,fe39404c,29622db5,b06c989a,8d7a0c4d,85018796,d006bd5e,43dec087,7b77feef,2211c1a5,724af5e9,a841e09c,d7940bc5,43d70c7e,51676689,7682ef15), +S(9c2421ee,e2e7e66b,decbd152,a8839f1e,4cf03808,649399bd,ba55cfbd,9dda6360,8d9477c1,c66a532b,967895ae,66c7585e,608e9653,4f870bd2,c97d7398,74a84700), +S(22040517,334bb5cd,2252d1b9,8a9da91f,a0bd32b5,562c8218,4d991e01,d94e8f13,167d3dd5,738a467e,f8e03064,d6482c2d,64503892,b4f5b9d3,c4b04684,fe2f15c0), +S(b648a617,3c728243,f3c0c7ec,2aadcb13,dfab92fd,77da9aca,1602d47a,80022dd4,7199a3cf,89c596e0,d607d05e,de95c8db,ad763ac0,76fa7ee8,ba7ae6e1,4c14308a), +S(a7d7ab3,6722b9d7,940b2a15,c94bb9fb,41a139d4,26215286,bfff84ec,57386dae,25ea853a,c3e772b6,f400d850,a7cf5760,ed568add,a145ea75,6f20b77a,c32d9f28), +S(9787a21d,ea3dab74,366214b4,933a702c,7a07c4ab,696eddb7,3a84cb5f,80f2ba41,8663b959,2214a018,e373e360,a9e035be,f68d9e01,f6fff1ab,f8ad9b8d,3f6f324), +S(1d2ebbd0,65bd4f50,8dd697db,9c8bafff,b548edef,856fa4e,39f893cd,349ff205,85d0716b,109ab208,a96367e3,bd0a2314,ad2c8586,169096ef,9521d780,61df01a4), +S(d0a506ce,14e88414,46c08a61,98ea0aaf,75b9dfc2,c4d2cc58,1238a597,154981b4,dc8c863c,7c4611a1,85744975,34c8c02d,7cb7504b,dffa91f5,96765a25,98d1f506), +S(b6c4d103,a57d0af,27e93627,f55a34b7,75b2ef48,47d7612a,5fac0748,b41afee9,dc9440a1,596cbfd9,ff87fade,8b426091,4799dad1,ce0f7b60,d032e94b,bbaf53f9), +S(5b5d965c,f2f37462,86f088e8,b58887ab,2182f874,484686dd,43a245e3,dcbc55c7,6718ba28,cf43ba30,eeba6e49,a7234ec8,7f01762,e915ff12,41fb461b,6d87a875), +S(bc85aec9,55e6e99a,c5fa7738,c7972354,57b3935b,bb69e8e1,ddc69d01,d34a47f5,59dd49e8,cb3100a0,9c48ceaa,20cbde82,5072e13a,7af0a44e,601044a,361dd971), +S(66b7ffeb,a34d8cbc,e00b4d1b,a0558741,5123d8b2,89ebdba0,47587d66,b260bc99,43bafb96,c88a5917,c6333dd9,b4a546b5,1c37ab48,3f3873a3,6932ab97,efd79712), +S(3cf9208a,b230b73d,68470411,bf3d4899,e0f19675,f829e32f,cd148d,3c07d7c8,21fc39b3,ea5079a2,ae131935,9a3e98df,62b97b37,2a473a63,f3b56e24,25b30e27), +S(66e3fcef,b7b24cf7,af0f8de2,8e53c2df,2bd1dfb2,c0289b10,31239da0,948e129e,df4074b0,488f3f09,a674a40c,b3207f34,a0282661,2e5ac4ae,8d443c9e,d1184045), +S(28df781d,4ec05680,590f4658,713c8a91,fef23763,87ddb6dd,674a35c8,b0e74459,eb66159,95ecf0e8,34f24e87,6f0dd86b,5c86a45a,fe5190f5,721f833e,10a196c0), +S(85d8da47,48ad1a73,dec8409b,e84f1a13,16e65c51,96aad27e,766746f,3d477c2d,a76b74ac,99a3996f,a794ac9a,ce103843,6b4f5fdf,cc3b2a59,df867e8f,382e1ebf)}, +{S(39ca1e6b,9fd848fb,ac24c444,5a9f398b,8639fa6f,c0c2f2b0,8058d84e,6c0caf1a,8797227c,f956ba7e,5228a452,91cdd51f,8958ab7f,43f6c8b5,e06176b0,dc9048e4), +S(4c87e538,c9eac9ba,d5a2a81e,43a6f1e5,f8403c01,68ad5020,4adef77d,5e3aecde,6ee8b74d,dd0b9bb7,c8b7ed7a,728dd99d,a9fab941,f0132d0e,998e65b9,ffbcb9a), +S(1226617,9f5dabe4,6d963b7,e96247e1,e29f2440,f831c8be,578d628a,78561987,2d3552bf,ddb5ec6e,a7758830,9badce7b,41d71926,857962d3,c3bb28cd,5d68ce7f), +S(866c0a90,893b6b3d,807a96fe,3c67b928,67c1d95,e05146fb,40038476,26981201,8d8f3188,da86e510,b7a7642a,97778201,3926dae6,4ce80663,335bc448,d204413d), +S(8eeb2e94,9a66824,26a6f474,9e7578d3,1b356aa8,d1b42049,5fb83e5f,5d08f723,e439d710,c45063c6,d23aad9e,ac0cae8e,36552ab,ca6f2c02,6eeb03ff,6162a052), +S(ffc93fcd,85fd9502,78369b3d,291f1ffd,5da44964,888d5eba,3c3f60c,95082bfa,9aa66635,a4b0defc,b2514e97,515aa0ec,3f65ce8,6f6962f7,72eaca41,d5ea7983), +S(605ccd66,4f18c83d,edf36f62,e5089f14,4ed23f4,f88635fa,ab161567,fd20c8d5,cfccf020,363a805c,1d614aa5,b9a912ec,99cfea61,5c088789,275ef531,dddf2418), +S(d1e4f37e,7d3902aa,dfdd7254,fc727a44,98eb9303,a12fe71b,4d193be4,8dba6913,bdd29d53,4881cbc6,c2e301fb,7d757bc9,9224f12f,4296e834,9badb88f,84fcc289), +S(f30b6d53,f330e6b6,b23d21df,7b4350a0,c42ad202,4a92751a,5dfed94c,47bbe60f,b5ca6c03,b31d06cb,183b0b18,4432a06d,8143d511,8af4bc01,c364f024,b46e0c38), +S(540944cd,42101851,c2cdb0ad,61264e18,cbf948cf,2090df68,54482628,74271ecf,cd16820b,4ccf9131,476b8778,ba3e83,f5970507,7110686c,653be572,2e99db3f), +S(846e5478,5d9cad5b,5109c7e4,6fd62b04,f686c723,1fc3c0af,66bea20a,d9d60dd0,4b1a28c1,78bd097f,aeee951f,fd4f46a9,4658a76c,268ee7b7,9aea4bcd,e75fc8ff), +S(16e732f4,43b4c616,24a495d5,4497a23c,c95612d0,58df9f81,11d1340c,4b2b8b5f,61ee476f,30ac2be7,e3ff09f3,ebf0b3e,2d76177a,30573465,101f4cc4,ec0585be), +S(4f30ef37,2c730ba,a6a40ff1,94b6b58f,436111d6,848b4e60,10be9b9f,abef17b7,b579a133,7f3247f2,8c6afc05,644778f2,3668e73a,a7c6d14b,649bf948,ef126142), +S(595a0d2f,1668c0b4,9ba0994f,3b681c42,6e3a67be,e957bf52,47acd9c4,7cb7d009,fb10684b,3ef1b0ee,37684ba7,53858b3,3586b837,aba6d82a,958eb947,2eca319e), +S(85dfb59e,d7ef6e0e,355e0ce1,304fe5dc,8bc6a3ad,74de3352,2089f224,8894e0c4,7a9b9ad1,10099903,d0d84a33,6838d422,5f98abde,32d82ab1,a383969c,1fb98bb2), +S(c8e13980,cf58416d,8719bc94,96e21774,c29f2e1c,5a36e760,2ce7783e,2c810fd5,5bdcded7,bb484d46,48bc40e3,ee6a3761,cf995e36,2af21f0,10048a91,6fbd4717), +S(80b98fb8,e48f44e,db69fd8b,18eec95,2404fb59,45c8a35c,bf3616e8,c746aecd,d44010a7,20622d14,6af5319e,155fe4ff,591bb829,f5086c7b,1fc1ed6a,32ccbaa5), +S(17629b1,cf015e58,eccdc7a,de049215,fca806e7,805e0e35,951df2ed,5cb87d38,afd56698,44f6aefb,528dcea4,29438e0c,d10c4b21,23f02444,a950834,97a61f17), +S(592677f8,695479dc,b215af2d,bbc90621,e7f3cba8,650563fe,1b2a8765,6c44107b,3741e4e1,b39b0e2a,58373166,854a1d31,ed062a25,c4e3e1fe,bc82e941,eeaaf50d), +S(98d5f85a,a93c9d87,e34e3bb3,597d9380,f0a7e5c5,b03ec219,4025c89e,42126453,dbe42a83,66753aec,61f7f01d,e5dfde1e,b4b989cf,95bd36bc,a66ddc0e,ffeea196), +S(9187b546,70d2b9a6,b711c88d,353bee60,72a1f5d9,ce75288d,4e6c9111,80dd4126,80e73529,d211ea24,d4bccff2,b9de3e31,c6307ee2,3cd9267e,b2d372ef,78f8d2c0), +S(e38c81ad,8ddfd8ca,4e01f380,78eafecb,f8edba6,8e33e565,309a3ad9,f0abe0eb,9f0ace1,f05f0a85,a1488644,88cce81a,2cf55eb3,a91fc10a,e6b82f47,60dbe618), +S(7ee9955f,99e218e7,dadfed94,dad7054e,3e0b97ba,932338db,69ed056b,6f8adf55,5244e198,524a105e,2b5de11,81d7bfe9,ad56aa0,128a3d87,8cbcc5c0,25b41ca), +S(eb9e5ae8,cdf64b28,76349aab,c3f75c9c,9d95a335,3214d0cd,d43123c,265b08d,858611ee,f67a32b9,7b8a9090,6639e998,a05d9bbf,8ccb7c1b,9e5eb711,4216b877), +S(2aa74ebd,7e8b6b2d,952effaf,e5545eb9,e99b9678,a2515698,975247ac,c83ff081,1ec12cbe,6877aafc,f353f641,1a5edf9f,e4bcc09f,31422df,d076932d,8f0defbf), +S(1b7b8fee,a3ed4af1,cf9b07fe,b435ef76,1d081b1d,f1007697,f78fe5d9,89076aec,b4aa0d8a,efbc71d9,d338e998,197054f0,20c5a2df,7a9504b1,ca7cb603,6641f85d), +S(3f293b75,9f152a4c,b92e319d,e5d02b82,f5dcfbc,2ee7a53d,fdf7ef6c,e2595c32,b67babb8,d1d1963,fd742c22,5ad5bbe4,27e57d6e,b9e17bbb,f91d2c1e,a455c1d0), +S(3eb9968a,c9b01fd0,882ec65a,8f9f5a5a,b0fbec2d,e2dcbf88,cc9a70b7,887ca59a,1a4de130,4a46fcc7,6719c254,dad5e88e,9d6a0839,9a9a28ac,7f171aa5,9624ee2d), +S(a559381a,f41b944f,e2bab9d9,62ec7c53,efb25ce4,1ff1a456,54a99f46,d97ce20c,ebc6f66f,75ad7322,4c1319c6,4268c997,4142,11ca65b4,58c5f79a,be0ba0cd), +S(a8bc942f,c60ff2e1,140f9a97,3d7e0b8b,77698254,57098005,f9186e97,9e430593,2a82070f,25480267,c4fca773,3173b354,fcd5cc1b,ae497af8,58b7d451,8f048c73), +S(2f456ca2,c4f8806b,ce4caf12,32446b07,3405dcab,7b3cdcc0,247dd079,adc7a626,7308e58,5b9bafab,b2dee049,9bbf60ac,fdb37242,3e915156,15314ffe,5ad866fd), +S(b56f4e9f,9e4fd1fc,7d8edde0,98f935f8,4c750d70,5f0c132b,d8c465b6,6a540f17,cd171acb,d63357a9,2c23ee52,fa7d2e2,de2bd69c,343357ab,b95d0350,fdffec02)}, +{S(ec474055,43c52e68,5c9e6c75,97616fbe,edb70df4,fe3c375d,d7d24729,2b120851,22c1c1a7,30066375,5ef8c2fc,86452667,90347223,f11a32d7,9f1c0169,a467530c), +S(3f50e502,c45fd922,94fcc46c,b3118a86,43af00d1,634bd694,dfc0eeb8,be2dd4d5,7cb992e0,f29fbc5f,2887161e,6d1e266d,f11fb723,3b6c020f,26eee393,fe96b526), +S(443007f2,43c3f6f9,76914031,c41e0d49,61337340,9bd4a681,f20e4c79,934fc2de,df67adec,c9ce5f6a,e6c8312,699e0353,68ee87e3,1e96790f,f0bd3408,94af74e2), +S(1e15b9e9,c28f77df,75837a0,cc9504ab,a3a49aef,26a88d99,543fa7d2,a875620b,2a081093,6afbc025,3808ba31,f5597287,e32898ac,77fd0021,9e6fc298,26b0370c), +S(cfff0258,ff6c0d97,99823447,775b75b9,1881e06e,bbd72ba4,28f8248c,5cf2144e,61e63569,5c4a8fb4,f68f974,219bbf4e,e0c277dd,4b74b843,88f99041,f97809e8), +S(2824f4b,f72f9229,2aa04058,7a0c5395,4c87e7dd,bc5dd199,af6918e,6db62f1e,16ab1473,3bf8382c,521af6fd,27f8b2b3,b421dbdd,bcf06c62,3bcd86b6,4bf33274), +S(5dc7571e,27d6b955,6c789b4a,80d49fd3,17416fa4,e04a7eb2,3cdbb88c,9c253a44,b7261e2e,39327d68,a5456abc,9d4600c7,fb6d6e51,a732c7f6,c64cbd0d,56de4a17), +S(e93f3aaa,5d9edc53,6029d332,9ac0bffe,af27d4dd,40f550e5,3df879a2,a5c1d993,25b442d7,f2e2e03e,c7f1588,16a1af43,b5d2870f,e0cdf429,babb19e8,951c0982), +S(8f91f5a5,7aa40d62,ba407d8,6ea5678b,65c84ea8,f241e2aa,dd6df242,52635a86,e9333d7b,d6c319be,3ff4f5b6,f286a8eb,27d5a1bd,29646cdf,77441c40,f716a6f0), +S(77d398e0,228add30,e9e120ea,b16436be,30c254ae,65016672,8bea1198,de1fb17f,749a20c8,ad6f4312,fb6e6fa,c390a4a8,209704be,3355362f,31db9b45,f3876963), +S(96976a85,b6dfc4b6,13dde357,c21c3518,a5f55c7b,a2d22976,592d7632,3b5a8546,96dc660f,8ef3b0b6,adbe77b5,69024fb5,dd713566,617cfc51,c8013f2,5b424e9a), +S(49093c4d,26194278,623c2ff9,6c8e2f11,f9edf3b,13c33099,57b57f1,9db451c6,5d53ff56,50b82edc,9dee9f43,ed6db93b,f6a26233,2dbcd699,130aa9ce,5130384f), +S(49187f03,d5f5f628,b9210b88,8ac4f1b5,2f754015,541e9f38,162e969d,6a99f4f8,276aacaf,d38d0bbb,416bcd0b,8ea590d9,7735a3f2,8de72aaa,76bed0d,6644bd80), +S(7d64e446,65c03917,87fe0b14,16ab1048,3a6025af,b20e8c19,3bbba444,2864c587,2c0da181,6507f8b6,4c9e5684,a4d53d98,d6b88215,772def9f,fa5a7a1b,f2b2ccee), +S(2223484b,9ee12b26,2a21a18d,2682ab01,c291ee1c,fe3b4b9e,2e93fb67,aa08535d,4cd26418,bf0d62fd,b266a768,5f7aaffe,d7bc95e1,be41c6bc,7a0c9076,1ace3974), +S(aac92330,7d6a55d8,552ce6f3,9c531d5e,afdd5313,f801242c,21df07b3,a656c618,93d9be6c,590901a9,1413cc23,94cb426e,e6a61593,93511c,e67e1ffe,68b8f3c4), +S(6ec1a0c7,fe40c40a,f3515ff6,60f0b53b,8fb6be3d,d912f8b2,c7a473d2,3e49d201,b10f000c,191e9423,60fe6b5b,2b6b7b85,73c0c2ee,384dedd6,e3dc04a9,7834f93b), +S(bd982a5d,a4d0291c,38568fae,ebc76df3,f2b0e5b9,1cd0d3b6,d2f32077,6c35c43,48566068,d5142f6a,90b13105,e7841d32,38d869d4,fcc7319,3e3cc9ea,76739c5b), +S(25d54513,b9084ddc,a3f20e18,94382290,115ad5f2,dc72c267,ba845b3c,6ade39f9,e908508,7fc5efab,a6f62c41,ea8fe856,226c8e2f,95dc31fd,2b49a7c3,6aa53b39), +S(29ab6cd5,add595d0,cb64ead9,c3d275a6,ce383f15,9340faf5,118ec2d2,9bb9a62d,54584613,dc27c249,d5d1210e,9e121aa4,7d606fad,1c4621e1,67f67b90,d8f3434c), +S(4cfd960,86f86d5,bd805667,55979c32,d5419dbc,946d63a3,40dcc6f,6d6dcd48,f032b7b5,9d85d0a9,fdc290bd,a1fc703,55b5404c,f70d45c,d15fa9e1,33ee9319), +S(9c786066,b6642e11,139aa303,800314b0,6afd4d97,e8314a1,de9d7002,5b7bbbf4,463a2ded,e2185c8d,944f29f0,140f6b66,9ad6e3aa,8ab6e292,a2af551e,685e58ca), +S(4e98485,f15c506d,6cd29d7c,3f9a59ea,4bfab065,78d86b63,f25e74e3,e7aea96,2baf3fb1,c26f2b0b,1a0725b1,5d1ceeaa,7ccece9,a1dd8f2,7f80d825,d8cf1d71), +S(8412c389,bc88e9bc,b157d835,85af0dfd,48689532,e38044b9,117b8acd,ce3b62cb,17eaa404,ffc1f62a,38f7ce99,6216b1f,40bb62e9,6d1f7a5,8bca370,c0d30b44), +S(31b9b8dd,7d37b38e,892e94c7,a5e817c8,ffaa1c1c,f56979ff,7f25815b,758b6d09,cdb680a,ae795ef1,f94e7e87,50ad9077,7a55eec6,c6f0795a,ef951e3c,ab45d186), +S(2be45d05,e89c58b1,8212890b,b6eaf935,6f03e37a,fd957291,4ab71a97,7af8350d,c3b05f04,c9f7a1db,b6689fe0,6ecf7a80,3ecaa147,8d09a1ec,9a7d71dd,a75406da), +S(5185cfa5,fe6302c,b5573594,61f375dd,c483a66b,c615b5f9,30abbd4a,5c7ae0c,83cc447e,53c91e07,6f44d265,389bef06,549b8d78,9776000b,5c35ce36,5fcff98d), +S(cd42328d,e4a16323,c51ef888,b7e67ba,f9ee1c53,82161b90,65e1db15,bddcffd9,caed06b1,7e86b470,b665de93,74725fdc,94792c57,5509ebfd,f012133e,122302f3), +S(7a1ffea,8fe5114b,8a638306,3b7811c3,25a40c19,42451557,679e75e2,b304ab91,1ef3fbde,4f0283ab,96efbc83,bcbb5a6a,d781a215,e6ff6262,ca50b9c3,986816db), +S(cf0bdf47,a3f15b24,5c7136c2,3a3e38f2,661fa8a9,4df29fbd,8b41ef22,c291dc6e,c73d1fe3,919e0aee,5b3adc4b,1a86e709,4b039302,d44a0d56,638c3eba,24857a99), +S(3a571630,935c1f02,d6fd8744,2c082060,cd5e792a,1c6f92bd,c4eed01,686df50d,7a1ec78c,4a660cd0,ae90c00d,1a8f5f22,1f5507e1,4487e5ee,2dea74d6,17a69494), +S(1c5e5481,32b49a7f,66ae9fed,8323480e,d1ab974,622e7cf0,8993895e,ec87fac,b00309f0,7c80b970,d446a605,e2b3d52c,5c215314,d901cdb3,aaa284c1,a03d2740)}, +{S(2b081f0,268d6ff4,1090561d,79144bb9,554b1f3f,1f0f2cfb,c9344e2,b692157a,597920fb,c528543c,26499af1,8b5e7d7b,5ebf5ada,5df4a46c,edef52f2,1e2fda5e), +S(2ce45dc7,d84d3143,884d6696,73738e55,e30f6045,8bac95cc,c30e86f8,71779827,deb79108,80a1b675,a628fb09,725c9307,d1629b07,8027f566,29f8560c,2ea80458), +S(9dfa0cb6,2a63244a,35ce3a0c,f102e7c7,93a4530e,21c6c03f,15a4fb91,e116c480,b01c1aff,902f0831,bc8cd268,663f0ce3,6d8e22be,86026460,a8950636,ce44626b), +S(61a32d1d,cbd7e887,def51ffc,9c1dfd55,d06d72f6,a73ee2df,f83cfa0f,52d47bb4,69a3b17c,fa91e3d6,faf28d83,2695aa66,c87b14ee,7b2d987c,80242fc,ce2cc42e), +S(8cbbac63,5414c0ac,b6d7f659,5c6eca39,886c3ceb,82549f72,d07a4019,e3076eb8,c838dc49,fd5af1b5,e503a430,71901bcc,90e1ea38,9f735e31,236491ec,43e7b621), +S(d3f77c5f,663c6efa,670b46bf,dfa96af4,fc4720d8,e1df6e8c,1ffc5696,f37cb55,aeea0c3e,50eee6a9,16462a13,90ce5d47,c060efff,1fd3108,1db77513,34300332), +S(6f774118,4a0210a0,79695d20,f93f861b,658137c,3a072076,7d80e5fb,8b1ebdff,c12aecc9,b55bff04,bd6b6e73,870deadc,666973b8,ec498bfd,bcc4c33d,23f5d674), +S(fecfabd4,897a948e,5fab7200,969f9955,9eb1c9dd,2a31325f,34dc4f80,13da72c9,ba70c9bc,c8048aee,6fdaf5f1,8ef638ba,ce739c0c,76ec4c13,fd4dd6c1,1663d02d), +S(d1a1a1d4,24fb5ab1,3e985c86,9bd7c02f,f81b4633,dcd22e96,c3f33489,2e80d543,cd5b79ae,af62769f,dce99530,8b921b5e,39a60fd6,f989dd7e,1d0d7219,e9ee8865), +S(7099682a,c3c083a8,80467746,fb924d4a,56f23d16,a3b57f10,1a824b9e,653d45,6a9c296b,cdd72c93,df840003,24ce78b9,1f9df6b2,bfa33922,ef32733,fe49cb31), +S(1035866a,4e9ff0fe,6b0066c6,3f0a2392,c0b8cd61,36e13ada,21f6dae9,f22c39eb,6390f9ae,ec1989de,2146cd00,a5eee99e,76ea4536,423e9bf2,c778ff29,85538fa8), +S(e18351cf,163e4df7,d31851c0,409b5705,a5ffd472,dbda5dd3,bf05e66b,fae50fec,264c1d26,41f185e2,72b908d4,77222484,c651e8e1,9a9e1fb0,1ec5ed4a,8a4b6c08), +S(dfbee778,ae4bc89,24f32c18,bc0a740f,d01922b1,28e1a595,283bfb4a,fd8f2f76,d11f9b3c,25ae3619,99ec2c9c,2f1a5903,d80eae59,e096c5d,c5e37201,81756acb), +S(842cdb54,414fa977,58ae3fb1,9316ef32,af9c4f0d,649f0abd,cb94267a,124b59fe,a016f899,288f4caf,dcc6edcc,3cbcb561,fdb4047a,f789e1a8,51ad21b3,be62f5c8), +S(3deb5d22,a81540ef,cff29ac5,585a056a,204e4d67,2fb858f3,5c23e939,790c744f,20d73911,5b24b1a0,a4b31302,73321dc5,d8b74398,d6516439,4e1423f8,b4022d6f), +S(3108e61a,1e0f079,f76e3ab0,d69cf068,779674e6,49768aab,718a09b0,640251bc,245a9f2d,141f390c,f1a17bcc,a06c5a66,5cf3a87c,1096f5e9,b04c4fd6,737d9a56), +S(63b9eaa,ce6b32cb,e4cf4a69,6599f8fb,3797bff5,9103ba0,c1351e78,b16cb0fa,938ac414,ef911df6,bda32b5f,1f69cd7a,87a25d82,177763de,568ca95,e846fa5a), +S(f37a5a41,cc96a04c,c882c27e,e362d054,7d6267f1,c91c5403,2daa5c12,1700abda,108bd6ad,27aa72de,48406693,758a74df,53a3ff98,d490e303,54c45ffa,c64638bc), +S(52afb7fd,6a16dc6b,98f9d7d9,555068d2,c2317035,b7492e8a,fbf28aea,3b1fcaf3,548d8ca1,2cf7a11a,b0100455,c7240290,6cb2e92b,101d1e2e,32ab263a,3f3de413), +S(f644fce7,874e9154,8f3fb284,b7d1ba17,fad6eb6e,c581f57d,5aa11804,86de9889,b2acbd8f,5bed4270,ec131ea,1891c99d,ddb46648,60acaf39,d68d2a54,a58b92bc), +S(863cdfdc,66065a4,50c2b7c3,1d694c58,e63ccc09,fccfacdb,4fdf0b1a,b150e937,14d168dc,c84d859b,55a3d5af,9d17ce4e,83bd90ed,55e099f2,50932dad,b5d2693a), +S(9f5569e0,50a26288,5d91f82e,9cacdf9e,f4487676,730f4da1,46ce8769,3d8807ba,cba008af,547e01f,6a9c6c45,8f9d71e1,8ad062c4,4b305b52,3f3a6655,3979a2b9), +S(a0f14b6b,99f0bd74,cf9864bb,17b1c43d,51ade513,6cd72a15,89312dee,706d50c1,e2bd2d82,c549b4da,cebfb888,c1a7c5d2,f0757fe8,53e07fb4,747eb7a1,542137cc), +S(9e7bd727,fbab45a9,db36d17d,5e5437eb,f028a10b,392ea470,d5cff0d3,2e9bb0fc,fb52eb32,e43133db,28125280,e3cc55a6,76877c58,b4051f70,9c031f84,24f12d9f), +S(7d8b1a30,4c0c8931,2d5d712d,ab396efc,7a117483,7f62bb38,62a81a3,660b1068,472a2dbf,ee99c398,94d14c1e,ce87cf17,c8aee10a,4720357c,c5ce79a6,19aafe2b), +S(d5eb073c,a5afa126,70602de8,417fe50d,bd8f0768,d615ef2f,565e421b,4e7842f9,52571e4c,e4f0c424,fd288f3e,8b6c54b7,7481c3a,43230fc7,4c6f48b,d4041089), +S(3c41cd8a,77728b07,ea592254,5ac45462,2c7927fb,6a7aeefd,61635cc4,217acc90,eab0f00e,84099fcc,c2f4d339,77ff7d68,4c035b3f,34c6c4e6,aa812c9f,43af366c), +S(1eeeca5e,cadfae31,188218ae,7beda45,57f85c25,5c99dd64,1d00d8ce,2e6f7809,d7e5c2ff,4ddf421f,cf09b655,113b8cf1,a4c25e90,d02b871,91dbac55,d6606ef1), +S(54c13737,454414e1,76bfaf1e,b4402bf8,678daab1,555412d0,c6d3fd44,653510ae,753f6a,f382d0be,f1dab47c,1b9368f9,57d586c4,acef0d19,dc241ce,f008ea3a), +S(4d608c37,1fd6f635,9ffc57c1,9f1aa5b3,5b0f5702,55851cec,34278d2f,465fc8f4,12d1592d,c2cbccc3,7e5c9fae,4b864e9a,ca6967e,9d4852e,9adc9e31,1000670f), +S(71157d64,8c0a1a33,19b713af,f806cf9b,c91a446e,2ba48ca2,fdd1ed4e,8c43da59,c2ac2aeb,a298fcfa,c0d5eefc,6eae54ec,330f5c0,5b34952a,9821ded3,9b72d383), +S(327f876c,93652555,fa80a054,968b4712,930dc930,12ee6b8d,c10263ed,3b89a762,4d2bfb15,4cadbfd9,4f6696da,a1e66846,8aacaf8f,1428201,636026a5,46dfc92e)}, +{S(4d3b98d0,b5926a8b,3e5622d6,10b30e88,caa6e7ba,eb10bc3c,38aec3c9,c1267578,e84056d8,4726291d,e6880a2f,2d3b0b01,371dfa27,5b8c9cff,4805d18e,a5bdc788), +S(6e463689,111d1a5d,d10b09e1,5d0f438b,1cebdb67,7a6cd230,bf6349c3,70667db9,de10eb3f,5d2f4320,7265952f,b33fc23f,154972fd,d3394cc0,21b66276,1b51db3), +S(48235e7b,76c94c32,b0d21bf1,7fc215ed,df036366,a9ef494,19723485,78db8943,4f5ac8ce,36c77403,b2fa83ba,1fd0e88a,3da4c8cd,3c10ddb,aafe2d0,5da40a2d), +S(668af7c1,4063dfba,1a4187f3,f69cb457,cae4edbf,a3bf9669,4080b6de,bc3e2f0e,ec95f37c,7bac26a0,df23275a,283828a8,5a102d8,f33eef1e,87cb56c1,850740cf), +S(d4426fcd,cbdfd904,725fb501,656b9f2e,2a9f9ee3,c6522064,f078165f,61c31d97,e73f2a38,c56838a7,174ee704,948d28fa,5b5fdc34,7774df9f,72f27834,a85eb4d), +S(d0f49ec3,42076b68,4cd91172,f15584fc,ea38aaf0,a3201063,f854ff1d,f68d4600,28d95ef2,82dd7d6d,72be7854,e8858b1d,a142002b,ad7b7b4d,bd1e582e,94341e16), +S(8a36f3c3,50bc0f1a,1b1687ed,4ff83a68,1578d74c,c28fa875,f6969e52,4887bbb1,15ab9e05,c3ff823d,ba090e21,1033c34c,fa713d39,feec4346,88e3ecba,4b431e10), +S(4d1ef23b,b316e821,7d2cc409,a1baa273,cc06f79,8fdd4d16,5d5b6805,3718e238,fc37e62b,db18154a,2add98b0,ec221e8b,bd1a2096,ac2dd1fb,cf8e2e64,821301fe), +S(eec1f8e5,76e87803,bac48bb4,65ed923a,a68b2965,64365d45,bd1c24c4,cf7041b0,2c6985e4,7cccbc38,3b85be66,ab34a166,c98a8000,aad08f73,616e4d2,2a15a009), +S(9fbc20e4,de372a38,90443786,bd7cfc40,c6195b29,4cf51874,6ccd9ecb,cee223e9,f734bfc8,a6973209,903edaf8,52f63bca,b23fc1a4,879906b9,1c5df169,9d24683a), +S(7984c8ec,a2b02dd4,e8b9c69c,6f803418,48f108fc,b63d7038,de58e567,e64a894,49adeb11,13c705a0,9eb01e50,dea5be48,86e5d424,689282ba,6d64f745,74f45e8c), +S(29a7400b,16f5712a,2324becc,29fc4b98,57fbb926,f8741dcb,324c26d9,6cd178a3,90770be5,5c0a94a8,16bcfa38,aeab11aa,5ec3b7d9,eb4e7d29,1bee1c02,69e87267), +S(8299d2fc,84770bff,a4e630b9,8f2e6744,99b1c7f5,719e907a,d70515f5,140a00c0,c790968f,a3c3d4ee,3e25a1ee,8e1d4923,3c22f034,ba7c172,b5d7d91c,99eabfa8), +S(5cfbd498,5b608db3,5d1a2872,b9cd03fd,d775e498,4629f41,61a2bde4,fb2582f1,8288fa89,81056333,acd1720b,bde757b4,e83d0a49,9c5f2220,521a0bc8,dbe827f8), +S(281f1fb8,e144e39d,9ec2104a,96bf0f1d,494eaff3,57fe084,63825228,ecd286e1,ae40e075,d19ee5f1,1dd7e22b,f1c277ed,9a02abe9,975609c,a7c811f9,7c54e493), +S(51698bc6,73d3289d,6b4882b0,cab14e67,97d31221,e5bc6e53,af061aa1,9f546daf,7b850099,fe977f6c,f50abe00,bb3a0b68,90f47c45,24e9ae02,94304b6b,20bd986c), +S(db701e92,9b696c86,d7fb459c,97af90df,ef847bf5,1d235337,2a2a4792,5fa8ae53,edc7e98f,1a108bc4,8fdbe65c,2904058f,7da5e188,e71d194c,4e9dbfe6,8a55d18), +S(c900f57f,e9a31d4c,9715a822,5a906e90,22d81c12,714006d5,81be0c7b,aeb5a490,8493eb00,90517d9c,b70a4bc,39043ffb,e0863475,17cde2,a9bd0d95,f616bb66), +S(d74e842a,fe2da0df,df6342bb,582fc223,717e0641,f1ce0e14,584c5c63,f379ad72,cefdbd7b,b4ecbdaf,409a0fa3,9a0a305,b1bd986,4913f977,bec6c47d,5d525c10), +S(b00a5f4,f033d126,64366147,a1bbb9b6,ea60a38b,863c5f3a,e323e8e5,1aee200c,11e9f1f7,b7701a4c,26a881ce,30fac1e0,92e157d7,b9c2e4ce,cffeb38a,172ead87), +S(5772b134,68bf9f09,d26074c5,16dd7472,d3a83624,92306cc5,c7544ec0,d73de280,2e2a7931,aefe2a31,6dbad1c,e7f9d42b,7f38197f,43024f16,9e27fbc,7af31d0b), +S(8bf8af02,ccdafb15,598f6725,5f172fb4,ba8960e0,6c81ffa5,b4c1c313,6f95f29b,96041af,1efd128,ef133e5e,b0aa3d9a,6ac3a651,92598b09,ed649847,385a9b2c), +S(292889a2,d8329139,3410385f,cf5bf489,7e1ee23c,e0e3b5ed,82ceb340,d89f87a5,41099fb2,bcec7e07,d4d4ad14,3cf605d1,b0a32487,1736063b,e49b06f6,d648aa69), +S(ad227b2b,737dfd02,665c15d5,9b28c7e8,76413dfa,25c9068b,90efa79,ce83142b,82f1eef1,7e2f6b86,87137302,741f8486,26fad679,9c6a22fb,3a49e341,c7e51e9a), +S(b4245dc5,5df02839,4cff2610,4a4255ef,89f3e708,21541c3a,4631ee4c,145bf85,5a40f72b,7a67540b,6858e5e,b15005c1,3fee862f,3cc54a52,7643204f,d0b8be2f), +S(15aaef61,568537a4,695c1990,c05ecb9,2c605232,f705c3e3,729720de,7e9c2400,e6efd1fb,b74e9e43,ec1244e0,bb4cff2,2a5ede8c,848a4f5f,5eec6f8c,77b6f5af), +S(ade2e63d,4a828328,b4c53763,30790331,734d7f90,37c1a584,59570c8,f31e72d1,c42898ab,3633dc7b,f3a454f9,d5475c4e,fcf1f786,d1f609fa,23616f26,b23a1a97), +S(d8a9043d,297681ea,c5ed63a5,de306500,6b66e4fb,167aa5ec,c76a8e2e,df426e7a,cd3de058,a0a93d7d,7122d777,1446b2b4,d4cf53a7,1759fea3,78adcf03,5093f4f6), +S(30651cb,592d282b,5348f192,5be3f04d,da5033bc,39e2fc7b,1e61500d,9769b57c,dadf77cc,44853f67,53b1dbdc,17a97d3c,e6d5b2e7,8c6087fa,800c5af9,ccdc54c), +S(aa21c60d,6f7d6253,9d42bafe,95c58f30,33c0396c,fa0ceef9,6d2f91ed,d6569044,4d519779,3b19515,92e2d952,2be520b1,11a5453e,ec6d7ccb,3e6db3bd,3d0c84c9), +S(5335cea5,e99eeb23,765b3444,d9bc7be6,1da67d6,91bcc42f,d43ae543,e9c22bc,c4072fdf,8963addb,5f980f7f,f314795,373cf3dc,935e0e64,c3d3d98c,342530cf), +S(708a530e,9e52c73b,ee87c9d8,8161c810,5d5762,2c29ae69,1cf999a8,3a1187a5,6477b7ee,1e065768,569a923,4492c7d7,c13258c3,92cac175,a75b0e63,b8c2426f)}, +{S(3fbd5a4d,ebbeff54,8c2271e5,33dbaed3,fb8ccc23,e3fa2579,4c8f7fd4,47ae186e,fdee4625,45bf75f5,5c29a724,6496d970,4616c54,ba01d0ba,feb9155b,cafdb555), +S(c1483ec1,78ba8414,c371b57c,49c687fa,69669e2,e3e1067,cc6d2a93,b1a9d24e,edf94395,962adfed,c2ebb3bb,29346136,e4dc870c,5c76299e,3b07da35,6bb26bed), +S(26df4b09,693a3905,2cb7a1be,5bc2cc97,222b70e3,3d297a54,43741228,beb77017,a3d6b908,cc6d5f80,aecda93,99e17a8,ce33c423,f00cfc4,dea8354,af502760), +S(b6c265d5,90475506,e15b2388,b894718b,be67aee5,ba40ceca,51876946,e336d903,b451d3f1,2c666c85,bf9486cb,296c39f9,49f9f98e,96d50a19,80f86f85,a1efb999), +S(da6cf69c,feec7b1f,c848639a,7e27932a,f49cd695,a2e56a50,693fa862,6e257c66,4506f44e,e6e0d822,7e67dc4a,9f8e2ec2,d3ec0c3a,c2a70c7d,d25fa9c,34cbe3ae), +S(d57648db,adf18b77,db185ffe,3f86f859,6adeec05,ffb86215,4b894a0,75776eac,a3f2fec7,7186d81e,4228cb1f,691e00e4,82a125a5,bbe9e6ec,45a53604,4932491e), +S(4de6cc4,d64d52c8,49c0e8d2,45409ba0,88248399,1916df3c,238be4de,ee2504d2,b389e7f1,ca72e9e,1cec2ed7,70f21441,590f0bab,1b963f1c,411f9bff,d3df03f0), +S(15f1bb11,78b01439,f26412,1d36a44d,b8333fbc,eabeb471,da2e6c1,1b8b3ee3,bf137117,35e10854,95acf3ad,97fe510b,33d6628f,e67d0067,499169e6,6c12274c), +S(badc76d5,481e77,9df71d6e,223c6965,9e9ecba5,8415a95b,eb7118cc,b1f931a4,475e47ee,115d258,3f0607f1,7542ccde,626e6d57,6ea884f9,61b41354,aef37247), +S(13015ae5,d770f4a9,75825bae,a6cbbece,78536dcb,78d7116e,d304aaca,199add2b,f5e28585,7a99ff0d,a4fd15e,8ac650a,98421629,aa102bca,25df3930,7e5cfcbb), +S(7734d2ac,707b9b53,afbd2a64,50c9b609,1905c391,958d7215,f92353ee,fd3c7be5,751d38f,ef48bfea,8fa5de06,8188a658,ae6c9c75,a359a4ea,efaac5e0,b5e859aa), +S(91814384,7fe2ed34,e9cc9c61,3fc2c67f,2b76a208,561d0e06,271b812f,6c678856,9a97f6e0,9888e076,93c9ebec,b8773485,c3c5d208,c793a77c,6984fb09,cdfd67b2), +S(98c516fa,2a2c8073,70ca9d7c,b4187108,ea345652,c8f814b8,b4a9405f,b48c2469,7b3446f3,2e8c4764,a8eb0846,4be3bc6d,f42b8d14,b7da65a2,ac96a018,d0831c7a), +S(5691d1e3,713302c7,48bf633,189ce032,10832e4a,9af1dbc2,abc3e99b,cb4faa01,d802e21a,fab84c54,5d665ed3,54130d9d,f7f18283,30b3a1fe,e30c2298,8b71654b), +S(1f8cb624,6440b640,aadba62d,c02f4ce7,a0ba9be7,d535987,64072fed,95c0d1a1,647a9dea,abf8247e,f46b60c6,53cdcd5e,cff0d1c6,88b7519b,a778f9ff,c894e1f6), +S(1489af53,94878f07,5cfb2e20,931fa3a4,e585d494,78818e4,f47f05e1,2be54d14,cd5bd721,4e535822,43270bc2,dc692ba4,c57e494c,eba92d4c,dd2e13c8,e24d8550), +S(66159248,2b2229d,ea70ff76,d2a5e70f,ad1905c0,9211e3d6,2d1d652f,ccd709a7,8f5ab85,57948aec,67e7b538,fa9c704b,ae939c22,4041e6e1,65f6045b,a6fd0fdf), +S(bc894efc,d0fb7497,ba70d654,961aa79b,6ac5a795,95537c80,82c525c,2c44c3a1,d5254292,ef0fb6fc,db587393,3b17adfd,87d13320,858ff783,75e356fb,b0d3415e), +S(f117d7f6,85457601,9b559bf5,f5bc150c,13363e7b,72123435,b441d98b,d169dd27,a8f4a23e,dd0d8f2f,8950c124,1abac43e,e629b0e1,8505c3bf,780ea378,20c8623f), +S(2a8d99c2,65a66a51,56b60556,775c61bc,b2a81a62,34896a31,16238c2a,b7716ec3,5e842306,efe11f66,5a049c0b,fe3ac74d,d72c5033,6dbd04bf,2a77b0d2,4d7ea651), +S(ea747597,1a6b6d94,2e368bcd,9979876e,afa4622d,313d819d,5e8291c8,2da95830,41d4a478,e0950bb9,e6595bef,3c197e5,d0f77ae,6340ca8f,2947fec4,70465193), +S(114150c3,fe8853ed,9f3e26f7,bc9f3d6f,aa50ba0e,6ae2d8ff,97924b04,dd9678b4,5530c22f,4ac30716,2b272015,460426ba,9602256c,ab735174,1a2fbbfd,cd71d134), +S(65d96017,c91a746a,656eb595,d39dc9bb,3476dc0b,1a1036f2,df7a4ea8,1846631,de46bfad,6999b108,1f358edd,7809919e,4de768f1,fb21dc09,4b248bbd,56b3dc76), +S(f2aec214,61c040c0,ebd18204,bc277312,732b452,266bfd55,aa071853,e458bea7,52a1b71a,eefe2c48,5ae2918,e236f1d2,1622d37,13b4bc04,36124567,d48cc453), +S(370ef89d,c39e637e,8bf6be31,63a4f76,7cebb202,c868647e,db18f991,977681de,e6d402ba,9769363a,b963729,822bd6aa,9794592f,36e54461,579ae53d,4c8bc4cd), +S(8db6356c,4f31f46f,961e4342,a1ff50a1,8240629c,a0decc36,e1bb24af,f6742e57,8ee033bb,96958466,15626ad6,736e9025,fb76320b,c2d0ceb8,ce3400cd,743f934f), +S(14a1a08,502510e7,1060f291,1316ee01,b1fc2bd3,c88eaa1b,656cba0e,8e3515e4,5a4dc536,b62c349b,c9bfc6d7,fb677231,1368655e,fcb9c89e,572aa58d,a57f08c6), +S(d530fc7c,4d5b4fd1,5f44ba0,c0f08f24,889b278a,93ee30ab,935fc112,5e244a58,39c0ea88,5984c2d1,d5119a28,7cd842ca,d3cb54c8,ab6aa222,c01e7152,98aad10f), +S(50f3c13c,a474f604,ca992658,bca68207,76acff7d,d507d63a,b5e18b28,5c5be81,685e151c,7d8fddee,6c9d8513,dbf167e2,c32dd70f,b6932397,38eb63fb,3e4f7afe), +S(c0a72dda,13174682,726ede1f,7ecbaa68,b4b137f6,d44298d3,4e17b7fc,10e19d4a,1e45ff3e,4a4239ba,4a897489,a265a60d,9a91f3f2,83fe2e75,9e770156,c9ebb3ca), +S(7121e14e,7e2a2c57,76b5702e,c83a845c,28785c79,9099a007,54b50fca,b4d9279c,e6b3ff5,ce62fa35,adf45e69,2ccafb91,b805d7cc,b6eff2e1,38dfd680,d0684401), +S(c0c01f34,ae41b8cf,e466b4c9,c6a5d5f6,14f570d6,fcbef768,a81a6c8f,5ff4adb,f47b0a41,1bca80a3,836c85f4,bf8a4731,3243bc2e,8f2ea47a,3b1008b,53caebca)}, +{S(4f20ce51,84fb2949,443286cd,8ea201eb,15248749,6e15aab6,f3ea2597,d4cbf47c,bf37770,62691c5a,d6c6cb8d,c30fd3b1,73578a3,bcac43c2,c8404b6e,c085c97c), +S(17ceec36,7fad4365,520599d7,62c66c12,5abeff81,ce7242dc,bde4e799,402759c0,91e024e1,e2147fe9,73091001,984dd3c0,9f887257,73bbbedf,47f00c7b,c5c9f626), +S(dcffc4a,5557f2a6,ac7a3527,5a8228ec,325ea0bd,d9bf52c3,8a78217,6bd716,87658163,dcfc39e2,ad08a499,898a1505,988d9b86,72b6d1e9,64e6845b,cb41129e), +S(625fff43,45337aa2,1efa0884,73a6662e,d5340470,a79576a4,362e30dc,bcf762d4,92ad0a66,d0bea2a6,d7eedfe0,e33295b9,3a656e45,9220026a,5ff3be8f,83184187), +S(410b96fe,7db23faa,7d123e97,c1a82a9,7b24a26a,80143e50,dcc6d9a9,1a6e81d2,ca0da356,dce88799,5f8cc790,64d197aa,6532dcf1,20fe93c3,7e2ff4e2,f14394a7), +S(8136e51d,ca68170b,136d40fe,76980b4d,d4f435fd,e38f3017,99de734c,b2491551,823dd1ed,de1d326,676649a3,9d5ba083,7c48e180,ecd0a648,eaffe7c8,2894e819), +S(64a67d9a,a7a31390,3ed9e348,e7300917,6c1d52d0,be63f54b,aa3ee8f3,f1227a52,ef770581,df4aa013,6d191e99,cde7f42,a14fdfbb,11e1b709,bb540100,1dcda1ed), +S(5fcf0465,a905aa8a,a1da5073,d524e8a3,30af663e,f4307359,c03a4c6c,c423dd9a,58641e67,fa821fc1,2307a66e,fe0129e6,4ace7c36,c3f5395c,db87667e,5e742a42), +S(aae6747f,ac3d8c9a,148009ea,c2d25574,39a8b546,455fb3a4,5016891a,f9372dbc,66084f19,b1d97f2c,22e182c,d5450d43,d56636e4,92651cf6,22772a7c,5b46d9), +S(377dc2c8,13e36bb4,642d1e02,cafce754,2ac6d9fd,c2212edb,5432674f,38e242c7,8395dc2a,39d3b1cd,ae9d7d37,d0c4597a,11f931d8,75c8bcf5,8eab03d3,674d5841), +S(35c598c0,7ac5dc3,7afe6895,29d815e9,406e2608,292ffa0e,7b24df65,3278d8ce,e793aaf1,45f538f6,c133309e,53cb5343,dc1dcc74,985c57f,27361c6,aae23e7b), +S(e9666336,6bb286d6,c86f425a,2d5658cc,1d733223,9ec2e9de,c8ab7295,4b329845,908dc533,b6098e9e,9b737e4,b96e7345,e635f591,60bb3df2,75e165bd,d1cc5998), +S(46fab0d4,7fc6586a,31cf861d,ff5e0bb8,cc12b60a,53103007,c8974ab8,204af703,845ab7de,7654fb36,618dbfb1,287534a9,2d43db6f,2a2cdfe4,5365b4b1,893fbe9d), +S(4d80486f,fe748d1e,f88aabff,76bb82c6,a45db736,76ee0ff7,d77cdffa,2c69d07c,2a52044b,d4fc6a59,fd16dabb,df35bb6,8057ad4c,292e87b5,528a3847,c8784638), +S(2c1d108b,f4945c0e,df62cc15,6bf0830f,7a45ca,1baa636e,9f759bb8,bf078a55,81e34495,d269afbc,1be39ce7,5417ebf7,d45decb6,eaddb635,4480a7f7,8d7dd34d), +S(320a08af,eac009eb,7f254b8d,395d836f,ca6ea527,4e2f309d,dfb7f120,2f1b3cdb,75269a2,41199c0e,5f1cd9e2,d102a294,2324a3ea,cfae231f,99ccc5f3,e0af00c2), +S(8b893fcb,9a524af2,6de5aa38,8ac3dc,2159817c,7062e5c9,d5c9e7f7,dd889ad8,cec6a5ba,481f7e3,88c1cab,c11505f2,39afa143,68977ed6,52ea2d6a,19d2cbfd), +S(ea89b95b,36cd5203,22c8e5af,7461f9e1,a054f23d,2720469,fa74cd67,3a52aab5,5325d16c,4b866865,2437b6b8,598b31c4,59e6101,2cc1b147,e0473527,5935ada5), +S(cdfea79a,8c16ce78,75a9fa1c,5b7647fb,ad641ffc,5b73fb31,d9354a1c,3c1cabfc,184c309b,b0f52999,2a3f6b93,77b9e6a7,6da6b943,d8031408,b71223cf,b3ba9100), +S(3daaaf0f,785a6397,c652331,630931ee,a975c522,35899736,1b7e5fcb,409880fa,952efec1,ebd4c107,b26a98f3,c6683903,a498c840,ff4a36c7,ade569e4,c899919b), +S(7cea5226,a56d21cd,45bfdbb0,7fea6670,40247c70,ef43da28,d1f8bbf0,6e4ef2a6,b03edff9,6a5f32c5,6f8f63f6,ba9feb68,f43cca62,391ea587,81396c7,5d963b67), +S(1f5f4c27,847ba921,c63cef52,8b57fef5,5bdb5344,ea67a23,c173828d,c59199e1,d37f6918,e0b774ad,317dbcac,75c82188,c8a421f0,ff5756bd,853a05b0,c95ef089), +S(36cd4da9,2a77613b,6417deac,1d9a0dad,1bf0e506,de26b529,7fffbd03,4a4663f3,ec1dd8f6,6226bf5f,fedb071f,7027f9d8,d931e6af,e378396c,d0d296eb,a63737e3), +S(9835c156,1be21ce5,db788f1,3c0aea13,fde6861e,97cb2cc7,a67fbd37,17eefadc,7fad454b,7372d969,a6e754ef,c73415d7,fcd4d589,c8e255c5,1adf5a9a,82228f42), +S(5e218414,d9c9f0ad,35ded20e,76a484a1,d41b3894,ba9d3be4,bcb4546b,371d0e4d,76966ecf,9c8f1c9a,452cf971,10ca6555,2ca59d31,21092e93,333bbd61,6eb9cfcb), +S(b105f4f4,40e7ea66,e3272da9,d6b2b76e,d00e96a5,6f95224,34ca0df1,5340c585,9e8fea7f,35bc9eec,f82ae118,bcb6dc33,acae587b,f37b149,1f8312e2,4ffc86d8), +S(81d5713e,a732b4d,98d085a9,75cac9b5,3fa65171,e5cf49f4,684a7856,7c24fea9,32480cf7,a0bc0c50,a4de8200,9343b524,4a0f2aa8,ce67b11f,4a5482cc,6fa00bf2), +S(d47b4f1,88f5e7ed,a9eab2e5,8ad2c140,c6278d63,517bfaca,8cfb64aa,cfbcc7ec,524f6580,9d3ee034,afb1e64b,1a0f8ae1,1e464915,3722e345,bfda9671,1b94a5), +S(16e85ad8,6a953564,39b97957,7bedd0e9,6e2eed72,76ba269a,626fbd58,447996c0,8bf74f51,4bdbb6c1,4de81a3,1ff12aa5,de49bd52,63a962ab,b777439a,47eadee7), +S(c299c6b0,6e6c78ae,852bd55c,dea35f99,d264cb5a,e836b77d,ab209ac9,c05201e1,a558c66d,c9ee7fa4,c777b0db,288b328,428b230a,7c53d516,522ccec4,af0ae08c), +S(63c4624,35ef974b,393b05b3,7d1c89d7,b0d8958,ebd541d7,584e2bbc,7235c795,1d806446,ecfc7bfb,bce099f2,6ce37a49,61b53453,5b65642,c0cd23f5,a4eef9d7), +S(6d36d105,ed8cc5ce,53f2cb69,8ab620f9,469a3e5c,b25bf6e6,d413f414,c5af726a,1b45a3cb,1c889961,8d273993,6a3affd6,233a66c9,4bef75ca,3a8fb6e4,ec05ffb2)}, +{S(abdd85c7,a2f8bc31,343382d4,e405978,3874c8d0,1405ef14,85047cf7,f0f71d50,d5a03157,798fe828,a03ab63e,84bb007,b53a5315,1db7af14,e4ab612a,736232d4), +S(31297c6c,f567267b,3c8d65a9,72afc752,e8525eb3,de2958aa,76f72e14,5ad903d7,f4735877,a6c6d89b,d1beb50b,edd1235b,5f5e5d0a,878e4610,e7d756c5,34813389), +S(64706e69,11a7d0a1,2e587c86,91117a27,cbfa64ad,1d5617fc,81e55b8f,64e0da86,59d9af3a,419957d2,b3de7570,15fd8531,a5d07430,5cfd7444,5e7e70b3,57e62772), +S(a4988ed2,89d8397c,f1b897d3,b81d80fa,92658ce,2b935f4e,e2e3f0f9,b193af51,813fb8,73270570,50f23c3,f8082bcb,563ee366,1f6b2af3,f631f5f,916c8478), +S(3c2769bf,af401993,595a01d9,9c72a6f2,699591fe,4b869077,8c6b5ee0,f172a866,f3e0d8b6,cff168c,95873f44,871d27b,df1e79a2,d9e0bd4f,6f90f682,538c1f24), +S(49d93e09,df655edd,19548fbe,affce201,4c6822a7,e196eb98,b9ddfad7,3cb70125,26e6957f,84ced17b,c64f710f,b37656d,31ba088a,98350337,8f7323cf,c57f0eee), +S(53c06842,49997cb2,6e5b4cc,5f166fe7,db0ec0bd,52639a27,d8fedea7,214a78bb,8a8dd3f1,b3081dd4,948255ed,dd178089,a0fa7342,1ea616a5,1f639057,34a489c6), +S(7a8e7d18,3f2aa640,d0e2ea02,4cdca5fa,1767d9f,9ae38805,5d38e8e4,a81d33b7,c2fb92e3,5556fd14,4a894be2,3d97c6d4,30872ccb,25e239c0,d959a24f,aaa77397), +S(a5221a2d,29cf3ef2,f066897e,4ee74ac2,95b34cd7,54390814,297537ae,abdf603f,ec0ff395,8c3a1d1b,5a379417,5a61cd97,782c9683,aa2c7c07,5d147db0,2b134278), +S(3f49da9c,1d62eccc,afc4b88c,814e44dc,8440341d,f347de1,fb60126d,59578dbd,c3cf8e96,2fa9478a,f1be08dc,961734ca,5021a65d,b1b45f80,78fa8e8f,d2813a79), +S(47b16636,f5a64b07,534be14d,6ae37af1,9da79b42,666b201d,d0afda9a,2daeb6b6,f1218111,31ebd87e,e1fd7c9b,d24a0a11,a12e842c,6c00f445,6a342309,9b171f12), +S(a7b5a8ea,1f23ff1e,c1768eaa,2fef0d66,b75744c6,dc925d3f,9068beff,d69b32f4,fe01a23c,b0e5acac,e60058a2,889f9434,9ffce6c,b24f4a3a,662e0079,99bcb690), +S(3e14e2c,e7044716,d42e9b6e,54cb0500,a1e4374e,18917336,e3205e31,4a878b47,18af982d,2c78ac23,818644f1,ec657da8,ad66bdb,3d5a9b84,3f8bb988,4ef8dc3f), +S(71393e6,746d3072,830299c6,c1244303,750742be,361c5f08,6eb314a4,76f1736a,dc30a7ea,9b644339,ce8f1fe4,eeeba07,5bb08934,8135e819,cb061559,aa14e42f), +S(37721b73,e6861f15,7993696d,aded49d3,78994f3d,e2b573a7,defc907e,d6f301f2,ee0e1755,d8efb25a,5cf4d783,ec847425,746fa442,d460cead,56e73a69,42561de1), +S(7803c663,509fc9cc,55b372e1,dc0fa76f,149a0ca6,3db4516c,4abc0ad7,5961e4ac,356c72f7,794a70e4,db3463be,eaa847cb,256c58cd,b6a7d862,fde4feef,d896a46f), +S(32976d3d,a3d033cd,c073b0f,c7d2f445,25646893,fbded1c8,1a0a1761,a8703206,5e6b7900,a069ce4c,65cd84cd,f290f092,2b936bda,af6ea40d,9c36a321,a7c9dcfc), +S(c52c7b18,b5fae5fd,a4e3597f,39c96b8c,6d6c856a,80f1210d,a1ebfc15,34850763,b87e50f6,20b66865,307d0747,a02ba22a,b310712b,cb0bab6b,963c589c,c5a208b1), +S(7de59c8c,3922fd51,68f4151e,cb783775,cd0bc0b,1185ecd3,6ee075e1,14e66cf7,688e2cad,e4d49da7,fe691497,412c9372,c67288e8,ca4b64de,308eabeb,723fda15), +S(ac49d6f3,32cda691,c345f099,667ace08,f6496126,830c39ed,877223a8,cedc8be7,267e6a52,5ddae4f6,7e05f0e8,52b9dfe,5101c491,64d791c9,82249937,c3a7b031), +S(5a92401b,698cc394,c9b714c8,bdcd92d1,20fa72e9,b1311839,1c383024,f469ed22,e29f2926,84c255a9,a739ef0e,5d13cc55,987f5b3a,5c6ed623,29431033,70edb4a2), +S(3609dfba,51616095,ab060e77,d6779025,6456eddb,f4b651c6,442cd673,f893878b,f85fa9b9,442050d8,ad9d9314,9ede8698,91dfc99e,c05a2a48,5854cbeb,55a6c380), +S(332bb85e,92c90a15,3bf602f,45dc33ab,3dea5ef8,7034af81,944113a7,4edc94d9,59b6c879,5f2a824,96d631b5,ceff8708,507db41a,375c7257,7533d8f1,461fbaf1), +S(16e9e054,916b894e,730d7126,27b1bc81,e7689efc,23cfeacb,a423362,df49d87f,303d0428,b701f1e5,fe8ae460,e54adeb2,d4b5aa93,a9c7d7ec,7b903cdb,20e440f3), +S(4e62ab89,1d4c4cf0,2c44915a,4e2fd522,88d75aa8,e22b7463,30dbfbca,97ed9515,a7c21be3,3b5cd522,4de0bd25,faa9c2de,5d6b2f50,b50a6901,b7167b3,c4def4fc), +S(649eedbd,5612c429,2aedbacc,b846e759,4a2b5870,f21452f3,1ac9e697,fc055db9,ca694303,ee206a4a,acfc4cb3,1aa9f117,8fcbe37f,d6bd11a4,669289cc,7c37b0a), +S(e858f72a,5fe2314,951ca096,8ba59760,e3d2a667,e76dcae8,c3ae2d7a,4721afbc,f1c7131d,3e2d0468,ebb89bce,700e0eca,ae83afee,75620938,60e1fc70,cfc7810a), +S(cd351498,29ccb1e6,9b18e35a,72a24b30,e074793d,aab4028b,1c5eefe2,b7b3163d,6bbd52b2,93b43cb3,a19f6291,69ba5b2a,59785099,16842093,1e58dc1,a040c57b), +S(19ffe344,69ba3e43,7d901863,3be7c298,ad8b65a0,49c30dc1,bae30ca5,97ab38fb,c33ca345,efeec662,96802e95,69f0f34d,12ceb64f,30fc704b,b77261f0,ce5c98eb), +S(8a2f772a,a38a5b55,a7081d0a,61bc27d5,89f9832b,1326a230,d81b9f58,4d634293,a4707a0e,a7bf528c,ac62e361,6f09287c,182aa3b6,6862430,dcfef3c2,69d1567), +S(e583bee3,1dbc8f0e,572eb18f,366f88e9,3a7a0484,b4299b9d,335f7836,a222636,8a4fae1b,be122228,be9d8afe,be223c53,dac161ae,ca77ff4f,e14d9c78,894fdfec), +S(8b6e862a,35566848,50b6d4f4,39a25950,47abf695,c08b6414,f95a1335,8dd553fd,15a1f76e,f12ee34b,f2ef43d2,b14605e,db53c3a5,e7cc7c2f,27fc252b,c1641642)}, +{S(1c185b5d,e988ae93,eebe0aa4,a98396aa,fff2671d,8246ce2a,4394db96,7a541ad4,dddf4244,3532024f,d225f86d,133b8156,3ea8c92b,f0ddc354,88e6a04a,d41da5fc), +S(addee173,b29de510,58dc107a,47fad47e,c48bf332,2f7c138d,51060322,571faacd,3890624e,c6920ca8,6a9aadb9,90a15156,799dd771,901823e4,9f3bfcb6,8bf05d5c), +S(9e20bbed,ccdd5c05,d683b2ef,852760b8,e246e5d9,6a8900ea,999ac8bf,5e8f12e3,9f28e5a,b4257f6b,b826d076,ffff259e,1caeda5b,7d34f658,ddfa0401,7cd4768e), +S(dc825d1,5f707c17,46920014,9d7be56,acf2d1d3,c444fa27,cefe5019,6f5b317f,226d4960,2f349d4e,9cd10a57,6bf01681,e4981cb6,4235d347,72a1e5ce,7694a20c), +S(812e2cda,3f473919,1f2ac087,7d70d0e0,2ca0551f,10c96d95,51ba4199,22780f90,c8d05855,6b6364bc,d9aff119,5b9ef26b,85cffa72,1e880b83,eed73cbd,d23b91e1), +S(aebb0870,76f5918e,68194fce,42d0b925,cfd2a506,359af62,146c8ceb,8502231a,c1c19605,e0456cb1,3e57229b,45c83ff7,c3695a2a,31908bc0,31b08140,9c2040fb), +S(af7332f3,3ec274c8,d34f47ac,fcbacf8f,7980cca5,7220012b,8fd5ff94,cbf3d8b,d439f1a2,89799dc8,92b7e53d,a84a9e82,7bf7bdb,7240c34a,caef59a,777188a8), +S(baf71cf,7851a758,12d7e09b,192741f2,1b5d2a36,6e31892e,e54c282c,81163a6b,1ef3bf2c,a81acdfe,17cd6b45,266241a0,22caf299,ed4d87cd,68d3d4d4,526b4d38), +S(615991c5,d250cebf,8c7bd1b2,969213f0,403c7da1,a3ba913,44fd0490,88c2474d,4f014177,12142cca,163f29a1,f5790004,32726712,93c2e87e,f46d2138,c14040b6), +S(b1574b39,26ff27c7,b2dace6,6108b93f,3fc75d48,478567cc,66bba29e,750c0c86,2759967d,8d05be25,3f88a66f,830dfb83,5139e32d,6f42cf3a,43b199ce,ab85b55c), +S(5fe92a7f,d1c407fc,967dbb19,e9fd4d,8361aefc,a3d5a9a4,2f8237a3,458e5e90,9b89ce35,57d469b6,9b9034d6,cee93609,c291d023,d1d9349a,d9bcf47a,aed8b2a9), +S(d65b0a5c,41b2dc6b,e5aa87e4,adfef952,621f9d99,550e424d,176ee180,65f666e,a76fad91,3b80b0cc,3d3ceac3,9a465cb9,4d8c79de,92adf9cd,7a4efae7,c85c30a4), +S(61d7de65,fe34ec4c,f82f67b1,75887263,11683263,145cbeae,18ed192d,14ced48d,effac049,d7e5412c,5052160a,6d1b2230,7157669b,856af0e,e3e46a25,2d2ee19), +S(9a77de66,5165a9be,3dd2758c,39aa7a14,1f052358,fbac634,5ea701c8,c93bc4a9,1044e428,bb381024,70108d56,b8b3e3bc,7512300c,5a6ae44b,93b2098f,a13fc023), +S(4ccb2426,b6eed0f9,651f80d5,72b23e78,d84d6928,57648077,3663216a,bc8a418f,1840c,bf5ccdd7,19f7fa8a,33e7151,aa351d,2f620972,6ec67d1f,fdada8c6), +S(53f96bb7,86516e0f,2ac7611a,1aac61d3,cfbca76a,9609fe,e4cae036,52f68271,97e3acbc,468b777b,bd1c8263,5332dcc4,b08b9fb1,9608fb35,cd51e49b,f09d9087), +S(395253a1,b6a349a6,dfdb0d6e,65695572,2a597411,fdea9294,6e48d107,596d8ac8,c57110d4,dd0d35a7,663fb3aa,e15d8c4,dce5cb67,d3173d91,a6ff7ea2,1bd28107), +S(d7becbeb,c47d0de0,899ffdff,8620124d,b29c8e5a,fd71a0ed,76e0df76,bd4e26e6,d8b52fa3,e16e7f19,e925e769,3b5a731e,18f3163b,1ad4db34,7f878381,da75fc15), +S(fa3afae0,4f8c1fa2,778446af,88e29150,256b0413,d9bfeb44,45288e41,29be15a5,9dc76b39,574453ab,2d46cf23,ce8cdb06,cbe7df15,d03fd390,4470a86a,822028df), +S(da56da00,dfdd788f,90a12219,db03cac1,403efef3,ae706031,e153aa16,b3a52eb3,1012ca8e,ae20efdf,41c77128,93fce97,fc66b187,caec55db,7aaa81ef,cc12838f), +S(f07866f0,cca3474c,40e7fa59,26df41c0,e46fbfce,faab92e8,9ccd1170,3ccf79bf,37ed66d5,5e891f4,e644fa04,182f34b6,1f1aedbc,d2a71aac,dd1523bf,f579dace), +S(853f72d1,edc4d953,348528b8,3656894d,67032333,28a16801,64a84511,15c5e968,197737d0,de83e73b,247d861,510ac76c,3ca214d8,ebbb958a,74ce1c31,5e715e87), +S(7c7eae74,dce7ef76,9ef0ce86,cf6ac861,ffc3d4a9,6313f379,fb2c0325,daa91aba,131e1689,fb017e15,e869d858,2dcfc4f9,153d1e8d,246fd613,b3922302,5b5c3767), +S(56028652,bce9dc6c,c8b4ad5c,f9f222c3,412e5bb7,8d556225,2c06c2e4,25a6e31a,2aa8e093,d8653f6,2153972c,e54806ba,666d49ba,3787934a,a37bd65e,79374ac0), +S(2eb98b01,550a00dc,59d280b0,71e472b5,a65eea89,298fe4b0,9f6f0e07,9315ad7b,74e22fc5,3daecdee,6a0b50be,e17f1d7d,d9481e77,28778957,274c8d29,a0d89fdc), +S(7268b61b,f65d73aa,37766a99,9960d998,18aa4ef2,ae8a97b1,db8476fb,32f891a4,824e99db,3157b706,38573513,618f6901,ce1fcff8,f25019d7,c5c45bb2,f3bb4d47), +S(cdea8771,4a764e3f,a94e7356,879b7d9e,da7c5b6f,28c172a6,1c0ab012,9b9ddd7b,daf49b12,34ce20aa,263b4349,f9f88cc5,1334db26,59b7c587,212f407f,cbb2644b), +S(38831af3,193c8860,690a9d74,cc0079c0,9e3ae0fa,ebe0da02,67ad6e23,99059d19,be188500,5193f11f,e34e70a7,e470cedc,902bee92,e7041403,c2f1ae53,7a8bb077), +S(df3acf55,bc6d97ce,34ebeb46,34fe1010,ed3d6d6,383c11a7,53a93123,e9c8381f,94c22735,ae6f858a,59f663e2,12532e14,4efe6a81,981c7619,e5002968,dcb81df5), +S(a8b08b86,4946ac6d,a101eb85,ee7bdf55,24282ca1,a9956e4a,eeb1afe9,87a43ddc,80ff0174,375c95fe,cea6e00,20f17123,5cda4bba,d4ef893c,78ffe37c,205d5577), +S(fd9941ce,e1c26864,248f7035,352787d1,aba9e93e,f5edd333,d08c89b8,4bb9dc8f,85be138a,42bf190b,921681fa,8777a619,878d4d02,11016c72,8bc151ab,1a687b5a), +S(7e2cd40e,f8c94077,f44b1d15,48425e3d,7e125be6,46707bad,2818b0ed,a7dc0151,6fa48af7,d523054c,7d59e574,cde106a2,776411bf,5111f7d3,65c43ac5,df8ddd68)}, +{S(282c5bc7,5b9c3f76,73e244af,29f22b80,c171bcac,d7e39b4f,ac7ba6cc,656d9010,e8db2eb0,a56699f1,73d5b5f7,99d39e14,dde34648,f159ad0d,c1c7767a,19ae72aa), +S(d5a3eb7,cad9c548,839ceb7f,67145e0e,96c60d8d,68415f76,73b73700,5ce3a8b,34ae4e12,355d1df1,25149efb,1a9050fd,490e251c,4404fb37,31b6dcc9,e233b9f1), +S(68718b29,86197989,3c5f7b1b,48abc254,13bd23c8,96c8828,7000ebe6,6db742a2,bef9d2a1,bb596fdb,3caeef3b,4d950568,8a94b436,4fd85f37,30b20de,b9e9a4fe), +S(a5ed1709,7932011f,9a597511,a526e61d,f22d0bd8,ae3e15ce,655820e6,b1ff1238,dd6dc7d0,81e70b57,4f235c10,c7c3dbed,a57743c1,15e6fe01,a20ac751,34cdace), +S(ec37904d,9662a487,1a471d9f,778bdef3,430df9e2,26fc42e4,7fc4bf5f,80e3a9c4,8413f2f,1ed55d8b,8448e336,ac9d1418,c48846e2,acb43509,f1a3d935,8cd18ed6), +S(b09f9c76,1cbbb685,f695328,61c459a4,d2b16989,3cbbad2f,dd49c87,1d860db4,dbbf9049,31b18454,21c41f2d,2185e3d6,c8f55dad,f1514ab0,655c856e,3391278e), +S(ed1a335,48864e9d,b41abcad,3344f4e7,ebe57841,9371095a,6b95fe4e,ae59edd7,d1146be9,83adc77d,bd9c107f,3092a9c2,9c271248,d78ce913,7831127c,c403f44c), +S(d39507d2,6ba377f5,c7116aca,78df331d,a795cdfb,54e5c912,8558c0e,997b74f3,fa7971d4,32cb5a44,589dc705,de28ad0,382206f1,6e11229f,86ff82a,efef3131), +S(641dc311,baa77b14,35f408e1,528445df,53c5ac5c,32803a3d,84e8fb66,60d71d,2b355a47,76980bfc,8a4e0ac6,a3bd7b02,a6b20ffb,f8650b16,89010456,6953e49c), +S(c3dd73bc,cfb744bc,57bc95f9,3c260df7,7f3b7e74,9e4a5237,f3865f8f,f0c89489,15d58dfb,83654754,80e53bb2,a1ba430a,ce213c38,ea71c7b7,51b4143a,fe2bd124), +S(3f883fa2,e834df1a,6e9b5c46,b663880e,9a0b42f1,891b92c,eb30600d,5641813e,7acff194,a5fb76e5,bd3d8fd4,2c7f07a8,3a991ba6,7f0e4edd,c55e1d8d,3025d590), +S(70c8d4f5,21d808e7,221bd5c6,31f171a9,5e7aa358,4477068c,2549c59e,228688bf,52badf20,6106d5a8,d7bff921,580eb5f5,3a53aeff,e0369f9a,1bcb282d,7b4cc26c), +S(ae08db34,874d39ff,bfb9c92c,5e4253ca,7ed508fd,d12841e9,63600461,b2b3a0e1,dc0504ef,d209be71,381eefd2,91508120,fb6ec1e,df62d24a,cb1d77a9,4eebf1be), +S(627027ad,4aa88477,c6240517,87a25b88,7d5b98f,b968221e,8e45d584,3db6e0bc,34b553a7,c6ac7004,69367afd,17c5eaf8,7605ca18,6a57667b,650fd8c7,18ab76aa), +S(573ef2ae,72ae8fd5,eeb0b720,f8967b44,f7d9d96d,c8a4825c,23a3dbed,fd2bb442,264f508e,efe5e0a2,55e55a54,bbf739b5,757d0a15,994ea9b8,4e139738,7c484786), +S(28907848,cf84eec6,773a384,ce5f4a5a,24c8afc8,606488a2,ccdeff25,6f896dab,ea87d4f,41df8727,2fe84537,d11126d5,62618bee,a51008ca,895a8375,4f05ec5e), +S(163db4c4,536114f0,75521627,c61f62d9,14214d64,ac9e66b0,d85b9991,62c54c5b,7ffc24e1,11c0c845,1c574e9b,e4b56610,696d3667,a6e6abbe,9d1a5ea9,4122aa1f), +S(2ec11f2b,71ffc28c,fb5e779e,7739098e,c969bc78,3cca5a22,77d2bf53,e6574d1c,c5e9fdf2,89a3090d,e24d13a1,bc8377d9,de0bcf4,63482ebd,9620cbdf,8b238fb0), +S(30549ae0,9a46820f,f49423b8,9c6fdd48,703132fd,ac166dc9,90609a32,49039f0a,b8c94b4b,36d39247,732976e,fc16d500,ccdc07f0,d7b97db5,7a1d9fbf,d8cb5d2), +S(98685f94,a043399c,89e74674,240322ac,5a595bf5,41aaa44e,d781781a,10fe9225,4506b1ef,7561b811,53f44e8f,325f9222,e999013,30523885,d8c59864,db13a3ef), +S(9acba196,3014ea9,1baba28c,e273c6e5,b9a2e1a0,98216c3b,194a0b56,dbda7db6,f0a3358e,eec737af,2e313262,b29ddf6,2adb9e97,9f56def2,65102272,6b976290), +S(e81e91a1,7aeec75c,19df0ef7,fd07ce2b,e477c031,179e3f99,4ca13857,e2b5ff93,65236424,aaa8b6cb,fdb2fb20,46ae3c3d,839d97ed,217edc6c,c774f889,d2ce8b45), +S(61e60aeb,821c3f80,b53ca78,2c3b4d21,960eb0d2,c90202f0,a5fba651,1725ddba,b029275f,690d10bc,b52e8bb2,acceb071,f07834fe,64175088,a97e26f9,8ff34432), +S(a931c410,8fcb4346,6802dd4a,8ec2cf62,cf4c5558,8129299c,b3a87e95,6fba2a34,c21a8dd1,43d4a639,339fec49,f56d717c,658a55af,ad72da1,c754fb9a,117cf6e7), +S(fb5c106f,da32fcfe,ffe9b5a2,7ac8cfd8,d9a73da1,5fa6340f,e09d187a,7a83cb88,a3f4c60f,90003375,11c39100,ba4c4721,c6c138c1,cbae09dc,46d1a1d2,5baa95fb), +S(dc25e18a,18f0035c,2a05e80d,d6b38830,7fb3b176,a66ae451,8c5640db,7540dd24,3ba83beb,3e6b29c2,97a0ead6,148f9b93,711556e2,e5fd513e,ee649228,c62d8f3c), +S(ecf7b689,ca03b840,739283e9,c3003a01,65ea3f,3bd17e06,9260c0e9,ad403273,5e0dbad6,47997fca,c0d7ba2a,170a7954,67036ae8,e61dc532,b5fe184a,deb8a7ea), +S(263e593b,10c982d5,1bf89ec9,71f6a3f4,60e53bf4,cb2f6af3,2381214b,2e981bbc,e255bc11,11470eb8,894ead67,c618d7ca,a6b76ae1,a230ef05,3830d028,4a7faf37), +S(f79781e7,a4137ac4,7a9a9d00,9d239b37,6cd0fa3c,b9f5de46,8cba5a11,ffcdd69,d10ba78,896e086d,5e25444,165e79d9,7b3d485,1a448e03,26d8906b,2f27745b), +S(a4d28024,11f577c1,c5d08fbc,457a46bd,428f4d2a,b29475ea,ef622876,593e49f0,e4855491,ac0342b1,dc804bc2,7ae23877,82eeaf22,52874a00,4d4e0d66,b07b434f), +S(87195a80,dc83be4e,cfc9d4b8,29725cbe,11101c26,13c98f2,641753af,1ee840f8,f9fce233,66931c51,4ea09224,b565dec7,22763d8f,6f572057,fdd7d96e,9811289a), +S(210a917a,d9df2779,6746ff30,1ad9ccc8,78f61a5f,1ff4082b,5364dacd,57b4a278,98f1e4ab,af4a1a84,85c6417e,7298c82,c87619e5,500df403,80d8ec01,f384d9fe)}, +{S(6c16768c,433a000b,adc47b10,ba4e132c,f5480e65,ae83d1a6,8aec34d2,c00c76dd,ca1a47dd,66c2d74a,ddb69283,2ea289a6,ae679669,edd80bdd,4ffdab2a,defbb542), +S(f757e860,ed04db61,594bd647,5ae81b7e,d6d2fa58,80cad10a,7756fa26,810b8543,f2aad599,4e491e02,9b1ae256,2c90912a,1c9aa6cd,dfc2331d,a0069a79,861208a), +S(d9f269d2,9aa777c6,9989d706,91403dfd,9025b491,ba03ddf2,dab8c9,af7dc764,1b39b85c,cb4749fb,7f47086a,ce63924f,3ebb4213,af5dfc95,fda796e6,c6b0b8b0), +S(d05e14f6,fe6ca50,a23e9339,e449f771,98e842d4,80a72d5f,8f5e4c06,43547cb9,869e3bea,6b19e0f2,de83fa8a,e932086d,d66e838b,637ea603,5f0fa081,5912c8f1), +S(9f723d81,1818046f,b7512abb,faeb46d3,52d8da9b,3abe819f,3861f9c9,963c583b,37df0657,3f2bb428,6c8b3efe,f6941e2c,4e48d90b,931cd0a5,78a4b52c,6581ee7a), +S(e65f0b42,54ad9df9,681c0db,3428ccaa,11194df3,9e837aab,4564e1fa,254e6f97,43e59d10,54aa35b5,80373e08,cfc02aaa,4f581406,58341e67,7e50977e,5bd893dc), +S(605d61db,589fd91,78a65cb5,99697001,73afca81,23f663ac,5fffd0b9,8f5e7a64,a976a9d,a47745f,447ad4dd,7eb63875,c228b979,a7dda50a,d994df7b,545d0ede), +S(43298aaa,faf20e9d,c2240256,493ef19f,5630db6b,f6376e4a,356bd034,98f1be7e,737551c3,653af1cb,4f8c1e8a,347f50ca,142c03e0,29007f29,c76bb763,b52ed053), +S(8afba782,d6373f0c,54734f1b,4b854e63,bf2a3b4f,23f57a3e,6c2eae86,25c691c6,da3054aa,228b9757,b7321da0,64516249,652fd814,15017584,2c7683ce,1a3638a2), +S(3156d359,e01d64fa,9c8fd8b2,c47c3492,82dd459a,fe89d94f,35906da2,c6d0208,85a23f48,f0a7448f,c57ee545,3978e2cb,6f2bbe54,864477d8,a63775f7,7ff7289f), +S(88e1a44b,1e206eab,49fe97af,30be5e47,25e1011f,312a5222,e9e80819,b3f26357,63dfe52e,10317c4e,227b2a5a,d61b713e,2d93aba7,f0a51e0,b5621191,40c58ded), +S(d10de96b,f2e4a6f8,78e0f37e,15569f3c,b9717a38,7fb98928,6d65d171,4b81b301,2c0a46c9,6a2e3884,e7f3b146,acc170d2,6d12b959,4b75a901,dd535016,f0355ae2), +S(eb36b865,812ae4bd,7893e50,5aef6f14,bfc90c1b,42e75ea5,91615aa,a2101784,1523537b,790b2a61,fb6696d0,a622ff31,efea1255,e1dceb86,763985e2,6c5ca8df), +S(d54be697,e41396c6,3d63f96f,bde9bba2,36ab1649,3c156159,3df81d69,c906fe60,89de1769,433b5678,1f7a2206,ca98258,20d0c7dd,a6d5b672,f77029c2,6bb59f33), +S(d5aa72fc,9063c2f8,bd0fec97,da30dcd2,a5b36aee,7894463a,f7042795,1998c979,ed90095d,bf2d3a67,2d2f1a0f,9737c4d,e8f3e773,c04b77d3,a2345dda,ab662199), +S(ee8cd53e,8ab64281,b5cad323,f03fd06d,7aa166eb,df9185b4,8d0eb0e6,1bd0bc61,4781263d,fc518e4,809e5ea7,7f9df238,1ee7b6ee,ab25c1d9,5cbf3fce,72fdd615), +S(ddc5e95e,2a46736d,9bbeee74,74364bf9,e1d2724f,c43522c,cffa05a8,7d078be9,60908fb,809ae964,98a26cd9,67532df2,409491aa,73c46803,eb58861,7ad86745), +S(ae503a2b,b6250ff6,6ee615d8,41cae4e,751160fe,aef7f33b,dd1feaad,ab236b58,6e53d2a8,8f09f78f,96d49a6,2f98773b,a282b575,ab6e24f8,4d604c3c,8583a66c), +S(8a502d08,bb3cc1da,438c5780,e2120c50,12c1a972,8aaab6bc,5d908b6e,2a83dbdb,fa02e62b,85d7de78,8cf11d9e,ab406523,bba1f912,53006a89,f3a491cc,dd99575c), +S(b52891bf,5acb0019,a8d10b94,87fa47c4,22f83a00,ef539e91,44bd9f7a,d5075716,ae58653a,b167a9e4,b71eecd7,4f4a8786,19c19026,29c0018d,9f082e7d,5920b2f), +S(176170af,b40a3e79,8a88b98f,fb6c578c,d1ab56b5,b7f4142e,b2d84a59,1b009f97,6e1d5682,36176d58,ce5fcac6,4d4d2885,5db107dd,5215c71f,b4076aaf,d31c5d24), +S(27359f7e,8d3e3dcd,ea35f603,d8fb15c0,bd63c08c,3ae4d2fe,8cb6434a,ae2e716d,a0d64207,8fba00dd,4683d597,27f3c67f,3c25075d,802a4ea8,eb08c20b,47a941f9), +S(1e9d955a,2f68478,5227e866,491990a5,62c802ed,1b106bb5,42d02d29,93542067,fbf5f466,57707b3,3f116a23,fe5991a8,90a9583f,fd063943,37a19aa7,e125ccab), +S(b5c4c10b,1b0e0813,37deef6f,c089d2e1,ee14da2d,cbb48e6,74b7dbd4,429e22eb,fdac245,b109947,8f6a53a2,8a1ec4fe,da43b4a9,2ef49e25,8f9296c2,88c48378), +S(bd2f651c,ff6e614b,1d6535cf,c3a2c5d2,da5307b0,1cbd3f48,655623c2,55503916,3715b0bd,bcf29d97,63d7fb35,f9c5b54c,769a863,3517a2d6,8dde74e4,c4277779), +S(c4c2a8e8,f1e257a8,fcd0b11b,30635c5e,782fedcf,f99b0b95,828e1369,3ee0af73,3a08abb4,777a066b,49ec4c01,aa5b0868,f100a473,e555def1,7c5a9d84,b1fd9ae), +S(4aa77ce,15dd97ff,47c1125a,77bcf0e9,d302b79a,e8a919c6,a875e5ed,eab8c2ec,31a09dc4,89a90240,334836f6,302d7e81,57f19762,a9b5f727,6c276e63,560a9d10), +S(3731162e,66a8d2d8,ff4df3e,95950103,f5a03f9a,86bf37e5,605746,cf4be846,e19d7835,10af5daf,724be4b1,932dfac6,23899ccf,7e3e58ab,5bf3265c,667cbf28), +S(6e2114ed,297ba44f,c3926603,bc03a87c,af3e9f2c,8bd84e64,afcd9846,bd9c8f0a,faa6e5f3,3d90f91d,82592af0,7f3a26e2,f6f4138a,2f06a6a1,4286eb71,2e95cf94), +S(50d775b5,f72d186b,266a14e5,254cb5aa,49fd8633,81c36b09,842632d7,ff004130,cbfe11c4,f0b15aa8,3ae8dbcb,9feff9c0,d68a26ba,11095b3c,ba94739a,2091bbc2), +S(8f3ccf31,f8b74b9b,624a5d1b,7cb1096e,202fe5e7,233777aa,859864d3,775732c0,980e32c1,d2c61ace,7610b926,6831ac27,56f19788,ab7a77da,18c421a0,9a46bad4), +S(24cfc017,6da2b46f,a8bb5bf9,636be1ef,fd7e297f,29122fb3,e84c9ab0,c18ada5f,14007044,f8639e59,67978eb2,a21256d8,126a635e,5b07eb0d,97059ec5,6875a3c4)}, +{S(6efcde8b,e99d9ee8,ee0d6b8f,a76584bd,5deb67b1,415e729b,48f3d41a,f1cc1386,4ddcef4a,a6ad5be2,d1e83449,9eca4a8c,73219f80,464a4a9e,ebb7f3f1,b70c9fd2), +S(24fdd052,a1e535e2,4eb79ffd,f03093f8,5778241a,b845b548,31b9a82,730ee3e,c6ff8ebc,7edfd9df,9b7410a,7f54c93d,ff0c682b,152bf4db,1b79c0a6,9889797d), +S(aaaf86ed,31dbf395,687c959,6c445b6c,dcd1fe7e,ba2aa13d,1bf41867,dc87b30b,582b9683,729be5c,85fa83e,2ba2abac,e3037262,2a24aa35,c7753312,1de2fb93), +S(23930d0d,2400db1d,56525bb4,67172fe5,e930bf86,21124fa4,6c5a421e,10b059ea,5e11f202,beca3d5e,dc9b282c,2e86d5d9,30f8f5d,27a5c4d,d2cd6dde,6d1497ef), +S(76ad10d0,bc92ad8f,55b665a1,8ee84e01,2e92dcc9,37e0c604,59bd6fd4,ded2d9d2,d4ca7386,ce0c4c5,fd37da9b,eb8fb040,97d98891,35a5ecc0,320dfffc,95ed3c10), +S(10b324b,e959f0c8,c8a82142,4a8f87c1,fdeb7f88,258e1021,c9cfaa66,b131f3a4,590e672a,daa8d547,161f635f,153fa12,b3500694,677af3f8,90dd4ca6,9620bb56), +S(afdb2acb,ebfdc11b,3577177c,d8bcde00,65151495,79c6ad2b,f7386275,a9314317,87d7786f,5ba775c0,ea47b141,cd0d4274,c7e58634,b64e4c58,f7f0c595,5a307250), +S(574cddbd,59b34df5,30f5dc4,61884ebd,1c867ed5,6cb60832,4a11b1f5,29ebf733,1bfea852,34256807,1fdb4f5c,485caa73,7136e3c3,b4b8a39a,389d7dc8,724f16fa), +S(97ffea2b,5de34e1d,495ce082,d0097b72,e7daddb8,1cb622c,2c14e814,bb0ae278,45fd3d2a,9d1e6530,61b4a356,65aa9e70,43766950,622e1c25,2baab265,6d4ed95f), +S(de627f6a,a7b56d85,535c398,80d0276b,b910ce4a,6066435b,512e5e0,21ef55ef,753033a6,ef89f053,c0e662c8,1557e6cc,d8b4c8d4,5204f5d,e1c8c742,72b96277), +S(b126c35a,d7993bd0,164867c,58c88421,d2cddb6f,d16a5966,7d9683bb,1b428eb5,a9ed1bb9,e9eacf9e,e712bcda,be629143,ad0e7652,82cbfab8,e586cb07,131e5b1d), +S(847b90cb,8837f488,ef027a05,71b2be6c,620cf86f,ead235ad,e76e3408,d0dd1073,9a2667be,6ce36e7b,d76117a9,fdb8f1b8,7c7cb45e,1a03f53e,7b32bc63,6f274b4e), +S(8ea21457,6f1bc2c8,fbee9065,c2cf5c3e,7a3b9fe5,403fb980,96040c2e,c6fe1488,dd75b454,acef4d3b,1b355a63,f0cd17a6,66aa9e65,f1262629,f0c7d1e0,33571b58), +S(9e11bb60,ba4b2d5d,fe53bb9c,598edb16,f3926bea,1cc90eb4,3e05ca34,e83f1896,263d7ea,50d83b8,791fc911,a4f73cac,4d42a09a,85f5ae68,86cb268a,fd562dd0), +S(f741856e,f353a7c7,17db9a13,4ab4aaf9,13c1f7da,cef08bfd,6f81dce5,b1130e20,ee63dd2f,48e15f68,d1acbf49,705fe010,231e26b5,14146c47,1a689960,d568eca4), +S(671ef05a,410b41d9,3b092b04,e523468d,44837d2d,26dba670,27400715,eeefa2b5,686d318b,b49eccbf,40dc18af,f1938fa9,b16d4d2c,c19dd2ac,47c7830f,89b8d55c), +S(59ea10a1,e5bffd6,a34593f4,b986e37b,5294ddbc,60d92906,52c6e9d5,75f88c55,c0a2eb5,6d04ab99,abb5b76f,7b2b55c9,c09d44f3,3785e3d4,64554c3e,dc7a334c), +S(37f2c7c5,69c6fd15,9b721d8b,8d40138e,a8873b6b,452af0a7,89a50551,e9703c1e,d114109f,f9e6d7c0,c51a542f,b2e3ef5b,74654bef,5eb84aef,c87f5096,2a30c078), +S(1d280637,9d77e509,126a440e,b1e56f1a,8723728e,97c92420,5ed13081,98c868b9,85003989,93a4a600,dfd0f092,b13a1186,c1c52dd8,8fc8eace,9bd4f1c1,b47741d8), +S(39aed6e6,a123061c,228d3d1f,857e0c9b,29b70cdc,549b4ea1,9fb6802a,8d8beacf,6bf86967,98e3dbf6,75865a1a,b86d5bbb,10f16e8,4f9104a0,87602c,e6946aec), +S(aa770804,4a996b1d,5bda074c,941b30c1,d1474da6,47d7c4ed,248d3a9f,c3c3c525,10ba5652,b20482f,fc2434ce,ac185d8d,af6cc6e3,61e77d3f,258abc0b,55610879), +S(7626a96,9f9ef188,3ea82737,83e5571e,4054fb73,6190977a,299c2a05,d29f60c7,172d4618,e5f88055,ebfcdf9f,55267ee5,cdf18396,1d5a2a22,55b87ba3,c7d7d2b9), +S(1a550684,d1195da7,c4b09349,f149eae2,5a1ef23,c9a81109,115d93e4,c98cdbda,c31d7dc1,b7efd019,c491010e,30f90ed8,7503c4bb,1b37fbce,3dae199,6609e3b1), +S(8d2306d2,dd8c753f,2b093e62,86fc282,ba3e1dbd,7b4ba101,83d1070e,d2d06e67,97dd14c2,d2c1d147,486a3dfc,d608ba28,d63fc03,251a106c,9811b088,978e3a5e), +S(f31a69ab,97039589,940851f3,cdc98bc5,d400ff93,63794f81,4d88215,4f00db99,56e510be,7f41b009,89792401,13641590,40f5f305,f27fe1e2,db1cd7ae,887ff5e2), +S(ce96b3e9,6eb94b7c,8bdc7b57,efd2186f,62e23e72,f11337ab,be7405d3,43b4d762,cc0dc898,33e7a632,d0fed52d,487f2c60,96c69664,f698a71c,3f7f8a29,4f181add), +S(bed97e25,7d31b5fd,36b41227,462d9122,706da670,d432ceff,5d37d83e,fefda56c,c0cfe30a,2c3b3074,1af492b6,e3797c4f,3b00593c,6806e2e2,f2cff401,6e877ff6), +S(923bc6c9,960f6e4d,ca2a7070,6d160e19,83a16b6c,8535783f,12c5ac69,4aad226a,c47f08b,6b2056d2,8e9f119,9ec6d5ce,b48801b8,7ee56280,d6a48352,b2b42b1), +S(b3cb28fb,7465cdda,85823dcf,819400b,357bce11,23d9229a,eddb8262,53b246c3,cf035ed0,b624dd68,8a31eb5f,3b28e83e,c0bf9453,649dfe4f,44078eac,9345f2a6), +S(c69aa2b9,ab3c5e45,8713a912,e7f95bb,4e5498a6,d4090323,5cfed1c9,c2a60709,2e95e198,85637d55,744e32a7,98c02c7e,b29f3bf5,7cf7c870,7cafdf41,f6710f0c), +S(45996af,5795ea6e,43e0fd29,671e119b,8b8d6ad2,4eac90ec,d27d5db1,b4fb6a39,2c0651f3,1c7d93cc,98d79d7d,f21110fc,8c1dd74b,f1ffefac,a3d52484,f8da40cd), +S(264559d8,7829256b,ed116900,d82d0c37,9f0e4d12,53c68e6f,cf2d41ae,7cddab8b,861a42e6,d92caed3,108439c8,fcbf8d28,8579ce50,c6350e19,3609b4b9,ffe217bc)}, +{S(ac13e0db,846df259,fc38d6,3b0248ec,9fcfa8d4,bcee368b,1f4a66c6,d41f9163,6721b0df,2ed06fda,9b485cc2,aa56f1f3,3a913e99,f6809577,95280451,9ddc96ec), +S(b6b7227f,228da269,a0e5640b,8a2cfa34,555ccdec,2243dd0d,4b2da0a9,b4cb5e4,6afe41f9,dc129d28,4786bb76,17786c8d,42597435,240f998a,f970620,90d32059), +S(460672e4,4f2768b9,842a98a5,ca8b90df,7d9f52bc,3fa2665c,4272d7ad,5f48b992,6d7f8b36,13b38fa5,80ed1d4a,21d196bf,be491b46,49c96da8,342441d3,f4af4ca2), +S(1d3d4ab8,b7c06136,8dfd612a,25f04016,2bd3f6cd,cd9cf58d,c11647a0,d28b629f,434dca08,17bbf964,eb0a316c,b2b0df20,eb2e965d,c4d8d795,1d4a6e66,5ed23d38), +S(9c5d6342,303bc7c,73763cb9,2e3d7069,7d913f6c,1a6e2f47,39470da3,22b7c1b,825c1a54,395b9b41,ccc2e3b5,3fe1092,f04c382f,b2ee3a29,fd59e255,5f22fc15), +S(5c751285,a4b55535,fe24fe27,568868f3,afb43cf,aad1d2b1,c6367daa,ac9493b2,e2388ab4,414c4e4f,e34a4c78,c869dd93,7094ce2d,4f4666a8,2eef8047,3b681fb6), +S(8c1592f3,8d73e277,d3c18d4,ee3eabce,32e86f92,2b27c2f0,1f50509e,74dbc211,399c9507,43cd9e7b,200c255b,bd25670e,cc111462,2d5dfacf,9dbebdb,53ee59ab), +S(85320e36,5f40235e,621171d5,c8008845,890f521b,d7e2cccb,88c7fb7f,a08200c,96bbe8ec,74b5f1b1,2a6ecbee,2aea6f0c,b6d0657,aac3556c,ddc4e46f,17cd31f1), +S(5fc21f20,13403705,687b8ad3,387a725a,f2e6300e,13d28403,569d4cb6,5dda7f34,bb709fbf,be95aeef,c00846b6,a4645b72,dbb4e1ed,866edb57,7bc5d9a8,2b774b0b), +S(fa40e658,588f8a5e,29d380e9,c1a6482c,888f53e5,e331f8ed,9b1273a,56d094e5,5486cff5,3b7baaaa,de8a51a6,1d1a9255,95ecbea3,39955c0e,172de4c3,4762eca1), +S(9f87d04c,5fcc48f,375c40af,3197c28f,c62cf3c5,10fcdbde,5aec79a7,4e6a6bc0,9a6cc172,23a770c7,a03b5333,6922170d,e9409f3b,9846b9f4,41832ae1,f70f5c57), +S(bb66dd5b,2f88786e,736b50,e536a0f0,3d59b86,511e95ca,1bab2cb8,875bb187,f8215527,c76a5af,e5e76a33,eb2622d,5f822ad1,d284c68b,c840f65d,4f731c63), +S(74d223e4,bce2d6b9,b2fa9482,46327e04,18eda6c,cfdd76c7,cda8be62,3f6dd3a9,b7276bb3,817c0e72,e1ab002d,50531065,e1c4ca30,9c6d6f18,bb5796ee,457b4270), +S(80298b62,eb4d3ff2,e10607dd,dbcacda4,3bb30e57,f3c8c7e7,6f9f3968,bf391316,fc72362b,48c8b606,4e428e6d,1ef2ac87,931caf75,e936a33c,228a5caa,c460c5f0), +S(8519f27d,9560acdc,509fddee,9b4a4a7a,8b13496f,14760a08,22609f3b,2ae07963,193aa9db,b98293f8,e70d7253,51d3893,a9f5fc73,6f3c8e65,28a2dfd6,5dedc220), +S(49d734f9,c8eff915,fd66757b,d6484bc9,548f20a,d8c05959,f651eb36,e45cb88,4c594f79,7651b49e,929932a4,59e3bf21,3e74c0b8,acb20907,697a25a7,ed21057b), +S(6a528c6d,19b1e28d,b4d9ec9e,19c4f7be,184ef845,1f41b322,e5932f05,575bcc4a,7350b90b,c22ab41f,40c13a80,18749e8c,275d3e5e,5d687df0,ddd47133,c092eadc), +S(6f3df40f,5647143f,cb93b23,4795d9a7,708db6b8,2e2df53c,f214de4b,61eebaa9,dee10664,54b625ba,34ce4b54,f7285714,7874b5d0,6b38b1dc,37b7471f,9208dcbe), +S(5abfd7eb,c4c5dc14,cbf0e335,f2e87e7a,7db96a2c,b78000aa,64fa8aca,517ee1e5,d65a98d4,20d872e4,4c43997,55cca5c0,bb94ccc0,b25e30fe,8b5a4fcc,7006364f), +S(1bf3714b,da04d769,782e37cb,c4a4b347,f9fc769d,a18e4940,d19a205a,bdd22a23,d0852b21,33b04274,183f4de4,9a20769e,4a08ea16,ca8782bd,84a4da7c,64c928a2), +S(773ab884,a4e90454,ea467caf,f18c3b64,e316468c,b5789fa6,4958f73e,ec3204f1,62213b85,b4838d8a,fa3a14f9,32db7d79,dec538c7,d872d9d2,be1640a2,4e367caa), +S(33a283d9,9b7564ed,6ed10d88,ba26ba,fbf3a375,e00e10d1,577fce27,2c204324,bf84dac3,40736625,cf0e6be6,98072c6c,5fb8bf9d,2850be84,ded3f652,569370d2), +S(62bdb467,596ffefa,22b735fd,d3dfd959,d4a6e187,a19d4c1f,4d647b4e,db380c3b,210a8e93,d1a184d0,a3548be7,6283d180,8e4f32d9,52834c,515953f0,4ecf9acf), +S(ef16d3a3,233f03da,5864801a,c246756b,d1356137,971bc164,b5512067,b369dad2,480e3d32,7f1df8b0,646c3b58,a51126a3,e91522de,ab77d6d2,f2bedadf,1219b877), +S(a6834869,c006d044,a9dcfb9,8a5a14df,86469fd1,fd0cba06,a4e8ec1e,1fba89d6,c1a3e0ff,7abeb1e,8cac11a6,8c1b4c1c,f663e615,9f508c35,f4747f50,84b247e9), +S(203d13c6,53a3c36e,55a836de,b38c7443,681d7b7,c681d71a,38fb0fde,986ce9c3,5d7dba97,573ffd85,b3fd4417,f09192e1,92461c4c,125a9947,ced9c737,ecac65b2), +S(c48819,b8f32966,bd50f162,30f5c0a1,45cb3570,d9c4b104,4c306696,2f4d6667,feb08ff9,1f543c1,35b6e0f0,b21d7624,91ac096a,181bf093,fcf8f4b7,bf6559a2), +S(31441031,ceabfbf8,59bcdd8b,6e177f91,df7bfe08,f9015172,1ead3acd,ab64acff,e36315bf,6f087118,32894704,8d2fd259,6b8beae2,e1917341,d690a1f,786db5f9), +S(e3e4750a,310c48,38920654,b6afa032,79589d52,74e48139,6e22d9cd,3c05fbdd,f05868fe,5452da6f,fadcafb6,69e5edfb,4b9a7840,3a305004,345ddce1,eaca43ac), +S(3659ba70,60d8200c,9512facb,5c730111,4cdc2b9b,aa5bde14,8ad9bf9d,d8f8fb8c,b1185617,f91fe5e8,ec68da07,138b6780,e1ebd12b,1bb44eca,8a1b9472,8337585e), +S(1a46b7e9,fe99a4ea,492fbc90,3281b924,6831fe59,9360af53,bde4ce8b,43ed5996,97c317e1,5c0e23a8,f1c11f7b,5f9c140a,af786b56,10ad8ba3,d11b12ed,17379f81), +S(f16a409c,677a40be,402f8efb,3752373c,aced053c,6f702b82,8bda222c,a412b6fd,d5becee8,ebacd866,285958a5,8b1cf1b1,e9abf9a6,db61435b,d9725187,135fa955)}, +{S(32c932eb,6fa35974,90a408a6,ce962d7a,ef2bd22,72cdaa,cb80f798,9836abc3,3e145848,c2f8197e,f0264d7c,370d1784,7d21a09c,77fd9f7a,73245ce7,2ce5f3f6), +S(49d837bb,63890b4e,8a4a63ea,6d88599a,c9961c20,80dcc955,aca6a101,bc935f16,358a7f6d,b540ac03,78d83bc,304cabf1,84c7580c,46c258ec,58f22254,e3e03aa), +S(23516ddd,40dab9d8,63dcad6c,cd325503,b783379,d870ace0,9a0b238c,d7b6b2bf,b1fb8268,a7814efc,54f3d637,88956b67,a3997a31,10a738a4,94786d95,a5fa1c59), +S(6b4e215e,df56e6ce,6378fa98,5d604f68,e3561275,788283d6,c40cb249,6d16310e,cdf9537e,e6f4304,dbcb9df,f8b97a71,a12f014e,29867e5,6b09b388,78c9ce8d), +S(f4f30433,c933dddb,949ad868,cc0d52e5,247149a,7ec98f12,3e7f63b4,acf6b7b9,949123eb,9fb848fc,d7b94401,a64b21a3,53fde44c,d93dae3e,b7a2d3d4,78055af2), +S(dc3523f4,cd24be1b,30787dd7,5140fff,b66e4487,55e9a3c9,6124fe59,c07faa28,47b945d7,6d37b855,8ede59fe,e297a8e7,81d3ea96,f0a81588,b68db767,9b9641f5), +S(b92cace4,e31dc724,3b3530b1,f90de1c3,47cc39e5,5b247455,a1296912,4e3c2a09,78f89163,c735cb13,b1d8fe7e,547027f,68d8f864,a1f093b,22c0d9cb,95fe28c2), +S(8f7ed1f1,77238a68,bbe32e4d,ae6d67fd,be07c9a2,9fc6b940,6ef81a77,65a8fb75,98e627d8,d32095bd,5913daa5,920c5c60,334691be,537b08d6,da5b8c19,7bf81c8f), +S(47fa27ac,e035176f,34c59581,8d3dca2c,a2b40e53,29756c55,7cf81f75,4f99316a,ddee5921,f381ce26,3634a34d,1b4f9513,4d9f0e50,5e96bb79,b87d98b5,282aee7c), +S(7584cb68,60ae81f2,e0df701c,97d7aa29,8132cb96,fee4ad59,15424bec,2e280dcd,4b76458b,e3926b5b,bf59ad77,da4a96c9,1f9147bd,88a234c0,74b0e09c,a6993228), +S(2cd4c11e,70d432ff,38550aca,481667f4,d09ad11f,9aed62d4,968492d7,5de28dae,82514708,3e5bf46,341177e8,9ad2cfb3,a215578c,52f9436,d3952432,e9acd430), +S(2b524c99,2b18a6e0,30863716,362d236d,e385a10c,3679eec,2774edb7,a1a89be9,1abb3b28,3477769a,5c7b4580,93efb22e,f2e61296,da90d4d3,1d6b2ff9,1766f89d), +S(d642c258,9d0e47ef,f5b2b60d,9321db58,727315ad,522daf58,3bdf35d3,336f1081,1019505a,994030be,484e5340,abea0b7a,51276c99,29cd1f1b,9d19798d,aaacf3d9), +S(3e5e09b,451bcf5d,549f1d66,b96da0ea,25e63270,dae59606,bfc3165b,f89f29fd,2ce591f5,32d57be6,4fc48aa4,ba40231d,9c104615,b76ed6bf,11957694,16d2f0e9), +S(4756965b,82fc23bf,64041d23,a23cba32,cb71d3e7,ef3e6c03,51b20f3f,dec049b6,75f3a293,eae07f4,362c47e9,44a78561,323244ac,bcecef0c,6ba2f5fe,d1933679), +S(f296e9c1,41694ce2,c197ba85,bb9f172,54fc0bc7,f89347,a0e92b8,58491a39,73c7fbdd,91c88ce2,bbcadaae,df8880f6,aff07e8d,3a1ce05,a468e3c2,3008d98d), +S(b437d387,ddae39cf,e26edc85,b0e600bc,2a199b6d,b521f9c9,88d921dd,7e6fc761,ce2111f4,d937905e,2af7f2dc,559f9eb8,bef286dd,909a5965,53c7f61c,f51aed18), +S(bacd4a38,f3e1b7b1,b601fa5a,2a579e87,459fd189,a607314,5a0dcfb6,1ad3c21b,8be8d6b3,9553648f,2a94754f,4c6c14,c4917296,aa9987f0,deeb7e66,d81c3777), +S(d8164748,8ac6bca,945fce70,e8f6a256,90512c8c,dd4c8fbf,b553c131,96f7f607,16b75474,65a80a67,86b5246f,e086d32c,4db03b83,58271938,41877c38,2b5bebed), +S(9c2b0749,cef57b4e,36b31328,e01503dd,ddbd2834,5cd86ca2,5224b967,1b7897d5,f020f978,4eed44cf,cc4aa33f,b2eb4b71,f24b5f3a,a8dc1d72,569bdefb,5f6276fc), +S(ea277814,9f0ab428,63b05bb1,c113ea7b,91afb815,e8f0791,12c11573,eb044e4d,8199dc4f,4e72b691,1c562ded,1220aec3,ab967029,139d30ac,58c753d2,f4548030), +S(4be6fcf8,40673659,5a9e4f2e,877ad7bf,28e25177,63d74238,6e43e6da,1c1c43fd,eb5456f3,d1c40592,2eec37ab,3e0d08da,b7cd257d,9babab02,44e5b2d6,a827a7cb), +S(3f1e9ab5,160733e2,9e7aeb6a,378d169f,9be5c266,a6462e2d,e736be07,f88c1da1,907fa0b9,814da057,9bb11309,aab51902,a0699aad,9422e1f,b8f1a8c4,aa9d4399), +S(eb730dbb,1ba9b2f,50453837,35ec6da2,ac4b5019,86cf03f0,3f5061e2,a28285f9,41dc3a0f,f42fb1b5,d3b464a5,6e305fe5,c60c4561,d6e5a6a7,8cba87ce,15c392fa), +S(aeac891d,f7032059,54d0bab7,41927702,1a595a4c,37bfc34c,5d315876,3e85f3ce,168f8260,1331b5c5,edf941d9,9f1cfe0b,72fd2a1c,3e4bbc2c,c62d47e6,6399105d), +S(667e04e6,daca6315,4888ac26,a268876a,f4b754fb,87687ca7,3c4cff77,d6dac204,1826a26a,cdca828,8e2ac81b,855a4d40,86f3009b,162fba82,83cb1d17,b9f7aa4c), +S(240ec754,24e46326,8e2e4ce0,240f335c,78c46150,1e18cedc,b32e3c51,77ade3e5,be09c744,cf6e9c6a,75976c03,530329af,5e11e5ed,3fb13e8c,af40bc5f,95872645), +S(7b83e4b7,70e7a442,3efbb501,c23881c5,2bbde4b9,d5aacc38,7071decf,79690025,d242ed74,441d1ae6,61b97c83,70be2f52,dcbc2831,1e8707e0,1b44c827,420dcd45), +S(63589c41,fa8975f4,c8738f57,579cc0d8,447218c,69da1a34,ee06af0c,215f6c27,c34f2ede,7589760b,80dbae48,94a3c13c,7351bf5c,33a35351,9988ba67,c2a56d48), +S(db092b0f,4638ee45,190473c7,cb60cfec,45c94d96,99aaf289,82d28af,16ba1c66,8a96ecdf,29ad2fd6,3a85a7fc,b73ab6d7,719bbd6b,98d052b3,3a0cd91,ab924f46), +S(11c4dd8d,3eddc0cd,9a832dd2,dc91c8bd,491fdb51,f5da21c5,732dfb7a,362b8df9,ba4c2789,740b53d5,51bc9fbc,776f049b,e848182d,9d13abb7,e7cd860,96911eff), +S(a65a3a01,df3b5ef2,e620d431,49fbe1,4d71457f,19d1ed35,aea39d57,89303fdd,86715f6b,f300a390,470bc272,6f12d389,7979e2fd,b0512c35,252bb571,fd19752c)}, +{S(d8558716,b7033a9b,29afb346,fd71663a,79b6e86,2719bf12,6e532dc3,f581b7d,a790d460,1e5b2630,1ad6ec43,62f79120,d75449d,8a500e2e,6f17c021,8037a405), +S(842c01b3,54353026,c43dedc7,8829ead1,db35b63d,8c4d0d36,8cd7b661,2eb5e11,f173cab1,a37ee0d0,68e097af,17bf859c,13bb4823,255abddb,f0dbeffc,573e06e7), +S(acac5cae,414c3556,38e293fa,e7cda051,18924e9d,abb81bdd,29123768,c7f21443,5d17b909,5b997254,5f56770c,dcb8af40,e37e1a8b,6e01a989,34ec22fb,f7d04537), +S(c8e73810,c024c6eb,d5398bda,3784261e,542279e5,3438d49e,83b2639f,80889aea,7a2183e7,be4f81,b0337993,935657c4,c55d20df,729d2e8d,b25af238,f3d85f4b), +S(f78c5f53,5e7ccb53,555a6f2c,b1de1c5f,da379360,f6a7fc52,eaf86ecb,dbb3bf90,cf2d33f5,eab2ee1d,5a32eea3,18f9927b,cc982fed,cc9add2e,2461ba14,9def0292), +S(4cd40c43,bdb8a042,2babc95d,eb00a405,59519074,5906a8b7,b5ea00da,b7f995f5,a0bd1c74,79125d2f,5baec520,21fb7c62,415817f7,2afb80,b2315dda,40cf4c4b), +S(647c5950,f8a7fe9,e6945b3d,6da91932,b486a4fb,ed903836,9fbc20f9,a849ac08,d331cf32,d72e148,b47af547,6794a33d,55f49ffb,be47db02,7d2de73c,542bbbc5), +S(97664e78,980a49f0,8269ff19,649e86cd,7da88a76,eb1441d8,a5f3fd2a,6ea335d2,b2898268,9a8cd91b,b1b16be8,ee46b4bc,252f7016,f72432c0,431f1264,8d7450a7), +S(523f68b,b39c2ded,81d22a4e,575483ee,d8748c9f,52c06081,391c27d7,7afe3805,5c331672,4464dc47,cc9cfe32,864b6095,ee8bd6a8,42c1af98,b3e33183,a46e2471), +S(cad866de,5cbf4938,989b835d,5aed958,cd7c316b,980b7c76,2109d688,d7ef5b25,3ae79c30,e77d6d4e,fe404b8f,324179c2,f677f434,8a1c4367,2a0fb5eb,b706607a), +S(ba065cef,b47170a,d6796033,d157fd1c,f22052d0,7b7f9992,6cd58e03,316f95a5,26177c08,bc535702,7f5d03a4,9d982637,d74a6b20,696be76e,742243be,b9ecddca), +S(27ca8178,be756f12,22cebe6c,d05310d8,5a6c4f59,eec71613,7777b625,e6d44c97,de547a17,ddee9fc5,1fecee01,45f9cda1,b65f097,5d1b9544,aa2317f5,102537cb), +S(bfab1d94,d04f4909,dee00998,78f77cc7,d9de94a7,96b5b770,5f3c759d,2ae97ec1,6ec39a8d,9e900a79,b8b88098,d1e5d79d,b75ef91,e442cb2f,27ea531a,2db21bb9), +S(b48a4f25,9d82242,59f08a08,29b05ac8,ae6b97b5,56cccb84,20a479f5,df92701e,beef137f,9f9acdc,8d31a780,2290fe79,9d9470a7,3c8a01a,35abcbee,9730d17a), +S(e3f5d307,ed2f2f13,d23ae5b5,9dd567f0,8161996,776d506f,b53e14f2,70a52370,40ecc697,7da3771f,32a66438,cf70ea9e,550194be,1af85a08,c8a4515d,32365803), +S(818b0462,d5a815b1,57216ab2,4d795886,17cc99bb,7a7abd91,655cacb7,ba99335e,c6ad05a6,7d2a391,a15b6600,7716e02c,9fe40db2,f82283ef,c9c0a7d5,ebe854f4), +S(7e3c52ed,23220b73,ba47613a,bf39a9fb,b3a6bb6e,22c972a9,3ef21a61,50cdf830,b3e4a95b,875719b3,bec1b113,9e29670d,4ba8f39a,2fb76700,f69961fc,bd01fa2c), +S(594e4129,9c1a117e,ce8564bf,ba88ce04,297f2e14,7ecda07c,5f12913c,14d9a5cc,60bd54c8,7395fee2,7fedccfb,ca9524a9,b5750b2d,d712621d,e73e0692,46c2e347), +S(3686bf4c,f387e340,6fc314e,f02c637,ee6f5062,ee9bb567,235b00e6,4d516648,915e5904,b106e057,a0db43,151ac9f8,4871e843,126d5285,337dc3b4,52c67165), +S(338dbd1f,42480753,516d3cb2,c535492b,72849870,a7828b48,643dc143,b966ea61,e51f11ec,86104334,9e9dae17,78116032,949c66c5,3c4d441d,3c88cf4,c7ad61c9), +S(56f935ae,f58bb403,7649198d,1a5da704,26fd944e,c5694c18,38c94287,2130215e,a9c48fd0,3b059474,e528016f,9c998e02,cac7c40b,8c859852,b58b9082,b638222b), +S(1faadcd3,da472591,cc723754,82546c81,c4f53c14,d0d8dc5e,ab95a58f,379e6899,5bdcc45f,42d0ba3f,783a0806,a5d08c74,a1b1b9f5,a559248a,8681b153,74e74958), +S(532d8cd8,fdf838c7,70b87ca1,4703a884,116dd928,74acc660,6ddddd61,8eb053e8,67a31325,853db4d,3e5877b1,c76e7e39,468d2d77,37cb8a6d,af4f16b8,17cd8ad8), +S(8a8cbfd6,d45e5740,aa9f0a21,f40e3671,ef897fe,bf2bf753,ee2d2f75,844ab648,d00eed6,efefa26,46c36895,3a54045d,96da4cce,8ffc554b,9bc989ac,2f62acaf), +S(38ae095a,3c705343,38e542ff,6789902b,cc1b0b5,7763cc43,2f50cd9a,d26d0f1f,100de239,87026f09,e483839c,fe9e1f10,11bcfafa,662a9331,95a8e4ec,e4fc804c), +S(82d9e5a8,385de1f4,fa541796,a00533d9,a3aa4656,74583d07,c4b3c344,b6ff8cb6,70bf2bd3,5765165b,a466171e,f26439e8,f790e178,f67ef5,d2e15e98,435b4261), +S(1843988b,42ddec86,dcc6c9ab,36b381ad,a0ca745e,aba36bf0,237e2830,579aaafb,f1bdc95c,d76337e,cb3cfd65,d9c30b7a,e7c7d667,65c9db5a,6130edf5,e240cec4), +S(a32f7415,9c2743c7,2ef192bf,4a68e838,97a86a0a,3997d1ce,fda3c581,b4fbe683,8862903b,db791be1,dbab5031,ca57f161,b6449bcc,db061438,f45e610d,50ff3bef), +S(b09dcc04,d9c30c35,2bd63880,a766da1,f6314287,dc201bbf,9605516,3db2a09,7580cf9b,7e30dbf2,8f72e9c,a5152ff1,956ae42b,3e952b18,512824c4,7f4e5b9c), +S(ca07cbfb,b24ad1a5,edd9a12a,8ac54157,6f3f2ba1,4b878d82,ab7dc996,bd7e2c95,5123ceef,cd20f120,b575dd98,43ef9936,c53cf90c,c481f340,fa166452,72af1c8d), +S(f8058324,c6b9c2e7,e62147e9,a41ad78d,60e3ecf4,17524c05,80832add,f11349e2,6a39f1a5,f577a932,3217e559,f15eeddc,af6b674a,9d921772,a053b960,a4dfd633), +S(2e3c0532,6255d80f,a42fc69,d5c92aa4,cd326a5,3e8535f0,435efb7b,694a09ec,ffe0076e,9a93904a,42251dbf,47d03e54,1fb75ac3,8f8499ae,dacb797d,7738c9b1)}, +{S(7bd8469f,80f009fa,b4960cdc,bbfbd4ad,d8e37bb,a4b2a34e,d5c95d17,7a94c207,f3062154,c3bcc160,b2aee99,aac98446,516a277d,85b37fe9,34be9359,4af905c6), +S(139b7c10,ce844844,f5d0a9db,bd7e1679,17b37e93,9bb6fd2b,4f19643,f22a6af1,32d4e929,27f5951b,ffa4ddde,4b091ec8,531a6f23,f1772c9d,ada292db,2b88c1da), +S(f49cdd14,14b38e5a,2dd34bff,3d01e1cf,ddefb954,2a641edb,df698d83,774ee70,5c10a6d9,200253e4,a932a42d,2e770f18,69d0336f,3c44f480,ce4a3305,83050c31), +S(ee145304,4771c862,745f03b,4776ade3,104ea0cf,eda8710a,5fa108eb,1e946826,b91f14,b6127808,f1175b72,2c09e02c,66eae622,109f4156,261d65ff,506b88bd), +S(c9ebbdda,867f333d,39142483,2e4150a8,c98090ec,d8ba9c09,3673330a,8777d790,c46d72c6,6028477c,e4754960,d40bd10b,b2defc1a,17dbf018,538b71b2,d208372b), +S(707bf0e3,9f2c8c6c,73a5d0d3,3edb32e3,46e73ac5,dbeef6c,60fb5ebe,b95ece24,adc6edbe,151bcb7c,2ed5fab,1cb9b2de,3ba2f3c5,ca762082,902582cd,e9e27f54), +S(4a002722,9fda7d33,320fc533,27b6c9cb,88a09c2d,e95aad01,65f68f45,1c82e2a9,233416cf,1cc1ee38,90816a09,17c5fd0d,da0bb8f5,d33c709f,6f1b07b9,916282e0), +S(8efefe27,b45a4cc0,3088b6e2,2a0baeb0,3e772763,58af3217,f39c7222,1e20b59a,b9f3fcdf,65771acf,cc7b7486,9b10bc3f,b0e8fb2,960cad82,24ea2430,fdad1634), +S(7bd3815d,6779f321,195047a5,b1772b19,ab29a99f,cc082e93,c442e927,b1ddb235,eeeb4bb7,480f3dd0,92e627a,a042533d,a9eb598a,6cd1ed9,2d75aa89,a592ae8f), +S(883f939b,6bc9169a,3860d36,9894c4b5,2863b5d8,d0348c4c,62368a94,737fc3cb,96e37629,c05b7231,8800ad96,8e922f7e,5b8a2c39,62a25210,9b3e4949,4b24934f), +S(4ad8cfb8,e8ba3265,4d32a656,76822176,95c40b92,e97c6d3b,af26449e,149f4b3c,491d3eda,89930ffe,e401b994,54919947,7ef33a8d,6cfdfb9,eb28295a,c5ce94fa), +S(ff15cd1a,4b185632,c6f11ee7,19319bd3,abce5167,65539608,b1ee3a4e,1671369,24df322b,ab157296,40aeb039,c00ab8,91c96833,4142f87a,1e00d105,b08c63a2), +S(3fc8e63e,995fda97,1d09d96d,4c84e18c,3e0f4d6a,9f8bca41,20c7c832,c4e9d49b,e17b239d,8e6f7fe7,3c4e46d,3aef9040,6bd631f2,da1677c8,db698484,85922ae0), +S(d88b3d3,6bfe995e,45812e9f,63e8b6e7,d5a87562,1c4a23b7,ab46f6ad,2f7d1e81,63079694,7c97b00e,311bfdb6,198c2c4e,eda57d09,b17fd74f,7140b40e,d2842d06), +S(da6971d1,4c0e9c37,e5b1379b,9cedd83e,218ba47,95e4af56,7956922,c64750cc,a14a0bd1,ebd0727a,258c1246,3aaff478,fcb490f0,53d08a40,44cedc97,61be43fa), +S(d098ccf,e2fee442,74377e1c,57d0b924,45f0954f,7af643d8,b7ed5d9e,956fba23,85c99754,17df24ef,2786621b,c0be5069,a9c59da1,61e14759,ee26b524,e9587d18), +S(633f9b18,9dd98f3d,8c4de,528f7170,1c9d5972,cabe3219,cc4e5f0e,e7e094e0,3d69c877,28c859e5,d9e8ea27,3c04ec98,ca084df5,d7c9cb34,9fa537ad,f7da0b5e), +S(2e14be9,af0dda46,8d59df19,9ac9edb0,c875f829,5715cdda,5ba3bed5,d54fcab2,a04688b,64c5d34c,752396d7,f864a9e1,59eea9aa,db8c93c1,5b4d7cd2,539bfa0), +S(adc92567,7678b197,1e45ed31,38a991dd,a4cd3586,a1ce1498,3ea30be0,642a2dbf,70f2c69b,7e47aa55,cab6ab22,e6482571,e8e1ea52,a52df934,d5ab99d9,acce2770), +S(ab89aaff,b04be186,183e8076,46c64111,476c552d,10df84ba,10a1efdb,32c01162,fccc1e20,17ac63a4,b9f78ca5,af245a74,4174c952,cfe29491,11ce1d71,e4be8f87), +S(1195576c,ca3a49b9,4db3f827,1ff2308e,66b66739,a30d73cd,e8acda4,a382002c,6a2be3a1,c6ae9f0d,b314a7d4,728977f2,17e7c7d0,199868fb,c7f79d31,6cd7d32), +S(8a15bed9,bfa215f5,42c62c89,da0adb8,c68cbc33,d9c879d7,a2f2803,b7068556,ef437bc1,1786cd73,6dc321d0,a3360517,3e7572f5,bce04b7a,3c8cdb85,cb56e697), +S(b4521d6d,f9b20080,4d3799ca,4cdc87bc,ea970d60,a3005071,e910210f,5654da88,c4ddf348,2a23e98f,b86ab9e8,4decc6b6,ad18d879,e96435d7,4b944d8c,f7cc1587), +S(4074523e,b75634f7,6442c3bf,ed9a52d4,5f6636f0,77a10e84,5e6ed950,b673a9ea,d8889a02,ec95b511,aa74db1a,10c91547,45b89b57,981011a0,9d4ce57b,e4e1f032), +S(b2e71794,e6ac98d1,ce532974,df79215e,bed8c668,561dc391,505e9e26,8444a858,94d8ff19,b8a74599,fbe5f471,e7f3e1ff,e0238cc9,2504f99a,9c4f5fbc,2e482854), +S(2e672209,8a6b4ca3,905a8910,6d23daf5,aeee63e4,34e7bade,70395df0,e5a1af87,708e9fd2,a3c0a3b1,b0e03f96,c3d477d2,abf6dc0c,bb8a7181,ca4b18db,ed12e3f7), +S(7ec0fbda,63fe7404,438e36,d567d9b0,bdf18b09,d929329b,24a8bc91,816fd433,f80ab84a,99d214fa,5d288e3b,c2b5560f,a1791412,9c3d16ff,cabed23,736e4f85), +S(f166252a,34572146,8bf3a3d7,bdd2c67c,b0d36b02,d7a70033,add26f97,128b1637,134eea4a,42b482c7,ad625407,bb89a615,656e3a2d,232f4bbb,a33660b2,403d6f63), +S(7af860e0,27d3b1df,aa0244e2,51f9459e,488afbce,6a3aa610,e5e223b7,81ba2d93,6ad22116,415c668,7dd3f4f7,b5a00599,bd35705,951e1093,3f85f815,4d0c8af7), +S(e4ad03b7,e01c5d04,7030fe59,6e7e7960,77d9847a,e604d2c1,d801a5eb,e21c0731,c7757ea8,f57af58f,b64f3eb9,c7762bc9,544f28d,a80d760f,c46b0c9,589019e8), +S(ffb2f941,f27aa8ad,6a59ed01,24e83bb,d49f2588,a5602389,15329f6d,f77220dc,6812c00,7dd44185,fc3f0687,6f7a62d0,d31adc40,c0a1a060,c67df13b,e4cd4873), +S(42ca15ab,9f245041,ce991e19,3d696f4f,4c277df9,8cad603,8ad0772c,2da6e03,972d10d9,37e3a836,9b831b2e,347ff11,29917a59,7ef94158,7c977604,73cb849c)}, +{S(576abbcb,8b768480,882aefc,81380709,831625a4,b9de63a7,b9c3390b,9cb4c7fe,b49453e4,6e17bbae,2f1f8f9b,91c3ed04,80d5f194,33917cbb,d28b878,bc6e6c4e), +S(f9d8a157,c151181,3e085c1d,ef2958fb,df2a17b2,6b330a0b,2d512c87,69e5c14,7eacca29,26aa402f,f8b78d57,f5e02add,91087da9,d607bb41,b56a40f8,f7b19b78), +S(d31dff73,7d2d3422,7fe39dee,b2eb4bcf,dc84bd39,d6cfc4ea,ff09812,23400a80,4af55e8a,fe8e8ab1,2e2c4463,d41824df,7b53e44d,efd946ad,b6128214,4244055d), +S(9ff2bce8,a9fe6c7e,e68a8292,f0d2f4c4,8d963c47,63018a55,89a2c130,667bc861,eb138923,94aadfc9,6eca7c5,78c0fcc,bb31a40f,98d02e93,a140abd3,cdf041b3), +S(1397cd8b,aed3c601,b6eee616,243a61dc,fead22fa,da50db4c,1f9e2776,6e5bc9da,534a8e23,59316503,cae233f0,3b6ef0bf,1c7e0105,119d1a49,ee688f04,40695c66), +S(4ee38986,511024ab,5385f710,42bc3778,7cbedd0a,ad13ba24,b77f42c8,2ae935d6,cf87468,24a38404,f313965,a64c927e,4ba0b7e0,140f6b36,47e2049e,35a74e4f), +S(7614cd7f,9b5f1455,74d0d38a,370f69ca,f3050297,10af5242,e5ccf19b,187dd189,b946eded,e4b72db1,6dad876e,396e836a,875d7c9a,28a9c739,f665c741,29ab7648), +S(67fd2372,5bfb445e,5254bc42,f7dbc1a1,65bd4017,cd1019b0,8a3f96cb,7b3c7cec,b556e950,a144febd,a81dd3f2,f729ecb,fe43fc78,8658bb7d,2b9735d7,b06a920a), +S(57572b1f,1f17070e,e9b30b6b,c7168cb2,4741ec5a,b3496b1a,c06ec0f2,5f910fce,8cfe2940,3dc97084,7ab28da7,167e78fe,f2310c83,ca476a97,91ca35a9,610bc560), +S(1f111332,1e31a294,cab4df73,5a0ef333,e753c2f,7c83705c,9a5bf27,1321c4f8,8fed26de,202c92dc,5b51b13b,6e9bae41,3c7c88d7,b858dd72,a11f073b,e2945f9b), +S(23c9e313,b04eebff,15fb0625,43de6975,d19decf6,6416f4d1,855083bb,d738f882,90673370,f380ca49,e876d5f4,b6649de0,24f4454,29cf9d91,96f4f196,8a49ed99), +S(b9251407,6ef7f01e,379aafe8,8f22c156,65a85ead,f671d8c9,89602c5f,804725e7,b3a9409f,7bf973b4,aebe08e1,5ac65562,56983f89,23415e0d,eeda4f4a,c0d7c5f2), +S(1bf9deee,948b3fe1,b4345800,51c67266,8fdb7af2,99275a83,706f9716,7e38e38a,688fc563,771b7d27,f9c09953,c40cf009,a55d7329,5fae0b7d,8fc37710,729a3911), +S(34e20de5,9d00dd45,19a70b3f,2994fc4,588ca9b2,beaf6afe,4a1daae2,10692f33,7804aff0,a43f1ba0,438c05ff,8d013e3b,e5180bb7,3a969825,fc97ef52,6da1b6a8), +S(80fc119e,85e88b0c,8c84d23f,9e44e96,1c7722d8,51d4c9bf,f1824fb3,365823ef,efee941a,a60743a,28b6ffd,39762f9e,437d2b00,206e718,7fc423bf,4eff0caa), +S(89ab0f45,e3860393,f24b1845,7578fe79,b812926a,6bff3788,c8baf283,89fdbf0e,57d4fc21,42bf446f,8e4d9331,659e7673,90391fe6,62e77ee7,f7a4886c,8f440c8d), +S(1f092931,664bb98b,79d8fb4c,efb287a0,f72641fb,1cebe711,820c92e0,42f26437,59f63ca0,b8e2e959,a97b1c1d,1cfa4c02,380dc42f,db7cb5b0,995ceba1,d7e45d94), +S(95ac9f36,f447928f,344eb4e1,9ea806,717600e5,148ad222,fdd52a83,86bc3537,cdef5355,e928b1e8,225b5a53,bb976822,6fb50d1f,6c6cde20,758d5ab0,e9f28543), +S(a9ce5ddd,9941ea69,1343ea71,c85fcd73,6269826d,6eda5008,44cdd1b9,4a66044d,29504563,1fcb7590,27d904c5,4ffc325,2ce3c8a2,169f4649,907db751,2ef3ce43), +S(2edf81,45c4bcf9,62425707,ccb36a3e,7fa1fadb,4062d14d,f78771eb,f3ec15d9,dcfc961c,547548f2,73206d9e,aa0d829,a235f66c,5afbba92,68fdf9e6,abc8260b), +S(fcf5b985,c935e207,92907b93,e9976ceb,ed320a14,3cf286ad,b38540ad,b4077dee,8a0e0b4d,1ab114b1,caf7d0d,f749f219,b75acea5,6a71b3f6,aa18557b,1da85262), +S(2bd4391f,42b70803,2baf4816,54569f48,95f1434e,be6f146d,41447f45,f14581b3,dbc9937a,61f43af7,42635810,5cdfa02c,49a5186,ce67bbbd,7ced2842,19a37506), +S(eb00deae,6cf69ccb,abe6b93e,e5493e05,d22e53c1,b069a6c,4660330a,4e3bc069,18002f2f,61b08dbb,60c784b8,4c6d71d4,6b004e6a,3089a0d5,f853d659,83242d9b), +S(c7c62a5f,ce15326f,25b2fc5b,697cc7f7,26d231e9,e7e9f15f,5998b8b0,10605524,8ad4b370,ea0506f6,f25eb16a,78f87ef2,f408cd17,fa4ec63d,4ee21448,1d5286b7), +S(aa1c2baf,632673de,6f6704aa,5a76c077,be0c24b5,223de654,88d1386f,15a1a002,de4648e4,fda7db79,41efc5e8,6fec516b,c6aef164,62d6dc08,fe93ebc7,a85261f5), +S(11871161,13c3c670,e7f5366,edd22282,1f76ec98,d1a3500d,f0e483d1,e53f2666,d0042c9e,8dc1d72c,f53836f3,2c76b5b6,52fd5ec1,9e8fde42,aed1a7e0,9d242745), +S(e232a92c,9ffdabcf,24422182,34078534,6b6b79f5,983ddd57,2580c3df,e4ee4118,6c1144c7,471342d8,7a784fe1,587ef576,483f8980,bbab12f9,35aa0d84,83c1d76d), +S(1ab6237,3998ded,e50aec45,8043f830,8a7b4564,2dd3c9bb,4804f98e,a7c2e0c9,5528e158,6a23aec9,81f04b51,b90576a9,a9e7feb5,53200e51,e604898f,e55996f3), +S(3bc24bc9,cbc58de3,46644de9,b17ffa7,39a0f7d8,83eb9f52,af19eaf4,d8d52891,f71cf5b,7587c275,8014127b,f404b70b,b257bad7,f5b78d2e,c792e1d6,b2fa4493), +S(a2bf9afe,e6eec182,ef5866a,b4bdfe2e,9d045323,343aa422,8c1a13ae,fee515dd,a5ee438e,3aa35484,c5f5a1d5,43fa15d7,ff0d1c55,6571678b,a3c5694e,f93cfa1d), +S(a0b2b4f,ed0ddd23,8812806c,fccdfa9,7fb3b42a,748721ae,6477dc9b,18953133,325ee7d3,4a540d0,fc3e3935,79ba7372,905c7b17,4f12b456,b43db5c7,cb50ec66), +S(e7b9796b,5ca006d1,632f482d,7f0fe393,2cf16a5a,e104eea7,a7ea1c25,1073e879,ed476773,e6e961d0,20bdefd5,8c833e35,634a40da,1256750c,c718ef75,45575e97)}, +{S(a8565dfb,75f8eea8,ca9ca6e7,c7d18a5,bf3e437,5d1f4e87,68d5f51a,57199ac5,daa7d7c6,cb86b215,a682141f,2308d9b,4c204196,eb779f32,fcddf0a2,da194921), +S(974619cb,86016199,20f507ee,62d10295,44abdd66,456952a0,54e945bd,7890250f,6c8d8bc8,21da8234,1ffd0cf0,548be1dc,a1bb7e1f,47354dc8,3e5d96c8,2c9676f3), +S(24bbdc24,1396b6e1,75f23a6,4bfb41fe,f8329b80,d306586a,ecb69e41,2a2014b8,aa6448ec,f00a0710,27b46f09,d696642b,9274ce3a,11a3e986,e84536e3,7fd7b2f8), +S(eed9a6b4,68004486,e3bd388d,591d3b65,2f35a3f1,9401e5de,81a86f5e,b7cd972c,c81f9aaa,d7300671,b3dbdd73,a095c79a,d73ffbd5,9f845eed,9fe3a57f,a41e9468), +S(5260e0f6,fdc6858a,8d519d3f,6c71929e,36979b65,431a6f3a,a7507797,e54654e2,5af860e5,fbcf9676,bb00c329,d3e2e058,efc860e5,cb9006ad,224caa32,9fd49f07), +S(11e53f67,d844c511,b8118f28,de6ed9b8,66b70bf,214d4d1,ed79adfc,18f7d6bb,20dd984d,7b9eb626,77e411da,2e823045,685a4bc5,2a3f4e5a,3aedea95,1060b330), +S(98c9f3f6,81e220e6,d4bba711,fa8b212a,dcc21bc4,8219b813,eabdfac5,70e6fffe,bd0890be,d9cf4ec9,44f6abb1,56250329,a37d2cc4,64c931ba,8606c2ce,55127aa2), +S(f644f4f0,43d7713,ba4380d8,26ad0f3f,44106352,142fef13,7c6e05ce,5e9f1571,3192280b,f3971223,c00ed336,94779866,536020b6,79ba8cb5,c4f9c515,69d2f97d), +S(334ab869,32c4097c,8d8d8a23,d529b079,6a759d47,a907b047,548e735,5b3b766b,18f11736,d54c9d00,89149b07,35f5a9de,b15d9c,cde4ee06,155a4f3f,de98a7bb), +S(983542dc,61b43ee5,c4a7f36f,22da008e,832d4eac,6791d838,1a095d0e,6d8a14b5,cd225f2c,334d1ba9,94b0a681,d6be7696,16bfb2a2,426e9939,d2238cd4,43bebd02), +S(dbbac008,1b678270,4a0fcef0,73683822,a3d4107,d7f1a71b,41497da2,9cc942a0,cd25ef66,36f21a8b,532371ae,b91b67a,deea5797,983dc36f,54aed202,d9845515), +S(477949e6,9ed28a74,879bc8cc,660696cb,115e6392,5a63817b,60e5187f,1f77f3be,dd8ca490,fb8e3bc1,44f5fe9f,aa41ce73,56a1dce1,cc8e11c3,ca5725e,d1b764ae), +S(7616b9e8,b451d4e2,e4826586,9bfad6c8,ddbf5fd2,2342c6c8,42d6bbe0,398f94a2,4e3bb1a9,76efd345,3c4474ad,e6a494f6,4f97c6dc,c98cf68,72bca24b,dd9e946f), +S(b87fb86f,6ec4ad7d,5bec3bee,e8d68618,c8e4906d,1c584368,ec819f2f,871ca8c3,c64723c0,aa587911,4dda9c75,493f739b,e8c2221b,b2e75ee5,b25def54,a1d40c2f), +S(56ea4572,61a6ccfb,46fced99,1258b31e,8573a488,aa53b7ad,65333452,b06d41c4,d8529601,4145e12e,a72ae4d1,5ae6e5f6,9cc88ba1,4d79467a,3df3bfef,33d84290), +S(e4c6540a,19682e0d,e1f1258a,103037a0,af4df5ad,f27cbb7c,9e3ce67d,e23e13d8,a31e1b08,4bdb5728,36e53d93,1de035,c90b1efe,b5343b23,cac0e7a2,bf5b3868), +S(1902cf3b,90fae93,1855d758,24995b03,e1604861,199853c6,ece84903,c8bd67de,3b3d41e3,a2dd4c28,16d492c3,e6c53c83,e5203c7c,a8100d41,24cbdcd0,e12fe222), +S(6519f4d3,b5d731fe,eada6806,727623a4,daf924d9,b6337a51,56096ec4,16ab42d4,62e2c1ea,afa990bd,6dd91675,e3b2d1e2,acb2fee8,e56ec30b,eb25bdce,2d3ad30e), +S(e1128682,519b965e,a933f197,eb0997a0,16114459,4c0915cc,9c55ea4,a30c1ad1,cb1370ba,f8707c78,84817ee2,8227da3b,7b7c97c8,266af491,e0d52bc4,ea0f9614), +S(4366960c,6ff595d4,143d4cd4,f0f0df2d,3bf864d5,73790abc,23419c7d,6ed9201b,623faab8,2caebb5a,b4c42bf6,b2a686cd,4640cde1,a95a65a1,f8d32836,9e5ee0cb), +S(5acdf691,3c1e283,c1220355,6efd99c5,d347ef69,bda1d040,44cbf0d1,ae41b16a,1bca567a,71698c35,e35e031c,e8a98dd,e34270d1,4e2e2439,9276a7c3,6a1f35df), +S(807ecc04,81aae374,1efec46c,8c6c194b,faa0607c,cf5b7cda,fc270fb5,f5b416bd,cc60be6a,6736dd94,848fbb05,375f6459,d556866d,165a2c16,41984411,dda33fc3), +S(29c470bd,97737284,765adcaa,68a98af7,5e6c275f,fa4fcd5d,6c71d428,bd3bfd79,b19ab40f,33c15201,41fed31f,681f176,4a464373,23283677,a40b4018,99a6eec0), +S(41a6d6f9,40bb8abd,9e8748,dcfd23f0,5333eafc,4ce311a3,161440a6,619efabb,b2a3702e,900788cd,bf35204,27e0facd,b090804,62f65418,89a3c34f,ae2cc008), +S(d5f5096d,776ffdb,f694b9c5,c9a9ae0,ab5897ff,c5ca3320,82cb2a2b,8afcfe89,6461e24e,28560d11,336244da,2038e13,c69ed5,a7a435a6,d07a1d72,be43daa0), +S(f65a00d9,5707ce6c,6bd55e8b,4b0ef381,1eca65b2,9845433,d7b307e,518ea724,7ae079e,9aecabf0,4ec5210a,b85328f7,e60c8ff7,3deb037b,c8e6e1d3,34774734), +S(346cff42,23c9ed2d,a1082d46,eeaff341,f7866e72,d95561b9,678def2d,9f7cd187,f97f85d8,92002750,11efcc9e,f8ff58e4,894f105f,b94e7390,7e185806,575698b3), +S(d0e3cdff,a47417f3,86f64a2,4029e3fd,9bc7a464,6e839bf9,232a0d50,349ecaac,5bdbecfa,2a2b35d3,ce2e9837,222535c1,57ec5bda,5fd70186,1920803d,a279989e), +S(f6bbbd77,b8dba8fd,704a3f02,1bc418c0,f8524c49,ccfcd14d,fcbf7f04,c9a18d,38184001,f39b257b,6755a132,86bdfd92,1a8ff771,fdd5530d,48eb8227,ea70be1), +S(6717bbd0,f019990a,c01a2996,e34f0912,9bf60a3a,71d8124e,fd86c777,9cfad879,9581f790,a16825d8,f44f316f,db3f0bde,108643cc,b390bdc0,75f3dccb,6520029f), +S(417c765,ca91a120,2b07459e,3713d5e1,bbcdfa82,bbc26cc9,279fa2d2,59251fa2,8d281a2a,ed38a80a,cb697989,9839d7c5,265b4e78,8a9e1176,66cfb6fc,4143a935), +S(e2f349b0,f89c69bd,3c8cf2a4,10730dc5,8e0beed4,7048c58c,15f9ffc2,508d2cc2,e014d0d7,f07d8dc8,7e79f513,89fdea45,bdcbb417,1f63424c,81cb8426,1f2b3be0)}, +{S(aceb57c9,187a5202,118c4dbe,573906e1,646b0325,781c1352,574ed15,e02b87b,68ece7f4,4037ff05,d4b89120,d90f08c6,f0499fee,d4e9e02a,a2e68bcc,2d7b70a), +S(365e555e,de9130af,99f996b2,106229c,c36c1ea5,8b065cb5,38af3a5d,2cec1145,81fc523c,b4b97bd3,cccce1e1,d1980769,fbc25a9f,a403adba,8e7e8074,13c87f9c), +S(d0a3812c,b9244d7b,c1f5b652,adbb0df,22d15d41,b1724071,fd297d00,bc8cbb01,f8d7650e,fda2be30,24ded196,eb3baf7f,351d2013,2479640,16ee4c6,b469951), +S(8f4ce1e2,a51c0ebf,f5e34cb1,c6aedd87,85e415dc,e7307119,143bbe9a,3e7fc632,617009a,ee7d4d81,1ba2bf14,d1647911,bf1a3bbe,cba8dfda,9030ead3,803fc217), +S(ea23d837,54cb2e9f,9b884ef,f4d1a708,bc1826c6,59fea53b,f52c51b4,9fe0e21b,7e8c691b,cfc3b7e,56a7699c,4f56a11a,fca5710d,963d602b,b102e1c5,b36dc3f7), +S(e3c970b2,c764c9f4,ad8bdc15,cf995690,807f5d09,4a849787,9d278d18,eed6ceea,aad8c7d7,13ce5439,b9125d9e,c14b5d8a,1c694cfc,f84e6922,b7e58df1,4ab8a34), +S(8ade30a,94b236b9,9597be14,bd421130,b6843895,a85f3613,efcfa0ce,9781a96e,78e4bf57,974cfc0f,c310330e,6aa47de8,2b0f5009,5a703fa,50093d5b,a8e8f0ef), +S(fa5f1cd3,4427d71a,de7e79b2,b0a17ba9,66d05324,1f9996e,be8143c1,9186d24a,3481bd18,2319ddf8,f344e4b0,196b3ddb,10deef4,d8d75c0e,49fc5fe4,cbd6e1fc), +S(8b88b79e,8cd28dc8,58e3f1a6,155146b9,af1e3697,d57b7435,c649f6c3,bf8574ca,e736106c,8ffb9bf4,d83d79f2,4faf8fe2,ba5dc258,e4ae1b1b,b58a1a7e,4922c95b), +S(12078a5,5c46d721,96a148d2,fdf6505b,d059e423,c5d5295e,facc2b82,aec51f5d,66a4332d,cd265085,add9a141,2fae2562,17441d7,dd9596ad,46309a0d,bfb4e55e), +S(841523ef,29f5bffa,b31a526d,bf74b16b,fac3a3aa,391f7404,6675cba8,7808c171,7a3fc3f5,bac300b5,7ef843df,e334c995,cf66de11,2283fdfc,767cb57e,e7e7329c), +S(c8831ece,f4545c2b,387378b4,f88173d3,f1cc7db9,d064774d,60394f0a,ecaf5af6,f32f1a48,bb802757,34e66cbe,58a3ed3f,adf28dd9,374a42a,a824a095,6701322a), +S(30001ff3,7b1b1691,9a135a31,287e3a3d,383ef3ca,94748e33,a52c146,586dc4b9,9d71b25d,6fc35db7,26b58d1f,642dabb,46dfa64d,e0ec2a12,c53c414a,9dd2574b), +S(a17d3621,74d3c789,c4e00888,fd4b0f4e,ea3929cf,afea9e9f,7439901e,d6b0fe44,2bcf09ef,2d374194,510fc057,dc973fe1,bb687428,91e9056d,a5b4df7a,de79bf), +S(4725e2cb,19f95359,2da72565,d8405e09,92a64299,9ad74ed5,b41f5d24,44cb6b0f,be23fa82,7aec3121,7b90028d,b61d1092,764b2824,9f3fa0ef,91929db9,b2e0246b), +S(67c560dd,74c276c4,df3efbe3,b95dca4e,a56c4563,cc7ae225,ebea90e0,f5e212fa,2c9e3120,d52ef31d,7e9e36d6,eafbcdbf,ed8a28c6,7edefb94,1df7f38b,cb05c160), +S(8468da98,7b33b79b,e08da5fd,57cee298,ef86f624,3bb975da,2f4261e8,f7531d92,455d8a8e,b4f45693,2e8b6f77,ddefe070,591dd37f,d6ad3a27,5774055b,8a63e650), +S(3416d4bb,78de7570,b1e9e912,83a3e8fc,be6524d7,4463dee6,82e84e52,72c0953c,94e55458,2c17fffd,321364c9,16658093,986b56,f88b4818,129e19c8,ce685dcc), +S(5c66928c,a39a6e22,672c1dba,8bb6331b,41a7f43c,a72276a6,afd3e209,6416a9c5,181cdfc4,15e7d6a3,c24be94b,7fe328cc,ab624c0d,dfabb1b8,f9a73b56,cdfe1b28), +S(971f7a13,210680a3,ff6a12ad,17481a63,ef624d0c,e4121166,7e63aaf7,9cafce,5de2fd1b,3149e321,2980c7d,88a49018,26f83f18,7438061e,9bdb8d33,6a4b08f6), +S(650277a7,9ae7682d,c5f3526b,8411342e,b48277a4,9876caa7,61ec6815,9a1f13c3,a903255,fcf09808,cd97d92a,26dbd2e4,7a29571f,ae91107a,7cb6f0cc,3aea1985), +S(76a79cc9,7fb80ab3,e8d31e5a,d11f5ce4,74696d23,f1ee7aab,3928848b,556f483e,1779bc5d,c763d1ef,7611b402,4583f07d,c7dc9c96,7afcf83f,e6b6ee42,da75972e), +S(6e0b4015,474fe250,d372400f,13efa0b,70c4e8df,816c0e8b,8d27a7,a8168d54,f01dafc8,8178dcf7,15f8fcc2,e7163137,9e1dd4cb,6c88cfbd,e9a051f,ad204c3f), +S(ee5dd472,b5efeba9,d0e354dc,21228d22,40a69088,842d00dd,6b6358e4,309d1f5b,bce93ac,3fd4a098,9e74448f,5832643a,a2a172f2,eff1e2c6,c61ea99,cc6e7cdc), +S(df99a925,ef2e9f9e,57208fe6,5373ff94,876b1448,368dd453,436c59d0,f2a857e2,88dcfe81,4397f990,56f92a27,143c902a,2a6a66f7,f7e9652e,e0b16f13,33252a1e), +S(9186f095,43dc64db,ad582561,cab96a38,89be54ad,e1cdb27d,674af836,22b5d284,71ae31d5,a73b29f,54af1aa3,2d8e541b,14f7cebc,9279ac26,c846d466,aa975e20), +S(645da454,63357bfb,61b5b932,1897a73b,87af6077,81487bc8,af1a66ba,49bc5e37,4b925aab,aa7bbc19,5963025e,f1896cb5,b6463242,cd8a35f3,b1b404b0,7faf8e94), +S(5cd9a6c4,e9d372db,90a65f11,1f1a1b5,f28bc3b8,3d05f599,39979c91,5277eab1,c147420f,7dfc4ef4,d7d1f08c,1c523771,86a8d7a7,10cd7017,82b97c55,63287aa8), +S(4fd699b1,2c720ccd,7b977e5b,dc622671,18ac3028,bd635b26,fce648cf,335cacbb,3936f10c,aee5f51,26b86240,3249e1d3,5566714d,17ddc19e,cc4d1056,71e523f6), +S(b3fa0545,83510d6b,91226711,4bac7f4,ba4ae5fb,baad7230,3003efcc,4c3c18e1,57a3db8a,6cbf0a94,845e7d67,f9b01902,55aa5b66,ef31abd,34ee0410,ed55d0e0), +S(fd73c052,b194c6c6,dd46aca9,d640981a,ec796009,17a565eb,e77fd534,649a2115,9df8973e,37e877bb,fdf5454f,d9082926,fb09fea9,d162bde0,fb635483,59458f55), +S(2982dbbc,5f366c9f,78e29ebb,ecb1bb22,3deb5c4e,e638b458,3bd3a9af,3149f8ef,59e4a416,5099ddf5,4605acc6,384a4362,f6a2466b,ed1c127b,a918d94e,e93859e7)}, +{S(8aff982a,fbe09f67,6d6e0f49,e2b68f88,8f20dd2e,6387b420,8157ab24,d19027ed,f2350ea9,d00fd861,41259f03,b51b5326,6ce05a34,74508bd4,31ca74e1,366eaf92), +S(27ff285b,1e14961d,a042bd31,56aa44af,5e73717d,fa413a47,b300f358,e1960dd0,8b578851,264a8fea,2e29bbcb,cb9c90e4,93e8c731,983f4bba,65381e88,bc83a8a7), +S(fc6acf61,4a214859,1418ab5e,e0f0274a,309a8248,2cf01f73,db8a9790,825486df,190b9c0d,46953d99,c9de2bdc,bcc15d23,ee90485c,c4c152d8,e28322e5,4c927d54), +S(743bcc6,ac86b0be,a25cce81,1fdcfc13,73f23926,e3116fc8,9415b8c0,4c1983ac,f3df10fd,4afbd3b2,dc0678c9,102150e6,3d005680,6a5e45fe,c95ea495,9f2b8555), +S(bb165428,2c13362b,b1e017e6,6402613e,f82bbe22,9429f29c,6a1a522e,4956d67c,ec542c4f,7fbf3c6c,32e71aaa,86e3e4e7,e52b0d43,98589e15,1f17417a,40b31b07), +S(b3f74ed2,5a7fd474,5820a2f6,221349aa,e41af762,25c2b706,160a463d,1d59e7bc,a9af9d2d,89dcdfe0,21ca46e8,5f09bdb5,197c8f23,bc56d705,851974da,1608dad2), +S(20c0914e,f88902a8,6af0ff68,a08f96ea,25f15ea6,b1128900,120028a1,1049a77a,339567f2,71a1f1c7,16eb1d56,2f009537,68ff4cd3,9a81c6d9,6359d2f5,5d04db9c), +S(a3555aea,2e96f05,d25a145e,4ad0d2f7,fb453974,8c4a3097,a703c0f5,404a0e7a,ee236b76,8fa04380,b0448beb,d2589665,e43299ee,b9fc78fe,5a64db69,ac92b7df), +S(37191a66,1d2a7bd,c96a0767,ce47d97d,7acfb8c0,ce251e9a,1421e2d6,29230c2b,57093393,4783afd7,2df6524e,871c8e67,ff2f48c9,c73e2054,fb219cf,d3c2a68c), +S(1a2f5b6c,5fbe300,8b01407a,b0b28c3d,c823cca9,b4c71a1e,4fc814f1,e186e062,b2f1c632,a9d92a4c,82d31a55,f4fd50bd,d53ee99a,2e1452a4,e43e5ac4,b8cbb7c6), +S(2976575c,c5e70e47,cd9c10e1,32a593dd,12b65215,38613cb7,22390022,73fb41d0,c3f0b08d,a2a3a046,d87dcb13,38c35824,1a8b9959,e2567543,852dcf73,c4f5cba2), +S(bca28e75,5cd6ab74,85884b30,ef399f,44188695,fe9c4143,6016bdec,25d502f7,b67538d4,a571e935,cbefe237,c5a01f77,4ade337c,fec9f95f,3e9cf042,f0dbab6c), +S(3dfe1718,beafee83,b858048d,25d46ee6,7741d3bc,bec1e52d,3ce308cf,738b715,8499a8b3,a0c7c599,f62f056a,a8364494,ec6e0198,2c47bbf8,7e2df591,de0ff537), +S(bde6252e,a9e4823f,36bd1737,ce188fae,be4a271,9984c9e6,76f9f4ff,d070c1c1,2e5db82d,e02a1fe1,39d903,7e7adeef,12d40366,de0eb164,c04b2ef4,b1e849b6), +S(2c74b766,eebac93c,479fc0bd,78a3805,de50be2d,a6ad70c6,9048e43e,c91343af,ab7a929d,588ff993,55094f83,6e7b3b58,c6381bfb,b284f9bf,7dc44cc2,67cc741c), +S(f0e084a7,af9abfaf,b6ebf3c5,b526d545,b8b1cf5e,8e09a06c,3670aa37,6af83a3d,6bb279db,abdb2b2d,fcc97510,2b075dfe,b42d9e6a,5a8af760,f4b63788,c315f8dc), +S(715aa28f,4e52fc26,a2f4b9f,391894b0,6adc3b69,b508827b,4732396f,5eb7edb5,c5d0d68b,3a8c6532,2f6303ab,99b6c48a,88572c4c,56c780d1,d51d2441,86ba110c), +S(8f980e69,3511ec3,cca89b2c,362835bd,24d9c8a6,97deff86,5540f7c2,b0bacf8b,2d5e8470,f2041ca6,f158ac83,e92a2345,4059492f,af27ada2,92bbe51a,d67ee5aa), +S(6823a4e9,d80838b2,750dada3,cc31f59f,3cc9d6c8,3f33aa5,38d949aa,c4d6d657,e087127a,3ddc19cb,e4088a2a,6df61863,e8e81cf5,c5cea4a8,8cd2ab51,bfbcba8d), +S(8c9af14b,11add28a,818f85f3,276d1d7a,1e3478f4,23e74b72,caaf2440,24558538,a7c17174,da1eed2,7eeb7b6,c1d93e4e,9e4515c5,3cd888d5,e4527cdb,94a64fb1), +S(5fadb7c4,74b13592,a1a27f76,b7c2011a,102b66a0,c6ffbc02,a7306e1b,a9ccf49c,7bf61c4f,134f8b4,7a5f90a1,938918a1,4d151f2c,7f1c4bea,cb8c4773,cf11609d), +S(79a21b82,9325fbe5,c01ac979,8b89cc47,379eac4b,682fd747,47e0c04b,879b404d,abfa4d5c,7ff916c4,9f489c12,5235bd9d,a0395b6b,84d6699f,c96f9c0a,5a4cab2b), +S(b213d11d,e4b5601a,5f10827e,d39a7825,adc36bc0,1130a055,cf8b3e8e,fc96d10b,27c0e5b7,a739fcd0,5eb73321,3fd1bbb7,873de0a1,2b92cbc,21de57c6,2bc812b1), +S(299ef8e,e131f523,72949d7e,fc2f0f7f,9965e69b,56725b55,4d513435,ac8b0b3e,8ba93fa0,2a4d97b3,54d47c10,d5d791c5,f724b68,4f501eda,1931e563,2c6faf06), +S(5143ab76,43a21de7,7ffd0f3b,c4746fb0,589be22d,9d9ca2fb,89403a39,86d1cd37,20991000,a7c01e4b,26d9236a,45568bbd,91c968d6,c87dbe05,15063af,d8db5a03), +S(738ce787,49783066,923ceec9,a841d60b,56855e09,93e67cb9,9d52a0ca,7a64b5b2,aba44aa,272945fc,5eee0330,976b659a,a6455dde,feb5c894,cd274414,71610384), +S(6bb9bbe0,4c3dbaf,6c60adcf,5ec5fa59,29cdb04b,14633c10,5dfca2c,183e1d97,b7dac59b,5c35c3cc,15521da5,89c0d333,9dac05c6,614acaf1,d8b9e834,8e02c3c9), +S(f325eeb8,49a32b2a,fb19491d,8c3c112f,a7ca3443,438c8c19,99bdf791,6981472a,169df94,a26f26b1,e5aaf810,7a148faa,17742c3,10cac320,6daa69,f8aad67b), +S(d279bc0c,f7f58a85,b5abbe25,936d5088,4d8ae8a4,b415ea30,2c0f1133,de98603c,1e69875e,2e38f9af,222e03b1,6c833bd1,12bc10f8,1724da7e,bc780e6f,5228fd17), +S(224d079c,750eb1b4,2d70aa25,5fa0c3fd,c2d07c1d,ae4d6cb1,17c1e61c,5ec1c6b3,e54dc4fa,b0e05362,60d27fa7,ba53c37c,a37ce30e,617365dd,1c58a59d,2c93ed00), +S(f4741ca2,b3de5414,49426531,d546272d,ab8fc55d,8f65eb3d,5ea780a,d25cb53b,3b7290bf,dda0d0f,e3704f27,d8537063,f2fe9571,4a0791a3,e1a25865,96a5b0b1), +S(e931258e,8eb5559c,6d697272,8a704c17,b775a26,5b4527d4,a4d4d742,bbfd71fa,4e1ccc9,b3c0211f,17a14be9,636ab4bf,4c6b931e,44a1ca0c,c2642f2b,e8b2c928)}, +{S(fa01dd32,fada2843,c51845e6,3cdc1b76,79dee47b,d2f4b767,5133aa5e,62029057,6ea6596a,b0ea0201,b6c8bbbc,e9d07fd0,8040e1fa,198c8767,67ab6055,34a33), +S(97ec9d33,a9d88115,471619b5,3fc58a08,e6997662,7a28afc0,b75b2f49,55eba300,92ad1d6a,f8a0a100,27d9ba90,4f7fea6a,571f3c32,53393a7c,79abb0cf,9a558390), +S(ef364ba7,626d72a6,87bc9776,3f2c0833,50640bec,6ff4d80,9dabcf2,9ea9145c,7f8d7c48,1bd80ff4,8eccfa9d,2de5eeb9,800cb98,c02da539,3b3d6c83,8fe4a2ff), +S(45961303,a778b47a,89109231,3242304,30a17859,7d940e9f,fc2f25bd,1be61c00,5fa356b6,daad2b1d,7bb19cce,b9148d31,58d2651a,b4b436c0,b99193f6,61cb037d), +S(8aa677f4,d73c0725,e2163e5d,ed3dc312,7ad5ee29,f9bad8b8,5ab8f50d,ec6d77e9,1fcb9da0,d3fb9bc3,3a45bcdc,50aa2ba1,16c2b05e,836b539c,863163c7,2436c334), +S(8c6b2873,33082bf5,a3597a26,7cc14696,2b689f20,59caf1d9,35972c98,9b14c86b,aa86d282,a1107f8e,21307e0,2ad1420a,a4061fea,3e3dd6f5,9b5d6900,6bf4827c), +S(46c963f0,3bdbf433,cbd60858,5a4d659e,9815c286,9f684eaa,cd879d66,ceed05ed,be2a8d60,636c5b80,e443b13a,9e21c91e,90a9e781,1c35101a,dfd61a49,88193e86), +S(cdbe43bc,582f3936,314a88f9,fa21b29d,f4b5acf5,96cdac3,4667e9c4,b02b926b,8f2a5b62,4f20b20d,cce97348,d73d5653,8651dd41,dfedd476,8792fa61,1bac16fa), +S(6f9c5a84,1ffededc,ec45dc63,7ad15aea,207116aa,a3036ea,ddfb0656,1dfd074d,ddf1c22f,9168232d,cf9c36a5,dfb7835e,62d28405,bd32ec15,5e3ddb3e,df834088), +S(42000663,3223b99,e15a2a65,bd95b229,820abee9,5ba5be39,6f8879b7,3f421e7b,9f3f3d66,40de91bf,c6872619,87487226,57e60a4,3ac633cc,48f684c0,cf42696b), +S(f02335b9,9cb524b7,45fa9167,41da4259,f70279d8,efe851ab,f5b0b8a5,32a087ff,e1bc6767,ba068b22,cb7389e1,36805da5,c30ca62a,e59b92f5,48e4dd1d,5327cfbc), +S(5bbda2dc,cf8154e8,28ed49b1,2fdabc3e,eb8c3f9,d0da5878,77611ff4,49d72e7c,312377c3,6277addb,d5b044e,fe136626,d5f7e7e7,a73cfc4b,9751e8ec,e4f77084), +S(5cd5cb83,ba2f225d,1ef4faf6,22e226e1,eaa85a5e,99721d3,82aae23a,f9dff565,254f58ba,9c49244a,4178a067,b0e4bf6f,dd7f3e15,65e21637,bc41f9f3,55045908), +S(3b20ebc6,b453aa16,e5b61381,1d81ca1,f87dce6d,b54ba85b,d8578ee3,23bff228,8c9d3054,56627a,7313505b,4aa5140d,9fc40d83,bcc298a6,43842f04,70a335f4), +S(cd531999,cf33db75,df4430c6,bbcf32d0,642be18,5736d79b,f2947989,e52c8da8,c7e99c34,2a5c1112,400edc69,f58246e3,d3cebbef,2c43ff47,7520b027,e2aa7d78), +S(40b3856b,273bd2a5,145b70f,d16a2972,e488b33a,f3719143,db7bc567,26ff23c4,d8bf895f,71d96e6e,20d523dd,1256bd56,44e11442,c4757d74,f116ae44,69dc9b21), +S(1a0cf029,2d7cce75,32b74bae,acec6864,9e682788,3cef4bbd,c8b24fdb,53e885a5,32c87d92,6f969f69,7989837d,d8ec8ef1,c284d9db,2a86ecd3,5bbb6772,dea06692), +S(7fd5d251,93dd6c17,8d0be92c,342f94a3,c92c061,27998f4d,54f7dfb6,1326fefa,ea7d0755,e0a804bb,8b7ac8f2,dbe1dd7f,9ccd36ca,2fa94365,631ae455,5d080075), +S(51820145,6c07fa3e,70d7b24a,7754b11,e42828e9,c1b96b0f,fd79bead,2f44050e,126f5526,1a55b724,7d08c868,366d697f,a6898c66,d14094f3,44b0a6b3,613d043c), +S(86f2c87d,46038770,3be5ddc6,c2ba1ccc,7dfdd56c,a9986663,882f85da,345886da,ed34fc59,4b66f7e,f06f54de,84f3c7f6,ea1d877b,bbfc4185,3df800f2,fa805027), +S(7f7d8a69,5b86ca13,d6a0ba07,99e60cbe,f5c4e1f4,c74a62bb,93d94d4f,8c1f296e,44a14061,b2c741c4,6a52639e,9bf08776,5db5d496,92bb6d1b,e97f9ced,a89953e7), +S(ec61e956,83714c55,1b72ed5f,c5b09663,6dbdea9a,64d13ef8,c9cf0c55,89da5ae4,39a6e38f,9f7927cf,ffcd0847,df91e856,4188bf58,276bb4df,3721335a,5357c77a), +S(e5906c85,4a75bee9,322d70be,a5d31c76,31a59389,2f479bf,8dc11bef,9ad5101c,125b3a58,8c6c1c5f,288402f4,3ce74ec5,fe9c2dd3,3f3605df,9ab41210,32641524), +S(6c9faca8,b1b435b9,213fde17,ce967f05,46e6f27a,cf0e131,8496bcfd,d856b092,a04ac67d,4bb07624,6b59df97,2fbe2c1f,bb04be99,e269d33f,ccc81f76,3f567577), +S(61031a0c,730cf279,d929b4f,5608f16e,6b1b1440,c04e5a9,fa300ff8,27303def,acc4d732,afb4730e,39a10c0f,5ae2cee9,5099be03,bf5612ac,391900fd,b51238c2), +S(e58fa07f,ebc3aa4c,61ff4fe3,bfc8d04d,48a1e3c9,935317e1,83d537f9,7f35826b,d2402844,7e63c3e0,be630190,8139a75e,2e1a2b22,b05ce52b,e453ccf7,7c35f1fa), +S(4d4d2982,b45a339,1720af,cf6b92df,2c201d38,5b9b6c3a,8fc53b4f,fd3bfdd1,d72650fb,d130482d,116524fa,e2b3dd71,c68b4bbd,54fc55a8,f9824578,cff67503), +S(9adeb6f9,6ffcbb56,f171919c,a8a64c70,9b8ae835,828bd573,b7a1bbc1,3efb0360,6d920a2e,d2e3f41b,4820d838,ca342b66,9af35a7f,7b6d09fd,b1ba4298,9abe027c), +S(64ba9514,d8680f6c,dd66895d,9c5ad45f,6e29,33506f8e,d7be9770,822aa9b8,7ed8c0dd,59bce424,481f88d7,3e641b61,a010e490,97cf84ca,16c2e045,49e9c6ca), +S(9e4ac64d,9ca58a04,46ca18bf,c1700f2c,16937ef9,c82e8b55,9ccbd751,2a0c0222,315ba2e2,601b18b2,cf7f1720,9c4cff2f,e39dfcf0,c2546fb1,e930898b,5b023274), +S(f13a99e5,8dc72fcb,c62a492,d2850704,621ddf48,f1f433e6,9a9814c4,17d4b84a,cc3d3732,f0f4166a,55946e32,e1c01f91,491c82b8,ef0d269d,7a66f039,ac02dfae), +S(fd6451fb,84cfb18d,3ef0acf8,56c4ef4d,553c562,f7ae4d2a,303f2ea3,3e8f62bb,18ba314d,4e78ea87,490185a3,e43cbb33,5d54b6d,2dff17c0,2f526f78,ecd3f31e)}, +{S(f1a749e,6cab100e,2aeef8ee,6a654551,c0ff906e,e7d11d77,f390955e,9d29d783,a60f7295,3c8c3bf7,f1dc1358,e39baf76,3dba22a0,1ce7917e,aeabd996,e21e845b), +S(e8c45020,4c9d9ad,f7878aa4,184a1576,d4c65d5a,c1c4d494,ff427e86,8b42ec1e,aabff02d,8a715c2c,34414b27,808882c3,f656389c,71c26d6b,d7ac8013,83f4c57c), +S(c1febd79,1784fea9,bf378237,a05522de,1081df6c,27d22ea2,aad805dc,7c2f1c4c,c38782e9,fcc1004e,aa677f79,536aa069,7dd9002d,ac16936a,1f0b8736,8734174e), +S(91925564,4d9bdf2d,4522825b,5758b3f0,4d32da73,3a4e772,bfe3eb2c,9909f4ef,2568e18c,1a0448ab,d038ae62,a652d152,4bdec1c1,a0293695,9772bb65,d78450af), +S(25bb4202,9880c39,f5bde432,c1fa357c,7f4867f,6fee48b9,24ecc824,5e1a5253,5d43db2,64c23715,b4b0eeae,63127cf6,9b4bc79e,f96ea8cc,d17cb53c,c3ac0fc5), +S(2597e080,e772d36f,df500782,5f92f797,c61c72c7,8d801dd1,3deb1bfb,9e91b12a,fd5918b8,938ded17,a458d0ae,559c552f,bd45feb2,5b4f59a8,f5b735cb,bdab92c1), +S(70231b28,f578dc12,9f8ac54d,fd4e3577,73d0fcbf,65be0dcd,51132882,5a36e7e1,d12aaf89,4dff3e42,405a4140,58524e30,b7c6c4a1,83763268,6852acff,83d2b7cb), +S(f8ddfd5e,5f3b46a1,ab363169,12b74c97,b0bd654d,87824040,bf6d2cad,b4fcbf95,931fc58f,5b429636,5e080d5a,8fb35ba0,f92104d3,891d6584,8d24c0f7,fc95bda3), +S(a033f432,670a382c,57e2408d,3bdcd2a6,6758e63d,77574598,6b123e4,d927bf10,83b52f69,d79e7445,b6e33545,c23f16fd,52691151,96ee60d6,2ecf6de5,b2961a0c), +S(8e77f9ed,9a643f3c,bf197b09,80f92860,f37d8b83,93633230,6c902c38,3bb7f96d,71b4da9f,f736f9f1,f8c3c099,c34c1bc4,30bb5d26,3c861e2c,726fe891,cdf7d1ce), +S(f34153e2,29934c71,5d895102,778425f5,e92f4ee5,b96d1333,df207e62,6761b328,954584f1,64c8f35f,2c4e0188,76186ceb,3e91523a,5e8ac03,d5998253,49b7b8ac), +S(e133aa94,c0252f05,379b5bd7,75ba3f1f,92de2876,68613613,28946904,11b3ed52,40363801,613423b7,cc6c0cc5,af3641f4,dc2a7ac4,48b178ae,d1393605,103bd6dc), +S(28119c6f,a57d02ac,856edb00,f594c7be,22772b0d,700ad14,713affe5,7e385b5c,969b6cb2,8ef483a0,db4a96bb,92e2d332,6e6d86a1,73bc3d5,831bcbf2,5efc437d), +S(8c728d65,8b78d96,44003708,dadb48b,65dcf6f,6d9412c0,e31cce3d,b5384d00,bb3cf660,9908467d,285f1c7f,40f4f18,ca618093,92633beb,b4ce30c4,72680662), +S(477321b6,1fd5b4ef,3acd1e8d,8432ef5d,e70576ee,6b8490e6,839f1985,dec96490,88008466,2244e3f9,7d2ded5d,2193c70e,2d72c67b,9b7cd70e,9f14cb05,70306bee), +S(ebedd345,ccdd0e04,4bd3d4d7,e1f1cb6b,ec06ad10,5ec2cec8,821580f5,d08a63d4,4278bfb0,88e4ff81,a3fe15bb,e01be36,40450f85,885da0ae,e15c6b9f,e78ad14a), +S(f4795df9,41b315e2,24a98dac,d9149ff2,8b9a7bf,e758a1f3,5cb6336e,8e1f9814,6982bc20,285c27d8,12c5c648,d0635c7,fdab85e6,fc6905d8,65da387e,596da791), +S(65a5964e,ea76e30c,74c472bd,3ddd5169,11dcfb3e,1f2d7ff2,9661e254,4a38ea30,a7c394af,80ebbd32,e442271f,b061bb42,a7b1758f,44d7d952,89152fa2,a88fe3f9), +S(f3d10725,da6b6c76,6da6fb5b,969ba7c6,3e33b4f2,d062a446,4ffb20bc,dea2d376,4d65ff69,64518942,bc3142a6,2148137,7bb609dd,6545bc26,9678ea19,62812ddb), +S(f5fe0f35,cde00589,301584a2,f4f5b1e9,3977082e,9c9bd50d,7c2c672b,ef05cc9f,1b49ac82,486e6344,dea32ca3,c96cd5c1,446ac2fb,2a658a42,50425f32,e8d72e94), +S(fce17cd4,d9519a53,f0a100f,ca54d1f9,fa87eded,98a12654,769c95be,151e33c3,40d342ef,83a4d715,bd13df0,f21197c6,e189681b,efa0d925,248733f,5ee07b8), +S(fd5d90d4,a97c1d1c,4fe18a10,6808f46,f6ea4422,c4408860,c2256b66,618af8e0,7ffc76c3,539bdec8,f59a9a7b,b36fd534,99306cf3,2dd1fe43,a2db5b59,af2f7e3b), +S(1c71f824,1b147abd,9e3c1ca3,fad5146b,e531dae7,c9c0d586,4f2d8bd8,7a6457aa,23e7e758,2cfc92dd,e498c0af,b942182a,92e02bb0,7e95bc1b,763d8030,9ddc9137), +S(dfb018bd,9bc352,f36889b8,2a46512,8850a158,872554cb,3a3dad28,a0496f20,2daa780b,d615d778,3de8f5e8,25cbd934,5c021df1,9ef80a6d,39ff87db,67a1e5ca), +S(bbd320ee,dacc1282,d3fd2109,c26f6bcd,46205ec1,d96b806,dca35dc1,4baa823d,ae7beed,3b5f72bc,ba66c794,89c05666,efa85966,14bacc45,9a99d882,8edbdbfe), +S(c9cd8f21,a068f78b,ce5129c0,9084be52,e48d688b,f474e690,b7720360,e362dfce,a10b9fe2,78c7814e,37851b5a,36aa4246,54c6279e,89df8fc2,ed189ad8,11518f22), +S(ddcf39db,aba52181,72c36a53,50883245,39ccddd8,46ec4258,e72dcd71,40041491,85cadc4a,a569265d,412c8fa9,4872bce1,51a750f7,b43385e2,2db405e3,54428a5b), +S(391562c3,f19436b1,a6e41d06,7435fbe8,27de66b5,555540c5,3ca7a0cc,c7876457,c3a5d917,5b56f67c,66ff269f,72c0a1ac,74503106,9059aaad,f3e66dad,45a80ee0), +S(63d4b224,7b2d441d,680a0437,604533cf,1dc48c9,bdcb9e10,e0249960,f966b2d4,e25cb896,ba165d4,46f73344,61e6856d,4c186736,402dc6a0,d866f97e,bd5cdfff), +S(5fe057df,5d2508c7,611dc21d,412739fe,3e7cf9e9,670812df,cbb00255,4d44cb22,33b88e83,9f22a7bd,17c149bb,65bd4a49,29b2a29e,b975776c,e82189de,80c7d45c), +S(5ac83bf,498f7eb0,79507ac,d5fbc587,f758afa9,b6a1ee51,4c857f8d,608a7b1f,1c866393,8a91904,f0530bdd,ba15390a,4c10fc4c,ef8a2f07,d799c89f,69a33097), +S(b0f9e4b9,b29790b6,33bcc04f,d860cb0f,823d8d1a,4cc1a1c1,413c1606,cc9a8e2c,b617d40e,7bc52192,be344f46,f9021c0f,ccaf33fd,3e8e3118,93df993a,20c2ee7b)}, +{S(eccf169c,9514a854,8f7e1131,a7438469,4df7dc2,fab96462,20e5799d,6d3f672d,452e53a2,aaf17617,37055bb7,24b64f4a,8fef29ed,f8571ff9,a3a6d2c4,6acdb91e), +S(a77bcddd,a0fecd39,a99c6387,57bda1bf,30257248,6a3fa08a,e2d6ff17,e6e4b6ea,debf4c03,b4bb5c7a,8a386a7b,1e459426,6c78eec6,55f01cd9,f137ff18,c5fbdb1d), +S(a77b91ec,6db6a66e,a48de424,65079a2e,ce220fba,da221601,840546ec,2295c2a2,3c721fea,81f5fe05,163562a9,849bdb15,90bc818e,86674ea2,57fe8d0f,4050086c), +S(99a28a1a,3bf2af79,ef2bf134,d31880a,71c2aad3,824fb7df,23fc4fb7,d54b2910,620e2918,df14e3c5,dbfceada,1905941d,32d77592,89ec607a,f9851a6c,5592803d), +S(7eb52616,71402db8,905c7097,2af96b72,2bd77d,f124bbcc,5418f217,f6d8c7be,ce1e663c,8276bf42,99919592,11feb13b,66aefa37,5d6dca15,8b7b66a3,ffc6d7ec), +S(c88b1815,f183e6ea,3ce8469f,ada5b88b,805288d6,828473ba,368d52f,2145e7a4,55e78f2d,3784952e,cb47f6b0,113eb471,8cc58225,85f9d1e,2198dc60,af3f90c9), +S(dd893c5e,a2e4e70a,fcc161ac,47232d3b,77f16c95,54c98770,9a7a6f64,c0cf7ab1,a1a58b41,c7d4d0c5,6d6c908b,32d97467,b8b6ed20,73e6a677,54935665,6a92a480), +S(591b8422,eddbfaf9,d2c27c28,dd84dd30,712a15a0,deb752dd,dee682cc,34722ea7,877b0c99,6a248082,fd442509,b0ce4cc1,b181d4f8,8ff755dd,5f0dba66,ebf95d1f), +S(75f9e3a1,ffdd902,be5d1d2b,3ed18b37,62e42e95,8b024ce8,f892ee13,ab35c674,57fabc84,7c68cfdf,272effee,e7a6ee2c,5fecdeb4,8e4877c,ccf2a8de,2e2264cc), +S(c8a53d5,e1895cdf,db61c1a2,395a866b,ad803773,23ea43ca,775408f7,a4141cc6,ddeff9c9,97a11e4d,d0afab30,f63229f8,1b52ac,c25749ae,2749ddb4,2b201196), +S(8827d23,668f3006,b966cb19,698a066d,aea556b7,4108739d,d6414d8,e8dd78c9,3d009ac7,2baabb53,2e3658e1,8941d4b1,efe512b8,fd7696d5,14b12216,215f10e0), +S(dde6b713,5cf165c6,53c7f5db,542501bc,b0a41e3c,c6779aa6,194ac1d1,8a830b01,25c04b4a,937e16b6,e72616e2,d64a413b,6a7c29ac,71dfcbf6,826261dc,2507c16), +S(8cf6210c,5426b3a5,ed594699,da6cb8b9,8069a3d7,b926cae9,fedb2e96,25d20010,78017fc1,7915e3c8,62557896,acd002fc,7263bd7f,aed38fca,d63ccaa3,57391f30), +S(35772904,91661db6,340e7d1c,a98db8bc,2f50f557,283ccf11,8e446f71,925ade9b,fd8a4a56,b82dff95,a59e29ea,bd5d8e8b,a876bf95,4abf0537,60832d1b,d7edc31c), +S(60e4201c,4dbd9c99,c5eda030,f041f51d,f648f77b,13ec2072,4d89b6be,f249d793,ebd96057,d60b7cae,71349c51,1a3ca99e,847419ff,cdcaa0c8,54d75d40,8263d81b), +S(f39d686,b17ad518,3a7d300f,1bfd015c,57541f08,a96b5943,43d2ef82,bf20bb6e,f1298c9c,633a958a,a0d12b87,8c95836d,f9f93b5f,5e3a6bbd,93a75ba1,1b96d4d0), +S(37ea7dc7,2a3a0b4e,72412814,bc1e1233,17ea3e1c,c4ede35f,cab5d31c,93cc330b,aebaca93,8b14b315,708360e,5662e6a1,af25069b,cc07f581,225dd131,c656c607), +S(ff1f61ed,ba3cfc6f,2fdf3043,37205bab,301c965b,501e4f2f,fcacde00,dd127b25,fb1edca5,90e00f87,eeb56ef9,94e9bb12,b64ad1ea,f5ef0afe,6f0125b4,e100a483), +S(3376e0a5,b93f15b6,c46b92ea,e313ea2d,c5d0b961,a2623487,8919cf5e,25e9ae38,a4cfc1be,fd24647a,20ae014b,2041ab3f,6cb7585d,48a607f8,299e0c10,96bcfdf1), +S(be575f99,842187b,30bcb312,987ea218,3d613442,8878804,b5e7d920,12e58d9c,154e02b0,b573c81b,d2079a4f,4a6efe5f,5f37502b,33225064,4eb38b2c,3f0a1767), +S(5a215836,f1f2997d,9b09d4d0,6473c55c,46cd3006,70d85d6f,6b5531aa,c8da043f,ef5fba1e,b6e1deaf,bd83e480,fcd4984d,cf60f91f,4799e8b4,3f4edd15,f94b6d33), +S(d73fee2,16a503e3,a7d6b0a2,675adb1d,197c3fae,4d43835c,b6b043f5,d44909f5,6f2cc9ee,fbc36b4d,a5b3e704,c13daee9,cb81ce9d,470f1290,8b32f047,ae231053), +S(26fda2e4,d07ec613,ded58e14,ee84e421,ea58e5b9,5beed698,d847f6a6,db185f6,683c0002,bcd6d8b7,1d06e592,db4b961d,f2518fbb,47cb4ad9,96020d84,ed8a5909), +S(cd3d4e87,e433f2b5,5dc55c6,a3f280fc,57f899e1,f8f0777f,32705f3,eb24551c,2315d85b,7521e4e3,8e69f29b,a49a3203,abc7f280,ad49365a,4c78f21c,3ee12542), +S(652476ac,2c9b871c,e108fa13,6a739766,879a76ec,60d787ac,a1b7447a,67f8afd8,b66bf6db,cd3a1393,f70ac7b6,d53069d2,5f084dd7,f05c97a8,76f7f646,c7b67fa8), +S(61ab4f97,61c96446,ea7a75de,7ed36224,7b5ce8b9,e7b442c3,432f9fa0,ec74355e,f391652b,17a910f,6d476c29,89e854f7,d31a5f31,fead5fbd,5013ea56,e44985db), +S(36e4bb36,e62f78a6,a6155351,36a73637,13fe8be8,1c8c3460,a94bb642,4f7c80de,12b38983,c10079f9,b0016df7,fba0685d,5eb87518,234c65c0,7dff006,dbb6a563), +S(f5e4cb89,101e90d4,b2f50097,aa0b22fa,df076932,f4045e9b,7a9ce8d6,ba178780,c12ec4ae,56db7971,3a1bb0f,2559e3a1,de3f8200,650c809,74101940,181eb52b), +S(1138ad12,333790f9,20e979f6,a6471274,2a9bb567,2356e3c,80ffff89,a9de533,4caada48,a78ae26b,790f23c1,606a5820,98642f4,bab5bfff,95748f6a,2ccd6bc), +S(e0346d21,121ff741,fe4eaa23,938a4347,a71df442,9e55359e,aa20d691,c9f40840,c1197c8e,c36676a9,28a92b56,811845d5,d9632c65,9142cc12,3c65e54f,c282dbd), +S(d42011d6,1061388,fec6b7f,3f332b20,24ab318f,2a9ba7ed,23731207,3e32478e,451a2b16,5c82b1f3,e4d2a0a0,bb407b84,904db4d0,caaf733c,e31fa97d,2fb1735b), +S(63964eee,619074e0,780140fe,2e90836,e72328d2,448386d4,59c5be23,187f5048,c49304c5,947630be,5c60064e,3cb40436,c2a7f46c,b221937b,c7c5d7b1,76cf5e37)}, +{S(8f741868,43906722,ab9f5c6e,c796573b,622fa2ae,6d985bfe,ea4d51a1,8f141792,61ecd858,d6992c4a,bdc22472,fb8fd242,929dc5b5,36ea8e35,d1c8c513,bcb9e31e), +S(f2dd67e5,6f75c397,76b29366,149ba4ff,69385651,53afb385,3853acb7,9fc2bd59,3a24641c,d48ca39f,fe992bf1,50291604,79066af4,a0cf364c,9e52a9f,9b51eb66), +S(9386aa5e,c3452728,a8f65141,e2f43a14,c250173,9349c96d,e1968a4e,48cd30,a3a38a85,4f68048,d8f81002,3eef9966,780262cb,aacbe859,a8fc66fc,27c37f32), +S(6c9901ea,920c0f4c,ce51fde7,ab283f98,eebc30dd,c76a3219,1df4c4c9,db467aac,6773f8ae,e601201a,84dd4485,fa560e22,81d5eabb,25a3b3d8,525f4a56,65f79d05), +S(ed1eafec,876154e0,58597caa,8250b0ef,7262ff70,b719ec9b,63c0b2ff,9d167fe3,73505073,2b563f93,89078cc3,93ff9837,227ab8a6,c7d789c,6d2bc835,2018f77b), +S(515806b5,13d4d4bf,83533b56,3b39bf9c,4e808426,f2e4cf16,562e759,cf2d56ab,83c2fb,673a08a6,b8a86b1f,e1ba23d9,3347903a,d6855059,130d8d39,737ddead), +S(30a726d4,d8db1cfa,d59331a0,8f4b5376,36848547,914dcd75,37a80e40,109b8e35,8f628b92,6a11ddc0,dfb1cebb,934aeaa4,3840d442,a61145d1,803f771f,7bf65d7d), +S(116867a8,d72fb00e,80a6f267,e8163770,34affeff,36d667cd,38219f0a,e3c9038d,270f15be,b2a3d50a,4088720a,e9a2c3dd,df00817e,31e1a5b1,d850fe23,dfe51657), +S(abea2899,e4575c6a,201c96fb,a60a24ee,1f1fe0c9,b718b54d,18981938,4f33a1f4,d43d54e3,9e8d433a,ce66ad94,e52662fa,8013e778,f8bc2e3f,31938a6d,5681c660), +S(1fa796d,9f658aa8,6ccd0fb4,6a735651,102e3181,302e371b,8c965dd4,5f078b30,69815d18,43c3b4d9,f7fa4af7,3d2e5dda,390e5372,28608912,79826a53,a437031b), +S(f5022faa,c8caa29f,304ab6c3,d00931c5,e09085e2,73beab04,c1d18f87,1c0fde73,c6abd143,73213fe8,ffa5ec64,8a22dddd,fdf2cb25,e32afd58,4f92dca7,838e8249), +S(8190b10b,97bc72b9,301b1dc,cc60e69e,460e389e,ce7d5d11,4e2284de,853ea02f,f1ffb850,dbff0f06,561b75f6,5d2ae823,cb13881f,d1150eff,274db4cf,112d2253), +S(ea230fbe,c58d7e2f,1a3cea60,f9018562,d2fefb49,8efa312f,4beafcd3,139da094,6045d69d,b27bee6f,3357180c,e92d3866,b480faf4,2debc033,cfa118fb,b89c3bd2), +S(333d063,ccef6aa1,f78c81b3,4a84975c,82bc2cc2,bb897608,f0bed49d,cd08829,90ad105e,f72b7e4f,a927240d,9c69729b,a0aae3a2,3a45342,3be2c385,488840a1), +S(4d95cb48,58d808a3,be82f42c,da4f64a8,c64ae176,3b50257f,2e4ae655,fcc4802,5f6efffc,99bdde54,6d8ffde5,e9a551d0,121a39c3,86db540d,1caf74b4,894c5559), +S(b87b5eca,6e0111bc,5b756816,fa82acf9,77f81376,af796cdd,1e8fcb09,4d363d1,442fa845,9c2a7799,2c09015a,db80f26a,28428851,62432660,56026009,5f2f9d8), +S(34baf43a,a82cce1b,19945590,ef3cb582,2ab03142,6538ea5f,74571582,ee14cf00,9a76705b,c0141e29,75d11543,215377b5,3c051c31,156697cb,e8f56721,da386e2b), +S(f07c5d98,a2579c17,53b3fb58,22a139a1,53e7deeb,ae9304b,114bb188,d61cdd0a,ec18ce0c,1e51b8bc,e12f3d85,23739f8,bc25708f,32deb81d,a780cc4a,1010692d), +S(9a146c80,5ee261ad,3e708885,aa41041a,53bd3758,b3d1ab7a,1a44aa7e,29acca7,fc553e71,4ad8a192,90f94ed7,7c171f9d,9ad9a047,6791f045,4a3ab7d3,f8834f02), +S(c8088409,650feb74,9f9fe21,61772279,128db1d7,58610a9a,8b9fc4b,ef9683b7,692a6be3,132a08d3,82295ee7,1c469465,ae7d63d6,c20c7357,36935003,28799639), +S(53bdc8b2,3edd83b6,b149b79,c88130c6,b207f999,e7045285,7e828f81,b325b9d8,a9a039d1,79486167,8fda727b,1706e9ec,7ec3eba3,26e6a4a7,e27db3f0,8a6ee238), +S(fd08fb47,4af98207,3d8b4ef6,d39012f4,78225f1a,bde3c841,6fe3881b,4fd276c6,d38b53a9,100da1fd,1d2a987e,6907370e,7bca492e,98a22e5d,74a10c9b,93a197e1), +S(5c42ad93,2306363e,a0edf86d,31d14b04,c3f7bc09,c9fe1326,d1ad085d,c84fb7ca,1bdbf812,e9ad6486,ff572d4e,de5be4c9,59de7be3,f21e0dd8,76534091,f13ca3d3), +S(66257876,115e7eef,fc0e6132,9f177d3a,437c81c4,1150f86b,45904f86,30bae971,df830e1e,33aeded,721a0a6a,62a3a402,1d2b7ab7,438b7b3c,d834d67,3a857aed), +S(4feea8d8,2cc6601,c847deff,35581c1d,bf1f4070,402bb948,ce9a41ee,16661627,c09a7686,ad6bcec4,ea9ab0f7,8316adc0,7c7a2899,9332cee7,5d70c50d,249a0007), +S(2d3bb180,73f5345e,cff0c901,9a6f2fb4,e0a237a3,9315fc11,fd53c7d5,aec43670,58a9459c,2710ac75,ff2510ce,4c9c5fb8,b4f739c9,c6611494,daf896db,e43b080), +S(bd539f5f,47b25116,7159153,f402e0af,8650c17a,de7c5dde,2d9d9cc2,d0a3103d,407cab4f,ca581f10,eb386e20,9158541b,8649951e,b2f5e454,2a7032b6,53f0caa), +S(c7a72935,87ba5114,744c3d0,9030be19,9ccea57c,7f80be87,bfb5b79a,8f8e200,7c2a98f8,b4526422,b211bea0,875a81f1,d379012,486db005,e31b9682,404e14a3), +S(cdf20316,f4b63ca4,c472e1cd,b3a938be,291d98b9,3ad8f3f2,4f3e1a4d,f1a6cc80,ab993e8a,68988d4d,2749760f,241399c8,136ee9d2,3d4ae7d1,e6d26df4,6056587b), +S(1d341e6,2eca1f48,165bb2f3,86207da1,f2c7fc86,dff7a75,cb63976e,f21bb074,923b53ed,fe2f5bb5,56aa7cae,2a08ff86,160e3344,c4adc09a,e7aeadfd,f31e2b9c), +S(8704f69d,9d335975,f0e3bb83,5aa3024a,60103d89,e5578253,fbb3d537,1983ce4e,94f4adfa,31dbd13d,95c738b2,8a569453,cba45efd,1cfd20b6,78f6a724,e9a8d025), +S(7175407f,1b58f010,d4cda4c6,2511e59d,b7edcf28,f5476d99,5cf39944,b26b64f1,bc4baabc,bb1c2aaf,c92cbfe,ecb33791,4fe01748,8bb8e2d5,bd918104,4dbdc75a)}, +{S(a16a4734,9afd167f,d5e79d24,9784d87,5121fa24,2c3a54a,88f9b176,72669aa1,4df3fb81,7021efdc,e5296735,3a177b5c,51cc7762,4755ba28,1084db5c,4809e02c), +S(91d1abe3,8d3f9671,54337e03,d27fa6f8,c3007f32,323d15c8,31306b3a,30900328,b1b8c71d,b388009b,98000f9f,291b66e3,f890d42c,a5812f34,5c070f6,e73b89f6), +S(61b64b1c,f2a0e720,e9bb4853,537b9f38,66baff87,388df7f9,f14c06c7,12080b96,44444011,b6ddadc5,7ee00eed,b6af3772,e4116711,c3853f13,7f9c7b00,2bf2a1dc), +S(3b96b2ee,d9cf1ed6,3aaed8e9,aca3a464,d6a6fbf5,e6fd48f0,5aacc318,dfdbc87,51c41c26,506cac9e,bd0c5dbc,8ce8788a,3469e42d,de794707,9e0cd0d9,826e9c58), +S(7bbd147f,77b293ac,ff797b9,a52778de,5874b754,c08df397,72ed8ef7,53242efc,3e843df6,75abef2b,e4d32c83,205322cb,f53bde0,2563eb8e,b5dfbe6f,27d4cada), +S(becb7fc5,de84f994,9f97e55d,bdb6981e,f38c0c45,1e0e454,519c9411,5bae3d7,754145ec,ee6f9c7c,f91963fb,5b0a683a,ef24313f,1125570c,c9b9c7d2,afab99a8), +S(87936626,aa88346d,6d4330d9,3a188ed6,992bdbb8,387b395e,d21dab93,63d833eb,a28c868a,18dbe0e7,12ca5237,53f6a50b,9313e687,85f3b31f,ec778fac,87aa9327), +S(e79d4b2d,e33de1e2,e7eeeb44,d197aec1,f5883ad6,1394dd79,de274ef9,76e3b022,9c73ade7,7c661527,ec2ec6cd,b370c130,380bdd9a,4bcb668a,86e8259a,ca85f293), +S(863f0d65,34de1222,237a07bd,ebb066b5,2c1cdd83,d7a6d3df,278e57c8,bb59b8c7,c546940b,99d04ae2,5cf7c881,28a985cc,9b6223a6,ffc06fe9,8a3e0f68,439b9db6), +S(71e9b0d1,3972d9e0,2225bbda,5a1024e9,c373eeb,f6514eb1,c113ef88,dffdc3a,4436c52e,c58a34c,562638c7,8d76e3fa,29e3586d,fa667577,2fe0b932,c4a1ade2), +S(ef4a500d,c9369125,78fcfcbe,3c313bbf,f0323caa,75750b6b,a317e1e3,dd8054e3,e807e9cf,7911c919,fef82e40,a3ae1b9b,ed8ded38,e74126ed,863199de,c031f2a1), +S(806dd4e0,fbf72904,c7b0080b,4e7526bc,c71fc52d,f143da80,e571041,dd964915,2f4e2e67,3348c32d,6bcc0741,2e76f4fe,944f96bb,d73382c8,c6880cf6,629eac8a), +S(9ea889e8,acf0441d,6e299687,c532ea8f,8b9453ed,5fea0d47,f735056b,1eb3bfa1,e43f79a8,4d302f3c,88698896,5fa7b8f1,a92c620,dfcb3462,c4befe3f,4afbff5e), +S(9a990a22,1d27d8f3,40e79489,58cff3ca,2720dd3d,ac71688d,9c3c9e2f,afeee215,4957ac76,db370918,7992b0b,63370656,7e0f4a0a,9e5f1d9a,be8f7d5e,8a950eef), +S(d3291003,98ad3d92,1d6cbc6e,b37ac3f3,9360cea6,23edd794,64d34a51,fa7adc60,657c110,5bd8df6b,fe52addb,2fdfc41b,810a1ff7,8662021c,7c220b0d,b3509d14), +S(65eac576,e149d97,3cbd772c,60570870,e437e92c,2e5138ac,9c0534df,b7a45582,ebecb6a,edb87cc1,417e066e,fef8e52e,c61eb00c,dfd98205,91d63c08,9dfd5347), +S(b6976b99,c2515be2,2bc901fd,8671255b,f8fd76ca,1f3474cd,5eebe39e,98f6f14f,84ab17d,da67b61c,fd01881e,b1087e69,845aecc9,ce1535fe,1c7245fa,8df98181), +S(c7f5967f,f9910e10,54c93e1e,d0290102,9bf31787,15f53758,f5c53cd3,c79a52bf,bfb01210,5c1ec69c,847ceffc,d1105ac0,528129fe,3b4d3086,2b6e9562,836f5eb2), +S(ffa0da7a,e8984e4,d02a0fe3,acfb4e81,2a63d6b1,682dcd78,fd2635bf,88cfdf1d,49459ee5,3fad1097,2da786fe,45a2d201,e4a52260,7779b1d4,23defafe,29e70098), +S(5a53d683,3bc1740f,d02f278b,2ac15a87,f137f2,c798f157,725a4aac,63f1798d,ac5e7ec5,86d5960f,e25f9e25,7cf9ee05,110d9595,e440d032,c416d444,6242d10), +S(70f67487,9b030a4d,9ccc0bf2,90d5b78,c455f8bd,a1fa2b52,efaf0200,6b70a6cb,10f5b1c5,dc46c0c0,68757804,93805aa7,5a259dbd,95b4bd14,d031daef,a81bf7bb), +S(a4baf0d7,d3a53c29,e78ff81a,52d634a,e009391b,30a9aa91,df8f7bb6,13e3c16,c9f9d001,7f388f09,b6802c45,e1fa036e,99443467,c3847937,8b384a9,dada35cc), +S(351b8e4a,dd336c28,5d140c57,9f2b089d,3c656a05,b1ed6,4cdbaf7e,e5bc671b,b996e61c,cb14553c,b7b79803,c82332b6,704ce97,fb4e19a5,1f70b13d,f8e2732f), +S(d248350,92898c0,5dbb4465,18695efa,e59ac007,d58b5df5,bb3b7038,82f18e61,23455e7f,5104051a,44600be5,2e242a90,95213d25,b4fd65a7,62c3f9fc,9234c2a5), +S(d3fc6d75,10cb0b20,77b52b00,93e84d47,54dd1a28,4f3928f2,a9e3cc02,f1869588,26e86b02,c16171d4,4238aecf,666146f4,9386e0eb,52dfed87,7ac0b409,51ced10b), +S(1c611335,3d115906,182b0e4a,7eb3d39f,552c49f0,c5928aa1,15ae00dd,c23a3b70,1c3e3c4e,ed65ce47,ea82a33f,df8fa6b5,532977d9,53aed38a,f0f4dab3,98477c6b), +S(6487c5c6,abb6e673,821c4b0,2c485f83,3e149af1,83b3f025,71a81fbe,660e98e3,63c4f6b4,7eb37ed6,7668b41,1e83d9c8,9ea323f3,2d9e8918,20b65276,a8a7b7d6), +S(1b0baf63,6daaf2c4,28a62bce,bdd41de2,a4d7cf69,93f0b931,222a40cb,9f5f9a2f,af9a62cd,f91e2c6b,47f308af,e2de8f16,def4972f,24bf4c5b,2b1f92ac,f63a21d2), +S(95bbd974,78e1b8a4,1622e460,8aa82fe9,e77d43e7,492a0d21,1146d987,f9b8f255,412bc52e,d61c3880,210d3df7,f0d2f27,d458d51,388803e,fef1c016,d7c9e7f6), +S(a3466715,5b6ea598,2d3945fb,743a1510,c671b96f,a3494a57,e0349010,55ae087,de35a05a,1a943a42,7210165e,55d5cfae,3ac15490,dc6b0f43,34c0c99b,dd778608), +S(2ed76c11,52ac3600,7aa17c85,a5f902f1,7c845a05,a4e0aaa0,7b05e836,cbcad59,9c60b2bf,bc47a0dd,d3259151,37e89812,a08d39fe,cf5806be,eb538575,3b159531), +S(20e6e2e7,96946bb6,30c7071e,f1b92ea3,d53d280e,e450111,5f5da36f,840dd273,2c528501,b0eaa61b,b5f45e52,6878b9aa,7ee13686,c25796c3,3f8302e9,44b9469c)}, +{S(f040a2fa,b839c753,4e216425,6c2e8dd8,57c52dac,e75cab3d,512a7b1d,562075d2,9e211cf4,bab24e0e,f745e2a0,9b59565b,be7b2449,8123f6b2,ba383b25,29554b36), +S(c66813b,904831cc,12f89e3f,bde93eb3,11ade6dd,f6cfdf72,21cc61a2,ff46bf26,3b60c8c9,9da35a58,7b9650af,f85ca785,ece41146,e7ed8d6d,ef8d26d1,f3d055ce), +S(cd38ece8,7c7a9cbb,e23b58ef,59925633,734de285,f93b3ac4,eb01e03a,adab904b,a5f48fcd,afe414f4,1a44917a,5dcb80b9,30373af9,70e9f22d,c1af80f,a8b06320), +S(72d6f7db,199564a2,6e823a49,eb0171cb,ebb76a2a,add56c7c,6d3102a,9c3ee18c,bd2039ec,c390839f,e2d4451c,9437fef6,3e98dc62,3ab0eea4,c56376f2,e270f626), +S(2ea6c313,1e101867,2454e15c,d34d5fad,13829d5,4ca86062,f074e512,a274167e,67e3d34a,56f12e1b,43687f51,c2d56395,14355d7d,9cc52726,22f62ab8,91c8d5de), +S(d66bdd78,8b20da57,b2485804,a2f6e2ef,78c7ca87,ae1c5c66,fc533533,5b624162,1a8688a1,300e6d39,e130037d,3f074ccc,57addd1b,88977e64,2ab296ac,d6e054c9), +S(6d6458d5,d1683d85,8f9e40,15e5a94a,73868bda,54f6139c,446b5283,6d211542,e44c7ca8,33761e13,ca5458ff,dc682f22,3819411c,a3c5feb6,24f06412,471b9f5a), +S(49f8063,b3d98f6,f159f2e6,65b0e07,8ef8c7df,44da06c3,55b592ac,13402b9d,b0b2d838,4b24ab11,de895013,e897e825,45c3e8dd,6cdb0990,555cd871,5841f8cd), +S(8b2fb6bd,e60449da,2684f8e3,6267fff7,254051ac,faea37cb,102c9bfa,91abb2ca,c82cb9ab,c33c1817,10d3fb19,60f2850b,5072eb47,404266f7,c7964fb,f98027d3), +S(cf90331d,73644476,47c8f86e,eaa6e67b,f3fb4b3c,4c895b82,30ab2f38,80df1e42,9c493d94,3471efd5,ea90f723,db576a35,8cd1ee6,1a119b56,6c65b16,112eb2b4), +S(e70667cd,8d2759e,43f99417,ecc505a7,953d80dd,e7ce2cba,3c8c948b,d43a912a,92a534b3,51449a66,82395a3,b75877ae,851923a2,e791acc3,7293d728,777a2247), +S(4cc07d11,4a715e9f,4b4d0811,f0337c7e,f4bdff74,2fb008d2,1ce8a9ea,50520d47,478b279,613d92d3,dd24ae31,2658eda8,28a7d628,f0346e04,5d5d9dff,7178f093), +S(2a1cee60,4cdd3b2c,1f859bfa,af63d7e3,9aaad910,92c2a38f,a9362798,9753c30d,325c248e,d409e8f3,b96dccab,6fdb62a6,83b7eaf3,36d2864e,b821663d,ed31a6f5), +S(7c18d0bb,9a01969d,302616cb,bad8722e,d00103fa,9985a50b,765f0e2b,9a2ea14c,f6365a6c,b06e4749,c48c212c,63fff571,8f46e0cf,6fdc8c42,34d4db64,ceb72080), +S(a706754,65cde407,e853e882,8fb7a2fe,98638d7e,64b8df0f,b0a7a0b4,e629d0ee,fd694b2c,1354a5e9,415926d0,1590eaac,dbd1b36b,5ecc46b5,72467c3f,e2cc5393), +S(7ff57a63,36ec73da,cc1dc527,928cc6ff,4ec063b1,56b36292,23b8bbb0,a8ba2c7d,4d6dfc43,da0fe33a,1e75dbf5,5e5d669e,be6471d,eb8a4102,6db1a41e,9d5da637), +S(d4b1f7bc,87558c27,7e0fdf91,22bfe488,b3182555,599dd384,5cc039b5,93218e9f,992f79dd,c8f46682,5c44a54d,626b352f,7f59139b,d545f78b,44bd0b10,55c3c1fa), +S(897773f,a9de63a7,46ebf58e,248d0c21,10f90230,a792f0b6,ea5a25a0,9d1940d2,b7c7dd27,d561dde6,ca7588b,8e3a09c7,16297ba3,9d501744,f9639a25,b16b4f64), +S(2f9cb312,b071a600,e5d24cfc,79b0fdbb,f6da1527,10ec395d,53078453,1a3b07e7,49260f95,757b9b66,feeb5c20,16aa051,b444bfc8,836fd8a2,ab913e98,731fa97e), +S(5c53b27c,4c0ae241,8569c806,8dd43a5c,6fa23ac6,74d001b4,eee6a748,d86c9e6d,4e0e720a,f430972f,b0ab89b8,79a56eb4,f0af5161,cae83ca1,964a8099,f9d497c1), +S(2671ef50,5a321387,9560f0d9,e8588707,1c2b87b5,d06bb9d,dec3d179,6275b098,750ea18b,dbdcbd58,be994eb5,cb3539f5,8c3dc630,7d50bbf1,f69050d6,235826be), +S(59baa5ce,9d6e707b,b0738f4f,d37c9890,801ed796,a82afb2a,ecd2c5ba,195be65b,e6b66356,20a8a106,b58dc202,10cccdd1,e0e8c579,c92f3fbf,8b335765,b30d8291), +S(bb422d0,88abedca,e4686479,295aa1a1,77d7e68b,293bcd31,4097ddc1,af764b90,a96d33f6,46d4861d,a471f853,e0c6ae32,b1eea619,a7441504,a773f5e6,fc548805), +S(8d7df8a5,f08ba2b0,923662fc,e594f111,5295cf6e,c5aec9ca,df0f7236,fe51b362,26452215,7d8572d0,f057ec9,6f572f11,ebad3fd0,56032240,26b54df2,991f9046), +S(9e2b1637,352d8988,1e76fdec,c2dc8533,6a71b18b,3c98e59d,397602f5,8b9087d7,b997404f,1c0b1e64,90cff078,fdc47c42,aedf245a,e69d844c,18a146fa,6d8c3d13), +S(972c7bc4,6362bca6,b58f1d0b,87c0b8dc,fe91a217,7f0cd7af,404f6f06,47e09358,cfda778,a59d944b,4ec08bcb,3aabd70a,cd6f29c5,204c9161,fe2e5bd5,71d03f6c), +S(f7dd32ed,89ceaace,52e7f26b,202ea6a5,c7e8ff42,6c7ebc16,12106f7c,6fe51a54,7349c17d,d8ea6ad1,cb346e3d,26989950,3de00c11,4205b3b5,50d27ff7,67efe75d), +S(c9f96f88,3e34aed,97351928,fa77b07a,f4b01bb4,e4515f0,59745ee5,decc9fbc,6fd62453,dd6c9dab,10fb7d79,c15b4822,178eba31,258800e4,519e627e,91ef20c9), +S(9c28cc93,809b35b3,96a4c9cd,d6976391,17402ffb,5588cd76,7c41a92f,e971a9a,ca3b2634,28513516,86a661c4,747aece4,c8130d93,ff4108a6,3365e725,2bbb80ce), +S(263a3fca,437c4dbf,48ca36e6,aa892d61,abf58f6a,d3c82b1f,fe945dc,c45a15f8,604c5bec,69e0f1a7,3e8f8a80,4f762cda,96ba2198,35268887,910c8df0,e83d3044), +S(7fe42dfb,b3466ed4,d7cb8242,5e66b5e1,14a70516,b118911f,9170656a,3dbb04fa,d11385f4,b0a3a0bc,cf09374f,868cb30f,55175d77,2d3e463a,a298b6ed,1e6f6fa6), +S(53f2432b,a8171714,3fa9df3d,ff41ced2,4a29b314,bc5a8c96,f5f6400a,d7c0979,42ad1004,3e0f8648,332b1c1f,6ee4f821,b42a5b0a,361747ba,60816f2,ac84c58d)}, +{S(b8b52efd,bc367a5c,a1534bb2,f339a048,50fc4941,1668780,dcdb8b51,2daa7526,306a2236,856070ea,1e0fd846,cd571889,e20968cf,cd490bc9,facfc4e5,a5970b2a), +S(27e226b6,ed59c89,5bd20232,bc677c35,495d9601,5f37493f,5075718c,2017e42c,a130a5c8,54ed8ab3,ed657e0f,ee4a04cc,1b59a291,6e96465a,74b36144,7cc621f0), +S(1733f1c0,da38fa79,a7b37988,1822ef51,2392d8cb,59d1ad1e,afaf535a,e151fb64,a93ddb00,af779565,eeb230af,815f9434,958ad39b,387d9069,a03cfcb,8563a920), +S(e3f4b777,d06c8839,c63dfb41,73281787,72debac0,ed45b991,724c19bd,85ab3c58,2d6a84ea,745decd9,e6444b7a,dbb59fa3,21957b7c,3f8141e6,fd633d3f,7539dcdb), +S(a2b42fb8,9ac10df9,ebe804b6,c105e855,25cb05eb,7407d383,3031e216,64491ff5,d0973dbd,346a87b4,f4ddfddd,12be3131,e6c6a397,8e17be2c,bda23683,62f80765), +S(66d441a2,6b28378b,cf23d33b,ffac1163,7c23bbb7,7ad352e7,ff5cc09f,41bf6e91,982aa46e,5fa0b19a,28ecfdee,539c0ec,b5f06e2a,217f7687,6c3cbf1d,e92a6068), +S(3721fccc,20338f8a,779aceb8,eae3fc7f,bb0e4040,1de2c8e5,27941ad7,f789d0f7,d9516c54,8f457b6e,d44f6bbb,23f36c7c,e6fdc548,60e5042a,b3dd4f67,ad5ae3ea), +S(959e980,4618bed2,73b5cc48,5565df27,b8e09c9,a128a9e5,ea92e347,66e02015,cee3a227,1bddee01,3582d65d,c3e26c8a,f80a4601,abcff432,b1737127,91ca15a4), +S(f2e81d16,c19466a6,1b56931,935d03e2,aad6b8d0,7f193d97,bacdc29e,13cdcf38,afb8e973,8d563dc4,1e7688f6,c6b43b71,f366b576,9479f093,88fd09e5,faa1063f), +S(98305a48,800f92e0,bd815192,7b8658fc,60a97c64,c9f97383,68812614,3563910e,d32db8e2,6699b969,5b644c08,39f2399,f8ef45ad,a0d857c5,2d0c7c3f,96a62993), +S(8dbd4fba,113c50ba,ff3f251c,96aba9c0,440d8e69,8a1e4ec1,84fba97a,e497c443,f642b1d9,b012eef2,40c6ad38,fe441d11,cfb42ec2,a3c15540,45e64c76,c15be491), +S(deea5bb6,c7eac0a2,93e90817,836a3e55,2a7f1354,395296c8,97964c2a,4527a727,4cbe143c,c9fde617,c6142335,4323b9d8,bba13dd7,fbd46db5,cbf4ce2a,11c9c00), +S(349f46a5,8621034,9f207a07,4558787d,336cb0cf,a56c1e67,8dd3b04a,4d717f4b,a6479d8,f7f017a6,32c369c0,8679fecd,985b3c16,ff444ba0,3fe43575,8b96455a), +S(a6d818c9,dc182fd7,81343bc,b737811f,611c8499,e44a6cdb,33a36beb,7e44b545,1a8ee36e,d6e9b191,b9cbf840,3924e6b8,ac3c3f8a,cbc9a0b5,ff965d6c,734d741d), +S(f9cad333,7b82ea41,b00f3ef1,bba37b8b,fcb24e8a,175fe380,8e399b67,d21837e7,cb206854,4e7f2cda,28c035f1,b8b50009,319797da,bb498b99,d31e24e2,4fa27ca9), +S(25042b59,f9b29a9c,83d04515,c78f1c25,5b72f97f,7b387113,e88c36b9,9da3ebdc,d966ba9e,a7eb9734,e1481cb7,2df63252,7492e1c4,43f1fc9,c0efe0af,442b5a13), +S(e19c4319,b5c9a01e,b588c629,8a7c6b76,1b80bf4b,e39424e0,666ddc45,fd57e0f6,1b0a2c30,4a1bb1b1,9dd0b50d,29df625,bf958a73,46cc6b1d,81a213a3,b6636285), +S(59c26fc1,6d151c0c,7da0edf6,c474463c,587c45cb,7e407589,d15aad89,de223fa0,f7b227b5,4855c1c4,1e576431,8a7106eb,ea214686,ef815b42,db8c18ae,d5c940a5), +S(d967d546,e07ac1c2,31fd50df,a1d25a51,60594d88,3e816f6a,bd62c15c,446aeff6,8eee6c03,6e22a014,5d9cf3af,9b44e005,cd1d36ce,d7c420f5,e2db918b,e4fbf83a), +S(424b149d,9104254e,3f5772b3,7d973cf2,a46bd110,89d8f850,7666f04d,382c972b,7272ad07,54c18fbd,66e2abb3,952c526,d8113d5b,166283a3,9ac8ecb6,2b7a3e46), +S(40b4b2ac,bd299270,e64bc470,8607c586,3bb50913,45e573f3,a5e2461b,47dbc053,d094311e,fd81bb1f,4622d17e,68044107,a2a8ed54,3cd5ff8c,b531b28b,9b8ec99e), +S(79e79ded,6bc0d851,fa769b5e,8d65857c,f3c1c18e,6c990cb6,116fc45b,63e9f924,4fa89e89,ae4214fc,ba2aecdb,41984788,8154eaa6,bcbbe29f,f04a6262,7299f469), +S(a11ad5ea,59c644b2,8dd7402a,5f96a970,68d96e2e,eb77d59a,fe0c2fc,cc6b252f,38e379d5,150109df,36ed7ad3,a2daa41b,4fb9c731,718cf5e3,8f8f8cf7,d1f3d770), +S(b3002b00,ec5be154,cd8e5226,4b97f5c9,f444b305,8f59c4c,bcda5edf,9d10dc88,f7e9ae65,6ad2c823,8e8e0436,e007d821,b17d9405,984eccc4,617e3977,2f25d636), +S(8d1267b1,94da1334,fd20cb8f,77fa01cf,9e9ced90,43107e41,d1ec4057,eb6115a2,a7ba1b9e,2c6f0f19,5ff1f50a,7a8da22f,da3003fa,44b818b9,953b44d3,e6d6a0df), +S(dde6a3a0,87ef41db,2359e4e7,ca7cb064,424301e7,c5cbb5bc,4b6e504a,f3af4837,24175b1c,b4b39b7e,23718e26,be4a22bb,8bf54302,1f156234,e7f18010,d538aeb), +S(79efa584,2fb89f4e,85f556e,c4be170d,5c1ef88a,3f3f75cf,6b20fc1a,96984ad,b0704aaf,e4d8f30f,4f29fa85,6d55da13,91f5f3ce,36cdef6f,25133999,cc8541a), +S(3aa09dc0,5546977f,7369fa0a,7b60c94b,eab86a1,10d85af7,7b826475,7d67eaf5,343b4cf3,aa6c5ebc,ed041d7f,2381be57,f7fd32d0,29a2f42,a7c8821,4f425d8), +S(53fe8af9,8f9419fb,1445bb6a,94750d46,46be9f37,b7155763,88b11064,df2e6ffa,6cd77e81,84aeab9d,e9bf3093,bb9b21a3,a04a0719,fc428f3d,d5e14c8c,9b16cd7a), +S(fc395dc4,a5114dc8,bcb0f7f0,3a4d3e9,38a87a3d,78d33864,d1dc4cba,9e41e20e,c7991f6e,f72f82f6,b3147e56,74224929,fddeb8a5,97a1b1d4,8852733c,1830b941), +S(b1d25d51,b4558f5f,d0ccb868,3af9a9cf,62a169c6,91627fa5,92d80b18,36695f94,8f92258d,fcf16f4e,8415f53,e65457e8,9f090e72,5479c123,5a481464,a11cd4f9), +S(b866d6b1,42df940f,2cf28b54,c92f0c12,94e0b6a2,2a91f2ef,44bcd88c,4384480d,e6eb4f4c,bd95148f,765d8728,15652853,db1add7f,b4e27929,f19a64b7,f3b34c87)}, +{S(d4aaf32e,dd897f48,5ab16466,76d747cd,fec5b7a0,a05c917b,60c07311,45d16f89,4857e649,beff4089,2470f700,cadb73ae,d4866a84,c3f0b975,6fd8570e,df9d29d8), +S(4ebe5b8a,f3b1583c,9f41bd98,afaba549,f45c381e,c93ec9d1,4a543d87,9cefbaf3,63ed1d17,9b215f34,f1f580be,4b3f671f,2fa14689,74cd03d1,19fadae3,c92935ff), +S(20df6160,556dd3c5,a26620a8,70ff5323,cbbab94,be3e3bdd,ad8b936c,554f28f1,7168e7ab,cdbafad,26fbb5be,a09dadde,ed36c20f,c8deafaf,75a480b5,f980e981), +S(86c663f2,cc6f7ee2,50be25fd,fb35fd8e,5873481b,c477bf5b,c0f1bc1e,3f1320f,c13c5795,cce0ad92,e31240da,90a823d0,d2352314,f2852e67,cb62e0c2,8570994a), +S(3fd8085e,57f6870,b25e41d9,7df00126,150f6022,a7ede22f,d27da581,d234ccaa,c6657746,98d6ac03,ed1ea2d7,bd3f70be,86351c5d,407a4d7c,227fd7d0,c330ef04), +S(1510fcf0,b0fb5a23,c15e041,2a7f6d89,9fac4244,8ce316bf,d88fb58b,10e23118,1879dc07,b34d0a62,f0b9517f,3629ae0f,e8aa6d30,5a783f37,69bdf65,3b40408e), +S(67e9982b,c40f427,98df055c,2d8bdcc0,2ea97bad,68d34024,85498e27,d99e19e4,4f087caa,efc5fd7f,b099c134,a273635c,d1d5ace3,26e3103f,9b2fe22c,e95f288e), +S(e8eeab21,6c3395d6,d16338ea,de4108da,1c25e471,67fb13d5,99e8daaf,93e7345f,7fd2ba87,7c7266a5,65a31548,99950ea1,e5e3d73f,612addea,318ad5bc,a965228d), +S(ab20c7c8,9dd74c20,447bc762,e374c548,e7a8ac31,eec11123,1a040cd1,36e9a546,facacfb2,52eb9532,9106a26a,60128a0f,ae1d7e5c,fd39483c,aeb54dd9,231b55ee), +S(a9004211,b7cf5494,1c530a0e,d658fb6e,3b5d2ee1,37b7d7de,45fef6b5,efddbf0f,58cbaf67,5cc5a131,54eef7a1,462b5d1c,408d5d56,3553ca55,45388d77,c6391d4f), +S(8db64274,422ae0f5,6474b83a,89912fa,e3a39b6c,b3fb8370,308a572e,b6b3c020,9b71a72d,431fd44,aa8632ee,23bc678,61d96edd,b7ec72ab,4b1679b8,a4ba73e4), +S(301b330,c478189d,dce4314f,380cb2d8,38bbd416,5dfad8c4,90f2443f,2a56148b,737da0,1c05cf73,db36a1a4,5005f562,1327167f,d3b60ece,3da3705d,131903fe), +S(b9cbc7a3,4a1cbdd1,300e789d,b7ffec1c,dfe1f738,fbe1fe19,67dd7c14,92ee3ba7,5a816a0,9d08c4be,2b8d062f,200fde4c,534fbdbf,854c7e53,64532c08,60c97c01), +S(6a15e51,6f9f0a7c,25f2eac7,649285ea,d86a1e01,5a386dc,c7f94ba8,4782b45b,63eafaf4,660642ef,988aeee7,642e7c4b,71124a1c,2ca2f5c3,d4f2eec9,ea72d70e), +S(f4c696f3,34c56e08,2ab2e627,4d450f34,fa7fbce,29f3e14d,332bcadf,87d5fe0d,6ee44edf,f574d9a8,363f98b6,b863a648,27d3020,1e652935,be12041c,1bbcc7c3), +S(d2f3d5ad,237ba177,ed312bbb,1d02fb2a,e4bda20f,41f5c217,8b70dd9a,c26ee9b0,cc5912d4,2ea1af01,aa914b98,8c42cef8,46a5a059,664c8545,fc00b662,e0327920), +S(5588b0a4,757beb33,e668af5f,adf87fb3,2aed8e16,e6ceabf1,1576ae17,c6a2b843,70d8961b,ac203e89,c437b88b,ce331309,c4f7eca8,d614299c,74aef9b2,17c741de), +S(f993cd07,f6eb75ad,d41426d5,cc653886,18dde1f0,88aaf3cd,b2631eea,158373e0,1e74f804,5f60349e,a85b90e1,206f0ea4,b0cd3740,861186be,648063e8,58c2b395), +S(2cd04170,78291a50,750218b9,44a11a64,1cb75e7d,cd5cc4f9,64f53c8d,a1ef08f4,1f54a70f,f66ce343,c7ed3001,78d7b99e,49129e23,90b5a026,7ba25af5,3467b6d3), +S(52fc09a1,d4f0cc2e,c7ba6cba,1b30e1f0,b9e37f31,3bf59c33,60fc02e3,3b0c15e8,9bd14bcd,a7c7b6ab,dd7e17dd,ab81a1cf,846be336,a76858a1,8e8a0194,776f0a80), +S(90d29aba,764a9b49,1e2878c2,9b964bf6,e510af,3dd5aeb9,3fe29e13,b8f03b23,396b1f6d,e9b8fd1f,463ca064,11b09823,26cb6ab7,4bbbcaef,43031497,f149a620), +S(ce1d6e8e,ddd063f4,316cb006,b4a4213d,9e0952c8,43e6e1e7,570a35e,aad7fa53,a1abcd7,e2c23ad0,895c5aa8,82a805cd,1d7d434c,72f0c528,2ceec0b7,a7016f7c), +S(4df6e1d3,93a4be66,6fd88c75,e1e686a1,e2cb1844,f5f1303e,f7b0a751,99b42bf5,262d8b9,f7e202a3,78a51928,91ee3fc9,f269ef5d,e14dd0ff,f1fec9f4,4cdb9058), +S(f71b9bfa,bcc353a4,11a055eb,a7d6f48f,47c4e437,96382bcc,d5b882cd,a9059638,bfc1c3f8,fea7df8b,d1cd088c,b1f02e47,377d6656,9b3bd8a2,8b457ba5,e6453468), +S(ad5e9212,d3ef76d,8319fd98,72ee753f,ec99fab0,6244f4e2,a9567068,a635eb53,65fb538f,cb570092,7b0f775a,73ffb0c1,4e6c2274,e253f3a6,2dba9caa,27a3e5e4), +S(81a7dfa0,7659fdbd,57e1c8ae,20c14a80,ee8bfc51,46caa8db,b077b653,23bad4a,ac9d2438,3ef0d99f,26744be4,77e69d51,49d44ab9,84801bb,759d3a5b,7fed1e2e), +S(3bf8c1d0,a613316b,e90eab62,6788c8c3,b1641d65,d0e50245,9e5b19c1,ab1eb617,e1edb59a,8594d73,669e6f93,ca10e210,1254946b,8c9e8eac,3fa84a49,e4e2944f), +S(30f9283a,767c551c,e9fe87d9,5730eff6,fc302a4a,1810e4de,11ba62af,fa17eaae,1f383ac5,e714240d,67980617,d96b0c05,76008599,f8e3fa04,d57454e9,927e729b), +S(1c5d4ac6,91d37d0c,9db5e071,c809a59e,99056263,fbd83028,ee9530e9,c2b3f3c9,b98c7be9,7a2fb196,3d3d4a75,4f7fecce,2fbeb8fd,cf23c229,73b6875,86bd276a), +S(3dfe48e5,2f055be1,1db79fa4,501b44d8,f5ae8447,c5a1293a,a79f683f,1e1e9bf,2d7e8303,b988fc17,18c9b64c,1c03373d,27fd0c32,13c26e6c,b684ca94,49f79d5e), +S(adc4251b,c3ef6d5a,a4d6eb22,46ab2787,bc835b65,1d17ceae,489f181d,57d37248,4f0c489d,1c3a1814,a2f9c1c9,d6fe908f,4623aa44,ebaf4143,79fb8352,15234014), +S(edfe16b2,db401803,11f98920,7a2fef7,d05b2a3b,b676899f,9c6e2192,d38f93e0,1196fd0e,35a24c9,6b28b055,b4fa2f2d,a4c2aeff,3b91dd81,c2fe86c1,1d6bf682)}, +{S(b4b57b34,6e1b41b,7394e655,e059cc93,44c5d83e,f0ef17db,2789db5d,13777b78,6fa187a7,4d983b7e,cea6a268,61039430,63e599e7,cba73144,fe3eb23,677c6265), +S(9937238,7300054a,1a8713b7,6942f003,99818b28,6c6fba5d,ca60b9da,1aa7767,6c003e1,848ce30a,65601eb,e7b76acf,b2e122b6,882d7439,f463c042,ef1b31a), +S(ebd177f8,b5757665,58851c7f,a7ada38b,e3596080,f2679181,f994efd3,82714784,d0fe8eb0,97c852f7,b284d5f,bd81f77f,79c35af7,cc30338f,4e63211e,9e20a244), +S(367ef258,b279f923,a18215b7,67d396e4,c6bc874d,2be6b369,b01afffa,2e041741,bd961242,2452eddb,33831dcf,fb3a0273,30ef141f,6db77d91,5bec2ecb,553b6e6c), +S(d89f40c4,f752cff4,5bae5762,37f5096e,f27d46d0,d934d4de,c3011a28,59464e8e,9d32661e,e2319d6,f6427ea,a3014b5,cf98306c,666c4a9e,970dba2e,65e04886), +S(ef6ff862,1d84c5d5,22e490f4,db21181f,a17bafea,3e097868,4f1f0215,759772b9,ae006f11,aa85db2d,3624cf51,ae319ad2,8b4970e7,eac03301,1eb15db8,dc59d62b), +S(8b0a1b1b,d476bbfb,6da1d071,68d3a988,3b49802f,8ffa04a3,bbba1313,17c67a00,d8c74ae5,65c38597,8d9fda2e,dff6b932,1512e40b,ec5b62e2,59d4d81c,9b657b55), +S(9aa9250f,12ffde38,21384434,849d7eb7,bcafbae5,9a3b861f,68a3addb,d75d3715,19b4b1a8,8d8bfeee,38b54564,30d5f73e,ed0365fe,49092d4a,2f52fa12,b65e3ac7), +S(aaccc00f,55e96f0c,e66d9b43,12f9abd2,6772d8b4,30a6c62,edd2aab4,97acbc22,5af203cf,97d11147,82374056,f012f5f9,2825476a,820dce2e,6e1c4b33,cef5337c), +S(43c34546,2836b544,ddd6e432,6aa19b4a,9de7fdfb,86f43cae,ce98ce7c,32b1ccaf,dd518249,f1fbc1c7,1f905860,17a6f60b,15be97d4,18c66d42,f4f9adcd,d722c096), +S(9a38eb25,935441ab,8983097a,d58c821f,d784f091,5f85dc26,3f0c020b,b80c39a0,d8e6dc57,41e4ba5c,576179e8,9a6dcb4a,bd7178c6,13a1100b,e2bd731b,f3e819e2), +S(6b10527,204a4f7c,e8afcacc,fe771634,376f18da,f12774e,50f23a90,9efe0223,b443a451,529b4208,c8c98904,f5eb2ee,2e2ede2d,80ca50c5,aa29b95a,714181a), +S(1a88fecc,71d7550a,abf7faf0,8e884e95,835f6dc8,1815d2d7,7dab66ea,b238d6b2,82cf6711,1dd38ff,d0daebbc,ea2c064b,17b6b21d,34804f93,4a037936,9edec692), +S(a6b1751,f30507fe,5927b6d4,a92ebbbd,77358c02,9b750d05,a56e4d41,efb99144,ccf7c048,a2a0983d,fdcccfd,a071b80,e8035866,c479ea3a,3bbe7c80,12dfd618), +S(e186601e,8b545292,f23ae7fa,4cadc80f,1fcaa1a3,430ddec6,cfd2af47,c835cdf9,fd471f16,7c3683c9,2e5fc0c2,89b646a5,c8ebda6d,5b6da213,d862c3f6,2c292e9c), +S(91b3935,d8ce2b80,c179ee0b,87850140,4c418c7f,7cf94e4a,64b9fc9c,e396a093,45a5043b,8184546c,9083982f,550807d7,d61fe677,ce73ef21,9b3aa573,97c4eca1), +S(3fbe61fd,2a387654,dfc428e7,dac09e91,5e1ae7d6,d3794288,743f2535,20858ef5,206fd9a0,e3265118,e0a6475c,4df87e43,cc7c8898,59d8aa08,23b6dfff,b68b34d7), +S(31a35020,697d9d52,55476289,ce4fcbdc,4e1e0690,c2c36d1b,a4f4640f,e4c5ba18,91f660f9,159d463a,857f08ad,fc3c5ddd,804507c5,92f73de4,2ee44555,da538553), +S(7dc6b83a,10f26e71,e12c0bd,7ebcccc6,61b4394a,68f576fe,bfca1c23,256e8aa2,b4796977,bd386b98,f3e2fa8e,798b6548,fae52a80,40bb12ea,7e6ad675,64fc8736), +S(67a9c3ff,9c7b99b2,5318ff9e,2b85ee23,ec244655,8042ea8b,d880e23e,7d3ce221,a7bcbbbb,895ca7b1,847a43fa,98809ce4,98016123,bbb3c099,7d34debd,cb023f8d), +S(36602997,eba2c6c5,aab4cb65,8d4efd46,65ab3965,f643ff66,831646dc,f6443bf3,c82d0e80,ef775f9c,7ec7862a,e3158556,a57038d,e6850dd1,e349629c,2546239), +S(9eb9244b,299bfd76,f63bb140,ae2f42a1,4af1e072,83f8259f,6478ac03,d411df24,e43f91da,13c2ba21,a9d17d2f,7a8a629d,9051346,93a6552a,538d590,9d2bdd38), +S(ba4450fa,27d57993,3d949a1a,66013906,7d1a9716,6794993d,e45d9426,b4bfc5ed,8e3f3b9b,d8cb8210,7a5ae2af,92b96259,b73633f,6528ac04,20c3e101,6bb6d8a8), +S(e6d5335f,b67abd36,2712c7fe,575ee769,53d488b,236e8589,5664fb04,7f385248,9e255154,e070a5bb,e98e97f6,281fb999,a75e68ea,7681fdf6,fea093bd,919aa5a4), +S(63c099a9,300a331a,3bc4348a,a373e514,c84a810e,1ea8a8d1,4ac8d7cb,818eb534,ed7d4029,3cc4a086,b1d40c24,6086109,a02dbcb5,a864777,27939024,6fd6bf91), +S(7088617f,66cd93f,8130eaeb,874c3f77,3bcb0daa,78923b70,a65512a2,992554dc,5a3ff995,3c712066,291ac4a2,dfc2573e,1d0aed56,75ef526b,b15f61b0,d20f8156), +S(cc354aaf,746d756b,9387730f,2f12b999,4fcd815c,6d25cdab,2e1185aa,4aa639b3,fb1dead9,4fd76859,1aac8d79,5c337924,dc155fbe,5cd5c953,4d55ee31,f6d284a6), +S(e7e47c3a,e2bf4307,7f33ec3d,ac1ae2a7,5c669e61,e248f588,590cfe07,3e2186e0,46e9c4d5,4429fdcf,5efb375e,18f46cc8,3fa7a403,6013777f,e450e228,aebd4cd0), +S(c6ed5e63,28ec31b1,37041108,42d4ac23,fbb883bb,349d88db,1d747cf7,325fe9cc,21b8bfa4,b62807cf,d6cd11ed,a38084d5,7bb068d4,9f0dd30e,f3f431e2,b57022e4), +S(331924c7,50b3417e,48e279ff,6ed7f3dc,ba2e121e,9f69f8fb,e64093b6,c38a8cc6,357086be,e4cc0fe7,d45a49fe,41d004ce,80466165,316164ab,3b171f03,b9a7841f), +S(b4319cc9,f3e0d3b,313626ae,5385796b,c49b300c,88ba4553,dec0aa4a,77829372,b8f82bb6,6590afd4,48501f,63de3a5d,8f84edea,35c1ee44,88d6333e,f522a808), +S(da433d5e,11ceccc0,abc5c762,6ce7bab4,2e89b221,f785c409,282de545,f3fceb19,1b67242c,de57efcf,e214423b,506a1ade,718803d2,6dd84d88,97b18ede,590a2fcb)}, +{S(ebae7464,ece277b8,309d056c,cf3775e2,11a77aa,81c316a4,b6b7b953,6f90f539,62a4d6a2,95fdd811,f2051715,322f17e5,1753c9d0,835ef9a0,3e8dc9f5,c69bda31), +S(5b20700c,1af63394,a3e4cadb,b0ea682e,19cf495a,b908418a,d41f4c6c,ea4477f0,8435d15e,34b03a22,ca89c73d,326c2f88,142d2e23,8964ef6d,99287125,79738f78), +S(b2f25f91,138b974b,561328c0,92f50fdf,8a694004,fd4879d0,12a4a6cc,c8059d1d,d9ec0b2d,b8e81b2,f6feaf55,9776ff78,cda3401b,47826de0,ca06e579,9d866c09), +S(64e79790,7783d6fb,321eb785,acdeb2ff,4628270,fec3342c,527c8db0,a34c516e,c0c4da5d,abf3da9c,a8613f82,ca28e84,a1a18376,c9967c08,aaf70bea,7a2f34c2), +S(a50cae84,a08f4f32,4984853a,d4c6bdaf,77eaa788,9cb8fe95,72fd56e,9078ee73,120ecbf,76e47b38,503067c8,36853003,60ed261a,40fdf440,161ef2cd,19786b93), +S(76ff3ac8,80a451a9,6741fc70,82bc4c82,7bd51c08,95eea8c8,b422b8a9,96ba4794,25555d71,d4313a60,b189a154,58e0a40,c643c204,277334e,966e2abd,3a23f6c3), +S(307e5caa,8b708760,3d9f845b,b78f4f10,72c49c10,9747f91d,192f8d6e,70c0f4be,f5992f76,37167e1d,55cd31a6,1cdb4756,85eb1503,34fb6009,e0240a18,fa8302b8), +S(d8e62e47,b28fd165,4d420137,884dcf21,c10cb159,d9885843,da34b0d9,d09b2758,675c75b4,b903ad28,2055a71b,2c470e2b,1dce69bf,ecf160cf,3a027de2,55b723a9), +S(ec5639c7,73dac23d,3008dabf,732dc005,3154703d,26ee3bbc,7689286e,4a73e39f,aaa5ea4a,2cf5c23d,57cdd0d8,8accbbf9,9fd2c213,97bb45f8,83547876,3aab1248), +S(3d928ee3,2065557a,27722f08,5202f48f,40917ed6,c7ac1963,2a122226,8b0cb9df,ece112a4,e7a05ad6,17c2fd83,76f89102,9eb94eb0,930fb23c,a342d7f1,f021a0c7), +S(616228a5,cc6c3a92,cd694cec,4b2b8574,5dfffa90,b2a36d8f,32eaa6cc,2530de51,50d8d140,4d506a78,700f8e82,967b36a5,1b4de644,a8e22271,d509c8d2,4adf3148), +S(6f85f308,e847b145,c13a07be,bebdd4ba,6c138939,6afd8670,733f44a8,969406d0,864bcde1,be36c9c7,b7e04ef8,cd2366e2,b3c22902,5ee7efce,d005ef5b,ff7dae2b), +S(f3d1ecc3,53a82621,1bd78f0f,aa029076,c6ca779,9bdc54b2,128fa3d2,aec00c6d,75aa0cf9,fd0b7bed,19183e34,58142f66,c94a5aa9,3915435e,ae51c1fe,96625ccd), +S(a5918de3,f18cd8d1,2a234f9f,3a19fcaa,2d83671d,ad566f16,8aea2b1f,b9de41b0,c515dda6,43c0f6c8,d8fea16,5d595917,16b7f521,43d3b941,f28585ed,8a49c06c), +S(3c49e2ef,1d2d3464,81e05fa0,33366609,1615ebcf,535f68,be257f35,7bd91592,57901e0a,c8af3a31,aa404987,72c903fd,175c9b00,5c7458ee,ed667f11,57754132), +S(6c45ff2,c0c30320,83c343e6,dc80b4f7,bb64502a,52f412ff,ada521d4,a544a9f0,e9936037,f1e641eb,1cd6f801,a25271d3,cffe67d,c9bd7162,babf9855,9628a9a8), +S(66df5d95,acdf4260,ee0e465c,e3916d79,395df522,aa086aeb,6c283bb7,18296d46,cb1f3deb,8aea0337,625f46dd,903416d1,5647be91,1633c4c0,cf0e629a,413476fc), +S(428bbba5,ef351762,9eee4059,a3339213,40c7fee2,5ccb051c,88d75e53,ba618858,ef18809c,28227ccc,115876df,b3f378cd,374c0670,2c658501,7990e767,922c3999), +S(e8993820,d782657,ed8badc2,d515e360,df336730,860ef49e,65ca58dd,1a385815,feb41189,16c7e8f6,53c7f5a6,5fd7b6be,7a029814,149c4645,847073be,770959de), +S(2b77e42a,63502244,d6c7d1be,54b7857,9e2742d2,7143d689,fa3f70a3,5986ccf1,721e9da8,bee88ad4,2155dc9a,28be505,86648378,1d6af5b1,382cd47d,771e6428), +S(acffce3a,ed6beea3,2ad71633,21e1ca53,6f69ce76,fb5cd394,9d9dcc14,bbcee96,5384c97d,eac946c0,afc85b54,f3a56b79,fe263bff,63e1894c,6d52ef1b,9b456602), +S(e13d8d4b,25bece8d,90a008e4,c004824e,223b06b,7cf65ebd,1215e910,2e67b639,3e92b1f,14cbee57,9640b377,6ed5938f,9aee0e11,b139a678,3f207cf4,6dd7e20b), +S(d8f356d9,d2498eaa,b3fa12a,cb64562b,dff3e270,c7809a31,25a9ae65,9cb1f3c5,a5403cda,2d499a7c,7402b57c,c9f99e3,64f5085a,91fd8cfd,8a67c7a8,dbce04fb), +S(350062b5,22fb5d0a,8c79a5db,29e92216,79b9fbc6,3e1f95ca,e7d087f3,fedffc49,74cacf57,5e79c85b,d7e77a40,796e8750,a3ca57f2,a47cce8f,3d2de02d,b014df0b), +S(c159e630,9ab23135,58ebfb6b,22edaf93,eac8e16,77cd9f3b,1cd9492,20bf8e54,99244263,53f32608,831c6d74,da51d61,c344defe,f4c1e401,6a3db44b,4c57f4ae), +S(9e568b70,36a2daa2,fe7a3a52,49c56eb8,3fe4afa2,decebd60,c6c3245f,17bc6a13,b6643644,274eab9f,5e83c598,14978681,17c5a078,765156ae,3cb65fd3,830e06ae), +S(9bee7471,6b6c1ff5,62c1bc36,57a65de3,99a91d72,115703f4,4c3819a1,87828478,bb23a3da,ed34028a,7d39a7ed,fe2e23b,73e085a2,d6c2e51a,ef2a2076,a7c902ad), +S(c430c044,91228a7a,ea835698,ecf0f552,9aeef469,a36305cb,52902ccd,1c897473,40d0ee56,61cca82,80d11da,bffe97c4,f10c93aa,5e07224c,154b666e,bcd58c74), +S(2be073f6,b294a01b,eda0b0db,6832e4bc,23ef3889,7a859853,5ee726ef,ae0f15b1,6153f846,349c2a98,26008065,8be2a7d8,311a5e70,cc310ff8,7935a901,8d575813), +S(2934de46,a6d921f8,720567e6,b46e6362,36a7ed53,483b13ed,20958452,3225accd,5979698,26927cd7,abfe4c57,c53fc72a,48b71679,174c749d,aecdb057,e6a2d961), +S(4e9991b,92fa8c4e,4e8efe45,66966073,319e80d3,a54d4b7a,b61cfcc4,7ddaa5d5,9d03ea22,21d4d80e,261952e2,73f6a8cf,c31f6091,e5aa0a8f,2281ffbf,1345df9e), +S(ff3d6136,ffac5b0c,bfc6c5c0,c30dc01a,7ea3d56c,20bd3103,b178e3d3,ae180068,eccdc641,7b1bfff1,bf2fc8d3,2269523e,ab89890d,bffe0a19,8f594490,e7739bb8)} +#else +# error Configuration mismatch, invalid COMB_* parameters. Try deleting precomputed_ecmult_gen.c before the build. +#endif +}; +#undef S diff --git a/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult_gen.h b/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult_gen.h new file mode 100644 index 0000000000..283738a5ce --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/precomputed_ecmult_gen.h @@ -0,0 +1,26 @@ +/********************************************************************************* + * Copyright (c) 2013, 2014, 2015, 2021 Thomas Daede, Cory Fields, Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *********************************************************************************/ + +#ifndef SECP256K1_PRECOMPUTED_ECMULT_GEN_H +#define SECP256K1_PRECOMPUTED_ECMULT_GEN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "group.h" +#include "ecmult_gen.h" +#ifdef EXHAUSTIVE_TEST_ORDER +static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]; +#else +extern const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]; +#endif /* defined(EXHAUSTIVE_TEST_ORDER) */ + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_PRECOMPUTED_ECMULT_GEN_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scalar.h b/crypto/secp256k1/libsecp256k1/src/scalar.h index 27e9d8375e..70f49b1cf2 100644 --- a/crypto/secp256k1/libsecp256k1/src/scalar.h +++ b/crypto/secp256k1/libsecp256k1/src/scalar.h @@ -1,40 +1,44 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCALAR_ -#define _SECP256K1_SCALAR_ +#ifndef SECP256K1_SCALAR_H +#define SECP256K1_SCALAR_H -#include "num.h" - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif +#include "util.h" #if defined(EXHAUSTIVE_TEST_ORDER) #include "scalar_low.h" -#elif defined(USE_SCALAR_4X64) +#elif defined(SECP256K1_WIDEMUL_INT128) #include "scalar_4x64.h" -#elif defined(USE_SCALAR_8X32) +#elif defined(SECP256K1_WIDEMUL_INT64) #include "scalar_8x32.h" #else -#error "Please select scalar implementation" +#error "Please select wide multiplication implementation" #endif /** Clear a scalar to prevent the leak of sensitive data. */ static void secp256k1_scalar_clear(secp256k1_scalar *r); -/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ -static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); +/** Access bits (1 < count <= 32) from a scalar. All requested bits must belong to the same 32-bit limb. */ +static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count); -/** Access bits from a scalar. Not constant time. */ -static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); +/** Access bits (1 < count <= 32) from a scalar. offset + count must be < 256. Not constant time in offset and count. */ +static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); -/** Set a scalar from a big endian byte array. */ +/** Set a scalar from a big endian byte array. The scalar will be reduced modulo group order `n`. + * In: bin: pointer to a 32-byte array. + * Out: r: scalar to be set. + * overflow: non-zero if the scalar was bigger or equal to `n` before reduction, zero otherwise (can be NULL). + */ static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow); +/** Set a scalar from a big endian byte array and returns 1 if it is a valid + * seckey and 0 otherwise. */ +static int secp256k1_scalar_set_b32_seckey(secp256k1_scalar *r, const unsigned char *bin); + /** Set a scalar to an unsigned integer. */ static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v); @@ -50,13 +54,6 @@ static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int /** Multiply two scalars (modulo the group order). */ static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); -/** Shift a scalar right by some amount strictly between 0 and 16, returning - * the low bits that were shifted off */ -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); - -/** Compute the square of a scalar (modulo the group order). */ -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a); - /** Compute the inverse of a scalar (modulo the group order). */ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a); @@ -66,6 +63,9 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_sc /** Compute the complement of a scalar (modulo the group order). */ static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); +/** Multiply a scalar with the multiplicative inverse of 2. */ +static void secp256k1_scalar_half(secp256k1_scalar *r, const secp256k1_scalar *a); + /** Check whether a scalar equals zero. */ static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); @@ -82,25 +82,24 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar *a); * Returns -1 if the number was negated, 1 otherwise */ static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); -#ifndef USE_NUM_NONE -/** Convert a scalar to a number. */ -static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a); - -/** Get the order of the group as a number. */ -static void secp256k1_scalar_order_get_num(secp256k1_num *r); -#endif - /** Compare two scalars. */ static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); -#ifdef USE_ENDOMORPHISM -/** Find r1 and r2 such that r1+r2*2^128 = a. */ -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); -/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); -#endif +/** Find r1 and r2 such that r1+r2*2^128 = k. */ +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k); +/** Find r1 and r2 such that r1+r2*lambda = k, where r1 and r2 or their + * negations are maximum 128 bits long (see secp256k1_ge_mul_lambda). It is + * required that r1, r2, and k all point to different objects. */ +static void secp256k1_scalar_split_lambda(secp256k1_scalar * SECP256K1_RESTRICT r1, secp256k1_scalar * SECP256K1_RESTRICT r2, const secp256k1_scalar * SECP256K1_RESTRICT k); /** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); -#endif +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +static void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag); + +/** Check invariants on a scalar (no-op unless VERIFY is enabled). */ +static void secp256k1_scalar_verify(const secp256k1_scalar *r); +#define SECP256K1_SCALAR_VERIFY(r) secp256k1_scalar_verify(r) + +#endif /* SECP256K1_SCALAR_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scalar_4x64.h b/crypto/secp256k1/libsecp256k1/src/scalar_4x64.h index cff406038f..700964291e 100644 --- a/crypto/secp256k1/libsecp256k1/src/scalar_4x64.h +++ b/crypto/secp256k1/libsecp256k1/src/scalar_4x64.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_ -#define _SECP256K1_SCALAR_REPR_ +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H #include @@ -16,4 +16,4 @@ typedef struct { #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} -#endif +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scalar_4x64_impl.h b/crypto/secp256k1/libsecp256k1/src/scalar_4x64_impl.h index 56e7bd82af..807b9b70ab 100644 --- a/crypto/secp256k1/libsecp256k1/src/scalar_4x64_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/scalar_4x64_impl.h @@ -1,11 +1,16 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ -#define _SECP256K1_SCALAR_REPR_IMPL_H_ +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H + +#include "checkmem.h" +#include "int128.h" +#include "modinv64_impl.h" +#include "util.h" /* Limbs of the secp256k1 order. */ #define SECP256K1_N_0 ((uint64_t)0xBFD25E8CD0364141ULL) @@ -24,33 +29,33 @@ #define SECP256K1_N_H_2 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) #define SECP256K1_N_H_3 ((uint64_t)0x7FFFFFFFFFFFFFFFULL) -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { - r->d[0] = 0; - r->d[1] = 0; - r->d[2] = 0; - r->d[3] = 0; -} - SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { r->d[0] = v; r->d[1] = 0; r->d[2] = 0; r->d[3] = 0; + + SECP256K1_SCALAR_VERIFY(r); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + SECP256K1_SCALAR_VERIFY(a); + VERIFY_CHECK(count > 0 && count <= 32); VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6); - return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1); + + return (a->d[offset >> 6] >> (offset & 0x3F)) & (0xFFFFFFFF >> (32 - count)); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - VERIFY_CHECK(count < 32); +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + SECP256K1_SCALAR_VERIFY(a); + VERIFY_CHECK(count > 0 && count <= 32); VERIFY_CHECK(offset + count <= 256); + if ((offset + count - 1) >> 6 == offset >> 6) { - return secp256k1_scalar_get_bits(a, offset, count); + return secp256k1_scalar_get_bits_limb32(a, offset, count); } else { VERIFY_CHECK((offset >> 6) + 1 < 4); - return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & ((((uint64_t)1) << count) - 1); + return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & (0xFFFFFFFF >> (32 - count)); } } @@ -67,95 +72,177 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal } SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, unsigned int overflow) { - uint128_t t; + secp256k1_uint128 t; VERIFY_CHECK(overflow <= 1); - t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; - r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[1] + overflow * SECP256K1_N_C_1; - r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[2] + overflow * SECP256K1_N_C_2; - r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint64_t)r->d[3]; - r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; + + secp256k1_u128_from_u64(&t, r->d[0]); + secp256k1_u128_accum_u64(&t, overflow * SECP256K1_N_C_0); + r->d[0] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[1]); + secp256k1_u128_accum_u64(&t, overflow * SECP256K1_N_C_1); + r->d[1] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[2]); + secp256k1_u128_accum_u64(&t, overflow * SECP256K1_N_C_2); + r->d[2] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[3]); + r->d[3] = secp256k1_u128_to_u64(&t); + + SECP256K1_SCALAR_VERIFY(r); return overflow; } static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { int overflow; - uint128_t t = (uint128_t)a->d[0] + b->d[0]; - r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)a->d[1] + b->d[1]; - r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)a->d[2] + b->d[2]; - r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)a->d[3] + b->d[3]; - r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - overflow = t + secp256k1_scalar_check_overflow(r); + secp256k1_uint128 t; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + + secp256k1_u128_from_u64(&t, a->d[0]); + secp256k1_u128_accum_u64(&t, b->d[0]); + r->d[0] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, a->d[1]); + secp256k1_u128_accum_u64(&t, b->d[1]); + r->d[1] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, a->d[2]); + secp256k1_u128_accum_u64(&t, b->d[2]); + r->d[2] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, a->d[3]); + secp256k1_u128_accum_u64(&t, b->d[3]); + r->d[3] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + overflow = secp256k1_u128_to_u64(&t) + secp256k1_scalar_check_overflow(r); VERIFY_CHECK(overflow == 0 || overflow == 1); secp256k1_scalar_reduce(r, overflow); + + SECP256K1_SCALAR_VERIFY(r); return overflow; } static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { - uint128_t t; + secp256k1_uint128 t; + volatile int vflag = flag; + SECP256K1_SCALAR_VERIFY(r); VERIFY_CHECK(bit < 256); - bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */ - t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F)); - r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[1] + (((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F)); - r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[2] + (((uint64_t)((bit >> 6) == 2)) << (bit & 0x3F)); - r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[3] + (((uint64_t)((bit >> 6) == 3)) << (bit & 0x3F)); - r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; -#ifdef VERIFY - VERIFY_CHECK((t >> 64) == 0); - VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); -#endif + + bit += ((uint32_t) vflag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */ + secp256k1_u128_from_u64(&t, r->d[0]); + secp256k1_u128_accum_u64(&t, ((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F)); + r->d[0] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[1]); + secp256k1_u128_accum_u64(&t, ((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F)); + r->d[1] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[2]); + secp256k1_u128_accum_u64(&t, ((uint64_t)((bit >> 6) == 2)) << (bit & 0x3F)); + r->d[2] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[3]); + secp256k1_u128_accum_u64(&t, ((uint64_t)((bit >> 6) == 3)) << (bit & 0x3F)); + r->d[3] = secp256k1_u128_to_u64(&t); + + SECP256K1_SCALAR_VERIFY(r); + VERIFY_CHECK(secp256k1_u128_hi_u64(&t) == 0); } static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { int over; - r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56; - r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56; - r->d[2] = (uint64_t)b32[15] | (uint64_t)b32[14] << 8 | (uint64_t)b32[13] << 16 | (uint64_t)b32[12] << 24 | (uint64_t)b32[11] << 32 | (uint64_t)b32[10] << 40 | (uint64_t)b32[9] << 48 | (uint64_t)b32[8] << 56; - r->d[3] = (uint64_t)b32[7] | (uint64_t)b32[6] << 8 | (uint64_t)b32[5] << 16 | (uint64_t)b32[4] << 24 | (uint64_t)b32[3] << 32 | (uint64_t)b32[2] << 40 | (uint64_t)b32[1] << 48 | (uint64_t)b32[0] << 56; + r->d[0] = secp256k1_read_be64(&b32[24]); + r->d[1] = secp256k1_read_be64(&b32[16]); + r->d[2] = secp256k1_read_be64(&b32[8]); + r->d[3] = secp256k1_read_be64(&b32[0]); over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); if (overflow) { *overflow = over; } + + SECP256K1_SCALAR_VERIFY(r); } static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { - bin[0] = a->d[3] >> 56; bin[1] = a->d[3] >> 48; bin[2] = a->d[3] >> 40; bin[3] = a->d[3] >> 32; bin[4] = a->d[3] >> 24; bin[5] = a->d[3] >> 16; bin[6] = a->d[3] >> 8; bin[7] = a->d[3]; - bin[8] = a->d[2] >> 56; bin[9] = a->d[2] >> 48; bin[10] = a->d[2] >> 40; bin[11] = a->d[2] >> 32; bin[12] = a->d[2] >> 24; bin[13] = a->d[2] >> 16; bin[14] = a->d[2] >> 8; bin[15] = a->d[2]; - bin[16] = a->d[1] >> 56; bin[17] = a->d[1] >> 48; bin[18] = a->d[1] >> 40; bin[19] = a->d[1] >> 32; bin[20] = a->d[1] >> 24; bin[21] = a->d[1] >> 16; bin[22] = a->d[1] >> 8; bin[23] = a->d[1]; - bin[24] = a->d[0] >> 56; bin[25] = a->d[0] >> 48; bin[26] = a->d[0] >> 40; bin[27] = a->d[0] >> 32; bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; + SECP256K1_SCALAR_VERIFY(a); + + secp256k1_write_be64(&bin[0], a->d[3]); + secp256k1_write_be64(&bin[8], a->d[2]); + secp256k1_write_be64(&bin[16], a->d[1]); + secp256k1_write_be64(&bin[24], a->d[0]); } SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + return (a->d[0] | a->d[1] | a->d[2] | a->d[3]) == 0; } static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { uint64_t nonzero = 0xFFFFFFFFFFFFFFFFULL * (secp256k1_scalar_is_zero(a) == 0); - uint128_t t = (uint128_t)(~a->d[0]) + SECP256K1_N_0 + 1; - r->d[0] = t & nonzero; t >>= 64; - t += (uint128_t)(~a->d[1]) + SECP256K1_N_1; - r->d[1] = t & nonzero; t >>= 64; - t += (uint128_t)(~a->d[2]) + SECP256K1_N_2; - r->d[2] = t & nonzero; t >>= 64; - t += (uint128_t)(~a->d[3]) + SECP256K1_N_3; - r->d[3] = t & nonzero; + secp256k1_uint128 t; + SECP256K1_SCALAR_VERIFY(a); + + secp256k1_u128_from_u64(&t, ~a->d[0]); + secp256k1_u128_accum_u64(&t, SECP256K1_N_0 + 1); + r->d[0] = secp256k1_u128_to_u64(&t) & nonzero; secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, ~a->d[1]); + secp256k1_u128_accum_u64(&t, SECP256K1_N_1); + r->d[1] = secp256k1_u128_to_u64(&t) & nonzero; secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, ~a->d[2]); + secp256k1_u128_accum_u64(&t, SECP256K1_N_2); + r->d[2] = secp256k1_u128_to_u64(&t) & nonzero; secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, ~a->d[3]); + secp256k1_u128_accum_u64(&t, SECP256K1_N_3); + r->d[3] = secp256k1_u128_to_u64(&t) & nonzero; + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_half(secp256k1_scalar *r, const secp256k1_scalar *a) { + /* Writing `/` for field division and `//` for integer division, we compute + * + * a/2 = (a - (a&1))/2 + (a&1)/2 + * = (a >> 1) + (a&1 ? 1/2 : 0) + * = (a >> 1) + (a&1 ? n//2+1 : 0), + * + * where n is the group order and in the last equality we have used 1/2 = n//2+1 (mod n). + * For n//2, we have the constants SECP256K1_N_H_0, ... + * + * This sum does not overflow. The most extreme case is a = -2, the largest odd scalar. Here: + * - the left summand is: a >> 1 = (a - a&1)/2 = (n-2-1)//2 = (n-3)//2 + * - the right summand is: a&1 ? n//2+1 : 0 = n//2+1 = (n-1)//2 + 2//2 = (n+1)//2 + * Together they sum to (n-3)//2 + (n+1)//2 = (2n-2)//2 = n - 1, which is less than n. + */ + uint64_t mask = -(uint64_t)(a->d[0] & 1U); + secp256k1_uint128 t; + SECP256K1_SCALAR_VERIFY(a); + + secp256k1_u128_from_u64(&t, (a->d[0] >> 1) | (a->d[1] << 63)); + secp256k1_u128_accum_u64(&t, (SECP256K1_N_H_0 + 1U) & mask); + r->d[0] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, (a->d[1] >> 1) | (a->d[2] << 63)); + secp256k1_u128_accum_u64(&t, SECP256K1_N_H_1 & mask); + r->d[1] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, (a->d[2] >> 1) | (a->d[3] << 63)); + secp256k1_u128_accum_u64(&t, SECP256K1_N_H_2 & mask); + r->d[2] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64); + r->d[3] = secp256k1_u128_to_u64(&t) + (a->d[3] >> 1) + (SECP256K1_N_H_3 & mask); +#ifdef VERIFY + /* The line above only computed the bottom 64 bits of r->d[3]; redo the computation + * in full 128 bits to make sure the top 64 bits are indeed zero. */ + secp256k1_u128_accum_u64(&t, a->d[3] >> 1); + secp256k1_u128_accum_u64(&t, SECP256K1_N_H_3 & mask); + secp256k1_u128_rshift(&t, 64); + VERIFY_CHECK(secp256k1_u128_to_u64(&t) == 0); + + SECP256K1_SCALAR_VERIFY(r); +#endif } SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3]) == 0; } static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { int yes = 0; int no = 0; + SECP256K1_SCALAR_VERIFY(a); + no |= (a->d[3] < SECP256K1_N_H_3); yes |= (a->d[3] > SECP256K1_N_H_3) & ~no; no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; /* No need for a > check. */ @@ -168,16 +255,26 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { /* If we are flag = 0, mask = 00...00 and this is a no-op; * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ - uint64_t mask = !flag - 1; + volatile int vflag = flag; + uint64_t mask = -vflag; uint64_t nonzero = (secp256k1_scalar_is_zero(r) != 0) - 1; - uint128_t t = (uint128_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); - r->d[0] = t & nonzero; t >>= 64; - t += (uint128_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); - r->d[1] = t & nonzero; t >>= 64; - t += (uint128_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); - r->d[2] = t & nonzero; t >>= 64; - t += (uint128_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); - r->d[3] = t & nonzero; + secp256k1_uint128 t; + SECP256K1_SCALAR_VERIFY(r); + + secp256k1_u128_from_u64(&t, r->d[0] ^ mask); + secp256k1_u128_accum_u64(&t, (SECP256K1_N_0 + 1) & mask); + r->d[0] = secp256k1_u128_to_u64(&t) & nonzero; secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[1] ^ mask); + secp256k1_u128_accum_u64(&t, SECP256K1_N_1 & mask); + r->d[1] = secp256k1_u128_to_u64(&t) & nonzero; secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[2] ^ mask); + secp256k1_u128_accum_u64(&t, SECP256K1_N_2 & mask); + r->d[2] = secp256k1_u128_to_u64(&t) & nonzero; secp256k1_u128_rshift(&t, 64); + secp256k1_u128_accum_u64(&t, r->d[3] ^ mask); + secp256k1_u128_accum_u64(&t, SECP256K1_N_3 & mask); + r->d[3] = secp256k1_u128_to_u64(&t) & nonzero; + + SECP256K1_SCALAR_VERIFY(r); return 2 * (mask == 0) - 1; } @@ -187,14 +284,15 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { #define muladd(a,b) { \ uint64_t tl, th; \ { \ - uint128_t t = (uint128_t)a * b; \ - th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ - tl = t; \ + secp256k1_uint128 t; \ + secp256k1_u128_mul(&t, a, b); \ + th = secp256k1_u128_hi_u64(&t); /* at most 0xFFFFFFFFFFFFFFFE */ \ + tl = secp256k1_u128_to_u64(&t); \ } \ c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ + th += (c0 < tl); /* at most 0xFFFFFFFFFFFFFFFF */ \ c1 += th; /* overflow is handled on the next line */ \ - c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \ + c2 += (c1 < th); /* never overflows by contract (verified in the next line) */ \ VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ } @@ -202,51 +300,30 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { #define muladd_fast(a,b) { \ uint64_t tl, th; \ { \ - uint128_t t = (uint128_t)a * b; \ - th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ - tl = t; \ + secp256k1_uint128 t; \ + secp256k1_u128_mul(&t, a, b); \ + th = secp256k1_u128_hi_u64(&t); /* at most 0xFFFFFFFFFFFFFFFE */ \ + tl = secp256k1_u128_to_u64(&t); \ } \ c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ + th += (c0 < tl); /* at most 0xFFFFFFFFFFFFFFFF */ \ c1 += th; /* never overflows by contract (verified in the next line) */ \ VERIFY_CHECK(c1 >= th); \ } -/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define muladd2(a,b) { \ - uint64_t tl, th, th2, tl2; \ - { \ - uint128_t t = (uint128_t)a * b; \ - th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ - tl = t; \ - } \ - th2 = th + th; /* at most 0xFFFFFFFFFFFFFFFE (in case th was 0x7FFFFFFFFFFFFFFF) */ \ - c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ - tl2 = tl + tl; /* at most 0xFFFFFFFFFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFFFFFFFFFF) */ \ - th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ - c0 += tl2; /* overflow is handled on the next line */ \ - th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ - c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \ - c1 += th2; /* overflow is handled on the next line */ \ - c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \ -} - /** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ #define sumadd(a) { \ unsigned int over; \ c0 += (a); /* overflow is handled on the next line */ \ - over = (c0 < (a)) ? 1 : 0; \ + over = (c0 < (a)); \ c1 += over; /* overflow is handled on the next line */ \ - c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ + c2 += (c1 < over); /* never overflows by contract */ \ } /** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ #define sumadd_fast(a) { \ c0 += (a); /* overflow is handled on the next line */ \ - c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ + c1 += (c0 < (a)); /* never overflows by contract (verified the next line) */ \ VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ VERIFY_CHECK(c2 == 0); \ } @@ -375,10 +452,18 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "movq %%r10, %q5\n" /* extract m6 */ "movq %%r8, %q6\n" - : "=g"(m0), "=g"(m1), "=g"(m2), "=g"(m3), "=g"(m4), "=g"(m5), "=g"(m6) - : "S"(l), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) + : "=&g"(m0), "=&g"(m1), "=&g"(m2), "=g"(m3), "=g"(m4), "=g"(m5), "=g"(m6) + : "S"(l), "i"(SECP256K1_N_C_0), "i"(SECP256K1_N_C_1) : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc"); + SECP256K1_CHECKMEM_MSAN_DEFINE(&m0, sizeof(m0)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&m1, sizeof(m1)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&m2, sizeof(m2)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&m3, sizeof(m3)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&m4, sizeof(m4)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&m5, sizeof(m5)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&m6, sizeof(m6)); + /* Reduce 385 bits into 258. */ __asm__ __volatile__( /* Preload */ @@ -455,9 +540,15 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) /* extract p4 */ "movq %%r9, %q4\n" : "=&g"(p0), "=&g"(p1), "=&g"(p2), "=g"(p3), "=g"(p4) - : "g"(m0), "g"(m1), "g"(m2), "g"(m3), "g"(m4), "g"(m5), "g"(m6), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) + : "g"(m0), "g"(m1), "g"(m2), "g"(m3), "g"(m4), "g"(m5), "g"(m6), "i"(SECP256K1_N_C_0), "i"(SECP256K1_N_C_1) : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "cc"); + SECP256K1_CHECKMEM_MSAN_DEFINE(&p0, sizeof(p0)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&p1, sizeof(p1)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&p2, sizeof(p2)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&p3, sizeof(p3)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&p4, sizeof(p4)); + /* Reduce 258 bits into 256. */ __asm__ __volatile__( /* Preload */ @@ -501,11 +592,15 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) /* Extract c */ "movq %%r9, %q0\n" : "=g"(c) - : "g"(p0), "g"(p1), "g"(p2), "g"(p3), "g"(p4), "D"(r), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) + : "g"(p0), "g"(p1), "g"(p2), "g"(p3), "g"(p4), "D"(r), "i"(SECP256K1_N_C_0), "i"(SECP256K1_N_C_1) : "rax", "rdx", "r8", "r9", "r10", "cc", "memory"); + + SECP256K1_CHECKMEM_MSAN_DEFINE(r, sizeof(*r)); + SECP256K1_CHECKMEM_MSAN_DEFINE(&c, sizeof(c)); + #else - uint128_t c; - uint64_t c0, c1, c2; + secp256k1_uint128 c128; + uint64_t c, c0, c1, c2; uint64_t n0 = l[4], n1 = l[5], n2 = l[6], n3 = l[7]; uint64_t m0, m1, m2, m3, m4, m5; uint32_t m6; @@ -562,21 +657,25 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) /* Reduce 258 bits into 256. */ /* r[0..3] = p[0..3] + p[4] * SECP256K1_N_C. */ - c = p0 + (uint128_t)SECP256K1_N_C_0 * p4; - r->d[0] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; - c += p1 + (uint128_t)SECP256K1_N_C_1 * p4; - r->d[1] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; - c += p2 + (uint128_t)p4; - r->d[2] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; - c += p3; - r->d[3] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; + secp256k1_u128_from_u64(&c128, p0); + secp256k1_u128_accum_mul(&c128, SECP256K1_N_C_0, p4); + r->d[0] = secp256k1_u128_to_u64(&c128); secp256k1_u128_rshift(&c128, 64); + secp256k1_u128_accum_u64(&c128, p1); + secp256k1_u128_accum_mul(&c128, SECP256K1_N_C_1, p4); + r->d[1] = secp256k1_u128_to_u64(&c128); secp256k1_u128_rshift(&c128, 64); + secp256k1_u128_accum_u64(&c128, p2); + secp256k1_u128_accum_u64(&c128, p4); + r->d[2] = secp256k1_u128_to_u64(&c128); secp256k1_u128_rshift(&c128, 64); + secp256k1_u128_accum_u64(&c128, p3); + r->d[3] = secp256k1_u128_to_u64(&c128); + c = secp256k1_u128_hi_u64(&c128); #endif /* Final reduction of r. */ secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); } -static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, const secp256k1_scalar *b) { +static void secp256k1_scalar_mul_512(uint64_t *l8, const secp256k1_scalar *a, const secp256k1_scalar *b) { #ifdef USE_ASM_X86_64 const uint64_t *pb = b->d; __asm__ __volatile__( @@ -591,7 +690,7 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, c /* (rax,rdx) = a0 * b0 */ "movq %%r15, %%rax\n" "mulq %%r11\n" - /* Extract l0 */ + /* Extract l8[0] */ "movq %%rax, 0(%%rsi)\n" /* (r8,r9,r10) = (rdx) */ "movq %%rdx, %%r8\n" @@ -609,7 +708,7 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, c "addq %%rax, %%r8\n" "adcq %%rdx, %%r9\n" "adcq $0, %%r10\n" - /* Extract l1 */ + /* Extract l8[1] */ "movq %%r8, 8(%%rsi)\n" "xorq %%r8, %%r8\n" /* (r9,r10,r8) += a0 * b2 */ @@ -630,7 +729,7 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, c "addq %%rax, %%r9\n" "adcq %%rdx, %%r10\n" "adcq $0, %%r8\n" - /* Extract l2 */ + /* Extract l8[2] */ "movq %%r9, 16(%%rsi)\n" "xorq %%r9, %%r9\n" /* (r10,r8,r9) += a0 * b3 */ @@ -659,7 +758,7 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, c "addq %%rax, %%r10\n" "adcq %%rdx, %%r8\n" "adcq $0, %%r9\n" - /* Extract l3 */ + /* Extract l8[3] */ "movq %%r10, 24(%%rsi)\n" "xorq %%r10, %%r10\n" /* (r8,r9,r10) += a1 * b3 */ @@ -680,7 +779,7 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, c "addq %%rax, %%r8\n" "adcq %%rdx, %%r9\n" "adcq $0, %%r10\n" - /* Extract l4 */ + /* Extract l8[4] */ "movq %%r8, 32(%%rsi)\n" "xorq %%r8, %%r8\n" /* (r9,r10,r8) += a2 * b3 */ @@ -695,188 +794,54 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, c "addq %%rax, %%r9\n" "adcq %%rdx, %%r10\n" "adcq $0, %%r8\n" - /* Extract l5 */ + /* Extract l8[5] */ "movq %%r9, 40(%%rsi)\n" /* (r10,r8) += a3 * b3 */ "movq %%r15, %%rax\n" "mulq %%r14\n" "addq %%rax, %%r10\n" "adcq %%rdx, %%r8\n" - /* Extract l6 */ + /* Extract l8[6] */ "movq %%r10, 48(%%rsi)\n" - /* Extract l7 */ + /* Extract l8[7] */ "movq %%r8, 56(%%rsi)\n" : "+d"(pb) - : "S"(l), "D"(a->d) + : "S"(l8), "D"(a->d) : "rax", "rbx", "rcx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "cc", "memory"); + + SECP256K1_CHECKMEM_MSAN_DEFINE(l8, sizeof(*l8) * 8); + #else /* 160 bit accumulator. */ uint64_t c0 = 0, c1 = 0; uint32_t c2 = 0; - /* l[0..7] = a[0..3] * b[0..3]. */ + /* l8[0..7] = a[0..3] * b[0..3]. */ muladd_fast(a->d[0], b->d[0]); - extract_fast(l[0]); + extract_fast(l8[0]); muladd(a->d[0], b->d[1]); muladd(a->d[1], b->d[0]); - extract(l[1]); + extract(l8[1]); muladd(a->d[0], b->d[2]); muladd(a->d[1], b->d[1]); muladd(a->d[2], b->d[0]); - extract(l[2]); + extract(l8[2]); muladd(a->d[0], b->d[3]); muladd(a->d[1], b->d[2]); muladd(a->d[2], b->d[1]); muladd(a->d[3], b->d[0]); - extract(l[3]); + extract(l8[3]); muladd(a->d[1], b->d[3]); muladd(a->d[2], b->d[2]); muladd(a->d[3], b->d[1]); - extract(l[4]); + extract(l8[4]); muladd(a->d[2], b->d[3]); muladd(a->d[3], b->d[2]); - extract(l[5]); + extract(l8[5]); muladd_fast(a->d[3], b->d[3]); - extract_fast(l[6]); + extract_fast(l8[6]); VERIFY_CHECK(c1 == 0); - l[7] = c0; -#endif -} - -static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar *a) { -#ifdef USE_ASM_X86_64 - __asm__ __volatile__( - /* Preload */ - "movq 0(%%rdi), %%r11\n" - "movq 8(%%rdi), %%r12\n" - "movq 16(%%rdi), %%r13\n" - "movq 24(%%rdi), %%r14\n" - /* (rax,rdx) = a0 * a0 */ - "movq %%r11, %%rax\n" - "mulq %%r11\n" - /* Extract l0 */ - "movq %%rax, 0(%%rsi)\n" - /* (r8,r9,r10) = (rdx,0) */ - "movq %%rdx, %%r8\n" - "xorq %%r9, %%r9\n" - "xorq %%r10, %%r10\n" - /* (r8,r9,r10) += 2 * a0 * a1 */ - "movq %%r11, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* Extract l1 */ - "movq %%r8, 8(%%rsi)\n" - "xorq %%r8, %%r8\n" - /* (r9,r10,r8) += 2 * a0 * a2 */ - "movq %%r11, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* (r9,r10,r8) += a1 * a1 */ - "movq %%r12, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* Extract l2 */ - "movq %%r9, 16(%%rsi)\n" - "xorq %%r9, %%r9\n" - /* (r10,r8,r9) += 2 * a0 * a3 */ - "movq %%r11, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += 2 * a1 * a2 */ - "movq %%r12, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* Extract l3 */ - "movq %%r10, 24(%%rsi)\n" - "xorq %%r10, %%r10\n" - /* (r8,r9,r10) += 2 * a1 * a3 */ - "movq %%r12, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* (r8,r9,r10) += a2 * a2 */ - "movq %%r13, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* Extract l4 */ - "movq %%r8, 32(%%rsi)\n" - "xorq %%r8, %%r8\n" - /* (r9,r10,r8) += 2 * a2 * a3 */ - "movq %%r13, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* Extract l5 */ - "movq %%r9, 40(%%rsi)\n" - /* (r10,r8) += a3 * a3 */ - "movq %%r14, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - /* Extract l6 */ - "movq %%r10, 48(%%rsi)\n" - /* Extract l7 */ - "movq %%r8, 56(%%rsi)\n" - : - : "S"(l), "D"(a->d) - : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc", "memory"); -#else - /* 160 bit accumulator. */ - uint64_t c0 = 0, c1 = 0; - uint32_t c2 = 0; - - /* l[0..7] = a[0..3] * b[0..3]. */ - muladd_fast(a->d[0], a->d[0]); - extract_fast(l[0]); - muladd2(a->d[0], a->d[1]); - extract(l[1]); - muladd2(a->d[0], a->d[2]); - muladd(a->d[1], a->d[1]); - extract(l[2]); - muladd2(a->d[0], a->d[3]); - muladd2(a->d[1], a->d[2]); - extract(l[3]); - muladd2(a->d[1], a->d[3]); - muladd(a->d[2], a->d[2]); - extract(l[4]); - muladd2(a->d[2], a->d[3]); - extract(l[5]); - muladd_fast(a->d[3], a->d[3]); - extract_fast(l[6]); - VERIFY_CHECK(c1 == 0); - l[7] = c0; + l8[7] = c0; #endif } @@ -884,48 +849,40 @@ static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar *a) { #undef sumadd_fast #undef muladd #undef muladd_fast -#undef muladd2 #undef extract #undef extract_fast static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { uint64_t l[8]; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + secp256k1_scalar_mul_512(l, a, b); secp256k1_scalar_reduce_512(r, l); + + SECP256K1_SCALAR_VERIFY(r); } -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { - int ret; - VERIFY_CHECK(n > 0); - VERIFY_CHECK(n < 16); - ret = r->d[0] & ((1 << n) - 1); - r->d[0] = (r->d[0] >> n) + (r->d[1] << (64 - n)); - r->d[1] = (r->d[1] >> n) + (r->d[2] << (64 - n)); - r->d[2] = (r->d[2] >> n) + (r->d[3] << (64 - n)); - r->d[3] = (r->d[3] >> n); - return ret; -} +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k) { + SECP256K1_SCALAR_VERIFY(k); -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { - uint64_t l[8]; - secp256k1_scalar_sqr_512(l, a); - secp256k1_scalar_reduce_512(r, l); -} - -#ifdef USE_ENDOMORPHISM -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - r1->d[0] = a->d[0]; - r1->d[1] = a->d[1]; + r1->d[0] = k->d[0]; + r1->d[1] = k->d[1]; r1->d[2] = 0; r1->d[3] = 0; - r2->d[0] = a->d[2]; - r2->d[1] = a->d[3]; + r2->d[0] = k->d[2]; + r2->d[1] = k->d[3]; r2->d[2] = 0; r2->d[3] = 0; + + SECP256K1_SCALAR_VERIFY(r1); + SECP256K1_SCALAR_VERIFY(r2); } -#endif SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0; } @@ -934,7 +891,10 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, unsigned int shiftlimbs; unsigned int shiftlow; unsigned int shifthigh; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); VERIFY_CHECK(shift >= 256); + secp256k1_scalar_mul_512(l, a, b); shiftlimbs = shift >> 6; shiftlow = shift & 0x3F; @@ -944,6 +904,97 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[3] = shift < 320 ? (l[3 + shiftlimbs] >> shiftlow) : 0; secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1); + + SECP256K1_SCALAR_VERIFY(r); } +static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { + uint64_t mask0, mask1; + volatile int vflag = flag; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d)); + + mask0 = vflag + ~((uint64_t)0); + mask1 = ~mask0; + r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1); + r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1); + r->d[2] = (r->d[2] & mask0) | (a->d[2] & mask1); + r->d[3] = (r->d[3] & mask0) | (a->d[3] & mask1); + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_from_signed62(secp256k1_scalar *r, const secp256k1_modinv64_signed62 *a) { + const uint64_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4]; + + /* The output from secp256k1_modinv64{_var} should be normalized to range [0,modulus), and + * have limbs in [0,2^62). The modulus is < 2^256, so the top limb must be below 2^(256-62*4). + */ + VERIFY_CHECK(a0 >> 62 == 0); + VERIFY_CHECK(a1 >> 62 == 0); + VERIFY_CHECK(a2 >> 62 == 0); + VERIFY_CHECK(a3 >> 62 == 0); + VERIFY_CHECK(a4 >> 8 == 0); + + r->d[0] = a0 | a1 << 62; + r->d[1] = a1 >> 2 | a2 << 60; + r->d[2] = a2 >> 4 | a3 << 58; + r->d[3] = a3 >> 6 | a4 << 56; + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_to_signed62(secp256k1_modinv64_signed62 *r, const secp256k1_scalar *a) { + const uint64_t M62 = UINT64_MAX >> 2; + const uint64_t a0 = a->d[0], a1 = a->d[1], a2 = a->d[2], a3 = a->d[3]; + SECP256K1_SCALAR_VERIFY(a); + + r->v[0] = a0 & M62; + r->v[1] = (a0 >> 62 | a1 << 2) & M62; + r->v[2] = (a1 >> 60 | a2 << 4) & M62; + r->v[3] = (a2 >> 58 | a3 << 6) & M62; + r->v[4] = a3 >> 56; +} + +static const secp256k1_modinv64_modinfo secp256k1_const_modinfo_scalar = { + {{0x3FD25E8CD0364141LL, 0x2ABB739ABD2280EELL, -0x15LL, 0, 256}}, + 0x34F20099AA774EC1LL +}; + +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_modinv64_signed62 s; +#ifdef VERIFY + int zero_in = secp256k1_scalar_is_zero(x); #endif + SECP256K1_SCALAR_VERIFY(x); + + secp256k1_scalar_to_signed62(&s, x); + secp256k1_modinv64(&s, &secp256k1_const_modinfo_scalar); + secp256k1_scalar_from_signed62(r, &s); + + SECP256K1_SCALAR_VERIFY(r); + VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in); +} + +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_modinv64_signed62 s; +#ifdef VERIFY + int zero_in = secp256k1_scalar_is_zero(x); +#endif + SECP256K1_SCALAR_VERIFY(x); + + secp256k1_scalar_to_signed62(&s, x); + secp256k1_modinv64_var(&s, &secp256k1_const_modinfo_scalar); + secp256k1_scalar_from_signed62(r, &s); + + SECP256K1_SCALAR_VERIFY(r); + VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in); +} + +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + + return !(a->d[0] & 1); +} + +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scalar_8x32.h b/crypto/secp256k1/libsecp256k1/src/scalar_8x32.h index 1319664f65..17863ef937 100644 --- a/crypto/secp256k1/libsecp256k1/src/scalar_8x32.h +++ b/crypto/secp256k1/libsecp256k1/src/scalar_8x32.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_ -#define _SECP256K1_SCALAR_REPR_ +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H #include @@ -16,4 +16,4 @@ typedef struct { #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} -#endif +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scalar_8x32_impl.h b/crypto/secp256k1/libsecp256k1/src/scalar_8x32_impl.h index aae4f35c08..2610496052 100644 --- a/crypto/secp256k1/libsecp256k1/src/scalar_8x32_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/scalar_8x32_impl.h @@ -1,11 +1,15 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ -#define _SECP256K1_SCALAR_REPR_IMPL_H_ +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H + +#include "checkmem.h" +#include "modinv32_impl.h" +#include "util.h" /* Limbs of the secp256k1 order. */ #define SECP256K1_N_0 ((uint32_t)0xD0364141UL) @@ -34,17 +38,6 @@ #define SECP256K1_N_H_6 ((uint32_t)0xFFFFFFFFUL) #define SECP256K1_N_H_7 ((uint32_t)0x7FFFFFFFUL) -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { - r->d[0] = 0; - r->d[1] = 0; - r->d[2] = 0; - r->d[3] = 0; - r->d[4] = 0; - r->d[5] = 0; - r->d[6] = 0; - r->d[7] = 0; -} - SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { r->d[0] = v; r->d[1] = 0; @@ -54,21 +47,28 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig r->d[5] = 0; r->d[6] = 0; r->d[7] = 0; + + SECP256K1_SCALAR_VERIFY(r); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + SECP256K1_SCALAR_VERIFY(a); + VERIFY_CHECK(count > 0 && count <= 32); VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); - return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1); + + return (a->d[offset >> 5] >> (offset & 0x1F)) & (0xFFFFFFFF >> (32 - count)); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - VERIFY_CHECK(count < 32); +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + SECP256K1_SCALAR_VERIFY(a); + VERIFY_CHECK(count > 0 && count <= 32); VERIFY_CHECK(offset + count <= 256); + if ((offset + count - 1) >> 5 == offset >> 5) { - return secp256k1_scalar_get_bits(a, offset, count); + return secp256k1_scalar_get_bits_limb32(a, offset, count); } else { VERIFY_CHECK((offset >> 5) + 1 < 8); - return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1); + return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & (0xFFFFFFFF >> (32 - count)); } } @@ -93,6 +93,7 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_t overflow) { uint64_t t; VERIFY_CHECK(overflow <= 1); + t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; r->d[0] = t & 0xFFFFFFFFUL; t >>= 32; t += (uint64_t)r->d[1] + overflow * SECP256K1_N_C_1; @@ -109,12 +110,17 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_ r->d[6] = t & 0xFFFFFFFFUL; t >>= 32; t += (uint64_t)r->d[7]; r->d[7] = t & 0xFFFFFFFFUL; + + SECP256K1_SCALAR_VERIFY(r); return overflow; } static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { int overflow; uint64_t t = (uint64_t)a->d[0] + b->d[0]; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; t += (uint64_t)a->d[1] + b->d[1]; r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; @@ -133,13 +139,18 @@ static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, overflow = t + secp256k1_scalar_check_overflow(r); VERIFY_CHECK(overflow == 0 || overflow == 1); secp256k1_scalar_reduce(r, overflow); + + SECP256K1_SCALAR_VERIFY(r); return overflow; } static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { uint64_t t; + volatile int vflag = flag; + SECP256K1_SCALAR_VERIFY(r); VERIFY_CHECK(bit < 256); - bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */ + + bit += ((uint32_t) vflag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */ t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F)); r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F)); @@ -156,46 +167,53 @@ static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; t += (uint64_t)r->d[7] + (((uint32_t)((bit >> 5) == 7)) << (bit & 0x1F)); r->d[7] = t & 0xFFFFFFFFULL; -#ifdef VERIFY + + SECP256K1_SCALAR_VERIFY(r); VERIFY_CHECK((t >> 32) == 0); - VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); -#endif } static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { int over; - r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24; - r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24; - r->d[2] = (uint32_t)b32[23] | (uint32_t)b32[22] << 8 | (uint32_t)b32[21] << 16 | (uint32_t)b32[20] << 24; - r->d[3] = (uint32_t)b32[19] | (uint32_t)b32[18] << 8 | (uint32_t)b32[17] << 16 | (uint32_t)b32[16] << 24; - r->d[4] = (uint32_t)b32[15] | (uint32_t)b32[14] << 8 | (uint32_t)b32[13] << 16 | (uint32_t)b32[12] << 24; - r->d[5] = (uint32_t)b32[11] | (uint32_t)b32[10] << 8 | (uint32_t)b32[9] << 16 | (uint32_t)b32[8] << 24; - r->d[6] = (uint32_t)b32[7] | (uint32_t)b32[6] << 8 | (uint32_t)b32[5] << 16 | (uint32_t)b32[4] << 24; - r->d[7] = (uint32_t)b32[3] | (uint32_t)b32[2] << 8 | (uint32_t)b32[1] << 16 | (uint32_t)b32[0] << 24; + r->d[0] = secp256k1_read_be32(&b32[28]); + r->d[1] = secp256k1_read_be32(&b32[24]); + r->d[2] = secp256k1_read_be32(&b32[20]); + r->d[3] = secp256k1_read_be32(&b32[16]); + r->d[4] = secp256k1_read_be32(&b32[12]); + r->d[5] = secp256k1_read_be32(&b32[8]); + r->d[6] = secp256k1_read_be32(&b32[4]); + r->d[7] = secp256k1_read_be32(&b32[0]); over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); if (overflow) { *overflow = over; } + + SECP256K1_SCALAR_VERIFY(r); } static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { - bin[0] = a->d[7] >> 24; bin[1] = a->d[7] >> 16; bin[2] = a->d[7] >> 8; bin[3] = a->d[7]; - bin[4] = a->d[6] >> 24; bin[5] = a->d[6] >> 16; bin[6] = a->d[6] >> 8; bin[7] = a->d[6]; - bin[8] = a->d[5] >> 24; bin[9] = a->d[5] >> 16; bin[10] = a->d[5] >> 8; bin[11] = a->d[5]; - bin[12] = a->d[4] >> 24; bin[13] = a->d[4] >> 16; bin[14] = a->d[4] >> 8; bin[15] = a->d[4]; - bin[16] = a->d[3] >> 24; bin[17] = a->d[3] >> 16; bin[18] = a->d[3] >> 8; bin[19] = a->d[3]; - bin[20] = a->d[2] >> 24; bin[21] = a->d[2] >> 16; bin[22] = a->d[2] >> 8; bin[23] = a->d[2]; - bin[24] = a->d[1] >> 24; bin[25] = a->d[1] >> 16; bin[26] = a->d[1] >> 8; bin[27] = a->d[1]; - bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; + SECP256K1_SCALAR_VERIFY(a); + + secp256k1_write_be32(&bin[0], a->d[7]); + secp256k1_write_be32(&bin[4], a->d[6]); + secp256k1_write_be32(&bin[8], a->d[5]); + secp256k1_write_be32(&bin[12], a->d[4]); + secp256k1_write_be32(&bin[16], a->d[3]); + secp256k1_write_be32(&bin[20], a->d[2]); + secp256k1_write_be32(&bin[24], a->d[1]); + secp256k1_write_be32(&bin[28], a->d[0]); } SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + return (a->d[0] | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; } static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(a) == 0); uint64_t t = (uint64_t)(~a->d[0]) + SECP256K1_N_0 + 1; + SECP256K1_SCALAR_VERIFY(a); + r->d[0] = t & nonzero; t >>= 32; t += (uint64_t)(~a->d[1]) + SECP256K1_N_1; r->d[1] = t & nonzero; t >>= 32; @@ -211,15 +229,69 @@ static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar r->d[6] = t & nonzero; t >>= 32; t += (uint64_t)(~a->d[7]) + SECP256K1_N_7; r->d[7] = t & nonzero; + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_half(secp256k1_scalar *r, const secp256k1_scalar *a) { + /* Writing `/` for field division and `//` for integer division, we compute + * + * a/2 = (a - (a&1))/2 + (a&1)/2 + * = (a >> 1) + (a&1 ? 1/2 : 0) + * = (a >> 1) + (a&1 ? n//2+1 : 0), + * + * where n is the group order and in the last equality we have used 1/2 = n//2+1 (mod n). + * For n//2, we have the constants SECP256K1_N_H_0, ... + * + * This sum does not overflow. The most extreme case is a = -2, the largest odd scalar. Here: + * - the left summand is: a >> 1 = (a - a&1)/2 = (n-2-1)//2 = (n-3)//2 + * - the right summand is: a&1 ? n//2+1 : 0 = n//2+1 = (n-1)//2 + 2//2 = (n+1)//2 + * Together they sum to (n-3)//2 + (n+1)//2 = (2n-2)//2 = n - 1, which is less than n. + */ + uint32_t mask = -(uint32_t)(a->d[0] & 1U); + uint64_t t = (uint32_t)((a->d[0] >> 1) | (a->d[1] << 31)); + SECP256K1_SCALAR_VERIFY(a); + + t += (SECP256K1_N_H_0 + 1U) & mask; + r->d[0] = t; t >>= 32; + t += (uint32_t)((a->d[1] >> 1) | (a->d[2] << 31)); + t += SECP256K1_N_H_1 & mask; + r->d[1] = t; t >>= 32; + t += (uint32_t)((a->d[2] >> 1) | (a->d[3] << 31)); + t += SECP256K1_N_H_2 & mask; + r->d[2] = t; t >>= 32; + t += (uint32_t)((a->d[3] >> 1) | (a->d[4] << 31)); + t += SECP256K1_N_H_3 & mask; + r->d[3] = t; t >>= 32; + t += (uint32_t)((a->d[4] >> 1) | (a->d[5] << 31)); + t += SECP256K1_N_H_4 & mask; + r->d[4] = t; t >>= 32; + t += (uint32_t)((a->d[5] >> 1) | (a->d[6] << 31)); + t += SECP256K1_N_H_5 & mask; + r->d[5] = t; t >>= 32; + t += (uint32_t)((a->d[6] >> 1) | (a->d[7] << 31)); + t += SECP256K1_N_H_6 & mask; + r->d[6] = t; t >>= 32; + r->d[7] = (uint32_t)t + (uint32_t)(a->d[7] >> 1) + (SECP256K1_N_H_7 & mask); + + /* The line above only computed the bottom 32 bits of r->d[7]. Redo the computation + * in full 64 bits to make sure the top 32 bits are indeed zero. */ + VERIFY_CHECK((t + (a->d[7] >> 1) + (SECP256K1_N_H_7 & mask)) >> 32 == 0); + + SECP256K1_SCALAR_VERIFY(r); } SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; } static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { int yes = 0; int no = 0; + SECP256K1_SCALAR_VERIFY(a); + no |= (a->d[7] < SECP256K1_N_H_7); yes |= (a->d[7] > SECP256K1_N_H_7) & ~no; no |= (a->d[6] < SECP256K1_N_H_6) & ~yes; /* No need for a > check. */ @@ -238,9 +310,12 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { /* If we are flag = 0, mask = 00...00 and this is a no-op; * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ - uint32_t mask = !flag - 1; + volatile int vflag = flag; + uint32_t mask = -vflag; uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0); uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); + SECP256K1_SCALAR_VERIFY(r); + r->d[0] = t & nonzero; t >>= 32; t += (uint64_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); r->d[1] = t & nonzero; t >>= 32; @@ -256,6 +331,8 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { r->d[6] = t & nonzero; t >>= 32; t += (uint64_t)(r->d[7] ^ mask) + (SECP256K1_N_7 & mask); r->d[7] = t & nonzero; + + SECP256K1_SCALAR_VERIFY(r); return 2 * (mask == 0) - 1; } @@ -271,9 +348,9 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { tl = t; \ } \ c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ + th += (c0 < tl); /* at most 0xFFFFFFFF */ \ c1 += th; /* overflow is handled on the next line */ \ - c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \ + c2 += (c1 < th); /* never overflows by contract (verified in the next line) */ \ VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ } @@ -286,46 +363,24 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { tl = t; \ } \ c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ + th += (c0 < tl); /* at most 0xFFFFFFFF */ \ c1 += th; /* never overflows by contract (verified in the next line) */ \ VERIFY_CHECK(c1 >= th); \ } -/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define muladd2(a,b) { \ - uint32_t tl, th, th2, tl2; \ - { \ - uint64_t t = (uint64_t)a * b; \ - th = t >> 32; /* at most 0xFFFFFFFE */ \ - tl = t; \ - } \ - th2 = th + th; /* at most 0xFFFFFFFE (in case th was 0x7FFFFFFF) */ \ - c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ - tl2 = tl + tl; /* at most 0xFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFF) */ \ - th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ - c0 += tl2; /* overflow is handled on the next line */ \ - th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ - c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \ - c1 += th2; /* overflow is handled on the next line */ \ - c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \ -} - /** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ #define sumadd(a) { \ unsigned int over; \ c0 += (a); /* overflow is handled on the next line */ \ - over = (c0 < (a)) ? 1 : 0; \ + over = (c0 < (a)); \ c1 += over; /* overflow is handled on the next line */ \ - c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ + c2 += (c1 < over); /* never overflows by contract */ \ } /** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ #define sumadd_fast(a) { \ c0 += (a); /* overflow is handled on the next line */ \ - c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ + c1 += (c0 < (a)); /* never overflows by contract (verified the next line) */ \ VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ VERIFY_CHECK(c2 == 0); \ } @@ -576,124 +631,52 @@ static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar *a, con l[15] = c0; } -static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar *a) { - /* 96 bit accumulator. */ - uint32_t c0 = 0, c1 = 0, c2 = 0; - - /* l[0..15] = a[0..7]^2. */ - muladd_fast(a->d[0], a->d[0]); - extract_fast(l[0]); - muladd2(a->d[0], a->d[1]); - extract(l[1]); - muladd2(a->d[0], a->d[2]); - muladd(a->d[1], a->d[1]); - extract(l[2]); - muladd2(a->d[0], a->d[3]); - muladd2(a->d[1], a->d[2]); - extract(l[3]); - muladd2(a->d[0], a->d[4]); - muladd2(a->d[1], a->d[3]); - muladd(a->d[2], a->d[2]); - extract(l[4]); - muladd2(a->d[0], a->d[5]); - muladd2(a->d[1], a->d[4]); - muladd2(a->d[2], a->d[3]); - extract(l[5]); - muladd2(a->d[0], a->d[6]); - muladd2(a->d[1], a->d[5]); - muladd2(a->d[2], a->d[4]); - muladd(a->d[3], a->d[3]); - extract(l[6]); - muladd2(a->d[0], a->d[7]); - muladd2(a->d[1], a->d[6]); - muladd2(a->d[2], a->d[5]); - muladd2(a->d[3], a->d[4]); - extract(l[7]); - muladd2(a->d[1], a->d[7]); - muladd2(a->d[2], a->d[6]); - muladd2(a->d[3], a->d[5]); - muladd(a->d[4], a->d[4]); - extract(l[8]); - muladd2(a->d[2], a->d[7]); - muladd2(a->d[3], a->d[6]); - muladd2(a->d[4], a->d[5]); - extract(l[9]); - muladd2(a->d[3], a->d[7]); - muladd2(a->d[4], a->d[6]); - muladd(a->d[5], a->d[5]); - extract(l[10]); - muladd2(a->d[4], a->d[7]); - muladd2(a->d[5], a->d[6]); - extract(l[11]); - muladd2(a->d[5], a->d[7]); - muladd(a->d[6], a->d[6]); - extract(l[12]); - muladd2(a->d[6], a->d[7]); - extract(l[13]); - muladd_fast(a->d[7], a->d[7]); - extract_fast(l[14]); - VERIFY_CHECK(c1 == 0); - l[15] = c0; -} - #undef sumadd #undef sumadd_fast #undef muladd #undef muladd_fast -#undef muladd2 #undef extract #undef extract_fast static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { uint32_t l[16]; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + secp256k1_scalar_mul_512(l, a, b); secp256k1_scalar_reduce_512(r, l); + + SECP256K1_SCALAR_VERIFY(r); } -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { - int ret; - VERIFY_CHECK(n > 0); - VERIFY_CHECK(n < 16); - ret = r->d[0] & ((1 << n) - 1); - r->d[0] = (r->d[0] >> n) + (r->d[1] << (32 - n)); - r->d[1] = (r->d[1] >> n) + (r->d[2] << (32 - n)); - r->d[2] = (r->d[2] >> n) + (r->d[3] << (32 - n)); - r->d[3] = (r->d[3] >> n) + (r->d[4] << (32 - n)); - r->d[4] = (r->d[4] >> n) + (r->d[5] << (32 - n)); - r->d[5] = (r->d[5] >> n) + (r->d[6] << (32 - n)); - r->d[6] = (r->d[6] >> n) + (r->d[7] << (32 - n)); - r->d[7] = (r->d[7] >> n); - return ret; -} +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k) { + SECP256K1_SCALAR_VERIFY(k); -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { - uint32_t l[16]; - secp256k1_scalar_sqr_512(l, a); - secp256k1_scalar_reduce_512(r, l); -} - -#ifdef USE_ENDOMORPHISM -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - r1->d[0] = a->d[0]; - r1->d[1] = a->d[1]; - r1->d[2] = a->d[2]; - r1->d[3] = a->d[3]; + r1->d[0] = k->d[0]; + r1->d[1] = k->d[1]; + r1->d[2] = k->d[2]; + r1->d[3] = k->d[3]; r1->d[4] = 0; r1->d[5] = 0; r1->d[6] = 0; r1->d[7] = 0; - r2->d[0] = a->d[4]; - r2->d[1] = a->d[5]; - r2->d[2] = a->d[6]; - r2->d[3] = a->d[7]; + r2->d[0] = k->d[4]; + r2->d[1] = k->d[5]; + r2->d[2] = k->d[6]; + r2->d[3] = k->d[7]; r2->d[4] = 0; r2->d[5] = 0; r2->d[6] = 0; r2->d[7] = 0; + + SECP256K1_SCALAR_VERIFY(r1); + SECP256K1_SCALAR_VERIFY(r2); } -#endif SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0; } @@ -702,7 +685,10 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, unsigned int shiftlimbs; unsigned int shiftlow; unsigned int shifthigh; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); VERIFY_CHECK(shift >= 256); + secp256k1_scalar_mul_512(l, a, b); shiftlimbs = shift >> 5; shiftlow = shift & 0x1F; @@ -716,6 +702,115 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0; secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1); + + SECP256K1_SCALAR_VERIFY(r); } +static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { + uint32_t mask0, mask1; + volatile int vflag = flag; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d)); + + mask0 = vflag + ~((uint32_t)0); + mask1 = ~mask0; + r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1); + r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1); + r->d[2] = (r->d[2] & mask0) | (a->d[2] & mask1); + r->d[3] = (r->d[3] & mask0) | (a->d[3] & mask1); + r->d[4] = (r->d[4] & mask0) | (a->d[4] & mask1); + r->d[5] = (r->d[5] & mask0) | (a->d[5] & mask1); + r->d[6] = (r->d[6] & mask0) | (a->d[6] & mask1); + r->d[7] = (r->d[7] & mask0) | (a->d[7] & mask1); + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_from_signed30(secp256k1_scalar *r, const secp256k1_modinv32_signed30 *a) { + const uint32_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4], + a5 = a->v[5], a6 = a->v[6], a7 = a->v[7], a8 = a->v[8]; + + /* The output from secp256k1_modinv32{_var} should be normalized to range [0,modulus), and + * have limbs in [0,2^30). The modulus is < 2^256, so the top limb must be below 2^(256-30*8). + */ + VERIFY_CHECK(a0 >> 30 == 0); + VERIFY_CHECK(a1 >> 30 == 0); + VERIFY_CHECK(a2 >> 30 == 0); + VERIFY_CHECK(a3 >> 30 == 0); + VERIFY_CHECK(a4 >> 30 == 0); + VERIFY_CHECK(a5 >> 30 == 0); + VERIFY_CHECK(a6 >> 30 == 0); + VERIFY_CHECK(a7 >> 30 == 0); + VERIFY_CHECK(a8 >> 16 == 0); + + r->d[0] = a0 | a1 << 30; + r->d[1] = a1 >> 2 | a2 << 28; + r->d[2] = a2 >> 4 | a3 << 26; + r->d[3] = a3 >> 6 | a4 << 24; + r->d[4] = a4 >> 8 | a5 << 22; + r->d[5] = a5 >> 10 | a6 << 20; + r->d[6] = a6 >> 12 | a7 << 18; + r->d[7] = a7 >> 14 | a8 << 16; + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_to_signed30(secp256k1_modinv32_signed30 *r, const secp256k1_scalar *a) { + const uint32_t M30 = UINT32_MAX >> 2; + const uint32_t a0 = a->d[0], a1 = a->d[1], a2 = a->d[2], a3 = a->d[3], + a4 = a->d[4], a5 = a->d[5], a6 = a->d[6], a7 = a->d[7]; + SECP256K1_SCALAR_VERIFY(a); + + r->v[0] = a0 & M30; + r->v[1] = (a0 >> 30 | a1 << 2) & M30; + r->v[2] = (a1 >> 28 | a2 << 4) & M30; + r->v[3] = (a2 >> 26 | a3 << 6) & M30; + r->v[4] = (a3 >> 24 | a4 << 8) & M30; + r->v[5] = (a4 >> 22 | a5 << 10) & M30; + r->v[6] = (a5 >> 20 | a6 << 12) & M30; + r->v[7] = (a6 >> 18 | a7 << 14) & M30; + r->v[8] = a7 >> 16; +} + +static const secp256k1_modinv32_modinfo secp256k1_const_modinfo_scalar = { + {{0x10364141L, 0x3F497A33L, 0x348A03BBL, 0x2BB739ABL, -0x146L, 0, 0, 0, 65536}}, + 0x2A774EC1L +}; + +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_modinv32_signed30 s; +#ifdef VERIFY + int zero_in = secp256k1_scalar_is_zero(x); #endif + SECP256K1_SCALAR_VERIFY(x); + + secp256k1_scalar_to_signed30(&s, x); + secp256k1_modinv32(&s, &secp256k1_const_modinfo_scalar); + secp256k1_scalar_from_signed30(r, &s); + + SECP256K1_SCALAR_VERIFY(r); + VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in); +} + +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_modinv32_signed30 s; +#ifdef VERIFY + int zero_in = secp256k1_scalar_is_zero(x); +#endif + SECP256K1_SCALAR_VERIFY(x); + + secp256k1_scalar_to_signed30(&s, x); + secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_scalar); + secp256k1_scalar_from_signed30(r, &s); + + SECP256K1_SCALAR_VERIFY(r); + VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in); +} + +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + + return !(a->d[0] & 1); +} + +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scalar_impl.h b/crypto/secp256k1/libsecp256k1/src/scalar_impl.h index f5b2376407..0232a8c223 100644 --- a/crypto/secp256k1/libsecp256k1/src/scalar_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/scalar_impl.h @@ -1,316 +1,120 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCALAR_IMPL_H_ -#define _SECP256K1_SCALAR_IMPL_H_ +#ifndef SECP256K1_SCALAR_IMPL_H +#define SECP256K1_SCALAR_IMPL_H -#include "group.h" -#include "scalar.h" - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" +#ifdef VERIFY +#include #endif +#include "scalar.h" +#include "util.h" + #if defined(EXHAUSTIVE_TEST_ORDER) #include "scalar_low_impl.h" -#elif defined(USE_SCALAR_4X64) +#elif defined(SECP256K1_WIDEMUL_INT128) #include "scalar_4x64_impl.h" -#elif defined(USE_SCALAR_8X32) +#elif defined(SECP256K1_WIDEMUL_INT64) #include "scalar_8x32_impl.h" #else -#error "Please select scalar implementation" +#error "Please select wide multiplication implementation" #endif -#ifndef USE_NUM_NONE -static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a) { - unsigned char c[32]; - secp256k1_scalar_get_b32(c, a); - secp256k1_num_set_bin(r, c, 32); +static const secp256k1_scalar secp256k1_scalar_one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); +static const secp256k1_scalar secp256k1_scalar_zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { + secp256k1_memclear(r, sizeof(secp256k1_scalar)); +} + +static int secp256k1_scalar_set_b32_seckey(secp256k1_scalar *r, const unsigned char *bin) { + int overflow; + secp256k1_scalar_set_b32(r, bin, &overflow); + + SECP256K1_SCALAR_VERIFY(r); + return (!overflow) & (!secp256k1_scalar_is_zero(r)); +} + +static void secp256k1_scalar_verify(const secp256k1_scalar *r) { + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); + + (void)r; } -/** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ -static void secp256k1_scalar_order_get_num(secp256k1_num *r) { #if defined(EXHAUSTIVE_TEST_ORDER) - static const unsigned char order[32] = { - 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,0,EXHAUSTIVE_TEST_ORDER - }; -#else - static const unsigned char order[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 - }; -#endif - secp256k1_num_set_bin(r, order, 32); -} -#endif +/* Begin of section generated by sage/gen_exhaustive_groups.sage. */ +# if EXHAUSTIVE_TEST_ORDER == 7 +# define EXHAUSTIVE_TEST_LAMBDA 2 +# elif EXHAUSTIVE_TEST_ORDER == 13 +# define EXHAUSTIVE_TEST_LAMBDA 9 +# elif EXHAUSTIVE_TEST_ORDER == 199 +# define EXHAUSTIVE_TEST_LAMBDA 92 +# else +# error No known lambda for the specified exhaustive test group order. +# endif +/* End of section generated by sage/gen_exhaustive_groups.sage. */ -static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { -#if defined(EXHAUSTIVE_TEST_ORDER) - int i; - *r = 0; - for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) - if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) - *r = i; - /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus - * have a composite group order; fix it in exhaustive_tests.c). */ - VERIFY_CHECK(*r != 0); -} -#else - secp256k1_scalar *t; - int i; - /* First compute x ^ (2^N - 1) for some values of N. */ - secp256k1_scalar x2, x3, x4, x6, x7, x8, x15, x30, x60, x120, x127; - - secp256k1_scalar_sqr(&x2, x); - secp256k1_scalar_mul(&x2, &x2, x); - - secp256k1_scalar_sqr(&x3, &x2); - secp256k1_scalar_mul(&x3, &x3, x); - - secp256k1_scalar_sqr(&x4, &x3); - secp256k1_scalar_mul(&x4, &x4, x); - - secp256k1_scalar_sqr(&x6, &x4); - secp256k1_scalar_sqr(&x6, &x6); - secp256k1_scalar_mul(&x6, &x6, &x2); - - secp256k1_scalar_sqr(&x7, &x6); - secp256k1_scalar_mul(&x7, &x7, x); - - secp256k1_scalar_sqr(&x8, &x7); - secp256k1_scalar_mul(&x8, &x8, x); - - secp256k1_scalar_sqr(&x15, &x8); - for (i = 0; i < 6; i++) { - secp256k1_scalar_sqr(&x15, &x15); - } - secp256k1_scalar_mul(&x15, &x15, &x7); - - secp256k1_scalar_sqr(&x30, &x15); - for (i = 0; i < 14; i++) { - secp256k1_scalar_sqr(&x30, &x30); - } - secp256k1_scalar_mul(&x30, &x30, &x15); - - secp256k1_scalar_sqr(&x60, &x30); - for (i = 0; i < 29; i++) { - secp256k1_scalar_sqr(&x60, &x60); - } - secp256k1_scalar_mul(&x60, &x60, &x30); - - secp256k1_scalar_sqr(&x120, &x60); - for (i = 0; i < 59; i++) { - secp256k1_scalar_sqr(&x120, &x120); - } - secp256k1_scalar_mul(&x120, &x120, &x60); - - secp256k1_scalar_sqr(&x127, &x120); - for (i = 0; i < 6; i++) { - secp256k1_scalar_sqr(&x127, &x127); - } - secp256k1_scalar_mul(&x127, &x127, &x7); - - /* Then accumulate the final result (t starts at x127). */ - t = &x127; - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 3; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 5; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 5; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x4); /* 1111 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 4; i++) { /* 000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 10; i++) { /* 0000000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 9; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x8); /* 11111111 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 5; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x4); /* 1111 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 5; i++) { /* 000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 4; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 8; i++) { /* 000000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 3; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 3; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 6; i++) { /* 00000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 8; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(r, t, &x6); /* 111111 */ -} - -SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { - return !(a->d[0] & 1); -} -#endif - -static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { -#if defined(USE_SCALAR_INV_BUILTIN) - secp256k1_scalar_inverse(r, x); -#elif defined(USE_SCALAR_INV_NUM) - unsigned char b[32]; - secp256k1_num n, m; - secp256k1_scalar t = *x; - secp256k1_scalar_get_b32(b, &t); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_scalar_order_get_num(&m); - secp256k1_num_mod_inverse(&n, &n, &m); - secp256k1_num_get_bin(b, 32, &n); - secp256k1_scalar_set_b32(r, b, NULL); - /* Verify that the inverse was computed correctly, without GMP code. */ - secp256k1_scalar_mul(&t, &t, r); - CHECK(secp256k1_scalar_is_one(&t)); -#else -#error "Please select scalar inverse implementation" -#endif -} - -#ifdef USE_ENDOMORPHISM -#if defined(EXHAUSTIVE_TEST_ORDER) /** - * Find k1 and k2 given k, such that k1 + k2 * lambda == k mod n; unlike in the - * full case we don't bother making k1 and k2 be small, we just want them to be + * Find r1 and r2 given k, such that r1 + r2 * lambda == k mod n; unlike in the + * full case we don't bother making r1 and r2 be small, we just want them to be * nontrivial to get full test coverage for the exhaustive tests. We therefore - * (arbitrarily) set k2 = k + 5 and k1 = k - k2 * lambda. + * (arbitrarily) set r2 = k + 5 (mod n) and r1 = k - r2 * lambda (mod n). */ -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - *r2 = (*a + 5) % EXHAUSTIVE_TEST_ORDER; - *r1 = (*a + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; +static void secp256k1_scalar_split_lambda(secp256k1_scalar * SECP256K1_RESTRICT r1, secp256k1_scalar * SECP256K1_RESTRICT r2, const secp256k1_scalar * SECP256K1_RESTRICT k) { + SECP256K1_SCALAR_VERIFY(k); + VERIFY_CHECK(r1 != k); + VERIFY_CHECK(r2 != k); + VERIFY_CHECK(r1 != r2); + + *r2 = (*k + 5) % EXHAUSTIVE_TEST_ORDER; + *r1 = (*k + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; + + SECP256K1_SCALAR_VERIFY(r1); + SECP256K1_SCALAR_VERIFY(r2); } #else /** * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where - * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, - * 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72} + * lambda is: */ +static const secp256k1_scalar secp256k1_const_lambda = SECP256K1_SCALAR_CONST( + 0x5363AD4CUL, 0xC05C30E0UL, 0xA5261C02UL, 0x8812645AUL, + 0x122E22EAUL, 0x20816678UL, 0xDF02967CUL, 0x1B23BD72UL +); + +#ifdef VERIFY +static void secp256k1_scalar_split_lambda_verify(const secp256k1_scalar *r1, const secp256k1_scalar *r2, const secp256k1_scalar *k); +#endif + +/* + * Both lambda and beta are primitive cube roots of unity. That is lambda^3 == 1 mod n and + * beta^3 == 1 mod p, where n is the curve order and p is the field order. * - * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm - * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 - * and k2 have a small size. - * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are: + * Furthermore, because (X^3 - 1) = (X - 1)(X^2 + X + 1), the primitive cube roots of unity are + * roots of X^2 + X + 1. Therefore lambda^2 + lambda == -1 mod n and beta^2 + beta == -1 mod p. + * (The other primitive cube roots of unity are lambda^2 and beta^2 respectively.) + * + * Let l = -1/2 + i*sqrt(3)/2, the complex root of X^2 + X + 1. We can define a ring + * homomorphism phi : Z[l] -> Z_n where phi(a + b*l) == a + b*lambda mod n. The kernel of phi + * is a lattice over Z[l] (considering Z[l] as a Z-module). This lattice is generated by a + * reduced basis {a1 + b1*l, a2 + b2*l} where * * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3} * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8} * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} * - * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives + * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm + * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 + * and k2 are small in absolute value. + * + * The algorithm computes c1 = round(b2 * k / n) and c2 = round((-b1) * k / n), and gives * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and - * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2. + * compute r2 = k2 mod n, and r1 = k1 mod n = (k - r2 * lambda) mod n, avoiding the need for + * the constants a1 and a2. * * g1, g2 are precomputed constants used to replace division with a rounded multiplication * when decomposing the scalar for an endomorphism-based point multiplication. @@ -322,21 +126,21 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez), * Section 4.3 (here we use a somewhat higher-precision estimate): * d = a1*b2 - b1*a2 - * g1 = round((2^272)*b2/d) - * g2 = round((2^272)*b1/d) + * g1 = round(2^384 * b2/d) + * g2 = round(2^384 * (-b1)/d) * - * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found - * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda'). + * (Note that d is also equal to the curve order, n, here because [a1,b1] and [a2,b2] + * can be found as outputs of the Extended Euclidean Algorithm on inputs n and lambda). * - * The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order). + * The function below splits k into r1 and r2, such that + * - r1 + lambda * r2 == k (mod n) + * - either r1 < 2^128 or -r1 mod n < 2^128 + * - either r2 < 2^128 or -r2 mod n < 2^128 + * + * See proof below. */ - -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { +static void secp256k1_scalar_split_lambda(secp256k1_scalar * SECP256K1_RESTRICT r1, secp256k1_scalar * SECP256K1_RESTRICT r2, const secp256k1_scalar * SECP256K1_RESTRICT k) { secp256k1_scalar c1, c2; - static const secp256k1_scalar minus_lambda = SECP256K1_SCALAR_CONST( - 0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL, - 0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL - ); static const secp256k1_scalar minus_b1 = SECP256K1_SCALAR_CONST( 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL @@ -346,25 +150,172 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL ); static const secp256k1_scalar g1 = SECP256K1_SCALAR_CONST( - 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL, - 0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL + 0x3086D221UL, 0xA7D46BCDUL, 0xE86C90E4UL, 0x9284EB15UL, + 0x3DAA8A14UL, 0x71E8CA7FUL, 0xE893209AUL, 0x45DBB031UL ); static const secp256k1_scalar g2 = SECP256K1_SCALAR_CONST( - 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL, - 0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL + 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C4UL, + 0x221208ACUL, 0x9DF506C6UL, 0x1571B4AEUL, 0x8AC47F71UL ); - VERIFY_CHECK(r1 != a); - VERIFY_CHECK(r2 != a); + SECP256K1_SCALAR_VERIFY(k); + VERIFY_CHECK(r1 != k); + VERIFY_CHECK(r2 != k); + VERIFY_CHECK(r1 != r2); + /* these _var calls are constant time since the shift amount is constant */ - secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272); - secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272); + secp256k1_scalar_mul_shift_var(&c1, k, &g1, 384); + secp256k1_scalar_mul_shift_var(&c2, k, &g2, 384); secp256k1_scalar_mul(&c1, &c1, &minus_b1); secp256k1_scalar_mul(&c2, &c2, &minus_b2); secp256k1_scalar_add(r2, &c1, &c2); - secp256k1_scalar_mul(r1, r2, &minus_lambda); - secp256k1_scalar_add(r1, r1, a); -} -#endif -#endif + secp256k1_scalar_mul(r1, r2, &secp256k1_const_lambda); + secp256k1_scalar_negate(r1, r1); + secp256k1_scalar_add(r1, r1, k); + SECP256K1_SCALAR_VERIFY(r1); + SECP256K1_SCALAR_VERIFY(r2); +#ifdef VERIFY + secp256k1_scalar_split_lambda_verify(r1, r2, k); #endif +} + +#ifdef VERIFY +/* + * Proof for secp256k1_scalar_split_lambda's bounds. + * + * Let + * - epsilon1 = 2^256 * |g1/2^384 - b2/d| + * - epsilon2 = 2^256 * |g2/2^384 - (-b1)/d| + * - c1 = round(k*g1/2^384) + * - c2 = round(k*g2/2^384) + * + * Lemma 1: |c1 - k*b2/d| < 2^-1 + epsilon1 + * + * |c1 - k*b2/d| + * = + * |c1 - k*g1/2^384 + k*g1/2^384 - k*b2/d| + * <= {triangle inequality} + * |c1 - k*g1/2^384| + |k*g1/2^384 - k*b2/d| + * = + * |c1 - k*g1/2^384| + k*|g1/2^384 - b2/d| + * < {rounding in c1 and 0 <= k < 2^256} + * 2^-1 + 2^256 * |g1/2^384 - b2/d| + * = {definition of epsilon1} + * 2^-1 + epsilon1 + * + * Lemma 2: |c2 - k*(-b1)/d| < 2^-1 + epsilon2 + * + * |c2 - k*(-b1)/d| + * = + * |c2 - k*g2/2^384 + k*g2/2^384 - k*(-b1)/d| + * <= {triangle inequality} + * |c2 - k*g2/2^384| + |k*g2/2^384 - k*(-b1)/d| + * = + * |c2 - k*g2/2^384| + k*|g2/2^384 - (-b1)/d| + * < {rounding in c2 and 0 <= k < 2^256} + * 2^-1 + 2^256 * |g2/2^384 - (-b1)/d| + * = {definition of epsilon2} + * 2^-1 + epsilon2 + * + * Let + * - k1 = k - c1*a1 - c2*a2 + * - k2 = - c1*b1 - c2*b2 + * + * Lemma 3: |k1| < (a1 + a2 + 1)/2 < 2^128 + * + * |k1| + * = {definition of k1} + * |k - c1*a1 - c2*a2| + * = {(a1*b2 - b1*a2)/n = 1} + * |k*(a1*b2 - b1*a2)/n - c1*a1 - c2*a2| + * = + * |a1*(k*b2/n - c1) + a2*(k*(-b1)/n - c2)| + * <= {triangle inequality} + * a1*|k*b2/n - c1| + a2*|k*(-b1)/n - c2| + * < {Lemma 1 and Lemma 2} + * a1*(2^-1 + epsilon1) + a2*(2^-1 + epsilon2) + * < {rounding up to an integer} + * (a1 + a2 + 1)/2 + * < {rounding up to a power of 2} + * 2^128 + * + * Lemma 4: |k2| < (-b1 + b2)/2 + 1 < 2^128 + * + * |k2| + * = {definition of k2} + * |- c1*a1 - c2*a2| + * = {(b1*b2 - b1*b2)/n = 0} + * |k*(b1*b2 - b1*b2)/n - c1*b1 - c2*b2| + * = + * |b1*(k*b2/n - c1) + b2*(k*(-b1)/n - c2)| + * <= {triangle inequality} + * (-b1)*|k*b2/n - c1| + b2*|k*(-b1)/n - c2| + * < {Lemma 1 and Lemma 2} + * (-b1)*(2^-1 + epsilon1) + b2*(2^-1 + epsilon2) + * < {rounding up to an integer} + * (-b1 + b2)/2 + 1 + * < {rounding up to a power of 2} + * 2^128 + * + * Let + * - r2 = k2 mod n + * - r1 = k - r2*lambda mod n. + * + * Notice that r1 is defined such that r1 + r2 * lambda == k (mod n). + * + * Lemma 5: r1 == k1 mod n. + * + * r1 + * == {definition of r1 and r2} + * k - k2*lambda + * == {definition of k2} + * k - (- c1*b1 - c2*b2)*lambda + * == + * k + c1*b1*lambda + c2*b2*lambda + * == {a1 + b1*lambda == 0 mod n and a2 + b2*lambda == 0 mod n} + * k - c1*a1 - c2*a2 + * == {definition of k1} + * k1 + * + * From Lemma 3, Lemma 4, Lemma 5 and the definition of r2, we can conclude that + * + * - either r1 < 2^128 or -r1 mod n < 2^128 + * - either r2 < 2^128 or -r2 mod n < 2^128. + * + * Q.E.D. + */ +static void secp256k1_scalar_split_lambda_verify(const secp256k1_scalar *r1, const secp256k1_scalar *r2, const secp256k1_scalar *k) { + secp256k1_scalar s; + unsigned char buf1[32]; + unsigned char buf2[32]; + + /* (a1 + a2 + 1)/2 is 0xa2a8918ca85bafe22016d0b917e4dd77 */ + static const unsigned char k1_bound[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa2, 0xa8, 0x91, 0x8c, 0xa8, 0x5b, 0xaf, 0xe2, 0x20, 0x16, 0xd0, 0xb9, 0x17, 0xe4, 0xdd, 0x77 + }; + + /* (-b1 + b2)/2 + 1 is 0x8a65287bd47179fb2be08846cea267ed */ + static const unsigned char k2_bound[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8a, 0x65, 0x28, 0x7b, 0xd4, 0x71, 0x79, 0xfb, 0x2b, 0xe0, 0x88, 0x46, 0xce, 0xa2, 0x67, 0xed + }; + + secp256k1_scalar_mul(&s, &secp256k1_const_lambda, r2); + secp256k1_scalar_add(&s, &s, r1); + VERIFY_CHECK(secp256k1_scalar_eq(&s, k)); + + secp256k1_scalar_negate(&s, r1); + secp256k1_scalar_get_b32(buf1, r1); + secp256k1_scalar_get_b32(buf2, &s); + VERIFY_CHECK(secp256k1_memcmp_var(buf1, k1_bound, 32) < 0 || secp256k1_memcmp_var(buf2, k1_bound, 32) < 0); + + secp256k1_scalar_negate(&s, r2); + secp256k1_scalar_get_b32(buf1, r2); + secp256k1_scalar_get_b32(buf2, &s); + VERIFY_CHECK(secp256k1_memcmp_var(buf1, k2_bound, 32) < 0 || secp256k1_memcmp_var(buf2, k2_bound, 32) < 0); +} +#endif /* VERIFY */ +#endif /* !defined(EXHAUSTIVE_TEST_ORDER) */ + +#endif /* SECP256K1_SCALAR_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scalar_low.h b/crypto/secp256k1/libsecp256k1/src/scalar_low.h index 5574c44c7a..2711eb932d 100644 --- a/crypto/secp256k1/libsecp256k1/src/scalar_low.h +++ b/crypto/secp256k1/libsecp256k1/src/scalar_low.h @@ -1,15 +1,24 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015, 2022 Andrew Poelstra, Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_ -#define _SECP256K1_SCALAR_REPR_ +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H #include /** A scalar modulo the group order of the secp256k1 curve. */ typedef uint32_t secp256k1_scalar; -#endif +/* A compile-time constant equal to 2^32 (modulo order). */ +#define SCALAR_2P32 ((0xffffffffUL % EXHAUSTIVE_TEST_ORDER) + 1U) + +/* Compute a*2^32 + b (modulo order). */ +#define SCALAR_HORNER(a, b) (((uint64_t)(a) * SCALAR_2P32 + (b)) % EXHAUSTIVE_TEST_ORDER) + +/* Evaluates to the provided 256-bit constant reduced modulo order. */ +#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER((d7), (d6)), (d5)), (d4)), (d3)), (d2)), (d1)), (d0)) + +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scalar_low_impl.h b/crypto/secp256k1/libsecp256k1/src/scalar_low_impl.h index 4f94441f49..84e1a380a3 100644 --- a/crypto/secp256k1/libsecp256k1/src/scalar_low_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/scalar_low_impl.h @@ -1,114 +1,206 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ -#define _SECP256K1_SCALAR_REPR_IMPL_H_ +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H +#include "checkmem.h" #include "scalar.h" +#include "util.h" #include SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + return !(*a & 1); } -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } -SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { + *r = v % EXHAUSTIVE_TEST_ORDER; -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - if (offset < 32) - return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); - else - return 0; + SECP256K1_SCALAR_VERIFY(r); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - return secp256k1_scalar_get_bits(a, offset, count); +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + SECP256K1_SCALAR_VERIFY(a); + + VERIFY_CHECK(count > 0 && count <= 32); + if (offset < 32) { + return (*a >> offset) & (0xFFFFFFFF >> (32 - count)); + } else { + return 0; + } +} + +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + SECP256K1_SCALAR_VERIFY(a); + + return secp256k1_scalar_get_bits_limb32(a, offset, count); } SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; + + SECP256K1_SCALAR_VERIFY(r); return *r < *b; } static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { + SECP256K1_SCALAR_VERIFY(r); + if (flag && bit < 32) - *r += (1 << bit); -#ifdef VERIFY - VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); -#endif + *r += ((uint32_t)1 << bit); + + SECP256K1_SCALAR_VERIFY(r); + VERIFY_CHECK(bit < 32); + /* Verify that adding (1 << bit) will not overflow any in-range scalar *r by overflowing the underlying uint32_t. */ + VERIFY_CHECK(((uint32_t)1 << bit) - 1 <= UINT32_MAX - EXHAUSTIVE_TEST_ORDER); } static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { - const int base = 0x100 % EXHAUSTIVE_TEST_ORDER; int i; + int over = 0; *r = 0; for (i = 0; i < 32; i++) { - *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER; + *r = (*r * 0x100) + b32[i]; + if (*r >= EXHAUSTIVE_TEST_ORDER) { + over = 1; + *r %= EXHAUSTIVE_TEST_ORDER; + } } - /* just deny overflow, it basically always happens */ - if (overflow) *overflow = 0; + if (overflow) *overflow = over; + + SECP256K1_SCALAR_VERIFY(r); } static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { + SECP256K1_SCALAR_VERIFY(a); + memset(bin, 0, 32); bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; } SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + return *a == 0; } static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + if (*a == 0) { *r = 0; } else { *r = EXHAUSTIVE_TEST_ORDER - *a; } + + SECP256K1_SCALAR_VERIFY(r); } SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + return *a == 1; } static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + return *a > EXHAUSTIVE_TEST_ORDER / 2; } static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + SECP256K1_SCALAR_VERIFY(r); + if (flag) secp256k1_scalar_negate(r, r); + + SECP256K1_SCALAR_VERIFY(r); return flag ? -1 : 1; } static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; -} -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { - int ret; - VERIFY_CHECK(n > 0); - VERIFY_CHECK(n < 16); - ret = *r & ((1 << n) - 1); - *r >>= n; - return ret; -} - -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { - *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER; + SECP256K1_SCALAR_VERIFY(r); } static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + *r1 = *a; *r2 = 0; + + SECP256K1_SCALAR_VERIFY(r1); + SECP256K1_SCALAR_VERIFY(r2); } SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_SCALAR_VERIFY(b); + return *a == *b; } -#endif +static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { + uint32_t mask0, mask1; + volatile int vflag = flag; + SECP256K1_SCALAR_VERIFY(a); + SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r)); + + mask0 = vflag + ~((uint32_t)0); + mask1 = ~mask0; + *r = (*r & mask0) | (*a & mask1); + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { + int i; + uint32_t res = 0; + SECP256K1_SCALAR_VERIFY(x); + + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) { + if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) { + res = i; + break; + } + } + + /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus + * have a composite group order; fix it in exhaustive_tests.c). */ + VERIFY_CHECK(res != 0); + *r = res; + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { + SECP256K1_SCALAR_VERIFY(x); + + secp256k1_scalar_inverse(r, x); + + SECP256K1_SCALAR_VERIFY(r); +} + +static void secp256k1_scalar_half(secp256k1_scalar *r, const secp256k1_scalar *a) { + SECP256K1_SCALAR_VERIFY(a); + + *r = (*a + ((-(uint32_t)(*a & 1)) & EXHAUSTIVE_TEST_ORDER)) >> 1; + + SECP256K1_SCALAR_VERIFY(r); +} + +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/scratch.h b/crypto/secp256k1/libsecp256k1/src/scratch.h new file mode 100644 index 0000000000..6164330b39 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/scratch.h @@ -0,0 +1,44 @@ +/*********************************************************************** + * Copyright (c) 2017 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCRATCH_H +#define SECP256K1_SCRATCH_H + +/* The typedef is used internally; the struct name is used in the public API + * (where it is exposed as a different typedef) */ +typedef struct secp256k1_scratch_space_struct { + /** guard against interpreting this object as other types */ + unsigned char magic[8]; + /** actual allocated data */ + void *data; + /** amount that has been allocated (i.e. `data + offset` is the next + * available pointer) */ + size_t alloc_size; + /** maximum size available to allocate */ + size_t max_size; +} secp256k1_scratch; + +typedef struct secp256k1_scratch_space_struct secp256k1_scratch_space; + +static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size); + +static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch); + +/** Returns an opaque object used to "checkpoint" a scratch space. Used + * with `secp256k1_scratch_apply_checkpoint` to undo allocations. */ +static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch); + +/** Applies a check point received from `secp256k1_scratch_checkpoint`, + * undoing all allocations since that point. */ +static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint); + +/** Returns the maximum allocation the scratch space will allow */ +static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t n_objects); + +/** Returns a pointer into the most recently allocated frame, or NULL if there is insufficient available space */ +static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t n); + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/scratch_impl.h b/crypto/secp256k1/libsecp256k1/src/scratch_impl.h new file mode 100644 index 0000000000..f71a20b963 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/scratch_impl.h @@ -0,0 +1,99 @@ +/*********************************************************************** + * Copyright (c) 2017 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCRATCH_IMPL_H +#define SECP256K1_SCRATCH_IMPL_H + +#include "util.h" +#include "scratch.h" + +static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t size) { + const size_t base_alloc = ROUND_TO_ALIGN(sizeof(secp256k1_scratch)); + void *alloc = checked_malloc(error_callback, base_alloc + size); + secp256k1_scratch* ret = (secp256k1_scratch *)alloc; + if (ret != NULL) { + memset(ret, 0, sizeof(*ret)); + memcpy(ret->magic, "scratch", 8); + ret->data = (void *) ((char *) alloc + base_alloc); + ret->max_size = size; + } + return ret; +} + +static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch) { + if (scratch != NULL) { + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return; + } + VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */ + memset(scratch->magic, 0, sizeof(scratch->magic)); + free(scratch); + } +} + +static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch) { + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return 0; + } + return scratch->alloc_size; +} + +static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint) { + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return; + } + if (checkpoint > scratch->alloc_size) { + secp256k1_callback_call(error_callback, "invalid checkpoint"); + return; + } + scratch->alloc_size = checkpoint; +} + +static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t objects) { + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return 0; + } + /* Ensure that multiplication will not wrap around */ + if (ALIGNMENT > 1 && objects > SIZE_MAX/(ALIGNMENT - 1)) { + return 0; + } + if (scratch->max_size - scratch->alloc_size <= objects * (ALIGNMENT - 1)) { + return 0; + } + return scratch->max_size - scratch->alloc_size - objects * (ALIGNMENT - 1); +} + +static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t size) { + void *ret; + size_t rounded_size; + + rounded_size = ROUND_TO_ALIGN(size); + /* Check that rounding did not wrap around */ + if (rounded_size < size) { + return NULL; + } + size = rounded_size; + + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return NULL; + } + + if (size > scratch->max_size - scratch->alloc_size) { + return NULL; + } + ret = (void *) ((char *) scratch->data + scratch->alloc_size); + memset(ret, 0, size); + scratch->alloc_size += size; + + return ret; +} + +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/secp256k1.c b/crypto/secp256k1/libsecp256k1/src/secp256k1.c old mode 100755 new mode 100644 index 7d637bfad1..a248519dfd --- a/crypto/secp256k1/libsecp256k1/src/secp256k1.c +++ b/crypto/secp256k1/libsecp256k1/src/secp256k1.c @@ -1,13 +1,29 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#include "include/secp256k1.h" +/* This is a C project. It should not be compiled with a C++ compiler, + * and we error out if we detect one. + * + * We still want to be able to test the project with a C++ compiler + * because it is still good to know if this will lead to real trouble, so + * there is a possibility to override the check. But be warned that + * compiling with a C++ compiler is not supported. */ +#if defined(__cplusplus) && !defined(SECP256K1_CPLUSPLUS_TEST_OVERRIDE) +#error Trying to compile a C project with a C++ compiler. +#endif +#define SECP256K1_BUILD + +#include "../include/secp256k1.h" +#include "../include/secp256k1_preallocated.h" + +#include "assumptions.h" +#include "checkmem.h" #include "util.h" -#include "num_impl.h" + #include "field_impl.h" #include "scalar_impl.h" #include "group_impl.h" @@ -17,6 +33,14 @@ #include "ecdsa_impl.h" #include "eckey_impl.h" #include "hash_impl.h" +#include "int128_impl.h" +#include "scratch_impl.h" +#include "selftest.h" +#include "hsort_impl.h" + +#ifdef SECP256K1_NO_BUILD +# error "secp256k1.h processed without SECP256K1_BUILD defined while building secp256k1.c" +#endif #define ARG_CHECK(cond) do { \ if (EXPECT(!(cond), 0)) { \ @@ -25,124 +49,202 @@ } \ } while(0) -static void default_illegal_callback_fn(const char* str, void* data) { - fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); - abort(); -} - -static const secp256k1_callback default_illegal_callback = { - default_illegal_callback_fn, - NULL -}; - -static void default_error_callback_fn(const char* str, void* data) { - fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); - abort(); -} - -static const secp256k1_callback default_error_callback = { - default_error_callback_fn, - NULL -}; - +#define ARG_CHECK_VOID(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + secp256k1_callback_call(&ctx->illegal_callback, #cond); \ + return; \ + } \ +} while(0) +/* Note that whenever you change the context struct, you must also change the + * context_eq function. */ struct secp256k1_context_struct { - secp256k1_ecmult_context ecmult_ctx; secp256k1_ecmult_gen_context ecmult_gen_ctx; secp256k1_callback illegal_callback; secp256k1_callback error_callback; + int declassify; }; -secp256k1_context* secp256k1_context_create(unsigned int flags) { - secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context)); +static const secp256k1_context secp256k1_context_static_ = { + { 0 }, + { secp256k1_default_illegal_callback_fn, 0 }, + { secp256k1_default_error_callback_fn, 0 }, + 0 +}; +const secp256k1_context *secp256k1_context_static = &secp256k1_context_static_; +const secp256k1_context *secp256k1_context_no_precomp = &secp256k1_context_static_; + +/* Helper function that determines if a context is proper, i.e., is not the static context or a copy thereof. + * + * This is intended for "context" functions such as secp256k1_context_clone. Functions that need specific + * features of a context should still check for these features directly. For example, a function that needs + * ecmult_gen should directly check for the existence of the ecmult_gen context. */ +static int secp256k1_context_is_proper(const secp256k1_context* ctx) { + return secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx); +} + +void secp256k1_selftest(void) { + if (!secp256k1_selftest_passes()) { + secp256k1_callback_call(&default_error_callback, "self test failed"); + } +} + +size_t secp256k1_context_preallocated_size(unsigned int flags) { + size_t ret = sizeof(secp256k1_context); + /* A return value of 0 is reserved as an indicator for errors when we call this function internally. */ + VERIFY_CHECK(ret != 0); + + if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { + secp256k1_callback_call(&default_illegal_callback, + "Invalid flags"); + return 0; + } + + if (EXPECT(!SECP256K1_CHECKMEM_RUNNING() && (flags & SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY), 0)) { + secp256k1_callback_call(&default_illegal_callback, + "Declassify flag requires running with memory checking"); + return 0; + } + + return ret; +} + +size_t secp256k1_context_preallocated_clone_size(const secp256k1_context* ctx) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_context_is_proper(ctx)); + return sizeof(secp256k1_context); +} + +secp256k1_context* secp256k1_context_preallocated_create(void* prealloc, unsigned int flags) { + size_t prealloc_size; + secp256k1_context* ret; + + secp256k1_selftest(); + + prealloc_size = secp256k1_context_preallocated_size(flags); + if (prealloc_size == 0) { + return NULL; + } + VERIFY_CHECK(prealloc != NULL); + ret = (secp256k1_context*)prealloc; ret->illegal_callback = default_illegal_callback; ret->error_callback = default_error_callback; - if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { - secp256k1_callback_call(&ret->illegal_callback, - "Invalid flags"); - free(ret); - return NULL; + /* Flags have been checked by secp256k1_context_preallocated_size. */ + VERIFY_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_CONTEXT); + secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx); + ret->declassify = !!(flags & SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY); + + return ret; +} + +secp256k1_context* secp256k1_context_create(unsigned int flags) { + size_t const prealloc_size = secp256k1_context_preallocated_size(flags); + secp256k1_context* ctx = (secp256k1_context*)checked_malloc(&default_error_callback, prealloc_size); + if (EXPECT(secp256k1_context_preallocated_create(ctx, flags) == NULL, 0)) { + free(ctx); + return NULL; } - secp256k1_ecmult_context_init(&ret->ecmult_ctx); - secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); + return ctx; +} - if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { - secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback); - } - if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) { - secp256k1_ecmult_context_build(&ret->ecmult_ctx, &ret->error_callback); - } +secp256k1_context* secp256k1_context_preallocated_clone(const secp256k1_context* ctx, void* prealloc) { + secp256k1_context* ret; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(prealloc != NULL); + ARG_CHECK(secp256k1_context_is_proper(ctx)); + ret = (secp256k1_context*)prealloc; + *ret = *ctx; return ret; } secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { - secp256k1_context* ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, sizeof(secp256k1_context)); - ret->illegal_callback = ctx->illegal_callback; - ret->error_callback = ctx->error_callback; - secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx, &ctx->error_callback); - secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx, &ctx->error_callback); + secp256k1_context* ret; + size_t prealloc_size; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_context_is_proper(ctx)); + + prealloc_size = secp256k1_context_preallocated_clone_size(ctx); + ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, prealloc_size); + ret = secp256k1_context_preallocated_clone(ctx, ret); return ret; } -void secp256k1_context_destroy(secp256k1_context* ctx) { - if (ctx != NULL) { - secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); - secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); +void secp256k1_context_preallocated_destroy(secp256k1_context* ctx) { + ARG_CHECK_VOID(ctx == NULL || secp256k1_context_is_proper(ctx)); - free(ctx); + /* Defined as noop */ + if (ctx == NULL) { + return; } + + secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); +} + +void secp256k1_context_destroy(secp256k1_context* ctx) { + ARG_CHECK_VOID(ctx == NULL || secp256k1_context_is_proper(ctx)); + + /* Defined as noop */ + if (ctx == NULL) { + return; + } + + secp256k1_context_preallocated_destroy(ctx); + free(ctx); } void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + /* We compare pointers instead of checking secp256k1_context_is_proper() here + because setting callbacks is allowed on *copies* of the static context: + it's harmless and makes testing easier. */ + ARG_CHECK_VOID(ctx != secp256k1_context_static); if (fun == NULL) { - fun = default_illegal_callback_fn; + fun = secp256k1_default_illegal_callback_fn; } ctx->illegal_callback.fn = fun; ctx->illegal_callback.data = data; } void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + /* We compare pointers instead of checking secp256k1_context_is_proper() here + because setting callbacks is allowed on *copies* of the static context: + it's harmless and makes testing easier. */ + ARG_CHECK_VOID(ctx != secp256k1_context_static); if (fun == NULL) { - fun = default_error_callback_fn; + fun = secp256k1_default_error_callback_fn; } ctx->error_callback.fn = fun; ctx->error_callback.data = data; } +static secp256k1_scratch_space* secp256k1_scratch_space_create(const secp256k1_context* ctx, size_t max_size) { + VERIFY_CHECK(ctx != NULL); + return secp256k1_scratch_create(&ctx->error_callback, max_size); +} + +static void secp256k1_scratch_space_destroy(const secp256k1_context *ctx, secp256k1_scratch_space* scratch) { + VERIFY_CHECK(ctx != NULL); + secp256k1_scratch_destroy(&ctx->error_callback, scratch); +} + +/* Mark memory as no-longer-secret for the purpose of analysing constant-time behaviour + * of the software. + */ +static SECP256K1_INLINE void secp256k1_declassify(const secp256k1_context* ctx, const void *p, size_t len) { + if (EXPECT(ctx->declassify, 0)) SECP256K1_CHECKMEM_DEFINE(p, len); +} + static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { - if (sizeof(secp256k1_ge_storage) == 64) { - /* When the secp256k1_ge_storage type is exactly 64 byte, use its - * representation inside secp256k1_pubkey, as conversion is very fast. - * Note that secp256k1_pubkey_save must use the same representation. */ - secp256k1_ge_storage s; - memcpy(&s, &pubkey->data[0], 64); - secp256k1_ge_from_storage(ge, &s); - } else { - /* Otherwise, fall back to 32-byte big endian for X and Y. */ - secp256k1_fe x, y; - secp256k1_fe_set_b32(&x, pubkey->data); - secp256k1_fe_set_b32(&y, pubkey->data + 32); - secp256k1_ge_set_xy(ge, &x, &y); - } + secp256k1_ge_from_bytes(ge, pubkey->data); ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); return 1; } static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { - if (sizeof(secp256k1_ge_storage) == 64) { - secp256k1_ge_storage s; - secp256k1_ge_to_storage(&s, ge); - memcpy(&pubkey->data[0], &s, 64); - } else { - VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); - secp256k1_fe_normalize_var(&ge->x); - secp256k1_fe_normalize_var(&ge->y); - secp256k1_fe_get_b32(pubkey->data, &ge->x); - secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); - } + secp256k1_ge_to_bytes(pubkey->data, ge); } int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { @@ -155,6 +257,9 @@ int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pu if (!secp256k1_eckey_pubkey_parse(&Q, input, inputlen)) { return 0; } + if (!secp256k1_ge_is_in_correct_subgroup(&Q)) { + return 0; + } secp256k1_pubkey_save(pubkey, &Q); secp256k1_ge_clear(&Q); return 1; @@ -167,7 +272,7 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *o VERIFY_CHECK(ctx != NULL); ARG_CHECK(outputlen != NULL); - ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33 : 65)); + ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33u : 65u)); len = *outputlen; *outputlen = 0; ARG_CHECK(output != NULL); @@ -183,6 +288,60 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *o return ret; } +int secp256k1_ec_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_pubkey* pubkey0, const secp256k1_pubkey* pubkey1) { + unsigned char out[2][33]; + const secp256k1_pubkey* pk[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + pk[0] = pubkey0; pk[1] = pubkey1; + for (i = 0; i < 2; i++) { + size_t out_size = sizeof(out[i]); + /* If the public key is NULL or invalid, ec_pubkey_serialize will call + * the illegal_callback and return 0. In that case we will serialize the + * key as all zeros which is less than any valid public key. This + * results in consistent comparisons even if NULL or invalid pubkeys are + * involved and prevents edge cases such as sorting algorithms that use + * this function and do not terminate as a result. */ + if (!secp256k1_ec_pubkey_serialize(ctx, out[i], &out_size, pk[i], SECP256K1_EC_COMPRESSED)) { + /* Note that ec_pubkey_serialize should already set the output to + * zero in that case, but it's not guaranteed by the API, we can't + * test it and writing a VERIFY_CHECK is more complex than + * explicitly memsetting (again). */ + memset(out[i], 0, sizeof(out[i])); + } + } + return secp256k1_memcmp_var(out[0], out[1], sizeof(out[0])); +} + +static int secp256k1_ec_pubkey_sort_cmp(const void* pk1, const void* pk2, void *ctx) { + return secp256k1_ec_pubkey_cmp((secp256k1_context *)ctx, + *(secp256k1_pubkey **)pk1, + *(secp256k1_pubkey **)pk2); +} + +int secp256k1_ec_pubkey_sort(const secp256k1_context* ctx, const secp256k1_pubkey **pubkeys, size_t n_pubkeys) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkeys != NULL); + + /* Suppress wrong warning (fixed in MSVC 19.33) */ + #if defined(_MSC_VER) && (_MSC_VER < 1933) + #pragma warning(push) + #pragma warning(disable: 4090) + #endif + + /* Casting away const is fine because neither secp256k1_hsort nor + * secp256k1_ec_pubkey_sort_cmp modify the data pointed to by the cmp_data + * argument. */ + secp256k1_hsort(pubkeys, n_pubkeys, sizeof(*pubkeys), secp256k1_ec_pubkey_sort_cmp, (void *)ctx); + + #if defined(_MSC_VER) && (_MSC_VER < 1933) + #pragma warning(pop) + #endif + + return 1; +} + static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) { (void)ctx; if (sizeof(secp256k1_scalar) == 32) { @@ -288,122 +447,163 @@ int secp256k1_ecdsa_signature_normalize(const secp256k1_context* ctx, secp256k1_ return ret; } -int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { +int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msghash32, const secp256k1_pubkey *pubkey) { secp256k1_ge q; secp256k1_scalar r, s; secp256k1_scalar m; VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(pubkey != NULL); - secp256k1_scalar_set_b32(&m, msg32, NULL); + secp256k1_scalar_set_b32(&m, msghash32, NULL); secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); return (!secp256k1_scalar_is_high(&s) && secp256k1_pubkey_load(ctx, &q, pubkey) && - secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m)); + secp256k1_ecdsa_sig_verify(&r, &s, &q, &m)); +} + +static SECP256K1_INLINE void buffer_append(unsigned char *buf, unsigned int *offset, const void *data, unsigned int len) { + memcpy(buf + *offset, data, len); + *offset += len; } static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { unsigned char keydata[112]; - int keylen = 64; - secp256k1_rfc6979_hmac_sha256_t rng; + unsigned int offset = 0; + secp256k1_rfc6979_hmac_sha256 rng; unsigned int i; + secp256k1_scalar msg; + unsigned char msgmod32[32]; + secp256k1_scalar_set_b32(&msg, msg32, NULL); + secp256k1_scalar_get_b32(msgmod32, &msg); /* We feed a byte array to the PRNG as input, consisting of: - * - the private key (32 bytes) and message (32 bytes), see RFC 6979 3.2d. + * - the private key (32 bytes) and reduced message (32 bytes), see RFC 6979 3.2d. * - optionally 32 extra bytes of data, see RFC 6979 3.6 Additional Data. * - optionally 16 extra bytes with the algorithm name. * Because the arguments have distinct fixed lengths it is not possible for * different argument mixtures to emulate each other and result in the same * nonces. */ - memcpy(keydata, key32, 32); - memcpy(keydata + 32, msg32, 32); + buffer_append(keydata, &offset, key32, 32); + buffer_append(keydata, &offset, msgmod32, 32); if (data != NULL) { - memcpy(keydata + 64, data, 32); - keylen = 96; + buffer_append(keydata, &offset, data, 32); } if (algo16 != NULL) { - memcpy(keydata + keylen, algo16, 16); - keylen += 16; + buffer_append(keydata, &offset, algo16, 16); } - secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, keylen); - memset(keydata, 0, sizeof(keydata)); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, offset); for (i = 0; i <= counter; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); + + secp256k1_memclear(keydata, sizeof(keydata)); + secp256k1_rfc6979_hmac_sha256_clear(&rng); return 1; } const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979; -int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { - secp256k1_scalar r, s; +static int secp256k1_ecdsa_sign_inner(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { secp256k1_scalar sec, non, msg; int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(signature != NULL); - ARG_CHECK(seckey != NULL); + int is_sec_valid; + unsigned char nonce32[32]; + unsigned int count = 0; + /* Default initialization here is important so we won't pass uninit values to the cmov in the end */ + *r = secp256k1_scalar_zero; + *s = secp256k1_scalar_zero; + if (recid) { + *recid = 0; + } if (noncefp == NULL) { noncefp = secp256k1_nonce_function_default; } - secp256k1_scalar_set_b32(&sec, seckey, &overflow); /* Fail if the secret key is invalid. */ - if (!overflow && !secp256k1_scalar_is_zero(&sec)) { - unsigned char nonce32[32]; - unsigned int count = 0; - secp256k1_scalar_set_b32(&msg, msg32, NULL); - while (1) { - ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); - if (!ret) { + is_sec_valid = secp256k1_scalar_set_b32_seckey(&sec, seckey); + secp256k1_scalar_cmov(&sec, &secp256k1_scalar_one, !is_sec_valid); + secp256k1_scalar_set_b32(&msg, msg32, NULL); + while (1) { + int is_nonce_valid; + ret = !!noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); + if (!ret) { + break; + } + is_nonce_valid = secp256k1_scalar_set_b32_seckey(&non, nonce32); + /* The nonce is still secret here, but it being invalid is less likely than 1:2^255. */ + secp256k1_declassify(ctx, &is_nonce_valid, sizeof(is_nonce_valid)); + if (is_nonce_valid) { + ret = secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, r, s, &sec, &msg, &non, recid); + /* The final signature is no longer a secret, nor is the fact that we were successful or not. */ + secp256k1_declassify(ctx, &ret, sizeof(ret)); + if (ret) { break; } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - if (!overflow && !secp256k1_scalar_is_zero(&non)) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) { - break; - } - } - count++; } - memset(nonce32, 0, 32); - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); + count++; } - if (ret) { - secp256k1_ecdsa_signature_save(signature, &r, &s); - } else { - memset(signature, 0, sizeof(*signature)); + /* We don't want to declassify is_sec_valid and therefore the range of + * seckey. As a result is_sec_valid is included in ret only after ret was + * used as a branching variable. */ + ret &= is_sec_valid; + secp256k1_memclear(nonce32, sizeof(nonce32)); + secp256k1_scalar_clear(&msg); + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); + secp256k1_scalar_cmov(r, &secp256k1_scalar_zero, !ret); + secp256k1_scalar_cmov(s, &secp256k1_scalar_zero, !ret); + if (recid) { + const int zero = 0; + secp256k1_int_cmov(recid, &zero, !ret); } return ret; } +int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar r, s; + int ret; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msghash32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(seckey != NULL); + + ret = secp256k1_ecdsa_sign_inner(ctx, &r, &s, NULL, msghash32, seckey, noncefp, noncedata); + secp256k1_ecdsa_signature_save(signature, &r, &s); + return ret; +} + int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey) { secp256k1_scalar sec; int ret; - int overflow; VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - ret = !overflow && !secp256k1_scalar_is_zero(&sec); + ret = secp256k1_scalar_set_b32_seckey(&sec, seckey); secp256k1_scalar_clear(&sec); return ret; } -int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) { +static int secp256k1_ec_pubkey_create_helper(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_scalar *seckey_scalar, secp256k1_ge *p, const unsigned char *seckey) { secp256k1_gej pj; + int ret; + + ret = secp256k1_scalar_set_b32_seckey(seckey_scalar, seckey); + secp256k1_scalar_cmov(seckey_scalar, &secp256k1_scalar_one, !ret); + + secp256k1_ecmult_gen(ecmult_gen_ctx, &pj, seckey_scalar); + secp256k1_ge_set_gej(p, &pj); + secp256k1_gej_clear(&pj); + return ret; +} + +int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) { secp256k1_ge p; - secp256k1_scalar sec; - int overflow; + secp256k1_scalar seckey_scalar; int ret = 0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(pubkey != NULL); @@ -411,101 +611,142 @@ int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *p ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); ARG_CHECK(seckey != NULL); - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - ret = (!overflow) & (!secp256k1_scalar_is_zero(&sec)); - if (ret) { - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec); - secp256k1_ge_set_gej(&p, &pj); - secp256k1_pubkey_save(pubkey, &p); - } + ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &seckey_scalar, &p, seckey); + secp256k1_pubkey_save(pubkey, &p); + secp256k1_memczero(pubkey, sizeof(*pubkey), !ret); + + secp256k1_scalar_clear(&seckey_scalar); + return ret; +} + +int secp256k1_ec_seckey_negate(const secp256k1_context* ctx, unsigned char *seckey) { + secp256k1_scalar sec; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + + ret = secp256k1_scalar_set_b32_seckey(&sec, seckey); + secp256k1_scalar_cmov(&sec, &secp256k1_scalar_zero, !ret); + secp256k1_scalar_negate(&sec, &sec); + secp256k1_scalar_get_b32(seckey, &sec); + secp256k1_scalar_clear(&sec); return ret; } -int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar term; - secp256k1_scalar sec; +int secp256k1_ec_privkey_negate(const secp256k1_context* ctx, unsigned char *seckey) { + return secp256k1_ec_seckey_negate(ctx, seckey); +} + +int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) { int ret = 0; - int overflow = 0; + secp256k1_ge p; VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(pubkey != NULL); - secp256k1_scalar_set_b32(&term, tweak, &overflow); - secp256k1_scalar_set_b32(&sec, seckey, NULL); - - ret = !overflow && secp256k1_eckey_privkey_tweak_add(&sec, &term); - memset(seckey, 0, 32); + ret = secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); if (ret) { - secp256k1_scalar_get_b32(seckey, &sec); + secp256k1_ge_neg(&p, &p); + secp256k1_pubkey_save(pubkey, &p); } + return ret; +} - secp256k1_scalar_clear(&sec); + +static int secp256k1_ec_seckey_tweak_add_helper(secp256k1_scalar *sec, const unsigned char *tweak32) { + secp256k1_scalar term; + int overflow = 0; + int ret = 0; + + secp256k1_scalar_set_b32(&term, tweak32, &overflow); + ret = (!overflow) & secp256k1_eckey_privkey_tweak_add(sec, &term); secp256k1_scalar_clear(&term); return ret; } -int secp256k1_ec_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { - secp256k1_ge p; - secp256k1_scalar term; +int secp256k1_ec_seckey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + secp256k1_scalar sec; int ret = 0; - int overflow = 0; VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(seckey != NULL); + ARG_CHECK(tweak32 != NULL); - secp256k1_scalar_set_b32(&term, tweak, &overflow); - ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); + ret = secp256k1_scalar_set_b32_seckey(&sec, seckey); + ret &= secp256k1_ec_seckey_tweak_add_helper(&sec, tweak32); + secp256k1_scalar_cmov(&sec, &secp256k1_scalar_zero, !ret); + secp256k1_scalar_get_b32(seckey, &sec); + + secp256k1_scalar_clear(&sec); + return ret; +} + +int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + return secp256k1_ec_seckey_tweak_add(ctx, seckey, tweak32); +} + +static int secp256k1_ec_pubkey_tweak_add_helper(secp256k1_ge *p, const unsigned char *tweak32) { + secp256k1_scalar term; + int overflow = 0; + secp256k1_scalar_set_b32(&term, tweak32, &overflow); + return !overflow && secp256k1_eckey_pubkey_tweak_add(p, &term); +} + +int secp256k1_ec_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak32) { + secp256k1_ge p; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(tweak32 != NULL); + + ret = secp256k1_pubkey_load(ctx, &p, pubkey); memset(pubkey, 0, sizeof(*pubkey)); + ret = ret && secp256k1_ec_pubkey_tweak_add_helper(&p, tweak32); if (ret) { - if (secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term)) { - secp256k1_pubkey_save(pubkey, &p); - } else { - ret = 0; - } + secp256k1_pubkey_save(pubkey, &p); } return ret; } -int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { +int secp256k1_ec_seckey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { secp256k1_scalar factor; secp256k1_scalar sec; int ret = 0; int overflow = 0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); - secp256k1_scalar_set_b32(&factor, tweak, &overflow); - secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = !overflow && secp256k1_eckey_privkey_tweak_mul(&sec, &factor); - memset(seckey, 0, 32); - if (ret) { - secp256k1_scalar_get_b32(seckey, &sec); - } + secp256k1_scalar_set_b32(&factor, tweak32, &overflow); + ret = secp256k1_scalar_set_b32_seckey(&sec, seckey); + ret &= (!overflow) & secp256k1_eckey_privkey_tweak_mul(&sec, &factor); + secp256k1_scalar_cmov(&sec, &secp256k1_scalar_zero, !ret); + secp256k1_scalar_get_b32(seckey, &sec); secp256k1_scalar_clear(&sec); secp256k1_scalar_clear(&factor); return ret; } -int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { +int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + return secp256k1_ec_seckey_tweak_mul(ctx, seckey, tweak32); +} + +int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak32) { secp256k1_ge p; secp256k1_scalar factor; int ret = 0; int overflow = 0; VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); - secp256k1_scalar_set_b32(&factor, tweak, &overflow); + secp256k1_scalar_set_b32(&factor, tweak32, &overflow); ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); memset(pubkey, 0, sizeof(*pubkey)); if (ret) { - if (secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor)) { + if (secp256k1_eckey_pubkey_tweak_mul(&p, &factor)) { secp256k1_pubkey_save(pubkey, &p); } else { ret = 0; @@ -517,8 +758,11 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); + ARG_CHECK(secp256k1_context_is_proper(ctx)); + + if (secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)) { + secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); + } return 1; } @@ -527,6 +771,7 @@ int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey * secp256k1_gej Qj; secp256k1_ge Q; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(pubnonce != NULL); memset(pubnonce, 0, sizeof(*pubnonce)); ARG_CHECK(n >= 1); @@ -535,6 +780,7 @@ int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey * secp256k1_gej_set_infinity(&Qj); for (i = 0; i < n; i++) { + ARG_CHECK(pubnonces[i] != NULL); secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); secp256k1_gej_add_ge(&Qj, &Qj, &Q); } @@ -546,14 +792,40 @@ int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey * return 1; } +int secp256k1_tagged_sha256(const secp256k1_context* ctx, unsigned char *hash32, const unsigned char *tag, size_t taglen, const unsigned char *msg, size_t msglen) { + secp256k1_sha256 sha; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(hash32 != NULL); + ARG_CHECK(tag != NULL); + ARG_CHECK(msg != NULL); + + secp256k1_sha256_initialize_tagged(&sha, tag, taglen); + secp256k1_sha256_write(&sha, msg, msglen); + secp256k1_sha256_finalize(&sha, hash32); + secp256k1_sha256_clear(&sha); + return 1; +} + #ifdef ENABLE_MODULE_ECDH # include "modules/ecdh/main_impl.h" #endif -#ifdef ENABLE_MODULE_SCHNORR -# include "modules/schnorr/main_impl.h" -#endif - #ifdef ENABLE_MODULE_RECOVERY # include "modules/recovery/main_impl.h" #endif + +#ifdef ENABLE_MODULE_EXTRAKEYS +# include "modules/extrakeys/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG +# include "modules/schnorrsig/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_MUSIG +# include "modules/musig/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT +# include "modules/ellswift/main_impl.h" +#endif diff --git a/crypto/secp256k1/libsecp256k1/src/selftest.h b/crypto/secp256k1/libsecp256k1/src/selftest.h new file mode 100644 index 0000000000..d083ac9524 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/selftest.h @@ -0,0 +1,32 @@ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SELFTEST_H +#define SECP256K1_SELFTEST_H + +#include "hash.h" + +#include + +static int secp256k1_selftest_sha256(void) { + static const char *input63 = "For this sample, this 63-byte string will be used as input data"; + static const unsigned char output32[32] = { + 0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, + 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42, + }; + unsigned char out[32]; + secp256k1_sha256 hasher; + secp256k1_sha256_initialize(&hasher); + secp256k1_sha256_write(&hasher, (const unsigned char*)input63, 63); + secp256k1_sha256_finalize(&hasher, out); + return secp256k1_memcmp_var(out, output32, 32) == 0; +} + +static int secp256k1_selftest_passes(void) { + return secp256k1_selftest_sha256(); +} + +#endif /* SECP256K1_SELFTEST_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/testrand.h b/crypto/secp256k1/libsecp256k1/src/testrand.h index f8efa93c7c..3c1ed3d45d 100644 --- a/crypto/secp256k1/libsecp256k1/src/testrand.h +++ b/crypto/secp256k1/libsecp256k1/src/testrand.h @@ -1,38 +1,48 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_TESTRAND_H_ -#define _SECP256K1_TESTRAND_H_ +#ifndef SECP256K1_TESTRAND_H +#define SECP256K1_TESTRAND_H -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif +#include "util.h" /* A non-cryptographic RNG used only for test infrastructure. */ /** Seed the pseudorandom number generator for testing. */ -SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16); +SECP256K1_INLINE static void testrand_seed(const unsigned char *seed16); /** Generate a pseudorandom number in the range [0..2**32-1]. */ -static uint32_t secp256k1_rand32(void); +SECP256K1_INLINE static uint32_t testrand32(void); + +/** Generate a pseudorandom number in the range [0..2**64-1]. */ +SECP256K1_INLINE static uint64_t testrand64(void); /** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or * more. */ -static uint32_t secp256k1_rand_bits(int bits); +SECP256K1_INLINE static uint64_t testrand_bits(int bits); /** Generate a pseudorandom number in the range [0..range-1]. */ -static uint32_t secp256k1_rand_int(uint32_t range); +static uint32_t testrand_int(uint32_t range); /** Generate a pseudorandom 32-byte array. */ -static void secp256k1_rand256(unsigned char *b32); +static void testrand256(unsigned char *b32); /** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ -static void secp256k1_rand256_test(unsigned char *b32); +static void testrand256_test(unsigned char *b32); /** Generate pseudorandom bytes with long sequences of zero and one bits. */ -static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len); +static void testrand_bytes_test(unsigned char *bytes, size_t len); -#endif +/** Flip a single random bit in a byte array */ +static void testrand_flip(unsigned char *b, size_t len); + +/** Initialize the test RNG using (hex encoded) array up to 16 bytes, or randomly if hexseed is NULL. */ +static void testrand_init(const char* hexseed); + +/** Print final test information. */ +static void testrand_finish(void); + +#endif /* SECP256K1_TESTRAND_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/testrand_impl.h b/crypto/secp256k1/libsecp256k1/src/testrand_impl.h index 15c7b9f12d..b84f5730a9 100644 --- a/crypto/secp256k1/libsecp256k1/src/testrand_impl.h +++ b/crypto/secp256k1/libsecp256k1/src/testrand_impl.h @@ -1,100 +1,110 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_TESTRAND_IMPL_H_ -#define _SECP256K1_TESTRAND_IMPL_H_ +#ifndef SECP256K1_TESTRAND_IMPL_H +#define SECP256K1_TESTRAND_IMPL_H #include +#include #include #include "testrand.h" #include "hash.h" +#include "util.h" -static secp256k1_rfc6979_hmac_sha256_t secp256k1_test_rng; -static uint32_t secp256k1_test_rng_precomputed[8]; -static int secp256k1_test_rng_precomputed_used = 8; -static uint64_t secp256k1_test_rng_integer; -static int secp256k1_test_rng_integer_bits_left = 0; +static uint64_t secp256k1_test_state[4]; -SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { - secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); -} +SECP256K1_INLINE static void testrand_seed(const unsigned char *seed16) { + static const unsigned char PREFIX[] = {'s', 'e', 'c', 'p', '2', '5', '6', 'k', '1', ' ', 't', 'e', 's', 't', ' ', 'i', 'n', 'i', 't'}; + unsigned char out32[32]; + secp256k1_sha256 hash; + int i; -SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { - if (secp256k1_test_rng_precomputed_used == 8) { - secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed)); - secp256k1_test_rng_precomputed_used = 0; - } - return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; -} - -static uint32_t secp256k1_rand_bits(int bits) { - uint32_t ret; - if (secp256k1_test_rng_integer_bits_left < bits) { - secp256k1_test_rng_integer |= (((uint64_t)secp256k1_rand32()) << secp256k1_test_rng_integer_bits_left); - secp256k1_test_rng_integer_bits_left += 32; - } - ret = secp256k1_test_rng_integer; - secp256k1_test_rng_integer >>= bits; - secp256k1_test_rng_integer_bits_left -= bits; - ret &= ((~((uint32_t)0)) >> (32 - bits)); - return ret; -} - -static uint32_t secp256k1_rand_int(uint32_t range) { - /* We want a uniform integer between 0 and range-1, inclusive. - * B is the smallest number such that range <= 2**B. - * two mechanisms implemented here: - * - generate B bits numbers until one below range is found, and return it - * - find the largest multiple M of range that is <= 2**(B+A), generate B+A - * bits numbers until one below M is found, and return it modulo range - * The second mechanism consumes A more bits of entropy in every iteration, - * but may need fewer iterations due to M being closer to 2**(B+A) then - * range is to 2**B. The array below (indexed by B) contains a 0 when the - * first mechanism is to be used, and the number A otherwise. - */ - static const int addbits[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0}; - uint32_t trange, mult; - int bits = 0; - if (range <= 1) { - return 0; - } - trange = range - 1; - while (trange > 0) { - trange >>= 1; - bits++; - } - if (addbits[bits]) { - bits = bits + addbits[bits]; - mult = ((~((uint32_t)0)) >> (32 - bits)) / range; - trange = range * mult; - } else { - trange = range; - mult = 1; - } - while(1) { - uint32_t x = secp256k1_rand_bits(bits); - if (x < trange) { - return (mult == 1) ? x : (x % range); - } + /* Use SHA256(PREFIX || seed16) as initial state. */ + secp256k1_sha256_initialize(&hash); + secp256k1_sha256_write(&hash, PREFIX, sizeof(PREFIX)); + secp256k1_sha256_write(&hash, seed16, 16); + secp256k1_sha256_finalize(&hash, out32); + for (i = 0; i < 4; ++i) { + uint64_t s = 0; + int j; + for (j = 0; j < 8; ++j) s = (s << 8) | out32[8*i + j]; + secp256k1_test_state[i] = s; } } -static void secp256k1_rand256(unsigned char *b32) { - secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); +SECP256K1_INLINE static uint64_t rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); } -static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len) { +SECP256K1_INLINE static uint64_t testrand64(void) { + /* Test-only Xoshiro256++ RNG. See https://prng.di.unimi.it/ */ + const uint64_t result = rotl(secp256k1_test_state[0] + secp256k1_test_state[3], 23) + secp256k1_test_state[0]; + const uint64_t t = secp256k1_test_state[1] << 17; + secp256k1_test_state[2] ^= secp256k1_test_state[0]; + secp256k1_test_state[3] ^= secp256k1_test_state[1]; + secp256k1_test_state[1] ^= secp256k1_test_state[2]; + secp256k1_test_state[0] ^= secp256k1_test_state[3]; + secp256k1_test_state[2] ^= t; + secp256k1_test_state[3] = rotl(secp256k1_test_state[3], 45); + return result; +} + +SECP256K1_INLINE static uint64_t testrand_bits(int bits) { + if (bits == 0) return 0; + return testrand64() >> (64 - bits); +} + +SECP256K1_INLINE static uint32_t testrand32(void) { + return testrand64() >> 32; +} + +static uint32_t testrand_int(uint32_t range) { + uint32_t mask = 0; + uint32_t range_copy; + /* Reduce range by 1, changing its meaning to "maximum value". */ + VERIFY_CHECK(range != 0); + range -= 1; + /* Count the number of bits in range. */ + range_copy = range; + while (range_copy) { + mask = (mask << 1) | 1U; + range_copy >>= 1; + } + /* Generation loop. */ + while (1) { + uint32_t val = testrand64() & mask; + if (val <= range) return val; + } +} + +static void testrand256(unsigned char *b32) { + int i; + for (i = 0; i < 4; ++i) { + uint64_t val = testrand64(); + b32[0] = val; + b32[1] = val >> 8; + b32[2] = val >> 16; + b32[3] = val >> 24; + b32[4] = val >> 32; + b32[5] = val >> 40; + b32[6] = val >> 48; + b32[7] = val >> 56; + b32 += 8; + } +} + +static void testrand_bytes_test(unsigned char *bytes, size_t len) { size_t bits = 0; memset(bytes, 0, len); while (bits < len * 8) { int now; uint32_t val; - now = 1 + (secp256k1_rand_bits(6) * secp256k1_rand_bits(5) + 16) / 31; - val = secp256k1_rand_bits(1); + now = 1 + (testrand_bits(6) * testrand_bits(5) + 16) / 31; + val = testrand_bits(1); while (now > 0 && bits < len * 8) { bytes[bits / 8] |= val << (bits % 8); now--; @@ -103,8 +113,55 @@ static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len) { } } -static void secp256k1_rand256_test(unsigned char *b32) { - secp256k1_rand_bytes_test(b32, 32); +static void testrand256_test(unsigned char *b32) { + testrand_bytes_test(b32, 32); } -#endif +static void testrand_flip(unsigned char *b, size_t len) { + b[testrand_int(len)] ^= (1 << testrand_bits(3)); +} + +static void testrand_init(const char* hexseed) { + unsigned char seed16[16] = {0}; + if (hexseed && strlen(hexseed) != 0) { + int pos = 0; + while (pos < 16 && hexseed[0] != 0 && hexseed[1] != 0) { + unsigned short sh; + if ((sscanf(hexseed, "%2hx", &sh)) == 1) { + seed16[pos] = sh; + } else { + break; + } + hexseed += 2; + pos++; + } + } else { + FILE *frand = fopen("/dev/urandom", "rb"); + if ((frand == NULL) || fread(&seed16, 1, sizeof(seed16), frand) != sizeof(seed16)) { + uint64_t t = time(NULL) * (uint64_t)1337; + fprintf(stderr, "WARNING: could not read 16 bytes from /dev/urandom; falling back to insecure PRNG\n"); + seed16[0] ^= t; + seed16[1] ^= t >> 8; + seed16[2] ^= t >> 16; + seed16[3] ^= t >> 24; + seed16[4] ^= t >> 32; + seed16[5] ^= t >> 40; + seed16[6] ^= t >> 48; + seed16[7] ^= t >> 56; + } + if (frand) { + fclose(frand); + } + } + + printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); + testrand_seed(seed16); +} + +static void testrand_finish(void) { + unsigned char run32[32]; + testrand256(run32); + printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); +} + +#endif /* SECP256K1_TESTRAND_IMPL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/tests.c b/crypto/secp256k1/libsecp256k1/src/tests.c index 9ae7d30281..88628a14ea 100644 --- a/crypto/secp256k1/libsecp256k1/src/tests.c +++ b/crypto/secp256k1/libsecp256k1/src/tests.c @@ -1,51 +1,89 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif +/*********************************************************************** + * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include #include +#include #include +#ifdef USE_EXTERNAL_DEFAULT_CALLBACKS + #pragma message("Ignoring USE_EXTERNAL_CALLBACKS in tests.") + #undef USE_EXTERNAL_DEFAULT_CALLBACKS +#endif +#if defined(VERIFY) && defined(COVERAGE) + #pragma message("Defining VERIFY for tests being built for coverage analysis support is meaningless.") +#endif #include "secp256k1.c" -#include "include/secp256k1.h" + +#include "../include/secp256k1.h" +#include "../include/secp256k1_preallocated.h" #include "testrand_impl.h" +#include "checkmem.h" +#include "testutil.h" +#include "util.h" -#ifdef ENABLE_OPENSSL_TESTS -#include "openssl/bn.h" -#include "openssl/ec.h" -#include "openssl/ecdsa.h" -#include "openssl/obj_mac.h" +#include "../contrib/lax_der_parsing.c" +#include "../contrib/lax_der_privatekey_parsing.c" + +#include "modinv32_impl.h" +#ifdef SECP256K1_WIDEMUL_INT128 +#include "modinv64_impl.h" +#include "int128_impl.h" #endif -#include "contrib/lax_der_parsing.c" -#include "contrib/lax_der_privatekey_parsing.c" +#define CONDITIONAL_TEST(cnt, nam) if (COUNT < (cnt)) { printf("Skipping %s (iteration count too low)\n", nam); } else -#if !defined(VG_CHECK) -# if defined(VALGRIND) -# include -# define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y)) -# define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y)) -# else -# define VG_UNDEF(x,y) -# define VG_CHECK(x,y) -# endif -#endif +static int COUNT = 16; +static secp256k1_context *CTX = NULL; +static secp256k1_context *STATIC_CTX = NULL; -static int count = 64; -static secp256k1_context *ctx = NULL; +static int all_bytes_equal(const void* s, unsigned char value, size_t n) { + const unsigned char *p = s; + size_t i; -static void counting_illegal_callback_fn(const char* str, void* data) { + for (i = 0; i < n; i++) { + if (p[i] != value) { + return 0; + } + } + return 1; +} + +#define CHECK_COUNTING_CALLBACK_VOID(ctx, expr_or_stmt, callback, callback_setter) do { \ + int32_t _calls_to_callback = 0; \ + secp256k1_callback _saved_callback = ctx->callback; \ + callback_setter(ctx, counting_callback_fn, &_calls_to_callback); \ + { expr_or_stmt; } \ + ctx->callback = _saved_callback; \ + CHECK(_calls_to_callback == 1); \ +} while(0); + +/* CHECK that expr_or_stmt calls the error or illegal callback of ctx exactly once + * + * Useful for checking functions that return void (e.g., API functions that use ARG_CHECK_VOID) */ +#define CHECK_ERROR_VOID(ctx, expr_or_stmt) \ + CHECK_COUNTING_CALLBACK_VOID(ctx, expr_or_stmt, error_callback, secp256k1_context_set_error_callback) +#define CHECK_ILLEGAL_VOID(ctx, expr_or_stmt) \ + CHECK_COUNTING_CALLBACK_VOID(ctx, expr_or_stmt, illegal_callback, secp256k1_context_set_illegal_callback) + +/* CHECK that + * - expr calls the illegal callback of ctx exactly once and, + * - expr == 0 (or equivalently, expr == NULL) + * + * Useful for checking functions that return an integer or a pointer. */ +#define CHECK_ILLEGAL(ctx, expr) CHECK_ILLEGAL_VOID(ctx, CHECK((expr) == 0)) +#define CHECK_ERROR(ctx, expr) CHECK_ERROR_VOID(ctx, CHECK((expr) == 0)) + +static void counting_callback_fn(const char* str, void* data) { /* Dummy callback function that just counts. */ int32_t *p; (void)str; p = data; + CHECK(*p != INT32_MAX); (*p)++; } @@ -54,198 +92,375 @@ static void uncounting_illegal_callback_fn(const char* str, void* data) { int32_t *p; (void)str; p = data; + CHECK(*p != INT32_MIN); (*p)--; } -void random_field_element_test(secp256k1_fe *fe) { - do { - unsigned char b32[32]; - secp256k1_rand256_test(b32); - if (secp256k1_fe_set_b32(fe, b32)) { - break; +static void run_xoshiro256pp_tests(void) { + { + size_t i; + /* Sanity check that we run before the actual seeding. */ + for (i = 0; i < sizeof(secp256k1_test_state)/sizeof(secp256k1_test_state[0]); i++) { + CHECK(secp256k1_test_state[i] == 0); } - } while(1); -} - -void random_field_element_magnitude(secp256k1_fe *fe) { - secp256k1_fe zero; - int n = secp256k1_rand_int(9); - secp256k1_fe_normalize(fe); - if (n == 0) { - return; } - secp256k1_fe_clear(&zero); - secp256k1_fe_negate(&zero, &zero, 0); - secp256k1_fe_mul_int(&zero, n - 1); - secp256k1_fe_add(fe, &zero); - VERIFY_CHECK(fe->magnitude == n); -} - -void random_group_element_test(secp256k1_ge *ge) { - secp256k1_fe fe; - do { - random_field_element_test(&fe); - if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand_bits(1))) { - secp256k1_fe_normalize(&ge->y); - break; + { + int i; + unsigned char buf32[32]; + unsigned char seed16[16] = { + 'C', 'H', 'I', 'C', 'K', 'E', 'N', '!', + 'C', 'H', 'I', 'C', 'K', 'E', 'N', '!', + }; + unsigned char buf32_expected[32] = { + 0xAF, 0xCC, 0xA9, 0x16, 0xB5, 0x6C, 0xE3, 0xF0, + 0x44, 0x3F, 0x45, 0xE0, 0x47, 0xA5, 0x08, 0x36, + 0x4C, 0xCC, 0xC1, 0x18, 0xB2, 0xD8, 0x8F, 0xEF, + 0x43, 0x26, 0x15, 0x57, 0x37, 0x00, 0xEF, 0x30, + }; + testrand_seed(seed16); + for (i = 0; i < 17; i++) { + testrand256(buf32); } - } while(1); + CHECK(secp256k1_memcmp_var(buf32, buf32_expected, sizeof(buf32)) == 0); + } } -void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { - secp256k1_fe z2, z3; - do { - random_field_element_test(&gej->z); - if (!secp256k1_fe_is_zero(&gej->z)) { - break; - } - } while(1); - secp256k1_fe_sqr(&z2, &gej->z); - secp256k1_fe_mul(&z3, &z2, &gej->z); - secp256k1_fe_mul(&gej->x, &ge->x, &z2); - secp256k1_fe_mul(&gej->y, &ge->y, &z3); - gej->infinity = ge->infinity; +static void run_selftest_tests(void) { + /* Test public API */ + secp256k1_selftest(); } -void random_scalar_order_test(secp256k1_scalar *num) { - do { - unsigned char b32[32]; - int overflow = 0; - secp256k1_rand256_test(b32); - secp256k1_scalar_set_b32(num, b32, &overflow); - if (overflow || secp256k1_scalar_is_zero(num)) { - continue; - } - break; - } while(1); +static int ecmult_gen_context_eq(const secp256k1_ecmult_gen_context *a, const secp256k1_ecmult_gen_context *b) { + return a->built == b->built + && secp256k1_scalar_eq(&a->scalar_offset, &b->scalar_offset) + && secp256k1_ge_eq_var(&a->ge_offset, &b->ge_offset) + && secp256k1_fe_equal(&a->proj_blind, &b->proj_blind); } -void random_scalar_order(secp256k1_scalar *num) { - do { - unsigned char b32[32]; - int overflow = 0; - secp256k1_rand256(b32); - secp256k1_scalar_set_b32(num, b32, &overflow); - if (overflow || secp256k1_scalar_is_zero(num)) { - continue; - } - break; - } while(1); +static int context_eq(const secp256k1_context *a, const secp256k1_context *b) { + return a->declassify == b->declassify + && ecmult_gen_context_eq(&a->ecmult_gen_ctx, &b->ecmult_gen_ctx) + && a->illegal_callback.fn == b->illegal_callback.fn + && a->illegal_callback.data == b->illegal_callback.data + && a->error_callback.fn == b->error_callback.fn + && a->error_callback.data == b->error_callback.data; } -void run_context_tests(void) { +static void run_deprecated_context_flags_test(void) { + /* Check that a context created with any of the flags in the flags array is + * identical to the NONE context. */ + unsigned int flags[] = { SECP256K1_CONTEXT_SIGN, + SECP256K1_CONTEXT_VERIFY, + SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY }; + secp256k1_context *none_ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + int i; + for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) { + secp256k1_context *tmp_ctx; + CHECK(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE) == secp256k1_context_preallocated_size(flags[i])); + tmp_ctx = secp256k1_context_create(flags[i]); + CHECK(context_eq(none_ctx, tmp_ctx)); + secp256k1_context_destroy(tmp_ctx); + } + secp256k1_context_destroy(none_ctx); +} + +static void run_ec_illegal_argument_tests(void) { secp256k1_pubkey pubkey; + secp256k1_pubkey zero_pubkey; secp256k1_ecdsa_signature sig; unsigned char ctmp[32]; - int32_t ecount; - int32_t ecount2; - secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); - secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + /* Setup */ + memset(ctmp, 1, 32); + memset(&zero_pubkey, 0, sizeof(zero_pubkey)); + + /* Verify context-type checking illegal-argument errors. */ + CHECK_ILLEGAL(STATIC_CTX, secp256k1_ec_pubkey_create(STATIC_CTX, &pubkey, ctmp)); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, ctmp) == 1); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_ecdsa_sign(STATIC_CTX, &sig, ctmp, ctmp, NULL, NULL)); + SECP256K1_CHECKMEM_UNDEFINE(&sig, sizeof(sig)); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, ctmp, ctmp, NULL, NULL) == 1); + SECP256K1_CHECKMEM_CHECK(&sig, sizeof(sig)); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, ctmp, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(STATIC_CTX, &sig, ctmp, &pubkey) == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, ctmp) == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(STATIC_CTX, &pubkey, ctmp) == 1); + CHECK(secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey, ctmp) == 1); + CHECK(secp256k1_ec_pubkey_negate(STATIC_CTX, &pubkey) == 1); + CHECK(secp256k1_ec_pubkey_negate(CTX, &pubkey) == 1); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_ec_pubkey_negate(STATIC_CTX, &zero_pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_negate(CTX, NULL)); + CHECK(secp256k1_ec_pubkey_tweak_mul(STATIC_CTX, &pubkey, ctmp) == 1); +} + +static void run_static_context_tests(int use_prealloc) { + /* Check that deprecated secp256k1_context_no_precomp is an alias to secp256k1_context_static. */ + CHECK(secp256k1_context_no_precomp == secp256k1_context_static); + + { + unsigned char seed[32] = {0x17}; + + /* Randomizing secp256k1_context_static is not supported. */ + CHECK_ILLEGAL(STATIC_CTX, secp256k1_context_randomize(STATIC_CTX, seed)); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_context_randomize(STATIC_CTX, NULL)); + + /* Destroying or cloning secp256k1_context_static is not supported. */ + if (use_prealloc) { + CHECK_ILLEGAL(STATIC_CTX, secp256k1_context_preallocated_clone_size(STATIC_CTX)); + { + secp256k1_context *my_static_ctx = malloc(sizeof(*STATIC_CTX)); + CHECK(my_static_ctx != NULL); + memset(my_static_ctx, 0x2a, sizeof(*my_static_ctx)); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_context_preallocated_clone(STATIC_CTX, my_static_ctx)); + CHECK(all_bytes_equal(my_static_ctx, 0x2a, sizeof(*my_static_ctx))); + free(my_static_ctx); + } + CHECK_ILLEGAL_VOID(STATIC_CTX, secp256k1_context_preallocated_destroy(STATIC_CTX)); + } else { + CHECK_ILLEGAL(STATIC_CTX, secp256k1_context_clone(STATIC_CTX)); + CHECK_ILLEGAL_VOID(STATIC_CTX, secp256k1_context_destroy(STATIC_CTX)); + } + } + + { + /* Verify that setting and resetting illegal callback works */ + int32_t dummy = 0; + secp256k1_context_set_illegal_callback(STATIC_CTX, counting_callback_fn, &dummy); + CHECK(STATIC_CTX->illegal_callback.fn == counting_callback_fn); + CHECK(STATIC_CTX->illegal_callback.data == &dummy); + secp256k1_context_set_illegal_callback(STATIC_CTX, NULL, NULL); + CHECK(STATIC_CTX->illegal_callback.fn == secp256k1_default_illegal_callback_fn); + CHECK(STATIC_CTX->illegal_callback.data == NULL); + } +} + +static void run_proper_context_tests(int use_prealloc) { + int32_t dummy = 0; + secp256k1_context *my_ctx, *my_ctx_fresh; + void *my_ctx_prealloc = NULL; + unsigned char seed[32] = {0x17}; secp256k1_gej pubj; secp256k1_ge pub; secp256k1_scalar msg, key, nonce; secp256k1_scalar sigr, sigs; - ecount = 0; - ecount2 = 10; - secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount2); - secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, NULL); - CHECK(vrfy->error_callback.fn != sign->error_callback.fn); + /* Fresh reference context for comparison */ + my_ctx_fresh = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + + if (use_prealloc) { + my_ctx_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); + CHECK(my_ctx_prealloc != NULL); + my_ctx = secp256k1_context_preallocated_create(my_ctx_prealloc, SECP256K1_CONTEXT_NONE); + } else { + my_ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + } + + /* Randomize and reset randomization */ + CHECK(context_eq(my_ctx, my_ctx_fresh)); + CHECK(secp256k1_context_randomize(my_ctx, seed) == 1); + CHECK(!context_eq(my_ctx, my_ctx_fresh)); + CHECK(secp256k1_context_randomize(my_ctx, NULL) == 1); + CHECK(context_eq(my_ctx, my_ctx_fresh)); + + /* set error callback (to a function that still aborts in case malloc() fails in secp256k1_context_clone() below) */ + secp256k1_context_set_error_callback(my_ctx, secp256k1_default_illegal_callback_fn, NULL); + CHECK(my_ctx->error_callback.fn != secp256k1_default_error_callback_fn); + CHECK(my_ctx->error_callback.fn == secp256k1_default_illegal_callback_fn); + + /* check if sizes for cloning are consistent */ + CHECK(secp256k1_context_preallocated_clone_size(my_ctx) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); /*** clone and destroy all of them to make sure cloning was complete ***/ { secp256k1_context *ctx_tmp; - ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_destroy(ctx_tmp); + if (use_prealloc) { + /* clone into a non-preallocated context and then again into a new preallocated one. */ + ctx_tmp = my_ctx; + my_ctx = secp256k1_context_clone(my_ctx); + CHECK(context_eq(ctx_tmp, my_ctx)); + secp256k1_context_preallocated_destroy(ctx_tmp); + + free(my_ctx_prealloc); + my_ctx_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); + CHECK(my_ctx_prealloc != NULL); + ctx_tmp = my_ctx; + my_ctx = secp256k1_context_preallocated_clone(my_ctx, my_ctx_prealloc); + CHECK(context_eq(ctx_tmp, my_ctx)); + secp256k1_context_destroy(ctx_tmp); + } else { + /* clone into a preallocated context and then again into a new non-preallocated one. */ + void *prealloc_tmp; + + prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); + CHECK(prealloc_tmp != NULL); + ctx_tmp = my_ctx; + my_ctx = secp256k1_context_preallocated_clone(my_ctx, prealloc_tmp); + CHECK(context_eq(ctx_tmp, my_ctx)); + secp256k1_context_destroy(ctx_tmp); + + ctx_tmp = my_ctx; + my_ctx = secp256k1_context_clone(my_ctx); + CHECK(context_eq(ctx_tmp, my_ctx)); + secp256k1_context_preallocated_destroy(ctx_tmp); + free(prealloc_tmp); + } } /* Verify that the error callback makes it across the clone. */ - CHECK(vrfy->error_callback.fn != sign->error_callback.fn); + CHECK(my_ctx->error_callback.fn != secp256k1_default_error_callback_fn); + CHECK(my_ctx->error_callback.fn == secp256k1_default_illegal_callback_fn); /* And that it resets back to default. */ - secp256k1_context_set_error_callback(sign, NULL, NULL); - CHECK(vrfy->error_callback.fn == sign->error_callback.fn); + secp256k1_context_set_error_callback(my_ctx, NULL, NULL); + CHECK(my_ctx->error_callback.fn == secp256k1_default_error_callback_fn); + CHECK(context_eq(my_ctx, my_ctx_fresh)); + + /* Verify that setting and resetting illegal callback works */ + secp256k1_context_set_illegal_callback(my_ctx, counting_callback_fn, &dummy); + CHECK(my_ctx->illegal_callback.fn == counting_callback_fn); + CHECK(my_ctx->illegal_callback.data == &dummy); + secp256k1_context_set_illegal_callback(my_ctx, NULL, NULL); + CHECK(my_ctx->illegal_callback.fn == secp256k1_default_illegal_callback_fn); + CHECK(my_ctx->illegal_callback.data == NULL); + CHECK(context_eq(my_ctx, my_ctx_fresh)); /*** attempt to use them ***/ - random_scalar_order_test(&msg); - random_scalar_order_test(&key); - secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key); + testutil_random_scalar_order_test(&msg); + testutil_random_scalar_order_test(&key); + secp256k1_ecmult_gen(&my_ctx->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); - /* Verify context-type checking illegal-argument errors. */ - memset(ctmp, 1, 32); - CHECK(secp256k1_ec_pubkey_create(vrfy, &pubkey, ctmp) == 0); - CHECK(ecount == 1); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(sign, &pubkey, ctmp) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ecdsa_sign(vrfy, &sig, ctmp, ctmp, NULL, NULL) == 0); - CHECK(ecount == 2); - VG_UNDEF(&sig, sizeof(sig)); - CHECK(secp256k1_ecdsa_sign(sign, &sig, ctmp, ctmp, NULL, NULL) == 1); - VG_CHECK(&sig, sizeof(sig)); - CHECK(ecount2 == 10); - CHECK(secp256k1_ecdsa_verify(sign, &sig, ctmp, &pubkey) == 0); - CHECK(ecount2 == 11); - CHECK(secp256k1_ecdsa_verify(vrfy, &sig, ctmp, &pubkey) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_tweak_add(sign, &pubkey, ctmp) == 0); - CHECK(ecount2 == 12); - CHECK(secp256k1_ec_pubkey_tweak_add(vrfy, &pubkey, ctmp) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_tweak_mul(sign, &pubkey, ctmp) == 0); - CHECK(ecount2 == 13); - CHECK(secp256k1_ec_pubkey_tweak_mul(vrfy, &pubkey, ctmp) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_context_randomize(vrfy, ctmp) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_context_randomize(sign, NULL) == 1); - CHECK(ecount2 == 13); - secp256k1_context_set_illegal_callback(vrfy, NULL, NULL); - secp256k1_context_set_illegal_callback(sign, NULL, NULL); - - /* This shouldn't leak memory, due to already-set tests. */ - secp256k1_ecmult_gen_context_build(&sign->ecmult_gen_ctx, NULL); - secp256k1_ecmult_context_build(&vrfy->ecmult_ctx, NULL); - /* obtain a working nonce */ do { - random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); + testutil_random_scalar_order_test(&nonce); + } while(!secp256k1_ecdsa_sig_sign(&my_ctx->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try signing */ - CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); - CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); + CHECK(secp256k1_ecdsa_sig_sign(&my_ctx->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try verifying */ - CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sigr, &sigs, &pub, &msg)); - CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sigr, &sigs, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&sigr, &sigs, &pub, &msg)); /* cleanup */ - secp256k1_context_destroy(none); - secp256k1_context_destroy(sign); - secp256k1_context_destroy(vrfy); - secp256k1_context_destroy(both); + if (use_prealloc) { + secp256k1_context_preallocated_destroy(my_ctx); + free(my_ctx_prealloc); + } else { + secp256k1_context_destroy(my_ctx); + } + secp256k1_context_destroy(my_ctx_fresh); + /* Defined as no-op. */ secp256k1_context_destroy(NULL); + secp256k1_context_preallocated_destroy(NULL); +} + +static void run_scratch_tests(void) { + const size_t adj_alloc = ((500 + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; + + size_t checkpoint; + size_t checkpoint_2; + secp256k1_scratch_space *scratch; + secp256k1_scratch_space local_scratch; + + /* Test public API */ + scratch = secp256k1_scratch_space_create(CTX, 1000); + CHECK(scratch != NULL); + + /* Test internal API */ + CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 0) == 1000); + CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 1) == 1000 - (ALIGNMENT - 1)); + CHECK(scratch->alloc_size == 0); + CHECK(scratch->alloc_size % ALIGNMENT == 0); + + /* Allocating 500 bytes succeeds */ + checkpoint = secp256k1_scratch_checkpoint(&CTX->error_callback, scratch); + CHECK(secp256k1_scratch_alloc(&CTX->error_callback, scratch, 500) != NULL); + CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 0) == 1000 - adj_alloc); + CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 1) == 1000 - adj_alloc - (ALIGNMENT - 1)); + CHECK(scratch->alloc_size != 0); + CHECK(scratch->alloc_size % ALIGNMENT == 0); + + /* Allocating another 501 bytes fails */ + CHECK(secp256k1_scratch_alloc(&CTX->error_callback, scratch, 501) == NULL); + CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 0) == 1000 - adj_alloc); + CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 1) == 1000 - adj_alloc - (ALIGNMENT - 1)); + CHECK(scratch->alloc_size != 0); + CHECK(scratch->alloc_size % ALIGNMENT == 0); + + /* ...but it succeeds once we apply the checkpoint to undo it */ + secp256k1_scratch_apply_checkpoint(&CTX->error_callback, scratch, checkpoint); + CHECK(scratch->alloc_size == 0); + CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 0) == 1000); + CHECK(secp256k1_scratch_alloc(&CTX->error_callback, scratch, 500) != NULL); + CHECK(scratch->alloc_size != 0); + + /* try to apply a bad checkpoint */ + checkpoint_2 = secp256k1_scratch_checkpoint(&CTX->error_callback, scratch); + secp256k1_scratch_apply_checkpoint(&CTX->error_callback, scratch, checkpoint); + CHECK_ERROR_VOID(CTX, secp256k1_scratch_apply_checkpoint(&CTX->error_callback, scratch, checkpoint_2)); /* checkpoint_2 is after checkpoint */ + CHECK_ERROR_VOID(CTX, secp256k1_scratch_apply_checkpoint(&CTX->error_callback, scratch, (size_t) -1)); /* this is just wildly invalid */ + + /* try to use badly initialized scratch space */ + secp256k1_scratch_space_destroy(CTX, scratch); + memset(&local_scratch, 0, sizeof(local_scratch)); + scratch = &local_scratch; + CHECK_ERROR(CTX, secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 0)); + CHECK_ERROR(CTX, secp256k1_scratch_alloc(&CTX->error_callback, scratch, 500)); + CHECK_ERROR_VOID(CTX, secp256k1_scratch_space_destroy(CTX, scratch)); + + /* Test that large integers do not wrap around in a bad way */ + scratch = secp256k1_scratch_space_create(CTX, 1000); + /* Try max allocation with a large number of objects. Only makes sense if + * ALIGNMENT is greater than 1 because otherwise the objects take no extra + * space. */ + CHECK(ALIGNMENT <= 1 || !secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, (SIZE_MAX / (ALIGNMENT - 1)) + 1)); + /* Try allocating SIZE_MAX to test wrap around which only happens if + * ALIGNMENT > 1, otherwise it returns NULL anyway because the scratch + * space is too small. */ + CHECK(secp256k1_scratch_alloc(&CTX->error_callback, scratch, SIZE_MAX) == NULL); + secp256k1_scratch_space_destroy(CTX, scratch); + + /* cleanup */ + secp256k1_scratch_space_destroy(CTX, NULL); /* no-op */ +} + +static void run_ctz_tests(void) { + static const uint32_t b32[] = {1, 0xffffffff, 0x5e56968f, 0xe0d63129}; + static const uint64_t b64[] = {1, 0xffffffffffffffff, 0xbcd02462139b3fc3, 0x98b5f80c769693ef}; + int shift; + unsigned i; + for (i = 0; i < sizeof(b32) / sizeof(b32[0]); ++i) { + for (shift = 0; shift < 32; ++shift) { + CHECK(secp256k1_ctz32_var_debruijn(b32[i] << shift) == shift); + CHECK(secp256k1_ctz32_var(b32[i] << shift) == shift); + } + } + for (i = 0; i < sizeof(b64) / sizeof(b64[0]); ++i) { + for (shift = 0; shift < 64; ++shift) { + CHECK(secp256k1_ctz64_var_debruijn(b64[i] << shift) == shift); + CHECK(secp256k1_ctz64_var(b64[i] << shift) == shift); + } + } } /***** HASH TESTS *****/ -void run_sha256_tests(void) { - static const char *inputs[8] = { +static void run_sha256_known_output_tests(void) { + static const char *inputs[] = { "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "For this sample, this 63-byte string will be used as input data", - "This is exactly 64 bytes long, not counting the terminating byte" + "This is exactly 64 bytes long, not counting the terminating byte", + "aaaaa", }; - static const unsigned char outputs[8][32] = { + static const unsigned int repeat[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1000000/5 + }; + static const unsigned char outputs[][32] = { {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}, {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad}, {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50}, @@ -253,28 +468,158 @@ void run_sha256_tests(void) { {0x68, 0x19, 0xd9, 0x15, 0xc7, 0x3f, 0x4d, 0x1e, 0x77, 0xe4, 0xe1, 0xb5, 0x2d, 0x1f, 0xa0, 0xf9, 0xcf, 0x9b, 0xea, 0xea, 0xd3, 0x93, 0x9f, 0x15, 0x87, 0x4b, 0xd9, 0x88, 0xe2, 0xa2, 0x36, 0x30}, {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1}, {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42}, - {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8} + {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8}, + {0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67, 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0}, }; - int i; - for (i = 0; i < 8; i++) { + unsigned int i, ninputs; + + /* Skip last input vector for low iteration counts */ + ninputs = sizeof(inputs)/sizeof(inputs[0]) - 1; + CONDITIONAL_TEST(16, "run_sha256_known_output_tests 1000000") ninputs++; + + for (i = 0; i < ninputs; i++) { unsigned char out[32]; - secp256k1_sha256_t hasher; + secp256k1_sha256 hasher; + unsigned int j; + /* 1. Run: simply write the input bytestrings */ + j = repeat[i]; secp256k1_sha256_initialize(&hasher); - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); + while (j > 0) { + secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); + j--; + } secp256k1_sha256_finalize(&hasher, out); - CHECK(memcmp(out, outputs[i], 32) == 0); + CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); + /* 2. Run: split the input bytestrings randomly before writing */ if (strlen(inputs[i]) > 0) { - int split = secp256k1_rand_int(strlen(inputs[i])); + int split = testrand_int(strlen(inputs[i])); secp256k1_sha256_initialize(&hasher); - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); + j = repeat[i]; + while (j > 0) { + secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); + secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); + j--; + } secp256k1_sha256_finalize(&hasher, out); - CHECK(memcmp(out, outputs[i], 32) == 0); + CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); } } } -void run_hmac_sha256_tests(void) { +/** SHA256 counter tests + +The tests verify that the SHA256 counter doesn't wrap around at message length +2^i bytes for i = 20, ..., 33. This wide range aims at being independent of the +implementation of the counter and it catches multiple natural 32-bit overflows +(e.g., counting bits, counting bytes, counting blocks, ...). + +The test vectors have been generated using following Python script which relies +on https://github.com/cloudtools/sha256/ (v0.3 on Python v3.10.2). + +``` +from sha256 import sha256 +from copy import copy + +def midstate_c_definition(hasher): + ret = ' {{0x' + hasher.state[0].hex('_', 4).replace('_', ', 0x') + '},\n' + ret += ' {0x00}, ' + str(hex(hasher.state[1])) + '}' + return ret + +def output_c_literal(hasher): + return '{0x' + hasher.digest().hex('_').replace('_', ', 0x') + '}' + +MESSAGE = b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno' +assert(len(MESSAGE) == 64) +BYTE_BOUNDARIES = [(2**b)//len(MESSAGE) - 1 for b in range(20, 34)] + +midstates = [] +digests = [] +hasher = sha256() +for i in range(BYTE_BOUNDARIES[-1] + 1): + if i in BYTE_BOUNDARIES: + midstates.append(midstate_c_definition(hasher)) + hasher_copy = copy(hasher) + hasher_copy.update(MESSAGE) + digests.append(output_c_literal(hasher_copy)) + hasher.update(MESSAGE) + +for x in midstates: + print(x + ',') + +for x in digests: + print(x + ',') +``` +*/ +static void run_sha256_counter_tests(void) { + static const char *input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"; + static const secp256k1_sha256 midstates[] = { + {{0xa2b5c8bb, 0x26c88bb3, 0x2abdc3d2, 0x9def99a3, 0xdfd21a6e, 0x41fe585b, 0x7ef2c440, 0x2b79adda}, + {0x00}, 0xfffc0}, + {{0xa0d29445, 0x9287de66, 0x76aabd71, 0x41acd765, 0x0c7528b4, 0x84e14906, 0x942faec6, 0xcc5a7b26}, + {0x00}, 0x1fffc0}, + {{0x50449526, 0xb9f1d657, 0xa0fc13e9, 0x50860f10, 0xa550c431, 0x3fbc97c1, 0x7bbb2d89, 0xdb67bac1}, + {0x00}, 0x3fffc0}, + {{0x54a6efdc, 0x46762e7b, 0x88bfe73f, 0xbbd149c7, 0x41620c43, 0x1168da7b, 0x2c5960f9, 0xeccffda6}, + {0x00}, 0x7fffc0}, + {{0x2515a8f5, 0x5faa2977, 0x3a850486, 0xac858cad, 0x7b7276ee, 0x235c0385, 0xc53a157c, 0x7cb3e69c}, + {0x00}, 0xffffc0}, + {{0x34f39828, 0x409fedb7, 0x4bbdd0fb, 0x3b643634, 0x7806bf2e, 0xe0d1b713, 0xca3f2e1e, 0xe38722c2}, + {0x00}, 0x1ffffc0}, + {{0x389ef5c5, 0x38c54167, 0x8f5d56ab, 0x582a75cc, 0x8217caef, 0xf10947dd, 0x6a1998a8, 0x048f0b8c}, + {0x00}, 0x3ffffc0}, + {{0xd6c3f394, 0x0bee43b9, 0x6783f497, 0x29fa9e21, 0x6ce491c1, 0xa81fe45e, 0x2fc3859a, 0x269012d0}, + {0x00}, 0x7ffffc0}, + {{0x6dd3c526, 0x44d88aa0, 0x806a1bae, 0xfbcc0d32, 0x9d6144f3, 0x9d2bd757, 0x9851a957, 0xb50430ad}, + {0x00}, 0xfffffc0}, + {{0x2add4021, 0xdfe8a9e6, 0xa56317c6, 0x7a15f5bb, 0x4a48aacd, 0x5d368414, 0x4f00e6f0, 0xd9355023}, + {0x00}, 0x1fffffc0}, + {{0xb66666b4, 0xdbeac32b, 0x0ea351ae, 0xcba9da46, 0x6278b874, 0x8c508e23, 0xe16ca776, 0x8465bac1}, + {0x00}, 0x3fffffc0}, + {{0xb6744789, 0x9cce87aa, 0xc4c478b7, 0xf38404d8, 0x2e38ba62, 0xa3f7019b, 0x50458fe7, 0x3047dbec}, + {0x00}, 0x7fffffc0}, + {{0x8b1297ba, 0xba261a80, 0x2ba1b0dd, 0xfbc67d6d, 0x61072c4e, 0x4b5a2a0f, 0x52872760, 0x2dfeb162}, + {0x00}, 0xffffffc0}, + {{0x24f33cf7, 0x41ad6583, 0x41c8ff5d, 0xca7ef35f, 0x50395756, 0x021b743e, 0xd7126cd7, 0xd037473a}, + {0x00}, 0x1ffffffc0}, + }; + static const unsigned char outputs[][32] = { + {0x0e, 0x83, 0xe2, 0xc9, 0x4f, 0xb2, 0xb8, 0x2b, 0x89, 0x06, 0x92, 0x78, 0x04, 0x03, 0x48, 0x5c, 0x48, 0x44, 0x67, 0x61, 0x77, 0xa4, 0xc7, 0x90, 0x9e, 0x92, 0x55, 0x10, 0x05, 0xfe, 0x39, 0x15}, + {0x1d, 0x1e, 0xd7, 0xb8, 0xa3, 0xa7, 0x8a, 0x79, 0xfd, 0xa0, 0x05, 0x08, 0x9c, 0xeb, 0xf0, 0xec, 0x67, 0x07, 0x9f, 0x8e, 0x3c, 0x0d, 0x8e, 0xf9, 0x75, 0x55, 0x13, 0xc1, 0xe8, 0x77, 0xf8, 0xbb}, + {0x66, 0x95, 0x6c, 0xc9, 0xe0, 0x39, 0x65, 0xb6, 0xb0, 0x05, 0xd1, 0xaf, 0xaf, 0xf3, 0x1d, 0xb9, 0xa4, 0xda, 0x6f, 0x20, 0xcd, 0x3a, 0xae, 0x64, 0xc2, 0xdb, 0xee, 0xf5, 0xb8, 0x8d, 0x57, 0x0e}, + {0x3c, 0xbb, 0x1c, 0x12, 0x5e, 0x17, 0xfd, 0x54, 0x90, 0x45, 0xa7, 0x7b, 0x61, 0x6c, 0x1d, 0xfe, 0xe6, 0xcc, 0x7f, 0xee, 0xcf, 0xef, 0x33, 0x35, 0x50, 0x62, 0x16, 0x70, 0x2f, 0x87, 0xc3, 0xc9}, + {0x53, 0x4d, 0xa8, 0xe7, 0x1e, 0x98, 0x73, 0x8d, 0xd9, 0xa3, 0x54, 0xa5, 0x0e, 0x59, 0x2c, 0x25, 0x43, 0x6f, 0xaa, 0xa2, 0xf5, 0x21, 0x06, 0x3e, 0xc9, 0x82, 0x06, 0x94, 0x98, 0x72, 0x9d, 0xa7}, + {0xef, 0x7e, 0xe9, 0x6b, 0xd3, 0xe5, 0xb7, 0x41, 0x4c, 0xc8, 0xd3, 0x07, 0x52, 0x9a, 0x5a, 0x8b, 0x4e, 0x1e, 0x75, 0xa4, 0x17, 0x78, 0xc8, 0x36, 0xcd, 0xf8, 0x2e, 0xd9, 0x57, 0xe3, 0xd7, 0x07}, + {0x87, 0x16, 0xfb, 0xf9, 0xa5, 0xf8, 0xc4, 0x56, 0x2b, 0x48, 0x52, 0x8e, 0x2d, 0x30, 0x85, 0xb6, 0x4c, 0x56, 0xb5, 0xd1, 0x16, 0x9c, 0xcf, 0x32, 0x95, 0xad, 0x03, 0xe8, 0x05, 0x58, 0x06, 0x76}, + {0x75, 0x03, 0x80, 0x28, 0xf2, 0xa7, 0x63, 0x22, 0x1a, 0x26, 0x9c, 0x68, 0xe0, 0x58, 0xfc, 0x73, 0xeb, 0x42, 0xf6, 0x86, 0x16, 0x24, 0x4b, 0xbc, 0x24, 0xf7, 0x02, 0xc8, 0x3d, 0x90, 0xe2, 0xb0}, + {0xdf, 0x49, 0x0f, 0x15, 0x7b, 0x7d, 0xbf, 0xe0, 0xd4, 0xcf, 0x47, 0xc0, 0x80, 0x93, 0x4a, 0x61, 0xaa, 0x03, 0x07, 0x66, 0xb3, 0x38, 0x5d, 0xc8, 0xc9, 0x07, 0x61, 0xfb, 0x97, 0x10, 0x2f, 0xd8}, + {0x77, 0x19, 0x40, 0x56, 0x41, 0xad, 0xbc, 0x59, 0xda, 0x1e, 0xc5, 0x37, 0x14, 0x63, 0x7b, 0xfb, 0x79, 0xe2, 0x7a, 0xb1, 0x55, 0x42, 0x99, 0x42, 0x56, 0xfe, 0x26, 0x9d, 0x0f, 0x7e, 0x80, 0xc6}, + {0x50, 0xe7, 0x2a, 0x0e, 0x26, 0x44, 0x2f, 0xe2, 0x55, 0x2d, 0xc3, 0x93, 0x8a, 0xc5, 0x86, 0x58, 0x22, 0x8c, 0x0c, 0xbf, 0xb1, 0xd2, 0xca, 0x87, 0x2a, 0xe4, 0x35, 0x26, 0x6f, 0xcd, 0x05, 0x5e}, + {0xe4, 0x80, 0x6f, 0xdb, 0x3d, 0x7d, 0xba, 0xde, 0x50, 0x3f, 0xea, 0x00, 0x3d, 0x46, 0x59, 0x64, 0xfd, 0x58, 0x1c, 0xa1, 0xb8, 0x7d, 0x5f, 0xac, 0x94, 0x37, 0x9e, 0xa0, 0xc0, 0x9c, 0x93, 0x8b}, + {0x2c, 0xf3, 0xa9, 0xf6, 0x15, 0x25, 0x80, 0x70, 0x76, 0x99, 0x7d, 0xf1, 0xc3, 0x2f, 0xa3, 0x31, 0xff, 0x92, 0x35, 0x2e, 0x8d, 0x04, 0x13, 0x33, 0xd8, 0x0d, 0xdb, 0x4a, 0xf6, 0x8c, 0x03, 0x34}, + {0xec, 0x12, 0x24, 0x9f, 0x35, 0xa4, 0x29, 0x8b, 0x9e, 0x4a, 0x95, 0xf8, 0x61, 0xaf, 0x61, 0xc5, 0x66, 0x55, 0x3e, 0x3f, 0x2a, 0x98, 0xea, 0x71, 0x16, 0x6b, 0x1c, 0xd9, 0xe4, 0x09, 0xd2, 0x8e}, + }; + unsigned int i; + for (i = 0; i < sizeof(midstates)/sizeof(midstates[0]); i++) { + unsigned char out[32]; + secp256k1_sha256 hasher = midstates[i]; + secp256k1_sha256_write(&hasher, (const unsigned char*)input, strlen(input)); + secp256k1_sha256_finalize(&hasher, out); + CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); + } +} + +/* Tests for the equality of two sha256 structs. This function only produces a + * correct result if an integer multiple of 64 many bytes have been written + * into the hash functions. This function is used by some module tests. */ +static void test_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 *sha2) { + /* Is buffer fully consumed? */ + CHECK((sha1->bytes & 0x3F) == 0); + + CHECK(sha1->bytes == sha2->bytes); + CHECK(secp256k1_memcmp_var(sha1->s, sha2->s, sizeof(sha1->s)) == 0); +} + +static void run_hmac_sha256_tests(void) { static const char *keys[6] = { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "\x4a\x65\x66\x65", @@ -301,24 +646,24 @@ void run_hmac_sha256_tests(void) { }; int i; for (i = 0; i < 6; i++) { - secp256k1_hmac_sha256_t hasher; + secp256k1_hmac_sha256 hasher; unsigned char out[32]; secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); secp256k1_hmac_sha256_finalize(&hasher, out); - CHECK(memcmp(out, outputs[i], 32) == 0); + CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { - int split = secp256k1_rand_int(strlen(inputs[i])); + int split = testrand_int(strlen(inputs[i])); secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); secp256k1_hmac_sha256_finalize(&hasher, out); - CHECK(memcmp(out, outputs[i], 32) == 0); + CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); } } } -void run_rfc6979_hmac_sha256_tests(void) { +static void run_rfc6979_hmac_sha256_tests(void) { static const unsigned char key1[65] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a, 0}; static const unsigned char out1[3][32] = { {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb}, @@ -333,322 +678,1354 @@ void run_rfc6979_hmac_sha256_tests(void) { {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94} }; - secp256k1_rfc6979_hmac_sha256_t rng; + secp256k1_rfc6979_hmac_sha256 rng; unsigned char out[32]; int i; secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 64); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); - CHECK(memcmp(out, out1[i], 32) == 0); + CHECK(secp256k1_memcmp_var(out, out1[i], 32) == 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 65); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); - CHECK(memcmp(out, out1[i], 32) != 0); + CHECK(secp256k1_memcmp_var(out, out1[i], 32) != 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 64); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); - CHECK(memcmp(out, out2[i], 32) == 0); + CHECK(secp256k1_memcmp_var(out, out2[i], 32) == 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); } -/***** RANDOM TESTS *****/ +static void run_tagged_sha256_tests(void) { + unsigned char tag[32] = { 0 }; + unsigned char msg[32] = { 0 }; + unsigned char hash32[32]; + unsigned char hash_expected[32] = { + 0x04, 0x7A, 0x5E, 0x17, 0xB5, 0x86, 0x47, 0xC1, + 0x3C, 0xC6, 0xEB, 0xC0, 0xAA, 0x58, 0x3B, 0x62, + 0xFB, 0x16, 0x43, 0x32, 0x68, 0x77, 0x40, 0x6C, + 0xE2, 0x76, 0x55, 0x9A, 0x3B, 0xDE, 0x55, 0xB3 + }; -void test_rand_bits(int rand32, int bits) { - /* (1-1/2^B)^rounds[B] < 1/10^9, so rounds is the number of iterations to - * get a false negative chance below once in a billion */ - static const unsigned int rounds[7] = {1, 30, 73, 156, 322, 653, 1316}; - /* We try multiplying the results with various odd numbers, which shouldn't - * influence the uniform distribution modulo a power of 2. */ - static const uint32_t mults[6] = {1, 3, 21, 289, 0x9999, 0x80402011}; - /* We only select up to 6 bits from the output to analyse */ - unsigned int usebits = bits > 6 ? 6 : bits; - unsigned int maxshift = bits - usebits; - /* For each of the maxshift+1 usebits-bit sequences inside a bits-bit - number, track all observed outcomes, one per bit in a uint64_t. */ - uint64_t x[6][27] = {{0}}; - unsigned int i, shift, m; - /* Multiply the output of all rand calls with the odd number m, which - should not change the uniformity of its distribution. */ - for (i = 0; i < rounds[usebits]; i++) { - uint32_t r = (rand32 ? secp256k1_rand32() : secp256k1_rand_bits(bits)); - CHECK((((uint64_t)r) >> bits) == 0); - for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { - uint32_t rm = r * mults[m]; - for (shift = 0; shift <= maxshift; shift++) { - x[m][shift] |= (((uint64_t)1) << ((rm >> shift) & ((1 << usebits) - 1))); + /* API test */ + CHECK(secp256k1_tagged_sha256(CTX, hash32, tag, sizeof(tag), msg, sizeof(msg)) == 1); + CHECK_ILLEGAL(CTX, secp256k1_tagged_sha256(CTX, NULL, tag, sizeof(tag), msg, sizeof(msg))); + CHECK_ILLEGAL(CTX, secp256k1_tagged_sha256(CTX, hash32, NULL, 0, msg, sizeof(msg))); + CHECK_ILLEGAL(CTX, secp256k1_tagged_sha256(CTX, hash32, tag, sizeof(tag), NULL, 0)); + + /* Static test vector */ + memcpy(tag, "tag", 3); + memcpy(msg, "msg", 3); + CHECK(secp256k1_tagged_sha256(CTX, hash32, tag, 3, msg, 3) == 1); + CHECK(secp256k1_memcmp_var(hash32, hash_expected, sizeof(hash32)) == 0); +} + +/***** MODINV TESTS *****/ + +/* Compute the modular inverse of (odd) x mod 2^64. */ +static uint64_t modinv2p64(uint64_t x) { + /* If w = 1/x mod 2^(2^L), then w*(2 - w*x) = 1/x mod 2^(2^(L+1)). See + * Hacker's Delight second edition, Henry S. Warren, Jr., pages 245-247 for + * why. Start with L=0, for which it is true for every odd x that + * 1/x=1 mod 2. Iterating 6 times gives us 1/x mod 2^64. */ + int l; + uint64_t w = 1; + CHECK(x & 1); + for (l = 0; l < 6; ++l) w *= (2 - w*x); + return w; +} + + +/* compute out = (a*b) mod m; if b=NULL, treat b=1; if m=NULL, treat m=infinity. + * + * Out is a 512-bit number (represented as 32 uint16_t's in LE order). The other + * arguments are 256-bit numbers (represented as 16 uint16_t's in LE order). */ +static void mulmod256(uint16_t* out, const uint16_t* a, const uint16_t* b, const uint16_t* m) { + uint16_t mul[32]; + uint64_t c = 0; + int i, j; + int m_bitlen = 0; + int mul_bitlen = 0; + + if (b != NULL) { + /* Compute the product of a and b, and put it in mul. */ + for (i = 0; i < 32; ++i) { + for (j = i <= 15 ? 0 : i - 15; j <= i && j <= 15; j++) { + c += (uint64_t)a[j] * b[i - j]; + } + mul[i] = c & 0xFFFF; + c >>= 16; + } + CHECK(c == 0); + + /* compute the highest set bit in mul */ + for (i = 511; i >= 0; --i) { + if ((mul[i >> 4] >> (i & 15)) & 1) { + mul_bitlen = i; + break; + } + } + } else { + /* if b==NULL, set mul=a. */ + memcpy(mul, a, 32); + memset(mul + 16, 0, 32); + /* compute the highest set bit in mul */ + for (i = 255; i >= 0; --i) { + if ((mul[i >> 4] >> (i & 15)) & 1) { + mul_bitlen = i; + break; } } } - for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { - for (shift = 0; shift <= maxshift; shift++) { - /* Test that the lower usebits bits of x[shift] are 1 */ - CHECK(((~x[m][shift]) << (64 - (1 << usebits))) == 0); + + if (m) { + /* Compute the highest set bit in m. */ + for (i = 255; i >= 0; --i) { + if ((m[i >> 4] >> (i & 15)) & 1) { + m_bitlen = i; + break; + } + } + + /* Try do mul -= m<= 0; --i) { + uint16_t mul2[32]; + int64_t cs; + + /* Compute mul2 = mul - m<= 0 && bitpos < 256) { + sub |= ((m[bitpos >> 4] >> (bitpos & 15)) & 1) << p; + } + } + /* Add mul[j]-sub to accumulator, and shift bottom 16 bits out to mul2[j]. */ + cs += mul[j]; + cs -= sub; + mul2[j] = (cs & 0xFFFF); + cs >>= 16; + } + /* If remainder of subtraction is 0, set mul = mul2. */ + if (cs == 0) { + memcpy(mul, mul2, sizeof(mul)); + } + } + /* Sanity check: test that all limbs higher than m's highest are zero */ + for (i = (m_bitlen >> 4) + 1; i < 32; ++i) { + CHECK(mul[i] == 0); + } + } + memcpy(out, mul, 32); +} + +/* Convert a 256-bit number represented as 16 uint16_t's to signed30 notation. */ +static void uint16_to_signed30(secp256k1_modinv32_signed30* out, const uint16_t* in) { + int i; + memset(out->v, 0, sizeof(out->v)); + for (i = 0; i < 256; ++i) { + out->v[i / 30] |= (int32_t)(((in[i >> 4]) >> (i & 15)) & 1) << (i % 30); + } +} + +/* Convert a 256-bit number in signed30 notation to a representation as 16 uint16_t's. */ +static void signed30_to_uint16(uint16_t* out, const secp256k1_modinv32_signed30* in) { + int i; + memset(out, 0, 32); + for (i = 0; i < 256; ++i) { + out[i >> 4] |= (((in->v[i / 30]) >> (i % 30)) & 1) << (i & 15); + } +} + +/* Randomly mutate the sign of limbs in signed30 representation, without changing the value. */ +static void mutate_sign_signed30(secp256k1_modinv32_signed30* x) { + int i; + for (i = 0; i < 16; ++i) { + int pos = testrand_bits(3); + if (x->v[pos] > 0 && x->v[pos + 1] <= 0x3fffffff) { + x->v[pos] -= 0x40000000; + x->v[pos + 1] += 1; + } else if (x->v[pos] < 0 && x->v[pos + 1] >= 0x3fffffff) { + x->v[pos] += 0x40000000; + x->v[pos + 1] -= 1; } } } -/* Subrange must be a whole divisor of range, and at most 64 */ -void test_rand_int(uint32_t range, uint32_t subrange) { - /* (1-1/subrange)^rounds < 1/10^9 */ - int rounds = (subrange * 2073) / 100; +/* Test secp256k1_modinv32{_var}, using inputs in 16-bit limb format, and returning inverse. */ +static void test_modinv32_uint16(uint16_t* out, const uint16_t* in, const uint16_t* mod) { + uint16_t tmp[16]; + secp256k1_modinv32_signed30 x; + secp256k1_modinv32_modinfo m; + int i, vartime, nonzero; + + uint16_to_signed30(&x, in); + nonzero = (x.v[0] | x.v[1] | x.v[2] | x.v[3] | x.v[4] | x.v[5] | x.v[6] | x.v[7] | x.v[8]) != 0; + uint16_to_signed30(&m.modulus, mod); + + /* compute 1/modulus mod 2^30 */ + m.modulus_inv30 = modinv2p64(m.modulus.v[0]) & 0x3fffffff; + CHECK(((m.modulus_inv30 * m.modulus.v[0]) & 0x3fffffff) == 1); + + /* Test secp256k1_jacobi32_maybe_var. */ + if (nonzero) { + int jac; + uint16_t sqr[16], negone[16]; + mulmod256(sqr, in, in, mod); + uint16_to_signed30(&x, sqr); + /* Compute jacobi symbol of in^2, which must be 1 (or uncomputable). */ + jac = secp256k1_jacobi32_maybe_var(&x, &m); + CHECK(jac == 0 || jac == 1); + /* Then compute the jacobi symbol of -(in^2). x and -x have opposite + * jacobi symbols if and only if (mod % 4) == 3. */ + negone[0] = mod[0] - 1; + for (i = 1; i < 16; ++i) negone[i] = mod[i]; + mulmod256(sqr, sqr, negone, mod); + uint16_to_signed30(&x, sqr); + jac = secp256k1_jacobi32_maybe_var(&x, &m); + CHECK(jac == 0 || jac == 1 - (mod[0] & 2)); + } + + uint16_to_signed30(&x, in); + mutate_sign_signed30(&m.modulus); + for (vartime = 0; vartime < 2; ++vartime) { + /* compute inverse */ + (vartime ? secp256k1_modinv32_var : secp256k1_modinv32)(&x, &m); + + /* produce output */ + signed30_to_uint16(out, &x); + + /* check if the inverse times the input is 1 (mod m), unless x is 0. */ + mulmod256(tmp, out, in, mod); + CHECK(tmp[0] == nonzero); + for (i = 1; i < 16; ++i) CHECK(tmp[i] == 0); + + /* invert again */ + (vartime ? secp256k1_modinv32_var : secp256k1_modinv32)(&x, &m); + + /* check if the result is equal to the input */ + signed30_to_uint16(tmp, &x); + for (i = 0; i < 16; ++i) CHECK(tmp[i] == in[i]); + } +} + +#ifdef SECP256K1_WIDEMUL_INT128 +/* Convert a 256-bit number represented as 16 uint16_t's to signed62 notation. */ +static void uint16_to_signed62(secp256k1_modinv64_signed62* out, const uint16_t* in) { int i; - uint64_t x = 0; - CHECK((range % subrange) == 0); - for (i = 0; i < rounds; i++) { - uint32_t r = secp256k1_rand_int(range); - CHECK(r < range); - r = r % subrange; - x |= (((uint64_t)1) << r); - } - /* Test that the lower subrange bits of x are 1. */ - CHECK(((~x) << (64 - subrange)) == 0); -} - -void run_rand_bits(void) { - size_t b; - test_rand_bits(1, 32); - for (b = 1; b <= 32; b++) { - test_rand_bits(0, b); + memset(out->v, 0, sizeof(out->v)); + for (i = 0; i < 256; ++i) { + out->v[i / 62] |= (int64_t)(((in[i >> 4]) >> (i & 15)) & 1) << (i % 62); } } -void run_rand_int(void) { - static const uint32_t ms[] = {1, 3, 17, 1000, 13771, 999999, 33554432}; - static const uint32_t ss[] = {1, 3, 6, 9, 13, 31, 64}; - unsigned int m, s; - for (m = 0; m < sizeof(ms) / sizeof(ms[0]); m++) { - for (s = 0; s < sizeof(ss) / sizeof(ss[0]); s++) { - test_rand_int(ms[m] * ss[s], ss[s]); - } - } -} - -/***** NUM TESTS *****/ - -#ifndef USE_NUM_NONE -void random_num_negate(secp256k1_num *num) { - if (secp256k1_rand_bits(1)) { - secp256k1_num_negate(num); - } -} - -void random_num_order_test(secp256k1_num *num) { - secp256k1_scalar sc; - random_scalar_order_test(&sc); - secp256k1_scalar_get_num(num, &sc); -} - -void random_num_order(secp256k1_num *num) { - secp256k1_scalar sc; - random_scalar_order(&sc); - secp256k1_scalar_get_num(num, &sc); -} - -void test_num_negate(void) { - secp256k1_num n1; - secp256k1_num n2; - random_num_order_test(&n1); /* n1 = R */ - random_num_negate(&n1); - secp256k1_num_copy(&n2, &n1); /* n2 = R */ - secp256k1_num_sub(&n1, &n2, &n1); /* n1 = n2-n1 = 0 */ - CHECK(secp256k1_num_is_zero(&n1)); - secp256k1_num_copy(&n1, &n2); /* n1 = R */ - secp256k1_num_negate(&n1); /* n1 = -R */ - CHECK(!secp256k1_num_is_zero(&n1)); - secp256k1_num_add(&n1, &n2, &n1); /* n1 = n2+n1 = 0 */ - CHECK(secp256k1_num_is_zero(&n1)); - secp256k1_num_copy(&n1, &n2); /* n1 = R */ - secp256k1_num_negate(&n1); /* n1 = -R */ - CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2)); - secp256k1_num_negate(&n1); /* n1 = R */ - CHECK(secp256k1_num_eq(&n1, &n2)); -} - -void test_num_add_sub(void) { +/* Convert a 256-bit number in signed62 notation to a representation as 16 uint16_t's. */ +static void signed62_to_uint16(uint16_t* out, const secp256k1_modinv64_signed62* in) { int i; - secp256k1_scalar s; - secp256k1_num n1; - secp256k1_num n2; - secp256k1_num n1p2, n2p1, n1m2, n2m1; - random_num_order_test(&n1); /* n1 = R1 */ - if (secp256k1_rand_bits(1)) { - random_num_negate(&n1); - } - random_num_order_test(&n2); /* n2 = R2 */ - if (secp256k1_rand_bits(1)) { - random_num_negate(&n2); - } - secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */ - secp256k1_num_add(&n2p1, &n2, &n1); /* n2p1 = R2 + R1 */ - secp256k1_num_sub(&n1m2, &n1, &n2); /* n1m2 = R1 - R2 */ - secp256k1_num_sub(&n2m1, &n2, &n1); /* n2m1 = R2 - R1 */ - CHECK(secp256k1_num_eq(&n1p2, &n2p1)); - CHECK(!secp256k1_num_eq(&n1p2, &n1m2)); - secp256k1_num_negate(&n2m1); /* n2m1 = -R2 + R1 */ - CHECK(secp256k1_num_eq(&n2m1, &n1m2)); - CHECK(!secp256k1_num_eq(&n2m1, &n1)); - secp256k1_num_add(&n2m1, &n2m1, &n2); /* n2m1 = -R2 + R1 + R2 = R1 */ - CHECK(secp256k1_num_eq(&n2m1, &n1)); - CHECK(!secp256k1_num_eq(&n2p1, &n1)); - secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */ - CHECK(secp256k1_num_eq(&n2p1, &n1)); - - /* check is_one */ - secp256k1_scalar_set_int(&s, 1); - secp256k1_scalar_get_num(&n1, &s); - CHECK(secp256k1_num_is_one(&n1)); - /* check that 2^n + 1 is never 1 */ - secp256k1_scalar_get_num(&n2, &s); - for (i = 0; i < 250; ++i) { - secp256k1_num_add(&n1, &n1, &n1); /* n1 *= 2 */ - secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = n1 + 1 */ - CHECK(!secp256k1_num_is_one(&n1p2)); + memset(out, 0, 32); + for (i = 0; i < 256; ++i) { + out[i >> 4] |= (((in->v[i / 62]) >> (i % 62)) & 1) << (i & 15); } } -void test_num_mod(void) { +/* Randomly mutate the sign of limbs in signed62 representation, without changing the value. */ +static void mutate_sign_signed62(secp256k1_modinv64_signed62* x) { + static const int64_t M62 = (int64_t)(UINT64_MAX >> 2); int i; - secp256k1_scalar s; - secp256k1_num order, n; - - /* check that 0 mod anything is 0 */ - random_scalar_order_test(&s); - secp256k1_scalar_get_num(&order, &s); - secp256k1_scalar_set_int(&s, 0); - secp256k1_scalar_get_num(&n, &s); - secp256k1_num_mod(&n, &order); - CHECK(secp256k1_num_is_zero(&n)); - - /* check that anything mod 1 is 0 */ - secp256k1_scalar_set_int(&s, 1); - secp256k1_scalar_get_num(&order, &s); - secp256k1_scalar_get_num(&n, &s); - secp256k1_num_mod(&n, &order); - CHECK(secp256k1_num_is_zero(&n)); - - /* check that increasing the number past 2^256 does not break this */ - random_scalar_order_test(&s); - secp256k1_scalar_get_num(&n, &s); - /* multiply by 2^8, which'll test this case with high probability */ for (i = 0; i < 8; ++i) { - secp256k1_num_add(&n, &n, &n); + int pos = testrand_bits(2); + if (x->v[pos] > 0 && x->v[pos + 1] <= M62) { + x->v[pos] -= (M62 + 1); + x->v[pos + 1] += 1; + } else if (x->v[pos] < 0 && x->v[pos + 1] >= -M62) { + x->v[pos] += (M62 + 1); + x->v[pos + 1] -= 1; + } } - secp256k1_num_mod(&n, &order); - CHECK(secp256k1_num_is_zero(&n)); } -void test_num_jacobi(void) { - secp256k1_scalar sqr; - secp256k1_scalar small; - secp256k1_scalar five; /* five is not a quadratic residue */ - secp256k1_num order, n; +/* Test secp256k1_modinv64{_var}, using inputs in 16-bit limb format, and returning inverse. */ +static void test_modinv64_uint16(uint16_t* out, const uint16_t* in, const uint16_t* mod) { + static const int64_t M62 = (int64_t)(UINT64_MAX >> 2); + uint16_t tmp[16]; + secp256k1_modinv64_signed62 x; + secp256k1_modinv64_modinfo m; + int i, vartime, nonzero; + + uint16_to_signed62(&x, in); + nonzero = (x.v[0] | x.v[1] | x.v[2] | x.v[3] | x.v[4]) != 0; + uint16_to_signed62(&m.modulus, mod); + + /* compute 1/modulus mod 2^62 */ + m.modulus_inv62 = modinv2p64(m.modulus.v[0]) & M62; + CHECK(((m.modulus_inv62 * m.modulus.v[0]) & M62) == 1); + + /* Test secp256k1_jacobi64_maybe_var. */ + if (nonzero) { + int jac; + uint16_t sqr[16], negone[16]; + mulmod256(sqr, in, in, mod); + uint16_to_signed62(&x, sqr); + /* Compute jacobi symbol of in^2, which must be 1 (or uncomputable). */ + jac = secp256k1_jacobi64_maybe_var(&x, &m); + CHECK(jac == 0 || jac == 1); + /* Then compute the jacobi symbol of -(in^2). x and -x have opposite + * jacobi symbols if and only if (mod % 4) == 3. */ + negone[0] = mod[0] - 1; + for (i = 1; i < 16; ++i) negone[i] = mod[i]; + mulmod256(sqr, sqr, negone, mod); + uint16_to_signed62(&x, sqr); + jac = secp256k1_jacobi64_maybe_var(&x, &m); + CHECK(jac == 0 || jac == 1 - (mod[0] & 2)); + } + + uint16_to_signed62(&x, in); + mutate_sign_signed62(&m.modulus); + for (vartime = 0; vartime < 2; ++vartime) { + /* compute inverse */ + (vartime ? secp256k1_modinv64_var : secp256k1_modinv64)(&x, &m); + + /* produce output */ + signed62_to_uint16(out, &x); + + /* check if the inverse times the input is 1 (mod m), unless x is 0. */ + mulmod256(tmp, out, in, mod); + CHECK(tmp[0] == nonzero); + for (i = 1; i < 16; ++i) CHECK(tmp[i] == 0); + + /* invert again */ + (vartime ? secp256k1_modinv64_var : secp256k1_modinv64)(&x, &m); + + /* check if the result is equal to the input */ + signed62_to_uint16(tmp, &x); + for (i = 0; i < 16; ++i) CHECK(tmp[i] == in[i]); + } +} +#endif + +/* test if a and b are coprime */ +static int coprime(const uint16_t* a, const uint16_t* b) { + uint16_t x[16], y[16], t[16]; int i; - /* squares mod 5 are 1, 4 */ - const int jacobi5[10] = { 0, 1, -1, -1, 1, 0, 1, -1, -1, 1 }; + int iszero; + memcpy(x, a, 32); + memcpy(y, b, 32); - /* check some small values with 5 as the order */ - secp256k1_scalar_set_int(&five, 5); - secp256k1_scalar_get_num(&order, &five); - for (i = 0; i < 10; ++i) { - secp256k1_scalar_set_int(&small, i); - secp256k1_scalar_get_num(&n, &small); - CHECK(secp256k1_num_jacobi(&n, &order) == jacobi5[i]); + /* simple gcd loop: while x!=0, (x,y)=(y%x,x) */ + while (1) { + iszero = 1; + for (i = 0; i < 16; ++i) { + if (x[i] != 0) { + iszero = 0; + break; + } + } + if (iszero) break; + mulmod256(t, y, NULL, x); + memcpy(y, x, 32); + memcpy(x, t, 32); } - /** test large values with 5 as group order */ - secp256k1_scalar_get_num(&order, &five); - /* we first need a scalar which is not a multiple of 5 */ - do { - secp256k1_num fiven; - random_scalar_order_test(&sqr); - secp256k1_scalar_get_num(&fiven, &five); - secp256k1_scalar_get_num(&n, &sqr); - secp256k1_num_mod(&n, &fiven); - } while (secp256k1_num_is_zero(&n)); - /* next force it to be a residue. 2 is a nonresidue mod 5 so we can - * just multiply by two, i.e. add the number to itself */ - if (secp256k1_num_jacobi(&n, &order) == -1) { - secp256k1_num_add(&n, &n, &n); + /* return whether y=1 */ + if (y[0] != 1) return 0; + for (i = 1; i < 16; ++i) { + if (y[i] != 0) return 0; } - - /* test residue */ - CHECK(secp256k1_num_jacobi(&n, &order) == 1); - /* test nonresidue */ - secp256k1_num_add(&n, &n, &n); - CHECK(secp256k1_num_jacobi(&n, &order) == -1); - - /** test with secp group order as order */ - secp256k1_scalar_order_get_num(&order); - random_scalar_order_test(&sqr); - secp256k1_scalar_sqr(&sqr, &sqr); - /* test residue */ - secp256k1_scalar_get_num(&n, &sqr); - CHECK(secp256k1_num_jacobi(&n, &order) == 1); - /* test nonresidue */ - secp256k1_scalar_mul(&sqr, &sqr, &five); - secp256k1_scalar_get_num(&n, &sqr); - CHECK(secp256k1_num_jacobi(&n, &order) == -1); - /* test multiple of the order*/ - CHECK(secp256k1_num_jacobi(&order, &order) == 0); - - /* check one less than the order */ - secp256k1_scalar_set_int(&small, 1); - secp256k1_scalar_get_num(&n, &small); - secp256k1_num_sub(&n, &order, &n); - CHECK(secp256k1_num_jacobi(&n, &order) == 1); /* sage confirms this is 1 */ + return 1; } -void run_num_smalltests(void) { +static void run_modinv_tests(void) { + /* Fixed test cases. Each tuple is (input, modulus, output), each as 16x16 bits in LE order. */ + static const uint16_t CASES[][3][16] = { + /* Test cases triggering edge cases in divsteps */ + + /* Test case known to need 713 divsteps */ + {{0x1513, 0x5389, 0x54e9, 0x2798, 0x1957, 0x66a0, 0x8057, 0x3477, + 0x7784, 0x1052, 0x326a, 0x9331, 0x6506, 0xa95c, 0x91f3, 0xfb5e}, + {0x2bdd, 0x8df4, 0xcc61, 0x481f, 0xdae5, 0x5ca7, 0xf43b, 0x7d54, + 0x13d6, 0x469b, 0x2294, 0x20f4, 0xb2a4, 0xa2d1, 0x3ff1, 0xfd4b}, + {0xffd8, 0xd9a0, 0x456e, 0x81bb, 0xbabd, 0x6cea, 0x6dbd, 0x73ab, + 0xbb94, 0x3d3c, 0xdf08, 0x31c4, 0x3e32, 0xc179, 0x2486, 0xb86b}}, + /* Test case known to need 589 divsteps, reaching delta=-140 and + delta=141. */ + {{0x3fb1, 0x903b, 0x4eb7, 0x4813, 0xd863, 0x26bf, 0xd89f, 0xa8a9, + 0x02fe, 0x57c6, 0x554a, 0x4eab, 0x165e, 0x3d61, 0xee1e, 0x456c}, + {0x9295, 0x823b, 0x5c1f, 0x5386, 0x48e0, 0x02ff, 0x4c2a, 0xa2da, + 0xe58f, 0x967c, 0xc97e, 0x3f5a, 0x69fb, 0x52d9, 0x0a86, 0xb4a3}, + {0x3d30, 0xb893, 0xa809, 0xa7a8, 0x26f5, 0x5b42, 0x55be, 0xf4d0, + 0x12c2, 0x7e6a, 0xe41a, 0x90c7, 0xebfa, 0xf920, 0x304e, 0x1419}}, + /* Test case known to need 650 divsteps, and doing 65 consecutive (f,g/2) steps. */ + {{0x8583, 0x5058, 0xbeae, 0xeb69, 0x48bc, 0x52bb, 0x6a9d, 0xcc94, + 0x2a21, 0x87d5, 0x5b0d, 0x42f6, 0x5b8a, 0x2214, 0xe9d6, 0xa040}, + {0x7531, 0x27cb, 0x7e53, 0xb739, 0x6a5f, 0x83f5, 0xa45c, 0xcb1d, + 0x8a87, 0x1c9c, 0x51d7, 0x851c, 0xb9d8, 0x1fbe, 0xc241, 0xd4a3}, + {0xcdb4, 0x275c, 0x7d22, 0xa906, 0x0173, 0xc054, 0x7fdf, 0x5005, + 0x7fb8, 0x9059, 0xdf51, 0x99df, 0x2654, 0x8f6e, 0x070f, 0xb347}}, + /* example needing 713 divsteps; delta=-2..3 */ + {{0xe2e9, 0xee91, 0x4345, 0xe5ad, 0xf3ec, 0x8f42, 0x0364, 0xd5c9, + 0xff49, 0xbef5, 0x4544, 0x4c7c, 0xae4b, 0xfd9d, 0xb35b, 0xda9d}, + {0x36e7, 0x8cca, 0x2ed0, 0x47b3, 0xaca4, 0xb374, 0x7d2a, 0x0772, + 0x6bdb, 0xe0a7, 0x900b, 0xfe10, 0x788c, 0x6f22, 0xd909, 0xf298}, + {0xd8c6, 0xba39, 0x13ed, 0x198c, 0x16c8, 0xb837, 0xa5f2, 0x9797, + 0x0113, 0x882a, 0x15b5, 0x324c, 0xabee, 0xe465, 0x8170, 0x85ac}}, + /* example needing 713 divsteps; delta=-2..3 */ + {{0xd5b7, 0x2966, 0x040e, 0xf59a, 0x0387, 0xd96d, 0xbfbc, 0xd850, + 0x2d96, 0x872a, 0xad81, 0xc03c, 0xbb39, 0xb7fa, 0xd904, 0xef78}, + {0x6279, 0x4314, 0xfdd3, 0x1568, 0x0982, 0x4d13, 0x625f, 0x010c, + 0x22b1, 0x0cc3, 0xf22d, 0x5710, 0x1109, 0x5751, 0x7714, 0xfcf2}, + {0xdb13, 0x5817, 0x232e, 0xe456, 0xbbbc, 0x6fbe, 0x4572, 0xa358, + 0xc76d, 0x928e, 0x0162, 0x5314, 0x8325, 0x5683, 0xe21b, 0xda88}}, + /* example needing 713 divsteps; delta=-2..3 */ + {{0xa06f, 0x71ee, 0x3bac, 0x9ebb, 0xdeaa, 0x09ed, 0x1cf7, 0x9ec9, + 0x7158, 0x8b72, 0x5d53, 0x5479, 0x5c75, 0xbb66, 0x9125, 0xeccc}, + {0x2941, 0xd46c, 0x3cd4, 0x4a9d, 0x5c4a, 0x256b, 0xbd6c, 0x9b8e, + 0x8fe0, 0x8a14, 0xffe8, 0x2496, 0x618d, 0xa9d7, 0x5018, 0xfb29}, + {0x437c, 0xbd60, 0x7590, 0x94bb, 0x0095, 0xd35e, 0xd4fe, 0xd6da, + 0x0d4e, 0x5342, 0x4cd2, 0x169b, 0x661c, 0x1380, 0xed2d, 0x85c1}}, + /* example reaching delta=-64..65; 661 divsteps */ + {{0xfde4, 0x68d6, 0x6c48, 0x7f77, 0x1c78, 0x96de, 0x2fd9, 0xa6c2, + 0xbbb5, 0xd319, 0x69cf, 0xd4b3, 0xa321, 0xcda0, 0x172e, 0xe530}, + {0xd9e3, 0x0f60, 0x3d86, 0xeeab, 0x25ee, 0x9582, 0x2d50, 0xfe16, + 0xd4e2, 0xe3ba, 0x94e2, 0x9833, 0x6c5e, 0x8982, 0x13b6, 0xe598}, + {0xe675, 0xf55a, 0x10f6, 0xabde, 0x5113, 0xecaa, 0x61ae, 0xad9f, + 0x0c27, 0xef33, 0x62e5, 0x211d, 0x08fa, 0xa78d, 0xc675, 0x8bae}}, + /* example reaching delta=-64..65; 661 divsteps */ + {{0x21bf, 0x52d5, 0x8fd4, 0xaa18, 0x156a, 0x7247, 0xebb8, 0x5717, + 0x4eb5, 0x1421, 0xb58f, 0x3b0b, 0x5dff, 0xe533, 0xb369, 0xd28a}, + {0x9f6b, 0xe463, 0x2563, 0xc74d, 0x6d81, 0x636a, 0x8fc8, 0x7a94, + 0x9429, 0x1585, 0xf35e, 0x7ff5, 0xb64f, 0x9720, 0xba74, 0xe108}, + {0xa5ab, 0xea7b, 0xfe5e, 0x8a85, 0x13be, 0x7934, 0xe8a0, 0xa187, + 0x86b5, 0xe477, 0xb9a4, 0x75d7, 0x538f, 0xdd70, 0xc781, 0xb67d}}, + /* example reaching delta=-64..65; 661 divsteps */ + {{0xa41a, 0x3e8d, 0xf1f5, 0x9493, 0x868c, 0x5103, 0x2725, 0x3ceb, + 0x6032, 0x3624, 0xdc6b, 0x9120, 0xbf4c, 0x8821, 0x91ad, 0xb31a}, + {0x5c0b, 0xdda5, 0x20f8, 0x32a1, 0xaf73, 0x6ec5, 0x4779, 0x43d6, + 0xd454, 0x9573, 0xbf84, 0x5a58, 0xe04e, 0x307e, 0xd1d5, 0xe230}, + {0xda15, 0xbcd6, 0x7180, 0xabd3, 0x04e6, 0x6986, 0xc0d7, 0x90bb, + 0x3a4d, 0x7c95, 0xaaab, 0x9ab3, 0xda34, 0xa7f6, 0x9636, 0x6273}}, + /* example doing 123 consecutive (f,g/2) steps; 615 divsteps */ + {{0xb4d6, 0xb38f, 0x00aa, 0xebda, 0xd4c2, 0x70b8, 0x9dad, 0x58ee, + 0x68f8, 0x48d3, 0xb5ff, 0xf422, 0x9e46, 0x2437, 0x18d0, 0xd9cc}, + {0x5c83, 0xfed7, 0x97f5, 0x3f07, 0xcaad, 0x95b1, 0xb4a4, 0xb005, + 0x23af, 0xdd27, 0x6c0d, 0x932c, 0xe2b2, 0xe3ae, 0xfb96, 0xdf67}, + {0x3105, 0x0127, 0xfd48, 0x039b, 0x35f1, 0xbc6f, 0x6c0a, 0xb572, + 0xe4df, 0xebad, 0x8edc, 0xb89d, 0x9555, 0x4c26, 0x1fef, 0x997c}}, + /* example doing 123 consecutive (f,g/2) steps; 614 divsteps */ + {{0x5138, 0xd474, 0x385f, 0xc964, 0x00f2, 0x6df7, 0x862d, 0xb185, + 0xb264, 0xe9e1, 0x466c, 0xf39e, 0xafaf, 0x5f41, 0x47e2, 0xc89d}, + {0x8607, 0x9c81, 0x46a2, 0x7dcc, 0xcb0c, 0x9325, 0xe149, 0x2bde, + 0x6632, 0x2869, 0xa261, 0xb163, 0xccee, 0x22ae, 0x91e0, 0xcfd5}, + {0x831c, 0xda22, 0xb080, 0xba7a, 0x26e2, 0x54b0, 0x073b, 0x5ea0, + 0xed4b, 0xcb3d, 0xbba1, 0xbec8, 0xf2ad, 0xae0d, 0x349b, 0x17d1}}, + /* example doing 123 consecutive (f,g/2) steps; 614 divsteps */ + {{0xe9a5, 0xb4ad, 0xd995, 0x9953, 0xcdff, 0x50d7, 0xf715, 0x9dc7, + 0x3e28, 0x15a9, 0x95a3, 0x8554, 0x5b5e, 0xad1d, 0x6d57, 0x3d50}, + {0x3ad9, 0xbd60, 0x5cc7, 0x6b91, 0xadeb, 0x71f6, 0x7cc4, 0xa58a, + 0x2cce, 0xf17c, 0x38c9, 0x97ed, 0x65fb, 0x3fa6, 0xa6bc, 0xeb24}, + {0xf96c, 0x1963, 0x8151, 0xa0cc, 0x299b, 0xf277, 0x001a, 0x16bb, + 0xfd2e, 0x532d, 0x0410, 0xe117, 0x6b00, 0x44ec, 0xca6a, 0x1745}}, + /* example doing 446 (f,g/2) steps; 523 divsteps */ + {{0x3758, 0xa56c, 0xe41e, 0x4e47, 0x0975, 0xa82b, 0x107c, 0x89cf, + 0x2093, 0x5a0c, 0xda37, 0xe007, 0x6074, 0x4f68, 0x2f5a, 0xbb8a}, + {0x4beb, 0xa40f, 0x2c42, 0xd9d6, 0x97e8, 0xca7c, 0xd395, 0x894f, + 0x1f50, 0x8067, 0xa233, 0xb850, 0x1746, 0x1706, 0xbcda, 0xdf32}, + {0x762a, 0xceda, 0x4c45, 0x1ca0, 0x8c37, 0xd8c5, 0xef57, 0x7a2c, + 0x6e98, 0xe38a, 0xc50e, 0x2ca9, 0xcb85, 0x24d5, 0xc29c, 0x61f6}}, + /* example doing 446 (f,g/2) steps; 523 divsteps */ + {{0x6f38, 0x74ad, 0x7332, 0x4073, 0x6521, 0xb876, 0xa370, 0xa6bd, + 0xcea5, 0xbd06, 0x969f, 0x77c6, 0x1e69, 0x7c49, 0x7d51, 0xb6e7}, + {0x3f27, 0x4be4, 0xd81e, 0x1396, 0xb21f, 0x92aa, 0x6dc3, 0x6283, + 0x6ada, 0x3ca2, 0xc1e5, 0x8b9b, 0xd705, 0x5598, 0x8ba1, 0xe087}, + {0x6a22, 0xe834, 0xbc8d, 0xcee9, 0x42fc, 0xfc77, 0x9c45, 0x1ca8, + 0xeb66, 0xed74, 0xaaf9, 0xe75f, 0xfe77, 0x46d2, 0x179b, 0xbf3e}}, + /* example doing 336 (f,(f+g)/2) steps; 693 divsteps */ + {{0x7ea7, 0x444e, 0x84ea, 0xc447, 0x7c1f, 0xab97, 0x3de6, 0x5878, + 0x4e8b, 0xc017, 0x03e0, 0xdc40, 0xbbd0, 0x74ce, 0x0169, 0x7ab5}, + {0x4023, 0x154f, 0xfbe4, 0x8195, 0xfda0, 0xef54, 0x9e9a, 0xc703, + 0x2803, 0xf760, 0x6302, 0xed5b, 0x7157, 0x6456, 0xdd7d, 0xf14b}, + {0xb6fb, 0xe3b3, 0x0733, 0xa77e, 0x44c5, 0x3003, 0xc937, 0xdd4d, + 0x5355, 0x14e9, 0x184e, 0xcefe, 0xe6b5, 0xf2e0, 0x0a28, 0x5b74}}, + /* example doing 336 (f,(f+g)/2) steps; 687 divsteps */ + {{0xa893, 0xb5f4, 0x1ede, 0xa316, 0x242c, 0xbdcc, 0xb017, 0x0836, + 0x3a37, 0x27fb, 0xfb85, 0x251e, 0xa189, 0xb15d, 0xa4b8, 0xc24c}, + {0xb0b7, 0x57ba, 0xbb6d, 0x9177, 0xc896, 0xc7f2, 0x43b4, 0x85a6, + 0xe6c4, 0xe50e, 0x3109, 0x7ca5, 0xd73d, 0x13ff, 0x0c3d, 0xcd62}, + {0x48ca, 0xdb34, 0xe347, 0x2cef, 0x4466, 0x10fb, 0x7ee1, 0x6344, + 0x4308, 0x966d, 0xd4d1, 0xb099, 0x994f, 0xd025, 0x2187, 0x5866}}, + /* example doing 267 (g,(g-f)/2) steps; 678 divsteps */ + {{0x0775, 0x1754, 0x01f6, 0xdf37, 0xc0be, 0x8197, 0x072f, 0x6cf5, + 0x8b36, 0x8069, 0x5590, 0xb92d, 0x6084, 0x47a4, 0x23fe, 0xddd5}, + {0x8e1b, 0xda37, 0x27d9, 0x312e, 0x3a2f, 0xef6d, 0xd9eb, 0x8153, + 0xdcba, 0x9fa3, 0x9f80, 0xead5, 0x134d, 0x2ebb, 0x5ec0, 0xe032}, + {0x1cb6, 0x5a61, 0x1bed, 0x77d6, 0xd5d1, 0x7498, 0xef33, 0x2dd2, + 0x1089, 0xedbd, 0x6958, 0x16ae, 0x336c, 0x45e6, 0x4361, 0xbadc}}, + /* example doing 267 (g,(g-f)/2) steps; 676 divsteps */ + {{0x0207, 0xf948, 0xc430, 0xf36b, 0xf0a7, 0x5d36, 0x751f, 0x132c, + 0x6f25, 0xa630, 0xca1f, 0xc967, 0xaf9c, 0x34e7, 0xa38f, 0xbe9f}, + {0x5fb9, 0x7321, 0x6561, 0x5fed, 0x54ec, 0x9c3a, 0xee0e, 0x6717, + 0x49af, 0xb896, 0xf4f5, 0x451c, 0x722a, 0xf116, 0x64a9, 0xcf0b}, + {0xf4d7, 0xdb47, 0xfef2, 0x4806, 0x4cb8, 0x18c7, 0xd9a7, 0x4951, + 0x14d8, 0x5c3a, 0xd22d, 0xd7b2, 0x750c, 0x3de7, 0x8b4a, 0x19aa}}, + + /* Test cases triggering edge cases in divsteps variant starting with delta=1/2 */ + + /* example needing 590 divsteps; delta=-5/2..7/2 */ + {{0x9118, 0xb640, 0x53d7, 0x30ab, 0x2a23, 0xd907, 0x9323, 0x5b3a, + 0xb6d4, 0x538a, 0x7637, 0xfe97, 0xfd05, 0x3cc0, 0x453a, 0xfb7e}, + {0x6983, 0x4f75, 0x4ad1, 0x48ad, 0xb2d9, 0x521d, 0x3dbc, 0x9cc0, + 0x4b60, 0x0ac6, 0xd3be, 0x0fb6, 0xd305, 0x3895, 0x2da5, 0xfdf8}, + {0xcec1, 0x33ac, 0xa801, 0x8194, 0xe36c, 0x65ef, 0x103b, 0xca54, + 0xfa9b, 0xb41d, 0x9b52, 0xb6f7, 0xa611, 0x84aa, 0x3493, 0xbf54}}, + /* example needing 590 divsteps; delta=-3/2..5/2 */ + {{0xb5f2, 0x42d0, 0x35e8, 0x8ca0, 0x4b62, 0x6e1d, 0xbdf3, 0x890e, + 0x8c82, 0x23d8, 0xc79a, 0xc8e8, 0x789e, 0x353d, 0x9766, 0xea9d}, + {0x6fa1, 0xacba, 0x4b7a, 0x5de1, 0x95d0, 0xc845, 0xebbf, 0x6f5a, + 0x30cf, 0x52db, 0x69b7, 0xe278, 0x4b15, 0x8411, 0x2ab2, 0xf3e7}, + {0xf12c, 0x9d6d, 0x95fa, 0x1878, 0x9f13, 0x4fb5, 0x3c8b, 0xa451, + 0x7182, 0xc4b6, 0x7e2a, 0x7bb7, 0x6e0e, 0x5b68, 0xde55, 0x9927}}, + /* example needing 590 divsteps; delta=-3/2..5/2 */ + {{0x229c, 0x4ef8, 0x1e93, 0xe5dc, 0xcde5, 0x6d62, 0x263b, 0xad11, + 0xced0, 0x88ff, 0xae8e, 0x3183, 0x11d2, 0xa50b, 0x350d, 0xeb40}, + {0x3157, 0xe2ea, 0x8a02, 0x0aa3, 0x5ae1, 0xb26c, 0xea27, 0x6805, + 0x87e2, 0x9461, 0x37c1, 0x2f8d, 0x85d2, 0x77a8, 0xf805, 0xeec9}, + {0x6f4e, 0x2748, 0xf7e5, 0xd8d3, 0xabe2, 0x7270, 0xc4e0, 0xedc7, + 0xf196, 0x78ca, 0x9139, 0xd8af, 0x72c6, 0xaf2f, 0x85d2, 0x6cd3}}, + /* example needing 590 divsteps; delta=-5/2..7/2 */ + {{0xdce8, 0xf1fe, 0x6708, 0x021e, 0xf1ca, 0xd609, 0x5443, 0x85ce, + 0x7a05, 0x8f9c, 0x90c3, 0x52e7, 0x8e1d, 0x97b8, 0xc0bf, 0xf2a1}, + {0xbd3d, 0xed11, 0x1625, 0xb4c5, 0x844c, 0xa413, 0x2569, 0xb9ba, + 0xcd35, 0xff84, 0xcd6e, 0x7f0b, 0x7d5d, 0x10df, 0x3efe, 0xfbe5}, + {0xa9dd, 0xafef, 0xb1b7, 0x4c8d, 0x50e4, 0xafbf, 0x2d5a, 0xb27c, + 0x0653, 0x66b6, 0x5d36, 0x4694, 0x7e35, 0xc47c, 0x857f, 0x32c5}}, + /* example needing 590 divsteps; delta=-3/2..5/2 */ + {{0x7902, 0xc9f8, 0x926b, 0xaaeb, 0x90f8, 0x1c89, 0xcce3, 0x96b7, + 0x28b2, 0x87a2, 0x136d, 0x695a, 0xa8df, 0x9061, 0x9e31, 0xee82}, + {0xd3a9, 0x3c02, 0x818c, 0x6b81, 0x34b3, 0xebbb, 0xe2c8, 0x7712, + 0xbfd6, 0x8248, 0xa6f4, 0xba6f, 0x03bb, 0xfb54, 0x7575, 0xfe89}, + {0x8246, 0x0d63, 0x478e, 0xf946, 0xf393, 0x0451, 0x08c2, 0x5919, + 0x5fd6, 0x4c61, 0xbeb7, 0x9a15, 0x30e1, 0x55fc, 0x6a01, 0x3724}}, + /* example reaching delta=-127/2..129/2; 571 divsteps */ + {{0x3eff, 0x926a, 0x77f5, 0x1fff, 0x1a5b, 0xf3ef, 0xf64b, 0x8681, + 0xf800, 0xf9bc, 0x761d, 0xe268, 0x62b0, 0xa032, 0xba9c, 0xbe56}, + {0xb8f9, 0x00e7, 0x47b7, 0xdffc, 0xfd9d, 0x5abb, 0xa19b, 0x1868, + 0x31fd, 0x3b29, 0x3674, 0x5449, 0xf54d, 0x1d19, 0x6ac7, 0xff6f}, + {0xf1d7, 0x3551, 0x5682, 0x9adf, 0xe8aa, 0x19a5, 0x8340, 0x71db, + 0xb7ab, 0x4cfd, 0xf661, 0x632c, 0xc27e, 0xd3c6, 0xdf42, 0xd306}}, + /* example reaching delta=-127/2..129/2; 571 divsteps */ + {{0x0000, 0x0000, 0x0000, 0x0000, 0x3aff, 0x2ed7, 0xf2e0, 0xabc7, + 0x8aee, 0x166e, 0x7ed0, 0x9ac7, 0x714a, 0xb9c5, 0x4d58, 0xad6c}, + {0x9cf9, 0x47e2, 0xa421, 0xb277, 0xffc2, 0x2747, 0x6486, 0x94c1, + 0x1d99, 0xd49b, 0x1096, 0x991a, 0xe986, 0xae02, 0xe89b, 0xea36}, + {0x1fb4, 0x98d8, 0x19b7, 0x80e9, 0xcdac, 0xaa5a, 0xf1e6, 0x0074, + 0xe393, 0xed8b, 0x8d5c, 0xe17d, 0x81b3, 0xc16d, 0x54d3, 0x9be3}}, + /* example reaching delta=-127/2..129/2; 571 divsteps */ + {{0xd047, 0x7e36, 0x3157, 0x7ab6, 0xb4d9, 0x8dae, 0x7534, 0x4f5d, + 0x489e, 0xa8ab, 0x8a3d, 0xd52c, 0x62af, 0xa032, 0xba9c, 0xbe56}, + {0xb1f1, 0x737f, 0x5964, 0x5afb, 0x3712, 0x8ef9, 0x19f7, 0x9669, + 0x664d, 0x03ad, 0xc352, 0xf7a5, 0xf545, 0x1d19, 0x6ac7, 0xff6f}, + {0xa834, 0x5256, 0x27bc, 0x33bd, 0xba11, 0x5a7b, 0x791e, 0xe6c0, + 0x9ac4, 0x9370, 0x1130, 0x28b4, 0x2b2e, 0x231b, 0x082a, 0x796e}}, + /* example doing 123 consecutive (f,g/2) steps; 554 divsteps */ + {{0x6ab1, 0x6ea0, 0x1a99, 0xe0c2, 0xdd45, 0x645d, 0x8dbc, 0x466a, + 0xfa64, 0x4289, 0xd3f7, 0xfc8f, 0x2894, 0xe3c5, 0xa008, 0xcc14}, + {0xc75f, 0xc083, 0x4cc2, 0x64f2, 0x2aff, 0x4c12, 0x8461, 0xc4ae, + 0xbbfa, 0xb336, 0xe4b2, 0x3ac5, 0x2c22, 0xf56c, 0x5381, 0xe943}, + {0xcd80, 0x760d, 0x4395, 0xb3a6, 0xd497, 0xf583, 0x82bd, 0x1daa, + 0xbe92, 0x2613, 0xfdfb, 0x869b, 0x0425, 0xa333, 0x7056, 0xc9c5}}, + /* example doing 123 consecutive (f,g/2) steps; 554 divsteps */ + {{0x71d4, 0x64df, 0xec4f, 0x74d8, 0x7e0c, 0x40d3, 0x7073, 0x4cc8, + 0x2a2a, 0xb1ff, 0x8518, 0x6513, 0xb0ea, 0x640a, 0x62d9, 0xd5f4}, + {0xdc75, 0xd937, 0x3b13, 0x1d36, 0xdf83, 0xd034, 0x1c1c, 0x4332, + 0x4cc3, 0xeeec, 0x7d94, 0x6771, 0x3384, 0x74b0, 0x947d, 0xf2c4}, + {0x0a82, 0x37a4, 0x12d5, 0xec97, 0x972c, 0xe6bf, 0xc348, 0xa0a9, + 0xc50c, 0xdc7c, 0xae30, 0x19d1, 0x0fca, 0x35e1, 0xd6f6, 0x81ee}}, + /* example doing 123 consecutive (f,g/2) steps; 554 divsteps */ + {{0xa6b1, 0xabc5, 0x5bbc, 0x7f65, 0xdd32, 0xaa73, 0xf5a3, 0x1982, + 0xced4, 0xe949, 0x0fd6, 0x2bc4, 0x2bd7, 0xe3c5, 0xa008, 0xcc14}, + {0x4b5f, 0x8f96, 0xa375, 0xfbcf, 0x1c7d, 0xf1ec, 0x03f5, 0xb35d, + 0xb999, 0xdb1f, 0xc9a1, 0xb4c7, 0x1dd5, 0xf56c, 0x5381, 0xe943}, + {0xaa3d, 0x38b9, 0xf17d, 0xeed9, 0x9988, 0x69ee, 0xeb88, 0x1495, + 0x203f, 0x18c8, 0x82b7, 0xdcb2, 0x34a7, 0x6b00, 0x6998, 0x589a}}, + /* example doing 453 (f,g/2) steps; 514 divsteps */ + {{0xa478, 0xe60d, 0x3244, 0x60e6, 0xada3, 0xfe50, 0xb6b1, 0x2eae, + 0xd0ef, 0xa7b1, 0xef63, 0x05c0, 0xe213, 0x443e, 0x4427, 0x2448}, + {0x258f, 0xf9ef, 0xe02b, 0x92dd, 0xd7f3, 0x252b, 0xa503, 0x9089, + 0xedff, 0x96c1, 0xfe3a, 0x3a39, 0x198a, 0x981d, 0x0627, 0xedb7}, + {0x595a, 0x45be, 0x8fb0, 0x2265, 0xc210, 0x02b8, 0xdce9, 0xe241, + 0xcab6, 0xbf0d, 0x0049, 0x8d9a, 0x2f51, 0xae54, 0x5785, 0xb411}}, + /* example doing 453 (f,g/2) steps; 514 divsteps */ + {{0x48f0, 0x7db3, 0xdafe, 0x1c92, 0x5912, 0xe11a, 0xab52, 0xede1, + 0x3182, 0x8980, 0x5d2b, 0x9b5b, 0x8718, 0xda27, 0x1683, 0x1de2}, + {0x168f, 0x6f36, 0xce7a, 0xf435, 0x19d4, 0xda5e, 0x2351, 0x9af5, + 0xb003, 0x0ef5, 0x3b4c, 0xecec, 0xa9f0, 0x78e1, 0xdfef, 0xe823}, + {0x5f55, 0xfdcc, 0xb233, 0x2914, 0x84f0, 0x97d1, 0x9cf4, 0x2159, + 0xbf56, 0xb79c, 0x17a3, 0x7cef, 0xd5de, 0x34f0, 0x5311, 0x4c54}}, + /* example doing 510 (f,(f+g)/2) steps; 512 divsteps */ + {{0x2789, 0x2e04, 0x6e0e, 0xb6cd, 0xe4de, 0x4dbf, 0x228d, 0x7877, + 0xc335, 0x806b, 0x38cd, 0x8049, 0xa73b, 0xcfa2, 0x82f7, 0x9e19}, + {0xc08d, 0xb99d, 0xb8f3, 0x663d, 0xbbb3, 0x1284, 0x1485, 0x1d49, + 0xc98f, 0x9e78, 0x1588, 0x11e3, 0xd91a, 0xa2c7, 0xfff1, 0xc7b9}, + {0x1e1f, 0x411d, 0x7c49, 0x0d03, 0xe789, 0x2f8e, 0x5d55, 0xa95e, + 0x826e, 0x8de5, 0x52a0, 0x1abc, 0x4cd7, 0xd13a, 0x4395, 0x63e1}}, + /* example doing 510 (f,(f+g)/2) steps; 512 divsteps */ + {{0xd5a1, 0xf786, 0x555c, 0xb14b, 0x44ae, 0x535f, 0x4a49, 0xffc3, + 0xf497, 0x70d1, 0x57c8, 0xa933, 0xc85a, 0x1910, 0x75bf, 0x960b}, + {0xfe53, 0x5058, 0x496d, 0xfdff, 0x6fb8, 0x4100, 0x92bd, 0xe0c4, + 0xda89, 0xe0a4, 0x841b, 0x43d4, 0xa388, 0x957f, 0x99ca, 0x9abf}, + {0xe530, 0x05bc, 0xfeec, 0xfc7e, 0xbcd3, 0x1239, 0x54cb, 0x7042, + 0xbccb, 0x139e, 0x9076, 0x0203, 0x6068, 0x90c7, 0x1ddf, 0x488d}}, + /* example doing 228 (g,(g-f)/2) steps; 538 divsteps */ + {{0x9488, 0xe54b, 0x0e43, 0x81d2, 0x06e7, 0x4b66, 0x36d0, 0x53d6, + 0x2b68, 0x22ec, 0x3fa9, 0xc1a7, 0x9ad2, 0xa596, 0xb3ac, 0xdf42}, + {0xe31f, 0x0b28, 0x5f3b, 0xc1ff, 0x344c, 0xbf5f, 0xd2ec, 0x2936, + 0x9995, 0xdeb2, 0xae6c, 0x2852, 0xa2c6, 0xb306, 0x8120, 0xe305}, + {0xa56e, 0xfb98, 0x1537, 0x4d85, 0x619e, 0x866c, 0x3cd4, 0x779a, + 0xdd66, 0xa80d, 0xdc2f, 0xcae4, 0xc74c, 0x5175, 0xa65d, 0x605e}}, + /* example doing 228 (g,(g-f)/2) steps; 537 divsteps */ + {{0x8cd5, 0x376d, 0xd01b, 0x7176, 0x19ef, 0xcf09, 0x8403, 0x5e52, + 0x83c1, 0x44de, 0xb91e, 0xb33d, 0xe15c, 0x51e7, 0xbad8, 0x6359}, + {0x3b75, 0xf812, 0x5f9e, 0xa04e, 0x92d3, 0x226e, 0x540e, 0x7c9a, + 0x31c6, 0x46d2, 0x0b7b, 0xdb4a, 0xe662, 0x4950, 0x0265, 0xf76f}, + {0x09ed, 0x692f, 0xe8f1, 0x3482, 0xab54, 0x36b4, 0x8442, 0x6ae9, + 0x4329, 0x6505, 0x183b, 0x1c1d, 0x482d, 0x7d63, 0xb44f, 0xcc09}}, + + /* Test cases with the group order as modulus. */ + + /* Test case with the group order as modulus, needing 635 divsteps. */ + {{0x95ed, 0x6c01, 0xd113, 0x5ff1, 0xd7d0, 0x29cc, 0x5817, 0x6120, + 0xca8e, 0xaad1, 0x25ae, 0x8e84, 0x9af6, 0x30bf, 0xf0ed, 0x1686}, + {0x4141, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x1631, 0xbf4a, 0x286a, 0x2716, 0x469f, 0x2ac8, 0x1312, 0xe9bc, + 0x04f4, 0x304b, 0x9931, 0x113b, 0xd932, 0xc8f4, 0x0d0d, 0x01a1}}, + /* example with group size as modulus needing 631 divsteps */ + {{0x85ed, 0xc284, 0x9608, 0x3c56, 0x19b6, 0xbb5b, 0x2850, 0xdab7, + 0xa7f5, 0xe9ab, 0x06a4, 0x5bbb, 0x1135, 0xa186, 0xc424, 0xc68b}, + {0x4141, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x8479, 0x450a, 0x8fa3, 0xde05, 0xb2f5, 0x7793, 0x7269, 0xbabb, + 0xc3b3, 0xd49b, 0x3377, 0x03c6, 0xe694, 0xc760, 0xd3cb, 0x2811}}, + /* example with group size as modulus needing 565 divsteps starting at delta=1/2 */ + {{0x8432, 0x5ceb, 0xa847, 0x6f1e, 0x51dd, 0x535a, 0x6ddc, 0x70ce, + 0x6e70, 0xc1f6, 0x18f2, 0x2a7e, 0xc8e7, 0x39f8, 0x7e96, 0xebbf}, + {0x4141, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x257e, 0x449f, 0x689f, 0x89aa, 0x3989, 0xb661, 0x376c, 0x1e32, + 0x654c, 0xee2e, 0xf4e2, 0x33c8, 0x3f2f, 0x9716, 0x6046, 0xcaa3}}, + /* Test case with the group size as modulus, needing 981 divsteps with + broken eta handling. */ + {{0xfeb9, 0xb877, 0xee41, 0x7fa3, 0x87da, 0x94c4, 0x9d04, 0xc5ae, + 0x5708, 0x0994, 0xfc79, 0x0916, 0xbf32, 0x3ad8, 0xe11c, 0x5ca2}, + {0x4141, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x0f12, 0x075e, 0xce1c, 0x6f92, 0xc80f, 0xca92, 0x9a04, 0x6126, + 0x4b6c, 0x57d6, 0xca31, 0x97f3, 0x1f99, 0xf4fd, 0xda4d, 0x42ce}}, + /* Test case with the group size as modulus, input = 0. */ + {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0x4141, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + /* Test case with the group size as modulus, input = 1. */ + {{0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0x4141, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + /* Test case with the group size as modulus, input = 2. */ + {{0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0x4141, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x20a1, 0x681b, 0x2f46, 0xdfe9, 0x501d, 0x57a4, 0x6e73, 0x5d57, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x7fff}}, + /* Test case with the group size as modulus, input = group - 1. */ + {{0x4140, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x4141, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x4140, 0xd036, 0x5e8c, 0xbfd2, 0xa03b, 0xaf48, 0xdce6, 0xbaae, + 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}}, + + /* Test cases with the field size as modulus. */ + + /* Test case with the field size as modulus, needing 637 divsteps. */ + {{0x9ec3, 0x1919, 0xca84, 0x7c11, 0xf996, 0x06f3, 0x5408, 0x6688, + 0x1320, 0xdb8a, 0x632a, 0x0dcb, 0x8a84, 0x6bee, 0x9c95, 0xe34e}, + {0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x18e5, 0x19b6, 0xdf92, 0x1aaa, 0x09fb, 0x8a3f, 0x52b0, 0x8701, + 0xac0c, 0x2582, 0xda44, 0x9bcc, 0x6828, 0x1c53, 0xbd8f, 0xbd2c}}, + /* example with field size as modulus needing 637 divsteps */ + {{0xaec3, 0xa7cf, 0x2f2d, 0x0693, 0x5ad5, 0xa8ff, 0x7ec7, 0x30ff, + 0x0c8b, 0xc242, 0xcab2, 0x063a, 0xf86e, 0x6057, 0x9cbd, 0xf6d8}, + {0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x0310, 0x579d, 0xcb38, 0x9030, 0x3ded, 0x9bb9, 0x1234, 0x63ce, + 0x0c63, 0x8e3d, 0xacfe, 0x3c20, 0xdc85, 0xf859, 0x919e, 0x1d45}}, + /* example with field size as modulus needing 564 divsteps starting at delta=1/2 */ + {{0x63ae, 0x8d10, 0x0071, 0xdb5c, 0xb454, 0x78d1, 0x744a, 0x5f8e, + 0xe4d8, 0x87b1, 0x8e62, 0x9590, 0xcede, 0xa070, 0x36b4, 0x7f6f}, + {0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0xfdc8, 0xe8d5, 0xbe15, 0x9f86, 0xa5fe, 0xf18e, 0xa7ff, 0xd291, + 0xf4c2, 0x9c87, 0xf150, 0x073e, 0x69b8, 0xf7c4, 0xee4b, 0xc7e6}}, + /* Test case with the field size as modulus, needing 935 divsteps with + broken eta handling. */ + {{0x1b37, 0xbdc3, 0x8bcd, 0x25e3, 0x1eae, 0x567d, 0x30b6, 0xf0d8, + 0x9277, 0x0cf8, 0x9c2e, 0xecd7, 0x631d, 0xe38f, 0xd4f8, 0x5c93}, + {0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x1622, 0xe05b, 0xe880, 0x7de9, 0x3e45, 0xb682, 0xee6c, 0x67ed, + 0xa179, 0x15db, 0x6b0d, 0xa656, 0x7ccb, 0x8ef7, 0xa2ff, 0xe279}}, + /* Test case with the field size as modulus, input = 0. */ + {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + /* Test case with the field size as modulus, input = 1. */ + {{0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + /* Test case with the field size as modulus, input = 2. */ + {{0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0xfe18, 0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x7fff}}, + /* Test case with the field size as modulus, input = field - 1. */ + {{0xfc2e, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {0xfc2e, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}}, + + /* Selected from a large number of random inputs to reach small/large + * d/e values in various configurations. */ + {{0x3a08, 0x23e1, 0x4d8c, 0xe606, 0x3263, 0x67af, 0x9bf1, 0x9d70, + 0xf5fd, 0x12e4, 0x03c8, 0xb9ca, 0xe847, 0x8c5d, 0x6322, 0xbd30}, + {0x8359, 0x59dd, 0x1831, 0x7c1a, 0x1e83, 0xaee1, 0x770d, 0xcea8, + 0xfbb1, 0xeed6, 0x10b5, 0xe2c6, 0x36ea, 0xee17, 0xe32c, 0xffff}, + {0x1727, 0x0f36, 0x6f85, 0x5d0c, 0xca6c, 0x3072, 0x9628, 0x5842, + 0xcb44, 0x7c2b, 0xca4f, 0x62e5, 0x29b1, 0x6ffd, 0x9055, 0xc196}}, + {{0x905d, 0x41c8, 0xa2ff, 0x295b, 0x72bb, 0x4679, 0x6d01, 0x2c98, + 0xb3e0, 0xc537, 0xa310, 0xe07e, 0xe72f, 0x4999, 0x1148, 0xf65e}, + {0x5b41, 0x4239, 0x3c37, 0x5130, 0x30e3, 0xff35, 0xc51f, 0x1a43, + 0xdb23, 0x13cf, 0x9f49, 0xf70c, 0x5e70, 0xd411, 0x3005, 0xf8c6}, + {0xc30e, 0x68f0, 0x201a, 0xe10c, 0x864a, 0x6243, 0xe946, 0x43ae, + 0xf3f1, 0x52dc, 0x1f7f, 0x50d4, 0x2797, 0x064c, 0x5ca4, 0x90e3}}, + {{0xf1b5, 0xc6e5, 0xd2c4, 0xff95, 0x27c5, 0x0c92, 0x5d19, 0x7ae5, + 0x4fbe, 0x5438, 0x99e1, 0x880d, 0xd892, 0xa05c, 0x6ffd, 0x7eac}, + {0x2153, 0xcc9d, 0xfc6c, 0x8358, 0x49a1, 0x01e2, 0xcef0, 0x4969, + 0xd69a, 0x8cef, 0xf5b2, 0xfd95, 0xdcc2, 0x71f4, 0x6ae2, 0xceeb}, + {0x9b2e, 0xcdc6, 0x0a5c, 0x7317, 0x9084, 0xe228, 0x56cf, 0xd512, + 0x628a, 0xce21, 0x3473, 0x4e13, 0x8823, 0x1ed0, 0x34d0, 0xbfa3}}, + {{0x5bae, 0x53e5, 0x5f4d, 0x21ca, 0xb875, 0x8ecf, 0x9aa6, 0xbe3c, + 0x9f96, 0x7b82, 0x375d, 0x4d3e, 0x491c, 0xb1eb, 0x04c9, 0xb6c8}, + {0xfcfd, 0x10b7, 0x73b2, 0xd23b, 0xa357, 0x67da, 0x0d9f, 0x8702, + 0xa037, 0xff8e, 0x0e8b, 0x1801, 0x2c5c, 0x4e6e, 0x4558, 0xfff2}, + {0xc50f, 0x5654, 0x6713, 0x5ef5, 0xa7ce, 0xa647, 0xc832, 0x69ce, + 0x1d5c, 0x4310, 0x0746, 0x5a01, 0x96ea, 0xde4b, 0xa88b, 0x5543}}, + {{0xdc7f, 0x5e8c, 0x89d1, 0xb077, 0xd521, 0xcf90, 0x32fa, 0x5737, + 0x839e, 0x1464, 0x007c, 0x09c6, 0x9371, 0xe8ea, 0xc1cb, 0x75c4}, + {0xe3a3, 0x107f, 0xa82a, 0xa375, 0x4578, 0x60f4, 0x75c9, 0x5ee4, + 0x3fd7, 0x2736, 0x2871, 0xd3d2, 0x5f1d, 0x1abb, 0xa764, 0xffff}, + {0x45c6, 0x1f2e, 0xb14c, 0x84d7, 0x7bb7, 0x5a04, 0x0504, 0x3f33, + 0x5cc1, 0xb07a, 0x6a6c, 0x786f, 0x647f, 0xe1d7, 0x78a2, 0x4cf4}}, + {{0xc006, 0x356f, 0x8cd2, 0x967b, 0xb49e, 0x2d4e, 0x14bf, 0x4bcb, + 0xddab, 0xd3f9, 0xa068, 0x2c1c, 0xd242, 0xa56d, 0xf2c7, 0x5f97}, + {0x465b, 0xb745, 0x0e0d, 0x69a9, 0x987d, 0xcb37, 0xf637, 0xb311, + 0xc4d6, 0x2ddb, 0xf68f, 0x2af9, 0x959d, 0x3f53, 0x98f2, 0xf640}, + {0xc0f2, 0x6bfb, 0xf5c3, 0x91c1, 0x6b05, 0x0825, 0x5ca0, 0x7df7, + 0x9d55, 0x6d9e, 0xfe94, 0x2ad9, 0xd9f0, 0xe68b, 0xa72b, 0xd1b2}}, + {{0x2279, 0x61ba, 0x5bc6, 0x136b, 0xf544, 0x717c, 0xafda, 0x02bd, + 0x79af, 0x1fad, 0xea09, 0x81bb, 0x932b, 0x32c9, 0xdf1d, 0xe576}, + {0x8215, 0x7817, 0xca82, 0x43b0, 0x9b06, 0xea65, 0x1291, 0x0621, + 0x0089, 0x46fe, 0xc5a6, 0xddd7, 0x8065, 0xc6a0, 0x214b, 0xfc64}, + {0x04bf, 0x6f2a, 0x86b2, 0x841a, 0x4a95, 0xc632, 0x97b7, 0x5821, + 0x2b18, 0x1bb0, 0x3e97, 0x935e, 0xcc7d, 0x066b, 0xd513, 0xc251}}, + {{0x76e8, 0x5bc2, 0x3eaa, 0x04fc, 0x9974, 0x92c1, 0x7c15, 0xfa89, + 0x1151, 0x36ee, 0x48b2, 0x049c, 0x5f16, 0xcee4, 0x925b, 0xe98e}, + {0x913f, 0x0a2d, 0xa185, 0x9fea, 0xda5a, 0x4025, 0x40d7, 0x7cfa, + 0x88ca, 0xbbe8, 0xb265, 0xb7e4, 0x6cb1, 0xed64, 0xc6f9, 0xffb5}, + {0x6ab1, 0x1a86, 0x5009, 0x152b, 0x1cc4, 0xe2c8, 0x960b, 0x19d0, + 0x3554, 0xc562, 0xd013, 0xcf91, 0x10e1, 0x7933, 0xe195, 0xcf49}}, + {{0x9cb5, 0xd2d7, 0xc6ed, 0xa818, 0xb495, 0x06ee, 0x0f4a, 0x06e3, + 0x4c5a, 0x80ce, 0xd49a, 0x4cd7, 0x7487, 0x92af, 0xe516, 0x676c}, + {0xd6e9, 0x6b85, 0x619a, 0xb52c, 0x20a0, 0x2f79, 0x3545, 0x1edd, + 0x5a6f, 0x8082, 0x9b80, 0xf8f8, 0xc78a, 0xd0a3, 0xadf4, 0xffff}, + {0x01c2, 0x2118, 0xef5e, 0xa877, 0x046a, 0xd2c2, 0x2ad5, 0x951c, + 0x8900, 0xa5c9, 0x8d0f, 0x6b61, 0x55d3, 0xd572, 0x48de, 0x9219}}, + {{0x5114, 0x0644, 0x23dd, 0x01d3, 0xc101, 0xa659, 0xea17, 0x640f, + 0xf767, 0x2644, 0x9cec, 0xd8ba, 0xd6da, 0x9156, 0x8aeb, 0x875a}, + {0xc1bf, 0xdae9, 0xe96b, 0xce77, 0xf7a1, 0x3e99, 0x5c2e, 0x973b, + 0xd048, 0x5bd0, 0x4e8a, 0xcb85, 0xce39, 0x37f5, 0x815d, 0xffff}, + {0x48cc, 0x35b6, 0x26d4, 0x2ea6, 0x50d6, 0xa2f9, 0x64b6, 0x03bf, + 0xd00c, 0xe057, 0x3343, 0xfb79, 0x3ce5, 0xf717, 0xc5af, 0xe185}}, + {{0x13ff, 0x6c76, 0x2077, 0x16e0, 0xd5ca, 0xf2ad, 0x8dba, 0x8f49, + 0x7887, 0x16f9, 0xb646, 0xfc87, 0xfa31, 0x5096, 0xf08c, 0x3fbe}, + {0x8139, 0x6fd7, 0xf6df, 0xa7bf, 0x6699, 0x5361, 0x6f65, 0x13c8, + 0xf4d1, 0xe28f, 0xc545, 0x0a8c, 0x5274, 0xb0a6, 0xffff, 0xffff}, + {0x22ca, 0x0cd6, 0xc1b5, 0xb064, 0x44a7, 0x297b, 0x495f, 0x34ac, + 0xfa95, 0xec62, 0xf08d, 0x621c, 0x66a6, 0xba94, 0x84c6, 0x8ee0}}, + {{0xaa30, 0x312e, 0x439c, 0x4e88, 0x2e2f, 0x32dc, 0xb880, 0xa28e, + 0xf795, 0xc910, 0xb406, 0x8dd7, 0xb187, 0xa5a5, 0x38f1, 0xe49e}, + {0xfb19, 0xf64a, 0xba6a, 0x8ec2, 0x7255, 0xce89, 0x2cf9, 0x9cba, + 0xe1fe, 0x50da, 0x1705, 0xac52, 0xe3d4, 0x4269, 0x0648, 0xfd77}, + {0xb4c8, 0x6e8a, 0x2b5f, 0x4c2d, 0x5a67, 0xa7bb, 0x7d6d, 0x5569, + 0xa0ea, 0x244a, 0xc0f2, 0xf73d, 0x58cf, 0xac7f, 0xd32b, 0x3018}}, + {{0xc953, 0x1ae1, 0xae46, 0x8709, 0x19c2, 0xa986, 0x9abe, 0x1611, + 0x0395, 0xd5ab, 0xf0f6, 0xb5b0, 0x5b2b, 0x0317, 0x80ba, 0x376d}, + {0xfe77, 0xbc03, 0xac2f, 0x9d00, 0xa175, 0x293d, 0x3b56, 0x0e3a, + 0x0a9c, 0xf40c, 0x690e, 0x1508, 0x95d4, 0xddc4, 0xe805, 0xffff}, + {0xb1ce, 0x0929, 0xa5fe, 0x4b50, 0x9d5d, 0x8187, 0x2557, 0x4376, + 0x11ba, 0xdcef, 0xc1f3, 0xd531, 0x1824, 0x93f6, 0xd81f, 0x8f83}}, + {{0xb8d2, 0xb900, 0x4a0c, 0x7188, 0xa5bf, 0x1b0b, 0x2ae5, 0xa35b, + 0x98e0, 0x610c, 0x86db, 0x2487, 0xa267, 0x002c, 0xebb6, 0xc5f4}, + {0x9cdd, 0x1c1b, 0x2f06, 0x43d1, 0xce47, 0xc334, 0x6e60, 0xc016, + 0x989e, 0x0ab2, 0x0cac, 0x1196, 0xe2d9, 0x2e04, 0xc62b, 0xffff}, + {0xdc36, 0x1f05, 0x6aa9, 0x7a20, 0x944f, 0x2fd3, 0xa553, 0xdb4f, + 0xbd5c, 0x3a75, 0x25d4, 0xe20e, 0xa387, 0x1410, 0xdbb1, 0x1b60}}, + {{0x76b3, 0x2207, 0x4930, 0x5dd7, 0x65a0, 0xd55c, 0xb443, 0x53b7, + 0x5c22, 0x818a, 0xb2e7, 0x9de8, 0x9985, 0xed45, 0x33b1, 0x53e8}, + {0x7913, 0x44e1, 0xf15b, 0x5edd, 0x34f3, 0x4eba, 0x0758, 0x7104, + 0x32d9, 0x28f3, 0x4401, 0x85c5, 0xb695, 0xb899, 0xc0f2, 0xffff}, + {0x7f43, 0xd202, 0x24c9, 0x69f3, 0x74dc, 0x1a69, 0xeaee, 0x5405, + 0x1755, 0x4bb8, 0x04e3, 0x2fd2, 0xada8, 0x39eb, 0x5b4d, 0x96ca}}, + {{0x807b, 0x7112, 0xc088, 0xdafd, 0x02fa, 0x9d95, 0x5e42, 0xc033, + 0xde0a, 0xeecf, 0x8e90, 0x8da1, 0xb17e, 0x9a5b, 0x4c6d, 0x1914}, + {0x4871, 0xd1cb, 0x47d7, 0x327f, 0x09ec, 0x97bb, 0x2fae, 0xd346, + 0x6b78, 0x3707, 0xfeb2, 0xa6ab, 0x13df, 0x76b0, 0x8fb9, 0xffb3}, + {0x179e, 0xb63b, 0x4784, 0x231e, 0x9f42, 0x7f1a, 0xa3fb, 0xdd8c, + 0xd1eb, 0xb4c9, 0x8ca7, 0x018c, 0xf691, 0x576c, 0xa7d6, 0xce27}}, + {{0x5f45, 0x7c64, 0x083d, 0xedd5, 0x08a0, 0x0c64, 0x6c6f, 0xec3c, + 0xe2fb, 0x352c, 0x9303, 0x75e4, 0xb4e0, 0x8b09, 0xaca4, 0x7025}, + {0x1025, 0xb482, 0xfed5, 0xa678, 0x8966, 0x9359, 0x5329, 0x98bb, + 0x85b2, 0x73ba, 0x9982, 0x6fdc, 0xf190, 0xbe8c, 0xdc5c, 0xfd93}, + {0x83a2, 0x87a4, 0xa680, 0x52a1, 0x1ba1, 0x8848, 0x5db7, 0x9744, + 0x409c, 0x0745, 0x0e1e, 0x1cfc, 0x00cd, 0xf573, 0x2071, 0xccaa}}, + {{0xf61f, 0x63d4, 0x536c, 0x9eb9, 0x5ddd, 0xbb11, 0x9014, 0xe904, + 0xfe01, 0x6b45, 0x1858, 0xcb5b, 0x4c38, 0x43e1, 0x381d, 0x7f94}, + {0xf61f, 0x63d4, 0xd810, 0x7ca3, 0x8a04, 0x4b83, 0x11fc, 0xdf94, + 0x4169, 0xbd05, 0x608e, 0x7151, 0x4fbf, 0xb31a, 0x38a7, 0xa29b}, + {0xe621, 0xdfa5, 0x3d06, 0x1d03, 0x81e6, 0x00da, 0x53a6, 0x965e, + 0x93e5, 0x2164, 0x5b61, 0x59b8, 0xa629, 0x8d73, 0x699a, 0x6111}}, + {{0x4cc3, 0xd29e, 0xf4a3, 0x3428, 0x2048, 0xeec9, 0x5f50, 0x99a4, + 0x6de9, 0x05f2, 0x5aa9, 0x5fd2, 0x98b4, 0x1adc, 0x225f, 0x777f}, + {0xe649, 0x37da, 0x5ba6, 0x5765, 0x3f4a, 0x8a1c, 0x2e79, 0xf550, + 0x1a54, 0xcd1e, 0x7218, 0x3c3c, 0x6311, 0xfe28, 0x95fb, 0xed97}, + {0xe9b6, 0x0c47, 0x3f0e, 0x849b, 0x11f8, 0xe599, 0x5e4d, 0xd618, + 0xa06d, 0x33a0, 0x9a3e, 0x44db, 0xded8, 0x10f0, 0x94d2, 0x81fb}}, + {{0x2e59, 0x7025, 0xd413, 0x455a, 0x1ce3, 0xbd45, 0x7263, 0x27f7, + 0x23e3, 0x518e, 0xbe06, 0xc8c4, 0xe332, 0x4276, 0x68b4, 0xb166}, + {0x596f, 0x0cf6, 0xc8ec, 0x787b, 0x04c1, 0x473c, 0xd2b8, 0x8d54, + 0x9cdf, 0x77f2, 0xd3f3, 0x6735, 0x0638, 0xf80e, 0x9467, 0xc6aa}, + {0xc7e7, 0x1822, 0xb62a, 0xec0d, 0x89cd, 0x7846, 0xbfa2, 0x35d5, + 0xfa38, 0x870f, 0x494b, 0x1697, 0x8b17, 0xf904, 0x10b6, 0x9822}}, + {{0x6d5b, 0x1d4f, 0x0aaf, 0x807b, 0x35fb, 0x7ee8, 0x00c6, 0x059a, + 0xddf0, 0x1fb1, 0xc38a, 0xd78e, 0x2aa4, 0x79e7, 0xad28, 0xc3f1}, + {0xe3bb, 0x174e, 0xe0a8, 0x74b6, 0xbd5b, 0x35f6, 0x6d23, 0x6328, + 0xc11f, 0x83e1, 0xf928, 0xa918, 0x838e, 0xbf43, 0xe243, 0xfffb}, + {0x9cf2, 0x6b8b, 0x3476, 0x9d06, 0xdcf2, 0xdb8a, 0x89cd, 0x4857, + 0x75c2, 0xabb8, 0x490b, 0xc9bd, 0x890e, 0xe36e, 0xd552, 0xfffa}}, + {{0x2f09, 0x9d62, 0xa9fc, 0xf090, 0xd6d1, 0x9d1d, 0x1828, 0xe413, + 0xc92b, 0x3d5a, 0x1373, 0x368c, 0xbaf2, 0x2158, 0x71eb, 0x08a3}, + {0x2f09, 0x1d62, 0x4630, 0x0de1, 0x06dc, 0xf7f1, 0xc161, 0x1e92, + 0x7495, 0x97e4, 0x94b6, 0xa39e, 0x4f1b, 0x18f8, 0x7bd4, 0x0c4c}, + {0xeb3d, 0x723d, 0x0907, 0x525b, 0x463a, 0x49a8, 0xc6b8, 0xce7f, + 0x740c, 0x0d7d, 0xa83b, 0x457f, 0xae8e, 0xc6af, 0xd331, 0x0475}}, + {{0x6abd, 0xc7af, 0x3e4e, 0x95fd, 0x8fc4, 0xee25, 0x1f9c, 0x0afe, + 0x291d, 0xcde0, 0x48f4, 0xb2e8, 0xf7af, 0x8f8d, 0x0bd6, 0x078d}, + {0x4037, 0xbf0e, 0x2081, 0xf363, 0x13b2, 0x381e, 0xfb6e, 0x818e, + 0x27e4, 0x5662, 0x18b0, 0x0cd2, 0x81f5, 0x9415, 0x0d6c, 0xf9fb}, + {0xd205, 0x0981, 0x0498, 0x1f08, 0xdb93, 0x1732, 0x0579, 0x1424, + 0xad95, 0x642f, 0x050c, 0x1d6d, 0xfc95, 0xfc4a, 0xd41b, 0x3521}}, + {{0xf23a, 0x4633, 0xaef4, 0x1a92, 0x3c8b, 0x1f09, 0x30f3, 0x4c56, + 0x2a2f, 0x4f62, 0xf5e4, 0x8329, 0x63cc, 0xb593, 0xec6a, 0xc428}, + {0x93a7, 0xfcf6, 0x606d, 0xd4b2, 0x2aad, 0x28b4, 0xc65b, 0x8998, + 0x4e08, 0xd178, 0x0900, 0xc82b, 0x7470, 0xa342, 0x7c0f, 0xffff}, + {0x315f, 0xf304, 0xeb7b, 0xe5c3, 0x1451, 0x6311, 0x8f37, 0x93a8, + 0x4a38, 0xa6c6, 0xe393, 0x1087, 0x6301, 0xd673, 0x4ec4, 0xffff}}, + {{0x892e, 0xeed0, 0x1165, 0xcbc1, 0x5545, 0xa280, 0x7243, 0x10c9, + 0x9536, 0x36af, 0xb3fc, 0x2d7c, 0xe8a5, 0x09d6, 0xe1d4, 0xe85d}, + {0xae09, 0xc28a, 0xd777, 0xbd80, 0x23d6, 0xf980, 0xeb7c, 0x4e0e, + 0xf7dc, 0x6475, 0xf10a, 0x2d33, 0x5dfd, 0x797a, 0x7f1c, 0xf71a}, + {0x4064, 0x8717, 0xd091, 0x80b0, 0x4527, 0x8442, 0xac8b, 0x9614, + 0xc633, 0x35f5, 0x7714, 0x2e83, 0x4aaa, 0xd2e4, 0x1acd, 0x0562}}, + {{0xdb64, 0x0937, 0x308b, 0x53b0, 0x00e8, 0xc77f, 0x2f30, 0x37f7, + 0x79ce, 0xeb7f, 0xde81, 0x9286, 0xafda, 0x0e62, 0xae00, 0x0067}, + {0x2cc7, 0xd362, 0xb161, 0x0557, 0x4ff2, 0xb9c8, 0x06fe, 0x5f2b, + 0xde33, 0x0190, 0x28c6, 0xb886, 0xee2b, 0x5a4e, 0x3289, 0x0185}, + {0x4215, 0x923e, 0xf34f, 0xb362, 0x88f8, 0xceec, 0xafdd, 0x7f42, + 0x0c57, 0x56b2, 0xa366, 0x6a08, 0x0826, 0xfb8f, 0x1b03, 0x0163}}, + {{0xa4ba, 0x8408, 0x810a, 0xdeba, 0x47a3, 0x853a, 0xeb64, 0x2f74, + 0x3039, 0x038c, 0x7fbb, 0x498e, 0xd1e9, 0x46fb, 0x5691, 0x32a4}, + {0xd749, 0xb49d, 0x20b7, 0x2af6, 0xd34a, 0xd2da, 0x0a10, 0xf781, + 0x58c9, 0x171f, 0x3cb6, 0x6337, 0x88cd, 0xcf1e, 0xb246, 0x7351}, + {0xf729, 0xcf0a, 0x96ea, 0x032c, 0x4a8f, 0x42fe, 0xbac8, 0xec65, + 0x1510, 0x0d75, 0x4c17, 0x8d29, 0xa03f, 0x8b7e, 0x2c49, 0x0000}}, + {{0x0fa4, 0x8e1c, 0x3788, 0xba3c, 0x8d52, 0xd89d, 0x12c8, 0xeced, + 0x9fe6, 0x9b88, 0xecf3, 0xe3c8, 0xac48, 0x76ed, 0xf23e, 0xda79}, + {0x1103, 0x227c, 0x5b00, 0x3fcf, 0xc5d0, 0x2d28, 0x8020, 0x4d1c, + 0xc6b9, 0x67f9, 0x6f39, 0x989a, 0xda53, 0x3847, 0xd416, 0xe0d0}, + {0xdd8e, 0xcf31, 0x3710, 0x7e44, 0xa511, 0x933c, 0x0cc3, 0x5145, + 0xf632, 0x5e1d, 0x038f, 0x5ce7, 0x7265, 0xda9d, 0xded6, 0x08f8}}, + {{0xe2c8, 0x91d5, 0xa5f5, 0x735f, 0x6b58, 0x56dc, 0xb39d, 0x5c4a, + 0x57d0, 0xa1c2, 0xd92f, 0x9ad4, 0xf7c4, 0x51dd, 0xaf5c, 0x0096}, + {0x1739, 0x7207, 0x7505, 0xbf35, 0x42de, 0x0a29, 0xa962, 0xdedf, + 0x53e8, 0x12bf, 0xcde7, 0xd8e2, 0x8d4d, 0x2c4b, 0xb1b1, 0x0628}, + {0x992d, 0xe3a7, 0xb422, 0xc198, 0x23ab, 0xa6ef, 0xb45d, 0x50da, + 0xa738, 0x014a, 0x2310, 0x85fb, 0x5fe8, 0x1b18, 0x1774, 0x03a7}}, + {{0x1f16, 0x2b09, 0x0236, 0xee90, 0xccf9, 0x9775, 0x8130, 0x4c91, + 0x9091, 0x310b, 0x6dc4, 0x86f6, 0xc2e8, 0xef60, 0xfc0e, 0xf3a4}, + {0x9f49, 0xac15, 0x02af, 0x110f, 0xc59d, 0x5677, 0xa1a9, 0x38d5, + 0x914f, 0xa909, 0x3a3a, 0x4a39, 0x3703, 0xea30, 0x73da, 0xffad}, + {0x15ed, 0xdd16, 0x83c7, 0x270a, 0x862f, 0xd8ad, 0xcaa1, 0x5f41, + 0x99a9, 0x3fc8, 0x7bb2, 0x360a, 0xb06d, 0xfadc, 0x1b36, 0xffa8}}, + {{0xc4e0, 0xb8fd, 0x5106, 0xe169, 0x754c, 0xa58c, 0xc413, 0x8224, + 0x5483, 0x63ec, 0xd477, 0x8473, 0x4778, 0x9281, 0x0000, 0x0000}, + {0x85e1, 0xff54, 0xb200, 0xe413, 0xf4f4, 0x4c0f, 0xfcec, 0xc183, + 0x60d3, 0x1b0c, 0x3834, 0x601c, 0x943c, 0xbe6e, 0x0002, 0x0000}, + {0xf4f8, 0xfd5e, 0x61ef, 0xece8, 0x9199, 0xe5c4, 0x05a6, 0xe6c3, + 0xc4ae, 0x8b28, 0x66b1, 0x8a95, 0x9ece, 0x8f4a, 0x0001, 0x0000}}, + {{0xeae9, 0xa1b4, 0xc6d8, 0x2411, 0x2b5a, 0x1dd0, 0x2dc9, 0xb57b, + 0x5ccd, 0x4957, 0xaf59, 0xa04b, 0x5f42, 0xab7c, 0x2826, 0x526f}, + {0xf407, 0x165a, 0xb724, 0x2f12, 0x2ea1, 0x470b, 0x4464, 0xbd35, + 0x606f, 0xd73e, 0x50d3, 0x8a7f, 0x8029, 0x7ffc, 0xbe31, 0x6cfb}, + {0x8171, 0x1f4c, 0xced2, 0x9c99, 0x6d7e, 0x5a0f, 0xfefb, 0x59e3, + 0xa0c8, 0xabd9, 0xc4c5, 0x57d3, 0xbfa3, 0x4f11, 0x96a2, 0x5a7d}}, + {{0xe068, 0x4cc0, 0x8bcd, 0xc903, 0x9e52, 0xb3e1, 0xd745, 0x0995, + 0xdd8f, 0xf14b, 0xd2ac, 0xd65a, 0xda1d, 0xa742, 0xbac5, 0x474c}, + {0x7481, 0xf2ad, 0x9757, 0x2d82, 0xb683, 0xb16b, 0x0002, 0x7b60, + 0x8f0c, 0x2594, 0x8f64, 0x3b7a, 0x3552, 0x8d9d, 0xb9d7, 0x67eb}, + {0xcaab, 0xb9a1, 0xf966, 0xe311, 0x5b34, 0x0fa0, 0x6abc, 0x8134, + 0xab3d, 0x90f6, 0x1984, 0x9232, 0xec17, 0x74e5, 0x2ceb, 0x434e}}, + {{0x0fb1, 0x7a55, 0x1a5c, 0x53eb, 0xd7b3, 0x7a01, 0xca32, 0x31f6, + 0x3b74, 0x679e, 0x1501, 0x6c57, 0xdb20, 0x8b7c, 0xd7d0, 0x8097}, + {0xb127, 0xb20c, 0xe3a2, 0x96f3, 0xe0d8, 0xd50c, 0x14b4, 0x0b40, + 0x6eeb, 0xa258, 0x99db, 0x3c8c, 0x0f51, 0x4198, 0x3887, 0xffd0}, + {0x0273, 0x9f8c, 0x9669, 0xbbba, 0x1c49, 0x767c, 0xc2af, 0x59f0, + 0x1366, 0xd397, 0x63ac, 0x6fe8, 0x1a9a, 0x1259, 0x01d0, 0x0016}}, + {{0x7876, 0x2a35, 0xa24a, 0x433e, 0x5501, 0x573c, 0xd76d, 0xcb82, + 0x1334, 0xb4a6, 0xf290, 0xc797, 0xeae9, 0x2b83, 0x1e2b, 0x8b14}, + {0x3885, 0x8aef, 0x9dea, 0x2b8c, 0xdd7c, 0xd7cd, 0xb0cc, 0x05ee, + 0x361b, 0x3800, 0xb0d4, 0x4c23, 0xbd3f, 0x5180, 0x9783, 0xff80}, + {0xab36, 0x3104, 0xdae8, 0x0704, 0x4a28, 0x6714, 0x824b, 0x0051, + 0x8134, 0x1f6a, 0x712d, 0x1f03, 0x03b2, 0xecac, 0x377d, 0xfef9}} + }; + + int i, j, ok; + + /* Test known inputs/outputs */ + for (i = 0; (size_t)i < sizeof(CASES) / sizeof(CASES[0]); ++i) { + uint16_t out[16]; + test_modinv32_uint16(out, CASES[i][0], CASES[i][1]); + for (j = 0; j < 16; ++j) CHECK(out[j] == CASES[i][2][j]); +#ifdef SECP256K1_WIDEMUL_INT128 + test_modinv64_uint16(out, CASES[i][0], CASES[i][1]); + for (j = 0; j < 16; ++j) CHECK(out[j] == CASES[i][2][j]); +#endif + } + + for (i = 0; i < 100 * COUNT; ++i) { + /* 256-bit numbers in 16-uint16_t's notation */ + static const uint16_t ZERO[16] = {0}; + uint16_t xd[16]; /* the number (in range [0,2^256)) to be inverted */ + uint16_t md[16]; /* the modulus (odd, in range [3,2^256)) */ + uint16_t id[16]; /* the inverse of xd mod md */ + + /* generate random xd and md, so that md is odd, md>1, xd>= 16; + } +} + +/* Negate a 256-bit number (represented as 16 uint16_t's in LE order) mod 2^256. */ +static void neg256(uint16_t* out, const uint16_t* a) { + int i; + uint32_t carry = 1; + for (i = 0; i < 16; ++i) { + carry += (uint16_t)~a[i]; + out[i] = carry; + carry >>= 16; + } +} + +/* Right-shift a 256-bit number (represented as 16 uint16_t's in LE order). */ +static void rshift256(uint16_t* out, const uint16_t* a, int n, int sign_extend) { + uint16_t sign = sign_extend && (a[15] >> 15); + int i, j; + for (i = 15; i >= 0; --i) { + uint16_t v = 0; + for (j = 0; j < 16; ++j) { + int frompos = i*16 + j + n; + if (frompos >= 256) { + v |= sign << j; + } else { + v |= ((uint16_t)((a[frompos >> 4] >> (frompos & 15)) & 1)) << j; + } + } + out[i] = v; + } +} + +/* Load a 64-bit unsigned integer into an array of 16 uint16_t's in LE order representing a 256-bit value. */ +static void load256u64(uint16_t* out, uint64_t v, int is_signed) { + int i; + uint64_t sign = is_signed && (v >> 63) ? UINT64_MAX : 0; + for (i = 0; i < 4; ++i) { + out[i] = v >> (16 * i); + } + for (i = 4; i < 16; ++i) { + out[i] = sign; + } +} + +/* Load a 128-bit unsigned integer into an array of 16 uint16_t's in LE order representing a 256-bit value. */ +static void load256two64(uint16_t* out, uint64_t hi, uint64_t lo, int is_signed) { + int i; + uint64_t sign = is_signed && (hi >> 63) ? UINT64_MAX : 0; + for (i = 0; i < 4; ++i) { + out[i] = lo >> (16 * i); + } + for (i = 4; i < 8; ++i) { + out[i] = hi >> (16 * (i - 4)); + } + for (i = 8; i < 16; ++i) { + out[i] = sign; + } +} + +/* Check whether the 256-bit value represented by array of 16-bit values is in range -2^127 < v < 2^127. */ +static int int256is127(const uint16_t* v) { + int all_0 = ((v[7] & 0x8000) == 0), all_1 = ((v[7] & 0x8000) == 0x8000); + int i; + for (i = 8; i < 16; ++i) { + if (v[i] != 0) all_0 = 0; + if (v[i] != 0xffff) all_1 = 0; + } + return all_0 || all_1; +} + +static void load256u128(uint16_t* out, const secp256k1_uint128* v) { + uint64_t lo = secp256k1_u128_to_u64(v), hi = secp256k1_u128_hi_u64(v); + load256two64(out, hi, lo, 0); +} + +static void load256i128(uint16_t* out, const secp256k1_int128* v) { + uint64_t lo; + int64_t hi; + secp256k1_int128 c = *v; + lo = secp256k1_i128_to_u64(&c); + secp256k1_i128_rshift(&c, 64); + hi = secp256k1_i128_to_i64(&c); + load256two64(out, hi, lo, 1); +} + +static void run_int128_test_case(void) { + unsigned char buf[32]; + uint64_t v[4]; + secp256k1_int128 swa, swz; + secp256k1_uint128 uwa, uwz; + uint64_t ub, uc; + int64_t sb, sc; + uint16_t rswa[16], rswz[32], rswr[32], ruwa[16], ruwz[32], ruwr[32]; + uint16_t rub[16], ruc[16], rsb[16], rsc[16]; + int i; + + /* Generate 32-byte random value. */ + testrand256_test(buf); + /* Convert into 4 64-bit integers. */ + for (i = 0; i < 4; ++i) { + uint64_t vi = 0; + int j; + for (j = 0; j < 8; ++j) vi = (vi << 8) + buf[8*i + j]; + v[i] = vi; + } + /* Convert those into a 128-bit value and two 64-bit values (signed and unsigned). */ + secp256k1_u128_load(&uwa, v[1], v[0]); + secp256k1_i128_load(&swa, v[1], v[0]); + ub = v[2]; + sb = v[2]; + uc = v[3]; + sc = v[3]; + /* Load those also into 16-bit array representations. */ + load256u128(ruwa, &uwa); + load256i128(rswa, &swa); + load256u64(rub, ub, 0); + load256u64(rsb, sb, 1); + load256u64(ruc, uc, 0); + load256u64(rsc, sc, 1); + /* test secp256k1_u128_mul */ + mulmod256(ruwr, rub, ruc, NULL); + secp256k1_u128_mul(&uwz, ub, uc); + load256u128(ruwz, &uwz); + CHECK(secp256k1_memcmp_var(ruwr, ruwz, 16) == 0); + /* test secp256k1_u128_accum_mul */ + mulmod256(ruwr, rub, ruc, NULL); + add256(ruwr, ruwr, ruwa); + uwz = uwa; + secp256k1_u128_accum_mul(&uwz, ub, uc); + load256u128(ruwz, &uwz); + CHECK(secp256k1_memcmp_var(ruwr, ruwz, 16) == 0); + /* test secp256k1_u128_accum_u64 */ + add256(ruwr, rub, ruwa); + uwz = uwa; + secp256k1_u128_accum_u64(&uwz, ub); + load256u128(ruwz, &uwz); + CHECK(secp256k1_memcmp_var(ruwr, ruwz, 16) == 0); + /* test secp256k1_u128_rshift */ + rshift256(ruwr, ruwa, uc % 128, 0); + uwz = uwa; + secp256k1_u128_rshift(&uwz, uc % 128); + load256u128(ruwz, &uwz); + CHECK(secp256k1_memcmp_var(ruwr, ruwz, 16) == 0); + /* test secp256k1_u128_to_u64 */ + CHECK(secp256k1_u128_to_u64(&uwa) == v[0]); + /* test secp256k1_u128_hi_u64 */ + CHECK(secp256k1_u128_hi_u64(&uwa) == v[1]); + /* test secp256k1_u128_from_u64 */ + secp256k1_u128_from_u64(&uwz, ub); + load256u128(ruwz, &uwz); + CHECK(secp256k1_memcmp_var(rub, ruwz, 16) == 0); + /* test secp256k1_u128_check_bits */ + { + int uwa_bits = 0; + int j; + for (j = 0; j < 128; ++j) { + if (ruwa[j / 16] >> (j % 16)) uwa_bits = 1 + j; + } + for (j = 0; j < 128; ++j) { + CHECK(secp256k1_u128_check_bits(&uwa, j) == (uwa_bits <= j)); + } + } + /* test secp256k1_i128_mul */ + mulmod256(rswr, rsb, rsc, NULL); + secp256k1_i128_mul(&swz, sb, sc); + load256i128(rswz, &swz); + CHECK(secp256k1_memcmp_var(rswr, rswz, 16) == 0); + /* test secp256k1_i128_accum_mul */ + mulmod256(rswr, rsb, rsc, NULL); + add256(rswr, rswr, rswa); + if (int256is127(rswr)) { + swz = swa; + secp256k1_i128_accum_mul(&swz, sb, sc); + load256i128(rswz, &swz); + CHECK(secp256k1_memcmp_var(rswr, rswz, 16) == 0); + } + /* test secp256k1_i128_det */ + { + uint16_t rsd[16], rse[16], rst[32]; + int64_t sd = v[0], se = v[1]; + load256u64(rsd, sd, 1); + load256u64(rse, se, 1); + mulmod256(rst, rsc, rsd, NULL); + neg256(rst, rst); + mulmod256(rswr, rsb, rse, NULL); + add256(rswr, rswr, rst); + secp256k1_i128_det(&swz, sb, sc, sd, se); + load256i128(rswz, &swz); + CHECK(secp256k1_memcmp_var(rswr, rswz, 16) == 0); + } + /* test secp256k1_i128_rshift */ + rshift256(rswr, rswa, uc % 127, 1); + swz = swa; + secp256k1_i128_rshift(&swz, uc % 127); + load256i128(rswz, &swz); + CHECK(secp256k1_memcmp_var(rswr, rswz, 16) == 0); + /* test secp256k1_i128_to_u64 */ + CHECK(secp256k1_i128_to_u64(&swa) == v[0]); + /* test secp256k1_i128_from_i64 */ + secp256k1_i128_from_i64(&swz, sb); + load256i128(rswz, &swz); + CHECK(secp256k1_memcmp_var(rsb, rswz, 16) == 0); + /* test secp256k1_i128_to_i64 */ + CHECK(secp256k1_i128_to_i64(&swz) == sb); + /* test secp256k1_i128_eq_var */ + { + int expect = (uc & 1); + swz = swa; + if (!expect) { + /* Make sure swz != swa */ + uint64_t v0c = v[0], v1c = v[1]; + if (ub & 64) { + v1c ^= (((uint64_t)1) << (ub & 63)); + } else { + v0c ^= (((uint64_t)1) << (ub & 63)); + } + secp256k1_i128_load(&swz, v1c, v0c); + } + CHECK(secp256k1_i128_eq_var(&swa, &swz) == expect); + } + /* test secp256k1_i128_check_pow2 (sign == 1) */ + { + int expect = (uc & 1); + int pos = ub % 127; + if (expect) { + /* If expect==1, set swz to exactly 2^pos. */ + uint64_t hi = 0; + uint64_t lo = 0; + if (pos >= 64) { + hi = (((uint64_t)1) << (pos & 63)); + } else { + lo = (((uint64_t)1) << (pos & 63)); + } + secp256k1_i128_load(&swz, hi, lo); + } else { + /* If expect==0, set swz = swa, but update expect=1 if swa happens to equal 2^pos. */ + if (pos >= 64) { + if ((v[1] == (((uint64_t)1) << (pos & 63))) && v[0] == 0) expect = 1; + } else { + if ((v[0] == (((uint64_t)1) << (pos & 63))) && v[1] == 0) expect = 1; + } + swz = swa; + } + CHECK(secp256k1_i128_check_pow2(&swz, pos, 1) == expect); + } + /* test secp256k1_i128_check_pow2 (sign == -1) */ + { + int expect = (uc & 1); + int pos = ub % 127; + if (expect) { + /* If expect==1, set swz to exactly -2^pos. */ + uint64_t hi = ~(uint64_t)0; + uint64_t lo = ~(uint64_t)0; + if (pos >= 64) { + hi <<= (pos & 63); + lo = 0; + } else { + lo <<= (pos & 63); + } + secp256k1_i128_load(&swz, hi, lo); + } else { + /* If expect==0, set swz = swa, but update expect=1 if swa happens to equal -2^pos. */ + if (pos >= 64) { + if ((v[1] == ((~(uint64_t)0) << (pos & 63))) && v[0] == 0) expect = 1; + } else { + if ((v[0] == ((~(uint64_t)0) << (pos & 63))) && v[1] == ~(uint64_t)0) expect = 1; + } + swz = swa; + } + CHECK(secp256k1_i128_check_pow2(&swz, pos, -1) == expect); + } +} + +static void run_int128_tests(void) { + { /* secp256k1_u128_accum_mul */ + secp256k1_uint128 res; + + /* Check secp256k1_u128_accum_mul overflow */ + secp256k1_u128_mul(&res, UINT64_MAX, UINT64_MAX); + secp256k1_u128_accum_mul(&res, UINT64_MAX, UINT64_MAX); + CHECK(secp256k1_u128_to_u64(&res) == 2); + CHECK(secp256k1_u128_hi_u64(&res) == 18446744073709551612U); + } + { /* secp256k1_u128_accum_mul */ + secp256k1_int128 res; + + /* Compute INT128_MAX = 2^127 - 1 with secp256k1_i128_accum_mul */ + secp256k1_i128_mul(&res, INT64_MAX, INT64_MAX); + secp256k1_i128_accum_mul(&res, INT64_MAX, INT64_MAX); + CHECK(secp256k1_i128_to_u64(&res) == 2); + secp256k1_i128_accum_mul(&res, 4, 9223372036854775807); + secp256k1_i128_accum_mul(&res, 1, 1); + CHECK(secp256k1_i128_to_u64(&res) == UINT64_MAX); + secp256k1_i128_rshift(&res, 64); + CHECK(secp256k1_i128_to_i64(&res) == INT64_MAX); + + /* Compute INT128_MIN = - 2^127 with secp256k1_i128_accum_mul */ + secp256k1_i128_mul(&res, INT64_MAX, INT64_MIN); + CHECK(secp256k1_i128_to_u64(&res) == (uint64_t)INT64_MIN); + secp256k1_i128_accum_mul(&res, INT64_MAX, INT64_MIN); + CHECK(secp256k1_i128_to_u64(&res) == 0); + secp256k1_i128_accum_mul(&res, 2, INT64_MIN); + CHECK(secp256k1_i128_to_u64(&res) == 0); + secp256k1_i128_rshift(&res, 64); + CHECK(secp256k1_i128_to_i64(&res) == INT64_MIN); + } + { + /* Randomized tests. */ + int i; + for (i = 0; i < 256 * COUNT; ++i) run_int128_test_case(); } } #endif /***** SCALAR TESTS *****/ -void scalar_test(void) { +static void scalar_test(void) { secp256k1_scalar s; secp256k1_scalar s1; secp256k1_scalar s2; -#ifndef USE_NUM_NONE - secp256k1_num snum, s1num, s2num; - secp256k1_num order, half_order; -#endif unsigned char c[32]; /* Set 's' to a random scalar, with value 'snum'. */ - random_scalar_order_test(&s); + testutil_random_scalar_order_test(&s); /* Set 's1' to a random scalar, with value 's1num'. */ - random_scalar_order_test(&s1); + testutil_random_scalar_order_test(&s1); /* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */ - random_scalar_order_test(&s2); + testutil_random_scalar_order_test(&s2); secp256k1_scalar_get_b32(c, &s2); -#ifndef USE_NUM_NONE - secp256k1_scalar_get_num(&snum, &s); - secp256k1_scalar_get_num(&s1num, &s1); - secp256k1_scalar_get_num(&s2num, &s2); - - secp256k1_scalar_order_get_num(&order); - half_order = order; - secp256k1_num_shift(&half_order, 1); -#endif - { int i; /* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */ @@ -657,7 +2034,7 @@ void scalar_test(void) { for (i = 0; i < 256; i += 4) { secp256k1_scalar t; int j; - secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4)); + secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_limb32(&s, 256 - 4 - i, 4)); for (j = 0; j < 4; j++) { secp256k1_scalar_add(&n, &n, &n); } @@ -674,7 +2051,7 @@ void scalar_test(void) { while (i < 256) { secp256k1_scalar t; int j; - int now = secp256k1_rand_int(15) + 1; + int now = testrand_int(15) + 1; if (now + i > 256) { now = 256 - i; } @@ -688,122 +2065,6 @@ void scalar_test(void) { CHECK(secp256k1_scalar_eq(&n, &s)); } -#ifndef USE_NUM_NONE - { - /* Test that adding the scalars together is equal to adding their numbers together modulo the order. */ - secp256k1_num rnum; - secp256k1_num r2num; - secp256k1_scalar r; - secp256k1_num_add(&rnum, &snum, &s2num); - secp256k1_num_mod(&rnum, &order); - secp256k1_scalar_add(&r, &s, &s2); - secp256k1_scalar_get_num(&r2num, &r); - CHECK(secp256k1_num_eq(&rnum, &r2num)); - } - - { - /* Test that multiplying the scalars is equal to multiplying their numbers modulo the order. */ - secp256k1_scalar r; - secp256k1_num r2num; - secp256k1_num rnum; - secp256k1_num_mul(&rnum, &snum, &s2num); - secp256k1_num_mod(&rnum, &order); - secp256k1_scalar_mul(&r, &s, &s2); - secp256k1_scalar_get_num(&r2num, &r); - CHECK(secp256k1_num_eq(&rnum, &r2num)); - /* The result can only be zero if at least one of the factors was zero. */ - CHECK(secp256k1_scalar_is_zero(&r) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_zero(&s2))); - /* The results can only be equal to one of the factors if that factor was zero, or the other factor was one. */ - CHECK(secp256k1_num_eq(&rnum, &snum) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_one(&s2))); - CHECK(secp256k1_num_eq(&rnum, &s2num) == (secp256k1_scalar_is_zero(&s2) || secp256k1_scalar_is_one(&s))); - } - - { - secp256k1_scalar neg; - secp256k1_num negnum; - secp256k1_num negnum2; - /* Check that comparison with zero matches comparison with zero on the number. */ - CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s)); - /* Check that comparison with the half order is equal to testing for high scalar. */ - CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &half_order) > 0)); - secp256k1_scalar_negate(&neg, &s); - secp256k1_num_sub(&negnum, &order, &snum); - secp256k1_num_mod(&negnum, &order); - /* Check that comparison with the half order is equal to testing for high scalar after negation. */ - CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &half_order) > 0)); - /* Negating should change the high property, unless the value was already zero. */ - CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s)); - secp256k1_scalar_get_num(&negnum2, &neg); - /* Negating a scalar should be equal to (order - n) mod order on the number. */ - CHECK(secp256k1_num_eq(&negnum, &negnum2)); - secp256k1_scalar_add(&neg, &neg, &s); - /* Adding a number to its negation should result in zero. */ - CHECK(secp256k1_scalar_is_zero(&neg)); - secp256k1_scalar_negate(&neg, &neg); - /* Negating zero should still result in zero. */ - CHECK(secp256k1_scalar_is_zero(&neg)); - } - - { - /* Test secp256k1_scalar_mul_shift_var. */ - secp256k1_scalar r; - secp256k1_num one; - secp256k1_num rnum; - secp256k1_num rnum2; - unsigned char cone[1] = {0x01}; - unsigned int shift = 256 + secp256k1_rand_int(257); - secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift); - secp256k1_num_mul(&rnum, &s1num, &s2num); - secp256k1_num_shift(&rnum, shift - 1); - secp256k1_num_set_bin(&one, cone, 1); - secp256k1_num_add(&rnum, &rnum, &one); - secp256k1_num_shift(&rnum, 1); - secp256k1_scalar_get_num(&rnum2, &r); - CHECK(secp256k1_num_eq(&rnum, &rnum2)); - } - - { - /* test secp256k1_scalar_shr_int */ - secp256k1_scalar r; - int i; - random_scalar_order_test(&r); - for (i = 0; i < 100; ++i) { - int low; - int shift = 1 + secp256k1_rand_int(15); - int expected = r.d[0] % (1 << shift); - low = secp256k1_scalar_shr_int(&r, shift); - CHECK(expected == low); - } - } -#endif - - { - /* Test that scalar inverses are equal to the inverse of their number modulo the order. */ - if (!secp256k1_scalar_is_zero(&s)) { - secp256k1_scalar inv; -#ifndef USE_NUM_NONE - secp256k1_num invnum; - secp256k1_num invnum2; -#endif - secp256k1_scalar_inverse(&inv, &s); -#ifndef USE_NUM_NONE - secp256k1_num_mod_inverse(&invnum, &snum, &order); - secp256k1_scalar_get_num(&invnum2, &inv); - CHECK(secp256k1_num_eq(&invnum, &invnum2)); -#endif - secp256k1_scalar_mul(&inv, &inv, &s); - /* Multiplying a scalar with its inverse must result in one. */ - CHECK(secp256k1_scalar_is_one(&inv)); - secp256k1_scalar_inverse(&inv, &inv); - /* Inverting one must result in one. */ - CHECK(secp256k1_scalar_is_one(&inv)); -#ifndef USE_NUM_NONE - secp256k1_scalar_get_num(&invnum, &inv); - CHECK(secp256k1_num_is_one(&invnum)); -#endif - } - } - { /* Test commutativity of add. */ secp256k1_scalar r1, r2; @@ -817,7 +2078,7 @@ void scalar_test(void) { secp256k1_scalar b; int i; /* Test add_bit. */ - int bit = secp256k1_rand_bits(8); + int bit = testrand_bits(8); secp256k1_scalar_set_int(&b, 1); CHECK(secp256k1_scalar_is_one(&b)); for (i = 0; i < bit; i++) { @@ -874,72 +2135,117 @@ void scalar_test(void) { CHECK(secp256k1_scalar_eq(&r1, &r2)); } - { - /* Test square. */ - secp256k1_scalar r1, r2; - secp256k1_scalar_sqr(&r1, &s1); - secp256k1_scalar_mul(&r2, &s1, &s1); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - } - { /* Test multiplicative identity. */ - secp256k1_scalar r1, v1; - secp256k1_scalar_set_int(&v1,1); - secp256k1_scalar_mul(&r1, &s1, &v1); + secp256k1_scalar r1; + secp256k1_scalar_mul(&r1, &s1, &secp256k1_scalar_one); CHECK(secp256k1_scalar_eq(&r1, &s1)); } { /* Test additive identity. */ - secp256k1_scalar r1, v0; - secp256k1_scalar_set_int(&v0,0); - secp256k1_scalar_add(&r1, &s1, &v0); + secp256k1_scalar r1; + secp256k1_scalar_add(&r1, &s1, &secp256k1_scalar_zero); CHECK(secp256k1_scalar_eq(&r1, &s1)); } { /* Test zero product property. */ - secp256k1_scalar r1, v0; - secp256k1_scalar_set_int(&v0,0); - secp256k1_scalar_mul(&r1, &s1, &v0); - CHECK(secp256k1_scalar_eq(&r1, &v0)); + secp256k1_scalar r1; + secp256k1_scalar_mul(&r1, &s1, &secp256k1_scalar_zero); + CHECK(secp256k1_scalar_eq(&r1, &secp256k1_scalar_zero)); } + { + /* Test halving. */ + secp256k1_scalar r; + secp256k1_scalar_add(&r, &s, &s); + secp256k1_scalar_half(&r, &r); + CHECK(secp256k1_scalar_eq(&r, &s)); + } } -void run_scalar_tests(void) { +static void run_scalar_set_b32_seckey_tests(void) { + unsigned char b32[32]; + secp256k1_scalar s1; + secp256k1_scalar s2; + + /* Usually set_b32 and set_b32_seckey give the same result */ + testutil_random_scalar_order_b32(b32); + secp256k1_scalar_set_b32(&s1, b32, NULL); + CHECK(secp256k1_scalar_set_b32_seckey(&s2, b32) == 1); + CHECK(secp256k1_scalar_eq(&s1, &s2) == 1); + + memset(b32, 0, sizeof(b32)); + CHECK(secp256k1_scalar_set_b32_seckey(&s2, b32) == 0); + memset(b32, 0xFF, sizeof(b32)); + CHECK(secp256k1_scalar_set_b32_seckey(&s2, b32) == 0); +} + +static void run_scalar_tests(void) { int i; - for (i = 0; i < 128 * count; i++) { + for (i = 0; i < 128 * COUNT; i++) { scalar_test(); } + for (i = 0; i < COUNT; i++) { + run_scalar_set_b32_seckey_tests(); + } + + { + /* Check that the scalar constants secp256k1_scalar_zero and + secp256k1_scalar_one contain the expected values. */ + secp256k1_scalar zero, one; + + CHECK(secp256k1_scalar_is_zero(&secp256k1_scalar_zero)); + secp256k1_scalar_set_int(&zero, 0); + CHECK(secp256k1_scalar_eq(&zero, &secp256k1_scalar_zero)); + + CHECK(secp256k1_scalar_is_one(&secp256k1_scalar_one)); + secp256k1_scalar_set_int(&one, 1); + CHECK(secp256k1_scalar_eq(&one, &secp256k1_scalar_one)); + } { /* (-1)+1 should be zero. */ - secp256k1_scalar s, o; - secp256k1_scalar_set_int(&s, 1); - CHECK(secp256k1_scalar_is_one(&s)); - secp256k1_scalar_negate(&o, &s); - secp256k1_scalar_add(&o, &o, &s); + secp256k1_scalar o; + secp256k1_scalar_negate(&o, &secp256k1_scalar_one); + secp256k1_scalar_add(&o, &o, &secp256k1_scalar_one); CHECK(secp256k1_scalar_is_zero(&o)); secp256k1_scalar_negate(&o, &o); CHECK(secp256k1_scalar_is_zero(&o)); } -#ifndef USE_NUM_NONE { - /* A scalar with value of the curve order should be 0. */ - secp256k1_num order; - secp256k1_scalar zero; - unsigned char bin[32]; - int overflow = 0; - secp256k1_scalar_order_get_num(&order); - secp256k1_num_get_bin(bin, 32, &order); - secp256k1_scalar_set_b32(&zero, bin, &overflow); - CHECK(overflow == 1); - CHECK(secp256k1_scalar_is_zero(&zero)); + /* Test that halving and doubling roundtrips on some fixed values. */ + static const secp256k1_scalar HALF_TESTS[] = { + /* 0 */ + SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0), + /* 1 */ + SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1), + /* -1 */ + SECP256K1_SCALAR_CONST(0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffeul, 0xbaaedce6ul, 0xaf48a03bul, 0xbfd25e8cul, 0xd0364140ul), + /* -2 (largest odd value) */ + SECP256K1_SCALAR_CONST(0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffeul, 0xbaaedce6ul, 0xaf48a03bul, 0xbfd25e8cul, 0xd036413Ful), + /* Half the secp256k1 order */ + SECP256K1_SCALAR_CONST(0x7ffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0x5d576e73ul, 0x57a4501dul, 0xdfe92f46ul, 0x681b20a0ul), + /* Half the secp256k1 order + 1 */ + SECP256K1_SCALAR_CONST(0x7ffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0x5d576e73ul, 0x57a4501dul, 0xdfe92f46ul, 0x681b20a1ul), + /* 2^255 */ + SECP256K1_SCALAR_CONST(0x80000000ul, 0, 0, 0, 0, 0, 0, 0), + /* 2^255 - 1 */ + SECP256K1_SCALAR_CONST(0x7ffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful), + }; + unsigned n; + for (n = 0; n < sizeof(HALF_TESTS) / sizeof(HALF_TESTS[0]); ++n) { + secp256k1_scalar s; + secp256k1_scalar_half(&s, &HALF_TESTS[n]); + secp256k1_scalar_add(&s, &s, &s); + CHECK(secp256k1_scalar_eq(&s, &HALF_TESTS[n])); + secp256k1_scalar_add(&s, &s, &s); + secp256k1_scalar_half(&s, &s); + CHECK(secp256k1_scalar_eq(&s, &HALF_TESTS[n])); + } } -#endif { /* Does check_overflow check catch all ones? */ @@ -960,12 +2266,9 @@ void run_scalar_tests(void) { secp256k1_scalar y; secp256k1_scalar z; secp256k1_scalar zz; - secp256k1_scalar one; secp256k1_scalar r1; secp256k1_scalar r2; -#if defined(USE_SCALAR_INV_NUM) secp256k1_scalar zzv; -#endif int overflow; unsigned char chal[33][2][32] = { {{0xff, 0xff, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, @@ -1499,7 +2802,6 @@ void run_scalar_tests(void) { 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}} }; - secp256k1_scalar_set_int(&one, 1); for (i = 0; i < 33; i++) { secp256k1_scalar_set_b32(&x, chal[i][0], &overflow); CHECK(!overflow); @@ -1510,91 +2812,40 @@ void run_scalar_tests(void) { secp256k1_scalar_set_b32(&r2, res[i][1], &overflow); CHECK(!overflow); secp256k1_scalar_mul(&z, &x, &y); - CHECK(!secp256k1_scalar_check_overflow(&z)); CHECK(secp256k1_scalar_eq(&r1, &z)); if (!secp256k1_scalar_is_zero(&y)) { secp256k1_scalar_inverse(&zz, &y); - CHECK(!secp256k1_scalar_check_overflow(&zz)); -#if defined(USE_SCALAR_INV_NUM) secp256k1_scalar_inverse_var(&zzv, &y); CHECK(secp256k1_scalar_eq(&zzv, &zz)); -#endif secp256k1_scalar_mul(&z, &z, &zz); - CHECK(!secp256k1_scalar_check_overflow(&z)); CHECK(secp256k1_scalar_eq(&x, &z)); secp256k1_scalar_mul(&zz, &zz, &y); - CHECK(!secp256k1_scalar_check_overflow(&zz)); - CHECK(secp256k1_scalar_eq(&one, &zz)); + CHECK(secp256k1_scalar_eq(&secp256k1_scalar_one, &zz)); } secp256k1_scalar_mul(&z, &x, &x); - CHECK(!secp256k1_scalar_check_overflow(&z)); - secp256k1_scalar_sqr(&zz, &x); - CHECK(!secp256k1_scalar_check_overflow(&zz)); - CHECK(secp256k1_scalar_eq(&zz, &z)); - CHECK(secp256k1_scalar_eq(&r2, &zz)); + CHECK(secp256k1_scalar_eq(&r2, &z)); } } } /***** FIELD TESTS *****/ -void random_fe(secp256k1_fe *x) { - unsigned char bin[32]; - do { - secp256k1_rand256(bin); - if (secp256k1_fe_set_b32(x, bin)) { - return; - } - } while(1); -} - -void random_fe_test(secp256k1_fe *x) { - unsigned char bin[32]; - do { - secp256k1_rand256_test(bin); - if (secp256k1_fe_set_b32(x, bin)) { - return; - } - } while(1); -} - -void random_fe_non_zero(secp256k1_fe *nz) { - int tries = 10; - while (--tries >= 0) { - random_fe(nz); - secp256k1_fe_normalize(nz); - if (!secp256k1_fe_is_zero(nz)) { - break; - } - } - /* Infinitesimal probability of spurious failure here */ - CHECK(tries >= 0); -} - -void random_fe_non_square(secp256k1_fe *ns) { +static void random_fe_non_square(secp256k1_fe *ns) { secp256k1_fe r; - random_fe_non_zero(ns); + testutil_random_fe_non_zero(ns); if (secp256k1_fe_sqrt(&r, ns)) { secp256k1_fe_negate(ns, ns, 1); } } -int check_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { +static int fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { secp256k1_fe an = *a; secp256k1_fe bn = *b; secp256k1_fe_normalize_weak(&an); - secp256k1_fe_normalize_var(&bn); - return secp256k1_fe_equal_var(&an, &bn); + return secp256k1_fe_equal(&an, &bn); } -int check_fe_inverse(const secp256k1_fe *a, const secp256k1_fe *ai) { - secp256k1_fe x; - secp256k1_fe one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_fe_mul(&x, a, ai); - return check_fe_equal(&x, &one); -} - -void run_field_convert(void) { +static void run_field_convert(void) { static const unsigned char b32[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, @@ -1613,63 +2864,204 @@ void run_field_convert(void) { unsigned char b322[32]; secp256k1_fe_storage fes2; /* Check conversions to fe. */ - CHECK(secp256k1_fe_set_b32(&fe2, b32)); - CHECK(secp256k1_fe_equal_var(&fe, &fe2)); + CHECK(secp256k1_fe_set_b32_limit(&fe2, b32)); + CHECK(secp256k1_fe_equal(&fe, &fe2)); secp256k1_fe_from_storage(&fe2, &fes); - CHECK(secp256k1_fe_equal_var(&fe, &fe2)); + CHECK(secp256k1_fe_equal(&fe, &fe2)); /* Check conversion from fe. */ secp256k1_fe_get_b32(b322, &fe); - CHECK(memcmp(b322, b32, 32) == 0); + CHECK(secp256k1_memcmp_var(b322, b32, 32) == 0); secp256k1_fe_to_storage(&fes2, &fe); - CHECK(memcmp(&fes2, &fes, sizeof(fes)) == 0); + CHECK(secp256k1_memcmp_var(&fes2, &fes, sizeof(fes)) == 0); } -int fe_memcmp(const secp256k1_fe *a, const secp256k1_fe *b) { - secp256k1_fe t = *b; +static void run_field_be32_overflow(void) { + { + static const unsigned char zero_overflow[32] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F, + }; + static const unsigned char zero[32] = { 0x00 }; + unsigned char out[32]; + secp256k1_fe fe; + CHECK(secp256k1_fe_set_b32_limit(&fe, zero_overflow) == 0); + secp256k1_fe_set_b32_mod(&fe, zero_overflow); + CHECK(secp256k1_fe_normalizes_to_zero(&fe) == 1); + secp256k1_fe_normalize(&fe); + CHECK(secp256k1_fe_is_zero(&fe) == 1); + secp256k1_fe_get_b32(out, &fe); + CHECK(secp256k1_memcmp_var(out, zero, 32) == 0); + } + { + static const unsigned char one_overflow[32] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30, + }; + static const unsigned char one[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + unsigned char out[32]; + secp256k1_fe fe; + CHECK(secp256k1_fe_set_b32_limit(&fe, one_overflow) == 0); + secp256k1_fe_set_b32_mod(&fe, one_overflow); + secp256k1_fe_normalize(&fe); + CHECK(secp256k1_fe_cmp_var(&fe, &secp256k1_fe_one) == 0); + secp256k1_fe_get_b32(out, &fe); + CHECK(secp256k1_memcmp_var(out, one, 32) == 0); + } + { + static const unsigned char ff_overflow[32] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + static const unsigned char ff[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xD0, + }; + unsigned char out[32]; + secp256k1_fe fe; + const secp256k1_fe fe_ff = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0x01, 0x000003d0); + CHECK(secp256k1_fe_set_b32_limit(&fe, ff_overflow) == 0); + secp256k1_fe_set_b32_mod(&fe, ff_overflow); + secp256k1_fe_normalize(&fe); + CHECK(secp256k1_fe_cmp_var(&fe, &fe_ff) == 0); + secp256k1_fe_get_b32(out, &fe); + CHECK(secp256k1_memcmp_var(out, ff, 32) == 0); + } +} + +/* Returns true if two field elements have the same representation. */ +static int fe_identical(const secp256k1_fe *a, const secp256k1_fe *b) { + int ret = 1; + /* Compare the struct member that holds the limbs. */ + ret &= (secp256k1_memcmp_var(a->n, b->n, sizeof(a->n)) == 0); + return ret; +} + +static void run_field_half(void) { + secp256k1_fe t, u; + int m; + + /* Check magnitude 0 input */ + secp256k1_fe_get_bounds(&t, 0); + secp256k1_fe_half(&t); #ifdef VERIFY - t.magnitude = a->magnitude; - t.normalized = a->normalized; + CHECK(t.magnitude == 1); + CHECK(t.normalized == 0); #endif - return memcmp(a, &t, sizeof(secp256k1_fe)); + CHECK(secp256k1_fe_normalizes_to_zero(&t)); + + /* Check non-zero magnitudes in the supported range */ + for (m = 1; m < 32; m++) { + /* Check max-value input */ + secp256k1_fe_get_bounds(&t, m); + + u = t; + secp256k1_fe_half(&u); +#ifdef VERIFY + CHECK(u.magnitude == (m >> 1) + 1); + CHECK(u.normalized == 0); +#endif + secp256k1_fe_normalize_weak(&u); + secp256k1_fe_add(&u, &u); + CHECK(fe_equal(&t, &u)); + + /* Check worst-case input: ensure the LSB is 1 so that P will be added, + * which will also cause all carries to be 1, since all limbs that can + * generate a carry are initially even and all limbs of P are odd in + * every existing field implementation. */ + secp256k1_fe_get_bounds(&t, m); + CHECK(t.n[0] > 0); + CHECK((t.n[0] & 1) == 0); + --t.n[0]; + + u = t; + secp256k1_fe_half(&u); +#ifdef VERIFY + CHECK(u.magnitude == (m >> 1) + 1); + CHECK(u.normalized == 0); +#endif + secp256k1_fe_normalize_weak(&u); + secp256k1_fe_add(&u, &u); + CHECK(fe_equal(&t, &u)); + } } -void run_field_misc(void) { +static void run_field_misc(void) { secp256k1_fe x; secp256k1_fe y; secp256k1_fe z; secp256k1_fe q; + int v; secp256k1_fe fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5); int i, j; - for (i = 0; i < 5*count; i++) { + for (i = 0; i < 1000 * COUNT; i++) { secp256k1_fe_storage xs, ys, zs; - random_fe(&x); - random_fe_non_zero(&y); + if (i & 1) { + testutil_random_fe(&x); + } else { + testutil_random_fe_test(&x); + } + testutil_random_fe_non_zero(&y); + v = testrand_bits(15); + /* Test that fe_add_int is equivalent to fe_set_int + fe_add. */ + secp256k1_fe_set_int(&q, v); /* q = v */ + z = x; /* z = x */ + secp256k1_fe_add(&z, &q); /* z = x+v */ + q = x; /* q = x */ + secp256k1_fe_add_int(&q, v); /* q = x+v */ + CHECK(fe_equal(&q, &z)); /* Test the fe equality and comparison operations. */ CHECK(secp256k1_fe_cmp_var(&x, &x) == 0); - CHECK(secp256k1_fe_equal_var(&x, &x)); + CHECK(secp256k1_fe_equal(&x, &x)); z = x; secp256k1_fe_add(&z,&y); /* Test fe conditional move; z is not normalized here. */ q = x; secp256k1_fe_cmov(&x, &z, 0); - VERIFY_CHECK(!x.normalized && x.magnitude == z.magnitude); +#ifdef VERIFY + CHECK(!x.normalized); + CHECK((x.magnitude == q.magnitude) || (x.magnitude == z.magnitude)); + CHECK((x.magnitude >= q.magnitude) && (x.magnitude >= z.magnitude)); +#endif + x = q; secp256k1_fe_cmov(&x, &x, 1); - CHECK(fe_memcmp(&x, &z) != 0); - CHECK(fe_memcmp(&x, &q) == 0); + CHECK(!fe_identical(&x, &z)); + CHECK(fe_identical(&x, &q)); secp256k1_fe_cmov(&q, &z, 1); - VERIFY_CHECK(!q.normalized && q.magnitude == z.magnitude); - CHECK(fe_memcmp(&q, &z) == 0); +#ifdef VERIFY + CHECK(!q.normalized); + CHECK((q.magnitude == x.magnitude) || (q.magnitude == z.magnitude)); + CHECK((q.magnitude >= x.magnitude) && (q.magnitude >= z.magnitude)); +#endif + CHECK(fe_identical(&q, &z)); + q = z; secp256k1_fe_normalize_var(&x); secp256k1_fe_normalize_var(&z); - CHECK(!secp256k1_fe_equal_var(&x, &z)); + CHECK(!secp256k1_fe_equal(&x, &z)); secp256k1_fe_normalize_var(&q); secp256k1_fe_cmov(&q, &z, (i&1)); - VERIFY_CHECK(q.normalized && q.magnitude == 1); +#ifdef VERIFY + CHECK(q.normalized && q.magnitude == 1); +#endif for (j = 0; j < 6; j++) { - secp256k1_fe_negate(&z, &z, j+1); + secp256k1_fe_negate_unchecked(&z, &z, j+1); secp256k1_fe_normalize_var(&q); secp256k1_fe_cmov(&q, &z, (j&1)); - VERIFY_CHECK(!q.normalized && q.magnitude == (j+2)); +#ifdef VERIFY + CHECK(!q.normalized && q.magnitude == z.magnitude); +#endif } secp256k1_fe_normalize_var(&z); /* Test storage conversion and conditional moves. */ @@ -1678,9 +3070,9 @@ void run_field_misc(void) { secp256k1_fe_to_storage(&zs, &z); secp256k1_fe_storage_cmov(&zs, &xs, 0); secp256k1_fe_storage_cmov(&zs, &zs, 1); - CHECK(memcmp(&xs, &zs, sizeof(xs)) != 0); + CHECK(secp256k1_memcmp_var(&xs, &zs, sizeof(xs)) != 0); secp256k1_fe_storage_cmov(&ys, &xs, 1); - CHECK(memcmp(&xs, &ys, sizeof(xs)) == 0); + CHECK(secp256k1_memcmp_var(&xs, &ys, sizeof(xs)) == 0); secp256k1_fe_from_storage(&x, &xs); secp256k1_fe_from_storage(&y, &ys); secp256k1_fe_from_storage(&z, &zs); @@ -1689,85 +3081,124 @@ void run_field_misc(void) { secp256k1_fe_add(&y, &x); z = x; secp256k1_fe_mul_int(&z, 3); - CHECK(check_fe_equal(&y, &z)); + CHECK(fe_equal(&y, &z)); secp256k1_fe_add(&y, &x); secp256k1_fe_add(&z, &x); - CHECK(check_fe_equal(&z, &y)); + CHECK(fe_equal(&z, &y)); z = x; secp256k1_fe_mul_int(&z, 5); secp256k1_fe_mul(&q, &x, &fe5); - CHECK(check_fe_equal(&z, &q)); + CHECK(fe_equal(&z, &q)); secp256k1_fe_negate(&x, &x, 1); secp256k1_fe_add(&z, &x); secp256k1_fe_add(&q, &x); - CHECK(check_fe_equal(&y, &z)); - CHECK(check_fe_equal(&q, &y)); + CHECK(fe_equal(&y, &z)); + CHECK(fe_equal(&q, &y)); + /* Check secp256k1_fe_half. */ + z = x; + secp256k1_fe_half(&z); + secp256k1_fe_add(&z, &z); + CHECK(fe_equal(&x, &z)); + secp256k1_fe_add(&z, &z); + secp256k1_fe_half(&z); + CHECK(fe_equal(&x, &z)); } } -void run_field_inv(void) { - secp256k1_fe x, xi, xii; +static void test_fe_mul(const secp256k1_fe* a, const secp256k1_fe* b, int use_sqr) +{ + secp256k1_fe c, an, bn; + /* Variables in BE 32-byte format. */ + unsigned char a32[32], b32[32], c32[32]; + /* Variables in LE 16x uint16_t format. */ + uint16_t a16[16], b16[16], c16[16]; + /* Field modulus in LE 16x uint16_t format. */ + static const uint16_t m16[16] = { + 0xfc2f, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + }; + uint16_t t16[32]; int i; - for (i = 0; i < 10*count; i++) { - random_fe_non_zero(&x); - secp256k1_fe_inv(&xi, &x); - CHECK(check_fe_inverse(&x, &xi)); - secp256k1_fe_inv(&xii, &xi); - CHECK(check_fe_equal(&x, &xii)); + + /* Compute C = A * B in fe format. */ + c = *a; + if (use_sqr) { + secp256k1_fe_sqr(&c, &c); + } else { + secp256k1_fe_mul(&c, &c, b); } + + /* Convert A, B, C into LE 16x uint16_t format. */ + an = *a; + bn = *b; + secp256k1_fe_normalize_var(&c); + secp256k1_fe_normalize_var(&an); + secp256k1_fe_normalize_var(&bn); + secp256k1_fe_get_b32(a32, &an); + secp256k1_fe_get_b32(b32, &bn); + secp256k1_fe_get_b32(c32, &c); + for (i = 0; i < 16; ++i) { + a16[i] = a32[31 - 2*i] + ((uint16_t)a32[30 - 2*i] << 8); + b16[i] = b32[31 - 2*i] + ((uint16_t)b32[30 - 2*i] << 8); + c16[i] = c32[31 - 2*i] + ((uint16_t)c32[30 - 2*i] << 8); + } + /* Compute T = A * B in LE 16x uint16_t format. */ + mulmod256(t16, a16, b16, m16); + /* Compare */ + CHECK(secp256k1_memcmp_var(t16, c16, 32) == 0); } -void run_field_inv_var(void) { - secp256k1_fe x, xi, xii; +static void run_fe_mul(void) { int i; - for (i = 0; i < 10*count; i++) { - random_fe_non_zero(&x); - secp256k1_fe_inv_var(&xi, &x); - CHECK(check_fe_inverse(&x, &xi)); - secp256k1_fe_inv_var(&xii, &xi); - CHECK(check_fe_equal(&x, &xii)); + for (i = 0; i < 100 * COUNT; ++i) { + secp256k1_fe a, b, c, d; + testutil_random_fe(&a); + testutil_random_fe_magnitude(&a, 8); + testutil_random_fe(&b); + testutil_random_fe_magnitude(&b, 8); + testutil_random_fe_test(&c); + testutil_random_fe_magnitude(&c, 8); + testutil_random_fe_test(&d); + testutil_random_fe_magnitude(&d, 8); + test_fe_mul(&a, &a, 1); + test_fe_mul(&c, &c, 1); + test_fe_mul(&a, &b, 0); + test_fe_mul(&a, &c, 0); + test_fe_mul(&c, &b, 0); + test_fe_mul(&c, &d, 0); } } -void run_field_inv_all_var(void) { - secp256k1_fe x[16], xi[16], xii[16]; +static void run_sqr(void) { int i; - /* Check it's safe to call for 0 elements */ - secp256k1_fe_inv_all_var(xi, x, 0); - for (i = 0; i < count; i++) { - size_t j; - size_t len = secp256k1_rand_int(15) + 1; - for (j = 0; j < len; j++) { - random_fe_non_zero(&x[j]); - } - secp256k1_fe_inv_all_var(xi, x, len); - for (j = 0; j < len; j++) { - CHECK(check_fe_inverse(&x[j], &xi[j])); - } - secp256k1_fe_inv_all_var(xii, xi, len); - for (j = 0; j < len; j++) { - CHECK(check_fe_equal(&x[j], &xii[j])); - } + secp256k1_fe x, y, lhs, rhs, tmp; + + secp256k1_fe_set_int(&x, 1); + secp256k1_fe_negate(&x, &x, 1); + + for (i = 1; i <= 512; ++i) { + secp256k1_fe_mul_int(&x, 2); + secp256k1_fe_normalize(&x); + + /* Check that (x+y)*(x-y) = x^2 - y*2 for some random values y */ + testutil_random_fe_test(&y); + + lhs = x; + secp256k1_fe_add(&lhs, &y); /* lhs = x+y */ + secp256k1_fe_negate(&tmp, &y, 1); /* tmp = -y */ + secp256k1_fe_add(&tmp, &x); /* tmp = x-y */ + secp256k1_fe_mul(&lhs, &lhs, &tmp); /* lhs = (x+y)*(x-y) */ + + secp256k1_fe_sqr(&rhs, &x); /* rhs = x^2 */ + secp256k1_fe_sqr(&tmp, &y); /* tmp = y^2 */ + secp256k1_fe_negate(&tmp, &tmp, 1); /* tmp = -y^2 */ + secp256k1_fe_add(&rhs, &tmp); /* rhs = x^2 - y^2 */ + + CHECK(fe_equal(&lhs, &rhs)); } } -void run_sqr(void) { - secp256k1_fe x, s; - - { - int i; - secp256k1_fe_set_int(&x, 1); - secp256k1_fe_negate(&x, &x, 1); - - for (i = 1; i <= 512; ++i) { - secp256k1_fe_mul_int(&x, 2); - secp256k1_fe_normalize(&x); - secp256k1_fe_sqr(&s, &x); - } - } -} - -void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) { +static void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) { secp256k1_fe r1, r2; int v = secp256k1_fe_sqrt(&r1, a); CHECK((v == 0) == (k == NULL)); @@ -1781,7 +3212,7 @@ void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) { } } -void run_sqrt(void) { +static void run_sqrt(void) { secp256k1_fe ns, x, s, t; int i; @@ -1803,11 +3234,13 @@ void run_sqrt(void) { for (i = 0; i < 10; i++) { int j; random_fe_non_square(&ns); - for (j = 0; j < count; j++) { - random_fe(&x); + for (j = 0; j < COUNT; j++) { + testutil_random_fe(&x); secp256k1_fe_sqr(&s, &x); + CHECK(secp256k1_fe_is_square_var(&s)); test_sqrt(&s, &x); secp256k1_fe_negate(&t, &s, 1); + CHECK(!secp256k1_fe_is_square_var(&t)); test_sqrt(&t, NULL); secp256k1_fe_mul(&t, &s, &ns); test_sqrt(&t, NULL); @@ -1815,19 +3248,394 @@ void run_sqrt(void) { } } -/***** GROUP TESTS *****/ +/***** FIELD/SCALAR INVERSE TESTS *****/ -void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { - CHECK(a->infinity == b->infinity); - if (a->infinity) { +static const secp256k1_scalar scalar_minus_one = SECP256K1_SCALAR_CONST( + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, + 0xBAAEDCE6, 0xAF48A03B, 0xBFD25E8C, 0xD0364140 +); + +static const secp256k1_fe fe_minus_one = SECP256K1_FE_CONST( + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFC2E +); + +/* These tests test the following identities: + * + * for x==0: 1/x == 0 + * for x!=0: x*(1/x) == 1 + * for x!=0 and x!=1: 1/(1/x - 1) + 1 == -1/(x-1) + */ + +static void test_inverse_scalar(secp256k1_scalar* out, const secp256k1_scalar* x, int var) +{ + secp256k1_scalar l, r, t; + + (var ? secp256k1_scalar_inverse_var : secp256k1_scalar_inverse)(&l, x); /* l = 1/x */ + if (out) *out = l; + if (secp256k1_scalar_is_zero(x)) { + CHECK(secp256k1_scalar_is_zero(&l)); return; } - CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); - CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); + secp256k1_scalar_mul(&t, x, &l); /* t = x*(1/x) */ + CHECK(secp256k1_scalar_is_one(&t)); /* x*(1/x) == 1 */ + secp256k1_scalar_add(&r, x, &scalar_minus_one); /* r = x-1 */ + if (secp256k1_scalar_is_zero(&r)) return; + (var ? secp256k1_scalar_inverse_var : secp256k1_scalar_inverse)(&r, &r); /* r = 1/(x-1) */ + secp256k1_scalar_add(&l, &scalar_minus_one, &l); /* l = 1/x-1 */ + (var ? secp256k1_scalar_inverse_var : secp256k1_scalar_inverse)(&l, &l); /* l = 1/(1/x-1) */ + secp256k1_scalar_add(&l, &l, &secp256k1_scalar_one); /* l = 1/(1/x-1)+1 */ + secp256k1_scalar_add(&l, &r, &l); /* l = 1/(1/x-1)+1 + 1/(x-1) */ + CHECK(secp256k1_scalar_is_zero(&l)); /* l == 0 */ } +static void test_inverse_field(secp256k1_fe* out, const secp256k1_fe* x, int var) +{ + secp256k1_fe l, r, t; + + (var ? secp256k1_fe_inv_var : secp256k1_fe_inv)(&l, x) ; /* l = 1/x */ + if (out) *out = l; + t = *x; /* t = x */ + if (secp256k1_fe_normalizes_to_zero_var(&t)) { + CHECK(secp256k1_fe_normalizes_to_zero(&l)); + return; + } + secp256k1_fe_mul(&t, x, &l); /* t = x*(1/x) */ + secp256k1_fe_add(&t, &fe_minus_one); /* t = x*(1/x)-1 */ + CHECK(secp256k1_fe_normalizes_to_zero(&t)); /* x*(1/x)-1 == 0 */ + r = *x; /* r = x */ + secp256k1_fe_add(&r, &fe_minus_one); /* r = x-1 */ + if (secp256k1_fe_normalizes_to_zero_var(&r)) return; + (var ? secp256k1_fe_inv_var : secp256k1_fe_inv)(&r, &r); /* r = 1/(x-1) */ + secp256k1_fe_add(&l, &fe_minus_one); /* l = 1/x-1 */ + (var ? secp256k1_fe_inv_var : secp256k1_fe_inv)(&l, &l); /* l = 1/(1/x-1) */ + secp256k1_fe_add_int(&l, 1); /* l = 1/(1/x-1)+1 */ + secp256k1_fe_add(&l, &r); /* l = 1/(1/x-1)+1 + 1/(x-1) */ + CHECK(secp256k1_fe_normalizes_to_zero_var(&l)); /* l == 0 */ +} + +static void run_inverse_tests(void) +{ + /* Fixed test cases for field inverses: pairs of (x, 1/x) mod p. */ + static const secp256k1_fe fe_cases[][2] = { + /* 0 */ + {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), + SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}, + /* 1 */ + {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), + SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1)}, + /* -1 */ + {SECP256K1_FE_CONST(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0xfffffc2e), + SECP256K1_FE_CONST(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0xfffffc2e)}, + /* 2 */ + {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2), + SECP256K1_FE_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7ffffe18)}, + /* 2**128 */ + {SECP256K1_FE_CONST(0, 0, 0, 1, 0, 0, 0, 0), + SECP256K1_FE_CONST(0xbcb223fe, 0xdc24a059, 0xd838091d, 0xd2253530, 0xffffffff, 0xffffffff, 0xffffffff, 0x434dd931)}, + /* Input known to need 637 divsteps */ + {SECP256K1_FE_CONST(0xe34e9c95, 0x6bee8a84, 0x0dcb632a, 0xdb8a1320, 0x66885408, 0x06f3f996, 0x7c11ca84, 0x19199ec3), + SECP256K1_FE_CONST(0xbd2cbd8f, 0x1c536828, 0x9bccda44, 0x2582ac0c, 0x870152b0, 0x8a3f09fb, 0x1aaadf92, 0x19b618e5)}, + /* Input known to need 567 divsteps starting with delta=1/2. */ + {SECP256K1_FE_CONST(0xf6bc3ba3, 0x636451c4, 0x3e46357d, 0x2c21d619, 0x0988e234, 0x15985661, 0x6672982b, 0xa7549bfc), + SECP256K1_FE_CONST(0xb024fdc7, 0x5547451e, 0x426c585f, 0xbd481425, 0x73df6b75, 0xeef6d9d0, 0x389d87d4, 0xfbb440ba)}, + /* Input known to need 566 divsteps starting with delta=1/2. */ + {SECP256K1_FE_CONST(0xb595d81b, 0x2e3c1e2f, 0x482dbc65, 0xe4865af7, 0x9a0a50aa, 0x29f9e618, 0x6f87d7a5, 0x8d1063ae), + SECP256K1_FE_CONST(0xc983337c, 0x5d5c74e1, 0x49918330, 0x0b53afb5, 0xa0428a0b, 0xce6eef86, 0x059bd8ef, 0xe5b908de)}, + /* Set of 10 inputs accessing all 128 entries in the modinv32 divsteps_var table */ + {SECP256K1_FE_CONST(0x00000000, 0x00000000, 0xe0ff1f80, 0x1f000000, 0x00000000, 0x00000000, 0xfeff0100, 0x00000000), + SECP256K1_FE_CONST(0x9faf9316, 0x77e5049d, 0x0b5e7a1b, 0xef70b893, 0x18c9e30c, 0x045e7fd7, 0x29eddf8c, 0xd62e9e3d)}, + {SECP256K1_FE_CONST(0x621a538d, 0x511b2780, 0x35688252, 0x53f889a4, 0x6317c3ac, 0x32ba0a46, 0x6277c0d1, 0xccd31192), + SECP256K1_FE_CONST(0x38513b0c, 0x5eba856f, 0xe29e882e, 0x9b394d8c, 0x34bda011, 0xeaa66943, 0x6a841a4c, 0x6ae8bcff)}, + {SECP256K1_FE_CONST(0x00000200, 0xf0ffff1f, 0x00000000, 0x0000e0ff, 0xffffffff, 0xfffcffff, 0xffffffff, 0xffff0100), + SECP256K1_FE_CONST(0x5da42a52, 0x3640de9e, 0x13e64343, 0x0c7591b7, 0x6c1e3519, 0xf048c5b6, 0x0484217c, 0xedbf8b2f)}, + {SECP256K1_FE_CONST(0xd1343ef9, 0x4b952621, 0x7c52a2ee, 0x4ea1281b, 0x4ab46410, 0x9f26998d, 0xa686a8ff, 0x9f2103e8), + SECP256K1_FE_CONST(0x84044385, 0x9a4619bf, 0x74e35b6d, 0xa47e0c46, 0x6b7fb47d, 0x9ffab128, 0xb0775aa3, 0xcb318bd1)}, + {SECP256K1_FE_CONST(0xb27235d2, 0xc56a52be, 0x210db37a, 0xd50d23a4, 0xbe621bdd, 0x5df22c6a, 0xe926ba62, 0xd2e4e440), + SECP256K1_FE_CONST(0x67a26e54, 0x483a9d3c, 0xa568469e, 0xd258ab3d, 0xb9ec9981, 0xdca9b1bd, 0x8d2775fe, 0x53ae429b)}, + {SECP256K1_FE_CONST(0x00000000, 0x00000000, 0x00e0ffff, 0xffffff83, 0xffffffff, 0x3f00f00f, 0x000000e0, 0xffffffff), + SECP256K1_FE_CONST(0x310e10f8, 0x23bbfab0, 0xac94907d, 0x076c9a45, 0x8d357d7f, 0xc763bcee, 0x00d0e615, 0x5a6acef6)}, + {SECP256K1_FE_CONST(0xfeff0300, 0x001c0000, 0xf80700c0, 0x0ff0ffff, 0xffffffff, 0x0fffffff, 0xffff0100, 0x7f0000fe), + SECP256K1_FE_CONST(0x28e2fdb4, 0x0709168b, 0x86f598b0, 0x3453a370, 0x530cf21f, 0x32f978d5, 0x1d527a71, 0x59269b0c)}, + {SECP256K1_FE_CONST(0xc2591afa, 0x7bb98ef7, 0x090bb273, 0x85c14f87, 0xbb0b28e0, 0x54d3c453, 0x85c66753, 0xd5574d2f), + SECP256K1_FE_CONST(0xfdca70a2, 0x70ce627c, 0x95e66fae, 0x848a6dbb, 0x07ffb15c, 0x5f63a058, 0xba4140ed, 0x6113b503)}, + {SECP256K1_FE_CONST(0xf5475db3, 0xedc7b5a3, 0x411c047e, 0xeaeb452f, 0xc625828e, 0x1cf5ad27, 0x8eec1060, 0xc7d3e690), + SECP256K1_FE_CONST(0x5eb756c0, 0xf963f4b9, 0xdc6a215e, 0xec8cc2d8, 0x2e9dec01, 0xde5eb88d, 0x6aba7164, 0xaecb2c5a)}, + {SECP256K1_FE_CONST(0x00000000, 0x00f8ffff, 0xffffffff, 0x01000000, 0xe0ff1f00, 0x00000000, 0xffffff7f, 0x00000000), + SECP256K1_FE_CONST(0xe0d2e3d8, 0x49b6157d, 0xe54e88c2, 0x1a7f02ca, 0x7dd28167, 0xf1125d81, 0x7bfa444e, 0xbe110037)}, + /* Selection of randomly generated inputs that reach high/low d/e values in various configurations. */ + {SECP256K1_FE_CONST(0x13cc08a4, 0xd8c41f0f, 0x179c3e67, 0x54c46c67, 0xc4109221, 0x09ab3b13, 0xe24d9be1, 0xffffe950), + SECP256K1_FE_CONST(0xb80c8006, 0xd16abaa7, 0xcabd71e5, 0xcf6714f4, 0x966dd3d0, 0x64767a2d, 0xe92c4441, 0x51008cd1)}, + {SECP256K1_FE_CONST(0xaa6db990, 0x95efbca1, 0x3cc6ff71, 0x0602e24a, 0xf49ff938, 0x99fffc16, 0x46f40993, 0xc6e72057), + SECP256K1_FE_CONST(0xd5d3dd69, 0xb0c195e5, 0x285f1d49, 0xe639e48c, 0x9223f8a9, 0xca1d731d, 0x9ca482f9, 0xa5b93e06)}, + {SECP256K1_FE_CONST(0x1c680eac, 0xaeabffd8, 0x9bdc4aee, 0x1781e3de, 0xa3b08108, 0x0015f2e0, 0x94449e1b, 0x2f67a058), + SECP256K1_FE_CONST(0x7f083f8d, 0x31254f29, 0x6510f475, 0x245c373d, 0xc5622590, 0x4b323393, 0x32ed1719, 0xc127444b)}, + {SECP256K1_FE_CONST(0x147d44b3, 0x012d83f8, 0xc160d386, 0x1a44a870, 0x9ba6be96, 0x8b962707, 0x267cbc1a, 0xb65b2f0a), + SECP256K1_FE_CONST(0x555554ff, 0x170aef1e, 0x50a43002, 0xe51fbd36, 0xafadb458, 0x7a8aded1, 0x0ca6cd33, 0x6ed9087c)}, + {SECP256K1_FE_CONST(0x12423796, 0x22f0fe61, 0xf9ca017c, 0x5384d107, 0xa1fbf3b2, 0x3b018013, 0x916a3c37, 0x4000b98c), + SECP256K1_FE_CONST(0x20257700, 0x08668f94, 0x1177e306, 0x136c01f5, 0x8ed1fbd2, 0x95ec4589, 0xae38edb9, 0xfd19b6d7)}, + {SECP256K1_FE_CONST(0xdcf2d030, 0x9ab42cb4, 0x93ffa181, 0xdcd23619, 0x39699b52, 0x08909a20, 0xb5a17695, 0x3a9dcf21), + SECP256K1_FE_CONST(0x1f701dea, 0xe211fb1f, 0x4f37180d, 0x63a0f51c, 0x29fe1e40, 0xa40b6142, 0x2e7b12eb, 0x982b06b6)}, + {SECP256K1_FE_CONST(0x79a851f6, 0xa6314ed3, 0xb35a55e6, 0xca1c7d7f, 0xe32369ea, 0xf902432e, 0x375308c5, 0xdfd5b600), + SECP256K1_FE_CONST(0xcaae00c5, 0xe6b43851, 0x9dabb737, 0x38cba42c, 0xa02c8549, 0x7895dcbf, 0xbd183d71, 0xafe4476a)}, + {SECP256K1_FE_CONST(0xede78fdd, 0xcfc92bf1, 0x4fec6c6c, 0xdb8d37e2, 0xfb66bc7b, 0x28701870, 0x7fa27c9a, 0x307196ec), + SECP256K1_FE_CONST(0x68193a6c, 0x9a8b87a7, 0x2a760c64, 0x13e473f6, 0x23ae7bed, 0x1de05422, 0x88865427, 0xa3418265)}, + {SECP256K1_FE_CONST(0xa40b2079, 0xb8f88e89, 0xa7617997, 0x89baf5ae, 0x174df343, 0x75138eae, 0x2711595d, 0x3fc3e66c), + SECP256K1_FE_CONST(0x9f99c6a5, 0x6d685267, 0xd4b87c37, 0x9d9c4576, 0x358c692b, 0x6bbae0ed, 0x3389c93d, 0x7fdd2655)}, + {SECP256K1_FE_CONST(0x7c74c6b6, 0xe98d9151, 0x72645cf1, 0x7f06e321, 0xcefee074, 0x15b2113a, 0x10a9be07, 0x08a45696), + SECP256K1_FE_CONST(0x8c919a88, 0x898bc1e0, 0x77f26f97, 0x12e655b7, 0x9ba0ac40, 0xe15bb19e, 0x8364cc3b, 0xe227a8ee)}, + {SECP256K1_FE_CONST(0x109ba1ce, 0xdafa6d4a, 0xa1cec2b2, 0xeb1069f4, 0xb7a79e5b, 0xec6eb99b, 0xaec5f643, 0xee0e723e), + SECP256K1_FE_CONST(0x93d13eb8, 0x4bb0bcf9, 0xe64f5a71, 0xdbe9f359, 0x7191401c, 0x6f057a4a, 0xa407fe1b, 0x7ecb65cc)}, + {SECP256K1_FE_CONST(0x3db076cd, 0xec74a5c9, 0xf61dd138, 0x90e23e06, 0xeeedd2d0, 0x74cbc4e0, 0x3dbe1e91, 0xded36a78), + SECP256K1_FE_CONST(0x3f07f966, 0x8e2a1e09, 0x706c71df, 0x02b5e9d5, 0xcb92ddbf, 0xcdd53010, 0x16545564, 0xe660b107)}, + {SECP256K1_FE_CONST(0xe31c73ed, 0xb4c4b82c, 0x02ae35f7, 0x4cdec153, 0x98b522fd, 0xf7d2460c, 0x6bf7c0f8, 0x4cf67b0d), + SECP256K1_FE_CONST(0x4b8f1faf, 0x94e8b070, 0x19af0ff6, 0xa319cd31, 0xdf0a7ffb, 0xefaba629, 0x59c50666, 0x1fe5b843)}, + {SECP256K1_FE_CONST(0x4c8b0e6e, 0x83392ab6, 0xc0e3e9f1, 0xbbd85497, 0x16698897, 0xf552d50d, 0x79652ddb, 0x12f99870), + SECP256K1_FE_CONST(0x56d5101f, 0xd23b7949, 0x17dc38d6, 0xf24022ef, 0xcf18e70a, 0x5cc34424, 0x438544c3, 0x62da4bca)}, + {SECP256K1_FE_CONST(0xb0e040e2, 0x40cc35da, 0x7dd5c611, 0x7fccb178, 0x28888137, 0xbc930358, 0xea2cbc90, 0x775417dc), + SECP256K1_FE_CONST(0xca37f0d4, 0x016dd7c8, 0xab3ae576, 0x96e08d69, 0x68ed9155, 0xa9b44270, 0x900ae35d, 0x7c7800cd)}, + {SECP256K1_FE_CONST(0x8a32ea49, 0x7fbb0bae, 0x69724a9d, 0x8e2105b2, 0xbdf69178, 0x862577ef, 0x35055590, 0x667ddaef), + SECP256K1_FE_CONST(0xd02d7ead, 0xc5e190f0, 0x559c9d72, 0xdaef1ffc, 0x64f9f425, 0xf43645ea, 0x7341e08d, 0x11768e96)}, + {SECP256K1_FE_CONST(0xa3592d98, 0x9abe289d, 0x579ebea6, 0xbb0857a8, 0xe242ab73, 0x85f9a2ce, 0xb6998f0f, 0xbfffbfc6), + SECP256K1_FE_CONST(0x093c1533, 0x32032efa, 0x6aa46070, 0x0039599e, 0x589c35f4, 0xff525430, 0x7fe3777a, 0x44b43ddc)}, + {SECP256K1_FE_CONST(0x647178a3, 0x229e607b, 0xcc98521a, 0xcce3fdd9, 0x1e1bc9c9, 0x97fb7c6a, 0x61b961e0, 0x99b10709), + SECP256K1_FE_CONST(0x98217c13, 0xd51ddf78, 0x96310e77, 0xdaebd908, 0x602ca683, 0xcb46d07a, 0xa1fcf17e, 0xc8e2feb3)}, + {SECP256K1_FE_CONST(0x7334627c, 0x73f98968, 0x99464b4b, 0xf5964958, 0x1b95870d, 0xc658227e, 0x5e3235d8, 0xdcab5787), + SECP256K1_FE_CONST(0x000006fd, 0xc7e9dd94, 0x40ae367a, 0xe51d495c, 0x07603b9b, 0x2d088418, 0x6cc5c74c, 0x98514307)}, + {SECP256K1_FE_CONST(0x82e83876, 0x96c28938, 0xa50dd1c5, 0x605c3ad1, 0xc048637d, 0x7a50825f, 0x335ed01a, 0x00005760), + SECP256K1_FE_CONST(0xb0393f9f, 0x9f2aa55e, 0xf5607e2e, 0x5287d961, 0x60b3e704, 0xf3e16e80, 0xb4f9a3ea, 0xfec7f02d)}, + {SECP256K1_FE_CONST(0xc97b6cec, 0x3ee6b8dc, 0x98d24b58, 0x3c1970a1, 0xfe06297a, 0xae813529, 0xe76bb6bd, 0x771ae51d), + SECP256K1_FE_CONST(0x0507c702, 0xd407d097, 0x47ddeb06, 0xf6625419, 0x79f48f79, 0x7bf80d0b, 0xfc34b364, 0x253a5db1)}, + {SECP256K1_FE_CONST(0xd559af63, 0x77ea9bc4, 0x3cf1ad14, 0x5c7a4bbb, 0x10e7d18b, 0x7ce0dfac, 0x380bb19d, 0x0bb99bd3), + SECP256K1_FE_CONST(0x00196119, 0xb9b00d92, 0x34edfdb5, 0xbbdc42fc, 0xd2daa33a, 0x163356ca, 0xaa8754c8, 0xb0ec8b0b)}, + {SECP256K1_FE_CONST(0x8ddfa3dc, 0x52918da0, 0x640519dc, 0x0af8512a, 0xca2d33b2, 0xbde52514, 0xda9c0afc, 0xcb29fce4), + SECP256K1_FE_CONST(0xb3e4878d, 0x5cb69148, 0xcd54388b, 0xc23acce0, 0x62518ba8, 0xf09def92, 0x7b31e6aa, 0x6ba35b02)}, + {SECP256K1_FE_CONST(0xf8207492, 0xe3049f0a, 0x65285f2b, 0x0bfff996, 0x00ca112e, 0xc05da837, 0x546d41f9, 0x5194fb91), + SECP256K1_FE_CONST(0x7b7ee50b, 0xa8ed4bbd, 0xf6469930, 0x81419a5c, 0x071441c7, 0x290d046e, 0x3b82ea41, 0x611c5f95)}, + {SECP256K1_FE_CONST(0x050f7c80, 0x5bcd3c6b, 0x823cb724, 0x5ce74db7, 0xa4e39f5c, 0xbd8828d7, 0xfd4d3e07, 0x3ec2926a), + SECP256K1_FE_CONST(0x000d6730, 0xb0171314, 0x4764053d, 0xee157117, 0x48fd61da, 0xdea0b9db, 0x1d5e91c6, 0xbdc3f59e)}, + {SECP256K1_FE_CONST(0x3e3ea8eb, 0x05d760cf, 0x23009263, 0xb3cb3ac9, 0x088f6f0d, 0x3fc182a3, 0xbd57087c, 0xe67c62f9), + SECP256K1_FE_CONST(0xbe988716, 0xa29c1bf6, 0x4456aed6, 0xab1e4720, 0x49929305, 0x51043bf4, 0xebd833dd, 0xdd511e8b)}, + {SECP256K1_FE_CONST(0x6964d2a9, 0xa7fa6501, 0xa5959249, 0x142f4029, 0xea0c1b5f, 0x2f487ef6, 0x301ac80a, 0x768be5cd), + SECP256K1_FE_CONST(0x3918ffe4, 0x07492543, 0xed24d0b7, 0x3df95f8f, 0xaffd7cb4, 0x0de2191c, 0x9ec2f2ad, 0x2c0cb3c6)}, + {SECP256K1_FE_CONST(0x37c93520, 0xf6ddca57, 0x2b42fd5e, 0xb5c7e4de, 0x11b5b81c, 0xb95e91f3, 0x95c4d156, 0x39877ccb), + SECP256K1_FE_CONST(0x9a94b9b5, 0x57eb71ee, 0x4c975b8b, 0xac5262a8, 0x077b0595, 0xe12a6b1f, 0xd728edef, 0x1a6bf956)} + }; + /* Fixed test cases for scalar inverses: pairs of (x, 1/x) mod n. */ + static const secp256k1_scalar scalar_cases[][2] = { + /* 0 */ + {SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0), + SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0)}, + /* 1 */ + {SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1), + SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1)}, + /* -1 */ + {SECP256K1_SCALAR_CONST(0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0xbaaedce6, 0xaf48a03b, 0xbfd25e8c, 0xd0364140), + SECP256K1_SCALAR_CONST(0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0xbaaedce6, 0xaf48a03b, 0xbfd25e8c, 0xd0364140)}, + /* 2 */ + {SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 2), + SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x5d576e73, 0x57a4501d, 0xdfe92f46, 0x681b20a1)}, + /* 2**128 */ + {SECP256K1_SCALAR_CONST(0, 0, 0, 1, 0, 0, 0, 0), + SECP256K1_SCALAR_CONST(0x50a51ac8, 0x34b9ec24, 0x4b0dff66, 0x5588b13e, 0x9984d5b3, 0xcf80ef0f, 0xd6a23766, 0xa3ee9f22)}, + /* Input known to need 635 divsteps */ + {SECP256K1_SCALAR_CONST(0xcb9f1d35, 0xdd4416c2, 0xcd71bf3f, 0x6365da66, 0x3c9b3376, 0x8feb7ae9, 0x32a5ef60, 0x19199ec3), + SECP256K1_SCALAR_CONST(0x1d7c7bba, 0xf1893d53, 0xb834bd09, 0x36b411dc, 0x42c2e42f, 0xec72c428, 0x5e189791, 0x8e9bc708)}, + /* Input known to need 566 divsteps starting with delta=1/2. */ + {SECP256K1_SCALAR_CONST(0x7e3c993d, 0xa4272488, 0xbc015b49, 0x2db54174, 0xd382083a, 0xebe6db35, 0x80f82eff, 0xcd132c72), + SECP256K1_SCALAR_CONST(0x086f34a0, 0x3e631f76, 0x77418f28, 0xcc84ac95, 0x6304439d, 0x365db268, 0x312c6ded, 0xd0b934f8)}, + /* Input known to need 565 divsteps starting with delta=1/2. */ + {SECP256K1_SCALAR_CONST(0xbad7e587, 0x3f307859, 0x60d93147, 0x8a18491e, 0xb38a9fd5, 0x254350d3, 0x4b1f0e4b, 0x7dd6edc4), + SECP256K1_SCALAR_CONST(0x89f2df26, 0x39e2b041, 0xf19bd876, 0xd039c8ac, 0xc2223add, 0x29c4943e, 0x6632d908, 0x515f467b)}, + /* Selection of randomly generated inputs that reach low/high d/e values in various configurations. */ + {SECP256K1_SCALAR_CONST(0x1950d757, 0xb37a5809, 0x435059bb, 0x0bb8997e, 0x07e1e3c8, 0x5e5d7d2c, 0x6a0ed8e3, 0xdbde180e), + SECP256K1_SCALAR_CONST(0xbf72af9b, 0x750309e2, 0x8dda230b, 0xfe432b93, 0x7e25e475, 0x4388251e, 0x633d894b, 0x3bcb6f8c)}, + {SECP256K1_SCALAR_CONST(0x9bccf4e7, 0xc5a515e3, 0x50637aa9, 0xbb65a13f, 0x391749a1, 0x62de7d4e, 0xf6d7eabb, 0x3cd10ce0), + SECP256K1_SCALAR_CONST(0xaf2d5623, 0xb6385a33, 0xcd0365be, 0x5e92a70d, 0x7f09179c, 0x3baaf30f, 0x8f9cc83b, 0x20092f67)}, + {SECP256K1_SCALAR_CONST(0x73a57111, 0xb242952a, 0x5c5dee59, 0xf3be2ace, 0xa30a7659, 0xa46e5f47, 0xd21267b1, 0x39e642c9), + SECP256K1_SCALAR_CONST(0xa711df07, 0xcbcf13ef, 0xd61cc6be, 0xbcd058ce, 0xb02cf157, 0x272d4a18, 0x86d0feb3, 0xcd5fa004)}, + {SECP256K1_SCALAR_CONST(0x04884963, 0xce0580b1, 0xba547030, 0x3c691db3, 0x9cd2c84f, 0x24c7cebd, 0x97ebfdba, 0x3e785ec2), + SECP256K1_SCALAR_CONST(0xaaaaaf14, 0xd7c99ba7, 0x517ce2c1, 0x78a28b4c, 0x3769a851, 0xe5c5a03d, 0x4cc28f33, 0x0ec4dc5d)}, + {SECP256K1_SCALAR_CONST(0x1679ed49, 0x21f537b1, 0x815cb8ae, 0x9efc511c, 0x5b9fa037, 0x0b0f275e, 0x6c985281, 0x6c4a9905), + SECP256K1_SCALAR_CONST(0xb14ac3d5, 0x62b52999, 0xef34ead1, 0xffca4998, 0x0294341a, 0x1f8172aa, 0xea1624f9, 0x302eea62)}, + {SECP256K1_SCALAR_CONST(0x626b37c0, 0xf0057c35, 0xee982f83, 0x452a1fd3, 0xea826506, 0x48b08a9d, 0x1d2c4799, 0x4ad5f6ec), + SECP256K1_SCALAR_CONST(0xe38643b7, 0x567bfc2f, 0x5d2f1c15, 0xe327239c, 0x07112443, 0x69509283, 0xfd98e77a, 0xdb71c1e8)}, + {SECP256K1_SCALAR_CONST(0x1850a3a7, 0x759efc56, 0x54f287b2, 0x14d1234b, 0xe263bbc9, 0xcf4d8927, 0xd5f85f27, 0x965bd816), + SECP256K1_SCALAR_CONST(0x3b071831, 0xcac9619a, 0xcceb0596, 0xf614d63b, 0x95d0db2f, 0xc6a00901, 0x8eaa2621, 0xabfa0009)}, + {SECP256K1_SCALAR_CONST(0x94ae5d06, 0xa27dc400, 0x487d72be, 0xaa51ebed, 0xe475b5c0, 0xea675ffc, 0xf4df627a, 0xdca4222f), + SECP256K1_SCALAR_CONST(0x01b412ed, 0xd7830956, 0x1532537e, 0xe5e3dc99, 0x8fd3930a, 0x54f8d067, 0x32ef5760, 0x594438a5)}, + {SECP256K1_SCALAR_CONST(0x1f24278a, 0xb5bfe374, 0xa328dbbc, 0xebe35f48, 0x6620e009, 0xd58bb1b4, 0xb5a6bf84, 0x8815f63a), + SECP256K1_SCALAR_CONST(0xfe928416, 0xca5ba2d3, 0xfde513da, 0x903a60c7, 0x9e58ad8a, 0x8783bee4, 0x083a3843, 0xa608c914)}, + {SECP256K1_SCALAR_CONST(0xdc107d58, 0x274f6330, 0x67dba8bc, 0x26093111, 0x5201dfb8, 0x968ce3f5, 0xf34d1bd4, 0xf2146504), + SECP256K1_SCALAR_CONST(0x660cfa90, 0x13c3d93e, 0x7023b1e5, 0xedd09e71, 0x6d9c9d10, 0x7a3d2cdb, 0xdd08edc3, 0xaa78fcfb)}, + {SECP256K1_SCALAR_CONST(0x7cd1e905, 0xc6f02776, 0x2f551cc7, 0x5da61cff, 0x7da05389, 0x1119d5a4, 0x631c7442, 0x894fd4f7), + SECP256K1_SCALAR_CONST(0xff20862a, 0x9d3b1a37, 0x1628803b, 0x3004ccae, 0xaa23282a, 0xa89a1109, 0xd94ece5e, 0x181bdc46)}, + {SECP256K1_SCALAR_CONST(0x5b9dade8, 0x23d26c58, 0xcd12d818, 0x25b8ae97, 0x3dea04af, 0xf482c96b, 0xa062f254, 0x9e453640), + SECP256K1_SCALAR_CONST(0x50c38800, 0x15fa53f4, 0xbe1e5392, 0x5c9b120a, 0x262c22c7, 0x18fa0816, 0x5f2baab4, 0x8cb5db46)}, + {SECP256K1_SCALAR_CONST(0x11cdaeda, 0x969c464b, 0xef1f4ab0, 0x5b01d22e, 0x656fd098, 0x882bea84, 0x65cdbe7a, 0x0c19ff03), + SECP256K1_SCALAR_CONST(0x1968d0fa, 0xac46f103, 0xb55f1f72, 0xb3820bed, 0xec6b359a, 0x4b1ae0ad, 0x7e38e1fb, 0x295ccdfb)}, + {SECP256K1_SCALAR_CONST(0x2c351aa1, 0x26e91589, 0x194f8a1e, 0x06561f66, 0x0cb97b7f, 0x10914454, 0x134d1c03, 0x157266b4), + SECP256K1_SCALAR_CONST(0xbe49ada6, 0x92bd8711, 0x41b176c4, 0xa478ba95, 0x14883434, 0x9d1cd6f3, 0xcc4b847d, 0x22af80f5)}, + {SECP256K1_SCALAR_CONST(0x6ba07c6e, 0x13a60edb, 0x6247f5c3, 0x84b5fa56, 0x76fe3ec5, 0x80426395, 0xf65ec2ae, 0x623ba730), + SECP256K1_SCALAR_CONST(0x25ac23f7, 0x418cd747, 0x98376f9d, 0x4a11c7bf, 0x24c8ebfe, 0x4c8a8655, 0x345f4f52, 0x1c515595)}, + {SECP256K1_SCALAR_CONST(0x9397a712, 0x8abb6951, 0x2d4a3d54, 0x703b1c2a, 0x0661dca8, 0xd75c9b31, 0xaed4d24b, 0xd2ab2948), + SECP256K1_SCALAR_CONST(0xc52e8bef, 0xd55ce3eb, 0x1c897739, 0xeb9fb606, 0x36b9cd57, 0x18c51cc2, 0x6a87489e, 0xffd0dcf3)}, + {SECP256K1_SCALAR_CONST(0xe6a808cc, 0xeb437888, 0xe97798df, 0x4e224e44, 0x7e3b380a, 0x207c1653, 0x889f3212, 0xc6738b6f), + SECP256K1_SCALAR_CONST(0x31f9ae13, 0xd1e08b20, 0x757a2e5e, 0x5243a0eb, 0x8ae35f73, 0x19bb6122, 0xb910f26b, 0xda70aa55)}, + {SECP256K1_SCALAR_CONST(0xd0320548, 0xab0effe7, 0xa70779e0, 0x61a347a6, 0xb8c1e010, 0x9d5281f8, 0x2ee588a6, 0x80000000), + SECP256K1_SCALAR_CONST(0x1541897e, 0x78195c90, 0x7583dd9e, 0x728b6100, 0xbce8bc6d, 0x7a53b471, 0x5dcd9e45, 0x4425fcaf)}, + {SECP256K1_SCALAR_CONST(0x93d623f1, 0xd45b50b0, 0x796e9186, 0x9eac9407, 0xd30edc20, 0xef6304cf, 0x250494e7, 0xba503de9), + SECP256K1_SCALAR_CONST(0x7026d638, 0x1178b548, 0x92043952, 0x3c7fb47c, 0xcd3ea236, 0x31d82b01, 0x612fc387, 0x80b9b957)}, + {SECP256K1_SCALAR_CONST(0xf860ab39, 0x55f5d412, 0xa4d73bcc, 0x3b48bd90, 0xc248ffd3, 0x13ca10be, 0x8fba84cc, 0xdd28d6a3), + SECP256K1_SCALAR_CONST(0x5c32fc70, 0xe0b15d67, 0x76694700, 0xfe62be4d, 0xeacdb229, 0x7a4433d9, 0x52155cd0, 0x7649ab59)}, + {SECP256K1_SCALAR_CONST(0x4e41311c, 0x0800af58, 0x7a690a8e, 0xe175c9ba, 0x6981ab73, 0xac532ea8, 0x5c1f5e63, 0x6ac1f189), + SECP256K1_SCALAR_CONST(0xfffffff9, 0xd075982c, 0x7fbd3825, 0xc05038a2, 0x4533b91f, 0x94ec5f45, 0xb280b28f, 0x842324dc)}, + {SECP256K1_SCALAR_CONST(0x48e473bf, 0x3555eade, 0xad5d7089, 0x2424c4e4, 0x0a99397c, 0x2dc796d8, 0xb7a43a69, 0xd0364141), + SECP256K1_SCALAR_CONST(0x634976b2, 0xa0e47895, 0x1ec38593, 0x266d6fd0, 0x6f602644, 0x9bb762f1, 0x7180c704, 0xe23a4daa)}, + {SECP256K1_SCALAR_CONST(0xbe83878d, 0x3292fc54, 0x26e71c62, 0x556ccedc, 0x7cbb8810, 0x4032a720, 0x34ead589, 0xe4d6bd13), + SECP256K1_SCALAR_CONST(0x6cd150ad, 0x25e59d0f, 0x74cbae3d, 0x6377534a, 0x1e6562e8, 0xb71b9d18, 0xe1e5d712, 0x8480abb3)}, + {SECP256K1_SCALAR_CONST(0xcdddf2e5, 0xefc15f88, 0xc9ee06de, 0x8a846ca9, 0x28561581, 0x68daa5fb, 0xd1cf3451, 0xeb1782d0), + SECP256K1_SCALAR_CONST(0xffffffd9, 0xed8d2af4, 0x993c865a, 0x23e9681a, 0x3ca3a3dc, 0xe6d5a46e, 0xbd86bd87, 0x61b55c70)}, + {SECP256K1_SCALAR_CONST(0xb6a18f1f, 0x04872df9, 0x08165ec4, 0x319ca19c, 0x6c0359ab, 0x1f7118fb, 0xc2ef8082, 0xca8b7785), + SECP256K1_SCALAR_CONST(0xff55b19b, 0x0f1ac78c, 0x0f0c88c2, 0x2358d5ad, 0x5f455e4e, 0x3330b72f, 0x274dc153, 0xffbf272b)}, + {SECP256K1_SCALAR_CONST(0xea4898e5, 0x30eba3e8, 0xcf0e5c3d, 0x06ec6844, 0x01e26fb6, 0x75636225, 0xc5d08f4c, 0x1decafa0), + SECP256K1_SCALAR_CONST(0xe5a014a8, 0xe3c4ec1e, 0xea4f9b32, 0xcfc7b386, 0x00630806, 0x12c08d02, 0x6407ccc2, 0xb067d90e)}, + {SECP256K1_SCALAR_CONST(0x70e9aea9, 0x7e933af0, 0x8a23bfab, 0x23e4b772, 0xff951863, 0x5ffcf47d, 0x6bebc918, 0x2ca58265), + SECP256K1_SCALAR_CONST(0xf4e00006, 0x81bc6441, 0x4eb6ec02, 0xc194a859, 0x80ad7c48, 0xba4e9afb, 0x8b6bdbe0, 0x989d8f77)}, + {SECP256K1_SCALAR_CONST(0x3c56c774, 0x46efe6f0, 0xe93618b8, 0xf9b5a846, 0xd247df61, 0x83b1e215, 0x06dc8bcc, 0xeefc1bf5), + SECP256K1_SCALAR_CONST(0xfff8937a, 0x2cd9586b, 0x43c25e57, 0xd1cefa7a, 0x9fb91ed3, 0x95b6533d, 0x8ad0de5b, 0xafb93f00)}, + {SECP256K1_SCALAR_CONST(0xfb5c2772, 0x5cb30e83, 0xe38264df, 0xe4e3ebf3, 0x392aa92e, 0xa68756a1, 0x51279ac5, 0xb50711a8), + SECP256K1_SCALAR_CONST(0x000013af, 0x1105bfe7, 0xa6bbd7fb, 0x3d638f99, 0x3b266b02, 0x072fb8bc, 0x39251130, 0x2e0fd0ea)} + }; + int i, var, testrand; + unsigned char b32[32]; + secp256k1_fe x_fe; + secp256k1_scalar x_scalar; + memset(b32, 0, sizeof(b32)); + /* Test fixed test cases through test_inverse_{scalar,field}, both ways. */ + for (i = 0; (size_t)i < sizeof(fe_cases)/sizeof(fe_cases[0]); ++i) { + for (var = 0; var <= 1; ++var) { + test_inverse_field(&x_fe, &fe_cases[i][0], var); + CHECK(fe_equal(&x_fe, &fe_cases[i][1])); + test_inverse_field(&x_fe, &fe_cases[i][1], var); + CHECK(fe_equal(&x_fe, &fe_cases[i][0])); + } + } + for (i = 0; (size_t)i < sizeof(scalar_cases)/sizeof(scalar_cases[0]); ++i) { + for (var = 0; var <= 1; ++var) { + test_inverse_scalar(&x_scalar, &scalar_cases[i][0], var); + CHECK(secp256k1_scalar_eq(&x_scalar, &scalar_cases[i][1])); + test_inverse_scalar(&x_scalar, &scalar_cases[i][1], var); + CHECK(secp256k1_scalar_eq(&x_scalar, &scalar_cases[i][0])); + } + } + /* Test inputs 0..999 and their respective negations. */ + for (i = 0; i < 1000; ++i) { + b32[31] = i & 0xff; + b32[30] = (i >> 8) & 0xff; + secp256k1_scalar_set_b32(&x_scalar, b32, NULL); + secp256k1_fe_set_b32_mod(&x_fe, b32); + for (var = 0; var <= 1; ++var) { + test_inverse_scalar(NULL, &x_scalar, var); + test_inverse_field(NULL, &x_fe, var); + } + secp256k1_scalar_negate(&x_scalar, &x_scalar); + secp256k1_fe_negate(&x_fe, &x_fe, 1); + for (var = 0; var <= 1; ++var) { + test_inverse_scalar(NULL, &x_scalar, var); + test_inverse_field(NULL, &x_fe, var); + } + } + /* test 128*count random inputs; half with testrand256_test, half with testrand256 */ + for (testrand = 0; testrand <= 1; ++testrand) { + for (i = 0; i < 64 * COUNT; ++i) { + (testrand ? testrand256_test : testrand256)(b32); + secp256k1_scalar_set_b32(&x_scalar, b32, NULL); + secp256k1_fe_set_b32_mod(&x_fe, b32); + for (var = 0; var <= 1; ++var) { + test_inverse_scalar(NULL, &x_scalar, var); + test_inverse_field(NULL, &x_fe, var); + } + } + } +} + +/***** HSORT TESTS *****/ + +static void test_heap_swap(void) { + unsigned char a[600]; + unsigned char e[sizeof(a)]; + memset(a, 21, 200); + memset(a + 200, 99, 200); + memset(a + 400, 42, 200); + memset(e, 42, 200); + memset(e + 200, 99, 200); + memset(e + 400, 21, 200); + secp256k1_heap_swap(a, 0, 2, 200); + CHECK(secp256k1_memcmp_var(a, e, sizeof(a)) == 0); +} + +static void test_hsort_is_sorted(unsigned char *elements, size_t n, size_t len) { + size_t i; + for (i = 1; i < n; i++) { + CHECK(secp256k1_memcmp_var(&elements[(i-1) * len], &elements[i * len], len) <= 0); + } +} + +struct test_hsort_cmp_data { + size_t counter; + size_t element_len; +}; + + +static int test_hsort_cmp(const void *ele1, const void *ele2, void *data) { + struct test_hsort_cmp_data *d = (struct test_hsort_cmp_data *) data; + d->counter += 1; + return secp256k1_memcmp_var((unsigned char *)ele1, (unsigned char *)ele2, d->element_len); +} + +#define NUM 65 +#define MAX_ELEMENT_LEN 65 +static void test_hsort(size_t element_len) { + unsigned char elements[NUM * MAX_ELEMENT_LEN] = { 0 }; + struct test_hsort_cmp_data data; + int i; + + VERIFY_CHECK(element_len <= MAX_ELEMENT_LEN); + data.counter = 0; + data.element_len = element_len; + + secp256k1_hsort(elements, 0, element_len, test_hsort_cmp, &data); + CHECK(data.counter == 0); + secp256k1_hsort(elements, 1, element_len, test_hsort_cmp, &data); + CHECK(data.counter == 0); + secp256k1_hsort(elements, NUM, element_len, test_hsort_cmp, &data); + CHECK(data.counter >= NUM - 1); + test_hsort_is_sorted(elements, NUM, element_len); + + /* Test hsort with array of random length n */ + for (i = 0; i < COUNT; i++) { + int n = testrand_int(NUM); + testrand_bytes_test(elements, n*element_len); + secp256k1_hsort(elements, n, element_len, test_hsort_cmp, &data); + test_hsort_is_sorted(elements, n, element_len); + } +} +#undef NUM +#undef MAX_ELEMENT_LEN + + +static void run_hsort_tests(void) { + test_heap_swap(); + test_hsort(1); + test_hsort(64); + test_hsort(65); +} + +/***** GROUP TESTS *****/ + /* This compares jacobian points including their Z, not just their geometric meaning. */ -int gej_xyz_equals_gej(const secp256k1_gej *a, const secp256k1_gej *b) { +static int gej_xyz_equals_gej(const secp256k1_gej *a, const secp256k1_gej *b) { secp256k1_gej a2; secp256k1_gej b2; int ret = 1; @@ -1848,101 +3656,70 @@ int gej_xyz_equals_gej(const secp256k1_gej *a, const secp256k1_gej *b) { return ret; } -void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { - secp256k1_fe z2s; - secp256k1_fe u1, u2, s1, s2; - CHECK(a->infinity == b->infinity); - if (a->infinity) { - return; - } - /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ - secp256k1_fe_sqr(&z2s, &b->z); - secp256k1_fe_mul(&u1, &a->x, &z2s); - u2 = b->x; secp256k1_fe_normalize_weak(&u2); - secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); - s2 = b->y; secp256k1_fe_normalize_weak(&s2); - CHECK(secp256k1_fe_equal_var(&u1, &u2)); - CHECK(secp256k1_fe_equal_var(&s1, &s2)); -} - -void test_ge(void) { +static void test_ge(void) { int i, i1; -#ifdef USE_ENDOMORPHISM int runs = 6; -#else - int runs = 4; -#endif - /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4). - * The second in each pair of identical points uses a random Z coordinate in the Jacobian form. - * All magnitudes are randomized. - * All 17*17 combinations of points are added to each other, using all applicable methods. - * - * When the endomorphism code is compiled in, p5 = lambda*p1 and p6 = lambda^2*p1 are added as well. + /* 25 points are used: + * - infinity + * - for each of four random points p1 p2 p3 p4, we add the point, its + * negation, and then those two again but with randomized Z coordinate. + * - The same is then done for lambda*p1 and lambda^2*p1. */ - secp256k1_ge *ge = (secp256k1_ge *)malloc(sizeof(secp256k1_ge) * (1 + 4 * runs)); - secp256k1_gej *gej = (secp256k1_gej *)malloc(sizeof(secp256k1_gej) * (1 + 4 * runs)); - secp256k1_fe *zinv = (secp256k1_fe *)malloc(sizeof(secp256k1_fe) * (1 + 4 * runs)); - secp256k1_fe zf; + secp256k1_ge *ge = (secp256k1_ge *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_ge) * (1 + 4 * runs)); + secp256k1_gej *gej = (secp256k1_gej *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_gej) * (1 + 4 * runs)); + secp256k1_fe zf, r; secp256k1_fe zfi2, zfi3; secp256k1_gej_set_infinity(&gej[0]); - secp256k1_ge_clear(&ge[0]); - secp256k1_ge_set_gej_var(&ge[0], &gej[0]); + secp256k1_ge_set_infinity(&ge[0]); for (i = 0; i < runs; i++) { - int j; + int j, k; secp256k1_ge g; - random_group_element_test(&g); -#ifdef USE_ENDOMORPHISM + testutil_random_ge_test(&g); if (i >= runs - 2) { secp256k1_ge_mul_lambda(&g, &ge[1]); + CHECK(!secp256k1_ge_eq_var(&g, &ge[1])); } if (i >= runs - 1) { secp256k1_ge_mul_lambda(&g, &g); } -#endif ge[1 + 4 * i] = g; ge[2 + 4 * i] = g; secp256k1_ge_neg(&ge[3 + 4 * i], &g); secp256k1_ge_neg(&ge[4 + 4 * i], &g); secp256k1_gej_set_ge(&gej[1 + 4 * i], &ge[1 + 4 * i]); - random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]); + testutil_random_ge_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]); secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]); - random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]); + testutil_random_ge_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]); for (j = 0; j < 4; j++) { - random_field_element_magnitude(&ge[1 + j + 4 * i].x); - random_field_element_magnitude(&ge[1 + j + 4 * i].y); - random_field_element_magnitude(&gej[1 + j + 4 * i].x); - random_field_element_magnitude(&gej[1 + j + 4 * i].y); - random_field_element_magnitude(&gej[1 + j + 4 * i].z); + testutil_random_ge_x_magnitude(&ge[1 + j + 4 * i]); + testutil_random_ge_y_magnitude(&ge[1 + j + 4 * i]); + testutil_random_gej_x_magnitude(&gej[1 + j + 4 * i]); + testutil_random_gej_y_magnitude(&gej[1 + j + 4 * i]); + testutil_random_gej_z_magnitude(&gej[1 + j + 4 * i]); } - } - /* Compute z inverses. */ - { - secp256k1_fe *zs = malloc(sizeof(secp256k1_fe) * (1 + 4 * runs)); - for (i = 0; i < 4 * runs + 1; i++) { - if (i == 0) { - /* The point at infinity does not have a meaningful z inverse. Any should do. */ - do { - random_field_element_test(&zs[i]); - } while(secp256k1_fe_is_zero(&zs[i])); - } else { - zs[i] = gej[i].z; + for (j = 0; j < 4; ++j) { + for (k = 0; k < 4; ++k) { + int expect_equal = (j >> 1) == (k >> 1); + CHECK(secp256k1_ge_eq_var(&ge[1 + j + 4 * i], &ge[1 + k + 4 * i]) == expect_equal); + CHECK(secp256k1_gej_eq_var(&gej[1 + j + 4 * i], &gej[1 + k + 4 * i]) == expect_equal); + CHECK(secp256k1_gej_eq_ge_var(&gej[1 + j + 4 * i], &ge[1 + k + 4 * i]) == expect_equal); + CHECK(secp256k1_gej_eq_ge_var(&gej[1 + k + 4 * i], &ge[1 + j + 4 * i]) == expect_equal); } } - secp256k1_fe_inv_all_var(zinv, zs, 4 * runs + 1); - free(zs); } /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */ - do { - random_field_element_test(&zf); - } while(secp256k1_fe_is_zero(&zf)); - random_field_element_magnitude(&zf); + testutil_random_fe_non_zero_test(&zf); + testutil_random_fe_magnitude(&zf, 8); secp256k1_fe_inv_var(&zfi3, &zf); secp256k1_fe_sqr(&zfi2, &zfi3); secp256k1_fe_mul(&zfi3, &zfi3, &zfi2); + /* Generate random r */ + testutil_random_fe_non_zero_test(&r); + for (i1 = 0; i1 < 1 + 4 * runs; i1++) { int i2; for (i2 = 0; i2 < 1 + 4 * runs; i2++) { @@ -1954,16 +3731,16 @@ void test_ge(void) { /* Check Z ratio. */ if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&refj)) { secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z); - CHECK(secp256k1_fe_equal_var(&zrz, &refj.z)); + CHECK(secp256k1_fe_equal(&zrz, &refj.z)); } secp256k1_ge_set_gej_var(&ref, &refj); /* Test gej + ge with Z ratio result (var). */ secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr); - ge_equals_gej(&ref, &resj); + CHECK(secp256k1_gej_eq_ge_var(&resj, &ref)); if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&resj)) { secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z); - CHECK(secp256k1_fe_equal_var(&zrz, &resj.z)); + CHECK(secp256k1_fe_equal(&zrz, &resj.z)); } /* Test gej + ge (var, with additional Z factor). */ @@ -1971,17 +3748,17 @@ void test_ge(void) { secp256k1_ge ge2_zfi = ge[i2]; /* the second term with x and y rescaled for z = 1/zf */ secp256k1_fe_mul(&ge2_zfi.x, &ge2_zfi.x, &zfi2); secp256k1_fe_mul(&ge2_zfi.y, &ge2_zfi.y, &zfi3); - random_field_element_magnitude(&ge2_zfi.x); - random_field_element_magnitude(&ge2_zfi.y); + testutil_random_ge_x_magnitude(&ge2_zfi); + testutil_random_ge_y_magnitude(&ge2_zfi); secp256k1_gej_add_zinv_var(&resj, &gej[i1], &ge2_zfi, &zf); - ge_equals_gej(&ref, &resj); + CHECK(secp256k1_gej_eq_ge_var(&resj, &ref)); } /* Test gej + ge (const). */ if (i2 != 0) { /* secp256k1_gej_add_ge does not support its second argument being infinity. */ secp256k1_gej_add_ge(&resj, &gej[i1], &ge[i2]); - ge_equals_gej(&ref, &resj); + CHECK(secp256k1_gej_eq_ge_var(&resj, &ref)); } /* Test doubling (var). */ @@ -1989,13 +3766,16 @@ void test_ge(void) { secp256k1_fe zr2; /* Normal doubling with Z ratio result. */ secp256k1_gej_double_var(&resj, &gej[i1], &zr2); - ge_equals_gej(&ref, &resj); + CHECK(secp256k1_gej_eq_ge_var(&resj, &ref)); /* Check Z ratio. */ secp256k1_fe_mul(&zr2, &zr2, &gej[i1].z); - CHECK(secp256k1_fe_equal_var(&zr2, &resj.z)); + CHECK(secp256k1_fe_equal(&zr2, &resj.z)); /* Normal doubling. */ secp256k1_gej_double_var(&resj, &gej[i2], NULL); - ge_equals_gej(&ref, &resj); + CHECK(secp256k1_gej_eq_ge_var(&resj, &ref)); + /* Constant-time doubling. */ + secp256k1_gej_double(&resj, &gej[i2]); + CHECK(secp256k1_gej_eq_ge_var(&resj, &ref)); } /* Test adding opposites. */ @@ -2007,12 +3787,12 @@ void test_ge(void) { if (i1 == 0) { CHECK(secp256k1_ge_is_infinity(&ge[i1])); CHECK(secp256k1_gej_is_infinity(&gej[i1])); - ge_equals_gej(&ref, &gej[i2]); + CHECK(secp256k1_gej_eq_ge_var(&gej[i2], &ref)); } if (i2 == 0) { CHECK(secp256k1_ge_is_infinity(&ge[i2])); CHECK(secp256k1_gej_is_infinity(&gej[i2])); - ge_equals_gej(&ref, &gej[i1]); + CHECK(secp256k1_gej_eq_ge_var(&gej[i1], &ref)); } } } @@ -2020,12 +3800,12 @@ void test_ge(void) { /* Test adding all points together in random order equals infinity. */ { secp256k1_gej sum = SECP256K1_GEJ_CONST_INFINITY; - secp256k1_gej *gej_shuffled = (secp256k1_gej *)malloc((4 * runs + 1) * sizeof(secp256k1_gej)); + secp256k1_gej *gej_shuffled = (secp256k1_gej *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_gej)); for (i = 0; i < 4 * runs + 1; i++) { gej_shuffled[i] = gej[i]; } for (i = 0; i < 4 * runs + 1; i++) { - int swap = i + secp256k1_rand_int(4 * runs + 1 - i); + int swap = i + testrand_int(4 * runs + 1 - i); if (swap != i) { secp256k1_gej t = gej_shuffled[i]; gej_shuffled[i] = gej_shuffled[swap]; @@ -2039,37 +3819,109 @@ void test_ge(void) { free(gej_shuffled); } - /* Test batch gej -> ge conversion with and without known z ratios. */ + /* Test batch gej -> ge conversion without known z ratios. */ { - secp256k1_fe *zr = (secp256k1_fe *)malloc((4 * runs + 1) * sizeof(secp256k1_fe)); - secp256k1_ge *ge_set_table = (secp256k1_ge *)malloc((4 * runs + 1) * sizeof(secp256k1_ge)); - secp256k1_ge *ge_set_all = (secp256k1_ge *)malloc((4 * runs + 1) * sizeof(secp256k1_ge)); - for (i = 0; i < 4 * runs + 1; i++) { - /* Compute gej[i + 1].z / gez[i].z (with gej[n].z taken to be 1). */ - if (i < 4 * runs) { - secp256k1_fe_mul(&zr[i + 1], &zinv[i], &gej[i + 1].z); - } - } - secp256k1_ge_set_table_gej_var(ge_set_table, gej, zr, 4 * runs + 1); - secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1, &ctx->error_callback); + secp256k1_ge *ge_set_all = (secp256k1_ge *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge)); + secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1); for (i = 0; i < 4 * runs + 1; i++) { secp256k1_fe s; - random_fe_non_zero(&s); + testutil_random_fe_non_zero(&s); secp256k1_gej_rescale(&gej[i], &s); - ge_equals_gej(&ge_set_table[i], &gej[i]); - ge_equals_gej(&ge_set_all[i], &gej[i]); + CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all[i])); } - free(ge_set_table); free(ge_set_all); - free(zr); + } + + /* Test that all elements have X coordinates on the curve. */ + for (i = 1; i < 4 * runs + 1; i++) { + secp256k1_fe n; + CHECK(secp256k1_ge_x_on_curve_var(&ge[i].x)); + /* And the same holds after random rescaling. */ + secp256k1_fe_mul(&n, &zf, &ge[i].x); + CHECK(secp256k1_ge_x_frac_on_curve_var(&n, &zf)); + } + + /* Test correspondence of secp256k1_ge_x{,_frac}_on_curve_var with ge_set_xo. */ + { + secp256k1_fe n; + secp256k1_ge q; + int ret_on_curve, ret_frac_on_curve, ret_set_xo; + secp256k1_fe_mul(&n, &zf, &r); + ret_on_curve = secp256k1_ge_x_on_curve_var(&r); + ret_frac_on_curve = secp256k1_ge_x_frac_on_curve_var(&n, &zf); + ret_set_xo = secp256k1_ge_set_xo_var(&q, &r, 0); + CHECK(ret_on_curve == ret_frac_on_curve); + CHECK(ret_on_curve == ret_set_xo); + if (ret_set_xo) CHECK(secp256k1_fe_equal(&r, &q.x)); + } + + /* Test batch gej -> ge conversion with many infinities. */ + for (i = 0; i < 4 * runs + 1; i++) { + int odd; + testutil_random_ge_test(&ge[i]); + odd = secp256k1_fe_is_odd(&ge[i].x); + CHECK(odd == 0 || odd == 1); + /* randomly set half the points to infinity */ + if (odd == i % 2) { + secp256k1_ge_set_infinity(&ge[i]); + } + secp256k1_gej_set_ge(&gej[i], &ge[i]); + } + /* batch convert */ + secp256k1_ge_set_all_gej_var(ge, gej, 4 * runs + 1); + /* check result */ + for (i = 0; i < 4 * runs + 1; i++) { + CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge[i])); + } + + /* Test batch gej -> ge conversion with all infinities. */ + for (i = 0; i < 4 * runs + 1; i++) { + secp256k1_gej_set_infinity(&gej[i]); + } + /* batch convert */ + secp256k1_ge_set_all_gej_var(ge, gej, 4 * runs + 1); + /* check result */ + for (i = 0; i < 4 * runs + 1; i++) { + CHECK(secp256k1_ge_is_infinity(&ge[i])); } free(ge); free(gej); - free(zinv); } -void test_add_neg_y_diff_x(void) { +static void test_intialized_inf(void) { + secp256k1_ge p; + secp256k1_gej pj, npj, infj1, infj2, infj3; + secp256k1_fe zinv; + + /* Test that adding P+(-P) results in a fully initialized infinity*/ + testutil_random_ge_test(&p); + secp256k1_gej_set_ge(&pj, &p); + secp256k1_gej_neg(&npj, &pj); + + secp256k1_gej_add_var(&infj1, &pj, &npj, NULL); + CHECK(secp256k1_gej_is_infinity(&infj1)); + CHECK(secp256k1_fe_is_zero(&infj1.x)); + CHECK(secp256k1_fe_is_zero(&infj1.y)); + CHECK(secp256k1_fe_is_zero(&infj1.z)); + + secp256k1_gej_add_ge_var(&infj2, &npj, &p, NULL); + CHECK(secp256k1_gej_is_infinity(&infj2)); + CHECK(secp256k1_fe_is_zero(&infj2.x)); + CHECK(secp256k1_fe_is_zero(&infj2.y)); + CHECK(secp256k1_fe_is_zero(&infj2.z)); + + secp256k1_fe_set_int(&zinv, 1); + secp256k1_gej_add_zinv_var(&infj3, &npj, &p, &zinv); + CHECK(secp256k1_gej_is_infinity(&infj3)); + CHECK(secp256k1_fe_is_zero(&infj3.x)); + CHECK(secp256k1_fe_is_zero(&infj3.y)); + CHECK(secp256k1_fe_is_zero(&infj3.z)); + + +} + +static void test_add_neg_y_diff_x(void) { /* The point of this test is to check that we can add two points * whose y-coordinates are negatives of each other but whose x * coordinates differ. If the x-coordinates were the same, these @@ -2083,22 +3935,15 @@ void test_add_neg_y_diff_x(void) { * which this test is a regression test for. * * These points were generated in sage as - * # secp256k1 params - * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) - * C = EllipticCurve ([F (0), F (7)]) - * G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) - * N = FiniteField(G.order()) * - * # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F) - * x = polygen(N) - * lam = (1 - x^3).roots()[1][0] + * load("secp256k1_params.sage") * * # random "bad pair" * P = C.random_element() - * Q = -int(lam) * P - * print " P: %x %x" % P.xy() - * print " Q: %x %x" % Q.xy() - * print "P + Q: %x %x" % (P + Q).xy() + * Q = -int(LAMBDA) * P + * print(" P: %x %x" % P.xy()) + * print(" Q: %x %x" % Q.xy()) + * print("P + Q: %x %x" % (P + Q).xy()) */ secp256k1_gej aj = SECP256K1_GEJ_CONST( 0x8d24cd95, 0x0a355af1, 0x3c543505, 0x44238d30, @@ -2125,27 +3970,101 @@ void test_add_neg_y_diff_x(void) { secp256k1_gej_add_var(&resj, &aj, &bj, NULL); secp256k1_ge_set_gej(&res, &resj); - ge_equals_gej(&res, &sumj); + CHECK(secp256k1_gej_eq_ge_var(&sumj, &res)); secp256k1_gej_add_ge(&resj, &aj, &b); secp256k1_ge_set_gej(&res, &resj); - ge_equals_gej(&res, &sumj); + CHECK(secp256k1_gej_eq_ge_var(&sumj, &res)); secp256k1_gej_add_ge_var(&resj, &aj, &b, NULL); secp256k1_ge_set_gej(&res, &resj); - ge_equals_gej(&res, &sumj); + CHECK(secp256k1_gej_eq_ge_var(&sumj, &res)); } -void run_ge(void) { +static void test_ge_bytes(void) { int i; - for (i = 0; i < count * 32; i++) { + + for (i = 0; i < COUNT + 1; i++) { + unsigned char buf[64]; + secp256k1_ge p, q; + + if (i == 0) { + secp256k1_ge_set_infinity(&p); + } else { + testutil_random_ge_test(&p); + } + + if (!secp256k1_ge_is_infinity(&p)) { + secp256k1_ge_to_bytes(buf, &p); + + secp256k1_ge_from_bytes(&q, buf); + CHECK(secp256k1_ge_eq_var(&p, &q)); + + secp256k1_ge_from_bytes_ext(&q, buf); + CHECK(secp256k1_ge_eq_var(&p, &q)); + } + secp256k1_ge_to_bytes_ext(buf, &p); + secp256k1_ge_from_bytes_ext(&q, buf); + CHECK(secp256k1_ge_eq_var(&p, &q)); + } +} + +static void run_ge(void) { + int i; + for (i = 0; i < COUNT * 32; i++) { test_ge(); } test_add_neg_y_diff_x(); + test_intialized_inf(); + test_ge_bytes(); } -void test_ec_combine(void) { - secp256k1_scalar sum = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); +static void test_gej_cmov(const secp256k1_gej *a, const secp256k1_gej *b) { + secp256k1_gej t = *a; + secp256k1_gej_cmov(&t, b, 0); + CHECK(gej_xyz_equals_gej(&t, a)); + secp256k1_gej_cmov(&t, b, 1); + CHECK(gej_xyz_equals_gej(&t, b)); +} + +static void run_gej(void) { + int i; + secp256k1_gej a, b; + + /* Tests for secp256k1_gej_cmov */ + for (i = 0; i < COUNT; i++) { + secp256k1_gej_set_infinity(&a); + secp256k1_gej_set_infinity(&b); + test_gej_cmov(&a, &b); + + testutil_random_gej_test(&a); + test_gej_cmov(&a, &b); + test_gej_cmov(&b, &a); + + b = a; + test_gej_cmov(&a, &b); + + testutil_random_gej_test(&b); + test_gej_cmov(&a, &b); + test_gej_cmov(&b, &a); + } + + /* Tests for secp256k1_gej_eq_var */ + for (i = 0; i < COUNT; i++) { + secp256k1_fe fe; + testutil_random_gej_test(&a); + testutil_random_gej_test(&b); + CHECK(!secp256k1_gej_eq_var(&a, &b)); + + b = a; + testutil_random_fe_non_zero_test(&fe); + secp256k1_gej_rescale(&a, &fe); + CHECK(secp256k1_gej_eq_var(&a, &b)); + } +} + +static void test_ec_combine(void) { + secp256k1_scalar sum = secp256k1_scalar_zero; secp256k1_pubkey data[6]; const secp256k1_pubkey* d[6]; secp256k1_pubkey sd; @@ -2155,103 +4074,148 @@ void test_ec_combine(void) { int i; for (i = 1; i <= 6; i++) { secp256k1_scalar s; - random_scalar_order_test(&s); + testutil_random_scalar_order_test(&s); secp256k1_scalar_add(&sum, &sum, &s); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &s); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &Qj, &s); secp256k1_ge_set_gej(&Q, &Qj); secp256k1_pubkey_save(&data[i - 1], &Q); d[i - 1] = &data[i - 1]; - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sum); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &Qj, &sum); secp256k1_ge_set_gej(&Q, &Qj); secp256k1_pubkey_save(&sd, &Q); - CHECK(secp256k1_ec_pubkey_combine(ctx, &sd2, d, i) == 1); - CHECK(memcmp(&sd, &sd2, sizeof(sd)) == 0); + CHECK(secp256k1_ec_pubkey_combine(CTX, &sd2, d, i) == 1); + CHECK(secp256k1_memcmp_var(&sd, &sd2, sizeof(sd)) == 0); } } -void run_ec_combine(void) { +static void run_ec_combine(void) { int i; - for (i = 0; i < count * 8; i++) { + for (i = 0; i < COUNT * 8; i++) { test_ec_combine(); } } -void test_group_decompress(const secp256k1_fe* x) { +static void test_group_decompress(const secp256k1_fe* x) { /* The input itself, normalized. */ secp256k1_fe fex = *x; - secp256k1_fe fez; - /* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */ - secp256k1_ge ge_quad, ge_even, ge_odd; - secp256k1_gej gej_quad; + /* Results of set_xo_var(..., 0), set_xo_var(..., 1). */ + secp256k1_ge ge_even, ge_odd; /* Return values of the above calls. */ - int res_quad, res_even, res_odd; + int res_even, res_odd; secp256k1_fe_normalize_var(&fex); - res_quad = secp256k1_ge_set_xquad(&ge_quad, &fex); res_even = secp256k1_ge_set_xo_var(&ge_even, &fex, 0); res_odd = secp256k1_ge_set_xo_var(&ge_odd, &fex, 1); - CHECK(res_quad == res_even); - CHECK(res_quad == res_odd); + CHECK(res_even == res_odd); - if (res_quad) { - secp256k1_fe_normalize_var(&ge_quad.x); + if (res_even) { secp256k1_fe_normalize_var(&ge_odd.x); secp256k1_fe_normalize_var(&ge_even.x); - secp256k1_fe_normalize_var(&ge_quad.y); secp256k1_fe_normalize_var(&ge_odd.y); secp256k1_fe_normalize_var(&ge_even.y); /* No infinity allowed. */ - CHECK(!ge_quad.infinity); CHECK(!ge_even.infinity); CHECK(!ge_odd.infinity); /* Check that the x coordinates check out. */ - CHECK(secp256k1_fe_equal_var(&ge_quad.x, x)); - CHECK(secp256k1_fe_equal_var(&ge_even.x, x)); - CHECK(secp256k1_fe_equal_var(&ge_odd.x, x)); - - /* Check that the Y coordinate result in ge_quad is a square. */ - CHECK(secp256k1_fe_is_quad_var(&ge_quad.y)); + CHECK(secp256k1_fe_equal(&ge_even.x, x)); + CHECK(secp256k1_fe_equal(&ge_odd.x, x)); /* Check odd/even Y in ge_odd, ge_even. */ CHECK(secp256k1_fe_is_odd(&ge_odd.y)); CHECK(!secp256k1_fe_is_odd(&ge_even.y)); - - /* Check secp256k1_gej_has_quad_y_var. */ - secp256k1_gej_set_ge(&gej_quad, &ge_quad); - CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); - do { - random_fe_test(&fez); - } while (secp256k1_fe_is_zero(&fez)); - secp256k1_gej_rescale(&gej_quad, &fez); - CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); - secp256k1_gej_neg(&gej_quad, &gej_quad); - CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); - do { - random_fe_test(&fez); - } while (secp256k1_fe_is_zero(&fez)); - secp256k1_gej_rescale(&gej_quad, &fez); - CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); - secp256k1_gej_neg(&gej_quad, &gej_quad); - CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); } } -void run_group_decompress(void) { +static void run_group_decompress(void) { int i; - for (i = 0; i < count * 4; i++) { + for (i = 0; i < COUNT * 4; i++) { secp256k1_fe fe; - random_fe_test(&fe); + testutil_random_fe_test(&fe); test_group_decompress(&fe); } } /***** ECMULT TESTS *****/ -void run_ecmult_chain(void) { +static void test_pre_g_table(const secp256k1_ge_storage * pre_g, size_t n) { + /* Tests the pre_g / pre_g_128 tables for consistency. + * For independent verification we take a "geometric" approach to verification. + * We check that every entry is on-curve. + * We check that for consecutive entries p and q, that p + gg - q = 0 by checking + * (1) p, gg, and -q are colinear. + * (2) p, gg, and -q are all distinct. + * where gg is twice the generator, where the generator is the first table entry. + * + * Checking the table's generators are correct is done in run_ecmult_pre_g. + */ + secp256k1_gej g2; + secp256k1_ge p, q, gg; + secp256k1_fe dpx, dpy, dqx, dqy; + size_t i; + + CHECK(0 < n); + + secp256k1_ge_from_storage(&p, &pre_g[0]); + CHECK(secp256k1_ge_is_valid_var(&p)); + + secp256k1_gej_set_ge(&g2, &p); + secp256k1_gej_double_var(&g2, &g2, NULL); + secp256k1_ge_set_gej_var(&gg, &g2); + for (i = 1; i < n; ++i) { + secp256k1_fe_negate(&dpx, &p.x, 1); secp256k1_fe_add(&dpx, &gg.x); secp256k1_fe_normalize_weak(&dpx); + secp256k1_fe_negate(&dpy, &p.y, 1); secp256k1_fe_add(&dpy, &gg.y); secp256k1_fe_normalize_weak(&dpy); + /* Check that p is not equal to gg */ + CHECK(!secp256k1_fe_normalizes_to_zero_var(&dpx) || !secp256k1_fe_normalizes_to_zero_var(&dpy)); + + secp256k1_ge_from_storage(&q, &pre_g[i]); + CHECK(secp256k1_ge_is_valid_var(&q)); + + secp256k1_fe_negate(&dqx, &q.x, 1); secp256k1_fe_add(&dqx, &gg.x); + dqy = q.y; secp256k1_fe_add(&dqy, &gg.y); + /* Check that -q is not equal to gg */ + CHECK(!secp256k1_fe_normalizes_to_zero_var(&dqx) || !secp256k1_fe_normalizes_to_zero_var(&dqy)); + + /* Check that -q is not equal to p */ + CHECK(!secp256k1_fe_equal(&dpx, &dqx) || !secp256k1_fe_equal(&dpy, &dqy)); + + /* Check that p, -q and gg are colinear */ + secp256k1_fe_mul(&dpx, &dpx, &dqy); + secp256k1_fe_mul(&dpy, &dpy, &dqx); + CHECK(secp256k1_fe_equal(&dpx, &dpy)); + + p = q; + } +} + +static void run_ecmult_pre_g(void) { + secp256k1_ge_storage gs; + secp256k1_gej gj; + secp256k1_ge g; + size_t i; + + /* Check that the pre_g and pre_g_128 tables are consistent. */ + test_pre_g_table(secp256k1_pre_g, ECMULT_TABLE_SIZE(WINDOW_G)); + test_pre_g_table(secp256k1_pre_g_128, ECMULT_TABLE_SIZE(WINDOW_G)); + + /* Check the first entry from the pre_g table. */ + secp256k1_ge_to_storage(&gs, &secp256k1_ge_const_g); + CHECK(secp256k1_memcmp_var(&gs, &secp256k1_pre_g[0], sizeof(gs)) == 0); + + /* Check the first entry from the pre_g_128 table. */ + secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); + for (i = 0; i < 128; ++i) { + secp256k1_gej_double_var(&gj, &gj, NULL); + } + secp256k1_ge_set_gej(&g, &gj); + secp256k1_ge_to_storage(&gs, &g); + CHECK(secp256k1_memcmp_var(&gs, &secp256k1_pre_g_128[0], sizeof(gs)) == 0); +} + +static void run_ecmult_chain(void) { /* random starting point A (on the curve) */ secp256k1_gej a = SECP256K1_GEJ_CONST( 0x8b30bbe9, 0xae2a9906, 0x96b22f67, 0x0709dff3, @@ -2272,8 +4236,8 @@ void run_ecmult_chain(void) { static const secp256k1_scalar xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337); static const secp256k1_scalar gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113); /* accumulators with the resulting coefficients to A and G */ - secp256k1_scalar ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_scalar ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_scalar ae = secp256k1_scalar_one; + secp256k1_scalar ge = secp256k1_scalar_zero; /* actual points */ secp256k1_gej x; secp256k1_gej x2; @@ -2281,9 +4245,9 @@ void run_ecmult_chain(void) { /* the point being computed */ x = a; - for (i = 0; i < 200*count; i++) { + for (i = 0; i < 200*COUNT; i++) { /* in each iteration, compute X = xn*X + gn*G; */ - secp256k1_ecmult(&ctx->ecmult_ctx, &x, &x, &xn, &gn); + secp256k1_ecmult(&x, &x, &xn, &gn); /* also compute ae and ge: the actual accumulated factors for A and G */ /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */ secp256k1_scalar_mul(&ae, &ae, &xn); @@ -2302,36 +4266,28 @@ void run_ecmult_chain(void) { 0xB95CBCA2, 0xC77DA786, 0x539BE8FD, 0x53354D2D, 0x3B4F566A, 0xE6580454, 0x07ED6015, 0xEE1B2A88 ); - - secp256k1_gej_neg(&rp, &rp); - secp256k1_gej_add_var(&rp, &rp, &x, NULL); - CHECK(secp256k1_gej_is_infinity(&rp)); + CHECK(secp256k1_gej_eq_var(&rp, &x)); } } /* redo the computation, but directly with the resulting ae and ge coefficients: */ - secp256k1_ecmult(&ctx->ecmult_ctx, &x2, &a, &ae, &ge); - secp256k1_gej_neg(&x2, &x2); - secp256k1_gej_add_var(&x2, &x2, &x, NULL); - CHECK(secp256k1_gej_is_infinity(&x2)); + secp256k1_ecmult(&x2, &a, &ae, &ge); + CHECK(secp256k1_gej_eq_var(&x, &x2)); } -void test_point_times_order(const secp256k1_gej *point) { +static void test_point_times_order(const secp256k1_gej *point) { /* X * (point + G) + (order-X) * (pointer + G) = 0 */ secp256k1_scalar x; secp256k1_scalar nx; - secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); secp256k1_gej res1, res2; secp256k1_ge res3; unsigned char pub[65]; size_t psize = 65; - random_scalar_order_test(&x); + testutil_random_scalar_order_test(&x); secp256k1_scalar_negate(&nx, &x); - secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */ - secp256k1_ecmult(&ctx->ecmult_ctx, &res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ + secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */ + secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ secp256k1_gej_add_var(&res1, &res1, &res2, NULL); CHECK(secp256k1_gej_is_infinity(&res1)); - CHECK(secp256k1_gej_is_valid_var(&res1) == 0); secp256k1_ge_set_gej(&res3, &res1); CHECK(secp256k1_ge_is_infinity(&res3)); CHECK(secp256k1_ge_is_valid_var(&res3) == 0); @@ -2339,18 +4295,98 @@ void test_point_times_order(const secp256k1_gej *point) { psize = 65; CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0); /* check zero/one edge cases */ - secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &zero); + secp256k1_ecmult(&res1, point, &secp256k1_scalar_zero, &secp256k1_scalar_zero); secp256k1_ge_set_gej(&res3, &res1); CHECK(secp256k1_ge_is_infinity(&res3)); - secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &one, &zero); + secp256k1_ecmult(&res1, point, &secp256k1_scalar_one, &secp256k1_scalar_zero); secp256k1_ge_set_gej(&res3, &res1); - ge_equals_gej(&res3, point); - secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &one); + CHECK(secp256k1_gej_eq_ge_var(point, &res3)); + secp256k1_ecmult(&res1, point, &secp256k1_scalar_zero, &secp256k1_scalar_one); secp256k1_ge_set_gej(&res3, &res1); - ge_equals_ge(&res3, &secp256k1_ge_const_g); + CHECK(secp256k1_ge_eq_var(&secp256k1_ge_const_g, &res3)); } -void run_point_times_order(void) { +/* These scalars reach large (in absolute value) outputs when fed to secp256k1_scalar_split_lambda. + * + * They are computed as: + * - For a in [-2, -1, 0, 1, 2]: + * - For b in [-3, -1, 1, 3]: + * - Output (a*LAMBDA + (ORDER+b)/2) % ORDER + */ +static const secp256k1_scalar scalars_near_split_bounds[20] = { + SECP256K1_SCALAR_CONST(0xd938a566, 0x7f479e3e, 0xb5b3c7fa, 0xefdb3749, 0x3aa0585c, 0xc5ea2367, 0xe1b660db, 0x0209e6fc), + SECP256K1_SCALAR_CONST(0xd938a566, 0x7f479e3e, 0xb5b3c7fa, 0xefdb3749, 0x3aa0585c, 0xc5ea2367, 0xe1b660db, 0x0209e6fd), + SECP256K1_SCALAR_CONST(0xd938a566, 0x7f479e3e, 0xb5b3c7fa, 0xefdb3749, 0x3aa0585c, 0xc5ea2367, 0xe1b660db, 0x0209e6fe), + SECP256K1_SCALAR_CONST(0xd938a566, 0x7f479e3e, 0xb5b3c7fa, 0xefdb3749, 0x3aa0585c, 0xc5ea2367, 0xe1b660db, 0x0209e6ff), + SECP256K1_SCALAR_CONST(0x2c9c52b3, 0x3fa3cf1f, 0x5ad9e3fd, 0x77ed9ba5, 0xb294b893, 0x3722e9a5, 0x00e698ca, 0x4cf7632d), + SECP256K1_SCALAR_CONST(0x2c9c52b3, 0x3fa3cf1f, 0x5ad9e3fd, 0x77ed9ba5, 0xb294b893, 0x3722e9a5, 0x00e698ca, 0x4cf7632e), + SECP256K1_SCALAR_CONST(0x2c9c52b3, 0x3fa3cf1f, 0x5ad9e3fd, 0x77ed9ba5, 0xb294b893, 0x3722e9a5, 0x00e698ca, 0x4cf7632f), + SECP256K1_SCALAR_CONST(0x2c9c52b3, 0x3fa3cf1f, 0x5ad9e3fd, 0x77ed9ba5, 0xb294b893, 0x3722e9a5, 0x00e698ca, 0x4cf76330), + SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xd576e735, 0x57a4501d, 0xdfe92f46, 0x681b209f), + SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xd576e735, 0x57a4501d, 0xdfe92f46, 0x681b20a0), + SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xd576e735, 0x57a4501d, 0xdfe92f46, 0x681b20a1), + SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xd576e735, 0x57a4501d, 0xdfe92f46, 0x681b20a2), + SECP256K1_SCALAR_CONST(0xd363ad4c, 0xc05c30e0, 0xa5261c02, 0x88126459, 0xf85915d7, 0x7825b696, 0xbeebc5c2, 0x833ede11), + SECP256K1_SCALAR_CONST(0xd363ad4c, 0xc05c30e0, 0xa5261c02, 0x88126459, 0xf85915d7, 0x7825b696, 0xbeebc5c2, 0x833ede12), + SECP256K1_SCALAR_CONST(0xd363ad4c, 0xc05c30e0, 0xa5261c02, 0x88126459, 0xf85915d7, 0x7825b696, 0xbeebc5c2, 0x833ede13), + SECP256K1_SCALAR_CONST(0xd363ad4c, 0xc05c30e0, 0xa5261c02, 0x88126459, 0xf85915d7, 0x7825b696, 0xbeebc5c2, 0x833ede14), + SECP256K1_SCALAR_CONST(0x26c75a99, 0x80b861c1, 0x4a4c3805, 0x1024c8b4, 0x704d760e, 0xe95e7cd3, 0xde1bfdb1, 0xce2c5a42), + SECP256K1_SCALAR_CONST(0x26c75a99, 0x80b861c1, 0x4a4c3805, 0x1024c8b4, 0x704d760e, 0xe95e7cd3, 0xde1bfdb1, 0xce2c5a43), + SECP256K1_SCALAR_CONST(0x26c75a99, 0x80b861c1, 0x4a4c3805, 0x1024c8b4, 0x704d760e, 0xe95e7cd3, 0xde1bfdb1, 0xce2c5a44), + SECP256K1_SCALAR_CONST(0x26c75a99, 0x80b861c1, 0x4a4c3805, 0x1024c8b4, 0x704d760e, 0xe95e7cd3, 0xde1bfdb1, 0xce2c5a45) +}; + +static void test_ecmult_target(const secp256k1_scalar* target, int mode) { + /* Mode: 0=ecmult_gen, 1=ecmult, 2=ecmult_const */ + secp256k1_scalar n1, n2; + secp256k1_ge p; + secp256k1_gej pj, p1j, p2j, ptj; + + /* Generate random n1,n2 such that n1+n2 = -target. */ + testutil_random_scalar_order_test(&n1); + secp256k1_scalar_add(&n2, &n1, target); + secp256k1_scalar_negate(&n2, &n2); + + /* Generate a random input point. */ + if (mode != 0) { + testutil_random_ge_test(&p); + secp256k1_gej_set_ge(&pj, &p); + } + + /* EC multiplications */ + if (mode == 0) { + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &p1j, &n1); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &p2j, &n2); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &ptj, target); + } else if (mode == 1) { + secp256k1_ecmult(&p1j, &pj, &n1, &secp256k1_scalar_zero); + secp256k1_ecmult(&p2j, &pj, &n2, &secp256k1_scalar_zero); + secp256k1_ecmult(&ptj, &pj, target, &secp256k1_scalar_zero); + } else { + secp256k1_ecmult_const(&p1j, &p, &n1); + secp256k1_ecmult_const(&p2j, &p, &n2); + secp256k1_ecmult_const(&ptj, &p, target); + } + + /* Add them all up: n1*P + n2*P + target*P = (n1+n2+target)*P = (n1+n1-n1-n2)*P = 0. */ + secp256k1_gej_add_var(&ptj, &ptj, &p1j, NULL); + secp256k1_gej_add_var(&ptj, &ptj, &p2j, NULL); + CHECK(secp256k1_gej_is_infinity(&ptj)); +} + +static void run_ecmult_near_split_bound(void) { + int i; + unsigned j; + for (i = 0; i < 4*COUNT; ++i) { + for (j = 0; j < sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); ++j) { + test_ecmult_target(&scalars_near_split_bounds[j], 0); + test_ecmult_target(&scalars_near_split_bounds[j], 1); + test_ecmult_target(&scalars_near_split_bounds[j], 2); + } + } +} + +static void run_point_times_order(void) { int i; secp256k1_fe x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2); static const secp256k1_fe xr = SECP256K1_FE_CONST( @@ -2363,16 +4399,15 @@ void run_point_times_order(void) { secp256k1_gej j; CHECK(secp256k1_ge_is_valid_var(&p)); secp256k1_gej_set_ge(&j, &p); - CHECK(secp256k1_gej_is_valid_var(&j)); test_point_times_order(&j); } secp256k1_fe_sqr(&x, &x); } secp256k1_fe_normalize_var(&x); - CHECK(secp256k1_fe_equal_var(&x, &xr)); + CHECK(secp256k1_fe_equal(&x, &xr)); } -void ecmult_const_random_mult(void) { +static void ecmult_const_random_mult(void) { /* random starting point A (on the curve) */ secp256k1_ge a = SECP256K1_GE_CONST( 0x6d986544, 0x57ff52b8, 0xcf1b8126, 0x5b802a5b, @@ -2396,18 +4431,18 @@ void ecmult_const_random_mult(void) { secp256k1_ecmult_const(&b, &a, &xn); CHECK(secp256k1_ge_is_valid_var(&a)); - ge_equals_gej(&expected_b, &b); + CHECK(secp256k1_gej_eq_ge_var(&b, &expected_b)); } -void ecmult_const_commutativity(void) { +static void ecmult_const_commutativity(void) { secp256k1_scalar a; secp256k1_scalar b; secp256k1_gej res1; secp256k1_gej res2; secp256k1_ge mid1; secp256k1_ge mid2; - random_scalar_order_test(&a); - random_scalar_order_test(&b); + testutil_random_scalar_order_test(&a); + testutil_random_scalar_order_test(&b); secp256k1_ecmult_const(&res1, &secp256k1_ge_const_g, &a); secp256k1_ecmult_const(&res2, &secp256k1_ge_const_g, &b); @@ -2417,32 +4452,134 @@ void ecmult_const_commutativity(void) { secp256k1_ecmult_const(&res2, &mid2, &a); secp256k1_ge_set_gej(&mid1, &res1); secp256k1_ge_set_gej(&mid2, &res2); - ge_equals_ge(&mid1, &mid2); + CHECK(secp256k1_ge_eq_var(&mid1, &mid2)); } -void ecmult_const_mult_zero_one(void) { - secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); +static void ecmult_const_mult_zero_one(void) { + secp256k1_scalar s; secp256k1_scalar negone; secp256k1_gej res1; secp256k1_ge res2; secp256k1_ge point; - secp256k1_scalar_negate(&negone, &one); + secp256k1_ge inf; - random_group_element_test(&point); - secp256k1_ecmult_const(&res1, &point, &zero); + testutil_random_scalar_order_test(&s); + secp256k1_scalar_negate(&negone, &secp256k1_scalar_one); + testutil_random_ge_test(&point); + secp256k1_ge_set_infinity(&inf); + + /* 0*point */ + secp256k1_ecmult_const(&res1, &point, &secp256k1_scalar_zero); + CHECK(secp256k1_gej_is_infinity(&res1)); + + /* s*inf */ + secp256k1_ecmult_const(&res1, &inf, &s); + CHECK(secp256k1_gej_is_infinity(&res1)); + + /* 1*point */ + secp256k1_ecmult_const(&res1, &point, &secp256k1_scalar_one); secp256k1_ge_set_gej(&res2, &res1); - CHECK(secp256k1_ge_is_infinity(&res2)); - secp256k1_ecmult_const(&res1, &point, &one); - secp256k1_ge_set_gej(&res2, &res1); - ge_equals_ge(&res2, &point); + CHECK(secp256k1_ge_eq_var(&res2, &point)); + + /* -1*point */ secp256k1_ecmult_const(&res1, &point, &negone); secp256k1_gej_neg(&res1, &res1); secp256k1_ge_set_gej(&res2, &res1); - ge_equals_ge(&res2, &point); + CHECK(secp256k1_ge_eq_var(&res2, &point)); } -void ecmult_const_chain_multiply(void) { +static void ecmult_const_check_result(const secp256k1_ge *A, const secp256k1_scalar* q, const secp256k1_gej *res) { + secp256k1_gej pointj, res2j; + secp256k1_ge res2; + secp256k1_gej_set_ge(&pointj, A); + secp256k1_ecmult(&res2j, &pointj, q, &secp256k1_scalar_zero); + secp256k1_ge_set_gej(&res2, &res2j); + CHECK(secp256k1_gej_eq_ge_var(res, &res2)); +} + +static void ecmult_const_edges(void) { + secp256k1_scalar q; + secp256k1_ge point; + secp256k1_gej res; + size_t i; + size_t cases = 1 + sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); + + /* We are trying to reach the following edge cases (variables are defined as + * in ecmult_const_impl.h): + * 1. i = 0: s = 0 <=> q = -K + * 2. i > 0: v1, v2 large values + * <=> s1, s2 large values + * <=> s = scalars_near_split_bounds[i] + * <=> q = 2*scalars_near_split_bounds[i] - K + */ + for (i = 0; i < cases; ++i) { + secp256k1_scalar_negate(&q, &secp256k1_ecmult_const_K); + if (i > 0) { + secp256k1_scalar_add(&q, &q, &scalars_near_split_bounds[i - 1]); + secp256k1_scalar_add(&q, &q, &scalars_near_split_bounds[i - 1]); + } + testutil_random_ge_test(&point); + secp256k1_ecmult_const(&res, &point, &q); + ecmult_const_check_result(&point, &q, &res); + } +} + +static void ecmult_const_mult_xonly(void) { + int i; + + /* Test correspondence between secp256k1_ecmult_const and secp256k1_ecmult_const_xonly. */ + for (i = 0; i < 2*COUNT; ++i) { + secp256k1_ge base; + secp256k1_gej basej, resj; + secp256k1_fe n, d, resx, v; + secp256k1_scalar q; + int res; + /* Random base point. */ + testutil_random_ge_test(&base); + /* Random scalar to multiply it with. */ + testutil_random_scalar_order_test(&q); + /* If i is odd, n=d*base.x for random non-zero d */ + if (i & 1) { + testutil_random_fe_non_zero_test(&d); + secp256k1_fe_mul(&n, &base.x, &d); + } else { + n = base.x; + } + /* Perform x-only multiplication. */ + res = secp256k1_ecmult_const_xonly(&resx, &n, (i & 1) ? &d : NULL, &q, i & 2); + CHECK(res); + /* Perform normal multiplication. */ + secp256k1_gej_set_ge(&basej, &base); + secp256k1_ecmult(&resj, &basej, &q, NULL); + /* Check that resj's X coordinate corresponds with resx. */ + secp256k1_fe_sqr(&v, &resj.z); + secp256k1_fe_mul(&v, &v, &resx); + CHECK(fe_equal(&v, &resj.x)); + } + + /* Test that secp256k1_ecmult_const_xonly correctly rejects X coordinates not on curve. */ + for (i = 0; i < 2*COUNT; ++i) { + secp256k1_fe x, n, d, r; + int res; + secp256k1_scalar q; + testutil_random_scalar_order_test(&q); + /* Generate random X coordinate not on the curve. */ + do { + testutil_random_fe_test(&x); + } while (secp256k1_ge_x_on_curve_var(&x)); + /* If i is odd, n=d*x for random non-zero d. */ + if (i & 1) { + testutil_random_fe_non_zero_test(&d); + secp256k1_fe_mul(&n, &x, &d); + } else { + n = x; + } + res = secp256k1_ecmult_const_xonly(&r, &n, (i & 1) ? &d : NULL, &q, 0); + CHECK(res == 0); + } +} + +static void ecmult_const_chain_multiply(void) { /* Check known result (randomly generated test problem from sage) */ const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST( 0x4968d524, 0x2abf9b7a, 0x466abbcf, 0x34b11b6d, @@ -2465,17 +4602,639 @@ void ecmult_const_chain_multiply(void) { secp256k1_ecmult_const(&point, &tmp, &scalar); } secp256k1_ge_set_gej(&res, &point); - ge_equals_gej(&res, &expected_point); + CHECK(secp256k1_gej_eq_ge_var(&expected_point, &res)); } -void run_ecmult_const_tests(void) { +static void run_ecmult_const_tests(void) { ecmult_const_mult_zero_one(); + ecmult_const_edges(); ecmult_const_random_mult(); ecmult_const_commutativity(); ecmult_const_chain_multiply(); + ecmult_const_mult_xonly(); } -void test_wnaf(const secp256k1_scalar *number, int w) { +typedef struct { + secp256k1_scalar *sc; + secp256k1_ge *pt; +} ecmult_multi_data; + +static int ecmult_multi_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *cbdata) { + ecmult_multi_data *data = (ecmult_multi_data*) cbdata; + *sc = data->sc[idx]; + *pt = data->pt[idx]; + return 1; +} + +static int ecmult_multi_false_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *cbdata) { + (void)sc; + (void)pt; + (void)idx; + (void)cbdata; + return 0; +} + +static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func ecmult_multi) { + int ncount; + secp256k1_scalar sc[32]; + secp256k1_ge pt[32]; + secp256k1_gej r; + secp256k1_gej r2; + ecmult_multi_data data; + + data.sc = sc; + data.pt = pt; + + /* No points to multiply */ + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, NULL, ecmult_multi_callback, &data, 0)); + + /* Check 1- and 2-point multiplies against ecmult */ + for (ncount = 0; ncount < COUNT; ncount++) { + secp256k1_ge ptg; + secp256k1_gej ptgj; + testutil_random_scalar_order(&sc[0]); + testutil_random_scalar_order(&sc[1]); + + testutil_random_ge_test(&ptg); + secp256k1_gej_set_ge(&ptgj, &ptg); + pt[0] = ptg; + pt[1] = secp256k1_ge_const_g; + + /* only G scalar */ + secp256k1_ecmult(&r2, &ptgj, &secp256k1_scalar_zero, &sc[0]); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &sc[0], ecmult_multi_callback, &data, 0)); + CHECK(secp256k1_gej_eq_var(&r, &r2)); + + /* 1-point */ + secp256k1_ecmult(&r2, &ptgj, &sc[0], &secp256k1_scalar_zero); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 1)); + CHECK(secp256k1_gej_eq_var(&r, &r2)); + + /* Try to multiply 1 point, but callback returns false */ + CHECK(!ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_false_callback, &data, 1)); + + /* 2-point */ + secp256k1_ecmult(&r2, &ptgj, &sc[0], &sc[1]); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 2)); + CHECK(secp256k1_gej_eq_var(&r, &r2)); + + /* 2-point with G scalar */ + secp256k1_ecmult(&r2, &ptgj, &sc[0], &sc[1]); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &sc[1], ecmult_multi_callback, &data, 1)); + CHECK(secp256k1_gej_eq_var(&r, &r2)); + } + + /* Check infinite outputs of various forms */ + for (ncount = 0; ncount < COUNT; ncount++) { + secp256k1_ge ptg; + size_t i, j; + size_t sizes[] = { 2, 10, 32 }; + + for (j = 0; j < 3; j++) { + for (i = 0; i < 32; i++) { + testutil_random_scalar_order(&sc[i]); + secp256k1_ge_set_infinity(&pt[i]); + } + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, sizes[j])); + CHECK(secp256k1_gej_is_infinity(&r)); + } + + for (j = 0; j < 3; j++) { + for (i = 0; i < 32; i++) { + testutil_random_ge_test(&ptg); + pt[i] = ptg; + secp256k1_scalar_set_int(&sc[i], 0); + } + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, sizes[j])); + CHECK(secp256k1_gej_is_infinity(&r)); + } + + for (j = 0; j < 3; j++) { + testutil_random_ge_test(&ptg); + for (i = 0; i < 16; i++) { + testutil_random_scalar_order(&sc[2*i]); + secp256k1_scalar_negate(&sc[2*i + 1], &sc[2*i]); + pt[2 * i] = ptg; + pt[2 * i + 1] = ptg; + } + + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, sizes[j])); + CHECK(secp256k1_gej_is_infinity(&r)); + + testutil_random_scalar_order(&sc[0]); + for (i = 0; i < 16; i++) { + testutil_random_ge_test(&ptg); + + sc[2*i] = sc[0]; + sc[2*i+1] = sc[0]; + pt[2 * i] = ptg; + secp256k1_ge_neg(&pt[2*i+1], &pt[2*i]); + } + + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, sizes[j])); + CHECK(secp256k1_gej_is_infinity(&r)); + } + + testutil_random_ge_test(&ptg); + secp256k1_scalar_set_int(&sc[0], 0); + pt[0] = ptg; + for (i = 1; i < 32; i++) { + pt[i] = ptg; + + testutil_random_scalar_order(&sc[i]); + secp256k1_scalar_add(&sc[0], &sc[0], &sc[i]); + secp256k1_scalar_negate(&sc[i], &sc[i]); + } + + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 32)); + CHECK(secp256k1_gej_is_infinity(&r)); + } + + /* Check random points, constant scalar */ + for (ncount = 0; ncount < COUNT; ncount++) { + size_t i; + secp256k1_gej_set_infinity(&r); + + testutil_random_scalar_order(&sc[0]); + for (i = 0; i < 20; i++) { + secp256k1_ge ptg; + sc[i] = sc[0]; + testutil_random_ge_test(&ptg); + pt[i] = ptg; + secp256k1_gej_add_ge_var(&r, &r, &pt[i], NULL); + } + + secp256k1_ecmult(&r2, &r, &sc[0], &secp256k1_scalar_zero); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 20)); + CHECK(secp256k1_gej_eq_var(&r, &r2)); + } + + /* Check random scalars, constant point */ + for (ncount = 0; ncount < COUNT; ncount++) { + size_t i; + secp256k1_ge ptg; + secp256k1_gej p0j; + secp256k1_scalar rs; + secp256k1_scalar_set_int(&rs, 0); + + testutil_random_ge_test(&ptg); + for (i = 0; i < 20; i++) { + testutil_random_scalar_order(&sc[i]); + pt[i] = ptg; + secp256k1_scalar_add(&rs, &rs, &sc[i]); + } + + secp256k1_gej_set_ge(&p0j, &pt[0]); + secp256k1_ecmult(&r2, &p0j, &rs, &secp256k1_scalar_zero); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 20)); + CHECK(secp256k1_gej_eq_var(&r, &r2)); + } + + /* Sanity check that zero scalars don't cause problems */ + for (ncount = 0; ncount < 20; ncount++) { + testutil_random_scalar_order(&sc[ncount]); + testutil_random_ge_test(&pt[ncount]); + } + + secp256k1_scalar_set_int(&sc[0], 0); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 20)); + secp256k1_scalar_set_int(&sc[1], 0); + secp256k1_scalar_set_int(&sc[2], 0); + secp256k1_scalar_set_int(&sc[3], 0); + secp256k1_scalar_set_int(&sc[4], 0); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 6)); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 5)); + CHECK(secp256k1_gej_is_infinity(&r)); + + /* Run through s0*(t0*P) + s1*(t1*P) exhaustively for many small values of s0, s1, t0, t1 */ + { + const size_t TOP = 8; + size_t s0i, s1i; + size_t t0i, t1i; + secp256k1_ge ptg; + secp256k1_gej ptgj; + + testutil_random_ge_test(&ptg); + secp256k1_gej_set_ge(&ptgj, &ptg); + + for(t0i = 0; t0i < TOP; t0i++) { + for(t1i = 0; t1i < TOP; t1i++) { + secp256k1_gej t0p, t1p; + secp256k1_scalar t0, t1; + + secp256k1_scalar_set_int(&t0, (t0i + 1) / 2); + secp256k1_scalar_cond_negate(&t0, t0i & 1); + secp256k1_scalar_set_int(&t1, (t1i + 1) / 2); + secp256k1_scalar_cond_negate(&t1, t1i & 1); + + secp256k1_ecmult(&t0p, &ptgj, &t0, &secp256k1_scalar_zero); + secp256k1_ecmult(&t1p, &ptgj, &t1, &secp256k1_scalar_zero); + + for(s0i = 0; s0i < TOP; s0i++) { + for(s1i = 0; s1i < TOP; s1i++) { + secp256k1_scalar tmp1, tmp2; + secp256k1_gej expected, actual; + + secp256k1_ge_set_gej(&pt[0], &t0p); + secp256k1_ge_set_gej(&pt[1], &t1p); + + secp256k1_scalar_set_int(&sc[0], (s0i + 1) / 2); + secp256k1_scalar_cond_negate(&sc[0], s0i & 1); + secp256k1_scalar_set_int(&sc[1], (s1i + 1) / 2); + secp256k1_scalar_cond_negate(&sc[1], s1i & 1); + + secp256k1_scalar_mul(&tmp1, &t0, &sc[0]); + secp256k1_scalar_mul(&tmp2, &t1, &sc[1]); + secp256k1_scalar_add(&tmp1, &tmp1, &tmp2); + + secp256k1_ecmult(&expected, &ptgj, &tmp1, &secp256k1_scalar_zero); + CHECK(ecmult_multi(&CTX->error_callback, scratch, &actual, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 2)); + CHECK(secp256k1_gej_eq_var(&actual, &expected)); + } + } + } + } + } +} + +static int test_ecmult_multi_random(secp256k1_scratch *scratch) { + /* Large random test for ecmult_multi_* functions which exercises: + * - Few or many inputs (0 up to 128, roughly exponentially distributed). + * - Few or many 0*P or a*INF inputs (roughly uniformly distributed). + * - Including or excluding an nonzero a*G term (or such a term at all). + * - Final expected result equal to infinity or not (roughly 50%). + * - ecmult_multi_var, ecmult_strauss_single_batch, ecmult_pippenger_single_batch + */ + + /* These 4 variables define the eventual input to the ecmult_multi function. + * g_scalar is the G scalar fed to it (or NULL, possibly, if g_scalar=0), and + * scalars[0..filled-1] and gejs[0..filled-1] are the scalars and points + * which form its normal inputs. */ + int filled = 0; + secp256k1_scalar g_scalar = secp256k1_scalar_zero; + secp256k1_scalar scalars[128]; + secp256k1_gej gejs[128]; + /* The expected result, and the computed result. */ + secp256k1_gej expected, computed; + /* Temporaries. */ + secp256k1_scalar sc_tmp; + secp256k1_ge ge_tmp; + /* Variables needed for the actual input to ecmult_multi. */ + secp256k1_ge ges[128]; + ecmult_multi_data data; + + int i; + /* Which multiplication function to use */ + int fn = testrand_int(3); + secp256k1_ecmult_multi_func ecmult_multi = fn == 0 ? secp256k1_ecmult_multi_var : + fn == 1 ? secp256k1_ecmult_strauss_batch_single : + secp256k1_ecmult_pippenger_batch_single; + /* Simulate exponentially distributed num. */ + int num_bits = 2 + testrand_int(6); + /* Number of (scalar, point) inputs (excluding g). */ + int num = testrand_int((1 << num_bits) + 1); + /* Number of those which are nonzero. */ + int num_nonzero = testrand_int(num + 1); + /* Whether we're aiming to create an input with nonzero expected result. */ + int nonzero_result = testrand_bits(1); + /* Whether we will provide nonzero g multiplicand. In some cases our hand + * is forced here based on num_nonzero and nonzero_result. */ + int g_nonzero = num_nonzero == 0 ? nonzero_result : + num_nonzero == 1 && !nonzero_result ? 1 : + (int)testrand_bits(1); + /* Which g_scalar pointer to pass into ecmult_multi(). */ + const secp256k1_scalar* g_scalar_ptr = (g_nonzero || testrand_bits(1)) ? &g_scalar : NULL; + /* How many EC multiplications were performed in this function. */ + int mults = 0; + /* How many randomization steps to apply to the input list. */ + int rands = (int)testrand_bits(3); + if (rands > num_nonzero) rands = num_nonzero; + + secp256k1_gej_set_infinity(&expected); + secp256k1_gej_set_infinity(&gejs[0]); + secp256k1_scalar_set_int(&scalars[0], 0); + + if (g_nonzero) { + /* If g_nonzero, set g_scalar to nonzero value r. */ + testutil_random_scalar_order_test(&g_scalar); + if (!nonzero_result) { + /* If expected=0 is desired, add a (a*r, -(1/a)*g) term to compensate. */ + CHECK(num_nonzero > filled); + testutil_random_scalar_order_test(&sc_tmp); + secp256k1_scalar_mul(&scalars[filled], &sc_tmp, &g_scalar); + secp256k1_scalar_inverse_var(&sc_tmp, &sc_tmp); + secp256k1_scalar_negate(&sc_tmp, &sc_tmp); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &gejs[filled], &sc_tmp); + ++filled; + ++mults; + } + } + + if (nonzero_result && filled < num_nonzero) { + /* If a nonzero result is desired, and there is space, add a random nonzero term. */ + testutil_random_scalar_order_test(&scalars[filled]); + testutil_random_ge_test(&ge_tmp); + secp256k1_gej_set_ge(&gejs[filled], &ge_tmp); + ++filled; + } + + if (nonzero_result) { + /* Compute the expected result using normal ecmult. */ + CHECK(filled <= 1); + secp256k1_ecmult(&expected, &gejs[0], &scalars[0], &g_scalar); + mults += filled + g_nonzero; + } + + /* At this point we have expected = scalar_g*G + sum(scalars[i]*gejs[i] for i=0..filled-1). */ + CHECK(filled <= 1 + !nonzero_result); + CHECK(filled <= num_nonzero); + + /* Add entries to scalars,gejs so that there are num of them. All the added entries + * either have scalar=0 or point=infinity, so these do not change the expected result. */ + while (filled < num) { + if (testrand_bits(1)) { + secp256k1_gej_set_infinity(&gejs[filled]); + testutil_random_scalar_order_test(&scalars[filled]); + } else { + secp256k1_scalar_set_int(&scalars[filled], 0); + testutil_random_ge_test(&ge_tmp); + secp256k1_gej_set_ge(&gejs[filled], &ge_tmp); + } + ++filled; + } + + /* Now perform cheapish transformations on gejs and scalars, for indices + * 0..num_nonzero-1, which do not change the expected result, but may + * convert some of them to be both non-0-scalar and non-infinity-point. */ + for (i = 0; i < rands; ++i) { + int j; + secp256k1_scalar v, iv; + /* Shuffle the entries. */ + for (j = 0; j < num_nonzero; ++j) { + int k = testrand_int(num_nonzero - j); + if (k != 0) { + secp256k1_gej gej = gejs[j]; + secp256k1_scalar sc = scalars[j]; + gejs[j] = gejs[j + k]; + scalars[j] = scalars[j + k]; + gejs[j + k] = gej; + scalars[j + k] = sc; + } + } + /* Perturb all consecutive pairs of inputs: + * a*P + b*Q -> (a+b)*P + b*(Q-P). */ + for (j = 0; j + 1 < num_nonzero; j += 2) { + secp256k1_gej gej; + secp256k1_scalar_add(&scalars[j], &scalars[j], &scalars[j+1]); + secp256k1_gej_neg(&gej, &gejs[j]); + secp256k1_gej_add_var(&gejs[j+1], &gejs[j+1], &gej, NULL); + } + /* Transform the last input: a*P -> (v*a) * ((1/v)*P). */ + CHECK(num_nonzero >= 1); + testutil_random_scalar_order_test(&v); + secp256k1_scalar_inverse(&iv, &v); + secp256k1_scalar_mul(&scalars[num_nonzero - 1], &scalars[num_nonzero - 1], &v); + secp256k1_ecmult(&gejs[num_nonzero - 1], &gejs[num_nonzero - 1], &iv, NULL); + ++mults; + } + + /* Shuffle all entries (0..num-1). */ + for (i = 0; i < num; ++i) { + int j = testrand_int(num - i); + if (j != 0) { + secp256k1_gej gej = gejs[i]; + secp256k1_scalar sc = scalars[i]; + gejs[i] = gejs[i + j]; + scalars[i] = scalars[i + j]; + gejs[i + j] = gej; + scalars[i + j] = sc; + } + } + + /* Compute affine versions of all inputs. */ + secp256k1_ge_set_all_gej_var(ges, gejs, filled); + /* Invoke ecmult_multi code. */ + data.sc = scalars; + data.pt = ges; + CHECK(ecmult_multi(&CTX->error_callback, scratch, &computed, g_scalar_ptr, ecmult_multi_callback, &data, filled)); + mults += num_nonzero + g_nonzero; + /* Compare with expected result. */ + CHECK(secp256k1_gej_eq_var(&computed, &expected)); + return mults; +} + +static void test_ecmult_multi_batch_single(secp256k1_ecmult_multi_func ecmult_multi) { + secp256k1_scalar sc; + secp256k1_ge pt; + secp256k1_gej r; + ecmult_multi_data data; + secp256k1_scratch *scratch_empty; + + testutil_random_ge_test(&pt); + testutil_random_scalar_order(&sc); + data.sc = ≻ + data.pt = &pt; + + /* Try to multiply 1 point, but scratch space is empty.*/ + scratch_empty = secp256k1_scratch_create(&CTX->error_callback, 0); + CHECK(!ecmult_multi(&CTX->error_callback, scratch_empty, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, 1)); + secp256k1_scratch_destroy(&CTX->error_callback, scratch_empty); +} + +static void test_secp256k1_pippenger_bucket_window_inv(void) { + int i; + + CHECK(secp256k1_pippenger_bucket_window_inv(0) == 0); + for(i = 1; i <= PIPPENGER_MAX_BUCKET_WINDOW; i++) { + /* Bucket_window of 8 is not used with endo */ + if (i == 8) { + continue; + } + CHECK(secp256k1_pippenger_bucket_window(secp256k1_pippenger_bucket_window_inv(i)) == i); + if (i != PIPPENGER_MAX_BUCKET_WINDOW) { + CHECK(secp256k1_pippenger_bucket_window(secp256k1_pippenger_bucket_window_inv(i)+1) > i); + } + } +} + +/** + * Probabilistically test the function returning the maximum number of possible points + * for a given scratch space. + */ +static void test_ecmult_multi_pippenger_max_points(void) { + size_t scratch_size = testrand_bits(8); + size_t max_size = secp256k1_pippenger_scratch_size(secp256k1_pippenger_bucket_window_inv(PIPPENGER_MAX_BUCKET_WINDOW-1)+512, 12); + secp256k1_scratch *scratch; + size_t n_points_supported; + int bucket_window = 0; + + for(; scratch_size < max_size; scratch_size+=256) { + size_t i; + size_t total_alloc; + size_t checkpoint; + scratch = secp256k1_scratch_create(&CTX->error_callback, scratch_size); + CHECK(scratch != NULL); + checkpoint = secp256k1_scratch_checkpoint(&CTX->error_callback, scratch); + n_points_supported = secp256k1_pippenger_max_points(&CTX->error_callback, scratch); + if (n_points_supported == 0) { + secp256k1_scratch_destroy(&CTX->error_callback, scratch); + continue; + } + bucket_window = secp256k1_pippenger_bucket_window(n_points_supported); + /* allocate `total_alloc` bytes over `PIPPENGER_SCRATCH_OBJECTS` many allocations */ + total_alloc = secp256k1_pippenger_scratch_size(n_points_supported, bucket_window); + for (i = 0; i < PIPPENGER_SCRATCH_OBJECTS - 1; i++) { + CHECK(secp256k1_scratch_alloc(&CTX->error_callback, scratch, 1)); + total_alloc--; + } + CHECK(secp256k1_scratch_alloc(&CTX->error_callback, scratch, total_alloc)); + secp256k1_scratch_apply_checkpoint(&CTX->error_callback, scratch, checkpoint); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); + } + CHECK(bucket_window == PIPPENGER_MAX_BUCKET_WINDOW); +} + +static void test_ecmult_multi_batch_size_helper(void) { + size_t n_batches, n_batch_points, max_n_batch_points, n; + + max_n_batch_points = 0; + n = 1; + CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 0); + + max_n_batch_points = 1; + n = 0; + CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1); + CHECK(n_batches == 0); + CHECK(n_batch_points == 0); + + max_n_batch_points = 2; + n = 5; + CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1); + CHECK(n_batches == 3); + CHECK(n_batch_points == 2); + + max_n_batch_points = ECMULT_MAX_POINTS_PER_BATCH; + n = ECMULT_MAX_POINTS_PER_BATCH; + CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1); + CHECK(n_batches == 1); + CHECK(n_batch_points == ECMULT_MAX_POINTS_PER_BATCH); + + max_n_batch_points = ECMULT_MAX_POINTS_PER_BATCH + 1; + n = ECMULT_MAX_POINTS_PER_BATCH + 1; + CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1); + CHECK(n_batches == 2); + CHECK(n_batch_points == ECMULT_MAX_POINTS_PER_BATCH/2 + 1); + + max_n_batch_points = 1; + n = SIZE_MAX; + CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1); + CHECK(n_batches == SIZE_MAX); + CHECK(n_batch_points == 1); + + max_n_batch_points = 2; + n = SIZE_MAX; + CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1); + CHECK(n_batches == SIZE_MAX/2 + 1); + CHECK(n_batch_points == 2); +} + +/** + * Run secp256k1_ecmult_multi_var with num points and a scratch space restricted to + * 1 <= i <= num points. + */ +static void test_ecmult_multi_batching(void) { + static const int n_points = 2*ECMULT_PIPPENGER_THRESHOLD; + secp256k1_scalar scG; + secp256k1_scalar *sc = (secp256k1_scalar *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_scalar) * n_points); + secp256k1_ge *pt = (secp256k1_ge *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_ge) * n_points); + secp256k1_gej r; + secp256k1_gej r2; + ecmult_multi_data data; + int i; + secp256k1_scratch *scratch; + + secp256k1_gej_set_infinity(&r2); + + /* Get random scalars and group elements and compute result */ + testutil_random_scalar_order(&scG); + secp256k1_ecmult(&r2, &r2, &secp256k1_scalar_zero, &scG); + for(i = 0; i < n_points; i++) { + secp256k1_ge ptg; + secp256k1_gej ptgj; + testutil_random_ge_test(&ptg); + secp256k1_gej_set_ge(&ptgj, &ptg); + pt[i] = ptg; + testutil_random_scalar_order(&sc[i]); + secp256k1_ecmult(&ptgj, &ptgj, &sc[i], NULL); + secp256k1_gej_add_var(&r2, &r2, &ptgj, NULL); + } + data.sc = sc; + data.pt = pt; + secp256k1_gej_neg(&r2, &r2); + + /* Test with empty scratch space. It should compute the correct result using + * ecmult_mult_simple algorithm which doesn't require a scratch space. */ + scratch = secp256k1_scratch_create(&CTX->error_callback, 0); + CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); + secp256k1_gej_add_var(&r, &r, &r2, NULL); + CHECK(secp256k1_gej_is_infinity(&r)); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); + + /* Test with space for 1 point in pippenger. That's not enough because + * ecmult_multi selects strauss which requires more memory. It should + * therefore select the simple algorithm. */ + scratch = secp256k1_scratch_create(&CTX->error_callback, secp256k1_pippenger_scratch_size(1, 1) + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); + CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); + secp256k1_gej_add_var(&r, &r, &r2, NULL); + CHECK(secp256k1_gej_is_infinity(&r)); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); + + for(i = 1; i <= n_points; i++) { + if (i > ECMULT_PIPPENGER_THRESHOLD) { + int bucket_window = secp256k1_pippenger_bucket_window(i); + size_t scratch_size = secp256k1_pippenger_scratch_size(i, bucket_window); + scratch = secp256k1_scratch_create(&CTX->error_callback, scratch_size + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); + } else { + size_t scratch_size = secp256k1_strauss_scratch_size(i); + scratch = secp256k1_scratch_create(&CTX->error_callback, scratch_size + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); + } + CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); + secp256k1_gej_add_var(&r, &r, &r2, NULL); + CHECK(secp256k1_gej_is_infinity(&r)); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); + } + free(sc); + free(pt); +} + +static void run_ecmult_multi_tests(void) { + secp256k1_scratch *scratch; + int64_t todo = (int64_t)320 * COUNT; + + test_secp256k1_pippenger_bucket_window_inv(); + test_ecmult_multi_pippenger_max_points(); + scratch = secp256k1_scratch_create(&CTX->error_callback, 819200); + test_ecmult_multi(scratch, secp256k1_ecmult_multi_var); + test_ecmult_multi(NULL, secp256k1_ecmult_multi_var); + test_ecmult_multi(scratch, secp256k1_ecmult_pippenger_batch_single); + test_ecmult_multi_batch_single(secp256k1_ecmult_pippenger_batch_single); + test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single); + test_ecmult_multi_batch_single(secp256k1_ecmult_strauss_batch_single); + while (todo > 0) { + todo -= test_ecmult_multi_random(scratch); + } + secp256k1_scratch_destroy(&CTX->error_callback, scratch); + + /* Run test_ecmult_multi with space for exactly one point */ + scratch = secp256k1_scratch_create(&CTX->error_callback, secp256k1_strauss_scratch_size(1) + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); + test_ecmult_multi(scratch, secp256k1_ecmult_multi_var); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); + + test_ecmult_multi_batch_size_helper(); + test_ecmult_multi_batching(); +} + +static void test_wnaf(const secp256k1_scalar *number, int w) { secp256k1_scalar x, two, t; int wnaf[256]; int zeroes = -1; @@ -2509,43 +5268,23 @@ void test_wnaf(const secp256k1_scalar *number, int w) { CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */ } -void test_constant_wnaf_negate(const secp256k1_scalar *number) { - secp256k1_scalar neg1 = *number; - secp256k1_scalar neg2 = *number; - int sign1 = 1; - int sign2 = 1; - - if (!secp256k1_scalar_get_bits(&neg1, 0, 1)) { - secp256k1_scalar_negate(&neg1, &neg1); - sign1 = -1; - } - sign2 = secp256k1_scalar_cond_negate(&neg2, secp256k1_scalar_is_even(&neg2)); - CHECK(sign1 == sign2); - CHECK(secp256k1_scalar_eq(&neg1, &neg2)); -} - -void test_constant_wnaf(const secp256k1_scalar *number, int w) { +static void test_fixed_wnaf(const secp256k1_scalar *number, int w) { secp256k1_scalar x, shift; int wnaf[256] = {0}; int i; int skew; - secp256k1_scalar num = *number; + secp256k1_scalar num, unused; secp256k1_scalar_set_int(&x, 0); secp256k1_scalar_set_int(&shift, 1 << w); - /* With USE_ENDOMORPHISM on we only consider 128-bit numbers */ -#ifdef USE_ENDOMORPHISM - for (i = 0; i < 16; ++i) { - secp256k1_scalar_shr_int(&num, 8); - } -#endif - skew = secp256k1_wnaf_const(wnaf, num, w); + /* Make num a 128-bit scalar. */ + secp256k1_scalar_split_128(&num, &unused, number); + skew = secp256k1_wnaf_fixed(wnaf, &num, w); - for (i = WNAF_SIZE(w); i >= 0; --i) { + for (i = WNAF_SIZE(w)-1; i >= 0; --i) { secp256k1_scalar t; int v = wnaf[i]; - CHECK(v != 0); /* check nonzero */ - CHECK(v & 1); /* check parity */ + CHECK(v == 0 || v & 1); /* check parity */ CHECK(v > -(1 << w)); /* check range above */ CHECK(v < (1 << w)); /* check range below */ @@ -2558,27 +5297,88 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) { } secp256k1_scalar_add(&x, &x, &t); } - /* Skew num because when encoding numbers as odd we use an offset */ - secp256k1_scalar_cadd_bit(&num, skew == 2, 1); + /* If skew is 1 then add 1 to num */ + secp256k1_scalar_cadd_bit(&num, 0, skew == 1); CHECK(secp256k1_scalar_eq(&x, &num)); } -void run_wnaf(void) { +/* Checks that the first 8 elements of wnaf are equal to wnaf_expected and the + * rest is 0.*/ +static void test_fixed_wnaf_small_helper(int *wnaf, int *wnaf_expected, int w) { int i; - secp256k1_scalar n = {{0}}; + for (i = WNAF_SIZE(w)-1; i >= 8; --i) { + CHECK(wnaf[i] == 0); + } + for (i = 7; i >= 0; --i) { + CHECK(wnaf[i] == wnaf_expected[i]); + } +} - /* Sanity check: 1 and 2 are the smallest odd and even numbers and should - * have easier-to-diagnose failure modes */ - n.d[0] = 1; - test_constant_wnaf(&n, 4); - n.d[0] = 2; - test_constant_wnaf(&n, 4); +static void test_fixed_wnaf_small(void) { + int w = 4; + int wnaf[256] = {0}; + int i; + int skew; + secp256k1_scalar num; + + secp256k1_scalar_set_int(&num, 0); + skew = secp256k1_wnaf_fixed(wnaf, &num, w); + for (i = WNAF_SIZE(w)-1; i >= 0; --i) { + int v = wnaf[i]; + CHECK(v == 0); + } + CHECK(skew == 0); + + secp256k1_scalar_set_int(&num, 1); + skew = secp256k1_wnaf_fixed(wnaf, &num, w); + for (i = WNAF_SIZE(w)-1; i >= 1; --i) { + int v = wnaf[i]; + CHECK(v == 0); + } + CHECK(wnaf[0] == 1); + CHECK(skew == 0); + + { + int wnaf_expected[8] = { 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf }; + secp256k1_scalar_set_int(&num, 0xffffffff); + skew = secp256k1_wnaf_fixed(wnaf, &num, w); + test_fixed_wnaf_small_helper(wnaf, wnaf_expected, w); + CHECK(skew == 0); + } + { + int wnaf_expected[8] = { -1, -1, -1, -1, -1, -1, -1, 0xf }; + secp256k1_scalar_set_int(&num, 0xeeeeeeee); + skew = secp256k1_wnaf_fixed(wnaf, &num, w); + test_fixed_wnaf_small_helper(wnaf, wnaf_expected, w); + CHECK(skew == 1); + } + { + int wnaf_expected[8] = { 1, 0, 1, 0, 1, 0, 1, 0 }; + secp256k1_scalar_set_int(&num, 0x01010101); + skew = secp256k1_wnaf_fixed(wnaf, &num, w); + test_fixed_wnaf_small_helper(wnaf, wnaf_expected, w); + CHECK(skew == 0); + } + { + int wnaf_expected[8] = { -0xf, 0, 0xf, -0xf, 0, 0xf, 1, 0 }; + secp256k1_scalar_set_int(&num, 0x01ef1ef1); + skew = secp256k1_wnaf_fixed(wnaf, &num, w); + test_fixed_wnaf_small_helper(wnaf, wnaf_expected, w); + CHECK(skew == 0); + } +} + +static void run_wnaf(void) { + int i; + secp256k1_scalar n; + + /* Test 0 for fixed wnaf */ + test_fixed_wnaf_small(); /* Random tests */ - for (i = 0; i < count; i++) { - random_scalar_order(&n); + for (i = 0; i < COUNT; i++) { + testutil_random_scalar_order(&n); test_wnaf(&n, 4+(i%10)); - test_constant_wnaf_negate(&n); - test_constant_wnaf(&n, 4 + (i % 10)); + test_fixed_wnaf(&n, 4 + (i % 10)); } secp256k1_scalar_set_int(&n, 0); CHECK(secp256k1_scalar_cond_negate(&n, 1) == -1); @@ -2587,96 +5387,243 @@ void run_wnaf(void) { CHECK(secp256k1_scalar_is_zero(&n)); } -void test_ecmult_constants(void) { - /* Test ecmult_gen() for [0..36) and [order-36..0). */ +static int test_ecmult_accumulate_cb(secp256k1_scalar* sc, secp256k1_ge* pt, size_t idx, void* data) { + const secp256k1_scalar* indata = (const secp256k1_scalar*)data; + *sc = *indata; + *pt = secp256k1_ge_const_g; + CHECK(idx == 0); + return 1; +} + +static void test_ecmult_accumulate(secp256k1_sha256* acc, const secp256k1_scalar* x, secp256k1_scratch* scratch) { + /* Compute x*G in 6 different ways, serialize it uncompressed, and feed it into acc. */ + secp256k1_gej rj1, rj2, rj3, rj4, rj5, rj6, gj, infj; + secp256k1_ge r; + unsigned char bytes[65]; + size_t size = 65; + secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); + secp256k1_gej_set_infinity(&infj); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &rj1, x); + secp256k1_ecmult(&rj2, &gj, x, &secp256k1_scalar_zero); + secp256k1_ecmult(&rj3, &infj, &secp256k1_scalar_zero, x); + CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &rj4, x, NULL, NULL, 0)); + CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1)); + secp256k1_ecmult_const(&rj6, &secp256k1_ge_const_g, x); + secp256k1_ge_set_gej_var(&r, &rj1); + CHECK(secp256k1_gej_eq_ge_var(&rj2, &r)); + CHECK(secp256k1_gej_eq_ge_var(&rj3, &r)); + CHECK(secp256k1_gej_eq_ge_var(&rj4, &r)); + CHECK(secp256k1_gej_eq_ge_var(&rj5, &r)); + CHECK(secp256k1_gej_eq_ge_var(&rj6, &r)); + if (secp256k1_ge_is_infinity(&r)) { + /* Store infinity as 0x00 */ + const unsigned char zerobyte[1] = {0}; + secp256k1_sha256_write(acc, zerobyte, 1); + } else { + /* Store other points using their uncompressed serialization. */ + secp256k1_eckey_pubkey_serialize(&r, bytes, &size, 0); + CHECK(size == 65); + secp256k1_sha256_write(acc, bytes, size); + } +} + +static void test_ecmult_constants_2bit(void) { + /* Using test_ecmult_accumulate, test ecmult for: + * - For i in 0..36: + * - Key i + * - Key -i + * - For i in 0..255: + * - For j in 1..255 (only odd values): + * - Key (j*2^i) mod order + */ secp256k1_scalar x; - secp256k1_gej r; - secp256k1_ge ng; - int i; - int j; - secp256k1_ge_neg(&ng, &secp256k1_ge_const_g); - for (i = 0; i < 36; i++ ) { - secp256k1_scalar_set_int(&x, i); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x); - for (j = 0; j < i; j++) { - if (j == i - 1) { - ge_equals_gej(&secp256k1_ge_const_g, &r); - } - secp256k1_gej_add_ge(&r, &r, &ng); - } - CHECK(secp256k1_gej_is_infinity(&r)); - } - for (i = 1; i <= 36; i++ ) { + secp256k1_sha256 acc; + unsigned char b32[32]; + int i, j; + secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(CTX, 65536); + + /* Expected hash of all the computed points; created with an independent + * implementation. */ + static const unsigned char expected32[32] = { + 0xe4, 0x71, 0x1b, 0x4d, 0x14, 0x1e, 0x68, 0x48, + 0xb7, 0xaf, 0x47, 0x2b, 0x4c, 0xd2, 0x04, 0x14, + 0x3a, 0x75, 0x87, 0x60, 0x1a, 0xf9, 0x63, 0x60, + 0xd0, 0xcb, 0x1f, 0xaa, 0x85, 0x9a, 0xb7, 0xb4 + }; + secp256k1_sha256_initialize(&acc); + for (i = 0; i <= 36; ++i) { secp256k1_scalar_set_int(&x, i); + test_ecmult_accumulate(&acc, &x, scratch); secp256k1_scalar_negate(&x, &x); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x); - for (j = 0; j < i; j++) { - if (j == i - 1) { - ge_equals_gej(&ng, &r); - } - secp256k1_gej_add_ge(&r, &r, &secp256k1_ge_const_g); + test_ecmult_accumulate(&acc, &x, scratch); + }; + for (i = 0; i < 256; ++i) { + for (j = 1; j < 256; j += 2) { + int k; + secp256k1_scalar_set_int(&x, j); + for (k = 0; k < i; ++k) secp256k1_scalar_add(&x, &x, &x); + test_ecmult_accumulate(&acc, &x, scratch); } - CHECK(secp256k1_gej_is_infinity(&r)); + } + secp256k1_sha256_finalize(&acc, b32); + CHECK(secp256k1_memcmp_var(b32, expected32, 32) == 0); + + secp256k1_scratch_space_destroy(CTX, scratch); +} + +static void test_ecmult_constants_sha(uint32_t prefix, size_t iter, const unsigned char* expected32) { + /* Using test_ecmult_accumulate, test ecmult for: + * - Key 0 + * - Key 1 + * - Key -1 + * - For i in range(iter): + * - Key SHA256(LE32(prefix) || LE16(i)) + */ + secp256k1_scalar x; + secp256k1_sha256 acc; + unsigned char b32[32]; + unsigned char inp[6]; + size_t i; + secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(CTX, 65536); + + inp[0] = prefix & 0xFF; + inp[1] = (prefix >> 8) & 0xFF; + inp[2] = (prefix >> 16) & 0xFF; + inp[3] = (prefix >> 24) & 0xFF; + secp256k1_sha256_initialize(&acc); + secp256k1_scalar_set_int(&x, 0); + test_ecmult_accumulate(&acc, &x, scratch); + secp256k1_scalar_set_int(&x, 1); + test_ecmult_accumulate(&acc, &x, scratch); + secp256k1_scalar_negate(&x, &x); + test_ecmult_accumulate(&acc, &x, scratch); + + for (i = 0; i < iter; ++i) { + secp256k1_sha256 gen; + inp[4] = i & 0xff; + inp[5] = (i >> 8) & 0xff; + secp256k1_sha256_initialize(&gen); + secp256k1_sha256_write(&gen, inp, sizeof(inp)); + secp256k1_sha256_finalize(&gen, b32); + secp256k1_scalar_set_b32(&x, b32, NULL); + test_ecmult_accumulate(&acc, &x, scratch); + } + secp256k1_sha256_finalize(&acc, b32); + CHECK(secp256k1_memcmp_var(b32, expected32, 32) == 0); + + secp256k1_scratch_space_destroy(CTX, scratch); +} + +static void run_ecmult_constants(void) { + /* Expected hashes of all points in the tests below. Computed using an + * independent implementation. */ + static const unsigned char expected32_6bit20[32] = { + 0x68, 0xb6, 0xed, 0x6f, 0x28, 0xca, 0xc9, 0x7f, + 0x8e, 0x8b, 0xd6, 0xc0, 0x61, 0x79, 0x34, 0x6e, + 0x5a, 0x8f, 0x2b, 0xbc, 0x3e, 0x1f, 0xc5, 0x2e, + 0x2a, 0xd0, 0x45, 0x67, 0x7f, 0x95, 0x95, 0x8e + }; + static const unsigned char expected32_8bit8[32] = { + 0x8b, 0x65, 0x8e, 0xea, 0x86, 0xae, 0x3c, 0x95, + 0x90, 0xb6, 0x77, 0xa4, 0x8c, 0x76, 0xd9, 0xec, + 0xf5, 0xab, 0x8a, 0x2f, 0xfd, 0xdb, 0x19, 0x12, + 0x1a, 0xee, 0xe6, 0xb7, 0x6e, 0x05, 0x3f, 0xc6 + }; + /* For every combination of 6 bit positions out of 256, restricted to + * 20-bit windows (i.e., the first and last bit position are no more than + * 19 bits apart), all 64 bit patterns occur in the input scalars used in + * this test. */ + CONDITIONAL_TEST(1, "test_ecmult_constants_sha 1024") { + test_ecmult_constants_sha(4808378u, 1024, expected32_6bit20); + } + + /* For every combination of 8 consecutive bit positions, all 256 bit + * patterns occur in the input scalars used in this test. */ + CONDITIONAL_TEST(3, "test_ecmult_constants_sha 2048") { + test_ecmult_constants_sha(1607366309u, 2048, expected32_8bit8); + } + + CONDITIONAL_TEST(16, "test_ecmult_constants_2bit") { + test_ecmult_constants_2bit(); } } -void run_ecmult_constants(void) { - test_ecmult_constants(); -} - -void test_ecmult_gen_blind(void) { +static void test_ecmult_gen_blind(void) { /* Test ecmult_gen() blinding and confirm that the blinding changes, the affine points match, and the z's don't match. */ secp256k1_scalar key; secp256k1_scalar b; unsigned char seed32[32]; secp256k1_gej pgej; secp256k1_gej pgej2; - secp256k1_gej i; + secp256k1_ge p; secp256k1_ge pge; - random_scalar_order_test(&key); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej, &key); - secp256k1_rand256(seed32); - b = ctx->ecmult_gen_ctx.blind; - i = ctx->ecmult_gen_ctx.initial; - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); - CHECK(!secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind)); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej2, &key); + testutil_random_scalar_order_test(&key); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &pgej, &key); + testrand256(seed32); + b = CTX->ecmult_gen_ctx.scalar_offset; + p = CTX->ecmult_gen_ctx.ge_offset; + secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, seed32); + CHECK(!secp256k1_scalar_eq(&b, &CTX->ecmult_gen_ctx.scalar_offset)); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &pgej2, &key); CHECK(!gej_xyz_equals_gej(&pgej, &pgej2)); - CHECK(!gej_xyz_equals_gej(&i, &ctx->ecmult_gen_ctx.initial)); + CHECK(!secp256k1_ge_eq_var(&p, &CTX->ecmult_gen_ctx.ge_offset)); secp256k1_ge_set_gej(&pge, &pgej); - ge_equals_gej(&pge, &pgej2); + CHECK(secp256k1_gej_eq_ge_var(&pgej2, &pge)); } -void test_ecmult_gen_blind_reset(void) { +static void test_ecmult_gen_blind_reset(void) { /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */ secp256k1_scalar b; - secp256k1_gej initial; - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0); - b = ctx->ecmult_gen_ctx.blind; - initial = ctx->ecmult_gen_ctx.initial; - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0); - CHECK(secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind)); - CHECK(gej_xyz_equals_gej(&initial, &ctx->ecmult_gen_ctx.initial)); + secp256k1_ge p1, p2; + secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, 0); + b = CTX->ecmult_gen_ctx.scalar_offset; + p1 = CTX->ecmult_gen_ctx.ge_offset; + secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, 0); + CHECK(secp256k1_scalar_eq(&b, &CTX->ecmult_gen_ctx.scalar_offset)); + p2 = CTX->ecmult_gen_ctx.ge_offset; + CHECK(secp256k1_ge_eq_var(&p1, &p2)); } -void run_ecmult_gen_blind(void) { +/* Verify that ecmult_gen for scalars gn for which gn + scalar_offset = {-1,0,1}. */ +static void test_ecmult_gen_edge_cases(void) { + int i; + secp256k1_gej res1, res2, res3; + secp256k1_scalar gn = secp256k1_scalar_one; /* gn = 1 */ + secp256k1_scalar_add(&gn, &gn, &CTX->ecmult_gen_ctx.scalar_offset); /* gn = 1 + scalar_offset */ + secp256k1_scalar_negate(&gn, &gn); /* gn = -1 - scalar_offset */ + + for (i = -1; i < 2; ++i) { + /* Run test with gn = i - scalar_offset (so that the ecmult_gen recoded value represents i). */ + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &res1, &gn); + secp256k1_ecmult(&res2, NULL, &secp256k1_scalar_zero, &gn); + secp256k1_ecmult_const(&res3, &secp256k1_ge_const_g, &gn); + CHECK(secp256k1_gej_eq_var(&res1, &res2)); + CHECK(secp256k1_gej_eq_var(&res1, &res3)); + secp256k1_scalar_add(&gn, &gn, &secp256k1_scalar_one); + } +} + +static void run_ecmult_gen_blind(void) { int i; test_ecmult_gen_blind_reset(); + test_ecmult_gen_edge_cases(); for (i = 0; i < 10; i++) { test_ecmult_gen_blind(); } } -#ifdef USE_ENDOMORPHISM /***** ENDOMORPHISH TESTS *****/ -void test_scalar_split(void) { - secp256k1_scalar full; - secp256k1_scalar s1, slam; +static void test_scalar_split(const secp256k1_scalar* full) { + secp256k1_scalar s, s1, slam; const unsigned char zero[32] = {0}; unsigned char tmp[32]; - random_scalar_order_test(&full); - secp256k1_scalar_split_lambda(&s1, &slam, &full); + secp256k1_scalar_split_lambda(&s1, &slam, full); + + /* check slam*lambda + s1 == full */ + secp256k1_scalar_mul(&s, &secp256k1_const_lambda, &slam); + secp256k1_scalar_add(&s, &s, &s1); + CHECK(secp256k1_scalar_eq(&s, full)); /* check that both are <= 128 bits in size */ if (secp256k1_scalar_is_high(&s1)) { @@ -2687,29 +5634,44 @@ void test_scalar_split(void) { } secp256k1_scalar_get_b32(tmp, &s1); - CHECK(memcmp(zero, tmp, 16) == 0); + CHECK(secp256k1_memcmp_var(zero, tmp, 16) == 0); secp256k1_scalar_get_b32(tmp, &slam); - CHECK(memcmp(zero, tmp, 16) == 0); + CHECK(secp256k1_memcmp_var(zero, tmp, 16) == 0); } -void run_endomorphism_tests(void) { - test_scalar_split(); -} -#endif -void ec_pubkey_parse_pointtest(const unsigned char *input, int xvalid, int yvalid) { +static void run_endomorphism_tests(void) { + unsigned i; + static secp256k1_scalar s; + test_scalar_split(&secp256k1_scalar_zero); + test_scalar_split(&secp256k1_scalar_one); + secp256k1_scalar_negate(&s,&secp256k1_scalar_one); + test_scalar_split(&s); + test_scalar_split(&secp256k1_const_lambda); + secp256k1_scalar_add(&s, &secp256k1_const_lambda, &secp256k1_scalar_one); + test_scalar_split(&s); + + for (i = 0; i < 100U * COUNT; ++i) { + secp256k1_scalar full; + testutil_random_scalar_order_test(&full); + test_scalar_split(&full); + } + for (i = 0; i < sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); ++i) { + test_scalar_split(&scalars_near_split_bounds[i]); + } +} + +static void ec_pubkey_parse_pointtest(const unsigned char *input, int xvalid, int yvalid) { unsigned char pubkeyc[65]; secp256k1_pubkey pubkey; secp256k1_ge ge; size_t pubkeyclen; - int32_t ecount; - ecount = 0; - secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + for (pubkeyclen = 3; pubkeyclen <= 65; pubkeyclen++) { /* Smaller sizes are tested exhaustively elsewhere. */ int32_t i; memcpy(&pubkeyc[1], input, 64); - VG_UNDEF(&pubkeyc[pubkeyclen], 65 - pubkeyclen); + SECP256K1_CHECKMEM_UNDEFINE(&pubkeyc[pubkeyclen], 65 - pubkeyclen); for (i = 0; i < 256; i++) { /* Try all type bytes. */ int xpass; @@ -2728,51 +5690,45 @@ void ec_pubkey_parse_pointtest(const unsigned char *input, int xvalid, int yvali unsigned char pubkeyo[65]; size_t outl; memset(&pubkey, 0, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - ecount = 0; - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pubkeyc, pubkeyclen) == 1); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); outl = 65; - VG_UNDEF(pubkeyo, 65); - CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_COMPRESSED) == 1); - VG_CHECK(pubkeyo, outl); + SECP256K1_CHECKMEM_UNDEFINE(pubkeyo, 65); + CHECK(secp256k1_ec_pubkey_serialize(CTX, pubkeyo, &outl, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + SECP256K1_CHECKMEM_CHECK(pubkeyo, outl); CHECK(outl == 33); - CHECK(memcmp(&pubkeyo[1], &pubkeyc[1], 32) == 0); + CHECK(secp256k1_memcmp_var(&pubkeyo[1], &pubkeyc[1], 32) == 0); CHECK((pubkeyclen != 33) || (pubkeyo[0] == pubkeyc[0])); if (ypass) { /* This test isn't always done because we decode with alternative signs, so the y won't match. */ CHECK(pubkeyo[0] == ysign); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1); + CHECK(secp256k1_pubkey_load(CTX, &ge, &pubkey) == 1); memset(&pubkey, 0, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); secp256k1_pubkey_save(&pubkey, &ge); - VG_CHECK(&pubkey, sizeof(pubkey)); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); outl = 65; - VG_UNDEF(pubkeyo, 65); - CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); - VG_CHECK(pubkeyo, outl); + SECP256K1_CHECKMEM_UNDEFINE(pubkeyo, 65); + CHECK(secp256k1_ec_pubkey_serialize(CTX, pubkeyo, &outl, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); + SECP256K1_CHECKMEM_CHECK(pubkeyo, outl); CHECK(outl == 65); CHECK(pubkeyo[0] == 4); - CHECK(memcmp(&pubkeyo[1], input, 64) == 0); + CHECK(secp256k1_memcmp_var(&pubkeyo[1], input, 64) == 0); } - CHECK(ecount == 0); } else { /* These cases must fail to parse. */ memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pubkeyc, pubkeyclen) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_pubkey_load(CTX, &ge, &pubkey)); } } } - secp256k1_context_set_illegal_callback(ctx, NULL, NULL); } -void run_ec_pubkey_parse_test(void) { +static void run_ec_pubkey_parse_test(void) { #define SECP256K1_EC_PARSE_TEST_NVALID (12) const unsigned char valid[SECP256K1_EC_PARSE_TEST_NVALID][64] = { { @@ -2952,141 +5908,99 @@ void run_ec_pubkey_parse_test(void) { 0xB8, 0x00 }; unsigned char sout[65]; - unsigned char shortkey[2]; + unsigned char shortkey[2] = { 0 }; secp256k1_ge ge; secp256k1_pubkey pubkey; size_t len; int32_t i; - int32_t ecount; - int32_t ecount2; - ecount = 0; + /* Nothing should be reading this far into pubkeyc. */ - VG_UNDEF(&pubkeyc[65], 1); - secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + SECP256K1_CHECKMEM_UNDEFINE(&pubkeyc[65], 1); /* Zero length claimed, fail, zeroize, no illegal arg error. */ memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(shortkey, 2); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 0) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); + SECP256K1_CHECKMEM_UNDEFINE(shortkey, 2); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, shortkey, 0) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_pubkey_load(CTX, &ge, &pubkey)); /* Length one claimed, fail, zeroize, no illegal arg error. */ for (i = 0; i < 256 ; i++) { memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; shortkey[0] = i; - VG_UNDEF(&shortkey[1], 1); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 1) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); + SECP256K1_CHECKMEM_UNDEFINE(&shortkey[1], 1); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, shortkey, 1) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_pubkey_load(CTX, &ge, &pubkey)); } /* Length two claimed, fail, zeroize, no illegal arg error. */ for (i = 0; i < 65536 ; i++) { memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; shortkey[0] = i & 255; shortkey[1] = i >> 8; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 2) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, shortkey, 2) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_pubkey_load(CTX, &ge, &pubkey)); } memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); /* 33 bytes claimed on otherwise valid input starting with 0x04, fail, zeroize output, no illegal arg error. */ - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 33) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pubkeyc, 33) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_pubkey_load(CTX, &ge, &pubkey)); /* NULL pubkey, illegal arg error. Pubkey isn't rewritten before this step, since it's NULL into the parser. */ - CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, pubkeyc, 65) == 0); - CHECK(ecount == 2); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_parse(CTX, NULL, pubkeyc, 65)); /* NULL input string. Illegal arg and zeroize output. */ memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, NULL, 65) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 1); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 2); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_parse(CTX, &pubkey, NULL, 65)); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_pubkey_load(CTX, &ge, &pubkey)); /* 64 bytes claimed on input starting with 0x04, fail, zeroize output, no illegal arg error. */ memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 64) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pubkeyc, 64) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_pubkey_load(CTX, &ge, &pubkey)); /* 66 bytes claimed, fail, zeroize output, no illegal arg error. */ memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 66) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pubkeyc, 66) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_pubkey_load(CTX, &ge, &pubkey)); /* Valid parse. */ memset(&pubkey, 0, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 65) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - VG_UNDEF(&ge, sizeof(ge)); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1); - VG_CHECK(&ge.x, sizeof(ge.x)); - VG_CHECK(&ge.y, sizeof(ge.y)); - VG_CHECK(&ge.infinity, sizeof(ge.infinity)); - ge_equals_ge(&secp256k1_ge_const_g, &ge); - CHECK(ecount == 0); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pubkeyc, 65) == 1); + CHECK(secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, pubkeyc, 65) == 1); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + SECP256K1_CHECKMEM_UNDEFINE(&ge, sizeof(ge)); + CHECK(secp256k1_pubkey_load(CTX, &ge, &pubkey) == 1); + SECP256K1_CHECKMEM_CHECK(&ge.x, sizeof(ge.x)); + SECP256K1_CHECKMEM_CHECK(&ge.y, sizeof(ge.y)); + SECP256K1_CHECKMEM_CHECK(&ge.infinity, sizeof(ge.infinity)); + CHECK(secp256k1_ge_eq_var(&ge, &secp256k1_ge_const_g)); /* secp256k1_ec_pubkey_serialize illegal args. */ - ecount = 0; len = 65; - CHECK(secp256k1_ec_pubkey_serialize(ctx, NULL, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 0); - CHECK(ecount == 1); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_serialize(CTX, NULL, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED)); CHECK(len == 0); - CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, NULL, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 0); - CHECK(ecount == 2); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_serialize(CTX, sout, NULL, &pubkey, SECP256K1_EC_UNCOMPRESSED)); len = 65; - VG_UNDEF(sout, 65); - CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, NULL, SECP256K1_EC_UNCOMPRESSED) == 0); - VG_CHECK(sout, 65); - CHECK(ecount == 3); + SECP256K1_CHECKMEM_UNDEFINE(sout, 65); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_serialize(CTX, sout, &len, NULL, SECP256K1_EC_UNCOMPRESSED)); + SECP256K1_CHECKMEM_CHECK(sout, 65); CHECK(len == 0); len = 65; - CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, &pubkey, ~0) == 0); - CHECK(ecount == 4); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_serialize(CTX, sout, &len, &pubkey, ~0)); CHECK(len == 0); len = 65; - VG_UNDEF(sout, 65); - CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); - VG_CHECK(sout, 65); - CHECK(ecount == 4); + SECP256K1_CHECKMEM_UNDEFINE(sout, 65); + CHECK(secp256k1_ec_pubkey_serialize(CTX, sout, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); + SECP256K1_CHECKMEM_CHECK(sout, 65); CHECK(len == 65); /* Multiple illegal args. Should still set arg error only once. */ - ecount = 0; - ecount2 = 11; - CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0); - CHECK(ecount == 1); - /* Does the illegal arg callback actually change the behavior? */ - secp256k1_context_set_illegal_callback(ctx, uncounting_illegal_callback_fn, &ecount2); - CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0); - CHECK(ecount == 1); - CHECK(ecount2 == 10); - secp256k1_context_set_illegal_callback(ctx, NULL, NULL); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_parse(CTX, NULL, NULL, 65)); /* Try a bunch of prefabbed points with all possible encodings. */ for (i = 0; i < SECP256K1_EC_PARSE_TEST_NVALID; i++) { ec_pubkey_parse_pointtest(valid[i], 1, 1); @@ -3099,7 +6013,7 @@ void run_ec_pubkey_parse_test(void) { } } -void run_eckey_edge_case_test(void) { +static void run_eckey_edge_case_test(void) { const unsigned char orderc[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, @@ -3115,259 +6029,284 @@ void run_eckey_edge_case_test(void) { secp256k1_pubkey pubkey_negone; const secp256k1_pubkey *pubkeys[3]; size_t len; - int32_t ecount; /* Group order is too large, reject. */ - CHECK(secp256k1_ec_seckey_verify(ctx, orderc) == 0); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, orderc) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(secp256k1_ec_seckey_verify(CTX, orderc) == 0); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, orderc) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); /* Maximum value is too large, reject. */ memset(ctmp, 255, 32); - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + CHECK(secp256k1_ec_seckey_verify(CTX, ctmp) == 0); memset(&pubkey, 1, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, ctmp) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); /* Zero is too small, reject. */ memset(ctmp, 0, 32); - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + CHECK(secp256k1_ec_seckey_verify(CTX, ctmp) == 0); memset(&pubkey, 1, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, ctmp) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); /* One must be accepted. */ ctmp[31] = 0x01; - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); + CHECK(secp256k1_ec_seckey_verify(CTX, ctmp) == 1); memset(&pubkey, 0, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, ctmp) == 1); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); pubkey_one = pubkey; /* Group order + 1 is too large, reject. */ memcpy(ctmp, orderc, 32); ctmp[31] = 0x42; - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + CHECK(secp256k1_ec_seckey_verify(CTX, ctmp) == 0); memset(&pubkey, 1, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, ctmp) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); /* -1 must be accepted. */ ctmp[31] = 0x40; - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); + CHECK(secp256k1_ec_seckey_verify(CTX, ctmp) == 1); memset(&pubkey, 0, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, ctmp) == 1); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); pubkey_negone = pubkey; - /* Tweak of zero leaves the value changed. */ + /* Tweak of zero leaves the value unchanged. */ memset(ctmp2, 0, 32); - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, ctmp2) == 1); - CHECK(memcmp(orderc, ctmp, 31) == 0 && ctmp[31] == 0x40); + CHECK(secp256k1_ec_seckey_tweak_add(CTX, ctmp, ctmp2) == 1); + CHECK(secp256k1_memcmp_var(orderc, ctmp, 31) == 0 && ctmp[31] == 0x40); memcpy(&pubkey2, &pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, ctmp2) == 1); + CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0); /* Multiply tweak of zero zeroizes the output. */ - CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, ctmp2) == 0); - CHECK(memcmp(zeros, ctmp, 32) == 0); - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, ctmp2) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + CHECK(secp256k1_ec_seckey_tweak_mul(CTX, ctmp, ctmp2) == 0); + CHECK(secp256k1_memcmp_var(zeros, ctmp, 32) == 0); + CHECK(secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey, ctmp2) == 0); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(pubkey)) == 0); memcpy(&pubkey, &pubkey2, sizeof(pubkey)); - /* Overflowing key tweak zeroizes. */ + /* If seckey_tweak_add or seckey_tweak_mul are called with an overflowing + seckey, the seckey is zeroized. */ + memcpy(ctmp, orderc, 32); + memset(ctmp2, 0, 32); + ctmp2[31] = 0x01; + CHECK(secp256k1_ec_seckey_verify(CTX, ctmp2) == 1); + CHECK(secp256k1_ec_seckey_verify(CTX, ctmp) == 0); + CHECK(secp256k1_ec_seckey_tweak_add(CTX, ctmp, ctmp2) == 0); + CHECK(secp256k1_memcmp_var(zeros, ctmp, 32) == 0); + memcpy(ctmp, orderc, 32); + CHECK(secp256k1_ec_seckey_tweak_mul(CTX, ctmp, ctmp2) == 0); + CHECK(secp256k1_memcmp_var(zeros, ctmp, 32) == 0); + /* If seckey_tweak_add or seckey_tweak_mul are called with an overflowing + tweak, the seckey is zeroized. */ memcpy(ctmp, orderc, 32); ctmp[31] = 0x40; - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, orderc) == 0); - CHECK(memcmp(zeros, ctmp, 32) == 0); + CHECK(secp256k1_ec_seckey_tweak_add(CTX, ctmp, orderc) == 0); + CHECK(secp256k1_memcmp_var(zeros, ctmp, 32) == 0); memcpy(ctmp, orderc, 32); ctmp[31] = 0x40; - CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, orderc) == 0); - CHECK(memcmp(zeros, ctmp, 32) == 0); + CHECK(secp256k1_ec_seckey_tweak_mul(CTX, ctmp, orderc) == 0); + CHECK(secp256k1_memcmp_var(zeros, ctmp, 32) == 0); memcpy(ctmp, orderc, 32); ctmp[31] = 0x40; - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, orderc) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + /* If pubkey_tweak_add or pubkey_tweak_mul are called with an overflowing + tweak, the pubkey is zeroized. */ + CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, orderc) == 0); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(pubkey)) == 0); memcpy(&pubkey, &pubkey2, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, orderc) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + CHECK(secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey, orderc) == 0); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(pubkey)) == 0); memcpy(&pubkey, &pubkey2, sizeof(pubkey)); - /* Private key tweaks results in a key of zero. */ + /* If the resulting key in secp256k1_ec_seckey_tweak_add and + * secp256k1_ec_pubkey_tweak_add is 0 the functions fail and in the latter + * case the pubkey is zeroized. */ + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x40; + memset(ctmp2, 0, 32); ctmp2[31] = 1; - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp2, ctmp) == 0); - CHECK(memcmp(zeros, ctmp2, 32) == 0); + CHECK(secp256k1_ec_seckey_tweak_add(CTX, ctmp2, ctmp) == 0); + CHECK(secp256k1_memcmp_var(zeros, ctmp2, 32) == 0); ctmp2[31] = 1; - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, ctmp2) == 0); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(pubkey)) == 0); memcpy(&pubkey, &pubkey2, sizeof(pubkey)); /* Tweak computation wraps and results in a key of 1. */ ctmp2[31] = 2; - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp2, ctmp) == 1); - CHECK(memcmp(ctmp2, zeros, 31) == 0 && ctmp2[31] == 1); + CHECK(secp256k1_ec_seckey_tweak_add(CTX, ctmp2, ctmp) == 1); + CHECK(secp256k1_memcmp_var(ctmp2, zeros, 31) == 0 && ctmp2[31] == 1); ctmp2[31] = 2; - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, ctmp2) == 1); ctmp2[31] = 1; - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, ctmp2) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey2, ctmp2) == 1); + CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0); /* Tweak mul * 2 = 1+1. */ - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, ctmp2) == 1); ctmp2[31] = 2; - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey2, ctmp2) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); - /* Test argument errors. */ - ecount = 0; - secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); - CHECK(ecount == 0); + CHECK(secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey2, ctmp2) == 1); + CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0); /* Zeroize pubkey on parse error. */ memset(&pubkey, 0, 32); - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, ctmp2)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(pubkey)) == 0); memcpy(&pubkey, &pubkey2, sizeof(pubkey)); memset(&pubkey2, 0, 32); - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey2, ctmp2) == 0); - CHECK(ecount == 2); - CHECK(memcmp(&pubkey2, zeros, sizeof(pubkey2)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey2, ctmp2)); + CHECK(secp256k1_memcmp_var(&pubkey2, zeros, sizeof(pubkey2)) == 0); /* Plain argument errors. */ - ecount = 0; - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); - CHECK(ecount == 0); - CHECK(secp256k1_ec_seckey_verify(ctx, NULL) == 0); - CHECK(ecount == 1); - ecount = 0; + CHECK(secp256k1_ec_seckey_verify(CTX, ctmp) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ec_seckey_verify(CTX, NULL)); memset(ctmp2, 0, 32); ctmp2[31] = 4; - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, NULL, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, NULL) == 0); - CHECK(ecount == 2); - ecount = 0; + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_tweak_add(CTX, NULL, ctmp2)); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, NULL)); memset(ctmp2, 0, 32); ctmp2[31] = 4; - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, NULL, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, NULL) == 0); - CHECK(ecount == 2); - ecount = 0; + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_tweak_mul(CTX, NULL, ctmp2)); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey, NULL)); memset(ctmp2, 0, 32); - CHECK(secp256k1_ec_privkey_tweak_add(ctx, NULL, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, NULL) == 0); - CHECK(ecount == 2); - ecount = 0; + CHECK_ILLEGAL(CTX, secp256k1_ec_seckey_tweak_add(CTX, NULL, ctmp2)); + CHECK_ILLEGAL(CTX, secp256k1_ec_seckey_tweak_add(CTX, ctmp, NULL)); memset(ctmp2, 0, 32); ctmp2[31] = 1; - CHECK(secp256k1_ec_privkey_tweak_mul(ctx, NULL, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, NULL) == 0); - CHECK(ecount == 2); - ecount = 0; - CHECK(secp256k1_ec_pubkey_create(ctx, NULL, ctmp) == 0); - CHECK(ecount == 1); + CHECK_ILLEGAL(CTX, secp256k1_ec_seckey_tweak_mul(CTX, NULL, ctmp2)); + CHECK_ILLEGAL(CTX, secp256k1_ec_seckey_tweak_mul(CTX, ctmp, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_create(CTX, NULL, ctmp)); memset(&pubkey, 1, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, NULL) == 0); - CHECK(ecount == 2); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_create(CTX, &pubkey, NULL)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); /* secp256k1_ec_pubkey_combine tests. */ - ecount = 0; pubkeys[0] = &pubkey_one; - VG_UNDEF(&pubkeys[0], sizeof(secp256k1_pubkey *)); - VG_UNDEF(&pubkeys[1], sizeof(secp256k1_pubkey *)); - VG_UNDEF(&pubkeys[2], sizeof(secp256k1_pubkey *)); + SECP256K1_CHECKMEM_UNDEFINE(&pubkeys[0], sizeof(secp256k1_pubkey *)); + SECP256K1_CHECKMEM_UNDEFINE(&pubkeys[1], sizeof(secp256k1_pubkey *)); + SECP256K1_CHECKMEM_UNDEFINE(&pubkeys[2], sizeof(secp256k1_pubkey *)); memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 0) == 0); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_pubkey_combine(ctx, NULL, pubkeys, 1) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - CHECK(ecount == 2); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(secp256k1_pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_combine(CTX, &pubkey, pubkeys, 0)); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_combine(CTX, NULL, pubkeys, 1)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, NULL, 1) == 0); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - CHECK(ecount == 3); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(secp256k1_pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_combine(CTX, &pubkey, NULL, 1)); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); pubkeys[0] = &pubkey_negone; memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 1) == 1); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); - CHECK(ecount == 3); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(CTX, &pubkey, pubkeys, 1) == 1); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); len = 33; - CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); - CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp2, &len, &pubkey_negone, SECP256K1_EC_COMPRESSED) == 1); - CHECK(memcmp(ctmp, ctmp2, 33) == 0); + CHECK(secp256k1_ec_pubkey_serialize(CTX, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + CHECK(secp256k1_ec_pubkey_serialize(CTX, ctmp2, &len, &pubkey_negone, SECP256K1_EC_COMPRESSED) == 1); + CHECK(secp256k1_memcmp_var(ctmp, ctmp2, 33) == 0); /* Result is infinity. */ pubkeys[0] = &pubkey_one; pubkeys[1] = &pubkey_negone; memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 2) == 0); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - CHECK(ecount == 3); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(CTX, &pubkey, pubkeys, 2) == 0); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); /* Passes through infinity but comes out one. */ pubkeys[2] = &pubkey_one; memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 3) == 1); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); - CHECK(ecount == 3); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(CTX, &pubkey, pubkeys, 3) == 1); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); len = 33; - CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); - CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp2, &len, &pubkey_one, SECP256K1_EC_COMPRESSED) == 1); - CHECK(memcmp(ctmp, ctmp2, 33) == 0); + CHECK(secp256k1_ec_pubkey_serialize(CTX, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + CHECK(secp256k1_ec_pubkey_serialize(CTX, ctmp2, &len, &pubkey_one, SECP256K1_EC_COMPRESSED) == 1); + CHECK(secp256k1_memcmp_var(ctmp, ctmp2, 33) == 0); /* Adds to two. */ pubkeys[1] = &pubkey_one; memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 2) == 1); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); - CHECK(ecount == 3); - secp256k1_context_set_illegal_callback(ctx, NULL, NULL); + SECP256K1_CHECKMEM_UNDEFINE(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(CTX, &pubkey, pubkeys, 2) == 1); + SECP256K1_CHECKMEM_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_memcmp_var(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); } -void random_sign(secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *key, const secp256k1_scalar *msg, int *recid) { +static void run_eckey_negate_test(void) { + unsigned char seckey[32]; + unsigned char seckey_tmp[32]; + + testutil_random_scalar_order_b32(seckey); + memcpy(seckey_tmp, seckey, 32); + + /* Verify negation changes the key and changes it back */ + CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 1); + CHECK(secp256k1_memcmp_var(seckey, seckey_tmp, 32) != 0); + CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 1); + CHECK(secp256k1_memcmp_var(seckey, seckey_tmp, 32) == 0); + + /* Check that privkey alias gives same result */ + CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 1); + CHECK(secp256k1_ec_privkey_negate(CTX, seckey_tmp) == 1); + CHECK(secp256k1_memcmp_var(seckey, seckey_tmp, 32) == 0); + + /* Negating all 0s fails */ + memset(seckey, 0, 32); + memset(seckey_tmp, 0, 32); + CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 0); + /* Check that seckey is not modified */ + CHECK(secp256k1_memcmp_var(seckey, seckey_tmp, 32) == 0); + + /* Negating an overflowing seckey fails and the seckey is zeroed. In this + * test, the seckey has 16 random bytes to ensure that ec_seckey_negate + * doesn't just set seckey to a constant value in case of failure. */ + testutil_random_scalar_order_b32(seckey); + memset(seckey, 0xFF, 16); + memset(seckey_tmp, 0, 32); + CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 0); + CHECK(secp256k1_memcmp_var(seckey, seckey_tmp, 32) == 0); +} + +static void random_sign(secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *key, const secp256k1_scalar *msg, int *recid) { secp256k1_scalar nonce; do { - random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sigr, sigs, key, msg, &nonce, recid)); + testutil_random_scalar_order_test(&nonce); + } while(!secp256k1_ecdsa_sig_sign(&CTX->ecmult_gen_ctx, sigr, sigs, key, msg, &nonce, recid)); } -void test_ecdsa_sign_verify(void) { +static void test_ecdsa_sign_verify(void) { secp256k1_gej pubj; secp256k1_ge pub; secp256k1_scalar one; secp256k1_scalar msg, key; secp256k1_scalar sigr, sigs; - int recid; int getrec; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key); + int recid; + testutil_random_scalar_order_test(&msg); + testutil_random_scalar_order_test(&key); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); - getrec = secp256k1_rand_bits(1); - random_sign(&sigr, &sigs, &key, &msg, getrec?&recid:NULL); + getrec = testrand_bits(1); + /* The specific way in which this conditional is written sidesteps a potential bug in clang. + See the commit messages of the commit that introduced this comment for details. */ if (getrec) { + random_sign(&sigr, &sigs, &key, &msg, &recid); CHECK(recid >= 0 && recid < 4); + } else { + random_sign(&sigr, &sigs, &key, &msg, NULL); } - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&sigr, &sigs, &pub, &msg)); secp256k1_scalar_set_int(&one, 1); secp256k1_scalar_add(&msg, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg)); + CHECK(!secp256k1_ecdsa_sig_verify(&sigr, &sigs, &pub, &msg)); } -void run_ecdsa_sign_verify(void) { +static void run_ecdsa_sign_verify(void) { int i; - for (i = 0; i < 10*count; i++) { + for (i = 0; i < 10*COUNT; i++) { test_ecdsa_sign_verify(); } } @@ -3419,12 +6358,12 @@ static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 5); } -int is_empty_signature(const secp256k1_ecdsa_signature *sig) { +static int is_empty_signature(const secp256k1_ecdsa_signature *sig) { static const unsigned char res[sizeof(secp256k1_ecdsa_signature)] = {0}; - return memcmp(sig, res, sizeof(secp256k1_ecdsa_signature)) == 0; + return secp256k1_memcmp_var(sig, res, sizeof(secp256k1_ecdsa_signature)) == 0; } -void test_ecdsa_end_to_end(void) { +static void test_ecdsa_end_to_end(void) { unsigned char extra[32] = {0x00}; unsigned char privkey[32]; unsigned char message[32]; @@ -3436,139 +6375,161 @@ void test_ecdsa_end_to_end(void) { unsigned char pubkeyc[65]; size_t pubkeyclen = 65; secp256k1_pubkey pubkey; + secp256k1_pubkey pubkey_tmp; unsigned char seckey[300]; size_t seckeylen = 300; /* Generate a random key and message. */ { secp256k1_scalar msg, key; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); + testutil_random_scalar_order_test(&msg); + testutil_random_scalar_order_test(&key); secp256k1_scalar_get_b32(privkey, &key); secp256k1_scalar_get_b32(message, &msg); } /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + CHECK(secp256k1_ec_seckey_verify(CTX, privkey) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, privkey) == 1); /* Verify exporting and importing public key. */ - CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyc, &pubkeyclen, &pubkey, secp256k1_rand_bits(1) == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)); + CHECK(secp256k1_ec_pubkey_serialize(CTX, pubkeyc, &pubkeyclen, &pubkey, testrand_bits(1) == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)); memset(&pubkey, 0, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pubkeyc, pubkeyclen) == 1); + + /* Verify negation changes the key and changes it back */ + memcpy(&pubkey_tmp, &pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_negate(CTX, &pubkey_tmp) == 1); + CHECK(secp256k1_memcmp_var(&pubkey_tmp, &pubkey, sizeof(pubkey)) != 0); + CHECK(secp256k1_ec_pubkey_negate(CTX, &pubkey_tmp) == 1); + CHECK(secp256k1_memcmp_var(&pubkey_tmp, &pubkey, sizeof(pubkey)) == 0); /* Verify private key import and export. */ - CHECK(ec_privkey_export_der(ctx, seckey, &seckeylen, privkey, secp256k1_rand_bits(1) == 1)); - CHECK(ec_privkey_import_der(ctx, privkey2, seckey, seckeylen) == 1); - CHECK(memcmp(privkey, privkey2, 32) == 0); + CHECK(ec_privkey_export_der(CTX, seckey, &seckeylen, privkey, testrand_bits(1) == 1)); + CHECK(ec_privkey_import_der(CTX, privkey2, seckey, seckeylen) == 1); + CHECK(secp256k1_memcmp_var(privkey, privkey2, 32) == 0); /* Optionally tweak the keys using addition. */ - if (secp256k1_rand_int(3) == 0) { + if (testrand_int(3) == 0) { int ret1; int ret2; + int ret3; unsigned char rnd[32]; + unsigned char privkey_tmp[32]; secp256k1_pubkey pubkey2; - secp256k1_rand256_test(rnd); - ret1 = secp256k1_ec_privkey_tweak_add(ctx, privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, rnd); + testrand256_test(rnd); + memcpy(privkey_tmp, privkey, 32); + ret1 = secp256k1_ec_seckey_tweak_add(CTX, privkey, rnd); + ret2 = secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, rnd); + /* Check that privkey alias gives same result */ + ret3 = secp256k1_ec_privkey_tweak_add(CTX, privkey_tmp, rnd); CHECK(ret1 == ret2); + CHECK(ret2 == ret3); if (ret1 == 0) { return; } - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + CHECK(secp256k1_memcmp_var(privkey, privkey_tmp, 32) == 0); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey2, privkey) == 1); + CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0); } /* Optionally tweak the keys using multiplication. */ - if (secp256k1_rand_int(3) == 0) { + if (testrand_int(3) == 0) { int ret1; int ret2; + int ret3; unsigned char rnd[32]; + unsigned char privkey_tmp[32]; secp256k1_pubkey pubkey2; - secp256k1_rand256_test(rnd); - ret1 = secp256k1_ec_privkey_tweak_mul(ctx, privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, rnd); + testrand256_test(rnd); + memcpy(privkey_tmp, privkey, 32); + ret1 = secp256k1_ec_seckey_tweak_mul(CTX, privkey, rnd); + ret2 = secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey, rnd); + /* Check that privkey alias gives same result */ + ret3 = secp256k1_ec_privkey_tweak_mul(CTX, privkey_tmp, rnd); CHECK(ret1 == ret2); + CHECK(ret2 == ret3); if (ret1 == 0) { return; } - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + CHECK(secp256k1_memcmp_var(privkey, privkey_tmp, 32) == 0); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey2, privkey) == 1); + CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0); } /* Sign. */ - CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign(ctx, &signature[4], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign(ctx, &signature[1], message, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &signature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &signature[4], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &signature[1], message, privkey, NULL, extra) == 1); extra[31] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, &signature[2], message, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &signature[2], message, privkey, NULL, extra) == 1); extra[31] = 0; extra[0] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, &signature[3], message, privkey, NULL, extra) == 1); - CHECK(memcmp(&signature[0], &signature[4], sizeof(signature[0])) == 0); - CHECK(memcmp(&signature[0], &signature[1], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[0], &signature[2], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[0], &signature[3], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[1], &signature[2], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[1], &signature[3], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[2], &signature[3], sizeof(signature[0])) != 0); + CHECK(secp256k1_ecdsa_sign(CTX, &signature[3], message, privkey, NULL, extra) == 1); + CHECK(secp256k1_memcmp_var(&signature[0], &signature[4], sizeof(signature[0])) == 0); + CHECK(secp256k1_memcmp_var(&signature[0], &signature[1], sizeof(signature[0])) != 0); + CHECK(secp256k1_memcmp_var(&signature[0], &signature[2], sizeof(signature[0])) != 0); + CHECK(secp256k1_memcmp_var(&signature[0], &signature[3], sizeof(signature[0])) != 0); + CHECK(secp256k1_memcmp_var(&signature[1], &signature[2], sizeof(signature[0])) != 0); + CHECK(secp256k1_memcmp_var(&signature[1], &signature[3], sizeof(signature[0])) != 0); + CHECK(secp256k1_memcmp_var(&signature[2], &signature[3], sizeof(signature[0])) != 0); /* Verify. */ - CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[1], message, &pubkey) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[2], message, &pubkey) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[3], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[0], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[1], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[2], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[3], message, &pubkey) == 1); /* Test lower-S form, malleate, verify and fail, test again, malleate again */ - CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[0])); - secp256k1_ecdsa_signature_load(ctx, &r, &s, &signature[0]); + CHECK(!secp256k1_ecdsa_signature_normalize(CTX, NULL, &signature[0])); + secp256k1_ecdsa_signature_load(CTX, &r, &s, &signature[0]); secp256k1_scalar_negate(&s, &s); secp256k1_ecdsa_signature_save(&signature[5], &r, &s); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 0); - CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); - CHECK(secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5])); - CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); - CHECK(!secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5])); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[5], message, &pubkey) == 0); + CHECK(secp256k1_ecdsa_signature_normalize(CTX, NULL, &signature[5])); + CHECK(secp256k1_ecdsa_signature_normalize(CTX, &signature[5], &signature[5])); + CHECK(!secp256k1_ecdsa_signature_normalize(CTX, NULL, &signature[5])); + CHECK(!secp256k1_ecdsa_signature_normalize(CTX, &signature[5], &signature[5])); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[5], message, &pubkey) == 1); secp256k1_scalar_negate(&s, &s); secp256k1_ecdsa_signature_save(&signature[5], &r, &s); - CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1); - CHECK(memcmp(&signature[5], &signature[0], 64) == 0); + CHECK(!secp256k1_ecdsa_signature_normalize(CTX, NULL, &signature[5])); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[5], message, &pubkey) == 1); + CHECK(secp256k1_memcmp_var(&signature[5], &signature[0], 64) == 0); /* Serialize/parse DER and verify again */ - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1); + CHECK(secp256k1_ecdsa_signature_serialize_der(CTX, sig, &siglen, &signature[0]) == 1); memset(&signature[0], 0, sizeof(signature[0])); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &signature[0], sig, siglen) == 1); + CHECK(secp256k1_ecdsa_verify(CTX, &signature[0], message, &pubkey) == 1); /* Serialize/destroy/parse DER and verify again. */ siglen = 74; - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1); - sig[secp256k1_rand_int(siglen)] += 1 + secp256k1_rand_int(255); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 0 || - secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 0); + CHECK(secp256k1_ecdsa_signature_serialize_der(CTX, sig, &siglen, &signature[0]) == 1); + sig[testrand_int(siglen)] += 1 + testrand_int(255); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &signature[0], sig, siglen) == 0 || + secp256k1_ecdsa_verify(CTX, &signature[0], message, &pubkey) == 0); } -void test_random_pubkeys(void) { +static void test_random_pubkeys(void) { secp256k1_ge elem; secp256k1_ge elem2; unsigned char in[65]; /* Generate some randomly sized pubkeys. */ - size_t len = secp256k1_rand_bits(2) == 0 ? 65 : 33; - if (secp256k1_rand_bits(2) == 0) { - len = secp256k1_rand_bits(6); + size_t len = testrand_bits(2) == 0 ? 65 : 33; + if (testrand_bits(2) == 0) { + len = testrand_bits(6); } if (len == 65) { - in[0] = secp256k1_rand_bits(1) ? 4 : (secp256k1_rand_bits(1) ? 6 : 7); + in[0] = testrand_bits(1) ? 4 : (testrand_bits(1) ? 6 : 7); } else { - in[0] = secp256k1_rand_bits(1) ? 2 : 3; + in[0] = testrand_bits(1) ? 2 : 3; } - if (secp256k1_rand_bits(3) == 0) { - in[0] = secp256k1_rand_bits(8); + if (testrand_bits(3) == 0) { + in[0] = testrand_bits(8); } if (len > 1) { - secp256k1_rand256(&in[1]); + testrand256(&in[1]); } if (len > 33) { - secp256k1_rand256(&in[33]); + testrand256(&in[33]); } if (secp256k1_eckey_pubkey_parse(&elem, in, len)) { unsigned char out[65]; @@ -3579,7 +6540,7 @@ void test_random_pubkeys(void) { /* If the pubkey can be parsed, it should round-trip... */ CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33)); CHECK(size == len); - CHECK(memcmp(&in[1], &out[1], len-1) == 0); + CHECK(secp256k1_memcmp_var(&in[1], &out[1], len-1) == 0); /* ... except for the type of hybrid inputs. */ if ((in[0] != 6) && (in[0] != 7)) { CHECK(in[0] == out[0]); @@ -3588,9 +6549,9 @@ void test_random_pubkeys(void) { CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0)); CHECK(size == 65); CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size)); - ge_equals_ge(&elem,&elem2); + CHECK(secp256k1_ge_eq_var(&elem2, &elem)); /* Check that the X9.62 hybrid type is checked. */ - in[0] = secp256k1_rand_bits(1) ? 6 : 7; + in[0] = testrand_bits(1) ? 6 : 7; res = secp256k1_eckey_pubkey_parse(&elem2, in, size); if (firstb == 2 || firstb == 3) { if (in[0] == firstb + 4) { @@ -3600,37 +6561,221 @@ void test_random_pubkeys(void) { } } if (res) { - ge_equals_ge(&elem,&elem2); + CHECK(secp256k1_ge_eq_var(&elem, &elem2)); CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0)); - CHECK(memcmp(&in[1], &out[1], 64) == 0); + CHECK(secp256k1_memcmp_var(&in[1], &out[1], 64) == 0); } } } -void run_random_pubkeys(void) { +static void run_pubkey_comparison(void) { + unsigned char pk1_ser[33] = { + 0x02, + 0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11, + 0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23 + }; + const unsigned char pk2_ser[33] = { + 0x02, + 0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d, + 0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c + }; + secp256k1_pubkey pk1; + secp256k1_pubkey pk2; + + CHECK(secp256k1_ec_pubkey_parse(CTX, &pk1, pk1_ser, sizeof(pk1_ser)) == 1); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pk2, pk2_ser, sizeof(pk2_ser)) == 1); + + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_ec_pubkey_cmp(CTX, NULL, &pk2) < 0)); + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk1, NULL) > 0)); + CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk1, &pk2) < 0); + CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk2, &pk1) > 0); + CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk1, &pk1) == 0); + CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk2, &pk2) == 0); + { + secp256k1_pubkey pk_tmp; + memset(&pk_tmp, 0, sizeof(pk_tmp)); /* illegal pubkey */ + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk_tmp, &pk2) < 0)); + { + int32_t ecount = 0; + secp256k1_context_set_illegal_callback(CTX, counting_callback_fn, &ecount); + CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk_tmp, &pk_tmp) == 0); + CHECK(ecount == 2); + secp256k1_context_set_illegal_callback(CTX, NULL, NULL); + } + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk2, &pk_tmp) > 0)); + } + + /* Make pk2 the same as pk1 but with 3 rather than 2. Note that in + * an uncompressed encoding, these would have the opposite ordering */ + pk1_ser[0] = 3; + CHECK(secp256k1_ec_pubkey_parse(CTX, &pk2, pk1_ser, sizeof(pk1_ser)) == 1); + CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk1, &pk2) < 0); + CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk2, &pk1) > 0); +} + +static void test_sort_helper(secp256k1_pubkey *pk, size_t *pk_order, size_t n_pk) { + size_t i; + const secp256k1_pubkey *pk_test[5]; + + for (i = 0; i < n_pk; i++) { + pk_test[i] = &pk[pk_order[i]]; + } + secp256k1_ec_pubkey_sort(CTX, pk_test, n_pk); + for (i = 0; i < n_pk; i++) { + CHECK(secp256k1_memcmp_var(pk_test[i], &pk[i], sizeof(*pk_test[i])) == 0); + } +} + +static void permute(size_t *arr, size_t n) { + size_t i; + for (i = n - 1; i >= 1; i--) { + size_t tmp, j; + j = testrand_int(i + 1); + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +} + +static void test_sort_api(void) { + secp256k1_pubkey pks[2]; + const secp256k1_pubkey *pks_ptr[2]; + + pks_ptr[0] = &pks[0]; + pks_ptr[1] = &pks[1]; + + testutil_random_pubkey_test(&pks[0]); + testutil_random_pubkey_test(&pks[1]); + + CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, 2) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_sort(CTX, NULL, 2)); + CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, 0) == 1); + /* Test illegal public keys */ + memset(&pks[0], 0, sizeof(pks[0])); + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, 2) == 1)); + memset(&pks[1], 0, sizeof(pks[1])); + { + int32_t ecount = 0; + secp256k1_context_set_illegal_callback(CTX, counting_callback_fn, &ecount); + CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, 2) == 1); + CHECK(ecount == 2); + secp256k1_context_set_illegal_callback(CTX, NULL, NULL); + } +} + +static void test_sort(void) { + secp256k1_pubkey pk[5]; + unsigned char pk_ser[5][33] = { + { 0x02, 0x08 }, + { 0x02, 0x0b }, + { 0x02, 0x0c }, + { 0x03, 0x05 }, + { 0x03, 0x0a }, + }; int i; - for (i = 0; i < 10*count; i++) { + size_t pk_order[5] = { 0, 1, 2, 3, 4 }; + + for (i = 0; i < 5; i++) { + CHECK(secp256k1_ec_pubkey_parse(CTX, &pk[i], pk_ser[i], sizeof(pk_ser[i]))); + } + + permute(pk_order, 1); + test_sort_helper(pk, pk_order, 1); + permute(pk_order, 2); + test_sort_helper(pk, pk_order, 2); + permute(pk_order, 3); + test_sort_helper(pk, pk_order, 3); + for (i = 0; i < COUNT; i++) { + permute(pk_order, 4); + test_sort_helper(pk, pk_order, 4); + } + for (i = 0; i < COUNT; i++) { + permute(pk_order, 5); + test_sort_helper(pk, pk_order, 5); + } + /* Check that sorting also works for random pubkeys */ + for (i = 0; i < COUNT; i++) { + int j; + const secp256k1_pubkey *pk_ptr[5]; + for (j = 0; j < 5; j++) { + testutil_random_pubkey_test(&pk[j]); + pk_ptr[j] = &pk[j]; + } + secp256k1_ec_pubkey_sort(CTX, pk_ptr, 5); + for (j = 1; j < 5; j++) { + CHECK(secp256k1_ec_pubkey_sort_cmp(&pk_ptr[j - 1], &pk_ptr[j], CTX) <= 0); + } + } +} + +/* Test vectors from BIP-MuSig2 */ +static void test_sort_vectors(void) { + enum { N_PUBKEYS = 6 }; + unsigned char pk_ser[N_PUBKEYS][33] = { + { 0x02, 0xDD, 0x30, 0x8A, 0xFE, 0xC5, 0x77, 0x7E, 0x13, 0x12, 0x1F, + 0xA7, 0x2B, 0x9C, 0xC1, 0xB7, 0xCC, 0x01, 0x39, 0x71, 0x53, 0x09, + 0xB0, 0x86, 0xC9, 0x60, 0xE1, 0x8F, 0xD9, 0x69, 0x77, 0x4E, 0xB8 }, + { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, + 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, + 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, + { 0x03, 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, + 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D, 0xA2, + 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 }, + { 0x02, 0x35, 0x90, 0xA9, 0x4E, 0x76, 0x8F, 0x8E, 0x18, 0x15, 0xC2, + 0xF2, 0x4B, 0x4D, 0x80, 0xA8, 0xE3, 0x14, 0x93, 0x16, 0xC3, 0x51, + 0x8C, 0xE7, 0xB7, 0xAD, 0x33, 0x83, 0x68, 0xD0, 0x38, 0xCA, 0x66 }, + { 0x02, 0xDD, 0x30, 0x8A, 0xFE, 0xC5, 0x77, 0x7E, 0x13, 0x12, 0x1F, + 0xA7, 0x2B, 0x9C, 0xC1, 0xB7, 0xCC, 0x01, 0x39, 0x71, 0x53, 0x09, + 0xB0, 0x86, 0xC9, 0x60, 0xE1, 0x8F, 0xD9, 0x69, 0x77, 0x4E, 0xFF }, + { 0x02, 0xDD, 0x30, 0x8A, 0xFE, 0xC5, 0x77, 0x7E, 0x13, 0x12, 0x1F, + 0xA7, 0x2B, 0x9C, 0xC1, 0xB7, 0xCC, 0x01, 0x39, 0x71, 0x53, 0x09, + 0xB0, 0x86, 0xC9, 0x60, 0xE1, 0x8F, 0xD9, 0x69, 0x77, 0x4E, 0xB8 } + }; + secp256k1_pubkey pubkeys[N_PUBKEYS]; + secp256k1_pubkey *sorted[N_PUBKEYS]; + const secp256k1_pubkey *pks_ptr[N_PUBKEYS]; + int i; + + sorted[0] = &pubkeys[3]; + sorted[1] = &pubkeys[0]; + sorted[2] = &pubkeys[0]; + sorted[3] = &pubkeys[4]; + sorted[4] = &pubkeys[1]; + sorted[5] = &pubkeys[2]; + + for (i = 0; i < N_PUBKEYS; i++) { + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkeys[i], pk_ser[i], sizeof(pk_ser[i]))); + pks_ptr[i] = &pubkeys[i]; + } + CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, N_PUBKEYS) == 1); + for (i = 0; i < N_PUBKEYS; i++) { + CHECK(secp256k1_memcmp_var(pks_ptr[i], sorted[i], sizeof(secp256k1_pubkey)) == 0); + } +} + +static void run_pubkey_sort(void) { + test_sort_api(); + test_sort(); + test_sort_vectors(); +} + + +static void run_random_pubkeys(void) { + int i; + for (i = 0; i < 10*COUNT; i++) { test_random_pubkeys(); } } -void run_ecdsa_end_to_end(void) { +static void run_ecdsa_end_to_end(void) { int i; - for (i = 0; i < 64*count; i++) { + for (i = 0; i < 64*COUNT; i++) { test_ecdsa_end_to_end(); } } -int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) { +static int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) { static const unsigned char zeroes[32] = {0}; -#ifdef ENABLE_OPENSSL_TESTS - static const unsigned char max_scalar[32] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, - 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40 - }; -#endif int ret = 0; @@ -3646,32 +6791,24 @@ int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_ size_t len_der_lax = 2048; int parsed_der_lax = 0, valid_der_lax = 0, roundtrips_der_lax = 0; -#ifdef ENABLE_OPENSSL_TESTS - ECDSA_SIG *sig_openssl; - const unsigned char *sigptr; - unsigned char roundtrip_openssl[2048]; - int len_openssl = 2048; - int parsed_openssl, valid_openssl = 0, roundtrips_openssl = 0; -#endif - - parsed_der = secp256k1_ecdsa_signature_parse_der(ctx, &sig_der, sig, siglen); + parsed_der = secp256k1_ecdsa_signature_parse_der(CTX, &sig_der, sig, siglen); if (parsed_der) { - ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der, &sig_der)) << 0; - valid_der = (memcmp(compact_der, zeroes, 32) != 0) && (memcmp(compact_der + 32, zeroes, 32) != 0); + ret |= (!secp256k1_ecdsa_signature_serialize_compact(CTX, compact_der, &sig_der)) << 0; + valid_der = (secp256k1_memcmp_var(compact_der, zeroes, 32) != 0) && (secp256k1_memcmp_var(compact_der + 32, zeroes, 32) != 0); } if (valid_der) { - ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der, &len_der, &sig_der)) << 1; - roundtrips_der = (len_der == siglen) && memcmp(roundtrip_der, sig, siglen) == 0; + ret |= (!secp256k1_ecdsa_signature_serialize_der(CTX, roundtrip_der, &len_der, &sig_der)) << 1; + roundtrips_der = (len_der == siglen) && secp256k1_memcmp_var(roundtrip_der, sig, siglen) == 0; } - parsed_der_lax = ecdsa_signature_parse_der_lax(ctx, &sig_der_lax, sig, siglen); + parsed_der_lax = ecdsa_signature_parse_der_lax(CTX, &sig_der_lax, sig, siglen); if (parsed_der_lax) { - ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der_lax, &sig_der_lax)) << 10; - valid_der_lax = (memcmp(compact_der_lax, zeroes, 32) != 0) && (memcmp(compact_der_lax + 32, zeroes, 32) != 0); + ret |= (!secp256k1_ecdsa_signature_serialize_compact(CTX, compact_der_lax, &sig_der_lax)) << 10; + valid_der_lax = (secp256k1_memcmp_var(compact_der_lax, zeroes, 32) != 0) && (secp256k1_memcmp_var(compact_der_lax + 32, zeroes, 32) != 0); } if (valid_der_lax) { - ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der_lax, &len_der_lax, &sig_der_lax)) << 11; - roundtrips_der_lax = (len_der_lax == siglen) && memcmp(roundtrip_der_lax, sig, siglen) == 0; + ret |= (!secp256k1_ecdsa_signature_serialize_der(CTX, roundtrip_der_lax, &len_der_lax, &sig_der_lax)) << 11; + roundtrips_der_lax = (len_der_lax == siglen) && secp256k1_memcmp_var(roundtrip_der_lax, sig, siglen) == 0; } if (certainly_der) { @@ -3687,49 +6824,13 @@ int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_ if (valid_der) { ret |= (!roundtrips_der_lax) << 12; ret |= (len_der != len_der_lax) << 13; - ret |= (memcmp(roundtrip_der_lax, roundtrip_der, len_der) != 0) << 14; + ret |= ((len_der != len_der_lax) || (secp256k1_memcmp_var(roundtrip_der_lax, roundtrip_der, len_der) != 0)) << 14; } ret |= (roundtrips_der != roundtrips_der_lax) << 15; if (parsed_der) { ret |= (!parsed_der_lax) << 16; } -#ifdef ENABLE_OPENSSL_TESTS - sig_openssl = ECDSA_SIG_new(); - sigptr = sig; - parsed_openssl = (d2i_ECDSA_SIG(&sig_openssl, &sigptr, siglen) != NULL); - if (parsed_openssl) { - valid_openssl = !BN_is_negative(sig_openssl->r) && !BN_is_negative(sig_openssl->s) && BN_num_bits(sig_openssl->r) > 0 && BN_num_bits(sig_openssl->r) <= 256 && BN_num_bits(sig_openssl->s) > 0 && BN_num_bits(sig_openssl->s) <= 256; - if (valid_openssl) { - unsigned char tmp[32] = {0}; - BN_bn2bin(sig_openssl->r, tmp + 32 - BN_num_bytes(sig_openssl->r)); - valid_openssl = memcmp(tmp, max_scalar, 32) < 0; - } - if (valid_openssl) { - unsigned char tmp[32] = {0}; - BN_bn2bin(sig_openssl->s, tmp + 32 - BN_num_bytes(sig_openssl->s)); - valid_openssl = memcmp(tmp, max_scalar, 32) < 0; - } - } - len_openssl = i2d_ECDSA_SIG(sig_openssl, NULL); - if (len_openssl <= 2048) { - unsigned char *ptr = roundtrip_openssl; - CHECK(i2d_ECDSA_SIG(sig_openssl, &ptr) == len_openssl); - roundtrips_openssl = valid_openssl && ((size_t)len_openssl == siglen) && (memcmp(roundtrip_openssl, sig, siglen) == 0); - } else { - len_openssl = 0; - } - ECDSA_SIG_free(sig_openssl); - - ret |= (parsed_der && !parsed_openssl) << 4; - ret |= (valid_der && !valid_openssl) << 5; - ret |= (roundtrips_openssl && !parsed_der) << 6; - ret |= (roundtrips_der != roundtrips_openssl) << 7; - if (roundtrips_openssl) { - ret |= (len_der != (size_t)len_openssl) << 8; - ret |= (memcmp(roundtrip_der, roundtrip_openssl, len_der) != 0) << 9; - } -#endif return ret; } @@ -3747,27 +6848,27 @@ static void assign_big_endian(unsigned char *ptr, size_t ptrlen, uint32_t val) { static void damage_array(unsigned char *sig, size_t *len) { int pos; - int action = secp256k1_rand_bits(3); + int action = testrand_bits(3); if (action < 1 && *len > 3) { /* Delete a byte. */ - pos = secp256k1_rand_int(*len); + pos = testrand_int(*len); memmove(sig + pos, sig + pos + 1, *len - pos - 1); (*len)--; return; } else if (action < 2 && *len < 2048) { /* Insert a byte. */ - pos = secp256k1_rand_int(1 + *len); + pos = testrand_int(1 + *len); memmove(sig + pos + 1, sig + pos, *len - pos); - sig[pos] = secp256k1_rand_bits(8); + sig[pos] = testrand_bits(8); (*len)++; return; } else if (action < 4) { /* Modify a byte. */ - sig[secp256k1_rand_int(*len)] += 1 + secp256k1_rand_int(255); + sig[testrand_int(*len)] += 1 + testrand_int(255); return; } else { /* action < 8 */ /* Modify a bit. */ - sig[secp256k1_rand_int(*len)] ^= 1 << secp256k1_rand_bits(3); + sig[testrand_int(*len)] ^= 1 << testrand_bits(3); return; } } @@ -3780,23 +6881,23 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly int n; *len = 0; - der = secp256k1_rand_bits(2) == 0; + der = testrand_bits(2) == 0; *certainly_der = der; *certainly_not_der = 0; - indet = der ? 0 : secp256k1_rand_int(10) == 0; + indet = der ? 0 : testrand_int(10) == 0; for (n = 0; n < 2; n++) { /* We generate two classes of numbers: nlow==1 "low" ones (up to 32 bytes), nlow==0 "high" ones (32 bytes with 129 top bits set, or larger than 32 bytes) */ - nlow[n] = der ? 1 : (secp256k1_rand_bits(3) != 0); + nlow[n] = der ? 1 : (testrand_bits(3) != 0); /* The length of the number in bytes (the first byte of which will always be nonzero) */ - nlen[n] = nlow[n] ? secp256k1_rand_int(33) : 32 + secp256k1_rand_int(200) * secp256k1_rand_int(8) / 8; + nlen[n] = nlow[n] ? testrand_int(33) : 32 + testrand_int(200) * testrand_bits(3) / 8; CHECK(nlen[n] <= 232); /* The top bit of the number. */ - nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : secp256k1_rand_bits(1)); + nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : testrand_bits(1)); /* The top byte of the number (after the potential hardcoded 16 0xFF characters for "high" 32 bytes numbers) */ - nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + secp256k1_rand_bits(7) : 1 + secp256k1_rand_int(127)); + nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + testrand_bits(7) : 1 + testrand_int(127)); /* The number of zero bytes in front of the number (which is 0 or 1 in case of DER, otherwise we extend up to 300 bytes) */ - nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? secp256k1_rand_int(3) : secp256k1_rand_int(300 - nlen[n]) * secp256k1_rand_int(8) / 8); + nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? testrand_int(3) : testrand_int(300 - nlen[n]) * testrand_bits(3) / 8); if (nzlen[n] > ((nlen[n] == 0 || nhbit[n]) ? 1 : 0)) { *certainly_not_der = 1; } @@ -3805,7 +6906,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly nlenlen[n] = nlen[n] + nzlen[n] < 128 ? 0 : (nlen[n] + nzlen[n] < 256 ? 1 : 2); if (!der) { /* nlenlen[n] max 127 bytes */ - int add = secp256k1_rand_int(127 - nlenlen[n]) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256; + int add = testrand_int(127 - nlenlen[n]) * testrand_bits(4) * testrand_bits(4) / 256; nlenlen[n] += add; if (add != 0) { *certainly_not_der = 1; @@ -3819,7 +6920,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly CHECK(tlen <= 856); /* The length of the garbage inside the tuple. */ - elen = (der || indet) ? 0 : secp256k1_rand_int(980 - tlen) * secp256k1_rand_int(8) / 8; + elen = (der || indet) ? 0 : testrand_int(980 - tlen) * testrand_bits(3) / 8; if (elen != 0) { *certainly_not_der = 1; } @@ -3827,7 +6928,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly CHECK(tlen <= 980); /* The length of the garbage after the end of the tuple. */ - glen = der ? 0 : secp256k1_rand_int(990 - tlen) * secp256k1_rand_int(8) / 8; + glen = der ? 0 : testrand_int(990 - tlen) * testrand_bits(3) / 8; if (glen != 0) { *certainly_not_der = 1; } @@ -3842,7 +6943,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly } else { int tlenlen = tlen < 128 ? 0 : (tlen < 256 ? 1 : 2); if (!der) { - int add = secp256k1_rand_int(127 - tlenlen) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256; + int add = testrand_int(127 - tlenlen) * testrand_bits(4) * testrand_bits(4) / 256; tlenlen += add; if (add != 0) { *certainly_not_der = 1; @@ -3893,13 +6994,13 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly nlen[n]--; } /* Generate remaining random bytes of number */ - secp256k1_rand_bytes_test(sig + *len, nlen[n]); + testrand_bytes_test(sig + *len, nlen[n]); *len += nlen[n]; nlen[n] = 0; } /* Generate random garbage inside tuple. */ - secp256k1_rand_bytes_test(sig + *len, elen); + testrand_bytes_test(sig + *len, elen); *len += elen; /* Generate end-of-contents bytes. */ @@ -3911,16 +7012,16 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly CHECK(tlen + glen <= 1121); /* Generate random garbage outside tuple. */ - secp256k1_rand_bytes_test(sig + *len, glen); + testrand_bytes_test(sig + *len, glen); *len += glen; tlen += glen; CHECK(tlen <= 1121); CHECK(tlen == *len); } -void run_ecdsa_der_parse(void) { +static void run_ecdsa_der_parse(void) { int i,j; - for (i = 0; i < 200 * count; i++) { + for (i = 0; i < 200 * COUNT; i++) { unsigned char buffer[2048]; size_t buflen = 0; int certainly_der = 0; @@ -3950,7 +7051,7 @@ void run_ecdsa_der_parse(void) { } /* Tests several edge cases. */ -void test_ecdsa_edge_cases(void) { +static void test_ecdsa_edge_cases(void) { int t; secp256k1_ecdsa_signature sig; @@ -3964,10 +7065,10 @@ void test_ecdsa_edge_cases(void) { secp256k1_scalar_negate(&ss, &ss); secp256k1_scalar_inverse(&ss, &ss); secp256k1_scalar_set_int(&sr, 1); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sr); + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &keyj, &sr); secp256k1_ge_set_gej(&key, &keyj); msg = ss; - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 0); } /* Verify signature with r of zero fails. */ @@ -3986,7 +7087,7 @@ void test_ecdsa_edge_cases(void) { secp256k1_scalar_set_int(&msg, 0); secp256k1_scalar_set_int(&sr, 0); CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey_mods_zero, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify( &sr, &ss, &key, &msg) == 0); } /* Verify signature with s of zero fails. */ @@ -4005,7 +7106,7 @@ void test_ecdsa_edge_cases(void) { secp256k1_scalar_set_int(&msg, 0); secp256k1_scalar_set_int(&sr, 1); CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 0); } /* Verify signature with message 0 passes. */ @@ -4033,14 +7134,14 @@ void test_ecdsa_edge_cases(void) { secp256k1_scalar_set_int(&sr, 2); CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); CHECK(secp256k1_eckey_pubkey_parse(&key2, pubkey2, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key2, &msg) == 1); secp256k1_scalar_negate(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key2, &msg) == 1); secp256k1_scalar_set_int(&ss, 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key2, &msg) == 0); } /* Verify signature with message 1 passes. */ @@ -4074,15 +7175,15 @@ void test_ecdsa_edge_cases(void) { secp256k1_scalar_set_b32(&sr, csr, NULL); CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); CHECK(secp256k1_eckey_pubkey_parse(&key2, pubkey2, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key2, &msg) == 1); secp256k1_scalar_negate(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key2, &msg) == 1); secp256k1_scalar_set_int(&ss, 2); secp256k1_scalar_inverse_var(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key2, &msg) == 0); } /* Verify signature with message -1 passes. */ @@ -4108,19 +7209,18 @@ void test_ecdsa_edge_cases(void) { secp256k1_scalar_negate(&msg, &msg); secp256k1_scalar_set_b32(&sr, csr, NULL); CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 1); secp256k1_scalar_negate(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 1); secp256k1_scalar_set_int(&ss, 3); secp256k1_scalar_inverse_var(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&sr, &ss, &key, &msg) == 0); } /* Signature where s would be zero. */ { secp256k1_pubkey pubkey; size_t siglen; - int32_t ecount; unsigned char signature[72]; static const unsigned char nonce[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4146,72 +7246,42 @@ void test_ecdsa_edge_cases(void) { 0xb8, 0x12, 0xe0, 0x0b, 0x81, 0x7a, 0x77, 0x62, 0x65, 0xdf, 0xdd, 0x31, 0xb9, 0x3e, 0x29, 0xa9, }; - ecount = 0; - secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 0); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 0); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, msg, key, precomputed_nonce_function, nonce) == 0); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, msg, key, precomputed_nonce_function, nonce2) == 0); msg[31] = 0xaa; - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 1); - CHECK(ecount == 0); - CHECK(secp256k1_ecdsa_sign(ctx, NULL, msg, key, precomputed_nonce_function, nonce2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, NULL, key, precomputed_nonce_function, nonce2) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, NULL, precomputed_nonce_function, nonce2) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, key) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, NULL, msg, &pubkey) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, NULL, &pubkey) == 0); - CHECK(ecount == 5); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, NULL) == 0); - CHECK(ecount == 6); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, &pubkey) == 1); - CHECK(ecount == 6); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, NULL) == 0); - CHECK(ecount == 7); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, msg, key, precomputed_nonce_function, nonce) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign(CTX, NULL, msg, key, precomputed_nonce_function, nonce2)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign(CTX, &sig, NULL, key, precomputed_nonce_function, nonce2)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign(CTX, &sig, msg, NULL, precomputed_nonce_function, nonce2)); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, msg, key, precomputed_nonce_function, nonce2) == 1); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, key) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_verify(CTX, NULL, msg, &pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_verify(CTX, &sig, NULL, &pubkey)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_verify(CTX, &sig, msg, NULL)); + CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg, &pubkey) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_create(CTX, &pubkey, NULL)); /* That pubkeyload fails via an ARGCHECK is a little odd but makes sense because pubkeys are an opaque data type. */ - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, &pubkey) == 0); - CHECK(ecount == 8); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_verify(CTX, &sig, msg, &pubkey)); siglen = 72; - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, NULL, &siglen, &sig) == 0); - CHECK(ecount == 9); - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, NULL, &sig) == 0); - CHECK(ecount == 10); - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, NULL) == 0); - CHECK(ecount == 11); - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 1); - CHECK(ecount == 11); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, NULL, signature, siglen) == 0); - CHECK(ecount == 12); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, NULL, siglen) == 0); - CHECK(ecount == 13); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, signature, siglen) == 1); - CHECK(ecount == 13); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_serialize_der(CTX, NULL, &siglen, &sig)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_serialize_der(CTX, signature, NULL, &sig)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_serialize_der(CTX, signature, &siglen, NULL)); + CHECK(secp256k1_ecdsa_signature_serialize_der(CTX, signature, &siglen, &sig) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_parse_der(CTX, NULL, signature, siglen)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_parse_der(CTX, &sig, NULL, siglen)); + CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, signature, siglen) == 1); siglen = 10; /* Too little room for a signature does not fail via ARGCHECK. */ - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 0); - CHECK(ecount == 13); - ecount = 0; - CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, NULL) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, NULL, &sig) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, signature, NULL) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, signature, &sig) == 1); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, NULL, signature) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, NULL) == 0); - CHECK(ecount == 5); - CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature) == 1); - CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_signature_serialize_der(CTX, signature, &siglen, &sig) == 0); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_normalize(CTX, NULL, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_serialize_compact(CTX, NULL, &sig)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_serialize_compact(CTX, signature, NULL)); + CHECK(secp256k1_ecdsa_signature_serialize_compact(CTX, signature, &sig) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_parse_compact(CTX, NULL, signature)); + CHECK_ILLEGAL(CTX, secp256k1_ecdsa_signature_parse_compact(CTX, &sig, NULL)); + CHECK(secp256k1_ecdsa_signature_parse_compact(CTX, &sig, signature) == 1); memset(signature, 255, 64); - CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature) == 0); - CHECK(ecount == 5); - secp256k1_context_set_illegal_callback(ctx, NULL, NULL); + CHECK(secp256k1_ecdsa_signature_parse_compact(CTX, &sig, signature) == 0); } /* Nonce function corner cases. */ @@ -4228,33 +7298,33 @@ void test_ecdsa_edge_cases(void) { msg[31] = 1; /* High key results in signature failure. */ memset(key, 0xFF, 32); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, msg, key, NULL, extra) == 0); CHECK(is_empty_signature(&sig)); /* Zero key results in signature failure. */ memset(key, 0, 32); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, msg, key, NULL, extra) == 0); CHECK(is_empty_signature(&sig)); /* Nonce function failure results in signature failure. */ key[31] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_fail, extra) == 0); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, msg, key, nonce_function_test_fail, extra) == 0); CHECK(is_empty_signature(&sig)); /* The retry loop successfully makes its way to the first good value. */ - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_retry, extra) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &sig, msg, key, nonce_function_test_retry, extra) == 1); CHECK(!is_empty_signature(&sig)); - CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, nonce_function_rfc6979, extra) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &sig2, msg, key, nonce_function_rfc6979, extra) == 1); CHECK(!is_empty_signature(&sig2)); - CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0); + CHECK(secp256k1_memcmp_var(&sig, &sig2, sizeof(sig)) == 0); /* The default nonce function is deterministic. */ - CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &sig2, msg, key, NULL, extra) == 1); CHECK(!is_empty_signature(&sig2)); - CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0); + CHECK(secp256k1_memcmp_var(&sig, &sig2, sizeof(sig)) == 0); /* The default nonce function changes output with different messages. */ for(i = 0; i < 256; i++) { int j; msg[0] = i; - CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &sig2, msg, key, NULL, extra) == 1); CHECK(!is_empty_signature(&sig2)); - secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2); + secp256k1_ecdsa_signature_load(CTX, &sr[i], &ss, &sig2); for (j = 0; j < i; j++) { CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j])); } @@ -4265,9 +7335,9 @@ void test_ecdsa_edge_cases(void) { for(i = 256; i < 512; i++) { int j; key[0] = i - 256; - CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(CTX, &sig2, msg, key, NULL, extra) == 1); CHECK(!is_empty_signature(&sig2)); - secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2); + secp256k1_ecdsa_signature_load(CTX, &sr[i], &ss, &sig2); for (j = 0; j < i; j++) { CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j])); } @@ -4282,24 +7352,24 @@ void test_ecdsa_edge_cases(void) { unsigned char nonce2[32]; unsigned char nonce3[32]; unsigned char nonce4[32]; - VG_UNDEF(nonce,32); - VG_UNDEF(nonce2,32); - VG_UNDEF(nonce3,32); - VG_UNDEF(nonce4,32); + SECP256K1_CHECKMEM_UNDEFINE(nonce,32); + SECP256K1_CHECKMEM_UNDEFINE(nonce2,32); + SECP256K1_CHECKMEM_UNDEFINE(nonce3,32); + SECP256K1_CHECKMEM_UNDEFINE(nonce4,32); CHECK(nonce_function_rfc6979(nonce, zeros, zeros, NULL, NULL, 0) == 1); - VG_CHECK(nonce,32); + SECP256K1_CHECKMEM_CHECK(nonce,32); CHECK(nonce_function_rfc6979(nonce2, zeros, zeros, zeros, NULL, 0) == 1); - VG_CHECK(nonce2,32); + SECP256K1_CHECKMEM_CHECK(nonce2,32); CHECK(nonce_function_rfc6979(nonce3, zeros, zeros, NULL, (void *)zeros, 0) == 1); - VG_CHECK(nonce3,32); + SECP256K1_CHECKMEM_CHECK(nonce3,32); CHECK(nonce_function_rfc6979(nonce4, zeros, zeros, zeros, (void *)zeros, 0) == 1); - VG_CHECK(nonce4,32); - CHECK(memcmp(nonce, nonce2, 32) != 0); - CHECK(memcmp(nonce, nonce3, 32) != 0); - CHECK(memcmp(nonce, nonce4, 32) != 0); - CHECK(memcmp(nonce2, nonce3, 32) != 0); - CHECK(memcmp(nonce2, nonce4, 32) != 0); - CHECK(memcmp(nonce3, nonce4, 32) != 0); + SECP256K1_CHECKMEM_CHECK(nonce4,32); + CHECK(secp256k1_memcmp_var(nonce, nonce2, 32) != 0); + CHECK(secp256k1_memcmp_var(nonce, nonce3, 32) != 0); + CHECK(secp256k1_memcmp_var(nonce, nonce4, 32) != 0); + CHECK(secp256k1_memcmp_var(nonce2, nonce3, 32) != 0); + CHECK(secp256k1_memcmp_var(nonce2, nonce4, 32) != 0); + CHECK(secp256k1_memcmp_var(nonce3, nonce4, 32) != 0); } @@ -4313,175 +7383,399 @@ void test_ecdsa_edge_cases(void) { 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, }; size_t outlen = 300; - CHECK(!ec_privkey_export_der(ctx, privkey, &outlen, seckey, 0)); + CHECK(!ec_privkey_export_der(CTX, privkey, &outlen, seckey, 0)); outlen = 300; - CHECK(!ec_privkey_export_der(ctx, privkey, &outlen, seckey, 1)); + CHECK(!ec_privkey_export_der(CTX, privkey, &outlen, seckey, 1)); } } -void run_ecdsa_edge_cases(void) { +static void run_ecdsa_edge_cases(void) { test_ecdsa_edge_cases(); } -#ifdef ENABLE_OPENSSL_TESTS -EC_KEY *get_openssl_key(const unsigned char *key32) { - unsigned char privkey[300]; - size_t privkeylen; - const unsigned char* pbegin = privkey; - int compr = secp256k1_rand_bits(1); - EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); - CHECK(ec_privkey_export_der(ctx, privkey, &privkeylen, key32, compr)); - CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen)); - CHECK(EC_KEY_check_key(ec_key)); - return ec_key; -} +/** Wycheproof tests -void test_ecdsa_openssl(void) { - secp256k1_gej qj; - secp256k1_ge q; - secp256k1_scalar sigr, sigs; - secp256k1_scalar one; - secp256k1_scalar msg2; - secp256k1_scalar key, msg; - EC_KEY *ec_key; - unsigned int sigsize = 80; - size_t secp_sigsize = 80; - unsigned char message[32]; - unsigned char signature[80]; - unsigned char key32[32]; - secp256k1_rand256_test(message); - secp256k1_scalar_set_b32(&msg, message, NULL); - random_scalar_order_test(&key); - secp256k1_scalar_get_b32(key32, &key); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key); - secp256k1_ge_set_gej(&q, &qj); - ec_key = get_openssl_key(key32); - CHECK(ec_key != NULL); - CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); - CHECK(secp256k1_ecdsa_sig_parse(&sigr, &sigs, signature, sigsize)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg)); - secp256k1_scalar_set_int(&one, 1); - secp256k1_scalar_add(&msg2, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg2)); +The tests check for known attacks (range checks in (r,s), arithmetic errors, malleability). +*/ +static void test_ecdsa_wycheproof(void) { + #include "wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h" - random_sign(&sigr, &sigs, &key, &msg, NULL); - CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sigr, &sigs)); - CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1); + int t; + for (t = 0; t < SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS; t++) { + secp256k1_ecdsa_signature signature; + secp256k1_sha256 hasher; + secp256k1_pubkey pubkey; + const unsigned char *msg, *sig, *pk; + unsigned char out[32] = {0}; + int actual_verify = 0; - EC_KEY_free(ec_key); -} + memset(&pubkey, 0, sizeof(pubkey)); + pk = &wycheproof_ecdsa_public_keys[testvectors[t].pk_offset]; + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pk, 65) == 1); -void run_ecdsa_openssl(void) { - int i; - for (i = 0; i < 10*count; i++) { - test_ecdsa_openssl(); + secp256k1_sha256_initialize(&hasher); + msg = &wycheproof_ecdsa_messages[testvectors[t].msg_offset]; + secp256k1_sha256_write(&hasher, msg, testvectors[t].msg_len); + secp256k1_sha256_finalize(&hasher, out); + + sig = &wycheproof_ecdsa_signatures[testvectors[t].sig_offset]; + if (secp256k1_ecdsa_signature_parse_der(CTX, &signature, sig, testvectors[t].sig_len) == 1) { + actual_verify = secp256k1_ecdsa_verify(CTX, (const secp256k1_ecdsa_signature *)&signature, out, &pubkey); + } + CHECK(testvectors[t].expected_verify == actual_verify); } } -#endif + +/* Tests cases from Wycheproof test suite. */ +static void run_ecdsa_wycheproof(void) { + test_ecdsa_wycheproof(); +} #ifdef ENABLE_MODULE_ECDH # include "modules/ecdh/tests_impl.h" #endif -#ifdef ENABLE_MODULE_SCHNORR -# include "modules/schnorr/tests_impl.h" -#endif - #ifdef ENABLE_MODULE_RECOVERY # include "modules/recovery/tests_impl.h" #endif +#ifdef ENABLE_MODULE_EXTRAKEYS +# include "modules/extrakeys/tests_impl.h" +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG +# include "modules/schnorrsig/tests_impl.h" +#endif + +#ifdef ENABLE_MODULE_MUSIG +# include "modules/musig/tests_impl.h" +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT +# include "modules/ellswift/tests_impl.h" +#endif + +static void run_secp256k1_memczero_test(void) { + unsigned char buf1[6] = {1, 2, 3, 4, 5, 6}; + unsigned char buf2[sizeof(buf1)]; + + /* secp256k1_memczero(..., ..., 0) is a noop. */ + memcpy(buf2, buf1, sizeof(buf1)); + secp256k1_memczero(buf1, sizeof(buf1), 0); + CHECK(secp256k1_memcmp_var(buf1, buf2, sizeof(buf1)) == 0); + + /* secp256k1_memczero(..., ..., 1) zeros the buffer. */ + memset(buf2, 0, sizeof(buf2)); + secp256k1_memczero(buf1, sizeof(buf1) , 1); + CHECK(secp256k1_memcmp_var(buf1, buf2, sizeof(buf1)) == 0); +} + + +static void run_secp256k1_is_zero_array_test(void) { + unsigned char buf1[3] = {0, 1}; + unsigned char buf2[3] = {1, 0}; + + CHECK(secp256k1_is_zero_array(buf1, 0) == 1); + CHECK(secp256k1_is_zero_array(buf1, 1) == 1); + CHECK(secp256k1_is_zero_array(buf1, 2) == 0); + CHECK(secp256k1_is_zero_array(buf2, 1) == 0); + CHECK(secp256k1_is_zero_array(buf2, 2) == 0); +} + +static void run_secp256k1_byteorder_tests(void) { + { + const uint32_t x = 0xFF03AB45; + const unsigned char x_be[4] = {0xFF, 0x03, 0xAB, 0x45}; + unsigned char buf[4]; + uint32_t x_; + + secp256k1_write_be32(buf, x); + CHECK(secp256k1_memcmp_var(buf, x_be, sizeof(buf)) == 0); + + x_ = secp256k1_read_be32(buf); + CHECK(x == x_); + } + + { + const uint64_t x = 0xCAFE0123BEEF4567; + const unsigned char x_be[8] = {0xCA, 0xFE, 0x01, 0x23, 0xBE, 0xEF, 0x45, 0x67}; + unsigned char buf[8]; + uint64_t x_; + + secp256k1_write_be64(buf, x); + CHECK(secp256k1_memcmp_var(buf, x_be, sizeof(buf)) == 0); + + x_ = secp256k1_read_be64(buf); + CHECK(x == x_); + } +} + +static void int_cmov_test(void) { + int r = INT_MAX; + int a = 0; + + secp256k1_int_cmov(&r, &a, 0); + CHECK(r == INT_MAX); + + r = 0; a = INT_MAX; + secp256k1_int_cmov(&r, &a, 1); + CHECK(r == INT_MAX); + + a = 0; + secp256k1_int_cmov(&r, &a, 1); + CHECK(r == 0); + + a = 1; + secp256k1_int_cmov(&r, &a, 1); + CHECK(r == 1); + + r = 1; a = 0; + secp256k1_int_cmov(&r, &a, 0); + CHECK(r == 1); + +} + +static void fe_cmov_test(void) { + static const secp256k1_fe zero = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0); + static const secp256k1_fe one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); + static const secp256k1_fe max = SECP256K1_FE_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL + ); + secp256k1_fe r = max; + secp256k1_fe a = zero; + + secp256k1_fe_cmov(&r, &a, 0); + CHECK(fe_identical(&r, &max)); + + r = zero; a = max; + secp256k1_fe_cmov(&r, &a, 1); + CHECK(fe_identical(&r, &max)); + + a = zero; + secp256k1_fe_cmov(&r, &a, 1); + CHECK(fe_identical(&r, &zero)); + + a = one; + secp256k1_fe_cmov(&r, &a, 1); + CHECK(fe_identical(&r, &one)); + + r = one; a = zero; + secp256k1_fe_cmov(&r, &a, 0); + CHECK(fe_identical(&r, &one)); +} + +static void fe_storage_cmov_test(void) { + static const secp256k1_fe_storage zero = SECP256K1_FE_STORAGE_CONST(0, 0, 0, 0, 0, 0, 0, 0); + static const secp256k1_fe_storage one = SECP256K1_FE_STORAGE_CONST(0, 0, 0, 0, 0, 0, 0, 1); + static const secp256k1_fe_storage max = SECP256K1_FE_STORAGE_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL + ); + secp256k1_fe_storage r = max; + secp256k1_fe_storage a = zero; + + secp256k1_fe_storage_cmov(&r, &a, 0); + CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0); + + r = zero; a = max; + secp256k1_fe_storage_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0); + + a = zero; + secp256k1_fe_storage_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &zero, sizeof(r)) == 0); + + a = one; + secp256k1_fe_storage_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &one, sizeof(r)) == 0); + + r = one; a = zero; + secp256k1_fe_storage_cmov(&r, &a, 0); + CHECK(secp256k1_memcmp_var(&r, &one, sizeof(r)) == 0); +} + +static void scalar_cmov_test(void) { + static const secp256k1_scalar max = SECP256K1_SCALAR_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, + 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364140UL + ); + secp256k1_scalar r = max; + secp256k1_scalar a = secp256k1_scalar_zero; + + secp256k1_scalar_cmov(&r, &a, 0); + CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0); + + r = secp256k1_scalar_zero; a = max; + secp256k1_scalar_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0); + + a = secp256k1_scalar_zero; + secp256k1_scalar_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &secp256k1_scalar_zero, sizeof(r)) == 0); + + a = secp256k1_scalar_one; + secp256k1_scalar_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &secp256k1_scalar_one, sizeof(r)) == 0); + + r = secp256k1_scalar_one; a = secp256k1_scalar_zero; + secp256k1_scalar_cmov(&r, &a, 0); + CHECK(secp256k1_memcmp_var(&r, &secp256k1_scalar_one, sizeof(r)) == 0); +} + +static void ge_storage_cmov_test(void) { + static const secp256k1_ge_storage zero = SECP256K1_GE_STORAGE_CONST(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + static const secp256k1_ge_storage one = SECP256K1_GE_STORAGE_CONST(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1); + static const secp256k1_ge_storage max = SECP256K1_GE_STORAGE_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL + ); + secp256k1_ge_storage r = max; + secp256k1_ge_storage a = zero; + + secp256k1_ge_storage_cmov(&r, &a, 0); + CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0); + + r = zero; a = max; + secp256k1_ge_storage_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0); + + a = zero; + secp256k1_ge_storage_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &zero, sizeof(r)) == 0); + + a = one; + secp256k1_ge_storage_cmov(&r, &a, 1); + CHECK(secp256k1_memcmp_var(&r, &one, sizeof(r)) == 0); + + r = one; a = zero; + secp256k1_ge_storage_cmov(&r, &a, 0); + CHECK(secp256k1_memcmp_var(&r, &one, sizeof(r)) == 0); +} + +static void run_cmov_tests(void) { + int_cmov_test(); + fe_cmov_test(); + fe_storage_cmov_test(); + scalar_cmov_test(); + ge_storage_cmov_test(); +} + int main(int argc, char **argv) { - unsigned char seed16[16] = {0}; - unsigned char run32[32] = {0}; + /* Disable buffering for stdout to improve reliability of getting + * diagnostic information. Happens right at the start of main because + * setbuf must be used before any other operation on the stream. */ + setbuf(stdout, NULL); + /* Also disable buffering for stderr because it's not guaranteed that it's + * unbuffered on all systems. */ + setbuf(stderr, NULL); + /* find iteration count */ if (argc > 1) { - count = strtol(argv[1], NULL, 0); + COUNT = strtol(argv[1], NULL, 0); + } else { + const char* env = getenv("SECP256K1_TEST_ITERS"); + if (env && strlen(env) > 0) { + COUNT = strtol(env, NULL, 0); + } } + if (COUNT <= 0) { + fputs("An iteration count of 0 or less is not allowed.\n", stderr); + return EXIT_FAILURE; + } + printf("test count = %i\n", COUNT); + + /* run test RNG tests (must run before we really initialize the test RNG) */ + run_xoshiro256pp_tests(); /* find random seed */ - if (argc > 2) { - int pos = 0; - const char* ch = argv[2]; - while (pos < 16 && ch[0] != 0 && ch[1] != 0) { - unsigned short sh; - if (sscanf(ch, "%2hx", &sh)) { - seed16[pos] = sh; - } else { - break; - } - ch += 2; - pos++; - } - } else { - FILE *frand = fopen("/dev/urandom", "r"); - if ((frand == NULL) || !fread(&seed16, sizeof(seed16), 1, frand)) { - uint64_t t = time(NULL) * (uint64_t)1337; - seed16[0] ^= t; - seed16[1] ^= t >> 8; - seed16[2] ^= t >> 16; - seed16[3] ^= t >> 24; - seed16[4] ^= t >> 32; - seed16[5] ^= t >> 40; - seed16[6] ^= t >> 48; - seed16[7] ^= t >> 56; - } - fclose(frand); + testrand_init(argc > 2 ? argv[2] : NULL); + + /*** Setup test environment ***/ + + /* Create a global context available to all tests */ + CTX = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + /* Randomize the context only with probability 15/16 + to make sure we test without context randomization from time to time. + TODO Reconsider this when recalibrating the tests. */ + if (testrand_bits(4)) { + unsigned char rand32[32]; + testrand256(rand32); + CHECK(secp256k1_context_randomize(CTX, rand32)); } - secp256k1_rand_seed(seed16); + /* Make a writable copy of secp256k1_context_static in order to test the effect of API functions + that write to the context. The API does not support cloning the static context, so we use + memcpy instead. The user is not supposed to copy a context but we should still ensure that + the API functions handle copies of the static context gracefully. */ + STATIC_CTX = malloc(sizeof(*secp256k1_context_static)); + CHECK(STATIC_CTX != NULL); + memcpy(STATIC_CTX, secp256k1_context_static, sizeof(secp256k1_context)); + CHECK(!secp256k1_context_is_proper(STATIC_CTX)); - printf("test count = %i\n", count); - printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); + /*** Run actual tests ***/ - /* initialize */ - run_context_tests(); - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if (secp256k1_rand_bits(1)) { - secp256k1_rand256(run32); - CHECK(secp256k1_context_randomize(ctx, secp256k1_rand_bits(1) ? run32 : NULL)); - } + /* selftest tests */ + run_selftest_tests(); - run_rand_bits(); - run_rand_int(); + /* context tests */ + run_proper_context_tests(0); run_proper_context_tests(1); + run_static_context_tests(0); run_static_context_tests(1); + run_deprecated_context_flags_test(); - run_sha256_tests(); + /* scratch tests */ + run_scratch_tests(); + + /* integer arithmetic tests */ +#ifdef SECP256K1_WIDEMUL_INT128 + run_int128_tests(); +#endif + run_ctz_tests(); + run_modinv_tests(); + run_inverse_tests(); + + /* sorting tests */ + run_hsort_tests(); + + /* hash tests */ + run_sha256_known_output_tests(); + run_sha256_counter_tests(); run_hmac_sha256_tests(); run_rfc6979_hmac_sha256_tests(); - -#ifndef USE_NUM_NONE - /* num tests */ - run_num_smalltests(); -#endif + run_tagged_sha256_tests(); /* scalar tests */ run_scalar_tests(); /* field tests */ - run_field_inv(); - run_field_inv_var(); - run_field_inv_all_var(); + run_field_half(); run_field_misc(); run_field_convert(); + run_field_be32_overflow(); + run_fe_mul(); run_sqr(); run_sqrt(); /* group tests */ run_ge(); + run_gej(); run_group_decompress(); /* ecmult tests */ + run_ecmult_pre_g(); run_wnaf(); run_point_times_order(); + run_ecmult_near_split_bound(); run_ecmult_chain(); run_ecmult_constants(); run_ecmult_gen_blind(); run_ecmult_const_tests(); + run_ecmult_multi_tests(); run_ec_combine(); /* endomorphism tests */ -#ifdef USE_ENDOMORPHISM run_endomorphism_tests(); -#endif /* EC point parser test */ run_ec_pubkey_parse_test(); @@ -4489,37 +7783,59 @@ int main(int argc, char **argv) { /* EC key edge cases */ run_eckey_edge_case_test(); + /* EC key arithmetic test */ + run_eckey_negate_test(); + #ifdef ENABLE_MODULE_ECDH /* ecdh tests */ run_ecdh_tests(); #endif /* ecdsa tests */ + run_ec_illegal_argument_tests(); + run_pubkey_comparison(); + run_pubkey_sort(); run_random_pubkeys(); run_ecdsa_der_parse(); run_ecdsa_sign_verify(); run_ecdsa_end_to_end(); run_ecdsa_edge_cases(); -#ifdef ENABLE_OPENSSL_TESTS - run_ecdsa_openssl(); -#endif - -#ifdef ENABLE_MODULE_SCHNORR - /* Schnorr tests */ - run_schnorr_tests(); -#endif + run_ecdsa_wycheproof(); #ifdef ENABLE_MODULE_RECOVERY /* ECDSA pubkey recovery tests */ run_recovery_tests(); #endif - secp256k1_rand256(run32); - printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); +#ifdef ENABLE_MODULE_EXTRAKEYS + run_extrakeys_tests(); +#endif - /* shutdown */ - secp256k1_context_destroy(ctx); +#ifdef ENABLE_MODULE_SCHNORRSIG + run_schnorrsig_tests(); +#endif + +#ifdef ENABLE_MODULE_MUSIG + run_musig_tests(); +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT + run_ellswift_tests(); +#endif + + /* util tests */ + run_secp256k1_memczero_test(); + run_secp256k1_is_zero_array_test(); + run_secp256k1_byteorder_tests(); + + run_cmov_tests(); + + /*** Tear down test environment ***/ + free(STATIC_CTX); + secp256k1_context_destroy(CTX); + + testrand_finish(); printf("no problems found\n"); - return 0; + return EXIT_SUCCESS; } diff --git a/crypto/secp256k1/libsecp256k1/src/tests_exhaustive.c b/crypto/secp256k1/libsecp256k1/src/tests_exhaustive.c index b040bb0733..f8bbcaaf5c 100644 --- a/crypto/secp256k1/libsecp256k1/src/tests_exhaustive.c +++ b/crypto/secp256k1/libsecp256k1/src/tests_exhaustive.c @@ -1,75 +1,48 @@ /*********************************************************************** - * Copyright (c) 2016 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif + * Copyright (c) 2016 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include #include - #include -#undef USE_ECMULT_STATIC_PRECOMPUTATION - #ifndef EXHAUSTIVE_TEST_ORDER /* see group_impl.h for allowable values */ #define EXHAUSTIVE_TEST_ORDER 13 -#define EXHAUSTIVE_TEST_LAMBDA 9 /* cube root of 1 mod 13 */ #endif -#include "include/secp256k1.h" -#include "group.h" +/* These values of B are all values in [1, 8] that result in a curve with even order. */ +#define EXHAUSTIVE_TEST_CURVE_HAS_EVEN_ORDER (SECP256K1_B == 1 || SECP256K1_B == 6 || SECP256K1_B == 8) + +#ifdef USE_EXTERNAL_DEFAULT_CALLBACKS + #pragma message("Ignoring USE_EXTERNAL_CALLBACKS in exhaustive_tests.") + #undef USE_EXTERNAL_DEFAULT_CALLBACKS +#endif #include "secp256k1.c" + +#include "../include/secp256k1.h" +#include "assumptions.h" +#include "group.h" #include "testrand_impl.h" +#include "ecmult_compute_table_impl.h" +#include "ecmult_gen_compute_table_impl.h" +#include "testutil.h" +#include "util.h" -#ifdef ENABLE_MODULE_RECOVERY -#include "src/modules/recovery/main_impl.h" -#include "include/secp256k1_recovery.h" -#endif +static int count = 2; -/** stolen from tests.c */ -void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { - CHECK(a->infinity == b->infinity); - if (a->infinity) { - return; - } - CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); - CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); +static uint32_t num_cores = 1; +static uint32_t this_core = 0; + +SECP256K1_INLINE static int skip_section(uint64_t* iter) { + if (num_cores == 1) return 0; + *iter += 0xe7037ed1a0b428dbULL; + return ((((uint32_t)*iter ^ (*iter >> 32)) * num_cores) >> 32) != this_core; } -void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { - secp256k1_fe z2s; - secp256k1_fe u1, u2, s1, s2; - CHECK(a->infinity == b->infinity); - if (a->infinity) { - return; - } - /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ - secp256k1_fe_sqr(&z2s, &b->z); - secp256k1_fe_mul(&u1, &a->x, &z2s); - u2 = b->x; secp256k1_fe_normalize_weak(&u2); - secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); - s2 = b->y; secp256k1_fe_normalize_weak(&s2); - CHECK(secp256k1_fe_equal_var(&u1, &u2)); - CHECK(secp256k1_fe_equal_var(&s1, &s2)); -} - -void random_fe(secp256k1_fe *x) { - unsigned char bin[32]; - do { - secp256k1_rand256(bin); - if (secp256k1_fe_set_b32(x, bin)) { - return; - } - } while(1); -} -/** END stolen from tests.c */ - -int secp256k1_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg32, +static int secp256k1_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int attempt) { secp256k1_scalar s; @@ -89,115 +62,184 @@ int secp256k1_nonce_function_smallint(unsigned char *nonce32, const unsigned cha return 1; } -#ifdef USE_ENDOMORPHISM -void test_exhaustive_endomorphism(const secp256k1_ge *group, int order) { +static void test_exhaustive_endomorphism(const secp256k1_ge *group) { int i; - for (i = 0; i < order; i++) { + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) { secp256k1_ge res; secp256k1_ge_mul_lambda(&res, &group[i]); - ge_equals_ge(&group[i * EXHAUSTIVE_TEST_LAMBDA % EXHAUSTIVE_TEST_ORDER], &res); + CHECK(secp256k1_ge_eq_var(&group[i * EXHAUSTIVE_TEST_LAMBDA % EXHAUSTIVE_TEST_ORDER], &res)); } } -#endif -void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { +static void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj) { int i, j; + uint64_t iter = 0; /* Sanity-check (and check infinity functions) */ CHECK(secp256k1_ge_is_infinity(&group[0])); CHECK(secp256k1_gej_is_infinity(&groupj[0])); - for (i = 1; i < order; i++) { + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { CHECK(!secp256k1_ge_is_infinity(&group[i])); CHECK(!secp256k1_gej_is_infinity(&groupj[i])); } /* Check all addition formulae */ - for (j = 0; j < order; j++) { + for (j = 0; j < EXHAUSTIVE_TEST_ORDER; j++) { secp256k1_fe fe_inv; + if (skip_section(&iter)) continue; secp256k1_fe_inv(&fe_inv, &groupj[j].z); - for (i = 0; i < order; i++) { + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) { secp256k1_ge zless_gej; secp256k1_gej tmp; /* add_var */ secp256k1_gej_add_var(&tmp, &groupj[i], &groupj[j], NULL); - ge_equals_gej(&group[(i + j) % order], &tmp); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(i + j) % EXHAUSTIVE_TEST_ORDER])); /* add_ge */ if (j > 0) { secp256k1_gej_add_ge(&tmp, &groupj[i], &group[j]); - ge_equals_gej(&group[(i + j) % order], &tmp); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(i + j) % EXHAUSTIVE_TEST_ORDER])); } /* add_ge_var */ secp256k1_gej_add_ge_var(&tmp, &groupj[i], &group[j], NULL); - ge_equals_gej(&group[(i + j) % order], &tmp); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(i + j) % EXHAUSTIVE_TEST_ORDER])); /* add_zinv_var */ zless_gej.infinity = groupj[j].infinity; zless_gej.x = groupj[j].x; zless_gej.y = groupj[j].y; secp256k1_gej_add_zinv_var(&tmp, &groupj[i], &zless_gej, &fe_inv); - ge_equals_gej(&group[(i + j) % order], &tmp); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(i + j) % EXHAUSTIVE_TEST_ORDER])); } } /* Check doubling */ - for (i = 0; i < order; i++) { + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) { secp256k1_gej tmp; - if (i > 0) { - secp256k1_gej_double_nonzero(&tmp, &groupj[i], NULL); - ge_equals_gej(&group[(2 * i) % order], &tmp); - } + secp256k1_gej_double(&tmp, &groupj[i]); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(2 * i) % EXHAUSTIVE_TEST_ORDER])); secp256k1_gej_double_var(&tmp, &groupj[i], NULL); - ge_equals_gej(&group[(2 * i) % order], &tmp); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(2 * i) % EXHAUSTIVE_TEST_ORDER])); } /* Check negation */ - for (i = 1; i < order; i++) { + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { secp256k1_ge tmp; secp256k1_gej tmpj; secp256k1_ge_neg(&tmp, &group[i]); - ge_equals_ge(&group[order - i], &tmp); + CHECK(secp256k1_ge_eq_var(&tmp, &group[EXHAUSTIVE_TEST_ORDER - i])); secp256k1_gej_neg(&tmpj, &groupj[i]); - ge_equals_gej(&group[order - i], &tmpj); + CHECK(secp256k1_gej_eq_ge_var(&tmpj, &group[EXHAUSTIVE_TEST_ORDER - i])); } } -void test_exhaustive_ecmult(const secp256k1_context *ctx, const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { +static void test_exhaustive_ecmult(const secp256k1_ge *group, const secp256k1_gej *groupj) { int i, j, r_log; - for (r_log = 1; r_log < order; r_log++) { - for (j = 0; j < order; j++) { - for (i = 0; i < order; i++) { + uint64_t iter = 0; + for (r_log = 1; r_log < EXHAUSTIVE_TEST_ORDER; r_log++) { + for (j = 0; j < EXHAUSTIVE_TEST_ORDER; j++) { + if (skip_section(&iter)) continue; + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) { secp256k1_gej tmp; secp256k1_scalar na, ng; secp256k1_scalar_set_int(&na, i); secp256k1_scalar_set_int(&ng, j); - secp256k1_ecmult(&ctx->ecmult_ctx, &tmp, &groupj[r_log], &na, &ng); - ge_equals_gej(&group[(i * r_log + j) % order], &tmp); + secp256k1_ecmult(&tmp, &groupj[r_log], &na, &ng); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(i * r_log + j) % EXHAUSTIVE_TEST_ORDER])); + } + } + } - if (i > 0) { - secp256k1_ecmult_const(&tmp, &group[i], &ng); - ge_equals_gej(&group[(i * j) % order], &tmp); - } + for (j = 0; j < EXHAUSTIVE_TEST_ORDER; j++) { + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) { + int ret; + secp256k1_gej tmp; + secp256k1_fe xn, xd, tmpf; + secp256k1_scalar ng; + + if (skip_section(&iter)) continue; + + secp256k1_scalar_set_int(&ng, j); + + /* Test secp256k1_ecmult_const. */ + secp256k1_ecmult_const(&tmp, &group[i], &ng); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(i * j) % EXHAUSTIVE_TEST_ORDER])); + + if (i != 0 && j != 0) { + /* Test secp256k1_ecmult_const_xonly with all curve X coordinates, and xd=NULL. */ + ret = secp256k1_ecmult_const_xonly(&tmpf, &group[i].x, NULL, &ng, 0); + CHECK(ret); + CHECK(secp256k1_fe_equal(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x)); + + /* Test secp256k1_ecmult_const_xonly with all curve X coordinates, with random xd. */ + testutil_random_fe_non_zero(&xd); + secp256k1_fe_mul(&xn, &xd, &group[i].x); + ret = secp256k1_ecmult_const_xonly(&tmpf, &xn, &xd, &ng, 0); + CHECK(ret); + CHECK(secp256k1_fe_equal(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x)); } } } } -void r_from_k(secp256k1_scalar *r, const secp256k1_ge *group, int k) { +typedef struct { + secp256k1_scalar sc[2]; + secp256k1_ge pt[2]; +} ecmult_multi_data; + +static int ecmult_multi_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *cbdata) { + ecmult_multi_data *data = (ecmult_multi_data*) cbdata; + *sc = data->sc[idx]; + *pt = data->pt[idx]; + return 1; +} + +static void test_exhaustive_ecmult_multi(const secp256k1_context *ctx, const secp256k1_ge *group) { + int i, j, k, x, y; + uint64_t iter = 0; + secp256k1_scratch *scratch = secp256k1_scratch_create(&ctx->error_callback, 4096); + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) { + for (j = 0; j < EXHAUSTIVE_TEST_ORDER; j++) { + for (k = 0; k < EXHAUSTIVE_TEST_ORDER; k++) { + for (x = 0; x < EXHAUSTIVE_TEST_ORDER; x++) { + if (skip_section(&iter)) continue; + for (y = 0; y < EXHAUSTIVE_TEST_ORDER; y++) { + secp256k1_gej tmp; + secp256k1_scalar g_sc; + ecmult_multi_data data; + + secp256k1_scalar_set_int(&data.sc[0], i); + secp256k1_scalar_set_int(&data.sc[1], j); + secp256k1_scalar_set_int(&g_sc, k); + data.pt[0] = group[x]; + data.pt[1] = group[y]; + + secp256k1_ecmult_multi_var(&ctx->error_callback, scratch, &tmp, &g_sc, ecmult_multi_callback, &data, 2); + CHECK(secp256k1_gej_eq_ge_var(&tmp, &group[(i * x + j * y + k) % EXHAUSTIVE_TEST_ORDER])); + } + } + } + } + } + secp256k1_scratch_destroy(&ctx->error_callback, scratch); +} + +static void r_from_k(secp256k1_scalar *r, const secp256k1_ge *group, int k, int* overflow) { secp256k1_fe x; unsigned char x_bin[32]; k %= EXHAUSTIVE_TEST_ORDER; x = group[k].x; secp256k1_fe_normalize(&x); secp256k1_fe_get_b32(x_bin, &x); - secp256k1_scalar_set_b32(r, x_bin, NULL); + secp256k1_scalar_set_b32(r, x_bin, overflow); } -void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { +static void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *group) { int s, r, msg, key; - for (s = 1; s < order; s++) { - for (r = 1; r < order; r++) { - for (msg = 1; msg < order; msg++) { - for (key = 1; key < order; key++) { + uint64_t iter = 0; + for (s = 1; s < EXHAUSTIVE_TEST_ORDER; s++) { + for (r = 1; r < EXHAUSTIVE_TEST_ORDER; r++) { + for (msg = 1; msg < EXHAUSTIVE_TEST_ORDER; msg++) { + for (key = 1; key < EXHAUSTIVE_TEST_ORDER; key++) { secp256k1_ge nonconst_ge; secp256k1_ecdsa_signature sig; secp256k1_pubkey pk; @@ -206,6 +248,8 @@ void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *gr int k, should_verify; unsigned char msg32[32]; + if (skip_section(&iter)) continue; + secp256k1_scalar_set_int(&s_s, s); secp256k1_scalar_set_int(&r_s, r); secp256k1_scalar_set_int(&msg_s, msg); @@ -215,9 +259,9 @@ void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *gr /* Run through every k value that gives us this r and check that *one* works. * Note there could be none, there could be multiple, ECDSA is weird. */ should_verify = 0; - for (k = 0; k < order; k++) { + for (k = 0; k < EXHAUSTIVE_TEST_ORDER; k++) { secp256k1_scalar check_x_s; - r_from_k(&check_x_s, group, k); + r_from_k(&check_x_s, group, k, NULL); if (r_s == check_x_s) { secp256k1_scalar_set_int(&s_times_k_s, k); secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); @@ -242,14 +286,17 @@ void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *gr } } -void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { +static void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *group) { int i, j, k; + uint64_t iter = 0; /* Loop */ - for (i = 1; i < order; i++) { /* message */ - for (j = 1; j < order; j++) { /* key */ - for (k = 1; k < order; k++) { /* nonce */ + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { /* message */ + for (j = 1; j < EXHAUSTIVE_TEST_ORDER; j++) { /* key */ + if (skip_section(&iter)) continue; + for (k = 1; k < EXHAUSTIVE_TEST_ORDER; k++) { /* nonce */ const int starting_k = k; + int ret; secp256k1_ecdsa_signature sig; secp256k1_scalar sk, msg, r, s, expected_r; unsigned char sk32[32], msg32[32]; @@ -258,16 +305,17 @@ void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *grou secp256k1_scalar_get_b32(sk32, &sk); secp256k1_scalar_get_b32(msg32, &msg); - secp256k1_ecdsa_sign(ctx, &sig, msg32, sk32, secp256k1_nonce_function_smallint, &k); + ret = secp256k1_ecdsa_sign(ctx, &sig, msg32, sk32, secp256k1_nonce_function_smallint, &k); + CHECK(ret == 1); secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); /* Note that we compute expected_r *after* signing -- this is important * because our nonce-computing function function might change k during * signing. */ - r_from_k(&expected_r, group, k); + r_from_k(&expected_r, group, k, NULL); CHECK(r == expected_r); - CHECK((k * s) % order == (i + r * j) % order || - (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); + CHECK((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER || + (k * (EXHAUSTIVE_TEST_ORDER - s)) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER); /* Overflow means we've tried every possible nonce */ if (k < starting_k) { @@ -288,183 +336,131 @@ void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *grou } #ifdef ENABLE_MODULE_RECOVERY -void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { - int i, j, k; - - /* Loop */ - for (i = 1; i < order; i++) { /* message */ - for (j = 1; j < order; j++) { /* key */ - for (k = 1; k < order; k++) { /* nonce */ - const int starting_k = k; - secp256k1_fe r_dot_y_normalized; - secp256k1_ecdsa_recoverable_signature rsig; - secp256k1_ecdsa_signature sig; - secp256k1_scalar sk, msg, r, s, expected_r; - unsigned char sk32[32], msg32[32]; - int expected_recid; - int recid; - secp256k1_scalar_set_int(&msg, i); - secp256k1_scalar_set_int(&sk, j); - secp256k1_scalar_get_b32(sk32, &sk); - secp256k1_scalar_get_b32(msg32, &msg); - - secp256k1_ecdsa_sign_recoverable(ctx, &rsig, msg32, sk32, secp256k1_nonce_function_smallint, &k); - - /* Check directly */ - secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, &rsig); - r_from_k(&expected_r, group, k); - CHECK(r == expected_r); - CHECK((k * s) % order == (i + r * j) % order || - (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); - /* In computing the recid, there is an overflow condition that is disabled in - * scalar_low_impl.h `secp256k1_scalar_set_b32` because almost every r.y value - * will exceed the group order, and our signing code always holds out for r - * values that don't overflow, so with a proper overflow check the tests would - * loop indefinitely. */ - r_dot_y_normalized = group[k].y; - secp256k1_fe_normalize(&r_dot_y_normalized); - /* Also the recovery id is flipped depending if we hit the low-s branch */ - if ((k * s) % order == (i + r * j) % order) { - expected_recid = secp256k1_fe_is_odd(&r_dot_y_normalized) ? 1 : 0; - } else { - expected_recid = secp256k1_fe_is_odd(&r_dot_y_normalized) ? 0 : 1; - } - CHECK(recid == expected_recid); - - /* Convert to a standard sig then check */ - secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig); - secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); - /* Note that we compute expected_r *after* signing -- this is important - * because our nonce-computing function function might change k during - * signing. */ - r_from_k(&expected_r, group, k); - CHECK(r == expected_r); - CHECK((k * s) % order == (i + r * j) % order || - (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); - - /* Overflow means we've tried every possible nonce */ - if (k < starting_k) { - break; - } - } - } - } -} - -void test_exhaustive_recovery_verify(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { - /* This is essentially a copy of test_exhaustive_verify, with recovery added */ - int s, r, msg, key; - for (s = 1; s < order; s++) { - for (r = 1; r < order; r++) { - for (msg = 1; msg < order; msg++) { - for (key = 1; key < order; key++) { - secp256k1_ge nonconst_ge; - secp256k1_ecdsa_recoverable_signature rsig; - secp256k1_ecdsa_signature sig; - secp256k1_pubkey pk; - secp256k1_scalar sk_s, msg_s, r_s, s_s; - secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s; - int recid = 0; - int k, should_verify; - unsigned char msg32[32]; - - secp256k1_scalar_set_int(&s_s, s); - secp256k1_scalar_set_int(&r_s, r); - secp256k1_scalar_set_int(&msg_s, msg); - secp256k1_scalar_set_int(&sk_s, key); - secp256k1_scalar_get_b32(msg32, &msg_s); - - /* Verify by hand */ - /* Run through every k value that gives us this r and check that *one* works. - * Note there could be none, there could be multiple, ECDSA is weird. */ - should_verify = 0; - for (k = 0; k < order; k++) { - secp256k1_scalar check_x_s; - r_from_k(&check_x_s, group, k); - if (r_s == check_x_s) { - secp256k1_scalar_set_int(&s_times_k_s, k); - secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); - secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s); - secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s); - should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s); - } - } - /* nb we have a "high s" rule */ - should_verify &= !secp256k1_scalar_is_high(&s_s); - - /* We would like to try recovering the pubkey and checking that it matches, - * but pubkey recovery is impossible in the exhaustive tests (the reason - * being that there are 12 nonzero r values, 12 nonzero points, and no - * overlap between the sets, so there are no valid signatures). */ - - /* Verify by converting to a standard signature and calling verify */ - secp256k1_ecdsa_recoverable_signature_save(&rsig, &r_s, &s_s, recid); - secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig); - memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge)); - secp256k1_pubkey_save(&pk, &nonconst_ge); - CHECK(should_verify == - secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk)); - } - } - } - } -} +#include "modules/recovery/tests_exhaustive_impl.h" #endif -int main(void) { +#ifdef ENABLE_MODULE_EXTRAKEYS +#include "modules/extrakeys/tests_exhaustive_impl.h" +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG +#include "modules/schnorrsig/tests_exhaustive_impl.h" +#endif + +#ifdef ENABLE_MODULE_ELLSWIFT +#include "modules/ellswift/tests_exhaustive_impl.h" +#endif + +int main(int argc, char** argv) { int i; secp256k1_gej groupj[EXHAUSTIVE_TEST_ORDER]; secp256k1_ge group[EXHAUSTIVE_TEST_ORDER]; + unsigned char rand32[32]; + secp256k1_context *ctx; - /* Build context */ - secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + /* Disable buffering for stdout to improve reliability of getting + * diagnostic information. Happens right at the start of main because + * setbuf must be used before any other operation on the stream. */ + setbuf(stdout, NULL); + /* Also disable buffering for stderr because it's not guaranteed that it's + * unbuffered on all systems. */ + setbuf(stderr, NULL); - /* TODO set z = 1, then do num_tests runs with random z values */ + printf("Exhaustive tests for order %lu\n", (unsigned long)EXHAUSTIVE_TEST_ORDER); - /* Generate the entire group */ - secp256k1_gej_set_infinity(&groupj[0]); - secp256k1_ge_set_gej(&group[0], &groupj[0]); - for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { - /* Set a different random z-value for each Jacobian point */ - secp256k1_fe z; - random_fe(&z); + /* find iteration count */ + if (argc > 1) { + count = strtol(argv[1], NULL, 0); + } + printf("test count = %i\n", count); - secp256k1_gej_add_ge(&groupj[i], &groupj[i - 1], &secp256k1_ge_const_g); - secp256k1_ge_set_gej(&group[i], &groupj[i]); - secp256k1_gej_rescale(&groupj[i], &z); + /* find random seed */ + testrand_init(argc > 2 ? argv[2] : NULL); - /* Verify against ecmult_gen */ - { - secp256k1_scalar scalar_i; - secp256k1_gej generatedj; - secp256k1_ge generated; - - secp256k1_scalar_set_int(&scalar_i, i); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &generatedj, &scalar_i); - secp256k1_ge_set_gej(&generated, &generatedj); - - CHECK(group[i].infinity == 0); - CHECK(generated.infinity == 0); - CHECK(secp256k1_fe_equal_var(&generated.x, &group[i].x)); - CHECK(secp256k1_fe_equal_var(&generated.y, &group[i].y)); + /* set up split processing */ + if (argc > 4) { + num_cores = strtol(argv[3], NULL, 0); + this_core = strtol(argv[4], NULL, 0); + if (num_cores < 1 || this_core >= num_cores) { + fprintf(stderr, "Usage: %s [count] [seed] [numcores] [thiscore]\n", argv[0]); + return EXIT_FAILURE; } + printf("running tests for core %lu (out of [0..%lu])\n", (unsigned long)this_core, (unsigned long)num_cores - 1); } - /* Run the tests */ -#ifdef USE_ENDOMORPHISM - test_exhaustive_endomorphism(group, EXHAUSTIVE_TEST_ORDER); -#endif - test_exhaustive_addition(group, groupj, EXHAUSTIVE_TEST_ORDER); - test_exhaustive_ecmult(ctx, group, groupj, EXHAUSTIVE_TEST_ORDER); - test_exhaustive_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); - test_exhaustive_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); + /* Recreate the ecmult{,_gen} tables using the right generator (as selected via EXHAUSTIVE_TEST_ORDER) */ + secp256k1_ecmult_gen_compute_table(&secp256k1_ecmult_gen_prec_table[0][0], &secp256k1_ge_const_g, COMB_BLOCKS, COMB_TEETH, COMB_SPACING); + secp256k1_ecmult_compute_two_tables(secp256k1_pre_g, secp256k1_pre_g_128, WINDOW_G, &secp256k1_ge_const_g); + + while (count--) { + /* Build context */ + ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + testrand256(rand32); + CHECK(secp256k1_context_randomize(ctx, rand32)); + + /* Generate the entire group */ + secp256k1_gej_set_infinity(&groupj[0]); + secp256k1_ge_set_gej(&group[0], &groupj[0]); + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { + secp256k1_gej_add_ge(&groupj[i], &groupj[i - 1], &secp256k1_ge_const_g); + secp256k1_ge_set_gej(&group[i], &groupj[i]); + if (count != 0) { + /* Set a different random z-value for each Jacobian point, except z=1 + is used in the last iteration. */ + secp256k1_fe z; + testutil_random_fe(&z); + secp256k1_gej_rescale(&groupj[i], &z); + } + + /* Verify against ecmult_gen */ + { + secp256k1_scalar scalar_i; + secp256k1_gej generatedj; + secp256k1_ge generated; + + secp256k1_scalar_set_int(&scalar_i, i); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &generatedj, &scalar_i); + secp256k1_ge_set_gej(&generated, &generatedj); + + CHECK(group[i].infinity == 0); + CHECK(generated.infinity == 0); + CHECK(secp256k1_fe_equal(&generated.x, &group[i].x)); + CHECK(secp256k1_fe_equal(&generated.y, &group[i].y)); + } + } + + /* Run the tests */ + test_exhaustive_endomorphism(group); + test_exhaustive_addition(group, groupj); + test_exhaustive_ecmult(group, groupj); + test_exhaustive_ecmult_multi(ctx, group); + test_exhaustive_sign(ctx, group); + test_exhaustive_verify(ctx, group); #ifdef ENABLE_MODULE_RECOVERY - test_exhaustive_recovery_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); - test_exhaustive_recovery_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_recovery(ctx, group); +#endif +#ifdef ENABLE_MODULE_EXTRAKEYS + test_exhaustive_extrakeys(ctx, group); +#endif +#ifdef ENABLE_MODULE_SCHNORRSIG + test_exhaustive_schnorrsig(ctx); +#endif +#ifdef ENABLE_MODULE_ELLSWIFT + /* The ellswift algorithm does have additional edge cases when operating on + * curves of even order, which are not included in the code as secp256k1 is + * of odd order. Skip the ellswift tests if the used exhaustive tests curve + * is even-ordered accordingly. */ + #if !EXHAUSTIVE_TEST_CURVE_HAS_EVEN_ORDER + test_exhaustive_ellswift(ctx, group); + #endif #endif - secp256k1_context_destroy(ctx); - return 0; -} + secp256k1_context_destroy(ctx); + } + testrand_finish(); + + printf("no problems found\n"); + return EXIT_SUCCESS; +} diff --git a/crypto/secp256k1/libsecp256k1/src/testutil.h b/crypto/secp256k1/libsecp256k1/src/testutil.h new file mode 100644 index 0000000000..64b3bb41c0 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/testutil.h @@ -0,0 +1,148 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_TESTUTIL_H +#define SECP256K1_TESTUTIL_H + +#include "field.h" +#include "group.h" +#include "testrand.h" +#include "util.h" + +static void testutil_random_fe(secp256k1_fe *x) { + unsigned char bin[32]; + do { + testrand256(bin); + if (secp256k1_fe_set_b32_limit(x, bin)) { + return; + } + } while(1); +} + +static void testutil_random_fe_non_zero(secp256k1_fe *nz) { + do { + testutil_random_fe(nz); + } while (secp256k1_fe_is_zero(nz)); +} + +static void testutil_random_fe_magnitude(secp256k1_fe *fe, int m) { + secp256k1_fe zero; + int n = testrand_int(m + 1); + secp256k1_fe_normalize(fe); + if (n == 0) { + return; + } + secp256k1_fe_set_int(&zero, 0); + secp256k1_fe_negate(&zero, &zero, 0); + secp256k1_fe_mul_int_unchecked(&zero, n - 1); + secp256k1_fe_add(fe, &zero); +#ifdef VERIFY + CHECK(fe->magnitude == n); +#endif +} + +static void testutil_random_fe_test(secp256k1_fe *x) { + unsigned char bin[32]; + do { + testrand256_test(bin); + if (secp256k1_fe_set_b32_limit(x, bin)) { + return; + } + } while(1); +} + +static void testutil_random_fe_non_zero_test(secp256k1_fe *fe) { + do { + testutil_random_fe_test(fe); + } while(secp256k1_fe_is_zero(fe)); +} + +static void testutil_random_ge_x_magnitude(secp256k1_ge *ge) { + testutil_random_fe_magnitude(&ge->x, SECP256K1_GE_X_MAGNITUDE_MAX); +} + +static void testutil_random_ge_y_magnitude(secp256k1_ge *ge) { + testutil_random_fe_magnitude(&ge->y, SECP256K1_GE_Y_MAGNITUDE_MAX); +} + +static void testutil_random_gej_x_magnitude(secp256k1_gej *gej) { + testutil_random_fe_magnitude(&gej->x, SECP256K1_GEJ_X_MAGNITUDE_MAX); +} + +static void testutil_random_gej_y_magnitude(secp256k1_gej *gej) { + testutil_random_fe_magnitude(&gej->y, SECP256K1_GEJ_Y_MAGNITUDE_MAX); +} + +static void testutil_random_gej_z_magnitude(secp256k1_gej *gej) { + testutil_random_fe_magnitude(&gej->z, SECP256K1_GEJ_Z_MAGNITUDE_MAX); +} + +static void testutil_random_ge_test(secp256k1_ge *ge) { + secp256k1_fe fe; + do { + testutil_random_fe_test(&fe); + if (secp256k1_ge_set_xo_var(ge, &fe, testrand_bits(1))) { + secp256k1_fe_normalize(&ge->y); + break; + } + } while(1); + ge->infinity = 0; +} + +static void testutil_random_ge_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { + secp256k1_fe z2, z3; + testutil_random_fe_non_zero_test(&gej->z); + secp256k1_fe_sqr(&z2, &gej->z); + secp256k1_fe_mul(&z3, &z2, &gej->z); + secp256k1_fe_mul(&gej->x, &ge->x, &z2); + secp256k1_fe_mul(&gej->y, &ge->y, &z3); + gej->infinity = ge->infinity; +} + +static void testutil_random_gej_test(secp256k1_gej *gej) { + secp256k1_ge ge; + testutil_random_ge_test(&ge); + testutil_random_ge_jacobian_test(gej, &ge); +} + +static void testutil_random_pubkey_test(secp256k1_pubkey *pk) { + secp256k1_ge ge; + testutil_random_ge_test(&ge); + secp256k1_pubkey_save(pk, &ge); +} + +static void testutil_random_scalar_order_test(secp256k1_scalar *num) { + do { + unsigned char b32[32]; + int overflow = 0; + testrand256_test(b32); + secp256k1_scalar_set_b32(num, b32, &overflow); + if (overflow || secp256k1_scalar_is_zero(num)) { + continue; + } + break; + } while(1); +} + +static void testutil_random_scalar_order(secp256k1_scalar *num) { + do { + unsigned char b32[32]; + int overflow = 0; + testrand256(b32); + secp256k1_scalar_set_b32(num, b32, &overflow); + if (overflow || secp256k1_scalar_is_zero(num)) { + continue; + } + break; + } while(1); +} + +static void testutil_random_scalar_order_b32(unsigned char *b32) { + secp256k1_scalar num; + testutil_random_scalar_order(&num); + secp256k1_scalar_get_b32(b32, &num); +} + +#endif /* SECP256K1_TESTUTIL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/util.h b/crypto/secp256k1/libsecp256k1/src/util.h index 4092a86c91..5f29f4076c 100644 --- a/crypto/secp256k1/libsecp256k1/src/util.h +++ b/crypto/secp256k1/libsecp256k1/src/util.h @@ -1,19 +1,88 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_UTIL_H_ -#define _SECP256K1_UTIL_H_ +#ifndef SECP256K1_UTIL_H +#define SECP256K1_UTIL_H -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif +#include "../include/secp256k1.h" +#include "checkmem.h" +#include #include #include #include +#include +#if defined(_MSC_VER) +/* For SecureZeroMemory */ +#include +#endif + +#define STR_(x) #x +#define STR(x) STR_(x) +#define DEBUG_CONFIG_MSG(x) "DEBUG_CONFIG: " x +#define DEBUG_CONFIG_DEF(x) DEBUG_CONFIG_MSG(#x "=" STR(x)) + +/* Debug helper for printing arrays of unsigned char. */ +#define PRINT_BUF(buf, len) do { \ + printf("%s[%lu] = ", #buf, (unsigned long)len); \ + print_buf_plain(buf, len); \ +} while(0) + +static void print_buf_plain(const unsigned char *buf, size_t len) { + size_t i; + printf("{"); + for (i = 0; i < len; i++) { + if (i % 8 == 0) { + printf("\n "); + } else { + printf(" "); + } + printf("0x%02X,", buf[i]); + } + printf("\n}\n"); +} + +# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if SECP256K1_GNUC_PREREQ(2,7) +# define SECP256K1_INLINE __inline__ +# elif (defined(_MSC_VER)) +# define SECP256K1_INLINE __inline +# else +# define SECP256K1_INLINE +# endif +# else +# define SECP256K1_INLINE inline +# endif + +/** Assert statically that expr is true. + * + * This is a statement-like macro and can only be used inside functions. + */ +#define STATIC_ASSERT(expr) do { \ + switch(0) { \ + case 0: \ + /* If expr evaluates to 0, we have two case labels "0", which is illegal. */ \ + case /* ERROR: static assertion failed */ (expr): \ + ; \ + } \ +} while(0) + +/** Assert statically that expr is an integer constant expression, and run stmt. + * + * Useful for example to enforce that magnitude arguments are constant. + */ +#define ASSERT_INT_CONST_AND_DO(expr, stmt) do { \ + switch(42) { \ + /* C allows only integer constant expressions as case labels. */ \ + case /* ERROR: integer argument is not constant */ (expr): \ + break; \ + default: ; \ + } \ + stmt; \ +} while(0) typedef struct { void (*fn)(const char *text, void* data); @@ -24,6 +93,33 @@ static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * cb->fn(text, (void*)cb->data); } +#ifndef USE_EXTERNAL_DEFAULT_CALLBACKS +static void secp256k1_default_illegal_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); + abort(); +} +static void secp256k1_default_error_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); + abort(); +} +#else +void secp256k1_default_illegal_callback_fn(const char* str, void* data); +void secp256k1_default_error_callback_fn(const char* str, void* data); +#endif + +static const secp256k1_callback default_illegal_callback = { + secp256k1_default_illegal_callback_fn, + NULL +}; + +static const secp256k1_callback default_error_callback = { + secp256k1_default_error_callback_fn, + NULL +}; + + #ifdef DETERMINISTIC #define TEST_FAILURE(msg) do { \ fprintf(stderr, "%s\n", msg); \ @@ -36,7 +132,7 @@ static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * } while(0) #endif -#ifdef HAVE_BUILTIN_EXPECT +#if SECP256K1_GNUC_PREREQ(3, 0) #define EXPECT(x,c) __builtin_expect((x),(c)) #else #define EXPECT(x,c) (x) @@ -56,16 +152,11 @@ static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * } while(0) #endif -/* Like assert(), but when VERIFY is defined, and side-effect safe. */ -#if defined(COVERAGE) -#define VERIFY_CHECK(check) -#define VERIFY_SETUP(stmt) -#elif defined(VERIFY) +/* Like assert(), but when VERIFY is defined. */ +#if defined(VERIFY) #define VERIFY_CHECK CHECK -#define VERIFY_SETUP(stmt) do { stmt; } while(0) #else -#define VERIFY_CHECK(cond) do { (void)(cond); } while(0) -#define VERIFY_SETUP(stmt) +#define VERIFY_CHECK(cond) #endif static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { @@ -76,6 +167,20 @@ static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_ return ret; } +#if defined(__BIGGEST_ALIGNMENT__) +#define ALIGNMENT __BIGGEST_ALIGNMENT__ +#else +/* Using 16 bytes alignment because common architectures never have alignment + * requirements above 8 for any of the types we care about. In addition we + * leave some room because currently we don't care about a few bytes. */ +#define ALIGNMENT 16 +#endif + +/* ceil(x/y) for integers x > 0 and y > 0. Here, / denotes rational division. */ +#define CEIL_DIV(x, y) (1 + ((x) - 1) / (y)) + +#define ROUND_TO_ALIGN(size) (CEIL_DIV(size, ALIGNMENT) * ALIGNMENT) + /* Macro for restrict, when available and not in a VERIFY build. */ #if defined(SECP256K1_BUILD) && defined(VERIFY) # define SECP256K1_RESTRICT @@ -93,21 +198,254 @@ static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_ # endif #endif -#if defined(_WIN32) -# define I64FORMAT "I64d" -# define I64uFORMAT "I64u" +#if defined(__GNUC__) +# define SECP256K1_GNUC_EXT __extension__ #else -# define I64FORMAT "lld" -# define I64uFORMAT "llu" +# define SECP256K1_GNUC_EXT #endif -#if defined(HAVE___INT128) -# if defined(__GNUC__) -# define SECP256K1_GNUC_EXT __extension__ -# else -# define SECP256K1_GNUC_EXT -# endif -SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; +/* Zero memory if flag == 1. Flag must be 0 or 1. Constant time. */ +static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag) { + unsigned char *p = (unsigned char *)s; + /* Access flag with a volatile-qualified lvalue. + This prevents clang from figuring out (after inlining) that flag can + take only be 0 or 1, which leads to variable time code. */ + volatile int vflag = flag; + unsigned char mask = -(unsigned char) vflag; + while (len) { + *p &= ~mask; + p++; + len--; + } +} + +/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */ +static SECP256K1_INLINE void secp256k1_memclear(void *ptr, size_t len) { +#if defined(_MSC_VER) + /* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */ + SecureZeroMemory(ptr, len); +#elif defined(__GNUC__) + /* We use a memory barrier that scares the compiler away from optimizing out the memset. + * + * Quoting Adam Langley in commit ad1907fe73334d6c696c8539646c21b11178f20f + * in BoringSSL (ISC License): + * As best as we can tell, this is sufficient to break any optimisations that + * might try to eliminate "superfluous" memsets. + * This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it + * is pretty efficient, because the compiler can still implement the memset() efficiently, + * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by + * Yang et al. (USENIX Security 2017) for more background. + */ + memset(ptr, 0, len); + __asm__ __volatile__("" : : "r"(ptr) : "memory"); +#else + void *(*volatile const volatile_memset)(void *, int, size_t) = memset; + volatile_memset(ptr, 0, len); +#endif +#ifdef VERIFY + SECP256K1_CHECKMEM_UNDEFINE(ptr, len); +#endif +} + +/** Semantics like memcmp. Variable-time. + * + * We use this to avoid possible compiler bugs with memcmp, e.g. + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189 + */ +static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n) { + const unsigned char *p1 = s1, *p2 = s2; + size_t i; + + for (i = 0; i < n; i++) { + int diff = p1[i] - p2[i]; + if (diff != 0) { + return diff; + } + } + return 0; +} + +/* Return 1 if all elements of array s are 0 and otherwise return 0. + * Constant-time. */ +static SECP256K1_INLINE int secp256k1_is_zero_array(const unsigned char *s, size_t len) { + unsigned char acc = 0; + int ret; + size_t i; + + for (i = 0; i < len; i++) { + acc |= s[i]; + } + ret = (acc == 0); + /* acc may contain secret values. Try to explicitly clear it. */ + secp256k1_memclear(&acc, sizeof(acc)); + return ret; +} + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized and non-negative.*/ +static SECP256K1_INLINE void secp256k1_int_cmov(int *r, const int *a, int flag) { + unsigned int mask0, mask1, r_masked, a_masked; + /* Access flag with a volatile-qualified lvalue. + This prevents clang from figuring out (after inlining) that flag can + take only be 0 or 1, which leads to variable time code. */ + volatile int vflag = flag; + + /* Casting a negative int to unsigned and back to int is implementation defined behavior */ + VERIFY_CHECK(*r >= 0 && *a >= 0); + + mask0 = (unsigned int)vflag + ~0u; + mask1 = ~mask0; + r_masked = ((unsigned int)*r & mask0); + a_masked = ((unsigned int)*a & mask1); + + *r = (int)(r_masked | a_masked); +} + +#if defined(USE_FORCE_WIDEMUL_INT128_STRUCT) +/* If USE_FORCE_WIDEMUL_INT128_STRUCT is set, use int128_struct. */ +# define SECP256K1_WIDEMUL_INT128 1 +# define SECP256K1_INT128_STRUCT 1 +#elif defined(USE_FORCE_WIDEMUL_INT128) +/* If USE_FORCE_WIDEMUL_INT128 is set, use int128. */ +# define SECP256K1_WIDEMUL_INT128 1 +# define SECP256K1_INT128_NATIVE 1 +#elif defined(USE_FORCE_WIDEMUL_INT64) +/* If USE_FORCE_WIDEMUL_INT64 is set, use int64. */ +# define SECP256K1_WIDEMUL_INT64 1 +#elif defined(UINT128_MAX) || defined(__SIZEOF_INT128__) +/* If a native 128-bit integer type exists, use int128. */ +# define SECP256K1_WIDEMUL_INT128 1 +# define SECP256K1_INT128_NATIVE 1 +#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) +/* On 64-bit MSVC targets (x86_64 and arm64), use int128_struct + * (which has special logic to implement using intrinsics on those systems). */ +# define SECP256K1_WIDEMUL_INT128 1 +# define SECP256K1_INT128_STRUCT 1 +#elif SIZE_MAX > 0xffffffff +/* Systems with 64-bit pointers (and thus registers) very likely benefit from + * using 64-bit based arithmetic (even if we need to fall back to 32x32->64 based + * multiplication logic). */ +# define SECP256K1_WIDEMUL_INT128 1 +# define SECP256K1_INT128_STRUCT 1 +#else +/* Lastly, fall back to int64 based arithmetic. */ +# define SECP256K1_WIDEMUL_INT64 1 #endif +#ifndef __has_builtin +#define __has_builtin(x) 0 #endif + +/* Determine the number of trailing zero bits in a (non-zero) 32-bit x. + * This function is only intended to be used as fallback for + * secp256k1_ctz32_var, but permits it to be tested separately. */ +static SECP256K1_INLINE int secp256k1_ctz32_var_debruijn(uint32_t x) { + static const uint8_t debruijn[32] = { + 0x00, 0x01, 0x02, 0x18, 0x03, 0x13, 0x06, 0x19, 0x16, 0x04, 0x14, 0x0A, + 0x10, 0x07, 0x0C, 0x1A, 0x1F, 0x17, 0x12, 0x05, 0x15, 0x09, 0x0F, 0x0B, + 0x1E, 0x11, 0x08, 0x0E, 0x1D, 0x0D, 0x1C, 0x1B + }; + return debruijn[(uint32_t)((x & -x) * 0x04D7651FU) >> 27]; +} + +/* Determine the number of trailing zero bits in a (non-zero) 64-bit x. + * This function is only intended to be used as fallback for + * secp256k1_ctz64_var, but permits it to be tested separately. */ +static SECP256K1_INLINE int secp256k1_ctz64_var_debruijn(uint64_t x) { + static const uint8_t debruijn[64] = { + 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, + 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, + 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, + 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 + }; + return debruijn[(uint64_t)((x & -x) * 0x022FDD63CC95386DU) >> 58]; +} + +/* Determine the number of trailing zero bits in a (non-zero) 32-bit x. */ +static SECP256K1_INLINE int secp256k1_ctz32_var(uint32_t x) { + VERIFY_CHECK(x != 0); +#if (__has_builtin(__builtin_ctz) || SECP256K1_GNUC_PREREQ(3,4)) + /* If the unsigned type is sufficient to represent the largest uint32_t, consider __builtin_ctz. */ + if (((unsigned)UINT32_MAX) == UINT32_MAX) { + return __builtin_ctz(x); + } +#endif +#if (__has_builtin(__builtin_ctzl) || SECP256K1_GNUC_PREREQ(3,4)) + /* Otherwise consider __builtin_ctzl (the unsigned long type is always at least 32 bits). */ + return __builtin_ctzl(x); +#else + /* If no suitable CTZ builtin is available, use a (variable time) software emulation. */ + return secp256k1_ctz32_var_debruijn(x); +#endif +} + +/* Determine the number of trailing zero bits in a (non-zero) 64-bit x. */ +static SECP256K1_INLINE int secp256k1_ctz64_var(uint64_t x) { + VERIFY_CHECK(x != 0); +#if (__has_builtin(__builtin_ctzl) || SECP256K1_GNUC_PREREQ(3,4)) + /* If the unsigned long type is sufficient to represent the largest uint64_t, consider __builtin_ctzl. */ + if (((unsigned long)UINT64_MAX) == UINT64_MAX) { + return __builtin_ctzl(x); + } +#endif +#if (__has_builtin(__builtin_ctzll) || SECP256K1_GNUC_PREREQ(3,4)) + /* Otherwise consider __builtin_ctzll (the unsigned long long type is always at least 64 bits). */ + return __builtin_ctzll(x); +#else + /* If no suitable CTZ builtin is available, use a (variable time) software emulation. */ + return secp256k1_ctz64_var_debruijn(x); +#endif +} + +/* Read a uint32_t in big endian */ +SECP256K1_INLINE static uint32_t secp256k1_read_be32(const unsigned char* p) { + return (uint32_t)p[0] << 24 | + (uint32_t)p[1] << 16 | + (uint32_t)p[2] << 8 | + (uint32_t)p[3]; +} + +/* Write a uint32_t in big endian */ +SECP256K1_INLINE static void secp256k1_write_be32(unsigned char* p, uint32_t x) { + p[3] = x; + p[2] = x >> 8; + p[1] = x >> 16; + p[0] = x >> 24; +} + +/* Read a uint64_t in big endian */ +SECP256K1_INLINE static uint64_t secp256k1_read_be64(const unsigned char* p) { + return (uint64_t)p[0] << 56 | + (uint64_t)p[1] << 48 | + (uint64_t)p[2] << 40 | + (uint64_t)p[3] << 32 | + (uint64_t)p[4] << 24 | + (uint64_t)p[5] << 16 | + (uint64_t)p[6] << 8 | + (uint64_t)p[7]; +} + +/* Write a uint64_t in big endian */ +SECP256K1_INLINE static void secp256k1_write_be64(unsigned char* p, uint64_t x) { + p[7] = x; + p[6] = x >> 8; + p[5] = x >> 16; + p[4] = x >> 24; + p[3] = x >> 32; + p[2] = x >> 40; + p[1] = x >> 48; + p[0] = x >> 56; +} + +/* Rotate a uint32_t to the right. */ +SECP256K1_INLINE static uint32_t secp256k1_rotr32(const uint32_t x, const unsigned int by) { +#if defined(_MSC_VER) + return _rotr(x, by); /* needs */ +#else + /* Reduce rotation amount to avoid UB when shifting. */ + const unsigned int mask = CHAR_BIT * sizeof(x) - 1; + /* Turned into a rot instruction by GCC and clang. */ + return (x >> (by & mask)) | (x << ((-by) & mask)); +#endif +} + +#endif /* SECP256K1_UTIL_H */ diff --git a/crypto/secp256k1/libsecp256k1/src/wycheproof/WYCHEPROOF_COPYING b/crypto/secp256k1/libsecp256k1/src/wycheproof/WYCHEPROOF_COPYING new file mode 100644 index 0000000000..cddf9d9182 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/wycheproof/WYCHEPROOF_COPYING @@ -0,0 +1,212 @@ +* The file `ecdsa_secp256k1_sha256_bitcoin_test.json` in this directory + comes from Google's project Wycheproof with git commit + `b063b4aedae951c69df014cd25fa6d69ae9e8cb9`, see + https://github.com/google/wycheproof/blob/b063b4aedae951c69df014cd25fa6d69ae9e8cb9/testvectors_v1/ecdsa_secp256k1_sha256_bitcoin_test.json + +* The file `ecdsa_secp256k1_sha256_bitcoin_test.h` is generated from + `ecdsa_secp256k1_sha256_bitcoin_test.json` using the script + `tests_wycheproof_generate.py`. + +------------------------------------------------------------------------------- + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/crypto/secp256k1/libsecp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h b/crypto/secp256k1/libsecp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h new file mode 100644 index 0000000000..736737fd61 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h @@ -0,0 +1,1564 @@ +/* Note: this file was autogenerated using tests_wycheproof_generate.py. Do not edit. */ +#define SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS (463) + +typedef struct { + size_t pk_offset; + size_t msg_offset; + size_t msg_len; + size_t sig_offset; + size_t sig_len; + int expected_verify; +} wycheproof_ecdsa_testvector; + +static const unsigned char wycheproof_ecdsa_messages[] = { 0x31,0x32,0x33,0x34,0x30,0x30, + 0x32,0x35,0x35,0x38,0x35, + 0x34,0x32,0x36,0x34,0x37,0x39,0x37,0x32,0x34, + 0x37,0x31,0x33,0x38,0x36,0x38,0x34,0x38,0x39,0x31, + 0x31,0x30,0x33,0x35,0x39,0x33,0x33,0x31,0x36,0x36,0x38, + 0x33,0x39,0x34,0x39,0x34,0x30,0x31,0x32,0x31,0x35, + 0x31,0x33,0x34,0x34,0x32,0x39,0x33,0x30,0x37,0x39, + 0x33,0x37,0x30,0x36,0x32,0x31,0x31,0x37,0x31,0x32, + 0x33,0x34,0x33,0x36,0x38,0x38,0x37,0x31,0x32, + 0x31,0x33,0x35,0x31,0x35,0x33,0x30,0x33,0x37,0x30, + 0x36,0x35,0x35,0x33,0x32,0x30,0x33,0x31,0x32,0x36, + 0x31,0x35,0x36,0x34,0x33,0x34,0x36,0x36,0x30,0x33, + 0x34,0x34,0x32,0x39,0x35,0x33,0x39,0x31,0x31,0x37, + 0x31,0x30,0x39,0x35,0x33,0x32,0x36,0x31,0x33,0x35,0x31, + 0x35,0x39,0x38,0x37,0x33,0x35,0x30,0x30,0x34,0x31, + 0x33,0x34,0x36,0x33,0x30,0x30,0x36,0x38,0x37,0x38, + 0x39,0x38,0x31,0x37,0x33,0x32,0x30,0x32,0x38,0x37, + 0x33,0x32,0x32,0x32,0x30,0x34,0x31,0x30,0x34,0x36, + 0x36,0x36,0x36,0x36,0x33,0x30,0x37,0x31,0x30,0x34, + 0x31,0x30,0x33,0x35,0x39,0x35,0x31,0x38,0x39,0x38, + 0x31,0x38,0x34,0x36,0x35,0x39,0x37,0x31,0x39,0x35, + 0x33,0x31,0x33,0x36,0x30,0x34,0x36,0x31,0x38,0x39, + 0x32,0x36,0x36,0x33,0x37,0x38,0x34,0x32,0x35,0x34, + 0x31,0x36,0x35,0x32,0x31,0x30,0x30,0x35,0x32,0x34, + 0x35,0x37,0x34,0x38,0x30,0x38,0x31,0x36,0x39,0x36, + 0x36,0x33,0x34,0x33,0x39,0x31,0x33,0x34,0x36,0x38, + 0x31,0x35,0x34,0x31,0x31,0x30,0x33,0x35,0x39,0x38, + 0x31,0x30,0x34,0x37,0x38,0x35,0x38,0x30,0x31,0x32,0x38, + 0x31,0x30,0x35,0x33,0x36,0x32,0x38,0x35,0x35,0x36,0x38, + 0x39,0x35,0x33,0x39,0x30,0x34,0x31,0x30,0x35, + 0x39,0x37,0x38,0x38,0x34,0x38,0x30,0x33,0x39, + 0x33,0x36,0x31,0x30,0x36,0x37,0x32,0x34,0x34,0x32, + 0x31,0x30,0x35,0x34,0x32,0x34,0x30,0x37,0x30,0x35, + 0x35,0x31,0x37,0x34,0x34,0x34,0x38,0x31,0x39,0x37, + 0x31,0x39,0x36,0x37,0x35,0x36,0x31,0x32,0x35,0x31, + 0x33,0x34,0x34,0x37,0x32,0x35,0x33,0x33,0x34,0x33, + 0x33,0x36,0x38,0x32,0x36,0x34,0x33,0x31,0x38, + 0x33,0x32,0x36,0x31,0x31,0x39,0x38,0x36,0x30,0x38, + 0x39,0x36,0x37,0x38,0x37,0x38,0x31,0x30,0x39,0x34, + 0x34,0x39,0x35,0x38,0x38,0x32,0x33,0x38,0x32,0x33, + 0x38,0x32,0x34,0x36,0x33,0x37,0x38,0x33,0x37, + 0x31,0x31,0x30,0x32,0x30,0x38,0x33,0x33,0x37,0x37,0x36, + 0x31,0x33,0x33,0x38,0x37,0x31,0x36,0x34,0x38, + 0x33,0x32,0x32,0x31,0x34,0x34,0x31,0x36,0x32, + 0x31,0x30,0x36,0x38,0x36,0x36,0x35,0x35,0x35,0x34,0x36, + 0x36,0x32,0x31,0x35,0x35,0x32,0x34,0x36, + 0x37,0x30,0x33,0x30,0x38,0x31,0x38,0x37,0x37,0x34, + 0x35,0x39,0x32,0x34,0x35,0x32,0x33,0x37,0x34,0x34, + 0x31,0x34,0x39,0x35,0x35,0x38,0x36,0x36,0x32,0x31, + 0x34,0x30,0x30,0x35,0x33,0x31,0x34,0x34,0x30,0x36, + 0x33,0x30,0x39,0x36,0x34,0x35,0x37,0x35,0x31,0x32, + 0x32,0x37,0x38,0x34,0x30,0x32,0x35,0x36,0x32,0x30, + 0x32,0x36,0x31,0x38,0x37,0x38,0x37,0x34,0x31,0x38, + 0x31,0x36,0x34,0x32,0x36,0x32,0x35,0x32,0x36,0x32, + 0x36,0x38,0x32,0x34,0x31,0x38,0x39,0x34,0x33,0x36, + 0x34,0x38,0x34,0x32,0x34,0x35,0x34,0x32,0x35, + 0x4d,0x73,0x67, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x4d,0x65,0x73,0x73,0x61,0x67,0x65}; + +static const unsigned char wycheproof_ecdsa_public_keys[] = { 0x04,0xb8,0x38,0xff,0x44,0xe5,0xbc,0x17,0x7b,0xf2,0x11,0x89,0xd0,0x76,0x60,0x82,0xfc,0x9d,0x84,0x32,0x26,0x88,0x7f,0xc9,0x76,0x03,0x71,0x10,0x0b,0x7e,0xe2,0x0a,0x6f,0xf0,0xc9,0xd7,0x5b,0xfb,0xa7,0xb3,0x1a,0x6b,0xca,0x19,0x74,0x49,0x6e,0xeb,0x56,0xde,0x35,0x70,0x71,0x95,0x5d,0x83,0xc4,0xb1,0xba,0xda,0xa0,0xb2,0x18,0x32,0xe9, + 0x04,0x07,0x31,0x0f,0x90,0xa9,0xea,0xe1,0x49,0xa0,0x84,0x02,0xf5,0x41,0x94,0xa0,0xf7,0xb4,0xac,0x42,0x7b,0xf8,0xd9,0xbd,0x6c,0x76,0x81,0x07,0x1d,0xc4,0x7d,0xc3,0x62,0x26,0xa6,0xd3,0x7a,0xc4,0x6d,0x61,0xfd,0x60,0x0c,0x0b,0xf1,0xbf,0xf8,0x76,0x89,0xed,0x11,0x7d,0xda,0x6b,0x0e,0x59,0x31,0x8a,0xe0,0x10,0xa1,0x97,0xa2,0x6c,0xa0, + 0x04,0xbc,0x97,0xe7,0x58,0x5e,0xec,0xad,0x48,0xe1,0x66,0x83,0xbc,0x40,0x91,0x70,0x8e,0x1a,0x93,0x0c,0x68,0x3f,0xc4,0x70,0x01,0xd4,0xb3,0x83,0x59,0x4f,0x2c,0x4e,0x22,0x70,0x59,0x89,0xcf,0x69,0xda,0xea,0xdd,0x4e,0x4e,0x4b,0x81,0x51,0xed,0x88,0x8d,0xfe,0xc2,0x0f,0xb0,0x17,0x28,0xd8,0x9d,0x56,0xb3,0xf3,0x8f,0x2a,0xe9,0xc8,0xc5, + 0x04,0x44,0xad,0x33,0x9a,0xfb,0xc2,0x1e,0x9a,0xbf,0x7b,0x60,0x2a,0x5c,0xa5,0x35,0xea,0x37,0x81,0x35,0xb6,0xd1,0x0d,0x81,0x31,0x0b,0xdd,0x82,0x93,0xd1,0xdf,0x32,0x52,0xb6,0x3f,0xf7,0xd0,0x77,0x47,0x70,0xf8,0xfe,0x1d,0x17,0x22,0xfa,0x83,0xac,0xd0,0x2f,0x43,0x4e,0x4f,0xc1,0x10,0xa0,0xcc,0x8f,0x6d,0xdd,0xd3,0x7d,0x56,0xc4,0x63, + 0x04,0x12,0x60,0xc2,0x12,0x2c,0x9e,0x24,0x4e,0x1a,0xf5,0x15,0x1b,0xed,0xe0,0xc3,0xae,0x23,0xb5,0x4d,0x7c,0x59,0x68,0x81,0xd3,0xee,0xba,0xd2,0x1f,0x37,0xdd,0x87,0x8c,0x5c,0x9a,0x0c,0x1a,0x9a,0xde,0x76,0x73,0x7a,0x88,0x11,0xbd,0x6a,0x7f,0x92,0x87,0xc9,0x78,0xee,0x39,0x6a,0xa8,0x9c,0x11,0xe4,0x72,0x29,0xd2,0xcc,0xb5,0x52,0xf0, + 0x04,0x18,0x77,0x04,0x5b,0xe2,0x5d,0x34,0xa1,0xd0,0x60,0x0f,0x9d,0x5c,0x00,0xd0,0x64,0x5a,0x2a,0x54,0x37,0x9b,0x6c,0xee,0xfa,0xd2,0xe6,0xbf,0x5c,0x2a,0x33,0x52,0xce,0x82,0x1a,0x53,0x2c,0xc1,0x75,0x1e,0xe1,0xd3,0x6d,0x41,0xc3,0xd6,0xab,0x4e,0x9b,0x14,0x3e,0x44,0xec,0x46,0xd7,0x34,0x78,0xea,0x6a,0x79,0xa5,0xc0,0xe5,0x41,0x59, + 0x04,0x45,0x54,0x39,0xfc,0xc3,0xd2,0xde,0xec,0xed,0xde,0xae,0xce,0x60,0xe7,0xbd,0x17,0x30,0x4f,0x36,0xeb,0xb6,0x02,0xad,0xf5,0xa2,0x2e,0x0b,0x8f,0x1d,0xb4,0x6a,0x50,0xae,0xc3,0x8f,0xb2,0xba,0xf2,0x21,0xe9,0xa8,0xd1,0x88,0x7c,0x7b,0xf6,0x22,0x2d,0xd1,0x83,0x46,0x34,0xe7,0x72,0x63,0x31,0x5a,0xf6,0xd2,0x36,0x09,0xd0,0x4f,0x77, + 0x04,0x2e,0x1f,0x46,0x6b,0x02,0x4c,0x0c,0x3a,0xce,0x24,0x37,0xde,0x09,0x12,0x7f,0xed,0x04,0xb7,0x06,0xf9,0x4b,0x19,0xa2,0x1b,0xb1,0xc2,0xac,0xf3,0x5c,0xec,0xe7,0x18,0x04,0x49,0xae,0x35,0x23,0xd7,0x25,0x34,0xe9,0x64,0x97,0x2c,0xfd,0x3b,0x38,0xaf,0x0b,0xdd,0xd9,0x61,0x9e,0x5a,0xf2,0x23,0xe4,0xd1,0xa4,0x0f,0x34,0xcf,0x9f,0x1d, + 0x04,0x8e,0x7a,0xbd,0xbb,0xd1,0x8d,0xe7,0x45,0x23,0x74,0xc1,0x87,0x9a,0x1c,0x3b,0x01,0xd1,0x32,0x61,0xe7,0xd4,0x57,0x1c,0x3b,0x47,0xa1,0xc7,0x6c,0x55,0xa2,0x33,0x73,0x26,0xed,0x89,0x7c,0xd5,0x17,0xa4,0xf5,0x34,0x9d,0xb8,0x09,0x78,0x0f,0x6d,0x2f,0x2b,0x9f,0x62,0x99,0xd8,0xb5,0xa8,0x90,0x77,0xf1,0x11,0x9a,0x71,0x8f,0xd7,0xb3, + 0x04,0x7b,0x33,0x3d,0x43,0x40,0xd3,0xd7,0x18,0xdd,0x3e,0x6a,0xff,0x7d,0xe7,0xbb,0xf8,0xb7,0x2b,0xfd,0x61,0x6c,0x84,0x20,0x05,0x60,0x52,0x84,0x23,0x76,0xb9,0xaf,0x19,0x42,0x11,0x7c,0x5a,0xfe,0xac,0x75,0x5d,0x6f,0x37,0x6f,0xc6,0x32,0x9a,0x7d,0x76,0x05,0x1b,0x87,0x12,0x3a,0x4a,0x5d,0x0b,0xc4,0xa5,0x39,0x38,0x0f,0x03,0xde,0x7b, + 0x04,0xd3,0x0c,0xa4,0xa0,0xdd,0xb6,0x61,0x6c,0x85,0x1d,0x30,0xce,0xd6,0x82,0xc4,0x0f,0x83,0xc6,0x27,0x58,0xa1,0xf2,0x75,0x99,0x88,0xd6,0x76,0x3a,0x88,0xf1,0xc0,0xe5,0x03,0xa8,0x0d,0x54,0x15,0x65,0x0d,0x41,0x23,0x97,0x84,0xe8,0xe2,0xfb,0x12,0x35,0xe9,0xfe,0x99,0x1d,0x11,0x2e,0xbb,0x81,0x18,0x6c,0xbf,0x0d,0xa2,0xde,0x3a,0xff, + 0x04,0x48,0x96,0x9b,0x39,0x99,0x12,0x97,0xb3,0x32,0xa6,0x52,0xd3,0xee,0x6e,0x01,0xe9,0x09,0xb3,0x99,0x04,0xe7,0x1f,0xa2,0x35,0x4a,0x78,0x30,0xc7,0x75,0x0b,0xaf,0x24,0xb4,0x01,0x2d,0x1b,0x83,0x0d,0x19,0x9c,0xcb,0x1f,0xc9,0x72,0xb3,0x2b,0xfd,0xed,0x55,0xf0,0x9c,0xd6,0x2d,0x25,0x7e,0x5e,0x84,0x4e,0x27,0xe5,0x7a,0x15,0x94,0xec, + 0x04,0x02,0xef,0x4d,0x6d,0x6c,0xfd,0x5a,0x94,0xf1,0xd7,0x78,0x42,0x26,0xe3,0xe2,0xa6,0xc0,0xa4,0x36,0xc5,0x58,0x39,0x61,0x9f,0x38,0xfb,0x44,0x72,0xb5,0xf9,0xee,0x77,0x7e,0xb4,0xac,0xd4,0xee,0xbd,0xa5,0xcd,0x72,0x87,0x5f,0xfd,0x2a,0x2f,0x26,0x22,0x9c,0x2d,0xc6,0xb4,0x65,0x00,0x91,0x9a,0x43,0x2c,0x86,0x73,0x9f,0x3a,0xe8,0x66, + 0x04,0x46,0x4f,0x4f,0xf7,0x15,0x72,0x9c,0xae,0x50,0x72,0xca,0x3b,0xd8,0x01,0xd3,0x19,0x5b,0x67,0xae,0xc6,0x5e,0x9b,0x01,0xaa,0xd2,0x0a,0x29,0x43,0xdc,0xbc,0xb5,0x84,0xb1,0xaf,0xd2,0x9d,0x31,0xa3,0x9a,0x11,0xd5,0x70,0xaa,0x15,0x97,0x43,0x9b,0x3b,0x2d,0x19,0x71,0xbf,0x2f,0x1a,0xbf,0x15,0x43,0x2d,0x02,0x07,0xb1,0x0d,0x1d,0x08, + 0x04,0x15,0x7f,0x8f,0xdd,0xf3,0x73,0xeb,0x5f,0x49,0xcf,0xcf,0x10,0xd8,0xb8,0x53,0xcf,0x91,0xcb,0xcd,0x7d,0x66,0x5c,0x35,0x22,0xba,0x7d,0xd7,0x38,0xdd,0xb7,0x9a,0x4c,0xde,0xad,0xf1,0xa5,0xc4,0x48,0xea,0x3c,0x9f,0x41,0x91,0xa8,0x99,0x9a,0xbf,0xcc,0x75,0x7a,0xc6,0xd6,0x45,0x67,0xef,0x07,0x2c,0x47,0xfe,0xc6,0x13,0x44,0x3b,0x8f, + 0x04,0x09,0x34,0xa5,0x37,0x46,0x6c,0x07,0x43,0x0e,0x2c,0x48,0xfe,0xb9,0x90,0xbb,0x19,0xfb,0x78,0xce,0xcc,0x9c,0xee,0x42,0x4e,0xa4,0xd1,0x30,0x29,0x1a,0xa2,0x37,0xf0,0xd4,0xf9,0x2d,0x23,0xb4,0x62,0x80,0x4b,0x5b,0x68,0xc5,0x25,0x58,0xc0,0x1c,0x99,0x96,0xdb,0xf7,0x27,0xfc,0xca,0xbb,0xee,0xdb,0x96,0x21,0xa4,0x00,0x53,0x5a,0xfa, + 0x04,0xd6,0xef,0x20,0xbe,0x66,0xc8,0x93,0xf7,0x41,0xa9,0xbf,0x90,0xd9,0xb7,0x46,0x75,0xd1,0xc2,0xa3,0x12,0x96,0x39,0x7a,0xcb,0x3e,0xf1,0x74,0xfd,0x0b,0x30,0x0c,0x65,0x4a,0x0c,0x95,0x47,0x8c,0xa0,0x03,0x99,0x16,0x2d,0x7f,0x0f,0x2d,0xc8,0x9e,0xfd,0xc2,0xb2,0x8a,0x30,0xfb,0xab,0xe2,0x85,0x85,0x72,0x95,0xa4,0xb0,0xc4,0xe2,0x65, + 0x04,0xb7,0x29,0x1d,0x14,0x04,0xe0,0xc0,0xc0,0x7d,0xab,0x93,0x72,0x18,0x9f,0x4b,0xd5,0x8d,0x2c,0xea,0xa8,0xd1,0x5e,0xde,0x54,0x4d,0x95,0x14,0x54,0x5b,0xa9,0xee,0x06,0x29,0xc9,0xa6,0x3d,0x5e,0x30,0x87,0x69,0xcc,0x30,0xec,0x27,0x6a,0x41,0x0e,0x64,0x64,0xa2,0x7e,0xea,0xfd,0x9e,0x59,0x9d,0xb1,0x0f,0x05,0x3a,0x4f,0xe4,0xa8,0x29, + 0x04,0x6e,0x28,0x30,0x33,0x05,0xd6,0x42,0xcc,0xb9,0x23,0xb7,0x22,0xea,0x86,0xb2,0xa0,0xbc,0x8e,0x37,0x35,0xec,0xb2,0x6e,0x84,0x9b,0x19,0xc9,0xf7,0x6b,0x2f,0xdb,0xb8,0x18,0x6e,0x80,0xd6,0x4d,0x8c,0xab,0x16,0x4f,0x52,0x38,0xf5,0x31,0x84,0x61,0xbf,0x89,0xd4,0xd9,0x6e,0xe6,0x54,0x4c,0x81,0x6c,0x75,0x66,0x94,0x77,0x74,0xe0,0xf6, + 0x04,0x37,0x5b,0xda,0x93,0xf6,0xaf,0x92,0xfb,0x5f,0x8f,0x4b,0x1b,0x5f,0x05,0x34,0xe3,0xba,0xfa,0xb3,0x4c,0xb7,0xad,0x9f,0xb9,0xd0,0xb7,0x22,0xe4,0xa5,0xc3,0x02,0xa9,0xa0,0x0b,0x9f,0x38,0x7a,0x5a,0x39,0x60,0x97,0xaa,0x21,0x62,0xfc,0x5b,0xbc,0xf4,0xa5,0x26,0x33,0x72,0xf6,0x81,0xc9,0x4d,0xa5,0x1e,0x97,0x99,0x12,0x09,0x90,0xfd, + 0x04,0xd7,0x5b,0x68,0x21,0x6b,0xab,0xe0,0x3a,0xe2,0x57,0xe9,0x4b,0x4e,0x3b,0xf1,0xc5,0x2f,0x44,0xe3,0xdf,0x26,0x6d,0x15,0x24,0xff,0x8c,0x5e,0xa6,0x9d,0xa7,0x31,0x97,0xda,0x4b,0xff,0x9e,0xd1,0xc5,0x3f,0x44,0x91,0x7a,0x67,0xd7,0xb9,0x78,0x59,0x8e,0x89,0xdf,0x35,0x9e,0x3d,0x59,0x13,0xea,0xea,0x24,0xf3,0xae,0x25,0x9a,0xbc,0x44, + 0x04,0x78,0xbc,0xda,0x14,0x0a,0xed,0x23,0xd4,0x30,0xcb,0x23,0xc3,0xdc,0x0d,0x01,0xf4,0x23,0xdb,0x13,0x4e,0xe9,0x4a,0x3a,0x8c,0xb4,0x83,0xf2,0xde,0xac,0x2a,0xc6,0x53,0x11,0x81,0x14,0xf6,0xf3,0x30,0x45,0xd4,0xe9,0xed,0x91,0x07,0x08,0x50,0x07,0xbf,0xbd,0xdf,0x8f,0x58,0xfe,0x7a,0x1a,0x24,0x45,0xd6,0x6a,0x99,0x00,0x45,0x47,0x6e, + 0x04,0xbb,0x79,0xf6,0x18,0x57,0xf7,0x43,0xbf,0xa1,0xb6,0xe7,0x11,0x1c,0xe4,0x09,0x43,0x77,0x25,0x69,0x69,0xe4,0xe1,0x51,0x59,0x12,0x3d,0x95,0x48,0xac,0xc3,0xbe,0x6c,0x1f,0x9d,0x9f,0x88,0x60,0xdc,0xff,0xd3,0xeb,0x36,0xdd,0x6c,0x31,0xff,0x2e,0x72,0x26,0xc2,0x00,0x9c,0x4c,0x94,0xd8,0xd7,0xd2,0xb5,0x68,0x6b,0xf7,0xab,0xd6,0x77, + 0x04,0x93,0x59,0x18,0x27,0xd9,0xe6,0x71,0x3b,0x4e,0x9f,0xae,0xa6,0x2c,0x72,0xb2,0x8d,0xfe,0xfa,0x68,0xe0,0xc0,0x51,0x60,0xb5,0xd6,0xaa,0xe8,0x8f,0xd2,0xe3,0x6c,0x36,0x07,0x3f,0x55,0x45,0xad,0x5a,0xf4,0x10,0xaf,0x26,0xaf,0xff,0x68,0x65,0x4c,0xf7,0x2d,0x45,0xe4,0x93,0x48,0x93,0x11,0x20,0x32,0x47,0x34,0x7a,0x89,0x0f,0x45,0x18, + 0x04,0x31,0xed,0x30,0x81,0xae,0xfe,0x00,0x1e,0xb6,0x40,0x20,0x69,0xee,0x2c,0xcc,0x18,0x62,0x93,0x7b,0x85,0x99,0x51,0x44,0xdb,0xa9,0x50,0x39,0x43,0x58,0x7b,0xf0,0xda,0xda,0x01,0xb8,0xcc,0x4d,0xf3,0x4f,0x5a,0xb3,0xb1,0xa3,0x59,0x61,0x52,0x08,0x94,0x6e,0x5e,0xe3,0x5f,0x98,0xee,0x77,0x5b,0x8c,0xce,0xcd,0x86,0xcc,0xc1,0x65,0x0f, + 0x04,0x7d,0xff,0x66,0xfa,0x98,0x50,0x9f,0xf3,0xe2,0xe5,0x10,0x45,0xf4,0x39,0x05,0x23,0xdc,0xcd,0xa4,0x3a,0x3b,0xc2,0x88,0x5e,0x58,0xc2,0x48,0x09,0x09,0x90,0xee,0xa8,0x54,0xc7,0x6c,0x2b,0x9a,0xde,0xb6,0xbb,0x57,0x18,0x23,0xe0,0x7f,0xd7,0xc6,0x5c,0x86,0x39,0xcf,0x9d,0x90,0x52,0x60,0x06,0x4c,0x8e,0x76,0x75,0xce,0x6d,0x98,0xb4, + 0x04,0x42,0x80,0x50,0x9a,0xab,0x64,0xed,0xfc,0x0b,0x4a,0x29,0x67,0xe4,0xcb,0xce,0x84,0x9c,0xb5,0x44,0xe4,0xa7,0x73,0x13,0xc8,0xe6,0xec,0xe5,0x79,0xfb,0xd7,0x42,0x0a,0x2e,0x89,0xfe,0x5c,0xc1,0x92,0x7d,0x55,0x4e,0x6a,0x3b,0xb1,0x40,0x33,0xea,0x7c,0x92,0x2c,0xd7,0x5c,0xba,0x2c,0x74,0x15,0xfd,0xab,0x52,0xf2,0x0b,0x18,0x60,0xf1, + 0x04,0x4f,0x8d,0xf1,0x45,0x19,0x4e,0x3c,0x4f,0xc3,0xee,0xa2,0x6d,0x43,0xce,0x75,0xb4,0x02,0xd6,0xb1,0x74,0x72,0xdd,0xcb,0xb2,0x54,0xb8,0xa7,0x9b,0x0b,0xf3,0xd9,0xcb,0x2a,0xa2,0x0d,0x82,0x84,0x4c,0xb2,0x66,0x34,0x4e,0x71,0xca,0x78,0xf2,0xad,0x27,0xa7,0x5a,0x09,0xe5,0xbc,0x0f,0xa5,0x7e,0x4e,0xfd,0x9d,0x46,0x5a,0x08,0x88,0xdb, + 0x04,0x95,0x98,0xa5,0x7d,0xd6,0x7e,0xc3,0xe1,0x6b,0x58,0x7a,0x33,0x8a,0xa3,0xa1,0x0a,0x3a,0x39,0x13,0xb4,0x1a,0x3a,0xf3,0x2e,0x3e,0xd3,0xff,0x01,0x35,0x8c,0x6b,0x14,0x12,0x28,0x19,0xed,0xf8,0x07,0x4b,0xbc,0x52,0x1f,0x7d,0x4c,0xdc,0xe8,0x2f,0xef,0x7a,0x51,0x67,0x06,0xaf,0xfb,0xa1,0xd9,0x3d,0x9d,0xea,0x9c,0xca,0xe1,0xa2,0x07, + 0x04,0x91,0x71,0xfe,0xc3,0xca,0x20,0x80,0x6b,0xc0,0x84,0xf1,0x2f,0x07,0x60,0x91,0x1b,0x60,0x99,0x0b,0xd8,0x0e,0x5b,0x2a,0x71,0xca,0x03,0xa0,0x48,0xb2,0x0f,0x83,0x7e,0x63,0x4f,0xd1,0x78,0x63,0x76,0x1b,0x29,0x58,0xd2,0xbe,0x4e,0x14,0x9f,0x8d,0x3d,0x7a,0xbb,0xdc,0x18,0xbe,0x03,0xf4,0x51,0xab,0x6c,0x17,0xfa,0x0a,0x1f,0x83,0x30, + 0x04,0x77,0x7c,0x89,0x30,0xb6,0xe1,0xd2,0x71,0x10,0x0f,0xe6,0x8c,0xe9,0x3f,0x16,0x3f,0xa3,0x76,0x12,0xc5,0xff,0xf6,0x7f,0x4a,0x62,0xfc,0x3b,0xaf,0xaf,0x3d,0x17,0xa9,0xed,0x73,0xd8,0x6f,0x60,0xa5,0x1b,0x5e,0xd9,0x13,0x53,0xa3,0xb0,0x54,0xed,0xc0,0xaa,0x92,0xc9,0xeb,0xcb,0xd0,0xb7,0x5d,0x18,0x8f,0xdc,0x88,0x27,0x91,0xd6,0x8d, + 0x04,0xea,0xbc,0x24,0x8f,0x62,0x6e,0x0a,0x63,0xe1,0xeb,0x81,0xc4,0x3d,0x46,0x1a,0x39,0xa1,0xdb,0xa8,0x81,0xeb,0x6e,0xe2,0x15,0x2b,0x07,0xc3,0x2d,0x71,0xbc,0xf4,0x70,0x06,0x03,0xca,0xa8,0xb9,0xd3,0x3d,0xb1,0x3a,0xf4,0x4c,0x6e,0xfb,0xec,0x8a,0x19,0x8e,0xd6,0x12,0x4a,0xc9,0xeb,0x17,0xea,0xaf,0xd2,0x82,0x4a,0x54,0x5e,0xc0,0x00, + 0x04,0x9f,0x7a,0x13,0xad,0xa1,0x58,0xa5,0x5f,0x9d,0xdf,0x1a,0x45,0xf0,0x44,0xf0,0x73,0xd9,0xb8,0x00,0x30,0xef,0xdc,0xfc,0x9f,0x9f,0x58,0x41,0x8f,0xbc,0xea,0xf0,0x01,0xf8,0xad,0xa0,0x17,0x50,0x90,0xf8,0x0d,0x47,0x22,0x7d,0x67,0x13,0xb6,0x74,0x0f,0x9a,0x00,0x91,0xd8,0x8a,0x83,0x7d,0x0a,0x1c,0xd7,0x7b,0x58,0xa8,0xf2,0x8d,0x73, + 0x04,0x11,0xc4,0xf3,0xe4,0x61,0xcd,0x01,0x9b,0x5c,0x06,0xea,0x0c,0xea,0x4c,0x40,0x90,0xc3,0xcc,0x3e,0x3c,0x5d,0x9f,0x3c,0x6d,0x65,0xb4,0x36,0x82,0x6d,0xa9,0xb4,0xdb,0xbb,0xeb,0x7a,0x77,0xe4,0xcb,0xfd,0xa2,0x07,0x09,0x7c,0x43,0x42,0x37,0x05,0xf7,0x2c,0x80,0x47,0x6d,0xa3,0xda,0xc4,0x0a,0x48,0x3b,0x0a,0xb0,0xf2,0xea,0xd1,0xcb, + 0x04,0xe2,0xe1,0x86,0x82,0xd5,0x31,0x23,0xaa,0x01,0xa6,0xc5,0xd0,0x0b,0x0c,0x62,0x3d,0x67,0x1b,0x46,0x2e,0xa8,0x0b,0xdd,0xd6,0x52,0x27,0xfd,0x51,0x05,0x98,0x8a,0xa4,0x16,0x19,0x07,0xb3,0xfd,0x25,0x04,0x4a,0x94,0x9e,0xa4,0x1c,0x8e,0x2e,0xa8,0x45,0x9d,0xc6,0xf1,0x65,0x48,0x56,0xb8,0xb6,0x1b,0x31,0x54,0x3b,0xb1,0xb4,0x5b,0xdb, + 0x04,0x90,0xf8,0xd4,0xca,0x73,0xde,0x08,0xa6,0x56,0x4a,0xaf,0x00,0x52,0x47,0xb6,0xf0,0xff,0xe9,0x78,0x50,0x4d,0xce,0x52,0x60,0x5f,0x46,0xb7,0xc3,0xe5,0x61,0x97,0xda,0xfa,0xdb,0xe5,0x28,0xeb,0x70,0xd9,0xee,0x7e,0xa0,0xe7,0x07,0x02,0xdb,0x54,0xf7,0x21,0x51,0x4c,0x7b,0x86,0x04,0xac,0x2c,0xb2,0x14,0xf1,0xde,0xcb,0x7e,0x38,0x3d, + 0x04,0x82,0x4c,0x19,0x5c,0x73,0xcf,0xfd,0xf0,0x38,0xd1,0x01,0xbc,0xe1,0x68,0x7b,0x5c,0x3b,0x61,0x46,0xf3,0x95,0xc8,0x85,0x97,0x6f,0x77,0x53,0xb2,0x37,0x6b,0x94,0x8e,0x3c,0xde,0xfa,0x6f,0xc3,0x47,0xd1,0x3e,0x4d,0xcb,0xc6,0x3a,0x0b,0x03,0xa1,0x65,0x18,0x0c,0xd2,0xbe,0x14,0x31,0xa0,0xcf,0x74,0xce,0x1e,0xa2,0x50,0x82,0xd2,0xbc, + 0x04,0x27,0x88,0xa5,0x2f,0x07,0x8e,0xb3,0xf2,0x02,0xc4,0xfa,0x73,0xe0,0xd3,0x38,0x6f,0xaf,0x3d,0xf6,0xbe,0x85,0x60,0x03,0x63,0x6f,0x59,0x99,0x22,0xd4,0xf5,0x26,0x8f,0x30,0xb4,0xf2,0x07,0xc9,0x19,0xbb,0xdf,0x5e,0x67,0xa8,0xbe,0x42,0x65,0xa8,0x17,0x47,0x54,0xb3,0xab,0xa8,0xf1,0x6e,0x57,0x5b,0x77,0xff,0x4d,0x5a,0x7e,0xb6,0x4f, + 0x04,0xd5,0x33,0xb7,0x89,0xa4,0xaf,0x89,0x0f,0xa7,0xa8,0x2a,0x1f,0xae,0x58,0xc4,0x04,0xf9,0xa6,0x2a,0x50,0xb4,0x9a,0xda,0xfa,0xb3,0x49,0xc5,0x13,0xb4,0x15,0x08,0x74,0x01,0xb4,0x17,0x1b,0x80,0x3e,0x76,0xb3,0x4a,0x98,0x61,0xe1,0x0f,0x7b,0xc2,0x89,0xa0,0x66,0xfd,0x01,0xbd,0x29,0xf8,0x4c,0x98,0x7a,0x10,0xa5,0xfb,0x18,0xc2,0xd4, + 0x04,0x3a,0x31,0x50,0x79,0x8c,0x8a,0xf6,0x9d,0x1e,0x6e,0x98,0x1f,0x3a,0x45,0x40,0x2b,0xa1,0xd7,0x32,0xf4,0xbe,0x83,0x30,0xc5,0x16,0x4f,0x49,0xe1,0x0e,0xc5,0x55,0xb4,0x22,0x1b,0xd8,0x42,0xbc,0x5e,0x4d,0x97,0xef,0xf3,0x71,0x65,0xf6,0x0e,0x39,0x98,0xa4,0x24,0xd7,0x2a,0x45,0x0c,0xf9,0x5e,0xa4,0x77,0xc7,0x82,0x87,0xd0,0x34,0x3a, + 0x04,0x3b,0x37,0xdf,0x5f,0xb3,0x47,0xc6,0x9a,0x0f,0x17,0xd8,0x5c,0x0c,0x7c,0xa8,0x37,0x36,0x88,0x3a,0x82,0x5e,0x13,0x14,0x3d,0x0f,0xcf,0xc8,0x10,0x1e,0x85,0x1e,0x80,0x0d,0xe3,0xc0,0x90,0xb6,0xca,0x21,0xba,0x54,0x35,0x17,0x33,0x0c,0x04,0xb1,0x2f,0x94,0x8c,0x6b,0xad,0xf1,0x4a,0x63,0xab,0xff,0xdf,0x4e,0xf8,0xc7,0x53,0x70,0x26, + 0x04,0xfe,0xb5,0x16,0x3b,0x0e,0xce,0x30,0xff,0x3e,0x03,0xc7,0xd5,0x5c,0x43,0x80,0xfa,0x2f,0xa8,0x1e,0xe2,0xc0,0x35,0x49,0x42,0xff,0x6f,0x08,0xc9,0x9d,0x0c,0xd8,0x2c,0xe8,0x7d,0xe0,0x5e,0xe1,0xbd,0xa0,0x89,0xd3,0xe4,0xe2,0x48,0xfa,0x0f,0x72,0x11,0x02,0xac,0xff,0xfd,0xf5,0x0e,0x65,0x4b,0xe2,0x81,0x43,0x39,0x99,0xdf,0x89,0x7e, + 0x04,0x23,0x8c,0xed,0x00,0x1c,0xf2,0x2b,0x88,0x53,0xe0,0x2e,0xdc,0x89,0xcb,0xec,0xa5,0x05,0x0b,0xa7,0xe0,0x42,0xa7,0xa7,0x7f,0x93,0x82,0xcd,0x41,0x49,0x22,0x89,0x76,0x40,0x68,0x3d,0x30,0x94,0x64,0x38,0x40,0xf2,0x95,0x89,0x0a,0xa4,0xc1,0x8a,0xa3,0x9b,0x41,0xd7,0x7d,0xd0,0xfb,0x3b,0xb2,0x70,0x0e,0x4f,0x9e,0xc2,0x84,0xff,0xc2, + 0x04,0x96,0x1c,0xf6,0x48,0x17,0xc0,0x6c,0x0e,0x51,0xb3,0xc2,0x73,0x6c,0x92,0x2f,0xde,0x18,0xbd,0x8c,0x49,0x06,0xfc,0xd7,0xf5,0xef,0x66,0xc4,0x67,0x85,0x08,0xf3,0x5e,0xd2,0xc5,0xd1,0x81,0x68,0xcf,0xbe,0x70,0xf2,0xf1,0x23,0xbd,0x74,0x19,0x23,0x2b,0xb9,0x2d,0xd6,0x91,0x13,0xe2,0x94,0x10,0x61,0x88,0x94,0x81,0xc5,0xa0,0x27,0xbf, + 0x04,0x13,0x68,0x1e,0xae,0x16,0x8c,0xd4,0xea,0x7c,0xf2,0xe2,0xa4,0x5d,0x05,0x27,0x42,0xd1,0x0a,0x9f,0x64,0xe7,0x96,0x86,0x7d,0xbd,0xcb,0x82,0x9f,0xe0,0xb1,0x02,0x88,0x16,0x52,0x87,0x60,0xd1,0x77,0x37,0x6c,0x09,0xdf,0x79,0xde,0x39,0x55,0x7c,0x32,0x9c,0xc1,0x75,0x35,0x17,0xac,0xff,0xe8,0xfa,0x2e,0xc2,0x98,0x02,0x6b,0x83,0x84, + 0x04,0x5a,0xa7,0xab,0xfd,0xb6,0xb4,0x08,0x6d,0x54,0x33,0x25,0xe5,0xd7,0x9c,0x6e,0x95,0xce,0x42,0xf8,0x66,0xd2,0xbb,0x84,0x90,0x96,0x33,0xa0,0x4b,0xb1,0xaa,0x31,0xc2,0x91,0xc8,0x00,0x88,0x79,0x49,0x05,0xe1,0xda,0x33,0x33,0x6d,0x87,0x4e,0x2f,0x91,0xcc,0xf4,0x5c,0xc5,0x91,0x85,0xbe,0xde,0x5d,0xd6,0xf3,0xf7,0xac,0xaa,0xe1,0x8b, + 0x04,0x00,0x27,0x77,0x91,0xb3,0x05,0xa4,0x5b,0x2b,0x39,0x59,0x0b,0x2f,0x05,0xd3,0x39,0x2a,0x6c,0x81,0x82,0xce,0xf4,0xeb,0x54,0x01,0x20,0xe0,0xf5,0xc2,0x06,0xc3,0xe4,0x64,0x10,0x82,0x33,0xfb,0x0b,0x8c,0x3a,0xc8,0x92,0xd7,0x9e,0xf8,0xe0,0xfb,0xf9,0x2e,0xd1,0x33,0xad,0xdb,0x45,0x54,0x27,0x01,0x32,0x58,0x4d,0xc5,0x2e,0xef,0x41, + 0x04,0x6e,0xfa,0x09,0x2b,0x68,0xde,0x94,0x60,0xf0,0xbc,0xc9,0x19,0x00,0x5a,0x5f,0x6e,0x80,0xe1,0x9d,0xe9,0x89,0x68,0xbe,0x3c,0xd2,0xc7,0x70,0xa9,0x94,0x9b,0xfb,0x1a,0xc7,0x5e,0x6e,0x50,0x87,0xd6,0x55,0x0d,0x5f,0x9b,0xeb,0x1e,0x79,0xe5,0x02,0x93,0x07,0xbc,0x25,0x52,0x35,0xe2,0xd5,0xdc,0x99,0x24,0x1a,0xc3,0xab,0x88,0x6c,0x49, + 0x04,0x72,0xd4,0xa1,0x9c,0x4f,0x9d,0x2c,0xf5,0x84,0x8e,0xa4,0x04,0x45,0xb7,0x0d,0x46,0x96,0xb5,0xf0,0x2d,0x63,0x2c,0x0c,0x65,0x4c,0xc7,0xd7,0xee,0xb0,0xc6,0xd0,0x58,0xe8,0xc4,0xcd,0x99,0x43,0xe4,0x59,0x17,0x4c,0x7a,0xc0,0x1f,0xa7,0x42,0x19,0x8e,0x47,0xe6,0xc1,0x9a,0x6b,0xdb,0x0c,0x4f,0x6c,0x23,0x78,0x31,0xc1,0xb3,0xf9,0x42, + 0x04,0x2a,0x8e,0xa2,0xf5,0x0d,0xcc,0xed,0x0c,0x21,0x75,0x75,0xbd,0xfa,0x7c,0xd4,0x7d,0x1c,0x6f,0x10,0x00,0x41,0xec,0x0e,0x35,0x51,0x27,0x94,0xc1,0xbe,0x7e,0x74,0x02,0x58,0xf8,0xc1,0x71,0x22,0xed,0x30,0x3f,0xda,0x71,0x43,0xeb,0x58,0xbe,0xde,0x70,0x29,0x5b,0x65,0x32,0x66,0x01,0x3b,0x0b,0x0e,0xbd,0x3f,0x05,0x31,0x37,0xf6,0xec, + 0x04,0x88,0xde,0x68,0x9c,0xe9,0xaf,0x1e,0x94,0xbe,0x6a,0x20,0x89,0xc8,0xa8,0xb1,0x25,0x3f,0xfd,0xbb,0x6c,0x8e,0x9c,0x86,0x24,0x9b,0xa2,0x20,0x00,0x1a,0x4a,0xd3,0xb8,0x0c,0x49,0x98,0xe5,0x48,0x42,0xf4,0x13,0xb9,0xed,0xb1,0x82,0x5a,0xcb,0xb6,0x33,0x5e,0x81,0xe4,0xd1,0x84,0xb2,0xb0,0x1c,0x8b,0xeb,0xdc,0x85,0xd1,0xf2,0x89,0x46, + 0x04,0xfe,0xa2,0xd3,0x1f,0x70,0xf9,0x0d,0x5f,0xb3,0xe0,0x0e,0x18,0x6a,0xc4,0x2a,0xb3,0xc1,0x61,0x5c,0xee,0x71,0x4e,0x0b,0x4e,0x11,0x31,0xb3,0xd4,0xd8,0x22,0x5b,0xf7,0xb0,0x37,0xa1,0x8d,0xf2,0xac,0x15,0x34,0x3f,0x30,0xf7,0x40,0x67,0xdd,0xf2,0x9e,0x81,0x7d,0x5f,0x77,0xf8,0xdc,0xe0,0x57,0x14,0xda,0x59,0xc0,0x94,0xf0,0xcd,0xa9, + 0x04,0x72,0x58,0x91,0x1e,0x3d,0x42,0x33,0x49,0x16,0x64,0x79,0xdb,0xe0,0xb8,0x34,0x1a,0xf7,0xfb,0xd0,0x3d,0x0a,0x7e,0x10,0xed,0xcc,0xb3,0x6b,0x6c,0xee,0xa5,0xa3,0xdb,0x17,0xac,0x2b,0x89,0x92,0x79,0x11,0x28,0xfa,0x3b,0x96,0xdc,0x2f,0xbd,0x4c,0xa3,0xbf,0xa7,0x82,0xef,0x28,0x32,0xfc,0x66,0x56,0x94,0x3d,0xb1,0x8e,0x73,0x46,0xb0, + 0x04,0x4f,0x28,0x46,0x1d,0xea,0x64,0x47,0x4d,0x6b,0xb3,0x4d,0x14,0x99,0xc9,0x7d,0x37,0xb9,0xe9,0x56,0x33,0xdf,0x1c,0xee,0xea,0xac,0xd4,0x50,0x16,0xc9,0x8b,0x39,0x14,0xc8,0x81,0x88,0x10,0xb8,0xcc,0x06,0xdd,0xb4,0x0e,0x8a,0x12,0x61,0xc5,0x28,0xfa,0xa5,0x89,0x45,0x5d,0x5a,0x6d,0xf9,0x3b,0x77,0xbc,0x5e,0x0e,0x49,0x3c,0x74,0x70, + 0x04,0x74,0xf2,0xa8,0x14,0xfb,0x5d,0x8e,0xca,0x91,0xa6,0x9b,0x5e,0x60,0x71,0x27,0x32,0xb3,0x93,0x7d,0xe3,0x28,0x29,0xbe,0x97,0x4e,0xd7,0xb6,0x8c,0x5c,0x2f,0x5d,0x66,0xef,0xf0,0xf0,0x7c,0x56,0xf9,0x87,0xa6,0x57,0xf4,0x21,0x96,0x20,0x5f,0x58,0x8c,0x0f,0x1d,0x96,0xfd,0x8a,0x63,0xa5,0xf2,0x38,0xb4,0x8f,0x47,0x87,0x88,0xfe,0x3b, + 0x04,0x19,0x5b,0x51,0xa7,0xcc,0x4a,0x21,0xb8,0x27,0x4a,0x70,0xa9,0x0d,0xe7,0x79,0x81,0x4c,0x3c,0x8c,0xa3,0x58,0x32,0x82,0x08,0xc0,0x9a,0x29,0xf3,0x36,0xb8,0x2d,0x6a,0xb2,0x41,0x6b,0x7c,0x92,0xff,0xfd,0xc2,0x9c,0x3b,0x12,0x82,0xdd,0x2a,0x77,0xa4,0xd0,0x4d,0xf7,0xf7,0x45,0x20,0x47,0x39,0x3d,0x84,0x99,0x89,0xc5,0xce,0xe9,0xad, + 0x04,0x62,0x2f,0xc7,0x47,0x32,0x03,0x4b,0xec,0x2d,0xdf,0x3b,0xc1,0x6d,0x34,0xb3,0xd1,0xf7,0xa3,0x27,0xdd,0x2a,0x8c,0x19,0xba,0xb4,0xbb,0x4f,0xe3,0xa2,0x4b,0x58,0xaa,0x73,0x6b,0x2f,0x2f,0xae,0x76,0xf4,0xdf,0xae,0xcc,0x90,0x96,0x33,0x3b,0x01,0x32,0x8d,0x51,0xeb,0x3f,0xda,0x9c,0x92,0x27,0xe9,0x0d,0x0b,0x44,0x99,0x83,0xc4,0xf0, + 0x04,0x1f,0x7f,0x85,0xca,0xf2,0xd7,0x55,0x0e,0x7a,0xf9,0xb6,0x50,0x23,0xeb,0xb4,0xdc,0xe3,0x45,0x03,0x11,0x69,0x23,0x09,0xdb,0x26,0x99,0x69,0xb8,0x34,0xb6,0x11,0xc7,0x08,0x27,0xf4,0x5b,0x78,0x02,0x0e,0xcb,0xba,0xf4,0x84,0xfd,0xd5,0xbf,0xaa,0xe6,0x87,0x0f,0x11,0x84,0xc2,0x15,0x81,0xba,0xf6,0xef,0x82,0xbd,0x7b,0x53,0x0f,0x93, + 0x04,0x49,0xc1,0x97,0xdc,0x80,0xad,0x1d,0xa4,0x7a,0x43,0x42,0xb9,0x38,0x93,0xe8,0xe1,0xfb,0x0b,0xb9,0x4f,0xc3,0x3a,0x83,0xe7,0x83,0xc0,0x0b,0x24,0xc7,0x81,0x37,0x7a,0xef,0xc2,0x0d,0xa9,0x2b,0xac,0x76,0x29,0x51,0xf7,0x24,0x74,0xbe,0xcc,0x73,0x4d,0x4c,0xc2,0x2b,0xa8,0x1b,0x89,0x5e,0x28,0x2f,0xda,0xc4,0xdf,0x7a,0xf0,0xf3,0x7d, + 0x04,0xd8,0xcb,0x68,0x51,0x7b,0x61,0x6a,0x56,0x40,0x0a,0xa3,0x86,0x86,0x35,0xe5,0x4b,0x6f,0x69,0x95,0x98,0xa2,0xf6,0x16,0x77,0x57,0x65,0x49,0x80,0xba,0xf6,0xac,0xbe,0x7e,0xc8,0xcf,0x44,0x9c,0x84,0x9a,0xa0,0x34,0x61,0xa3,0x0e,0xfa,0xda,0x41,0x45,0x3c,0x57,0xc6,0xe6,0xfb,0xc9,0x3b,0xbc,0x6f,0xa4,0x9a,0xda,0x6d,0xc0,0x55,0x5c, + 0x04,0x03,0x07,0x13,0xfb,0x63,0xf2,0xaa,0x6f,0xe2,0xca,0xdf,0x1b,0x20,0xef,0xc2,0x59,0xc7,0x74,0x45,0xda,0xfa,0x87,0xda,0xc3,0x98,0xb8,0x40,0x65,0xca,0x34,0x7d,0xf3,0xb2,0x27,0x81,0x8d,0xe1,0xa3,0x9b,0x58,0x9c,0xb0,0x71,0xd8,0x3e,0x53,0x17,0xcc,0xcd,0xc2,0x33,0x8e,0x51,0xe3,0x12,0xfe,0x31,0xd8,0xdc,0x34,0xa4,0x80,0x17,0x50, + 0x04,0xba,0xbb,0x36,0x77,0xb0,0x95,0x58,0x02,0xd8,0xe9,0x29,0xa4,0x13,0x55,0x64,0x0e,0xaf,0x1e,0xa1,0x35,0x3f,0x8a,0x77,0x13,0x31,0xc4,0x94,0x6e,0x34,0x80,0xaf,0xa7,0x25,0x2f,0x19,0x6c,0x87,0xed,0x3d,0x2a,0x59,0xd3,0xb1,0xb5,0x59,0x13,0x7f,0xed,0x00,0x13,0xfe,0xce,0xfc,0x19,0xfb,0x5a,0x92,0x68,0x2b,0x9b,0xca,0x51,0xb9,0x50, + 0x04,0x1a,0xab,0x20,0x18,0x79,0x34,0x71,0x11,0x1a,0x8a,0x0e,0x9b,0x14,0x3f,0xde,0x02,0xfc,0x95,0x92,0x07,0x96,0xd3,0xa6,0x3d,0xe3,0x29,0xb4,0x24,0x39,0x6f,0xba,0x60,0xbb,0xe4,0x13,0x07,0x05,0x17,0x47,0x92,0x44,0x1b,0x31,0x8d,0x3a,0xa3,0x1d,0xfe,0x85,0x77,0x82,0x1e,0x9b,0x44,0x6e,0xc5,0x73,0xd2,0x72,0xe0,0x36,0xc4,0xeb,0xe9, + 0x04,0x8c,0xb0,0xb9,0x09,0x49,0x9c,0x83,0xea,0x80,0x6c,0xd8,0x85,0xb1,0xdd,0x46,0x7a,0x01,0x19,0xf0,0x6a,0x88,0xa0,0x27,0x6e,0xb0,0xcf,0xda,0x27,0x45,0x35,0xa8,0xff,0x47,0xb5,0x42,0x88,0x33,0xbc,0x3f,0x2c,0x8b,0xf9,0xd9,0x04,0x11,0x58,0xcf,0x33,0x71,0x8a,0x69,0x96,0x1c,0xd0,0x17,0x29,0xbc,0x00,0x11,0xd1,0xe5,0x86,0xab,0x75, + 0x04,0x8f,0x03,0xcf,0x1a,0x42,0x27,0x2b,0xb1,0x53,0x27,0x23,0x09,0x3f,0x72,0xe6,0xfe,0xea,0xc8,0x5e,0x17,0x00,0xe9,0xfb,0xe9,0xa6,0xa2,0xdd,0x64,0x2d,0x74,0xbf,0x5d,0x3b,0x89,0xa7,0x18,0x9d,0xad,0x8c,0xf7,0x5f,0xc2,0x2f,0x6f,0x15,0x8a,0xa2,0x7f,0x9c,0x2c,0xa0,0x0d,0xac,0xa7,0x85,0xbe,0x33,0x58,0xf2,0xbd,0xa3,0x86,0x2c,0xa0, + 0x04,0x44,0xde,0x3b,0x9c,0x7a,0x57,0xa8,0xc9,0xe8,0x20,0x95,0x27,0x53,0x42,0x1e,0x7d,0x98,0x7b,0xb3,0xd7,0x9f,0x71,0xf0,0x13,0x80,0x5c,0x89,0x7e,0x01,0x8f,0x8a,0xce,0xa2,0x46,0x07,0x58,0xc8,0xf9,0x8d,0x3f,0xdc,0xe1,0x21,0xa9,0x43,0x65,0x9e,0x37,0x2c,0x32,0x6f,0xff,0x2e,0x5f,0xc2,0xae,0x7f,0xa3,0xf7,0x9d,0xaa,0xe1,0x3c,0x12, + 0x04,0x6f,0xb8,0xb2,0xb4,0x8e,0x33,0x03,0x12,0x68,0xad,0x6a,0x51,0x74,0x84,0xdc,0x88,0x39,0xea,0x90,0xf6,0x66,0x9e,0xa0,0xc7,0xac,0x32,0x33,0xe2,0xac,0x31,0x39,0x4a,0x0a,0xc8,0xbb,0xe7,0xf7,0x3c,0x2f,0xf4,0xdf,0x99,0x78,0x72,0x7a,0xc1,0xdf,0xc2,0xfd,0x58,0x64,0x7d,0x20,0xf3,0x1f,0x99,0x10,0x53,0x16,0xb6,0x46,0x71,0xf2,0x04, + 0x04,0xbe,0xa7,0x11,0x22,0xa0,0x48,0x69,0x3e,0x90,0x5f,0xf6,0x02,0xb3,0xcf,0x9d,0xd1,0x8a,0xf6,0x9b,0x9f,0xc9,0xd8,0x43,0x1d,0x2b,0x1d,0xd2,0x6b,0x94,0x2c,0x95,0xe6,0xf4,0x3c,0x7b,0x8b,0x95,0xeb,0x62,0x08,0x2c,0x12,0xdb,0x9d,0xbd,0xa7,0xfe,0x38,0xe4,0x5c,0xbe,0x4a,0x48,0x86,0x90,0x7f,0xb8,0x1b,0xdb,0x0c,0x5e,0xa9,0x24,0x6c, + 0x04,0xda,0x91,0x8c,0x73,0x1b,0xa0,0x6a,0x20,0xcb,0x94,0xef,0x33,0xb7,0x78,0xe9,0x81,0xa4,0x04,0xa3,0x05,0xf1,0x94,0x1f,0xe3,0x36,0x66,0xb4,0x5b,0x03,0x35,0x31,0x56,0xe2,0xbb,0x26,0x94,0xf5,0x75,0xb4,0x51,0x83,0xbe,0x78,0xe5,0xc9,0xb5,0x21,0x0b,0xf3,0xbf,0x48,0x8f,0xd4,0xc8,0x29,0x45,0x16,0xd8,0x95,0x72,0xca,0x4f,0x53,0x91, + 0x04,0x30,0x07,0xe9,0x2c,0x39,0x37,0xda,0xde,0x79,0x64,0xdf,0xa3,0x5b,0x0e,0xff,0x03,0x1f,0x7e,0xb0,0x2a,0xed,0x0a,0x03,0x14,0x41,0x11,0x06,0xcd,0xeb,0x70,0xfe,0x3d,0x5a,0x75,0x46,0xfc,0x05,0x52,0x99,0x7b,0x20,0xe3,0xd6,0xf4,0x13,0xe7,0x5e,0x2c,0xb6,0x6e,0x11,0x63,0x22,0x69,0x71,0x14,0xb7,0x9b,0xac,0x73,0x4b,0xfc,0x4d,0xc5, + 0x04,0x60,0xe7,0x34,0xef,0x56,0x24,0xd3,0xcb,0xf0,0xdd,0xd3,0x75,0x01,0x1b,0xd6,0x63,0xd6,0xd6,0xae,0xbc,0x64,0x4e,0xb5,0x99,0xfd,0xf9,0x8d,0xbd,0xcd,0x18,0xce,0x9b,0xd2,0xd9,0x0b,0x3a,0xc3,0x1f,0x13,0x9a,0xf8,0x32,0xcc,0xcf,0x6c,0xcb,0xbb,0x2c,0x6e,0xa1,0x1f,0xa9,0x73,0x70,0xdc,0x99,0x06,0xda,0x47,0x4d,0x7d,0x8a,0x75,0x67, + 0x04,0x85,0xa9,0x00,0xe9,0x78,0x58,0xf6,0x93,0xc0,0xb7,0xdf,0xa2,0x61,0xe3,0x80,0xda,0xd6,0xea,0x04,0x6d,0x1f,0x65,0xdd,0xee,0xed,0xd5,0xf7,0xd8,0xaf,0x0b,0xa3,0x37,0x69,0x74,0x4d,0x15,0xad,0xd4,0xf6,0xc0,0xbc,0x3b,0x0d,0xa2,0xae,0xc9,0x3b,0x34,0xcb,0x8c,0x65,0xf9,0x34,0x0d,0xdf,0x74,0xe7,0xb0,0x00,0x9e,0xee,0xcc,0xce,0x3c, + 0x04,0x38,0x06,0x6f,0x75,0xd8,0x8e,0xfc,0x4c,0x93,0xde,0x36,0xf4,0x9e,0x03,0x7b,0x23,0x4c,0xc1,0x8b,0x1d,0xe5,0x60,0x87,0x50,0xa6,0x2c,0xab,0x03,0x45,0x40,0x10,0x46,0xa3,0xe8,0x4b,0xed,0x8c,0xfc,0xb8,0x19,0xef,0x4d,0x55,0x04,0x44,0xf2,0xce,0x4b,0x65,0x17,0x66,0xb6,0x9e,0x2e,0x29,0x01,0xf8,0x88,0x36,0xff,0x90,0x03,0x4f,0xed, + 0x04,0x98,0xf6,0x81,0x77,0xdc,0x95,0xc1,0xb4,0xcb,0xfa,0x52,0x45,0x48,0x8c,0xa5,0x23,0xa7,0xd5,0x62,0x94,0x70,0xd0,0x35,0xd6,0x21,0xa4,0x43,0xc7,0x2f,0x39,0xaa,0xbf,0xa3,0x3d,0x29,0x54,0x6f,0xa1,0xc6,0x48,0xf2,0xc7,0xd5,0xcc,0xf7,0x0c,0xf1,0xce,0x4a,0xb7,0x9b,0x5d,0xb1,0xac,0x05,0x9d,0xbe,0xcd,0x06,0x8d,0xbd,0xff,0x1b,0x89, + 0x04,0x5c,0x2b,0xbf,0xa2,0x3c,0x9b,0x9a,0xd0,0x7f,0x03,0x8a,0xa8,0x9b,0x49,0x30,0xbf,0x26,0x7d,0x94,0x01,0xe4,0x25,0x5d,0xe9,0xe8,0xda,0x0a,0x50,0x78,0xec,0x82,0x77,0xe3,0xe8,0x82,0xa3,0x1d,0x5e,0x6a,0x37,0x9e,0x07,0x93,0x98,0x3c,0xcd,0xed,0x39,0xb9,0x5c,0x43,0x53,0xab,0x2f,0xf0,0x1e,0xa5,0x36,0x9b,0xa4,0x7b,0x0c,0x31,0x91, + 0x04,0x2e,0xa7,0x13,0x34,0x32,0x33,0x9c,0x69,0xd2,0x7f,0x9b,0x26,0x72,0x81,0xbd,0x2d,0xdd,0x5f,0x19,0xd6,0x33,0x8d,0x40,0x0a,0x05,0xcd,0x36,0x47,0xb1,0x57,0xa3,0x85,0x35,0x47,0x80,0x82,0x98,0x44,0x8e,0xdb,0x5e,0x70,0x1a,0xde,0x84,0xcd,0x5f,0xb1,0xac,0x95,0x67,0xba,0x5e,0x8f,0xb6,0x8a,0x6b,0x93,0x3e,0xc4,0xb5,0xcc,0x84,0xcc, + 0x04,0x2e,0xa7,0x13,0x34,0x32,0x33,0x9c,0x69,0xd2,0x7f,0x9b,0x26,0x72,0x81,0xbd,0x2d,0xdd,0x5f,0x19,0xd6,0x33,0x8d,0x40,0x0a,0x05,0xcd,0x36,0x47,0xb1,0x57,0xa3,0x85,0xca,0xb8,0x7f,0x7d,0x67,0xbb,0x71,0x24,0xa1,0x8f,0xe5,0x21,0x7b,0x32,0xa0,0x4e,0x53,0x6a,0x98,0x45,0xa1,0x70,0x49,0x75,0x94,0x6c,0xc1,0x3a,0x4a,0x33,0x77,0x63, + 0x04,0x8a,0xa2,0xc6,0x4f,0xa9,0xc6,0x43,0x75,0x63,0xab,0xfb,0xcb,0xd0,0x0b,0x20,0x48,0xd4,0x8c,0x18,0xc1,0x52,0xa2,0xa6,0xf4,0x90,0x36,0xde,0x76,0x47,0xeb,0xe8,0x2e,0x1c,0xe6,0x43,0x87,0x99,0x5c,0x68,0xa0,0x60,0xfa,0x3b,0xc0,0x39,0x9b,0x05,0xcc,0x06,0xee,0xc7,0xd5,0x98,0xf7,0x50,0x41,0xa4,0x91,0x7e,0x69,0x2b,0x7f,0x51,0xff, + 0x04,0x39,0x14,0x27,0xff,0x7e,0xe7,0x80,0x13,0xc1,0x4a,0xec,0x7d,0x96,0xa8,0xa0,0x62,0x20,0x92,0x98,0xa7,0x83,0x83,0x5e,0x94,0xfd,0x65,0x49,0xd5,0x02,0xff,0xf7,0x1f,0xdd,0x66,0x24,0xec,0x34,0x3a,0xd9,0xfc,0xf4,0xd9,0x87,0x21,0x81,0xe5,0x9f,0x84,0x2f,0x9b,0xa4,0xcc,0xca,0xe0,0x9a,0x6c,0x09,0x72,0xfb,0x6a,0xc6,0xb4,0xc6,0xbd, + 0x04,0xe7,0x62,0xb8,0xa2,0x19,0xb4,0xf1,0x80,0x21,0x9c,0xc7,0xa9,0x05,0x92,0x45,0xe4,0x96,0x1b,0xd1,0x91,0xc0,0x38,0x99,0x78,0x9c,0x7a,0x34,0xb8,0x9e,0x8c,0x13,0x8e,0xc1,0x53,0x3e,0xf0,0x41,0x9b,0xb7,0x37,0x6e,0x0b,0xfd,0xe9,0x31,0x9d,0x10,0xa0,0x69,0x68,0x79,0x1d,0x9e,0xa0,0xee,0xd9,0xc1,0xce,0x63,0x45,0xae,0xd9,0x75,0x9e, + 0x04,0x9a,0xed,0xb0,0xd2,0x81,0xdb,0x16,0x4e,0x13,0x00,0x00,0xc5,0x69,0x7f,0xae,0x0f,0x30,0x5e,0xf8,0x48,0xbe,0x6f,0xff,0xb4,0x3a,0xc5,0x93,0xfb,0xb9,0x50,0xe9,0x52,0xfa,0x6f,0x63,0x33,0x59,0xbd,0xcd,0x82,0xb5,0x6b,0x0b,0x9f,0x96,0x5b,0x03,0x77,0x89,0xd4,0x6b,0x9a,0x81,0x41,0xb7,0x91,0xb2,0xae,0xfa,0x71,0x3f,0x96,0xc1,0x75, + 0x04,0x8a,0xd4,0x45,0xdb,0x62,0x81,0x62,0x60,0xe4,0xe6,0x87,0xfd,0x18,0x84,0xe4,0x8b,0x9f,0xc0,0x63,0x6d,0x03,0x15,0x47,0xd6,0x33,0x15,0xe7,0x92,0xe1,0x9b,0xfa,0xee,0x1d,0xe6,0x4f,0x99,0xd5,0xf1,0xcd,0x8b,0x6e,0xc9,0xcb,0x0f,0x78,0x7a,0x65,0x4a,0xe8,0x69,0x93,0xba,0x3d,0xb1,0x00,0x8e,0xf4,0x3c,0xff,0x06,0x84,0xcb,0x22,0xbd, + 0x04,0x1f,0x57,0x99,0xc9,0x5b,0xe8,0x90,0x63,0xb2,0x4f,0x26,0xe4,0x0c,0xb9,0x28,0xc1,0xa8,0x68,0xa7,0x6f,0xb0,0x09,0x46,0x07,0xe8,0x04,0x3d,0xb4,0x09,0xc9,0x1c,0x32,0xe7,0x57,0x24,0xe8,0x13,0xa4,0x19,0x1e,0x3a,0x83,0x90,0x07,0xf0,0x8e,0x2e,0x89,0x73,0x88,0xb0,0x6d,0x4a,0x00,0xde,0x6d,0xe6,0x0e,0x53,0x6d,0x91,0xfa,0xb5,0x66, + 0x04,0xa3,0x33,0x1a,0x4e,0x1b,0x42,0x23,0xec,0x2c,0x02,0x7e,0xdd,0x48,0x2c,0x92,0x8a,0x14,0xed,0x35,0x8d,0x93,0xf1,0xd4,0x21,0x7d,0x39,0xab,0xf6,0x9f,0xcb,0x5c,0xcc,0x28,0xd6,0x84,0xd2,0xaa,0xab,0xcd,0x63,0x83,0x77,0x5c,0xaa,0x62,0x39,0xde,0x26,0xd4,0xc6,0x93,0x7b,0xb6,0x03,0xec,0xb4,0x19,0x60,0x82,0xf4,0xcf,0xfd,0x50,0x9d, + 0x04,0x3f,0x39,0x52,0x19,0x97,0x74,0xc7,0xcf,0x39,0xb3,0x8b,0x66,0xcb,0x10,0x42,0xa6,0x26,0x0d,0x86,0x80,0x80,0x38,0x45,0xe4,0xd4,0x33,0xad,0xba,0x3b,0xb2,0x48,0x18,0x5e,0xa4,0x95,0xb6,0x8c,0xbc,0x7e,0xd4,0x17,0x3e,0xe6,0x3c,0x90,0x42,0xdc,0x50,0x26,0x25,0xc7,0xeb,0x7e,0x21,0xfb,0x02,0xca,0x9a,0x91,0x14,0xe0,0xa3,0xa1,0x8d, + 0x04,0xcd,0xfb,0x8c,0x0f,0x42,0x2e,0x14,0x4e,0x13,0x7c,0x24,0x12,0xc8,0x6c,0x17,0x1f,0x5f,0xe3,0xfa,0x3f,0x5b,0xbb,0x54,0x4e,0x90,0x76,0x28,0x8f,0x3c,0xed,0x78,0x6e,0x05,0x4f,0xd0,0x72,0x1b,0x77,0xc1,0x1c,0x79,0xbe,0xac,0xb3,0xc9,0x42,0x11,0xb0,0xa1,0x9b,0xda,0x08,0x65,0x2e,0xfe,0xaf,0x92,0x51,0x3a,0x3b,0x0a,0x16,0x36,0x98, + 0x04,0x73,0x59,0x8a,0x6a,0x1c,0x68,0x27,0x8f,0xa6,0xbf,0xd0,0xce,0x40,0x64,0xe6,0x82,0x35,0xbc,0x1c,0x0f,0x6b,0x20,0xa9,0x28,0x10,0x8b,0xe3,0x36,0x73,0x0f,0x87,0xe3,0xcb,0xae,0x61,0x25,0x19,0xb5,0x03,0x2e,0xcc,0x85,0xae,0xd8,0x11,0x27,0x1a,0x95,0xfe,0x79,0x39,0xd5,0xd3,0x46,0x01,0x40,0xba,0x31,0x8f,0x4d,0x14,0xab,0xa3,0x1d, + 0x04,0x58,0xde,0xbd,0x9a,0x7e,0xe2,0xc9,0xd5,0x91,0x32,0x47,0x8a,0x54,0x40,0xae,0x4d,0x5d,0x7e,0xd4,0x37,0x30,0x83,0x69,0xf9,0x2e,0xa8,0x6c,0x82,0x18,0x3f,0x10,0xa1,0x67,0x73,0xe7,0x6f,0x5e,0xdb,0xf4,0xda,0x0e,0x4f,0x1b,0xdf,0xfa,0xc0,0xf5,0x72,0x57,0xe1,0xdf,0xa4,0x65,0x84,0x29,0x31,0x30,0x9a,0x24,0x24,0x5f,0xda,0x6a,0x5d, + 0x04,0x8b,0x90,0x4d,0xe4,0x79,0x67,0x34,0x0c,0x5f,0x8c,0x35,0x72,0xa7,0x20,0x92,0x4e,0xf7,0x57,0x86,0x37,0xfe,0xab,0x19,0x49,0xac,0xb2,0x41,0xa5,0xa6,0xac,0x3f,0x5b,0x95,0x09,0x04,0x49,0x6f,0x98,0x24,0xb1,0xd6,0x3f,0x33,0x13,0xba,0xe2,0x1b,0x89,0xfa,0xe8,0x9a,0xfd,0xfc,0x81,0x1b,0x5e,0xce,0x03,0xfd,0x5a,0xa3,0x01,0x86,0x4f, + 0x04,0xf4,0x89,0x2b,0x6d,0x52,0x5c,0x77,0x1e,0x03,0x5f,0x2a,0x25,0x27,0x08,0xf3,0x78,0x4e,0x48,0x23,0x86,0x04,0xb4,0xf9,0x4d,0xc5,0x6e,0xaa,0x1e,0x54,0x6d,0x94,0x1a,0x34,0x6b,0x1a,0xa0,0xbc,0xe6,0x8b,0x1c,0x50,0xe5,0xb5,0x2f,0x50,0x9f,0xb5,0x52,0x2e,0x5c,0x25,0xe0,0x28,0xbc,0x8f,0x86,0x34,0x02,0xed,0xb7,0xbc,0xad,0x8b,0x1b, + 0x04,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4,0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,0xd4,0xb8, + 0x04,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0xb7,0xc5,0x25,0x88,0xd9,0x5c,0x3b,0x9a,0xa2,0x5b,0x04,0x03,0xf1,0xee,0xf7,0x57,0x02,0xe8,0x4b,0xb7,0x59,0x7a,0xab,0xe6,0x63,0xb8,0x2f,0x6f,0x04,0xef,0x27,0x77, + 0x04,0x78,0x2c,0x8e,0xd1,0x7e,0x3b,0x2a,0x78,0x3b,0x54,0x64,0xf3,0x3b,0x09,0x65,0x2a,0x71,0xc6,0x78,0xe0,0x5e,0xc5,0x1e,0x84,0xe2,0xbc,0xfc,0x66,0x3a,0x3d,0xe9,0x63,0xaf,0x9a,0xcb,0x42,0x80,0xb8,0xc7,0xf7,0xc4,0x2f,0x4e,0xf9,0xab,0xa6,0x24,0x5e,0xc1,0xec,0x17,0x12,0xfd,0x38,0xa0,0xfa,0x96,0x41,0x8d,0x8c,0xd6,0xaa,0x61,0x52, + 0x04,0x6e,0x82,0x35,0x55,0x45,0x29,0x14,0x09,0x91,0x82,0xc6,0xb2,0xc1,0xd6,0xf0,0xb5,0xd2,0x8d,0x50,0xcc,0xd0,0x05,0xaf,0x2c,0xe1,0xbb,0xa5,0x41,0xaa,0x40,0xca,0xff,0x00,0x00,0x00,0x01,0x06,0x04,0x92,0xd5,0xa5,0x67,0x3e,0x0f,0x25,0xd8,0xd5,0x0f,0xb7,0xe5,0x8c,0x49,0xd8,0x6d,0x46,0xd4,0x21,0x69,0x55,0xe0,0xaa,0x3d,0x40,0xe1, + 0x04,0x6e,0x82,0x35,0x55,0x45,0x29,0x14,0x09,0x91,0x82,0xc6,0xb2,0xc1,0xd6,0xf0,0xb5,0xd2,0x8d,0x50,0xcc,0xd0,0x05,0xaf,0x2c,0xe1,0xbb,0xa5,0x41,0xaa,0x40,0xca,0xff,0xff,0xff,0xff,0xfe,0xf9,0xfb,0x6d,0x2a,0x5a,0x98,0xc1,0xf0,0xda,0x27,0x2a,0xf0,0x48,0x1a,0x73,0xb6,0x27,0x92,0xb9,0x2b,0xde,0x96,0xaa,0x1e,0x55,0xc2,0xbb,0x4e, + 0x04,0x00,0x00,0x00,0x01,0x3f,0xd2,0x22,0x48,0xd6,0x4d,0x95,0xf7,0x3c,0x29,0xb4,0x8a,0xb4,0x86,0x31,0x85,0x0b,0xe5,0x03,0xfd,0x00,0xf8,0x46,0x8b,0x5f,0x0f,0x70,0xe0,0xf6,0xee,0x7a,0xa4,0x3b,0xc2,0xc6,0xfd,0x25,0xb1,0xd8,0x26,0x92,0x41,0xcb,0xdd,0x9d,0xbb,0x0d,0xac,0x96,0xdc,0x96,0x23,0x1f,0x43,0x07,0x05,0xf8,0x38,0x71,0x7d, + 0x04,0x25,0xaf,0xd6,0x89,0xac,0xab,0xae,0xd6,0x7c,0x1f,0x29,0x6d,0xe5,0x94,0x06,0xf8,0xc5,0x50,0xf5,0x71,0x46,0xa0,0xb4,0xec,0x2c,0x97,0x87,0x6d,0xff,0xff,0xff,0xff,0xfa,0x46,0xa7,0x6e,0x52,0x03,0x22,0xdf,0xbc,0x49,0x1e,0xc4,0xf0,0xcc,0x19,0x74,0x20,0xfc,0x4e,0xa5,0x88,0x3d,0x8f,0x6d,0xd5,0x3c,0x35,0x4b,0xc4,0xf6,0x7c,0x35, + 0x04,0xd1,0x2e,0x6c,0x66,0xb6,0x77,0x34,0xc3,0xc8,0x4d,0x26,0x01,0xcf,0x5d,0x35,0xdc,0x09,0x7e,0x27,0x63,0x7f,0x0a,0xca,0x4a,0x4f,0xdb,0x74,0xb6,0xaa,0xdd,0x3b,0xb9,0x3f,0x5b,0xdf,0xf8,0x8b,0xd5,0x73,0x6d,0xf8,0x98,0xe6,0x99,0x00,0x6e,0xd7,0x50,0xf1,0x1c,0xf0,0x7c,0x58,0x66,0xcd,0x7a,0xd7,0x0c,0x71,0x21,0xff,0xff,0xff,0xff, + 0x04,0x6d,0x4a,0x7f,0x60,0xd4,0x77,0x4a,0x4f,0x0a,0xa8,0xbb,0xde,0xdb,0x95,0x3c,0x7e,0xea,0x79,0x09,0x40,0x7e,0x31,0x64,0x75,0x56,0x64,0xbc,0x28,0x00,0x00,0x00,0x00,0xe6,0x59,0xd3,0x4e,0x4d,0xf3,0x8d,0x9e,0x8c,0x9e,0xaa,0xdf,0xba,0x36,0x61,0x2c,0x76,0x91,0x95,0xbe,0x86,0xc7,0x7a,0xac,0x3f,0x36,0xe7,0x8b,0x53,0x86,0x80,0xfb}; + +static const unsigned char wycheproof_ecdsa_signatures[] = { 0x30,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x21,0x00,0x90,0x0e,0x75,0xad,0x23,0x3f,0xcc,0x90,0x85,0x09,0xdb,0xff,0x59,0x22,0x64,0x7d,0xb3,0x7c,0x21,0xf4,0xaf,0xd3,0x20,0x3a,0xe8,0xdc,0x4a,0xe7,0x79,0x4b,0x0f,0x87, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x81,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x82,0x00,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x44,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x85,0x01,0x00,0x00,0x00,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x89,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x84,0x7f,0xff,0xff,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x84,0x80,0x00,0x00,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x84,0xff,0xff,0xff,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x85,0xff,0xff,0xff,0xff,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x88,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00, + 0x30,0x47,0x00,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x05,0x00, + 0x30,0x4a,0x49,0x81,0x77,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x25,0x00,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x04,0xde,0xad,0xbe,0xef, + 0x30,0x4d,0xaa,0x00,0xbb,0x00,0xcd,0x00,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4d,0x22,0x29,0xaa,0x00,0xbb,0x00,0xcd,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4d,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x28,0xaa,0x00,0xbb,0x00,0xcd,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x81, + 0x30,0x4b,0xaa,0x02,0xaa,0xbb,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x80,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00, + 0x30,0x80,0x31,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00, + 0x05,0x00, + 0x2e,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x2f,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x31,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x32,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0xff,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x00, + 0x30,0x49,0x30,0x01,0x02,0x30,0x44,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x44,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31, + 0x30,0x44,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x82,0x10,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00, + 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00, + 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x05,0x00,0x00,0x00, + 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x06,0x08,0x11,0x22,0x00,0x00, + 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,0xfe,0x02,0xbe,0xef, + 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x02,0xbe,0xef, + 0x30,0x47,0x30,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x30,0x00, + 0x30,0x48,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x01,0x00, + 0x30,0x48,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0xbf,0x7f,0x00, + 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0xa0,0x02,0x05,0x00, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0xa0,0x00, + 0x30,0x47,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x23,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65, + 0x30,0x67,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x43,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x64,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x43,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xca,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x43,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x13,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x43,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x08,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x46,0x02,0x81,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x02,0x82,0x00,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x22,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x20,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4a,0x02,0x85,0x01,0x00,0x00,0x00,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4e,0x02,0x89,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x02,0x84,0x7f,0xff,0xff,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x02,0x84,0x80,0x00,0x00,0x00,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x02,0x84,0xff,0xff,0xff,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4a,0x02,0x85,0xff,0xff,0xff,0xff,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4d,0x02,0x88,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x80,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x22,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x23,0x02,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x24,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02, + 0x30,0x47,0x02,0x23,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x02,0x23,0x00,0x00,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x02,0x23,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x05,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4a,0x22,0x26,0x49,0x81,0x77,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x22,0x25,0x25,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4d,0x22,0x23,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x04,0xde,0xad,0xbe,0xef,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x24,0x02,0x81,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4b,0x22,0x27,0xaa,0x02,0xaa,0xbb,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x22,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x22,0x80,0x03,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x24,0x05,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x00,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x01,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x03,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x04,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0xff,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x24,0x02,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x22,0x25,0x02,0x01,0x00,0x02,0x20,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x02,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0xe5,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x44,0x02,0x20,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x44,0x02,0x20,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x82,0x10,0x48,0x02,0x82,0x10,0x22,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x46,0x02,0x22,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x25,0x09,0x01,0x80,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x25,0x02,0x01,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x43,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xbb, + 0x30,0x43,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa4,0x56,0xeb,0x31,0xba, + 0x30,0x43,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf7,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x43,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x01,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x81,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x82,0x00,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x21,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x1f,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4a,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x85,0x01,0x00,0x00,0x00,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4e,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x89,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x84,0x7f,0xff,0xff,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x84,0x80,0x00,0x00,0x00,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x84,0xff,0xff,0xff,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4a,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x85,0xff,0xff,0xff,0xff,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4d,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x88,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x80,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x22,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x22,0x00,0x00,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x22,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x05,0x00, + 0x30,0x4a,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x25,0x49,0x81,0x77,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x24,0x25,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4d,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x22,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x04,0xde,0xad,0xbe,0xef, + 0x30,0x25,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x81, + 0x30,0x4b,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x26,0xaa,0x02,0xaa,0xbb,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x80,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00, + 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x80,0x03,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00, + 0x30,0x25,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x05,0x00, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x01,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x03,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x04,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0xff,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x25,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x00, + 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x24,0x02,0x01,0x6f,0x02,0x1f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6d,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0x3a, + 0x30,0x44,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x1f,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31, + 0x30,0x44,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x1f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x82,0x10,0x48,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x82,0x10,0x21,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x30,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x21,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x26,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x09,0x01,0x80, + 0x30,0x26,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x01,0x00, + 0x30,0x45,0x02,0x21,0x01,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x83,0xb9,0x0d,0xea,0xbc,0xa4,0xb0,0x5c,0x45,0x74,0xe4,0x9b,0x58,0x99,0xb9,0x64,0xa6,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x44,0x02,0x20,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x86,0x43,0xb0,0x30,0xef,0x46,0x1f,0x1b,0xcd,0xf5,0x3f,0xde,0x3e,0xf9,0x4c,0xe2,0x24,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x46,0x02,0x22,0x01,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x84,0x3f,0xad,0x3b,0xf4,0x85,0x3e,0x07,0xf7,0xc9,0x87,0x70,0xc9,0x9b,0xff,0xc4,0x64,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0xff,0x7e,0xc1,0x08,0x63,0x31,0x05,0x65,0xa9,0x08,0x45,0x7f,0xa0,0xf1,0xb8,0x7a,0x7b,0x01,0xa0,0xf2,0x2a,0x0a,0x98,0x43,0xf6,0x4a,0xed,0xc3,0x34,0x36,0x7c,0xdc,0x9b,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x44,0x02,0x20,0x7e,0xc1,0x08,0x63,0x31,0x05,0x65,0xa9,0x08,0x45,0x7f,0xa0,0xf1,0xb8,0x7a,0x79,0xbc,0x4f,0xcf,0x10,0xb9,0xe0,0xe4,0x32,0x0a,0xc0,0x21,0xc1,0x06,0xb3,0x1d,0xdc,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0xfe,0x7e,0xc1,0x08,0x63,0x31,0x05,0x65,0xa9,0x08,0x45,0x7f,0xa0,0xf1,0xb8,0x7a,0x7c,0x46,0xf2,0x15,0x43,0x5b,0x4f,0xa3,0xba,0x8b,0x1b,0x64,0xa7,0x66,0x46,0x9b,0x5a,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x01,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4d,0x02,0x29,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x01,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x7f,0xc1,0xe1,0x97,0xd8,0xae,0xbe,0x20,0x3c,0x96,0xc8,0x72,0x32,0x27,0x21,0x72,0xfb,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x82,0x4c,0x83,0xde,0x0b,0x50,0x2c,0xdf,0xc5,0x17,0x23,0xb5,0x18,0x86,0xb4,0xf0,0x79,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x46,0x02,0x22,0x01,0x00,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9a,0x3b,0xb6,0x0f,0xa1,0xa1,0x48,0x15,0xbb,0xc0,0xa9,0x54,0xa0,0x75,0x8d,0x2c,0x72,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x44,0x02,0x20,0x90,0x0e,0x75,0xad,0x23,0x3f,0xcc,0x90,0x85,0x09,0xdb,0xff,0x59,0x22,0x64,0x7e,0xf8,0xcd,0x45,0x0e,0x00,0x8a,0x7f,0xff,0x29,0x09,0xec,0x5a,0xa9,0x14,0xce,0x46,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0xfe,0x90,0x0e,0x75,0xad,0x23,0x3f,0xcc,0x90,0x85,0x09,0xdb,0xff,0x59,0x22,0x64,0x80,0x3e,0x1e,0x68,0x27,0x51,0x41,0xdf,0xc3,0x69,0x37,0x8d,0xcd,0xd8,0xde,0x8d,0x05,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0x01,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x45,0x02,0x21,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x4d,0x02,0x29,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba, + 0x30,0x06,0x02,0x01,0x00,0x02,0x01,0x00, + 0x30,0x06,0x02,0x01,0x00,0x02,0x01,0x01, + 0x30,0x06,0x02,0x01,0x00,0x02,0x01,0xff, + 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41, + 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40, + 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42, + 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f, + 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30, + 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x00, + 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x01, + 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0xff, + 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41, + 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40, + 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42, + 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f, + 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30, + 0x30,0x06,0x02,0x01,0xff,0x02,0x01,0x00, + 0x30,0x06,0x02,0x01,0xff,0x02,0x01,0x01, + 0x30,0x06,0x02,0x01,0xff,0x02,0x01,0xff, + 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41, + 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40, + 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42, + 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f, + 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x01,0x00, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x01,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x01,0xff, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x01,0x00, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x01,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x01,0xff, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x01,0x00, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x01,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x01,0xff, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x01,0x00, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x01,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x01,0xff, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x01,0x00, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x01,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x01,0xff, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f, + 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30, + 0x30,0x08,0x02,0x01,0x00,0x09,0x03,0x80,0xfe,0x01, + 0x30,0x06,0x02,0x01,0x00,0x09,0x01,0x42, + 0x30,0x06,0x02,0x01,0x00,0x01,0x01,0x01, + 0x30,0x06,0x02,0x01,0x00,0x01,0x01,0x00, + 0x30,0x05,0x02,0x01,0x00,0x05,0x00, + 0x30,0x05,0x02,0x01,0x00,0x0c,0x00, + 0x30,0x06,0x02,0x01,0x00,0x0c,0x01,0x30, + 0x30,0x05,0x02,0x01,0x00,0x30,0x00, + 0x30,0x08,0x02,0x01,0x00,0x30,0x03,0x02,0x01,0x00, + 0x30,0x08,0x02,0x01,0x01,0x09,0x03,0x80,0xfe,0x01, + 0x30,0x06,0x02,0x01,0x01,0x09,0x01,0x42, + 0x30,0x06,0x02,0x01,0x01,0x01,0x01,0x01, + 0x30,0x06,0x02,0x01,0x01,0x01,0x01,0x00, + 0x30,0x05,0x02,0x01,0x01,0x05,0x00, + 0x30,0x05,0x02,0x01,0x01,0x0c,0x00, + 0x30,0x06,0x02,0x01,0x01,0x0c,0x01,0x30, + 0x30,0x05,0x02,0x01,0x01,0x30,0x00, + 0x30,0x08,0x02,0x01,0x01,0x30,0x03,0x02,0x01,0x00, + 0x30,0x08,0x02,0x01,0xff,0x09,0x03,0x80,0xfe,0x01, + 0x30,0x06,0x02,0x01,0xff,0x09,0x01,0x42, + 0x30,0x06,0x02,0x01,0xff,0x01,0x01,0x01, + 0x30,0x06,0x02,0x01,0xff,0x01,0x01,0x00, + 0x30,0x05,0x02,0x01,0xff,0x05,0x00, + 0x30,0x05,0x02,0x01,0xff,0x0c,0x00, + 0x30,0x06,0x02,0x01,0xff,0x0c,0x01,0x30, + 0x30,0x05,0x02,0x01,0xff,0x30,0x00, + 0x30,0x08,0x02,0x01,0xff,0x30,0x03,0x02,0x01,0x00, + 0x30,0x28,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x09,0x03,0x80,0xfe,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x09,0x01,0x42, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x01,0x01,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x01,0x01,0x00, + 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x05,0x00, + 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x0c,0x00, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x0c,0x01,0x30, + 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x30,0x00, + 0x30,0x28,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x30,0x03,0x02,0x01,0x00, + 0x30,0x28,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x09,0x03,0x80,0xfe,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x09,0x01,0x42, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x01,0x01,0x01, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x01,0x01,0x00, + 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x05,0x00, + 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x0c,0x00, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x0c,0x01,0x30, + 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x30,0x00, + 0x30,0x28,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x30,0x03,0x02,0x01,0x00, + 0x30,0x0a,0x09,0x03,0x80,0xfe,0x01,0x09,0x03,0x80,0xfe,0x01, + 0x30,0x06,0x09,0x01,0x42,0x09,0x01,0x42, + 0x30,0x06,0x01,0x01,0x01,0x01,0x01,0x01, + 0x30,0x06,0x01,0x01,0x00,0x01,0x01,0x00, + 0x30,0x04,0x05,0x00,0x05,0x00, + 0x30,0x04,0x0c,0x00,0x0c,0x00, + 0x30,0x06,0x0c,0x01,0x30,0x0c,0x01,0x30, + 0x30,0x04,0x30,0x00,0x30,0x00, + 0x30,0x0a,0x30,0x03,0x02,0x01,0x00,0x30,0x03,0x02,0x01,0x00, + 0x30,0x08,0x09,0x03,0x80,0xfe,0x01,0x02,0x01,0x00, + 0x30,0x06,0x09,0x01,0x42,0x02,0x01,0x00, + 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x00, + 0x30,0x06,0x01,0x01,0x00,0x02,0x01,0x00, + 0x30,0x05,0x05,0x00,0x02,0x01,0x00, + 0x30,0x05,0x0c,0x00,0x02,0x01,0x00, + 0x30,0x06,0x0c,0x01,0x30,0x02,0x01,0x00, + 0x30,0x05,0x30,0x00,0x02,0x01,0x00, + 0x30,0x08,0x30,0x03,0x02,0x01,0x00,0x02,0x01,0x00, + 0x30,0x45,0x02,0x21,0x00,0xdd,0x1b,0x7d,0x09,0xa7,0xbd,0x82,0x18,0x96,0x10,0x34,0xa3,0x9a,0x87,0xfe,0xcf,0x53,0x14,0xf0,0x0c,0x4d,0x25,0xeb,0x58,0xa0,0x7a,0xc8,0x5e,0x85,0xea,0xb5,0x16,0x02,0x20,0x35,0x13,0x8c,0x40,0x1e,0xf8,0xd3,0x49,0x3d,0x65,0xc9,0x00,0x2f,0xe6,0x2b,0x43,0xae,0xe5,0x68,0x73,0x1b,0x74,0x45,0x48,0x35,0x89,0x96,0xd9,0xcc,0x42,0x7e,0x06, + 0x30,0x45,0x02,0x21,0x00,0x95,0xc2,0x92,0x67,0xd9,0x72,0xa0,0x43,0xd9,0x55,0x22,0x45,0x46,0x22,0x2b,0xba,0x34,0x3f,0xc1,0xd4,0xdb,0x0f,0xec,0x26,0x2a,0x33,0xac,0x61,0x30,0x56,0x96,0xae,0x02,0x20,0x6e,0xdf,0xe9,0x67,0x13,0xae,0xd5,0x6f,0x8a,0x28,0xa6,0x65,0x3f,0x57,0xe0,0xb8,0x29,0x71,0x2e,0x5e,0xdd,0xc6,0x7f,0x34,0x68,0x2b,0x24,0xf0,0x67,0x6b,0x26,0x40, + 0x30,0x44,0x02,0x20,0x28,0xf9,0x4a,0x89,0x4e,0x92,0x02,0x46,0x99,0xe3,0x45,0xfe,0x66,0x97,0x1e,0x3e,0xdc,0xd0,0x50,0x02,0x33,0x86,0x13,0x5a,0xb3,0x93,0x9d,0x55,0x08,0x98,0xfb,0x25,0x02,0x20,0x32,0x96,0x3e,0x5b,0xd4,0x1f,0xa5,0x91,0x1e,0xd8,0xf3,0x7d,0xeb,0x86,0xda,0xe0,0xa7,0x62,0xbb,0x61,0x21,0xc8,0x94,0x61,0x50,0x83,0xc5,0xd9,0x5e,0xa0,0x1d,0xb3, + 0x30,0x45,0x02,0x21,0x00,0xbe,0x26,0xb1,0x8f,0x95,0x49,0xf8,0x9f,0x41,0x1a,0x9b,0x52,0x53,0x6b,0x15,0xaa,0x27,0x0b,0x84,0x54,0x8d,0x0e,0x85,0x9a,0x19,0x52,0xa2,0x7a,0xf1,0xa7,0x7a,0xc6,0x02,0x20,0x70,0xc1,0xd4,0xfa,0x9c,0xd0,0x3c,0xc8,0xea,0xa8,0xd5,0x06,0xed,0xb9,0x7e,0xed,0x7b,0x83,0x58,0xb4,0x53,0xc8,0x8a,0xef,0xbb,0x88,0x0a,0x3f,0x0e,0x8d,0x47,0x2f, + 0x30,0x45,0x02,0x21,0x00,0xb1,0xa4,0xb1,0x47,0x8e,0x65,0xcc,0x3e,0xaf,0xdf,0x22,0x5d,0x12,0x98,0xb4,0x3f,0x2d,0xa1,0x9e,0x4b,0xcf,0xf7,0xea,0xcc,0x0a,0x2e,0x98,0xcd,0x4b,0x74,0xb1,0x14,0x02,0x20,0x17,0x9a,0xa3,0x1e,0x30,0x4c,0xc1,0x42,0xcf,0x50,0x73,0x17,0x17,0x51,0xb2,0x8f,0x3f,0x5e,0x0f,0xa8,0x8c,0x99,0x4e,0x7c,0x55,0xf1,0xbc,0x07,0xb8,0xd5,0x6c,0x16, + 0x30,0x44,0x02,0x20,0x32,0x53,0x32,0x02,0x12,0x61,0xf1,0xbd,0x18,0xf2,0x71,0x2a,0xa1,0xe2,0x25,0x2d,0xa2,0x37,0x96,0xda,0x8a,0x4b,0x1f,0xf6,0xea,0x18,0xca,0xfe,0xc7,0xe1,0x71,0xf2,0x02,0x20,0x40,0xb4,0xf5,0xe2,0x87,0xee,0x61,0xfc,0x3c,0x80,0x41,0x86,0x98,0x23,0x60,0x89,0x1e,0xaa,0x35,0xc7,0x5f,0x05,0xa4,0x3e,0xcd,0x48,0xb3,0x5d,0x98,0x4a,0x66,0x48, + 0x30,0x45,0x02,0x21,0x00,0xa2,0x3a,0xd1,0x8d,0x8f,0xc6,0x6d,0x81,0xaf,0x09,0x03,0x89,0x0c,0xbd,0x45,0x3a,0x55,0x4c,0xb0,0x4c,0xdc,0x1a,0x8c,0xa7,0xf7,0xf7,0x8e,0x53,0x67,0xed,0x88,0xa0,0x02,0x20,0x23,0xe3,0xeb,0x2c,0xe1,0xc0,0x4e,0xa7,0x48,0xc3,0x89,0xbd,0x97,0x37,0x4a,0xa9,0x41,0x3b,0x92,0x68,0x85,0x1c,0x04,0xdc,0xd9,0xf8,0x8e,0x78,0x81,0x3f,0xee,0x56, + 0x30,0x44,0x02,0x20,0x2b,0xde,0xa4,0x1c,0xda,0x63,0xa2,0xd1,0x4b,0xf4,0x73,0x53,0xbd,0x20,0x88,0x0a,0x69,0x09,0x01,0xde,0x7c,0xd6,0xe3,0xcc,0x6d,0x8e,0xd5,0xba,0x0c,0xdb,0x10,0x91,0x02,0x20,0x3c,0xea,0x66,0xbc,0xcf,0xc9,0xf9,0xbf,0x8c,0x7c,0xa4,0xe1,0xc1,0x45,0x7c,0xc9,0x14,0x5e,0x13,0xe9,0x36,0xd9,0x0b,0x3d,0x9c,0x77,0x86,0xb8,0xb2,0x6c,0xf4,0xc7, + 0x30,0x45,0x02,0x21,0x00,0xd7,0xcd,0x76,0xec,0x01,0xc1,0xb1,0x07,0x9e,0xba,0x9e,0x2a,0xa2,0xa3,0x97,0x24,0x3c,0x47,0x58,0xc9,0x8a,0x1b,0xa0,0xb7,0x40,0x4a,0x34,0x0b,0x9b,0x00,0xce,0xd6,0x02,0x20,0x35,0x75,0x00,0x1e,0x19,0xd9,0x22,0xe6,0xde,0x8b,0x3d,0x6c,0x84,0xea,0x43,0xb5,0xc3,0x33,0x81,0x06,0xcf,0x29,0x99,0x01,0x34,0xe7,0x66,0x9a,0x82,0x6f,0x78,0xe6, + 0x30,0x45,0x02,0x21,0x00,0xa8,0x72,0xc7,0x44,0xd9,0x36,0xdb,0x21,0xa1,0x0c,0x36,0x1d,0xd5,0xc9,0x06,0x33,0x55,0xf8,0x49,0x02,0x21,0x96,0x52,0xf6,0xfc,0x56,0xdc,0x95,0xa7,0x13,0x9d,0x96,0x02,0x20,0x40,0x0d,0xf7,0x57,0x5d,0x97,0x56,0x21,0x0e,0x9c,0xcc,0x77,0x16,0x2c,0x6b,0x59,0x3c,0x77,0x46,0xcf,0xb4,0x8a,0xc2,0x63,0xc4,0x27,0x50,0xb4,0x21,0xef,0x4b,0xb9, + 0x30,0x45,0x02,0x21,0x00,0x9f,0xa9,0xaf,0xe0,0x77,0x52,0xda,0x10,0xb3,0x6d,0x3a,0xfc,0xd0,0xfe,0x44,0xbf,0xc4,0x02,0x44,0xd7,0x52,0x03,0x59,0x9c,0xf8,0xf5,0x04,0x7f,0xa3,0x45,0x38,0x54,0x02,0x20,0x50,0xe0,0xa7,0xc0,0x13,0xbf,0xbf,0x51,0x81,0x97,0x36,0x97,0x2d,0x44,0xb4,0xb5,0x6b,0xc2,0xa2,0xb2,0xc1,0x80,0xdf,0x6e,0xc6,0x72,0xdf,0x17,0x14,0x10,0xd7,0x7a, + 0x30,0x45,0x02,0x21,0x00,0x88,0x56,0x40,0x38,0x4d,0x0d,0x91,0x0e,0xfb,0x17,0x7b,0x46,0xbe,0x6c,0x3d,0xc5,0xca,0xc8,0x1f,0x0b,0x88,0xc3,0x19,0x0b,0xb6,0xb5,0xf9,0x9c,0x26,0x41,0xf2,0x05,0x02,0x20,0x73,0x8e,0xd9,0xbf,0xf1,0x16,0x30,0x6d,0x9c,0xaa,0x0f,0x8f,0xc6,0x08,0xbe,0x24,0x3e,0x0b,0x56,0x77,0x79,0xd8,0xda,0xb0,0x3e,0x8e,0x19,0xd5,0x53,0xf1,0xdc,0x8e, + 0x30,0x44,0x02,0x20,0x2d,0x05,0x1f,0x91,0xc5,0xa9,0xd4,0x40,0xc5,0x67,0x69,0x85,0x71,0x04,0x83,0xbc,0x4f,0x1a,0x6c,0x61,0x1b,0x10,0xc9,0x5a,0x2f,0xf0,0x36,0x3d,0x90,0xc2,0xa4,0x58,0x02,0x20,0x6d,0xdf,0x94,0xe6,0xfb,0xa5,0xbe,0x58,0x68,0x33,0xd0,0xc5,0x3c,0xf2,0x16,0xad,0x39,0x48,0xf3,0x79,0x53,0xc2,0x6c,0x1c,0xf4,0x96,0x8e,0x9a,0x9e,0x82,0x43,0xdc, + 0x30,0x45,0x02,0x21,0x00,0xf3,0xac,0x25,0x23,0x96,0x74,0x82,0xf5,0x3d,0x50,0x85,0x22,0x71,0x2d,0x58,0x3f,0x43,0x79,0xcd,0x82,0x41,0x01,0xff,0x63,0x5e,0xa0,0x93,0x51,0x17,0xba,0xa5,0x4f,0x02,0x20,0x27,0xf1,0x08,0x12,0x22,0x73,0x97,0xe0,0x2c,0xea,0x96,0xfb,0x0e,0x68,0x07,0x61,0x63,0x6d,0xab,0x2b,0x08,0x0d,0x1f,0xc5,0xd1,0x16,0x85,0xcb,0xe8,0x50,0x0c,0xfe, + 0x30,0x45,0x02,0x21,0x00,0x96,0x44,0x7c,0xf6,0x8c,0x3a,0xb7,0x26,0x6e,0xd7,0x44,0x7d,0xe3,0xac,0x52,0xfe,0xd7,0xcc,0x08,0xcb,0xdf,0xea,0x39,0x1c,0x18,0xa9,0xb8,0xab,0x37,0x0b,0xc9,0x13,0x02,0x20,0x0f,0x5e,0x78,0x74,0xd3,0xac,0x0e,0x91,0x8f,0x01,0xc8,0x85,0xa1,0x63,0x91,0x77,0xc9,0x23,0xf8,0x66,0x0d,0x1c,0xeb,0xa1,0xca,0x1f,0x30,0x1b,0xc6,0x75,0xcd,0xbc, + 0x30,0x44,0x02,0x20,0x53,0x0a,0x08,0x32,0xb6,0x91,0xda,0x0b,0x56,0x19,0xa0,0xb1,0x1d,0xe6,0x87,0x7f,0x3c,0x09,0x71,0xba,0xaa,0x68,0xed,0x12,0x27,0x58,0xc2,0x9c,0xaa,0xf4,0x6b,0x72,0x02,0x20,0x6c,0x89,0xe4,0x4f,0x5e,0xb3,0x30,0x60,0xea,0x4b,0x46,0x31,0x8c,0x39,0x13,0x8e,0xae,0xde,0xc7,0x2d,0xe4,0x2b,0xa5,0x76,0x57,0x9a,0x6a,0x46,0x90,0xe3,0x39,0xf3, + 0x30,0x45,0x02,0x21,0x00,0x9c,0x54,0xc2,0x55,0x00,0xbd,0xe0,0xb9,0x2d,0x72,0xd6,0xec,0x48,0x3d,0xc2,0x48,0x2f,0x36,0x54,0x29,0x4c,0xa7,0x4d,0xe7,0x96,0xb6,0x81,0x25,0x5e,0xd5,0x8a,0x77,0x02,0x20,0x67,0x74,0x53,0xc6,0xb5,0x6f,0x52,0x76,0x31,0xc9,0xf6,0x7b,0x3f,0x3e,0xb6,0x21,0xfd,0x88,0x58,0x2b,0x4a,0xff,0x15,0x6d,0x2f,0x15,0x67,0xd6,0x21,0x1a,0x2a,0x33, + 0x30,0x45,0x02,0x21,0x00,0xe7,0x90,0x9d,0x41,0x43,0x9e,0x2f,0x6a,0xf2,0x91,0x36,0xc7,0x34,0x8c,0xa2,0x64,0x1a,0x2b,0x07,0x0d,0x5b,0x64,0xf9,0x1e,0xa9,0xda,0x70,0x70,0xc7,0xa2,0x61,0x8b,0x02,0x20,0x42,0xd7,0x82,0xf1,0x32,0xfa,0x1d,0x36,0xc2,0xc8,0x8b,0xa2,0x7c,0x3d,0x67,0x8d,0x80,0x18,0x4a,0x5d,0x1e,0xcc,0xac,0x75,0x01,0xf0,0xb4,0x7e,0x3d,0x20,0x50,0x08, + 0x30,0x44,0x02,0x20,0x59,0x24,0x87,0x32,0x09,0x59,0x31,0x35,0xa4,0xc3,0xda,0x7b,0xb3,0x81,0x22,0x7f,0x8a,0x4b,0x6a,0xa9,0xf3,0x4f,0xe5,0xbb,0x7f,0x8f,0xbc,0x13,0x1a,0x03,0x9f,0xfe,0x02,0x20,0x1f,0x1b,0xb1,0x1b,0x44,0x1c,0x8f,0xea,0xa4,0x0f,0x44,0x21,0x3d,0x9a,0x40,0x5e,0xd7,0x92,0xd5,0x9f,0xb4,0x9d,0x5b,0xcd,0xd9,0xa4,0x28,0x5a,0xe5,0x69,0x30,0x22, + 0x30,0x45,0x02,0x21,0x00,0xee,0xb6,0x92,0xc9,0xb2,0x62,0x96,0x9b,0x23,0x1c,0x38,0xb5,0xa7,0xf6,0x06,0x49,0xe0,0xc8,0x75,0xcd,0x64,0xdf,0x88,0xf3,0x3a,0xa5,0x71,0xfa,0x3d,0x29,0xab,0x0e,0x02,0x20,0x21,0x8b,0x3a,0x1e,0xb0,0x63,0x79,0xc2,0xc1,0x8c,0xf5,0x1b,0x06,0x43,0x07,0x86,0xd1,0xc6,0x4c,0xd2,0xd2,0x4c,0x9b,0x23,0x2b,0x23,0xe5,0xba,0xc7,0x98,0x9a,0xcd, + 0x30,0x45,0x02,0x21,0x00,0xa4,0x00,0x34,0x17,0x7f,0x36,0x09,0x1c,0x2b,0x65,0x36,0x84,0xa0,0xe3,0xeb,0x5d,0x4b,0xff,0x18,0xe4,0xd0,0x9f,0x66,0x4c,0x28,0x00,0xe7,0xca,0xfd,0xa1,0xda,0xf8,0x02,0x20,0x3a,0x3e,0xc2,0x98,0x53,0x70,0x4e,0x52,0x03,0x1c,0x58,0x92,0x7a,0x80,0x0a,0x96,0x83,0x53,0xad,0xc3,0xd9,0x73,0xbe,0xba,0x91,0x72,0xcb,0xbe,0xab,0x4d,0xd1,0x49, + 0x30,0x45,0x02,0x21,0x00,0xb5,0xd7,0x95,0xcc,0x75,0xce,0xa5,0xc4,0x34,0xfa,0x41,0x85,0x18,0x0c,0xd6,0xbd,0x21,0x22,0x3f,0x3d,0x5a,0x86,0xda,0x66,0x70,0xd7,0x1d,0x95,0x68,0x0d,0xad,0xbf,0x02,0x20,0x54,0xe4,0xd8,0x81,0x0a,0x00,0x1e,0xcb,0xb9,0xf7,0xca,0x1c,0x2e,0xbf,0xdb,0x9d,0x00,0x9e,0x90,0x31,0xa4,0x31,0xac,0xa3,0xc2,0x0a,0xb4,0xe0,0xd1,0x37,0x4e,0xc1, + 0x30,0x44,0x02,0x20,0x07,0xdc,0x24,0x78,0xd4,0x3c,0x12,0x32,0xa4,0x59,0x56,0x08,0xc6,0x44,0x26,0xc3,0x55,0x10,0x05,0x1a,0x63,0x1a,0xe6,0xa5,0xa6,0xeb,0x11,0x61,0xe5,0x7e,0x42,0xe1,0x02,0x20,0x4a,0x59,0xea,0x0f,0xdb,0x72,0xd1,0x21,0x65,0xce,0xa3,0xbf,0x1c,0xa8,0x6b,0xa9,0x75,0x17,0xbd,0x18,0x8d,0xb3,0xdb,0xd2,0x1a,0x5a,0x15,0x78,0x50,0x02,0x19,0x84, + 0x30,0x45,0x02,0x21,0x00,0xdd,0xd2,0x0c,0x4a,0x05,0x59,0x6c,0xa8,0x68,0xb5,0x58,0x83,0x9f,0xce,0x9f,0x65,0x11,0xdd,0xd8,0x3d,0x1c,0xcb,0x53,0xf8,0x2e,0x52,0x69,0xd5,0x59,0xa0,0x15,0x52,0x02,0x20,0x5b,0x91,0x73,0x47,0x29,0xd9,0x30,0x93,0xff,0x22,0x12,0x3c,0x4a,0x25,0x81,0x9d,0x7f,0xeb,0x66,0xa2,0x50,0x66,0x3f,0xc7,0x80,0xcb,0x66,0xfc,0x7b,0x6e,0x6d,0x17, + 0x30,0x45,0x02,0x21,0x00,0x9c,0xde,0x6e,0x0e,0xde,0x0a,0x00,0x3f,0x02,0xfd,0xa0,0xa0,0x1b,0x59,0xfa,0xcf,0xe5,0xde,0xc0,0x63,0x31,0x8f,0x27,0x9c,0xe2,0xde,0x7a,0x9b,0x10,0x62,0xf7,0xb7,0x02,0x20,0x28,0x86,0xa5,0xb8,0xc6,0x79,0xbd,0xf8,0x22,0x4c,0x66,0xf9,0x08,0xfd,0x62,0x05,0x49,0x2c,0xb7,0x0b,0x00,0x68,0xd4,0x6a,0xe4,0xf3,0x3a,0x41,0x49,0xb1,0x2a,0x52, + 0x30,0x45,0x02,0x21,0x00,0xc5,0x77,0x10,0x16,0xd0,0xdd,0x63,0x57,0x14,0x3c,0x89,0xf6,0x84,0xcd,0x74,0x04,0x23,0x50,0x25,0x54,0xc0,0xc5,0x9a,0xa8,0xc9,0x95,0x84,0xf1,0xff,0x38,0xf6,0x09,0x02,0x20,0x54,0xb4,0x05,0xf4,0x47,0x75,0x46,0x68,0x6e,0x46,0x4c,0x54,0x63,0xb4,0xfd,0x41,0x90,0x57,0x2e,0x58,0xd0,0xf7,0xe7,0x35,0x7f,0x6e,0x61,0x94,0x7d,0x20,0x71,0x5c, + 0x30,0x45,0x02,0x21,0x00,0xa2,0x4e,0xbc,0x0e,0xc2,0x24,0xbd,0x67,0xae,0x39,0x7c,0xbe,0x6f,0xa3,0x7b,0x31,0x25,0xad,0xbd,0x34,0x89,0x1a,0xbe,0x2d,0x7c,0x73,0x56,0x92,0x19,0x16,0xdf,0xe6,0x02,0x20,0x34,0xf6,0xeb,0x63,0x74,0x73,0x1b,0xbb,0xaf,0xc4,0x92,0x4f,0xb8,0xb0,0xbd,0xcd,0xda,0x49,0x45,0x6d,0x72,0x4c,0xda,0xe6,0x17,0x8d,0x87,0x01,0x4c,0xb5,0x3d,0x8c, + 0x30,0x44,0x02,0x20,0x25,0x57,0xd6,0x4a,0x7a,0xee,0x2e,0x09,0x31,0xc0,0x12,0xe4,0xfe,0xa1,0xcd,0x3a,0x2c,0x33,0x4e,0xda,0xe6,0x8c,0xde,0xb7,0x15,0x8c,0xaf,0x21,0xb6,0x8e,0x5a,0x24,0x02,0x20,0x7f,0x06,0xcd,0xbb,0x6a,0x90,0x02,0x3a,0x97,0x38,0x82,0xed,0x97,0xb0,0x80,0xfe,0x6b,0x05,0xaf,0x3e,0xc9,0x3d,0xb6,0xf1,0xa4,0x39,0x9a,0x69,0xed,0xf7,0x67,0x0d, + 0x30,0x45,0x02,0x21,0x00,0xc4,0xf2,0xec,0xcb,0xb6,0xa2,0x43,0x50,0xc8,0x46,0x64,0x50,0xb9,0xd6,0x1b,0x20,0x7e,0xe3,0x59,0xe0,0x37,0xb3,0xdc,0xed,0xb4,0x2a,0x3f,0x2e,0x6d,0xd6,0xae,0xb5,0x02,0x20,0x32,0x63,0xc6,0xb5,0x9a,0x2f,0x55,0xcd,0xd1,0xc6,0xe1,0x48,0x94,0xd5,0xe5,0x96,0x3b,0x28,0xbc,0x3e,0x24,0x69,0xac,0x9b,0xa1,0x19,0x79,0x91,0xca,0x7f,0xf9,0xc7, + 0x30,0x45,0x02,0x21,0x00,0xef,0xf0,0x47,0x81,0xc9,0xcb,0xcd,0x16,0x2d,0x0a,0x25,0xa6,0xe2,0xeb,0xcc,0xa4,0x35,0x06,0xc5,0x23,0x38,0x5c,0xb5,0x15,0xd4,0x9e,0xa3,0x8a,0x1b,0x12,0xfc,0xad,0x02,0x20,0x15,0xac,0xd7,0x31,0x94,0xc9,0x1a,0x95,0x47,0x85,0x34,0xf2,0x30,0x15,0xb6,0x72,0xeb,0xed,0x21,0x3e,0x45,0x42,0x4d,0xd2,0xc8,0xe2,0x6a,0xc8,0xb3,0xeb,0x34,0xa5, + 0x30,0x45,0x02,0x21,0x00,0xf5,0x8b,0x4e,0x31,0x10,0xa6,0x4b,0xf1,0xb5,0xdb,0x97,0x63,0x9e,0xe0,0xe5,0xa9,0xc8,0xdf,0xa4,0x9d,0xc5,0x9b,0x67,0x98,0x91,0xf5,0x20,0xfd,0xf0,0x58,0x4c,0x87,0x02,0x20,0x2c,0xd8,0xfe,0x51,0x88,0x8a,0xee,0x9d,0xb3,0xe0,0x75,0x44,0x0f,0xd4,0xdb,0x73,0xb5,0xc7,0x32,0xfb,0x87,0xb5,0x10,0xe9,0x70,0x93,0xd6,0x64,0x15,0xf6,0x2a,0xf7, + 0x30,0x45,0x02,0x21,0x00,0xf8,0xab,0xec,0xaa,0x4f,0x0c,0x50,0x2d,0xe4,0xbf,0x59,0x03,0xd4,0x84,0x17,0xf7,0x86,0xbf,0x92,0xe8,0xad,0x72,0xfe,0xc0,0xbd,0x7f,0xcb,0x78,0x00,0xc0,0xbb,0xe3,0x02,0x20,0x4c,0x7f,0x9e,0x23,0x10,0x76,0xa3,0x0b,0x7a,0xe3,0x6b,0x0c,0xeb,0xe6,0x9c,0xce,0xf1,0xcd,0x19,0x4f,0x7c,0xce,0x93,0xa5,0x58,0x8f,0xd6,0x81,0x4f,0x43,0x7c,0x0e, + 0x30,0x44,0x02,0x20,0x5d,0x5b,0x38,0xbd,0x37,0xad,0x49,0x8b,0x22,0x27,0xa6,0x33,0x26,0x8a,0x8c,0xca,0x87,0x9a,0x5c,0x7c,0x94,0xa4,0xe4,0x16,0xbd,0x0a,0x61,0x4d,0x09,0xe6,0x06,0xd2,0x02,0x20,0x12,0xb8,0xd6,0x64,0xea,0x99,0x91,0x06,0x2e,0xcb,0xb8,0x34,0xe5,0x84,0x00,0xe2,0x5c,0x46,0x00,0x7a,0xf8,0x4f,0x60,0x07,0xd7,0xf1,0x68,0x54,0x43,0x26,0x9a,0xfe, + 0x30,0x44,0x02,0x20,0x0c,0x1c,0xd9,0xfe,0x40,0x34,0xf0,0x86,0xa2,0xb5,0x2d,0x65,0xb9,0xd3,0x83,0x4d,0x72,0xae,0xbe,0x7f,0x33,0xdf,0xe8,0xf9,0x76,0xda,0x82,0x64,0x81,0x77,0xd8,0xe3,0x02,0x20,0x13,0x10,0x57,0x82,0xe3,0xd0,0xcf,0xe8,0x5c,0x27,0x78,0xde,0xc1,0xa8,0x48,0xb2,0x7a,0xc0,0xae,0x07,0x1a,0xa6,0xda,0x34,0x1a,0x95,0x53,0xa9,0x46,0xb4,0x1e,0x59, + 0x30,0x45,0x02,0x21,0x00,0xae,0x79,0x35,0xfb,0x96,0xff,0x24,0x6b,0x7b,0x5d,0x56,0x62,0x87,0x0d,0x1b,0xa5,0x87,0xb0,0x3d,0x6e,0x13,0x60,0xba,0xf4,0x79,0x88,0xb5,0xc0,0x2c,0xcc,0x1a,0x5b,0x02,0x20,0x5f,0x00,0xc3,0x23,0x27,0x20,0x83,0x78,0x2d,0x4a,0x59,0xf2,0xdf,0xd6,0x5e,0x49,0xde,0x06,0x93,0x62,0x70,0x16,0x90,0x0e,0xf7,0xe6,0x14,0x28,0x05,0x66,0x64,0xb3, + 0x30,0x44,0x02,0x20,0x00,0xa1,0x34,0xb5,0xc6,0xcc,0xbc,0xef,0xd4,0xc8,0x82,0xb9,0x45,0xba,0xeb,0x49,0x33,0x44,0x41,0x72,0x79,0x5f,0xa6,0x79,0x6a,0xae,0x14,0x90,0x67,0x54,0x70,0x98,0x02,0x20,0x56,0x6e,0x46,0x10,0x5d,0x24,0xd8,0x90,0x15,0x1e,0x3e,0xea,0x3e,0xbf,0x88,0xf5,0xb9,0x2b,0x3f,0x5e,0xc9,0x3a,0x21,0x77,0x65,0xa6,0xdc,0xbd,0x94,0xf2,0xc5,0x5b, + 0x30,0x44,0x02,0x20,0x2e,0x47,0x21,0x36,0x3a,0xd3,0x99,0x2c,0x13,0x9e,0x5a,0x1c,0x26,0x39,0x5d,0x2c,0x2d,0x77,0x78,0x24,0xaa,0x24,0xfd,0xe0,0x75,0xe0,0xd7,0x38,0x11,0x71,0x30,0x9d,0x02,0x20,0x74,0x0f,0x7c,0x49,0x44,0x18,0xe1,0x30,0x0d,0xd4,0x51,0x2f,0x78,0x2a,0x58,0x80,0x0b,0xff,0x6a,0x7a,0xbd,0xfd,0xd2,0x0f,0xbb,0xd4,0xf0,0x55,0x15,0xca,0x1a,0x4f, + 0x30,0x44,0x02,0x20,0x68,0x52,0xe9,0xd3,0xcd,0x9f,0xe3,0x73,0xc2,0xd5,0x04,0x87,0x79,0x67,0xd3,0x65,0xab,0x14,0x56,0x70,0x7b,0x68,0x17,0xa0,0x42,0x86,0x46,0x94,0xe1,0x96,0x0c,0xcf,0x02,0x20,0x06,0x4b,0x27,0xea,0x14,0x2b,0x30,0x88,0x7b,0x84,0xc8,0x6a,0xdc,0xcb,0x2f,0xa3,0x9a,0x69,0x11,0xad,0x21,0xfc,0x7e,0x81,0x9f,0x59,0x3b,0xe5,0x2b,0xc4,0xf3,0xbd, + 0x30,0x44,0x02,0x20,0x18,0x8a,0x8c,0x56,0x48,0xdc,0x79,0xea,0xce,0x15,0x8c,0xf8,0x86,0xc6,0x2b,0x54,0x68,0xf0,0x5f,0xd9,0x5f,0x03,0xa7,0x63,0x5c,0x5b,0x4c,0x31,0xf0,0x9a,0xf4,0xc5,0x02,0x20,0x36,0x36,0x1a,0x0b,0x57,0x1a,0x00,0xc6,0xcd,0x5e,0x68,0x6c,0xcb,0xfc,0xfa,0x70,0x3c,0x4f,0x97,0xe4,0x89,0x38,0x34,0x6d,0x0c,0x10,0x3f,0xdc,0x76,0xdc,0x58,0x67, + 0x30,0x45,0x02,0x21,0x00,0xa7,0x4f,0x1f,0xb9,0xa8,0x26,0x3f,0x62,0xfc,0x44,0x16,0xa5,0xb7,0xd5,0x84,0xf4,0x20,0x6f,0x39,0x96,0xbb,0x91,0xf6,0xfc,0x8e,0x73,0xb9,0xe9,0x2b,0xad,0x0e,0x13,0x02,0x20,0x68,0x15,0x03,0x2e,0x8c,0x7d,0x76,0xc3,0xab,0x06,0xa8,0x6f,0x33,0x24,0x9c,0xe9,0x94,0x01,0x48,0xcb,0x36,0xd1,0xf4,0x17,0xc2,0xe9,0x92,0xe8,0x01,0xaf,0xa3,0xfa, + 0x30,0x44,0x02,0x20,0x07,0x24,0x48,0x65,0xb7,0x2f,0xf3,0x7e,0x62,0xe3,0x14,0x6f,0x0d,0xc1,0x46,0x82,0xba,0xdd,0x71,0x97,0x79,0x91,0x35,0xf0,0xb0,0x0a,0xde,0x76,0x71,0x74,0x2b,0xfe,0x02,0x20,0x0d,0x80,0xc2,0x23,0x8e,0xdb,0x4e,0x4a,0x7a,0x86,0xa8,0xc5,0x7c,0xa9,0xaf,0x17,0x11,0xf4,0x06,0xf7,0xf5,0xda,0x02,0x99,0xaa,0x04,0xe2,0x93,0x2d,0x96,0x07,0x54, + 0x30,0x45,0x02,0x21,0x00,0xda,0x7f,0xdd,0x05,0xb5,0xba,0xda,0xbd,0x61,0x9d,0x80,0x5c,0x4e,0xe7,0xd9,0xa8,0x4f,0x84,0xdd,0xd5,0xcf,0x9c,0x5b,0xf4,0xd4,0x33,0x81,0x40,0xd6,0x89,0xef,0x08,0x02,0x20,0x28,0xf1,0xcf,0x4f,0xa1,0xc3,0xc5,0x86,0x2c,0xfa,0x14,0x9c,0x00,0x13,0xcf,0x5f,0xe6,0xcf,0x50,0x76,0xca,0xe0,0x00,0x51,0x10,0x63,0xe7,0xde,0x25,0xbb,0x38,0xe5, + 0x30,0x45,0x02,0x21,0x00,0xd3,0x02,0x7c,0x65,0x6f,0x6d,0x4f,0xdf,0xd8,0xed,0xe2,0x20,0x93,0xe3,0xc3,0x03,0xb0,0x13,0x3c,0x34,0x0d,0x61,0x5e,0x77,0x56,0xf6,0x25,0x3a,0xea,0x92,0x72,0x38,0x02,0x20,0x09,0xae,0xf0,0x60,0xc8,0xe4,0xce,0xf9,0x72,0x97,0x40,0x11,0x55,0x8d,0xf1,0x44,0xfe,0xd2,0x5c,0xa6,0x9a,0xe8,0xd0,0xb2,0xea,0xf1,0xa8,0xfe,0xef,0xbe,0xc4,0x17, + 0x30,0x44,0x02,0x20,0x0b,0xf6,0xc0,0x18,0x8d,0xc9,0x57,0x1c,0xd0,0xe2,0x1e,0xec,0xac,0x5f,0xbb,0x19,0xd2,0x43,0x49,0x88,0xe9,0xcc,0x10,0x24,0x45,0x93,0xef,0x3a,0x98,0x09,0x9f,0x69,0x02,0x20,0x48,0x64,0xa5,0x62,0x66,0x1f,0x92,0x21,0xec,0x88,0xe3,0xdd,0x0b,0xc2,0xf6,0xe2,0x7a,0xc1,0x28,0xc3,0x0c,0xc1,0xa8,0x0f,0x79,0xec,0x67,0x0a,0x22,0xb0,0x42,0xee, + 0x30,0x45,0x02,0x21,0x00,0xae,0x45,0x96,0x40,0xd5,0xd1,0x17,0x9b,0xe4,0x7a,0x47,0xfa,0x53,0x8e,0x16,0xd9,0x4d,0xde,0xa5,0x58,0x5e,0x7a,0x24,0x48,0x04,0xa5,0x17,0x42,0xc6,0x86,0x44,0x3a,0x02,0x20,0x6c,0x8e,0x30,0xe5,0x30,0xa6,0x34,0xfa,0xe8,0x0b,0x3c,0xeb,0x06,0x29,0x78,0xb3,0x9e,0xdb,0xe1,0x97,0x77,0xe0,0xa2,0x45,0x53,0xb6,0x88,0x86,0x18,0x1f,0xd8,0x97, + 0x30,0x44,0x02,0x20,0x1c,0xf3,0x51,0x7b,0xa3,0xbf,0x2a,0xb8,0xb9,0xea,0xd4,0xeb,0xb6,0xe8,0x66,0xcb,0x88,0xa1,0xde,0xac,0xb6,0xa7,0x85,0xd3,0xb6,0x3b,0x48,0x3c,0xa0,0x2a,0xc4,0x95,0x02,0x20,0x24,0x9a,0x79,0x8b,0x73,0x60,0x6f,0x55,0xf5,0xf1,0xc7,0x0d,0xe6,0x7c,0xb1,0xa0,0xcf,0xf9,0x5d,0x7d,0xc5,0x0b,0x3a,0x61,0x7d,0xf8,0x61,0xba,0xd3,0xc6,0xb1,0xc9, + 0x30,0x45,0x02,0x21,0x00,0xe6,0x9b,0x52,0x38,0x26,0x5e,0xa3,0x5d,0x77,0xe4,0xdd,0x17,0x22,0x88,0xd8,0xce,0xa1,0x98,0x10,0xa1,0x02,0x92,0x61,0x7d,0x59,0x76,0x51,0x9d,0xc5,0x75,0x7c,0xb8,0x02,0x20,0x4b,0x03,0xc5,0xbc,0x47,0xe8,0x26,0xbd,0xb2,0x73,0x28,0xab,0xd3,0x8d,0x30,0x56,0xd7,0x74,0x76,0xb2,0x13,0x0f,0x3d,0xf6,0xec,0x48,0x91,0xaf,0x08,0xba,0x1e,0x29, + 0x30,0x44,0x02,0x20,0x5f,0x9d,0x7d,0x7c,0x87,0x0d,0x08,0x5f,0xc1,0xd4,0x9f,0xff,0x69,0xe4,0xa2,0x75,0x81,0x28,0x00,0xd2,0xcf,0x89,0x73,0xe7,0x32,0x58,0x66,0xcb,0x40,0xfa,0x2b,0x6f,0x02,0x20,0x6d,0x1f,0x54,0x91,0xd9,0xf7,0x17,0xa5,0x97,0xa1,0x5f,0xd5,0x40,0x40,0x64,0x86,0xd7,0x6a,0x44,0x69,0x7b,0x3f,0x0d,0x9d,0x6d,0xce,0xf6,0x66,0x9f,0x8a,0x0a,0x56, + 0x30,0x44,0x02,0x20,0x0a,0x7d,0x5b,0x19,0x59,0xf7,0x1d,0xf9,0xf8,0x17,0x14,0x6e,0xe4,0x9b,0xd5,0xc8,0x9b,0x43,0x1e,0x79,0x93,0xe2,0xfd,0xec,0xab,0x68,0x58,0x95,0x7d,0xa6,0x85,0xae,0x02,0x20,0x0f,0x8a,0xad,0x2d,0x25,0x46,0x90,0xbd,0xc1,0x3f,0x34,0xa4,0xfe,0xc4,0x4a,0x02,0xfd,0x74,0x5a,0x42,0x2d,0xf0,0x5c,0xcb,0xb5,0x46,0x35,0xa8,0xb8,0x6b,0x96,0x09, + 0x30,0x44,0x02,0x20,0x79,0xe8,0x8b,0xf5,0x76,0xb7,0x4b,0xc0,0x7c,0xa1,0x42,0x39,0x5f,0xda,0x28,0xf0,0x3d,0x3d,0x5e,0x64,0x0b,0x0b,0x4f,0xf0,0x75,0x2c,0x6d,0x94,0xcd,0x55,0x34,0x08,0x02,0x20,0x32,0xce,0xa0,0x5b,0xd2,0xd7,0x06,0xc8,0xf6,0x03,0x6a,0x50,0x7e,0x2a,0xb7,0x76,0x60,0x04,0xf0,0x90,0x4e,0x2e,0x5c,0x58,0x62,0x74,0x9c,0x00,0x73,0x24,0x5d,0x6a, + 0x30,0x45,0x02,0x21,0x00,0x9d,0x54,0xe0,0x37,0xa0,0x02,0x12,0xb3,0x77,0xbc,0x88,0x74,0x79,0x8b,0x8d,0xa0,0x80,0x56,0x4b,0xbd,0xf7,0xe0,0x75,0x91,0xb8,0x61,0x28,0x58,0x09,0xd0,0x14,0x88,0x02,0x20,0x18,0xb4,0xe5,0x57,0x66,0x7a,0x82,0xbd,0x95,0x96,0x5f,0x07,0x06,0xf8,0x1a,0x29,0x24,0x3f,0xbd,0xd8,0x69,0x68,0xa7,0xeb,0xeb,0x43,0x06,0x9d,0xb3,0xb1,0x8c,0x7f, + 0x30,0x44,0x02,0x20,0x26,0x64,0xf1,0xff,0xa9,0x82,0xfe,0xdb,0xcc,0x7c,0xab,0x1b,0x8b,0xc6,0xe2,0xcb,0x42,0x02,0x18,0xd2,0xa6,0x07,0x7a,0xd0,0x8e,0x59,0x1b,0xa9,0xfe,0xab,0x33,0xbd,0x02,0x20,0x49,0xf5,0xc7,0xcb,0x51,0x5e,0x83,0x87,0x2a,0x3d,0x41,0xb4,0xcd,0xb8,0x5f,0x24,0x2a,0xd9,0xd6,0x1a,0x5b,0xfc,0x01,0xde,0xbf,0xbb,0x52,0xc6,0xc8,0x4b,0xa7,0x28, + 0x30,0x44,0x02,0x20,0x58,0x27,0x51,0x83,0x44,0x84,0x4f,0xd6,0xa7,0xde,0x73,0xcb,0xb0,0xa6,0xbe,0xfd,0xea,0x7b,0x13,0xd2,0xde,0xe4,0x47,0x53,0x17,0xf0,0xf1,0x8f,0xfc,0x81,0x52,0x4b,0x02,0x20,0x4f,0x5c,0xcb,0x4e,0x0b,0x48,0x8b,0x5a,0x5d,0x76,0x0a,0xac,0xdd,0xb2,0xd7,0x91,0x97,0x0f,0xe4,0x3d,0xa6,0x1e,0xb3,0x0e,0x2e,0x90,0x20,0x8a,0x81,0x7e,0x46,0xdb, + 0x30,0x45,0x02,0x21,0x00,0x97,0xab,0x19,0xbd,0x13,0x9c,0xac,0x31,0x93,0x25,0x86,0x92,0x18,0xb1,0xbc,0xe1,0x11,0x87,0x5d,0x63,0xfb,0x12,0x09,0x8a,0x04,0xb0,0xcd,0x59,0xb6,0xfd,0xd3,0xa3,0x02,0x20,0x43,0x1d,0x9c,0xea,0x3a,0x24,0x38,0x47,0x30,0x3c,0xeb,0xda,0x56,0x47,0x64,0x31,0xd0,0x34,0x33,0x9f,0x31,0xd7,0x85,0xee,0x88,0x52,0xdb,0x4f,0x04,0x0d,0x49,0x21, + 0x30,0x44,0x02,0x20,0x52,0xc6,0x83,0x14,0x4e,0x44,0x11,0x9a,0xe2,0x01,0x37,0x49,0xd4,0x96,0x4e,0xf6,0x75,0x09,0x27,0x8f,0x6d,0x38,0xba,0x86,0x9a,0xdc,0xfa,0x69,0x97,0x0e,0x12,0x3d,0x02,0x20,0x34,0x79,0x91,0x01,0x67,0x40,0x8f,0x45,0xbd,0xa4,0x20,0xa6,0x26,0xec,0x9c,0x4e,0xc7,0x11,0xc1,0x27,0x4b,0xe0,0x92,0x19,0x8b,0x41,0x87,0xc0,0x18,0xb5,0x62,0xca, + 0x30,0x16,0x02,0x11,0x01,0x45,0x51,0x23,0x19,0x50,0xb7,0x5f,0xc4,0x40,0x2d,0xa1,0x72,0x2f,0xc9,0xba,0xeb,0x02,0x01,0x03, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2c,0x02,0x01,0x03, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x3f,0x02,0x01,0x03, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x3e,0x9a,0x75,0x82,0x88,0x60,0x89,0xc6,0x2f,0xb8,0x40,0xcf,0x3b,0x83,0x06,0x1c,0xd1,0xcf,0xf3,0xae,0x43,0x41,0x80,0x8b,0xb5,0xbd,0xee,0x61,0x91,0x17,0x41,0x77, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x24,0x23,0x8e,0x70,0xb4,0x31,0xb1,0xa6,0x4e,0xfd,0xf9,0x03,0x26,0x69,0x93,0x9d,0x4b,0x77,0xf2,0x49,0x50,0x3f,0xc6,0x90,0x5f,0xeb,0x75,0x40,0xde,0xa3,0xe6,0xd2, + 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x01, + 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x02, + 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x03, + 0x30,0x06,0x02,0x01,0x02,0x02,0x01,0x01, + 0x30,0x06,0x02,0x01,0x02,0x02,0x01,0x02, + 0x30,0x06,0x02,0x01,0x02,0x02,0x01,0x03, + 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x43,0x02,0x01,0x03, + 0x30,0x08,0x02,0x01,0x02,0x02,0x03,0xed,0x29,0x79, + 0x30,0x26,0x02,0x02,0x01,0x01,0x02,0x20,0x3a,0x74,0xe9,0xd3,0xa7,0x4e,0x9d,0x3a,0x74,0xe9,0xd3,0xa7,0x4e,0x9d,0x3a,0x74,0x9f,0x8a,0xb3,0x73,0x2a,0x0a,0x89,0x60,0x4a,0x09,0xbc,0xe5,0xb2,0x91,0x6d,0xa4, + 0x30,0x2b,0x02,0x07,0x2d,0x9b,0x4d,0x34,0x79,0x52,0xcc,0x02,0x20,0x03,0x43,0xae,0xfc,0x2f,0x25,0xd9,0x8b,0x88,0x2e,0x86,0xeb,0x9e,0x30,0xd5,0x5a,0x6e,0xb5,0x08,0xb5,0x16,0x51,0x0b,0x34,0x02,0x4a,0xe4,0xb6,0x36,0x23,0x30,0xb3, + 0x30,0x31,0x02,0x0d,0x10,0x33,0xe6,0x7e,0x37,0xb3,0x2b,0x44,0x55,0x80,0xbf,0x4e,0xfc,0x02,0x20,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x8f,0xe1,0xca,0xb5,0xee,0xfd,0xb2,0x14,0x06,0x1d,0xce,0x3b,0x22,0x78,0x9f,0x1d,0x6f, + 0x30,0x26,0x02,0x02,0x01,0x01,0x02,0x20,0x78,0x32,0x66,0xe9,0x0f,0x43,0xda,0xfe,0x5c,0xd9,0xb3,0xb0,0xbe,0x86,0xde,0x22,0xf9,0xde,0x83,0x67,0x7d,0x0f,0x50,0x71,0x3a,0x46,0x8e,0xc7,0x2f,0xcf,0x5d,0x57, + 0x30,0x31,0x02,0x0d,0x06,0x25,0x22,0xbb,0xd3,0xec,0xbe,0x7c,0x39,0xe9,0x3e,0x7c,0x26,0x02,0x20,0x78,0x32,0x66,0xe9,0x0f,0x43,0xda,0xfe,0x5c,0xd9,0xb3,0xb0,0xbe,0x86,0xde,0x22,0xf9,0xde,0x83,0x67,0x7d,0x0f,0x50,0x71,0x3a,0x46,0x8e,0xc7,0x2f,0xcf,0x5d,0x57, + 0x30,0x45,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x40,0xc1,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0, + 0x30,0x16,0x02,0x09,0x00,0x9c,0x44,0xfe,0xbf,0x31,0xc3,0x59,0x4d,0x02,0x09,0x00,0x83,0x9e,0xd2,0x82,0x47,0xc2,0xb0,0x6b, + 0x30,0x1e,0x02,0x0d,0x09,0xdf,0x8b,0x68,0x24,0x30,0xbe,0xef,0x6f,0x5f,0xd7,0xc7,0xcf,0x02,0x0d,0x0f,0xd0,0xa6,0x2e,0x13,0x77,0x8f,0x42,0x22,0xa0,0xd6,0x1c,0x8a, + 0x30,0x26,0x02,0x11,0x00,0x8a,0x59,0x8e,0x56,0x3a,0x89,0xf5,0x26,0xc3,0x2e,0xbe,0xc8,0xde,0x26,0x36,0x7a,0x02,0x11,0x00,0x84,0xf6,0x33,0xe2,0x04,0x26,0x30,0xe9,0x9d,0xd0,0xf1,0xe1,0x6f,0x7a,0x04,0xbf, + 0x30,0x2e,0x02,0x15,0x00,0xaa,0x6e,0xeb,0x58,0x23,0xf7,0xfa,0x31,0xb4,0x66,0xbb,0x47,0x37,0x97,0xf0,0xd0,0x31,0x4c,0x0b,0xdf,0x02,0x15,0x00,0xe2,0x97,0x7c,0x47,0x9e,0x6d,0x25,0x70,0x3c,0xeb,0xbc,0x6b,0xd5,0x61,0x93,0x8c,0xc9,0xd1,0xbf,0xb9, + 0x30,0x25,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x01,0x01, + 0x30,0x25,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x01,0x00, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x41,0x9d,0x98,0x1c,0x51,0x5a,0xf8,0xcc,0x82,0x54,0x5a,0xac,0x0c,0x85,0xe9,0xe3,0x08,0xfb,0xb2,0xea,0xb6,0xac,0xd7,0xed,0x49,0x7e,0x0b,0x41,0x45,0xa1,0x8f,0xd9, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x1b,0x21,0x71,0x7a,0xd7,0x1d,0x23,0xbb,0xac,0x60,0xa9,0xad,0x0b,0xaf,0x75,0xb0,0x63,0xc9,0xfd,0xf5,0x2a,0x00,0xeb,0xf9,0x9d,0x02,0x21,0x72,0x91,0x09,0x93,0xc9, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x2f,0x58,0x8f,0x66,0x01,0x8f,0x3d,0xd1,0x4d,0xb3,0xe2,0x8e,0x77,0x99,0x64,0x87,0xe3,0x24,0x86,0xb5,0x21,0xed,0x8e,0x5a,0x20,0xf0,0x65,0x91,0x95,0x17,0x77,0xe9, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x09,0x1a,0x08,0x87,0x0f,0xf4,0xda,0xf9,0x12,0x3b,0x30,0xc2,0x0e,0x8c,0x4f,0xc8,0x50,0x57,0x58,0xdc,0xf4,0x07,0x4f,0xca,0xff,0x21,0x70,0xc9,0xbf,0xcf,0x74,0xf4, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x7c,0x37,0x0d,0xc0,0xce,0x8c,0x59,0xa8,0xb2,0x73,0xcb,0xa4,0x4a,0x7c,0x11,0x91,0xfc,0x31,0x86,0xdc,0x03,0xca,0xb9,0x6b,0x05,0x67,0x31,0x2d,0xf0,0xd0,0xb2,0x50, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x70,0xb5,0x9a,0x7d,0x1e,0xe7,0x7a,0x2f,0x9e,0x04,0x91,0xc2,0xa7,0xcf,0xcd,0x0e,0xd0,0x4d,0xf4,0xa3,0x51,0x92,0xf6,0x13,0x2d,0xcc,0x66,0x8c,0x79,0xa6,0x16,0x0e, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x27,0x36,0xd7,0x6e,0x41,0x22,0x46,0xe0,0x97,0x14,0x8e,0x2b,0xf6,0x29,0x15,0x61,0x4e,0xb7,0xc4,0x28,0x91,0x3a,0x58,0xeb,0x5e,0x9c,0xd4,0x67,0x4a,0x94,0x23,0xde, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x4a,0x1e,0x12,0x83,0x1f,0xbe,0x93,0x62,0x7b,0x02,0xd6,0xe7,0xf2,0x4b,0xcc,0xdd,0x6e,0xf4,0xb2,0xd0,0xf4,0x67,0x39,0xea,0xf3,0xb1,0xea,0xf0,0xca,0x11,0x77,0x70, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x06,0xc7,0x78,0xd4,0xdf,0xff,0x7d,0xee,0x06,0xed,0x88,0xbc,0x4e,0x0e,0xd3,0x4f,0xc5,0x53,0xaa,0xd6,0x7c,0xaf,0x79,0x6f,0x2a,0x1c,0x64,0x87,0xc1,0xb2,0xe8,0x77, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x4d,0xe4,0x59,0xef,0x91,0x59,0xaf,0xa0,0x57,0xfe,0xb3,0xec,0x40,0xfe,0xf0,0x1c,0x45,0xb8,0x09,0xf4,0xab,0x29,0x6e,0xa4,0x8c,0x20,0x6d,0x42,0x49,0xa2,0xb4,0x51, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x74,0x5d,0x29,0x49,0x78,0x00,0x73,0x02,0x03,0x35,0x02,0xe1,0xac,0xc4,0x8b,0x63,0xae,0x65,0x00,0xbe,0x43,0xad,0xbe,0xa1,0xb2,0x58,0xd6,0xb4,0x23,0xdb,0xb4,0x16, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x7b,0x2a,0x78,0x5e,0x38,0x96,0xf5,0x9b,0x2d,0x69,0xda,0x57,0x64,0x8e,0x80,0xad,0x3c,0x13,0x3a,0x75,0x0a,0x28,0x47,0xfd,0x20,0x98,0xcc,0xd9,0x02,0x04,0x2b,0x6c, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x71,0xae,0x94,0xa7,0x2c,0xa8,0x96,0x87,0x5e,0x7a,0xa4,0xa4,0xc3,0xd2,0x9a,0xfd,0xb4,0xb3,0x5b,0x69,0x96,0x27,0x3e,0x63,0xc4,0x7a,0xc5,0x19,0x25,0x6c,0x5e,0xb1, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x0f,0xa5,0x27,0xfa,0x73,0x43,0xc0,0xbc,0x9e,0xc3,0x5a,0x62,0x78,0xbf,0xbf,0xf4,0xd8,0x33,0x01,0xb1,0x54,0xfc,0x4b,0xd1,0x4a,0xee,0x7e,0xb9,0x34,0x45,0xb5,0xf9, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x65,0x39,0xc0,0xad,0xad,0xd0,0x52,0x5f,0xf4,0x26,0x22,0x16,0x4c,0xe9,0x31,0x43,0x48,0xbd,0x08,0x63,0xb4,0xc8,0x0e,0x93,0x6b,0x23,0xca,0x04,0x14,0x26,0x46,0x71, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa1, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,0x02,0x20,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x0a,0x6b,0xdd,0x5e,0x1b,0xba,0x77,0xf5,0x23,0x84,0x21,0x93,0xb3,0xb8,0x2e,0x44,0x8e,0x05,0xd5,0xf1,0x1e, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,0x02,0x20,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x0a,0x6b,0xdd,0x5e,0x1b,0xba,0x77,0xf5,0x23,0x84,0x21,0x93,0xb3,0xb8,0x2e,0x44,0x8e,0x05,0xd5,0xf1,0x1e, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x16,0xe1,0xe4,0x59,0x45,0x76,0x79,0xdf,0x5b,0x94,0x34,0xae,0x23,0xf4,0x74,0xb3,0xe8,0xd2,0xa7,0x0b,0xd6,0xb5,0xdb,0xe6,0x92,0xba,0x16,0xda,0x01,0xf1,0xfb,0x0a, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x1c,0x94,0x0f,0x31,0x3f,0x92,0x64,0x7b,0xe2,0x57,0xec,0xcd,0x7e,0xd0,0x8b,0x0b,0xae,0xf3,0xf0,0x47,0x8f,0x25,0x87,0x1b,0x53,0x63,0x53,0x02,0xc5,0xf6,0x31,0x4a, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x15,0xd9,0x4a,0x85,0x07,0x7b,0x49,0x3f,0x91,0xcb,0x71,0x01,0xec,0x63,0xe1,0xb0,0x1b,0xe5,0x8b,0x59,0x4e,0x85,0x5f,0x45,0x05,0x0a,0x8c,0x14,0x06,0x2d,0x68,0x9b, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x5b,0x1d,0x27,0xa7,0x69,0x4c,0x14,0x62,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9d,0x9e,0xf3,0xb9,0xfb,0x58,0x38,0x54,0x18,0xd9,0xc9,0x82,0x10,0x50,0x77,0xd1,0xb7, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x2d,0x85,0x89,0x6b,0x3e,0xb9,0xdb,0xb5,0xa5,0x2f,0x42,0xf9,0xc9,0x26,0x1e,0xd3,0xfc,0x46,0x64,0x4e,0xc6,0x5f,0x06,0xad,0xe3,0xfd,0x78,0xf2,0x57,0xe4,0x34,0x32, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x5b,0x0b,0x12,0xd6,0x7d,0x73,0xb7,0x6b,0x4a,0x5e,0x85,0xf3,0x92,0x4c,0x3d,0xa7,0xf8,0x8c,0xc8,0x9d,0x8c,0xbe,0x0d,0x5b,0xc7,0xfa,0xf1,0xe4,0xaf,0xc8,0x68,0x64, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x69,0x4c,0x14,0x62,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x09,0xe6,0x0e,0x68,0xb9,0x0d,0x0b,0x5e,0x6c,0x5d,0xdd,0xd0,0xcb,0x69,0x4d,0x87,0x99, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x3d,0x7f,0x48,0x7c,0x07,0xbf,0xc5,0xf3,0x08,0x46,0x93,0x8a,0x3d,0xce,0xf6,0x96,0x44,0x47,0x07,0xcf,0x96,0x77,0x25,0x4a,0x92,0xb0,0x6c,0x63,0xab,0x86,0x7d,0x22, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x6c,0x76,0x48,0xfc,0x0f,0xbf,0x8a,0x06,0xad,0xb8,0xb8,0x39,0xf9,0x7b,0x4f,0xf7,0xa8,0x00,0xf1,0x1b,0x1e,0x37,0xc5,0x93,0xb2,0x61,0x39,0x45,0x99,0x79,0x2b,0xa4, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x64,0x1c,0x9c,0x5d,0x79,0x0d,0xc0,0x9c,0xdd,0x3d,0xfa,0xbb,0x62,0xcd,0xf4,0x53,0xe6,0x97,0x47,0xa7,0xe3,0xd7,0xaa,0x1a,0x71,0x41,0x89,0xef,0x53,0x17,0x1a,0x99, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x29,0x79,0x8c,0x5c,0x45,0xbd,0xf5,0x8b,0x4a,0x7b,0x2f,0xdc,0x2c,0x46,0xab,0x4a,0xf1,0x21,0x8c,0x7e,0xeb,0x9f,0x0f,0x27,0xa8,0x8f,0x12,0x67,0x67,0x4d,0xe3,0xb0, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x0b,0x70,0xf2,0x2c,0xa2,0xbb,0x3c,0xef,0xad,0xca,0x1a,0x57,0x11,0xfa,0x3a,0x59,0xf4,0x69,0x53,0x85,0xeb,0x5a,0xed,0xf3,0x49,0x5d,0x0b,0x6d,0x00,0xf8,0xfd,0x85, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x16,0xe1,0xe4,0x59,0x45,0x76,0x79,0xdf,0x5b,0x94,0x34,0xae,0x23,0xf4,0x74,0xb3,0xe8,0xd2,0xa7,0x0b,0xd6,0xb5,0xdb,0xe6,0x92,0xba,0x16,0xda,0x01,0xf1,0xfb,0x0a, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x22,0x52,0xd6,0x85,0xe8,0x31,0xb6,0xcf,0x09,0x5e,0x4f,0x05,0x35,0xee,0xaf,0x0d,0xdd,0x3b,0xfa,0x91,0xc2,0x10,0xc9,0xd9,0xdc,0x17,0x22,0x47,0x02,0xea,0xf8,0x8f, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x75,0x13,0x5a,0xbd,0x7c,0x42,0x5b,0x60,0x37,0x1a,0x47,0x7f,0x09,0xce,0x0f,0x27,0x4f,0x64,0xa8,0xc6,0xb0,0x61,0xa0,0x7b,0x5d,0x63,0xe9,0x3c,0x65,0x04,0x6c,0x53, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x2a,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x3e,0x3a,0x49,0xa2,0x3a,0x6d,0x8a,0xbe,0x95,0x46,0x1f,0x84,0x45,0x67,0x6b,0x17, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x3e,0x88,0x83,0x77,0xac,0x6c,0x71,0xac,0x9d,0xec,0x3f,0xdb,0x9b,0x56,0xc9,0xfe,0xaf,0x0c,0xfa,0xca,0x9f,0x82,0x7f,0xc5,0xeb,0x65,0xfc,0x3e,0xac,0x81,0x12,0x10, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x30,0xbb,0xb7,0x94,0xdb,0x58,0x83,0x63,0xb4,0x06,0x79,0xf6,0xc1,0x82,0xa5,0x0d,0x3c,0xe9,0x67,0x9a,0xcd,0xd3,0xff,0xbe,0x36,0xd7,0x81,0x3d,0xac,0xbd,0xc8,0x18, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x2c,0x37,0xfd,0x99,0x56,0x22,0xc4,0xfb,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc7,0xce,0xe7,0x45,0x11,0x0c,0xb4,0x5a,0xb5,0x58,0xed,0x7c,0x90,0xc1,0x5a,0x2f, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x7f,0xd9,0x95,0x62,0x2c,0x4f,0xb7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x88,0x3f,0xfa,0xb5,0xb3,0x26,0x52,0xcc,0xdc,0xaa,0x29,0x0f,0xcc,0xb9,0x7d, + 0x30,0x43,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x1f,0x4c,0xd5,0x3b,0xa7,0x60,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9e,0x5c,0xf1,0x43,0xe2,0x53,0x96,0x26,0x19,0x0a,0x3a,0xb0,0x9c,0xce,0x47, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x56,0x22,0xc4,0xfb,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x92,0x8a,0x8f,0x1c,0x7a,0xc7,0xbe,0xc1,0x80,0x8b,0x9f,0x61,0xc0,0x1e,0xc3,0x27, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x44,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x41,0x03,0xb8,0x78,0x53,0xfd,0x3b,0x7d,0x3f,0x8e,0x17,0x51,0x25,0xb4,0x38,0x2f,0x25,0xed, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x27,0x39,0xce,0x73,0x9c,0xe7,0x39,0xce,0x73,0x9c,0xe7,0x39,0xce,0x73,0x9c,0xe7,0x05,0x56,0x02,0x98,0xd1,0xf2,0xf0,0x8d,0xc4,0x19,0xac,0x27,0x3a,0x5b,0x54,0xd9, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x48,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x31,0xc8,0x3a,0xe8,0x2e,0xbe,0x08,0x98,0x77,0x6b,0x4c,0x69,0xd1,0x1f,0x88,0xde, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x64,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x06,0xdd,0x3a,0x19,0xb8,0xd5,0xfb,0x87,0x52,0x35,0x96,0x3c,0x59,0x3b,0xd2,0xd3, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x6a,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x3e,0x3a,0x49,0xa2,0x3a,0x6d,0x8a,0xbe,0x95,0x46,0x1f,0x84,0x45,0x67,0x6b,0x15, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x2a,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x3e,0x3a,0x49,0xa2,0x3a,0x6d,0x8a,0xbe,0x95,0x46,0x1f,0x84,0x45,0x67,0x6b,0x17, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, + 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x18,0x5d,0xdb,0xca,0x6d,0xac,0x41,0xb1,0xda,0x03,0x3c,0xfb,0x60,0xc1,0x52,0x86,0x9e,0x74,0xb3,0xcd,0x66,0xe9,0xff,0xdf,0x1b,0x6b,0xc0,0x9e,0xd6,0x5e,0xe4,0x0c, + 0x30,0x44,0x02,0x20,0x32,0xb0,0xd1,0x0d,0x8d,0x0e,0x04,0xbc,0x8d,0x4d,0x06,0x4d,0x27,0x06,0x99,0xe8,0x7c,0xff,0xc9,0xb4,0x9c,0x5c,0x20,0x73,0x0e,0x1c,0x26,0xf6,0x10,0x5d,0xdc,0xda,0x02,0x20,0x29,0xed,0x3d,0x67,0xb3,0xd5,0x05,0xbe,0x95,0x58,0x0d,0x77,0xd5,0xb7,0x92,0xb4,0x36,0x88,0x11,0x79,0xb2,0xb6,0xb2,0xe0,0x4c,0x5f,0xe5,0x92,0xd3,0x8d,0x82,0xd9, + 0x30,0x44,0x02,0x20,0x32,0xb0,0xd1,0x0d,0x8d,0x0e,0x04,0xbc,0x8d,0x4d,0x06,0x4d,0x27,0x06,0x99,0xe8,0x7c,0xff,0xc9,0xb4,0x9c,0x5c,0x20,0x73,0x0e,0x1c,0x26,0xf6,0x10,0x5d,0xdc,0xda,0x02,0x20,0x29,0xed,0x3d,0x67,0xb3,0xd5,0x05,0xbe,0x95,0x58,0x0d,0x77,0xd5,0xb7,0x92,0xb4,0x36,0x88,0x11,0x79,0xb2,0xb6,0xb2,0xe0,0x4c,0x5f,0xe5,0x92,0xd3,0x8d,0x82,0xd9, + 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0,0x02,0x20,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x32,0xf2,0x22,0xf8,0xfa,0xef,0xdb,0x53,0x3f,0x26,0x5d,0x46,0x1c,0x29,0xa4,0x73,0x73, + 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0, + 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x48,0xc7,0x9f,0xac,0xd4,0x32,0x14,0xc0,0x11,0x12,0x3c,0x1b,0x03,0xa9,0x34,0x12,0xa5, + 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x65,0xe4,0x45,0xf1,0xf5,0xdf,0xb6,0xa6,0x7e,0x4c,0xba,0x8c,0x38,0x53,0x48,0xe6,0xe7, + 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x65,0xe4,0x45,0xf1,0xf5,0xdf,0xb6,0xa6,0x7e,0x4c,0xba,0x8c,0x38,0x53,0x48,0xe6,0xe7, + 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x48,0xc7,0x9f,0xac,0xd4,0x32,0x14,0xc0,0x11,0x12,0x3c,0x1b,0x03,0xa9,0x34,0x12,0xa5, + 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x0e,0xb1,0x0e,0x5a,0xb9,0x5f,0x2f,0x27,0x53,0x48,0xd8,0x2a,0xd2,0xe4,0xd7,0x94,0x9c,0x81,0x93,0x80,0x0d,0x8c,0x9c,0x75,0xdf,0x58,0xe3,0x43,0xf0,0xeb,0xba,0x7b, + 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0, + 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x48,0xc7,0x9f,0xac,0xd4,0x32,0x14,0xc0,0x11,0x12,0x3c,0x1b,0x03,0xa9,0x34,0x12,0xa5, + 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x65,0xe4,0x45,0xf1,0xf5,0xdf,0xb6,0xa6,0x7e,0x4c,0xba,0x8c,0x38,0x53,0x48,0xe6,0xe7, + 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x65,0xe4,0x45,0xf1,0xf5,0xdf,0xb6,0xa6,0x7e,0x4c,0xba,0x8c,0x38,0x53,0x48,0xe6,0xe7, + 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x48,0xc7,0x9f,0xac,0xd4,0x32,0x14,0xc0,0x11,0x12,0x3c,0x1b,0x03,0xa9,0x34,0x12,0xa5, + 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x0e,0xb1,0x0e,0x5a,0xb9,0x5f,0x2f,0x27,0x53,0x48,0xd8,0x2a,0xd2,0xe4,0xd7,0x94,0x9c,0x81,0x93,0x80,0x0d,0x8c,0x9c,0x75,0xdf,0x58,0xe3,0x43,0xf0,0xeb,0xba,0x7b, + 0x30,0x45,0x02,0x21,0x00,0xbb,0x5a,0x52,0xf4,0x2f,0x9c,0x92,0x61,0xed,0x43,0x61,0xf5,0x94,0x22,0xa1,0xe3,0x00,0x36,0xe7,0xc3,0x2b,0x27,0x0c,0x88,0x07,0xa4,0x19,0xfe,0xca,0x60,0x50,0x23,0x02,0x20,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x63,0xcf,0xd6,0x6a,0x19,0x0a,0x60,0x08,0x89,0x1e,0x0d,0x81,0xd4,0x9a,0x09,0x52, + 0x30,0x44,0x02,0x20,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x0a,0x6b,0xdd,0x5e,0x1b,0xba,0x77,0xf5,0x23,0x84,0x21,0x93,0xb3,0xb8,0x2e,0x44,0x8e,0x05,0xd5,0xf1,0x1e,0x02,0x20,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x63,0xcf,0xd6,0x6a,0x19,0x0a,0x60,0x08,0x89,0x1e,0x0d,0x81,0xd4,0x9a,0x09,0x52, + 0x30,0x45,0x02,0x21,0x00,0xbb,0x5a,0x52,0xf4,0x2f,0x9c,0x92,0x61,0xed,0x43,0x61,0xf5,0x94,0x22,0xa1,0xe3,0x00,0x36,0xe7,0xc3,0x2b,0x27,0x0c,0x88,0x07,0xa4,0x19,0xfe,0xca,0x60,0x50,0x23,0x02,0x20,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x63,0xcf,0xd6,0x6a,0x19,0x0a,0x60,0x08,0x89,0x1e,0x0d,0x81,0xd4,0x9a,0x09,0x52, + 0x30,0x44,0x02,0x20,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x0a,0x6b,0xdd,0x5e,0x1b,0xba,0x77,0xf5,0x23,0x84,0x21,0x93,0xb3,0xb8,0x2e,0x44,0x8e,0x05,0xd5,0xf1,0x1e,0x02,0x20,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x63,0xcf,0xd6,0x6a,0x19,0x0a,0x60,0x08,0x89,0x1e,0x0d,0x81,0xd4,0x9a,0x09,0x52, + 0x30,0x45,0x02,0x21,0x00,0xf8,0x0a,0xe4,0xf9,0x6c,0xdb,0xc9,0xd8,0x53,0xf8,0x3d,0x47,0xaa,0xe2,0x25,0xbf,0x40,0x7d,0x51,0xc5,0x6b,0x77,0x76,0xcd,0x67,0xd0,0xdc,0x19,0x5d,0x99,0xa9,0xdc,0x02,0x20,0x4c,0xfc,0x1d,0x94,0x1e,0x08,0xcb,0x9a,0xce,0xad,0xde,0x0f,0x4c,0xce,0xad,0x76,0xb3,0x0d,0x33,0x2f,0xc4,0x42,0x11,0x5d,0x50,0xe6,0x73,0xe2,0x86,0x86,0xb7,0x0b, + 0x30,0x44,0x02,0x20,0x10,0x9c,0xd8,0xae,0x03,0x74,0x35,0x89,0x84,0xa8,0x24,0x9c,0x0a,0x84,0x36,0x28,0xf2,0x83,0x5f,0xfa,0xd1,0xdf,0x1a,0x9a,0x69,0xaa,0x2f,0xe7,0x23,0x55,0x54,0x5c,0x02,0x20,0x53,0x90,0xff,0x25,0x0a,0xc4,0x27,0x4e,0x1c,0xb2,0x5c,0xd6,0xca,0x64,0x91,0xf6,0xb9,0x12,0x81,0xe3,0x2f,0x5b,0x26,0x4d,0x87,0x97,0x7a,0xed,0x4a,0x94,0xe7,0x7b, + 0x30,0x45,0x02,0x21,0x00,0xd0,0x35,0xee,0x1f,0x17,0xfd,0xb0,0xb2,0x68,0x1b,0x16,0x3e,0x33,0xc3,0x59,0x93,0x26,0x59,0x99,0x0a,0xf7,0x7d,0xca,0x63,0x20,0x12,0xb3,0x0b,0x27,0xa0,0x57,0xb3,0x02,0x20,0x19,0x39,0xd9,0xf3,0xb2,0x85,0x8b,0xc1,0x3e,0x34,0x74,0xcb,0x50,0xe6,0xa8,0x2b,0xe4,0x4f,0xaa,0x71,0x94,0x0f,0x87,0x6c,0x1c,0xba,0x4c,0x3e,0x98,0x92,0x02,0xb6, + 0x30,0x44,0x02,0x20,0x4f,0x05,0x3f,0x56,0x3a,0xd3,0x4b,0x74,0xfd,0x8c,0x99,0x34,0xce,0x59,0xe7,0x9c,0x2e,0xb8,0xe6,0xec,0xa0,0xfe,0xf5,0xb3,0x23,0xca,0x67,0xd5,0xac,0x7e,0xd2,0x38,0x02,0x20,0x4d,0x4b,0x05,0xda,0xa0,0x71,0x9e,0x77,0x3d,0x86,0x17,0xdc,0xe5,0x63,0x1c,0x5f,0xd6,0xf5,0x9c,0x9b,0xdc,0x74,0x8e,0x4b,0x55,0xc9,0x70,0x04,0x0a,0xf0,0x1b,0xe5, + 0x30,0x44,0x02,0x20,0x6d,0x6a,0x4f,0x55,0x6c,0xcc,0xe1,0x54,0xe7,0xfb,0x9f,0x19,0xe7,0x6c,0x3d,0xec,0xa1,0x3d,0x59,0xcc,0x2a,0xeb,0x4e,0xca,0xd9,0x68,0xaa,0xb2,0xde,0xd4,0x59,0x65,0x02,0x20,0x53,0xb9,0xfa,0x74,0x80,0x3e,0xde,0x0f,0xc4,0x44,0x1b,0xf6,0x83,0xd5,0x6c,0x56,0x4d,0x3e,0x27,0x4e,0x09,0xcc,0xf4,0x73,0x90,0xba,0xdd,0x14,0x71,0xc0,0x5f,0xb7, + 0x30,0x44,0x02,0x21,0x00,0xaa,0xd5,0x03,0xde,0x9b,0x9f,0xd6,0x6b,0x94,0x8e,0x9a,0xcf,0x59,0x6f,0x0a,0x0e,0x65,0xe7,0x00,0xb2,0x8b,0x26,0xec,0x56,0xe6,0xe4,0x5e,0x84,0x64,0x89,0xb3,0xc4,0x02,0x1f,0x0d,0xdc,0x3a,0x2f,0x89,0xab,0xb8,0x17,0xbb,0x85,0xc0,0x62,0xce,0x02,0xf8,0x23,0xc6,0x3f,0xc2,0x6b,0x26,0x9e,0x0b,0xc9,0xb8,0x4d,0x81,0xa5,0xaa,0x12,0x3d, + 0x30,0x45,0x02,0x21,0x00,0x91,0x82,0xce,0xbd,0x3b,0xb8,0xab,0x57,0x2e,0x16,0x71,0x74,0x39,0x72,0x09,0xef,0x4b,0x1d,0x43,0x9a,0xf3,0xb2,0x00,0xcd,0xf0,0x03,0x62,0x00,0x89,0xe4,0x32,0x25,0x02,0x20,0x54,0x47,0x7c,0x98,0x2e,0xa0,0x19,0xd2,0xe1,0x00,0x04,0x97,0xfc,0x25,0xfc,0xee,0x1b,0xcc,0xae,0x55,0xf2,0xac,0x27,0x53,0x0a,0xe5,0x3b,0x29,0xc4,0xb3,0x56,0xa4, + 0x30,0x44,0x02,0x20,0x38,0x54,0xa3,0x99,0x8a,0xeb,0xdf,0x2d,0xbc,0x28,0xad,0xac,0x41,0x81,0x46,0x2c,0xca,0xc7,0x87,0x39,0x07,0xab,0x7f,0x21,0x2c,0x42,0xdb,0x0e,0x69,0xb5,0x6e,0xd8,0x02,0x20,0x3e,0xd3,0xf6,0xb8,0xa3,0x88,0xd0,0x2f,0x3e,0x4d,0xf9,0xf2,0xae,0x9c,0x1b,0xd2,0xc3,0x91,0x6a,0x68,0x64,0x60,0xdf,0xfc,0xd4,0x29,0x09,0xcd,0x7f,0x82,0x05,0x8e, + 0x30,0x45,0x02,0x21,0x00,0xe9,0x4d,0xbd,0xc3,0x87,0x95,0xfe,0x5c,0x90,0x4d,0x8f,0x16,0xd9,0x69,0xd3,0xb5,0x87,0xf0,0xa2,0x5d,0x2d,0xe9,0x0b,0x6d,0x8c,0x5c,0x53,0xff,0x88,0x7e,0x36,0x07,0x02,0x20,0x7a,0x94,0x73,0x69,0xc1,0x64,0x97,0x25,0x21,0xbb,0x8a,0xf4,0x06,0x81,0x3b,0x2d,0x9f,0x94,0xd2,0xae,0xaa,0x53,0xd4,0xc2,0x15,0xaa,0xa0,0xa2,0x57,0x8a,0x2c,0x5d, + 0x30,0x44,0x02,0x20,0x49,0xfc,0x10,0x2a,0x08,0xca,0x47,0xb6,0x0e,0x08,0x58,0xcd,0x02,0x84,0xd2,0x2c,0xdd,0xd7,0x23,0x3f,0x94,0xaa,0xff,0xbb,0x2d,0xb1,0xdd,0x2c,0xf0,0x84,0x25,0xe1,0x02,0x20,0x5b,0x16,0xfc,0xa5,0xa1,0x2c,0xdb,0x39,0x70,0x16,0x97,0xad,0x8e,0x39,0xff,0xd6,0xbd,0xec,0x00,0x24,0x29,0x8a,0xfa,0xa2,0x32,0x6a,0xea,0x09,0x20,0x0b,0x14,0xd6, + 0x30,0x44,0x02,0x20,0x41,0xef,0xa7,0xd3,0xf0,0x5a,0x00,0x10,0x67,0x5f,0xcb,0x91,0x8a,0x45,0xc6,0x93,0xda,0x4b,0x34,0x8d,0xf2,0x1a,0x59,0xd6,0xf9,0xcd,0x73,0xe0,0xd8,0x31,0xd6,0x7a,0x02,0x20,0x44,0x54,0xad,0xa6,0x93,0xe5,0xe2,0x6b,0x7b,0xd6,0x93,0x23,0x6d,0x34,0x0f,0x80,0x54,0x5c,0x83,0x45,0x77,0xb6,0xf7,0x3d,0x37,0x8c,0x7b,0xcc,0x53,0x42,0x44,0xda, + 0x30,0x45,0x02,0x21,0x00,0xb6,0x15,0x69,0x8c,0x35,0x8b,0x35,0x92,0x0d,0xd8,0x83,0xec,0xa6,0x25,0xa6,0xc5,0xf7,0x56,0x39,0x70,0xcd,0xfc,0x37,0x8f,0x8f,0xe0,0xce,0xe1,0x70,0x92,0x14,0x4c,0x02,0x20,0x25,0xf4,0x7b,0x32,0x6b,0x5b,0xe1,0xfb,0x61,0x0b,0x88,0x51,0x53,0xea,0x84,0xd4,0x1e,0xb4,0x71,0x6b,0xe6,0x6a,0x99,0x4e,0x87,0x79,0x98,0x9d,0xf1,0xc8,0x63,0xd4, + 0x30,0x45,0x02,0x21,0x00,0x87,0xcf,0x8c,0x0e,0xb8,0x2d,0x44,0xf6,0x9c,0x60,0xa2,0xff,0x54,0x57,0xd3,0xaa,0xa3,0x22,0xe7,0xec,0x61,0xae,0x5a,0xec,0xfd,0x67,0x8a,0xe1,0xc1,0x93,0x2b,0x0e,0x02,0x20,0x3a,0xdd,0x3b,0x11,0x58,0x15,0x04,0x7d,0x6e,0xb3,0x40,0xa3,0xe0,0x08,0x98,0x9e,0xaa,0x0f,0x87,0x08,0xd1,0x79,0x48,0x14,0x72,0x90,0x94,0xd0,0x8d,0x24,0x60,0xd3, + 0x30,0x44,0x02,0x20,0x62,0xf4,0x8e,0xf7,0x1a,0xce,0x27,0xbf,0x5a,0x01,0x83,0x4d,0xe1,0xf7,0xe3,0xf9,0x48,0xb9,0xdc,0xe1,0xca,0x1e,0x91,0x1d,0x5e,0x13,0xd3,0xb1,0x04,0x47,0x1d,0x82,0x02,0x20,0x5e,0xa8,0xf3,0x3f,0x0c,0x77,0x89,0x72,0xc4,0x58,0x20,0x80,0xde,0xda,0x9b,0x34,0x18,0x57,0xdd,0x64,0x51,0x4f,0x08,0x49,0xa0,0x5f,0x69,0x64,0xc2,0xe3,0x40,0x22, + 0x30,0x45,0x02,0x21,0x00,0xf6,0xb0,0xe2,0xf6,0xfe,0x02,0x0c,0xf7,0xc0,0xc2,0x01,0x37,0x43,0x43,0x44,0xed,0x7a,0xdd,0x6c,0x4b,0xe5,0x18,0x61,0xe2,0xd1,0x4c,0xbd,0xa4,0x72,0xa6,0xff,0xb4,0x02,0x20,0x64,0x16,0xc8,0xdd,0x3e,0x5c,0x52,0x82,0xb3,0x06,0xe8,0xdc,0x8f,0xf3,0x4a,0xb6,0x4c,0xc9,0x95,0x49,0x23,0x2d,0x67,0x8d,0x71,0x44,0x02,0xeb,0x6c,0xa7,0xaa,0x0f, + 0x30,0x45,0x02,0x21,0x00,0xdb,0x09,0xd8,0x46,0x0f,0x05,0xef,0xf2,0x3b,0xc7,0xe4,0x36,0xb6,0x7d,0xa5,0x63,0xfa,0x4b,0x4e,0xdb,0x58,0xac,0x24,0xce,0x20,0x1f,0xa8,0xa3,0x58,0x12,0x50,0x57,0x02,0x20,0x46,0xda,0x11,0x67,0x54,0x60,0x29,0x40,0xc8,0x99,0x9c,0x8d,0x66,0x5f,0x78,0x6c,0x50,0xf5,0x77,0x2c,0x0a,0x3c,0xdb,0xda,0x07,0x5e,0x77,0xea,0xbc,0x64,0xdf,0x16, + 0x30,0x44,0x02,0x20,0x59,0x2c,0x41,0xe1,0x65,0x17,0xf1,0x2f,0xca,0xbd,0x98,0x26,0x76,0x74,0xf9,0x74,0xb5,0x88,0xe9,0xf3,0x5d,0x35,0x40,0x6c,0x1a,0x7b,0xb2,0xed,0x1d,0x19,0xb7,0xb8,0x02,0x20,0x3e,0x65,0xa0,0x6b,0xd9,0xf8,0x3c,0xaa,0xeb,0x7b,0x00,0xf2,0x36,0x8d,0x7e,0x0d,0xec,0xe6,0xb1,0x22,0x21,0x26,0x9a,0x9b,0x5b,0x76,0x51,0x98,0xf8,0x40,0xa3,0xa1, + 0x30,0x45,0x02,0x21,0x00,0xbe,0x0d,0x70,0x88,0x7d,0x5e,0x40,0x82,0x1a,0x61,0xb6,0x80,0x47,0xde,0x4e,0xa0,0x3d,0xeb,0xfd,0xf5,0x1c,0xdf,0x4d,0x4b,0x19,0x55,0x58,0xb9,0x59,0xa0,0x32,0xb2,0x02,0x20,0x7d,0x99,0x4b,0x2d,0x8f,0x1d,0xbb,0xeb,0x13,0x53,0x4e,0xb3,0xf6,0xe5,0xdc,0xcd,0x85,0xf5,0xc4,0x13,0x3c,0x27,0xd9,0xe6,0x42,0x71,0xb1,0x82,0x6c,0xe1,0xf6,0x7d, + 0x30,0x45,0x02,0x21,0x00,0xfa,0xe9,0x2d,0xfc,0xb2,0xee,0x39,0x2d,0x27,0x0a,0xf3,0xa5,0x73,0x9f,0xaa,0x26,0xd4,0xf9,0x7b,0xfd,0x39,0xed,0x3c,0xbe,0xe4,0xd2,0x9e,0x26,0xaf,0x3b,0x20,0x6a,0x02,0x20,0x6c,0x9b,0xa3,0x7f,0x9f,0xaa,0x6a,0x1f,0xd3,0xf6,0x5f,0x23,0xb4,0xe8,0x53,0xd4,0x69,0x2a,0x72,0x74,0x24,0x0a,0x12,0xdb,0x7b,0xa3,0x88,0x48,0x30,0x63,0x0d,0x16, + 0x30,0x44,0x02,0x20,0x17,0x6a,0x25,0x57,0x56,0x6f,0xfa,0x51,0x8b,0x11,0x22,0x66,0x94,0xeb,0x98,0x02,0xed,0x20,0x98,0xbf,0xe2,0x78,0xe5,0x57,0x0f,0xe1,0xd5,0xd7,0xaf,0x18,0xa9,0x43,0x02,0x20,0x12,0x91,0xdf,0x6a,0x0e,0xd5,0xfc,0x0d,0x15,0x09,0x8e,0x70,0xbc,0xf1,0x3a,0x00,0x92,0x84,0xdf,0xd0,0x68,0x9d,0x3b,0xb4,0xbe,0x6c,0xee,0xb9,0xbe,0x14,0x87,0xc4, + 0x30,0x44,0x02,0x20,0x60,0xbe,0x20,0xc3,0xdb,0xc1,0x62,0xdd,0x34,0xd2,0x67,0x80,0x62,0x1c,0x10,0x4b,0xbe,0x5d,0xac,0xe6,0x30,0x17,0x1b,0x2d,0xae,0xf0,0xd8,0x26,0x40,0x9e,0xe5,0xc2,0x02,0x20,0x42,0x7f,0x7e,0x4d,0x88,0x9d,0x54,0x91,0x70,0xbd,0xa6,0xa9,0x40,0x9f,0xb1,0xcb,0x8b,0x0e,0x76,0x3d,0x13,0xee,0xa7,0xbd,0x97,0xf6,0x4c,0xf4,0x1d,0xc6,0xe4,0x97, + 0x30,0x45,0x02,0x21,0x00,0xed,0xf0,0x3c,0xf6,0x3f,0x65,0x88,0x83,0x28,0x9a,0x1a,0x59,0x3d,0x10,0x07,0x89,0x5b,0x9f,0x23,0x6d,0x27,0xc9,0xc1,0xf1,0x31,0x30,0x89,0xaa,0xed,0x6b,0x16,0xae,0x02,0x20,0x1a,0x4d,0xd6,0xfc,0x08,0x14,0xdc,0x52,0x3d,0x1f,0xef,0xa8,0x1c,0x64,0xfb,0xf5,0xe6,0x18,0xe6,0x51,0xe7,0x09,0x6f,0xcc,0xad,0xbb,0x94,0xcd,0x48,0xe5,0xe0,0xcd}; + +static const wycheproof_ecdsa_testvector testvectors[SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS] = { + /* tcId: 1. Signature malleability */ + {0, 0, 6, 0, 72, 0 }, + /* tcId: 2. valid */ + {0, 0, 6, 72, 71, 1 }, + /* tcId: 3. length of sequence [r, s] uses long form encoding */ + {0, 0, 6, 143, 72, 0 }, + /* tcId: 4. length of sequence [r, s] contains a leading 0 */ + {0, 0, 6, 215, 73, 0 }, + /* tcId: 5. length of sequence [r, s] uses 70 instead of 69 */ + {0, 0, 6, 288, 71, 0 }, + /* tcId: 6. length of sequence [r, s] uses 68 instead of 69 */ + {0, 0, 6, 359, 71, 0 }, + /* tcId: 7. uint32 overflow in length of sequence [r, s] */ + {0, 0, 6, 430, 76, 0 }, + /* tcId: 8. uint64 overflow in length of sequence [r, s] */ + {0, 0, 6, 506, 80, 0 }, + /* tcId: 9. length of sequence [r, s] = 2**31 - 1 */ + {0, 0, 6, 586, 75, 0 }, + /* tcId: 10. length of sequence [r, s] = 2**31 */ + {0, 0, 6, 661, 75, 0 }, + /* tcId: 11. length of sequence [r, s] = 2**32 - 1 */ + {0, 0, 6, 736, 75, 0 }, + /* tcId: 12. length of sequence [r, s] = 2**40 - 1 */ + {0, 0, 6, 811, 76, 0 }, + /* tcId: 13. length of sequence [r, s] = 2**64 - 1 */ + {0, 0, 6, 887, 79, 0 }, + /* tcId: 14. incorrect length of sequence [r, s] */ + {0, 0, 6, 966, 71, 0 }, + /* tcId: 15. replaced sequence [r, s] by an indefinite length tag without termination */ + {0, 0, 6, 1037, 71, 0 }, + /* tcId: 16. removing sequence [r, s] */ + {0, 0, 6, 1108, 0, 0 }, + /* tcId: 17. lonely sequence tag */ + {0, 0, 6, 1108, 1, 0 }, + /* tcId: 18. appending 0's to sequence [r, s] */ + {0, 0, 6, 1109, 73, 0 }, + /* tcId: 19. prepending 0's to sequence [r, s] */ + {0, 0, 6, 1182, 73, 0 }, + /* tcId: 20. appending unused 0's to sequence [r, s] */ + {0, 0, 6, 1255, 73, 0 }, + /* tcId: 21. appending null value to sequence [r, s] */ + {0, 0, 6, 1328, 73, 0 }, + /* tcId: 22. prepending garbage to sequence [r, s] */ + {0, 0, 6, 1401, 76, 0 }, + /* tcId: 23. prepending garbage to sequence [r, s] */ + {0, 0, 6, 1477, 75, 0 }, + /* tcId: 24. appending garbage to sequence [r, s] */ + {0, 0, 6, 1552, 79, 0 }, + /* tcId: 25. including undefined tags */ + {0, 0, 6, 1631, 79, 0 }, + /* tcId: 26. including undefined tags */ + {0, 0, 6, 1710, 79, 0 }, + /* tcId: 27. including undefined tags */ + {0, 0, 6, 1789, 79, 0 }, + /* tcId: 28. truncated length of sequence [r, s] */ + {0, 0, 6, 1868, 2, 0 }, + /* tcId: 29. including undefined tags to sequence [r, s] */ + {0, 0, 6, 1870, 77, 0 }, + /* tcId: 30. using composition with indefinite length for sequence [r, s] */ + {0, 0, 6, 1947, 75, 0 }, + /* tcId: 31. using composition with wrong tag for sequence [r, s] */ + {0, 0, 6, 2022, 75, 0 }, + /* tcId: 32. Replacing sequence [r, s] with NULL */ + {0, 0, 6, 2097, 2, 0 }, + /* tcId: 33. changing tag value of sequence [r, s] */ + {0, 0, 6, 2099, 71, 0 }, + /* tcId: 34. changing tag value of sequence [r, s] */ + {0, 0, 6, 2170, 71, 0 }, + /* tcId: 35. changing tag value of sequence [r, s] */ + {0, 0, 6, 2241, 71, 0 }, + /* tcId: 36. changing tag value of sequence [r, s] */ + {0, 0, 6, 2312, 71, 0 }, + /* tcId: 37. changing tag value of sequence [r, s] */ + {0, 0, 6, 2383, 71, 0 }, + /* tcId: 38. dropping value of sequence [r, s] */ + {0, 0, 6, 2454, 2, 0 }, + /* tcId: 39. using composition for sequence [r, s] */ + {0, 0, 6, 2456, 75, 0 }, + /* tcId: 40. truncated sequence [r, s] */ + {0, 0, 6, 2531, 70, 0 }, + /* tcId: 41. truncated sequence [r, s] */ + {0, 0, 6, 2601, 70, 0 }, + /* tcId: 42. sequence [r, s] of size 4166 to check for overflows */ + {0, 0, 6, 2671, 4170, 0 }, + /* tcId: 43. indefinite length */ + {0, 0, 6, 6841, 73, 0 }, + /* tcId: 44. indefinite length with truncated delimiter */ + {0, 0, 6, 6914, 72, 0 }, + /* tcId: 45. indefinite length with additional element */ + {0, 0, 6, 6986, 75, 0 }, + /* tcId: 46. indefinite length with truncated element */ + {0, 0, 6, 7061, 77, 0 }, + /* tcId: 47. indefinite length with garbage */ + {0, 0, 6, 7138, 77, 0 }, + /* tcId: 48. indefinite length with nonempty EOC */ + {0, 0, 6, 7215, 75, 0 }, + /* tcId: 49. prepend empty sequence */ + {0, 0, 6, 7290, 73, 0 }, + /* tcId: 50. append empty sequence */ + {0, 0, 6, 7363, 73, 0 }, + /* tcId: 51. append zero */ + {0, 0, 6, 7436, 74, 0 }, + /* tcId: 52. append garbage with high tag number */ + {0, 0, 6, 7510, 74, 0 }, + /* tcId: 53. append null with explicit tag */ + {0, 0, 6, 7584, 75, 0 }, + /* tcId: 54. append null with implicit tag */ + {0, 0, 6, 7659, 73, 0 }, + /* tcId: 55. sequence of sequence */ + {0, 0, 6, 7732, 73, 0 }, + /* tcId: 56. truncated sequence: removed last 1 elements */ + {0, 0, 6, 7805, 37, 0 }, + /* tcId: 57. repeating element in sequence */ + {0, 0, 6, 7842, 105, 0 }, + /* tcId: 58. flipped bit 0 in r */ + {0, 0, 6, 7947, 69, 0 }, + /* tcId: 59. flipped bit 32 in r */ + {0, 0, 6, 8016, 69, 0 }, + /* tcId: 60. flipped bit 48 in r */ + {0, 0, 6, 8085, 69, 0 }, + /* tcId: 61. flipped bit 64 in r */ + {0, 0, 6, 8154, 69, 0 }, + /* tcId: 62. length of r uses long form encoding */ + {0, 0, 6, 8223, 72, 0 }, + /* tcId: 63. length of r contains a leading 0 */ + {0, 0, 6, 8295, 73, 0 }, + /* tcId: 64. length of r uses 34 instead of 33 */ + {0, 0, 6, 8368, 71, 0 }, + /* tcId: 65. length of r uses 32 instead of 33 */ + {0, 0, 6, 8439, 71, 0 }, + /* tcId: 66. uint32 overflow in length of r */ + {0, 0, 6, 8510, 76, 0 }, + /* tcId: 67. uint64 overflow in length of r */ + {0, 0, 6, 8586, 80, 0 }, + /* tcId: 68. length of r = 2**31 - 1 */ + {0, 0, 6, 8666, 75, 0 }, + /* tcId: 69. length of r = 2**31 */ + {0, 0, 6, 8741, 75, 0 }, + /* tcId: 70. length of r = 2**32 - 1 */ + {0, 0, 6, 8816, 75, 0 }, + /* tcId: 71. length of r = 2**40 - 1 */ + {0, 0, 6, 8891, 76, 0 }, + /* tcId: 72. length of r = 2**64 - 1 */ + {0, 0, 6, 8967, 79, 0 }, + /* tcId: 73. incorrect length of r */ + {0, 0, 6, 9046, 71, 0 }, + /* tcId: 74. replaced r by an indefinite length tag without termination */ + {0, 0, 6, 9117, 71, 0 }, + /* tcId: 75. removing r */ + {0, 0, 6, 9188, 36, 0 }, + /* tcId: 76. lonely integer tag */ + {0, 0, 6, 9224, 37, 0 }, + /* tcId: 77. lonely integer tag */ + {0, 0, 6, 9261, 38, 0 }, + /* tcId: 78. appending 0's to r */ + {0, 0, 6, 9299, 73, 0 }, + /* tcId: 79. prepending 0's to r */ + {0, 0, 6, 9372, 73, 0 }, + /* tcId: 80. appending unused 0's to r */ + {0, 0, 6, 9445, 73, 0 }, + /* tcId: 81. appending null value to r */ + {0, 0, 6, 9518, 73, 0 }, + /* tcId: 82. prepending garbage to r */ + {0, 0, 6, 9591, 76, 0 }, + /* tcId: 83. prepending garbage to r */ + {0, 0, 6, 9667, 75, 0 }, + /* tcId: 84. appending garbage to r */ + {0, 0, 6, 9742, 79, 0 }, + /* tcId: 85. truncated length of r */ + {0, 0, 6, 9821, 38, 0 }, + /* tcId: 86. including undefined tags to r */ + {0, 0, 6, 9859, 77, 0 }, + /* tcId: 87. using composition with indefinite length for r */ + {0, 0, 6, 9936, 75, 0 }, + /* tcId: 88. using composition with wrong tag for r */ + {0, 0, 6, 10011, 75, 0 }, + /* tcId: 89. Replacing r with NULL */ + {0, 0, 6, 10086, 38, 0 }, + /* tcId: 90. changing tag value of r */ + {0, 0, 6, 10124, 71, 0 }, + /* tcId: 91. changing tag value of r */ + {0, 0, 6, 10195, 71, 0 }, + /* tcId: 92. changing tag value of r */ + {0, 0, 6, 10266, 71, 0 }, + /* tcId: 93. changing tag value of r */ + {0, 0, 6, 10337, 71, 0 }, + /* tcId: 94. changing tag value of r */ + {0, 0, 6, 10408, 71, 0 }, + /* tcId: 95. dropping value of r */ + {0, 0, 6, 10479, 38, 0 }, + /* tcId: 96. using composition for r */ + {0, 0, 6, 10517, 75, 0 }, + /* tcId: 97. modifying first byte of r */ + {0, 0, 6, 10592, 71, 0 }, + /* tcId: 98. modifying last byte of r */ + {0, 0, 6, 10663, 71, 0 }, + /* tcId: 99. truncated r */ + {0, 0, 6, 10734, 70, 0 }, + /* tcId: 100. truncated r */ + {0, 0, 6, 10804, 70, 0 }, + /* tcId: 101. r of size 4130 to check for overflows */ + {0, 0, 6, 10874, 4172, 0 }, + /* tcId: 102. leading ff in r */ + {0, 0, 6, 15046, 72, 0 }, + /* tcId: 103. replaced r by infinity */ + {0, 0, 6, 15118, 39, 0 }, + /* tcId: 104. replacing r with zero */ + {0, 0, 6, 15157, 39, 0 }, + /* tcId: 105. flipped bit 0 in s */ + {0, 0, 6, 15196, 69, 0 }, + /* tcId: 106. flipped bit 32 in s */ + {0, 0, 6, 15265, 69, 0 }, + /* tcId: 107. flipped bit 48 in s */ + {0, 0, 6, 15334, 69, 0 }, + /* tcId: 108. flipped bit 64 in s */ + {0, 0, 6, 15403, 69, 0 }, + /* tcId: 109. length of s uses long form encoding */ + {0, 0, 6, 15472, 72, 0 }, + /* tcId: 110. length of s contains a leading 0 */ + {0, 0, 6, 15544, 73, 0 }, + /* tcId: 111. length of s uses 33 instead of 32 */ + {0, 0, 6, 15617, 71, 0 }, + /* tcId: 112. length of s uses 31 instead of 32 */ + {0, 0, 6, 15688, 71, 0 }, + /* tcId: 113. uint32 overflow in length of s */ + {0, 0, 6, 15759, 76, 0 }, + /* tcId: 114. uint64 overflow in length of s */ + {0, 0, 6, 15835, 80, 0 }, + /* tcId: 115. length of s = 2**31 - 1 */ + {0, 0, 6, 15915, 75, 0 }, + /* tcId: 116. length of s = 2**31 */ + {0, 0, 6, 15990, 75, 0 }, + /* tcId: 117. length of s = 2**32 - 1 */ + {0, 0, 6, 16065, 75, 0 }, + /* tcId: 118. length of s = 2**40 - 1 */ + {0, 0, 6, 16140, 76, 0 }, + /* tcId: 119. length of s = 2**64 - 1 */ + {0, 0, 6, 16216, 79, 0 }, + /* tcId: 120. incorrect length of s */ + {0, 0, 6, 16295, 71, 0 }, + /* tcId: 121. replaced s by an indefinite length tag without termination */ + {0, 0, 6, 16366, 71, 0 }, + /* tcId: 122. appending 0's to s */ + {0, 0, 6, 16437, 73, 0 }, + /* tcId: 123. prepending 0's to s */ + {0, 0, 6, 16510, 73, 0 }, + /* tcId: 124. appending null value to s */ + {0, 0, 6, 16583, 73, 0 }, + /* tcId: 125. prepending garbage to s */ + {0, 0, 6, 16656, 76, 0 }, + /* tcId: 126. prepending garbage to s */ + {0, 0, 6, 16732, 75, 0 }, + /* tcId: 127. appending garbage to s */ + {0, 0, 6, 16807, 79, 0 }, + /* tcId: 128. truncated length of s */ + {0, 0, 6, 16886, 39, 0 }, + /* tcId: 129. including undefined tags to s */ + {0, 0, 6, 16925, 77, 0 }, + /* tcId: 130. using composition with indefinite length for s */ + {0, 0, 6, 17002, 75, 0 }, + /* tcId: 131. using composition with wrong tag for s */ + {0, 0, 6, 17077, 75, 0 }, + /* tcId: 132. Replacing s with NULL */ + {0, 0, 6, 17152, 39, 0 }, + /* tcId: 133. changing tag value of s */ + {0, 0, 6, 17191, 71, 0 }, + /* tcId: 134. changing tag value of s */ + {0, 0, 6, 17262, 71, 0 }, + /* tcId: 135. changing tag value of s */ + {0, 0, 6, 17333, 71, 0 }, + /* tcId: 136. changing tag value of s */ + {0, 0, 6, 17404, 71, 0 }, + /* tcId: 137. changing tag value of s */ + {0, 0, 6, 17475, 71, 0 }, + /* tcId: 138. dropping value of s */ + {0, 0, 6, 17546, 39, 0 }, + /* tcId: 139. using composition for s */ + {0, 0, 6, 17585, 75, 0 }, + /* tcId: 140. modifying first byte of s */ + {0, 0, 6, 17660, 71, 0 }, + /* tcId: 141. modifying last byte of s */ + {0, 0, 6, 17731, 71, 0 }, + /* tcId: 142. truncated s */ + {0, 0, 6, 17802, 70, 0 }, + /* tcId: 143. truncated s */ + {0, 0, 6, 17872, 70, 0 }, + /* tcId: 144. s of size 4129 to check for overflows */ + {0, 0, 6, 17942, 4172, 0 }, + /* tcId: 145. leading ff in s */ + {0, 0, 6, 22114, 72, 0 }, + /* tcId: 146. replaced s by infinity */ + {0, 0, 6, 22186, 40, 0 }, + /* tcId: 147. replacing s with zero */ + {0, 0, 6, 22226, 40, 0 }, + /* tcId: 148. replaced r by r + n */ + {0, 0, 6, 22266, 71, 0 }, + /* tcId: 149. replaced r by r - n */ + {0, 0, 6, 22337, 70, 0 }, + /* tcId: 150. replaced r by r + 256 * n */ + {0, 0, 6, 22407, 72, 0 }, + /* tcId: 151. replaced r by -r */ + {0, 0, 6, 22479, 71, 0 }, + /* tcId: 152. replaced r by n - r */ + {0, 0, 6, 22550, 70, 0 }, + /* tcId: 153. replaced r by -n - r */ + {0, 0, 6, 22620, 71, 0 }, + /* tcId: 154. replaced r by r + 2**256 */ + {0, 0, 6, 22691, 71, 0 }, + /* tcId: 155. replaced r by r + 2**320 */ + {0, 0, 6, 22762, 79, 0 }, + /* tcId: 156. replaced s by s + n */ + {0, 0, 6, 22841, 71, 0 }, + /* tcId: 157. replaced s by s - n */ + {0, 0, 6, 22912, 71, 0 }, + /* tcId: 158. replaced s by s + 256 * n */ + {0, 0, 6, 22983, 72, 0 }, + /* tcId: 159. replaced s by -s */ + {0, 0, 6, 23055, 70, 0 }, + /* tcId: 160. replaced s by -n - s */ + {0, 0, 6, 23125, 71, 0 }, + /* tcId: 161. replaced s by s + 2**256 */ + {0, 0, 6, 23196, 71, 0 }, + /* tcId: 162. replaced s by s - 2**256 */ + {0, 0, 6, 23267, 71, 0 }, + /* tcId: 163. replaced s by s + 2**320 */ + {0, 0, 6, 23338, 79, 0 }, + /* tcId: 164. Signature with special case values r=0 and s=0 */ + {0, 0, 6, 23417, 8, 0 }, + /* tcId: 165. Signature with special case values r=0 and s=1 */ + {0, 0, 6, 23425, 8, 0 }, + /* tcId: 166. Signature with special case values r=0 and s=-1 */ + {0, 0, 6, 23433, 8, 0 }, + /* tcId: 167. Signature with special case values r=0 and s=n */ + {0, 0, 6, 23441, 40, 0 }, + /* tcId: 168. Signature with special case values r=0 and s=n - 1 */ + {0, 0, 6, 23481, 40, 0 }, + /* tcId: 169. Signature with special case values r=0 and s=n + 1 */ + {0, 0, 6, 23521, 40, 0 }, + /* tcId: 170. Signature with special case values r=0 and s=p */ + {0, 0, 6, 23561, 40, 0 }, + /* tcId: 171. Signature with special case values r=0 and s=p + 1 */ + {0, 0, 6, 23601, 40, 0 }, + /* tcId: 172. Signature with special case values r=1 and s=0 */ + {0, 0, 6, 23641, 8, 0 }, + /* tcId: 173. Signature with special case values r=1 and s=1 */ + {0, 0, 6, 23649, 8, 0 }, + /* tcId: 174. Signature with special case values r=1 and s=-1 */ + {0, 0, 6, 23657, 8, 0 }, + /* tcId: 175. Signature with special case values r=1 and s=n */ + {0, 0, 6, 23665, 40, 0 }, + /* tcId: 176. Signature with special case values r=1 and s=n - 1 */ + {0, 0, 6, 23705, 40, 0 }, + /* tcId: 177. Signature with special case values r=1 and s=n + 1 */ + {0, 0, 6, 23745, 40, 0 }, + /* tcId: 178. Signature with special case values r=1 and s=p */ + {0, 0, 6, 23785, 40, 0 }, + /* tcId: 179. Signature with special case values r=1 and s=p + 1 */ + {0, 0, 6, 23825, 40, 0 }, + /* tcId: 180. Signature with special case values r=-1 and s=0 */ + {0, 0, 6, 23865, 8, 0 }, + /* tcId: 181. Signature with special case values r=-1 and s=1 */ + {0, 0, 6, 23873, 8, 0 }, + /* tcId: 182. Signature with special case values r=-1 and s=-1 */ + {0, 0, 6, 23881, 8, 0 }, + /* tcId: 183. Signature with special case values r=-1 and s=n */ + {0, 0, 6, 23889, 40, 0 }, + /* tcId: 184. Signature with special case values r=-1 and s=n - 1 */ + {0, 0, 6, 23929, 40, 0 }, + /* tcId: 185. Signature with special case values r=-1 and s=n + 1 */ + {0, 0, 6, 23969, 40, 0 }, + /* tcId: 186. Signature with special case values r=-1 and s=p */ + {0, 0, 6, 24009, 40, 0 }, + /* tcId: 187. Signature with special case values r=-1 and s=p + 1 */ + {0, 0, 6, 24049, 40, 0 }, + /* tcId: 188. Signature with special case values r=n and s=0 */ + {0, 0, 6, 24089, 40, 0 }, + /* tcId: 189. Signature with special case values r=n and s=1 */ + {0, 0, 6, 24129, 40, 0 }, + /* tcId: 190. Signature with special case values r=n and s=-1 */ + {0, 0, 6, 24169, 40, 0 }, + /* tcId: 191. Signature with special case values r=n and s=n */ + {0, 0, 6, 24209, 72, 0 }, + /* tcId: 192. Signature with special case values r=n and s=n - 1 */ + {0, 0, 6, 24281, 72, 0 }, + /* tcId: 193. Signature with special case values r=n and s=n + 1 */ + {0, 0, 6, 24353, 72, 0 }, + /* tcId: 194. Signature with special case values r=n and s=p */ + {0, 0, 6, 24425, 72, 0 }, + /* tcId: 195. Signature with special case values r=n and s=p + 1 */ + {0, 0, 6, 24497, 72, 0 }, + /* tcId: 196. Signature with special case values r=n - 1 and s=0 */ + {0, 0, 6, 24569, 40, 0 }, + /* tcId: 197. Signature with special case values r=n - 1 and s=1 */ + {0, 0, 6, 24609, 40, 0 }, + /* tcId: 198. Signature with special case values r=n - 1 and s=-1 */ + {0, 0, 6, 24649, 40, 0 }, + /* tcId: 199. Signature with special case values r=n - 1 and s=n */ + {0, 0, 6, 24689, 72, 0 }, + /* tcId: 200. Signature with special case values r=n - 1 and s=n - 1 */ + {0, 0, 6, 24761, 72, 0 }, + /* tcId: 201. Signature with special case values r=n - 1 and s=n + 1 */ + {0, 0, 6, 24833, 72, 0 }, + /* tcId: 202. Signature with special case values r=n - 1 and s=p */ + {0, 0, 6, 24905, 72, 0 }, + /* tcId: 203. Signature with special case values r=n - 1 and s=p + 1 */ + {0, 0, 6, 24977, 72, 0 }, + /* tcId: 204. Signature with special case values r=n + 1 and s=0 */ + {0, 0, 6, 25049, 40, 0 }, + /* tcId: 205. Signature with special case values r=n + 1 and s=1 */ + {0, 0, 6, 25089, 40, 0 }, + /* tcId: 206. Signature with special case values r=n + 1 and s=-1 */ + {0, 0, 6, 25129, 40, 0 }, + /* tcId: 207. Signature with special case values r=n + 1 and s=n */ + {0, 0, 6, 25169, 72, 0 }, + /* tcId: 208. Signature with special case values r=n + 1 and s=n - 1 */ + {0, 0, 6, 25241, 72, 0 }, + /* tcId: 209. Signature with special case values r=n + 1 and s=n + 1 */ + {0, 0, 6, 25313, 72, 0 }, + /* tcId: 210. Signature with special case values r=n + 1 and s=p */ + {0, 0, 6, 25385, 72, 0 }, + /* tcId: 211. Signature with special case values r=n + 1 and s=p + 1 */ + {0, 0, 6, 25457, 72, 0 }, + /* tcId: 212. Signature with special case values r=p and s=0 */ + {0, 0, 6, 25529, 40, 0 }, + /* tcId: 213. Signature with special case values r=p and s=1 */ + {0, 0, 6, 25569, 40, 0 }, + /* tcId: 214. Signature with special case values r=p and s=-1 */ + {0, 0, 6, 25609, 40, 0 }, + /* tcId: 215. Signature with special case values r=p and s=n */ + {0, 0, 6, 25649, 72, 0 }, + /* tcId: 216. Signature with special case values r=p and s=n - 1 */ + {0, 0, 6, 25721, 72, 0 }, + /* tcId: 217. Signature with special case values r=p and s=n + 1 */ + {0, 0, 6, 25793, 72, 0 }, + /* tcId: 218. Signature with special case values r=p and s=p */ + {0, 0, 6, 25865, 72, 0 }, + /* tcId: 219. Signature with special case values r=p and s=p + 1 */ + {0, 0, 6, 25937, 72, 0 }, + /* tcId: 220. Signature with special case values r=p + 1 and s=0 */ + {0, 0, 6, 26009, 40, 0 }, + /* tcId: 221. Signature with special case values r=p + 1 and s=1 */ + {0, 0, 6, 26049, 40, 0 }, + /* tcId: 222. Signature with special case values r=p + 1 and s=-1 */ + {0, 0, 6, 26089, 40, 0 }, + /* tcId: 223. Signature with special case values r=p + 1 and s=n */ + {0, 0, 6, 26129, 72, 0 }, + /* tcId: 224. Signature with special case values r=p + 1 and s=n - 1 */ + {0, 0, 6, 26201, 72, 0 }, + /* tcId: 225. Signature with special case values r=p + 1 and s=n + 1 */ + {0, 0, 6, 26273, 72, 0 }, + /* tcId: 226. Signature with special case values r=p + 1 and s=p */ + {0, 0, 6, 26345, 72, 0 }, + /* tcId: 227. Signature with special case values r=p + 1 and s=p + 1 */ + {0, 0, 6, 26417, 72, 0 }, + /* tcId: 228. Signature encoding contains incorrect types: r=0, s=0.25 */ + {0, 0, 6, 26489, 10, 0 }, + /* tcId: 229. Signature encoding contains incorrect types: r=0, s=nan */ + {0, 0, 6, 26499, 8, 0 }, + /* tcId: 230. Signature encoding contains incorrect types: r=0, s=True */ + {0, 0, 6, 26507, 8, 0 }, + /* tcId: 231. Signature encoding contains incorrect types: r=0, s=False */ + {0, 0, 6, 26515, 8, 0 }, + /* tcId: 232. Signature encoding contains incorrect types: r=0, s=Null */ + {0, 0, 6, 26523, 7, 0 }, + /* tcId: 233. Signature encoding contains incorrect types: r=0, s=empyt UTF-8 string */ + {0, 0, 6, 26530, 7, 0 }, + /* tcId: 234. Signature encoding contains incorrect types: r=0, s="0" */ + {0, 0, 6, 26537, 8, 0 }, + /* tcId: 235. Signature encoding contains incorrect types: r=0, s=empty list */ + {0, 0, 6, 26545, 7, 0 }, + /* tcId: 236. Signature encoding contains incorrect types: r=0, s=list containing 0 */ + {0, 0, 6, 26552, 10, 0 }, + /* tcId: 237. Signature encoding contains incorrect types: r=1, s=0.25 */ + {0, 0, 6, 26562, 10, 0 }, + /* tcId: 238. Signature encoding contains incorrect types: r=1, s=nan */ + {0, 0, 6, 26572, 8, 0 }, + /* tcId: 239. Signature encoding contains incorrect types: r=1, s=True */ + {0, 0, 6, 26580, 8, 0 }, + /* tcId: 240. Signature encoding contains incorrect types: r=1, s=False */ + {0, 0, 6, 26588, 8, 0 }, + /* tcId: 241. Signature encoding contains incorrect types: r=1, s=Null */ + {0, 0, 6, 26596, 7, 0 }, + /* tcId: 242. Signature encoding contains incorrect types: r=1, s=empyt UTF-8 string */ + {0, 0, 6, 26603, 7, 0 }, + /* tcId: 243. Signature encoding contains incorrect types: r=1, s="0" */ + {0, 0, 6, 26610, 8, 0 }, + /* tcId: 244. Signature encoding contains incorrect types: r=1, s=empty list */ + {0, 0, 6, 26618, 7, 0 }, + /* tcId: 245. Signature encoding contains incorrect types: r=1, s=list containing 0 */ + {0, 0, 6, 26625, 10, 0 }, + /* tcId: 246. Signature encoding contains incorrect types: r=-1, s=0.25 */ + {0, 0, 6, 26635, 10, 0 }, + /* tcId: 247. Signature encoding contains incorrect types: r=-1, s=nan */ + {0, 0, 6, 26645, 8, 0 }, + /* tcId: 248. Signature encoding contains incorrect types: r=-1, s=True */ + {0, 0, 6, 26653, 8, 0 }, + /* tcId: 249. Signature encoding contains incorrect types: r=-1, s=False */ + {0, 0, 6, 26661, 8, 0 }, + /* tcId: 250. Signature encoding contains incorrect types: r=-1, s=Null */ + {0, 0, 6, 26669, 7, 0 }, + /* tcId: 251. Signature encoding contains incorrect types: r=-1, s=empyt UTF-8 string */ + {0, 0, 6, 26676, 7, 0 }, + /* tcId: 252. Signature encoding contains incorrect types: r=-1, s="0" */ + {0, 0, 6, 26683, 8, 0 }, + /* tcId: 253. Signature encoding contains incorrect types: r=-1, s=empty list */ + {0, 0, 6, 26691, 7, 0 }, + /* tcId: 254. Signature encoding contains incorrect types: r=-1, s=list containing 0 */ + {0, 0, 6, 26698, 10, 0 }, + /* tcId: 255. Signature encoding contains incorrect types: r=n, s=0.25 */ + {0, 0, 6, 26708, 42, 0 }, + /* tcId: 256. Signature encoding contains incorrect types: r=n, s=nan */ + {0, 0, 6, 26750, 40, 0 }, + /* tcId: 257. Signature encoding contains incorrect types: r=n, s=True */ + {0, 0, 6, 26790, 40, 0 }, + /* tcId: 258. Signature encoding contains incorrect types: r=n, s=False */ + {0, 0, 6, 26830, 40, 0 }, + /* tcId: 259. Signature encoding contains incorrect types: r=n, s=Null */ + {0, 0, 6, 26870, 39, 0 }, + /* tcId: 260. Signature encoding contains incorrect types: r=n, s=empyt UTF-8 string */ + {0, 0, 6, 26909, 39, 0 }, + /* tcId: 261. Signature encoding contains incorrect types: r=n, s="0" */ + {0, 0, 6, 26948, 40, 0 }, + /* tcId: 262. Signature encoding contains incorrect types: r=n, s=empty list */ + {0, 0, 6, 26988, 39, 0 }, + /* tcId: 263. Signature encoding contains incorrect types: r=n, s=list containing 0 */ + {0, 0, 6, 27027, 42, 0 }, + /* tcId: 264. Signature encoding contains incorrect types: r=p, s=0.25 */ + {0, 0, 6, 27069, 42, 0 }, + /* tcId: 265. Signature encoding contains incorrect types: r=p, s=nan */ + {0, 0, 6, 27111, 40, 0 }, + /* tcId: 266. Signature encoding contains incorrect types: r=p, s=True */ + {0, 0, 6, 27151, 40, 0 }, + /* tcId: 267. Signature encoding contains incorrect types: r=p, s=False */ + {0, 0, 6, 27191, 40, 0 }, + /* tcId: 268. Signature encoding contains incorrect types: r=p, s=Null */ + {0, 0, 6, 27231, 39, 0 }, + /* tcId: 269. Signature encoding contains incorrect types: r=p, s=empyt UTF-8 string */ + {0, 0, 6, 27270, 39, 0 }, + /* tcId: 270. Signature encoding contains incorrect types: r=p, s="0" */ + {0, 0, 6, 27309, 40, 0 }, + /* tcId: 271. Signature encoding contains incorrect types: r=p, s=empty list */ + {0, 0, 6, 27349, 39, 0 }, + /* tcId: 272. Signature encoding contains incorrect types: r=p, s=list containing 0 */ + {0, 0, 6, 27388, 42, 0 }, + /* tcId: 273. Signature encoding contains incorrect types: r=0.25, s=0.25 */ + {0, 0, 6, 27430, 12, 0 }, + /* tcId: 274. Signature encoding contains incorrect types: r=nan, s=nan */ + {0, 0, 6, 27442, 8, 0 }, + /* tcId: 275. Signature encoding contains incorrect types: r=True, s=True */ + {0, 0, 6, 27450, 8, 0 }, + /* tcId: 276. Signature encoding contains incorrect types: r=False, s=False */ + {0, 0, 6, 27458, 8, 0 }, + /* tcId: 277. Signature encoding contains incorrect types: r=Null, s=Null */ + {0, 0, 6, 27466, 6, 0 }, + /* tcId: 278. Signature encoding contains incorrect types: r=empyt UTF-8 string, s=empyt UTF-8 string */ + {0, 0, 6, 27472, 6, 0 }, + /* tcId: 279. Signature encoding contains incorrect types: r="0", s="0" */ + {0, 0, 6, 27478, 8, 0 }, + /* tcId: 280. Signature encoding contains incorrect types: r=empty list, s=empty list */ + {0, 0, 6, 27486, 6, 0 }, + /* tcId: 281. Signature encoding contains incorrect types: r=list containing 0, s=list containing 0 */ + {0, 0, 6, 27492, 12, 0 }, + /* tcId: 282. Signature encoding contains incorrect types: r=0.25, s=0 */ + {0, 0, 6, 27504, 10, 0 }, + /* tcId: 283. Signature encoding contains incorrect types: r=nan, s=0 */ + {0, 0, 6, 27514, 8, 0 }, + /* tcId: 284. Signature encoding contains incorrect types: r=True, s=0 */ + {0, 0, 6, 27522, 8, 0 }, + /* tcId: 285. Signature encoding contains incorrect types: r=False, s=0 */ + {0, 0, 6, 27530, 8, 0 }, + /* tcId: 286. Signature encoding contains incorrect types: r=Null, s=0 */ + {0, 0, 6, 27538, 7, 0 }, + /* tcId: 287. Signature encoding contains incorrect types: r=empyt UTF-8 string, s=0 */ + {0, 0, 6, 27545, 7, 0 }, + /* tcId: 288. Signature encoding contains incorrect types: r="0", s=0 */ + {0, 0, 6, 27552, 8, 0 }, + /* tcId: 289. Signature encoding contains incorrect types: r=empty list, s=0 */ + {0, 0, 6, 27560, 7, 0 }, + /* tcId: 290. Signature encoding contains incorrect types: r=list containing 0, s=0 */ + {0, 0, 6, 27567, 10, 0 }, + /* tcId: 291. Edge case for Shamir multiplication */ + {0, 6, 5, 27577, 71, 1 }, + /* tcId: 292. special case hash */ + {0, 11, 9, 27648, 71, 1 }, + /* tcId: 293. special case hash */ + {0, 20, 10, 27719, 70, 1 }, + /* tcId: 294. special case hash */ + {0, 30, 11, 27789, 71, 1 }, + /* tcId: 295. special case hash */ + {0, 41, 10, 27860, 71, 1 }, + /* tcId: 296. special case hash */ + {0, 51, 10, 27931, 70, 1 }, + /* tcId: 297. special case hash */ + {0, 61, 10, 28001, 71, 1 }, + /* tcId: 298. special case hash */ + {0, 71, 9, 28072, 70, 1 }, + /* tcId: 299. special case hash */ + {0, 80, 10, 28142, 71, 1 }, + /* tcId: 300. special case hash */ + {0, 90, 10, 28213, 71, 1 }, + /* tcId: 301. special case hash */ + {0, 100, 10, 28284, 71, 1 }, + /* tcId: 302. special case hash */ + {0, 110, 10, 28355, 71, 1 }, + /* tcId: 303. special case hash */ + {0, 120, 11, 28426, 70, 1 }, + /* tcId: 304. special case hash */ + {0, 131, 10, 28496, 71, 1 }, + /* tcId: 305. special case hash */ + {0, 141, 10, 28567, 71, 1 }, + /* tcId: 306. special case hash */ + {0, 151, 10, 28638, 70, 1 }, + /* tcId: 307. special case hash */ + {0, 161, 10, 28708, 71, 1 }, + /* tcId: 308. special case hash */ + {0, 171, 10, 28779, 71, 1 }, + /* tcId: 309. special case hash */ + {0, 181, 10, 28850, 70, 1 }, + /* tcId: 310. special case hash */ + {0, 191, 10, 28920, 71, 1 }, + /* tcId: 311. special case hash */ + {0, 201, 10, 28991, 71, 1 }, + /* tcId: 312. special case hash */ + {0, 211, 10, 29062, 71, 1 }, + /* tcId: 313. special case hash */ + {0, 221, 10, 29133, 70, 1 }, + /* tcId: 314. special case hash */ + {0, 231, 10, 29203, 71, 1 }, + /* tcId: 315. special case hash */ + {0, 241, 10, 29274, 71, 1 }, + /* tcId: 316. special case hash */ + {0, 251, 10, 29345, 71, 1 }, + /* tcId: 317. special case hash */ + {0, 261, 11, 29416, 71, 1 }, + /* tcId: 318. special case hash */ + {0, 272, 11, 29487, 70, 1 }, + /* tcId: 319. special case hash */ + {0, 283, 9, 29557, 71, 1 }, + /* tcId: 320. special case hash */ + {0, 292, 9, 29628, 71, 1 }, + /* tcId: 321. special case hash */ + {0, 301, 10, 29699, 71, 1 }, + /* tcId: 322. special case hash */ + {0, 311, 10, 29770, 71, 1 }, + /* tcId: 323. special case hash */ + {0, 321, 10, 29841, 70, 1 }, + /* tcId: 324. special case hash */ + {0, 331, 10, 29911, 70, 1 }, + /* tcId: 325. special case hash */ + {0, 341, 10, 29981, 71, 1 }, + /* tcId: 326. special case hash */ + {0, 351, 9, 30052, 70, 1 }, + /* tcId: 327. special case hash */ + {0, 360, 10, 30122, 70, 1 }, + /* tcId: 328. special case hash */ + {0, 370, 10, 30192, 70, 1 }, + /* tcId: 329. special case hash */ + {0, 380, 10, 30262, 70, 1 }, + /* tcId: 330. special case hash */ + {0, 390, 9, 30332, 71, 1 }, + /* tcId: 331. special case hash */ + {0, 399, 11, 30403, 70, 1 }, + /* tcId: 332. special case hash */ + {0, 410, 9, 30473, 71, 1 }, + /* tcId: 333. special case hash */ + {0, 419, 9, 30544, 71, 1 }, + /* tcId: 334. special case hash */ + {0, 428, 11, 30615, 70, 1 }, + /* tcId: 335. special case hash */ + {0, 439, 8, 30685, 71, 1 }, + /* tcId: 336. special case hash */ + {0, 447, 10, 30756, 70, 1 }, + /* tcId: 337. special case hash */ + {0, 457, 10, 30826, 71, 1 }, + /* tcId: 338. special case hash */ + {0, 467, 10, 30897, 70, 1 }, + /* tcId: 339. special case hash */ + {0, 477, 10, 30967, 70, 1 }, + /* tcId: 340. special case hash */ + {0, 487, 10, 31037, 70, 1 }, + /* tcId: 341. special case hash */ + {0, 497, 10, 31107, 71, 1 }, + /* tcId: 342. special case hash */ + {0, 507, 10, 31178, 70, 1 }, + /* tcId: 343. special case hash */ + {0, 517, 10, 31248, 70, 1 }, + /* tcId: 344. special case hash */ + {0, 527, 10, 31318, 71, 1 }, + /* tcId: 345. special case hash */ + {0, 537, 9, 31389, 70, 1 }, + /* tcId: 346. k*G has a large x-coordinate */ + {65, 0, 6, 31459, 24, 1 }, + /* tcId: 347. r too large */ + {65, 0, 6, 31483, 40, 0 }, + /* tcId: 348. r,s are large */ + {130, 0, 6, 31523, 40, 1 }, + /* tcId: 349. r and s^-1 have a large Hamming weight */ + {195, 0, 6, 31563, 70, 1 }, + /* tcId: 350. r and s^-1 have a large Hamming weight */ + {260, 0, 6, 31633, 70, 1 }, + /* tcId: 351. small r and s */ + {325, 0, 6, 31703, 8, 1 }, + /* tcId: 352. small r and s */ + {390, 0, 6, 31711, 8, 1 }, + /* tcId: 353. small r and s */ + {455, 0, 6, 31719, 8, 1 }, + /* tcId: 354. small r and s */ + {520, 0, 6, 31727, 8, 1 }, + /* tcId: 355. small r and s */ + {585, 0, 6, 31735, 8, 1 }, + /* tcId: 356. small r and s */ + {650, 0, 6, 31743, 8, 1 }, + /* tcId: 357. r is larger than n */ + {650, 0, 6, 31751, 40, 0 }, + /* tcId: 358. s is larger than n */ + {715, 0, 6, 31791, 10, 0 }, + /* tcId: 359. small r and s^-1 */ + {780, 0, 6, 31801, 40, 1 }, + /* tcId: 360. smallish r and s^-1 */ + {845, 0, 6, 31841, 45, 1 }, + /* tcId: 361. 100-bit r and small s^-1 */ + {910, 0, 6, 31886, 51, 1 }, + /* tcId: 362. small r and 100 bit s^-1 */ + {975, 0, 6, 31937, 40, 1 }, + /* tcId: 363. 100-bit r and s^-1 */ + {1040, 0, 6, 31977, 51, 1 }, + /* tcId: 364. r and s^-1 are close to n */ + {1105, 0, 6, 32028, 71, 1 }, + /* tcId: 365. r and s are 64-bit integer */ + {1170, 0, 6, 32099, 24, 1 }, + /* tcId: 366. r and s are 100-bit integer */ + {1235, 0, 6, 32123, 32, 1 }, + /* tcId: 367. r and s are 128-bit integer */ + {1300, 0, 6, 32155, 40, 1 }, + /* tcId: 368. r and s are 160-bit integer */ + {1365, 0, 6, 32195, 48, 1 }, + /* tcId: 369. s == 1 */ + {1430, 0, 6, 32243, 39, 1 }, + /* tcId: 370. s == 0 */ + {1430, 0, 6, 32282, 39, 0 }, + /* tcId: 371. edge case modular inverse */ + {1495, 0, 6, 32321, 70, 1 }, + /* tcId: 372. edge case modular inverse */ + {1560, 0, 6, 32391, 70, 1 }, + /* tcId: 373. edge case modular inverse */ + {1625, 0, 6, 32461, 70, 1 }, + /* tcId: 374. edge case modular inverse */ + {1690, 0, 6, 32531, 70, 1 }, + /* tcId: 375. edge case modular inverse */ + {1755, 0, 6, 32601, 70, 1 }, + /* tcId: 376. edge case modular inverse */ + {1820, 0, 6, 32671, 70, 1 }, + /* tcId: 377. edge case modular inverse */ + {1885, 0, 6, 32741, 70, 1 }, + /* tcId: 378. edge case modular inverse */ + {1950, 0, 6, 32811, 70, 1 }, + /* tcId: 379. edge case modular inverse */ + {2015, 0, 6, 32881, 70, 1 }, + /* tcId: 380. edge case modular inverse */ + {2080, 0, 6, 32951, 70, 1 }, + /* tcId: 381. edge case modular inverse */ + {2145, 0, 6, 33021, 70, 1 }, + /* tcId: 382. edge case modular inverse */ + {2210, 0, 6, 33091, 70, 1 }, + /* tcId: 383. edge case modular inverse */ + {2275, 0, 6, 33161, 70, 1 }, + /* tcId: 384. edge case modular inverse */ + {2340, 0, 6, 33231, 70, 1 }, + /* tcId: 385. edge case modular inverse */ + {2405, 0, 6, 33301, 70, 1 }, + /* tcId: 386. point at infinity during verify */ + {2470, 0, 6, 33371, 70, 0 }, + /* tcId: 387. edge case for signature malleability */ + {2535, 0, 6, 33441, 70, 1 }, + /* tcId: 388. edge case for signature malleability */ + {2600, 0, 6, 33511, 70, 0 }, + /* tcId: 389. u1 == 1 */ + {2665, 0, 6, 33581, 70, 1 }, + /* tcId: 390. u1 == n - 1 */ + {2730, 0, 6, 33651, 70, 1 }, + /* tcId: 391. u2 == 1 */ + {2795, 0, 6, 33721, 70, 1 }, + /* tcId: 392. u2 == n - 1 */ + {2860, 0, 6, 33791, 70, 1 }, + /* tcId: 393. edge case for u1 */ + {2925, 0, 6, 33861, 70, 1 }, + /* tcId: 394. edge case for u1 */ + {2990, 0, 6, 33931, 70, 1 }, + /* tcId: 395. edge case for u1 */ + {3055, 0, 6, 34001, 70, 1 }, + /* tcId: 396. edge case for u1 */ + {3120, 0, 6, 34071, 70, 1 }, + /* tcId: 397. edge case for u1 */ + {3185, 0, 6, 34141, 70, 1 }, + /* tcId: 398. edge case for u1 */ + {3250, 0, 6, 34211, 70, 1 }, + /* tcId: 399. edge case for u1 */ + {3315, 0, 6, 34281, 70, 1 }, + /* tcId: 400. edge case for u1 */ + {3380, 0, 6, 34351, 70, 1 }, + /* tcId: 401. edge case for u1 */ + {3445, 0, 6, 34421, 70, 1 }, + /* tcId: 402. edge case for u1 */ + {3510, 0, 6, 34491, 70, 1 }, + /* tcId: 403. edge case for u1 */ + {3575, 0, 6, 34561, 70, 1 }, + /* tcId: 404. edge case for u1 */ + {3640, 0, 6, 34631, 70, 1 }, + /* tcId: 405. edge case for u1 */ + {3705, 0, 6, 34701, 70, 1 }, + /* tcId: 406. edge case for u1 */ + {3770, 0, 6, 34771, 70, 1 }, + /* tcId: 407. edge case for u1 */ + {3835, 0, 6, 34841, 70, 1 }, + /* tcId: 408. edge case for u2 */ + {3900, 0, 6, 34911, 70, 1 }, + /* tcId: 409. edge case for u2 */ + {3965, 0, 6, 34981, 70, 1 }, + /* tcId: 410. edge case for u2 */ + {4030, 0, 6, 35051, 70, 1 }, + /* tcId: 411. edge case for u2 */ + {4095, 0, 6, 35121, 70, 1 }, + /* tcId: 412. edge case for u2 */ + {4160, 0, 6, 35191, 70, 1 }, + /* tcId: 413. edge case for u2 */ + {4225, 0, 6, 35261, 69, 1 }, + /* tcId: 414. edge case for u2 */ + {4290, 0, 6, 35330, 70, 1 }, + /* tcId: 415. edge case for u2 */ + {4355, 0, 6, 35400, 70, 1 }, + /* tcId: 416. edge case for u2 */ + {4420, 0, 6, 35470, 70, 1 }, + /* tcId: 417. edge case for u2 */ + {4485, 0, 6, 35540, 70, 1 }, + /* tcId: 418. edge case for u2 */ + {4550, 0, 6, 35610, 70, 1 }, + /* tcId: 419. edge case for u2 */ + {4615, 0, 6, 35680, 70, 1 }, + /* tcId: 420. edge case for u2 */ + {4680, 0, 6, 35750, 70, 1 }, + /* tcId: 421. edge case for u2 */ + {4745, 0, 6, 35820, 70, 1 }, + /* tcId: 422. edge case for u2 */ + {4810, 0, 6, 35890, 70, 1 }, + /* tcId: 423. point duplication during verification */ + {4875, 0, 6, 35960, 70, 1 }, + /* tcId: 424. duplication bug */ + {4940, 0, 6, 36030, 70, 0 }, + /* tcId: 425. comparison with point at infinity */ + {5005, 0, 6, 36100, 70, 0 }, + /* tcId: 426. extreme value for k and edgecase s */ + {5070, 0, 6, 36170, 71, 1 }, + /* tcId: 427. extreme value for k and s^-1 */ + {5135, 0, 6, 36241, 71, 1 }, + /* tcId: 428. extreme value for k and s^-1 */ + {5200, 0, 6, 36312, 71, 1 }, + /* tcId: 429. extreme value for k and s^-1 */ + {5265, 0, 6, 36383, 71, 1 }, + /* tcId: 430. extreme value for k and s^-1 */ + {5330, 0, 6, 36454, 71, 1 }, + /* tcId: 431. extreme value for k */ + {5395, 0, 6, 36525, 71, 1 }, + /* tcId: 432. extreme value for k and edgecase s */ + {5460, 0, 6, 36596, 70, 1 }, + /* tcId: 433. extreme value for k and s^-1 */ + {5525, 0, 6, 36666, 70, 1 }, + /* tcId: 434. extreme value for k and s^-1 */ + {5590, 0, 6, 36736, 70, 1 }, + /* tcId: 435. extreme value for k and s^-1 */ + {5655, 0, 6, 36806, 70, 1 }, + /* tcId: 436. extreme value for k and s^-1 */ + {5720, 0, 6, 36876, 70, 1 }, + /* tcId: 437. extreme value for k */ + {5785, 0, 6, 36946, 70, 1 }, + /* tcId: 438. public key shares x-coordinate with generator */ + {5850, 0, 6, 37016, 71, 0 }, + /* tcId: 439. public key shares x-coordinate with generator */ + {5850, 0, 6, 37087, 70, 0 }, + /* tcId: 440. public key shares x-coordinate with generator */ + {5915, 0, 6, 37157, 71, 0 }, + /* tcId: 441. public key shares x-coordinate with generator */ + {5915, 0, 6, 37228, 70, 0 }, + /* tcId: 442. pseudorandom signature */ + {5980, 546, 0, 37298, 71, 1 }, + /* tcId: 443. pseudorandom signature */ + {5980, 546, 3, 37369, 70, 1 }, + /* tcId: 444. pseudorandom signature */ + {5980, 0, 6, 37439, 71, 1 }, + /* tcId: 445. pseudorandom signature */ + {5980, 549, 20, 37510, 70, 1 }, + /* tcId: 446. y-coordinate of the public key is small */ + {6045, 569, 7, 37580, 70, 1 }, + /* tcId: 447. y-coordinate of the public key is small */ + {6045, 569, 7, 37650, 70, 1 }, + /* tcId: 448. y-coordinate of the public key is small */ + {6045, 569, 7, 37720, 71, 1 }, + /* tcId: 449. y-coordinate of the public key is large */ + {6110, 569, 7, 37791, 70, 1 }, + /* tcId: 450. y-coordinate of the public key is large */ + {6110, 569, 7, 37861, 71, 1 }, + /* tcId: 451. y-coordinate of the public key is large */ + {6110, 569, 7, 37932, 70, 1 }, + /* tcId: 452. x-coordinate of the public key is small */ + {6175, 569, 7, 38002, 70, 1 }, + /* tcId: 453. x-coordinate of the public key is small */ + {6175, 569, 7, 38072, 71, 1 }, + /* tcId: 454. x-coordinate of the public key is small */ + {6175, 569, 7, 38143, 71, 1 }, + /* tcId: 455. x-coordinate of the public key has many trailing 1's */ + {6240, 569, 7, 38214, 70, 1 }, + /* tcId: 456. x-coordinate of the public key has many trailing 1's */ + {6240, 569, 7, 38284, 71, 1 }, + /* tcId: 457. x-coordinate of the public key has many trailing 1's */ + {6240, 569, 7, 38355, 71, 1 }, + /* tcId: 458. y-coordinate of the public key has many trailing 1's */ + {6305, 569, 7, 38426, 70, 1 }, + /* tcId: 459. y-coordinate of the public key has many trailing 1's */ + {6305, 569, 7, 38496, 71, 1 }, + /* tcId: 460. y-coordinate of the public key has many trailing 1's */ + {6305, 569, 7, 38567, 71, 1 }, + /* tcId: 461. x-coordinate of the public key has many trailing 0's */ + {6370, 569, 7, 38638, 70, 1 }, + /* tcId: 462. x-coordinate of the public key has many trailing 0's */ + {6370, 569, 7, 38708, 70, 1 }, + /* tcId: 463. x-coordinate of the public key has many trailing 0's */ + {6370, 569, 7, 38778, 71, 1 }, + +}; diff --git a/crypto/secp256k1/libsecp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json b/crypto/secp256k1/libsecp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json new file mode 100644 index 0000000000..9c90747993 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json @@ -0,0 +1,6360 @@ +{ + "algorithm" : "ECDSA", + "schema" : "ecdsa_bitcoin_verify_schema.json", + "generatorVersion" : "0.9rc5", + "numberOfTests" : 463, + "header" : [ + "Test vectors of type EcdsaBitcoinVerify are meant for the verification", + "of a ECDSA variant used for bitcoin, that add signature non-malleability." + ], + "notes" : { + "ArithmeticError" : { + "bugType" : "EDGE_CASE", + "description" : "Some implementations of ECDSA have arithmetic errors that occur when intermediate results have extreme values. This test vector has been constructed to test such occurences.", + "cves" : [ + "CVE-2017-18146" + ] + }, + "BerEncodedSignature" : { + "bugType" : "BER_ENCODING", + "description" : "ECDSA signatures are usually DER encoded. This signature contains valid values for r and s, but it uses alternative BER encoding.", + "effect" : "Accepting alternative BER encodings may be benign in some cases, or be an issue if protocol requires signature malleability.", + "cves" : [ + "CVE-2020-14966", + "CVE-2020-13822", + "CVE-2019-14859", + "CVE-2016-1000342" + ] + }, + "EdgeCasePublicKey" : { + "bugType" : "EDGE_CASE", + "description" : "The test vector uses a special case public key. " + }, + "EdgeCaseShamirMultiplication" : { + "bugType" : "EDGE_CASE", + "description" : "Shamir proposed a fast method for computing the sum of two scalar multiplications efficiently. This test vector has been constructed so that an intermediate result is the point at infinity if Shamir's method is used." + }, + "IntegerOverflow" : { + "bugType" : "CAN_OF_WORMS", + "description" : "The test vector contains an r and s that has been modified, so that the original value is restored if the implementation ignores the most significant bits.", + "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + }, + "InvalidEncoding" : { + "bugType" : "CAN_OF_WORMS", + "description" : "ECDSA signatures are encoded using ASN.1. This test vector contains an incorrectly encoded signature. The test vector itself was generated from a valid signature by modifying its encoding.", + "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + }, + "InvalidSignature" : { + "bugType" : "AUTH_BYPASS", + "description" : "The signature contains special case values such as r=0 and s=0. Buggy implementations may accept such values, if the implementation does not check boundaries and computes s^(-1) == 0.", + "effect" : "Accepting such signatures can have the effect that an adversary can forge signatures without even knowning the message to sign.", + "cves" : [ + "CVE-2022-21449", + "CVE-2021-43572", + "CVE-2022-24884" + ] + }, + "InvalidTypesInSignature" : { + "bugType" : "AUTH_BYPASS", + "description" : "The signature contains invalid types. Dynamic typed languages sometime coerce such values of different types into integers. If an implementation is careless and has additional bugs, such as not checking integer boundaries then it may be possible that such signatures are accepted.", + "effect" : "Accepting such signatures can have the effect that an adversary can forge signatures without even knowning the message to sign.", + "cves" : [ + "CVE-2022-21449" + ] + }, + "ModifiedInteger" : { + "bugType" : "CAN_OF_WORMS", + "description" : "The test vector contains an r and s that has been modified. The goal is to check for arithmetic errors.", + "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + }, + "ModifiedSignature" : { + "bugType" : "CAN_OF_WORMS", + "description" : "The test vector contains an invalid signature that was generated from a valid signature by modifying it.", + "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + }, + "ModularInverse" : { + "bugType" : "EDGE_CASE", + "description" : "The test vectors contains a signature where computing the modular inverse of s hits an edge case.", + "effect" : "While the signature in this test vector is constructed and similar cases are unlikely to occur, it is important to determine if the underlying arithmetic error can be used to forge signatures.", + "cves" : [ + "CVE-2019-0865" + ] + }, + "PointDuplication" : { + "bugType" : "EDGE_CASE", + "description" : "Some implementations of ECDSA do not handle duplication and points at infinity correctly. This is a test vector that has been specially crafted to check for such an omission.", + "cves" : [ + "2020-12607", + "CVE-2015-2730" + ] + }, + "RangeCheck" : { + "bugType" : "CAN_OF_WORMS", + "description" : "The test vector contains an r and s that has been modified. By adding or subtracting the order of the group (or other values) the test vector checks whether signature verification verifies the range of r and s.", + "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + }, + "SignatureMalleabilityBitcoin" : { + "bugType" : "SIGNATURE_MALLEABILITY", + "description" : "\"BitCoins\"-curves are curves where signature malleability can be a serious issue. An implementation should only accept a signature s where s < n/2. If an implementation is not meant for uses cases that require signature malleability then this implemenation should be tested with another set of test vectors.", + "effect" : "In bitcoin exchanges, it may be used to make a double deposits or double withdrawals", + "links" : [ + "https://en.bitcoin.it/wiki/Transaction_malleability", + "https://en.bitcoinwiki.org/wiki/Transaction_Malleability" + ] + }, + "SmallRandS" : { + "bugType" : "EDGE_CASE", + "description" : "The test vectors contains a signature where both r and s are small integers. Some libraries cannot verify such signatures.", + "effect" : "While the signature in this test vector is constructed and similar cases are unlikely to occur, it is important to determine if the underlying arithmetic error can be used to forge signatures.", + "cves" : [ + "2020-13895" + ] + }, + "SpecialCaseHash" : { + "bugType" : "EDGE_CASE", + "description" : "The test vector contains a signature where the hash of the message is a special case, e.g., contains a long run of 0 or 1 bits." + }, + "ValidSignature" : { + "bugType" : "BASIC", + "description" : "The test vector contains a valid signature that was generated pseudorandomly. Such signatures should not fail to verify unless some of the parameters (e.g. curve or hash function) are not supported." + } + }, + "testGroups" : [ + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9", + "wx" : "00b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6f", + "wy" : "00f0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEuDj/ROW8F3vyEYnQdmCC/J2EMiaIf8l2\nA3EQC37iCm/wyddb+6ezGmvKGXRJbutW3jVwcZVdg8Sxutqgshgy6Q==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 1, + "comment" : "Signature malleability", + "flags" : [ + "SignatureMalleabilityBitcoin" + ], + "msg" : "313233343030", + "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022100900e75ad233fcc908509dbff5922647db37c21f4afd3203ae8dc4ae7794b0f87", + "result" : "invalid" + }, + { + "tcId" : 2, + "comment" : "valid", + "flags" : [ + "ValidSignature" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "valid" + }, + { + "tcId" : 3, + "comment" : "length of sequence [r, s] uses long form encoding", + "flags" : [ + "BerEncodedSignature" + ], + "msg" : "313233343030", + "sig" : "308145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 4, + "comment" : "length of sequence [r, s] contains a leading 0", + "flags" : [ + "BerEncodedSignature" + ], + "msg" : "313233343030", + "sig" : "30820045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 5, + "comment" : "length of sequence [r, s] uses 70 instead of 69", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 6, + "comment" : "length of sequence [r, s] uses 68 instead of 69", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 7, + "comment" : "uint32 overflow in length of sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30850100000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 8, + "comment" : "uint64 overflow in length of sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3089010000000000000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 9, + "comment" : "length of sequence [r, s] = 2**31 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30847fffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 10, + "comment" : "length of sequence [r, s] = 2**31", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "308480000000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 11, + "comment" : "length of sequence [r, s] = 2**32 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3084ffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 12, + "comment" : "length of sequence [r, s] = 2**40 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3085ffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 13, + "comment" : "length of sequence [r, s] = 2**64 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3088ffffffffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 14, + "comment" : "incorrect length of sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30ff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 15, + "comment" : "replaced sequence [r, s] by an indefinite length tag without termination", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 16, + "comment" : "removing sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "", + "result" : "invalid" + }, + { + "tcId" : 17, + "comment" : "lonely sequence tag", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30", + "result" : "invalid" + }, + { + "tcId" : 18, + "comment" : "appending 0's to sequence [r, s]", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result" : "invalid" + }, + { + "tcId" : 19, + "comment" : "prepending 0's to sequence [r, s]", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "30470000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 20, + "comment" : "appending unused 0's to sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result" : "invalid" + }, + { + "tcId" : 21, + "comment" : "appending null value to sequence [r, s]", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500", + "result" : "invalid" + }, + { + "tcId" : 22, + "comment" : "prepending garbage to sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304a4981773045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 23, + "comment" : "prepending garbage to sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304925003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 24, + "comment" : "appending garbage to sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef", + "result" : "invalid" + }, + { + "tcId" : 25, + "comment" : "including undefined tags", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "304daa00bb00cd003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 26, + "comment" : "including undefined tags", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304d2229aa00bb00cd00022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 27, + "comment" : "including undefined tags", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652228aa00bb00cd0002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 28, + "comment" : "truncated length of sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3081", + "result" : "invalid" + }, + { + "tcId" : 29, + "comment" : "including undefined tags to sequence [r, s]", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "304baa02aabb3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 30, + "comment" : "using composition with indefinite length for sequence [r, s]", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "30803045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result" : "invalid" + }, + { + "tcId" : 31, + "comment" : "using composition with wrong tag for sequence [r, s]", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "30803145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result" : "invalid" + }, + { + "tcId" : 32, + "comment" : "Replacing sequence [r, s] with NULL", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "0500", + "result" : "invalid" + }, + { + "tcId" : 33, + "comment" : "changing tag value of sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "2e45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 34, + "comment" : "changing tag value of sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "2f45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 35, + "comment" : "changing tag value of sequence [r, s]", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 36, + "comment" : "changing tag value of sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3245022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 37, + "comment" : "changing tag value of sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "ff45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 38, + "comment" : "dropping value of sequence [r, s]", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3000", + "result" : "invalid" + }, + { + "tcId" : 39, + "comment" : "using composition for sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304930010230442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 40, + "comment" : "truncated sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31", + "result" : "invalid" + }, + { + "tcId" : 41, + "comment" : "truncated sequence [r, s]", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 42, + "comment" : "sequence [r, s] of size 4166 to check for overflows", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30821046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "result" : "invalid" + }, + { + "tcId" : 43, + "comment" : "indefinite length", + "flags" : [ + "BerEncodedSignature" + ], + "msg" : "313233343030", + "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result" : "invalid" + }, + { + "tcId" : 44, + "comment" : "indefinite length with truncated delimiter", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba00", + "result" : "invalid" + }, + { + "tcId" : 45, + "comment" : "indefinite length with additional element", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba05000000", + "result" : "invalid" + }, + { + "tcId" : 46, + "comment" : "indefinite length with truncated element", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba060811220000", + "result" : "invalid" + }, + { + "tcId" : 47, + "comment" : "indefinite length with garbage", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000fe02beef", + "result" : "invalid" + }, + { + "tcId" : 48, + "comment" : "indefinite length with nonempty EOC", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0002beef", + "result" : "invalid" + }, + { + "tcId" : 49, + "comment" : "prepend empty sequence", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "30473000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 50, + "comment" : "append empty sequence", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba3000", + "result" : "invalid" + }, + { + "tcId" : 51, + "comment" : "append zero", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba020100", + "result" : "invalid" + }, + { + "tcId" : 52, + "comment" : "append garbage with high tag number", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31babf7f00", + "result" : "invalid" + }, + { + "tcId" : 53, + "comment" : "append null with explicit tag", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31baa0020500", + "result" : "invalid" + }, + { + "tcId" : 54, + "comment" : "append null with implicit tag", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31baa000", + "result" : "invalid" + }, + { + "tcId" : 55, + "comment" : "sequence of sequence", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 56, + "comment" : "truncated sequence: removed last 1 elements", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3023022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365", + "result" : "invalid" + }, + { + "tcId" : 57, + "comment" : "repeating element in sequence", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3067022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 58, + "comment" : "flipped bit 0 in r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 59, + "comment" : "flipped bit 32 in r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccac983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 60, + "comment" : "flipped bit 48 in r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5133ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 61, + "comment" : "flipped bit 64 in r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc08b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 62, + "comment" : "length of r uses long form encoding", + "flags" : [ + "BerEncodedSignature" + ], + "msg" : "313233343030", + "sig" : "304602812100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 63, + "comment" : "length of r contains a leading 0", + "flags" : [ + "BerEncodedSignature" + ], + "msg" : "313233343030", + "sig" : "30470282002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 64, + "comment" : "length of r uses 34 instead of 33", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 65, + "comment" : "length of r uses 32 instead of 33", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 66, + "comment" : "uint32 overflow in length of r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304a0285010000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 67, + "comment" : "uint64 overflow in length of r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304e028901000000000000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 68, + "comment" : "length of r = 2**31 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304902847fffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 69, + "comment" : "length of r = 2**31", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304902848000000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 70, + "comment" : "length of r = 2**32 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30490284ffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 71, + "comment" : "length of r = 2**40 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304a0285ffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 72, + "comment" : "length of r = 2**64 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304d0288ffffffffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 73, + "comment" : "incorrect length of r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304502ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 74, + "comment" : "replaced r by an indefinite length tag without termination", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045028000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 75, + "comment" : "removing r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "302202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 76, + "comment" : "lonely integer tag", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30230202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 77, + "comment" : "lonely integer tag", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3024022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502", + "result" : "invalid" + }, + { + "tcId" : 78, + "comment" : "appending 0's to r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 79, + "comment" : "prepending 0's to r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30470223000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 80, + "comment" : "appending unused 0's to r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 81, + "comment" : "appending null value to r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 82, + "comment" : "prepending garbage to r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304a2226498177022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 83, + "comment" : "prepending garbage to r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304922252500022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 84, + "comment" : "appending garbage to r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304d2223022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650004deadbeef02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 85, + "comment" : "truncated length of r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3024028102206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 86, + "comment" : "including undefined tags to r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304b2227aa02aabb022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 87, + "comment" : "using composition with indefinite length for r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30492280022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 88, + "comment" : "using composition with wrong tag for r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "30492280032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 89, + "comment" : "Replacing r with NULL", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3024050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 90, + "comment" : "changing tag value of r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 91, + "comment" : "changing tag value of r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045012100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 92, + "comment" : "changing tag value of r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 93, + "comment" : "changing tag value of r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045042100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 94, + "comment" : "changing tag value of r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045ff2100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 95, + "comment" : "dropping value of r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3024020002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 96, + "comment" : "using composition for r", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304922250201000220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 97, + "comment" : "modifying first byte of r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045022102813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 98, + "comment" : "modifying last byte of r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323e502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 99, + "comment" : "truncated r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3044022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832302206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 100, + "comment" : "truncated r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "30440220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 101, + "comment" : "r of size 4130 to check for overflows", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "308210480282102200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 102, + "comment" : "leading ff in r", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "30460222ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 103, + "comment" : "replaced r by infinity", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "302509018002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 104, + "comment" : "replacing r with zero", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "302502010002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 105, + "comment" : "flipped bit 0 in s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31bb", + "result" : "invalid" + }, + { + "tcId" : 106, + "comment" : "flipped bit 32 in s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a456eb31ba", + "result" : "invalid" + }, + { + "tcId" : 107, + "comment" : "flipped bit 48 in s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f713a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 108, + "comment" : "flipped bit 64 in s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758001d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 109, + "comment" : "length of s uses long form encoding", + "flags" : [ + "BerEncodedSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 110, + "comment" : "length of s contains a leading 0", + "flags" : [ + "BerEncodedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028200206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 111, + "comment" : "length of s uses 33 instead of 32", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 112, + "comment" : "length of s uses 31 instead of 32", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 113, + "comment" : "uint32 overflow in length of s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028501000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 114, + "comment" : "uint64 overflow in length of s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304e022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502890100000000000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 115, + "comment" : "length of s = 2**31 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502847fffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 116, + "comment" : "length of s = 2**31", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284800000006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 117, + "comment" : "length of s = 2**32 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284ffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 118, + "comment" : "length of s = 2**40 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650285ffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 119, + "comment" : "length of s = 2**64 - 1", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650288ffffffffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 120, + "comment" : "incorrect length of s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 121, + "comment" : "replaced s by an indefinite length tag without termination", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502806ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 122, + "comment" : "appending 0's to s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result" : "invalid" + }, + { + "tcId" : 123, + "comment" : "prepending 0's to s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022200006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 124, + "comment" : "appending null value to s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500", + "result" : "invalid" + }, + { + "tcId" : 125, + "comment" : "prepending garbage to s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222549817702206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 126, + "comment" : "prepending garbage to s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652224250002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 127, + "comment" : "appending garbage to s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef", + "result" : "invalid" + }, + { + "tcId" : 128, + "comment" : "truncated length of s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281", + "result" : "invalid" + }, + { + "tcId" : 129, + "comment" : "including undefined tags to s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "304b022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652226aa02aabb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 130, + "comment" : "using composition with indefinite length for s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result" : "invalid" + }, + { + "tcId" : 131, + "comment" : "using composition with wrong tag for s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228003206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result" : "invalid" + }, + { + "tcId" : 132, + "comment" : "Replacing s with NULL", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650500", + "result" : "invalid" + }, + { + "tcId" : 133, + "comment" : "changing tag value of s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236500206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 134, + "comment" : "changing tag value of s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236501206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 135, + "comment" : "changing tag value of s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236503206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 136, + "comment" : "changing tag value of s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236504206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 137, + "comment" : "changing tag value of s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365ff206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 138, + "comment" : "dropping value of s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650200", + "result" : "invalid" + }, + { + "tcId" : 139, + "comment" : "using composition for s", + "flags" : [ + "InvalidEncoding" + ], + "msg" : "313233343030", + "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222402016f021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 140, + "comment" : "modifying first byte of s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206df18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 141, + "comment" : "modifying last byte of s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb313a", + "result" : "invalid" + }, + { + "tcId" : 142, + "comment" : "truncated s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31", + "result" : "invalid" + }, + { + "tcId" : 143, + "comment" : "truncated s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 144, + "comment" : "s of size 4129 to check for overflows", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "30821048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028210216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "result" : "invalid" + }, + { + "tcId" : 145, + "comment" : "leading ff in s", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 146, + "comment" : "replaced s by infinity", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365090180", + "result" : "invalid" + }, + { + "tcId" : 147, + "comment" : "replacing s with zero", + "flags" : [ + "ModifiedSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365020100", + "result" : "invalid" + }, + { + "tcId" : 148, + "comment" : "replaced r by r + n", + "flags" : [ + "RangeCheck" + ], + "msg" : "313233343030", + "sig" : "3045022101813ef79ccefa9a56f7ba805f0e478583b90deabca4b05c4574e49b5899b964a602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 149, + "comment" : "replaced r by r - n", + "flags" : [ + "RangeCheck" + ], + "msg" : "313233343030", + "sig" : "30440220813ef79ccefa9a56f7ba805f0e47858643b030ef461f1bcdf53fde3ef94ce22402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 150, + "comment" : "replaced r by r + 256 * n", + "flags" : [ + "RangeCheck" + ], + "msg" : "313233343030", + "sig" : "304602220100813ef79ccefa9a56f7ba805f0e47843fad3bf4853e07f7c98770c99bffc4646502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 151, + "comment" : "replaced r by -r", + "flags" : [ + "ModifiedInteger" + ], + "msg" : "313233343030", + "sig" : "30450221ff7ec10863310565a908457fa0f1b87a7b01a0f22a0a9843f64aedc334367cdc9b02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 152, + "comment" : "replaced r by n - r", + "flags" : [ + "ModifiedInteger" + ], + "msg" : "313233343030", + "sig" : "304402207ec10863310565a908457fa0f1b87a79bc4fcf10b9e0e4320ac021c106b31ddc02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 153, + "comment" : "replaced r by -n - r", + "flags" : [ + "ModifiedInteger" + ], + "msg" : "313233343030", + "sig" : "30450221fe7ec10863310565a908457fa0f1b87a7c46f215435b4fa3ba8b1b64a766469b5a02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 154, + "comment" : "replaced r by r + 2**256", + "flags" : [ + "IntegerOverflow" + ], + "msg" : "313233343030", + "sig" : "3045022101813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 155, + "comment" : "replaced r by r + 2**320", + "flags" : [ + "IntegerOverflow" + ], + "msg" : "313233343030", + "sig" : "304d0229010000000000000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 156, + "comment" : "replaced s by s + n", + "flags" : [ + "RangeCheck" + ], + "msg" : "313233343030", + "sig" : "30450221016ff18a52dcc0336f7af62400a6dd9b7fc1e197d8aebe203c96c87232272172fb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 157, + "comment" : "replaced s by s - n", + "flags" : [ + "RangeCheck" + ], + "msg" : "313233343030", + "sig" : "30450221ff6ff18a52dcc0336f7af62400a6dd9b824c83de0b502cdfc51723b51886b4f07902206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 158, + "comment" : "replaced s by s + 256 * n", + "flags" : [ + "RangeCheck" + ], + "msg" : "313233343030", + "sig" : "3046022201006ff18a52dcc0336f7af62400a6dd9a3bb60fa1a14815bbc0a954a0758d2c72ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 159, + "comment" : "replaced s by -s", + "flags" : [ + "ModifiedInteger" + ], + "msg" : "313233343030", + "sig" : "30440220900e75ad233fcc908509dbff5922647ef8cd450e008a7fff2909ec5aa914ce4602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 160, + "comment" : "replaced s by -n - s", + "flags" : [ + "ModifiedInteger" + ], + "msg" : "313233343030", + "sig" : "30450221fe900e75ad233fcc908509dbff592264803e1e68275141dfc369378dcdd8de8d0502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 161, + "comment" : "replaced s by s + 2**256", + "flags" : [ + "IntegerOverflow" + ], + "msg" : "313233343030", + "sig" : "30450221016ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 162, + "comment" : "replaced s by s - 2**256", + "flags" : [ + "IntegerOverflow" + ], + "msg" : "313233343030", + "sig" : "30450221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 163, + "comment" : "replaced s by s + 2**320", + "flags" : [ + "IntegerOverflow" + ], + "msg" : "313233343030", + "sig" : "304d02290100000000000000006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result" : "invalid" + }, + { + "tcId" : 164, + "comment" : "Signature with special case values r=0 and s=0", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3006020100020100", + "result" : "invalid" + }, + { + "tcId" : 165, + "comment" : "Signature with special case values r=0 and s=1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3006020100020101", + "result" : "invalid" + }, + { + "tcId" : 166, + "comment" : "Signature with special case values r=0 and s=-1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30060201000201ff", + "result" : "invalid" + }, + { + "tcId" : 167, + "comment" : "Signature with special case values r=0 and s=n", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result" : "invalid" + }, + { + "tcId" : 168, + "comment" : "Signature with special case values r=0 and s=n - 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result" : "invalid" + }, + { + "tcId" : 169, + "comment" : "Signature with special case values r=0 and s=n + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result" : "invalid" + }, + { + "tcId" : 170, + "comment" : "Signature with special case values r=0 and s=p", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result" : "invalid" + }, + { + "tcId" : 171, + "comment" : "Signature with special case values r=0 and s=p + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result" : "invalid" + }, + { + "tcId" : 172, + "comment" : "Signature with special case values r=1 and s=0", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3006020101020100", + "result" : "invalid" + }, + { + "tcId" : 173, + "comment" : "Signature with special case values r=1 and s=1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3006020101020101", + "result" : "invalid" + }, + { + "tcId" : 174, + "comment" : "Signature with special case values r=1 and s=-1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30060201010201ff", + "result" : "invalid" + }, + { + "tcId" : 175, + "comment" : "Signature with special case values r=1 and s=n", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result" : "invalid" + }, + { + "tcId" : 176, + "comment" : "Signature with special case values r=1 and s=n - 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result" : "invalid" + }, + { + "tcId" : 177, + "comment" : "Signature with special case values r=1 and s=n + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result" : "invalid" + }, + { + "tcId" : 178, + "comment" : "Signature with special case values r=1 and s=p", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result" : "invalid" + }, + { + "tcId" : 179, + "comment" : "Signature with special case values r=1 and s=p + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result" : "invalid" + }, + { + "tcId" : 180, + "comment" : "Signature with special case values r=-1 and s=0", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30060201ff020100", + "result" : "invalid" + }, + { + "tcId" : 181, + "comment" : "Signature with special case values r=-1 and s=1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30060201ff020101", + "result" : "invalid" + }, + { + "tcId" : 182, + "comment" : "Signature with special case values r=-1 and s=-1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30060201ff0201ff", + "result" : "invalid" + }, + { + "tcId" : 183, + "comment" : "Signature with special case values r=-1 and s=n", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result" : "invalid" + }, + { + "tcId" : 184, + "comment" : "Signature with special case values r=-1 and s=n - 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result" : "invalid" + }, + { + "tcId" : 185, + "comment" : "Signature with special case values r=-1 and s=n + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result" : "invalid" + }, + { + "tcId" : 186, + "comment" : "Signature with special case values r=-1 and s=p", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result" : "invalid" + }, + { + "tcId" : 187, + "comment" : "Signature with special case values r=-1 and s=p + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result" : "invalid" + }, + { + "tcId" : 188, + "comment" : "Signature with special case values r=n and s=0", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020100", + "result" : "invalid" + }, + { + "tcId" : 189, + "comment" : "Signature with special case values r=n and s=1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101", + "result" : "invalid" + }, + { + "tcId" : 190, + "comment" : "Signature with special case values r=n and s=-1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410201ff", + "result" : "invalid" + }, + { + "tcId" : 191, + "comment" : "Signature with special case values r=n and s=n", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result" : "invalid" + }, + { + "tcId" : 192, + "comment" : "Signature with special case values r=n and s=n - 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result" : "invalid" + }, + { + "tcId" : 193, + "comment" : "Signature with special case values r=n and s=n + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result" : "invalid" + }, + { + "tcId" : 194, + "comment" : "Signature with special case values r=n and s=p", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result" : "invalid" + }, + { + "tcId" : 195, + "comment" : "Signature with special case values r=n and s=p + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result" : "invalid" + }, + { + "tcId" : 196, + "comment" : "Signature with special case values r=n - 1 and s=0", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020100", + "result" : "invalid" + }, + { + "tcId" : 197, + "comment" : "Signature with special case values r=n - 1 and s=1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020101", + "result" : "invalid" + }, + { + "tcId" : 198, + "comment" : "Signature with special case values r=n - 1 and s=-1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641400201ff", + "result" : "invalid" + }, + { + "tcId" : 199, + "comment" : "Signature with special case values r=n - 1 and s=n", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result" : "invalid" + }, + { + "tcId" : 200, + "comment" : "Signature with special case values r=n - 1 and s=n - 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result" : "invalid" + }, + { + "tcId" : 201, + "comment" : "Signature with special case values r=n - 1 and s=n + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result" : "invalid" + }, + { + "tcId" : 202, + "comment" : "Signature with special case values r=n - 1 and s=p", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result" : "invalid" + }, + { + "tcId" : 203, + "comment" : "Signature with special case values r=n - 1 and s=p + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result" : "invalid" + }, + { + "tcId" : 204, + "comment" : "Signature with special case values r=n + 1 and s=0", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020100", + "result" : "invalid" + }, + { + "tcId" : 205, + "comment" : "Signature with special case values r=n + 1 and s=1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020101", + "result" : "invalid" + }, + { + "tcId" : 206, + "comment" : "Signature with special case values r=n + 1 and s=-1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641420201ff", + "result" : "invalid" + }, + { + "tcId" : 207, + "comment" : "Signature with special case values r=n + 1 and s=n", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result" : "invalid" + }, + { + "tcId" : 208, + "comment" : "Signature with special case values r=n + 1 and s=n - 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result" : "invalid" + }, + { + "tcId" : 209, + "comment" : "Signature with special case values r=n + 1 and s=n + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result" : "invalid" + }, + { + "tcId" : 210, + "comment" : "Signature with special case values r=n + 1 and s=p", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result" : "invalid" + }, + { + "tcId" : 211, + "comment" : "Signature with special case values r=n + 1 and s=p + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result" : "invalid" + }, + { + "tcId" : 212, + "comment" : "Signature with special case values r=p and s=0", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020100", + "result" : "invalid" + }, + { + "tcId" : 213, + "comment" : "Signature with special case values r=p and s=1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020101", + "result" : "invalid" + }, + { + "tcId" : 214, + "comment" : "Signature with special case values r=p and s=-1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0201ff", + "result" : "invalid" + }, + { + "tcId" : 215, + "comment" : "Signature with special case values r=p and s=n", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result" : "invalid" + }, + { + "tcId" : 216, + "comment" : "Signature with special case values r=p and s=n - 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result" : "invalid" + }, + { + "tcId" : 217, + "comment" : "Signature with special case values r=p and s=n + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result" : "invalid" + }, + { + "tcId" : 218, + "comment" : "Signature with special case values r=p and s=p", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result" : "invalid" + }, + { + "tcId" : 219, + "comment" : "Signature with special case values r=p and s=p + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result" : "invalid" + }, + { + "tcId" : 220, + "comment" : "Signature with special case values r=p + 1 and s=0", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020100", + "result" : "invalid" + }, + { + "tcId" : 221, + "comment" : "Signature with special case values r=p + 1 and s=1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020101", + "result" : "invalid" + }, + { + "tcId" : 222, + "comment" : "Signature with special case values r=p + 1 and s=-1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc300201ff", + "result" : "invalid" + }, + { + "tcId" : 223, + "comment" : "Signature with special case values r=p + 1 and s=n", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result" : "invalid" + }, + { + "tcId" : 224, + "comment" : "Signature with special case values r=p + 1 and s=n - 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result" : "invalid" + }, + { + "tcId" : 225, + "comment" : "Signature with special case values r=p + 1 and s=n + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result" : "invalid" + }, + { + "tcId" : 226, + "comment" : "Signature with special case values r=p + 1 and s=p", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result" : "invalid" + }, + { + "tcId" : 227, + "comment" : "Signature with special case values r=p + 1 and s=p + 1", + "flags" : [ + "InvalidSignature" + ], + "msg" : "313233343030", + "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result" : "invalid" + }, + { + "tcId" : 228, + "comment" : "Signature encoding contains incorrect types: r=0, s=0.25", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3008020100090380fe01", + "result" : "invalid" + }, + { + "tcId" : 229, + "comment" : "Signature encoding contains incorrect types: r=0, s=nan", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006020100090142", + "result" : "invalid" + }, + { + "tcId" : 230, + "comment" : "Signature encoding contains incorrect types: r=0, s=True", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006020100010101", + "result" : "invalid" + }, + { + "tcId" : 231, + "comment" : "Signature encoding contains incorrect types: r=0, s=False", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006020100010100", + "result" : "invalid" + }, + { + "tcId" : 232, + "comment" : "Signature encoding contains incorrect types: r=0, s=Null", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201000500", + "result" : "invalid" + }, + { + "tcId" : 233, + "comment" : "Signature encoding contains incorrect types: r=0, s=empyt UTF-8 string", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201000c00", + "result" : "invalid" + }, + { + "tcId" : 234, + "comment" : "Signature encoding contains incorrect types: r=0, s=\"0\"", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30060201000c0130", + "result" : "invalid" + }, + { + "tcId" : 235, + "comment" : "Signature encoding contains incorrect types: r=0, s=empty list", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201003000", + "result" : "invalid" + }, + { + "tcId" : 236, + "comment" : "Signature encoding contains incorrect types: r=0, s=list containing 0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30080201003003020100", + "result" : "invalid" + }, + { + "tcId" : 237, + "comment" : "Signature encoding contains incorrect types: r=1, s=0.25", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3008020101090380fe01", + "result" : "invalid" + }, + { + "tcId" : 238, + "comment" : "Signature encoding contains incorrect types: r=1, s=nan", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006020101090142", + "result" : "invalid" + }, + { + "tcId" : 239, + "comment" : "Signature encoding contains incorrect types: r=1, s=True", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006020101010101", + "result" : "invalid" + }, + { + "tcId" : 240, + "comment" : "Signature encoding contains incorrect types: r=1, s=False", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006020101010100", + "result" : "invalid" + }, + { + "tcId" : 241, + "comment" : "Signature encoding contains incorrect types: r=1, s=Null", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201010500", + "result" : "invalid" + }, + { + "tcId" : 242, + "comment" : "Signature encoding contains incorrect types: r=1, s=empyt UTF-8 string", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201010c00", + "result" : "invalid" + }, + { + "tcId" : 243, + "comment" : "Signature encoding contains incorrect types: r=1, s=\"0\"", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30060201010c0130", + "result" : "invalid" + }, + { + "tcId" : 244, + "comment" : "Signature encoding contains incorrect types: r=1, s=empty list", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201013000", + "result" : "invalid" + }, + { + "tcId" : 245, + "comment" : "Signature encoding contains incorrect types: r=1, s=list containing 0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30080201013003020100", + "result" : "invalid" + }, + { + "tcId" : 246, + "comment" : "Signature encoding contains incorrect types: r=-1, s=0.25", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30080201ff090380fe01", + "result" : "invalid" + }, + { + "tcId" : 247, + "comment" : "Signature encoding contains incorrect types: r=-1, s=nan", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30060201ff090142", + "result" : "invalid" + }, + { + "tcId" : 248, + "comment" : "Signature encoding contains incorrect types: r=-1, s=True", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30060201ff010101", + "result" : "invalid" + }, + { + "tcId" : 249, + "comment" : "Signature encoding contains incorrect types: r=-1, s=False", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30060201ff010100", + "result" : "invalid" + }, + { + "tcId" : 250, + "comment" : "Signature encoding contains incorrect types: r=-1, s=Null", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201ff0500", + "result" : "invalid" + }, + { + "tcId" : 251, + "comment" : "Signature encoding contains incorrect types: r=-1, s=empyt UTF-8 string", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201ff0c00", + "result" : "invalid" + }, + { + "tcId" : 252, + "comment" : "Signature encoding contains incorrect types: r=-1, s=\"0\"", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30060201ff0c0130", + "result" : "invalid" + }, + { + "tcId" : 253, + "comment" : "Signature encoding contains incorrect types: r=-1, s=empty list", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050201ff3000", + "result" : "invalid" + }, + { + "tcId" : 254, + "comment" : "Signature encoding contains incorrect types: r=-1, s=list containing 0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30080201ff3003020100", + "result" : "invalid" + }, + { + "tcId" : 255, + "comment" : "Signature encoding contains incorrect types: r=n, s=0.25", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090380fe01", + "result" : "invalid" + }, + { + "tcId" : 256, + "comment" : "Signature encoding contains incorrect types: r=n, s=nan", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090142", + "result" : "invalid" + }, + { + "tcId" : 257, + "comment" : "Signature encoding contains incorrect types: r=n, s=True", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141010101", + "result" : "invalid" + }, + { + "tcId" : 258, + "comment" : "Signature encoding contains incorrect types: r=n, s=False", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141010100", + "result" : "invalid" + }, + { + "tcId" : 259, + "comment" : "Signature encoding contains incorrect types: r=n, s=Null", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410500", + "result" : "invalid" + }, + { + "tcId" : 260, + "comment" : "Signature encoding contains incorrect types: r=n, s=empyt UTF-8 string", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410c00", + "result" : "invalid" + }, + { + "tcId" : 261, + "comment" : "Signature encoding contains incorrect types: r=n, s=\"0\"", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410c0130", + "result" : "invalid" + }, + { + "tcId" : 262, + "comment" : "Signature encoding contains incorrect types: r=n, s=empty list", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641413000", + "result" : "invalid" + }, + { + "tcId" : 263, + "comment" : "Signature encoding contains incorrect types: r=n, s=list containing 0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641413003020100", + "result" : "invalid" + }, + { + "tcId" : 264, + "comment" : "Signature encoding contains incorrect types: r=p, s=0.25", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090380fe01", + "result" : "invalid" + }, + { + "tcId" : 265, + "comment" : "Signature encoding contains incorrect types: r=p, s=nan", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090142", + "result" : "invalid" + }, + { + "tcId" : 266, + "comment" : "Signature encoding contains incorrect types: r=p, s=True", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f010101", + "result" : "invalid" + }, + { + "tcId" : 267, + "comment" : "Signature encoding contains incorrect types: r=p, s=False", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f010100", + "result" : "invalid" + }, + { + "tcId" : 268, + "comment" : "Signature encoding contains incorrect types: r=p, s=Null", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0500", + "result" : "invalid" + }, + { + "tcId" : 269, + "comment" : "Signature encoding contains incorrect types: r=p, s=empyt UTF-8 string", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0c00", + "result" : "invalid" + }, + { + "tcId" : 270, + "comment" : "Signature encoding contains incorrect types: r=p, s=\"0\"", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0c0130", + "result" : "invalid" + }, + { + "tcId" : 271, + "comment" : "Signature encoding contains incorrect types: r=p, s=empty list", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f3000", + "result" : "invalid" + }, + { + "tcId" : 272, + "comment" : "Signature encoding contains incorrect types: r=p, s=list containing 0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f3003020100", + "result" : "invalid" + }, + { + "tcId" : 273, + "comment" : "Signature encoding contains incorrect types: r=0.25, s=0.25", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "300a090380fe01090380fe01", + "result" : "invalid" + }, + { + "tcId" : 274, + "comment" : "Signature encoding contains incorrect types: r=nan, s=nan", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006090142090142", + "result" : "invalid" + }, + { + "tcId" : 275, + "comment" : "Signature encoding contains incorrect types: r=True, s=True", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006010101010101", + "result" : "invalid" + }, + { + "tcId" : 276, + "comment" : "Signature encoding contains incorrect types: r=False, s=False", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006010100010100", + "result" : "invalid" + }, + { + "tcId" : 277, + "comment" : "Signature encoding contains incorrect types: r=Null, s=Null", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "300405000500", + "result" : "invalid" + }, + { + "tcId" : 278, + "comment" : "Signature encoding contains incorrect types: r=empyt UTF-8 string, s=empyt UTF-8 string", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30040c000c00", + "result" : "invalid" + }, + { + "tcId" : 279, + "comment" : "Signature encoding contains incorrect types: r=\"0\", s=\"0\"", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30060c01300c0130", + "result" : "invalid" + }, + { + "tcId" : 280, + "comment" : "Signature encoding contains incorrect types: r=empty list, s=empty list", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "300430003000", + "result" : "invalid" + }, + { + "tcId" : 281, + "comment" : "Signature encoding contains incorrect types: r=list containing 0, s=list containing 0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "300a30030201003003020100", + "result" : "invalid" + }, + { + "tcId" : 282, + "comment" : "Signature encoding contains incorrect types: r=0.25, s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3008090380fe01020100", + "result" : "invalid" + }, + { + "tcId" : 283, + "comment" : "Signature encoding contains incorrect types: r=nan, s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006090142020100", + "result" : "invalid" + }, + { + "tcId" : 284, + "comment" : "Signature encoding contains incorrect types: r=True, s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006010101020100", + "result" : "invalid" + }, + { + "tcId" : 285, + "comment" : "Signature encoding contains incorrect types: r=False, s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "3006010100020100", + "result" : "invalid" + }, + { + "tcId" : 286, + "comment" : "Signature encoding contains incorrect types: r=Null, s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050500020100", + "result" : "invalid" + }, + { + "tcId" : 287, + "comment" : "Signature encoding contains incorrect types: r=empyt UTF-8 string, s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30050c00020100", + "result" : "invalid" + }, + { + "tcId" : 288, + "comment" : "Signature encoding contains incorrect types: r=\"0\", s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30060c0130020100", + "result" : "invalid" + }, + { + "tcId" : 289, + "comment" : "Signature encoding contains incorrect types: r=empty list, s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30053000020100", + "result" : "invalid" + }, + { + "tcId" : 290, + "comment" : "Signature encoding contains incorrect types: r=list containing 0, s=0", + "flags" : [ + "InvalidTypesInSignature" + ], + "msg" : "313233343030", + "sig" : "30083003020100020100", + "result" : "invalid" + }, + { + "tcId" : 291, + "comment" : "Edge case for Shamir multiplication", + "flags" : [ + "EdgeCaseShamirMultiplication" + ], + "msg" : "3235353835", + "sig" : "3045022100dd1b7d09a7bd8218961034a39a87fecf5314f00c4d25eb58a07ac85e85eab516022035138c401ef8d3493d65c9002fe62b43aee568731b744548358996d9cc427e06", + "result" : "valid" + }, + { + "tcId" : 292, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "343236343739373234", + "sig" : "304502210095c29267d972a043d955224546222bba343fc1d4db0fec262a33ac61305696ae02206edfe96713aed56f8a28a6653f57e0b829712e5eddc67f34682b24f0676b2640", + "result" : "valid" + }, + { + "tcId" : 293, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "37313338363834383931", + "sig" : "3044022028f94a894e92024699e345fe66971e3edcd050023386135ab3939d550898fb25022032963e5bd41fa5911ed8f37deb86dae0a762bb6121c894615083c5d95ea01db3", + "result" : "valid" + }, + { + "tcId" : 294, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "3130333539333331363638", + "sig" : "3045022100be26b18f9549f89f411a9b52536b15aa270b84548d0e859a1952a27af1a77ac6022070c1d4fa9cd03cc8eaa8d506edb97eed7b8358b453c88aefbb880a3f0e8d472f", + "result" : "valid" + }, + { + "tcId" : 295, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33393439343031323135", + "sig" : "3045022100b1a4b1478e65cc3eafdf225d1298b43f2da19e4bcff7eacc0a2e98cd4b74b1140220179aa31e304cc142cf5073171751b28f3f5e0fa88c994e7c55f1bc07b8d56c16", + "result" : "valid" + }, + { + "tcId" : 296, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31333434323933303739", + "sig" : "30440220325332021261f1bd18f2712aa1e2252da23796da8a4b1ff6ea18cafec7e171f2022040b4f5e287ee61fc3c804186982360891eaa35c75f05a43ecd48b35d984a6648", + "result" : "valid" + }, + { + "tcId" : 297, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33373036323131373132", + "sig" : "3045022100a23ad18d8fc66d81af0903890cbd453a554cb04cdc1a8ca7f7f78e5367ed88a0022023e3eb2ce1c04ea748c389bd97374aa9413b9268851c04dcd9f88e78813fee56", + "result" : "valid" + }, + { + "tcId" : 298, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "333433363838373132", + "sig" : "304402202bdea41cda63a2d14bf47353bd20880a690901de7cd6e3cc6d8ed5ba0cdb109102203cea66bccfc9f9bf8c7ca4e1c1457cc9145e13e936d90b3d9c7786b8b26cf4c7", + "result" : "valid" + }, + { + "tcId" : 299, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31333531353330333730", + "sig" : "3045022100d7cd76ec01c1b1079eba9e2aa2a397243c4758c98a1ba0b7404a340b9b00ced602203575001e19d922e6de8b3d6c84ea43b5c3338106cf29990134e7669a826f78e6", + "result" : "valid" + }, + { + "tcId" : 300, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "36353533323033313236", + "sig" : "3045022100a872c744d936db21a10c361dd5c9063355f84902219652f6fc56dc95a7139d960220400df7575d9756210e9ccc77162c6b593c7746cfb48ac263c42750b421ef4bb9", + "result" : "valid" + }, + { + "tcId" : 301, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31353634333436363033", + "sig" : "30450221009fa9afe07752da10b36d3afcd0fe44bfc40244d75203599cf8f5047fa3453854022050e0a7c013bfbf51819736972d44b4b56bc2a2b2c180df6ec672df171410d77a", + "result" : "valid" + }, + { + "tcId" : 302, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "34343239353339313137", + "sig" : "3045022100885640384d0d910efb177b46be6c3dc5cac81f0b88c3190bb6b5f99c2641f2050220738ed9bff116306d9caa0f8fc608be243e0b567779d8dab03e8e19d553f1dc8e", + "result" : "valid" + }, + { + "tcId" : 303, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "3130393533323631333531", + "sig" : "304402202d051f91c5a9d440c5676985710483bc4f1a6c611b10c95a2ff0363d90c2a45802206ddf94e6fba5be586833d0c53cf216ad3948f37953c26c1cf4968e9a9e8243dc", + "result" : "valid" + }, + { + "tcId" : 304, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "35393837333530303431", + "sig" : "3045022100f3ac2523967482f53d508522712d583f4379cd824101ff635ea0935117baa54f022027f10812227397e02cea96fb0e680761636dab2b080d1fc5d11685cbe8500cfe", + "result" : "valid" + }, + { + "tcId" : 305, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33343633303036383738", + "sig" : "304502210096447cf68c3ab7266ed7447de3ac52fed7cc08cbdfea391c18a9b8ab370bc91302200f5e7874d3ac0e918f01c885a1639177c923f8660d1ceba1ca1f301bc675cdbc", + "result" : "valid" + }, + { + "tcId" : 306, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "39383137333230323837", + "sig" : "30440220530a0832b691da0b5619a0b11de6877f3c0971baaa68ed122758c29caaf46b7202206c89e44f5eb33060ea4b46318c39138eaedec72de42ba576579a6a4690e339f3", + "result" : "valid" + }, + { + "tcId" : 307, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33323232303431303436", + "sig" : "30450221009c54c25500bde0b92d72d6ec483dc2482f3654294ca74de796b681255ed58a770220677453c6b56f527631c9f67b3f3eb621fd88582b4aff156d2f1567d6211a2a33", + "result" : "valid" + }, + { + "tcId" : 308, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "36363636333037313034", + "sig" : "3045022100e7909d41439e2f6af29136c7348ca2641a2b070d5b64f91ea9da7070c7a2618b022042d782f132fa1d36c2c88ba27c3d678d80184a5d1eccac7501f0b47e3d205008", + "result" : "valid" + }, + { + "tcId" : 309, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31303335393531383938", + "sig" : "304402205924873209593135a4c3da7bb381227f8a4b6aa9f34fe5bb7f8fbc131a039ffe02201f1bb11b441c8feaa40f44213d9a405ed792d59fb49d5bcdd9a4285ae5693022", + "result" : "valid" + }, + { + "tcId" : 310, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31383436353937313935", + "sig" : "3045022100eeb692c9b262969b231c38b5a7f60649e0c875cd64df88f33aa571fa3d29ab0e0220218b3a1eb06379c2c18cf51b06430786d1c64cd2d24c9b232b23e5bac7989acd", + "result" : "valid" + }, + { + "tcId" : 311, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33313336303436313839", + "sig" : "3045022100a40034177f36091c2b653684a0e3eb5d4bff18e4d09f664c2800e7cafda1daf802203a3ec29853704e52031c58927a800a968353adc3d973beba9172cbbeab4dd149", + "result" : "valid" + }, + { + "tcId" : 312, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "32363633373834323534", + "sig" : "3045022100b5d795cc75cea5c434fa4185180cd6bd21223f3d5a86da6670d71d95680dadbf022054e4d8810a001ecbb9f7ca1c2ebfdb9d009e9031a431aca3c20ab4e0d1374ec1", + "result" : "valid" + }, + { + "tcId" : 313, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31363532313030353234", + "sig" : "3044022007dc2478d43c1232a4595608c64426c35510051a631ae6a5a6eb1161e57e42e102204a59ea0fdb72d12165cea3bf1ca86ba97517bd188db3dbd21a5a157850021984", + "result" : "valid" + }, + { + "tcId" : 314, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "35373438303831363936", + "sig" : "3045022100ddd20c4a05596ca868b558839fce9f6511ddd83d1ccb53f82e5269d559a0155202205b91734729d93093ff22123c4a25819d7feb66a250663fc780cb66fc7b6e6d17", + "result" : "valid" + }, + { + "tcId" : 315, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "36333433393133343638", + "sig" : "30450221009cde6e0ede0a003f02fda0a01b59facfe5dec063318f279ce2de7a9b1062f7b702202886a5b8c679bdf8224c66f908fd6205492cb70b0068d46ae4f33a4149b12a52", + "result" : "valid" + }, + { + "tcId" : 316, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31353431313033353938", + "sig" : "3045022100c5771016d0dd6357143c89f684cd740423502554c0c59aa8c99584f1ff38f609022054b405f4477546686e464c5463b4fd4190572e58d0f7e7357f6e61947d20715c", + "result" : "valid" + }, + { + "tcId" : 317, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "3130343738353830313238", + "sig" : "3045022100a24ebc0ec224bd67ae397cbe6fa37b3125adbd34891abe2d7c7356921916dfe6022034f6eb6374731bbbafc4924fb8b0bdcdda49456d724cdae6178d87014cb53d8c", + "result" : "valid" + }, + { + "tcId" : 318, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "3130353336323835353638", + "sig" : "304402202557d64a7aee2e0931c012e4fea1cd3a2c334edae68cdeb7158caf21b68e5a2402207f06cdbb6a90023a973882ed97b080fe6b05af3ec93db6f1a4399a69edf7670d", + "result" : "valid" + }, + { + "tcId" : 319, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "393533393034313035", + "sig" : "3045022100c4f2eccbb6a24350c8466450b9d61b207ee359e037b3dcedb42a3f2e6dd6aeb502203263c6b59a2f55cdd1c6e14894d5e5963b28bc3e2469ac9ba1197991ca7ff9c7", + "result" : "valid" + }, + { + "tcId" : 320, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "393738383438303339", + "sig" : "3045022100eff04781c9cbcd162d0a25a6e2ebcca43506c523385cb515d49ea38a1b12fcad022015acd73194c91a95478534f23015b672ebed213e45424dd2c8e26ac8b3eb34a5", + "result" : "valid" + }, + { + "tcId" : 321, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33363130363732343432", + "sig" : "3045022100f58b4e3110a64bf1b5db97639ee0e5a9c8dfa49dc59b679891f520fdf0584c8702202cd8fe51888aee9db3e075440fd4db73b5c732fb87b510e97093d66415f62af7", + "result" : "valid" + }, + { + "tcId" : 322, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31303534323430373035", + "sig" : "3045022100f8abecaa4f0c502de4bf5903d48417f786bf92e8ad72fec0bd7fcb7800c0bbe302204c7f9e231076a30b7ae36b0cebe69ccef1cd194f7cce93a5588fd6814f437c0e", + "result" : "valid" + }, + { + "tcId" : 323, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "35313734343438313937", + "sig" : "304402205d5b38bd37ad498b2227a633268a8cca879a5c7c94a4e416bd0a614d09e606d2022012b8d664ea9991062ecbb834e58400e25c46007af84f6007d7f1685443269afe", + "result" : "valid" + }, + { + "tcId" : 324, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31393637353631323531", + "sig" : "304402200c1cd9fe4034f086a2b52d65b9d3834d72aebe7f33dfe8f976da82648177d8e3022013105782e3d0cfe85c2778dec1a848b27ac0ae071aa6da341a9553a946b41e59", + "result" : "valid" + }, + { + "tcId" : 325, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33343437323533333433", + "sig" : "3045022100ae7935fb96ff246b7b5d5662870d1ba587b03d6e1360baf47988b5c02ccc1a5b02205f00c323272083782d4a59f2dfd65e49de0693627016900ef7e61428056664b3", + "result" : "valid" + }, + { + "tcId" : 326, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "333638323634333138", + "sig" : "3044022000a134b5c6ccbcefd4c882b945baeb4933444172795fa6796aae1490675470980220566e46105d24d890151e3eea3ebf88f5b92b3f5ec93a217765a6dcbd94f2c55b", + "result" : "valid" + }, + { + "tcId" : 327, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33323631313938363038", + "sig" : "304402202e4721363ad3992c139e5a1c26395d2c2d777824aa24fde075e0d7381171309d0220740f7c494418e1300dd4512f782a58800bff6a7abdfdd20fbbd4f05515ca1a4f", + "result" : "valid" + }, + { + "tcId" : 328, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "39363738373831303934", + "sig" : "304402206852e9d3cd9fe373c2d504877967d365ab1456707b6817a042864694e1960ccf0220064b27ea142b30887b84c86adccb2fa39a6911ad21fc7e819f593be52bc4f3bd", + "result" : "valid" + }, + { + "tcId" : 329, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "34393538383233383233", + "sig" : "30440220188a8c5648dc79eace158cf886c62b5468f05fd95f03a7635c5b4c31f09af4c5022036361a0b571a00c6cd5e686ccbfcfa703c4f97e48938346d0c103fdc76dc5867", + "result" : "valid" + }, + { + "tcId" : 330, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "383234363337383337", + "sig" : "3045022100a74f1fb9a8263f62fc4416a5b7d584f4206f3996bb91f6fc8e73b9e92bad0e1302206815032e8c7d76c3ab06a86f33249ce9940148cb36d1f417c2e992e801afa3fa", + "result" : "valid" + }, + { + "tcId" : 331, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "3131303230383333373736", + "sig" : "3044022007244865b72ff37e62e3146f0dc14682badd7197799135f0b00ade7671742bfe02200d80c2238edb4e4a7a86a8c57ca9af1711f406f7f5da0299aa04e2932d960754", + "result" : "valid" + }, + { + "tcId" : 332, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "313333383731363438", + "sig" : "3045022100da7fdd05b5badabd619d805c4ee7d9a84f84ddd5cf9c5bf4d4338140d689ef08022028f1cf4fa1c3c5862cfa149c0013cf5fe6cf5076cae000511063e7de25bb38e5", + "result" : "valid" + }, + { + "tcId" : 333, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "333232313434313632", + "sig" : "3045022100d3027c656f6d4fdfd8ede22093e3c303b0133c340d615e7756f6253aea927238022009aef060c8e4cef972974011558df144fed25ca69ae8d0b2eaf1a8feefbec417", + "result" : "valid" + }, + { + "tcId" : 334, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "3130363836363535353436", + "sig" : "304402200bf6c0188dc9571cd0e21eecac5fbb19d2434988e9cc10244593ef3a98099f6902204864a562661f9221ec88e3dd0bc2f6e27ac128c30cc1a80f79ec670a22b042ee", + "result" : "valid" + }, + { + "tcId" : 335, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "3632313535323436", + "sig" : "3045022100ae459640d5d1179be47a47fa538e16d94ddea5585e7a244804a51742c686443a02206c8e30e530a634fae80b3ceb062978b39edbe19777e0a24553b68886181fd897", + "result" : "valid" + }, + { + "tcId" : 336, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "37303330383138373734", + "sig" : "304402201cf3517ba3bf2ab8b9ead4ebb6e866cb88a1deacb6a785d3b63b483ca02ac4950220249a798b73606f55f5f1c70de67cb1a0cff95d7dc50b3a617df861bad3c6b1c9", + "result" : "valid" + }, + { + "tcId" : 337, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "35393234353233373434", + "sig" : "3045022100e69b5238265ea35d77e4dd172288d8cea19810a10292617d5976519dc5757cb802204b03c5bc47e826bdb27328abd38d3056d77476b2130f3df6ec4891af08ba1e29", + "result" : "valid" + }, + { + "tcId" : 338, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31343935353836363231", + "sig" : "304402205f9d7d7c870d085fc1d49fff69e4a275812800d2cf8973e7325866cb40fa2b6f02206d1f5491d9f717a597a15fd540406486d76a44697b3f0d9d6dcef6669f8a0a56", + "result" : "valid" + }, + { + "tcId" : 339, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "34303035333134343036", + "sig" : "304402200a7d5b1959f71df9f817146ee49bd5c89b431e7993e2fdecab6858957da685ae02200f8aad2d254690bdc13f34a4fec44a02fd745a422df05ccbb54635a8b86b9609", + "result" : "valid" + }, + { + "tcId" : 340, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "33303936343537353132", + "sig" : "3044022079e88bf576b74bc07ca142395fda28f03d3d5e640b0b4ff0752c6d94cd553408022032cea05bd2d706c8f6036a507e2ab7766004f0904e2e5c5862749c0073245d6a", + "result" : "valid" + }, + { + "tcId" : 341, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "32373834303235363230", + "sig" : "30450221009d54e037a00212b377bc8874798b8da080564bbdf7e07591b861285809d01488022018b4e557667a82bd95965f0706f81a29243fbdd86968a7ebeb43069db3b18c7f", + "result" : "valid" + }, + { + "tcId" : 342, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "32363138373837343138", + "sig" : "304402202664f1ffa982fedbcc7cab1b8bc6e2cb420218d2a6077ad08e591ba9feab33bd022049f5c7cb515e83872a3d41b4cdb85f242ad9d61a5bfc01debfbb52c6c84ba728", + "result" : "valid" + }, + { + "tcId" : 343, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "31363432363235323632", + "sig" : "304402205827518344844fd6a7de73cbb0a6befdea7b13d2dee4475317f0f18ffc81524b02204f5ccb4e0b488b5a5d760aacddb2d791970fe43da61eb30e2e90208a817e46db", + "result" : "valid" + }, + { + "tcId" : 344, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "36383234313839343336", + "sig" : "304502210097ab19bd139cac319325869218b1bce111875d63fb12098a04b0cd59b6fdd3a30220431d9cea3a243847303cebda56476431d034339f31d785ee8852db4f040d4921", + "result" : "valid" + }, + { + "tcId" : 345, + "comment" : "special case hash", + "flags" : [ + "SpecialCaseHash" + ], + "msg" : "343834323435343235", + "sig" : "3044022052c683144e44119ae2013749d4964ef67509278f6d38ba869adcfa69970e123d02203479910167408f45bda420a626ec9c4ec711c1274be092198b4187c018b562ca", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0", + "wx" : "07310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc362", + "wy" : "26a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEBzEPkKnq4UmghAL1QZSg97SsQnv42b1s\ndoEHHcR9w2ImptN6xG1h/WAMC/G/+HaJ7RF92msOWTGK4BChl6JsoA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 346, + "comment" : "k*G has a large x-coordinate", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "30160211014551231950b75fc4402da1722fc9baeb020103", + "result" : "valid" + }, + { + "tcId" : 347, + "comment" : "r too large", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2c020103", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5", + "wx" : "00bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22", + "wy" : "705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvJfnWF7srUjhZoO8QJFwjhqTDGg/xHAB\n1LODWU8sTiJwWYnPadrq3U5OS4FR7YiN/sIPsBco2J1Ws/OPKunIxQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 348, + "comment" : "r,s are large", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f020103", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463", + "wx" : "44ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252", + "wy" : "00b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERK0zmvvCHpq/e2AqXKU16jeBNbbRDYEx\nC92Ck9HfMlK2P/fQd0dw+P4dFyL6g6zQL0NOT8EQoMyPbd3TfVbEYw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 349, + "comment" : "r and s^-1 have a large Hamming weight", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e9a7582886089c62fb840cf3b83061cd1cff3ae4341808bb5bdee6191174177", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0", + "wx" : "1260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c", + "wy" : "5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEmDCEiyeJE4a9RUb7eDDriO1TXxZaIHT\n7rrSHzfdh4xcmgwamt52c3qIEb1qf5KHyXjuOWqonBHkcinSzLVS8A==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 350, + "comment" : "r and s^-1 have a large Hamming weight", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022024238e70b431b1a64efdf9032669939d4b77f249503fc6905feb7540dea3e6d2", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159", + "wx" : "1877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce", + "wy" : "00821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGHcEW+JdNKHQYA+dXADQZFoqVDebbO76\n0ua/XCozUs6CGlMswXUe4dNtQcPWq06bFD5E7EbXNHjqanmlwOVBWQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 351, + "comment" : "small r and s", + "flags" : [ + "SmallRandS", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3006020101020101", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77", + "wx" : "455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50", + "wy" : "00aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERVQ5/MPS3uzt3q7OYOe9FzBPNuu2Aq31\noi4Ljx20alCuw4+yuvIh6ajRiHx79iIt0YNGNOdyYzFa9tI2CdBPdw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 352, + "comment" : "small r and s", + "flags" : [ + "SmallRandS", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3006020101020102", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d", + "wx" : "2e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece718", + "wy" : "0449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELh9GawJMDDrOJDfeCRJ/7QS3BvlLGaIb\nscKs81zs5xgESa41I9clNOlklyz9OzivC93ZYZ5a8iPk0aQPNM+fHQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 353, + "comment" : "small r and s", + "flags" : [ + "SmallRandS", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3006020101020103", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "048e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a2337326ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3", + "wx" : "008e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a23373", + "wy" : "26ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a2337326ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjnq9u9GN50UjdMGHmhw7AdEyYefUVxw7\nR6HHbFWiM3Mm7Yl81Rek9TSduAl4D20vK59imdi1qJB38RGacY/Xsw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 354, + "comment" : "small r and s", + "flags" : [ + "SmallRandS", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3006020102020101", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "047b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af1942117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b", + "wx" : "7b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af19", + "wy" : "42117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af1942117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEezM9Q0DT1xjdPmr/fee7+Lcr/WFshCAF\nYFKEI3a5rxlCEXxa/qx1XW83b8Yymn12BRuHEjpKXQvEpTk4DwPeew==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 355, + "comment" : "small r and s", + "flags" : [ + "SmallRandS", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3006020102020102", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e503a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff", + "wx" : "00d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e5", + "wy" : "03a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e503a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0wykoN22YWyFHTDO1oLED4PGJ1ih8nWZ\niNZ2OojxwOUDqA1UFWUNQSOXhOji+xI16f6ZHREuu4EYbL8Not46/w==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 356, + "comment" : "small r and s", + "flags" : [ + "SmallRandS", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3006020102020103", + "result" : "valid" + }, + { + "tcId" : 357, + "comment" : "r is larger than n", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364143020103", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0448969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec", + "wx" : "48969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24", + "wy" : "00b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000448969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAESJabOZkSl7MyplLT7m4B6QmzmQTnH6I1\nSngwx3ULryS0AS0bgw0ZnMsfyXKzK/3tVfCc1i0lfl6ETiflehWU7A==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 358, + "comment" : "s is larger than n", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "30080201020203ed2979", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866", + "wx" : "02ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee77", + "wy" : "7eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAu9NbWz9WpTx13hCJuPipsCkNsVYOWGf\nOPtEcrX57nd+tKzU7r2lzXKHX/0qLyYinC3GtGUAkZpDLIZznzroZg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 359, + "comment" : "small r and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "30260202010102203a74e9d3a74e9d3a74e9d3a74e9d3a749f8ab3732a0a89604a09bce5b2916da4", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08", + "wx" : "464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584", + "wy" : "00b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERk9P9xVynK5Qcso72AHTGVtnrsZemwGq\n0gopQ9y8tYSxr9KdMaOaEdVwqhWXQ5s7LRlxvy8avxVDLQIHsQ0dCA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 360, + "comment" : "smallish r and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "302b02072d9b4d347952cc02200343aefc2f25d98b882e86eb9e30d55a6eb508b516510b34024ae4b6362330b3", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f", + "wx" : "157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4c", + "wy" : "00deadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEFX+P3fNz619Jz88Q2LhTz5HLzX1mXDUi\nun3XON23mkzerfGlxEjqPJ9BkaiZmr/MdXrG1kVn7wcsR/7GE0Q7jw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 361, + "comment" : "100-bit r and small s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3031020d1033e67e37b32b445580bf4efc02206f906f906f906f906f906f906f906f8fe1cab5eefdb214061dce3b22789f1d6f", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa", + "wx" : "0934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0", + "wy" : "00d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECTSlN0ZsB0MOLEj+uZC7Gft4zsyc7kJO\npNEwKRqiN/DU+S0jtGKAS1toxSVYwByZltv3J/zKu+7bliGkAFNa+g==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 362, + "comment" : "small r and 100 bit s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3026020201010220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265", + "wx" : "00d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c65", + "wy" : "4a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1u8gvmbIk/dBqb+Q2bdGddHCoxKWOXrL\nPvF0/QswDGVKDJVHjKADmRYtfw8tyJ79wrKKMPur4oWFcpWksMTiZQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 363, + "comment" : "100-bit r and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3031020d062522bbd3ecbe7c39e93e7c260220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829", + "wx" : "00b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee06", + "wy" : "29c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtykdFATgwMB9q5NyGJ9L1Y0s6qjRXt5U\nTZUUVFup7gYpyaY9XjCHacww7CdqQQ5kZKJ+6v2eWZ2xDwU6T+SoKQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 364, + "comment" : "r and s^-1 are close to n", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3045022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03640c1022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "046e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6", + "wx" : "6e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8", + "wy" : "186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbigwMwXWQsy5I7ci6oayoLyONzXssm6E\nmxnJ92sv27gYboDWTYyrFk9SOPUxhGG/idTZbuZUTIFsdWaUd3Tg9g==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 365, + "comment" : "r and s are 64-bit integer", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "30160209009c44febf31c3594d020900839ed28247c2b06b", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd", + "wx" : "375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9", + "wy" : "00a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEN1vak/avkvtfj0sbXwU047r6s0y3rZ+5\n0Lci5KXDAqmgC584elo5YJeqIWL8W7z0pSYzcvaByU2lHpeZEgmQ/Q==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 366, + "comment" : "r and s are 100-bit integer", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "301e020d09df8b682430beef6f5fd7c7cf020d0fd0a62e13778f4222a0d61c8a", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44", + "wx" : "00d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197", + "wy" : "00da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE11toIWur4DriV+lLTjvxxS9E498mbRUk\n/4xepp2nMZfaS/+e0cU/RJF6Z9e5eFmOid81nj1ZE+rqJPOuJZq8RA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 367, + "comment" : "r and s are 128-bit integer", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "30260211008a598e563a89f526c32ebec8de26367a02110084f633e2042630e99dd0f1e16f7a04bf", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0478bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e", + "wx" : "78bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653", + "wy" : "118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000478bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeLzaFArtI9QwyyPD3A0B9CPbE07pSjqM\ntIPy3qwqxlMRgRT28zBF1OntkQcIUAe/vd+PWP56GiRF1mqZAEVHbg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 368, + "comment" : "r and s are 160-bit integer", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "302e021500aa6eeb5823f7fa31b466bb473797f0d0314c0bdf021500e2977c479e6d25703cebbc6bd561938cc9d1bfb9", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677", + "wx" : "00bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c", + "wy" : "1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEu3n2GFf3Q7+htucRHOQJQ3claWnk4VFZ\nEj2VSKzDvmwfnZ+IYNz/0+s23Wwx/y5yJsIAnEyU2NfStWhr96vWdw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 369, + "comment" : "s == 1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020101", + "result" : "valid" + }, + { + "tcId" : 370, + "comment" : "s == 0", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020100", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0493591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518", + "wx" : "0093591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36", + "wy" : "073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000493591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEk1kYJ9nmcTtOn66mLHKyjf76aODAUWC1\n1qroj9LjbDYHP1VFrVr0EK8mr/9oZUz3LUXkk0iTESAyRzR6iQ9FGA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 371, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220419d981c515af8cc82545aac0c85e9e308fbb2eab6acd7ed497e0b4145a18fd9", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0431ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0dada01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f", + "wx" : "31ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0da", + "wy" : "00da01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000431ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0dada01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMe0wga7+AB62QCBp7izMGGKTe4WZUUTb\nqVA5Q1h78NraAbjMTfNPWrOxo1lhUgiUbl7jX5jud1uMzs2GzMFlDw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 372, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102201b21717ad71d23bbac60a9ad0baf75b063c9fdf52a00ebf99d022172910993c9", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "047dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea854c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4", + "wx" : "7dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea8", + "wy" : "54c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea854c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEff9m+phQn/Pi5RBF9DkFI9zNpDo7wohe\nWMJICQmQ7qhUx2wrmt62u1cYI+B/18ZchjnPnZBSYAZMjnZ1zm2YtA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 373, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102202f588f66018f3dd14db3e28e77996487e32486b521ed8e5a20f06591951777e9", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "044280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1", + "wx" : "4280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a", + "wy" : "2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEQoBQmqtk7fwLSiln5MvOhJy1ROSncxPI\n5uzlefvXQgouif5cwZJ9VU5qO7FAM+p8kizXXLosdBX9q1LyCxhg8Q==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 374, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220091a08870ff4daf9123b30c20e8c4fc8505758dcf4074fcaff2170c9bfcf74f4", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "044f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db", + "wx" : "4f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb", + "wy" : "2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAET43xRRlOPE/D7qJtQ851tALWsXRy3cuy\nVLinmwvz2csqog2ChEyyZjROccp48q0np1oJ5bwPpX5O/Z1GWgiI2w==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 375, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102207c370dc0ce8c59a8b273cba44a7c1191fc3186dc03cab96b0567312df0d0b250", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "049598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207", + "wx" : "009598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14", + "wy" : "122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElZilfdZ+w+FrWHoziqOhCjo5E7QaOvMu\nPtP/ATWMaxQSKBnt+AdLvFIffUzc6C/velFnBq/7odk9neqcyuGiBw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 376, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022070b59a7d1ee77a2f9e0491c2a7cfcd0ed04df4a35192f6132dcc668c79a6160e", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "049171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330", + "wx" : "009171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e", + "wy" : "634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkXH+w8oggGvAhPEvB2CRG2CZC9gOWypx\nygOgSLIPg35jT9F4Y3YbKVjSvk4Un409ervcGL4D9FGrbBf6Ch+DMA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 377, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102202736d76e412246e097148e2bf62915614eb7c428913a58eb5e9cd4674a9423de", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d", + "wx" : "777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9", + "wy" : "00ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd3yJMLbh0nEQD+aM6T8WP6N2EsX/9n9K\nYvw7r689F6ntc9hvYKUbXtkTU6OwVO3AqpLJ68vQt10Yj9yIJ5HWjQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 378, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102204a1e12831fbe93627b02d6e7f24bccdd6ef4b2d0f46739eaf3b1eaf0ca117770", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf4700603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000", + "wx" : "00eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf470", + "wy" : "0603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf4700603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE6rwkj2JuCmPh64HEPUYaOaHbqIHrbuIV\nKwfDLXG89HAGA8qoudM9sTr0TG777IoZjtYSSsnrF+qv0oJKVF7AAA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 379, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022006c778d4dfff7dee06ed88bc4e0ed34fc553aad67caf796f2a1c6487c1b2e877", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "049f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73", + "wx" : "009f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001", + "wy" : "00f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEn3oTraFYpV+d3xpF8ETwc9m4ADDv3Pyf\nn1hBj7zq8AH4raAXUJD4DUcifWcTtnQPmgCR2IqDfQoc13tYqPKNcw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 380, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102204de459ef9159afa057feb3ec40fef01c45b809f4ab296ea48c206d4249a2b451", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0411c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4dbbbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb", + "wx" : "11c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4db", + "wy" : "00bbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000411c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4dbbbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEcTz5GHNAZtcBuoM6kxAkMPMPjxdnzxt\nZbQ2gm2ptNu763p35Mv9ogcJfENCNwX3LIBHbaPaxApIOwqw8urRyw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 381, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220745d294978007302033502e1acc48b63ae6500be43adbea1b258d6b423dbb416", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb", + "wx" : "00e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4", + "wy" : "161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE4uGGgtUxI6oBpsXQCwxiPWcbRi6oC93W\nUif9UQWYiqQWGQez/SUESpSepByOLqhFncbxZUhWuLYbMVQ7sbRb2w==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 382, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102207b2a785e3896f59b2d69da57648e80ad3c133a750a2847fd2098ccd902042b6c", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0490f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197dafadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d", + "wx" : "0090f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197da", + "wy" : "00fadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000490f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197dafadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkPjUynPeCKZWSq8AUke28P/peFBNzlJg\nX0a3w+Vhl9r62+Uo63DZ7n6g5wcC21T3IVFMe4YErCyyFPHey344PQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 383, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022071ae94a72ca896875e7aa4a4c3d29afdb4b35b6996273e63c47ac519256c5eb1", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc", + "wx" : "00824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e", + "wy" : "3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEgkwZXHPP/fA40QG84Wh7XDthRvOVyIWX\nb3dTsjdrlI483vpvw0fRPk3LxjoLA6FlGAzSvhQxoM90zh6iUILSvA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 384, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102200fa527fa7343c0bc9ec35a6278bfbff4d83301b154fc4bd14aee7eb93445b5f9", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "042788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f", + "wx" : "2788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f", + "wy" : "30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJ4ilLweOs/ICxPpz4NM4b6899r6FYANj\nb1mZItT1Jo8wtPIHyRm7315nqL5CZagXR1Szq6jxbldbd/9NWn62Tw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 385, + "comment" : "edge case modular inverse", + "flags" : [ + "ModularInverse", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102206539c0adadd0525ff42622164ce9314348bd0863b4c80e936b23ca0414264671", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4", + "wx" : "00d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b4150874", + "wy" : "01b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1TO3iaSviQ+nqCofrljEBPmmKlC0mtr6\ns0nFE7QVCHQBtBcbgD52s0qYYeEPe8KJoGb9Ab0p+EyYehCl+xjC1A==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 386, + "comment" : "point at infinity during verify", + "flags" : [ + "PointDuplication", + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a", + "wx" : "3a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4", + "wy" : "221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOjFQeYyK9p0ebpgfOkVAK6HXMvS+gzDF\nFk9J4Q7FVbQiG9hCvF5Nl+/zcWX2DjmYpCTXKkUM+V6kd8eCh9A0Og==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 387, + "comment" : "edge case for signature malleability", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026", + "wx" : "3b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e80", + "wy" : "0de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOzffX7NHxpoPF9hcDHyoNzaIOoJeExQ9\nD8/IEB6FHoAN48CQtsohulQ1FzMMBLEvlIxrrfFKY6v/3074x1NwJg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 388, + "comment" : "edge case for signature malleability", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e", + "wx" : "00feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82c", + "wy" : "00e87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/rUWOw7OMP8+A8fVXEOA+i+oHuLANUlC\n/28IyZ0M2CzofeBe4b2gidPk4kj6D3IRAqz//fUOZUvigUM5md+Jfg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 389, + "comment" : "u1 == 1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2", + "wx" : "238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd4149228976", + "wy" : "40683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEI4ztABzyK4hT4C7cicvspQULp+BCp6d/\nk4LNQUkiiXZAaD0wlGQ4QPKViQqkwYqjm0HXfdD7O7JwDk+ewoT/wg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 390, + "comment" : "u1 == n - 1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf", + "wx" : "00961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35e", + "wy" : "00d2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElhz2SBfAbA5Rs8JzbJIv3hi9jEkG/Nf1\n72bEZ4UI817SxdGBaM++cPLxI710GSMruS3WkRPilBBhiJSBxaAnvw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 391, + "comment" : "u2 == 1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384", + "wx" : "13681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b10288", + "wy" : "16528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE2gerhaM1Op88uKkXQUnQtEKn2TnloZ9\nvcuCn+CxAogWUodg0Xc3bAnfed45VXwynMF1NRes/+j6LsKYAmuDhA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 392, + "comment" : "u2 == n - 1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b", + "wx" : "5aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c2", + "wy" : "0091c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWqer/ba0CG1UMyXl15xulc5C+GbSu4SQ\nljOgS7GqMcKRyACIeUkF4dozM22HTi+RzPRcxZGFvt5d1vP3rKrhiw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 393, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41", + "wx" : "277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e4", + "wy" : "64108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEACd3kbMFpFsrOVkLLwXTOSpsgYLO9OtU\nASDg9cIGw+RkEIIz+wuMOsiS15744Pv5LtEzrdtFVCcBMlhNxS7vQQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 394, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02201c940f313f92647be257eccd7ed08b0baef3f0478f25871b53635302c5f6314a", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49", + "wx" : "6efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1a", + "wy" : "00c75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbvoJK2jelGDwvMkZAFpfboDhnemJaL48\n0sdwqZSb+xrHXm5Qh9ZVDV+b6x555QKTB7wlUjXi1dyZJBrDq4hsSQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 395, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022015d94a85077b493f91cb7101ec63e1b01be58b594e855f45050a8c14062d689b", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942", + "wx" : "72d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058", + "wy" : "00e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEctShnE+dLPWEjqQERbcNRpa18C1jLAxl\nTMfX7rDG0FjoxM2ZQ+RZF0x6wB+nQhmOR+bBmmvbDE9sI3gxwbP5Qg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 396, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b1d27a7694c146244a5ad0bd0636d9d9ef3b9fb58385418d9c982105077d1b7", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec", + "wx" : "2a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e7402", + "wy" : "58f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKo6i9Q3M7QwhdXW9+nzUfRxvEABB7A41\nUSeUwb5+dAJY+MFxIu0wP9pxQ+tYvt5wKVtlMmYBOwsOvT8FMTf27A==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 397, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202d85896b3eb9dbb5a52f42f9c9261ed3fc46644ec65f06ade3fd78f257e43432", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946", + "wx" : "0088de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b8", + "wy" : "0c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiN5onOmvHpS+aiCJyKixJT/9u2yOnIYk\nm6IgABpK07gMSZjlSEL0E7ntsYJay7YzXoHk0YSysByL69yF0fKJRg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 398, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b0b12d67d73b76b4a5e85f3924c3da7f88cc89d8cbe0d5bc7faf1e4afc86864", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9", + "wx" : "00fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7", + "wy" : "00b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/qLTH3D5DV+z4A4YasQqs8FhXO5xTgtO\nETGz1NgiW/ewN6GN8qwVND8w90Bn3fKegX1fd/jc4FcU2lnAlPDNqQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 399, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220694c146244a5ad0bd0636d9e12bc9e09e60e68b90d0b5e6c5dddd0cb694d8799", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0", + "wx" : "7258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db", + "wy" : "17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEcliRHj1CM0kWZHnb4Lg0Gvf70D0KfhDt\nzLNrbO6lo9sXrCuJknkRKPo7ltwvvUyjv6eC7ygy/GZWlD2xjnNGsA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 400, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203d7f487c07bfc5f30846938a3dcef696444707cf9677254a92b06c63ab867d22", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470", + "wx" : "4f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914", + "wy" : "00c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAETyhGHepkR01rs00Umcl9N7npVjPfHO7q\nrNRQFsmLORTIgYgQuMwG3bQOihJhxSj6pYlFXVpt+Tt3vF4OSTx0cA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 401, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206c7648fc0fbf8a06adb8b839f97b4ff7a800f11b1e37c593b261394599792ba4", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b", + "wx" : "74f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66", + "wy" : "00eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEdPKoFPtdjsqRppteYHEnMrOTfeMoKb6X\nTte2jFwvXWbv8PB8VvmHplf0IZYgX1iMDx2W/YpjpfI4tI9Hh4j+Ow==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 402, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220641c9c5d790dc09cdd3dfabb62cdf453e69747a7e3d7aa1a714189ef53171a99", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad", + "wx" : "195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6a", + "wy" : "00b2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGVtRp8xKIbgnSnCpDed5gUw8jKNYMoII\nwJop8za4LWqyQWt8kv/9wpw7EoLdKnek0E3390UgRzk9hJmJxc7prQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 403, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022029798c5c45bdf58b4a7b2fdc2c46ab4af1218c7eeb9f0f27a88f1267674de3b0", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0", + "wx" : "622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa", + "wy" : "736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYi/HRzIDS+wt3zvBbTSz0fejJ90qjBm6\ntLtP46JLWKpzay8vrnb0367MkJYzOwEyjVHrP9qckifpDQtEmYPE8A==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 404, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02200b70f22ca2bb3cefadca1a5711fa3a59f4695385eb5aedf3495d0b6d00f8fd85", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93", + "wx" : "1f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c7", + "wy" : "0827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH3+FyvLXVQ56+bZQI+u03ONFAxFpIwnb\nJplpuDS2EccIJ/RbeAIOy7r0hP3Vv6rmhw8RhMIVgbr274K9e1MPkw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 405, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d", + "wx" : "49c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377a", + "wy" : "00efc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEScGX3ICtHaR6Q0K5OJPo4fsLuU/DOoPn\ng8ALJMeBN3rvwg2pK6x2KVH3JHS+zHNNTMIrqBuJXigv2sTfevDzfQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 406, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202252d685e831b6cf095e4f0535eeaf0ddd3bfa91c210c9d9dc17224702eaf88f", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c", + "wx" : "00d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe", + "wy" : "7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2MtoUXthalZACqOGhjXlS29plZii9hZ3\nV2VJgLr2rL5+yM9EnISaoDRhow762kFFPFfG5vvJO7xvpJrabcBVXA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 407, + "comment" : "edge case for u1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022075135abd7c425b60371a477f09ce0f274f64a8c6b061a07b5d63e93c65046c53", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750", + "wx" : "030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3", + "wy" : "00b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAwcT+2Pyqm/iyt8bIO/CWcd0Rdr6h9rD\nmLhAZco0ffOyJ4GN4aObWJywcdg+UxfMzcIzjlHjEv4x2Nw0pIAXUA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 408, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950", + "wx" : "00babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7", + "wy" : "252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEurs2d7CVWALY6SmkE1VkDq8eoTU/incT\nMcSUbjSAr6clLxlsh+09KlnTsbVZE3/tABP+zvwZ+1qSaCubylG5UA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 409, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e888377ac6c71ac9dec3fdb9b56c9feaf0cfaca9f827fc5eb65fc3eac811210", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9", + "wx" : "1aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60", + "wy" : "00bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGqsgGHk0cREaig6bFD/eAvyVkgeW06Y9\n4ym0JDlvumC75BMHBRdHkkQbMY06ox3+hXeCHptEbsVz0nLgNsTr6Q==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 410, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022030bbb794db588363b40679f6c182a50d3ce9679acdd3ffbe36d7813dacbdc818", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75", + "wx" : "008cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff", + "wy" : "47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjLC5CUmcg+qAbNiFsd1GegEZ8GqIoCdu\nsM/aJ0U1qP9HtUKIM7w/LIv52QQRWM8zcYpplhzQFym8ABHR5YardQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 411, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202c37fd995622c4fb7fffffffffffffffc7cee745110cb45ab558ed7c90c15a2f", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0", + "wx" : "008f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d", + "wy" : "3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjwPPGkInK7FTJyMJP3Lm/urIXhcA6fvp\npqLdZC10v107iacYna2M91/CL28ViqJ/nCygDaynhb4zWPK9o4YsoA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 412, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02207fd995622c4fb7ffffffffffffffffff5d883ffab5b32652ccdcaa290fccb97d", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12", + "wx" : "44de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8ace", + "wy" : "00a2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERN47nHpXqMnoIJUnU0IefZh7s9efcfAT\ngFyJfgGPis6iRgdYyPmNP9zhIalDZZ43LDJv/y5fwq5/o/edquE8Eg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 413, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304302207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc021f4cd53ba7608fffffffffffffffffffff9e5cf143e2539626190a3ab09cce47", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204", + "wx" : "6fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a", + "wy" : "0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEb7iytI4zAxJorWpRdITciDnqkPZmnqDH\nrDIz4qwxOUoKyLvn9zwv9N+ZeHJ6wd/C/VhkfSDzH5kQUxa2RnHyBA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 414, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205622c4fb7fffffffffffffffffffffff928a8f1c7ac7bec1808b9f61c01ec327", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c", + "wx" : "00bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6", + "wy" : "00f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvqcRIqBIaT6QX/YCs8+d0Yr2m5/J2EMd\nKx3Sa5Qsleb0PHuLletiCCwS2529p/445Fy+SkiGkH+4G9sMXqkkbA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 415, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022044104104104104104104104104104103b87853fd3b7d3f8e175125b4382f25ed", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391", + "wx" : "00da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156", + "wy" : "00e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2pGMcxugaiDLlO8zt3jpgaQEowXxlB/j\nNma0WwM1MVbiuyaU9XW0UYO+eOXJtSEL879Ij9TIKUUW2JVyyk9TkQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 416, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202739ce739ce739ce739ce739ce739ce705560298d1f2f08dc419ac273a5b54d9", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5", + "wx" : "3007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d", + "wy" : "5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMAfpLDk32t55ZN+jWw7/Ax9+sCrtCgMU\nQREGzetw/j1adUb8BVKZeyDj1vQT514stm4RYyJpcRS3m6xzS/xNxQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 417, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02204888888888888888888888888888888831c83ae82ebe0898776b4c69d11f88de", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567", + "wx" : "60e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9b", + "wy" : "00d2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYOc071Yk08vw3dN1ARvWY9bWrrxkTrWZ\n/fmNvc0YzpvS2Qs6wx8TmvgyzM9sy7ssbqEfqXNw3JkG2kdNfYp1Zw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 418, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206492492492492492492492492492492406dd3a19b8d5fb875235963c593bd2d3", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c", + "wx" : "0085a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba337", + "wy" : "69744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEhakA6XhY9pPAt9+iYeOA2tbqBG0fZd3u\n7dX32K8LozdpdE0VrdT2wLw7DaKuyTs0y4xl+TQN33TnsACe7szOPA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 419, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b15", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed", + "wx" : "38066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046", + "wy" : "00a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOAZvddiO/EyT3jb0ngN7I0zBix3lYIdQ\npiyrA0VAEEaj6EvtjPy4Ge9NVQRE8s5LZRdmtp4uKQH4iDb/kANP7Q==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 420, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89", + "wx" : "0098f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabf", + "wy" : "00a33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmPaBd9yVwbTL+lJFSIylI6fVYpRw0DXW\nIaRDxy85qr+jPSlUb6HGSPLH1cz3DPHOSrebXbGsBZ2+zQaNvf8biQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 421, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191", + "wx" : "5c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277", + "wy" : "00e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEXCu/ojybmtB/A4qom0kwvyZ9lAHkJV3p\n6NoKUHjsgnfj6IKjHV5qN54Hk5g8ze05uVxDU6sv8B6lNpukewwxkQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 422, + "comment" : "edge case for u2", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220185ddbca6dac41b1da033cfb60c152869e74b3cd66e9ffdf1b6bc09ed65ee40c", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc", + "wx" : "2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385", + "wy" : "3547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\nBc02R7FXo4U1R4CCmESO215wGt6EzV+xrJVnul6Ptoprkz7EtcyEzA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 423, + "comment" : "point duplication during verification", + "flags" : [ + "PointDuplication" + ], + "msg" : "313233343030", + "sig" : "3044022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022029ed3d67b3d505be95580d77d5b792b436881179b2b6b2e04c5fe592d38d82d9", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763", + "wx" : "2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385", + "wy" : "00cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\nBc02R7FXo4XKuH99Z7txJKGP5SF7MqBOU2qYRaFwSXWUbME6SjN3Yw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 424, + "comment" : "duplication bug", + "flags" : [ + "PointDuplication" + ], + "msg" : "313233343030", + "sig" : "3044022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022029ed3d67b3d505be95580d77d5b792b436881179b2b6b2e04c5fe592d38d82d9", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff", + "wx" : "008aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e", + "wy" : "1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiqLGT6nGQ3Vjq/vL0AsgSNSMGMFSoqb0\nkDbedkfr6C4c5kOHmVxooGD6O8A5mwXMBu7H1Zj3UEGkkX5pK39R/w==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 425, + "comment" : "comparison with point at infinity ", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0022033333333333333333333333333333332f222f8faefdb533f265d461c29a47373", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd", + "wx" : "391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71f", + "wy" : "00dd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEORQn/37ngBPBSux9lqigYiCSmKeDg16U\n/WVJ1QL/9x/dZiTsNDrZ/PTZhyGB5Z+EL5ukzMrgmmwJcvtqxrTGvQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 426, + "comment" : "extreme value for k and edgecase s", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e", + "wx" : "00e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138e", + "wy" : "00c1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE52K4ohm08YAhnMepBZJF5JYb0ZHAOJl4\nnHo0uJ6ME47BUz7wQZu3N24L/ekxnRCgaWh5HZ6g7tnBzmNFrtl1ng==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 427, + "comment" : "extreme value for k and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175", + "wx" : "009aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952", + "wy" : "00fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmu2w0oHbFk4TAADFaX+uDzBe+Ei+b/+0\nOsWT+7lQ6VL6b2MzWb3NgrVrC5+WWwN3idRrmoFBt5GyrvpxP5bBdQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 428, + "comment" : "extreme value for k and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd", + "wx" : "008ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee", + "wy" : "1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEitRF22KBYmDk5of9GITki5/AY20DFUfW\nMxXnkuGb+u4d5k+Z1fHNi27Jyw94emVK6GmTuj2xAI70PP8GhMsivQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 429, + "comment" : "extreme value for k and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566", + "wx" : "1f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32", + "wy" : "00e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH1eZyVvokGOyTybkDLkowahop2+wCUYH\n6AQ9tAnJHDLnVyToE6QZHjqDkAfwji6Jc4iwbUoA3m3mDlNtkfq1Zg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 430, + "comment" : "extreme value for k and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d", + "wx" : "00a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc", + "wy" : "28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEozMaThtCI+wsAn7dSCySihTtNY2T8dQh\nfTmr9p/LXMwo1oTSqqvNY4N3XKpiOd4m1MaTe7YD7LQZYIL0z/1QnQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 431, + "comment" : "extreme value for k", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee502200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d", + "wx" : "3f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb24818", + "wy" : "5ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEPzlSGZd0x885s4tmyxBCpiYNhoCAOEXk\n1DOtujuySBhepJW2jLx+1Bc+5jyQQtxQJiXH634h+wLKmpEU4KOhjQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 432, + "comment" : "extreme value for k and edgecase s", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698", + "wx" : "00cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e", + "wy" : "054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzfuMD0IuFE4TfCQSyGwXH1/j+j9bu1RO\nkHYojzzteG4FT9ByG3fBHHm+rLPJQhGwoZvaCGUu/q+SUTo7ChY2mA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 433, + "comment" : "extreme value for k and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d", + "wx" : "73598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3", + "wy" : "00cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEc1mKahxoJ4+mv9DOQGTmgjW8HA9rIKko\nEIvjNnMPh+PLrmElGbUDLsyFrtgRJxqV/nk51dNGAUC6MY9NFKujHQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 434, + "comment" : "extreme value for k and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d", + "wx" : "58debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a1", + "wy" : "6773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWN69mn7iydWRMkeKVECuTV1+1Dcwg2n5\nLqhsghg/EKFnc+dvXtv02g5PG9/6wPVyV+HfpGWEKTEwmiQkX9pqXQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 435, + "comment" : "extreme value for k and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f", + "wx" : "008b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b", + "wy" : "00950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEi5BN5HlnNAxfjDVypyCSTvdXhjf+qxlJ\nrLJBpaasP1uVCQRJb5gksdY/MxO64huJ+uia/fyBG17OA/1aowGGTw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 436, + "comment" : "extreme value for k and s^-1", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b", + "wx" : "00f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a", + "wy" : "346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE9IkrbVJcdx4DXyolJwjzeE5II4YEtPlN\nxW6qHlRtlBo0axqgvOaLHFDltS9Qn7VSLlwl4Ci8j4Y0Au23vK2LGw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 437, + "comment" : "extreme value for k", + "flags" : [ + "ArithmeticError" + ], + "msg" : "313233343030", + "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + "wx" : "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "wy" : "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\nWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuA==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 438, + "comment" : "public key shares x-coordinate with generator", + "flags" : [ + "PointDuplication" + ], + "msg" : "313233343030", + "sig" : "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", + "result" : "invalid" + }, + { + "tcId" : 439, + "comment" : "public key shares x-coordinate with generator", + "flags" : [ + "PointDuplication" + ], + "msg" : "313233343030", + "sig" : "3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777", + "wx" : "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "wy" : "00b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\nWfKBWxb4F5i3xSWI2Vw7mqJbBAPx7vdXAuhLt1l6q+ZjuC9vBO8ndw==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 440, + "comment" : "public key shares x-coordinate with generator", + "flags" : [ + "PointDuplication" + ], + "msg" : "313233343030", + "sig" : "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", + "result" : "invalid" + }, + { + "tcId" : 441, + "comment" : "public key shares x-coordinate with generator", + "flags" : [ + "PointDuplication" + ], + "msg" : "313233343030", + "sig" : "3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", + "result" : "invalid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152", + "wx" : "782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963", + "wy" : "00af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeCyO0X47Kng7VGTzOwllKnHGeOBexR6E\n4rz8Zjo96WOvmstCgLjH98QvTvmrpiRewewXEv04oPqWQY2M1qphUg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 442, + "comment" : "pseudorandom signature", + "flags" : [ + "ValidSignature" + ], + "msg" : "", + "sig" : "3045022100f80ae4f96cdbc9d853f83d47aae225bf407d51c56b7776cd67d0dc195d99a9dc02204cfc1d941e08cb9aceadde0f4ccead76b30d332fc442115d50e673e28686b70b", + "result" : "valid" + }, + { + "tcId" : 443, + "comment" : "pseudorandom signature", + "flags" : [ + "ValidSignature" + ], + "msg" : "4d7367", + "sig" : "30440220109cd8ae0374358984a8249c0a843628f2835ffad1df1a9a69aa2fe72355545c02205390ff250ac4274e1cb25cd6ca6491f6b91281e32f5b264d87977aed4a94e77b", + "result" : "valid" + }, + { + "tcId" : 444, + "comment" : "pseudorandom signature", + "flags" : [ + "ValidSignature" + ], + "msg" : "313233343030", + "sig" : "3045022100d035ee1f17fdb0b2681b163e33c359932659990af77dca632012b30b27a057b302201939d9f3b2858bc13e3474cb50e6a82be44faa71940f876c1cba4c3e989202b6", + "result" : "valid" + }, + { + "tcId" : 445, + "comment" : "pseudorandom signature", + "flags" : [ + "ValidSignature" + ], + "msg" : "0000000000000000000000000000000000000000", + "sig" : "304402204f053f563ad34b74fd8c9934ce59e79c2eb8e6eca0fef5b323ca67d5ac7ed23802204d4b05daa0719e773d8617dce5631c5fd6f59c9bdc748e4b55c970040af01be5", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1", + "wx" : "6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff", + "wy" : "01060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\n4bulQapAyv8AAAABBgSS1aVnPg8l2NUPt+WMSdhtRtQhaVXgqj1A4Q==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 446, + "comment" : "y-coordinate of the public key is small", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "304402206d6a4f556ccce154e7fb9f19e76c3deca13d59cc2aeb4ecad968aab2ded45965022053b9fa74803ede0fc4441bf683d56c564d3e274e09ccf47390badd1471c05fb7", + "result" : "valid" + }, + { + "tcId" : 447, + "comment" : "y-coordinate of the public key is small", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3044022100aad503de9b9fd66b948e9acf596f0a0e65e700b28b26ec56e6e45e846489b3c4021f0ddc3a2f89abb817bb85c062ce02f823c63fc26b269e0bc9b84d81a5aa123d", + "result" : "valid" + }, + { + "tcId" : 448, + "comment" : "y-coordinate of the public key is small", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "30450221009182cebd3bb8ab572e167174397209ef4b1d439af3b200cdf003620089e43225022054477c982ea019d2e1000497fc25fcee1bccae55f2ac27530ae53b29c4b356a4", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e", + "wx" : "6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff", + "wy" : "00fffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\n4bulQapAyv/////++fttKlqYwfDaJyrwSBpztieSuSvelqoeVcK7Tg==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 449, + "comment" : "y-coordinate of the public key is large", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "304402203854a3998aebdf2dbc28adac4181462ccac7873907ab7f212c42db0e69b56ed802203ed3f6b8a388d02f3e4df9f2ae9c1bd2c3916a686460dffcd42909cd7f82058e", + "result" : "valid" + }, + { + "tcId" : 450, + "comment" : "y-coordinate of the public key is large", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3045022100e94dbdc38795fe5c904d8f16d969d3b587f0a25d2de90b6d8c5c53ff887e360702207a947369c164972521bb8af406813b2d9f94d2aeaa53d4c215aaa0a2578a2c5d", + "result" : "valid" + }, + { + "tcId" : 451, + "comment" : "y-coordinate of the public key is large", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3044022049fc102a08ca47b60e0858cd0284d22cddd7233f94aaffbb2db1dd2cf08425e102205b16fca5a12cdb39701697ad8e39ffd6bdec0024298afaa2326aea09200b14d6", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d", + "wx" : "013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0", + "wy" : "00f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAAAAAT/SIkjWTZX3PCm0irSGMYUL5QP9\nAPhGi18PcOD27nqkO8LG/SWx2CaSQcvdnbsNrJbcliMfQwcF+DhxfQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 452, + "comment" : "x-coordinate of the public key is small", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3044022041efa7d3f05a0010675fcb918a45c693da4b348df21a59d6f9cd73e0d831d67a02204454ada693e5e26b7bd693236d340f80545c834577b6f73d378c7bcc534244da", + "result" : "valid" + }, + { + "tcId" : 453, + "comment" : "x-coordinate of the public key is small", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3045022100b615698c358b35920dd883eca625a6c5f7563970cdfc378f8fe0cee17092144c022025f47b326b5be1fb610b885153ea84d41eb4716be66a994e8779989df1c863d4", + "result" : "valid" + }, + { + "tcId" : 454, + "comment" : "x-coordinate of the public key is small", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "304502210087cf8c0eb82d44f69c60a2ff5457d3aaa322e7ec61ae5aecfd678ae1c1932b0e02203add3b115815047d6eb340a3e008989eaa0f8708d1794814729094d08d2460d3", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "0425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35", + "wx" : "25afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dffffffff", + "wy" : "00fa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJa/WiayrrtZ8Hylt5ZQG+MVQ9XFGoLTs\nLJeHbf/////6RqduUgMi37xJHsTwzBl0IPxOpYg9j23VPDVLxPZ8NQ==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 455, + "comment" : "x-coordinate of the public key has many trailing 1's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3044022062f48ef71ace27bf5a01834de1f7e3f948b9dce1ca1e911d5e13d3b104471d8202205ea8f33f0c778972c4582080deda9b341857dd64514f0849a05f6964c2e34022", + "result" : "valid" + }, + { + "tcId" : 456, + "comment" : "x-coordinate of the public key has many trailing 1's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3045022100f6b0e2f6fe020cf7c0c20137434344ed7add6c4be51861e2d14cbda472a6ffb402206416c8dd3e5c5282b306e8dc8ff34ab64cc99549232d678d714402eb6ca7aa0f", + "result" : "valid" + }, + { + "tcId" : 457, + "comment" : "x-coordinate of the public key has many trailing 1's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3045022100db09d8460f05eff23bc7e436b67da563fa4b4edb58ac24ce201fa8a358125057022046da116754602940c8999c8d665f786c50f5772c0a3cdbda075e77eabc64df16", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "04d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff", + "wx" : "00d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb9", + "wy" : "3f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0S5sZrZ3NMPITSYBz1013Al+J2N/CspK\nT9t0tqrdO7k/W9/4i9VzbfiY5pkAbtdQ8RzwfFhmzXrXDHEh/////w==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 458, + "comment" : "y-coordinate of the public key has many trailing 1's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "30440220592c41e16517f12fcabd98267674f974b588e9f35d35406c1a7bb2ed1d19b7b802203e65a06bd9f83caaeb7b00f2368d7e0dece6b12221269a9b5b765198f840a3a1", + "result" : "valid" + }, + { + "tcId" : 459, + "comment" : "y-coordinate of the public key has many trailing 1's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3045022100be0d70887d5e40821a61b68047de4ea03debfdf51cdf4d4b195558b959a032b202207d994b2d8f1dbbeb13534eb3f6e5dccd85f5c4133c27d9e64271b1826ce1f67d", + "result" : "valid" + }, + { + "tcId" : 460, + "comment" : "y-coordinate of the public key has many trailing 1's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3045022100fae92dfcb2ee392d270af3a5739faa26d4f97bfd39ed3cbee4d29e26af3b206a02206c9ba37f9faa6a1fd3f65f23b4e853d4692a7274240a12db7ba3884830630d16", + "result" : "valid" + } + ] + }, + { + "type" : "EcdsaBitcoinVerify", + "publicKey" : { + "type" : "EcPublicKey", + "curve" : "secp256k1", + "keySize" : 256, + "uncompressed" : "046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb", + "wx" : "6d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000", + "wy" : "00e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb" + }, + "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb", + "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbUp/YNR3Sk8KqLve25U8fup5CUB+MWR1\nVmS8KAAAAADmWdNOTfONnoyeqt+6NmEsdpGVvobHeqw/NueLU4aA+w==\n-----END PUBLIC KEY-----\n", + "sha" : "SHA-256", + "tests" : [ + { + "tcId" : 461, + "comment" : "x-coordinate of the public key has many trailing 0's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "30440220176a2557566ffa518b11226694eb9802ed2098bfe278e5570fe1d5d7af18a94302201291df6a0ed5fc0d15098e70bcf13a009284dfd0689d3bb4be6ceeb9be1487c4", + "result" : "valid" + }, + { + "tcId" : 462, + "comment" : "x-coordinate of the public key has many trailing 0's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3044022060be20c3dbc162dd34d26780621c104bbe5dace630171b2daef0d826409ee5c20220427f7e4d889d549170bda6a9409fb1cb8b0e763d13eea7bd97f64cf41dc6e497", + "result" : "valid" + }, + { + "tcId" : 463, + "comment" : "x-coordinate of the public key has many trailing 0's", + "flags" : [ + "EdgeCasePublicKey" + ], + "msg" : "4d657373616765", + "sig" : "3045022100edf03cf63f658883289a1a593d1007895b9f236d27c9c1f1313089aaed6b16ae02201a4dd6fc0814dc523d1fefa81c64fbf5e618e651e7096fccadbb94cd48e5e0cd", + "result" : "valid" + } + ] + } + ] +} diff --git a/crypto/secp256k1/libsecp256k1/tools/check-abi.sh b/crypto/secp256k1/libsecp256k1/tools/check-abi.sh new file mode 100755 index 0000000000..601a64ba96 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/tools/check-abi.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +set -eu + +default_base_version="$(git describe --match "v*.*.*" --abbrev=0)" +default_new_version="HEAD" + +display_help_and_exit() { + echo "Usage: $0 [ []]" + echo "" + echo "Description: This script uses the ABI Compliance Checker tool to determine if the ABI" + echo " of a new version of libsecp256k1 has changed in a backward-incompatible way." + echo "" + echo "Options:" + echo " base_ver Specify the base version as a git commit-ish" + echo " (default: most recent reachable tag matching \"v.*.*\", currently \"$default_base_version\")" + echo " new_ver Specify the new version as a git commit-ish" + echo " (default: $default_new_version)" + echo " -h, --help Display this help message" + exit 0 +} + +if [ "$#" -eq 0 ]; then + base_version="$default_base_version" + new_version="$default_new_version" +elif [ "$#" -eq 1 ] && { [ "$1" = "-h" ] || [ "$1" = "--help" ]; }; then + display_help_and_exit +elif [ "$#" -eq 1 ] || [ "$#" -eq 2 ]; then + base_version="$1" + if [ "$#" -eq 2 ]; then + new_version="$2" + fi +else + echo "Invalid usage. See help:" + echo "" + display_help_and_exit +fi + +checkout_and_build() { + _orig_dir="$(pwd)" + git worktree add --detach "$1" "$2" + cd "$1" + mkdir build && cd build + cmake -S .. --preset dev-mode \ + -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=None -DCMAKE_C_FLAGS="-g -Og -gdwarf-4" \ + -DSECP256K1_BUILD_BENCHMARK=OFF \ + -DSECP256K1_BUILD_TESTS=OFF \ + -DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF \ + -DSECP256K1_BUILD_CTIME_TESTS=OFF \ + -DSECP256K1_BUILD_EXAMPLES=OFF + cmake --build . -j "$(nproc)" + # FIXME: Just set LIBPATH to lib/libsecp256k1.so once version 0.6.0 is + # released. + if [ -f "src/libsecp256k1.so" ]; then + LIBPATH="src/libsecp256k1.so" + else + LIBPATH="lib/libsecp256k1.so" + fi + abi-dumper $LIBPATH -o ABI.dump -lver "$2" -public-headers ../include/ + cd "$_orig_dir" +} + +echo "Comparing $base_version (base version) to $new_version (new version)" +echo + +base_source_dir="$(mktemp -d)" +checkout_and_build "$base_source_dir" "$base_version" + +new_source_dir="$(mktemp -d)" +checkout_and_build "$new_source_dir" "$new_version" + +abi-compliance-checker -lib libsecp256k1 -old "${base_source_dir}/build/ABI.dump" -new "${new_source_dir}/build/ABI.dump" +git worktree remove "$base_source_dir" +git worktree remove "$new_source_dir" diff --git a/crypto/secp256k1/libsecp256k1/tools/test_vectors_musig2_generate.py b/crypto/secp256k1/libsecp256k1/tools/test_vectors_musig2_generate.py new file mode 100755 index 0000000000..97424419f3 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/tools/test_vectors_musig2_generate.py @@ -0,0 +1,656 @@ +#!/usr/bin/env python3 + +import sys +import json +import textwrap + +max_pubkeys = 0 + +if len(sys.argv) < 2: + print( + "This script converts BIP MuSig2 test vectors in a given directory to a C file that can be used in the test framework." + ) + print("Usage: %s
" % sys.argv[0]) + sys.exit(1) + + +def hexstr_to_intarray(str): + return ", ".join([f"0x{b:02X}" for b in bytes.fromhex(str)]) + + +def create_init(name): + return """ +static const struct musig_%s_vector musig_%s_vector = { +""" % ( + name, + name, + ) + + +def init_array(key): + return textwrap.indent("{ %s },\n" % hexstr_to_intarray(data[key]), 4 * " ") + + +def init_arrays(key): + s = textwrap.indent("{\n", 4 * " ") + s += textwrap.indent( + ",\n".join(["{ %s }" % hexstr_to_intarray(x) for x in data[key]]), 8 * " " + ) + s += textwrap.indent("\n},\n", 4 * " ") + return s + + +def init_indices(array): + return " %d, { %s }" % ( + len(array), + ", ".join(map(str, array) if len(array) > 0 else "0"), + ) + + +def init_is_xonly(case): + if len(case["tweak_indices"]) > 0: + return ", ".join(map(lambda x: "1" if x else "0", case["is_xonly"])) + return "0" + + +def init_optional_expected(case): + return hexstr_to_intarray(case["expected"]) if "expected" in case else 0 + + +def init_cases(cases, f): + s = textwrap.indent("{\n", 4 * " ") + for (i, case) in enumerate(cases): + s += textwrap.indent("%s\n" % f(case), 8 * " ") + s += textwrap.indent("},\n", 4 * " ") + return s + + +def finish_init(): + return "};\n" + + +s = ( + """/** + * Automatically generated by %s. + * + * The test vectors for the KeySort function are included in this file. They can + * be found in src/modules/extrakeys/tests_impl.h. */ +""" + % sys.argv[0] +) + + +s += """ +enum MUSIG_ERROR { + MUSIG_PUBKEY, + MUSIG_TWEAK, + MUSIG_PUBNONCE, + MUSIG_AGGNONCE, + MUSIG_SECNONCE, + MUSIG_SIG, + MUSIG_SIG_VERIFY, + MUSIG_OTHER +}; +""" + +# key agg vectors +with open(sys.argv[1] + "/key_agg_vectors.json", "r") as f: + data = json.load(f) + + max_key_indices = max( + len(test_case["key_indices"]) for test_case in data["valid_test_cases"] + ) + max_tweak_indices = max( + len(test_case["tweak_indices"]) for test_case in data["error_test_cases"] + ) + num_pubkeys = len(data["pubkeys"]) + max_pubkeys = max(num_pubkeys, max_pubkeys) + num_tweaks = len(data["tweaks"]) + num_valid_cases = len(data["valid_test_cases"]) + num_error_cases = len(data["error_test_cases"]) + + # Add structures for valid and error cases + s += ( + """ +struct musig_key_agg_valid_test_case { + size_t key_indices_len; + size_t key_indices[%d]; + unsigned char expected[32]; +}; +""" + % max_key_indices + ) + s += """ +struct musig_key_agg_error_test_case { + size_t key_indices_len; + size_t key_indices[%d]; + size_t tweak_indices_len; + size_t tweak_indices[%d]; + int is_xonly[%d]; + enum MUSIG_ERROR error; +}; +""" % ( + max_key_indices, + max_tweak_indices, + max_tweak_indices, + ) + + # Add structure for entire vector + s += """ +struct musig_key_agg_vector { + unsigned char pubkeys[%d][33]; + unsigned char tweaks[%d][32]; + struct musig_key_agg_valid_test_case valid_case[%d]; + struct musig_key_agg_error_test_case error_case[%d]; +}; +""" % ( + num_pubkeys, + num_tweaks, + num_valid_cases, + num_error_cases, + ) + + s += create_init("key_agg") + # Add pubkeys and tweaks to the vector + s += init_arrays("pubkeys") + s += init_arrays("tweaks") + + # Add valid cases to the vector + s += init_cases( + data["valid_test_cases"], + lambda case: "{ %s, { %s }}," + % (init_indices(case["key_indices"]), hexstr_to_intarray(case["expected"])), + ) + + def comment_to_error(case): + comment = case["comment"] + if "public key" in comment.lower(): + return "MUSIG_PUBKEY" + elif "tweak" in comment.lower(): + return "MUSIG_TWEAK" + else: + sys.exit("Unknown error") + + # Add error cases to the vector + s += init_cases( + data["error_test_cases"], + lambda case: "{ %s, %s, { %s }, %s }," + % ( + init_indices(case["key_indices"]), + init_indices(case["tweak_indices"]), + init_is_xonly(case), + comment_to_error(case), + ), + ) + + s += finish_init() + +# nonce gen vectors +with open(sys.argv[1] + "/nonce_gen_vectors.json", "r") as f: + data = json.load(f) + + # The MuSig2 implementation only allows messages of length 32 + data["test_cases"] = list( + filter(lambda c: c["msg"] is None or len(c["msg"]) == 64, data["test_cases"]) + ) + + num_tests = len(data["test_cases"]) + + s += """ +struct musig_nonce_gen_test_case { + unsigned char rand_[32]; + int has_sk; + unsigned char sk[32]; + unsigned char pk[33]; + int has_aggpk; + unsigned char aggpk[32]; + int has_msg; + unsigned char msg[32]; + int has_extra_in; + unsigned char extra_in[32]; + unsigned char expected_secnonce[97]; + unsigned char expected_pubnonce[66]; +}; +""" + + s += ( + """ +struct musig_nonce_gen_vector { + struct musig_nonce_gen_test_case test_case[%d]; +}; +""" + % num_tests + ) + + s += create_init("nonce_gen") + + def init_array_maybe(array): + return "%d , { %s }" % ( + 0 if array is None else 1, + hexstr_to_intarray(array) if array is not None else 0, + ) + + s += init_cases( + data["test_cases"], + lambda case: "{ { %s }, %s, { %s }, %s, %s, %s, { %s }, { %s } }," + % ( + hexstr_to_intarray(case["rand_"]), + init_array_maybe(case["sk"]), + hexstr_to_intarray(case["pk"]), + init_array_maybe(case["aggpk"]), + init_array_maybe(case["msg"]), + init_array_maybe(case["extra_in"]), + hexstr_to_intarray(case["expected_secnonce"]), + hexstr_to_intarray(case["expected_pubnonce"]), + ), + ) + + s += finish_init() + +# nonce agg vectors +with open(sys.argv[1] + "/nonce_agg_vectors.json", "r") as f: + data = json.load(f) + + num_pnonces = len(data["pnonces"]) + num_valid_cases = len(data["valid_test_cases"]) + num_error_cases = len(data["error_test_cases"]) + + pnonce_indices_len = 2 + for case in data["valid_test_cases"] + data["error_test_cases"]: + assert len(case["pnonce_indices"]) == pnonce_indices_len + + # Add structures for valid and error cases + s += """ +struct musig_nonce_agg_test_case { + size_t pnonce_indices[2]; + /* if valid case */ + unsigned char expected[66]; + /* if error case */ + int invalid_nonce_idx; +}; +""" + # Add structure for entire vector + s += """ +struct musig_nonce_agg_vector { + unsigned char pnonces[%d][66]; + struct musig_nonce_agg_test_case valid_case[%d]; + struct musig_nonce_agg_test_case error_case[%d]; +}; +""" % ( + num_pnonces, + num_valid_cases, + num_error_cases, + ) + + s += create_init("nonce_agg") + s += init_arrays("pnonces") + + for cases in (data["valid_test_cases"], data["error_test_cases"]): + s += init_cases( + cases, + lambda case: "{ { %s }, { %s }, %d }," + % ( + ", ".join(map(str, case["pnonce_indices"])), + init_optional_expected(case), + case["error"]["signer"] if "error" in case else 0, + ), + ) + s += finish_init() + +# sign/verify vectors +with open(sys.argv[1] + "/sign_verify_vectors.json", "r") as f: + data = json.load(f) + + # The MuSig2 implementation only allows messages of length 32 + assert list(filter(lambda x: len(x) == 64, data["msgs"]))[0] == data["msgs"][0] + data["msgs"] = [data["msgs"][0]] + + def filter_msg32(k): + return list(filter(lambda x: x["msg_index"] == 0, data[k])) + + data["valid_test_cases"] = filter_msg32("valid_test_cases") + data["sign_error_test_cases"] = filter_msg32("sign_error_test_cases") + data["verify_error_test_cases"] = filter_msg32("verify_error_test_cases") + data["verify_fail_test_cases"] = filter_msg32("verify_fail_test_cases") + + num_pubkeys = len(data["pubkeys"]) + max_pubkeys = max(num_pubkeys, max_pubkeys) + num_secnonces = len(data["secnonces"]) + num_pubnonces = len(data["pnonces"]) + num_aggnonces = len(data["aggnonces"]) + num_msgs = len(data["msgs"]) + num_valid_cases = len(data["valid_test_cases"]) + num_sign_error_cases = len(data["sign_error_test_cases"]) + num_verify_fail_cases = len(data["verify_fail_test_cases"]) + num_verify_error_cases = len(data["verify_error_test_cases"]) + + all_cases = ( + data["valid_test_cases"] + + data["sign_error_test_cases"] + + data["verify_error_test_cases"] + + data["verify_fail_test_cases"] + ) + max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases) + max_nonce_indices = max( + len(test_case["nonce_indices"]) if "nonce_indices" in test_case else 0 + for test_case in all_cases + ) + # Add structures for valid and error cases + s += ( + """ +/* Omit pubnonces in the test vectors because our partial signature verification + * implementation is able to accept the aggnonce directly. */ +struct musig_valid_case { + size_t key_indices_len; + size_t key_indices[%d]; + size_t aggnonce_index; + size_t msg_index; + size_t signer_index; + unsigned char expected[32]; +}; +""" + % max_key_indices + ) + + s += ( + """ +struct musig_sign_error_case { + size_t key_indices_len; + size_t key_indices[%d]; + size_t aggnonce_index; + size_t msg_index; + size_t secnonce_index; + enum MUSIG_ERROR error; +}; +""" + % max_key_indices + ) + + s += """ +struct musig_verify_fail_error_case { + unsigned char sig[32]; + size_t key_indices_len; + size_t key_indices[%d]; + size_t nonce_indices_len; + size_t nonce_indices[%d]; + size_t msg_index; + size_t signer_index; + enum MUSIG_ERROR error; +}; +""" % ( + max_key_indices, + max_nonce_indices, + ) + + # Add structure for entire vector + s += """ +struct musig_sign_verify_vector { + unsigned char sk[32]; + unsigned char pubkeys[%d][33]; + unsigned char secnonces[%d][194]; + unsigned char pubnonces[%d][194]; + unsigned char aggnonces[%d][66]; + unsigned char msgs[%d][32]; + struct musig_valid_case valid_case[%d]; + struct musig_sign_error_case sign_error_case[%d]; + struct musig_verify_fail_error_case verify_fail_case[%d]; + struct musig_verify_fail_error_case verify_error_case[%d]; +}; +""" % ( + num_pubkeys, + num_secnonces, + num_pubnonces, + num_aggnonces, + num_msgs, + num_valid_cases, + num_sign_error_cases, + num_verify_fail_cases, + num_verify_error_cases, + ) + + s += create_init("sign_verify") + s += init_array("sk") + s += init_arrays("pubkeys") + s += init_arrays("secnonces") + s += init_arrays("pnonces") + s += init_arrays("aggnonces") + s += init_arrays("msgs") + + s += init_cases( + data["valid_test_cases"], + lambda case: "{ %s, %d, %d, %d, { %s }}," + % ( + init_indices(case["key_indices"]), + case["aggnonce_index"], + case["msg_index"], + case["signer_index"], + init_optional_expected(case), + ), + ) + + def sign_error(case): + comment = case["comment"] + if "pubkey" in comment or "public key" in comment: + return "MUSIG_PUBKEY" + elif "Aggregate nonce" in comment: + return "MUSIG_AGGNONCE" + elif "Secnonce" in comment: + return "MUSIG_SECNONCE" + else: + sys.exit("Unknown sign error") + + s += init_cases( + data["sign_error_test_cases"], + lambda case: "{ %s, %d, %d, %d, %s }," + % ( + init_indices(case["key_indices"]), + case["aggnonce_index"], + case["msg_index"], + case["secnonce_index"], + sign_error(case), + ), + ) + + def verify_error(case): + comment = case["comment"] + if "exceeds" in comment: + return "MUSIG_SIG" + elif "Wrong signer" in comment or "Wrong signature" in comment: + return "MUSIG_SIG_VERIFY" + elif "pubnonce" in comment: + return "MUSIG_PUBNONCE" + elif "pubkey" in comment: + return "MUSIG_PUBKEY" + else: + sys.exit("Unknown verify error") + + for cases in ("verify_fail_test_cases", "verify_error_test_cases"): + s += init_cases( + data[cases], + lambda case: "{ { %s }, %s, %s, %d, %d, %s }," + % ( + hexstr_to_intarray(case["sig"]), + init_indices(case["key_indices"]), + init_indices(case["nonce_indices"]), + case["msg_index"], + case["signer_index"], + verify_error(case), + ), + ) + + s += finish_init() + +# tweak vectors +with open(sys.argv[1] + "/tweak_vectors.json", "r") as f: + data = json.load(f) + + num_pubkeys = len(data["pubkeys"]) + max_pubkeys = max(num_pubkeys, max_pubkeys) + num_pubnonces = len(data["pnonces"]) + num_tweaks = len(data["tweaks"]) + num_valid_cases = len(data["valid_test_cases"]) + num_error_cases = len(data["error_test_cases"]) + + all_cases = data["valid_test_cases"] + data["error_test_cases"] + max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases) + max_tweak_indices = max(len(test_case["tweak_indices"]) for test_case in all_cases) + max_nonce_indices = max(len(test_case["nonce_indices"]) for test_case in all_cases) + # Add structures for valid and error cases + s += """ +struct musig_tweak_case { + size_t key_indices_len; + size_t key_indices[%d]; + size_t nonce_indices_len; + size_t nonce_indices[%d]; + size_t tweak_indices_len; + size_t tweak_indices[%d]; + int is_xonly[%d]; + size_t signer_index; + unsigned char expected[32]; +}; +""" % ( + max_key_indices, + max_nonce_indices, + max_tweak_indices, + max_tweak_indices, + ) + + # Add structure for entire vector + s += """ +struct musig_tweak_vector { + unsigned char sk[32]; + unsigned char secnonce[97]; + unsigned char aggnonce[66]; + unsigned char msg[32]; + unsigned char pubkeys[%d][33]; + unsigned char pubnonces[%d][194]; + unsigned char tweaks[%d][32]; + struct musig_tweak_case valid_case[%d]; + struct musig_tweak_case error_case[%d]; +}; +""" % ( + num_pubkeys, + num_pubnonces, + num_tweaks, + num_valid_cases, + num_error_cases, + ) + s += create_init("tweak") + s += init_array("sk") + s += init_array("secnonce") + s += init_array("aggnonce") + s += init_array("msg") + s += init_arrays("pubkeys") + s += init_arrays("pnonces") + s += init_arrays("tweaks") + + s += init_cases( + data["valid_test_cases"], + lambda case: "{ %s, %s, %s, { %s }, %d, { %s }}," + % ( + init_indices(case["key_indices"]), + init_indices(case["nonce_indices"]), + init_indices(case["tweak_indices"]), + init_is_xonly(case), + case["signer_index"], + init_optional_expected(case), + ), + ) + + s += init_cases( + data["error_test_cases"], + lambda case: "{ %s, %s, %s, { %s }, %d, { %s }}," + % ( + init_indices(case["key_indices"]), + init_indices(case["nonce_indices"]), + init_indices(case["tweak_indices"]), + init_is_xonly(case), + case["signer_index"], + init_optional_expected(case), + ), + ) + + s += finish_init() + +# sigagg vectors +with open(sys.argv[1] + "/sig_agg_vectors.json", "r") as f: + data = json.load(f) + + num_pubkeys = len(data["pubkeys"]) + max_pubkeys = max(num_pubkeys, max_pubkeys) + num_tweaks = len(data["tweaks"]) + num_psigs = len(data["psigs"]) + num_valid_cases = len(data["valid_test_cases"]) + num_error_cases = len(data["error_test_cases"]) + + all_cases = data["valid_test_cases"] + data["error_test_cases"] + max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases) + max_tweak_indices = max(len(test_case["tweak_indices"]) for test_case in all_cases) + max_psig_indices = max(len(test_case["psig_indices"]) for test_case in all_cases) + + # Add structures for valid and error cases + s += """ +/* Omit pubnonces in the test vectors because they're only needed for + * implementations that do not directly accept an aggnonce. */ +struct musig_sig_agg_case { + size_t key_indices_len; + size_t key_indices[%d]; + size_t tweak_indices_len; + size_t tweak_indices[%d]; + int is_xonly[%d]; + unsigned char aggnonce[66]; + size_t psig_indices_len; + size_t psig_indices[%d]; + /* if valid case */ + unsigned char expected[64]; + /* if error case */ + int invalid_sig_idx; +}; +""" % ( + max_key_indices, + max_tweak_indices, + max_tweak_indices, + max_psig_indices, + ) + + # Add structure for entire vector + s += """ +struct musig_sig_agg_vector { + unsigned char pubkeys[%d][33]; + unsigned char tweaks[%d][32]; + unsigned char psigs[%d][32]; + unsigned char msg[32]; + struct musig_sig_agg_case valid_case[%d]; + struct musig_sig_agg_case error_case[%d]; +}; +""" % ( + num_pubkeys, + num_tweaks, + num_psigs, + num_valid_cases, + num_error_cases, + ) + + s += create_init("sig_agg") + s += init_arrays("pubkeys") + s += init_arrays("tweaks") + s += init_arrays("psigs") + s += init_array("msg") + + for cases in (data["valid_test_cases"], data["error_test_cases"]): + s += init_cases( + cases, + lambda case: "{ %s, %s, { %s }, { %s }, %s, { %s }, %d }," + % ( + init_indices(case["key_indices"]), + init_indices(case["tweak_indices"]), + init_is_xonly(case), + hexstr_to_intarray(case["aggnonce"]), + init_indices(case["psig_indices"]), + init_optional_expected(case), + case["error"]["signer"] if "error" in case else 0, + ), + ) + s += finish_init() +s += "enum { MUSIG_VECTORS_MAX_PUBKEYS = %d };" % max_pubkeys +print(s) diff --git a/crypto/secp256k1/libsecp256k1/tools/tests_wycheproof_generate.py b/crypto/secp256k1/libsecp256k1/tools/tests_wycheproof_generate.py new file mode 100755 index 0000000000..b26dfa89d6 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/tools/tests_wycheproof_generate.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Random "Randy" Lattice and Sean Andersen +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php. +''' +Generate a C file with ECDSA testvectors from the Wycheproof project. +''' + +import json +import sys + +filename_input = sys.argv[1] + +with open(filename_input) as f: + doc = json.load(f) + +num_groups = len(doc['testGroups']) + +def to_c_array(x): + if x == "": + return "" + s = ',0x'.join(a+b for a,b in zip(x[::2], x[1::2])) + return "0x" + s + + +num_vectors = 0 +offset_msg_running, offset_pk_running, offset_sig = 0, 0, 0 +out = "" +messages = "" +signatures = "" +public_keys = "" +cache_msgs = {} +cache_public_keys = {} + +for i in range(num_groups): + group = doc['testGroups'][i] + num_tests = len(group['tests']) + public_key = group['publicKey'] + for j in range(num_tests): + test_vector = group['tests'][j] + # // 2 to convert hex to byte length + sig_size = len(test_vector['sig']) // 2 + msg_size = len(test_vector['msg']) // 2 + + if test_vector['result'] == "invalid": + expected_verify = 0 + elif test_vector['result'] == "valid": + expected_verify = 1 + else: + raise ValueError("invalid result field") + + if num_vectors != 0 and sig_size != 0: + signatures += ",\n " + + new_msg = False + msg = to_c_array(test_vector['msg']) + msg_offset = offset_msg_running + # check for repeated msg + if msg not in cache_msgs: + if num_vectors != 0 and msg_size != 0: + messages += ",\n " + cache_msgs[msg] = offset_msg_running + messages += msg + new_msg = True + else: + msg_offset = cache_msgs[msg] + + new_pk = False + pk = to_c_array(public_key['uncompressed']) + pk_offset = offset_pk_running + # check for repeated pk + if pk not in cache_public_keys: + if num_vectors != 0: + public_keys += ",\n " + cache_public_keys[pk] = offset_pk_running + public_keys += pk + new_pk = True + else: + pk_offset = cache_public_keys[pk] + + signatures += to_c_array(test_vector['sig']) + + out += " /" + "* tcId: " + str(test_vector['tcId']) + ". " + test_vector['comment'] + " *" + "/\n" + out += f" {{{pk_offset}, {msg_offset}, {msg_size}, {offset_sig}, {sig_size}, {expected_verify} }},\n" + if new_msg: + offset_msg_running += msg_size + if new_pk: + offset_pk_running += 65 + offset_sig += sig_size + num_vectors += 1 + +struct_definition = """ +typedef struct { + size_t pk_offset; + size_t msg_offset; + size_t msg_len; + size_t sig_offset; + size_t sig_len; + int expected_verify; +} wycheproof_ecdsa_testvector; +""" + + +print("/* Note: this file was autogenerated using tests_wycheproof_generate.py. Do not edit. */") +print(f"#define SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS ({num_vectors})") + +print(struct_definition) + +print("static const unsigned char wycheproof_ecdsa_messages[] = { " + messages + "};\n") +print("static const unsigned char wycheproof_ecdsa_public_keys[] = { " + public_keys + "};\n") +print("static const unsigned char wycheproof_ecdsa_signatures[] = { " + signatures + "};\n") + +print("static const wycheproof_ecdsa_testvector testvectors[SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS] = {") +print(out) +print("};") diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go index 61abc1eaf0..60ae7d9e55 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -12,25 +12,14 @@ package secp256k1 #cgo CFLAGS: -I./libsecp256k1 #cgo CFLAGS: -I./libsecp256k1/src/ -#ifdef __SIZEOF_INT128__ -# define HAVE___INT128 -# define USE_FIELD_5X52 -# define USE_SCALAR_4X64 -#else -# define USE_FIELD_10X26 -# define USE_SCALAR_8X32 -#endif - #ifndef NDEBUG # define NDEBUG #endif -#define USE_ENDOMORPHISM -#define USE_NUM_NONE -#define USE_FIELD_INV_BUILTIN -#define USE_SCALAR_INV_BUILTIN #include "./libsecp256k1/src/secp256k1.c" #include "./libsecp256k1/src/modules/recovery/main_impl.h" +#include "./libsecp256k1/src/precomputed_ecmult.c" +#include "./libsecp256k1/src/precomputed_ecmult_gen.c" #include "ext.h" typedef void (*callbackFunc) (const char* msg, void* data); From 1ca2da81e6a212f0d74dfa500e3ced3312296fab Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 13 Mar 2025 11:43:00 +0100 Subject: [PATCH 183/940] eth/ethconfig: add HistoryMode (#31365) Here I am adding a config option and geth flag (`--history.chain`) for configuring history pruning. There are two options available: - `--history.chain all` is the default and will keep all history like before. - `--history.chain postmerge` will configure the history cutoff point to the merge block. The option doesn't actually do anything right now, but we need it as a precursor for other history pruning changes. --- cmd/geth/main.go | 1 + cmd/utils/flags.go | 21 +++++++-- core/blockchain.go | 10 ++++ core/genesis.go | 15 +++--- eth/backend.go | 43 ++++++++++++----- eth/ethconfig/config.go | 4 ++ eth/ethconfig/gen_config.go | 6 +++ eth/ethconfig/historymode.go | 90 ++++++++++++++++++++++++++++++++++++ 8 files changed, 168 insertions(+), 22 deletions(-) create mode 100644 eth/ethconfig/historymode.go diff --git a/cmd/geth/main.go b/cmd/geth/main.go index fda6edb78d..fd3f4e1bab 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -86,6 +86,7 @@ var ( utils.SnapshotFlag, utils.TxLookupLimitFlag, // deprecated utils.TransactionHistoryFlag, + utils.ChainHistoryFlag, utils.StateHistoryFlag, utils.LightServeFlag, // deprecated utils.LightIngressFlag, // deprecated diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 1394f9060e..7c32d7e734 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -272,6 +272,12 @@ var ( Value: ethconfig.Defaults.TransactionHistory, Category: flags.StateCategory, } + ChainHistoryFlag = &cli.StringFlag{ + Name: "history.chain", + Usage: `Blockchain history retention ("all" or "postmerge")`, + Value: ethconfig.Defaults.HistoryMode.String(), + Category: flags.StateCategory, + } // Beacon client light sync settings BeaconApiFlag = &cli.StringSliceFlag{ Name: "beacon.api", @@ -1566,10 +1572,19 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.IsSet(SyncTargetFlag.Name) { cfg.SyncMode = ethconfig.FullSync // dev sync target forces full sync } else if ctx.IsSet(SyncModeFlag.Name) { - if err = cfg.SyncMode.UnmarshalText([]byte(ctx.String(SyncModeFlag.Name))); err != nil { - Fatalf("invalid --syncmode flag: %v", err) + value := ctx.String(SyncModeFlag.Name) + if err = cfg.SyncMode.UnmarshalText([]byte(value)); err != nil { + Fatalf("--%v: %v", SyncModeFlag.Name, err) } } + + if ctx.IsSet(ChainHistoryFlag.Name) { + value := ctx.String(ChainHistoryFlag.Name) + if err = cfg.HistoryMode.UnmarshalText([]byte(value)); err != nil { + Fatalf("--%s: %v", ChainHistoryFlag.Name, err) + } + } + if ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = ctx.Uint64(NetworkIdFlag.Name) } @@ -2086,7 +2101,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh gspec = MakeGenesis(ctx) chainDb = MakeChainDatabase(ctx, stack, readonly) ) - config, err := core.LoadChainConfig(chainDb, gspec) + config, _, err := core.LoadChainConfig(chainDb, gspec) if err != nil { Fatalf("%v", err) } diff --git a/core/blockchain.go b/core/blockchain.go index b98c2d43aa..7aad5c9d26 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -154,6 +154,10 @@ type CacheConfig struct { SnapshotNoBuild bool // Whether the background generation is allowed SnapshotWait bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it + + // This defines the cutoff block for history expiry. + // Blocks before this number may be unavailable in the chain database. + HistoryPruningCutoff uint64 } // triedbConfig derives the configures for trie database. @@ -2519,3 +2523,9 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) { func (bc *BlockChain) GetTrieFlushInterval() time.Duration { return time.Duration(bc.flushInterval.Load()) } + +// HistoryPruningCutoff returns the configured history pruning point. +// Blocks before this might not be available in the database. +func (bc *BlockChain) HistoryPruningCutoff() uint64 { + return bc.cacheConfig.HistoryPruningCutoff +} diff --git a/core/genesis.go b/core/genesis.go index 9bd8c4f8b9..23f4a73ec5 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -386,7 +386,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g // LoadChainConfig loads the stored chain config if it is already present in // database, otherwise, return the config in the provided genesis specification. -func LoadChainConfig(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, error) { +func LoadChainConfig(db ethdb.Database, genesis *Genesis) (cfg *params.ChainConfig, ghash common.Hash, err error) { // Load the stored chain config from the database. It can be nil // in case the database is empty. Notably, we only care about the // chain config corresponds to the canonical chain. @@ -394,27 +394,28 @@ func LoadChainConfig(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, if stored != (common.Hash{}) { storedcfg := rawdb.ReadChainConfig(db, stored) if storedcfg != nil { - return storedcfg, nil + return storedcfg, stored, nil } } // Load the config from the provided genesis specification if genesis != nil { // Reject invalid genesis spec without valid chain config if genesis.Config == nil { - return nil, errGenesisNoConfig + return nil, common.Hash{}, errGenesisNoConfig } // If the canonical genesis header is present, but the chain // config is missing(initialize the empty leveldb with an // external ancient chain segment), ensure the provided genesis // is matched. - if stored != (common.Hash{}) && genesis.ToBlock().Hash() != stored { - return nil, &GenesisMismatchError{stored, genesis.ToBlock().Hash()} + ghash := genesis.ToBlock().Hash() + if stored != (common.Hash{}) && ghash != stored { + return nil, ghash, &GenesisMismatchError{stored, ghash} } - return genesis.Config, nil + return genesis.Config, ghash, nil } // There is no stored chain config and no new config provided, // In this case the default chain config(mainnet) will be used - return params.MainnetChainConfig, nil + return params.MainnetChainConfig, params.MainnetGenesisHash, nil } // chainConfigOrDefault retrieves the attached chain configuration. If the genesis diff --git a/eth/backend.go b/eth/backend.go index 8fbbc20a47..1790e413fd 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -110,6 +110,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if !config.SyncMode.IsValid() { return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode) } + if !config.HistoryMode.IsValid() { + return nil, fmt.Errorf("invalid history mode %d", config.HistoryMode) + } 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) @@ -125,7 +128,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024) - // Assemble the Ethereum object chainDb, err := stack.OpenDatabaseWithFreezer("chaindata", config.DatabaseCache, config.DatabaseHandles, config.DatabaseFreezer, "eth/db/chaindata/", false) if err != nil { return nil, err @@ -140,8 +142,10 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { log.Error("Failed to recover state", "error", err) } } - // Transfer mining-related config to the ethash config. - chainConfig, err := core.LoadChainConfig(chainDb, config.Genesis) + + // Here we determine genesis hash and active ChainConfig. + // We need these to figure out the consensus parameters and to set up history pruning. + chainConfig, genesisHash, err := core.LoadChainConfig(chainDb, config.Genesis) if err != nil { return nil, err } @@ -149,10 +153,24 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } + + // Validate history pruning configuration. + var historyPruningCutoff uint64 + if config.HistoryMode == ethconfig.PostMergeHistory { + prunecfg, ok := ethconfig.HistoryPrunePoints[genesisHash] + if !ok { + return nil, fmt.Errorf("no history pruning point is defined for genesis %x", genesisHash) + } + historyPruningCutoff = prunecfg.BlockNumber + } + + // Set networkID to chainID by default. networkID := config.NetworkId if networkID == 0 { networkID = chainConfig.ChainID.Uint64() } + + // Assemble the Ethereum object. eth := &Ethereum{ config: config, chainDb: chainDb, @@ -190,15 +208,16 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { EnablePreimageRecording: config.EnablePreimageRecording, } cacheConfig = &core.CacheConfig{ - TrieCleanLimit: config.TrieCleanCache, - TrieCleanNoPrefetch: config.NoPrefetch, - TrieDirtyLimit: config.TrieDirtyCache, - TrieDirtyDisabled: config.NoPruning, - TrieTimeLimit: config.TrieTimeout, - SnapshotLimit: config.SnapshotCache, - Preimages: config.Preimages, - StateHistory: config.StateHistory, - StateScheme: scheme, + TrieCleanLimit: config.TrieCleanCache, + TrieCleanNoPrefetch: config.NoPrefetch, + TrieDirtyLimit: config.TrieDirtyCache, + TrieDirtyDisabled: config.NoPruning, + TrieTimeLimit: config.TrieTimeout, + SnapshotLimit: config.SnapshotCache, + Preimages: config.Preimages, + StateHistory: config.StateHistory, + StateScheme: scheme, + HistoryPruningCutoff: historyPruningCutoff, } ) if config.VMTrace != "" { diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 0bf9ce3579..ec6de9e663 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -48,6 +48,7 @@ var FullNodeGPO = gasprice.Config{ // Defaults contains default settings for use on the Ethereum main net. var Defaults = Config{ + HistoryMode: AllHistory, SyncMode: SnapSync, NetworkId: 0, // enable auto configuration of networkID == chainID TxLookupLimit: 2350000, @@ -81,6 +82,9 @@ type Config struct { NetworkId uint64 SyncMode SyncMode + // HistoryMode configures chain history retention. + HistoryMode HistoryMode + // This can be set to list of enrtree:// URLs which will be queried for // nodes to connect to. EthDiscoveryURLs []string diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 11c0c06372..bcfe8a31d6 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -19,6 +19,7 @@ func (c Config) MarshalTOML() (interface{}, error) { Genesis *core.Genesis `toml:",omitempty"` NetworkId uint64 SyncMode SyncMode + HistoryMode HistoryMode EthDiscoveryURLs []string SnapDiscoveryURLs []string NoPruning bool @@ -55,6 +56,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.Genesis = c.Genesis enc.NetworkId = c.NetworkId enc.SyncMode = c.SyncMode + enc.HistoryMode = c.HistoryMode enc.EthDiscoveryURLs = c.EthDiscoveryURLs enc.SnapDiscoveryURLs = c.SnapDiscoveryURLs enc.NoPruning = c.NoPruning @@ -95,6 +97,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { Genesis *core.Genesis `toml:",omitempty"` NetworkId *uint64 SyncMode *SyncMode + HistoryMode *HistoryMode EthDiscoveryURLs []string SnapDiscoveryURLs []string NoPruning *bool @@ -140,6 +143,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.SyncMode != nil { c.SyncMode = *dec.SyncMode } + if dec.HistoryMode != nil { + c.HistoryMode = *dec.HistoryMode + } if dec.EthDiscoveryURLs != nil { c.EthDiscoveryURLs = dec.EthDiscoveryURLs } diff --git a/eth/ethconfig/historymode.go b/eth/ethconfig/historymode.go new file mode 100644 index 0000000000..cf904ab591 --- /dev/null +++ b/eth/ethconfig/historymode.go @@ -0,0 +1,90 @@ +// Copyright 2025 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 ethconfig + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params" +) + +// HistoryMode configures history pruning. +type HistoryMode uint32 + +const ( + // AllHistory (default) means that all chain history down to genesis block will be kept. + AllHistory HistoryMode = iota + + // PostMergeHistory sets the history pruning point to the merge activation block. + PostMergeHistory +) + +func (m HistoryMode) IsValid() bool { + return m <= PostMergeHistory +} + +func (m HistoryMode) String() string { + switch m { + case AllHistory: + return "all" + case PostMergeHistory: + return "postmerge" + default: + return fmt.Sprintf("invalid HistoryMode(%d)", m) + } +} + +// MarshalText implements encoding.TextMarshaler. +func (m HistoryMode) MarshalText() ([]byte, error) { + if m.IsValid() { + return []byte(m.String()), nil + } + return nil, fmt.Errorf("unknown history mode %d", m) +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (m *HistoryMode) UnmarshalText(text []byte) error { + switch string(text) { + case "all": + *m = AllHistory + case "postmerge": + *m = PostMergeHistory + default: + return fmt.Errorf(`unknown sync mode %q, want "all" or "postmerge"`, text) + } + return nil +} + +type HistoryPrunePoint struct { + BlockNumber uint64 + BlockHash common.Hash +} + +// HistoryPrunePoints contains the pre-defined history pruning cutoff blocks for known networks. +var HistoryPrunePoints = map[common.Hash]*HistoryPrunePoint{ + // mainnet + params.MainnetGenesisHash: { + BlockNumber: 15537394, + BlockHash: common.HexToHash("0x56a9bb0302da44b8c0b3df540781424684c3af04d0b7a38d72842b762076a664"), + }, + // sepolia + params.SepoliaGenesisHash: { + BlockNumber: 1735371, + BlockHash: common.HexToHash("0x36fb89fba5b7857cf0ca78b5a9625b4043ff4555dfce9b7bcdcdd758a11eb946"), + }, +} From 18faa251b3cdf9ead91d861c524d7a9e3dec0af7 Mon Sep 17 00:00:00 2001 From: Pierre R Date: Tue, 11 Mar 2025 18:26:16 +0900 Subject: [PATCH 184/940] Update core/txpool/txpool.go Co-authored-by: jwasinger --- core/txpool/txpool.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index e09c920779..9b1136756b 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -486,6 +486,8 @@ func (p *TxPool) Sync() error { // Clear removes all tracked txs from the subpools. func (p *TxPool) Clear() { + // Invoke Sync to ensure that txs pending addition don't get added to the pool after + // the subpools are subsequently cleared p.Sync() for _, subpool := range p.subpools { subpool.Clear() From f3e4866073d4650a7f461315c517333c6407ab5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Thu, 13 Mar 2025 12:35:10 +0100 Subject: [PATCH 185/940] core: update blockProcFeed in insertChain (#31065) This PR moves the updating of the `blockProcFeed` event feed from `InsertChain` to `insertChain` in order to ensure that the feed subscribers are notified whenever block processing happens. Note that this event is not subscribed to anywhere in our codebase at the moment, earlier it was used by the LES server to avoid slowing down block processing. Now I want to do the same with the log indexer, the problem is that back then every block insertion was done by `InsertChain`, now the regular payload insertion is done by `InsertBlockWithoutSetHead`. Both of these (and also `SetCanonical` if needed) calls `insertChain` so I moved the feed update there. --- core/blockchain.go | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 7aad5c9d26..2024c63b80 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -235,14 +235,15 @@ type BlockChain struct { statedb *state.CachingDB // State database to reuse between imports (contains state cache) txIndexer *txIndexer // Transaction indexer, might be nil if not enabled - hc *HeaderChain - rmLogsFeed event.Feed - chainFeed event.Feed - chainHeadFeed event.Feed - logsFeed event.Feed - blockProcFeed event.Feed - scope event.SubscriptionScope - genesisBlock *types.Block + hc *HeaderChain + rmLogsFeed event.Feed + chainFeed event.Feed + chainHeadFeed event.Feed + logsFeed event.Feed + blockProcFeed event.Feed + blockProcCounter int32 + scope event.SubscriptionScope + genesisBlock *types.Block // This mutex synchronizes chain write operations. // Readers don't need to take it, they can just read the database. @@ -1574,8 +1575,6 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { if len(chain) == 0 { return 0, nil } - bc.blockProcFeed.Send(true) - defer bc.blockProcFeed.Send(false) // Do a sanity check that the provided chain is actually ordered and linked. for i := 1; i < len(chain); i++ { @@ -1615,6 +1614,16 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness if bc.insertStopped() { return nil, 0, nil } + + if atomic.AddInt32(&bc.blockProcCounter, 1) == 1 { + bc.blockProcFeed.Send(true) + } + defer func() { + if atomic.AddInt32(&bc.blockProcCounter, -1) == 0 { + bc.blockProcFeed.Send(false) + } + }() + // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) SenderCacher().RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain) From 5117f77af9339358699b7b9bf9a64cccdc9c6aed Mon Sep 17 00:00:00 2001 From: Chen Kai <281165273grape@gmail.com> Date: Thu, 13 Mar 2025 15:16:01 +0100 Subject: [PATCH 186/940] p2p/discover: expose discv5 functions for portal JSON-RPC interface (#31117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #31093 Here we add some API functions on the UDPv5 object for the purpose of implementing the Portal Network JSON-RPC API in the shisui client. --------- Signed-off-by: Chen Kai <281165273grape@gmail.com> --- cmd/devp2p/discv4cmd.go | 2 +- cmd/devp2p/discv5cmd.go | 3 +- p2p/discover/table.go | 8 ++++ p2p/discover/v4_udp.go | 19 ++++++--- p2p/discover/v5_udp.go | 82 +++++++++++++++++++++++++++++-------- p2p/discover/v5_udp_test.go | 4 +- 6 files changed, 92 insertions(+), 26 deletions(-) diff --git a/cmd/devp2p/discv4cmd.go b/cmd/devp2p/discv4cmd.go index 8c48b3a557..84c7ef0c44 100644 --- a/cmd/devp2p/discv4cmd.go +++ b/cmd/devp2p/discv4cmd.go @@ -163,7 +163,7 @@ func discv4Ping(ctx *cli.Context) error { defer disc.Close() start := time.Now() - if err := disc.Ping(n); err != nil { + if _, err := disc.Ping(n); err != nil { return fmt.Errorf("node didn't respond: %v", err) } fmt.Printf("node responded to ping (RTT %v).\n", time.Since(start)) diff --git a/cmd/devp2p/discv5cmd.go b/cmd/devp2p/discv5cmd.go index 2422ef6644..dd253dd082 100644 --- a/cmd/devp2p/discv5cmd.go +++ b/cmd/devp2p/discv5cmd.go @@ -84,7 +84,8 @@ func discv5Ping(ctx *cli.Context) error { disc, _ := startV5(ctx) defer disc.Close() - fmt.Println(disc.Ping(n)) + _, err := disc.Ping(n) + fmt.Println(err) return nil } diff --git a/p2p/discover/table.go b/p2p/discover/table.go index 392279f905..6a3d1af3af 100644 --- a/p2p/discover/table.go +++ b/p2p/discover/table.go @@ -694,3 +694,11 @@ func pushNode(list []*tableNode, n *tableNode, max int) ([]*tableNode, *tableNod list[0] = n return list, removed } + +// deleteNode removes a node from the table. +func (tab *Table) deleteNode(n *enode.Node) { + tab.mutex.Lock() + defer tab.mutex.Unlock() + b := tab.bucket(n.ID()) + tab.deleteInBucket(b, n.ID()) +} diff --git a/p2p/discover/v4_udp.go b/p2p/discover/v4_udp.go index 29ae5f2c08..dd3f363f7e 100644 --- a/p2p/discover/v4_udp.go +++ b/p2p/discover/v4_udp.go @@ -210,12 +210,6 @@ func (t *UDPv4) ourEndpoint() v4wire.Endpoint { return v4wire.NewEndpoint(addr, uint16(node.TCP())) } -// Ping sends a ping message to the given node. -func (t *UDPv4) Ping(n *enode.Node) error { - _, err := t.ping(n) - return err -} - // 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) { addr, ok := n.UDPEndpoint() @@ -229,6 +223,19 @@ func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) { return seq, err } +// Ping calls PING on a node and waits for a PONG response. +func (t *UDPv4) Ping(n *enode.Node) (pong *v4wire.Pong, err error) { + addr, ok := n.UDPEndpoint() + if !ok { + return nil, errNoUDPEndpoint + } + rm := t.sendPing(n.ID(), addr, nil) + if err = <-rm.errc; err == nil { + pong = rm.reply.(*v4wire.Pong) + } + return pong, err +} + // 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 netip.AddrPort, callback func()) *replyMatcher { diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 48256ea4de..9e849751c1 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -200,12 +200,6 @@ func (t *UDPv5) Close() { }) } -// Ping sends a ping message to the given node. -func (t *UDPv5) Ping(n *enode.Node) error { - _, err := t.ping(n) - return err -} - // Resolve searches for a specific node with the given ID and tries to get the most recent // version of the node record for it. It returns n if the node could not be resolved. func (t *UDPv5) Resolve(n *enode.Node) *enode.Node { @@ -226,6 +220,36 @@ func (t *UDPv5) Resolve(n *enode.Node) *enode.Node { return n } +// ResolveNodeId searches for a specific Node with the given ID. +// It returns nil if the nodeId could not be resolved. +func (t *UDPv5) ResolveNodeId(id enode.ID) *enode.Node { + if id == t.Self().ID() { + return t.Self() + } + + n := t.tab.getNode(id) + if n != nil { + // Try asking directly. This works if the Node is still responding on the endpoint we have. + if resp, err := t.RequestENR(n); err == nil { + return resp + } + } + + // Otherwise do a network lookup. + result := t.Lookup(id) + for _, rn := range result { + if rn.ID() == id { + if n != nil && rn.Seq() <= n.Seq() { + return n + } else { + return rn + } + } + } + + return n +} + // AllNodes returns all the nodes stored in the local table. func (t *UDPv5) AllNodes() []*enode.Node { t.tab.mutex.Lock() @@ -240,7 +264,18 @@ func (t *UDPv5) AllNodes() []*enode.Node { return nodes } -// LocalNode returns the current local node running the +// AddKnownNode adds a node to the routing table. +// The function should be used for testing only. +func (t *UDPv5) AddKnownNode(n *enode.Node) bool { + return t.tab.addFoundNode(n, true) +} + +// DeleteNode removes a node from the routing table. Used for Portal discv5 DeleteEnr API. +func (t *UDPv5) DeleteNode(n *enode.Node) { + t.tab.deleteNode(n) +} + +// LocalNode returns the current local Node running the // protocol. func (t *UDPv5) LocalNode() *enode.LocalNode { return t.localNode @@ -328,7 +363,7 @@ func (t *UDPv5) lookupWorker(destNode *enode.Node, target enode.ID) ([]*enode.No err error ) var r []*enode.Node - r, err = t.findnode(destNode, dists) + r, err = t.Findnode(destNode, dists) if errors.Is(err, errClosed) { return nil, err } @@ -359,21 +394,31 @@ func lookupDistances(target, dest enode.ID) (dists []uint) { // ping calls PING on a node and waits for a PONG response. func (t *UDPv5) ping(n *enode.Node) (uint64, error) { + pong, err := t.Ping(n) + if err != nil { + return 0, err + } + + return pong.ENRSeq, nil +} + +// Ping calls PING on a node and waits for a PONG response. +func (t *UDPv5) Ping(n *enode.Node) (*v5wire.Pong, error) { req := &v5wire.Ping{ENRSeq: t.localNode.Node().Seq()} resp := t.callToNode(n, v5wire.PongMsg, req) defer t.callDone(resp) select { case pong := <-resp.ch: - return pong.(*v5wire.Pong).ENRSeq, nil + return pong.(*v5wire.Pong), nil case err := <-resp.err: - return 0, err + return nil, err } } // RequestENR requests n's record. func (t *UDPv5) RequestENR(n *enode.Node) (*enode.Node, error) { - nodes, err := t.findnode(n, []uint{0}) + nodes, err := t.Findnode(n, []uint{0}) if err != nil { return nil, err } @@ -383,8 +428,8 @@ func (t *UDPv5) RequestENR(n *enode.Node) (*enode.Node, error) { return nodes[0], nil } -// findnode calls FINDNODE on a node and waits for responses. -func (t *UDPv5) findnode(n *enode.Node, distances []uint) ([]*enode.Node, error) { +// Findnode calls FINDNODE on a node and waits for responses. +func (t *UDPv5) Findnode(n *enode.Node, distances []uint) ([]*enode.Node, error) { resp := t.callToNode(n, v5wire.NodesMsg, &v5wire.Findnode{Distances: distances}) return t.waitForNodes(resp, distances) } @@ -736,8 +781,8 @@ func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr netip.AddrPort, p v return true } -// getNode looks for a node record in table and database. -func (t *UDPv5) getNode(id enode.ID) *enode.Node { +// GetNode looks for a node record in table and database. +func (t *UDPv5) GetNode(id enode.ID) *enode.Node { if n := t.tab.getNode(id); n != nil { return n } @@ -747,6 +792,11 @@ func (t *UDPv5) getNode(id enode.ID) *enode.Node { return nil } +// Nodes returns the nodes in the routing table. +func (t *UDPv5) Nodes() [][]BucketNode { + return t.tab.Nodes() +} + // handle processes incoming packets according to their message type. func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort) { switch p := p.(type) { @@ -776,7 +826,7 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort 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 { + if n := t.GetNode(fromID); n != nil { challenge.Node = n challenge.RecordSeq = n.Seq() } diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 8631b918ff..371f414760 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -288,7 +288,7 @@ func TestUDPv5_findnodeCall(t *testing.T) { ) go func() { var err error - response, err = test.udp.findnode(remote, distances) + response, err = test.udp.Findnode(remote, distances) done <- err }() @@ -398,7 +398,7 @@ func TestUDPv5_callTimeoutReset(t *testing.T) { done = make(chan error, 1) ) go func() { - _, err := test.udp.findnode(remote, []uint{distance}) + _, err := test.udp.Findnode(remote, []uint{distance}) done <- err }() From 444a6d007a08bddcec0b68b60ab507ea8bc1d078 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Thu, 13 Mar 2025 15:21:47 +0100 Subject: [PATCH 187/940] cmd/workload: implement checks for history-pruned node (#31355) Co-authored-by: Felix Lange --- cmd/workload/filtertest.go | 15 +++++---- cmd/workload/filtertestgen.go | 4 +-- cmd/workload/filtertestperf.go | 2 +- cmd/workload/historytest.go | 56 ++++++++++++++++++++++++---------- cmd/workload/testsuite.go | 37 +++++++++++++++++++--- 5 files changed, 85 insertions(+), 29 deletions(-) diff --git a/cmd/workload/filtertest.go b/cmd/workload/filtertest.go index 0e709ac0fe..bc76857911 100644 --- a/cmd/workload/filtertest.go +++ b/cmd/workload/filtertest.go @@ -108,7 +108,7 @@ func (s *filterTestSuite) filterFullRange(t *utesting.T) { } func (s *filterTestSuite) queryAndCheck(t *utesting.T, query *filterQuery) { - query.run(s.cfg.client) + query.run(s.cfg.client, s.cfg.historyPruneBlock) if query.Err != nil { t.Errorf("Filter query failed (fromBlock: %d toBlock: %d addresses: %v topics: %v error: %v)", query.FromBlock, query.ToBlock, query.Address, query.Topics, query.Err) return @@ -125,7 +125,7 @@ func (s *filterTestSuite) fullRangeQueryAndCheck(t *utesting.T, query *filterQue Address: query.Address, Topics: query.Topics, } - frQuery.run(s.cfg.client) + frQuery.run(s.cfg.client, s.cfg.historyPruneBlock) if frQuery.Err != nil { t.Errorf("Full range filter query failed (addresses: %v topics: %v error: %v)", frQuery.Address, frQuery.Topics, frQuery.Err) return @@ -197,7 +197,7 @@ func (fq *filterQuery) calculateHash() common.Hash { return crypto.Keccak256Hash(enc) } -func (fq *filterQuery) run(client *client) { +func (fq *filterQuery) run(client *client, historyPruneBlock *uint64) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() logs, err := client.Eth.FilterLogs(ctx, ethereum.FilterQuery{ @@ -207,10 +207,13 @@ func (fq *filterQuery) run(client *client) { Topics: fq.Topics, }) if err != nil { + if err = validateHistoryPruneErr(fq.Err, uint64(fq.FromBlock), historyPruneBlock); err == errPrunedHistory { + return + } else if err != nil { + fmt.Printf("Filter query failed: fromBlock: %d toBlock: %d addresses: %v topics: %v error: %v\n", + fq.FromBlock, fq.ToBlock, fq.Address, fq.Topics, err) + } fq.Err = err - fmt.Printf("Filter query failed: fromBlock: %d toBlock: %d addresses: %v topics: %v error: %v\n", - fq.FromBlock, fq.ToBlock, fq.Address, fq.Topics, err) - return } fq.results = logs } diff --git a/cmd/workload/filtertestgen.go b/cmd/workload/filtertestgen.go index 29aad9ddd9..e50ec57b47 100644 --- a/cmd/workload/filtertestgen.go +++ b/cmd/workload/filtertestgen.go @@ -70,7 +70,7 @@ func filterGenCmd(ctx *cli.Context) error { f.updateFinalizedBlock() query := f.newQuery() - query.run(f.client) + query.run(f.client, nil) if query.Err != nil { f.errors = append(f.errors, query) continue @@ -81,7 +81,7 @@ func filterGenCmd(ctx *cli.Context) error { if extQuery == nil { break } - extQuery.run(f.client) + extQuery.run(f.client, nil) if extQuery.Err == nil && len(extQuery.results) < len(query.results) { extQuery.Err = fmt.Errorf("invalid result length; old range %d %d; old length %d; new range %d %d; new length %d; address %v; Topics %v", query.FromBlock, query.ToBlock, len(query.results), diff --git a/cmd/workload/filtertestperf.go b/cmd/workload/filtertestperf.go index c1f2aff580..7f4cad4ab9 100644 --- a/cmd/workload/filtertestperf.go +++ b/cmd/workload/filtertestperf.go @@ -70,7 +70,7 @@ func filterPerfCmd(ctx *cli.Context) error { queries[pick] = queries[len(queries)-1] queries = queries[:len(queries)-1] start := time.Now() - qt.query.run(cfg.client) + qt.query.run(cfg.client, cfg.historyPruneBlock) qt.runtime = append(qt.runtime, time.Since(start)) slices.Sort(qt.runtime) qt.medianTime = qt.runtime[len(qt.runtime)/2] diff --git a/cmd/workload/historytest.go b/cmd/workload/historytest.go index a681510422..29fe3f5098 100644 --- a/cmd/workload/historytest.go +++ b/cmd/workload/historytest.go @@ -108,8 +108,11 @@ func (s *historyTestSuite) testGetBlockByHash(t *utesting.T) { for i, num := range s.tests.BlockNumbers { bhash := s.tests.BlockHashes[i] b, err := s.cfg.client.getBlockByHash(ctx, bhash, false) - if err != nil { - t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + if err = validateHistoryPruneErr(err, num, s.cfg.historyPruneBlock); err == errPrunedHistory { + continue + } else if err != nil { + t.Errorf("block %d (hash %v): error %v", num, bhash, err) + continue } if b == nil { t.Errorf("block %d (hash %v): not found", num, bhash) @@ -127,8 +130,11 @@ func (s *historyTestSuite) testGetBlockByNumber(t *utesting.T) { for i, num := range s.tests.BlockNumbers { bhash := s.tests.BlockHashes[i] b, err := s.cfg.client.getBlockByNumber(ctx, num, false) - if err != nil { - t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + if err = validateHistoryPruneErr(err, num, s.cfg.historyPruneBlock); err == errPrunedHistory { + continue + } else if err != nil { + t.Errorf("block %d (hash %v): error %v", num, bhash, err) + continue } if b == nil { t.Errorf("block %d (hash %v): not found", num, bhash) @@ -146,8 +152,11 @@ func (s *historyTestSuite) testGetBlockTransactionCountByHash(t *utesting.T) { for i, num := range s.tests.BlockNumbers { bhash := s.tests.BlockHashes[i] count, err := s.cfg.client.getBlockTransactionCountByHash(ctx, bhash) - if err != nil { - t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + if err = validateHistoryPruneErr(err, num, s.cfg.historyPruneBlock); err == errPrunedHistory { + continue + } else if err != nil { + t.Errorf("block %d (hash %v): error %v", num, bhash, err) + continue } expectedCount := uint64(s.tests.TxCounts[i]) if count != expectedCount { @@ -162,8 +171,11 @@ func (s *historyTestSuite) testGetBlockTransactionCountByNumber(t *utesting.T) { for i, num := range s.tests.BlockNumbers { bhash := s.tests.BlockHashes[i] count, err := s.cfg.client.getBlockTransactionCountByNumber(ctx, num) - if err != nil { - t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + if err = validateHistoryPruneErr(err, num, s.cfg.historyPruneBlock); err == errPrunedHistory { + continue + } else if err != nil { + t.Errorf("block %d (hash %v): error %v", num, bhash, err) + continue } expectedCount := uint64(s.tests.TxCounts[i]) if count != expectedCount { @@ -178,8 +190,11 @@ func (s *historyTestSuite) testGetBlockReceiptsByHash(t *utesting.T) { for i, num := range s.tests.BlockNumbers { bhash := s.tests.BlockHashes[i] receipts, err := s.cfg.client.getBlockReceipts(ctx, bhash) - if err != nil { - t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + if err = validateHistoryPruneErr(err, num, s.cfg.historyPruneBlock); err == errPrunedHistory { + continue + } else if err != nil { + t.Errorf("block %d (hash %v): error %v", num, bhash, err) + continue } hash := calcReceiptsHash(receipts) expectedHash := s.tests.ReceiptsHashes[i] @@ -195,8 +210,11 @@ func (s *historyTestSuite) testGetBlockReceiptsByNumber(t *utesting.T) { for i, num := range s.tests.BlockNumbers { bhash := s.tests.BlockHashes[i] receipts, err := s.cfg.client.getBlockReceipts(ctx, hexutil.Uint64(num)) - if err != nil { - t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + if err = validateHistoryPruneErr(err, num, s.cfg.historyPruneBlock); err == errPrunedHistory { + continue + } else if err != nil { + t.Errorf("block %d (hash %v): error %v", num, bhash, err) + continue } hash := calcReceiptsHash(receipts) expectedHash := s.tests.ReceiptsHashes[i] @@ -218,8 +236,11 @@ func (s *historyTestSuite) testGetTransactionByBlockHashAndIndex(t *utesting.T) } tx, err := s.cfg.client.getTransactionByBlockHashAndIndex(ctx, bhash, uint64(txIndex)) - if err != nil { - t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + if err = validateHistoryPruneErr(err, num, s.cfg.historyPruneBlock); err == errPrunedHistory { + continue + } else if err != nil { + t.Errorf("block %d (hash %v): error %v", num, bhash, err) + continue } if tx == nil { t.Errorf("block %d (hash %v): txIndex %d not found", num, bhash, txIndex) @@ -243,8 +264,11 @@ func (s *historyTestSuite) testGetTransactionByBlockNumberAndIndex(t *utesting.T } tx, err := s.cfg.client.getTransactionByBlockNumberAndIndex(ctx, num, uint64(txIndex)) - if err != nil { - t.Fatalf("block %d (hash %v): error %v", num, bhash, err) + if err = validateHistoryPruneErr(err, num, s.cfg.historyPruneBlock); err == errPrunedHistory { + continue + } else if err != nil { + t.Errorf("block %d (hash %v): error %v", num, bhash, err) + continue } if tx == nil { t.Errorf("block %d (hash %v): txIndex %d not found", num, bhash, txIndex) diff --git a/cmd/workload/testsuite.go b/cmd/workload/testsuite.go index 3e3ea1d001..e7019e2055 100644 --- a/cmd/workload/testsuite.go +++ b/cmd/workload/testsuite.go @@ -18,13 +18,17 @@ package main import ( "embed" + "fmt" "io/fs" "os" "slices" + "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/internal/utesting" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" "github.com/urfave/cli/v2" ) @@ -77,10 +81,31 @@ var ( // testConfig holds the parameters for testing. type testConfig struct { - client *client - fsys fs.FS - filterQueryFile string - historyTestFile string + client *client + fsys fs.FS + filterQueryFile string + historyTestFile string + historyPruneBlock *uint64 +} + +var errPrunedHistory = fmt.Errorf("attempt to access pruned history") + +// validateHistoryPruneErr checks whether the given error is caused by access +// to history before the pruning threshold block (it is an rpc.Error with code 4444). +// In this case, errPrunedHistory is returned. +// If the error is a pruned history error that occurs when accessing a block past the +// historyPrune block, an error is returned. +// Otherwise, the original value of err is returned. +func validateHistoryPruneErr(err error, blockNum uint64, historyPruneBlock *uint64) error { + if err != nil { + if rpcErr, ok := err.(rpc.Error); ok && rpcErr.ErrorCode() == 4444 { + if historyPruneBlock != nil && blockNum > *historyPruneBlock { + return fmt.Errorf("pruned history error returned after pruning threshold") + } + return errPrunedHistory + } + } + return err } func testConfigFromCLI(ctx *cli.Context) (cfg testConfig) { @@ -98,10 +123,14 @@ func testConfigFromCLI(ctx *cli.Context) (cfg testConfig) { cfg.fsys = builtinTestFiles cfg.filterQueryFile = "queries/filter_queries_mainnet.json" cfg.historyTestFile = "queries/history_mainnet.json" + cfg.historyPruneBlock = new(uint64) + *cfg.historyPruneBlock = ethconfig.HistoryPrunePoints[params.MainnetGenesisHash].BlockNumber case ctx.Bool(testSepoliaFlag.Name): cfg.fsys = builtinTestFiles cfg.filterQueryFile = "queries/filter_queries_sepolia.json" cfg.historyTestFile = "queries/history_sepolia.json" + cfg.historyPruneBlock = new(uint64) + *cfg.historyPruneBlock = ethconfig.HistoryPrunePoints[params.SepoliaGenesisHash].BlockNumber default: cfg.fsys = os.DirFS(".") cfg.filterQueryFile = ctx.String(filterQueryFileFlag.Name) From 78be413ca96fcdbb60265f4e8d80ce68a1fc890b Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 13 Mar 2025 18:54:20 +0100 Subject: [PATCH 188/940] eth/ethconfig: fix history prune blocks (#31383) --- eth/ethconfig/historymode.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/eth/ethconfig/historymode.go b/eth/ethconfig/historymode.go index cf904ab591..c3661004e8 100644 --- a/eth/ethconfig/historymode.go +++ b/eth/ethconfig/historymode.go @@ -76,15 +76,17 @@ type HistoryPrunePoint struct { } // HistoryPrunePoints contains the pre-defined history pruning cutoff blocks for known networks. +// They point to the first post-merge block. Any pruning should truncate *up to* but excluding +// given block. var HistoryPrunePoints = map[common.Hash]*HistoryPrunePoint{ // mainnet params.MainnetGenesisHash: { - BlockNumber: 15537394, - BlockHash: common.HexToHash("0x56a9bb0302da44b8c0b3df540781424684c3af04d0b7a38d72842b762076a664"), + BlockNumber: 15537393, + BlockHash: common.HexToHash("0x55b11b918355b1ef9c5db810302ebad0bf2544255b530cdce90674d5887bb286"), }, // sepolia params.SepoliaGenesisHash: { - BlockNumber: 1735371, - BlockHash: common.HexToHash("0x36fb89fba5b7857cf0ca78b5a9625b4043ff4555dfce9b7bcdcdd758a11eb946"), + BlockNumber: 1450409, + BlockHash: common.HexToHash("0x229f6b18ca1552f1d5146deceb5387333f40dc6275aebee3f2c5c4ece07d02db"), }, } From f9f1172d5988e9ef40dd5124a72c99bcbee01991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Thu, 13 Mar 2025 19:04:16 +0100 Subject: [PATCH 189/940] core/filtermaps: FilterMaps log index generator and search logic (#31079) This PR is #1 of a 3-part series that implements the new log index intended to replace core/bloombits. Replaces https://github.com/ethereum/go-ethereum/pull/30370 This part implements the new data structure, the log index generator and the search logic. This PR has most of the complexity but it does not affect any existing code yet so maybe it is easier to review separately. FilterMaps data structure explanation: https://gist.github.com/zsfelfoldi/a60795f9da7ae6422f28c7a34e02a07e Log index generator code overview: https://gist.github.com/zsfelfoldi/97105dff0b1a4f5ed557924a24b9b9e7 Search pattern matcher code overview: https://gist.github.com/zsfelfoldi/5981735641c956afb18065e84f8aff34 Note that the possibility of a tree hashing scheme and remote proof protocol are mentioned in the documents above but they are not exactly specified yet. These specs are WIP and will be finalized after the local log indexer/filter code is finalized and merged. --------- Co-authored-by: Felix Lange --- core/filtermaps/chain_view.go | 156 ++++ core/filtermaps/checkpoints.go | 63 ++ core/filtermaps/checkpoints_holesky.json | 20 + core/filtermaps/checkpoints_mainnet.json | 256 +++++++ core/filtermaps/checkpoints_sepolia.json | 63 ++ core/filtermaps/filtermaps.go | 726 ++++++++++++++++++ core/filtermaps/indexer.go | 395 ++++++++++ core/filtermaps/indexer_test.go | 444 +++++++++++ core/filtermaps/map_renderer.go | 768 +++++++++++++++++++ core/filtermaps/matcher.go | 934 +++++++++++++++++++++++ core/filtermaps/matcher_backend.go | 206 +++++ core/filtermaps/matcher_test.go | 87 +++ core/filtermaps/math.go | 212 +++++ core/filtermaps/math_test.go | 149 ++++ core/rawdb/accessors_indexes.go | 305 ++++++++ core/rawdb/database.go | 4 + core/rawdb/schema.go | 37 + 17 files changed, 4825 insertions(+) create mode 100644 core/filtermaps/chain_view.go create mode 100644 core/filtermaps/checkpoints.go create mode 100644 core/filtermaps/checkpoints_holesky.json create mode 100644 core/filtermaps/checkpoints_mainnet.json create mode 100644 core/filtermaps/checkpoints_sepolia.json create mode 100644 core/filtermaps/filtermaps.go create mode 100644 core/filtermaps/indexer.go create mode 100644 core/filtermaps/indexer_test.go create mode 100644 core/filtermaps/map_renderer.go create mode 100644 core/filtermaps/matcher.go create mode 100644 core/filtermaps/matcher_backend.go create mode 100644 core/filtermaps/matcher_test.go create mode 100644 core/filtermaps/math.go create mode 100644 core/filtermaps/math_test.go diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go new file mode 100644 index 0000000000..bc0de47ded --- /dev/null +++ b/core/filtermaps/chain_view.go @@ -0,0 +1,156 @@ +// Copyright 2025 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 filtermaps + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +// blockchain represents the underlying blockchain of ChainView. +type blockchain interface { + GetHeader(hash common.Hash, number uint64) *types.Header + GetCanonicalHash(number uint64) common.Hash + GetReceiptsByHash(hash common.Hash) types.Receipts +} + +// ChainView represents an immutable view of a chain with a block id and a set +// of receipts associated to each block number and a block hash associated with +// all block numbers except the head block. This is because in the future +// ChainView might represent a view where the head block is currently being +// created. Block id is a unique identifier that can also be calculated for the +// head block. +// Note that the view's head does not have to be the current canonical head +// of the underlying blockchain, it should only possess the block headers +// and receipts up until the expected chain view head. +type ChainView struct { + chain blockchain + headNumber uint64 + hashes []common.Hash // block hashes starting backwards from headNumber until first canonical hash +} + +// NewChainView creates a new ChainView. +func NewChainView(chain blockchain, number uint64, hash common.Hash) *ChainView { + cv := &ChainView{ + chain: chain, + headNumber: number, + hashes: []common.Hash{hash}, + } + cv.extendNonCanonical() + return cv +} + +// getBlockHash returns the block hash belonging to the given block number. +// Note that the hash of the head block is not returned because ChainView might +// represent a view where the head block is currently being created. +func (cv *ChainView) getBlockHash(number uint64) common.Hash { + if number >= cv.headNumber { + panic("invalid block number") + } + return cv.blockHash(number) +} + +// getBlockId returns the unique block id belonging to the given block number. +// Note that it is currently equal to the block hash. In the future it might +// be a different id for future blocks if the log index root becomes part of +// consensus and therefore rendering the index with the new head will happen +// before the hash of that new head is available. +func (cv *ChainView) getBlockId(number uint64) common.Hash { + if number > cv.headNumber { + panic("invalid block number") + } + return cv.blockHash(number) +} + +// getReceipts returns the set of receipts belonging to the block at the given +// block number. +func (cv *ChainView) getReceipts(number uint64) types.Receipts { + if number > cv.headNumber { + panic("invalid block number") + } + return cv.chain.GetReceiptsByHash(cv.blockHash(number)) +} + +// limitedView returns a new chain view that is a truncated version of the parent view. +func (cv *ChainView) limitedView(newHead uint64) *ChainView { + if newHead >= cv.headNumber { + return cv + } + return NewChainView(cv.chain, newHead, cv.blockHash(newHead)) +} + +// equalViews returns true if the two chain views are equivalent. +func equalViews(cv1, cv2 *ChainView) bool { + if cv1 == nil || cv2 == nil { + return false + } + return cv1.headNumber == cv2.headNumber && cv1.getBlockId(cv1.headNumber) == cv2.getBlockId(cv2.headNumber) +} + +// matchViews returns true if the two chain views are equivalent up until the +// specified block number. If the specified number is higher than one of the +// heads then false is returned. +func matchViews(cv1, cv2 *ChainView, number uint64) bool { + if cv1 == nil || cv2 == nil { + return false + } + if cv1.headNumber < number || cv2.headNumber < number { + return false + } + if number == cv1.headNumber || number == cv2.headNumber { + return cv1.getBlockId(number) == cv2.getBlockId(number) + } + return cv1.getBlockHash(number) == cv2.getBlockHash(number) +} + +// extendNonCanonical checks whether the previously known reverse list of head +// hashes still ends with one that is canonical on the underlying blockchain. +// If necessary then it traverses further back on the header chain and adds +// more hashes to the list. +func (cv *ChainView) extendNonCanonical() bool { + for { + hash, number := cv.hashes[len(cv.hashes)-1], cv.headNumber-uint64(len(cv.hashes)-1) + if cv.chain.GetCanonicalHash(number) == hash { + return true + } + if number == 0 { + log.Error("Unknown genesis block hash found") + return false + } + header := cv.chain.GetHeader(hash, number) + if header == nil { + log.Error("Header not found", "number", number, "hash", hash) + return false + } + cv.hashes = append(cv.hashes, header.ParentHash) + } +} + +// blockHash returns the given block hash without doing the head number check. +func (cv *ChainView) blockHash(number uint64) common.Hash { + if number+uint64(len(cv.hashes)) <= cv.headNumber { + hash := cv.chain.GetCanonicalHash(number) + if !cv.extendNonCanonical() { + return common.Hash{} + } + if number+uint64(len(cv.hashes)) <= cv.headNumber { + return hash + } + } + return cv.hashes[cv.headNumber-number] +} diff --git a/core/filtermaps/checkpoints.go b/core/filtermaps/checkpoints.go new file mode 100644 index 0000000000..f8d6500aa7 --- /dev/null +++ b/core/filtermaps/checkpoints.go @@ -0,0 +1,63 @@ +// Copyright 2025 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 filtermaps + +import ( + _ "embed" + "encoding/json" + + "github.com/ethereum/go-ethereum/common" +) + +// checkpointList lists checkpoints for finalized epochs of a given chain. +// This allows the indexer to start indexing from the latest available +// checkpoint and then index tail epochs in reverse order. +type checkpointList []epochCheckpoint + +// epochCheckpoint specified the last block of the epoch and the first log +// value index where that block starts. This allows a log value iterator to +// be initialized at the epoch boundary. +type epochCheckpoint struct { + BlockNumber uint64 // block that generated the last log value of the given epoch + BlockId common.Hash + FirstIndex uint64 // first log value index of the given block +} + +//go:embed checkpoints_mainnet.json +var checkpointsMainnetJSON []byte + +//go:embed checkpoints_sepolia.json +var checkpointsSepoliaJSON []byte + +//go:embed checkpoints_holesky.json +var checkpointsHoleskyJSON []byte + +// checkpoints lists sets of checkpoints for multiple chains. The matching +// checkpoint set is autodetected by the indexer once the canonical chain is +// known. +var checkpoints = []checkpointList{ + decodeCheckpoints(checkpointsMainnetJSON), + decodeCheckpoints(checkpointsSepoliaJSON), + decodeCheckpoints(checkpointsHoleskyJSON), +} + +func decodeCheckpoints(encoded []byte) (result checkpointList) { + if err := json.Unmarshal(encoded, &result); err != nil { + panic(err) + } + return +} diff --git a/core/filtermaps/checkpoints_holesky.json b/core/filtermaps/checkpoints_holesky.json new file mode 100644 index 0000000000..c30856db4f --- /dev/null +++ b/core/filtermaps/checkpoints_holesky.json @@ -0,0 +1,20 @@ +[ +{"blockNumber": 814411, "blockId": "0xf763e96fc3920359c5f706803024b78e83796a3a8563bb5a83c3ddd7cbfde287", "firstIndex": 67107637}, +{"blockNumber": 914278, "blockId": "0x0678cf8d53c0d6d27896df657d98cc73bc63ca468b6295068003938ef9b0f927", "firstIndex": 134217671}, +{"blockNumber": 1048874, "blockId": "0x3620c3d52a40ff4d9fc58c3104cfa2f327f55592caf6a2394c207a5e00b4f740", "firstIndex": 201326382}, +{"blockNumber": 1144441, "blockId": "0x438fb42850f5a0d8e1666de598a4d0106b62da0f7448c62fe029b8cbad35d08d", "firstIndex": 268435440}, +{"blockNumber": 1230411, "blockId": "0xf0ee07e60a93910723b259473a253dd9cf674e8b78c4f153b32ad7032efffeeb", "firstIndex": 335543079}, +{"blockNumber": 1309112, "blockId": "0xc1646e5ef4b4343880a85b1a4111e3321d609a1225e9cebbe10d1c7abf99e58d", "firstIndex": 402653100}, +{"blockNumber": 1380522, "blockId": "0x1617cae91989d97ac6335c4217aa6cc7f7f4c2837e20b3b5211d98d6f9e97e44", "firstIndex": 469761917}, +{"blockNumber": 1476962, "blockId": "0xd978455d2618d093dfc685d7f43f61be6dae0fa8a9cb915ae459aa6e0a5525f0", "firstIndex": 536870773}, +{"blockNumber": 1533518, "blockId": "0xe7d39d71bd9d5f1f3157c35e0329531a7950a19e3042407e38948b89b5384f78", "firstIndex": 603979664}, +{"blockNumber": 1613787, "blockId": "0xa793168d135c075732a618ec367faaed5f359ffa81898c73cb4ec54ec2caa696", "firstIndex": 671088003}, +{"blockNumber": 1719099, "blockId": "0xc4394c71a8a24efe64c5ff2afcdd1594f3708524e6084aa7dadd862bd704ab03", "firstIndex": 738196914}, +{"blockNumber": 1973165, "blockId": "0xee3a9e959a437c707a3036736ec8d42a9261ac6100972c26f65eedcde315a81d", "firstIndex": 805306333}, +{"blockNumber": 2274844, "blockId": "0x76e2d33653ed9282c63ad09d721e1f2e29064aa9c26202e20fc4cc73e8dfe5f6", "firstIndex": 872415141}, +{"blockNumber": 2530503, "blockId": "0x59f4e45345f8b8f848be5004fe75c4a28f651864256c3aa9b2da63369432b718", "firstIndex": 939523693}, +{"blockNumber": 2781903, "blockId": "0xc981e91c6fb69c5e8146ead738fcfc561831f11d7786d39c7fa533966fc37675", "firstIndex": 1006632906}, +{"blockNumber": 3101713, "blockId": "0xc7baa577c91d8439e3fc79002d2113d07ca54a4724bf2f1f5af937b7ba8e1f32", "firstIndex": 1073741382}, +{"blockNumber": 3221770, "blockId": "0xa6b8240b7883fcc71aa5001b5ba66c889975c5217e14c16edebdd6f6e23a9424", "firstIndex": 1140850360} +] + diff --git a/core/filtermaps/checkpoints_mainnet.json b/core/filtermaps/checkpoints_mainnet.json new file mode 100644 index 0000000000..d2b031a474 --- /dev/null +++ b/core/filtermaps/checkpoints_mainnet.json @@ -0,0 +1,256 @@ +[ +{"blockNumber": 4166218, "blockId": "0xdd767e0426256179125551e8e40f33565a96d1c94076c7746fa79d767ed4ad65", "firstIndex": 67108680}, +{"blockNumber": 4514014, "blockId": "0x33a0879bdabea4a7a3f2b424388cbcbf2fbd519bddadf13752a259049c78e95d", "firstIndex": 134217343}, +{"blockNumber": 4817415, "blockId": "0x4f0e8c7dd04fbe0985b9394575b19f13ea66a2a628fa5b08178ce4b138c6db80", "firstIndex": 201326352}, +{"blockNumber": 5087733, "blockId": "0xc84cd5e9cda999c919803c7a53a23bb77a18827fbde401d3463f1e9e52536424", "firstIndex": 268435343}, +{"blockNumber": 5306107, "blockId": "0x13f028b5fc055d23f55a92a2eeecfbcfbda8a08e4cd519ce451ba2e70428f5f9", "firstIndex": 335544094}, +{"blockNumber": 5509918, "blockId": "0x1ed770a58a7b4d4a828b7bb44c8820a674d562b23a6a0139981abe4c489d4dad", "firstIndex": 402652853}, +{"blockNumber": 5670390, "blockId": "0x3923ee6a62e6cc5132afdadf1851ae4e73148e6fbe0a8319cafd2a120c98efa3", "firstIndex": 469761897}, +{"blockNumber": 5826139, "blockId": "0xe61bc6ef03c333805f26319e1688f82553f98aa5e902b200e0621a3371b69050", "firstIndex": 536870853}, +{"blockNumber": 5953029, "blockId": "0x43d710b1b7243b848400975048ccefdfaba091c692c7f01c619d988886cc160f", "firstIndex": 603979580}, +{"blockNumber": 6102846, "blockId": "0xa100b2018f6545cc689656b4b846677b138955b7efd30e850cd14c246430ba18", "firstIndex": 671088291}, +{"blockNumber": 6276718, "blockId": "0xb832ac448b06c104ba50faefd58b0b94d53c0fba5cb268086adad4db99c2f35f", "firstIndex": 738197399}, +{"blockNumber": 6448696, "blockId": "0x48e8ae6f729ad6c76b6cf632bd52a6df7886ed55be09d43c5004fcc1463e533b", "firstIndex": 805305988}, +{"blockNumber": 6655974, "blockId": "0xac395971a6ffc30f807848f68b97b2834f8ea13478a7615860b6a69e3d0823ca", "firstIndex": 872415033}, +{"blockNumber": 6873949, "blockId": "0xc522ddb1113b1e9a87b2bdcb11ce78756beba6454a890122f121a032b5769354", "firstIndex": 939523784}, +{"blockNumber": 7080953, "blockId": "0x3606de577d80120d1edbb64bad7fa6795e788bae342866a98cc58ce2f7575045", "firstIndex": 1006632796}, +{"blockNumber": 7267002, "blockId": "0xad770882a69d216e955e34fef84851e56c0de82deacd6187a7a41f6170cd6c6d", "firstIndex": 1073741045}, +{"blockNumber": 7466708, "blockId": "0x17a48817b3a65aba333a5b56f3ff2e86fbcc19e184b046a5305a5182fdd8eb8a", "firstIndex": 1140850680}, +{"blockNumber": 7661807, "blockId": "0xa74731ee775fbd3f4d9313c68562737dd7c8d2c9eb968791d8abe167e16ddc96", "firstIndex": 1207959112}, +{"blockNumber": 7834556, "blockId": "0xe4b4812448075508cb05a0e3257f91b49509dc78cd963676a633864db6e78956", "firstIndex": 1275068095}, +{"blockNumber": 7990068, "blockId": "0x07bd4ca38abb4584a6209e04035646aa545ebbb6c948d438d4c25bfd9cb205fa", "firstIndex": 1342176620}, +{"blockNumber": 8143032, "blockId": "0x0e3149e9637290b044ee693b8fcb66e23d22db3ad0bdda32962138ba18e59f3f", "firstIndex": 1409285949}, +{"blockNumber": 8297660, "blockId": "0x34cd24f80247f7dfaf316b2e637f4b62f72ecc90703014fb25cb98ad044fc2c0", "firstIndex": 1476394911}, +{"blockNumber": 8465137, "blockId": "0x4452fa296498248d7f10c9dc6ec1e4ae7503aa07f491e6d38b21aea5d2c658a8", "firstIndex": 1543503744}, +{"blockNumber": 8655820, "blockId": "0x7bdb9008b30be420f7152cc294ac6e5328eed5b4abd954a34105de3da24f3cc6", "firstIndex": 1610612619}, +{"blockNumber": 8807187, "blockId": "0xde03e3bfddc722c019f0b59bc55efabcd5ab68c6711f4c08d0390a56f396590d", "firstIndex": 1677721589}, +{"blockNumber": 8911171, "blockId": "0xe44f342de74ab05a2a994f8841bdf88f720b9dc260177ba4030d0f7077901324", "firstIndex": 1744830310}, +{"blockNumber": 8960320, "blockId": "0x79764f9ff6e0fe4848eda1805687872021076e4e603112861af84181395ac559", "firstIndex": 1811938893}, +{"blockNumber": 9085994, "blockId": "0x24a101d1c8a63367a0953d10dc79c3b587a93bd7fd382084708adefce0b8363f", "firstIndex": 1879047965}, +{"blockNumber": 9230924, "blockId": "0xb176a98d3acd855cbb75265fb6be955a8d51abc771e021e13275d5b3ecb07eeb", "firstIndex": 1946156668}, +{"blockNumber": 9390535, "blockId": "0x640f5e2d511a5141878d57ae7a619f19b72a2bd3ef019cf0a22d74d93d9acf07", "firstIndex": 2013265733}, +{"blockNumber": 9515674, "blockId": "0xff4a7b6b21aeaeb6e1a75ecd22b1f34c058a0ce1477ce90a8ce78165fd1d0941", "firstIndex": 2080374553}, +{"blockNumber": 9659426, "blockId": "0xc351455249343b41e9171e183612b68c3c895271c62bd2c53d9e3ab1aa865aa1", "firstIndex": 2147483567}, +{"blockNumber": 9794018, "blockId": "0xde98035b4b7f9449c256239b65c7ff2c0330de44dee190106d0a96fb6f683238", "firstIndex": 2214592213}, +{"blockNumber": 9923840, "blockId": "0x881da313a1e2b6fab58a1d6fa65b5dacfdc9d68a3112a647104955b5233f84e3", "firstIndex": 2281701302}, +{"blockNumber": 10042435, "blockId": "0x451f6459640a6f54e2a535cc3a49cfc469861da3ddc101840ab3aef9e17fa424", "firstIndex": 2348810174}, +{"blockNumber": 10168883, "blockId": "0x5d16ff5adf0df1e4dc810da60af37399ef733be7870f21112b8c2cfff4995dd9", "firstIndex": 2415918783}, +{"blockNumber": 10289554, "blockId": "0x85d5690f15a787c43b9a49e8dd6e324f0b3e0c9796d07c0cfb128e5c168f5488", "firstIndex": 2483027930}, +{"blockNumber": 10386676, "blockId": "0x20f675ea72db448024a8a0b8e3ec180cac37a5910575bc32f8d9f5cdfe3c2649", "firstIndex": 2550136212}, +{"blockNumber": 10479675, "blockId": "0x014abb07acf2330cc78800ca1f564928f2daccca4b389bf5c59f4b840d843ec0", "firstIndex": 2617245218}, +{"blockNumber": 10562661, "blockId": "0xd437607a3f81ce8b7c605e167ce5e52bf8a3e02cdc646997bd0ccc57a50ad7d1", "firstIndex": 2684354520}, +{"blockNumber": 10641508, "blockId": "0x2e8ab6470c29f90ac23dcfc58310f0208f5d0e752a0c7982a77a223eca104082", "firstIndex": 2751462730}, +{"blockNumber": 10717156, "blockId": "0x8820447b6429dd12be603c1c130be532e9db065bb4bc6b2a9d4551794d63789a", "firstIndex": 2818571831}, +{"blockNumber": 10784549, "blockId": "0xc557daab80a7cdc963d62aa881faf3ab1baceff8e027046bcd203e432e0983b3", "firstIndex": 2885680800}, +{"blockNumber": 10848651, "blockId": "0xede1b0de5db6685a6f589096ceb8fccb08d3ff60e8b00a93caa4a775b48e07fc", "firstIndex": 2952789740}, +{"blockNumber": 10909166, "blockId": "0x989db675899d13323006a4d6174557e3c5501c672afd60d8bd902fc98d37e92e", "firstIndex": 3019897599}, +{"blockNumber": 10972902, "blockId": "0x5484050cc2c7d774bc5cd6af1c2ef8c19d1de12dabe25867c9b365924ea10434", "firstIndex": 3087007422}, +{"blockNumber": 11036597, "blockId": "0x1e3686e19056587c385262d5b0a07b3ec04e804c2d59e9aaca1e5876e78f69ae", "firstIndex": 3154116231}, +{"blockNumber": 11102520, "blockId": "0x339cf302fe813cce3bb9318b860dfa8be7f688413f38a6ea1987a1b84d742b4b", "firstIndex": 3221224863}, +{"blockNumber": 11168162, "blockId": "0xc0fa21ea090627610bcac4732dff702633f310cabafc42bc500d3d4805198fe0", "firstIndex": 3288334273}, +{"blockNumber": 11233707, "blockId": "0x491c37a479b8cf22eaa3654ae34c5ddc4627df8c58ca8a6979159e1710428576", "firstIndex": 3355442691}, +{"blockNumber": 11300526, "blockId": "0xb7366d2a24df99002cffe0c9a00959c93ef0dcfc3fd17389e2020bf5caa788eb", "firstIndex": 3422551480}, +{"blockNumber": 11367621, "blockId": "0xce53df5080c5b5238bb7717dfbfd88c2f574cfbb3d91f92b57171a00e9776cd2", "firstIndex": 3489660710}, +{"blockNumber": 11431881, "blockId": "0x2a08ff9c4f6fd152166213d902f0870822429f01d5f90e384ac54a3eac0ceb3a", "firstIndex": 3556768626}, +{"blockNumber": 11497107, "blockId": "0x1f99c6b65f2b1cb06ed1786c6a0274ff1b9eacab6cb729fcd386f10ebbd88123", "firstIndex": 3623878389}, +{"blockNumber": 11560104, "blockId": "0xebe6924817bbdfe52af49667da1376bae5a2994b375d4b996e8ff2683744e37a", "firstIndex": 3690986640}, +{"blockNumber": 11625129, "blockId": "0xbe6eee325329ee2fe632d8576864c29dd1c79bab891dc0a22d5b2ac87618d26e", "firstIndex": 3758095773}, +{"blockNumber": 11690397, "blockId": "0xc28bf55f858ddf5b82d1ceb3b5258b90a9ca34df8863a1c652c4d359f5748fdf", "firstIndex": 3825204492}, +{"blockNumber": 11755087, "blockId": "0x0c10cde6ce1bbe24dc57347fe4aaebc17b7d8e8d7d97e3db573133477f494740", "firstIndex": 3892314051}, +{"blockNumber": 11819674, "blockId": "0x36b694a1776c94e4c6ae4a410931b2086de47a83e437517040e3290ce9afff67", "firstIndex": 3959422445}, +{"blockNumber": 11883358, "blockId": "0x21f447aca9ddf94ed71df9fa3648a12acc2ba603f89f24c4784936864c41945f", "firstIndex": 4026531743}, +{"blockNumber": 11948524, "blockId": "0x71a52b6cce80d3a552b0daa18beb952facf81a89bc7ca769d08ac297f317507a", "firstIndex": 4093640009}, +{"blockNumber": 12013168, "blockId": "0x9a7fb369b8d8cd0edd0d890d636096f20c63abb7eb5798ad1e578cac599e3db8", "firstIndex": 4160748475}, +{"blockNumber": 12078711, "blockId": "0x5de09329413b0c2f58d926f225197552a335ba3d5544d7bdb45e7574f78c9b8d", "firstIndex": 4227858275}, +{"blockNumber": 12143640, "blockId": "0xbeafc0e1e0586f5a95f00f2a796d7df122c79c187aa2d917129297f24b8306bd", "firstIndex": 4294967145}, +{"blockNumber": 12208005, "blockId": "0x052487095cdd4a604808e6c14e30fb68b3fa546d35585b315f287219d38ef77c", "firstIndex": 4362075289}, +{"blockNumber": 12272465, "blockId": "0x82c8a50413bd67a0d6f53b085adcd9ae8c25ecc07ed766fa80297a8dcae63b29", "firstIndex": 4429184610}, +{"blockNumber": 12329418, "blockId": "0x294c147e48d32c217ff3f27a3c8c989f15eee57a911408ec4c28d4f13a36bb3b", "firstIndex": 4496292968}, +{"blockNumber": 12382388, "blockId": "0x8c2555965ff735690d2d94ececc48df4700e079c7b21b8e601a30d4e99bc4b5b", "firstIndex": 4563401809}, +{"blockNumber": 12437052, "blockId": "0x2e38362031f36a0f3394da619dcc03be03c19700594cbd1df84c2c476a87de63", "firstIndex": 4630511012}, +{"blockNumber": 12490026, "blockId": "0x122749c02a55c9c2a1e69068f54b6c1d25419eb743e3553aba91acf1daeadc35", "firstIndex": 4697619920}, +{"blockNumber": 12541747, "blockId": "0xfb9f12aa2902da798ac05fab425434f8c7ce98050d67d416dbb32f98c21f66f7", "firstIndex": 4764728267}, +{"blockNumber": 12597413, "blockId": "0x9a7a399c2904ac8d0fec580550525e7e1a73d8f65f739bf7c05d86e389d0d3f7", "firstIndex": 4831837757}, +{"blockNumber": 12651950, "blockId": "0xb78dcb572cdafb9c4e2f3863ef518a3b2df0cd4f76faa26a423b2ca0c1cde734", "firstIndex": 4898946491}, +{"blockNumber": 12706472, "blockId": "0xfd21f41ec6b0c39287d7d48c134d1212a261c53d65db99739994b003150bbad1", "firstIndex": 4966054796}, +{"blockNumber": 12762929, "blockId": "0xc94d994bc40b2ae7dc23cf2b92cc01e84915f090bb57c0d9a67584bd564d3916", "firstIndex": 5033164307}, +{"blockNumber": 12816689, "blockId": "0x7770c72f22cbf6ccf7ab85d203088f7ede89632cf0042c690102f926a90bd09d", "firstIndex": 5100273412}, +{"blockNumber": 12872408, "blockId": "0x2e008b8c952d828875d777f7912f472af96ffc977f2ceae884006682cab6b8ed", "firstIndex": 5167381625}, +{"blockNumber": 12929718, "blockId": "0x85eb0ed3c5910c6a01b65ef0a5b76c59c2cdb5094e6e27eb87c751d77bcc2c88", "firstIndex": 5234491305}, +{"blockNumber": 12988757, "blockId": "0xdf12045bea73af18d4e71f8be8e334160f78b85f96a3535a4056409d8b61355a", "firstIndex": 5301600237}, +{"blockNumber": 13049172, "blockId": "0xf07608d97a101cd9a95fee9d9062a15bcb333263e555f8cfa31da037e0468f30", "firstIndex": 5368709080}, +{"blockNumber": 13108936, "blockId": "0x42739341db582d2f39b91ec9e8cc758777ca3f6ff9f25cd98883619fd5f026a7", "firstIndex": 5435817013}, +{"blockNumber": 13175495, "blockId": "0x564f25eacb229350b7c648b5828169e7a0344ae62e866206828e2cfad8947f10", "firstIndex": 5502926476}, +{"blockNumber": 13237721, "blockId": "0x0973425abec0fa6319701b46e07c2373b0580e3adbed6900aad27d5bf26dcb95", "firstIndex": 5570035419}, +{"blockNumber": 13298771, "blockId": "0xf3a16fec5be808c9f7782fb578dc8cef7f8e2110f7289bd03c0cc13977dd1518", "firstIndex": 5637143840}, +{"blockNumber": 13361281, "blockId": "0x3c0b6364201ca9221b61af3de27a3a87e111870b8c7efc43a6d8496e98c68690", "firstIndex": 5704253046}, +{"blockNumber": 13421819, "blockId": "0x2f472e57997b95558b99e3e5e7e0e8d4dbf8b71c081aac6536c9ff5925dac2ce", "firstIndex": 5771361231}, +{"blockNumber": 13480620, "blockId": "0xc4d689e87464a0c83c661c8e3a0614c370631de857f7e385b161dfe8bacd3e71", "firstIndex": 5838469468}, +{"blockNumber": 13535793, "blockId": "0xe7674bacc8edce9fb3efd59b92c97da48fe7ace1de314b4a67d7d032fc3bb680", "firstIndex": 5905578026}, +{"blockNumber": 13590588, "blockId": "0x6a3e86bdce7dd7d8792e1af9156edd8c3ffee7c20fed97001f58a9a2699f6594", "firstIndex": 5972687757}, +{"blockNumber": 13646707, "blockId": "0xab404a5d3709cf571b04e9493f37116eeb5dd2bc9dc10c48387c1e0199013d69", "firstIndex": 6039797165}, +{"blockNumber": 13703025, "blockId": "0x20e2fde15b8fe56f5dd7ab0f324c552038167ed44864bf3978e531ae68d6d138", "firstIndex": 6106905803}, +{"blockNumber": 13761024, "blockId": "0x2ae49275e13e780f1d29aea8507b2a708ff7bfe977efac93e050273b8b3a8164", "firstIndex": 6174015107}, +{"blockNumber": 13819468, "blockId": "0xb9d19cb31dedb1128b11cad9ffd6e58c70fe7ba65ba68f1ac63668ac5160ad85", "firstIndex": 6241124350}, +{"blockNumber": 13877932, "blockId": "0x80b1ff0bb069a8479360a15eaa84ba30da02cfacadc564837f4b1c90478addb8", "firstIndex": 6308232256}, +{"blockNumber": 13935384, "blockId": "0xe1f5469a559a6114dd469af61b118b9d9551a69bbd49a4e88f2a2d724830c871", "firstIndex": 6375341632}, +{"blockNumber": 13994042, "blockId": "0x25188fb75f2328c870ade7c38ef42ff5fddef9c4e364eebe4c5d8d9cc3ecabab", "firstIndex": 6442449799}, +{"blockNumber": 14051123, "blockId": "0xf4ef2bce9ee9222bdcf6b3a0c204676d9345e211e10c983e523930274e041ef1", "firstIndex": 6509559107}, +{"blockNumber": 14109189, "blockId": "0x80b730c28f75d8cb5ec2fb736341cd87cb4ecb2c9c614e0a4ecc0f9812675d50", "firstIndex": 6576667347}, +{"blockNumber": 14166822, "blockId": "0xf662a24b91684fa8ac462b31071f406de8d6183dba46d30d690f4407bc6af36f", "firstIndex": 6643777079}, +{"blockNumber": 14222488, "blockId": "0x7333e324c96b12f11a38d1fc2ddb4860e018b90f5dc10f3dbe19f7679bb95535", "firstIndex": 6710885890}, +{"blockNumber": 14277180, "blockId": "0x4373c1000e8e10179657689e2f0e42f88bd1601ecb4a5d83970d10287f6654cc", "firstIndex": 6777994595}, +{"blockNumber": 14331080, "blockId": "0x9c708a750a3f284ec0ee950110b36fd488cb1ec24cd0c2ea72c19551ec5c42a5", "firstIndex": 6845103719}, +{"blockNumber": 14384243, "blockId": "0x34ce7503b76335aa18dec880b0cefd388a29e0fcff6f2e1ddda8fb8c0ac1daf0", "firstIndex": 6912212376}, +{"blockNumber": 14437670, "blockId": "0x79842efd3e406b41f51935fe2e6ad20a7dd5a9db2280ebd7f602ed93da1e3c24", "firstIndex": 6979320543}, +{"blockNumber": 14489204, "blockId": "0xcd12addf0afdc229e9fe3bd0a34677a3826c5e78d4baf715f8ed36b736d6627a", "firstIndex": 7046430591}, +{"blockNumber": 14541688, "blockId": "0x55f617abf208a73fc467e8cb5feead586b671dbb0f6281570b3c44b8eabb2b9e", "firstIndex": 7113538755}, +{"blockNumber": 14594551, "blockId": "0xc7211bf772e93c8c2f945fcb6098b47c3455604cb8b94a505cb5cb720914c369", "firstIndex": 7180646025}, +{"blockNumber": 14645065, "blockId": "0x6d5b0326f4b22e2b0196986a514f23ec6e9a62f70f53300a22b21ff661a6ef7e", "firstIndex": 7247756883}, +{"blockNumber": 14695926, "blockId": "0x0a77272250e43b4bb46c02eb76944881a3c6b00a21bb9086a8229199bd62d97a", "firstIndex": 7314865843}, +{"blockNumber": 14746330, "blockId": "0xd677fdbaf8efb1bfdc138ac6b2bd5d0e890a29acb1f52f40169181ad517b0d31", "firstIndex": 7381974956}, +{"blockNumber": 14798546, "blockId": "0xbb277e8623acd2ce2340cf32f6c0ddab70fd95d862287f68a3c37250a70619cd", "firstIndex": 7449082890}, +{"blockNumber": 14848230, "blockId": "0x587b39f11bdaa2091291c7c3947e88df2e91e7997f2375dfd43b6e310a538582", "firstIndex": 7516192636}, +{"blockNumber": 14897646, "blockId": "0xf5b5c9d0c024ca0c0f0c6171871f609687f4ccb064ededbd61176cf23a9011e8", "firstIndex": 7583299602}, +{"blockNumber": 14950782, "blockId": "0x50549486afaf92a4c3520012b325e914ef77a82e4d6530a71f9b1cca31bfae18", "firstIndex": 7650409868}, +{"blockNumber": 15004101, "blockId": "0x7edac55dea3ee4308db60b9bc0524836226fe301e085b3ce39105bd145ba7fc3", "firstIndex": 7717517503}, +{"blockNumber": 15056903, "blockId": "0xb4cfd02d435718598179cdba3f5c11eb8653fe97ec8d89c60673e3e07b8dfc94", "firstIndex": 7784627997}, +{"blockNumber": 15108302, "blockId": "0x53c77a7de4515e9e93467a76f04cc401834bcdd64e9dfa03cf6d2844a6930293", "firstIndex": 7851736988}, +{"blockNumber": 15159526, "blockId": "0x1a31ad84b423254d7ff24e7eca54048ed8cc13cec5eb7289bf3f98ed4de9f724", "firstIndex": 7918844431}, +{"blockNumber": 15211013, "blockId": "0xe5d491e1d6cc5322454143b915c106be1bf28114a41b054ba5e5cfe0abecafba", "firstIndex": 7985953942}, +{"blockNumber": 15264389, "blockId": "0xd9939bb9e58e95d2672c1148b4ec5730204527d3f3fc98ca03a67dc85cf3d710", "firstIndex": 8053063187}, +{"blockNumber": 15315862, "blockId": "0x7254f99c4bb05235d5b437984c9132164e33182d4ce11a3847999da5c28b4092", "firstIndex": 8120172147}, +{"blockNumber": 15364726, "blockId": "0x11b57547579d9009679e327f57e308fe86856391805bc3c86e7b39daae890f52", "firstIndex": 8187281042}, +{"blockNumber": 15412886, "blockId": "0xbe3602b1dbef9015a3ec7968ac7652edf4424934b6bf7b713b99d8556f1d9444", "firstIndex": 8254390023}, +{"blockNumber": 15462792, "blockId": "0x3348ca4e14ac8d3c6ac6df676deaf3e3b5e0a11b599f73bd9739b74ebd693efe", "firstIndex": 8321499024}, +{"blockNumber": 15509914, "blockId": "0xbc98fd6b71438d5a169f9373172fea799fa3d22a8e6fe648d35e1070f2261113", "firstIndex": 8388606521}, +{"blockNumber": 15558748, "blockId": "0x5fa2cf499276ae74a5b8618990e71ed11a063619afe25c01b46e6252eba14c19", "firstIndex": 8455716577}, +{"blockNumber": 15604217, "blockId": "0x78a608e13d2eb3c5fed81a19b829ede88071cf01ea9ff58112a7472435f97c30", "firstIndex": 8522825668}, +{"blockNumber": 15651869, "blockId": "0xd465d861d925d1475440782ff16c2b3361ba3c8e169d7cc90eb8dfc0f31b0aac", "firstIndex": 8589934080}, +{"blockNumber": 15700968, "blockId": "0x71e3def131271e02c06ca945d14a995703a48faac1334a9e2e2321edd0b504d0", "firstIndex": 8657043390}, +{"blockNumber": 15762986, "blockId": "0x9b1b51dca2eae29162ca66968a77b45175f134b44aea3defadcb924f83e0b944", "firstIndex": 8724151376}, +{"blockNumber": 15814455, "blockId": "0x3c04a509cb6304d3df4bef57e0119d9e615ab737ec0b4a7deada6e5f57d9f873", "firstIndex": 8791260562}, +{"blockNumber": 15865639, "blockId": "0x9e9e26148c774518ecf362c0e7c65a5c1b054a8a3e4e36036c70e273fac6147c", "firstIndex": 8858368894}, +{"blockNumber": 15920564, "blockId": "0x9efe1d4dbfd9aa891ac0cffd3e1422a27ba2ea4add211b6900a2242cdb0f0ca0", "firstIndex": 8925477950}, +{"blockNumber": 15974371, "blockId": "0xc63ccef7bc35a0b431a411f99fe581b322d00cfc6422d078696808a5658a32ac", "firstIndex": 8992587107}, +{"blockNumber": 16032913, "blockId": "0x3e60957224964669a8646914e3166553b9f4256d5be160b17995d838af3ef137", "firstIndex": 9059696632}, +{"blockNumber": 16091057, "blockId": "0x12b346047bb49063ab6d9e737775924cf05c52114202ddb1a2bdaf9caabbfe0c", "firstIndex": 9126804912}, +{"blockNumber": 16150977, "blockId": "0x49318a32ff0ce979c4061c1c34db2a94fb06e7669c93742b75aff14a134fa598", "firstIndex": 9193913896}, +{"blockNumber": 16207432, "blockId": "0xf7870865edf81be4389a0be01468da959de703df0d431610814d16ed480176e4", "firstIndex": 9261019778}, +{"blockNumber": 16262582, "blockId": "0x25818e0f4d54af6c44ef7b23add34409a47de3ab1c905889478f3ec8ad173ec3", "firstIndex": 9328131320}, +{"blockNumber": 16319695, "blockId": "0x25de4b1c18cc503f5d12b4fa9072d33a11fa503a3dbeb9ab3d016b57c1e5cd4d", "firstIndex": 9395240790}, +{"blockNumber": 16373605, "blockId": "0x3794a5e0d2aa10baf1e6a5ec623d6089fdd39799eff633017d8df5144526939f", "firstIndex": 9462349509}, +{"blockNumber": 16423494, "blockId": "0xe0217d947ba3865dfc9288e0c890b0996457bb9d18467bd125e86bbb0052b57f", "firstIndex": 9529458033}, +{"blockNumber": 16474853, "blockId": "0xd454f033d190f22f9e56f0209ea1eeb3b6257805d5d88650d2759eb4d24821b7", "firstIndex": 9596567055}, +{"blockNumber": 16525689, "blockId": "0x8a23cbbf3e258e13f5a1ada434366796cb4a3e5b1062455582fb2bc3ab991541", "firstIndex": 9663674943}, +{"blockNumber": 16574203, "blockId": "0xc1a5b7d26e8222bd2d56ef4108f75d69f7c116707d348950834e00962241a4f8", "firstIndex": 9730785112}, +{"blockNumber": 16622622, "blockId": "0x3ddb3ef7a4309bd788258fb0d62613c89a0b4de715f4e12f6017a194d19d6481", "firstIndex": 9797893665}, +{"blockNumber": 16672585, "blockId": "0x8aa5e9f72b261f9e2a9eb768483d1bbd84d3a88fdb1346f6a9a7f262fd28ba41", "firstIndex": 9865002893}, +{"blockNumber": 16720124, "blockId": "0x2128f8baf264166e37554d5c31a06de58d9ccfb663117358251da548a23a060f", "firstIndex": 9932111275}, +{"blockNumber": 16769162, "blockId": "0x6b3e849482d3222032740ad6b8f98e24636c82682a6a3572b1ef76dfebc66821", "firstIndex": 9999217824}, +{"blockNumber": 16818311, "blockId": "0xe45f57381978a2bfc85bd20af1c41e2b630412642ac4f606b477f05f030ef5d9", "firstIndex": 10066328668}, +{"blockNumber": 16869531, "blockId": "0xa154555266d24dc1f4885af5fafcf8cab3de788998cf69e1d28f56aa13a40c43", "firstIndex": 10133437302}, +{"blockNumber": 16921611, "blockId": "0xf1f829b4ab5eec6e243916dd530993fa11eef5510fd730e8d09ead6b380355a1", "firstIndex": 10200547185}, +{"blockNumber": 16974870, "blockId": "0x1a33202b95926ae4cb8e6e99d8d150f3c50d817b3a316452bdf428c971dabde5", "firstIndex": 10267655914}, +{"blockNumber": 17031277, "blockId": "0x706c9dd0dc81e7ac29d2ea0f826e6b8a1dcb5adb1b904ff6e43260729c9fd0a7", "firstIndex": 10334764934}, +{"blockNumber": 17086330, "blockId": "0x085a80cafe96b520105b9a1f8e7a2bbc9474da24da7e6344ca7c4d32db822f92", "firstIndex": 10401871892}, +{"blockNumber": 17141311, "blockId": "0x33ec6513dfa515bc5f6356476b4eb075a8064181d6aaf6aa1a1e18887e342f74", "firstIndex": 10468982364}, +{"blockNumber": 17190907, "blockId": "0x6f41273d3bf30d3347e7eb68872a49b3ac947f314543478be7a28a55e5c41a3c", "firstIndex": 10536090817}, +{"blockNumber": 17237199, "blockId": "0x9a87a14a128c0345a366940f821a14f16719de628658ac0628e410a72d723e90", "firstIndex": 10603200178}, +{"blockNumber": 17287181, "blockId": "0x9c6e78adcf562ac63c103e3e5a02f025023079aca79bdd6ef18f7bd2a6271c29", "firstIndex": 10670309183}, +{"blockNumber": 17338652, "blockId": "0x1b747da97b2397a293602af57514dab4ca1010bb6c601ff05cb2012dd1124ebb", "firstIndex": 10737418023}, +{"blockNumber": 17389337, "blockId": "0xbc3c0ca1e5989605b9b59c94b418562eb17ccbce30e45ac8531cf0b3867a6b2c", "firstIndex": 10804522857}, +{"blockNumber": 17442261, "blockId": "0x1ec341be1cbd09f559bfa3d3e39a341d8e21052eeb7880931d43d086651733b7", "firstIndex": 10871635535}, +{"blockNumber": 17497787, "blockId": "0x6069880d486f2548599df1e14e12752d3eb9bc99843a98cd6631c22be1b58554", "firstIndex": 10938744657}, +{"blockNumber": 17554322, "blockId": "0x69b2564bc00b1f310f6b416912869d7530d7864bf7d70d55c7ace554f129b989", "firstIndex": 11005852829}, +{"blockNumber": 17608492, "blockId": "0x7d590653d5fa52c0d3ee453a77d2088504f57adcef35cd57c567afb554608457", "firstIndex": 11072961972}, +{"blockNumber": 17664272, "blockId": "0xdc16159d3500cdc7410873102f41fc55de2a8a41e3779c4b70e6224a541e2b9e", "firstIndex": 11140070967}, +{"blockNumber": 17715101, "blockId": "0x655e33c4e81182464ea0b0e1fdbc53ce53902431db5107326b816091a4564652", "firstIndex": 11207179487}, +{"blockNumber": 17764042, "blockId": "0x54439184f31cd83ba06b48b6dbfdd744ae7246355be1327b44744058711d05c0", "firstIndex": 11274287303}, +{"blockNumber": 17814383, "blockId": "0xfb453bc951360c76fb09bb1b9a3e39d23ececa0adb93368cc3f41f0457845089", "firstIndex": 11341397984}, +{"blockNumber": 17864648, "blockId": "0x32a68823ef4ec0cbab2fe50c97e3f462b575e8b117da40d00c710b4c66ee1d6d", "firstIndex": 11408505657}, +{"blockNumber": 17913366, "blockId": "0x04b944aab8a4ff91b77c2191817cf051766100c227616a3746af53407e740124", "firstIndex": 11475614351}, +{"blockNumber": 17961690, "blockId": "0x08bee7cc0b764106ca01dd5370b617879487ffb423688c96e948dce125990f45", "firstIndex": 11542723488}, +{"blockNumber": 18011048, "blockId": "0x94c39d3a64f3e9a91b1d98554cd29e1390e30fa61cfa4e909c503eee2fd9f165", "firstIndex": 11609833142}, +{"blockNumber": 18061209, "blockId": "0x2ee9ade68955c030488c8a30537bdf948355f7dd5ae64942b5bfce1be6650e19", "firstIndex": 11676941316}, +{"blockNumber": 18111692, "blockId": "0xd6c4fd0c1cc20ed5e7960bb5043e9e5e9c66a4d2ec5709ac9797fff678435640", "firstIndex": 11744050346}, +{"blockNumber": 18166212, "blockId": "0x3262588c2ef79a3b3f6a3db6435202d22f5667cd48c136b0797404901525c9ff", "firstIndex": 11811159686}, +{"blockNumber": 18218743, "blockId": "0x935bd9a4164ff7ecd09a37b916ce5bf78487bd19377b5b17be153e39318aee74", "firstIndex": 11878268593}, +{"blockNumber": 18271236, "blockId": "0xe58ebb821f27e3665898f390802a3d129d217b3a3ee36d890a85cf22a0a8aa33", "firstIndex": 11945376750}, +{"blockNumber": 18323007, "blockId": "0x3997a841468efa1bc614bfc3de4502274901b04b428f87a1f3086dfd78cda1eb", "firstIndex": 12012485748}, +{"blockNumber": 18372443, "blockId": "0xc44a13a5d02e8dc39f355de5e21ce7bb311ce7f4d9114ff480dce235a169e416", "firstIndex": 12079595370}, +{"blockNumber": 18421829, "blockId": "0x7da63a0b613d8745597b2ac64fd5cc8b2fb14b24d163b12a0a39d7d3d4ff7b5c", "firstIndex": 12146703582}, +{"blockNumber": 18471706, "blockId": "0xd632a1893f415ff618f4b612a7687e6af1f12feeed81f46f0022090829c1eb4c", "firstIndex": 12213812677}, +{"blockNumber": 18522301, "blockId": "0x44fa2cf08145ae40e8e42f4e6b4ab7df360a17c5a065ce45fcc41b51bee011f4", "firstIndex": 12280921639}, +{"blockNumber": 18572935, "blockId": "0x72b8ab4c78c90425ee054b4806a8be703da0febdf1d51866358ec2bd21ba9529", "firstIndex": 12348029751}, +{"blockNumber": 18623431, "blockId": "0x8c4cb2f13501d9788820280c6f16692d0737258c3896f1e4bded32d838febf7f", "firstIndex": 12415138965}, +{"blockNumber": 18675470, "blockId": "0x523b73c19ea8b3ae32ef141a83ef9855e667ebf51443cfcabd1a06659359062a", "firstIndex": 12482247454}, +{"blockNumber": 18725728, "blockId": "0x0cfbd131eb5dad51488238079fba29a63eebb5c32d1a543cb072e48dc2104ef3", "firstIndex": 12549356369}, +{"blockNumber": 18778387, "blockId": "0xc4906c77af8058b9f172a4f0e8788c7887f05caa5ac752b38b5387080f74ae49", "firstIndex": 12616465992}, +{"blockNumber": 18835044, "blockId": "0x49c5e07f409a841dc81f3ef8417f1951f8fcc13c90134f9d2a0cd11938f9fa36", "firstIndex": 12683575082}, +{"blockNumber": 18883308, "blockId": "0x386a58dd5f79a419eeb05075b07b3ff3bc836a265c9688854a504223b1d6a830", "firstIndex": 12750683753}, +{"blockNumber": 18933635, "blockId": "0xd3881292147589bd2e192769e5c9175b5d03a453fe1ef3c4b5b6858ac9402a2f", "firstIndex": 12817792470}, +{"blockNumber": 18988254, "blockId": "0xcbe72dfa15428ac21b9c59c703ceaa0eb4b2205927687261d7aaed3dbb3783ea", "firstIndex": 12884882858}, +{"blockNumber": 19041325, "blockId": "0x92b077e1c2f8819da728f0307c914fdcd57eba14ea07d9a45c28d1ed8ffff576", "firstIndex": 12952010530}, +{"blockNumber": 19089163, "blockId": "0x43f8ab2d3dfc34c8e18cba903074d54e235dc546f19c4eb78245a522c266c84e", "firstIndex": 13019119228}, +{"blockNumber": 19140629, "blockId": "0xab7b7ae5424b18105a13b657fa6099d4ab67fde5baff39fe6e4de707397e995c", "firstIndex": 13086228236}, +{"blockNumber": 19192118, "blockId": "0x451327e6a5cf6ce1c8c14c01687dc5f719f3c2176f46bac4f264616256e30d1c", "firstIndex": 13153337116}, +{"blockNumber": 19237836, "blockId": "0x9b260d6be369557d1dc88aca423e2697e697d941d1b726c183015b5649e248c8", "firstIndex": 13220445421}, +{"blockNumber": 19291271, "blockId": "0x4878c28d79e1f71bc11e062eb61cb52ae6a18b670b0f9bea38b477944615078e", "firstIndex": 13287554254}, +{"blockNumber": 19344448, "blockId": "0x56243b9ad863bf90953fe9aa6e64a426629384db1190e70dce79575d30595f7e", "firstIndex": 13354663659}, +{"blockNumber": 19394948, "blockId": "0x195173b64dda7908d6aa39a63c8bdd29ec181d401e369d513be1308550d0ddcb", "firstIndex": 13421771935}, +{"blockNumber": 19443075, "blockId": "0xd39c1d60996475e65d1ab5b4e755f510ca466564a8155d35db6667988d6c0e44", "firstIndex": 13488880427}, +{"blockNumber": 19488383, "blockId": "0x28956eb8856fa8db59c02585016b8baf43bc44bc35b00bdaf8a6babe51101c5c", "firstIndex": 13555977105}, +{"blockNumber": 19534584, "blockId": "0x2421c97b0f140185d4c20943cd4ed7d7424468482feb76e3003a1cc69da3fd7b", "firstIndex": 13623097580}, +{"blockNumber": 19579602, "blockId": "0x25f96529028e9f51c59aec9ce8de282b7dd67066fd46a1694130698ed0f40d8b", "firstIndex": 13690207623}, +{"blockNumber": 19621517, "blockId": "0x4f6f6e0a0488f3d51823bc4b07c292348c259b1866968f77ee76b66b37101c75", "firstIndex": 13757315529}, +{"blockNumber": 19665085, "blockId": "0x00f9315f89681b44bff46f1bad8894bc6dfae1c459d3d6520f9881861304a496", "firstIndex": 13824425382}, +{"blockNumber": 19709229, "blockId": "0x24e022b21ae1ba8a3e8c87cb9734aa1d1810fc4a69fe147d3ebb1ff0df8bcc15", "firstIndex": 13891534799}, +{"blockNumber": 19755387, "blockId": "0x77f184b7183b1a351760d242041249464b42cfaa6fbc4326f352b06bb3b21a02", "firstIndex": 13958642483}, +{"blockNumber": 19803894, "blockId": "0xf37eb1b054a6d61272940361f386eb744cded84d15c3250a7eabadede257371c", "firstIndex": 14025751618}, +{"blockNumber": 19847885, "blockId": "0x4659649fa8a3b4bbe8978673ba9a22ae20352c7052b676d373b5a51b1967ffa4", "firstIndex": 14092848654}, +{"blockNumber": 19894193, "blockId": "0x15606bdc0f1a710bd69443c7154d4979aece9329977b65990c9b39d6df84ed5c", "firstIndex": 14159970181}, +{"blockNumber": 19938551, "blockId": "0x6a8f4571924ed902bd8e71bf8ed9cc9d72cabeabc410277c8f0fc2b477d00eb7", "firstIndex": 14227077892}, +{"blockNumber": 19985354, "blockId": "0x7b6fb6376410b4d9e5d7ee02f78b2054e005dd2976eea47fc714f66b967dc285", "firstIndex": 14294187965}, +{"blockNumber": 20028440, "blockId": "0x9b37440b71c24756b8855b8012432b84276ae94c80aa1ccc8b70a7705992103c", "firstIndex": 14361296503}, +{"blockNumber": 20071780, "blockId": "0xa2ed129f343f3d60419772ec5635edcd36b8680c9419b6626e2bc84b230c709b", "firstIndex": 14428405230}, +{"blockNumber": 20113832, "blockId": "0xe7a610e8bcbf8ded141ebc7142de03dfc54b1bcc79e3bf8d07fad4e42b665bba", "firstIndex": 14495512019}, +{"blockNumber": 20156854, "blockId": "0xbe09704f65a70ef8843d9c8e511ddc989ea139dbe94cdfe37f52b03620d62385", "firstIndex": 14562622430}, +{"blockNumber": 20200135, "blockId": "0x9a58c34d5f77342e94065d119905c000223cd988c4b11f1539fff20737159630", "firstIndex": 14629731923}, +{"blockNumber": 20244389, "blockId": "0x1e733f0db9ef21183107259b3c2408c78fa5a01469928cd295f3ea7e8eedda45", "firstIndex": 14696840011}, +{"blockNumber": 20288489, "blockId": "0xb5ad7edd86b181226c8c7be0a08069e3955234e797426843fff9de0f57ec59cc", "firstIndex": 14763949714}, +{"blockNumber": 20333582, "blockId": "0x8040c209f5cd1738ee0f85c2f1db7c43a420d148680c7390fd1701b9f0bb671a", "firstIndex": 14831058335}, +{"blockNumber": 20377087, "blockId": "0x08fdc4cd246b6ae9d4a45646b0aed6af3bb330eb6cd4c8b93646157e7b002b84", "firstIndex": 14898167722}, +{"blockNumber": 20421699, "blockId": "0x5a2912b5fc2f02df33b655155990f92dcaacda5b75427fe3d87fb38f36b1c17d", "firstIndex": 14965275691}, +{"blockNumber": 20467194, "blockId": "0x3deaf4325c461004b090b0261996c645ab529c1471feaf7dc2bbe1f128180297", "firstIndex": 15032385211}, +{"blockNumber": 20512397, "blockId": "0x37e39697ec1b7683a6202be250ffaee7a1102e8030f87550b94af05ec66cec83", "firstIndex": 15099493973}, +{"blockNumber": 20557443, "blockId": "0x8e9c04468f3111eab8b1f6a58b277862c624861c237cadecc53ec249bd811bda", "firstIndex": 15166602882}, +{"blockNumber": 20595899, "blockId": "0x9787555fe57e4650002257eb2c88f1ef435b99d406e33fe2f889be180123ef25", "firstIndex": 15233709908}, +{"blockNumber": 20638606, "blockId": "0x70681cffd159ce2e580dbbbe8fa6b5343dbcb081429cdda6c577e615bef4ef05", "firstIndex": 15300820678}, +{"blockNumber": 20683605, "blockId": "0xb32662d5e241132ffe2249caea67f5746a6f4382297b2ac87c81e2794faf1f7a", "firstIndex": 15367929350}, +{"blockNumber": 20728630, "blockId": "0x15a817c846928b673032d5eacd0cff7a04217d268457aa30a322ecca32be4d49", "firstIndex": 15435037830}, +{"blockNumber": 20771519, "blockId": "0x542bc7b9804bbc45f4be470f4dc56f215a4dec71fed71eba2ffc804afd262b95", "firstIndex": 15502145990}, +{"blockNumber": 20815097, "blockId": "0x798cdd51c964fcf18561d70095d9613b84ba836817972799c9dfd0bfbe1e042b", "firstIndex": 15569256033}, +{"blockNumber": 20857859, "blockId": "0xfb5bb066d419a651d8e0186569eb4e8d8bcd5181d8f02e0d578b5dfe2fc738dd", "firstIndex": 15636364671}, +{"blockNumber": 20896890, "blockId": "0x834b8d6fad779e4cf8214128f6c93d7387b6d6279e517f6f0a284b5d831cc3ae", "firstIndex": 15703472902}, +{"blockNumber": 20939387, "blockId": "0x7adee7c78420c711efa216c61e0b561e581d7ff0331efd91ee16a609b34cfdc2", "firstIndex": 15770582325}, +{"blockNumber": 20981303, "blockId": "0x6f5d7b0cc6dad5eb258176e07de21795a8347d68f7303f06934046e0236bea6d", "firstIndex": 15837691713}, +{"blockNumber": 21023216, "blockId": "0x96cfe35a45df1297a36f42c59ebe706ab0473dfbf59ce910b5c5a8dbf696de1c", "firstIndex": 15904799667}, +{"blockNumber": 21068378, "blockId": "0x93753875ff330d922b23f823203198f3b1bb8833367c6b6a8f896ff54be2c12d", "firstIndex": 15971909040}, +{"blockNumber": 21112445, "blockId": "0x6ac02fa6ae486b86aba562eaf6f3d883befaa8ebedcfd8d74bdb7368d42deee3", "firstIndex": 16039003625}, +{"blockNumber": 21155992, "blockId": "0x25f76896b4b693bafb79e9a535e2bf00ed62a577e35209749346e8e79a60bb71", "firstIndex": 16106126344}, +{"blockNumber": 21200962, "blockId": "0x725f2befe913cb2659d262e2d3b6f79a706b31c557d52669471da22347ec8287", "firstIndex": 16173235265}, +{"blockNumber": 21244663, "blockId": "0x6778c4194f54e70939da38853daddb22bfaf160d35617ab05d0f5c476741147b", "firstIndex": 16240344735}, +{"blockNumber": 21290273, "blockId": "0x433ac819c40bd3061205fe0ece0645eec73f54a0a5c1559c981f983345bc0154", "firstIndex": 16307453543}, +{"blockNumber": 21336156, "blockId": "0x261dc8c1639d505624150d2388d15ed10bfb4c3ce9c0c327a4ec26531689a097", "firstIndex": 16374562466}, +{"blockNumber": 21378880, "blockId": "0x5c78b2b70553140dfdfdd4f415b98f88e74f74662315834038fd99042277d917", "firstIndex": 16441671104}, +{"blockNumber": 21421613, "blockId": "0x854532f9d1c77627b763f9cbc7099a653d59554ed57fa763bc218834c82955fe", "firstIndex": 16508780351}, +{"blockNumber": 21466875, "blockId": "0xb8b83cc62084e948235ef4b5973bf7fd988fa28bcaa72f7d38ad8e50de729618", "firstIndex": 16575888599}, +{"blockNumber": 21511942, "blockId": "0xe806a28bc1b7f8cd752c8ceedbe081d49773d4558a9fb95e3357c0c07172522d", "firstIndex": 16642996907}, +{"blockNumber": 21550291, "blockId": "0x1f3e26d303e7a2a9b0614f12f62b189da365b3947c5fe2d99ed2711b37fe7daa", "firstIndex": 16710106826}, +{"blockNumber": 21592690, "blockId": "0xa1408cfbc693faee4425e8fd9e83a181be535c33f874b56c3a7a114404c4f686", "firstIndex": 16777215566}, +{"blockNumber": 21636275, "blockId": "0x704734c2d0351f8ccd38721a9a4b80c063368afaaa857518d98498180a502bba", "firstIndex": 16844323959}, +{"blockNumber": 21681066, "blockId": "0x1e738568ed393395c498b109ad61c0286747318aae0364936f19a7b6aba94aef", "firstIndex": 16911433076}, +{"blockNumber": 21725592, "blockId": "0xee87b7948e25a7498a247c616a0fbaa27f21b004e11fc56f2a20c03791ed8122", "firstIndex": 16978540993} +] + diff --git a/core/filtermaps/checkpoints_sepolia.json b/core/filtermaps/checkpoints_sepolia.json new file mode 100644 index 0000000000..3e3ea23b24 --- /dev/null +++ b/core/filtermaps/checkpoints_sepolia.json @@ -0,0 +1,63 @@ +[ +{"blockNumber": 3246675, "blockId": "0x36bf7de9e1f151963088ca3efa206b6e78411d699d2f64f3bf86895294275e0b", "firstIndex": 67107286}, +{"blockNumber": 3575582, "blockId": "0x08931012467636d3b67ae187790951daed2bb6423f9cd94e166df787b856788d", "firstIndex": 134217672}, +{"blockNumber": 3694264, "blockId": "0x1f35f276a3c78e5942ee285fcbd0c687691853c599a2f5b174ea88f653bc9514", "firstIndex": 201326578}, +{"blockNumber": 3725632, "blockId": "0x3bcb264c56c3eeab6c8588145f09dff3fb5f821d9fc1e7b92264b14314dae553", "firstIndex": 268433636}, +{"blockNumber": 3795390, "blockId": "0x2d1ef2815bb8e018b275fa65540b98265285016aff12596bd89a3b1442d248eb", "firstIndex": 335542953}, +{"blockNumber": 3856683, "blockId": "0x8a9a46d6f53975cd9ec829c3c307a99fb62b8428cefb63ffe06d17143649c3ee", "firstIndex": 402648835}, +{"blockNumber": 3869370, "blockId": "0x2e8c04e7e5e96d09260b65d77b1770b4105b0db2ee7d638c48f086b8afac17db", "firstIndex": 469759276}, +{"blockNumber": 3938357, "blockId": "0xf20f2cdbcc412d5340e31955d14a6526ea748ba99b5ec70b6615bdb18bcd4cfb", "firstIndex": 536868027}, +{"blockNumber": 3984894, "blockId": "0x0bcd886b3cebb884d5beeaf5ad15ee1514968b5ad07177297c7d9c00f27aa406", "firstIndex": 603968430}, +{"blockNumber": 4002664, "blockId": "0x7d3575b6ca685468fa5a5fa9ff9d5fac4415b0a67a3ed87d3530f127db32fff4", "firstIndex": 671088417}, +{"blockNumber": 4113187, "blockId": "0x3a5313ac5b602134bb73535b22801261e891ccb7bd660ab20e0a536dc46d3e13", "firstIndex": 738197016}, +{"blockNumber": 4260758, "blockId": "0xe30fb9a304d3602896a5716d310f67ba34ccef7f809a3ead4b2d991cb9ee4eb0", "firstIndex": 805306270}, +{"blockNumber": 4391131, "blockId": "0x3958478c1c3be9b7caedbcc96230ed446d711e56580e324bc2fcf903fc87c90f", "firstIndex": 872415115}, +{"blockNumber": 4515650, "blockId": "0x46a3a7b97a9dff4ef4dc2c1cc5cd501f2182d9548655b77b5e07a2dbb41071a4", "firstIndex": 939523930}, +{"blockNumber": 4634818, "blockId": "0x2197d0dd3925c1d7ba3e2c4eef20035b68efc0a2506f76ddd9e481e0ce8ca6e1", "firstIndex": 1006628557}, +{"blockNumber": 4718295, "blockId": "0xcce7bb4af1a41e6056ef68192e60c738be01ac3e071ed1ec52cead08a39995ce", "firstIndex": 1073734698}, +{"blockNumber": 4753438, "blockId": "0xa60e043728a369cdf39a399bd7a903085ee9386f38176947578e5692b4b01f65", "firstIndex": 1140843192}, +{"blockNumber": 4786522, "blockId": "0x10629cadc00e65f193fa4d10ecd2bf1855e442814c4a409d19aae9eb895dce13", "firstIndex": 1207956586}, +{"blockNumber": 4811706, "blockId": "0xf1e94111f0086733bdcb4a653486a8b94ec998b61dda0af0fd465c9b4e344f87", "firstIndex": 1275058221}, +{"blockNumber": 4841796, "blockId": "0xa530f7dd72881ac831affdc579c9d75f6d4b6853b1f1894d320bd9047df5f9eb", "firstIndex": 1342177155}, +{"blockNumber": 4914835, "blockId": "0xbd8321e354f72c4190225f8ed63d4aba794b3b568677d985e099cb62d9d36bae", "firstIndex": 1409286143}, +{"blockNumber": 4992519, "blockId": "0x4a06a5a4aa5bc52151937cc1c0f8da691a0282e94aab8b73b9faa87da8d028de", "firstIndex": 1476384367}, +{"blockNumber": 5088668, "blockId": "0xb7d5ee03c08ed3936348eeb3931be8f804e61f2b09debf305967c6a7bbf007e0", "firstIndex": 1543502599}, +{"blockNumber": 5155029, "blockId": "0x84f590dfc2e11f1ca53c1757ac3c508d56f55ee24d6ca5501895974be4250d76", "firstIndex": 1610605837}, +{"blockNumber": 5204413, "blockId": "0xeaf2c3fb6f927c16d38fab08b34303867b87470558612404c7f9e3256b80c5b9", "firstIndex": 1677720841}, +{"blockNumber": 5269957, "blockId": "0x596e0b2e8e4c18c803b61767320fe32c063153d870c94e4a08e9a68cbaa582a9", "firstIndex": 1744825147}, +{"blockNumber": 5337678, "blockId": "0x7b2d54f8af1ecaaaab994e137d4421d8236c1c10d9a7bdcb9e5500db7a3fe9a3", "firstIndex": 1811939316}, +{"blockNumber": 5399058, "blockId": "0xb61ef16d55c96682fb62b0110a2dbc50d8eff2526be4121ece3690700611c71b", "firstIndex": 1879046044}, +{"blockNumber": 5422707, "blockId": "0xdabcab7c0cc9cb9f22f7507a1076c87831cb1afed9d0aa5bcd93f22266720c91", "firstIndex": 1946156915}, +{"blockNumber": 5454264, "blockId": "0xe1bde812906605ce662f5fd9f01b49c7331fb25f52ab5b12d35ea2b4da5458fe", "firstIndex": 2013259168}, +{"blockNumber": 5498898, "blockId": "0x9533d9c5353d22f8a235e95831cfbf4d5a7220a430ca23494526a9d3aa866fe8", "firstIndex": 2080374321}, +{"blockNumber": 5554801, "blockId": "0xe7b320bbecb19f1e99dd6ce4aed1efc754d7b2022e1f80389e8a21413c465f55", "firstIndex": 2147476253}, +{"blockNumber": 5594725, "blockId": "0xce6750be4a5b3e0fe152dd02308e94f7d56b254852a7e9acef6e14105053d7d1", "firstIndex": 2214591591}, +{"blockNumber": 5645198, "blockId": "0x5d42d39999c546f37001d5f613732fb54032384dd71a686d3664d2c8a1337752", "firstIndex": 2281696503}, +{"blockNumber": 5687659, "blockId": "0x3ed941be39a33ffa69cf3531a67f5a25f712ba05db890ff377f60d26842e4b1c", "firstIndex": 2348801751}, +{"blockNumber": 5727823, "blockId": "0xaf699b6c4cd58181bd609a66990b8edb5d1b94d5ff1ab732ded35ce7b8373353", "firstIndex": 2415917178}, +{"blockNumber": 5784505, "blockId": "0x621c740d04ea41f70a2f0537e21e5b96169aea8a8efee0ae5527717e5c40aa64", "firstIndex": 2483024581}, +{"blockNumber": 5843958, "blockId": "0xec122204a4e4698748f55a1c9f8582c46bacda029aee4de1a234e67e3288e6b1", "firstIndex": 2550136761}, +{"blockNumber": 5906359, "blockId": "0x8af5ce73fbd7a6110fb8b19b75a7322456ece88fcfa1614c745f1a65f4e915c1", "firstIndex": 2617245617}, +{"blockNumber": 5977944, "blockId": "0xbc8186258298a4f376124989cfb7b22c2bea6603a5245bb6c505c5fc45844bbd", "firstIndex": 2684350982}, +{"blockNumber": 6051571, "blockId": "0x54f9df9d9d73d1aa1cfcd6f372377c6013ecba2a1ed158d3c304f4fca51dae58", "firstIndex": 2751463209}, +{"blockNumber": 6118461, "blockId": "0xfea757fad3f763c62a514a9c24924934539ca56620bd811f83e9cc2e671f0cf0", "firstIndex": 2818572283}, +{"blockNumber": 6174385, "blockId": "0x2d8d0226e58f7516c13f9e1c9cf3ea65bb520fa1dfd7249dc9ea34a4e1fd430d", "firstIndex": 2885681036}, +{"blockNumber": 6276318, "blockId": "0xa922e9d54fd062b658c4866ed218632ddd51f250d671628a42968bb912d3ed5d", "firstIndex": 2952789983}, +{"blockNumber": 6368452, "blockId": "0x8d3d7466a7c9ca7298f82c37c38b0f64ec04522d2ed2e2349f8edc020c57f2c4", "firstIndex": 3019898695}, +{"blockNumber": 6470810, "blockId": "0x9887c35542835ee81153fa0e4d8a9e6f170b6e14fc78d8c7f3d900d0a70434f1", "firstIndex": 3087007578}, +{"blockNumber": 6553334, "blockId": "0x7b0d89a0282c18785fcc108dbdc9d45dd9d63b7084ddc676df9e9504585a5969", "firstIndex": 3154115987}, +{"blockNumber": 6663825, "blockId": "0xff6cec99324a89d6d36275c17a4569f0cba203fe5b0350f155a7d5445e0ed419", "firstIndex": 3221224775}, +{"blockNumber": 6767082, "blockId": "0xe10a96a7194f98bf262f0cb1cdfb4d3b9a2072139dfcbe3f1eb01419e353044e", "firstIndex": 3288334139}, +{"blockNumber": 6886709, "blockId": "0x20f6a5d986913025ad5b6b6387d818e49a3caf838326f4002c1439ca61313be5", "firstIndex": 3355442979}, +{"blockNumber": 6978948, "blockId": "0xd7c3024765245ec49e6a48b076d540bc91f57f2ccc125e17d60dd37bb669f843", "firstIndex": 3422551908}, +{"blockNumber": 7098891, "blockId": "0x05114c037e1b4d69a46d74a974be9bce45e87ad2226a59b44dd17f98dd2fd0d1", "firstIndex": 3489659530}, +{"blockNumber": 7203157, "blockId": "0xc0f610014fcd9f2850274b58179d474f0947676fd0639b2884316467c631811d", "firstIndex": 3556769512}, +{"blockNumber": 7256735, "blockId": "0x0324c15b3b23fd82c2962dd167618e77e60ebeac5a2c87f672caddc9732337b3", "firstIndex": 3623876508}, +{"blockNumber": 7307851, "blockId": "0x8e23280d1a3aec877d7758413ed20299d381aa43e7e2fc6f381ad96e8ff0acef", "firstIndex": 3690987098}, +{"blockNumber": 7369389, "blockId": "0xbf6436eb2b88539945d6673141a14cb79ffc1e7db2b57176acf8e02ff3b6fcd3", "firstIndex": 3758096287}, +{"blockNumber": 7445220, "blockId": "0x147619f74815283d834ac08ff494fb4791207b3949c64b2623f11ff6141ee7a7", "firstIndex": 3825204992}, +{"blockNumber": 7511632, "blockId": "0x5094d64868f419e6ac3d253d19d5feda76564a0d56d7bbf8a822dff1c2261b30", "firstIndex": 3892314047}, +{"blockNumber": 7557280, "blockId": "0x54aba9351a1ba51873645221aa7c991024da1fe468a600ddb6e2559351d9c28f", "firstIndex": 3959422859}, +{"blockNumber": 7606304, "blockId": "0xbbe2fed08cf0b0ff2cb6ae9fd7257843f77a04a7d4cafb06d7a4bedea6ab0c98", "firstIndex": 4026531690} +] + diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go new file mode 100644 index 0000000000..95dd181551 --- /dev/null +++ b/core/filtermaps/filtermaps.go @@ -0,0 +1,726 @@ +// 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 filtermaps + +import ( + "bytes" + "errors" + "fmt" + "os" + "slices" + "sync" + "time" + + "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/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/ethdb/leveldb" + "github.com/ethereum/go-ethereum/log" +) + +const ( + cachedLastBlocks = 1000 // last block of map pointers + cachedLvPointers = 1000 // first log value pointer of block pointers + cachedBaseRows = 100 // groups of base layer filter row data + cachedFilterMaps = 3 // complete filter maps (cached by map renderer) + cachedRenderSnapshots = 8 // saved map renderer data at block boundaries +) + +// FilterMaps is the in-memory representation of the log index structure that is +// responsible for building and updating the index according to the canonical +// chain. +// +// Note that FilterMaps implements the same data structure as proposed in EIP-7745 +// without the tree hashing and consensus changes: +// https://eips.ethereum.org/EIPS/eip-7745 +type FilterMaps struct { + // If disabled is set, log indexing is fully disabled. + // This is configured by the --history.logs.disable Geth flag. + // We chose to implement disabling this way because it requires less special + // case logic in eth/filters. + disabled bool + + closeCh chan struct{} + closeWg sync.WaitGroup + history uint64 + exportFileName string + Params + + db ethdb.KeyValueStore + + // fields written by the indexer and read by matcher backend. Indexer can + // read them without a lock and write them under indexLock write lock. + // Matcher backend can read them under indexLock read lock. + indexLock sync.RWMutex + indexedRange filterMapsRange + indexedView *ChainView // always consistent with the log index + + // also accessed by indexer and matcher backend but no locking needed. + filterMapCache *lru.Cache[uint32, filterMap] + lastBlockCache *lru.Cache[uint32, lastBlockOfMap] + lvPointerCache *lru.Cache[uint64, uint64] + baseRowsCache *lru.Cache[uint64, [][]uint32] + + // the matchers set and the fields of FilterMapsMatcherBackend instances are + // read and written both by exported functions and the indexer. + // Note that if both indexLock and matchersLock needs to be locked then + // indexLock should be locked first. + matchersLock sync.Mutex + matchers map[*FilterMapsMatcherBackend]struct{} + + // fields only accessed by the indexer (no mutex required). + renderSnapshots *lru.Cache[uint64, *renderedMap] + startedHeadIndex, startedTailIndex, startedTailUnindex bool + startedHeadIndexAt, startedTailIndexAt, startedTailUnindexAt time.Time + loggedHeadIndex, loggedTailIndex bool + lastLogHeadIndex, lastLogTailIndex time.Time + ptrHeadIndex, ptrTailIndex, ptrTailUnindexBlock uint64 + ptrTailUnindexMap uint32 + + targetView *ChainView + matcherSyncRequest *FilterMapsMatcherBackend + finalBlock, lastFinal uint64 + lastFinalEpoch uint32 + stop bool + targetViewCh chan *ChainView + finalBlockCh chan uint64 + blockProcessingCh chan bool + blockProcessing bool + matcherSyncCh chan *FilterMapsMatcherBackend + waitIdleCh chan chan bool + tailRenderer *mapRenderer + + // test hooks + testDisableSnapshots, testSnapshotUsed bool +} + +// filterMap is a full or partial in-memory representation of a filter map where +// rows are allowed to have a nil value meaning the row is not stored in the +// structure. Note that therefore a known empty row should be represented with +// a zero-length slice. +// It can be used as a memory cache or an overlay while preparing a batch of +// changes to the structure. In either case a nil value should be interpreted +// as transparent (uncached/unchanged). +type filterMap []FilterRow + +// copy returns a copy of the given filter map. Note that the row slices are +// copied but their contents are not. This permits extending the rows further +// (which happens during map rendering) without affecting the validity of +// copies made for snapshots during rendering. +func (fm filterMap) copy() filterMap { + c := make(filterMap, len(fm)) + copy(c, fm) + return c +} + +// FilterRow encodes a single row of a filter map as a list of column indices. +// Note that the values are always stored in the same order as they were added +// and if the same column index is added twice, it is also stored twice. +// Order of column indices and potential duplications do not matter when searching +// for a value but leaving the original order makes reverting to a previous state +// simpler. +type FilterRow []uint32 + +// Equal returns true if the given filter rows are equivalent. +func (a FilterRow) Equal(b FilterRow) bool { + return slices.Equal(a, b) +} + +// filterMapsRange describes the rendered range of filter maps and the range +// of fully rendered blocks. +type filterMapsRange struct { + initialized bool + headBlockIndexed bool + headBlockDelimiter uint64 // zero if afterLastIndexedBlock != targetBlockNumber + // if initialized then all maps are rendered between firstRenderedMap and + // afterLastRenderedMap-1 + firstRenderedMap, afterLastRenderedMap uint32 + // if tailPartialEpoch > 0 then maps between firstRenderedMap-mapsPerEpoch and + // firstRenderedMap-mapsPerEpoch+tailPartialEpoch-1 are rendered + tailPartialEpoch uint32 + // if initialized then all log values belonging to blocks between + // firstIndexedBlock and afterLastIndexedBlock are fully rendered + // blockLvPointers are available between firstIndexedBlock and afterLastIndexedBlock-1 + firstIndexedBlock, afterLastIndexedBlock uint64 +} + +// hasIndexedBlocks returns true if the range has at least one fully indexed block. +func (fmr *filterMapsRange) hasIndexedBlocks() bool { + return fmr.initialized && fmr.afterLastIndexedBlock > fmr.firstIndexedBlock +} + +// lastBlockOfMap is used for caching the (number, id) pairs belonging to the +// last block of each map. +type lastBlockOfMap struct { + number uint64 + id common.Hash +} + +// Config contains the configuration options for NewFilterMaps. +type Config struct { + History uint64 // number of historical blocks to index + Disabled bool // disables indexing completely + + // This option enables the checkpoint JSON file generator. + // If set, the given file will be updated with checkpoint information. + ExportFileName string +} + +// NewFilterMaps creates a new FilterMaps and starts the indexer. +func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, params Params, config Config) *FilterMaps { + rs, initialized, err := rawdb.ReadFilterMapsRange(db) + if err != nil { + log.Error("Error reading log index range", "error", err) + } + params.deriveFields() + f := &FilterMaps{ + db: db, + closeCh: make(chan struct{}), + waitIdleCh: make(chan chan bool), + targetViewCh: make(chan *ChainView, 1), + finalBlockCh: make(chan uint64, 1), + blockProcessingCh: make(chan bool, 1), + history: config.History, + disabled: config.Disabled, + exportFileName: config.ExportFileName, + Params: params, + indexedRange: filterMapsRange{ + initialized: initialized, + headBlockIndexed: rs.HeadBlockIndexed, + headBlockDelimiter: rs.HeadBlockDelimiter, + firstIndexedBlock: rs.FirstIndexedBlock, + afterLastIndexedBlock: rs.AfterLastIndexedBlock, + firstRenderedMap: rs.FirstRenderedMap, + afterLastRenderedMap: rs.AfterLastRenderedMap, + tailPartialEpoch: rs.TailPartialEpoch, + }, + matcherSyncCh: make(chan *FilterMapsMatcherBackend), + matchers: make(map[*FilterMapsMatcherBackend]struct{}), + filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps), + lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks), + lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers), + baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows), + renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots), + } + + // Set initial indexer target. + f.targetView = initView + if f.indexedRange.initialized { + f.indexedView = f.initChainView(f.targetView) + f.indexedRange.headBlockIndexed = f.indexedRange.afterLastIndexedBlock == f.indexedView.headNumber+1 + if !f.indexedRange.headBlockIndexed { + f.indexedRange.headBlockDelimiter = 0 + } + } + if f.indexedRange.hasIndexedBlocks() { + log.Info("Initialized log indexer", + "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, + "first map", f.indexedRange.firstRenderedMap, "last map", f.indexedRange.afterLastRenderedMap-1, + "head indexed", f.indexedRange.headBlockIndexed) + } + return f +} + +// Start starts the indexer. +func (f *FilterMaps) Start() { + if !f.testDisableSnapshots && f.indexedRange.initialized && f.indexedRange.headBlockIndexed && + f.indexedRange.firstRenderedMap < f.indexedRange.afterLastRenderedMap { + // previous target head rendered; load last map as snapshot + if err := f.loadHeadSnapshot(); err != nil { + log.Error("Could not load head filter map snapshot", "error", err) + } + } + f.closeWg.Add(1) + go f.indexerLoop() +} + +// Stop ensures that the indexer is fully stopped before returning. +func (f *FilterMaps) Stop() { + close(f.closeCh) + f.closeWg.Wait() +} + +// initChainView returns a chain view consistent with both the current target +// view and the current state of the log index as found in the database, based +// on the last block of stored maps. +// Note that the returned view might be shorter than the existing index if +// the latest maps are not consistent with targetView. +func (f *FilterMaps) initChainView(chainView *ChainView) *ChainView { + mapIndex := f.indexedRange.afterLastRenderedMap + for { + var ok bool + mapIndex, ok = f.lastMapBoundaryBefore(mapIndex) + if !ok { + break + } + lastBlockNumber, lastBlockId, err := f.getLastBlockOfMap(mapIndex) + if err != nil { + log.Error("Could not initialize indexed chain view", "error", err) + break + } + if lastBlockNumber <= chainView.headNumber && chainView.getBlockId(lastBlockNumber) == lastBlockId { + return chainView.limitedView(lastBlockNumber) + } + } + return chainView.limitedView(0) +} + +// reset un-initializes the FilterMaps structure and removes all related data from +// the database. The function returns true if everything was successfully removed. +func (f *FilterMaps) reset() bool { + f.indexLock.Lock() + f.indexedRange = filterMapsRange{} + f.indexedView = nil + f.filterMapCache.Purge() + f.renderSnapshots.Purge() + f.lastBlockCache.Purge() + f.lvPointerCache.Purge() + f.baseRowsCache.Purge() + f.indexLock.Unlock() + // deleting the range first ensures that resetDb will be called again at next + // startup and any leftover data will be removed even if it cannot finish now. + rawdb.DeleteFilterMapsRange(f.db) + return f.removeDbWithPrefix([]byte(rawdb.FilterMapsPrefix), "Resetting log index database") +} + +// init initializes an empty log index according to the current targetView. +func (f *FilterMaps) init() error { + f.indexLock.Lock() + defer f.indexLock.Unlock() + + var bestIdx, bestLen int + for idx, checkpointList := range checkpoints { + // binary search for the last matching epoch head + min, max := 0, len(checkpointList) + for min < max { + mid := (min + max + 1) / 2 + cp := checkpointList[mid-1] + if cp.BlockNumber <= f.targetView.headNumber && f.targetView.getBlockId(cp.BlockNumber) == cp.BlockId { + min = mid + } else { + max = mid - 1 + } + } + if max > bestLen { + bestIdx, bestLen = idx, max + } + } + batch := f.db.NewBatch() + for epoch := range bestLen { + cp := checkpoints[bestIdx][epoch] + f.storeLastBlockOfMap(batch, (uint32(epoch+1)< 0 { + cp := checkpoints[bestIdx][bestLen-1] + fmr.firstIndexedBlock = cp.BlockNumber + 1 + fmr.afterLastIndexedBlock = cp.BlockNumber + 1 + fmr.firstRenderedMap = uint32(bestLen) << f.logMapsPerEpoch + fmr.afterLastRenderedMap = uint32(bestLen) << f.logMapsPerEpoch + } + f.setRange(batch, f.targetView, fmr) + return batch.Write() +} + +// removeDbWithPrefix removes data with the given prefix from the database and +// returns true if everything was successfully removed. +func (f *FilterMaps) removeDbWithPrefix(prefix []byte, action string) bool { + it := f.db.NewIterator(prefix, nil) + hasData := it.Next() + it.Release() + if !hasData { + return true + } + + end := bytes.Clone(prefix) + end[len(end)-1]++ + start := time.Now() + var retry bool + for { + err := f.db.DeleteRange(prefix, end) + if err == nil { + log.Info(action+" finished", "elapsed", time.Since(start)) + return true + } + if err != leveldb.ErrTooManyKeys { + log.Error(action+" failed", "error", err) + return false + } + select { + case <-f.closeCh: + return false + default: + } + if !retry { + log.Info(action + " in progress...") + retry = true + } + } +} + +// setRange updates the indexed chain view and covered range and also adds the +// changes to the given batch. +// Note that this function assumes that the index write lock is being held. +func (f *FilterMaps) setRange(batch ethdb.KeyValueWriter, newView *ChainView, newRange filterMapsRange) { + f.indexedView = newView + f.indexedRange = newRange + f.updateMatchersValidRange() + if newRange.initialized { + rs := rawdb.FilterMapsRange{ + HeadBlockIndexed: newRange.headBlockIndexed, + HeadBlockDelimiter: newRange.headBlockDelimiter, + FirstIndexedBlock: newRange.firstIndexedBlock, + AfterLastIndexedBlock: newRange.afterLastIndexedBlock, + FirstRenderedMap: newRange.firstRenderedMap, + AfterLastRenderedMap: newRange.afterLastRenderedMap, + TailPartialEpoch: newRange.tailPartialEpoch, + } + rawdb.WriteFilterMapsRange(batch, rs) + } else { + rawdb.DeleteFilterMapsRange(batch) + } +} + +// getLogByLvIndex returns the log at the given log value index. If the index does +// not point to the first log value entry of a log then no log and no error are +// returned as this can happen when the log value index was a false positive. +// Note that this function assumes that the log index structure is consistent +// with the canonical chain at the point where the given log value index points. +// If this is not the case then an invalid result or an error may be returned. +// Note that this function assumes that the indexer read lock is being held when +// called from outside the indexerLoop goroutine. +func (f *FilterMaps) getLogByLvIndex(lvIndex uint64) (*types.Log, error) { + mapIndex := uint32(lvIndex >> f.logValuesPerMap) + if mapIndex < f.indexedRange.firstRenderedMap || mapIndex >= f.indexedRange.afterLastRenderedMap { + return nil, nil + } + // find possible block range based on map to block pointers + lastBlockNumber, _, err := f.getLastBlockOfMap(mapIndex) + if err != nil { + return nil, fmt.Errorf("failed to retrieve last block of map %d containing searched log value index %d: %v", mapIndex, lvIndex, err) + } + var firstBlockNumber uint64 + if mapIndex > 0 { + firstBlockNumber, _, err = f.getLastBlockOfMap(mapIndex - 1) + if err != nil { + return nil, fmt.Errorf("failed to retrieve last block of map %d before searched log value index %d: %v", mapIndex, lvIndex, err) + } + } + if firstBlockNumber < f.indexedRange.firstIndexedBlock { + firstBlockNumber = f.indexedRange.firstIndexedBlock + } + // find block with binary search based on block to log value index pointers + for firstBlockNumber < lastBlockNumber { + midBlockNumber := (firstBlockNumber + lastBlockNumber + 1) / 2 + midLvPointer, err := f.getBlockLvPointer(midBlockNumber) + if err != nil { + return nil, fmt.Errorf("failed to retrieve log value pointer of block %d while binary searching log value index %d: %v", midBlockNumber, lvIndex, err) + } + if lvIndex < midLvPointer { + lastBlockNumber = midBlockNumber - 1 + } else { + firstBlockNumber = midBlockNumber + } + } + // get block receipts + receipts := f.indexedView.getReceipts(firstBlockNumber) + if receipts == nil { + return nil, fmt.Errorf("failed to retrieve receipts for block %d containing searched log value index %d: %v", firstBlockNumber, lvIndex, err) + } + lvPointer, err := f.getBlockLvPointer(firstBlockNumber) + if err != nil { + return nil, fmt.Errorf("failed to retrieve log value pointer of block %d containing searched log value index %d: %v", firstBlockNumber, lvIndex, err) + } + // iterate through receipts to find the exact log starting at lvIndex + for _, receipt := range receipts { + for _, log := range receipt.Logs { + if lvPointer > lvIndex { + // lvIndex does not point to the first log value (address value) + // generated by a log as true matches should always do, so it + // is considered a false positive (no log and no error returned). + return nil, nil + } + if lvPointer == lvIndex { + return log, nil // potential match + } + lvPointer += uint64(len(log.Topics) + 1) + } + } + return nil, nil +} + +// getFilterMap fetches an entire filter map from the database. +func (f *FilterMaps) getFilterMap(mapIndex uint32) (filterMap, error) { + if fm, ok := f.filterMapCache.Get(mapIndex); ok { + return fm, nil + } + fm := make(filterMap, f.mapHeight) + for rowIndex := range fm { + var err error + fm[rowIndex], err = f.getFilterMapRow(mapIndex, uint32(rowIndex), false) + if err != nil { + return nil, fmt.Errorf("failed to load filter map %d from database: %v", mapIndex, err) + } + } + f.filterMapCache.Add(mapIndex, fm) + return fm, nil +} + +// getFilterMapRow fetches the given filter map row. If baseLayerOnly is true +// then only the first baseRowLength entries are returned. +func (f *FilterMaps) getFilterMapRow(mapIndex, rowIndex uint32, baseLayerOnly bool) (FilterRow, error) { + baseMapRowIndex := f.mapRowIndex(mapIndex&-f.baseRowGroupLength, rowIndex) + baseRows, ok := f.baseRowsCache.Get(baseMapRowIndex) + if !ok { + var err error + baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, baseMapRowIndex, f.baseRowGroupLength, f.logMapWidth) + if err != nil { + return nil, fmt.Errorf("failed to retrieve filter map %d base rows %d: %v", mapIndex, rowIndex, err) + } + f.baseRowsCache.Add(baseMapRowIndex, baseRows) + } + baseRow := baseRows[mapIndex&(f.baseRowGroupLength-1)] + if baseLayerOnly { + return baseRow, nil + } + extRow, err := rawdb.ReadFilterMapExtRow(f.db, f.mapRowIndex(mapIndex, rowIndex), f.logMapWidth) + if err != nil { + return nil, fmt.Errorf("failed to retrieve filter map %d extended row %d: %v", mapIndex, rowIndex, err) + } + return FilterRow(append(baseRow, extRow...)), nil +} + +// storeFilterMapRows stores a set of filter map rows at the corresponding map +// indices and a shared row index. +func (f *FilterMaps) storeFilterMapRows(batch ethdb.Batch, mapIndices []uint32, rowIndex uint32, rows []FilterRow) error { + for len(mapIndices) > 0 { + baseMapIndex := mapIndices[0] & -f.baseRowGroupLength + groupLength := 1 + for groupLength < len(mapIndices) && mapIndices[groupLength]&-f.baseRowGroupLength == baseMapIndex { + groupLength++ + } + if err := f.storeFilterMapRowsOfGroup(batch, mapIndices[:groupLength], rowIndex, rows[:groupLength]); err != nil { + return err + } + mapIndices, rows = mapIndices[groupLength:], rows[groupLength:] + } + return nil +} + +// storeFilterMapRowsOfGroup stores a set of filter map rows at map indices +// belonging to the same base row group. +func (f *FilterMaps) storeFilterMapRowsOfGroup(batch ethdb.Batch, mapIndices []uint32, rowIndex uint32, rows []FilterRow) error { + baseMapIndex := mapIndices[0] & -f.baseRowGroupLength + baseMapRowIndex := f.mapRowIndex(baseMapIndex, rowIndex) + var baseRows [][]uint32 + if uint32(len(mapIndices)) != f.baseRowGroupLength { // skip base rows read if all rows are replaced + var ok bool + baseRows, ok = f.baseRowsCache.Get(baseMapRowIndex) + if !ok { + var err error + baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, baseMapRowIndex, f.baseRowGroupLength, f.logMapWidth) + if err != nil { + return fmt.Errorf("failed to retrieve filter map %d base rows %d for modification: %v", mapIndices[0]&-f.baseRowGroupLength, rowIndex, err) + } + } + } else { + baseRows = make([][]uint32, f.baseRowGroupLength) + } + for i, mapIndex := range mapIndices { + if mapIndex&-f.baseRowGroupLength != baseMapIndex { + panic("mapIndices are not in the same base row group") + } + baseRow := []uint32(rows[i]) + var extRow FilterRow + if uint32(len(rows[i])) > f.baseRowLength { + extRow = baseRow[f.baseRowLength:] + baseRow = baseRow[:f.baseRowLength] + } + baseRows[mapIndex&(f.baseRowGroupLength-1)] = baseRow + rawdb.WriteFilterMapExtRow(batch, f.mapRowIndex(mapIndex, rowIndex), extRow, f.logMapWidth) + } + f.baseRowsCache.Add(baseMapRowIndex, baseRows) + rawdb.WriteFilterMapBaseRows(batch, baseMapRowIndex, baseRows, f.logMapWidth) + return nil +} + +// mapRowIndex calculates the unified storage index where the given row of the +// given map is stored. Note that this indexing scheme is the same as the one +// proposed in EIP-7745 for tree-hashing the filter map structure and for the +// same data proximity reasons it is also suitable for database representation. +// See also: +// https://eips.ethereum.org/EIPS/eip-7745#hash-tree-structure +func (f *FilterMaps) mapRowIndex(mapIndex, rowIndex uint32) uint64 { + epochIndex, mapSubIndex := mapIndex>>f.logMapsPerEpoch, mapIndex&(f.mapsPerEpoch-1) + return (uint64(epochIndex)<= f.indexedRange.afterLastIndexedBlock && f.indexedRange.headBlockIndexed { + return f.indexedRange.headBlockDelimiter, nil + } + if lvPointer, ok := f.lvPointerCache.Get(blockNumber); ok { + return lvPointer, nil + } + lvPointer, err := rawdb.ReadBlockLvPointer(f.db, blockNumber) + if err != nil { + return 0, fmt.Errorf("failed to retrieve log value pointer of block %d: %v", blockNumber, err) + } + f.lvPointerCache.Add(blockNumber, lvPointer) + return lvPointer, nil +} + +// storeBlockLvPointer stores the starting log value index where the log values +// generated by the given block are located. +func (f *FilterMaps) storeBlockLvPointer(batch ethdb.Batch, blockNumber, lvPointer uint64) { + f.lvPointerCache.Add(blockNumber, lvPointer) + rawdb.WriteBlockLvPointer(batch, blockNumber, lvPointer) +} + +// deleteBlockLvPointer deletes the starting log value index where the log values +// generated by the given block are located. +func (f *FilterMaps) deleteBlockLvPointer(batch ethdb.Batch, blockNumber uint64) { + f.lvPointerCache.Remove(blockNumber) + rawdb.DeleteBlockLvPointer(batch, blockNumber) +} + +// getLastBlockOfMap returns the number and id of the block that generated the +// last log value entry of the given map. +func (f *FilterMaps) getLastBlockOfMap(mapIndex uint32) (uint64, common.Hash, error) { + if lastBlock, ok := f.lastBlockCache.Get(mapIndex); ok { + return lastBlock.number, lastBlock.id, nil + } + number, id, err := rawdb.ReadFilterMapLastBlock(f.db, mapIndex) + if err != nil { + return 0, common.Hash{}, fmt.Errorf("failed to retrieve last block of map %d: %v", mapIndex, err) + } + f.lastBlockCache.Add(mapIndex, lastBlockOfMap{number: number, id: id}) + return number, id, nil +} + +// storeLastBlockOfMap stores the number of the block that generated the last +// log value entry of the given map. +func (f *FilterMaps) storeLastBlockOfMap(batch ethdb.Batch, mapIndex uint32, number uint64, id common.Hash) { + f.lastBlockCache.Add(mapIndex, lastBlockOfMap{number: number, id: id}) + rawdb.WriteFilterMapLastBlock(batch, mapIndex, number, id) +} + +// deleteLastBlockOfMap deletes the number of the block that generated the last +// log value entry of the given map. +func (f *FilterMaps) deleteLastBlockOfMap(batch ethdb.Batch, mapIndex uint32) { + f.lastBlockCache.Remove(mapIndex) + rawdb.DeleteFilterMapLastBlock(batch, mapIndex) +} + +// deleteTailEpoch deletes index data from the earliest, either fully or partially +// indexed epoch. The last block pointer for the last map of the epoch and the +// corresponding block log value pointer are retained as these are always assumed +// to be available for each epoch. +func (f *FilterMaps) deleteTailEpoch(epoch uint32) error { + f.indexLock.Lock() + defer f.indexLock.Unlock() + + firstMap := epoch << f.logMapsPerEpoch + lastBlock, _, err := f.getLastBlockOfMap(firstMap + f.mapsPerEpoch - 1) + if err != nil { + return fmt.Errorf("failed to retrieve last block of deleted epoch %d: %v", epoch, err) + } + var firstBlock uint64 + if epoch > 0 { + firstBlock, _, err = f.getLastBlockOfMap(firstMap - 1) + if err != nil { + return fmt.Errorf("failed to retrieve last block before deleted epoch %d: %v", epoch, err) + } + firstBlock++ + } + fmr := f.indexedRange + if f.indexedRange.firstRenderedMap == firstMap && + f.indexedRange.afterLastRenderedMap > firstMap+f.mapsPerEpoch && + f.indexedRange.tailPartialEpoch == 0 { + fmr.firstRenderedMap = firstMap + f.mapsPerEpoch + fmr.firstIndexedBlock = lastBlock + 1 + } else if f.indexedRange.firstRenderedMap == firstMap+f.mapsPerEpoch { + fmr.tailPartialEpoch = 0 + } else { + return errors.New("invalid tail epoch number") + } + f.setRange(f.db, f.indexedView, fmr) + rawdb.DeleteFilterMapRows(f.db, f.mapRowIndex(firstMap, 0), f.mapRowIndex(firstMap+f.mapsPerEpoch, 0)) + for mapIndex := firstMap; mapIndex < firstMap+f.mapsPerEpoch; mapIndex++ { + f.filterMapCache.Remove(mapIndex) + } + rawdb.DeleteFilterMapLastBlocks(f.db, firstMap, firstMap+f.mapsPerEpoch-1) // keep last enrty + for mapIndex := firstMap; mapIndex < firstMap+f.mapsPerEpoch-1; mapIndex++ { + f.lastBlockCache.Remove(mapIndex) + } + rawdb.DeleteBlockLvPointers(f.db, firstBlock, lastBlock) // keep last enrty + for blockNumber := firstBlock; blockNumber < lastBlock; blockNumber++ { + f.lvPointerCache.Remove(blockNumber) + } + return nil +} + +// exportCheckpoints exports epoch checkpoints in the format used by checkpoints.go. +func (f *FilterMaps) exportCheckpoints() { + finalLvPtr, err := f.getBlockLvPointer(f.finalBlock + 1) + if err != nil { + log.Error("Error fetching log value pointer of finalized block", "block", f.finalBlock, "error", err) + return + } + epochCount := uint32(finalLvPtr >> (f.logValuesPerMap + f.logMapsPerEpoch)) + if epochCount == f.lastFinalEpoch { + return + } + w, err := os.Create(f.exportFileName) + if err != nil { + log.Error("Error creating checkpoint export file", "name", f.exportFileName, "error", err) + return + } + defer w.Close() + + log.Info("Exporting log index checkpoints", "epochs", epochCount, "file", f.exportFileName) + w.WriteString("[\n") + comma := "," + for epoch := uint32(0); epoch < epochCount; epoch++ { + lastBlock, lastBlockId, err := f.getLastBlockOfMap((epoch+1)<. + +package filtermaps + +import ( + "math" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +const ( + logFrequency = time.Second * 20 // log info frequency during long indexing/unindexing process + headLogDelay = time.Second // head indexing log info delay (do not log if finished faster) +) + +// updateLoop initializes and updates the log index structure according to the +// current targetView. +func (f *FilterMaps) indexerLoop() { + defer f.closeWg.Done() + + if f.disabled { + f.reset() + return + } + log.Info("Started log indexer") + + for !f.stop { + if !f.indexedRange.initialized { + if err := f.init(); err != nil { + log.Error("Error initializing log index", "error", err) + f.waitForEvent() + continue + } + } + if !f.targetHeadIndexed() { + if !f.tryIndexHead() { + f.waitForEvent() + } + } else { + if f.finalBlock != f.lastFinal { + if f.exportFileName != "" { + f.exportCheckpoints() + } + f.lastFinal = f.finalBlock + } + if f.tryIndexTail() && f.tryUnindexTail() { + f.waitForEvent() + } + } + } +} + +// SetTargetView sets a new target chain view for the indexer to render. +// Note that SetTargetView never blocks. +func (f *FilterMaps) SetTargetView(targetView *ChainView) { + if targetView == nil { + panic("nil targetView") + } + for { + select { + case <-f.targetViewCh: + case f.targetViewCh <- targetView: + return + } + } +} + +// SetFinalBlock sets the finalized block number used for exporting checkpoints. +// Note that SetFinalBlock never blocks. +func (f *FilterMaps) SetFinalBlock(finalBlock uint64) { + for { + select { + case <-f.finalBlockCh: + case f.finalBlockCh <- finalBlock: + return + } + } +} + +// SetBlockProcessing sets the block processing flag that temporarily suspends +// log index rendering. +// Note that SetBlockProcessing never blocks. +func (f *FilterMaps) SetBlockProcessing(blockProcessing bool) { + for { + select { + case <-f.blockProcessingCh: + case f.blockProcessingCh <- blockProcessing: + return + } + } +} + +// WaitIdle blocks until the indexer is in an idle state while synced up to the +// latest targetView. +func (f *FilterMaps) WaitIdle() { + if f.disabled { + f.closeWg.Wait() + return + } + for { + ch := make(chan bool) + f.waitIdleCh <- ch + if <-ch { + return + } + } +} + +// waitForEvent blocks until an event happens that the indexer might react to. +func (f *FilterMaps) waitForEvent() { + for !f.stop && (f.blockProcessing || f.targetHeadIndexed()) { + f.processSingleEvent(true) + } +} + +// processEvents processes all events, blocking only if a block processing is +// happening and indexing should be suspended. +func (f *FilterMaps) processEvents() { + for !f.stop && f.processSingleEvent(f.blockProcessing) { + } +} + +// processSingleEvent processes a single event either in a blocking or +// non-blocking manner. +func (f *FilterMaps) processSingleEvent(blocking bool) bool { + if f.matcherSyncRequest != nil && f.targetHeadIndexed() { + f.matcherSyncRequest.synced() + f.matcherSyncRequest = nil + } + if blocking { + select { + case targetView := <-f.targetViewCh: + f.setTargetView(targetView) + case f.finalBlock = <-f.finalBlockCh: + case f.matcherSyncRequest = <-f.matcherSyncCh: + case f.blockProcessing = <-f.blockProcessingCh: + case <-f.closeCh: + f.stop = true + case ch := <-f.waitIdleCh: + select { + case targetView := <-f.targetViewCh: + f.setTargetView(targetView) + default: + } + ch <- !f.blockProcessing && f.targetHeadIndexed() + } + } else { + select { + case targetView := <-f.targetViewCh: + f.setTargetView(targetView) + case f.finalBlock = <-f.finalBlockCh: + case f.matcherSyncRequest = <-f.matcherSyncCh: + case f.blockProcessing = <-f.blockProcessingCh: + case <-f.closeCh: + f.stop = true + default: + return false + } + } + return true +} + +// setTargetView updates the target chain view of the iterator. +func (f *FilterMaps) setTargetView(targetView *ChainView) { + f.targetView = targetView +} + +// tryIndexHead tries to render head maps according to the current targetView +// and returns true if successful. +func (f *FilterMaps) tryIndexHead() bool { + headRenderer, err := f.renderMapsBefore(math.MaxUint32) + if err != nil { + log.Error("Error creating log index head renderer", "error", err) + return false + } + if headRenderer == nil { + return true + } + if !f.startedHeadIndex { + f.lastLogHeadIndex = time.Now() + f.startedHeadIndexAt = f.lastLogHeadIndex + f.startedHeadIndex = true + f.ptrHeadIndex = f.indexedRange.afterLastIndexedBlock + } + if _, err := headRenderer.run(func() bool { + f.processEvents() + return f.stop + }, func() { + f.tryUnindexTail() + if f.indexedRange.hasIndexedBlocks() && f.indexedRange.afterLastIndexedBlock >= f.ptrHeadIndex && + ((!f.loggedHeadIndex && time.Since(f.startedHeadIndexAt) > headLogDelay) || + time.Since(f.lastLogHeadIndex) > logFrequency) { + log.Info("Log index head rendering in progress", + "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, + "processed", f.indexedRange.afterLastIndexedBlock-f.ptrHeadIndex, + "remaining", f.indexedView.headNumber+1-f.indexedRange.afterLastIndexedBlock, + "elapsed", common.PrettyDuration(time.Since(f.startedHeadIndexAt))) + f.loggedHeadIndex = true + f.lastLogHeadIndex = time.Now() + } + }); err != nil { + log.Error("Log index head rendering failed", "error", err) + return false + } + if f.loggedHeadIndex { + log.Info("Log index head rendering finished", + "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, + "processed", f.indexedRange.afterLastIndexedBlock-f.ptrHeadIndex, + "elapsed", common.PrettyDuration(time.Since(f.startedHeadIndexAt))) + } + f.loggedHeadIndex, f.startedHeadIndex = false, false + return true +} + +// tryIndexTail tries to render tail epochs until the tail target block is +// indexed and returns true if successful. +// Note that tail indexing is only started if the log index head is fully +// rendered according to targetView and is suspended as soon as the targetView +// is changed. +func (f *FilterMaps) tryIndexTail() bool { + for firstEpoch := f.indexedRange.firstRenderedMap >> f.logMapsPerEpoch; firstEpoch > 0 && f.needTailEpoch(firstEpoch-1); { + f.processEvents() + if f.stop || !f.targetHeadIndexed() { + return false + } + // resume process if tail rendering was interrupted because of head rendering + tailRenderer := f.tailRenderer + f.tailRenderer = nil + if tailRenderer != nil && tailRenderer.afterLastMap != f.indexedRange.firstRenderedMap { + tailRenderer = nil + } + if tailRenderer == nil { + var err error + tailRenderer, err = f.renderMapsBefore(f.indexedRange.firstRenderedMap) + if err != nil { + log.Error("Error creating log index tail renderer", "error", err) + return false + } + } + if tailRenderer == nil { + return true + } + if !f.startedTailIndex { + f.lastLogTailIndex = time.Now() + f.startedTailIndexAt = f.lastLogTailIndex + f.startedTailIndex = true + f.ptrTailIndex = f.indexedRange.firstIndexedBlock - f.tailPartialBlocks() + } + done, err := tailRenderer.run(func() bool { + f.processEvents() + return f.stop || !f.targetHeadIndexed() + }, func() { + tpb, ttb := f.tailPartialBlocks(), f.tailTargetBlock() + remaining := uint64(1) + if f.indexedRange.firstIndexedBlock > ttb+tpb { + remaining = f.indexedRange.firstIndexedBlock - ttb - tpb + } + if f.indexedRange.hasIndexedBlocks() && f.ptrTailIndex >= f.indexedRange.firstIndexedBlock && + (!f.loggedTailIndex || time.Since(f.lastLogTailIndex) > logFrequency) { + log.Info("Log index tail rendering in progress", + "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, + "processed", f.ptrTailIndex-f.indexedRange.firstIndexedBlock+tpb, + "remaining", remaining, + "next tail epoch percentage", f.indexedRange.tailPartialEpoch*100/f.mapsPerEpoch, + "elapsed", common.PrettyDuration(time.Since(f.startedTailIndexAt))) + f.loggedTailIndex = true + f.lastLogTailIndex = time.Now() + } + }) + if err != nil { + log.Error("Log index tail rendering failed", "error", err) + } + if !done { + f.tailRenderer = tailRenderer // only keep tail renderer if interrupted by stopCb + return false + } + } + if f.loggedTailIndex { + log.Info("Log index tail rendering finished", + "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, + "processed", f.ptrTailIndex-f.indexedRange.firstIndexedBlock, + "elapsed", common.PrettyDuration(time.Since(f.startedTailIndexAt))) + f.loggedTailIndex = false + } + return true +} + +// tryUnindexTail removes entire epochs of log index data as long as the first +// fully indexed block is at least as old as the tail target. +// Note that unindexing is very quick as it only removes continuous ranges of +// data from the database and is also called while running head indexing. +func (f *FilterMaps) tryUnindexTail() bool { + for { + firstEpoch := (f.indexedRange.firstRenderedMap - f.indexedRange.tailPartialEpoch) >> f.logMapsPerEpoch + if f.needTailEpoch(firstEpoch) { + break + } + f.processEvents() + if f.stop { + return false + } + if !f.startedTailUnindex { + f.startedTailUnindexAt = time.Now() + f.startedTailUnindex = true + f.ptrTailUnindexMap = f.indexedRange.firstRenderedMap - f.indexedRange.tailPartialEpoch + f.ptrTailUnindexBlock = f.indexedRange.firstIndexedBlock - f.tailPartialBlocks() + } + if err := f.deleteTailEpoch(firstEpoch); err != nil { + log.Error("Log index tail epoch unindexing failed", "error", err) + return false + } + } + if f.startedTailUnindex { + log.Info("Log index tail unindexing finished", + "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, + "removed maps", f.indexedRange.firstRenderedMap-f.ptrTailUnindexMap, + "removed blocks", f.indexedRange.firstIndexedBlock-f.tailPartialBlocks()-f.ptrTailUnindexBlock, + "elapsed", common.PrettyDuration(time.Since(f.startedTailUnindexAt))) + f.startedTailUnindex = false + } + return true +} + +// needTailEpoch returns true if the given tail epoch needs to be kept +// according to the current tail target, false if it can be removed. +func (f *FilterMaps) needTailEpoch(epoch uint32) bool { + firstEpoch := f.indexedRange.firstRenderedMap >> f.logMapsPerEpoch + if epoch > firstEpoch { + return true + } + if epoch+1 < firstEpoch { + return false + } + tailTarget := f.tailTargetBlock() + if tailTarget < f.indexedRange.firstIndexedBlock { + return true + } + tailLvIndex, err := f.getBlockLvPointer(tailTarget) + if err != nil { + log.Error("Could not get log value index of tail block", "error", err) + return true + } + return uint64(epoch+1)<<(f.logValuesPerMap+f.logMapsPerEpoch) >= tailLvIndex +} + +// tailTargetBlock returns the target value for the tail block number according +// to the log history parameter and the current index head. +func (f *FilterMaps) tailTargetBlock() uint64 { + if f.history == 0 || f.indexedView.headNumber < f.history { + return 0 + } + return f.indexedView.headNumber + 1 - f.history +} + +// tailPartialBlocks returns the number of rendered blocks in the partially +// rendered next tail epoch. +func (f *FilterMaps) tailPartialBlocks() uint64 { + if f.indexedRange.tailPartialEpoch == 0 { + return 0 + } + end, _, err := f.getLastBlockOfMap(f.indexedRange.firstRenderedMap - f.mapsPerEpoch + f.indexedRange.tailPartialEpoch - 1) + if err != nil { + log.Error("Error fetching last block of map", "mapIndex", f.indexedRange.firstRenderedMap-f.mapsPerEpoch+f.indexedRange.tailPartialEpoch-1, "error", err) + } + var start uint64 + if f.indexedRange.firstRenderedMap-f.mapsPerEpoch > 0 { + start, _, err = f.getLastBlockOfMap(f.indexedRange.firstRenderedMap - f.mapsPerEpoch - 1) + if err != nil { + log.Error("Error fetching last block of map", "mapIndex", f.indexedRange.firstRenderedMap-f.mapsPerEpoch-1, "error", err) + } + } + return end - start +} + +// targetHeadIndexed returns true if the current log index is consistent with +// targetView with its head block fully rendered. +func (f *FilterMaps) targetHeadIndexed() bool { + return equalViews(f.targetView, f.indexedView) && f.indexedRange.headBlockIndexed +} diff --git a/core/filtermaps/indexer_test.go b/core/filtermaps/indexer_test.go new file mode 100644 index 0000000000..17ad765e04 --- /dev/null +++ b/core/filtermaps/indexer_test.go @@ -0,0 +1,444 @@ +// 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 filtermaps + +import ( + crand "crypto/rand" + "crypto/sha256" + "math/big" + "math/rand" + "sync" + "testing" + + "github.com/ethereum/go-ethereum/common" + "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/ethdb" + "github.com/ethereum/go-ethereum/params" +) + +var testParams = Params{ + logMapHeight: 2, + logMapWidth: 24, + logMapsPerEpoch: 4, + logValuesPerMap: 4, + baseRowGroupLength: 4, + baseRowLengthRatio: 2, + logLayerDiff: 2, +} + +func TestIndexerRandomRange(t *testing.T) { + ts := newTestSetup(t) + defer ts.close() + + forks := make([][]common.Hash, 10) + ts.chain.addBlocks(1000, 5, 2, 4, false) // 51 log values per block + for i := range forks { + if i != 0 { + forkBlock := rand.Intn(1000) + ts.chain.setHead(forkBlock) + ts.chain.addBlocks(1000-forkBlock, 5, 2, 4, false) // 51 log values per block + } + forks[i] = ts.chain.getCanonicalChain() + } + lvPerBlock := uint64(51) + ts.setHistory(0, false) + var ( + history int + noHistory bool + fork, head = len(forks) - 1, 1000 + checkSnapshot bool + ) + ts.fm.WaitIdle() + for i := 0; i < 200; i++ { + switch rand.Intn(3) { + case 0: + // change history settings + switch rand.Intn(10) { + case 0: + history, noHistory = 0, false + case 1: + history, noHistory = 0, true + default: + history, noHistory = rand.Intn(1000)+1, false + } + ts.testDisableSnapshots = rand.Intn(2) == 0 + ts.setHistory(uint64(history), noHistory) + case 1: + // change head to random position of random fork + fork, head = rand.Intn(len(forks)), rand.Intn(1001) + ts.chain.setCanonicalChain(forks[fork][:head+1]) + case 2: + if head < 1000 { + checkSnapshot = !noHistory && head != 0 // no snapshot generated for block 0 + // add blocks after the current head + head += rand.Intn(1000-head) + 1 + ts.fm.testSnapshotUsed = false + ts.chain.setCanonicalChain(forks[fork][:head+1]) + } + } + ts.fm.WaitIdle() + if checkSnapshot { + if ts.fm.testSnapshotUsed == ts.fm.testDisableSnapshots { + ts.t.Fatalf("Invalid snapshot used state after head extension (used: %v, disabled: %v)", ts.fm.testSnapshotUsed, ts.fm.testDisableSnapshots) + } + checkSnapshot = false + } + if noHistory { + if ts.fm.indexedRange.initialized { + t.Fatalf("filterMapsRange initialized while indexing is disabled") + } + continue + } + if !ts.fm.indexedRange.initialized { + t.Fatalf("filterMapsRange not initialized while indexing is enabled") + } + var tailBlock uint64 + if history > 0 && history <= head { + tailBlock = uint64(head + 1 - history) + } + var tailEpoch uint32 + if tailBlock > 0 { + tailLvPtr := (tailBlock - 1) * lvPerBlock // no logs in genesis block, only delimiter + tailEpoch = uint32(tailLvPtr >> (testParams.logValuesPerMap + testParams.logMapsPerEpoch)) + } + var expTailBlock uint64 + if tailEpoch > 0 { + tailLvPtr := uint64(tailEpoch) << (testParams.logValuesPerMap + testParams.logMapsPerEpoch) // first available lv ptr + // (expTailBlock-1)*lvPerBlock >= tailLvPtr + expTailBlock = (tailLvPtr + lvPerBlock*2 - 1) / lvPerBlock + } + if ts.fm.indexedRange.afterLastIndexedBlock != uint64(head+1) { + ts.t.Fatalf("Invalid index head (expected #%d, got #%d)", head, ts.fm.indexedRange.afterLastIndexedBlock-1) + } + if ts.fm.indexedRange.headBlockDelimiter != uint64(head)*lvPerBlock { + ts.t.Fatalf("Invalid index head delimiter pointer (expected %d, got %d)", uint64(head)*lvPerBlock, ts.fm.indexedRange.headBlockDelimiter) + } + if ts.fm.indexedRange.firstIndexedBlock != expTailBlock { + ts.t.Fatalf("Invalid index tail block (expected #%d, got #%d)", expTailBlock, ts.fm.indexedRange.firstIndexedBlock) + } + } +} + +func TestIndexerCompareDb(t *testing.T) { + ts := newTestSetup(t) + defer ts.close() + + ts.chain.addBlocks(500, 10, 3, 4, true) + ts.setHistory(0, false) + ts.fm.WaitIdle() + // revert points are stored after block 500 + ts.chain.addBlocks(500, 10, 3, 4, true) + ts.fm.WaitIdle() + chain1 := ts.chain.getCanonicalChain() + ts.storeDbHash("chain 1 [0, 1000]") + + ts.chain.setHead(600) + ts.fm.WaitIdle() + ts.storeDbHash("chain 1/2 [0, 600]") + + ts.chain.addBlocks(600, 10, 3, 4, true) + ts.fm.WaitIdle() + chain2 := ts.chain.getCanonicalChain() + ts.storeDbHash("chain 2 [0, 1200]") + + ts.chain.setHead(600) + ts.fm.WaitIdle() + ts.checkDbHash("chain 1/2 [0, 600]") + + ts.setHistory(800, false) + ts.chain.setCanonicalChain(chain1) + ts.fm.WaitIdle() + ts.storeDbHash("chain 1 [201, 1000]") + + ts.setHistory(0, false) + ts.fm.WaitIdle() + ts.checkDbHash("chain 1 [0, 1000]") + + ts.setHistory(800, false) + ts.chain.setCanonicalChain(chain2) + ts.fm.WaitIdle() + ts.storeDbHash("chain 2 [401, 1200]") + + ts.setHistory(0, true) + ts.fm.WaitIdle() + ts.storeDbHash("no index") + + ts.chain.setCanonicalChain(chain2[:501]) + ts.setHistory(0, false) + ts.fm.WaitIdle() + ts.chain.setCanonicalChain(chain2) + ts.fm.WaitIdle() + ts.checkDbHash("chain 2 [0, 1200]") + + ts.chain.setCanonicalChain(chain1) + ts.fm.WaitIdle() + ts.setHistory(800, false) + ts.fm.WaitIdle() + ts.checkDbHash("chain 1 [201, 1000]") + + ts.chain.setCanonicalChain(chain2) + ts.fm.WaitIdle() + ts.checkDbHash("chain 2 [401, 1200]") + + ts.setHistory(0, true) + ts.fm.WaitIdle() + ts.checkDbHash("no index") +} + +type testSetup struct { + t *testing.T + fm *FilterMaps + db ethdb.Database + chain *testChain + params Params + dbHashes map[string]common.Hash + testDisableSnapshots bool +} + +func newTestSetup(t *testing.T) *testSetup { + params := testParams + params.deriveFields() + ts := &testSetup{ + t: t, + db: rawdb.NewMemoryDatabase(), + params: params, + dbHashes: make(map[string]common.Hash), + } + ts.chain = ts.newTestChain() + return ts +} + +func (ts *testSetup) setHistory(history uint64, noHistory bool) { + if ts.fm != nil { + ts.fm.Stop() + } + head := ts.chain.CurrentBlock() + view := NewChainView(ts.chain, head.Number.Uint64(), head.Hash()) + config := Config{ + History: history, + Disabled: noHistory, + } + ts.fm = NewFilterMaps(ts.db, view, ts.params, config) + ts.fm.testDisableSnapshots = ts.testDisableSnapshots + ts.fm.Start() +} + +func (ts *testSetup) storeDbHash(id string) { + dbHash := ts.fmDbHash() + for otherId, otherHash := range ts.dbHashes { + if otherHash == dbHash { + ts.t.Fatalf("Unexpected equal database hashes `%s` and `%s`", id, otherId) + } + } + ts.dbHashes[id] = dbHash +} + +func (ts *testSetup) checkDbHash(id string) { + if ts.fmDbHash() != ts.dbHashes[id] { + ts.t.Fatalf("Database `%s` hash mismatch", id) + } +} + +func (ts *testSetup) fmDbHash() common.Hash { + hasher := sha256.New() + it := ts.db.NewIterator(nil, nil) + for it.Next() { + hasher.Write(it.Key()) + hasher.Write(it.Value()) + } + it.Release() + var result common.Hash + hasher.Sum(result[:0]) + return result +} + +func (ts *testSetup) close() { + if ts.fm != nil { + ts.fm.Stop() + } + ts.db.Close() + ts.chain.db.Close() +} + +type testChain struct { + ts *testSetup + db ethdb.Database + lock sync.RWMutex + canonical []common.Hash + blocks map[common.Hash]*types.Block + receipts map[common.Hash]types.Receipts +} + +func (ts *testSetup) newTestChain() *testChain { + return &testChain{ + ts: ts, + blocks: make(map[common.Hash]*types.Block), + receipts: make(map[common.Hash]types.Receipts), + } +} + +func (tc *testChain) CurrentBlock() *types.Header { + tc.lock.RLock() + defer tc.lock.RUnlock() + + if len(tc.canonical) == 0 { + return nil + } + return tc.blocks[tc.canonical[len(tc.canonical)-1]].Header() +} + +func (tc *testChain) GetHeader(hash common.Hash, number uint64) *types.Header { + tc.lock.RLock() + defer tc.lock.RUnlock() + + if block := tc.blocks[hash]; block != nil { + return block.Header() + } + return nil +} + +func (tc *testChain) GetCanonicalHash(number uint64) common.Hash { + tc.lock.RLock() + defer tc.lock.RUnlock() + + if uint64(len(tc.canonical)) <= number { + return common.Hash{} + } + return tc.canonical[number] +} + +func (tc *testChain) GetReceiptsByHash(hash common.Hash) types.Receipts { + tc.lock.RLock() + defer tc.lock.RUnlock() + + return tc.receipts[hash] +} + +func (tc *testChain) addBlocks(count, maxTxPerBlock, maxLogsPerReceipt, maxTopicsPerLog int, random bool) { + tc.lock.Lock() + blockGen := func(i int, gen *core.BlockGen) { + var txCount int + if random { + txCount = rand.Intn(maxTxPerBlock + 1) + } else { + txCount = maxTxPerBlock + } + for k := txCount; k > 0; k-- { + receipt := types.NewReceipt(nil, false, 0) + var logCount int + if random { + logCount = rand.Intn(maxLogsPerReceipt + 1) + } else { + logCount = maxLogsPerReceipt + } + receipt.Logs = make([]*types.Log, logCount) + for i := range receipt.Logs { + log := &types.Log{} + receipt.Logs[i] = log + crand.Read(log.Address[:]) + var topicCount int + if random { + topicCount = rand.Intn(maxTopicsPerLog + 1) + } else { + topicCount = maxTopicsPerLog + } + log.Topics = make([]common.Hash, topicCount) + for j := range log.Topics { + crand.Read(log.Topics[j][:]) + } + } + gen.AddUncheckedReceipt(receipt) + gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) + } + } + + var ( + blocks []*types.Block + receipts []types.Receipts + engine = ethash.NewFaker() + ) + + if len(tc.canonical) == 0 { + gspec := &core.Genesis{ + Alloc: types.GenesisAlloc{}, + BaseFee: big.NewInt(params.InitialBaseFee), + Config: params.TestChainConfig, + } + tc.db, blocks, receipts = core.GenerateChainWithGenesis(gspec, engine, count, blockGen) + gblock := gspec.ToBlock() + ghash := gblock.Hash() + tc.canonical = []common.Hash{ghash} + tc.blocks[ghash] = gblock + tc.receipts[ghash] = types.Receipts{} + } else { + blocks, receipts = core.GenerateChain(params.TestChainConfig, tc.blocks[tc.canonical[len(tc.canonical)-1]], engine, tc.db, count, blockGen) + } + + for i, block := range blocks { + num, hash := int(block.NumberU64()), block.Hash() + if len(tc.canonical) != num { + panic("canonical chain length mismatch") + } + tc.canonical = append(tc.canonical, hash) + tc.blocks[hash] = block + if receipts[i] != nil { + tc.receipts[hash] = receipts[i] + } else { + tc.receipts[hash] = types.Receipts{} + } + } + tc.lock.Unlock() + tc.setTargetHead() +} + +func (tc *testChain) setHead(headNum int) { + tc.lock.Lock() + tc.canonical = tc.canonical[:headNum+1] + tc.lock.Unlock() + tc.setTargetHead() +} + +func (tc *testChain) setTargetHead() { + head := tc.CurrentBlock() + if tc.ts.fm != nil { + if !tc.ts.fm.disabled { + //tc.ts.fm.targetViewCh <- NewChainView(tc, head.Number.Uint64(), head.Hash()) + tc.ts.fm.SetTargetView(NewChainView(tc, head.Number.Uint64(), head.Hash())) + } + } +} + +func (tc *testChain) getCanonicalChain() []common.Hash { + tc.lock.RLock() + defer tc.lock.RUnlock() + + cc := make([]common.Hash, len(tc.canonical)) + copy(cc, tc.canonical) + return cc +} + +// restore an earlier state of the chain +func (tc *testChain) setCanonicalChain(cc []common.Hash) { + tc.lock.Lock() + tc.canonical = make([]common.Hash, len(cc)) + copy(tc.canonical, cc) + tc.lock.Unlock() + tc.setTargetHead() +} diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go new file mode 100644 index 0000000000..5bd48a4b23 --- /dev/null +++ b/core/filtermaps/map_renderer.go @@ -0,0 +1,768 @@ +// 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 filtermaps + +import ( + "errors" + "fmt" + "math" + "sort" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +const ( + maxMapsPerBatch = 32 // maximum number of maps rendered in memory + valuesPerCallback = 1024 // log values processed per event process callback + cachedRowMappings = 10000 // log value to row mappings cached during rendering + + // Number of rows written to db in a single batch. + // The map renderer splits up writes like this to ensure that regular + // block processing latency is not affected by large batch writes. + rowsPerBatch = 1024 +) + +var ( + errChainUpdate = errors.New("rendered section of chain updated") +) + +// mapRenderer represents a process that renders filter maps in a specified +// range according to the actual targetView. +type mapRenderer struct { + f *FilterMaps + afterLastMap uint32 + currentMap *renderedMap + finishedMaps map[uint32]*renderedMap + firstFinished, afterLastFinished uint32 + iterator *logIterator +} + +// renderedMap represents a single filter map that is being rendered in memory. +type renderedMap struct { + filterMap filterMap + mapIndex uint32 + lastBlock uint64 + lastBlockId common.Hash + blockLvPtrs []uint64 // start pointers of blocks starting in this map; last one is lastBlock + finished bool // iterator finished; all values rendered + headDelimiter uint64 // if finished then points to the future block delimiter of the head block +} + +// firstBlock returns the first block number that starts in the given map. +func (r *renderedMap) firstBlock() uint64 { + return r.lastBlock + 1 - uint64(len(r.blockLvPtrs)) +} + +// renderMapsBefore creates a mapRenderer that renders the log index until the +// specified map index boundary, starting from the latest available starting +// point that is consistent with the current targetView. +// The renderer ensures that filterMapsRange, indexedView and the actual map +// data are always consistent with each other. If afterLastMap is greater than +// the latest existing rendered map then indexedView is updated to targetView, +// otherwise it is checked that the rendered range is consistent with both +// views. +func (f *FilterMaps) renderMapsBefore(afterLastMap uint32) (*mapRenderer, error) { + nextMap, startBlock, startLvPtr, err := f.lastCanonicalMapBoundaryBefore(afterLastMap) + if err != nil { + return nil, err + } + if snapshot := f.lastCanonicalSnapshotBefore(afterLastMap); snapshot != nil && snapshot.mapIndex >= nextMap { + return f.renderMapsFromSnapshot(snapshot) + } + if nextMap >= afterLastMap { + return nil, nil + } + return f.renderMapsFromMapBoundary(nextMap, afterLastMap, startBlock, startLvPtr) +} + +// renderMapsFromSnapshot creates a mapRenderer that starts rendering from a +// snapshot made at a block boundary. +func (f *FilterMaps) renderMapsFromSnapshot(cp *renderedMap) (*mapRenderer, error) { + f.testSnapshotUsed = true + iter, err := f.newLogIteratorFromBlockDelimiter(cp.lastBlock) + if err != nil { + return nil, fmt.Errorf("failed to create log iterator from block delimiter %d: %v", cp.lastBlock, err) + } + return &mapRenderer{ + f: f, + currentMap: &renderedMap{ + filterMap: cp.filterMap.copy(), + mapIndex: cp.mapIndex, + lastBlock: cp.lastBlock, + blockLvPtrs: cp.blockLvPtrs, + }, + finishedMaps: make(map[uint32]*renderedMap), + firstFinished: cp.mapIndex, + afterLastFinished: cp.mapIndex, + afterLastMap: math.MaxUint32, + iterator: iter, + }, nil +} + +// renderMapsFromMapBoundary creates a mapRenderer that starts rendering at a +// map boundary. +func (f *FilterMaps) renderMapsFromMapBoundary(firstMap, afterLastMap uint32, startBlock, startLvPtr uint64) (*mapRenderer, error) { + iter, err := f.newLogIteratorFromMapBoundary(firstMap, startBlock, startLvPtr) + if err != nil { + return nil, fmt.Errorf("failed to create log iterator from map boundary %d: %v", firstMap, err) + } + return &mapRenderer{ + f: f, + currentMap: &renderedMap{ + filterMap: f.emptyFilterMap(), + mapIndex: firstMap, + lastBlock: iter.blockNumber, + }, + finishedMaps: make(map[uint32]*renderedMap), + firstFinished: firstMap, + afterLastFinished: firstMap, + afterLastMap: afterLastMap, + iterator: iter, + }, nil +} + +// lastCanonicalSnapshotBefore returns the latest cached snapshot that matches +// the current targetView. +func (f *FilterMaps) lastCanonicalSnapshotBefore(afterLastMap uint32) *renderedMap { + var best *renderedMap + for _, blockNumber := range f.renderSnapshots.Keys() { + if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.afterLastIndexedBlock && + blockNumber <= f.targetView.headNumber && f.targetView.getBlockId(blockNumber) == cp.lastBlockId && + cp.mapIndex < afterLastMap && (best == nil || blockNumber > best.lastBlock) { + best = cp + } + } + return best +} + +// lastCanonicalMapBoundaryBefore returns the latest map boundary before the +// specified map index that matches the current targetView. This can either +// be a checkpoint (hardcoded or left from a previously unindexed tail epoch) +// or the boundary of a currently rendered map. +// Along with the next map index where the rendering can be started, the number +// and starting log value pointer of the last block is also returned. +func (f *FilterMaps) lastCanonicalMapBoundaryBefore(afterLastMap uint32) (nextMap uint32, startBlock, startLvPtr uint64, err error) { + if !f.indexedRange.initialized { + return 0, 0, 0, nil + } + mapIndex := afterLastMap + for { + var ok bool + if mapIndex, ok = f.lastMapBoundaryBefore(mapIndex); !ok { + return 0, 0, 0, nil + } + lastBlock, lastBlockId, err := f.getLastBlockOfMap(mapIndex) + if err != nil { + return 0, 0, 0, fmt.Errorf("failed to retrieve last block of reverse iterated map %d: %v", mapIndex, err) + } + if lastBlock >= f.indexedView.headNumber || lastBlock >= f.targetView.headNumber || + lastBlockId != f.targetView.getBlockId(lastBlock) { + // map is not full or inconsistent with targetView; roll back + continue + } + lvPtr, err := f.getBlockLvPointer(lastBlock) + if err != nil { + return 0, 0, 0, fmt.Errorf("failed to retrieve log value pointer of last canonical boundary block %d: %v", lastBlock, err) + } + return mapIndex + 1, lastBlock, lvPtr, nil + } +} + +// lastMapBoundaryBefore returns the latest map boundary before the specified +// map index. +func (f *FilterMaps) lastMapBoundaryBefore(mapIndex uint32) (uint32, bool) { + if !f.indexedRange.initialized || f.indexedRange.afterLastRenderedMap == 0 { + return 0, false + } + if mapIndex > f.indexedRange.afterLastRenderedMap { + mapIndex = f.indexedRange.afterLastRenderedMap + } + if mapIndex > f.indexedRange.firstRenderedMap { + return mapIndex - 1, true + } + if mapIndex+f.mapsPerEpoch > f.indexedRange.firstRenderedMap { + if mapIndex > f.indexedRange.firstRenderedMap-f.mapsPerEpoch+f.indexedRange.tailPartialEpoch { + mapIndex = f.indexedRange.firstRenderedMap - f.mapsPerEpoch + f.indexedRange.tailPartialEpoch + } + } else { + mapIndex = (mapIndex >> f.logMapsPerEpoch) << f.logMapsPerEpoch + } + if mapIndex == 0 { + return 0, false + } + return mapIndex - 1, true +} + +// emptyFilterMap returns an empty filter map. +func (f *FilterMaps) emptyFilterMap() filterMap { + return make(filterMap, f.mapHeight) +} + +// loadHeadSnapshot loads the last rendered map from the database and creates +// a snapshot. +func (f *FilterMaps) loadHeadSnapshot() error { + fm, err := f.getFilterMap(f.indexedRange.afterLastRenderedMap - 1) + if err != nil { + return fmt.Errorf("failed to load head snapshot map %d: %v", f.indexedRange.afterLastRenderedMap-1, err) + } + lastBlock, _, err := f.getLastBlockOfMap(f.indexedRange.afterLastRenderedMap - 1) + if err != nil { + return fmt.Errorf("failed to retrieve last block of head snapshot map %d: %v", f.indexedRange.afterLastRenderedMap-1, err) + } + var firstBlock uint64 + if f.indexedRange.afterLastRenderedMap > 1 { + prevLastBlock, _, err := f.getLastBlockOfMap(f.indexedRange.afterLastRenderedMap - 2) + if err != nil { + return fmt.Errorf("failed to retrieve last block of map %d before head snapshot: %v", f.indexedRange.afterLastRenderedMap-2, err) + } + firstBlock = prevLastBlock + 1 + } + lvPtrs := make([]uint64, lastBlock+1-firstBlock) + for i := range lvPtrs { + lvPtrs[i], err = f.getBlockLvPointer(firstBlock + uint64(i)) + if err != nil { + return fmt.Errorf("failed to retrieve log value pointer of head snapshot block %d: %v", firstBlock+uint64(i), err) + } + } + f.renderSnapshots.Add(f.indexedRange.afterLastIndexedBlock-1, &renderedMap{ + filterMap: fm, + mapIndex: f.indexedRange.afterLastRenderedMap - 1, + lastBlock: f.indexedRange.afterLastIndexedBlock - 1, + lastBlockId: f.indexedView.getBlockId(f.indexedRange.afterLastIndexedBlock - 1), + blockLvPtrs: lvPtrs, + finished: true, + headDelimiter: f.indexedRange.headBlockDelimiter, + }) + return nil +} + +// makeSnapshot creates a snapshot of the current state of the rendered map. +func (r *mapRenderer) makeSnapshot() { + r.f.renderSnapshots.Add(r.iterator.blockNumber, &renderedMap{ + filterMap: r.currentMap.filterMap.copy(), + mapIndex: r.currentMap.mapIndex, + lastBlock: r.iterator.blockNumber, + lastBlockId: r.f.targetView.getBlockId(r.currentMap.lastBlock), + blockLvPtrs: r.currentMap.blockLvPtrs, + finished: true, + headDelimiter: r.iterator.lvIndex, + }) +} + +// run does the actual map rendering. It periodically calls the stopCb callback +// and if it returns true the process is interrupted an can be resumed later +// by calling run again. The writeCb callback is called after new maps have +// been written to disk and the index range has been updated accordingly. +func (r *mapRenderer) run(stopCb func() bool, writeCb func()) (bool, error) { + for { + if done, err := r.renderCurrentMap(stopCb); !done { + return done, err // stopped or failed + } + // map finished + r.finishedMaps[r.currentMap.mapIndex] = r.currentMap + r.afterLastFinished++ + if len(r.finishedMaps) >= maxMapsPerBatch || r.afterLastFinished&(r.f.baseRowGroupLength-1) == 0 { + if err := r.writeFinishedMaps(stopCb); err != nil { + return false, err + } + writeCb() + } + if r.afterLastFinished == r.afterLastMap || r.iterator.finished { + if err := r.writeFinishedMaps(stopCb); err != nil { + return false, err + } + writeCb() + return true, nil + } + r.currentMap = &renderedMap{ + filterMap: r.f.emptyFilterMap(), + mapIndex: r.afterLastFinished, + } + } +} + +// renderCurrentMap renders a single map. +func (r *mapRenderer) renderCurrentMap(stopCb func() bool) (bool, error) { + if !r.iterator.updateChainView(r.f.targetView) { + return false, errChainUpdate + } + var waitCnt int + + if r.iterator.lvIndex == 0 { + r.currentMap.blockLvPtrs = []uint64{0} + } + type lvPos struct{ rowIndex, layerIndex uint32 } + rowMappingCache := lru.NewCache[common.Hash, lvPos](cachedRowMappings) + defer rowMappingCache.Purge() + + for r.iterator.lvIndex < uint64(r.currentMap.mapIndex+1)<= valuesPerCallback { + if stopCb() { + return false, nil + } + if !r.iterator.updateChainView(r.f.targetView) { + return false, errChainUpdate + } + waitCnt = 0 + } + r.currentMap.lastBlock = r.iterator.blockNumber + if r.iterator.delimiter { + r.currentMap.lastBlock++ + r.currentMap.blockLvPtrs = append(r.currentMap.blockLvPtrs, r.iterator.lvIndex+1) + } + if logValue := r.iterator.getValueHash(); logValue != (common.Hash{}) { + lvp, cached := rowMappingCache.Get(logValue) + if !cached { + lvp = lvPos{rowIndex: r.f.rowIndex(r.currentMap.mapIndex, 0, logValue)} + } + for uint32(len(r.currentMap.filterMap[lvp.rowIndex])) >= r.f.maxRowLength(lvp.layerIndex) { + lvp.layerIndex++ + lvp.rowIndex = r.f.rowIndex(r.currentMap.mapIndex, lvp.layerIndex, logValue) + cached = false + } + r.currentMap.filterMap[lvp.rowIndex] = append(r.currentMap.filterMap[lvp.rowIndex], r.f.columnIndex(r.iterator.lvIndex, &logValue)) + if !cached { + rowMappingCache.Add(logValue, lvp) + } + } + if err := r.iterator.next(); err != nil { + return false, fmt.Errorf("failed to advance log iterator at %d while rendering map %d: %v", r.iterator.lvIndex, r.currentMap.mapIndex, err) + } + if !r.f.testDisableSnapshots && r.afterLastMap >= r.f.indexedRange.afterLastRenderedMap && + (r.iterator.delimiter || r.iterator.finished) { + r.makeSnapshot() + } + } + if r.iterator.finished { + r.currentMap.finished = true + r.currentMap.headDelimiter = r.iterator.lvIndex + } + r.currentMap.lastBlockId = r.f.targetView.getBlockId(r.currentMap.lastBlock) + return true, nil +} + +// writeFinishedMaps writes rendered maps to the database and updates +// filterMapsRange and indexedView accordingly. +func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { + if len(r.finishedMaps) == 0 { + return nil + } + r.f.indexLock.Lock() + defer r.f.indexLock.Unlock() + + oldRange := r.f.indexedRange + tempRange, err := r.getTempRange() + if err != nil { + return fmt.Errorf("failed to get temporary rendered range: %v", err) + } + newRange, err := r.getUpdatedRange() + if err != nil { + return fmt.Errorf("failed to get updated rendered range: %v", err) + } + renderedView := r.f.targetView // stopCb callback might still change targetView while writing finished maps + + batch := r.f.db.NewBatch() + var writeCnt int + checkWriteCnt := func() { + writeCnt++ + if writeCnt == rowsPerBatch { + writeCnt = 0 + if err := batch.Write(); err != nil { + log.Crit("Error writing log index update batch", "error", err) + } + // do not exit while in partially written state but do allow processing + // events and pausing while block processing is in progress + pauseCb() + batch = r.f.db.NewBatch() + } + } + + r.f.setRange(batch, r.f.indexedView, tempRange) + // add or update filter rows + for rowIndex := uint32(0); rowIndex < r.f.mapHeight; rowIndex++ { + var ( + mapIndices []uint32 + rows []FilterRow + ) + for mapIndex := r.firstFinished; mapIndex < r.afterLastFinished; mapIndex++ { + row := r.finishedMaps[mapIndex].filterMap[rowIndex] + if fm, _ := r.f.filterMapCache.Get(mapIndex); fm != nil && row.Equal(fm[rowIndex]) { + continue + } + mapIndices = append(mapIndices, mapIndex) + rows = append(rows, row) + } + if newRange.afterLastRenderedMap == r.afterLastFinished { // head updated; remove future entries + for mapIndex := r.afterLastFinished; mapIndex < oldRange.afterLastRenderedMap; mapIndex++ { + if fm, _ := r.f.filterMapCache.Get(mapIndex); fm != nil && len(fm[rowIndex]) == 0 { + continue + } + mapIndices = append(mapIndices, mapIndex) + rows = append(rows, nil) + } + } + if err := r.f.storeFilterMapRows(batch, mapIndices, rowIndex, rows); err != nil { + return fmt.Errorf("failed to store filter maps %v row %d: %v", mapIndices, rowIndex, err) + } + checkWriteCnt() + } + // update filter map cache + if newRange.afterLastRenderedMap == r.afterLastFinished { + // head updated; cache new head maps and remove future entries + for mapIndex := r.firstFinished; mapIndex < r.afterLastFinished; mapIndex++ { + r.f.filterMapCache.Add(mapIndex, r.finishedMaps[mapIndex].filterMap) + } + for mapIndex := r.afterLastFinished; mapIndex < oldRange.afterLastRenderedMap; mapIndex++ { + r.f.filterMapCache.Remove(mapIndex) + } + } else { + // head not updated; do not cache maps during tail rendering because we + // need head maps to be available in the cache + for mapIndex := r.firstFinished; mapIndex < r.afterLastFinished; mapIndex++ { + r.f.filterMapCache.Remove(mapIndex) + } + } + // add or update block pointers + blockNumber := r.finishedMaps[r.firstFinished].firstBlock() + for mapIndex := r.firstFinished; mapIndex < r.afterLastFinished; mapIndex++ { + renderedMap := r.finishedMaps[mapIndex] + r.f.storeLastBlockOfMap(batch, mapIndex, renderedMap.lastBlock, renderedMap.lastBlockId) + checkWriteCnt() + if blockNumber != renderedMap.firstBlock() { + panic("non-continuous block numbers") + } + for _, lvPtr := range renderedMap.blockLvPtrs { + r.f.storeBlockLvPointer(batch, blockNumber, lvPtr) + checkWriteCnt() + blockNumber++ + } + } + if newRange.afterLastRenderedMap == r.afterLastFinished { // head updated; remove future entries + for mapIndex := r.afterLastFinished; mapIndex < oldRange.afterLastRenderedMap; mapIndex++ { + r.f.deleteLastBlockOfMap(batch, mapIndex) + checkWriteCnt() + } + for ; blockNumber < oldRange.afterLastIndexedBlock; blockNumber++ { + r.f.deleteBlockLvPointer(batch, blockNumber) + checkWriteCnt() + } + } + r.finishedMaps = make(map[uint32]*renderedMap) + r.firstFinished = r.afterLastFinished + r.f.setRange(batch, renderedView, newRange) + if err := batch.Write(); err != nil { + log.Crit("Error writing log index update batch", "error", err) + } + return nil +} + +// getTempRange returns a temporary filterMapsRange that is committed to the +// database while the newly rendered maps are partially written. Writing all +// processed maps in a single database batch would be a serious hit on db +// performance so instead safety is ensured by first reverting the valid map +// range to the unchanged region until all new map data is committed. +func (r *mapRenderer) getTempRange() (filterMapsRange, error) { + tempRange := r.f.indexedRange + if err := tempRange.addRenderedRange(r.firstFinished, r.firstFinished, r.afterLastMap, r.f.mapsPerEpoch); err != nil { + return filterMapsRange{}, fmt.Errorf("failed to update temporary rendered range: %v", err) + } + if tempRange.firstRenderedMap != r.f.indexedRange.firstRenderedMap { + // first rendered map changed; update first indexed block + if tempRange.firstRenderedMap > 0 { + lastBlock, _, err := r.f.getLastBlockOfMap(tempRange.firstRenderedMap - 1) + if err != nil { + return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d before temporary range: %v", tempRange.firstRenderedMap-1, err) + } + tempRange.firstIndexedBlock = lastBlock + 1 + } else { + tempRange.firstIndexedBlock = 0 + } + } + if tempRange.afterLastRenderedMap != r.f.indexedRange.afterLastRenderedMap { + // first rendered map changed; update first indexed block + if tempRange.afterLastRenderedMap > 0 { + lastBlock, _, err := r.f.getLastBlockOfMap(tempRange.afterLastRenderedMap - 1) + if err != nil { + return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d at the end of temporary range: %v", tempRange.afterLastRenderedMap-1, err) + } + tempRange.afterLastIndexedBlock = lastBlock + } else { + tempRange.afterLastIndexedBlock = 0 + } + tempRange.headBlockDelimiter = 0 + } + return tempRange, nil +} + +// getUpdatedRange returns the updated filterMapsRange after writing the newly +// rendered maps. +func (r *mapRenderer) getUpdatedRange() (filterMapsRange, error) { + // update filterMapsRange + newRange := r.f.indexedRange + if err := newRange.addRenderedRange(r.firstFinished, r.afterLastFinished, r.afterLastMap, r.f.mapsPerEpoch); err != nil { + return filterMapsRange{}, fmt.Errorf("failed to update rendered range: %v", err) + } + if newRange.firstRenderedMap != r.f.indexedRange.firstRenderedMap { + // first rendered map changed; update first indexed block + if newRange.firstRenderedMap > 0 { + lastBlock, _, err := r.f.getLastBlockOfMap(newRange.firstRenderedMap - 1) + if err != nil { + return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d before rendered range: %v", newRange.firstRenderedMap-1, err) + } + newRange.firstIndexedBlock = lastBlock + 1 + } else { + newRange.firstIndexedBlock = 0 + } + } + if newRange.afterLastRenderedMap == r.afterLastFinished { + // last rendered map changed; update last indexed block and head pointers + lm := r.finishedMaps[r.afterLastFinished-1] + newRange.headBlockIndexed = lm.finished + if lm.finished { + newRange.afterLastIndexedBlock = r.f.targetView.headNumber + 1 + if lm.lastBlock != r.f.targetView.headNumber { + panic("map rendering finished but last block != head block") + } + newRange.headBlockDelimiter = lm.headDelimiter + } else { + newRange.afterLastIndexedBlock = lm.lastBlock + newRange.headBlockDelimiter = 0 + } + } else { + // last rendered map not replaced; ensure that target chain view matches + // indexed chain view on the rendered section + if lastBlock := r.finishedMaps[r.afterLastFinished-1].lastBlock; !matchViews(r.f.indexedView, r.f.targetView, lastBlock) { + return filterMapsRange{}, errChainUpdate + } + } + return newRange, nil +} + +// addRenderedRange adds the range [firstRendered, afterLastRendered) and +// removes [afterLastRendered, afterLastRemoved) from the set of rendered maps. +func (fmr *filterMapsRange) addRenderedRange(firstRendered, afterLastRendered, afterLastRemoved, mapsPerEpoch uint32) error { + if !fmr.initialized { + return errors.New("log index not initialized") + } + + // Here we create a slice of endpoints for the rendered sections. There are two endpoints + // for each section: the index of the first map, and the index after the last map in the + // section. We then iterate the endpoints -- adding d values -- to determine whether the + // sections are contiguous or whether they have a gap. + type endpoint struct { + m uint32 + d int + } + endpoints := []endpoint{{fmr.firstRenderedMap, 1}, {fmr.afterLastRenderedMap, -1}, {firstRendered, 1}, {afterLastRendered, -101}, {afterLastRemoved, 100}} + if fmr.tailPartialEpoch > 0 { + endpoints = append(endpoints, []endpoint{{fmr.firstRenderedMap - mapsPerEpoch, 1}, {fmr.firstRenderedMap - mapsPerEpoch + fmr.tailPartialEpoch, -1}}...) + } + sort.Slice(endpoints, func(i, j int) bool { return endpoints[i].m < endpoints[j].m }) + var ( + sum int + merged []uint32 + last bool + ) + for i, e := range endpoints { + sum += e.d + if i < len(endpoints)-1 && endpoints[i+1].m == e.m { + continue + } + if (sum > 0) != last { + merged = append(merged, e.m) + last = !last + } + } + + switch len(merged) { + case 0: + // Initialized database, but no finished maps yet. + fmr.tailPartialEpoch = 0 + fmr.firstRenderedMap = firstRendered + fmr.afterLastRenderedMap = firstRendered + + case 2: + // One rendered section (no partial tail epoch). + fmr.tailPartialEpoch = 0 + fmr.firstRenderedMap = merged[0] + fmr.afterLastRenderedMap = merged[1] + + case 4: + // Two rendered sections (with a gap). + // First section (merged[0]-merged[1]) is for the partial tail epoch, + // and it has to start exactly one epoch before the main section. + if merged[2] != merged[0]+mapsPerEpoch { + return fmt.Errorf("invalid tail partial epoch: %v", merged) + } + fmr.tailPartialEpoch = merged[1] - merged[0] + fmr.firstRenderedMap = merged[2] + fmr.afterLastRenderedMap = merged[3] + + default: + return fmt.Errorf("invalid number of rendered sections: %v", merged) + } + return nil +} + +// logIterator iterates on the linear log value index range. +type logIterator struct { + chainView *ChainView + blockNumber uint64 + receipts types.Receipts + blockStart, delimiter, finished bool + txIndex, logIndex, topicIndex int + lvIndex uint64 +} + +var errUnindexedRange = errors.New("unindexed range") + +// newLogIteratorFromBlockDelimiter creates a logIterator starting at the +// given block's first log value entry (the block delimiter), according to the +// current targetView. +func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber uint64) (*logIterator, error) { + if blockNumber > f.targetView.headNumber { + return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", blockNumber, f.targetView.headNumber) + } + if blockNumber < f.indexedRange.firstIndexedBlock || blockNumber >= f.indexedRange.afterLastIndexedBlock { + return nil, errUnindexedRange + } + var lvIndex uint64 + if f.indexedRange.headBlockIndexed && blockNumber+1 == f.indexedRange.afterLastIndexedBlock { + lvIndex = f.indexedRange.headBlockDelimiter + } else { + var err error + lvIndex, err = f.getBlockLvPointer(blockNumber + 1) + if err != nil { + return nil, fmt.Errorf("failed to retrieve log value pointer of block %d after delimiter: %v", blockNumber+1, err) + } + lvIndex-- + } + finished := blockNumber == f.targetView.headNumber + return &logIterator{ + chainView: f.targetView, + blockNumber: blockNumber, + finished: finished, + delimiter: !finished, + lvIndex: lvIndex, + }, nil +} + +// newLogIteratorFromMapBoundary creates a logIterator starting at the given +// map boundary, according to the current targetView. +func (f *FilterMaps) newLogIteratorFromMapBoundary(mapIndex uint32, startBlock, startLvPtr uint64) (*logIterator, error) { + if startBlock > f.targetView.headNumber { + return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", startBlock, f.targetView.headNumber) + } + // get block receipts + receipts := f.targetView.getReceipts(startBlock) + if receipts == nil { + return nil, fmt.Errorf("receipts not found for start block %d", startBlock) + } + // initialize iterator at block start + l := &logIterator{ + chainView: f.targetView, + blockNumber: startBlock, + receipts: receipts, + blockStart: true, + lvIndex: startLvPtr, + } + l.nextValid() + targetIndex := uint64(mapIndex) << f.logValuesPerMap + if l.lvIndex > targetIndex { + return nil, fmt.Errorf("log value pointer %d of last block of map is after map boundary %d", l.lvIndex, targetIndex) + } + // iterate to map boundary + for l.lvIndex < targetIndex { + if l.finished { + return nil, fmt.Errorf("iterator already finished at %d before map boundary target %d", l.lvIndex, targetIndex) + } + if err := l.next(); err != nil { + return nil, fmt.Errorf("failed to advance log iterator at %d before map boundary target %d: %v", l.lvIndex, targetIndex, err) + } + } + return l, nil +} + +// updateChainView updates the iterator's chain view if it still matches the +// previous view at the current position. Returns true if successful. +func (l *logIterator) updateChainView(cv *ChainView) bool { + if !matchViews(cv, l.chainView, l.blockNumber) { + return false + } + l.chainView = cv + return true +} + +// getValueHash returns the log value hash at the current position. +func (l *logIterator) getValueHash() common.Hash { + if l.delimiter || l.finished { + return common.Hash{} + } + log := l.receipts[l.txIndex].Logs[l.logIndex] + if l.topicIndex == 0 { + return addressValue(log.Address) + } + return topicValue(log.Topics[l.topicIndex-1]) +} + +// next moves the iterator to the next log value index. +func (l *logIterator) next() error { + if l.finished { + return nil + } + if l.delimiter { + l.delimiter = false + l.blockNumber++ + l.receipts = l.chainView.getReceipts(l.blockNumber) + if l.receipts == nil { + return fmt.Errorf("receipts not found for block %d", l.blockNumber) + } + l.txIndex, l.logIndex, l.topicIndex, l.blockStart = 0, 0, 0, true + } else { + l.topicIndex++ + l.blockStart = false + } + l.lvIndex++ + l.nextValid() + return nil +} + +// nextValid updates the internal transaction, log and topic index pointers +// to the next existing log value of the given block if necessary. +// Note that nextValid does not advance the log value index pointer. +func (l *logIterator) nextValid() { + for ; l.txIndex < len(l.receipts); l.txIndex++ { + receipt := l.receipts[l.txIndex] + for ; l.logIndex < len(receipt.Logs); l.logIndex++ { + log := receipt.Logs[l.logIndex] + if l.topicIndex <= len(log.Topics) { + return + } + l.topicIndex = 0 + } + l.logIndex = 0 + } + if l.blockNumber == l.chainView.headNumber { + l.finished = true + } else { + l.delimiter = true + } +} diff --git a/core/filtermaps/matcher.go b/core/filtermaps/matcher.go new file mode 100644 index 0000000000..19acbd762a --- /dev/null +++ b/core/filtermaps/matcher.go @@ -0,0 +1,934 @@ +// 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 filtermaps + +import ( + "context" + "errors" + "fmt" + "math" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +const doRuntimeStats = false + +// ErrMatchAll is returned when the specified filter matches everything. +// Handling this case in filtermaps would require an extra special case and +// would actually be slower than reverting to legacy filter. +var ErrMatchAll = errors.New("match all patterns not supported") + +// MatcherBackend defines the functions required for searching in the log index +// data structure. It is currently implemented by FilterMapsMatcherBackend but +// once EIP-7745 is implemented and active, these functions can also be trustlessly +// served by a remote prover. +type MatcherBackend interface { + GetParams() *Params + GetBlockLvPointer(ctx context.Context, blockNumber uint64) (uint64, error) + GetFilterMapRow(ctx context.Context, mapIndex, rowIndex uint32, baseLayerOnly bool) (FilterRow, error) + GetLogByLvIndex(ctx context.Context, lvIndex uint64) (*types.Log, error) + SyncLogIndex(ctx context.Context) (SyncRange, error) + Close() +} + +// SyncRange is returned by MatcherBackend.SyncLogIndex. It contains the latest +// chain head, the indexed range that is currently consistent with the chain +// and the valid range that has not been changed and has been consistent with +// all states of the chain since the previous SyncLogIndex or the creation of +// the matcher backend. +type SyncRange struct { + HeadNumber uint64 + // block range where the index has not changed since the last matcher sync + // and therefore the set of matches found in this region is guaranteed to + // be valid and complete. + Valid bool + FirstValid, LastValid uint64 + // block range indexed according to the given chain head. + Indexed bool + FirstIndexed, LastIndexed uint64 +} + +// GetPotentialMatches returns a list of logs that are potential matches for the +// given filter criteria. If parts of the log index in the searched range are +// missing or changed during the search process then the resulting logs belonging +// to that block range might be missing or incorrect. +// Also note that the returned list may contain false positives. +func GetPotentialMatches(ctx context.Context, backend MatcherBackend, firstBlock, lastBlock uint64, addresses []common.Address, topics [][]common.Hash) ([]*types.Log, error) { + params := backend.GetParams() + var getLogStats runtimeStats + // find the log value index range to search + firstIndex, err := backend.GetBlockLvPointer(ctx, firstBlock) + if err != nil { + return nil, fmt.Errorf("failed to retrieve log value pointer for first block %d: %v", firstBlock, err) + } + lastIndex, err := backend.GetBlockLvPointer(ctx, lastBlock+1) + if err != nil { + return nil, fmt.Errorf("failed to retrieve log value pointer after last block %d: %v", lastBlock, err) + } + if lastIndex > 0 { + lastIndex-- + } + firstMap, lastMap := uint32(firstIndex>>params.logValuesPerMap), uint32(lastIndex>>params.logValuesPerMap) + firstEpoch, lastEpoch := firstMap>>params.logMapsPerEpoch, lastMap>>params.logMapsPerEpoch + + // build matcher according to the given filter criteria + matchers := make([]matcher, len(topics)+1) + // matchAddress signals a match when there is a match for any of the given + // addresses. + // If the list of addresses is empty then it creates a "wild card" matcher + // that signals every index as a potential match. + matchAddress := make(matchAny, len(addresses)) + for i, address := range addresses { + matchAddress[i] = &singleMatcher{backend: backend, value: addressValue(address)} + } + matchers[0] = matchAddress + for i, topicList := range topics { + // matchTopic signals a match when there is a match for any of the topics + // specified for the given position (topicList). + // If topicList is empty then it creates a "wild card" matcher that signals + // every index as a potential match. + matchTopic := make(matchAny, len(topicList)) + for j, topic := range topicList { + matchTopic[j] = &singleMatcher{backend: backend, value: topicValue(topic)} + } + matchers[i+1] = matchTopic + } + // matcher is the final sequence matcher that signals a match when all underlying + // matchers signal a match for consecutive log value indices. + matcher := newMatchSequence(params, matchers) + + // processEpoch returns the potentially matching logs from the given epoch. + processEpoch := func(epochIndex uint32) ([]*types.Log, error) { + var logs []*types.Log + // create a list of map indices to process + fm, lm := epochIndex< lastMap { + lm = lastMap + } + // + mapIndices := make([]uint32, lm+1-fm) + for i := range mapIndices { + mapIndices[i] = fm + uint32(i) + } + // find potential matches + matches, err := getAllMatches(ctx, matcher, mapIndices) + if err != nil { + return logs, err + } + // get the actual logs located at the matching log value indices + var st int + getLogStats.setState(&st, stGetLog) + defer getLogStats.setState(&st, stNone) + for _, m := range matches { + if m == nil { + return nil, ErrMatchAll + } + mlogs, err := getLogsFromMatches(ctx, backend, firstIndex, lastIndex, m) + if err != nil { + return logs, err + } + logs = append(logs, mlogs...) + } + getLogStats.addAmount(st, int64(len(logs))) + return logs, nil + } + + type task struct { + epochIndex uint32 + logs []*types.Log + err error + done chan struct{} + } + + taskCh := make(chan *task) + var wg sync.WaitGroup + defer func() { + close(taskCh) + wg.Wait() + }() + + worker := func() { + for task := range taskCh { + if task == nil { + break + } + task.logs, task.err = processEpoch(task.epochIndex) + close(task.done) + } + wg.Done() + } + + start := time.Now() + for i := 0; i < 4; i++ { + wg.Add(1) + go worker() + } + + var logs []*types.Log + // startEpoch is the next task to send whenever a worker can accept it. + // waitEpoch is the next task we are waiting for to finish in order to append + // results in the correct order. + startEpoch, waitEpoch := firstEpoch, firstEpoch + tasks := make(map[uint32]*task) + tasks[startEpoch] = &task{epochIndex: startEpoch, done: make(chan struct{})} + for waitEpoch <= lastEpoch { + select { + case taskCh <- tasks[startEpoch]: + startEpoch++ + if startEpoch <= lastEpoch { + if tasks[startEpoch] == nil { + tasks[startEpoch] = &task{epochIndex: startEpoch, done: make(chan struct{})} + } + } + case <-tasks[waitEpoch].done: + logs = append(logs, tasks[waitEpoch].logs...) + if err := tasks[waitEpoch].err; err != nil { + if err == ErrMatchAll { + return logs, err + } + return logs, fmt.Errorf("failed to process log index epoch %d: %v", waitEpoch, err) + } + delete(tasks, waitEpoch) + waitEpoch++ + if waitEpoch <= lastEpoch { + if tasks[waitEpoch] == nil { + tasks[waitEpoch] = &task{epochIndex: waitEpoch, done: make(chan struct{})} + } + } + } + } + if doRuntimeStats { + log.Info("Log search finished", "elapsed", time.Since(start)) + for i, ma := range matchers { + for j, m := range ma.(matchAny) { + log.Info("Single matcher stats", "matchSequence", i, "matchAny", j) + m.(*singleMatcher).stats.print() + } + } + log.Info("Get log stats") + getLogStats.print() + } + return logs, nil +} + +// getLogsFromMatches returns the list of potentially matching logs located at +// the given list of matching log indices. Matches outside the firstIndex to +// lastIndex range are not returned. +func getLogsFromMatches(ctx context.Context, backend MatcherBackend, firstIndex, lastIndex uint64, matches potentialMatches) ([]*types.Log, error) { + var logs []*types.Log + for _, match := range matches { + if match < firstIndex || match > lastIndex { + continue + } + log, err := backend.GetLogByLvIndex(ctx, match) + if err != nil { + return logs, fmt.Errorf("failed to retrieve log at index %d: %v", match, err) + } + if log != nil { + logs = append(logs, log) + } + } + return logs, nil +} + +// matcher defines a general abstraction for any matcher configuration that +// can instantiate a matcherInstance. +type matcher interface { + newInstance(mapIndices []uint32) matcherInstance +} + +// matcherInstance defines a general abstraction for a matcher configuration +// working on a specific set of map indices and eventually returning a list of +// potentially matching log value indices. +// Note that processing happens per mapping layer, each call returning a set +// of results for the maps where the processing has been finished at the given +// layer. Map indices can also be dropped before a result is returned for them +// in case the result is no longer interesting. Dropping indices twice or after +// a result has been returned has no effect. Exactly one matcherResult is +// returned per requested map index unless dropped. +type matcherInstance interface { + getMatchesForLayer(ctx context.Context, layerIndex uint32) ([]matcherResult, error) + dropIndices(mapIndices []uint32) +} + +// matcherResult contains the list of potentially matching log value indices +// for a given map index. +type matcherResult struct { + mapIndex uint32 + matches potentialMatches +} + +// getAllMatches creates an instance for a given matcher and set of map indices, +// iterates through mapping layers and collects all results, then returns all +// results in the same order as the map indices were specified. +func getAllMatches(ctx context.Context, matcher matcher, mapIndices []uint32) ([]potentialMatches, error) { + instance := matcher.newInstance(mapIndices) + resultsMap := make(map[uint32]potentialMatches) + for layerIndex := uint32(0); len(resultsMap) < len(mapIndices); layerIndex++ { + results, err := instance.getMatchesForLayer(ctx, layerIndex) + if err != nil { + return nil, err + } + for _, result := range results { + resultsMap[result.mapIndex] = result.matches + } + } + matches := make([]potentialMatches, len(mapIndices)) + for i, mapIndex := range mapIndices { + matches[i] = resultsMap[mapIndex] + } + return matches, nil +} + +// singleMatcher implements matcher by returning matches for a single log value hash. +type singleMatcher struct { + backend MatcherBackend + value common.Hash + stats runtimeStats +} + +// singleMatcherInstance is an instance of singleMatcher. +type singleMatcherInstance struct { + *singleMatcher + mapIndices []uint32 + filterRows map[uint32][]FilterRow +} + +// newInstance creates a new instance of singleMatcher. +func (m *singleMatcher) newInstance(mapIndices []uint32) matcherInstance { + filterRows := make(map[uint32][]FilterRow) + for _, idx := range mapIndices { + filterRows[idx] = []FilterRow{} + } + copiedIndices := make([]uint32, len(mapIndices)) + copy(copiedIndices, mapIndices) + return &singleMatcherInstance{ + singleMatcher: m, + mapIndices: copiedIndices, + filterRows: filterRows, + } +} + +// getMatchesForLayer implements matcherInstance. +func (m *singleMatcherInstance) getMatchesForLayer(ctx context.Context, layerIndex uint32) (results []matcherResult, err error) { + var st int + m.stats.setState(&st, stOther) + params := m.backend.GetParams() + maskedMapIndex, rowIndex := uint32(math.MaxUint32), uint32(0) + for _, mapIndex := range m.mapIndices { + filterRows, ok := m.filterRows[mapIndex] + if !ok { + continue + } + if mm := params.maskedMapIndex(mapIndex, layerIndex); mm != maskedMapIndex { + // only recalculate rowIndex when necessary + maskedMapIndex = mm + rowIndex = params.rowIndex(mapIndex, layerIndex, m.value) + } + if layerIndex == 0 { + m.stats.setState(&st, stFetchFirst) + } else { + m.stats.setState(&st, stFetchMore) + } + filterRow, err := m.backend.GetFilterMapRow(ctx, mapIndex, rowIndex, layerIndex == 0) + if err != nil { + m.stats.setState(&st, stNone) + return nil, fmt.Errorf("failed to retrieve filter map %d row %d: %v", mapIndex, rowIndex, err) + } + m.stats.addAmount(st, int64(len(filterRow))) + m.stats.setState(&st, stOther) + filterRows = append(filterRows, filterRow) + if uint32(len(filterRow)) < params.maxRowLength(layerIndex) { + m.stats.setState(&st, stProcess) + matches := params.potentialMatches(filterRows, mapIndex, m.value) + m.stats.addAmount(st, int64(len(matches))) + results = append(results, matcherResult{ + mapIndex: mapIndex, + matches: matches, + }) + m.stats.setState(&st, stOther) + delete(m.filterRows, mapIndex) + } else { + m.filterRows[mapIndex] = filterRows + } + } + m.cleanMapIndices() + m.stats.setState(&st, stNone) + return results, nil +} + +// dropIndices implements matcherInstance. +func (m *singleMatcherInstance) dropIndices(dropIndices []uint32) { + for _, mapIndex := range dropIndices { + delete(m.filterRows, mapIndex) + } + m.cleanMapIndices() +} + +// cleanMapIndices removes map indices from the list if there is no matching +// filterRows entry because a result has been returned or the index has been +// dropped. +func (m *singleMatcherInstance) cleanMapIndices() { + var j int + for i, mapIndex := range m.mapIndices { + if _, ok := m.filterRows[mapIndex]; ok { + if i != j { + m.mapIndices[j] = mapIndex + } + j++ + } + } + m.mapIndices = m.mapIndices[:j] +} + +// matchAny combinines a set of matchers and returns a match for every position +// where any of the underlying matchers signaled a match. A zero-length matchAny +// acts as a "wild card" that signals a potential match at every position. +type matchAny []matcher + +// matchAnyInstance is an instance of matchAny. +type matchAnyInstance struct { + matchAny + childInstances []matcherInstance + childResults map[uint32]matchAnyResults +} + +// matchAnyResults is used by matchAnyInstance to collect results from all +// child matchers for a specific map index. Once all results has been received +// a merged result is returned for the given map and this structure is discarded. +type matchAnyResults struct { + matches []potentialMatches + done []bool + needMore int +} + +// newInstance creates a new instance of matchAny. +func (m matchAny) newInstance(mapIndices []uint32) matcherInstance { + if len(m) == 1 { + return m[0].newInstance(mapIndices) + } + childResults := make(map[uint32]matchAnyResults) + for _, idx := range mapIndices { + childResults[idx] = matchAnyResults{ + matches: make([]potentialMatches, len(m)), + done: make([]bool, len(m)), + needMore: len(m), + } + } + childInstances := make([]matcherInstance, len(m)) + for i, matcher := range m { + childInstances[i] = matcher.newInstance(mapIndices) + } + return &matchAnyInstance{ + matchAny: m, + childInstances: childInstances, + childResults: childResults, + } +} + +// getMatchesForLayer implements matcherInstance. +func (m *matchAnyInstance) getMatchesForLayer(ctx context.Context, layerIndex uint32) (mergedResults []matcherResult, err error) { + if len(m.matchAny) == 0 { + // return "wild card" results (potentialMatches(nil) is interpreted as a + // potential match at every log value index of the map). + mergedResults = make([]matcherResult, len(m.childResults)) + var i int + for mapIndex := range m.childResults { + mergedResults[i] = matcherResult{mapIndex: mapIndex, matches: nil} + i++ + } + return mergedResults, nil + } + for i, childInstance := range m.childInstances { + results, err := childInstance.getMatchesForLayer(ctx, layerIndex) + if err != nil { + return nil, fmt.Errorf("failed to evaluate child matcher on layer %d: %v", layerIndex, err) + } + for _, result := range results { + mr, ok := m.childResults[result.mapIndex] + if !ok || mr.done[i] { + continue + } + mr.done[i] = true + mr.matches[i] = result.matches + mr.needMore-- + if mr.needMore == 0 || result.matches == nil { + mergedResults = append(mergedResults, matcherResult{ + mapIndex: result.mapIndex, + matches: mergeResults(mr.matches), + }) + delete(m.childResults, result.mapIndex) + } else { + m.childResults[result.mapIndex] = mr + } + } + } + return mergedResults, nil +} + +// dropIndices implements matcherInstance. +func (m *matchAnyInstance) dropIndices(dropIndices []uint32) { + for _, childInstance := range m.childInstances { + childInstance.dropIndices(dropIndices) + } + for _, mapIndex := range dropIndices { + delete(m.childResults, mapIndex) + } +} + +// mergeResults merges multiple lists of matches into a single one, preserving +// ascending order and filtering out any duplicates. +func mergeResults(results []potentialMatches) potentialMatches { + if len(results) == 0 { + return nil + } + var sumLen int + for _, res := range results { + if res == nil { + // nil is a wild card; all indices in map range are potential matches + return nil + } + sumLen += len(res) + } + merged := make(potentialMatches, 0, sumLen) + for { + best := -1 + for i, res := range results { + if len(res) == 0 { + continue + } + if best < 0 || res[0] < results[best][0] { + best = i + } + } + if best < 0 { + return merged + } + if len(merged) == 0 || results[best][0] > merged[len(merged)-1] { + merged = append(merged, results[best][0]) + } + results[best] = results[best][1:] + } +} + +// matchSequence combines two matchers, a "base" and a "next" matcher with a +// positive integer offset so that the resulting matcher signals a match at log +// value index X when the base matcher returns a match at X and the next matcher +// gives a match at X+offset. Note that matchSequence can be used recursively to +// detect any log value sequence. +type matchSequence struct { + params *Params + base, next matcher + offset uint64 + statsLock sync.Mutex + baseStats, nextStats matchOrderStats +} + +// newInstance creates a new instance of matchSequence. +func (m *matchSequence) newInstance(mapIndices []uint32) matcherInstance { + // determine set of indices to request from next matcher + nextIndices := make([]uint32, 0, len(mapIndices)*3/2) + needMatched := make(map[uint32]struct{}) + baseRequested := make(map[uint32]struct{}) + nextRequested := make(map[uint32]struct{}) + for _, mapIndex := range mapIndices { + needMatched[mapIndex] = struct{}{} + baseRequested[mapIndex] = struct{}{} + if _, ok := nextRequested[mapIndex]; !ok { + nextIndices = append(nextIndices, mapIndex) + nextRequested[mapIndex] = struct{}{} + } + nextIndices = append(nextIndices, mapIndex+1) + nextRequested[mapIndex+1] = struct{}{} + } + return &matchSequenceInstance{ + matchSequence: m, + baseInstance: m.base.newInstance(mapIndices), + nextInstance: m.next.newInstance(nextIndices), + needMatched: needMatched, + baseRequested: baseRequested, + nextRequested: nextRequested, + baseResults: make(map[uint32]potentialMatches), + nextResults: make(map[uint32]potentialMatches), + } +} + +// matchOrderStats collects statistics about the evaluating cost and the +// occurrence of empty result sets from both base and next child matchers. +// This allows the optimization of the evaluation order by evaluating the +// child first that is cheaper and/or gives empty results more often and not +// evaluating the other child in most cases. +// Note that matchOrderStats is specific to matchSequence and the results are +// carried over to future instances as the results are mostly useful when +// evaluating layer zero of each instance. For this reason it should be used +// in a thread safe way as is may be accessed from multiple worker goroutines. +type matchOrderStats struct { + totalCount, nonEmptyCount, totalCost uint64 +} + +// add collects statistics after a child has been evaluated for a certain layer. +func (ms *matchOrderStats) add(empty bool, layerIndex uint32) { + if empty && layerIndex != 0 { + // matchers may be evaluated for higher layers after all results have + // been returned. Also, empty results are not relevant when previous + // layers yielded matches already, so these cases can be ignored. + return + } + ms.totalCount++ + if !empty { + ms.nonEmptyCount++ + } + ms.totalCost += uint64(layerIndex + 1) +} + +// mergeStats merges two sets of matchOrderStats. +func (ms *matchOrderStats) mergeStats(add matchOrderStats) { + ms.totalCount += add.totalCount + ms.nonEmptyCount += add.nonEmptyCount + ms.totalCost += add.totalCost +} + +// baseFirst returns true if the base child matcher should be evaluated first. +func (m *matchSequence) baseFirst() bool { + m.statsLock.Lock() + bf := float64(m.baseStats.totalCost)*float64(m.nextStats.totalCount)+ + float64(m.baseStats.nonEmptyCount)*float64(m.nextStats.totalCost) < + float64(m.baseStats.totalCost)*float64(m.nextStats.nonEmptyCount)+ + float64(m.nextStats.totalCost)*float64(m.baseStats.totalCount) + m.statsLock.Unlock() + return bf +} + +// mergeBaseStats merges a set of matchOrderStats into the base matcher stats. +func (m *matchSequence) mergeBaseStats(stats matchOrderStats) { + m.statsLock.Lock() + m.baseStats.mergeStats(stats) + m.statsLock.Unlock() +} + +// mergeNextStats merges a set of matchOrderStats into the next matcher stats. +func (m *matchSequence) mergeNextStats(stats matchOrderStats) { + m.statsLock.Lock() + m.nextStats.mergeStats(stats) + m.statsLock.Unlock() +} + +// newMatchSequence creates a recursive sequence matcher from a list of underlying +// matchers. The resulting matcher signals a match at log value index X when each +// underlying matcher matchers[i] returns a match at X+i. +func newMatchSequence(params *Params, matchers []matcher) matcher { + if len(matchers) == 0 { + panic("zero length sequence matchers are not allowed") + } + if len(matchers) == 1 { + return matchers[0] + } + return &matchSequence{ + params: params, + base: newMatchSequence(params, matchers[:len(matchers)-1]), + next: matchers[len(matchers)-1], + offset: uint64(len(matchers) - 1), + } +} + +// matchSequenceInstance is an instance of matchSequence. +type matchSequenceInstance struct { + *matchSequence + baseInstance, nextInstance matcherInstance + baseRequested, nextRequested, needMatched map[uint32]struct{} + baseResults, nextResults map[uint32]potentialMatches +} + +// getMatchesForLayer implements matcherInstance. +func (m *matchSequenceInstance) getMatchesForLayer(ctx context.Context, layerIndex uint32) (matchedResults []matcherResult, err error) { + // decide whether to evaluate base or next matcher first + baseFirst := m.baseFirst() + if baseFirst { + if err := m.evalBase(ctx, layerIndex); err != nil { + return nil, err + } + } + if err := m.evalNext(ctx, layerIndex); err != nil { + return nil, err + } + if !baseFirst { + if err := m.evalBase(ctx, layerIndex); err != nil { + return nil, err + } + } + // evaluate and return matched results where possible + for mapIndex := range m.needMatched { + if _, ok := m.baseRequested[mapIndex]; ok { + continue + } + if _, ok := m.nextRequested[mapIndex]; ok { + continue + } + if _, ok := m.nextRequested[mapIndex+1]; ok { + continue + } + matchedResults = append(matchedResults, matcherResult{ + mapIndex: mapIndex, + matches: m.params.matchResults(mapIndex, m.offset, m.baseResults[mapIndex], m.nextResults[mapIndex], m.nextResults[mapIndex+1]), + }) + delete(m.needMatched, mapIndex) + } + return matchedResults, nil +} + +// dropIndices implements matcherInstance. +func (m *matchSequenceInstance) dropIndices(dropIndices []uint32) { + for _, mapIndex := range dropIndices { + delete(m.needMatched, mapIndex) + } + var dropBase, dropNext []uint32 + for _, mapIndex := range dropIndices { + if m.dropBase(mapIndex) { + dropBase = append(dropBase, mapIndex) + } + } + m.baseInstance.dropIndices(dropBase) + for _, mapIndex := range dropIndices { + if m.dropNext(mapIndex) { + dropNext = append(dropNext, mapIndex) + } + if m.dropNext(mapIndex + 1) { + dropNext = append(dropNext, mapIndex+1) + } + } + m.nextInstance.dropIndices(dropNext) +} + +// evalBase evaluates the base child matcher and drops map indices from the +// next matcher if possible. +func (m *matchSequenceInstance) evalBase(ctx context.Context, layerIndex uint32) error { + results, err := m.baseInstance.getMatchesForLayer(ctx, layerIndex) + if err != nil { + return fmt.Errorf("failed to evaluate base matcher on layer %d: %v", layerIndex, err) + } + var ( + dropIndices []uint32 + stats matchOrderStats + ) + for _, r := range results { + m.baseResults[r.mapIndex] = r.matches + delete(m.baseRequested, r.mapIndex) + stats.add(r.matches != nil && len(r.matches) == 0, layerIndex) + } + m.mergeBaseStats(stats) + for _, r := range results { + if m.dropNext(r.mapIndex) { + dropIndices = append(dropIndices, r.mapIndex) + } + if m.dropNext(r.mapIndex + 1) { + dropIndices = append(dropIndices, r.mapIndex+1) + } + } + if len(dropIndices) > 0 { + m.nextInstance.dropIndices(dropIndices) + } + return nil +} + +// evalNext evaluates the next child matcher and drops map indices from the +// base matcher if possible. +func (m *matchSequenceInstance) evalNext(ctx context.Context, layerIndex uint32) error { + results, err := m.nextInstance.getMatchesForLayer(ctx, layerIndex) + if err != nil { + return fmt.Errorf("failed to evaluate next matcher on layer %d: %v", layerIndex, err) + } + var ( + dropIndices []uint32 + stats matchOrderStats + ) + for _, r := range results { + m.nextResults[r.mapIndex] = r.matches + delete(m.nextRequested, r.mapIndex) + stats.add(r.matches != nil && len(r.matches) == 0, layerIndex) + } + m.mergeNextStats(stats) + for _, r := range results { + if r.mapIndex > 0 && m.dropBase(r.mapIndex-1) { + dropIndices = append(dropIndices, r.mapIndex-1) + } + if m.dropBase(r.mapIndex) { + dropIndices = append(dropIndices, r.mapIndex) + } + } + if len(dropIndices) > 0 { + m.baseInstance.dropIndices(dropIndices) + } + return nil +} + +// dropBase checks whether the given map index can be dropped from the base +// matcher based on the known results from the next matcher and removes it +// from the internal requested set and returns true if possible. +func (m *matchSequenceInstance) dropBase(mapIndex uint32) bool { + if _, ok := m.baseRequested[mapIndex]; !ok { + return false + } + if _, ok := m.needMatched[mapIndex]; ok { + if next := m.nextResults[mapIndex]; next == nil || + (len(next) > 0 && next[len(next)-1] >= (uint64(mapIndex)< 0 && nextNext[0] < (uint64(mapIndex+1)< 0 && prevBase[len(prevBase)-1]+m.offset >= (uint64(mapIndex)< 0 && base[0]+m.offset < (uint64(mapIndex+1)< 0 { + // discard items from nextRes whose corresponding base matcher results + // with the negative offset applied would be located at mapIndex-1. + start := 0 + for start < len(nextRes) && nextRes[start] < uint64(mapIndex)< 0 { + // discard items from nextNextRes whose corresponding base matcher results + // with the negative offset applied would still be located at mapIndex+1. + stop := 0 + for stop < len(nextNextRes) && nextNextRes[stop] < uint64(mapIndex+1)< 0 && len(baseRes) > 0 { + if nextRes[0] > baseRes[0]+offset { + baseRes = baseRes[1:] + } else if nextRes[0] < baseRes[0]+offset { + nextRes = nextRes[1:] + } else { + matchedRes = append(matchedRes, baseRes[0]) + baseRes = baseRes[1:] + nextRes = nextRes[1:] + } + } + } else { + // baseRes is a wild card so just return next matcher results with + // negative offset. + for len(nextRes) > 0 { + matchedRes = append(matchedRes, nextRes[0]-offset) + nextRes = nextRes[1:] + } + } + } + return matchedRes +} + +// runtimeStats collects processing time statistics while searching in the log +// index. Used only when the doRuntimeStats global flag is true. +type runtimeStats struct { + dt, cnt, amount [stCount]int64 +} + +const ( + stNone = iota + stFetchFirst + stFetchMore + stProcess + stGetLog + stOther + stCount +) + +var stNames = []string{"", "fetchFirst", "fetchMore", "process", "getLog", "other"} + +// set sets the processing state to one of the pre-defined constants. +// Processing time spent in each state is measured separately. +func (ts *runtimeStats) setState(state *int, newState int) { + if !doRuntimeStats || newState == *state { + return + } + now := int64(mclock.Now()) + atomic.AddInt64(&ts.dt[*state], now) + atomic.AddInt64(&ts.dt[newState], -now) + atomic.AddInt64(&ts.cnt[newState], 1) + *state = newState +} + +func (ts *runtimeStats) addAmount(state int, amount int64) { + atomic.AddInt64(&ts.amount[state], amount) +} + +// print prints the collected statistics. +func (ts *runtimeStats) print() { + for i := 1; i < stCount; i++ { + log.Info("Matcher stats", "name", stNames[i], "dt", time.Duration(ts.dt[i]), "count", ts.cnt[i], "amount", ts.amount[i]) + } +} diff --git a/core/filtermaps/matcher_backend.go b/core/filtermaps/matcher_backend.go new file mode 100644 index 0000000000..66f95f2145 --- /dev/null +++ b/core/filtermaps/matcher_backend.go @@ -0,0 +1,206 @@ +// 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 filtermaps + +import ( + "context" + + "github.com/ethereum/go-ethereum/core/types" +) + +// FilterMapsMatcherBackend implements MatcherBackend. +type FilterMapsMatcherBackend struct { + f *FilterMaps + + // these fields should be accessed under f.matchersLock mutex. + valid bool + firstValid, lastValid uint64 + syncCh chan SyncRange +} + +// NewMatcherBackend returns a FilterMapsMatcherBackend after registering it in +// the active matcher set. +// Note that Close should always be called when the matcher is no longer used. +func (f *FilterMaps) NewMatcherBackend() *FilterMapsMatcherBackend { + f.indexLock.RLock() + f.matchersLock.Lock() + defer func() { + f.matchersLock.Unlock() + f.indexLock.RUnlock() + }() + + fm := &FilterMapsMatcherBackend{ + f: f, + valid: f.indexedRange.initialized && f.indexedRange.afterLastIndexedBlock > f.indexedRange.firstIndexedBlock, + firstValid: f.indexedRange.firstIndexedBlock, + lastValid: f.indexedRange.afterLastIndexedBlock - 1, + } + f.matchers[fm] = struct{}{} + return fm +} + +// GetParams returns the filtermaps parameters. +// GetParams implements MatcherBackend. +func (fm *FilterMapsMatcherBackend) GetParams() *Params { + return &fm.f.Params +} + +// Close removes the matcher from the set of active matchers and ensures that +// any SyncLogIndex calls are cancelled. +// Close implements MatcherBackend. +func (fm *FilterMapsMatcherBackend) Close() { + fm.f.matchersLock.Lock() + defer fm.f.matchersLock.Unlock() + + delete(fm.f.matchers, fm) +} + +// GetFilterMapRow returns the given row of the given map. If the row is empty +// then a non-nil zero length row is returned. If baseLayerOnly is true then +// only the first baseRowLength entries of the row are guaranteed to be +// returned. +// Note that the returned slices should not be modified, they should be copied +// on write. +// GetFilterMapRow implements MatcherBackend. +func (fm *FilterMapsMatcherBackend) GetFilterMapRow(ctx context.Context, mapIndex, rowIndex uint32, baseLayerOnly bool) (FilterRow, error) { + return fm.f.getFilterMapRow(mapIndex, rowIndex, baseLayerOnly) +} + +// GetBlockLvPointer returns the starting log value index where the log values +// generated by the given block are located. If blockNumber is beyond the current +// head then the first unoccupied log value index is returned. +// GetBlockLvPointer implements MatcherBackend. +func (fm *FilterMapsMatcherBackend) GetBlockLvPointer(ctx context.Context, blockNumber uint64) (uint64, error) { + fm.f.indexLock.RLock() + defer fm.f.indexLock.RUnlock() + + return fm.f.getBlockLvPointer(blockNumber) +} + +// GetLogByLvIndex returns the log at the given log value index. +// Note that this function assumes that the log index structure is consistent +// with the canonical chain at the point where the given log value index points. +// If this is not the case then an invalid result may be returned or certain +// logs might not be returned at all. +// No error is returned though because of an inconsistency between the chain and +// the log index. It is the caller's responsibility to verify this consistency +// using SyncLogIndex and re-process certain blocks if necessary. +// GetLogByLvIndex implements MatcherBackend. +func (fm *FilterMapsMatcherBackend) GetLogByLvIndex(ctx context.Context, lvIndex uint64) (*types.Log, error) { + fm.f.indexLock.RLock() + defer fm.f.indexLock.RUnlock() + + return fm.f.getLogByLvIndex(lvIndex) +} + +// synced signals to the matcher that has triggered a synchronisation that it +// has been finished and the log index is consistent with the chain head passed +// as a parameter. +// Note that if the log index head was far behind the chain head then it might not +// be synced up to the given head in a single step. Still, the latest chain head +// should be passed as a parameter and the existing log index should be consistent +// with that chain. +func (fm *FilterMapsMatcherBackend) synced() { + fm.f.indexLock.RLock() + fm.f.matchersLock.Lock() + defer func() { + fm.f.matchersLock.Unlock() + fm.f.indexLock.RUnlock() + }() + + var ( + indexed bool + lastIndexed, subLastIndexed uint64 + ) + if !fm.f.indexedRange.headBlockIndexed { + subLastIndexed = 1 + } + if fm.f.indexedRange.afterLastIndexedBlock-subLastIndexed > fm.f.indexedRange.firstIndexedBlock { + indexed, lastIndexed = true, fm.f.indexedRange.afterLastIndexedBlock-subLastIndexed-1 + } + fm.syncCh <- SyncRange{ + HeadNumber: fm.f.indexedView.headNumber, + Valid: fm.valid, + FirstValid: fm.firstValid, + LastValid: fm.lastValid, + Indexed: indexed, + FirstIndexed: fm.f.indexedRange.firstIndexedBlock, + LastIndexed: lastIndexed, + } + fm.valid = indexed + fm.firstValid = fm.f.indexedRange.firstIndexedBlock + fm.lastValid = lastIndexed + fm.syncCh = nil +} + +// SyncLogIndex ensures that the log index is consistent with the current state +// of the chain and is synced up to the current head. It blocks until this state +// is achieved or the context is cancelled. +// If successful, it returns a SyncRange that contains the latest chain head, +// the indexed range that is currently consistent with the chain and the valid +// range that has not been changed and has been consistent with all states of the +// chain since the previous SyncLogIndex or the creation of the matcher backend. +func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange, error) { + if fm.f.disabled { + return SyncRange{HeadNumber: fm.f.targetView.headNumber}, nil + } + + syncCh := make(chan SyncRange, 1) + fm.f.matchersLock.Lock() + fm.syncCh = syncCh + fm.f.matchersLock.Unlock() + + select { + case fm.f.matcherSyncCh <- fm: + case <-ctx.Done(): + return SyncRange{}, ctx.Err() + } + select { + case vr := <-syncCh: + return vr, nil + case <-ctx.Done(): + return SyncRange{}, ctx.Err() + } +} + +// updateMatchersValidRange iterates through active matchers and limits their +// valid range with the current indexed range. This function should be called +// whenever a part of the log index has been removed, before adding new blocks +// to it. +// Note that this function assumes that the index read lock is being held. +func (f *FilterMaps) updateMatchersValidRange() { + f.matchersLock.Lock() + defer f.matchersLock.Unlock() + + for fm := range f.matchers { + if !f.indexedRange.hasIndexedBlocks() { + fm.valid = false + } + if !fm.valid { + continue + } + if fm.firstValid < f.indexedRange.firstIndexedBlock { + fm.firstValid = f.indexedRange.firstIndexedBlock + } + if fm.lastValid >= f.indexedRange.afterLastIndexedBlock { + fm.lastValid = f.indexedRange.afterLastIndexedBlock - 1 + } + if fm.firstValid > fm.lastValid { + fm.valid = false + } + } +} diff --git a/core/filtermaps/matcher_test.go b/core/filtermaps/matcher_test.go new file mode 100644 index 0000000000..5a49ce66ec --- /dev/null +++ b/core/filtermaps/matcher_test.go @@ -0,0 +1,87 @@ +// 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 filtermaps + +import ( + "context" + crand "crypto/rand" + "math/rand" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +func TestMatcher(t *testing.T) { + ts := newTestSetup(t) + defer ts.close() + + ts.chain.addBlocks(100, 10, 10, 4, true) + ts.setHistory(0, false) + ts.fm.WaitIdle() + + for i := 0; i < 2000; i++ { + bhash := ts.chain.canonical[rand.Intn(len(ts.chain.canonical))] + receipts := ts.chain.receipts[bhash] + if len(receipts) == 0 { + continue + } + receipt := receipts[rand.Intn(len(receipts))] + if len(receipt.Logs) == 0 { + continue + } + log := receipt.Logs[rand.Intn(len(receipt.Logs))] + var ok bool + addresses := make([]common.Address, rand.Intn(3)) + for i := range addresses { + crand.Read(addresses[i][:]) + } + if len(addresses) > 0 { + addresses[rand.Intn(len(addresses))] = log.Address + ok = true + } + topics := make([][]common.Hash, rand.Intn(len(log.Topics)+1)) + for j := range topics { + topics[j] = make([]common.Hash, rand.Intn(3)) + for i := range topics[j] { + crand.Read(topics[j][i][:]) + } + if len(topics[j]) > 0 { + topics[j][rand.Intn(len(topics[j]))] = log.Topics[j] + ok = true + } + } + if !ok { + continue // cannot search for match-all pattern + } + mb := ts.fm.NewMatcherBackend() + logs, err := GetPotentialMatches(context.Background(), mb, 0, 1000, addresses, topics) + mb.Close() + if err != nil { + t.Fatalf("Log search error: %v", err) + } + var found bool + for _, l := range logs { + if l == log { + found = true + break + } + } + if !found { + t.Fatalf("Log search did not return expected log (addresses: %v, topics: %v, expected log: %v)", addresses, topics, *log) + } + } +} diff --git a/core/filtermaps/math.go b/core/filtermaps/math.go new file mode 100644 index 0000000000..762a99be9e --- /dev/null +++ b/core/filtermaps/math.go @@ -0,0 +1,212 @@ +// 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 filtermaps + +import ( + "crypto/sha256" + "encoding/binary" + "hash/fnv" + "math" + "sort" + + "github.com/ethereum/go-ethereum/common" +) + +// Params defines the basic parameters of the log index structure. +type Params struct { + logMapHeight uint // log2(mapHeight) + logMapWidth uint // log2(mapWidth) + logMapsPerEpoch uint // log2(mapsPerEpoch) + logValuesPerMap uint // log2(logValuesPerMap) + baseRowLengthRatio uint // baseRowLength / average row length + logLayerDiff uint // maxRowLength log2 growth per layer + // derived fields + mapHeight uint32 // filter map height (number of rows) + mapsPerEpoch uint32 // number of maps in an epoch + baseRowLength uint32 // maximum number of log values per row on layer 0 + valuesPerMap uint64 // number of log values marked on each filter map + // not affecting consensus + baseRowGroupLength uint32 // length of base row groups in local database +} + +// DefaultParams is the set of parameters used on mainnet. +var DefaultParams = Params{ + logMapHeight: 16, + logMapWidth: 24, + logMapsPerEpoch: 10, + logValuesPerMap: 16, + baseRowGroupLength: 32, + baseRowLengthRatio: 8, + logLayerDiff: 4, +} + +// RangeTestParams puts one log value per epoch, ensuring block exact tail unindexing for testing +var RangeTestParams = Params{ + logMapHeight: 4, + logMapWidth: 24, + logMapsPerEpoch: 0, + logValuesPerMap: 0, + baseRowGroupLength: 32, + baseRowLengthRatio: 16, // baseRowLength >= 1 + logLayerDiff: 4, +} + +// deriveFields calculates the derived fields of the parameter set. +func (p *Params) deriveFields() { + p.mapHeight = uint32(1) << p.logMapHeight + p.mapsPerEpoch = uint32(1) << p.logMapsPerEpoch + p.valuesPerMap = uint64(1) << p.logValuesPerMap + p.baseRowLength = uint32(p.valuesPerMap * uint64(p.baseRowLengthRatio) / uint64(p.mapHeight)) +} + +// addressValue returns the log value hash of a log emitting address. +func addressValue(address common.Address) common.Hash { + var result common.Hash + hasher := sha256.New() + hasher.Write(address[:]) + hasher.Sum(result[:0]) + return result +} + +// topicValue returns the log value hash of a log topic. +func topicValue(topic common.Hash) common.Hash { + var result common.Hash + hasher := sha256.New() + hasher.Write(topic[:]) + hasher.Sum(result[:0]) + return result +} + +// rowIndex returns the row index in which the given log value should be marked +// on the given map and mapping layer. Note that row assignments are re-shuffled +// with a different frequency on each mapping layer, allowing efficient disk +// access and Merkle proofs for long sections of short rows on lower order +// layers while avoiding putting too many heavy rows next to each other on +// higher order layers. +func (p *Params) rowIndex(mapIndex, layerIndex uint32, logValue common.Hash) uint32 { + hasher := sha256.New() + hasher.Write(logValue[:]) + var indexEnc [8]byte + binary.LittleEndian.PutUint32(indexEnc[0:4], p.maskedMapIndex(mapIndex, layerIndex)) + binary.LittleEndian.PutUint32(indexEnc[4:8], layerIndex) + hasher.Write(indexEnc[:]) + var hash common.Hash + hasher.Sum(hash[:0]) + return binary.LittleEndian.Uint32(hash[:4]) % p.mapHeight +} + +// columnIndex returns the column index where the given log value at the given +// position should be marked. +func (p *Params) columnIndex(lvIndex uint64, logValue *common.Hash) uint32 { + var indexEnc [8]byte + binary.LittleEndian.PutUint64(indexEnc[:], lvIndex) + // Note: reusing the hasher brings practically no performance gain and would + // require passing it through the entire matcher logic because of multi-thread + // matching + hasher := fnv.New64a() + hasher.Write(indexEnc[:]) + hasher.Write(logValue[:]) + hash := hasher.Sum64() + hashBits := p.logMapWidth - p.logValuesPerMap + return uint32(lvIndex%p.valuesPerMap)<>(64-hashBits)) ^ uint32(hash)>>(32-hashBits)) +} + +// maxRowLength returns the maximum length filter rows are populated up to +// when using the given mapping layer. A log value can be marked on the map +// according to a given mapping layer if the row mapping on that layer points +// to a row that has not yet reached the maxRowLength belonging to that layer. +// This means that a row that is considered full on a given layer may still be +// extended further on a higher order layer. +// Each value is marked on the lowest order layer possible, assuming that marks +// are added in ascending log value index order. +// When searching for a log value one should consider all layers and process +// corresponding rows up until the first one where the row mapped to the given +// layer is not full. +func (p *Params) maxRowLength(layerIndex uint32) uint32 { + logLayerDiff := uint(layerIndex) * p.logLayerDiff + if logLayerDiff > p.logMapsPerEpoch { + logLayerDiff = p.logMapsPerEpoch + } + return p.baseRowLength << logLayerDiff +} + +// maskedMapIndex returns the index used for row mapping calculation on the +// given layer. On layer zero the mapping changes once per epoch, then the +// frequency of re-mapping increases with every new layer until it reaches +// the frequency where it is different for every mapIndex. +func (p *Params) maskedMapIndex(mapIndex, layerIndex uint32) uint32 { + logLayerDiff := uint(layerIndex) * p.logLayerDiff + if logLayerDiff > p.logMapsPerEpoch { + logLayerDiff = p.logMapsPerEpoch + } + return mapIndex & (uint32(math.MaxUint32) << (p.logMapsPerEpoch - logLayerDiff)) +} + +// potentialMatches returns the list of log value indices potentially matching +// the given log value hash in the range of the filter map the row belongs to. +// Note that the list of indices is always sorted and potential duplicates are +// removed. Though the column indices are stored in the same order they were +// added and therefore the true matches are automatically reverse transformed +// in the right order, false positives can ruin this property. Since these can +// only be separated from true matches after the combined pattern matching of the +// outputs of individual log value matchers and this pattern matcher assumes a +// sorted and duplicate-free list of indices, we should ensure these properties +// here. +func (p *Params) potentialMatches(rows []FilterRow, mapIndex uint32, logValue common.Hash) potentialMatches { + results := make(potentialMatches, 0, 8) + mapFirst := uint64(mapIndex) << p.logValuesPerMap + for i, row := range rows { + rowLen, maxLen := len(row), int(p.maxRowLength(uint32(i))) + if rowLen > maxLen { + rowLen = maxLen // any additional entries are generated by another log value on a higher mapping layer + } + for i := 0; i < rowLen; i++ { + if potentialMatch := mapFirst + uint64(row[i]>>(p.logMapWidth-p.logValuesPerMap)); row[i] == p.columnIndex(potentialMatch, &logValue) { + results = append(results, potentialMatch) + } + } + if rowLen < maxLen { + break + } + if i == len(rows)-1 { + panic("potentialMatches: insufficient list of row alternatives") + } + } + sort.Sort(results) + // remove duplicates + j := 0 + for i, match := range results { + if i == 0 || match != results[i-1] { + results[j] = results[i] + j++ + } + } + return results[:j] +} + +// potentialMatches is a strictly monotonically increasing list of log value +// indices in the range of a filter map that are potential matches for certain +// filter criteria. +// potentialMatches implements sort.Interface. +// Note that nil is used as a wildcard and therefore means that all log value +// indices in the filter map range are potential matches. If there are no +// potential matches in the given map's range then an empty slice should be used. +type potentialMatches []uint64 + +func (p potentialMatches) Len() int { return len(p) } +func (p potentialMatches) Less(i, j int) bool { return p[i] < p[j] } +func (p potentialMatches) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/core/filtermaps/math_test.go b/core/filtermaps/math_test.go new file mode 100644 index 0000000000..a4c1609059 --- /dev/null +++ b/core/filtermaps/math_test.go @@ -0,0 +1,149 @@ +// 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 filtermaps + +import ( + crand "crypto/rand" + "math/rand" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +func TestSingleMatch(t *testing.T) { + params := DefaultParams + params.deriveFields() + + for count := 0; count < 100000; count++ { + // generate a row with a single random entry + mapIndex := rand.Uint32() + lvIndex := uint64(mapIndex)< 0; i-- { + j := rand.Intn(i) + row[i], row[j] = row[j], row[i] + } + // split up into a list of rows if longer than allowed + var rows []FilterRow + for layerIndex := uint32(0); row != nil; layerIndex++ { + maxLen := int(params.maxRowLength(layerIndex)) + if len(row) > maxLen { + rows = append(rows, row[:maxLen]) + row = row[maxLen:] + } else { + rows = append(rows, row) + row = nil + } + } + // check retrieved matches while also counting false positives + for i, lvHash := range lvHashes { + matches := params.potentialMatches(rows, mapIndex, lvHash) + if i < testPmLen { + // check single entry match + if len(matches) < 1 { + t.Fatalf("Invalid length of matches (got %d, expected >=1)", len(matches)) + } + var found bool + for _, lvi := range matches { + if lvi == lvIndices[i] { + found = true + } else { + falsePositives++ + } + } + if !found { + t.Fatalf("Expected match not found (got %v, expected %d)", matches, lvIndices[i]) + } + } else { + // check "long series" match + if len(matches) < testPmLen { + t.Fatalf("Invalid length of matches (got %d, expected >=%d)", len(matches), testPmLen) + } + // since results are ordered, first testPmLen entries should always match exactly + for j := 0; j < testPmLen; j++ { + if matches[j] != lvStart+uint64(j) { + t.Fatalf("Incorrect match at index %d (got %d, expected %d)", j, matches[j], lvStart+uint64(j)) + } + } + // the rest are false positives + falsePositives += len(matches) - testPmLen + } + } + } + // Whenever looking for a certain log value hash, each entry in the row that + // was generated by another log value hash (a "foreign entry") has a + // valuesPerMap // 2^32 chance of yielding a false positive if the reverse + // transformed 32 bit integer is by random chance less than valuesPerMap and + // is therefore considered a potentially valid match. + // We have testPmLen unique hash entries and a testPmLen long series of entries + // for the same hash. For each of the testPmLen unique hash entries there are + // testPmLen*2-1 foreign entries while for the long series there are testPmLen + // foreign entries. This means that after performing all these filtering runs, + // we have processed 2*testPmLen^2 foreign entries, which given us an estimate + // of how many false positives to expect. + expFalse := int(uint64(testPmCount*testPmLen*testPmLen*2) * params.valuesPerMap >> params.logMapWidth) + if falsePositives < expFalse/2 || falsePositives > expFalse*3/2 { + t.Fatalf("False positive rate out of expected range (got %d, expected %d +-50%%)", falsePositives, expFalse) + } +} diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index 4f2ef0a880..f679c3aeb3 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -18,6 +18,8 @@ package rawdb import ( "bytes" + "encoding/binary" + "errors" "math/big" "github.com/ethereum/go-ethereum/common" @@ -179,3 +181,306 @@ func DeleteBloombits(db ethdb.Database, bit uint, from uint64, to uint64) { log.Crit("Failed to delete bloom bits", "err", it.Error()) } } + +// ReadFilterMapRow retrieves a filter map row at the given mapRowIndex +// (see filtermaps.mapRowIndex for the storage index encoding). +// Note that zero length rows are not stored in the database and therefore all +// non-existent entries are interpreted as empty rows and return no error. +// Also note that the mapRowIndex indexing scheme is the same as the one +// proposed in EIP-7745 for tree-hashing the filter map structure and for the +// same data proximity reasons it is also suitable for database representation. +// See also: +// https://eips.ethereum.org/EIPS/eip-7745#hash-tree-structure +func ReadFilterMapExtRow(db ethdb.KeyValueReader, mapRowIndex uint64, bitLength uint) ([]uint32, error) { + byteLength := int(bitLength) / 8 + if int(bitLength) != byteLength*8 { + panic("invalid bit length") + } + key := filterMapRowKey(mapRowIndex, false) + has, err := db.Has(key) + if err != nil { + return nil, err + } + if !has { + return nil, nil + } + encRow, err := db.Get(key) + if err != nil { + return nil, err + } + if len(encRow)%byteLength != 0 { + return nil, errors.New("Invalid encoded extended filter row length") + } + row := make([]uint32, len(encRow)/byteLength) + var b [4]byte + for i := range row { + copy(b[:byteLength], encRow[i*byteLength:(i+1)*byteLength]) + row[i] = binary.LittleEndian.Uint32(b[:]) + } + return row, nil +} + +func ReadFilterMapBaseRows(db ethdb.KeyValueReader, mapRowIndex uint64, rowCount uint32, bitLength uint) ([][]uint32, error) { + byteLength := int(bitLength) / 8 + if int(bitLength) != byteLength*8 { + panic("invalid bit length") + } + key := filterMapRowKey(mapRowIndex, true) + has, err := db.Has(key) + if err != nil { + return nil, err + } + rows := make([][]uint32, rowCount) + if !has { + return rows, nil + } + encRows, err := db.Get(key) + if err != nil { + return nil, err + } + encLen := len(encRows) + var ( + entryCount, entriesInRow, rowIndex, headerLen, headerBits int + headerByte byte + ) + for headerLen+byteLength*entryCount < encLen { + if headerBits == 0 { + headerByte = encRows[headerLen] + headerLen++ + headerBits = 8 + } + if headerByte&1 > 0 { + entriesInRow++ + entryCount++ + } else { + if entriesInRow > 0 { + rows[rowIndex] = make([]uint32, entriesInRow) + entriesInRow = 0 + } + rowIndex++ + } + headerByte >>= 1 + headerBits-- + } + if headerLen+byteLength*entryCount > encLen { + return nil, errors.New("Invalid encoded base filter rows length") + } + if entriesInRow > 0 { + rows[rowIndex] = make([]uint32, entriesInRow) + } + nextEntry := headerLen + for _, row := range rows { + for i := range row { + var b [4]byte + copy(b[:byteLength], encRows[nextEntry:nextEntry+byteLength]) + row[i] = binary.LittleEndian.Uint32(b[:]) + nextEntry += byteLength + } + } + return rows, nil +} + +// WriteFilterMapRow stores a filter map row at the given mapRowIndex or deletes +// any existing entry if the row is empty. +func WriteFilterMapExtRow(db ethdb.KeyValueWriter, mapRowIndex uint64, row []uint32, bitLength uint) { + byteLength := int(bitLength) / 8 + if int(bitLength) != byteLength*8 { + panic("invalid bit length") + } + var err error + if len(row) > 0 { + encRow := make([]byte, len(row)*byteLength) + for i, c := range row { + var b [4]byte + binary.LittleEndian.PutUint32(b[:], c) + copy(encRow[i*byteLength:(i+1)*byteLength], b[:byteLength]) + } + err = db.Put(filterMapRowKey(mapRowIndex, false), encRow) + } else { + err = db.Delete(filterMapRowKey(mapRowIndex, false)) + } + if err != nil { + log.Crit("Failed to store extended filter map row", "err", err) + } +} + +func WriteFilterMapBaseRows(db ethdb.KeyValueWriter, mapRowIndex uint64, rows [][]uint32, bitLength uint) { + byteLength := int(bitLength) / 8 + if int(bitLength) != byteLength*8 { + panic("invalid bit length") + } + var entryCount, zeroBits int + for i, row := range rows { + if len(row) > 0 { + entryCount += len(row) + zeroBits = i + } + } + var err error + if entryCount > 0 { + headerLen := (zeroBits + entryCount + 7) / 8 + encRows := make([]byte, headerLen+entryCount*byteLength) + nextEntry := headerLen + + headerPtr, headerByte := 0, byte(1) + addHeaderBit := func(bit bool) { + if bit { + encRows[headerPtr] += headerByte + } + if headerByte += headerByte; headerByte == 0 { + headerPtr++ + headerByte = 1 + } + } + + for _, row := range rows { + for _, entry := range row { + var b [4]byte + binary.LittleEndian.PutUint32(b[:], entry) + copy(encRows[nextEntry:nextEntry+byteLength], b[:byteLength]) + nextEntry += byteLength + addHeaderBit(true) + } + if zeroBits == 0 { + break + } + addHeaderBit(false) + zeroBits-- + } + err = db.Put(filterMapRowKey(mapRowIndex, true), encRows) + } else { + err = db.Delete(filterMapRowKey(mapRowIndex, true)) + } + if err != nil { + log.Crit("Failed to store base filter map rows", "err", err) + } +} + +func DeleteFilterMapRows(db ethdb.KeyValueRangeDeleter, firstMapRowIndex, afterLastMapRowIndex uint64) { + if err := db.DeleteRange(filterMapRowKey(firstMapRowIndex, false), filterMapRowKey(afterLastMapRowIndex, false)); err != nil { + log.Crit("Failed to delete range of filter map rows", "err", err) + } +} + +// ReadFilterMapLastBlock retrieves the number of the block that generated the +// last log value entry of the given map. +func ReadFilterMapLastBlock(db ethdb.KeyValueReader, mapIndex uint32) (uint64, common.Hash, error) { + enc, err := db.Get(filterMapLastBlockKey(mapIndex)) + if err != nil { + return 0, common.Hash{}, err + } + if len(enc) != 40 { + return 0, common.Hash{}, errors.New("Invalid block number and id encoding") + } + var id common.Hash + copy(id[:], enc[8:]) + return binary.BigEndian.Uint64(enc[:8]), id, nil +} + +// WriteFilterMapLastBlock stores the number of the block that generated the +// last log value entry of the given map. +func WriteFilterMapLastBlock(db ethdb.KeyValueWriter, mapIndex uint32, blockNumber uint64, id common.Hash) { + var enc [40]byte + binary.BigEndian.PutUint64(enc[:8], blockNumber) + copy(enc[8:], id[:]) + if err := db.Put(filterMapLastBlockKey(mapIndex), enc[:]); err != nil { + log.Crit("Failed to store filter map last block pointer", "err", err) + } +} + +// DeleteFilterMapLastBlock deletes the number of the block that generated the +// last log value entry of the given map. +func DeleteFilterMapLastBlock(db ethdb.KeyValueWriter, mapIndex uint32) { + if err := db.Delete(filterMapLastBlockKey(mapIndex)); err != nil { + log.Crit("Failed to delete filter map last block pointer", "err", err) + } +} + +func DeleteFilterMapLastBlocks(db ethdb.KeyValueRangeDeleter, firstMapIndex, afterLastMapIndex uint32) { + if err := db.DeleteRange(filterMapLastBlockKey(firstMapIndex), filterMapLastBlockKey(afterLastMapIndex)); err != nil { + log.Crit("Failed to delete range of filter map last block pointers", "err", err) + } +} + +// ReadBlockLvPointer retrieves the starting log value index where the log values +// generated by the given block are located. +func ReadBlockLvPointer(db ethdb.KeyValueReader, blockNumber uint64) (uint64, error) { + encPtr, err := db.Get(filterMapBlockLVKey(blockNumber)) + if err != nil { + return 0, err + } + if len(encPtr) != 8 { + return 0, errors.New("Invalid log value pointer encoding") + } + return binary.BigEndian.Uint64(encPtr), nil +} + +// WriteBlockLvPointer stores the starting log value index where the log values +// generated by the given block are located. +func WriteBlockLvPointer(db ethdb.KeyValueWriter, blockNumber, lvPointer uint64) { + var encPtr [8]byte + binary.BigEndian.PutUint64(encPtr[:], lvPointer) + if err := db.Put(filterMapBlockLVKey(blockNumber), encPtr[:]); err != nil { + log.Crit("Failed to store block log value pointer", "err", err) + } +} + +// DeleteBlockLvPointer deletes the starting log value index where the log values +// generated by the given block are located. +func DeleteBlockLvPointer(db ethdb.KeyValueWriter, blockNumber uint64) { + if err := db.Delete(filterMapBlockLVKey(blockNumber)); err != nil { + log.Crit("Failed to delete block log value pointer", "err", err) + } +} + +func DeleteBlockLvPointers(db ethdb.KeyValueRangeDeleter, firstBlockNumber, afterLastBlockNumber uint64) { + if err := db.DeleteRange(filterMapBlockLVKey(firstBlockNumber), filterMapBlockLVKey(afterLastBlockNumber)); err != nil { + log.Crit("Failed to delete range of block log value pointers", "err", err) + } +} + +// FilterMapsRange is a storage representation of the block range covered by the +// filter maps structure and the corresponting log value index range. +type FilterMapsRange struct { + HeadBlockIndexed bool + HeadBlockDelimiter uint64 + FirstIndexedBlock, AfterLastIndexedBlock uint64 + FirstRenderedMap, AfterLastRenderedMap, TailPartialEpoch uint32 +} + +// ReadFilterMapsRange retrieves the filter maps range data. Note that if the +// database entry is not present, that is interpreted as a valid non-initialized +// state and returns a blank range structure and no error. +func ReadFilterMapsRange(db ethdb.KeyValueReader) (FilterMapsRange, bool, error) { + if has, err := db.Has(filterMapsRangeKey); !has || err != nil { + return FilterMapsRange{}, false, err + } + encRange, err := db.Get(filterMapsRangeKey) + if err != nil { + return FilterMapsRange{}, false, err + } + var fmRange FilterMapsRange + if err := rlp.DecodeBytes(encRange, &fmRange); err != nil { + return FilterMapsRange{}, false, err + } + return fmRange, true, err +} + +// WriteFilterMapsRange stores the filter maps range data. +func WriteFilterMapsRange(db ethdb.KeyValueWriter, fmRange FilterMapsRange) { + encRange, err := rlp.EncodeToBytes(&fmRange) + if err != nil { + log.Crit("Failed to encode filter maps range", "err", err) + } + if err := db.Put(filterMapsRangeKey, encRange); err != nil { + log.Crit("Failed to store filter maps range", "err", err) + } +} + +// DeleteFilterMapsRange deletes the filter maps range data which is interpreted +// as reverting to the un-initialized state. +func DeleteFilterMapsRange(db ethdb.KeyValueWriter) { + if err := db.Delete(filterMapsRangeKey); err != nil { + log.Crit("Failed to delete filter maps range", "err", err) + } +} diff --git a/core/rawdb/database.go b/core/rawdb/database.go index ae1e7c0bdc..bc29347324 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -376,6 +376,7 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { storageSnaps stat preimages stat bloomBits stat + filterMaps stat beaconHeaders stat cliqueSnaps stat @@ -440,6 +441,8 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { bloomBits.Add(size) case bytes.HasPrefix(key, BloomBitsIndexPrefix): bloomBits.Add(size) + case bytes.HasPrefix(key, []byte(FilterMapsPrefix)): + filterMaps.Add(size) case bytes.HasPrefix(key, skeletonHeaderPrefix) && len(key) == (len(skeletonHeaderPrefix)+8): beaconHeaders.Add(size) case bytes.HasPrefix(key, CliqueSnapshotPrefix) && len(key) == 7+common.HashLength: @@ -505,6 +508,7 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { {"Key-Value store", "Block hash->number", hashNumPairings.Size(), hashNumPairings.Count()}, {"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()}, {"Key-Value store", "Bloombit index", bloomBits.Size(), bloomBits.Count()}, + {"Key-Value store", "Log search index", filterMaps.Size(), filterMaps.Count()}, {"Key-Value store", "Contract codes", codes.Size(), codes.Count()}, {"Key-Value store", "Hash trie nodes", legacyTries.Size(), legacyTries.Count()}, {"Key-Value store", "Path trie state lookups", stateLookups.Size(), stateLookups.Count()}, diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 5480c7a72c..b41951113c 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -145,6 +145,12 @@ var ( FixedCommitteeRootKey = []byte("fixedRoot-") // bigEndian64(syncPeriod) -> committee root hash SyncCommitteeKey = []byte("committee-") // bigEndian64(syncPeriod) -> serialized committee + FilterMapsPrefix = "fm-" + filterMapsRangeKey = []byte(FilterMapsPrefix + "R") + filterMapRowPrefix = []byte(FilterMapsPrefix + "r") // filterMapRowPrefix + mapRowIndex (uint64 big endian) -> filter row + filterMapLastBlockPrefix = []byte(FilterMapsPrefix + "b") // filterMapLastBlockPrefix + mapIndex (uint32 big endian) -> block number (uint64 big endian) + filterMapBlockLVPrefix = []byte(FilterMapsPrefix + "p") // filterMapBlockLVPrefix + num (uint64 big endian) -> log value pointer (uint64 big endian) + preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) preimageHitsCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) preimageMissCounter = metrics.NewRegisteredCounter("db/preimage/miss", nil) @@ -342,3 +348,34 @@ func IsStorageTrieNode(key []byte) bool { ok, _, _ := ResolveStorageTrieNode(key) return ok } + +// filterMapRowKey = filterMapRowPrefix + mapRowIndex (uint64 big endian) +func filterMapRowKey(mapRowIndex uint64, base bool) []byte { + extLen := 8 + if base { + extLen = 9 + } + l := len(filterMapRowPrefix) + key := make([]byte, l+extLen) + copy(key[:l], filterMapRowPrefix) + binary.BigEndian.PutUint64(key[l:l+8], mapRowIndex) + return key +} + +// filterMapLastBlockKey = filterMapLastBlockPrefix + mapIndex (uint32 big endian) +func filterMapLastBlockKey(mapIndex uint32) []byte { + l := len(filterMapLastBlockPrefix) + key := make([]byte, l+4) + copy(key[:l], filterMapLastBlockPrefix) + binary.BigEndian.PutUint32(key[l:], mapIndex) + return key +} + +// filterMapBlockLVKey = filterMapBlockLVPrefix + num (uint64 big endian) +func filterMapBlockLVKey(number uint64) []byte { + l := len(filterMapBlockLVPrefix) + key := make([]byte, l+8) + copy(key[:l], filterMapBlockLVPrefix) + binary.BigEndian.PutUint64(key[l:], number) + return key +} From e5758c606ab1762423f78cd168a8a38df5407fd3 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Fri, 14 Mar 2025 15:27:38 +0100 Subject: [PATCH 190/940] accounts/abi: improve unpack performance (#31387) Slightly improves performance of abi.Unpack ``` Before BenchmarkUnpack/0-14 5965714 210.9 ns/op 280 B/op 5 allocs/op BenchmarkUnpack/1-14 2148283 569.7 ns/op 688 B/op 16 allocs/op After: BenchmarkUnpack/0-14 7693365 151.2 ns/op 136 B/op 4 allocs/op BenchmarkUnpack/1-14 2261294 508.9 ns/op 544 B/op 15 allocs/op ``` replaces https://github.com/ethereum/go-ethereum/pull/31292 since I was unable to push to your branch @Exca-DK --------- Co-authored-by: Exca-DK --- accounts/abi/argument.go | 33 ++++++++++++++++++------------ accounts/abi/unpack_test.go | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 227a088b7d..e48f763890 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -77,18 +77,18 @@ func (arguments Arguments) isTuple() bool { } // Unpack performs the operation hexdata -> Go format. -func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) { +func (arguments Arguments) Unpack(data []byte) ([]any, error) { if len(data) == 0 { if len(arguments.NonIndexed()) != 0 { return nil, errors.New("abi: attempting to unmarshal an empty string while arguments are expected") } - return make([]interface{}, 0), nil + return make([]any, 0), nil } return arguments.UnpackValues(data) } // UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value. -func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error { +func (arguments Arguments) UnpackIntoMap(v map[string]any, data []byte) error { // Make sure map is not nil if v == nil { return errors.New("abi: cannot unpack into a nil map") @@ -110,7 +110,7 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) } // Copy performs the operation go format -> provided struct. -func (arguments Arguments) Copy(v interface{}, values []interface{}) error { +func (arguments Arguments) Copy(v any, values []any) error { // make sure the passed value is arguments pointer if reflect.Ptr != reflect.ValueOf(v).Kind() { return fmt.Errorf("abi: Unpack(non-pointer %T)", v) @@ -128,7 +128,7 @@ func (arguments Arguments) Copy(v interface{}, values []interface{}) error { } // copyAtomic copies ( hexdata -> go ) a single value -func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{}) error { +func (arguments Arguments) copyAtomic(v any, marshalledValues any) error { dst := reflect.ValueOf(v).Elem() src := reflect.ValueOf(marshalledValues) @@ -139,7 +139,7 @@ func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{ } // copyTuple copies a batch of values from marshalledValues to v. -func (arguments Arguments) copyTuple(v interface{}, marshalledValues []interface{}) error { +func (arguments Arguments) copyTuple(v any, marshalledValues []any) error { value := reflect.ValueOf(v).Elem() nonIndexedArgs := arguments.NonIndexed() @@ -181,11 +181,17 @@ func (arguments Arguments) copyTuple(v interface{}, marshalledValues []interface // UnpackValues can be used to unpack ABI-encoded hexdata according to the ABI-specification, // without supplying a struct to unpack into. Instead, this method returns a list containing the // values. An atomic argument will be a list with one element. -func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { - nonIndexedArgs := arguments.NonIndexed() - retval := make([]interface{}, 0, len(nonIndexedArgs)) - virtualArgs := 0 - for index, arg := range nonIndexedArgs { +func (arguments Arguments) UnpackValues(data []byte) ([]any, error) { + var ( + retval = make([]any, 0) + virtualArgs = 0 + index = 0 + ) + + for _, arg := range arguments { + if arg.Indexed { + continue + } marshalledValue, err := toGoType((index+virtualArgs)*32, arg.Type, data) if err != nil { return nil, err @@ -208,18 +214,19 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { virtualArgs += getTypeSize(arg.Type)/32 - 1 } retval = append(retval, marshalledValue) + index++ } return retval, nil } // PackValues performs the operation Go format -> Hexdata. // It is the semantic opposite of UnpackValues. -func (arguments Arguments) PackValues(args []interface{}) ([]byte, error) { +func (arguments Arguments) PackValues(args []any) ([]byte, error) { return arguments.Pack(args...) } // Pack performs the operation Go format -> Hexdata. -func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) { +func (arguments Arguments) Pack(args ...any) ([]byte, error) { // Make sure arguments match up and pack them abiArgs := arguments if len(args) != len(abiArgs) { diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 7df7b9c403..74db298b3f 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -31,6 +31,46 @@ import ( "github.com/stretchr/testify/require" ) +func BenchmarkUnpack(b *testing.B) { + testCases := []struct { + def string + packed string + }{ + { + def: `[{"type": "uint32"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + }, + { + def: `[{"type": "uint32[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + } + for i, test := range testCases { + b.Run(strconv.Itoa(i), func(b *testing.B) { + def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) + abi, err := JSON(strings.NewReader(def)) + if err != nil { + b.Fatalf("invalid ABI definition %s: %v", def, err) + } + encb, err := hex.DecodeString(test.packed) + if err != nil { + b.Fatalf("invalid hex %s: %v", test.packed, err) + } + + b.ResetTimer() + + var result any + for range b.N { + result, _ = abi.Unpack("method", encb) + } + _ = result + }) + } +} + // TestUnpack tests the general pack/unpack tests in packing_test.go func TestUnpack(t *testing.T) { t.Parallel() From 51177ed8c54d5eabc216bad25135684268288da4 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 14 Mar 2025 11:56:53 -0400 Subject: [PATCH 191/940] log: fix SetDefault for custom loggers (#31368) Currently, even though it takes in a `Logger` interface, `log.SetDefualt` enforces that the concrete type of the provided logger is `*logger` because: 1. in `init` `root.Store` is called with a `*logger` 2. `atomic.Value` panics if the concrete type provided in `Store` is not consistent across calls. ([ref](https://pkg.go.dev/sync/atomic#Value.Store)) > All calls to Store for a given Value must use values of the same concrete type. This PR changes to use `sync.RWMutex` and adds a test that panics on `master`. --- log/root.go | 19 ++++++++++++++----- log/root_test.go | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 log/root_test.go diff --git a/log/root.go b/log/root.go index 91209c46ad..c09a36b114 100644 --- a/log/root.go +++ b/log/root.go @@ -3,18 +3,24 @@ package log import ( "log/slog" "os" - "sync/atomic" + "sync" ) -var root atomic.Value +var ( + rootLock sync.RWMutex + root Logger +) func init() { - root.Store(&logger{slog.New(DiscardHandler())}) + root = &logger{slog.New(DiscardHandler())} } // SetDefault sets the default global logger func SetDefault(l Logger) { - root.Store(l) + rootLock.Lock() + defer rootLock.Unlock() + + root = l if lg, ok := l.(*logger); ok { slog.SetDefault(lg.inner) } @@ -22,7 +28,10 @@ func SetDefault(l Logger) { // Root returns the root logger func Root() Logger { - return root.Load().(Logger) + rootLock.RLock() + defer rootLock.RUnlock() + + return root } // The following functions bypass the exported logger methods (logger.Debug, diff --git a/log/root_test.go b/log/root_test.go new file mode 100644 index 0000000000..b9b22af669 --- /dev/null +++ b/log/root_test.go @@ -0,0 +1,19 @@ +package log + +import ( + "testing" +) + +// SetDefault should properly set the default logger when custom loggers are +// provided. +func TestSetDefaultCustomLogger(t *testing.T) { + type customLogger struct { + Logger // Implement the Logger interface + } + + customLog := &customLogger{} + SetDefault(customLog) + if Root() != customLog { + t.Error("expected custom logger to be set as default") + } +} From 475e87cbc1d9f6fbc66327ce57476e7d10c1da7e Mon Sep 17 00:00:00 2001 From: danceratopz Date: Fri, 14 Mar 2025 17:56:24 +0100 Subject: [PATCH 192/940] cmd/evm: fix statetest with multi-fork statetest fixtures (#31374) Fixes `evm statetest` for state test fixtures with multiple fork entries in their `post` field (e.g., [chainId.json](https://github.com/ethereum/tests/blob/81862e4848585a438d64f911a19b3825f0f4cd95/GeneralStateTests/stChainId/chainId.json#L39)). When these re-activated flags aren't exposed, `statetest` only executes the fixture for a single fork entry instead of all of the forks as expected. This only affects ethereum/tests state test fixtures, not ethereum/execution-spec-tests (EEST) state tests. EEST writes a separate fixture/test case (i.e. a separate top-level dict entry in the .json) for each fork configuration as apposed to combining multiple forks in one fixture test case: New EEST state tests targeting Prague behavior are not affected. --- cmd/evm/staterunner.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 8f81a95315..1b0eb2ca2a 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -53,7 +53,9 @@ var stateTestCommand = &cli.Command{ Flags: slices.Concat([]cli.Flag{ BenchFlag, DumpFlag, + forkFlag, HumanReadableFlag, + idxFlag, RunFlag, }, traceFlags), } From e3853e910a53696c9e1199c85e86b8b6e3287476 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:53:05 +0100 Subject: [PATCH 193/940] tests: update ethereum/tests to v17.0 (#31381) Get the re-filled tests (plus removal of outdated EIP-2537 tests) --- tests/block_test.go | 3 ++ tests/state_test.go | 9 ---- tests/testdata | 2 +- tests/transaction_test.go | 7 +-- tests/transaction_test_util.go | 88 ++++++++++++++++++++-------------- 5 files changed, 57 insertions(+), 52 deletions(-) diff --git a/tests/block_test.go b/tests/block_test.go index 15806b3eff..f146e4ee6a 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -63,6 +63,9 @@ func TestBlockchain(t *testing.T) { // With chain history removal, TDs become unavailable, this transition tests based on TTD are unrunnable bt.skipLoad(`.*bcArrowGlacierToParis/powToPosBlockRejection.json`) + // This directory contains no test. + bt.skipLoad(`.*\.meta/.*`) + bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { execBlockTest(t, bt, test) }) diff --git a/tests/state_test.go b/tests/state_test.go index e7525118e2..301bc3a7a9 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -54,18 +54,9 @@ func initMatcher(st *testMatcher) { // Uses 1GB RAM per tested fork st.skipLoad(`^stStaticCall/static_Call1MB`) - // Out-of-date EIP-2537 tests - // TODO (@s1na) reenable in the future - st.skipLoad(`^stEIP2537/`) - // 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) { diff --git a/tests/testdata b/tests/testdata index faf33b4714..81862e4848 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2 +Subproject commit 81862e4848585a438d64f911a19b3825f0f4cd95 diff --git a/tests/transaction_test.go b/tests/transaction_test.go index 8147173905..6260df0f3f 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -20,7 +20,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/params" ) func TestTransaction(t *testing.T) { @@ -58,8 +57,7 @@ func TestTransaction(t *testing.T) { txt.skipLoad("^ttEIP1559/GasLimitPriceProductOverflow.json") txt.walk(t, transactionTestDir, func(t *testing.T, name string, test *TransactionTest) { - cfg := params.MainnetChainConfig - if err := txt.checkFailure(t, test.Run(cfg)); err != nil { + if err := txt.checkFailure(t, test.Run()); err != nil { t.Error(err) } }) @@ -75,8 +73,7 @@ func TestExecutionSpecTransaction(t *testing.T) { st.skipLoad("^prague/eip7702_set_code_tx/invalid_tx/empty_authorization_list.json") st.walk(t, executionSpecTransactionTestDir, func(t *testing.T, name string, test *TransactionTest) { - cfg := params.MainnetChainConfig - if err := st.checkFailure(t, test.Run(cfg)); err != nil { + if err := st.checkFailure(t, test.Run()); err != nil { t.Error(err) } }) diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 3f91a82ec5..b2efabe82e 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -18,6 +18,7 @@ package tests import ( "fmt" + "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -65,11 +66,11 @@ func (tt *TransactionTest) validateFork(fork *ttFork) error { return nil } -func (tt *TransactionTest) Run(config *params.ChainConfig) error { +func (tt *TransactionTest) Run() error { if err := tt.validate(); err != nil { return err } - validateTx := func(rlpData hexutil.Bytes, signer types.Signer, isHomestead, isIstanbul, isShanghai bool) (sender common.Address, hash common.Hash, requiredGas uint64, err error) { + validateTx := func(rlpData hexutil.Bytes, signer types.Signer, rules *params.Rules) (sender common.Address, hash common.Hash, requiredGas uint64, err error) { tx := new(types.Transaction) if err = tx.UnmarshalBinary(rlpData); err != nil { return @@ -79,62 +80,75 @@ func (tt *TransactionTest) Run(config *params.ChainConfig) error { return } // Intrinsic gas - requiredGas, err = core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, isHomestead, isIstanbul, isShanghai) + requiredGas, err = core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) if err != nil { return } if requiredGas > tx.Gas() { return sender, hash, 0, fmt.Errorf("insufficient gas ( %d < %d )", tx.Gas(), requiredGas) } + + if rules.IsPrague { + var floorDataGas uint64 + floorDataGas, err = core.FloorDataGas(tx.Data()) + if err != nil { + return + } + if tx.Gas() < floorDataGas { + return sender, hash, 0, fmt.Errorf("%w: have %d, want %d", core.ErrFloorDataGas, tx.Gas(), floorDataGas) + } + } hash = tx.Hash() return sender, hash, requiredGas, nil } for _, testcase := range []struct { - name string - signer types.Signer - fork *ttFork - isHomestead bool - isIstanbul bool - isShanghai bool + name string + isMerge bool }{ - {"Frontier", types.FrontierSigner{}, tt.Result["Frontier"], false, false, false}, - {"Homestead", types.HomesteadSigner{}, tt.Result["Homestead"], true, false, false}, - {"EIP150", types.HomesteadSigner{}, tt.Result["EIP150"], true, false, false}, - {"EIP158", types.NewEIP155Signer(config.ChainID), tt.Result["EIP158"], true, false, false}, - {"Byzantium", types.NewEIP155Signer(config.ChainID), tt.Result["Byzantium"], true, false, false}, - {"Constantinople", types.NewEIP155Signer(config.ChainID), tt.Result["Constantinople"], true, false, false}, - {"Istanbul", types.NewEIP155Signer(config.ChainID), tt.Result["Istanbul"], true, true, false}, - {"Berlin", types.NewEIP2930Signer(config.ChainID), tt.Result["Berlin"], true, true, false}, - {"London", types.NewLondonSigner(config.ChainID), tt.Result["London"], true, true, false}, - {"Paris", types.NewLondonSigner(config.ChainID), tt.Result["Paris"], true, true, false}, - {"Shanghai", types.NewLondonSigner(config.ChainID), tt.Result["Shanghai"], true, true, true}, - {"Cancun", types.NewCancunSigner(config.ChainID), tt.Result["Cancun"], true, true, true}, - {"Prague", types.NewPragueSigner(config.ChainID), tt.Result["Prague"], true, true, true}, + {"Frontier", false}, + {"Homestead", false}, + {"EIP150", false}, + {"EIP158", false}, + {"Byzantium", false}, + {"Constantinople", false}, + {"Istanbul", false}, + {"Berlin", false}, + {"London", false}, + {"Paris", true}, + {"Shanghai", true}, + {"Cancun", true}, + {"Prague", true}, } { - if testcase.fork == nil { + expected := tt.Result[testcase.name] + if expected == nil { continue } - sender, hash, gas, err := validateTx(tt.Txbytes, testcase.signer, testcase.isHomestead, testcase.isIstanbul, testcase.isShanghai) + config, ok := Forks[testcase.name] + if !ok || config == nil { + return UnsupportedForkError{Name: testcase.name} + } + var ( + rules = config.Rules(new(big.Int), testcase.isMerge, 0) + signer = types.MakeSigner(config, new(big.Int), 0) + ) + sender, hash, gas, err := validateTx(tt.Txbytes, signer, &rules) if err != nil { - if testcase.fork.Hash != nil { - return fmt.Errorf("unexpected error: %v", err) + if expected.Hash != nil { + return fmt.Errorf("unexpected error fork %s: %v", testcase.name, err) } continue } - if testcase.fork.Exception != nil { - return fmt.Errorf("expected error %v, got none (%v)", *testcase.fork.Exception, err) + if expected.Exception != nil { + return fmt.Errorf("expected error %v, got none (%v), fork %s", *expected.Exception, err, testcase.name) } - if common.Hash(*testcase.fork.Hash) != hash { - return fmt.Errorf("hash mismatch: got %x, want %x", hash, common.Hash(*testcase.fork.Hash)) + if common.Hash(*expected.Hash) != hash { + return fmt.Errorf("hash mismatch: got %x, want %x", hash, common.Hash(*expected.Hash)) } - if common.Address(*testcase.fork.Sender) != sender { - return fmt.Errorf("sender mismatch: got %x, want %x", sender, testcase.fork.Sender) + if common.Address(*expected.Sender) != sender { + return fmt.Errorf("sender mismatch: got %x, want %x", sender, expected.Sender) } - if hash != common.Hash(*testcase.fork.Hash) { - return fmt.Errorf("hash mismatch: got %x, want %x", hash, testcase.fork.Hash) - } - if uint64(testcase.fork.IntrinsicGas) != gas { - return fmt.Errorf("intrinsic gas mismatch: got %d, want %d", gas, uint64(testcase.fork.IntrinsicGas)) + if uint64(expected.IntrinsicGas) != gas { + return fmt.Errorf("intrinsic gas mismatch: got %d, want %d", gas, uint64(expected.IntrinsicGas)) } } return nil From 7d99f7df0056ea450119a14767d17e818812e736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladimir=20T=C3=A1mara=20Pati=C3=B1o?= Date: Sat, 15 Mar 2025 13:35:10 -0400 Subject: [PATCH 194/940] cmd/utils: fix geth test issue on OpenBSD (#31357) --- cmd/utils/cmd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 33c93c2cc6..d91d6ca5a8 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -63,8 +63,8 @@ var ErrImportInterrupted = errors.New("interrupted") // is redirected to a different file. func Fatalf(format string, args ...interface{}) { w := io.MultiWriter(os.Stdout, os.Stderr) - if runtime.GOOS == "windows" { - // The SameFile check below doesn't work on Windows. + if runtime.GOOS == "windows" || runtime.GOOS == "openbsd" { + // The SameFile check below doesn't work on Windows neither OpenBSD. // stdout is unlikely to get redirected though, so just print there. w = os.Stdout } else { From d25c3c32b24c5e176d9433b9f8da53eaf8afa95f Mon Sep 17 00:00:00 2001 From: Mike Weyandt Date: Sun, 16 Mar 2025 21:48:08 -0400 Subject: [PATCH 195/940] metrics: spin up meter ticker routine when enabling metric system (#31400) Addresses https://github.com/ethereum/go-ethereum/issues/31244 --- metrics/meter.go | 17 +++++++++-------- metrics/metrics.go | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/metrics/meter.go b/metrics/meter.go index 194bd1f304..197e5abbed 100644 --- a/metrics/meter.go +++ b/metrics/meter.go @@ -131,19 +131,15 @@ var arbiter = meterTicker{meters: make(map[*Meter]struct{})} type meterTicker struct { mu sync.RWMutex - started bool - meters map[*Meter]struct{} + once sync.Once + meters map[*Meter]struct{} } -// add adds another *Meter ot the arbiter, and starts the arbiter ticker. +// add a *Meter to the arbiter func (ma *meterTicker) add(m *Meter) { ma.mu.Lock() defer ma.mu.Unlock() ma.meters[m] = struct{}{} - if !ma.started { - ma.started = true - go ma.loop() - } } // remove removes a meter from the set of ticked meters. @@ -153,7 +149,7 @@ func (ma *meterTicker) remove(m *Meter) { ma.mu.Unlock() } -// loop ticks meters on a 5 second interval. +// loop ticks meters on a 5-second interval. func (ma *meterTicker) loop() { ticker := time.NewTicker(5 * time.Second) for range ticker.C { @@ -167,3 +163,8 @@ func (ma *meterTicker) loop() { ma.mu.RUnlock() } } + +// startMeterTickerLoop will start the arbiter ticker. +func startMeterTickerLoop() { + arbiter.once.Do(func() { go arbiter.loop() }) +} diff --git a/metrics/metrics.go b/metrics/metrics.go index c4c43b7576..088948d403 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -30,6 +30,7 @@ func Enabled() bool { // the program, before any metrics collection will happen. func Enable() { metricsEnabled = true + startMeterTickerLoop() } var threadCreateProfile = pprof.Lookup("threadcreate") From 881ee4062f93eaa6d0cc95202326caa7af4f88c9 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Mon, 17 Mar 2025 14:13:12 +0800 Subject: [PATCH 196/940] eth/catalyst: fix flaky test (#31403) This pull request enhances the unit test, avoiding unnecessary failure in CI. ``` --- FAIL: TestSimulatedBeaconSendWithdrawals (12.08s) simulated_beacon_test.go:139: timed out without including all withdrawals/txs FAIL ``` --- eth/catalyst/simulated_beacon_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eth/catalyst/simulated_beacon_test.go b/eth/catalyst/simulated_beacon_test.go index ea35482896..3a74a92ed5 100644 --- a/eth/catalyst/simulated_beacon_test.go +++ b/eth/catalyst/simulated_beacon_test.go @@ -120,7 +120,7 @@ func TestSimulatedBeaconSendWithdrawals(t *testing.T) { includedTxs := make(map[common.Hash]struct{}) var includedWithdrawals []uint64 - timer := time.NewTimer(12 * time.Second) + timer := time.NewTimer(30 * time.Second) for { select { case ev := <-chainHeadCh: @@ -131,8 +131,8 @@ func TestSimulatedBeaconSendWithdrawals(t *testing.T) { for _, includedWithdrawal := range block.Withdrawals() { includedWithdrawals = append(includedWithdrawals, includedWithdrawal.Index) } - // ensure all withdrawals/txs included. this will take two blocks b/c number of withdrawals > 10 - if len(includedTxs) == len(txs) && len(includedWithdrawals) == len(withdrawals) && ev.Header.Number.Cmp(big.NewInt(2)) == 0 { + // ensure all withdrawals/txs included. this will at least take two blocks b/c number of withdrawals > 10 + if len(includedTxs) == len(txs) && len(includedWithdrawals) == len(withdrawals) { return } case <-timer.C: From 74c6b69384557d33d47a4863d859f6f4cc3485d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:22:12 +0100 Subject: [PATCH 197/940] go.mod: bump golang.org/x/net from 0.34.0 to 0.36.0 (#31369) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.34.0 to 0.36.0.
Commits
  • 85d1d54 go.mod: update golang.org/x dependencies
  • cde1dda proxy, http/httpproxy: do not mismatch IPv6 zone ids against hosts
  • fe7f039 publicsuffix: spruce up code gen and speed up PublicSuffix
  • 459513d internal/http3: move more common stream processing to genericConn
  • aad0180 http2: fix flakiness from t.Log when GOOS=js
  • b73e574 http2: don't log expected errors from writing invalid trailers
  • 5f45c77 internal/http3: make read-data tests usable for server handlers
  • 43c2540 http2, internal/httpcommon: reject userinfo in :authority
  • 1d78a08 http2, internal/httpcommon: factor out server header logic for h2/h3
  • 0d7dc54 quic: add Conn.ConnectionState
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/net&package-manager=go_modules&previous-version=0.34.0&new-version=0.36.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/ethereum/go-ethereum/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index eac0d7a7fd..053c7b7a7d 100644 --- a/go.mod +++ b/go.mod @@ -143,7 +143,7 @@ require ( github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.34.0 // indirect + golang.org/x/net v0.36.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index 4537d194d0..40800ed257 100644 --- a/go.sum +++ b/go.sum @@ -619,8 +619,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= From 1cdf4d6da7fbc0d481d25b9510da98c25bce384d Mon Sep 17 00:00:00 2001 From: Shude Li Date: Mon, 17 Mar 2025 16:32:44 +0800 Subject: [PATCH 198/940] eth/catalyst: set FeeRecipient in dev mode (#31316) this adds 2 features to improve `geth --dev` experience. 1. we don't need to use `dev_SetFeeRecipient` to set initial coinbase address. it was a pain. 2. we don't need to unlock keystore if we don't use it. we had it because of clique. --- cmd/geth/config.go | 2 +- cmd/utils/flags.go | 7 +++++-- eth/catalyst/simulated_beacon.go | 3 ++- eth/catalyst/simulated_beacon_test.go | 2 +- ethclient/simulated/backend.go | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 71ab0b6968..4215403234 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -233,7 +233,7 @@ func makeFullNode(ctx *cli.Context) *node.Node { if ctx.IsSet(utils.DeveloperFlag.Name) { // Start dev mode. - simBeacon, err := catalyst.NewSimulatedBeacon(ctx.Uint64(utils.DeveloperPeriodFlag.Name), eth) + simBeacon, err := catalyst.NewSimulatedBeacon(ctx.Uint64(utils.DeveloperPeriodFlag.Name), cfg.Eth.Miner.PendingFeeRecipient, eth) if err != nil { utils.Fatalf("failed to register dev mode catalyst service: %v", err) } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 7c32d7e734..06eabbf313 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1757,8 +1757,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { // the miner will fail to start. cfg.Miner.PendingFeeRecipient = developer.Address - if err := ks.Unlock(developer, passphrase); err != nil { - Fatalf("Failed to unlock developer account: %v", err) + // try to unlock the first keystore account + if len(ks.Accounts()) > 0 { + if err := ks.Unlock(developer, passphrase); err != nil { + Fatalf("Failed to unlock developer account: %v", err) + } } log.Info("Using developer account", "address", developer.Address) diff --git a/eth/catalyst/simulated_beacon.go b/eth/catalyst/simulated_beacon.go index c71add93bc..dd9d8f9062 100644 --- a/eth/catalyst/simulated_beacon.go +++ b/eth/catalyst/simulated_beacon.go @@ -108,7 +108,7 @@ func payloadVersion(config *params.ChainConfig, time uint64) engine.PayloadVersi } // NewSimulatedBeacon constructs a new simulated beacon chain. -func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) { +func NewSimulatedBeacon(period uint64, feeRecipient common.Address, eth *eth.Ethereum) (*SimulatedBeacon, error) { block := eth.BlockChain().CurrentBlock() current := engine.ForkchoiceStateV1{ HeadBlockHash: block.Hash(), @@ -131,6 +131,7 @@ func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, err engineAPI: engineAPI, lastBlockTime: block.Time, curForkchoiceState: current, + feeRecipient: feeRecipient, }, nil } diff --git a/eth/catalyst/simulated_beacon_test.go b/eth/catalyst/simulated_beacon_test.go index 3a74a92ed5..24eee6e925 100644 --- a/eth/catalyst/simulated_beacon_test.go +++ b/eth/catalyst/simulated_beacon_test.go @@ -55,7 +55,7 @@ func startSimulatedBeaconEthService(t *testing.T, genesis *core.Genesis, period t.Fatal("can't create eth service:", err) } - simBeacon, err := NewSimulatedBeacon(period, ethservice) + simBeacon, err := NewSimulatedBeacon(period, common.Address{}, ethservice) if err != nil { t.Fatal("can't create simulated beacon:", err) } diff --git a/ethclient/simulated/backend.go b/ethclient/simulated/backend.go index 65d44b9efa..d573c7e750 100644 --- a/ethclient/simulated/backend.go +++ b/ethclient/simulated/backend.go @@ -120,7 +120,7 @@ func newWithNode(stack *node.Node, conf *eth.Config, blockPeriod uint64) (*Backe return nil, err } // Set up the simulated beacon - beacon, err := catalyst.NewSimulatedBeacon(blockPeriod, backend) + beacon, err := catalyst.NewSimulatedBeacon(blockPeriod, common.Address{}, backend) if err != nil { return nil, err } From 64bd21393e734b266913f549f9f642f2bd5cc4e4 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Mon, 17 Mar 2025 15:56:55 +0100 Subject: [PATCH 199/940] cmd/abigen, accounts/abi/bind: implement abigen version 2 (#31379) This PR implements a new version of the abigen utility (v2) which exists along with the pre-existing v1 version. Abigen is a utility command provided by go-ethereum that, given a solidity contract ABI definition, will generate Go code to transact/call the contract methods, converting the method parameters/results and structures defined in the contract into corresponding Go types. This is useful for preventing the need to write custom boilerplate code for contract interactions. Methods in the generated bindings perform encoding between Go types and Solidity ABI-encoded packed bytecode, as well as some action (e.g. `eth_call` or creating and submitting a transaction). This limits the flexibility of how the generated bindings can be used, and prevents easily adding new functionality, as it will make the generated bindings larger for each feature added. Abigen v2 was conceived of by the observation that the only functionality that generated Go bindings ought to perform is conversion between Go types and ABI-encoded packed data. Go-ethereum already provides various APIs which in conjunction with conversion methods generated in v2 bindings can cover all functionality currently provided by v1, and facilitate all other previously-desired use-cases. ## Generating Bindings To generate contract bindings using abigen v2, invoke the `abigen` command with the `--v2` flag. The functionality of all other flags is preserved between the v2 and v1 versions. ## What is Generated in the Bindings The execution of `abigen --v2` generates Go code containing methods which convert between Go types and corresponding ABI-encoded data expected by the contract. For each input-accepting contract method and the constructor, a "packing" method is generated in the binding which converts from Go types to the corresponding packed solidity expected by the contract. If a method returns output, an "unpacking" method is generated to convert this output from ABI-encoded data to the corresponding Go types. For contracts which emit events, an unpacking method is defined for each event to unpack the corresponding raw log to the Go type that it represents. Likewise, where custom errors are defined by contracts, an unpack method is generated to unpack raw error data into a Go type. ## Using the Generated Bindings For a smooth user-experience, abigen v2 comes with a number of utility functions to be used in conjunction with the generated bindings for performing common contract interaction use-cases. These include: * filtering for historical logs of a given topic * watching the chain for emission of logs with a given topic * contract deployment methods * Call/Transact methods https://geth.ethereum.org will be updated to include a new tutorial page for abigen v2 with full code examples. The page currently exists in a PR: https://github.com/ethereum/go-ethereum/pull/31390 . There are also extensive examples of interactions with contract bindings in [test cases](https://github.com/ethereum/go-ethereum/blob/cc855c7ede460270ae9c83bba278b23cb4f26a00/accounts/abi/bind/v2/lib_test.go) provided with this PR. --------- Co-authored-by: Sina Mahmoodi Co-authored-by: Felix Lange --- accounts/abi/{bind => abigen}/bind.go | 141 ++-- accounts/abi/{bind => abigen}/bind_test.go | 14 +- accounts/abi/abigen/bindv2.go | 373 ++++++++++ accounts/abi/abigen/bindv2_test.go | 342 +++++++++ accounts/abi/{bind => abigen}/source.go.tpl | 0 accounts/abi/abigen/source2.go.tpl | 238 +++++++ accounts/abi/{bind => abigen}/template.go | 67 +- .../abigen/testdata/v2/callbackparam.go.txt | 64 ++ .../abi/abigen/testdata/v2/crowdsale.go.txt | 304 ++++++++ accounts/abi/abigen/testdata/v2/dao.go.txt | 655 ++++++++++++++++++ .../testdata/v2/deeplynestedarray.go.txt | 114 +++ accounts/abi/abigen/testdata/v2/empty.go.txt | 52 ++ .../abigen/testdata/v2/eventchecker.go.txt | 261 +++++++ accounts/abi/abigen/testdata/v2/getter.go.txt | 89 +++ .../testdata/v2/identifiercollision.go.txt | 102 +++ .../abigen/testdata/v2/inputchecker.go.txt | 123 ++++ .../abi/abigen/testdata/v2/interactor.go.txt | 126 ++++ .../abigen/testdata/v2/nameconflict.go.txt | 137 ++++ .../testdata/v2/numericmethodname.go.txt | 129 ++++ .../abigen/testdata/v2/outputchecker.go.txt | 253 +++++++ .../abi/abigen/testdata/v2/overload.go.txt | 159 +++++ .../abigen/testdata/v2/rangekeyword.go.txt | 64 ++ accounts/abi/abigen/testdata/v2/slicer.go.txt | 152 ++++ .../abi/abigen/testdata/v2/structs-abi.go.txt | 116 ++++ .../abi/abigen/testdata/v2/structs.go.txt | 119 ++++ accounts/abi/abigen/testdata/v2/token.go.txt | 319 +++++++++ accounts/abi/abigen/testdata/v2/tuple.go.txt | 228 ++++++ accounts/abi/abigen/testdata/v2/tupler.go.txt | 89 +++ .../abi/abigen/testdata/v2/underscorer.go.txt | 322 +++++++++ accounts/abi/bind/auth.go | 179 ----- accounts/abi/bind/old.go | 294 ++++++++ accounts/abi/bind/v2/auth.go | 96 +++ accounts/abi/bind/{ => v2}/backend.go | 13 + accounts/abi/bind/{ => v2}/base.go | 216 +++--- accounts/abi/bind/{ => v2}/base_test.go | 2 +- accounts/abi/bind/v2/dep_tree.go | 167 +++++ accounts/abi/bind/v2/dep_tree_test.go | 370 ++++++++++ accounts/abi/bind/v2/generate_test.go | 102 +++ .../bind/v2/internal/contracts/db/bindings.go | 293 ++++++++ .../internal/contracts/db/combined-abi.json | 1 + .../v2/internal/contracts/db/contract.sol | 66 ++ .../v2/internal/contracts/events/bindings.go | 160 +++++ .../contracts/events/combined-abi.json | 1 + .../v2/internal/contracts/events/contract.sol | 36 + .../contracts/nested_libraries/abi.json | 1 + .../contracts/nested_libraries/bindings.go | 486 +++++++++++++ .../nested_libraries/combined-abi.json | 1 + .../contracts/nested_libraries/contract.sol | 76 ++ .../contracts/solc_errors/bindings.go | 217 ++++++ .../contracts/solc_errors/combined-abi.json | 1 + .../contracts/solc_errors/contract.sol | 36 + .../contracts/uint256arrayreturn/bindings.go | 77 ++ .../uint256arrayreturn/combined-abi.json | 1 + .../contracts/uint256arrayreturn/contract.sol | 10 + accounts/abi/bind/v2/lib.go | 243 +++++++ accounts/abi/bind/v2/lib_test.go | 361 ++++++++++ accounts/abi/bind/{ => v2}/util.go | 32 +- accounts/abi/bind/{ => v2}/util_test.go | 13 +- cmd/abigen/main.go | 36 +- go.mod | 2 +- 60 files changed, 8305 insertions(+), 436 deletions(-) rename accounts/abi/{bind => abigen}/bind.go (75%) rename accounts/abi/{bind => abigen}/bind_test.go (99%) create mode 100644 accounts/abi/abigen/bindv2.go create mode 100644 accounts/abi/abigen/bindv2_test.go rename accounts/abi/{bind => abigen}/source.go.tpl (100%) create mode 100644 accounts/abi/abigen/source2.go.tpl rename accounts/abi/{bind => abigen}/template.go (64%) create mode 100644 accounts/abi/abigen/testdata/v2/callbackparam.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/crowdsale.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/dao.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/deeplynestedarray.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/empty.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/eventchecker.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/getter.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/identifiercollision.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/inputchecker.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/interactor.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/nameconflict.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/numericmethodname.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/outputchecker.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/overload.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/rangekeyword.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/slicer.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/structs-abi.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/structs.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/token.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/tuple.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/tupler.go.txt create mode 100644 accounts/abi/abigen/testdata/v2/underscorer.go.txt delete mode 100644 accounts/abi/bind/auth.go create mode 100644 accounts/abi/bind/old.go create mode 100644 accounts/abi/bind/v2/auth.go rename accounts/abi/bind/{ => v2}/backend.go (90%) rename accounts/abi/bind/{ => v2}/base.go (85%) rename accounts/abi/bind/{ => v2}/base_test.go (99%) create mode 100644 accounts/abi/bind/v2/dep_tree.go create mode 100644 accounts/abi/bind/v2/dep_tree_test.go create mode 100644 accounts/abi/bind/v2/generate_test.go create mode 100644 accounts/abi/bind/v2/internal/contracts/db/bindings.go create mode 100644 accounts/abi/bind/v2/internal/contracts/db/combined-abi.json create mode 100644 accounts/abi/bind/v2/internal/contracts/db/contract.sol create mode 100644 accounts/abi/bind/v2/internal/contracts/events/bindings.go create mode 100644 accounts/abi/bind/v2/internal/contracts/events/combined-abi.json create mode 100644 accounts/abi/bind/v2/internal/contracts/events/contract.sol create mode 100644 accounts/abi/bind/v2/internal/contracts/nested_libraries/abi.json create mode 100644 accounts/abi/bind/v2/internal/contracts/nested_libraries/bindings.go create mode 100644 accounts/abi/bind/v2/internal/contracts/nested_libraries/combined-abi.json create mode 100644 accounts/abi/bind/v2/internal/contracts/nested_libraries/contract.sol create mode 100644 accounts/abi/bind/v2/internal/contracts/solc_errors/bindings.go create mode 100644 accounts/abi/bind/v2/internal/contracts/solc_errors/combined-abi.json create mode 100644 accounts/abi/bind/v2/internal/contracts/solc_errors/contract.sol create mode 100644 accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/bindings.go create mode 100644 accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/combined-abi.json create mode 100644 accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/contract.sol create mode 100644 accounts/abi/bind/v2/lib.go create mode 100644 accounts/abi/bind/v2/lib_test.go rename accounts/abi/bind/{ => v2}/util.go (60%) rename accounts/abi/bind/{ => v2}/util_test.go (88%) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/abigen/bind.go similarity index 75% rename from accounts/abi/bind/bind.go rename to accounts/abi/abigen/bind.go index 71357c7a8c..56e5e214de 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/abigen/bind.go @@ -14,11 +14,11 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// Package bind generates Ethereum contract Go bindings. +// Package abigen generates Ethereum contract Go bindings. // // Detailed usage document and tutorial available on the go-ethereum Wiki page: -// https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts -package bind +// https://geth.ethereum.org/docs/developers/dapp-developer/native-bindings +package abigen import ( "bytes" @@ -33,13 +33,6 @@ import ( "github.com/ethereum/go-ethereum/log" ) -// Lang is a target programming language selector to generate bindings for. -type Lang int - -const ( - LangGo Lang = iota -) - func isKeyWord(arg string) bool { switch arg { case "break": @@ -81,7 +74,7 @@ func isKeyWord(arg string) bool { // to be used as is in client code, but rather as an intermediate struct which // enforces compile time type safety and naming convention as opposed to having to // manually maintain hard coded strings that break on runtime. -func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) { +func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, libs map[string]string, aliases map[string]string) (string, error) { var ( // contracts is the map of each individual contract requested binding contracts = make(map[string]*tmplContract) @@ -125,14 +118,14 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] for _, input := range evmABI.Constructor.Inputs { if hasStruct(input.Type) { - bindStructType[lang](input.Type, structs) + bindStructType(input.Type, structs) } } for _, original := range evmABI.Methods { // Normalize the method for capital cases and non-anonymous inputs/outputs normalized := original - normalizedName := methodNormalizer[lang](alias(aliases, original.Name)) + normalizedName := abi.ToCamelCase(alias(aliases, original.Name)) // Ensure there is no duplicated identifier var identifiers = callIdentifiers if !original.IsConstant() { @@ -159,17 +152,17 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } if hasStruct(input.Type) { - bindStructType[lang](input.Type, structs) + bindStructType(input.Type, structs) } } normalized.Outputs = make([]abi.Argument, len(original.Outputs)) copy(normalized.Outputs, original.Outputs) for j, output := range normalized.Outputs { if output.Name != "" { - normalized.Outputs[j].Name = capitalise(output.Name) + normalized.Outputs[j].Name = abi.ToCamelCase(output.Name) } if hasStruct(output.Type) { - bindStructType[lang](output.Type, structs) + bindStructType(output.Type, structs) } } // Append the methods to the call or transact lists @@ -188,7 +181,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] normalized := original // Ensure there is no duplicated identifier - normalizedName := methodNormalizer[lang](alias(aliases, original.Name)) + normalizedName := abi.ToCamelCase(alias(aliases, original.Name)) // Name shouldn't start with a digit. It will make the generated code invalid. if len(normalizedName) > 0 && unicode.IsDigit(rune(normalizedName[0])) { normalizedName = fmt.Sprintf("E%s", normalizedName) @@ -213,14 +206,14 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] // Event is a bit special, we need to define event struct in binding, // ensure there is no camel-case-style name conflict. for index := 0; ; index++ { - if !used[capitalise(normalized.Inputs[j].Name)] { - used[capitalise(normalized.Inputs[j].Name)] = true + if !used[abi.ToCamelCase(normalized.Inputs[j].Name)] { + used[abi.ToCamelCase(normalized.Inputs[j].Name)] = true break } normalized.Inputs[j].Name = fmt.Sprintf("%s%d", normalized.Inputs[j].Name, index) } if hasStruct(input.Type) { - bindStructType[lang](input.Type, structs) + bindStructType(input.Type, structs) } } // Append the event to the accumulator list @@ -233,8 +226,9 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] if evmABI.HasReceive() { receive = &tmplMethod{Original: evmABI.Receive} } + contracts[types[i]] = &tmplContract{ - Type: capitalise(types[i]), + Type: abi.ToCamelCase(types[i]), InputABI: strings.ReplaceAll(strippedABI, "\"", "\\\""), InputBin: strings.TrimPrefix(strings.TrimSpace(bytecodes[i]), "0x"), Constructor: evmABI.Constructor, @@ -245,6 +239,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] Events: events, Libraries: make(map[string]string), } + // Function 4-byte signatures are stored in the same sequence // as types, if available. if len(fsigs) > i { @@ -270,6 +265,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] _, ok := isLib[types[i]] contracts[types[i]].Library = ok } + // Generate the contract template data content and render it data := &tmplData{ Package: pkg, @@ -280,36 +276,25 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] buffer := new(bytes.Buffer) funcs := map[string]interface{}{ - "bindtype": bindType[lang], - "bindtopictype": bindTopicType[lang], - "namedtype": namedType[lang], - "capitalise": capitalise, + "bindtype": bindType, + "bindtopictype": bindTopicType, + "capitalise": abi.ToCamelCase, "decapitalise": decapitalise, } - tmpl := template.Must(template.New("").Funcs(funcs).Parse(tmplSource[lang])) + tmpl := template.Must(template.New("").Funcs(funcs).Parse(tmplSource)) if err := tmpl.Execute(buffer, data); err != nil { return "", err } - // For Go bindings pass the code through gofmt to clean it up - if lang == LangGo { - code, err := format.Source(buffer.Bytes()) - if err != nil { - return "", fmt.Errorf("%v\n%s", err, buffer) - } - return string(code), nil + // Pass the code through gofmt to clean it up + code, err := format.Source(buffer.Bytes()) + if err != nil { + return "", fmt.Errorf("%v\n%s", err, buffer) } - // For all others just return as is for now - return buffer.String(), nil + return string(code), nil } -// bindType is a set of type binders that convert Solidity types to some supported -// programming language types. -var bindType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ - LangGo: bindTypeGo, -} - -// bindBasicTypeGo converts basic solidity types(except array, slice and tuple) to Go ones. -func bindBasicTypeGo(kind abi.Type) string { +// bindBasicType converts basic solidity types(except array, slice and tuple) to Go ones. +func bindBasicType(kind abi.Type) string { switch kind.T { case abi.AddressTy: return "common.Address" @@ -332,32 +317,26 @@ func bindBasicTypeGo(kind abi.Type) string { } } -// bindTypeGo converts solidity types to Go ones. Since there is no clear mapping +// bindType converts solidity types to Go ones. Since there is no clear mapping // from all Solidity types to Go ones (e.g. uint17), those that cannot be exactly // mapped will use an upscaled type (e.g. BigDecimal). -func bindTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { +func bindType(kind abi.Type, structs map[string]*tmplStruct) string { switch kind.T { case abi.TupleTy: return structs[kind.TupleRawName+kind.String()].Name case abi.ArrayTy: - return fmt.Sprintf("[%d]", kind.Size) + bindTypeGo(*kind.Elem, structs) + return fmt.Sprintf("[%d]", kind.Size) + bindType(*kind.Elem, structs) case abi.SliceTy: - return "[]" + bindTypeGo(*kind.Elem, structs) + return "[]" + bindType(*kind.Elem, structs) default: - return bindBasicTypeGo(kind) + return bindBasicType(kind) } } -// bindTopicType is a set of type binders that convert Solidity types to some -// supported programming language topic types. -var bindTopicType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ - LangGo: bindTopicTypeGo, -} - -// bindTopicTypeGo converts a Solidity topic type to a Go one. It is almost the same +// bindTopicType converts a Solidity topic type to a Go one. It is almost the same // functionality as for simple types, but dynamic types get converted to hashes. -func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { - bound := bindTypeGo(kind, structs) +func bindTopicType(kind abi.Type, structs map[string]*tmplStruct) string { + bound := bindType(kind, structs) // todo(rjl493456442) according solidity documentation, indexed event // parameters that are not value types i.e. arrays and structs are not @@ -371,16 +350,10 @@ func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { return bound } -// bindStructType is a set of type binders that convert Solidity tuple types to some supported -// programming language struct definition. -var bindStructType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ - LangGo: bindStructTypeGo, -} - -// bindStructTypeGo converts a Solidity tuple type to a Go one and records the mapping -// in the given map. -// Notably, this function will resolve and record nested struct recursively. -func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { +// bindStructType converts a Solidity tuple type to a Go one and records the mapping +// in the given map. Notably, this function will resolve and record nested struct +// recursively. +func bindStructType(kind abi.Type, structs map[string]*tmplStruct) string { switch kind.T { case abi.TupleTy: // We compose a raw struct name and a canonical parameter expression @@ -398,16 +371,20 @@ func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { fields []*tmplField ) for i, elem := range kind.TupleElems { - name := capitalise(kind.TupleRawNames[i]) + name := abi.ToCamelCase(kind.TupleRawNames[i]) name = abi.ResolveNameConflict(name, func(s string) bool { return names[s] }) names[name] = true - fields = append(fields, &tmplField{Type: bindStructTypeGo(*elem, structs), Name: name, SolKind: *elem}) + fields = append(fields, &tmplField{ + Type: bindStructType(*elem, structs), + Name: name, + SolKind: *elem, + }) } name := kind.TupleRawName if name == "" { name = fmt.Sprintf("Struct%d", len(structs)) } - name = capitalise(name) + name = abi.ToCamelCase(name) structs[id] = &tmplStruct{ Name: name, @@ -415,20 +392,14 @@ func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { } return name case abi.ArrayTy: - return fmt.Sprintf("[%d]", kind.Size) + bindStructTypeGo(*kind.Elem, structs) + return fmt.Sprintf("[%d]", kind.Size) + bindStructType(*kind.Elem, structs) case abi.SliceTy: - return "[]" + bindStructTypeGo(*kind.Elem, structs) + return "[]" + bindStructType(*kind.Elem, structs) default: - return bindBasicTypeGo(kind) + return bindBasicType(kind) } } -// namedType is a set of functions that transform language specific types to -// named versions that may be used inside method names. -var namedType = map[Lang]func(string, abi.Type) string{ - LangGo: func(string, abi.Type) string { panic("this shouldn't be needed") }, -} - // alias returns an alias of the given string based on the aliasing rules // or returns itself if no rule is matched. func alias(aliases map[string]string, n string) string { @@ -438,21 +409,11 @@ func alias(aliases map[string]string, n string) string { return n } -// methodNormalizer is a name transformer that modifies Solidity method names to -// conform to target language naming conventions. -var methodNormalizer = map[Lang]func(string) string{ - LangGo: abi.ToCamelCase, -} - -// capitalise makes a camel-case string which starts with an upper case character. -var capitalise = abi.ToCamelCase - // decapitalise makes a camel-case string which starts with a lower case character. func decapitalise(input string) string { if len(input) == 0 { return input } - goForm := abi.ToCamelCase(input) return strings.ToLower(goForm[:1]) + goForm[1:] } @@ -471,7 +432,7 @@ func structured(args abi.Arguments) bool { } // If the field name is empty when normalized or collides (var, Var, _var, _Var), // we can't organize into a struct - field := capitalise(out.Name) + field := abi.ToCamelCase(out.Name) if field == "" || exists[field] { return false } diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/abigen/bind_test.go similarity index 99% rename from accounts/abi/bind/bind_test.go rename to accounts/abi/abigen/bind_test.go index a390a3c47c..3871560912 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/abigen/bind_test.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 bind +package abigen import ( "fmt" @@ -2072,20 +2072,22 @@ var bindTests = []struct { // Tests that packages generated by the binder can be successfully compiled and // the requested tester run against it. -func TestGolangBindings(t *testing.T) { +func TestBindings(t *testing.T) { t.Parallel() // Skip the test if no Go command can be found gocmd := runtime.GOROOT() + "/bin/go" if !common.FileExist(gocmd) { t.Skip("go sdk not found for testing") } - // Create a temporary workspace for the test suite - ws := t.TempDir() - pkg := filepath.Join(ws, "bindtest") + // Create a temporary workspace for the test suite + path := t.TempDir() + pkg := filepath.Join(path, "bindtest") if err := os.MkdirAll(pkg, 0700); err != nil { t.Fatalf("failed to create package: %v", err) } + t.Log("tmpdir", pkg) + // Generate the test suite for all the contracts for i, tt := range bindTests { t.Run(tt.name, func(t *testing.T) { @@ -2096,7 +2098,7 @@ func TestGolangBindings(t *testing.T) { types = []string{tt.name} } // Generate the binding and create a Go source file in the workspace - bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", LangGo, tt.libs, tt.aliases) + bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", tt.libs, tt.aliases) if err != nil { t.Fatalf("test %d: failed to generate binding: %v", i, err) } diff --git a/accounts/abi/abigen/bindv2.go b/accounts/abi/abigen/bindv2.go new file mode 100644 index 0000000000..ef4b769bb4 --- /dev/null +++ b/accounts/abi/abigen/bindv2.go @@ -0,0 +1,373 @@ +// 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 abigen + +import ( + "bytes" + "fmt" + "go/format" + "reflect" + "regexp" + "slices" + "sort" + "strings" + "text/template" + "unicode" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +// underlyingBindType returns a string representation of the Go type +// that corresponds to the given ABI type, panicking if it is not a +// pointer. +func underlyingBindType(typ abi.Type) string { + goType := typ.GetType() + if goType.Kind() != reflect.Pointer { + panic("trying to retrieve underlying bind type of non-pointer type.") + } + return goType.Elem().String() +} + +// isPointerType returns true if the underlying type is a pointer. +func isPointerType(typ abi.Type) bool { + return typ.GetType().Kind() == reflect.Pointer +} + +// OLD: +// binder is used during the conversion of an ABI definition into Go bindings +// (as part of the execution of BindV2). In contrast to contractBinder, binder +// contains binding-generation-state that is shared between contracts: +// +// a global struct map of structs emitted by all contracts is tracked and expanded. +// Structs generated in the bindings are not prefixed with the contract name +// that uses them (to keep the generated bindings less verbose). +// +// This contrasts to other per-contract state (constructor/method/event/error, +// pack/unpack methods) which are guaranteed to be unique because of their +// association with the uniquely-named owning contract (whether prefixed in the +// generated symbol name, or as a member method on a contract struct). +// +// In addition, binder contains the input alias map. In BindV2, a binder is +// instantiated to produce a set of tmplContractV2 and tmplStruct objects from +// the provided ABI definition. These are used as part of the input to rendering +// the binding template. + +// NEW: +// binder is used to translate an ABI definition into a set of data-structures +// that will be used to render the template and produce Go bindings. This can +// be thought of as the "backend" that sanitizes the ABI definition to a format +// that can be directly rendered with minimal complexity in the template. +// +// The input data to the template rendering consists of: +// - the set of all contracts requested for binding, each containing +// methods/events/errors to emit pack/unpack methods for. +// - the set of structures defined by the contracts, and created +// as part of the binding process. +type binder struct { + // contracts is the map of each individual contract requested binding. + // It is keyed by the contract name provided in the ABI definition. + contracts map[string]*tmplContractV2 + + // structs is the map of all emitted structs from contracts being bound. + // it is keyed by a unique identifier generated from the name of the owning contract + // and the solidity type signature of the struct + structs map[string]*tmplStruct + + // aliases is a map for renaming instances of named events/functions/errors + // to specified values. it is keyed by source symbol name, and values are + // what the replacement name should be. + aliases map[string]string +} + +// BindStructType registers the type to be emitted as a struct in the +// bindings. +func (b *binder) BindStructType(typ abi.Type) { + bindStructType(typ, b.structs) +} + +// contractBinder holds state for binding of a single contract. It is a type +// registry for compiling maps of identifiers that will be emitted in generated +// bindings. +type contractBinder struct { + binder *binder + + // all maps are keyed by the original (non-normalized) name of the symbol in question + // from the provided ABI definition. + calls map[string]*tmplMethod + events map[string]*tmplEvent + errors map[string]*tmplError + callIdentifiers map[string]bool + eventIdentifiers map[string]bool + errorIdentifiers map[string]bool +} + +func newContractBinder(binder *binder) *contractBinder { + return &contractBinder{ + binder, + make(map[string]*tmplMethod), + make(map[string]*tmplEvent), + make(map[string]*tmplError), + make(map[string]bool), + make(map[string]bool), + make(map[string]bool), + } +} + +// registerIdentifier applies alias renaming, name normalization (conversion +// from snake to camel-case), and registers the normalized name in the specified identifier map. +// It returns an error if the normalized name already exists in the map. +func (cb *contractBinder) registerIdentifier(identifiers map[string]bool, original string) (normalized string, err error) { + normalized = abi.ToCamelCase(alias(cb.binder.aliases, original)) + + // Name shouldn't start with a digit. It will make the generated code invalid. + if len(normalized) > 0 && unicode.IsDigit(rune(normalized[0])) { + normalized = fmt.Sprintf("E%s", normalized) + normalized = abi.ResolveNameConflict(normalized, func(name string) bool { + _, ok := identifiers[name] + return ok + }) + } + if _, ok := identifiers[normalized]; ok { + return "", fmt.Errorf("duplicate symbol '%s'", normalized) + } + identifiers[normalized] = true + return normalized, nil +} + +// bindMethod registers a method to be emitted in the bindings. The name, inputs +// and outputs are normalized. If any inputs are struct-type their structs are +// registered to be emitted in the bindings. Any methods that return more than +// one output have their results gathered into a struct. +func (cb *contractBinder) bindMethod(original abi.Method) error { + normalized := original + normalizedName, err := cb.registerIdentifier(cb.callIdentifiers, original.Name) + if err != nil { + return err + } + normalized.Name = normalizedName + + normalized.Inputs = normalizeArgs(original.Inputs) + for _, input := range normalized.Inputs { + if hasStruct(input.Type) { + cb.binder.BindStructType(input.Type) + } + } + normalized.Outputs = normalizeArgs(original.Outputs) + for _, output := range normalized.Outputs { + if hasStruct(output.Type) { + cb.binder.BindStructType(output.Type) + } + } + + var isStructured bool + // If the call returns multiple values, gather them into a struct + if len(normalized.Outputs) > 1 { + isStructured = true + } + cb.calls[original.Name] = &tmplMethod{ + Original: original, + Normalized: normalized, + Structured: isStructured, + } + return nil +} + +// normalize a set of arguments by stripping underscores, giving a generic name +// in the case where the arg name collides with a reserved Go keyword, and finally +// converting to camel-case. +func normalizeArgs(args abi.Arguments) abi.Arguments { + args = slices.Clone(args) + used := make(map[string]bool) + + for i, input := range args { + if isKeyWord(input.Name) { + args[i].Name = fmt.Sprintf("arg%d", i) + } + args[i].Name = abi.ToCamelCase(args[i].Name) + if args[i].Name == "" { + args[i].Name = fmt.Sprintf("arg%d", i) + } else { + args[i].Name = strings.ToLower(args[i].Name[:1]) + args[i].Name[1:] + } + + for index := 0; ; index++ { + if !used[args[i].Name] { + used[args[i].Name] = true + break + } + args[i].Name = fmt.Sprintf("%s%d", args[i].Name, index) + } + } + return args +} + +// normalizeErrorOrEventFields normalizes errors/events for emitting through +// bindings: Any anonymous fields are given generated names. +func (cb *contractBinder) normalizeErrorOrEventFields(originalInputs abi.Arguments) abi.Arguments { + normalizedArguments := normalizeArgs(originalInputs) + for _, input := range normalizedArguments { + if hasStruct(input.Type) { + cb.binder.BindStructType(input.Type) + } + } + return normalizedArguments +} + +// bindEvent normalizes an event and registers it to be emitted in the bindings. +func (cb *contractBinder) bindEvent(original abi.Event) error { + // Skip anonymous events as they don't support explicit filtering + if original.Anonymous { + return nil + } + normalizedName, err := cb.registerIdentifier(cb.eventIdentifiers, original.Name) + if err != nil { + return err + } + + normalized := original + normalized.Name = normalizedName + normalized.Inputs = cb.normalizeErrorOrEventFields(original.Inputs) + cb.events[original.Name] = &tmplEvent{Original: original, Normalized: normalized} + return nil +} + +// bindError normalizes an error and registers it to be emitted in the bindings. +func (cb *contractBinder) bindError(original abi.Error) error { + normalizedName, err := cb.registerIdentifier(cb.errorIdentifiers, original.Name) + if err != nil { + return err + } + + normalized := original + normalized.Name = normalizedName + normalized.Inputs = cb.normalizeErrorOrEventFields(original.Inputs) + cb.errors[original.Name] = &tmplError{Original: original, Normalized: normalized} + return nil +} + +// parseLibraryDeps extracts references to library dependencies from the unlinked +// hex string deployment bytecode. +func parseLibraryDeps(unlinkedCode string) (res []string) { + reMatchSpecificPattern, err := regexp.Compile(`__\$([a-f0-9]+)\$__`) + if err != nil { + panic(err) + } + for _, match := range reMatchSpecificPattern.FindAllStringSubmatch(unlinkedCode, -1) { + res = append(res, match[1]) + } + return res +} + +// iterSorted iterates the map in the lexicographic order of the keys calling +// onItem on each. If the callback returns an error, iteration is halted and +// the error is returned from iterSorted. +func iterSorted[V any](inp map[string]V, onItem func(string, V) error) error { + var sortedKeys []string + for key := range inp { + sortedKeys = append(sortedKeys, key) + } + sort.Strings(sortedKeys) + + for _, key := range sortedKeys { + if err := onItem(key, inp[key]); err != nil { + return err + } + } + return nil +} + +// BindV2 generates a Go wrapper around a contract ABI. This wrapper isn't meant +// to be used as is in client code, but rather as an intermediate struct which +// enforces compile time type safety and naming convention as opposed to having to +// manually maintain hard coded strings that break on runtime. +func BindV2(types []string, abis []string, bytecodes []string, pkg string, libs map[string]string, aliases map[string]string) (string, error) { + b := binder{ + contracts: make(map[string]*tmplContractV2), + structs: make(map[string]*tmplStruct), + aliases: aliases, + } + for i := 0; i < len(types); i++ { + // Parse the actual ABI to generate the binding for + evmABI, err := abi.JSON(strings.NewReader(abis[i])) + if err != nil { + return "", err + } + + for _, input := range evmABI.Constructor.Inputs { + if hasStruct(input.Type) { + bindStructType(input.Type, b.structs) + } + } + + cb := newContractBinder(&b) + err = iterSorted(evmABI.Methods, func(_ string, original abi.Method) error { + return cb.bindMethod(original) + }) + if err != nil { + return "", err + } + err = iterSorted(evmABI.Events, func(_ string, original abi.Event) error { + return cb.bindEvent(original) + }) + if err != nil { + return "", err + } + err = iterSorted(evmABI.Errors, func(_ string, original abi.Error) error { + return cb.bindError(original) + }) + if err != nil { + return "", err + } + b.contracts[types[i]] = newTmplContractV2(types[i], abis[i], bytecodes[i], evmABI.Constructor, cb) + } + + invertedLibs := make(map[string]string) + for pattern, name := range libs { + invertedLibs[name] = pattern + } + data := tmplDataV2{ + Package: pkg, + Contracts: b.contracts, + Libraries: invertedLibs, + Structs: b.structs, + } + + for typ, contract := range data.Contracts { + for _, depPattern := range parseLibraryDeps(contract.InputBin) { + data.Contracts[typ].Libraries[libs[depPattern]] = depPattern + } + } + buffer := new(bytes.Buffer) + funcs := map[string]interface{}{ + "bindtype": bindType, + "bindtopictype": bindTopicType, + "capitalise": abi.ToCamelCase, + "decapitalise": decapitalise, + "ispointertype": isPointerType, + "underlyingbindtype": underlyingBindType, + } + tmpl := template.Must(template.New("").Funcs(funcs).Parse(tmplSourceV2)) + if err := tmpl.Execute(buffer, data); err != nil { + return "", err + } + // Pass the code through gofmt to clean it up + code, err := format.Source(buffer.Bytes()) + if err != nil { + return "", fmt.Errorf("%v\n%s", err, buffer) + } + return string(code), nil +} diff --git a/accounts/abi/abigen/bindv2_test.go b/accounts/abi/abigen/bindv2_test.go new file mode 100644 index 0000000000..2756ba0835 --- /dev/null +++ b/accounts/abi/abigen/bindv2_test.go @@ -0,0 +1,342 @@ +// 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 abigen + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/crypto" +) + +type bindV2Test struct { + name string + abis []string + bytecodes []string + types []string + aliases map[string]string +} + +func bindCombinedJSON(test *bindV2Test) (string, error) { + var ( + abis []string + bins []string + types []string + ) + libs := make(map[string]string) + for i := 0; i < len(test.types); i++ { + // fully qualified name is of the form : + typeName := test.types[i] + abis = append(abis, test.abis[i]) + bins = append(bins, test.bytecodes[i]) + types = append(types, typeName) + + // Derive the library placeholder which is a 34 character prefix of the + // hex encoding of the keccak256 hash of the fully qualified library name. + // Note that the fully qualified library name is the path of its source + // file and the library name separated by ":". + libPattern := crypto.Keccak256Hash([]byte(typeName)).String()[2:36] // the first 2 chars are 0x + libs[libPattern] = typeName + } + if test.aliases == nil { + test.aliases = make(map[string]string) + } + code, err := BindV2(types, abis, bins, "bindtests", libs, test.aliases) + if err != nil { + return "", fmt.Errorf("error creating bindings: %v", err) + } + return code, nil +} + +var combinedJSONBindTestsV2 = []bindV2Test{ + { + "Empty", + []string{`[]`}, + []string{`606060405260068060106000396000f3606060405200`}, + nil, + nil, + }, + { + "Token", + []string{`[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"spentAllowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"decimalUnits","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`}, + []string{`60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056`}, + nil, + nil, + }, + { + "Crowdsale", + []string{`[{"constant":false,"inputs":[],"name":"checkGoalReached","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"deadline","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"tokenReward","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"fundingGoal","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"funders","outputs":[{"name":"addr","type":"address"},{"name":"amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingGoalInEthers","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"etherCostOfEachToken","type":"uint256"},{"name":"addressOfTokenUsedAsReward","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"backer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isContribution","type":"bool"}],"name":"FundTransfer","type":"event"}]`}, + []string{`606060408190526007805460ff1916905560a0806105a883396101006040529051608051915160c05160e05160008054600160a060020a03199081169095178155670de0b6b3a7640000958602600155603c9093024201600355930260045560058054909216909217905561052f90819061007990396000f36060604052361561006c5760e060020a600035046301cb3b20811461008257806329dcb0cf1461014457806338af3eed1461014d5780636e66f6e91461015f5780637a3a0e84146101715780637b3e5e7b1461017a578063a035b1fe14610183578063dc0d3dff1461018c575b61020060075460009060ff161561032357610002565b61020060035460009042106103205760025460015490106103cb576002548154600160a060020a0316908290606082818181858883f150915460025460408051600160a060020a039390931683526020830191909152818101869052517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6945090819003909201919050a15b60405160008054600160a060020a039081169230909116319082818181858883f150506007805460ff1916600117905550505050565b6103a160035481565b6103ab600054600160a060020a031681565b6103ab600554600160a060020a031681565b6103a160015481565b6103a160025481565b6103a160045481565b6103be60043560068054829081101561000257506000526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101547ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409190910154600160a060020a03919091169082565b005b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a815481600160a060020a030219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a9004600160a060020a0316600160a060020a031663a9059cbb3360046000505484046040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505060408051600160a060020a03331681526020810184905260018183015290517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf692509081900360600190a15b50565b5060a0604052336060908152346080819052600680546001810180835592939282908280158290116102025760020281600202836000526020600020918201910161020291905b8082111561039d57805473ffffffffffffffffffffffffffffffffffffffff19168155600060019190910190815561036a565b5090565b6060908152602090f35b600160a060020a03166060908152602090f35b6060918252608052604090f35b5b60065481101561010e576006805482908110156100025760009182526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600680549254600160a060020a0316928490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460405190915082818181858883f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf660066000508281548110156100025760008290526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01548154600160a060020a039190911691908490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460408051600160a060020a0394909416845260208401919091526000838201525191829003606001919050a16001016103cc56`}, + nil, + nil, + }, + { + "DAO", + []string{`[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"executed","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"numberOfVotes","type":"uint256"},{"name":"currentResult","type":"int256"},{"name":"proposalHash","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberId","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numProposals","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"members","outputs":[{"name":"member","type":"address"},{"name":"canVote","type":"bool"},{"name":"name","type":"string"},{"name":"memberSince","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"debatingPeriodInMinutes","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minimumQuorum","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"targetMember","type":"address"},{"name":"canVote","type":"bool"},{"name":"memberName","type":"string"}],"name":"changeMembership","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"majorityMargin","outputs":[{"name":"","type":"int256"}],"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"JobDescription","type":"string"},{"name":"transactionBytecode","type":"bytes"}],"name":"newProposal","outputs":[{"name":"proposalID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"}],"name":"changeVotingRules","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"supportsProposal","type":"bool"},{"name":"justificationText","type":"string"}],"name":"vote","outputs":[{"name":"voteID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"codeChecksOut","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"type":"function"},{"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"},{"name":"congressLeader","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"justification","type":"string"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"int256"},{"indexed":false,"name":"quorum","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"member","type":"address"},{"indexed":false,"name":"isMember","type":"bool"}],"name":"MembershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minimumQuorum","type":"uint256"},{"indexed":false,"name":"debatingPeriodInMinutes","type":"uint256"},{"indexed":false,"name":"majorityMargin","type":"int256"}],"name":"ChangeOfRules","type":"event"}]`}, + []string{`606060405260405160808061145f833960e06040529051905160a05160c05160008054600160a060020a03191633179055600184815560028490556003839055600780549182018082558280158290116100b8576003028160030283600052602060002091820191016100b891906101c8565b50506060919091015160029190910155600160a060020a0381166000146100a65760008054600160a060020a031916821790555b505050506111f18061026e6000396000f35b505060408051608081018252600080825260208281018290528351908101845281815292820192909252426060820152600780549194509250811015610002579081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889050815181546020848101517401000000000000000000000000000000000000000002600160a060020a03199290921690921760a060020a60ff021916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f9081018390048201949192919091019083901061023e57805160ff19168380011785555b50610072929150610226565b5050600060028201556001015b8082111561023a578054600160a860020a031916815560018181018054600080835592600290821615610100026000190190911604601f81901061020c57506101bb565b601f0160209004906000526020600020908101906101bb91905b8082111561023a5760008155600101610226565b5090565b828001600101855582156101af579182015b828111156101af57825182600050559160200191906001019061025056606060405236156100b95760e060020a6000350463013cf08b81146100bb578063237e9492146101285780633910682114610281578063400e3949146102995780635daf08ca146102a257806369bd34361461032f5780638160f0b5146103385780638da5cb5b146103415780639644fcbd14610353578063aa02a90f146103be578063b1050da5146103c7578063bcca1fd3146104b5578063d3c0715b146104dc578063eceb29451461058d578063f2fde38b1461067b575b005b61069c6004356004805482908110156100025790600052602060002090600a02016000506005810154815460018301546003840154600485015460068601546007870154600160a060020a03959095169750929560020194919360ff828116946101009093041692919089565b60408051602060248035600481810135601f81018590048502860185019096528585526107759581359591946044949293909201918190840183828082843750949650505050505050600060006004600050848154811015610002575090527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e600a8402908101547f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101904210806101e65750600481015460ff165b8061026757508060000160009054906101000a9004600160a060020a03168160010160005054846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816007016000505414155b8061027757506001546005820154105b1561109257610002565b61077560043560066020526000908152604090205481565b61077560055481565b61078760043560078054829081101561000257506000526003026000805160206111d18339815191528101547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a820154600160a060020a0382169260a060020a90920460ff16917fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689019084565b61077560025481565b61077560015481565b610830600054600160a060020a031681565b604080516020604435600481810135601f81018490048402850184019095528484526100b9948135946024803595939460649492939101918190840183828082843750949650505050505050600080548190600160a060020a03908116339091161461084d57610002565b61077560035481565b604080516020604435600481810135601f8101849004840285018401909552848452610775948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024909101945090925082915084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806104ab5750604081205460078054909190811015610002579082526003026000805160206111d1833981519152015460a060020a900460ff16155b15610ce557610002565b6100b960043560243560443560005433600160a060020a03908116911614610b1857610002565b604080516020604435600481810135601f810184900484028501840190955284845261077594813594602480359593946064949293910191819084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806105835750604081205460078054909190811015610002579082526003026000805160206111d18339815191520181505460a060020a900460ff16155b15610f1d57610002565b604080516020606435600481810135601f81018490048402850184019095528484526107759481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600460005086815481101561000257908252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01815090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005054149150610cdc565b6100b960043560005433600160a060020a03908116911614610f0857610002565b604051808a600160a060020a031681526020018981526020018060200188815260200187815260200186815260200185815260200184815260200183815260200182810382528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561075e5780601f106107335761010080835404028352916020019161075e565b820191906000526020600020905b81548152906001019060200180831161074157829003601f168201915b50509a505050505050505050505060405180910390f35b60408051918252519081900360200190f35b60408051600160a060020a038616815260208101859052606081018390526080918101828152845460026001821615610100026000190190911604928201839052909160a08301908590801561081e5780601f106107f35761010080835404028352916020019161081e565b820191906000526020600020905b81548152906001019060200180831161080157829003601f168201915b50509550505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b600160a060020a03851660009081526006602052604081205414156108a957604060002060078054918290556001820180825582801582901161095c5760030281600302836000526020600020918201910161095c9190610a4f565b600160a060020a03851660009081526006602052604090205460078054919350908390811015610002575060005250600381026000805160206111d183398151915201805474ff0000000000000000000000000000000000000000191660a060020a85021781555b60408051600160a060020a03871681526020810186905281517f27b022af4a8347100c7a041ce5ccf8e14d644ff05de696315196faae8cd50c9b929181900390910190a15050505050565b505050915081506080604051908101604052808681526020018581526020018481526020014281526020015060076000508381548110156100025790600052602060002090600302016000508151815460208481015160a060020a02600160a060020a03199290921690921774ff00000000000000000000000000000000000000001916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f90810183900482019491929190910190839010610ad357805160ff19168380011785555b50610b03929150610abb565b5050600060028201556001015b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610aa15750610a42565b601f016020900490600052602060002090810190610a4291905b80821115610acf5760008155600101610abb565b5090565b82800160010185558215610a36579182015b82811115610a36578251826000505591602001919060010190610ae5565b50506060919091015160029190910155610911565b600183905560028290556003819055604080518481526020810184905280820183905290517fa439d3fa452be5e0e1e24a8145e715f4fd8b9c08c96a42fd82a855a85e5d57de9181900360600190a1505050565b50508585846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005081905550600260005054603c024201816003016000508190555060008160040160006101000a81548160ff0219169083021790555060008160040160016101000a81548160ff02191690830217905550600081600501600050819055507f646fec02522b41e7125cfc859a64fd4f4cefd5dc3b6237ca0abe251ded1fa881828787876040518085815260200184600160a060020a03168152602001838152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610cc45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600182016005555b50949350505050565b6004805460018101808355909190828015829011610d1c57600a0281600a028360005260206000209182019101610d1c9190610db8565b505060048054929450918491508110156100025790600052602060002090600a02016000508054600160a060020a031916871781556001818101879055855160028381018054600082815260209081902096975091959481161561010002600019011691909104601f90810182900484019391890190839010610ed857805160ff19168380011785555b50610b6c929150610abb565b50506001015b80821115610acf578054600160a060020a03191681556000600182810182905560028381018054848255909281161561010002600019011604601f819010610e9c57505b5060006003830181905560048301805461ffff191690556005830181905560068301819055600783018190556008830180548282559082526020909120610db2916002028101905b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610eba57505b5050600101610e44565b601f016020900490600052602060002090810190610dfc9190610abb565b601f016020900490600052602060002090810190610e929190610abb565b82800160010185558215610da6579182015b82811115610da6578251826000505591602001919060010190610eea565b60008054600160a060020a0319168217905550565b600480548690811015610002576000918252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01905033600160a060020a0316600090815260098201602052604090205490915060ff1660011415610f8457610002565b33600160a060020a031660009081526009820160205260409020805460ff1916600190811790915560058201805490910190558315610fcd576006810180546001019055610fda565b6006810180546000190190555b7fc34f869b7ff431b034b7b9aea9822dac189a685e0b015c7d1be3add3f89128e8858533866040518085815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561107a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b6006810154600354901315611158578060000160009054906101000a9004600160a060020a0316600160a060020a03168160010160005054670de0b6b3a76400000284604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111225780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f15050505060048101805460ff191660011761ff00191661010017905561116d565b60048101805460ff191660011761ff00191690555b60068101546005820154600483015460408051888152602081019490945283810192909252610100900460ff166060830152517fd220b7272a8b6d0d7d6bcdace67b936a8f175e6d5c1b3ee438b72256b32ab3af9181900360800190a1509291505056a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688`}, + nil, + nil, + }, + { + "InputChecker", + []string{` + [ + {"type":"function","name":"noInput","constant":true,"inputs":[],"outputs":[]}, + {"type":"function","name":"namedInput","constant":true,"inputs":[{"name":"str","type":"string"}],"outputs":[]}, + {"type":"function","name":"anonInput","constant":true,"inputs":[{"name":"","type":"string"}],"outputs":[]}, + {"type":"function","name":"namedInputs","constant":true,"inputs":[{"name":"str1","type":"string"},{"name":"str2","type":"string"}],"outputs":[]}, + {"type":"function","name":"anonInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"","type":"string"}],"outputs":[]}, + {"type":"function","name":"mixedInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"str","type":"string"}],"outputs":[]} + ] + `}, + []string{``}, + nil, + nil, + }, + { + "OutputChecker", + []string{` + [ + {"type":"function","name":"noOutput","constant":true,"inputs":[],"outputs":[]}, + {"type":"function","name":"namedOutput","constant":true,"inputs":[],"outputs":[{"name":"str","type":"string"}]}, + {"type":"function","name":"anonOutput","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"}]}, + {"type":"function","name":"namedOutputs","constant":true,"inputs":[],"outputs":[{"name":"str1","type":"string"},{"name":"str2","type":"string"}]}, + {"type":"function","name":"collidingOutputs","constant":true,"inputs":[],"outputs":[{"name":"str","type":"string"},{"name":"Str","type":"string"}]}, + {"type":"function","name":"anonOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"","type":"string"}]}, + {"type":"function","name":"mixedOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"str","type":"string"}]} + ] + `}, + []string{``}, + nil, + nil, + }, + { + "EventChecker", + []string{` + [ + {"type":"event","name":"empty","inputs":[]}, + {"type":"event","name":"indexed","inputs":[{"name":"addr","type":"address","indexed":true},{"name":"num","type":"int256","indexed":true}]}, + {"type":"event","name":"mixed","inputs":[{"name":"addr","type":"address","indexed":true},{"name":"num","type":"int256"}]}, + {"type":"event","name":"anonymous","anonymous":true,"inputs":[]}, + {"type":"event","name":"dynamic","inputs":[{"name":"idxStr","type":"string","indexed":true},{"name":"idxDat","type":"bytes","indexed":true},{"name":"str","type":"string"},{"name":"dat","type":"bytes"}]}, + {"type":"event","name":"unnamed","inputs":[{"name":"","type":"uint256","indexed": true},{"name":"","type":"uint256","indexed":true}]} + ] + `}, + []string{``}, + nil, + nil, + }, + { + "Interactor", + []string{`[{"constant":true,"inputs":[],"name":"transactString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[],"name":"deployString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"str","type":"string"}],"name":"transact","outputs":[],"type":"function"},{"inputs":[{"name":"str","type":"string"}],"type":"constructor"}]`}, + []string{`6060604052604051610328380380610328833981016040528051018060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10608d57805160ff19168380011785555b50607c9291505b8082111560ba57838155600101606b565b50505061026a806100be6000396000f35b828001600101855582156064579182015b828111156064578251826000505591602001919060010190609e565b509056606060405260e060020a60003504630d86a0e181146100315780636874e8091461008d578063d736c513146100ea575b005b610190600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b61019060008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b60206004803580820135601f81018490049093026080908101604052606084815261002f946024939192918401918190838280828437509496505050505050508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023157805160ff19168380011785555b506102619291505b808211156102665760008155830161017d565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161020c57829003601f168201915b505050505081565b82800160010185558215610175579182015b82811115610175578251826000505591602001919060010190610243565b505050565b509056`}, + nil, + nil, + }, + { + "Getter", + []string{`[{"constant":true,"inputs":[],"name":"getter","outputs":[{"name":"","type":"string"},{"name":"","type":"int256"},{"name":"","type":"bytes32"}],"type":"function"}]`}, + []string{`606060405260dc8060106000396000f3606060405260e060020a6000350463993a04b78114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`}, + nil, + nil, + }, + { + "Tupler", + []string{`[{"constant":true,"inputs":[],"name":"tuple","outputs":[{"name":"a","type":"string"},{"name":"b","type":"int256"},{"name":"c","type":"bytes32"}],"type":"function"}]`}, + []string{`606060405260dc8060106000396000f3606060405260e060020a60003504633175aae28114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`}, + nil, + nil, + }, + { + "Slicer", + []string{`[{"constant":true,"inputs":[{"name":"input","type":"address[]"}],"name":"echoAddresses","outputs":[{"name":"output","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"uint24[23]"}],"name":"echoFancyInts","outputs":[{"name":"output","type":"uint24[23]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"int256[]"}],"name":"echoInts","outputs":[{"name":"output","type":"int256[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"bool[]"}],"name":"echoBools","outputs":[{"name":"output","type":"bool[]"}],"type":"function"}]`}, + []string{`606060405261015c806100126000396000f3606060405260e060020a6000350463be1127a3811461003c578063d88becc014610092578063e15a3db71461003c578063f637e5891461003c575b005b604080516020600480358082013583810285810185019096528085526100ee959294602494909392850192829185019084908082843750949650505050505050604080516020810190915260009052805b919050565b604080516102e0818101909252610138916004916102e491839060179083908390808284375090955050505050506102e0604051908101604052806017905b60008152602001906001900390816100d15790505081905061008d565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b60405180826102e0808381846000600461015cf15090500191505060405180910390f3`}, + nil, + nil, + }, + { + "Structs", + []string{`[{"inputs":[],"name":"F","outputs":[{"components":[{"internalType":"bytes32","name":"B","type":"bytes32"}],"internalType":"structStructs.A[]","name":"a","type":"tuple[]"},{"internalType":"uint256[]","name":"c","type":"uint256[]"},{"internalType":"bool[]","name":"d","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"G","outputs":[{"components":[{"internalType":"bytes32","name":"B","type":"bytes32"}],"internalType":"structStructs.A[]","name":"a","type":"tuple[]"}],"stateMutability":"view","type":"function"}]`}, + []string{`608060405234801561001057600080fd5b50610278806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806328811f591461003b5780636fecb6231461005b575b600080fd5b610043610070565b604051610052939291906101a0565b60405180910390f35b6100636100d6565b6040516100529190610186565b604080516002808252606082810190935282918291829190816020015b610095610131565b81526020019060019003908161008d575050805190915061026960611b9082906000906100be57fe5b60209081029190910101515293606093508392509050565b6040805160028082526060828101909352829190816020015b6100f7610131565b8152602001906001900390816100ef575050805190915061026960611b90829060009061012057fe5b602090810291909101015152905090565b60408051602081019091526000815290565b815260200190565b6000815180845260208085019450808401835b8381101561017b578151518752958201959082019060010161015e565b509495945050505050565b600060208252610199602083018461014b565b9392505050565b6000606082526101b3606083018661014b565b6020838203818501528186516101c98185610239565b91508288019350845b818110156101f3576101e5838651610143565b9484019492506001016101d2565b505084810360408601528551808252908201925081860190845b8181101561022b57825115158552938301939183019160010161020d565b509298975050505050505050565b9081526020019056fea2646970667358221220eb85327e285def14230424c52893aebecec1e387a50bb6b75fc4fdbed647f45f64736f6c63430006050033`}, + nil, + nil, + }, + { + `Underscorer`, + []string{`[{"constant":true,"inputs":[],"name":"LowerUpperCollision","outputs":[{"name":"_res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_under_scored_func","outputs":[{"name":"_int","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UnderscoredOutput","outputs":[{"name":"_int","type":"int256"},{"name":"_string","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperLowerCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"AllPurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"__","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperUpperCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LowerLowerCollision","outputs":[{"name":"_res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"}]`}, []string{`6060604052341561000f57600080fd5b6103858061001e6000396000f30060606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461009357806346546dbe146100c357806367e6633d146100ec5780639df4848514610181578063af7486ab146101b1578063b564b34d146101e1578063e02ab24d14610211578063e409ca4514610241575b600080fd5b341561009e57600080fd5b6100a6610271565b604051808381526020018281526020019250505060405180910390f35b34156100ce57600080fd5b6100d6610286565b6040518082815260200191505060405180910390f35b34156100f757600080fd5b6100ff61028e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561014557808201518184015260208101905061012a565b50505050905090810190601f1680156101725780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561018c57600080fd5b6101946102dc565b604051808381526020018281526020019250505060405180910390f35b34156101bc57600080fd5b6101c46102f1565b604051808381526020018281526020019250505060405180910390f35b34156101ec57600080fd5b6101f4610306565b604051808381526020018281526020019250505060405180910390f35b341561021c57600080fd5b61022461031b565b604051808381526020018281526020019250505060405180910390f35b341561024c57600080fd5b610254610330565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b600080905090565b6000610298610345565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a72305820d1a53d9de9d1e3d55cb3dc591900b63c4f1ded79114f7b79b332684840e186a40029`}, + nil, + nil, + }, + { + `DeeplyNestedArray`, + []string{`[{"constant":false,"inputs":[{"name":"arr","type":"uint64[3][4][5]"}],"name":"storeDeepUintArray","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"retrieveDeepArray","outputs":[{"name":"","type":"uint64[3][4][5]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"name":"deepUint64Array","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"}]`}, + []string{`6060604052341561000f57600080fd5b6106438061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063344248551461005c5780638ed4573a1461011457806398ed1856146101ab575b600080fd5b341561006757600080fd5b610112600480806107800190600580602002604051908101604052809291906000905b828210156101055783826101800201600480602002604051908101604052809291906000905b828210156100f25783826060020160038060200260405190810160405280929190826003602002808284378201915050505050815260200190600101906100b0565b505050508152602001906001019061008a565b5050505091905050610208565b005b341561011f57600080fd5b61012761021d565b604051808260056000925b8184101561019b578284602002015160046000925b8184101561018d5782846020020151600360200280838360005b8381101561017c578082015181840152602081019050610161565b505050509050019260010192610147565b925050509260010192610132565b9250505091505060405180910390f35b34156101b657600080fd5b6101de6004808035906020019091908035906020019091908035906020019091905050610309565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b80600090600561021992919061035f565b5050565b6102256103b0565b6000600580602002604051908101604052809291906000905b8282101561030057838260040201600480602002604051908101604052809291906000905b828210156102ed578382016003806020026040519081016040528092919082600380156102d9576020028201916000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff16815260200190600801906020826007010492830192600103820291508084116102945790505b505050505081526020019060010190610263565b505050508152602001906001019061023e565b50505050905090565b60008360058110151561031857fe5b600402018260048110151561032957fe5b018160038110151561033757fe5b6004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b826005600402810192821561039f579160200282015b8281111561039e5782518290600461038e9291906103df565b5091602001919060040190610375565b5b5090506103ac919061042d565b5090565b610780604051908101604052806005905b6103c9610459565b8152602001906001900390816103c15790505090565b826004810192821561041c579160200282015b8281111561041b5782518290600361040b929190610488565b50916020019190600101906103f2565b5b5090506104299190610536565b5090565b61045691905b8082111561045257600081816104499190610562565b50600401610433565b5090565b90565b610180604051908101604052806004905b6104726105a7565b81526020019060019003908161046a5790505090565b82600380016004900481019282156105255791602002820160005b838211156104ef57835183826101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555092602001926008016020816007010492830192600103026104a3565b80156105235782816101000a81549067ffffffffffffffff02191690556008016020816007010492830192600103026104ef565b505b50905061053291906105d9565b5090565b61055f91905b8082111561055b57600081816105529190610610565b5060010161053c565b5090565b90565b50600081816105719190610610565b50600101600081816105839190610610565b50600101600081816105959190610610565b5060010160006105a59190610610565b565b6060604051908101604052806003905b600067ffffffffffffffff168152602001906001900390816105b75790505090565b61060d91905b8082111561060957600081816101000a81549067ffffffffffffffff0219169055506001016105df565b5090565b90565b50600090555600a165627a7a7230582087e5a43f6965ab6ef7a4ff056ab80ed78fd8c15cff57715a1bf34ec76a93661c0029`}, + nil, + nil, + }, + { + `CallbackParam`, + []string{`[ + { + "constant": false, + "inputs": [ + { + "name": "callback", + "type": "function" + } + ], + "name": "test", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ]`}, + []string{`608060405234801561001057600080fd5b5061015e806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063d7a5aba214610040575b600080fd5b34801561004c57600080fd5b506100be6004803603602081101561006357600080fd5b810190808035806c0100000000000000000000000090049068010000000000000000900463ffffffff1677ffffffffffffffffffffffffffffffffffffffffffffffff169091602001919093929190939291905050506100c0565b005b818160016040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561011657600080fd5b505af115801561012a573d6000803e3d6000fd5b50505050505056fea165627a7a7230582062f87455ff84be90896dbb0c4e4ddb505c600d23089f8e80a512548440d7e2580029`}, + nil, + nil, + }, + { + `Tuple`, + []string{` +[{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"indexed":false,"internalType":"struct Tuple.S","name":"a","type":"tuple"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"indexed":false,"internalType":"struct Tuple.T[2][]","name":"b","type":"tuple[2][]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"indexed":false,"internalType":"struct Tuple.T[][2]","name":"c","type":"tuple[][2]"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"indexed":false,"internalType":"struct Tuple.S[]","name":"d","type":"tuple[]"},{"indexed":false,"internalType":"uint256[]","name":"e","type":"uint256[]"}],"name":"TupleEvent","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"}],"indexed":false,"internalType":"struct Tuple.P[]","name":"","type":"tuple[]"}],"name":"TupleEvent2","type":"event"},{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S","name":"a","type":"tuple"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[2][]","name":"b","type":"tuple[2][]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[][2]","name":"c","type":"tuple[][2]"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S[]","name":"d","type":"tuple[]"},{"internalType":"uint256[]","name":"e","type":"uint256[]"}],"name":"func1","outputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[2][]","name":"","type":"tuple[2][]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[][2]","name":"","type":"tuple[][2]"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S[]","name":"","type":"tuple[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S","name":"a","type":"tuple"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[2][]","name":"b","type":"tuple[2][]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[][2]","name":"c","type":"tuple[][2]"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S[]","name":"d","type":"tuple[]"},{"internalType":"uint256[]","name":"e","type":"uint256[]"}],"name":"func2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"uint16","name":"x","type":"uint16"},{"internalType":"uint16","name":"y","type":"uint16"}],"internalType":"struct Tuple.Q[]","name":"","type":"tuple[]"}],"name":"func3","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}]`}, + []string{`60806040523480156100115760006000fd5b50610017565b6110b2806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100465760003560e01c8063443c79b41461004c578063d0062cdd14610080578063e4d9a43b1461009c57610046565b60006000fd5b610066600480360361006191908101906107b8565b6100b8565b604051610077959493929190610ccb565b60405180910390f35b61009a600480360361009591908101906107b8565b6100ef565b005b6100b660048036036100b19190810190610775565b610136565b005b6100c061013a565b60606100ca61015e565b606060608989898989945094509450945094506100e2565b9550955095509550959050565b7f18d6e66efa53739ca6d13626f35ebc700b31cced3eddb50c70bbe9c082c6cd008585858585604051610126959493929190610ccb565b60405180910390a15b5050505050565b5b50565b60405180606001604052806000815260200160608152602001606081526020015090565b60405180604001604052806002905b606081526020019060019003908161016d57905050905661106e565b600082601f830112151561019d5760006000fd5b81356101b06101ab82610d6f565b610d41565b915081818352602084019350602081019050838560808402820111156101d65760006000fd5b60005b8381101561020757816101ec888261037a565b8452602084019350608083019250505b6001810190506101d9565b5050505092915050565b600082601f83011215156102255760006000fd5b600261023861023382610d98565b610d41565b9150818360005b83811015610270578135860161025588826103f3565b8452602084019350602083019250505b60018101905061023f565b5050505092915050565b600082601f830112151561028e5760006000fd5b81356102a161029c82610dbb565b610d41565b915081818352602084019350602081019050838560408402820111156102c75760006000fd5b60005b838110156102f857816102dd888261058b565b8452602084019350604083019250505b6001810190506102ca565b5050505092915050565b600082601f83011215156103165760006000fd5b813561032961032482610de4565b610d41565b9150818183526020840193506020810190508360005b83811015610370578135860161035588826105d8565b8452602084019350602083019250505b60018101905061033f565b5050505092915050565b600082601f830112151561038e5760006000fd5b60026103a161039c82610e0d565b610d41565b915081838560408402820111156103b85760006000fd5b60005b838110156103e957816103ce88826106fe565b8452602084019350604083019250505b6001810190506103bb565b5050505092915050565b600082601f83011215156104075760006000fd5b813561041a61041582610e30565b610d41565b915081818352602084019350602081019050838560408402820111156104405760006000fd5b60005b83811015610471578161045688826106fe565b8452602084019350604083019250505b600181019050610443565b5050505092915050565b600082601f830112151561048f5760006000fd5b81356104a261049d82610e59565b610d41565b915081818352602084019350602081019050838560208402820111156104c85760006000fd5b60005b838110156104f957816104de8882610760565b8452602084019350602083019250505b6001810190506104cb565b5050505092915050565b600082601f83011215156105175760006000fd5b813561052a61052582610e82565b610d41565b915081818352602084019350602081019050838560208402820111156105505760006000fd5b60005b8381101561058157816105668882610760565b8452602084019350602083019250505b600181019050610553565b5050505092915050565b60006040828403121561059e5760006000fd5b6105a86040610d41565b905060006105b88482850161074b565b60008301525060206105cc8482850161074b565b60208301525092915050565b6000606082840312156105eb5760006000fd5b6105f56060610d41565b9050600061060584828501610760565b600083015250602082013567ffffffffffffffff8111156106265760006000fd5b6106328482850161047b565b602083015250604082013567ffffffffffffffff8111156106535760006000fd5b61065f848285016103f3565b60408301525092915050565b60006060828403121561067e5760006000fd5b6106886060610d41565b9050600061069884828501610760565b600083015250602082013567ffffffffffffffff8111156106b95760006000fd5b6106c58482850161047b565b602083015250604082013567ffffffffffffffff8111156106e65760006000fd5b6106f2848285016103f3565b60408301525092915050565b6000604082840312156107115760006000fd5b61071b6040610d41565b9050600061072b84828501610760565b600083015250602061073f84828501610760565b60208301525092915050565b60008135905061075a8161103a565b92915050565b60008135905061076f81611054565b92915050565b6000602082840312156107885760006000fd5b600082013567ffffffffffffffff8111156107a35760006000fd5b6107af8482850161027a565b91505092915050565b6000600060006000600060a086880312156107d35760006000fd5b600086013567ffffffffffffffff8111156107ee5760006000fd5b6107fa8882890161066b565b955050602086013567ffffffffffffffff8111156108185760006000fd5b61082488828901610189565b945050604086013567ffffffffffffffff8111156108425760006000fd5b61084e88828901610211565b935050606086013567ffffffffffffffff81111561086c5760006000fd5b61087888828901610302565b925050608086013567ffffffffffffffff8111156108965760006000fd5b6108a288828901610503565b9150509295509295909350565b60006108bb8383610a6a565b60808301905092915050565b60006108d38383610ac2565b905092915050565b60006108e78383610c36565b905092915050565b60006108fb8383610c8d565b60408301905092915050565b60006109138383610cbc565b60208301905092915050565b600061092a82610f0f565b6109348185610fb7565b935061093f83610eab565b8060005b8381101561097157815161095788826108af565b975061096283610f5c565b9250505b600181019050610943565b5085935050505092915050565b600061098982610f1a565b6109938185610fc8565b9350836020820285016109a585610ebb565b8060005b858110156109e257848403895281516109c285826108c7565b94506109cd83610f69565b925060208a019950505b6001810190506109a9565b50829750879550505050505092915050565b60006109ff82610f25565b610a098185610fd3565b935083602082028501610a1b85610ec5565b8060005b85811015610a585784840389528151610a3885826108db565b9450610a4383610f76565b925060208a019950505b600181019050610a1f565b50829750879550505050505092915050565b610a7381610f30565b610a7d8184610fe4565b9250610a8882610ed5565b8060005b83811015610aba578151610aa087826108ef565b9650610aab83610f83565b9250505b600181019050610a8c565b505050505050565b6000610acd82610f3b565b610ad78185610fef565b9350610ae283610edf565b8060005b83811015610b14578151610afa88826108ef565b9750610b0583610f90565b9250505b600181019050610ae6565b5085935050505092915050565b6000610b2c82610f51565b610b368185611011565b9350610b4183610eff565b8060005b83811015610b73578151610b598882610907565b9750610b6483610faa565b9250505b600181019050610b45565b5085935050505092915050565b6000610b8b82610f46565b610b958185611000565b9350610ba083610eef565b8060005b83811015610bd2578151610bb88882610907565b9750610bc383610f9d565b9250505b600181019050610ba4565b5085935050505092915050565b6000606083016000830151610bf76000860182610cbc565b5060208301518482036020860152610c0f8282610b80565b91505060408301518482036040860152610c298282610ac2565b9150508091505092915050565b6000606083016000830151610c4e6000860182610cbc565b5060208301518482036020860152610c668282610b80565b91505060408301518482036040860152610c808282610ac2565b9150508091505092915050565b604082016000820151610ca36000850182610cbc565b506020820151610cb66020850182610cbc565b50505050565b610cc581611030565b82525050565b600060a0820190508181036000830152610ce58188610bdf565b90508181036020830152610cf9818761091f565b90508181036040830152610d0d818661097e565b90508181036060830152610d2181856109f4565b90508181036080830152610d358184610b21565b90509695505050505050565b6000604051905081810181811067ffffffffffffffff82111715610d655760006000fd5b8060405250919050565b600067ffffffffffffffff821115610d875760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610db05760006000fd5b602082029050919050565b600067ffffffffffffffff821115610dd35760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610dfc5760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e255760006000fd5b602082029050919050565b600067ffffffffffffffff821115610e485760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e715760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e9a5760006000fd5b602082029050602081019050919050565b6000819050602082019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600061ffff82169050919050565b6000819050919050565b61104381611022565b811415156110515760006000fd5b50565b61105d81611030565b8114151561106b5760006000fd5b50565bfea365627a7a72315820d78c6ba7ee332581e6c4d9daa5fc07941841230f7ce49edf6e05b1b63853e8746c6578706572696d656e74616cf564736f6c634300050c0040`}, + nil, + nil, + }, + { + "Overload", + []string{`[{"constant":false,"inputs":[{"name":"i","type":"uint256"},{"name":"j","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"i","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"}],"name":"bar","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"},{"indexed":false,"name":"j","type":"uint256"}],"name":"bar","type":"event"}]`}, + []string{`608060405234801561001057600080fd5b50610153806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806304bc52f81461003b5780632fbebd3814610073575b600080fd5b6100716004803603604081101561005157600080fd5b8101908080359060200190929190803590602001909291905050506100a1565b005b61009f6004803603602081101561008957600080fd5b81019080803590602001909291905050506100e4565b005b7fae42e9514233792a47a1e4554624e83fe852228e1503f63cd383e8a431f4f46d8282604051808381526020018281526020019250505060405180910390a15050565b7f0423a1321222a0a8716c22b92fac42d85a45a612b696a461784d9fa537c81e5c816040518082815260200191505060405180910390a15056fea265627a7a72305820e22b049858b33291cbe67eeaece0c5f64333e439d27032ea8337d08b1de18fe864736f6c634300050a0032`}, + nil, + nil, + }, + { + "IdentifierCollision", + []string{`[{"constant":true,"inputs":[],"name":"MyVar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_myVar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`}, + []string{"60806040523480156100115760006000fd5b50610017565b60c3806100256000396000f3fe608060405234801560105760006000fd5b506004361060365760003560e01c806301ad4d8714603c5780634ef1f0ad146058576036565b60006000fd5b60426074565b6040518082815260200191505060405180910390f35b605e607d565b6040518082815260200191505060405180910390f35b60006000505481565b60006000600050549050608b565b9056fea265627a7a7231582067c8d84688b01c4754ba40a2a871cede94ea1f28b5981593ab2a45b46ac43af664736f6c634300050c0032"}, + nil, + map[string]string{"_myVar": "pubVar"}, // alias MyVar to PubVar,\ + }, + { + "NameConflict", + []string{`[ { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "int256", "name": "msg", "type": "int256" }, { "indexed": false, "internalType": "int256", "name": "_msg", "type": "int256" } ], "name": "log", "type": "event" }, { "inputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "req", "type": "tuple" } ], "name": "addRequest", "outputs": [], "stateMutability": "pure", "type": "function" }, { "inputs": [], "name": "getRequest", "outputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "", "type": "tuple" } ], "stateMutability": "pure", "type": "function" } ]`}, + []string{"0x608060405234801561001057600080fd5b5061042b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063c2bb515f1461003b578063cce7b04814610059575b600080fd5b610043610075565b60405161005091906101af565b60405180910390f35b610073600480360381019061006e91906103ac565b6100b5565b005b61007d6100b8565b604051806040016040528060405180602001604052806000815250815260200160405180602001604052806000815250815250905090565b50565b604051806040016040528060608152602001606081525090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561010c5780820151818401526020810190506100f1565b8381111561011b576000848401525b50505050565b6000601f19601f8301169050919050565b600061013d826100d2565b61014781856100dd565b93506101578185602086016100ee565b61016081610121565b840191505092915050565b600060408301600083015184820360008601526101888282610132565b915050602083015184820360208601526101a28282610132565b9150508091505092915050565b600060208201905081810360008301526101c9818461016b565b905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61022282610121565b810181811067ffffffffffffffff82111715610241576102406101ea565b5b80604052505050565b60006102546101d1565b90506102608282610219565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561028f5761028e6101ea565b5b61029882610121565b9050602081019050919050565b82818337600083830152505050565b60006102c76102c284610274565b61024a565b9050828152602081018484840111156102e3576102e261026f565b5b6102ee8482856102a5565b509392505050565b600082601f83011261030b5761030a61026a565b5b813561031b8482602086016102b4565b91505092915050565b60006040828403121561033a576103396101e5565b5b610344604061024a565b9050600082013567ffffffffffffffff81111561036457610363610265565b5b610370848285016102f6565b600083015250602082013567ffffffffffffffff81111561039457610393610265565b5b6103a0848285016102f6565b60208301525092915050565b6000602082840312156103c2576103c16101db565b5b600082013567ffffffffffffffff8111156103e0576103df6101e0565b5b6103ec84828501610324565b9150509291505056fea264697066735822122033bca1606af9b6aeba1673f98c52003cec19338539fb44b86690ce82c51483b564736f6c634300080e0033"}, + nil, + nil, + }, + { + "RangeKeyword", + []string{`[{"inputs":[{"internalType":"uint256","name":"range","type":"uint256"}],"name":"functionWithKeywordParameter","outputs":[],"stateMutability":"pure","type":"function"}]`}, + []string{"0x608060405234801561001057600080fd5b5060dc8061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063527a119f14602d575b600080fd5b60436004803603810190603f9190605b565b6045565b005b50565b6000813590506055816092565b92915050565b600060208284031215606e57606d608d565b5b6000607a848285016048565b91505092915050565b6000819050919050565b600080fd5b6099816083565b811460a357600080fd5b5056fea2646970667358221220d4f4525e2615516394055d369fb17df41c359e5e962734f27fd683ea81fd9db164736f6c63430008070033"}, + nil, + nil, + }, + { + "NumericMethodName", + []string{`[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_param","type":"address"}],"name":"_1TestEvent","type":"event"},{"inputs":[],"name":"_1test","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"__1test","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"__2test","outputs":[],"stateMutability":"pure","type":"function"}]`}, + []string{"0x6080604052348015600f57600080fd5b5060958061001e6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80639d993132146041578063d02767c7146049578063ffa02795146051575b600080fd5b60476059565b005b604f605b565b005b6057605d565b005b565b565b56fea26469706673582212200382ca602dff96a7e2ba54657985e2b4ac423a56abe4a1f0667bc635c4d4371f64736f6c63430008110033"}, + nil, + nil, + }, + { + "Structs", + []string{`[{"inputs":[],"name":"F","outputs":[{"components":[{"internalType":"bytes32","name":"B","type":"bytes32"}],"internalType":"structStructs.A[]","name":"a","type":"tuple[]"},{"internalType":"uint256[]","name":"c","type":"uint256[]"},{"internalType":"bool[]","name":"d","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"G","outputs":[{"components":[{"internalType":"bytes32","name":"B","type":"bytes32"}],"internalType":"structStructs.A[]","name":"a","type":"tuple[]"}],"stateMutability":"view","type":"function"}]`}, + []string{`608060405234801561001057600080fd5b50610278806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806328811f591461003b5780636fecb6231461005b575b600080fd5b610043610070565b604051610052939291906101a0565b60405180910390f35b6100636100d6565b6040516100529190610186565b604080516002808252606082810190935282918291829190816020015b610095610131565b81526020019060019003908161008d575050805190915061026960611b9082906000906100be57fe5b60209081029190910101515293606093508392509050565b6040805160028082526060828101909352829190816020015b6100f7610131565b8152602001906001900390816100ef575050805190915061026960611b90829060009061012057fe5b602090810291909101015152905090565b60408051602081019091526000815290565b815260200190565b6000815180845260208085019450808401835b8381101561017b578151518752958201959082019060010161015e565b509495945050505050565b600060208252610199602083018461014b565b9392505050565b6000606082526101b3606083018661014b565b6020838203818501528186516101c98185610239565b91508288019350845b818110156101f3576101e5838651610143565b9484019492506001016101d2565b505084810360408601528551808252908201925081860190845b8181101561022b57825115158552938301939183019160010161020d565b509298975050505050505050565b9081526020019056fea2646970667358221220eb85327e285def14230424c52893aebecec1e387a50bb6b75fc4fdbed647f45f64736f6c63430006050033`}, + nil, + nil, + }, +} + +// TestBindingV2ConvertedV1Tests regenerates contracts from the v1 binding test +// cases (using v2 binding mode) and ensures that no mutations occurred compared +// to the expected output included under testdata/v2. +func TestBindingV2ConvertedV1Tests(t *testing.T) { + for _, tc := range combinedJSONBindTestsV2 { + fname := fmt.Sprintf("testdata/v2/%v.go.txt", strings.ToLower(tc.name)) + t.Run(tc.name, func(t *testing.T) { + if tc.types == nil { + tc.types = []string{tc.name} + } + have, err := bindCombinedJSON(&tc) + if err != nil { + t.Fatalf("got error from bindCombinedJSON: %v", err) + } + // Set this environment variable to regenerate the test outputs. + if os.Getenv("WRITE_TEST_FILES") != "" { + if err := os.WriteFile((fname), []byte(have), 0666); err != nil { + t.Fatalf("err writing expected output to file: %v\n", err) + } + } + // Verify the generated code + want, err := os.ReadFile(fname) + if err != nil { + t.Fatalf("failed to read file %v", fname) + } + if have != string(want) { + t.Fatalf("wrong output: %v", prettyDiff(have, string(want))) + } + }) + } +} + +func TestNormalizeArgs(t *testing.T) { + type normalizeArgsTc struct { + inp []string + expected []string + } + for i, tc := range []normalizeArgsTc{ + {[]string{"arg1", "arg1"}, []string{"arg1", "arg10"}}, + {[]string{"", ""}, []string{"arg0", "arg1"}}, + {[]string{"var", "const"}, []string{"arg0", "arg1"}}, + {[]string{"_res", "Res"}, []string{"res", "res0"}}, + {[]string{"_", "__"}, []string{"arg0", "arg1"}}} { + var inpArgs abi.Arguments + for _, inpArgName := range tc.inp { + inpArgs = append(inpArgs, abi.Argument{ + Name: inpArgName, + }) + } + res := normalizeArgs(inpArgs) + for j, resArg := range res { + if resArg.Name != tc.expected[j] { + t.Fatalf("mismatch for test index %d, arg index %d: expected %v. got %v", i, j, tc.expected[j], resArg.Name) + } + } + } +} + +// returns a "pretty diff" on two strings. Useful if the strings are large. +func prettyDiff(have, want string) string { + if have == want { + return "" + } + var i = 0 + for ; i < len(want) && i < len(have); i++ { + if want[i] != have[i] { + break + } + } + s := max(0, i-50) + he := min(len(have), i+50) + we := min(len(want), i+50) + return fmt.Sprintf("diff after %d characters\nhave: ...%q...\nwant: ...%q...\n", + i, have[s:he], want[s:we]) +} diff --git a/accounts/abi/bind/source.go.tpl b/accounts/abi/abigen/source.go.tpl similarity index 100% rename from accounts/abi/bind/source.go.tpl rename to accounts/abi/abigen/source.go.tpl diff --git a/accounts/abi/abigen/source2.go.tpl b/accounts/abi/abigen/source2.go.tpl new file mode 100644 index 0000000000..8f9d4d4103 --- /dev/null +++ b/accounts/abi/abigen/source2.go.tpl @@ -0,0 +1,238 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package {{.Package}} + +import ( + "bytes" + "math/big" + "errors" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = 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}} + {{capitalise $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 (index $.Libraries .Type) -}} + ID: "{{index $.Libraries .Type}}", + {{ else -}} + ID: "{{.Type}}", + {{end -}} + {{if .InputBin -}} + Bin: "0x{{.InputBin}}", + {{end -}} + {{if .Libraries -}} + Deps: []*bind.MetaData{ + {{- range $name, $pattern := .Libraries}} + &{{$name}}MetaData, + {{- end}} + }, + {{end}} + } + + // {{.Type}} is an auto generated Go binding around an Ethereum contract. + type {{.Type}} struct { + abi abi.ABI + } + + // New{{.Type}} creates a new instance of {{.Type}}. + func New{{.Type}}() *{{.Type}} { + parsed, err := {{.Type}}MetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &{{.Type}}{abi: *parsed} + } + + // Instance creates a wrapper for a deployed contract instance at the given address. + // Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. + func (c *{{.Type}}) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) + } + + {{ if .Constructor.Inputs }} + // PackConstructor is the Go binding used to pack the parameters required for + // contract deployment. + // + // Solidity: {{.Constructor.String}} + func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) PackConstructor({{range .Constructor.Inputs}} {{.Name}} {{bindtype .Type $structs}}, {{end}}) []byte { + enc, err := {{ decapitalise $contract.Type}}.abi.Pack("" {{range .Constructor.Inputs}}, {{.Name}}{{end}}) + if err != nil { + panic(err) + } + return enc + } + {{ end }} + + {{range .Calls}} + // Pack{{.Normalized.Name}} is the Go binding used to pack the parameters required for calling + // the contract method with ID 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) Pack{{.Normalized.Name}}({{range .Normalized.Inputs}} {{.Name}} {{bindtype .Type $structs}}, {{end}}) []byte { + enc, err := {{ decapitalise $contract.Type}}.abi.Pack("{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + if err != nil { + panic(err) + } + return enc + } + + {{/* Unpack method is needed only when there are return args */}} + {{if .Normalized.Outputs }} + {{ if .Structured }} + // {{.Normalized.Name}}Output serves as a container for the return parameters of contract + // method {{ .Normalized.Name }}. + type {{.Normalized.Name}}Output struct { + {{range .Normalized.Outputs}} + {{capitalise .Name}} {{bindtype .Type $structs}}{{end}} + } + {{ end }} + + // Unpack{{.Normalized.Name}} is the Go binding that unpacks the parameters returned + // from invoking the contract method with ID 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) Unpack{{.Normalized.Name}}(data []byte) ( + {{- if .Structured}} {{.Normalized.Name}}Output,{{else}} + {{- range .Normalized.Outputs}} {{bindtype .Type $structs}},{{- end }} + {{- end }} error) { + out, err := {{ decapitalise $contract.Type}}.abi.Unpack("{{.Original.Name}}", data) + {{- if .Structured}} + outstruct := new({{.Normalized.Name}}Output) + if err != nil { + return *outstruct, err + } + {{- range $i, $t := .Normalized.Outputs}} + {{- if ispointertype .Type}} + outstruct.{{capitalise .Name}} = abi.ConvertType(out[{{$i}}], new({{underlyingbindtype .Type }})).({{bindtype .Type $structs}}) + {{- else }} + outstruct.{{capitalise .Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}) + {{- end }} + {{- end }} + return *outstruct, err + {{else}} + if err != nil { + return {{range $i, $_ := .Normalized.Outputs}}{{if ispointertype .Type}}new({{underlyingbindtype .Type }}), {{else}}*new({{bindtype .Type $structs}}), {{end}}{{end}} err + } + {{- range $i, $t := .Normalized.Outputs}} + {{- if ispointertype .Type }} + out{{$i}} := abi.ConvertType(out[{{$i}}], new({{underlyingbindtype .Type}})).({{bindtype .Type $structs}}) + {{- else }} + out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}) + {{- end }} + {{- end}} + return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err + {{- end}} + } + {{end}} + {{end}} + + {{range .Events}} + // {{$contract.Type}}{{.Normalized.Name}} represents a {{.Original.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 + } + + const {{$contract.Type}}{{.Normalized.Name}}EventName = "{{.Original.Name}}" + + // ContractEventName returns the user-defined event name. + func ({{$contract.Type}}{{.Normalized.Name}}) ContractEventName() string { + return {{$contract.Type}}{{.Normalized.Name}}EventName + } + + // Unpack{{.Normalized.Name}}Event is the Go binding that unpacks the event data emitted + // by contract. + // + // Solidity: {{.Original.String}} + func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) Unpack{{.Normalized.Name}}Event(log *types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { + event := "{{.Original.Name}}" + if log.Topics[0] != {{ decapitalise $contract.Type}}.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new({{$contract.Type}}{{.Normalized.Name}}) + if len(log.Data) > 0 { + if err := {{ decapitalise $contract.Type}}.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range {{ decapitalise $contract.Type}}.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil + } + {{end}} + + {{ if .Errors }} + // UnpackError attempts to decode the provided error data using user-defined + // error definitions. + func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) UnpackError(raw []byte) (any, error) { + {{- range $k, $v := .Errors}} + if bytes.Equal(raw[:4], {{ decapitalise $contract.Type}}.abi.Errors["{{.Normalized.Name}}"].ID.Bytes()[:4]) { + return {{ decapitalise $contract.Type}}.Unpack{{.Normalized.Name}}Error(raw[4:]) + } + {{- end }} + return nil, errors.New("Unknown error") + } + {{ end }} + + {{range .Errors}} + // {{$contract.Type}}{{.Normalized.Name}} represents a {{.Original.Name}} error 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}} + } + + // ErrorID returns the hash of canonical representation of the error's signature. + // + // Solidity: {{.Original.String}} + func {{$contract.Type}}{{.Normalized.Name}}ErrorID() common.Hash { + return common.HexToHash("{{.Original.ID}}") + } + + // Unpack{{.Normalized.Name}}Error is the Go binding used to decode the provided + // error data into the corresponding Go error struct. + // + // Solidity: {{.Original.String}} + func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) Unpack{{.Normalized.Name}}Error(raw []byte) (*{{$contract.Type}}{{.Normalized.Name}}, error) { + out := new({{$contract.Type}}{{.Normalized.Name}}) + if err := {{ decapitalise $contract.Type}}.abi.UnpackIntoInterface(out, "{{.Normalized.Name}}", raw); err != nil { + return nil, err + } + return out, nil + } + {{end}} +{{end}} diff --git a/accounts/abi/bind/template.go b/accounts/abi/abigen/template.go similarity index 64% rename from accounts/abi/bind/template.go rename to accounts/abi/abigen/template.go index 4a0062af0a..cbb21037a6 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/abigen/template.go @@ -14,10 +14,12 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package bind +package abigen import ( _ "embed" + "strings" + "unicode" "github.com/ethereum/go-ethereum/accounts/abi" ) @@ -42,10 +44,48 @@ type tmplContract struct { Fallback *tmplMethod // Additional special fallback function Receive *tmplMethod // Additional special receive function Events map[string]*tmplEvent // Contract events accessors - Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs + Libraries map[string]string // Same as tmplData, but filtered to only keep direct deps that the contract needs Library bool // Indicator whether the contract is a library } +type tmplContractV2 struct { + Type string // Type name of the main contract binding + InputABI string // JSON ABI used as the input to generate the binding from + InputBin string // Optional EVM bytecode used to generate deploy code from + Constructor abi.Method // Contract constructor for deploy parametrization + Calls map[string]*tmplMethod // All contract methods (excluding fallback, receive) + Events map[string]*tmplEvent // Contract events accessors + Libraries map[string]string // all direct library dependencies + Errors map[string]*tmplError // all errors defined +} + +func newTmplContractV2(typ string, abiStr string, bytecode string, constructor abi.Method, cb *contractBinder) *tmplContractV2 { + // Strip any whitespace from the JSON ABI + strippedABI := strings.Map(func(r rune) rune { + if unicode.IsSpace(r) { + return -1 + } + return r + }, abiStr) + return &tmplContractV2{ + abi.ToCamelCase(typ), + strings.ReplaceAll(strippedABI, "\"", "\\\""), + strings.TrimPrefix(strings.TrimSpace(bytecode), "0x"), + constructor, + cb.calls, + cb.events, + make(map[string]string), + cb.errors, + } +} + +type tmplDataV2 struct { + Package string // Name of the package to use for the generated bindings + Contracts map[string]*tmplContractV2 // Contracts that will be emitted in the bindings (keyed by contract name) + Libraries map[string]string // Map of the contract's name to link pattern + Structs map[string]*tmplStruct // Contract struct type definitions +} + // tmplMethod is a wrapper around an abi.Method that contains a few preprocessed // and cached data fields. type tmplMethod struct { @@ -61,6 +101,13 @@ type tmplEvent struct { Normalized abi.Event // Normalized version of the parsed fields } +// tmplError is a wrapper around an abi.Error that contains a few preprocessed +// and cached data fields. +type tmplError struct { + Original abi.Error + Normalized abi.Error +} + // tmplField is a wrapper around a struct field with binding language // struct type definition and relative filed name. type tmplField struct { @@ -76,14 +123,14 @@ type tmplStruct struct { Fields []*tmplField // Struct fields definition depends on the binding language. } -// tmplSource is language to template mapping containing all the supported -// programming languages the package can generate to. -var tmplSource = map[Lang]string{ - LangGo: tmplSourceGo, -} - -// tmplSourceGo is the Go source template that the generated Go contract binding +// tmplSource is the Go source template that the generated Go contract binding // is based on. // //go:embed source.go.tpl -var tmplSourceGo string +var tmplSource string + +// tmplSourceV2 is the Go source template that the generated Go contract binding +// for abigen v2 is based on. +// +//go:embed source2.go.tpl +var tmplSourceV2 string diff --git a/accounts/abi/abigen/testdata/v2/callbackparam.go.txt b/accounts/abi/abigen/testdata/v2/callbackparam.go.txt new file mode 100644 index 0000000000..e3205bde0d --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/callbackparam.go.txt @@ -0,0 +1,64 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// CallbackParamMetaData contains all meta data concerning the CallbackParam contract. +var CallbackParamMetaData = bind.MetaData{ + ABI: "[{\"constant\":false,\"inputs\":[{\"name\":\"callback\",\"type\":\"function\"}],\"name\":\"test\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ID: "949f96f86d3c2e1bcc15563ad898beaaca", + Bin: "0x608060405234801561001057600080fd5b5061015e806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063d7a5aba214610040575b600080fd5b34801561004c57600080fd5b506100be6004803603602081101561006357600080fd5b810190808035806c0100000000000000000000000090049068010000000000000000900463ffffffff1677ffffffffffffffffffffffffffffffffffffffffffffffff169091602001919093929190939291905050506100c0565b005b818160016040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561011657600080fd5b505af115801561012a573d6000803e3d6000fd5b50505050505056fea165627a7a7230582062f87455ff84be90896dbb0c4e4ddb505c600d23089f8e80a512548440d7e2580029", +} + +// CallbackParam is an auto generated Go binding around an Ethereum contract. +type CallbackParam struct { + abi abi.ABI +} + +// NewCallbackParam creates a new instance of CallbackParam. +func NewCallbackParam() *CallbackParam { + parsed, err := CallbackParamMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &CallbackParam{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *CallbackParam) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackTest is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd7a5aba2. +// +// Solidity: function test(function callback) returns() +func (callbackParam *CallbackParam) PackTest(callback [24]byte) []byte { + enc, err := callbackParam.abi.Pack("test", callback) + if err != nil { + panic(err) + } + return enc +} diff --git a/accounts/abi/abigen/testdata/v2/crowdsale.go.txt b/accounts/abi/abigen/testdata/v2/crowdsale.go.txt new file mode 100644 index 0000000000..60d8b4ec11 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/crowdsale.go.txt @@ -0,0 +1,304 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// CrowdsaleMetaData contains all meta data concerning the Crowdsale contract. +var CrowdsaleMetaData = bind.MetaData{ + ABI: "[{\"constant\":false,\"inputs\":[],\"name\":\"checkGoalReached\",\"outputs\":[],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"deadline\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"beneficiary\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"tokenReward\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"fundingGoal\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"amountRaised\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"price\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"funders\",\"outputs\":[{\"name\":\"addr\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"inputs\":[{\"name\":\"ifSuccessfulSendTo\",\"type\":\"address\"},{\"name\":\"fundingGoalInEthers\",\"type\":\"uint256\"},{\"name\":\"durationInMinutes\",\"type\":\"uint256\"},{\"name\":\"etherCostOfEachToken\",\"type\":\"uint256\"},{\"name\":\"addressOfTokenUsedAsReward\",\"type\":\"address\"}],\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"backer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"isContribution\",\"type\":\"bool\"}],\"name\":\"FundTransfer\",\"type\":\"event\"}]", + ID: "84d7e935785c5c648282d326307bb8fa0d", + Bin: "0x606060408190526007805460ff1916905560a0806105a883396101006040529051608051915160c05160e05160008054600160a060020a03199081169095178155670de0b6b3a7640000958602600155603c9093024201600355930260045560058054909216909217905561052f90819061007990396000f36060604052361561006c5760e060020a600035046301cb3b20811461008257806329dcb0cf1461014457806338af3eed1461014d5780636e66f6e91461015f5780637a3a0e84146101715780637b3e5e7b1461017a578063a035b1fe14610183578063dc0d3dff1461018c575b61020060075460009060ff161561032357610002565b61020060035460009042106103205760025460015490106103cb576002548154600160a060020a0316908290606082818181858883f150915460025460408051600160a060020a039390931683526020830191909152818101869052517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6945090819003909201919050a15b60405160008054600160a060020a039081169230909116319082818181858883f150506007805460ff1916600117905550505050565b6103a160035481565b6103ab600054600160a060020a031681565b6103ab600554600160a060020a031681565b6103a160015481565b6103a160025481565b6103a160045481565b6103be60043560068054829081101561000257506000526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101547ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409190910154600160a060020a03919091169082565b005b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a815481600160a060020a030219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a9004600160a060020a0316600160a060020a031663a9059cbb3360046000505484046040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505060408051600160a060020a03331681526020810184905260018183015290517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf692509081900360600190a15b50565b5060a0604052336060908152346080819052600680546001810180835592939282908280158290116102025760020281600202836000526020600020918201910161020291905b8082111561039d57805473ffffffffffffffffffffffffffffffffffffffff19168155600060019190910190815561036a565b5090565b6060908152602090f35b600160a060020a03166060908152602090f35b6060918252608052604090f35b5b60065481101561010e576006805482908110156100025760009182526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600680549254600160a060020a0316928490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460405190915082818181858883f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf660066000508281548110156100025760008290526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01548154600160a060020a039190911691908490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460408051600160a060020a0394909416845260208401919091526000838201525191829003606001919050a16001016103cc56", +} + +// Crowdsale is an auto generated Go binding around an Ethereum contract. +type Crowdsale struct { + abi abi.ABI +} + +// NewCrowdsale creates a new instance of Crowdsale. +func NewCrowdsale() *Crowdsale { + parsed, err := CrowdsaleMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Crowdsale{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Crowdsale) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackConstructor is the Go binding used to pack the parameters required for +// contract deployment. +// +// Solidity: constructor(address ifSuccessfulSendTo, uint256 fundingGoalInEthers, uint256 durationInMinutes, uint256 etherCostOfEachToken, address addressOfTokenUsedAsReward) returns() +func (crowdsale *Crowdsale) PackConstructor(ifSuccessfulSendTo common.Address, fundingGoalInEthers *big.Int, durationInMinutes *big.Int, etherCostOfEachToken *big.Int, addressOfTokenUsedAsReward common.Address) []byte { + enc, err := crowdsale.abi.Pack("", ifSuccessfulSendTo, fundingGoalInEthers, durationInMinutes, etherCostOfEachToken, addressOfTokenUsedAsReward) + if err != nil { + panic(err) + } + return enc +} + +// PackAmountRaised is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x7b3e5e7b. +// +// Solidity: function amountRaised() returns(uint256) +func (crowdsale *Crowdsale) PackAmountRaised() []byte { + enc, err := crowdsale.abi.Pack("amountRaised") + if err != nil { + panic(err) + } + return enc +} + +// UnpackAmountRaised is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x7b3e5e7b. +// +// Solidity: function amountRaised() returns(uint256) +func (crowdsale *Crowdsale) UnpackAmountRaised(data []byte) (*big.Int, error) { + out, err := crowdsale.abi.Unpack("amountRaised", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackBeneficiary is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x38af3eed. +// +// Solidity: function beneficiary() returns(address) +func (crowdsale *Crowdsale) PackBeneficiary() []byte { + enc, err := crowdsale.abi.Pack("beneficiary") + if err != nil { + panic(err) + } + return enc +} + +// UnpackBeneficiary is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x38af3eed. +// +// Solidity: function beneficiary() returns(address) +func (crowdsale *Crowdsale) UnpackBeneficiary(data []byte) (common.Address, error) { + out, err := crowdsale.abi.Unpack("beneficiary", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, err +} + +// PackCheckGoalReached is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x01cb3b20. +// +// Solidity: function checkGoalReached() returns() +func (crowdsale *Crowdsale) PackCheckGoalReached() []byte { + enc, err := crowdsale.abi.Pack("checkGoalReached") + if err != nil { + panic(err) + } + return enc +} + +// PackDeadline is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x29dcb0cf. +// +// Solidity: function deadline() returns(uint256) +func (crowdsale *Crowdsale) PackDeadline() []byte { + enc, err := crowdsale.abi.Pack("deadline") + if err != nil { + panic(err) + } + return enc +} + +// UnpackDeadline is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x29dcb0cf. +// +// Solidity: function deadline() returns(uint256) +func (crowdsale *Crowdsale) UnpackDeadline(data []byte) (*big.Int, error) { + out, err := crowdsale.abi.Unpack("deadline", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackFunders is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xdc0d3dff. +// +// Solidity: function funders(uint256 ) returns(address addr, uint256 amount) +func (crowdsale *Crowdsale) PackFunders(arg0 *big.Int) []byte { + enc, err := crowdsale.abi.Pack("funders", arg0) + if err != nil { + panic(err) + } + return enc +} + +// FundersOutput serves as a container for the return parameters of contract +// method Funders. +type FundersOutput struct { + Addr common.Address + Amount *big.Int +} + +// UnpackFunders is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xdc0d3dff. +// +// Solidity: function funders(uint256 ) returns(address addr, uint256 amount) +func (crowdsale *Crowdsale) UnpackFunders(data []byte) (FundersOutput, error) { + out, err := crowdsale.abi.Unpack("funders", data) + outstruct := new(FundersOutput) + if err != nil { + return *outstruct, err + } + outstruct.Addr = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.Amount = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackFundingGoal is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x7a3a0e84. +// +// Solidity: function fundingGoal() returns(uint256) +func (crowdsale *Crowdsale) PackFundingGoal() []byte { + enc, err := crowdsale.abi.Pack("fundingGoal") + if err != nil { + panic(err) + } + return enc +} + +// UnpackFundingGoal is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x7a3a0e84. +// +// Solidity: function fundingGoal() returns(uint256) +func (crowdsale *Crowdsale) UnpackFundingGoal(data []byte) (*big.Int, error) { + out, err := crowdsale.abi.Unpack("fundingGoal", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackPrice is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa035b1fe. +// +// Solidity: function price() returns(uint256) +func (crowdsale *Crowdsale) PackPrice() []byte { + enc, err := crowdsale.abi.Pack("price") + if err != nil { + panic(err) + } + return enc +} + +// UnpackPrice is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xa035b1fe. +// +// Solidity: function price() returns(uint256) +func (crowdsale *Crowdsale) UnpackPrice(data []byte) (*big.Int, error) { + out, err := crowdsale.abi.Unpack("price", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackTokenReward is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x6e66f6e9. +// +// Solidity: function tokenReward() returns(address) +func (crowdsale *Crowdsale) PackTokenReward() []byte { + enc, err := crowdsale.abi.Pack("tokenReward") + if err != nil { + panic(err) + } + return enc +} + +// UnpackTokenReward is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x6e66f6e9. +// +// Solidity: function tokenReward() returns(address) +func (crowdsale *Crowdsale) UnpackTokenReward(data []byte) (common.Address, error) { + out, err := crowdsale.abi.Unpack("tokenReward", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, err +} + +// CrowdsaleFundTransfer represents a FundTransfer event raised by the Crowdsale contract. +type CrowdsaleFundTransfer struct { + Backer common.Address + Amount *big.Int + IsContribution bool + Raw *types.Log // Blockchain specific contextual infos +} + +const CrowdsaleFundTransferEventName = "FundTransfer" + +// ContractEventName returns the user-defined event name. +func (CrowdsaleFundTransfer) ContractEventName() string { + return CrowdsaleFundTransferEventName +} + +// UnpackFundTransferEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event FundTransfer(address backer, uint256 amount, bool isContribution) +func (crowdsale *Crowdsale) UnpackFundTransferEvent(log *types.Log) (*CrowdsaleFundTransfer, error) { + event := "FundTransfer" + if log.Topics[0] != crowdsale.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(CrowdsaleFundTransfer) + if len(log.Data) > 0 { + if err := crowdsale.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range crowdsale.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/abigen/testdata/v2/dao.go.txt b/accounts/abi/abigen/testdata/v2/dao.go.txt new file mode 100644 index 0000000000..72a80949f6 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/dao.go.txt @@ -0,0 +1,655 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// DAOMetaData contains all meta data concerning the DAO contract. +var DAOMetaData = bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"proposals\",\"outputs\":[{\"name\":\"recipient\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"votingDeadline\",\"type\":\"uint256\"},{\"name\":\"executed\",\"type\":\"bool\"},{\"name\":\"proposalPassed\",\"type\":\"bool\"},{\"name\":\"numberOfVotes\",\"type\":\"uint256\"},{\"name\":\"currentResult\",\"type\":\"int256\"},{\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"proposalNumber\",\"type\":\"uint256\"},{\"name\":\"transactionBytecode\",\"type\":\"bytes\"}],\"name\":\"executeProposal\",\"outputs\":[{\"name\":\"result\",\"type\":\"int256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"memberId\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"numProposals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"name\":\"member\",\"type\":\"address\"},{\"name\":\"canVote\",\"type\":\"bool\"},{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"memberSince\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"debatingPeriodInMinutes\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minimumQuorum\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"targetMember\",\"type\":\"address\"},{\"name\":\"canVote\",\"type\":\"bool\"},{\"name\":\"memberName\",\"type\":\"string\"}],\"name\":\"changeMembership\",\"outputs\":[],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"majorityMargin\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"beneficiary\",\"type\":\"address\"},{\"name\":\"etherAmount\",\"type\":\"uint256\"},{\"name\":\"JobDescription\",\"type\":\"string\"},{\"name\":\"transactionBytecode\",\"type\":\"bytes\"}],\"name\":\"newProposal\",\"outputs\":[{\"name\":\"proposalID\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"minimumQuorumForProposals\",\"type\":\"uint256\"},{\"name\":\"minutesForDebate\",\"type\":\"uint256\"},{\"name\":\"marginOfVotesForMajority\",\"type\":\"int256\"}],\"name\":\"changeVotingRules\",\"outputs\":[],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"proposalNumber\",\"type\":\"uint256\"},{\"name\":\"supportsProposal\",\"type\":\"bool\"},{\"name\":\"justificationText\",\"type\":\"string\"}],\"name\":\"vote\",\"outputs\":[{\"name\":\"voteID\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"proposalNumber\",\"type\":\"uint256\"},{\"name\":\"beneficiary\",\"type\":\"address\"},{\"name\":\"etherAmount\",\"type\":\"uint256\"},{\"name\":\"transactionBytecode\",\"type\":\"bytes\"}],\"name\":\"checkProposalCode\",\"outputs\":[{\"name\":\"codeChecksOut\",\"type\":\"bool\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"type\":\"function\"},{\"inputs\":[{\"name\":\"minimumQuorumForProposals\",\"type\":\"uint256\"},{\"name\":\"minutesForDebate\",\"type\":\"uint256\"},{\"name\":\"marginOfVotesForMajority\",\"type\":\"int256\"},{\"name\":\"congressLeader\",\"type\":\"address\"}],\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"proposalID\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"description\",\"type\":\"string\"}],\"name\":\"ProposalAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"proposalID\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"position\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"justification\",\"type\":\"string\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"proposalID\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"result\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"quorum\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"active\",\"type\":\"bool\"}],\"name\":\"ProposalTallied\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"member\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"isMember\",\"type\":\"bool\"}],\"name\":\"MembershipChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"minimumQuorum\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"debatingPeriodInMinutes\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"majorityMargin\",\"type\":\"int256\"}],\"name\":\"ChangeOfRules\",\"type\":\"event\"}]", + ID: "d0a4ad96d49edb1c33461cebc6fb260919", + Bin: "0x606060405260405160808061145f833960e06040529051905160a05160c05160008054600160a060020a03191633179055600184815560028490556003839055600780549182018082558280158290116100b8576003028160030283600052602060002091820191016100b891906101c8565b50506060919091015160029190910155600160a060020a0381166000146100a65760008054600160a060020a031916821790555b505050506111f18061026e6000396000f35b505060408051608081018252600080825260208281018290528351908101845281815292820192909252426060820152600780549194509250811015610002579081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889050815181546020848101517401000000000000000000000000000000000000000002600160a060020a03199290921690921760a060020a60ff021916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f9081018390048201949192919091019083901061023e57805160ff19168380011785555b50610072929150610226565b5050600060028201556001015b8082111561023a578054600160a860020a031916815560018181018054600080835592600290821615610100026000190190911604601f81901061020c57506101bb565b601f0160209004906000526020600020908101906101bb91905b8082111561023a5760008155600101610226565b5090565b828001600101855582156101af579182015b828111156101af57825182600050559160200191906001019061025056606060405236156100b95760e060020a6000350463013cf08b81146100bb578063237e9492146101285780633910682114610281578063400e3949146102995780635daf08ca146102a257806369bd34361461032f5780638160f0b5146103385780638da5cb5b146103415780639644fcbd14610353578063aa02a90f146103be578063b1050da5146103c7578063bcca1fd3146104b5578063d3c0715b146104dc578063eceb29451461058d578063f2fde38b1461067b575b005b61069c6004356004805482908110156100025790600052602060002090600a02016000506005810154815460018301546003840154600485015460068601546007870154600160a060020a03959095169750929560020194919360ff828116946101009093041692919089565b60408051602060248035600481810135601f81018590048502860185019096528585526107759581359591946044949293909201918190840183828082843750949650505050505050600060006004600050848154811015610002575090527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e600a8402908101547f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101904210806101e65750600481015460ff165b8061026757508060000160009054906101000a9004600160a060020a03168160010160005054846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816007016000505414155b8061027757506001546005820154105b1561109257610002565b61077560043560066020526000908152604090205481565b61077560055481565b61078760043560078054829081101561000257506000526003026000805160206111d18339815191528101547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a820154600160a060020a0382169260a060020a90920460ff16917fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689019084565b61077560025481565b61077560015481565b610830600054600160a060020a031681565b604080516020604435600481810135601f81018490048402850184019095528484526100b9948135946024803595939460649492939101918190840183828082843750949650505050505050600080548190600160a060020a03908116339091161461084d57610002565b61077560035481565b604080516020604435600481810135601f8101849004840285018401909552848452610775948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024909101945090925082915084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806104ab5750604081205460078054909190811015610002579082526003026000805160206111d1833981519152015460a060020a900460ff16155b15610ce557610002565b6100b960043560243560443560005433600160a060020a03908116911614610b1857610002565b604080516020604435600481810135601f810184900484028501840190955284845261077594813594602480359593946064949293910191819084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806105835750604081205460078054909190811015610002579082526003026000805160206111d18339815191520181505460a060020a900460ff16155b15610f1d57610002565b604080516020606435600481810135601f81018490048402850184019095528484526107759481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600460005086815481101561000257908252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01815090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005054149150610cdc565b6100b960043560005433600160a060020a03908116911614610f0857610002565b604051808a600160a060020a031681526020018981526020018060200188815260200187815260200186815260200185815260200184815260200183815260200182810382528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561075e5780601f106107335761010080835404028352916020019161075e565b820191906000526020600020905b81548152906001019060200180831161074157829003601f168201915b50509a505050505050505050505060405180910390f35b60408051918252519081900360200190f35b60408051600160a060020a038616815260208101859052606081018390526080918101828152845460026001821615610100026000190190911604928201839052909160a08301908590801561081e5780601f106107f35761010080835404028352916020019161081e565b820191906000526020600020905b81548152906001019060200180831161080157829003601f168201915b50509550505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b600160a060020a03851660009081526006602052604081205414156108a957604060002060078054918290556001820180825582801582901161095c5760030281600302836000526020600020918201910161095c9190610a4f565b600160a060020a03851660009081526006602052604090205460078054919350908390811015610002575060005250600381026000805160206111d183398151915201805474ff0000000000000000000000000000000000000000191660a060020a85021781555b60408051600160a060020a03871681526020810186905281517f27b022af4a8347100c7a041ce5ccf8e14d644ff05de696315196faae8cd50c9b929181900390910190a15050505050565b505050915081506080604051908101604052808681526020018581526020018481526020014281526020015060076000508381548110156100025790600052602060002090600302016000508151815460208481015160a060020a02600160a060020a03199290921690921774ff00000000000000000000000000000000000000001916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f90810183900482019491929190910190839010610ad357805160ff19168380011785555b50610b03929150610abb565b5050600060028201556001015b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610aa15750610a42565b601f016020900490600052602060002090810190610a4291905b80821115610acf5760008155600101610abb565b5090565b82800160010185558215610a36579182015b82811115610a36578251826000505591602001919060010190610ae5565b50506060919091015160029190910155610911565b600183905560028290556003819055604080518481526020810184905280820183905290517fa439d3fa452be5e0e1e24a8145e715f4fd8b9c08c96a42fd82a855a85e5d57de9181900360600190a1505050565b50508585846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005081905550600260005054603c024201816003016000508190555060008160040160006101000a81548160ff0219169083021790555060008160040160016101000a81548160ff02191690830217905550600081600501600050819055507f646fec02522b41e7125cfc859a64fd4f4cefd5dc3b6237ca0abe251ded1fa881828787876040518085815260200184600160a060020a03168152602001838152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610cc45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600182016005555b50949350505050565b6004805460018101808355909190828015829011610d1c57600a0281600a028360005260206000209182019101610d1c9190610db8565b505060048054929450918491508110156100025790600052602060002090600a02016000508054600160a060020a031916871781556001818101879055855160028381018054600082815260209081902096975091959481161561010002600019011691909104601f90810182900484019391890190839010610ed857805160ff19168380011785555b50610b6c929150610abb565b50506001015b80821115610acf578054600160a060020a03191681556000600182810182905560028381018054848255909281161561010002600019011604601f819010610e9c57505b5060006003830181905560048301805461ffff191690556005830181905560068301819055600783018190556008830180548282559082526020909120610db2916002028101905b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610eba57505b5050600101610e44565b601f016020900490600052602060002090810190610dfc9190610abb565b601f016020900490600052602060002090810190610e929190610abb565b82800160010185558215610da6579182015b82811115610da6578251826000505591602001919060010190610eea565b60008054600160a060020a0319168217905550565b600480548690811015610002576000918252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01905033600160a060020a0316600090815260098201602052604090205490915060ff1660011415610f8457610002565b33600160a060020a031660009081526009820160205260409020805460ff1916600190811790915560058201805490910190558315610fcd576006810180546001019055610fda565b6006810180546000190190555b7fc34f869b7ff431b034b7b9aea9822dac189a685e0b015c7d1be3add3f89128e8858533866040518085815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561107a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b6006810154600354901315611158578060000160009054906101000a9004600160a060020a0316600160a060020a03168160010160005054670de0b6b3a76400000284604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111225780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f15050505060048101805460ff191660011761ff00191661010017905561116d565b60048101805460ff191660011761ff00191690555b60068101546005820154600483015460408051888152602081019490945283810192909252610100900460ff166060830152517fd220b7272a8b6d0d7d6bcdace67b936a8f175e6d5c1b3ee438b72256b32ab3af9181900360800190a1509291505056a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688", +} + +// DAO is an auto generated Go binding around an Ethereum contract. +type DAO struct { + abi abi.ABI +} + +// NewDAO creates a new instance of DAO. +func NewDAO() *DAO { + parsed, err := DAOMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &DAO{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *DAO) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackConstructor is the Go binding used to pack the parameters required for +// contract deployment. +// +// Solidity: constructor(uint256 minimumQuorumForProposals, uint256 minutesForDebate, int256 marginOfVotesForMajority, address congressLeader) returns() +func (dAO *DAO) PackConstructor(minimumQuorumForProposals *big.Int, minutesForDebate *big.Int, marginOfVotesForMajority *big.Int, congressLeader common.Address) []byte { + enc, err := dAO.abi.Pack("", minimumQuorumForProposals, minutesForDebate, marginOfVotesForMajority, congressLeader) + if err != nil { + panic(err) + } + return enc +} + +// PackChangeMembership is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9644fcbd. +// +// Solidity: function changeMembership(address targetMember, bool canVote, string memberName) returns() +func (dAO *DAO) PackChangeMembership(targetMember common.Address, canVote bool, memberName string) []byte { + enc, err := dAO.abi.Pack("changeMembership", targetMember, canVote, memberName) + if err != nil { + panic(err) + } + return enc +} + +// PackChangeVotingRules is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xbcca1fd3. +// +// Solidity: function changeVotingRules(uint256 minimumQuorumForProposals, uint256 minutesForDebate, int256 marginOfVotesForMajority) returns() +func (dAO *DAO) PackChangeVotingRules(minimumQuorumForProposals *big.Int, minutesForDebate *big.Int, marginOfVotesForMajority *big.Int) []byte { + enc, err := dAO.abi.Pack("changeVotingRules", minimumQuorumForProposals, minutesForDebate, marginOfVotesForMajority) + if err != nil { + panic(err) + } + return enc +} + +// PackCheckProposalCode is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xeceb2945. +// +// Solidity: function checkProposalCode(uint256 proposalNumber, address beneficiary, uint256 etherAmount, bytes transactionBytecode) returns(bool codeChecksOut) +func (dAO *DAO) PackCheckProposalCode(proposalNumber *big.Int, beneficiary common.Address, etherAmount *big.Int, transactionBytecode []byte) []byte { + enc, err := dAO.abi.Pack("checkProposalCode", proposalNumber, beneficiary, etherAmount, transactionBytecode) + if err != nil { + panic(err) + } + return enc +} + +// UnpackCheckProposalCode is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xeceb2945. +// +// Solidity: function checkProposalCode(uint256 proposalNumber, address beneficiary, uint256 etherAmount, bytes transactionBytecode) returns(bool codeChecksOut) +func (dAO *DAO) UnpackCheckProposalCode(data []byte) (bool, error) { + out, err := dAO.abi.Unpack("checkProposalCode", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, err +} + +// PackDebatingPeriodInMinutes is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x69bd3436. +// +// Solidity: function debatingPeriodInMinutes() returns(uint256) +func (dAO *DAO) PackDebatingPeriodInMinutes() []byte { + enc, err := dAO.abi.Pack("debatingPeriodInMinutes") + if err != nil { + panic(err) + } + return enc +} + +// UnpackDebatingPeriodInMinutes is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x69bd3436. +// +// Solidity: function debatingPeriodInMinutes() returns(uint256) +func (dAO *DAO) UnpackDebatingPeriodInMinutes(data []byte) (*big.Int, error) { + out, err := dAO.abi.Unpack("debatingPeriodInMinutes", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackExecuteProposal is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x237e9492. +// +// Solidity: function executeProposal(uint256 proposalNumber, bytes transactionBytecode) returns(int256 result) +func (dAO *DAO) PackExecuteProposal(proposalNumber *big.Int, transactionBytecode []byte) []byte { + enc, err := dAO.abi.Pack("executeProposal", proposalNumber, transactionBytecode) + if err != nil { + panic(err) + } + return enc +} + +// UnpackExecuteProposal is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x237e9492. +// +// Solidity: function executeProposal(uint256 proposalNumber, bytes transactionBytecode) returns(int256 result) +func (dAO *DAO) UnpackExecuteProposal(data []byte) (*big.Int, error) { + out, err := dAO.abi.Unpack("executeProposal", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackMajorityMargin is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xaa02a90f. +// +// Solidity: function majorityMargin() returns(int256) +func (dAO *DAO) PackMajorityMargin() []byte { + enc, err := dAO.abi.Pack("majorityMargin") + if err != nil { + panic(err) + } + return enc +} + +// UnpackMajorityMargin is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xaa02a90f. +// +// Solidity: function majorityMargin() returns(int256) +func (dAO *DAO) UnpackMajorityMargin(data []byte) (*big.Int, error) { + out, err := dAO.abi.Unpack("majorityMargin", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackMemberId is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x39106821. +// +// Solidity: function memberId(address ) returns(uint256) +func (dAO *DAO) PackMemberId(arg0 common.Address) []byte { + enc, err := dAO.abi.Pack("memberId", arg0) + if err != nil { + panic(err) + } + return enc +} + +// UnpackMemberId is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x39106821. +// +// Solidity: function memberId(address ) returns(uint256) +func (dAO *DAO) UnpackMemberId(data []byte) (*big.Int, error) { + out, err := dAO.abi.Unpack("memberId", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackMembers is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x5daf08ca. +// +// Solidity: function members(uint256 ) returns(address member, bool canVote, string name, uint256 memberSince) +func (dAO *DAO) PackMembers(arg0 *big.Int) []byte { + enc, err := dAO.abi.Pack("members", arg0) + if err != nil { + panic(err) + } + return enc +} + +// MembersOutput serves as a container for the return parameters of contract +// method Members. +type MembersOutput struct { + Member common.Address + CanVote bool + Name string + MemberSince *big.Int +} + +// UnpackMembers is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x5daf08ca. +// +// Solidity: function members(uint256 ) returns(address member, bool canVote, string name, uint256 memberSince) +func (dAO *DAO) UnpackMembers(data []byte) (MembersOutput, error) { + out, err := dAO.abi.Unpack("members", data) + outstruct := new(MembersOutput) + if err != nil { + return *outstruct, err + } + outstruct.Member = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.CanVote = *abi.ConvertType(out[1], new(bool)).(*bool) + outstruct.Name = *abi.ConvertType(out[2], new(string)).(*string) + outstruct.MemberSince = abi.ConvertType(out[3], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackMinimumQuorum is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8160f0b5. +// +// Solidity: function minimumQuorum() returns(uint256) +func (dAO *DAO) PackMinimumQuorum() []byte { + enc, err := dAO.abi.Pack("minimumQuorum") + if err != nil { + panic(err) + } + return enc +} + +// UnpackMinimumQuorum is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x8160f0b5. +// +// Solidity: function minimumQuorum() returns(uint256) +func (dAO *DAO) UnpackMinimumQuorum(data []byte) (*big.Int, error) { + out, err := dAO.abi.Unpack("minimumQuorum", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackNewProposal is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb1050da5. +// +// Solidity: function newProposal(address beneficiary, uint256 etherAmount, string JobDescription, bytes transactionBytecode) returns(uint256 proposalID) +func (dAO *DAO) PackNewProposal(beneficiary common.Address, etherAmount *big.Int, jobDescription string, transactionBytecode []byte) []byte { + enc, err := dAO.abi.Pack("newProposal", beneficiary, etherAmount, jobDescription, transactionBytecode) + if err != nil { + panic(err) + } + return enc +} + +// UnpackNewProposal is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xb1050da5. +// +// Solidity: function newProposal(address beneficiary, uint256 etherAmount, string JobDescription, bytes transactionBytecode) returns(uint256 proposalID) +func (dAO *DAO) UnpackNewProposal(data []byte) (*big.Int, error) { + out, err := dAO.abi.Unpack("newProposal", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackNumProposals is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x400e3949. +// +// Solidity: function numProposals() returns(uint256) +func (dAO *DAO) PackNumProposals() []byte { + enc, err := dAO.abi.Pack("numProposals") + if err != nil { + panic(err) + } + return enc +} + +// UnpackNumProposals is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x400e3949. +// +// Solidity: function numProposals() returns(uint256) +func (dAO *DAO) UnpackNumProposals(data []byte) (*big.Int, error) { + out, err := dAO.abi.Unpack("numProposals", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackOwner is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8da5cb5b. +// +// Solidity: function owner() returns(address) +func (dAO *DAO) PackOwner() []byte { + enc, err := dAO.abi.Pack("owner") + if err != nil { + panic(err) + } + return enc +} + +// UnpackOwner is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x8da5cb5b. +// +// Solidity: function owner() returns(address) +func (dAO *DAO) UnpackOwner(data []byte) (common.Address, error) { + out, err := dAO.abi.Unpack("owner", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, err +} + +// PackProposals is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x013cf08b. +// +// Solidity: function proposals(uint256 ) returns(address recipient, uint256 amount, string description, uint256 votingDeadline, bool executed, bool proposalPassed, uint256 numberOfVotes, int256 currentResult, bytes32 proposalHash) +func (dAO *DAO) PackProposals(arg0 *big.Int) []byte { + enc, err := dAO.abi.Pack("proposals", arg0) + if err != nil { + panic(err) + } + return enc +} + +// ProposalsOutput serves as a container for the return parameters of contract +// method Proposals. +type ProposalsOutput struct { + Recipient common.Address + Amount *big.Int + Description string + VotingDeadline *big.Int + Executed bool + ProposalPassed bool + NumberOfVotes *big.Int + CurrentResult *big.Int + ProposalHash [32]byte +} + +// UnpackProposals is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x013cf08b. +// +// Solidity: function proposals(uint256 ) returns(address recipient, uint256 amount, string description, uint256 votingDeadline, bool executed, bool proposalPassed, uint256 numberOfVotes, int256 currentResult, bytes32 proposalHash) +func (dAO *DAO) UnpackProposals(data []byte) (ProposalsOutput, error) { + out, err := dAO.abi.Unpack("proposals", data) + outstruct := new(ProposalsOutput) + if err != nil { + return *outstruct, err + } + outstruct.Recipient = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.Amount = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + outstruct.Description = *abi.ConvertType(out[2], new(string)).(*string) + outstruct.VotingDeadline = abi.ConvertType(out[3], new(big.Int)).(*big.Int) + outstruct.Executed = *abi.ConvertType(out[4], new(bool)).(*bool) + outstruct.ProposalPassed = *abi.ConvertType(out[5], new(bool)).(*bool) + outstruct.NumberOfVotes = abi.ConvertType(out[6], new(big.Int)).(*big.Int) + outstruct.CurrentResult = abi.ConvertType(out[7], new(big.Int)).(*big.Int) + outstruct.ProposalHash = *abi.ConvertType(out[8], new([32]byte)).(*[32]byte) + return *outstruct, err + +} + +// PackTransferOwnership is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (dAO *DAO) PackTransferOwnership(newOwner common.Address) []byte { + enc, err := dAO.abi.Pack("transferOwnership", newOwner) + if err != nil { + panic(err) + } + return enc +} + +// PackVote is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd3c0715b. +// +// Solidity: function vote(uint256 proposalNumber, bool supportsProposal, string justificationText) returns(uint256 voteID) +func (dAO *DAO) PackVote(proposalNumber *big.Int, supportsProposal bool, justificationText string) []byte { + enc, err := dAO.abi.Pack("vote", proposalNumber, supportsProposal, justificationText) + if err != nil { + panic(err) + } + return enc +} + +// UnpackVote is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xd3c0715b. +// +// Solidity: function vote(uint256 proposalNumber, bool supportsProposal, string justificationText) returns(uint256 voteID) +func (dAO *DAO) UnpackVote(data []byte) (*big.Int, error) { + out, err := dAO.abi.Unpack("vote", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// DAOChangeOfRules represents a ChangeOfRules event raised by the DAO contract. +type DAOChangeOfRules struct { + MinimumQuorum *big.Int + DebatingPeriodInMinutes *big.Int + MajorityMargin *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const DAOChangeOfRulesEventName = "ChangeOfRules" + +// ContractEventName returns the user-defined event name. +func (DAOChangeOfRules) ContractEventName() string { + return DAOChangeOfRulesEventName +} + +// UnpackChangeOfRulesEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event ChangeOfRules(uint256 minimumQuorum, uint256 debatingPeriodInMinutes, int256 majorityMargin) +func (dAO *DAO) UnpackChangeOfRulesEvent(log *types.Log) (*DAOChangeOfRules, error) { + event := "ChangeOfRules" + if log.Topics[0] != dAO.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(DAOChangeOfRules) + if len(log.Data) > 0 { + if err := dAO.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range dAO.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// DAOMembershipChanged represents a MembershipChanged event raised by the DAO contract. +type DAOMembershipChanged struct { + Member common.Address + IsMember bool + Raw *types.Log // Blockchain specific contextual infos +} + +const DAOMembershipChangedEventName = "MembershipChanged" + +// ContractEventName returns the user-defined event name. +func (DAOMembershipChanged) ContractEventName() string { + return DAOMembershipChangedEventName +} + +// UnpackMembershipChangedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event MembershipChanged(address member, bool isMember) +func (dAO *DAO) UnpackMembershipChangedEvent(log *types.Log) (*DAOMembershipChanged, error) { + event := "MembershipChanged" + if log.Topics[0] != dAO.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(DAOMembershipChanged) + if len(log.Data) > 0 { + if err := dAO.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range dAO.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// DAOProposalAdded represents a ProposalAdded event raised by the DAO contract. +type DAOProposalAdded struct { + ProposalID *big.Int + Recipient common.Address + Amount *big.Int + Description string + Raw *types.Log // Blockchain specific contextual infos +} + +const DAOProposalAddedEventName = "ProposalAdded" + +// ContractEventName returns the user-defined event name. +func (DAOProposalAdded) ContractEventName() string { + return DAOProposalAddedEventName +} + +// UnpackProposalAddedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event ProposalAdded(uint256 proposalID, address recipient, uint256 amount, string description) +func (dAO *DAO) UnpackProposalAddedEvent(log *types.Log) (*DAOProposalAdded, error) { + event := "ProposalAdded" + if log.Topics[0] != dAO.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(DAOProposalAdded) + if len(log.Data) > 0 { + if err := dAO.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range dAO.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// DAOProposalTallied represents a ProposalTallied event raised by the DAO contract. +type DAOProposalTallied struct { + ProposalID *big.Int + Result *big.Int + Quorum *big.Int + Active bool + Raw *types.Log // Blockchain specific contextual infos +} + +const DAOProposalTalliedEventName = "ProposalTallied" + +// ContractEventName returns the user-defined event name. +func (DAOProposalTallied) ContractEventName() string { + return DAOProposalTalliedEventName +} + +// UnpackProposalTalliedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event ProposalTallied(uint256 proposalID, int256 result, uint256 quorum, bool active) +func (dAO *DAO) UnpackProposalTalliedEvent(log *types.Log) (*DAOProposalTallied, error) { + event := "ProposalTallied" + if log.Topics[0] != dAO.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(DAOProposalTallied) + if len(log.Data) > 0 { + if err := dAO.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range dAO.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// DAOVoted represents a Voted event raised by the DAO contract. +type DAOVoted struct { + ProposalID *big.Int + Position bool + Voter common.Address + Justification string + Raw *types.Log // Blockchain specific contextual infos +} + +const DAOVotedEventName = "Voted" + +// ContractEventName returns the user-defined event name. +func (DAOVoted) ContractEventName() string { + return DAOVotedEventName +} + +// UnpackVotedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event Voted(uint256 proposalID, bool position, address voter, string justification) +func (dAO *DAO) UnpackVotedEvent(log *types.Log) (*DAOVoted, error) { + event := "Voted" + if log.Topics[0] != dAO.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(DAOVoted) + if len(log.Data) > 0 { + if err := dAO.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range dAO.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/abigen/testdata/v2/deeplynestedarray.go.txt b/accounts/abi/abigen/testdata/v2/deeplynestedarray.go.txt new file mode 100644 index 0000000000..00f717d020 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/deeplynestedarray.go.txt @@ -0,0 +1,114 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// DeeplyNestedArrayMetaData contains all meta data concerning the DeeplyNestedArray contract. +var DeeplyNestedArrayMetaData = bind.MetaData{ + ABI: "[{\"constant\":false,\"inputs\":[{\"name\":\"arr\",\"type\":\"uint64[3][4][5]\"}],\"name\":\"storeDeepUintArray\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"retrieveDeepArray\",\"outputs\":[{\"name\":\"\",\"type\":\"uint64[3][4][5]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"deepUint64Array\",\"outputs\":[{\"name\":\"\",\"type\":\"uint64\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]", + ID: "3a44c26b21f02743d5dbeb02d24a67bf41", + Bin: "0x6060604052341561000f57600080fd5b6106438061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063344248551461005c5780638ed4573a1461011457806398ed1856146101ab575b600080fd5b341561006757600080fd5b610112600480806107800190600580602002604051908101604052809291906000905b828210156101055783826101800201600480602002604051908101604052809291906000905b828210156100f25783826060020160038060200260405190810160405280929190826003602002808284378201915050505050815260200190600101906100b0565b505050508152602001906001019061008a565b5050505091905050610208565b005b341561011f57600080fd5b61012761021d565b604051808260056000925b8184101561019b578284602002015160046000925b8184101561018d5782846020020151600360200280838360005b8381101561017c578082015181840152602081019050610161565b505050509050019260010192610147565b925050509260010192610132565b9250505091505060405180910390f35b34156101b657600080fd5b6101de6004808035906020019091908035906020019091908035906020019091905050610309565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b80600090600561021992919061035f565b5050565b6102256103b0565b6000600580602002604051908101604052809291906000905b8282101561030057838260040201600480602002604051908101604052809291906000905b828210156102ed578382016003806020026040519081016040528092919082600380156102d9576020028201916000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff16815260200190600801906020826007010492830192600103820291508084116102945790505b505050505081526020019060010190610263565b505050508152602001906001019061023e565b50505050905090565b60008360058110151561031857fe5b600402018260048110151561032957fe5b018160038110151561033757fe5b6004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b826005600402810192821561039f579160200282015b8281111561039e5782518290600461038e9291906103df565b5091602001919060040190610375565b5b5090506103ac919061042d565b5090565b610780604051908101604052806005905b6103c9610459565b8152602001906001900390816103c15790505090565b826004810192821561041c579160200282015b8281111561041b5782518290600361040b929190610488565b50916020019190600101906103f2565b5b5090506104299190610536565b5090565b61045691905b8082111561045257600081816104499190610562565b50600401610433565b5090565b90565b610180604051908101604052806004905b6104726105a7565b81526020019060019003908161046a5790505090565b82600380016004900481019282156105255791602002820160005b838211156104ef57835183826101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555092602001926008016020816007010492830192600103026104a3565b80156105235782816101000a81549067ffffffffffffffff02191690556008016020816007010492830192600103026104ef565b505b50905061053291906105d9565b5090565b61055f91905b8082111561055b57600081816105529190610610565b5060010161053c565b5090565b90565b50600081816105719190610610565b50600101600081816105839190610610565b50600101600081816105959190610610565b5060010160006105a59190610610565b565b6060604051908101604052806003905b600067ffffffffffffffff168152602001906001900390816105b75790505090565b61060d91905b8082111561060957600081816101000a81549067ffffffffffffffff0219169055506001016105df565b5090565b90565b50600090555600a165627a7a7230582087e5a43f6965ab6ef7a4ff056ab80ed78fd8c15cff57715a1bf34ec76a93661c0029", +} + +// DeeplyNestedArray is an auto generated Go binding around an Ethereum contract. +type DeeplyNestedArray struct { + abi abi.ABI +} + +// NewDeeplyNestedArray creates a new instance of DeeplyNestedArray. +func NewDeeplyNestedArray() *DeeplyNestedArray { + parsed, err := DeeplyNestedArrayMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &DeeplyNestedArray{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *DeeplyNestedArray) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackDeepUint64Array is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x98ed1856. +// +// Solidity: function deepUint64Array(uint256 , uint256 , uint256 ) view returns(uint64) +func (deeplyNestedArray *DeeplyNestedArray) PackDeepUint64Array(arg0 *big.Int, arg1 *big.Int, arg2 *big.Int) []byte { + enc, err := deeplyNestedArray.abi.Pack("deepUint64Array", arg0, arg1, arg2) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDeepUint64Array is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x98ed1856. +// +// Solidity: function deepUint64Array(uint256 , uint256 , uint256 ) view returns(uint64) +func (deeplyNestedArray *DeeplyNestedArray) UnpackDeepUint64Array(data []byte) (uint64, error) { + out, err := deeplyNestedArray.abi.Unpack("deepUint64Array", data) + if err != nil { + return *new(uint64), err + } + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + return out0, err +} + +// PackRetrieveDeepArray is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8ed4573a. +// +// Solidity: function retrieveDeepArray() view returns(uint64[3][4][5]) +func (deeplyNestedArray *DeeplyNestedArray) PackRetrieveDeepArray() []byte { + enc, err := deeplyNestedArray.abi.Pack("retrieveDeepArray") + if err != nil { + panic(err) + } + return enc +} + +// UnpackRetrieveDeepArray is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x8ed4573a. +// +// Solidity: function retrieveDeepArray() view returns(uint64[3][4][5]) +func (deeplyNestedArray *DeeplyNestedArray) UnpackRetrieveDeepArray(data []byte) ([5][4][3]uint64, error) { + out, err := deeplyNestedArray.abi.Unpack("retrieveDeepArray", data) + if err != nil { + return *new([5][4][3]uint64), err + } + out0 := *abi.ConvertType(out[0], new([5][4][3]uint64)).(*[5][4][3]uint64) + return out0, err +} + +// PackStoreDeepUintArray is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x34424855. +// +// Solidity: function storeDeepUintArray(uint64[3][4][5] arr) returns() +func (deeplyNestedArray *DeeplyNestedArray) PackStoreDeepUintArray(arr [5][4][3]uint64) []byte { + enc, err := deeplyNestedArray.abi.Pack("storeDeepUintArray", arr) + if err != nil { + panic(err) + } + return enc +} diff --git a/accounts/abi/abigen/testdata/v2/empty.go.txt b/accounts/abi/abigen/testdata/v2/empty.go.txt new file mode 100644 index 0000000000..7082e20799 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/empty.go.txt @@ -0,0 +1,52 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// EmptyMetaData contains all meta data concerning the Empty contract. +var EmptyMetaData = bind.MetaData{ + ABI: "[]", + ID: "c4ce3210982aa6fc94dabe46dc1dbf454d", + Bin: "0x606060405260068060106000396000f3606060405200", +} + +// Empty is an auto generated Go binding around an Ethereum contract. +type Empty struct { + abi abi.ABI +} + +// NewEmpty creates a new instance of Empty. +func NewEmpty() *Empty { + parsed, err := EmptyMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Empty{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Empty) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} diff --git a/accounts/abi/abigen/testdata/v2/eventchecker.go.txt b/accounts/abi/abigen/testdata/v2/eventchecker.go.txt new file mode 100644 index 0000000000..92558c5efe --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/eventchecker.go.txt @@ -0,0 +1,261 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// EventCheckerMetaData contains all meta data concerning the EventChecker contract. +var EventCheckerMetaData = bind.MetaData{ + ABI: "[{\"type\":\"event\",\"name\":\"empty\",\"inputs\":[]},{\"type\":\"event\",\"name\":\"indexed\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"indexed\":true},{\"name\":\"num\",\"type\":\"int256\",\"indexed\":true}]},{\"type\":\"event\",\"name\":\"mixed\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"indexed\":true},{\"name\":\"num\",\"type\":\"int256\"}]},{\"type\":\"event\",\"name\":\"anonymous\",\"anonymous\":true,\"inputs\":[]},{\"type\":\"event\",\"name\":\"dynamic\",\"inputs\":[{\"name\":\"idxStr\",\"type\":\"string\",\"indexed\":true},{\"name\":\"idxDat\",\"type\":\"bytes\",\"indexed\":true},{\"name\":\"str\",\"type\":\"string\"},{\"name\":\"dat\",\"type\":\"bytes\"}]},{\"type\":\"event\",\"name\":\"unnamed\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"indexed\":true},{\"name\":\"\",\"type\":\"uint256\",\"indexed\":true}]}]", + ID: "253d421f98e29b25315bde79c1251ab27c", +} + +// EventChecker is an auto generated Go binding around an Ethereum contract. +type EventChecker struct { + abi abi.ABI +} + +// NewEventChecker creates a new instance of EventChecker. +func NewEventChecker() *EventChecker { + parsed, err := EventCheckerMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &EventChecker{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *EventChecker) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// EventCheckerDynamic represents a dynamic event raised by the EventChecker contract. +type EventCheckerDynamic struct { + IdxStr common.Hash + IdxDat common.Hash + Str string + Dat []byte + Raw *types.Log // Blockchain specific contextual infos +} + +const EventCheckerDynamicEventName = "dynamic" + +// ContractEventName returns the user-defined event name. +func (EventCheckerDynamic) ContractEventName() string { + return EventCheckerDynamicEventName +} + +// UnpackDynamicEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event dynamic(string indexed idxStr, bytes indexed idxDat, string str, bytes dat) +func (eventChecker *EventChecker) UnpackDynamicEvent(log *types.Log) (*EventCheckerDynamic, error) { + event := "dynamic" + if log.Topics[0] != eventChecker.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(EventCheckerDynamic) + if len(log.Data) > 0 { + if err := eventChecker.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range eventChecker.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// EventCheckerEmpty represents a empty event raised by the EventChecker contract. +type EventCheckerEmpty struct { + Raw *types.Log // Blockchain specific contextual infos +} + +const EventCheckerEmptyEventName = "empty" + +// ContractEventName returns the user-defined event name. +func (EventCheckerEmpty) ContractEventName() string { + return EventCheckerEmptyEventName +} + +// UnpackEmptyEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event empty() +func (eventChecker *EventChecker) UnpackEmptyEvent(log *types.Log) (*EventCheckerEmpty, error) { + event := "empty" + if log.Topics[0] != eventChecker.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(EventCheckerEmpty) + if len(log.Data) > 0 { + if err := eventChecker.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range eventChecker.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// EventCheckerIndexed represents a indexed event raised by the EventChecker contract. +type EventCheckerIndexed struct { + Addr common.Address + Num *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const EventCheckerIndexedEventName = "indexed" + +// ContractEventName returns the user-defined event name. +func (EventCheckerIndexed) ContractEventName() string { + return EventCheckerIndexedEventName +} + +// UnpackIndexedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event indexed(address indexed addr, int256 indexed num) +func (eventChecker *EventChecker) UnpackIndexedEvent(log *types.Log) (*EventCheckerIndexed, error) { + event := "indexed" + if log.Topics[0] != eventChecker.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(EventCheckerIndexed) + if len(log.Data) > 0 { + if err := eventChecker.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range eventChecker.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// EventCheckerMixed represents a mixed event raised by the EventChecker contract. +type EventCheckerMixed struct { + Addr common.Address + Num *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const EventCheckerMixedEventName = "mixed" + +// ContractEventName returns the user-defined event name. +func (EventCheckerMixed) ContractEventName() string { + return EventCheckerMixedEventName +} + +// UnpackMixedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event mixed(address indexed addr, int256 num) +func (eventChecker *EventChecker) UnpackMixedEvent(log *types.Log) (*EventCheckerMixed, error) { + event := "mixed" + if log.Topics[0] != eventChecker.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(EventCheckerMixed) + if len(log.Data) > 0 { + if err := eventChecker.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range eventChecker.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// EventCheckerUnnamed represents a unnamed event raised by the EventChecker contract. +type EventCheckerUnnamed struct { + Arg0 *big.Int + Arg1 *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const EventCheckerUnnamedEventName = "unnamed" + +// ContractEventName returns the user-defined event name. +func (EventCheckerUnnamed) ContractEventName() string { + return EventCheckerUnnamedEventName +} + +// UnpackUnnamedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event unnamed(uint256 indexed arg0, uint256 indexed arg1) +func (eventChecker *EventChecker) UnpackUnnamedEvent(log *types.Log) (*EventCheckerUnnamed, error) { + event := "unnamed" + if log.Topics[0] != eventChecker.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(EventCheckerUnnamed) + if len(log.Data) > 0 { + if err := eventChecker.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range eventChecker.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/abigen/testdata/v2/getter.go.txt b/accounts/abi/abigen/testdata/v2/getter.go.txt new file mode 100644 index 0000000000..8e6e7debbf --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/getter.go.txt @@ -0,0 +1,89 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// GetterMetaData contains all meta data concerning the Getter contract. +var GetterMetaData = bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"getter\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"int256\"},{\"name\":\"\",\"type\":\"bytes32\"}],\"type\":\"function\"}]", + ID: "e23a74c8979fe93c9fff15e4f51535ad54", + Bin: "0x606060405260dc8060106000396000f3606060405260e060020a6000350463993a04b78114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3", +} + +// Getter is an auto generated Go binding around an Ethereum contract. +type Getter struct { + abi abi.ABI +} + +// NewGetter creates a new instance of Getter. +func NewGetter() *Getter { + parsed, err := GetterMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Getter{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Getter) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackGetter is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x993a04b7. +// +// Solidity: function getter() returns(string, int256, bytes32) +func (getter *Getter) PackGetter() []byte { + enc, err := getter.abi.Pack("getter") + if err != nil { + panic(err) + } + return enc +} + +// GetterOutput serves as a container for the return parameters of contract +// method Getter. +type GetterOutput struct { + Arg0 string + Arg1 *big.Int + Arg2 [32]byte +} + +// UnpackGetter is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x993a04b7. +// +// Solidity: function getter() returns(string, int256, bytes32) +func (getter *Getter) UnpackGetter(data []byte) (GetterOutput, error) { + out, err := getter.abi.Unpack("getter", data) + outstruct := new(GetterOutput) + if err != nil { + return *outstruct, err + } + outstruct.Arg0 = *abi.ConvertType(out[0], new(string)).(*string) + outstruct.Arg1 = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + outstruct.Arg2 = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + return *outstruct, err + +} diff --git a/accounts/abi/abigen/testdata/v2/identifiercollision.go.txt b/accounts/abi/abigen/testdata/v2/identifiercollision.go.txt new file mode 100644 index 0000000000..60554aac13 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/identifiercollision.go.txt @@ -0,0 +1,102 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// IdentifierCollisionMetaData contains all meta data concerning the IdentifierCollision contract. +var IdentifierCollisionMetaData = bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"MyVar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"_myVar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]", + ID: "1863c5622f8ac2c09c42f063ca883fe438", + Bin: "0x60806040523480156100115760006000fd5b50610017565b60c3806100256000396000f3fe608060405234801560105760006000fd5b506004361060365760003560e01c806301ad4d8714603c5780634ef1f0ad146058576036565b60006000fd5b60426074565b6040518082815260200191505060405180910390f35b605e607d565b6040518082815260200191505060405180910390f35b60006000505481565b60006000600050549050608b565b9056fea265627a7a7231582067c8d84688b01c4754ba40a2a871cede94ea1f28b5981593ab2a45b46ac43af664736f6c634300050c0032", +} + +// IdentifierCollision is an auto generated Go binding around an Ethereum contract. +type IdentifierCollision struct { + abi abi.ABI +} + +// NewIdentifierCollision creates a new instance of IdentifierCollision. +func NewIdentifierCollision() *IdentifierCollision { + parsed, err := IdentifierCollisionMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &IdentifierCollision{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *IdentifierCollision) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackMyVar is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x4ef1f0ad. +// +// Solidity: function MyVar() view returns(uint256) +func (identifierCollision *IdentifierCollision) PackMyVar() []byte { + enc, err := identifierCollision.abi.Pack("MyVar") + if err != nil { + panic(err) + } + return enc +} + +// UnpackMyVar is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x4ef1f0ad. +// +// Solidity: function MyVar() view returns(uint256) +func (identifierCollision *IdentifierCollision) UnpackMyVar(data []byte) (*big.Int, error) { + out, err := identifierCollision.abi.Unpack("MyVar", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackPubVar is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x01ad4d87. +// +// Solidity: function _myVar() view returns(uint256) +func (identifierCollision *IdentifierCollision) PackPubVar() []byte { + enc, err := identifierCollision.abi.Pack("_myVar") + if err != nil { + panic(err) + } + return enc +} + +// UnpackPubVar is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x01ad4d87. +// +// Solidity: function _myVar() view returns(uint256) +func (identifierCollision *IdentifierCollision) UnpackPubVar(data []byte) (*big.Int, error) { + out, err := identifierCollision.abi.Unpack("_myVar", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} diff --git a/accounts/abi/abigen/testdata/v2/inputchecker.go.txt b/accounts/abi/abigen/testdata/v2/inputchecker.go.txt new file mode 100644 index 0000000000..7b226aa90b --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/inputchecker.go.txt @@ -0,0 +1,123 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// InputCheckerMetaData contains all meta data concerning the InputChecker contract. +var InputCheckerMetaData = bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"noInput\",\"constant\":true,\"inputs\":[],\"outputs\":[]},{\"type\":\"function\",\"name\":\"namedInput\",\"constant\":true,\"inputs\":[{\"name\":\"str\",\"type\":\"string\"}],\"outputs\":[]},{\"type\":\"function\",\"name\":\"anonInput\",\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"string\"}],\"outputs\":[]},{\"type\":\"function\",\"name\":\"namedInputs\",\"constant\":true,\"inputs\":[{\"name\":\"str1\",\"type\":\"string\"},{\"name\":\"str2\",\"type\":\"string\"}],\"outputs\":[]},{\"type\":\"function\",\"name\":\"anonInputs\",\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"}],\"outputs\":[]},{\"type\":\"function\",\"name\":\"mixedInputs\",\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"str\",\"type\":\"string\"}],\"outputs\":[]}]", + ID: "e551ce092312e54f54f45ffdf06caa4cdc", +} + +// InputChecker is an auto generated Go binding around an Ethereum contract. +type InputChecker struct { + abi abi.ABI +} + +// NewInputChecker creates a new instance of InputChecker. +func NewInputChecker() *InputChecker { + parsed, err := InputCheckerMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &InputChecker{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *InputChecker) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackAnonInput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x3e708e82. +// +// Solidity: function anonInput(string ) returns() +func (inputChecker *InputChecker) PackAnonInput(arg0 string) []byte { + enc, err := inputChecker.abi.Pack("anonInput", arg0) + if err != nil { + panic(err) + } + return enc +} + +// PackAnonInputs is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x28160527. +// +// Solidity: function anonInputs(string , string ) returns() +func (inputChecker *InputChecker) PackAnonInputs(arg0 string, arg1 string) []byte { + enc, err := inputChecker.abi.Pack("anonInputs", arg0, arg1) + if err != nil { + panic(err) + } + return enc +} + +// PackMixedInputs is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc689ebdc. +// +// Solidity: function mixedInputs(string , string str) returns() +func (inputChecker *InputChecker) PackMixedInputs(arg0 string, str string) []byte { + enc, err := inputChecker.abi.Pack("mixedInputs", arg0, str) + if err != nil { + panic(err) + } + return enc +} + +// PackNamedInput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0d402005. +// +// Solidity: function namedInput(string str) returns() +func (inputChecker *InputChecker) PackNamedInput(str string) []byte { + enc, err := inputChecker.abi.Pack("namedInput", str) + if err != nil { + panic(err) + } + return enc +} + +// PackNamedInputs is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x63c796ed. +// +// Solidity: function namedInputs(string str1, string str2) returns() +func (inputChecker *InputChecker) PackNamedInputs(str1 string, str2 string) []byte { + enc, err := inputChecker.abi.Pack("namedInputs", str1, str2) + if err != nil { + panic(err) + } + return enc +} + +// PackNoInput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x53539029. +// +// Solidity: function noInput() returns() +func (inputChecker *InputChecker) PackNoInput() []byte { + enc, err := inputChecker.abi.Pack("noInput") + if err != nil { + panic(err) + } + return enc +} diff --git a/accounts/abi/abigen/testdata/v2/interactor.go.txt b/accounts/abi/abigen/testdata/v2/interactor.go.txt new file mode 100644 index 0000000000..cc0900856e --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/interactor.go.txt @@ -0,0 +1,126 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// InteractorMetaData contains all meta data concerning the Interactor contract. +var InteractorMetaData = bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"transactString\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"deployString\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"str\",\"type\":\"string\"}],\"name\":\"transact\",\"outputs\":[],\"type\":\"function\"},{\"inputs\":[{\"name\":\"str\",\"type\":\"string\"}],\"type\":\"constructor\"}]", + ID: "f63980878028f3242c9033fdc30fd21a81", + Bin: "0x6060604052604051610328380380610328833981016040528051018060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10608d57805160ff19168380011785555b50607c9291505b8082111560ba57838155600101606b565b50505061026a806100be6000396000f35b828001600101855582156064579182015b828111156064578251826000505591602001919060010190609e565b509056606060405260e060020a60003504630d86a0e181146100315780636874e8091461008d578063d736c513146100ea575b005b610190600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b61019060008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b60206004803580820135601f81018490049093026080908101604052606084815261002f946024939192918401918190838280828437509496505050505050508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023157805160ff19168380011785555b506102619291505b808211156102665760008155830161017d565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161020c57829003601f168201915b505050505081565b82800160010185558215610175579182015b82811115610175578251826000505591602001919060010190610243565b505050565b509056", +} + +// Interactor is an auto generated Go binding around an Ethereum contract. +type Interactor struct { + abi abi.ABI +} + +// NewInteractor creates a new instance of Interactor. +func NewInteractor() *Interactor { + parsed, err := InteractorMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Interactor{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Interactor) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackConstructor is the Go binding used to pack the parameters required for +// contract deployment. +// +// Solidity: constructor(string str) returns() +func (interactor *Interactor) PackConstructor(str string) []byte { + enc, err := interactor.abi.Pack("", str) + if err != nil { + panic(err) + } + return enc +} + +// PackDeployString is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x6874e809. +// +// Solidity: function deployString() returns(string) +func (interactor *Interactor) PackDeployString() []byte { + enc, err := interactor.abi.Pack("deployString") + if err != nil { + panic(err) + } + return enc +} + +// UnpackDeployString is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x6874e809. +// +// Solidity: function deployString() returns(string) +func (interactor *Interactor) UnpackDeployString(data []byte) (string, error) { + out, err := interactor.abi.Unpack("deployString", data) + if err != nil { + return *new(string), err + } + out0 := *abi.ConvertType(out[0], new(string)).(*string) + return out0, err +} + +// PackTransact is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd736c513. +// +// Solidity: function transact(string str) returns() +func (interactor *Interactor) PackTransact(str string) []byte { + enc, err := interactor.abi.Pack("transact", str) + if err != nil { + panic(err) + } + return enc +} + +// PackTransactString is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0d86a0e1. +// +// Solidity: function transactString() returns(string) +func (interactor *Interactor) PackTransactString() []byte { + enc, err := interactor.abi.Pack("transactString") + if err != nil { + panic(err) + } + return enc +} + +// UnpackTransactString is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x0d86a0e1. +// +// Solidity: function transactString() returns(string) +func (interactor *Interactor) UnpackTransactString(data []byte) (string, error) { + out, err := interactor.abi.Unpack("transactString", data) + if err != nil { + return *new(string), err + } + out0 := *abi.ConvertType(out[0], new(string)).(*string) + return out0, err +} diff --git a/accounts/abi/abigen/testdata/v2/nameconflict.go.txt b/accounts/abi/abigen/testdata/v2/nameconflict.go.txt new file mode 100644 index 0000000000..6228bf7cc7 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/nameconflict.go.txt @@ -0,0 +1,137 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// Oraclerequest is an auto generated low-level Go binding around an user-defined struct. +type Oraclerequest struct { + Data []byte + Data0 []byte +} + +// NameConflictMetaData contains all meta data concerning the NameConflict contract. +var NameConflictMetaData = bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"msg\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"_msg\",\"type\":\"int256\"}],\"name\":\"log\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"internalType\":\"structoracle.request\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"addRequest\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"internalType\":\"structoracle.request\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "8f6e2703b307244ae6bd61ed94ce959cf9", + Bin: "0x608060405234801561001057600080fd5b5061042b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063c2bb515f1461003b578063cce7b04814610059575b600080fd5b610043610075565b60405161005091906101af565b60405180910390f35b610073600480360381019061006e91906103ac565b6100b5565b005b61007d6100b8565b604051806040016040528060405180602001604052806000815250815260200160405180602001604052806000815250815250905090565b50565b604051806040016040528060608152602001606081525090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561010c5780820151818401526020810190506100f1565b8381111561011b576000848401525b50505050565b6000601f19601f8301169050919050565b600061013d826100d2565b61014781856100dd565b93506101578185602086016100ee565b61016081610121565b840191505092915050565b600060408301600083015184820360008601526101888282610132565b915050602083015184820360208601526101a28282610132565b9150508091505092915050565b600060208201905081810360008301526101c9818461016b565b905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61022282610121565b810181811067ffffffffffffffff82111715610241576102406101ea565b5b80604052505050565b60006102546101d1565b90506102608282610219565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561028f5761028e6101ea565b5b61029882610121565b9050602081019050919050565b82818337600083830152505050565b60006102c76102c284610274565b61024a565b9050828152602081018484840111156102e3576102e261026f565b5b6102ee8482856102a5565b509392505050565b600082601f83011261030b5761030a61026a565b5b813561031b8482602086016102b4565b91505092915050565b60006040828403121561033a576103396101e5565b5b610344604061024a565b9050600082013567ffffffffffffffff81111561036457610363610265565b5b610370848285016102f6565b600083015250602082013567ffffffffffffffff81111561039457610393610265565b5b6103a0848285016102f6565b60208301525092915050565b6000602082840312156103c2576103c16101db565b5b600082013567ffffffffffffffff8111156103e0576103df6101e0565b5b6103ec84828501610324565b9150509291505056fea264697066735822122033bca1606af9b6aeba1673f98c52003cec19338539fb44b86690ce82c51483b564736f6c634300080e0033", +} + +// NameConflict is an auto generated Go binding around an Ethereum contract. +type NameConflict struct { + abi abi.ABI +} + +// NewNameConflict creates a new instance of NameConflict. +func NewNameConflict() *NameConflict { + parsed, err := NameConflictMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &NameConflict{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *NameConflict) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackAddRequest is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xcce7b048. +// +// Solidity: function addRequest((bytes,bytes) req) pure returns() +func (nameConflict *NameConflict) PackAddRequest(req Oraclerequest) []byte { + enc, err := nameConflict.abi.Pack("addRequest", req) + if err != nil { + panic(err) + } + return enc +} + +// PackGetRequest is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc2bb515f. +// +// Solidity: function getRequest() pure returns((bytes,bytes)) +func (nameConflict *NameConflict) PackGetRequest() []byte { + enc, err := nameConflict.abi.Pack("getRequest") + if err != nil { + panic(err) + } + return enc +} + +// UnpackGetRequest is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xc2bb515f. +// +// Solidity: function getRequest() pure returns((bytes,bytes)) +func (nameConflict *NameConflict) UnpackGetRequest(data []byte) (Oraclerequest, error) { + out, err := nameConflict.abi.Unpack("getRequest", data) + if err != nil { + return *new(Oraclerequest), err + } + out0 := *abi.ConvertType(out[0], new(Oraclerequest)).(*Oraclerequest) + return out0, err +} + +// NameConflictLog represents a log event raised by the NameConflict contract. +type NameConflictLog struct { + Msg *big.Int + Msg0 *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const NameConflictLogEventName = "log" + +// ContractEventName returns the user-defined event name. +func (NameConflictLog) ContractEventName() string { + return NameConflictLogEventName +} + +// UnpackLogEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event log(int256 msg, int256 _msg) +func (nameConflict *NameConflict) UnpackLogEvent(log *types.Log) (*NameConflictLog, error) { + event := "log" + if log.Topics[0] != nameConflict.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(NameConflictLog) + if len(log.Data) > 0 { + if err := nameConflict.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range nameConflict.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/abigen/testdata/v2/numericmethodname.go.txt b/accounts/abi/abigen/testdata/v2/numericmethodname.go.txt new file mode 100644 index 0000000000..5a2208e0d4 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/numericmethodname.go.txt @@ -0,0 +1,129 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// NumericMethodNameMetaData contains all meta data concerning the NumericMethodName contract. +var NumericMethodNameMetaData = bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_param\",\"type\":\"address\"}],\"name\":\"_1TestEvent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_1test\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"__1test\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"__2test\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "a691b347afbc44b90dd9a1dfbc65661904", + Bin: "0x6080604052348015600f57600080fd5b5060958061001e6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80639d993132146041578063d02767c7146049578063ffa02795146051575b600080fd5b60476059565b005b604f605b565b005b6057605d565b005b565b565b56fea26469706673582212200382ca602dff96a7e2ba54657985e2b4ac423a56abe4a1f0667bc635c4d4371f64736f6c63430008110033", +} + +// NumericMethodName is an auto generated Go binding around an Ethereum contract. +type NumericMethodName struct { + abi abi.ABI +} + +// NewNumericMethodName creates a new instance of NumericMethodName. +func NewNumericMethodName() *NumericMethodName { + parsed, err := NumericMethodNameMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &NumericMethodName{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *NumericMethodName) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackE1test is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xffa02795. +// +// Solidity: function _1test() pure returns() +func (numericMethodName *NumericMethodName) PackE1test() []byte { + enc, err := numericMethodName.abi.Pack("_1test") + if err != nil { + panic(err) + } + return enc +} + +// PackE1test0 is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd02767c7. +// +// Solidity: function __1test() pure returns() +func (numericMethodName *NumericMethodName) PackE1test0() []byte { + enc, err := numericMethodName.abi.Pack("__1test") + if err != nil { + panic(err) + } + return enc +} + +// PackE2test is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9d993132. +// +// Solidity: function __2test() pure returns() +func (numericMethodName *NumericMethodName) PackE2test() []byte { + enc, err := numericMethodName.abi.Pack("__2test") + if err != nil { + panic(err) + } + return enc +} + +// NumericMethodNameE1TestEvent represents a _1TestEvent event raised by the NumericMethodName contract. +type NumericMethodNameE1TestEvent struct { + Param common.Address + Raw *types.Log // Blockchain specific contextual infos +} + +const NumericMethodNameE1TestEventEventName = "_1TestEvent" + +// ContractEventName returns the user-defined event name. +func (NumericMethodNameE1TestEvent) ContractEventName() string { + return NumericMethodNameE1TestEventEventName +} + +// UnpackE1TestEventEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event _1TestEvent(address _param) +func (numericMethodName *NumericMethodName) UnpackE1TestEventEvent(log *types.Log) (*NumericMethodNameE1TestEvent, error) { + event := "_1TestEvent" + if log.Topics[0] != numericMethodName.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(NumericMethodNameE1TestEvent) + if len(log.Data) > 0 { + if err := numericMethodName.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range numericMethodName.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/abigen/testdata/v2/outputchecker.go.txt b/accounts/abi/abigen/testdata/v2/outputchecker.go.txt new file mode 100644 index 0000000000..6f1f8e6795 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/outputchecker.go.txt @@ -0,0 +1,253 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// OutputCheckerMetaData contains all meta data concerning the OutputChecker contract. +var OutputCheckerMetaData = bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"noOutput\",\"constant\":true,\"inputs\":[],\"outputs\":[]},{\"type\":\"function\",\"name\":\"namedOutput\",\"constant\":true,\"inputs\":[],\"outputs\":[{\"name\":\"str\",\"type\":\"string\"}]},{\"type\":\"function\",\"name\":\"anonOutput\",\"constant\":true,\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\"}]},{\"type\":\"function\",\"name\":\"namedOutputs\",\"constant\":true,\"inputs\":[],\"outputs\":[{\"name\":\"str1\",\"type\":\"string\"},{\"name\":\"str2\",\"type\":\"string\"}]},{\"type\":\"function\",\"name\":\"collidingOutputs\",\"constant\":true,\"inputs\":[],\"outputs\":[{\"name\":\"str\",\"type\":\"string\"},{\"name\":\"Str\",\"type\":\"string\"}]},{\"type\":\"function\",\"name\":\"anonOutputs\",\"constant\":true,\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"}]},{\"type\":\"function\",\"name\":\"mixedOutputs\",\"constant\":true,\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"str\",\"type\":\"string\"}]}]", + ID: "cc1d4e235801a590b506d5130b0cca90a1", +} + +// OutputChecker is an auto generated Go binding around an Ethereum contract. +type OutputChecker struct { + abi abi.ABI +} + +// NewOutputChecker creates a new instance of OutputChecker. +func NewOutputChecker() *OutputChecker { + parsed, err := OutputCheckerMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &OutputChecker{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *OutputChecker) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackAnonOutput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x008bda05. +// +// Solidity: function anonOutput() returns(string) +func (outputChecker *OutputChecker) PackAnonOutput() []byte { + enc, err := outputChecker.abi.Pack("anonOutput") + if err != nil { + panic(err) + } + return enc +} + +// UnpackAnonOutput is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x008bda05. +// +// Solidity: function anonOutput() returns(string) +func (outputChecker *OutputChecker) UnpackAnonOutput(data []byte) (string, error) { + out, err := outputChecker.abi.Unpack("anonOutput", data) + if err != nil { + return *new(string), err + } + out0 := *abi.ConvertType(out[0], new(string)).(*string) + return out0, err +} + +// PackAnonOutputs is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x3c401115. +// +// Solidity: function anonOutputs() returns(string, string) +func (outputChecker *OutputChecker) PackAnonOutputs() []byte { + enc, err := outputChecker.abi.Pack("anonOutputs") + if err != nil { + panic(err) + } + return enc +} + +// AnonOutputsOutput serves as a container for the return parameters of contract +// method AnonOutputs. +type AnonOutputsOutput struct { + Arg0 string + Arg1 string +} + +// UnpackAnonOutputs is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x3c401115. +// +// Solidity: function anonOutputs() returns(string, string) +func (outputChecker *OutputChecker) UnpackAnonOutputs(data []byte) (AnonOutputsOutput, error) { + out, err := outputChecker.abi.Unpack("anonOutputs", data) + outstruct := new(AnonOutputsOutput) + if err != nil { + return *outstruct, err + } + outstruct.Arg0 = *abi.ConvertType(out[0], new(string)).(*string) + outstruct.Arg1 = *abi.ConvertType(out[1], new(string)).(*string) + return *outstruct, err + +} + +// PackCollidingOutputs is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xeccbc1ee. +// +// Solidity: function collidingOutputs() returns(string str, string Str) +func (outputChecker *OutputChecker) PackCollidingOutputs() []byte { + enc, err := outputChecker.abi.Pack("collidingOutputs") + if err != nil { + panic(err) + } + return enc +} + +// CollidingOutputsOutput serves as a container for the return parameters of contract +// method CollidingOutputs. +type CollidingOutputsOutput struct { + Str string + Str0 string +} + +// UnpackCollidingOutputs is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xeccbc1ee. +// +// Solidity: function collidingOutputs() returns(string str, string Str) +func (outputChecker *OutputChecker) UnpackCollidingOutputs(data []byte) (CollidingOutputsOutput, error) { + out, err := outputChecker.abi.Unpack("collidingOutputs", data) + outstruct := new(CollidingOutputsOutput) + if err != nil { + return *outstruct, err + } + outstruct.Str = *abi.ConvertType(out[0], new(string)).(*string) + outstruct.Str0 = *abi.ConvertType(out[1], new(string)).(*string) + return *outstruct, err + +} + +// PackMixedOutputs is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x21b77b44. +// +// Solidity: function mixedOutputs() returns(string, string str) +func (outputChecker *OutputChecker) PackMixedOutputs() []byte { + enc, err := outputChecker.abi.Pack("mixedOutputs") + if err != nil { + panic(err) + } + return enc +} + +// MixedOutputsOutput serves as a container for the return parameters of contract +// method MixedOutputs. +type MixedOutputsOutput struct { + Arg0 string + Str string +} + +// UnpackMixedOutputs is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x21b77b44. +// +// Solidity: function mixedOutputs() returns(string, string str) +func (outputChecker *OutputChecker) UnpackMixedOutputs(data []byte) (MixedOutputsOutput, error) { + out, err := outputChecker.abi.Unpack("mixedOutputs", data) + outstruct := new(MixedOutputsOutput) + if err != nil { + return *outstruct, err + } + outstruct.Arg0 = *abi.ConvertType(out[0], new(string)).(*string) + outstruct.Str = *abi.ConvertType(out[1], new(string)).(*string) + return *outstruct, err + +} + +// PackNamedOutput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x5e632bd5. +// +// Solidity: function namedOutput() returns(string str) +func (outputChecker *OutputChecker) PackNamedOutput() []byte { + enc, err := outputChecker.abi.Pack("namedOutput") + if err != nil { + panic(err) + } + return enc +} + +// UnpackNamedOutput is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x5e632bd5. +// +// Solidity: function namedOutput() returns(string str) +func (outputChecker *OutputChecker) UnpackNamedOutput(data []byte) (string, error) { + out, err := outputChecker.abi.Unpack("namedOutput", data) + if err != nil { + return *new(string), err + } + out0 := *abi.ConvertType(out[0], new(string)).(*string) + return out0, err +} + +// PackNamedOutputs is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x7970a189. +// +// Solidity: function namedOutputs() returns(string str1, string str2) +func (outputChecker *OutputChecker) PackNamedOutputs() []byte { + enc, err := outputChecker.abi.Pack("namedOutputs") + if err != nil { + panic(err) + } + return enc +} + +// NamedOutputsOutput serves as a container for the return parameters of contract +// method NamedOutputs. +type NamedOutputsOutput struct { + Str1 string + Str2 string +} + +// UnpackNamedOutputs is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x7970a189. +// +// Solidity: function namedOutputs() returns(string str1, string str2) +func (outputChecker *OutputChecker) UnpackNamedOutputs(data []byte) (NamedOutputsOutput, error) { + out, err := outputChecker.abi.Unpack("namedOutputs", data) + outstruct := new(NamedOutputsOutput) + if err != nil { + return *outstruct, err + } + outstruct.Str1 = *abi.ConvertType(out[0], new(string)).(*string) + outstruct.Str2 = *abi.ConvertType(out[1], new(string)).(*string) + return *outstruct, err + +} + +// PackNoOutput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x625f0306. +// +// Solidity: function noOutput() returns() +func (outputChecker *OutputChecker) PackNoOutput() []byte { + enc, err := outputChecker.abi.Pack("noOutput") + if err != nil { + panic(err) + } + return enc +} diff --git a/accounts/abi/abigen/testdata/v2/overload.go.txt b/accounts/abi/abigen/testdata/v2/overload.go.txt new file mode 100644 index 0000000000..ed7c0b543c --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/overload.go.txt @@ -0,0 +1,159 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// OverloadMetaData contains all meta data concerning the Overload contract. +var OverloadMetaData = bind.MetaData{ + ABI: "[{\"constant\":false,\"inputs\":[{\"name\":\"i\",\"type\":\"uint256\"},{\"name\":\"j\",\"type\":\"uint256\"}],\"name\":\"foo\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"foo\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"bar\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"i\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"j\",\"type\":\"uint256\"}],\"name\":\"bar\",\"type\":\"event\"}]", + ID: "f49f0ff7ed407de5c37214f49309072aec", + Bin: "0x608060405234801561001057600080fd5b50610153806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806304bc52f81461003b5780632fbebd3814610073575b600080fd5b6100716004803603604081101561005157600080fd5b8101908080359060200190929190803590602001909291905050506100a1565b005b61009f6004803603602081101561008957600080fd5b81019080803590602001909291905050506100e4565b005b7fae42e9514233792a47a1e4554624e83fe852228e1503f63cd383e8a431f4f46d8282604051808381526020018281526020019250505060405180910390a15050565b7f0423a1321222a0a8716c22b92fac42d85a45a612b696a461784d9fa537c81e5c816040518082815260200191505060405180910390a15056fea265627a7a72305820e22b049858b33291cbe67eeaece0c5f64333e439d27032ea8337d08b1de18fe864736f6c634300050a0032", +} + +// Overload is an auto generated Go binding around an Ethereum contract. +type Overload struct { + abi abi.ABI +} + +// NewOverload creates a new instance of Overload. +func NewOverload() *Overload { + parsed, err := OverloadMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Overload{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Overload) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackFoo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x04bc52f8. +// +// Solidity: function foo(uint256 i, uint256 j) returns() +func (overload *Overload) PackFoo(i *big.Int, j *big.Int) []byte { + enc, err := overload.abi.Pack("foo", i, j) + if err != nil { + panic(err) + } + return enc +} + +// PackFoo0 is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2fbebd38. +// +// Solidity: function foo(uint256 i) returns() +func (overload *Overload) PackFoo0(i *big.Int) []byte { + enc, err := overload.abi.Pack("foo0", i) + if err != nil { + panic(err) + } + return enc +} + +// OverloadBar represents a bar event raised by the Overload contract. +type OverloadBar struct { + I *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const OverloadBarEventName = "bar" + +// ContractEventName returns the user-defined event name. +func (OverloadBar) ContractEventName() string { + return OverloadBarEventName +} + +// UnpackBarEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event bar(uint256 i) +func (overload *Overload) UnpackBarEvent(log *types.Log) (*OverloadBar, error) { + event := "bar" + if log.Topics[0] != overload.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(OverloadBar) + if len(log.Data) > 0 { + if err := overload.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range overload.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// OverloadBar0 represents a bar0 event raised by the Overload contract. +type OverloadBar0 struct { + I *big.Int + J *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const OverloadBar0EventName = "bar0" + +// ContractEventName returns the user-defined event name. +func (OverloadBar0) ContractEventName() string { + return OverloadBar0EventName +} + +// UnpackBar0Event is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event bar(uint256 i, uint256 j) +func (overload *Overload) UnpackBar0Event(log *types.Log) (*OverloadBar0, error) { + event := "bar0" + if log.Topics[0] != overload.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(OverloadBar0) + if len(log.Data) > 0 { + if err := overload.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range overload.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/abigen/testdata/v2/rangekeyword.go.txt b/accounts/abi/abigen/testdata/v2/rangekeyword.go.txt new file mode 100644 index 0000000000..c7f1425395 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/rangekeyword.go.txt @@ -0,0 +1,64 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// RangeKeywordMetaData contains all meta data concerning the RangeKeyword contract. +var RangeKeywordMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"range\",\"type\":\"uint256\"}],\"name\":\"functionWithKeywordParameter\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "cec8c872ba06feb1b8f0a00e7b237eb226", + Bin: "0x608060405234801561001057600080fd5b5060dc8061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063527a119f14602d575b600080fd5b60436004803603810190603f9190605b565b6045565b005b50565b6000813590506055816092565b92915050565b600060208284031215606e57606d608d565b5b6000607a848285016048565b91505092915050565b6000819050919050565b600080fd5b6099816083565b811460a357600080fd5b5056fea2646970667358221220d4f4525e2615516394055d369fb17df41c359e5e962734f27fd683ea81fd9db164736f6c63430008070033", +} + +// RangeKeyword is an auto generated Go binding around an Ethereum contract. +type RangeKeyword struct { + abi abi.ABI +} + +// NewRangeKeyword creates a new instance of RangeKeyword. +func NewRangeKeyword() *RangeKeyword { + parsed, err := RangeKeywordMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &RangeKeyword{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *RangeKeyword) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackFunctionWithKeywordParameter is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x527a119f. +// +// Solidity: function functionWithKeywordParameter(uint256 range) pure returns() +func (rangeKeyword *RangeKeyword) PackFunctionWithKeywordParameter(arg0 *big.Int) []byte { + enc, err := rangeKeyword.abi.Pack("functionWithKeywordParameter", arg0) + if err != nil { + panic(err) + } + return enc +} diff --git a/accounts/abi/abigen/testdata/v2/slicer.go.txt b/accounts/abi/abigen/testdata/v2/slicer.go.txt new file mode 100644 index 0000000000..b66c05cf0f --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/slicer.go.txt @@ -0,0 +1,152 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// SlicerMetaData contains all meta data concerning the Slicer contract. +var SlicerMetaData = bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[{\"name\":\"input\",\"type\":\"address[]\"}],\"name\":\"echoAddresses\",\"outputs\":[{\"name\":\"output\",\"type\":\"address[]\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"input\",\"type\":\"uint24[23]\"}],\"name\":\"echoFancyInts\",\"outputs\":[{\"name\":\"output\",\"type\":\"uint24[23]\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"input\",\"type\":\"int256[]\"}],\"name\":\"echoInts\",\"outputs\":[{\"name\":\"output\",\"type\":\"int256[]\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"input\",\"type\":\"bool[]\"}],\"name\":\"echoBools\",\"outputs\":[{\"name\":\"output\",\"type\":\"bool[]\"}],\"type\":\"function\"}]", + ID: "082c0740ab6537c7169cb573d097c52112", + Bin: "0x606060405261015c806100126000396000f3606060405260e060020a6000350463be1127a3811461003c578063d88becc014610092578063e15a3db71461003c578063f637e5891461003c575b005b604080516020600480358082013583810285810185019096528085526100ee959294602494909392850192829185019084908082843750949650505050505050604080516020810190915260009052805b919050565b604080516102e0818101909252610138916004916102e491839060179083908390808284375090955050505050506102e0604051908101604052806017905b60008152602001906001900390816100d15790505081905061008d565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b60405180826102e0808381846000600461015cf15090500191505060405180910390f3", +} + +// Slicer is an auto generated Go binding around an Ethereum contract. +type Slicer struct { + abi abi.ABI +} + +// NewSlicer creates a new instance of Slicer. +func NewSlicer() *Slicer { + parsed, err := SlicerMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Slicer{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Slicer) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackEchoAddresses is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xbe1127a3. +// +// Solidity: function echoAddresses(address[] input) returns(address[] output) +func (slicer *Slicer) PackEchoAddresses(input []common.Address) []byte { + enc, err := slicer.abi.Pack("echoAddresses", input) + if err != nil { + panic(err) + } + return enc +} + +// UnpackEchoAddresses is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xbe1127a3. +// +// Solidity: function echoAddresses(address[] input) returns(address[] output) +func (slicer *Slicer) UnpackEchoAddresses(data []byte) ([]common.Address, error) { + out, err := slicer.abi.Unpack("echoAddresses", data) + if err != nil { + return *new([]common.Address), err + } + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + return out0, err +} + +// PackEchoBools is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xf637e589. +// +// Solidity: function echoBools(bool[] input) returns(bool[] output) +func (slicer *Slicer) PackEchoBools(input []bool) []byte { + enc, err := slicer.abi.Pack("echoBools", input) + if err != nil { + panic(err) + } + return enc +} + +// UnpackEchoBools is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xf637e589. +// +// Solidity: function echoBools(bool[] input) returns(bool[] output) +func (slicer *Slicer) UnpackEchoBools(data []byte) ([]bool, error) { + out, err := slicer.abi.Unpack("echoBools", data) + if err != nil { + return *new([]bool), err + } + out0 := *abi.ConvertType(out[0], new([]bool)).(*[]bool) + return out0, err +} + +// PackEchoFancyInts is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd88becc0. +// +// Solidity: function echoFancyInts(uint24[23] input) returns(uint24[23] output) +func (slicer *Slicer) PackEchoFancyInts(input [23]*big.Int) []byte { + enc, err := slicer.abi.Pack("echoFancyInts", input) + if err != nil { + panic(err) + } + return enc +} + +// UnpackEchoFancyInts is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xd88becc0. +// +// Solidity: function echoFancyInts(uint24[23] input) returns(uint24[23] output) +func (slicer *Slicer) UnpackEchoFancyInts(data []byte) ([23]*big.Int, error) { + out, err := slicer.abi.Unpack("echoFancyInts", data) + if err != nil { + return *new([23]*big.Int), err + } + out0 := *abi.ConvertType(out[0], new([23]*big.Int)).(*[23]*big.Int) + return out0, err +} + +// PackEchoInts is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xe15a3db7. +// +// Solidity: function echoInts(int256[] input) returns(int256[] output) +func (slicer *Slicer) PackEchoInts(input []*big.Int) []byte { + enc, err := slicer.abi.Pack("echoInts", input) + if err != nil { + panic(err) + } + return enc +} + +// UnpackEchoInts is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xe15a3db7. +// +// Solidity: function echoInts(int256[] input) returns(int256[] output) +func (slicer *Slicer) UnpackEchoInts(data []byte) ([]*big.Int, error) { + out, err := slicer.abi.Unpack("echoInts", data) + if err != nil { + return *new([]*big.Int), err + } + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + return out0, err +} diff --git a/accounts/abi/abigen/testdata/v2/structs-abi.go.txt b/accounts/abi/abigen/testdata/v2/structs-abi.go.txt new file mode 100644 index 0000000000..aab6242707 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/structs-abi.go.txt @@ -0,0 +1,116 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package v1bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// Struct0 is an auto generated low-level Go binding around an user-defined struct. +type Struct0 struct { + B [32]byte +} + +// StructsMetaData contains all meta data concerning the Structs contract. +var StructsMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"F\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"B\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.A[]\",\"name\":\"a\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[]\",\"name\":\"c\",\"type\":\"uint256[]\"},{\"internalType\":\"bool[]\",\"name\":\"d\",\"type\":\"bool[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"G\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"B\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.A[]\",\"name\":\"a\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ID: "Structs", +} + +// Structs is an auto generated Go binding around an Ethereum contract. +type Structs struct { + abi abi.ABI +} + +// NewStructs creates a new instance of Structs. +func NewStructs() *Structs { + parsed, err := StructsMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Structs{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +<<<<<<< HEAD +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Structs) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +======= +// Use this to create the instance object passed to abigen v2 library functions Call, +// Transact, etc. +func (c *Structs) Instance(backend bind.ContractBackend, addr common.Address) bind.BoundContract { + return bind.NewBoundContract(backend, addr, c.abi) +>>>>>>> 854c25e086 (accounts/abi/abigen: improve v2 template) +} + +// F is the Go binding used to pack the parameters required for calling +// the contract method 0x28811f59. +// +// Solidity: function F() view returns((bytes32)[] a, uint256[] c, bool[] d) +func (structs *Structs) PackF() ([]byte, error) { + return structs.abi.Pack("F") +} + +// FOutput serves as a container for the return parameters of contract +// method F. +type FOutput struct { + A []Struct0 + C []*big.Int + D []bool +} + +// UnpackF is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x28811f59. +// +// Solidity: function F() view returns((bytes32)[] a, uint256[] c, bool[] d) +func (structs *Structs) UnpackF(data []byte) (*FOutput, error) { + out, err := structs.abi.Unpack("F", data) + if err != nil { + return nil, err + } + ret := new(FOutput) + ret.A = *abi.ConvertType(out[0], new([]Struct0)).(*[]Struct0) + ret.C = *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) + ret.D = *abi.ConvertType(out[2], new([]bool)).(*[]bool) + return ret, nil +} + +// G is the Go binding used to pack the parameters required for calling +// the contract method 0x6fecb623. +// +// Solidity: function G() view returns((bytes32)[] a) +func (structs *Structs) PackG() ([]byte, error) { + return structs.abi.Pack("G") +} + +// UnpackG is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x6fecb623. +// +// Solidity: function G() view returns((bytes32)[] a) +func (structs *Structs) UnpackG(data []byte) (*[]Struct0, error) { + out, err := structs.abi.Unpack("G", data) + if err != nil { + return nil, err + } + out0 := *abi.ConvertType(out[0], new([]Struct0)).(*[]Struct0) + return &out0, nil +} diff --git a/accounts/abi/abigen/testdata/v2/structs.go.txt b/accounts/abi/abigen/testdata/v2/structs.go.txt new file mode 100644 index 0000000000..7fe59c5616 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/structs.go.txt @@ -0,0 +1,119 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// Struct0 is an auto generated low-level Go binding around an user-defined struct. +type Struct0 struct { + B [32]byte +} + +// StructsMetaData contains all meta data concerning the Structs contract. +var StructsMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"F\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"B\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.A[]\",\"name\":\"a\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[]\",\"name\":\"c\",\"type\":\"uint256[]\"},{\"internalType\":\"bool[]\",\"name\":\"d\",\"type\":\"bool[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"G\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"B\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.A[]\",\"name\":\"a\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ID: "920a35318e7581766aec7a17218628a91d", + Bin: "0x608060405234801561001057600080fd5b50610278806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806328811f591461003b5780636fecb6231461005b575b600080fd5b610043610070565b604051610052939291906101a0565b60405180910390f35b6100636100d6565b6040516100529190610186565b604080516002808252606082810190935282918291829190816020015b610095610131565b81526020019060019003908161008d575050805190915061026960611b9082906000906100be57fe5b60209081029190910101515293606093508392509050565b6040805160028082526060828101909352829190816020015b6100f7610131565b8152602001906001900390816100ef575050805190915061026960611b90829060009061012057fe5b602090810291909101015152905090565b60408051602081019091526000815290565b815260200190565b6000815180845260208085019450808401835b8381101561017b578151518752958201959082019060010161015e565b509495945050505050565b600060208252610199602083018461014b565b9392505050565b6000606082526101b3606083018661014b565b6020838203818501528186516101c98185610239565b91508288019350845b818110156101f3576101e5838651610143565b9484019492506001016101d2565b505084810360408601528551808252908201925081860190845b8181101561022b57825115158552938301939183019160010161020d565b509298975050505050505050565b9081526020019056fea2646970667358221220eb85327e285def14230424c52893aebecec1e387a50bb6b75fc4fdbed647f45f64736f6c63430006050033", +} + +// Structs is an auto generated Go binding around an Ethereum contract. +type Structs struct { + abi abi.ABI +} + +// NewStructs creates a new instance of Structs. +func NewStructs() *Structs { + parsed, err := StructsMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Structs{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Structs) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackF is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x28811f59. +// +// Solidity: function F() view returns((bytes32)[] a, uint256[] c, bool[] d) +func (structs *Structs) PackF() []byte { + enc, err := structs.abi.Pack("F") + if err != nil { + panic(err) + } + return enc +} + +// FOutput serves as a container for the return parameters of contract +// method F. +type FOutput struct { + A []Struct0 + C []*big.Int + D []bool +} + +// UnpackF is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x28811f59. +// +// Solidity: function F() view returns((bytes32)[] a, uint256[] c, bool[] d) +func (structs *Structs) UnpackF(data []byte) (FOutput, error) { + out, err := structs.abi.Unpack("F", data) + outstruct := new(FOutput) + if err != nil { + return *outstruct, err + } + outstruct.A = *abi.ConvertType(out[0], new([]Struct0)).(*[]Struct0) + outstruct.C = *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) + outstruct.D = *abi.ConvertType(out[2], new([]bool)).(*[]bool) + return *outstruct, err + +} + +// PackG is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x6fecb623. +// +// Solidity: function G() view returns((bytes32)[] a) +func (structs *Structs) PackG() []byte { + enc, err := structs.abi.Pack("G") + if err != nil { + panic(err) + } + return enc +} + +// UnpackG is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x6fecb623. +// +// Solidity: function G() view returns((bytes32)[] a) +func (structs *Structs) UnpackG(data []byte) ([]Struct0, error) { + out, err := structs.abi.Unpack("G", data) + if err != nil { + return *new([]Struct0), err + } + out0 := *abi.ConvertType(out[0], new([]Struct0)).(*[]Struct0) + return out0, err +} diff --git a/accounts/abi/abigen/testdata/v2/token.go.txt b/accounts/abi/abigen/testdata/v2/token.go.txt new file mode 100644 index 0000000000..aca18cb227 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/token.go.txt @@ -0,0 +1,319 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// TokenMetaData contains all meta data concerning the Token contract. +var TokenMetaData = bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"approveAndCall\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"address\"}],\"name\":\"spentAllowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialSupply\",\"type\":\"uint256\"},{\"name\":\"tokenName\",\"type\":\"string\"},{\"name\":\"decimalUnits\",\"type\":\"uint8\"},{\"name\":\"tokenSymbol\",\"type\":\"string\"}],\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"}]", + ID: "1317f51c845ce3bfb7c268e5337a825f12", + Bin: "0x60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056", +} + +// Token is an auto generated Go binding around an Ethereum contract. +type Token struct { + abi abi.ABI +} + +// NewToken creates a new instance of Token. +func NewToken() *Token { + parsed, err := TokenMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Token{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Token) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackConstructor is the Go binding used to pack the parameters required for +// contract deployment. +// +// Solidity: constructor(uint256 initialSupply, string tokenName, uint8 decimalUnits, string tokenSymbol) returns() +func (token *Token) PackConstructor(initialSupply *big.Int, tokenName string, decimalUnits uint8, tokenSymbol string) []byte { + enc, err := token.abi.Pack("", initialSupply, tokenName, decimalUnits, tokenSymbol) + if err != nil { + panic(err) + } + return enc +} + +// PackAllowance is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xdd62ed3e. +// +// Solidity: function allowance(address , address ) returns(uint256) +func (token *Token) PackAllowance(arg0 common.Address, arg1 common.Address) []byte { + enc, err := token.abi.Pack("allowance", arg0, arg1) + if err != nil { + panic(err) + } + return enc +} + +// UnpackAllowance is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xdd62ed3e. +// +// Solidity: function allowance(address , address ) returns(uint256) +func (token *Token) UnpackAllowance(data []byte) (*big.Int, error) { + out, err := token.abi.Unpack("allowance", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackApproveAndCall is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xcae9ca51. +// +// Solidity: function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns(bool success) +func (token *Token) PackApproveAndCall(spender common.Address, value *big.Int, extraData []byte) []byte { + enc, err := token.abi.Pack("approveAndCall", spender, value, extraData) + if err != nil { + panic(err) + } + return enc +} + +// UnpackApproveAndCall is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xcae9ca51. +// +// Solidity: function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns(bool success) +func (token *Token) UnpackApproveAndCall(data []byte) (bool, error) { + out, err := token.abi.Unpack("approveAndCall", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, err +} + +// PackBalanceOf is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x70a08231. +// +// Solidity: function balanceOf(address ) returns(uint256) +func (token *Token) PackBalanceOf(arg0 common.Address) []byte { + enc, err := token.abi.Pack("balanceOf", arg0) + if err != nil { + panic(err) + } + return enc +} + +// UnpackBalanceOf is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x70a08231. +// +// Solidity: function balanceOf(address ) returns(uint256) +func (token *Token) UnpackBalanceOf(data []byte) (*big.Int, error) { + out, err := token.abi.Unpack("balanceOf", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackDecimals is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x313ce567. +// +// Solidity: function decimals() returns(uint8) +func (token *Token) PackDecimals() []byte { + enc, err := token.abi.Pack("decimals") + if err != nil { + panic(err) + } + return enc +} + +// UnpackDecimals is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x313ce567. +// +// Solidity: function decimals() returns(uint8) +func (token *Token) UnpackDecimals(data []byte) (uint8, error) { + out, err := token.abi.Unpack("decimals", data) + if err != nil { + return *new(uint8), err + } + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + return out0, err +} + +// PackName is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x06fdde03. +// +// Solidity: function name() returns(string) +func (token *Token) PackName() []byte { + enc, err := token.abi.Pack("name") + if err != nil { + panic(err) + } + return enc +} + +// UnpackName is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x06fdde03. +// +// Solidity: function name() returns(string) +func (token *Token) UnpackName(data []byte) (string, error) { + out, err := token.abi.Unpack("name", data) + if err != nil { + return *new(string), err + } + out0 := *abi.ConvertType(out[0], new(string)).(*string) + return out0, err +} + +// PackSpentAllowance is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xdc3080f2. +// +// Solidity: function spentAllowance(address , address ) returns(uint256) +func (token *Token) PackSpentAllowance(arg0 common.Address, arg1 common.Address) []byte { + enc, err := token.abi.Pack("spentAllowance", arg0, arg1) + if err != nil { + panic(err) + } + return enc +} + +// UnpackSpentAllowance is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xdc3080f2. +// +// Solidity: function spentAllowance(address , address ) returns(uint256) +func (token *Token) UnpackSpentAllowance(data []byte) (*big.Int, error) { + out, err := token.abi.Unpack("spentAllowance", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackSymbol is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x95d89b41. +// +// Solidity: function symbol() returns(string) +func (token *Token) PackSymbol() []byte { + enc, err := token.abi.Pack("symbol") + if err != nil { + panic(err) + } + return enc +} + +// UnpackSymbol is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x95d89b41. +// +// Solidity: function symbol() returns(string) +func (token *Token) UnpackSymbol(data []byte) (string, error) { + out, err := token.abi.Unpack("symbol", data) + if err != nil { + return *new(string), err + } + out0 := *abi.ConvertType(out[0], new(string)).(*string) + return out0, err +} + +// PackTransfer is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa9059cbb. +// +// Solidity: function transfer(address _to, uint256 _value) returns() +func (token *Token) PackTransfer(to common.Address, value *big.Int) []byte { + enc, err := token.abi.Pack("transfer", to, value) + if err != nil { + panic(err) + } + return enc +} + +// PackTransferFrom is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _value) returns(bool success) +func (token *Token) PackTransferFrom(from common.Address, to common.Address, value *big.Int) []byte { + enc, err := token.abi.Pack("transferFrom", from, to, value) + if err != nil { + panic(err) + } + return enc +} + +// UnpackTransferFrom is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _value) returns(bool success) +func (token *Token) UnpackTransferFrom(data []byte) (bool, error) { + out, err := token.abi.Unpack("transferFrom", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, err +} + +// TokenTransfer represents a Transfer event raised by the Token contract. +type TokenTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const TokenTransferEventName = "Transfer" + +// ContractEventName returns the user-defined event name. +func (TokenTransfer) ContractEventName() string { + return TokenTransferEventName +} + +// UnpackTransferEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (token *Token) UnpackTransferEvent(log *types.Log) (*TokenTransfer, error) { + event := "Transfer" + if log.Topics[0] != token.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TokenTransfer) + if len(log.Data) > 0 { + if err := token.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range token.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/abigen/testdata/v2/tuple.go.txt b/accounts/abi/abigen/testdata/v2/tuple.go.txt new file mode 100644 index 0000000000..65af765463 --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/tuple.go.txt @@ -0,0 +1,228 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// TupleP is an auto generated low-level Go binding around an user-defined struct. +type TupleP struct { + X uint8 + Y uint8 +} + +// TupleQ is an auto generated low-level Go binding around an user-defined struct. +type TupleQ struct { + X uint16 + Y uint16 +} + +// TupleS is an auto generated low-level Go binding around an user-defined struct. +type TupleS struct { + A *big.Int + B []*big.Int + C []TupleT +} + +// TupleT is an auto generated low-level Go binding around an user-defined struct. +type TupleT struct { + X *big.Int + Y *big.Int +} + +// TupleMetaData contains all meta data concerning the Tuple contract. +var TupleMetaData = bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structTuple.S\",\"name\":\"a\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structTuple.T[2][]\",\"name\":\"b\",\"type\":\"tuple[2][]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structTuple.T[][2]\",\"name\":\"c\",\"type\":\"tuple[][2]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structTuple.S[]\",\"name\":\"d\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"e\",\"type\":\"uint256[]\"}],\"name\":\"TupleEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"x\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"y\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structTuple.P[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"TupleEvent2\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"}],\"internalType\":\"structTuple.S\",\"name\":\"a\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[2][]\",\"name\":\"b\",\"type\":\"tuple[2][]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[][2]\",\"name\":\"c\",\"type\":\"tuple[][2]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"}],\"internalType\":\"structTuple.S[]\",\"name\":\"d\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[]\",\"name\":\"e\",\"type\":\"uint256[]\"}],\"name\":\"func1\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"}],\"internalType\":\"structTuple.S\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[2][]\",\"name\":\"\",\"type\":\"tuple[2][]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[][2]\",\"name\":\"\",\"type\":\"tuple[][2]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"}],\"internalType\":\"structTuple.S[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"}],\"internalType\":\"structTuple.S\",\"name\":\"a\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[2][]\",\"name\":\"b\",\"type\":\"tuple[2][]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[][2]\",\"name\":\"c\",\"type\":\"tuple[][2]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"structTuple.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"}],\"internalType\":\"structTuple.S[]\",\"name\":\"d\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[]\",\"name\":\"e\",\"type\":\"uint256[]\"}],\"name\":\"func2\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"x\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"y\",\"type\":\"uint16\"}],\"internalType\":\"structTuple.Q[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"func3\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "96ee1e2b1b89f8c495f200e4956278a4d4", + Bin: "0x60806040523480156100115760006000fd5b50610017565b6110b2806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100465760003560e01c8063443c79b41461004c578063d0062cdd14610080578063e4d9a43b1461009c57610046565b60006000fd5b610066600480360361006191908101906107b8565b6100b8565b604051610077959493929190610ccb565b60405180910390f35b61009a600480360361009591908101906107b8565b6100ef565b005b6100b660048036036100b19190810190610775565b610136565b005b6100c061013a565b60606100ca61015e565b606060608989898989945094509450945094506100e2565b9550955095509550959050565b7f18d6e66efa53739ca6d13626f35ebc700b31cced3eddb50c70bbe9c082c6cd008585858585604051610126959493929190610ccb565b60405180910390a15b5050505050565b5b50565b60405180606001604052806000815260200160608152602001606081526020015090565b60405180604001604052806002905b606081526020019060019003908161016d57905050905661106e565b600082601f830112151561019d5760006000fd5b81356101b06101ab82610d6f565b610d41565b915081818352602084019350602081019050838560808402820111156101d65760006000fd5b60005b8381101561020757816101ec888261037a565b8452602084019350608083019250505b6001810190506101d9565b5050505092915050565b600082601f83011215156102255760006000fd5b600261023861023382610d98565b610d41565b9150818360005b83811015610270578135860161025588826103f3565b8452602084019350602083019250505b60018101905061023f565b5050505092915050565b600082601f830112151561028e5760006000fd5b81356102a161029c82610dbb565b610d41565b915081818352602084019350602081019050838560408402820111156102c75760006000fd5b60005b838110156102f857816102dd888261058b565b8452602084019350604083019250505b6001810190506102ca565b5050505092915050565b600082601f83011215156103165760006000fd5b813561032961032482610de4565b610d41565b9150818183526020840193506020810190508360005b83811015610370578135860161035588826105d8565b8452602084019350602083019250505b60018101905061033f565b5050505092915050565b600082601f830112151561038e5760006000fd5b60026103a161039c82610e0d565b610d41565b915081838560408402820111156103b85760006000fd5b60005b838110156103e957816103ce88826106fe565b8452602084019350604083019250505b6001810190506103bb565b5050505092915050565b600082601f83011215156104075760006000fd5b813561041a61041582610e30565b610d41565b915081818352602084019350602081019050838560408402820111156104405760006000fd5b60005b83811015610471578161045688826106fe565b8452602084019350604083019250505b600181019050610443565b5050505092915050565b600082601f830112151561048f5760006000fd5b81356104a261049d82610e59565b610d41565b915081818352602084019350602081019050838560208402820111156104c85760006000fd5b60005b838110156104f957816104de8882610760565b8452602084019350602083019250505b6001810190506104cb565b5050505092915050565b600082601f83011215156105175760006000fd5b813561052a61052582610e82565b610d41565b915081818352602084019350602081019050838560208402820111156105505760006000fd5b60005b8381101561058157816105668882610760565b8452602084019350602083019250505b600181019050610553565b5050505092915050565b60006040828403121561059e5760006000fd5b6105a86040610d41565b905060006105b88482850161074b565b60008301525060206105cc8482850161074b565b60208301525092915050565b6000606082840312156105eb5760006000fd5b6105f56060610d41565b9050600061060584828501610760565b600083015250602082013567ffffffffffffffff8111156106265760006000fd5b6106328482850161047b565b602083015250604082013567ffffffffffffffff8111156106535760006000fd5b61065f848285016103f3565b60408301525092915050565b60006060828403121561067e5760006000fd5b6106886060610d41565b9050600061069884828501610760565b600083015250602082013567ffffffffffffffff8111156106b95760006000fd5b6106c58482850161047b565b602083015250604082013567ffffffffffffffff8111156106e65760006000fd5b6106f2848285016103f3565b60408301525092915050565b6000604082840312156107115760006000fd5b61071b6040610d41565b9050600061072b84828501610760565b600083015250602061073f84828501610760565b60208301525092915050565b60008135905061075a8161103a565b92915050565b60008135905061076f81611054565b92915050565b6000602082840312156107885760006000fd5b600082013567ffffffffffffffff8111156107a35760006000fd5b6107af8482850161027a565b91505092915050565b6000600060006000600060a086880312156107d35760006000fd5b600086013567ffffffffffffffff8111156107ee5760006000fd5b6107fa8882890161066b565b955050602086013567ffffffffffffffff8111156108185760006000fd5b61082488828901610189565b945050604086013567ffffffffffffffff8111156108425760006000fd5b61084e88828901610211565b935050606086013567ffffffffffffffff81111561086c5760006000fd5b61087888828901610302565b925050608086013567ffffffffffffffff8111156108965760006000fd5b6108a288828901610503565b9150509295509295909350565b60006108bb8383610a6a565b60808301905092915050565b60006108d38383610ac2565b905092915050565b60006108e78383610c36565b905092915050565b60006108fb8383610c8d565b60408301905092915050565b60006109138383610cbc565b60208301905092915050565b600061092a82610f0f565b6109348185610fb7565b935061093f83610eab565b8060005b8381101561097157815161095788826108af565b975061096283610f5c565b9250505b600181019050610943565b5085935050505092915050565b600061098982610f1a565b6109938185610fc8565b9350836020820285016109a585610ebb565b8060005b858110156109e257848403895281516109c285826108c7565b94506109cd83610f69565b925060208a019950505b6001810190506109a9565b50829750879550505050505092915050565b60006109ff82610f25565b610a098185610fd3565b935083602082028501610a1b85610ec5565b8060005b85811015610a585784840389528151610a3885826108db565b9450610a4383610f76565b925060208a019950505b600181019050610a1f565b50829750879550505050505092915050565b610a7381610f30565b610a7d8184610fe4565b9250610a8882610ed5565b8060005b83811015610aba578151610aa087826108ef565b9650610aab83610f83565b9250505b600181019050610a8c565b505050505050565b6000610acd82610f3b565b610ad78185610fef565b9350610ae283610edf565b8060005b83811015610b14578151610afa88826108ef565b9750610b0583610f90565b9250505b600181019050610ae6565b5085935050505092915050565b6000610b2c82610f51565b610b368185611011565b9350610b4183610eff565b8060005b83811015610b73578151610b598882610907565b9750610b6483610faa565b9250505b600181019050610b45565b5085935050505092915050565b6000610b8b82610f46565b610b958185611000565b9350610ba083610eef565b8060005b83811015610bd2578151610bb88882610907565b9750610bc383610f9d565b9250505b600181019050610ba4565b5085935050505092915050565b6000606083016000830151610bf76000860182610cbc565b5060208301518482036020860152610c0f8282610b80565b91505060408301518482036040860152610c298282610ac2565b9150508091505092915050565b6000606083016000830151610c4e6000860182610cbc565b5060208301518482036020860152610c668282610b80565b91505060408301518482036040860152610c808282610ac2565b9150508091505092915050565b604082016000820151610ca36000850182610cbc565b506020820151610cb66020850182610cbc565b50505050565b610cc581611030565b82525050565b600060a0820190508181036000830152610ce58188610bdf565b90508181036020830152610cf9818761091f565b90508181036040830152610d0d818661097e565b90508181036060830152610d2181856109f4565b90508181036080830152610d358184610b21565b90509695505050505050565b6000604051905081810181811067ffffffffffffffff82111715610d655760006000fd5b8060405250919050565b600067ffffffffffffffff821115610d875760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610db05760006000fd5b602082029050919050565b600067ffffffffffffffff821115610dd35760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610dfc5760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e255760006000fd5b602082029050919050565b600067ffffffffffffffff821115610e485760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e715760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e9a5760006000fd5b602082029050602081019050919050565b6000819050602082019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600061ffff82169050919050565b6000819050919050565b61104381611022565b811415156110515760006000fd5b50565b61105d81611030565b8114151561106b5760006000fd5b50565bfea365627a7a72315820d78c6ba7ee332581e6c4d9daa5fc07941841230f7ce49edf6e05b1b63853e8746c6578706572696d656e74616cf564736f6c634300050c0040", +} + +// Tuple is an auto generated Go binding around an Ethereum contract. +type Tuple struct { + abi abi.ABI +} + +// NewTuple creates a new instance of Tuple. +func NewTuple() *Tuple { + parsed, err := TupleMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Tuple{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Tuple) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackFunc1 is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x443c79b4. +// +// Solidity: function func1((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) pure returns((uint256,uint256[],(uint256,uint256)[]), (uint256,uint256)[2][], (uint256,uint256)[][2], (uint256,uint256[],(uint256,uint256)[])[], uint256[]) +func (tuple *Tuple) PackFunc1(a TupleS, b [][2]TupleT, c [2][]TupleT, d []TupleS, e []*big.Int) []byte { + enc, err := tuple.abi.Pack("func1", a, b, c, d, e) + if err != nil { + panic(err) + } + return enc +} + +// Func1Output serves as a container for the return parameters of contract +// method Func1. +type Func1Output struct { + Arg0 TupleS + Arg1 [][2]TupleT + Arg2 [2][]TupleT + Arg3 []TupleS + Arg4 []*big.Int +} + +// UnpackFunc1 is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x443c79b4. +// +// Solidity: function func1((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) pure returns((uint256,uint256[],(uint256,uint256)[]), (uint256,uint256)[2][], (uint256,uint256)[][2], (uint256,uint256[],(uint256,uint256)[])[], uint256[]) +func (tuple *Tuple) UnpackFunc1(data []byte) (Func1Output, error) { + out, err := tuple.abi.Unpack("func1", data) + outstruct := new(Func1Output) + if err != nil { + return *outstruct, err + } + outstruct.Arg0 = *abi.ConvertType(out[0], new(TupleS)).(*TupleS) + outstruct.Arg1 = *abi.ConvertType(out[1], new([][2]TupleT)).(*[][2]TupleT) + outstruct.Arg2 = *abi.ConvertType(out[2], new([2][]TupleT)).(*[2][]TupleT) + outstruct.Arg3 = *abi.ConvertType(out[3], new([]TupleS)).(*[]TupleS) + outstruct.Arg4 = *abi.ConvertType(out[4], new([]*big.Int)).(*[]*big.Int) + return *outstruct, err + +} + +// PackFunc2 is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd0062cdd. +// +// Solidity: function func2((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) returns() +func (tuple *Tuple) PackFunc2(a TupleS, b [][2]TupleT, c [2][]TupleT, d []TupleS, e []*big.Int) []byte { + enc, err := tuple.abi.Pack("func2", a, b, c, d, e) + if err != nil { + panic(err) + } + return enc +} + +// PackFunc3 is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xe4d9a43b. +// +// Solidity: function func3((uint16,uint16)[] ) pure returns() +func (tuple *Tuple) PackFunc3(arg0 []TupleQ) []byte { + enc, err := tuple.abi.Pack("func3", arg0) + if err != nil { + panic(err) + } + return enc +} + +// TupleTupleEvent represents a TupleEvent event raised by the Tuple contract. +type TupleTupleEvent struct { + A TupleS + B [][2]TupleT + C [2][]TupleT + D []TupleS + E []*big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const TupleTupleEventEventName = "TupleEvent" + +// ContractEventName returns the user-defined event name. +func (TupleTupleEvent) ContractEventName() string { + return TupleTupleEventEventName +} + +// UnpackTupleEventEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event TupleEvent((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) +func (tuple *Tuple) UnpackTupleEventEvent(log *types.Log) (*TupleTupleEvent, error) { + event := "TupleEvent" + if log.Topics[0] != tuple.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TupleTupleEvent) + if len(log.Data) > 0 { + if err := tuple.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range tuple.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TupleTupleEvent2 represents a TupleEvent2 event raised by the Tuple contract. +type TupleTupleEvent2 struct { + Arg0 []TupleP + Raw *types.Log // Blockchain specific contextual infos +} + +const TupleTupleEvent2EventName = "TupleEvent2" + +// ContractEventName returns the user-defined event name. +func (TupleTupleEvent2) ContractEventName() string { + return TupleTupleEvent2EventName +} + +// UnpackTupleEvent2Event is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event TupleEvent2((uint8,uint8)[] arg0) +func (tuple *Tuple) UnpackTupleEvent2Event(log *types.Log) (*TupleTupleEvent2, error) { + event := "TupleEvent2" + if log.Topics[0] != tuple.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TupleTupleEvent2) + if len(log.Data) > 0 { + if err := tuple.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range tuple.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/abigen/testdata/v2/tupler.go.txt b/accounts/abi/abigen/testdata/v2/tupler.go.txt new file mode 100644 index 0000000000..caa692dade --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/tupler.go.txt @@ -0,0 +1,89 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// TuplerMetaData contains all meta data concerning the Tupler contract. +var TuplerMetaData = bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"tuple\",\"outputs\":[{\"name\":\"a\",\"type\":\"string\"},{\"name\":\"b\",\"type\":\"int256\"},{\"name\":\"c\",\"type\":\"bytes32\"}],\"type\":\"function\"}]", + ID: "a8f4d2061f55c712cfae266c426a1cd568", + Bin: "0x606060405260dc8060106000396000f3606060405260e060020a60003504633175aae28114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3", +} + +// Tupler is an auto generated Go binding around an Ethereum contract. +type Tupler struct { + abi abi.ABI +} + +// NewTupler creates a new instance of Tupler. +func NewTupler() *Tupler { + parsed, err := TuplerMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Tupler{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Tupler) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackTuple is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x3175aae2. +// +// Solidity: function tuple() returns(string a, int256 b, bytes32 c) +func (tupler *Tupler) PackTuple() []byte { + enc, err := tupler.abi.Pack("tuple") + if err != nil { + panic(err) + } + return enc +} + +// TupleOutput serves as a container for the return parameters of contract +// method Tuple. +type TupleOutput struct { + A string + B *big.Int + C [32]byte +} + +// UnpackTuple is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x3175aae2. +// +// Solidity: function tuple() returns(string a, int256 b, bytes32 c) +func (tupler *Tupler) UnpackTuple(data []byte) (TupleOutput, error) { + out, err := tupler.abi.Unpack("tuple", data) + outstruct := new(TupleOutput) + if err != nil { + return *outstruct, err + } + outstruct.A = *abi.ConvertType(out[0], new(string)).(*string) + outstruct.B = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + outstruct.C = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + return *outstruct, err + +} diff --git a/accounts/abi/abigen/testdata/v2/underscorer.go.txt b/accounts/abi/abigen/testdata/v2/underscorer.go.txt new file mode 100644 index 0000000000..ef9eb864fa --- /dev/null +++ b/accounts/abi/abigen/testdata/v2/underscorer.go.txt @@ -0,0 +1,322 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindtests + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// UnderscorerMetaData contains all meta data concerning the Underscorer contract. +var UnderscorerMetaData = bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"LowerUpperCollision\",\"outputs\":[{\"name\":\"_res\",\"type\":\"int256\"},{\"name\":\"Res\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"_under_scored_func\",\"outputs\":[{\"name\":\"_int\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"UnderscoredOutput\",\"outputs\":[{\"name\":\"_int\",\"type\":\"int256\"},{\"name\":\"_string\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"PurelyUnderscoredOutput\",\"outputs\":[{\"name\":\"_\",\"type\":\"int256\"},{\"name\":\"res\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"UpperLowerCollision\",\"outputs\":[{\"name\":\"_Res\",\"type\":\"int256\"},{\"name\":\"res\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"AllPurelyUnderscoredOutput\",\"outputs\":[{\"name\":\"_\",\"type\":\"int256\"},{\"name\":\"__\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"UpperUpperCollision\",\"outputs\":[{\"name\":\"_Res\",\"type\":\"int256\"},{\"name\":\"Res\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"LowerLowerCollision\",\"outputs\":[{\"name\":\"_res\",\"type\":\"int256\"},{\"name\":\"res\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]", + ID: "5873a90ab43c925dfced86ad53f871f01d", + Bin: "0x6060604052341561000f57600080fd5b6103858061001e6000396000f30060606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461009357806346546dbe146100c357806367e6633d146100ec5780639df4848514610181578063af7486ab146101b1578063b564b34d146101e1578063e02ab24d14610211578063e409ca4514610241575b600080fd5b341561009e57600080fd5b6100a6610271565b604051808381526020018281526020019250505060405180910390f35b34156100ce57600080fd5b6100d6610286565b6040518082815260200191505060405180910390f35b34156100f757600080fd5b6100ff61028e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561014557808201518184015260208101905061012a565b50505050905090810190601f1680156101725780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561018c57600080fd5b6101946102dc565b604051808381526020018281526020019250505060405180910390f35b34156101bc57600080fd5b6101c46102f1565b604051808381526020018281526020019250505060405180910390f35b34156101ec57600080fd5b6101f4610306565b604051808381526020018281526020019250505060405180910390f35b341561021c57600080fd5b61022461031b565b604051808381526020018281526020019250505060405180910390f35b341561024c57600080fd5b610254610330565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b600080905090565b6000610298610345565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a72305820d1a53d9de9d1e3d55cb3dc591900b63c4f1ded79114f7b79b332684840e186a40029", +} + +// Underscorer is an auto generated Go binding around an Ethereum contract. +type Underscorer struct { + abi abi.ABI +} + +// NewUnderscorer creates a new instance of Underscorer. +func NewUnderscorer() *Underscorer { + parsed, err := UnderscorerMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &Underscorer{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *Underscorer) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackAllPurelyUnderscoredOutput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb564b34d. +// +// Solidity: function AllPurelyUnderscoredOutput() view returns(int256 _, int256 __) +func (underscorer *Underscorer) PackAllPurelyUnderscoredOutput() []byte { + enc, err := underscorer.abi.Pack("AllPurelyUnderscoredOutput") + if err != nil { + panic(err) + } + return enc +} + +// AllPurelyUnderscoredOutputOutput serves as a container for the return parameters of contract +// method AllPurelyUnderscoredOutput. +type AllPurelyUnderscoredOutputOutput struct { + Arg0 *big.Int + Arg1 *big.Int +} + +// UnpackAllPurelyUnderscoredOutput is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xb564b34d. +// +// Solidity: function AllPurelyUnderscoredOutput() view returns(int256 _, int256 __) +func (underscorer *Underscorer) UnpackAllPurelyUnderscoredOutput(data []byte) (AllPurelyUnderscoredOutputOutput, error) { + out, err := underscorer.abi.Unpack("AllPurelyUnderscoredOutput", data) + outstruct := new(AllPurelyUnderscoredOutputOutput) + if err != nil { + return *outstruct, err + } + outstruct.Arg0 = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.Arg1 = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackLowerLowerCollision is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xe409ca45. +// +// Solidity: function LowerLowerCollision() view returns(int256 _res, int256 res) +func (underscorer *Underscorer) PackLowerLowerCollision() []byte { + enc, err := underscorer.abi.Pack("LowerLowerCollision") + if err != nil { + panic(err) + } + return enc +} + +// LowerLowerCollisionOutput serves as a container for the return parameters of contract +// method LowerLowerCollision. +type LowerLowerCollisionOutput struct { + Res *big.Int + Res0 *big.Int +} + +// UnpackLowerLowerCollision is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xe409ca45. +// +// Solidity: function LowerLowerCollision() view returns(int256 _res, int256 res) +func (underscorer *Underscorer) UnpackLowerLowerCollision(data []byte) (LowerLowerCollisionOutput, error) { + out, err := underscorer.abi.Unpack("LowerLowerCollision", data) + outstruct := new(LowerLowerCollisionOutput) + if err != nil { + return *outstruct, err + } + outstruct.Res = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.Res0 = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackLowerUpperCollision is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x03a59213. +// +// Solidity: function LowerUpperCollision() view returns(int256 _res, int256 Res) +func (underscorer *Underscorer) PackLowerUpperCollision() []byte { + enc, err := underscorer.abi.Pack("LowerUpperCollision") + if err != nil { + panic(err) + } + return enc +} + +// LowerUpperCollisionOutput serves as a container for the return parameters of contract +// method LowerUpperCollision. +type LowerUpperCollisionOutput struct { + Res *big.Int + Res0 *big.Int +} + +// UnpackLowerUpperCollision is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x03a59213. +// +// Solidity: function LowerUpperCollision() view returns(int256 _res, int256 Res) +func (underscorer *Underscorer) UnpackLowerUpperCollision(data []byte) (LowerUpperCollisionOutput, error) { + out, err := underscorer.abi.Unpack("LowerUpperCollision", data) + outstruct := new(LowerUpperCollisionOutput) + if err != nil { + return *outstruct, err + } + outstruct.Res = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.Res0 = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackPurelyUnderscoredOutput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9df48485. +// +// Solidity: function PurelyUnderscoredOutput() view returns(int256 _, int256 res) +func (underscorer *Underscorer) PackPurelyUnderscoredOutput() []byte { + enc, err := underscorer.abi.Pack("PurelyUnderscoredOutput") + if err != nil { + panic(err) + } + return enc +} + +// PurelyUnderscoredOutputOutput serves as a container for the return parameters of contract +// method PurelyUnderscoredOutput. +type PurelyUnderscoredOutputOutput struct { + Arg0 *big.Int + Res *big.Int +} + +// UnpackPurelyUnderscoredOutput is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x9df48485. +// +// Solidity: function PurelyUnderscoredOutput() view returns(int256 _, int256 res) +func (underscorer *Underscorer) UnpackPurelyUnderscoredOutput(data []byte) (PurelyUnderscoredOutputOutput, error) { + out, err := underscorer.abi.Unpack("PurelyUnderscoredOutput", data) + outstruct := new(PurelyUnderscoredOutputOutput) + if err != nil { + return *outstruct, err + } + outstruct.Arg0 = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.Res = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackUnderscoredOutput is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x67e6633d. +// +// Solidity: function UnderscoredOutput() view returns(int256 _int, string _string) +func (underscorer *Underscorer) PackUnderscoredOutput() []byte { + enc, err := underscorer.abi.Pack("UnderscoredOutput") + if err != nil { + panic(err) + } + return enc +} + +// UnderscoredOutputOutput serves as a container for the return parameters of contract +// method UnderscoredOutput. +type UnderscoredOutputOutput struct { + Int *big.Int + String string +} + +// UnpackUnderscoredOutput is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x67e6633d. +// +// Solidity: function UnderscoredOutput() view returns(int256 _int, string _string) +func (underscorer *Underscorer) UnpackUnderscoredOutput(data []byte) (UnderscoredOutputOutput, error) { + out, err := underscorer.abi.Unpack("UnderscoredOutput", data) + outstruct := new(UnderscoredOutputOutput) + if err != nil { + return *outstruct, err + } + outstruct.Int = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.String = *abi.ConvertType(out[1], new(string)).(*string) + return *outstruct, err + +} + +// PackUpperLowerCollision is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xaf7486ab. +// +// Solidity: function UpperLowerCollision() view returns(int256 _Res, int256 res) +func (underscorer *Underscorer) PackUpperLowerCollision() []byte { + enc, err := underscorer.abi.Pack("UpperLowerCollision") + if err != nil { + panic(err) + } + return enc +} + +// UpperLowerCollisionOutput serves as a container for the return parameters of contract +// method UpperLowerCollision. +type UpperLowerCollisionOutput struct { + Res *big.Int + Res0 *big.Int +} + +// UnpackUpperLowerCollision is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xaf7486ab. +// +// Solidity: function UpperLowerCollision() view returns(int256 _Res, int256 res) +func (underscorer *Underscorer) UnpackUpperLowerCollision(data []byte) (UpperLowerCollisionOutput, error) { + out, err := underscorer.abi.Unpack("UpperLowerCollision", data) + outstruct := new(UpperLowerCollisionOutput) + if err != nil { + return *outstruct, err + } + outstruct.Res = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.Res0 = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackUpperUpperCollision is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xe02ab24d. +// +// Solidity: function UpperUpperCollision() view returns(int256 _Res, int256 Res) +func (underscorer *Underscorer) PackUpperUpperCollision() []byte { + enc, err := underscorer.abi.Pack("UpperUpperCollision") + if err != nil { + panic(err) + } + return enc +} + +// UpperUpperCollisionOutput serves as a container for the return parameters of contract +// method UpperUpperCollision. +type UpperUpperCollisionOutput struct { + Res *big.Int + Res0 *big.Int +} + +// UnpackUpperUpperCollision is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xe02ab24d. +// +// Solidity: function UpperUpperCollision() view returns(int256 _Res, int256 Res) +func (underscorer *Underscorer) UnpackUpperUpperCollision(data []byte) (UpperUpperCollisionOutput, error) { + out, err := underscorer.abi.Unpack("UpperUpperCollision", data) + outstruct := new(UpperUpperCollisionOutput) + if err != nil { + return *outstruct, err + } + outstruct.Res = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.Res0 = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackUnderScoredFunc is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x46546dbe. +// +// Solidity: function _under_scored_func() view returns(int256 _int) +func (underscorer *Underscorer) PackUnderScoredFunc() []byte { + enc, err := underscorer.abi.Pack("_under_scored_func") + if err != nil { + panic(err) + } + return enc +} + +// UnpackUnderScoredFunc is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x46546dbe. +// +// Solidity: function _under_scored_func() view returns(int256 _int) +func (underscorer *Underscorer) UnpackUnderScoredFunc(data []byte) (*big.Int, error) { + out, err := underscorer.abi.Unpack("_under_scored_func", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go deleted file mode 100644 index b5e6e349c4..0000000000 --- a/accounts/abi/bind/auth.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2016 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 bind - -import ( - "context" - "crypto/ecdsa" - "errors" - "io" - "math/big" - - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/accounts/external" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" -) - -// ErrNoChainID is returned whenever the user failed to specify a chain id. -var ErrNoChainID = errors.New("no chain id specified") - -// ErrNotAuthorized is returned when an account is not properly unlocked. -var ErrNotAuthorized = errors.New("not authorized to sign this account") - -// NewTransactor is a utility method to easily create a transaction signer from -// an encrypted json key stream and the associated passphrase. -// -// Deprecated: Use NewTransactorWithChainID instead. -func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { - log.Warn("WARNING: NewTransactor has been deprecated in favour of NewTransactorWithChainID") - json, err := io.ReadAll(keyin) - if err != nil { - return nil, err - } - key, err := keystore.DecryptKey(json, passphrase) - if err != nil { - return nil, err - } - return NewKeyedTransactor(key.PrivateKey), nil -} - -// NewKeyStoreTransactor is a utility method to easily create a transaction signer from -// a decrypted key from a keystore. -// -// Deprecated: Use NewKeyStoreTransactorWithChainID instead. -func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { - log.Warn("WARNING: NewKeyStoreTransactor has been deprecated in favour of NewTransactorWithChainID") - signer := types.HomesteadSigner{} - return &TransactOpts{ - From: account.Address, - Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { - if address != account.Address { - return nil, ErrNotAuthorized - } - signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) - if err != nil { - return nil, err - } - return tx.WithSignature(signer, signature) - }, - Context: context.Background(), - }, nil -} - -// NewKeyedTransactor is a utility method to easily create a transaction signer -// from a single private key. -// -// Deprecated: Use NewKeyedTransactorWithChainID instead. -func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { - log.Warn("WARNING: NewKeyedTransactor has been deprecated in favour of NewKeyedTransactorWithChainID") - keyAddr := crypto.PubkeyToAddress(key.PublicKey) - signer := types.HomesteadSigner{} - return &TransactOpts{ - From: keyAddr, - Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { - if address != keyAddr { - return nil, ErrNotAuthorized - } - signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) - if err != nil { - return nil, err - } - return tx.WithSignature(signer, signature) - }, - Context: context.Background(), - } -} - -// NewTransactorWithChainID is a utility method to easily create a transaction signer from -// an encrypted json key stream and the associated passphrase. -func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.Int) (*TransactOpts, error) { - json, err := io.ReadAll(keyin) - if err != nil { - return nil, err - } - key, err := keystore.DecryptKey(json, passphrase) - if err != nil { - return nil, err - } - return NewKeyedTransactorWithChainID(key.PrivateKey, chainID) -} - -// NewKeyStoreTransactorWithChainID is a utility method to easily create a transaction signer from -// a decrypted key from a keystore. -func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) (*TransactOpts, error) { - if chainID == nil { - return nil, ErrNoChainID - } - signer := types.LatestSignerForChainID(chainID) - return &TransactOpts{ - From: account.Address, - Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { - if address != account.Address { - return nil, ErrNotAuthorized - } - signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) - if err != nil { - return nil, err - } - return tx.WithSignature(signer, signature) - }, - Context: context.Background(), - }, nil -} - -// 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) { - if chainID == nil { - return nil, ErrNoChainID - } - keyAddr := crypto.PubkeyToAddress(key.PublicKey) - signer := types.LatestSignerForChainID(chainID) - return &TransactOpts{ - From: keyAddr, - Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { - if address != keyAddr { - return nil, ErrNotAuthorized - } - signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) - if err != nil { - return nil, err - } - return tx.WithSignature(signer, signature) - }, - Context: context.Background(), - }, nil -} - -// NewClefTransactor is a utility method to easily create a transaction signer -// with a clef backend. -func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) *TransactOpts { - return &TransactOpts{ - From: account.Address, - Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) { - if address != account.Address { - return nil, ErrNotAuthorized - } - return clef.SignTx(account, transaction, nil) // Clef enforces its own chain id - }, - Context: context.Background(), - } -} diff --git a/accounts/abi/bind/old.go b/accounts/abi/bind/old.go new file mode 100644 index 0000000000..b09f5f3c7a --- /dev/null +++ b/accounts/abi/bind/old.go @@ -0,0 +1,294 @@ +// Copyright 2016 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 bind is the runtime for abigen v1 generated contract bindings. +// Deprecated: please use github.com/ethereum/go-ethereum/bind/v2 +package bind + +import ( + "context" + "crypto/ecdsa" + "errors" + "io" + "math/big" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/abigen" + bind2 "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/accounts/external" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" +) + +// Bind generates a v1 contract binding. +// Deprecated: binding generation has moved to github.com/ethereum/go-ethereum/accounts/abi/abigen +func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, libs map[string]string, aliases map[string]string) (string, error) { + return abigen.Bind(types, abis, bytecodes, fsigs, pkg, libs, aliases) +} + +// auth.go + +// ErrNoChainID is returned whenever the user failed to specify a chain id. +var ErrNoChainID = errors.New("no chain id specified") + +// ErrNotAuthorized is returned when an account is not properly unlocked. +var ErrNotAuthorized = bind2.ErrNotAuthorized + +// NewTransactor is a utility method to easily create a transaction signer from +// an encrypted json key stream and the associated passphrase. +// +// Deprecated: Use NewTransactorWithChainID instead. +func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { + log.Warn("WARNING: NewTransactor has been deprecated in favour of NewTransactorWithChainID") + json, err := io.ReadAll(keyin) + if err != nil { + return nil, err + } + key, err := keystore.DecryptKey(json, passphrase) + if err != nil { + return nil, err + } + return NewKeyedTransactor(key.PrivateKey), nil +} + +// NewKeyStoreTransactor is a utility method to easily create a transaction signer from +// a decrypted key from a keystore. +// +// Deprecated: Use NewKeyStoreTransactorWithChainID instead. +func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { + log.Warn("WARNING: NewKeyStoreTransactor has been deprecated in favour of NewTransactorWithChainID") + signer := types.HomesteadSigner{} + return &TransactOpts{ + From: account.Address, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != account.Address { + return nil, ErrNotAuthorized + } + signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + Context: context.Background(), + }, nil +} + +// NewKeyedTransactor is a utility method to easily create a transaction signer +// from a single private key. +// +// Deprecated: Use NewKeyedTransactorWithChainID instead. +func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { + log.Warn("WARNING: NewKeyedTransactor has been deprecated in favour of NewKeyedTransactorWithChainID") + keyAddr := crypto.PubkeyToAddress(key.PublicKey) + signer := types.HomesteadSigner{} + return &TransactOpts{ + From: keyAddr, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != keyAddr { + return nil, ErrNotAuthorized + } + signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + Context: context.Background(), + } +} + +// NewTransactorWithChainID is a utility method to easily create a transaction signer from +// an encrypted json key stream and the associated passphrase. +func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.Int) (*TransactOpts, error) { + json, err := io.ReadAll(keyin) + if err != nil { + return nil, err + } + key, err := keystore.DecryptKey(json, passphrase) + if err != nil { + return nil, err + } + return NewKeyedTransactorWithChainID(key.PrivateKey, chainID) +} + +// NewKeyStoreTransactorWithChainID is a utility method to easily create a transaction signer from +// a decrypted key from a keystore. +func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) (*TransactOpts, error) { + // New version panics for chainID == nil, catch it here. + if chainID == nil { + return nil, ErrNoChainID + } + return bind2.NewKeyStoreTransactor(keystore, account, chainID), nil +} + +// 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) { + // New version panics for chainID == nil, catch it here. + if chainID == nil { + return nil, ErrNoChainID + } + return bind2.NewKeyedTransactor(key, chainID), nil +} + +// NewClefTransactor is a utility method to easily create a transaction signer +// with a clef backend. +func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) *TransactOpts { + return bind2.NewClefTransactor(clef, account) +} + +// backend.go + +var ( + // ErrNoCode is returned by call and transact operations for which the requested + // recipient contract to operate on does not exist in the state db or does not + // have any code associated with it (i.e. self-destructed). + ErrNoCode = bind2.ErrNoCode + + // ErrNoPendingState is raised when attempting to perform a pending state action + // on a backend that doesn't implement PendingContractCaller. + ErrNoPendingState = bind2.ErrNoPendingState + + // ErrNoBlockHashState is raised when attempting to perform a block hash action + // on a backend that doesn't implement BlockHashContractCaller. + ErrNoBlockHashState = bind2.ErrNoBlockHashState + + // ErrNoCodeAfterDeploy is returned by WaitDeployed if contract creation leaves + // an empty contract behind. + ErrNoCodeAfterDeploy = bind2.ErrNoCodeAfterDeploy +) + +// ContractCaller defines the methods needed to allow operating with a contract on a read +// only basis. +type ContractCaller = bind2.ContractCaller + +// PendingContractCaller defines methods to perform contract calls on the pending state. +// Call will try to discover this interface when access to the pending state is requested. +// If the backend does not support the pending state, Call returns ErrNoPendingState. +type PendingContractCaller = bind2.PendingContractCaller + +// BlockHashContractCaller defines methods to perform contract calls on a specific block hash. +// Call will try to discover this interface when access to a block by hash is requested. +// If the backend does not support the block hash state, Call returns ErrNoBlockHashState. +type BlockHashContractCaller = bind2.BlockHashContractCaller + +// ContractTransactor defines the methods needed to allow operating with a contract +// on a write only basis. Besides the transacting method, the remainder are helpers +// used when the user does not provide some needed values, but rather leaves it up +// to the transactor to decide. +type ContractTransactor = bind2.ContractTransactor + +// DeployBackend wraps the operations needed by WaitMined and WaitDeployed. +type DeployBackend = bind2.DeployBackend + +// ContractFilterer defines the methods needed to access log events using one-off +// queries or continuous event subscriptions. +type ContractFilterer = bind2.ContractFilterer + +// ContractBackend defines the methods needed to work with contracts on a read-write basis. +type ContractBackend = bind2.ContractBackend + +// base.go + +type SignerFn = bind2.SignerFn + +type CallOpts = bind2.CallOpts + +type TransactOpts = bind2.TransactOpts + +type FilterOpts = bind2.FilterOpts + +type WatchOpts = bind2.WatchOpts + +type BoundContract = bind2.BoundContract + +func NewBoundContract(address common.Address, abi abi.ABI, caller ContractCaller, transactor ContractTransactor, filterer ContractFilterer) *BoundContract { + return bind2.NewBoundContract(address, abi, caller, transactor, filterer) +} + +func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBackend, params ...interface{}) (common.Address, *types.Transaction, *BoundContract, error) { + packed, err := abi.Pack("", params...) + if err != nil { + return common.Address{}, nil, nil, err + } + addr, tx, err := bind2.DeployContract(opts, bytecode, backend, packed) + if err != nil { + return common.Address{}, nil, nil, err + } + contract := NewBoundContract(addr, abi, backend, backend, backend) + return addr, tx, contract, nil +} + +// MetaData collects all metadata for a bound contract. +type MetaData struct { + Bin string // runtime bytecode (as a hex string) + ABI string // the raw ABI definition (JSON) + Sigs map[string]string // 4byte identifier -> function signature + mu sync.Mutex + parsedABI *abi.ABI +} + +// GetAbi returns the parsed ABI definition. +func (m *MetaData) GetAbi() (*abi.ABI, error) { + m.mu.Lock() + defer m.mu.Unlock() + + if m.parsedABI != nil { + return m.parsedABI, nil + } + if parsed, err := abi.JSON(strings.NewReader(m.ABI)); err != nil { + return nil, err + } else { + m.parsedABI = &parsed + } + return m.parsedABI, nil +} + +// util.go + +// WaitMined waits for tx to be mined on the blockchain. +// It stops waiting when the context is canceled. +func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) { + return bind2.WaitMined(ctx, b, tx.Hash()) +} + +// WaitMinedHash waits for a transaction with the provided hash to be mined on the blockchain. +// It stops waiting when the context is canceled. +func WaitMinedHash(ctx context.Context, b DeployBackend, hash common.Hash) (*types.Receipt, error) { + return bind2.WaitMined(ctx, b, hash) +} + +// WaitDeployed waits for a contract deployment transaction and returns the on-chain +// contract address when it is mined. It stops waiting when ctx is canceled. +func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) { + if tx.To() != nil { + return common.Address{}, errors.New("tx is not contract creation") + } + return bind2.WaitDeployed(ctx, b, tx.Hash()) +} + +// WaitDeployedHash waits for a contract deployment transaction with the provided hash and returns the on-chain +// contract address when it is mined. It stops waiting when ctx is canceled. +func WaitDeployedHash(ctx context.Context, b DeployBackend, hash common.Hash) (common.Address, error) { + return bind2.WaitDeployed(ctx, b, hash) +} diff --git a/accounts/abi/bind/v2/auth.go b/accounts/abi/bind/v2/auth.go new file mode 100644 index 0000000000..0a452a2c75 --- /dev/null +++ b/accounts/abi/bind/v2/auth.go @@ -0,0 +1,96 @@ +// Copyright 2016 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 bind + +import ( + "context" + "crypto/ecdsa" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/external" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" +) + +// ErrNotAuthorized is returned when an account is not properly unlocked. +var ErrNotAuthorized = errors.New("not authorized to sign this account") + +// NewKeyStoreTransactor is a utility method to easily create a transaction signer from +// a decrypted key from a keystore. +func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) *TransactOpts { + if chainID == nil { + panic("nil chainID") + } + signer := types.LatestSignerForChainID(chainID) + return &TransactOpts{ + From: account.Address, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != account.Address { + return nil, ErrNotAuthorized + } + signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + Context: context.Background(), + } +} + +// NewKeyedTransactor is a utility method to easily create a transaction signer +// from a single private key. +func NewKeyedTransactor(key *ecdsa.PrivateKey, chainID *big.Int) *TransactOpts { + if chainID == nil { + panic("nil chainID") + } + keyAddr := crypto.PubkeyToAddress(key.PublicKey) + signer := types.LatestSignerForChainID(chainID) + return &TransactOpts{ + From: keyAddr, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != keyAddr { + return nil, ErrNotAuthorized + } + signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + Context: context.Background(), + } +} + +// NewClefTransactor is a utility method to easily create a transaction signer +// with a clef backend. +func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) *TransactOpts { + return &TransactOpts{ + From: account.Address, + Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) { + if address != account.Address { + return nil, ErrNotAuthorized + } + return clef.SignTx(account, transaction, nil) // Clef enforces its own chain id + }, + Context: context.Background(), + } +} diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/v2/backend.go similarity index 90% rename from accounts/abi/bind/backend.go rename to accounts/abi/bind/v2/backend.go index 38b3046970..2f5f17b31e 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/v2/backend.go @@ -43,6 +43,11 @@ var ( // ErrNoCodeAfterDeploy is returned by WaitDeployed if contract creation leaves // an empty contract behind. ErrNoCodeAfterDeploy = errors.New("no contract code after deployment") + + // ErrNoAddressInReceipt is returned by WaitDeployed when the receipt for the + // transaction hash does not contain a contract address. This error may indicate + // that the transaction hash was not a CREATE transaction. + ErrNoAddressInReceipt = errors.New("no contract address in receipt") ) // ContractCaller defines the methods needed to allow operating with a contract on a read @@ -118,3 +123,11 @@ type ContractBackend interface { ContractTransactor ContractFilterer } + +// Backend combines all backend methods used in this package. This type is provided for +// convenience. It is meant to be used when you need to hold a reference to a backend that +// is used for both deployment and contract interaction. +type Backend interface { + DeployBackend + ContractBackend +} diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/v2/base.go similarity index 85% rename from accounts/abi/bind/base.go rename to accounts/abi/bind/v2/base.go index 0504089c71..a9b667e697 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/v2/base.go @@ -25,10 +25,10 @@ import ( "sync" "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" ) @@ -89,25 +89,42 @@ type WatchOpts struct { // MetaData collects all metadata for a bound contract. type MetaData struct { - mu sync.Mutex - Sigs map[string]string - Bin string - ABI string - ab *abi.ABI + Bin string // deployer bytecode (as a hex string) + ABI string // the raw ABI definition (JSON) + Deps []*MetaData // library dependencies of the contract + + // For bindings that were compiled from combined-json ID is the Solidity + // library pattern: a 34 character prefix of the hex encoding of the keccak256 + // hash of the fully qualified 'library name', i.e. the path of the source file. + // + // For contracts compiled from the ABI definition alone, this is the type name + // of the contract (as specified in the ABI definition or overridden via the + // --type flag). + // + // This is a unique identifier of a contract within a compilation unit. When + // used as part of a multi-contract deployment with library dependencies, the + // ID is used to link contracts during deployment using [LinkAndDeploy]. + ID string + + mu sync.Mutex + parsedABI *abi.ABI } -func (m *MetaData) GetAbi() (*abi.ABI, error) { +// ParseABI returns the parsed ABI specification, or an error if the string +// representation of the ABI set in the MetaData instance could not be parsed. +func (m *MetaData) ParseABI() (*abi.ABI, error) { m.mu.Lock() defer m.mu.Unlock() - if m.ab != nil { - return m.ab, nil + + if m.parsedABI != nil { + return m.parsedABI, nil } if parsed, err := abi.JSON(strings.NewReader(m.ABI)); err != nil { return nil, err } else { - m.ab = &parsed + m.parsedABI = &parsed } - return m.ab, nil + return m.parsedABI, nil } // BoundContract is the base wrapper object that reflects a contract on the @@ -133,94 +150,23 @@ func NewBoundContract(address common.Address, abi abi.ABI, caller ContractCaller } } -// DeployContract deploys a contract onto the Ethereum blockchain and binds the -// deployment address with a Go wrapper. -func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBackend, params ...interface{}) (common.Address, *types.Transaction, *BoundContract, error) { - // Otherwise try to deploy the contract - c := NewBoundContract(common.Address{}, abi, backend, backend, backend) - - input, err := c.abi.Pack("", params...) - if err != nil { - return common.Address{}, nil, nil, err - } - tx, err := c.transact(opts, nil, append(bytecode, input...)) - if err != nil { - return common.Address{}, nil, nil, err - } - c.address = crypto.CreateAddress(opts.From, tx.Nonce()) - return c.address, tx, c, 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 (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method string, params ...interface{}) error { - // Don't crash on a lazy user - if opts == nil { - opts = new(CallOpts) - } +func (c *BoundContract) Call(opts *CallOpts, results *[]any, method string, params ...any) error { if results == nil { - results = new([]interface{}) + results = new([]any) } // Pack the input, call and unpack the results input, err := c.abi.Pack(method, params...) if err != nil { return err } - var ( - msg = ethereum.CallMsg{From: opts.From, To: &c.address, Data: input} - ctx = ensureContext(opts.Context) - code []byte - output []byte - ) - if opts.Pending { - pb, ok := c.caller.(PendingContractCaller) - if !ok { - return ErrNoPendingState - } - output, err = pb.PendingCallContract(ctx, msg) - if err != nil { - return err - } - if len(output) == 0 { - // Make sure we have a contract to operate on, and bail out otherwise. - if code, err = pb.PendingCodeAt(ctx, c.address); err != nil { - return err - } else if len(code) == 0 { - return ErrNoCode - } - } - } else if opts.BlockHash != (common.Hash{}) { - bh, ok := c.caller.(BlockHashContractCaller) - if !ok { - return ErrNoBlockHashState - } - output, err = bh.CallContractAtHash(ctx, msg, opts.BlockHash) - if err != nil { - return err - } - if len(output) == 0 { - // Make sure we have a contract to operate on, and bail out otherwise. - if code, err = bh.CodeAtHash(ctx, c.address, opts.BlockHash); err != nil { - return err - } else if len(code) == 0 { - return ErrNoCode - } - } - } else { - output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber) - if err != nil { - return err - } - if len(output) == 0 { - // Make sure we have a contract to operate on, and bail out otherwise. - if code, err = c.caller.CodeAt(ctx, c.address, opts.BlockNumber); err != nil { - return err - } else if len(code) == 0 { - return ErrNoCode - } - } + + output, err := c.call(opts, input) + if err != nil { + return err } if len(*results) == 0 { @@ -232,26 +178,97 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri return c.abi.UnpackIntoInterface(res[0], method, output) } +// CallRaw executes an eth_call against the contract with the raw calldata as +// input. It returns the call's return data or an error. +func (c *BoundContract) CallRaw(opts *CallOpts, input []byte) ([]byte, error) { + return c.call(opts, input) +} + +func (c *BoundContract) call(opts *CallOpts, input []byte) ([]byte, error) { + // Don't crash on a lazy user + if opts == nil { + opts = new(CallOpts) + } + var ( + msg = ethereum.CallMsg{From: opts.From, To: &c.address, Data: input} + ctx = ensureContext(opts.Context) + code []byte + output []byte + err error + ) + if opts.Pending { + pb, ok := c.caller.(PendingContractCaller) + if !ok { + return nil, ErrNoPendingState + } + output, err = pb.PendingCallContract(ctx, msg) + if err != nil { + return nil, err + } + if len(output) == 0 { + // Make sure we have a contract to operate on, and bail out otherwise. + if code, err = pb.PendingCodeAt(ctx, c.address); err != nil { + return nil, err + } else if len(code) == 0 { + return nil, ErrNoCode + } + } + } else if opts.BlockHash != (common.Hash{}) { + bh, ok := c.caller.(BlockHashContractCaller) + if !ok { + return nil, ErrNoBlockHashState + } + output, err = bh.CallContractAtHash(ctx, msg, opts.BlockHash) + if err != nil { + return nil, err + } + if len(output) == 0 { + // Make sure we have a contract to operate on, and bail out otherwise. + if code, err = bh.CodeAtHash(ctx, c.address, opts.BlockHash); err != nil { + return nil, err + } else if len(code) == 0 { + return nil, ErrNoCode + } + } + } else { + output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber) + if err != nil { + return nil, err + } + if len(output) == 0 { + // Make sure we have a contract to operate on, and bail out otherwise. + if code, err = c.caller.CodeAt(ctx, c.address, opts.BlockNumber); err != nil { + return nil, err + } else if len(code) == 0 { + return nil, ErrNoCode + } + } + } + return output, nil +} + // Transact invokes the (paid) contract method with params as input values. -func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { +func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...any) (*types.Transaction, error) { // Otherwise pack up the parameters and invoke the contract input, err := c.abi.Pack(method, params...) if err != nil { return nil, err } - // todo(rjl493456442) check whether the method is payable or not, - // reject invalid transaction at the first place return c.transact(opts, &c.address, input) } // RawTransact initiates a transaction with the given raw calldata as the input. // It's usually used to initiate transactions for invoking **Fallback** function. func (c *BoundContract) RawTransact(opts *TransactOpts, calldata []byte) (*types.Transaction, error) { - // todo(rjl493456442) check whether the method is payable or not, - // reject invalid transaction at the first place return c.transact(opts, &c.address, calldata) } +// RawCreationTransact creates and submits a contract-creation transaction with +// the given calldata as the input. +func (c *BoundContract) RawCreationTransact(opts *TransactOpts, calldata []byte) (*types.Transaction, error) { + return c.transact(opts, nil, calldata) +} + // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. func (c *BoundContract) Transfer(opts *TransactOpts) (*types.Transaction, error) { @@ -433,14 +450,13 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i // FilterLogs filters contract logs for past blocks, returning the necessary // channels to construct a strongly typed bound iterator on top of them. -func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]interface{}) (chan types.Log, event.Subscription, error) { +func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]any) (chan types.Log, event.Subscription, error) { // Don't crash on a lazy user if opts == nil { opts = new(FilterOpts) } // Append the event selector to the query parameters and construct the topic set - query = append([][]interface{}{{c.abi.Events[name].ID}}, query...) - + query = append([][]any{{c.abi.Events[name].ID}}, query...) topics, err := abi.MakeTopics(query...) if err != nil { return nil, nil, err @@ -479,13 +495,13 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int // WatchLogs filters subscribes to contract logs for future blocks, returning a // subscription object that can be used to tear down the watcher. -func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]interface{}) (chan types.Log, event.Subscription, error) { +func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]any) (chan types.Log, event.Subscription, error) { // Don't crash on a lazy user if opts == nil { opts = new(WatchOpts) } // Append the event selector to the query parameters and construct the topic set - query = append([][]interface{}{{c.abi.Events[name].ID}}, query...) + query = append([][]any{{c.abi.Events[name].ID}}, query...) topics, err := abi.MakeTopics(query...) if err != nil { @@ -509,7 +525,7 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter } // UnpackLog unpacks a retrieved log into the provided output structure. -func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) error { +func (c *BoundContract) UnpackLog(out any, event string, log types.Log) error { // Anonymous events are not supported. if len(log.Topics) == 0 { return errNoEventSignature @@ -532,7 +548,7 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) } // UnpackLogIntoMap unpacks a retrieved log into the provided map. -func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error { +func (c *BoundContract) UnpackLogIntoMap(out map[string]any, event string, log types.Log) error { // Anonymous events are not supported. if len(log.Topics) == 0 { return errNoEventSignature diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/v2/base_test.go similarity index 99% rename from accounts/abi/bind/base_test.go rename to accounts/abi/bind/v2/base_test.go index f7eb7d14d3..80d0f22f2c 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/v2/base_test.go @@ -26,7 +26,7 @@ import ( "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/accounts/abi/bind/v2" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" diff --git a/accounts/abi/bind/v2/dep_tree.go b/accounts/abi/bind/v2/dep_tree.go new file mode 100644 index 0000000000..72a6468951 --- /dev/null +++ b/accounts/abi/bind/v2/dep_tree.go @@ -0,0 +1,167 @@ +// Copyright 2025 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 bind + +import ( + "encoding/hex" + "fmt" + "maps" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// DeploymentParams contains parameters needed to deploy one or more contracts via LinkAndDeploy +type DeploymentParams struct { + // list of all contracts targeted for the deployment + Contracts []*MetaData + + // optional map of ABI-encoded constructor inputs keyed by the MetaData.ID. + Inputs map[string][]byte + + // optional map of override addresses for specifying already-deployed + // contracts. It is keyed by the MetaData.ID. + Overrides map[string]common.Address +} + +// validate determines whether the contracts specified in the DeploymentParams +// instance have embedded deployer code in their provided MetaData instances. +func (d *DeploymentParams) validate() error { + for _, meta := range d.Contracts { + if meta.Bin == "" { + return fmt.Errorf("cannot deploy contract %s: deployer code missing from metadata", meta.ID) + } + } + return nil +} + +// DeploymentResult contains information about the result of a pending +// deployment made by LinkAndDeploy. +type DeploymentResult struct { + // Map of contract MetaData.ID to pending deployment transaction + Txs map[string]*types.Transaction + + // Map of contract MetaData.ID to the address where it will be deployed + Addresses map[string]common.Address +} + +// DeployFn deploys a contract given a deployer and optional input. It returns +// the address and a pending transaction, or an error if the deployment failed. +type DeployFn func(input, deployer []byte) (common.Address, *types.Transaction, error) + +// depTreeDeployer is responsible for taking a dependency, deploying-and-linking +// its components in the proper order. A depTreeDeployer cannot be used after +// calling LinkAndDeploy other than to retrieve the deployment result. +type depTreeDeployer struct { + deployedAddrs map[string]common.Address + deployerTxs map[string]*types.Transaction + inputs map[string][]byte // map of the root contract pattern to the constructor input (if there is any) + deployFn DeployFn +} + +func newDepTreeDeployer(deployParams *DeploymentParams, deployFn DeployFn) *depTreeDeployer { + deployedAddrs := maps.Clone(deployParams.Overrides) + if deployedAddrs == nil { + deployedAddrs = make(map[string]common.Address) + } + inputs := deployParams.Inputs + if inputs == nil { + inputs = make(map[string][]byte) + } + return &depTreeDeployer{ + deployFn: deployFn, + deployedAddrs: deployedAddrs, + deployerTxs: make(map[string]*types.Transaction), + inputs: inputs, + } +} + +// linkAndDeploy deploys a contract and it's dependencies. Because libraries +// can in-turn have their own library dependencies, linkAndDeploy performs +// deployment recursively (deepest-dependency first). The address of the +// pending contract deployment for the top-level contract is returned. +func (d *depTreeDeployer) linkAndDeploy(metadata *MetaData) (common.Address, error) { + // Don't re-deploy aliased or previously-deployed contracts + if addr, ok := d.deployedAddrs[metadata.ID]; ok { + return addr, nil + } + // If this contract/library depends on other libraries deploy them + // (and their dependencies) first + deployerCode := metadata.Bin + for _, dep := range metadata.Deps { + addr, err := d.linkAndDeploy(dep) + if err != nil { + return common.Address{}, err + } + // Link their deployed addresses into the bytecode to produce + deployerCode = strings.ReplaceAll(deployerCode, "__$"+dep.ID+"$__", strings.ToLower(addr.String()[2:])) + } + // Finally, deploy the top-level contract. + code, err := hex.DecodeString(deployerCode[2:]) + if err != nil { + panic(fmt.Sprintf("error decoding contract deployer hex %s:\n%v", deployerCode[2:], err)) + } + addr, tx, err := d.deployFn(d.inputs[metadata.ID], code) + if err != nil { + return common.Address{}, err + } + d.deployedAddrs[metadata.ID] = addr + d.deployerTxs[metadata.ID] = tx + return addr, nil +} + +// result returns a DeploymentResult instance referencing contracts deployed +// and not including any overrides specified for this deployment. +func (d *depTreeDeployer) result() *DeploymentResult { + // filter the override addresses from the deployed address set. + for pattern := range d.deployedAddrs { + if _, ok := d.deployerTxs[pattern]; !ok { + delete(d.deployedAddrs, pattern) + } + } + return &DeploymentResult{ + Txs: d.deployerTxs, + Addresses: d.deployedAddrs, + } +} + +// LinkAndDeploy performs the contract deployment specified by params using the +// provided DeployFn to create, sign and submit transactions. +// +// Contracts can depend on libraries, which in-turn can have their own library +// dependencies. Therefore, LinkAndDeploy performs the deployment recursively, +// starting with libraries (and contracts) that don't have dependencies, and +// progressing through the contracts that depend upon them. +// +// If an error is encountered, the returned DeploymentResult only contains +// entries for the contracts whose deployment submission succeeded. +// +// LinkAndDeploy performs creation and submission of creation transactions, +// but does not ensure that the contracts are included in the chain. +func LinkAndDeploy(params *DeploymentParams, deploy DeployFn) (*DeploymentResult, error) { + if err := params.validate(); err != nil { + return nil, err + } + deployer := newDepTreeDeployer(params, deploy) + for _, contract := range params.Contracts { + if _, err := deployer.linkAndDeploy(contract); err != nil { + return deployer.result(), err + } + } + return deployer.result(), nil +} diff --git a/accounts/abi/bind/v2/dep_tree_test.go b/accounts/abi/bind/v2/dep_tree_test.go new file mode 100644 index 0000000000..e686e3fec4 --- /dev/null +++ b/accounts/abi/bind/v2/dep_tree_test.go @@ -0,0 +1,370 @@ +// 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 bind + +import ( + "fmt" + "regexp" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "golang.org/x/exp/rand" +) + +type linkTestCase struct { + // map of pattern to unlinked bytecode (for the purposes of tests just contains the patterns of its dependencies) + libCodes map[string]string + contractCodes map[string]string + + overrides map[string]common.Address +} + +func copyMetaData(m *MetaData) *MetaData { + m.mu.Lock() + defer m.mu.Unlock() + + var deps []*MetaData + if len(m.Deps) > 0 { + for _, dep := range m.Deps { + deps = append(deps, copyMetaData(dep)) + } + } + return &MetaData{ + Bin: m.Bin, + ABI: m.ABI, + Deps: deps, + ID: m.ID, + parsedABI: m.parsedABI, + } +} + +func makeLinkTestCase(input map[rune][]rune, overrides map[rune]common.Address) *linkTestCase { + codes := make(map[string]string) + libCodes := make(map[string]string) + contractCodes := make(map[string]string) + + inputMap := make(map[rune]map[rune]struct{}) + // set of solidity patterns for all contracts that are known to be libraries + libs := make(map[string]struct{}) + + // map of test contract id (rune) to the solidity library pattern (hash of that rune) + patternMap := map[rune]string{} + + for contract, deps := range input { + inputMap[contract] = make(map[rune]struct{}) + if _, ok := patternMap[contract]; !ok { + patternMap[contract] = crypto.Keccak256Hash([]byte(string(contract))).String()[2:36] + } + + for _, dep := range deps { + if _, ok := patternMap[dep]; !ok { + patternMap[dep] = crypto.Keccak256Hash([]byte(string(dep))).String()[2:36] + } + codes[patternMap[contract]] = codes[patternMap[contract]] + fmt.Sprintf("__$%s$__", patternMap[dep]) + inputMap[contract][dep] = struct{}{} + libs[patternMap[dep]] = struct{}{} + } + } + overridesPatterns := make(map[string]common.Address) + for contractId, overrideAddr := range overrides { + pattern := crypto.Keccak256Hash([]byte(string(contractId))).String()[2:36] + overridesPatterns[pattern] = overrideAddr + } + + for _, pattern := range patternMap { + if _, ok := libs[pattern]; ok { + // if the library didn't depend on others, give it some dummy code to not bork deployment logic down-the-line + if len(codes[pattern]) == 0 { + libCodes[pattern] = "ff" + } else { + libCodes[pattern] = codes[pattern] + } + } else { + contractCodes[pattern] = codes[pattern] + } + } + + return &linkTestCase{ + libCodes, + contractCodes, + overridesPatterns, + } +} + +var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + +type linkTestCaseInput struct { + input map[rune][]rune + overrides map[rune]struct{} + expectDeployed map[rune]struct{} +} + +// linkDeps will return a set of root dependencies and their sub-dependencies connected via the Deps field +func linkDeps(deps map[string]*MetaData) []*MetaData { + roots := make(map[string]struct{}) + for pattern := range deps { + roots[pattern] = struct{}{} + } + + connectedDeps := make(map[string]*MetaData) + for pattern, dep := range deps { + connectedDeps[pattern] = internalLinkDeps(dep, deps, &roots) + } + + var rootMetadatas []*MetaData + for pattern := range roots { + dep := connectedDeps[pattern] + rootMetadatas = append(rootMetadatas, dep) + } + return rootMetadatas +} + +// internalLinkDeps is the internal recursing logic of linkDeps: +// It links the contract referred to by MetaData given the depMap (map of solidity +// link pattern to contract metadata object), deleting contract entries from the +// roots map if they were referenced as dependencies. It returns a new MetaData +// object which is the linked version of metadata parameter. +func internalLinkDeps(metadata *MetaData, depMap map[string]*MetaData, roots *map[string]struct{}) *MetaData { + linked := copyMetaData(metadata) + depPatterns := parseLibraryDeps(metadata.Bin) + for _, pattern := range depPatterns { + delete(*roots, pattern) + connectedDep := internalLinkDeps(depMap[pattern], depMap, roots) + linked.Deps = append(linked.Deps, connectedDep) + } + return linked +} + +func testLinkCase(tcInput linkTestCaseInput) error { + var ( + testAddr = crypto.PubkeyToAddress(testKey.PublicKey) + overridesAddrs = make(map[common.Address]struct{}) + overrideAddrs = make(map[rune]common.Address) + ) + // generate deterministic addresses for the override set. + rand.Seed(42) + for contract := range tcInput.overrides { + var addr common.Address + rand.Read(addr[:]) + overrideAddrs[contract] = addr + overridesAddrs[addr] = struct{}{} + } + + tc := makeLinkTestCase(tcInput.input, overrideAddrs) + allContracts := make(map[rune]struct{}) + + for contract, deps := range tcInput.input { + allContracts[contract] = struct{}{} + for _, dep := range deps { + allContracts[dep] = struct{}{} + } + } + + var testAddrNonce uint64 + mockDeploy := func(input []byte, deployer []byte) (common.Address, *types.Transaction, error) { + contractAddr := crypto.CreateAddress(testAddr, testAddrNonce) + testAddrNonce++ + + if len(deployer) >= 20 { + // assert that this contract only references libs that are known to be deployed or in the override set + for i := 0; i < len(deployer); i += 20 { + var dep common.Address + dep.SetBytes(deployer[i : i+20]) + if _, ok := overridesAddrs[dep]; !ok { + return common.Address{}, nil, fmt.Errorf("reference to dependent contract that has not yet been deployed: %x\n", dep) + } + } + } + overridesAddrs[contractAddr] = struct{}{} + // we don't care about the txs themselves for the sake of the linking tests. so we can return nil for them in the mock deployer + return contractAddr, nil, nil + } + + contracts := make(map[string]*MetaData) + overrides := make(map[string]common.Address) + + for pattern, bin := range tc.contractCodes { + contracts[pattern] = &MetaData{ID: pattern, Bin: "0x" + bin} + } + for pattern, bin := range tc.libCodes { + contracts[pattern] = &MetaData{ + Bin: "0x" + bin, + ID: pattern, + } + } + + contractsList := linkDeps(contracts) + + for pattern, override := range tc.overrides { + overrides[pattern] = override + } + + deployParams := &DeploymentParams{ + Contracts: contractsList, + Overrides: overrides, + } + res, err := LinkAndDeploy(deployParams, mockDeploy) + if err != nil { + return err + } + + if len(res.Txs) != len(tcInput.expectDeployed) { + return fmt.Errorf("got %d deployed contracts. expected %d.\n", len(res.Addresses), len(tcInput.expectDeployed)) + } + for contract := range tcInput.expectDeployed { + pattern := crypto.Keccak256Hash([]byte(string(contract))).String()[2:36] + if _, ok := res.Addresses[pattern]; !ok { + return fmt.Errorf("expected contract %s was not deployed\n", string(contract)) + } + } + return nil +} + +func TestContractLinking(t *testing.T) { + for i, tc := range []linkTestCaseInput{ + // test simple contract without any dependencies or overrides + { + map[rune][]rune{ + 'a': {}}, + map[rune]struct{}{}, + map[rune]struct{}{ + 'a': {}}, + }, + // test deployment of a contract that depends on somes libraries. + { + map[rune][]rune{ + 'a': {'b', 'c', 'd', 'e'}}, + map[rune]struct{}{}, + map[rune]struct{}{ + 'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}}, + }, + // test deployment of a contract that depends on some libraries, + // one of which has its own library dependencies. + { + map[rune][]rune{ + 'a': {'b', 'c', 'd', 'e'}, + 'e': {'f', 'g', 'h', 'i'}}, + map[rune]struct{}{}, + map[rune]struct{}{ + 'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'i': {}}, + }, + // test single contract only without deps + { + map[rune][]rune{ + 'a': {}}, + map[rune]struct{}{}, + map[rune]struct{}{ + 'a': {}, + }, + }, + // test that libraries at different levels of the tree can share deps, + // and that these shared deps will only be deployed once. + { + map[rune][]rune{ + 'a': {'b', 'c', 'd', 'e'}, + 'e': {'f', 'g', 'h', 'i', 'm'}, + 'i': {'j', 'k', 'l', 'm'}}, + map[rune]struct{}{}, + map[rune]struct{}{ + 'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'i': {}, 'j': {}, 'k': {}, 'l': {}, 'm': {}, + }, + }, + // test two contracts can be deployed which don't share deps + linkTestCaseInput{ + map[rune][]rune{ + 'a': {'b', 'c', 'd', 'e'}, + 'f': {'g', 'h', 'i', 'j'}}, + map[rune]struct{}{}, + map[rune]struct{}{ + 'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'i': {}, 'j': {}, + }, + }, + // test two contracts can be deployed which share deps + linkTestCaseInput{ + map[rune][]rune{ + 'a': {'b', 'c', 'd', 'e'}, + 'f': {'g', 'c', 'd', 'h'}}, + map[rune]struct{}{}, + map[rune]struct{}{ + 'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, + }, + }, + // test one contract with overrides for all lib deps + linkTestCaseInput{ + map[rune][]rune{ + 'a': {'b', 'c', 'd', 'e'}}, + map[rune]struct{}{'b': {}, 'c': {}, 'd': {}, 'e': {}}, + map[rune]struct{}{ + 'a': {}}, + }, + // test one contract with overrides for some lib deps + linkTestCaseInput{ + map[rune][]rune{ + 'a': {'b', 'c'}}, + map[rune]struct{}{'b': {}, 'c': {}}, + map[rune]struct{}{ + 'a': {}}, + }, + // test deployment of a contract with overrides + linkTestCaseInput{ + map[rune][]rune{ + 'a': {}}, + map[rune]struct{}{'a': {}}, + map[rune]struct{}{}, + }, + // two contracts ('a' and 'f') share some dependencies. contract 'a' is marked as an override. expect that any of + // its depdencies that aren't shared with 'f' are not deployed. + linkTestCaseInput{map[rune][]rune{ + 'a': {'b', 'c', 'd', 'e'}, + 'f': {'g', 'c', 'd', 'h'}}, + map[rune]struct{}{'a': {}}, + map[rune]struct{}{ + 'f': {}, 'g': {}, 'c': {}, 'd': {}, 'h': {}}, + }, + // test nested libraries that share deps at different levels of the tree... with override. + // same condition as above test: no sub-dependencies of + { + map[rune][]rune{ + 'a': {'b', 'c', 'd', 'e'}, + 'e': {'f', 'g', 'h', 'i', 'm'}, + 'i': {'j', 'k', 'l', 'm'}, + 'l': {'n', 'o', 'p'}}, + map[rune]struct{}{ + 'i': {}, + }, + map[rune]struct{}{ + 'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'm': {}}, + }, + } { + if err := testLinkCase(tc); err != nil { + t.Fatalf("test case %d failed: %v", i, err) + } + } +} + +func parseLibraryDeps(unlinkedCode string) (res []string) { + reMatchSpecificPattern, err := regexp.Compile(`__\$([a-f0-9]+)\$__`) + if err != nil { + panic(err) + } + for _, match := range reMatchSpecificPattern.FindAllStringSubmatch(unlinkedCode, -1) { + res = append(res, match[1]) + } + return res +} diff --git a/accounts/abi/bind/v2/generate_test.go b/accounts/abi/bind/v2/generate_test.go new file mode 100644 index 0000000000..ae35e0b475 --- /dev/null +++ b/accounts/abi/bind/v2/generate_test.go @@ -0,0 +1,102 @@ +// 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 bind_test + +import ( + "encoding/json" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/abigen" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common/compiler" + "github.com/ethereum/go-ethereum/crypto" +) + +// Run go generate to recreate the test bindings. +// +//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen -v2 -combined-json internal/contracts/db/combined-abi.json -type DBStats -pkg db -out internal/contracts/db/bindings.go +//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen -v2 -combined-json internal/contracts/events/combined-abi.json -type C -pkg events -out internal/contracts/events/bindings.go +//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen -v2 -combined-json internal/contracts/nested_libraries/combined-abi.json -type C1 -pkg nested_libraries -out internal/contracts/nested_libraries/bindings.go +//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen -v2 -combined-json internal/contracts/solc_errors/combined-abi.json -type C -pkg solc_errors -out internal/contracts/solc_errors/bindings.go +//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen -v2 -combined-json internal/contracts/uint256arrayreturn/combined-abi.json -type C -pkg uint256arrayreturn -out internal/contracts/uint256arrayreturn/bindings.go + +// TestBindingGeneration tests that re-running generation of bindings does not result in +// mutations to the binding code. +func TestBindingGeneration(t *testing.T) { + matches, _ := filepath.Glob("internal/contracts/*") + var dirs []string + for _, match := range matches { + f, _ := os.Stat(match) + if f.IsDir() { + dirs = append(dirs, f.Name()) + } + } + + for _, dir := range dirs { + var ( + abis []string + bins []string + types []string + libs = make(map[string]string) + ) + basePath := filepath.Join("internal/contracts", dir) + combinedJsonPath := filepath.Join(basePath, "combined-abi.json") + abiBytes, err := os.ReadFile(combinedJsonPath) + if err != nil { + t.Fatalf("error trying to read file %s: %v", combinedJsonPath, err) + } + contracts, err := compiler.ParseCombinedJSON(abiBytes, "", "", "", "") + if err != nil { + t.Fatalf("Failed to read contract information from json output: %v", err) + } + + for name, contract := range contracts { + // fully qualified name is of the form : + nameParts := strings.Split(name, ":") + typeName := nameParts[len(nameParts)-1] + abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse + if err != nil { + utils.Fatalf("Failed to parse ABIs from compiler output: %v", err) + } + abis = append(abis, string(abi)) + bins = append(bins, contract.Code) + types = append(types, typeName) + + // Derive the library placeholder which is a 34 character prefix of the + // hex encoding of the keccak256 hash of the fully qualified library name. + // Note that the fully qualified library name is the path of its source + // file and the library name separated by ":". + libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36] // the first 2 chars are 0x + libs[libPattern] = typeName + } + code, err := abigen.BindV2(types, abis, bins, dir, libs, make(map[string]string)) + if err != nil { + t.Fatalf("error creating bindings for package %s: %v", dir, err) + } + + existingBindings, err := os.ReadFile(filepath.Join(basePath, "bindings.go")) + if err != nil { + t.Fatalf("ReadFile returned error: %v", err) + } + if code != string(existingBindings) { + t.Fatalf("code mismatch for %s", dir) + } + } +} diff --git a/accounts/abi/bind/v2/internal/contracts/db/bindings.go b/accounts/abi/bind/v2/internal/contracts/db/bindings.go new file mode 100644 index 0000000000..6291160fe9 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/db/bindings.go @@ -0,0 +1,293 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package db + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// DBStats is an auto generated low-level Go binding around an user-defined struct. +type DBStats struct { + Gets *big.Int + Inserts *big.Int + Mods *big.Int +} + +// DBMetaData contains all meta data concerning the DB contract. +var DBMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"key\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"Insert\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"key\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"KeyedInsert\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"k\",\"type\":\"uint256\"}],\"name\":\"get\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNamedStatParams\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"inserts\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mods\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStatParams\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStatsStruct\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"inserts\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mods\",\"type\":\"uint256\"}],\"internalType\":\"structDB.Stats\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"k\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"v\",\"type\":\"uint256\"}],\"name\":\"insert\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ID: "253cc2574e2f8b5e909644530e4934f6ac", + Bin: "0x60806040525f5f553480156011575f5ffd5b5060405180606001604052805f81526020015f81526020015f81525060035f820151815f015560208201518160010155604082015181600201559050506105f78061005b5f395ff3fe60806040526004361061004d575f3560e01c80631d834a1b146100cb5780636fcb9c70146101075780639507d39a14610133578063e369ba3b1461016f578063ee8161e01461019b5761006a565b3661006a57345f5f82825461006291906103eb565b925050819055005b348015610075575f5ffd5b505f36606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050509050915050805190602001f35b3480156100d6575f5ffd5b506100f160048036038101906100ec919061044c565b6101c5565b6040516100fe9190610499565b60405180910390f35b348015610112575f5ffd5b5061011b6102ef565b60405161012a939291906104b2565b60405180910390f35b34801561013e575f5ffd5b50610159600480360381019061015491906104e7565b61030e565b6040516101669190610499565b60405180910390f35b34801561017a575f5ffd5b50610183610341565b604051610192939291906104b2565b60405180910390f35b3480156101a6575f5ffd5b506101af610360565b6040516101bc9190610561565b60405180910390f35b5f5f82036101da5760028054905090506102e9565b5f60015f8581526020019081526020015f20540361023757600283908060018154018082558091505060019003905f5260205f20015f909190919091505560036001015f81548092919061022d9061057a565b9190505550610252565b60036002015f81548092919061024c9061057a565b91905055505b8160015f8581526020019081526020015f20819055507f8b39ff47dca36ab5b8b80845238af53aa579625ac7fb173dc09376adada4176983836002805490506040516102a0939291906104b2565b60405180910390a1827f40bed843c6c5f72002f9b469cf4c1ee9f7fb1eb48f091c1267970f98522ac02d836040516102d89190610499565b60405180910390a260028054905090505b92915050565b5f5f5f60035f0154600360010154600360020154925092509250909192565b5f60035f015f8154809291906103239061057a565b919050555060015f8381526020019081526020015f20549050919050565b5f5f5f60035f0154600360010154600360020154925092509250909192565b610368610397565b60036040518060600160405290815f820154815260200160018201548152602001600282015481525050905090565b60405180606001604052805f81526020015f81526020015f81525090565b5f819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6103f5826103b5565b9150610400836103b5565b9250828201905080821115610418576104176103be565b5b92915050565b5f5ffd5b61042b816103b5565b8114610435575f5ffd5b50565b5f8135905061044681610422565b92915050565b5f5f604083850312156104625761046161041e565b5b5f61046f85828601610438565b925050602061048085828601610438565b9150509250929050565b610493816103b5565b82525050565b5f6020820190506104ac5f83018461048a565b92915050565b5f6060820190506104c55f83018661048a565b6104d2602083018561048a565b6104df604083018461048a565b949350505050565b5f602082840312156104fc576104fb61041e565b5b5f61050984828501610438565b91505092915050565b61051b816103b5565b82525050565b606082015f8201516105355f850182610512565b5060208201516105486020850182610512565b50604082015161055b6040850182610512565b50505050565b5f6060820190506105745f830184610521565b92915050565b5f610584826103b5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036105b6576105b56103be565b5b60018201905091905056fea264697066735822122063e58431f2afdc667f8e687d3e6a99085a93c1fd3ce40b218463b8ddd3cc093664736f6c634300081c0033", +} + +// DB is an auto generated Go binding around an Ethereum contract. +type DB struct { + abi abi.ABI +} + +// NewDB creates a new instance of DB. +func NewDB() *DB { + parsed, err := DBMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &DB{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *DB) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackGet is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9507d39a. +// +// Solidity: function get(uint256 k) returns(uint256) +func (dB *DB) PackGet(k *big.Int) []byte { + enc, err := dB.abi.Pack("get", k) + if err != nil { + panic(err) + } + return enc +} + +// UnpackGet is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x9507d39a. +// +// Solidity: function get(uint256 k) returns(uint256) +func (dB *DB) UnpackGet(data []byte) (*big.Int, error) { + out, err := dB.abi.Unpack("get", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// PackGetNamedStatParams is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xe369ba3b. +// +// Solidity: function getNamedStatParams() view returns(uint256 gets, uint256 inserts, uint256 mods) +func (dB *DB) PackGetNamedStatParams() []byte { + enc, err := dB.abi.Pack("getNamedStatParams") + if err != nil { + panic(err) + } + return enc +} + +// GetNamedStatParamsOutput serves as a container for the return parameters of contract +// method GetNamedStatParams. +type GetNamedStatParamsOutput struct { + Gets *big.Int + Inserts *big.Int + Mods *big.Int +} + +// UnpackGetNamedStatParams is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xe369ba3b. +// +// Solidity: function getNamedStatParams() view returns(uint256 gets, uint256 inserts, uint256 mods) +func (dB *DB) UnpackGetNamedStatParams(data []byte) (GetNamedStatParamsOutput, error) { + out, err := dB.abi.Unpack("getNamedStatParams", data) + outstruct := new(GetNamedStatParamsOutput) + if err != nil { + return *outstruct, err + } + outstruct.Gets = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.Inserts = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + outstruct.Mods = abi.ConvertType(out[2], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackGetStatParams is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x6fcb9c70. +// +// Solidity: function getStatParams() view returns(uint256, uint256, uint256) +func (dB *DB) PackGetStatParams() []byte { + enc, err := dB.abi.Pack("getStatParams") + if err != nil { + panic(err) + } + return enc +} + +// GetStatParamsOutput serves as a container for the return parameters of contract +// method GetStatParams. +type GetStatParamsOutput struct { + Arg0 *big.Int + Arg1 *big.Int + Arg2 *big.Int +} + +// UnpackGetStatParams is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x6fcb9c70. +// +// Solidity: function getStatParams() view returns(uint256, uint256, uint256) +func (dB *DB) UnpackGetStatParams(data []byte) (GetStatParamsOutput, error) { + out, err := dB.abi.Unpack("getStatParams", data) + outstruct := new(GetStatParamsOutput) + if err != nil { + return *outstruct, err + } + outstruct.Arg0 = abi.ConvertType(out[0], new(big.Int)).(*big.Int) + outstruct.Arg1 = abi.ConvertType(out[1], new(big.Int)).(*big.Int) + outstruct.Arg2 = abi.ConvertType(out[2], new(big.Int)).(*big.Int) + return *outstruct, err + +} + +// PackGetStatsStruct is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xee8161e0. +// +// Solidity: function getStatsStruct() view returns((uint256,uint256,uint256)) +func (dB *DB) PackGetStatsStruct() []byte { + enc, err := dB.abi.Pack("getStatsStruct") + if err != nil { + panic(err) + } + return enc +} + +// UnpackGetStatsStruct is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xee8161e0. +// +// Solidity: function getStatsStruct() view returns((uint256,uint256,uint256)) +func (dB *DB) UnpackGetStatsStruct(data []byte) (DBStats, error) { + out, err := dB.abi.Unpack("getStatsStruct", data) + if err != nil { + return *new(DBStats), err + } + out0 := *abi.ConvertType(out[0], new(DBStats)).(*DBStats) + return out0, err +} + +// PackInsert is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x1d834a1b. +// +// Solidity: function insert(uint256 k, uint256 v) returns(uint256) +func (dB *DB) PackInsert(k *big.Int, v *big.Int) []byte { + enc, err := dB.abi.Pack("insert", k, v) + if err != nil { + panic(err) + } + return enc +} + +// UnpackInsert is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x1d834a1b. +// +// Solidity: function insert(uint256 k, uint256 v) returns(uint256) +func (dB *DB) UnpackInsert(data []byte) (*big.Int, error) { + out, err := dB.abi.Unpack("insert", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// DBInsert represents a Insert event raised by the DB contract. +type DBInsert struct { + Key *big.Int + Value *big.Int + Length *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const DBInsertEventName = "Insert" + +// ContractEventName returns the user-defined event name. +func (DBInsert) ContractEventName() string { + return DBInsertEventName +} + +// UnpackInsertEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event Insert(uint256 key, uint256 value, uint256 length) +func (dB *DB) UnpackInsertEvent(log *types.Log) (*DBInsert, error) { + event := "Insert" + if log.Topics[0] != dB.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(DBInsert) + if len(log.Data) > 0 { + if err := dB.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range dB.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// DBKeyedInsert represents a KeyedInsert event raised by the DB contract. +type DBKeyedInsert struct { + Key *big.Int + Value *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const DBKeyedInsertEventName = "KeyedInsert" + +// ContractEventName returns the user-defined event name. +func (DBKeyedInsert) ContractEventName() string { + return DBKeyedInsertEventName +} + +// UnpackKeyedInsertEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event KeyedInsert(uint256 indexed key, uint256 value) +func (dB *DB) UnpackKeyedInsertEvent(log *types.Log) (*DBKeyedInsert, error) { + event := "KeyedInsert" + if log.Topics[0] != dB.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(DBKeyedInsert) + if len(log.Data) > 0 { + if err := dB.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range dB.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/bind/v2/internal/contracts/db/combined-abi.json b/accounts/abi/bind/v2/internal/contracts/db/combined-abi.json new file mode 100644 index 0000000000..38a67f745a --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/db/combined-abi.json @@ -0,0 +1 @@ +{"contracts":{"contract.sol:DB":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"key","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"length","type":"uint256"}],"name":"Insert","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"key","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"KeyedInsert","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"k","type":"uint256"}],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getNamedStatParams","outputs":[{"internalType":"uint256","name":"gets","type":"uint256"},{"internalType":"uint256","name":"inserts","type":"uint256"},{"internalType":"uint256","name":"mods","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStatParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStatsStruct","outputs":[{"components":[{"internalType":"uint256","name":"gets","type":"uint256"},{"internalType":"uint256","name":"inserts","type":"uint256"},{"internalType":"uint256","name":"mods","type":"uint256"}],"internalType":"struct DB.Stats","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"k","type":"uint256"},{"internalType":"uint256","name":"v","type":"uint256"}],"name":"insert","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}],"bin":"60806040525f5f553480156011575f5ffd5b5060405180606001604052805f81526020015f81526020015f81525060035f820151815f015560208201518160010155604082015181600201559050506105f78061005b5f395ff3fe60806040526004361061004d575f3560e01c80631d834a1b146100cb5780636fcb9c70146101075780639507d39a14610133578063e369ba3b1461016f578063ee8161e01461019b5761006a565b3661006a57345f5f82825461006291906103eb565b925050819055005b348015610075575f5ffd5b505f36606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050509050915050805190602001f35b3480156100d6575f5ffd5b506100f160048036038101906100ec919061044c565b6101c5565b6040516100fe9190610499565b60405180910390f35b348015610112575f5ffd5b5061011b6102ef565b60405161012a939291906104b2565b60405180910390f35b34801561013e575f5ffd5b50610159600480360381019061015491906104e7565b61030e565b6040516101669190610499565b60405180910390f35b34801561017a575f5ffd5b50610183610341565b604051610192939291906104b2565b60405180910390f35b3480156101a6575f5ffd5b506101af610360565b6040516101bc9190610561565b60405180910390f35b5f5f82036101da5760028054905090506102e9565b5f60015f8581526020019081526020015f20540361023757600283908060018154018082558091505060019003905f5260205f20015f909190919091505560036001015f81548092919061022d9061057a565b9190505550610252565b60036002015f81548092919061024c9061057a565b91905055505b8160015f8581526020019081526020015f20819055507f8b39ff47dca36ab5b8b80845238af53aa579625ac7fb173dc09376adada4176983836002805490506040516102a0939291906104b2565b60405180910390a1827f40bed843c6c5f72002f9b469cf4c1ee9f7fb1eb48f091c1267970f98522ac02d836040516102d89190610499565b60405180910390a260028054905090505b92915050565b5f5f5f60035f0154600360010154600360020154925092509250909192565b5f60035f015f8154809291906103239061057a565b919050555060015f8381526020019081526020015f20549050919050565b5f5f5f60035f0154600360010154600360020154925092509250909192565b610368610397565b60036040518060600160405290815f820154815260200160018201548152602001600282015481525050905090565b60405180606001604052805f81526020015f81526020015f81525090565b5f819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6103f5826103b5565b9150610400836103b5565b9250828201905080821115610418576104176103be565b5b92915050565b5f5ffd5b61042b816103b5565b8114610435575f5ffd5b50565b5f8135905061044681610422565b92915050565b5f5f604083850312156104625761046161041e565b5b5f61046f85828601610438565b925050602061048085828601610438565b9150509250929050565b610493816103b5565b82525050565b5f6020820190506104ac5f83018461048a565b92915050565b5f6060820190506104c55f83018661048a565b6104d2602083018561048a565b6104df604083018461048a565b949350505050565b5f602082840312156104fc576104fb61041e565b5b5f61050984828501610438565b91505092915050565b61051b816103b5565b82525050565b606082015f8201516105355f850182610512565b5060208201516105486020850182610512565b50604082015161055b6040850182610512565b50505050565b5f6060820190506105745f830184610521565b92915050565b5f610584826103b5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036105b6576105b56103be565b5b60018201905091905056fea264697066735822122063e58431f2afdc667f8e687d3e6a99085a93c1fd3ce40b218463b8ddd3cc093664736f6c634300081c0033"}},"version":"0.8.28+commit.7893614a.Darwin.appleclang"} diff --git a/accounts/abi/bind/v2/internal/contracts/db/contract.sol b/accounts/abi/bind/v2/internal/contracts/db/contract.sol new file mode 100644 index 0000000000..f24aa8d381 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/db/contract.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract DB { + uint balance = 0; + mapping(uint => uint) private _store; + uint[] private _keys; + struct Stats { + uint gets; + uint inserts; + uint mods; // modifications + } + Stats _stats; + + event KeyedInsert(uint indexed key, uint value); + event Insert(uint key, uint value, uint length); + + constructor() { + _stats = Stats(0, 0, 0); + } + + // insert adds a key value to the store, returning the new length of the store. + function insert(uint k, uint v) external returns (uint) { + // No need to store 0 values + if (v == 0) { + return _keys.length; + } + // Check if a key is being overriden + if (_store[k] == 0) { + _keys.push(k); + _stats.inserts++; + } else { + _stats.mods++; + } + _store[k] = v; + emit Insert(k, v, _keys.length); + emit KeyedInsert(k, v); + + return _keys.length; + } + + function get(uint k) public returns (uint) { + _stats.gets++; + return _store[k]; + } + + function getStatParams() public view returns (uint, uint, uint) { + return (_stats.gets, _stats.inserts, _stats.mods); + } + + function getNamedStatParams() public view returns (uint gets, uint inserts, uint mods) { + return (_stats.gets, _stats.inserts, _stats.mods); + } + + function getStatsStruct() public view returns (Stats memory) { + return _stats; + } + + receive() external payable { + balance += msg.value; + } + + fallback(bytes calldata _input) external returns (bytes memory _output) { + _output = _input; + } +} \ No newline at end of file diff --git a/accounts/abi/bind/v2/internal/contracts/events/bindings.go b/accounts/abi/bind/v2/internal/contracts/events/bindings.go new file mode 100644 index 0000000000..580bffa23e --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/events/bindings.go @@ -0,0 +1,160 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package events + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// CMetaData contains all meta data concerning the C contract. +var CMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"data\",\"type\":\"uint256\"}],\"name\":\"basic1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"flag\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"data\",\"type\":\"uint256\"}],\"name\":\"basic2\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"EmitMulti\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"EmitOne\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ID: "55ef3c19a0ab1c1845f9e347540c1e51f5", + Bin: "0x6080604052348015600e575f5ffd5b506101a08061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c8063cb49374914610038578063e8e49a7114610042575b5f5ffd5b61004061004c565b005b61004a6100fd565b005b60017f8f17dc823e2f9fcdf730b8182c935574691e811e7d46399fe0ff0087795cd207600260405161007e9190610151565b60405180910390a260037f8f17dc823e2f9fcdf730b8182c935574691e811e7d46399fe0ff0087795cd20760046040516100b89190610151565b60405180910390a25f15157f3b29b9f6d15ba80d866afb3d70b7548ab1ffda3ef6e65f35f1cb05b0e2b29f4e60016040516100f39190610151565b60405180910390a2565b60017f8f17dc823e2f9fcdf730b8182c935574691e811e7d46399fe0ff0087795cd207600260405161012f9190610151565b60405180910390a2565b5f819050919050565b61014b81610139565b82525050565b5f6020820190506101645f830184610142565b9291505056fea26469706673582212207331c79de16a73a1639c4c4b3489ea78a3ed35fe62a178824f586df12672ac0564736f6c634300081c0033", +} + +// C is an auto generated Go binding around an Ethereum contract. +type C struct { + abi abi.ABI +} + +// NewC creates a new instance of C. +func NewC() *C { + parsed, err := CMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &C{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *C) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackEmitMulti is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xcb493749. +// +// Solidity: function EmitMulti() returns() +func (c *C) PackEmitMulti() []byte { + enc, err := c.abi.Pack("EmitMulti") + if err != nil { + panic(err) + } + return enc +} + +// PackEmitOne is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xe8e49a71. +// +// Solidity: function EmitOne() returns() +func (c *C) PackEmitOne() []byte { + enc, err := c.abi.Pack("EmitOne") + if err != nil { + panic(err) + } + return enc +} + +// CBasic1 represents a basic1 event raised by the C contract. +type CBasic1 struct { + Id *big.Int + Data *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const CBasic1EventName = "basic1" + +// ContractEventName returns the user-defined event name. +func (CBasic1) ContractEventName() string { + return CBasic1EventName +} + +// UnpackBasic1Event is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event basic1(uint256 indexed id, uint256 data) +func (c *C) UnpackBasic1Event(log *types.Log) (*CBasic1, error) { + event := "basic1" + if log.Topics[0] != c.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(CBasic1) + if len(log.Data) > 0 { + if err := c.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range c.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// CBasic2 represents a basic2 event raised by the C contract. +type CBasic2 struct { + Flag bool + Data *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const CBasic2EventName = "basic2" + +// ContractEventName returns the user-defined event name. +func (CBasic2) ContractEventName() string { + return CBasic2EventName +} + +// UnpackBasic2Event is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event basic2(bool indexed flag, uint256 data) +func (c *C) UnpackBasic2Event(log *types.Log) (*CBasic2, error) { + event := "basic2" + if log.Topics[0] != c.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(CBasic2) + if len(log.Data) > 0 { + if err := c.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range c.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} diff --git a/accounts/abi/bind/v2/internal/contracts/events/combined-abi.json b/accounts/abi/bind/v2/internal/contracts/events/combined-abi.json new file mode 100644 index 0000000000..bd6b7c3a60 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/events/combined-abi.json @@ -0,0 +1 @@ +{"contracts":{"contract.sol:C":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"basic1","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"flag","type":"bool"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"basic2","type":"event"},{"inputs":[],"name":"EmitMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"EmitOne","outputs":[],"stateMutability":"nonpayable","type":"function"}],"bin":"6080604052348015600e575f5ffd5b506101a08061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c8063cb49374914610038578063e8e49a7114610042575b5f5ffd5b61004061004c565b005b61004a6100fd565b005b60017f8f17dc823e2f9fcdf730b8182c935574691e811e7d46399fe0ff0087795cd207600260405161007e9190610151565b60405180910390a260037f8f17dc823e2f9fcdf730b8182c935574691e811e7d46399fe0ff0087795cd20760046040516100b89190610151565b60405180910390a25f15157f3b29b9f6d15ba80d866afb3d70b7548ab1ffda3ef6e65f35f1cb05b0e2b29f4e60016040516100f39190610151565b60405180910390a2565b60017f8f17dc823e2f9fcdf730b8182c935574691e811e7d46399fe0ff0087795cd207600260405161012f9190610151565b60405180910390a2565b5f819050919050565b61014b81610139565b82525050565b5f6020820190506101645f830184610142565b9291505056fea26469706673582212207331c79de16a73a1639c4c4b3489ea78a3ed35fe62a178824f586df12672ac0564736f6c634300081c0033"}},"version":"0.8.28+commit.7893614a.Darwin.appleclang"} diff --git a/accounts/abi/bind/v2/internal/contracts/events/contract.sol b/accounts/abi/bind/v2/internal/contracts/events/contract.sol new file mode 100644 index 0000000000..a30b38a9d4 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/events/contract.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + +contract C { + event basic1( + uint256 indexed id, + uint256 data + ); + event basic2( + bool indexed flag, + uint256 data + ); + + function EmitOne() public { + emit basic1( + uint256(1), + uint256(2)); + } + + // emit multiple events, different types + function EmitMulti() public { + emit basic1( + uint256(1), + uint256(2)); + emit basic1( + uint256(3), + uint256(4)); + emit basic2( + false, + uint256(1)); + } + + constructor() { + // do something with these + } +} \ No newline at end of file diff --git a/accounts/abi/bind/v2/internal/contracts/nested_libraries/abi.json b/accounts/abi/bind/v2/internal/contracts/nested_libraries/abi.json new file mode 100644 index 0000000000..7cfcdaa93a --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/nested_libraries/abi.json @@ -0,0 +1 @@ +{"contracts":{"contract.sol:Array":{"abi":[],"bin":"61044261004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063677ca2d814610038575b5f80fd5b818015610043575f80fd5b5061005e60048036038101906100599190610235565b610060565b005b5f8280549050116100a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161009d906102cd565b60405180910390fd5b81600183805490506100b89190610318565b815481106100c9576100c861034b565b5b905f5260205f2001548282815481106100e5576100e461034b565b5b905f5260205f2001819055508181815481106101045761010361034b565b5b905f5260205f20015473__$e0273646c631009d12385ab5282af2d432$__63ee05608590916040518263ffffffff1660e01b81526004016101459190610387565b602060405180830381865af4158015610160573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061018491906103b4565b8282815481106101975761019661034b565b5b905f5260205f200181905550818054806101b4576101b36103df565b5b600190038181905f5260205f20015f905590555050565b5f80fd5b5f819050919050565b6101e1816101cf565b81146101eb575f80fd5b50565b5f813590506101fc816101d8565b92915050565b5f819050919050565b61021481610202565b811461021e575f80fd5b50565b5f8135905061022f8161020b565b92915050565b5f806040838503121561024b5761024a6101cb565b5b5f610258858286016101ee565b925050602061026985828601610221565b9150509250929050565b5f82825260208201905092915050565b7f43616e27742072656d6f76652066726f6d20656d7074792061727261790000005f82015250565b5f6102b7601d83610273565b91506102c282610283565b602082019050919050565b5f6020820190508181035f8301526102e4816102ab565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61032282610202565b915061032d83610202565b9250828203905081811115610345576103446102eb565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b61038181610202565b82525050565b5f60208201905061039a5f830184610378565b92915050565b5f815190506103ae8161020b565b92915050565b5f602082840312156103c9576103c86101cb565b5b5f6103d6848285016103a0565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea26469706673582212200680afb351728e7eaa7168f68e59cd7151eff98288314447ad7638a444ed11de64736f6c634300081a0033"},"contract.sol:RecursiveDep":{"abi":[{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"AddOne","outputs":[{"internalType":"uint256","name":"ret","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"61019d61004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063ee05608514610038575b5f80fd5b610052600480360381019061004d91906100b4565b610068565b60405161005f91906100ee565b60405180910390f35b5f6001826100769190610134565b9050919050565b5f80fd5b5f819050919050565b61009381610081565b811461009d575f80fd5b50565b5f813590506100ae8161008a565b92915050565b5f602082840312156100c9576100c861007d565b5b5f6100d6848285016100a0565b91505092915050565b6100e881610081565b82525050565b5f6020820190506101015f8301846100df565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61013e82610081565b915061014983610081565b925082820190508082111561016157610160610107565b5b9291505056fea2646970667358221220d392325a1e387a65c76bff6fecec456650b48856b1e00afc4fa76fb9181da23c64736f6c634300081a0033"},"contract.sol:TestArray":{"abi":[{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"arr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"testArrayRemove","outputs":[],"stateMutability":"nonpayable","type":"function"}],"bin":"6080604052348015600e575f80fd5b506103438061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c806371e5ee5f14610038578063807fc49a14610068575b5f80fd5b610052600480360381019061004d91906101f0565b610084565b60405161005f919061022a565b60405180910390f35b610082600480360381019061007d91906101f0565b6100a3565b005b5f8181548110610092575f80fd5b905f5260205f20015f915090505481565b5f5b60038110156100e0575f81908060018154018082558091505060019003905f5260205f20015f909190919091505580806001019150506100a5565b505f73__$37f5055d0d00ca8ab20a50453e6986094c$__63677ca2d8909160016040518363ffffffff1660e01b815260040161011d92919061028c565b5f6040518083038186803b158015610133575f80fd5b505af4158015610145573d5f803e3d5ffd5b5050505060025f805490501461015e5761015d6102b3565b5b5f805f81548110610172576101716102e0565b5b905f5260205f20015414610189576101886102b3565b5b60025f60018154811061019f5761019e6102e0565b5b905f5260205f200154146101b6576101b56102b3565b5b50565b5f80fd5b5f819050919050565b6101cf816101bd565b81146101d9575f80fd5b50565b5f813590506101ea816101c6565b92915050565b5f60208284031215610205576102046101b9565b5b5f610212848285016101dc565b91505092915050565b610224816101bd565b82525050565b5f60208201905061023d5f83018461021b565b92915050565b8082525050565b5f819050919050565b5f819050919050565b5f61027661027161026c8461024a565b610253565b6101bd565b9050919050565b6102868161025c565b82525050565b5f60408201905061029f5f830185610243565b6102ac602083018461027d565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffdfea26469706673582212204be2c6230af664b290f016e88cfac62bf7c08823b1fd1bcce8bdcd7fbb785b8a64736f6c634300081a0033"}},"version":"0.8.26+commit.8a97fa7a.Darwin.appleclang"} diff --git a/accounts/abi/bind/v2/internal/contracts/nested_libraries/bindings.go b/accounts/abi/bind/v2/internal/contracts/nested_libraries/bindings.go new file mode 100644 index 0000000000..6fd6a1b285 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/nested_libraries/bindings.go @@ -0,0 +1,486 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nested_libraries + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// C1MetaData contains all meta data concerning the C1 contract. +var C1MetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"v1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"v2\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"Do\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"res\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "ae26158f1824f3918bd66724ee8b6eb7c9", + Bin: "0x6080604052348015600e575f5ffd5b506040516103983803806103988339818101604052810190602e91906066565b5050609d565b5f5ffd5b5f819050919050565b6048816038565b81146051575f5ffd5b50565b5f815190506060816041565b92915050565b5f5f6040838503121560795760786034565b5b5f6084858286016054565b92505060206093858286016054565b9150509250929050565b6102ee806100aa5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c80632ad112721461002d575b5f5ffd5b6100476004803603810190610042919061019e565b61005d565b60405161005491906101d8565b60405180910390f35b5f600173__$ffc1393672b8ed81d0c8093ffcb0e7fbe8$__632ad112725f6040518263ffffffff1660e01b81526004016100979190610200565b602060405180830381865af41580156100b2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100d6919061022d565b73__$5f33a1fab8ea7d932b4bc8c5e7dcd90bc2$__632ad11272856040518263ffffffff1660e01b815260040161010d9190610200565b602060405180830381865af4158015610128573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061014c919061022d565b6101569190610285565b6101609190610285565b9050919050565b5f5ffd5b5f819050919050565b61017d8161016b565b8114610187575f5ffd5b50565b5f8135905061019881610174565b92915050565b5f602082840312156101b3576101b2610167565b5b5f6101c08482850161018a565b91505092915050565b6101d28161016b565b82525050565b5f6020820190506101eb5f8301846101c9565b92915050565b6101fa8161016b565b82525050565b5f6020820190506102135f8301846101f1565b92915050565b5f8151905061022781610174565b92915050565b5f6020828403121561024257610241610167565b5b5f61024f84828501610219565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61028f8261016b565b915061029a8361016b565b92508282019050808211156102b2576102b1610258565b5b9291505056fea26469706673582212205d4715a8d20a3a0a43113e268ec8868b3c3ce24f7cbdb8735b4eeeebf0b5565164736f6c634300081c0033", + Deps: []*bind.MetaData{ + &L1MetaData, + &L4MetaData, + }, +} + +// C1 is an auto generated Go binding around an Ethereum contract. +type C1 struct { + abi abi.ABI +} + +// NewC1 creates a new instance of C1. +func NewC1() *C1 { + parsed, err := C1MetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &C1{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *C1) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackConstructor is the Go binding used to pack the parameters required for +// contract deployment. +// +// Solidity: constructor(uint256 v1, uint256 v2) returns() +func (c1 *C1) PackConstructor(v1 *big.Int, v2 *big.Int) []byte { + enc, err := c1.abi.Pack("", v1, v2) + if err != nil { + panic(err) + } + return enc +} + +// PackDo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256 res) +func (c1 *C1) PackDo(val *big.Int) []byte { + enc, err := c1.abi.Pack("Do", val) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDo is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256 res) +func (c1 *C1) UnpackDo(data []byte) (*big.Int, error) { + out, err := c1.abi.Unpack("Do", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// C2MetaData contains all meta data concerning the C2 contract. +var C2MetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"v1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"v2\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"Do\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"res\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "78ef2840de5b706112ca2dbfa765501a89", + Bin: "0x6080604052348015600e575f5ffd5b506040516103983803806103988339818101604052810190602e91906066565b5050609d565b5f5ffd5b5f819050919050565b6048816038565b81146051575f5ffd5b50565b5f815190506060816041565b92915050565b5f5f6040838503121560795760786034565b5b5f6084858286016054565b92505060206093858286016054565b9150509250929050565b6102ee806100aa5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c80632ad112721461002d575b5f5ffd5b6100476004803603810190610042919061019e565b61005d565b60405161005491906101d8565b60405180910390f35b5f600173__$ffc1393672b8ed81d0c8093ffcb0e7fbe8$__632ad112725f6040518263ffffffff1660e01b81526004016100979190610200565b602060405180830381865af41580156100b2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100d6919061022d565b73__$6070639404c39b5667691bb1f9177e1eac$__632ad11272856040518263ffffffff1660e01b815260040161010d9190610200565b602060405180830381865af4158015610128573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061014c919061022d565b6101569190610285565b6101609190610285565b9050919050565b5f5ffd5b5f819050919050565b61017d8161016b565b8114610187575f5ffd5b50565b5f8135905061019881610174565b92915050565b5f602082840312156101b3576101b2610167565b5b5f6101c08482850161018a565b91505092915050565b6101d28161016b565b82525050565b5f6020820190506101eb5f8301846101c9565b92915050565b6101fa8161016b565b82525050565b5f6020820190506102135f8301846101f1565b92915050565b5f8151905061022781610174565b92915050565b5f6020828403121561024257610241610167565b5b5f61024f84828501610219565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61028f8261016b565b915061029a8361016b565b92508282019050808211156102b2576102b1610258565b5b9291505056fea2646970667358221220dd394981f1e9fefa4d88bac1c4f1da4131779c7d3bd4189958d278e57e96d96f64736f6c634300081c0033", + Deps: []*bind.MetaData{ + &L1MetaData, + &L4bMetaData, + }, +} + +// C2 is an auto generated Go binding around an Ethereum contract. +type C2 struct { + abi abi.ABI +} + +// NewC2 creates a new instance of C2. +func NewC2() *C2 { + parsed, err := C2MetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &C2{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *C2) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackConstructor is the Go binding used to pack the parameters required for +// contract deployment. +// +// Solidity: constructor(uint256 v1, uint256 v2) returns() +func (c2 *C2) PackConstructor(v1 *big.Int, v2 *big.Int) []byte { + enc, err := c2.abi.Pack("", v1, v2) + if err != nil { + panic(err) + } + return enc +} + +// PackDo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256 res) +func (c2 *C2) PackDo(val *big.Int) []byte { + enc, err := c2.abi.Pack("Do", val) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDo is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256 res) +func (c2 *C2) UnpackDo(data []byte) (*big.Int, error) { + out, err := c2.abi.Unpack("Do", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// L1MetaData contains all meta data concerning the L1 contract. +var L1MetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"Do\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "ffc1393672b8ed81d0c8093ffcb0e7fbe8", + Bin: "0x61011c61004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106032575f3560e01c80632ad11272146036575b5f5ffd5b604c600480360381019060489190609c565b6060565b6040516057919060cf565b60405180910390f35b5f60019050919050565b5f5ffd5b5f819050919050565b607e81606e565b81146087575f5ffd5b50565b5f813590506096816077565b92915050565b5f6020828403121560ae5760ad606a565b5b5f60b984828501608a565b91505092915050565b60c981606e565b82525050565b5f60208201905060e05f83018460c2565b9291505056fea26469706673582212200161c5f22d130a2b7ec6cf22e0910e42e32c2881fa4a8a01455f524f63cf218d64736f6c634300081c0033", +} + +// L1 is an auto generated Go binding around an Ethereum contract. +type L1 struct { + abi abi.ABI +} + +// NewL1 creates a new instance of L1. +func NewL1() *L1 { + parsed, err := L1MetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &L1{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *L1) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackDo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l1 *L1) PackDo(val *big.Int) []byte { + enc, err := l1.abi.Pack("Do", val) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDo is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l1 *L1) UnpackDo(data []byte) (*big.Int, error) { + out, err := l1.abi.Unpack("Do", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// L2MetaData contains all meta data concerning the L2 contract. +var L2MetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"Do\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "2ce896a6dd38932d354f317286f90bc675", + Bin: "0x61025161004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c80632ad1127214610038575b5f5ffd5b610052600480360381019061004d9190610129565b610068565b60405161005f9190610163565b60405180910390f35b5f600173__$ffc1393672b8ed81d0c8093ffcb0e7fbe8$__632ad11272846040518263ffffffff1660e01b81526004016100a29190610163565b602060405180830381865af41580156100bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e19190610190565b6100eb91906101e8565b9050919050565b5f5ffd5b5f819050919050565b610108816100f6565b8114610112575f5ffd5b50565b5f81359050610123816100ff565b92915050565b5f6020828403121561013e5761013d6100f2565b5b5f61014b84828501610115565b91505092915050565b61015d816100f6565b82525050565b5f6020820190506101765f830184610154565b92915050565b5f8151905061018a816100ff565b92915050565b5f602082840312156101a5576101a46100f2565b5b5f6101b28482850161017c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6101f2826100f6565b91506101fd836100f6565b9250828201905080821115610215576102146101bb565b5b9291505056fea264697066735822122026999f96e14b0e279909ca5972343113c358e93a904569409a86866e2064f0fa64736f6c634300081c0033", + Deps: []*bind.MetaData{ + &L1MetaData, + }, +} + +// L2 is an auto generated Go binding around an Ethereum contract. +type L2 struct { + abi abi.ABI +} + +// NewL2 creates a new instance of L2. +func NewL2() *L2 { + parsed, err := L2MetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &L2{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *L2) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackDo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l2 *L2) PackDo(val *big.Int) []byte { + enc, err := l2.abi.Pack("Do", val) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDo is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l2 *L2) UnpackDo(data []byte) (*big.Int, error) { + out, err := l2.abi.Unpack("Do", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// L2bMetaData contains all meta data concerning the L2b contract. +var L2bMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"Do\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "fd1474cf57f7ed48491e8bfdfd0d172adf", + Bin: "0x61025161004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c80632ad1127214610038575b5f5ffd5b610052600480360381019061004d9190610129565b610068565b60405161005f9190610163565b60405180910390f35b5f600173__$ffc1393672b8ed81d0c8093ffcb0e7fbe8$__632ad11272846040518263ffffffff1660e01b81526004016100a29190610163565b602060405180830381865af41580156100bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e19190610190565b6100eb91906101e8565b9050919050565b5f5ffd5b5f819050919050565b610108816100f6565b8114610112575f5ffd5b50565b5f81359050610123816100ff565b92915050565b5f6020828403121561013e5761013d6100f2565b5b5f61014b84828501610115565b91505092915050565b61015d816100f6565b82525050565b5f6020820190506101765f830184610154565b92915050565b5f8151905061018a816100ff565b92915050565b5f602082840312156101a5576101a46100f2565b5b5f6101b28482850161017c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6101f2826100f6565b91506101fd836100f6565b9250828201905080821115610215576102146101bb565b5b9291505056fea2646970667358221220d6e7078682642d273736fd63baaa28538fe72495816c810fa0e77034de385dc564736f6c634300081c0033", + Deps: []*bind.MetaData{ + &L1MetaData, + }, +} + +// L2b is an auto generated Go binding around an Ethereum contract. +type L2b struct { + abi abi.ABI +} + +// NewL2b creates a new instance of L2b. +func NewL2b() *L2b { + parsed, err := L2bMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &L2b{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *L2b) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackDo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l2b *L2b) PackDo(val *big.Int) []byte { + enc, err := l2b.abi.Pack("Do", val) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDo is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l2b *L2b) UnpackDo(data []byte) (*big.Int, error) { + out, err := l2b.abi.Unpack("Do", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// L3MetaData contains all meta data concerning the L3 contract. +var L3MetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"Do\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "d03b97f5e1a564374023a72ac7d1806773", + Bin: "0x61011c61004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106032575f3560e01c80632ad11272146036575b5f5ffd5b604c600480360381019060489190609c565b6060565b6040516057919060cf565b60405180910390f35b5f60019050919050565b5f5ffd5b5f819050919050565b607e81606e565b81146087575f5ffd5b50565b5f813590506096816077565b92915050565b5f6020828403121560ae5760ad606a565b5b5f60b984828501608a565b91505092915050565b60c981606e565b82525050565b5f60208201905060e05f83018460c2565b9291505056fea264697066735822122094cfcb0ce039318885cc58f6d8e609e6e4bec575e1a046d3d15ea2e01e97241e64736f6c634300081c0033", +} + +// L3 is an auto generated Go binding around an Ethereum contract. +type L3 struct { + abi abi.ABI +} + +// NewL3 creates a new instance of L3. +func NewL3() *L3 { + parsed, err := L3MetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &L3{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *L3) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackDo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l3 *L3) PackDo(val *big.Int) []byte { + enc, err := l3.abi.Pack("Do", val) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDo is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l3 *L3) UnpackDo(data []byte) (*big.Int, error) { + out, err := l3.abi.Unpack("Do", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// L4MetaData contains all meta data concerning the L4 contract. +var L4MetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"Do\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "5f33a1fab8ea7d932b4bc8c5e7dcd90bc2", + Bin: "0x6102d161004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c80632ad1127214610038575b5f5ffd5b610052600480360381019061004d91906101a9565b610068565b60405161005f91906101e3565b60405180910390f35b5f600173__$d03b97f5e1a564374023a72ac7d1806773$__632ad11272846040518263ffffffff1660e01b81526004016100a291906101e3565b602060405180830381865af41580156100bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e19190610210565b73__$2ce896a6dd38932d354f317286f90bc675$__632ad11272856040518263ffffffff1660e01b815260040161011891906101e3565b602060405180830381865af4158015610133573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101579190610210565b6101619190610268565b61016b9190610268565b9050919050565b5f5ffd5b5f819050919050565b61018881610176565b8114610192575f5ffd5b50565b5f813590506101a38161017f565b92915050565b5f602082840312156101be576101bd610172565b5b5f6101cb84828501610195565b91505092915050565b6101dd81610176565b82525050565b5f6020820190506101f65f8301846101d4565b92915050565b5f8151905061020a8161017f565b92915050565b5f6020828403121561022557610224610172565b5b5f610232848285016101fc565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61027282610176565b915061027d83610176565b92508282019050808211156102955761029461023b565b5b9291505056fea2646970667358221220531485f0b9ff78ba5ef06ef345aaddccec3ad15d1460014ccd7c2a58d36d0d4464736f6c634300081c0033", + Deps: []*bind.MetaData{ + &L2MetaData, + &L3MetaData, + }, +} + +// L4 is an auto generated Go binding around an Ethereum contract. +type L4 struct { + abi abi.ABI +} + +// NewL4 creates a new instance of L4. +func NewL4() *L4 { + parsed, err := L4MetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &L4{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *L4) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackDo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l4 *L4) PackDo(val *big.Int) []byte { + enc, err := l4.abi.Pack("Do", val) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDo is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l4 *L4) UnpackDo(data []byte) (*big.Int, error) { + out, err := l4.abi.Unpack("Do", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} + +// L4bMetaData contains all meta data concerning the L4b contract. +var L4bMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"Do\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "6070639404c39b5667691bb1f9177e1eac", + Bin: "0x61025161004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c80632ad1127214610038575b5f5ffd5b610052600480360381019061004d9190610129565b610068565b60405161005f9190610163565b60405180910390f35b5f600173__$fd1474cf57f7ed48491e8bfdfd0d172adf$__632ad11272846040518263ffffffff1660e01b81526004016100a29190610163565b602060405180830381865af41580156100bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e19190610190565b6100eb91906101e8565b9050919050565b5f5ffd5b5f819050919050565b610108816100f6565b8114610112575f5ffd5b50565b5f81359050610123816100ff565b92915050565b5f6020828403121561013e5761013d6100f2565b5b5f61014b84828501610115565b91505092915050565b61015d816100f6565b82525050565b5f6020820190506101765f830184610154565b92915050565b5f8151905061018a816100ff565b92915050565b5f602082840312156101a5576101a46100f2565b5b5f6101b28482850161017c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6101f2826100f6565b91506101fd836100f6565b9250828201905080821115610215576102146101bb565b5b9291505056fea264697066735822122008a2478fd2427f180ace529e137b69337cb655dc21d6426de37054c32e821c6a64736f6c634300081c0033", + Deps: []*bind.MetaData{ + &L2bMetaData, + }, +} + +// L4b is an auto generated Go binding around an Ethereum contract. +type L4b struct { + abi abi.ABI +} + +// NewL4b creates a new instance of L4b. +func NewL4b() *L4b { + parsed, err := L4bMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &L4b{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *L4b) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackDo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l4b *L4b) PackDo(val *big.Int) []byte { + enc, err := l4b.abi.Pack("Do", val) + if err != nil { + panic(err) + } + return enc +} + +// UnpackDo is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ad11272. +// +// Solidity: function Do(uint256 val) pure returns(uint256) +func (l4b *L4b) UnpackDo(data []byte) (*big.Int, error) { + out, err := l4b.abi.Unpack("Do", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, err +} diff --git a/accounts/abi/bind/v2/internal/contracts/nested_libraries/combined-abi.json b/accounts/abi/bind/v2/internal/contracts/nested_libraries/combined-abi.json new file mode 100644 index 0000000000..61e928aab1 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/nested_libraries/combined-abi.json @@ -0,0 +1 @@ +{"contracts":{"contract.sol:C1":{"abi":[{"inputs":[{"internalType":"uint256","name":"v1","type":"uint256"},{"internalType":"uint256","name":"v2","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"Do","outputs":[{"internalType":"uint256","name":"res","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"6080604052348015600e575f5ffd5b506040516103983803806103988339818101604052810190602e91906066565b5050609d565b5f5ffd5b5f819050919050565b6048816038565b81146051575f5ffd5b50565b5f815190506060816041565b92915050565b5f5f6040838503121560795760786034565b5b5f6084858286016054565b92505060206093858286016054565b9150509250929050565b6102ee806100aa5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c80632ad112721461002d575b5f5ffd5b6100476004803603810190610042919061019e565b61005d565b60405161005491906101d8565b60405180910390f35b5f600173__$ffc1393672b8ed81d0c8093ffcb0e7fbe8$__632ad112725f6040518263ffffffff1660e01b81526004016100979190610200565b602060405180830381865af41580156100b2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100d6919061022d565b73__$5f33a1fab8ea7d932b4bc8c5e7dcd90bc2$__632ad11272856040518263ffffffff1660e01b815260040161010d9190610200565b602060405180830381865af4158015610128573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061014c919061022d565b6101569190610285565b6101609190610285565b9050919050565b5f5ffd5b5f819050919050565b61017d8161016b565b8114610187575f5ffd5b50565b5f8135905061019881610174565b92915050565b5f602082840312156101b3576101b2610167565b5b5f6101c08482850161018a565b91505092915050565b6101d28161016b565b82525050565b5f6020820190506101eb5f8301846101c9565b92915050565b6101fa8161016b565b82525050565b5f6020820190506102135f8301846101f1565b92915050565b5f8151905061022781610174565b92915050565b5f6020828403121561024257610241610167565b5b5f61024f84828501610219565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61028f8261016b565b915061029a8361016b565b92508282019050808211156102b2576102b1610258565b5b9291505056fea26469706673582212205d4715a8d20a3a0a43113e268ec8868b3c3ce24f7cbdb8735b4eeeebf0b5565164736f6c634300081c0033"},"contract.sol:C2":{"abi":[{"inputs":[{"internalType":"uint256","name":"v1","type":"uint256"},{"internalType":"uint256","name":"v2","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"Do","outputs":[{"internalType":"uint256","name":"res","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"6080604052348015600e575f5ffd5b506040516103983803806103988339818101604052810190602e91906066565b5050609d565b5f5ffd5b5f819050919050565b6048816038565b81146051575f5ffd5b50565b5f815190506060816041565b92915050565b5f5f6040838503121560795760786034565b5b5f6084858286016054565b92505060206093858286016054565b9150509250929050565b6102ee806100aa5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c80632ad112721461002d575b5f5ffd5b6100476004803603810190610042919061019e565b61005d565b60405161005491906101d8565b60405180910390f35b5f600173__$ffc1393672b8ed81d0c8093ffcb0e7fbe8$__632ad112725f6040518263ffffffff1660e01b81526004016100979190610200565b602060405180830381865af41580156100b2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100d6919061022d565b73__$6070639404c39b5667691bb1f9177e1eac$__632ad11272856040518263ffffffff1660e01b815260040161010d9190610200565b602060405180830381865af4158015610128573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061014c919061022d565b6101569190610285565b6101609190610285565b9050919050565b5f5ffd5b5f819050919050565b61017d8161016b565b8114610187575f5ffd5b50565b5f8135905061019881610174565b92915050565b5f602082840312156101b3576101b2610167565b5b5f6101c08482850161018a565b91505092915050565b6101d28161016b565b82525050565b5f6020820190506101eb5f8301846101c9565b92915050565b6101fa8161016b565b82525050565b5f6020820190506102135f8301846101f1565b92915050565b5f8151905061022781610174565b92915050565b5f6020828403121561024257610241610167565b5b5f61024f84828501610219565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61028f8261016b565b915061029a8361016b565b92508282019050808211156102b2576102b1610258565b5b9291505056fea2646970667358221220dd394981f1e9fefa4d88bac1c4f1da4131779c7d3bd4189958d278e57e96d96f64736f6c634300081c0033"},"contract.sol:L1":{"abi":[{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"Do","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"61011c61004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106032575f3560e01c80632ad11272146036575b5f5ffd5b604c600480360381019060489190609c565b6060565b6040516057919060cf565b60405180910390f35b5f60019050919050565b5f5ffd5b5f819050919050565b607e81606e565b81146087575f5ffd5b50565b5f813590506096816077565b92915050565b5f6020828403121560ae5760ad606a565b5b5f60b984828501608a565b91505092915050565b60c981606e565b82525050565b5f60208201905060e05f83018460c2565b9291505056fea26469706673582212200161c5f22d130a2b7ec6cf22e0910e42e32c2881fa4a8a01455f524f63cf218d64736f6c634300081c0033"},"contract.sol:L2":{"abi":[{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"Do","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"61025161004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c80632ad1127214610038575b5f5ffd5b610052600480360381019061004d9190610129565b610068565b60405161005f9190610163565b60405180910390f35b5f600173__$ffc1393672b8ed81d0c8093ffcb0e7fbe8$__632ad11272846040518263ffffffff1660e01b81526004016100a29190610163565b602060405180830381865af41580156100bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e19190610190565b6100eb91906101e8565b9050919050565b5f5ffd5b5f819050919050565b610108816100f6565b8114610112575f5ffd5b50565b5f81359050610123816100ff565b92915050565b5f6020828403121561013e5761013d6100f2565b5b5f61014b84828501610115565b91505092915050565b61015d816100f6565b82525050565b5f6020820190506101765f830184610154565b92915050565b5f8151905061018a816100ff565b92915050565b5f602082840312156101a5576101a46100f2565b5b5f6101b28482850161017c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6101f2826100f6565b91506101fd836100f6565b9250828201905080821115610215576102146101bb565b5b9291505056fea264697066735822122026999f96e14b0e279909ca5972343113c358e93a904569409a86866e2064f0fa64736f6c634300081c0033"},"contract.sol:L2b":{"abi":[{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"Do","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"61025161004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c80632ad1127214610038575b5f5ffd5b610052600480360381019061004d9190610129565b610068565b60405161005f9190610163565b60405180910390f35b5f600173__$ffc1393672b8ed81d0c8093ffcb0e7fbe8$__632ad11272846040518263ffffffff1660e01b81526004016100a29190610163565b602060405180830381865af41580156100bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e19190610190565b6100eb91906101e8565b9050919050565b5f5ffd5b5f819050919050565b610108816100f6565b8114610112575f5ffd5b50565b5f81359050610123816100ff565b92915050565b5f6020828403121561013e5761013d6100f2565b5b5f61014b84828501610115565b91505092915050565b61015d816100f6565b82525050565b5f6020820190506101765f830184610154565b92915050565b5f8151905061018a816100ff565b92915050565b5f602082840312156101a5576101a46100f2565b5b5f6101b28482850161017c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6101f2826100f6565b91506101fd836100f6565b9250828201905080821115610215576102146101bb565b5b9291505056fea2646970667358221220d6e7078682642d273736fd63baaa28538fe72495816c810fa0e77034de385dc564736f6c634300081c0033"},"contract.sol:L3":{"abi":[{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"Do","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"61011c61004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106032575f3560e01c80632ad11272146036575b5f5ffd5b604c600480360381019060489190609c565b6060565b6040516057919060cf565b60405180910390f35b5f60019050919050565b5f5ffd5b5f819050919050565b607e81606e565b81146087575f5ffd5b50565b5f813590506096816077565b92915050565b5f6020828403121560ae5760ad606a565b5b5f60b984828501608a565b91505092915050565b60c981606e565b82525050565b5f60208201905060e05f83018460c2565b9291505056fea264697066735822122094cfcb0ce039318885cc58f6d8e609e6e4bec575e1a046d3d15ea2e01e97241e64736f6c634300081c0033"},"contract.sol:L4":{"abi":[{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"Do","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"6102d161004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c80632ad1127214610038575b5f5ffd5b610052600480360381019061004d91906101a9565b610068565b60405161005f91906101e3565b60405180910390f35b5f600173__$d03b97f5e1a564374023a72ac7d1806773$__632ad11272846040518263ffffffff1660e01b81526004016100a291906101e3565b602060405180830381865af41580156100bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e19190610210565b73__$2ce896a6dd38932d354f317286f90bc675$__632ad11272856040518263ffffffff1660e01b815260040161011891906101e3565b602060405180830381865af4158015610133573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101579190610210565b6101619190610268565b61016b9190610268565b9050919050565b5f5ffd5b5f819050919050565b61018881610176565b8114610192575f5ffd5b50565b5f813590506101a38161017f565b92915050565b5f602082840312156101be576101bd610172565b5b5f6101cb84828501610195565b91505092915050565b6101dd81610176565b82525050565b5f6020820190506101f65f8301846101d4565b92915050565b5f8151905061020a8161017f565b92915050565b5f6020828403121561022557610224610172565b5b5f610232848285016101fc565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61027282610176565b915061027d83610176565b92508282019050808211156102955761029461023b565b5b9291505056fea2646970667358221220531485f0b9ff78ba5ef06ef345aaddccec3ad15d1460014ccd7c2a58d36d0d4464736f6c634300081c0033"},"contract.sol:L4b":{"abi":[{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"Do","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"61025161004d600b8282823980515f1a6073146041577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c80632ad1127214610038575b5f5ffd5b610052600480360381019061004d9190610129565b610068565b60405161005f9190610163565b60405180910390f35b5f600173__$fd1474cf57f7ed48491e8bfdfd0d172adf$__632ad11272846040518263ffffffff1660e01b81526004016100a29190610163565b602060405180830381865af41580156100bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e19190610190565b6100eb91906101e8565b9050919050565b5f5ffd5b5f819050919050565b610108816100f6565b8114610112575f5ffd5b50565b5f81359050610123816100ff565b92915050565b5f6020828403121561013e5761013d6100f2565b5b5f61014b84828501610115565b91505092915050565b61015d816100f6565b82525050565b5f6020820190506101765f830184610154565b92915050565b5f8151905061018a816100ff565b92915050565b5f602082840312156101a5576101a46100f2565b5b5f6101b28482850161017c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6101f2826100f6565b91506101fd836100f6565b9250828201905080821115610215576102146101bb565b5b9291505056fea264697066735822122008a2478fd2427f180ace529e137b69337cb655dc21d6426de37054c32e821c6a64736f6c634300081c0033"}},"version":"0.8.28+commit.7893614a.Darwin.appleclang"} diff --git a/accounts/abi/bind/v2/internal/contracts/nested_libraries/contract.sol b/accounts/abi/bind/v2/internal/contracts/nested_libraries/contract.sol new file mode 100644 index 0000000000..1794e72ac9 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/nested_libraries/contract.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + + +// L1 +// \ +// L2 L3 L1 +// \ / / +// L4 / +// \ / +// C1 +// +library L1 { + function Do(uint256 val) public pure returns (uint256) { + return uint256(1); + } +} + +library L2 { + function Do(uint256 val) public pure returns (uint256) { + return L1.Do(val) + uint256(1); + } +} + +library L3 { + function Do(uint256 val) public pure returns (uint256) { + return uint256(1); + } +} + +library L4 { + function Do(uint256 val) public pure returns (uint256) { + return L2.Do(uint256(val)) + L3.Do(uint256(val)) + uint256(1); + } +} + +contract C1 { + function Do(uint256 val) public pure returns (uint256 res) { + return L4.Do(uint256(val)) + L1.Do(uint256(0)) + uint256(1); + } + + constructor(uint256 v1, uint256 v2) { + // do something with these + } +} + +// second contract+libraries: slightly different library deps than V1, but sharing several +// L1 +// \ +// L2b L3 L1 +// \ / / +// L4b / +// \ / +// C2 +// +library L4b { + function Do(uint256 val) public pure returns (uint256) { + return L2b.Do(uint256(val)) + uint256(1); + } +} + +library L2b { + function Do(uint256 val) public pure returns (uint256) { + return L1.Do(uint256(val)) + uint256(1); + } +} + +contract C2 { + function Do(uint256 val) public pure returns (uint256 res) { + return L4b.Do(uint256(val)) + L1.Do(uint256(0)) + uint256(1); + } + + constructor(uint256 v1, uint256 v2) { + // do something with these + } +} \ No newline at end of file diff --git a/accounts/abi/bind/v2/internal/contracts/solc_errors/bindings.go b/accounts/abi/bind/v2/internal/contracts/solc_errors/bindings.go new file mode 100644 index 0000000000..067fb2b0e1 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/solc_errors/bindings.go @@ -0,0 +1,217 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package solc_errors + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// CMetaData contains all meta data concerning the C contract. +var CMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"arg1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"arg2\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"arg3\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"arg4\",\"type\":\"bool\"}],\"name\":\"BadThing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"arg1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"arg2\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"arg3\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"arg4\",\"type\":\"uint256\"}],\"name\":\"BadThing2\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Bar\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Foo\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "55ef3c19a0ab1c1845f9e347540c1e51f5", + Bin: "0x6080604052348015600e575f5ffd5b506101c58061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c8063b0a378b014610038578063bfb4ebcf14610042575b5f5ffd5b61004061004c565b005b61004a610092565b005b5f6001600260036040517fd233a24f00000000000000000000000000000000000000000000000000000000815260040161008994939291906100ef565b60405180910390fd5b5f600160025f6040517fbb6a82f10000000000000000000000000000000000000000000000000000000081526004016100ce949392919061014c565b60405180910390fd5b5f819050919050565b6100e9816100d7565b82525050565b5f6080820190506101025f8301876100e0565b61010f60208301866100e0565b61011c60408301856100e0565b61012960608301846100e0565b95945050505050565b5f8115159050919050565b61014681610132565b82525050565b5f60808201905061015f5f8301876100e0565b61016c60208301866100e0565b61017960408301856100e0565b610186606083018461013d565b9594505050505056fea26469706673582212206a82b4c28576e4483a81102558271cfefc891cd63b95440dea521185c1ff6a2a64736f6c634300081c0033", +} + +// C is an auto generated Go binding around an Ethereum contract. +type C struct { + abi abi.ABI +} + +// NewC creates a new instance of C. +func NewC() *C { + parsed, err := CMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &C{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *C) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackBar is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb0a378b0. +// +// Solidity: function Bar() pure returns() +func (c *C) PackBar() []byte { + enc, err := c.abi.Pack("Bar") + if err != nil { + panic(err) + } + return enc +} + +// PackFoo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xbfb4ebcf. +// +// Solidity: function Foo() pure returns() +func (c *C) PackFoo() []byte { + enc, err := c.abi.Pack("Foo") + if err != nil { + panic(err) + } + return enc +} + +// UnpackError attempts to decode the provided error data using user-defined +// error definitions. +func (c *C) UnpackError(raw []byte) (any, error) { + if bytes.Equal(raw[:4], c.abi.Errors["BadThing"].ID.Bytes()[:4]) { + return c.UnpackBadThingError(raw[4:]) + } + if bytes.Equal(raw[:4], c.abi.Errors["BadThing2"].ID.Bytes()[:4]) { + return c.UnpackBadThing2Error(raw[4:]) + } + return nil, errors.New("Unknown error") +} + +// CBadThing represents a BadThing error raised by the C contract. +type CBadThing struct { + Arg1 *big.Int + Arg2 *big.Int + Arg3 *big.Int + Arg4 bool +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error BadThing(uint256 arg1, uint256 arg2, uint256 arg3, bool arg4) +func CBadThingErrorID() common.Hash { + return common.HexToHash("0xbb6a82f123854747ef4381e30e497f934a3854753fec99a69c35c30d4b46714d") +} + +// UnpackBadThingError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error BadThing(uint256 arg1, uint256 arg2, uint256 arg3, bool arg4) +func (c *C) UnpackBadThingError(raw []byte) (*CBadThing, error) { + out := new(CBadThing) + if err := c.abi.UnpackIntoInterface(out, "BadThing", raw); err != nil { + return nil, err + } + return out, nil +} + +// CBadThing2 represents a BadThing2 error raised by the C contract. +type CBadThing2 struct { + Arg1 *big.Int + Arg2 *big.Int + Arg3 *big.Int + Arg4 *big.Int +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error BadThing2(uint256 arg1, uint256 arg2, uint256 arg3, uint256 arg4) +func CBadThing2ErrorID() common.Hash { + return common.HexToHash("0xd233a24f02271fe7c9470e060d0fda6447a142bf12ab31fed7ab65affd546175") +} + +// UnpackBadThing2Error is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error BadThing2(uint256 arg1, uint256 arg2, uint256 arg3, uint256 arg4) +func (c *C) UnpackBadThing2Error(raw []byte) (*CBadThing2, error) { + out := new(CBadThing2) + if err := c.abi.UnpackIntoInterface(out, "BadThing2", raw); err != nil { + return nil, err + } + return out, nil +} + +// C2MetaData contains all meta data concerning the C2 contract. +var C2MetaData = bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"arg1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"arg2\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"arg3\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"arg4\",\"type\":\"bool\"}],\"name\":\"BadThing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Foo\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "78ef2840de5b706112ca2dbfa765501a89", + Bin: "0x6080604052348015600e575f5ffd5b506101148061001c5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c8063bfb4ebcf14602a575b5f5ffd5b60306032565b005b5f600160025f6040517fbb6a82f1000000000000000000000000000000000000000000000000000000008152600401606c949392919060a3565b60405180910390fd5b5f819050919050565b6085816075565b82525050565b5f8115159050919050565b609d81608b565b82525050565b5f60808201905060b45f830187607e565b60bf6020830186607e565b60ca6040830185607e565b60d560608301846096565b9594505050505056fea2646970667358221220e90bf647ffc897060e44b88d54995ed0c03c988fbccaf034375c2ff4e594690764736f6c634300081c0033", +} + +// C2 is an auto generated Go binding around an Ethereum contract. +type C2 struct { + abi abi.ABI +} + +// NewC2 creates a new instance of C2. +func NewC2() *C2 { + parsed, err := C2MetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &C2{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *C2) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackFoo is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xbfb4ebcf. +// +// Solidity: function Foo() pure returns() +func (c2 *C2) PackFoo() []byte { + enc, err := c2.abi.Pack("Foo") + if err != nil { + panic(err) + } + return enc +} + +// UnpackError attempts to decode the provided error data using user-defined +// error definitions. +func (c2 *C2) UnpackError(raw []byte) (any, error) { + if bytes.Equal(raw[:4], c2.abi.Errors["BadThing"].ID.Bytes()[:4]) { + return c2.UnpackBadThingError(raw[4:]) + } + return nil, errors.New("Unknown error") +} + +// C2BadThing represents a BadThing error raised by the C2 contract. +type C2BadThing struct { + Arg1 *big.Int + Arg2 *big.Int + Arg3 *big.Int + Arg4 bool +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error BadThing(uint256 arg1, uint256 arg2, uint256 arg3, bool arg4) +func C2BadThingErrorID() common.Hash { + return common.HexToHash("0xbb6a82f123854747ef4381e30e497f934a3854753fec99a69c35c30d4b46714d") +} + +// UnpackBadThingError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error BadThing(uint256 arg1, uint256 arg2, uint256 arg3, bool arg4) +func (c2 *C2) UnpackBadThingError(raw []byte) (*C2BadThing, error) { + out := new(C2BadThing) + if err := c2.abi.UnpackIntoInterface(out, "BadThing", raw); err != nil { + return nil, err + } + return out, nil +} diff --git a/accounts/abi/bind/v2/internal/contracts/solc_errors/combined-abi.json b/accounts/abi/bind/v2/internal/contracts/solc_errors/combined-abi.json new file mode 100644 index 0000000000..a8fdf9dc3c --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/solc_errors/combined-abi.json @@ -0,0 +1 @@ +{"contracts":{"contract.sol:C":{"abi":[{"inputs":[{"internalType":"uint256","name":"arg1","type":"uint256"},{"internalType":"uint256","name":"arg2","type":"uint256"},{"internalType":"uint256","name":"arg3","type":"uint256"},{"internalType":"bool","name":"arg4","type":"bool"}],"name":"BadThing","type":"error"},{"inputs":[{"internalType":"uint256","name":"arg1","type":"uint256"},{"internalType":"uint256","name":"arg2","type":"uint256"},{"internalType":"uint256","name":"arg3","type":"uint256"},{"internalType":"uint256","name":"arg4","type":"uint256"}],"name":"BadThing2","type":"error"},{"inputs":[],"name":"Bar","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"Foo","outputs":[],"stateMutability":"pure","type":"function"}],"bin":"6080604052348015600e575f5ffd5b506101c58061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c8063b0a378b014610038578063bfb4ebcf14610042575b5f5ffd5b61004061004c565b005b61004a610092565b005b5f6001600260036040517fd233a24f00000000000000000000000000000000000000000000000000000000815260040161008994939291906100ef565b60405180910390fd5b5f600160025f6040517fbb6a82f10000000000000000000000000000000000000000000000000000000081526004016100ce949392919061014c565b60405180910390fd5b5f819050919050565b6100e9816100d7565b82525050565b5f6080820190506101025f8301876100e0565b61010f60208301866100e0565b61011c60408301856100e0565b61012960608301846100e0565b95945050505050565b5f8115159050919050565b61014681610132565b82525050565b5f60808201905061015f5f8301876100e0565b61016c60208301866100e0565b61017960408301856100e0565b610186606083018461013d565b9594505050505056fea26469706673582212206a82b4c28576e4483a81102558271cfefc891cd63b95440dea521185c1ff6a2a64736f6c634300081c0033"},"contract.sol:C2":{"abi":[{"inputs":[{"internalType":"uint256","name":"arg1","type":"uint256"},{"internalType":"uint256","name":"arg2","type":"uint256"},{"internalType":"uint256","name":"arg3","type":"uint256"},{"internalType":"bool","name":"arg4","type":"bool"}],"name":"BadThing","type":"error"},{"inputs":[],"name":"Foo","outputs":[],"stateMutability":"pure","type":"function"}],"bin":"6080604052348015600e575f5ffd5b506101148061001c5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c8063bfb4ebcf14602a575b5f5ffd5b60306032565b005b5f600160025f6040517fbb6a82f1000000000000000000000000000000000000000000000000000000008152600401606c949392919060a3565b60405180910390fd5b5f819050919050565b6085816075565b82525050565b5f8115159050919050565b609d81608b565b82525050565b5f60808201905060b45f830187607e565b60bf6020830186607e565b60ca6040830185607e565b60d560608301846096565b9594505050505056fea2646970667358221220e90bf647ffc897060e44b88d54995ed0c03c988fbccaf034375c2ff4e594690764736f6c634300081c0033"}},"version":"0.8.28+commit.7893614a.Darwin.appleclang"} diff --git a/accounts/abi/bind/v2/internal/contracts/solc_errors/contract.sol b/accounts/abi/bind/v2/internal/contracts/solc_errors/contract.sol new file mode 100644 index 0000000000..541352a1d8 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/solc_errors/contract.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + +error BadThing(uint256 arg1, uint256 arg2, uint256 arg3, bool arg4); +error BadThing2(uint256 arg1, uint256 arg2, uint256 arg3, uint256 arg4); + +contract C { + function Foo() public pure { + revert BadThing({ + arg1: uint256(0), + arg2: uint256(1), + arg3: uint256(2), + arg4: false + }); + } + function Bar() public pure { + revert BadThing2({ + arg1: uint256(0), + arg2: uint256(1), + arg3: uint256(2), + arg4: uint256(3) + }); + } +} + +// purpose of this is to test that generation of metadata for contract that emits one error produces valid Go code +contract C2 { + function Foo() public pure { + revert BadThing({ + arg1: uint256(0), + arg2: uint256(1), + arg3: uint256(2), + arg4: false + }); + } +} \ No newline at end of file diff --git a/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/bindings.go b/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/bindings.go new file mode 100644 index 0000000000..4999cc75d9 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/bindings.go @@ -0,0 +1,77 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package uint256arrayreturn + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// MyContractMetaData contains all meta data concerning the MyContract contract. +var MyContractMetaData = bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"GetNums\",\"outputs\":[{\"internalType\":\"uint256[5]\",\"name\":\"\",\"type\":\"uint256[5]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ID: "e48e83c9c45b19a47bd451eedc725a6bff", + Bin: "0x6080604052348015600e575f5ffd5b506101a78061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063bd6d10071461002d575b5f5ffd5b61003561004b565b6040516100429190610158565b60405180910390f35b610053610088565b5f6040518060a001604052805f8152602001600181526020016002815260200160038152602001600481525090508091505090565b6040518060a00160405280600590602082028036833780820191505090505090565b5f60059050919050565b5f81905092915050565b5f819050919050565b5f819050919050565b6100d9816100c7565b82525050565b5f6100ea83836100d0565b60208301905092915050565b5f602082019050919050565b61010b816100aa565b61011581846100b4565b9250610120826100be565b805f5b8381101561015057815161013787826100df565b9650610142836100f6565b925050600181019050610123565b505050505050565b5f60a08201905061016b5f830184610102565b9291505056fea2646970667358221220ef76cc678ca215c3e9e5261e3f33ac1cb9901c3186c2af167bfcd8f03b3b864c64736f6c634300081c0033", +} + +// MyContract is an auto generated Go binding around an Ethereum contract. +type MyContract struct { + abi abi.ABI +} + +// NewMyContract creates a new instance of MyContract. +func NewMyContract() *MyContract { + parsed, err := MyContractMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &MyContract{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *MyContract) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackGetNums is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xbd6d1007. +// +// Solidity: function GetNums() pure returns(uint256[5]) +func (myContract *MyContract) PackGetNums() []byte { + enc, err := myContract.abi.Pack("GetNums") + if err != nil { + panic(err) + } + return enc +} + +// UnpackGetNums is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xbd6d1007. +// +// Solidity: function GetNums() pure returns(uint256[5]) +func (myContract *MyContract) UnpackGetNums(data []byte) ([5]*big.Int, error) { + out, err := myContract.abi.Unpack("GetNums", data) + if err != nil { + return *new([5]*big.Int), err + } + out0 := *abi.ConvertType(out[0], new([5]*big.Int)).(*[5]*big.Int) + return out0, err +} diff --git a/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/combined-abi.json b/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/combined-abi.json new file mode 100644 index 0000000000..f0b424b82f --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/combined-abi.json @@ -0,0 +1 @@ +{"contracts":{"contract.sol:MyContract":{"abi":[{"inputs":[],"name":"GetNums","outputs":[{"internalType":"uint256[5]","name":"","type":"uint256[5]"}],"stateMutability":"pure","type":"function"}],"bin":"6080604052348015600e575f5ffd5b506101a78061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063bd6d10071461002d575b5f5ffd5b61003561004b565b6040516100429190610158565b60405180910390f35b610053610088565b5f6040518060a001604052805f8152602001600181526020016002815260200160038152602001600481525090508091505090565b6040518060a00160405280600590602082028036833780820191505090505090565b5f60059050919050565b5f81905092915050565b5f819050919050565b5f819050919050565b6100d9816100c7565b82525050565b5f6100ea83836100d0565b60208301905092915050565b5f602082019050919050565b61010b816100aa565b61011581846100b4565b9250610120826100be565b805f5b8381101561015057815161013787826100df565b9650610142836100f6565b925050600181019050610123565b505050505050565b5f60a08201905061016b5f830184610102565b9291505056fea2646970667358221220ef76cc678ca215c3e9e5261e3f33ac1cb9901c3186c2af167bfcd8f03b3b864c64736f6c634300081c0033"}},"version":"0.8.28+commit.7893614a.Darwin.appleclang"} diff --git a/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/contract.sol b/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/contract.sol new file mode 100644 index 0000000000..cb2aa54b38 --- /dev/null +++ b/accounts/abi/bind/v2/internal/contracts/uint256arrayreturn/contract.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + +contract MyContract { + // emit multiple events, different types + function GetNums() public pure returns (uint256[5] memory) { + uint256[5] memory myNums = [uint256(0), uint256(1), uint256(2), uint256(3), uint256(4)]; + return myNums; + } +} \ No newline at end of file diff --git a/accounts/abi/bind/v2/lib.go b/accounts/abi/bind/v2/lib.go new file mode 100644 index 0000000000..3831161341 --- /dev/null +++ b/accounts/abi/bind/v2/lib.go @@ -0,0 +1,243 @@ +// 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 bind implements utilities for interacting with Solidity contracts. +// This is the 'runtime' for contract bindings generated with the abigen command. +// It includes methods for calling/transacting, filtering chain history for +// specific custom Solidity event types, and creating event subscriptions to monitor the +// chain for event occurrences. +// +// Two methods for contract deployment are provided: +// - [DeployContract] is intended to be used for deployment of a single contract. +// - [LinkAndDeploy] is intended for the deployment of multiple +// contracts, potentially with library dependencies. +package bind + +import ( + "errors" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/event" +) + +// ContractEvent is a type constraint for ABI event types. +type ContractEvent interface { + ContractEventName() string +} + +// FilterEvents filters a historical block range for instances of emission of a +// specific event type from a specified contract. It returns an error if the +// provided filter opts are invalid or the backend is closed. +// +// FilterEvents is intended to be used with contract event unpack methods in +// bindings generated with the abigen --v2 flag. It should be +// preferred over BoundContract.FilterLogs. +func FilterEvents[Ev ContractEvent](c *BoundContract, opts *FilterOpts, unpack func(*types.Log) (*Ev, error), topics ...[]any) (*EventIterator[Ev], error) { + var e Ev + logs, sub, err := c.FilterLogs(opts, e.ContractEventName(), topics...) + if err != nil { + return nil, err + } + return &EventIterator[Ev]{unpack: unpack, logs: logs, sub: sub}, nil +} + +// WatchEvents creates an event subscription to notify when logs of the +// specified event type are emitted from the given contract. Received logs are +// unpacked and forwarded to sink. If topics are specified, only events are +// forwarded which match the topics. +// +// WatchEvents returns a subscription or an error if the provided WatchOpts are +// invalid or the backend is closed. +// +// WatchEvents is intended to be used with contract event unpack methods in +// bindings generated with the abigen --v2 flag. It should be +// preferred over BoundContract.WatchLogs. +func WatchEvents[Ev ContractEvent](c *BoundContract, opts *WatchOpts, unpack func(*types.Log) (*Ev, error), sink chan<- *Ev, topics ...[]any) (event.Subscription, error) { + var e Ev + logs, sub, err := c.WatchLogs(opts, e.ContractEventName(), topics...) + 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 + ev, err := unpack(&log) + if err != nil { + return err + } + + select { + case sink <- ev: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// EventIterator is an object for iterating over the results of a event log +// filter call. +type EventIterator[T any] struct { + current *T + unpack func(*types.Log) (*T, error) + logs <-chan types.Log + sub ethereum.Subscription + fail error // error to hold reason for iteration failure + closed bool // true if Close has been called +} + +// Value returns the current value of the iterator, or nil if there isn't one. +func (it *EventIterator[T]) Value() *T { + return it.current +} + +// Next advances the iterator to the subsequent event (if there is one), +// returning true if the iterator advanced. +// +// If the attempt to convert the raw log object to an instance of T using the +// unpack function provided via FilterEvents returns an error: that error is +// returned and subsequent calls to Next will not advance the iterator. +func (it *EventIterator[T]) Next() (advanced bool) { + // If the iterator failed with an error, don't proceed + if it.fail != nil || it.closed { + return false + } + // if the iterator is still active, block until a log is received or the + // underlying subscription terminates. + select { + case log := <-it.logs: + res, err := it.unpack(&log) + if err != nil { + it.fail = err + return false + } + it.current = res + return true + case <-it.sub.Err(): + // regardless of how the subscription ends, still be able to iterate + // over any unread logs. + select { + case log := <-it.logs: + res, err := it.unpack(&log) + if err != nil { + it.fail = err + return false + } + it.current = res + return true + default: + return false + } + } +} + +// Error returns an error if iteration has failed. +func (it *EventIterator[T]) Error() error { + return it.fail +} + +// Close releases any pending underlying resources. Any subsequent calls to +// Next will not advance the iterator, but the current value remains accessible. +func (it *EventIterator[T]) Close() error { + it.closed = true + it.sub.Unsubscribe() + return nil +} + +// Call performs an eth_call to a contract with optional call data. +// +// To call a function that doesn't return any output, pass nil as the unpack +// function. This can be useful if you just want to check that the function +// doesn't revert. +// +// Call is intended to be used with contract method unpack methods in +// bindings generated with the abigen --v2 flag. It should be +// preferred over BoundContract.Call +func Call[T any](c *BoundContract, opts *CallOpts, calldata []byte, unpack func([]byte) (T, error)) (T, error) { + var defaultResult T + packedOutput, err := c.CallRaw(opts, calldata) + if err != nil { + return defaultResult, err + } + if unpack == nil { + if len(packedOutput) > 0 { + return defaultResult, errors.New("contract returned data, but no unpack function was given") + } + return defaultResult, nil + } + res, err := unpack(packedOutput) + if err != nil { + return defaultResult, err + } + return res, err +} + +// Transact creates and submits a transaction to a contract with optional input +// data. +// +// Transact is identical to BoundContract.RawTransact, and is provided as a +// package-level method so that interactions with contracts whose bindings were +// generated with the abigen --v2 flag are consistent (they do not require +// calling methods on the BoundContract instance). +func Transact(c *BoundContract, opt *TransactOpts, data []byte) (*types.Transaction, error) { + return c.RawTransact(opt, data) +} + +// DeployContract creates and submits a deployment transaction based on the +// deployer bytecode and optional ABI-encoded constructor input. It returns +// the address and creation transaction of the pending contract, or an error +// if the creation failed. +// +// To initiate the deployment of multiple contracts with one method call, see the +// [LinkAndDeploy] method. +func DeployContract(opts *TransactOpts, bytecode []byte, backend ContractBackend, constructorInput []byte) (common.Address, *types.Transaction, error) { + c := NewBoundContract(common.Address{}, abi.ABI{}, backend, backend, backend) + + tx, err := c.RawCreationTransact(opts, append(bytecode, constructorInput...)) + if err != nil { + return common.Address{}, nil, err + } + return crypto.CreateAddress(opts.From, tx.Nonce()), tx, nil +} + +// DefaultDeployer returns a DeployFn that signs and submits creation transactions +// using the given signer. +// +// The DeployFn returned by DefaultDeployer should be used by LinkAndDeploy in +// almost all cases, unless a custom DeployFn implementation is needed. +func DefaultDeployer(opts *TransactOpts, backend ContractBackend) DeployFn { + return func(input []byte, deployer []byte) (common.Address, *types.Transaction, error) { + addr, tx, err := DeployContract(opts, deployer, backend, input) + if err != nil { + return common.Address{}, nil, err + } + return addr, tx, nil + } +} diff --git a/accounts/abi/bind/v2/lib_test.go b/accounts/abi/bind/v2/lib_test.go new file mode 100644 index 0000000000..fc895edad5 --- /dev/null +++ b/accounts/abi/bind/v2/lib_test.go @@ -0,0 +1,361 @@ +// 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 bind_test + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2/internal/contracts/events" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2/internal/contracts/nested_libraries" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2/internal/contracts/solc_errors" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/ethclient/simulated" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" +) + +var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") +var testAddr = crypto.PubkeyToAddress(testKey.PublicKey) + +func testSetup() (*backends.SimulatedBackend, error) { + backend := simulated.NewBackend( + types.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000000000)}, + }, + func(nodeConf *node.Config, ethConf *ethconfig.Config) { + ethConf.Genesis.Difficulty = big.NewInt(0) + }, + ) + + // we should just be able to use the backend directly, instead of using + // this deprecated interface. However, the simulated backend no longer + // implements backends.SimulatedBackend... + bindBackend := backends.SimulatedBackend{ + Backend: backend, + Client: backend.Client(), + } + return &bindBackend, nil +} + +func makeTestDeployer(backend simulated.Client) func(input, deployer []byte) (common.Address, *types.Transaction, error) { + chainId, _ := backend.ChainID(context.Background()) + return bind.DefaultDeployer(bind.NewKeyedTransactor(testKey, chainId), backend) +} + +// test that deploying a contract with library dependencies works, +// verifying by calling method on the deployed contract. +func TestDeploymentLibraries(t *testing.T) { + bindBackend, err := testSetup() + if err != nil { + t.Fatalf("err setting up test: %v", err) + } + defer bindBackend.Backend.Close() + + c := nested_libraries.NewC1() + constructorInput := c.PackConstructor(big.NewInt(42), big.NewInt(1)) + deploymentParams := &bind.DeploymentParams{ + Contracts: []*bind.MetaData{&nested_libraries.C1MetaData}, + Inputs: map[string][]byte{nested_libraries.C1MetaData.ID: constructorInput}, + } + res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend.Client)) + if err != nil { + t.Fatalf("err: %+v\n", err) + } + bindBackend.Commit() + + if len(res.Addresses) != 5 { + t.Fatalf("deployment should have generated 5 addresses. got %d", len(res.Addresses)) + } + for _, tx := range res.Txs { + _, err = bind.WaitDeployed(context.Background(), bindBackend, tx.Hash()) + if err != nil { + t.Fatalf("error deploying library: %+v", err) + } + } + + doInput := c.PackDo(big.NewInt(1)) + contractAddr := res.Addresses[nested_libraries.C1MetaData.ID] + callOpts := &bind.CallOpts{From: common.Address{}, Context: context.Background()} + instance := c.Instance(bindBackend, contractAddr) + internalCallCount, err := bind.Call(instance, callOpts, doInput, c.UnpackDo) + if err != nil { + t.Fatalf("err unpacking result: %v", err) + } + if internalCallCount.Uint64() != 6 { + t.Fatalf("expected internal call count of 6. got %d.", internalCallCount.Uint64()) + } +} + +// Same as TestDeployment. However, stagger the deployments with overrides: +// first deploy the library deps and then the contract. +func TestDeploymentWithOverrides(t *testing.T) { + bindBackend, err := testSetup() + if err != nil { + t.Fatalf("err setting up test: %v", err) + } + defer bindBackend.Backend.Close() + + // deploy all the library dependencies of our target contract, but not the target contract itself. + deploymentParams := &bind.DeploymentParams{ + Contracts: nested_libraries.C1MetaData.Deps, + } + res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend)) + if err != nil { + t.Fatalf("err: %+v\n", err) + } + bindBackend.Commit() + + if len(res.Addresses) != 4 { + t.Fatalf("deployment should have generated 4 addresses. got %d", len(res.Addresses)) + } + for _, tx := range res.Txs { + _, err = bind.WaitDeployed(context.Background(), bindBackend, tx.Hash()) + if err != nil { + t.Fatalf("error deploying library: %+v", err) + } + } + + c := nested_libraries.NewC1() + constructorInput := c.PackConstructor(big.NewInt(42), big.NewInt(1)) + overrides := res.Addresses + + // deploy the contract + deploymentParams = &bind.DeploymentParams{ + Contracts: []*bind.MetaData{&nested_libraries.C1MetaData}, + Inputs: map[string][]byte{nested_libraries.C1MetaData.ID: constructorInput}, + Overrides: overrides, + } + res, err = bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend)) + if err != nil { + t.Fatalf("err: %+v\n", err) + } + bindBackend.Commit() + + if len(res.Addresses) != 1 { + t.Fatalf("deployment should have generated 1 address. got %d", len(res.Addresses)) + } + for _, tx := range res.Txs { + _, err = bind.WaitDeployed(context.Background(), bindBackend, tx.Hash()) + if err != nil { + t.Fatalf("error deploying library: %+v", err) + } + } + + // call the deployed contract and make sure it returns the correct result + doInput := c.PackDo(big.NewInt(1)) + instance := c.Instance(bindBackend, res.Addresses[nested_libraries.C1MetaData.ID]) + callOpts := new(bind.CallOpts) + internalCallCount, err := bind.Call(instance, callOpts, doInput, c.UnpackDo) + if err != nil { + t.Fatalf("error calling contract: %v", err) + } + if internalCallCount.Uint64() != 6 { + t.Fatalf("expected internal call count of 6. got %d.", internalCallCount.Uint64()) + } +} + +// returns transaction auth to send a basic transaction from testAddr +func defaultTxAuth() *bind.TransactOpts { + signer := types.LatestSigner(params.AllDevChainProtocolChanges) + opts := &bind.TransactOpts{ + From: testAddr, + Nonce: nil, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey) + if err != nil { + return nil, err + } + signedTx, err := tx.WithSignature(signer, signature) + if err != nil { + return nil, err + } + return signedTx, nil + }, + Context: context.Background(), + } + return opts +} + +func TestEvents(t *testing.T) { + // test watch/filter logs method on a contract that emits various kinds of events (struct-containing, etc.) + backend, err := testSetup() + if err != nil { + t.Fatalf("error setting up testing env: %v", err) + } + deploymentParams := &bind.DeploymentParams{ + Contracts: []*bind.MetaData{&events.CMetaData}, + } + res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(backend)) + if err != nil { + t.Fatalf("error deploying contract for testing: %v", err) + } + + backend.Commit() + if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[events.CMetaData.ID].Hash()); err != nil { + t.Fatalf("WaitDeployed failed %v", err) + } + + c := events.NewC() + instance := c.Instance(backend, res.Addresses[events.CMetaData.ID]) + + newCBasic1Ch := make(chan *events.CBasic1) + newCBasic2Ch := make(chan *events.CBasic2) + watchOpts := &bind.WatchOpts{} + sub1, err := bind.WatchEvents(instance, watchOpts, c.UnpackBasic1Event, newCBasic1Ch) + if err != nil { + t.Fatalf("WatchEvents returned error: %v", err) + } + sub2, err := bind.WatchEvents(instance, watchOpts, c.UnpackBasic2Event, newCBasic2Ch) + if err != nil { + t.Fatalf("WatchEvents returned error: %v", err) + } + defer sub1.Unsubscribe() + defer sub2.Unsubscribe() + + packedInput := c.PackEmitMulti() + tx, err := bind.Transact(instance, defaultTxAuth(), packedInput) + if err != nil { + t.Fatalf("failed to send transaction: %v", err) + } + backend.Commit() + if _, err := bind.WaitMined(context.Background(), backend, tx.Hash()); err != nil { + t.Fatalf("error waiting for tx to be mined: %v", err) + } + + timeout := time.NewTimer(2 * time.Second) + e1Count := 0 + e2Count := 0 + for { + select { + case <-newCBasic1Ch: + e1Count++ + case <-newCBasic2Ch: + e2Count++ + case <-timeout.C: + goto done + } + if e1Count == 2 && e2Count == 1 { + break + } + } +done: + if e1Count != 2 { + t.Fatalf("expected event type 1 count to be 2. got %d", e1Count) + } + if e2Count != 1 { + t.Fatalf("expected event type 2 count to be 1. got %d", e2Count) + } + + // now, test that we can filter those same logs after they were included in the chain + + filterOpts := &bind.FilterOpts{ + Start: 0, + Context: context.Background(), + } + it, err := bind.FilterEvents(instance, filterOpts, c.UnpackBasic1Event) + if err != nil { + t.Fatalf("error filtering logs %v\n", err) + } + it2, err := bind.FilterEvents(instance, filterOpts, c.UnpackBasic2Event) + if err != nil { + t.Fatalf("error filtering logs %v\n", err) + } + + e1Count = 0 + e2Count = 0 + for it.Next() { + if err := it.Error(); err != nil { + t.Fatalf("got error while iterating events for e1: %v", err) + } + e1Count++ + } + for it2.Next() { + if err := it2.Error(); err != nil { + t.Fatalf("got error while iterating events for e2: %v", err) + } + e2Count++ + } + if e1Count != 2 { + t.Fatalf("expected e1Count of 2 from filter call. got %d", e1Count) + } + if e2Count != 1 { + t.Fatalf("expected e2Count of 1 from filter call. got %d", e1Count) + } +} + +func TestErrors(t *testing.T) { + // test watch/filter logs method on a contract that emits various kinds of events (struct-containing, etc.) + backend, err := testSetup() + if err != nil { + t.Fatalf("error setting up testing env: %v", err) + } + deploymentParams := &bind.DeploymentParams{ + Contracts: []*bind.MetaData{&solc_errors.CMetaData}, + } + res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(backend)) + if err != nil { + t.Fatalf("error deploying contract for testing: %v", err) + } + + backend.Commit() + if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[solc_errors.CMetaData.ID].Hash()); err != nil { + t.Fatalf("WaitDeployed failed %v", err) + } + + c := solc_errors.NewC() + instance := c.Instance(backend, res.Addresses[solc_errors.CMetaData.ID]) + packedInput := c.PackFoo() + opts := &bind.CallOpts{From: res.Addresses[solc_errors.CMetaData.ID]} + _, err = bind.Call[struct{}](instance, opts, packedInput, nil) + if err == nil { + t.Fatalf("expected call to fail") + } + raw, hasRevertErrorData := ethclient.RevertErrorData(err) + if !hasRevertErrorData { + t.Fatalf("expected call error to contain revert error data.") + } + rawUnpackedErr, err := c.UnpackError(raw) + if err != nil { + t.Fatalf("expected to unpack error") + } + + unpackedErr, ok := rawUnpackedErr.(*solc_errors.CBadThing) + if !ok { + t.Fatalf("unexpected type for error") + } + if unpackedErr.Arg1.Cmp(big.NewInt(0)) != 0 { + t.Fatalf("bad unpacked error result: expected Arg1 field to be 0. got %s", unpackedErr.Arg1.String()) + } + if unpackedErr.Arg2.Cmp(big.NewInt(1)) != 0 { + t.Fatalf("bad unpacked error result: expected Arg2 field to be 1. got %s", unpackedErr.Arg2.String()) + } + if unpackedErr.Arg3.Cmp(big.NewInt(2)) != 0 { + t.Fatalf("bad unpacked error result: expected Arg3 to be 2. got %s", unpackedErr.Arg3.String()) + } + if unpackedErr.Arg4 != false { + t.Fatalf("bad unpacked error result: expected Arg4 to be false. got true") + } +} diff --git a/accounts/abi/bind/util.go b/accounts/abi/bind/v2/util.go similarity index 60% rename from accounts/abi/bind/util.go rename to accounts/abi/bind/v2/util.go index c83116e9a1..438848a753 100644 --- a/accounts/abi/bind/util.go +++ b/accounts/abi/bind/v2/util.go @@ -29,19 +29,13 @@ import ( // WaitMined waits for tx to be mined on the blockchain. // It stops waiting when the context is canceled. -func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) { - return WaitMinedHash(ctx, b, tx.Hash()) -} - -// WaitMinedHash waits for a transaction with the provided hash to be mined on the blockchain. -// It stops waiting when the context is canceled. -func WaitMinedHash(ctx context.Context, b DeployBackend, hash common.Hash) (*types.Receipt, error) { +func WaitMined(ctx context.Context, b DeployBackend, txHash common.Hash) (*types.Receipt, error) { queryTicker := time.NewTicker(time.Second) defer queryTicker.Stop() - logger := log.New("hash", hash) + logger := log.New("hash", txHash) for { - receipt, err := b.TransactionReceipt(ctx, hash) + receipt, err := b.TransactionReceipt(ctx, txHash) if err == nil { return receipt, nil } @@ -61,24 +55,16 @@ func WaitMinedHash(ctx context.Context, b DeployBackend, hash common.Hash) (*typ } } -// WaitDeployed waits for a contract deployment transaction and returns the on-chain -// contract address when it is mined. It stops waiting when ctx is canceled. -func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) { - if tx.To() != nil { - return common.Address{}, errors.New("tx is not contract creation") - } - return WaitDeployedHash(ctx, b, tx.Hash()) -} - -// WaitDeployedHash waits for a contract deployment transaction with the provided hash and returns the on-chain -// contract address when it is mined. It stops waiting when ctx is canceled. -func WaitDeployedHash(ctx context.Context, b DeployBackend, hash common.Hash) (common.Address, error) { - receipt, err := WaitMinedHash(ctx, b, hash) +// WaitDeployed waits for a contract deployment transaction with the provided hash and +// returns the on-chain contract address when it is mined. It stops waiting when ctx is +// canceled. +func WaitDeployed(ctx context.Context, b DeployBackend, hash common.Hash) (common.Address, error) { + receipt, err := WaitMined(ctx, b, hash) if err != nil { return common.Address{}, err } if receipt.ContractAddress == (common.Address{}) { - return common.Address{}, errors.New("zero address") + return common.Address{}, ErrNoAddressInReceipt } // Check that code has indeed been deployed at the address. // This matters on pre-Homestead chains: OOG in the constructor diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/v2/util_test.go similarity index 88% rename from accounts/abi/bind/util_test.go rename to accounts/abi/bind/v2/util_test.go index 04d1bb63bc..b1b647a7b9 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/v2/util_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -31,8 +31,6 @@ import ( "github.com/ethereum/go-ethereum/params" ) -var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - var waitDeployedTests = map[string]struct { code string gas uint64 @@ -77,7 +75,7 @@ func TestWaitDeployed(t *testing.T) { ctx = context.Background() ) go func() { - address, err = bind.WaitDeployed(ctx, backend.Client(), tx) + address, err = bind.WaitDeployed(ctx, backend.Client(), tx.Hash()) close(mined) }() @@ -122,9 +120,8 @@ func TestWaitDeployedCornerCases(t *testing.T) { 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() { - t.Errorf("error mismatch: want %q, got %q, ", notContractCreation, err) + if _, err := bind.WaitDeployed(ctx, backend.Client(), tx.Hash()); err != bind.ErrNoAddressInReceipt { + t.Errorf("error mismatch: want %q, got %q, ", bind.ErrNoAddressInReceipt, err) } // Create a transaction that is not mined. @@ -133,7 +130,7 @@ func TestWaitDeployedCornerCases(t *testing.T) { go func() { contextCanceled := errors.New("context canceled") - if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != contextCanceled.Error() { + if _, err := bind.WaitDeployed(ctx, backend.Client(), tx.Hash()); err.Error() != contextCanceled.Error() { t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err) } }() diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 10343190c3..c82358be49 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -24,7 +24,7 @@ import ( "regexp" "strings" - "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/abigen" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common/compiler" "github.com/ethereum/go-ethereum/crypto" @@ -63,14 +63,13 @@ var ( Name: "out", Usage: "Output file for the generated binding (default = stdout)", } - langFlag = &cli.StringFlag{ - Name: "lang", - Usage: "Destination language for the bindings (go)", - Value: "go", - } aliasFlag = &cli.StringFlag{ Name: "alias", - Usage: "Comma separated aliases for function and event renaming, e.g. original1=alias1, original2=alias2", + Usage: "Comma separated aliases for function and event renaming. If --v2 is set, errors are aliased as well. e.g. original1=alias1, original2=alias2", + } + v2Flag = &cli.BoolFlag{ + Name: "v2", + Usage: "Generates v2 bindings", } ) @@ -86,13 +85,13 @@ func init() { excFlag, pkgFlag, outFlag, - langFlag, aliasFlag, + v2Flag, } - app.Action = abigen + app.Action = generate } -func abigen(c *cli.Context) error { +func generate(c *cli.Context) error { flags.CheckExclusive(c, abiFlag, jsonFlag) // Only one source can be selected. if c.String(pkgFlag.Name) == "" { @@ -101,13 +100,6 @@ func abigen(c *cli.Context) error { if c.String(abiFlag.Name) == "" && c.String(jsonFlag.Name) == "" { utils.Fatalf("Either contract ABI source (--abi) or combined-json (--combined-json) are required") } - var lang bind.Lang - switch c.String(langFlag.Name) { - case "go": - lang = bind.LangGo - default: - utils.Fatalf("Unsupported destination language \"%s\" (--lang)", c.String(langFlag.Name)) - } // If the entire solidity code was specified, build and bind based on that var ( abis []string @@ -219,7 +211,15 @@ func abigen(c *cli.Context) error { } } // Generate the contract binding - code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs, aliases) + var ( + code string + err error + ) + if c.IsSet(v2Flag.Name) { + code, err = abigen.BindV2(types, abis, bins, c.String(pkgFlag.Name), libs, aliases) + } else { + code, err = abigen.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), libs, aliases) + } if err != nil { utils.Fatalf("Failed to generate ABI binding: %v", err) } diff --git a/go.mod b/go.mod index 053c7b7a7d..5ec51dd1ea 100644 --- a/go.mod +++ b/go.mod @@ -65,6 +65,7 @@ require ( go.uber.org/automaxprocs v1.5.2 go.uber.org/goleak v1.3.0 golang.org/x/crypto v0.35.0 + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df golang.org/x/sync v0.11.0 golang.org/x/sys v0.30.0 golang.org/x/text v0.22.0 @@ -141,7 +142,6 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.36.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect From 0f06e3511534477cfb1f8aad23adf4eaa60debcc Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 17 Mar 2025 16:01:37 +0100 Subject: [PATCH 200/940] core/rawdb: allow for truncation in the freezer (#31362) Here we add the notion of prunable tables for the `TruncateTail` operation in the freezer. TruncateTail for the chain freezer now only truncates the body and receipts tables, leaving headers and hashes as-is. This change also requires changing the validation/repair at startup to allow for tables with different tail. For the header and hash tables, we now require them to start at number zero. --------- Co-authored-by: Felix Lange Co-authored-by: Gary Rong --- core/rawdb/ancient_scheme.go | 40 +++++++------ core/rawdb/ancient_utils.go | 12 ++-- core/rawdb/chain_freezer.go | 4 +- core/rawdb/freezer.go | 88 ++++++++++++++++++----------- core/rawdb/freezer_batch.go | 2 +- core/rawdb/freezer_memory.go | 28 +++++---- core/rawdb/freezer_memory_test.go | 14 +++-- core/rawdb/freezer_resettable.go | 2 +- core/rawdb/freezer_table.go | 50 ++++++++-------- core/rawdb/freezer_table_test.go | 94 +++++++++++++++---------------- core/rawdb/freezer_test.go | 28 +++++---- ethdb/database.go | 2 + 12 files changed, 208 insertions(+), 156 deletions(-) diff --git a/core/rawdb/ancient_scheme.go b/core/rawdb/ancient_scheme.go index 67bfa37ecc..1ffebed3e7 100644 --- a/core/rawdb/ancient_scheme.go +++ b/core/rawdb/ancient_scheme.go @@ -37,13 +37,21 @@ const ( ChainFreezerReceiptTable = "receipts" ) -// chainFreezerNoSnappy configures whether compression is disabled for the ancient-tables. -// Hashes and difficulties don't compress well. -var chainFreezerNoSnappy = map[string]bool{ - ChainFreezerHeaderTable: false, - ChainFreezerHashTable: true, - ChainFreezerBodiesTable: false, - ChainFreezerReceiptTable: false, +// chainFreezerTableConfigs configures the settings for tables in the chain freezer. +// Compression is disabled for hashes as they don't compress well. Additionally, +// tail truncation is disabled for the header and hash tables, as these are intended +// to be retained long-term. +var chainFreezerTableConfigs = map[string]freezerTableConfig{ + ChainFreezerHeaderTable: {noSnappy: false, prunable: false}, + ChainFreezerHashTable: {noSnappy: true, prunable: false}, + ChainFreezerBodiesTable: {noSnappy: false, prunable: true}, + ChainFreezerReceiptTable: {noSnappy: false, prunable: true}, +} + +// freezerTableConfig contains the settings for a freezer table. +type freezerTableConfig struct { + noSnappy bool // disables item compression + prunable bool // true for tables that can be pruned by TruncateTail } const ( @@ -58,13 +66,13 @@ const ( stateHistoryStorageData = "storage.data" ) -// stateFreezerNoSnappy configures whether compression is disabled for the state freezer. -var stateFreezerNoSnappy = map[string]bool{ - stateHistoryMeta: true, - stateHistoryAccountIndex: false, - stateHistoryStorageIndex: false, - stateHistoryAccountData: false, - stateHistoryStorageData: false, +// stateFreezerTableConfigs configures the settings for tables in the state freezer. +var stateFreezerTableConfigs = map[string]freezerTableConfig{ + stateHistoryMeta: {noSnappy: true, prunable: true}, + stateHistoryAccountIndex: {noSnappy: false, prunable: true}, + stateHistoryStorageIndex: {noSnappy: false, prunable: true}, + stateHistoryAccountData: {noSnappy: false, prunable: true}, + stateHistoryStorageData: {noSnappy: false, prunable: true}, } // The list of identifiers of ancient stores. @@ -85,7 +93,7 @@ var freezers = []string{ChainFreezerName, MerkleStateFreezerName, VerkleStateFre // state freezer. func NewStateFreezer(ancientDir string, verkle bool, readOnly bool) (ethdb.ResettableAncientStore, error) { if ancientDir == "" { - return NewMemoryFreezer(readOnly, stateFreezerNoSnappy), nil + return NewMemoryFreezer(readOnly, stateFreezerTableConfigs), nil } var name string if verkle { @@ -93,5 +101,5 @@ func NewStateFreezer(ancientDir string, verkle bool, readOnly bool) (ethdb.Reset } else { name = filepath.Join(ancientDir, MerkleStateFreezerName) } - return newResettableFreezer(name, "eth/db/state", readOnly, stateHistoryTableSize, stateFreezerNoSnappy) + return newResettableFreezer(name, "eth/db/state", readOnly, stateHistoryTableSize, stateFreezerTableConfigs) } diff --git a/core/rawdb/ancient_utils.go b/core/rawdb/ancient_utils.go index 6804d7a91a..f4909d86e7 100644 --- a/core/rawdb/ancient_utils.go +++ b/core/rawdb/ancient_utils.go @@ -51,7 +51,7 @@ func (info *freezerInfo) size() common.StorageSize { return total } -func inspect(name string, order map[string]bool, reader ethdb.AncientReader) (freezerInfo, error) { +func inspect(name string, order map[string]freezerTableConfig, reader ethdb.AncientReader) (freezerInfo, error) { info := freezerInfo{name: name} for t := range order { size, err := reader.AncientSize(t) @@ -82,7 +82,7 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) { for _, freezer := range freezers { switch freezer { case ChainFreezerName: - info, err := inspect(ChainFreezerName, chainFreezerNoSnappy, db) + info, err := inspect(ChainFreezerName, chainFreezerTableConfigs, db) if err != nil { return nil, err } @@ -99,7 +99,7 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) { } defer f.Close() - info, err := inspect(freezer, stateFreezerNoSnappy, f) + info, err := inspect(freezer, stateFreezerTableConfigs, f) if err != nil { return nil, err } @@ -119,13 +119,13 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) { func InspectFreezerTable(ancient string, freezerName string, tableName string, start, end int64) error { var ( path string - tables map[string]bool + tables map[string]freezerTableConfig ) switch freezerName { case ChainFreezerName: - path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy + path, tables = resolveChainFreezerDir(ancient), chainFreezerTableConfigs case MerkleStateFreezerName, VerkleStateFreezerName: - path, tables = filepath.Join(ancient, freezerName), stateFreezerNoSnappy + path, tables = filepath.Join(ancient, freezerName), stateFreezerTableConfigs default: return fmt.Errorf("unknown freezer, supported ones: %v", freezers) } diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index 0627aca34c..f3c671f45a 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -62,9 +62,9 @@ func newChainFreezer(datadir string, namespace string, readonly bool) (*chainFre freezer ethdb.AncientStore ) if datadir == "" { - freezer = NewMemoryFreezer(readonly, chainFreezerNoSnappy) + freezer = NewMemoryFreezer(readonly, chainFreezerTableConfigs) } else { - freezer, err = NewFreezer(datadir, namespace, readonly, freezerTableSize, chainFreezerNoSnappy) + freezer, err = NewFreezer(datadir, namespace, readonly, freezerTableSize, chainFreezerTableConfigs) } if err != nil { return nil, err diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index c5a72eff7e..105d3af934 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -78,7 +78,7 @@ type Freezer struct { // // The 'tables' argument defines the data tables. If the value of a map // entry is true, snappy compression is disabled for the table. -func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize uint32, tables map[string]bool) (*Freezer, error) { +func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize uint32, tables map[string]freezerTableConfig) (*Freezer, error) { // Create the initial freezer object var ( readMeter = metrics.NewRegisteredMeter(namespace+"ancient/read", nil) @@ -121,8 +121,8 @@ func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize ui } // Create the tables. - for name, disableSnappy := range tables { - table, err := newTable(datadir, name, readMeter, writeMeter, sizeGauge, maxTableSize, disableSnappy, readonly) + for name, config := range tables { + table, err := newTable(datadir, name, readMeter, writeMeter, sizeGauge, maxTableSize, config, readonly) if err != nil { for _, table := range freezer.tables { table.Close() @@ -301,7 +301,8 @@ func (f *Freezer) TruncateHead(items uint64) (uint64, error) { return oitems, nil } -// TruncateTail discards any recent data below the provided threshold number. +// TruncateTail discards all data below the specified threshold. Note that only +// 'prunable' tables will be truncated. func (f *Freezer) TruncateTail(tail uint64) (uint64, error) { if f.readonly { return 0, errReadOnly @@ -314,8 +315,10 @@ func (f *Freezer) TruncateTail(tail uint64) (uint64, error) { return old, nil } for _, table := range f.tables { - if err := table.truncateTail(tail); err != nil { - return 0, err + if table.config.prunable { + if err := table.truncateTail(tail); err != nil { + return 0, err + } } } f.tail.Store(tail) @@ -343,56 +346,77 @@ func (f *Freezer) validate() error { return nil } var ( - head uint64 - tail uint64 - name string + head uint64 + prunedTail *uint64 ) - // Hack to get boundary of any table - for kind, table := range f.tables { + // get any head value + for _, table := range f.tables { head = table.items.Load() - tail = table.itemHidden.Load() - name = kind break } - // Now check every table against those boundaries. for kind, table := range f.tables { + // all tables have to have the same head if head != table.items.Load() { - return fmt.Errorf("freezer tables %s and %s have differing head: %d != %d", kind, name, table.items.Load(), head) + return fmt.Errorf("freezer table %s has a differing head: %d != %d", kind, table.items.Load(), head) } - if tail != table.itemHidden.Load() { - return fmt.Errorf("freezer tables %s and %s have differing tail: %d != %d", kind, name, table.itemHidden.Load(), tail) + if !table.config.prunable { + // non-prunable tables have to start at 0 + if table.itemHidden.Load() != 0 { + return fmt.Errorf("non-prunable freezer table '%s' has a non-zero tail: %d", kind, table.itemHidden.Load()) + } + } else { + // prunable tables have to have the same length + if prunedTail == nil { + tmp := table.itemHidden.Load() + prunedTail = &tmp + } + if *prunedTail != table.itemHidden.Load() { + return fmt.Errorf("freezer table %s has differing tail: %d != %d", kind, table.itemHidden.Load(), *prunedTail) + } } } + + if prunedTail == nil { + tmp := uint64(0) + prunedTail = &tmp + } + f.frozen.Store(head) - f.tail.Store(tail) + f.tail.Store(*prunedTail) return nil } // repair truncates all data tables to the same length. func (f *Freezer) repair() error { var ( - head = uint64(math.MaxUint64) - tail = uint64(0) + head = uint64(math.MaxUint64) + prunedTail = uint64(0) ) + // get the minimal head and the maximum tail for _, table := range f.tables { - items := table.items.Load() - if head > items { - head = items - } - hidden := table.itemHidden.Load() - if hidden > tail { - tail = hidden - } + head = min(head, table.items.Load()) + prunedTail = max(prunedTail, table.itemHidden.Load()) } - for _, table := range f.tables { + // apply the pruning + for kind, table := range f.tables { + // all tables need to have the same head if err := table.truncateHead(head); err != nil { return err } - if err := table.truncateTail(tail); err != nil { - return err + if !table.config.prunable { + // non-prunable tables have to start at 0 + if table.itemHidden.Load() != 0 { + panic(fmt.Sprintf("non-prunable freezer table %s has non-zero tail: %v", kind, table.itemHidden.Load())) + } + } else { + // prunable tables have to have the same length + if err := table.truncateTail(prunedTail); err != nil { + return err + } } } + f.frozen.Store(head) - f.tail.Store(tail) + f.tail.Store(prunedTail) return nil } diff --git a/core/rawdb/freezer_batch.go b/core/rawdb/freezer_batch.go index 801d30f73f..99b63df4dc 100644 --- a/core/rawdb/freezer_batch.go +++ b/core/rawdb/freezer_batch.go @@ -96,7 +96,7 @@ type freezerTableBatch struct { // newBatch creates a new batch for the freezer table. func (t *freezerTable) newBatch() *freezerTableBatch { batch := &freezerTableBatch{t: t} - if !t.noCompression { + if !t.config.noSnappy { batch.sb = new(snappyBuffer) } batch.reset() diff --git a/core/rawdb/freezer_memory.go b/core/rawdb/freezer_memory.go index 2d3dbb07dd..4274546de5 100644 --- a/core/rawdb/freezer_memory.go +++ b/core/rawdb/freezer_memory.go @@ -30,17 +30,19 @@ import ( // 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 + + name string + config freezerTableConfig } // newMemoryTable initializes the memory table. -func newMemoryTable(name string) *memoryTable { - return &memoryTable{name: name} +func newMemoryTable(name string, config freezerTableConfig) *memoryTable { + return &memoryTable{name: name, config: config} } // has returns an indicator whether the specified data exists. @@ -218,10 +220,10 @@ type MemoryFreezer struct { } // NewMemoryFreezer initializes an in-memory freezer instance. -func NewMemoryFreezer(readonly bool, tableName map[string]bool) *MemoryFreezer { +func NewMemoryFreezer(readonly bool, tableName map[string]freezerTableConfig) *MemoryFreezer { tables := make(map[string]*memoryTable) - for name := range tableName { - tables[name] = newMemoryTable(name) + for name, cfg := range tableName { + tables[name] = newMemoryTable(name, cfg) } return &MemoryFreezer{ writeBatch: newMemoryBatch(), @@ -368,7 +370,9 @@ func (f *MemoryFreezer) TruncateHead(items uint64) (uint64, error) { return old, nil } -// TruncateTail discards any recent data below the provided threshold number. +// TruncateTail discards all data below the provided threshold number. +// Note this will only truncate 'prunable' tables. Block headers and canonical +// hashes cannot be truncated at this time. func (f *MemoryFreezer) TruncateTail(tail uint64) (uint64, error) { f.lock.Lock() defer f.lock.Unlock() @@ -381,8 +385,10 @@ func (f *MemoryFreezer) TruncateTail(tail uint64) (uint64, error) { return old, nil } for _, table := range f.tables { - if err := table.truncateTail(tail); err != nil { - return 0, err + if table.config.prunable { + if err := table.truncateTail(tail); err != nil { + return 0, err + } } } f.tail = tail @@ -412,8 +418,8 @@ func (f *MemoryFreezer) Reset() error { defer f.lock.Unlock() tables := make(map[string]*memoryTable) - for name := range f.tables { - tables[name] = newMemoryTable(name) + for name, table := range f.tables { + tables[name] = newMemoryTable(name, table.config) } f.tables = tables f.items, f.tail = 0, 0 diff --git a/core/rawdb/freezer_memory_test.go b/core/rawdb/freezer_memory_test.go index e71de0f629..4bd31d8027 100644 --- a/core/rawdb/freezer_memory_test.go +++ b/core/rawdb/freezer_memory_test.go @@ -25,16 +25,22 @@ import ( func TestMemoryFreezer(t *testing.T) { ancienttest.TestAncientSuite(t, func(kinds []string) ethdb.AncientStore { - tables := make(map[string]bool) + tables := make(map[string]freezerTableConfig) for _, kind := range kinds { - tables[kind] = true + tables[kind] = freezerTableConfig{ + noSnappy: true, + prunable: true, + } } return NewMemoryFreezer(false, tables) }) ancienttest.TestResettableAncientSuite(t, func(kinds []string) ethdb.ResettableAncientStore { - tables := make(map[string]bool) + tables := make(map[string]freezerTableConfig) for _, kind := range kinds { - tables[kind] = true + tables[kind] = freezerTableConfig{ + noSnappy: true, + prunable: true, + } } return NewMemoryFreezer(false, tables) }) diff --git a/core/rawdb/freezer_resettable.go b/core/rawdb/freezer_resettable.go index 7c77a06efc..2e64e6074c 100644 --- a/core/rawdb/freezer_resettable.go +++ b/core/rawdb/freezer_resettable.go @@ -49,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, maxTableSize uint32, tables map[string]bool) (*resettableFreezer, error) { +func newResettableFreezer(datadir string, namespace string, readonly bool, maxTableSize uint32, tables map[string]freezerTableConfig) (*resettableFreezer, error) { if err := cleanup(datadir); err != nil { return nil, err } diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go index e553df7029..aec24b207e 100644 --- a/core/rawdb/freezer_table.go +++ b/core/rawdb/freezer_table.go @@ -100,11 +100,11 @@ type freezerTable struct { // should never be lower than itemOffset. itemHidden atomic.Uint64 - noCompression bool // if true, disables snappy compression. Note: does not work retroactively - readonly bool - maxFileSize uint32 // Max file size for data-files - name string - path string + config freezerTableConfig // if true, disables snappy compression. Note: does not work retroactively + readonly bool + maxFileSize uint32 // Max file size for data-files + name string + path string head *os.File // File descriptor for the data head of the table index *os.File // File descriptor for the indexEntry file of the table @@ -125,20 +125,20 @@ type freezerTable struct { } // newFreezerTable opens the given path as a freezer table. -func newFreezerTable(path, name string, disableSnappy, readonly bool) (*freezerTable, error) { - return newTable(path, name, metrics.NewInactiveMeter(), metrics.NewInactiveMeter(), metrics.NewGauge(), freezerTableSize, disableSnappy, readonly) +func newFreezerTable(path, name string, config freezerTableConfig, readonly bool) (*freezerTable, error) { + return newTable(path, name, metrics.NewInactiveMeter(), metrics.NewInactiveMeter(), metrics.NewGauge(), freezerTableSize, config, readonly) } // newTable opens a freezer table, creating the data and index files if they are // non-existent. Both files are truncated to the shortest common length to ensure // they don't go out of sync. -func newTable(path string, name string, readMeter, writeMeter *metrics.Meter, sizeGauge *metrics.Gauge, maxFilesize uint32, noCompression, readonly bool) (*freezerTable, error) { +func newTable(path string, name string, readMeter, writeMeter *metrics.Meter, sizeGauge *metrics.Gauge, maxFilesize uint32, config freezerTableConfig, readonly bool) (*freezerTable, error) { // Ensure the containing directory exists and open the indexEntry file if err := os.MkdirAll(path, 0755); err != nil { return nil, err } var idxName string - if noCompression { + if config.noSnappy { idxName = fmt.Sprintf("%s.ridx", name) // raw index file } else { idxName = fmt.Sprintf("%s.cidx", name) // compressed index file @@ -176,19 +176,19 @@ func newTable(path string, name string, readMeter, writeMeter *metrics.Meter, si } // Create the table and repair any past inconsistency tab := &freezerTable{ - index: index, - metadata: metadata, - lastSync: time.Now(), - files: make(map[uint32]*os.File), - readMeter: readMeter, - writeMeter: writeMeter, - sizeGauge: sizeGauge, - name: name, - path: path, - logger: log.New("database", path, "table", name), - noCompression: noCompression, - readonly: readonly, - maxFileSize: maxFilesize, + index: index, + metadata: metadata, + lastSync: time.Now(), + files: make(map[uint32]*os.File), + readMeter: readMeter, + writeMeter: writeMeter, + sizeGauge: sizeGauge, + name: name, + path: path, + logger: log.New("database", path, "table", name), + config: config, + readonly: readonly, + maxFileSize: maxFilesize, } if err := tab.repair(); err != nil { tab.Close() @@ -871,7 +871,7 @@ func (t *freezerTable) openFile(num uint32, opener func(string) (*os.File, error var exist bool if f, exist = t.files[num]; !exist { var name string - if t.noCompression { + if t.config.noSnappy { name = fmt.Sprintf("%s.%04d.rdat", t.name, num) } else { name = fmt.Sprintf("%s.%04d.cdat", t.name, num) @@ -987,13 +987,13 @@ func (t *freezerTable) RetrieveItems(start, count, maxBytes uint64) ([][]byte, e item := diskData[offset : offset+diskSize] offset += diskSize decompressedSize := diskSize - if !t.noCompression { + if !t.config.noSnappy { decompressedSize, _ = snappy.DecodedLen(item) } if i > 0 && maxBytes != 0 && uint64(outputSize+decompressedSize) > maxBytes { break } - if !t.noCompression { + if !t.config.noSnappy { data, err := snappy.Decode(nil, item) if err != nil { return nil, err diff --git a/core/rawdb/freezer_table_test.go b/core/rawdb/freezer_table_test.go index 9a72af6ccc..96edac7e4a 100644 --- a/core/rawdb/freezer_table_test.go +++ b/core/rawdb/freezer_table_test.go @@ -39,7 +39,7 @@ func TestFreezerBasics(t *testing.T) { // set cutoff at 50 bytes f, err := newTable(os.TempDir(), fmt.Sprintf("unittest-%d", rand.Uint64()), - metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, false) + metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -84,7 +84,7 @@ func TestFreezerBasicsClosing(t *testing.T) { f *freezerTable err error ) - f, err = newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err = newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -98,7 +98,7 @@ func TestFreezerBasicsClosing(t *testing.T) { require.NoError(t, batch.commit()) f.Close() - f, err = newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err = newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -115,7 +115,7 @@ func TestFreezerBasicsClosing(t *testing.T) { t.Fatalf("test %d, got \n%x != \n%x", y, got, exp) } f.Close() - f, err = newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err = newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -130,7 +130,7 @@ func TestFreezerRepairDanglingHead(t *testing.T) { // Fill table { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -159,7 +159,7 @@ func TestFreezerRepairDanglingHead(t *testing.T) { // Now open it again { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -182,7 +182,7 @@ func TestFreezerRepairDanglingHeadLarge(t *testing.T) { // Fill a table and close it { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -208,7 +208,7 @@ func TestFreezerRepairDanglingHeadLarge(t *testing.T) { // Now open it again { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -231,7 +231,7 @@ func TestFreezerRepairDanglingHeadLarge(t *testing.T) { // And if we open it, we should now be able to read all of them (new values) { - f, _ := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, _ := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) for y := 1; y < 255; y++ { exp := getChunk(15, ^y) got, err := f.Retrieve(uint64(y)) @@ -253,7 +253,7 @@ func TestSnappyDetection(t *testing.T) { // Open with snappy { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -264,7 +264,7 @@ func TestSnappyDetection(t *testing.T) { // Open with snappy { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -277,7 +277,7 @@ func TestSnappyDetection(t *testing.T) { // Open without snappy { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, false, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: false}, false) if err != nil { t.Fatal(err) } @@ -308,7 +308,7 @@ func TestFreezerRepairDanglingIndex(t *testing.T) { // Fill a table and close it { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -344,7 +344,7 @@ func TestFreezerRepairDanglingIndex(t *testing.T) { // 45, 45, 15 // with 3+3+1 items { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -365,7 +365,7 @@ func TestFreezerTruncate(t *testing.T) { // Fill table { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -381,7 +381,7 @@ func TestFreezerTruncate(t *testing.T) { // Reopen, truncate { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -406,7 +406,7 @@ func TestFreezerRepairFirstFile(t *testing.T) { // Fill table { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -439,7 +439,7 @@ func TestFreezerRepairFirstFile(t *testing.T) { // Reopen { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -474,7 +474,7 @@ func TestFreezerReadAndTruncate(t *testing.T) { // Fill table { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -490,7 +490,7 @@ func TestFreezerReadAndTruncate(t *testing.T) { // Reopen and read all files { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -521,7 +521,7 @@ func TestFreezerOffset(t *testing.T) { fname := fmt.Sprintf("offset-%d", rand.Uint64()) // Fill table - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -545,7 +545,7 @@ func TestFreezerOffset(t *testing.T) { f.Close() // Now open again - f, err = newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + f, err = newTable(os.TempDir(), fname, rm, wm, sg, 40, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -597,7 +597,7 @@ func TestFreezerOffset(t *testing.T) { // Check that existing items have been moved to index 1M. { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -631,7 +631,7 @@ func TestTruncateTail(t *testing.T) { fname := fmt.Sprintf("truncate-tail-%d", rand.Uint64()) // Fill table - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -682,7 +682,7 @@ func TestTruncateTail(t *testing.T) { // Reopen the table, the deletion information should be persisted as well f.Close() - f, err = newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + f, err = newTable(os.TempDir(), fname, rm, wm, sg, 40, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -716,7 +716,7 @@ func TestTruncateTail(t *testing.T) { // Reopen the table, the above testing should still pass f.Close() - f, err = newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + f, err = newTable(os.TempDir(), fname, rm, wm, sg, 40, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -772,7 +772,7 @@ func TestTruncateHead(t *testing.T) { fname := fmt.Sprintf("truncate-head-blow-tail-%d", rand.Uint64()) // Fill table - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -883,7 +883,7 @@ func TestSequentialRead(t *testing.T) { rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge() fname := fmt.Sprintf("batchread-%d", rand.Uint64()) { // Fill table - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -893,7 +893,7 @@ func TestSequentialRead(t *testing.T) { f.Close() } { // Open it, iterate, verify iteration - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -914,7 +914,7 @@ func TestSequentialRead(t *testing.T) { } { // Open it, iterate, verify byte limit. The byte limit is less than item // size, so each lookup should only return one item - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 40, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -943,7 +943,7 @@ func TestSequentialReadByteLimit(t *testing.T) { rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge() fname := fmt.Sprintf("batchread-2-%d", rand.Uint64()) { // Fill table - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 100, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 100, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -965,7 +965,7 @@ func TestSequentialReadByteLimit(t *testing.T) { {100, 109, 10}, } { { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 100, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 100, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -993,7 +993,7 @@ func TestSequentialReadNoByteLimit(t *testing.T) { rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge() fname := fmt.Sprintf("batchread-3-%d", rand.Uint64()) { // Fill table - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 100, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 100, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -1011,7 +1011,7 @@ func TestSequentialReadNoByteLimit(t *testing.T) { {31, 30}, } { { - f, err := newTable(os.TempDir(), fname, rm, wm, sg, 100, true, false) + f, err := newTable(os.TempDir(), fname, rm, wm, sg, 100, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -1038,7 +1038,7 @@ func TestFreezerReadonly(t *testing.T) { // Case 1: Check it fails on non-existent file. _, err := newTable(tmpdir, fmt.Sprintf("readonlytest-%d", rand.Uint64()), - metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, true) + metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, true) if err == nil { t.Fatal("readonly table instantiation should fail for non-existent table") } @@ -1053,7 +1053,7 @@ func TestFreezerReadonly(t *testing.T) { idxFile.Write(make([]byte, 17)) idxFile.Close() _, err = newTable(tmpdir, fname, - metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, true) + metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, true) if err == nil { t.Errorf("readonly table instantiation should fail for invalid index size") } @@ -1063,7 +1063,7 @@ func TestFreezerReadonly(t *testing.T) { // again in readonly triggers an error. fname = fmt.Sprintf("readonlytest-%d", rand.Uint64()) f, err := newTable(tmpdir, fname, - metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, false) + metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatalf("failed to instantiate table: %v", err) } @@ -1076,7 +1076,7 @@ func TestFreezerReadonly(t *testing.T) { t.Fatal(err) } _, err = newTable(tmpdir, fname, - metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, true) + metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, true) if err == nil { t.Errorf("readonly table instantiation should fail for corrupt table file") } @@ -1085,7 +1085,7 @@ func TestFreezerReadonly(t *testing.T) { // Should be successful. fname = fmt.Sprintf("readonlytest-%d", rand.Uint64()) f, err = newTable(tmpdir, fname, - metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, false) + metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatalf("failed to instantiate table: %v\n", err) } @@ -1094,7 +1094,7 @@ func TestFreezerReadonly(t *testing.T) { t.Fatal(err) } f, err = newTable(tmpdir, fname, - metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, true) + metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, true) if err != nil { t.Fatal(err) } @@ -1234,7 +1234,7 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value { func runRandTest(rt randTest) bool { fname := fmt.Sprintf("randtest-%d", rand.Uint64()) - f, err := newTable(os.TempDir(), fname, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, false) + f, err := newTable(os.TempDir(), fname, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, false) if err != nil { panic("failed to initialize table") } @@ -1243,7 +1243,7 @@ func runRandTest(rt randTest) bool { switch step.op { case opReload: f.Close() - f, err = newTable(os.TempDir(), fname, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, true, false) + f, err = newTable(os.TempDir(), fname, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 50, freezerTableConfig{noSnappy: true}, false) if err != nil { rt[i].err = fmt.Errorf("failed to reload table %v", err) } @@ -1381,7 +1381,7 @@ func TestIndexValidation(t *testing.T) { } for _, c := range cases { fn := fmt.Sprintf("t-%d", rand.Uint64()) - f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 10*dataSize, true, false) + f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 10*dataSize, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -1392,7 +1392,7 @@ func TestIndexValidation(t *testing.T) { f.Close() // reopen the table, corruption should be truncated - f, err = newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 100, true, false) + f, err = newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 100, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -1422,7 +1422,7 @@ func TestFlushOffsetTracking(t *testing.T) { fileSize = 100 ) fn := fmt.Sprintf("t-%d", rand.Uint64()) - f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, true, false) + f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -1533,7 +1533,7 @@ func TestTailTruncationCrash(t *testing.T) { fileSize = 100 ) fn := fmt.Sprintf("t-%d", rand.Uint64()) - f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, true, false) + f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } @@ -1563,7 +1563,7 @@ func TestTailTruncationCrash(t *testing.T) { // the offset f.metadata.setFlushOffset(31*indexEntrySize, true) - f, err = newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, true, false) + f, err = newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), fileSize, freezerTableConfig{noSnappy: true}, false) if err != nil { t.Fatal(err) } diff --git a/core/rawdb/freezer_test.go b/core/rawdb/freezer_test.go index 7d82ea305f..150734d3ac 100644 --- a/core/rawdb/freezer_test.go +++ b/core/rawdb/freezer_test.go @@ -31,7 +31,7 @@ import ( "github.com/stretchr/testify/require" ) -var freezerTestTableDef = map[string]bool{"test": true} +var freezerTestTableDef = map[string]freezerTableConfig{"test": {noSnappy: true}} func TestFreezerModify(t *testing.T) { t.Parallel() @@ -47,7 +47,7 @@ func TestFreezerModify(t *testing.T) { valuesRLP = append(valuesRLP, iv) } - tables := map[string]bool{"raw": true, "rlp": false} + tables := map[string]freezerTableConfig{"raw": {noSnappy: true}, "rlp": {noSnappy: false}} f, _ := newFreezerForTesting(t, tables) defer f.Close() @@ -111,7 +111,7 @@ func TestFreezerModifyRollback(t *testing.T) { f.Close() // Reopen and check that the rolled-back data doesn't reappear. - tables := map[string]bool{"test": true} + tables := map[string]freezerTableConfig{"test": {noSnappy: true}} f2, err := NewFreezer(dir, "", false, 2049, tables) if err != nil { t.Fatalf("can't reopen freezer after failed ModifyAncients: %v", err) @@ -249,7 +249,7 @@ func TestFreezerConcurrentModifyTruncate(t *testing.T) { } func TestFreezerReadonlyValidate(t *testing.T) { - tables := map[string]bool{"a": true, "b": true} + tables := map[string]freezerTableConfig{"a": {noSnappy: true}, "b": {noSnappy: true}} dir := t.TempDir() // Open non-readonly freezer and fill individual tables // with different amount of data. @@ -285,7 +285,7 @@ func TestFreezerReadonlyValidate(t *testing.T) { func TestFreezerConcurrentReadonly(t *testing.T) { t.Parallel() - tables := map[string]bool{"a": true} + tables := map[string]freezerTableConfig{"a": {noSnappy: true}} dir := t.TempDir() f, err := NewFreezer(dir, "", false, 2049, tables) @@ -333,7 +333,7 @@ func TestFreezerConcurrentReadonly(t *testing.T) { } } -func newFreezerForTesting(t *testing.T, tables map[string]bool) (*Freezer, string) { +func newFreezerForTesting(t *testing.T, tables map[string]freezerTableConfig) (*Freezer, string) { t.Helper() dir := t.TempDir() @@ -379,7 +379,7 @@ func checkAncientCount(t *testing.T, f *Freezer, kind string, n uint64) { func TestFreezerCloseSync(t *testing.T) { t.Parallel() - f, _ := newFreezerForTesting(t, map[string]bool{"a": true, "b": true}) + f, _ := newFreezerForTesting(t, map[string]freezerTableConfig{"a": {noSnappy: true}, "b": {noSnappy: true}}) defer f.Close() // Now, close and sync. This mimics the behaviour if the node is shut down, @@ -401,17 +401,23 @@ func TestFreezerCloseSync(t *testing.T) { func TestFreezerSuite(t *testing.T) { ancienttest.TestAncientSuite(t, func(kinds []string) ethdb.AncientStore { - tables := make(map[string]bool) + tables := make(map[string]freezerTableConfig) for _, kind := range kinds { - tables[kind] = true + tables[kind] = freezerTableConfig{ + noSnappy: true, + prunable: true, + } } f, _ := newFreezerForTesting(t, tables) return f }) ancienttest.TestResettableAncientSuite(t, func(kinds []string) ethdb.ResettableAncientStore { - tables := make(map[string]bool) + tables := make(map[string]freezerTableConfig) for _, kind := range kinds { - tables[kind] = true + tables[kind] = freezerTableConfig{ + noSnappy: true, + prunable: true, + } } f, _ := newResettableFreezer(t.TempDir(), "", false, 2048, tables) return f diff --git a/ethdb/database.go b/ethdb/database.go index 323f8f5d6f..b1577512f3 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -128,6 +128,8 @@ type AncientWriter interface { // is item_n(start from 0). The deleted items may not be removed from the ancient store // immediately, but only when the accumulated deleted data reach the threshold then // will be removed all together. + // + // Note that data marked as non-prunable will still be retained and remain accessible. TruncateTail(n uint64) (uint64, error) // Sync flushes all in-memory ancient store data to disk. From d85f796356846f40d3e00ec6d03c1a3e3410a3b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Mon, 17 Mar 2025 18:59:04 +0100 Subject: [PATCH 201/940] eth/filters: implement log filter using new log index (#31080) This PR is #2 of a 3-part series that implements the new log index intended to replace core/bloombits. Based on https://github.com/ethereum/go-ethereum/pull/31079 Replaces https://github.com/ethereum/go-ethereum/pull/30370 This part replaces the old bloombits based log search logic in `eth/filters` to use the new `core/filtermaps` logic. FilterMaps data structure explanation: https://gist.github.com/zsfelfoldi/a60795f9da7ae6422f28c7a34e02a07e Log index generator code overview: https://gist.github.com/zsfelfoldi/97105dff0b1a4f5ed557924a24b9b9e7 Search pattern matcher code overview: https://gist.github.com/zsfelfoldi/5981735641c956afb18065e84f8aff34 Note that the possibility of a tree hashing scheme and remote proof protocol are mentioned in the documents above but they are not exactly specified yet. These specs are WIP and will be finalized after the local log indexer/filter code is finalized and merged. --------- Co-authored-by: Felix Lange --- cmd/geth/chaincmd.go | 3 + cmd/geth/main.go | 3 + cmd/utils/flags.go | 26 ++ common/range.go | 115 +++++ common/range_test.go | 36 ++ core/filtermaps/checkpoints_holesky.json | 37 +- core/filtermaps/checkpoints_mainnet.json | 516 ++++++++++++----------- core/filtermaps/checkpoints_sepolia.json | 127 +++--- core/filtermaps/filtermaps.go | 116 ++--- core/filtermaps/indexer.go | 144 ++++--- core/filtermaps/indexer_test.go | 52 ++- core/filtermaps/map_renderer.go | 270 ++++++------ core/filtermaps/matcher.go | 293 ++++++------- core/filtermaps/matcher_backend.go | 56 +-- core/rawdb/accessors_indexes.go | 21 +- eth/api_backend.go | 5 + eth/backend.go | 74 ++++ eth/ethconfig/config.go | 8 +- eth/filters/filter.go | 394 +++++++++++------ eth/filters/filter_system.go | 5 +- eth/filters/filter_system_test.go | 88 ++-- eth/filters/filter_test.go | 196 ++++++++- internal/ethapi/api_test.go | 6 +- internal/ethapi/backend.go | 6 +- internal/ethapi/transaction_args_test.go | 10 +- 25 files changed, 1593 insertions(+), 1014 deletions(-) create mode 100644 common/range.go create mode 100644 common/range_test.go diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index c30927d9ff..95239bd640 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -100,6 +100,9 @@ if one is set. Otherwise it prints the genesis from the datadir.`, utils.VMTraceFlag, utils.VMTraceJsonConfigFlag, utils.TransactionHistoryFlag, + utils.LogHistoryFlag, + utils.LogNoHistoryFlag, + utils.LogExportCheckpointsFlag, utils.StateHistoryFlag, }, utils.DatabaseFlags), Description: ` diff --git a/cmd/geth/main.go b/cmd/geth/main.go index fd3f4e1bab..2995d87624 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -87,6 +87,9 @@ var ( utils.TxLookupLimitFlag, // deprecated utils.TransactionHistoryFlag, utils.ChainHistoryFlag, + utils.LogHistoryFlag, + utils.LogNoHistoryFlag, + utils.LogExportCheckpointsFlag, utils.StateHistoryFlag, utils.LightServeFlag, // deprecated utils.LightIngressFlag, // deprecated diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 06eabbf313..2e3bb6aead 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -278,6 +278,23 @@ var ( Value: ethconfig.Defaults.HistoryMode.String(), Category: flags.StateCategory, } + LogHistoryFlag = &cli.Uint64Flag{ + Name: "history.logs", + Usage: "Number of recent blocks to maintain log search index for (default = about one year, 0 = entire chain)", + Value: ethconfig.Defaults.LogHistory, + Category: flags.StateCategory, + } + LogNoHistoryFlag = &cli.BoolFlag{ + Name: "history.logs.disable", + Usage: "Do not maintain log search index", + Category: flags.StateCategory, + } + LogExportCheckpointsFlag = &cli.StringFlag{ + Name: "history.logs.export", + Usage: "Export checkpoints to file in go source file format", + Category: flags.StateCategory, + Value: "", + } // Beacon client light sync settings BeaconApiFlag = &cli.StringSliceFlag{ Name: "beacon.api", @@ -1636,6 +1653,15 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { cfg.StateScheme = rawdb.HashScheme log.Warn("Forcing hash state-scheme for archive mode") } + if ctx.IsSet(LogHistoryFlag.Name) { + cfg.LogHistory = ctx.Uint64(LogHistoryFlag.Name) + } + if ctx.IsSet(LogNoHistoryFlag.Name) { + cfg.LogNoHistory = true + } + if ctx.IsSet(LogExportCheckpointsFlag.Name) { + cfg.LogExportCheckpoints = ctx.String(LogExportCheckpointsFlag.Name) + } if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) { cfg.TrieCleanCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100 } diff --git a/common/range.go b/common/range.go new file mode 100644 index 0000000000..c3a26ea7f5 --- /dev/null +++ b/common/range.go @@ -0,0 +1,115 @@ +// Copyright 2025 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 common + +import ( + "iter" +) + +// Range represents a range of integers. +type Range[T uint32 | uint64] struct { + first, afterLast T +} + +// NewRange creates a new range based of first element and number of elements. +func NewRange[T uint32 | uint64](first, count T) Range[T] { + return Range[T]{first, first + count} +} + +// First returns the first element of the range. +func (r Range[T]) First() T { + return r.first +} + +// Last returns the last element of the range. This panics for empty ranges. +func (r Range[T]) Last() T { + if r.first == r.afterLast { + panic("last item of zero length range is not allowed") + } + return r.afterLast - 1 +} + +// AfterLast returns the first element after the range. This allows obtaining +// information about the end part of zero length ranges. +func (r Range[T]) AfterLast() T { + return r.afterLast +} + +// Count returns the number of elements in the range. +func (r Range[T]) Count() T { + return r.afterLast - r.first +} + +// IsEmpty returns true if the range is empty. +func (r Range[T]) IsEmpty() bool { + return r.first == r.afterLast +} + +// Includes returns true if the given element is inside the range. +func (r Range[T]) Includes(v T) bool { + return v >= r.first && v < r.afterLast +} + +// SetFirst updates the first element of the list. +func (r *Range[T]) SetFirst(v T) { + r.first = v + if r.afterLast < r.first { + r.afterLast = r.first + } +} + +// SetAfterLast updates the end of the range by specifying the first element +// after the range. This allows setting zero length ranges. +func (r *Range[T]) SetAfterLast(v T) { + r.afterLast = v + if r.afterLast < r.first { + r.first = r.afterLast + } +} + +// SetLast updates last element of the range. +func (r *Range[T]) SetLast(v T) { + r.SetAfterLast(v + 1) +} + +// Intersection returns the intersection of two ranges. +func (r Range[T]) Intersection(q Range[T]) Range[T] { + i := Range[T]{first: max(r.first, q.first), afterLast: min(r.afterLast, q.afterLast)} + if i.first > i.afterLast { + return Range[T]{} + } + return i +} + +// Union returns the union of two ranges. Panics for gapped ranges. +func (r Range[T]) Union(q Range[T]) Range[T] { + if max(r.first, q.first) > min(r.afterLast, q.afterLast) { + panic("cannot create union; gap between ranges") + } + return Range[T]{first: min(r.first, q.first), afterLast: max(r.afterLast, q.afterLast)} +} + +// Iter iterates all integers in the range. +func (r Range[T]) Iter() iter.Seq[T] { + return func(yield func(T) bool) { + for i := r.first; i < r.afterLast; i++ { + if !yield(i) { + break + } + } + } +} diff --git a/common/range_test.go b/common/range_test.go new file mode 100644 index 0000000000..878b6d66c8 --- /dev/null +++ b/common/range_test.go @@ -0,0 +1,36 @@ +// Copyright 2025 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 common + +import ( + "slices" + "testing" +) + +func TestRangeIter(t *testing.T) { + r := NewRange[uint32](1, 7) + values := slices.Collect(r.Iter()) + if !slices.Equal(values, []uint32{1, 2, 3, 4, 5, 6, 7}) { + t.Fatalf("wrong iter values: %v", values) + } + + empty := NewRange[uint32](1, 0) + values = slices.Collect(empty.Iter()) + if !slices.Equal(values, []uint32{}) { + t.Fatalf("wrong iter values: %v", values) + } +} diff --git a/core/filtermaps/checkpoints_holesky.json b/core/filtermaps/checkpoints_holesky.json index c30856db4f..b8f6be9caf 100644 --- a/core/filtermaps/checkpoints_holesky.json +++ b/core/filtermaps/checkpoints_holesky.json @@ -1,20 +1,21 @@ [ -{"blockNumber": 814411, "blockId": "0xf763e96fc3920359c5f706803024b78e83796a3a8563bb5a83c3ddd7cbfde287", "firstIndex": 67107637}, -{"blockNumber": 914278, "blockId": "0x0678cf8d53c0d6d27896df657d98cc73bc63ca468b6295068003938ef9b0f927", "firstIndex": 134217671}, -{"blockNumber": 1048874, "blockId": "0x3620c3d52a40ff4d9fc58c3104cfa2f327f55592caf6a2394c207a5e00b4f740", "firstIndex": 201326382}, -{"blockNumber": 1144441, "blockId": "0x438fb42850f5a0d8e1666de598a4d0106b62da0f7448c62fe029b8cbad35d08d", "firstIndex": 268435440}, -{"blockNumber": 1230411, "blockId": "0xf0ee07e60a93910723b259473a253dd9cf674e8b78c4f153b32ad7032efffeeb", "firstIndex": 335543079}, -{"blockNumber": 1309112, "blockId": "0xc1646e5ef4b4343880a85b1a4111e3321d609a1225e9cebbe10d1c7abf99e58d", "firstIndex": 402653100}, -{"blockNumber": 1380522, "blockId": "0x1617cae91989d97ac6335c4217aa6cc7f7f4c2837e20b3b5211d98d6f9e97e44", "firstIndex": 469761917}, -{"blockNumber": 1476962, "blockId": "0xd978455d2618d093dfc685d7f43f61be6dae0fa8a9cb915ae459aa6e0a5525f0", "firstIndex": 536870773}, -{"blockNumber": 1533518, "blockId": "0xe7d39d71bd9d5f1f3157c35e0329531a7950a19e3042407e38948b89b5384f78", "firstIndex": 603979664}, -{"blockNumber": 1613787, "blockId": "0xa793168d135c075732a618ec367faaed5f359ffa81898c73cb4ec54ec2caa696", "firstIndex": 671088003}, -{"blockNumber": 1719099, "blockId": "0xc4394c71a8a24efe64c5ff2afcdd1594f3708524e6084aa7dadd862bd704ab03", "firstIndex": 738196914}, -{"blockNumber": 1973165, "blockId": "0xee3a9e959a437c707a3036736ec8d42a9261ac6100972c26f65eedcde315a81d", "firstIndex": 805306333}, -{"blockNumber": 2274844, "blockId": "0x76e2d33653ed9282c63ad09d721e1f2e29064aa9c26202e20fc4cc73e8dfe5f6", "firstIndex": 872415141}, -{"blockNumber": 2530503, "blockId": "0x59f4e45345f8b8f848be5004fe75c4a28f651864256c3aa9b2da63369432b718", "firstIndex": 939523693}, -{"blockNumber": 2781903, "blockId": "0xc981e91c6fb69c5e8146ead738fcfc561831f11d7786d39c7fa533966fc37675", "firstIndex": 1006632906}, -{"blockNumber": 3101713, "blockId": "0xc7baa577c91d8439e3fc79002d2113d07ca54a4724bf2f1f5af937b7ba8e1f32", "firstIndex": 1073741382}, -{"blockNumber": 3221770, "blockId": "0xa6b8240b7883fcc71aa5001b5ba66c889975c5217e14c16edebdd6f6e23a9424", "firstIndex": 1140850360} +{"blockNumber": 814410, "blockId": "0x6c38f0d4ff2c23ae187f581cebb0963c0ec2dbf051b289de1582c369c98a3244", "firstIndex": 67107349}, +{"blockNumber": 914268, "blockId": "0xeff161573a11eb6e2ab930674a5245b2c5ffc5e9e63093503344ec6fa60578a3", "firstIndex": 134216064}, +{"blockNumber": 1048866, "blockId": "0xebd3b95415dad9ab7f2b1d25e48c791e299063c09427bbde54217029c3e215ad", "firstIndex": 201325914}, +{"blockNumber": 1144433, "blockId": "0x0c895438ef12a2c835b4372c209e40a499ba2b18ed0e658846813784de391392", "firstIndex": 268434935}, +{"blockNumber": 1230406, "blockId": "0xd3512e7241efc9853e46b1ad565403d302f62457b6dd84917c31ff375fabf487", "firstIndex": 335544096}, +{"blockNumber": 1309104, "blockId": "0xcf108c6e002e7a5657bf7587adde03edf5f20d03e95b66a194eb8080daaf4f97", "firstIndex": 402653143}, +{"blockNumber": 1380499, "blockId": "0x984b0f8b6bf06f1240bbca8c1df9bef3880bedafd5b5c2a55cbc2f64c9efb974", "firstIndex": 469759822}, +{"blockNumber": 1476950, "blockId": "0x8323b528bb8d80a96b172de92452be0f45078a9ca311cb4be6675f089e25a426", "firstIndex": 536870335}, +{"blockNumber": 1533506, "blockId": "0x737dc416070aa3b522a0c2ab813a70c1820f062c718f27597394f309f0004106", "firstIndex": 603979618}, +{"blockNumber": 1613764, "blockId": "0x9d6a5a505afdda86b1ebcc2b10cb687a1f89c2e2b74315945a3ddc6a0b3c9cd6", "firstIndex": 671088253}, +{"blockNumber": 1719073, "blockId": "0x17bf6a51d9c55a908c3e9e652f80b2aa464b049c697abf3bd5a537e461aff0b9", "firstIndex": 738197366}, +{"blockNumber": 1973133, "blockId": "0x14b288d70e688de3334d09283670301aacfed21c193da8a56fd63767f8177705", "firstIndex": 805305624}, +{"blockNumber": 2274761, "blockId": "0xf02790b273b04219e001d2fcc93e8e47708cb228364e96ad754bc8050d08a9aa", "firstIndex": 872414871}, +{"blockNumber": 2530470, "blockId": "0x157ea98b1a7e66dd3f045da8e25219800671f9a000211d3d94006efd33d89a80", "firstIndex": 939523234}, +{"blockNumber": 2781706, "blockId": "0xa723663a584e280700d2302eba03d1b3b6549333db70c6152576d33e2911f594", "firstIndex": 1006632936}, +{"blockNumber": 3101669, "blockId": "0xa6e66a18fed64d33178c7088f273c404be597662c34f6e6884cf2e24f3ea4ace", "firstIndex": 1073741353}, +{"blockNumber": 3221725, "blockId": "0xe771f897dece48b1583cc1d1d10de8015da57407eb1fdf239fdbe46eaab85143", "firstIndex": 1140850137}, +{"blockNumber": 3357164, "blockId": "0x6252d0aa54c79623b0680069c88d7b5c47983f0d5c4845b6c811b8d9b5e8ff3c", "firstIndex": 1207959453}, +{"blockNumber": 3447019, "blockId": "0xeb7d585e1e063f3cc05ed399fbf6c2df63c271f62f030acb804e9fb1e74b6dc1", "firstIndex": 1275067542} ] - diff --git a/core/filtermaps/checkpoints_mainnet.json b/core/filtermaps/checkpoints_mainnet.json index d2b031a474..ca30280e03 100644 --- a/core/filtermaps/checkpoints_mainnet.json +++ b/core/filtermaps/checkpoints_mainnet.json @@ -1,256 +1,264 @@ [ -{"blockNumber": 4166218, "blockId": "0xdd767e0426256179125551e8e40f33565a96d1c94076c7746fa79d767ed4ad65", "firstIndex": 67108680}, -{"blockNumber": 4514014, "blockId": "0x33a0879bdabea4a7a3f2b424388cbcbf2fbd519bddadf13752a259049c78e95d", "firstIndex": 134217343}, -{"blockNumber": 4817415, "blockId": "0x4f0e8c7dd04fbe0985b9394575b19f13ea66a2a628fa5b08178ce4b138c6db80", "firstIndex": 201326352}, -{"blockNumber": 5087733, "blockId": "0xc84cd5e9cda999c919803c7a53a23bb77a18827fbde401d3463f1e9e52536424", "firstIndex": 268435343}, -{"blockNumber": 5306107, "blockId": "0x13f028b5fc055d23f55a92a2eeecfbcfbda8a08e4cd519ce451ba2e70428f5f9", "firstIndex": 335544094}, -{"blockNumber": 5509918, "blockId": "0x1ed770a58a7b4d4a828b7bb44c8820a674d562b23a6a0139981abe4c489d4dad", "firstIndex": 402652853}, -{"blockNumber": 5670390, "blockId": "0x3923ee6a62e6cc5132afdadf1851ae4e73148e6fbe0a8319cafd2a120c98efa3", "firstIndex": 469761897}, -{"blockNumber": 5826139, "blockId": "0xe61bc6ef03c333805f26319e1688f82553f98aa5e902b200e0621a3371b69050", "firstIndex": 536870853}, -{"blockNumber": 5953029, "blockId": "0x43d710b1b7243b848400975048ccefdfaba091c692c7f01c619d988886cc160f", "firstIndex": 603979580}, -{"blockNumber": 6102846, "blockId": "0xa100b2018f6545cc689656b4b846677b138955b7efd30e850cd14c246430ba18", "firstIndex": 671088291}, -{"blockNumber": 6276718, "blockId": "0xb832ac448b06c104ba50faefd58b0b94d53c0fba5cb268086adad4db99c2f35f", "firstIndex": 738197399}, -{"blockNumber": 6448696, "blockId": "0x48e8ae6f729ad6c76b6cf632bd52a6df7886ed55be09d43c5004fcc1463e533b", "firstIndex": 805305988}, -{"blockNumber": 6655974, "blockId": "0xac395971a6ffc30f807848f68b97b2834f8ea13478a7615860b6a69e3d0823ca", "firstIndex": 872415033}, -{"blockNumber": 6873949, "blockId": "0xc522ddb1113b1e9a87b2bdcb11ce78756beba6454a890122f121a032b5769354", "firstIndex": 939523784}, -{"blockNumber": 7080953, "blockId": "0x3606de577d80120d1edbb64bad7fa6795e788bae342866a98cc58ce2f7575045", "firstIndex": 1006632796}, -{"blockNumber": 7267002, "blockId": "0xad770882a69d216e955e34fef84851e56c0de82deacd6187a7a41f6170cd6c6d", "firstIndex": 1073741045}, -{"blockNumber": 7466708, "blockId": "0x17a48817b3a65aba333a5b56f3ff2e86fbcc19e184b046a5305a5182fdd8eb8a", "firstIndex": 1140850680}, -{"blockNumber": 7661807, "blockId": "0xa74731ee775fbd3f4d9313c68562737dd7c8d2c9eb968791d8abe167e16ddc96", "firstIndex": 1207959112}, -{"blockNumber": 7834556, "blockId": "0xe4b4812448075508cb05a0e3257f91b49509dc78cd963676a633864db6e78956", "firstIndex": 1275068095}, -{"blockNumber": 7990068, "blockId": "0x07bd4ca38abb4584a6209e04035646aa545ebbb6c948d438d4c25bfd9cb205fa", "firstIndex": 1342176620}, -{"blockNumber": 8143032, "blockId": "0x0e3149e9637290b044ee693b8fcb66e23d22db3ad0bdda32962138ba18e59f3f", "firstIndex": 1409285949}, -{"blockNumber": 8297660, "blockId": "0x34cd24f80247f7dfaf316b2e637f4b62f72ecc90703014fb25cb98ad044fc2c0", "firstIndex": 1476394911}, -{"blockNumber": 8465137, "blockId": "0x4452fa296498248d7f10c9dc6ec1e4ae7503aa07f491e6d38b21aea5d2c658a8", "firstIndex": 1543503744}, -{"blockNumber": 8655820, "blockId": "0x7bdb9008b30be420f7152cc294ac6e5328eed5b4abd954a34105de3da24f3cc6", "firstIndex": 1610612619}, -{"blockNumber": 8807187, "blockId": "0xde03e3bfddc722c019f0b59bc55efabcd5ab68c6711f4c08d0390a56f396590d", "firstIndex": 1677721589}, -{"blockNumber": 8911171, "blockId": "0xe44f342de74ab05a2a994f8841bdf88f720b9dc260177ba4030d0f7077901324", "firstIndex": 1744830310}, -{"blockNumber": 8960320, "blockId": "0x79764f9ff6e0fe4848eda1805687872021076e4e603112861af84181395ac559", "firstIndex": 1811938893}, -{"blockNumber": 9085994, "blockId": "0x24a101d1c8a63367a0953d10dc79c3b587a93bd7fd382084708adefce0b8363f", "firstIndex": 1879047965}, -{"blockNumber": 9230924, "blockId": "0xb176a98d3acd855cbb75265fb6be955a8d51abc771e021e13275d5b3ecb07eeb", "firstIndex": 1946156668}, -{"blockNumber": 9390535, "blockId": "0x640f5e2d511a5141878d57ae7a619f19b72a2bd3ef019cf0a22d74d93d9acf07", "firstIndex": 2013265733}, -{"blockNumber": 9515674, "blockId": "0xff4a7b6b21aeaeb6e1a75ecd22b1f34c058a0ce1477ce90a8ce78165fd1d0941", "firstIndex": 2080374553}, -{"blockNumber": 9659426, "blockId": "0xc351455249343b41e9171e183612b68c3c895271c62bd2c53d9e3ab1aa865aa1", "firstIndex": 2147483567}, -{"blockNumber": 9794018, "blockId": "0xde98035b4b7f9449c256239b65c7ff2c0330de44dee190106d0a96fb6f683238", "firstIndex": 2214592213}, -{"blockNumber": 9923840, "blockId": "0x881da313a1e2b6fab58a1d6fa65b5dacfdc9d68a3112a647104955b5233f84e3", "firstIndex": 2281701302}, -{"blockNumber": 10042435, "blockId": "0x451f6459640a6f54e2a535cc3a49cfc469861da3ddc101840ab3aef9e17fa424", "firstIndex": 2348810174}, -{"blockNumber": 10168883, "blockId": "0x5d16ff5adf0df1e4dc810da60af37399ef733be7870f21112b8c2cfff4995dd9", "firstIndex": 2415918783}, -{"blockNumber": 10289554, "blockId": "0x85d5690f15a787c43b9a49e8dd6e324f0b3e0c9796d07c0cfb128e5c168f5488", "firstIndex": 2483027930}, -{"blockNumber": 10386676, "blockId": "0x20f675ea72db448024a8a0b8e3ec180cac37a5910575bc32f8d9f5cdfe3c2649", "firstIndex": 2550136212}, -{"blockNumber": 10479675, "blockId": "0x014abb07acf2330cc78800ca1f564928f2daccca4b389bf5c59f4b840d843ec0", "firstIndex": 2617245218}, -{"blockNumber": 10562661, "blockId": "0xd437607a3f81ce8b7c605e167ce5e52bf8a3e02cdc646997bd0ccc57a50ad7d1", "firstIndex": 2684354520}, -{"blockNumber": 10641508, "blockId": "0x2e8ab6470c29f90ac23dcfc58310f0208f5d0e752a0c7982a77a223eca104082", "firstIndex": 2751462730}, -{"blockNumber": 10717156, "blockId": "0x8820447b6429dd12be603c1c130be532e9db065bb4bc6b2a9d4551794d63789a", "firstIndex": 2818571831}, -{"blockNumber": 10784549, "blockId": "0xc557daab80a7cdc963d62aa881faf3ab1baceff8e027046bcd203e432e0983b3", "firstIndex": 2885680800}, -{"blockNumber": 10848651, "blockId": "0xede1b0de5db6685a6f589096ceb8fccb08d3ff60e8b00a93caa4a775b48e07fc", "firstIndex": 2952789740}, -{"blockNumber": 10909166, "blockId": "0x989db675899d13323006a4d6174557e3c5501c672afd60d8bd902fc98d37e92e", "firstIndex": 3019897599}, -{"blockNumber": 10972902, "blockId": "0x5484050cc2c7d774bc5cd6af1c2ef8c19d1de12dabe25867c9b365924ea10434", "firstIndex": 3087007422}, -{"blockNumber": 11036597, "blockId": "0x1e3686e19056587c385262d5b0a07b3ec04e804c2d59e9aaca1e5876e78f69ae", "firstIndex": 3154116231}, -{"blockNumber": 11102520, "blockId": "0x339cf302fe813cce3bb9318b860dfa8be7f688413f38a6ea1987a1b84d742b4b", "firstIndex": 3221224863}, -{"blockNumber": 11168162, "blockId": "0xc0fa21ea090627610bcac4732dff702633f310cabafc42bc500d3d4805198fe0", "firstIndex": 3288334273}, -{"blockNumber": 11233707, "blockId": "0x491c37a479b8cf22eaa3654ae34c5ddc4627df8c58ca8a6979159e1710428576", "firstIndex": 3355442691}, -{"blockNumber": 11300526, "blockId": "0xb7366d2a24df99002cffe0c9a00959c93ef0dcfc3fd17389e2020bf5caa788eb", "firstIndex": 3422551480}, -{"blockNumber": 11367621, "blockId": "0xce53df5080c5b5238bb7717dfbfd88c2f574cfbb3d91f92b57171a00e9776cd2", "firstIndex": 3489660710}, -{"blockNumber": 11431881, "blockId": "0x2a08ff9c4f6fd152166213d902f0870822429f01d5f90e384ac54a3eac0ceb3a", "firstIndex": 3556768626}, -{"blockNumber": 11497107, "blockId": "0x1f99c6b65f2b1cb06ed1786c6a0274ff1b9eacab6cb729fcd386f10ebbd88123", "firstIndex": 3623878389}, -{"blockNumber": 11560104, "blockId": "0xebe6924817bbdfe52af49667da1376bae5a2994b375d4b996e8ff2683744e37a", "firstIndex": 3690986640}, -{"blockNumber": 11625129, "blockId": "0xbe6eee325329ee2fe632d8576864c29dd1c79bab891dc0a22d5b2ac87618d26e", "firstIndex": 3758095773}, -{"blockNumber": 11690397, "blockId": "0xc28bf55f858ddf5b82d1ceb3b5258b90a9ca34df8863a1c652c4d359f5748fdf", "firstIndex": 3825204492}, -{"blockNumber": 11755087, "blockId": "0x0c10cde6ce1bbe24dc57347fe4aaebc17b7d8e8d7d97e3db573133477f494740", "firstIndex": 3892314051}, -{"blockNumber": 11819674, "blockId": "0x36b694a1776c94e4c6ae4a410931b2086de47a83e437517040e3290ce9afff67", "firstIndex": 3959422445}, -{"blockNumber": 11883358, "blockId": "0x21f447aca9ddf94ed71df9fa3648a12acc2ba603f89f24c4784936864c41945f", "firstIndex": 4026531743}, -{"blockNumber": 11948524, "blockId": "0x71a52b6cce80d3a552b0daa18beb952facf81a89bc7ca769d08ac297f317507a", "firstIndex": 4093640009}, -{"blockNumber": 12013168, "blockId": "0x9a7fb369b8d8cd0edd0d890d636096f20c63abb7eb5798ad1e578cac599e3db8", "firstIndex": 4160748475}, -{"blockNumber": 12078711, "blockId": "0x5de09329413b0c2f58d926f225197552a335ba3d5544d7bdb45e7574f78c9b8d", "firstIndex": 4227858275}, -{"blockNumber": 12143640, "blockId": "0xbeafc0e1e0586f5a95f00f2a796d7df122c79c187aa2d917129297f24b8306bd", "firstIndex": 4294967145}, -{"blockNumber": 12208005, "blockId": "0x052487095cdd4a604808e6c14e30fb68b3fa546d35585b315f287219d38ef77c", "firstIndex": 4362075289}, -{"blockNumber": 12272465, "blockId": "0x82c8a50413bd67a0d6f53b085adcd9ae8c25ecc07ed766fa80297a8dcae63b29", "firstIndex": 4429184610}, -{"blockNumber": 12329418, "blockId": "0x294c147e48d32c217ff3f27a3c8c989f15eee57a911408ec4c28d4f13a36bb3b", "firstIndex": 4496292968}, -{"blockNumber": 12382388, "blockId": "0x8c2555965ff735690d2d94ececc48df4700e079c7b21b8e601a30d4e99bc4b5b", "firstIndex": 4563401809}, -{"blockNumber": 12437052, "blockId": "0x2e38362031f36a0f3394da619dcc03be03c19700594cbd1df84c2c476a87de63", "firstIndex": 4630511012}, -{"blockNumber": 12490026, "blockId": "0x122749c02a55c9c2a1e69068f54b6c1d25419eb743e3553aba91acf1daeadc35", "firstIndex": 4697619920}, -{"blockNumber": 12541747, "blockId": "0xfb9f12aa2902da798ac05fab425434f8c7ce98050d67d416dbb32f98c21f66f7", "firstIndex": 4764728267}, -{"blockNumber": 12597413, "blockId": "0x9a7a399c2904ac8d0fec580550525e7e1a73d8f65f739bf7c05d86e389d0d3f7", "firstIndex": 4831837757}, -{"blockNumber": 12651950, "blockId": "0xb78dcb572cdafb9c4e2f3863ef518a3b2df0cd4f76faa26a423b2ca0c1cde734", "firstIndex": 4898946491}, -{"blockNumber": 12706472, "blockId": "0xfd21f41ec6b0c39287d7d48c134d1212a261c53d65db99739994b003150bbad1", "firstIndex": 4966054796}, -{"blockNumber": 12762929, "blockId": "0xc94d994bc40b2ae7dc23cf2b92cc01e84915f090bb57c0d9a67584bd564d3916", "firstIndex": 5033164307}, -{"blockNumber": 12816689, "blockId": "0x7770c72f22cbf6ccf7ab85d203088f7ede89632cf0042c690102f926a90bd09d", "firstIndex": 5100273412}, -{"blockNumber": 12872408, "blockId": "0x2e008b8c952d828875d777f7912f472af96ffc977f2ceae884006682cab6b8ed", "firstIndex": 5167381625}, -{"blockNumber": 12929718, "blockId": "0x85eb0ed3c5910c6a01b65ef0a5b76c59c2cdb5094e6e27eb87c751d77bcc2c88", "firstIndex": 5234491305}, -{"blockNumber": 12988757, "blockId": "0xdf12045bea73af18d4e71f8be8e334160f78b85f96a3535a4056409d8b61355a", "firstIndex": 5301600237}, -{"blockNumber": 13049172, "blockId": "0xf07608d97a101cd9a95fee9d9062a15bcb333263e555f8cfa31da037e0468f30", "firstIndex": 5368709080}, -{"blockNumber": 13108936, "blockId": "0x42739341db582d2f39b91ec9e8cc758777ca3f6ff9f25cd98883619fd5f026a7", "firstIndex": 5435817013}, -{"blockNumber": 13175495, "blockId": "0x564f25eacb229350b7c648b5828169e7a0344ae62e866206828e2cfad8947f10", "firstIndex": 5502926476}, -{"blockNumber": 13237721, "blockId": "0x0973425abec0fa6319701b46e07c2373b0580e3adbed6900aad27d5bf26dcb95", "firstIndex": 5570035419}, -{"blockNumber": 13298771, "blockId": "0xf3a16fec5be808c9f7782fb578dc8cef7f8e2110f7289bd03c0cc13977dd1518", "firstIndex": 5637143840}, -{"blockNumber": 13361281, "blockId": "0x3c0b6364201ca9221b61af3de27a3a87e111870b8c7efc43a6d8496e98c68690", "firstIndex": 5704253046}, -{"blockNumber": 13421819, "blockId": "0x2f472e57997b95558b99e3e5e7e0e8d4dbf8b71c081aac6536c9ff5925dac2ce", "firstIndex": 5771361231}, -{"blockNumber": 13480620, "blockId": "0xc4d689e87464a0c83c661c8e3a0614c370631de857f7e385b161dfe8bacd3e71", "firstIndex": 5838469468}, -{"blockNumber": 13535793, "blockId": "0xe7674bacc8edce9fb3efd59b92c97da48fe7ace1de314b4a67d7d032fc3bb680", "firstIndex": 5905578026}, -{"blockNumber": 13590588, "blockId": "0x6a3e86bdce7dd7d8792e1af9156edd8c3ffee7c20fed97001f58a9a2699f6594", "firstIndex": 5972687757}, -{"blockNumber": 13646707, "blockId": "0xab404a5d3709cf571b04e9493f37116eeb5dd2bc9dc10c48387c1e0199013d69", "firstIndex": 6039797165}, -{"blockNumber": 13703025, "blockId": "0x20e2fde15b8fe56f5dd7ab0f324c552038167ed44864bf3978e531ae68d6d138", "firstIndex": 6106905803}, -{"blockNumber": 13761024, "blockId": "0x2ae49275e13e780f1d29aea8507b2a708ff7bfe977efac93e050273b8b3a8164", "firstIndex": 6174015107}, -{"blockNumber": 13819468, "blockId": "0xb9d19cb31dedb1128b11cad9ffd6e58c70fe7ba65ba68f1ac63668ac5160ad85", "firstIndex": 6241124350}, -{"blockNumber": 13877932, "blockId": "0x80b1ff0bb069a8479360a15eaa84ba30da02cfacadc564837f4b1c90478addb8", "firstIndex": 6308232256}, -{"blockNumber": 13935384, "blockId": "0xe1f5469a559a6114dd469af61b118b9d9551a69bbd49a4e88f2a2d724830c871", "firstIndex": 6375341632}, -{"blockNumber": 13994042, "blockId": "0x25188fb75f2328c870ade7c38ef42ff5fddef9c4e364eebe4c5d8d9cc3ecabab", "firstIndex": 6442449799}, -{"blockNumber": 14051123, "blockId": "0xf4ef2bce9ee9222bdcf6b3a0c204676d9345e211e10c983e523930274e041ef1", "firstIndex": 6509559107}, -{"blockNumber": 14109189, "blockId": "0x80b730c28f75d8cb5ec2fb736341cd87cb4ecb2c9c614e0a4ecc0f9812675d50", "firstIndex": 6576667347}, -{"blockNumber": 14166822, "blockId": "0xf662a24b91684fa8ac462b31071f406de8d6183dba46d30d690f4407bc6af36f", "firstIndex": 6643777079}, -{"blockNumber": 14222488, "blockId": "0x7333e324c96b12f11a38d1fc2ddb4860e018b90f5dc10f3dbe19f7679bb95535", "firstIndex": 6710885890}, -{"blockNumber": 14277180, "blockId": "0x4373c1000e8e10179657689e2f0e42f88bd1601ecb4a5d83970d10287f6654cc", "firstIndex": 6777994595}, -{"blockNumber": 14331080, "blockId": "0x9c708a750a3f284ec0ee950110b36fd488cb1ec24cd0c2ea72c19551ec5c42a5", "firstIndex": 6845103719}, -{"blockNumber": 14384243, "blockId": "0x34ce7503b76335aa18dec880b0cefd388a29e0fcff6f2e1ddda8fb8c0ac1daf0", "firstIndex": 6912212376}, -{"blockNumber": 14437670, "blockId": "0x79842efd3e406b41f51935fe2e6ad20a7dd5a9db2280ebd7f602ed93da1e3c24", "firstIndex": 6979320543}, -{"blockNumber": 14489204, "blockId": "0xcd12addf0afdc229e9fe3bd0a34677a3826c5e78d4baf715f8ed36b736d6627a", "firstIndex": 7046430591}, -{"blockNumber": 14541688, "blockId": "0x55f617abf208a73fc467e8cb5feead586b671dbb0f6281570b3c44b8eabb2b9e", "firstIndex": 7113538755}, -{"blockNumber": 14594551, "blockId": "0xc7211bf772e93c8c2f945fcb6098b47c3455604cb8b94a505cb5cb720914c369", "firstIndex": 7180646025}, -{"blockNumber": 14645065, "blockId": "0x6d5b0326f4b22e2b0196986a514f23ec6e9a62f70f53300a22b21ff661a6ef7e", "firstIndex": 7247756883}, -{"blockNumber": 14695926, "blockId": "0x0a77272250e43b4bb46c02eb76944881a3c6b00a21bb9086a8229199bd62d97a", "firstIndex": 7314865843}, -{"blockNumber": 14746330, "blockId": "0xd677fdbaf8efb1bfdc138ac6b2bd5d0e890a29acb1f52f40169181ad517b0d31", "firstIndex": 7381974956}, -{"blockNumber": 14798546, "blockId": "0xbb277e8623acd2ce2340cf32f6c0ddab70fd95d862287f68a3c37250a70619cd", "firstIndex": 7449082890}, -{"blockNumber": 14848230, "blockId": "0x587b39f11bdaa2091291c7c3947e88df2e91e7997f2375dfd43b6e310a538582", "firstIndex": 7516192636}, -{"blockNumber": 14897646, "blockId": "0xf5b5c9d0c024ca0c0f0c6171871f609687f4ccb064ededbd61176cf23a9011e8", "firstIndex": 7583299602}, -{"blockNumber": 14950782, "blockId": "0x50549486afaf92a4c3520012b325e914ef77a82e4d6530a71f9b1cca31bfae18", "firstIndex": 7650409868}, -{"blockNumber": 15004101, "blockId": "0x7edac55dea3ee4308db60b9bc0524836226fe301e085b3ce39105bd145ba7fc3", "firstIndex": 7717517503}, -{"blockNumber": 15056903, "blockId": "0xb4cfd02d435718598179cdba3f5c11eb8653fe97ec8d89c60673e3e07b8dfc94", "firstIndex": 7784627997}, -{"blockNumber": 15108302, "blockId": "0x53c77a7de4515e9e93467a76f04cc401834bcdd64e9dfa03cf6d2844a6930293", "firstIndex": 7851736988}, -{"blockNumber": 15159526, "blockId": "0x1a31ad84b423254d7ff24e7eca54048ed8cc13cec5eb7289bf3f98ed4de9f724", "firstIndex": 7918844431}, -{"blockNumber": 15211013, "blockId": "0xe5d491e1d6cc5322454143b915c106be1bf28114a41b054ba5e5cfe0abecafba", "firstIndex": 7985953942}, -{"blockNumber": 15264389, "blockId": "0xd9939bb9e58e95d2672c1148b4ec5730204527d3f3fc98ca03a67dc85cf3d710", "firstIndex": 8053063187}, -{"blockNumber": 15315862, "blockId": "0x7254f99c4bb05235d5b437984c9132164e33182d4ce11a3847999da5c28b4092", "firstIndex": 8120172147}, -{"blockNumber": 15364726, "blockId": "0x11b57547579d9009679e327f57e308fe86856391805bc3c86e7b39daae890f52", "firstIndex": 8187281042}, -{"blockNumber": 15412886, "blockId": "0xbe3602b1dbef9015a3ec7968ac7652edf4424934b6bf7b713b99d8556f1d9444", "firstIndex": 8254390023}, -{"blockNumber": 15462792, "blockId": "0x3348ca4e14ac8d3c6ac6df676deaf3e3b5e0a11b599f73bd9739b74ebd693efe", "firstIndex": 8321499024}, -{"blockNumber": 15509914, "blockId": "0xbc98fd6b71438d5a169f9373172fea799fa3d22a8e6fe648d35e1070f2261113", "firstIndex": 8388606521}, -{"blockNumber": 15558748, "blockId": "0x5fa2cf499276ae74a5b8618990e71ed11a063619afe25c01b46e6252eba14c19", "firstIndex": 8455716577}, -{"blockNumber": 15604217, "blockId": "0x78a608e13d2eb3c5fed81a19b829ede88071cf01ea9ff58112a7472435f97c30", "firstIndex": 8522825668}, -{"blockNumber": 15651869, "blockId": "0xd465d861d925d1475440782ff16c2b3361ba3c8e169d7cc90eb8dfc0f31b0aac", "firstIndex": 8589934080}, -{"blockNumber": 15700968, "blockId": "0x71e3def131271e02c06ca945d14a995703a48faac1334a9e2e2321edd0b504d0", "firstIndex": 8657043390}, -{"blockNumber": 15762986, "blockId": "0x9b1b51dca2eae29162ca66968a77b45175f134b44aea3defadcb924f83e0b944", "firstIndex": 8724151376}, -{"blockNumber": 15814455, "blockId": "0x3c04a509cb6304d3df4bef57e0119d9e615ab737ec0b4a7deada6e5f57d9f873", "firstIndex": 8791260562}, -{"blockNumber": 15865639, "blockId": "0x9e9e26148c774518ecf362c0e7c65a5c1b054a8a3e4e36036c70e273fac6147c", "firstIndex": 8858368894}, -{"blockNumber": 15920564, "blockId": "0x9efe1d4dbfd9aa891ac0cffd3e1422a27ba2ea4add211b6900a2242cdb0f0ca0", "firstIndex": 8925477950}, -{"blockNumber": 15974371, "blockId": "0xc63ccef7bc35a0b431a411f99fe581b322d00cfc6422d078696808a5658a32ac", "firstIndex": 8992587107}, -{"blockNumber": 16032913, "blockId": "0x3e60957224964669a8646914e3166553b9f4256d5be160b17995d838af3ef137", "firstIndex": 9059696632}, -{"blockNumber": 16091057, "blockId": "0x12b346047bb49063ab6d9e737775924cf05c52114202ddb1a2bdaf9caabbfe0c", "firstIndex": 9126804912}, -{"blockNumber": 16150977, "blockId": "0x49318a32ff0ce979c4061c1c34db2a94fb06e7669c93742b75aff14a134fa598", "firstIndex": 9193913896}, -{"blockNumber": 16207432, "blockId": "0xf7870865edf81be4389a0be01468da959de703df0d431610814d16ed480176e4", "firstIndex": 9261019778}, -{"blockNumber": 16262582, "blockId": "0x25818e0f4d54af6c44ef7b23add34409a47de3ab1c905889478f3ec8ad173ec3", "firstIndex": 9328131320}, -{"blockNumber": 16319695, "blockId": "0x25de4b1c18cc503f5d12b4fa9072d33a11fa503a3dbeb9ab3d016b57c1e5cd4d", "firstIndex": 9395240790}, -{"blockNumber": 16373605, "blockId": "0x3794a5e0d2aa10baf1e6a5ec623d6089fdd39799eff633017d8df5144526939f", "firstIndex": 9462349509}, -{"blockNumber": 16423494, "blockId": "0xe0217d947ba3865dfc9288e0c890b0996457bb9d18467bd125e86bbb0052b57f", "firstIndex": 9529458033}, -{"blockNumber": 16474853, "blockId": "0xd454f033d190f22f9e56f0209ea1eeb3b6257805d5d88650d2759eb4d24821b7", "firstIndex": 9596567055}, -{"blockNumber": 16525689, "blockId": "0x8a23cbbf3e258e13f5a1ada434366796cb4a3e5b1062455582fb2bc3ab991541", "firstIndex": 9663674943}, -{"blockNumber": 16574203, "blockId": "0xc1a5b7d26e8222bd2d56ef4108f75d69f7c116707d348950834e00962241a4f8", "firstIndex": 9730785112}, -{"blockNumber": 16622622, "blockId": "0x3ddb3ef7a4309bd788258fb0d62613c89a0b4de715f4e12f6017a194d19d6481", "firstIndex": 9797893665}, -{"blockNumber": 16672585, "blockId": "0x8aa5e9f72b261f9e2a9eb768483d1bbd84d3a88fdb1346f6a9a7f262fd28ba41", "firstIndex": 9865002893}, -{"blockNumber": 16720124, "blockId": "0x2128f8baf264166e37554d5c31a06de58d9ccfb663117358251da548a23a060f", "firstIndex": 9932111275}, -{"blockNumber": 16769162, "blockId": "0x6b3e849482d3222032740ad6b8f98e24636c82682a6a3572b1ef76dfebc66821", "firstIndex": 9999217824}, -{"blockNumber": 16818311, "blockId": "0xe45f57381978a2bfc85bd20af1c41e2b630412642ac4f606b477f05f030ef5d9", "firstIndex": 10066328668}, -{"blockNumber": 16869531, "blockId": "0xa154555266d24dc1f4885af5fafcf8cab3de788998cf69e1d28f56aa13a40c43", "firstIndex": 10133437302}, -{"blockNumber": 16921611, "blockId": "0xf1f829b4ab5eec6e243916dd530993fa11eef5510fd730e8d09ead6b380355a1", "firstIndex": 10200547185}, -{"blockNumber": 16974870, "blockId": "0x1a33202b95926ae4cb8e6e99d8d150f3c50d817b3a316452bdf428c971dabde5", "firstIndex": 10267655914}, -{"blockNumber": 17031277, "blockId": "0x706c9dd0dc81e7ac29d2ea0f826e6b8a1dcb5adb1b904ff6e43260729c9fd0a7", "firstIndex": 10334764934}, -{"blockNumber": 17086330, "blockId": "0x085a80cafe96b520105b9a1f8e7a2bbc9474da24da7e6344ca7c4d32db822f92", "firstIndex": 10401871892}, -{"blockNumber": 17141311, "blockId": "0x33ec6513dfa515bc5f6356476b4eb075a8064181d6aaf6aa1a1e18887e342f74", "firstIndex": 10468982364}, -{"blockNumber": 17190907, "blockId": "0x6f41273d3bf30d3347e7eb68872a49b3ac947f314543478be7a28a55e5c41a3c", "firstIndex": 10536090817}, -{"blockNumber": 17237199, "blockId": "0x9a87a14a128c0345a366940f821a14f16719de628658ac0628e410a72d723e90", "firstIndex": 10603200178}, -{"blockNumber": 17287181, "blockId": "0x9c6e78adcf562ac63c103e3e5a02f025023079aca79bdd6ef18f7bd2a6271c29", "firstIndex": 10670309183}, -{"blockNumber": 17338652, "blockId": "0x1b747da97b2397a293602af57514dab4ca1010bb6c601ff05cb2012dd1124ebb", "firstIndex": 10737418023}, -{"blockNumber": 17389337, "blockId": "0xbc3c0ca1e5989605b9b59c94b418562eb17ccbce30e45ac8531cf0b3867a6b2c", "firstIndex": 10804522857}, -{"blockNumber": 17442261, "blockId": "0x1ec341be1cbd09f559bfa3d3e39a341d8e21052eeb7880931d43d086651733b7", "firstIndex": 10871635535}, -{"blockNumber": 17497787, "blockId": "0x6069880d486f2548599df1e14e12752d3eb9bc99843a98cd6631c22be1b58554", "firstIndex": 10938744657}, -{"blockNumber": 17554322, "blockId": "0x69b2564bc00b1f310f6b416912869d7530d7864bf7d70d55c7ace554f129b989", "firstIndex": 11005852829}, -{"blockNumber": 17608492, "blockId": "0x7d590653d5fa52c0d3ee453a77d2088504f57adcef35cd57c567afb554608457", "firstIndex": 11072961972}, -{"blockNumber": 17664272, "blockId": "0xdc16159d3500cdc7410873102f41fc55de2a8a41e3779c4b70e6224a541e2b9e", "firstIndex": 11140070967}, -{"blockNumber": 17715101, "blockId": "0x655e33c4e81182464ea0b0e1fdbc53ce53902431db5107326b816091a4564652", "firstIndex": 11207179487}, -{"blockNumber": 17764042, "blockId": "0x54439184f31cd83ba06b48b6dbfdd744ae7246355be1327b44744058711d05c0", "firstIndex": 11274287303}, -{"blockNumber": 17814383, "blockId": "0xfb453bc951360c76fb09bb1b9a3e39d23ececa0adb93368cc3f41f0457845089", "firstIndex": 11341397984}, -{"blockNumber": 17864648, "blockId": "0x32a68823ef4ec0cbab2fe50c97e3f462b575e8b117da40d00c710b4c66ee1d6d", "firstIndex": 11408505657}, -{"blockNumber": 17913366, "blockId": "0x04b944aab8a4ff91b77c2191817cf051766100c227616a3746af53407e740124", "firstIndex": 11475614351}, -{"blockNumber": 17961690, "blockId": "0x08bee7cc0b764106ca01dd5370b617879487ffb423688c96e948dce125990f45", "firstIndex": 11542723488}, -{"blockNumber": 18011048, "blockId": "0x94c39d3a64f3e9a91b1d98554cd29e1390e30fa61cfa4e909c503eee2fd9f165", "firstIndex": 11609833142}, -{"blockNumber": 18061209, "blockId": "0x2ee9ade68955c030488c8a30537bdf948355f7dd5ae64942b5bfce1be6650e19", "firstIndex": 11676941316}, -{"blockNumber": 18111692, "blockId": "0xd6c4fd0c1cc20ed5e7960bb5043e9e5e9c66a4d2ec5709ac9797fff678435640", "firstIndex": 11744050346}, -{"blockNumber": 18166212, "blockId": "0x3262588c2ef79a3b3f6a3db6435202d22f5667cd48c136b0797404901525c9ff", "firstIndex": 11811159686}, -{"blockNumber": 18218743, "blockId": "0x935bd9a4164ff7ecd09a37b916ce5bf78487bd19377b5b17be153e39318aee74", "firstIndex": 11878268593}, -{"blockNumber": 18271236, "blockId": "0xe58ebb821f27e3665898f390802a3d129d217b3a3ee36d890a85cf22a0a8aa33", "firstIndex": 11945376750}, -{"blockNumber": 18323007, "blockId": "0x3997a841468efa1bc614bfc3de4502274901b04b428f87a1f3086dfd78cda1eb", "firstIndex": 12012485748}, -{"blockNumber": 18372443, "blockId": "0xc44a13a5d02e8dc39f355de5e21ce7bb311ce7f4d9114ff480dce235a169e416", "firstIndex": 12079595370}, -{"blockNumber": 18421829, "blockId": "0x7da63a0b613d8745597b2ac64fd5cc8b2fb14b24d163b12a0a39d7d3d4ff7b5c", "firstIndex": 12146703582}, -{"blockNumber": 18471706, "blockId": "0xd632a1893f415ff618f4b612a7687e6af1f12feeed81f46f0022090829c1eb4c", "firstIndex": 12213812677}, -{"blockNumber": 18522301, "blockId": "0x44fa2cf08145ae40e8e42f4e6b4ab7df360a17c5a065ce45fcc41b51bee011f4", "firstIndex": 12280921639}, -{"blockNumber": 18572935, "blockId": "0x72b8ab4c78c90425ee054b4806a8be703da0febdf1d51866358ec2bd21ba9529", "firstIndex": 12348029751}, -{"blockNumber": 18623431, "blockId": "0x8c4cb2f13501d9788820280c6f16692d0737258c3896f1e4bded32d838febf7f", "firstIndex": 12415138965}, -{"blockNumber": 18675470, "blockId": "0x523b73c19ea8b3ae32ef141a83ef9855e667ebf51443cfcabd1a06659359062a", "firstIndex": 12482247454}, -{"blockNumber": 18725728, "blockId": "0x0cfbd131eb5dad51488238079fba29a63eebb5c32d1a543cb072e48dc2104ef3", "firstIndex": 12549356369}, -{"blockNumber": 18778387, "blockId": "0xc4906c77af8058b9f172a4f0e8788c7887f05caa5ac752b38b5387080f74ae49", "firstIndex": 12616465992}, -{"blockNumber": 18835044, "blockId": "0x49c5e07f409a841dc81f3ef8417f1951f8fcc13c90134f9d2a0cd11938f9fa36", "firstIndex": 12683575082}, -{"blockNumber": 18883308, "blockId": "0x386a58dd5f79a419eeb05075b07b3ff3bc836a265c9688854a504223b1d6a830", "firstIndex": 12750683753}, -{"blockNumber": 18933635, "blockId": "0xd3881292147589bd2e192769e5c9175b5d03a453fe1ef3c4b5b6858ac9402a2f", "firstIndex": 12817792470}, -{"blockNumber": 18988254, "blockId": "0xcbe72dfa15428ac21b9c59c703ceaa0eb4b2205927687261d7aaed3dbb3783ea", "firstIndex": 12884882858}, -{"blockNumber": 19041325, "blockId": "0x92b077e1c2f8819da728f0307c914fdcd57eba14ea07d9a45c28d1ed8ffff576", "firstIndex": 12952010530}, -{"blockNumber": 19089163, "blockId": "0x43f8ab2d3dfc34c8e18cba903074d54e235dc546f19c4eb78245a522c266c84e", "firstIndex": 13019119228}, -{"blockNumber": 19140629, "blockId": "0xab7b7ae5424b18105a13b657fa6099d4ab67fde5baff39fe6e4de707397e995c", "firstIndex": 13086228236}, -{"blockNumber": 19192118, "blockId": "0x451327e6a5cf6ce1c8c14c01687dc5f719f3c2176f46bac4f264616256e30d1c", "firstIndex": 13153337116}, -{"blockNumber": 19237836, "blockId": "0x9b260d6be369557d1dc88aca423e2697e697d941d1b726c183015b5649e248c8", "firstIndex": 13220445421}, -{"blockNumber": 19291271, "blockId": "0x4878c28d79e1f71bc11e062eb61cb52ae6a18b670b0f9bea38b477944615078e", "firstIndex": 13287554254}, -{"blockNumber": 19344448, "blockId": "0x56243b9ad863bf90953fe9aa6e64a426629384db1190e70dce79575d30595f7e", "firstIndex": 13354663659}, -{"blockNumber": 19394948, "blockId": "0x195173b64dda7908d6aa39a63c8bdd29ec181d401e369d513be1308550d0ddcb", "firstIndex": 13421771935}, -{"blockNumber": 19443075, "blockId": "0xd39c1d60996475e65d1ab5b4e755f510ca466564a8155d35db6667988d6c0e44", "firstIndex": 13488880427}, -{"blockNumber": 19488383, "blockId": "0x28956eb8856fa8db59c02585016b8baf43bc44bc35b00bdaf8a6babe51101c5c", "firstIndex": 13555977105}, -{"blockNumber": 19534584, "blockId": "0x2421c97b0f140185d4c20943cd4ed7d7424468482feb76e3003a1cc69da3fd7b", "firstIndex": 13623097580}, -{"blockNumber": 19579602, "blockId": "0x25f96529028e9f51c59aec9ce8de282b7dd67066fd46a1694130698ed0f40d8b", "firstIndex": 13690207623}, -{"blockNumber": 19621517, "blockId": "0x4f6f6e0a0488f3d51823bc4b07c292348c259b1866968f77ee76b66b37101c75", "firstIndex": 13757315529}, -{"blockNumber": 19665085, "blockId": "0x00f9315f89681b44bff46f1bad8894bc6dfae1c459d3d6520f9881861304a496", "firstIndex": 13824425382}, -{"blockNumber": 19709229, "blockId": "0x24e022b21ae1ba8a3e8c87cb9734aa1d1810fc4a69fe147d3ebb1ff0df8bcc15", "firstIndex": 13891534799}, -{"blockNumber": 19755387, "blockId": "0x77f184b7183b1a351760d242041249464b42cfaa6fbc4326f352b06bb3b21a02", "firstIndex": 13958642483}, -{"blockNumber": 19803894, "blockId": "0xf37eb1b054a6d61272940361f386eb744cded84d15c3250a7eabadede257371c", "firstIndex": 14025751618}, -{"blockNumber": 19847885, "blockId": "0x4659649fa8a3b4bbe8978673ba9a22ae20352c7052b676d373b5a51b1967ffa4", "firstIndex": 14092848654}, -{"blockNumber": 19894193, "blockId": "0x15606bdc0f1a710bd69443c7154d4979aece9329977b65990c9b39d6df84ed5c", "firstIndex": 14159970181}, -{"blockNumber": 19938551, "blockId": "0x6a8f4571924ed902bd8e71bf8ed9cc9d72cabeabc410277c8f0fc2b477d00eb7", "firstIndex": 14227077892}, -{"blockNumber": 19985354, "blockId": "0x7b6fb6376410b4d9e5d7ee02f78b2054e005dd2976eea47fc714f66b967dc285", "firstIndex": 14294187965}, -{"blockNumber": 20028440, "blockId": "0x9b37440b71c24756b8855b8012432b84276ae94c80aa1ccc8b70a7705992103c", "firstIndex": 14361296503}, -{"blockNumber": 20071780, "blockId": "0xa2ed129f343f3d60419772ec5635edcd36b8680c9419b6626e2bc84b230c709b", "firstIndex": 14428405230}, -{"blockNumber": 20113832, "blockId": "0xe7a610e8bcbf8ded141ebc7142de03dfc54b1bcc79e3bf8d07fad4e42b665bba", "firstIndex": 14495512019}, -{"blockNumber": 20156854, "blockId": "0xbe09704f65a70ef8843d9c8e511ddc989ea139dbe94cdfe37f52b03620d62385", "firstIndex": 14562622430}, -{"blockNumber": 20200135, "blockId": "0x9a58c34d5f77342e94065d119905c000223cd988c4b11f1539fff20737159630", "firstIndex": 14629731923}, -{"blockNumber": 20244389, "blockId": "0x1e733f0db9ef21183107259b3c2408c78fa5a01469928cd295f3ea7e8eedda45", "firstIndex": 14696840011}, -{"blockNumber": 20288489, "blockId": "0xb5ad7edd86b181226c8c7be0a08069e3955234e797426843fff9de0f57ec59cc", "firstIndex": 14763949714}, -{"blockNumber": 20333582, "blockId": "0x8040c209f5cd1738ee0f85c2f1db7c43a420d148680c7390fd1701b9f0bb671a", "firstIndex": 14831058335}, -{"blockNumber": 20377087, "blockId": "0x08fdc4cd246b6ae9d4a45646b0aed6af3bb330eb6cd4c8b93646157e7b002b84", "firstIndex": 14898167722}, -{"blockNumber": 20421699, "blockId": "0x5a2912b5fc2f02df33b655155990f92dcaacda5b75427fe3d87fb38f36b1c17d", "firstIndex": 14965275691}, -{"blockNumber": 20467194, "blockId": "0x3deaf4325c461004b090b0261996c645ab529c1471feaf7dc2bbe1f128180297", "firstIndex": 15032385211}, -{"blockNumber": 20512397, "blockId": "0x37e39697ec1b7683a6202be250ffaee7a1102e8030f87550b94af05ec66cec83", "firstIndex": 15099493973}, -{"blockNumber": 20557443, "blockId": "0x8e9c04468f3111eab8b1f6a58b277862c624861c237cadecc53ec249bd811bda", "firstIndex": 15166602882}, -{"blockNumber": 20595899, "blockId": "0x9787555fe57e4650002257eb2c88f1ef435b99d406e33fe2f889be180123ef25", "firstIndex": 15233709908}, -{"blockNumber": 20638606, "blockId": "0x70681cffd159ce2e580dbbbe8fa6b5343dbcb081429cdda6c577e615bef4ef05", "firstIndex": 15300820678}, -{"blockNumber": 20683605, "blockId": "0xb32662d5e241132ffe2249caea67f5746a6f4382297b2ac87c81e2794faf1f7a", "firstIndex": 15367929350}, -{"blockNumber": 20728630, "blockId": "0x15a817c846928b673032d5eacd0cff7a04217d268457aa30a322ecca32be4d49", "firstIndex": 15435037830}, -{"blockNumber": 20771519, "blockId": "0x542bc7b9804bbc45f4be470f4dc56f215a4dec71fed71eba2ffc804afd262b95", "firstIndex": 15502145990}, -{"blockNumber": 20815097, "blockId": "0x798cdd51c964fcf18561d70095d9613b84ba836817972799c9dfd0bfbe1e042b", "firstIndex": 15569256033}, -{"blockNumber": 20857859, "blockId": "0xfb5bb066d419a651d8e0186569eb4e8d8bcd5181d8f02e0d578b5dfe2fc738dd", "firstIndex": 15636364671}, -{"blockNumber": 20896890, "blockId": "0x834b8d6fad779e4cf8214128f6c93d7387b6d6279e517f6f0a284b5d831cc3ae", "firstIndex": 15703472902}, -{"blockNumber": 20939387, "blockId": "0x7adee7c78420c711efa216c61e0b561e581d7ff0331efd91ee16a609b34cfdc2", "firstIndex": 15770582325}, -{"blockNumber": 20981303, "blockId": "0x6f5d7b0cc6dad5eb258176e07de21795a8347d68f7303f06934046e0236bea6d", "firstIndex": 15837691713}, -{"blockNumber": 21023216, "blockId": "0x96cfe35a45df1297a36f42c59ebe706ab0473dfbf59ce910b5c5a8dbf696de1c", "firstIndex": 15904799667}, -{"blockNumber": 21068378, "blockId": "0x93753875ff330d922b23f823203198f3b1bb8833367c6b6a8f896ff54be2c12d", "firstIndex": 15971909040}, -{"blockNumber": 21112445, "blockId": "0x6ac02fa6ae486b86aba562eaf6f3d883befaa8ebedcfd8d74bdb7368d42deee3", "firstIndex": 16039003625}, -{"blockNumber": 21155992, "blockId": "0x25f76896b4b693bafb79e9a535e2bf00ed62a577e35209749346e8e79a60bb71", "firstIndex": 16106126344}, -{"blockNumber": 21200962, "blockId": "0x725f2befe913cb2659d262e2d3b6f79a706b31c557d52669471da22347ec8287", "firstIndex": 16173235265}, -{"blockNumber": 21244663, "blockId": "0x6778c4194f54e70939da38853daddb22bfaf160d35617ab05d0f5c476741147b", "firstIndex": 16240344735}, -{"blockNumber": 21290273, "blockId": "0x433ac819c40bd3061205fe0ece0645eec73f54a0a5c1559c981f983345bc0154", "firstIndex": 16307453543}, -{"blockNumber": 21336156, "blockId": "0x261dc8c1639d505624150d2388d15ed10bfb4c3ce9c0c327a4ec26531689a097", "firstIndex": 16374562466}, -{"blockNumber": 21378880, "blockId": "0x5c78b2b70553140dfdfdd4f415b98f88e74f74662315834038fd99042277d917", "firstIndex": 16441671104}, -{"blockNumber": 21421613, "blockId": "0x854532f9d1c77627b763f9cbc7099a653d59554ed57fa763bc218834c82955fe", "firstIndex": 16508780351}, -{"blockNumber": 21466875, "blockId": "0xb8b83cc62084e948235ef4b5973bf7fd988fa28bcaa72f7d38ad8e50de729618", "firstIndex": 16575888599}, -{"blockNumber": 21511942, "blockId": "0xe806a28bc1b7f8cd752c8ceedbe081d49773d4558a9fb95e3357c0c07172522d", "firstIndex": 16642996907}, -{"blockNumber": 21550291, "blockId": "0x1f3e26d303e7a2a9b0614f12f62b189da365b3947c5fe2d99ed2711b37fe7daa", "firstIndex": 16710106826}, -{"blockNumber": 21592690, "blockId": "0xa1408cfbc693faee4425e8fd9e83a181be535c33f874b56c3a7a114404c4f686", "firstIndex": 16777215566}, -{"blockNumber": 21636275, "blockId": "0x704734c2d0351f8ccd38721a9a4b80c063368afaaa857518d98498180a502bba", "firstIndex": 16844323959}, -{"blockNumber": 21681066, "blockId": "0x1e738568ed393395c498b109ad61c0286747318aae0364936f19a7b6aba94aef", "firstIndex": 16911433076}, -{"blockNumber": 21725592, "blockId": "0xee87b7948e25a7498a247c616a0fbaa27f21b004e11fc56f2a20c03791ed8122", "firstIndex": 16978540993} +{"blockNumber": 4166212, "blockId": "0xd94b724fc1c7dceb3251b51b81f7a0f3220ae5b9add1e62917004f14f2a3532c", "firstIndex": 67108840}, +{"blockNumber": 4513996, "blockId": "0xc0fd25fef5888609d05fa8c5620d8e18c31cdd675dd4ee926ff966668f0e5d76", "firstIndex": 134217480}, +{"blockNumber": 4817399, "blockId": "0x8573c3166fb7f716e97cf6109d382f86441238e0b85828944a072ae8583a6cfa", "firstIndex": 201326547}, +{"blockNumber": 5087706, "blockId": "0xcd2dfae45901e299b25faa04c10df60983d5c0a3d0e478e789c7aeec980cf691", "firstIndex": 268435422}, +{"blockNumber": 5306085, "blockId": "0xe8026984c85873f2b24018a7e0bdf8c2df136b2fc49666b4addf0d2e067890da", "firstIndex": 335544018}, +{"blockNumber": 5509898, "blockId": "0x41bc63dc8184f9a7d4b9a5a554e00eee32fee60ccfa2339264be11270ac28de1", "firstIndex": 402652789}, +{"blockNumber": 5670367, "blockId": "0xe61c2ba463f2f458817ed1bf0ff9fb9d07e9d7354f46b48175b2d784b817bf3b", "firstIndex": 469761896}, +{"blockNumber": 5826113, "blockId": "0xfbbb1fc5e03a5562bf6b7f1799d7a572d9ef66c7fd0e0b9f4fed7262767b5c86", "firstIndex": 536870852}, +{"blockNumber": 5953008, "blockId": "0x6bbdccd094928e846de3c615a33f2952e3259afaa1929f4ee241a56907d0593b", "firstIndex": 603979150}, +{"blockNumber": 6102812, "blockId": "0x2403f2502088a1fa26c1294f5245032fe3b7f3a8bb14c12d0ba8d577156bbc1b", "firstIndex": 671087962}, +{"blockNumber": 6276672, "blockId": "0xeaa05a0e0574fbb164244628a7d14d9d47f1692941098aa737059d44104401df", "firstIndex": 738197399}, +{"blockNumber": 6448662, "blockId": "0xe6f097fa18a2cef425514e863659e42e1aa8d74df49cb0bed5877e82a08d1f84", "firstIndex": 805306056}, +{"blockNumber": 6655925, "blockId": "0xee5c9d87b06dc0c2e850fead07bcd13f85d45ad6b5a6e7ebee53cc8618772786", "firstIndex": 872415229}, +{"blockNumber": 6873878, "blockId": "0x9a0ea103146da21fa1d9cab7ff609ec2c5e7f1856288a1f744239588e33904c2", "firstIndex": 939524080}, +{"blockNumber": 7080893, "blockId": "0x35ad45055d7a1a3ef94efeb05e4122757bcc126ff1bc2b4ac72dc78ab3c0fd75", "firstIndex": 1006632327}, +{"blockNumber": 7266955, "blockId": "0x7b80f70520f2c16eb5890f4963af8f60446f50af82b589ceaf009d09e704b302", "firstIndex": 1073741608}, +{"blockNumber": 7466649, "blockId": "0xea8980b5c692c729013f9cc4c9f66e94d5ef2c5caad23f370be0953b6d85f32c", "firstIndex": 1140850335}, +{"blockNumber": 7661736, "blockId": "0x615cdb03dbf29a22d59bbc769c03f3647c2c9abb7d1767f3f6529708209e7073", "firstIndex": 1207959232}, +{"blockNumber": 7834494, "blockId": "0x05b7dd13e2eb8a833e4b278f9151ca01b294ae5fc5617769422ec85ffb446215", "firstIndex": 1275068098}, +{"blockNumber": 7989998, "blockId": "0x4b5026add7f2fc2c02993b82c61bceba1b75cfcb8a78c5112cc2832bc0413be6", "firstIndex": 1342177025}, +{"blockNumber": 8142950, "blockId": "0x9f56b7753a0e9964973f3e096e1385215e3aef232b448359e5bec05046b016a3", "firstIndex": 1409285545}, +{"blockNumber": 8297598, "blockId": "0x2ddfeb161fe34ff73c4a995bb94256c3b522b39348169edb97bb3d876ccdf77d", "firstIndex": 1476394898}, +{"blockNumber": 8465061, "blockId": "0xfdbe5435da5ae9fb34a9154e5ebe515afac9a128e383f798f1e69952be404fcd", "firstIndex": 1543503805}, +{"blockNumber": 8655740, "blockId": "0x305137325a39a44aba997e214c05f32d965658f7e3fe20322f2e57e72f239977", "firstIndex": 1610612406}, +{"blockNumber": 8807102, "blockId": "0xc32f9fd9a43d2b502dbcc4a683ffe324fca9a871753478bcb1f4fb9573da96a5", "firstIndex": 1677721343}, +{"blockNumber": 8911110, "blockId": "0x806eabee7dc429b57afcb6c0b72b61728b4f13c62ee9942f1813790463f9ab5b", "firstIndex": 1744830172}, +{"blockNumber": 8960262, "blockId": "0xa69f24032e9d5761565e726d484926a0932c6ca7fdb4c04a55bfc5e8f5879c4d", "firstIndex": 1811938729}, +{"blockNumber": 9085906, "blockId": "0x922b4d6aeca64517f5048fa1ffa98d3e813bc415716a1763d07cf2bdea236896", "firstIndex": 1879048062}, +{"blockNumber": 9230838, "blockId": "0xd892f513c48c95a859ae59c4e00ec4be0d684c549456c90e9c36669c11092f50", "firstIndex": 1946156580}, +{"blockNumber": 9390449, "blockId": "0xcc0ced78fa66b570f338d129794d574560a23958e28d0d5288003d4542cec734", "firstIndex": 2013264376}, +{"blockNumber": 9515554, "blockId": "0xc06d04737813c3e2c8e910b2d4543c5c684c7bfe235bb501445f68fd0663f3d9", "firstIndex": 2080374749}, +{"blockNumber": 9659367, "blockId": "0x765fa33d9418b1ed648e88b497b4bf4aa66990e6413dfc155525cda61e3cc813", "firstIndex": 2147483344}, +{"blockNumber": 9793940, "blockId": "0x9527dcbd85a100c51aee4ba90828fee23312f5f041859f3416a54fd87a437ce2", "firstIndex": 2214591669}, +{"blockNumber": 9923756, "blockId": "0xc4da5fdd2de077459fe84f721d7fc01ef69683e03e634b0c5443186486792246", "firstIndex": 2281700949}, +{"blockNumber": 10042325, "blockId": "0x6f554f195d20e4ba1262f73cf2c1cd44b14a71befe5ef0a5318fc309f8cde9fa", "firstIndex": 2348810131}, +{"blockNumber": 10168768, "blockId": "0xdcdf88ec2c197d552343c80d01375a35d6462aff39c5bd976160f7176d2add64", "firstIndex": 2415918723}, +{"blockNumber": 10289467, "blockId": "0x5ece23babcf6b8838695b891b044c3dcf8120cdc15acd83018e96ffc590f6cd0", "firstIndex": 2483027720}, +{"blockNumber": 10386601, "blockId": "0xd398ee129aea1247019fa39dc2f5083819687d8f5ad17ec39ba1803d178fbcda", "firstIndex": 2550136043}, +{"blockNumber": 10479586, "blockId": "0x61c1cccd60a546eacc29f2ae2a6facab402b4f35e2986c6629b302e6b1ebca3e", "firstIndex": 2617245577}, +{"blockNumber": 10562579, "blockId": "0x14fd6a079050e3e110140372605c050945d6db03746fa5b84a8718cb2a0e9b86", "firstIndex": 2684353802}, +{"blockNumber": 10641438, "blockId": "0x1998dcae09111b2c1bf6d0592e2f0b4a0143fe7db7115ff94b2b73b74542cee4", "firstIndex": 2751463334}, +{"blockNumber": 10717094, "blockId": "0x9ce45a150bb6bd13687d0692c86716911ffc6aff5831a03f4015bdffb85f5093", "firstIndex": 2818571144}, +{"blockNumber": 10784494, "blockId": "0xf65c936cf578e673696477f7db7189b47222fdf7ed13096564b9d47b15c86eb9", "firstIndex": 2885680709}, +{"blockNumber": 10848591, "blockId": "0x84ea8e9d5789302ebe88888115488f91cfb75fd89e282dfbd29ba9d6225ab0ca", "firstIndex": 2952789491}, +{"blockNumber": 10909102, "blockId": "0x22275047f643f4a3b82c349274a53d56a00da25beac89655877fb8cbfa3182c8", "firstIndex": 3019898024}, +{"blockNumber": 10972828, "blockId": "0x38e8acfec19bb53ab9fe70dd3577ccd8bd7c41b4d468b8f099a19bf06ce56518", "firstIndex": 3087006561}, +{"blockNumber": 11036532, "blockId": "0x478dac03f520e987a6e845cac1b3a756d69e4f5257f20758b8fc38456e7b6884", "firstIndex": 3154116463}, +{"blockNumber": 11102457, "blockId": "0x1a36616b03351ebe481330fc86578f57d9da5c0dda59f4406d49b53a2fa9b6f6", "firstIndex": 3221224961}, +{"blockNumber": 11168092, "blockId": "0xb23af483ca6dbc2fb8d2fada1f8189de2e155758ed9ecbbb20c234a30c7e093c", "firstIndex": 3288333510}, +{"blockNumber": 11233640, "blockId": "0xdc4c80d8370823773425b31e70b3af59582b556514857d1e9a9b4c53b880a424", "firstIndex": 3355442901}, +{"blockNumber": 11300454, "blockId": "0xdbd4d8e9c1756093037f431330db4604e5a3e67bb74f425f667633d5298fe34c", "firstIndex": 3422551962}, +{"blockNumber": 11367550, "blockId": "0x9e00816bd5b39353657a99421d278091599a39f246bbf8c0898f83e6d70b7c7c", "firstIndex": 3489660743}, +{"blockNumber": 11431820, "blockId": "0xd32d5e5871ce71acc9dcc7cf9d8cb9d964646182529c327a0ddf617814e27d74", "firstIndex": 3556769150}, +{"blockNumber": 11497031, "blockId": "0xed823054d4b293294e3301d3131e2ae9f0ce63c9f07d2d80fc144e42d535d61d", "firstIndex": 3623878513}, +{"blockNumber": 11560027, "blockId": "0x7098177efe77cfb5912dc63069fe366033111041ca5c539907a89e439c861d8f", "firstIndex": 3690987092}, +{"blockNumber": 11625049, "blockId": "0x61fccb47104a076b905d390498a1b38c317348bb1567e69aa1b670bed7a6a13f", "firstIndex": 3758096043}, +{"blockNumber": 11690298, "blockId": "0xaf6f9e9c92db9e155f1ffb35eb68765c09de1206c353c9a56a5d5fa53e2d88d2", "firstIndex": 3825204430}, +{"blockNumber": 11755003, "blockId": "0xf9efb54f08a2b59086a607541005928f1bda54fa2c46fcc48352fa6aa461c03a", "firstIndex": 3892313541}, +{"blockNumber": 11819591, "blockId": "0xa551deb3bd2ec0ca2683cb76adb8fb295d171a3787aa5ff071bd1fa94d3af82e", "firstIndex": 3959422322}, +{"blockNumber": 11883278, "blockId": "0x60c7a359d4aeb09b63b64487fa7794aee87c41b11446f69ba83e24d5bce6947f", "firstIndex": 4026531239}, +{"blockNumber": 11948436, "blockId": "0x1c46fb22653e5f9eb9503fe532151519845d05b121291766715973e027eb9c0c", "firstIndex": 4093639741}, +{"blockNumber": 12013084, "blockId": "0x0b8d1da9e70c4494ba61190390c891230846e69d9b0be605df8b04c4199ffd1b", "firstIndex": 4160749561}, +{"blockNumber": 12078612, "blockId": "0xb049af260be25c6153b67c227689b0556d8fb7d6033c3f61b8218f5c4ac5917a", "firstIndex": 4227857310}, +{"blockNumber": 12143549, "blockId": "0x685dce41efbe2bab0ac9a4b9026d9e5faa3e01ae4637c8181cd2f1eac326fe6a", "firstIndex": 4294966232}, +{"blockNumber": 12207918, "blockId": "0x53644ea8f781c6270f1136ed4bbcb956c98f12a4793c2f56f49b3105282b13ea", "firstIndex": 4362075410}, +{"blockNumber": 12272370, "blockId": "0x503523e1a01cb7d68be0eb22f36280c0ee7a1fc802061a704e326fbb8efcfe27", "firstIndex": 4429184831}, +{"blockNumber": 12329342, "blockId": "0xe6a1bf78dd827def078e23c768cf6e96666ee06b5fdc113380a4769d85f4bd33", "firstIndex": 4496293151}, +{"blockNumber": 12382311, "blockId": "0x352fe793c16b1d8aea195af86ee9aec3dbaa83e7a32872a0d222a77e96fc0e57", "firstIndex": 4563402486}, +{"blockNumber": 12436970, "blockId": "0x90276349edf0941bb3327dc1d749d0371fe550eaddafb5141fcacdd281de0976", "firstIndex": 4630510187}, +{"blockNumber": 12489954, "blockId": "0x71894b1e1608aeba777662a6055e601ce6f17950dbe3844c3601e0f88cbd5848", "firstIndex": 4697619586}, +{"blockNumber": 12541655, "blockId": "0xc34c7299041df72a81c4b86e81639d2dfcebfae603e287fc143881a636ce1188", "firstIndex": 4764728948}, +{"blockNumber": 12597319, "blockId": "0x4c4dc71d8d2f1223ad0469ddfe09fa8934f64e3712ed83708d6e1b9c64eceebb", "firstIndex": 4831837390}, +{"blockNumber": 12651863, "blockId": "0x406a642c8364fb61cbd896512a2d19ecdba3932ab09ac67cf48d91aa1a03f24e", "firstIndex": 4898946362}, +{"blockNumber": 12706391, "blockId": "0xa7fc3739898f7ff5733896313b248fb0b306a132681609b8b9e2671b42dac3a1", "firstIndex": 4966054748}, +{"blockNumber": 12762840, "blockId": "0x5a1048966dfa55a48248517c45683ce342671bf544117d2bac13d8e343563136", "firstIndex": 5033164303}, +{"blockNumber": 12816597, "blockId": "0x97f5b87f422870a8ffeff70c12f4377dde96d248aa912cb64ebfaea51dc086b6", "firstIndex": 5100272541}, +{"blockNumber": 12872315, "blockId": "0x432f7df7973fdea4e5abe2c09b634ca3b724e37a19d5ec23ca5810e4854c6b33", "firstIndex": 5167382243}, +{"blockNumber": 12929620, "blockId": "0xa4524e3b4c5dadac91df2f29696532cfed377f47469fe7cfabf10baac945eea2", "firstIndex": 5234490748}, +{"blockNumber": 12988653, "blockId": "0x9be70e31aeea164c370d8d183a1af45120693b13d360edc78214535c40ef1d63", "firstIndex": 5301600248}, +{"blockNumber": 13049074, "blockId": "0x3076857bd17959c2a3df18357eab3ecbb7ca25457785b07074d2e885eb566fc2", "firstIndex": 5368707746}, +{"blockNumber": 13108823, "blockId": "0x67b2764f6b53779e3d683def2c7659c6d92814152574073d24f10cd67200a22b", "firstIndex": 5435817680}, +{"blockNumber": 13175389, "blockId": "0x0d41e34dbca58dec45e0509b6cbf027b2377220845a85caebbf3a14b8505e8ce", "firstIndex": 5502925085}, +{"blockNumber": 13237624, "blockId": "0x723e0818d54ab1b1c53efc2f2f448c16c1f943af2033575c612c3c71228d4ddf", "firstIndex": 5570034948}, +{"blockNumber": 13298658, "blockId": "0xd7f9f477b20bcf1379ccaaae701c9658a02b177861e0af9e873c63fe8b854f4b", "firstIndex": 5637144562}, +{"blockNumber": 13361166, "blockId": "0x9f9e4130093269d59045f91344a13eb2786023e02099f53dd44854d50a7f5ffb", "firstIndex": 5704253260}, +{"blockNumber": 13421716, "blockId": "0x28752f35ad2adeba342ef6aa51bca1c0abc757c4f712cf620c8a5e6a8576636e", "firstIndex": 5771361775}, +{"blockNumber": 13480516, "blockId": "0x43f4ecf24c17b7a77621e2ca09c88c53b3407fb018f4bb3a032c212015b4e18d", "firstIndex": 5838469616}, +{"blockNumber": 13535688, "blockId": "0x99ffcd9982219a4be45fa5f15622b288afe4f85da536956d39dccac1ec416444", "firstIndex": 5905579739}, +{"blockNumber": 13590487, "blockId": "0xff7b74464a318037e0670c0be7a5b1b79418d1a42c7a3587c46adc1ef720c819", "firstIndex": 5972688013}, +{"blockNumber": 13646596, "blockId": "0xd555ce5f2b65ffeec9b9e3e75a56f5f23d7353a1014bcc861efd7df6e5dc2c92", "firstIndex": 6039797525}, +{"blockNumber": 13702902, "blockId": "0x3e8feab590c6631c63931fee83bf7e10234890bdf377b1b374fb70221b9ac9c0", "firstIndex": 6106905641}, +{"blockNumber": 13760908, "blockId": "0x18e96fa585c57aad1f2a8dc9639d9f4fe53c3f38894862471b7cec17f97f3cb1", "firstIndex": 6174014330}, +{"blockNumber": 13819340, "blockId": "0x25384bf2cef178e30c4d9e0abae59357055241fc715133b2bb078e8278e5296a", "firstIndex": 6241123906}, +{"blockNumber": 13877817, "blockId": "0x4a84a0a7035dbfed0e1281fb1df162a195f2c516686a2e2a6ad605e6f2b3cf57", "firstIndex": 6308232690}, +{"blockNumber": 13935260, "blockId": "0x6c14a8e563614edbad66698ebe911e997e27844f9d33c7069795379540e71a44", "firstIndex": 6375341148}, +{"blockNumber": 13993914, "blockId": "0xc0991d1bc431c5215fb0218b0b541f2b4fae0994775e5eddb016965fe5b4a0c7", "firstIndex": 6442448947}, +{"blockNumber": 14051007, "blockId": "0x854803ce364b6fe4446800e74448a5ee883e7d472e8a0347f1ad13bd347fa69f", "firstIndex": 6509558964}, +{"blockNumber": 14109063, "blockId": "0xa3fadce7ab18a5fedcfed9e3b1f0cf2fb32151172c362327c602343bc26dde8f", "firstIndex": 6576668017}, +{"blockNumber": 14166701, "blockId": "0xaa2443a38e2b0d6b01cf4b73de54d2b7e92c99475bd0802beebd86845c126d1b", "firstIndex": 6643774648}, +{"blockNumber": 14222367, "blockId": "0xa27c78134c1fbf432c8caee7c9d2ef323fdde519a065804c9c8da6ca1615e04f", "firstIndex": 6710886238}, +{"blockNumber": 14277029, "blockId": "0x5d0ed08b65db01e382c339dcb2715b2927fb472b0c1f4256841c386d785c3f3a", "firstIndex": 6777995247}, +{"blockNumber": 14330955, "blockId": "0x3e5014d82c416549acfe2e26b13ff5ddf29ad74943ef5b94a65eca0a4d72d82e", "firstIndex": 6845102969}, +{"blockNumber": 14384139, "blockId": "0x720e1fd687292019c3fa1812c39c73d20fde783c0196f43378a51cb4e0b46d65", "firstIndex": 6912212078}, +{"blockNumber": 14437534, "blockId": "0xe4342ab6f363066d9c2514a870241ceb63df232d33659fdb3928faf433360bb4", "firstIndex": 6979321493}, +{"blockNumber": 14489073, "blockId": "0xeb2f9923d816e773460eccfa42eb4ff2bbfc353b756ba274e98dc85c64ab1536", "firstIndex": 7046428879}, +{"blockNumber": 14541559, "blockId": "0x55cc33721fa9022964f47c30f4146fee7cc80f5b4158d7ecea0ff661cbba3487", "firstIndex": 7113538857}, +{"blockNumber": 14594432, "blockId": "0x676441bdc1ec430a9fbc05e56a0437a475606a253f9fdffc86f5f6286c159b5d", "firstIndex": 7180647956}, +{"blockNumber": 14644942, "blockId": "0x03232a1d3c9b2f1f0c2a4b780c83bce66238d9abdeed71c2a8af9e97a53011b0", "firstIndex": 7247754981}, +{"blockNumber": 14695793, "blockId": "0x6017f6d1d79188692e1a1a18de5f93b83b97905c8ff5bed5cef4b2e9f4d4d41b", "firstIndex": 7314863646}, +{"blockNumber": 14746186, "blockId": "0x332c8ac0b2960fb1627407d45443201a0f6de7421b52af077b32fa6e018e5401", "firstIndex": 7381974499}, +{"blockNumber": 14798403, "blockId": "0x4507ae1d9f27a3eada874dcf04112a5d4ee7155701afd3fb857fe58201a2dede", "firstIndex": 7449082752}, +{"blockNumber": 14848093, "blockId": "0xff98c820c66c3beaaa3b195158c94f099148573a7f032295ba7156c13f78eaa8", "firstIndex": 7516191978}, +{"blockNumber": 14897508, "blockId": "0x49c31d3433b197585f733d7c382ae16d9d78bf59c333a9b76362cc6c5fed270c", "firstIndex": 7583300663}, +{"blockNumber": 14950638, "blockId": "0xf1a1609206788977841927271808fe1c42d059026385d025bf4cea0c0a05966b", "firstIndex": 7650408992}, +{"blockNumber": 15003958, "blockId": "0xf9e6b41108d907672f29ba1df97ed83aca2ba933335e6b5ccfb5d4001807b33f", "firstIndex": 7717519105}, +{"blockNumber": 15056783, "blockId": "0x126a5a5c22e878a4c42bea890d48cfe00edf7fbc27d805c88a5269540bc94a42", "firstIndex": 7784628173}, +{"blockNumber": 15108163, "blockId": "0x5f8494ccacefce9fef8a95a52247f2670ed30bb5a3b3deb85c645e72c115d506", "firstIndex": 7851735261}, +{"blockNumber": 15159385, "blockId": "0x0fed6c5aafb53e9cdb0d8620c3eef9b619fb3ae9559296618f634eddae33f0c6", "firstIndex": 7918844299}, +{"blockNumber": 15210872, "blockId": "0x37bdb94b57044b67fbd9b9a7cdc728fcfd2066cf1904cab478fd42d41ec6e1f0", "firstIndex": 7985954119}, +{"blockNumber": 15264226, "blockId": "0xc173ad8a791e2293efd8e0b2c9f088fac49233aabb1e72db6a045aa9904f4728", "firstIndex": 8053061840}, +{"blockNumber": 15315693, "blockId": "0x985cf97bf28f0becb2b16abfe629a5f520596e45fc23f4936bc2f6298b8145f9", "firstIndex": 8120172048}, +{"blockNumber": 15364606, "blockId": "0x593362ef8a82140f3dd3ff13d0ce50287dcb0b8b3d31ffcc7813c6be16f7438d", "firstIndex": 8187281275}, +{"blockNumber": 15412727, "blockId": "0x5a6ff10acc48e9e8bcf963b042012ea094628b9488b8bf569783b3297c67eedd", "firstIndex": 8254388575}, +{"blockNumber": 15462642, "blockId": "0x137f15c5d112b0fdc6e4c84393032030646122c3b0d86286143a1ab8bfacbac4", "firstIndex": 8321497214}, +{"blockNumber": 15509781, "blockId": "0xe58a8ca223b7c03755d046a6212bc33fa9814f73efe52804d8eea7ae4b4bd7f9", "firstIndex": 8388606496}, +{"blockNumber": 15558625, "blockId": "0x4127d527b58c7685a1237d228508ea77d40f33dbeffb5cc30e47e83a4b6152a5", "firstIndex": 8455714910}, +{"blockNumber": 15604075, "blockId": "0x7d1c1bccfe5c23a1edd81246e6e55277f271cffef30bde22c9d1202f764dd96f", "firstIndex": 8522823324}, +{"blockNumber": 15651742, "blockId": "0x732e5203a504fd97510325c1fb876476ca132831e78182367cd4b4efae1232c3", "firstIndex": 8589934155}, +{"blockNumber": 15700810, "blockId": "0xe031decb5e42a69dafcc814441227085508cf51c9c77f35d06487db19bd05a6a", "firstIndex": 8657041374}, +{"blockNumber": 15762855, "blockId": "0xbdff9b1e193c44f35bf38945d2523c74ef59c4f352efc93fad02ef34eef1c5f0", "firstIndex": 8724150924}, +{"blockNumber": 15814304, "blockId": "0x524a226d9f48e37db00e252c7f6a1350d1829d38fe83c756021cc11c56d3b2dd", "firstIndex": 8791259373}, +{"blockNumber": 15865514, "blockId": "0x4e4ad46f3ae7fb2a2e7cb94aa804929cb7353c79c78cc2cbcee710da5f0ec4b5", "firstIndex": 8858369571}, +{"blockNumber": 15920411, "blockId": "0xa39e4cbd8e84b427e44b8d06b5b1149652f3af5fa88633b802665b8677772bc5", "firstIndex": 8925477782}, +{"blockNumber": 15974193, "blockId": "0x4a3f82935e6fcda6ce7636001989b65b79422d362e60833e01185a7960b2fa55", "firstIndex": 8992587369}, +{"blockNumber": 16032739, "blockId": "0x7f50bb76dfd01125e0a4a7595106e43329eb8bd02e819be2ade4248a403c714a", "firstIndex": 9059696611}, +{"blockNumber": 16090896, "blockId": "0xdc4db130973ef793d2223844e35122a2477e642d86c69616fb3604d2a79805c4", "firstIndex": 9126804425}, +{"blockNumber": 16150783, "blockId": "0xb46294fe1cbcbbdff7309ebf0bf481e78e2589d386b95fa4c781c437e02e0aec", "firstIndex": 9193912139}, +{"blockNumber": 16207278, "blockId": "0x8a3af0387572b56989bb6c98d8860e07b5cdefb2ebe7b1dc58be07c24a53e056", "firstIndex": 9261022215}, +{"blockNumber": 16262389, "blockId": "0xec5a03d88cfc1bf8c278ddce7ace5032c3f7ed5032b4575df54779ec1abca131", "firstIndex": 9328130680}, +{"blockNumber": 16319525, "blockId": "0x74ae702375e242205fe4986448b0ee494d4a38ccc813981489c4b0488e58a949", "firstIndex": 9395240779}, +{"blockNumber": 16373441, "blockId": "0x5f404555cf45c547ef0fc044f2701bc7a28ce1e432de06e0264dbfd1c17447d0", "firstIndex": 9462347671}, +{"blockNumber": 16423343, "blockId": "0xe4af890b6c4dd3b10af2e6c08f14563bd2a3121b22a3cc6a0db29d438c1dcc59", "firstIndex": 9529457704}, +{"blockNumber": 16474687, "blockId": "0x019a8b374cf150fcda1c8af2a3e7ba63603ae81744d6343897c4b17ee58411d5", "firstIndex": 9596566169}, +{"blockNumber": 16525504, "blockId": "0xad394ce7e84e1c904cc5dd6dabd51b1a575c0b2fb006f10f272875b7f921904e", "firstIndex": 9663675287}, +{"blockNumber": 16574051, "blockId": "0x098e2dca2eda0d700aa3127bdfb679ce16e3ca297a305978c6ecfff044269511", "firstIndex": 9730784563}, +{"blockNumber": 16622457, "blockId": "0x8627f1237731c1127116898724f1b6420b8e7bcd8e18a0ea568f192bbd2cd55d", "firstIndex": 9797893241}, +{"blockNumber": 16672410, "blockId": "0x3e32b46faa670b191b89bea84a68022d5ea8b90008b388a948ff27f871d17292", "firstIndex": 9865002964}, +{"blockNumber": 16719964, "blockId": "0x1668c3ea6cb256f306e93851cc2c00612f85df5cf7b5527ffce14c89088d7fdf", "firstIndex": 9932111708}, +{"blockNumber": 16769014, "blockId": "0xed9a6f88e47b5bfe4d5bc92e1c1bfeb252f716f0990ffa1f907655c0f5e3a365", "firstIndex": 9999220312}, +{"blockNumber": 16818134, "blockId": "0x93504ba617500698a1b46f3110cd26827b8efe468190b2a91d3595784e34a1b6", "firstIndex": 10066329167}, +{"blockNumber": 16869369, "blockId": "0x94ca4b395a5c36c4e9d07cbb08271f0680455af4e4659906b647e16abebd7d4e", "firstIndex": 10133438415}, +{"blockNumber": 16921428, "blockId": "0x66650775bff4cb95de56099c10b06f3dfe302a731b391f406d1aa551121308ba", "firstIndex": 10200547148}, +{"blockNumber": 16974677, "blockId": "0x58d5fc4cd45047dac10d55a036e0a4448faacc1041b29c4c7fb41a6e9394c3ff", "firstIndex": 10267655623}, +{"blockNumber": 17031050, "blockId": "0x9d15b831979e95fc4149ecae46478cac1e54470b277d57d7102d19a72f28eeba", "firstIndex": 10334764441}, +{"blockNumber": 17086163, "blockId": "0x978ff48863fcdb50b274ea4220e7635c13c41bae91912db9e24205fb917fde85", "firstIndex": 10401873176}, +{"blockNumber": 17141086, "blockId": "0x4084d442499893361731f17534944d260cccd8e07d41c52d7160910555770b90", "firstIndex": 10468982462}, +{"blockNumber": 17190735, "blockId": "0x42ed86fb42def23870df6ec23204f557669ec7cd8de59c9f3ef9ab90704e4b11", "firstIndex": 10536090726}, +{"blockNumber": 17237026, "blockId": "0x9a49d943f82a7335f8049df4d953080f25920e3b098f6a2d872520166b225961", "firstIndex": 10603199938}, +{"blockNumber": 17287007, "blockId": "0xac3d189676d24eadc62adcf97d8730a001a7766fe3ac27b18e745ca9727f6c46", "firstIndex": 10670308186}, +{"blockNumber": 17338498, "blockId": "0xe50e251aa0a3209fa8a0030b237cf8357b08eeb80492a432c8aa5969a820ee42", "firstIndex": 10737417623}, +{"blockNumber": 17389178, "blockId": "0x1e18cedcfa6c81bc845c9136fc92f9f27ca8fff8847289bb139f374f0f6ba733", "firstIndex": 10804526769}, +{"blockNumber": 17442038, "blockId": "0x07f47ebbee99938fb96beb1ffadf8266f71d0d73f393172f0e24facd40d45c97", "firstIndex": 10871635940}, +{"blockNumber": 17497589, "blockId": "0x247a5e852e36e46f7897ad1875e93d810ff4434bb835b469afae3a3d3d4a9c9a", "firstIndex": 10938744251}, +{"blockNumber": 17554111, "blockId": "0x420e420a1b599e4dc3bd115652b4d6f5eedc391086ef064f97a9cbffc02b62f9", "firstIndex": 11005853686}, +{"blockNumber": 17608282, "blockId": "0xb2ba644d3593d3c832f932f14ffec532e26e9e1cdcd8fbe7477f46e238c6bffd", "firstIndex": 11072962303}, +{"blockNumber": 17664091, "blockId": "0x6d0bfff8145652a617bfe03ab87e3af09219cdb822c9c214b42b16f20742c1eb", "firstIndex": 11140070260}, +{"blockNumber": 17714917, "blockId": "0x61509544b5174d3ff5d48816ff54f2929c8a400ef21454116056baa136b607b6", "firstIndex": 11207179013}, +{"blockNumber": 17763850, "blockId": "0x8da83012621f42670601406c902ce6e48e77c6285dcc6983e108e69b3a8d5d2d", "firstIndex": 11274288732}, +{"blockNumber": 17814186, "blockId": "0xc37bda200856589c220dc206e31186d6c12761fd193f5bc7123cf331fbbed7f5", "firstIndex": 11341397343}, +{"blockNumber": 17864461, "blockId": "0x99af43893dc9f54c55abbdbd7b000e27248145371e9b00db116dfb961b36749c", "firstIndex": 11408506122}, +{"blockNumber": 17913212, "blockId": "0x9b642236d63d756fcd3404713bc6abe97804b46a9e665ae5f1d9aa48e693fe78", "firstIndex": 11475614347}, +{"blockNumber": 17961497, "blockId": "0xaec9b1e851cf51646673ec7698e1d5964d44eb04729ad11385f6ae84d497070a", "firstIndex": 11542723713}, +{"blockNumber": 18010859, "blockId": "0xb15fb7fc308516cad5f1dadfb7dd92fd3fe612308f67154cf2a241990aa15bc4", "firstIndex": 11609833204}, +{"blockNumber": 18061052, "blockId": "0xd8ea94b8b8a7380d21dc433abb69973f3de2eeb339f4aaffdb79f85a5d86929d", "firstIndex": 11676938565}, +{"blockNumber": 18111466, "blockId": "0x5b5cc6d182bffaf06692a7efda8cad5d4742fdbce5c1146b3be3c5be10ea046a", "firstIndex": 11744048539}, +{"blockNumber": 18166001, "blockId": "0x901d8401c795542c75069cd917781fa587ad416da0a5298f144fae2f14305705", "firstIndex": 11811159949}, +{"blockNumber": 18218505, "blockId": "0x5894285023f34ec6fd501cd90b605e118b9688ca7c01082289bf69a6987142bc", "firstIndex": 11878268395}, +{"blockNumber": 18271037, "blockId": "0x3f0fce315fd993d966b6c599ebd360462466e67046d512dc430ac07f75243bae", "firstIndex": 11945377050}, +{"blockNumber": 18322778, "blockId": "0xfa6536b3b06e7b579e53a8d01368182808c950586e39e12485be3145c3acbf43", "firstIndex": 12012486036}, +{"blockNumber": 18372240, "blockId": "0x5531859d5b8a4093020e2fb971808d0eeaddd7d61dc58d70f34923081f97336f", "firstIndex": 12079595358}, +{"blockNumber": 18421630, "blockId": "0xfeadff676fe8f04d0362b77ea2d7c3ea59b05d68cc6b2cc95cfe751558b1bfa7", "firstIndex": 12146703872}, +{"blockNumber": 18471472, "blockId": "0x352b0a17e4160d334b876eb180d686fd67c7ddc40a78219b0bc4b59f5ae5912d", "firstIndex": 12213813174}, +{"blockNumber": 18522088, "blockId": "0xf7d408309246089531b47c787049c7ffd2820c1b87b4804033a458bc193a3432", "firstIndex": 12280921181}, +{"blockNumber": 18572725, "blockId": "0x44126d4a5b43594b09d26e0b0a5dc859c074865cb9b11ab78c80f28406fd0240", "firstIndex": 12348029615}, +{"blockNumber": 18623223, "blockId": "0xd3aec1f98cea30e870d0f530194e9a72e225eb45eefe435e38da5967eb2fa470", "firstIndex": 12415139522}, +{"blockNumber": 18675228, "blockId": "0x24deaef2508038bddf8e9020f95128ae34eb1786f786c3f98df0bdf95f3e97cc", "firstIndex": 12482248123}, +{"blockNumber": 18725495, "blockId": "0x2e5a7edd7337b20e862741e116680a472089426dbc2b0eb5f1c984f8d6da935b", "firstIndex": 12549357121}, +{"blockNumber": 18778174, "blockId": "0xe734a1084fa5eeff427bba8e8d3623181a30dd9bad128fc22de9b15dffd0e549", "firstIndex": 12616466131}, +{"blockNumber": 18834807, "blockId": "0x0924a55ef4f9c2605261433c5b236d47645484efa44b34dc9f15b7c2e6b47a74", "firstIndex": 12683575000}, +{"blockNumber": 18883054, "blockId": "0xef638ec491a1cf685b22bf4072e41710440d6133a53e31250762825247d3eb64", "firstIndex": 12750683712}, +{"blockNumber": 18933405, "blockId": "0x6e9eefc2e121d13e6c04544ea370fe8543afeb36fef3a8e2ea68afb079738c8c", "firstIndex": 12817792510}, +{"blockNumber": 18988033, "blockId": "0x4c98c0dbb6a7217609c4b277fe7ff9e2c32c8d000ee628a3f37b2b296e1ca421", "firstIndex": 12884901389}, +{"blockNumber": 19041096, "blockId": "0x61a219a23d111cd07861ff47b89d4b2840c0ab5421d5d55a6f1fe43da3f33b98", "firstIndex": 12952010147}, +{"blockNumber": 19088914, "blockId": "0xefb26ba58447e50e9b820e0b0d16c08da45793a824af12a2e1f38b6f46b7e36a", "firstIndex": 13019118891}, +{"blockNumber": 19140413, "blockId": "0x91dbb13623fc4d5a4e462dfa0a03c92bf5301948dd4b2c3e5fddd2bc88856d47", "firstIndex": 13086228137}, +{"blockNumber": 19191876, "blockId": "0xdd7f97af7ad206b2636656ed4722fe1c47c6ba9fa5531066785acbe4f8d4c4ad", "firstIndex": 13153336551}, +{"blockNumber": 19237651, "blockId": "0xf1e875f314314abe3654b667c6443c772dd67c525c52877b06515ea8fc5a391b", "firstIndex": 13220444812}, +{"blockNumber": 19291032, "blockId": "0x9eda269ac47957b619d2a8c408b5efc8cfb168a46bfde351f43325fa337fce47", "firstIndex": 13287553967}, +{"blockNumber": 19344225, "blockId": "0x62859b78d45f589f679fc6a3bf266a2e0aa906fd61d787755ec51cfadc05eaf6", "firstIndex": 13354663338}, +{"blockNumber": 19394709, "blockId": "0x7cda3d193bcfe8ddbc89b85e98c814dbbe31a54ccab52ab7738ecd003061f3c8", "firstIndex": 13421772549}, +{"blockNumber": 19442850, "blockId": "0xd95f3f8bab5b91c3e1f848c9455936850bf92cf6a5086b817f6f81031bc0f81e", "firstIndex": 13488880704}, +{"blockNumber": 19488177, "blockId": "0x3a1a9623ee332d6decada9359cf84eeafb81fffa997d6cf4f3efcc92e98e9310", "firstIndex": 13555989570}, +{"blockNumber": 19534365, "blockId": "0x5c7a8ee7cbba4894ea412cc335895a9a7d3369d35779bcdc97a6c24b6a81a7ba", "firstIndex": 13623097446}, +{"blockNumber": 19579409, "blockId": "0x4280f5f76cb0f9947f9da1cb9de6c4b6e65b37b3a3c174f5fb29d360cf389ffb", "firstIndex": 13690206790}, +{"blockNumber": 19621406, "blockId": "0x0a98ca72e97fd295c7c73263b17185d74dbe427f41c616a5d5454faa5a1c63a0", "firstIndex": 13757316653}, +{"blockNumber": 19664868, "blockId": "0xc8c53d89b7a849861f3daaf9503e6397a0340cecb085850c3636bee6ea2b7189", "firstIndex": 13824424608}, +{"blockNumber": 19709011, "blockId": "0xf65babc88ef6a9eb2ffce9a6844adf895995f65a2facd1956f5df17ca68dbf94", "firstIndex": 13891534141}, +{"blockNumber": 19755170, "blockId": "0xf903882449eeb86d69af33b6797099275e82d8787334a02a42a2168dbd739b95", "firstIndex": 13958642627}, +{"blockNumber": 19803666, "blockId": "0xa8a975f570db082a3771790bb1fe405667dde4674ff49e31092687fa92727e36", "firstIndex": 14025752433}, +{"blockNumber": 19847730, "blockId": "0x89d479a4b4d9faa7af3e3f61d13a7a9c80a11c4adf7cd018859eb0ddba30bdd5", "firstIndex": 14092860598}, +{"blockNumber": 19894138, "blockId": "0x740278e6dc79cfd2b030780868a1b8e1520dbae0e8d3ee0a3ef43c84c83c6e0a", "firstIndex": 14159952129}, +{"blockNumber": 19938334, "blockId": "0x05ae7ce9813235c19baa57658bc5c8e160130328a1fd2cc58d2baf2d9a4ae097", "firstIndex": 14227078393}, +{"blockNumber": 19985138, "blockId": "0x511c8876a93a77fa473ae0d29e25d8163162c09b7212f506be0ea73840ea3971", "firstIndex": 14294187397}, +{"blockNumber": 20028221, "blockId": "0x64379baedf429cfa65df076142a7d9909d7e369d6aa6b8e161bb686944d169ff", "firstIndex": 14361296446}, +{"blockNumber": 20071555, "blockId": "0x4f43d8b1091d2bd0c6b080ce51bce08aae6be605e00889be3cdd17cb80614ff8", "firstIndex": 14428405409}, +{"blockNumber": 20113611, "blockId": "0xebbf87409ef6732a53513414926b0aa998a7269f9e9717a3acbe96a33c2de937", "firstIndex": 14495514255}, +{"blockNumber": 20156628, "blockId": "0x70218108c0669f42c4ac1afff80947cf4a0a2fd8e9300b31d45bbe330a5159c9", "firstIndex": 14562622257}, +{"blockNumber": 20199886, "blockId": "0x1d6aaa4b041eb0cc9caed34347bb943e50a139caf8998d781ff4f06d4aa727dc", "firstIndex": 14629732017}, +{"blockNumber": 20244148, "blockId": "0x37fed57b6945a815ec56c84c6261e90cf9f3883d9cbffc62b70d9722c1f0f363", "firstIndex": 14696839730}, +{"blockNumber": 20288249, "blockId": "0x1d9fe664431e093c4ef6139ad35fea767a2e66825e605cfea9e91d1738665619", "firstIndex": 14763948803}, +{"blockNumber": 20333358, "blockId": "0x1ac7c1362791507057b7e87d7118b4f61c2919c8ebdb498ecf7d64a59ba3d2e2", "firstIndex": 14831058814}, +{"blockNumber": 20376855, "blockId": "0xf6a19eac8a402f591079a4aa7ff57349c350ec96d683a031e4d85c05bc0541b2", "firstIndex": 14898167076}, +{"blockNumber": 20421474, "blockId": "0xe8767aa7516b632dc8c0fed3a366273ef14bd7b8c2212998b7105fb80b4c0d9b", "firstIndex": 14965276285}, +{"blockNumber": 20466974, "blockId": "0xafa2d2e6c9594762c163c339069cb15aa9fd27d301268892e12f99a3f2912ade", "firstIndex": 15032384674}, +{"blockNumber": 20512183, "blockId": "0xc1c51f9372d781d7ac0a1a7aa052503bbde3e1706bf65f225b0f6a6eed93d055", "firstIndex": 15099493832}, +{"blockNumber": 20557251, "blockId": "0xa905087c15e2b12b19cd23f20089b471cd9815dcff73842d2043e13a276fcc55", "firstIndex": 15166601921}, +{"blockNumber": 20595654, "blockId": "0x9e7772dd946f65e7569f34f6896d8e597ac8ff88700b871de21ff578c0c995e6", "firstIndex": 15233711474}, +{"blockNumber": 20638340, "blockId": "0xc08b46af83db6f0e5d1acad7020bacd59d0f18df72651d32c9b60edd0351a886", "firstIndex": 15300820584}, +{"blockNumber": 20683359, "blockId": "0x7ec93a1f1d211c24d93ce7e344634efef680a6388374cf3831d250ecd63711f9", "firstIndex": 15367929168}, +{"blockNumber": 20728401, "blockId": "0x4ad4124c2595abcf4477cac4eb70c0c9372bbd48f2066c7ac5b8e9f94817ab48", "firstIndex": 15435038303}, +{"blockNumber": 20771272, "blockId": "0x68fd6b12fdb4add8b2957105a21b571c7dcb114c6c2ca02f5fa40730a108f864", "firstIndex": 15502146509}, +{"blockNumber": 20814862, "blockId": "0x4e7f640bf3c135b2442ca4c744023021af163e8d45e8d776fb7051c49d79fcff", "firstIndex": 15569256173}, +{"blockNumber": 20857627, "blockId": "0x9b023bffed12530b5a68db263bb621a147e0cf02b30ec39a82b82a1fdeb7ca36", "firstIndex": 15636364955}, +{"blockNumber": 20896662, "blockId": "0x8c3adf694b8520ed1edd38282b2f58cf383426176628b5be6330a56882e2a07e", "firstIndex": 15703473445}, +{"blockNumber": 20939156, "blockId": "0x0649e2559f767da945a674c9d6c700628109e18d0757ad33496a228a827413a4", "firstIndex": 15770581979}, +{"blockNumber": 20981054, "blockId": "0xebf0ecca671b833f77df70106cf1171d4dd3fa0f062607e4845569073997f1cd", "firstIndex": 15837691319}, +{"blockNumber": 21022980, "blockId": "0x07479520c08a727c42e3616aca7fc4435773f4ef277d84369190263159606d71", "firstIndex": 15904799391}, +{"blockNumber": 21068139, "blockId": "0x669cfd03b293a61815588cb9cef928a512d328c1fe9191fe6b281573f429f8b8", "firstIndex": 15971908604}, +{"blockNumber": 21112368, "blockId": "0x98957aedaf8b0483be208e8d16a3e6d73ff217e732f3649650671c92c8fb57a5", "firstIndex": 16039007815}, +{"blockNumber": 21155756, "blockId": "0xc301e40988fbe19b1254ab3abe2f78fe0cd35259898be02476179a041926f777", "firstIndex": 16106127130}, +{"blockNumber": 21200717, "blockId": "0x8d35b199ee65c5ccf4ca0fc22b50282850cd88b72580679f1568eea67d3431e8", "firstIndex": 16173235593}, +{"blockNumber": 21244396, "blockId": "0xe7ec084eb8a7125fe26c4ef64fdbb3e0a727b2d882fb1e4fdad1d7fa3dc55fd2", "firstIndex": 16240343803}, +{"blockNumber": 21290031, "blockId": "0x8bb31b883d30875b7ed8a01c35a6f51e603b8d974c4e74af20fb9c723e5ac5df", "firstIndex": 16307452772}, +{"blockNumber": 21335893, "blockId": "0xd0976b7c946a7556e607e47a02d2cfcccd259508e2828b9c4faa5c7105a597a8", "firstIndex": 16374562657}, +{"blockNumber": 21378611, "blockId": "0x72d42953f013aeb7c84bb22c9e07828b92f73885b20c208af612874df8fe85ed", "firstIndex": 16441671192}, +{"blockNumber": 21421343, "blockId": "0x663b3cddcf3f7cfa59ed29b4894e43fa784c07576cfec897ff1a3838235ecb50", "firstIndex": 16508779766}, +{"blockNumber": 21466598, "blockId": "0xe04ebd60289dbcc09a27e053e7b240a59e928e2a76a85a6fa4044ee387c46d18", "firstIndex": 16575888836}, +{"blockNumber": 21511717, "blockId": "0x5ea9863a0b504f381010ff383d60a56390ba9cef162d9d5a077b1884d2adac98", "firstIndex": 16642998234}, +{"blockNumber": 21550050, "blockId": "0x2a7b3e635c80521887ca3ebda04541090ec720dd817cd06fcba61e7ae0f78a4f", "firstIndex": 16710106733}, +{"blockNumber": 21592440, "blockId": "0xc7095268d0d53cb5a069c2ea7107cc42172bb1b817f04154938e6b52bdbb369c", "firstIndex": 16777215261}, +{"blockNumber": 21636007, "blockId": "0x55f463b932053ebfc02728a12c2cdfb2cb4700a115cde686c9ab22bb4c336ecb", "firstIndex": 16844324844}, +{"blockNumber": 21680799, "blockId": "0x4521d473aa7f5150f920c66fe639b20f30cb373b32e425fcb7dcce9803b506be", "firstIndex": 16911431255}, +{"blockNumber": 21725330, "blockId": "0x793876007ce3594df603628766b139a02273ceee43d5b3ca2d0ca2f13a5fc5d9", "firstIndex": 16978541626}, +{"blockNumber": 21771310, "blockId": "0xd0db23bb28d6e39917348b1879dd560c73354ea6d7d0bbee0b7a8fcbcede1091", "firstIndex": 17045650902}, +{"blockNumber": 21811348, "blockId": "0x8165948c08db34aeb8cc2a3e331a00af2d09fbff9c466019fb2f2892ca3f7b71", "firstIndex": 17112760024}, +{"blockNumber": 21851615, "blockId": "0x3083e8f4fbb4d726ef19b1a5bce20e639a0418eac384f9967f24c7697a7e2dfc", "firstIndex": 17179868870}, +{"blockNumber": 21894041, "blockId": "0x9b0776a020374e4985f6a7e1199596bedd387ff085f65224d724ab11955c56fe", "firstIndex": 17246977342}, +{"blockNumber": 21932218, "blockId": "0xe9c50eddc21759d3ab790e2babba56f4b8d38eb739f1b561bc337a1ba6e15393", "firstIndex": 17314085541}, +{"blockNumber": 21959188, "blockId": "0x6b9c482cc4822af2ad62a359b923062556ab6a046d1a39a8243b764848690601", "firstIndex": 17381193886}, +{"blockNumber": 21994911, "blockId": "0x0d99ef9dd42dd1c62fc5249eb4f618e7672ab93fa0ba7545c77360371cf972e5", "firstIndex": 17448302795}, +{"blockNumber": 22026007, "blockId": "0xf7cdc7f6694f2c2ed31fa8a607f65cfa59d0dd7d7424ab5c017f959ae2982c71", "firstIndex": 17515413036}, +{"blockNumber": 22059890, "blockId": "0x82b768a0dddefda2eefd3a33596ea2be075312f1dd4b01f6b0d377faca2af98b", "firstIndex": 17582521768} ] - diff --git a/core/filtermaps/checkpoints_sepolia.json b/core/filtermaps/checkpoints_sepolia.json index 3e3ea23b24..c6d3cd9086 100644 --- a/core/filtermaps/checkpoints_sepolia.json +++ b/core/filtermaps/checkpoints_sepolia.json @@ -1,63 +1,68 @@ [ -{"blockNumber": 3246675, "blockId": "0x36bf7de9e1f151963088ca3efa206b6e78411d699d2f64f3bf86895294275e0b", "firstIndex": 67107286}, -{"blockNumber": 3575582, "blockId": "0x08931012467636d3b67ae187790951daed2bb6423f9cd94e166df787b856788d", "firstIndex": 134217672}, -{"blockNumber": 3694264, "blockId": "0x1f35f276a3c78e5942ee285fcbd0c687691853c599a2f5b174ea88f653bc9514", "firstIndex": 201326578}, -{"blockNumber": 3725632, "blockId": "0x3bcb264c56c3eeab6c8588145f09dff3fb5f821d9fc1e7b92264b14314dae553", "firstIndex": 268433636}, -{"blockNumber": 3795390, "blockId": "0x2d1ef2815bb8e018b275fa65540b98265285016aff12596bd89a3b1442d248eb", "firstIndex": 335542953}, -{"blockNumber": 3856683, "blockId": "0x8a9a46d6f53975cd9ec829c3c307a99fb62b8428cefb63ffe06d17143649c3ee", "firstIndex": 402648835}, -{"blockNumber": 3869370, "blockId": "0x2e8c04e7e5e96d09260b65d77b1770b4105b0db2ee7d638c48f086b8afac17db", "firstIndex": 469759276}, -{"blockNumber": 3938357, "blockId": "0xf20f2cdbcc412d5340e31955d14a6526ea748ba99b5ec70b6615bdb18bcd4cfb", "firstIndex": 536868027}, -{"blockNumber": 3984894, "blockId": "0x0bcd886b3cebb884d5beeaf5ad15ee1514968b5ad07177297c7d9c00f27aa406", "firstIndex": 603968430}, -{"blockNumber": 4002664, "blockId": "0x7d3575b6ca685468fa5a5fa9ff9d5fac4415b0a67a3ed87d3530f127db32fff4", "firstIndex": 671088417}, -{"blockNumber": 4113187, "blockId": "0x3a5313ac5b602134bb73535b22801261e891ccb7bd660ab20e0a536dc46d3e13", "firstIndex": 738197016}, -{"blockNumber": 4260758, "blockId": "0xe30fb9a304d3602896a5716d310f67ba34ccef7f809a3ead4b2d991cb9ee4eb0", "firstIndex": 805306270}, -{"blockNumber": 4391131, "blockId": "0x3958478c1c3be9b7caedbcc96230ed446d711e56580e324bc2fcf903fc87c90f", "firstIndex": 872415115}, -{"blockNumber": 4515650, "blockId": "0x46a3a7b97a9dff4ef4dc2c1cc5cd501f2182d9548655b77b5e07a2dbb41071a4", "firstIndex": 939523930}, -{"blockNumber": 4634818, "blockId": "0x2197d0dd3925c1d7ba3e2c4eef20035b68efc0a2506f76ddd9e481e0ce8ca6e1", "firstIndex": 1006628557}, -{"blockNumber": 4718295, "blockId": "0xcce7bb4af1a41e6056ef68192e60c738be01ac3e071ed1ec52cead08a39995ce", "firstIndex": 1073734698}, -{"blockNumber": 4753438, "blockId": "0xa60e043728a369cdf39a399bd7a903085ee9386f38176947578e5692b4b01f65", "firstIndex": 1140843192}, -{"blockNumber": 4786522, "blockId": "0x10629cadc00e65f193fa4d10ecd2bf1855e442814c4a409d19aae9eb895dce13", "firstIndex": 1207956586}, -{"blockNumber": 4811706, "blockId": "0xf1e94111f0086733bdcb4a653486a8b94ec998b61dda0af0fd465c9b4e344f87", "firstIndex": 1275058221}, -{"blockNumber": 4841796, "blockId": "0xa530f7dd72881ac831affdc579c9d75f6d4b6853b1f1894d320bd9047df5f9eb", "firstIndex": 1342177155}, -{"blockNumber": 4914835, "blockId": "0xbd8321e354f72c4190225f8ed63d4aba794b3b568677d985e099cb62d9d36bae", "firstIndex": 1409286143}, -{"blockNumber": 4992519, "blockId": "0x4a06a5a4aa5bc52151937cc1c0f8da691a0282e94aab8b73b9faa87da8d028de", "firstIndex": 1476384367}, -{"blockNumber": 5088668, "blockId": "0xb7d5ee03c08ed3936348eeb3931be8f804e61f2b09debf305967c6a7bbf007e0", "firstIndex": 1543502599}, -{"blockNumber": 5155029, "blockId": "0x84f590dfc2e11f1ca53c1757ac3c508d56f55ee24d6ca5501895974be4250d76", "firstIndex": 1610605837}, -{"blockNumber": 5204413, "blockId": "0xeaf2c3fb6f927c16d38fab08b34303867b87470558612404c7f9e3256b80c5b9", "firstIndex": 1677720841}, -{"blockNumber": 5269957, "blockId": "0x596e0b2e8e4c18c803b61767320fe32c063153d870c94e4a08e9a68cbaa582a9", "firstIndex": 1744825147}, -{"blockNumber": 5337678, "blockId": "0x7b2d54f8af1ecaaaab994e137d4421d8236c1c10d9a7bdcb9e5500db7a3fe9a3", "firstIndex": 1811939316}, -{"blockNumber": 5399058, "blockId": "0xb61ef16d55c96682fb62b0110a2dbc50d8eff2526be4121ece3690700611c71b", "firstIndex": 1879046044}, -{"blockNumber": 5422707, "blockId": "0xdabcab7c0cc9cb9f22f7507a1076c87831cb1afed9d0aa5bcd93f22266720c91", "firstIndex": 1946156915}, -{"blockNumber": 5454264, "blockId": "0xe1bde812906605ce662f5fd9f01b49c7331fb25f52ab5b12d35ea2b4da5458fe", "firstIndex": 2013259168}, -{"blockNumber": 5498898, "blockId": "0x9533d9c5353d22f8a235e95831cfbf4d5a7220a430ca23494526a9d3aa866fe8", "firstIndex": 2080374321}, -{"blockNumber": 5554801, "blockId": "0xe7b320bbecb19f1e99dd6ce4aed1efc754d7b2022e1f80389e8a21413c465f55", "firstIndex": 2147476253}, -{"blockNumber": 5594725, "blockId": "0xce6750be4a5b3e0fe152dd02308e94f7d56b254852a7e9acef6e14105053d7d1", "firstIndex": 2214591591}, -{"blockNumber": 5645198, "blockId": "0x5d42d39999c546f37001d5f613732fb54032384dd71a686d3664d2c8a1337752", "firstIndex": 2281696503}, -{"blockNumber": 5687659, "blockId": "0x3ed941be39a33ffa69cf3531a67f5a25f712ba05db890ff377f60d26842e4b1c", "firstIndex": 2348801751}, -{"blockNumber": 5727823, "blockId": "0xaf699b6c4cd58181bd609a66990b8edb5d1b94d5ff1ab732ded35ce7b8373353", "firstIndex": 2415917178}, -{"blockNumber": 5784505, "blockId": "0x621c740d04ea41f70a2f0537e21e5b96169aea8a8efee0ae5527717e5c40aa64", "firstIndex": 2483024581}, -{"blockNumber": 5843958, "blockId": "0xec122204a4e4698748f55a1c9f8582c46bacda029aee4de1a234e67e3288e6b1", "firstIndex": 2550136761}, -{"blockNumber": 5906359, "blockId": "0x8af5ce73fbd7a6110fb8b19b75a7322456ece88fcfa1614c745f1a65f4e915c1", "firstIndex": 2617245617}, -{"blockNumber": 5977944, "blockId": "0xbc8186258298a4f376124989cfb7b22c2bea6603a5245bb6c505c5fc45844bbd", "firstIndex": 2684350982}, -{"blockNumber": 6051571, "blockId": "0x54f9df9d9d73d1aa1cfcd6f372377c6013ecba2a1ed158d3c304f4fca51dae58", "firstIndex": 2751463209}, -{"blockNumber": 6118461, "blockId": "0xfea757fad3f763c62a514a9c24924934539ca56620bd811f83e9cc2e671f0cf0", "firstIndex": 2818572283}, -{"blockNumber": 6174385, "blockId": "0x2d8d0226e58f7516c13f9e1c9cf3ea65bb520fa1dfd7249dc9ea34a4e1fd430d", "firstIndex": 2885681036}, -{"blockNumber": 6276318, "blockId": "0xa922e9d54fd062b658c4866ed218632ddd51f250d671628a42968bb912d3ed5d", "firstIndex": 2952789983}, -{"blockNumber": 6368452, "blockId": "0x8d3d7466a7c9ca7298f82c37c38b0f64ec04522d2ed2e2349f8edc020c57f2c4", "firstIndex": 3019898695}, -{"blockNumber": 6470810, "blockId": "0x9887c35542835ee81153fa0e4d8a9e6f170b6e14fc78d8c7f3d900d0a70434f1", "firstIndex": 3087007578}, -{"blockNumber": 6553334, "blockId": "0x7b0d89a0282c18785fcc108dbdc9d45dd9d63b7084ddc676df9e9504585a5969", "firstIndex": 3154115987}, -{"blockNumber": 6663825, "blockId": "0xff6cec99324a89d6d36275c17a4569f0cba203fe5b0350f155a7d5445e0ed419", "firstIndex": 3221224775}, -{"blockNumber": 6767082, "blockId": "0xe10a96a7194f98bf262f0cb1cdfb4d3b9a2072139dfcbe3f1eb01419e353044e", "firstIndex": 3288334139}, -{"blockNumber": 6886709, "blockId": "0x20f6a5d986913025ad5b6b6387d818e49a3caf838326f4002c1439ca61313be5", "firstIndex": 3355442979}, -{"blockNumber": 6978948, "blockId": "0xd7c3024765245ec49e6a48b076d540bc91f57f2ccc125e17d60dd37bb669f843", "firstIndex": 3422551908}, -{"blockNumber": 7098891, "blockId": "0x05114c037e1b4d69a46d74a974be9bce45e87ad2226a59b44dd17f98dd2fd0d1", "firstIndex": 3489659530}, -{"blockNumber": 7203157, "blockId": "0xc0f610014fcd9f2850274b58179d474f0947676fd0639b2884316467c631811d", "firstIndex": 3556769512}, -{"blockNumber": 7256735, "blockId": "0x0324c15b3b23fd82c2962dd167618e77e60ebeac5a2c87f672caddc9732337b3", "firstIndex": 3623876508}, -{"blockNumber": 7307851, "blockId": "0x8e23280d1a3aec877d7758413ed20299d381aa43e7e2fc6f381ad96e8ff0acef", "firstIndex": 3690987098}, -{"blockNumber": 7369389, "blockId": "0xbf6436eb2b88539945d6673141a14cb79ffc1e7db2b57176acf8e02ff3b6fcd3", "firstIndex": 3758096287}, -{"blockNumber": 7445220, "blockId": "0x147619f74815283d834ac08ff494fb4791207b3949c64b2623f11ff6141ee7a7", "firstIndex": 3825204992}, -{"blockNumber": 7511632, "blockId": "0x5094d64868f419e6ac3d253d19d5feda76564a0d56d7bbf8a822dff1c2261b30", "firstIndex": 3892314047}, -{"blockNumber": 7557280, "blockId": "0x54aba9351a1ba51873645221aa7c991024da1fe468a600ddb6e2559351d9c28f", "firstIndex": 3959422859}, -{"blockNumber": 7606304, "blockId": "0xbbe2fed08cf0b0ff2cb6ae9fd7257843f77a04a7d4cafb06d7a4bedea6ab0c98", "firstIndex": 4026531690} +{"blockNumber": 3246675, "blockId": "0x36bf7de9e1f151963088ca3efa206b6e78411d699d2f64f3bf86895294275e0b", "firstIndex": 67108765}, +{"blockNumber": 3575560, "blockId": "0x4652e3bee440f946aeaa3358c9a62b9bc4d41f663737ab00fded00c2662bfa29", "firstIndex": 134217644}, +{"blockNumber": 3694262, "blockId": "0x433573f97e563ca04fa53e0d0eb019d0ffe9dd032a05ee5b33ce7705aedfd34d", "firstIndex": 201316990}, +{"blockNumber": 3725628, "blockId": "0x1e25ebd76b9e2a2007bfdd7c82433cce7dae8beb190d249c82bf83d0cd177735", "firstIndex": 268426577}, +{"blockNumber": 3795378, "blockId": "0xca999083e01d5947212fb878d529abecdd18a6012997b0d5326afcf6908f17e5", "firstIndex": 335543438}, +{"blockNumber": 3856681, "blockId": "0x48148cd35de3de6c626f76ce5d97cfc6acd88772af69c0aef3d640c29ba82096", "firstIndex": 402641717}, +{"blockNumber": 3869367, "blockId": "0x08bafccf9ece7b72e4e069fc3c7493fbf25732881758917df2e8f9a51fc2c75f", "firstIndex": 469761225}, +{"blockNumber": 3938346, "blockId": "0xc638eb890c0e65ce1169ef0bb6b74dede2f4f6144ff8a5739c4894ff41a22fa2", "firstIndex": 536865235}, +{"blockNumber": 3984892, "blockId": "0x6a7782f0765b0f0c406b3cb107fd8bb14c6906293d9bdc5cc00e081bfd1ae59f", "firstIndex": 603972697}, +{"blockNumber": 4002660, "blockId": "0xda473de053602bc42fcbb074a32c908303f7f6db2ed8c38192665dce80276702", "firstIndex": 671087183}, +{"blockNumber": 4113149, "blockId": "0xd1782f677262226194725028858da83e672748e409fe1c21bdd77c07be0662c8", "firstIndex": 738197365}, +{"blockNumber": 4260733, "blockId": "0xc356600819e49d311963312157c481fd9be43a36ad040a0512fd17559c78d394", "firstIndex": 805305957}, +{"blockNumber": 4391073, "blockId": "0x06f903dc765b4b0ca1a40847eb74d30b0b51904a70c46f2e836dc5b3ea3dd8d3", "firstIndex": 872415067}, +{"blockNumber": 4515567, "blockId": "0xe99d3849755a1b4ec9a65d003260c111d4886e29ad6243fc750c72dbc79dbe4c", "firstIndex": 939523746}, +{"blockNumber": 4634815, "blockId": "0x9f281e749b192ef58242ff9fccd496a9075c30bd28c61ed4ce6487fc2d167e5c", "firstIndex": 1006629595}, +{"blockNumber": 4718286, "blockId": "0x23d2a40ec3ae059a45006ba651a70f308b6b282829b9cfdf2534e4311e34050f", "firstIndex": 1073731435}, +{"blockNumber": 4753427, "blockId": "0x6df7295f9ccb45a95e6cc72a8ee56bda992513b3bf4baa3d62219871a0b5a912", "firstIndex": 1140843105}, +{"blockNumber": 4786511, "blockId": "0x705c79435411c1af81385a1eca34343427eceb3f6af72e7f665552d6b0eceb6c", "firstIndex": 1207957185}, +{"blockNumber": 4811696, "blockId": "0x69a6e60d1b958b469feafb1dca97f38f97620a90c21ed92f90080f6443ee6c78", "firstIndex": 1275061401}, +{"blockNumber": 4841770, "blockId": "0x0a0e9d2d3d177601a478428297b5b9a42124166fefe42f2221c7a612c31e7ca1", "firstIndex": 1342174442}, +{"blockNumber": 4914785, "blockId": "0x5ca0e12230aeacbce9064dff15dafb9f24e20b4a737f7d04df8549008b829fa3", "firstIndex": 1409284680}, +{"blockNumber": 4992516, "blockId": "0xb9cb1700d8b65615fc3a019b2e9b2ece3b4f1e0e2fcfc01ff40bcf53e7291b10", "firstIndex": 1476387066}, +{"blockNumber": 5088617, "blockId": "0x33122f693a264fb2ab626232fac5e2714010fd65bdceb772109511f7c9497333", "firstIndex": 1543503849}, +{"blockNumber": 5155024, "blockId": "0x187716822dd6ab9c21138ae5a8e763197a5e7ec48bf0e756c5e6fa2c9f2f24bf", "firstIndex": 1610604247}, +{"blockNumber": 5204373, "blockId": "0x753b6495979ca90a1b915edad6af33c58bbabe68b45f95c7645113ec1d35d0e6", "firstIndex": 1677721200}, +{"blockNumber": 5269952, "blockId": "0xcbb0409ed824631120d6951b55537143d9a1c82ca6dd6255d2eb31c57844685c", "firstIndex": 1744829248}, +{"blockNumber": 5337623, "blockId": "0x0b460658511c4ae5205c038430789f9b31f3c08ba4acc06d273b7a13a149cf8b", "firstIndex": 1811939255}, +{"blockNumber": 5399044, "blockId": "0x9d07e37321e2b019f4837cc4f95f103da87ecdcb77e131e9d42d8643b0446524", "firstIndex": 1879041131}, +{"blockNumber": 5422692, "blockId": "0x9d9e27614635989788e32f15cd7a0abf7470dccf3336b77547baeb3423b629ca", "firstIndex": 1946154968}, +{"blockNumber": 5454259, "blockId": "0x01e694443d471d3411fe0b52720fd4a189e687b14cc8ede116f5e93f0ad96bb6", "firstIndex": 2013265148}, +{"blockNumber": 5498863, "blockId": "0xc4cb906c96d9f80b830b8add25318c38b3ff857c1bd577cd9cae0a324a068ffc", "firstIndex": 2080373677}, +{"blockNumber": 5554788, "blockId": "0x9b934b2d66723559d82e0f4cd49a2497234fe892248cb2f46c13f6a9585cfddd", "firstIndex": 2147475372}, +{"blockNumber": 5594711, "blockId": "0x840c0b7889b8c882cfa0eceb516dd73043b51c0e5a0c1be849a0e2a5dda7e842", "firstIndex": 2214592267}, +{"blockNumber": 5645179, "blockId": "0x188873a43506fee33349bc33df4a55059401e98dc7f0a5d488a0bc5c87dfd431", "firstIndex": 2281695869}, +{"blockNumber": 5687634, "blockId": "0x7ea8d7a2afccf795a2a02eb00746d89db57f13f8936cf7ab0f0a7db1b1ceb341", "firstIndex": 2348806824}, +{"blockNumber": 5727808, "blockId": "0x3f3eaf36c8e0271403737676907eac15312927c1d60ce814337654b7d7f2b2bd", "firstIndex": 2415915517}, +{"blockNumber": 5784480, "blockId": "0x10ec5adf01449c29550f5117f09ecafc49fc614d7da5886cf01619950827f850", "firstIndex": 2483023750}, +{"blockNumber": 5843906, "blockId": "0x9e6e14b3fba395a9ae7b3f1295f33a12d0f8b9f10e1aaab1649a90a56a323676", "firstIndex": 2550136398}, +{"blockNumber": 5906280, "blockId": "0x2188869a164e9c19232f6702a5233dc27a2304839159dd7230cc93ebdfc6c048", "firstIndex": 2617245012}, +{"blockNumber": 5977929, "blockId": "0xb247181ed597d9473c2c6e5762ae45a05f328d8df215fdac83d19ae4c028109a", "firstIndex": 2684347033}, +{"blockNumber": 6051479, "blockId": "0x0e8634c95dac31b7c835b44d0a14290e9212b31b9c3f621997ad1cca2d8ab0ba", "firstIndex": 2751463372}, +{"blockNumber": 6118422, "blockId": "0xa642c4457d4b63d68a5502bdba2355616e34495bf3ab2d8518a45ded54a16be4", "firstIndex": 2818563217}, +{"blockNumber": 6174274, "blockId": "0xbb9808bc56b5f14636e654bdd6d50d35b31345255926341ef3ddb54840095bcc", "firstIndex": 2885680274}, +{"blockNumber": 6276207, "blockId": "0x7ae027a18889e1b60a46ea3e5f2759035f3d9041de68eca0b154068ec533db59", "firstIndex": 2952789656}, +{"blockNumber": 6368344, "blockId": "0x8b4401f89589d9e99259e6c05c18b1780e96b65027caf9d83edf80390d317f66", "firstIndex": 3019898378}, +{"blockNumber": 6470718, "blockId": "0x0e2f8de093392c38750581c41e93c2fb1c0f6676b65c9af52792f3c56e894457", "firstIndex": 3087007589}, +{"blockNumber": 6553237, "blockId": "0xa6c4f3a1fe3b4e116c367fcbb1ae98e0f25570fdb2f1eadee2681deb39462c1e", "firstIndex": 3154116356}, +{"blockNumber": 6663750, "blockId": "0x9049748ddf655c7cc2ccbe2d36010b3a67ae011d114d32b1c812a7a53102f27f", "firstIndex": 3221225375}, +{"blockNumber": 6766894, "blockId": "0xc98188fb313b1beb7fc4f415b4a74c363903b3b5e0172437d79446bc011238b5", "firstIndex": 3288334172}, +{"blockNumber": 6886576, "blockId": "0x4ae8237a94198c82c266f01e472fdcd3ae150c84ecf714205a9be672f1e705b8", "firstIndex": 3355443040}, +{"blockNumber": 6978746, "blockId": "0xb2b69ce29c5c9c46c5cbc6e96260c34313d8b0b4a739cf4091c98f37093aa732", "firstIndex": 3422552017}, +{"blockNumber": 7098871, "blockId": "0x9ab2b681feeb38287a1b689fa64a50efd3407b6331fd6896187cad98a29ce107", "firstIndex": 3489660879}, +{"blockNumber": 7203023, "blockId": "0xdedfff5985c1c93d476120d2afbaa61967bae4edabb9711c7794a1b1cd453aa1", "firstIndex": 3556769365}, +{"blockNumber": 7256709, "blockId": "0xc078041cffc1802b6342fd2ba5a92ff8076ac0f5b72b4a77ba75cd486fe1b3c9", "firstIndex": 3623876563}, +{"blockNumber": 7307744, "blockId": "0xdf8dcdd4af9213a79587eb2f4d91f4111da74f99207ee05e4ae50bcb4f8d5435", "firstIndex": 3690986225}, +{"blockNumber": 7369268, "blockId": "0x62315823621a38a1f138e193b85259988fcc15f4a74d0cf19a412920bcdcad98", "firstIndex": 3758096030}, +{"blockNumber": 7445109, "blockId": "0x8b668ac1274a8dcc9526eb115c2f67bd56f6657b5072c7542da2252daca10fef", "firstIndex": 3825204921}, +{"blockNumber": 7511512, "blockId": "0x056ad7411652aa64849c67705a86e42221cb88f7fb6a7012ab7d3d5b9a30eb76", "firstIndex": 3892313524}, +{"blockNumber": 7557259, "blockId": "0xef660b97661f073b7c7319b69451e16d26ecaed54f9237e209999d137da2bfd4", "firstIndex": 3959415096}, +{"blockNumber": 7606260, "blockId": "0x9f5f06ad381166261780864bf17ad4d3cdd475f87ba51fa7f9ba621bf0ac0acb", "firstIndex": 4026521703}, +{"blockNumber": 7654244, "blockId": "0xefe5b537435001203741bf445ca26466baf7ad3f63c2bba94f0f658aed8c244b", "firstIndex": 4093627258}, +{"blockNumber": 7700433, "blockId": "0x89af6e8c5aa934a9139944b3de7a15232069479dba387e0fdd043ad36156c8bf", "firstIndex": 4160749200}, +{"blockNumber": 7730079, "blockId": "0x08e0d511a93e2a9c004b3456d77d687ae86247417ada1cdd1f85332a62dfed1d", "firstIndex": 4227846795}, +{"blockNumber": 7777515, "blockId": "0xeba8faed2e12bb9ed5e7fad19dd82662f15f6f4f512a0d232eedf1e676712428", "firstIndex": 4294966082}, +{"blockNumber": 7828860, "blockId": "0x62c054bd24be351dc4777460ee922a75fdcea5c9830455cbac6fa29552719c85", "firstIndex": 4362076087}, +{"blockNumber": 7869890, "blockId": "0x5664bcfa6151f798781e22bea4f9a2c796d097402350cb131e4e3c78e13e461a", "firstIndex": 4429183267} ] - diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index 95dd181551..fe75c1ea7d 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -95,11 +95,11 @@ type FilterMaps struct { targetView *ChainView matcherSyncRequest *FilterMapsMatcherBackend + historyCutoff uint64 finalBlock, lastFinal uint64 lastFinalEpoch uint32 stop bool - targetViewCh chan *ChainView - finalBlockCh chan uint64 + targetCh chan targetUpdate blockProcessingCh chan bool blockProcessing bool matcherSyncCh chan *FilterMapsMatcherBackend @@ -145,24 +145,23 @@ func (a FilterRow) Equal(b FilterRow) bool { // filterMapsRange describes the rendered range of filter maps and the range // of fully rendered blocks. type filterMapsRange struct { - initialized bool - headBlockIndexed bool - headBlockDelimiter uint64 // zero if afterLastIndexedBlock != targetBlockNumber - // if initialized then all maps are rendered between firstRenderedMap and - // afterLastRenderedMap-1 - firstRenderedMap, afterLastRenderedMap uint32 + initialized bool + headIndexed bool + headDelimiter uint64 // zero if headIndexed is false + // if initialized then all maps are rendered in the maps range + maps common.Range[uint32] // if tailPartialEpoch > 0 then maps between firstRenderedMap-mapsPerEpoch and // firstRenderedMap-mapsPerEpoch+tailPartialEpoch-1 are rendered tailPartialEpoch uint32 - // if initialized then all log values belonging to blocks between - // firstIndexedBlock and afterLastIndexedBlock are fully rendered - // blockLvPointers are available between firstIndexedBlock and afterLastIndexedBlock-1 - firstIndexedBlock, afterLastIndexedBlock uint64 + // if initialized then all log values in the blocks range are fully + // rendered + // blockLvPointers are available in the blocks range + blocks common.Range[uint64] } // hasIndexedBlocks returns true if the range has at least one fully indexed block. func (fmr *filterMapsRange) hasIndexedBlocks() bool { - return fmr.initialized && fmr.afterLastIndexedBlock > fmr.firstIndexedBlock + return fmr.initialized && !fmr.blocks.IsEmpty() && !fmr.maps.IsEmpty() } // lastBlockOfMap is used for caching the (number, id) pairs belonging to the @@ -183,7 +182,7 @@ type Config struct { } // NewFilterMaps creates a new FilterMaps and starts the indexer. -func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, params Params, config Config) *FilterMaps { +func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) *FilterMaps { rs, initialized, err := rawdb.ReadFilterMapsRange(db) if err != nil { log.Error("Error reading log index range", "error", err) @@ -193,22 +192,19 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, params Params, c db: db, closeCh: make(chan struct{}), waitIdleCh: make(chan chan bool), - targetViewCh: make(chan *ChainView, 1), - finalBlockCh: make(chan uint64, 1), + targetCh: make(chan targetUpdate, 1), blockProcessingCh: make(chan bool, 1), history: config.History, disabled: config.Disabled, exportFileName: config.ExportFileName, Params: params, indexedRange: filterMapsRange{ - initialized: initialized, - headBlockIndexed: rs.HeadBlockIndexed, - headBlockDelimiter: rs.HeadBlockDelimiter, - firstIndexedBlock: rs.FirstIndexedBlock, - afterLastIndexedBlock: rs.AfterLastIndexedBlock, - firstRenderedMap: rs.FirstRenderedMap, - afterLastRenderedMap: rs.AfterLastRenderedMap, - tailPartialEpoch: rs.TailPartialEpoch, + initialized: initialized, + headIndexed: rs.HeadIndexed, + headDelimiter: rs.HeadDelimiter, + blocks: common.NewRange(rs.BlocksFirst, rs.BlocksAfterLast-rs.BlocksFirst), + maps: common.NewRange(rs.MapsFirst, rs.MapsAfterLast-rs.MapsFirst), + tailPartialEpoch: rs.TailPartialEpoch, }, matcherSyncCh: make(chan *FilterMapsMatcherBackend), matchers: make(map[*FilterMapsMatcherBackend]struct{}), @@ -223,24 +219,23 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, params Params, c f.targetView = initView if f.indexedRange.initialized { f.indexedView = f.initChainView(f.targetView) - f.indexedRange.headBlockIndexed = f.indexedRange.afterLastIndexedBlock == f.indexedView.headNumber+1 - if !f.indexedRange.headBlockIndexed { - f.indexedRange.headBlockDelimiter = 0 + f.indexedRange.headIndexed = f.indexedRange.blocks.AfterLast() == f.indexedView.headNumber+1 + if !f.indexedRange.headIndexed { + f.indexedRange.headDelimiter = 0 } } if f.indexedRange.hasIndexedBlocks() { log.Info("Initialized log indexer", - "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, - "first map", f.indexedRange.firstRenderedMap, "last map", f.indexedRange.afterLastRenderedMap-1, - "head indexed", f.indexedRange.headBlockIndexed) + "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "first map", f.indexedRange.maps.First(), "last map", f.indexedRange.maps.Last(), + "head indexed", f.indexedRange.headIndexed) } return f } // Start starts the indexer. func (f *FilterMaps) Start() { - if !f.testDisableSnapshots && f.indexedRange.initialized && f.indexedRange.headBlockIndexed && - f.indexedRange.firstRenderedMap < f.indexedRange.afterLastRenderedMap { + if !f.testDisableSnapshots && f.indexedRange.hasIndexedBlocks() && f.indexedRange.headIndexed { // previous target head rendered; load last map as snapshot if err := f.loadHeadSnapshot(); err != nil { log.Error("Could not load head filter map snapshot", "error", err) @@ -262,7 +257,7 @@ func (f *FilterMaps) Stop() { // Note that the returned view might be shorter than the existing index if // the latest maps are not consistent with targetView. func (f *FilterMaps) initChainView(chainView *ChainView) *ChainView { - mapIndex := f.indexedRange.afterLastRenderedMap + mapIndex := f.indexedRange.maps.AfterLast() for { var ok bool mapIndex, ok = f.lastMapBoundaryBefore(mapIndex) @@ -332,10 +327,8 @@ func (f *FilterMaps) init() error { } if bestLen > 0 { cp := checkpoints[bestIdx][bestLen-1] - fmr.firstIndexedBlock = cp.BlockNumber + 1 - fmr.afterLastIndexedBlock = cp.BlockNumber + 1 - fmr.firstRenderedMap = uint32(bestLen) << f.logMapsPerEpoch - fmr.afterLastRenderedMap = uint32(bestLen) << f.logMapsPerEpoch + fmr.blocks = common.NewRange(cp.BlockNumber+1, 0) + fmr.maps = common.NewRange(uint32(bestLen)<> f.logValuesPerMap) - if mapIndex < f.indexedRange.firstRenderedMap || mapIndex >= f.indexedRange.afterLastRenderedMap { + if !f.indexedRange.maps.Includes(mapIndex) { return nil, nil } // find possible block range based on map to block pointers @@ -425,8 +418,8 @@ func (f *FilterMaps) getLogByLvIndex(lvIndex uint64) (*types.Log, error) { return nil, fmt.Errorf("failed to retrieve last block of map %d before searched log value index %d: %v", mapIndex, lvIndex, err) } } - if firstBlockNumber < f.indexedRange.firstIndexedBlock { - firstBlockNumber = f.indexedRange.firstIndexedBlock + if firstBlockNumber < f.indexedRange.blocks.First() { + firstBlockNumber = f.indexedRange.blocks.First() } // find block with binary search based on block to log value index pointers for firstBlockNumber < lastBlockNumber { @@ -453,6 +446,11 @@ func (f *FilterMaps) getLogByLvIndex(lvIndex uint64) (*types.Log, error) { // iterate through receipts to find the exact log starting at lvIndex for _, receipt := range receipts { for _, log := range receipt.Logs { + l := uint64(len(log.Topics) + 1) + r := f.valuesPerMap - lvPointer%f.valuesPerMap + if l > r { + lvPointer += r // skip to map boundary + } if lvPointer > lvIndex { // lvIndex does not point to the first log value (address value) // generated by a log as true matches should always do, so it @@ -462,7 +460,7 @@ func (f *FilterMaps) getLogByLvIndex(lvIndex uint64) (*types.Log, error) { if lvPointer == lvIndex { return log, nil // potential match } - lvPointer += uint64(len(log.Topics) + 1) + lvPointer += l } } return nil, nil @@ -580,8 +578,8 @@ func (f *FilterMaps) mapRowIndex(mapIndex, rowIndex uint32) uint64 { // Note that this function assumes that the indexer read lock is being held when // called from outside the indexerLoop goroutine. func (f *FilterMaps) getBlockLvPointer(blockNumber uint64) (uint64, error) { - if blockNumber >= f.indexedRange.afterLastIndexedBlock && f.indexedRange.headBlockIndexed { - return f.indexedRange.headBlockDelimiter, nil + if blockNumber >= f.indexedRange.blocks.AfterLast() && f.indexedRange.headIndexed { + return f.indexedRange.headDelimiter, nil } if lvPointer, ok := f.lvPointerCache.Get(blockNumber); ok { return lvPointer, nil @@ -658,26 +656,28 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) error { firstBlock++ } fmr := f.indexedRange - if f.indexedRange.firstRenderedMap == firstMap && - f.indexedRange.afterLastRenderedMap > firstMap+f.mapsPerEpoch && + if f.indexedRange.maps.First() == firstMap && + f.indexedRange.maps.AfterLast() > firstMap+f.mapsPerEpoch && f.indexedRange.tailPartialEpoch == 0 { - fmr.firstRenderedMap = firstMap + f.mapsPerEpoch - fmr.firstIndexedBlock = lastBlock + 1 - } else if f.indexedRange.firstRenderedMap == firstMap+f.mapsPerEpoch { + fmr.maps.SetFirst(firstMap + f.mapsPerEpoch) + fmr.blocks.SetFirst(lastBlock + 1) + } else if f.indexedRange.maps.First() == firstMap+f.mapsPerEpoch { fmr.tailPartialEpoch = 0 } else { return errors.New("invalid tail epoch number") } f.setRange(f.db, f.indexedView, fmr) - rawdb.DeleteFilterMapRows(f.db, f.mapRowIndex(firstMap, 0), f.mapRowIndex(firstMap+f.mapsPerEpoch, 0)) + first := f.mapRowIndex(firstMap, 0) + count := f.mapRowIndex(firstMap+f.mapsPerEpoch, 0) - first + rawdb.DeleteFilterMapRows(f.db, common.NewRange(first, count)) for mapIndex := firstMap; mapIndex < firstMap+f.mapsPerEpoch; mapIndex++ { f.filterMapCache.Remove(mapIndex) } - rawdb.DeleteFilterMapLastBlocks(f.db, firstMap, firstMap+f.mapsPerEpoch-1) // keep last enrty + rawdb.DeleteFilterMapLastBlocks(f.db, common.NewRange(firstMap, f.mapsPerEpoch-1)) // keep last enrty for mapIndex := firstMap; mapIndex < firstMap+f.mapsPerEpoch-1; mapIndex++ { f.lastBlockCache.Remove(mapIndex) } - rawdb.DeleteBlockLvPointers(f.db, firstBlock, lastBlock) // keep last enrty + rawdb.DeleteBlockLvPointers(f.db, common.NewRange(firstBlock, lastBlock-firstBlock)) // keep last enrty for blockNumber := firstBlock; blockNumber < lastBlock; blockNumber++ { f.lvPointerCache.Remove(blockNumber) } diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 54a3687648..addda03df4 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -66,28 +66,25 @@ func (f *FilterMaps) indexerLoop() { } } +type targetUpdate struct { + targetView *ChainView + historyCutoff, finalBlock uint64 +} + // SetTargetView sets a new target chain view for the indexer to render. // Note that SetTargetView never blocks. -func (f *FilterMaps) SetTargetView(targetView *ChainView) { +func (f *FilterMaps) SetTarget(targetView *ChainView, historyCutoff, finalBlock uint64) { if targetView == nil { panic("nil targetView") } for { select { - case <-f.targetViewCh: - case f.targetViewCh <- targetView: - return - } - } -} - -// SetFinalBlock sets the finalized block number used for exporting checkpoints. -// Note that SetFinalBlock never blocks. -func (f *FilterMaps) SetFinalBlock(finalBlock uint64) { - for { - select { - case <-f.finalBlockCh: - case f.finalBlockCh <- finalBlock: + case <-f.targetCh: + case f.targetCh <- targetUpdate{ + targetView: targetView, + historyCutoff: historyCutoff, + finalBlock: finalBlock, + }: return } } @@ -145,26 +142,24 @@ func (f *FilterMaps) processSingleEvent(blocking bool) bool { } if blocking { select { - case targetView := <-f.targetViewCh: - f.setTargetView(targetView) - case f.finalBlock = <-f.finalBlockCh: + case target := <-f.targetCh: + f.setTarget(target) case f.matcherSyncRequest = <-f.matcherSyncCh: case f.blockProcessing = <-f.blockProcessingCh: case <-f.closeCh: f.stop = true case ch := <-f.waitIdleCh: select { - case targetView := <-f.targetViewCh: - f.setTargetView(targetView) + case target := <-f.targetCh: + f.setTarget(target) default: } ch <- !f.blockProcessing && f.targetHeadIndexed() } } else { select { - case targetView := <-f.targetViewCh: - f.setTargetView(targetView) - case f.finalBlock = <-f.finalBlockCh: + case target := <-f.targetCh: + f.setTarget(target) case f.matcherSyncRequest = <-f.matcherSyncCh: case f.blockProcessing = <-f.blockProcessingCh: case <-f.closeCh: @@ -177,8 +172,10 @@ func (f *FilterMaps) processSingleEvent(blocking bool) bool { } // setTargetView updates the target chain view of the iterator. -func (f *FilterMaps) setTargetView(targetView *ChainView) { - f.targetView = targetView +func (f *FilterMaps) setTarget(target targetUpdate) { + f.targetView = target.targetView + f.historyCutoff = target.historyCutoff + f.finalBlock = target.finalBlock } // tryIndexHead tries to render head maps according to the current targetView @@ -196,20 +193,20 @@ func (f *FilterMaps) tryIndexHead() bool { f.lastLogHeadIndex = time.Now() f.startedHeadIndexAt = f.lastLogHeadIndex f.startedHeadIndex = true - f.ptrHeadIndex = f.indexedRange.afterLastIndexedBlock + f.ptrHeadIndex = f.indexedRange.blocks.AfterLast() } if _, err := headRenderer.run(func() bool { f.processEvents() return f.stop }, func() { f.tryUnindexTail() - if f.indexedRange.hasIndexedBlocks() && f.indexedRange.afterLastIndexedBlock >= f.ptrHeadIndex && + if f.indexedRange.hasIndexedBlocks() && f.indexedRange.blocks.AfterLast() >= f.ptrHeadIndex && ((!f.loggedHeadIndex && time.Since(f.startedHeadIndexAt) > headLogDelay) || time.Since(f.lastLogHeadIndex) > logFrequency) { log.Info("Log index head rendering in progress", - "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, - "processed", f.indexedRange.afterLastIndexedBlock-f.ptrHeadIndex, - "remaining", f.indexedView.headNumber+1-f.indexedRange.afterLastIndexedBlock, + "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "processed", f.indexedRange.blocks.AfterLast()-f.ptrHeadIndex, + "remaining", f.indexedView.headNumber-f.indexedRange.blocks.Last(), "elapsed", common.PrettyDuration(time.Since(f.startedHeadIndexAt))) f.loggedHeadIndex = true f.lastLogHeadIndex = time.Now() @@ -218,10 +215,10 @@ func (f *FilterMaps) tryIndexHead() bool { log.Error("Log index head rendering failed", "error", err) return false } - if f.loggedHeadIndex { + if f.loggedHeadIndex && f.indexedRange.hasIndexedBlocks() { log.Info("Log index head rendering finished", - "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, - "processed", f.indexedRange.afterLastIndexedBlock-f.ptrHeadIndex, + "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "processed", f.indexedRange.blocks.AfterLast()-f.ptrHeadIndex, "elapsed", common.PrettyDuration(time.Since(f.startedHeadIndexAt))) } f.loggedHeadIndex, f.startedHeadIndex = false, false @@ -234,7 +231,11 @@ func (f *FilterMaps) tryIndexHead() bool { // rendered according to targetView and is suspended as soon as the targetView // is changed. func (f *FilterMaps) tryIndexTail() bool { - for firstEpoch := f.indexedRange.firstRenderedMap >> f.logMapsPerEpoch; firstEpoch > 0 && f.needTailEpoch(firstEpoch-1); { + for { + firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch + if firstEpoch == 0 || !f.needTailEpoch(firstEpoch-1) { + break + } f.processEvents() if f.stop || !f.targetHeadIndexed() { return false @@ -242,25 +243,25 @@ func (f *FilterMaps) tryIndexTail() bool { // resume process if tail rendering was interrupted because of head rendering tailRenderer := f.tailRenderer f.tailRenderer = nil - if tailRenderer != nil && tailRenderer.afterLastMap != f.indexedRange.firstRenderedMap { + if tailRenderer != nil && tailRenderer.renderBefore != f.indexedRange.maps.First() { tailRenderer = nil } if tailRenderer == nil { var err error - tailRenderer, err = f.renderMapsBefore(f.indexedRange.firstRenderedMap) + tailRenderer, err = f.renderMapsBefore(f.indexedRange.maps.First()) if err != nil { log.Error("Error creating log index tail renderer", "error", err) return false } } if tailRenderer == nil { - return true + break } if !f.startedTailIndex { f.lastLogTailIndex = time.Now() f.startedTailIndexAt = f.lastLogTailIndex f.startedTailIndex = true - f.ptrTailIndex = f.indexedRange.firstIndexedBlock - f.tailPartialBlocks() + f.ptrTailIndex = f.indexedRange.blocks.First() - f.tailPartialBlocks() } done, err := tailRenderer.run(func() bool { f.processEvents() @@ -268,14 +269,14 @@ func (f *FilterMaps) tryIndexTail() bool { }, func() { tpb, ttb := f.tailPartialBlocks(), f.tailTargetBlock() remaining := uint64(1) - if f.indexedRange.firstIndexedBlock > ttb+tpb { - remaining = f.indexedRange.firstIndexedBlock - ttb - tpb + if f.indexedRange.blocks.First() > ttb+tpb { + remaining = f.indexedRange.blocks.First() - ttb - tpb } - if f.indexedRange.hasIndexedBlocks() && f.ptrTailIndex >= f.indexedRange.firstIndexedBlock && + if f.indexedRange.hasIndexedBlocks() && f.ptrTailIndex >= f.indexedRange.blocks.First() && (!f.loggedTailIndex || time.Since(f.lastLogTailIndex) > logFrequency) { log.Info("Log index tail rendering in progress", - "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, - "processed", f.ptrTailIndex-f.indexedRange.firstIndexedBlock+tpb, + "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "processed", f.ptrTailIndex-f.indexedRange.blocks.First()+tpb, "remaining", remaining, "next tail epoch percentage", f.indexedRange.tailPartialEpoch*100/f.mapsPerEpoch, "elapsed", common.PrettyDuration(time.Since(f.startedTailIndexAt))) @@ -283,7 +284,8 @@ func (f *FilterMaps) tryIndexTail() bool { f.lastLogTailIndex = time.Now() } }) - if err != nil { + if err != nil && f.needTailEpoch(firstEpoch-1) { + // stop silently if cutoff point has move beyond epoch boundary while rendering log.Error("Log index tail rendering failed", "error", err) } if !done { @@ -291,10 +293,10 @@ func (f *FilterMaps) tryIndexTail() bool { return false } } - if f.loggedTailIndex { + if f.loggedTailIndex && f.indexedRange.hasIndexedBlocks() { log.Info("Log index tail rendering finished", - "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, - "processed", f.ptrTailIndex-f.indexedRange.firstIndexedBlock, + "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "processed", f.ptrTailIndex-f.indexedRange.blocks.First(), "elapsed", common.PrettyDuration(time.Since(f.startedTailIndexAt))) f.loggedTailIndex = false } @@ -307,7 +309,7 @@ func (f *FilterMaps) tryIndexTail() bool { // data from the database and is also called while running head indexing. func (f *FilterMaps) tryUnindexTail() bool { for { - firstEpoch := (f.indexedRange.firstRenderedMap - f.indexedRange.tailPartialEpoch) >> f.logMapsPerEpoch + firstEpoch := (f.indexedRange.maps.First() - f.indexedRange.tailPartialEpoch) >> f.logMapsPerEpoch if f.needTailEpoch(firstEpoch) { break } @@ -318,19 +320,19 @@ func (f *FilterMaps) tryUnindexTail() bool { if !f.startedTailUnindex { f.startedTailUnindexAt = time.Now() f.startedTailUnindex = true - f.ptrTailUnindexMap = f.indexedRange.firstRenderedMap - f.indexedRange.tailPartialEpoch - f.ptrTailUnindexBlock = f.indexedRange.firstIndexedBlock - f.tailPartialBlocks() + f.ptrTailUnindexMap = f.indexedRange.maps.First() - f.indexedRange.tailPartialEpoch + f.ptrTailUnindexBlock = f.indexedRange.blocks.First() - f.tailPartialBlocks() } if err := f.deleteTailEpoch(firstEpoch); err != nil { log.Error("Log index tail epoch unindexing failed", "error", err) return false } } - if f.startedTailUnindex { + if f.startedTailUnindex && f.indexedRange.hasIndexedBlocks() { log.Info("Log index tail unindexing finished", - "first block", f.indexedRange.firstIndexedBlock, "last block", f.indexedRange.afterLastIndexedBlock-1, - "removed maps", f.indexedRange.firstRenderedMap-f.ptrTailUnindexMap, - "removed blocks", f.indexedRange.firstIndexedBlock-f.tailPartialBlocks()-f.ptrTailUnindexBlock, + "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "removed maps", f.indexedRange.maps.First()-f.ptrTailUnindexMap, + "removed blocks", f.indexedRange.blocks.First()-f.tailPartialBlocks()-f.ptrTailUnindexBlock, "elapsed", common.PrettyDuration(time.Since(f.startedTailUnindexAt))) f.startedTailUnindex = false } @@ -340,23 +342,29 @@ func (f *FilterMaps) tryUnindexTail() bool { // needTailEpoch returns true if the given tail epoch needs to be kept // according to the current tail target, false if it can be removed. func (f *FilterMaps) needTailEpoch(epoch uint32) bool { - firstEpoch := f.indexedRange.firstRenderedMap >> f.logMapsPerEpoch + firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch if epoch > firstEpoch { return true } if epoch+1 < firstEpoch { return false } - tailTarget := f.tailTargetBlock() - if tailTarget < f.indexedRange.firstIndexedBlock { - return true + if epoch > 0 { + lastBlockOfPrevEpoch, _, err := f.getLastBlockOfMap(epoch<= firstEpoch + } + if f.historyCutoff > lastBlockOfPrevEpoch { + return false + } } - tailLvIndex, err := f.getBlockLvPointer(tailTarget) + lastBlockOfEpoch, _, err := f.getLastBlockOfMap((epoch+1)<= firstEpoch } - return uint64(epoch+1)<<(f.logValuesPerMap+f.logMapsPerEpoch) >= tailLvIndex + return f.tailTargetBlock() <= lastBlockOfEpoch } // tailTargetBlock returns the target value for the tail block number according @@ -374,15 +382,15 @@ func (f *FilterMaps) tailPartialBlocks() uint64 { if f.indexedRange.tailPartialEpoch == 0 { return 0 } - end, _, err := f.getLastBlockOfMap(f.indexedRange.firstRenderedMap - f.mapsPerEpoch + f.indexedRange.tailPartialEpoch - 1) + end, _, err := f.getLastBlockOfMap(f.indexedRange.maps.First() - f.mapsPerEpoch + f.indexedRange.tailPartialEpoch - 1) if err != nil { - log.Error("Error fetching last block of map", "mapIndex", f.indexedRange.firstRenderedMap-f.mapsPerEpoch+f.indexedRange.tailPartialEpoch-1, "error", err) + log.Error("Error fetching last block of map", "mapIndex", f.indexedRange.maps.First()-f.mapsPerEpoch+f.indexedRange.tailPartialEpoch-1, "error", err) } var start uint64 - if f.indexedRange.firstRenderedMap-f.mapsPerEpoch > 0 { - start, _, err = f.getLastBlockOfMap(f.indexedRange.firstRenderedMap - f.mapsPerEpoch - 1) + if f.indexedRange.maps.First()-f.mapsPerEpoch > 0 { + start, _, err = f.getLastBlockOfMap(f.indexedRange.maps.First() - f.mapsPerEpoch - 1) if err != nil { - log.Error("Error fetching last block of map", "mapIndex", f.indexedRange.firstRenderedMap-f.mapsPerEpoch-1, "error", err) + log.Error("Error fetching last block of map", "mapIndex", f.indexedRange.maps.First()-f.mapsPerEpoch-1, "error", err) } } return end - start @@ -391,5 +399,5 @@ func (f *FilterMaps) tailPartialBlocks() uint64 { // targetHeadIndexed returns true if the current log index is consistent with // targetView with its head block fully rendered. func (f *FilterMaps) targetHeadIndexed() bool { - return equalViews(f.targetView, f.indexedView) && f.indexedRange.headBlockIndexed + return equalViews(f.targetView, f.indexedView) && f.indexedRange.headIndexed } diff --git a/core/filtermaps/indexer_test.go b/core/filtermaps/indexer_test.go index 17ad765e04..a02f8d2459 100644 --- a/core/filtermaps/indexer_test.go +++ b/core/filtermaps/indexer_test.go @@ -48,16 +48,35 @@ func TestIndexerRandomRange(t *testing.T) { defer ts.close() forks := make([][]common.Hash, 10) - ts.chain.addBlocks(1000, 5, 2, 4, false) // 51 log values per block + ts.chain.addBlocks(1000, 5, 2, 4, false) for i := range forks { if i != 0 { forkBlock := rand.Intn(1000) ts.chain.setHead(forkBlock) - ts.chain.addBlocks(1000-forkBlock, 5, 2, 4, false) // 51 log values per block + ts.chain.addBlocks(1000-forkBlock, 5, 2, 4, false) } forks[i] = ts.chain.getCanonicalChain() } - lvPerBlock := uint64(51) + expspos := func(block uint64) uint64 { // expected position of block start + if block == 0 { + return 0 + } + logCount := (block - 1) * 5 * 2 + mapIndex := logCount / 3 + spos := mapIndex*16 + (logCount%3)*5 + if mapIndex == 0 || logCount%3 != 0 { + spos++ + } + return spos + } + expdpos := func(block uint64) uint64 { // expected position of delimiter + if block == 0 { + return 0 + } + logCount := block * 5 * 2 + mapIndex := (logCount - 1) / 3 + return mapIndex*16 + (logCount-mapIndex*3)*5 + } ts.setHistory(0, false) var ( history int @@ -115,23 +134,26 @@ func TestIndexerRandomRange(t *testing.T) { } var tailEpoch uint32 if tailBlock > 0 { - tailLvPtr := (tailBlock - 1) * lvPerBlock // no logs in genesis block, only delimiter + tailLvPtr := expspos(tailBlock) - 1 tailEpoch = uint32(tailLvPtr >> (testParams.logValuesPerMap + testParams.logMapsPerEpoch)) } + tailLvPtr := uint64(tailEpoch) << (testParams.logValuesPerMap + testParams.logMapsPerEpoch) // first available lv ptr var expTailBlock uint64 if tailEpoch > 0 { - tailLvPtr := uint64(tailEpoch) << (testParams.logValuesPerMap + testParams.logMapsPerEpoch) // first available lv ptr - // (expTailBlock-1)*lvPerBlock >= tailLvPtr - expTailBlock = (tailLvPtr + lvPerBlock*2 - 1) / lvPerBlock + for expspos(expTailBlock) <= tailLvPtr { + expTailBlock++ + } } - if ts.fm.indexedRange.afterLastIndexedBlock != uint64(head+1) { - ts.t.Fatalf("Invalid index head (expected #%d, got #%d)", head, ts.fm.indexedRange.afterLastIndexedBlock-1) + if ts.fm.indexedRange.blocks.Last() != uint64(head) { + ts.t.Fatalf("Invalid index head (expected #%d, got #%d)", head, ts.fm.indexedRange.blocks.Last()) } - if ts.fm.indexedRange.headBlockDelimiter != uint64(head)*lvPerBlock { - ts.t.Fatalf("Invalid index head delimiter pointer (expected %d, got %d)", uint64(head)*lvPerBlock, ts.fm.indexedRange.headBlockDelimiter) + expHeadDelimiter := expdpos(uint64(head)) + if ts.fm.indexedRange.headDelimiter != expHeadDelimiter { + ts.t.Fatalf("Invalid index head delimiter pointer (expected %d, got %d)", expHeadDelimiter, ts.fm.indexedRange.headDelimiter) } - if ts.fm.indexedRange.firstIndexedBlock != expTailBlock { - ts.t.Fatalf("Invalid index tail block (expected #%d, got #%d)", expTailBlock, ts.fm.indexedRange.firstIndexedBlock) + + if ts.fm.indexedRange.blocks.First() != expTailBlock { + ts.t.Fatalf("Invalid index tail block (expected #%d, got #%d)", expTailBlock, ts.fm.indexedRange.blocks.First()) } } } @@ -235,7 +257,7 @@ func (ts *testSetup) setHistory(history uint64, noHistory bool) { History: history, Disabled: noHistory, } - ts.fm = NewFilterMaps(ts.db, view, ts.params, config) + ts.fm = NewFilterMaps(ts.db, view, 0, 0, ts.params, config) ts.fm.testDisableSnapshots = ts.testDisableSnapshots ts.fm.Start() } @@ -420,7 +442,7 @@ func (tc *testChain) setTargetHead() { if tc.ts.fm != nil { if !tc.ts.fm.disabled { //tc.ts.fm.targetViewCh <- NewChainView(tc, head.Number.Uint64(), head.Hash()) - tc.ts.fm.SetTargetView(NewChainView(tc, head.Number.Uint64(), head.Hash())) + tc.ts.fm.SetTarget(NewChainView(tc, head.Number.Uint64(), head.Hash()), 0, 0) } } } diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index 5bd48a4b23..4f45a7f2b2 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -46,12 +46,12 @@ var ( // mapRenderer represents a process that renders filter maps in a specified // range according to the actual targetView. type mapRenderer struct { - f *FilterMaps - afterLastMap uint32 - currentMap *renderedMap - finishedMaps map[uint32]*renderedMap - firstFinished, afterLastFinished uint32 - iterator *logIterator + f *FilterMaps + renderBefore uint32 + currentMap *renderedMap + finishedMaps map[uint32]*renderedMap + finished common.Range[uint32] + iterator *logIterator } // renderedMap represents a single filter map that is being rendered in memory. @@ -74,22 +74,22 @@ func (r *renderedMap) firstBlock() uint64 { // specified map index boundary, starting from the latest available starting // point that is consistent with the current targetView. // The renderer ensures that filterMapsRange, indexedView and the actual map -// data are always consistent with each other. If afterLastMap is greater than +// data are always consistent with each other. If renderBefore is greater than // the latest existing rendered map then indexedView is updated to targetView, // otherwise it is checked that the rendered range is consistent with both // views. -func (f *FilterMaps) renderMapsBefore(afterLastMap uint32) (*mapRenderer, error) { - nextMap, startBlock, startLvPtr, err := f.lastCanonicalMapBoundaryBefore(afterLastMap) +func (f *FilterMaps) renderMapsBefore(renderBefore uint32) (*mapRenderer, error) { + nextMap, startBlock, startLvPtr, err := f.lastCanonicalMapBoundaryBefore(renderBefore) if err != nil { return nil, err } - if snapshot := f.lastCanonicalSnapshotBefore(afterLastMap); snapshot != nil && snapshot.mapIndex >= nextMap { + if snapshot := f.lastCanonicalSnapshotBefore(renderBefore); snapshot != nil && snapshot.mapIndex >= nextMap { return f.renderMapsFromSnapshot(snapshot) } - if nextMap >= afterLastMap { + if nextMap >= renderBefore { return nil, nil } - return f.renderMapsFromMapBoundary(nextMap, afterLastMap, startBlock, startLvPtr) + return f.renderMapsFromMapBoundary(nextMap, renderBefore, startBlock, startLvPtr) } // renderMapsFromSnapshot creates a mapRenderer that starts rendering from a @@ -108,17 +108,16 @@ func (f *FilterMaps) renderMapsFromSnapshot(cp *renderedMap) (*mapRenderer, erro lastBlock: cp.lastBlock, blockLvPtrs: cp.blockLvPtrs, }, - finishedMaps: make(map[uint32]*renderedMap), - firstFinished: cp.mapIndex, - afterLastFinished: cp.mapIndex, - afterLastMap: math.MaxUint32, - iterator: iter, + finishedMaps: make(map[uint32]*renderedMap), + finished: common.NewRange(cp.mapIndex, 0), + renderBefore: math.MaxUint32, + iterator: iter, }, nil } // renderMapsFromMapBoundary creates a mapRenderer that starts rendering at a // map boundary. -func (f *FilterMaps) renderMapsFromMapBoundary(firstMap, afterLastMap uint32, startBlock, startLvPtr uint64) (*mapRenderer, error) { +func (f *FilterMaps) renderMapsFromMapBoundary(firstMap, renderBefore uint32, startBlock, startLvPtr uint64) (*mapRenderer, error) { iter, err := f.newLogIteratorFromMapBoundary(firstMap, startBlock, startLvPtr) if err != nil { return nil, fmt.Errorf("failed to create log iterator from map boundary %d: %v", firstMap, err) @@ -130,22 +129,21 @@ func (f *FilterMaps) renderMapsFromMapBoundary(firstMap, afterLastMap uint32, st mapIndex: firstMap, lastBlock: iter.blockNumber, }, - finishedMaps: make(map[uint32]*renderedMap), - firstFinished: firstMap, - afterLastFinished: firstMap, - afterLastMap: afterLastMap, - iterator: iter, + finishedMaps: make(map[uint32]*renderedMap), + finished: common.NewRange(firstMap, 0), + renderBefore: renderBefore, + iterator: iter, }, nil } // lastCanonicalSnapshotBefore returns the latest cached snapshot that matches // the current targetView. -func (f *FilterMaps) lastCanonicalSnapshotBefore(afterLastMap uint32) *renderedMap { +func (f *FilterMaps) lastCanonicalSnapshotBefore(renderBefore uint32) *renderedMap { var best *renderedMap for _, blockNumber := range f.renderSnapshots.Keys() { - if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.afterLastIndexedBlock && + if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.blocks.AfterLast() && blockNumber <= f.targetView.headNumber && f.targetView.getBlockId(blockNumber) == cp.lastBlockId && - cp.mapIndex < afterLastMap && (best == nil || blockNumber > best.lastBlock) { + cp.mapIndex < renderBefore && (best == nil || blockNumber > best.lastBlock) { best = cp } } @@ -158,11 +156,11 @@ func (f *FilterMaps) lastCanonicalSnapshotBefore(afterLastMap uint32) *renderedM // or the boundary of a currently rendered map. // Along with the next map index where the rendering can be started, the number // and starting log value pointer of the last block is also returned. -func (f *FilterMaps) lastCanonicalMapBoundaryBefore(afterLastMap uint32) (nextMap uint32, startBlock, startLvPtr uint64, err error) { +func (f *FilterMaps) lastCanonicalMapBoundaryBefore(renderBefore uint32) (nextMap uint32, startBlock, startLvPtr uint64, err error) { if !f.indexedRange.initialized { return 0, 0, 0, nil } - mapIndex := afterLastMap + mapIndex := renderBefore for { var ok bool if mapIndex, ok = f.lastMapBoundaryBefore(mapIndex); !ok { @@ -188,18 +186,18 @@ func (f *FilterMaps) lastCanonicalMapBoundaryBefore(afterLastMap uint32) (nextMa // lastMapBoundaryBefore returns the latest map boundary before the specified // map index. func (f *FilterMaps) lastMapBoundaryBefore(mapIndex uint32) (uint32, bool) { - if !f.indexedRange.initialized || f.indexedRange.afterLastRenderedMap == 0 { + if !f.indexedRange.initialized || f.indexedRange.maps.AfterLast() == 0 { return 0, false } - if mapIndex > f.indexedRange.afterLastRenderedMap { - mapIndex = f.indexedRange.afterLastRenderedMap + if mapIndex > f.indexedRange.maps.AfterLast() { + mapIndex = f.indexedRange.maps.AfterLast() } - if mapIndex > f.indexedRange.firstRenderedMap { + if mapIndex > f.indexedRange.maps.First() { return mapIndex - 1, true } - if mapIndex+f.mapsPerEpoch > f.indexedRange.firstRenderedMap { - if mapIndex > f.indexedRange.firstRenderedMap-f.mapsPerEpoch+f.indexedRange.tailPartialEpoch { - mapIndex = f.indexedRange.firstRenderedMap - f.mapsPerEpoch + f.indexedRange.tailPartialEpoch + if mapIndex+f.mapsPerEpoch > f.indexedRange.maps.First() { + if mapIndex > f.indexedRange.maps.First()-f.mapsPerEpoch+f.indexedRange.tailPartialEpoch { + mapIndex = f.indexedRange.maps.First() - f.mapsPerEpoch + f.indexedRange.tailPartialEpoch } } else { mapIndex = (mapIndex >> f.logMapsPerEpoch) << f.logMapsPerEpoch @@ -218,19 +216,19 @@ func (f *FilterMaps) emptyFilterMap() filterMap { // loadHeadSnapshot loads the last rendered map from the database and creates // a snapshot. func (f *FilterMaps) loadHeadSnapshot() error { - fm, err := f.getFilterMap(f.indexedRange.afterLastRenderedMap - 1) + fm, err := f.getFilterMap(f.indexedRange.maps.Last()) if err != nil { - return fmt.Errorf("failed to load head snapshot map %d: %v", f.indexedRange.afterLastRenderedMap-1, err) + return fmt.Errorf("failed to load head snapshot map %d: %v", f.indexedRange.maps.Last(), err) } - lastBlock, _, err := f.getLastBlockOfMap(f.indexedRange.afterLastRenderedMap - 1) + lastBlock, _, err := f.getLastBlockOfMap(f.indexedRange.maps.Last()) if err != nil { - return fmt.Errorf("failed to retrieve last block of head snapshot map %d: %v", f.indexedRange.afterLastRenderedMap-1, err) + return fmt.Errorf("failed to retrieve last block of head snapshot map %d: %v", f.indexedRange.maps.Last(), err) } var firstBlock uint64 - if f.indexedRange.afterLastRenderedMap > 1 { - prevLastBlock, _, err := f.getLastBlockOfMap(f.indexedRange.afterLastRenderedMap - 2) + if f.indexedRange.maps.AfterLast() > 1 { + prevLastBlock, _, err := f.getLastBlockOfMap(f.indexedRange.maps.Last() - 1) if err != nil { - return fmt.Errorf("failed to retrieve last block of map %d before head snapshot: %v", f.indexedRange.afterLastRenderedMap-2, err) + return fmt.Errorf("failed to retrieve last block of map %d before head snapshot: %v", f.indexedRange.maps.Last()-1, err) } firstBlock = prevLastBlock + 1 } @@ -241,14 +239,14 @@ func (f *FilterMaps) loadHeadSnapshot() error { return fmt.Errorf("failed to retrieve log value pointer of head snapshot block %d: %v", firstBlock+uint64(i), err) } } - f.renderSnapshots.Add(f.indexedRange.afterLastIndexedBlock-1, &renderedMap{ + f.renderSnapshots.Add(f.indexedRange.blocks.Last(), &renderedMap{ filterMap: fm, - mapIndex: f.indexedRange.afterLastRenderedMap - 1, - lastBlock: f.indexedRange.afterLastIndexedBlock - 1, - lastBlockId: f.indexedView.getBlockId(f.indexedRange.afterLastIndexedBlock - 1), + mapIndex: f.indexedRange.maps.Last(), + lastBlock: f.indexedRange.blocks.Last(), + lastBlockId: f.indexedView.getBlockId(f.indexedRange.blocks.Last()), blockLvPtrs: lvPtrs, finished: true, - headDelimiter: f.indexedRange.headBlockDelimiter, + headDelimiter: f.indexedRange.headDelimiter, }) return nil } @@ -277,14 +275,14 @@ func (r *mapRenderer) run(stopCb func() bool, writeCb func()) (bool, error) { } // map finished r.finishedMaps[r.currentMap.mapIndex] = r.currentMap - r.afterLastFinished++ - if len(r.finishedMaps) >= maxMapsPerBatch || r.afterLastFinished&(r.f.baseRowGroupLength-1) == 0 { + r.finished.SetLast(r.finished.AfterLast()) + if len(r.finishedMaps) >= maxMapsPerBatch || r.finished.AfterLast()&(r.f.baseRowGroupLength-1) == 0 { if err := r.writeFinishedMaps(stopCb); err != nil { return false, err } writeCb() } - if r.afterLastFinished == r.afterLastMap || r.iterator.finished { + if r.finished.AfterLast() == r.renderBefore || r.iterator.finished { if err := r.writeFinishedMaps(stopCb); err != nil { return false, err } @@ -293,7 +291,7 @@ func (r *mapRenderer) run(stopCb func() bool, writeCb func()) (bool, error) { } r.currentMap = &renderedMap{ filterMap: r.f.emptyFilterMap(), - mapIndex: r.afterLastFinished, + mapIndex: r.finished.AfterLast(), } } } @@ -323,11 +321,6 @@ func (r *mapRenderer) renderCurrentMap(stopCb func() bool) (bool, error) { } waitCnt = 0 } - r.currentMap.lastBlock = r.iterator.blockNumber - if r.iterator.delimiter { - r.currentMap.lastBlock++ - r.currentMap.blockLvPtrs = append(r.currentMap.blockLvPtrs, r.iterator.lvIndex+1) - } if logValue := r.iterator.getValueHash(); logValue != (common.Hash{}) { lvp, cached := rowMappingCache.Get(logValue) if !cached { @@ -346,9 +339,15 @@ func (r *mapRenderer) renderCurrentMap(stopCb func() bool) (bool, error) { if err := r.iterator.next(); err != nil { return false, fmt.Errorf("failed to advance log iterator at %d while rendering map %d: %v", r.iterator.lvIndex, r.currentMap.mapIndex, err) } - if !r.f.testDisableSnapshots && r.afterLastMap >= r.f.indexedRange.afterLastRenderedMap && - (r.iterator.delimiter || r.iterator.finished) { - r.makeSnapshot() + if !r.iterator.skipToBoundary { + r.currentMap.lastBlock = r.iterator.blockNumber + if r.iterator.blockStart { + r.currentMap.blockLvPtrs = append(r.currentMap.blockLvPtrs, r.iterator.lvIndex) + } + if !r.f.testDisableSnapshots && r.renderBefore >= r.f.indexedRange.maps.AfterLast() && + (r.iterator.delimiter || r.iterator.finished) { + r.makeSnapshot() + } } } if r.iterator.finished { @@ -402,7 +401,7 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { mapIndices []uint32 rows []FilterRow ) - for mapIndex := r.firstFinished; mapIndex < r.afterLastFinished; mapIndex++ { + for mapIndex := range r.finished.Iter() { row := r.finishedMaps[mapIndex].filterMap[rowIndex] if fm, _ := r.f.filterMapCache.Get(mapIndex); fm != nil && row.Equal(fm[rowIndex]) { continue @@ -410,8 +409,8 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { mapIndices = append(mapIndices, mapIndex) rows = append(rows, row) } - if newRange.afterLastRenderedMap == r.afterLastFinished { // head updated; remove future entries - for mapIndex := r.afterLastFinished; mapIndex < oldRange.afterLastRenderedMap; mapIndex++ { + if newRange.maps.AfterLast() == r.finished.AfterLast() { // head updated; remove future entries + for mapIndex := r.finished.AfterLast(); mapIndex < oldRange.maps.AfterLast(); mapIndex++ { if fm, _ := r.f.filterMapCache.Get(mapIndex); fm != nil && len(fm[rowIndex]) == 0 { continue } @@ -425,24 +424,24 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { checkWriteCnt() } // update filter map cache - if newRange.afterLastRenderedMap == r.afterLastFinished { + if newRange.maps.AfterLast() == r.finished.AfterLast() { // head updated; cache new head maps and remove future entries - for mapIndex := r.firstFinished; mapIndex < r.afterLastFinished; mapIndex++ { + for mapIndex := range r.finished.Iter() { r.f.filterMapCache.Add(mapIndex, r.finishedMaps[mapIndex].filterMap) } - for mapIndex := r.afterLastFinished; mapIndex < oldRange.afterLastRenderedMap; mapIndex++ { + for mapIndex := r.finished.AfterLast(); mapIndex < oldRange.maps.AfterLast(); mapIndex++ { r.f.filterMapCache.Remove(mapIndex) } } else { // head not updated; do not cache maps during tail rendering because we // need head maps to be available in the cache - for mapIndex := r.firstFinished; mapIndex < r.afterLastFinished; mapIndex++ { + for mapIndex := range r.finished.Iter() { r.f.filterMapCache.Remove(mapIndex) } } // add or update block pointers - blockNumber := r.finishedMaps[r.firstFinished].firstBlock() - for mapIndex := r.firstFinished; mapIndex < r.afterLastFinished; mapIndex++ { + blockNumber := r.finishedMaps[r.finished.First()].firstBlock() + for mapIndex := range r.finished.Iter() { renderedMap := r.finishedMaps[mapIndex] r.f.storeLastBlockOfMap(batch, mapIndex, renderedMap.lastBlock, renderedMap.lastBlockId) checkWriteCnt() @@ -455,18 +454,18 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { blockNumber++ } } - if newRange.afterLastRenderedMap == r.afterLastFinished { // head updated; remove future entries - for mapIndex := r.afterLastFinished; mapIndex < oldRange.afterLastRenderedMap; mapIndex++ { + if newRange.maps.AfterLast() == r.finished.AfterLast() { // head updated; remove future entries + for mapIndex := r.finished.AfterLast(); mapIndex < oldRange.maps.AfterLast(); mapIndex++ { r.f.deleteLastBlockOfMap(batch, mapIndex) checkWriteCnt() } - for ; blockNumber < oldRange.afterLastIndexedBlock; blockNumber++ { + for ; blockNumber < oldRange.blocks.AfterLast(); blockNumber++ { r.f.deleteBlockLvPointer(batch, blockNumber) checkWriteCnt() } } r.finishedMaps = make(map[uint32]*renderedMap) - r.firstFinished = r.afterLastFinished + r.finished.SetFirst(r.finished.AfterLast()) r.f.setRange(batch, renderedView, newRange) if err := batch.Write(); err != nil { log.Crit("Error writing log index update batch", "error", err) @@ -481,33 +480,33 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { // range to the unchanged region until all new map data is committed. func (r *mapRenderer) getTempRange() (filterMapsRange, error) { tempRange := r.f.indexedRange - if err := tempRange.addRenderedRange(r.firstFinished, r.firstFinished, r.afterLastMap, r.f.mapsPerEpoch); err != nil { + if err := tempRange.addRenderedRange(r.finished.First(), r.finished.First(), r.renderBefore, r.f.mapsPerEpoch); err != nil { return filterMapsRange{}, fmt.Errorf("failed to update temporary rendered range: %v", err) } - if tempRange.firstRenderedMap != r.f.indexedRange.firstRenderedMap { + if tempRange.maps.First() != r.f.indexedRange.maps.First() { // first rendered map changed; update first indexed block - if tempRange.firstRenderedMap > 0 { - lastBlock, _, err := r.f.getLastBlockOfMap(tempRange.firstRenderedMap - 1) + if tempRange.maps.First() > 0 { + firstBlock, _, err := r.f.getLastBlockOfMap(tempRange.maps.First() - 1) if err != nil { - return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d before temporary range: %v", tempRange.firstRenderedMap-1, err) + return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d before temporary range: %v", tempRange.maps.First()-1, err) } - tempRange.firstIndexedBlock = lastBlock + 1 + tempRange.blocks.SetFirst(firstBlock + 1) // firstBlock is probably partially rendered } else { - tempRange.firstIndexedBlock = 0 + tempRange.blocks.SetFirst(0) } } - if tempRange.afterLastRenderedMap != r.f.indexedRange.afterLastRenderedMap { - // first rendered map changed; update first indexed block - if tempRange.afterLastRenderedMap > 0 { - lastBlock, _, err := r.f.getLastBlockOfMap(tempRange.afterLastRenderedMap - 1) + if tempRange.maps.AfterLast() != r.f.indexedRange.maps.AfterLast() { + // last rendered map changed; update last indexed block + if !tempRange.maps.IsEmpty() { + lastBlock, _, err := r.f.getLastBlockOfMap(tempRange.maps.Last()) if err != nil { - return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d at the end of temporary range: %v", tempRange.afterLastRenderedMap-1, err) + return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d at the end of temporary range: %v", tempRange.maps.Last(), err) } - tempRange.afterLastIndexedBlock = lastBlock + tempRange.blocks.SetAfterLast(lastBlock) // lastBlock is probably partially rendered } else { - tempRange.afterLastIndexedBlock = 0 + tempRange.blocks.SetAfterLast(0) } - tempRange.headBlockDelimiter = 0 + tempRange.headDelimiter = 0 } return tempRange, nil } @@ -517,39 +516,39 @@ func (r *mapRenderer) getTempRange() (filterMapsRange, error) { func (r *mapRenderer) getUpdatedRange() (filterMapsRange, error) { // update filterMapsRange newRange := r.f.indexedRange - if err := newRange.addRenderedRange(r.firstFinished, r.afterLastFinished, r.afterLastMap, r.f.mapsPerEpoch); err != nil { + if err := newRange.addRenderedRange(r.finished.First(), r.finished.AfterLast(), r.renderBefore, r.f.mapsPerEpoch); err != nil { return filterMapsRange{}, fmt.Errorf("failed to update rendered range: %v", err) } - if newRange.firstRenderedMap != r.f.indexedRange.firstRenderedMap { + if newRange.maps.First() != r.f.indexedRange.maps.First() { // first rendered map changed; update first indexed block - if newRange.firstRenderedMap > 0 { - lastBlock, _, err := r.f.getLastBlockOfMap(newRange.firstRenderedMap - 1) + if newRange.maps.First() > 0 { + firstBlock, _, err := r.f.getLastBlockOfMap(newRange.maps.First() - 1) if err != nil { - return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d before rendered range: %v", newRange.firstRenderedMap-1, err) + return filterMapsRange{}, fmt.Errorf("failed to retrieve last block of map %d before rendered range: %v", newRange.maps.First()-1, err) } - newRange.firstIndexedBlock = lastBlock + 1 + newRange.blocks.SetFirst(firstBlock + 1) // firstBlock is probably partially rendered } else { - newRange.firstIndexedBlock = 0 + newRange.blocks.SetFirst(0) } } - if newRange.afterLastRenderedMap == r.afterLastFinished { + if newRange.maps.AfterLast() == r.finished.AfterLast() { // last rendered map changed; update last indexed block and head pointers - lm := r.finishedMaps[r.afterLastFinished-1] - newRange.headBlockIndexed = lm.finished + lm := r.finishedMaps[r.finished.Last()] + newRange.headIndexed = lm.finished if lm.finished { - newRange.afterLastIndexedBlock = r.f.targetView.headNumber + 1 + newRange.blocks.SetLast(r.f.targetView.headNumber) if lm.lastBlock != r.f.targetView.headNumber { panic("map rendering finished but last block != head block") } - newRange.headBlockDelimiter = lm.headDelimiter + newRange.headDelimiter = lm.headDelimiter } else { - newRange.afterLastIndexedBlock = lm.lastBlock - newRange.headBlockDelimiter = 0 + newRange.blocks.SetAfterLast(lm.lastBlock) // lastBlock is probably partially rendered + newRange.headDelimiter = 0 } } else { // last rendered map not replaced; ensure that target chain view matches // indexed chain view on the rendered section - if lastBlock := r.finishedMaps[r.afterLastFinished-1].lastBlock; !matchViews(r.f.indexedView, r.f.targetView, lastBlock) { + if lastBlock := r.finishedMaps[r.finished.Last()].lastBlock; !matchViews(r.f.indexedView, r.f.targetView, lastBlock) { return filterMapsRange{}, errChainUpdate } } @@ -571,9 +570,9 @@ func (fmr *filterMapsRange) addRenderedRange(firstRendered, afterLastRendered, a m uint32 d int } - endpoints := []endpoint{{fmr.firstRenderedMap, 1}, {fmr.afterLastRenderedMap, -1}, {firstRendered, 1}, {afterLastRendered, -101}, {afterLastRemoved, 100}} + endpoints := []endpoint{{fmr.maps.First(), 1}, {fmr.maps.AfterLast(), -1}, {firstRendered, 1}, {afterLastRendered, -101}, {afterLastRemoved, 100}} if fmr.tailPartialEpoch > 0 { - endpoints = append(endpoints, []endpoint{{fmr.firstRenderedMap - mapsPerEpoch, 1}, {fmr.firstRenderedMap - mapsPerEpoch + fmr.tailPartialEpoch, -1}}...) + endpoints = append(endpoints, []endpoint{{fmr.maps.First() - mapsPerEpoch, 1}, {fmr.maps.First() - mapsPerEpoch + fmr.tailPartialEpoch, -1}}...) } sort.Slice(endpoints, func(i, j int) bool { return endpoints[i].m < endpoints[j].m }) var ( @@ -596,14 +595,12 @@ func (fmr *filterMapsRange) addRenderedRange(firstRendered, afterLastRendered, a case 0: // Initialized database, but no finished maps yet. fmr.tailPartialEpoch = 0 - fmr.firstRenderedMap = firstRendered - fmr.afterLastRenderedMap = firstRendered + fmr.maps = common.NewRange(firstRendered, 0) case 2: // One rendered section (no partial tail epoch). fmr.tailPartialEpoch = 0 - fmr.firstRenderedMap = merged[0] - fmr.afterLastRenderedMap = merged[1] + fmr.maps = common.NewRange(merged[0], merged[1]-merged[0]) case 4: // Two rendered sections (with a gap). @@ -613,8 +610,7 @@ func (fmr *filterMapsRange) addRenderedRange(firstRendered, afterLastRendered, a return fmt.Errorf("invalid tail partial epoch: %v", merged) } fmr.tailPartialEpoch = merged[1] - merged[0] - fmr.firstRenderedMap = merged[2] - fmr.afterLastRenderedMap = merged[3] + fmr.maps = common.NewRange(merged[2], merged[3]-merged[2]) default: return fmt.Errorf("invalid number of rendered sections: %v", merged) @@ -624,12 +620,13 @@ func (fmr *filterMapsRange) addRenderedRange(firstRendered, afterLastRendered, a // logIterator iterates on the linear log value index range. type logIterator struct { - chainView *ChainView - blockNumber uint64 - receipts types.Receipts - blockStart, delimiter, finished bool - txIndex, logIndex, topicIndex int - lvIndex uint64 + params *Params + chainView *ChainView + blockNumber uint64 + receipts types.Receipts + blockStart, delimiter, skipToBoundary, finished bool + txIndex, logIndex, topicIndex int + lvIndex uint64 } var errUnindexedRange = errors.New("unindexed range") @@ -641,12 +638,12 @@ func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber uint64) (*logI if blockNumber > f.targetView.headNumber { return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", blockNumber, f.targetView.headNumber) } - if blockNumber < f.indexedRange.firstIndexedBlock || blockNumber >= f.indexedRange.afterLastIndexedBlock { + if !f.indexedRange.blocks.Includes(blockNumber) { return nil, errUnindexedRange } var lvIndex uint64 - if f.indexedRange.headBlockIndexed && blockNumber+1 == f.indexedRange.afterLastIndexedBlock { - lvIndex = f.indexedRange.headBlockDelimiter + if f.indexedRange.headIndexed && blockNumber+1 == f.indexedRange.blocks.AfterLast() { + lvIndex = f.indexedRange.headDelimiter } else { var err error lvIndex, err = f.getBlockLvPointer(blockNumber + 1) @@ -656,13 +653,16 @@ func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber uint64) (*logI lvIndex-- } finished := blockNumber == f.targetView.headNumber - return &logIterator{ + l := &logIterator{ chainView: f.targetView, + params: &f.Params, blockNumber: blockNumber, finished: finished, delimiter: !finished, lvIndex: lvIndex, - }, nil + } + l.enforceValidState() + return l, nil } // newLogIteratorFromMapBoundary creates a logIterator starting at the given @@ -679,12 +679,13 @@ func (f *FilterMaps) newLogIteratorFromMapBoundary(mapIndex uint32, startBlock, // initialize iterator at block start l := &logIterator{ chainView: f.targetView, + params: &f.Params, blockNumber: startBlock, receipts: receipts, blockStart: true, lvIndex: startLvPtr, } - l.nextValid() + l.enforceValidState() targetIndex := uint64(mapIndex) << f.logValuesPerMap if l.lvIndex > targetIndex { return nil, fmt.Errorf("log value pointer %d of last block of map is after map boundary %d", l.lvIndex, targetIndex) @@ -713,7 +714,7 @@ func (l *logIterator) updateChainView(cv *ChainView) bool { // getValueHash returns the log value hash at the current position. func (l *logIterator) getValueHash() common.Hash { - if l.delimiter || l.finished { + if l.delimiter || l.finished || l.skipToBoundary { return common.Hash{} } log := l.receipts[l.txIndex].Logs[l.logIndex] @@ -725,6 +726,13 @@ func (l *logIterator) getValueHash() common.Hash { // next moves the iterator to the next log value index. func (l *logIterator) next() error { + if l.skipToBoundary { + l.lvIndex++ + if l.lvIndex%l.params.valuesPerMap == 0 { + l.skipToBoundary = false + } + return nil + } if l.finished { return nil } @@ -741,18 +749,26 @@ func (l *logIterator) next() error { l.blockStart = false } l.lvIndex++ - l.nextValid() + l.enforceValidState() return nil } -// nextValid updates the internal transaction, log and topic index pointers +// enforceValidState updates the internal transaction, log and topic index pointers // to the next existing log value of the given block if necessary. -// Note that nextValid does not advance the log value index pointer. -func (l *logIterator) nextValid() { +// Note that enforceValidState does not advance the log value index pointer. +func (l *logIterator) enforceValidState() { + if l.delimiter || l.finished || l.skipToBoundary { + return + } for ; l.txIndex < len(l.receipts); l.txIndex++ { receipt := l.receipts[l.txIndex] for ; l.logIndex < len(receipt.Logs); l.logIndex++ { log := receipt.Logs[l.logIndex] + if l.topicIndex == 0 && uint64(len(log.Topics)+1) > l.params.valuesPerMap-l.lvIndex%l.params.valuesPerMap { + // next log would be split by map boundary; skip to boundary + l.skipToBoundary = true + return + } if l.topicIndex <= len(log.Topics) { return } diff --git a/core/filtermaps/matcher.go b/core/filtermaps/matcher.go index 19acbd762a..6c05672cbc 100644 --- a/core/filtermaps/matcher.go +++ b/core/filtermaps/matcher.go @@ -61,11 +61,9 @@ type SyncRange struct { // block range where the index has not changed since the last matcher sync // and therefore the set of matches found in this region is guaranteed to // be valid and complete. - Valid bool - FirstValid, LastValid uint64 + ValidBlocks common.Range[uint64] // block range indexed according to the given chain head. - Indexed bool - FirstIndexed, LastIndexed uint64 + IndexedBlocks common.Range[uint64] } // GetPotentialMatches returns a list of logs that are potential matches for the @@ -75,7 +73,6 @@ type SyncRange struct { // Also note that the returned list may contain false positives. func GetPotentialMatches(ctx context.Context, backend MatcherBackend, firstBlock, lastBlock uint64, addresses []common.Address, topics [][]common.Hash) ([]*types.Log, error) { params := backend.GetParams() - var getLogStats runtimeStats // find the log value index range to search firstIndex, err := backend.GetBlockLvPointer(ctx, firstBlock) if err != nil { @@ -88,8 +85,6 @@ func GetPotentialMatches(ctx context.Context, backend MatcherBackend, firstBlock if lastIndex > 0 { lastIndex-- } - firstMap, lastMap := uint32(firstIndex>>params.logValuesPerMap), uint32(lastIndex>>params.logValuesPerMap) - firstEpoch, lastEpoch := firstMap>>params.logMapsPerEpoch, lastMap>>params.logMapsPerEpoch // build matcher according to the given filter criteria matchers := make([]matcher, len(topics)+1) @@ -117,45 +112,45 @@ func GetPotentialMatches(ctx context.Context, backend MatcherBackend, firstBlock // matchers signal a match for consecutive log value indices. matcher := newMatchSequence(params, matchers) - // processEpoch returns the potentially matching logs from the given epoch. - processEpoch := func(epochIndex uint32) ([]*types.Log, error) { - var logs []*types.Log - // create a list of map indices to process - fm, lm := epochIndex< lastMap { - lm = lastMap - } - // - mapIndices := make([]uint32, lm+1-fm) - for i := range mapIndices { - mapIndices[i] = fm + uint32(i) - } - // find potential matches - matches, err := getAllMatches(ctx, matcher, mapIndices) - if err != nil { - return logs, err - } - // get the actual logs located at the matching log value indices - var st int - getLogStats.setState(&st, stGetLog) - defer getLogStats.setState(&st, stNone) - for _, m := range matches { - if m == nil { - return nil, ErrMatchAll - } - mlogs, err := getLogsFromMatches(ctx, backend, firstIndex, lastIndex, m) - if err != nil { - return logs, err - } - logs = append(logs, mlogs...) - } - getLogStats.addAmount(st, int64(len(logs))) - return logs, nil + m := &matcherEnv{ + ctx: ctx, + backend: backend, + params: params, + matcher: matcher, + firstIndex: firstIndex, + lastIndex: lastIndex, + firstMap: uint32(firstIndex >> params.logValuesPerMap), + lastMap: uint32(lastIndex >> params.logValuesPerMap), } + start := time.Now() + res, err := m.process() + + if doRuntimeStats { + log.Info("Log search finished", "elapsed", time.Since(start)) + for i, ma := range matchers { + for j, m := range ma.(matchAny) { + log.Info("Single matcher stats", "matchSequence", i, "matchAny", j) + m.(*singleMatcher).stats.print() + } + } + log.Info("Get log stats") + m.getLogStats.print() + } + return res, err +} + +type matcherEnv struct { + getLogStats runtimeStats // 64 bit aligned + ctx context.Context + backend MatcherBackend + params *Params + matcher matcher + firstIndex, lastIndex uint64 + firstMap, lastMap uint32 +} + +func (m *matcherEnv) process() ([]*types.Log, error) { type task struct { epochIndex uint32 logs []*types.Log @@ -175,18 +170,18 @@ func GetPotentialMatches(ctx context.Context, backend MatcherBackend, firstBlock if task == nil { break } - task.logs, task.err = processEpoch(task.epochIndex) + task.logs, task.err = m.processEpoch(task.epochIndex) close(task.done) } wg.Done() } - start := time.Now() - for i := 0; i < 4; i++ { + for range 4 { wg.Add(1) go worker() } + firstEpoch, lastEpoch := m.firstMap>>m.params.logMapsPerEpoch, m.lastMap>>m.params.logMapsPerEpoch var logs []*types.Log // startEpoch is the next task to send whenever a worker can accept it. // waitEpoch is the next task we are waiting for to finish in order to append @@ -220,30 +215,58 @@ func GetPotentialMatches(ctx context.Context, backend MatcherBackend, firstBlock } } } - if doRuntimeStats { - log.Info("Log search finished", "elapsed", time.Since(start)) - for i, ma := range matchers { - for j, m := range ma.(matchAny) { - log.Info("Single matcher stats", "matchSequence", i, "matchAny", j) - m.(*singleMatcher).stats.print() - } - } - log.Info("Get log stats") - getLogStats.print() + return logs, nil +} + +// processEpoch returns the potentially matching logs from the given epoch. +func (m *matcherEnv) processEpoch(epochIndex uint32) ([]*types.Log, error) { + var logs []*types.Log + // create a list of map indices to process + fm, lm := epochIndex< m.lastMap { + lm = m.lastMap + } + // + mapIndices := make([]uint32, lm+1-fm) + for i := range mapIndices { + mapIndices[i] = fm + uint32(i) + } + // find potential matches + matches, err := m.getAllMatches(mapIndices) + if err != nil { + return logs, err + } + // get the actual logs located at the matching log value indices + var st int + m.getLogStats.setState(&st, stGetLog) + defer m.getLogStats.setState(&st, stNone) + for _, match := range matches { + if match == nil { + return nil, ErrMatchAll + } + mlogs, err := m.getLogsFromMatches(match) + if err != nil { + return logs, err + } + logs = append(logs, mlogs...) + } + m.getLogStats.addAmount(st, int64(len(logs))) return logs, nil } // getLogsFromMatches returns the list of potentially matching logs located at // the given list of matching log indices. Matches outside the firstIndex to // lastIndex range are not returned. -func getLogsFromMatches(ctx context.Context, backend MatcherBackend, firstIndex, lastIndex uint64, matches potentialMatches) ([]*types.Log, error) { +func (m *matcherEnv) getLogsFromMatches(matches potentialMatches) ([]*types.Log, error) { var logs []*types.Log for _, match := range matches { - if match < firstIndex || match > lastIndex { + if match < m.firstIndex || match > m.lastIndex { continue } - log, err := backend.GetLogByLvIndex(ctx, match) + log, err := m.backend.GetLogByLvIndex(m.ctx, match) if err != nil { return logs, fmt.Errorf("failed to retrieve log at index %d: %v", match, err) } @@ -254,6 +277,28 @@ func getLogsFromMatches(ctx context.Context, backend MatcherBackend, firstIndex, return logs, nil } +// getAllMatches creates an instance for a given matcher and set of map indices, +// iterates through mapping layers and collects all results, then returns all +// results in the same order as the map indices were specified. +func (m *matcherEnv) getAllMatches(mapIndices []uint32) ([]potentialMatches, error) { + instance := m.matcher.newInstance(mapIndices) + resultsMap := make(map[uint32]potentialMatches) + for layerIndex := uint32(0); len(resultsMap) < len(mapIndices); layerIndex++ { + results, err := instance.getMatchesForLayer(m.ctx, layerIndex) + if err != nil { + return nil, err + } + for _, result := range results { + resultsMap[result.mapIndex] = result.matches + } + } + matches := make([]potentialMatches, len(mapIndices)) + for i, mapIndex := range mapIndices { + matches[i] = resultsMap[mapIndex] + } + return matches, nil +} + // matcher defines a general abstraction for any matcher configuration that // can instantiate a matcherInstance. type matcher interface { @@ -281,28 +326,6 @@ type matcherResult struct { matches potentialMatches } -// getAllMatches creates an instance for a given matcher and set of map indices, -// iterates through mapping layers and collects all results, then returns all -// results in the same order as the map indices were specified. -func getAllMatches(ctx context.Context, matcher matcher, mapIndices []uint32) ([]potentialMatches, error) { - instance := matcher.newInstance(mapIndices) - resultsMap := make(map[uint32]potentialMatches) - for layerIndex := uint32(0); len(resultsMap) < len(mapIndices); layerIndex++ { - results, err := instance.getMatchesForLayer(ctx, layerIndex) - if err != nil { - return nil, err - } - for _, result := range results { - resultsMap[result.mapIndex] = result.matches - } - } - matches := make([]potentialMatches, len(mapIndices)) - for i, mapIndex := range mapIndices { - matches[i] = resultsMap[mapIndex] - } - return matches, nil -} - // singleMatcher implements matcher by returning matches for a single log value hash. type singleMatcher struct { backend MatcherBackend @@ -550,24 +573,18 @@ type matchSequence struct { // newInstance creates a new instance of matchSequence. func (m *matchSequence) newInstance(mapIndices []uint32) matcherInstance { // determine set of indices to request from next matcher - nextIndices := make([]uint32, 0, len(mapIndices)*3/2) needMatched := make(map[uint32]struct{}) baseRequested := make(map[uint32]struct{}) nextRequested := make(map[uint32]struct{}) for _, mapIndex := range mapIndices { needMatched[mapIndex] = struct{}{} baseRequested[mapIndex] = struct{}{} - if _, ok := nextRequested[mapIndex]; !ok { - nextIndices = append(nextIndices, mapIndex) - nextRequested[mapIndex] = struct{}{} - } - nextIndices = append(nextIndices, mapIndex+1) - nextRequested[mapIndex+1] = struct{}{} + nextRequested[mapIndex] = struct{}{} } return &matchSequenceInstance{ matchSequence: m, baseInstance: m.base.newInstance(mapIndices), - nextInstance: m.next.newInstance(nextIndices), + nextInstance: m.next.newInstance(mapIndices), needMatched: needMatched, baseRequested: baseRequested, nextRequested: nextRequested, @@ -687,12 +704,9 @@ func (m *matchSequenceInstance) getMatchesForLayer(ctx context.Context, layerInd if _, ok := m.nextRequested[mapIndex]; ok { continue } - if _, ok := m.nextRequested[mapIndex+1]; ok { - continue - } matchedResults = append(matchedResults, matcherResult{ mapIndex: mapIndex, - matches: m.params.matchResults(mapIndex, m.offset, m.baseResults[mapIndex], m.nextResults[mapIndex], m.nextResults[mapIndex+1]), + matches: m.params.matchResults(mapIndex, m.offset, m.baseResults[mapIndex], m.nextResults[mapIndex]), }) delete(m.needMatched, mapIndex) } @@ -715,9 +729,6 @@ func (m *matchSequenceInstance) dropIndices(dropIndices []uint32) { if m.dropNext(mapIndex) { dropNext = append(dropNext, mapIndex) } - if m.dropNext(mapIndex + 1) { - dropNext = append(dropNext, mapIndex+1) - } } m.nextInstance.dropIndices(dropNext) } @@ -743,9 +754,6 @@ func (m *matchSequenceInstance) evalBase(ctx context.Context, layerIndex uint32) if m.dropNext(r.mapIndex) { dropIndices = append(dropIndices, r.mapIndex) } - if m.dropNext(r.mapIndex + 1) { - dropIndices = append(dropIndices, r.mapIndex+1) - } } if len(dropIndices) > 0 { m.nextInstance.dropIndices(dropIndices) @@ -771,9 +779,6 @@ func (m *matchSequenceInstance) evalNext(ctx context.Context, layerIndex uint32) } m.mergeNextStats(stats) for _, r := range results { - if r.mapIndex > 0 && m.dropBase(r.mapIndex-1) { - dropIndices = append(dropIndices, r.mapIndex-1) - } if m.dropBase(r.mapIndex) { dropIndices = append(dropIndices, r.mapIndex) } @@ -792,12 +797,7 @@ func (m *matchSequenceInstance) dropBase(mapIndex uint32) bool { return false } if _, ok := m.needMatched[mapIndex]; ok { - if next := m.nextResults[mapIndex]; next == nil || - (len(next) > 0 && next[len(next)-1] >= (uint64(mapIndex)< 0 && nextNext[0] < (uint64(mapIndex+1)< 0 { return false } } @@ -812,15 +812,8 @@ func (m *matchSequenceInstance) dropNext(mapIndex uint32) bool { if _, ok := m.nextRequested[mapIndex]; !ok { return false } - if _, ok := m.needMatched[mapIndex-1]; ok { - if prevBase := m.baseResults[mapIndex-1]; prevBase == nil || - (len(prevBase) > 0 && prevBase[len(prevBase)-1]+m.offset >= (uint64(mapIndex)< 0 && base[0]+m.offset < (uint64(mapIndex+1)< 0 { return false } } @@ -833,59 +826,39 @@ func (m *matchSequenceInstance) dropNext(mapIndex uint32) bool { // results at mapIndex and mapIndex+1. Note that acquiring nextNextRes may be // skipped and it can be substituted with an empty list if baseRes has no potential // matches that could be sequence matched with anything that could be in nextNextRes. -func (params *Params) matchResults(mapIndex uint32, offset uint64, baseRes, nextRes, nextNextRes potentialMatches) potentialMatches { +func (params *Params) matchResults(mapIndex uint32, offset uint64, baseRes, nextRes potentialMatches) potentialMatches { if nextRes == nil || (baseRes != nil && len(baseRes) == 0) { // if nextRes is a wild card or baseRes is empty then the sequence matcher // result equals baseRes. return baseRes } - if len(nextRes) > 0 { - // discard items from nextRes whose corresponding base matcher results - // with the negative offset applied would be located at mapIndex-1. - start := 0 - for start < len(nextRes) && nextRes[start] < uint64(mapIndex)<= min { + result = append(result, v-offset) + } } - nextRes = nextRes[start:] + return result } - if len(nextNextRes) > 0 { - // discard items from nextNextRes whose corresponding base matcher results - // with the negative offset applied would still be located at mapIndex+1. - stop := 0 - for stop < len(nextNextRes) && nextNextRes[stop] < uint64(mapIndex+1)< 0 && len(baseRes) > 0 { - if nextRes[0] > baseRes[0]+offset { - baseRes = baseRes[1:] - } else if nextRes[0] < baseRes[0]+offset { - nextRes = nextRes[1:] - } else { - matchedRes = append(matchedRes, baseRes[0]) - baseRes = baseRes[1:] - nextRes = nextRes[1:] - } - } + for len(nextRes) > 0 && len(baseRes) > 0 { + if nextRes[0] > baseRes[0]+offset { + baseRes = baseRes[1:] + } else if nextRes[0] < baseRes[0]+offset { + nextRes = nextRes[1:] } else { - // baseRes is a wild card so just return next matcher results with - // negative offset. - for len(nextRes) > 0 { - matchedRes = append(matchedRes, nextRes[0]-offset) - nextRes = nextRes[1:] - } + matchedRes = append(matchedRes, baseRes[0]) + baseRes = baseRes[1:] + nextRes = nextRes[1:] } } return matchedRes diff --git a/core/filtermaps/matcher_backend.go b/core/filtermaps/matcher_backend.go index 66f95f2145..4c4668e321 100644 --- a/core/filtermaps/matcher_backend.go +++ b/core/filtermaps/matcher_backend.go @@ -19,6 +19,7 @@ package filtermaps import ( "context" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) @@ -27,9 +28,8 @@ type FilterMapsMatcherBackend struct { f *FilterMaps // these fields should be accessed under f.matchersLock mutex. - valid bool - firstValid, lastValid uint64 - syncCh chan SyncRange + validBlocks common.Range[uint64] + syncCh chan SyncRange } // NewMatcherBackend returns a FilterMapsMatcherBackend after registering it in @@ -43,11 +43,9 @@ func (f *FilterMaps) NewMatcherBackend() *FilterMapsMatcherBackend { f.indexLock.RUnlock() }() - fm := &FilterMapsMatcherBackend{ - f: f, - valid: f.indexedRange.initialized && f.indexedRange.afterLastIndexedBlock > f.indexedRange.firstIndexedBlock, - firstValid: f.indexedRange.firstIndexedBlock, - lastValid: f.indexedRange.afterLastIndexedBlock - 1, + fm := &FilterMapsMatcherBackend{f: f} + if f.indexedRange.initialized { + fm.validBlocks = f.indexedRange.blocks } f.matchers[fm] = struct{}{} return fm @@ -122,28 +120,16 @@ func (fm *FilterMapsMatcherBackend) synced() { fm.f.indexLock.RUnlock() }() - var ( - indexed bool - lastIndexed, subLastIndexed uint64 - ) - if !fm.f.indexedRange.headBlockIndexed { - subLastIndexed = 1 - } - if fm.f.indexedRange.afterLastIndexedBlock-subLastIndexed > fm.f.indexedRange.firstIndexedBlock { - indexed, lastIndexed = true, fm.f.indexedRange.afterLastIndexedBlock-subLastIndexed-1 + indexedBlocks := fm.f.indexedRange.blocks + if !fm.f.indexedRange.headIndexed && !indexedBlocks.IsEmpty() { + indexedBlocks.SetAfterLast(indexedBlocks.Last()) // remove partially indexed last block } fm.syncCh <- SyncRange{ - HeadNumber: fm.f.indexedView.headNumber, - Valid: fm.valid, - FirstValid: fm.firstValid, - LastValid: fm.lastValid, - Indexed: indexed, - FirstIndexed: fm.f.indexedRange.firstIndexedBlock, - LastIndexed: lastIndexed, + HeadNumber: fm.f.indexedView.headNumber, + ValidBlocks: fm.validBlocks, + IndexedBlocks: indexedBlocks, } - fm.valid = indexed - fm.firstValid = fm.f.indexedRange.firstIndexedBlock - fm.lastValid = lastIndexed + fm.validBlocks = indexedBlocks fm.syncCh = nil } @@ -187,20 +173,10 @@ func (f *FilterMaps) updateMatchersValidRange() { defer f.matchersLock.Unlock() for fm := range f.matchers { - if !f.indexedRange.hasIndexedBlocks() { - fm.valid = false - } - if !fm.valid { + if !f.indexedRange.initialized { + fm.validBlocks = common.Range[uint64]{} continue } - if fm.firstValid < f.indexedRange.firstIndexedBlock { - fm.firstValid = f.indexedRange.firstIndexedBlock - } - if fm.lastValid >= f.indexedRange.afterLastIndexedBlock { - fm.lastValid = f.indexedRange.afterLastIndexedBlock - 1 - } - if fm.firstValid > fm.lastValid { - fm.valid = false - } + fm.validBlocks = fm.validBlocks.Intersection(f.indexedRange.blocks) } } diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index f679c3aeb3..9f3d55aa3f 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -356,8 +356,8 @@ func WriteFilterMapBaseRows(db ethdb.KeyValueWriter, mapRowIndex uint64, rows [] } } -func DeleteFilterMapRows(db ethdb.KeyValueRangeDeleter, firstMapRowIndex, afterLastMapRowIndex uint64) { - if err := db.DeleteRange(filterMapRowKey(firstMapRowIndex, false), filterMapRowKey(afterLastMapRowIndex, false)); err != nil { +func DeleteFilterMapRows(db ethdb.KeyValueRangeDeleter, mapRows common.Range[uint64]) { + if err := db.DeleteRange(filterMapRowKey(mapRows.First(), false), filterMapRowKey(mapRows.AfterLast(), false)); err != nil { log.Crit("Failed to delete range of filter map rows", "err", err) } } @@ -396,8 +396,8 @@ func DeleteFilterMapLastBlock(db ethdb.KeyValueWriter, mapIndex uint32) { } } -func DeleteFilterMapLastBlocks(db ethdb.KeyValueRangeDeleter, firstMapIndex, afterLastMapIndex uint32) { - if err := db.DeleteRange(filterMapLastBlockKey(firstMapIndex), filterMapLastBlockKey(afterLastMapIndex)); err != nil { +func DeleteFilterMapLastBlocks(db ethdb.KeyValueRangeDeleter, maps common.Range[uint32]) { + if err := db.DeleteRange(filterMapLastBlockKey(maps.First()), filterMapLastBlockKey(maps.AfterLast())); err != nil { log.Crit("Failed to delete range of filter map last block pointers", "err", err) } } @@ -433,8 +433,8 @@ func DeleteBlockLvPointer(db ethdb.KeyValueWriter, blockNumber uint64) { } } -func DeleteBlockLvPointers(db ethdb.KeyValueRangeDeleter, firstBlockNumber, afterLastBlockNumber uint64) { - if err := db.DeleteRange(filterMapBlockLVKey(firstBlockNumber), filterMapBlockLVKey(afterLastBlockNumber)); err != nil { +func DeleteBlockLvPointers(db ethdb.KeyValueRangeDeleter, blocks common.Range[uint64]) { + if err := db.DeleteRange(filterMapBlockLVKey(blocks.First()), filterMapBlockLVKey(blocks.AfterLast())); err != nil { log.Crit("Failed to delete range of block log value pointers", "err", err) } } @@ -442,10 +442,11 @@ func DeleteBlockLvPointers(db ethdb.KeyValueRangeDeleter, firstBlockNumber, afte // FilterMapsRange is a storage representation of the block range covered by the // filter maps structure and the corresponting log value index range. type FilterMapsRange struct { - HeadBlockIndexed bool - HeadBlockDelimiter uint64 - FirstIndexedBlock, AfterLastIndexedBlock uint64 - FirstRenderedMap, AfterLastRenderedMap, TailPartialEpoch uint32 + HeadIndexed bool + HeadDelimiter uint64 + BlocksFirst, BlocksAfterLast uint64 + MapsFirst, MapsAfterLast uint32 + TailPartialEpoch uint32 } // ReadFilterMapsRange retrieves the filter maps range data. Note that if the diff --git a/eth/api_backend.go b/eth/api_backend.go index 75b039dbe1..b4b63556a9 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/txpool" @@ -413,6 +414,10 @@ func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma } } +func (b *EthAPIBackend) NewMatcherBackend() filtermaps.MatcherBackend { + return b.eth.filterMaps.NewMatcherBackend() +} + func (b *EthAPIBackend) Engine() consensus.Engine { return b.eth.engine } diff --git a/eth/backend.go b/eth/backend.go index 1790e413fd..99cb3841c3 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/pruner" "github.com/ethereum/go-ethereum/core/txpool" @@ -88,6 +89,9 @@ type Ethereum struct { bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports closeBloomHandler chan struct{} + filterMaps *filtermaps.FilterMaps + closeFilterMaps chan chan struct{} + APIBackend *EthAPIBackend miner *miner.Miner @@ -244,6 +248,10 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { return nil, err } eth.bloomIndexer.Start(eth.blockchain) + fmConfig := filtermaps.Config{History: config.LogHistory, Disabled: config.LogNoHistory, ExportFileName: config.LogExportCheckpoints} + chainView := eth.newChainView(eth.blockchain.CurrentBlock()) + eth.filterMaps = filtermaps.NewFilterMaps(chainDb, chainView, 0, 0, filtermaps.DefaultParams, fmConfig) + eth.closeFilterMaps = make(chan chan struct{}) if config.BlobPool.Datadir != "" { config.BlobPool.Datadir = stack.ResolvePath(config.BlobPool.Datadir) @@ -398,9 +406,71 @@ func (s *Ethereum) Start() error { // Start the networking layer s.handler.Start(s.p2pServer.MaxPeers) + + // start log indexer + s.filterMaps.Start() + go s.updateFilterMapsHeads() return nil } +func (s *Ethereum) newChainView(head *types.Header) *filtermaps.ChainView { + if head == nil { + return nil + } + return filtermaps.NewChainView(s.blockchain, head.Number.Uint64(), head.Hash()) +} + +func (s *Ethereum) updateFilterMapsHeads() { + headEventCh := make(chan core.ChainEvent, 10) + blockProcCh := make(chan bool, 10) + sub := s.blockchain.SubscribeChainEvent(headEventCh) + sub2 := s.blockchain.SubscribeBlockProcessingEvent(blockProcCh) + defer func() { + sub.Unsubscribe() + sub2.Unsubscribe() + for { + select { + case <-headEventCh: + case <-blockProcCh: + default: + return + } + } + }() + + var head *types.Header + setHead := func(newHead *types.Header) { + if newHead == nil { + return + } + if head == nil || newHead.Hash() != head.Hash() { + head = newHead + chainView := s.newChainView(head) + historyCutoff := s.blockchain.HistoryPruningCutoff() + var finalBlock uint64 + if fb := s.blockchain.CurrentFinalBlock(); fb != nil { + finalBlock = fb.Number.Uint64() + } + s.filterMaps.SetTarget(chainView, historyCutoff, finalBlock) + } + } + setHead(s.blockchain.CurrentBlock()) + + for { + select { + case ev := <-headEventCh: + setHead(ev.Header) + case blockProc := <-blockProcCh: + s.filterMaps.SetBlockProcessing(blockProc) + case <-time.After(time.Second * 10): + setHead(s.blockchain.CurrentBlock()) + case ch := <-s.closeFilterMaps: + close(ch) + return + } + } +} + func (s *Ethereum) setupDiscovery() error { eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode()) @@ -443,6 +513,10 @@ func (s *Ethereum) Stop() error { // Then stop everything else. s.bloomIndexer.Close() close(s.closeBloomHandler) + ch := make(chan struct{}) + s.closeFilterMaps <- ch + <-ch + s.filterMaps.Stop() s.txPool.Close() s.blockchain.Stop() s.engine.Close() diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index ec6de9e663..365857347c 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -53,6 +53,7 @@ var Defaults = Config{ NetworkId: 0, // enable auto configuration of networkID == chainID TxLookupLimit: 2350000, TransactionHistory: 2350000, + LogHistory: 2350000, StateHistory: params.FullImmutabilityThreshold, DatabaseCache: 512, TrieCleanCache: 154, @@ -97,8 +98,11 @@ type Config struct { // 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. + TransactionHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head whose tx indices are reserved. + LogHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head where a log search index is maintained. + LogNoHistory bool `toml:",omitempty"` // No log search index is maintained. + LogExportCheckpoints string // export log index checkpoints to file + 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 // nodes on top. It can be 'hash', 'path', or none which means use the scheme diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 09ccb93907..cedb5b3519 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -19,12 +19,15 @@ package filters import ( "context" "errors" + "math" "math/big" "slices" + "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" ) @@ -38,36 +41,14 @@ type Filter struct { block *common.Hash // Block hash if filtering a single block begin, end int64 // Range interval if filtering multiple blocks - matcher *bloombits.Matcher + rangeLogsTestHook chan rangeLogsTestEvent } // NewRangeFilter creates a new filter which uses a bloom filter on blocks to // figure out whether a particular block is interesting or not. func (sys *FilterSystem) NewRangeFilter(begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter { - // Flatten the address and topic filter clauses into a single bloombits filter - // system. Since the bloombits are not positional, nil topics are permitted, - // which get flattened into a nil byte slice. - var filters [][][]byte - if len(addresses) > 0 { - filter := make([][]byte, len(addresses)) - for i, address := range addresses { - filter[i] = address.Bytes() - } - filters = append(filters, filter) - } - for _, topicList := range topics { - filter := make([][]byte, len(topicList)) - for i, topic := range topicList { - filter[i] = topic.Bytes() - } - filters = append(filters, filter) - } - size, _ := sys.backend.BloomStatus() - // Create a generic filter and convert it into a range filter filter := newFilter(sys, addresses, topics) - - filter.matcher = bloombits.NewMatcher(size, filters) filter.begin = begin filter.end = end @@ -113,161 +94,304 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return nil, errPendingLogsUnsupported } - resolveSpecial := func(number int64) (int64, error) { - var hdr *types.Header + resolveSpecial := func(number int64) (uint64, error) { switch number { - case rpc.LatestBlockNumber.Int64(), rpc.PendingBlockNumber.Int64(): - // we should return head here since we've already captured - // that we need to get the pending logs in the pending boolean above - hdr, _ = f.sys.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber) - if hdr == nil { - return 0, errors.New("latest header not found") - } + case rpc.LatestBlockNumber.Int64(): + // when searching from and/or until the current head, we resolve it + // to MaxUint64 which is translated by rangeLogs to the actual head + // in each iteration, ensuring that the head block will be searched + // even if the chain is updated during search. + return math.MaxUint64, nil case rpc.FinalizedBlockNumber.Int64(): - hdr, _ = f.sys.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber) + hdr, _ := f.sys.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber) if hdr == nil { return 0, errors.New("finalized header not found") } + return hdr.Number.Uint64(), nil case rpc.SafeBlockNumber.Int64(): - hdr, _ = f.sys.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber) + hdr, _ := f.sys.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber) if hdr == nil { return 0, errors.New("safe header not found") } - default: - return number, nil + return hdr.Number.Uint64(), nil } - return hdr.Number.Int64(), nil + if number < 0 { + return 0, errors.New("negative block number") + } + return uint64(number), nil } - var err error // range query need to resolve the special begin/end block number - if f.begin, err = resolveSpecial(f.begin); err != nil { + begin, err := resolveSpecial(f.begin) + if err != nil { return nil, err } - if f.end, err = resolveSpecial(f.end); err != nil { + end, err := resolveSpecial(f.end) + if err != nil { return nil, err } + return f.rangeLogs(ctx, begin, end) +} - logChan, errChan := f.rangeLogsAsync(ctx) - var logs []*types.Log - for { - select { - case log := <-logChan: - logs = append(logs, log) - case err := <-errChan: - return logs, err - } +const ( + rangeLogsTestSync = iota + rangeLogsTestTrimmed + rangeLogsTestIndexed + rangeLogsTestUnindexed + rangeLogsTestDone +) + +type rangeLogsTestEvent struct { + event int + begin, end uint64 +} + +// searchSession represents a single search session. +type searchSession struct { + ctx context.Context + filter *Filter + mb filtermaps.MatcherBackend + syncRange filtermaps.SyncRange // latest synchronized state with the matcher + firstBlock, lastBlock uint64 // specified search range; each can be MaxUint64 + searchRange common.Range[uint64] // actual search range; end trimmed to latest head + matchRange common.Range[uint64] // range in which we have results (subset of searchRange) + matches []*types.Log // valid set of matches in matchRange + forceUnindexed bool // revert to unindexed search +} + +// newSearchSession returns a new searchSession. +func newSearchSession(ctx context.Context, filter *Filter, mb filtermaps.MatcherBackend, firstBlock, lastBlock uint64) (*searchSession, error) { + s := &searchSession{ + ctx: ctx, + filter: filter, + mb: mb, + firstBlock: firstBlock, + lastBlock: lastBlock, } + // enforce a consistent state before starting the search in order to be able + // to determine valid range later + if err := s.syncMatcher(0); err != nil { + return nil, err + } + return s, nil } -// rangeLogsAsync retrieves block-range logs that match the filter criteria asynchronously, -// it creates and returns two channels: one for delivering log data, and one for reporting errors. -func (f *Filter) rangeLogsAsync(ctx context.Context) (chan *types.Log, chan error) { - var ( - logChan = make(chan *types.Log) - errChan = make(chan error) - ) - - go func() { - defer func() { - close(errChan) - close(logChan) - }() - - // Gather all indexed logs, and finish with non indexed ones - var ( - end = uint64(f.end) - size, sections = f.sys.backend.BloomStatus() - err error - ) - if indexed := sections * size; indexed > uint64(f.begin) { - if indexed > end { - indexed = end + 1 - } - if err = f.indexedLogs(ctx, indexed-1, logChan); err != nil { - errChan <- err - return - } - } - - if err := f.unindexedLogs(ctx, end, logChan); err != nil { - errChan <- err - return - } - - errChan <- nil - }() - - return logChan, errChan -} - -// indexedLogs returns the logs matching the filter criteria based on the bloom -// bits indexed available locally or via the network. -func (f *Filter) indexedLogs(ctx context.Context, end uint64, logChan chan *types.Log) error { - // Create a matcher session and request servicing from the backend - matches := make(chan uint64, 64) - - session, err := f.matcher.Start(ctx, uint64(f.begin), end, matches) +// syncMatcher performs a synchronization step with the matcher. The resulting +// syncRange structure holds information about the latest range of indexed blocks +// and the guaranteed valid blocks whose log index have not been changed since +// the previous synchronization. +// The function also performs trimming of the match set in order to always keep +// it consistent with the synced matcher state. +// Tail trimming is only performed if the first block of the valid log index range +// is higher than trimTailThreshold. This is useful because unindexed log search +// is not affected by the valid tail (on the other hand, valid head is taken into +// account in order to provide reorg safety, even though the log index is not used). +// In case of indexed search the tail is only trimmed if the first part of the +// recently obtained results might be invalid. If guaranteed valid new results +// have been added at the head of previously validated results then there is no +// need to discard those even if the index tail have been unindexed since that. +func (s *searchSession) syncMatcher(trimTailThreshold uint64) error { + if s.filter.rangeLogsTestHook != nil && !s.matchRange.IsEmpty() { + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{event: rangeLogsTestSync, begin: s.matchRange.First(), end: s.matchRange.Last()} + } + var err error + s.syncRange, err = s.mb.SyncLogIndex(s.ctx) if err != nil { return err } - defer session.Close() + // update actual search range based on current head number + first := min(s.firstBlock, s.syncRange.HeadNumber) + last := min(s.lastBlock, s.syncRange.HeadNumber) + s.searchRange = common.NewRange(first, last+1-first) + // discard everything that is not needed or might be invalid + trimRange := s.syncRange.ValidBlocks + if trimRange.First() <= trimTailThreshold { + // everything before this point is already known to be valid; if this is + // valid then keep everything before + trimRange.SetFirst(0) + } + trimRange = trimRange.Intersection(s.searchRange) + s.trimMatches(trimRange) + if s.filter.rangeLogsTestHook != nil { + if !s.matchRange.IsEmpty() { + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{event: rangeLogsTestTrimmed, begin: s.matchRange.First(), end: s.matchRange.Last()} + } else { + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{event: rangeLogsTestTrimmed, begin: 0, end: 0} + } + } + return nil +} - f.sys.backend.ServiceFilter(ctx, session) +// trimMatches removes any entries from the current set of matches that is outside +// the given range. +func (s *searchSession) trimMatches(trimRange common.Range[uint64]) { + s.matchRange = s.matchRange.Intersection(trimRange) + if s.matchRange.IsEmpty() { + s.matches = nil + return + } + for len(s.matches) > 0 && s.matches[0].BlockNumber < s.matchRange.First() { + s.matches = s.matches[1:] + } + for len(s.matches) > 0 && s.matches[len(s.matches)-1].BlockNumber > s.matchRange.Last() { + s.matches = s.matches[:len(s.matches)-1] + } +} - for { - select { - case number, ok := <-matches: - // Abort if all matches have been fulfilled - if !ok { - err := session.Error() - if err == nil { - f.begin = int64(end) + 1 - } - return err - } - f.begin = int64(number) + 1 +// searchInRange performs a single range search, either indexed or unindexed. +func (s *searchSession) searchInRange(r common.Range[uint64], indexed bool) ([]*types.Log, error) { + first, last := r.First(), r.Last() + if indexed { + if s.filter.rangeLogsTestHook != nil { + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestIndexed, first, last} + } + results, err := s.filter.indexedLogs(s.ctx, s.mb, first, last) + if err != filtermaps.ErrMatchAll { + return results, err + } + // "match all" filters are not supported by filtermaps; fall back to + // unindexed search which is the most efficient in this case + s.forceUnindexed = true + // fall through to unindexed case + } + if s.filter.rangeLogsTestHook != nil { + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestUnindexed, first, last} + } + return s.filter.unindexedLogs(s.ctx, first, last) +} - // Retrieve the suggested block and pull any truly matching logs - header, err := f.sys.backend.HeaderByNumber(ctx, rpc.BlockNumber(number)) - if header == nil || err != nil { - return err - } - found, err := f.checkMatches(ctx, header) +// doSearchIteration performs a search on a range missing from an incomplete set +// of results, adds the new section and removes invalidated entries. +func (s *searchSession) doSearchIteration() error { + switch { + case s.syncRange.IndexedBlocks.IsEmpty(): + // indexer is not ready; fallback to completely unindexed search, do not check valid range + var err error + s.matchRange = s.searchRange + s.matches, err = s.searchInRange(s.searchRange, false) + return err + + case s.matchRange.IsEmpty(): + // no results yet; try search in entire range + indexedSearchRange := s.searchRange.Intersection(s.syncRange.IndexedBlocks) + var err error + if s.forceUnindexed = indexedSearchRange.IsEmpty(); !s.forceUnindexed { + // indexed search on the intersection of indexed and searched range + s.matchRange = indexedSearchRange + s.matches, err = s.searchInRange(indexedSearchRange, true) if err != nil { return err } - for _, log := range found { - logChan <- log + return s.syncMatcher(0) // trim everything that the matcher considers potentially invalid + } else { + // no intersection of indexed and searched range; unindexed search on the whole searched range + s.matchRange = s.searchRange + s.matches, err = s.searchInRange(s.searchRange, false) + if err != nil { + return err } + return s.syncMatcher(math.MaxUint64) // unindexed search is not affected by the tail of valid range + } - case <-ctx.Done(): - return ctx.Err() + case !s.matchRange.IsEmpty() && s.matchRange.First() > s.searchRange.First(): + // we have results but tail section is missing; do unindexed search for + // the tail part but still allow indexed search for missing head section + tailRange := common.NewRange(s.searchRange.First(), s.matchRange.First()-s.searchRange.First()) + tailMatches, err := s.searchInRange(tailRange, false) + if err != nil { + return err + } + s.matches = append(tailMatches, s.matches...) + s.matchRange = tailRange.Union(s.matchRange) + return s.syncMatcher(math.MaxUint64) // unindexed search is not affected by the tail of valid range + + case !s.matchRange.IsEmpty() && s.matchRange.First() == s.searchRange.First() && s.searchRange.AfterLast() > s.matchRange.AfterLast(): + // we have results but head section is missing + headRange := common.NewRange(s.matchRange.AfterLast(), s.searchRange.AfterLast()-s.matchRange.AfterLast()) + if !s.forceUnindexed { + indexedHeadRange := headRange.Intersection(s.syncRange.IndexedBlocks) + if !indexedHeadRange.IsEmpty() && indexedHeadRange.First() == headRange.First() { + // indexed head range search is possible + headRange = indexedHeadRange + } else { + s.forceUnindexed = true + } + } + headMatches, err := s.searchInRange(headRange, !s.forceUnindexed) + if err != nil { + return err + } + s.matches = append(s.matches, headMatches...) + s.matchRange = s.matchRange.Union(headRange) + if s.forceUnindexed { + return s.syncMatcher(math.MaxUint64) // unindexed search is not affected by the tail of valid range + } else { + return s.syncMatcher(headRange.First()) // trim if the tail of latest head search results might be invalid + } + + default: + panic("invalid search session state") + } +} + +func (f *Filter) rangeLogs(ctx context.Context, firstBlock, lastBlock uint64) ([]*types.Log, error) { + if f.rangeLogsTestHook != nil { + defer func() { + f.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestDone, 0, 0} + close(f.rangeLogsTestHook) + }() + } + + if firstBlock > lastBlock { + return nil, nil + } + mb := f.sys.backend.NewMatcherBackend() + defer mb.Close() + + session, err := newSearchSession(ctx, f, mb, firstBlock, lastBlock) + if err != nil { + return nil, err + } + for session.searchRange != session.matchRange { + if err := session.doSearchIteration(); err != nil { + return session.matches, err } } + return session.matches, nil +} + +func (f *Filter) indexedLogs(ctx context.Context, mb filtermaps.MatcherBackend, begin, end uint64) ([]*types.Log, error) { + start := time.Now() + potentialMatches, err := filtermaps.GetPotentialMatches(ctx, mb, begin, end, f.addresses, f.topics) + matches := filterLogs(potentialMatches, nil, nil, f.addresses, f.topics) + log.Trace("Performed indexed log search", "begin", begin, "end", end, "true matches", len(matches), "false positives", len(potentialMatches)-len(matches), "elapsed", common.PrettyDuration(time.Since(start))) + return matches, err } // unindexedLogs returns the logs matching the filter criteria based on raw block // iteration and bloom matching. -func (f *Filter) unindexedLogs(ctx context.Context, end uint64, logChan chan *types.Log) error { - for ; f.begin <= int64(end); f.begin++ { - header, err := f.sys.backend.HeaderByNumber(ctx, rpc.BlockNumber(f.begin)) +func (f *Filter) unindexedLogs(ctx context.Context, begin, end uint64) ([]*types.Log, error) { + start := time.Now() + log.Warn("Performing unindexed log search", "begin", begin, "end", end) + var matches []*types.Log + for blockNumber := begin; blockNumber <= end; blockNumber++ { + select { + case <-ctx.Done(): + return matches, ctx.Err() + default: + } + header, err := f.sys.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber)) if header == nil || err != nil { - return err + return matches, err } found, err := f.blockLogs(ctx, header) if err != nil { - return err - } - for _, log := range found { - select { - case logChan <- log: - case <-ctx.Done(): - return ctx.Err() - } + return matches, err } + matches = append(matches, found...) } - return nil + log.Trace("Performed unindexed log search", "begin", begin, "end", end, "matches", len(matches), "elapsed", common.PrettyDuration(time.Since(start))) + return matches, nil } // blockLogs returns the logs matching the filter criteria within a single block. diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 86012b3f9a..7531a1ecfc 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -29,7 +29,7 @@ import ( "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/bloombits" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" @@ -69,8 +69,7 @@ type Backend interface { SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription - BloomStatus() (uint64, uint64) - ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) + NewMatcherBackend() filtermaps.MatcherBackend } // FilterSystem holds resources shared by all filters. diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index aec5ee4166..c35d823f5a 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -20,7 +20,6 @@ import ( "context" "errors" "math/big" - "math/rand" "reflect" "runtime" "testing" @@ -29,7 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" @@ -41,7 +40,7 @@ import ( type testBackend struct { db ethdb.Database - sections uint64 + fm *filtermaps.FilterMaps txFeed event.Feed logsFeed event.Feed rmLogsFeed event.Feed @@ -59,10 +58,28 @@ func (b *testBackend) CurrentHeader() *types.Header { return hdr } +func (b *testBackend) CurrentBlock() *types.Header { + return b.CurrentHeader() +} + func (b *testBackend) ChainDb() ethdb.Database { return b.db } +func (b *testBackend) GetCanonicalHash(number uint64) common.Hash { + return rawdb.ReadCanonicalHash(b.db, number) +} + +func (b *testBackend) GetHeader(hash common.Hash, number uint64) *types.Header { + hdr, _ := b.HeaderByHash(context.Background(), hash) + return hdr +} + +func (b *testBackend) GetReceiptsByHash(hash common.Hash) types.Receipts { + r, _ := b.GetReceipts(context.Background(), hash) + return r +} + func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { var ( hash common.Hash @@ -137,35 +154,26 @@ func (b *testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subsc return b.chainFeed.Subscribe(ch) } -func (b *testBackend) BloomStatus() (uint64, uint64) { - return params.BloomBitsBlocks, b.sections +func (b *testBackend) NewMatcherBackend() filtermaps.MatcherBackend { + return b.fm.NewMatcherBackend() } -func (b *testBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { - requests := make(chan chan *bloombits.Retrieval) +func (b *testBackend) startFilterMaps(history uint64, disabled bool, params filtermaps.Params) { + head := b.CurrentBlock() + chainView := filtermaps.NewChainView(b, head.Number.Uint64(), head.Hash()) + config := filtermaps.Config{ + History: history, + Disabled: disabled, + ExportFileName: "", + } + b.fm = filtermaps.NewFilterMaps(b.db, chainView, 0, 0, params, config) + b.fm.Start() + b.fm.WaitIdle() +} - go session.Multiplex(16, 0, requests) - go func() { - for { - // Wait for a service request or a shutdown - select { - case <-ctx.Done(): - return - - case request := <-requests: - task := <-request - - task.Bitsets = make([][]byte, len(task.Sections)) - for i, section := range task.Sections { - if rand.Int()%4 != 0 { // Handle occasional missing deliveries - head := rawdb.ReadCanonicalHash(b.db, (section+1)*params.BloomBitsBlocks-1) - task.Bitsets[i], _ = rawdb.ReadBloomBits(b.db, task.Bit, section, head) - } - } - request <- task - } - } - }() +func (b *testBackend) stopFilterMaps() { + b.fm.Stop() + b.fm = nil } func (b *testBackend) setPending(block *types.Block, receipts types.Receipts) { @@ -173,7 +181,7 @@ func (b *testBackend) setPending(block *types.Block, receipts types.Receipts) { b.pendingReceipts = receipts } -func newTestFilterSystem(t testing.TB, db ethdb.Database, cfg Config) (*testBackend, *FilterSystem) { +func newTestFilterSystem(db ethdb.Database, cfg Config) (*testBackend, *FilterSystem) { backend := &testBackend{db: db} sys := NewFilterSystem(backend, cfg) return backend, sys @@ -189,7 +197,7 @@ func TestBlockSubscription(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - backend, sys = newTestFilterSystem(t, db, Config{}) + backend, sys = newTestFilterSystem(db, Config{}) api = NewFilterAPI(sys) genesis = &core.Genesis{ Config: params.TestChainConfig, @@ -244,7 +252,7 @@ func TestPendingTxFilter(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - backend, sys = newTestFilterSystem(t, db, Config{}) + backend, sys = newTestFilterSystem(db, Config{}) api = NewFilterAPI(sys) transactions = []*types.Transaction{ @@ -300,7 +308,7 @@ func TestPendingTxFilterFullTx(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - backend, sys = newTestFilterSystem(t, db, Config{}) + backend, sys = newTestFilterSystem(db, Config{}) api = NewFilterAPI(sys) transactions = []*types.Transaction{ @@ -356,7 +364,7 @@ func TestPendingTxFilterFullTx(t *testing.T) { func TestLogFilterCreation(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - _, sys = newTestFilterSystem(t, db, Config{}) + _, sys = newTestFilterSystem(db, Config{}) api = NewFilterAPI(sys) testCases = []struct { @@ -403,7 +411,7 @@ func TestInvalidLogFilterCreation(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - _, sys = newTestFilterSystem(t, db, Config{}) + _, sys = newTestFilterSystem(db, Config{}) api = NewFilterAPI(sys) ) @@ -429,7 +437,7 @@ func TestInvalidGetLogsRequest(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - _, sys = newTestFilterSystem(t, db, Config{}) + _, sys = newTestFilterSystem(db, Config{}) api = NewFilterAPI(sys) blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") ) @@ -455,7 +463,7 @@ func TestInvalidGetRangeLogsRequest(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - _, sys = newTestFilterSystem(t, db, Config{}) + _, sys = newTestFilterSystem(db, Config{}) api = NewFilterAPI(sys) ) @@ -470,7 +478,7 @@ func TestLogFilter(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - backend, sys = newTestFilterSystem(t, db, Config{}) + backend, sys = newTestFilterSystem(db, Config{}) api = NewFilterAPI(sys) firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") @@ -575,7 +583,7 @@ func TestPendingTxFilterDeadlock(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - backend, sys = newTestFilterSystem(t, db, Config{Timeout: timeout}) + backend, sys = newTestFilterSystem(db, Config{Timeout: timeout}) api = NewFilterAPI(sys) done = make(chan struct{}) ) @@ -599,7 +607,7 @@ func TestPendingTxFilterDeadlock(t *testing.T) { // Create a bunch of filters that will // timeout either in 100ms or 200ms subs := make([]*Subscription, 20) - for i := 0; i < len(subs); i++ { + for i := range subs { fid := api.NewPendingTransactionFilter(nil) api.filtersMu.Lock() f, ok := api.filters[fid] diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index e2790d91eb..4026c03e89 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -46,15 +47,27 @@ func makeReceipt(addr common.Address) *types.Receipt { return receipt } -func BenchmarkFilters(b *testing.B) { +func BenchmarkFiltersIndexed(b *testing.B) { + benchmarkFilters(b, 0, false) +} + +func BenchmarkFiltersHalfIndexed(b *testing.B) { + benchmarkFilters(b, 50000, false) +} + +func BenchmarkFiltersUnindexed(b *testing.B) { + benchmarkFilters(b, 0, true) +} + +func benchmarkFilters(b *testing.B, history uint64, noHistory bool) { var ( - db = rawdb.NewMemoryDatabase() - _, sys = newTestFilterSystem(b, db, Config{}) - key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr1 = crypto.PubkeyToAddress(key1.PublicKey) - addr2 = common.BytesToAddress([]byte("jeff")) - addr3 = common.BytesToAddress([]byte("ethereum")) - addr4 = common.BytesToAddress([]byte("random addresses please")) + db = rawdb.NewMemoryDatabase() + backend, sys = newTestFilterSystem(db, Config{}) + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = common.BytesToAddress([]byte("jeff")) + addr3 = common.BytesToAddress([]byte("ethereum")) + addr4 = common.BytesToAddress([]byte("random addresses please")) gspec = &core.Genesis{ Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}}, @@ -94,9 +107,12 @@ func BenchmarkFilters(b *testing.B) { rawdb.WriteHeadBlockHash(db, block.Hash()) rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i]) } + backend.startFilterMaps(history, noHistory, filtermaps.DefaultParams) + defer backend.stopFilterMaps() + b.ResetTimer() - filter := sys.NewRangeFilter(0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil) + filter := sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{addr1, addr2, addr3, addr4}, nil) for i := 0; i < b.N; i++ { filter.begin = 0 @@ -107,10 +123,22 @@ func BenchmarkFilters(b *testing.B) { } } -func TestFilters(t *testing.T) { +func TestFiltersIndexed(t *testing.T) { + testFilters(t, 0, false) +} + +func TestFiltersHalfIndexed(t *testing.T) { + testFilters(t, 500, false) +} + +func TestFiltersUnindexed(t *testing.T) { + testFilters(t, 0, true) +} + +func testFilters(t *testing.T, history uint64, noHistory bool) { var ( db = rawdb.NewMemoryDatabase() - backend, sys = newTestFilterSystem(t, db, Config{}) + backend, sys = newTestFilterSystem(db, Config{}) // Sender account key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr = crypto.PubkeyToAddress(key1.PublicKey) @@ -279,6 +307,9 @@ func TestFilters(t *testing.T) { }) backend.setPending(pchain[0], preceipts[0]) + backend.startFilterMaps(history, noHistory, filtermaps.DefaultParams) + defer backend.stopFilterMaps() + for i, tc := range []struct { f *Filter want string @@ -387,3 +418,146 @@ func TestFilters(t *testing.T) { } }) } + +func TestRangeLogs(t *testing.T) { + var ( + db = rawdb.NewMemoryDatabase() + backend, sys = newTestFilterSystem(db, Config{}) + gspec = &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{}, + BaseFee: big.NewInt(params.InitialBaseFee), + } + ) + _, err := gspec.Commit(db, triedb.NewDatabase(db, nil)) + if err != nil { + t.Fatal(err) + } + chain, _ := core.GenerateChain(gspec.Config, gspec.ToBlock(), ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) {}) + var l uint64 + bc, err := core.NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, &l) + if err != nil { + t.Fatal(err) + } + _, err = bc.InsertChain(chain[:600]) + if err != nil { + t.Fatal(err) + } + + backend.startFilterMaps(200, false, filtermaps.RangeTestParams) + defer backend.stopFilterMaps() + + var ( + testCase, event int + filter *Filter + addresses = []common.Address{{}} + ) + + expEvent := func(exp rangeLogsTestEvent) { + event++ + ev := <-filter.rangeLogsTestHook + if ev != exp { + t.Fatalf("Test case #%d: wrong test event #%d received (got %v, expected %v)", testCase, event, ev, exp) + } + } + + newFilter := func(begin, end int64) { + testCase++ + event = 0 + filter = sys.NewRangeFilter(begin, end, addresses, nil) + filter.rangeLogsTestHook = make(chan rangeLogsTestEvent) + go func(filter *Filter) { + filter.Logs(context.Background()) + // ensure that filter will not be blocked if we exit early + for range filter.rangeLogsTestHook { + } + }(filter) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 0, 0}) + } + + updateHead := func() { + head := bc.CurrentBlock() + backend.fm.SetTarget(filtermaps.NewChainView(backend, head.Number.Uint64(), head.Hash()), 0, 0) + backend.fm.WaitIdle() + } + + // test case #1 + newFilter(300, 500) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 401, 500}) + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 401, 500}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 401, 500}) + expEvent(rangeLogsTestEvent{rangeLogsTestUnindexed, 300, 400}) + if _, err := bc.InsertChain(chain[600:700]); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 300, 500}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 300, 500}) // unindexed search is not affected by trimmed tail + expEvent(rangeLogsTestEvent{rangeLogsTestDone, 0, 0}) + + // test case #2 + newFilter(400, int64(rpc.LatestBlockNumber)) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 501, 700}) + if _, err := bc.InsertChain(chain[700:800]); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 501, 700}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 601, 698}) + expEvent(rangeLogsTestEvent{rangeLogsTestUnindexed, 400, 600}) + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 698}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 400, 698}) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 699, 800}) + if err := bc.SetHead(750); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 800}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 400, 748}) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 749, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 400, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestDone, 0, 0}) + + // test case #3 + newFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber)) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 750, 750}) + if err := bc.SetHead(740); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 750, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 0, 0}) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 740, 740}) + if _, err := bc.InsertChain(chain[740:750]); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 740, 740}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 0, 0}) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 750, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 750, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 750, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestDone, 0, 0}) + + // test case #4 + newFilter(400, int64(rpc.LatestBlockNumber)) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 551, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 551, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 551, 750}) + expEvent(rangeLogsTestEvent{rangeLogsTestUnindexed, 400, 550}) + if _, err := bc.InsertChain(chain[750:1000]); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 750}) + // indexed range affected by tail pruning so we have to discard the entire + // match set + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 0, 0}) + expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 801, 1000}) + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 801, 1000}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 801, 1000}) + expEvent(rangeLogsTestEvent{rangeLogsTestUnindexed, 400, 800}) + expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 1000}) + expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 400, 1000}) +} diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index d70cb90ec9..88ff7b8af3 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -46,7 +46,7 @@ import ( "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/bloombits" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -615,11 +615,9 @@ func (b testBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) func (b testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { panic("implement me") } -func (b testBackend) BloomStatus() (uint64, uint64) { panic("implement me") } -func (b testBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { +func (b testBackend) NewMatcherBackend() filtermaps.MatcherBackend { panic("implement me") } - func TestEstimateGas(t *testing.T) { t.Parallel() // Initialize test accounts diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 3d8f7aa700..9e2ea2c876 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -27,7 +27,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -93,8 +93,8 @@ 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 - BloomStatus() (uint64, uint64) - ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) + + NewMatcherBackend() filtermaps.MatcherBackend } func GetAPIs(apiBackend Backend) []rpc.API { diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index e017804861..a5fd9bb0d4 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -30,7 +30,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -393,12 +393,12 @@ func (b *backendMock) TxPoolContent() (map[common.Address][]*types.Transaction, func (b *backendMock) TxPoolContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) { return nil, nil } -func (b *backendMock) SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription { return nil } -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) SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription { return nil } +func (b *backendMock) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { return nil } func (b *backendMock) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { return nil } func (b *backendMock) Engine() consensus.Engine { return nil } + +func (b *backendMock) NewMatcherBackend() filtermaps.MatcherBackend { return nil } From 40ad6bedf6cb4cb36851a713720ee81b095f2592 Mon Sep 17 00:00:00 2001 From: Shahar Rosenberg Date: Tue, 18 Mar 2025 11:05:12 +0000 Subject: [PATCH 202/940] eth/tracers: fix precompile move feat for debug_traceCall (#31348) `debug_traceCall` was ignoring the override `movePrecompileToAddress`. Now it is at feature-parity with eth_call. --- eth/tracers/api.go | 26 ++++++++++++++----------- eth/tracers/api_test.go | 43 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/eth/tracers/api.go b/eth/tracers/api.go index d13aee555f..627dd487fc 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -279,7 +279,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed TxIndex: i, TxHash: tx.Hash(), } - res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, task.statedb, config) + res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, task.statedb, config, nil) 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) @@ -632,7 +632,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac TxIndex: i, TxHash: tx.Hash(), } - res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, statedb, config) + res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, statedb, config, nil) if err != nil { return nil, err } @@ -676,7 +676,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat // 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) + res, err := api.traceTx(ctx, txs[task.index], msg, txctx, blockCtx, task.statedb, config, nil) if err != nil { results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()} continue @@ -894,7 +894,7 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config * TxIndex: int(index), TxHash: hash, } - return api.traceTx(ctx, tx, msg, txctx, vmctx, statedb, config) + return api.traceTx(ctx, tx, msg, txctx, vmctx, statedb, config, nil) } // TraceCall lets you trace a given eth_call. It collects the structured logs @@ -907,10 +907,11 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config * func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceCallConfig) (interface{}, error) { // Try to retrieve the specified block var ( - err error - block *types.Block - statedb *state.StateDB - release StateReleaseFunc + err error + block *types.Block + statedb *state.StateDB + release StateReleaseFunc + precompiles vm.PrecompiledContracts ) if hash, ok := blockNrOrHash.Hash(); ok { block, err = api.blockByHash(ctx, hash) @@ -952,7 +953,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc config.BlockOverrides.Apply(&vmctx) rules := api.backend.ChainConfig().Rules(vmctx.BlockNumber, vmctx.Random != nil, vmctx.Time) - precompiles := vm.ActivePrecompiledContracts(rules) + precompiles = vm.ActivePrecompiledContracts(rules) if err := config.StateOverrides.Apply(statedb, precompiles); err != nil { return nil, err } @@ -977,13 +978,13 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc if config != nil { traceConfig = &config.TraceConfig } - return api.traceTx(ctx, tx, msg, new(Context), vmctx, statedb, traceConfig) + return api.traceTx(ctx, tx, msg, new(Context), vmctx, statedb, traceConfig, precompiles) } // 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, tx *types.Transaction, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (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, precompiles vm.PrecompiledContracts) (interface{}, error) { var ( tracer *Tracer err error @@ -1009,6 +1010,9 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor } tracingStateDB := state.NewHookedState(statedb, tracer.Hooks) evm := vm.NewEVM(vmctx, tracingStateDB, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true}) + if precompiles != nil { + evm.SetPrecompiles(precompiles) + } // Define a meaningful timeout of a single transaction trace if config.Timeout != nil { diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 95e7739be0..796719bd63 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -642,6 +642,7 @@ func TestTracingWithOverrides(t *testing.T) { t.Parallel() // Initialize test accounts accounts := newAccounts(3) + ecRecoverAddress := common.HexToAddress("0x0000000000000000000000000000000000000001") storageAccount := common.Address{0x13, 37} genesis := &core.Genesis{ Config: params.TestChainConfig, @@ -940,6 +941,48 @@ func TestTracingWithOverrides(t *testing.T) { }, want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000055"}`, }, + { // Call to precompile ECREC (0x01), but code was modified to add 1 to input + blockNumber: rpc.LatestBlockNumber, + call: ethapi.TransactionArgs{ + From: &randomAccounts[0].addr, + To: &ecRecoverAddress, + Data: newRPCBytes(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")), + }, + config: &TraceCallConfig{ + StateOverrides: &override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{ + Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether))), + }, + ecRecoverAddress: override.OverrideAccount{ + // The code below adds one to input + Code: newRPCBytes(common.Hex2Bytes("60003560010160005260206000f3")), + MovePrecompileTo: &randomAccounts[2].addr, + }, + }, + }, + want: `{"gas":21167,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000002"}`, + }, + { // Call to ECREC Precompiled on a different address, expect the original behaviour of ECREC precompile + blockNumber: rpc.LatestBlockNumber, + call: ethapi.TransactionArgs{ + From: &randomAccounts[0].addr, + To: &randomAccounts[2].addr, // Moved EcRecover + Data: newRPCBytes(common.Hex2Bytes("82f3df49d3645876de6313df2bbe9fbce593f21341a7b03acdb9423bc171fcc9000000000000000000000000000000000000000000000000000000000000001cba13918f50da910f2d55a7ea64cf716ba31dad91856f45908dde900530377d8a112d60f36900d18eb8f9d3b4f85a697b545085614509e3520e4b762e35d0d6bd")), + }, + config: &TraceCallConfig{ + StateOverrides: &override.StateOverride{ + randomAccounts[0].addr: override.OverrideAccount{ + Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether))), + }, + ecRecoverAddress: override.OverrideAccount{ + // The code below adds one to input + Code: newRPCBytes(common.Hex2Bytes("60003560010160005260206000f3")), + MovePrecompileTo: &randomAccounts[2].addr, // Move EcRecover to this address + }, + }, + }, + want: `{"gas":25664,"failed":false,"returnValue":"000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074"}`, + }, } for i, tc := range testSuite { result, err := api.TraceCall(context.Background(), tc.call, rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, tc.config) From 668118bfe12b32c1c0f74878d18806c099426b82 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 18 Mar 2025 12:07:49 +0100 Subject: [PATCH 203/940] params: add hoodi testnet definition (#31406) Adds support for the new hoodi testnet. Hoodi is meant for stakers to test their setup. For more info please refer to https://hoodi.ethpandaops.io/. --- beacon/params/networks.go | 13 +++++++++++ cmd/blsync/main.go | 1 + cmd/devp2p/nodesetcmd.go | 2 ++ cmd/geth/main.go | 4 ++++ cmd/utils/flags.go | 27 ++++++++++++++++++++-- core/filtermaps/checkpoints.go | 4 ++++ core/filtermaps/checkpoints_hoodi.json | 1 + core/forkid/forkid_test.go | 11 +++++++++ core/genesis.go | 16 +++++++++++++ core/genesis_alloc.go | 1 + core/genesis_test.go | 11 +++++++++ core/rawdb/accessors_indexes_test.go | 8 +++++++ params/bootnodes.go | 11 +++++++++ params/config.go | 32 ++++++++++++++++++++++++++ 14 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 core/filtermaps/checkpoints_hoodi.json diff --git a/beacon/params/networks.go b/beacon/params/networks.go index eda225e0fe..c547986977 100644 --- a/beacon/params/networks.go +++ b/beacon/params/networks.go @@ -55,4 +55,17 @@ var ( AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}). AddFork("DENEB", 29696, []byte{5, 1, 112, 0}). AddFork("ELECTRA", 115968, []byte{6, 1, 112, 0}) + + HoodiLightConfig = (&ChainConfig{ + GenesisValidatorsRoot: common.HexToHash("0x212f13fc4df078b6cb7db228f1c8307566dcecf900867401a92023d7ba99cb5f"), + GenesisTime: 1742212800, + Checkpoint: common.HexToHash(""), + }). + AddFork("GENESIS", 0, common.FromHex("0x10000910")). + AddFork("ALTAIR", 0, common.FromHex("0x20000910")). + AddFork("BELLATRIX", 0, common.FromHex("0x30000910")). + AddFork("CAPELLA", 0, common.FromHex("0x40000910")). + AddFork("DENEB", 0, common.FromHex("0x50000910")). + AddFork("ELECTRA", 2048, common.FromHex("0x60000910")). + AddFork("FULU", 18446744073709551615, common.FromHex("0x70000910")) ) diff --git a/cmd/blsync/main.go b/cmd/blsync/main.go index 57bc46c367..60caa4aa2a 100644 --- a/cmd/blsync/main.go +++ b/cmd/blsync/main.go @@ -47,6 +47,7 @@ func main() { utils.MainnetFlag, utils.SepoliaFlag, utils.HoleskyFlag, + utils.HoodiFlag, utils.BlsyncApiFlag, utils.BlsyncJWTSecretFlag, }, diff --git a/cmd/devp2p/nodesetcmd.go b/cmd/devp2p/nodesetcmd.go index c8177f049d..d7725fadb1 100644 --- a/cmd/devp2p/nodesetcmd.go +++ b/cmd/devp2p/nodesetcmd.go @@ -234,6 +234,8 @@ func ethFilter(args []string) (nodeFilter, error) { filter = forkid.NewStaticFilter(params.SepoliaChainConfig, core.DefaultSepoliaGenesisBlock().ToBlock()) case "holesky": filter = forkid.NewStaticFilter(params.HoleskyChainConfig, core.DefaultHoleskyGenesisBlock().ToBlock()) + case "hoodi": + filter = forkid.NewStaticFilter(params.HoodiChainConfig, core.DefaultHoodiGenesisBlock().ToBlock()) default: return nil, fmt.Errorf("unknown network %q", args[0]) } diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 2995d87624..07fbeaca5c 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -296,6 +296,9 @@ func prepare(ctx *cli.Context) { case ctx.IsSet(utils.HoleskyFlag.Name): log.Info("Starting Geth on Holesky testnet...") + case ctx.IsSet(utils.HoodiFlag.Name): + log.Info("Starting Geth on Hoodi testnet...") + case ctx.IsSet(utils.DeveloperFlag.Name): log.Info("Starting Geth in ephemeral dev mode...") log.Warn(`You are running Geth in --dev mode. Please note the following: @@ -322,6 +325,7 @@ func prepare(ctx *cli.Context) { // Make sure we're not on any supported preconfigured testnet either if !ctx.IsSet(utils.HoleskyFlag.Name) && !ctx.IsSet(utils.SepoliaFlag.Name) && + !ctx.IsSet(utils.HoodiFlag.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) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 2e3bb6aead..d60f9c64d5 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -134,7 +134,7 @@ var ( } NetworkIdFlag = &cli.Uint64Flag{ Name: "networkid", - Usage: "Explicitly set network id (integer)(For testnets: use --sepolia, --holesky instead)", + Usage: "Explicitly set network id (integer)(For testnets: use --sepolia, --holesky, --hoodi instead)", Value: ethconfig.Defaults.NetworkId, Category: flags.EthCategory, } @@ -153,6 +153,11 @@ var ( Usage: "Holesky network: pre-configured proof-of-stake test network", Category: flags.EthCategory, } + HoodiFlag = &cli.BoolFlag{ + Name: "hoodi", + Usage: "Hoodi network: pre-configured proof-of-stake test network", + Category: flags.EthCategory, + } // Dev mode DeveloperFlag = &cli.BoolFlag{ Name: "dev", @@ -958,6 +963,7 @@ var ( TestnetFlags = []cli.Flag{ SepoliaFlag, HoleskyFlag, + HoodiFlag, } // NetworkFlags is the flag group of all built-in supported networks. NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...) @@ -984,6 +990,9 @@ func MakeDataDir(ctx *cli.Context) string { if ctx.Bool(HoleskyFlag.Name) { return filepath.Join(path, "holesky") } + if ctx.Bool(HoodiFlag.Name) { + return filepath.Join(path, "hoodi") + } return path } Fatalf("Cannot determine default data directory, please set manually (--datadir)") @@ -1044,6 +1053,8 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { urls = params.HoleskyBootnodes case ctx.Bool(SepoliaFlag.Name): urls = params.SepoliaBootnodes + case ctx.Bool(HoodiFlag.Name): + urls = params.HoodiBootnodes } } cfg.BootstrapNodes = mustParseBootnodes(urls) @@ -1428,6 +1439,8 @@ func SetDataDir(ctx *cli.Context, cfg *node.Config) { cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia") case ctx.Bool(HoleskyFlag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "holesky") + case ctx.Bool(HoodiFlag.Name) && cfg.DataDir == node.DefaultDataDir(): + cfg.DataDir = filepath.Join(node.DefaultDataDir(), "hoodi") } } @@ -1554,7 +1567,7 @@ func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) { // SetEthConfig applies eth-related command line flags to the config. func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { // Avoid conflicting network flags - flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag) + flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag, HoodiFlag) flags.CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer // Set configurations from CLI flags @@ -1738,6 +1751,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } cfg.Genesis = core.DefaultSepoliaGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.SepoliaGenesisHash) + case ctx.Bool(HoodiFlag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { + cfg.NetworkId = 560048 + } + cfg.Genesis = core.DefaultHoodiGenesisBlock() + SetDNSDiscoveryDefaults(cfg, params.HoodiGenesisHash) case ctx.Bool(DeveloperFlag.Name): if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = 1337 @@ -1852,6 +1871,8 @@ func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig { config.ChainConfig = *bparams.SepoliaLightConfig case ctx.Bool(HoleskyFlag.Name): config.ChainConfig = *bparams.HoleskyLightConfig + case ctx.Bool(HoodiFlag.Name): + config.ChainConfig = *bparams.HoodiLightConfig default: if !customConfig { config.ChainConfig = *bparams.MainnetLightConfig @@ -2118,6 +2139,8 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis { genesis = core.DefaultHoleskyGenesisBlock() case ctx.Bool(SepoliaFlag.Name): genesis = core.DefaultSepoliaGenesisBlock() + case ctx.Bool(HoodiFlag.Name): + genesis = core.DefaultHoodiGenesisBlock() case ctx.Bool(DeveloperFlag.Name): Fatalf("Developer chains are ephemeral") } diff --git a/core/filtermaps/checkpoints.go b/core/filtermaps/checkpoints.go index f8d6500aa7..face4ea5d3 100644 --- a/core/filtermaps/checkpoints.go +++ b/core/filtermaps/checkpoints.go @@ -46,6 +46,9 @@ var checkpointsSepoliaJSON []byte //go:embed checkpoints_holesky.json var checkpointsHoleskyJSON []byte +//go:embed checkpoints_hoodi.json +var checkpointsHoodiJSON []byte + // checkpoints lists sets of checkpoints for multiple chains. The matching // checkpoint set is autodetected by the indexer once the canonical chain is // known. @@ -53,6 +56,7 @@ var checkpoints = []checkpointList{ decodeCheckpoints(checkpointsMainnetJSON), decodeCheckpoints(checkpointsSepoliaJSON), decodeCheckpoints(checkpointsHoleskyJSON), + decodeCheckpoints(checkpointsHoodiJSON), } func decodeCheckpoints(encoded []byte) (result checkpointList) { diff --git a/core/filtermaps/checkpoints_hoodi.json b/core/filtermaps/checkpoints_hoodi.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/core/filtermaps/checkpoints_hoodi.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go index bebc20ad9d..31e2b534be 100644 --- a/core/forkid/forkid_test.go +++ b/core/forkid/forkid_test.go @@ -112,6 +112,17 @@ func TestCreation(t *testing.T) { {123, 2740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 0}}, // Future Prague block }, }, + // Hoodi test cases + { + params.HoodiChainConfig, + core.DefaultHoodiGenesisBlock().ToBlock(), + []testcase{ + {0, 0, ID{Hash: checksumToBytes(0xbef71d30), Next: 1742999832}}, // Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London, Paris, Shanghai, Cancun block + {123, 1742999831, ID{Hash: checksumToBytes(0xbef71d30), Next: 1742999832}}, // Last Cancun block + {123, 1742999832, ID{Hash: checksumToBytes(0x0929e24e), Next: 0}}, // First Prague block + {123, 2740434112, ID{Hash: checksumToBytes(0x0929e24e), Next: 0}}, // Future Prague block + }, + }, } for i, tt := range tests { for j, ttt := range tt.cases { diff --git a/core/genesis.go b/core/genesis.go index 23f4a73ec5..95782a827a 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -221,6 +221,8 @@ func getGenesisState(db ethdb.Database, blockhash common.Hash) (alloc types.Gene genesis = DefaultSepoliaGenesisBlock() case params.HoleskyGenesisHash: genesis = DefaultHoleskyGenesisBlock() + case params.HoodiGenesisHash: + genesis = DefaultHoodiGenesisBlock() } if genesis != nil { return genesis.Alloc, nil @@ -431,6 +433,8 @@ func (g *Genesis) chainConfigOrDefault(ghash common.Hash, stored *params.ChainCo return params.HoleskyChainConfig case ghash == params.SepoliaGenesisHash: return params.SepoliaChainConfig + case ghash == params.HoodiGenesisHash: + return params.HoodiChainConfig default: return stored } @@ -625,6 +629,18 @@ func DefaultHoleskyGenesisBlock() *Genesis { } } +// DefaultHoodiGenesisBlock returns the Hoodi network genesis block. +func DefaultHoodiGenesisBlock() *Genesis { + return &Genesis{ + Config: params.HoodiChainConfig, + Nonce: 0x1234, + GasLimit: 0x2255100, + Difficulty: big.NewInt(0x01), + Timestamp: 1742212800, + Alloc: decodePrealloc(hoodiAllocData), + } +} + // DeveloperGenesisBlock returns the 'geth --dev' genesis block. func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis { // Override the default period to the user requested one diff --git a/core/genesis_alloc.go b/core/genesis_alloc.go index 28bb2d5c10..68a1838d98 100644 --- a/core/genesis_alloc.go +++ b/core/genesis_alloc.go @@ -24,3 +24,4 @@ package core 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\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" +const hoodiAllocData = "\xf93\x9d\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\xf9!.\x90!\x9a\xb5@5l\xbb\x83\x9c\xbe\x050=w\x05\xfa\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 \xdc\xec\xa8pk)\xe9\x17\xda\xcf%\xfc\xee\xf9Z\xca\xc8\xd9\rvZ\xc9&f<\xe4\ta\x95\x95+adsolcC\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\u0791i\x16\xa8{\x823?BE\x04f#\xb27\x94\xc6\\\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xf9\x02Y\x92\ta\xefH\x0e\xb5^\x80\u045a\xd85y\xa6L\x00p\x02\x80\xf9\x02B\x01\xb9\x01\xf83s\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x14`\xcbW`\x11_T\x80\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\x14a\x01\xf4W`\x01\x82\x02`\x01\x90_[_\x82\x11\x15`hW\x81\x01\x90\x83\x02\x84\x83\x02\x90\x04\x91`\x01\x01\x91\x90`MV[\x90\x93\x90\x04\x92PPP6`8\x14`\x88W6a\x01\xf4W4a\x01\xf4W_R` _\xf3[4\x10a\x01\xf4W`\x01T`\x01\x01`\x01U`\x03T\x80`\x03\x02`\x04\x013\x81U`\x01\x01_5\x81U`\x01\x01` 5\x90U3``\x1b_R`8_`\x147`L_\xa0`\x01\x01`\x03U\x00[`\x03T`\x02T\x80\x82\x03\x80`\x10\x11`\xdfWP`\x10[_[\x81\x81\x14a\x01\x83W\x82\x81\x01`\x03\x02`\x04\x01\x81`L\x02\x81T``\x1b\x81R`\x14\x01\x81`\x01\x01T\x81R` \x01\x90`\x02\x01T\x80\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\x16\x82R\x90`\x10\x01\x90`@\x1c\x90\x81`8\x1c\x81`\a\x01S\x81`0\x1c\x81`\x06\x01S\x81`(\x1c\x81`\x05\x01S\x81` \x1c\x81`\x04\x01S\x81`\x18\x1c\x81`\x03\x01S\x81`\x10\x1c\x81`\x02\x01S\x81`\b\x1c\x81`\x01\x01SS`\x01\x01`\xe1V[\x91\x01\x80\x92\x14a\x01\x95W\x90`\x02Ua\x01\xa0V[\x90P_`\x02U_`\x03U[_T\x80\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\x14\x15a\x01\xcdWP_[`\x01T`\x02\x82\x82\x01\x11a\x01\xe2WPP_a\x01\xe8V[\x01`\x02\x90\x03[_U_`\x01U`L\x02_\xf3[__\xfd\xf8D\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\x00\xa0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf9\x01\xff\x92\xbb\xdd\xc7\xceH\x86B\xfbW\x9f\x8b\x00\xf3\xa5\x90\x00rQ\x80\xf9\x01\xe8\x01\xb9\x01\x9e3s\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x14`\xd3W`\x11_T\x80\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\x14a\x01\x9aW`\x01\x82\x02`\x01\x90_[_\x82\x11\x15`hW\x81\x01\x90\x83\x02\x84\x83\x02\x90\x04\x91`\x01\x01\x91\x90`MV[\x90\x93\x90\x04\x92PPP6``\x14`\x88W6a\x01\x9aW4a\x01\x9aW_R` _\xf3[4\x10a\x01\x9aW`\x01T`\x01\x01`\x01U`\x03T\x80`\x04\x02`\x04\x013\x81U`\x01\x01_5\x81U`\x01\x01` 5\x81U`\x01\x01`@5\x90U3``\x1b_R``_`\x147`t_\xa0`\x01\x01`\x03U\x00[`\x03T`\x02T\x80\x82\x03\x80`\x02\x11`\xe7WP`\x02[_[\x81\x81\x14a\x01)W\x82\x81\x01`\x04\x02`\x04\x01\x81`t\x02\x81T``\x1b\x81R`\x14\x01\x81`\x01\x01T\x81R` \x01\x81`\x02\x01T\x81R` \x01\x90`\x03\x01T\x90R`\x01\x01`\xe9V[\x91\x01\x80\x92\x14a\x01;W\x90`\x02Ua\x01FV[\x90P_`\x02U_`\x03U[_T\x80\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\x14\x15a\x01sWP_[`\x01T`\x01\x82\x82\x01\x11a\x01\x88WPP_a\x01\x8eV[\x01`\x01\x90\x03[_U_`\x01U`t\x02_\xf3[__\xfd\xf8D\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\x00\xa0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8m\x92\xf9\b'\xf1\xc5:\x10\xcbz\x023[\x17S \x00)5\x80\xf8W\x01\xb8S3s\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x14`FW` 6\x03`BW_5`\x01C\x03\x81\x11`BWa\x1f\xff\x81C\x03\x11`BWa\x1f\xff\x90\x06T_R` _\xf3[__\xfd[_5a\x1f\xff`\x01C\x03\x06U\x00\xc0\xf8|\x93\x0f=\xf6\xd72\x80~\xf11\x9f\xb7\xb8\xbb\x85\"\u043e\xac\x02\x80\xf8e\x01\xb8a3s\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x14`MW` 6\x14`$W__\xfd[_5\x80\x15`IWb\x00\x1f\xff\x81\x06\x90\x81T\x14`\x8e\u0344h\xa0\x03\x7f\x05\x8a\x9d\xaf\xady\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94@O\xfd\x9d\xd6T(\xe0\x96\u0667\xb87\x92Bc\xef@\xfb1\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94E\u0720to\xc5k@\v)\x1f]\x96W\xa7\x94d\xe8\xf1R\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\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\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\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94Q\x80\xdb\x027)\x1adI\u0769\xed3\xad\x90\xa3\x87\x87b\x1c\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94Rs\x0f4}\xefk\xa0\x9a\xdf\xf6.\xac`\xd5\xfe\xe8 [\u010a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94^\xac\x0f\xbd=\xfe\xf8\xae>\xfa<]\xc1\xaa\x19;\xc6\x03=\xfd\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94_\x10\u069bh\xf0lv\xf3\xc6$\xf8\xb2\xee;*&\x985\x1b\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe1\x94a\bf\xc6\b\x97h\u0695RK\xccL\xe7\xdba\xed\xa3\x93\x1c\x8b\xa5o\xa5\xb9\x90\x19\xa5\xc8\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\xe0\x94v\x7fuv\x94M2\x13t\x92\x1d\xf18X\x9a0\xe3\xc5\x03\r\x8a\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\xe0\x94\x8d\xf7\x87\x8d5q\xbe\xf5\xe5\xa7D\xf9b\x87\xc8\xd2\x03\x86\xd7Z\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\x90)\xc7r\xdd\xe8Gb-\xf1U>\xd9\u067d\xb7\x81.O\x93\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\u251a'\xd0\xc7\x15\xd3\xf2\xaf/\xac9\xa4\x1cI\xed5\x00J;\u03cc\x01\x9d\x97\x1eO\xe8@\x1et\x00\x00\x00\xe0\x94\x9b8?\x8eL\xd5\xd3\xdd_\x90\x06\xb6\xa5\b\x96\n\x1es\x03u\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\x9bI\x1f\x041\x89\xafm1\xd3\u0531\xa7\xca\x1c\xf7/@\xc5*\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\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\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\xe0\x94\u010e#\xc5\xf6\xe1\xea\v\xae\xf6S\a4\xed\u00d6\x8fy\xaf.\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94\xc5d\xaf\x15F!\xee\x8d\x05\x89u\x8dSU\x11\xae\xc8\xf6{@\x8b\bE\x95\x16\x14\x01HJ\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\xe0\x94\u053bU];\r\x7f\xf1|`aa\xb4N7&\x89\xc1OK\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94\xda)\xbbqf\x9fF\xf2\xa7y\xb4\xb6/\x03dJ\x84\xee4y\x8b\bE\x95\x16\x14\x01HJ\x00\x00\x00\xe1\x94\xdb\xf6@\u07a0G\xfa~\xe7F\xd0\x1a1x#\x86\xf8'\xcf\xc1\x8b\bE\x95\x16\x14\x01HJ\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\xe4\x95^\x10~\xa50\xb4\xc2\u06ca2=\xf0\xa1C\u0628+\x9c\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\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\xebt.C\x95n\x0e\xa8\x9a-\xb6\xbfb7\u01de\xe4dY\x81\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\xe1\x94\xfcz\xf4\x9b\x80\xac\xf0AtCf\xb0\"r\x01\x97#\xc9O\x9c\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00" diff --git a/core/genesis_test.go b/core/genesis_test.go index 86e5617ef8..726bda86bb 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -104,6 +104,15 @@ func testSetupGenesis(t *testing.T, scheme string) { }, wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash}, }, + { + name: "custom block in DB, genesis == hoodi", + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { + tdb := triedb.NewDatabase(db, newDbConfig(scheme)) + customg.Commit(db, tdb) + return SetupGenesisBlock(db, tdb, DefaultHoodiGenesisBlock()) + }, + wantErr: &GenesisMismatchError{Stored: customghash, New: params.HoodiGenesisHash}, + }, { name: "compatible config in DB", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { @@ -178,6 +187,8 @@ func TestGenesisHashes(t *testing.T) { }{ {DefaultGenesisBlock(), params.MainnetGenesisHash}, {DefaultSepoliaGenesisBlock(), params.SepoliaGenesisHash}, + {DefaultHoleskyGenesisBlock(), params.HoleskyGenesisHash}, + {DefaultHoodiGenesisBlock(), params.HoodiGenesisHash}, } { // Test via MustCommit db := rawdb.NewMemoryDatabase() diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go index 1bee455503..ea25bf1e2c 100644 --- a/core/rawdb/accessors_indexes_test.go +++ b/core/rawdb/accessors_indexes_test.go @@ -119,6 +119,7 @@ func TestDeleteBloomBits(t *testing.T) { for s := uint64(0); s < 2; s++ { WriteBloomBits(db, i, s, params.MainnetGenesisHash, []byte{0x01, 0x02}) WriteBloomBits(db, i, s, params.SepoliaGenesisHash, []byte{0x01, 0x02}) + WriteBloomBits(db, i, s, params.HoodiGenesisHash, []byte{0x01, 0x02}) } } check := func(bit uint, section uint64, head common.Hash, exist bool) { @@ -133,24 +134,31 @@ func TestDeleteBloomBits(t *testing.T) { // Check the existence of written data. check(0, 0, params.MainnetGenesisHash, true) check(0, 0, params.SepoliaGenesisHash, true) + check(0, 0, params.HoodiGenesisHash, true) // Check the existence of deleted data. DeleteBloombits(db, 0, 0, 1) check(0, 0, params.MainnetGenesisHash, false) check(0, 0, params.SepoliaGenesisHash, false) + check(0, 0, params.HoodiGenesisHash, false) check(0, 1, params.MainnetGenesisHash, true) check(0, 1, params.SepoliaGenesisHash, true) + check(0, 1, params.HoodiGenesisHash, true) // Check the existence of deleted data. DeleteBloombits(db, 0, 0, 2) check(0, 0, params.MainnetGenesisHash, false) check(0, 0, params.SepoliaGenesisHash, false) + check(0, 0, params.HoodiGenesisHash, false) check(0, 1, params.MainnetGenesisHash, false) check(0, 1, params.SepoliaGenesisHash, false) + check(0, 1, params.HoodiGenesisHash, false) // Bit1 shouldn't be affect. check(1, 0, params.MainnetGenesisHash, true) check(1, 0, params.SepoliaGenesisHash, true) + check(1, 0, params.HoodiGenesisHash, true) check(1, 1, params.MainnetGenesisHash, true) check(1, 1, params.SepoliaGenesisHash, true) + check(1, 1, params.HoodiGenesisHash, true) } diff --git a/params/bootnodes.go b/params/bootnodes.go index 124765313a..28e3395540 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -28,6 +28,15 @@ var MainnetBootnodes = []string{ "enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303", // bootnode-hetzner-fsn } +// HoodiBootnodes are the enode URLs of the P2P bootstrap nodes running on the +// Hoodi test network. +var HoodiBootnodes = []string{ + // EF DevOps + "enode://2112dd3839dd752813d4df7f40936f06829fc54c0e051a93967c26e5f5d27d99d886b57b4ffcc3c475e930ec9e79c56ef1dbb7d86ca5ee83a9d2ccf36e5c240c@134.209.138.84:30303", + "enode://60203fcb3524e07c5df60a14ae1c9c5b24023ea5d47463dfae051d2c9f3219f309657537576090ca0ae641f73d419f53d8e8000d7a464319d4784acd7d2abc41@209.38.124.160:30303", + "enode://8ae4a48101b2299597341263da0deb47cc38aa4d3ef4b7430b897d49bfa10eb1ccfe1655679b1ed46928ef177fbf21b86837bd724400196c508427a6f41602cd@134.199.184.23:30303", +} + // HoleskyBootnodes are the enode URLs of the P2P bootstrap nodes running on the // Holesky test network. var HoleskyBootnodes = []string{ @@ -84,6 +93,8 @@ func KnownDNSNetwork(genesis common.Hash, protocol string) string { net = "sepolia" case HoleskyGenesisHash: net = "holesky" + case HoodiGenesisHash: + net = "hoodi" default: return "" } diff --git a/params/config.go b/params/config.go index 593c70b139..8f9e02583b 100644 --- a/params/config.go +++ b/params/config.go @@ -31,6 +31,7 @@ var ( MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") HoleskyGenesisHash = common.HexToHash("0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4") SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") + HoodiGenesisHash = common.HexToHash("0xbbe312868b376a3001692a646dd2d7d1e4406380dfd86b98aa8a34d1557c971b") ) func newUint64(val uint64) *uint64 { return &val } @@ -125,6 +126,36 @@ var ( Prague: DefaultPragueBlobConfig, }, } + // HoodiChainConfig contains the chain parameters to run a node on the Hoodi test network. + HoodiChainConfig = &ChainConfig{ + ChainID: big.NewInt(560048), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + 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: nil, + GrayGlacierBlock: nil, + TerminalTotalDifficulty: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + ShanghaiTime: newUint64(0), + CancunTime: newUint64(0), + PragueTime: newUint64(1742999832), + DepositContractAddress: common.HexToAddress("0x00000000219ab540356cBB839Cbe05303d7705Fa"), + Ethash: new(EthashConfig), + BlobScheduleConfig: &BlobScheduleConfig{ + Cancun: DefaultCancunBlobConfig, + Prague: DefaultPragueBlobConfig, + }, + } // AllEthashProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Ethash consensus. AllEthashProtocolChanges = &ChainConfig{ @@ -338,6 +369,7 @@ var NetworkNames = map[string]string{ MainnetChainConfig.ChainID.String(): "mainnet", SepoliaChainConfig.ChainID.String(): "sepolia", HoleskyChainConfig.ChainID.String(): "holesky", + HoodiChainConfig.ChainID.String(): "hoodi", } // ChainConfig is the core config which determines the blockchain settings. From e5f4b274b39df4e8a44b9bc14294cef8ebb91bd2 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Tue, 18 Mar 2025 12:40:38 +0100 Subject: [PATCH 204/940] internal/ethapi: fix logs bloom in eth_simulateV1 (#31411) Geth was returning empty logsBloom for the simulated block. --- internal/ethapi/simulate.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index ac76372424..097de8b0b0 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -217,9 +217,13 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if err := sim.sanitizeCall(&call, sim.state, header, blockContext, &gasUsed); err != nil { return nil, nil, err } - tx := call.ToTransaction(types.DynamicFeeTxType) + var ( + tx = call.ToTransaction(types.DynamicFeeTxType) + txHash = tx.Hash() + ) txes[i] = tx - tracer.reset(tx.Hash(), uint(i)) + tracer.reset(txHash, uint(i)) + sim.state.SetTxContext(txHash, i) // EoA check is always skipped, even in validation mode. msg := call.ToMessage(header.BaseFee, !sim.validate, true) result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp) From fe640f8f57526e8e0790df18a7f6190adecba08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Tue, 18 Mar 2025 13:46:23 +0100 Subject: [PATCH 205/940] core/filtermaps: fixed indexer checkpoint initialization (#31419) This PR fixes a bug in the `lastMapBoundaryBefore` logic that resulted in incorrect checkpoint initialization (started rendering from the previous epoch boundary which caused the `needTailEpoch` check to fail). Apparently the bug was present before but went unnoticed because `needTailEpoch` behaved differently. Fixes https://github.com/ethereum/go-ethereum/issues/31413 --- core/filtermaps/indexer.go | 3 +++ core/filtermaps/map_renderer.go | 29 ++++++++++++++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index addda03df4..835e84cc0a 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -346,6 +346,9 @@ func (f *FilterMaps) needTailEpoch(epoch uint32) bool { if epoch > firstEpoch { return true } + if (epoch+1)<= f.indexedRange.maps.AfterLast() { + return true + } if epoch+1 < firstEpoch { return false } diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index 4f45a7f2b2..ba2d399e88 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -185,27 +185,30 @@ func (f *FilterMaps) lastCanonicalMapBoundaryBefore(renderBefore uint32) (nextMa // lastMapBoundaryBefore returns the latest map boundary before the specified // map index. -func (f *FilterMaps) lastMapBoundaryBefore(mapIndex uint32) (uint32, bool) { - if !f.indexedRange.initialized || f.indexedRange.maps.AfterLast() == 0 { +func (f *FilterMaps) lastMapBoundaryBefore(renderBefore uint32) (uint32, bool) { + if !f.indexedRange.initialized || f.indexedRange.maps.AfterLast() == 0 || renderBefore == 0 { return 0, false } - if mapIndex > f.indexedRange.maps.AfterLast() { - mapIndex = f.indexedRange.maps.AfterLast() + afterLastFullMap := f.indexedRange.maps.AfterLast() + if afterLastFullMap > 0 && f.indexedRange.headIndexed { + afterLastFullMap-- // last map is not full } - if mapIndex > f.indexedRange.maps.First() { - return mapIndex - 1, true + firstRendered := min(renderBefore-1, afterLastFullMap) + if firstRendered == 0 { + return 0, false } - if mapIndex+f.mapsPerEpoch > f.indexedRange.maps.First() { - if mapIndex > f.indexedRange.maps.First()-f.mapsPerEpoch+f.indexedRange.tailPartialEpoch { - mapIndex = f.indexedRange.maps.First() - f.mapsPerEpoch + f.indexedRange.tailPartialEpoch - } + if firstRendered >= f.indexedRange.maps.First() { + return firstRendered - 1, true + } + if firstRendered+f.mapsPerEpoch > f.indexedRange.maps.First() { + firstRendered = min(firstRendered, f.indexedRange.maps.First()-f.mapsPerEpoch+f.indexedRange.tailPartialEpoch) } else { - mapIndex = (mapIndex >> f.logMapsPerEpoch) << f.logMapsPerEpoch + firstRendered = (firstRendered >> f.logMapsPerEpoch) << f.logMapsPerEpoch } - if mapIndex == 0 { + if firstRendered == 0 { return 0, false } - return mapIndex - 1, true + return firstRendered - 1, true } // emptyFilterMap returns an empty filter map. From dba58830e98dccc381fcc2feb9eba259789cdf5c Mon Sep 17 00:00:00 2001 From: Delweng Date: Tue, 18 Mar 2025 21:32:29 +0800 Subject: [PATCH 206/940] cmd: set name to chaindata for all the opened db (#31352) When I'm running `geth import --metrics`, the metrics is different to normal `geth --metrics`, so the grafana dashboard needs to be updated, eg: `eth_db_chaindata_disk_read` vs `disk_read`. So I think we should always set the name to `eth/db/chaindata` for more convenient. --------- Signed-off-by: jsvisa --- cmd/utils/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d60f9c64d5..77dac8bd1a 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2076,7 +2076,7 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb. } chainDb = remotedb.New(client) default: - chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "", readonly) + chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "eth/db/chaindata/", readonly) } if err != nil { Fatalf("Could not open database: %v", err) From c4f045071031ed19534915a7ff5792354669b3db Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Tue, 18 Mar 2025 09:41:34 -0500 Subject: [PATCH 207/940] ethclient: Add EstimateGasAtBlock[Hash] to estimate against a specific block (#27508) The main use case I see of this is that it allows users to estimate gas against the same state that they query for their nonce, and the same state they base the data of their transaction against. This helps ensure that gas estimation won't fail and the transaction won't revert on-chain because of a mismatch between the state used for gas estimation and the state used to generate the inputs to gas estimation or the transaction's nonce when submitted to the mempool. This PR also updates the EstimateGas comment based on the new geth `eth_estimateGas` default of using latest state as of v1.12.0: https://github.com/ethereum/go-ethereum/pull/24363 --------- Co-authored-by: Felix Lange --- ethclient/ethclient.go | 32 +++++++++++++++++++++++++++++--- ethclient/ethclient_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 3d6a28eabf..872b3b03dc 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -640,9 +640,13 @@ func (ec *Client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock * } // EstimateGas tries to estimate the gas needed to execute a specific transaction based on -// the current pending state of the backend blockchain. There is no guarantee that this is -// the true gas limit requirement as other transactions may be added or removed by miners, -// but it should provide a basis for setting a reasonable default. +// the current state of the backend blockchain. There is no guarantee that this is the +// true gas limit requirement as other transactions may be added or removed by miners, but +// it should provide a basis for setting a reasonable default. +// +// Note that the state used by this method is implementation-defined by the remote RPC +// server, but it's reasonable to assume that it will either be the pending or latest +// state. func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) { var hex hexutil.Uint64 err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg)) @@ -652,6 +656,28 @@ func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64 return uint64(hex), nil } +// EstimateGasAtBlock is almost the same as EstimateGas except that it selects the block height +// instead of using the remote RPC's default state for gas estimation. +func (ec *Client) EstimateGasAtBlock(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) (uint64, error) { + var hex hexutil.Uint64 + err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg), toBlockNumArg(blockNumber)) + if err != nil { + return 0, err + } + return uint64(hex), nil +} + +// EstimateGasAtBlockHash is almost the same as EstimateGas except that it selects the block +// hash instead of using the remote RPC's default state for gas estimation. +func (ec *Client) EstimateGasAtBlockHash(ctx context.Context, msg ethereum.CallMsg, blockHash common.Hash) (uint64, error) { + var hex hexutil.Uint64 + err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg), rpc.BlockNumberOrHashWithHash(blockHash, false)) + if err != nil { + return 0, err + } + return uint64(hex), nil +} + // SendTransaction injects a signed transaction into the pending pool for execution. // // If the transaction was a contract creation use the TransactionReceipt method to get the diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 787cad3f96..29e311c1b4 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -592,6 +592,33 @@ func testAtFunctions(t *testing.T, client *rpc.Client) { if !bytes.Equal(code, penCode) { t.Fatalf("unexpected code: %v %v", code, penCode) } + // Use HeaderByNumber to get a header for EstimateGasAtBlock and EstimateGasAtBlockHash + latestHeader, err := ec.HeaderByNumber(context.Background(), nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + // EstimateGasAtBlock + msg := ethereum.CallMsg{ + From: testAddr, + To: &common.Address{}, + Gas: 21000, + Value: big.NewInt(1), + } + gas, err := ec.EstimateGasAtBlock(context.Background(), msg, latestHeader.Number) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if gas != 21000 { + t.Fatalf("unexpected gas limit: %v", gas) + } + // EstimateGasAtBlockHash + gas, err = ec.EstimateGasAtBlockHash(context.Background(), msg, latestHeader.Hash()) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if gas != 21000 { + t.Fatalf("unexpected gas limit: %v", gas) + } } func testTransactionSender(t *testing.T, client *rpc.Client) { From 930836ed66c9ff8eaffc8cd168cd9c76fad82c29 Mon Sep 17 00:00:00 2001 From: minh-bq Date: Wed, 19 Mar 2025 13:20:50 +0700 Subject: [PATCH 208/940] core/txpool, eth: add GetRLP to transaction pool (#31307) Currently, when answering GetPooledTransaction request, txpool.Get() is used. When the requested hash is blob transaction, blobpool.Get() is called. This function loads the RLP-encoded transaction from limbo then decodes and returns. Later, in answerGetPooledTransactions, we need to RLP encode again. This decode then encode is wasteful. This commit adds GetRLP to transaction pool interface so that answerGetPooledTransactions can use the RLP-encoded from limbo directly. --------- Co-authored-by: Gary Rong --- core/txpool/blobpool/blobpool.go | 24 +++++- core/txpool/legacypool/legacypool.go | 15 ++++ core/txpool/subpool.go | 3 + core/txpool/txpool.go | 11 +++ eth/handler.go | 4 + eth/handler_test.go | 15 ++++ eth/protocols/eth/handler.go | 4 + eth/protocols/eth/handler_test.go | 116 ++++++++++++++++++++++++--- eth/protocols/eth/handlers.go | 15 ++-- 9 files changed, 184 insertions(+), 23 deletions(-) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 7ad95612bf..59a5645040 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1189,8 +1189,7 @@ func (p *BlobPool) Has(hash common.Hash) bool { return p.lookup.exists(hash) } -// Get returns a transaction if it is contained in the pool, or nil otherwise. -func (p *BlobPool) Get(hash common.Hash) *types.Transaction { +func (p *BlobPool) getRLP(hash common.Hash) []byte { // Track the amount of time waiting to retrieve a fully resolved blob tx from // the pool and the amount of time actually spent on pulling the data from disk. getStart := time.Now() @@ -1212,14 +1211,31 @@ func (p *BlobPool) Get(hash common.Hash) *types.Transaction { log.Error("Tracked blob transaction missing from store", "hash", hash, "id", id, "err", err) return nil } + return data +} + +// Get returns a transaction if it is contained in the pool, or nil otherwise. +func (p *BlobPool) Get(hash common.Hash) *types.Transaction { + data := p.getRLP(hash) + if len(data) == 0 { + return nil + } item := new(types.Transaction) - if err = rlp.DecodeBytes(data, item); err != nil { - log.Error("Blobs corrupted for traced transaction", "hash", hash, "id", id, "err", err) + if err := rlp.DecodeBytes(data, item); err != nil { + id, _ := p.lookup.storeidOfTx(hash) + + log.Error("Blobs corrupted for traced transaction", + "hash", hash, "id", id, "err", err) return nil } return item } +// GetRLP returns a RLP-encoded transaction if it is contained in the pool. +func (p *BlobPool) GetRLP(hash common.Hash) []byte { + return p.getRLP(hash) +} + // GetBlobs returns a number of blobs are proofs for the given versioned hashes. // This is a utility method for the engine API, enabling consensus clients to // retrieve blobs from the pools directly instead of the network. diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 8c09d48695..78be81480f 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -40,6 +40,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/uint256" ) @@ -1010,6 +1011,20 @@ func (pool *LegacyPool) get(hash common.Hash) *types.Transaction { return pool.all.Get(hash) } +// GetRLP returns a RLP-encoded transaction if it is contained in the pool. +func (pool *LegacyPool) GetRLP(hash common.Hash) []byte { + tx := pool.all.Get(hash) + if tx == nil { + return nil + } + encoded, err := rlp.EncodeToBytes(tx) + if err != nil { + log.Error("Failed to encoded transaction in legacy pool", "hash", hash, "err", err) + return nil + } + return encoded +} + // GetBlobs is not supported by the legacy transaction pool, it is just here to // implement the txpool.SubPool interface. func (pool *LegacyPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) { diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 242af02136..1392cfb274 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -124,6 +124,9 @@ type SubPool interface { // Get returns a transaction if it is contained in the pool, or nil otherwise. Get(hash common.Hash) *types.Transaction + // GetRLP returns a RLP-encoded transaction if it is contained in the pool. + GetRLP(hash common.Hash) []byte + // GetBlobs returns a number of blobs are proofs for the given versioned hashes. // This is a utility method for the engine API, enabling consensus clients to // retrieve blobs from the pools directly instead of the network. diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 55812415f9..042e3d36d9 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -309,6 +309,17 @@ func (p *TxPool) Get(hash common.Hash) *types.Transaction { return nil } +// GetRLP returns a RLP-encoded transaction if it is contained in the pool. +func (p *TxPool) GetRLP(hash common.Hash) []byte { + for _, subpool := range p.subpools { + encoded := subpool.GetRLP(hash) + if len(encoded) != 0 { + return encoded + } + } + return nil +} + // GetBlobs returns a number of blobs are proofs for the given versioned hashes. // This is a utility method for the engine API, enabling consensus clients to // retrieve blobs from the pools directly instead of the network. diff --git a/eth/handler.go b/eth/handler.go index 6ac890902b..4c83f5613c 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -67,6 +67,10 @@ type txPool interface { // tx hash. Get(hash common.Hash) *types.Transaction + // GetRLP retrieves the RLP-encoded transaction from local txpool + // with given tx hash. + GetRLP(hash common.Hash) []byte + // Add should add the given transactions to the pool. Add(txs []*types.Transaction, sync bool) []error diff --git a/eth/handler_test.go b/eth/handler_test.go index d5d46a3c65..0c6b9854e6 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/uint256" ) @@ -78,6 +79,20 @@ func (p *testTxPool) Get(hash common.Hash) *types.Transaction { return p.pool[hash] } +// Get retrieves the transaction from local txpool with given +// tx hash. +func (p *testTxPool) GetRLP(hash common.Hash) []byte { + p.lock.Lock() + defer p.lock.Unlock() + + tx := p.pool[hash] + if tx != nil { + blob, _ := rlp.EncodeToBytes(tx) + return blob + } + return nil +} + // Add appends a batch of transactions to the pool, and notifies any // listeners if the addition channel is non nil func (p *testTxPool) Add(txs []*types.Transaction, sync bool) []error { diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index a0848137fa..eca6777bd6 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -86,6 +86,10 @@ type Backend interface { type TxPool interface { // Get retrieves the transaction from the local txpool with the given hash. Get(hash common.Hash) *types.Transaction + + // GetRLP retrieves the RLP-encoded transaction from the local txpool with + // the given hash. + GetRLP(hash common.Hash) []byte } // MakeProtocols constructs the P2P protocol definitions for `eth`. diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index f92599dba7..36f5e90c9a 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -18,9 +18,11 @@ package eth import ( "bytes" + "crypto/sha256" "math" "math/big" "math/rand" + "os" "testing" "time" @@ -30,15 +32,18 @@ import ( "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/blobpool" "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/crypto/kzg4844" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "github.com/holiman/uint256" ) var ( @@ -62,12 +67,12 @@ type testBackend struct { // newTestBackend creates an empty chain and wraps it into a mock backend. func newTestBackend(blocks int) *testBackend { - return newTestBackendWithGenerator(blocks, false, nil) + return newTestBackendWithGenerator(blocks, false, false, nil) } // 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 { +func newTestBackendWithGenerator(blocks int, shanghai bool, cancun bool, generator func(int, *core.BlockGen)) *testBackend { var ( // Create a database pre-initialize with a genesis block db = rawdb.NewMemoryDatabase() @@ -99,9 +104,21 @@ func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int, } } + if cancun { + config.CancunTime = u64(0) + config.BlobScheduleConfig = ¶ms.BlobScheduleConfig{ + Cancun: ¶ms.BlobConfig{ + Target: 3, + Max: 6, + UpdateFraction: params.DefaultCancunBlobConfig.UpdateFraction, + }, + } + } + gspec := &core.Genesis{ - Config: config, - Alloc: types.GenesisAlloc{testAddr: {Balance: big.NewInt(100_000_000_000_000_000)}}, + Config: config, + Alloc: types.GenesisAlloc{testAddr: {Balance: big.NewInt(100_000_000_000_000_000)}}, + Difficulty: common.Big0, } chain, _ := core.NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil) @@ -115,8 +132,12 @@ func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int, txconfig := legacypool.DefaultConfig txconfig.Journal = "" // Don't litter the disk with test journals - pool := legacypool.New(txconfig, chain) - txpool, _ := txpool.New(txconfig.PriceLimit, chain, []txpool.SubPool{pool}) + storage, _ := os.MkdirTemp("", "blobpool-") + defer os.RemoveAll(storage) + + blobPool := blobpool.New(blobpool.Config{Datadir: storage}, chain) + legacyPool := legacypool.New(txconfig, chain) + txpool, _ := txpool.New(txconfig.PriceLimit, chain, []txpool.SubPool{legacyPool, blobPool}) return &testBackend{ db: db, @@ -351,7 +372,7 @@ func testGetBlockBodies(t *testing.T, protocol uint) { } } - backend := newTestBackendWithGenerator(maxBodiesServe+15, true, gen) + backend := newTestBackendWithGenerator(maxBodiesServe+15, true, false, gen) defer backend.close() peer, _ := newTestPeer("peer", protocol, backend) @@ -471,7 +492,7 @@ func testGetBlockReceipts(t *testing.T, protocol uint) { } } // Assemble the test environment - backend := newTestBackendWithGenerator(4, false, generator) + backend := newTestBackendWithGenerator(4, false, false, generator) defer backend.close() peer, _ := newTestPeer("peer", protocol, backend) @@ -548,7 +569,7 @@ func setup() (*testBackend, *testPeer) { block.SetExtra([]byte("yeehaw")) } } - backend := newTestBackendWithGenerator(maxBodiesServe+15, true, gen) + backend := newTestBackendWithGenerator(maxBodiesServe+15, true, false, gen) peer, _ := newTestPeer("peer", ETH68, backend) // Discard all messages go func() { @@ -573,3 +594,80 @@ func FuzzEthProtocolHandlers(f *testing.F) { handler(backend, decoder{msg: msg}, peer.Peer) }) } + +func TestGetPooledTransaction(t *testing.T) { + t.Run("blobTx", func(t *testing.T) { + testGetPooledTransaction(t, true) + }) + t.Run("legacyTx", func(t *testing.T) { + testGetPooledTransaction(t, false) + }) +} + +func testGetPooledTransaction(t *testing.T, blobTx bool) { + var ( + emptyBlob = kzg4844.Blob{} + emptyBlobs = []kzg4844.Blob{emptyBlob} + emptyBlobCommit, _ = kzg4844.BlobToCommitment(&emptyBlob) + emptyBlobProof, _ = kzg4844.ComputeBlobProof(&emptyBlob, emptyBlobCommit) + emptyBlobHash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit) + ) + backend := newTestBackendWithGenerator(0, true, true, nil) + defer backend.close() + + peer, _ := newTestPeer("peer", ETH68, backend) + defer peer.close() + + var ( + tx *types.Transaction + err error + signer = types.NewCancunSigner(params.TestChainConfig.ChainID) + ) + if blobTx { + tx, err = types.SignNewTx(testKey, signer, &types.BlobTx{ + ChainID: uint256.MustFromBig(params.TestChainConfig.ChainID), + Nonce: 0, + GasTipCap: uint256.NewInt(20_000_000_000), + GasFeeCap: uint256.NewInt(21_000_000_000), + Gas: 21000, + To: testAddr, + BlobHashes: []common.Hash{emptyBlobHash}, + BlobFeeCap: uint256.MustFromBig(common.Big1), + Sidecar: &types.BlobTxSidecar{ + Blobs: emptyBlobs, + Commitments: []kzg4844.Commitment{emptyBlobCommit}, + Proofs: []kzg4844.Proof{emptyBlobProof}, + }, + }) + if err != nil { + t.Fatal(err) + } + } else { + tx, err = types.SignTx( + types.NewTransaction(0, testAddr, big.NewInt(10_000), params.TxGas, big.NewInt(1_000_000_000), nil), + signer, + testKey, + ) + if err != nil { + t.Fatal(err) + } + } + errs := backend.txpool.Add([]*types.Transaction{tx}, true) + for _, err := range errs { + if err != nil { + t.Fatal(err) + } + } + + // Send the hash request and verify the response + p2p.Send(peer.app, GetPooledTransactionsMsg, GetPooledTransactionsPacket{ + RequestId: 123, + GetPooledTransactionsRequest: []common.Hash{tx.Hash()}, + }) + if err := p2p.ExpectMsg(peer.app, PooledTransactionsMsg, PooledTransactionsPacket{ + RequestId: 123, + PooledTransactionsResponse: []*types.Transaction{tx}, + }); err != nil { + t.Errorf("pooled transaction mismatch: %v", err) + } +} diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go index b3886270f3..ab56be7ffc 100644 --- a/eth/protocols/eth/handlers.go +++ b/eth/protocols/eth/handlers.go @@ -397,18 +397,13 @@ func answerGetPooledTransactions(backend Backend, query GetPooledTransactionsReq break } // Retrieve the requested transaction, skipping if unknown to us - tx := backend.TxPool().Get(hash) - if tx == nil { + encoded := backend.TxPool().GetRLP(hash) + if len(encoded) == 0 { continue } - // If known, encode and queue for response packet - if encoded, err := rlp.EncodeToBytes(tx); err != nil { - log.Error("Failed to encode transaction", "err", err) - } else { - hashes = append(hashes, hash) - txs = append(txs, encoded) - bytes += len(encoded) - } + hashes = append(hashes, hash) + txs = append(txs, encoded) + bytes += len(encoded) } return hashes, txs } From b47e4d5b38b34c045cb10af6c0b5603c285310cd Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 19 Mar 2025 07:21:40 +0100 Subject: [PATCH 209/940] core/types: reduce allocs in transaction signing (#31258) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR roughly halves the number of allocations needed to compute the sigHash for a transaction. This sigHash is used whenever we recover a signature of a transaction, so quite often. During a recent benchmark full syncing on Holesky, roughly 2.8% of all allocations were happening here because the fields from the transaction would be copied multiple times. ``` 66168733 153175654 (flat, cum) 2.80% of Total . . 368:func (s londonSigner) Hash(tx *Transaction) common.Hash { . . 369: if tx.Type() != DynamicFeeTxType { . . 370: return s.eip2930Signer.Hash(tx) . . 371: } . 19169966 372: return prefixedRlpHash( . . 373: tx.Type(), 26442187 26442187 374: []interface{}{ . . 375: s.chainId, 6848616 6848616 376: tx.Nonce(), . 19694077 377: tx.GasTipCap(), . 18956774 378: tx.GasFeeCap(), 6357089 6357089 379: tx.Gas(), . 12321050 380: tx.To(), . 16865054 381: tx.Value(), 13435187 13435187 382: tx.Data(), 13085654 13085654 383: tx.AccessList(), . . 384: }) . . 385:} ``` This PR reduces the allocations and speeds up the computation of the sigHash by ~22%, which is quite significantly given that this operation involves a call to Keccak ``` // BenchmarkHash-8 440082 2639 ns/op 384 B/op 13 allocs/op // BenchmarkHash-8 493566 2033 ns/op 240 B/op 6 allocs/op ``` ``` Hash-8 2.691µ ± 8% 2.097µ ± 9% -22.07% (p=0.000 n=10) ``` It also kinda cleans up stuff in my opinion, since the transaction should itself know best how to compute the sighash ![Screenshot_2025-02-25_13-52-41](https://github.com/user-attachments/assets/e2b268aa-e137-417d-926b-f3619daef748) --------- Co-authored-by: Gary Rong --- core/types/transaction.go | 3 ++ core/types/transaction_signing.go | 70 +++---------------------------- core/types/transaction_test.go | 17 ++++++++ core/types/tx_access_list.go | 15 +++++++ core/types/tx_blob.go | 18 ++++++++ core/types/tx_dynamic_fee.go | 16 +++++++ core/types/tx_legacy.go | 13 ++++++ core/types/tx_setcode.go | 17 ++++++++ 8 files changed, 105 insertions(+), 64 deletions(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index 4e48248b4a..a2f4104635 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -100,6 +100,9 @@ type TxData interface { encode(*bytes.Buffer) error decode([]byte) error + + // sigHash returns the hash of the transaction that is ought to be signed + sigHash(*big.Int) common.Hash } // EncodeRLP implements rlp.Encoder diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 030fc472a0..89c08aeddd 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -233,20 +233,7 @@ func (s pragueSigner) Hash(tx *Transaction) common.Hash { if tx.Type() != SetCodeTxType { return s.cancunSigner.Hash(tx) } - return prefixedRlpHash( - tx.Type(), - []interface{}{ - s.chainId, - tx.Nonce(), - tx.GasTipCap(), - tx.GasFeeCap(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - tx.AccessList(), - tx.SetCodeAuthorizations(), - }) + return tx.inner.sigHash(s.chainId) } type cancunSigner struct{ londonSigner } @@ -301,21 +288,7 @@ func (s cancunSigner) Hash(tx *Transaction) common.Hash { if tx.Type() != BlobTxType { return s.londonSigner.Hash(tx) } - return prefixedRlpHash( - tx.Type(), - []interface{}{ - s.chainId, - tx.Nonce(), - tx.GasTipCap(), - tx.GasFeeCap(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - tx.AccessList(), - tx.BlobGasFeeCap(), - tx.BlobHashes(), - }) + return tx.inner.sigHash(s.chainId) } type londonSigner struct{ eip2930Signer } @@ -369,19 +342,7 @@ func (s londonSigner) Hash(tx *Transaction) common.Hash { if tx.Type() != DynamicFeeTxType { return s.eip2930Signer.Hash(tx) } - return prefixedRlpHash( - tx.Type(), - []interface{}{ - s.chainId, - tx.Nonce(), - tx.GasTipCap(), - tx.GasFeeCap(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - tx.AccessList(), - }) + return tx.inner.sigHash(s.chainId) } type eip2930Signer struct{ EIP155Signer } @@ -444,18 +405,7 @@ func (s eip2930Signer) Hash(tx *Transaction) common.Hash { case LegacyTxType: return s.EIP155Signer.Hash(tx) case AccessListTxType: - return prefixedRlpHash( - tx.Type(), - []interface{}{ - s.chainId, - tx.Nonce(), - tx.GasPrice(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - tx.AccessList(), - }) + return tx.inner.sigHash(s.chainId) default: // This _should_ not happen, but in case someone sends in a bad // json struct via RPC, it's probably more prudent to return an @@ -525,15 +475,7 @@ func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big // Hash returns the hash to be signed by the sender. // It does not uniquely identify the transaction. func (s EIP155Signer) Hash(tx *Transaction) common.Hash { - return rlpHash([]interface{}{ - tx.Nonce(), - tx.GasPrice(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - s.chainId, uint(0), uint(0), - }) + return tx.inner.sigHash(s.chainId) } // HomesteadSigner implements Signer interface using the @@ -597,7 +539,7 @@ func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v * // Hash returns the hash to be signed by the sender. // It does not uniquely identify the transaction. func (fs FrontierSigner) Hash(tx *Transaction) common.Hash { - return rlpHash([]interface{}{ + return rlpHash([]any{ tx.Nonce(), tx.GasPrice(), tx.Gas(), diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 17a7dda357..8922448d97 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -576,3 +576,20 @@ func TestYParityJSONUnmarshalling(t *testing.T) { } } } + +func BenchmarkHash(b *testing.B) { + signer := NewLondonSigner(big.NewInt(1)) + to := common.Address{} + tx := NewTx(&DynamicFeeTx{ + ChainID: big.NewInt(123), + Nonce: 1, + Gas: 1000000, + To: &to, + Value: big.NewInt(1), + GasTipCap: big.NewInt(500), + GasFeeCap: big.NewInt(500), + }) + for i := 0; i < b.N; i++ { + signer.Hash(tx) + } +} diff --git a/core/types/tx_access_list.go b/core/types/tx_access_list.go index 730a77b752..915de9a8ab 100644 --- a/core/types/tx_access_list.go +++ b/core/types/tx_access_list.go @@ -127,3 +127,18 @@ func (tx *AccessListTx) encode(b *bytes.Buffer) error { func (tx *AccessListTx) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } + +func (tx *AccessListTx) sigHash(chainID *big.Int) common.Hash { + return prefixedRlpHash( + AccessListTxType, + []any{ + chainID, + tx.Nonce, + tx.GasPrice, + tx.Gas, + tx.To, + tx.Value, + tx.Data, + tx.AccessList, + }) +} diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go index 32401db101..9b1d53958f 100644 --- a/core/types/tx_blob.go +++ b/core/types/tx_blob.go @@ -259,3 +259,21 @@ func (tx *BlobTx) decode(input []byte) error { } return nil } + +func (tx *BlobTx) sigHash(chainID *big.Int) common.Hash { + return prefixedRlpHash( + BlobTxType, + []any{ + chainID, + tx.Nonce, + tx.GasTipCap, + tx.GasFeeCap, + tx.Gas, + tx.To, + tx.Value, + tx.Data, + tx.AccessList, + tx.BlobFeeCap, + tx.BlobHashes, + }) +} diff --git a/core/types/tx_dynamic_fee.go b/core/types/tx_dynamic_fee.go index 981755cf70..bba81464f8 100644 --- a/core/types/tx_dynamic_fee.go +++ b/core/types/tx_dynamic_fee.go @@ -123,3 +123,19 @@ func (tx *DynamicFeeTx) encode(b *bytes.Buffer) error { func (tx *DynamicFeeTx) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } + +func (tx *DynamicFeeTx) sigHash(chainID *big.Int) common.Hash { + return prefixedRlpHash( + DynamicFeeTxType, + []any{ + chainID, + tx.Nonce, + tx.GasTipCap, + tx.GasFeeCap, + tx.Gas, + tx.To, + tx.Value, + tx.Data, + tx.AccessList, + }) +} diff --git a/core/types/tx_legacy.go b/core/types/tx_legacy.go index 71025b78fc..49f0a98809 100644 --- a/core/types/tx_legacy.go +++ b/core/types/tx_legacy.go @@ -123,3 +123,16 @@ func (tx *LegacyTx) encode(*bytes.Buffer) error { func (tx *LegacyTx) decode([]byte) error { panic("decode called on LegacyTx)") } + +// OBS: This is the post-EIP155 hash, the pre-EIP155 does not contain a chainID. +func (tx *LegacyTx) sigHash(chainID *big.Int) common.Hash { + return rlpHash([]any{ + tx.Nonce, + tx.GasPrice, + tx.Gas, + tx.To, + tx.Value, + tx.Data, + chainID, uint(0), uint(0), + }) +} diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index 894bac10a3..b8e38ef1f7 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -223,3 +223,20 @@ func (tx *SetCodeTx) encode(b *bytes.Buffer) error { func (tx *SetCodeTx) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } + +func (tx *SetCodeTx) sigHash(chainID *big.Int) common.Hash { + return prefixedRlpHash( + SetCodeTxType, + []any{ + chainID, + tx.Nonce, + tx.GasTipCap, + tx.GasFeeCap, + tx.Gas, + tx.To, + tx.Value, + tx.Data, + tx.AccessList, + tx.AuthList, + }) +} From 80b8d7a13c20254a9cfb9f7cbca1ab00aa6a3b50 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 19 Mar 2025 16:05:44 +0100 Subject: [PATCH 210/940] core/types: cleanup tx signer logic (#31434) This removes the signer type-train in favor of defining a single object that can handle all tx types. Supported types are enabled via a map. Notably, the new signer also supports disabling legacy transactions. --- cmd/evm/internal/t8ntool/tx_iterator.go | 2 +- core/types/transaction_signing.go | 315 ++++++++---------------- params/forks/forks.go | 4 +- 3 files changed, 110 insertions(+), 211 deletions(-) diff --git a/cmd/evm/internal/t8ntool/tx_iterator.go b/cmd/evm/internal/t8ntool/tx_iterator.go index d4ebb4b399..047626c56b 100644 --- a/cmd/evm/internal/t8ntool/tx_iterator.go +++ b/cmd/evm/internal/t8ntool/tx_iterator.go @@ -102,7 +102,7 @@ func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Tran if tx.protected { signed, err = types.SignTx(tx.tx, signer, tx.key) } else { - signed, err = types.SignTx(tx.tx, types.FrontierSigner{}, tx.key) + signed, err = types.SignTx(tx.tx, types.HomesteadSigner{}, tx.key) } if err != nil { return nil, NewError(ErrorJson, fmt.Errorf("tx %d: failed to sign tx: %v", i, err)) diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 89c08aeddd..01aa67c6ba 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -20,11 +20,13 @@ import ( "crypto/ecdsa" "errors" "fmt" + "maps" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/params/forks" ) var ErrInvalidChainId = errors.New("invalid chain id for signer") @@ -178,7 +180,101 @@ type Signer interface { Equal(Signer) bool } -type pragueSigner struct{ cancunSigner } +// modernSigner is the signer implementation that handles non-legacy transaction types. +// For legacy transactions, it defers to one of the legacy signers (frontier, homestead, eip155). +type modernSigner struct { + txtypes map[byte]struct{} + chainID *big.Int + legacy Signer +} + +func newModernSigner(chainID *big.Int, fork forks.Fork) Signer { + if chainID == nil || chainID.Sign() <= 0 { + panic(fmt.Sprintf("invalid chainID %v", chainID)) + } + s := &modernSigner{ + chainID: chainID, + txtypes: make(map[byte]struct{}, 4), + } + // configure legacy signer + switch { + case fork >= forks.SpuriousDragon: + s.legacy = NewEIP155Signer(chainID) + case fork >= forks.Homestead: + s.legacy = HomesteadSigner{} + default: + s.legacy = FrontierSigner{} + } + s.txtypes[LegacyTxType] = struct{}{} + // configure tx types + if fork >= forks.Berlin { + s.txtypes[AccessListTxType] = struct{}{} + } + if fork >= forks.London { + s.txtypes[DynamicFeeTxType] = struct{}{} + } + if fork >= forks.Cancun { + s.txtypes[BlobTxType] = struct{}{} + } + if fork >= forks.Prague { + s.txtypes[SetCodeTxType] = struct{}{} + } + return s +} + +func (s *modernSigner) ChainID() *big.Int { + return s.chainID +} + +func (s *modernSigner) Equal(s2 Signer) bool { + other, ok := s2.(*modernSigner) + return ok && s.chainID.Cmp(other.chainID) == 0 && maps.Equal(s.txtypes, other.txtypes) && s.legacy.Equal(other.legacy) +} + +func (s *modernSigner) Hash(tx *Transaction) common.Hash { + return tx.inner.sigHash(s.chainID) +} + +func (s *modernSigner) supportsType(txtype byte) bool { + _, ok := s.txtypes[txtype] + return ok +} + +func (s *modernSigner) Sender(tx *Transaction) (common.Address, error) { + tt := tx.Type() + if !s.supportsType(tt) { + return common.Address{}, ErrTxTypeNotSupported + } + if tt == LegacyTxType { + return s.legacy.Sender(tx) + } + if tx.ChainId().Cmp(s.chainID) != 0 { + return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainID) + } + // 'modern' txs are defined to use 0 and 1 as their recovery + // id, add 27 to become equivalent to unprotected Homestead signatures. + V, R, S := tx.RawSignatureValues() + V = new(big.Int).Add(V, big.NewInt(27)) + return recoverPlain(s.Hash(tx), R, S, V, true) +} + +func (s *modernSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { + tt := tx.Type() + if !s.supportsType(tt) { + return nil, nil, nil, ErrTxTypeNotSupported + } + if tt == LegacyTxType { + return s.legacy.SignatureValues(tx, sig) + } + // Check that chain ID of tx matches the signer. We also accept ID zero here, + // because it indicates that the chain ID was not specified in the tx. + if tx.inner.chainID().Sign() != 0 && tx.inner.chainID().Cmp(s.chainID) != 0 { + return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.inner.chainID(), s.chainID) + } + R, S, _ = decodeSignature(sig) + V = big.NewInt(int64(sig[64])) + return R, S, V, nil +} // NewPragueSigner returns a signer that accepts // - EIP-7702 set code transactions @@ -188,56 +284,9 @@ type pragueSigner struct{ cancunSigner } // - EIP-155 replay protected transactions, and // - legacy Homestead transactions. func NewPragueSigner(chainId *big.Int) Signer { - signer, _ := NewCancunSigner(chainId).(cancunSigner) - return pragueSigner{signer} + return newModernSigner(chainId, forks.Prague) } -func (s pragueSigner) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != SetCodeTxType { - return s.cancunSigner.Sender(tx) - } - V, R, S := tx.RawSignatureValues() - - // Set code txs are defined to use 0 and 1 as their recovery - // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) - } - return recoverPlain(s.Hash(tx), R, S, V, true) -} - -func (s pragueSigner) Equal(s2 Signer) bool { - x, ok := s2.(pragueSigner) - return ok && x.chainId.Cmp(s.chainId) == 0 -} - -func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - txdata, ok := tx.inner.(*SetCodeTx) - if !ok { - return s.cancunSigner.SignatureValues(tx, sig) - } - // Check that chain ID of tx matches the signer. We also accept ID zero here, - // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID.Sign() != 0 && txdata.ChainID.CmpBig(s.chainId) != 0 { - return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) - } - R, S, _ = decodeSignature(sig) - V = big.NewInt(int64(sig[64])) - return R, S, V, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s pragueSigner) Hash(tx *Transaction) common.Hash { - if tx.Type() != SetCodeTxType { - return s.cancunSigner.Hash(tx) - } - return tx.inner.sigHash(s.chainId) -} - -type cancunSigner struct{ londonSigner } - // NewCancunSigner returns a signer that accepts // - EIP-4844 blob transactions // - EIP-1559 dynamic fee transactions @@ -245,178 +294,27 @@ type cancunSigner struct{ londonSigner } // - EIP-155 replay protected transactions, and // - legacy Homestead transactions. func NewCancunSigner(chainId *big.Int) Signer { - return cancunSigner{londonSigner{eip2930Signer{NewEIP155Signer(chainId)}}} + return newModernSigner(chainId, forks.Cancun) } -func (s cancunSigner) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != BlobTxType { - return s.londonSigner.Sender(tx) - } - V, R, S := tx.RawSignatureValues() - // Blob txs are defined to use 0 and 1 as their recovery - // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) - } - return recoverPlain(s.Hash(tx), R, S, V, true) -} - -func (s cancunSigner) Equal(s2 Signer) bool { - x, ok := s2.(cancunSigner) - return ok && x.chainId.Cmp(s.chainId) == 0 -} - -func (s cancunSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - txdata, ok := tx.inner.(*BlobTx) - if !ok { - return s.londonSigner.SignatureValues(tx, sig) - } - // Check that chain ID of tx matches the signer. We also accept ID zero here, - // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID.Sign() != 0 && txdata.ChainID.CmpBig(s.chainId) != 0 { - return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) - } - R, S, _ = decodeSignature(sig) - V = big.NewInt(int64(sig[64])) - return R, S, V, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s cancunSigner) Hash(tx *Transaction) common.Hash { - if tx.Type() != BlobTxType { - return s.londonSigner.Hash(tx) - } - return tx.inner.sigHash(s.chainId) -} - -type londonSigner struct{ eip2930Signer } - // NewLondonSigner returns a signer that accepts // - EIP-1559 dynamic fee transactions // - EIP-2930 access list transactions, // - EIP-155 replay protected transactions, and // - legacy Homestead transactions. func NewLondonSigner(chainId *big.Int) Signer { - return londonSigner{eip2930Signer{NewEIP155Signer(chainId)}} + return newModernSigner(chainId, forks.London) } -func (s londonSigner) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != DynamicFeeTxType { - return s.eip2930Signer.Sender(tx) - } - V, R, S := tx.RawSignatureValues() - // DynamicFee txs are defined to use 0 and 1 as their recovery - // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) - } - return recoverPlain(s.Hash(tx), R, S, V, true) -} - -func (s londonSigner) Equal(s2 Signer) bool { - x, ok := s2.(londonSigner) - return ok && x.chainId.Cmp(s.chainId) == 0 -} - -func (s londonSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - txdata, ok := tx.inner.(*DynamicFeeTx) - if !ok { - return s.eip2930Signer.SignatureValues(tx, sig) - } - // Check that chain ID of tx matches the signer. We also accept ID zero here, - // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 { - return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) - } - R, S, _ = decodeSignature(sig) - V = big.NewInt(int64(sig[64])) - return R, S, V, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s londonSigner) Hash(tx *Transaction) common.Hash { - if tx.Type() != DynamicFeeTxType { - return s.eip2930Signer.Hash(tx) - } - return tx.inner.sigHash(s.chainId) -} - -type eip2930Signer struct{ EIP155Signer } - // NewEIP2930Signer returns a signer that accepts EIP-2930 access list transactions, // EIP-155 replay protected transactions, and legacy Homestead transactions. func NewEIP2930Signer(chainId *big.Int) Signer { - return eip2930Signer{NewEIP155Signer(chainId)} -} - -func (s eip2930Signer) ChainID() *big.Int { - return s.chainId -} - -func (s eip2930Signer) Equal(s2 Signer) bool { - x, ok := s2.(eip2930Signer) - return ok && x.chainId.Cmp(s.chainId) == 0 -} - -func (s eip2930Signer) Sender(tx *Transaction) (common.Address, error) { - V, R, S := tx.RawSignatureValues() - switch tx.Type() { - case LegacyTxType: - return s.EIP155Signer.Sender(tx) - case AccessListTxType: - // AL txs are defined to use 0 and 1 as their recovery - // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) - default: - return common.Address{}, ErrTxTypeNotSupported - } - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) - } - return recoverPlain(s.Hash(tx), R, S, V, true) -} - -func (s eip2930Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - switch txdata := tx.inner.(type) { - case *LegacyTx: - return s.EIP155Signer.SignatureValues(tx, sig) - case *AccessListTx: - // Check that chain ID of tx matches the signer. We also accept ID zero here, - // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 { - return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) - } - R, S, _ = decodeSignature(sig) - V = big.NewInt(int64(sig[64])) - default: - return nil, nil, nil, ErrTxTypeNotSupported - } - return R, S, V, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s eip2930Signer) Hash(tx *Transaction) common.Hash { - switch tx.Type() { - case LegacyTxType: - return s.EIP155Signer.Hash(tx) - case AccessListTxType: - return tx.inner.sigHash(s.chainId) - default: - // This _should_ not happen, but in case someone sends in a bad - // json struct via RPC, it's probably more prudent to return an - // empty hash instead of killing the node with a panic - //panic("Unsupported transaction type: %d", tx.typ) - return common.Hash{} - } + return newModernSigner(chainId, forks.Berlin) } // EIP155Signer implements Signer using the EIP-155 rules. This accepts transactions which // are replay-protected as well as unprotected homestead transactions. +// Deprecated: always use the Signer interface type type EIP155Signer struct { chainId, chainIdMul *big.Int } @@ -478,8 +376,9 @@ func (s EIP155Signer) Hash(tx *Transaction) common.Hash { return tx.inner.sigHash(s.chainId) } -// HomesteadSigner implements Signer interface using the -// homestead rules. +// HomesteadSigner implements Signer using the homestead rules. The only valid reason to +// use this type is creating legacy transactions which are intentionally not +// replay-protected. type HomesteadSigner struct{ FrontierSigner } func (hs HomesteadSigner) ChainID() *big.Int { @@ -505,8 +404,8 @@ func (hs HomesteadSigner) Sender(tx *Transaction) (common.Address, error) { return recoverPlain(hs.Hash(tx), r, s, v, true) } -// FrontierSigner implements Signer interface using the -// frontier rules. +// FrontierSigner implements Signer using the frontier rules. +// Deprecated: always use the Signer interface type type FrontierSigner struct{} func (fs FrontierSigner) ChainID() *big.Int { diff --git a/params/forks/forks.go b/params/forks/forks.go index 2d44e13b04..02f6e5b612 100644 --- a/params/forks/forks.go +++ b/params/forks/forks.go @@ -24,8 +24,8 @@ const ( FrontierThawing Homestead DAO - TangerineWhistle - SpuriousDragon + TangerineWhistle // a.k.a. the EIP150 fork + SpuriousDragon // a.k.a. the EIP155 fork Byzantium Constantinople Petersburg From 8e3cd41b0490dc54022c0384c30c576b10c7f8e9 Mon Sep 17 00:00:00 2001 From: maskpp Date: Thu, 20 Mar 2025 13:14:13 +0800 Subject: [PATCH 211/940] cmd/utils: force hash scheme for archive mode (#31439) --- cmd/utils/flags.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 77dac8bd1a..ae58c2d053 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1659,12 +1659,16 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { log.Warn("The flag --txlookuplimit is deprecated and will be removed, please use --history.transactions") cfg.TransactionHistory = ctx.Uint64(TxLookupLimitFlag.Name) } - if ctx.String(GCModeFlag.Name) == "archive" && cfg.TransactionHistory != 0 { - cfg.TransactionHistory = 0 - log.Warn("Disabled transaction unindexing for archive node") + if ctx.String(GCModeFlag.Name) == "archive" { + if cfg.TransactionHistory != 0 { + cfg.TransactionHistory = 0 + log.Warn("Disabled transaction unindexing for archive node") + } - cfg.StateScheme = rawdb.HashScheme - log.Warn("Forcing hash state-scheme for archive mode") + if cfg.StateScheme != rawdb.HashScheme { + cfg.StateScheme = rawdb.HashScheme + log.Warn("Forcing hash state-scheme for archive mode") + } } if ctx.IsSet(LogHistoryFlag.Name) { cfg.LogHistory = ctx.Uint64(LogHistoryFlag.Name) From 03cc2942c2c25208dac1b7c8fc1bc19f3d72fd97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Thu, 20 Mar 2025 09:23:10 +0100 Subject: [PATCH 212/940] cmd/workload: fixed filter test request error handling (#31424) This PR fixes the broken request error handling of the workload filter tests. Until now `validateHistoryPruneErr` was invoked with `fq.Err` as an input which was always nil and a timeout or http error was reported as a result content mismatch. Also, in case of `errPrunedHistory` it is wrong to return here without setting an error because then it will look like a valid empty result and the check will later fail. So instead `errPrunedHistory` is always returned now (without printing an error message) and the callers of `run` should handle this special case (typically ignore silently). --- cmd/workload/filtertest.go | 21 ++++++++++-------- cmd/workload/filtertestgen.go | 24 ++++----------------- cmd/workload/filtertestperf.go | 39 ++++++++++++++++++++++++++++------ 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/cmd/workload/filtertest.go b/cmd/workload/filtertest.go index bc76857911..52dd6e41ad 100644 --- a/cmd/workload/filtertest.go +++ b/cmd/workload/filtertest.go @@ -109,6 +109,9 @@ func (s *filterTestSuite) filterFullRange(t *utesting.T) { func (s *filterTestSuite) queryAndCheck(t *utesting.T, query *filterQuery) { query.run(s.cfg.client, s.cfg.historyPruneBlock) + if query.Err == errPrunedHistory { + return + } if query.Err != nil { t.Errorf("Filter query failed (fromBlock: %d toBlock: %d addresses: %v topics: %v error: %v)", query.FromBlock, query.ToBlock, query.Address, query.Topics, query.Err) return @@ -126,6 +129,9 @@ func (s *filterTestSuite) fullRangeQueryAndCheck(t *utesting.T, query *filterQue Topics: query.Topics, } frQuery.run(s.cfg.client, s.cfg.historyPruneBlock) + if frQuery.Err == errPrunedHistory { + return + } if frQuery.Err != nil { t.Errorf("Full range filter query failed (addresses: %v topics: %v error: %v)", frQuery.Address, frQuery.Topics, frQuery.Err) return @@ -206,14 +212,11 @@ func (fq *filterQuery) run(client *client, historyPruneBlock *uint64) { Addresses: fq.Address, Topics: fq.Topics, }) - if err != nil { - if err = validateHistoryPruneErr(fq.Err, uint64(fq.FromBlock), historyPruneBlock); err == errPrunedHistory { - return - } else if err != nil { - fmt.Printf("Filter query failed: fromBlock: %d toBlock: %d addresses: %v topics: %v error: %v\n", - fq.FromBlock, fq.ToBlock, fq.Address, fq.Topics, err) - } - fq.Err = err - } fq.results = logs + fq.Err = validateHistoryPruneErr(err, uint64(fq.FromBlock), historyPruneBlock) +} + +func (fq *filterQuery) printError() { + fmt.Printf("Filter query failed: fromBlock: %d toBlock: %d addresses: %v topics: %v error: %v\n", + fq.FromBlock, fq.ToBlock, fq.Address, fq.Topics, fq.Err) } diff --git a/cmd/workload/filtertestgen.go b/cmd/workload/filtertestgen.go index e50ec57b47..6d1f639819 100644 --- a/cmd/workload/filtertestgen.go +++ b/cmd/workload/filtertestgen.go @@ -40,7 +40,6 @@ var ( Action: filterGenCmd, Flags: []cli.Flag{ filterQueryFileFlag, - filterErrorFileFlag, }, } filterQueryFileFlag = &cli.StringFlag{ @@ -72,8 +71,8 @@ func filterGenCmd(ctx *cli.Context) error { query := f.newQuery() query.run(f.client, nil) if query.Err != nil { - f.errors = append(f.errors, query) - continue + query.printError() + exit("filter query failed") } if len(query.results) > 0 && len(query.results) <= maxFilterResultSize { for { @@ -90,8 +89,8 @@ func filterGenCmd(ctx *cli.Context) error { ) } if extQuery.Err != nil { - f.errors = append(f.errors, extQuery) - break + extQuery.printError() + exit("filter query failed") } if len(extQuery.results) > maxFilterResultSize { break @@ -101,7 +100,6 @@ func filterGenCmd(ctx *cli.Context) error { f.storeQuery(query) if time.Since(lastWrite) > time.Second*10 { f.writeQueries() - f.writeErrors() lastWrite = time.Now() } } @@ -112,18 +110,15 @@ func filterGenCmd(ctx *cli.Context) error { type filterTestGen struct { client *client queryFile string - errorFile string finalizedBlock int64 queries [filterBuckets][]*filterQuery - errors []*filterQuery } func newFilterTestGen(ctx *cli.Context) *filterTestGen { return &filterTestGen{ client: makeClient(ctx), queryFile: ctx.String(filterQueryFileFlag.Name), - errorFile: ctx.String(filterErrorFileFlag.Name), } } @@ -360,17 +355,6 @@ func (s *filterTestGen) writeQueries() { file.Close() } -// writeQueries serializes the generated errors to the error file. -func (s *filterTestGen) writeErrors() { - file, err := os.Create(s.errorFile) - if err != nil { - exit(fmt.Errorf("Error creating filter error file %s: %v", s.errorFile, err)) - return - } - defer file.Close() - json.NewEncoder(file).Encode(s.errors) -} - func mustGetFinalizedBlock(client *client) int64 { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() diff --git a/cmd/workload/filtertestperf.go b/cmd/workload/filtertestperf.go index 7f4cad4ab9..c7d2fdd02a 100644 --- a/cmd/workload/filtertestperf.go +++ b/cmd/workload/filtertestperf.go @@ -17,8 +17,10 @@ package main import ( + "encoding/json" "fmt" "math/rand" + "os" "slices" "sort" "time" @@ -41,7 +43,7 @@ var ( } ) -const passCount = 1 +const passCount = 3 func filterPerfCmd(ctx *cli.Context) error { cfg := testConfigFromCLI(ctx) @@ -61,7 +63,10 @@ func filterPerfCmd(ctx *cli.Context) error { } // Run test queries. - var failed, mismatch int + var ( + failed, pruned, mismatch int + errors []*filterQuery + ) for i := 1; i <= passCount; i++ { fmt.Println("Performance test pass", i, "/", passCount) for len(queries) > 0 { @@ -71,27 +76,35 @@ func filterPerfCmd(ctx *cli.Context) error { queries = queries[:len(queries)-1] start := time.Now() qt.query.run(cfg.client, cfg.historyPruneBlock) + if qt.query.Err == errPrunedHistory { + pruned++ + continue + } qt.runtime = append(qt.runtime, time.Since(start)) slices.Sort(qt.runtime) qt.medianTime = qt.runtime[len(qt.runtime)/2] if qt.query.Err != nil { + qt.query.printError() + errors = append(errors, qt.query) failed++ continue } if rhash := qt.query.calculateHash(); *qt.query.ResultHash != rhash { fmt.Printf("Filter query result mismatch: fromBlock: %d toBlock: %d addresses: %v topics: %v expected hash: %064x calculated hash: %064x\n", qt.query.FromBlock, qt.query.ToBlock, qt.query.Address, qt.query.Topics, *qt.query.ResultHash, rhash) + errors = append(errors, qt.query) + mismatch++ continue } processed = append(processed, qt) if len(processed)%50 == 0 { - fmt.Println(" processed:", len(processed), "remaining", len(queries), "failed:", failed, "result mismatch:", mismatch) + fmt.Println(" processed:", len(processed), "remaining", len(queries), "failed:", failed, "pruned:", pruned, "result mismatch:", mismatch) } } queries, processed = processed, nil } // Show results and stats. - fmt.Println("Performance test finished; processed:", len(queries), "failed:", failed, "result mismatch:", mismatch) + fmt.Println("Performance test finished; processed:", len(queries), "failed:", failed, "pruned:", pruned, "result mismatch:", mismatch) stats := make([]bucketStats, len(f.queries)) var wildcardStats bucketStats for _, qt := range queries { @@ -114,11 +127,14 @@ func filterPerfCmd(ctx *cli.Context) error { sort.Slice(queries, func(i, j int) bool { return queries[i].medianTime > queries[j].medianTime }) - for i := 0; i < 10; i++ { - q := queries[i] + for i, q := range queries { + if i >= 10 { + break + } fmt.Printf("Most expensive query #%-2d median runtime: %13v max runtime: %13v result count: %4d fromBlock: %9d toBlock: %9d addresses: %v topics: %v\n", i+1, q.medianTime, q.runtime[len(q.runtime)-1], len(q.query.results), q.query.FromBlock, q.query.ToBlock, q.query.Address, q.query.Topics) } + writeErrors(ctx.String(filterErrorFileFlag.Name), errors) return nil } @@ -135,3 +151,14 @@ func (st *bucketStats) print(name string) { fmt.Printf("%-20s queries: %4d average block length: %12.2f average log count: %7.2f average runtime: %13v\n", name, st.count, float64(st.blocks)/float64(st.count), float64(st.logs)/float64(st.count), st.runtime/time.Duration(st.count)) } + +// writeQueries serializes the generated errors to the error file. +func writeErrors(errorFile string, errors []*filterQuery) { + file, err := os.Create(errorFile) + if err != nil { + exit(fmt.Errorf("Error creating filter error file %s: %v", errorFile, err)) + return + } + defer file.Close() + json.NewEncoder(file).Encode(errors) +} From 43883c64566602305c079ed6a7c83183f0443dfb Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 20 Mar 2025 10:20:51 +0100 Subject: [PATCH 213/940] eth/tracers: hex-encode returnValue (#31216) This is a **breaking change** to the opcode tracer. The top-level `returnValue` field of a trace will be now hex-encoded. If the return data is empty, this field will contain "0x". Fixes #31196 --- eth/tracers/api_test.go | 42 ++++++++++++++++++------------------ eth/tracers/logger/logger.go | 7 +++--- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 796719bd63..c28abba85f 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -354,7 +354,7 @@ func TestTraceCall(t *testing.T) { }, config: nil, expectErr: nil, - expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`, + expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`, }, // Standard JSON trace upon the head, plain transfer. { @@ -366,7 +366,7 @@ func TestTraceCall(t *testing.T) { }, config: nil, expectErr: nil, - expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`, + expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`, }, // Upon the last state, default to the post block's state { @@ -377,7 +377,7 @@ func TestTraceCall(t *testing.T) { Value: (*hexutil.Big)(new(big.Int).Add(big.NewInt(params.Ether), big.NewInt(100))), }, config: nil, - expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`, + expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`, }, // Before the first transaction, should be failed { @@ -411,7 +411,7 @@ func TestTraceCall(t *testing.T) { }, config: &TraceCallConfig{TxIndex: uintPtr(2)}, expectErr: nil, - expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`, + expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`, }, // Standard JSON trace upon the non-existent block, error expects { @@ -435,7 +435,7 @@ func TestTraceCall(t *testing.T) { }, config: nil, expectErr: nil, - expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`, + expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`, }, // Tracing on 'pending' should fail: { @@ -458,7 +458,7 @@ func TestTraceCall(t *testing.T) { BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, }, expectErr: nil, - expect: ` {"gas":53018,"failed":false,"returnValue":"","structLogs":[ + expect: ` {"gas":53018,"failed":false,"returnValue":"0x","structLogs":[ {"pc":0,"op":"NUMBER","gas":24946984,"gasCost":2,"depth":1,"stack":[]}, {"pc":1,"op":"STOP","gas":24946982,"gasCost":0,"depth":1,"stack":["0x1337"]}]}`, }, @@ -535,7 +535,7 @@ func TestTraceTransaction(t *testing.T) { if !reflect.DeepEqual(have, &logger.ExecutionResult{ Gas: params.TxGas, Failed: false, - ReturnValue: "", + ReturnValue: []byte{}, StructLogs: []json.RawMessage{}, }) { t.Error("Transaction tracing result is different") @@ -596,7 +596,7 @@ func TestTraceBlock(t *testing.T) { // Trace head block { blockNumber: rpc.BlockNumber(genBlocks), - want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash), + want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}}]`, txHash), }, // Trace non-existent block { @@ -606,12 +606,12 @@ func TestTraceBlock(t *testing.T) { // Trace latest block { blockNumber: rpc.LatestBlockNumber, - want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash), + want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}}]`, txHash), }, // Trace pending block { blockNumber: rpc.PendingBlockNumber, - want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash), + want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}}]`, txHash), }, } for i, tc := range testSuite { @@ -704,7 +704,7 @@ func TestTracingWithOverrides(t *testing.T) { randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))}, }, }, - want: `{"gas":21000,"failed":false,"returnValue":""}`, + want: `{"gas":21000,"failed":false,"returnValue":"0x"}`, }, // Invalid call without state overriding { @@ -749,7 +749,7 @@ func TestTracingWithOverrides(t *testing.T) { }, }, }, - want: `{"gas":23347,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000007b"}`, + want: `{"gas":23347,"failed":false,"returnValue":"0x000000000000000000000000000000000000000000000000000000000000007b"}`, }, { // Override blocknumber blockNumber: rpc.LatestBlockNumber, @@ -761,7 +761,7 @@ func TestTracingWithOverrides(t *testing.T) { config: &TraceCallConfig{ BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, }, - want: `{"gas":59537,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000001337"}`, + want: `{"gas":59537,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000001337"}`, }, { // Override blocknumber, and query a blockhash blockNumber: rpc.LatestBlockNumber, @@ -781,7 +781,7 @@ func TestTracingWithOverrides(t *testing.T) { config: &TraceCallConfig{ BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, }, - want: `{"gas":72666,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}`, + want: `{"gas":72666,"failed":false,"returnValue":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}`, }, /* pragma solidity =0.8.12; @@ -815,7 +815,7 @@ func TestTracingWithOverrides(t *testing.T) { }, }, }, - want: `{"gas":44100,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001"}`, + want: `{"gas":44100,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000001"}`, }, { // Same again, this time with storage override blockNumber: rpc.LatestBlockNumber, @@ -833,7 +833,7 @@ func TestTracingWithOverrides(t *testing.T) { }, }, //want: `{"gas":46900,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000539"}`, - want: `{"gas":44100,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001"}`, + want: `{"gas":44100,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000001"}`, }, { // No state override blockNumber: rpc.LatestBlockNumber, @@ -863,7 +863,7 @@ func TestTracingWithOverrides(t *testing.T) { }, }, }, - want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000077"}`, + want: `{"gas":25288,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000077"}`, }, { // Full state override // The original storage is @@ -901,7 +901,7 @@ func TestTracingWithOverrides(t *testing.T) { }, }, }, - want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000011"}`, + want: `{"gas":25288,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000011"}`, }, { // Partial state override // The original storage is @@ -939,7 +939,7 @@ func TestTracingWithOverrides(t *testing.T) { }, }, }, - want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000055"}`, + want: `{"gas":25288,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000055"}`, }, { // Call to precompile ECREC (0x01), but code was modified to add 1 to input blockNumber: rpc.LatestBlockNumber, @@ -1084,7 +1084,7 @@ func TestTraceChain(t *testing.T) { backend.relHook = func() { rel.Add(1) } api := NewAPI(backend) - single := `{"txHash":"0x0000000000000000000000000000000000000000000000000000000000000000","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}` + single := `{"txHash":"0x0000000000000000000000000000000000000000000000000000000000000000","result":{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}}` var cases = []struct { start uint64 end uint64 @@ -1198,7 +1198,7 @@ func TestTraceBlockWithBasefee(t *testing.T) { // 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), + want: fmt.Sprintf(`[{"txHash":"%#x","result":{"gas":21002,"failed":false,"returnValue":"0x","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 { diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 02ff8146fb..a28cecf138 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -350,14 +350,13 @@ func (l *StructLogger) GetResult() (json.RawMessage, error) { failed := l.err != nil returnData := common.CopyBytes(l.output) // Return data when successful and revert reason when reverted, otherwise empty. - returnVal := fmt.Sprintf("%x", returnData) if failed && !errors.Is(l.err, vm.ErrExecutionReverted) { - returnVal = "" + returnData = []byte{} } return json.Marshal(&ExecutionResult{ Gas: l.usedGas, Failed: failed, - ReturnValue: returnVal, + ReturnValue: returnData, StructLogs: l.logs, }) } @@ -527,6 +526,6 @@ func (t *mdLogger) OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.O type ExecutionResult struct { Gas uint64 `json:"gas"` Failed bool `json:"failed"` - ReturnValue string `json:"returnValue"` + ReturnValue hexutil.Bytes `json:"returnValue"` StructLogs []json.RawMessage `json:"structLogs"` } From 0a8f41e2cb9b28210e73b9509bf645ec56eb1f5f Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 20 Mar 2025 20:33:13 +0800 Subject: [PATCH 214/940] eth/tracers: fix test (#31445) This pull request fixes a broken unit test ``` === CONT TestTracingWithOverrides api_test.go:1012: result: {"gas":21167,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000002","structLogs":[{"pc":0,"op":"PUSH1","gas":24978860,"gasCost":3,"depth":1,"stack":[]},{"pc":2,"op":"CALLDATALOAD","gas":24978857,"gasCost":3,"depth":1,"stack":["0x0"]},{"pc":3,"op":"PUSH1","gas":24978854,"gasCost":3,"depth":1,"stack":["0x1"]},{"pc":5,"op":"ADD","gas":24978851,"gasCost":3,"depth":1,"stack":["0x1","0x1"]},{"pc":6,"op":"PUSH1","gas":24978848,"gasCost":3,"depth":1,"stack":["0x2"]},{"pc":8,"op":"MSTORE","gas":24978845,"gasCost":6,"depth":1,"stack":["0x2","0x0"]},{"pc":9,"op":"PUSH1","gas":24978839,"gasCost":3,"depth":1,"stack":[]},{"pc":11,"op":"PUSH1","gas":24978836,"gasCost":3,"depth":1,"stack":["0x20"]},{"pc":13,"op":"RETURN","gas":24978833,"gasCost":0,"depth":1,"stack":["0x20","0x0"]}]} api_test.go:1013: test 10, result mismatch, have {21167 false 0x0000000000000000000000000000000000000000000000000000000000000002} , want {21167 false 0000000000000000000000000000000000000000000000000000000000000002} api_test.go:1012: result: {"gas":25664,"failed":false,"returnValue":"0x000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074","structLogs":[]} api_test.go:1013: test 11, result mismatch, have {25664 false 0x000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074} , want {25664 false 000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074} ``` --- eth/tracers/api_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index c28abba85f..529448e397 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -960,7 +960,7 @@ func TestTracingWithOverrides(t *testing.T) { }, }, }, - want: `{"gas":21167,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000002"}`, + want: `{"gas":21167,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000002"}`, }, { // Call to ECREC Precompiled on a different address, expect the original behaviour of ECREC precompile blockNumber: rpc.LatestBlockNumber, @@ -981,7 +981,7 @@ func TestTracingWithOverrides(t *testing.T) { }, }, }, - want: `{"gas":25664,"failed":false,"returnValue":"000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074"}`, + want: `{"gas":25664,"failed":false,"returnValue":"0x000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074"}`, }, } for i, tc := range testSuite { From 9fc2bbe1ceaaa3889d0a8eee8c9dcfb6ddefb95c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Thu, 20 Mar 2025 14:13:58 +0100 Subject: [PATCH 215/940] core/filtermaps: allow log search while head indexing (#31429) This PR changes the matcher syncing conditions so that it is possible to run a search while head indexing is in progress. Previously it was a requirement to have the head indexed in order to perform matcher sync before and after a search. This was unnecessarily strict as the purpose was just to avoid syncing the valid range with the temporary shortened indexed range applied while updating existing head maps. Now the sync condition explicitly checks whether the indexer has a temporary indexed range with some head maps being partially updated. It also fixes a deadlock that happened when matcher synchronization was attempted in the event handler called from the `writeFinishedMaps` periodical callback. --- core/filtermaps/filtermaps.go | 10 ++++++---- core/filtermaps/indexer.go | 14 +++++++++----- core/filtermaps/map_renderer.go | 8 ++++++-- core/filtermaps/matcher_backend.go | 2 +- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index fe75c1ea7d..dfc20521f6 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -70,6 +70,7 @@ type FilterMaps struct { indexLock sync.RWMutex indexedRange filterMapsRange indexedView *ChainView // always consistent with the log index + hasTempRange bool // also accessed by indexer and matcher backend but no locking needed. filterMapCache *lru.Cache[uint32, filterMap] @@ -94,7 +95,7 @@ type FilterMaps struct { ptrTailUnindexMap uint32 targetView *ChainView - matcherSyncRequest *FilterMapsMatcherBackend + matcherSyncRequests []*FilterMapsMatcherBackend historyCutoff uint64 finalBlock, lastFinal uint64 lastFinalEpoch uint32 @@ -330,7 +331,7 @@ func (f *FilterMaps) init() error { fmr.blocks = common.NewRange(cp.BlockNumber+1, 0) fmr.maps = common.NewRange(uint32(bestLen)< Date: Thu, 20 Mar 2025 17:11:40 +0100 Subject: [PATCH 216/940] p2p/discover: repeat WHOAREYOU challenge when handshake in progress (#31356) This fixes the handshake in a scenario where the remote end sends two unknown packets in a row. When this happens, we would previously respond to both with a WHOAREYOU challenge, but keep only the latest sent challenge. Transmission is assumed to be unreliable, so any client that sends two request packets simultaneously has to be prepared to follow up on whichever request leads to a handshake. With this fix, we force them to do the handshake that we can actually complete. Fixes #30581 --- p2p/discover/v5_udp.go | 26 +++++++++++- p2p/discover/v5_udp_test.go | 70 +++++++++++++++++++++++++++++++++ p2p/discover/v5wire/encoding.go | 6 +++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 9e849751c1..6f7c797152 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -50,11 +50,20 @@ const ( // encoding/decoding and with the handshake; the UDPv5 object handles higher-level concerns. type codecV5 interface { // Encode encodes a packet. - Encode(enode.ID, string, v5wire.Packet, *v5wire.Whoareyou) ([]byte, v5wire.Nonce, error) + // + // If the underlying type of 'p' is *v5wire.Whoareyou, a Whoareyou challenge packet is + // encoded. If the 'challenge' parameter is non-nil, the packet is encoded as a + // handshake message packet. Otherwise, the packet will be encoded as an ordinary + // message packet. + Encode(id enode.ID, addr string, p v5wire.Packet, challenge *v5wire.Whoareyou) ([]byte, v5wire.Nonce, error) // Decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails. // The *enode.Node return value is non-nil when the input contains a handshake response. - Decode([]byte, string) (enode.ID, *enode.Node, v5wire.Packet, error) + Decode(b []byte, addr string) (enode.ID, *enode.Node, v5wire.Packet, error) + + // CurrentChallenge returns the most recent WHOAREYOU challenge that was encoded to given node. + // This will return a non-nil value if there is an active handshake attempt with the node, and nil otherwise. + CurrentChallenge(id enode.ID, addr string) *v5wire.Whoareyou } // UDPv5 is the implementation of protocol version 5. @@ -824,6 +833,19 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort // handleUnknown initiates a handshake by responding with WHOAREYOU. func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) { + currentChallenge := t.codec.CurrentChallenge(fromID, fromAddr.String()) + if currentChallenge != nil { + // This case happens when the sender issues multiple concurrent requests. + // Since we only support one in-progress handshake at a time, we need to tell + // them which handshake attempt they need to complete. We tell them to use the + // existing handshake attempt since the response to that one might still be in + // transit. + t.log.Debug("Repeating discv5 handshake challenge", "id", fromID, "addr", fromAddr) + t.sendResponse(fromID, fromAddr, currentChallenge) + return + } + + // Send a fresh challenge. challenge := &v5wire.Whoareyou{Nonce: p.Nonce} crand.Read(challenge.IDNonce[:]) if n := t.GetNode(fromID); n != nil { diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 371f414760..3026dff538 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -140,6 +140,26 @@ func TestUDPv5_unknownPacket(t *testing.T) { test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { check(p, 0) }) +} + +func TestUDPv5_unknownPacketKnownNode(t *testing.T) { + t.Parallel() + test := newUDPV5Test(t) + defer test.close() + + nonce := v5wire.Nonce{1, 2, 3} + check := func(p *v5wire.Whoareyou, wantSeq uint64) { + t.Helper() + if p.Nonce != nonce { + t.Error("wrong nonce in WHOAREYOU:", p.Nonce, nonce) + } + if p.IDNonce == ([16]byte{}) { + t.Error("all zero ID nonce") + } + if p.RecordSeq != wantSeq { + t.Errorf("wrong record seq %d in WHOAREYOU, want %d", p.RecordSeq, wantSeq) + } + } // Make node known. n := test.getNode(test.remotekey, test.remoteaddr).Node() @@ -151,6 +171,42 @@ func TestUDPv5_unknownPacket(t *testing.T) { }) } +// This test checks that, when multiple 'unknown' packets are received during a handshake, +// the node sticks to the first handshake attempt. +func TestUDPv5_handshakeRepeatChallenge(t *testing.T) { + t.Parallel() + test := newUDPV5Test(t) + defer test.close() + + nonce1 := v5wire.Nonce{1} + nonce2 := v5wire.Nonce{2} + nonce3 := v5wire.Nonce{3} + check := func(p *v5wire.Whoareyou, wantNonce v5wire.Nonce) { + t.Helper() + if p.Nonce != wantNonce { + t.Error("wrong nonce in WHOAREYOU:", p.Nonce, wantNonce) + } + } + + // Unknown packet from unknown node. + test.packetIn(&v5wire.Unknown{Nonce: nonce1}) + test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { + check(p, nonce1) + }) + + // Second unknown packet. Here we expect the response to reference the + // first unknown packet. + test.packetIn(&v5wire.Unknown{Nonce: nonce2}) + test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { + check(p, nonce1) + }) + // Third unknown packet. This should still return the first nonce. + test.packetIn(&v5wire.Unknown{Nonce: nonce3}) + test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { + check(p, nonce1) + }) +} + // This test checks that incoming FINDNODE calls are handled correctly. func TestUDPv5_findnodeHandling(t *testing.T) { t.Parallel() @@ -698,6 +754,8 @@ type testCodec struct { test *udpV5Test id enode.ID ctr uint64 + + sentChallenges map[enode.ID]*v5wire.Whoareyou } type testCodecFrame struct { @@ -712,11 +770,23 @@ func (c *testCodec) Encode(toID enode.ID, addr string, p v5wire.Packet, _ *v5wir var authTag v5wire.Nonce binary.BigEndian.PutUint64(authTag[:], c.ctr) + if w, ok := p.(*v5wire.Whoareyou); ok { + // Store recently sent Whoareyou challenges. + if c.sentChallenges == nil { + c.sentChallenges = make(map[enode.ID]*v5wire.Whoareyou) + } + c.sentChallenges[toID] = w + } + penc, _ := rlp.EncodeToBytes(p) frame, err := rlp.EncodeToBytes(testCodecFrame{c.id, authTag, p.Kind(), penc}) return frame, authTag, err } +func (c *testCodec) CurrentChallenge(id enode.ID, addr string) *v5wire.Whoareyou { + return c.sentChallenges[id] +} + func (c *testCodec) Decode(input []byte, addr string) (enode.ID, *enode.Node, v5wire.Packet, error) { frame, p, err := c.decodeFrame(input) if err != nil { diff --git a/p2p/discover/v5wire/encoding.go b/p2p/discover/v5wire/encoding.go index 904a3ddec6..e50b7cd16d 100644 --- a/p2p/discover/v5wire/encoding.go +++ b/p2p/discover/v5wire/encoding.go @@ -245,6 +245,12 @@ func (c *Codec) EncodeRaw(id enode.ID, head Header, msgdata []byte) ([]byte, err return c.buf.Bytes(), nil } +// CurrentChallenge returns the latest challenge sent to the given node. +// This will return non-nil while a handshake is in progress. +func (c *Codec) CurrentChallenge(id enode.ID, addr string) *Whoareyou { + return c.sc.getHandshake(id, addr) +} + func (c *Codec) writeHeaders(head *Header) { c.buf.Reset() c.buf.Write(head.IV[:]) From 7fed9584b5426be5db6d7b0198acdec6515d9c81 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 21 Mar 2025 05:05:15 +0800 Subject: [PATCH 217/940] core/txpool/legacypool: reject gapped tx from delegated account (#31430) This pull request improves the protection mechanism in the txpool for senders with delegation. A sender with either delegation or pending delegation is now limited to a maximum of one in-flight executable transaction, while gapped transactions will be rejected. Reason: If nonce-gapped transaction from delegated/pending-delegated senders can be acceptable, then it's no-longer possible to send another "executable" transaction with correct nonce due to the policy of at most one inflight tx. The gapped transaction will be stuck in the txpool, with no meaningful way to unlock the sender. --------- Co-authored-by: lightclient --- core/txpool/legacypool/legacypool.go | 54 ++++++++++++++--------- core/txpool/legacypool/legacypool_test.go | 7 ++- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 78be81480f..7a0095a5ad 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -67,6 +67,10 @@ var ( // transactions is reached for specific accounts. ErrInflightTxLimitReached = errors.New("in-flight transaction limit reached for delegated accounts") + // ErrOutOfOrderTxFromDelegated is returned when the transaction with gapped + // nonce received from the accounts with delegation or pending delegation. + ErrOutOfOrderTxFromDelegated = errors.New("gapped-nonce tx from delegated accounts") + // ErrAuthorityReserved is returned if a transaction has an authorization // signed by an address which already has in-flight transactions known to the // pool. @@ -606,33 +610,39 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error { return pool.validateAuth(tx) } +// checkDelegationLimit determines if the tx sender is delegated or has a +// pending delegation, and if so, ensures they have at most one in-flight +// **executable** transaction, e.g. disallow stacked and gapped transactions +// from the account. +func (pool *LegacyPool) checkDelegationLimit(tx *types.Transaction) error { + from, _ := types.Sender(pool.signer, tx) // validated + + // Short circuit if the sender has neither delegation nor pending delegation. + if pool.currentState.GetCodeHash(from) == types.EmptyCodeHash && len(pool.all.auths[from]) == 0 { + return nil + } + pending := pool.pending[from] + if pending == nil { + // Transaction with gapped nonce is not supported for delegated accounts + if pool.pendingNonces.get(from) != tx.Nonce() { + return ErrOutOfOrderTxFromDelegated + } + return nil + } + // Transaction replacement is supported + if pending.Contains(tx.Nonce()) { + return nil + } + return ErrInflightTxLimitReached +} + // validateAuth verifies that the transaction complies with code authorization // restrictions brought by SetCode transaction type. func (pool *LegacyPool) validateAuth(tx *types.Transaction) error { - from, _ := types.Sender(pool.signer, tx) // validated - // Allow at most one in-flight tx for delegated accounts or those with a // pending authorization. - if pool.currentState.GetCodeHash(from) != types.EmptyCodeHash || len(pool.all.auths[from]) != 0 { - var ( - count int - exists bool - ) - pending := pool.pending[from] - if pending != nil { - count += pending.Len() - exists = pending.Contains(tx.Nonce()) - } - queue := pool.queue[from] - if queue != nil { - count += queue.Len() - exists = exists || queue.Contains(tx.Nonce()) - } - // Replace the existing in-flight transaction for delegated accounts - // are still supported - if count >= 1 && !exists { - return ErrInflightTxLimitReached - } + if err := pool.checkDelegationLimit(tx); err != nil { + return err } // Authorities cannot conflict with any pending or queued transactions. if auths := tx.SetCodeAuthorities(); len(auths) > 0 { diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index ef887041ad..3f269bd69e 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -2262,6 +2262,11 @@ func TestSetCodeTransactions(t *testing.T) { aa := common.Address{0xaa, 0xaa} statedb.SetCode(addrA, append(types.DelegationPrefix, aa.Bytes()...)) statedb.SetCode(aa, []byte{byte(vm.ADDRESS), byte(vm.PUSH0), byte(vm.SSTORE)}) + + // Send gapped transaction, it should be rejected. + if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrOutOfOrderTxFromDelegated) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrOutOfOrderTxFromDelegated, err) + } // Send transactions. First is accepted, second is rejected. if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyA)); err != nil { t.Fatalf("%s: failed to add remote transaction: %v", name, err) @@ -2269,7 +2274,7 @@ func TestSetCodeTransactions(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrInflightTxLimitReached) { t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err) } - // Also check gapped transaction. + // Check gapped transaction again. if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrInflightTxLimitReached) { t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err) } From 07cca7ab9f9c26e435acbf81432f61102d3ed1d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 21 Mar 2025 10:47:58 +0100 Subject: [PATCH 218/940] core/bloombits: remove old bloombits logic and chain indexer (#31081) This PR is #3 of a 3-part series that implements the new log index intended to replace core/bloombits. Based on https://github.com/ethereum/go-ethereum/pull/31079 and https://github.com/ethereum/go-ethereum/pull/31080 Replaces https://github.com/ethereum/go-ethereum/pull/30370 This part removes the old bloombits package and the chain indexer that was only used by bloombits. Deletes the old bloombits database. FilterMaps data structure explanation: https://gist.github.com/zsfelfoldi/a60795f9da7ae6422f28c7a34e02a07e Log index generator code overview: https://gist.github.com/zsfelfoldi/97105dff0b1a4f5ed557924a24b9b9e7 Search pattern matcher code overview: https://gist.github.com/zsfelfoldi/5981735641c956afb18065e84f8aff34 Note that the possibility of a tree hashing scheme and remote proof protocol are mentioned in the documents above but they are not exactly specified yet. These specs are WIP and will be finalized after the local log indexer/filter code is finalized and merged. --------- Co-authored-by: Felix Lange --- core/blockchain.go | 2 +- core/bloom_indexer.go | 92 ---- core/bloombits/doc.go | 18 - core/bloombits/generator.go | 98 ---- core/bloombits/generator_test.go | 100 ----- core/bloombits/matcher.go | 649 --------------------------- core/bloombits/matcher_test.go | 292 ------------ core/bloombits/scheduler.go | 181 -------- core/bloombits/scheduler_test.go | 103 ----- core/chain_indexer.go | 522 --------------------- core/chain_indexer_test.go | 246 ---------- core/filtermaps/filtermaps.go | 35 +- core/filtermaps/indexer.go | 33 +- core/rawdb/accessors_indexes.go | 56 +-- core/rawdb/accessors_indexes_test.go | 53 --- core/rawdb/database.go | 8 +- core/rawdb/schema.go | 24 +- eth/api_backend.go | 12 - eth/backend.go | 35 +- eth/bloombits.go | 74 --- params/network_params.go | 8 - 21 files changed, 80 insertions(+), 2561 deletions(-) delete mode 100644 core/bloom_indexer.go delete mode 100644 core/bloombits/doc.go delete mode 100644 core/bloombits/generator.go delete mode 100644 core/bloombits/generator_test.go delete mode 100644 core/bloombits/matcher.go delete mode 100644 core/bloombits/matcher_test.go delete mode 100644 core/bloombits/scheduler.go delete mode 100644 core/bloombits/scheduler_test.go delete mode 100644 core/chain_indexer.go delete mode 100644 core/chain_indexer_test.go delete mode 100644 eth/bloombits.go diff --git a/core/blockchain.go b/core/blockchain.go index 2024c63b80..2bf7fba427 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -906,7 +906,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha rawdb.DeleteBody(db, hash, num) rawdb.DeleteReceipts(db, hash, num) } - // Todo(rjl493456442) txlookup, bloombits, etc + // Todo(rjl493456442) txlookup, log index, etc } // If SetHead was only called as a chain reparation method, try to skip // touching the header chain altogether, unless the freezer is broken diff --git a/core/bloom_indexer.go b/core/bloom_indexer.go deleted file mode 100644 index 68a35d811e..0000000000 --- a/core/bloom_indexer.go +++ /dev/null @@ -1,92 +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 core - -import ( - "context" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/bitutil" - "github.com/ethereum/go-ethereum/core/bloombits" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" -) - -const ( - // bloomThrottling is the time to wait between processing two consecutive index - // sections. It's useful during chain upgrades to prevent disk overload. - bloomThrottling = 100 * time.Millisecond -) - -// BloomIndexer implements a core.ChainIndexer, building up a rotated bloom bits index -// for the Ethereum header bloom filters, permitting blazing fast filtering. -type BloomIndexer struct { - size uint64 // section size to generate bloombits for - db ethdb.Database // database instance to write index data and metadata into - gen *bloombits.Generator // generator to rotate the bloom bits crating the bloom index - section uint64 // Section is the section number being processed currently - head common.Hash // Head is the hash of the last header processed -} - -// NewBloomIndexer returns a chain indexer that generates bloom bits data for the -// canonical chain for fast logs filtering. -func NewBloomIndexer(db ethdb.Database, size, confirms uint64) *ChainIndexer { - backend := &BloomIndexer{ - db: db, - size: size, - } - table := rawdb.NewTable(db, string(rawdb.BloomBitsIndexPrefix)) - - return NewChainIndexer(db, table, backend, size, confirms, bloomThrottling, "bloombits") -} - -// Reset implements core.ChainIndexerBackend, starting a new bloombits index -// section. -func (b *BloomIndexer) Reset(ctx context.Context, section uint64, lastSectionHead common.Hash) error { - gen, err := bloombits.NewGenerator(uint(b.size)) - b.gen, b.section, b.head = gen, section, common.Hash{} - return err -} - -// Process implements core.ChainIndexerBackend, adding a new header's bloom into -// the index. -func (b *BloomIndexer) Process(ctx context.Context, header *types.Header) error { - b.gen.AddBloom(uint(header.Number.Uint64()-b.section*b.size), header.Bloom) - b.head = header.Hash() - return nil -} - -// Commit implements core.ChainIndexerBackend, finalizing the bloom section and -// writing it out into the database. -func (b *BloomIndexer) Commit() error { - batch := b.db.NewBatchWithSize((int(b.size) / 8) * types.BloomBitLength) - for i := 0; i < types.BloomBitLength; i++ { - bits, err := b.gen.Bitset(uint(i)) - if err != nil { - return err - } - rawdb.WriteBloomBits(batch, uint(i), b.section, b.head, bitutil.CompressBytes(bits)) - } - return batch.Write() -} - -// Prune returns an empty error since we don't support pruning here. -func (b *BloomIndexer) Prune(threshold uint64) error { - return nil -} diff --git a/core/bloombits/doc.go b/core/bloombits/doc.go deleted file mode 100644 index 3d159e74f7..0000000000 --- a/core/bloombits/doc.go +++ /dev/null @@ -1,18 +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 bloombits implements bloom filtering on batches of data. -package bloombits diff --git a/core/bloombits/generator.go b/core/bloombits/generator.go deleted file mode 100644 index 646151db0b..0000000000 --- a/core/bloombits/generator.go +++ /dev/null @@ -1,98 +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 bloombits - -import ( - "errors" - - "github.com/ethereum/go-ethereum/core/types" -) - -var ( - // errSectionOutOfBounds is returned if the user tried to add more bloom filters - // to the batch than available space, or if tries to retrieve above the capacity. - errSectionOutOfBounds = errors.New("section out of bounds") - - // errBloomBitOutOfBounds is returned if the user tried to retrieve specified - // bit bloom above the capacity. - errBloomBitOutOfBounds = errors.New("bloom bit out of bounds") -) - -// Generator takes a number of bloom filters and generates the rotated bloom bits -// to be used for batched filtering. -type Generator struct { - blooms [types.BloomBitLength][]byte // Rotated blooms for per-bit matching - sections uint // Number of sections to batch together - nextSec uint // Next section to set when adding a bloom -} - -// NewGenerator creates a rotated bloom generator that can iteratively fill a -// batched bloom filter's bits. -func NewGenerator(sections uint) (*Generator, error) { - if sections%8 != 0 { - return nil, errors.New("section count not multiple of 8") - } - b := &Generator{sections: sections} - for i := 0; i < types.BloomBitLength; i++ { - b.blooms[i] = make([]byte, sections/8) - } - return b, nil -} - -// AddBloom takes a single bloom filter and sets the corresponding bit column -// in memory accordingly. -func (b *Generator) AddBloom(index uint, bloom types.Bloom) error { - // Make sure we're not adding more bloom filters than our capacity - if b.nextSec >= b.sections { - return errSectionOutOfBounds - } - if b.nextSec != index { - return errors.New("bloom filter with unexpected index") - } - // Rotate the bloom and insert into our collection - byteIndex := b.nextSec / 8 - bitIndex := byte(7 - b.nextSec%8) - for byt := 0; byt < types.BloomByteLength; byt++ { - bloomByte := bloom[types.BloomByteLength-1-byt] - if bloomByte == 0 { - continue - } - base := 8 * byt - b.blooms[base+7][byteIndex] |= ((bloomByte >> 7) & 1) << bitIndex - b.blooms[base+6][byteIndex] |= ((bloomByte >> 6) & 1) << bitIndex - b.blooms[base+5][byteIndex] |= ((bloomByte >> 5) & 1) << bitIndex - b.blooms[base+4][byteIndex] |= ((bloomByte >> 4) & 1) << bitIndex - b.blooms[base+3][byteIndex] |= ((bloomByte >> 3) & 1) << bitIndex - b.blooms[base+2][byteIndex] |= ((bloomByte >> 2) & 1) << bitIndex - b.blooms[base+1][byteIndex] |= ((bloomByte >> 1) & 1) << bitIndex - b.blooms[base][byteIndex] |= (bloomByte & 1) << bitIndex - } - b.nextSec++ - return nil -} - -// Bitset returns the bit vector belonging to the given bit index after all -// blooms have been added. -func (b *Generator) Bitset(idx uint) ([]byte, error) { - if b.nextSec != b.sections { - return nil, errors.New("bloom not fully generated yet") - } - if idx >= types.BloomBitLength { - return nil, errBloomBitOutOfBounds - } - return b.blooms[idx], nil -} diff --git a/core/bloombits/generator_test.go b/core/bloombits/generator_test.go deleted file mode 100644 index ac1aee0b25..0000000000 --- a/core/bloombits/generator_test.go +++ /dev/null @@ -1,100 +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 bloombits - -import ( - "bytes" - crand "crypto/rand" - "math/rand" - "testing" - - "github.com/ethereum/go-ethereum/core/types" -) - -// Tests that batched bloom bits are correctly rotated from the input bloom -// filters. -func TestGenerator(t *testing.T) { - // Generate the input and the rotated output - var input, output [types.BloomBitLength][types.BloomByteLength]byte - - for i := 0; i < types.BloomBitLength; i++ { - for j := 0; j < types.BloomBitLength; j++ { - bit := byte(rand.Int() % 2) - - input[i][j/8] |= bit << byte(7-j%8) - output[types.BloomBitLength-1-j][i/8] |= bit << byte(7-i%8) - } - } - // Crunch the input through the generator and verify the result - gen, err := NewGenerator(types.BloomBitLength) - if err != nil { - t.Fatalf("failed to create bloombit generator: %v", err) - } - for i, bloom := range input { - if err := gen.AddBloom(uint(i), bloom); err != nil { - t.Fatalf("bloom %d: failed to add: %v", i, err) - } - } - for i, want := range output { - have, err := gen.Bitset(uint(i)) - if err != nil { - t.Fatalf("output %d: failed to retrieve bits: %v", i, err) - } - if !bytes.Equal(have, want[:]) { - t.Errorf("output %d: bit vector mismatch have %x, want %x", i, have, want) - } - } -} - -func BenchmarkGenerator(b *testing.B) { - var input [types.BloomBitLength][types.BloomByteLength]byte - b.Run("empty", func(b *testing.B) { - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - // Crunch the input through the generator and verify the result - gen, err := NewGenerator(types.BloomBitLength) - if err != nil { - b.Fatalf("failed to create bloombit generator: %v", err) - } - for j, bloom := range &input { - if err := gen.AddBloom(uint(j), bloom); err != nil { - b.Fatalf("bloom %d: failed to add: %v", i, err) - } - } - } - }) - for i := 0; i < types.BloomBitLength; i++ { - crand.Read(input[i][:]) - } - b.Run("random", func(b *testing.B) { - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - // Crunch the input through the generator and verify the result - gen, err := NewGenerator(types.BloomBitLength) - if err != nil { - b.Fatalf("failed to create bloombit generator: %v", err) - } - for j, bloom := range &input { - if err := gen.AddBloom(uint(j), bloom); err != nil { - b.Fatalf("bloom %d: failed to add: %v", i, err) - } - } - } - }) -} diff --git a/core/bloombits/matcher.go b/core/bloombits/matcher.go deleted file mode 100644 index 486581fe23..0000000000 --- a/core/bloombits/matcher.go +++ /dev/null @@ -1,649 +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 bloombits - -import ( - "bytes" - "context" - "errors" - "math" - "sort" - "sync" - "sync/atomic" - "time" - - "github.com/ethereum/go-ethereum/common/bitutil" - "github.com/ethereum/go-ethereum/crypto" -) - -// bloomIndexes represents the bit indexes inside the bloom filter that belong -// to some key. -type bloomIndexes [3]uint - -// calcBloomIndexes returns the bloom filter bit indexes belonging to the given key. -func calcBloomIndexes(b []byte) bloomIndexes { - b = crypto.Keccak256(b) - - var idxs bloomIndexes - for i := 0; i < len(idxs); i++ { - idxs[i] = (uint(b[2*i])<<8)&2047 + uint(b[2*i+1]) - } - return idxs -} - -// partialMatches with a non-nil vector represents a section in which some sub- -// matchers have already found potential matches. Subsequent sub-matchers will -// binary AND their matches with this vector. If vector is nil, it represents a -// section to be processed by the first sub-matcher. -type partialMatches struct { - section uint64 - bitset []byte -} - -// Retrieval represents a request for retrieval task assignments for a given -// bit with the given number of fetch elements, or a response for such a request. -// It can also have the actual results set to be used as a delivery data struct. -// -// The context and error fields are used by the light client to terminate matching -// early if an error is encountered on some path of the pipeline. -type Retrieval struct { - Bit uint - Sections []uint64 - Bitsets [][]byte - - Context context.Context - Error error -} - -// Matcher is a pipelined system of schedulers and logic matchers which perform -// binary AND/OR operations on the bit-streams, creating a stream of potential -// blocks to inspect for data content. -type Matcher struct { - sectionSize uint64 // Size of the data batches to filter on - - filters [][]bloomIndexes // Filter the system is matching for - schedulers map[uint]*scheduler // Retrieval schedulers for loading bloom bits - - retrievers chan chan uint // Retriever processes waiting for bit allocations - counters chan chan uint // Retriever processes waiting for task count reports - retrievals chan chan *Retrieval // Retriever processes waiting for task allocations - deliveries chan *Retrieval // Retriever processes waiting for task response deliveries - - running atomic.Bool // Atomic flag whether a session is live or not -} - -// NewMatcher creates a new pipeline for retrieving bloom bit streams and doing -// address and topic filtering on them. Setting a filter component to `nil` is -// allowed and will result in that filter rule being skipped (OR 0x11...1). -func NewMatcher(sectionSize uint64, filters [][][]byte) *Matcher { - // Create the matcher instance - m := &Matcher{ - sectionSize: sectionSize, - schedulers: make(map[uint]*scheduler), - retrievers: make(chan chan uint), - counters: make(chan chan uint), - retrievals: make(chan chan *Retrieval), - deliveries: make(chan *Retrieval), - } - // Calculate the bloom bit indexes for the groups we're interested in - m.filters = nil - - for _, filter := range filters { - // Gather the bit indexes of the filter rule, special casing the nil filter - if len(filter) == 0 { - continue - } - bloomBits := make([]bloomIndexes, len(filter)) - for i, clause := range filter { - if clause == nil { - bloomBits = nil - break - } - bloomBits[i] = calcBloomIndexes(clause) - } - // Accumulate the filter rules if no nil rule was within - if bloomBits != nil { - m.filters = append(m.filters, bloomBits) - } - } - // For every bit, create a scheduler to load/download the bit vectors - for _, bloomIndexLists := range m.filters { - for _, bloomIndexList := range bloomIndexLists { - for _, bloomIndex := range bloomIndexList { - m.addScheduler(bloomIndex) - } - } - } - return m -} - -// addScheduler adds a bit stream retrieval scheduler for the given bit index if -// it has not existed before. If the bit is already selected for filtering, the -// existing scheduler can be used. -func (m *Matcher) addScheduler(idx uint) { - if _, ok := m.schedulers[idx]; ok { - return - } - m.schedulers[idx] = newScheduler(idx) -} - -// Start starts the matching process and returns a stream of bloom matches in -// a given range of blocks. If there are no more matches in the range, the result -// channel is closed. -func (m *Matcher) Start(ctx context.Context, begin, end uint64, results chan uint64) (*MatcherSession, error) { - // Make sure we're not creating concurrent sessions - if m.running.Swap(true) { - return nil, errors.New("matcher already running") - } - defer m.running.Store(false) - - // Initiate a new matching round - session := &MatcherSession{ - matcher: m, - quit: make(chan struct{}), - ctx: ctx, - } - for _, scheduler := range m.schedulers { - scheduler.reset() - } - sink := m.run(begin, end, cap(results), session) - - // Read the output from the result sink and deliver to the user - session.pend.Add(1) - go func() { - defer session.pend.Done() - defer close(results) - - for { - select { - case <-session.quit: - return - - case res, ok := <-sink: - // New match result found - if !ok { - return - } - // Calculate the first and last blocks of the section - sectionStart := res.section * m.sectionSize - - first := sectionStart - if begin > first { - first = begin - } - last := sectionStart + m.sectionSize - 1 - if end < last { - last = end - } - // Iterate over all the blocks in the section and return the matching ones - for i := first; i <= last; i++ { - // Skip the entire byte if no matches are found inside (and we're processing an entire byte!) - next := res.bitset[(i-sectionStart)/8] - if next == 0 { - if i%8 == 0 { - i += 7 - } - continue - } - // Some bit it set, do the actual submatching - if bit := 7 - i%8; next&(1<= req.section }) - requests[req.bit] = append(queue[:index], append([]uint64{req.section}, queue[index:]...)...) - - // If it's a new bit and we have waiting fetchers, allocate to them - if len(queue) == 0 { - assign(req.bit) - } - - case fetcher := <-retrievers: - // New retriever arrived, find the lowest section-ed bit to assign - bit, best := uint(0), uint64(math.MaxUint64) - for idx := range unallocs { - if requests[idx][0] < best { - bit, best = idx, requests[idx][0] - } - } - // Stop tracking this bit (and alloc notifications if no more work is available) - delete(unallocs, bit) - if len(unallocs) == 0 { - retrievers = nil - } - allocs++ - fetcher <- bit - - case fetcher := <-m.counters: - // New task count request arrives, return number of items - fetcher <- uint(len(requests[<-fetcher])) - - case fetcher := <-m.retrievals: - // New fetcher waiting for tasks to retrieve, assign - task := <-fetcher - if want := len(task.Sections); want >= len(requests[task.Bit]) { - task.Sections = requests[task.Bit] - delete(requests, task.Bit) - } else { - task.Sections = append(task.Sections[:0], requests[task.Bit][:want]...) - requests[task.Bit] = append(requests[task.Bit][:0], requests[task.Bit][want:]...) - } - fetcher <- task - - // If anything was left unallocated, try to assign to someone else - if len(requests[task.Bit]) > 0 { - assign(task.Bit) - } - - case result := <-m.deliveries: - // New retrieval task response from fetcher, split out missing sections and - // deliver complete ones - var ( - sections = make([]uint64, 0, len(result.Sections)) - bitsets = make([][]byte, 0, len(result.Bitsets)) - missing = make([]uint64, 0, len(result.Sections)) - ) - for i, bitset := range result.Bitsets { - if len(bitset) == 0 { - missing = append(missing, result.Sections[i]) - continue - } - sections = append(sections, result.Sections[i]) - bitsets = append(bitsets, bitset) - } - m.schedulers[result.Bit].deliver(sections, bitsets) - allocs-- - - // Reschedule missing sections and allocate bit if newly available - if len(missing) > 0 { - queue := requests[result.Bit] - for _, section := range missing { - index := sort.Search(len(queue), func(i int) bool { return queue[i] >= section }) - queue = append(queue[:index], append([]uint64{section}, queue[index:]...)...) - } - requests[result.Bit] = queue - - if len(queue) == len(missing) { - assign(result.Bit) - } - } - - // End the session when all pending deliveries have arrived. - if shutdown == nil && allocs == 0 { - return - } - } - } -} - -// MatcherSession is returned by a started matcher to be used as a terminator -// for the actively running matching operation. -type MatcherSession struct { - matcher *Matcher - - closer sync.Once // Sync object to ensure we only ever close once - quit chan struct{} // Quit channel to request pipeline termination - - ctx context.Context // Context used by the light client to abort filtering - err error // Global error to track retrieval failures deep in the chain - errLock sync.Mutex - - pend sync.WaitGroup -} - -// Close stops the matching process and waits for all subprocesses to terminate -// before returning. The timeout may be used for graceful shutdown, allowing the -// currently running retrievals to complete before this time. -func (s *MatcherSession) Close() { - s.closer.Do(func() { - // Signal termination and wait for all goroutines to tear down - close(s.quit) - s.pend.Wait() - }) -} - -// Error returns any failure encountered during the matching session. -func (s *MatcherSession) Error() error { - s.errLock.Lock() - defer s.errLock.Unlock() - - return s.err -} - -// allocateRetrieval assigns a bloom bit index to a client process that can either -// immediately request and fetch the section contents assigned to this bit or wait -// a little while for more sections to be requested. -func (s *MatcherSession) allocateRetrieval() (uint, bool) { - fetcher := make(chan uint) - - select { - case <-s.quit: - return 0, false - case s.matcher.retrievers <- fetcher: - bit, ok := <-fetcher - return bit, ok - } -} - -// pendingSections returns the number of pending section retrievals belonging to -// the given bloom bit index. -func (s *MatcherSession) pendingSections(bit uint) int { - fetcher := make(chan uint) - - select { - case <-s.quit: - return 0 - case s.matcher.counters <- fetcher: - fetcher <- bit - return int(<-fetcher) - } -} - -// allocateSections assigns all or part of an already allocated bit-task queue -// to the requesting process. -func (s *MatcherSession) allocateSections(bit uint, count int) []uint64 { - fetcher := make(chan *Retrieval) - - select { - case <-s.quit: - return nil - case s.matcher.retrievals <- fetcher: - task := &Retrieval{ - Bit: bit, - Sections: make([]uint64, count), - } - fetcher <- task - return (<-fetcher).Sections - } -} - -// deliverSections delivers a batch of section bit-vectors for a specific bloom -// bit index to be injected into the processing pipeline. -func (s *MatcherSession) deliverSections(bit uint, sections []uint64, bitsets [][]byte) { - s.matcher.deliveries <- &Retrieval{Bit: bit, Sections: sections, Bitsets: bitsets} -} - -// Multiplex polls the matcher session for retrieval tasks and multiplexes it into -// the requested retrieval queue to be serviced together with other sessions. -// -// This method will block for the lifetime of the session. Even after termination -// 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() - if !ok { - return - } - // 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 - s.allocateSections(bit, 0) - s.deliverSections(bit, []uint64{}, [][]byte{}) - return - - case <-waitTimer.C: - // Throttling up, fetch whatever is available - } - } - // Allocate as much as we can handle and request servicing - sections := s.allocateSections(bit, batch) - request := make(chan *Retrieval) - - select { - case <-s.quit: - // Session terminating, we can't meaningfully service, abort - s.deliverSections(bit, sections, make([][]byte, len(sections))) - return - - case mux <- request: - // Retrieval accepted, something must arrive before we're aborting - request <- &Retrieval{Bit: bit, Sections: sections, Context: s.ctx} - - result := <-request - - // Deliver a result before s.Close() to avoid a deadlock - s.deliverSections(result.Bit, result.Sections, result.Bitsets) - - if result.Error != nil { - s.errLock.Lock() - s.err = result.Error - s.errLock.Unlock() - s.Close() - } - } - } -} diff --git a/core/bloombits/matcher_test.go b/core/bloombits/matcher_test.go deleted file mode 100644 index 7f3d5f279c..0000000000 --- a/core/bloombits/matcher_test.go +++ /dev/null @@ -1,292 +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 bloombits - -import ( - "context" - "math/rand" - "sync/atomic" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" -) - -const testSectionSize = 4096 - -// Tests that wildcard filter rules (nil) can be specified and are handled well. -func TestMatcherWildcards(t *testing.T) { - t.Parallel() - matcher := NewMatcher(testSectionSize, [][][]byte{ - {common.Address{}.Bytes(), common.Address{0x01}.Bytes()}, // Default address is not a wildcard - {common.Hash{}.Bytes(), common.Hash{0x01}.Bytes()}, // Default hash is not a wildcard - {common.Hash{0x01}.Bytes()}, // Plain rule, sanity check - {common.Hash{0x01}.Bytes(), nil}, // Wildcard suffix, drop rule - {nil, common.Hash{0x01}.Bytes()}, // Wildcard prefix, drop rule - {nil, nil}, // Wildcard combo, drop rule - {}, // Inited wildcard rule, drop rule - nil, // Proper wildcard rule, drop rule - }) - if len(matcher.filters) != 3 { - t.Fatalf("filter system size mismatch: have %d, want %d", len(matcher.filters), 3) - } - if len(matcher.filters[0]) != 2 { - t.Fatalf("address clause size mismatch: have %d, want %d", len(matcher.filters[0]), 2) - } - if len(matcher.filters[1]) != 2 { - t.Fatalf("combo topic clause size mismatch: have %d, want %d", len(matcher.filters[1]), 2) - } - if len(matcher.filters[2]) != 1 { - t.Fatalf("singletone topic clause size mismatch: have %d, want %d", len(matcher.filters[2]), 1) - } -} - -// Tests the matcher pipeline on a single continuous workflow without interrupts. -func TestMatcherContinuous(t *testing.T) { - t.Parallel() - testMatcherDiffBatches(t, [][]bloomIndexes{{{10, 20, 30}}}, 0, 100000, false, 75) - testMatcherDiffBatches(t, [][]bloomIndexes{{{32, 3125, 100}}, {{40, 50, 10}}}, 0, 100000, false, 81) - testMatcherDiffBatches(t, [][]bloomIndexes{{{4, 8, 11}, {7, 8, 17}}, {{9, 9, 12}, {15, 20, 13}}, {{18, 15, 15}, {12, 10, 4}}}, 0, 10000, false, 36) -} - -// Tests the matcher pipeline on a constantly interrupted and resumed work pattern -// with the aim of ensuring data items are requested only once. -func TestMatcherIntermittent(t *testing.T) { - t.Parallel() - testMatcherDiffBatches(t, [][]bloomIndexes{{{10, 20, 30}}}, 0, 100000, true, 75) - testMatcherDiffBatches(t, [][]bloomIndexes{{{32, 3125, 100}}, {{40, 50, 10}}}, 0, 100000, true, 81) - testMatcherDiffBatches(t, [][]bloomIndexes{{{4, 8, 11}, {7, 8, 17}}, {{9, 9, 12}, {15, 20, 13}}, {{18, 15, 15}, {12, 10, 4}}}, 0, 10000, true, 36) -} - -// Tests the matcher pipeline on random input to hopefully catch anomalies. -func TestMatcherRandom(t *testing.T) { - t.Parallel() - for i := 0; i < 10; i++ { - testMatcherBothModes(t, makeRandomIndexes([]int{1}, 50), 0, 10000, 0) - testMatcherBothModes(t, makeRandomIndexes([]int{3}, 50), 0, 10000, 0) - testMatcherBothModes(t, makeRandomIndexes([]int{2, 2, 2}, 20), 0, 10000, 0) - testMatcherBothModes(t, makeRandomIndexes([]int{5, 5, 5}, 50), 0, 10000, 0) - testMatcherBothModes(t, makeRandomIndexes([]int{4, 4, 4}, 20), 0, 10000, 0) - } -} - -// Tests that the matcher can properly find matches if the starting block is -// shifted from a multiple of 8. This is needed to cover an optimisation with -// bitset matching https://github.com/ethereum/go-ethereum/issues/15309. -func TestMatcherShifted(t *testing.T) { - t.Parallel() - // Block 0 always matches in the tests, skip ahead of first 8 blocks with the - // start to get a potential zero byte in the matcher bitset. - - // To keep the second bitset byte zero, the filter must only match for the first - // time in block 16, so doing an all-16 bit filter should suffice. - - // To keep the starting block non divisible by 8, block number 9 is the first - // that would introduce a shift and not match block 0. - testMatcherBothModes(t, [][]bloomIndexes{{{16, 16, 16}}}, 9, 64, 0) -} - -// Tests that matching on everything doesn't crash (special case internally). -func TestWildcardMatcher(t *testing.T) { - t.Parallel() - testMatcherBothModes(t, nil, 0, 10000, 0) -} - -// makeRandomIndexes generates a random filter system, composed of multiple filter -// criteria, each having one bloom list component for the address and arbitrarily -// many topic bloom list components. -func makeRandomIndexes(lengths []int, max int) [][]bloomIndexes { - res := make([][]bloomIndexes, len(lengths)) - for i, topics := range lengths { - res[i] = make([]bloomIndexes, topics) - for j := 0; j < topics; j++ { - for k := 0; k < len(res[i][j]); k++ { - res[i][j][k] = uint(rand.Intn(max-1) + 2) - } - } - } - return res -} - -// testMatcherDiffBatches runs the given matches test in single-delivery and also -// in batches delivery mode, verifying that all kinds of deliveries are handled -// correctly within. -func testMatcherDiffBatches(t *testing.T, filter [][]bloomIndexes, start, blocks uint64, intermittent bool, retrievals uint32) { - singleton := testMatcher(t, filter, start, blocks, intermittent, retrievals, 1) - batched := testMatcher(t, filter, start, blocks, intermittent, retrievals, 16) - - if singleton != batched { - t.Errorf("filter = %v blocks = %v intermittent = %v: request count mismatch, %v in singleton vs. %v in batched mode", filter, blocks, intermittent, singleton, batched) - } -} - -// testMatcherBothModes runs the given matcher test in both continuous as well as -// in intermittent mode, verifying that the request counts match each other. -func testMatcherBothModes(t *testing.T, filter [][]bloomIndexes, start, blocks uint64, retrievals uint32) { - continuous := testMatcher(t, filter, start, blocks, false, retrievals, 16) - intermittent := testMatcher(t, filter, start, blocks, true, retrievals, 16) - - if continuous != intermittent { - t.Errorf("filter = %v blocks = %v: request count mismatch, %v in continuous vs. %v in intermittent mode", filter, blocks, continuous, intermittent) - } -} - -// testMatcher is a generic tester to run the given matcher test and return the -// number of requests made for cross validation between different modes. -func testMatcher(t *testing.T, filter [][]bloomIndexes, start, blocks uint64, intermittent bool, retrievals uint32, maxReqCount int) uint32 { - // Create a new matcher an simulate our explicit random bitsets - matcher := NewMatcher(testSectionSize, nil) - matcher.filters = filter - - for _, rule := range filter { - for _, topic := range rule { - for _, bit := range topic { - matcher.addScheduler(bit) - } - } - } - // Track the number of retrieval requests made - var requested atomic.Uint32 - - // Start the matching session for the filter and the retriever goroutines - quit := make(chan struct{}) - matches := make(chan uint64, 16) - - session, err := matcher.Start(context.Background(), start, blocks-1, matches) - if err != nil { - t.Fatalf("failed to stat matcher session: %v", err) - } - startRetrievers(session, quit, &requested, maxReqCount) - - // Iterate over all the blocks and verify that the pipeline produces the correct matches - for i := start; i < blocks; i++ { - if expMatch3(filter, i) { - match, ok := <-matches - if !ok { - t.Errorf("filter = %v blocks = %v intermittent = %v: expected #%v, results channel closed", filter, blocks, intermittent, i) - return 0 - } - if match != i { - t.Errorf("filter = %v blocks = %v intermittent = %v: expected #%v, got #%v", filter, blocks, intermittent, i, match) - } - // If we're testing intermittent mode, abort and restart the pipeline - if intermittent { - session.Close() - close(quit) - - quit = make(chan struct{}) - matches = make(chan uint64, 16) - - session, err = matcher.Start(context.Background(), i+1, blocks-1, matches) - if err != nil { - t.Fatalf("failed to stat matcher session: %v", err) - } - startRetrievers(session, quit, &requested, maxReqCount) - } - } - } - // Ensure the result channel is torn down after the last block - match, ok := <-matches - if ok { - t.Errorf("filter = %v blocks = %v intermittent = %v: expected closed channel, got #%v", filter, blocks, intermittent, match) - } - // Clean up the session and ensure we match the expected retrieval count - session.Close() - close(quit) - - if retrievals != 0 && requested.Load() != retrievals { - t.Errorf("filter = %v blocks = %v intermittent = %v: request count mismatch, have #%v, want #%v", filter, blocks, intermittent, requested.Load(), retrievals) - } - return requested.Load() -} - -// startRetrievers starts a batch of goroutines listening for section requests -// and serving them. -func startRetrievers(session *MatcherSession, quit chan struct{}, retrievals *atomic.Uint32, batch int) { - requests := make(chan chan *Retrieval) - - for i := 0; i < 10; i++ { - // Start a multiplexer to test multiple threaded execution - go session.Multiplex(batch, 100*time.Microsecond, requests) - - // Start a services to match the above multiplexer - go func() { - for { - // Wait for a service request or a shutdown - select { - case <-quit: - return - - case request := <-requests: - task := <-request - - task.Bitsets = make([][]byte, len(task.Sections)) - for i, section := range task.Sections { - if rand.Int()%4 != 0 { // Handle occasional missing deliveries - task.Bitsets[i] = generateBitset(task.Bit, section) - retrievals.Add(1) - } - } - request <- task - } - } - }() - } -} - -// generateBitset generates the rotated bitset for the given bloom bit and section -// numbers. -func generateBitset(bit uint, section uint64) []byte { - bitset := make([]byte, testSectionSize/8) - for i := 0; i < len(bitset); i++ { - for b := 0; b < 8; b++ { - blockIdx := section*testSectionSize + uint64(i*8+b) - bitset[i] += bitset[i] - if (blockIdx % uint64(bit)) == 0 { - bitset[i]++ - } - } - } - return bitset -} - -func expMatch1(filter bloomIndexes, i uint64) bool { - for _, ii := range filter { - if (i % uint64(ii)) != 0 { - return false - } - } - return true -} - -func expMatch2(filter []bloomIndexes, i uint64) bool { - for _, ii := range filter { - if expMatch1(ii, i) { - return true - } - } - return false -} - -func expMatch3(filter [][]bloomIndexes, i uint64) bool { - for _, ii := range filter { - if !expMatch2(ii, i) { - return false - } - } - return true -} diff --git a/core/bloombits/scheduler.go b/core/bloombits/scheduler.go deleted file mode 100644 index a523bc55ab..0000000000 --- a/core/bloombits/scheduler.go +++ /dev/null @@ -1,181 +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 bloombits - -import ( - "sync" -) - -// 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 bit-vector from - bit uint // Bit index within the section to retrieve the vector of -} - -// response represents the state of a requested bit-vector through a scheduler. -type response struct { - cached []byte // Cached bits to dedup multiple requests - done chan struct{} // Channel to allow waiting for completion -} - -// scheduler handles the scheduling of bloom-filter retrieval operations for -// entire section-batches belonging to a single bloom bit. Beside scheduling the -// retrieval operations, this struct also deduplicates the requests and caches -// the results to minimize network/database overhead even in complex filtering -// scenarios. -type scheduler struct { - bit uint // Index of the bit in the bloom filter this scheduler is responsible for - responses map[uint64]*response // Currently pending retrieval requests or already cached responses - lock sync.Mutex // Lock protecting the responses from concurrent access -} - -// newScheduler creates a new bloom-filter retrieval scheduler for a specific -// bit index. -func newScheduler(idx uint) *scheduler { - return &scheduler{ - bit: idx, - responses: make(map[uint64]*response), - } -} - -// run creates a retrieval pipeline, receiving section indexes from sections and -// returning the results in the same order through the done channel. Concurrent -// runs of the same scheduler are allowed, leading to retrieval task deduplication. -func (s *scheduler) run(sections chan uint64, dist chan *request, done chan []byte, quit chan struct{}, wg *sync.WaitGroup) { - // Create a forwarder channel between requests and responses of the same size as - // the distribution channel (since that will block the pipeline anyway). - pend := make(chan uint64, cap(dist)) - - // Start the pipeline schedulers to forward between user -> distributor -> user - wg.Add(2) - go s.scheduleRequests(sections, dist, pend, quit, wg) - go s.scheduleDeliveries(pend, done, quit, wg) -} - -// reset cleans up any leftovers from previous runs. This is required before a -// restart to ensure the no previously requested but never delivered state will -// cause a lockup. -func (s *scheduler) reset() { - s.lock.Lock() - defer s.lock.Unlock() - - for section, res := range s.responses { - if res.cached == nil { - delete(s.responses, section) - } - } -} - -// scheduleRequests reads section retrieval requests from the input channel, -// deduplicates the stream and pushes unique retrieval tasks into the distribution -// channel for a database or network layer to honour. -func (s *scheduler) scheduleRequests(reqs chan uint64, dist chan *request, pend chan uint64, quit chan struct{}, wg *sync.WaitGroup) { - // Clean up the goroutine and pipeline when done - defer wg.Done() - defer close(pend) - - // Keep reading and scheduling section requests - for { - select { - case <-quit: - return - - case section, ok := <-reqs: - // New section retrieval requested - if !ok { - return - } - // Deduplicate retrieval requests - unique := false - - s.lock.Lock() - if s.responses[section] == nil { - s.responses[section] = &response{ - done: make(chan struct{}), - } - unique = true - } - s.lock.Unlock() - - // Schedule the section for retrieval and notify the deliverer to expect this section - if unique { - select { - case <-quit: - return - case dist <- &request{bit: s.bit, section: section}: - } - } - select { - case <-quit: - return - case pend <- section: - } - } - } -} - -// scheduleDeliveries reads section acceptance notifications and waits for them -// to be delivered, pushing them into the output data buffer. -func (s *scheduler) scheduleDeliveries(pend chan uint64, done chan []byte, quit chan struct{}, wg *sync.WaitGroup) { - // Clean up the goroutine and pipeline when done - defer wg.Done() - defer close(done) - - // Keep reading notifications and scheduling deliveries - for { - select { - case <-quit: - return - - case idx, ok := <-pend: - // New section retrieval pending - if !ok { - return - } - // Wait until the request is honoured - s.lock.Lock() - res := s.responses[idx] - s.lock.Unlock() - - select { - case <-quit: - return - case <-res.done: - } - // Deliver the result - select { - case <-quit: - return - case done <- res.cached: - } - } - } -} - -// deliver is called by the request distributor when a reply to a request arrives. -func (s *scheduler) deliver(sections []uint64, data [][]byte) { - s.lock.Lock() - defer s.lock.Unlock() - - for i, section := range sections { - if res := s.responses[section]; res != nil && res.cached == nil { // Avoid non-requests and double deliveries - res.cached = data[i] - close(res.done) - } - } -} diff --git a/core/bloombits/scheduler_test.go b/core/bloombits/scheduler_test.go deleted file mode 100644 index dcaaa91525..0000000000 --- a/core/bloombits/scheduler_test.go +++ /dev/null @@ -1,103 +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 bloombits - -import ( - "bytes" - "math/big" - "sync" - "sync/atomic" - "testing" -) - -// Tests that the scheduler can deduplicate and forward retrieval requests to -// underlying fetchers and serve responses back, irrelevant of the concurrency -// of the requesting clients or serving data fetchers. -func TestSchedulerSingleClientSingleFetcher(t *testing.T) { testScheduler(t, 1, 1, 5000) } -func TestSchedulerSingleClientMultiFetcher(t *testing.T) { testScheduler(t, 1, 10, 5000) } -func TestSchedulerMultiClientSingleFetcher(t *testing.T) { testScheduler(t, 10, 1, 5000) } -func TestSchedulerMultiClientMultiFetcher(t *testing.T) { testScheduler(t, 10, 10, 5000) } - -func testScheduler(t *testing.T, clients int, fetchers int, requests int) { - t.Parallel() - f := newScheduler(0) - - // Create a batch of handler goroutines that respond to bloom bit requests and - // deliver them to the scheduler. - var fetchPend sync.WaitGroup - fetchPend.Add(fetchers) - defer fetchPend.Wait() - - fetch := make(chan *request, 16) - defer close(fetch) - - var delivered atomic.Uint32 - for i := 0; i < fetchers; i++ { - go func() { - defer fetchPend.Done() - - for req := range fetch { - delivered.Add(1) - - f.deliver([]uint64{ - req.section + uint64(requests), // Non-requested data (ensure it doesn't go out of bounds) - req.section, // Requested data - req.section, // Duplicated data (ensure it doesn't double close anything) - }, [][]byte{ - {}, - new(big.Int).SetUint64(req.section).Bytes(), - new(big.Int).SetUint64(req.section).Bytes(), - }) - } - }() - } - // Start a batch of goroutines to concurrently run scheduling tasks - quit := make(chan struct{}) - - var pend sync.WaitGroup - pend.Add(clients) - - for i := 0; i < clients; i++ { - go func() { - defer pend.Done() - - in := make(chan uint64, 16) - out := make(chan []byte, 16) - - f.run(in, fetch, out, quit, &pend) - - go func() { - for j := 0; j < requests; j++ { - in <- uint64(j) - } - close(in) - }() - b := new(big.Int) - for j := 0; j < requests; j++ { - bits := <-out - if want := b.SetUint64(uint64(j)).Bytes(); !bytes.Equal(bits, want) { - t.Errorf("vector %d: delivered content mismatch: have %x, want %x", j, bits, want) - } - } - }() - } - pend.Wait() - - if have := delivered.Load(); int(have) != requests { - t.Errorf("request count mismatch: have %v, want %v", have, requests) - } -} diff --git a/core/chain_indexer.go b/core/chain_indexer.go deleted file mode 100644 index 2865daa1ff..0000000000 --- a/core/chain_indexer.go +++ /dev/null @@ -1,522 +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 core - -import ( - "context" - "encoding/binary" - "errors" - "fmt" - "sync" - "sync/atomic" - "time" - - "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/ethdb" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" -) - -// ChainIndexerBackend defines the methods needed to process chain segments in -// the background and write the segment results into the database. These can be -// used to create filter blooms or CHTs. -type ChainIndexerBackend interface { - // Reset initiates the processing of a new chain segment, potentially terminating - // any partially completed operations (in case of a reorg). - Reset(ctx context.Context, section uint64, prevHead common.Hash) error - - // Process crunches through the next header in the chain segment. The caller - // will ensure a sequential order of headers. - Process(ctx context.Context, header *types.Header) error - - // Commit finalizes the section metadata and stores it into the database. - Commit() error - - // Prune deletes the chain index older than the given threshold. - Prune(threshold uint64) error -} - -// ChainIndexerChain interface is used for connecting the indexer to a blockchain -type ChainIndexerChain interface { - // CurrentHeader retrieves the latest locally known header. - CurrentHeader() *types.Header - - // SubscribeChainHeadEvent subscribes to new head header notifications. - SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription -} - -// ChainIndexer does a post-processing job for equally sized sections of the -// canonical chain (like BlooomBits and CHT structures). A ChainIndexer is -// connected to the blockchain through the event system by starting a -// ChainHeadEventLoop in a goroutine. -// -// Further child ChainIndexers can be added which use the output of the parent -// section indexer. These child indexers receive new head notifications only -// after an entire section has been finished or in case of rollbacks that might -// affect already finished sections. -type ChainIndexer struct { - chainDb ethdb.Database // Chain database to index the data from - indexDb ethdb.Database // Prefixed table-view of the db to write index metadata into - backend ChainIndexerBackend // Background processor generating the index data content - children []*ChainIndexer // Child indexers to cascade chain updates to - - active atomic.Bool // Flag whether the event loop was started - update chan struct{} // Notification channel that headers should be processed - quit chan chan error // Quit channel to tear down running goroutines - ctx context.Context - ctxCancel func() - - sectionSize uint64 // Number of blocks in a single chain segment to process - confirmsReq uint64 // Number of confirmations before processing a completed segment - - storedSections uint64 // Number of sections successfully indexed into the database - knownSections uint64 // Number of sections known to be complete (block wise) - cascadedHead uint64 // Block number of the last completed section cascaded to subindexers - - checkpointSections uint64 // Number of sections covered by the checkpoint - checkpointHead common.Hash // Section head belonging to the checkpoint - - throttling time.Duration // Disk throttling to prevent a heavy upgrade from hogging resources - - log log.Logger - lock sync.Mutex -} - -// NewChainIndexer creates a new chain indexer to do background processing on -// chain segments of a given size after certain number of confirmations passed. -// The throttling parameter might be used to prevent database thrashing. -func NewChainIndexer(chainDb ethdb.Database, indexDb ethdb.Database, backend ChainIndexerBackend, section, confirm uint64, throttling time.Duration, kind string) *ChainIndexer { - c := &ChainIndexer{ - chainDb: chainDb, - indexDb: indexDb, - backend: backend, - update: make(chan struct{}, 1), - quit: make(chan chan error), - sectionSize: section, - confirmsReq: confirm, - throttling: throttling, - log: log.New("type", kind), - } - // Initialize database dependent fields and start the updater - c.loadValidSections() - c.ctx, c.ctxCancel = context.WithCancel(context.Background()) - - go c.updateLoop() - - return c -} - -// AddCheckpoint adds a checkpoint. Sections are never processed and the chain -// is not expected to be available before this point. The indexer assumes that -// the backend has sufficient information available to process subsequent sections. -// -// Note: knownSections == 0 and storedSections == checkpointSections until -// syncing reaches the checkpoint -func (c *ChainIndexer) AddCheckpoint(section uint64, shead common.Hash) { - c.lock.Lock() - defer c.lock.Unlock() - - // Short circuit if the given checkpoint is below than local's. - if c.checkpointSections >= section+1 || section < c.storedSections { - return - } - c.checkpointSections = section + 1 - c.checkpointHead = shead - - c.setSectionHead(section, shead) - c.setValidSections(section + 1) -} - -// Start creates a goroutine to feed chain head events into the indexer for -// cascading background processing. Children do not need to be started, they -// are notified about new events by their parents. -func (c *ChainIndexer) Start(chain ChainIndexerChain) { - events := make(chan ChainHeadEvent, 10) - sub := chain.SubscribeChainHeadEvent(events) - - go c.eventLoop(chain.CurrentHeader(), events, sub) -} - -// Close tears down all goroutines belonging to the indexer and returns any error -// that might have occurred internally. -func (c *ChainIndexer) Close() error { - var errs []error - - c.ctxCancel() - - // Tear down the primary update loop - errc := make(chan error) - c.quit <- errc - if err := <-errc; err != nil { - errs = append(errs, err) - } - // If needed, tear down the secondary event loop - if c.active.Load() { - c.quit <- errc - if err := <-errc; err != nil { - errs = append(errs, err) - } - } - // Close all children - for _, child := range c.children { - if err := child.Close(); err != nil { - errs = append(errs, err) - } - } - // Return any failures - switch { - case len(errs) == 0: - return nil - - case len(errs) == 1: - return errs[0] - - default: - return fmt.Errorf("%v", errs) - } -} - -// eventLoop is a secondary - optional - event loop of the indexer which is only -// started for the outermost indexer to push chain head events into a processing -// queue. -func (c *ChainIndexer) eventLoop(currentHeader *types.Header, events chan ChainHeadEvent, sub event.Subscription) { - // Mark the chain indexer as active, requiring an additional teardown - c.active.Store(true) - - defer sub.Unsubscribe() - - // Fire the initial new head event to start any outstanding processing - c.newHead(currentHeader.Number.Uint64(), false) - - var ( - prevHeader = currentHeader - prevHash = currentHeader.Hash() - ) - for { - select { - case errc := <-c.quit: - // Chain indexer terminating, report no failure and abort - errc <- nil - return - - case ev, ok := <-events: - // Received a new event, ensure it's not nil (closing) and update - if !ok { - errc := <-c.quit - errc <- nil - return - } - if ev.Header.ParentHash != prevHash { - // Reorg to the common ancestor if needed (might not exist in light sync mode, skip reorg then) - // TODO(karalabe, zsfelfoldi): This seems a bit brittle, can we detect this case explicitly? - - if rawdb.ReadCanonicalHash(c.chainDb, prevHeader.Number.Uint64()) != prevHash { - if h := rawdb.FindCommonAncestor(c.chainDb, prevHeader, ev.Header); h != nil { - c.newHead(h.Number.Uint64(), true) - } - } - } - c.newHead(ev.Header.Number.Uint64(), false) - - prevHeader, prevHash = ev.Header, ev.Header.Hash() - } - } -} - -// newHead notifies the indexer about new chain heads and/or reorgs. -func (c *ChainIndexer) newHead(head uint64, reorg bool) { - c.lock.Lock() - defer c.lock.Unlock() - - // If a reorg happened, invalidate all sections until that point - if reorg { - // Revert the known section number to the reorg point - known := (head + 1) / c.sectionSize - stored := known - if known < c.checkpointSections { - known = 0 - } - if stored < c.checkpointSections { - stored = c.checkpointSections - } - if known < c.knownSections { - c.knownSections = known - } - // Revert the stored sections from the database to the reorg point - if stored < c.storedSections { - c.setValidSections(stored) - } - // Update the new head number to the finalized section end and notify children - head = known * c.sectionSize - - if head < c.cascadedHead { - c.cascadedHead = head - for _, child := range c.children { - child.newHead(c.cascadedHead, true) - } - } - return - } - // No reorg, calculate the number of newly known sections and update if high enough - var sections uint64 - if head >= c.confirmsReq { - sections = (head + 1 - c.confirmsReq) / c.sectionSize - if sections < c.checkpointSections { - sections = 0 - } - if sections > c.knownSections { - if c.knownSections < c.checkpointSections { - // syncing reached the checkpoint, verify section head - syncedHead := rawdb.ReadCanonicalHash(c.chainDb, c.checkpointSections*c.sectionSize-1) - if syncedHead != c.checkpointHead { - c.log.Error("Synced chain does not match checkpoint", "number", c.checkpointSections*c.sectionSize-1, "expected", c.checkpointHead, "synced", syncedHead) - return - } - } - c.knownSections = sections - - select { - case c.update <- struct{}{}: - default: - } - } - } -} - -// updateLoop is the main event loop of the indexer which pushes chain segments -// down into the processing backend. -func (c *ChainIndexer) updateLoop() { - var ( - updating bool - updated time.Time - ) - - for { - select { - case errc := <-c.quit: - // Chain indexer terminating, report no failure and abort - errc <- nil - return - - case <-c.update: - // Section headers completed (or rolled back), update the index - c.lock.Lock() - if c.knownSections > c.storedSections { - // Periodically print an upgrade log message to the user - if time.Since(updated) > 8*time.Second { - if c.knownSections > c.storedSections+1 { - updating = true - c.log.Info("Upgrading chain index", "percentage", c.storedSections*100/c.knownSections) - } - updated = time.Now() - } - // Cache the current section count and head to allow unlocking the mutex - c.verifyLastHead() - section := c.storedSections - var oldHead common.Hash - if section > 0 { - oldHead = c.SectionHead(section - 1) - } - // Process the newly defined section in the background - c.lock.Unlock() - newHead, err := c.processSection(section, oldHead) - if err != nil { - select { - case <-c.ctx.Done(): - <-c.quit <- nil - return - default: - } - c.log.Error("Section processing failed", "error", err) - } - c.lock.Lock() - - // If processing succeeded and no reorgs occurred, mark the section completed - if err == nil && (section == 0 || oldHead == c.SectionHead(section-1)) { - c.setSectionHead(section, newHead) - c.setValidSections(section + 1) - if c.storedSections == c.knownSections && updating { - updating = false - c.log.Info("Finished upgrading chain index") - } - c.cascadedHead = c.storedSections*c.sectionSize - 1 - for _, child := range c.children { - c.log.Trace("Cascading chain index update", "head", c.cascadedHead) - child.newHead(c.cascadedHead, false) - } - } else { - // If processing failed, don't retry until further notification - c.log.Debug("Chain index processing failed", "section", section, "err", err) - c.verifyLastHead() - c.knownSections = c.storedSections - } - } - // If there are still further sections to process, reschedule - if c.knownSections > c.storedSections { - time.AfterFunc(c.throttling, func() { - select { - case c.update <- struct{}{}: - default: - } - }) - } - c.lock.Unlock() - } - } -} - -// processSection processes an entire section by calling backend functions while -// ensuring the continuity of the passed headers. Since the chain mutex is not -// held while processing, the continuity can be broken by a long reorg, in which -// case the function returns with an error. -func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (common.Hash, error) { - c.log.Trace("Processing new chain section", "section", section) - - // Reset and partial processing - if err := c.backend.Reset(c.ctx, section, lastHead); err != nil { - c.setValidSections(0) - return common.Hash{}, err - } - - for number := section * c.sectionSize; number < (section+1)*c.sectionSize; number++ { - hash := rawdb.ReadCanonicalHash(c.chainDb, number) - if hash == (common.Hash{}) { - return common.Hash{}, fmt.Errorf("canonical block #%d unknown", number) - } - header := rawdb.ReadHeader(c.chainDb, hash, number) - if header == nil { - return common.Hash{}, fmt.Errorf("block #%d [%x..] not found", number, hash[:4]) - } else if header.ParentHash != lastHead { - return common.Hash{}, errors.New("chain reorged during section processing") - } - if err := c.backend.Process(c.ctx, header); err != nil { - return common.Hash{}, err - } - lastHead = header.Hash() - } - if err := c.backend.Commit(); err != nil { - return common.Hash{}, err - } - return lastHead, nil -} - -// verifyLastHead compares last stored section head with the corresponding block hash in the -// actual canonical chain and rolls back reorged sections if necessary to ensure that stored -// sections are all valid -func (c *ChainIndexer) verifyLastHead() { - for c.storedSections > 0 && c.storedSections > c.checkpointSections { - if c.SectionHead(c.storedSections-1) == rawdb.ReadCanonicalHash(c.chainDb, c.storedSections*c.sectionSize-1) { - return - } - c.setValidSections(c.storedSections - 1) - } -} - -// Sections returns the number of processed sections maintained by the indexer -// and also the information about the last header indexed for potential canonical -// verifications. -func (c *ChainIndexer) Sections() (uint64, uint64, common.Hash) { - c.lock.Lock() - defer c.lock.Unlock() - - c.verifyLastHead() - return c.storedSections, c.storedSections*c.sectionSize - 1, c.SectionHead(c.storedSections - 1) -} - -// AddChildIndexer adds a child ChainIndexer that can use the output of this one -func (c *ChainIndexer) AddChildIndexer(indexer *ChainIndexer) { - if indexer == c { - panic("can't add indexer as a child of itself") - } - c.lock.Lock() - defer c.lock.Unlock() - - c.children = append(c.children, indexer) - - // Cascade any pending updates to new children too - sections := c.storedSections - if c.knownSections < sections { - // if a section is "stored" but not "known" then it is a checkpoint without - // available chain data so we should not cascade it yet - sections = c.knownSections - } - if sections > 0 { - indexer.newHead(sections*c.sectionSize-1, false) - } -} - -// Prune deletes all chain data older than given threshold. -func (c *ChainIndexer) Prune(threshold uint64) error { - return c.backend.Prune(threshold) -} - -// loadValidSections reads the number of valid sections from the index database -// and caches is into the local state. -func (c *ChainIndexer) loadValidSections() { - data, _ := c.indexDb.Get([]byte("count")) - if len(data) == 8 { - c.storedSections = binary.BigEndian.Uint64(data) - } -} - -// setValidSections writes the number of valid sections to the index database -func (c *ChainIndexer) setValidSections(sections uint64) { - // Set the current number of valid sections in the database - var data [8]byte - binary.BigEndian.PutUint64(data[:], sections) - c.indexDb.Put([]byte("count"), data[:]) - - // Remove any reorged sections, caching the valids in the mean time - for c.storedSections > sections { - c.storedSections-- - c.removeSectionHead(c.storedSections) - } - c.storedSections = sections // needed if new > old -} - -// SectionHead retrieves the last block hash of a processed section from the -// index database. -func (c *ChainIndexer) SectionHead(section uint64) common.Hash { - var data [8]byte - binary.BigEndian.PutUint64(data[:], section) - - hash, _ := c.indexDb.Get(append([]byte("shead"), data[:]...)) - if len(hash) == len(common.Hash{}) { - return common.BytesToHash(hash) - } - return common.Hash{} -} - -// setSectionHead writes the last block hash of a processed section to the index -// database. -func (c *ChainIndexer) setSectionHead(section uint64, hash common.Hash) { - var data [8]byte - binary.BigEndian.PutUint64(data[:], section) - - c.indexDb.Put(append([]byte("shead"), data[:]...), hash.Bytes()) -} - -// removeSectionHead removes the reference to a processed section from the index -// database. -func (c *ChainIndexer) removeSectionHead(section uint64) { - var data [8]byte - binary.BigEndian.PutUint64(data[:], section) - - c.indexDb.Delete(append([]byte("shead"), data[:]...)) -} diff --git a/core/chain_indexer_test.go b/core/chain_indexer_test.go deleted file mode 100644 index bf3bde756c..0000000000 --- a/core/chain_indexer_test.go +++ /dev/null @@ -1,246 +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 core - -import ( - "context" - "errors" - "fmt" - "math/big" - "math/rand" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/types" -) - -// Runs multiple tests with randomized parameters. -func TestChainIndexerSingle(t *testing.T) { - for i := 0; i < 10; i++ { - testChainIndexer(t, 1) - } -} - -// Runs multiple tests with randomized parameters and different number of -// chain backends. -func TestChainIndexerWithChildren(t *testing.T) { - for i := 2; i < 8; i++ { - testChainIndexer(t, i) - } -} - -// testChainIndexer runs a test with either a single chain indexer or a chain of -// multiple backends. The section size and required confirmation count parameters -// are randomized. -func testChainIndexer(t *testing.T, count int) { - db := rawdb.NewMemoryDatabase() - defer db.Close() - - // Create a chain of indexers and ensure they all report empty - backends := make([]*testChainIndexBackend, count) - for i := 0; i < count; i++ { - var ( - sectionSize = uint64(rand.Intn(100) + 1) - confirmsReq = uint64(rand.Intn(10)) - ) - backends[i] = &testChainIndexBackend{t: t, processCh: make(chan uint64)} - backends[i].indexer = NewChainIndexer(db, rawdb.NewTable(db, string([]byte{byte(i)})), backends[i], sectionSize, confirmsReq, 0, fmt.Sprintf("indexer-%d", i)) - - if sections, _, _ := backends[i].indexer.Sections(); sections != 0 { - t.Fatalf("Canonical section count mismatch: have %v, want %v", sections, 0) - } - if i > 0 { - backends[i-1].indexer.AddChildIndexer(backends[i].indexer) - } - } - defer backends[0].indexer.Close() // parent indexer shuts down children - // notify pings the root indexer about a new head or reorg, then expect - // processed blocks if a section is processable - notify := func(headNum, failNum uint64, reorg bool) { - backends[0].indexer.newHead(headNum, reorg) - if reorg { - for _, backend := range backends { - headNum = backend.reorg(headNum) - backend.assertSections() - } - return - } - var cascade bool - for _, backend := range backends { - headNum, cascade = backend.assertBlocks(headNum, failNum) - if !cascade { - break - } - backend.assertSections() - } - } - // inject inserts a new random canonical header into the database directly - inject := func(number uint64) { - header := &types.Header{Number: big.NewInt(int64(number)), Extra: big.NewInt(rand.Int63()).Bytes()} - if number > 0 { - header.ParentHash = rawdb.ReadCanonicalHash(db, number-1) - } - rawdb.WriteHeader(db, header) - rawdb.WriteCanonicalHash(db, header.Hash(), number) - } - // Start indexer with an already existing chain - for i := uint64(0); i <= 100; i++ { - inject(i) - } - notify(100, 100, false) - - // Add new blocks one by one - for i := uint64(101); i <= 1000; i++ { - inject(i) - notify(i, i, false) - } - // Do a reorg - notify(500, 500, true) - - // Create new fork - for i := uint64(501); i <= 1000; i++ { - inject(i) - notify(i, i, false) - } - for i := uint64(1001); i <= 1500; i++ { - inject(i) - } - // Failed processing scenario where less blocks are available than notified - notify(2000, 1500, false) - - // Notify about a reorg (which could have caused the missing blocks if happened during processing) - notify(1500, 1500, true) - - // Create new fork - for i := uint64(1501); i <= 2000; i++ { - inject(i) - notify(i, i, false) - } -} - -// testChainIndexBackend implements ChainIndexerBackend -type testChainIndexBackend struct { - t *testing.T - indexer *ChainIndexer - section, headerCnt, stored uint64 - processCh chan uint64 -} - -// assertSections verifies if a chain indexer has the correct number of section. -func (b *testChainIndexBackend) assertSections() { - // Keep trying for 3 seconds if it does not match - var sections uint64 - for i := 0; i < 300; i++ { - sections, _, _ = b.indexer.Sections() - if sections == b.stored { - return - } - time.Sleep(10 * time.Millisecond) - } - b.t.Fatalf("Canonical section count mismatch: have %v, want %v", sections, b.stored) -} - -// assertBlocks expects processing calls after new blocks have arrived. If the -// failNum < headNum then we are simulating a scenario where a reorg has happened -// after the processing has started and the processing of a section fails. -func (b *testChainIndexBackend) assertBlocks(headNum, failNum uint64) (uint64, bool) { - var sections uint64 - if headNum >= b.indexer.confirmsReq { - sections = (headNum + 1 - b.indexer.confirmsReq) / b.indexer.sectionSize - if sections > b.stored { - // expect processed blocks - for expectd := b.stored * b.indexer.sectionSize; expectd < sections*b.indexer.sectionSize; expectd++ { - if expectd > failNum { - // rolled back after processing started, no more process calls expected - // wait until updating is done to make sure that processing actually fails - var updating bool - for i := 0; i < 300; i++ { - b.indexer.lock.Lock() - updating = b.indexer.knownSections > b.indexer.storedSections - b.indexer.lock.Unlock() - if !updating { - break - } - time.Sleep(10 * time.Millisecond) - } - if updating { - b.t.Fatalf("update did not finish") - } - sections = expectd / b.indexer.sectionSize - break - } - select { - case <-time.After(10 * time.Second): - b.t.Fatalf("Expected processed block #%d, got nothing", expectd) - case processed := <-b.processCh: - if processed != expectd { - b.t.Errorf("Expected processed block #%d, got #%d", expectd, processed) - } - } - } - b.stored = sections - } - } - if b.stored == 0 { - return 0, false - } - return b.stored*b.indexer.sectionSize - 1, true -} - -func (b *testChainIndexBackend) reorg(headNum uint64) uint64 { - firstChanged := (headNum + 1) / b.indexer.sectionSize - if firstChanged < b.stored { - b.stored = firstChanged - } - return b.stored * b.indexer.sectionSize -} - -func (b *testChainIndexBackend) Reset(ctx context.Context, section uint64, prevHead common.Hash) error { - b.section = section - b.headerCnt = 0 - return nil -} - -func (b *testChainIndexBackend) Process(ctx context.Context, header *types.Header) error { - b.headerCnt++ - if b.headerCnt > b.indexer.sectionSize { - b.t.Error("Processing too many headers") - } - //t.processCh <- header.Number.Uint64() - select { - case <-time.After(10 * time.Second): - 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") - case b.processCh <- header.Number.Uint64(): - } - return nil -} - -func (b *testChainIndexBackend) Commit() error { - if b.headerCnt != b.indexer.sectionSize { - b.t.Error("Not enough headers processed") - } - return nil -} - -func (b *testChainIndexBackend) Prune(threshold uint64) error { - return nil -} diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index dfc20521f6..d74b11da04 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -17,7 +17,6 @@ package filtermaps import ( - "bytes" "errors" "fmt" "os" @@ -242,7 +241,8 @@ func (f *FilterMaps) Start() { log.Error("Could not load head filter map snapshot", "error", err) } } - f.closeWg.Add(1) + f.closeWg.Add(2) + go f.removeBloomBits() go f.indexerLoop() } @@ -292,7 +292,7 @@ func (f *FilterMaps) reset() bool { // deleting the range first ensures that resetDb will be called again at next // startup and any leftover data will be removed even if it cannot finish now. rawdb.DeleteFilterMapsRange(f.db) - return f.removeDbWithPrefix([]byte(rawdb.FilterMapsPrefix), "Resetting log index database") + return f.safeDeleteRange(rawdb.DeleteFilterMapsDb, "Resetting log index database") } // init initializes an empty log index according to the current targetView. @@ -335,24 +335,25 @@ func (f *FilterMaps) init() error { return batch.Write() } -// removeDbWithPrefix removes data with the given prefix from the database and -// returns true if everything was successfully removed. -func (f *FilterMaps) removeDbWithPrefix(prefix []byte, action string) bool { - it := f.db.NewIterator(prefix, nil) - hasData := it.Next() - it.Release() - if !hasData { - return true - } +// removeBloomBits removes old bloom bits data from the database. +func (f *FilterMaps) removeBloomBits() { + f.safeDeleteRange(rawdb.DeleteBloomBitsDb, "Removing old bloom bits database") + f.closeWg.Done() +} - end := bytes.Clone(prefix) - end[len(end)-1]++ +// safeDeleteRange calls the specified database range deleter function +// repeatedly as long as it returns leveldb.ErrTooManyKeys. +// This wrapper is necessary because of the leveldb fallback implementation +// of DeleteRange. +func (f *FilterMaps) safeDeleteRange(removeFn func(ethdb.KeyValueRangeDeleter) error, action string) bool { start := time.Now() var retry bool for { - err := f.db.DeleteRange(prefix, end) + err := removeFn(f.db) if err == nil { - log.Info(action+" finished", "elapsed", time.Since(start)) + if retry { + log.Info(action+" finished", "elapsed", time.Since(start)) + } return true } if err != leveldb.ErrTooManyKeys { @@ -365,7 +366,7 @@ func (f *FilterMaps) removeDbWithPrefix(prefix []byte, action string) bool { default: } if !retry { - log.Info(action + " in progress...") + log.Info(action+" in progress...", "elapsed", time.Since(start)) retry = true } } diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 61a9bf0352..69f42d8b60 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -44,13 +44,18 @@ func (f *FilterMaps) indexerLoop() { if !f.indexedRange.initialized { if err := f.init(); err != nil { log.Error("Error initializing log index", "error", err) - f.waitForEvent() + // unexpected error; there is not a lot we can do here, maybe it + // recovers, maybe not. Calling event processing here ensures + // that we can still properly shutdown in case of an infinite loop. + f.processSingleEvent(true) continue } } if !f.targetHeadIndexed() { if !f.tryIndexHead() { - f.waitForEvent() + // either shutdown or unexpected error; in the latter case ensure + // that proper shutdown is still possible. + f.processSingleEvent(true) } } else { if f.finalBlock != f.lastFinal { @@ -60,7 +65,7 @@ func (f *FilterMaps) indexerLoop() { f.lastFinal = f.finalBlock } if f.tryIndexTail() && f.tryUnindexTail() { - f.waitForEvent() + f.waitForNewHead() } } } @@ -119,8 +124,9 @@ func (f *FilterMaps) WaitIdle() { } } -// waitForEvent blocks until an event happens that the indexer might react to. -func (f *FilterMaps) waitForEvent() { +// waitForNewHead blocks until there is a new target head to index and block +// processing has been finished. +func (f *FilterMaps) waitForNewHead() { for !f.stop && (f.blockProcessing || f.targetHeadIndexed()) { f.processSingleEvent(true) } @@ -129,13 +135,16 @@ func (f *FilterMaps) waitForEvent() { // processEvents processes all events, blocking only if a block processing is // happening and indexing should be suspended. func (f *FilterMaps) processEvents() { - for !f.stop && f.processSingleEvent(f.blockProcessing) { + for f.processSingleEvent(f.blockProcessing) { } } // processSingleEvent processes a single event either in a blocking or -// non-blocking manner. +// non-blocking manner. It returns true if it did process an event. func (f *FilterMaps) processSingleEvent(blocking bool) bool { + if f.stop { + return false + } if !f.hasTempRange { for _, mb := range f.matcherSyncRequests { mb.synced() @@ -356,15 +365,17 @@ func (f *FilterMaps) needTailEpoch(epoch uint32) bool { if epoch+1 < firstEpoch { return false } + var lastBlockOfPrevEpoch uint64 if epoch > 0 { - lastBlockOfPrevEpoch, _, err := f.getLastBlockOfMap(epoch<= firstEpoch } - if f.historyCutoff > lastBlockOfPrevEpoch { - return false - } + } + if f.historyCutoff > lastBlockOfPrevEpoch { + return false } lastBlockOfEpoch, _, err := f.getLastBlockOfMap((epoch+1)<= 0 { - break - } - if len(it.Key()) != len(bloomBitsPrefix)+2+8+32 { - continue - } - db.Delete(it.Key()) - } - if it.Error() != nil { - log.Crit("Failed to delete bloom bits", "err", it.Error()) - } -} - // ReadFilterMapRow retrieves a filter map row at the given mapRowIndex // (see filtermaps.mapRowIndex for the storage index encoding). // Note that zero length rows are not stored in the database and therefore all @@ -485,3 +450,24 @@ func DeleteFilterMapsRange(db ethdb.KeyValueWriter) { log.Crit("Failed to delete filter maps range", "err", err) } } + +// deletePrefixRange deletes everything with the given prefix from the database. +func deletePrefixRange(db ethdb.KeyValueRangeDeleter, prefix []byte) error { + end := bytes.Clone(prefix) + end[len(end)-1]++ + return db.DeleteRange(prefix, end) +} + +// DeleteFilterMapsDb removes the entire filter maps database +func DeleteFilterMapsDb(db ethdb.KeyValueRangeDeleter) error { + return deletePrefixRange(db, []byte(filterMapsPrefix)) +} + +// DeleteFilterMapsDb removes the old bloombits database and the associated +// chain indexer database. +func DeleteBloomBitsDb(db ethdb.KeyValueRangeDeleter) error { + if err := deletePrefixRange(db, bloomBitsPrefix); err != nil { + return err + } + return deletePrefixRange(db, bloomBitsIndexPrefix) +} diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go index ea25bf1e2c..29b468fb2a 100644 --- a/core/rawdb/accessors_indexes_test.go +++ b/core/rawdb/accessors_indexes_test.go @@ -17,7 +17,6 @@ package rawdb import ( - "bytes" "math/big" "testing" @@ -25,7 +24,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/blocktest" - "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" ) @@ -111,54 +109,3 @@ func TestLookupStorage(t *testing.T) { }) } } - -func TestDeleteBloomBits(t *testing.T) { - // Prepare testing data - db := NewMemoryDatabase() - for i := uint(0); i < 2; i++ { - for s := uint64(0); s < 2; s++ { - WriteBloomBits(db, i, s, params.MainnetGenesisHash, []byte{0x01, 0x02}) - WriteBloomBits(db, i, s, params.SepoliaGenesisHash, []byte{0x01, 0x02}) - WriteBloomBits(db, i, s, params.HoodiGenesisHash, []byte{0x01, 0x02}) - } - } - check := func(bit uint, section uint64, head common.Hash, exist bool) { - bits, _ := ReadBloomBits(db, bit, section, head) - if exist && !bytes.Equal(bits, []byte{0x01, 0x02}) { - t.Fatalf("Bloombits mismatch") - } - if !exist && len(bits) > 0 { - t.Fatalf("Bloombits should be removed") - } - } - // Check the existence of written data. - check(0, 0, params.MainnetGenesisHash, true) - check(0, 0, params.SepoliaGenesisHash, true) - check(0, 0, params.HoodiGenesisHash, true) - - // Check the existence of deleted data. - DeleteBloombits(db, 0, 0, 1) - check(0, 0, params.MainnetGenesisHash, false) - check(0, 0, params.SepoliaGenesisHash, false) - check(0, 0, params.HoodiGenesisHash, false) - check(0, 1, params.MainnetGenesisHash, true) - check(0, 1, params.SepoliaGenesisHash, true) - check(0, 1, params.HoodiGenesisHash, true) - - // Check the existence of deleted data. - DeleteBloombits(db, 0, 0, 2) - check(0, 0, params.MainnetGenesisHash, false) - check(0, 0, params.SepoliaGenesisHash, false) - check(0, 0, params.HoodiGenesisHash, false) - check(0, 1, params.MainnetGenesisHash, false) - check(0, 1, params.SepoliaGenesisHash, false) - check(0, 1, params.HoodiGenesisHash, false) - - // Bit1 shouldn't be affect. - check(1, 0, params.MainnetGenesisHash, true) - check(1, 0, params.SepoliaGenesisHash, true) - check(1, 0, params.HoodiGenesisHash, true) - check(1, 1, params.MainnetGenesisHash, true) - check(1, 1, params.SepoliaGenesisHash, true) - check(1, 1, params.HoodiGenesisHash, true) -} diff --git a/core/rawdb/database.go b/core/rawdb/database.go index bc29347324..4c87e66cfd 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -375,7 +375,6 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { accountSnaps stat storageSnaps stat preimages stat - bloomBits stat filterMaps stat beaconHeaders stat cliqueSnaps stat @@ -437,11 +436,7 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { metadata.Add(size) case bytes.HasPrefix(key, genesisPrefix) && len(key) == (len(genesisPrefix)+common.HashLength): metadata.Add(size) - case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength): - bloomBits.Add(size) - case bytes.HasPrefix(key, BloomBitsIndexPrefix): - bloomBits.Add(size) - case bytes.HasPrefix(key, []byte(FilterMapsPrefix)): + case bytes.HasPrefix(key, []byte(filterMapsPrefix)): filterMaps.Add(size) case bytes.HasPrefix(key, skeletonHeaderPrefix) && len(key) == (len(skeletonHeaderPrefix)+8): beaconHeaders.Add(size) @@ -507,7 +502,6 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { {"Key-Value store", "Block number->hash", numHashPairings.Size(), numHashPairings.Count()}, {"Key-Value store", "Block hash->number", hashNumPairings.Size(), hashNumPairings.Count()}, {"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()}, - {"Key-Value store", "Bloombit index", bloomBits.Size(), bloomBits.Count()}, {"Key-Value store", "Log search index", filterMaps.Size(), filterMaps.Count()}, {"Key-Value store", "Contract codes", codes.Size(), codes.Count()}, {"Key-Value store", "Hash trie nodes", legacyTries.Size(), legacyTries.Count()}, diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index b41951113c..c21a96bd24 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -128,8 +128,8 @@ var ( configPrefix = []byte("ethereum-config-") // config prefix for the db genesisPrefix = []byte("ethereum-genesis-") // genesis state prefix for the db - // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress - BloomBitsIndexPrefix = []byte("iB") + // bloomBitsIndexPrefix is the data table of a chain indexer to track its progress + bloomBitsIndexPrefix = []byte("iB") ChtPrefix = []byte("chtRootV2-") // ChtPrefix + chtNum (uint64 big endian) -> trie root hash ChtTablePrefix = []byte("cht-") @@ -145,11 +145,11 @@ var ( FixedCommitteeRootKey = []byte("fixedRoot-") // bigEndian64(syncPeriod) -> committee root hash SyncCommitteeKey = []byte("committee-") // bigEndian64(syncPeriod) -> serialized committee - FilterMapsPrefix = "fm-" - filterMapsRangeKey = []byte(FilterMapsPrefix + "R") - filterMapRowPrefix = []byte(FilterMapsPrefix + "r") // filterMapRowPrefix + mapRowIndex (uint64 big endian) -> filter row - filterMapLastBlockPrefix = []byte(FilterMapsPrefix + "b") // filterMapLastBlockPrefix + mapIndex (uint32 big endian) -> block number (uint64 big endian) - filterMapBlockLVPrefix = []byte(FilterMapsPrefix + "p") // filterMapBlockLVPrefix + num (uint64 big endian) -> log value pointer (uint64 big endian) + filterMapsPrefix = "fm-" + filterMapsRangeKey = []byte(filterMapsPrefix + "R") + filterMapRowPrefix = []byte(filterMapsPrefix + "r") // filterMapRowPrefix + mapRowIndex (uint64 big endian) -> filter row + filterMapLastBlockPrefix = []byte(filterMapsPrefix + "b") // filterMapLastBlockPrefix + mapIndex (uint32 big endian) -> block number (uint64 big endian) + filterMapBlockLVPrefix = []byte(filterMapsPrefix + "p") // filterMapBlockLVPrefix + num (uint64 big endian) -> log value pointer (uint64 big endian) preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) preimageHitsCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) @@ -225,16 +225,6 @@ func storageSnapshotsKey(accountHash common.Hash) []byte { return append(SnapshotStoragePrefix, accountHash.Bytes()...) } -// bloomBitsKey = bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -func bloomBitsKey(bit uint, section uint64, hash common.Hash) []byte { - key := append(append(bloomBitsPrefix, make([]byte, 10)...), hash.Bytes()...) - - binary.BigEndian.PutUint16(key[1:], uint16(bit)) - binary.BigEndian.PutUint64(key[3:], section) - - return key -} - // skeletonHeaderKey = skeletonHeaderPrefix + num (uint64 big endian) func skeletonHeaderKey(number uint64) []byte { return append(skeletonHeaderPrefix, encodeBlockNumber(number)...) diff --git a/eth/api_backend.go b/eth/api_backend.go index b4b63556a9..b08e38afe5 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -28,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" @@ -403,17 +402,6 @@ func (b *EthAPIBackend) RPCTxFeeCap() float64 { return b.eth.config.RPCTxFeeCap } -func (b *EthAPIBackend) BloomStatus() (uint64, uint64) { - sections, _, _ := b.eth.bloomIndexer.Sections() - return params.BloomBitsBlocks, sections -} - -func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { - for i := 0; i < bloomFilterThreads; i++ { - go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests) - } -} - func (b *EthAPIBackend) NewMatcherBackend() filtermaps.MatcherBackend { return b.eth.filterMaps.NewMatcherBackend() } diff --git a/eth/backend.go b/eth/backend.go index 99cb3841c3..6deedab872 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -30,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/pruner" @@ -85,10 +84,6 @@ type Ethereum struct { engine consensus.Engine accountManager *accounts.Manager - bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests - bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports - closeBloomHandler chan struct{} - filterMaps *filtermaps.FilterMaps closeFilterMaps chan chan struct{} @@ -176,19 +171,16 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { // Assemble the Ethereum object. eth := &Ethereum{ - config: config, - chainDb: chainDb, - eventMux: stack.EventMux(), - accountManager: stack.AccountManager(), - engine: engine, - closeBloomHandler: make(chan struct{}), - networkID: networkID, - gasPrice: config.Miner.GasPrice, - 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), + config: config, + chainDb: chainDb, + eventMux: stack.EventMux(), + accountManager: stack.AccountManager(), + engine: engine, + networkID: networkID, + gasPrice: config.Miner.GasPrice, + p2pServer: stack.Server(), + discmix: enode.NewFairMix(0), + shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb), } bcVersion := rawdb.ReadDatabaseVersion(chainDb) var dbVer = "" @@ -247,7 +239,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } - eth.bloomIndexer.Start(eth.blockchain) fmConfig := filtermaps.Config{History: config.LogHistory, Disabled: config.LogNoHistory, ExportFileName: config.LogExportCheckpoints} chainView := eth.newChainView(eth.blockchain.CurrentBlock()) eth.filterMaps = filtermaps.NewFilterMaps(chainDb, chainView, 0, 0, filtermaps.DefaultParams, fmConfig) @@ -379,7 +370,6 @@ func (s *Ethereum) Downloader() *downloader.Downloader { return s.handler.downlo func (s *Ethereum) Synced() bool { return s.handler.synced.Load() } 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 } // Protocols returns all the currently configured // network protocols to start. @@ -398,9 +388,6 @@ func (s *Ethereum) Start() error { return err } - // Start the bloom bits servicing goroutines - s.startBloomHandlers(params.BloomBitsBlocks) - // Regularly update shutdown marker s.shutdownTracker.Start() @@ -511,8 +498,6 @@ func (s *Ethereum) Stop() error { s.handler.Stop() // Then stop everything else. - s.bloomIndexer.Close() - close(s.closeBloomHandler) ch := make(chan struct{}) s.closeFilterMaps <- ch <-ch diff --git a/eth/bloombits.go b/eth/bloombits.go deleted file mode 100644 index 0cb7050d23..0000000000 --- a/eth/bloombits.go +++ /dev/null @@ -1,74 +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 eth - -import ( - "time" - - "github.com/ethereum/go-ethereum/common/bitutil" - "github.com/ethereum/go-ethereum/core/rawdb" -) - -const ( - // bloomServiceThreads is the number of goroutines used globally by an Ethereum - // instance to service bloombits lookups for all running filters. - bloomServiceThreads = 16 - - // bloomFilterThreads is the number of goroutines used locally per filter to - // multiplex requests onto the global servicing goroutines. - bloomFilterThreads = 3 - - // bloomRetrievalBatch is the maximum number of bloom bit retrievals to service - // in a single batch. - bloomRetrievalBatch = 16 - - // bloomRetrievalWait is the maximum time to wait for enough bloom bit requests - // to accumulate request an entire batch (avoiding hysteresis). - bloomRetrievalWait = time.Duration(0) -) - -// startBloomHandlers starts a batch of goroutines to accept bloom bit database -// retrievals from possibly a range of filters and serving the data to satisfy. -func (eth *Ethereum) startBloomHandlers(sectionSize uint64) { - for i := 0; i < bloomServiceThreads; i++ { - go func() { - for { - select { - case <-eth.closeBloomHandler: - return - - case request := <-eth.bloomRequests: - task := <-request - task.Bitsets = make([][]byte, len(task.Sections)) - for i, section := range task.Sections { - head := rawdb.ReadCanonicalHash(eth.chainDb, (section+1)*sectionSize-1) - if compVector, err := rawdb.ReadBloomBits(eth.chainDb, task.Bit, section, head); err == nil { - if blob, err := bitutil.DecompressBytes(compVector, int(sectionSize/8)); err == nil { - task.Bitsets[i] = blob - } else { - task.Error = err - } - } else { - task.Error = err - } - } - request <- task - } - } - }() - } -} diff --git a/params/network_params.go b/params/network_params.go index 61bd6b2f42..c016e7fcf3 100644 --- a/params/network_params.go +++ b/params/network_params.go @@ -20,14 +20,6 @@ package params // aren't necessarily consensus related. const ( - // BloomBitsBlocks is the number of blocks a single bloom bit section vector - // contains on the server side. - BloomBitsBlocks uint64 = 4096 - - // BloomConfirms is the number of confirmation blocks before a bloom section is - // considered probably final and its rotated bits are calculated. - BloomConfirms = 256 - // FullImmutabilityThreshold is the number of blocks after which a chain segment is // considered immutable (i.e. soft finality). It is used by the downloader as a // hard limit against deep ancestors, by the blockchain against deep reorgs, by From 18869222646d1706168929515df83c442ebba2b0 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 21 Mar 2025 11:29:51 +0100 Subject: [PATCH 219/940] core: respect history cutoff in txindexer (#31393) In #31384 we unindex TXes prior to the merge block. However when the node starts up it will try to re-index those back if the config is to index the whole chain. This change makes the indexer aware of the history cutoff block, avoiding reindexing in that segment. --------- Co-authored-by: Gary Rong Co-authored-by: Felix Lange --- core/rawdb/accessors_chain.go | 8 + core/rawdb/accessors_indexes.go | 48 ++- core/txindexer.go | 151 +++++++-- core/txindexer_test.go | 538 ++++++++++++++++++++++---------- 4 files changed, 543 insertions(+), 202 deletions(-) diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 1a2b31b360..020d35619e 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -277,6 +277,14 @@ func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) { } } +// DeleteTxIndexTail deletes the number of oldest indexed block +// from database. +func DeleteTxIndexTail(db ethdb.KeyValueWriter) { + if err := db.Delete(txIndexTailKey); err != nil { + log.Crit("Failed to delete the transaction index tail", "err", err) + } +} + // ReadHeaderRange returns the rlp-encoded headers, starting at 'number', and going // backwards towards genesis. This method assumes that the caller already has // placed a cap on count, to prevent DoS issues. diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index 1d5897cef1..342aedd8dc 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -30,13 +30,8 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) -// ReadTxLookupEntry retrieves the positional metadata associated with a transaction -// hash to allow retrieving the transaction or receipt by hash. -func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) *uint64 { - data, _ := db.Get(txLookupKey(hash)) - if len(data) == 0 { - return nil - } +// DecodeTxLookupEntry decodes the supplied tx lookup data. +func DecodeTxLookupEntry(data []byte, db ethdb.Reader) *uint64 { // Database v6 tx lookup just stores the block number if len(data) < common.HashLength { number := new(big.Int).SetBytes(data).Uint64() @@ -49,12 +44,22 @@ func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) *uint64 { // Finally try database v3 tx lookup format var entry LegacyTxLookupEntry if err := rlp.DecodeBytes(data, &entry); err != nil { - log.Error("Invalid transaction lookup entry RLP", "hash", hash, "blob", data, "err", err) + log.Error("Invalid transaction lookup entry RLP", "blob", data, "err", err) return nil } return &entry.BlockIndex } +// ReadTxLookupEntry retrieves the positional metadata associated with a transaction +// hash to allow retrieving the transaction or receipt by hash. +func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) *uint64 { + data, _ := db.Get(txLookupKey(hash)) + if len(data) == 0 { + return nil + } + return DecodeTxLookupEntry(data, db) +} + // writeTxLookupEntry stores a positional metadata for a transaction, // enabling hash based transaction and receipt lookups. func writeTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash, numberBytes []byte) { @@ -95,6 +100,33 @@ func DeleteTxLookupEntries(db ethdb.KeyValueWriter, hashes []common.Hash) { } } +// DeleteAllTxLookupEntries purges all the transaction indexes in the database. +// If condition is specified, only the entry with condition as True will be +// removed; If condition is not specified, the entry is deleted. +func DeleteAllTxLookupEntries(db ethdb.KeyValueStore, condition func([]byte) bool) { + iter := NewKeyLengthIterator(db.NewIterator(txLookupPrefix, nil), common.HashLength+len(txLookupPrefix)) + defer iter.Release() + + batch := db.NewBatch() + for iter.Next() { + if condition == nil || condition(iter.Value()) { + batch.Delete(iter.Key()) + } + if batch.ValueSize() >= ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + log.Crit("Failed to delete transaction lookup entries", "err", err) + } + batch.Reset() + } + } + if batch.ValueSize() > 0 { + if err := batch.Write(); err != nil { + log.Crit("Failed to delete transaction lookup entries", "err", err) + } + batch.Reset() + } +} + // ReadTransaction retrieves a specific transaction from the database, along with // its added positional metadata. func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { diff --git a/core/txindexer.go b/core/txindexer.go index 293124f681..29e87905d5 100644 --- a/core/txindexer.go +++ b/core/txindexer.go @@ -44,7 +44,11 @@ type txIndexer struct { // * 0: means the entire chain should be indexed // * N: means the latest N blocks [HEAD-N+1, HEAD] should be indexed // and all others shouldn't. - limit uint64 + limit uint64 + + // cutoff denotes the block number before which the chain segment should + // be pruned and not available locally. + cutoff uint64 db ethdb.Database progress chan chan TxIndexProgress term chan chan struct{} @@ -55,6 +59,7 @@ type txIndexer struct { func newTxIndexer(limit uint64, chain *BlockChain) *txIndexer { indexer := &txIndexer{ limit: limit, + cutoff: chain.HistoryPruningCutoff(), db: chain.db, progress: make(chan chan TxIndexProgress), term: make(chan chan struct{}), @@ -64,7 +69,11 @@ func newTxIndexer(limit uint64, chain *BlockChain) *txIndexer { var msg string if limit == 0 { - msg = "entire chain" + if indexer.cutoff == 0 { + msg = "entire chain" + } else { + msg = fmt.Sprintf("blocks since #%d", indexer.cutoff) + } } else { msg = fmt.Sprintf("last %d blocks", limit) } @@ -74,23 +83,31 @@ func newTxIndexer(limit uint64, chain *BlockChain) *txIndexer { } // run executes the scheduled indexing/unindexing task in a separate thread. -// If the stop channel is closed, the task should be terminated as soon as -// possible, the done channel will be closed once the task is finished. -func (indexer *txIndexer) run(tail *uint64, head uint64, stop chan struct{}, done chan struct{}) { +// If the stop channel is closed, the task should terminate as soon as possible. +// The done channel will be closed once the task is complete. +// +// Existing transaction indexes are assumed to be valid, with both the head +// and tail above the configured cutoff. +func (indexer *txIndexer) run(head uint64, stop chan struct{}, done chan struct{}) { defer func() { close(done) }() - // Short circuit if chain is empty and nothing to index. - if head == 0 { + // Short circuit if the chain is either empty, or entirely below the + // cutoff point. + if head == 0 || head < indexer.cutoff { return } // The tail flag is not existent, it means the node is just initialized // and all blocks in the chain (part of them may from ancient store) are // not indexed yet, index the chain according to the configured limit. + tail := rawdb.ReadTxIndexTail(indexer.db) if tail == nil { + // Determine the first block for transaction indexing, taking the + // configured cutoff point into account. from := uint64(0) if indexer.limit != 0 && head >= indexer.limit { from = head - indexer.limit + 1 } + from = max(from, indexer.cutoff) rawdb.IndexTransactions(indexer.db, from, head+1, stop, true) return } @@ -98,25 +115,82 @@ func (indexer *txIndexer) run(tail *uint64, head uint64, stop chan struct{}, don // present), while the whole chain are requested for indexing. if indexer.limit == 0 || head < indexer.limit { if *tail > 0 { - // It can happen when chain is rewound to a historical point which - // is even lower than the indexes tail, recap the indexing target - // to new head to avoid reading non-existent block bodies. - end := *tail - if end > head+1 { - end = head + 1 - } - rawdb.IndexTransactions(indexer.db, 0, end, stop, true) + from := max(uint64(0), indexer.cutoff) + rawdb.IndexTransactions(indexer.db, from, *tail, stop, true) } return } // The tail flag is existent, adjust the index range according to configured // limit and the latest chain head. - if head-indexer.limit+1 < *tail { + from := head - indexer.limit + 1 + from = max(from, indexer.cutoff) + if from < *tail { // Reindex a part of missing indices and rewind index tail to HEAD-limit - rawdb.IndexTransactions(indexer.db, head-indexer.limit+1, *tail, stop, true) + rawdb.IndexTransactions(indexer.db, from, *tail, stop, true) } else { // Unindex a part of stale indices and forward index tail to HEAD-limit - rawdb.UnindexTransactions(indexer.db, *tail, head-indexer.limit+1, stop, false) + rawdb.UnindexTransactions(indexer.db, *tail, from, stop, false) + } +} + +// repair ensures that transaction indexes are in a valid state and invalidates +// them if they are not. The following cases are considered invalid: +// * The index tail is higher than the chain head. +// * The chain head is below the configured cutoff, but the index tail is not empty. +// * The index tail is below the configured cutoff, but it is not empty. +func (indexer *txIndexer) repair(head uint64) { + // If the transactions haven't been indexed yet, nothing to repair + tail := rawdb.ReadTxIndexTail(indexer.db) + if tail == nil { + return + } + // The transaction index tail is higher than the chain head, which may occur + // when the chain is rewound to a historical height below the index tail. + // Purge the transaction indexes from the database. **It's not a common case + // to rewind the chain head below the index tail**. + if *tail > head { + // A crash may occur between the two delete operations, + // potentially leaving dangling indexes in the database. + // However, this is considered acceptable. + rawdb.DeleteTxIndexTail(indexer.db) + rawdb.DeleteAllTxLookupEntries(indexer.db, nil) + log.Warn("Purge transaction indexes", "head", head, "tail", *tail) + return + } + + // If the entire chain is below the configured cutoff point, + // removing the tail of transaction indexing and purges the + // transaction indexes. **It's not a common case, as the cutoff + // is usually defined below the chain head**. + if head < indexer.cutoff { + // A crash may occur between the two delete operations, + // potentially leaving dangling indexes in the database. + // However, this is considered acceptable. + // + // The leftover indexes can't be unindexed by scanning + // the blocks as they are not guaranteed to be available. + // Traversing the database directly within the transaction + // index namespace might be slow and expensive, but we + // have no choice. + rawdb.DeleteTxIndexTail(indexer.db) + rawdb.DeleteAllTxLookupEntries(indexer.db, nil) + log.Warn("Purge transaction indexes", "head", head, "cutoff", indexer.cutoff) + return + } + + // The chain head is above the cutoff while the tail is below the + // cutoff. Shift the tail to the cutoff point and remove the indexes + // below. + if *tail < indexer.cutoff { + // A crash may occur between the two delete operations, + // potentially leaving dangling indexes in the database. + // However, this is considered acceptable. + rawdb.WriteTxIndexTail(indexer.db, indexer.cutoff) + rawdb.DeleteAllTxLookupEntries(indexer.db, func(blob []byte) bool { + n := rawdb.DecodeTxLookupEntry(blob, indexer.db) + return n != nil && *n < indexer.cutoff + }) + log.Warn("Purge transaction indexes below cutoff", "tail", *tail, "cutoff", indexer.cutoff) } } @@ -127,39 +201,39 @@ func (indexer *txIndexer) loop(chain *BlockChain) { // Listening to chain events and manipulate the transaction indexes. var ( - stop chan struct{} // Non-nil if background routine is active. - done chan struct{} // Non-nil if background routine is active. - lastHead uint64 // The latest announced chain head (whose tx indexes are assumed created) - lastTail = rawdb.ReadTxIndexTail(indexer.db) // The oldest indexed block, nil means nothing indexed + stop chan struct{} // Non-nil if background routine is active + done chan struct{} // Non-nil if background routine is active + head = rawdb.ReadHeadBlock(indexer.db).NumberU64() // The latest announced chain head headCh = make(chan ChainHeadEvent) sub = chain.SubscribeChainHeadEvent(headCh) ) defer sub.Unsubscribe() + // Validate the transaction indexes and repair if necessary + indexer.repair(head) + // Launch the initial processing if chain is not empty (head != genesis). // This step is useful in these scenarios that chain has no progress. - if head := rawdb.ReadHeadBlock(indexer.db); head != nil && head.Number().Uint64() != 0 { + if head != 0 { stop = make(chan struct{}) done = make(chan struct{}) - lastHead = head.Number().Uint64() - go indexer.run(rawdb.ReadTxIndexTail(indexer.db), head.NumberU64(), stop, done) + go indexer.run(head, stop, done) } for { select { - case head := <-headCh: + case h := <-headCh: if done == nil { stop = make(chan struct{}) done = make(chan struct{}) - go indexer.run(rawdb.ReadTxIndexTail(indexer.db), head.Header.Number.Uint64(), stop, done) + go indexer.run(h.Header.Number.Uint64(), stop, done) } - lastHead = head.Header.Number.Uint64() + head = h.Header.Number.Uint64() case <-done: stop = nil done = nil - lastTail = rawdb.ReadTxIndexTail(indexer.db) case ch := <-indexer.progress: - ch <- indexer.report(lastHead, lastTail) + ch <- indexer.report(head) case ch := <-indexer.term: if stop != nil { close(stop) @@ -175,12 +249,27 @@ func (indexer *txIndexer) loop(chain *BlockChain) { } // report returns the tx indexing progress. -func (indexer *txIndexer) report(head uint64, tail *uint64) TxIndexProgress { +func (indexer *txIndexer) report(head uint64) TxIndexProgress { + // Special case if the head is even below the cutoff, + // nothing to index. + if head < indexer.cutoff { + return TxIndexProgress{ + Indexed: 0, + Remaining: 0, + } + } + // Compute how many blocks are supposed to be indexed total := indexer.limit if indexer.limit == 0 || total > head { total = head + 1 // genesis included } + length := head - indexer.cutoff + 1 // all available chain for indexing + if total > length { + total = length + } + // Compute how many blocks have been indexed var indexed uint64 + tail := rawdb.ReadTxIndexTail(indexer.db) if tail != nil { indexed = head - *tail + 1 } diff --git a/core/txindexer_test.go b/core/txindexer_test.go index 4425f0d9a5..7a5688241f 100644 --- a/core/txindexer_test.go +++ b/core/txindexer_test.go @@ -29,6 +29,46 @@ import ( "github.com/ethereum/go-ethereum/params" ) +func verifyIndexes(t *testing.T, db ethdb.Database, block *types.Block, exist bool) { + for _, tx := range block.Transactions() { + lookup := rawdb.ReadTxLookupEntry(db, tx.Hash()) + if exist && lookup == nil { + t.Fatalf("missing %d %x", block.NumberU64(), tx.Hash().Hex()) + } + if !exist && lookup != nil { + t.Fatalf("unexpected %d %x", block.NumberU64(), tx.Hash().Hex()) + } + } +} + +func verify(t *testing.T, db ethdb.Database, blocks []*types.Block, expTail uint64) { + tail := rawdb.ReadTxIndexTail(db) + if tail == nil { + t.Fatal("Failed to write tx index tail") + return + } + if *tail != expTail { + t.Fatalf("Unexpected tx index tail, want %v, got %d", expTail, *tail) + } + for _, b := range blocks { + if b.Number().Uint64() < *tail { + verifyIndexes(t, db, b, false) + } else { + verifyIndexes(t, db, b, true) + } + } +} + +func verifyNoIndex(t *testing.T, db ethdb.Database, blocks []*types.Block) { + tail := rawdb.ReadTxIndexTail(db) + if tail != nil { + t.Fatalf("Unexpected tx index tail %d", *tail) + } + for _, b := range blocks { + verifyIndexes(t, db, b, false) + } +} + // TestTxIndexer tests the functionalities for managing transaction indexes. func TestTxIndexer(t *testing.T) { var ( @@ -50,163 +90,29 @@ func TestTxIndexer(t *testing.T) { gen.AddTx(tx) nonce += 1 }) - - // verifyIndexes checks if the transaction indexes are present or not - // of the specified block. - verifyIndexes := func(db ethdb.Database, number uint64, exist bool) { - if number == 0 { - return - } - block := blocks[number-1] - for _, tx := range block.Transactions() { - lookup := rawdb.ReadTxLookupEntry(db, tx.Hash()) - if exist && lookup == nil { - t.Fatalf("missing %d %x", number, tx.Hash().Hex()) - } - if !exist && lookup != nil { - t.Fatalf("unexpected %d %x", number, tx.Hash().Hex()) - } - } - } - verify := func(db ethdb.Database, expTail uint64, indexer *txIndexer) { - tail := rawdb.ReadTxIndexTail(db) - if tail == nil { - t.Fatal("Failed to write tx index tail") - } - if *tail != expTail { - t.Fatalf("Unexpected tx index tail, want %v, got %d", expTail, *tail) - } - if *tail != 0 { - for number := uint64(0); number < *tail; number += 1 { - verifyIndexes(db, number, false) - } - } - for number := *tail; number <= chainHead; number += 1 { - verifyIndexes(db, number, true) - } - progress := indexer.report(chainHead, tail) - if !progress.Done() { - t.Fatalf("Expect fully indexed") - } - } - var cases = []struct { - limitA uint64 - tailA uint64 - limitB uint64 - tailB uint64 - limitC uint64 - tailC uint64 + limits []uint64 + tails []uint64 }{ { - // LimitA: 0 - // TailA: 0 - // - // all blocks are indexed - limitA: 0, - tailA: 0, - - // LimitB: 1 - // TailB: 128 - // - // block-128 is indexed - limitB: 1, - tailB: 128, - - // LimitB: 64 - // TailB: 65 - // - // block [65, 128] are indexed - limitC: 64, - tailC: 65, + limits: []uint64{0, 1, 64, 129, 0}, + tails: []uint64{0, 128, 65, 0, 0}, }, { - // LimitA: 64 - // TailA: 65 - // - // block [65, 128] are indexed - limitA: 64, - tailA: 65, - - // LimitB: 1 - // TailB: 128 - // - // block-128 is indexed - limitB: 1, - tailB: 128, - - // LimitB: 64 - // TailB: 65 - // - // block [65, 128] are indexed - limitC: 64, - tailC: 65, + limits: []uint64{64, 1, 64, 0}, + tails: []uint64{65, 128, 65, 0}, }, { - // LimitA: 127 - // TailA: 2 - // - // block [2, 128] are indexed - limitA: 127, - tailA: 2, - - // LimitB: 1 - // TailB: 128 - // - // block-128 is indexed - limitB: 1, - tailB: 128, - - // LimitB: 64 - // TailB: 65 - // - // block [65, 128] are indexed - limitC: 64, - tailC: 65, + limits: []uint64{127, 1, 64, 0}, + tails: []uint64{2, 128, 65, 0}, }, { - // LimitA: 128 - // TailA: 1 - // - // block [2, 128] are indexed - limitA: 128, - tailA: 1, - - // LimitB: 1 - // TailB: 128 - // - // block-128 is indexed - limitB: 1, - tailB: 128, - - // LimitB: 64 - // TailB: 65 - // - // block [65, 128] are indexed - limitC: 64, - tailC: 65, + limits: []uint64{128, 1, 64, 0}, + tails: []uint64{1, 128, 65, 0}, }, { - // LimitA: 129 - // TailA: 0 - // - // block [0, 128] are indexed - limitA: 129, - tailA: 0, - - // LimitB: 1 - // TailB: 128 - // - // block-128 is indexed - limitB: 1, - tailB: 128, - - // LimitB: 64 - // TailB: 65 - // - // block [65, 128] are indexed - limitC: 64, - tailC: 65, + limits: []uint64{129, 1, 64, 0}, + tails: []uint64{0, 128, 65, 0}, }, } for _, c := range cases { @@ -215,26 +121,332 @@ func TestTxIndexer(t *testing.T) { // Index the initial blocks from ancient store indexer := &txIndexer{ - limit: c.limitA, + limit: 0, db: db, progress: make(chan chan TxIndexProgress), } - indexer.run(nil, 128, make(chan struct{}), make(chan struct{})) - verify(db, c.tailA, indexer) - - indexer.limit = c.limitB - indexer.run(rawdb.ReadTxIndexTail(db), 128, make(chan struct{}), make(chan struct{})) - verify(db, c.tailB, indexer) - - indexer.limit = c.limitC - indexer.run(rawdb.ReadTxIndexTail(db), 128, make(chan struct{}), make(chan struct{})) - verify(db, c.tailC, indexer) - - // Recover all indexes - indexer.limit = 0 - indexer.run(rawdb.ReadTxIndexTail(db), 128, make(chan struct{}), make(chan struct{})) - verify(db, 0, indexer) - + for i, limit := range c.limits { + indexer.limit = limit + indexer.run(chainHead, make(chan struct{}), make(chan struct{})) + verify(t, db, blocks, c.tails[i]) + } + db.Close() + } +} + +func TestTxIndexerRepair(t *testing.T) { + var ( + testBankKey, _ = crypto.GenerateKey() + testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) + testBankFunds = big.NewInt(1000000000000000000) + + gspec = &Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, + BaseFee: big.NewInt(params.InitialBaseFee), + } + engine = ethash.NewFaker() + nonce = uint64(0) + chainHead = uint64(128) + ) + _, blocks, receipts := GenerateChainWithGenesis(gspec, engine, int(chainHead), func(i int, gen *BlockGen) { + tx, _ := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("0xdeadbeef"), big.NewInt(1000), params.TxGas, big.NewInt(10*params.InitialBaseFee), nil), types.HomesteadSigner{}, testBankKey) + gen.AddTx(tx) + nonce += 1 + }) + tailPointer := func(n uint64) *uint64 { + return &n + } + var cases = []struct { + limit uint64 + head uint64 + cutoff uint64 + expTail *uint64 + }{ + // if *tail > head => purge indexes + { + limit: 0, + head: chainHead / 2, + cutoff: 0, + expTail: tailPointer(0), + }, + { + limit: 1, // tail = 128 + head: chainHead / 2, // newhead = 64 + cutoff: 0, + expTail: nil, + }, + { + limit: 64, // tail = 65 + head: chainHead / 2, // newhead = 64 + cutoff: 0, + expTail: nil, + }, + { + limit: 65, // tail = 64 + head: chainHead / 2, // newhead = 64 + cutoff: 0, + expTail: tailPointer(64), + }, + { + limit: 66, // tail = 63 + head: chainHead / 2, // newhead = 64 + cutoff: 0, + expTail: tailPointer(63), + }, + + // if tail < cutoff => remove indexes below cutoff + { + limit: 0, // tail = 0 + head: chainHead, // head = 128 + cutoff: chainHead, // cutoff = 128 + expTail: tailPointer(chainHead), + }, + { + limit: 1, // tail = 128 + head: chainHead, // head = 128 + cutoff: chainHead, // cutoff = 128 + expTail: tailPointer(128), + }, + { + limit: 2, // tail = 127 + head: chainHead, // head = 128 + cutoff: chainHead, // cutoff = 128 + expTail: tailPointer(chainHead), + }, + { + limit: 2, // tail = 127 + head: chainHead, // head = 128 + cutoff: chainHead / 2, // cutoff = 64 + expTail: tailPointer(127), + }, + + // if head < cutoff => purge indexes + { + limit: 0, // tail = 0 + head: chainHead, // head = 128 + cutoff: 2 * chainHead, // cutoff = 256 + expTail: nil, + }, + { + limit: 64, // tail = 65 + head: chainHead, // head = 128 + cutoff: chainHead / 2, // cutoff = 64 + expTail: tailPointer(65), + }, + } + for _, c := range cases { + db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...)) + + // Index the initial blocks from ancient store + indexer := &txIndexer{ + limit: c.limit, + db: db, + progress: make(chan chan TxIndexProgress), + } + indexer.run(chainHead, make(chan struct{}), make(chan struct{})) + + indexer.cutoff = c.cutoff + indexer.repair(c.head) + + if c.expTail == nil { + verifyNoIndex(t, db, blocks) + } else { + verify(t, db, blocks, *c.expTail) + } + db.Close() + } +} + +func TestTxIndexerReport(t *testing.T) { + var ( + testBankKey, _ = crypto.GenerateKey() + testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) + testBankFunds = big.NewInt(1000000000000000000) + + gspec = &Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, + BaseFee: big.NewInt(params.InitialBaseFee), + } + engine = ethash.NewFaker() + nonce = uint64(0) + chainHead = uint64(128) + ) + _, blocks, receipts := GenerateChainWithGenesis(gspec, engine, int(chainHead), func(i int, gen *BlockGen) { + tx, _ := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("0xdeadbeef"), big.NewInt(1000), params.TxGas, big.NewInt(10*params.InitialBaseFee), nil), types.HomesteadSigner{}, testBankKey) + gen.AddTx(tx) + nonce += 1 + }) + tailPointer := func(n uint64) *uint64 { + return &n + } + var cases = []struct { + head uint64 + limit uint64 + cutoff uint64 + tail *uint64 + expIndexed uint64 + expRemaining uint64 + }{ + // The entire chain is supposed to be indexed + { + // head = 128, limit = 0, cutoff = 0 => all: 129 + head: chainHead, + limit: 0, + cutoff: 0, + + // tail = 0 + tail: tailPointer(0), + expIndexed: 129, + expRemaining: 0, + }, + { + // head = 128, limit = 0, cutoff = 0 => all: 129 + head: chainHead, + limit: 0, + cutoff: 0, + + // tail = 1 + tail: tailPointer(1), + expIndexed: 128, + expRemaining: 1, + }, + { + // head = 128, limit = 0, cutoff = 0 => all: 129 + head: chainHead, + limit: 0, + cutoff: 0, + + // tail = 128 + tail: tailPointer(chainHead), + expIndexed: 1, + expRemaining: 128, + }, + { + // head = 128, limit = 256, cutoff = 0 => all: 129 + head: chainHead, + limit: 256, + cutoff: 0, + + // tail = 0 + tail: tailPointer(0), + expIndexed: 129, + expRemaining: 0, + }, + + // The chain with specific range is supposed to be indexed + { + // head = 128, limit = 64, cutoff = 0 => index: [65, 128] + head: chainHead, + limit: 64, + cutoff: 0, + + // tail = 0, part of them need to be unindexed + tail: tailPointer(0), + expIndexed: 129, + expRemaining: 0, + }, + { + // head = 128, limit = 64, cutoff = 0 => index: [65, 128] + head: chainHead, + limit: 64, + cutoff: 0, + + // tail = 64, one of them needs to be unindexed + tail: tailPointer(64), + expIndexed: 65, + expRemaining: 0, + }, + { + // head = 128, limit = 64, cutoff = 0 => index: [65, 128] + head: chainHead, + limit: 64, + cutoff: 0, + + // tail = 65, all of them have been indexed + tail: tailPointer(65), + expIndexed: 64, + expRemaining: 0, + }, + { + // head = 128, limit = 64, cutoff = 0 => index: [65, 128] + head: chainHead, + limit: 64, + cutoff: 0, + + // tail = 66, one of them has to be indexed + tail: tailPointer(66), + expIndexed: 63, + expRemaining: 1, + }, + + // The chain with configured cutoff, the chain range could be capped + { + // head = 128, limit = 64, cutoff = 66 => index: [66, 128] + head: chainHead, + limit: 64, + cutoff: 66, + + // tail = 0, part of them need to be unindexed + tail: tailPointer(0), + expIndexed: 129, + expRemaining: 0, + }, + { + // head = 128, limit = 64, cutoff = 66 => index: [66, 128] + head: chainHead, + limit: 64, + cutoff: 66, + + // tail = 66, all of them have been indexed + tail: tailPointer(66), + expIndexed: 63, + expRemaining: 0, + }, + { + // head = 128, limit = 64, cutoff = 66 => index: [66, 128] + head: chainHead, + limit: 64, + cutoff: 66, + + // tail = 67, one of them has to be indexed + tail: tailPointer(67), + expIndexed: 62, + expRemaining: 1, + }, + { + // head = 128, limit = 64, cutoff = 256 => index: [66, 128] + head: chainHead, + limit: 0, + cutoff: 256, + tail: nil, + expIndexed: 0, + expRemaining: 0, + }, + } + for _, c := range cases { + db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...)) + + // Index the initial blocks from ancient store + indexer := &txIndexer{ + limit: c.limit, + cutoff: c.cutoff, + db: db, + progress: make(chan chan TxIndexProgress), + } + if c.tail != nil { + rawdb.WriteTxIndexTail(db, *c.tail) + } + p := indexer.report(c.head) + if p.Indexed != c.expIndexed { + t.Fatalf("Unexpected indexed: %d, expected: %d", p.Indexed, c.expIndexed) + } + if p.Remaining != c.expRemaining { + t.Fatalf("Unexpected remaining: %d, expected: %d", p.Remaining, c.expRemaining) + } db.Close() } } From 8fe09df54f55c2803f492a4be3bd16a43fa7b659 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 21 Mar 2025 13:12:56 +0100 Subject: [PATCH 220/940] cmd/geth: add prune history command (#31384) This adds a new subcommand 'geth prune-history' that removes the pre-merge history on supported networks. Geth is not fully ready to work in this mode, please do not run this command on your production node. --------- Co-authored-by: Felix Lange --- cmd/geth/chaincmd.go | 61 ++++++++++++++++++++++ cmd/geth/main.go | 1 + core/blockchain.go | 3 +- core/rawdb/accessors_indexes.go | 5 +- core/rawdb/chain_iterator.go | 36 +++++++++++++ core/rawdb/chain_iterator_test.go | 85 +++++++++++++++++++++++-------- core/txindexer.go | 3 +- tests/testdata | 2 +- 8 files changed, 171 insertions(+), 25 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 95239bd640..05c8bc4c7c 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -35,6 +35,7 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/era" "github.com/ethereum/go-ethereum/log" @@ -189,6 +190,18 @@ It's deprecated, please use "geth db import" instead. This command dumps out the state for a given block (or latest, if none provided). `, } + + pruneCommand = &cli.Command{ + Action: pruneHistory, + Name: "prune-history", + Usage: "Prune blockchain history (block bodies and receipts) up to the merge block", + ArgsUsage: "", + Flags: utils.DatabaseFlags, + Description: ` +The prune-history command removes historical block bodies and receipts from the +blockchain database up to the merge block, while preserving block headers. This +helps reduce storage requirements for nodes that don't need full historical data.`, + } ) // initGenesis will initialise the given JSON format genesis file and writes it as @@ -598,3 +611,51 @@ func hashish(x string) bool { _, err := strconv.Atoi(x) return err != nil } + +func pruneHistory(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + // Open the chain database + chain, chaindb := utils.MakeChain(ctx, stack, false) + defer chaindb.Close() + defer chain.Stop() + + // Determine the prune point. This will be the first PoS block. + prunePoint, ok := ethconfig.HistoryPrunePoints[chain.Genesis().Hash()] + if !ok || prunePoint == nil { + return errors.New("prune point not found") + } + var ( + mergeBlock = prunePoint.BlockNumber + mergeBlockHash = prunePoint.BlockHash.Hex() + ) + + // Check we're far enough past merge to ensure all data is in freezer + currentHeader := chain.CurrentHeader() + if currentHeader == nil { + return errors.New("current header not found") + } + if currentHeader.Number.Uint64() < mergeBlock+params.FullImmutabilityThreshold { + return fmt.Errorf("chain not far enough past merge block, need %d more blocks", + mergeBlock+params.FullImmutabilityThreshold-currentHeader.Number.Uint64()) + } + + // Double-check the prune block in db has the expected hash. + hash := rawdb.ReadCanonicalHash(chaindb, mergeBlock) + if hash != common.HexToHash(mergeBlockHash) { + return fmt.Errorf("merge block hash mismatch: got %s, want %s", hash.Hex(), mergeBlockHash) + } + + log.Info("Starting history pruning", "head", currentHeader.Number, "tail", mergeBlock, "tailHash", mergeBlockHash) + start := time.Now() + rawdb.PruneTransactionIndex(chaindb, mergeBlock) + if _, err := chaindb.TruncateTail(mergeBlock); err != nil { + return fmt.Errorf("failed to truncate ancient data: %v", err) + } + log.Info("History pruning completed", "tail", mergeBlock, "elapsed", common.PrettyDuration(time.Since(start))) + + // TODO(s1na): what if there is a crash between the two prune operations? + + return nil +} diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 07fbeaca5c..9c0c0d9dfc 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -226,6 +226,7 @@ func init() { removedbCommand, dumpCommand, dumpGenesisCommand, + pruneCommand, // See accountcmd.go: accountCommand, walletCommand, diff --git a/core/blockchain.go b/core/blockchain.go index 2bf7fba427..d80236c902 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -332,7 +332,8 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis bc.prefetcher = newStatePrefetcher(chainConfig, bc.hc) bc.processor = NewStateProcessor(chainConfig, bc.hc) - bc.genesisBlock = bc.GetBlockByNumber(0) + genesisHeader := bc.GetHeaderByNumber(0) + bc.genesisBlock = types.NewBlockWithHeader(genesisHeader) if bc.genesisBlock == nil { return nil, ErrNoGenesis } diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index 342aedd8dc..7bb96b1fa1 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -103,13 +103,14 @@ func DeleteTxLookupEntries(db ethdb.KeyValueWriter, hashes []common.Hash) { // DeleteAllTxLookupEntries purges all the transaction indexes in the database. // If condition is specified, only the entry with condition as True will be // removed; If condition is not specified, the entry is deleted. -func DeleteAllTxLookupEntries(db ethdb.KeyValueStore, condition func([]byte) bool) { +func DeleteAllTxLookupEntries(db ethdb.KeyValueStore, condition func(common.Hash, []byte) bool) { iter := NewKeyLengthIterator(db.NewIterator(txLookupPrefix, nil), common.HashLength+len(txLookupPrefix)) defer iter.Release() batch := db.NewBatch() for iter.Next() { - if condition == nil || condition(iter.Value()) { + txhash := common.Hash(iter.Key()[1:]) + if condition == nil || condition(txhash, iter.Value()) { batch.Delete(iter.Key()) } if batch.ValueSize() >= ethdb.IdealBatchSize { diff --git a/core/rawdb/chain_iterator.go b/core/rawdb/chain_iterator.go index 759e5913d1..ecbc44e1f1 100644 --- a/core/rawdb/chain_iterator.go +++ b/core/rawdb/chain_iterator.go @@ -17,6 +17,7 @@ package rawdb import ( + "encoding/binary" "runtime" "sync/atomic" "time" @@ -361,3 +362,38 @@ func UnindexTransactions(db ethdb.Database, from uint64, to uint64, interrupt ch func unindexTransactionsForTesting(db ethdb.Database, from uint64, to uint64, interrupt chan struct{}, hook func(uint64) bool) { unindexTransactions(db, from, to, interrupt, hook, false) } + +// PruneTransactionIndex removes all tx index entries below a certain block number. +func PruneTransactionIndex(db ethdb.Database, pruneBlock uint64) { + tail := ReadTxIndexTail(db) + if tail == nil || *tail > pruneBlock { + return // no index, or index ends above pruneBlock + } + // There are blocks below pruneBlock in the index. Iterate the entire index to remove + // their entries. Note if this fails, the index is messed up, but tail still points to + // the old tail. + var count, removed int + DeleteAllTxLookupEntries(db, func(txhash common.Hash, v []byte) bool { + count++ + if count%10000000 == 0 { + log.Info("Pruning tx index", "count", count, "removed", removed) + } + if len(v) > 8 { + log.Error("Skipping legacy tx index entry", "hash", txhash) + return false + } + bn := decodeNumber(v) + if bn < pruneBlock { + removed++ + return true + } + return false + }) + WriteTxIndexTail(db, pruneBlock) +} + +func decodeNumber(b []byte) uint64 { + var numBuffer [8]byte + copy(numBuffer[8-len(b):], b) + return binary.BigEndian.Uint64(numBuffer[:]) +} diff --git a/core/rawdb/chain_iterator_test.go b/core/rawdb/chain_iterator_test.go index 390424f673..75bd5a9a94 100644 --- a/core/rawdb/chain_iterator_test.go +++ b/core/rawdb/chain_iterator_test.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" ) func TestChainIterator(t *testing.T) { @@ -102,19 +103,18 @@ func TestChainIterator(t *testing.T) { } } -func TestIndexTransactions(t *testing.T) { - // Construct test chain db - chainDb := NewMemoryDatabase() - - var block *types.Block +func initDatabaseWithTransactions(db ethdb.Database) ([]*types.Block, []*types.Transaction) { + var blocks []*types.Block var txs []*types.Transaction to := common.BytesToAddress([]byte{0x11}) // Write empty genesis block - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher()) - WriteBlock(chainDb, block) - WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) + block := types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher()) + WriteBlock(db, block) + WriteCanonicalHash(db, block.Hash(), block.NumberU64()) + blocks = append(blocks, block) + // Create transactions. for i := uint64(1); i <= 10; i++ { var tx *types.Transaction if i%2 == 0 { @@ -138,10 +138,21 @@ func TestIndexTransactions(t *testing.T) { }) } txs = append(txs, tx) - 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()) + block := types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher()) + WriteBlock(db, block) + WriteCanonicalHash(db, block.Hash(), block.NumberU64()) + blocks = append(blocks, block) } + + return blocks, txs +} + +func TestIndexTransactions(t *testing.T) { + // Construct test chain db + chainDB := NewMemoryDatabase() + + _, txs := initDatabaseWithTransactions(chainDB) + // verify checks whether the tx indices in the range [from, to) // is expected. verify := func(from, to int, exist bool, tail uint64) { @@ -149,7 +160,7 @@ func TestIndexTransactions(t *testing.T) { if i == 0 { continue } - number := ReadTxLookupEntry(chainDb, txs[i-1].Hash()) + number := ReadTxLookupEntry(chainDB, txs[i-1].Hash()) if exist && number == nil { t.Fatalf("Transaction index %d missing", i) } @@ -157,29 +168,29 @@ func TestIndexTransactions(t *testing.T) { t.Fatalf("Transaction index %d is not deleted", i) } } - number := ReadTxIndexTail(chainDb) + number := ReadTxIndexTail(chainDB) if number == nil || *number != tail { t.Fatalf("Transaction tail mismatch") } } - IndexTransactions(chainDb, 5, 11, nil, false) + IndexTransactions(chainDB, 5, 11, nil, false) verify(5, 11, true, 5) verify(0, 5, false, 5) - IndexTransactions(chainDb, 0, 5, nil, false) + IndexTransactions(chainDB, 0, 5, nil, false) verify(0, 11, true, 0) - UnindexTransactions(chainDb, 0, 5, nil, false) + UnindexTransactions(chainDB, 0, 5, nil, false) verify(5, 11, true, 5) verify(0, 5, false, 5) - UnindexTransactions(chainDb, 5, 11, nil, false) + UnindexTransactions(chainDB, 5, 11, nil, false) verify(0, 11, false, 11) // Testing corner cases signal := make(chan struct{}) var once sync.Once - indexTransactionsForTesting(chainDb, 5, 11, signal, func(n uint64) bool { + indexTransactionsForTesting(chainDB, 5, 11, signal, func(n uint64) bool { if n <= 8 { once.Do(func() { close(signal) @@ -190,11 +201,11 @@ func TestIndexTransactions(t *testing.T) { }) verify(9, 11, true, 9) verify(0, 9, false, 9) - IndexTransactions(chainDb, 0, 9, nil, false) + IndexTransactions(chainDB, 0, 9, nil, false) signal = make(chan struct{}) var once2 sync.Once - unindexTransactionsForTesting(chainDb, 0, 11, signal, func(n uint64) bool { + unindexTransactionsForTesting(chainDB, 0, 11, signal, func(n uint64) bool { if n >= 8 { once2.Do(func() { close(signal) @@ -206,3 +217,37 @@ func TestIndexTransactions(t *testing.T) { verify(8, 11, true, 8) verify(0, 8, false, 8) } + +func TestPruneTransactionIndex(t *testing.T) { + chainDB := NewMemoryDatabase() + blocks, _ := initDatabaseWithTransactions(chainDB) + lastBlock := blocks[len(blocks)-1].NumberU64() + pruneBlock := lastBlock - 3 + + IndexTransactions(chainDB, 0, lastBlock+1, nil, false) + + // Check all transactions are in index. + for _, block := range blocks { + for _, tx := range block.Transactions() { + num := ReadTxLookupEntry(chainDB, tx.Hash()) + if num == nil || *num != block.NumberU64() { + t.Fatalf("wrong TxLookup entry: %x -> %v", tx.Hash(), num) + } + } + } + + PruneTransactionIndex(chainDB, pruneBlock) + + // Check transactions from old blocks not included. + for _, block := range blocks { + for _, tx := range block.Transactions() { + num := ReadTxLookupEntry(chainDB, tx.Hash()) + if block.NumberU64() < pruneBlock && num != nil { + t.Fatalf("TxLookup entry not removed: %x -> %v", tx.Hash(), num) + } + if block.NumberU64() >= pruneBlock && (num == nil || *num != block.NumberU64()) { + t.Fatalf("wrong TxLookup entry after pruning: %x -> %v", tx.Hash(), num) + } + } + } +} diff --git a/core/txindexer.go b/core/txindexer.go index 29e87905d5..d0fce302f3 100644 --- a/core/txindexer.go +++ b/core/txindexer.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" @@ -186,7 +187,7 @@ func (indexer *txIndexer) repair(head uint64) { // potentially leaving dangling indexes in the database. // However, this is considered acceptable. rawdb.WriteTxIndexTail(indexer.db, indexer.cutoff) - rawdb.DeleteAllTxLookupEntries(indexer.db, func(blob []byte) bool { + rawdb.DeleteAllTxLookupEntries(indexer.db, func(txhash common.Hash, blob []byte) bool { n := rawdb.DecodeTxLookupEntry(blob, indexer.db) return n != nil && *n < indexer.cutoff }) diff --git a/tests/testdata b/tests/testdata index 81862e4848..faf33b4714 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit 81862e4848585a438d64f911a19b3825f0f4cd95 +Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2 From 624a5d8b235961a53f3091f86570d71c1cb872c4 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 21 Mar 2025 21:08:51 +0800 Subject: [PATCH 221/940] eth/filter: downgrade log level (#31450) --- eth/filters/filter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eth/filters/filter.go b/eth/filters/filter.go index cedb5b3519..b743c25994 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -372,7 +372,7 @@ func (f *Filter) indexedLogs(ctx context.Context, mb filtermaps.MatcherBackend, // iteration and bloom matching. func (f *Filter) unindexedLogs(ctx context.Context, begin, end uint64) ([]*types.Log, error) { start := time.Now() - log.Warn("Performing unindexed log search", "begin", begin, "end", end) + log.Debug("Performing unindexed log search", "begin", begin, "end", end) var matches []*types.Log for blockNumber := begin; blockNumber <= end; blockNumber++ { select { @@ -390,7 +390,7 @@ func (f *Filter) unindexedLogs(ctx context.Context, begin, end uint64) ([]*types } matches = append(matches, found...) } - log.Trace("Performed unindexed log search", "begin", begin, "end", end, "matches", len(matches), "elapsed", common.PrettyDuration(time.Since(start))) + log.Debug("Performed unindexed log search", "begin", begin, "end", end, "matches", len(matches), "elapsed", common.PrettyDuration(time.Since(start))) return matches, nil } From b0b2b765094ed4abc490ba26bc3be431c84c5b96 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Sun, 23 Mar 2025 17:38:26 +0100 Subject: [PATCH 222/940] internal/ethapi: return code 3 from call/estimateGas even if a revert reason was not returned (#31456) --- internal/ethapi/api.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index f3975d35a0..979a7e822a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -761,8 +761,7 @@ func (api *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockN if err != nil { return nil, err } - // If the result contains a revert reason, try to unpack and return it. - if len(result.Revert()) > 0 { + if errors.Is(result.Err, vm.ErrExecutionReverted) { return nil, newRevertError(result.Revert()) } return result.Return(), result.Err @@ -842,7 +841,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr // 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 { + if errors.Is(err, vm.ErrExecutionReverted) { return 0, newRevertError(revert) } return 0, err From fd4049dc1e9d8e80368c9e1ae1da5c2fd81644c5 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 24 Mar 2025 10:07:38 +0100 Subject: [PATCH 223/940] core/rawdb: improve database stats output (#31463) Instead of reporting all filtermaps stuff in one line, I'm breaking it down into the three separate kinds of entries here. ``` +-----------------------+-----------------------------+------------+------------+ | DATABASE | CATEGORY | SIZE | ITEMS | +-----------------------+-----------------------------+------------+------------+ | Key-Value store | Log index filter-map rows | 59.21 GiB | 616077345 | | Key-Value store | Log index last-block-of-map | 12.35 MiB | 269755 | | Key-Value store | Log index block-lv | 421.70 MiB | 22109169 | ``` Also added some other changes to make it easier to debug: - restored bloombits into the inspect output, so we notice if it doesn't get deleted for some reason - tracking of unaccounted key examples --- core/rawdb/accessors_indexes.go | 2 +- core/rawdb/database.go | 123 +++++++++++++++++++++----------- core/rawdb/schema.go | 23 +++--- 3 files changed, 94 insertions(+), 54 deletions(-) diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index 7bb96b1fa1..297e339c83 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -502,5 +502,5 @@ func DeleteBloomBitsDb(db ethdb.KeyValueRangeDeleter) error { if err := deletePrefixRange(db, bloomBitsPrefix); err != nil { return err } - return deletePrefixRange(db, bloomBitsIndexPrefix) + return deletePrefixRange(db, bloomBitsMetaPrefix) } diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 4c87e66cfd..a394f46e0a 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -20,8 +20,10 @@ import ( "bytes" "errors" "fmt" + "maps" "os" "path/filepath" + "slices" "strings" "time" @@ -360,24 +362,27 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { logged = time.Now() // Key-value store statistics - headers stat - bodies stat - receipts stat - tds stat - numHashPairings stat - hashNumPairings stat - legacyTries stat - stateLookups stat - accountTries stat - storageTries stat - codes stat - txLookups stat - accountSnaps stat - storageSnaps stat - preimages stat - filterMaps stat - beaconHeaders stat - cliqueSnaps stat + headers stat + bodies stat + receipts stat + tds stat + numHashPairings stat + hashNumPairings stat + legacyTries stat + stateLookups stat + accountTries stat + storageTries stat + codes stat + txLookups stat + accountSnaps stat + storageSnaps stat + preimages stat + beaconHeaders stat + cliqueSnaps stat + bloomBits stat + filterMapRows stat + filterMapLastBlock stat + filterMapBlockLV stat // Verkle statistics verkleTries stat @@ -393,6 +398,11 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { // Totals total common.StorageSize + + // This map tracks example keys for unaccounted data. + // For each unique two-byte prefix, the first unaccounted key encountered + // by the iterator will be stored. + unaccountedKeys = make(map[[2]byte][]byte) ) // Inspect key-value database first. for it.Next() { @@ -436,19 +446,33 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { metadata.Add(size) case bytes.HasPrefix(key, genesisPrefix) && len(key) == (len(genesisPrefix)+common.HashLength): metadata.Add(size) - case bytes.HasPrefix(key, []byte(filterMapsPrefix)): - filterMaps.Add(size) case bytes.HasPrefix(key, skeletonHeaderPrefix) && len(key) == (len(skeletonHeaderPrefix)+8): beaconHeaders.Add(size) case bytes.HasPrefix(key, CliqueSnapshotPrefix) && len(key) == 7+common.HashLength: cliqueSnaps.Add(size) - case bytes.HasPrefix(key, ChtTablePrefix) || - bytes.HasPrefix(key, ChtIndexTablePrefix) || - bytes.HasPrefix(key, ChtPrefix): // Canonical hash trie + + // new log index + case bytes.HasPrefix(key, filterMapRowPrefix) && len(key) <= len(filterMapRowPrefix)+9: + filterMapRows.Add(size) + case bytes.HasPrefix(key, filterMapLastBlockPrefix) && len(key) == len(filterMapLastBlockPrefix)+4: + filterMapLastBlock.Add(size) + case bytes.HasPrefix(key, filterMapBlockLVPrefix) && len(key) == len(filterMapBlockLVPrefix)+8: + filterMapBlockLV.Add(size) + + // old log index (deprecated) + case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength): + bloomBits.Add(size) + case bytes.HasPrefix(key, bloomBitsMetaPrefix) && len(key) < len(bloomBitsMetaPrefix)+8: + bloomBits.Add(size) + + // LES indexes (deprecated) + case bytes.HasPrefix(key, chtTablePrefix) || + bytes.HasPrefix(key, chtIndexTablePrefix) || + bytes.HasPrefix(key, chtPrefix): // Canonical hash trie chtTrieNodes.Add(size) - case bytes.HasPrefix(key, BloomTrieTablePrefix) || - bytes.HasPrefix(key, BloomTrieIndexPrefix) || - bytes.HasPrefix(key, BloomTriePrefix): // Bloomtrie sub + case bytes.HasPrefix(key, bloomTrieTablePrefix) || + bytes.HasPrefix(key, bloomTrieIndexPrefix) || + bytes.HasPrefix(key, bloomTriePrefix): // Bloomtrie sub bloomTrieNodes.Add(size) // Verkle trie data is detected, determine the sub-category @@ -468,24 +492,19 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { default: unaccounted.Add(size) } + + // Metadata keys + case slices.ContainsFunc(knownMetadataKeys, func(x []byte) bool { return bytes.Equal(x, key) }): + metadata.Add(size) + default: - var accounted bool - for _, meta := range [][]byte{ - databaseVersionKey, headHeaderKey, headBlockKey, headFastBlockKey, headFinalizedBlockKey, - lastPivotKey, fastTrieProgressKey, snapshotDisabledKey, SnapshotRootKey, snapshotJournalKey, - snapshotGeneratorKey, snapshotRecoveryKey, txIndexTailKey, fastTxLookupLimitKey, - uncleanShutdownKey, badBlockKey, transitionStatusKey, skeletonSyncStatusKey, - persistentStateIDKey, trieJournalKey, snapshotSyncStatusKey, snapSyncStatusFlagKey, - } { - if bytes.Equal(key, meta) { - metadata.Add(size) - accounted = true - break + unaccounted.Add(size) + if len(key) >= 2 { + prefix := [2]byte(key[:2]) + if _, ok := unaccountedKeys[prefix]; !ok { + unaccountedKeys[prefix] = bytes.Clone(key) } } - if !accounted { - unaccounted.Add(size) - } } count++ if count%1000 == 0 && time.Since(logged) > 8*time.Second { @@ -502,7 +521,10 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { {"Key-Value store", "Block number->hash", numHashPairings.Size(), numHashPairings.Count()}, {"Key-Value store", "Block hash->number", hashNumPairings.Size(), hashNumPairings.Count()}, {"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()}, - {"Key-Value store", "Log search index", filterMaps.Size(), filterMaps.Count()}, + {"Key-Value store", "Log index filter-map rows", filterMapRows.Size(), filterMapRows.Count()}, + {"Key-Value store", "Log index last-block-of-map", filterMapLastBlock.Size(), filterMapLastBlock.Count()}, + {"Key-Value store", "Log index block-lv", filterMapBlockLV.Size(), filterMapBlockLV.Count()}, + {"Key-Value store", "Log bloombits (deprecated)", bloomBits.Size(), bloomBits.Count()}, {"Key-Value store", "Contract codes", codes.Size(), codes.Count()}, {"Key-Value store", "Hash trie nodes", legacyTries.Size(), legacyTries.Count()}, {"Key-Value store", "Path trie state lookups", stateLookups.Size(), stateLookups.Count()}, @@ -543,10 +565,23 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { if unaccounted.size > 0 { log.Error("Database contains unaccounted data", "size", unaccounted.size, "count", unaccounted.count) + for _, e := range slices.SortedFunc(maps.Values(unaccountedKeys), bytes.Compare) { + log.Error(fmt.Sprintf(" example key: %x", e)) + } } return nil } +// This is the list of known 'metadata' keys stored in the databasse. +var knownMetadataKeys = [][]byte{ + databaseVersionKey, headHeaderKey, headBlockKey, headFastBlockKey, headFinalizedBlockKey, + lastPivotKey, fastTrieProgressKey, snapshotDisabledKey, SnapshotRootKey, snapshotJournalKey, + snapshotGeneratorKey, snapshotRecoveryKey, txIndexTailKey, fastTxLookupLimitKey, + uncleanShutdownKey, badBlockKey, transitionStatusKey, skeletonSyncStatusKey, + persistentStateIDKey, trieJournalKey, snapshotSyncStatusKey, snapSyncStatusFlagKey, + filterMapsRangeKey, +} + // printChainMetadata prints out chain metadata to stderr. func printChainMetadata(db ethdb.KeyValueStore) { fmt.Fprintf(os.Stderr, "Chain metadata\n") @@ -566,6 +601,7 @@ func ReadChainMetadata(db ethdb.KeyValueStore) [][]string { } return fmt.Sprintf("%d (%#x)", *val, *val) } + data := [][]string{ {"databaseVersion", pp(ReadDatabaseVersion(db))}, {"headBlockHash", fmt.Sprintf("%v", ReadHeadBlockHash(db))}, @@ -582,5 +618,8 @@ func ReadChainMetadata(db ethdb.KeyValueStore) [][]string { if b := ReadSkeletonSyncStatus(db); b != nil { data = append(data, []string{"SkeletonSyncStatus", string(b)}) } + if fmr, ok, _ := ReadFilterMapsRange(db); ok { + data = append(data, []string{"filterMapsRange", fmt.Sprintf("%+v", fmr)}) + } return data } diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index c21a96bd24..31e80da079 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -128,29 +128,30 @@ var ( configPrefix = []byte("ethereum-config-") // config prefix for the db genesisPrefix = []byte("ethereum-genesis-") // genesis state prefix for the db - // bloomBitsIndexPrefix is the data table of a chain indexer to track its progress - bloomBitsIndexPrefix = []byte("iB") - - ChtPrefix = []byte("chtRootV2-") // ChtPrefix + chtNum (uint64 big endian) -> trie root hash - ChtTablePrefix = []byte("cht-") - ChtIndexTablePrefix = []byte("chtIndexV2-") - - BloomTriePrefix = []byte("bltRoot-") // BloomTriePrefix + bloomTrieNum (uint64 big endian) -> trie root hash - BloomTrieTablePrefix = []byte("blt-") - BloomTrieIndexPrefix = []byte("bltIndex-") - CliqueSnapshotPrefix = []byte("clique-") BestUpdateKey = []byte("update-") // bigEndian64(syncPeriod) -> RLP(types.LightClientUpdate) (nextCommittee only referenced by root hash) FixedCommitteeRootKey = []byte("fixedRoot-") // bigEndian64(syncPeriod) -> committee root hash SyncCommitteeKey = []byte("committee-") // bigEndian64(syncPeriod) -> serialized committee + // new log index filterMapsPrefix = "fm-" filterMapsRangeKey = []byte(filterMapsPrefix + "R") filterMapRowPrefix = []byte(filterMapsPrefix + "r") // filterMapRowPrefix + mapRowIndex (uint64 big endian) -> filter row filterMapLastBlockPrefix = []byte(filterMapsPrefix + "b") // filterMapLastBlockPrefix + mapIndex (uint32 big endian) -> block number (uint64 big endian) filterMapBlockLVPrefix = []byte(filterMapsPrefix + "p") // filterMapBlockLVPrefix + num (uint64 big endian) -> log value pointer (uint64 big endian) + // old log index + bloomBitsMetaPrefix = []byte("iB") + + // LES indexes + chtPrefix = []byte("chtRootV2-") // ChtPrefix + chtNum (uint64 big endian) -> trie root hash + chtTablePrefix = []byte("cht-") + chtIndexTablePrefix = []byte("chtIndexV2-") + bloomTriePrefix = []byte("bltRoot-") // BloomTriePrefix + bloomTrieNum (uint64 big endian) -> trie root hash + bloomTrieTablePrefix = []byte("blt-") + bloomTrieIndexPrefix = []byte("bltIndex-") + preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) preimageHitsCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) preimageMissCounter = metrics.NewRegisteredCounter("db/preimage/miss", nil) From cbe902d5dadd5fb356f54f85dee7bdf556fa608e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Mon, 24 Mar 2025 12:27:11 +0100 Subject: [PATCH 224/940] core/filtermaps: fix log indexer init conditions (#31455) This PR adds an extra condition to the log indexer initialization in order to avoid initializing with block 0 as target head. Previously this caused the indexer to initialize without a checkpoint. Later, when the real chain head was set, it indexed the entire history, then unindexed most of it if only the recent history was supposed to be indexed. Now the init only happens when there is an actual synced chain head and therefore the index is initialized at the most recent checkpoint and only the last year is indexed according to the default parameters. During checkpoint initialization the best available checkpoint is also checked against the history cutoff point and fails if the indexing would have to start from a block older than the cutoff. If initialization fails then the indexer reverts to unindexed mode instead of retrying because the the failure conditions cannot be expected to recover later. --- core/filtermaps/filtermaps.go | 29 +++++++++++++++++++++++++---- core/filtermaps/indexer.go | 15 ++++++++++----- core/filtermaps/matcher_backend.go | 8 ++++---- eth/backend.go | 7 ++++++- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index d74b11da04..db7ab0a426 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -53,7 +53,8 @@ type FilterMaps struct { // This is configured by the --history.logs.disable Geth flag. // We chose to implement disabling this way because it requires less special // case logic in eth/filters. - disabled bool + disabled bool + disabledCh chan struct{} // closed by indexer if disabled closeCh chan struct{} closeWg sync.WaitGroup @@ -196,6 +197,7 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f blockProcessingCh: make(chan bool, 1), history: config.History, disabled: config.Disabled, + disabledCh: make(chan struct{}), exportFileName: config.ExportFileName, Params: params, indexedRange: filterMapsRange{ @@ -206,6 +208,8 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f maps: common.NewRange(rs.MapsFirst, rs.MapsAfterLast-rs.MapsFirst), tailPartialEpoch: rs.TailPartialEpoch, }, + historyCutoff: historyCutoff, + finalBlock: finalBlock, matcherSyncCh: make(chan *FilterMapsMatcherBackend), matchers: make(map[*FilterMapsMatcherBackend]struct{}), filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps), @@ -278,8 +282,13 @@ func (f *FilterMaps) initChainView(chainView *ChainView) *ChainView { } // reset un-initializes the FilterMaps structure and removes all related data from -// the database. The function returns true if everything was successfully removed. -func (f *FilterMaps) reset() bool { +// the database. +// Note that in case of leveldb database the fallback implementation of DeleteRange +// might take a long time to finish and deleting the entire database may be +// interrupted by a shutdown. Deleting the filterMapsRange entry first does +// guarantee though that the next init() will not return successfully until the +// entire database has been cleaned. +func (f *FilterMaps) reset() { f.indexLock.Lock() f.indexedRange = filterMapsRange{} f.indexedView = nil @@ -292,11 +301,16 @@ func (f *FilterMaps) reset() bool { // deleting the range first ensures that resetDb will be called again at next // startup and any leftover data will be removed even if it cannot finish now. rawdb.DeleteFilterMapsRange(f.db) - return f.safeDeleteRange(rawdb.DeleteFilterMapsDb, "Resetting log index database") + f.safeDeleteRange(rawdb.DeleteFilterMapsDb, "Resetting log index database") } // init initializes an empty log index according to the current targetView. func (f *FilterMaps) init() error { + // ensure that there is no remaining data in the filter maps key range + if !f.safeDeleteRange(rawdb.DeleteFilterMapsDb, "Resetting log index database") { + return errors.New("could not reset log index database") + } + f.indexLock.Lock() defer f.indexLock.Unlock() @@ -317,6 +331,13 @@ func (f *FilterMaps) init() error { bestIdx, bestLen = idx, max } } + var initBlockNumber uint64 + if bestLen > 0 { + initBlockNumber = checkpoints[bestIdx][bestLen-1].BlockNumber + } + if initBlockNumber < f.historyCutoff { + return errors.New("cannot start indexing before history cutoff point") + } batch := f.db.NewBatch() for epoch := range bestLen { cp := checkpoints[bestIdx][epoch] diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 69f42d8b60..026b3b4f38 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -36,20 +36,25 @@ func (f *FilterMaps) indexerLoop() { if f.disabled { f.reset() + close(f.disabledCh) return } log.Info("Started log indexer") for !f.stop { if !f.indexedRange.initialized { - if err := f.init(); err != nil { - log.Error("Error initializing log index", "error", err) - // unexpected error; there is not a lot we can do here, maybe it - // recovers, maybe not. Calling event processing here ensures - // that we can still properly shutdown in case of an infinite loop. + if f.targetView.headNumber == 0 { + // initialize when chain head is available f.processSingleEvent(true) continue } + if err := f.init(); err != nil { + log.Error("Error initializing log index; reverting to unindexed mode", "error", err) + f.reset() + f.disabled = true + close(f.disabledCh) + return + } } if !f.targetHeadIndexed() { if !f.tryIndexHead() { diff --git a/core/filtermaps/matcher_backend.go b/core/filtermaps/matcher_backend.go index f24e9706cb..01bae7bb22 100644 --- a/core/filtermaps/matcher_backend.go +++ b/core/filtermaps/matcher_backend.go @@ -141,10 +141,6 @@ func (fm *FilterMapsMatcherBackend) synced() { // range that has not been changed and has been consistent with all states of the // chain since the previous SyncLogIndex or the creation of the matcher backend. func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange, error) { - if fm.f.disabled { - return SyncRange{HeadNumber: fm.f.targetView.headNumber}, nil - } - syncCh := make(chan SyncRange, 1) fm.f.matchersLock.Lock() fm.syncCh = syncCh @@ -154,12 +150,16 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange case fm.f.matcherSyncCh <- fm: case <-ctx.Done(): return SyncRange{}, ctx.Err() + case <-fm.f.disabledCh: + return SyncRange{HeadNumber: fm.f.targetView.headNumber}, nil } select { case vr := <-syncCh: return vr, nil case <-ctx.Done(): return SyncRange{}, ctx.Err() + case <-fm.f.disabledCh: + return SyncRange{HeadNumber: fm.f.targetView.headNumber}, nil } } diff --git a/eth/backend.go b/eth/backend.go index 6deedab872..909d153a2b 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -241,7 +241,12 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } fmConfig := filtermaps.Config{History: config.LogHistory, Disabled: config.LogNoHistory, ExportFileName: config.LogExportCheckpoints} chainView := eth.newChainView(eth.blockchain.CurrentBlock()) - eth.filterMaps = filtermaps.NewFilterMaps(chainDb, chainView, 0, 0, filtermaps.DefaultParams, fmConfig) + historyCutoff := eth.blockchain.HistoryPruningCutoff() + var finalBlock uint64 + if fb := eth.blockchain.CurrentFinalBlock(); fb != nil { + finalBlock = fb.Number.Uint64() + } + eth.filterMaps = filtermaps.NewFilterMaps(chainDb, chainView, historyCutoff, finalBlock, filtermaps.DefaultParams, fmConfig) eth.closeFilterMaps = make(chan chan struct{}) if config.BlobPool.Datadir != "" { From 28238b6b7e004d838762bf96aa4c5be1271e5954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Mon, 24 Mar 2025 12:27:40 +0100 Subject: [PATCH 225/940] beacon/params: new checkpoints (#31470) This PR updates beacon checkpoints. The checkpoints are now stored as embedded hex files, in the same format that https://github.com/ethereum/go-ethereum/pull/31469 uses. --- beacon/params/checkpoint_holesky.hex | 1 + beacon/params/checkpoint_mainnet.hex | 1 + beacon/params/checkpoint_sepolia.hex | 1 + beacon/params/networks.go | 17 ++++++++++++++--- 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 beacon/params/checkpoint_holesky.hex create mode 100644 beacon/params/checkpoint_mainnet.hex create mode 100644 beacon/params/checkpoint_sepolia.hex diff --git a/beacon/params/checkpoint_holesky.hex b/beacon/params/checkpoint_holesky.hex new file mode 100644 index 0000000000..f1e27b48f6 --- /dev/null +++ b/beacon/params/checkpoint_holesky.hex @@ -0,0 +1 @@ +0xf5606a019f0f1006e9ec2070695045f4334450362a48da4c5965314510e0b4c3 \ No newline at end of file diff --git a/beacon/params/checkpoint_mainnet.hex b/beacon/params/checkpoint_mainnet.hex new file mode 100644 index 0000000000..a11c3394bb --- /dev/null +++ b/beacon/params/checkpoint_mainnet.hex @@ -0,0 +1 @@ +0x3c0cb4aa83beded1803d262664ba4392b1023f334d9cca02dc3a6925987ebe91 \ No newline at end of file diff --git a/beacon/params/checkpoint_sepolia.hex b/beacon/params/checkpoint_sepolia.hex new file mode 100644 index 0000000000..e4f2f96733 --- /dev/null +++ b/beacon/params/checkpoint_sepolia.hex @@ -0,0 +1 @@ +0xa8d56457aa414523d93659aef1f7409bbfb72ad75e94d917c8c0b1baa38153ef \ No newline at end of file diff --git a/beacon/params/networks.go b/beacon/params/networks.go index c547986977..7e73a2c69c 100644 --- a/beacon/params/networks.go +++ b/beacon/params/networks.go @@ -17,14 +17,25 @@ package params import ( + _ "embed" + "github.com/ethereum/go-ethereum/common" ) +//go:embed checkpoint_mainnet.hex +var checkpointMainnet string + +//go:embed checkpoint_sepolia.hex +var checkpointSepolia string + +//go:embed checkpoint_holesky.hex +var checkpointHolesky string + var ( MainnetLightConfig = (&ChainConfig{ GenesisValidatorsRoot: common.HexToHash("0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"), GenesisTime: 1606824023, - Checkpoint: common.HexToHash("0x6509b691f4de4f7b083f2784938fd52f0e131675432b3fd85ea549af9aebd3d0"), + Checkpoint: common.HexToHash(checkpointMainnet), }). AddFork("GENESIS", 0, []byte{0, 0, 0, 0}). AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}). @@ -35,7 +46,7 @@ var ( SepoliaLightConfig = (&ChainConfig{ GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"), GenesisTime: 1655733600, - Checkpoint: common.HexToHash("0x456e85f5608afab3465a0580bff8572255f6d97af0c5f939e3f7536b5edb2d3f"), + Checkpoint: common.HexToHash(checkpointSepolia), }). AddFork("GENESIS", 0, []byte{144, 0, 0, 105}). AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}). @@ -47,7 +58,7 @@ var ( HoleskyLightConfig = (&ChainConfig{ GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"), GenesisTime: 1695902400, - Checkpoint: common.HexToHash("0x6456a1317f54d4b4f2cb5bc9d153b5af0988fe767ef0609f0236cf29030bcff7"), + Checkpoint: common.HexToHash(checkpointHolesky), }). AddFork("GENESIS", 0, []byte{1, 1, 112, 0}). AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}). From 8e3b94da1e9437dc48ef945011f6ad21c03f3c51 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Mon, 24 Mar 2025 22:19:14 +0800 Subject: [PATCH 226/940] tests: update test submodule (#31479) This commit upgrades the test submodule to latest version: Latest: https://github.com/ethereum/tests/commit/81862e4848585a438d64f911a19b3825f0f4cd95 Old: https://github.com/ethereum/tests/commit/faf33b471465d3c6cdc3d04fbd690895f78d33f2 --- tests/testdata | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testdata b/tests/testdata index faf33b4714..81862e4848 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2 +Subproject commit 81862e4848585a438d64f911a19b3825f0f4cd95 From 71e9c9b8a732b33f50b4565627463fb252b4aeff Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 25 Mar 2025 05:08:53 +1100 Subject: [PATCH 227/940] internal/ethapi: support for beacon root and withdrawals in simulate api (#31304) Adds block override fields for beacon block root and withdrawals to the eth_simulateV1. Addresses https://github.com/ethereum/go-ethereum/issues/31264 --- eth/gasestimator/gasestimator.go | 4 +- eth/tracers/api.go | 4 +- internal/ethapi/api.go | 4 +- internal/ethapi/api_test.go | 18 +++++++ internal/ethapi/override/override.go | 14 ++++- internal/ethapi/simulate.go | 79 +++++++++++++++++++++++----- 6 files changed, 106 insertions(+), 17 deletions(-) diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index a6c4718cf4..fc8e3a2e42 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -223,7 +223,9 @@ func run(ctx context.Context, call *core.Message, opts *Options) (*core.Executio dirtyState = opts.State.Copy() ) if opts.BlockOverrides != nil { - opts.BlockOverrides.Apply(&evmContext) + if err := opts.BlockOverrides.Apply(&evmContext); err != nil { + return nil, err + } } // Lower the basefee to 0 to avoid breaking EVM // invariants (basefee < feecap). diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 627dd487fc..3cb86c80e2 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -950,7 +950,9 @@ 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 { - config.BlockOverrides.Apply(&vmctx) + if overrideErr := config.BlockOverrides.Apply(&vmctx); overrideErr != nil { + return nil, overrideErr + } rules := api.backend.ChainConfig().Rules(vmctx.BlockNumber, vmctx.Random != nil, vmctx.Time) precompiles = vm.ActivePrecompiledContracts(rules) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 979a7e822a..e0d5b32622 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -660,7 +660,9 @@ func (context *ChainContext) Config() *params.ChainConfig { func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) if blockOverrides != nil { - blockOverrides.Apply(&blockCtx) + if err := blockOverrides.Apply(&blockCtx); err != nil { + return nil, err + } } rules := b.ChainConfig().Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time) precompiles := vm.ActivePrecompiledContracts(rules) diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 88ff7b8af3..b086d1a6d5 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -1134,6 +1134,24 @@ func TestCall(t *testing.T) { }, want: "0x0000000000000000000000000000000000000000000000000000000000000000", }, + { + name: "unsupported block override beaconRoot", + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{}, + blockOverrides: override.BlockOverrides{ + BeaconRoot: &common.Hash{0, 1, 2}, + }, + expectErr: errors.New(`block override "beaconRoot" is not supported for this RPC method`), + }, + { + name: "unsupported block override withdrawals", + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{}, + blockOverrides: override.BlockOverrides{ + Withdrawals: &types.Withdrawals{}, + }, + expectErr: errors.New(`block override "withdrawals" is not supported for this RPC method`), + }, } for _, tc := range testSuite { result, err := api.Call(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides) diff --git a/internal/ethapi/override/override.go b/internal/ethapi/override/override.go index f6a8a94ffd..0bcf3c444d 100644 --- a/internal/ethapi/override/override.go +++ b/internal/ethapi/override/override.go @@ -17,6 +17,7 @@ package override import ( + "errors" "fmt" "math/big" @@ -128,12 +129,20 @@ type BlockOverrides struct { PrevRandao *common.Hash BaseFeePerGas *hexutil.Big BlobBaseFee *hexutil.Big + BeaconRoot *common.Hash + Withdrawals *types.Withdrawals } // Apply overrides the given header fields into the given block context. -func (o *BlockOverrides) Apply(blockCtx *vm.BlockContext) { +func (o *BlockOverrides) Apply(blockCtx *vm.BlockContext) error { if o == nil { - return + return nil + } + if o.BeaconRoot != nil { + return errors.New(`block override "beaconRoot" is not supported for this RPC method`) + } + if o.Withdrawals != nil { + return errors.New(`block override "withdrawals" is not supported for this RPC method`) } if o.Number != nil { blockCtx.BlockNumber = o.Number.ToInt() @@ -159,6 +168,7 @@ func (o *BlockOverrides) Apply(blockCtx *vm.BlockContext) { if o.BlobBaseFee != nil { blockCtx.BlobBaseFee = o.BlobBaseFee.ToInt() } + return nil } // MakeHeader returns a new header object with the overridden diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 097de8b0b0..ba346b132f 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -36,7 +36,6 @@ import ( "github.com/ethereum/go-ethereum/internal/ethapi/override" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/trie" ) const ( @@ -95,6 +94,47 @@ type simOpts struct { ReturnFullTransactions bool } +// simChainHeadReader implements ChainHeaderReader which is needed as input for FinalizeAndAssemble. +type simChainHeadReader struct { + context.Context + Backend +} + +func (m *simChainHeadReader) Config() *params.ChainConfig { + return m.Backend.ChainConfig() +} + +func (m *simChainHeadReader) CurrentHeader() *types.Header { + return m.Backend.CurrentHeader() +} + +func (m *simChainHeadReader) GetHeader(hash common.Hash, number uint64) *types.Header { + header, err := m.Backend.HeaderByNumber(m.Context, rpc.BlockNumber(number)) + if err != nil || header == nil { + return nil + } + if header.Hash() != hash { + return nil + } + return header +} + +func (m *simChainHeadReader) GetHeaderByNumber(number uint64) *types.Header { + header, err := m.Backend.HeaderByNumber(m.Context, rpc.BlockNumber(number)) + if err != nil { + return nil + } + return header +} + +func (m *simChainHeadReader) GetHeaderByHash(hash common.Hash) *types.Header { + header, err := m.Backend.HeaderByHash(m.Context, hash) + if err != nil { + return nil + } + return header +} + // simulator is a stateful object that simulates a series of blocks. // it is not safe for concurrent use. type simulator struct { @@ -209,6 +249,9 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if sim.chainConfig.IsPrague(header.Number, header.Time) || sim.chainConfig.IsVerkle(header.Number, header.Time) { core.ProcessParentBlockHash(header.ParentHash, evm) } + if header.ParentBeaconRoot != nil { + core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, evm) + } var allLogs []*types.Log for i, call := range block.Calls { if err := ctx.Err(); err != nil { @@ -258,6 +301,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, } callResults[i] = callRes } + header.GasUsed = gasUsed + if sim.chainConfig.IsCancun(header.Number, header.Time) { + header.BlobGasUsed = &blobGasUsed + } var requests [][]byte // Process EIP-7685 requests if sim.chainConfig.IsPrague(header.Number, header.Time) { @@ -271,20 +318,16 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, // EIP-7251 core.ProcessConsolidationQueue(&requests, evm) } - 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) - } if requests != nil { reqHash := types.CalcRequestsHash(requests) header.RequestsHash = &reqHash } - b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil)) + blockBody := &types.Body{Transactions: txes, Withdrawals: *block.BlockOverrides.Withdrawals} + chainHeadReader := &simChainHeadReader{ctx, sim.b} + b, err := sim.b.Engine().FinalizeAndAssemble(chainHeadReader, header, sim.state, blockBody, receipts) + if err != nil { + return nil, nil, err + } repairLogs(callResults, b.Hash()) return b, callResults, nil } @@ -346,6 +389,9 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) { n := new(big.Int).Add(prevNumber, big.NewInt(1)) block.BlockOverrides.Number = (*hexutil.Big)(n) } + if block.BlockOverrides.Withdrawals == nil { + block.BlockOverrides.Withdrawals = &types.Withdrawals{} + } 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)} @@ -360,7 +406,13 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) { 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: &override.BlockOverrides{Number: (*hexutil.Big)(n), Time: (*hexutil.Uint64)(&t)}} + b := simBlock{ + BlockOverrides: &override.BlockOverrides{ + Number: (*hexutil.Big)(n), + Time: (*hexutil.Uint64)(&t), + Withdrawals: &types.Withdrawals{}, + }, + } prevTimestamp = t res = append(res, b) } @@ -405,6 +457,9 @@ func (sim *simulator) makeHeaders(blocks []simBlock) ([]*types.Header, error) { var parentBeaconRoot *common.Hash if sim.chainConfig.IsCancun(overrides.Number.ToInt(), (uint64)(*overrides.Time)) { parentBeaconRoot = &common.Hash{} + if overrides.BeaconRoot != nil { + parentBeaconRoot = overrides.BeaconRoot + } } header = overrides.MakeHeader(&types.Header{ UncleHash: types.EmptyUncleHash, From a14b8eca04e9b7476f4a03c225c02e7bc2c32b71 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 25 Mar 2025 18:16:26 +0800 Subject: [PATCH 228/940] core/txpool: reject stale transaction for local tracking (#31473) Fixes https://github.com/ethereum/go-ethereum/issues/31451 --- core/txpool/locals/tx_tracker_test.go | 179 ++++++++++++++++++++++++++ core/txpool/txpool.go | 54 +++++++- 2 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 core/txpool/locals/tx_tracker_test.go diff --git a/core/txpool/locals/tx_tracker_test.go b/core/txpool/locals/tx_tracker_test.go new file mode 100644 index 0000000000..cb6b9b3453 --- /dev/null +++ b/core/txpool/locals/tx_tracker_test.go @@ -0,0 +1,179 @@ +// Copyright 2025 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 locals + +import ( + "errors" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "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 ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000000000) + gspec = &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{ + address: {Balance: funds}, + }, + BaseFee: big.NewInt(params.InitialBaseFee), + } + signer = types.LatestSigner(gspec.Config) +) + +type testEnv struct { + chain *core.BlockChain + pool *txpool.TxPool + tracker *TxTracker + genDb ethdb.Database +} + +func newTestEnv(t *testing.T, n int, gasTip uint64, journal string) *testEnv { + genDb, blocks, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), n, func(i int, gen *core.BlockGen) { + tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.BaseFee(), nil), signer, key) + if err != nil { + panic(err) + } + gen.AddTx(tx) + }) + + db := rawdb.NewMemoryDatabase() + chain, _ := core.NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil) + + legacyPool := legacypool.New(legacypool.DefaultConfig, chain) + pool, err := txpool.New(gasTip, chain, []txpool.SubPool{legacyPool}) + if err != nil { + t.Fatalf("Failed to create tx pool: %v", err) + } + if n, err := chain.InsertChain(blocks); err != nil { + t.Fatalf("Failed to process block %d: %v", n, err) + } + if err := pool.Sync(); err != nil { + t.Fatalf("Failed to sync the txpool, %v", err) + } + return &testEnv{ + chain: chain, + pool: pool, + tracker: New(journal, time.Minute, gspec.Config, pool), + genDb: genDb, + } +} + +func (env *testEnv) close() { + env.chain.Stop() +} + +func (env *testEnv) setGasTip(gasTip uint64) { + env.pool.SetGasTip(new(big.Int).SetUint64(gasTip)) +} + +func (env *testEnv) makeTx(nonce uint64, gasPrice *big.Int) *types.Transaction { + if nonce == 0 { + head := env.chain.CurrentHeader() + state, _ := env.chain.StateAt(head.Root) + nonce = state.GetNonce(address) + } + if gasPrice == nil { + gasPrice = big.NewInt(params.GWei) + } + tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{0x00}, big.NewInt(1000), params.TxGas, gasPrice, nil), signer, key) + return tx +} + +func (env *testEnv) commit() { + head := env.chain.CurrentBlock() + block := env.chain.GetBlock(head.Hash(), head.Number.Uint64()) + blocks, _ := core.GenerateChain(env.chain.Config(), block, ethash.NewFaker(), env.genDb, 1, func(i int, gen *core.BlockGen) { + tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.BaseFee(), nil), signer, key) + if err != nil { + panic(err) + } + gen.AddTx(tx) + }) + env.chain.InsertChain(blocks) + if err := env.pool.Sync(); err != nil { + panic(err) + } +} + +func TestRejectInvalids(t *testing.T) { + env := newTestEnv(t, 10, 0, "") + defer env.close() + + var cases = []struct { + gasTip uint64 + tx *types.Transaction + expErr error + commit bool + }{ + { + tx: env.makeTx(5, nil), // stale + expErr: core.ErrNonceTooLow, + }, + { + tx: env.makeTx(11, nil), // future transaction + expErr: nil, + }, + { + gasTip: params.GWei, + tx: env.makeTx(0, new(big.Int).SetUint64(params.GWei/2)), // low price + expErr: txpool.ErrUnderpriced, + }, + { + tx: types.NewTransaction(10, common.Address{0x00}, big.NewInt(1000), params.TxGas, big.NewInt(params.GWei), nil), // invalid signature + expErr: types.ErrInvalidSig, + }, + { + commit: true, + tx: env.makeTx(10, nil), // stale + expErr: core.ErrNonceTooLow, + }, + { + tx: env.makeTx(11, nil), + expErr: nil, + }, + } + for i, c := range cases { + if c.gasTip != 0 { + env.setGasTip(c.gasTip) + } + if c.commit { + env.commit() + } + gotErr := env.tracker.Track(c.tx) + if c.expErr == nil && gotErr != nil { + t.Fatalf("%d, unexpected error: %v", i, gotErr) + } + if c.expErr != nil && !errors.Is(gotErr, c.expErr) { + t.Fatalf("%d, unexpected error, want: %v, got: %v", i, c.expErr, gotErr) + } + } +} diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 042e3d36d9..3c00699dc7 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -24,11 +24,13 @@ import ( "github.com/ethereum/go-ethereum/common" "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/crypto/kzg4844" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" ) // TxStatus is the current status of a transaction as seen by the pool. @@ -53,11 +55,17 @@ var ( // BlockChain defines the minimal set of methods needed to back a tx pool with // a chain. Exists to allow mocking the live chain out of tests. type BlockChain interface { + // Config retrieves the chain's fork configuration. + Config() *params.ChainConfig + // CurrentBlock returns the current head of the chain. CurrentBlock() *types.Header // SubscribeChainHeadEvent subscribes to new blocks being added to the chain. SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription + + // StateAt returns a state database for a given root hash (generally the head). + StateAt(root common.Hash) (*state.StateDB, error) } // TxPool is an aggregator for various transaction specific pools, collectively @@ -67,6 +75,11 @@ type BlockChain interface { // resource constraints. type TxPool struct { subpools []SubPool // List of subpools for specialized transaction handling + chain BlockChain + signer types.Signer + + stateLock sync.RWMutex // The lock for protecting state instance + state *state.StateDB // Current state at the blockchain head reservations map[common.Address]SubPool // Map with the account to pool reservations reserveLock sync.Mutex // Lock protecting the account reservations @@ -86,8 +99,21 @@ func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) { // during initialization. head := chain.CurrentBlock() + // Initialize the state with head block, or fallback to empty one in + // case the head state is not available (might occur when node is not + // fully synced). + statedb, err := chain.StateAt(head.Root) + if err != nil { + statedb, err = chain.StateAt(types.EmptyRootHash) + } + if err != nil { + return nil, err + } pool := &TxPool{ subpools: subpools, + chain: chain, + signer: types.LatestSigner(chain.Config()), + state: statedb, reservations: make(map[common.Address]SubPool), quit: make(chan chan error), term: make(chan struct{}), @@ -101,7 +127,7 @@ func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) { return nil, err } } - go pool.loop(head, chain) + go pool.loop(head) return pool, nil } @@ -179,14 +205,14 @@ func (p *TxPool) Close() error { // loop is the transaction pool's main event loop, waiting for and reacting to // outside blockchain events as well as for various reporting and transaction // eviction events. -func (p *TxPool) loop(head *types.Header, chain BlockChain) { +func (p *TxPool) loop(head *types.Header) { // Close the termination marker when the pool stops defer close(p.term) // Subscribe to chain head events to trigger subpool resets var ( newHeadCh = make(chan core.ChainHeadEvent) - newHeadSub = chain.SubscribeChainHeadEvent(newHeadCh) + newHeadSub = p.chain.SubscribeChainHeadEvent(newHeadCh) ) defer newHeadSub.Unsubscribe() @@ -219,6 +245,14 @@ func (p *TxPool) loop(head *types.Header, chain BlockChain) { // Try to inject a busy marker and start a reset if successful select { case resetBusy <- struct{}{}: + statedb, err := p.chain.StateAt(newHead.Root) + if err != nil { + log.Crit("Failed to reset txpool state", "err", err) + } + p.stateLock.Lock() + p.state = statedb + p.stateLock.Unlock() + // Busy marker injected, start a new subpool reset go func(oldHead, newHead *types.Header) { for _, subpool := range p.subpools { @@ -339,6 +373,20 @@ func (p *TxPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Pr // ValidateTxBasics checks whether a transaction is valid according to the consensus // rules, but does not check state-dependent validation such as sufficient balance. func (p *TxPool) ValidateTxBasics(tx *types.Transaction) error { + addr, err := types.Sender(p.signer, tx) + if err != nil { + return err + } + // Reject transactions with stale nonce. Gapped-nonce future transactions + // are considered valid and will be handled by the subpool according to its + // internal policy. + p.stateLock.RLock() + nonce := p.state.GetNonce(addr) + p.stateLock.RUnlock() + + if nonce > tx.Nonce() { + return core.ErrNonceTooLow + } for _, subpool := range p.subpools { if subpool.Filter(tx) { return subpool.ValidateTxBasics(tx) From 19d2b4c88083463f4ff38ebe51962970b7b37fc3 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 25 Mar 2025 11:30:13 +0100 Subject: [PATCH 229/940] version: release v1.15.6 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 586bb870d1..44740849bb 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 6 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 6 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From aa6d0ef5f27508ba0ba3d7a146e9a033759a8edb Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 25 Mar 2025 12:26:15 +0100 Subject: [PATCH 230/940] version: begin v1.15.7 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 44740849bb..8cd428fd10 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 6 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 7 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From 21d36f7c3797c6c5b8b737d586a79fa5bb47115f Mon Sep 17 00:00:00 2001 From: nethoxa <135072738+nethoxa@users.noreply.github.com> Date: Tue, 25 Mar 2025 14:13:05 +0100 Subject: [PATCH 231/940] core: process EL requests in GenerateVerkleChain (#31175) --- core/chain_makers.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/chain_makers.go b/core/chain_makers.go index 8d09390b72..7a258dc05f 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -504,6 +504,13 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine if gen != nil { gen(i, b) } + + requests := b.collectRequests(false) + if requests != nil { + reqHash := types.CalcRequestsHash(requests) + b.header.RequestsHash = &reqHash + } + body := &types.Body{ Transactions: b.txs, Uncles: b.uncles, From 4ff5093df1dba2d5578f8eb4bfd44ca805d7f67f Mon Sep 17 00:00:00 2001 From: Shude Li Date: Tue, 25 Mar 2025 21:53:02 +0800 Subject: [PATCH 232/940] all: use fmt.Appendf instead of fmt.Sprintf where possible (#31301) --- cmd/utils/export_test.go | 14 ++++---- common/math/big.go | 2 +- common/math/integer.go | 2 +- core/state/snapshot/generate_test.go | 2 +- core/state/snapshot/iterator_test.go | 32 +++++++++---------- p2p/nat/nat.go | 2 +- p2p/nat/natpmp.go | 2 +- .../apitypes/signed_data_internal_test.go | 2 +- signer/core/signed_data_test.go | 2 +- triedb/pathdb/iterator_test.go | 32 +++++++++---------- 10 files changed, 46 insertions(+), 46 deletions(-) diff --git a/cmd/utils/export_test.go b/cmd/utils/export_test.go index b70d2451c6..d1a004d9b7 100644 --- a/cmd/utils/export_test.go +++ b/cmd/utils/export_test.go @@ -54,8 +54,8 @@ func (iter *testIterator) Next() (byte, []byte, []byte, bool) { if iter.index == 42 { iter.index += 1 } - return OpBatchAdd, []byte(fmt.Sprintf("key-%04d", iter.index)), - []byte(fmt.Sprintf("value %d", iter.index)), true + return OpBatchAdd, fmt.Appendf(nil, "key-%04d", iter.index), + fmt.Appendf(nil, "value %d", iter.index), true } func (iter *testIterator) Release() {} @@ -72,7 +72,7 @@ func testExport(t *testing.T, f string) { } // verify for i := 0; i < 1000; i++ { - v, err := db.Get([]byte(fmt.Sprintf("key-%04d", i))) + v, err := db.Get(fmt.Appendf(nil, "key-%04d", i)) if (i < 5 || i == 42) && err == nil { t.Fatalf("expected no element at idx %d, got '%v'", i, string(v)) } @@ -85,7 +85,7 @@ func testExport(t *testing.T, f string) { } } } - v, err := db.Get([]byte(fmt.Sprintf("key-%04d", 1000))) + v, err := db.Get(fmt.Appendf(nil, "key-%04d", 1000)) if err == nil { t.Fatalf("expected no element at idx %d, got '%v'", 1000, string(v)) } @@ -120,7 +120,7 @@ func (iter *deletionIterator) Next() (byte, []byte, []byte, bool) { if iter.index == 42 { iter.index += 1 } - return OpBatchDel, []byte(fmt.Sprintf("key-%04d", iter.index)), nil, true + return OpBatchDel, fmt.Appendf(nil, "key-%04d", iter.index), nil, true } func (iter *deletionIterator) Release() {} @@ -132,14 +132,14 @@ func testDeletion(t *testing.T, f string) { } db := rawdb.NewMemoryDatabase() for i := 0; i < 1000; i++ { - db.Put([]byte(fmt.Sprintf("key-%04d", i)), []byte(fmt.Sprintf("value %d", i))) + db.Put(fmt.Appendf(nil, "key-%04d", i), fmt.Appendf(nil, "value %d", i)) } err = ImportLDBData(db, f, 5, make(chan struct{})) if err != nil { t.Fatal(err) } for i := 0; i < 1000; i++ { - v, err := db.Get([]byte(fmt.Sprintf("key-%04d", i))) + v, err := db.Get(fmt.Appendf(nil, "key-%04d", i)) if i < 5 || i == 42 { if err != nil { t.Fatalf("expected element at idx %d, got '%v'", i, err) diff --git a/common/math/big.go b/common/math/big.go index 825f4baec9..493c2b7861 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -72,7 +72,7 @@ func (i *HexOrDecimal256) MarshalText() ([]byte, error) { if i == nil { return []byte("0x0"), nil } - return []byte(fmt.Sprintf("%#x", (*big.Int)(i))), nil + return fmt.Appendf(nil, "%#x", (*big.Int)(i)), nil } // Decimal256 unmarshals big.Int as a decimal string. When unmarshalling, diff --git a/common/math/integer.go b/common/math/integer.go index 25ced87053..dfcb0aecc4 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -48,7 +48,7 @@ func (i *HexOrDecimal64) UnmarshalText(input []byte) error { // MarshalText implements encoding.TextMarshaler. func (i HexOrDecimal64) MarshalText() ([]byte, error) { - return []byte(fmt.Sprintf("%#x", uint64(i))), nil + return fmt.Appendf(nil, "%#x", uint64(i)), nil } // ParseUint64 parses s as an integer in decimal or hexadecimal syntax. diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go index 661610840a..3de7735ef8 100644 --- a/core/state/snapshot/generate_test.go +++ b/core/state/snapshot/generate_test.go @@ -655,7 +655,7 @@ func testGenerateWithManyExtraAccounts(t *testing.T, scheme string) { for i := 0; i < 1000; i++ { acc := &types.StateAccount{Balance: uint256.NewInt(uint64(i)), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()} val, _ := rlp.EncodeToBytes(acc) - key := hashData([]byte(fmt.Sprintf("acc-%d", i))) + key := hashData(fmt.Appendf(nil, "acc-%d", i)) rawdb.WriteAccountSnapshot(helper.diskdb, key, val) } } diff --git a/core/state/snapshot/iterator_test.go b/core/state/snapshot/iterator_test.go index b9fe370b86..2e882f484e 100644 --- a/core/state/snapshot/iterator_test.go +++ b/core/state/snapshot/iterator_test.go @@ -329,27 +329,27 @@ func TestAccountIteratorTraversalValues(t *testing.T) { h = make(map[common.Hash][]byte) ) for i := byte(2); i < 0xff; i++ { - a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i)) + a[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 0, i) if i > 20 && i%2 == 0 { - b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i)) + b[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 1, i) } if i%4 == 0 { - c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i)) + c[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 2, i) } if i%7 == 0 { - d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i)) + d[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 3, i) } if i%8 == 0 { - e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i)) + e[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 4, i) } if i > 50 || i < 85 { - f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i)) + f[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 5, i) } if i%64 == 0 { - g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i)) + g[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 6, i) } if i%128 == 0 { - h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i)) + h[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 7, i) } } // Assemble a stack of snapshots from the account layers @@ -428,27 +428,27 @@ func TestStorageIteratorTraversalValues(t *testing.T) { h = make(map[common.Hash][]byte) ) for i := byte(2); i < 0xff; i++ { - a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i)) + a[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 0, i) if i > 20 && i%2 == 0 { - b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i)) + b[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 1, i) } if i%4 == 0 { - c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i)) + c[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 2, i) } if i%7 == 0 { - d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i)) + d[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 3, i) } if i%8 == 0 { - e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i)) + e[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 4, i) } if i > 50 || i < 85 { - f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i)) + f[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 5, i) } if i%64 == 0 { - g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i)) + g[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 6, i) } if i%128 == 0 { - h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i)) + h[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 7, i) } } // Assemble a stack of snapshots from the account layers diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index 5f7af7424d..a0ddb3b29b 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -140,7 +140,7 @@ type ExtIP net.IP func (n ExtIP) ExternalIP() (net.IP, error) { return net.IP(n), nil } func (n ExtIP) String() string { return fmt.Sprintf("ExtIP(%v)", net.IP(n)) } -func (n ExtIP) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("extip:%v", net.IP(n))), nil } +func (n ExtIP) MarshalText() ([]byte, error) { return fmt.Appendf(nil, "extip:%v", net.IP(n)), nil } // These do nothing. diff --git a/p2p/nat/natpmp.go b/p2p/nat/natpmp.go index b8f59ee890..4a9644ac1a 100644 --- a/p2p/nat/natpmp.go +++ b/p2p/nat/natpmp.go @@ -71,7 +71,7 @@ func (n *pmp) DeleteMapping(protocol string, extport, intport int) (err error) { } func (n *pmp) MarshalText() ([]byte, error) { - return []byte(fmt.Sprintf("natpmp:%v", n.gw)), nil + return fmt.Appendf(nil, "natpmp:%v", n.gw), nil } func discoverPMP() Interface { diff --git a/signer/core/apitypes/signed_data_internal_test.go b/signer/core/apitypes/signed_data_internal_test.go index 1a14b35ef2..bee9f1c351 100644 --- a/signer/core/apitypes/signed_data_internal_test.go +++ b/signer/core/apitypes/signed_data_internal_test.go @@ -282,7 +282,7 @@ func TestTypedDataArrayValidate(t *testing.T) { messageHash, tErr := td.HashStruct(td.PrimaryType, td.Message) assert.NoError(t, tErr, "failed to hash message: %v", tErr) - digest := crypto.Keccak256Hash([]byte(fmt.Sprintf("%s%s%s", "\x19\x01", string(domainSeparator), string(messageHash)))) + digest := crypto.Keccak256Hash(fmt.Appendf(nil, "%s%s%s", "\x19\x01", string(domainSeparator), string(messageHash))) assert.Equal(t, tc.Digest, digest.String(), "digest doesn't not match") assert.NoError(t, td.validate(), "validation failed", tErr) diff --git a/signer/core/signed_data_test.go b/signer/core/signed_data_test.go index b6c080736c..001f6b6838 100644 --- a/signer/core/signed_data_test.go +++ b/signer/core/signed_data_test.go @@ -369,7 +369,7 @@ func sign(typedData apitypes.TypedData) ([]byte, []byte, error) { if err != nil { return nil, nil, err } - rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) + rawData := fmt.Appendf(nil, "\x19\x01%s%s", string(domainSeparator), string(typedDataHash)) sighash := crypto.Keccak256(rawData) return typedDataHash, sighash, nil } diff --git a/triedb/pathdb/iterator_test.go b/triedb/pathdb/iterator_test.go index 05a166d1b6..3894118034 100644 --- a/triedb/pathdb/iterator_test.go +++ b/triedb/pathdb/iterator_test.go @@ -371,27 +371,27 @@ func TestAccountIteratorTraversalValues(t *testing.T) { h = make(map[common.Hash][]byte) ) for i := byte(2); i < 0xff; i++ { - a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i)) + a[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 0, i) if i > 20 && i%2 == 0 { - b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i)) + b[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 1, i) } if i%4 == 0 { - c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i)) + c[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 2, i) } if i%7 == 0 { - d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i)) + d[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 3, i) } if i%8 == 0 { - e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i)) + e[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 4, i) } if i > 50 || i < 85 { - f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i)) + f[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 5, i) } if i%64 == 0 { - g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i)) + g[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 6, i) } if i%128 == 0 { - h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i)) + h[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 7, i) } } // Assemble a stack of snapshots from the account layers @@ -480,27 +480,27 @@ func TestStorageIteratorTraversalValues(t *testing.T) { h = make(map[common.Hash][]byte) ) for i := byte(2); i < 0xff; i++ { - a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i)) + a[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 0, i) if i > 20 && i%2 == 0 { - b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i)) + b[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 1, i) } if i%4 == 0 { - c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i)) + c[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 2, i) } if i%7 == 0 { - d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i)) + d[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 3, i) } if i%8 == 0 { - e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i)) + e[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 4, i) } if i > 50 || i < 85 { - f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i)) + f[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 5, i) } if i%64 == 0 { - g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i)) + g[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 6, i) } if i%128 == 0 { - h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i)) + h[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 7, i) } } // Assemble a stack of snapshots from the account layers From 4dfec7e83e4634cc8ab254b4bdbe9e692142316b Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 25 Mar 2025 21:59:44 +0800 Subject: [PATCH 233/940] trie: optimize memory allocation (#30932) This pull request removes the node copy operation to reduce memory allocation. Key Changes as below: **(a) Use `decodeNodeUnsafe` for decoding nodes retrieved from the trie node reader** In the current implementation of the MPT, once a trie node blob is retrieved, it is passed to `decodeNode` for decoding. However, `decodeNode` assumes the supplied byte slice might be mutated later, so it performs a deep copy internally before parsing the node. Given that the node reader is implemented by the path database and the hash database, both of which guarantee the immutability of the returned byte slice. By restricting the node reader interface to explicitly guarantee that the returned byte slice will not be modified, we can safely replace `decodeNode` with `decodeNodeUnsafe`. This eliminates the need for a redundant byte copy during each node resolution. **(b) Modify the trie in place** In the current implementation of the MPT, a copy of a trie node is created before any modifications are made. These modifications include: - Node resolution: Converting the value from a hash to the actual node. - Node hashing: Tagging the hash into its cache. - Node commit: Replacing the children with its hash. - Structural changes: For example, adding a new child to a fullNode or replacing a child of a shortNode. This mechanism ensures that modifications only affect the live tree, leaving all previously created copies unaffected. Unfortunately, this property leads to a huge memory allocation requirement. For example, if we want to modify the fullNode for n times, the node will be copied for n times. In this pull request, all the trie modifications are made in place. In order to make sure all previously created copies are unaffected, the `Copy` function now will deep-copy all the live nodes rather than the root node itself. With this change, while the `Copy` function becomes more expensive, it's totally acceptable as it's not a frequently used one. For the normal trie operations (Get, GetNode, Hash, Commit, Insert, Delete), the node copy is not required anymore. --- trie/committer.go | 39 +++------ trie/hasher.go | 84 +++++++++--------- trie/node.go | 14 ++- trie/trie.go | 68 ++++++++++----- trie/trie_test.go | 168 ++++++++++++++++++++++++++++++++++++ triedb/database/database.go | 2 + 6 files changed, 279 insertions(+), 96 deletions(-) diff --git a/trie/committer.go b/trie/committer.go index 6c4374ccfd..0939a07abb 100644 --- a/trie/committer.go +++ b/trie/committer.go @@ -57,32 +57,26 @@ func (c *committer) commit(path []byte, n node, parallel bool) node { // Commit children, then parent, and remove the dirty flag. switch cn := n.(type) { case *shortNode: - // Commit child - collapsed := cn.copy() - // If the child is fullNode, recursively commit, // otherwise it can only be hashNode or valueNode. if _, ok := cn.Val.(*fullNode); ok { - collapsed.Val = c.commit(append(path, cn.Key...), cn.Val, false) + cn.Val = c.commit(append(path, cn.Key...), cn.Val, false) } // The key needs to be copied, since we're adding it to the // modified nodeset. - collapsed.Key = hexToCompact(cn.Key) - hashedNode := c.store(path, collapsed) + cn.Key = hexToCompact(cn.Key) + hashedNode := c.store(path, cn) if hn, ok := hashedNode.(hashNode); ok { return hn } - return collapsed + return cn case *fullNode: - hashedKids := c.commitChildren(path, cn, parallel) - collapsed := cn.copy() - collapsed.Children = hashedKids - - hashedNode := c.store(path, collapsed) + c.commitChildren(path, cn, parallel) + hashedNode := c.store(path, cn) if hn, ok := hashedNode.(hashNode); ok { return hn } - return collapsed + return cn case hashNode: return cn default: @@ -92,11 +86,10 @@ func (c *committer) commit(path []byte, n node, parallel bool) node { } // commitChildren commits the children of the given fullnode -func (c *committer) commitChildren(path []byte, n *fullNode, parallel bool) [17]node { +func (c *committer) commitChildren(path []byte, n *fullNode, parallel bool) { var ( - wg sync.WaitGroup - nodesMu sync.Mutex - children [17]node + wg sync.WaitGroup + nodesMu sync.Mutex ) for i := 0; i < 16; i++ { child := n.Children[i] @@ -106,22 +99,21 @@ func (c *committer) commitChildren(path []byte, n *fullNode, parallel bool) [17] // If it's the hashed child, save the hash value directly. // Note: it's impossible that the child in range [0, 15] // is a valueNode. - if hn, ok := child.(hashNode); ok { - children[i] = hn + if _, ok := child.(hashNode); ok { continue } // Commit the child recursively and store the "hashed" value. // Note the returned node can be some embedded nodes, so it's // possible the type is not hashNode. if !parallel { - children[i] = c.commit(append(path, byte(i)), child, false) + n.Children[i] = c.commit(append(path, byte(i)), child, false) } else { wg.Add(1) go func(index int) { p := append(path, byte(index)) childSet := trienode.NewNodeSet(c.nodes.Owner) childCommitter := newCommitter(childSet, c.tracer, c.collectLeaf) - children[index] = childCommitter.commit(p, child, false) + n.Children[index] = childCommitter.commit(p, child, false) nodesMu.Lock() c.nodes.MergeSet(childSet) nodesMu.Unlock() @@ -132,11 +124,6 @@ func (c *committer) commitChildren(path []byte, n *fullNode, parallel bool) [17] if parallel { wg.Wait() } - // For the 17th child, it's possible the type is valuenode. - if n.Children[16] != nil { - children[16] = n.Children[16] - } - return children } // store hashes the node n and adds it to the modified nodeset. If leaf collection diff --git a/trie/hasher.go b/trie/hasher.go index 28f7f3d0c3..614640ae3a 100644 --- a/trie/hasher.go +++ b/trie/hasher.go @@ -53,62 +53,56 @@ func returnHasherToPool(h *hasher) { hasherPool.Put(h) } -// hash collapses a node down into a hash node, also returning a copy of the -// original node initialized with the computed hash to replace the original one. -func (h *hasher) hash(n node, force bool) (hashed node, cached node) { +// hash collapses a node down into a hash node. +func (h *hasher) hash(n node, force bool) node { // Return the cached hash if it's available if hash, _ := n.cache(); hash != nil { - return hash, n + return hash } // Trie not processed yet, walk the children switch n := n.(type) { case *shortNode: - collapsed, cached := h.hashShortNodeChildren(n) + collapsed := h.hashShortNodeChildren(n) hashed := h.shortnodeToHash(collapsed, force) - // We need to retain the possibly _not_ hashed node, in case it was too - // small to be hashed if hn, ok := hashed.(hashNode); ok { - cached.flags.hash = hn + n.flags.hash = hn } else { - cached.flags.hash = nil + n.flags.hash = nil } - return hashed, cached + return hashed case *fullNode: - collapsed, cached := h.hashFullNodeChildren(n) - hashed = h.fullnodeToHash(collapsed, force) + collapsed := h.hashFullNodeChildren(n) + hashed := h.fullnodeToHash(collapsed, force) if hn, ok := hashed.(hashNode); ok { - cached.flags.hash = hn + n.flags.hash = hn } else { - cached.flags.hash = nil + n.flags.hash = nil } - return hashed, cached + return hashed default: // Value and hash nodes don't have children, so they're left as were - return n, n + return n } } -// hashShortNodeChildren collapses the short node. The returned collapsed node -// holds a live reference to the Key, and must not be modified. -func (h *hasher) hashShortNodeChildren(n *shortNode) (collapsed, cached *shortNode) { - // Hash the short node's child, caching the newly hashed subtree - collapsed, cached = n.copy(), n.copy() - // Previously, we did copy this one. We don't seem to need to actually - // do that, since we don't overwrite/reuse keys - // cached.Key = common.CopyBytes(n.Key) +// hashShortNodeChildren returns a copy of the supplied shortNode, with its child +// being replaced by either the hash or an embedded node if the child is small. +func (h *hasher) hashShortNodeChildren(n *shortNode) *shortNode { + var collapsed shortNode collapsed.Key = hexToCompact(n.Key) - // Unless the child is a valuenode or hashnode, hash it switch n.Val.(type) { case *fullNode, *shortNode: - collapsed.Val, cached.Val = h.hash(n.Val, false) + collapsed.Val = h.hash(n.Val, false) + default: + collapsed.Val = n.Val } - return collapsed, cached + return &collapsed } -func (h *hasher) hashFullNodeChildren(n *fullNode) (collapsed *fullNode, cached *fullNode) { - // Hash the full node's children, caching the newly hashed subtrees - cached = n.copy() - collapsed = n.copy() +// hashFullNodeChildren returns a copy of the supplied fullNode, with its child +// being replaced by either the hash or an embedded node if the child is small. +func (h *hasher) hashFullNodeChildren(n *fullNode) *fullNode { + var children [17]node if h.parallel { var wg sync.WaitGroup wg.Add(16) @@ -116,9 +110,9 @@ func (h *hasher) hashFullNodeChildren(n *fullNode) (collapsed *fullNode, cached go func(i int) { hasher := newHasher(false) if child := n.Children[i]; child != nil { - collapsed.Children[i], cached.Children[i] = hasher.hash(child, false) + children[i] = hasher.hash(child, false) } else { - collapsed.Children[i] = nilValueNode + children[i] = nilValueNode } returnHasherToPool(hasher) wg.Done() @@ -128,19 +122,21 @@ func (h *hasher) hashFullNodeChildren(n *fullNode) (collapsed *fullNode, cached } else { for i := 0; i < 16; i++ { if child := n.Children[i]; child != nil { - collapsed.Children[i], cached.Children[i] = h.hash(child, false) + children[i] = h.hash(child, false) } else { - collapsed.Children[i] = nilValueNode + children[i] = nilValueNode } } } - return collapsed, cached + if n.Children[16] != nil { + children[16] = n.Children[16] + } + return &fullNode{flags: nodeFlag{}, Children: children} } -// shortnodeToHash creates a hashNode from a shortNode. The supplied shortnode -// should have hex-type Key, which will be converted (without modification) -// into compact form for RLP encoding. -// If the rlp data is smaller than 32 bytes, `nil` is returned. +// shortNodeToHash computes the hash of the given shortNode. The shortNode must +// first be collapsed, with its key converted to compact form. If the RLP-encoded +// node data is smaller than 32 bytes, the node itself is returned. func (h *hasher) shortnodeToHash(n *shortNode, force bool) node { n.encode(h.encbuf) enc := h.encodedBytes() @@ -151,8 +147,8 @@ func (h *hasher) shortnodeToHash(n *shortNode, force bool) node { return h.hashData(enc) } -// fullnodeToHash is used to create a hashNode from a fullNode, (which -// may contain nil values) +// fullnodeToHash computes the hash of the given fullNode. If the RLP-encoded +// node data is smaller than 32 bytes, the node itself is returned. func (h *hasher) fullnodeToHash(n *fullNode, force bool) node { n.encode(h.encbuf) enc := h.encodedBytes() @@ -203,10 +199,10 @@ func (h *hasher) hashDataTo(dst, data []byte) { func (h *hasher) proofHash(original node) (collapsed, hashed node) { switch n := original.(type) { case *shortNode: - sn, _ := h.hashShortNodeChildren(n) + sn := h.hashShortNodeChildren(n) return sn, h.shortnodeToHash(sn, false) case *fullNode: - fn, _ := h.hashFullNodeChildren(n) + fn := h.hashFullNodeChildren(n) return fn, h.fullnodeToHash(fn, false) default: // Value and hash nodes don't have children, so they're left as were diff --git a/trie/node.go b/trie/node.go index ecc2de192d..96f077ebbb 100644 --- a/trie/node.go +++ b/trie/node.go @@ -79,15 +79,19 @@ func (n *fullNode) EncodeRLP(w io.Writer) error { return eb.Flush() } -func (n *fullNode) copy() *fullNode { copy := *n; return © } -func (n *shortNode) copy() *shortNode { copy := *n; return © } - // nodeFlag contains caching-related metadata about a node. type nodeFlag struct { hash hashNode // cached hash of the node (may be nil) dirty bool // whether the node has changes that must be written to the database } +func (n nodeFlag) copy() nodeFlag { + return nodeFlag{ + hash: common.CopyBytes(n.hash), + dirty: n.dirty, + } +} + func (n *fullNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } func (n hashNode) cache() (hashNode, bool) { return nil, true } @@ -228,7 +232,9 @@ func decodeRef(buf []byte) (node, []byte, error) { err := fmt.Errorf("oversized embedded node (size is %d bytes, want size < %d)", size, hashLen) return nil, buf, err } - n, err := decodeNode(nil, buf) + // The buffer content has already been copied or is safe to use; + // no additional copy is required. + n, err := decodeNodeUnsafe(nil, buf) return n, rest, err case kind == rlp.String && len(val) == 0: // empty node diff --git a/trie/trie.go b/trie/trie.go index ae2a7b21a2..fdb4da9be4 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -29,11 +29,11 @@ import ( "github.com/ethereum/go-ethereum/triedb/database" ) -// Trie is a Merkle Patricia Trie. Use New to create a trie that sits on -// top of a database. Whenever trie performs a commit operation, the generated -// nodes will be gathered and returned in a set. Once the trie is committed, -// it's not usable anymore. Callers have to re-create the trie with new root -// based on the updated trie database. +// Trie represents a Merkle Patricia Trie. Use New to create a trie that operates +// on top of a node database. During a commit operation, the trie collects all +// modified nodes into a set for return. After committing, the trie becomes +// unusable, and callers must recreate it with the new root based on the updated +// trie database. // // Trie is not safe for concurrent use. type Trie struct { @@ -67,13 +67,13 @@ func (t *Trie) newFlag() nodeFlag { // Copy returns a copy of Trie. func (t *Trie) Copy() *Trie { return &Trie{ - root: t.root, + root: copyNode(t.root), owner: t.owner, committed: t.committed, + unhashed: t.unhashed, + uncommitted: t.uncommitted, reader: t.reader, tracer: t.tracer.copy(), - uncommitted: t.uncommitted, - unhashed: t.unhashed, } } @@ -169,14 +169,12 @@ func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, newnode no } value, newnode, didResolve, err = t.get(n.Val, key, pos+len(n.Key)) if err == nil && didResolve { - n = n.copy() n.Val = newnode } return value, n, didResolve, err case *fullNode: value, newnode, didResolve, err = t.get(n.Children[key[pos]], key, pos+1) if err == nil && didResolve { - n = n.copy() n.Children[key[pos]] = newnode } return value, n, didResolve, err @@ -257,7 +255,6 @@ func (t *Trie) getNode(origNode node, path []byte, pos int) (item []byte, newnod } item, newnode, resolved, err = t.getNode(n.Val, path, pos+len(n.Key)) if err == nil && resolved > 0 { - n = n.copy() n.Val = newnode } return item, n, resolved, err @@ -265,7 +262,6 @@ func (t *Trie) getNode(origNode node, path []byte, pos int) (item []byte, newnod case *fullNode: item, newnode, resolved, err = t.getNode(n.Children[path[pos]], path, pos+1) if err == nil && resolved > 0 { - n = n.copy() n.Children[path[pos]] = newnode } return item, n, resolved, err @@ -375,7 +371,6 @@ func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error if !dirty || err != nil { return false, n, err } - n = n.copy() n.flags = t.newFlag() n.Children[key[0]] = nn return true, n, nil @@ -483,7 +478,6 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { if !dirty || err != nil { return false, n, err } - n = n.copy() n.flags = t.newFlag() n.Children[key[0]] = nn @@ -576,6 +570,36 @@ func concat(s1 []byte, s2 ...byte) []byte { return r } +// copyNode deep-copies the supplied node along with its children recursively. +func copyNode(n node) node { + switch n := (n).(type) { + case nil: + return nil + case valueNode: + return valueNode(common.CopyBytes(n)) + + case *shortNode: + return &shortNode{ + flags: n.flags.copy(), + Key: common.CopyBytes(n.Key), + Val: copyNode(n.Val), + } + case *fullNode: + var children [17]node + for i, cn := range n.Children { + children[i] = copyNode(cn) + } + return &fullNode{ + flags: n.flags.copy(), + Children: children, + } + case hashNode: + return n + default: + panic(fmt.Sprintf("%T: unknown node type", n)) + } +} + func (t *Trie) resolve(n node, prefix []byte) (node, error) { if n, ok := n.(hashNode); ok { return t.resolveAndTrack(n, prefix) @@ -593,15 +617,16 @@ func (t *Trie) resolveAndTrack(n hashNode, prefix []byte) (node, error) { return nil, err } t.tracer.onRead(prefix, blob) - return mustDecodeNode(n, blob), nil + + // The returned node blob won't be changed afterward. No need to + // deep-copy the slice. + return decodeNodeUnsafe(n, blob) } // Hash returns the root hash of the trie. It does not write to the // database and can be used even if the trie doesn't have one. func (t *Trie) Hash() common.Hash { - hash, cached := t.hashRoot() - t.root = cached - return common.BytesToHash(hash.(hashNode)) + return common.BytesToHash(t.hashRoot().(hashNode)) } // Commit collects all dirty nodes in the trie and replaces them with the @@ -652,9 +677,9 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) { } // hashRoot calculates the root hash of the given trie -func (t *Trie) hashRoot() (node, node) { +func (t *Trie) hashRoot() node { if t.root == nil { - return hashNode(types.EmptyRootHash.Bytes()), nil + return hashNode(types.EmptyRootHash.Bytes()) } // If the number of changes is below 100, we let one thread handle it h := newHasher(t.unhashed >= 100) @@ -662,8 +687,7 @@ func (t *Trie) hashRoot() (node, node) { returnHasherToPool(h) t.unhashed = 0 }() - hashed, cached := h.hash(t.root, true) - return hashed, cached + return h.hash(t.root, true) } // Witness returns a set containing all trie nodes that have been accessed. diff --git a/trie/trie_test.go b/trie/trie_test.go index 77234d9d9b..54d1b083d8 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -1330,3 +1330,171 @@ func printSet(set *trienode.NodeSet) string { } return out.String() } + +func TestTrieCopy(t *testing.T) { + testTrieCopy(t, []kv{ + {k: []byte("do"), v: []byte("verb")}, + {k: []byte("ether"), v: []byte("wookiedoo")}, + {k: []byte("horse"), v: []byte("stallion")}, + {k: []byte("shaman"), v: []byte("horse")}, + {k: []byte("doge"), v: []byte("coin")}, + {k: []byte("dog"), v: []byte("puppy")}, + }) + + var entries []kv + for i := 0; i < 256; i++ { + entries = append(entries, kv{k: testrand.Bytes(32), v: testrand.Bytes(32)}) + } + testTrieCopy(t, entries) +} + +func testTrieCopy(t *testing.T, entries []kv) { + tr := NewEmpty(nil) + for _, entry := range entries { + tr.Update(entry.k, entry.v) + } + trCpy := tr.Copy() + + if tr.Hash() != trCpy.Hash() { + t.Errorf("Hash mismatch: old %v, copy %v", tr.Hash(), trCpy.Hash()) + } + + // Check iterator + it, _ := tr.NodeIterator(nil) + itCpy, _ := trCpy.NodeIterator(nil) + + for it.Next(false) { + hasNext := itCpy.Next(false) + if !hasNext { + t.Fatal("Iterator is not matched") + } + if !bytes.Equal(it.Path(), itCpy.Path()) { + t.Fatal("Iterator is not matched") + } + if it.Leaf() != itCpy.Leaf() { + t.Fatal("Iterator is not matched") + } + if it.Leaf() && !bytes.Equal(it.LeafBlob(), itCpy.LeafBlob()) { + t.Fatal("Iterator is not matched") + } + } + + // Check commit + root, nodes := tr.Commit(false) + rootCpy, nodesCpy := trCpy.Commit(false) + if root != rootCpy { + t.Fatal("root mismatch") + } + if len(nodes.Nodes) != len(nodesCpy.Nodes) { + t.Fatal("commit node mismatch") + } + for p, n := range nodes.Nodes { + nn, exists := nodesCpy.Nodes[p] + if !exists { + t.Fatalf("node not exists: %v", p) + } + if !reflect.DeepEqual(n, nn) { + t.Fatalf("node mismatch: %v", p) + } + } +} + +func TestTrieCopyOldTrie(t *testing.T) { + testTrieCopyOldTrie(t, []kv{ + {k: []byte("do"), v: []byte("verb")}, + {k: []byte("ether"), v: []byte("wookiedoo")}, + {k: []byte("horse"), v: []byte("stallion")}, + {k: []byte("shaman"), v: []byte("horse")}, + {k: []byte("doge"), v: []byte("coin")}, + {k: []byte("dog"), v: []byte("puppy")}, + }) + + var entries []kv + for i := 0; i < 256; i++ { + entries = append(entries, kv{k: testrand.Bytes(32), v: testrand.Bytes(32)}) + } + testTrieCopyOldTrie(t, entries) +} + +func testTrieCopyOldTrie(t *testing.T, entries []kv) { + tr := NewEmpty(nil) + for _, entry := range entries { + tr.Update(entry.k, entry.v) + } + hash := tr.Hash() + + trCpy := tr.Copy() + for _, val := range entries { + if rand.Intn(2) == 0 { + trCpy.Delete(val.k) + } else { + trCpy.Update(val.k, testrand.Bytes(32)) + } + } + for i := 0; i < 10; i++ { + trCpy.Update(testrand.Bytes(32), testrand.Bytes(32)) + } + trCpy.Hash() + trCpy.Commit(false) + + // Traverse the original tree, the changes made on the copy one shouldn't + // affect the old one + for _, entry := range entries { + d, _ := tr.Get(entry.k) + if !bytes.Equal(d, entry.v) { + t.Errorf("Unexpected data, key: %v, want: %v, got: %v", entry.k, entry.v, d) + } + } + if tr.Hash() != hash { + t.Errorf("Hash mismatch: old %v, new %v", hash, tr.Hash()) + } +} + +func TestTrieCopyNewTrie(t *testing.T) { + testTrieCopyNewTrie(t, []kv{ + {k: []byte("do"), v: []byte("verb")}, + {k: []byte("ether"), v: []byte("wookiedoo")}, + {k: []byte("horse"), v: []byte("stallion")}, + {k: []byte("shaman"), v: []byte("horse")}, + {k: []byte("doge"), v: []byte("coin")}, + {k: []byte("dog"), v: []byte("puppy")}, + }) + + var entries []kv + for i := 0; i < 256; i++ { + entries = append(entries, kv{k: testrand.Bytes(32), v: testrand.Bytes(32)}) + } + testTrieCopyNewTrie(t, entries) +} + +func testTrieCopyNewTrie(t *testing.T, entries []kv) { + tr := NewEmpty(nil) + for _, entry := range entries { + tr.Update(entry.k, entry.v) + } + trCpy := tr.Copy() + hash := trCpy.Hash() + + for _, val := range entries { + if rand.Intn(2) == 0 { + tr.Delete(val.k) + } else { + tr.Update(val.k, testrand.Bytes(32)) + } + } + for i := 0; i < 10; i++ { + tr.Update(testrand.Bytes(32), testrand.Bytes(32)) + } + + // Traverse the original tree, the changes made on the copy one shouldn't + // affect the old one + for _, entry := range entries { + d, _ := trCpy.Get(entry.k) + if !bytes.Equal(d, entry.v) { + t.Errorf("Unexpected data, key: %v, want: %v, got: %v", entry.k, entry.v, d) + } + } + if trCpy.Hash() != hash { + t.Errorf("Hash mismatch: old %v, new %v", hash, tr.Hash()) + } +} diff --git a/triedb/database/database.go b/triedb/database/database.go index cd7ec1d931..8c61ea0293 100644 --- a/triedb/database/database.go +++ b/triedb/database/database.go @@ -27,6 +27,8 @@ type NodeReader interface { // node path and the corresponding node hash. No error will be returned // if the node is not found. // + // The returned node content won't be changed after the call. + // // 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) From c49aadc4b628c55da9948b0a1f37f487129ce28a Mon Sep 17 00:00:00 2001 From: sashabeton <23243361+sashabeton@users.noreply.github.com> Date: Tue, 25 Mar 2025 15:01:21 +0100 Subject: [PATCH 234/940] internal/ethapi: exclude 7702 authorities from result in eth_createAccessList (#31336) closes https://github.com/ethereum/go-ethereum/issues/31335 --------- Co-authored-by: sashabeton --- eth/tracers/logger/access_list_tracer.go | 12 +++------- internal/ethapi/api.go | 29 +++++++++++++++++++++--- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go index e8231461b0..0d51f40522 100644 --- a/eth/tracers/logger/access_list_tracer.go +++ b/eth/tracers/logger/access_list_tracer.go @@ -103,16 +103,10 @@ type AccessListTracer struct { // NewAccessListTracer creates a new tracer that can generate AccessLists. // An optional AccessList can be specified to occupy slots and addresses in // the resulting accesslist. -func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompiles []common.Address) *AccessListTracer { - excl := map[common.Address]struct{}{ - from: {}, to: {}, - } - for _, addr := range precompiles { - excl[addr] = struct{}{} - } +func NewAccessListTracer(acl types.AccessList, addressesToExclude map[common.Address]struct{}) *AccessListTracer { list := newAccessList() for _, al := range acl { - if _, ok := excl[al.Address]; !ok { + if _, ok := addressesToExclude[al.Address]; !ok { list.addAddress(al.Address) } for _, slot := range al.StorageKeys { @@ -120,7 +114,7 @@ func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompi } } return &AccessListTracer{ - excl: excl, + excl: addressesToExclude, list: list, } } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index e0d5b32622..203834fe38 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1166,10 +1166,33 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH // 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)) + // addressesToExclude contains sender, receiver, precompiles and valid authorizations + addressesToExclude := map[common.Address]struct{}{args.from(): {}, to: {}} + for _, addr := range precompiles { + addressesToExclude[addr] = struct{}{} + } + + // Prevent redundant operations if args contain more authorizations than EVM may handle + maxAuthorizations := uint64(*args.Gas) / params.CallNewAccountGas + if uint64(len(args.AuthorizationList)) > maxAuthorizations { + return nil, 0, nil, errors.New("insufficient gas to process all authorizations") + } + + for _, auth := range args.AuthorizationList { + // Duplicating stateTransition.validateAuthorization() logic + if (!auth.ChainID.IsZero() && auth.ChainID.CmpBig(b.ChainConfig().ChainID) != 0) || auth.Nonce+1 < auth.Nonce { + continue + } + + if authority, err := auth.Authority(); err == nil { + addressesToExclude[authority] = struct{}{} + } + } + // Create an initial tracer - prevTracer := logger.NewAccessListTracer(nil, args.from(), to, precompiles) + prevTracer := logger.NewAccessListTracer(nil, addressesToExclude) if args.AccessList != nil { - prevTracer = logger.NewAccessListTracer(*args.AccessList, args.from(), to, precompiles) + prevTracer = logger.NewAccessListTracer(*args.AccessList, addressesToExclude) } for { if err := ctx.Err(); err != nil { @@ -1186,7 +1209,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH msg := args.ToMessage(header.BaseFee, true, true) // Apply the transaction with the access list tracer - tracer := logger.NewAccessListTracer(accessList, args.from(), to, precompiles) + tracer := logger.NewAccessListTracer(accessList, addressesToExclude) config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true} evm := b.GetEVM(ctx, statedb, header, &config, nil) From c1ff2d8ba973f9f7ebfbf45e3c36f8d3299846ba Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 26 Mar 2025 12:59:40 +0800 Subject: [PATCH 235/940] core/state: fix double-increment of accountLoaded counter (#31493) --- core/state/statedb.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index efafdc1aa2..e3f5b9e1a0 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -600,7 +600,6 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject { // Insert into the live set obj := newObject(s, addr, acct) s.setStateObject(obj) - s.AccountLoaded++ return obj } From 5b4a74349372402fac545db7a7f80812a40b1b2b Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Wed, 26 Mar 2025 19:48:04 +0800 Subject: [PATCH 236/940] core/rawdb: remove LES database stats (#31495) This removes DB schema for LES related db entries. LES has been non-functional since the merge. --- core/rawdb/database.go | 16 ---------------- core/rawdb/schema.go | 8 -------- 2 files changed, 24 deletions(-) diff --git a/core/rawdb/database.go b/core/rawdb/database.go index a394f46e0a..7fca822155 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -388,10 +388,6 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { verkleTries stat verkleStateLookups stat - // Les statistic - chtTrieNodes stat - bloomTrieNodes stat - // Meta- and unaccounted data metadata stat unaccounted stat @@ -465,16 +461,6 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { case bytes.HasPrefix(key, bloomBitsMetaPrefix) && len(key) < len(bloomBitsMetaPrefix)+8: bloomBits.Add(size) - // LES indexes (deprecated) - case bytes.HasPrefix(key, chtTablePrefix) || - bytes.HasPrefix(key, chtIndexTablePrefix) || - bytes.HasPrefix(key, chtPrefix): // Canonical hash trie - chtTrieNodes.Add(size) - case bytes.HasPrefix(key, bloomTrieTablePrefix) || - 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):] @@ -538,8 +524,6 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { {"Key-Value store", "Beacon sync headers", beaconHeaders.Size(), beaconHeaders.Count()}, {"Key-Value store", "Clique snapshots", cliqueSnaps.Size(), cliqueSnaps.Count()}, {"Key-Value store", "Singleton metadata", metadata.Size(), metadata.Count()}, - {"Light client", "CHT trie nodes", chtTrieNodes.Size(), chtTrieNodes.Count()}, - {"Light client", "Bloom trie nodes", bloomTrieNodes.Size(), bloomTrieNodes.Count()}, } // Inspect all registered append-only file store then. ancients, err := inspectFreezers(db) diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 31e80da079..fa125cecc0 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -144,14 +144,6 @@ var ( // old log index bloomBitsMetaPrefix = []byte("iB") - // LES indexes - chtPrefix = []byte("chtRootV2-") // ChtPrefix + chtNum (uint64 big endian) -> trie root hash - chtTablePrefix = []byte("cht-") - chtIndexTablePrefix = []byte("chtIndexV2-") - bloomTriePrefix = []byte("bltRoot-") // BloomTriePrefix + bloomTrieNum (uint64 big endian) -> trie root hash - bloomTrieTablePrefix = []byte("blt-") - bloomTrieIndexPrefix = []byte("bltIndex-") - preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) preimageHitsCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) preimageMissCounter = metrics.NewRegisteredCounter("db/preimage/miss", nil) From a775e68421595d9c3807e68cce7ff2037991a781 Mon Sep 17 00:00:00 2001 From: VolodymyrBg Date: Wed, 26 Mar 2025 13:57:08 +0200 Subject: [PATCH 237/940] eth: downgrade peer removal error to warning level (#31492) --- eth/handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/handler.go b/eth/handler.go index 4c83f5613c..7179c9980b 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -403,7 +403,7 @@ func (h *handler) unregisterPeer(id string) { // Abort if the peer does not exist peer := h.peers.peer(id) if peer == nil { - logger.Error("Ethereum peer removal failed", "err", errPeerNotRegistered) + logger.Warn("Ethereum peer removal failed", "err", errPeerNotRegistered) return } // Remove the `eth` peer if it exists From a82303f4e3cedcebe31540a53dde4f24fc93da80 Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 26 Mar 2025 16:14:17 +0100 Subject: [PATCH 238/940] accounts/abi: include access-list in gas estimation (#31394) Simple bugfix to include the access-list in the gas-estimation step of the ABI bindings code. --- accounts/abi/bind/v2/base.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/accounts/abi/bind/v2/base.go b/accounts/abi/bind/v2/base.go index a9b667e697..535c0ed4fd 100644 --- a/accounts/abi/bind/v2/base.go +++ b/accounts/abi/bind/v2/base.go @@ -383,13 +383,14 @@ func (c *BoundContract) estimateGasLimit(opts *TransactOpts, contract *common.Ad } } msg := ethereum.CallMsg{ - From: opts.From, - To: contract, - GasPrice: gasPrice, - GasTipCap: gasTipCap, - GasFeeCap: gasFeeCap, - Value: value, - Data: input, + From: opts.From, + To: contract, + GasPrice: gasPrice, + GasTipCap: gasTipCap, + GasFeeCap: gasFeeCap, + Value: value, + Data: input, + AccessList: opts.AccessList, } return c.transactor.EstimateGas(ensureContext(opts.Context), msg) } From 6143c350ae1ecf3330678be02b4c2745bb6b8134 Mon Sep 17 00:00:00 2001 From: georgehao Date: Thu, 27 Mar 2025 19:22:17 +0800 Subject: [PATCH 239/940] internal/ethapi: CreateAccessList with stateOverrides (#31497) Add support for state overrides in eth_createAccessList. This will make the method consistent with other execution methods. --------- Co-authored-by: Sina Mahmoodi --- internal/ethapi/api.go | 16 ++++++-- internal/ethapi/api_test.go | 73 +++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 203834fe38..36a5df8087 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1117,12 +1117,13 @@ 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 (api *BlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { +// StateOverrides can be used to create the accessList while taking into account state changes from previous transactions. +func (api *BlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, stateOverrides *override.StateOverride) (*accessListResult, error) { bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) if blockNrOrHash != nil { bNrOrHash = *blockNrOrHash } - acl, gasUsed, vmerr, err := AccessList(ctx, api.b, bNrOrHash, args) + acl, gasUsed, vmerr, err := AccessList(ctx, api.b, bNrOrHash, args, stateOverrides) if err != nil { return nil, err } @@ -1136,13 +1137,22 @@ func (api *BlockChainAPI) CreateAccessList(ctx context.Context, args Transaction // AccessList creates an access list for the given transaction. // If the accesslist creation fails an error is returned. // If the transaction itself fails, an vmErr is returned. -func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args TransactionArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { +func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args TransactionArgs, stateOverrides *override.StateOverride) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { // Retrieve the execution context db, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if db == nil || err != nil { return nil, 0, nil, err } + // Apply state overrides immediately after StateAndHeaderByNumberOrHash. + // If not applied here, there could be cases where user-specified overrides (e.g., nonce) + // may conflict with default values from the database, leading to inconsistencies. + if stateOverrides != nil { + if err := stateOverrides.Apply(db, nil); err != nil { + return nil, 0, nil, err + } + } + // Ensure any missing fields are filled, extract the recipient and input data if err = args.setFeeDefaults(ctx, b, header); err != nil { return nil, 0, nil, err diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index b086d1a6d5..1ed1a8c8d8 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -3529,3 +3529,76 @@ func testRPCResponseWithFile(t *testing.T, testid int, result interface{}, rpc s func addressToHash(a common.Address) common.Hash { return common.BytesToHash(a.Bytes()) } + +func TestCreateAccessListWithStateOverrides(t *testing.T) { + // Initialize test backend + genesis := &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{ + common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7"): {Balance: big.NewInt(1000000000000000000)}, + }, + } + backend := newTestBackend(t, 1, genesis, ethash.NewFaker(), nil) + + // Create a new BlockChainAPI instance + api := NewBlockChainAPI(backend) + + // Create test contract code - a simple storage contract + // + // SPDX-License-Identifier: MIT + // pragma solidity ^0.8.0; + // + // contract SimpleStorage { + // uint256 private value; + // + // function retrieve() public view returns (uint256) { + // return value; + // } + // } + var ( + contractCode = hexutil.Bytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80632e64cec114602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60008054905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056")) + // Create state overrides with more complete state + contractAddr = common.HexToAddress("0x1234567890123456789012345678901234567890") + nonce = hexutil.Uint64(1) + overrides = &override.StateOverride{ + contractAddr: override.OverrideAccount{ + Code: &contractCode, + Balance: (*hexutil.Big)(big.NewInt(1000000000000000000)), + Nonce: &nonce, + State: map[common.Hash]common.Hash{ + common.Hash{}: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000002a"), + }, + }, + } + ) + + // Create transaction arguments with gas and value + var ( + from = common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") + data = hexutil.Bytes(common.Hex2Bytes("2e64cec1")) // retrieve() + gas = hexutil.Uint64(100000) + args = TransactionArgs{ + From: &from, + To: &contractAddr, + Data: &data, + Gas: &gas, + Value: new(hexutil.Big), + } + ) + // Call CreateAccessList + result, err := api.CreateAccessList(context.Background(), args, nil, overrides) + if err != nil { + t.Fatalf("Failed to create access list: %v", err) + } + if err != nil || result == nil { + t.Fatalf("Failed to create access list: %v", err) + } + require.NotNil(t, result.Accesslist) + + // Verify access list contains the contract address and storage slot + expected := &types.AccessList{{ + Address: contractAddr, + StorageKeys: []common.Hash{{}}, + }} + require.Equal(t, expected, result.Accesslist) +} From 714fa4f2e69a53ad714d6a0a259ab1c8b2032845 Mon Sep 17 00:00:00 2001 From: Delweng Date: Fri, 28 Mar 2025 15:15:13 +0800 Subject: [PATCH 240/940] cmd/geth: update geth subcommand arguments (#31293) --- cmd/geth/chaincmd.go | 35 ++++++++--------- cmd/geth/dbcmd.go | 94 +++++++++++++++++--------------------------- cmd/geth/main.go | 1 - 3 files changed, 53 insertions(+), 77 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 05c8bc4c7c..708dd8fb7a 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -37,7 +37,9 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/internal/era" + "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/urfave/cli/v2" @@ -66,7 +68,7 @@ It expects the genesis file as argument.`, Name: "dumpgenesis", Usage: "Dumps genesis block JSON configuration to stdout", ArgsUsage: "", - Flags: append([]cli.Flag{utils.DataDirFlag}, utils.NetworkFlags...), + Flags: slices.Concat([]cli.Flag{utils.DataDirFlag}, utils.NetworkFlags), Description: ` The dumpgenesis command prints the genesis configuration of the network preset if one is set. Otherwise it prints the genesis from the datadir.`, @@ -78,11 +80,11 @@ if one is set. Otherwise it prints the genesis from the datadir.`, ArgsUsage: " ( ... ) ", Flags: slices.Concat([]cli.Flag{ utils.CacheFlag, - utils.SyncModeFlag, utils.GCModeFlag, utils.SnapshotFlag, utils.CacheDatabaseFlag, utils.CacheGCFlag, + utils.NoCompactionFlag, utils.MetricsEnabledFlag, utils.MetricsEnabledExpensiveFlag, utils.MetricsHTTPFlag, @@ -105,7 +107,11 @@ if one is set. Otherwise it prints the genesis from the datadir.`, utils.LogNoHistoryFlag, utils.LogExportCheckpointsFlag, utils.StateHistoryFlag, - }, utils.DatabaseFlags), + }, utils.DatabaseFlags, debug.Flags), + Before: func(ctx *cli.Context) error { + flags.MigrateGlobalFlags(ctx) + return debug.Setup(ctx) + }, Description: ` The import command allows the import of blocks from an RLP-encoded format. This format can be a single file containing multiple RLP-encoded blocks, or multiple files can be given. @@ -119,10 +125,7 @@ to import successfully.`, Name: "export", Usage: "Export blockchain into file", ArgsUsage: " [ ]", - Flags: slices.Concat([]cli.Flag{ - utils.CacheFlag, - utils.SyncModeFlag, - }, utils.DatabaseFlags), + Flags: slices.Concat([]cli.Flag{utils.CacheFlag}, utils.DatabaseFlags), Description: ` Requires a first argument of the file to write to. Optional second and third arguments control the first and @@ -135,12 +138,7 @@ be gzipped.`, Name: "import-history", Usage: "Import an Era archive", ArgsUsage: "", - Flags: slices.Concat([]cli.Flag{ - utils.TxLookupLimitFlag, - }, - utils.DatabaseFlags, - utils.NetworkFlags, - ), + Flags: slices.Concat([]cli.Flag{utils.TxLookupLimitFlag, utils.TransactionHistoryFlag}, utils.DatabaseFlags, utils.NetworkFlags), Description: ` The import-history command will import blocks and their corresponding receipts from Era archives. @@ -151,7 +149,7 @@ from Era archives. Name: "export-history", Usage: "Export blockchain history to Era archives", ArgsUsage: " ", - Flags: slices.Concat(utils.DatabaseFlags), + Flags: utils.DatabaseFlags, Description: ` The export-history command will export blocks and their corresponding receipts into Era archives. Eras are typically packaged in steps of 8192 blocks. @@ -162,10 +160,7 @@ into Era archives. Eras are typically packaged in steps of 8192 blocks. Name: "import-preimages", Usage: "Import the preimage database from an RLP stream", ArgsUsage: "", - Flags: slices.Concat([]cli.Flag{ - utils.CacheFlag, - utils.SyncModeFlag, - }, utils.DatabaseFlags), + Flags: slices.Concat([]cli.Flag{utils.CacheFlag}, utils.DatabaseFlags), Description: ` The import-preimages command imports hash preimages from an RLP encoded stream. It's deprecated, please use "geth db import" instead. @@ -435,6 +430,10 @@ func importHistory(ctx *cli.Context) error { network = "mainnet" case ctx.Bool(utils.SepoliaFlag.Name): network = "sepolia" + case ctx.Bool(utils.HoleskyFlag.Name): + network = "holesky" + case ctx.Bool(utils.HoodiFlag.Name): + network = "hoodi" } } else { // No network flag set, try to determine network based on files diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go index cd41c57c75..44a52521f0 100644 --- a/cmd/geth/dbcmd.go +++ b/cmd/geth/dbcmd.go @@ -86,12 +86,10 @@ Remove blockchain and state databases`, }, } dbInspectCmd = &cli.Command{ - Action: inspect, - Name: "inspect", - ArgsUsage: " ", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Action: inspect, + Name: "inspect", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Usage: "Inspect the storage size for each type of data in the database", Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`, } @@ -109,16 +107,13 @@ a data corruption.`, Action: dbStats, Name: "stats", Usage: "Print leveldb statistics", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), } dbCompactCmd = &cli.Command{ Action: dbCompact, Name: "compact", Usage: "Compact leveldb database. WARNING: May take a very long time", Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, utils.CacheFlag, utils.CacheDatabaseFlag, }, utils.NetworkFlags, utils.DatabaseFlags), @@ -127,13 +122,11 @@ WARNING: This operation may take a very long time to finish, and may cause datab corruption if it is aborted during execution'!`, } dbGetCmd = &cli.Command{ - Action: dbGet, - Name: "get", - Usage: "Show the value of a database key", - ArgsUsage: "", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Action: dbGet, + Name: "get", + Usage: "Show the value of a database key", + ArgsUsage: "", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: "This command looks up the specified database key from the database.", } dbDeleteCmd = &cli.Command{ @@ -141,9 +134,7 @@ corruption if it is aborted during execution'!`, Name: "delete", Usage: "Delete a database key (WARNING: may corrupt your database)", ArgsUsage: "", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: `This command deletes the specified database key from the database. WARNING: This is a low-level operation which may cause database corruption!`, } @@ -152,59 +143,47 @@ WARNING: This is a low-level operation which may cause database corruption!`, Name: "put", Usage: "Set the value of a database key (WARNING: may corrupt your database)", ArgsUsage: " ", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: `This command sets a given database key to the given value. WARNING: This is a low-level operation which may cause database corruption!`, } dbGetSlotsCmd = &cli.Command{ - Action: dbDumpTrie, - Name: "dumptrie", - Usage: "Show the storage key/values of a given storage trie", - ArgsUsage: " ", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Action: dbDumpTrie, + Name: "dumptrie", + Usage: "Show the storage key/values of a given storage trie", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: "This command looks up the specified database key from the database.", } dbDumpFreezerIndex = &cli.Command{ - Action: freezerInspect, - Name: "freezer-index", - Usage: "Dump out the index of a specific freezer table", - ArgsUsage: " ", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Action: freezerInspect, + Name: "freezer-index", + Usage: "Dump out the index of a specific freezer table", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: "This command displays information about the freezer index.", } dbImportCmd = &cli.Command{ - Action: importLDBdata, - Name: "import", - Usage: "Imports leveldb-data from an exported RLP dump.", - ArgsUsage: " has .gz suffix, gzip compression will be used.", - ArgsUsage: " ", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Action: exportChaindata, + Name: "export", + Usage: "Exports the chain data into an RLP dump. If the has .gz suffix, gzip compression will be used.", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: "Exports the specified chain data to an RLP encoded stream, optionally gzip-compressed.", } dbMetadataCmd = &cli.Command{ - Action: showMetaData, - Name: "metadata", - Usage: "Shows metadata about the chain status.", - Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, - }, utils.NetworkFlags, utils.DatabaseFlags), + Action: showMetaData, + Name: "metadata", + Usage: "Shows metadata about the chain status.", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: "Shows metadata about the chain status.", } dbInspectHistoryCmd = &cli.Command{ @@ -213,7 +192,6 @@ WARNING: This is a low-level operation which may cause database corruption!`, Usage: "Inspect the state history within block range", ArgsUsage: "
[OPTIONAL ]", Flags: slices.Concat([]cli.Flag{ - utils.SyncModeFlag, &cli.Uint64Flag{ Name: "start", Usage: "block number of the range start, zero means earliest history", diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 9c0c0d9dfc..cd74fb7b6a 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -142,7 +142,6 @@ var ( utils.VMTraceJsonConfigFlag, utils.NetworkIdFlag, utils.EthStatsURLFlag, - utils.NoCompactionFlag, utils.GpoBlocksFlag, utils.GpoPercentileFlag, utils.GpoMaxGasPriceFlag, From 141968a48b45bf343c5921057eca158df5d3c96e Mon Sep 17 00:00:00 2001 From: rekyyang <511965710@qq.com> Date: Fri, 28 Mar 2025 15:16:37 +0800 Subject: [PATCH 241/940] core/txpool/legacypool: fix data race in checkDelegationLimit (#31475) --- core/txpool/legacypool/legacypool.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 7a0095a5ad..dafd185836 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -618,7 +618,7 @@ func (pool *LegacyPool) checkDelegationLimit(tx *types.Transaction) error { from, _ := types.Sender(pool.signer, tx) // validated // Short circuit if the sender has neither delegation nor pending delegation. - if pool.currentState.GetCodeHash(from) == types.EmptyCodeHash && len(pool.all.auths[from]) == 0 { + if pool.currentState.GetCodeHash(from) == types.EmptyCodeHash && pool.all.delegationTxsCount(from) == 0 { return nil } pending := pool.pending[from] @@ -1849,6 +1849,13 @@ func (t *lookup) removeAuthorities(tx *types.Transaction) { } } +// delegationTxsCount returns the number of pending authorizations for the specified address. +func (t *lookup) delegationTxsCount(addr common.Address) int { + t.lock.RLock() + defer t.lock.RUnlock() + return len(t.auths[addr]) +} + // numSlots calculates the number of slots needed for a single transaction. func numSlots(tx *types.Transaction) int { return int((tx.Size() + txSlotSize - 1) / txSlotSize) From 32f36a674990b5e2316321415d595c67b2f00b4f Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 28 Mar 2025 19:32:24 +0800 Subject: [PATCH 242/940] core/txpool: fix nonce assignment in local tracker (#31496) Fixes #31494 --- core/txpool/locals/tx_tracker_test.go | 39 +++++++++++++++++++++++++++ core/txpool/txpool.go | 13 +++++++-- eth/api_backend.go | 2 +- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/core/txpool/locals/tx_tracker_test.go b/core/txpool/locals/tx_tracker_test.go index cb6b9b3453..5585589b6c 100644 --- a/core/txpool/locals/tx_tracker_test.go +++ b/core/txpool/locals/tx_tracker_test.go @@ -108,6 +108,19 @@ func (env *testEnv) makeTx(nonce uint64, gasPrice *big.Int) *types.Transaction { return tx } +func (env *testEnv) makeTxs(n int) []*types.Transaction { + head := env.chain.CurrentHeader() + state, _ := env.chain.StateAt(head.Root) + nonce := state.GetNonce(address) + + var txs []*types.Transaction + for i := 0; i < n; i++ { + tx, _ := types.SignTx(types.NewTransaction(nonce+uint64(i), common.Address{0x00}, big.NewInt(1000), params.TxGas, big.NewInt(params.GWei), nil), signer, key) + txs = append(txs, tx) + } + return txs +} + func (env *testEnv) commit() { head := env.chain.CurrentBlock() block := env.chain.GetBlock(head.Hash(), head.Number.Uint64()) @@ -177,3 +190,29 @@ func TestRejectInvalids(t *testing.T) { } } } + +func TestResubmit(t *testing.T) { + env := newTestEnv(t, 10, 0, "") + defer env.close() + + txs := env.makeTxs(10) + txsA := txs[:len(txs)/2] + txsB := txs[len(txs)/2:] + env.pool.Add(txsA, true) + pending, queued := env.pool.ContentFrom(address) + if len(pending) != len(txsA) || len(queued) != 0 { + t.Fatalf("Unexpected txpool content: %d, %d", len(pending), len(queued)) + } + env.tracker.TrackAll(txs) + + resubmit, all := env.tracker.recheck(true) + if len(resubmit) != len(txsB) { + t.Fatalf("Unexpected transactions to resubmit, got: %d, want: %d", len(resubmit), len(txsB)) + } + if len(all) == 0 || len(all[address]) == 0 { + t.Fatalf("Unexpected transactions being tracked, got: %d, want: %d", 0, len(txs)) + } + if len(all[address]) != len(txs) { + t.Fatalf("Unexpected transactions being tracked, got: %d, want: %d", len(all[address]), len(txs)) + } +} diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index c5f7718057..649c5d1a78 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -466,9 +466,9 @@ func (p *TxPool) SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool) return p.subs.Track(event.JoinSubscriptions(subs...)) } -// Nonce returns the next nonce of an account, with all transactions executable +// PoolNonce returns the next nonce of an account, with all transactions executable // by the pool already applied on top. -func (p *TxPool) Nonce(addr common.Address) uint64 { +func (p *TxPool) PoolNonce(addr common.Address) uint64 { // Since (for now) accounts are unique to subpools, only one pool will have // (at max) a non-state nonce. To avoid stateful lookups, just return the // highest nonce for now. @@ -481,6 +481,15 @@ func (p *TxPool) Nonce(addr common.Address) uint64 { return nonce } +// Nonce returns the next nonce of an account at the current chain head. Unlike +// PoolNonce, this function does not account for pending executable transactions. +func (p *TxPool) Nonce(addr common.Address) uint64 { + p.stateLock.RLock() + defer p.stateLock.RUnlock() + + return p.state.GetNonce(addr) +} + // Stats retrieves the current pool stats, namely the number of pending and the // number of queued (non-executable) transactions. func (p *TxPool) Stats() (int, int) { diff --git a/eth/api_backend.go b/eth/api_backend.go index b08e38afe5..c8c5ca707f 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -327,7 +327,7 @@ func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) } func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { - return b.eth.txPool.Nonce(addr), nil + return b.eth.txPool.PoolNonce(addr), nil } func (b *EthAPIBackend) Stats() (runnable int, blocked int) { From c8a9a9c0917dd57d077a79044e65dbbdd421458b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 28 Mar 2025 16:17:28 +0100 Subject: [PATCH 243/940] core/filtermaps: revert to unindexed mode in case of indexing error (#31500) This PR changes log indexer error handling so that if an indexing error happens then it disables the indexer and reverts to unindexed more without resetting the database (except in case of a failed database init). Resetting the database on the first error would probably be overkill as a client update might fix this without having to reindex the entire history. It would also make debugging very hard. On the other hand, these errors do not resolve themselves automatically so constantly retrying makes no sense either. With these changes a new attempt to resume indexing is made every time the client is restarted. The PR also fixes https://github.com/ethereum/go-ethereum/issues/31491 which originated from the tail indexer trying to resume processing a failed map renderer. --------- Co-authored-by: Felix Lange --- core/filtermaps/chain_view.go | 6 ++- core/filtermaps/indexer.go | 97 ++++++++++++++++++++++------------- 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go index bc0de47ded..a8cf53b1c0 100644 --- a/core/filtermaps/chain_view.go +++ b/core/filtermaps/chain_view.go @@ -83,7 +83,11 @@ func (cv *ChainView) getReceipts(number uint64) types.Receipts { if number > cv.headNumber { panic("invalid block number") } - return cv.chain.GetReceiptsByHash(cv.blockHash(number)) + blockHash := cv.blockHash(number) + if blockHash == (common.Hash{}) { + log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber) + } + return cv.chain.GetReceiptsByHash(blockHash) } // limitedView returns a new chain view that is a truncated version of the parent view. diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 026b3b4f38..6732dc85ea 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -17,6 +17,7 @@ package filtermaps import ( + "errors" "math" "time" @@ -49,18 +50,15 @@ func (f *FilterMaps) indexerLoop() { continue } if err := f.init(); err != nil { - log.Error("Error initializing log index; reverting to unindexed mode", "error", err) - f.reset() - f.disabled = true - close(f.disabledCh) + f.disableForError("initialization", err) + f.reset() // remove broken index from DB return } } if !f.targetHeadIndexed() { - if !f.tryIndexHead() { - // either shutdown or unexpected error; in the latter case ensure - // that proper shutdown is still possible. - f.processSingleEvent(true) + if err := f.tryIndexHead(); err != nil && err != errChainUpdate { + f.disableForError("head rendering", err) + return } } else { if f.finalBlock != f.lastFinal { @@ -69,13 +67,36 @@ func (f *FilterMaps) indexerLoop() { } f.lastFinal = f.finalBlock } - if f.tryIndexTail() && f.tryUnindexTail() { - f.waitForNewHead() + if done, err := f.tryIndexTail(); err != nil { + f.disableForError("tail rendering", err) + return + } else if !done { + continue } + if done, err := f.tryUnindexTail(); err != nil { + f.disableForError("tail unindexing", err) + return + } else if !done { + continue + } + // tail indexing/unindexing is done; if head is also indexed then + // wait here until there is a new head + f.waitForNewHead() } } } +// disableForError is called when the indexer encounters a database error, for example a +// missing receipt. We can't continue operating when the database is broken, so the +// indexer goes into disabled state. +// Note that the partial index is left in disk; maybe a client update can fix the +// issue without reindexing. +func (f *FilterMaps) disableForError(op string, err error) { + log.Error("Log index "+op+" failed, reverting to unindexed mode", "error", err) + f.disabled = true + close(f.disabledCh) +} + type targetUpdate struct { targetView *ChainView historyCutoff, finalBlock uint64 @@ -116,14 +137,15 @@ func (f *FilterMaps) SetBlockProcessing(blockProcessing bool) { // WaitIdle blocks until the indexer is in an idle state while synced up to the // latest targetView. func (f *FilterMaps) WaitIdle() { - if f.disabled { - f.closeWg.Wait() - return - } for { ch := make(chan bool) - f.waitIdleCh <- ch - if <-ch { + select { + case f.waitIdleCh <- ch: + if <-ch { + return + } + case <-f.disabledCh: + f.closeWg.Wait() return } } @@ -196,16 +218,16 @@ func (f *FilterMaps) setTarget(target targetUpdate) { f.finalBlock = target.finalBlock } -// tryIndexHead tries to render head maps according to the current targetView -// and returns true if successful. -func (f *FilterMaps) tryIndexHead() bool { +// tryIndexHead tries to render head maps according to the current targetView. +// Should be called when targetHeadIndexed returns false. If this function +// returns no error then either stop is true or head indexing is finished. +func (f *FilterMaps) tryIndexHead() error { headRenderer, err := f.renderMapsBefore(math.MaxUint32) if err != nil { - log.Error("Error creating log index head renderer", "error", err) - return false + return err } if headRenderer == nil { - return true + return errors.New("head indexer has nothing to do") // tryIndexHead should be called when head is not indexed } if !f.startedHeadIndex { f.lastLogHeadIndex = time.Now() @@ -230,8 +252,7 @@ func (f *FilterMaps) tryIndexHead() bool { f.lastLogHeadIndex = time.Now() } }); err != nil { - log.Error("Log index head rendering failed", "error", err) - return false + return err } if f.loggedHeadIndex && f.indexedRange.hasIndexedBlocks() { log.Info("Log index head rendering finished", @@ -240,7 +261,7 @@ func (f *FilterMaps) tryIndexHead() bool { "elapsed", common.PrettyDuration(time.Since(f.startedHeadIndexAt))) } f.loggedHeadIndex, f.startedHeadIndex = false, false - return true + return nil } // tryIndexTail tries to render tail epochs until the tail target block is @@ -248,7 +269,7 @@ func (f *FilterMaps) tryIndexHead() bool { // Note that tail indexing is only started if the log index head is fully // rendered according to targetView and is suspended as soon as the targetView // is changed. -func (f *FilterMaps) tryIndexTail() bool { +func (f *FilterMaps) tryIndexTail() (bool, error) { for { firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch if firstEpoch == 0 || !f.needTailEpoch(firstEpoch-1) { @@ -256,7 +277,7 @@ func (f *FilterMaps) tryIndexTail() bool { } f.processEvents() if f.stop || !f.targetHeadIndexed() { - return false + return false, nil } // resume process if tail rendering was interrupted because of head rendering tailRenderer := f.tailRenderer @@ -268,8 +289,7 @@ func (f *FilterMaps) tryIndexTail() bool { var err error tailRenderer, err = f.renderMapsBefore(f.indexedRange.maps.First()) if err != nil { - log.Error("Error creating log index tail renderer", "error", err) - return false + return false, err } } if tailRenderer == nil { @@ -302,13 +322,16 @@ func (f *FilterMaps) tryIndexTail() bool { f.lastLogTailIndex = time.Now() } }) - if err != nil && f.needTailEpoch(firstEpoch-1) { + if err != nil && !f.needTailEpoch(firstEpoch-1) { // stop silently if cutoff point has move beyond epoch boundary while rendering - log.Error("Log index tail rendering failed", "error", err) + return true, nil + } + if err != nil { + return false, err } if !done { f.tailRenderer = tailRenderer // only keep tail renderer if interrupted by stopCb - return false + return false, nil } } if f.loggedTailIndex && f.indexedRange.hasIndexedBlocks() { @@ -318,14 +341,14 @@ func (f *FilterMaps) tryIndexTail() bool { "elapsed", common.PrettyDuration(time.Since(f.startedTailIndexAt))) f.loggedTailIndex = false } - return true + return true, nil } // tryUnindexTail removes entire epochs of log index data as long as the first // fully indexed block is at least as old as the tail target. // Note that unindexing is very quick as it only removes continuous ranges of // data from the database and is also called while running head indexing. -func (f *FilterMaps) tryUnindexTail() bool { +func (f *FilterMaps) tryUnindexTail() (bool, error) { for { firstEpoch := (f.indexedRange.maps.First() - f.indexedRange.tailPartialEpoch) >> f.logMapsPerEpoch if f.needTailEpoch(firstEpoch) { @@ -333,7 +356,7 @@ func (f *FilterMaps) tryUnindexTail() bool { } f.processEvents() if f.stop { - return false + return false, nil } if !f.startedTailUnindex { f.startedTailUnindexAt = time.Now() @@ -343,7 +366,7 @@ func (f *FilterMaps) tryUnindexTail() bool { } if err := f.deleteTailEpoch(firstEpoch); err != nil { log.Error("Log index tail epoch unindexing failed", "error", err) - return false + return false, err } } if f.startedTailUnindex && f.indexedRange.hasIndexedBlocks() { @@ -354,7 +377,7 @@ func (f *FilterMaps) tryUnindexTail() bool { "elapsed", common.PrettyDuration(time.Since(f.startedTailUnindexAt))) f.startedTailUnindex = false } - return true + return true, nil } // needTailEpoch returns true if the given tail epoch needs to be kept From ffa315f7460b6f050e89b63ca63876d974fb19bf Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 31 Mar 2025 09:49:19 +0200 Subject: [PATCH 244/940] .gitignore: ignore binaries (#31531) Ignores all hand-built binaries (built with go build, everything built with make is already ignored) --- .gitignore | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.gitignore b/.gitignore index 7000fedd25..269455db7a 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,16 @@ profile.cov .vscode tests/spec-tests/ + +# binaries +cmd/abidump/abidump +cmd/abigen/abigen +cmd/blsync/blsync +cmd/clef/clef +cmd/devp2p/devp2p +cmd/era/era +cmd/ethkey/ethkey +cmd/evm/evm +cmd/geth/geth +cmd/rlpdump/rlpdump +cmd/workload/workload \ No newline at end of file From 14d576c002309e38864f9afd95e7305e35a68035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Mon, 31 Mar 2025 14:47:56 +0200 Subject: [PATCH 245/940] core/filtermaps: hashdb safe delete range (#31525) This PR adds `rawdb.SafeDeleteRange` and uses it for range deletion in `core/filtermaps`. This includes deleting the old bloombits database, resetting the log index database and removing index data for unindexed tail epochs (which previously weren't properly implemented for the fallback case). `SafeDeleteRange` either calls `ethdb.DeleteRange` if the node uses the new path based state scheme or uses an iterator based fallback method that safely skips trie nodes in the range if the old hash based state scheme is used. Note that `ethdb.DeleteRange` also has its own iterator based fallback implementation in `ethdb/leveldb`. If a path based state scheme is used and the backing db is pebble (as it is on the majority of new nodes) then `rawdb.SafeDeleteRange` uses the fast native range delete. Also note that `rawdb.SafeDeleteRange` has different semantics from `ethdb.DeleteRange`, it does not automatically return if the operation takes a long time. Instead it receives a `stopCallback` that can interrupt the process if necessary. This is because in the safe mode potentially a lot of entries are iterated without being deleted (this is definitely the case when deleting the old bloombits database which has a single byte prefix) and therefore restarting the process every time a fixed number of entries have been iterated would result in a quadratic run time in the number of skipped entries. When running in safe mode, unindexing an epoch takes about a second, removing bloombits takes around 10s while resetting a full log index might take a few minutes. If a range delete operation takes a significant amount of time then log messages are printed. Also, any range delete operation can be interrupted by shutdown (tail uinindexing can also be interrupted by head indexing, similarly to how tail indexing works). If the last unindexed epoch might have "dirty" index data left then the indexed map range points to the first valid epoch and `cleanedEpochsBefore` points to the previous, potentially dirty one. At startup it is always assumed that the epoch before the first fully indexed one might be dirty. New tail maps are never rendered and also no further maps are unindexed before the previous unindexing is properly cleaned up. --------- Co-authored-by: Gary Rong Co-authored-by: Felix Lange --- core/filtermaps/filtermaps.go | 210 ++++++++++++++++++++------------ core/filtermaps/indexer.go | 32 ++--- core/rawdb/accessors_indexes.go | 38 +++--- core/rawdb/database.go | 73 +++++++++++ eth/backend.go | 7 +- ethdb/database.go | 9 +- ethdb/leveldb/leveldb.go | 4 +- 7 files changed, 256 insertions(+), 117 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index db7ab0a426..5722f17daa 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -29,7 +29,6 @@ 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/ethdb/leveldb" "github.com/ethereum/go-ethereum/log" ) @@ -59,6 +58,7 @@ type FilterMaps struct { closeCh chan struct{} closeWg sync.WaitGroup history uint64 + hashScheme bool // use hashdb-safe delete range method exportFileName string Params @@ -67,10 +67,11 @@ type FilterMaps struct { // fields written by the indexer and read by matcher backend. Indexer can // read them without a lock and write them under indexLock write lock. // Matcher backend can read them under indexLock read lock. - indexLock sync.RWMutex - indexedRange filterMapsRange - indexedView *ChainView // always consistent with the log index - hasTempRange bool + indexLock sync.RWMutex + indexedRange filterMapsRange + cleanedEpochsBefore uint32 // all unindexed data cleaned before this point + indexedView *ChainView // always consistent with the log index + hasTempRange bool // also accessed by indexer and matcher backend but no locking needed. filterMapCache *lru.Cache[uint32, filterMap] @@ -180,6 +181,10 @@ type Config struct { // This option enables the checkpoint JSON file generator. // If set, the given file will be updated with checkpoint information. ExportFileName string + + // expect trie nodes of hash based state scheme in the filtermaps key range; + // use safe iterator based implementation of DeleteRange that skips them + HashScheme bool } // NewFilterMaps creates a new FilterMaps and starts the indexer. @@ -197,6 +202,7 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f blockProcessingCh: make(chan bool, 1), history: config.History, disabled: config.Disabled, + hashScheme: config.HashScheme, disabledCh: make(chan struct{}), exportFileName: config.ExportFileName, Params: params, @@ -208,15 +214,17 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f maps: common.NewRange(rs.MapsFirst, rs.MapsAfterLast-rs.MapsFirst), tailPartialEpoch: rs.TailPartialEpoch, }, - historyCutoff: historyCutoff, - finalBlock: finalBlock, - matcherSyncCh: make(chan *FilterMapsMatcherBackend), - matchers: make(map[*FilterMapsMatcherBackend]struct{}), - filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps), - lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks), - lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers), - baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows), - renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots), + // deleting last unindexed epoch might have been interrupted by shutdown + cleanedEpochsBefore: max(rs.MapsFirst>>params.logMapsPerEpoch, 1) - 1, + historyCutoff: historyCutoff, + finalBlock: finalBlock, + matcherSyncCh: make(chan *FilterMapsMatcherBackend), + matchers: make(map[*FilterMapsMatcherBackend]struct{}), + filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps), + lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks), + lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers), + baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows), + renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots), } // Set initial indexer target. @@ -301,14 +309,24 @@ func (f *FilterMaps) reset() { // deleting the range first ensures that resetDb will be called again at next // startup and any leftover data will be removed even if it cannot finish now. rawdb.DeleteFilterMapsRange(f.db) - f.safeDeleteRange(rawdb.DeleteFilterMapsDb, "Resetting log index database") + f.safeDeleteWithLogs(rawdb.DeleteFilterMapsDb, "Resetting log index database", f.isShuttingDown) +} + +// isShuttingDown returns true if FilterMaps is shutting down. +func (f *FilterMaps) isShuttingDown() bool { + select { + case <-f.closeCh: + return true + default: + return false + } } // init initializes an empty log index according to the current targetView. func (f *FilterMaps) init() error { // ensure that there is no remaining data in the filter maps key range - if !f.safeDeleteRange(rawdb.DeleteFilterMapsDb, "Resetting log index database") { - return errors.New("could not reset log index database") + if err := f.safeDeleteWithLogs(rawdb.DeleteFilterMapsDb, "Resetting log index database", f.isShuttingDown); err != nil { + return err } f.indexLock.Lock() @@ -358,38 +376,37 @@ func (f *FilterMaps) init() error { // removeBloomBits removes old bloom bits data from the database. func (f *FilterMaps) removeBloomBits() { - f.safeDeleteRange(rawdb.DeleteBloomBitsDb, "Removing old bloom bits database") + f.safeDeleteWithLogs(rawdb.DeleteBloomBitsDb, "Removing old bloom bits database", f.isShuttingDown) f.closeWg.Done() } -// safeDeleteRange calls the specified database range deleter function -// repeatedly as long as it returns leveldb.ErrTooManyKeys. -// This wrapper is necessary because of the leveldb fallback implementation -// of DeleteRange. -func (f *FilterMaps) safeDeleteRange(removeFn func(ethdb.KeyValueRangeDeleter) error, action string) bool { - start := time.Now() - var retry bool - for { - err := removeFn(f.db) - if err == nil { - if retry { - log.Info(action+" finished", "elapsed", time.Since(start)) - } - return true +// safeDeleteWithLogs is a wrapper for a function that performs a safe range +// delete operation using rawdb.SafeDeleteRange. It emits log messages if the +// process takes long enough to call the stop callback. +func (f *FilterMaps) safeDeleteWithLogs(deleteFn func(db ethdb.KeyValueStore, hashScheme bool, stopCb func(bool) bool) error, action string, stopCb func() bool) error { + var ( + start = time.Now() + logPrinted bool + lastLogPrinted = start + ) + switch err := deleteFn(f.db, f.hashScheme, func(deleted bool) bool { + if deleted && !logPrinted || time.Since(lastLogPrinted) > time.Second*10 { + log.Info(action+" in progress...", "elapsed", common.PrettyDuration(time.Since(start))) + logPrinted, lastLogPrinted = true, time.Now() } - if err != leveldb.ErrTooManyKeys { - log.Error(action+" failed", "error", err) - return false - } - select { - case <-f.closeCh: - return false - default: - } - if !retry { - log.Info(action+" in progress...", "elapsed", time.Since(start)) - retry = true + return stopCb() + }); { + case err == nil: + if logPrinted { + log.Info(action+" finished", "elapsed", common.PrettyDuration(time.Since(start))) } + return nil + case errors.Is(err, rawdb.ErrDeleteRangeInterrupted): + log.Warn(action+" interrupted", "elapsed", common.PrettyDuration(time.Since(start))) + return err + default: + log.Error(action+" failed", "error", err) + return err } } @@ -658,54 +675,97 @@ func (f *FilterMaps) deleteLastBlockOfMap(batch ethdb.Batch, mapIndex uint32) { rawdb.DeleteFilterMapLastBlock(batch, mapIndex) } -// deleteTailEpoch deletes index data from the earliest, either fully or partially -// indexed epoch. The last block pointer for the last map of the epoch and the -// corresponding block log value pointer are retained as these are always assumed -// to be available for each epoch. -func (f *FilterMaps) deleteTailEpoch(epoch uint32) error { +// deleteTailEpoch deletes index data from the specified epoch. The last block +// pointer for the last map of the epoch and the corresponding block log value +// pointer are retained as these are always assumed to be available for each +// epoch as boundary markers. +// The function returns true if all index data related to the epoch (except for +// the boundary markers) has been fully removed. +func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { f.indexLock.Lock() defer f.indexLock.Unlock() + // determine epoch boundaries firstMap := epoch << f.logMapsPerEpoch lastBlock, _, err := f.getLastBlockOfMap(firstMap + f.mapsPerEpoch - 1) if err != nil { - return fmt.Errorf("failed to retrieve last block of deleted epoch %d: %v", epoch, err) + return false, fmt.Errorf("failed to retrieve last block of deleted epoch %d: %v", epoch, err) } var firstBlock uint64 if epoch > 0 { firstBlock, _, err = f.getLastBlockOfMap(firstMap - 1) if err != nil { - return fmt.Errorf("failed to retrieve last block before deleted epoch %d: %v", epoch, err) + return false, fmt.Errorf("failed to retrieve last block before deleted epoch %d: %v", epoch, err) } firstBlock++ } - fmr := f.indexedRange - if f.indexedRange.maps.First() == firstMap && - f.indexedRange.maps.AfterLast() > firstMap+f.mapsPerEpoch && - f.indexedRange.tailPartialEpoch == 0 { - fmr.maps.SetFirst(firstMap + f.mapsPerEpoch) - fmr.blocks.SetFirst(lastBlock + 1) - } else if f.indexedRange.maps.First() == firstMap+f.mapsPerEpoch { + // update rendered range if necessary + var ( + fmr = f.indexedRange + firstEpoch = f.indexedRange.maps.First() >> f.logMapsPerEpoch + afterLastEpoch = (f.indexedRange.maps.AfterLast() + f.mapsPerEpoch - 1) >> f.logMapsPerEpoch + ) + if f.indexedRange.tailPartialEpoch != 0 && firstEpoch > 0 { + firstEpoch-- + } + switch { + case epoch < firstEpoch: + // cleanup of already unindexed epoch; range not affected + case epoch == firstEpoch && epoch+1 < afterLastEpoch: + // first fully or partially rendered epoch and there is at least one + // rendered map in the next epoch; remove from indexed range fmr.tailPartialEpoch = 0 + fmr.maps.SetFirst((epoch + 1) << f.logMapsPerEpoch) + fmr.blocks.SetFirst(lastBlock + 1) + f.setRange(f.db, f.indexedView, fmr, false) + default: + // cannot be cleaned or unindexed; return with error + return false, errors.New("invalid tail epoch number") + } + // remove index data + if err := f.safeDeleteWithLogs(func(db ethdb.KeyValueStore, hashScheme bool, stopCb func(bool) bool) error { + first := f.mapRowIndex(firstMap, 0) + count := f.mapRowIndex(firstMap+f.mapsPerEpoch, 0) - first + if err := rawdb.DeleteFilterMapRows(f.db, common.NewRange(first, count), hashScheme, stopCb); err != nil { + return err + } + for mapIndex := firstMap; mapIndex < firstMap+f.mapsPerEpoch; mapIndex++ { + f.filterMapCache.Remove(mapIndex) + } + delMapRange := common.NewRange(firstMap, f.mapsPerEpoch-1) // keep last entry + if err := rawdb.DeleteFilterMapLastBlocks(f.db, delMapRange, hashScheme, stopCb); err != nil { + return err + } + for mapIndex := firstMap; mapIndex < firstMap+f.mapsPerEpoch-1; mapIndex++ { + f.lastBlockCache.Remove(mapIndex) + } + delBlockRange := common.NewRange(firstBlock, lastBlock-firstBlock) // keep last entry + if err := rawdb.DeleteBlockLvPointers(f.db, delBlockRange, hashScheme, stopCb); err != nil { + return err + } + for blockNumber := firstBlock; blockNumber < lastBlock; blockNumber++ { + f.lvPointerCache.Remove(blockNumber) + } + return nil + }, fmt.Sprintf("Deleting tail epoch #%d", epoch), func() bool { + f.processEvents() + return f.stop || !f.targetHeadIndexed() + }); err == nil { + // everything removed; mark as cleaned and report success + if f.cleanedEpochsBefore == epoch { + f.cleanedEpochsBefore = epoch + 1 + } + return true, nil } else { - return errors.New("invalid tail epoch number") + // more data left in epoch range; mark as dirty and report unfinished + if f.cleanedEpochsBefore > epoch { + f.cleanedEpochsBefore = epoch + } + if errors.Is(err, rawdb.ErrDeleteRangeInterrupted) { + return false, nil + } + return false, err } - f.setRange(f.db, f.indexedView, fmr, false) - first := f.mapRowIndex(firstMap, 0) - count := f.mapRowIndex(firstMap+f.mapsPerEpoch, 0) - first - rawdb.DeleteFilterMapRows(f.db, common.NewRange(first, count)) - for mapIndex := firstMap; mapIndex < firstMap+f.mapsPerEpoch; mapIndex++ { - f.filterMapCache.Remove(mapIndex) - } - rawdb.DeleteFilterMapLastBlocks(f.db, common.NewRange(firstMap, f.mapsPerEpoch-1)) // keep last enrty - for mapIndex := firstMap; mapIndex < firstMap+f.mapsPerEpoch-1; mapIndex++ { - f.lastBlockCache.Remove(mapIndex) - } - rawdb.DeleteBlockLvPointers(f.db, common.NewRange(firstBlock, lastBlock-firstBlock)) // keep last enrty - for blockNumber := firstBlock; blockNumber < lastBlock; blockNumber++ { - f.lvPointerCache.Remove(blockNumber) - } - return nil } // exportCheckpoints exports epoch checkpoints in the format used by checkpoints.go. diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 6732dc85ea..9a5424da4a 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -67,14 +67,17 @@ func (f *FilterMaps) indexerLoop() { } f.lastFinal = f.finalBlock } - if done, err := f.tryIndexTail(); err != nil { - f.disableForError("tail rendering", err) + // always attempt unindexing before indexing the tail in order to + // ensure that a potentially dirty previously unindexed epoch is + // always cleaned up before any new maps are rendered. + if done, err := f.tryUnindexTail(); err != nil { + f.disableForError("tail unindexing", err) return } else if !done { continue } - if done, err := f.tryUnindexTail(); err != nil { - f.disableForError("tail unindexing", err) + if done, err := f.tryIndexTail(); err != nil { + f.disableForError("tail rendering", err) return } else if !done { continue @@ -349,25 +352,24 @@ func (f *FilterMaps) tryIndexTail() (bool, error) { // Note that unindexing is very quick as it only removes continuous ranges of // data from the database and is also called while running head indexing. func (f *FilterMaps) tryUnindexTail() (bool, error) { - for { - firstEpoch := (f.indexedRange.maps.First() - f.indexedRange.tailPartialEpoch) >> f.logMapsPerEpoch - if f.needTailEpoch(firstEpoch) { - break - } - f.processEvents() - if f.stop { - return false, nil - } + firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch + if f.indexedRange.tailPartialEpoch > 0 && firstEpoch > 0 { + firstEpoch-- + } + for epoch := min(firstEpoch, f.cleanedEpochsBefore); !f.needTailEpoch(epoch); epoch++ { if !f.startedTailUnindex { f.startedTailUnindexAt = time.Now() f.startedTailUnindex = true f.ptrTailUnindexMap = f.indexedRange.maps.First() - f.indexedRange.tailPartialEpoch f.ptrTailUnindexBlock = f.indexedRange.blocks.First() - f.tailPartialBlocks() } - if err := f.deleteTailEpoch(firstEpoch); err != nil { - log.Error("Log index tail epoch unindexing failed", "error", err) + if done, err := f.deleteTailEpoch(epoch); !done { return false, err } + f.processEvents() + if f.stop || !f.targetHeadIndexed() { + return false, nil + } } if f.startedTailUnindex && f.indexedRange.hasIndexedBlocks() { log.Info("Log index tail unindexing finished", diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index 297e339c83..c413839b7b 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -354,10 +354,8 @@ func WriteFilterMapBaseRows(db ethdb.KeyValueWriter, mapRowIndex uint64, rows [] } } -func DeleteFilterMapRows(db ethdb.KeyValueRangeDeleter, mapRows common.Range[uint64]) { - if err := db.DeleteRange(filterMapRowKey(mapRows.First(), false), filterMapRowKey(mapRows.AfterLast(), false)); err != nil { - log.Crit("Failed to delete range of filter map rows", "err", err) - } +func DeleteFilterMapRows(db ethdb.KeyValueStore, mapRows common.Range[uint64], hashScheme bool, stopCallback func(bool) bool) error { + return SafeDeleteRange(db, filterMapRowKey(mapRows.First(), false), filterMapRowKey(mapRows.AfterLast(), false), hashScheme, stopCallback) } // ReadFilterMapLastBlock retrieves the number of the block that generated the @@ -368,7 +366,7 @@ func ReadFilterMapLastBlock(db ethdb.KeyValueReader, mapIndex uint32) (uint64, c return 0, common.Hash{}, err } if len(enc) != 40 { - return 0, common.Hash{}, errors.New("Invalid block number and id encoding") + return 0, common.Hash{}, errors.New("invalid block number and id encoding") } var id common.Hash copy(id[:], enc[8:]) @@ -394,10 +392,8 @@ func DeleteFilterMapLastBlock(db ethdb.KeyValueWriter, mapIndex uint32) { } } -func DeleteFilterMapLastBlocks(db ethdb.KeyValueRangeDeleter, maps common.Range[uint32]) { - if err := db.DeleteRange(filterMapLastBlockKey(maps.First()), filterMapLastBlockKey(maps.AfterLast())); err != nil { - log.Crit("Failed to delete range of filter map last block pointers", "err", err) - } +func DeleteFilterMapLastBlocks(db ethdb.KeyValueStore, maps common.Range[uint32], hashScheme bool, stopCallback func(bool) bool) error { + return SafeDeleteRange(db, filterMapLastBlockKey(maps.First()), filterMapLastBlockKey(maps.AfterLast()), hashScheme, stopCallback) } // ReadBlockLvPointer retrieves the starting log value index where the log values @@ -408,7 +404,7 @@ func ReadBlockLvPointer(db ethdb.KeyValueReader, blockNumber uint64) (uint64, er return 0, err } if len(encPtr) != 8 { - return 0, errors.New("Invalid log value pointer encoding") + return 0, errors.New("invalid log value pointer encoding") } return binary.BigEndian.Uint64(encPtr), nil } @@ -431,10 +427,8 @@ func DeleteBlockLvPointer(db ethdb.KeyValueWriter, blockNumber uint64) { } } -func DeleteBlockLvPointers(db ethdb.KeyValueRangeDeleter, blocks common.Range[uint64]) { - if err := db.DeleteRange(filterMapBlockLVKey(blocks.First()), filterMapBlockLVKey(blocks.AfterLast())); err != nil { - log.Crit("Failed to delete range of block log value pointers", "err", err) - } +func DeleteBlockLvPointers(db ethdb.KeyValueStore, blocks common.Range[uint64], hashScheme bool, stopCallback func(bool) bool) error { + return SafeDeleteRange(db, filterMapBlockLVKey(blocks.First()), filterMapBlockLVKey(blocks.AfterLast()), hashScheme, stopCallback) } // FilterMapsRange is a storage representation of the block range covered by the @@ -485,22 +479,22 @@ func DeleteFilterMapsRange(db ethdb.KeyValueWriter) { } // deletePrefixRange deletes everything with the given prefix from the database. -func deletePrefixRange(db ethdb.KeyValueRangeDeleter, prefix []byte) error { +func deletePrefixRange(db ethdb.KeyValueStore, prefix []byte, hashScheme bool, stopCallback func(bool) bool) error { end := bytes.Clone(prefix) end[len(end)-1]++ - return db.DeleteRange(prefix, end) + return SafeDeleteRange(db, prefix, end, hashScheme, stopCallback) } // DeleteFilterMapsDb removes the entire filter maps database -func DeleteFilterMapsDb(db ethdb.KeyValueRangeDeleter) error { - return deletePrefixRange(db, []byte(filterMapsPrefix)) +func DeleteFilterMapsDb(db ethdb.KeyValueStore, hashScheme bool, stopCallback func(bool) bool) error { + return deletePrefixRange(db, []byte(filterMapsPrefix), hashScheme, stopCallback) } -// DeleteFilterMapsDb removes the old bloombits database and the associated +// DeleteBloomBitsDb removes the old bloombits database and the associated // chain indexer database. -func DeleteBloomBitsDb(db ethdb.KeyValueRangeDeleter) error { - if err := deletePrefixRange(db, bloomBitsPrefix); err != nil { +func DeleteBloomBitsDb(db ethdb.KeyValueStore, hashScheme bool, stopCallback func(bool) bool) error { + if err := deletePrefixRange(db, bloomBitsPrefix, hashScheme, stopCallback); err != nil { return err } - return deletePrefixRange(db, bloomBitsMetaPrefix) + return deletePrefixRange(db, bloomBitsMetaPrefix, hashScheme, stopCallback) } diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 7fca822155..2a50e3f9ee 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -28,12 +28,15 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/log" "github.com/olekukonko/tablewriter" ) +var ErrDeleteRangeInterrupted = errors.New("safe delete range operation interrupted") + // freezerdb is a database wrapper that enables ancient chain segment freezing. type freezerdb struct { ethdb.KeyValueStore @@ -607,3 +610,73 @@ func ReadChainMetadata(db ethdb.KeyValueStore) [][]string { } return data } + +// SafeDeleteRange deletes all of the keys (and values) in the range +// [start,end) (inclusive on start, exclusive on end). +// If hashScheme is true then it always uses an iterator and skips hashdb trie +// node entries. If it is false and the backing db is pebble db then it uses +// the fast native range delete. +// In case of fallback mode (hashdb or leveldb) the range deletion might be +// very slow depending on the number of entries. In this case stopCallback +// is periodically called and if it returns an error then SafeDeleteRange +// stops and also returns that error. The callback is not called if native +// range delete is used or there are a small number of keys only. The bool +// argument passed to the callback is true if enrties have actually been +// deleted already. +func SafeDeleteRange(db ethdb.KeyValueStore, start, end []byte, hashScheme bool, stopCallback func(bool) bool) error { + if !hashScheme { + // delete entire range; use fast native range delete on pebble db + for { + switch err := db.DeleteRange(start, end); { + case err == nil: + return nil + case errors.Is(err, ethdb.ErrTooManyKeys): + if stopCallback(true) { + return ErrDeleteRangeInterrupted + } + default: + return err + } + } + } + + var ( + count, deleted, skipped int + buff = crypto.NewKeccakState() + startTime = time.Now() + ) + + batch := db.NewBatch() + it := db.NewIterator(nil, start) + defer func() { + it.Release() // it might be replaced during the process + log.Debug("SafeDeleteRange finished", "deleted", deleted, "skipped", skipped, "elapsed", common.PrettyDuration(time.Since(startTime))) + }() + + for it.Next() && bytes.Compare(end, it.Key()) > 0 { + // Prevent deletion for trie nodes in hash mode + if len(it.Key()) != 32 || crypto.HashData(buff, it.Value()) != common.BytesToHash(it.Key()) { + if err := batch.Delete(it.Key()); err != nil { + return err + } + deleted++ + } else { + skipped++ + } + count++ + if count > 10000 { // should not block for more than a second + if err := batch.Write(); err != nil { + return err + } + if stopCallback(deleted != 0) { + return ErrDeleteRangeInterrupted + } + start = append(bytes.Clone(it.Key()), 0) // appending a zero gives us the next possible key + it.Release() + batch = db.NewBatch() + it = db.NewIterator(nil, start) + count = 0 + } + } + return batch.Write() +} diff --git a/eth/backend.go b/eth/backend.go index 909d153a2b..ab612b1de7 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -239,7 +239,12 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } - fmConfig := filtermaps.Config{History: config.LogHistory, Disabled: config.LogNoHistory, ExportFileName: config.LogExportCheckpoints} + fmConfig := filtermaps.Config{ + History: config.LogHistory, + Disabled: config.LogNoHistory, + ExportFileName: config.LogExportCheckpoints, + HashScheme: scheme == rawdb.HashScheme, + } chainView := eth.newChainView(eth.blockchain.CurrentBlock()) historyCutoff := eth.blockchain.HistoryPruningCutoff() var finalBlock uint64 diff --git a/ethdb/database.go b/ethdb/database.go index b1577512f3..f2d458b85f 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -17,7 +17,10 @@ // Package ethdb defines the interfaces for an Ethereum data store. package ethdb -import "io" +import ( + "errors" + "io" +) // KeyValueReader wraps the Has and Get method of a backing data store. type KeyValueReader interface { @@ -37,10 +40,14 @@ type KeyValueWriter interface { Delete(key []byte) error } +var ErrTooManyKeys = errors.New("too many keys in deleted range") + // KeyValueRangeDeleter wraps the DeleteRange method of a backing data store. type KeyValueRangeDeleter interface { // DeleteRange deletes all of the keys (and values) in the range [start,end) // (inclusive on start, exclusive on end). + // Some implementations of DeleteRange may return ErrTooManyKeys after + // partially deleting entries in the given range. DeleteRange(start, end []byte) error } diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index 7f47523b82..ef02e91822 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -207,8 +207,6 @@ func (db *Database) Delete(key []byte) error { return db.db.Delete(key, nil) } -var ErrTooManyKeys = errors.New("too many keys in deleted range") - // DeleteRange deletes all of the keys (and values) in the range [start,end) // (inclusive on start, exclusive on end). // Note that this is a fallback implementation as leveldb does not natively @@ -228,7 +226,7 @@ func (db *Database) DeleteRange(start, end []byte) error { if err := batch.Write(); err != nil { return err } - return ErrTooManyKeys + return ethdb.ErrTooManyKeys } if err := batch.Delete(it.Key()); err != nil { return err From 82fc77a8658dc7adf53ba8c55e8329bf89d47544 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 31 Mar 2025 15:29:03 +0200 Subject: [PATCH 246/940] version: release go-ethereum v1.15.7 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 8cd428fd10..2098af17b5 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 7 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 7 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From 9c970d80a28d1eb98ea101cdb6209cc3be9962bc Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 31 Mar 2025 15:30:31 +0200 Subject: [PATCH 247/940] version: begin v1.15.8 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 2098af17b5..72fd903a1f 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 7 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 8 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From 9af88d1100e17da0764081acb76b0d2154fc1893 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 31 Mar 2025 18:26:56 +0200 Subject: [PATCH 248/940] version: back to v1.15.7, to fix the build --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 72fd903a1f..2098af17b5 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 8 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 7 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From 827d3fccf72b69324ba00f7050afd59cf956348d Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 31 Mar 2025 18:27:43 +0200 Subject: [PATCH 249/940] .travis.yml: remove macos build --- .travis.yml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5e8a493d03..43f8ced19c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,6 @@ language: go go_import_path: github.com/ethereum/go-ethereum sudo: false jobs: - allow_failures: - - stage: build - os: osx - env: - - azure-osx - include: # This builder create and push the Docker images for all architectures - stage: build @@ -62,23 +56,6 @@ jobs: - go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds - # This builder does the OSX Azure uploads - - stage: build - if: type = push - os: osx - osx_image: xcode14.2 - 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 - - go run build/ci.go archive -arch arm64 -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds - # These builders run the tests - stage: build if: type = push From f0cdc40cebd3fcb26d21ced0f1093efd7a2c949f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 31 Mar 2025 18:29:33 +0200 Subject: [PATCH 250/940] version: begin v1.15.8 release cycle reloaded --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 2098af17b5..72fd903a1f 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 7 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 8 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From bc36f2de83a5ba8e805af6ce4ea9da3ab7cb1df9 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Tue, 1 Apr 2025 13:42:01 +0200 Subject: [PATCH 251/940] eth, eth/filters: implement API error code for pruned blocks (#31361) Implements #31275 --------- Co-authored-by: Jared Wasinger Co-authored-by: Felix Lange --- core/blockchain_reader.go | 5 ++ eth/api_backend.go | 46 ++++++++++++++++--- eth/ethconfig/historymode.go | 6 +++ eth/filters/api.go | 5 ++ eth/filters/filter.go | 20 ++++++-- eth/filters/filter_system.go | 10 ++++ eth/filters/filter_system_test.go | 4 ++ internal/ethapi/api.go | 58 +++++++++++++----------- internal/ethapi/api_test.go | 7 +++ internal/ethapi/backend.go | 1 + internal/ethapi/transaction_args_test.go | 2 + rpc/types.go | 2 +- 12 files changed, 128 insertions(+), 38 deletions(-) diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 025b912ceb..415a0f5442 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -86,6 +86,11 @@ func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { return bc.hc.GetHeaderByNumber(number) } +// GetBlockNumber retrieves the block number associated with a block hash. +func (bc *BlockChain) GetBlockNumber(hash common.Hash) *uint64 { + return bc.hc.GetBlockNumber(hash) +} + // GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going // backwards from the given number. func (bc *BlockChain) GetHeadersFrom(number, count uint64) []rlp.RawValue { diff --git a/eth/api_backend.go b/eth/api_backend.go index c8c5ca707f..944c357e78 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethdb" @@ -91,7 +92,13 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb } return block, nil } - return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil + var bn uint64 + if number == rpc.EarliestBlockNumber { + bn = b.eth.blockchain.HistoryPruningCutoff() + } else { + bn = uint64(number) + } + return b.eth.blockchain.GetHeaderByNumber(bn), nil } func (b *EthAPIBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) { @@ -143,11 +150,27 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe } return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil } - return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil + bn := uint64(number) // the resolved number + if number == rpc.EarliestBlockNumber { + bn = b.eth.blockchain.HistoryPruningCutoff() + } + block := b.eth.blockchain.GetBlockByNumber(bn) + if block == nil && bn < b.eth.blockchain.HistoryPruningCutoff() { + return nil, ðconfig.PrunedHistoryError{} + } + return block, nil } func (b *EthAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { - return b.eth.blockchain.GetBlockByHash(hash), nil + number := b.eth.blockchain.GetBlockNumber(hash) + if number == nil { + return nil, nil + } + block := b.eth.blockchain.GetBlock(hash, *number) + if block == nil && *number < b.eth.blockchain.HistoryPruningCutoff() { + return nil, ðconfig.PrunedHistoryError{} + } + return block, nil } // GetBody returns body of a block. It does not resolve special block numbers. @@ -155,10 +178,14 @@ func (b *EthAPIBackend) GetBody(ctx context.Context, hash common.Hash, number rp if number < 0 || hash == (common.Hash{}) { return nil, errors.New("invalid arguments; expect hash and no special block numbers") } - if body := b.eth.blockchain.GetBody(hash); body != nil { - return body, nil + body := b.eth.blockchain.GetBody(hash) + if body == nil { + if uint64(number) < b.eth.blockchain.HistoryPruningCutoff() { + return nil, ðconfig.PrunedHistoryError{} + } + return nil, errors.New("block body not found") } - return nil, errors.New("block body not found") + return body, nil } func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) { @@ -175,6 +202,9 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r } block := b.eth.blockchain.GetBlock(hash, header.Number.Uint64()) if block == nil { + if header.Number.Uint64() < b.eth.blockchain.HistoryPruningCutoff() { + return nil, ðconfig.PrunedHistoryError{} + } return nil, errors.New("header found, but block body is missing") } return block, nil @@ -234,6 +264,10 @@ func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockN return nil, nil, errors.New("invalid arguments; neither block nor hash specified") } +func (b *EthAPIBackend) HistoryPruningCutoff() uint64 { + return b.eth.blockchain.HistoryPruningCutoff() +} + func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { return b.eth.blockchain.GetReceiptsByHash(hash), nil } diff --git a/eth/ethconfig/historymode.go b/eth/ethconfig/historymode.go index c3661004e8..a595d72feb 100644 --- a/eth/ethconfig/historymode.go +++ b/eth/ethconfig/historymode.go @@ -90,3 +90,9 @@ var HistoryPrunePoints = map[common.Hash]*HistoryPrunePoint{ BlockHash: common.HexToHash("0x229f6b18ca1552f1d5146deceb5387333f40dc6275aebee3f2c5c4ece07d02db"), }, } + +// PrunedHistoryError is returned when the requested history is pruned. +type PrunedHistoryError struct{} + +func (e *PrunedHistoryError) Error() string { return "pruned history unavailable" } +func (e *PrunedHistoryError) ErrorCode() int { return 4444 } diff --git a/eth/filters/api.go b/eth/filters/api.go index e3057a2af2..6593cbef27 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -29,6 +29,7 @@ import ( "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/eth/ethconfig" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rpc" ) @@ -354,9 +355,13 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type if crit.ToBlock != nil { end = crit.ToBlock.Int64() } + // Block numbers below 0 are special cases. if begin > 0 && end > 0 && begin > end { return nil, errInvalidBlockRange } + if begin > 0 && begin < int64(api.events.backend.HistoryPruningCutoff()) { + return nil, ðconfig.PrunedHistoryError{} + } // Construct the range filter filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics) } diff --git a/eth/filters/filter.go b/eth/filters/filter.go index b743c25994..e44b37d047 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" ) @@ -86,6 +87,9 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { if header == nil { return nil, errors.New("unknown block") } + if header.Number.Uint64() < f.sys.backend.HistoryPruningCutoff() { + return nil, ðconfig.PrunedHistoryError{} + } return f.blockLogs(ctx, header) } @@ -114,11 +118,19 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return 0, errors.New("safe header not found") } return hdr.Number.Uint64(), nil + case rpc.EarliestBlockNumber.Int64(): + earliest := f.sys.backend.HistoryPruningCutoff() + hdr, _ := f.sys.backend.HeaderByNumber(ctx, rpc.BlockNumber(earliest)) + if hdr == nil { + return 0, errors.New("earliest header not found") + } + return hdr.Number.Uint64(), nil + default: + if number < 0 { + return 0, errors.New("negative block number") + } + return uint64(number), nil } - if number < 0 { - return 0, errors.New("negative block number") - } - return uint64(number), nil } // range query need to resolve the special begin/end block number diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 7531a1ecfc..aca3c03ad6 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" @@ -64,6 +65,7 @@ type Backend interface { CurrentHeader() *types.Header ChainConfig() *params.ChainConfig + HistoryPruningCutoff() uint64 SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription @@ -304,6 +306,14 @@ func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*typ return nil, errPendingLogsUnsupported } + if from == rpc.EarliestBlockNumber { + from = rpc.BlockNumber(es.backend.HistoryPruningCutoff()) + } + // Queries beyond the pruning cutoff are not supported. + if uint64(from) < es.backend.HistoryPruningCutoff() { + return nil, ðconfig.PrunedHistoryError{} + } + // only interested in new mined logs if from == rpc.LatestBlockNumber && to == rpc.LatestBlockNumber { return es.subscribeLogs(crit, logs), nil diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index c35d823f5a..3bb019d105 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -181,6 +181,10 @@ func (b *testBackend) setPending(block *types.Block, receipts types.Receipts) { b.pendingReceipts = receipts } +func (b *testBackend) HistoryPruningCutoff() uint64 { + return 0 +} + func newTestFilterSystem(db ethdb.Database, cfg Config) (*testBackend, *FilterSystem) { backend := &testBackend{db: db} sys := NewFilterSystem(backend, cfg) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 36a5df8087..3b699748b8 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -549,21 +549,23 @@ func (api *BlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, block } // GetUncleCountByBlockNumber returns number of uncles in the block for the given block number -func (api *BlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { - if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil { +func (api *BlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error) { + block, err := api.b.BlockByNumber(ctx, blockNr) + if block != nil { n := hexutil.Uint(len(block.Uncles())) - return &n + return &n, nil } - return nil + return nil, err } // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash -func (api *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { - if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil { +func (api *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error) { + block, err := api.b.BlockByHash(ctx, blockHash) + if block != nil { n := hexutil.Uint(len(block.Uncles())) - return &n + return &n, nil } - return nil + return nil, err } // GetCode returns the code stored at the given address in the state for the given block number. @@ -596,9 +598,7 @@ func (api *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Addre 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 + return nil, err } receipts, err := api.b.GetReceipts(ctx, block.Hash()) if err != nil { @@ -1258,37 +1258,41 @@ func NewTransactionAPI(b Backend, nonceLock *AddrLocker) *TransactionAPI { } // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. -func (api *TransactionAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { - if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil { +func (api *TransactionAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error) { + block, err := api.b.BlockByNumber(ctx, blockNr) + if block != nil { n := hexutil.Uint(len(block.Transactions())) - return &n + return &n, nil } - return nil + return nil, err } // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. -func (api *TransactionAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { - if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil { +func (api *TransactionAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error) { + block, err := api.b.BlockByHash(ctx, blockHash) + if block != nil { n := hexutil.Uint(len(block.Transactions())) - return &n + return &n, nil } - return nil + return nil, err } // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. -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()) +func (api *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (*RPCTransaction, error) { + block, err := api.b.BlockByNumber(ctx, blockNr) + if block != nil { + return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig()), nil } - return nil + return nil, err } // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. -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()) +func (api *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (*RPCTransaction, error) { + block, err := api.b.BlockByHash(ctx, blockHash) + if block != nil { + return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig()), nil } - return nil + return nil, err } // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 1ed1a8c8d8..37210aa78b 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -520,8 +520,12 @@ func (b testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) if number == rpc.PendingBlockNumber { return b.pending, nil } + if number == rpc.EarliestBlockNumber { + number = 0 + } return b.chain.GetBlockByNumber(uint64(number)), nil } + func (b testBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { return b.chain.GetBlockByHash(hash), nil } @@ -618,6 +622,9 @@ func (b testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscripti func (b testBackend) NewMatcherBackend() filtermaps.MatcherBackend { panic("implement me") } + +func (b testBackend) HistoryPruningCutoff() uint64 { return b.chain.HistoryPruningCutoff() } + func TestEstimateGas(t *testing.T) { t.Parallel() // Initialize test accounts diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 9e2ea2c876..c4bf2e0591 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -85,6 +85,7 @@ type Backend interface { ChainConfig() *params.ChainConfig Engine() consensus.Engine + HistoryPruningCutoff() uint64 // This is copied from filters.Backend // eth/filters needs to be initialized from this backend type, so methods needed by diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index a5fd9bb0d4..b4d11a3033 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -402,3 +402,5 @@ func (b *backendMock) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) func (b *backendMock) Engine() consensus.Engine { return nil } func (b *backendMock) NewMatcherBackend() filtermaps.MatcherBackend { return nil } + +func (b *backendMock) HistoryPruningCutoff() uint64 { return 0 } diff --git a/rpc/types.go b/rpc/types.go index 2e53174b87..85f15344e8 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -63,11 +63,11 @@ type jsonWriter interface { type BlockNumber int64 const ( + EarliestBlockNumber = BlockNumber(-5) SafeBlockNumber = BlockNumber(-4) FinalizedBlockNumber = BlockNumber(-3) LatestBlockNumber = BlockNumber(-2) PendingBlockNumber = BlockNumber(-1) - EarliestBlockNumber = BlockNumber(0) ) // UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports: From 1bd70ba57aa943340e7a685ee3d89db072ac6ef6 Mon Sep 17 00:00:00 2001 From: John <33443230+gazzua@users.noreply.github.com> Date: Tue, 1 Apr 2025 21:07:47 +0900 Subject: [PATCH 252/940] p2p/nat: improve AddMapping code (#31486) It introduces a new variable to store the external port returned by the addAnyPortMapping function and ensures that the correct external port is returned even in case of an error. --------- Co-authored-by: Felix Lange --- p2p/nat/natupnp.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/p2p/nat/natupnp.go b/p2p/nat/natupnp.go index f1bb955892..1014dc69d2 100644 --- a/p2p/nat/natupnp.go +++ b/p2p/nat/natupnp.go @@ -82,7 +82,7 @@ func (n *upnp) ExternalIP() (addr net.IP, err error) { func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, lifetime time.Duration) (uint16, error) { ip, err := n.internalAddress() if err != nil { - return 0, nil // TODO: Shouldn't we return the error? + return 0, err } protocol = strings.ToUpper(protocol) lifetimeS := uint32(lifetime / time.Second) @@ -94,14 +94,15 @@ func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, li if err == nil { return uint16(extport), nil } - - return uint16(extport), n.withRateLimit(func() error { + // Try addAnyPortMapping if mapping specified port didn't work. + err = n.withRateLimit(func() error { p, err := n.addAnyPortMapping(protocol, extport, intport, ip, desc, lifetimeS) if err == nil { extport = int(p) } return err }) + return uint16(extport), err } func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.IP, desc string, lifetimeS uint32) (uint16, error) { From 4add312c8a8332b76e5263066a475e962637c9ac Mon Sep 17 00:00:00 2001 From: Delweng Date: Tue, 1 Apr 2025 20:10:22 +0800 Subject: [PATCH 253/940] cmd: apply snapshot cache flag in the MakeChain (#31534) --- cmd/utils/flags.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index ae58c2d053..fb2892d2c1 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2189,6 +2189,8 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh } if !ctx.Bool(SnapshotFlag.Name) { cache.SnapshotLimit = 0 // Disabled + } else if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheSnapshotFlag.Name) { + cache.SnapshotLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheSnapshotFlag.Name) / 100 } // If we're in readonly, do not bother generating snapshot data. if readonly { From 7e3170fb5ce4e03348d29d1a153c2591680058a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Tue, 1 Apr 2025 14:29:20 +0200 Subject: [PATCH 254/940] core/filtermaps: add metrics (#31511) This PR adds metrics related to map rendering and pattern matching to the `core/filtermaps` package. --- core/filtermaps/filtermaps.go | 21 +++++++++++++++++++++ core/filtermaps/map_renderer.go | 22 +++++++++++++++++++++- core/filtermaps/matcher.go | 12 ++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index 5722f17daa..18b1c7dc79 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -30,6 +30,23 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +var ( + mapCountGauge = metrics.NewRegisteredGauge("filtermaps/maps/count", nil) // actual number of rendered maps + mapLogValueMeter = metrics.NewRegisteredMeter("filtermaps/maps/logvalues", nil) // number of log values processed + mapBlockMeter = metrics.NewRegisteredMeter("filtermaps/maps/blocks", nil) // number of block delimiters processed + mapRenderTimer = metrics.NewRegisteredTimer("filtermaps/maps/rendertime", nil) // time elapsed while rendering a single map + mapWriteTimer = metrics.NewRegisteredTimer("filtermaps/maps/writetime", nil) // time elapsed while writing a batch of finished maps to db + matchRequestTimer = metrics.NewRegisteredTimer("filtermaps/match/requesttime", nil) // processing time a matching request in a single epoch + matchEpochTimer = metrics.NewRegisteredTimer("filtermaps/match/epochtime", nil) // total processing time a matching request + matchBaseRowAccessMeter = metrics.NewRegisteredMeter("filtermaps/match/baserowaccess", nil) // number of accessed rows on layer 0 + matchBaseRowSizeMeter = metrics.NewRegisteredMeter("filtermaps/match/baserowsize", nil) // size of accessed rows on layer 0 + matchExtRowAccessMeter = metrics.NewRegisteredMeter("filtermaps/match/extrowaccess", nil) // number of accessed rows on higher layers + matchExtRowSizeMeter = metrics.NewRegisteredMeter("filtermaps/match/extrowsize", nil) // size of accessed rows on higher layers + matchLogLookup = metrics.NewRegisteredMeter("filtermaps/match/loglookup", nil) // number of log lookups based on potential matches + matchAllMeter = metrics.NewRegisteredMeter("filtermaps/match/matchall", nil) // number of requests returned with ErrMatchAll ) const ( @@ -429,8 +446,12 @@ func (f *FilterMaps) setRange(batch ethdb.KeyValueWriter, newView *ChainView, ne TailPartialEpoch: newRange.tailPartialEpoch, } rawdb.WriteFilterMapsRange(batch, rs) + if !isTempRange { + mapCountGauge.Update(int64(newRange.maps.Count() + newRange.tailPartialEpoch)) + } } else { rawdb.DeleteFilterMapsRange(batch) + mapCountGauge.Update(0) } } diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index 1eaaa9bb1a..28f943abb3 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -21,6 +21,7 @@ import ( "fmt" "math" "sort" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/lru" @@ -301,6 +302,11 @@ func (r *mapRenderer) run(stopCb func() bool, writeCb func()) (bool, error) { // renderCurrentMap renders a single map. func (r *mapRenderer) renderCurrentMap(stopCb func() bool) (bool, error) { + var ( + totalTime time.Duration + logValuesProcessed, blocksProcessed int64 + ) + start := time.Now() if !r.iterator.updateChainView(r.f.targetView) { return false, errChainUpdate } @@ -316,9 +322,11 @@ func (r *mapRenderer) renderCurrentMap(stopCb func() bool) (bool, error) { for r.iterator.lvIndex < uint64(r.currentMap.mapIndex+1)<= valuesPerCallback { + totalTime += time.Since(start) if stopCb() { return false, nil } + start = time.Now() if !r.iterator.updateChainView(r.f.targetView) { return false, errChainUpdate } @@ -343,8 +351,10 @@ func (r *mapRenderer) renderCurrentMap(stopCb func() bool) (bool, error) { return false, fmt.Errorf("failed to advance log iterator at %d while rendering map %d: %v", r.iterator.lvIndex, r.currentMap.mapIndex, err) } if !r.iterator.skipToBoundary { + logValuesProcessed++ r.currentMap.lastBlock = r.iterator.blockNumber if r.iterator.blockStart { + blocksProcessed++ r.currentMap.blockLvPtrs = append(r.currentMap.blockLvPtrs, r.iterator.lvIndex) } if !r.f.testDisableSnapshots && r.renderBefore >= r.f.indexedRange.maps.AfterLast() && @@ -358,12 +368,18 @@ func (r *mapRenderer) renderCurrentMap(stopCb func() bool) (bool, error) { r.currentMap.headDelimiter = r.iterator.lvIndex } r.currentMap.lastBlockId = r.f.targetView.getBlockId(r.currentMap.lastBlock) + totalTime += time.Since(start) + mapRenderTimer.Update(totalTime) + mapLogValueMeter.Mark(logValuesProcessed) + mapBlockMeter.Mark(blocksProcessed) return true, nil } // writeFinishedMaps writes rendered maps to the database and updates // filterMapsRange and indexedView accordingly. func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { + var totalTime time.Duration + start := time.Now() if len(r.finishedMaps) == 0 { return nil } @@ -379,7 +395,7 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { if err != nil { return fmt.Errorf("failed to get updated rendered range: %v", err) } - renderedView := r.f.targetView // stopCb callback might still change targetView while writing finished maps + renderedView := r.f.targetView // pauseCb callback might still change targetView while writing finished maps batch := r.f.db.NewBatch() var writeCnt int @@ -393,7 +409,9 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { // do not exit while in partially written state but do allow processing // events and pausing while block processing is in progress r.f.indexLock.Unlock() + totalTime += time.Since(start) pauseCb() + start = time.Now() r.f.indexLock.Lock() batch = r.f.db.NewBatch() } @@ -477,6 +495,8 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { if err := batch.Write(); err != nil { log.Crit("Error writing log index update batch", "error", err) } + totalTime += time.Since(start) + mapWriteTimer.Update(totalTime) return nil } diff --git a/core/filtermaps/matcher.go b/core/filtermaps/matcher.go index 6c05672cbc..5738bf166a 100644 --- a/core/filtermaps/matcher.go +++ b/core/filtermaps/matcher.go @@ -125,6 +125,7 @@ func GetPotentialMatches(ctx context.Context, backend MatcherBackend, firstBlock start := time.Now() res, err := m.process() + matchRequestTimer.Update(time.Since(start)) if doRuntimeStats { log.Info("Log search finished", "elapsed", time.Since(start)) @@ -202,6 +203,7 @@ func (m *matcherEnv) process() ([]*types.Log, error) { logs = append(logs, tasks[waitEpoch].logs...) if err := tasks[waitEpoch].err; err != nil { if err == ErrMatchAll { + matchAllMeter.Mark(1) return logs, err } return logs, fmt.Errorf("failed to process log index epoch %d: %v", waitEpoch, err) @@ -220,6 +222,7 @@ func (m *matcherEnv) process() ([]*types.Log, error) { // processEpoch returns the potentially matching logs from the given epoch. func (m *matcherEnv) processEpoch(epochIndex uint32) ([]*types.Log, error) { + start := time.Now() var logs []*types.Log // create a list of map indices to process fm, lm := epochIndex< Date: Tue, 1 Apr 2025 22:13:37 +0800 Subject: [PATCH 255/940] accounts/abi/abigen: fix a flaky bind test case `NewSingleStructArgument` (#31501) found the failed testcase here https://ci.appveyor.com/project/ethereum/go-ethereum/builds/51767091/job/rbjke432c05pufja add a timeout to wait the tx to be mined. --------- Signed-off-by: jsvisa Co-authored-by: Jared Wasinger --- accounts/abi/abigen/bind_test.go | 55 ++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/accounts/abi/abigen/bind_test.go b/accounts/abi/abigen/bind_test.go index 3871560912..195064fb7a 100644 --- a/accounts/abi/abigen/bind_test.go +++ b/accounts/abi/abigen/bind_test.go @@ -541,7 +541,7 @@ var bindTests = []struct { struct A { bytes32 B; } - + function F() public view returns (A[] memory a, uint256[] memory c, bool[] memory d) { A[] memory a = new A[](2); a[0].B = bytes32(uint256(1234) << 96); @@ -549,7 +549,7 @@ var bindTests = []struct { bool[] memory d; return (a, c, d); } - + function G() public view returns (A[] memory a) { A[] memory a = new A[](2); a[0].B = bytes32(uint256(1234) << 96); @@ -571,10 +571,10 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - + sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000) defer sim.Close() - + // Deploy a structs method invoker contract and execute its default method _, _, structs, err := DeployStructs(auth, sim) if err != nil { @@ -1701,13 +1701,13 @@ var bindTests = []struct { `NewFallbacks`, ` pragma solidity >=0.6.0 <0.7.0; - + contract NewFallbacks { event Fallback(bytes data); fallback() external { emit Fallback(msg.data); } - + event Received(address addr, uint value); receive() external payable { emit Received(msg.sender, msg.value); @@ -1719,7 +1719,7 @@ var bindTests = []struct { ` "bytes" "math/big" - + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/core/types" @@ -1728,22 +1728,22 @@ var bindTests = []struct { ` key, _ := crypto.GenerateKey() addr := crypto.PubkeyToAddress(key.PublicKey) - + sim := backends.NewSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 1000000) defer sim.Close() - + opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) _, _, c, err := DeployNewFallbacks(opts, sim) if err != nil { t.Fatalf("Failed to deploy contract: %v", err) } sim.Commit() - + // Test receive function opts.Value = big.NewInt(100) c.Receive(opts) sim.Commit() - + var gotEvent bool iter, _ := c.FilterReceived(nil) defer iter.Close() @@ -1760,14 +1760,14 @@ var bindTests = []struct { if !gotEvent { t.Fatal("Expect to receive event emitted by receive") } - + // Test fallback function gotEvent = false opts.Value = nil calldata := []byte{0x01, 0x02, 0x03} c.Fallback(opts, calldata) sim.Commit() - + iter2, _ := c.FilterFallback(nil) defer iter2.Close() for iter2.Next() { @@ -1806,7 +1806,9 @@ var bindTests = []struct { []string{"608060405234801561001057600080fd5b50610113806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806324ec1d3f14602d575b600080fd5b60336035565b005b7fb4b2ff75e30cb4317eaae16dd8a187dd89978df17565104caa6c2797caae27d460405180604001604052806001815260200160028152506040516078919060ba565b60405180910390a1565b6040820160008201516096600085018260ad565b50602082015160a7602085018260ad565b50505050565b60b48160d3565b82525050565b600060408201905060cd60008301846082565b92915050565b600081905091905056fea26469706673582212208823628796125bf9941ce4eda18da1be3cf2931b231708ab848e1bd7151c0c9a64736f6c63430008070033"}, []string{`[{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"indexed":false,"internalType":"struct Test.MyStruct","name":"s","type":"tuple"}],"name":"StructEvent","type":"event"},{"inputs":[],"name":"TestEvent","outputs":[],"stateMutability":"nonpayable","type":"function"}]`}, ` + "context" "math/big" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" @@ -1828,12 +1830,23 @@ var bindTests = []struct { } sim.Commit() - _, err = d.TestEvent(user) + tx, err := d.TestEvent(user) if err != nil { t.Fatalf("Failed to call contract %v", err) } sim.Commit() + // Wait for the transaction to be mined + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + receipt, err := bind.WaitMined(ctx, sim, tx) + if err != nil { + t.Fatalf("Failed to wait for tx to be mined: %v", err) + } + if receipt.Status != types.ReceiptStatusSuccessful { + t.Fatal("Transaction failed") + } + it, err := d.FilterStructEvent(nil) if err != nil { t.Fatalf("Failed to filter contract event %v", err) @@ -1862,7 +1875,7 @@ var bindTests = []struct { `NewErrors`, ` pragma solidity >0.8.4; - + contract NewErrors { error MyError(uint256); error MyError1(uint256); @@ -1878,7 +1891,7 @@ var bindTests = []struct { ` "context" "math/big" - + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/core/types" @@ -1892,7 +1905,7 @@ var bindTests = []struct { sim = backends.NewSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil) ) defer sim.Close() - + _, tx, contract, err := DeployNewErrors(user, sim) if err != nil { t.Fatal(err) @@ -1917,12 +1930,12 @@ var bindTests = []struct { name: `ConstructorWithStructParam`, contract: ` pragma solidity >=0.8.0 <0.9.0; - + contract ConstructorWithStructParam { struct StructType { uint256 field; } - + constructor(StructType memory st) {} } `, @@ -1951,7 +1964,7 @@ var bindTests = []struct { t.Fatalf("DeployConstructorWithStructParam() got err %v; want nil err", err) } sim.Commit() - + if _, err = bind.WaitDeployed(context.Background(), sim, tx); err != nil { t.Logf("Deployment tx: %+v", tx) t.Errorf("bind.WaitDeployed(nil, %T, ) got err %v; want nil err", sim, err) @@ -2000,7 +2013,7 @@ var bindTests = []struct { t.Fatalf("DeployNameConflict() got err %v; want nil err", err) } sim.Commit() - + if _, err = bind.WaitDeployed(context.Background(), sim, tx); err != nil { t.Logf("Deployment tx: %+v", tx) t.Errorf("bind.WaitDeployed(nil, %T, ) got err %v; want nil err", sim, err) From a9e6c8daae7aa2691e227d7a79323f306f529ffd Mon Sep 17 00:00:00 2001 From: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Wed, 2 Apr 2025 15:06:54 +0800 Subject: [PATCH 256/940] triedb/pathdb: improve perf by separating nodes map (#31306) This PR refactors the `nodeSet` structure in the path database to use separate maps for account and storage trie nodes, resulting in performance improvements. The change maintains the same API while optimizing the internal data structure. --- triedb/pathdb/nodes.go | 195 ++++++++++++++++++++++++++--------------- 1 file changed, 126 insertions(+), 69 deletions(-) diff --git a/triedb/pathdb/nodes.go b/triedb/pathdb/nodes.go index c56e38066b..f90bd0f01c 100644 --- a/triedb/pathdb/nodes.go +++ b/triedb/pathdb/nodes.go @@ -36,8 +36,9 @@ import ( // transition, typically corresponding to a block execution. It can also represent // the combined trie node set from several aggregated state transitions. type nodeSet struct { - size uint64 // aggregated size of the trie node - nodes map[common.Hash]map[string]*trienode.Node // node set, mapped by owner and path + size uint64 // aggregated size of the trie node + accountNodes map[string]*trienode.Node // account trie nodes, mapped by path + storageNodes map[common.Hash]map[string]*trienode.Node // storage trie nodes, mapped by owner and path } // newNodeSet constructs the set with the provided dirty trie nodes. @@ -46,7 +47,17 @@ func newNodeSet(nodes map[common.Hash]map[string]*trienode.Node) *nodeSet { if nodes == nil { nodes = make(map[common.Hash]map[string]*trienode.Node) } - s := &nodeSet{nodes: nodes} + s := &nodeSet{ + accountNodes: make(map[string]*trienode.Node), + storageNodes: make(map[common.Hash]map[string]*trienode.Node), + } + for owner, subset := range nodes { + if owner == (common.Hash{}) { + s.accountNodes = subset + } else { + s.storageNodes[owner] = subset + } + } s.computeSize() return s } @@ -54,13 +65,12 @@ func newNodeSet(nodes map[common.Hash]map[string]*trienode.Node) *nodeSet { // computeSize calculates the database size of the held trie nodes. func (s *nodeSet) computeSize() { var size uint64 - for owner, subset := range s.nodes { - var prefix int - if owner != (common.Hash{}) { - prefix = common.HashLength // owner (32 bytes) for storage trie nodes - } + for path, n := range s.accountNodes { + size += uint64(len(n.Blob) + len(path)) + } + for _, subset := range s.storageNodes { for path, n := range subset { - size += uint64(prefix + len(n.Blob) + len(path)) + size += uint64(common.HashLength + len(n.Blob) + len(path)) } } s.size = size @@ -79,15 +89,18 @@ func (s *nodeSet) updateSize(delta int64) { // node retrieves the trie node with node path and its trie identifier. func (s *nodeSet) node(owner common.Hash, path []byte) (*trienode.Node, bool) { - subset, ok := s.nodes[owner] + // Account trie node + if owner == (common.Hash{}) { + n, ok := s.accountNodes[string(path)] + return n, ok + } + // Storage trie node + subset, ok := s.storageNodes[owner] if !ok { return nil, false } n, ok := subset[string(path)] - if !ok { - return nil, false - } - return n, true + return n, ok } // merge integrates the provided dirty nodes into the set. The provided nodeset @@ -97,15 +110,24 @@ func (s *nodeSet) merge(set *nodeSet) { delta int64 // size difference resulting from node merging overwrite counter // counter of nodes being overwritten ) - for owner, subset := range set.nodes { - var prefix int - if owner != (common.Hash{}) { - prefix = common.HashLength + + // Merge account nodes + for path, n := range set.accountNodes { + if orig, exist := s.accountNodes[path]; !exist { + delta += int64(len(n.Blob) + len(path)) + } else { + delta += int64(len(n.Blob) - len(orig.Blob)) + overwrite.add(len(orig.Blob) + len(path)) } - current, exist := s.nodes[owner] + s.accountNodes[path] = n + } + + // Merge storage nodes + for owner, subset := range set.storageNodes { + current, exist := s.storageNodes[owner] if !exist { for path, n := range subset { - delta += int64(prefix + len(n.Blob) + len(path)) + delta += int64(common.HashLength + len(n.Blob) + len(path)) } // Perform a shallow copy of the map for the subset instead of claiming it // directly from the provided nodeset to avoid potential concurrent map @@ -113,19 +135,19 @@ func (s *nodeSet) merge(set *nodeSet) { // accessible even after merging. Therefore, ownership of the nodes map // should still belong to the original layer, and any modifications to it // should be prevented. - s.nodes[owner] = maps.Clone(subset) + s.storageNodes[owner] = maps.Clone(subset) continue } for path, n := range subset { if orig, exist := current[path]; !exist { - delta += int64(prefix + len(n.Blob) + len(path)) + delta += int64(common.HashLength + len(n.Blob) + len(path)) } else { delta += int64(len(n.Blob) - len(orig.Blob)) - overwrite.add(prefix + len(orig.Blob) + len(path)) + overwrite.add(common.HashLength + len(orig.Blob) + len(path)) } current[path] = n } - s.nodes[owner] = current + s.storageNodes[owner] = current } overwrite.report(gcTrieNodeMeter, gcTrieNodeBytesMeter) s.updateSize(delta) @@ -136,34 +158,38 @@ func (s *nodeSet) merge(set *nodeSet) { func (s *nodeSet) revertTo(db ethdb.KeyValueReader, nodes map[common.Hash]map[string]*trienode.Node) { var delta int64 for owner, subset := range nodes { - current, ok := s.nodes[owner] - if !ok { - panic(fmt.Sprintf("non-existent subset (%x)", owner)) - } - for path, n := range subset { - orig, ok := current[path] - if !ok { - // There is a special case in merkle tree that one child is removed - // from a fullNode which only has two children, and then a new child - // with different position is immediately inserted into the fullNode. - // In this case, the clean child of the fullNode will also be marked - // as dirty because of node collapse and expansion. In case of database - // rollback, don't panic if this "clean" node occurs which is not - // present in buffer. - var blob []byte - if owner == (common.Hash{}) { - blob = rawdb.ReadAccountTrieNode(db, []byte(path)) - } else { - blob = rawdb.ReadStorageTrieNode(db, owner, []byte(path)) + if owner == (common.Hash{}) { + // Account trie nodes + for path, n := range subset { + orig, ok := s.accountNodes[path] + if !ok { + blob := rawdb.ReadAccountTrieNode(db, []byte(path)) + if bytes.Equal(blob, n.Blob) { + continue + } + panic(fmt.Sprintf("non-existent account node (%v) blob: %v", path, crypto.Keccak256Hash(n.Blob).Hex())) } - // Ignore the clean node in the case described above. - if bytes.Equal(blob, n.Blob) { - continue - } - panic(fmt.Sprintf("non-existent node (%x %v) blob: %v", owner, path, crypto.Keccak256Hash(n.Blob).Hex())) + s.accountNodes[path] = n + delta += int64(len(n.Blob)) - int64(len(orig.Blob)) + } + } else { + // Storage trie nodes + current, ok := s.storageNodes[owner] + if !ok { + panic(fmt.Sprintf("non-existent subset (%x)", owner)) + } + for path, n := range subset { + orig, ok := current[path] + if !ok { + blob := rawdb.ReadStorageTrieNode(db, owner, []byte(path)) + if bytes.Equal(blob, n.Blob) { + continue + } + panic(fmt.Sprintf("non-existent storage node (%x %v) blob: %v", owner, path, crypto.Keccak256Hash(n.Blob).Hex())) + } + current[path] = n + delta += int64(len(n.Blob)) - int64(len(orig.Blob)) } - current[path] = n - delta += int64(len(n.Blob)) - int64(len(orig.Blob)) } } s.updateSize(delta) @@ -184,8 +210,21 @@ type journalNodes struct { // encode serializes the content of trie nodes into the provided writer. func (s *nodeSet) encode(w io.Writer) error { - nodes := make([]journalNodes, 0, len(s.nodes)) - for owner, subset := range s.nodes { + nodes := make([]journalNodes, 0, len(s.storageNodes)+1) + + // Encode account nodes + if len(s.accountNodes) > 0 { + entry := journalNodes{Owner: common.Hash{}} + for path, node := range s.accountNodes { + entry.Nodes = append(entry.Nodes, journalNode{ + Path: []byte(path), + Blob: node.Blob, + }) + } + nodes = append(nodes, entry) + } + // Encode storage nodes + for owner, subset := range s.storageNodes { entry := journalNodes{Owner: owner} for path, node := range subset { entry.Nodes = append(entry.Nodes, journalNode{ @@ -204,43 +243,61 @@ func (s *nodeSet) decode(r *rlp.Stream) error { if err := r.Decode(&encoded); err != nil { return fmt.Errorf("load nodes: %v", err) } - nodes := make(map[common.Hash]map[string]*trienode.Node) + s.accountNodes = make(map[string]*trienode.Node) + s.storageNodes = make(map[common.Hash]map[string]*trienode.Node) + for _, entry := range encoded { - subset := make(map[string]*trienode.Node) - for _, n := range entry.Nodes { - if len(n.Blob) > 0 { - subset[string(n.Path)] = trienode.New(crypto.Keccak256Hash(n.Blob), n.Blob) - } else { - subset[string(n.Path)] = trienode.NewDeleted() + if entry.Owner == (common.Hash{}) { + // Account nodes + for _, n := range entry.Nodes { + if len(n.Blob) > 0 { + s.accountNodes[string(n.Path)] = trienode.New(crypto.Keccak256Hash(n.Blob), n.Blob) + } else { + s.accountNodes[string(n.Path)] = trienode.NewDeleted() + } } + } else { + // Storage nodes + subset := make(map[string]*trienode.Node) + for _, n := range entry.Nodes { + if len(n.Blob) > 0 { + subset[string(n.Path)] = trienode.New(crypto.Keccak256Hash(n.Blob), n.Blob) + } else { + subset[string(n.Path)] = trienode.NewDeleted() + } + } + s.storageNodes[entry.Owner] = subset } - nodes[entry.Owner] = subset } - s.nodes = nodes s.computeSize() return nil } // write flushes nodes into the provided database batch as a whole. func (s *nodeSet) write(batch ethdb.Batch, clean *fastcache.Cache) int { - return writeNodes(batch, s.nodes, clean) + nodes := make(map[common.Hash]map[string]*trienode.Node) + if len(s.accountNodes) > 0 { + nodes[common.Hash{}] = s.accountNodes + } + for owner, subset := range s.storageNodes { + nodes[owner] = subset + } + return writeNodes(batch, nodes, clean) } // reset clears all cached trie node data. func (s *nodeSet) reset() { - s.nodes = make(map[common.Hash]map[string]*trienode.Node) + s.accountNodes = make(map[string]*trienode.Node) + s.storageNodes = make(map[common.Hash]map[string]*trienode.Node) s.size = 0 } // dbsize returns the approximate size of db write. func (s *nodeSet) dbsize() int { var m int - for owner, nodes := range s.nodes { - if owner == (common.Hash{}) { - m += len(nodes) * len(rawdb.TrieNodeAccountPrefix) // database key prefix - } else { - m += len(nodes) * (len(rawdb.TrieNodeStoragePrefix)) // database key prefix - } + m += len(s.accountNodes) * len(rawdb.TrieNodeAccountPrefix) // database key prefix + for _, nodes := range s.storageNodes { + m += len(nodes) * (len(rawdb.TrieNodeStoragePrefix)) // database key prefix } return m + int(s.size) } From ee30681a8d4d176a3561db20e9c8867dafe97441 Mon Sep 17 00:00:00 2001 From: minh-bq Date: Wed, 2 Apr 2025 14:47:56 +0700 Subject: [PATCH 257/940] core/txpool: add GetMetadata to transaction pool (#31433) This is an alternative to #31309 With eth/68, transaction announcement must have transaction type and size. So in announceTransactions, we need to query the transaction from transaction pool with its hash. This creates overhead in case of blob transaction which needs to load data from billy and RLP decode. This commit creates a lightweight lookup from transaction hash to transaction size and a function GetMetadata to query transaction type and transaction size given the transaction hash. --------- Co-authored-by: Gary Rong --- core/txpool/blobpool/blobpool.go | 81 ++++++++++++++++---------- core/txpool/blobpool/blobpool_test.go | 12 +++- core/txpool/blobpool/evictheap_test.go | 8 +-- core/txpool/blobpool/lookup.go | 35 ++++++++--- core/txpool/legacypool/legacypool.go | 13 +++++ core/txpool/subpool.go | 10 ++++ core/txpool/txpool.go | 11 ++++ eth/handler.go | 4 ++ eth/handler_test.go | 16 +++++ eth/protocols/eth/broadcast.go | 6 +- eth/protocols/eth/handler.go | 5 ++ 11 files changed, 156 insertions(+), 45 deletions(-) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 59a5645040..5a20c3ce5a 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -87,8 +87,9 @@ type blobTxMeta struct { hash common.Hash // Transaction hash to maintain the lookup table vhashes []common.Hash // Blob versioned hashes to maintain the lookup table - id uint64 // Storage ID in the pool's persistent store - size uint32 // Byte size in the pool's persistent store + id uint64 // Storage ID in the pool's persistent store + storageSize uint32 // Byte size in the pool's persistent store + size uint64 // RLP-encoded size of transaction including the attached blob nonce uint64 // Needed to prioritize inclusion order within an account costCap *uint256.Int // Needed to validate cumulative balance sufficiency @@ -108,19 +109,20 @@ type blobTxMeta struct { // newBlobTxMeta retrieves the indexed metadata fields from a blob transaction // and assembles a helper struct to track in memory. -func newBlobTxMeta(id uint64, size uint32, tx *types.Transaction) *blobTxMeta { +func newBlobTxMeta(id uint64, size uint64, storageSize uint32, tx *types.Transaction) *blobTxMeta { meta := &blobTxMeta{ - hash: tx.Hash(), - vhashes: tx.BlobHashes(), - id: id, - size: size, - nonce: tx.Nonce(), - costCap: uint256.MustFromBig(tx.Cost()), - execTipCap: uint256.MustFromBig(tx.GasTipCap()), - execFeeCap: uint256.MustFromBig(tx.GasFeeCap()), - blobFeeCap: uint256.MustFromBig(tx.BlobGasFeeCap()), - execGas: tx.Gas(), - blobGas: tx.BlobGas(), + hash: tx.Hash(), + vhashes: tx.BlobHashes(), + id: id, + storageSize: storageSize, + size: size, + nonce: tx.Nonce(), + costCap: uint256.MustFromBig(tx.Cost()), + execTipCap: uint256.MustFromBig(tx.GasTipCap()), + execFeeCap: uint256.MustFromBig(tx.GasFeeCap()), + blobFeeCap: uint256.MustFromBig(tx.BlobGasFeeCap()), + execGas: tx.Gas(), + blobGas: tx.BlobGas(), } meta.basefeeJumps = dynamicFeeJumps(meta.execFeeCap) meta.blobfeeJumps = dynamicFeeJumps(meta.blobFeeCap) @@ -480,7 +482,7 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error { return errors.New("missing blob sidecar") } - meta := newBlobTxMeta(id, size, tx) + meta := newBlobTxMeta(id, tx.Size(), size, tx) if p.lookup.exists(meta.hash) { // This path is only possible after a crash, where deleted items are not // removed via the normal shutdown-startup procedure and thus may get @@ -507,7 +509,7 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error { p.spent[sender] = new(uint256.Int).Add(p.spent[sender], meta.costCap) p.lookup.track(meta) - p.stored += uint64(meta.size) + p.stored += uint64(meta.storageSize) return nil } @@ -539,7 +541,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 ids = append(ids, txs[i].id) nonces = append(nonces, txs[i].nonce) - p.stored -= uint64(txs[i].size) + p.stored -= uint64(txs[i].storageSize) p.lookup.untrack(txs[i]) // Included transactions blobs need to be moved to the limbo @@ -580,7 +582,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 nonces = append(nonces, txs[0].nonce) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[0].costCap) - p.stored -= uint64(txs[0].size) + p.stored -= uint64(txs[0].storageSize) p.lookup.untrack(txs[0]) // Included transactions blobs need to be moved to the limbo @@ -636,7 +638,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 dropRepeatedMeter.Mark(1) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[i].costCap) - p.stored -= uint64(txs[i].size) + p.stored -= uint64(txs[i].storageSize) p.lookup.untrack(txs[i]) if err := p.store.Delete(id); err != nil { @@ -658,7 +660,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 nonces = append(nonces, txs[j].nonce) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[j].costCap) - p.stored -= uint64(txs[j].size) + p.stored -= uint64(txs[j].storageSize) p.lookup.untrack(txs[j]) } txs = txs[:i] @@ -696,7 +698,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 nonces = append(nonces, last.nonce) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], last.costCap) - p.stored -= uint64(last.size) + p.stored -= uint64(last.storageSize) p.lookup.untrack(last) } if len(txs) == 0 { @@ -736,7 +738,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 nonces = append(nonces, last.nonce) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], last.costCap) - p.stored -= uint64(last.size) + p.stored -= uint64(last.storageSize) p.lookup.untrack(last) } p.index[addr] = txs @@ -1002,7 +1004,7 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error { } // Update the indices and metrics - meta := newBlobTxMeta(id, p.store.Size(id), tx) + meta := newBlobTxMeta(id, tx.Size(), p.store.Size(id), tx) if _, ok := p.index[addr]; !ok { if err := p.reserve(addr, true); err != nil { log.Warn("Failed to reserve account for blob pool", "tx", tx.Hash(), "from", addr, "err", err) @@ -1016,7 +1018,7 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error { p.spent[addr] = new(uint256.Int).Add(p.spent[addr], meta.costCap) } p.lookup.track(meta) - p.stored += uint64(meta.size) + p.stored += uint64(meta.storageSize) return nil } @@ -1041,7 +1043,7 @@ func (p *BlobPool) SetGasTip(tip *big.Int) { nonces = []uint64{tx.nonce} ) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[i].costCap) - p.stored -= uint64(tx.size) + p.stored -= uint64(tx.storageSize) p.lookup.untrack(tx) txs[i] = nil @@ -1051,7 +1053,7 @@ func (p *BlobPool) SetGasTip(tip *big.Int) { nonces = append(nonces, tx.nonce) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], tx.costCap) - p.stored -= uint64(tx.size) + p.stored -= uint64(tx.storageSize) p.lookup.untrack(tx) txs[i+1+j] = nil } @@ -1236,6 +1238,25 @@ func (p *BlobPool) GetRLP(hash common.Hash) []byte { return p.getRLP(hash) } +// GetMetadata returns the transaction type and transaction size with the +// given transaction hash. +// +// The size refers the length of the 'rlp encoding' of a blob transaction +// including the attached blobs. +func (p *BlobPool) GetMetadata(hash common.Hash) *txpool.TxMetadata { + p.lock.RLock() + defer p.lock.RUnlock() + + size, ok := p.lookup.sizeOfTx(hash) + if !ok { + return nil + } + return &txpool.TxMetadata{ + Type: types.BlobTxType, + Size: size, + } +} + // GetBlobs returns a number of blobs are proofs for the given versioned hashes. // This is a utility method for the engine API, enabling consensus clients to // retrieve blobs from the pools directly instead of the network. @@ -1375,7 +1396,7 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { if err != nil { return err } - meta := newBlobTxMeta(id, p.store.Size(id), tx) + meta := newBlobTxMeta(id, tx.Size(), p.store.Size(id), tx) var ( next = p.state.GetNonce(from) @@ -1403,7 +1424,7 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { p.lookup.untrack(prev) p.lookup.track(meta) - p.stored += uint64(meta.size) - uint64(prev.size) + p.stored += uint64(meta.storageSize) - uint64(prev.storageSize) } else { // Transaction extends previously scheduled ones p.index[from] = append(p.index[from], meta) @@ -1413,7 +1434,7 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { } p.spent[from] = new(uint256.Int).Add(p.spent[from], meta.costCap) p.lookup.track(meta) - p.stored += uint64(meta.size) + p.stored += uint64(meta.storageSize) } // Recompute the rolling eviction fields. In case of a replacement, this will // recompute all subsequent fields. In case of an append, this will only do @@ -1500,7 +1521,7 @@ func (p *BlobPool) drop() { p.index[from] = txs p.spent[from] = new(uint256.Int).Sub(p.spent[from], drop.costCap) } - p.stored -= uint64(drop.size) + p.stored -= uint64(drop.storageSize) p.lookup.untrack(drop) // Remove the transaction from the pool's eviction heap: diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index d9137cb679..b7c6cfa51e 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -376,7 +376,7 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) { var stored uint64 for _, txs := range pool.index { for _, tx := range txs { - stored += uint64(tx.size) + stored += uint64(tx.storageSize) } } if pool.stored != stored { @@ -1553,6 +1553,16 @@ func TestAdd(t *testing.T) { 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) } + if add.err == nil { + size, exist := pool.lookup.sizeOfTx(signed.Hash()) + if !exist { + t.Errorf("test %d, tx %d: failed to lookup transaction's size", i, j) + } + if size != signed.Size() { + t.Errorf("test %d, tx %d: transaction's size mismatches: have %v, want %v", + i, j, size, signed.Size()) + } + } verifyPoolInternals(t, pool) } verifyPoolInternals(t, pool) diff --git a/core/txpool/blobpool/evictheap_test.go b/core/txpool/blobpool/evictheap_test.go index e392932401..de4076e298 100644 --- a/core/txpool/blobpool/evictheap_test.go +++ b/core/txpool/blobpool/evictheap_test.go @@ -146,7 +146,7 @@ func TestPriceHeapSorting(t *testing.T) { ) index[addr] = []*blobTxMeta{{ id: uint64(j), - size: 128 * 1024, + storageSize: 128 * 1024, nonce: 0, execTipCap: execTip, execFeeCap: execFee, @@ -205,7 +205,7 @@ func benchmarkPriceHeapReinit(b *testing.B, datacap uint64) { ) index[addr] = []*blobTxMeta{{ id: uint64(i), - size: 128 * 1024, + storageSize: 128 * 1024, nonce: 0, execTipCap: execTip, execFeeCap: execFee, @@ -281,7 +281,7 @@ func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) { ) index[addr] = []*blobTxMeta{{ id: uint64(i), - size: 128 * 1024, + storageSize: 128 * 1024, nonce: 0, execTipCap: execTip, execFeeCap: execFee, @@ -312,7 +312,7 @@ func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) { ) metas[i] = &blobTxMeta{ id: uint64(int(blobs) + i), - size: 128 * 1024, + storageSize: 128 * 1024, nonce: 0, execTipCap: execTip, execFeeCap: execFee, diff --git a/core/txpool/blobpool/lookup.go b/core/txpool/blobpool/lookup.go index b5cf4d3799..7607cd487a 100644 --- a/core/txpool/blobpool/lookup.go +++ b/core/txpool/blobpool/lookup.go @@ -20,18 +20,24 @@ import ( "github.com/ethereum/go-ethereum/common" ) +type txMetadata struct { + id uint64 // the billy id of transction + size uint64 // the RLP encoded size of transaction (blobs are included) +} + // lookup maps blob versioned hashes to transaction hashes that include them, -// and transaction hashes to billy entries that include them. +// transaction hashes to billy entries that include them, transaction hashes +// to the transaction size type lookup struct { blobIndex map[common.Hash]map[common.Hash]struct{} - txIndex map[common.Hash]uint64 + txIndex map[common.Hash]*txMetadata } // newLookup creates a new index for tracking blob to tx; and tx to billy mappings. func newLookup() *lookup { return &lookup{ blobIndex: make(map[common.Hash]map[common.Hash]struct{}), - txIndex: make(map[common.Hash]uint64), + txIndex: make(map[common.Hash]*txMetadata), } } @@ -43,8 +49,11 @@ func (l *lookup) exists(txhash common.Hash) bool { // storeidOfTx returns the datastore storage item id of a transaction. func (l *lookup) storeidOfTx(txhash common.Hash) (uint64, bool) { - id, ok := l.txIndex[txhash] - return id, ok + meta, ok := l.txIndex[txhash] + if !ok { + return 0, false + } + return meta.id, true } // storeidOfBlob returns the datastore storage item id of a blob. @@ -61,6 +70,15 @@ func (l *lookup) storeidOfBlob(vhash common.Hash) (uint64, bool) { return 0, false // Weird, don't choke } +// sizeOfTx returns the RLP-encoded size of transaction +func (l *lookup) sizeOfTx(txhash common.Hash) (uint64, bool) { + meta, ok := l.txIndex[txhash] + if !ok { + return 0, false + } + return meta.size, true +} + // track inserts a new set of mappings from blob versioned hashes to transaction // hashes; and from transaction hashes to datastore storage item ids. func (l *lookup) track(tx *blobTxMeta) { @@ -71,8 +89,11 @@ func (l *lookup) track(tx *blobTxMeta) { } l.blobIndex[vhash][tx.hash] = struct{}{} // may be double mapped if a tx contains the same blob twice } - // Map the transaction hash to the datastore id - l.txIndex[tx.hash] = tx.id + // Map the transaction hash to the datastore id and RLP-encoded transaction size + l.txIndex[tx.hash] = &txMetadata{ + id: tx.id, + size: tx.size, + } } // untrack removes a set of mappings from blob versioned hashes to transaction diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index dafd185836..9066f3e16b 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1035,6 +1035,19 @@ func (pool *LegacyPool) GetRLP(hash common.Hash) []byte { return encoded } +// GetMetadata returns the transaction type and transaction size with the +// given transaction hash. +func (pool *LegacyPool) GetMetadata(hash common.Hash) *txpool.TxMetadata { + tx := pool.all.Get(hash) + if tx == nil { + return nil + } + return &txpool.TxMetadata{ + Type: tx.Type(), + Size: tx.Size(), + } +} + // GetBlobs is not supported by the legacy transaction pool, it is just here to // implement the txpool.SubPool interface. func (pool *LegacyPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) { diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 1392cfb274..f5cb852d8f 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -86,6 +86,12 @@ type PendingFilter struct { OnlyBlobTxs bool // Return only blob transactions (block blob-space filling) } +// TxMetadata denotes the metadata of a transaction. +type TxMetadata struct { + Type uint8 // The type of the transaction + Size uint64 // The length of the 'rlp encoding' of a transaction +} + // SubPool represents a specialized transaction pool that lives on its own (e.g. // blob pool). Since independent of how many specialized pools we have, they do // need to be updated in lockstep and assemble into one coherent view for block @@ -127,6 +133,10 @@ type SubPool interface { // GetRLP returns a RLP-encoded transaction if it is contained in the pool. GetRLP(hash common.Hash) []byte + // GetMetadata returns the transaction type and transaction size with the + // given transaction hash. + GetMetadata(hash common.Hash) *TxMetadata + // GetBlobs returns a number of blobs are proofs for the given versioned hashes. // This is a utility method for the engine API, enabling consensus clients to // retrieve blobs from the pools directly instead of the network. diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 649c5d1a78..083aac92c6 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -354,6 +354,17 @@ func (p *TxPool) GetRLP(hash common.Hash) []byte { return nil } +// GetMetadata returns the transaction type and transaction size with the given +// hash. +func (p *TxPool) GetMetadata(hash common.Hash) *TxMetadata { + for _, subpool := range p.subpools { + if meta := subpool.GetMetadata(hash); meta != nil { + return meta + } + } + return nil +} + // GetBlobs returns a number of blobs are proofs for the given versioned hashes. // This is a utility method for the engine API, enabling consensus clients to // retrieve blobs from the pools directly instead of the network. diff --git a/eth/handler.go b/eth/handler.go index 7179c9980b..b2ad6effdb 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -71,6 +71,10 @@ type txPool interface { // with given tx hash. GetRLP(hash common.Hash) []byte + // GetMetadata returns the transaction type and transaction size with the + // given transaction hash. + GetMetadata(hash common.Hash) *txpool.TxMetadata + // Add should add the given transactions to the pool. Add(txs []*types.Transaction, sync bool) []error diff --git a/eth/handler_test.go b/eth/handler_test.go index 0c6b9854e6..fb3103f241 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -93,6 +93,22 @@ func (p *testTxPool) GetRLP(hash common.Hash) []byte { return nil } +// GetMetadata returns the transaction type and transaction size with the given +// hash. +func (p *testTxPool) GetMetadata(hash common.Hash) *txpool.TxMetadata { + p.lock.Lock() + defer p.lock.Unlock() + + tx := p.pool[hash] + if tx != nil { + return &txpool.TxMetadata{ + Type: tx.Type(), + Size: tx.Size(), + } + } + return nil +} + // Add appends a batch of transactions to the pool, and notifies any // listeners if the addition channel is non nil func (p *testTxPool) Add(txs []*types.Transaction, sync bool) []error { diff --git a/eth/protocols/eth/broadcast.go b/eth/protocols/eth/broadcast.go index f0ed1d6bc9..21cea0d4ef 100644 --- a/eth/protocols/eth/broadcast.go +++ b/eth/protocols/eth/broadcast.go @@ -116,10 +116,10 @@ func (p *Peer) announceTransactions() { size common.StorageSize ) for count = 0; count < len(queue) && size < maxTxPacketSize; count++ { - if tx := p.txpool.Get(queue[count]); tx != nil { + if meta := p.txpool.GetMetadata(queue[count]); meta != nil { pending = append(pending, queue[count]) - pendingTypes = append(pendingTypes, tx.Type()) - pendingSizes = append(pendingSizes, uint32(tx.Size())) + pendingTypes = append(pendingTypes, meta.Type) + pendingSizes = append(pendingSizes, uint32(meta.Size)) size += common.HashLength } } diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index eca6777bd6..f2a3cb0292 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/p2p" @@ -90,6 +91,10 @@ type TxPool interface { // GetRLP retrieves the RLP-encoded transaction from the local txpool with // the given hash. GetRLP(hash common.Hash) []byte + + // GetMetadata returns the transaction type and transaction size with the + // given transaction hash. + GetMetadata(hash common.Hash) *txpool.TxMetadata } // MakeProtocols constructs the P2P protocol definitions for `eth`. From 3e4fbce034b384c99afeead6cf0f72be0a2b8f13 Mon Sep 17 00:00:00 2001 From: thinkAfCod Date: Wed, 2 Apr 2025 19:47:44 +0800 Subject: [PATCH 258/940] p2p/discover: repeat exact encoding when resending WHOAREYOU packet (#31543) When resending the WHOAREYOU packet, a new nonce and random IV should not be generated. The sent packet needs to match the previously-sent one exactly in order to make the handshake retry work. --------- Co-authored-by: Felix Lange --- p2p/discover/v5_udp_test.go | 40 +++++++++++++++++++++++---------- p2p/discover/v5wire/encoding.go | 16 +++++++++++-- p2p/discover/v5wire/msg.go | 3 +++ 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 3026dff538..606b35c4f2 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -181,29 +181,35 @@ func TestUDPv5_handshakeRepeatChallenge(t *testing.T) { nonce1 := v5wire.Nonce{1} nonce2 := v5wire.Nonce{2} nonce3 := v5wire.Nonce{3} - check := func(p *v5wire.Whoareyou, wantNonce v5wire.Nonce) { + var firstAuthTag *v5wire.Nonce + check := func(p *v5wire.Whoareyou, authTag, wantNonce v5wire.Nonce) { t.Helper() if p.Nonce != wantNonce { - t.Error("wrong nonce in WHOAREYOU:", p.Nonce, wantNonce) + t.Error("wrong nonce in WHOAREYOU:", p.Nonce, "want:", wantNonce) + } + if firstAuthTag == nil { + firstAuthTag = &authTag + } else if authTag != *firstAuthTag { + t.Error("wrong auth tag in WHOAREYOU header:", authTag, "want:", *firstAuthTag) } } // Unknown packet from unknown node. test.packetIn(&v5wire.Unknown{Nonce: nonce1}) - test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { - check(p, nonce1) + test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, authTag v5wire.Nonce) { + check(p, authTag, nonce1) }) // Second unknown packet. Here we expect the response to reference the // first unknown packet. test.packetIn(&v5wire.Unknown{Nonce: nonce2}) - test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { - check(p, nonce1) + test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, authTag v5wire.Nonce) { + check(p, authTag, nonce1) }) // Third unknown packet. This should still return the first nonce. test.packetIn(&v5wire.Unknown{Nonce: nonce3}) - test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { - check(p, nonce1) + test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, authTag v5wire.Nonce) { + check(p, authTag, nonce1) }) } @@ -766,20 +772,30 @@ type testCodecFrame struct { } func (c *testCodec) Encode(toID enode.ID, addr string, p v5wire.Packet, _ *v5wire.Whoareyou) ([]byte, v5wire.Nonce, error) { + // To match the behavior of v5wire.Codec, we return the cached encoding of + // WHOAREYOU challenges. + if wp, ok := p.(*v5wire.Whoareyou); ok && len(wp.Encoded) > 0 { + return wp.Encoded, wp.Nonce, nil + } + c.ctr++ var authTag v5wire.Nonce binary.BigEndian.PutUint64(authTag[:], c.ctr) + penc, _ := rlp.EncodeToBytes(p) + frame, err := rlp.EncodeToBytes(testCodecFrame{c.id, authTag, p.Kind(), penc}) + if err != nil { + return frame, authTag, err + } + // Store recently sent challenges. if w, ok := p.(*v5wire.Whoareyou); ok { - // Store recently sent Whoareyou challenges. + w.Nonce = authTag + w.Encoded = frame if c.sentChallenges == nil { c.sentChallenges = make(map[enode.ID]*v5wire.Whoareyou) } c.sentChallenges[toID] = w } - - penc, _ := rlp.EncodeToBytes(p) - frame, err := rlp.EncodeToBytes(testCodecFrame{c.id, authTag, p.Kind(), penc}) return frame, authTag, err } diff --git a/p2p/discover/v5wire/encoding.go b/p2p/discover/v5wire/encoding.go index e50b7cd16d..b16d14eda5 100644 --- a/p2p/discover/v5wire/encoding.go +++ b/p2p/discover/v5wire/encoding.go @@ -189,6 +189,11 @@ func (c *Codec) Encode(id enode.ID, addr string, packet Packet, challenge *Whoar ) switch { case packet.Kind() == WhoareyouPacket: + // just send the WHOAREYOU packet raw again, rather than the re-encoded challenge data + w := packet.(*Whoareyou) + if len(w.Encoded) > 0 { + return w.Encoded, w.Nonce, nil + } head, err = c.encodeWhoareyou(id, packet.(*Whoareyou)) case challenge != nil: // We have an unanswered challenge, send handshake. @@ -218,15 +223,22 @@ func (c *Codec) Encode(id enode.ID, addr string, packet Packet, challenge *Whoar // Store sent WHOAREYOU challenges. if challenge, ok := packet.(*Whoareyou); ok { challenge.ChallengeData = bytesCopy(&c.buf) + enc, err := c.EncodeRaw(id, head, msgData) + if err != nil { + return nil, Nonce{}, err + } + challenge.Encoded = bytes.Clone(enc) c.sc.storeSentHandshake(id, addr, challenge) - } else if msgData == nil { + return enc, head.Nonce, err + } + + if msgData == nil { headerData := c.buf.Bytes() msgData, err = c.encryptMessage(session, packet, &head, headerData) if err != nil { return nil, Nonce{}, err } } - enc, err := c.EncodeRaw(id, head, msgData) return enc, head.Nonce, err } diff --git a/p2p/discover/v5wire/msg.go b/p2p/discover/v5wire/msg.go index 401db2f6c5..089fd4ebdc 100644 --- a/p2p/discover/v5wire/msg.go +++ b/p2p/discover/v5wire/msg.go @@ -73,6 +73,9 @@ type ( Node *enode.Node sent mclock.AbsTime // for handshake GC. + + // Encoded is packet raw data for sending out, but should not be include in the RLP encoding. + Encoded []byte `rlp:"-"` } // PING is sent during liveness checks. From d2176f463b873567ff8982f362b843a898c429d1 Mon Sep 17 00:00:00 2001 From: thinkAfCod Date: Wed, 2 Apr 2025 20:56:21 +0800 Subject: [PATCH 259/940] p2p/discover: pass node instead of node ID to TALKREQ handler (#31075) This is for the implementation of Portal Network in the Shisui client. Their handler needs access to the node object in order to send further calls to the requesting node. This is a breaking API change but it should be fine, since there are basically no known users of TALKREQ outside of Portal network. --------- Signed-off-by: thinkAfCod Co-authored-by: Felix Lange --- p2p/discover/v5_talk.go | 14 ++++++++++---- p2p/discover/v5_udp.go | 3 +++ p2p/discover/v5_udp_test.go | 6 +++++- p2p/discover/v5wire/encoding.go | 8 ++++++-- p2p/discover/v5wire/encoding_test.go | 14 +++++++------- p2p/discover/v5wire/session.go | 16 ++++++++++++++-- 6 files changed, 45 insertions(+), 16 deletions(-) diff --git a/p2p/discover/v5_talk.go b/p2p/discover/v5_talk.go index 2246b47141..dca09870d8 100644 --- a/p2p/discover/v5_talk.go +++ b/p2p/discover/v5_talk.go @@ -39,7 +39,7 @@ const talkHandlerLaunchTimeout = 400 * time.Millisecond // Note that talk handlers are expected to come up with a response very quickly, within at // most 200ms or so. If the handler takes longer than that, the remote end may time out // and wont receive the response. -type TalkRequestHandler func(enode.ID, *net.UDPAddr, []byte) []byte +type TalkRequestHandler func(*enode.Node, *net.UDPAddr, []byte) []byte type talkSystem struct { transport *UDPv5 @@ -72,13 +72,19 @@ func (t *talkSystem) register(protocol string, handler TalkRequestHandler) { // handleRequest handles a talk request. func (t *talkSystem) handleRequest(id enode.ID, addr netip.AddrPort, req *v5wire.TalkRequest) { + n := t.transport.codec.SessionNode(id, addr.String()) + if n == nil { + // The node must be contained in the session here, since we wouldn't have + // received the request otherwise. + panic("missing node in session") + } t.mutex.Lock() handler, ok := t.handlers[req.Protocol] t.mutex.Unlock() if !ok { resp := &v5wire.TalkResponse{ReqID: req.ReqID} - t.transport.sendResponse(id, addr, resp) + t.transport.sendResponse(n.ID(), addr, resp) return } @@ -90,9 +96,9 @@ func (t *talkSystem) handleRequest(id enode.ID, addr netip.AddrPort, req *v5wire go func() { defer func() { t.slots <- struct{}{} }() udpAddr := &net.UDPAddr{IP: addr.Addr().AsSlice(), Port: int(addr.Port())} - respMessage := handler(id, udpAddr, req.Message) + respMessage := handler(n, udpAddr, req.Message) resp := &v5wire.TalkResponse{ReqID: req.ReqID, Message: respMessage} - t.transport.sendFromAnotherThread(id, addr, resp) + t.transport.sendFromAnotherThread(n.ID(), addr, resp) }() case <-timeout.C: // Couldn't get it in time, drop the request. diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 6f7c797152..9679f5c61a 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -64,6 +64,9 @@ type codecV5 interface { // CurrentChallenge returns the most recent WHOAREYOU challenge that was encoded to given node. // This will return a non-nil value if there is an active handshake attempt with the node, and nil otherwise. CurrentChallenge(id enode.ID, addr string) *v5wire.Whoareyou + + // SessionNode returns a node that has completed the handshake. + SessionNode(id enode.ID, addr string) *enode.Node } // UDPv5 is the implementation of protocol version 5. diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 606b35c4f2..3a384aab12 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -492,7 +492,7 @@ func TestUDPv5_talkHandling(t *testing.T) { defer test.close() var recvMessage []byte - test.udp.RegisterTalkHandler("test", func(id enode.ID, addr *net.UDPAddr, message []byte) []byte { + test.udp.RegisterTalkHandler("test", func(n *enode.Node, addr *net.UDPAddr, message []byte) []byte { recvMessage = message return []byte("test response") }) @@ -811,6 +811,10 @@ func (c *testCodec) Decode(input []byte, addr string) (enode.ID, *enode.Node, v5 return frame.NodeID, nil, p, nil } +func (c *testCodec) SessionNode(id enode.ID, addr string) *enode.Node { + return c.test.nodesByID[id].Node() +} + func (c *testCodec) decodeFrame(input []byte) (frame testCodecFrame, p v5wire.Packet, err error) { if err = rlp.DecodeBytes(input, &frame); err != nil { return frame, nil, fmt.Errorf("invalid frame: %v", err) diff --git a/p2p/discover/v5wire/encoding.go b/p2p/discover/v5wire/encoding.go index b16d14eda5..ec5ef8a261 100644 --- a/p2p/discover/v5wire/encoding.go +++ b/p2p/discover/v5wire/encoding.go @@ -359,7 +359,7 @@ func (c *Codec) encodeHandshakeHeader(toID enode.ID, addr string, challenge *Who } // TODO: this should happen when the first authenticated message is received - c.sc.storeNewSession(toID, addr, session) + c.sc.storeNewSession(toID, addr, session, challenge.Node) // Encode the auth header. var ( @@ -534,7 +534,7 @@ func (c *Codec) decodeHandshakeMessage(fromAddr string, head *Header, headerData } // Handshake OK, drop the challenge and store the new session keys. - c.sc.storeNewSession(auth.h.SrcID, fromAddr, session) + c.sc.storeNewSession(auth.h.SrcID, fromAddr, session, node) c.sc.deleteHandshake(auth.h.SrcID, fromAddr) return node, msg, nil } @@ -656,6 +656,10 @@ func (c *Codec) decryptMessage(input, nonce, headerData, readKey []byte) (Packet return DecodeMessage(msgdata[0], msgdata[1:]) } +func (c *Codec) SessionNode(id enode.ID, addr string) *enode.Node { + return c.sc.readNode(id, addr) +} + // checkValid performs some basic validity checks on the header. // The packetLen here is the length remaining after the static header. func (h *StaticHeader) checkValid(packetLen int, protocolID [6]byte) error { diff --git a/p2p/discover/v5wire/encoding_test.go b/p2p/discover/v5wire/encoding_test.go index df97e40e89..2304d0f132 100644 --- a/p2p/discover/v5wire/encoding_test.go +++ b/p2p/discover/v5wire/encoding_test.go @@ -166,7 +166,7 @@ func TestHandshake_rekey(t *testing.T) { readKey: []byte("BBBBBBBBBBBBBBBB"), writeKey: []byte("AAAAAAAAAAAAAAAA"), } - net.nodeA.c.sc.storeNewSession(net.nodeB.id(), net.nodeB.addr(), session) + net.nodeA.c.sc.storeNewSession(net.nodeB.id(), net.nodeB.addr(), session, net.nodeB.n()) // A -> B FINDNODE (encrypted with zero keys) findnode, authTag := net.nodeA.encode(t, net.nodeB, &Findnode{}) @@ -209,8 +209,8 @@ func TestHandshake_rekey2(t *testing.T) { readKey: []byte("CCCCCCCCCCCCCCCC"), writeKey: []byte("DDDDDDDDDDDDDDDD"), } - net.nodeA.c.sc.storeNewSession(net.nodeB.id(), net.nodeB.addr(), initKeysA) - net.nodeB.c.sc.storeNewSession(net.nodeA.id(), net.nodeA.addr(), initKeysB) + net.nodeA.c.sc.storeNewSession(net.nodeB.id(), net.nodeB.addr(), initKeysA, net.nodeB.n()) + net.nodeB.c.sc.storeNewSession(net.nodeA.id(), net.nodeA.addr(), initKeysB, net.nodeA.n()) // A -> B FINDNODE encrypted with initKeysA findnode, authTag := net.nodeA.encode(t, net.nodeB, &Findnode{Distances: []uint{3}}) @@ -362,8 +362,8 @@ func TestTestVectorsV5(t *testing.T) { ENRSeq: 2, }, prep: func(net *handshakeTest) { - net.nodeA.c.sc.storeNewSession(idB, addr, session) - net.nodeB.c.sc.storeNewSession(idA, addr, session.keysFlipped()) + net.nodeA.c.sc.storeNewSession(idB, addr, session, net.nodeB.n()) + net.nodeB.c.sc.storeNewSession(idA, addr, session.keysFlipped(), net.nodeA.n()) }, }, { @@ -499,8 +499,8 @@ func BenchmarkV5_DecodePing(b *testing.B) { readKey: []byte{233, 203, 93, 195, 86, 47, 177, 186, 227, 43, 2, 141, 244, 230, 120, 17}, writeKey: []byte{79, 145, 252, 171, 167, 216, 252, 161, 208, 190, 176, 106, 214, 39, 178, 134}, } - net.nodeA.c.sc.storeNewSession(net.nodeB.id(), net.nodeB.addr(), session) - net.nodeB.c.sc.storeNewSession(net.nodeA.id(), net.nodeA.addr(), session.keysFlipped()) + net.nodeA.c.sc.storeNewSession(net.nodeB.id(), net.nodeB.addr(), session, net.nodeB.n()) + net.nodeB.c.sc.storeNewSession(net.nodeA.id(), net.nodeA.addr(), session.keysFlipped(), net.nodeA.n()) addrB := net.nodeA.addr() ping := &Ping{ReqID: []byte("reqid"), ENRSeq: 5} enc, _, err := net.nodeA.c.Encode(net.nodeB.id(), addrB, ping, nil) diff --git a/p2p/discover/v5wire/session.go b/p2p/discover/v5wire/session.go index 862c21fcee..5a2166b143 100644 --- a/p2p/discover/v5wire/session.go +++ b/p2p/discover/v5wire/session.go @@ -54,11 +54,12 @@ type session struct { writeKey []byte readKey []byte nonceCounter uint32 + node *enode.Node } // keysFlipped returns a copy of s with the read and write keys flipped. func (s *session) keysFlipped() *session { - return &session{s.readKey, s.writeKey, s.nonceCounter} + return &session{s.readKey, s.writeKey, s.nonceCounter, s.node} } func NewSessionCache(maxItems int, clock mclock.Clock) *SessionCache { @@ -103,8 +104,19 @@ func (sc *SessionCache) readKey(id enode.ID, addr string) []byte { return nil } +func (sc *SessionCache) readNode(id enode.ID, addr string) *enode.Node { + if s := sc.session(id, addr); s != nil { + return s.node + } + return nil +} + // storeNewSession stores new encryption keys in the cache. -func (sc *SessionCache) storeNewSession(id enode.ID, addr string, s *session) { +func (sc *SessionCache) storeNewSession(id enode.ID, addr string, s *session, n *enode.Node) { + if n == nil { + panic("nil node in storeNewSession") + } + s.node = n sc.sessions.Add(sessionID{id, addr}, s) } From 82f01f9f24192f85de0019c1778ea239af701a41 Mon Sep 17 00:00:00 2001 From: owen <158327443+owenzimmew06@users.noreply.github.com> Date: Wed, 2 Apr 2025 20:19:25 +0300 Subject: [PATCH 260/940] README: fixup typos (#31540) Fixes a few typos in readme. --- cmd/clef/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/clef/README.md b/cmd/clef/README.md index a73ffd5b45..d23e70a3d4 100644 --- a/cmd/clef/README.md +++ b/cmd/clef/README.md @@ -1,6 +1,6 @@ # Clef -Clef can be used to sign transactions and data and is meant as a(n eventual) replacement for Geth's account management. This allows DApps to not depend on Geth's account management. When a DApp wants to sign data (or a transaction), it can send the content to Clef, which will then provide the user with context and asks for permission to sign the content. If the users grants the signing request, Clef will send the signature back to the DApp. +Clef can be used to sign transactions and data and is meant as a(n eventual) replacement for Geth's account management. This allows DApps to not depend on Geth's account management. When a DApp wants to sign data (or a transaction), it can send the content to Clef, which will then provide the user with context and ask for permission to sign the content. If the user grants the signing request, Clef will send the signature back to the DApp. This setup allows a DApp to connect to a remote Ethereum node and send transactions that are locally signed. This can help in situations when a DApp is connected to an untrusted remote Ethereum node, because a local one is not available, not synchronized with the chain, or is a node that has no built-in (or limited) account management. @@ -123,7 +123,7 @@ The External API is **untrusted**: it does not accept credentials, nor does it e Clef has one native console-based UI, for operation without any standalone tools. However, there is also an API to communicate with an external UI. To enable that UI, the signer needs to be executed with the `--stdio-ui` option, which allocates `stdin` / `stdout` for the UI API. -An example (insecure) proof-of-concept of has been implemented in `pythonsigner.py`. +An example (insecure) proof-of-concept has been implemented in `pythonsigner.py`. The model is as follows: @@ -335,7 +335,7 @@ Bash example: #### Arguments - content type [string]: type of signed data - - `text/validator`: hex data with custom validator defined in a contract + - `text/validator`: hex data with a custom validator defined in a contract - `application/clique`: [clique](https://github.com/ethereum/EIPs/issues/225) headers - `text/plain`: simple hex data validated by `account_ecRecover` - account [address]: account to sign with From e6098437a6b15c74ef5eb80ca0b99d38d2dd23d6 Mon Sep 17 00:00:00 2001 From: "fuder.eth" <139509124+vtjl10@users.noreply.github.com> Date: Wed, 2 Apr 2025 22:52:40 +0300 Subject: [PATCH 261/940] all: fix typos in docs and comments (#31548) Co-authored-by: lightclient --- cmd/clef/rules.md | 2 +- cmd/evm/README.md | 2 +- cmd/evm/eest.go | 2 +- eth/downloader/skeleton.go | 2 +- internal/guide/guide_test.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/clef/rules.md b/cmd/clef/rules.md index 3cd1bb52c6..ef89ec00c8 100644 --- a/cmd/clef/rules.md +++ b/cmd/clef/rules.md @@ -2,7 +2,7 @@ The `signer` binary contains a ruleset engine, implemented with [OttoVM](https://github.com/robertkrimen/otto) -It enables usecases like the following: +It enables use cases like the following: * I want to auto-approve transactions with contract `CasinoDapp`, with up to `0.05 ether` in value to maximum `1 ether` per 24h period * I want to auto-approve transaction to contract `EthAlarmClock` with `data`=`0xdeadbeef`, if `value=0`, `gas < 44k` and `gasPrice < 40Gwei` diff --git a/cmd/evm/README.md b/cmd/evm/README.md index f95b6b4d7b..17d663a50c 100644 --- a/cmd/evm/README.md +++ b/cmd/evm/README.md @@ -16,7 +16,7 @@ which can 1. Take a prestate, including - Accounts, - Block context information, - - Previous blockshashes (*optional) + - Previous block hashes (*optional) 2. Apply a set of transactions, 3. Apply a mining-reward (*optional), 4. And generate a post-state, including diff --git a/cmd/evm/eest.go b/cmd/evm/eest.go index 43071a3e5d..4cda2fc517 100644 --- a/cmd/evm/eest.go +++ b/cmd/evm/eest.go @@ -22,7 +22,7 @@ import "regexp" // within its filename by the execution spec test (EEST). type testMetadata struct { fork string - module string // which python module gnerated the test, e.g. eip7702 + module string // which python module generated the test, e.g. eip7702 file string // exact file the test came from, e.g. test_gas.py function string // func that created the test, e.g. test_valid_mcopy_operations parameters string // the name of the parameters which were used to fill the test, e.g. zero_inputs diff --git a/eth/downloader/skeleton.go b/eth/downloader/skeleton.go index 04421a2bf5..ad74dab844 100644 --- a/eth/downloader/skeleton.go +++ b/eth/downloader/skeleton.go @@ -275,7 +275,7 @@ func (s *skeleton) startup() { for { // If the sync cycle terminated or was terminated, propagate up when // higher layers request termination. There's no fancy explicit error - // signalling as the sync loop should never terminate (TM). + // signaling as the sync loop should never terminate (TM). newhead, err := s.sync(head) switch { case err == errSyncLinked: diff --git a/internal/guide/guide_test.go b/internal/guide/guide_test.go index 573898d7d0..71614c125d 100644 --- a/internal/guide/guide_test.go +++ b/internal/guide/guide_test.go @@ -15,7 +15,7 @@ // along with the go-ethereum library. If not, see . // This file contains the code snippets from the developer's guide embedded into -// Go tests. This ensures that any code published in out guides will not break +// Go tests. This ensures that any code published in our guides will not break // accidentally via some code update. If some API changes nonetheless that needs // modifying this file, please port any modification over into the developer's // guide wiki pages too! From 22c0605b68f544cbc6095c50e734eba9758ec34e Mon Sep 17 00:00:00 2001 From: antonis19 Date: Thu, 3 Apr 2025 06:35:52 +0200 Subject: [PATCH 262/940] eth/protocols/eth: improve over/underflow handling in `GetBlockHeaders` (#31522) --- eth/protocols/eth/handler_test.go | 28 ++++++++++++++++++++++++++++ eth/protocols/eth/handlers.go | 17 ++++++++++++----- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index 36f5e90c9a..bbbd888701 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -297,6 +297,34 @@ func testGetBlockHeaders(t *testing.T, protocol uint) { backend.chain.GetBlockByNumber(0).Hash(), }, }, + // Check a corner case where skipping causes overflow with reverse=false + { + &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 1}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1}, + []common.Hash{ + backend.chain.GetBlockByNumber(1).Hash(), + }, + }, + // Check a corner case where skipping causes overflow with reverse=true + { + &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 1}, Amount: 2, Reverse: true, Skip: math.MaxUint64 - 1}, + []common.Hash{ + backend.chain.GetBlockByNumber(1).Hash(), + }, + }, + // Check another corner case where skipping causes overflow with reverse=false + { + &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 1}, Amount: 2, Reverse: false, Skip: math.MaxUint64}, + []common.Hash{ + backend.chain.GetBlockByNumber(1).Hash(), + }, + }, + // Check another corner case where skipping causes overflow with reverse=true + { + &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 1}, Amount: 2, Reverse: true, Skip: math.MaxUint64}, + []common.Hash{ + backend.chain.GetBlockByNumber(1).Hash(), + }, + }, // Check a corner case where skipping overflow loops back into the chain start { &GetBlockHeadersRequest{Origin: HashOrNumber{Hash: backend.chain.GetBlockByNumber(3).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1}, diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go index ab56be7ffc..fda650da1c 100644 --- a/eth/protocols/eth/handlers.go +++ b/eth/protocols/eth/handlers.go @@ -128,15 +128,22 @@ func serviceNonContiguousBlockHeaderQuery(chain *core.BlockChain, query *GetBloc } case query.Reverse: // Number based traversal towards the genesis block - if query.Origin.Number >= query.Skip+1 { - query.Origin.Number -= query.Skip + 1 - } else { + current := query.Origin.Number + ancestor := current - (query.Skip + 1) + if ancestor >= current { // check for underflow unknown = true + } else { + query.Origin.Number = ancestor } case !query.Reverse: - // Number based traversal towards the leaf block - query.Origin.Number += query.Skip + 1 + current := query.Origin.Number + next := current + query.Skip + 1 + if next <= current { // check for overflow + unknown = true + } else { + query.Origin.Number = next + } } } return headers From 90d44e715d4f44fdad582f458c5973b0e6463082 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 3 Apr 2025 21:16:35 +0800 Subject: [PATCH 263/940] core, eth/downloader: implement pruning mode sync (#31414) This pull request introduces new sync logic for pruning mode. The downloader will now skip insertion of block bodies and receipts before the configured history cutoff point. Originally, in snap sync, the header chain and other components (bodies and receipts) were inserted separately. However, in Proof-of-Stake, this separation is unnecessary since the sync target is already verified by the CL. To simplify the process, this pull request modifies `InsertReceiptChain` to insert headers along with block bodies and receipts together. Besides, `InsertReceiptChain` doesn't have the notion of reorg, as the common ancestor is always be found before the sync and extra side chain is truncated at the beginning if they fall in the ancient store. The stale canonical chain flags will always be rewritten by the new chain. Explicit reorg logic is no longer required in `InsertReceiptChain`. --- cmd/geth/chaincmd.go | 2 +- cmd/utils/cmd.go | 10 +- cmd/utils/history_test.go | 2 +- core/blockchain.go | 249 +++++++++++---------- core/blockchain_reader.go | 6 + core/blockchain_test.go | 341 +++++++++++++++++++---------- core/error.go | 2 - core/headerchain.go | 10 +- core/rawdb/accessors_chain.go | 24 ++ core/rawdb/accessors_chain_test.go | 42 ++++ core/txindexer.go | 3 +- eth/backend.go | 34 +-- eth/downloader/beaconsync.go | 24 +- eth/downloader/downloader.go | 144 ++++++++---- eth/downloader/metrics.go | 1 - eth/downloader/queue.go | 242 +------------------- eth/downloader/resultstore.go | 4 +- 17 files changed, 598 insertions(+), 542 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 708dd8fb7a..0c36b82af5 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -457,7 +457,7 @@ func importHistory(ctx *cli.Context) error { network = networks[0] } - if err := utils.ImportHistory(chain, db, dir, network); err != nil { + if err := utils.ImportHistory(chain, dir, network); err != nil { return err } fmt.Printf("Import done in %v\n", time.Since(start)) diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index d91d6ca5a8..d34e15ebc0 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -246,8 +246,9 @@ func readList(filename string) ([]string, error) { } // ImportHistory imports Era1 files containing historical block information, -// starting from genesis. -func ImportHistory(chain *core.BlockChain, db ethdb.Database, dir string, network string) error { +// starting from genesis. The assumption is held that the provided chain +// segment in Era1 file should all be canonical and verified. +func ImportHistory(chain *core.BlockChain, dir string, network string) error { if chain.CurrentSnapBlock().Number.BitLen() != 0 { return errors.New("history import only supported when starting from genesis") } @@ -308,11 +309,6 @@ func ImportHistory(chain *core.BlockChain, db ethdb.Database, dir string, networ if err != nil { return fmt.Errorf("error reading receipts %d: %w", it.Number(), err) } - if status, err := chain.HeaderChain().InsertHeaderChain([]*types.Header{block.Header()}, start); err != nil { - return fmt.Errorf("error inserting header %d: %w", it.Number(), err) - } else if status != core.CanonStatTy { - return fmt.Errorf("error inserting header %d, not canon: %v", it.Number(), status) - } if _, err := chain.InsertReceiptChain([]*types.Block{block}, []types.Receipts{receipts}, 2^64-1); err != nil { return fmt.Errorf("error inserting body %d: %w", it.Number(), err) } diff --git a/cmd/utils/history_test.go b/cmd/utils/history_test.go index 8654c454f9..d3c6bda1c5 100644 --- a/cmd/utils/history_test.go +++ b/cmd/utils/history_test.go @@ -171,7 +171,7 @@ func TestHistoryImportAndExport(t *testing.T) { if err != nil { t.Fatalf("unable to initialize chain: %v", err) } - if err := ImportHistory(imported, db2, dir, "mainnet"); err != nil { + if err := ImportHistory(imported, dir, "mainnet"); err != nil { t.Fatalf("failed to import chain: %v", err) } if have, want := imported.CurrentHeader(), chain.CurrentHeader(); have.Hash() != want.Hash() { diff --git a/core/blockchain.go b/core/blockchain.go index d80236c902..d56996dadb 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -24,6 +24,7 @@ import ( "math/big" "runtime" "slices" + "sort" "strings" "sync" "sync/atomic" @@ -157,7 +158,8 @@ type CacheConfig struct { // This defines the cutoff block for history expiry. // Blocks before this number may be unavailable in the chain database. - HistoryPruningCutoff uint64 + HistoryPruningCutoffNumber uint64 + HistoryPruningCutoffHash common.Hash } // triedbConfig derives the configures for trie database. @@ -262,7 +264,6 @@ type BlockChain struct { txLookupLock sync.RWMutex txLookupCache *lru.Cache[common.Hash, txLookup] - wg sync.WaitGroup quit chan struct{} // shutdown signal, closed in Stop. stopping atomic.Bool // false if chain is running, true when stopped procInterrupt atomic.Bool // interrupt signaler for block processing @@ -333,10 +334,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis bc.processor = NewStateProcessor(chainConfig, bc.hc) genesisHeader := bc.GetHeaderByNumber(0) - bc.genesisBlock = types.NewBlockWithHeader(genesisHeader) - if bc.genesisBlock == nil { + if genesisHeader == nil { return nil, ErrNoGenesis } + bc.genesisBlock = types.NewBlockWithHeader(genesisHeader) bc.currentBlock.Store(nil) bc.currentSnapBlock.Store(nil) @@ -1110,7 +1111,6 @@ func (bc *BlockChain) stopWithoutSaving() { // the mutex should become available quickly. It cannot be taken again after Close has // returned. bc.chainmu.Close() - bc.wg.Wait() } // Stop stops the blockchain service. If any imports are currently in progress @@ -1197,79 +1197,64 @@ const ( SideStatTy ) -// InsertReceiptChain attempts to complete an already existing header chain with -// transaction and receipt data. +// InsertReceiptChain inserts a batch of blocks along with their receipts into +// the database. Unlike InsertChain, this function does not verify the state root +// in the blocks. It is used exclusively for snap sync. All the inserted blocks +// will be regarded as canonical, chain reorg is not supported. +// +// The optional ancientLimit can also be specified and chain segment before that +// will be directly stored in the ancient, getting rid of the chain migration. func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts, ancientLimit uint64) (int, error) { - // We don't require the chainMu here since we want to maximize the - // concurrency of header insertion and receipt insertion. - bc.wg.Add(1) - defer bc.wg.Done() + // Verify the supplied headers before insertion without lock + var headers []*types.Header + for _, block := range blockChain { + headers = append(headers, block.Header()) - var ( - ancientBlocks, liveBlocks types.Blocks - ancientReceipts, liveReceipts []types.Receipts - ) - // Do a sanity check that the provided chain is actually ordered and linked - for i, block := range blockChain { - if i != 0 { - prev := blockChain[i-1] - if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() { - log.Error("Non contiguous receipt insert", - "number", block.Number(), "hash", block.Hash(), "parent", block.ParentHash(), - "prevnumber", prev.Number(), "prevhash", prev.Hash()) - return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", - i-1, prev.NumberU64(), prev.Hash().Bytes()[:4], - i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4]) - } - } - if block.NumberU64() <= ancientLimit { - ancientBlocks, ancientReceipts = append(ancientBlocks, block), append(ancientReceipts, receiptChain[i]) - } else { - liveBlocks, liveReceipts = append(liveBlocks, block), append(liveReceipts, receiptChain[i]) - } - - // Here we also validate that blob transactions in the block do not contain a sidecar. - // While the sidecar does not affect the block hash / tx hash, sending blobs within a block is not allowed. + // Here we also validate that blob transactions in the block do not + // contain a sidecar. While the sidecar does not affect the block hash + // or tx hash, sending blobs within a block is not allowed. for txIndex, tx := range block.Transactions() { if tx.Type() == types.BlobTxType && tx.BlobTxSidecar() != nil { return 0, fmt.Errorf("block #%d contains unexpected blob sidecar in tx at index %d", block.NumberU64(), txIndex) } } } + if n, err := bc.hc.ValidateHeaderChain(headers); err != nil { + return n, err + } + // Hold the mutation lock + if !bc.chainmu.TryLock() { + return 0, errChainStopped + } + defer bc.chainmu.Unlock() var ( stats = struct{ processed, ignored int32 }{} start = time.Now() size = int64(0) ) - - // updateHead updates the head snap sync block if the inserted blocks are better - // and returns an indicator whether the inserted blocks are canonical. - updateHead := func(head *types.Block) bool { - if !bc.chainmu.TryLock() { - return false + // updateHead updates the head header and head snap block flags. + updateHead := func(header *types.Header) error { + batch := bc.db.NewBatch() + hash := header.Hash() + rawdb.WriteHeadHeaderHash(batch, hash) + rawdb.WriteHeadFastBlockHash(batch, hash) + if err := batch.Write(); err != nil { + return err } - defer bc.chainmu.Unlock() - - // Rewind may have occurred, skip in that case. - if bc.CurrentHeader().Number.Cmp(head.Number()) >= 0 { - rawdb.WriteHeadFastBlockHash(bc.db, head.Hash()) - bc.currentSnapBlock.Store(head.Header()) - headFastBlockGauge.Update(int64(head.NumberU64())) - return true - } - return false + bc.hc.currentHeader.Store(header) + bc.currentSnapBlock.Store(header) + headHeaderGauge.Update(header.Number.Int64()) + headFastBlockGauge.Update(header.Number.Int64()) + return nil } // writeAncient writes blockchain and corresponding receipt chain into ancient store. // // this function only accepts canonical chain data. All side chain will be reverted // eventually. writeAncient := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { - first := blockChain[0] - last := blockChain[len(blockChain)-1] - - // Ensure genesis is in ancients. - if first.NumberU64() == 1 { + // Ensure genesis is in the ancient store + if blockChain[0].NumberU64() == 1 { if frozen, _ := bc.db.Ancients(); frozen == 0 { writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []types.Receipts{nil}) if err != nil { @@ -1280,12 +1265,6 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ log.Info("Wrote genesis to ancients") } } - // Before writing the blocks to the ancients, we need to ensure that - // they correspond to the what the headerchain 'expects'. - // We only check the last block/header, since it's a contiguous chain. - if !bc.HasHeader(last.Hash(), last.NumberU64()) { - return 0, fmt.Errorf("containing header #%d [%x..] unknown", last.Number(), last.Hash().Bytes()[:4]) - } // Write all chain data to ancients. writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain) if err != nil { @@ -1298,44 +1277,28 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ if err := bc.db.Sync(); err != nil { return 0, err } - // Update the current snap block because all block data is now present in DB. - previousSnapBlock := bc.CurrentSnapBlock().Number.Uint64() - if !updateHead(blockChain[len(blockChain)-1]) { - // We end up here if the header chain has reorg'ed, and the blocks/receipts - // don't match the canonical chain. - if _, err := bc.db.TruncateHead(previousSnapBlock + 1); err != nil { - log.Error("Can't truncate ancient store after failed insert", "err", err) - } - return 0, errSideChainReceipts - } - - // Delete block data from the main database. - var ( - batch = bc.db.NewBatch() - canonHashes = make(map[common.Hash]struct{}, len(blockChain)) - ) + // Write hash to number mappings + batch := bc.db.NewBatch() for _, block := range blockChain { - canonHashes[block.Hash()] = struct{}{} - if block.NumberU64() == 0 { - continue - } - rawdb.DeleteCanonicalHash(batch, block.NumberU64()) - rawdb.DeleteBlockWithoutNumber(batch, block.Hash(), block.NumberU64()) - } - // Delete side chain hash-to-number mappings. - for _, nh := range rawdb.ReadAllHashesInRange(bc.db, first.NumberU64(), last.NumberU64()) { - if _, canon := canonHashes[nh.Hash]; !canon { - rawdb.DeleteHeader(batch, nh.Hash, nh.Number) - } + rawdb.WriteHeaderNumber(batch, block.Hash(), block.NumberU64()) } if err := batch.Write(); err != nil { return 0, err } + // Update the current snap block because all block data is now present in DB. + if err := updateHead(blockChain[len(blockChain)-1].Header()); err != nil { + return 0, err + } stats.processed += int32(len(blockChain)) return 0, nil } - // writeLive writes blockchain and corresponding receipt chain into active store. + // writeLive writes the blockchain and corresponding receipt chain to the active store. + // + // Notably, in different snap sync cycles, the supplied chain may partially reorganize + // existing local chain segments (reorg around the chain tip). The reorganized part + // will be included in the provided chain segment, and stale canonical markers will be + // silently rewritten. Therefore, no explicit reorg logic is needed. writeLive := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { var ( skipPresenceCheck = false @@ -1346,10 +1309,6 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ if bc.insertStopped() { return 0, errInsertionInterrupted } - // Short circuit if the owner header is unknown - if !bc.HasHeader(block.Hash(), block.NumberU64()) { - return i, fmt.Errorf("containing header #%d [%x..] unknown", block.Number(), block.Hash().Bytes()[:4]) - } if !skipPresenceCheck { // Ignore if the entire data is already known if bc.HasBlock(block.Hash(), block.NumberU64()) { @@ -1363,7 +1322,8 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ } } // Write all the data out into the database - rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()) + rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64()) + rawdb.WriteBlock(batch, block) rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i]) // Write everything belongs to the blocks into the database. So that @@ -1387,21 +1347,27 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ return 0, err } } - updateHead(blockChain[len(blockChain)-1]) + if err := updateHead(blockChain[len(blockChain)-1].Header()); err != nil { + return 0, err + } return 0, nil } - // Write downloaded chain data and corresponding receipt chain data - if len(ancientBlocks) > 0 { - if n, err := writeAncient(ancientBlocks, ancientReceipts); err != nil { + // Split the supplied blocks into two groups, according to the + // given ancient limit. + index := sort.Search(len(blockChain), func(i int) bool { + return blockChain[i].NumberU64() >= ancientLimit + }) + if index > 0 { + if n, err := writeAncient(blockChain[:index], receiptChain[:index]); err != nil { if err == errInsertionInterrupted { return 0, nil } return n, err } } - if len(liveBlocks) > 0 { - if n, err := writeLive(liveBlocks, liveReceipts); err != nil { + if index != len(blockChain) { + if n, err := writeLive(blockChain[index:], receiptChain[index:]); err != nil { if err == errInsertionInterrupted { return 0, nil } @@ -1420,7 +1386,6 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ context = append(context, []interface{}{"ignored", stats.ignored}...) } log.Debug("Imported new block receipts", context...) - return 0, nil } @@ -2505,15 +2470,83 @@ func (bc *BlockChain) InsertHeaderChain(chain []*types.Header) (int, error) { if i, err := bc.hc.ValidateHeaderChain(chain); err != nil { return i, err } - if !bc.chainmu.TryLock() { return 0, errChainStopped } defer bc.chainmu.Unlock() + _, err := bc.hc.InsertHeaderChain(chain, start) return 0, err } +// InsertHeadersBeforeCutoff inserts the given headers into the ancient store +// as they are claimed older than the configured chain cutoff point. All the +// inserted headers are regarded as canonical and chain reorg is not supported. +func (bc *BlockChain) InsertHeadersBeforeCutoff(headers []*types.Header) (int, error) { + if len(headers) == 0 { + return 0, nil + } + // TODO(rjl493456442): Headers before the configured cutoff have already + // been verified by the hash of cutoff header. Theoretically, header validation + // could be skipped here. + if n, err := bc.hc.ValidateHeaderChain(headers); err != nil { + return n, err + } + if !bc.chainmu.TryLock() { + return 0, errChainStopped + } + defer bc.chainmu.Unlock() + + // Initialize the ancient store with genesis block if it's empty. + var ( + frozen, _ = bc.db.Ancients() + first = headers[0].Number.Uint64() + ) + if first == 1 && frozen == 0 { + _, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []types.Receipts{nil}) + if err != nil { + log.Error("Error writing genesis to ancients", "err", err) + return 0, err + } + log.Info("Wrote genesis to ancient store") + } else if frozen != first { + return 0, fmt.Errorf("headers are gapped with the ancient store, first: %d, ancient: %d", first, frozen) + } + + // Write headers to the ancient store, with block bodies and receipts set to nil + // to ensure consistency across tables in the freezer. + _, err := rawdb.WriteAncientHeaderChain(bc.db, headers) + if err != nil { + return 0, err + } + if err := bc.db.Sync(); err != nil { + return 0, err + } + // Write hash to number mappings + batch := bc.db.NewBatch() + for _, header := range headers { + rawdb.WriteHeaderNumber(batch, header.Hash(), header.Number.Uint64()) + } + // Write head header and head snap block flags + last := headers[len(headers)-1] + rawdb.WriteHeadHeaderHash(batch, last.Hash()) + rawdb.WriteHeadFastBlockHash(batch, last.Hash()) + if err := batch.Write(); err != nil { + return 0, err + } + // Truncate the useless chain segment (zero bodies and receipts) in the + // ancient store. + if _, err := bc.db.TruncateTail(last.Number.Uint64() + 1); err != nil { + return 0, err + } + // Last step update all in-memory markers + bc.hc.currentHeader.Store(last) + bc.currentSnapBlock.Store(last) + headHeaderGauge.Update(last.Number.Int64()) + headFastBlockGauge.Update(last.Number.Int64()) + return 0, nil +} + // SetBlockValidatorAndProcessorForTesting sets the current validator and processor. // This method can be used to force an invalid blockchain to be verified for tests. // This method is unsafe and should only be used before block import starts. @@ -2533,9 +2566,3 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) { func (bc *BlockChain) GetTrieFlushInterval() time.Duration { return time.Duration(bc.flushInterval.Load()) } - -// HistoryPruningCutoff returns the configured history pruning point. -// Blocks before this might not be available in the database. -func (bc *BlockChain) HistoryPruningCutoff() uint64 { - return bc.cacheConfig.HistoryPruningCutoff -} diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 415a0f5442..4114723469 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -407,6 +407,12 @@ func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) { return bc.txIndexer.txIndexProgress() } +// HistoryPruningCutoff returns the configured history pruning point. +// Blocks before this might not be available in the database. +func (bc *BlockChain) HistoryPruningCutoff() (uint64, common.Hash) { + return bc.cacheConfig.HistoryPruningCutoffNumber, bc.cacheConfig.HistoryPruningCutoffHash +} + // TrieDB retrieves the low level trie database used for data storage. func (bc *BlockChain) TrieDB() *triedb.Database { return bc.triedb diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 04dfa87b8b..8f5a64e206 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -733,13 +733,6 @@ func testFastVsFullChains(t *testing.T, scheme string) { fast, _ := NewBlockChain(fastDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer fast.Stop() - headers := make([]*types.Header, len(blocks)) - for i, block := range blocks { - headers[i] = block.Header() - } - if n, err := fast.InsertHeaderChain(headers); err != nil { - t.Fatalf("failed to insert header %d: %v", n, err) - } if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } @@ -753,9 +746,6 @@ func testFastVsFullChains(t *testing.T, scheme string) { ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer ancient.Stop() - if n, err := ancient.InsertHeaderChain(headers); err != nil { - t.Fatalf("failed to insert header %d: %v", n, err) - } if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } @@ -880,13 +870,6 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) { fast, _ := NewBlockChain(fastDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer fast.Stop() - headers := make([]*types.Header, len(blocks)) - for i, block := range blocks { - headers[i] = block.Header() - } - if n, err := fast.InsertHeaderChain(headers); err != nil { - t.Fatalf("failed to insert header %d: %v", n, err) - } if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } @@ -900,9 +883,6 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) { ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer ancient.Stop() - if n, err := ancient.InsertHeaderChain(headers); err != nil { - t.Fatalf("failed to insert header %d: %v", n, err) - } if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } @@ -916,6 +896,11 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) { // Import the chain as a light node and ensure all pointers are updated lightDb := makeDb() defer lightDb.Close() + + headers := make([]*types.Header, len(blocks)) + for i, block := range blocks { + headers[i] = block.Header() + } light, _ := NewBlockChain(lightDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) if n, err := light.InsertHeaderChain(headers); err != nil { t.Fatalf("failed to insert header %d: %v", n, err) @@ -1710,13 +1695,6 @@ func testBlockchainRecovery(t *testing.T, scheme string) { defer ancientDb.Close() ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) - headers := make([]*types.Header, len(blocks)) - for i, block := range blocks { - headers[i] = block.Header() - } - if n, err := ancient.InsertHeaderChain(headers); err != nil { - t.Fatalf("failed to insert header %d: %v", n, err) - } if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } @@ -1741,82 +1719,6 @@ func testBlockchainRecovery(t *testing.T, scheme string) { } } -// This test checks that InsertReceiptChain will roll back correctly when attempting to insert a side chain. -func TestInsertReceiptChainRollback(t *testing.T) { - testInsertReceiptChainRollback(t, rawdb.HashScheme) - testInsertReceiptChainRollback(t, rawdb.PathScheme) -} - -func testInsertReceiptChainRollback(t *testing.T, scheme string) { - // Generate forked chain. The returned BlockChain object is used to process the side chain blocks. - tmpChain, sideblocks, canonblocks, gspec, err := getLongAndShortChains(scheme) - if err != nil { - t.Fatal(err) - } - defer tmpChain.Stop() - // Get the side chain receipts. - if _, err := tmpChain.InsertChain(sideblocks); err != nil { - t.Fatal("processing side chain failed:", err) - } - t.Log("sidechain head:", tmpChain.CurrentBlock().Number, tmpChain.CurrentBlock().Hash()) - sidechainReceipts := make([]types.Receipts, len(sideblocks)) - for i, block := range sideblocks { - sidechainReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash()) - } - // Get the canon chain receipts. - if _, err := tmpChain.InsertChain(canonblocks); err != nil { - t.Fatal("processing canon chain failed:", err) - } - t.Log("canon head:", tmpChain.CurrentBlock().Number, tmpChain.CurrentBlock().Hash()) - canonReceipts := make([]types.Receipts, len(canonblocks)) - for i, block := range canonblocks { - canonReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash()) - } - - // Set up a BlockChain that uses the ancient store. - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) - if err != nil { - t.Fatalf("failed to create temp freezer db: %v", err) - } - defer ancientDb.Close() - - ancientChain, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) - defer ancientChain.Stop() - - // Import the canonical header chain. - canonHeaders := make([]*types.Header, len(canonblocks)) - for i, block := range canonblocks { - canonHeaders[i] = block.Header() - } - if _, err = ancientChain.InsertHeaderChain(canonHeaders); err != nil { - t.Fatal("can't import canon headers:", err) - } - - // Try to insert blocks/receipts of the side chain. - _, err = ancientChain.InsertReceiptChain(sideblocks, sidechainReceipts, uint64(len(sideblocks))) - if err == nil { - t.Fatal("expected error from InsertReceiptChain.") - } - if ancientChain.CurrentSnapBlock().Number.Uint64() != 0 { - t.Fatalf("failed to rollback ancient data, want %d, have %d", 0, ancientChain.CurrentSnapBlock().Number) - } - if frozen, err := ancientChain.db.Ancients(); err != nil || frozen != 1 { - t.Fatalf("failed to truncate ancient data, frozen index is %d", frozen) - } - - // Insert blocks/receipts of the canonical chain. - _, err = ancientChain.InsertReceiptChain(canonblocks, canonReceipts, uint64(len(canonblocks))) - if err != nil { - t.Fatalf("can't import canon chain receipts: %v", err) - } - if ancientChain.CurrentSnapBlock().Number.Uint64() != canonblocks[len(canonblocks)-1].NumberU64() { - t.Fatalf("failed to insert ancient recept chain after rollback") - } - if frozen, _ := ancientChain.db.Ancients(); frozen != uint64(len(canonblocks))+1 { - t.Fatalf("wrong ancients count %d", frozen) - } -} - // Tests that importing a very large side fork, which is larger than the canon chain, // but where the difficulty per block is kept low: this means that it will not // overtake the 'canon' chain until after it's passed canon by about 200 blocks. @@ -2088,14 +1990,6 @@ func testInsertKnownChainData(t *testing.T, typ string, scheme string) { } } else if typ == "receipts" { inserter = func(blocks []*types.Block, receipts []types.Receipts) error { - headers := make([]*types.Header, 0, len(blocks)) - for _, block := range blocks { - headers = append(headers, block.Header()) - } - _, err := chain.InsertHeaderChain(headers) - if err != nil { - return err - } _, err = chain.InsertReceiptChain(blocks, receipts, 0) return err } @@ -2262,14 +2156,6 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i } } else if typ == "receipts" { inserter = func(blocks []*types.Block, receipts []types.Receipts) error { - headers := make([]*types.Header, 0, len(blocks)) - for _, block := range blocks { - headers = append(headers, block.Header()) - } - i, err := chain.InsertHeaderChain(headers) - if err != nil { - return fmt.Errorf("index %d: %w", i, err) - } _, err = chain.InsertReceiptChain(blocks, receipts, 0) return err } @@ -4265,3 +4151,220 @@ func TestEIP7702(t *testing.T) { t.Fatalf("addr2 storage wrong: expected %d, got %d", fortyTwo, actual) } } + +// Tests the scenario that the synchronization target in snap sync has been changed +// with a chain reorg at the tip. In this case the reorg'd segment should be unmarked +// with canonical flags. +func TestChainReorgSnapSync(t *testing.T) { + testChainReorgSnapSync(t, 0) + testChainReorgSnapSync(t, 32) + testChainReorgSnapSync(t, gomath.MaxUint64) +} + +func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) { + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) + + // Configure and generate a sample block chain + var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000000000) + gspec = &Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{address: {Balance: funds}}, + BaseFee: big.NewInt(params.InitialBaseFee), + } + signer = types.LatestSigner(gspec.Config) + engine = beacon.New(ethash.NewFaker()) + ) + genDb, blocks, receipts := GenerateChainWithGenesis(gspec, engine, 32, func(i int, block *BlockGen) { + block.SetCoinbase(common.Address{0x00}) + + // If the block number is multiple of 3, send a few bonus transactions to the miner + if i%3 == 2 { + for j := 0; j < i%4+1; j++ { + tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key) + if err != nil { + panic(err) + } + block.AddTx(tx) + } + } + }) + chainA, receiptsA := GenerateChain(gspec.Config, blocks[len(blocks)-1], engine, genDb, 16, func(i int, gen *BlockGen) { + gen.SetCoinbase(common.Address{0: byte(0xa), 19: byte(i)}) + }) + chainB, receiptsB := GenerateChain(gspec.Config, blocks[len(blocks)-1], engine, genDb, 20, func(i int, gen *BlockGen) { + gen.SetCoinbase(common.Address{0: byte(0xb), 19: byte(i)}) + }) + + db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + defer db.Close() + + chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil) + defer chain.Stop() + + if n, err := chain.InsertReceiptChain(blocks, receipts, ancientLimit); err != nil { + t.Fatalf("failed to insert receipt %d: %v", n, err) + } + if n, err := chain.InsertReceiptChain(chainA, receiptsA, ancientLimit); err != nil { + t.Fatalf("failed to insert receipt %d: %v", n, err) + } + // If the common ancestor is below the ancient limit, rewind the chain head. + // It's aligned with the behavior in the snap sync + ancestor := blocks[len(blocks)-1].NumberU64() + if ancestor < ancientLimit { + rawdb.WriteLastPivotNumber(db, ancestor) + chain.SetHead(ancestor) + } + if n, err := chain.InsertReceiptChain(chainB, receiptsB, ancientLimit); err != nil { + t.Fatalf("failed to insert receipt %d: %v", n, err) + } + head := chain.CurrentSnapBlock() + if head.Hash() != chainB[len(chainB)-1].Hash() { + t.Errorf("head snap block #%d: header mismatch: want: %v, got: %v", head.Number, chainB[len(chainB)-1].Hash(), head.Hash()) + } + + // Iterate over all chain data components, and cross reference + for i := 0; i < len(blocks); i++ { + num, hash := blocks[i].NumberU64(), blocks[i].Hash() + header := chain.GetHeaderByNumber(num) + if header.Hash() != hash { + t.Errorf("block #%d: header mismatch: want: %v, got: %v", num, hash, header.Hash()) + } + } + for i := 0; i < len(chainA); i++ { + num, hash := chainA[i].NumberU64(), chainA[i].Hash() + header := chain.GetHeaderByNumber(num) + if header == nil { + continue + } + if header.Hash() == hash { + t.Errorf("block #%d: unexpected canonical header: %v", num, hash) + } + } + for i := 0; i < len(chainB); i++ { + num, hash := chainB[i].NumberU64(), chainB[i].Hash() + header := chain.GetHeaderByNumber(num) + if header.Hash() != hash { + t.Errorf("block #%d: header mismatch: want: %v, got: %v", num, hash, header.Hash()) + } + } +} + +// Tests the scenario that all the inserted chain segment are with the configured +// chain cutoff point. In this case the chain segment before the cutoff should +// be persisted without the receipts and bodies; chain after should be persisted +// normally. +func TestInsertChainWithCutoff(t *testing.T) { + testInsertChainWithCutoff(t, 32, 32) // cutoff = 32, ancientLimit = 32 + testInsertChainWithCutoff(t, 32, 64) // cutoff = 32, ancientLimit = 64 (entire chain in ancient) + testInsertChainWithCutoff(t, 32, 65) // cutoff = 32, ancientLimit = 65 (64 blocks in ancient, 1 block in live) +} + +func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64) { + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) + + // Configure and generate a sample block chain + var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000000000) + gspec = &Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{address: {Balance: funds}}, + BaseFee: big.NewInt(params.InitialBaseFee), + } + signer = types.LatestSigner(gspec.Config) + engine = beacon.New(ethash.NewFaker()) + ) + _, blocks, receipts := GenerateChainWithGenesis(gspec, engine, int(2*cutoff), func(i int, block *BlockGen) { + block.SetCoinbase(common.Address{0x00}) + + tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key) + if err != nil { + panic(err) + } + block.AddTx(tx) + }) + db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + defer db.Close() + + cutoffBlock := blocks[cutoff-1] + config := DefaultCacheConfigWithScheme(rawdb.PathScheme) + config.HistoryPruningCutoffNumber = cutoffBlock.NumberU64() + config.HistoryPruningCutoffHash = cutoffBlock.Hash() + + chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil) + defer chain.Stop() + + var ( + headersBefore []*types.Header + blocksAfter []*types.Block + receiptsAfter []types.Receipts + ) + for i, b := range blocks { + if b.NumberU64() < cutoffBlock.NumberU64() { + headersBefore = append(headersBefore, b.Header()) + } else { + blocksAfter = append(blocksAfter, b) + receiptsAfter = append(receiptsAfter, receipts[i]) + } + } + if n, err := chain.InsertHeadersBeforeCutoff(headersBefore); err != nil { + t.Fatalf("failed to insert headers before cutoff %d: %v", n, err) + } + if n, err := chain.InsertReceiptChain(blocksAfter, receiptsAfter, ancientLimit); err != nil { + t.Fatalf("failed to insert receipt %d: %v", n, err) + } + headSnap := chain.CurrentSnapBlock() + if headSnap.Hash() != blocks[len(blocks)-1].Hash() { + t.Errorf("head snap block #%d: header mismatch: want: %v, got: %v", headSnap.Number, blocks[len(blocks)-1].Hash(), headSnap.Hash()) + } + headHeader := chain.CurrentHeader() + if headHeader.Hash() != blocks[len(blocks)-1].Hash() { + t.Errorf("head header #%d: header mismatch: want: %v, got: %v", headHeader.Number, blocks[len(blocks)-1].Hash(), headHeader.Hash()) + } + headBlock := chain.CurrentBlock() + if headBlock.Hash() != gspec.ToBlock().Hash() { + t.Errorf("head block #%d: header mismatch: want: %v, got: %v", headBlock.Number, gspec.ToBlock().Hash(), headBlock.Hash()) + } + + // Iterate over all chain data components, and cross reference + for i := 0; i < len(blocks); i++ { + num, hash := blocks[i].NumberU64(), blocks[i].Hash() + + // Canonical headers should be visible regardless of cutoff + header := chain.GetHeaderByNumber(num) + if header.Hash() != hash { + t.Errorf("block #%d: header mismatch: want: %v, got: %v", num, hash, header.Hash()) + } + tail, err := db.Tail() + if err != nil { + t.Fatalf("Failed to get chain tail, %v", err) + } + if tail != cutoffBlock.NumberU64() { + t.Fatalf("Unexpected chain tail, want: %d, got: %d", cutoffBlock.NumberU64(), tail) + } + // Block bodies and receipts before the cutoff should be non-existent + if num < cutoffBlock.NumberU64() { + body := chain.GetBody(hash) + if body != nil { + t.Fatalf("Unexpected block body: %d, cutoff: %d", num, cutoffBlock.NumberU64()) + } + receipts := chain.GetReceiptsByHash(hash) + if receipts != nil { + t.Fatalf("Unexpected block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64()) + } + } else { + body := chain.GetBody(hash) + if body == nil || len(body.Transactions) != 1 { + t.Fatalf("Missed block body: %d, cutoff: %d", num, cutoffBlock.NumberU64()) + } + receipts := chain.GetReceiptsByHash(hash) + if receipts == nil || len(receipts) != 1 { + t.Fatalf("Missed block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64()) + } + } + } +} diff --git a/core/error.go b/core/error.go index ce3bbb7888..de95e64636 100644 --- a/core/error.go +++ b/core/error.go @@ -28,8 +28,6 @@ var ( // ErrNoGenesis is returned when there is no Genesis Block. ErrNoGenesis = errors.New("genesis not found in chain") - - errSideChainReceipts = errors.New("side blocks can't be accepted as ancient chain data") ) // List of evm-call-message pre-checking errors. All state transition messages will diff --git a/core/headerchain.go b/core/headerchain.go index cb707a152f..f7acc49bef 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -237,7 +237,8 @@ func (hc *HeaderChain) WriteHeaders(headers []*types.Header) (int, error) { } // writeHeadersAndSetHead writes a batch of block headers and applies the last -// header as the chain head if the fork choicer says it's ok to update the chain. +// header as the chain head. +// // Note: This method is not concurrent-safe with inserting blocks simultaneously // into the chain, as side effects caused by reorganisations cannot be emulated // without the real blocks. Hence, writing headers directly should only be done @@ -272,12 +273,14 @@ func (hc *HeaderChain) writeHeadersAndSetHead(headers []*types.Header) (*headerW return result, nil } +// ValidateHeaderChain verifies that the supplied header chain is contiguous +// and conforms to consensus rules. func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header) (int, error) { // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { if chain[i].Number.Uint64() != chain[i-1].Number.Uint64()+1 { - hash := chain[i].Hash() - parentHash := chain[i-1].Hash() + hash, parentHash := chain[i].Hash(), chain[i-1].Hash() + // Chain broke ancestry, log a message (programming error) and skip insertion log.Error("Non contiguous header insert", "number", chain[i].Number, "hash", hash, "parent", chain[i].ParentHash, "prevnumber", chain[i-1].Number, "prevhash", parentHash) @@ -302,7 +305,6 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header) (int, error) { return i, err } } - return 0, nil } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 020d35619e..2f62d86e4b 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -737,6 +737,30 @@ func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *type return nil } +// WriteAncientHeaderChain writes the supplied headers along with nil block +// bodies and receipts into the ancient store. It's supposed to be used for +// storing chain segment before the chain cutoff. +func WriteAncientHeaderChain(db ethdb.AncientWriter, headers []*types.Header) (int64, error) { + return db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for _, header := range headers { + num := header.Number.Uint64() + if err := op.AppendRaw(ChainFreezerHashTable, num, header.Hash().Bytes()); err != nil { + return fmt.Errorf("can't add block %d hash: %v", num, err) + } + if err := op.Append(ChainFreezerHeaderTable, num, header); err != nil { + return fmt.Errorf("can't append block header %d: %v", num, err) + } + if err := op.AppendRaw(ChainFreezerBodiesTable, num, nil); err != nil { + return fmt.Errorf("can't append block body %d: %v", num, err) + } + if err := op.AppendRaw(ChainFreezerReceiptTable, num, nil); err != nil { + return fmt.Errorf("can't append block %d receipts: %v", num, err) + } + } + return nil + }) +} + // DeleteBlock removes all block data associated with a hash. func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { DeleteReceipts(db, hash, number) diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index efd16d5fa7..247e277582 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -464,6 +464,48 @@ func TestAncientStorage(t *testing.T) { } } +func TestWriteAncientHeaderChain(t *testing.T) { + db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), t.TempDir(), "", false) + if err != nil { + t.Fatalf("failed to create database with ancient backend") + } + defer db.Close() + + // Create a test block + var headers []*types.Header + headers = append(headers, &types.Header{ + Number: big.NewInt(0), + Extra: []byte("test block"), + UncleHash: types.EmptyUncleHash, + TxHash: types.EmptyTxsHash, + ReceiptHash: types.EmptyReceiptsHash, + }) + headers = append(headers, &types.Header{ + Number: big.NewInt(1), + Extra: []byte("test block"), + UncleHash: types.EmptyUncleHash, + TxHash: types.EmptyTxsHash, + ReceiptHash: types.EmptyReceiptsHash, + }) + // Write and verify the header in the database + WriteAncientHeaderChain(db, headers) + + for _, header := range headers { + if blob := ReadHeaderRLP(db, header.Hash(), header.Number.Uint64()); len(blob) == 0 { + t.Fatalf("no header returned") + } + if h := ReadCanonicalHash(db, header.Number.Uint64()); h != header.Hash() { + t.Fatalf("no canonical hash returned") + } + if blob := ReadBodyRLP(db, header.Hash(), header.Number.Uint64()); len(blob) != 0 { + t.Fatalf("unexpected body returned") + } + if blob := ReadReceiptsRLP(db, header.Hash(), header.Number.Uint64()); len(blob) != 0 { + t.Fatalf("unexpected body returned") + } + } +} + func TestCanonicalHashIteration(t *testing.T) { var cases = []struct { from, to uint64 diff --git a/core/txindexer.go b/core/txindexer.go index d0fce302f3..31f069995b 100644 --- a/core/txindexer.go +++ b/core/txindexer.go @@ -58,9 +58,10 @@ type txIndexer struct { // newTxIndexer initializes the transaction indexer. func newTxIndexer(limit uint64, chain *BlockChain) *txIndexer { + cutoff, _ := chain.HistoryPruningCutoff() indexer := &txIndexer{ limit: limit, - cutoff: chain.HistoryPruningCutoff(), + cutoff: cutoff, db: chain.db, progress: make(chan chan TxIndexProgress), term: make(chan chan struct{}), diff --git a/eth/backend.go b/eth/backend.go index ab612b1de7..79759710b6 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -154,13 +154,18 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } // Validate history pruning configuration. - var historyPruningCutoff uint64 + var ( + cutoffNumber uint64 + cutoffHash common.Hash + ) if config.HistoryMode == ethconfig.PostMergeHistory { prunecfg, ok := ethconfig.HistoryPrunePoints[genesisHash] if !ok { return nil, fmt.Errorf("no history pruning point is defined for genesis %x", genesisHash) } - historyPruningCutoff = prunecfg.BlockNumber + cutoffNumber = prunecfg.BlockNumber + cutoffHash = prunecfg.BlockHash + log.Info("Chain cutoff configured", "number", cutoffNumber, "hash", cutoffHash) } // Set networkID to chainID by default. @@ -204,16 +209,17 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { EnablePreimageRecording: config.EnablePreimageRecording, } cacheConfig = &core.CacheConfig{ - TrieCleanLimit: config.TrieCleanCache, - TrieCleanNoPrefetch: config.NoPrefetch, - TrieDirtyLimit: config.TrieDirtyCache, - TrieDirtyDisabled: config.NoPruning, - TrieTimeLimit: config.TrieTimeout, - SnapshotLimit: config.SnapshotCache, - Preimages: config.Preimages, - StateHistory: config.StateHistory, - StateScheme: scheme, - HistoryPruningCutoff: historyPruningCutoff, + TrieCleanLimit: config.TrieCleanCache, + TrieCleanNoPrefetch: config.NoPrefetch, + TrieDirtyLimit: config.TrieDirtyCache, + TrieDirtyDisabled: config.NoPruning, + TrieTimeLimit: config.TrieTimeout, + SnapshotLimit: config.SnapshotCache, + Preimages: config.Preimages, + StateHistory: config.StateHistory, + StateScheme: scheme, + HistoryPruningCutoffNumber: cutoffNumber, + HistoryPruningCutoffHash: cutoffHash, } ) if config.VMTrace != "" { @@ -246,7 +252,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { HashScheme: scheme == rawdb.HashScheme, } chainView := eth.newChainView(eth.blockchain.CurrentBlock()) - historyCutoff := eth.blockchain.HistoryPruningCutoff() + historyCutoff, _ := eth.blockchain.HistoryPruningCutoff() var finalBlock uint64 if fb := eth.blockchain.CurrentFinalBlock(); fb != nil { finalBlock = fb.Number.Uint64() @@ -443,7 +449,7 @@ func (s *Ethereum) updateFilterMapsHeads() { if head == nil || newHead.Hash() != head.Hash() { head = newHead chainView := s.newChainView(head) - historyCutoff := s.blockchain.HistoryPruningCutoff() + historyCutoff, _ := s.blockchain.HistoryPruningCutoff() var finalBlock uint64 if fb := s.blockchain.CurrentFinalBlock(); fb != nil { finalBlock = fb.Number.Uint64() diff --git a/eth/downloader/beaconsync.go b/eth/downloader/beaconsync.go index c142ea7435..33ad0f8971 100644 --- a/eth/downloader/beaconsync.go +++ b/eth/downloader/beaconsync.go @@ -273,8 +273,7 @@ func (d *Downloader) findBeaconAncestor() (uint64, error) { // fetchHeaders feeds skeleton headers to the downloader queue for scheduling // until sync errors or is finished. func (d *Downloader) fetchHeaders(from uint64) error { - var head *types.Header - _, tail, _, err := d.skeleton.Bounds() + head, tail, _, err := d.skeleton.Bounds() if err != nil { return err } @@ -294,6 +293,27 @@ func (d *Downloader) fetchHeaders(from uint64) error { fsHeaderContCheckTimer := time.NewTimer(fsHeaderContCheck) defer fsHeaderContCheckTimer.Stop() + // Verify the header at configured chain cutoff, ensuring it's matched with + // the configured hash. Skip the check if the configured cutoff is even higher + // than the sync target, which is definitely not a common case. + if d.chainCutoffNumber != 0 && d.chainCutoffNumber >= from && d.chainCutoffNumber <= head.Number.Uint64() { + h := d.skeleton.Header(d.chainCutoffNumber) + if h == nil { + if d.chainCutoffNumber < tail.Number.Uint64() { + dist := tail.Number.Uint64() - d.chainCutoffNumber + if len(localHeaders) >= int(dist) { + h = localHeaders[dist-1] + } + } + } + if h == nil { + return fmt.Errorf("header at chain cutoff is not available, cutoff: %d", d.chainCutoffNumber) + } + if h.Hash() != d.chainCutoffHash { + return fmt.Errorf("header at chain cutoff mismatched, want: %v, got: %v", d.chainCutoffHash, h.Hash()) + } + } + for { // Some beacon headers might have appeared since the last cycle, make // sure we're always syncing to all available ones diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 3f3f9b7f0c..4d13ae304c 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -20,6 +20,7 @@ package downloader import ( "errors" "fmt" + "sort" "sync" "sync/atomic" "time" @@ -120,6 +121,12 @@ type Downloader struct { committed atomic.Bool ancientLimit uint64 // The maximum block number which can be regarded as ancient data. + // The cutoff block number and hash before which chain segments (bodies + // and receipts) are skipped during synchronization. 0 means the entire + // chain segment is aimed for synchronization. + chainCutoffNumber uint64 + chainCutoffHash common.Hash + // Channels headerProcCh chan *headerTask // Channel to feed the header processor new tasks @@ -163,9 +170,6 @@ type BlockChain interface { // CurrentHeader retrieves the head header from the local chain. CurrentHeader() *types.Header - // InsertHeaderChain inserts a batch of headers into the local chain. - InsertHeaderChain([]*types.Header) (int, error) - // SetHead rewinds the local chain to a new head. SetHead(uint64) error @@ -187,10 +191,17 @@ type BlockChain interface { // SnapSyncCommitHead directly commits the head block to a certain entity. SnapSyncCommitHead(common.Hash) error + // InsertHeadersBeforeCutoff inserts a batch of headers before the configured + // chain cutoff into the ancient store. + InsertHeadersBeforeCutoff([]*types.Header) (int, error) + // InsertChain inserts a batch of blocks into the local chain. InsertChain(types.Blocks) (int, error) - // InsertReceiptChain inserts a batch of receipts into the local chain. + // InsertReceiptChain inserts a batch of blocks along with their receipts + // into the local chain. Blocks older than the specified `ancientLimit` + // are stored directly in the ancient store, while newer blocks are stored + // in the live key-value store. InsertReceiptChain(types.Blocks, []types.Receipts, uint64) (int, error) // Snapshots returns the blockchain snapshot tree to paused it during sync. @@ -199,22 +210,29 @@ type BlockChain interface { // TrieDB retrieves the low level trie database used for interacting // with trie nodes. TrieDB() *triedb.Database + + // HistoryPruningCutoff returns the configured history pruning point. + // Block bodies along with the receipts will be skipped for synchronization. + HistoryPruningCutoff() (uint64, common.Hash) } // New creates a new downloader to fetch hashes and blocks from remote peers. func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, dropPeer peerDropFn, success func()) *Downloader { + cutoffNumber, cutoffHash := chain.HistoryPruningCutoff() dl := &Downloader{ - stateDB: stateDb, - mux: mux, - queue: newQueue(blockCacheMaxItems, blockCacheInitialItems), - peers: newPeerSet(), - blockchain: chain, - dropPeer: dropPeer, - headerProcCh: make(chan *headerTask, 1), - quitCh: make(chan struct{}), - SnapSyncer: snap.NewSyncer(stateDb, chain.TrieDB().Scheme()), - stateSyncStart: make(chan *stateSync), - syncStartBlock: chain.CurrentSnapBlock().Number.Uint64(), + stateDB: stateDb, + mux: mux, + queue: newQueue(blockCacheMaxItems, blockCacheInitialItems), + peers: newPeerSet(), + blockchain: chain, + chainCutoffNumber: cutoffNumber, + chainCutoffHash: cutoffHash, + dropPeer: dropPeer, + headerProcCh: make(chan *headerTask, 1), + quitCh: make(chan struct{}), + SnapSyncer: snap.NewSyncer(stateDb, chain.TrieDB().Scheme()), + stateSyncStart: make(chan *stateSync), + syncStartBlock: chain.CurrentSnapBlock().Number.Uint64(), } // Create the post-merge skeleton syncer and start the process dl.skeleton = newSkeleton(stateDb, dl.peers, dropPeer, newBeaconBackfiller(dl, success)) @@ -503,6 +521,12 @@ func (d *Downloader) syncToHead() (err error) { } else { d.ancientLimit = 0 } + // Extend the ancient chain segment range if the ancient limit is even + // below the pre-configured chain cutoff. + if d.chainCutoffNumber != 0 && d.chainCutoffNumber > d.ancientLimit { + d.ancientLimit = d.chainCutoffNumber + log.Info("Extend the ancient range with configured cutoff", "cutoff", d.chainCutoffNumber) + } frozen, _ := d.stateDB.Ancients() // Ignore the error here since light client can also hit here. // If a part of blockchain data has already been written into active store, @@ -521,14 +545,23 @@ func (d *Downloader) syncToHead() (err error) { log.Info("Truncated excess ancient chain segment", "oldhead", frozen-1, "newhead", origin) } } + // Skip ancient chain segments if Geth is running with a configured chain cutoff. + // These segments are not guaranteed to be available in the network. + chainOffset := origin + 1 + if mode == ethconfig.SnapSync && d.chainCutoffNumber != 0 { + if chainOffset < d.chainCutoffNumber { + chainOffset = d.chainCutoffNumber + log.Info("Skip chain segment before cutoff", "origin", origin, "cutoff", d.chainCutoffNumber) + } + } // Initiate the sync using a concurrent header and content retrieval algorithm - d.queue.Prepare(origin+1, mode) + d.queue.Prepare(chainOffset, mode) // In beacon mode, headers are served by the skeleton syncer fetchers := []func() error{ - func() error { return d.fetchHeaders(origin + 1) }, // Headers are always retrieved - func() error { return d.fetchBodies(origin + 1) }, // Bodies are retrieved during normal and snap sync - func() error { return d.fetchReceipts(origin + 1) }, // Receipts are retrieved during snap sync + func() error { return d.fetchHeaders(origin + 1) }, // Headers are always retrieved + func() error { return d.fetchBodies(chainOffset) }, // Bodies are retrieved during normal and snap sync + func() error { return d.fetchReceipts(chainOffset) }, // Receipts are retrieved during snap sync func() error { return d.processHeaders(origin + 1) }, } if mode == ethconfig.SnapSync { @@ -666,7 +699,7 @@ func (d *Downloader) processHeaders(origin uint64) error { return nil } // Otherwise split the chunk of headers into batches and process them - headers, hashes := task.headers, task.hashes + headers, hashes, scheduled := task.headers, task.hashes, false for len(headers) > 0 { // Terminate if something failed in between processing chunks @@ -683,17 +716,21 @@ func (d *Downloader) processHeaders(origin uint64) error { chunkHeaders := headers[:limit] chunkHashes := hashes[:limit] - // In case of header only syncing, validate the chunk immediately - if mode == ethconfig.SnapSync { - // Although the received headers might be all valid, a legacy - // PoW/PoA sync must not accept post-merge headers. Make sure - // that any transition is rejected at this point. - if len(chunkHeaders) > 0 { - if n, err := d.blockchain.InsertHeaderChain(chunkHeaders); err != nil { - log.Warn("Invalid header encountered", "number", chunkHeaders[n].Number, "hash", chunkHashes[n], "parent", chunkHeaders[n].ParentHash, "err", err) - return fmt.Errorf("%w: %v", errInvalidChain, err) - } + // Split the headers around the chain cutoff + var cutoff int + if mode == ethconfig.SnapSync && d.chainCutoffNumber != 0 { + cutoff = sort.Search(len(chunkHeaders), func(i int) bool { + return chunkHeaders[i].Number.Uint64() >= d.chainCutoffNumber + }) + } + // Insert the header chain into the ancient store (with block bodies and + // receipts set to nil) if they fall before the cutoff. + if mode == ethconfig.SnapSync && cutoff != 0 { + if n, err := d.blockchain.InsertHeadersBeforeCutoff(chunkHeaders[:cutoff]); err != nil { + log.Warn("Failed to insert ancient header chain", "number", chunkHeaders[n].Number, "hash", chunkHashes[n], "parent", chunkHeaders[n].ParentHash, "err", err) + return fmt.Errorf("%w: %v", errInvalidChain, err) } + log.Debug("Inserted headers before cutoff", "number", chunkHeaders[cutoff-1].Number, "hash", chunkHashes[cutoff-1]) } // If we've reached the allowed number of pending headers, stall a bit for d.queue.PendingBodies() >= maxQueuedHeaders || d.queue.PendingReceipts() >= maxQueuedHeaders { @@ -704,12 +741,21 @@ func (d *Downloader) processHeaders(origin uint64) error { case <-timer.C: } } - // Otherwise insert the headers for content retrieval - inserts := d.queue.Schedule(chunkHeaders, chunkHashes, origin) - if len(inserts) != len(chunkHeaders) { - return fmt.Errorf("%w: stale headers", errBadPeer) + // Otherwise, schedule the headers for content retrieval (block bodies and + // potentially receipts in snap sync). + // + // Skip the bodies/receipts retrieval scheduling before the cutoff in snap + // sync if chain pruning is configured. + if mode == ethconfig.SnapSync && cutoff != 0 { + chunkHeaders = chunkHeaders[cutoff:] + chunkHashes = chunkHashes[cutoff:] + } + if len(chunkHeaders) > 0 { + scheduled = true + if d.queue.Schedule(chunkHeaders, chunkHashes, origin+uint64(cutoff)) != len(chunkHeaders) { + return fmt.Errorf("%w: stale headers", errBadPeer) + } } - headers = headers[limit:] hashes = hashes[limit:] origin += uint64(limit) @@ -721,11 +767,13 @@ func (d *Downloader) processHeaders(origin uint64) error { } d.syncStatsLock.Unlock() - // Signal the content downloaders of the availability of new tasks - for _, ch := range []chan bool{d.queue.blockWakeCh, d.queue.receiptWakeCh} { - select { - case ch <- true: - default: + // Signal the downloader of the availability of new tasks + if scheduled { + for _, ch := range []chan bool{d.queue.blockWakeCh, d.queue.receiptWakeCh} { + select { + case ch <- true: + default: + } } } } @@ -1085,10 +1133,20 @@ func (d *Downloader) reportSnapSyncProgress(force bool) { header = d.blockchain.CurrentHeader() block = d.blockchain.CurrentSnapBlock() ) - syncedBlocks := block.Number.Uint64() - d.syncStartBlock - if syncedBlocks == 0 { + // Prevent reporting if nothing has been synchronized yet + if block.Number.Uint64() <= d.syncStartBlock { return } + // Prevent reporting noise if the actual chain synchronization (headers + // and bodies) hasn't started yet. Inserting the ancient header chain is + // fast enough and would introduce significant bias if included in the count. + if d.chainCutoffNumber != 0 && block.Number.Uint64() <= d.chainCutoffNumber { + return + } + fetchedBlocks := block.Number.Uint64() - d.syncStartBlock + if d.chainCutoffNumber != 0 && d.chainCutoffNumber > d.syncStartBlock { + fetchedBlocks = block.Number.Uint64() - d.chainCutoffNumber + } // Retrieve the current chain head and calculate the ETA latest, _, _, err := d.skeleton.Bounds() if err != nil { @@ -1103,7 +1161,7 @@ func (d *Downloader) reportSnapSyncProgress(force bool) { } var ( left = latest.Number.Uint64() - block.Number.Uint64() - eta = time.Since(d.syncStartTime) / time.Duration(syncedBlocks) * time.Duration(left) + eta = time.Since(d.syncStartTime) / time.Duration(fetchedBlocks) * time.Duration(left) progress = fmt.Sprintf("%.2f%%", float64(block.Number.Uint64())*100/float64(latest.Number.Uint64())) headers = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(header.Number.Uint64()), common.StorageSize(headerBytes).TerminalString()) diff --git a/eth/downloader/metrics.go b/eth/downloader/metrics.go index 23c033a8ad..bfe80ddbf1 100644 --- a/eth/downloader/metrics.go +++ b/eth/downloader/metrics.go @@ -25,7 +25,6 @@ import ( var ( headerInMeter = metrics.NewRegisteredMeter("eth/downloader/headers/in", nil) headerReqTimer = metrics.NewRegisteredTimer("eth/downloader/headers/req", nil) - headerDropMeter = metrics.NewRegisteredMeter("eth/downloader/headers/drop", nil) headerTimeoutMeter = metrics.NewRegisteredMeter("eth/downloader/headers/timeout", nil) bodyInMeter = metrics.NewRegisteredMeter("eth/downloader/bodies/in", nil) diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index a1c114f057..000ad97ca9 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -73,7 +73,7 @@ type fetchResult struct { Withdrawals types.Withdrawals } -func newFetchResult(header *types.Header, fastSync bool) *fetchResult { +func newFetchResult(header *types.Header, snapSync bool) *fetchResult { item := &fetchResult{ Header: header, } @@ -82,7 +82,7 @@ func newFetchResult(header *types.Header, fastSync bool) *fetchResult { } else if header.WithdrawalsHash != nil { item.Withdrawals = make(types.Withdrawals, 0) } - if fastSync && !header.EmptyReceipts() { + if snapSync && !header.EmptyReceipts() { item.pending.Store(item.pending.Load() | (1 << receiptType)) } return item @@ -124,19 +124,8 @@ func (f *fetchResult) Done(kind uint) bool { // queue represents hashes that are either need fetching or are being fetched type queue struct { - mode SyncMode // Synchronisation mode to decide on the block parts to schedule for fetching - - // Headers are "special", they download in batches, supported by a skeleton chain - headerHead common.Hash // Hash of the last queued header to verify order - headerTaskPool map[uint64]*types.Header // Pending header retrieval tasks, mapping starting indexes to skeleton headers - headerTaskQueue *prque.Prque[int64, uint64] // Priority queue of the skeleton indexes to fetch the filling headers for - headerPeerMiss map[string]map[uint64]struct{} // Set of per-peer header batches known to be unavailable - headerPendPool map[string]*fetchRequest // Currently pending header retrieval operations - headerResults []*types.Header // Result cache accumulating the completed headers - headerHashes []common.Hash // Result cache accumulating the completed header hashes - headerProced int // Number of headers already processed from the results - headerOffset uint64 // Number of the first header in the result cache - headerContCh chan bool // Channel to notify when header download finishes + mode SyncMode // Synchronisation mode to decide on the block parts to schedule for fetching + headerHead common.Hash // Hash of the last queued header to verify order // All data retrievals below are based on an already assembles header chain blockTaskPool map[common.Hash]*types.Header // Pending block (body) retrieval tasks, mapping hashes to headers @@ -163,7 +152,6 @@ type queue struct { func newQueue(blockCacheLimit int, thresholdInitialSize int) *queue { lock := new(sync.RWMutex) q := &queue{ - headerContCh: make(chan bool, 1), blockTaskQueue: prque.New[int64, *types.Header](nil), blockWakeCh: make(chan bool, 1), receiptTaskQueue: prque.New[int64, *types.Header](nil), @@ -182,9 +170,7 @@ func (q *queue) Reset(blockCacheLimit int, thresholdInitialSize int) { q.closed = false q.mode = ethconfig.FullSync - q.headerHead = common.Hash{} - q.headerPendPool = make(map[string]*fetchRequest) q.blockTaskPool = make(map[common.Hash]*types.Header) q.blockTaskQueue.Reset() @@ -207,14 +193,6 @@ func (q *queue) Close() { q.lock.Unlock() } -// PendingHeaders retrieves the number of header requests pending for retrieval. -func (q *queue) PendingHeaders() int { - q.lock.Lock() - defer q.lock.Unlock() - - return q.headerTaskQueue.Size() -} - // PendingBodies retrieves the number of block body requests pending for retrieval. func (q *queue) PendingBodies() int { q.lock.Lock() @@ -260,54 +238,14 @@ func (q *queue) Idle() bool { return (queued + pending) == 0 } -// ScheduleSkeleton adds a batch of header retrieval tasks to the queue to fill -// up an already retrieved header skeleton. -func (q *queue) ScheduleSkeleton(from uint64, skeleton []*types.Header) { - q.lock.Lock() - defer q.lock.Unlock() - - // No skeleton retrieval can be in progress, fail hard if so (huge implementation bug) - if q.headerResults != nil { - panic("skeleton assembly already in progress") - } - // Schedule all the header retrieval tasks for the skeleton assembly - q.headerTaskPool = make(map[uint64]*types.Header) - q.headerTaskQueue = prque.New[int64, uint64](nil) - q.headerPeerMiss = make(map[string]map[uint64]struct{}) // Reset availability to correct invalid chains - q.headerResults = make([]*types.Header, len(skeleton)*MaxHeaderFetch) - q.headerHashes = make([]common.Hash, len(skeleton)*MaxHeaderFetch) - q.headerProced = 0 - q.headerOffset = from - q.headerContCh = make(chan bool, 1) - - for i, header := range skeleton { - index := from + uint64(i*MaxHeaderFetch) - - q.headerTaskPool[index] = header - q.headerTaskQueue.Push(index, -int64(index)) - } -} - -// RetrieveHeaders retrieves the header chain assemble based on the scheduled -// skeleton. -func (q *queue) RetrieveHeaders() ([]*types.Header, []common.Hash, int) { - q.lock.Lock() - defer q.lock.Unlock() - - headers, hashes, proced := q.headerResults, q.headerHashes, q.headerProced - q.headerResults, q.headerHashes, q.headerProced = nil, nil, 0 - - return headers, hashes, proced -} - // Schedule adds a set of headers for the download queue for scheduling, returning // the new headers encountered. -func (q *queue) Schedule(headers []*types.Header, hashes []common.Hash, from uint64) []*types.Header { +func (q *queue) Schedule(headers []*types.Header, hashes []common.Hash, from uint64) int { q.lock.Lock() defer q.lock.Unlock() // Insert all the headers prioritised by the contained block number - inserts := make([]*types.Header, 0, len(headers)) + var inserts int for i, header := range headers { // Make sure chain order is honoured and preserved throughout hash := hashes[i] @@ -337,7 +275,7 @@ func (q *queue) Schedule(headers []*types.Header, hashes []common.Hash, from uin q.receiptTaskQueue.Push(header, -int64(header.Number.Uint64())) } } - inserts = append(inserts, header) + inserts++ q.headerHead = hash from++ } @@ -390,7 +328,7 @@ func (q *queue) Results(block bool) []*fetchResult { q.resultSize = common.StorageSize(blockCacheSizeWeight)*size + (1-common.StorageSize(blockCacheSizeWeight))*q.resultSize } - // Using the newly calibrated resultsize, figure out the new throttle limit + // Using the newly calibrated result size, figure out the new throttle limit // on the result cache throttleThreshold := uint64((common.StorageSize(blockCacheMemory) + q.resultSize - 1) / q.resultSize) throttleThreshold = q.resultCache.SetThrottleThreshold(throttleThreshold) @@ -428,46 +366,6 @@ func (q *queue) stats() []interface{} { } } -// ReserveHeaders reserves a set of headers for the given peer, skipping any -// previously failed batches. -func (q *queue) ReserveHeaders(p *peerConnection, count int) *fetchRequest { - q.lock.Lock() - defer q.lock.Unlock() - - // Short circuit if the peer's already downloading something (sanity check to - // not corrupt state) - if _, ok := q.headerPendPool[p.id]; ok { - return nil - } - // Retrieve a batch of hashes, skipping previously failed ones - send, skip := uint64(0), []uint64{} - for send == 0 && !q.headerTaskQueue.Empty() { - from, _ := q.headerTaskQueue.Pop() - if q.headerPeerMiss[p.id] != nil { - if _, ok := q.headerPeerMiss[p.id][from]; ok { - skip = append(skip, from) - continue - } - } - send = from - } - // Merge all the skipped batches back - for _, from := range skip { - q.headerTaskQueue.Push(from, -int64(from)) - } - // Assemble and return the block download request - if send == 0 { - return nil - } - request := &fetchRequest{ - Peer: p, - From: send, - Time: time.Now(), - } - q.headerPendPool[p.id] = request - return request -} - // ReserveBodies reserves a set of body fetches for the given peer, skipping any // previously failed downloads. Beside the next batch of needed fetches, it also // returns a flag whether empty blocks were queued requiring processing. @@ -594,10 +492,6 @@ func (q *queue) Revoke(peerID string) { q.lock.Lock() defer q.lock.Unlock() - if request, ok := q.headerPendPool[peerID]; ok { - q.headerTaskQueue.Push(request.From, -int64(request.From)) - delete(q.headerPendPool, peerID) - } if request, ok := q.blockPendPool[peerID]; ok { for _, header := range request.Headers { q.blockTaskQueue.Push(header, -int64(header.Number.Uint64())) @@ -612,16 +506,6 @@ func (q *queue) Revoke(peerID string) { } } -// ExpireHeaders cancels a request that timed out and moves the pending fetch -// task back into the queue for rescheduling. -func (q *queue) ExpireHeaders(peer string) int { - q.lock.Lock() - defer q.lock.Unlock() - - headerTimeoutMeter.Mark(1) - return q.expire(peer, q.headerPendPool, q.headerTaskQueue) -} - // ExpireBodies checks for in flight block body requests that exceeded a timeout // allowance, canceling them and returning the responsible peers for penalisation. func (q *queue) ExpireBodies(peer string) int { @@ -670,116 +554,6 @@ func (q *queue) expire(peer string, pendPool map[string]*fetchRequest, taskQueue return len(req.Headers) } -// DeliverHeaders injects a header retrieval response into the header results -// cache. This method either accepts all headers it received, or none of them -// if they do not map correctly to the skeleton. -// -// If the headers are accepted, the method makes an attempt to deliver the set -// of ready headers to the processor to keep the pipeline full. However, it will -// not block to prevent stalling other pending deliveries. -func (q *queue) DeliverHeaders(id string, headers []*types.Header, hashes []common.Hash, headerProcCh chan *headerTask) (int, error) { - q.lock.Lock() - defer q.lock.Unlock() - - var logger log.Logger - if len(id) < 16 { - // Tests use short IDs, don't choke on them - logger = log.New("peer", id) - } else { - logger = log.New("peer", id[:16]) - } - // Short circuit if the data was never requested - request := q.headerPendPool[id] - if request == nil { - headerDropMeter.Mark(int64(len(headers))) - return 0, errNoFetchesPending - } - delete(q.headerPendPool, id) - - headerReqTimer.UpdateSince(request.Time) - headerInMeter.Mark(int64(len(headers))) - - // Ensure headers can be mapped onto the skeleton chain - target := q.headerTaskPool[request.From].Hash() - - accepted := len(headers) == MaxHeaderFetch - if accepted { - if headers[0].Number.Uint64() != request.From { - logger.Trace("First header broke chain ordering", "number", headers[0].Number, "hash", hashes[0], "expected", request.From) - accepted = false - } else if hashes[len(headers)-1] != target { - logger.Trace("Last header broke skeleton structure ", "number", headers[len(headers)-1].Number, "hash", hashes[len(headers)-1], "expected", target) - accepted = false - } - } - if accepted { - parentHash := hashes[0] - for i, header := range headers[1:] { - hash := hashes[i+1] - if want := request.From + 1 + uint64(i); header.Number.Uint64() != want { - logger.Warn("Header broke chain ordering", "number", header.Number, "hash", hash, "expected", want) - accepted = false - break - } - if parentHash != header.ParentHash { - logger.Warn("Header broke chain ancestry", "number", header.Number, "hash", hash) - accepted = false - break - } - // Set-up parent hash for next round - parentHash = hash - } - } - // If the batch of headers wasn't accepted, mark as unavailable - if !accepted { - logger.Trace("Skeleton filling not accepted", "from", request.From) - headerDropMeter.Mark(int64(len(headers))) - - miss := q.headerPeerMiss[id] - if miss == nil { - q.headerPeerMiss[id] = make(map[uint64]struct{}) - miss = q.headerPeerMiss[id] - } - miss[request.From] = struct{}{} - - q.headerTaskQueue.Push(request.From, -int64(request.From)) - return 0, errors.New("delivery not accepted") - } - // Clean up a successful fetch and try to deliver any sub-results - copy(q.headerResults[request.From-q.headerOffset:], headers) - copy(q.headerHashes[request.From-q.headerOffset:], hashes) - - delete(q.headerTaskPool, request.From) - - ready := 0 - for q.headerProced+ready < len(q.headerResults) && q.headerResults[q.headerProced+ready] != nil { - ready += MaxHeaderFetch - } - if ready > 0 { - // Headers are ready for delivery, gather them and push forward (non blocking) - processHeaders := make([]*types.Header, ready) - copy(processHeaders, q.headerResults[q.headerProced:q.headerProced+ready]) - - processHashes := make([]common.Hash, ready) - copy(processHashes, q.headerHashes[q.headerProced:q.headerProced+ready]) - - select { - case headerProcCh <- &headerTask{ - headers: processHeaders, - hashes: processHashes, - }: - logger.Trace("Pre-scheduled new headers", "count", len(processHeaders), "from", processHeaders[0].Number) - q.headerProced += len(processHeaders) - default: - } - } - // Check for termination and return - if len(q.headerTaskPool) == 0 { - q.headerContCh <- false - } - return len(headers), nil -} - // DeliverBodies injects a block body retrieval response into the results queue. // The method returns the number of blocks bodies accepted from the delivery and // also wakes any threads waiting for data delivery. diff --git a/eth/downloader/resultstore.go b/eth/downloader/resultstore.go index e4323c04eb..36c382fefc 100644 --- a/eth/downloader/resultstore.go +++ b/eth/downloader/resultstore.go @@ -76,7 +76,7 @@ func (r *resultStore) SetThrottleThreshold(threshold uint64) uint64 { // throttled - if true, the store is at capacity, this particular header is not prio now // item - the result to store data into // err - any error that occurred -func (r *resultStore) AddFetch(header *types.Header, fastSync bool) (stale, throttled bool, item *fetchResult, err error) { +func (r *resultStore) AddFetch(header *types.Header, snapSync bool) (stale, throttled bool, item *fetchResult, err error) { r.lock.Lock() defer r.lock.Unlock() @@ -86,7 +86,7 @@ func (r *resultStore) AddFetch(header *types.Header, fastSync bool) (stale, thro return stale, throttled, item, err } if item == nil { - item = newFetchResult(header, fastSync) + item = newFetchResult(header, snapSync) r.items[index] = item } return stale, throttled, item, err From db9be56bab751e3d75fcc29e282ff7e51bd95b8b Mon Sep 17 00:00:00 2001 From: Mobin Mohanan <47410557+tr1sm0s1n@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:48:35 +0530 Subject: [PATCH 264/940] build: upgrade to golangci-lint v2 (#31530) --- .golangci.yml | 131 +++++++++++++++++++++++++------------------- build/checksums.txt | 106 +++++++++++++++++------------------ 2 files changed, 127 insertions(+), 110 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index a702da524b..5ed06537bd 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,31 +1,25 @@ # This file configures github.com/golangci/golangci-lint. - +version: '2' run: - timeout: 20m tests: true - linters: - disable-all: true + default: none enable: - - goimports - - gosimple - - govet - - ineffassign - - misspell - - unconvert - - typecheck - - unused - - staticcheck - bidichk - - durationcheck - copyloopvar - - whitespace - - revive # only certain checks enabled - durationcheck - gocheckcompilerdirectives - - reassign + - govet + - ineffassign - mirror + - misspell + - reassign + - revive # only certain checks enabled + - staticcheck + - unconvert + - unused - usetesting + - whitespace ### linters we tried and will not be using: ### # - structcheck # lots of false positives @@ -36,44 +30,67 @@ linters: # - exhaustive # silly check # - makezero # false positives # - nilerr # several intentional - -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 + settings: + staticcheck: + checks: + # disable Quickfixes + - -QF1* + 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: + - '' + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling rules: - - name: receiver-naming - severity: warning - disabled: false - exclude: [""] - -issues: - # default is true. Enables skipping of directories: - # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ - exclude-dirs-use-default: true - exclude-files: - - core/genesis_alloc.go - exclude-rules: - - path: crypto/bn256/cloudflare/optate.go - linters: - - deadcode - - 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.' - exclude: - - 'SA1019: event.TypeMux is deprecated: use Feed' - - 'SA1019: strings.Title is deprecated' - - 'SA1019: strings.Title has been deprecated since Go 1.18 and an alternative has been available since Go 1.0: The rule Title uses for word boundaries does not handle Unicode punctuation properly. Use golang.org/x/text/cases instead.' - - 'SA1029: should not use built-in type string as key for value' + - linters: + - deadcode + - staticcheck + path: crypto/bn256/cloudflare/optate.go + - linters: + - revive + path: crypto/bn256/ + - 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: (.+)\.go$ + text: 'SA1019: event.TypeMux is deprecated: use Feed' + - path: (.+)\.go$ + text: 'SA1019: strings.Title is deprecated' + - path: (.+)\.go$ + text: 'SA1019: strings.Title has been deprecated since Go 1.18 and an alternative has been available since Go 1.0: The rule Title uses for word boundaries does not handle Unicode punctuation properly. Use golang.org/x/text/cases instead.' + - path: (.+)\.go$ + text: 'SA1029: should not use built-in type string as key for value' + paths: + - core/genesis_alloc.go + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - goimports + settings: + gofmt: + simplify: true + exclusions: + generated: lax + paths: + - core/genesis_alloc.go + - third_party$ + - builtin$ + - examples$ diff --git a/build/checksums.txt b/build/checksums.txt index 5ccb85bba6..6d3b718c3c 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -54,60 +54,60 @@ db128981033ac82a64688a123f631e61297b6b8f52ca913145e57caa8ce94cc3 go1.24.1.windo e28c4e6d0b913955765b46157ab88ae59bb636acaa12d7bec959aa6900f1cebd go1.24.1.windows-arm64.zip 6d352c1f154a102a5b90c480cc64bab205ccf2681e34e78a3a4d3f1ddfbc81e4 go1.24.1.windows-arm64.msi -# version:golangci 1.64.6 +# version:golangci 2.0.2 # https://github.com/golangci/golangci-lint/releases/ -# https://github.com/golangci/golangci-lint/releases/download/v1.64.6/ -08f9459e7125fed2612abd71596e04d172695921aff82120d1c1e5e9b6fff2a3 golangci-lint-1.64.6-darwin-amd64.tar.gz -8c10d0c7c3935b8c2269d628b6a06a8f48d8fb4cc31af02fe4ce0cd18b0704c1 golangci-lint-1.64.6-darwin-arm64.tar.gz -c07fcabb55deb8d2c4d390025568e76162d7f91b1d14bd2311be45d8d440a624 golangci-lint-1.64.6-freebsd-386.tar.gz -8ed1ef1102e1a42983ffcaae8e06de6a540334c3a69e205c610b8a7c92d469cd golangci-lint-1.64.6-freebsd-amd64.tar.gz -8f8dda66d1b4a85cc8a1daf1b69af6559c3eb0a41dd8033148a9ad85cfc0e1d9 golangci-lint-1.64.6-freebsd-armv6.tar.gz -59e8ca1fa254661b2a55e96515b14a10cd02221d443054deac5b28c3c3e12d6b golangci-lint-1.64.6-freebsd-armv7.tar.gz -e3d323d5f132e9b7593141bfe1d19c8460e65a55cea1008ec96945fed563f981 golangci-lint-1.64.6-illumos-amd64.tar.gz -5ce910f2a864c5fbeb32a30cbd506e1b2ef215f7a0f422cd5be6370b13db6f03 golangci-lint-1.64.6-linux-386.deb -2caab682a26b9a5fb94ba24e3a7e1404fa9eab2c12e36ae1c5548d80a1be190c golangci-lint-1.64.6-linux-386.rpm -2d82d0a4716e6d9b70c95103054855cb4b5f20f7bbdee42297f0189955bd14b6 golangci-lint-1.64.6-linux-386.tar.gz -9cd82503e9841abcaa57663fc899587fe90363c26d86a793a98d3080fd25e907 golangci-lint-1.64.6-linux-amd64.deb -981aaca5e5202d4fbb162ec7080490eb67ef5d32add5fb62fb02210597acc9da golangci-lint-1.64.6-linux-amd64.rpm -71e290acbacb7b3ba4f68f0540fb74dc180c4336ac8a6f3bdcd7fcc48b15148d golangci-lint-1.64.6-linux-amd64.tar.gz -718016bb06c1f598a8d23c7964e2643de621dbe5808688cb38857eb0bb773c84 golangci-lint-1.64.6-linux-arm64.deb -ddc0e7b4b10b47cf894aea157e89e3674bbb60f8f5c480110c21c49cc2c1634d golangci-lint-1.64.6-linux-arm64.rpm -99a7ff13dec7a8781a68408b6ecb8a1c5e82786cba3189eaa91d5cdcc24362ce golangci-lint-1.64.6-linux-arm64.tar.gz -90e360f89c244394912b8709fb83a900b6d56cf19141df2afaf9e902ef3057b1 golangci-lint-1.64.6-linux-armv6.deb -46546ff7c98d873ffcdbee06b39dc1024fc08db4fbf1f6309360a44cf976b5c2 golangci-lint-1.64.6-linux-armv6.rpm -e45c1a42868aca0b0ee54d14fb89da216f3b4409367cd7bce3b5f36788b4fc92 golangci-lint-1.64.6-linux-armv6.tar.gz -3cf6ddbbbf358db3de4b64a24f9683bbe2da3f003cfdee86cb610124b57abafb golangci-lint-1.64.6-linux-armv7.deb -508b6712710da10f11aab9ea5e63af415c932dfe7fff718e649d3100b838f797 golangci-lint-1.64.6-linux-armv7.rpm -da9a8bbee86b4dfee73fbc17e0856ec84c5b04919eb09bf3dd5904c39ce41753 golangci-lint-1.64.6-linux-armv7.tar.gz -ad496a58284e1e9c8ac6f993fec429dcd96c85a8c4715dbb6530a5af0dae7fbd golangci-lint-1.64.6-linux-loong64.deb -3bd70fa737b224750254dce616d9a188570e49b894b0cdb2fd04155e2c061350 golangci-lint-1.64.6-linux-loong64.rpm -a535af973499729f2215a84303eb0de61399057aad6901ddea1b4f73f68d5f2c golangci-lint-1.64.6-linux-loong64.tar.gz -6ad2a1cd37ca30303a488abfca2de52aff57519901c6d8d2608656fe9fb05292 golangci-lint-1.64.6-linux-mips64.deb -5f18369f0ca010a02c267352ebe6e3e0514c6debff49899c9e5520906c0da287 golangci-lint-1.64.6-linux-mips64.rpm -3449d6c13307b91b0e8817f8911c07c3412cdb6931b8d101e42db3e9762e91ad golangci-lint-1.64.6-linux-mips64.tar.gz -d4712a348f65dcaf9f6c58f1cfd6d0984d54a902873dca5e76f0d686f5c59499 golangci-lint-1.64.6-linux-mips64le.deb -57cea4538894558cb8c956d6b69c5509e4304546abe4a467478fc9ada0c736d6 golangci-lint-1.64.6-linux-mips64le.rpm -bc030977d44535b2152fddb2732f056d193c043992fe638ddecea21a40ef09fe golangci-lint-1.64.6-linux-mips64le.tar.gz -1ceb4e492efa527d246c61798c581f49113756fab8c39bb3eefdb1fa97041f92 golangci-lint-1.64.6-linux-ppc64le.deb -454e1c2b3583a8644e0c33a970fb4ce35b8f11848e1a770d9095d99d159ad0ab golangci-lint-1.64.6-linux-ppc64le.rpm -fddf30d35923eb6c7bb57520d8645768f802bf86c4cbf5a3a13049efb9e71b82 golangci-lint-1.64.6-linux-ppc64le.tar.gz -bd75f0dd6f65bee5821c433803b28f3c427ef3582764c3d0e7f7fae1c9d468b6 golangci-lint-1.64.6-linux-riscv64.deb -58457207c225cbd5340c8dcb75d9a44aa890d604e28464115a3a9762febaed04 golangci-lint-1.64.6-linux-riscv64.rpm -82639518a613a6705b7e2de5b28c278e875d782a5c97e9c1b2ac10b4ecd7852f golangci-lint-1.64.6-linux-riscv64.tar.gz -131d69204f8ced200b1437731e987cc886edac30dc87e6e1dcbd4f833d351713 golangci-lint-1.64.6-linux-s390x.deb -ca6caf28ca7a1df7cff720f8fd6ac4b8f2eac10c8cbfe7d2eade70876aded570 golangci-lint-1.64.6-linux-s390x.rpm -ed966d28a6512bc2b1120029a9f78ed77f2015e330b589a731d67d59be30b0b1 golangci-lint-1.64.6-linux-s390x.tar.gz -b181132b41943fc77ace7f9f5523085d12d3613f27774a0e35e17dd5e65ba589 golangci-lint-1.64.6-netbsd-386.tar.gz -f7b81c426006e3c699dc8665797a462aecba8c2cd23ac4971472e55184d95bc9 golangci-lint-1.64.6-netbsd-amd64.tar.gz -663d6fb4c3bef57b8aacdb1b1a4634075e55d294ed170724b443374860897ca6 golangci-lint-1.64.6-netbsd-arm64.tar.gz -8c7a76ee822568cc19352bbb9b2b0863dc5e185eb07782adbbaf648afd02ebcd golangci-lint-1.64.6-netbsd-armv6.tar.gz -0ce26d56ce78e516529e087118ba3f1bcd71d311b4c5b2bde6ec24a6e8966d85 golangci-lint-1.64.6-netbsd-armv7.tar.gz -135d5d998168683f46e4fab308cef5aa3c282025b7de6b258f976aadfb820db7 golangci-lint-1.64.6-source.tar.gz -ccdb0cc249531a205304a76308cfa7cda830083d083d557884416a2461148263 golangci-lint-1.64.6-windows-386.zip -2d88f282e08e1853c70bc7c914b5f58beaa6509903d56098aeb9bc3df30ea9d5 golangci-lint-1.64.6-windows-amd64.zip -6a3c6e7afc6916392679d7d6b95ac239827644e3e50ec4e8ca6ab1e4e6db65fe golangci-lint-1.64.6-windows-arm64.zip -9c9c1ef9687651566987f93e76252f7526c386901d7d8aeee044ca88115da4b1 golangci-lint-1.64.6-windows-armv6.zip -4f0df114155791799dfde8cd8cb6307fecfb17fed70b44205486ec925e2f39cf golangci-lint-1.64.6-windows-armv7.zip +# https://github.com/golangci/golangci-lint/releases/download/v2.0.2/ +a88cbdc86b483fe44e90bf2dcc3fec2af8c754116e6edf0aa6592cac5baa7a0e golangci-lint-2.0.2-darwin-amd64.tar.gz +664550e7954f5f4451aae99b4f7382c1a47039c66f39ca605f5d9af1a0d32b49 golangci-lint-2.0.2-darwin-arm64.tar.gz +bda0f0f27d300502faceda8428834a76ca25986f6d9fc2bd41d201c3ed73f08e golangci-lint-2.0.2-freebsd-386.tar.gz +1cbd0c7ade3fb027d61d38a646ec1b51be5846952b4b04a5330e7f4687f2270c golangci-lint-2.0.2-freebsd-amd64.tar.gz +1e828a597726198b2e35acdbcc5f3aad85244d79846d2d2bdb05241c5a535f9e golangci-lint-2.0.2-freebsd-armv6.tar.gz +848b49315dc5cddd0c9ce35e96ab33d584db0ea8fb57bcbf9784f1622bec0269 golangci-lint-2.0.2-freebsd-armv7.tar.gz +cabf9a6beab574c7f98581eb237919e580024759e3cdc05c4d516b044dce6770 golangci-lint-2.0.2-illumos-amd64.tar.gz +2fde80d15ed6527791f106d606120620e913c3a663c90a8596861d0a4461169e golangci-lint-2.0.2-linux-386.deb +804bc6e350a8c613aaa0a33d8d45414a80157b0ba1b2c2335ac859f85ad98ebd golangci-lint-2.0.2-linux-386.rpm +e64beb72fecf581e57d88ae3adb1c9d4bf022694b6bd92e3c8e460910bbdc37d golangci-lint-2.0.2-linux-386.tar.gz +9c55aed174d7a52bb1d4006b36e7edee9023631f6b814a80cb39c9860d6f75c3 golangci-lint-2.0.2-linux-amd64.deb +c55a2ef741a687b4c679696931f7fd4a467babd64c9457cf17bb9632fd1cecd1 golangci-lint-2.0.2-linux-amd64.rpm +89cc8a7810dc63b9a37900da03e37c3601caf46d42265d774e0f1a5d883d53e2 golangci-lint-2.0.2-linux-amd64.tar.gz +a3e78583c4e7ea1b63e82559f126bb3a5b12788676f158526752d53e67824b99 golangci-lint-2.0.2-linux-arm64.deb +bd5dd52b5c9f18aa7a2904eda9a9f91c628e98623fe70b7afcbb847e2de84422 golangci-lint-2.0.2-linux-arm64.rpm +789d5b91219ac68c2336f77d41cd7e33a910420594780f455893f8453d09595b golangci-lint-2.0.2-linux-arm64.tar.gz +534cd4c464a66178714ed68152c1ed7aa73e5700bf409e4ed1a8363adf96afca golangci-lint-2.0.2-linux-armv6.deb +cf7d02905a5fc80b96c9a64621693b4cc7337b1ce29986c19fd72608dafe66c5 golangci-lint-2.0.2-linux-armv6.rpm +a0d81cb527d8fe878377f2356b5773e219b0b91832a6b59e7b9bcf9a90fe0b0e golangci-lint-2.0.2-linux-armv6.tar.gz +dedd5be7fff8cba8fe15b658a59347ea90d7d02a9fff87f09c7687e6da05a8b6 golangci-lint-2.0.2-linux-armv7.deb +85521b6f3ad2f5a2bc9bfe14b9b08623f764964048f75ed6dfcfaf8eb7d57cc1 golangci-lint-2.0.2-linux-armv7.rpm +96471046c7780dda4ea680f65e92c2ef56ff58d40bcffaf6cfe9d6d48e3c27aa golangci-lint-2.0.2-linux-armv7.tar.gz +815d914a7738e4362466b2d11004e8618b696b49e8ace13df2c2b25f28fb1e17 golangci-lint-2.0.2-linux-loong64.deb +f16381e3d8a0f011b95e086d83d620248432b915d01f4beab4d29cfe4dc388b0 golangci-lint-2.0.2-linux-loong64.rpm +1bd8d7714f9c92db6a0f23bae89f39c85ba047bec8eeb42b8748d30ae3228d18 golangci-lint-2.0.2-linux-loong64.tar.gz +ea6e9d4aabb526aa298e47e8b026d8893d918c5eb919ba0ab403e315def74cc5 golangci-lint-2.0.2-linux-mips64.deb +519d8d53af83fdc9c25cc3fba8b663331ac22ef68131d4b0084cb6f425b6f79a golangci-lint-2.0.2-linux-mips64.rpm +80d655a0a1ac1b19dcef4b58fa2a7dadb646cc50ad08d460b5c53cdb421165e4 golangci-lint-2.0.2-linux-mips64.tar.gz +aa0e75384bb482c865d4dfc95d23ceb25666bf20461b67a832f0eea6670312ec golangci-lint-2.0.2-linux-mips64le.deb +f2a8b500fb69bdea1b01df6267aaa5218fa4a58aeb781c1a20d0d802fe465a52 golangci-lint-2.0.2-linux-mips64le.rpm +e66a0c0c9a275f02d27a7caa9576112622306f001d73dfc082cf1ae446fc1242 golangci-lint-2.0.2-linux-mips64le.tar.gz +e85ad51aac6428be2d8a37000d053697371a538a5bcbc1644caa7c5e77f6d0af golangci-lint-2.0.2-linux-ppc64le.deb +906798365eac1944af2a9b9a303e6fd49ec9043307bc681b7a96277f7f8beea5 golangci-lint-2.0.2-linux-ppc64le.rpm +f7f1a271b0af274d6c9ce000f5dc6e1fb194350c67bcc62494f96f791882ba92 golangci-lint-2.0.2-linux-ppc64le.tar.gz +eea8bf643a42bf05de9780530db22923e5ab0d588f0e173594dc6518f2a25d2a golangci-lint-2.0.2-linux-riscv64.deb +4ff40f9fe2954400836e2a011ba4744d00ffab5068a51368552dfce6aba3b81b golangci-lint-2.0.2-linux-riscv64.rpm +531d8f225866674977d630afbf0533eb02f9bec607fb13895f7a2cd7b2e0a648 golangci-lint-2.0.2-linux-riscv64.tar.gz +6f827647046c603f40d97ea5aadc6f48cd0bb5d19f7a3d56500c3b833d2a0342 golangci-lint-2.0.2-linux-s390x.deb +387a090e9576d19ca86aac738172e58e07c19f2784a13bb387f4f0d75fb9c8d3 golangci-lint-2.0.2-linux-s390x.rpm +57de1fb7722a9feb2d11ed0a007a93959d05b9db5929a392abc222e30012467e golangci-lint-2.0.2-linux-s390x.tar.gz +ed95e0492ea86bf79eb661f0334474b2a4255093685ff587eccd797c5a54db7e golangci-lint-2.0.2-netbsd-386.tar.gz +eab81d729778166415d349a80e568b2f2b3a781745a9be3212a92abb1e732daf golangci-lint-2.0.2-netbsd-amd64.tar.gz +d20add73f7c2de2c3b01ed4fd7b63ffcf0a6597d5ea228d1699e92339a3cd047 golangci-lint-2.0.2-netbsd-arm64.tar.gz +4e4f44e6057879cd62424ff1800a767d25a595c0e91d6d48809eea9186b4c739 golangci-lint-2.0.2-netbsd-armv6.tar.gz +51ec17b16d8743ae4098a0171f04f0ed4d64561e3051b982778b0e6c306a1b03 golangci-lint-2.0.2-netbsd-armv7.tar.gz +5482cf27b93fae1765c70ee2a95d4074d038e9dee61bdd61d017ce8893d3a4a8 golangci-lint-2.0.2-source.tar.gz +a35d8fdf3e14079a10880dbbb7586b46faec89be96f086b244b3e565aac80313 golangci-lint-2.0.2-windows-386.zip +fe4b946cc01366b989001215687003a9c4a7098589921f75e6228d6d8cffc15c golangci-lint-2.0.2-windows-amd64.zip +646bd9250ef8c771d85cd22fe8e6f2397ae39599179755e3bbfa9ef97ad44090 golangci-lint-2.0.2-windows-arm64.zip +ce1dc0bad6f8a61d64e6b3779eeb773479c175125d6f686b0e67ef9c8432d16e golangci-lint-2.0.2-windows-armv6.zip +92684a48faabe792b11ac27ca8b25551eff940b0a1e84ad7244e98b4994962db golangci-lint-2.0.2-windows-armv7.zip # This is the builder on PPA that will build Go itself (inception-y), don't modify! # From a0620f114c469503985376e7e4bdc28547d4ea5a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 3 Apr 2025 15:44:07 +0200 Subject: [PATCH 265/940] eth: fix calls to HistoryPruningCutoff (#31552) These were caused by crossed merges of recent PRs #31414 and #31361 --- eth/api_backend.go | 15 ++++++++------- internal/ethapi/api_test.go | 5 ++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/eth/api_backend.go b/eth/api_backend.go index 944c357e78..b39dd4cbdb 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -94,7 +94,7 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb } var bn uint64 if number == rpc.EarliestBlockNumber { - bn = b.eth.blockchain.HistoryPruningCutoff() + bn = b.HistoryPruningCutoff() } else { bn = uint64(number) } @@ -152,10 +152,10 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe } bn := uint64(number) // the resolved number if number == rpc.EarliestBlockNumber { - bn = b.eth.blockchain.HistoryPruningCutoff() + bn = b.HistoryPruningCutoff() } block := b.eth.blockchain.GetBlockByNumber(bn) - if block == nil && bn < b.eth.blockchain.HistoryPruningCutoff() { + if block == nil && bn < b.HistoryPruningCutoff() { return nil, ðconfig.PrunedHistoryError{} } return block, nil @@ -167,7 +167,7 @@ func (b *EthAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*typ return nil, nil } block := b.eth.blockchain.GetBlock(hash, *number) - if block == nil && *number < b.eth.blockchain.HistoryPruningCutoff() { + if block == nil && *number < b.HistoryPruningCutoff() { return nil, ðconfig.PrunedHistoryError{} } return block, nil @@ -180,7 +180,7 @@ func (b *EthAPIBackend) GetBody(ctx context.Context, hash common.Hash, number rp } body := b.eth.blockchain.GetBody(hash) if body == nil { - if uint64(number) < b.eth.blockchain.HistoryPruningCutoff() { + if uint64(number) < b.HistoryPruningCutoff() { return nil, ðconfig.PrunedHistoryError{} } return nil, errors.New("block body not found") @@ -202,7 +202,7 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r } block := b.eth.blockchain.GetBlock(hash, header.Number.Uint64()) if block == nil { - if header.Number.Uint64() < b.eth.blockchain.HistoryPruningCutoff() { + if header.Number.Uint64() < b.HistoryPruningCutoff() { return nil, ðconfig.PrunedHistoryError{} } return nil, errors.New("header found, but block body is missing") @@ -265,7 +265,8 @@ func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockN } func (b *EthAPIBackend) HistoryPruningCutoff() uint64 { - return b.eth.blockchain.HistoryPruningCutoff() + bn, _ := b.eth.blockchain.HistoryPruningCutoff() + return bn } func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 37210aa78b..3fbf32e22e 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -623,7 +623,10 @@ func (b testBackend) NewMatcherBackend() filtermaps.MatcherBackend { panic("implement me") } -func (b testBackend) HistoryPruningCutoff() uint64 { return b.chain.HistoryPruningCutoff() } +func (b testBackend) HistoryPruningCutoff() uint64 { + bn, _ := b.chain.HistoryPruningCutoff() + return bn +} func TestEstimateGas(t *testing.T) { t.Parallel() From 49f0d49e89af34eef7ea4d712b6936c4e7440311 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 3 Apr 2025 15:58:37 +0200 Subject: [PATCH 266/940] cmd/devp2p/internal/v5test: log test descriptions (#31551) This adds the test description text to the output, instead of keeping it as a Go comment. Logs are visible in the hive UI where these tests run, while Go comments are not. --- cmd/devp2p/internal/v5test/discv5tests.go | 35 ++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/cmd/devp2p/internal/v5test/discv5tests.go b/cmd/devp2p/internal/v5test/discv5tests.go index 7dbd3c3be5..2139cd8ca6 100644 --- a/cmd/devp2p/internal/v5test/discv5tests.go +++ b/cmd/devp2p/internal/v5test/discv5tests.go @@ -59,8 +59,9 @@ func (s *Suite) AllTests() []utesting.Test { } } -// TestPing sends PING and expects a PONG response. func (s *Suite) TestPing(t *utesting.T) { + t.Log(`This test is just a sanity check. It sends PING and expects a PONG response.`) + conn, l1 := s.listen1(t) defer conn.close() @@ -85,9 +86,10 @@ func checkPong(t *utesting.T, pong *v5wire.Pong, ping *v5wire.Ping, c net.Packet } } -// TestPingLargeRequestID sends PING with a 9-byte request ID, which isn't allowed by the spec. -// The remote node should not respond. func (s *Suite) TestPingLargeRequestID(t *utesting.T) { + t.Log(`This test sends PING with a 9-byte request ID, which isn't allowed by the spec. +The remote node should not respond.`) + conn, l1 := s.listen1(t) defer conn.close() @@ -104,10 +106,11 @@ func (s *Suite) TestPingLargeRequestID(t *utesting.T) { } } -// TestPingMultiIP establishes a session from one IP as usual. The session is then reused -// on another IP, which shouldn't work. The remote node should respond with WHOAREYOU for -// the attempt from a different IP. func (s *Suite) TestPingMultiIP(t *utesting.T) { + t.Log(`This test establishes a session from one IP as usual. The session is then reused +on another IP, which shouldn't work. The remote node should respond with WHOAREYOU for +the attempt from a different IP.`) + conn, l1, l2 := s.listen2(t) defer conn.close() @@ -120,6 +123,7 @@ func (s *Suite) TestPingMultiIP(t *utesting.T) { checkPong(t, resp.(*v5wire.Pong), ping, l1) // Send on l2. This reuses the session because there is only one codec. + t.Log("sending ping from alternate IP", l2.LocalAddr()) ping2 := &v5wire.Ping{ReqID: conn.nextReqID()} conn.write(l2, ping2, nil) switch resp := conn.read(l2).(type) { @@ -158,6 +162,10 @@ func (s *Suite) TestPingMultiIP(t *utesting.T) { // packet instead of a handshake message packet. The remote node should respond with // another WHOAREYOU challenge for the second packet. func (s *Suite) TestPingHandshakeInterrupted(t *utesting.T) { + t.Log(`TestPingHandshakeInterrupted starts a handshake, but doesn't finish it and sends a second ordinary message +packet instead of a handshake message packet. The remote node should respond with +another WHOAREYOU challenge for the second packet.`) + conn, l1 := s.listen1(t) defer conn.close() @@ -181,8 +189,10 @@ func (s *Suite) TestPingHandshakeInterrupted(t *utesting.T) { } } -// TestTalkRequest sends TALKREQ and expects an empty TALKRESP response. func (s *Suite) TestTalkRequest(t *utesting.T) { + t.Log(`This test sends some examples of TALKREQ with a protocol-id of "test-protocol" +and expects an empty TALKRESP response.`) + conn, l1 := s.listen1(t) defer conn.close() @@ -202,6 +212,7 @@ func (s *Suite) TestTalkRequest(t *utesting.T) { } // Empty request ID. + t.Log("sending TALKREQ with empty request-id") resp = conn.reqresp(l1, &v5wire.TalkRequest{Protocol: "test-protocol"}) switch resp := resp.(type) { case *v5wire.TalkResponse: @@ -216,8 +227,9 @@ func (s *Suite) TestTalkRequest(t *utesting.T) { } } -// TestFindnodeZeroDistance checks that the remote node returns itself for FINDNODE with distance zero. func (s *Suite) TestFindnodeZeroDistance(t *utesting.T) { + t.Log(`This test checks that the remote node returns itself for FINDNODE with distance zero.`) + conn, l1 := s.listen1(t) defer conn.close() @@ -233,9 +245,11 @@ func (s *Suite) TestFindnodeZeroDistance(t *utesting.T) { } } -// TestFindnodeResults pings the node under test from multiple nodes. After waiting for them to be -// accepted into the remote table, the test checks that they are returned by FINDNODE. func (s *Suite) TestFindnodeResults(t *utesting.T) { + t.Log(`This test pings the node under test from multiple other endpoints and node identities +(the 'bystanders'). After waiting for them to be accepted into the remote table, the test checks +that they are returned by FINDNODE.`) + // Create bystanders. nodes := make([]*bystander, 5) added := make(chan enode.ID, len(nodes)) @@ -273,6 +287,7 @@ func (s *Suite) TestFindnodeResults(t *utesting.T) { } // Send FINDNODE for all distances. + t.Log("requesting nodes") conn, l1 := s.listen1(t) defer conn.close() foundNodes, err := conn.findnode(l1, dists) From 553183e5de5dd6aa73038f3a24f90fb65e141402 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 3 Apr 2025 22:03:03 +0800 Subject: [PATCH 267/940] core, eth, node: use sync write option in pebble (#31519) Fixes #31499 --- core/bench_test.go | 8 ++++---- core/blockchain_repair_test.go | 8 ++++---- core/blockchain_sethead_test.go | 2 +- core/blockchain_snapshot_test.go | 4 ++-- core/blockchain_test.go | 2 +- ethdb/pebble/pebble.go | 4 ++-- node/database.go | 13 +++++++++---- 7 files changed, 23 insertions(+), 18 deletions(-) diff --git a/core/bench_test.go b/core/bench_test.go index 155fa6c3b5..00f924076a 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -183,7 +183,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { if !disk { db = rawdb.NewMemoryDatabase() } else { - pdb, err := pebble.New(b.TempDir(), 128, 128, "", false) + pdb, err := pebble.New(b.TempDir(), 128, 128, "", false, true) if err != nil { b.Fatalf("cannot create temporary database: %v", err) } @@ -303,7 +303,7 @@ func makeChainForBench(db ethdb.Database, genesis *Genesis, full bool, count uin func benchWriteChain(b *testing.B, full bool, count uint64) { genesis := &Genesis{Config: params.AllEthashProtocolChanges} for i := 0; i < b.N; i++ { - pdb, err := pebble.New(b.TempDir(), 1024, 128, "", false) + pdb, err := pebble.New(b.TempDir(), 1024, 128, "", false, true) if err != nil { b.Fatalf("error opening database: %v", err) } @@ -316,7 +316,7 @@ func benchWriteChain(b *testing.B, full bool, count uint64) { func benchReadChain(b *testing.B, full bool, count uint64) { dir := b.TempDir() - pdb, err := pebble.New(dir, 1024, 128, "", false) + pdb, err := pebble.New(dir, 1024, 128, "", false, true) if err != nil { b.Fatalf("error opening database: %v", err) } @@ -332,7 +332,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) { b.ResetTimer() for i := 0; i < b.N; i++ { - pdb, err = pebble.New(dir, 1024, 128, "", false) + pdb, err = pebble.New(dir, 1024, 128, "", false, true) if err != nil { b.Fatalf("error opening database: %v", err) } diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index 6c52d057ad..3ff1d77fc8 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -1765,7 +1765,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s datadir := t.TempDir() ancient := filepath.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false) + pdb, err := pebble.New(datadir, 0, 0, "", false, true) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } @@ -1850,7 +1850,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s chain.stopWithoutSaving() // Start a new blockchain back up and see where the repair leads us - pdb, err = pebble.New(datadir, 0, 0, "", false) + pdb, err = pebble.New(datadir, 0, 0, "", false, true) if err != nil { t.Fatalf("Failed to reopen persistent key-value database: %v", err) } @@ -1915,7 +1915,7 @@ func testIssue23496(t *testing.T, scheme string) { datadir := t.TempDir() ancient := filepath.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false) + pdb, err := pebble.New(datadir, 0, 0, "", false, true) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } @@ -1973,7 +1973,7 @@ func testIssue23496(t *testing.T, scheme string) { chain.stopWithoutSaving() // Start a new blockchain back up and see where the repair leads us - pdb, err = pebble.New(datadir, 0, 0, "", false) + pdb, err = pebble.New(datadir, 0, 0, "", false, true) if err != nil { t.Fatalf("Failed to reopen persistent key-value database: %v", err) } diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index 424854b2bf..e998b510df 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -1969,7 +1969,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme datadir := t.TempDir() ancient := filepath.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false) + pdb, err := pebble.New(datadir, 0, 0, "", false, true) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 1a6fe38af6..23effea15e 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -66,7 +66,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo datadir := t.TempDir() ancient := filepath.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false) + pdb, err := pebble.New(datadir, 0, 0, "", false, true) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } @@ -257,7 +257,7 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) { chain.triedb.Close() // Start a new blockchain back up and see where the repair leads us - pdb, err := pebble.New(snaptest.datadir, 0, 0, "", false) + pdb, err := pebble.New(snaptest.datadir, 0, 0, "", false, true) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 8f5a64e206..3f7c03b93c 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -2491,7 +2491,7 @@ func testSideImportPrunedBlocks(t *testing.T, scheme string) { datadir := t.TempDir() ancient := path.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false) + pdb, err := pebble.New(datadir, 0, 0, "", false, true) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index b87ecb2595..969e67af5a 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -144,7 +144,7 @@ func (l panicLogger) Fatalf(format string, args ...interface{}) { // New returns a wrapped pebble DB object. The namespace is the prefix that the // metrics reporting should use for surfacing internal stats. -func New(file string, cache int, handles int, namespace string, readonly bool) (*Database, error) { +func New(file string, cache int, handles int, namespace string, readonly bool, ephemeral bool) (*Database, error) { // Ensure we have some minimal caching and file guarantees if cache < minCache { cache = minCache @@ -185,7 +185,7 @@ func New(file string, cache int, handles int, namespace string, readonly bool) ( fn: file, log: logger, quitChan: make(chan chan error), - writeOptions: &pebble.WriteOptions{Sync: false}, + writeOptions: &pebble.WriteOptions{Sync: !ephemeral}, } opt := &pebble.Options{ // Pebble has a single combined cache area and the write diff --git a/node/database.go b/node/database.go index e3ccb91066..b7d0d856cb 100644 --- a/node/database.go +++ b/node/database.go @@ -36,6 +36,11 @@ type openOptions struct { Cache int // the capacity(in megabytes) of the data caching Handles int // number of files to be open simultaneously ReadOnly bool + + // Ephemeral means that filesystem sync operations should be avoided: + // data integrity in the face of a crash is not important. This option + // should typically be used in tests. + Ephemeral bool } // openDatabase opens both a disk-based key-value database such as leveldb or pebble, but also @@ -78,7 +83,7 @@ func openKeyValueDatabase(o openOptions) (ethdb.Database, error) { } if o.Type == rawdb.DBPebble || existingDb == rawdb.DBPebble { log.Info("Using pebble as the backing database") - return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) + return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) } if o.Type == rawdb.DBLeveldb || existingDb == rawdb.DBLeveldb { log.Info("Using leveldb as the backing database") @@ -86,7 +91,7 @@ func openKeyValueDatabase(o openOptions) (ethdb.Database, error) { } // No pre-existing database, no user-requested one either. Default to Pebble. log.Info("Defaulting to pebble as the backing database") - return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) + return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) } // newLevelDBDatabase creates a persistent key-value database without a freezer @@ -102,8 +107,8 @@ func newLevelDBDatabase(file string, cache int, handles int, namespace string, r // newPebbleDBDatabase creates a persistent key-value database without a freezer // moving immutable chain segments into cold storage. -func newPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) { - db, err := pebble.New(file, cache, handles, namespace, readonly) +func newPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool, ephemeral bool) (ethdb.Database, error) { + db, err := pebble.New(file, cache, handles, namespace, readonly, ephemeral) if err != nil { return nil, err } From 9f83e9e6734f82facbc66fd4cd591dd648aaec92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Thu, 3 Apr 2025 16:04:11 +0200 Subject: [PATCH 268/940] beacon/blsync: add checkpoint import/export file feature (#31469) This PR adds a new `--beacon.checkpoint.file` config flag to geth and blsync which specifies a checkpoint import/export file. If a file with an existing checkpoint is specified, it is used for initialization instead of the hardcoded one (except when `--beacon.checkpoint` is also specified simultaneously). Whenever the client encounters a new valid finality update with a suitable finalized beacon block root at an epoch boundary, it saves the block root in hex format to the checkpoint file. --- beacon/blsync/client.go | 10 +++++++++- beacon/light/head_tracker.go | 9 ++++++++- beacon/params/config.go | 34 ++++++++++++++++++++++++++++++++++ cmd/blsync/main.go | 1 + cmd/geth/main.go | 1 + cmd/utils/flags.go | 32 ++++++++++++++++++++++++++------ 6 files changed, 79 insertions(+), 8 deletions(-) diff --git a/beacon/blsync/client.go b/beacon/blsync/client.go index 3c93754d3d..744f469124 100644 --- a/beacon/blsync/client.go +++ b/beacon/blsync/client.go @@ -23,9 +23,11 @@ import ( "github.com/ethereum/go-ethereum/beacon/light/sync" "github.com/ethereum/go-ethereum/beacon/params" "github.com/ethereum/go-ethereum/beacon/types" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" ) @@ -46,7 +48,13 @@ func NewClient(config params.ClientConfig) *Client { var ( db = memorydb.New() committeeChain = light.NewCommitteeChain(db, &config.ChainConfig, config.Threshold, !config.NoFilter) - headTracker = light.NewHeadTracker(committeeChain, config.Threshold) + headTracker = light.NewHeadTracker(committeeChain, config.Threshold, func(checkpoint common.Hash) { + if saved, err := config.SaveCheckpointToFile(checkpoint); saved { + log.Debug("Saved beacon checkpoint", "file", config.CheckpointFile, "checkpoint", checkpoint) + } else if err != nil { + log.Error("Failed to save beacon checkpoint", "file", config.CheckpointFile, "checkpoint", checkpoint, "error", err) + } + }) ) headSync := sync.NewHeadSync(headTracker, committeeChain) diff --git a/beacon/light/head_tracker.go b/beacon/light/head_tracker.go index 010e548ddb..62faf1dbc1 100644 --- a/beacon/light/head_tracker.go +++ b/beacon/light/head_tracker.go @@ -21,7 +21,9 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/beacon/params" "github.com/ethereum/go-ethereum/beacon/types" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" ) @@ -38,13 +40,15 @@ type HeadTracker struct { hasFinalityUpdate bool prefetchHead types.HeadInfo changeCounter uint64 + saveCheckpoint func(common.Hash) } // NewHeadTracker creates a new HeadTracker. -func NewHeadTracker(committeeChain *CommitteeChain, minSignerCount int) *HeadTracker { +func NewHeadTracker(committeeChain *CommitteeChain, minSignerCount int, saveCheckpoint func(common.Hash)) *HeadTracker { return &HeadTracker{ committeeChain: committeeChain, minSignerCount: minSignerCount, + saveCheckpoint: saveCheckpoint, } } @@ -100,6 +104,9 @@ func (h *HeadTracker) ValidateFinality(update types.FinalityUpdate) (bool, error if replace { h.finalityUpdate, h.hasFinalityUpdate = update, true h.changeCounter++ + if h.saveCheckpoint != nil && update.Finalized.Slot%params.EpochLength == 0 { + h.saveCheckpoint(update.Finalized.Hash()) + } } return replace, err } diff --git a/beacon/params/config.go b/beacon/params/config.go index be2a40f171..2f6ba082c5 100644 --- a/beacon/params/config.go +++ b/beacon/params/config.go @@ -54,6 +54,7 @@ type ChainConfig struct { GenesisValidatorsRoot common.Hash // Root hash of the genesis validator set, used for signature domain calculation Forks Forks Checkpoint common.Hash + CheckpointFile string } // ForkAtEpoch returns the latest active fork at the given epoch. @@ -211,3 +212,36 @@ func (f Forks) Less(i, j int) bool { } return f[i].knownIndex < f[j].knownIndex } + +// SetCheckpointFile sets the checkpoint import/export file name and attempts to +// read the checkpoint from the file if it already exists. It returns true if +// a checkpoint has been loaded. +func (c *ChainConfig) SetCheckpointFile(checkpointFile string) (bool, error) { + c.CheckpointFile = checkpointFile + file, err := os.ReadFile(checkpointFile) + if os.IsNotExist(err) { + return false, nil // did not load checkpoint + } + if err != nil { + return false, fmt.Errorf("failed to read beacon checkpoint file: %v", err) + } + cp, err := hexutil.Decode(string(file)) + if err != nil { + return false, fmt.Errorf("failed to decode hex string in beacon checkpoint file: %v", err) + } + if len(cp) != 32 { + return false, fmt.Errorf("invalid hex string length in beacon checkpoint file: %d", len(cp)) + } + copy(c.Checkpoint[:len(cp)], cp) + return true, nil +} + +// SaveCheckpointToFile saves the given checkpoint to file if a checkpoint +// import/export file has been specified. +func (c *ChainConfig) SaveCheckpointToFile(checkpoint common.Hash) (bool, error) { + if c.CheckpointFile == "" { + return false, nil + } + err := os.WriteFile(c.CheckpointFile, []byte(checkpoint.Hex()), 0600) + return err == nil, err +} diff --git a/cmd/blsync/main.go b/cmd/blsync/main.go index 60caa4aa2a..39a9407304 100644 --- a/cmd/blsync/main.go +++ b/cmd/blsync/main.go @@ -43,6 +43,7 @@ func main() { utils.BeaconGenesisRootFlag, utils.BeaconGenesisTimeFlag, utils.BeaconCheckpointFlag, + utils.BeaconCheckpointFileFlag, //TODO datadir for optional permanent database utils.MainnetFlag, utils.SepoliaFlag, diff --git a/cmd/geth/main.go b/cmd/geth/main.go index cd74fb7b6a..ab46e059f3 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -157,6 +157,7 @@ var ( utils.BeaconGenesisRootFlag, utils.BeaconGenesisTimeFlag, utils.BeaconCheckpointFlag, + utils.BeaconCheckpointFileFlag, }, utils.NetworkFlags, utils.DatabaseFlags) rpcFlags = []cli.Flag{ diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index fb2892d2c1..f5fc94cebc 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -342,6 +342,11 @@ var ( Usage: "Beacon chain weak subjectivity checkpoint block hash", Category: flags.BeaconCategory, } + BeaconCheckpointFileFlag = &cli.StringFlag{ + Name: "beacon.checkpoint.file", + Usage: "Beacon chain weak subjectivity checkpoint import/export file", + Category: flags.BeaconCategory, + } BlsyncApiFlag = &cli.StringFlag{ Name: "blsync.engine.api", Usage: "Target EL engine API URL", @@ -1890,7 +1895,7 @@ func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig { if !ctx.IsSet(BeaconGenesisTimeFlag.Name) { Fatalf("Custom beacon chain config is specified but genesis time is missing") } - if !ctx.IsSet(BeaconCheckpointFlag.Name) { + if !ctx.IsSet(BeaconCheckpointFlag.Name) && !ctx.IsSet(BeaconCheckpointFileFlag.Name) { Fatalf("Custom beacon chain config is specified but checkpoint is missing") } config.ChainConfig = bparams.ChainConfig{ @@ -1915,13 +1920,28 @@ func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig { } } // Checkpoint is required with custom chain config and is optional with pre-defined config - if ctx.IsSet(BeaconCheckpointFlag.Name) { - if c, err := hexutil.Decode(ctx.String(BeaconCheckpointFlag.Name)); err == nil && len(c) <= 32 { - copy(config.Checkpoint[:len(c)], c) - } else { - Fatalf("Invalid hex string", "beacon.checkpoint", ctx.String(BeaconCheckpointFlag.Name), "error", err) + // If both checkpoint block hash and checkpoint file are specified then the + // client is initialized with the specified block hash and new checkpoints + // are saved to the specified file. + if ctx.IsSet(BeaconCheckpointFileFlag.Name) { + if _, err := config.SetCheckpointFile(ctx.String(BeaconCheckpointFileFlag.Name)); err != nil { + Fatalf("Could not load beacon checkpoint file", "beacon.checkpoint.file", ctx.String(BeaconCheckpointFileFlag.Name), "error", err) } } + if ctx.IsSet(BeaconCheckpointFlag.Name) { + hex := ctx.String(BeaconCheckpointFlag.Name) + c, err := hexutil.Decode(hex) + if err != nil { + Fatalf("Invalid hex string", "beacon.checkpoint", hex, "error", err) + } + if len(c) != 32 { + Fatalf("Invalid hex string length", "beacon.checkpoint", hex, "length", len(c)) + } + copy(config.Checkpoint[:len(c)], c) + } + if config.Checkpoint == (common.Hash{}) { + Fatalf("Beacon checkpoint not specified") + } config.Apis = ctx.StringSlice(BeaconApiFlag.Name) if config.Apis == nil { Fatalf("Beacon node light client API URL not specified") From ff365afc63f047c09ff04f41e12678c6b6698b72 Mon Sep 17 00:00:00 2001 From: Nathan Jo <162083209+qqqeck@users.noreply.github.com> Date: Fri, 4 Apr 2025 17:56:55 +0900 Subject: [PATCH 269/940] p2p/nat: remove forceful port mapping in upnp (#30265) Here we are modifying the port mapping logic so that existing port mappings will only be removed when they were previously created by geth. The AddAnyPortMapping functionality has been adapted to work consistently between the IGDv1 and IGDv2 backends. --- p2p/nat/natpmp.go | 3 +++ p2p/nat/natupnp.go | 36 +++++++++++++++++++++++------------- p2p/server_nat.go | 13 ++++--------- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/p2p/nat/natpmp.go b/p2p/nat/natpmp.go index 4a9644ac1a..ee07eb4ff6 100644 --- a/p2p/nat/natpmp.go +++ b/p2p/nat/natpmp.go @@ -49,6 +49,9 @@ func (n *pmp) AddMapping(protocol string, extport, intport int, name string, lif if lifetime <= 0 { return 0, errors.New("lifetime must not be <= 0") } + if extport == 0 { + extport = intport + } // Note order of port arguments is switched between our // AddMapping and the client's AddPortMapping. res, err := n.c.AddPortMapping(strings.ToLower(protocol), intport, extport, int(lifetime/time.Second)) diff --git a/p2p/nat/natupnp.go b/p2p/nat/natupnp.go index 1014dc69d2..ed00b8eeb6 100644 --- a/p2p/nat/natupnp.go +++ b/p2p/nat/natupnp.go @@ -86,15 +86,15 @@ func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, li } protocol = strings.ToUpper(protocol) lifetimeS := uint32(lifetime / time.Second) - n.DeleteMapping(protocol, extport, intport) - err = n.withRateLimit(func() error { - return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) - }) - if err == nil { - return uint16(extport), nil + if extport == 0 { + extport = intport + } else { + // Only delete port mapping if the external port was already used by geth. + n.DeleteMapping(protocol, extport, intport) } - // Try addAnyPortMapping if mapping specified port didn't work. + + // Try to add port mapping, preferring the specified external port. err = n.withRateLimit(func() error { p, err := n.addAnyPortMapping(protocol, extport, intport, ip, desc, lifetimeS) if err == nil { @@ -105,18 +105,28 @@ func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, li return uint16(extport), err } +// addAnyPortMapping tries to add a port mapping with the specified external port. +// If the external port is already in use, it will try to assign another port. func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.IP, desc string, lifetimeS uint32) (uint16, error) { if client, ok := n.client.(*internetgateway2.WANIPConnection2); ok { return client.AddAnyPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) } - // It will retry with a random port number if the client does - // not support AddAnyPortMapping. - extport = n.randomPort() + // For IGDv1 and v1 services we should first try to add with extport. err := n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) - if err != nil { - return 0, err + if err == nil { + return uint16(extport), nil } - return uint16(extport), nil + + // If above fails, we retry with a random port. + // We retry several times because of possible port conflicts. + for i := 0; i < 3; i++ { + extport = n.randomPort() + err := n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) + if err == nil { + return uint16(extport), nil + } + } + return 0, err } func (n *upnp) randomPort() int { diff --git a/p2p/server_nat.go b/p2p/server_nat.go index 933993bc1f..5830f950e1 100644 --- a/p2p/server_nat.go +++ b/p2p/server_nat.go @@ -150,14 +150,9 @@ func (srv *Server) portMappingLoop() { continue } - external := m.port - if m.extPort != 0 { - external = m.extPort - } - log := newLogger(m.protocol, external, m.port) - + log := newLogger(m.protocol, m.extPort, m.port) log.Trace("Attempting port mapping") - p, err := srv.NAT.AddMapping(m.protocol, external, m.port, m.name, portMapDuration) + p, err := srv.NAT.AddMapping(m.protocol, m.extPort, m.port, m.name, portMapDuration) if err != nil { log.Debug("Couldn't add port mapping", "err", err) m.extPort = 0 @@ -167,8 +162,8 @@ func (srv *Server) portMappingLoop() { // It was mapped! m.extPort = int(p) m.nextTime = srv.clock.Now().Add(portMapRefreshInterval) - if external != m.extPort { - log = newLogger(m.protocol, m.extPort, m.port) + log = newLogger(m.protocol, m.extPort, m.port) + if m.port != m.extPort { log.Info("NAT mapped alternative port") } else { log.Info("NAT mapped port") From 77dc1acafaad69e6adc98293541ee49644ed9218 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:07:46 +0200 Subject: [PATCH 270/940] internal/era: random access to header and receipts (#31544) Co-authored-by: lightclient Add GetHeaderByNumber and GetReceiptsByNumber to allow more efficient API request filling from Era files. --- internal/era/e2store/e2store.go | 12 +++++++ internal/era/era.go | 64 ++++++++++++++++++++++++++++----- internal/era/era_test.go | 53 ++++++++++++++++++++++----- 3 files changed, 112 insertions(+), 17 deletions(-) diff --git a/internal/era/e2store/e2store.go b/internal/era/e2store/e2store.go index 9832b72d48..b0d43bf55a 100644 --- a/internal/era/e2store/e2store.go +++ b/internal/era/e2store/e2store.go @@ -219,3 +219,15 @@ func (r *Reader) FindAll(want uint16) ([]*Entry, error) { off += int64(headerSize + length) } } + +// SkipN skips `n` entries starting from `offset` and returns the new offset. +func (r *Reader) SkipN(offset int64, n uint64) (int64, error) { + for i := uint64(0); i < n; i++ { + length, err := r.LengthAt(offset) + if err != nil { + return 0, err + } + offset += length + } + return offset, nil +} diff --git a/internal/era/era.go b/internal/era/era.go index daf337963d..5129186fe7 100644 --- a/internal/era/era.go +++ b/internal/era/era.go @@ -70,7 +70,7 @@ func ReadDir(dir, network string) ([]string, error) { } parts := strings.Split(entry.Name(), "-") if len(parts) != 3 || parts[0] != network { - // invalid era1 filename, skip + // Invalid era1 filename, skip. continue } if epoch, err := strconv.ParseUint(parts[1], 10, 64); err != nil { @@ -126,6 +126,29 @@ func (e *Era) Close() error { return e.f.Close() } +// GetHeaderByNumber returns the header for the given block number. +func (e *Era) GetHeaderByNumber(num uint64) (*types.Header, error) { + if e.m.start > num || e.m.start+e.m.count <= num { + return nil, errors.New("out-of-bounds") + } + off, err := e.readOffset(num) + if err != nil { + return nil, err + } + + // Read and decompress header. + r, _, err := newSnappyReader(e.s, TypeCompressedHeader, off) + if err != nil { + return nil, err + } + var header types.Header + if err := rlp.Decode(r, &header); err != nil { + return nil, err + } + return &header, nil +} + +// GetBlockByNumber returns the block for the given block number. func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) { if e.m.start > num || e.m.start+e.m.count <= num { return nil, errors.New("out-of-bounds") @@ -154,6 +177,34 @@ func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) { return types.NewBlockWithHeader(&header).WithBody(body), nil } +// GetReceiptsByNumber returns the receipts for the given block number. +func (e *Era) GetReceiptsByNumber(num uint64) (types.Receipts, error) { + if e.m.start > num || e.m.start+e.m.count <= num { + return nil, errors.New("out-of-bounds") + } + off, err := e.readOffset(num) + if err != nil { + return nil, err + } + + // Skip over header and body. + off, err = e.s.SkipN(off, 2) + if err != nil { + return nil, err + } + + // Read and decompress receipts. + r, _, err := newSnappyReader(e.s, TypeCompressedReceipts, off) + if err != nil { + return nil, err + } + var receipts types.Receipts + if err := rlp.Decode(r, &receipts); err != nil { + return nil, err + } + return receipts, nil +} + // Accumulator reads the accumulator entry in the Era1 file. func (e *Era) Accumulator() (common.Hash, error) { entry, err := e.s.Find(TypeAccumulator) @@ -187,13 +238,10 @@ func (e *Era) InitialTD() (*big.Int, error) { } off += n - // Skip over next two records. - for i := 0; i < 2; i++ { - length, err := e.s.LengthAt(off) - if err != nil { - return nil, err - } - off += length + // Skip over header and body. + off, err = e.s.SkipN(off, 2) + if err != nil { + return nil, err } // Read total difficulty after first block. diff --git a/internal/era/era_test.go b/internal/era/era_test.go index 72c3b385dd..46fc2e91f3 100644 --- a/internal/era/era_test.go +++ b/internal/era/era_test.go @@ -18,12 +18,15 @@ package era import ( "bytes" + "fmt" "io" "math/big" "os" "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" ) type testchain struct { @@ -48,9 +51,9 @@ func TestEra1Builder(t *testing.T) { chain = testchain{} ) for i := 0; i < 128; i++ { - chain.headers = append(chain.headers, []byte{byte('h'), byte(i)}) - chain.bodies = append(chain.bodies, []byte{byte('b'), byte(i)}) - chain.receipts = append(chain.receipts, []byte{byte('r'), byte(i)}) + chain.headers = append(chain.headers, mustEncode(&types.Header{Number: big.NewInt(int64(i))})) + chain.bodies = append(chain.bodies, mustEncode(&types.Body{Transactions: []*types.Transaction{types.NewTransaction(0, common.Address{byte(i)}, nil, 0, nil, nil)}})) + chain.receipts = append(chain.receipts, mustEncode(&types.Receipts{{CumulativeGasUsed: uint64(i)}})) chain.tds = append(chain.tds, big.NewInt(int64(i))) } @@ -91,13 +94,25 @@ func TestEra1Builder(t *testing.T) { t.Fatalf("unexpected error %v", it.Error()) } // Check headers. - header, err := io.ReadAll(it.Header) + rawHeader, err := io.ReadAll(it.Header) + if err != nil { + t.Fatalf("error reading header from iterator: %v", err) + } + if !bytes.Equal(rawHeader, chain.headers[i]) { + t.Fatalf("mismatched header: want %s, got %s", chain.headers[i], rawHeader) + } + header, err := e.GetHeaderByNumber(i) if err != nil { t.Fatalf("error reading header: %v", err) } - if !bytes.Equal(header, chain.headers[i]) { - t.Fatalf("mismatched header: want %s, got %s", chain.headers[i], header) + encHeader, err := rlp.EncodeToBytes(header) + if err != nil { + t.Fatalf("error encoding header: %v", err) } + if !bytes.Equal(encHeader, chain.headers[i]) { + t.Fatalf("mismatched header: want %s, got %s", chain.headers[i], encHeader) + } + // Check bodies. body, err := io.ReadAll(it.Body) if err != nil { @@ -106,13 +121,25 @@ func TestEra1Builder(t *testing.T) { if !bytes.Equal(body, chain.bodies[i]) { t.Fatalf("mismatched body: want %s, got %s", chain.bodies[i], body) } + // Check receipts. - receipts, err := io.ReadAll(it.Receipts) + rawReceipts, err := io.ReadAll(it.Receipts) + if err != nil { + t.Fatalf("error reading receipts from iterator: %v", err) + } + if !bytes.Equal(rawReceipts, chain.receipts[i]) { + t.Fatalf("mismatched receipts: want %s, got %s", chain.receipts[i], rawReceipts) + } + receipts, err := e.GetReceiptsByNumber(i) if err != nil { t.Fatalf("error reading receipts: %v", err) } - if !bytes.Equal(receipts, chain.receipts[i]) { - t.Fatalf("mismatched receipts: want %s, got %s", chain.receipts[i], receipts) + encReceipts, err := rlp.EncodeToBytes(receipts) + if err != nil { + t.Fatalf("error encoding receipts: %v", err) + } + if !bytes.Equal(encReceipts, chain.receipts[i]) { + t.Fatalf("mismatched receipts: want %s, got %s", chain.receipts[i], encReceipts) } // Check total difficulty. @@ -144,3 +171,11 @@ func TestEraFilename(t *testing.T) { } } } + +func mustEncode(obj any) []byte { + b, err := rlp.EncodeToBytes(obj) + if err != nil { + panic(fmt.Sprintf("failed in encode obj: %v", err)) + } + return b +} From 21b035eb29f6489ffee66d8ee2451873bc96dd2d Mon Sep 17 00:00:00 2001 From: Delweng Date: Mon, 7 Apr 2025 13:16:26 +0800 Subject: [PATCH 271/940] cmd/geth: set trie,gc and other cache flags for import chain (#31577) Signed-off-by: jsvisa --- cmd/geth/chaincmd.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 0c36b82af5..2279509542 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -79,11 +79,15 @@ if one is set. Otherwise it prints the genesis from the datadir.`, Usage: "Import a blockchain file", ArgsUsage: " ( ... ) ", Flags: slices.Concat([]cli.Flag{ - utils.CacheFlag, utils.GCModeFlag, utils.SnapshotFlag, + utils.CacheFlag, utils.CacheDatabaseFlag, + utils.CacheTrieFlag, utils.CacheGCFlag, + utils.CacheSnapshotFlag, + utils.CacheNoPrefetchFlag, + utils.CachePreimagesFlag, utils.NoCompactionFlag, utils.MetricsEnabledFlag, utils.MetricsEnabledExpensiveFlag, From ec6d1044045bcd6f8fe96892d840fe35c16ca7c8 Mon Sep 17 00:00:00 2001 From: Ocenka Date: Tue, 8 Apr 2025 15:44:13 +0300 Subject: [PATCH 272/940] eth/remotedb: improve error handling (#31331) This PR improves error handling in the remotedb package by fixing two issues: 1. In the `Has` method, we now properly propagate errors instead of silently returning false. This makes the behavior more predictable and helps clients better understand when there are connection issues. 2. In the `New` constructor, we add a nil check for the client parameter to prevent potential panics. This follows Go best practices for constructor functions. These changes make the code more robust and follow Go's error handling idioms without requiring any changes to other parts of the codebase. Changes: - Modified `Has` method to return errors instead of silently returning false - Added nil check in `New` constructor - Fixed field name in constructor to match struct definition --- ethdb/remotedb/remotedb.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ethdb/remotedb/remotedb.go b/ethdb/remotedb/remotedb.go index 247a4392db..8a91fdbcf2 100644 --- a/ethdb/remotedb/remotedb.go +++ b/ethdb/remotedb/remotedb.go @@ -34,7 +34,7 @@ type Database struct { func (db *Database) Has(key []byte) (bool, error) { if _, err := db.Get(key); err != nil { - return false, nil + return false, err } return true, nil } @@ -50,7 +50,7 @@ func (db *Database) Get(key []byte) ([]byte, error) { func (db *Database) HasAncient(kind string, number uint64) (bool, error) { if _, err := db.Ancient(kind, number); err != nil { - return false, nil + return false, err } return true, nil } @@ -144,7 +144,8 @@ func (db *Database) Close() error { } func New(client *rpc.Client) ethdb.Database { - return &Database{ - remote: client, + if client == nil { + return nil } + return &Database{remote: client} } From 2e739fce584a3cc8d84bf4c4604cd81c07294e2b Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 8 Apr 2025 21:46:27 +0800 Subject: [PATCH 273/940] core/txpool: add 7702 protection to blobpool (#31526) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request introduces two constraints in the blobPool: (a) If the sender has a pending authorization or delegation, only one in-flight executable transaction can be cached. (b) If the authority address in a SetCode transaction is already reserved by the blobPool, the transaction will be rejected. These constraints mitigate an attack where an attacker spams the pool with numerous blob transactions, evicts other transactions, and then cancels all pending blob transactions by draining the sender’s funds if they have a delegation. Note, because there is no exclusive lock held between different subpools when processing transactions, it's totally possible the SetCode transaction and blob transactions with conflict sender and authorities are accepted simultaneously. I think it's acceptable as it's very hard to be exploited. --------- Co-authored-by: lightclient --- core/txpool/blobpool/blobpool.go | 66 ++++++++--- core/txpool/blobpool/blobpool_test.go | 60 +++------- core/txpool/errors.go | 4 + core/txpool/legacypool/legacypool.go | 60 ++++++---- core/txpool/legacypool/legacypool2_test.go | 8 +- core/txpool/legacypool/legacypool_test.go | 82 +++++--------- core/txpool/reserver.go | 124 +++++++++++++++++++++ core/txpool/subpool.go | 6 +- core/txpool/txpool.go | 77 ++----------- eth/backend.go | 10 +- eth/protocols/eth/handler_test.go | 2 +- 11 files changed, 286 insertions(+), 213 deletions(-) create mode 100644 core/txpool/reserver.go diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 5a20c3ce5a..b1966905a8 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -298,8 +298,9 @@ func newBlobTxMeta(id uint64, size uint64, storageSize uint32, tx *types.Transac // minimums will need to be done only starting at the swapped in/out nonce // and leading up to the first no-change. type BlobPool struct { - config Config // Pool configuration - reserve txpool.AddressReserver // Address reserver to ensure exclusivity across subpools + config Config // Pool configuration + reserver *txpool.Reserver // Address reserver to ensure exclusivity across subpools + hasPendingAuth func(common.Address) bool // Determine whether the specified address has a pending 7702-auth store billy.Database // Persistent data store for the tx metadata and blobs stored uint64 // Useful data size of all transactions on disk @@ -329,13 +330,14 @@ type BlobPool struct { // New creates a new blob transaction pool to gather, sort and filter inbound // blob transactions from the network. -func New(config Config, chain BlockChain) *BlobPool { +func New(config Config, chain BlockChain, hasPendingAuth func(common.Address) bool) *BlobPool { // Sanitize the input to ensure no vulnerable gas prices are set config = (&config).sanitize() // Create the transaction pool with its initial settings return &BlobPool{ config: config, + hasPendingAuth: hasPendingAuth, signer: types.LatestSigner(chain.Config()), chain: chain, lookup: newLookup(), @@ -353,8 +355,8 @@ func (p *BlobPool) Filter(tx *types.Transaction) bool { // Init sets the gas price needed to keep a transaction in the pool and the chain // head to allow balance / nonce checks. The transaction journal will be loaded // from disk and filtered based on the provided starting settings. -func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.AddressReserver) error { - p.reserve = reserve +func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver *txpool.Reserver) error { + p.reserver = reserver var ( queuedir string @@ -499,7 +501,7 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error { return err } if _, ok := p.index[sender]; !ok { - if err := p.reserve(sender, true); err != nil { + if err := p.reserver.Hold(sender); err != nil { return err } p.index[sender] = []*blobTxMeta{} @@ -554,7 +556,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 if inclusions != nil { // only during reorgs will the heap be initialized heap.Remove(p.evict, p.evict.index[addr]) } - p.reserve(addr, false) + p.reserver.Release(addr) if gapped { log.Warn("Dropping dangling blob transactions", "from", addr, "missing", next, "drop", nonces, "ids", ids) @@ -707,7 +709,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 if inclusions != nil { // only during reorgs will the heap be initialized heap.Remove(p.evict, p.evict.index[addr]) } - p.reserve(addr, false) + p.reserver.Release(addr) } else { p.index[addr] = txs } @@ -1006,7 +1008,7 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error { // Update the indices and metrics meta := newBlobTxMeta(id, tx.Size(), p.store.Size(id), tx) if _, ok := p.index[addr]; !ok { - if err := p.reserve(addr, true); err != nil { + if err := p.reserver.Hold(addr); err != nil { log.Warn("Failed to reserve account for blob pool", "tx", tx.Hash(), "from", addr, "err", err) return err } @@ -1066,7 +1068,7 @@ func (p *BlobPool) SetGasTip(tip *big.Int) { delete(p.spent, addr) heap.Remove(p.evict, p.evict.index[addr]) - p.reserve(addr, false) + p.reserver.Release(addr) } // Clear out the transactions from the data store log.Warn("Dropping underpriced blob transaction", "from", addr, "rejected", tx.nonce, "tip", tx.execTipCap, "want", tip, "drop", nonces, "ids", ids) @@ -1101,6 +1103,39 @@ func (p *BlobPool) ValidateTxBasics(tx *types.Transaction) error { return txpool.ValidateTransaction(tx, p.head, p.signer, opts) } +// checkDelegationLimit determines if the tx sender is delegated or has a +// pending delegation, and if so, ensures they have at most one in-flight +// **executable** transaction, e.g. disallow stacked and gapped transactions +// from the account. +func (p *BlobPool) checkDelegationLimit(tx *types.Transaction) error { + from, _ := types.Sender(p.signer, tx) // validated + + // Short circuit if the sender has neither delegation nor pending delegation. + if p.state.GetCodeHash(from) == types.EmptyCodeHash { + // Because there is no exclusive lock held between different subpools + // when processing transactions, a blob transaction may be accepted + // while other SetCode transactions with pending authorities from the + // same address are also accepted simultaneously. + // + // This scenario is considered acceptable, as the rule primarily ensures + // that attackers cannot easily and endlessly stack blob transactions + // with a delegated or pending delegated sender. + if p.hasPendingAuth == nil || !p.hasPendingAuth(from) { + return nil + } + } + // Allow a single in-flight pending transaction. + pending := p.index[from] + if len(pending) == 0 { + return nil + } + // If account already has a pending transaction, allow replacement only. + if len(pending) == 1 && pending[0].nonce == tx.Nonce() { + return nil + } + return txpool.ErrInflightTxLimitReached +} + // validateTx checks whether a transaction is valid according to the consensus // rules and adheres to some heuristic limits of the local node (price and size). func (p *BlobPool) validateTx(tx *types.Transaction) error { @@ -1141,6 +1176,9 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error { if err := txpool.ValidateTransactionWithState(tx, p.signer, stateOpts); err != nil { return err } + if err := p.checkDelegationLimit(tx); err != nil { + return err + } // If the transaction replaces an existing one, ensure that price bumps are // adhered to. var ( @@ -1369,7 +1407,7 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { // only by this subpool until all transactions are evicted from, _ := types.Sender(p.signer, tx) // already validated above if _, ok := p.index[from]; !ok { - if err := p.reserve(from, true); err != nil { + if err := p.reserver.Hold(from); err != nil { addNonExclusiveMeter.Mark(1) return err } @@ -1381,7 +1419,7 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { // by a return statement before running deferred methods. Take care with // removing or subscoping err as it will break this clause. if err != nil { - p.reserve(from, false) + p.reserver.Release(from) } }() } @@ -1513,7 +1551,7 @@ func (p *BlobPool) drop() { if last { delete(p.index, from) delete(p.spent, from) - p.reserve(from, false) + p.reserver.Release(from) } else { txs[len(txs)-1] = nil txs = txs[:len(txs)-1] @@ -1789,7 +1827,7 @@ func (p *BlobPool) Clear() { // can't happen until Clear releases the reservation lock. Clear cannot // acquire the subpool lock until the transaction addition is completed. for acct := range p.index { - p.reserve(acct, false) + p.reserver.Release(acct) } p.lookup = newLookup() p.index = make(map[common.Address][]*blobTxMeta) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index b7c6cfa51e..4dfba3b52b 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -26,7 +26,6 @@ import ( "math/big" "os" "path/filepath" - "sync" "testing" "github.com/ethereum/go-ethereum/common" @@ -168,33 +167,6 @@ func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { return bc.statedb, nil } -// makeAddressReserver is a utility method to sanity check that accounts are -// properly reserved by the blobpool (no duplicate reserves or unreserves). -func makeAddressReserver() txpool.AddressReserver { - var ( - reserved = make(map[common.Address]struct{}) - lock sync.Mutex - ) - return func(addr common.Address, reserve bool) error { - lock.Lock() - defer lock.Unlock() - - _, exists := reserved[addr] - if reserve { - if exists { - panic("already reserved") - } - reserved[addr] = struct{}{} - return nil - } - if !exists { - panic("not reserved") - } - delete(reserved, addr) - return nil - } -} - // makeTx is a utility method to construct a random blob transaction and sign it // with a valid key, only setting the interesting fields from the perspective of // the blob pool. @@ -433,6 +405,10 @@ func verifyBlobRetrievals(t *testing.T, pool *BlobPool) { } } +func newReserver() *txpool.Reserver { + return txpool.NewReservationTracker().NewHandle(42) +} + // Tests that transactions can be loaded from disk on startup and that they are // correctly discarded if invalid. // @@ -699,8 +675,8 @@ func TestOpenDrops(t *testing.T) { blobfee: uint256.NewInt(params.BlobTxMinBlobGasprice), statedb: statedb, } - pool := New(Config{Datadir: storage}, chain) - if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil { + pool := New(Config{Datadir: storage}, chain, nil) + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { t.Fatalf("failed to create blob pool: %v", err) } defer pool.Close() @@ -817,8 +793,8 @@ func TestOpenIndex(t *testing.T) { blobfee: uint256.NewInt(params.BlobTxMinBlobGasprice), statedb: statedb, } - pool := New(Config{Datadir: storage}, chain) - if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil { + pool := New(Config{Datadir: storage}, chain, nil) + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { t.Fatalf("failed to create blob pool: %v", err) } defer pool.Close() @@ -918,8 +894,8 @@ func TestOpenHeap(t *testing.T) { blobfee: uint256.NewInt(105), statedb: statedb, } - pool := New(Config{Datadir: storage}, chain) - if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil { + pool := New(Config{Datadir: storage}, chain, nil) + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { t.Fatalf("failed to create blob pool: %v", err) } defer pool.Close() @@ -997,8 +973,8 @@ func TestOpenCap(t *testing.T) { blobfee: uint256.NewInt(105), statedb: statedb, } - pool := New(Config{Datadir: storage, Datacap: datacap}, chain) - if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil { + pool := New(Config{Datadir: storage, Datacap: datacap}, chain, nil) + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { t.Fatalf("failed to create blob pool: %v", err) } // Verify that enough transactions have been dropped to get the pool's size @@ -1098,8 +1074,8 @@ func TestChangingSlotterSize(t *testing.T) { blobfee: uint256.NewInt(105), statedb: statedb, } - pool := New(Config{Datadir: storage}, chain) - if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil { + pool := New(Config{Datadir: storage}, chain, nil) + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { t.Fatalf("failed to create blob pool: %v", err) } @@ -1541,8 +1517,8 @@ func TestAdd(t *testing.T) { blobfee: uint256.NewInt(105), statedb: statedb, } - pool := New(Config{Datadir: storage}, chain) - if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil { + pool := New(Config{Datadir: storage}, chain, nil) + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { t.Fatalf("test %d: failed to create blob pool: %v", i, err) } verifyPoolInternals(t, pool) @@ -1638,10 +1614,10 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) { blobfee: uint256.NewInt(blobfee), statedb: statedb, } - pool = New(Config{Datadir: ""}, chain) + pool = New(Config{Datadir: ""}, chain, nil) ) - if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil { + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { b.Fatalf("failed to create blob pool: %v", err) } // Make the pool not use disk (just drop everything). This test never reads diff --git a/core/txpool/errors.go b/core/txpool/errors.go index c38644857e..02f5703b6c 100644 --- a/core/txpool/errors.go +++ b/core/txpool/errors.go @@ -56,4 +56,8 @@ var ( // input transaction of non-blob type when a blob transaction from this sender // remains pending (and vice-versa). ErrAlreadyReserved = errors.New("address already reserved") + + // ErrInflightTxLimitReached is returned when the maximum number of in-flight + // transactions is reached for specific accounts. + ErrInflightTxLimitReached = errors.New("in-flight transaction limit reached for delegated accounts") ) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 9066f3e16b..278ad0791f 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -63,10 +63,6 @@ var ( // another remote transaction. ErrTxPoolOverflow = errors.New("txpool is full") - // ErrInflightTxLimitReached is returned when the maximum number of in-flight - // transactions is reached for specific accounts. - ErrInflightTxLimitReached = errors.New("in-flight transaction limit reached for delegated accounts") - // ErrOutOfOrderTxFromDelegated is returned when the transaction with gapped // nonce received from the accounts with delegation or pending delegation. ErrOutOfOrderTxFromDelegated = errors.New("gapped-nonce tx from delegated accounts") @@ -241,8 +237,8 @@ type LegacyPool struct { currentHead atomic.Pointer[types.Header] // Current head of the blockchain currentState *state.StateDB // Current state in the blockchain head pendingNonces *noncer // Pending state tracking virtual nonces + reserver *txpool.Reserver // Address reserver to ensure exclusivity across subpools - reserve txpool.AddressReserver // Address reserver to ensure exclusivity across subpools pending map[common.Address]*list // All currently processable transactions queue map[common.Address]*list // Queued but non-processable transactions beats map[common.Address]time.Time // Last heartbeat from each known account @@ -306,9 +302,9 @@ func (pool *LegacyPool) Filter(tx *types.Transaction) bool { // Init sets the gas price needed to keep a transaction in the pool and the chain // head to allow balance / nonce checks. The internal // goroutines will be spun up and the pool deemed operational afterwards. -func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserve txpool.AddressReserver) error { +func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserver *txpool.Reserver) error { // Set the address reserver to request exclusive access to pooled accounts - pool.reserve = reserve + pool.reserver = reserver // Set the basic pool parameters pool.gasTip.Store(uint256.NewInt(gasTip)) @@ -618,7 +614,7 @@ func (pool *LegacyPool) checkDelegationLimit(tx *types.Transaction) error { from, _ := types.Sender(pool.signer, tx) // validated // Short circuit if the sender has neither delegation nor pending delegation. - if pool.currentState.GetCodeHash(from) == types.EmptyCodeHash && pool.all.delegationTxsCount(from) == 0 { + if pool.currentState.GetCodeHash(from) == types.EmptyCodeHash && !pool.all.hasAuth(from) { return nil } pending := pool.pending[from] @@ -633,7 +629,7 @@ func (pool *LegacyPool) checkDelegationLimit(tx *types.Transaction) error { if pending.Contains(tx.Nonce()) { return nil } - return ErrInflightTxLimitReached + return txpool.ErrInflightTxLimitReached } // validateAuth verifies that the transaction complies with code authorization @@ -644,12 +640,24 @@ func (pool *LegacyPool) validateAuth(tx *types.Transaction) error { if err := pool.checkDelegationLimit(tx); err != nil { return err } - // Authorities cannot conflict with any pending or queued transactions. + // Authorities must not conflict with any pending or queued transactions, + // nor with addresses that have already been reserved. if auths := tx.SetCodeAuthorities(); len(auths) > 0 { for _, auth := range auths { if pool.pending[auth] != nil || pool.queue[auth] != nil { return ErrAuthorityReserved } + // Because there is no exclusive lock held between different subpools + // when processing transactions, the SetCode transaction may be accepted + // while other transactions with the same sender address are also + // accepted simultaneously in the other pools. + // + // This scenario is considered acceptable, as the rule primarily ensures + // that attackers cannot easily stack a SetCode transaction when the sender + // is reserved by other pools. + if pool.reserver.Has(auth) { + return ErrAuthorityReserved + } } } return nil @@ -683,7 +691,7 @@ func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) { _, hasQueued = pool.queue[from] ) if !hasPending && !hasQueued { - if err := pool.reserve(from, true); err != nil { + if err := pool.reserver.Hold(from); err != nil { return false, err } defer func() { @@ -694,7 +702,7 @@ func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) { // by a return statement before running deferred methods. Take care with // removing or subscoping err as it will break this clause. if err != nil { - pool.reserve(from, false) + pool.reserver.Release(from) } }() } @@ -1087,7 +1095,7 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo _, hasQueued = pool.queue[addr] ) if !hasPending && !hasQueued { - pool.reserve(addr, false) + pool.reserver.Release(addr) } }() } @@ -1467,7 +1475,7 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T delete(pool.queue, addr) delete(pool.beats, addr) if _, ok := pool.pending[addr]; !ok { - pool.reserve(addr, false) + pool.reserver.Release(addr) } } } @@ -1653,7 +1661,7 @@ func (pool *LegacyPool) demoteUnexecutables() { if list.Empty() { delete(pool.pending, addr) if _, ok := pool.queue[addr]; !ok { - pool.reserve(addr, false) + pool.reserver.Release(addr) } } } @@ -1862,11 +1870,13 @@ func (t *lookup) removeAuthorities(tx *types.Transaction) { } } -// delegationTxsCount returns the number of pending authorizations for the specified address. -func (t *lookup) delegationTxsCount(addr common.Address) int { +// hasAuth returns a flag indicating whether there are pending authorizations +// from the specified address. +func (t *lookup) hasAuth(addr common.Address) bool { t.lock.RLock() defer t.lock.RUnlock() - return len(t.auths[addr]) + + return len(t.auths[addr]) > 0 } // numSlots calculates the number of slots needed for a single transaction. @@ -1880,8 +1890,8 @@ func (pool *LegacyPool) Clear() { pool.mu.Lock() defer pool.mu.Unlock() - // unreserve each tracked account. Ideally, we could just clear the - // reservation map in the parent txpool context. However, if we clear in + // unreserve each tracked account. Ideally, we could just clear the + // reservation map in the parent txpool context. However, if we clear in // parent context, to avoid exposing the subpool lock, we have to lock the // reservations and then lock each subpool. // @@ -1892,11 +1902,11 @@ func (pool *LegacyPool) Clear() { // * TxPool.Clear attempts to lock subpool mutex // // The transaction addition may attempt to reserve the sender addr which - // can't happen until Clear releases the reservation lock. Clear cannot + // can't happen until Clear releases the reservation lock. Clear cannot // acquire the subpool lock until the transaction addition is completed. for _, tx := range pool.all.txs { senderAddr, _ := types.Sender(pool.signer, tx) - pool.reserve(senderAddr, false) + pool.reserver.Release(senderAddr) } pool.all = newLookup() pool.priced = newPricedList(pool.all) @@ -1904,3 +1914,9 @@ func (pool *LegacyPool) Clear() { pool.queue = make(map[common.Address]*list) pool.pendingNonces = newNoncer(pool.currentState) } + +// HasPendingAuth returns a flag indicating whether there are pending +// authorizations from the specific address cached in the pool. +func (pool *LegacyPool) HasPendingAuth(addr common.Address) bool { + return pool.all.hasAuth(addr) +} diff --git a/core/txpool/legacypool/legacypool2_test.go b/core/txpool/legacypool/legacypool2_test.go index d55e85d74f..3f210e3d1b 100644 --- a/core/txpool/legacypool/legacypool2_test.go +++ b/core/txpool/legacypool/legacypool2_test.go @@ -86,7 +86,7 @@ func TestTransactionFutureAttack(t *testing.T) { config.GlobalQueue = 100 config.GlobalSlots = 100 pool := New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() fillPool(t, pool) pending, _ := pool.Stats() @@ -120,7 +120,7 @@ func TestTransactionFuture1559(t *testing.T) { 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()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create a number of test accounts, fund them and make transactions @@ -153,7 +153,7 @@ func TestTransactionZAttack(t *testing.T) { 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()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create a number of test accounts, fund them and make transactions fillPool(t, pool) @@ -224,7 +224,7 @@ func BenchmarkFutureAttack(b *testing.B) { config.GlobalQueue = 100 config.GlobalSlots = 100 pool := New(config, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() fillPool(b, pool) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 3f269bd69e..c47a655204 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -24,7 +24,6 @@ import ( "math/big" "math/rand" "slices" - "sync" "sync/atomic" "testing" "time" @@ -168,42 +167,21 @@ func pricedSetCodeTxWithAuth(nonce uint64, gaslimit uint64, gasFee, tip *uint256 }) } -func makeAddressReserver() txpool.AddressReserver { - var ( - reserved = make(map[common.Address]struct{}) - lock sync.Mutex - ) - return func(addr common.Address, reserve bool) error { - lock.Lock() - defer lock.Unlock() - - _, exists := reserved[addr] - if reserve { - if exists { - panic("already reserved") - } - reserved[addr] = struct{}{} - return nil - } - if !exists { - panic("not reserved") - } - delete(reserved, addr) - return nil - } -} - func setupPool() (*LegacyPool, *ecdsa.PrivateKey) { return setupPoolWithConfig(params.TestChainConfig) } +func newReserver() *txpool.Reserver { + return txpool.NewReservationTracker().NewHandle(42) +} + func setupPoolWithConfig(config *params.ChainConfig) (*LegacyPool, *ecdsa.PrivateKey) { statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(config, 10000000, statedb, new(event.Feed)) key, _ := crypto.GenerateKey() pool := New(testTxPoolConfig, blockchain) - if err := pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()); err != nil { + if err := pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()); err != nil { panic(err) } // wait for the pool to initialize @@ -336,7 +314,7 @@ func TestStateChangeDuringReset(t *testing.T) { tx1 := transaction(1, 100000, key) pool := New(testTxPoolConfig, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() nonce := pool.Nonce(address) @@ -753,7 +731,7 @@ func TestPostponing(t *testing.T) { blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create two test accounts to produce different gap profiles with @@ -963,7 +941,7 @@ func TestQueueGlobalLimiting(t *testing.T) { config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible) pool := New(config, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create a number of test accounts and fund them (last one will be the local) @@ -1015,7 +993,7 @@ func TestQueueTimeLimiting(t *testing.T) { config.Lifetime = time.Second pool := New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create a test account to ensure remotes expire @@ -1176,7 +1154,7 @@ func TestPendingGlobalLimiting(t *testing.T) { config.GlobalSlots = config.AccountSlots * 10 pool := New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create a number of test accounts and fund them @@ -1275,7 +1253,7 @@ func TestCapClearsFromAll(t *testing.T) { config.GlobalSlots = 8 pool := New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create a number of test accounts and fund them @@ -1308,7 +1286,7 @@ func TestPendingMinimumAllowance(t *testing.T) { config.GlobalSlots = 1 pool := New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create a number of test accounts and fund them @@ -1352,7 +1330,7 @@ func TestRepricing(t *testing.T) { blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Keep track of transaction events to ensure all executables get announced @@ -1457,7 +1435,7 @@ func TestMinGasPriceEnforced(t *testing.T) { txPoolConfig := DefaultConfig txPoolConfig.NoLocals = true pool := New(txPoolConfig, blockchain) - pool.Init(txPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(txPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() key, _ := crypto.GenerateKey() @@ -1606,7 +1584,7 @@ func TestUnderpricing(t *testing.T) { config.GlobalQueue = 2 pool := New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Keep track of transaction events to ensure all executables get announced @@ -1696,7 +1674,7 @@ func TestStableUnderpricing(t *testing.T) { config.GlobalQueue = 0 pool := New(config, blockchain) - pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Keep track of transaction events to ensure all executables get announced @@ -1899,7 +1877,7 @@ func TestDeduplication(t *testing.T) { blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create a test account to add transactions with @@ -1966,7 +1944,7 @@ func TestReplacement(t *testing.T) { blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Keep track of transaction events to ensure all executables get announced @@ -2157,7 +2135,7 @@ func TestStatusCheck(t *testing.T) { blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create the test accounts to check various transaction statuses with @@ -2230,7 +2208,7 @@ func TestSetCodeTransactions(t *testing.T) { blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create the test accounts @@ -2271,12 +2249,12 @@ func TestSetCodeTransactions(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyA)); err != nil { t.Fatalf("%s: failed to add remote transaction: %v", name, err) } - if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrInflightTxLimitReached) { - t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err) + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) } // Check gapped transaction again. - if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrInflightTxLimitReached) { - t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err) + if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) } // Replace by fee. if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyA)); err != nil { @@ -2310,8 +2288,8 @@ func TestSetCodeTransactions(t *testing.T) { t.Fatalf("%s: failed to add with pending delegatio: %v", name, err) } // Also check gapped transaction is rejected. - if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, ErrInflightTxLimitReached) { - t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err) + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) } }, }, @@ -2386,7 +2364,7 @@ func TestSetCodeTransactions(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil { t.Fatalf("%s: failed to added single pooled for account with pending delegation: %v", name, err) } - if err, want := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyC)), ErrInflightTxLimitReached; !errors.Is(err, want) { + if err, want := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyC)), txpool.ErrInflightTxLimitReached; !errors.Is(err, want) { t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err) } }, @@ -2454,7 +2432,7 @@ func TestSetCodeTransactionsReorg(t *testing.T) { blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) - pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) + pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() // Create the test accounts @@ -2489,8 +2467,8 @@ func TestSetCodeTransactionsReorg(t *testing.T) { t.Fatalf("failed to add with remote setcode transaction: %v", err) } // Try to add a transactions in - if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); !errors.Is(err, ErrInflightTxLimitReached) { - t.Fatalf("unexpected error %v, expecting %v", err, ErrInflightTxLimitReached) + if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("unexpected error %v, expecting %v", err, txpool.ErrInflightTxLimitReached) } // Simulate the chain moving blockchain.statedb.SetNonce(addrA, 2, tracing.NonceChangeAuthorization) diff --git a/core/txpool/reserver.go b/core/txpool/reserver.go new file mode 100644 index 0000000000..76ead0f3bb --- /dev/null +++ b/core/txpool/reserver.go @@ -0,0 +1,124 @@ +// Copyright 2025 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 txpool + +import ( + "errors" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +var ( + // reservationsGaugeName is the prefix of a per-subpool address reservation + // metric. + // + // This is mostly a sanity metric to ensure there's no bug that would make + // some subpool hog all the reservations due to mis-accounting. + reservationsGaugeName = "txpool/reservations" +) + +// ReservationTracker is a struct shared between different subpools. It is used to reserve +// the account and ensure that one address cannot initiate transactions, authorizations, +// and other state-changing behaviors in different pools at the same time. +type ReservationTracker struct { + accounts map[common.Address]int + lock sync.RWMutex +} + +// NewReservationTracker initializes the account reservation tracker. +func NewReservationTracker() *ReservationTracker { + return &ReservationTracker{ + accounts: make(map[common.Address]int), + } +} + +// NewHandle creates a named handle on the ReservationTracker. The handle +// identifies the subpool so ownership of reservations can be determined. +func (r *ReservationTracker) NewHandle(id int) *Reserver { + return &Reserver{r, id} +} + +// Reserver is a named handle on ReservationTracker. It is held by subpools to +// make reservations for accounts it is tracking. The id is used to determine +// which pool owns an address and disallows non-owners to hold or release +// addresses it doesn't own. +type Reserver struct { + tracker *ReservationTracker + id int +} + +// Hold attempts to reserve the specified account address for the given pool. +// Returns an error if the account is already reserved. +func (h *Reserver) Hold(addr common.Address) error { + h.tracker.lock.Lock() + defer h.tracker.lock.Unlock() + + // Double reservations are forbidden even from the same pool to + // avoid subtle bugs in the long term. + owner, exists := h.tracker.accounts[addr] + if exists { + if owner == h.id { + log.Error("pool attempted to reserve already-owned address", "address", addr) + return nil // Ignore fault to give the pool a chance to recover while the bug gets fixed + } + return ErrAlreadyReserved + } + h.tracker.accounts[addr] = h.id + if metrics.Enabled() { + m := fmt.Sprintf("%s/%d", reservationsGaugeName, h.id) + metrics.GetOrRegisterGauge(m, nil).Inc(1) + } + return nil +} + +// Release attempts to release the reservation for the specified account. +// Returns an error if the address is not reserved or is reserved by another pool. +func (h *Reserver) Release(addr common.Address) error { + h.tracker.lock.Lock() + defer h.tracker.lock.Unlock() + + // Ensure subpools only attempt to unreserve their own owned addresses, + // otherwise flag as a programming error. + owner, exists := h.tracker.accounts[addr] + if !exists { + log.Error("pool attempted to unreserve non-reserved address", "address", addr) + return errors.New("address not reserved") + } + if owner != h.id { + log.Error("pool attempted to unreserve non-owned address", "address", addr) + return errors.New("address not owned") + } + delete(h.tracker.accounts, addr) + if metrics.Enabled() { + m := fmt.Sprintf("%s/%d", reservationsGaugeName, h.id) + metrics.GetOrRegisterGauge(m, nil).Dec(1) + } + return nil +} + +// Has returns a flag indicating if the address has been reserved or not. +func (h *Reserver) Has(address common.Address) bool { + h.tracker.lock.RLock() + defer h.tracker.lock.RUnlock() + + _, exists := h.tracker.accounts[address] + return exists +} diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index f5cb852d8f..2cb5103875 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -67,10 +67,6 @@ type LazyResolver interface { Get(hash common.Hash) *types.Transaction } -// AddressReserver is passed by the main transaction pool to subpools, so they -// may request (and relinquish) exclusive access to certain addresses. -type AddressReserver func(addr common.Address, reserve bool) error - // PendingFilter is a collection of filter rules to allow retrieving a subset // of transactions for announcement or mining. // @@ -109,7 +105,7 @@ type SubPool interface { // These should not be passed as a constructor argument - nor should the pools // start by themselves - in order to keep multiple subpools in lockstep with // one another. - Init(gasTip uint64, head *types.Header, reserve AddressReserver) error + Init(gasTip uint64, head *types.Header, reserver *Reserver) error // Close terminates any background processing threads and releases any held // resources. diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 083aac92c6..47d83e03d4 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -29,7 +29,6 @@ import ( "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" ) @@ -43,15 +42,6 @@ const ( TxStatusIncluded ) -var ( - // reservationsGaugeName is the prefix of a per-subpool address reservation - // metric. - // - // This is mostly a sanity metric to ensure there's no bug that would make - // some subpool hog all the reservations due to mis-accounting. - reservationsGaugeName = "txpool/reservations" -) - // BlockChain defines the minimal set of methods needed to back a tx pool with // a chain. Exists to allow mocking the live chain out of tests. type BlockChain interface { @@ -81,9 +71,6 @@ type TxPool struct { stateLock sync.RWMutex // The lock for protecting state instance state *state.StateDB // Current state at the blockchain head - reservations map[common.Address]SubPool // Map with the account to pool reservations - reserveLock sync.Mutex // Lock protecting the account reservations - subs event.SubscriptionScope // Subscription scope to unsubscribe all on shutdown quit chan chan error // Quit channel to tear down the head updater term chan struct{} // Termination channel to detect a closed pool @@ -110,17 +97,17 @@ func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) { return nil, err } pool := &TxPool{ - subpools: subpools, - chain: chain, - signer: types.LatestSigner(chain.Config()), - state: statedb, - reservations: make(map[common.Address]SubPool), - quit: make(chan chan error), - term: make(chan struct{}), - sync: make(chan chan error), + subpools: subpools, + chain: chain, + signer: types.LatestSigner(chain.Config()), + state: statedb, + quit: make(chan chan error), + term: make(chan struct{}), + sync: make(chan chan error), } + reserver := NewReservationTracker() for i, subpool := range subpools { - if err := subpool.Init(gasTip, head, pool.reserver(i, subpool)); err != nil { + if err := subpool.Init(gasTip, head, reserver.NewHandle(i)); err != nil { for j := i - 1; j >= 0; j-- { subpools[j].Close() } @@ -131,52 +118,6 @@ func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) { return pool, nil } -// reserver is a method to create an address reservation callback to exclusively -// assign/deassign addresses to/from subpools. This can ensure that at any point -// in time, only a single subpool is able to manage an account, avoiding cross -// subpool eviction issues and nonce conflicts. -func (p *TxPool) reserver(id int, subpool SubPool) AddressReserver { - return func(addr common.Address, reserve bool) error { - p.reserveLock.Lock() - defer p.reserveLock.Unlock() - - owner, exists := p.reservations[addr] - if reserve { - // Double reservations are forbidden even from the same pool to - // avoid subtle bugs in the long term. - if exists { - if owner == subpool { - log.Error("pool attempted to reserve already-owned address", "address", addr) - return nil // Ignore fault to give the pool a chance to recover while the bug gets fixed - } - return ErrAlreadyReserved - } - p.reservations[addr] = subpool - if metrics.Enabled() { - m := fmt.Sprintf("%s/%d", reservationsGaugeName, id) - metrics.GetOrRegisterGauge(m, nil).Inc(1) - } - return nil - } - // Ensure subpools only attempt to unreserve their own owned addresses, - // otherwise flag as a programming error. - if !exists { - log.Error("pool attempted to unreserve non-reserved address", "address", addr) - return errors.New("address not reserved") - } - if subpool != owner { - log.Error("pool attempted to unreserve non-owned address", "address", addr) - return errors.New("address not owned") - } - delete(p.reservations, addr) - if metrics.Enabled() { - m := fmt.Sprintf("%s/%d", reservationsGaugeName, id) - metrics.GetOrRegisterGauge(m, nil).Dec(1) - } - return nil - } -} - // Close terminates the transaction pool and all its subpools. func (p *TxPool) Close() error { var errs []error diff --git a/eth/backend.go b/eth/backend.go index 79759710b6..6716a77562 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -260,16 +260,16 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { eth.filterMaps = filtermaps.NewFilterMaps(chainDb, chainView, historyCutoff, finalBlock, filtermaps.DefaultParams, fmConfig) eth.closeFilterMaps = make(chan chan struct{}) - if config.BlobPool.Datadir != "" { - config.BlobPool.Datadir = stack.ResolvePath(config.BlobPool.Datadir) - } - blobPool := blobpool.New(config.BlobPool, eth.blockchain) - if config.TxPool.Journal != "" { config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal) } legacyPool := legacypool.New(config.TxPool, eth.blockchain) + if config.BlobPool.Datadir != "" { + config.BlobPool.Datadir = stack.ResolvePath(config.BlobPool.Datadir) + } + blobPool := blobpool.New(config.BlobPool, eth.blockchain, legacyPool.HasPendingAuth) + eth.txPool, err = txpool.New(config.TxPool.PriceLimit, eth.blockchain, []txpool.SubPool{legacyPool, blobPool}) if err != nil { return nil, err diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index bbbd888701..fa031d9899 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -135,7 +135,7 @@ func newTestBackendWithGenerator(blocks int, shanghai bool, cancun bool, generat storage, _ := os.MkdirTemp("", "blobpool-") defer os.RemoveAll(storage) - blobPool := blobpool.New(blobpool.Config{Datadir: storage}, chain) + blobPool := blobpool.New(blobpool.Config{Datadir: storage}, chain, nil) legacyPool := legacypool.New(txconfig, chain) txpool, _ := txpool.New(txconfig.PriceLimit, chain, []txpool.SubPool{legacyPool, blobPool}) From 5cc9137c9cec8a977b845a025d3deced9457fd48 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 8 Apr 2025 19:57:45 +0200 Subject: [PATCH 274/940] core/vm: optimize push2 opcode (#31267) During my benchmarks on Holesky, around 10% of all CPU time was spent in PUSH2 ``` ROUTINE ======================== github.com/ethereum/go-ethereum/core/vm.newFrontierInstructionSet.makePush.func1 in github.com/ethereum/go-ethereum/core/vm/instructions.go 16.38s 20.35s (flat, cum) 10.31% of Total 740ms 740ms 976: return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { . . 977: var ( 40ms 40ms 978: codeLen = len(scope.Contract.Code) 970ms 970ms 979: start = min(codeLen, int(*pc+1)) 200ms 200ms 980: end = min(codeLen, start+pushByteSize) . . 981: ) 670ms 2.39s 982: a := new(uint256.Int).SetBytes(scope.Contract.Code[start:end]) . . 983: . . 984: // Missing bytes: pushByteSize - len(pushData) 410ms 410ms 985: if missing := pushByteSize - (end - start); missing > 0 { . . 986: a.Lsh(a, uint(8*missing)) . . 987: } 12.69s 14.94s 988: scope.Stack.push2(*a) 10ms 10ms 989: *pc += size 650ms 650ms 990: return nil, nil . . 991: } . . 992:} ``` Which is quite crazy. We have a handwritten encoder for PUSH1 already, this PR adds one for PUSH2. PUSH2 is the second most used opcode as shown here: https://gist.github.com/shemnon/fb9b292a103abb02d98d64df6fbd35c8 since it is used by solidity quite significantly. Its used ~20 times as much as PUSH20 and PUSH32. # Benchmarks ``` BenchmarkPush/makePush-14 94196547 12.27 ns/op 0 B/op 0 allocs/op BenchmarkPush/push-14 429976924 2.829 ns/op 0 B/op 0 allocs/op ``` --------- Co-authored-by: jwasinger --- core/vm/instructions.go | 17 +++++++++++++++++ core/vm/jump_table.go | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 1785ffc139..0b3b1d1569 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -971,6 +971,23 @@ func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by return nil, nil } +// opPush2 is a specialized version of pushN +func opPush2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + var ( + codeLen = uint64(len(scope.Contract.Code)) + integer = new(uint256.Int) + ) + if *pc+2 < codeLen { + scope.Stack.push(integer.SetBytes2(scope.Contract.Code[*pc+1 : *pc+3])) + } else if *pc+1 < codeLen { + scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc+1]) << 8)) + } else { + scope.Stack.push(integer.Clear()) + } + *pc += 2 + return nil, nil +} + // make push instruction function func makePush(size uint64, pushByteSize int) executionFunc { return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 6610fa7f9a..ee811b447e 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -631,7 +631,7 @@ func newFrontierInstructionSet() JumpTable { maxStack: maxStack(0, 1), }, PUSH2: { - execute: makePush(2, 2), + execute: opPush2, constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), From a7f24c26c0a6a73357d76adf64d98f343bafd0e5 Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Wed, 9 Apr 2025 11:28:29 +0200 Subject: [PATCH 275/940] p2p/nat: fix UPnP port reset (#31566) Make UPnP more robust - Once a random port was mapped, we try to stick to it even if a UPnP refresh fails. Previously we were immediately moving back to try the default port, leading to frequent ENR changes. - We were deleting port mappings before refresh as a possible workaround. This created issues in some UPnP servers. The UPnP (and PMP) specification is explicit about the refresh requirements, and delete is clearly not needed (see https://github.com/ethereum/go-ethereum/pull/30265#issuecomment-2766987859). From now on we only delete when closing. - We were trying to add port mappings only once, and then moved on to random ports. Now we insist a bit more, so that a simple failed request won't lead to ENR changes. Fixes https://github.com/ethereum/go-ethereum/issues/31418 --------- Signed-off-by: Csaba Kiraly Co-authored-by: Felix Lange --- p2p/nat/natupnp.go | 49 +++++++++++++++++++++++++-------------- p2p/server_nat.go | 57 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 72 insertions(+), 34 deletions(-) diff --git a/p2p/nat/natupnp.go b/p2p/nat/natupnp.go index ed00b8eeb6..d79677db55 100644 --- a/p2p/nat/natupnp.go +++ b/p2p/nat/natupnp.go @@ -26,6 +26,7 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/log" "github.com/huin/goupnp" "github.com/huin/goupnp/dcps/internetgateway1" "github.com/huin/goupnp/dcps/internetgateway2" @@ -34,6 +35,8 @@ import ( const ( soapRequestTimeout = 3 * time.Second rateLimit = 200 * time.Millisecond + retryCount = 3 // number of retries after a failed AddPortMapping + randomCount = 3 // number of random ports to try ) type upnp struct { @@ -89,42 +92,43 @@ func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, li if extport == 0 { extport = intport - } else { - // Only delete port mapping if the external port was already used by geth. - n.DeleteMapping(protocol, extport, intport) } // Try to add port mapping, preferring the specified external port. - err = n.withRateLimit(func() error { - p, err := n.addAnyPortMapping(protocol, extport, intport, ip, desc, lifetimeS) - if err == nil { - extport = int(p) - } - return err - }) - return uint16(extport), err + return n.addAnyPortMapping(protocol, extport, intport, ip, desc, lifetimeS) } // addAnyPortMapping tries to add a port mapping with the specified external port. // If the external port is already in use, it will try to assign another port. func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.IP, desc string, lifetimeS uint32) (uint16, error) { if client, ok := n.client.(*internetgateway2.WANIPConnection2); ok { - return client.AddAnyPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) + return n.portWithRateLimit(func() (uint16, error) { + return client.AddAnyPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) + }) } // For IGDv1 and v1 services we should first try to add with extport. - err := n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) - if err == nil { - return uint16(extport), nil + for i := 0; i < retryCount+1; i++ { + err := n.withRateLimit(func() error { + return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) + }) + if err == nil { + return uint16(extport), nil + } + log.Debug("Failed to add port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", err) } // If above fails, we retry with a random port. // We retry several times because of possible port conflicts. - for i := 0; i < 3; i++ { + var err error + for i := 0; i < randomCount; i++ { extport = n.randomPort() - err := n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) + err := n.withRateLimit(func() error { + return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) + }) if err == nil { return uint16(extport), nil } + log.Debug("Failed to add random port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", err) } return 0, err } @@ -169,6 +173,17 @@ func (n *upnp) String() string { return "UPNP " + n.service } +func (n *upnp) portWithRateLimit(pfn func() (uint16, error)) (uint16, error) { + var port uint16 + var err error + fn := func() error { + port, err = pfn() + return err + } + n.withRateLimit(fn) + return port, err +} + func (n *upnp) withRateLimit(fn func() error) error { n.mu.Lock() defer n.mu.Unlock() diff --git a/p2p/server_nat.go b/p2p/server_nat.go index 5830f950e1..298c454a4a 100644 --- a/p2p/server_nat.go +++ b/p2p/server_nat.go @@ -31,12 +31,14 @@ const ( portMapRefreshInterval = 8 * time.Minute portMapRetryInterval = 5 * time.Minute extipRetryInterval = 2 * time.Minute + maxRetries = 5 // max number of failed attempts to refresh the mapping ) type portMapping struct { protocol string name string port int + retries int // number of failed attempts to refresh the mapping // for use by the portMappingLoop goroutine: extPort int // the mapped port returned by the NAT interface @@ -154,28 +156,49 @@ func (srv *Server) portMappingLoop() { log.Trace("Attempting port mapping") p, err := srv.NAT.AddMapping(m.protocol, m.extPort, m.port, m.name, portMapDuration) if err != nil { - log.Debug("Couldn't add port mapping", "err", err) - m.extPort = 0 + // Failed to add or refresh port mapping. + if m.extPort == 0 { + log.Debug("Couldn't add port mapping", "err", err) + } else { + // Failed refresh. Since UPnP implementation are often buggy, + // and lifetime is larger than the retry interval, this does not + // mean we lost our existing mapping. We do not reset the external + // port, as it is still our best chance, but we do retry soon. + // We could check the error code, but UPnP implementations are buggy. + log.Debug("Couldn't refresh port mapping", "err", err) + m.retries++ + if m.retries > maxRetries { + m.retries = 0 + err := srv.NAT.DeleteMapping(m.protocol, m.extPort, m.port) + log.Debug("Couldn't refresh port mapping, trying to delete it:", "err", err) + m.extPort = 0 + } + } m.nextTime = srv.clock.Now().Add(portMapRetryInterval) + // Note ENR is not updated here, i.e. we keep the last port. continue } - // It was mapped! - m.extPort = int(p) - m.nextTime = srv.clock.Now().Add(portMapRefreshInterval) - log = newLogger(m.protocol, m.extPort, m.port) - if m.port != m.extPort { - log.Info("NAT mapped alternative port") - } else { - log.Info("NAT mapped port") - } - // Update port in local ENR. - switch m.protocol { - case "TCP": - srv.localnode.Set(enr.TCP(m.extPort)) - case "UDP": - srv.localnode.SetFallbackUDP(m.extPort) + // It was mapped! + m.retries = 0 + log = newLogger(m.protocol, int(p), m.port) + if int(p) != m.extPort { + m.extPort = int(p) + if m.port != m.extPort { + log.Info("NAT mapped alternative port") + } else { + log.Info("NAT mapped port") + } + + // Update port in local ENR. + switch m.protocol { + case "TCP": + srv.localnode.Set(enr.TCP(m.extPort)) + case "UDP": + srv.localnode.SetFallbackUDP(m.extPort) + } } + m.nextTime = srv.clock.Now().Add(portMapRefreshInterval) } } } From 60b922fd529237ac5070a1750c93a4c132ed32fb Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Wed, 9 Apr 2025 14:19:28 -0600 Subject: [PATCH 276/940] core/txpool: add notice to` Clear` that is not meant for production code (#31567) The `Sync(..)` function explicitly says not to rely on in production code, but it is used in `Clear(..)` so should add a similar mention. --- core/txpool/blobpool/blobpool.go | 6 ++++++ core/txpool/legacypool/legacypool.go | 7 +++++-- core/txpool/txpool.go | 11 +++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index b1966905a8..1770066a8d 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1349,6 +1349,9 @@ func (p *BlobPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844. // Add inserts a set of blob transactions into the pool if they pass validation (both // consensus validity and pool restrictions). +// +// Note, if sync is set the method will block until all internal maintenance +// related to the add is finished. Only use this during tests for determinism. func (p *BlobPool) Add(txs []*types.Transaction, sync bool) []error { var ( adds = make([]*types.Transaction, 0, len(txs)) @@ -1792,6 +1795,9 @@ func (p *BlobPool) Status(hash common.Hash) txpool.TxStatus { // Clear implements txpool.SubPool, removing all tracked transactions // from the blob pool and persistent store. +// +// Note, do not use this in production / live code. In live code, the pool is +// meant to reset on a separate thread to avoid DoS vectors. func (p *BlobPool) Clear() { p.lock.Lock() defer p.lock.Unlock() diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 278ad0791f..75dc4a8461 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -927,8 +927,8 @@ func (pool *LegacyPool) addRemoteSync(tx *types.Transaction) error { // Add enqueues a batch of transactions into the pool if they are valid. // -// If sync is set, the method will block until all internal maintenance related -// to the add is finished. Only use this during tests for determinism! +// Note, if sync is set the method will block until all internal maintenance +// related to the add is finished. Only use this during tests for determinism. func (pool *LegacyPool) Add(txs []*types.Transaction, sync bool) []error { // Filter out known ones without obtaining the pool lock or recovering signatures var ( @@ -1886,6 +1886,9 @@ func numSlots(tx *types.Transaction) int { // Clear implements txpool.SubPool, removing all tracked txs from the pool // and rotating the journal. +// +// Note, do not use this in production / live code. In live code, the pool is +// meant to reset on a separate thread to avoid DoS vectors. func (pool *LegacyPool) Clear() { pool.mu.Lock() defer pool.mu.Unlock() diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 47d83e03d4..2ed38772ce 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -350,6 +350,9 @@ func (p *TxPool) ValidateTxBasics(tx *types.Transaction) error { // Add enqueues a batch of transactions into the pool if they are valid. Due // to the large transaction churn, add may postpone fully integrating the tx // to a later point to batch multiple ones together. +// +// Note, if sync is set the method will block until all internal maintenance +// related to the add is finished. Only use this during tests for determinism. func (p *TxPool) Add(txs []*types.Transaction, sync bool) []error { // Split the input transactions between the subpools. It shouldn't really // happen that we receive merged batches, but better graceful than strange @@ -503,8 +506,8 @@ func (p *TxPool) Status(hash common.Hash) TxStatus { // internal background reset operations. This method will run an explicit reset // operation to ensure the pool stabilises, thus avoiding flakey behavior. // -// Note, do not use this in production / live code. In live code, the pool is -// meant to reset on a separate thread to avoid DoS vectors. +// Note, this method is only used for testing and is susceptible to DoS vectors. +// In production code, the pool is meant to reset on a separate thread. func (p *TxPool) Sync() error { sync := make(chan error) select { @@ -516,6 +519,10 @@ func (p *TxPool) Sync() error { } // Clear removes all tracked txs from the subpools. +// +// Note, this method invokes Sync() and is only used for testing, because it is +// susceptible to DoS vectors. In production code, the pool is meant to reset on +// a separate thread. func (p *TxPool) Clear() { // Invoke Sync to ensure that txs pending addition don't get added to the pool after // the subpools are subsequently cleared From 0c2ad076734e87fcc008e4718ba7b1f4f881b1fa Mon Sep 17 00:00:00 2001 From: Luis Ayuso Date: Thu, 10 Apr 2025 03:11:24 +0200 Subject: [PATCH 277/940] core/txpool: allow tx and authority regardless of admission order (#31373) This PR proposes a change to the authorizations' validation introduced in commit cdb66c8. These changes make the expected behavior independent of the order of admission of authorizations, improving the predictability of the resulting state and the usability of the system with it. The current implementation behavior is dependent on the transaction submission order: This issue is related to authorities and the sender of a transaction, and can be reproduced respecting the normal nonce rules. The issue can be reproduced by the two following cases: **First case** - Given an empty pool. - Submit transaction `{ from: B, auths [ A ] }`: is accepted. - Submit transaction `{ from: A }`: Is accepted: it becomes the one in-flight transaction allowed. **Second case** - Given an empty pool. - Submit transaction `{ from: A }`: is accepted - Submit transaction `{ from: B, auths [ A ] }`: is rejected since there is already a queued/pending transaction from A. The expected behavior is that both sequences of events would lead to the same sets of accepted and rejected transactions. **Proposed changes** The queued/pending transactions issued from any authority of the transaction being validated have to be counted, allowing one transaction from accounts submitting an authorization. - Notice that the expected behavior was explicitly forbidden in the case "reject-delegation-from-pending-account", I believe that this behavior conflicts to the definition of the limitation, and it is removed in this PR. The expected behavior is tested in "accept-authorization-from-sender-of-one-inflight-tx". - Replacement tests have been separated to improve readability of the acceptance test. - The test "allow-more-than-one-tx-from-replaced-authority" has been extended with one extra transaction, since the system would always have accepted one transaction (but not two). - The test "accept-one-inflight-tx-of-delegated-account" is extended to clean-up state, avoiding leaking the delegation used into the other tests. Additionally, replacement check is removed to be tested in its own test case. **Expected behavior** The expected behavior of the authorizations' validation shall be as follows: ![image](https://github.com/user-attachments/assets/dbde7a1f-9679-4691-94eb-c197a0cbb823) Notice that replacement shall be allowed, and behavior shall remain coherent with the table, according to the replaced transaction. --------- Co-authored-by: lightclient --- core/txpool/blobpool/blobpool.go | 4 +- core/txpool/blobpool/blobpool_test.go | 43 ++++- core/txpool/legacypool/legacypool.go | 28 ++- core/txpool/legacypool/legacypool_test.go | 198 +++++++++++++++++----- core/txpool/reserver.go | 42 +++-- core/txpool/subpool.go | 2 +- 6 files changed, 242 insertions(+), 75 deletions(-) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 1770066a8d..12a4133b40 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -299,7 +299,7 @@ func newBlobTxMeta(id uint64, size uint64, storageSize uint32, tx *types.Transac // and leading up to the first no-change. type BlobPool struct { config Config // Pool configuration - reserver *txpool.Reserver // Address reserver to ensure exclusivity across subpools + reserver txpool.Reserver // Address reserver to ensure exclusivity across subpools hasPendingAuth func(common.Address) bool // Determine whether the specified address has a pending 7702-auth store billy.Database // Persistent data store for the tx metadata and blobs @@ -355,7 +355,7 @@ func (p *BlobPool) Filter(tx *types.Transaction) bool { // Init sets the gas price needed to keep a transaction in the pool and the chain // head to allow balance / nonce checks. The transaction journal will be loaded // from disk and filtered based on the provided starting settings. -func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver *txpool.Reserver) error { +func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reserver) error { p.reserver = reserver var ( diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 4dfba3b52b..76d21a0c9e 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -26,6 +26,7 @@ import ( "math/big" "os" "path/filepath" + "sync" "testing" "github.com/ethereum/go-ethereum/common" @@ -167,6 +168,44 @@ func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { return bc.statedb, nil } +// reserver is a utility struct to sanity check that accounts are +// properly reserved by the blobpool (no duplicate reserves or unreserves). +type reserver struct { + accounts map[common.Address]struct{} + lock sync.RWMutex +} + +func newReserver() txpool.Reserver { + return &reserver{accounts: make(map[common.Address]struct{})} +} + +func (r *reserver) Hold(addr common.Address) error { + r.lock.Lock() + defer r.lock.Unlock() + if _, exists := r.accounts[addr]; exists { + panic("already reserved") + } + r.accounts[addr] = struct{}{} + return nil +} + +func (r *reserver) Release(addr common.Address) error { + r.lock.Lock() + defer r.lock.Unlock() + if _, exists := r.accounts[addr]; !exists { + panic("not reserved") + } + delete(r.accounts, addr) + return nil +} + +func (r *reserver) Has(address common.Address) bool { + r.lock.RLock() + defer r.lock.RUnlock() + _, exists := r.accounts[address] + return exists +} + // makeTx is a utility method to construct a random blob transaction and sign it // with a valid key, only setting the interesting fields from the perspective of // the blob pool. @@ -405,10 +444,6 @@ func verifyBlobRetrievals(t *testing.T, pool *BlobPool) { } } -func newReserver() *txpool.Reserver { - return txpool.NewReservationTracker().NewHandle(42) -} - // Tests that transactions can be loaded from disk on startup and that they are // correctly discarded if invalid. // diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 75dc4a8461..04f1a2234c 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -237,7 +237,7 @@ type LegacyPool struct { currentHead atomic.Pointer[types.Header] // Current head of the blockchain currentState *state.StateDB // Current state in the blockchain head pendingNonces *noncer // Pending state tracking virtual nonces - reserver *txpool.Reserver // Address reserver to ensure exclusivity across subpools + reserver txpool.Reserver // Address reserver to ensure exclusivity across subpools pending map[common.Address]*list // All currently processable transactions queue map[common.Address]*list // Queued but non-processable transactions @@ -302,7 +302,7 @@ func (pool *LegacyPool) Filter(tx *types.Transaction) bool { // Init sets the gas price needed to keep a transaction in the pool and the chain // head to allow balance / nonce checks. The internal // goroutines will be spun up and the pool deemed operational afterwards. -func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserver *txpool.Reserver) error { +func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reserver) error { // Set the address reserver to request exclusive access to pooled accounts pool.reserver = reserver @@ -640,11 +640,18 @@ func (pool *LegacyPool) validateAuth(tx *types.Transaction) error { if err := pool.checkDelegationLimit(tx); err != nil { return err } - // Authorities must not conflict with any pending or queued transactions, - // nor with addresses that have already been reserved. + // For symmetry, allow at most one in-flight tx for any authority with a + // pending transaction. if auths := tx.SetCodeAuthorities(); len(auths) > 0 { for _, auth := range auths { - if pool.pending[auth] != nil || pool.queue[auth] != nil { + var count int + if pending := pool.pending[auth]; pending != nil { + count += pending.Len() + } + if queue := pool.queue[auth]; queue != nil { + count += queue.Len() + } + if count > 1 { return ErrAuthorityReserved } // Because there is no exclusive lock held between different subpools @@ -1907,9 +1914,14 @@ func (pool *LegacyPool) Clear() { // The transaction addition may attempt to reserve the sender addr which // can't happen until Clear releases the reservation lock. Clear cannot // acquire the subpool lock until the transaction addition is completed. - for _, tx := range pool.all.txs { - senderAddr, _ := types.Sender(pool.signer, tx) - pool.reserver.Release(senderAddr) + + for addr := range pool.pending { + if _, ok := pool.queue[addr]; !ok { + pool.reserver.Release(addr) + } + } + for addr := range pool.queue { + pool.reserver.Release(addr) } pool.all = newLookup() pool.priced = newPricedList(pool.all) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index c47a655204..bb1323a7d1 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -24,6 +24,7 @@ import ( "math/big" "math/rand" "slices" + "sync" "sync/atomic" "testing" "time" @@ -171,8 +172,39 @@ func setupPool() (*LegacyPool, *ecdsa.PrivateKey) { return setupPoolWithConfig(params.TestChainConfig) } -func newReserver() *txpool.Reserver { - return txpool.NewReservationTracker().NewHandle(42) +// reserver is a utility struct to sanity check that accounts are +// properly reserved by the blobpool (no duplicate reserves or unreserves). +type reserver struct { + accounts map[common.Address]struct{} + lock sync.RWMutex +} + +func newReserver() txpool.Reserver { + return &reserver{accounts: make(map[common.Address]struct{})} +} + +func (r *reserver) Hold(addr common.Address) error { + r.lock.Lock() + defer r.lock.Unlock() + if _, exists := r.accounts[addr]; exists { + panic("already reserved") + } + r.accounts[addr] = struct{}{} + return nil +} + +func (r *reserver) Release(addr common.Address) error { + r.lock.Lock() + defer r.lock.Unlock() + if _, exists := r.accounts[addr]; !exists { + panic("not reserved") + } + delete(r.accounts, addr) + return nil +} + +func (r *reserver) Has(address common.Address) bool { + return false // reserver only supports a single pool } func setupPoolWithConfig(config *params.ChainConfig) (*LegacyPool, *ecdsa.PrivateKey) { @@ -2232,9 +2264,8 @@ func TestSetCodeTransactions(t *testing.T) { }{ { // Check that only one in-flight transaction is allowed for accounts - // with delegation set. Also verify the accepted transaction can be - // replaced by fee. - name: "only-one-in-flight", + // with delegation set. + name: "accept-one-inflight-tx-of-delegated-account", pending: 1, run: func(name string) { aa := common.Address{0xaa, 0xaa} @@ -2249,6 +2280,7 @@ func TestSetCodeTransactions(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyA)); err != nil { t.Fatalf("%s: failed to add remote transaction: %v", name, err) } + // Second and further transactions shall be rejected if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) } @@ -2260,6 +2292,70 @@ func TestSetCodeTransactions(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyA)); err != nil { t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) } + + // Reset the delegation, avoid leaking state into the other tests + statedb.SetCode(addrA, nil) + }, + }, + { + // This test is analogous to the previous one, but the delegation is pending + // instead of set. + name: "allow-one-tx-from-pooled-delegation", + pending: 2, + run: func(name string) { + // Create a pending delegation request from B. + if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{0, keyB}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + // First transaction from B is accepted. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyB)); err != nil { + t.Fatalf("%s: failed to add remote transaction: %v", name, err) + } + // Second transaction fails due to limit. + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyB)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) + } + // Replace by fee for first transaction from B works. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(2), keyB)); err != nil { + t.Fatalf("%s: failed to add remote transaction: %v", name, err) + } + }, + }, + { + // This is the symmetric case of the previous one, where the delegation request + // is received after the transaction. The resulting state shall be the same. + name: "accept-authorization-from-sender-of-one-inflight-tx", + pending: 2, + run: func(name string) { + // The first in-flight transaction is accepted. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyB)); err != nil { + t.Fatalf("%s: failed to add with pending delegation: %v", name, err) + } + // Delegation is accepted. + if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{0, keyB}})); err != nil { + t.Fatalf("%s: failed to add remote transaction: %v", name, err) + } + // The second in-flight transaction is rejected. + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyB)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) + } + }, + }, + { + name: "reject-authorization-from-sender-with-more-than-one-inflight-tx", + pending: 2, + run: func(name string) { + // Submit two transactions. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyB)); err != nil { + t.Fatalf("%s: failed to add with pending delegation: %v", name, err) + } + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyB)); err != nil { + t.Fatalf("%s: failed to add with pending delegation: %v", name, err) + } + // Delegation rejected since two txs are already in-flight. + if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{0, keyB}})); !errors.Is(err, ErrAuthorityReserved) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrAuthorityReserved, err) + } }, }, { @@ -2267,7 +2363,7 @@ func TestSetCodeTransactions(t *testing.T) { pending: 2, run: func(name string) { // Send two transactions where the first has no conflicting delegations and - // the second should be allowed despite conflicting with the authorities in 1). + // the second should be allowed despite conflicting with the authorities in the first. if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})); err != nil { t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) } @@ -2276,28 +2372,10 @@ func TestSetCodeTransactions(t *testing.T) { } }, }, - { - name: "allow-one-tx-from-pooled-delegation", - pending: 2, - run: func(name string) { - // Verify C cannot originate another transaction when it has a pooled delegation. - if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{0, keyC}})); err != nil { - t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) - } - if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyC)); err != nil { - t.Fatalf("%s: failed to add with pending delegatio: %v", name, err) - } - // Also check gapped transaction is rejected. - if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { - t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) - } - }, - }, { name: "replace-by-fee-setcode-tx", pending: 1, run: func(name string) { - // 4. Fee bump the setcode tx send. if err := pool.addRemoteSync(setCodeTx(0, keyB, []unsignedAuth{{1, keyC}})); err != nil { t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) } @@ -2307,44 +2385,85 @@ func TestSetCodeTransactions(t *testing.T) { }, }, { - name: "allow-tx-from-replaced-authority", - pending: 2, + name: "allow-more-than-one-tx-from-replaced-authority", + pending: 3, run: func(name string) { - // Fee bump with a different auth list. Make sure that unlocks the authorities. + // Send transaction from A with B as an authority. if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyB}})); err != nil { t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) } + // Replace transaction with another having C as an authority. if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(3000), uint256.NewInt(300), keyA, []unsignedAuth{{0, keyC}})); err != nil { t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) } - // Now send a regular tx from B. + // B should not be considred as having an in-flight delegation, so + // should allow more than one pooled transaction. if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyB)); err != nil { t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) } + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(10), keyB)); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } }, }, { + // This test is analogous to the previous one, but the the replaced + // transaction is self-sponsored. name: "allow-tx-from-replaced-self-sponsor-authority", - pending: 2, + pending: 3, run: func(name string) { - // + // Send transaction from A with A as an authority. if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyA}})); err != nil { t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) } + // Replace transaction with a transaction with B as an authority. if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(30), uint256.NewInt(30), keyA, []unsignedAuth{{0, keyB}})); err != nil { t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) } - // Now send a regular tx from keyA. - if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyA)); err != nil { + // The one in-flight transaction limit from A no longer applies, so we + // can stack a second transaction for the account. + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyA)); err != nil { t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) } - // Make sure we can still send from keyB. + // B should still be able to send transactions. if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyB)); err != nil { t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) } + // However B still has the limitation to one in-flight transaction. + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyB)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) + } }, }, { + name: "replacements-respect-inflight-tx-count", + pending: 2, + run: func(name string) { + // Send transaction from A with B as an authority. + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyB}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + // Send two transactions from B. Only the first should be accepted due + // to in-flight limit. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyB)); err != nil { + t.Fatalf("%s: failed to add remote transaction: %v", name, err) + } + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyB)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) + } + // Replace the in-flight transaction from B. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(30), keyB)); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } + // Ensure the in-flight limit for B is still in place. + if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyB)); !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrInflightTxLimitReached, err) + } + }, + }, + { + // Since multiple authorizations can be pending simultaneously, replacing + // one of them should not break the one in-flight-transaction limit. name: "track-multiple-conflicting-delegations", pending: 3, run: func(name string) { @@ -2369,19 +2488,6 @@ func TestSetCodeTransactions(t *testing.T) { } }, }, - { - name: "reject-delegation-from-pending-account", - pending: 1, - run: func(name string) { - // Attempt to submit a delegation from an account with a pending tx. - if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil { - t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) - } - if err, want := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})), ErrAuthorityReserved; !errors.Is(err, want) { - t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err) - } - }, - }, { name: "remove-hash-from-authority-tracker", pending: 10, diff --git a/core/txpool/reserver.go b/core/txpool/reserver.go index 76ead0f3bb..b6ecef9f1a 100644 --- a/core/txpool/reserver.go +++ b/core/txpool/reserver.go @@ -52,22 +52,37 @@ func NewReservationTracker() *ReservationTracker { // NewHandle creates a named handle on the ReservationTracker. The handle // identifies the subpool so ownership of reservations can be determined. -func (r *ReservationTracker) NewHandle(id int) *Reserver { - return &Reserver{r, id} +func (r *ReservationTracker) NewHandle(id int) *ReservationHandle { + return &ReservationHandle{r, id} } -// Reserver is a named handle on ReservationTracker. It is held by subpools to +// Reserver is an interface for creating and releasing owned reservations in the +// ReservationTracker struct, which is shared between subpools. +type Reserver interface { + // Hold attempts to reserve the specified account address for the given pool. + // Returns an error if the account is already reserved. + Hold(addr common.Address) error + + // Release attempts to release the reservation for the specified account. + // Returns an error if the address is not reserved or is reserved by another pool. + Release(addr common.Address) error + + // Has returns a flag indicating if the address has been reserved by a pool + // other than one with the current Reserver handle. + Has(address common.Address) bool +} + +// ReservationHandle is a named handle on ReservationTracker. It is held by subpools to // make reservations for accounts it is tracking. The id is used to determine // which pool owns an address and disallows non-owners to hold or release // addresses it doesn't own. -type Reserver struct { +type ReservationHandle struct { tracker *ReservationTracker id int } -// Hold attempts to reserve the specified account address for the given pool. -// Returns an error if the account is already reserved. -func (h *Reserver) Hold(addr common.Address) error { +// Hold implements the Reserver interface. +func (h *ReservationHandle) Hold(addr common.Address) error { h.tracker.lock.Lock() defer h.tracker.lock.Unlock() @@ -89,9 +104,8 @@ func (h *Reserver) Hold(addr common.Address) error { return nil } -// Release attempts to release the reservation for the specified account. -// Returns an error if the address is not reserved or is reserved by another pool. -func (h *Reserver) Release(addr common.Address) error { +// Release implements the Reserver interface. +func (h *ReservationHandle) Release(addr common.Address) error { h.tracker.lock.Lock() defer h.tracker.lock.Unlock() @@ -114,11 +128,11 @@ func (h *Reserver) Release(addr common.Address) error { return nil } -// Has returns a flag indicating if the address has been reserved or not. -func (h *Reserver) Has(address common.Address) bool { +// Has implements the Reserver interface. +func (h *ReservationHandle) Has(address common.Address) bool { h.tracker.lock.RLock() defer h.tracker.lock.RUnlock() - _, exists := h.tracker.accounts[address] - return exists + id, exists := h.tracker.accounts[address] + return exists && id != h.id } diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 2cb5103875..8cfc14f164 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -105,7 +105,7 @@ type SubPool interface { // These should not be passed as a constructor argument - nor should the pools // start by themselves - in order to keep multiple subpools in lockstep with // one another. - Init(gasTip uint64, head *types.Header, reserver *Reserver) error + Init(gasTip uint64, head *types.Header, reserver Reserver) error // Close terminates any background processing threads and releases any held // resources. From 2547bb28a4a25969dd677f048155b64394fe59fd Mon Sep 17 00:00:00 2001 From: crStiv Date: Thu, 10 Apr 2025 12:26:35 +0300 Subject: [PATCH 278/940] eth/fetcher: Fix flaky TestTransactionForgotten test using mock clock (#31468) Fixes #31169 The TestTransactionForgotten test was flaky due to real time dependencies. This PR: - Replaces real time with mock clock for deterministic timing control - Adds precise state checks at timeout boundaries - Verifies underpriced cache states and cleanup - Improves test reliability by controlling transaction timestamps - Adds checks for transaction re-enqueueing behavior The changes ensure consistent test behavior without timing-related flakiness. --------- Co-authored-by: Zsolt Felfoldi --- eth/fetcher/tx_fetcher.go | 14 +-- eth/fetcher/tx_fetcher_test.go | 98 ++++++++++++++++++--- tests/fuzzers/txfetcher/txfetcher_fuzzer.go | 7 +- 3 files changed, 99 insertions(+), 20 deletions(-) diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 97d1e29862..1c192d4112 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -202,22 +202,23 @@ type TxFetcher struct { fetchTxs func(string, []common.Hash) error // Retrieves a set of txs from a remote peer dropPeer func(string) // Drops a peer in case of announcement violation - step chan struct{} // Notification channel when the fetcher loop iterates - clock mclock.Clock // Time wrapper to simulate in tests - rand *mrand.Rand // Randomizer to use in tests instead of map range loops (soft-random) + step chan struct{} // Notification channel when the fetcher loop iterates + clock mclock.Clock // Monotonic clock or simulated clock for tests + realTime func() time.Time // Real system time or simulated time for tests + rand *mrand.Rand // Randomizer to use in tests instead of map range loops (soft-random) } // NewTxFetcher creates a transaction fetcher to retrieve transaction // based on hash announcements. func NewTxFetcher(hasTx func(common.Hash) bool, addTxs func([]*types.Transaction) []error, fetchTxs func(string, []common.Hash) error, dropPeer func(string)) *TxFetcher { - return NewTxFetcherForTests(hasTx, addTxs, fetchTxs, dropPeer, mclock.System{}, nil) + return NewTxFetcherForTests(hasTx, addTxs, fetchTxs, dropPeer, mclock.System{}, time.Now, nil) } // NewTxFetcherForTests is a testing method to mock out the realtime clock with // a simulated version and the internal randomness with a deterministic one. func NewTxFetcherForTests( hasTx func(common.Hash) bool, addTxs func([]*types.Transaction) []error, fetchTxs func(string, []common.Hash) error, dropPeer func(string), - clock mclock.Clock, rand *mrand.Rand) *TxFetcher { + clock mclock.Clock, realTime func() time.Time, rand *mrand.Rand) *TxFetcher { return &TxFetcher{ notify: make(chan *txAnnounce), cleanup: make(chan *txDelivery), @@ -237,6 +238,7 @@ func NewTxFetcherForTests( fetchTxs: fetchTxs, dropPeer: dropPeer, clock: clock, + realTime: realTime, rand: rand, } } @@ -293,7 +295,7 @@ func (f *TxFetcher) Notify(peer string, types []byte, sizes []uint32, hashes []c // isKnownUnderpriced reports whether a transaction hash was recently found to be underpriced. func (f *TxFetcher) isKnownUnderpriced(hash common.Hash) bool { prevTime, ok := f.underpriced.Peek(hash) - if ok && prevTime.Before(time.Now().Add(-maxTxUnderpricedTimeout)) { + if ok && prevTime.Before(f.realTime().Add(-maxTxUnderpricedTimeout)) { f.underpriced.Remove(hash) return false } diff --git a/eth/fetcher/tx_fetcher_test.go b/eth/fetcher/tx_fetcher_test.go index 52b3591086..7f3080f5f6 100644 --- a/eth/fetcher/tx_fetcher_test.go +++ b/eth/fetcher/tx_fetcher_test.go @@ -2150,9 +2150,22 @@ func containsHashInAnnounces(slice []announce, hash common.Hash) bool { return false } -// Tests that a transaction is forgotten after the timeout. +// TestTransactionForgotten verifies that underpriced transactions are properly +// forgotten after the timeout period, testing both the exact timeout boundary +// and the cleanup of the underpriced cache. func TestTransactionForgotten(t *testing.T) { - fetcher := NewTxFetcher( + // Test ensures that underpriced transactions are properly forgotten after a timeout period, + // including checks for timeout boundary and cache cleanup. + t.Parallel() + + // Create a mock clock for deterministic time control + mockClock := new(mclock.Simulated) + mockTime := func() time.Time { + nanoTime := int64(mockClock.Now()) + return time.Unix(nanoTime/1000000000, nanoTime%1000000000) + } + + fetcher := NewTxFetcherForTests( func(common.Hash) bool { return false }, func(txs []*types.Transaction) []error { errs := make([]error, len(txs)) @@ -2163,24 +2176,83 @@ func TestTransactionForgotten(t *testing.T) { }, func(string, []common.Hash) error { return nil }, func(string) {}, + mockClock, + mockTime, + rand.New(rand.NewSource(0)), // Use fixed seed for deterministic behavior ) fetcher.Start() defer fetcher.Stop() - // Create one TX which is 5 minutes old, and one which is recent - tx1 := types.NewTx(&types.LegacyTx{Nonce: 0}) - tx1.SetTime(time.Now().Add(-maxTxUnderpricedTimeout - 1*time.Second)) - tx2 := types.NewTx(&types.LegacyTx{Nonce: 1}) - // Enqueue both in the fetcher. They will be immediately tagged as underpriced - if err := fetcher.Enqueue("asdf", []*types.Transaction{tx1, tx2}, false); err != nil { + // Create two test transactions with the same timestamp + tx1 := types.NewTransaction(0, common.Address{}, big.NewInt(100), 21000, big.NewInt(1), nil) + tx2 := types.NewTransaction(1, common.Address{}, big.NewInt(100), 21000, big.NewInt(1), nil) + + now := mockTime() + tx1.SetTime(now) + tx2.SetTime(now) + + // Initial state: both transactions should be marked as underpriced + if err := fetcher.Enqueue("peer", []*types.Transaction{tx1, tx2}, false); err != nil { t.Fatal(err) } - // isKnownUnderpriced should trigger removal of the first tx (no longer be known underpriced) - if fetcher.isKnownUnderpriced(tx1.Hash()) { - t.Fatal("transaction should be forgotten by now") + if !fetcher.isKnownUnderpriced(tx1.Hash()) { + t.Error("tx1 should be underpriced") } - // isKnownUnderpriced should not trigger removal of the second if !fetcher.isKnownUnderpriced(tx2.Hash()) { - t.Fatal("transaction should be known underpriced") + t.Error("tx2 should be underpriced") + } + + // Verify cache size + if size := fetcher.underpriced.Len(); size != 2 { + t.Errorf("wrong underpriced cache size: got %d, want %d", size, 2) + } + + // Just before timeout: transactions should still be underpriced + mockClock.Run(maxTxUnderpricedTimeout - time.Second) + if !fetcher.isKnownUnderpriced(tx1.Hash()) { + t.Error("tx1 should still be underpriced before timeout") + } + if !fetcher.isKnownUnderpriced(tx2.Hash()) { + t.Error("tx2 should still be underpriced before timeout") + } + + // Exactly at timeout boundary: transactions should still be present + mockClock.Run(time.Second) + if !fetcher.isKnownUnderpriced(tx1.Hash()) { + t.Error("tx1 should be present exactly at timeout") + } + if !fetcher.isKnownUnderpriced(tx2.Hash()) { + t.Error("tx2 should be present exactly at timeout") + } + + // After timeout: transactions should be forgotten + mockClock.Run(time.Second) + if fetcher.isKnownUnderpriced(tx1.Hash()) { + t.Error("tx1 should be forgotten after timeout") + } + if fetcher.isKnownUnderpriced(tx2.Hash()) { + t.Error("tx2 should be forgotten after timeout") + } + + // Verify cache is empty + if size := fetcher.underpriced.Len(); size != 0 { + t.Errorf("wrong underpriced cache size after timeout: got %d, want 0", size) + } + + // Re-enqueue tx1 with updated timestamp + tx1.SetTime(mockTime()) + if err := fetcher.Enqueue("peer", []*types.Transaction{tx1}, false); err != nil { + t.Fatal(err) + } + if !fetcher.isKnownUnderpriced(tx1.Hash()) { + t.Error("tx1 should be underpriced after re-enqueueing with new timestamp") + } + if fetcher.isKnownUnderpriced(tx2.Hash()) { + t.Error("tx2 should remain forgotten") + } + + // Verify final cache state + if size := fetcher.underpriced.Len(); size != 1 { + t.Errorf("wrong final underpriced cache size: got %d, want 1", size) } } diff --git a/tests/fuzzers/txfetcher/txfetcher_fuzzer.go b/tests/fuzzers/txfetcher/txfetcher_fuzzer.go index 51f2fc3b4d..c136253a62 100644 --- a/tests/fuzzers/txfetcher/txfetcher_fuzzer.go +++ b/tests/fuzzers/txfetcher/txfetcher_fuzzer.go @@ -84,7 +84,12 @@ func fuzz(input []byte) int { }, func(string, []common.Hash) error { return nil }, nil, - clock, rand, + clock, + func() time.Time { + nanoTime := int64(clock.Now()) + return time.Unix(nanoTime/1000000000, nanoTime%1000000000) + }, + rand, ) f.Start() defer f.Stop() From 4906c9911316c52ccd20e122d1e092abe3c7d6ca Mon Sep 17 00:00:00 2001 From: HackyMiner Date: Thu, 10 Apr 2025 19:46:54 +0900 Subject: [PATCH 279/940] accounts/usbwallet: full 32bit chainId support for Trezor (#17439) This fix allows Trezor to support full 32bit chainId in geth, with the next version of firmware. For `chainId > 2147483630` case, Trezor returns signature bit only. - Trezor returns only signature parity for `chainId > 2147483630` case. - for `chainId == 2147483630` case, Trezor returns `MAX_UINT32` or `0`, but it doesn't matter. (`2147483630 * 2 + 35` = `4294967295`(`MAX_UINT32`)) chainId | returned signature_v | compatible issue ---------|------------------------|-------------------- 0 < chainId <= 255 | chainId * 2 + 35 + v | no issue (firmware `1.6.2` for Trezor one) 255 < chainId <= 2147483630 | chainId * 2 + 35 + v | ***fixed.*** *firmware `1.6.3`* chainId > 2147483630 | v | *firmware `1.6.3`* Please see also: full 32bit chainId support for Trezor - Trezor one: https://github.com/trezor/trezor-mcu/pull/399 ***merged*** - Trezor model T: https://github.com/trezor/trezor-core/pull/311 ***merged*** --------- Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com> --- accounts/usbwallet/trezor.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index 1c4270d255..d4862d161b 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -25,6 +25,7 @@ import ( "errors" "fmt" "io" + "math" "math/big" "github.com/ethereum/go-ethereum/accounts" @@ -249,7 +250,11 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction } } // Extract the Ethereum signature and do a sanity validation - if len(response.GetSignatureR()) == 0 || len(response.GetSignatureS()) == 0 || response.GetSignatureV() == 0 { + if len(response.GetSignatureR()) == 0 || len(response.GetSignatureS()) == 0 { + return common.Address{}, nil, errors.New("reply lacks signature") + } else if response.GetSignatureV() == 0 && int(chainID.Int64()) <= (math.MaxUint32-36)/2 { + // for chainId >= (MaxUint32-36)/2, Trezor returns signature bit only + // https://github.com/trezor/trezor-mcu/pull/399 return common.Address{}, nil, errors.New("reply lacks signature") } signature := append(append(response.GetSignatureR(), response.GetSignatureS()...), byte(response.GetSignatureV())) @@ -261,7 +266,11 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction } else { // Trezor backend does not support typed transactions yet. signer = types.NewEIP155Signer(chainID) - signature[64] -= byte(chainID.Uint64()*2 + 35) + // if chainId is above (MaxUint32 - 36) / 2 then the final v values is returned + // directly. Otherwise, the returned value is 35 + chainid * 2. + if signature[64] > 1 && int(chainID.Int64()) <= (math.MaxUint32-36)/2 { + signature[64] -= byte(chainID.Uint64()*2 + 35) + } } // Inject the final signature into the transaction and sanity check the sender From 9b4eab6a29704f55fa7b4b92e296094f0dbcee22 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Thu, 10 Apr 2025 19:49:54 +0800 Subject: [PATCH 280/940] eth/catalyst: in tests, manually sync txpool after initial chain insertion to prevent race between txpool head reset and promotion of txs that will be subsequently added (#31595) before this changes, this will result in numerous test failures: ``` > go test -run=Eth2AssembleBlock -c > stress ./catalyst.test ``` The reason is that after creating/inserting the test chain, there is a race between the txpool head reset and the promotion of txs added from tests. Ensuring that the txpool state is up to date with the head of the chain before proceeding fixes these flaky tests. --- eth/catalyst/api_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index e91e07d05d..cb6ae053b6 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -447,6 +447,9 @@ func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block) n.Close() t.Fatal("can't import test blocks:", err) } + if err := ethservice.TxPool().Sync(); err != nil { + t.Fatal("failed to sync txpool after initial blockchain import:", err) + } ethservice.SetSynced() return n, ethservice From f64aa6eaf7a021226648aeae5ceef800fb9b66d0 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Fri, 11 Apr 2025 00:21:32 +0800 Subject: [PATCH 281/940] internal/testlog: fix log output from sub-loggers (#31539) When we instantiate a sub-logger via `go-ethereum/internal/testlog/logger.With`, we copy the reference to the `bufHandler` from the parent logger. However, internally, `go-ethereum/internal/testlog/logger.With` calls `log/slog/Logger.With` which creates a new handler instance (via `internal/bufHandler.WithAttrs`). This PR modifies sub-logger instantiation to use the newly-instantiated handler, instead of copying the reference from the parent instance. The type cast from `slog.Handler` to `*bufHandler` in `internal/testlog/Logger.With` is safe here because a `internal/testlog/Logger` can only be instantiated with a `*bufHandler` as the underlying handler type. Note, that I've also removed a pre-existing method that broke the above assumption. However, this method is not used in our codebase. I'm not sure if the assumption holds for forks of geth (e.g. optimism has modified the testlogger somewhat allowing test loggers to accept arbitrary handler types), but it seems okay to break API compatibility given that this is in the `internal` package. closes https://github.com/ethereum/go-ethereum/issues/31533 --- internal/testlog/testlog.go | 28 +++++++------ internal/testlog/testlog_test.go | 67 ++++++++++++++++++++++++++++++++ tests/testdata | 2 +- 3 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 internal/testlog/testlog_test.go diff --git a/internal/testlog/testlog.go b/internal/testlog/testlog.go index ad61af9eac..8a3ea85438 100644 --- a/internal/testlog/testlog.go +++ b/internal/testlog/testlog.go @@ -23,7 +23,6 @@ import ( "fmt" "log/slog" "sync" - "testing" "github.com/ethereum/go-ethereum/log" ) @@ -32,12 +31,21 @@ const ( termTimeFormat = "01-02|15:04:05.000" ) +// T wraps methods from testing.T used by the test logger into an interface. +// It is specified so that unit tests can instantiate the logger with an +// implementation of T which can capture the output of logging statements +// from T.Logf, as this cannot be using testing.T. +type T interface { + Logf(format string, args ...any) + Helper() +} + // logger implements log.Logger such that all output goes to the unit test log via // t.Logf(). All methods in between logger.Trace, logger.Debug, etc. are marked as test // helpers, so the file and line number in unit test output correspond to the call site // which emitted the log message. type logger struct { - t *testing.T + t T l log.Logger mu *sync.Mutex h *bufHandler @@ -78,7 +86,7 @@ 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 { +func Logger(t T, level slog.Level) log.Logger { handler := bufHandler{ buf: []slog.Record{}, attrs: []slog.Attr{}, @@ -92,17 +100,6 @@ func Logger(t *testing.T, level slog.Level) log.Logger { } } -// LoggerWithHandler returns -func LoggerWithHandler(t *testing.T, handler slog.Handler) log.Logger { - var bh bufHandler - return &logger{ - t: t, - l: log.NewLogger(handler), - mu: new(sync.Mutex), - h: &bh, - } -} - func (l *logger) Handler() slog.Handler { return l.l.Handler() } @@ -170,7 +167,8 @@ func (l *logger) Crit(msg string, ctx ...interface{}) { } func (l *logger) With(ctx ...interface{}) log.Logger { - return &logger{l.t, l.l.With(ctx...), l.mu, l.h} + newLogger := l.l.With(ctx...) + return &logger{l.t, newLogger, l.mu, newLogger.Handler().(*bufHandler)} } func (l *logger) New(ctx ...interface{}) log.Logger { diff --git a/internal/testlog/testlog_test.go b/internal/testlog/testlog_test.go new file mode 100644 index 0000000000..7789a47270 --- /dev/null +++ b/internal/testlog/testlog_test.go @@ -0,0 +1,67 @@ +package testlog + +import ( + "bytes" + "fmt" + "io" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/log" +) + +type mockT struct { + out io.Writer +} + +func (t *mockT) Helper() { + // noop for the purposes of unit tests +} + +func (t *mockT) Logf(format string, args ...any) { + // we could gate this operation in a mutex, but because testlogger + // only calls Logf with its internal mutex held, we just write output here + var lineBuf bytes.Buffer + if _, err := fmt.Fprintf(&lineBuf, format, args...); err != nil { + panic(err) + } + // The timestamp is locale-dependent, so we want to trim that off + // "INFO [01-01|00:00:00.000] a message ..." -> "a message..." + sanitized := strings.Split(lineBuf.String(), "]")[1] + if _, err := t.out.Write([]byte(sanitized)); err != nil { + panic(err) + } +} + +func TestLogging(t *testing.T) { + tests := []struct { + name string + expected string + run func(t *mockT) + }{ + { + "SubLogger", + ` Visible + Hide and seek foobar=123 + Also visible +`, + func(t *mockT) { + l := Logger(t, log.LevelInfo) + subLogger := l.New("foobar", 123) + + l.Info("Visible") + subLogger.Info("Hide and seek") + l.Info("Also visible") + }, + }, + } + + for _, tc := range tests { + outp := bytes.Buffer{} + mock := mockT{&outp} + tc.run(&mock) + if outp.String() != tc.expected { + fmt.Printf("output mismatch.\nwant: '%s'\ngot: '%s'\n", tc.expected, outp.String()) + } + } +} diff --git a/tests/testdata b/tests/testdata index 81862e4848..faf33b4714 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit 81862e4848585a438d64f911a19b3825f0f4cd95 +Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2 From a9444ea312eb4077a470cdb9b394ec0544cf116b Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 10 Apr 2025 23:54:44 +0200 Subject: [PATCH 282/940] tests/testdata: revert to v17.0 The submodule was accidentally updated to another commit by f64aa6eaf7. --- tests/testdata | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testdata b/tests/testdata index faf33b4714..81862e4848 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2 +Subproject commit 81862e4848585a438d64f911a19b3825f0f4cd95 From 0059b0ab6676232dd3809baa664d1e5b0d5e85ab Mon Sep 17 00:00:00 2001 From: levisyin Date: Fri, 11 Apr 2025 17:28:14 +0800 Subject: [PATCH 283/940] build: upgrade -dlgo version to Go 1.24.2 (#31538) --- build/checksums.txt | 94 ++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index 6d3b718c3c..a914d79860 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,54 +5,54 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/ b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz -# version:golang 1.24.1 +# version:golang 1.24.2 # https://go.dev/dl/ -8244ebf46c65607db10222b5806aeb31c1fcf8979c1b6b12f60c677e9a3c0656 go1.24.1.src.tar.gz -8d627dc163a4bffa2b1887112ad6194af175dce108d606ed1714a089fb806033 go1.24.1.aix-ppc64.tar.gz -addbfce2056744962e2d7436313ab93486660cf7a2e066d171b9d6f2da7c7abe go1.24.1.darwin-amd64.tar.gz -58d529334561cff11087cd4ab18fe0b46d8d5aad88f45c02b9645f847e014512 go1.24.1.darwin-amd64.pkg -295581b5619acc92f5106e5bcb05c51869337eb19742fdfa6c8346c18e78ff88 go1.24.1.darwin-arm64.tar.gz -78b0fc8ddc344eb499f1a952c687cb84cbd28ba2b739cfa0d4eb042f07e44e82 go1.24.1.darwin-arm64.pkg -e70053f56f7eb93806d80cbd5726f78509a0a467602f7bea0e2c4ee8ed7c3968 go1.24.1.dragonfly-amd64.tar.gz -3595e2674ed8fe72e604ca59c964d3e5277aafb08475c2b1aaca2d2fd69c24fc go1.24.1.freebsd-386.tar.gz -47d7de8bb64d5c3ee7b6723aa62d5ecb11e3568ef2249bbe1d4bbd432d37c00c go1.24.1.freebsd-amd64.tar.gz -04eec3bcfaa14c1370cdf98e8307fac7e4853496c3045afb9c3124a29cbca205 go1.24.1.freebsd-arm.tar.gz -51aa70146e40cfdc20927424083dc86e6223f85dc08089913a1651973b55665b go1.24.1.freebsd-arm64.tar.gz -3c131d8e3fc285a1340f87813153e24226d3ddbd6e54f3facbd6e4c46a84655e go1.24.1.freebsd-riscv64.tar.gz -201d09da737ba39d5367f87d4e8b31edaeeb3dc9b9c407cb8cfb40f90c5a727a go1.24.1.illumos-amd64.tar.gz -8c530ecedbc17e42ce10177bea07ccc96a3e77c792ea1ea72173a9675d16ffa5 go1.24.1.linux-386.tar.gz -cb2396bae64183cdccf81a9a6df0aea3bce9511fc21469fb89a0c00470088073 go1.24.1.linux-amd64.tar.gz -8df5750ffc0281017fb6070fba450f5d22b600a02081dceef47966ffaf36a3af go1.24.1.linux-arm64.tar.gz -6d95f8d7884bfe2364644c837f080f2b585903d0b771eb5b06044e226a4f120a go1.24.1.linux-armv6l.tar.gz -19304a4a56e46d04604547d2d83235dc4f9b192c79832560ce337d26cc7b835a go1.24.1.linux-loong64.tar.gz -6347be77fa5359c12a5308c8ab87147c1fc4717b0c216493d1706c3b9fcde22d go1.24.1.linux-mips.tar.gz -1647df415f7030b82d4105670192aa7e8910e18563bb0d505192d72800cc2d21 go1.24.1.linux-mips64.tar.gz -762da594e4ec0f9cf6defae6ef971f5f7901203ee6a2d979e317adec96657317 go1.24.1.linux-mips64le.tar.gz -9d8133c7b23a557399fab870b5cf464079c2b623a43b214a7567cf11c254a444 go1.24.1.linux-mipsle.tar.gz -132f10999abbaccbada47fa85462db30c423955913b14d6c692de25f4636c766 go1.24.1.linux-ppc64.tar.gz -0fb522efcefabae6e37e69bdc444094e75bfe824ea6d4cc3cbc70c7ae1b16858 go1.24.1.linux-ppc64le.tar.gz -eaef4323d5467ff97fb1979c8491764060dade19f02f3275a9313f9a0da3b9c0 go1.24.1.linux-riscv64.tar.gz -6c05e14d8f11094cb56a1c50f390b6b658bed8a7cbd8d1a57e926581b7eabfce go1.24.1.linux-s390x.tar.gz -5dbb287d343ea00d58a70b11629f32ee716dc50a6875c459ea2018df0f294cd8 go1.24.1.netbsd-386.tar.gz -617aa3faee50ce84c343db0888e9a210c310a7203666b4ed620f31030c9fb32f go1.24.1.netbsd-amd64.tar.gz -59a928b7080c4a6ac985946274b7c65ce1cecc0b468ecd992d17b7c12fab9296 go1.24.1.netbsd-arm.tar.gz -28daa8d0feb4aef2af60cefa3305bb9314de7e8a05cbca41ac548964cdfe89b7 go1.24.1.netbsd-arm64.tar.gz -b7382b2f5d99813aeac14db482faa3bfbd47a68880b607fa2a7e669e26bab9cd go1.24.1.openbsd-386.tar.gz -2513b6537c45deead5e641c7ce7502913e7d5e6f0b21c52542fb11f81578690f go1.24.1.openbsd-amd64.tar.gz -853c1917d4fc7b144c55a02842aa48542d5cc798dde8db96dc0fdbc263200e04 go1.24.1.openbsd-arm.tar.gz -6bc207b91e6f6ae3347fb54616a8fb2f5c11983713846a4cef111ff3f4f94d14 go1.24.1.openbsd-arm64.tar.gz -4279260e2f2b94ee94e81470d13db7367f4393b061fee60985528fa0fa430df4 go1.24.1.openbsd-ppc64.tar.gz -6fc4023a0a339ee0778522364a127d94c78e62122288d47d820dba703f81dc07 go1.24.1.openbsd-riscv64.tar.gz -b5eb9fafd77146e7e1f748acfd95559580ecc8d2f15abf432a20f58c929c7cd2 go1.24.1.plan9-386.tar.gz -24dcad6361b141fc8cced15b092351e12a99d2e58d7013204a3013c50daf9fdd go1.24.1.plan9-amd64.tar.gz -a026ac3b55aa1e6fdc2aaab30207a117eafbe965ed81d3aa0676409f280ddc37 go1.24.1.plan9-arm.tar.gz -8e4f6a77388dc6e5aa481efd5abdb3b9f5c9463bb82f4db074494e04e5c84992 go1.24.1.solaris-amd64.tar.gz -b799f4ab264eef12a014c759383ed934056608c483e0f73e34ea6caf9f1df5f9 go1.24.1.windows-386.zip -db128981033ac82a64688a123f631e61297b6b8f52ca913145e57caa8ce94cc3 go1.24.1.windows-386.msi -95666b551453209a2b8869d29d177285ff9573af10f085d961d7ae5440f645ce go1.24.1.windows-amd64.zip -5968e7adcf26e68a54f1cd41ad561275a670a8e2ca5263bc375b524638557dfb go1.24.1.windows-amd64.msi -e28c4e6d0b913955765b46157ab88ae59bb636acaa12d7bec959aa6900f1cebd go1.24.1.windows-arm64.zip -6d352c1f154a102a5b90c480cc64bab205ccf2681e34e78a3a4d3f1ddfbc81e4 go1.24.1.windows-arm64.msi +9dc77ffadc16d837a1bf32d99c624cb4df0647cee7b119edd9e7b1bcc05f2e00 go1.24.2.src.tar.gz +427b373540d8fd51dbcc46bdecd340af109cd41514443c000d3dcde72b2c65a3 go1.24.2.aix-ppc64.tar.gz +238d9c065d09ff6af229d2e3b8b5e85e688318d69f4006fb85a96e41c216ea83 go1.24.2.darwin-amd64.tar.gz +535ed9ff283fee39575a7fb9b6d8b1901b6dc640d06dc71fd7d3faeefdaf8030 go1.24.2.darwin-amd64.pkg +b70f8b3c5b4ccb0ad4ffa5ee91cd38075df20fdbd953a1daedd47f50fbcff47a go1.24.2.darwin-arm64.tar.gz +4732f607a47ce4d898c0af01ff68f07e0820a6b50603aef5d5c777d1102505e2 go1.24.2.darwin-arm64.pkg +c17686b5fd61a663fbfafccfa177961be59386cf294e935ce35866b9dcb8e78a go1.24.2.dragonfly-amd64.tar.gz +026f1dd906189acff714c7625686bbc4ed91042618ba010d45b671461acc9e63 go1.24.2.freebsd-386.tar.gz +49399ba759b570a8f87d12179133403da6c2dd296d63a8830dee309161b9c40c go1.24.2.freebsd-amd64.tar.gz +1f48f47183794d97c29736004247ab541177cf984ac6322c78bc43828daa1172 go1.24.2.freebsd-arm.tar.gz +ef856428b60a8c0bd9a2cba596e83024be6f1c2d5574e89cb1ff2262b08df8b9 go1.24.2.freebsd-arm64.tar.gz +ec2088823e16df00600a6d0f72e9a7dc6d2f80c9c140c2043c0cf20e1404d1a9 go1.24.2.freebsd-riscv64.tar.gz +e030e7cedbb8688f1d75cb80f3de6ee2e6617a67d34051e794e5992b53462147 go1.24.2.illumos-amd64.tar.gz +4c382776d52313266f3026236297a224a6688751256a2dffa3f524d8d6f6c0ba go1.24.2.linux-386.tar.gz +68097bd680839cbc9d464a0edce4f7c333975e27a90246890e9f1078c7e702ad go1.24.2.linux-amd64.tar.gz +756274ea4b68fa5535eb9fe2559889287d725a8da63c6aae4d5f23778c229f4b go1.24.2.linux-arm64.tar.gz +438d5d3d7dcb239b58d893a715672eabe670b9730b1fd1c8fc858a46722a598a go1.24.2.linux-armv6l.tar.gz +6aefd3bf59c3c5592eda4fb287322207f119c2210f3795afa9be48d3ccb73e1b go1.24.2.linux-loong64.tar.gz +93e49bb4692783b0e9a2deab9558c6e8d2867f35592aeff285adda60924167f3 go1.24.2.linux-mips.tar.gz +6e86e703675016f3faf6604b8f68f20dc1bba75849136e6dd4f43f69c8a4a9d9 go1.24.2.linux-mips64.tar.gz +f233d237538ca1559a7d7cf519a29f0147923a951377bc4e467af4c059e68851 go1.24.2.linux-mips64le.tar.gz +545e1b9a7939f923fd53bde98334b987ef42eb353ee3e0bfede8aa06079d6b24 go1.24.2.linux-mipsle.tar.gz +6eab31481f2f46187bc1b6c887662eef06fc9d7271a8390854072cdb387c8d74 go1.24.2.linux-ppc64.tar.gz +5fff857791d541c71d8ea0171c73f6f99770d15ff7e2ad979104856d01f36563 go1.24.2.linux-ppc64le.tar.gz +91bda1558fcbd1c92769ad86c8f5cf796f8c67b0d9d9c19f76eecfc75ce71527 go1.24.2.linux-riscv64.tar.gz +1cb3448166d6abb515a85a3ee5afbdf932081fb58ad7143a8fb666fbc06146d9 go1.24.2.linux-s390x.tar.gz +a9a2c0db2e826f20f00b02bee01dfdaeb49591c2f6ffacb78dc64a950894f7ff go1.24.2.netbsd-386.tar.gz +cd1a35b76ed9c7b6c0c1616741bd319699a77867ade0be9924f32496c0a87a3f go1.24.2.netbsd-amd64.tar.gz +8c666388d066e479155cc5116950eeb435df28087ef277c18f1dc7479f836e60 go1.24.2.netbsd-arm.tar.gz +5d42f0be04f58da5be788a1e260f8747c316b8ce182bf0b273c2e4c691feaa1a go1.24.2.netbsd-arm64.tar.gz +688effa23ea3973cc8b0fdf4246712cbeef55ff20c45f3a9e28b0c2db04246cf go1.24.2.openbsd-386.tar.gz +e5daf95f1048d8026b1366450a3f8044d668b0639db6422ad9a83755c6745cf7 go1.24.2.openbsd-amd64.tar.gz +aeadaf74bd544d1a12ba9b14c0e7cdb1964de3ba9a52acb4619e91dbae7def7b go1.24.2.openbsd-arm.tar.gz +9e222d9adb0ce836a5b3c8d5aadbd167c8869c030b113f4a81aa88e9a200f279 go1.24.2.openbsd-arm64.tar.gz +192fffa34536adc3cd1bb7c1ee785b8bc156ae7afd10bbf5db99ec8f2e93066e go1.24.2.openbsd-ppc64.tar.gz +a23e90b451a390549042c2a7efbec6f29ed98b2d5618c8d2a35704e21be96e09 go1.24.2.openbsd-riscv64.tar.gz +5cdcafe455d859b02779611a5a1e1d63e498b922e05818fb3debe410a5959e9e go1.24.2.plan9-386.tar.gz +81351659804fa505c1b3ec6fdf9599f7f88df08614307eeb96071bf5e2e74beb go1.24.2.plan9-amd64.tar.gz +6e337d5def14ed0123423c1c32e2e6d8b19161e5d5ffaa7356dad48ee0fd80b4 go1.24.2.plan9-arm.tar.gz +07e6926ebc476c044d7d5b17706abfc52be52bccc2073d1734174efe63c6b35e go1.24.2.solaris-amd64.tar.gz +13d86cb818bba331da75fcd18246ab31a1067b44fb4a243b6dfd93097eda7f37 go1.24.2.windows-386.zip +8a702d9f7104a15bd935f4191c58c24c0b6389e066b9d5661b93915114a2bef0 go1.24.2.windows-386.msi +29c553aabee0743e2ffa3e9fa0cda00ef3b3cc4ff0bc92007f31f80fd69892e1 go1.24.2.windows-amd64.zip +acefb191e72fea0bdb1a3f5f8f6f5ab18b42b3bbce0c7183f189f25953aff275 go1.24.2.windows-amd64.msi +ab267f7f9a3366d48d7664be9e627ce3e63273231430cce5f7783fb910f14148 go1.24.2.windows-arm64.zip +d187bfe539356c39573d2f46766d1d08122b4f33da00fd14d12485fa9e241ff5 go1.24.2.windows-arm64.msi # version:golangci 2.0.2 # https://github.com/golangci/golangci-lint/releases/ From f8ff24e8cfa95c7a1b55857dd5306a9d3b4e50ca Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 11 Apr 2025 11:31:16 +0200 Subject: [PATCH 284/940] version: release go-ethereum v1.15.8 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 72fd903a1f..945b3b58a2 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 8 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 8 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From 80753ba14787ba82954106d7b9025e3a623b96b0 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 11 Apr 2025 11:31:56 +0200 Subject: [PATCH 285/940] version: begin v1.15.9 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 945b3b58a2..c969ab479e 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 8 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 9 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From ecd5c18610c5276e7c6c34d2f317cf774441a81c Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Mon, 14 Apr 2025 10:13:45 +0200 Subject: [PATCH 286/940] p2p: better dial/serve success metrics (#31629) Our previous success metrics gave success even if a peer disconnected right after connection. These metrics only count peers that stayed connected for at least 1 min. The 1 min limit is an arbitrary choice. We do not use this for decision logic, only statistics. --- p2p/metrics.go | 4 ++++ p2p/peer.go | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/p2p/metrics.go b/p2p/metrics.go index 1fd0f26db3..8c9804206b 100644 --- a/p2p/metrics.go +++ b/p2p/metrics.go @@ -51,6 +51,10 @@ var ( dialSuccessMeter = metrics.NewRegisteredMeter("p2p/dials/success", nil) dialConnectionError = metrics.NewRegisteredMeter("p2p/dials/error/connection", nil) + // count peers that stayed connected for at least 1 min + serve1MinSuccessMeter = metrics.NewRegisteredMeter("p2p/serves/success/1min", nil) + dial1MinSuccessMeter = metrics.NewRegisteredMeter("p2p/dials/success/1min", nil) + // handshake error meters dialTooManyPeers = metrics.NewRegisteredMeter("p2p/dials/error/saturated", nil) dialAlreadyConnected = metrics.NewRegisteredMeter("p2p/dials/error/known", nil) diff --git a/p2p/peer.go b/p2p/peer.go index a01df63d0c..9ffb94e5a8 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -254,6 +254,8 @@ func (p *Peer) run() (remoteRequested bool, err error) { p.wg.Add(2) go p.readLoop(readErr) go p.pingLoop() + live1min := time.NewTimer(1 * time.Minute) + defer live1min.Stop() // Start all protocol handlers. writeStart <- struct{}{} @@ -285,6 +287,12 @@ loop: case err = <-p.disc: reason = discReasonForError(err) break loop + case <-live1min.C: + if p.Inbound() { + serve1MinSuccessMeter.Mark(1) + } else { + dial1MinSuccessMeter.Mark(1) + } } } From c5c75977ab55e4d7ea6147cc0e221b588e5e3754 Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Mon, 14 Apr 2025 12:45:27 +0200 Subject: [PATCH 287/940] eth: add logic to drop peers randomly when saturated (#31476) As of now, Geth disconnects peers only on protocol error or timeout, meaning once connection slots are filled, the peerset is largely fixed. As mentioned in https://github.com/ethereum/go-ethereum/issues/31321, Geth should occasionally disconnect peers to ensure some churn. What/when to disconnect could depend on: - the state of geth (e.g. sync or not) - current number of peers - peer level metrics This PR adds a very slow churn using a random drop. --------- Signed-off-by: Csaba Kiraly Co-authored-by: Felix Lange --- eth/backend.go | 7 +++ eth/dropper.go | 167 +++++++++++++++++++++++++++++++++++++++++++++++++ p2p/peer.go | 26 +++++++- p2p/server.go | 10 +-- 4 files changed, 204 insertions(+), 6 deletions(-) create mode 100644 eth/dropper.go diff --git a/eth/backend.go b/eth/backend.go index 6716a77562..c5dec77962 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -76,6 +76,7 @@ type Ethereum struct { handler *handler discmix *enode.FairMix + dropper *dropper // DB interfaces chainDb ethdb.Database // Block chain database @@ -300,6 +301,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { return nil, err } + eth.dropper = newDropper(eth.p2pServer.MaxDialedConns(), eth.p2pServer.MaxInboundConns()) + eth.miner = miner.New(eth, config.Miner, eth.engine) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) eth.miner.SetPrioAddresses(config.TxPool.Locals) @@ -410,6 +413,9 @@ func (s *Ethereum) Start() error { // Start the networking layer s.handler.Start(s.p2pServer.MaxPeers) + // Start the connection manager + s.dropper.Start(s.p2pServer, func() bool { return !s.Synced() }) + // start log indexer s.filterMaps.Start() go s.updateFilterMapsHeads() @@ -511,6 +517,7 @@ func (s *Ethereum) setupDiscovery() error { func (s *Ethereum) Stop() error { // Stop all the peer-related stuff first. s.discmix.Close() + s.dropper.Stop() s.handler.Stop() // Then stop everything else. diff --git a/eth/dropper.go b/eth/dropper.go new file mode 100644 index 0000000000..51f2a7a95a --- /dev/null +++ b/eth/dropper.go @@ -0,0 +1,167 @@ +// Copyright 2025 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 eth + +import ( + mrand "math/rand" + "slices" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "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" +) + +const ( + // Interval between peer drop events (uniform between min and max) + peerDropIntervalMin = 3 * time.Minute + // Interval between peer drop events (uniform between min and max) + peerDropIntervalMax = 7 * time.Minute + // Avoid dropping peers for some time after connection + doNotDropBefore = 10 * time.Minute + // How close to max should we initiate the drop timer. O should be fine, + // dropping when no more peers can be added. Larger numbers result in more + // aggressive drop behavior. + peerDropThreshold = 0 +) + +var ( + // droppedInbound is the number of inbound peers dropped + droppedInbound = metrics.NewRegisteredMeter("eth/dropper/inbound", nil) + // droppedOutbound is the number of outbound peers dropped + droppedOutbound = metrics.NewRegisteredMeter("eth/dropper/outbound", nil) +) + +// dropper monitors the state of the peer pool and makes changes as follows: +// - during sync the Downloader handles peer connections, so dropper is disabled +// - if not syncing and the peer count is close to the limit, it drops peers +// randomly every peerDropInterval to make space for new peers +// - peers are dropped separately from the inboud pool and from the dialed pool +type dropper struct { + maxDialPeers int // maximum number of dialed peers + maxInboundPeers int // maximum number of inbound peers + peersFunc getPeersFunc + syncingFunc getSyncingFunc + + // peerDropTimer introduces churn if we are close to limit capacity. + // We handle Dialed and Inbound connections separately + peerDropTimer *time.Timer + + wg sync.WaitGroup // wg for graceful shutdown + shutdownCh chan struct{} +} + +// Callback type to get the list of connected peers. +type getPeersFunc func() []*p2p.Peer + +// Callback type to get syncing status. +// Returns true while syncing, false when synced. +type getSyncingFunc func() bool + +func newDropper(maxDialPeers, maxInboundPeers int) *dropper { + cm := &dropper{ + maxDialPeers: maxDialPeers, + maxInboundPeers: maxInboundPeers, + peerDropTimer: time.NewTimer(randomDuration(peerDropIntervalMin, peerDropIntervalMax)), + shutdownCh: make(chan struct{}), + } + if peerDropIntervalMin > peerDropIntervalMax { + panic("peerDropIntervalMin duration must be less than or equal to peerDropIntervalMax duration") + } + return cm +} + +// Start the dropper. +func (cm *dropper) Start(srv *p2p.Server, syncingFunc getSyncingFunc) { + cm.peersFunc = srv.Peers + cm.syncingFunc = syncingFunc + cm.wg.Add(1) + go cm.loop() +} + +// Stop the dropper. +func (cm *dropper) Stop() { + cm.peerDropTimer.Stop() + close(cm.shutdownCh) + cm.wg.Wait() +} + +// dropRandomPeer selects one of the peers randomly and drops it from the peer pool. +func (cm *dropper) dropRandomPeer() bool { + peers := cm.peersFunc() + var numInbound int + for _, p := range peers { + if p.Inbound() { + numInbound++ + } + } + numDialed := len(peers) - numInbound + + selectDoNotDrop := func(p *p2p.Peer) bool { + // Avoid dropping trusted and static peers, or recent peers. + // Only drop peers if their respective category (dialed/inbound) + // is close to limit capacity. + return p.Trusted() || p.StaticDialed() || + p.Lifetime() < mclock.AbsTime(doNotDropBefore) || + (p.DynDialed() && cm.maxDialPeers-numDialed > peerDropThreshold) || + (p.Inbound() && cm.maxInboundPeers-numInbound > peerDropThreshold) + } + + droppable := slices.DeleteFunc(peers, selectDoNotDrop) + if len(droppable) > 0 { + p := droppable[mrand.Intn(len(droppable))] + log.Debug("Dropping random peer", "inbound", p.Inbound(), + "id", p.ID(), "duration", common.PrettyDuration(p.Lifetime()), "peercountbefore", len(peers)) + p.Disconnect(p2p.DiscUselessPeer) + if p.Inbound() { + droppedInbound.Mark(1) + } else { + droppedOutbound.Mark(1) + } + return true + } + return false +} + +// randomDuration generates a random duration between min and max. +func randomDuration(min, max time.Duration) time.Duration { + if min > max { + panic("min duration must be less than or equal to max duration") + } + return time.Duration(mrand.Int63n(int64(max-min)) + int64(min)) +} + +// loop is the main loop of the connection dropper. +func (cm *dropper) loop() { + defer cm.wg.Done() + + for { + select { + case <-cm.peerDropTimer.C: + // Drop a random peer if we are not syncing and the peer count is close to the limit. + if !cm.syncingFunc() { + cm.dropRandomPeer() + } + cm.peerDropTimer.Reset(randomDuration(peerDropIntervalMin, peerDropIntervalMax)) + case <-cm.shutdownCh: + return + } + } +} diff --git a/p2p/peer.go b/p2p/peer.go index 9ffb94e5a8..9a0a750ac8 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -220,11 +220,35 @@ func (p *Peer) String() string { return fmt.Sprintf("Peer %x %v", id[:8], p.RemoteAddr()) } -// Inbound returns true if the peer is an inbound connection +// Inbound returns true if the peer is an inbound (not dialed) connection. func (p *Peer) Inbound() bool { return p.rw.is(inboundConn) } +// Trusted returns true if the peer is configured as trusted. +// Trusted peers are accepted in above the MaxInboundConns limit. +// The peer can be either inbound or dialed. +func (p *Peer) Trusted() bool { + return p.rw.is(trustedConn) +} + +// DynDialed returns true if the peer was dialed successfully (passed handshake) and +// it is not configured as static. +func (p *Peer) DynDialed() bool { + return p.rw.is(dynDialedConn) +} + +// StaticDialed returns true if the peer was dialed successfully (passed handshake) and +// it is configured as static. +func (p *Peer) StaticDialed() bool { + return p.rw.is(staticDialedConn) +} + +// Lifetime returns the time since peer creation. +func (p *Peer) Lifetime() mclock.AbsTime { + return mclock.Now() - p.created +} + func newPeer(log log.Logger, conn *conn, protocols []Protocol) *Peer { protomap := matchProtocols(protocols, conn.caps, conn) p := &Peer{ diff --git a/p2p/server.go b/p2p/server.go index c1564352e5..4e72e29fa0 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -508,7 +508,7 @@ func (srv *Server) setupDiscovery() error { func (srv *Server) setupDialScheduler() { config := dialConfig{ self: srv.localnode.ID(), - maxDialPeers: srv.maxDialedConns(), + maxDialPeers: srv.MaxDialedConns(), maxActiveDials: srv.MaxPendingPeers, log: srv.Logger, netRestrict: srv.NetRestrict, @@ -527,11 +527,11 @@ func (srv *Server) setupDialScheduler() { } } -func (srv *Server) maxInboundConns() int { - return srv.MaxPeers - srv.maxDialedConns() +func (srv *Server) MaxInboundConns() int { + return srv.MaxPeers - srv.MaxDialedConns() } -func (srv *Server) maxDialedConns() (limit int) { +func (srv *Server) MaxDialedConns() (limit int) { if srv.NoDial || srv.MaxPeers == 0 { return 0 } @@ -736,7 +736,7 @@ func (srv *Server) postHandshakeChecks(peers map[enode.ID]*Peer, inboundCount in switch { case !c.is(trustedConn) && len(peers) >= srv.MaxPeers: return DiscTooManyPeers - case !c.is(trustedConn) && c.is(inboundConn) && inboundCount >= srv.maxInboundConns(): + case !c.is(trustedConn) && c.is(inboundConn) && inboundCount >= srv.MaxInboundConns(): return DiscTooManyPeers case peers[c.node.ID()] != nil: return DiscAlreadyConnected From 48ec86abbbcbe42d66302e9d4839d82cd9ced36f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 15 Apr 2025 14:32:46 +0200 Subject: [PATCH 288/940] core: initialize history pruning in BlockChain (#31636) I added the history mode configuration in eth/ethconfig initially, since it seemed like the logical place. But it turns out we need access to the intended pruning setting at a deeper level, and it actually needs to be integrated with the blockchain startup procedure. With this change applied, if a node previously had its history pruned, and is subsequently restarted **without** the `--history.chain postmerge` flag, the `BlockChain` initialization code will now verify the freezer tail against the known pruning point of the predefined network and will restore pruning status. Note that this logic is quite restrictive, we allow non-zero tail only for known networks, and only for the specific pruning point that is defined. --- cmd/geth/chaincmd.go | 4 +- cmd/workload/testsuite.go | 6 +- core/block_validator_test.go | 10 ++- core/blockchain.go | 64 ++++++++++++++++++- core/blockchain_reader.go | 6 +- core/blockchain_test.go | 58 +++++++++++------ .../ethconfig => core/history}/historymode.go | 28 ++++---- eth/api_backend.go | 10 +-- eth/backend.go | 44 +++++-------- eth/ethconfig/config.go | 5 +- eth/ethconfig/gen_config.go | 31 +++++++-- eth/filters/api.go | 4 +- eth/filters/filter.go | 4 +- eth/filters/filter_system.go | 4 +- 14 files changed, 188 insertions(+), 90 deletions(-) rename {eth/ethconfig => core/history}/historymode.go (79%) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 2279509542..c57a9a947d 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -31,11 +31,11 @@ import ( "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/history" "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" - "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/internal/era" @@ -625,7 +625,7 @@ func pruneHistory(ctx *cli.Context) error { defer chain.Stop() // Determine the prune point. This will be the first PoS block. - prunePoint, ok := ethconfig.HistoryPrunePoints[chain.Genesis().Hash()] + prunePoint, ok := history.PrunePoints[chain.Genesis().Hash()] if !ok || prunePoint == nil { return errors.New("prune point not found") } diff --git a/cmd/workload/testsuite.go b/cmd/workload/testsuite.go index e7019e2055..e8e25e7731 100644 --- a/cmd/workload/testsuite.go +++ b/cmd/workload/testsuite.go @@ -23,7 +23,7 @@ import ( "os" "slices" - "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/core/history" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/internal/utesting" "github.com/ethereum/go-ethereum/log" @@ -124,13 +124,13 @@ func testConfigFromCLI(ctx *cli.Context) (cfg testConfig) { cfg.filterQueryFile = "queries/filter_queries_mainnet.json" cfg.historyTestFile = "queries/history_mainnet.json" cfg.historyPruneBlock = new(uint64) - *cfg.historyPruneBlock = ethconfig.HistoryPrunePoints[params.MainnetGenesisHash].BlockNumber + *cfg.historyPruneBlock = history.PrunePoints[params.MainnetGenesisHash].BlockNumber case ctx.Bool(testSepoliaFlag.Name): cfg.fsys = builtinTestFiles cfg.filterQueryFile = "queries/filter_queries_sepolia.json" cfg.historyTestFile = "queries/history_sepolia.json" cfg.historyPruneBlock = new(uint64) - *cfg.historyPruneBlock = ethconfig.HistoryPrunePoints[params.SepoliaGenesisHash].BlockNumber + *cfg.historyPruneBlock = history.PrunePoints[params.SepoliaGenesisHash].BlockNumber default: cfg.fsys = os.DirFS(".") cfg.filterQueryFile = ctx.String(filterQueryFileFlag.Name) diff --git a/core/block_validator_test.go b/core/block_validator_test.go index 8af4057693..5217979236 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -50,8 +50,11 @@ func testHeaderVerification(t *testing.T, scheme string) { headers[i] = block.Header() } // Run the header checker for blocks one-by-one, checking for both valid and invalid nonces - chain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) + chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer chain.Stop() + if err != nil { + t.Fatal(err) + } for i := 0; i < len(blocks); i++ { for j, valid := range []bool{true, false} { @@ -163,8 +166,11 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) { postHeaders[i] = block.Header() } // 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) + chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil) defer chain.Stop() + if err != nil { + t.Fatal(err) + } // Verify the blocks before the merging for i := 0; i < len(preBlocks); i++ { diff --git a/core/blockchain.go b/core/blockchain.go index d56996dadb..901a93315a 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" + "github.com/ethereum/go-ethereum/core/history" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state/snapshot" @@ -158,8 +159,7 @@ type CacheConfig struct { // This defines the cutoff block for history expiry. // Blocks before this number may be unavailable in the chain database. - HistoryPruningCutoffNumber uint64 - HistoryPruningCutoffHash common.Hash + ChainHistoryMode history.HistoryMode } // triedbConfig derives the configures for trie database. @@ -255,6 +255,7 @@ type BlockChain struct { currentSnapBlock atomic.Pointer[types.Header] // Current head of snap-sync currentFinalBlock atomic.Pointer[types.Header] // Latest (consensus) finalized block currentSafeBlock atomic.Pointer[types.Header] // Latest (consensus) safe block + historyPrunePoint atomic.Pointer[history.PrunePoint] bodyCache *lru.Cache[common.Hash, *types.Body] bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue] @@ -533,6 +534,12 @@ func (bc *BlockChain) loadLastState() error { } bc.hc.SetCurrentHeader(headHeader) + // Initialize history pruning. + latest := max(headBlock.NumberU64(), headHeader.Number.Uint64()) + if err := bc.initializeHistoryPruning(latest); err != nil { + return err + } + // Restore the last known head snap block bc.currentSnapBlock.Store(headBlock.Header()) headFastBlockGauge.Update(int64(headBlock.NumberU64())) @@ -555,6 +562,7 @@ func (bc *BlockChain) loadLastState() error { headSafeBlockGauge.Update(int64(block.NumberU64())) } } + // Issue a status log for the user var ( currentSnapBlock = bc.CurrentSnapBlock() @@ -573,9 +581,57 @@ func (bc *BlockChain) loadLastState() error { if pivot := rawdb.ReadLastPivotNumber(bc.db); pivot != nil { log.Info("Loaded last snap-sync pivot marker", "number", *pivot) } + if pruning := bc.historyPrunePoint.Load(); pruning != nil { + log.Info("Chain history is pruned", "earliest", pruning.BlockNumber, "hash", pruning.BlockHash) + } return nil } +// initializeHistoryPruning sets bc.historyPrunePoint. +func (bc *BlockChain) initializeHistoryPruning(latest uint64) error { + freezerTail, _ := bc.db.Tail() + + switch bc.cacheConfig.ChainHistoryMode { + case history.KeepAll: + if freezerTail == 0 { + return nil + } + // The database was pruned somehow, so we need to figure out if it's a known + // configuration or an error. + predefinedPoint := history.PrunePoints[bc.genesisBlock.Hash()] + if predefinedPoint == nil || freezerTail != predefinedPoint.BlockNumber { + log.Error("Chain history database is pruned with unknown configuration", "tail", freezerTail) + return fmt.Errorf("unexpected database tail") + } + bc.historyPrunePoint.Store(predefinedPoint) + return nil + + case history.KeepPostMerge: + if freezerTail == 0 && latest != 0 { + // This is the case where a user is trying to run with --history.chain + // postmerge directly on an existing DB. We could just trigger the pruning + // here, but it'd be a bit dangerous since they may not have intended this + // action to happen. So just tell them how to do it. + log.Error(fmt.Sprintf("Chain history mode is configured as %q, but database is not pruned.", bc.cacheConfig.ChainHistoryMode.String())) + log.Error(fmt.Sprintf("Run 'geth prune-history' to prune pre-merge history.")) + return fmt.Errorf("history pruning requested via configuration") + } + predefinedPoint := history.PrunePoints[bc.genesisBlock.Hash()] + if predefinedPoint == nil { + log.Error("Chain history pruning is not supported for this network", "genesis", bc.genesisBlock.Hash()) + return fmt.Errorf("history pruning requested for unknown network") + } else if freezerTail != predefinedPoint.BlockNumber { + log.Error("Chain history database is pruned to unknown block", "tail", freezerTail) + return fmt.Errorf("unexpected database tail") + } + bc.historyPrunePoint.Store(predefinedPoint) + return nil + + default: + return fmt.Errorf("invalid history mode: %d", bc.cacheConfig.ChainHistoryMode) + } +} + // SetHead rewinds the local chain to a new head. Depending on whether the node // was snap synced or full synced and in which state, the method will try to // delete minimal data from disk whilst retaining chain consistency. @@ -1014,7 +1070,9 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) bc.currentSnapBlock.Store(bc.genesisBlock.Header()) headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) - return nil + + // Reset history pruning status. + return bc.initializeHistoryPruning(0) } // Export writes the active chain to the given writer. diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 4114723469..a8c2e26d18 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -410,7 +410,11 @@ func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) { // HistoryPruningCutoff returns the configured history pruning point. // Blocks before this might not be available in the database. func (bc *BlockChain) HistoryPruningCutoff() (uint64, common.Hash) { - return bc.cacheConfig.HistoryPruningCutoffNumber, bc.cacheConfig.HistoryPruningCutoffHash + pt := bc.historyPrunePoint.Load() + if pt == nil { + return 0, bc.genesisBlock.Hash() + } + return pt.BlockNumber, pt.BlockHash } // TrieDB retrieves the low level trie database used for data storage. diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 3f7c03b93c..289eff0a8f 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -33,6 +33,7 @@ import ( "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/history" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -4257,13 +4258,7 @@ func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) { // be persisted without the receipts and bodies; chain after should be persisted // normally. func TestInsertChainWithCutoff(t *testing.T) { - testInsertChainWithCutoff(t, 32, 32) // cutoff = 32, ancientLimit = 32 - testInsertChainWithCutoff(t, 32, 64) // cutoff = 32, ancientLimit = 64 (entire chain in ancient) - testInsertChainWithCutoff(t, 32, 65) // cutoff = 32, ancientLimit = 65 (64 blocks in ancient, 1 block in live) -} - -func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64) { - // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) + const chainLength = 64 // Configure and generate a sample block chain var ( @@ -4278,24 +4273,51 @@ func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64) signer = types.LatestSigner(gspec.Config) engine = beacon.New(ethash.NewFaker()) ) - _, blocks, receipts := GenerateChainWithGenesis(gspec, engine, int(2*cutoff), func(i int, block *BlockGen) { + _, blocks, receipts := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, block *BlockGen) { block.SetCoinbase(common.Address{0x00}) - tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key) if err != nil { panic(err) } block.AddTx(tx) }) + + // Run the actual tests. + t.Run("cutoff-32/ancientLimit-32", func(t *testing.T) { + // cutoff = 32, ancientLimit = 32 + testInsertChainWithCutoff(t, 32, 32, gspec, blocks, receipts) + }) + t.Run("cutoff-32/ancientLimit-64", func(t *testing.T) { + // cutoff = 32, ancientLimit = 64 (entire chain in ancient) + testInsertChainWithCutoff(t, 32, 64, gspec, blocks, receipts) + }) + t.Run("cutoff-32/ancientLimit-64", func(t *testing.T) { + // cutoff = 32, ancientLimit = 65 (64 blocks in ancient, 1 block in live) + testInsertChainWithCutoff(t, 32, 65, gspec, blocks, receipts) + }) +} + +func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64, genesis *Genesis, blocks []*types.Block, receipts []types.Receipts) { + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) + + // Add a known pruning point for the duration of the test. + ghash := genesis.ToBlock().Hash() + cutoffBlock := blocks[cutoff-1] + history.PrunePoints[ghash] = &history.PrunePoint{ + BlockNumber: cutoffBlock.NumberU64(), + BlockHash: cutoffBlock.Hash(), + } + defer func() { + delete(history.PrunePoints, ghash) + }() + + // Enable pruning in cache config. + config := DefaultCacheConfigWithScheme(rawdb.PathScheme) + config.ChainHistoryMode = history.KeepPostMerge + db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) defer db.Close() - - cutoffBlock := blocks[cutoff-1] - config := DefaultCacheConfigWithScheme(rawdb.PathScheme) - config.HistoryPruningCutoffNumber = cutoffBlock.NumberU64() - config.HistoryPruningCutoffHash = cutoffBlock.Hash() - - chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil) + chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), genesis, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil) defer chain.Stop() var ( @@ -4326,8 +4348,8 @@ func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64) t.Errorf("head header #%d: header mismatch: want: %v, got: %v", headHeader.Number, blocks[len(blocks)-1].Hash(), headHeader.Hash()) } headBlock := chain.CurrentBlock() - if headBlock.Hash() != gspec.ToBlock().Hash() { - t.Errorf("head block #%d: header mismatch: want: %v, got: %v", headBlock.Number, gspec.ToBlock().Hash(), headBlock.Hash()) + if headBlock.Hash() != ghash { + t.Errorf("head block #%d: header mismatch: want: %v, got: %v", headBlock.Number, ghash, headBlock.Hash()) } // Iterate over all chain data components, and cross reference diff --git a/eth/ethconfig/historymode.go b/core/history/historymode.go similarity index 79% rename from eth/ethconfig/historymode.go rename to core/history/historymode.go index a595d72feb..e735222d37 100644 --- a/eth/ethconfig/historymode.go +++ b/core/history/historymode.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 ethconfig +package history import ( "fmt" @@ -27,22 +27,22 @@ import ( type HistoryMode uint32 const ( - // AllHistory (default) means that all chain history down to genesis block will be kept. - AllHistory HistoryMode = iota + // KeepAll (default) means that all chain history down to genesis block will be kept. + KeepAll HistoryMode = iota - // PostMergeHistory sets the history pruning point to the merge activation block. - PostMergeHistory + // KeepPostMerge sets the history pruning point to the merge activation block. + KeepPostMerge ) func (m HistoryMode) IsValid() bool { - return m <= PostMergeHistory + return m <= KeepPostMerge } func (m HistoryMode) String() string { switch m { - case AllHistory: + case KeepAll: return "all" - case PostMergeHistory: + case KeepPostMerge: return "postmerge" default: return fmt.Sprintf("invalid HistoryMode(%d)", m) @@ -61,24 +61,24 @@ func (m HistoryMode) MarshalText() ([]byte, error) { func (m *HistoryMode) UnmarshalText(text []byte) error { switch string(text) { case "all": - *m = AllHistory + *m = KeepAll case "postmerge": - *m = PostMergeHistory + *m = KeepPostMerge default: return fmt.Errorf(`unknown sync mode %q, want "all" or "postmerge"`, text) } return nil } -type HistoryPrunePoint struct { +type PrunePoint struct { BlockNumber uint64 BlockHash common.Hash } -// HistoryPrunePoints contains the pre-defined history pruning cutoff blocks for known networks. +// PrunePoints the pre-defined history pruning cutoff blocks for known networks. // They point to the first post-merge block. Any pruning should truncate *up to* but excluding // given block. -var HistoryPrunePoints = map[common.Hash]*HistoryPrunePoint{ +var PrunePoints = map[common.Hash]*PrunePoint{ // mainnet params.MainnetGenesisHash: { BlockNumber: 15537393, @@ -91,7 +91,7 @@ var HistoryPrunePoints = map[common.Hash]*HistoryPrunePoint{ }, } -// PrunedHistoryError is returned when the requested history is pruned. +// PrunedHistoryError is returned by APIs when the requested history is pruned. type PrunedHistoryError struct{} func (e *PrunedHistoryError) Error() string { return "pruned history unavailable" } diff --git a/eth/api_backend.go b/eth/api_backend.go index b39dd4cbdb..182c081d2b 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -29,12 +29,12 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/filtermaps" + "github.com/ethereum/go-ethereum/core/history" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethdb" @@ -156,7 +156,7 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe } block := b.eth.blockchain.GetBlockByNumber(bn) if block == nil && bn < b.HistoryPruningCutoff() { - return nil, ðconfig.PrunedHistoryError{} + return nil, &history.PrunedHistoryError{} } return block, nil } @@ -168,7 +168,7 @@ func (b *EthAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*typ } block := b.eth.blockchain.GetBlock(hash, *number) if block == nil && *number < b.HistoryPruningCutoff() { - return nil, ðconfig.PrunedHistoryError{} + return nil, &history.PrunedHistoryError{} } return block, nil } @@ -181,7 +181,7 @@ func (b *EthAPIBackend) GetBody(ctx context.Context, hash common.Hash, number rp body := b.eth.blockchain.GetBody(hash) if body == nil { if uint64(number) < b.HistoryPruningCutoff() { - return nil, ðconfig.PrunedHistoryError{} + return nil, &history.PrunedHistoryError{} } return nil, errors.New("block body not found") } @@ -203,7 +203,7 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r block := b.eth.blockchain.GetBlock(hash, header.Number.Uint64()) if block == nil { if header.Number.Uint64() < b.HistoryPruningCutoff() { - return nil, ðconfig.PrunedHistoryError{} + return nil, &history.PrunedHistoryError{} } return nil, errors.New("header found, but block body is missing") } diff --git a/eth/backend.go b/eth/backend.go index c5dec77962..6d1b6bae99 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -145,7 +145,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { // Here we determine genesis hash and active ChainConfig. // We need these to figure out the consensus parameters and to set up history pruning. - chainConfig, genesisHash, err := core.LoadChainConfig(chainDb, config.Genesis) + chainConfig, _, err := core.LoadChainConfig(chainDb, config.Genesis) if err != nil { return nil, err } @@ -153,22 +153,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } - - // Validate history pruning configuration. - var ( - cutoffNumber uint64 - cutoffHash common.Hash - ) - if config.HistoryMode == ethconfig.PostMergeHistory { - prunecfg, ok := ethconfig.HistoryPrunePoints[genesisHash] - if !ok { - return nil, fmt.Errorf("no history pruning point is defined for genesis %x", genesisHash) - } - cutoffNumber = prunecfg.BlockNumber - cutoffHash = prunecfg.BlockHash - log.Info("Chain cutoff configured", "number", cutoffNumber, "hash", cutoffHash) - } - // Set networkID to chainID by default. networkID := config.NetworkId if networkID == 0 { @@ -195,6 +179,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } log.Info("Initialising Ethereum protocol", "network", networkID, "dbversion", dbVer) + // Create BlockChain object. if !config.SkipBcVersionCheck { if bcVersion != nil && *bcVersion > core.BlockChainVersion { return nil, fmt.Errorf("database version is v%d, Geth %s only supports v%d", *bcVersion, version.WithMeta, core.BlockChainVersion) @@ -210,17 +195,16 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { EnablePreimageRecording: config.EnablePreimageRecording, } cacheConfig = &core.CacheConfig{ - TrieCleanLimit: config.TrieCleanCache, - TrieCleanNoPrefetch: config.NoPrefetch, - TrieDirtyLimit: config.TrieDirtyCache, - TrieDirtyDisabled: config.NoPruning, - TrieTimeLimit: config.TrieTimeout, - SnapshotLimit: config.SnapshotCache, - Preimages: config.Preimages, - StateHistory: config.StateHistory, - StateScheme: scheme, - HistoryPruningCutoffNumber: cutoffNumber, - HistoryPruningCutoffHash: cutoffHash, + TrieCleanLimit: config.TrieCleanCache, + TrieCleanNoPrefetch: config.NoPrefetch, + TrieDirtyLimit: config.TrieDirtyCache, + TrieDirtyDisabled: config.NoPruning, + TrieTimeLimit: config.TrieTimeout, + SnapshotLimit: config.SnapshotCache, + Preimages: config.Preimages, + StateHistory: config.StateHistory, + StateScheme: scheme, + ChainHistoryMode: config.HistoryMode, } ) if config.VMTrace != "" { @@ -246,6 +230,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } + + // Initialize filtermaps log index. fmConfig := filtermaps.Config{ History: config.LogHistory, Disabled: config.LogNoHistory, @@ -261,6 +247,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { eth.filterMaps = filtermaps.NewFilterMaps(chainDb, chainView, historyCutoff, finalBlock, filtermaps.DefaultParams, fmConfig) eth.closeFilterMaps = make(chan chan struct{}) + // TxPool if config.TxPool.Journal != "" { config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal) } @@ -285,6 +272,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { eth.localTxTracker = locals.New(config.TxPool.Journal, rejournal, eth.blockchain.Config(), eth.txPool) stack.RegisterLifecycle(eth.localTxTracker) } + // 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{ diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 365857347c..5e19824135 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -27,6 +27,7 @@ import ( "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/history" "github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/core/txpool/legacypool" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -48,7 +49,7 @@ var FullNodeGPO = gasprice.Config{ // Defaults contains default settings for use on the Ethereum main net. var Defaults = Config{ - HistoryMode: AllHistory, + HistoryMode: history.KeepAll, SyncMode: SnapSync, NetworkId: 0, // enable auto configuration of networkID == chainID TxLookupLimit: 2350000, @@ -84,7 +85,7 @@ type Config struct { SyncMode SyncMode // HistoryMode configures chain history retention. - HistoryMode HistoryMode + HistoryMode history.HistoryMode // This can be set to list of enrtree:// URLs which will be queried for // nodes to connect to. diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index bcfe8a31d6..cdcddcc772 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/history" "github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/core/txpool/legacypool" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -19,13 +20,16 @@ func (c Config) MarshalTOML() (interface{}, error) { Genesis *core.Genesis `toml:",omitempty"` NetworkId uint64 SyncMode SyncMode - HistoryMode HistoryMode + HistoryMode history.HistoryMode EthDiscoveryURLs []string SnapDiscoveryURLs []string NoPruning bool NoPrefetch bool - TxLookupLimit uint64 `toml:",omitempty"` - TransactionHistory uint64 `toml:",omitempty"` + TxLookupLimit uint64 `toml:",omitempty"` + TransactionHistory uint64 `toml:",omitempty"` + LogHistory uint64 `toml:",omitempty"` + LogNoHistory bool `toml:",omitempty"` + LogExportCheckpoints string StateHistory uint64 `toml:",omitempty"` StateScheme string `toml:",omitempty"` RequiredBlocks map[uint64]common.Hash `toml:"-"` @@ -63,6 +67,9 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.NoPrefetch = c.NoPrefetch enc.TxLookupLimit = c.TxLookupLimit enc.TransactionHistory = c.TransactionHistory + enc.LogHistory = c.LogHistory + enc.LogNoHistory = c.LogNoHistory + enc.LogExportCheckpoints = c.LogExportCheckpoints enc.StateHistory = c.StateHistory enc.StateScheme = c.StateScheme enc.RequiredBlocks = c.RequiredBlocks @@ -97,13 +104,16 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { Genesis *core.Genesis `toml:",omitempty"` NetworkId *uint64 SyncMode *SyncMode - HistoryMode *HistoryMode + HistoryMode *history.HistoryMode EthDiscoveryURLs []string SnapDiscoveryURLs []string NoPruning *bool NoPrefetch *bool - TxLookupLimit *uint64 `toml:",omitempty"` - TransactionHistory *uint64 `toml:",omitempty"` + TxLookupLimit *uint64 `toml:",omitempty"` + TransactionHistory *uint64 `toml:",omitempty"` + LogHistory *uint64 `toml:",omitempty"` + LogNoHistory *bool `toml:",omitempty"` + LogExportCheckpoints *string StateHistory *uint64 `toml:",omitempty"` StateScheme *string `toml:",omitempty"` RequiredBlocks map[uint64]common.Hash `toml:"-"` @@ -164,6 +174,15 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.TransactionHistory != nil { c.TransactionHistory = *dec.TransactionHistory } + if dec.LogHistory != nil { + c.LogHistory = *dec.LogHistory + } + if dec.LogNoHistory != nil { + c.LogNoHistory = *dec.LogNoHistory + } + if dec.LogExportCheckpoints != nil { + c.LogExportCheckpoints = *dec.LogExportCheckpoints + } if dec.StateHistory != nil { c.StateHistory = *dec.StateHistory } diff --git a/eth/filters/api.go b/eth/filters/api.go index 6593cbef27..864dfd3746 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -28,8 +28,8 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/history" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rpc" ) @@ -360,7 +360,7 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type return nil, errInvalidBlockRange } if begin > 0 && begin < int64(api.events.backend.HistoryPruningCutoff()) { - return nil, ðconfig.PrunedHistoryError{} + return nil, &history.PrunedHistoryError{} } // Construct the range filter filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics) diff --git a/eth/filters/filter.go b/eth/filters/filter.go index e44b37d047..78c80d8f26 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -26,8 +26,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/filtermaps" + "github.com/ethereum/go-ethereum/core/history" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" ) @@ -88,7 +88,7 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return nil, errors.New("unknown block") } if header.Number.Uint64() < f.sys.backend.HistoryPruningCutoff() { - return nil, ðconfig.PrunedHistoryError{} + return nil, &history.PrunedHistoryError{} } return f.blockLogs(ctx, header) } diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index aca3c03ad6..b787f1067b 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -30,8 +30,8 @@ import ( "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/filtermaps" + "github.com/ethereum/go-ethereum/core/history" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" @@ -311,7 +311,7 @@ func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*typ } // Queries beyond the pruning cutoff are not supported. if uint64(from) < es.backend.HistoryPruningCutoff() { - return nil, ðconfig.PrunedHistoryError{} + return nil, &history.PrunedHistoryError{} } // only interested in new mined logs From 476f117211d0618ac3fa762a347089005fa90d2e Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 15 Apr 2025 20:34:34 +0800 Subject: [PATCH 289/940] all: remove martin from CODEOWNERS (#31637) Thank you, @holiman, for being an integral part of the Go-Ethereum and for your invaluable contributions over the years. This will always be your home and you're welcome back anytime! --- .github/CODEOWNERS | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b569180852..681b5e7c66 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,12 +9,11 @@ beacon/light/ @zsfelfoldi beacon/merkle/ @zsfelfoldi beacon/types/ @zsfelfoldi @fjl beacon/params/ @zsfelfoldi @fjl -cmd/clef/ @holiman -cmd/evm/ @holiman @MariusVanDerWijden @lightclient -core/state/ @rjl493456442 @holiman -crypto/ @gballet @jwasinger @holiman @fjl -core/ @holiman @rjl493456442 -eth/ @holiman @rjl493456442 +cmd/evm/ @MariusVanDerWijden @lightclient +core/state/ @rjl493456442 +crypto/ @gballet @jwasinger @fjl +core/ @rjl493456442 +eth/ @rjl493456442 eth/catalyst/ @MariusVanDerWijden @lightclient @fjl @jwasinger eth/tracers/ @s1na ethclient/ @fjl @@ -26,11 +25,9 @@ core/tracing/ @s1na graphql/ @s1na internal/ethapi/ @fjl @s1na @lightclient internal/era/ @lightclient -metrics/ @holiman -miner/ @MariusVanDerWijden @holiman @fjl @rjl493456442 +miner/ @MariusVanDerWijden @fjl @rjl493456442 node/ @fjl p2p/ @fjl @zsfelfoldi rlp/ @fjl -params/ @fjl @holiman @karalabe @gballet @rjl493456442 @zsfelfoldi -rpc/ @fjl @holiman -signer/ @holiman +params/ @fjl @karalabe @gballet @rjl493456442 @zsfelfoldi +rpc/ @fjl From 6928ec5d924604cc403a74ef3bbca29505443ab6 Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Tue, 15 Apr 2025 20:40:30 +0200 Subject: [PATCH 290/940] p2p: fix dial metrics not picking up the right error (#31621) Our metrics related to dial errors were off. The original error was not wrapped, so the caller function had no chance of picking it up. Therefore the most common error, which is "TooManyPeers", was not correctly counted. The metrics were originally introduced in https://github.com/ethereum/go-ethereum/pull/27621 I was thinking of various possible solutions. - the one proposed here wraps both the new error and the origial error. It is not a pattern we use in other parts of the code, but works. This is maybe the smallest possible change. - as an alternate, I could write a proper `errProtoHandshakeError` with it's own wrapped error - finally, I'm not even sure we need `errProtoHandshakeError`, maybe we could just pass up the original error. --------- Signed-off-by: Csaba Kiraly Co-authored-by: Felix Lange --- p2p/metrics.go | 41 ++++++++++++++++++++++++----------------- p2p/server.go | 12 ++++++++---- p2p/server_test.go | 4 ++-- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/p2p/metrics.go b/p2p/metrics.go index 8c9804206b..29c2acb0cb 100644 --- a/p2p/metrics.go +++ b/p2p/metrics.go @@ -49,7 +49,7 @@ var ( serveSuccessMeter = metrics.NewRegisteredMeter("p2p/serves/success", nil) dialMeter = metrics.NewRegisteredMeter("p2p/dials", nil) dialSuccessMeter = metrics.NewRegisteredMeter("p2p/dials/success", nil) - dialConnectionError = metrics.NewRegisteredMeter("p2p/dials/error/connection", nil) + dialConnectionError = metrics.NewRegisteredMeter("p2p/dials/error/connection", nil) // dial timeout; no route to host; connection refused; network is unreachable // count peers that stayed connected for at least 1 min serve1MinSuccessMeter = metrics.NewRegisteredMeter("p2p/serves/success/1min", nil) @@ -61,34 +61,41 @@ var ( dialSelf = metrics.NewRegisteredMeter("p2p/dials/error/self", nil) dialUselessPeer = metrics.NewRegisteredMeter("p2p/dials/error/useless", nil) dialUnexpectedIdentity = metrics.NewRegisteredMeter("p2p/dials/error/id/unexpected", nil) - dialEncHandshakeError = metrics.NewRegisteredMeter("p2p/dials/error/rlpx/enc", nil) - dialProtoHandshakeError = metrics.NewRegisteredMeter("p2p/dials/error/rlpx/proto", nil) + dialEncHandshakeError = metrics.NewRegisteredMeter("p2p/dials/error/rlpx/enc", nil) // EOF; connection reset during handshake; message too big; i/o timeout + dialProtoHandshakeError = metrics.NewRegisteredMeter("p2p/dials/error/rlpx/proto", nil) // EOF + + // capture the rest of errors that are not handled by the above meters + dialOtherError = metrics.NewRegisteredMeter("p2p/dials/error/other", nil) ) -// markDialError matches errors that occur while setting up a dial connection -// to the corresponding meter. +// markDialError matches errors that occur while setting up a dial connection to the +// corresponding meter. We don't maintain meters for evert possible error, just for +// the most interesting ones. func markDialError(err error) { if !metrics.Enabled() { return } - if err2 := errors.Unwrap(err); err2 != nil { - err = err2 - } - switch err { - case DiscTooManyPeers: + + var reason DiscReason + var handshakeErr *protoHandshakeError + d := errors.As(err, &reason) + switch { + case d && reason == DiscTooManyPeers: dialTooManyPeers.Mark(1) - case DiscAlreadyConnected: + case d && reason == DiscAlreadyConnected: dialAlreadyConnected.Mark(1) - case DiscSelf: + case d && reason == DiscSelf: dialSelf.Mark(1) - case DiscUselessPeer: + case d && reason == DiscUselessPeer: dialUselessPeer.Mark(1) - case DiscUnexpectedIdentity: + case d && reason == DiscUnexpectedIdentity: dialUnexpectedIdentity.Mark(1) - case errEncHandshakeError: - dialEncHandshakeError.Mark(1) - case errProtoHandshakeError: + case errors.As(err, &handshakeErr): dialProtoHandshakeError.Mark(1) + case errors.Is(err, errEncHandshakeError): + dialEncHandshakeError.Mark(1) + default: + dialOtherError.Mark(1) } } diff --git a/p2p/server.go b/p2p/server.go index 4e72e29fa0..d9105976dd 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -66,11 +66,15 @@ const ( ) var ( - errServerStopped = errors.New("server stopped") - errEncHandshakeError = errors.New("rlpx enc error") - errProtoHandshakeError = errors.New("rlpx proto error") + errServerStopped = errors.New("server stopped") + errEncHandshakeError = errors.New("rlpx enc error") ) +type protoHandshakeError struct{ err error } + +func (e *protoHandshakeError) Error() string { return fmt.Sprintf("rlpx proto error: %v", e.err) } +func (e *protoHandshakeError) Unwrap() error { return e.err } + // Server manages all peer connections. type Server struct { // Config fields may not be modified while the server is running. @@ -907,7 +911,7 @@ func (srv *Server) setupConn(c *conn, dialDest *enode.Node) error { phs, err := c.doProtoHandshake(srv.ourHandshake) if err != nil { clog.Trace("Failed p2p handshake", "err", err) - return fmt.Errorf("%w: %v", errProtoHandshakeError, err) + return &protoHandshakeError{err: err} } if id := c.node.ID(); !bytes.Equal(crypto.Keccak256(phs.ID), id[:]) { clog.Trace("Wrong devp2p handshake identity", "phsid", hex.EncodeToString(phs.ID)) diff --git a/p2p/server_test.go b/p2p/server_test.go index a0491e984a..d42926cf4c 100644 --- a/p2p/server_test.go +++ b/p2p/server_test.go @@ -410,11 +410,11 @@ func TestServerSetupConn(t *testing.T) { wantCloseErr: DiscUnexpectedIdentity, }, { - tt: &setupTransport{pubkey: clientpub, protoHandshakeErr: errProtoHandshakeError}, + tt: &setupTransport{pubkey: clientpub, protoHandshakeErr: DiscTooManyPeers}, dialDest: enode.NewV4(clientpub, nil, 0, 0), flags: dynDialedConn, wantCalls: "doEncHandshake,doProtoHandshake,close,", - wantCloseErr: errProtoHandshakeError, + wantCloseErr: DiscTooManyPeers, }, { tt: &setupTransport{pubkey: srvpub, phs: protoHandshake{ID: crypto.FromECDSAPub(srvpub)[1:]}}, From e3e9d7ccb677fe687f11d63c96be4b1b09211695 Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 16 Apr 2025 15:50:05 +0800 Subject: [PATCH 291/940] cmd/geth: remove the unused bloomfilter.size flag (#31646) --- cmd/geth/main.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index ab46e059f3..289030ae65 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -100,7 +100,6 @@ var ( utils.LightNoSyncServeFlag, // deprecated utils.EthRequiredBlocksFlag, utils.LegacyWhitelistFlag, // deprecated - utils.BloomFilterSizeFlag, utils.CacheFlag, utils.CacheDatabaseFlag, utils.CacheTrieFlag, From ebb3eb29d33770543fc0864a82e47a24d1c3e460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Wed, 16 Apr 2025 23:30:13 +0200 Subject: [PATCH 292/940] core/filtermaps: fix map renderer reorg issue (#31642) This PR fixes a bug in the map renderer that sometimes used an obsolete block log value pointer to initialize the iterator for rendering from a snapshot. This bug was triggered by chain reorgs and sometimes caused indexing errors and invalid search results. A few other conditions are also made safer that were not reported to cause issues yet but could potentially be unsafe in some corner cases. A new unit test is also added that reproduced the bug but passes with the new fixes. Fixes https://github.com/ethereum/go-ethereum/issues/31593 Might also fix https://github.com/ethereum/go-ethereum/issues/31589 though this issue has not been reproduced yet, but it appears to be related to a log index database corruption around a specific block, similarly to the other issue. Note that running this branch resets and regenerates the log index database. For this purpose a `Version` field has been added to `rawdb.FilterMapsRange` which will also make this easier in the future if a breaking database change is needed or the existing one is considered potentially broken due to a bug, like in this case. --- core/filtermaps/filtermaps.go | 27 +++++-- core/filtermaps/indexer_test.go | 110 +++++++++++++++++++++++++++++ core/filtermaps/map_renderer.go | 45 +++++------- core/filtermaps/matcher_backend.go | 3 + core/rawdb/accessors_indexes.go | 1 + 5 files changed, 153 insertions(+), 33 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index 18b1c7dc79..fa2d6e3ffb 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -50,6 +50,7 @@ var ( ) const ( + databaseVersion = 1 // reindexed if database version does not match cachedLastBlocks = 1000 // last block of map pointers cachedLvPointers = 1000 // first log value pointer of block pointers cachedBaseRows = 100 // groups of base layer filter row data @@ -138,13 +139,25 @@ type FilterMaps struct { // as transparent (uncached/unchanged). type filterMap []FilterRow -// copy returns a copy of the given filter map. Note that the row slices are -// copied but their contents are not. This permits extending the rows further +// fastCopy returns a copy of the given filter map. Note that the row slices are +// copied but their contents are not. This permits appending to the rows further // (which happens during map rendering) without affecting the validity of // copies made for snapshots during rendering. -func (fm filterMap) copy() filterMap { +// Appending to the rows of both the original map and the fast copy, or two fast +// copies of the same map would result in data corruption, therefore a fast copy +// should always be used in a read only way. +func (fm filterMap) fastCopy() filterMap { + return slices.Clone(fm) +} + +// fullCopy returns a copy of the given filter map, also making a copy of each +// individual filter row, ensuring that a modification to either one will never +// affect the other. +func (fm filterMap) fullCopy() filterMap { c := make(filterMap, len(fm)) - copy(c, fm) + for i, row := range fm { + c[i] = slices.Clone(row) + } return c } @@ -207,8 +220,9 @@ type Config struct { // NewFilterMaps creates a new FilterMaps and starts the indexer. func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) *FilterMaps { rs, initialized, err := rawdb.ReadFilterMapsRange(db) - if err != nil { - log.Error("Error reading log index range", "error", err) + if err != nil || rs.Version != databaseVersion { + rs, initialized = rawdb.FilterMapsRange{}, false + log.Warn("Invalid log index database version; resetting log index") } params.deriveFields() f := &FilterMaps{ @@ -437,6 +451,7 @@ func (f *FilterMaps) setRange(batch ethdb.KeyValueWriter, newView *ChainView, ne f.updateMatchersValidRange() if newRange.initialized { rs := rawdb.FilterMapsRange{ + Version: databaseVersion, HeadIndexed: newRange.headIndexed, HeadDelimiter: newRange.headDelimiter, BlocksFirst: newRange.blocks.First(), diff --git a/core/filtermaps/indexer_test.go b/core/filtermaps/indexer_test.go index a02f8d2459..4dddd27087 100644 --- a/core/filtermaps/indexer_test.go +++ b/core/filtermaps/indexer_test.go @@ -17,8 +17,10 @@ package filtermaps import ( + "context" crand "crypto/rand" "crypto/sha256" + "encoding/binary" "math/big" "math/rand" "sync" @@ -31,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" ) var testParams = Params{ @@ -104,6 +107,7 @@ func TestIndexerRandomRange(t *testing.T) { fork, head = rand.Intn(len(forks)), rand.Intn(1001) ts.chain.setCanonicalChain(forks[fork][:head+1]) case 2: + checkSnapshot = false if head < 1000 { checkSnapshot = !noHistory && head != 0 // no snapshot generated for block 0 // add blocks after the current head @@ -158,6 +162,63 @@ func TestIndexerRandomRange(t *testing.T) { } } +func TestIndexerMatcherView(t *testing.T) { + testIndexerMatcherView(t, false) +} + +func TestIndexerMatcherViewWithConcurrentRead(t *testing.T) { + testIndexerMatcherView(t, true) +} + +func testIndexerMatcherView(t *testing.T, concurrentRead bool) { + ts := newTestSetup(t) + defer ts.close() + + forks := make([][]common.Hash, 20) + hashes := make([]common.Hash, 20) + ts.chain.addBlocks(100, 5, 2, 4, true) + ts.setHistory(0, false) + for i := range forks { + if i != 0 { + ts.chain.setHead(100 - i) + ts.chain.addBlocks(i, 5, 2, 4, true) + } + ts.fm.WaitIdle() + forks[i] = ts.chain.getCanonicalChain() + hashes[i] = ts.matcherViewHash() + } + fork := len(forks) - 1 + for i := 0; i < 5000; i++ { + oldFork := fork + fork = rand.Intn(len(forks)) + stopCh := make(chan chan struct{}) + if concurrentRead { + go func() { + for { + ts.matcherViewHash() + select { + case ch := <-stopCh: + close(ch) + return + default: + } + } + }() + } + ts.chain.setCanonicalChain(forks[fork]) + ts.fm.WaitIdle() + if concurrentRead { + ch := make(chan struct{}) + stopCh <- ch + <-ch + } + hash := ts.matcherViewHash() + if hash != hashes[fork] { + t.Fatalf("Matcher view hash mismatch when switching from for %d to %d", oldFork, fork) + } + } +} + func TestIndexerCompareDb(t *testing.T) { ts := newTestSetup(t) defer ts.close() @@ -291,6 +352,55 @@ func (ts *testSetup) fmDbHash() common.Hash { return result } +func (ts *testSetup) matcherViewHash() common.Hash { + mb := ts.fm.NewMatcherBackend() + defer mb.Close() + + ctx := context.Background() + params := mb.GetParams() + hasher := sha256.New() + var headPtr uint64 + for b := uint64(0); ; b++ { + lvptr, err := mb.GetBlockLvPointer(ctx, b) + if err != nil || (b > 0 && lvptr == headPtr) { + break + } + var enc [8]byte + binary.LittleEndian.PutUint64(enc[:], lvptr) + hasher.Write(enc[:]) + headPtr = lvptr + } + headMap := uint32(headPtr >> params.logValuesPerMap) + var enc [12]byte + for r := uint32(0); r < params.mapHeight; r++ { + binary.LittleEndian.PutUint32(enc[:4], r) + for m := uint32(0); m <= headMap; m++ { + binary.LittleEndian.PutUint32(enc[4:8], m) + row, _ := mb.GetFilterMapRow(ctx, m, r, false) + for _, v := range row { + binary.LittleEndian.PutUint32(enc[8:], v) + hasher.Write(enc[:]) + } + } + } + var hash common.Hash + hasher.Sum(hash[:0]) + for i := 0; i < 50; i++ { + hasher.Reset() + hasher.Write(hash[:]) + lvptr := binary.LittleEndian.Uint64(hash[:8]) % headPtr + if log, _ := mb.GetLogByLvIndex(ctx, lvptr); log != nil { + enc, err := rlp.EncodeToBytes(log) + if err != nil { + panic(err) + } + hasher.Write(enc) + } + hasher.Sum(hash[:0]) + } + return hash +} + func (ts *testSetup) close() { if ts.fm != nil { ts.fm.Stop() diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index 28f943abb3..cd960ad31c 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -84,7 +84,7 @@ func (f *FilterMaps) renderMapsBefore(renderBefore uint32) (*mapRenderer, error) if err != nil { return nil, err } - if snapshot := f.lastCanonicalSnapshotBefore(renderBefore); snapshot != nil && snapshot.mapIndex >= nextMap { + if snapshot := f.lastCanonicalSnapshotOfMap(nextMap); snapshot != nil { return f.renderMapsFromSnapshot(snapshot) } if nextMap >= renderBefore { @@ -97,14 +97,14 @@ func (f *FilterMaps) renderMapsBefore(renderBefore uint32) (*mapRenderer, error) // snapshot made at a block boundary. func (f *FilterMaps) renderMapsFromSnapshot(cp *renderedMap) (*mapRenderer, error) { f.testSnapshotUsed = true - iter, err := f.newLogIteratorFromBlockDelimiter(cp.lastBlock) + iter, err := f.newLogIteratorFromBlockDelimiter(cp.lastBlock, cp.headDelimiter) if err != nil { return nil, fmt.Errorf("failed to create log iterator from block delimiter %d: %v", cp.lastBlock, err) } return &mapRenderer{ f: f, currentMap: &renderedMap{ - filterMap: cp.filterMap.copy(), + filterMap: cp.filterMap.fullCopy(), mapIndex: cp.mapIndex, lastBlock: cp.lastBlock, blockLvPtrs: cp.blockLvPtrs, @@ -137,14 +137,14 @@ func (f *FilterMaps) renderMapsFromMapBoundary(firstMap, renderBefore uint32, st }, nil } -// lastCanonicalSnapshotBefore returns the latest cached snapshot that matches -// the current targetView. -func (f *FilterMaps) lastCanonicalSnapshotBefore(renderBefore uint32) *renderedMap { +// lastCanonicalSnapshotOfMap returns the latest cached snapshot of the given map +// that is also consistent with the current targetView. +func (f *FilterMaps) lastCanonicalSnapshotOfMap(mapIndex uint32) *renderedMap { var best *renderedMap for _, blockNumber := range f.renderSnapshots.Keys() { if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.blocks.AfterLast() && blockNumber <= f.targetView.headNumber && f.targetView.getBlockId(blockNumber) == cp.lastBlockId && - cp.mapIndex < renderBefore && (best == nil || blockNumber > best.lastBlock) { + cp.mapIndex == mapIndex && (best == nil || blockNumber > best.lastBlock) { best = cp } } @@ -171,10 +171,9 @@ func (f *FilterMaps) lastCanonicalMapBoundaryBefore(renderBefore uint32) (nextMa if err != nil { return 0, 0, 0, fmt.Errorf("failed to retrieve last block of reverse iterated map %d: %v", mapIndex, err) } - if lastBlock >= f.indexedView.headNumber || lastBlock >= f.targetView.headNumber || - lastBlockId != f.targetView.getBlockId(lastBlock) { - // map is not full or inconsistent with targetView; roll back - continue + if (f.indexedRange.headIndexed && mapIndex >= f.indexedRange.maps.Last()) || + lastBlock >= f.targetView.headNumber || lastBlockId != f.targetView.getBlockId(lastBlock) { + continue // map is not full or inconsistent with targetView; roll back } lvPtr, err := f.getBlockLvPointer(lastBlock) if err != nil { @@ -257,11 +256,14 @@ func (f *FilterMaps) loadHeadSnapshot() error { // makeSnapshot creates a snapshot of the current state of the rendered map. func (r *mapRenderer) makeSnapshot() { - r.f.renderSnapshots.Add(r.iterator.blockNumber, &renderedMap{ - filterMap: r.currentMap.filterMap.copy(), + if r.iterator.blockNumber != r.currentMap.lastBlock || r.iterator.chainView != r.f.targetView { + panic("iterator state inconsistent with current rendered map") + } + r.f.renderSnapshots.Add(r.currentMap.lastBlock, &renderedMap{ + filterMap: r.currentMap.filterMap.fastCopy(), mapIndex: r.currentMap.mapIndex, - lastBlock: r.iterator.blockNumber, - lastBlockId: r.f.targetView.getBlockId(r.currentMap.lastBlock), + lastBlock: r.currentMap.lastBlock, + lastBlockId: r.iterator.chainView.getBlockId(r.currentMap.lastBlock), blockLvPtrs: r.currentMap.blockLvPtrs, finished: true, headDelimiter: r.iterator.lvIndex, @@ -661,24 +663,13 @@ var errUnindexedRange = errors.New("unindexed range") // newLogIteratorFromBlockDelimiter creates a logIterator starting at the // given block's first log value entry (the block delimiter), according to the // current targetView. -func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber uint64) (*logIterator, error) { +func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber, lvIndex uint64) (*logIterator, error) { if blockNumber > f.targetView.headNumber { return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", blockNumber, f.targetView.headNumber) } if !f.indexedRange.blocks.Includes(blockNumber) { return nil, errUnindexedRange } - var lvIndex uint64 - if f.indexedRange.headIndexed && blockNumber+1 == f.indexedRange.blocks.AfterLast() { - lvIndex = f.indexedRange.headDelimiter - } else { - var err error - lvIndex, err = f.getBlockLvPointer(blockNumber + 1) - if err != nil { - return nil, fmt.Errorf("failed to retrieve log value pointer of block %d after delimiter: %v", blockNumber+1, err) - } - lvIndex-- - } finished := blockNumber == f.targetView.headNumber l := &logIterator{ chainView: f.targetView, diff --git a/core/filtermaps/matcher_backend.go b/core/filtermaps/matcher_backend.go index 01bae7bb22..335ac84551 100644 --- a/core/filtermaps/matcher_backend.go +++ b/core/filtermaps/matcher_backend.go @@ -75,6 +75,9 @@ func (fm *FilterMapsMatcherBackend) Close() { // on write. // GetFilterMapRow implements MatcherBackend. func (fm *FilterMapsMatcherBackend) GetFilterMapRow(ctx context.Context, mapIndex, rowIndex uint32, baseLayerOnly bool) (FilterRow, error) { + fm.f.indexLock.RLock() + defer fm.f.indexLock.RUnlock() + return fm.f.getFilterMapRow(mapIndex, rowIndex, baseLayerOnly) } diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index c413839b7b..1a5c414c8e 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -434,6 +434,7 @@ func DeleteBlockLvPointers(db ethdb.KeyValueStore, blocks common.Range[uint64], // FilterMapsRange is a storage representation of the block range covered by the // filter maps structure and the corresponting log value index range. type FilterMapsRange struct { + Version uint32 HeadIndexed bool HeadDelimiter uint64 BlocksFirst, BlocksAfterLast uint64 From 846d578cc3c9629f226f70e39c25c461e4cbf143 Mon Sep 17 00:00:00 2001 From: maskpp Date: Thu, 17 Apr 2025 05:46:38 +0800 Subject: [PATCH 293/940] core/state: fix log format (#31610) Log `key` in hexadecimal string format. --- core/state/dump.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state/dump.go b/core/state/dump.go index c9aad4f8e2..11b5c32782 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -188,7 +188,7 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey [] c.OnAccount(address, account) accounts++ if time.Since(logged) > 8*time.Second { - log.Info("Trie dumping in progress", "at", it.Key, "accounts", accounts, + log.Info("Trie dumping in progress", "at", common.Bytes2Hex(it.Key), "accounts", accounts, "elapsed", common.PrettyDuration(time.Since(start))) logged = time.Now() } From 87974974a7b3fcce873851205b889f7d839d7fb7 Mon Sep 17 00:00:00 2001 From: Miro Date: Wed, 16 Apr 2025 22:36:53 -0400 Subject: [PATCH 294/940] core/txpool/legacypool: fix data race of txlookup access (#31641) --- core/txpool/legacypool/legacypool.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 04f1a2234c..7bf360ff65 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1827,6 +1827,16 @@ func (t *lookup) Remove(hash common.Hash) { delete(t.txs, hash) } +// Clear resets the lookup structure, removing all stored entries. +func (t *lookup) Clear() { + t.lock.Lock() + defer t.lock.Unlock() + + t.slots = 0 + t.txs = make(map[common.Hash]*types.Transaction) + t.auths = make(map[common.Address][]common.Hash) +} + // TxsBelowTip finds all remote transactions below the given tip threshold. func (t *lookup) TxsBelowTip(threshold *big.Int) types.Transactions { found := make(types.Transactions, 0, 128) @@ -1923,7 +1933,7 @@ func (pool *LegacyPool) Clear() { for addr := range pool.queue { pool.reserver.Release(addr) } - pool.all = newLookup() + pool.all.Clear() pool.priced = newPricedList(pool.all) pool.pending = make(map[common.Address]*list) pool.queue = make(map[common.Address]*list) From cb21177aa8b15861067c430f12439e40fc1ad124 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 17 Apr 2025 04:39:21 +0200 Subject: [PATCH 295/940] core: fix history pruning initialization for empty DB (#31656) This fixes an issue where running geth with `--history.chain postmerge` would not work on an empty database. ``` ERROR[04-16|23:11:12.913] Chain history database is pruned to unknown block tail=0 Fatal: Failed to register the Ethereum service: unexpected database tail ``` --- core/blockchain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/blockchain.go b/core/blockchain.go index 901a93315a..203dcd2693 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -620,7 +620,7 @@ func (bc *BlockChain) initializeHistoryPruning(latest uint64) error { if predefinedPoint == nil { log.Error("Chain history pruning is not supported for this network", "genesis", bc.genesisBlock.Hash()) return fmt.Errorf("history pruning requested for unknown network") - } else if freezerTail != predefinedPoint.BlockNumber { + } else if freezerTail > 0 && freezerTail != predefinedPoint.BlockNumber { log.Error("Chain history database is pruned to unknown block", "tail", freezerTail) return fmt.Errorf("unexpected database tail") } From e4448233940904e9c36f227b71f274c9df80a250 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Thu, 17 Apr 2025 10:32:40 +0200 Subject: [PATCH 296/940] core: fix sync reset in pruned nodes (#31638) This is an attempt at fixing #31601. I think what happens is the startup logic will try to get the full block body (it's `bc.loadLastState`) and fail because genesis block has been pruned from the freezer. This will cause it to keep repeating the reset logic, causing a deadlock. This can happen when due to an unsuccessful sync we don't have the state for the head (or any other state) fully, and try to redo the snap sync. --------- Co-authored-by: Gary Rong --- core/blockchain.go | 50 +++++++++++++++++++++++++++++++------------ core/txindexer.go | 19 +++++++++++++--- core/txpool/txpool.go | 14 ++++++------ 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 203dcd2693..c4caec66ed 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -514,19 +514,33 @@ func (bc *BlockChain) loadLastState() error { log.Warn("Empty database, resetting chain") return bc.Reset() } - // Make sure the entire head block is available - headBlock := bc.GetBlockByHash(head) + headHeader := bc.GetHeaderByHash(head) + if headHeader == nil { + // Corrupt or empty database, init from scratch + log.Warn("Head header missing, resetting chain", "hash", head) + return bc.Reset() + } + + var headBlock *types.Block + if cmp := headHeader.Number.Cmp(new(big.Int)); cmp == 1 { + // Make sure the entire head block is available. + headBlock = bc.GetBlockByHash(head) + } else if cmp == 0 { + // On a pruned node the block body might not be available. But a pruned + // block should never be the head block. The only exception is when, as + // a last resort, chain is reset to genesis. + headBlock = bc.genesisBlock + } if headBlock == nil { // Corrupt or empty database, init from scratch log.Warn("Head block missing, resetting chain", "hash", head) return bc.Reset() } // Everything seems to be fine, set as the head block - bc.currentBlock.Store(headBlock.Header()) + bc.currentBlock.Store(headHeader) headBlockGauge.Update(int64(headBlock.NumberU64())) // Restore the last known head header - headHeader := headBlock.Header() if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) { if header := bc.GetHeaderByHash(head); header != nil { headHeader = header @@ -642,11 +656,15 @@ func (bc *BlockChain) SetHead(head uint64) error { // Send chain head event to update the transaction pool header := bc.CurrentBlock() if block := bc.GetBlock(header.Hash(), header.Number.Uint64()); block == nil { - // This should never happen. In practice, previously currentBlock - // contained the entire block whereas now only a "marker", so there - // is an ever so slight chance for a race we should handle. - log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash()) - return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4]) + // In a pruned node the genesis block will not exist in the freezer. + // It should not happen that we set head to any other pruned block. + if header.Number.Uint64() > 0 { + // This should never happen. In practice, previously currentBlock + // contained the entire block whereas now only a "marker", so there + // is an ever so slight chance for a race we should handle. + log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash()) + return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4]) + } } bc.chainHeadFeed.Send(ChainHeadEvent{Header: header}) return nil @@ -663,11 +681,15 @@ func (bc *BlockChain) SetHeadWithTimestamp(timestamp uint64) error { // Send chain head event to update the transaction pool header := bc.CurrentBlock() if block := bc.GetBlock(header.Hash(), header.Number.Uint64()); block == nil { - // This should never happen. In practice, previously currentBlock - // contained the entire block whereas now only a "marker", so there - // is an ever so slight chance for a race we should handle. - log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash()) - return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4]) + // In a pruned node the genesis block will not exist in the freezer. + // It should not happen that we set head to any other pruned block. + if header.Number.Uint64() > 0 { + // This should never happen. In practice, previously currentBlock + // contained the entire block whereas now only a "marker", so there + // is an ever so slight chance for a race we should handle. + log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash()) + return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4]) + } } bc.chainHeadFeed.Send(ChainHeadEvent{Header: header}) return nil diff --git a/core/txindexer.go b/core/txindexer.go index 31f069995b..64a2e8c49f 100644 --- a/core/txindexer.go +++ b/core/txindexer.go @@ -196,6 +196,19 @@ func (indexer *txIndexer) repair(head uint64) { } } +// resolveHead resolves the block number of the current chain head. +func (indexer *txIndexer) resolveHead() uint64 { + headBlockHash := rawdb.ReadHeadBlockHash(indexer.db) + if headBlockHash == (common.Hash{}) { + return 0 + } + headBlockNumber := rawdb.ReadHeaderNumber(indexer.db, headBlockHash) + if headBlockNumber == nil { + return 0 + } + return *headBlockNumber +} + // loop is the scheduler of the indexer, assigning indexing/unindexing tasks depending // on the received chain event. func (indexer *txIndexer) loop(chain *BlockChain) { @@ -203,9 +216,9 @@ func (indexer *txIndexer) loop(chain *BlockChain) { // Listening to chain events and manipulate the transaction indexes. var ( - stop chan struct{} // Non-nil if background routine is active - done chan struct{} // Non-nil if background routine is active - head = rawdb.ReadHeadBlock(indexer.db).NumberU64() // The latest announced chain head + stop chan struct{} // Non-nil if background routine is active + done chan struct{} // Non-nil if background routine is active + head = indexer.resolveHead() // The latest announced chain head headCh = make(chan ChainHeadEvent) sub = chain.SubscribeChainHeadEvent(headCh) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 2ed38772ce..fc4a7be6d2 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -186,13 +186,15 @@ func (p *TxPool) loop(head *types.Header) { // Try to inject a busy marker and start a reset if successful select { case resetBusy <- struct{}{}: - statedb, err := p.chain.StateAt(newHead.Root) - if err != nil { - log.Crit("Failed to reset txpool state", "err", err) + // Updates the statedb with the new chain head. The head state may be + // unavailable if the initial state sync has not yet completed. + if statedb, err := p.chain.StateAt(newHead.Root); err != nil { + log.Error("Failed to reset txpool state", "err", err) + } else { + p.stateLock.Lock() + p.state = statedb + p.stateLock.Unlock() } - p.stateLock.Lock() - p.state = statedb - p.stateLock.Unlock() // Busy marker injected, start a new subpool reset go func(oldHead, newHead *types.Header) { From 01786f329f2fea24ad0d8308dce3ec72880ff5d7 Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Thu, 17 Apr 2025 10:33:59 +0200 Subject: [PATCH 297/940] eth: fix transaction sender cache miss before broadcast (#31657) BroadcastTransactions needs the Sender address to route message flows from the same Sender address consistently to the same random subset of peers. It however spent considerable time calculating the Sender addresses, even if the Sender address was already calculated and cached in other parts of the code. Since we only need the mapping, we can use any signer, and the one that had already been used is a better choice because of cache reuse. --- eth/handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/handler.go b/eth/handler.go index b2ad6effdb..8283d7d02f 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -484,7 +484,7 @@ func (h *handler) BroadcastTransactions(txs types.Transactions) { total := new(big.Int).Exp(direct, big.NewInt(2), nil) // Stabilise total peer count a bit based on sqrt peers var ( - signer = types.LatestSignerForChainID(h.chain.Config().ChainID) // Don't care about chain status, we just need *a* sender + signer = types.LatestSigner(h.chain.Config()) // Don't care about chain status, we just need *a* sender hasher = crypto.NewKeccakState() hash = make([]byte, 32) ) From 50b5f3125b0f13293eda17a8724103eafd249384 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Thu, 17 Apr 2025 02:46:00 -0600 Subject: [PATCH 298/940] params: add prague timestamp for mainnet (#31535) https://eips.ethereum.org/EIPS/eip-7600#activation Timestamp: `1746612311` Fork id: `0xc376cf8b` --- core/forkid/forkid_test.go | 19 ++++++++++--------- params/config.go | 2 ++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go index 31e2b534be..413e4d77a8 100644 --- a/core/forkid/forkid_test.go +++ b/core/forkid/forkid_test.go @@ -76,8 +76,10 @@ func TestCreation(t *testing.T) { {20000000, 1681338454, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 1681338455}}, // Last Gray Glacier block {20000000, 1681338455, ID{Hash: checksumToBytes(0xdce96c2d), Next: 1710338135}}, // First Shanghai block {30000000, 1710338134, ID{Hash: checksumToBytes(0xdce96c2d), Next: 1710338135}}, // Last Shanghai block - {40000000, 1710338135, ID{Hash: checksumToBytes(0x9f3d2254), Next: 0}}, // First Cancun block - {50000000, 2000000000, ID{Hash: checksumToBytes(0x9f3d2254), Next: 0}}, // Future Cancun block + {40000000, 1710338135, ID{Hash: checksumToBytes(0x9f3d2254), Next: 1746612311}}, // First Cancun block + {30000000, 1746022486, ID{Hash: checksumToBytes(0x9f3d2254), Next: 1746612311}}, // Last Cancun block + {30000000, 1746612311, ID{Hash: checksumToBytes(0xc376cf8b), Next: 0}}, // First Prague block + {50000000, 2000000000, ID{Hash: checksumToBytes(0xc376cf8b), Next: 0}}, // Future Prague block }, }, // Sepolia test cases @@ -137,9 +139,11 @@ func TestCreation(t *testing.T) { // fork ID. func TestValidation(t *testing.T) { // Config that has not timestamp enabled + // TODO(lightclient): this always needs to be updated when a mainnet timestamp is set. legacyConfig := *params.MainnetChainConfig legacyConfig.ShanghaiTime = nil legacyConfig.CancunTime = nil + legacyConfig.PragueTime = nil tests := []struct { config *params.ChainConfig @@ -314,9 +318,7 @@ func TestValidation(t *testing.T) { // Local is mainnet Prague, remote announces Shanghai + knowledge about Cancun. Remote // is definitely out of sync. It may or may not need the Prague update, we don't know yet. - // - // TODO(karalabe): Enable this when Cancun **and** Prague is specced, update all the numbers - //{params.MainnetChainConfig, 0, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}, nil}, + {params.MainnetChainConfig, 0, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 1710338135}, nil}, // Local is mainnet Shanghai, remote announces Cancun. Local is out of sync, accept. {params.MainnetChainConfig, 21000000, 1700000000, ID{Hash: checksumToBytes(0x9f3d2254), Next: 0}, nil}, @@ -324,8 +326,7 @@ func TestValidation(t *testing.T) { // Local is mainnet Shanghai, remote announces Cancun, but is not aware of Prague. Local // out of sync. Local also knows about a future fork, but that is uncertain yet. // - // TODO(karalabe): Enable this when Cancun **and** Prague is specced, update remote checksum - //{params.MainnetChainConfig, 21000000, 1678000000, ID{Hash: checksumToBytes(0x00000000), Next: 0}, nil}, + {params.MainnetChainConfig, 21000000, 1678000000, ID{Hash: checksumToBytes(0xc376cf8b), Next: 0}, nil}, // Local is mainnet Cancun. remote announces Shanghai but is not aware of further forks. // Remote needs software update. @@ -342,11 +343,11 @@ func TestValidation(t *testing.T) { // Local is mainnet Shanghai, remote is random Shanghai. {params.MainnetChainConfig, 20000000, 1681338455, ID{Hash: checksumToBytes(0x12345678), Next: 0}, ErrLocalIncompatibleOrStale}, - // Local is mainnet Cancun, far in the future. Remote announces Gopherium (non existing fork) + // Local is mainnet Prague, far in the future. Remote announces Gopherium (non existing fork) // at some future timestamp 8888888888, for itself, but past block for local. Local is incompatible. // // This case detects non-upgraded nodes with majority hash power (typical Ropsten mess). - {params.MainnetChainConfig, 88888888, 8888888888, ID{Hash: checksumToBytes(0x9f3d2254), Next: 8888888888}, ErrLocalIncompatibleOrStale}, + {params.MainnetChainConfig, 88888888, 8888888888, ID{Hash: checksumToBytes(0xc376cf8b), Next: 8888888888}, ErrLocalIncompatibleOrStale}, // Local is mainnet Shanghai. Remote is also in Shanghai, but announces Gopherium (non existing // fork) at timestamp 1668000000, before Cancun. Local is incompatible. diff --git a/params/config.go b/params/config.go index 8f9e02583b..03b797863c 100644 --- a/params/config.go +++ b/params/config.go @@ -60,10 +60,12 @@ var ( TerminalTotalDifficulty: MainnetTerminalTotalDifficulty, // 58_750_000_000_000_000_000_000 ShanghaiTime: newUint64(1681338455), CancunTime: newUint64(1710338135), + PragueTime: newUint64(1746612311), DepositContractAddress: common.HexToAddress("0x00000000219ab540356cbb839cbe05303d7705fa"), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, + Prague: DefaultPragueBlobConfig, }, } // HoleskyChainConfig contains the chain parameters to run a node on the Holesky test network. From 13b157a461c88678cd4e15ca005e7b45d823431b Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Thu, 17 Apr 2025 02:46:47 -0600 Subject: [PATCH 299/940] core,params: add fork readiness indicator in logs (#31340) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #31310 This has been requested a few times in the past and I think it is a nice quality-of-life improvement for users. At a predetermined interval, there will now be a "Fork ready" log when a future fork is scheduled, but not yet active. It can only possibly print after block import, which kinda avoids the scenario where the client isn't progressing or is syncing and the user thinks it's "ready" because it sees a ready log. New output: ```console INFO [03-08|21:32:57.472] Imported new potential chain segment number=7 hash=aa24ee..f09e62 blocks=1 txs=0 mgas=0.000 elapsed="874.916µs" mgasps=0.000 snapdiffs=973.00B triediffs=7.05KiB triedirty=0.00B INFO [03-08|21:32:57.473] Ready for fork activation fork=Prague date="18 Mar 25 19:29 CET" remaining=237h57m0s timestamp=1,742,322,597 INFO [03-08|21:32:57.475] Chain head was updated number=7 hash=aa24ee..f09e62 root=19b0de..8d32f2 elapsed="129.125µs" ``` Easiest way to verify this behavior is to apply this patch and run `geth --dev --dev.period=12` ```patch diff --git a/params/config.go b/params/config.go index 9c7719d901..030c4f80e7 100644 --- a/params/config.go +++ b/params/config.go @@ -174,7 +174,7 @@ var ( ShanghaiTime: newUint64(0), CancunTime: newUint64(0), TerminalTotalDifficulty: big.NewInt(0), - PragueTime: newUint64(0), + PragueTime: newUint64(uint64(time.Now().Add(time.Hour * 300).Unix())), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfig, ``` --- core/blockchain.go | 28 ++++++++++++++++++++++++++++ params/config.go | 17 +++++++++++++++++ params/forks/forks.go | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/core/blockchain.go b/core/blockchain.go index c4caec66ed..6667f64911 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "io" + "math" "math/big" "runtime" "slices" @@ -100,6 +101,10 @@ var ( errInvalidNewChain = errors.New("invalid new chain") ) +var ( + forkReadyInterval = 3 * time.Minute +) + const ( bodyCacheLimit = 256 blockCacheLimit = 256 @@ -275,6 +280,8 @@ type BlockChain struct { processor Processor // Block transaction processor interface vmConfig vm.Config logger *tracing.Hooks + + lastForkReadyAlert time.Time // Last time there was a fork readiness print out } // NewBlockChain returns a fully initialised block chain using information @@ -1884,6 +1891,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness trieDiffNodes, trieBufNodes, _ := bc.triedb.Size() stats.report(chain, it.index, snapDiffItems, snapBufItems, trieDiffNodes, trieBufNodes, setHead) + // Print confirmation that a future fork is scheduled, but not yet active. + bc.logForkReadiness(block) + if !setHead { // After merge we expect few side chains. Simply count // all blocks the CL gives us for GC processing time @@ -1917,6 +1927,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness "root", block.Root()) } } + stats.ignored += it.remaining() return witness, it.index, err } @@ -2514,6 +2525,23 @@ func (bc *BlockChain) reportBlock(block *types.Block, res *ProcessResult, err er log.Error(summarizeBadBlock(block, receipts, bc.Config(), err)) } +// logForkReadiness will write a log when a future fork is scheduled, but not +// active. This is useful so operators know their client is ready for the fork. +func (bc *BlockChain) logForkReadiness(block *types.Block) { + c := bc.Config() + current, last := c.LatestFork(block.Time()), c.LatestFork(math.MaxUint64) + t := c.Timestamp(last) + if t == nil { + return + } + at := time.Unix(int64(*t), 0) + if current < last && time.Now().After(bc.lastForkReadyAlert.Add(forkReadyInterval)) { + log.Info("Ready for fork activation", "fork", last, "date", at.Format(time.RFC822), + "remaining", time.Until(at).Round(time.Second), "timestamp", at.Unix()) + bc.lastForkReadyAlert = time.Now() + } +} + // summarizeBadBlock returns a string summarizing the bad block and other // relevant information. func summarizeBadBlock(block *types.Block, receipts []*types.Receipt, config *params.ChainConfig, err error) string { diff --git a/params/config.go b/params/config.go index 03b797863c..67aa6b2225 100644 --- a/params/config.go +++ b/params/config.go @@ -909,6 +909,23 @@ func (c *ChainConfig) LatestFork(time uint64) forks.Fork { } } +// Timestamp returns the timestamp associated with the fork or returns nil if +// the fork isn't defined or isn't a time-based fork. +func (c *ChainConfig) Timestamp(fork forks.Fork) *uint64 { + switch { + case fork == forks.Osaka: + return c.OsakaTime + case fork == forks.Prague: + return c.PragueTime + case fork == forks.Cancun: + return c.CancunTime + case fork == forks.Shanghai: + return c.ShanghaiTime + default: + return nil + } +} + // isForkBlockIncompatible returns true if a fork scheduled at block s1 cannot be // rescheduled to block s2 because head is already past the fork. func isForkBlockIncompatible(s1, s2, head *big.Int) bool { diff --git a/params/forks/forks.go b/params/forks/forks.go index 02f6e5b612..5c9612a625 100644 --- a/params/forks/forks.go +++ b/params/forks/forks.go @@ -20,7 +20,7 @@ package forks type Fork int const ( - Frontier = iota + Frontier Fork = iota FrontierThawing Homestead DAO @@ -41,3 +41,35 @@ const ( Prague Osaka ) + +// String implements fmt.Stringer. +func (f Fork) String() string { + s, ok := forkToString[f] + if !ok { + return "Unknown fork" + } + return s +} + +var forkToString = map[Fork]string{ + Frontier: "Frontier", + FrontierThawing: "Frontier Thawing", + Homestead: "Homestead", + DAO: "DAO", + TangerineWhistle: "Tangerine Whistle", + SpuriousDragon: "Spurious Dragon", + Byzantium: "Byzantium", + Constantinople: "Constantinople", + Petersburg: "Petersburg", + Istanbul: "Istanbul", + MuirGlacier: "Muir Glacier", + Berlin: "Berlin", + London: "London", + ArrowGlacier: "Arrow Glacier", + GrayGlacier: "Gray Glacier", + Paris: "Paris", + Shanghai: "Shanghai", + Cancun: "Cancun", + Prague: "Prague", + Osaka: "Osaka", +} From 074da25f66adfd31a5ea360db9efa40ad7964de3 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Thu, 17 Apr 2025 20:23:31 +0800 Subject: [PATCH 300/940] eth/catalyst: sanitize simulated beacon period to avoid overflowing time.Duration (#31407) closes #31401 --------- Co-authored-by: Marius van der Wijden Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Co-authored-by: Felix Lange --- eth/catalyst/simulated_beacon.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/eth/catalyst/simulated_beacon.go b/eth/catalyst/simulated_beacon.go index dd9d8f9062..b84df9a4d6 100644 --- a/eth/catalyst/simulated_beacon.go +++ b/eth/catalyst/simulated_beacon.go @@ -21,6 +21,7 @@ import ( "crypto/sha256" "errors" "fmt" + "math" "sync" "time" @@ -124,9 +125,13 @@ func NewSimulatedBeacon(period uint64, feeRecipient common.Address, eth *eth.Eth return nil, err } } + + // cap the dev mode period to a reasonable maximum value to avoid + // overflowing the time.Duration (int64) that it will occupy + const maxPeriod = uint64(math.MaxInt64 / time.Second) return &SimulatedBeacon{ eth: eth, - period: period, + period: min(period, maxPeriod), shutdownCh: make(chan struct{}), engineAPI: engineAPI, lastBlockTime: block.Time, From 9089f9461cc2a25703ee247256e1d0c48b64f815 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 18 Apr 2025 03:27:48 +0800 Subject: [PATCH 301/940] eth: add tx to locals only if it has a chance of acceptance (#31618) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request improves error handling for local transaction submissions. Specifically, if a transaction fails with a temporary error but might be accepted later, the error will not be returned to the user; instead, the transaction will be tracked locally for resubmission. However, if the transaction fails with a permanent error (e.g., invalid transaction or insufficient balance), the error will be propagated to the user. These errors returned in the legacyPool are regarded as temporary failure: - `ErrOutOfOrderTxFromDelegated` - `txpool.ErrInflightTxLimitReached` - `ErrAuthorityReserved` - `txpool.ErrUnderpriced` - `ErrTxPoolOverflow` - `ErrFutureReplacePending` Notably, InsufficientBalance is also treated as a permanent error, as it’s highly unlikely that users will transfer funds into the sender account after submitting the transaction. Otherwise, users may be confused—seeing their transaction submitted but unaware that the sender lacks sufficient funds—and continue waiting for it to be included. --------- Co-authored-by: lightclient --- core/txpool/blobpool/blobpool.go | 2 + core/txpool/blobpool/blobpool_test.go | 2 +- core/txpool/errors.go | 13 +- core/txpool/legacypool/legacypool2_test.go | 6 +- core/txpool/legacypool/legacypool_test.go | 59 ++++---- core/txpool/locals/errors.go | 46 ++++++ core/txpool/locals/tx_tracker.go | 20 +-- core/txpool/locals/tx_tracker_test.go | 58 +------- core/txpool/txpool.go | 25 ---- core/txpool/validation.go | 4 +- eth/api_backend.go | 26 ++-- eth/api_backend_test.go | 157 +++++++++++++++++++++ eth/fetcher/tx_fetcher.go | 4 +- eth/fetcher/tx_fetcher_test.go | 6 +- ethclient/simulated/backend_test.go | 8 +- 15 files changed, 284 insertions(+), 152 deletions(-) create mode 100644 core/txpool/locals/errors.go create mode 100644 eth/api_backend_test.go diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 12a4133b40..e506da228d 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1391,6 +1391,8 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { switch { case errors.Is(err, txpool.ErrUnderpriced): addUnderpricedMeter.Mark(1) + case errors.Is(err, txpool.ErrTxGasPriceTooLow): + addUnderpricedMeter.Mark(1) case errors.Is(err, core.ErrNonceTooLow): addStaleMeter.Mark(1) case errors.Is(err, core.ErrNonceTooHigh): diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 76d21a0c9e..0a323179a6 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -1484,7 +1484,7 @@ func TestAdd(t *testing.T) { { // New account, no previous txs, nonce 0, but blob fee cap too low from: "alice", tx: makeUnsignedTx(0, 1, 1, 0), - err: txpool.ErrUnderpriced, + err: txpool.ErrTxGasPriceTooLow, }, { // Same as above but blob fee cap equals minimum, should be accepted from: "alice", diff --git a/core/txpool/errors.go b/core/txpool/errors.go index 02f5703b6c..968c9d9542 100644 --- a/core/txpool/errors.go +++ b/core/txpool/errors.go @@ -16,7 +16,9 @@ package txpool -import "errors" +import ( + "errors" +) var ( // ErrAlreadyKnown is returned if the transactions is already contained @@ -26,14 +28,19 @@ var ( // ErrInvalidSender is returned if the transaction contains an invalid signature. ErrInvalidSender = errors.New("invalid sender") - // ErrUnderpriced is returned if a transaction's gas price is below the minimum - // configured for the transaction pool. + // ErrUnderpriced is returned if a transaction's gas price is too low to be + // included in the pool. If the gas price is lower than the minimum configured + // one for the transaction pool, use ErrTxGasPriceTooLow instead. ErrUnderpriced = errors.New("transaction underpriced") // ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced // with a different one without the required price bump. ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") + // ErrTxGasPriceTooLow is returned if a transaction's gas price is below the + // minimum configured for the transaction pool. + ErrTxGasPriceTooLow = errors.New("transaction gas price below minimum") + // ErrAccountLimitExceeded is returned if a transaction would exceed the number // allowed by a pool for a single account. ErrAccountLimitExceeded = errors.New("account limit exceeded") diff --git a/core/txpool/legacypool/legacypool2_test.go b/core/txpool/legacypool/legacypool2_test.go index 3f210e3d1b..deb06aa617 100644 --- a/core/txpool/legacypool/legacypool2_test.go +++ b/core/txpool/legacypool/legacypool2_test.go @@ -82,12 +82,14 @@ func TestTransactionFutureAttack(t *testing.T) { // Create the pool to test the limit enforcement with statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed)) + config := testTxPoolConfig config.GlobalQueue = 100 config.GlobalSlots = 100 pool := New(config, blockchain) pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver()) defer pool.Close() + fillPool(t, pool) pending, _ := pool.Stats() // Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops @@ -180,7 +182,9 @@ func TestTransactionZAttack(t *testing.T) { ivPending := countInvalidPending() t.Logf("invalid pending: %d\n", ivPending) - // Now, DETER-Z attack starts, let's add a bunch of expensive non-executables (from N accounts) along with balance-overdraft txs (from one account), and see if the pending-count drops + // Now, DETER-Z attack starts, let's add a bunch of expensive non-executables + // (from N accounts) along with balance-overdraft txs (from one account), and + // see if the pending-count drops for j := 0; j < int(pool.config.GlobalQueue); j++ { futureTxs := types.Transactions{} key, _ := crypto.GenerateKey() diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index bb1323a7d1..2fdf890320 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -413,7 +413,7 @@ func TestInvalidTransactions(t *testing.T) { tx = transaction(1, 100000, key) pool.gasTip.Store(uint256.NewInt(1000)) - if err, want := pool.addRemote(tx), txpool.ErrUnderpriced; !errors.Is(err, want) { + if err, want := pool.addRemote(tx), txpool.ErrTxGasPriceTooLow; !errors.Is(err, want) { t.Errorf("want %v have %v", want, err) } } @@ -484,7 +484,7 @@ func TestNegativeValue(t *testing.T) { tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key) from, _ := deriveSender(tx) testAddBalance(pool, from, big.NewInt(1)) - if err := pool.addRemote(tx); err != txpool.ErrNegativeValue { + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrNegativeValue) { t.Error("expected", txpool.ErrNegativeValue, "got", err) } } @@ -497,7 +497,7 @@ func TestTipAboveFeeCap(t *testing.T) { tx := dynamicFeeTx(0, 100, big.NewInt(1), big.NewInt(2), key) - if err := pool.addRemote(tx); err != core.ErrTipAboveFeeCap { + if err := pool.addRemote(tx); !errors.Is(err, core.ErrTipAboveFeeCap) { t.Error("expected", core.ErrTipAboveFeeCap, "got", err) } } @@ -512,12 +512,12 @@ func TestVeryHighValues(t *testing.T) { veryBigNumber.Lsh(veryBigNumber, 300) tx := dynamicFeeTx(0, 100, big.NewInt(1), veryBigNumber, key) - if err := pool.addRemote(tx); err != core.ErrTipVeryHigh { + if err := pool.addRemote(tx); !errors.Is(err, core.ErrTipVeryHigh) { t.Error("expected", core.ErrTipVeryHigh, "got", err) } tx2 := dynamicFeeTx(0, 100, veryBigNumber, big.NewInt(1), key) - if err := pool.addRemote(tx2); err != core.ErrFeeCapVeryHigh { + if err := pool.addRemote(tx2); !errors.Is(err, core.ErrFeeCapVeryHigh) { t.Error("expected", core.ErrFeeCapVeryHigh, "got", err) } } @@ -1424,14 +1424,14 @@ func TestRepricing(t *testing.T) { t.Fatalf("pool internal state corrupted: %v", err) } // Check that we can't add the old transactions back - if err := pool.addRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); !errors.Is(err, txpool.ErrUnderpriced) { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced) + if err := pool.addRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); !errors.Is(err, txpool.ErrTxGasPriceTooLow) { + t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow) } - if err := pool.addRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); !errors.Is(err, txpool.ErrUnderpriced) { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced) + if err := pool.addRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); !errors.Is(err, txpool.ErrTxGasPriceTooLow) { + t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow) } - if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[2])); !errors.Is(err, txpool.ErrUnderpriced) { - t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced) + if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[2])); !errors.Is(err, txpool.ErrTxGasPriceTooLow) { + t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow) } if err := validateEvents(events, 0); err != nil { t.Fatalf("post-reprice event firing failed: %v", err) @@ -1476,14 +1476,14 @@ func TestMinGasPriceEnforced(t *testing.T) { tx := pricedTransaction(0, 100000, big.NewInt(2), key) pool.SetGasTip(big.NewInt(tx.GasPrice().Int64() + 1)) - if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrUnderpriced) { + if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrTxGasPriceTooLow) { t.Fatalf("Min tip not enforced") } tx = dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), key) pool.SetGasTip(big.NewInt(tx.GasTipCap().Int64() + 1)) - if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrUnderpriced) { + if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrTxGasPriceTooLow) { t.Fatalf("Min tip not enforced") } } @@ -1560,16 +1560,16 @@ func TestRepricingDynamicFee(t *testing.T) { } // Check that we can't add the old transactions back tx := pricedTransaction(1, 100000, big.NewInt(1), keys[0]) - if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrUnderpriced) { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced) + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrTxGasPriceTooLow) { + t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow) } tx = dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1]) - if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrUnderpriced) { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced) + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrTxGasPriceTooLow) { + t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow) } tx = dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2]) - if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrUnderpriced) { - t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced) + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrTxGasPriceTooLow) { + t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow) } if err := validateEvents(events, 0); err != nil { t.Fatalf("post-reprice event firing failed: %v", err) @@ -1673,7 +1673,7 @@ func TestUnderpricing(t *testing.T) { t.Fatalf("failed to add well priced transaction: %v", err) } // Ensure that replacing a pending transaction with a future transaction fails - if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != ErrFutureReplacePending { + if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); !errors.Is(err, ErrFutureReplacePending) { t.Fatalf("adding future replace transaction error mismatch: have %v, want %v", err, ErrFutureReplacePending) } pending, queued = pool.Stats() @@ -1995,7 +1995,7 @@ func TestReplacement(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), key)); err != nil { t.Fatalf("failed to add original cheap pending transaction: %v", err) } - if err := pool.addRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, txpool.ErrReplaceUnderpriced) } if err := pool.addRemote(pricedTransaction(0, 100000, big.NewInt(2), key)); err != nil { @@ -2008,7 +2008,7 @@ func TestReplacement(t *testing.T) { if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil { t.Fatalf("failed to add original proper pending transaction: %v", err) } - if err := pool.addRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, txpool.ErrReplaceUnderpriced) } if err := pool.addRemote(pricedTransaction(0, 100000, big.NewInt(threshold), key)); err != nil { @@ -2022,7 +2022,7 @@ func TestReplacement(t *testing.T) { if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(1), key)); err != nil { t.Fatalf("failed to add original cheap queued transaction: %v", err) } - if err := pool.addRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original cheap queued transaction replacement error mismatch: have %v, want %v", err, txpool.ErrReplaceUnderpriced) } if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(2), key)); err != nil { @@ -2032,7 +2032,7 @@ func TestReplacement(t *testing.T) { if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(price), key)); err != nil { t.Fatalf("failed to add original proper queued transaction: %v", err) } - if err := pool.addRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original proper queued transaction replacement error mismatch: have %v, want %v", err, txpool.ErrReplaceUnderpriced) } if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(threshold), key)); err != nil { @@ -2096,7 +2096,7 @@ func TestReplacementDynamicFee(t *testing.T) { } // 2. Don't bump tip or feecap => discard tx = dynamicFeeTx(nonce, 100001, big.NewInt(2), big.NewInt(1), key) - if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original cheap %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced) } // 3. Bump both more than min => accept @@ -2117,24 +2117,25 @@ func TestReplacementDynamicFee(t *testing.T) { if err := pool.addRemoteSync(tx); err != nil { t.Fatalf("failed to add original proper %s transaction: %v", stage, err) } + // 6. Bump tip max allowed so it's still underpriced => discard tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold-1), key) - if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced) } // 7. Bump fee cap max allowed so it's still underpriced => discard tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold-1), big.NewInt(gasTipCap), key) - if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced) } // 8. Bump tip min for acceptance => accept tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold), key) - if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced) } // 9. Bump fee cap min for acceptance => accept tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(gasTipCap), key) - if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced { + if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) { t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced) } // 10. Check events match expected (3 new executable txs during pending, 0 during queue) diff --git a/core/txpool/locals/errors.go b/core/txpool/locals/errors.go new file mode 100644 index 0000000000..fda50bf218 --- /dev/null +++ b/core/txpool/locals/errors.go @@ -0,0 +1,46 @@ +// Copyright 2025 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 locals + +import ( + "errors" + + "github.com/ethereum/go-ethereum/core/txpool" + "github.com/ethereum/go-ethereum/core/txpool/legacypool" +) + +// IsTemporaryReject determines whether the given error indicates a temporary +// reason to reject a transaction from being included in the txpool. The result +// may change if the txpool's state changes later. +func IsTemporaryReject(err error) bool { + switch { + case errors.Is(err, legacypool.ErrOutOfOrderTxFromDelegated): + return true + case errors.Is(err, txpool.ErrInflightTxLimitReached): + return true + case errors.Is(err, legacypool.ErrAuthorityReserved): + return true + case errors.Is(err, txpool.ErrUnderpriced): + return true + case errors.Is(err, legacypool.ErrTxPoolOverflow): + return true + case errors.Is(err, legacypool.ErrFutureReplacePending): + return true + default: + return false + } +} diff --git a/core/txpool/locals/tx_tracker.go b/core/txpool/locals/tx_tracker.go index eccdcf422a..e08384ce71 100644 --- a/core/txpool/locals/tx_tracker.go +++ b/core/txpool/locals/tx_tracker.go @@ -74,32 +74,22 @@ func New(journalPath string, journalTime time.Duration, chainConfig *params.Chai // Track adds a transaction to the tracked set. // Note: blob-type transactions are ignored. -func (tracker *TxTracker) Track(tx *types.Transaction) error { - return tracker.TrackAll([]*types.Transaction{tx})[0] +func (tracker *TxTracker) Track(tx *types.Transaction) { + tracker.TrackAll([]*types.Transaction{tx}) } // TrackAll adds a list of transactions to the tracked set. // Note: blob-type transactions are ignored. -func (tracker *TxTracker) TrackAll(txs []*types.Transaction) []error { +func (tracker *TxTracker) TrackAll(txs []*types.Transaction) { tracker.mu.Lock() defer tracker.mu.Unlock() - var errors []error for _, tx := range txs { if tx.Type() == types.BlobTxType { - errors = append(errors, nil) - continue - } - // Ignore the transactions which are failed for fundamental - // validation such as invalid parameters. - if err := tracker.pool.ValidateTxBasics(tx); err != nil { - log.Debug("Invalid transaction submitted", "hash", tx.Hash(), "err", err) - errors = append(errors, err) continue } // If we're already tracking it, it's a no-op if _, ok := tracker.all[tx.Hash()]; ok { - errors = append(errors, nil) continue } // Theoretically, checking the error here is unnecessary since sender recovery @@ -108,11 +98,8 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) []error { // Therefore, the error is still checked just in case. addr, err := types.Sender(tracker.signer, tx) if err != nil { - errors = append(errors, err) continue } - errors = append(errors, nil) - tracker.all[tx.Hash()] = tx if tracker.byAddr[addr] == nil { tracker.byAddr[addr] = legacypool.NewSortedMap() @@ -124,7 +111,6 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) []error { } } localGauge.Update(int64(len(tracker.all))) - return errors } // recheck checks and returns any transactions that needs to be resubmitted. diff --git a/core/txpool/locals/tx_tracker_test.go b/core/txpool/locals/tx_tracker_test.go index 5585589b6c..0668d243fc 100644 --- a/core/txpool/locals/tx_tracker_test.go +++ b/core/txpool/locals/tx_tracker_test.go @@ -17,7 +17,6 @@ package locals import ( - "errors" "math/big" "testing" "time" @@ -91,10 +90,12 @@ func (env *testEnv) close() { env.chain.Stop() } +// nolint:unused func (env *testEnv) setGasTip(gasTip uint64) { env.pool.SetGasTip(new(big.Int).SetUint64(gasTip)) } +// nolint:unused func (env *testEnv) makeTx(nonce uint64, gasPrice *big.Int) *types.Transaction { if nonce == 0 { head := env.chain.CurrentHeader() @@ -121,6 +122,7 @@ func (env *testEnv) makeTxs(n int) []*types.Transaction { return txs } +// nolint:unused func (env *testEnv) commit() { head := env.chain.CurrentBlock() block := env.chain.GetBlock(head.Hash(), head.Number.Uint64()) @@ -137,60 +139,6 @@ func (env *testEnv) commit() { } } -func TestRejectInvalids(t *testing.T) { - env := newTestEnv(t, 10, 0, "") - defer env.close() - - var cases = []struct { - gasTip uint64 - tx *types.Transaction - expErr error - commit bool - }{ - { - tx: env.makeTx(5, nil), // stale - expErr: core.ErrNonceTooLow, - }, - { - tx: env.makeTx(11, nil), // future transaction - expErr: nil, - }, - { - gasTip: params.GWei, - tx: env.makeTx(0, new(big.Int).SetUint64(params.GWei/2)), // low price - expErr: txpool.ErrUnderpriced, - }, - { - tx: types.NewTransaction(10, common.Address{0x00}, big.NewInt(1000), params.TxGas, big.NewInt(params.GWei), nil), // invalid signature - expErr: types.ErrInvalidSig, - }, - { - commit: true, - tx: env.makeTx(10, nil), // stale - expErr: core.ErrNonceTooLow, - }, - { - tx: env.makeTx(11, nil), - expErr: nil, - }, - } - for i, c := range cases { - if c.gasTip != 0 { - env.setGasTip(c.gasTip) - } - if c.commit { - env.commit() - } - gotErr := env.tracker.Track(c.tx) - if c.expErr == nil && gotErr != nil { - t.Fatalf("%d, unexpected error: %v", i, gotErr) - } - if c.expErr != nil && !errors.Is(gotErr, c.expErr) { - t.Fatalf("%d, unexpected error, want: %v, got: %v", i, c.expErr, gotErr) - } - } -} - func TestResubmit(t *testing.T) { env := newTestEnv(t, 10, 0, "") defer env.close() diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index fc4a7be6d2..cc8f74c1b8 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -324,31 +324,6 @@ func (p *TxPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Pr return nil, nil } -// ValidateTxBasics checks whether a transaction is valid according to the consensus -// rules, but does not check state-dependent validation such as sufficient balance. -func (p *TxPool) ValidateTxBasics(tx *types.Transaction) error { - addr, err := types.Sender(p.signer, tx) - if err != nil { - return err - } - // Reject transactions with stale nonce. Gapped-nonce future transactions - // are considered valid and will be handled by the subpool according to its - // internal policy. - p.stateLock.RLock() - nonce := p.state.GetNonce(addr) - p.stateLock.RUnlock() - - if nonce > tx.Nonce() { - return core.ErrNonceTooLow - } - for _, subpool := range p.subpools { - if subpool.Filter(tx) { - return subpool.ValidateTxBasics(tx) - } - } - return fmt.Errorf("%w: received type %d", core.ErrTxTypeNotSupported, tx.Type()) -} - // Add enqueues a batch of transactions into the pool if they are valid. Due // to the large transaction churn, add may postpone fully integrating the tx // to a later point to batch multiple ones together. diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 8747724247..e370f2ce84 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -131,12 +131,12 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types } // Ensure the gasprice is high enough to cover the requirement of the calling pool if tx.GasTipCapIntCmp(opts.MinTip) < 0 { - return fmt.Errorf("%w: gas tip cap %v, minimum needed %v", ErrUnderpriced, tx.GasTipCap(), opts.MinTip) + return fmt.Errorf("%w: gas tip cap %v, minimum needed %v", ErrTxGasPriceTooLow, tx.GasTipCap(), opts.MinTip) } if tx.Type() == types.BlobTxType { // Ensure the blob fee cap satisfies the minimum blob gas price if tx.BlobGasFeeCapIntCmp(blobTxMinBlobGasPrice) < 0 { - return fmt.Errorf("%w: blob fee cap %v, minimum needed %v", ErrUnderpriced, tx.BlobGasFeeCap(), blobTxMinBlobGasPrice) + return fmt.Errorf("%w: blob fee cap %v, minimum needed %v", ErrTxGasPriceTooLow, tx.BlobGasFeeCap(), blobTxMinBlobGasPrice) } sidecar := tx.BlobTxSidecar() if sidecar == nil { diff --git a/eth/api_backend.go b/eth/api_backend.go index 182c081d2b..64fb58a1fd 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.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/txpool" + "github.com/ethereum/go-ethereum/core/txpool/locals" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -307,19 +308,24 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri } func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { - locals := b.eth.localTxTracker - if locals != nil { - if err := locals.Track(signedTx); err != nil { - return err - } - } - // No error will be returned to user if the transaction fails stateful - // validation (e.g., no available slot), as the locally submitted transactions - // may be resubmitted later via the local tracker. err := b.eth.txPool.Add([]*types.Transaction{signedTx}, false)[0] - if err != nil && locals == nil { + + // If the local transaction tracker is not configured, returns whatever + // returned from the txpool. + if b.eth.localTxTracker == nil { return err } + // If the transaction fails with an error indicating it is invalid, or if there is + // very little chance it will be accepted later (e.g., the gas price is below the + // configured minimum, or the sender has insufficient funds to cover the cost), + // propagate the error to the user. + if err != nil && !locals.IsTemporaryReject(err) { + return err + } + // No error will be returned to user if the transaction fails with a temporary + // error and might be accepted later (e.g., the transaction pool is full). + // Locally submitted transactions will be resubmitted later via the local tracker. + b.eth.localTxTracker.Track(signedTx) return nil } diff --git a/eth/api_backend_test.go b/eth/api_backend_test.go new file mode 100644 index 0000000000..049f68d827 --- /dev/null +++ b/eth/api_backend_test.go @@ -0,0 +1,157 @@ +// Copyright 2025 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 eth + +import ( + "context" + "crypto/ecdsa" + "errors" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "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/txpool" + "github.com/ethereum/go-ethereum/core/txpool/blobpool" + "github.com/ethereum/go-ethereum/core/txpool/legacypool" + "github.com/ethereum/go-ethereum/core/txpool/locals" + "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/holiman/uint256" +) + +var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000_000_000_000_000) + gspec = &core.Genesis{ + Config: params.MergedTestChainConfig, + Alloc: types.GenesisAlloc{ + address: {Balance: funds}, + }, + Difficulty: common.Big0, + BaseFee: big.NewInt(params.InitialBaseFee), + } + signer = types.LatestSignerForChainID(gspec.Config.ChainID) +) + +func initBackend(withLocal bool) *EthAPIBackend { + var ( + // Create a database pre-initialize with a genesis block + db = rawdb.NewMemoryDatabase() + engine = beacon.New(ethash.NewFaker()) + ) + chain, _ := core.NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil) + + txconfig := legacypool.DefaultConfig + txconfig.Journal = "" // Don't litter the disk with test journals + + blobPool := blobpool.New(blobpool.Config{Datadir: ""}, chain, nil) + legacyPool := legacypool.New(txconfig, chain) + txpool, _ := txpool.New(txconfig.PriceLimit, chain, []txpool.SubPool{legacyPool, blobPool}) + + eth := &Ethereum{ + blockchain: chain, + txPool: txpool, + } + if withLocal { + eth.localTxTracker = locals.New("", time.Minute, gspec.Config, txpool) + } + return &EthAPIBackend{ + eth: eth, + } +} + +func makeTx(nonce uint64, gasPrice *big.Int, amount *big.Int, key *ecdsa.PrivateKey) *types.Transaction { + if gasPrice == nil { + gasPrice = big.NewInt(params.GWei) + } + if amount == nil { + amount = big.NewInt(1000) + } + tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{0x00}, amount, params.TxGas, gasPrice, nil), signer, key) + return tx +} + +type unsignedAuth struct { + nonce uint64 + key *ecdsa.PrivateKey +} + +func pricedSetCodeTx(nonce uint64, gaslimit uint64, gasFee, tip *uint256.Int, key *ecdsa.PrivateKey, unsigned []unsignedAuth) *types.Transaction { + var authList []types.SetCodeAuthorization + for _, u := range unsigned { + auth, _ := types.SignSetCode(u.key, types.SetCodeAuthorization{ + ChainID: *uint256.MustFromBig(gspec.Config.ChainID), + Address: common.Address{0x42}, + Nonce: u.nonce, + }) + authList = append(authList, auth) + } + return pricedSetCodeTxWithAuth(nonce, gaslimit, gasFee, tip, key, authList) +} + +func pricedSetCodeTxWithAuth(nonce uint64, gaslimit uint64, gasFee, tip *uint256.Int, key *ecdsa.PrivateKey, authList []types.SetCodeAuthorization) *types.Transaction { + return types.MustSignNewTx(key, signer, &types.SetCodeTx{ + ChainID: uint256.MustFromBig(gspec.Config.ChainID), + Nonce: nonce, + GasTipCap: tip, + GasFeeCap: gasFee, + Gas: gaslimit, + To: common.Address{}, + Value: uint256.NewInt(100), + Data: nil, + AccessList: nil, + AuthList: authList, + }) +} + +func TestSendTx(t *testing.T) { + testSendTx(t, false) + testSendTx(t, true) +} + +func testSendTx(t *testing.T, withLocal bool) { + b := initBackend(withLocal) + + txA := pricedSetCodeTx(0, 250000, uint256.NewInt(params.GWei), uint256.NewInt(params.GWei), key, []unsignedAuth{ + { + nonce: 0, + key: key, + }, + }) + b.SendTx(context.Background(), txA) + + txB := makeTx(1, nil, nil, key) + err := b.SendTx(context.Background(), txB) + + if withLocal { + if err != nil { + t.Fatalf("Unexpected error sending tx: %v", err) + } + } else { + if !errors.Is(err, txpool.ErrInflightTxLimitReached) { + t.Fatalf("Unexpected error, want: %v, got: %v", txpool.ErrInflightTxLimitReached, err) + } + } +} diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 1c192d4112..ff17ae4945 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -345,7 +345,7 @@ func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) // Track the transaction hash if the price is too low for us. // Avoid re-request this transaction when we receive another // announcement. - if errors.Is(err, txpool.ErrUnderpriced) || errors.Is(err, txpool.ErrReplaceUnderpriced) { + if errors.Is(err, txpool.ErrUnderpriced) || errors.Is(err, txpool.ErrReplaceUnderpriced) || errors.Is(err, txpool.ErrTxGasPriceTooLow) { f.underpriced.Add(batch[j].Hash(), batch[j].Time()) } // Track a few interesting failure types @@ -355,7 +355,7 @@ func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) case errors.Is(err, txpool.ErrAlreadyKnown): duplicate++ - case errors.Is(err, txpool.ErrUnderpriced) || errors.Is(err, txpool.ErrReplaceUnderpriced): + case errors.Is(err, txpool.ErrUnderpriced) || errors.Is(err, txpool.ErrReplaceUnderpriced) || errors.Is(err, txpool.ErrTxGasPriceTooLow): underpriced++ default: diff --git a/eth/fetcher/tx_fetcher_test.go b/eth/fetcher/tx_fetcher_test.go index 7f3080f5f6..c4c8cac56e 100644 --- a/eth/fetcher/tx_fetcher_test.go +++ b/eth/fetcher/tx_fetcher_test.go @@ -1244,10 +1244,12 @@ func TestTransactionFetcherUnderpricedDedup(t *testing.T) { func(txs []*types.Transaction) []error { errs := make([]error, len(txs)) for i := 0; i < len(errs); i++ { - if i%2 == 0 { + if i%3 == 0 { errs[i] = txpool.ErrUnderpriced - } else { + } else if i%3 == 1 { errs[i] = txpool.ErrReplaceUnderpriced + } else { + errs[i] = txpool.ErrTxGasPriceTooLow } } return errs diff --git a/ethclient/simulated/backend_test.go b/ethclient/simulated/backend_test.go index fc78e84362..303e480a09 100644 --- a/ethclient/simulated/backend_test.go +++ b/ethclient/simulated/backend_test.go @@ -25,16 +25,14 @@ import ( "testing" "time" - "go.uber.org/goleak" - - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/holiman/uint256" - "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/crypto" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" + "go.uber.org/goleak" ) var _ bind.ContractBackend = (Client)(nil) From 2e0ad2cb4d11cc9dd094e3e2c1d196d08079ef91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 18 Apr 2025 13:39:11 +0200 Subject: [PATCH 302/940] core/filtermaps: only use common ancestor snapshots (#31668) This PR makes the conditions for using a map rendering snapshot stricter so that whenever a reorg happens, only a snapshot of a common ancestor block can be used. The issue fixed in https://github.com/ethereum/go-ethereum/pull/31642 originated from using a snapshot that wasn't a common ancestor. For example in the following reorg scenario: `A->B`, then `A->B2`, then `A->B2->C2`, then `A->B->C` the last reorg triggered a render from snapshot `B` saved earlier. Now this is possible under certain conditions but extra care is needed, for example if block `B` crosses a map boundary then it should not be allowed. With the latest fix the checks are sufficient but I realized I would just feel safer if we disallowed this rare and risky scenario altogether and just render from snapshot `A` after the last reorg in the example above. The performance difference if a few milliseconds and it occurs rarely (about once a day on Holesky, probably much more rare on Mainnet). Note that this PR only makes the snapshot conditions stricter and `TestIndexerRandomRange` does check that snapshots are still used whenever it's obviously possible (adding blocks after the current head without a reorg) so this change can be considered safe. Also I am running the unit tests and the fuzzer and everything seems to be fine. --- core/filtermaps/map_renderer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index cd960ad31c..23d84f0eca 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -143,6 +143,7 @@ func (f *FilterMaps) lastCanonicalSnapshotOfMap(mapIndex uint32) *renderedMap { var best *renderedMap for _, blockNumber := range f.renderSnapshots.Keys() { if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.blocks.AfterLast() && + blockNumber <= f.indexedView.headNumber && f.indexedView.getBlockId(blockNumber) == cp.lastBlockId && blockNumber <= f.targetView.headNumber && f.targetView.getBlockId(blockNumber) == cp.lastBlockId && cp.mapIndex == mapIndex && (best == nil || blockNumber > best.lastBlock) { best = cp From 4c9e7d1b187c1b42b7f3218724ad61d1ef9c9019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 18 Apr 2025 14:00:11 +0200 Subject: [PATCH 303/940] core/filtermaps: make ChainView thread safe (#31671) This PR makes `filtermaps.ChainView` thread safe because it is used concurrently both by the indexer and multiple matcher threads. Even though it represents an immutable view of the chain, adding a mutex lock to the `blockHash` function is necessary because it does so by extending its list of non-canonical hashes if the underlying blockchain is changed. The unsafe concurrency did cause a panic once after running the unit tests for several hours and it could also happen during live operation. --- core/filtermaps/chain_view.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go index a8cf53b1c0..d6f0a727bf 100644 --- a/core/filtermaps/chain_view.go +++ b/core/filtermaps/chain_view.go @@ -17,6 +17,8 @@ package filtermaps import ( + "sync" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" @@ -39,6 +41,7 @@ type blockchain interface { // of the underlying blockchain, it should only possess the block headers // and receipts up until the expected chain view head. type ChainView struct { + lock sync.Mutex chain blockchain headNumber uint64 hashes []common.Hash // block hashes starting backwards from headNumber until first canonical hash @@ -147,6 +150,9 @@ func (cv *ChainView) extendNonCanonical() bool { // blockHash returns the given block hash without doing the head number check. func (cv *ChainView) blockHash(number uint64) common.Hash { + cv.lock.Lock() + defer cv.lock.Unlock() + if number+uint64(len(cv.hashes)) <= cv.headNumber { hash := cv.chain.GetCanonicalHash(number) if !cv.extendNonCanonical() { From 1296cdb7484d3b6236f1d1d95381cc8ffde7d4d9 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Sat, 19 Apr 2025 21:42:54 +1000 Subject: [PATCH 304/940] core: fail execution if system call fails to execute (#31639) see: https://github.com/ethereum/pm/issues/1450#issuecomment-2800911584 --- cmd/evm/internal/t8ntool/execution.go | 8 ++++++-- core/chain_makers.go | 8 ++++++-- core/state_processor.go | 29 +++++++++++++++++---------- internal/ethapi/simulate.go | 8 ++++++-- miner/worker.go | 8 ++++++-- 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 7de1eb6949..b2e5f70714 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -363,9 +363,13 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not parse requests logs: %v", err)) } // EIP-7002 - core.ProcessWithdrawalQueue(&requests, evm) + if err := core.ProcessWithdrawalQueue(&requests, evm); err != nil { + return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not process withdrawal requests: %v", err)) + } // EIP-7251 - core.ProcessConsolidationQueue(&requests, evm) + if err := core.ProcessConsolidationQueue(&requests, evm); err != nil { + return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not process consolidation requests: %v", err)) + } } // Commit block diff --git a/core/chain_makers.go b/core/chain_makers.go index 7a258dc05f..37bddcfda5 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -328,9 +328,13 @@ func (b *BlockGen) collectRequests(readonly bool) (requests [][]byte) { blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase) evm := vm.NewEVM(blockContext, statedb, b.cm.config, vm.Config{}) // EIP-7002 - ProcessWithdrawalQueue(&requests, evm) + if err := ProcessWithdrawalQueue(&requests, evm); err != nil { + panic(fmt.Sprintf("could not process withdrawal requests: %v", err)) + } // EIP-7251 - ProcessConsolidationQueue(&requests, evm) + if err := ProcessConsolidationQueue(&requests, evm); err != nil { + panic(fmt.Sprintf("could not process consolidation requests: %v", err)) + } } return requests } diff --git a/core/state_processor.go b/core/state_processor.go index 9241d091ad..322bd24f41 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -113,9 +113,13 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg return nil, err } // EIP-7002 - ProcessWithdrawalQueue(&requests, evm) + if err := ProcessWithdrawalQueue(&requests, evm); err != nil { + return nil, err + } // EIP-7251 - ProcessConsolidationQueue(&requests, evm) + if err := ProcessConsolidationQueue(&requests, evm); err != nil { + return nil, err + } } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) @@ -265,17 +269,17 @@ func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) { // ProcessWithdrawalQueue calls the EIP-7002 withdrawal queue contract. // It returns the opaque request data returned by the contract. -func ProcessWithdrawalQueue(requests *[][]byte, evm *vm.EVM) { - processRequestsSystemCall(requests, evm, 0x01, params.WithdrawalQueueAddress) +func ProcessWithdrawalQueue(requests *[][]byte, evm *vm.EVM) error { + return processRequestsSystemCall(requests, evm, 0x01, params.WithdrawalQueueAddress) } // ProcessConsolidationQueue calls the EIP-7251 consolidation queue contract. // It returns the opaque request data returned by the contract. -func ProcessConsolidationQueue(requests *[][]byte, evm *vm.EVM) { - processRequestsSystemCall(requests, evm, 0x02, params.ConsolidationQueueAddress) +func ProcessConsolidationQueue(requests *[][]byte, evm *vm.EVM) error { + return processRequestsSystemCall(requests, evm, 0x02, params.ConsolidationQueueAddress) } -func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte, addr common.Address) { +func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte, addr common.Address) error { if tracer := evm.Config.Tracer; tracer != nil { onSystemCallStart(tracer, evm.GetVMContext()) if tracer.OnSystemCallEnd != nil { @@ -292,17 +296,20 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte } evm.SetTxContext(NewEVMTxContext(msg)) evm.StateDB.AddAddressToAccessList(addr) - ret, _, _ := evm.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560) + ret, _, err := evm.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560) evm.StateDB.Finalise(true) - if len(ret) == 0 { - return // skip empty output + if err != nil { + return fmt.Errorf("system call failed to execute: %v", err) + } + if len(ret) == 0 { + return nil // skip empty output } - // Append prefixed requestsData to the requests list. requestsData := make([]byte, len(ret)+1) requestsData[0] = requestType copy(requestsData[1:], ret) *requests = append(*requests, requestsData) + return nil } var depositTopic = common.HexToHash("0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5") diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index ba346b132f..9241b509da 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -314,9 +314,13 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, return nil, nil, err } // EIP-7002 - core.ProcessWithdrawalQueue(&requests, evm) + if err := core.ProcessWithdrawalQueue(&requests, evm); err != nil { + return nil, nil, err + } // EIP-7251 - core.ProcessConsolidationQueue(&requests, evm) + if err := core.ProcessConsolidationQueue(&requests, evm); err != nil { + return nil, nil, err + } } if requests != nil { reqHash := types.CalcRequestsHash(requests) diff --git a/miner/worker.go b/miner/worker.go index 8fb42e31bc..d80cb8913b 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -127,9 +127,13 @@ func (miner *Miner) generateWork(params *generateParams, witness bool) *newPaylo return &newPayloadResult{err: err} } // EIP-7002 - core.ProcessWithdrawalQueue(&requests, work.evm) + if err := core.ProcessWithdrawalQueue(&requests, work.evm); err != nil { + return &newPayloadResult{err: err} + } // EIP-7251 consolidations - core.ProcessConsolidationQueue(&requests, work.evm) + if err := core.ProcessConsolidationQueue(&requests, work.evm); err != nil { + return &newPayloadResult{err: err} + } } if requests != nil { reqHash := types.CalcRequestsHash(requests) From bf6da20012f63573fff4dad19634c5bf5dbef964 Mon Sep 17 00:00:00 2001 From: Morty <70688412+yiweichi@users.noreply.github.com> Date: Sat, 19 Apr 2025 22:02:31 +0800 Subject: [PATCH 305/940] eth/gasprice: fix eth_feeHistory blobGasUsedRatio divide zero (#31663) The API `eth_feeHistory` returns `{"jsonrpc":"2.0","id":1,"error":{"code":-32603,"message":"json: unsupported value: NaN"}}`, when we query `eth_feeHistory` with a old block that without a blob, or when the field `config.blobSchedule.cancun.max` in genesis.config is 0 (that happens for some projects fork geth but they don't have blob). So here we specially handle the case when maxBlobGas == 0 to prevent this issue from happening. --- eth/gasprice/feehistory.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 59830e9fe8..e5a197f640 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -108,7 +108,9 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit) if blobGasUsed := bf.header.BlobGasUsed; blobGasUsed != nil { maxBlobGas := eip4844.MaxBlobGasPerBlock(config, bf.header.Time) - bf.results.blobGasUsedRatio = float64(*blobGasUsed) / float64(maxBlobGas) + if maxBlobGas != 0 { + bf.results.blobGasUsedRatio = float64(*blobGasUsed) / float64(maxBlobGas) + } } if len(percentiles) == 0 { From 7f574372d5cc3b8d37b59dd0da53e9f779bbfdd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Sun, 20 Apr 2025 09:48:49 +0200 Subject: [PATCH 306/940] eth/filters, core/filtermaps: safe chain view update (#31590) This PR changes the chain view update mechanism of the log filter. Previously the head updates were all wired through the indexer, even in unindexed mode. This was both a bit weird and also unsafe as the indexer's chain view was updates asynchronously with some delay, making some log related tests flaky. Also, the reorg safety of the indexed search was integrated with unindexed search in a weird way, relying on `syncRange.ValidBlocks` in the unindexed case too, with a special condition added to only consider the head of the valid range but not the tail in the unindexed case. In this PR the current chain view is directly accessible through the filter backend and unindexed search is also chain view based, making it inherently safe. The matcher sync mechanism is now only used for indexed search as originally intended, removing a few ugly special conditions. The PR is currently based on top of https://github.com/ethereum/go-ethereum/pull/31642 Together they fix https://github.com/ethereum/go-ethereum/issues/31518 and replace https://github.com/ethereum/go-ethereum/pull/31542 --------- Co-authored-by: Gary Rong --- accounts/abi/abigen/bind_test.go | 5 +- core/filtermaps/chain_view.go | 61 ++++-- core/filtermaps/filtermaps.go | 8 +- core/filtermaps/indexer.go | 8 +- core/filtermaps/map_renderer.go | 32 +-- core/filtermaps/matcher.go | 2 +- core/filtermaps/matcher_backend.go | 6 +- eth/api_backend.go | 8 + eth/filters/filter.go | 250 +++++++++++++---------- eth/filters/filter_system.go | 1 + eth/filters/filter_system_test.go | 5 + eth/filters/filter_test.go | 137 ++++++++----- internal/ethapi/api_test.go | 3 + internal/ethapi/backend.go | 1 + internal/ethapi/transaction_args_test.go | 1 + 15 files changed, 327 insertions(+), 201 deletions(-) diff --git a/accounts/abi/abigen/bind_test.go b/accounts/abi/abigen/bind_test.go index 195064fb7a..b3c52e81e5 100644 --- a/accounts/abi/abigen/bind_test.go +++ b/accounts/abi/abigen/bind_test.go @@ -939,6 +939,7 @@ var bindTests = []struct { if _, err := eventer.RaiseSimpleEvent(auth, common.Address{byte(j)}, [32]byte{byte(j)}, true, big.NewInt(int64(10*i+j))); err != nil { t.Fatalf("block %d, event %d: raise failed: %v", i, j, err) } + time.Sleep(time.Millisecond * 200) } sim.Commit() } @@ -1495,7 +1496,7 @@ var bindTests = []struct { if n != 3 { t.Fatalf("Invalid bar0 event") } - case <-time.NewTimer(3 * time.Second).C: + case <-time.NewTimer(10 * time.Second).C: t.Fatalf("Wait bar0 event timeout") } @@ -1506,7 +1507,7 @@ var bindTests = []struct { if n != 1 { t.Fatalf("Invalid bar event") } - case <-time.NewTimer(3 * time.Second).C: + case <-time.NewTimer(10 * time.Second).C: t.Fatalf("Wait bar event timeout") } close(stopCh) diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go index d6f0a727bf..aa74f3901a 100644 --- a/core/filtermaps/chain_view.go +++ b/core/filtermaps/chain_view.go @@ -58,47 +58,75 @@ func NewChainView(chain blockchain, number uint64, hash common.Hash) *ChainView return cv } -// getBlockHash returns the block hash belonging to the given block number. +// HeadNumber returns the head block number of the chain view. +func (cv *ChainView) HeadNumber() uint64 { + return cv.headNumber +} + +// BlockHash returns the block hash belonging to the given block number. // Note that the hash of the head block is not returned because ChainView might // represent a view where the head block is currently being created. -func (cv *ChainView) getBlockHash(number uint64) common.Hash { - if number >= cv.headNumber { +func (cv *ChainView) BlockHash(number uint64) common.Hash { + cv.lock.Lock() + defer cv.lock.Unlock() + + if number > cv.headNumber { panic("invalid block number") } return cv.blockHash(number) } -// getBlockId returns the unique block id belonging to the given block number. +// BlockId returns the unique block id belonging to the given block number. // Note that it is currently equal to the block hash. In the future it might // be a different id for future blocks if the log index root becomes part of // consensus and therefore rendering the index with the new head will happen // before the hash of that new head is available. -func (cv *ChainView) getBlockId(number uint64) common.Hash { +func (cv *ChainView) BlockId(number uint64) common.Hash { + cv.lock.Lock() + defer cv.lock.Unlock() + if number > cv.headNumber { panic("invalid block number") } return cv.blockHash(number) } -// getReceipts returns the set of receipts belonging to the block at the given +// Header returns the block header at the given block number. +func (cv *ChainView) Header(number uint64) *types.Header { + return cv.chain.GetHeader(cv.BlockHash(number), number) +} + +// Receipts returns the set of receipts belonging to the block at the given // block number. -func (cv *ChainView) getReceipts(number uint64) types.Receipts { - if number > cv.headNumber { - panic("invalid block number") - } - blockHash := cv.blockHash(number) +func (cv *ChainView) Receipts(number uint64) types.Receipts { + blockHash := cv.BlockHash(number) if blockHash == (common.Hash{}) { log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber) } return cv.chain.GetReceiptsByHash(blockHash) } +// SharedRange returns the block range shared by two chain views. +func (cv *ChainView) SharedRange(cv2 *ChainView) common.Range[uint64] { + cv.lock.Lock() + defer cv.lock.Unlock() + + if cv == nil || cv2 == nil || !cv.extendNonCanonical() || !cv2.extendNonCanonical() { + return common.Range[uint64]{} + } + var sharedLen uint64 + for n := min(cv.headNumber+1-uint64(len(cv.hashes)), cv2.headNumber+1-uint64(len(cv2.hashes))); n <= cv.headNumber && n <= cv2.headNumber && cv.blockHash(n) == cv2.blockHash(n); n++ { + sharedLen = n + 1 + } + return common.NewRange(0, sharedLen) +} + // limitedView returns a new chain view that is a truncated version of the parent view. func (cv *ChainView) limitedView(newHead uint64) *ChainView { if newHead >= cv.headNumber { return cv } - return NewChainView(cv.chain, newHead, cv.blockHash(newHead)) + return NewChainView(cv.chain, newHead, cv.BlockHash(newHead)) } // equalViews returns true if the two chain views are equivalent. @@ -106,7 +134,7 @@ func equalViews(cv1, cv2 *ChainView) bool { if cv1 == nil || cv2 == nil { return false } - return cv1.headNumber == cv2.headNumber && cv1.getBlockId(cv1.headNumber) == cv2.getBlockId(cv2.headNumber) + return cv1.headNumber == cv2.headNumber && cv1.BlockId(cv1.headNumber) == cv2.BlockId(cv2.headNumber) } // matchViews returns true if the two chain views are equivalent up until the @@ -120,9 +148,9 @@ func matchViews(cv1, cv2 *ChainView, number uint64) bool { return false } if number == cv1.headNumber || number == cv2.headNumber { - return cv1.getBlockId(number) == cv2.getBlockId(number) + return cv1.BlockId(number) == cv2.BlockId(number) } - return cv1.getBlockHash(number) == cv2.getBlockHash(number) + return cv1.BlockHash(number) == cv2.BlockHash(number) } // extendNonCanonical checks whether the previously known reverse list of head @@ -150,9 +178,6 @@ func (cv *ChainView) extendNonCanonical() bool { // blockHash returns the given block hash without doing the head number check. func (cv *ChainView) blockHash(number uint64) common.Hash { - cv.lock.Lock() - defer cv.lock.Unlock() - if number+uint64(len(cv.hashes)) <= cv.headNumber { hash := cv.chain.GetCanonicalHash(number) if !cv.extendNonCanonical() { diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index fa2d6e3ffb..a617de8968 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -262,7 +262,7 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f f.targetView = initView if f.indexedRange.initialized { f.indexedView = f.initChainView(f.targetView) - f.indexedRange.headIndexed = f.indexedRange.blocks.AfterLast() == f.indexedView.headNumber+1 + f.indexedRange.headIndexed = f.indexedRange.blocks.AfterLast() == f.indexedView.HeadNumber()+1 if !f.indexedRange.headIndexed { f.indexedRange.headDelimiter = 0 } @@ -313,7 +313,7 @@ func (f *FilterMaps) initChainView(chainView *ChainView) *ChainView { log.Error("Could not initialize indexed chain view", "error", err) break } - if lastBlockNumber <= chainView.headNumber && chainView.getBlockId(lastBlockNumber) == lastBlockId { + if lastBlockNumber <= chainView.HeadNumber() && chainView.BlockId(lastBlockNumber) == lastBlockId { return chainView.limitedView(lastBlockNumber) } } @@ -370,7 +370,7 @@ func (f *FilterMaps) init() error { for min < max { mid := (min + max + 1) / 2 cp := checkpointList[mid-1] - if cp.BlockNumber <= f.targetView.headNumber && f.targetView.getBlockId(cp.BlockNumber) == cp.BlockId { + if cp.BlockNumber <= f.targetView.HeadNumber() && f.targetView.BlockId(cp.BlockNumber) == cp.BlockId { min = mid } else { max = mid - 1 @@ -512,7 +512,7 @@ func (f *FilterMaps) getLogByLvIndex(lvIndex uint64) (*types.Log, error) { } } // get block receipts - receipts := f.indexedView.getReceipts(firstBlockNumber) + receipts := f.indexedView.Receipts(firstBlockNumber) if receipts == nil { return nil, fmt.Errorf("failed to retrieve receipts for block %d containing searched log value index %d: %v", firstBlockNumber, lvIndex, err) } diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 9a5424da4a..383ec078c9 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -44,7 +44,7 @@ func (f *FilterMaps) indexerLoop() { for !f.stop { if !f.indexedRange.initialized { - if f.targetView.headNumber == 0 { + if f.targetView.HeadNumber() == 0 { // initialize when chain head is available f.processSingleEvent(true) continue @@ -249,7 +249,7 @@ func (f *FilterMaps) tryIndexHead() error { log.Info("Log index head rendering in progress", "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), "processed", f.indexedRange.blocks.AfterLast()-f.ptrHeadIndex, - "remaining", f.indexedView.headNumber-f.indexedRange.blocks.Last(), + "remaining", f.indexedView.HeadNumber()-f.indexedRange.blocks.Last(), "elapsed", common.PrettyDuration(time.Since(f.startedHeadIndexAt))) f.loggedHeadIndex = true f.lastLogHeadIndex = time.Now() @@ -418,10 +418,10 @@ func (f *FilterMaps) needTailEpoch(epoch uint32) bool { // tailTargetBlock returns the target value for the tail block number according // to the log history parameter and the current index head. func (f *FilterMaps) tailTargetBlock() uint64 { - if f.history == 0 || f.indexedView.headNumber < f.history { + if f.history == 0 || f.indexedView.HeadNumber() < f.history { return 0 } - return f.indexedView.headNumber + 1 - f.history + return f.indexedView.HeadNumber() + 1 - f.history } // tailPartialBlocks returns the number of rendered blocks in the partially diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index 23d84f0eca..7c2aa8dc32 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -143,8 +143,8 @@ func (f *FilterMaps) lastCanonicalSnapshotOfMap(mapIndex uint32) *renderedMap { var best *renderedMap for _, blockNumber := range f.renderSnapshots.Keys() { if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.blocks.AfterLast() && - blockNumber <= f.indexedView.headNumber && f.indexedView.getBlockId(blockNumber) == cp.lastBlockId && - blockNumber <= f.targetView.headNumber && f.targetView.getBlockId(blockNumber) == cp.lastBlockId && + blockNumber <= f.indexedView.HeadNumber() && f.indexedView.BlockId(blockNumber) == cp.lastBlockId && + blockNumber <= f.targetView.HeadNumber() && f.targetView.BlockId(blockNumber) == cp.lastBlockId && cp.mapIndex == mapIndex && (best == nil || blockNumber > best.lastBlock) { best = cp } @@ -173,7 +173,7 @@ func (f *FilterMaps) lastCanonicalMapBoundaryBefore(renderBefore uint32) (nextMa return 0, 0, 0, fmt.Errorf("failed to retrieve last block of reverse iterated map %d: %v", mapIndex, err) } if (f.indexedRange.headIndexed && mapIndex >= f.indexedRange.maps.Last()) || - lastBlock >= f.targetView.headNumber || lastBlockId != f.targetView.getBlockId(lastBlock) { + lastBlock >= f.targetView.HeadNumber() || lastBlockId != f.targetView.BlockId(lastBlock) { continue // map is not full or inconsistent with targetView; roll back } lvPtr, err := f.getBlockLvPointer(lastBlock) @@ -247,7 +247,7 @@ func (f *FilterMaps) loadHeadSnapshot() error { filterMap: fm, mapIndex: f.indexedRange.maps.Last(), lastBlock: f.indexedRange.blocks.Last(), - lastBlockId: f.indexedView.getBlockId(f.indexedRange.blocks.Last()), + lastBlockId: f.indexedView.BlockId(f.indexedRange.blocks.Last()), blockLvPtrs: lvPtrs, finished: true, headDelimiter: f.indexedRange.headDelimiter, @@ -264,7 +264,7 @@ func (r *mapRenderer) makeSnapshot() { filterMap: r.currentMap.filterMap.fastCopy(), mapIndex: r.currentMap.mapIndex, lastBlock: r.currentMap.lastBlock, - lastBlockId: r.iterator.chainView.getBlockId(r.currentMap.lastBlock), + lastBlockId: r.iterator.chainView.BlockId(r.currentMap.lastBlock), blockLvPtrs: r.currentMap.blockLvPtrs, finished: true, headDelimiter: r.iterator.lvIndex, @@ -370,7 +370,7 @@ func (r *mapRenderer) renderCurrentMap(stopCb func() bool) (bool, error) { r.currentMap.finished = true r.currentMap.headDelimiter = r.iterator.lvIndex } - r.currentMap.lastBlockId = r.f.targetView.getBlockId(r.currentMap.lastBlock) + r.currentMap.lastBlockId = r.f.targetView.BlockId(r.currentMap.lastBlock) totalTime += time.Since(start) mapRenderTimer.Update(totalTime) mapLogValueMeter.Mark(logValuesProcessed) @@ -566,8 +566,8 @@ func (r *mapRenderer) getUpdatedRange() (filterMapsRange, error) { lm := r.finishedMaps[r.finished.Last()] newRange.headIndexed = lm.finished if lm.finished { - newRange.blocks.SetLast(r.f.targetView.headNumber) - if lm.lastBlock != r.f.targetView.headNumber { + newRange.blocks.SetLast(r.f.targetView.HeadNumber()) + if lm.lastBlock != r.f.targetView.HeadNumber() { panic("map rendering finished but last block != head block") } newRange.headDelimiter = lm.headDelimiter @@ -665,13 +665,13 @@ var errUnindexedRange = errors.New("unindexed range") // given block's first log value entry (the block delimiter), according to the // current targetView. func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber, lvIndex uint64) (*logIterator, error) { - if blockNumber > f.targetView.headNumber { - return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", blockNumber, f.targetView.headNumber) + if blockNumber > f.targetView.HeadNumber() { + return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", blockNumber, f.targetView.HeadNumber()) } if !f.indexedRange.blocks.Includes(blockNumber) { return nil, errUnindexedRange } - finished := blockNumber == f.targetView.headNumber + finished := blockNumber == f.targetView.HeadNumber() l := &logIterator{ chainView: f.targetView, params: &f.Params, @@ -687,11 +687,11 @@ func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber, lvIndex uint6 // newLogIteratorFromMapBoundary creates a logIterator starting at the given // map boundary, according to the current targetView. func (f *FilterMaps) newLogIteratorFromMapBoundary(mapIndex uint32, startBlock, startLvPtr uint64) (*logIterator, error) { - if startBlock > f.targetView.headNumber { - return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", startBlock, f.targetView.headNumber) + if startBlock > f.targetView.HeadNumber() { + return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", startBlock, f.targetView.HeadNumber()) } // get block receipts - receipts := f.targetView.getReceipts(startBlock) + receipts := f.targetView.Receipts(startBlock) if receipts == nil { return nil, fmt.Errorf("receipts not found for start block %d", startBlock) } @@ -758,7 +758,7 @@ func (l *logIterator) next() error { if l.delimiter { l.delimiter = false l.blockNumber++ - l.receipts = l.chainView.getReceipts(l.blockNumber) + l.receipts = l.chainView.Receipts(l.blockNumber) if l.receipts == nil { return fmt.Errorf("receipts not found for block %d", l.blockNumber) } @@ -795,7 +795,7 @@ func (l *logIterator) enforceValidState() { } l.logIndex = 0 } - if l.blockNumber == l.chainView.headNumber { + if l.blockNumber == l.chainView.HeadNumber() { l.finished = true } else { l.delimiter = true diff --git a/core/filtermaps/matcher.go b/core/filtermaps/matcher.go index 5738bf166a..a5eeaaa5f0 100644 --- a/core/filtermaps/matcher.go +++ b/core/filtermaps/matcher.go @@ -57,7 +57,7 @@ type MatcherBackend interface { // all states of the chain since the previous SyncLogIndex or the creation of // the matcher backend. type SyncRange struct { - HeadNumber uint64 + IndexedView *ChainView // block range where the index has not changed since the last matcher sync // and therefore the set of matches found in this region is guaranteed to // be valid and complete. diff --git a/core/filtermaps/matcher_backend.go b/core/filtermaps/matcher_backend.go index 335ac84551..ee18a0694c 100644 --- a/core/filtermaps/matcher_backend.go +++ b/core/filtermaps/matcher_backend.go @@ -128,7 +128,7 @@ func (fm *FilterMapsMatcherBackend) synced() { indexedBlocks.SetAfterLast(indexedBlocks.Last()) // remove partially indexed last block } fm.syncCh <- SyncRange{ - HeadNumber: fm.f.targetView.headNumber, + IndexedView: fm.f.indexedView, ValidBlocks: fm.validBlocks, IndexedBlocks: indexedBlocks, } @@ -154,7 +154,7 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange case <-ctx.Done(): return SyncRange{}, ctx.Err() case <-fm.f.disabledCh: - return SyncRange{HeadNumber: fm.f.targetView.headNumber}, nil + return SyncRange{IndexedView: fm.f.indexedView}, nil } select { case vr := <-syncCh: @@ -162,7 +162,7 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange case <-ctx.Done(): return SyncRange{}, ctx.Err() case <-fm.f.disabledCh: - return SyncRange{HeadNumber: fm.f.targetView.headNumber}, nil + return SyncRange{IndexedView: fm.f.indexedView}, nil } } diff --git a/eth/api_backend.go b/eth/api_backend.go index 64fb58a1fd..10f7ffcbce 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -443,6 +443,14 @@ func (b *EthAPIBackend) RPCTxFeeCap() float64 { return b.eth.config.RPCTxFeeCap } +func (b *EthAPIBackend) CurrentView() *filtermaps.ChainView { + head := b.eth.blockchain.CurrentBlock() + if head == nil { + return nil + } + return filtermaps.NewChainView(b.eth.blockchain, head.Number.Uint64(), head.Hash()) +} + func (b *EthAPIBackend) NewMatcherBackend() filtermaps.MatcherBackend { return b.eth.filterMaps.NewMatcherBackend() } diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 78c80d8f26..dd6643c59e 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -146,25 +146,29 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { } const ( - rangeLogsTestSync = iota - rangeLogsTestTrimmed - rangeLogsTestIndexed - rangeLogsTestUnindexed - rangeLogsTestDone + rangeLogsTestDone = iota // zero range + rangeLogsTestSync // before sync; zero range + rangeLogsTestSynced // after sync; valid blocks range + rangeLogsTestIndexed // individual search range + rangeLogsTestUnindexed // individual search range + rangeLogsTestResults // results range after search iteration + rangeLogsTestReorg // results range trimmed by reorg ) type rangeLogsTestEvent struct { - event int - begin, end uint64 + event int + blocks common.Range[uint64] } // searchSession represents a single search session. type searchSession struct { - ctx context.Context - filter *Filter - mb filtermaps.MatcherBackend - syncRange filtermaps.SyncRange // latest synchronized state with the matcher - firstBlock, lastBlock uint64 // specified search range; each can be MaxUint64 + ctx context.Context + filter *Filter + mb filtermaps.MatcherBackend + syncRange filtermaps.SyncRange // latest synchronized state with the matcher + chainView *filtermaps.ChainView // can be more recent than the indexed view in syncRange + // block ranges always refer to the current chainView + firstBlock, lastBlock uint64 // specified search range; MaxUint64 means latest block searchRange common.Range[uint64] // actual search range; end trimmed to latest head matchRange common.Range[uint64] // range in which we have results (subset of searchRange) matches []*types.Log // valid set of matches in matchRange @@ -182,84 +186,99 @@ func newSearchSession(ctx context.Context, filter *Filter, mb filtermaps.Matcher } // enforce a consistent state before starting the search in order to be able // to determine valid range later - if err := s.syncMatcher(0); err != nil { + var err error + s.syncRange, err = s.mb.SyncLogIndex(s.ctx) + if err != nil { + return nil, err + } + if err := s.updateChainView(); err != nil { return nil, err } return s, nil } -// syncMatcher performs a synchronization step with the matcher. The resulting -// syncRange structure holds information about the latest range of indexed blocks -// and the guaranteed valid blocks whose log index have not been changed since -// the previous synchronization. -// The function also performs trimming of the match set in order to always keep -// it consistent with the synced matcher state. -// Tail trimming is only performed if the first block of the valid log index range -// is higher than trimTailThreshold. This is useful because unindexed log search -// is not affected by the valid tail (on the other hand, valid head is taken into -// account in order to provide reorg safety, even though the log index is not used). -// In case of indexed search the tail is only trimmed if the first part of the -// recently obtained results might be invalid. If guaranteed valid new results -// have been added at the head of previously validated results then there is no -// need to discard those even if the index tail have been unindexed since that. -func (s *searchSession) syncMatcher(trimTailThreshold uint64) error { - if s.filter.rangeLogsTestHook != nil && !s.matchRange.IsEmpty() { - s.filter.rangeLogsTestHook <- rangeLogsTestEvent{event: rangeLogsTestSync, begin: s.matchRange.First(), end: s.matchRange.Last()} - } - var err error - s.syncRange, err = s.mb.SyncLogIndex(s.ctx) - if err != nil { - return err +// updateChainView updates to the latest view of the underlying chain and sets +// searchRange by replacing MaxUint64 (meaning latest block) with actual head +// number in the specified search range. +// If the session already had an existing chain view and set of matches then +// it also trims part of the match set that a chain reorg might have invalidated. +func (s *searchSession) updateChainView() error { + // update chain view based on current chain head (might be more recent than + // the indexed view of syncRange as the indexer updates it asynchronously + // with some delay + newChainView := s.filter.sys.backend.CurrentView() + if newChainView == nil { + return errors.New("head block not available") } + head := newChainView.HeadNumber() + // update actual search range based on current head number - first := min(s.firstBlock, s.syncRange.HeadNumber) - last := min(s.lastBlock, s.syncRange.HeadNumber) - s.searchRange = common.NewRange(first, last+1-first) - // discard everything that is not needed or might be invalid - trimRange := s.syncRange.ValidBlocks - if trimRange.First() <= trimTailThreshold { - // everything before this point is already known to be valid; if this is - // valid then keep everything before - trimRange.SetFirst(0) + firstBlock, lastBlock := s.firstBlock, s.lastBlock + if firstBlock == math.MaxUint64 { + firstBlock = head } - trimRange = trimRange.Intersection(s.searchRange) - s.trimMatches(trimRange) - if s.filter.rangeLogsTestHook != nil { - if !s.matchRange.IsEmpty() { - s.filter.rangeLogsTestHook <- rangeLogsTestEvent{event: rangeLogsTestTrimmed, begin: s.matchRange.First(), end: s.matchRange.Last()} - } else { - s.filter.rangeLogsTestHook <- rangeLogsTestEvent{event: rangeLogsTestTrimmed, begin: 0, end: 0} - } + if lastBlock == math.MaxUint64 { + lastBlock = head } + if firstBlock > lastBlock || lastBlock > head { + return errInvalidBlockRange + } + s.searchRange = common.NewRange(firstBlock, lastBlock+1-firstBlock) + + // Trim existing match set in case a reorg may have invalidated some results + if !s.matchRange.IsEmpty() { + trimRange := newChainView.SharedRange(s.chainView).Intersection(s.searchRange) + s.matchRange, s.matches = s.trimMatches(trimRange, s.matchRange, s.matches) + } + s.chainView = newChainView return nil } -// trimMatches removes any entries from the current set of matches that is outside -// the given range. -func (s *searchSession) trimMatches(trimRange common.Range[uint64]) { - s.matchRange = s.matchRange.Intersection(trimRange) - if s.matchRange.IsEmpty() { - s.matches = nil - return +// trimMatches removes any entries from the specified set of matches that is +// outside the given range. +func (s *searchSession) trimMatches(trimRange, matchRange common.Range[uint64], matches []*types.Log) (common.Range[uint64], []*types.Log) { + newRange := matchRange.Intersection(trimRange) + if newRange == matchRange { + return matchRange, matches } - for len(s.matches) > 0 && s.matches[0].BlockNumber < s.matchRange.First() { - s.matches = s.matches[1:] + if newRange.IsEmpty() { + return newRange, nil } - for len(s.matches) > 0 && s.matches[len(s.matches)-1].BlockNumber > s.matchRange.Last() { - s.matches = s.matches[:len(s.matches)-1] + for len(matches) > 0 && matches[0].BlockNumber < newRange.First() { + matches = matches[1:] } + for len(matches) > 0 && matches[len(matches)-1].BlockNumber > newRange.Last() { + matches = matches[:len(matches)-1] + } + return newRange, matches } // searchInRange performs a single range search, either indexed or unindexed. -func (s *searchSession) searchInRange(r common.Range[uint64], indexed bool) ([]*types.Log, error) { - first, last := r.First(), r.Last() +func (s *searchSession) searchInRange(r common.Range[uint64], indexed bool) (common.Range[uint64], []*types.Log, error) { if indexed { if s.filter.rangeLogsTestHook != nil { - s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestIndexed, first, last} + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestIndexed, r} } - results, err := s.filter.indexedLogs(s.ctx, s.mb, first, last) - if err != filtermaps.ErrMatchAll { - return results, err + results, err := s.filter.indexedLogs(s.ctx, s.mb, r.First(), r.Last()) + if err != nil && !errors.Is(err, filtermaps.ErrMatchAll) { + return common.Range[uint64]{}, nil, err + } + if err == nil { + // sync with filtermaps matcher + if s.filter.rangeLogsTestHook != nil { + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestSync, common.Range[uint64]{}} + } + var syncErr error + if s.syncRange, syncErr = s.mb.SyncLogIndex(s.ctx); syncErr != nil { + return common.Range[uint64]{}, nil, syncErr + } + if s.filter.rangeLogsTestHook != nil { + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestSynced, s.syncRange.ValidBlocks} + } + // discard everything that might be invalid + trimRange := s.syncRange.ValidBlocks.Intersection(s.chainView.SharedRange(s.syncRange.IndexedView)) + matchRange, matches := s.trimMatches(trimRange, r, results) + return matchRange, matches, nil } // "match all" filters are not supported by filtermaps; fall back to // unindexed search which is the most efficient in this case @@ -267,79 +286,85 @@ func (s *searchSession) searchInRange(r common.Range[uint64], indexed bool) ([]* // fall through to unindexed case } if s.filter.rangeLogsTestHook != nil { - s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestUnindexed, first, last} + s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestUnindexed, r} } - return s.filter.unindexedLogs(s.ctx, first, last) + matches, err := s.filter.unindexedLogs(s.ctx, s.chainView, r.First(), r.Last()) + if err != nil { + return common.Range[uint64]{}, nil, err + } + return r, matches, nil } // doSearchIteration performs a search on a range missing from an incomplete set // of results, adds the new section and removes invalidated entries. func (s *searchSession) doSearchIteration() error { switch { - case s.syncRange.IndexedBlocks.IsEmpty(): - // indexer is not ready; fallback to completely unindexed search, do not check valid range - var err error - s.matchRange = s.searchRange - s.matches, err = s.searchInRange(s.searchRange, false) - return err - case s.matchRange.IsEmpty(): // no results yet; try search in entire range indexedSearchRange := s.searchRange.Intersection(s.syncRange.IndexedBlocks) - var err error if s.forceUnindexed = indexedSearchRange.IsEmpty(); !s.forceUnindexed { // indexed search on the intersection of indexed and searched range - s.matchRange = indexedSearchRange - s.matches, err = s.searchInRange(indexedSearchRange, true) + matchRange, matches, err := s.searchInRange(indexedSearchRange, true) if err != nil { return err } - return s.syncMatcher(0) // trim everything that the matcher considers potentially invalid + s.matchRange = matchRange + s.matches = matches + return nil } else { - // no intersection of indexed and searched range; unindexed search on the whole searched range - s.matchRange = s.searchRange - s.matches, err = s.searchInRange(s.searchRange, false) + // no intersection of indexed and searched range; unindexed search on + // the whole searched range + matchRange, matches, err := s.searchInRange(s.searchRange, false) if err != nil { return err } - return s.syncMatcher(math.MaxUint64) // unindexed search is not affected by the tail of valid range + s.matchRange = matchRange + s.matches = matches + return nil } case !s.matchRange.IsEmpty() && s.matchRange.First() > s.searchRange.First(): - // we have results but tail section is missing; do unindexed search for - // the tail part but still allow indexed search for missing head section + // Results are available, but the tail section is missing. Perform an unindexed + // search for the missing tail, while still allowing indexed search for the head. + // + // The unindexed search is necessary because the tail portion of the indexes + // has been pruned. tailRange := common.NewRange(s.searchRange.First(), s.matchRange.First()-s.searchRange.First()) - tailMatches, err := s.searchInRange(tailRange, false) + _, tailMatches, err := s.searchInRange(tailRange, false) if err != nil { return err } s.matches = append(tailMatches, s.matches...) s.matchRange = tailRange.Union(s.matchRange) - return s.syncMatcher(math.MaxUint64) // unindexed search is not affected by the tail of valid range + return nil case !s.matchRange.IsEmpty() && s.matchRange.First() == s.searchRange.First() && s.searchRange.AfterLast() > s.matchRange.AfterLast(): - // we have results but head section is missing + // Results are available, but the head section is missing. Try to perform + // the indexed search for the missing head, or fallback to unindexed search + // if the tail portion of indexed range has been pruned. headRange := common.NewRange(s.matchRange.AfterLast(), s.searchRange.AfterLast()-s.matchRange.AfterLast()) if !s.forceUnindexed { indexedHeadRange := headRange.Intersection(s.syncRange.IndexedBlocks) if !indexedHeadRange.IsEmpty() && indexedHeadRange.First() == headRange.First() { - // indexed head range search is possible headRange = indexedHeadRange } else { + // The tail portion of the indexes has been pruned, falling back + // to unindexed search. s.forceUnindexed = true } } - headMatches, err := s.searchInRange(headRange, !s.forceUnindexed) + headMatchRange, headMatches, err := s.searchInRange(headRange, !s.forceUnindexed) if err != nil { return err } - s.matches = append(s.matches, headMatches...) - s.matchRange = s.matchRange.Union(headRange) - if s.forceUnindexed { - return s.syncMatcher(math.MaxUint64) // unindexed search is not affected by the tail of valid range - } else { - return s.syncMatcher(headRange.First()) // trim if the tail of latest head search results might be invalid + if headMatchRange.First() != s.matchRange.AfterLast() { + // improbable corner case, first part of new head range invalidated by tail unindexing + s.matches, s.matchRange = headMatches, headMatchRange + return nil } + s.matches = append(s.matches, headMatches...) + s.matchRange = s.matchRange.Union(headMatchRange) + return nil default: panic("invalid search session state") @@ -349,7 +374,7 @@ func (s *searchSession) doSearchIteration() error { func (f *Filter) rangeLogs(ctx context.Context, firstBlock, lastBlock uint64) ([]*types.Log, error) { if f.rangeLogsTestHook != nil { defer func() { - f.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestDone, 0, 0} + f.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestDone, common.Range[uint64]{}} close(f.rangeLogsTestHook) }() } @@ -366,7 +391,17 @@ func (f *Filter) rangeLogs(ctx context.Context, firstBlock, lastBlock uint64) ([ } for session.searchRange != session.matchRange { if err := session.doSearchIteration(); err != nil { - return session.matches, err + return nil, err + } + if f.rangeLogsTestHook != nil { + f.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestResults, session.matchRange} + } + mr := session.matchRange + if err := session.updateChainView(); err != nil { + return nil, err + } + if f.rangeLogsTestHook != nil && session.matchRange != mr { + f.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestReorg, session.matchRange} } } return session.matches, nil @@ -382,7 +417,7 @@ func (f *Filter) indexedLogs(ctx context.Context, mb filtermaps.MatcherBackend, // unindexedLogs returns the logs matching the filter criteria based on raw block // iteration and bloom matching. -func (f *Filter) unindexedLogs(ctx context.Context, begin, end uint64) ([]*types.Log, error) { +func (f *Filter) unindexedLogs(ctx context.Context, chainView *filtermaps.ChainView, begin, end uint64) ([]*types.Log, error) { start := time.Now() log.Debug("Performing unindexed log search", "begin", begin, "end", end) var matches []*types.Log @@ -392,9 +427,14 @@ func (f *Filter) unindexedLogs(ctx context.Context, begin, end uint64) ([]*types return matches, ctx.Err() default: } - header, err := f.sys.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber)) - if header == nil || err != nil { - return matches, err + if blockNumber > chainView.HeadNumber() { + // check here so that we can return matches up until head along with + // the error + return matches, errInvalidBlockRange + } + header := chainView.Header(blockNumber) + if header == nil { + return matches, errors.New("header not found") } found, err := f.blockLogs(ctx, header) if err != nil { diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index b787f1067b..10e433f09b 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -71,6 +71,7 @@ type Backend interface { SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription + CurrentView() *filtermaps.ChainView NewMatcherBackend() filtermaps.MatcherBackend } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 3bb019d105..fa5d4fe897 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -154,6 +154,11 @@ func (b *testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subsc return b.chainFeed.Subscribe(ch) } +func (b *testBackend) CurrentView() *filtermaps.ChainView { + head := b.CurrentBlock() + return filtermaps.NewChainView(b, head.Number.Uint64(), head.Hash()) +} + func (b *testBackend) NewMatcherBackend() filtermaps.MatcherBackend { return b.fm.NewMatcherBackend() } diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 4026c03e89..d6065230f8 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -453,7 +453,8 @@ func TestRangeLogs(t *testing.T) { addresses = []common.Address{{}} ) - expEvent := func(exp rangeLogsTestEvent) { + expEvent := func(expEvent int, expFirst, expAfterLast uint64) { + exp := rangeLogsTestEvent{expEvent, common.NewRange[uint64](expFirst, expAfterLast-expFirst)} event++ ev := <-filter.rangeLogsTestHook if ev != exp { @@ -472,7 +473,6 @@ func TestRangeLogs(t *testing.T) { for range filter.rangeLogsTestHook { } }(filter) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 0, 0}) } updateHead := func() { @@ -483,81 +483,122 @@ func TestRangeLogs(t *testing.T) { // test case #1 newFilter(300, 500) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 401, 500}) - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 401, 500}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 401, 500}) - expEvent(rangeLogsTestEvent{rangeLogsTestUnindexed, 300, 400}) + expEvent(rangeLogsTestIndexed, 401, 501) + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 401, 601) + expEvent(rangeLogsTestResults, 401, 501) + expEvent(rangeLogsTestUnindexed, 300, 401) if _, err := bc.InsertChain(chain[600:700]); err != nil { t.Fatal(err) } updateHead() - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 300, 500}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 300, 500}) // unindexed search is not affected by trimmed tail - expEvent(rangeLogsTestEvent{rangeLogsTestDone, 0, 0}) + expEvent(rangeLogsTestResults, 300, 501) + expEvent(rangeLogsTestDone, 0, 0) // test case #2 newFilter(400, int64(rpc.LatestBlockNumber)) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 501, 700}) + expEvent(rangeLogsTestIndexed, 501, 701) if _, err := bc.InsertChain(chain[700:800]); err != nil { t.Fatal(err) } updateHead() - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 501, 700}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 601, 698}) - expEvent(rangeLogsTestEvent{rangeLogsTestUnindexed, 400, 600}) - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 698}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 400, 698}) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 699, 800}) - if err := bc.SetHead(750); err != nil { + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 601, 699) + expEvent(rangeLogsTestResults, 601, 699) + expEvent(rangeLogsTestUnindexed, 400, 601) + expEvent(rangeLogsTestResults, 400, 699) + expEvent(rangeLogsTestIndexed, 699, 801) + if _, err := bc.SetCanonical(chain[749]); err != nil { // set head to block 750 t.Fatal(err) } updateHead() - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 800}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 400, 748}) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 749, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 400, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestDone, 0, 0}) + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 601, 749) + expEvent(rangeLogsTestResults, 400, 749) + expEvent(rangeLogsTestIndexed, 749, 751) + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 551, 751) + expEvent(rangeLogsTestResults, 400, 751) + expEvent(rangeLogsTestDone, 0, 0) // test case #3 newFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber)) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 750, 750}) - if err := bc.SetHead(740); err != nil { + expEvent(rangeLogsTestIndexed, 750, 751) + if _, err := bc.SetCanonical(chain[739]); err != nil { t.Fatal(err) } updateHead() - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 750, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 0, 0}) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 740, 740}) + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 551, 739) + expEvent(rangeLogsTestResults, 0, 0) + expEvent(rangeLogsTestIndexed, 740, 741) if _, err := bc.InsertChain(chain[740:750]); err != nil { t.Fatal(err) } updateHead() - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 740, 740}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 0, 0}) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 750, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 750, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 750, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestDone, 0, 0}) + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 551, 739) + expEvent(rangeLogsTestResults, 0, 0) + expEvent(rangeLogsTestIndexed, 750, 751) + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 551, 751) + expEvent(rangeLogsTestResults, 750, 751) + expEvent(rangeLogsTestDone, 0, 0) // test case #4 + if _, err := bc.SetCanonical(chain[499]); err != nil { + t.Fatal(err) + } + updateHead() newFilter(400, int64(rpc.LatestBlockNumber)) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 551, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 551, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 551, 750}) - expEvent(rangeLogsTestEvent{rangeLogsTestUnindexed, 400, 550}) + expEvent(rangeLogsTestIndexed, 400, 501) + if _, err := bc.InsertChain(chain[500:650]); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 451, 499) + expEvent(rangeLogsTestResults, 451, 499) + expEvent(rangeLogsTestUnindexed, 400, 451) + expEvent(rangeLogsTestResults, 400, 499) + // indexed head extension seems possible + expEvent(rangeLogsTestIndexed, 499, 651) + // further head extension causes tail unindexing in searched range + if _, err := bc.InsertChain(chain[650:750]); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 551, 649) + // tail trimmed to 551; cannot merge with existing results + expEvent(rangeLogsTestResults, 551, 649) + expEvent(rangeLogsTestUnindexed, 400, 551) + expEvent(rangeLogsTestResults, 400, 649) + expEvent(rangeLogsTestIndexed, 649, 751) + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 551, 751) + expEvent(rangeLogsTestResults, 400, 751) + expEvent(rangeLogsTestDone, 0, 0) + + // test case #5 + newFilter(400, int64(rpc.LatestBlockNumber)) + expEvent(rangeLogsTestIndexed, 551, 751) + expEvent(rangeLogsTestSync, 0, 0) + expEvent(rangeLogsTestSynced, 551, 751) + expEvent(rangeLogsTestResults, 551, 751) + expEvent(rangeLogsTestUnindexed, 400, 551) if _, err := bc.InsertChain(chain[750:1000]); err != nil { t.Fatal(err) } updateHead() - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 750}) - // indexed range affected by tail pruning so we have to discard the entire - // match set - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 0, 0}) - expEvent(rangeLogsTestEvent{rangeLogsTestIndexed, 801, 1000}) - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 801, 1000}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 801, 1000}) - expEvent(rangeLogsTestEvent{rangeLogsTestUnindexed, 400, 800}) - expEvent(rangeLogsTestEvent{rangeLogsTestSync, 400, 1000}) - expEvent(rangeLogsTestEvent{rangeLogsTestTrimmed, 400, 1000}) + expEvent(rangeLogsTestResults, 400, 751) + // indexed tail already beyond results head; revert to unindexed head search + expEvent(rangeLogsTestUnindexed, 751, 1001) + if _, err := bc.SetCanonical(chain[899]); err != nil { + t.Fatal(err) + } + updateHead() + expEvent(rangeLogsTestResults, 400, 1001) + expEvent(rangeLogsTestReorg, 400, 901) + expEvent(rangeLogsTestDone, 0, 0) } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 3fbf32e22e..aff051937d 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -619,6 +619,9 @@ func (b testBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) func (b testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { panic("implement me") } +func (b testBackend) CurrentView() *filtermaps.ChainView { + panic("implement me") +} func (b testBackend) NewMatcherBackend() filtermaps.MatcherBackend { panic("implement me") } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index c4bf2e0591..e28cb93296 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -95,6 +95,7 @@ type Backend interface { SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription + CurrentView() *filtermaps.ChainView NewMatcherBackend() filtermaps.MatcherBackend } diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index b4d11a3033..9dd6a54729 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -401,6 +401,7 @@ func (b *backendMock) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) func (b *backendMock) Engine() consensus.Engine { return nil } +func (b *backendMock) CurrentView() *filtermaps.ChainView { return nil } func (b *backendMock) NewMatcherBackend() filtermaps.MatcherBackend { return nil } func (b *backendMock) HistoryPruningCutoff() uint64 { return 0 } From 5a7bbb423feb88ec8997dff57c3b644cc6c4f143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Sun, 20 Apr 2025 12:54:40 +0200 Subject: [PATCH 307/940] beacon/params, core/filtermaps: update checkpoints (#31674) This PR updates checkpoints for blsync and filtermaps. --- beacon/params/checkpoint_holesky.hex | 2 +- beacon/params/checkpoint_mainnet.hex | 2 +- beacon/params/checkpoint_sepolia.hex | 2 +- core/filtermaps/checkpoints_holesky.json | 3 ++- core/filtermaps/checkpoints_mainnet.json | 9 ++++++++- core/filtermaps/checkpoints_sepolia.json | 6 +++++- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/beacon/params/checkpoint_holesky.hex b/beacon/params/checkpoint_holesky.hex index f1e27b48f6..740d7aba21 100644 --- a/beacon/params/checkpoint_holesky.hex +++ b/beacon/params/checkpoint_holesky.hex @@ -1 +1 @@ -0xf5606a019f0f1006e9ec2070695045f4334450362a48da4c5965314510e0b4c3 \ No newline at end of file +0xd60e5310c5d52ced44cfb13be4e9f22a1e6a6dc56964c3cccd429182d26d72d0 \ No newline at end of file diff --git a/beacon/params/checkpoint_mainnet.hex b/beacon/params/checkpoint_mainnet.hex index a11c3394bb..45f065ca15 100644 --- a/beacon/params/checkpoint_mainnet.hex +++ b/beacon/params/checkpoint_mainnet.hex @@ -1 +1 @@ -0x3c0cb4aa83beded1803d262664ba4392b1023f334d9cca02dc3a6925987ebe91 \ No newline at end of file +0x02f0bb348b0d45f95a9b7e2bb5705768ad06548876cee03d880a2c9dabb1ff88 \ No newline at end of file diff --git a/beacon/params/checkpoint_sepolia.hex b/beacon/params/checkpoint_sepolia.hex index e4f2f96733..3d1b2885b3 100644 --- a/beacon/params/checkpoint_sepolia.hex +++ b/beacon/params/checkpoint_sepolia.hex @@ -1 +1 @@ -0xa8d56457aa414523d93659aef1f7409bbfb72ad75e94d917c8c0b1baa38153ef \ No newline at end of file +0xa0dad451a230c01be6f2492980ec5bb412d8cf33351a75e8b172b5b84a5fd03a \ No newline at end of file diff --git a/core/filtermaps/checkpoints_holesky.json b/core/filtermaps/checkpoints_holesky.json index b8f6be9caf..a56611cc8e 100644 --- a/core/filtermaps/checkpoints_holesky.json +++ b/core/filtermaps/checkpoints_holesky.json @@ -17,5 +17,6 @@ {"blockNumber": 3101669, "blockId": "0xa6e66a18fed64d33178c7088f273c404be597662c34f6e6884cf2e24f3ea4ace", "firstIndex": 1073741353}, {"blockNumber": 3221725, "blockId": "0xe771f897dece48b1583cc1d1d10de8015da57407eb1fdf239fdbe46eaab85143", "firstIndex": 1140850137}, {"blockNumber": 3357164, "blockId": "0x6252d0aa54c79623b0680069c88d7b5c47983f0d5c4845b6c811b8d9b5e8ff3c", "firstIndex": 1207959453}, -{"blockNumber": 3447019, "blockId": "0xeb7d585e1e063f3cc05ed399fbf6c2df63c271f62f030acb804e9fb1e74b6dc1", "firstIndex": 1275067542} +{"blockNumber": 3447019, "blockId": "0xeb7d585e1e063f3cc05ed399fbf6c2df63c271f62f030acb804e9fb1e74b6dc1", "firstIndex": 1275067542}, +{"blockNumber": 3546397, "blockId": "0xdabdef7defa4281180a57c5af121877b82274f15ccf074ea0096146f4c246df2", "firstIndex": 1342176778} ] diff --git a/core/filtermaps/checkpoints_mainnet.json b/core/filtermaps/checkpoints_mainnet.json index ca30280e03..70a08b1aaf 100644 --- a/core/filtermaps/checkpoints_mainnet.json +++ b/core/filtermaps/checkpoints_mainnet.json @@ -260,5 +260,12 @@ {"blockNumber": 21959188, "blockId": "0x6b9c482cc4822af2ad62a359b923062556ab6a046d1a39a8243b764848690601", "firstIndex": 17381193886}, {"blockNumber": 21994911, "blockId": "0x0d99ef9dd42dd1c62fc5249eb4f618e7672ab93fa0ba7545c77360371cf972e5", "firstIndex": 17448302795}, {"blockNumber": 22026007, "blockId": "0xf7cdc7f6694f2c2ed31fa8a607f65cfa59d0dd7d7424ab5c017f959ae2982c71", "firstIndex": 17515413036}, -{"blockNumber": 22059890, "blockId": "0x82b768a0dddefda2eefd3a33596ea2be075312f1dd4b01f6b0d377faca2af98b", "firstIndex": 17582521768} +{"blockNumber": 22059890, "blockId": "0x82b768a0dddefda2eefd3a33596ea2be075312f1dd4b01f6b0d377faca2af98b", "firstIndex": 17582521768}, +{"blockNumber": 22090784, "blockId": "0xf97c2eaf9a550360ac24000c0ff17ffa388a2bdd6f73f2f36718e332edfa107a", "firstIndex": 17649630983}, +{"blockNumber": 22121157, "blockId": "0xa790025235db782e899f23d8b09663ec2d74ec149e4125d62989f98829b08e2d", "firstIndex": 17716724973}, +{"blockNumber": 22148056, "blockId": "0xbe25ac4f1bdd89a7db5782bf1157e6c4378d80220d67a029397853ef16cd1a4c", "firstIndex": 17783838366}, +{"blockNumber": 22168652, "blockId": "0x6ae43618c915e636794e2cc2d75dde9992766881c7405fe6479c045ed4bee57e", "firstIndex": 17850956277}, +{"blockNumber": 22190975, "blockId": "0x9437121647899a4b7b84d67fbea7cc6ff967481c2eab4328ccd86e2cefe19420", "firstIndex": 17918066140}, +{"blockNumber": 22234357, "blockId": "0x036030830134f9224160d5a0b62da35ec7813dc8855d554bd22e9d38545243ed", "firstIndex": 17985175075}, +{"blockNumber": 22276736, "blockId": "0x5ceb96d98aa1b4c1c2f2fa253ae9cdb1b04e0420c11bf795400e8762c0a1635c", "firstIndex": 18052284344} ] diff --git a/core/filtermaps/checkpoints_sepolia.json b/core/filtermaps/checkpoints_sepolia.json index c6d3cd9086..8d799daefd 100644 --- a/core/filtermaps/checkpoints_sepolia.json +++ b/core/filtermaps/checkpoints_sepolia.json @@ -64,5 +64,9 @@ {"blockNumber": 7730079, "blockId": "0x08e0d511a93e2a9c004b3456d77d687ae86247417ada1cdd1f85332a62dfed1d", "firstIndex": 4227846795}, {"blockNumber": 7777515, "blockId": "0xeba8faed2e12bb9ed5e7fad19dd82662f15f6f4f512a0d232eedf1e676712428", "firstIndex": 4294966082}, {"blockNumber": 7828860, "blockId": "0x62c054bd24be351dc4777460ee922a75fdcea5c9830455cbac6fa29552719c85", "firstIndex": 4362076087}, -{"blockNumber": 7869890, "blockId": "0x5664bcfa6151f798781e22bea4f9a2c796d097402350cb131e4e3c78e13e461a", "firstIndex": 4429183267} +{"blockNumber": 7869890, "blockId": "0x5664bcfa6151f798781e22bea4f9a2c796d097402350cb131e4e3c78e13e461a", "firstIndex": 4429183267}, +{"blockNumber": 7911722, "blockId": "0x9a85e48e3135c97c51fc1786f2af0596c802e021b6c53cfca65a129cafcd23ed", "firstIndex": 4496287265}, +{"blockNumber": 7960147, "blockId": "0xc9359cc76d7090e1c8a031108f0ab7a8935d971efd4325fe53612a1d99562f6f", "firstIndex": 4563402388}, +{"blockNumber": 8030418, "blockId": "0x21867e68cd8327aed2da2601399d60f7f9e41dca4a4f2f9be982e5a2b9304a88", "firstIndex": 4630511616}, +{"blockNumber": 8087701, "blockId": "0x0fa8c8d7549cc9a8d308262706fe248efe759f8b63511efb1e7f3926e9af2dcb", "firstIndex": 4697614758} ] From 14f15430bb99646f516e239271f21e4a52584666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Mon, 21 Apr 2025 09:27:24 +0200 Subject: [PATCH 308/940] core/filtermaps: clone cached slices, fix tempRange (#31680) This PR ensures that caching a slice or a slice of slices will never affect the original version by always cloning a slice fetched from cache if it is not used in a guaranteed read only way. --- core/filtermaps/filtermaps.go | 9 ++++-- core/filtermaps/indexer.go | 3 ++ core/filtermaps/indexer_test.go | 52 +++++++++++++++++++++++++++++++++ core/filtermaps/map_renderer.go | 6 ++-- 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index a617de8968..920167ca8d 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -128,6 +128,7 @@ type FilterMaps struct { // test hooks testDisableSnapshots, testSnapshotUsed bool + testProcessEventsHook func() } // filterMap is a full or partial in-memory representation of a filter map where @@ -573,7 +574,7 @@ func (f *FilterMaps) getFilterMapRow(mapIndex, rowIndex uint32, baseLayerOnly bo } f.baseRowsCache.Add(baseMapRowIndex, baseRows) } - baseRow := baseRows[mapIndex&(f.baseRowGroupLength-1)] + baseRow := slices.Clone(baseRows[mapIndex&(f.baseRowGroupLength-1)]) if baseLayerOnly { return baseRow, nil } @@ -610,7 +611,9 @@ func (f *FilterMaps) storeFilterMapRowsOfGroup(batch ethdb.Batch, mapIndices []u if uint32(len(mapIndices)) != f.baseRowGroupLength { // skip base rows read if all rows are replaced var ok bool baseRows, ok = f.baseRowsCache.Get(baseMapRowIndex) - if !ok { + if ok { + baseRows = slices.Clone(baseRows) + } else { var err error baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, baseMapRowIndex, f.baseRowGroupLength, f.logMapWidth) if err != nil { @@ -656,7 +659,7 @@ func (f *FilterMaps) mapRowIndex(mapIndex, rowIndex uint32) uint64 { // called from outside the indexerLoop goroutine. func (f *FilterMaps) getBlockLvPointer(blockNumber uint64) (uint64, error) { if blockNumber >= f.indexedRange.blocks.AfterLast() && f.indexedRange.headIndexed { - return f.indexedRange.headDelimiter, nil + return f.indexedRange.headDelimiter + 1, nil } if lvPointer, ok := f.lvPointerCache.Get(blockNumber); ok { return lvPointer, nil diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 383ec078c9..787197345a 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -165,6 +165,9 @@ func (f *FilterMaps) waitForNewHead() { // processEvents processes all events, blocking only if a block processing is // happening and indexing should be suspended. func (f *FilterMaps) processEvents() { + if f.testProcessEventsHook != nil { + f.testProcessEventsHook() + } for f.processSingleEvent(f.blockProcessing) { } } diff --git a/core/filtermaps/indexer_test.go b/core/filtermaps/indexer_test.go index 4dddd27087..e60130ba4b 100644 --- a/core/filtermaps/indexer_test.go +++ b/core/filtermaps/indexer_test.go @@ -219,6 +219,58 @@ func testIndexerMatcherView(t *testing.T, concurrentRead bool) { } } +func TestLogsByIndex(t *testing.T) { + ts := newTestSetup(t) + defer func() { + ts.fm.testProcessEventsHook = nil + ts.close() + }() + + ts.chain.addBlocks(1000, 10, 3, 4, true) + ts.setHistory(0, false) + ts.fm.WaitIdle() + firstLog := make([]uint64, 1001) // first valid log position per block + lastLog := make([]uint64, 1001) // last valid log position per block + for i := uint64(0); i <= ts.fm.indexedRange.headDelimiter; i++ { + log, err := ts.fm.getLogByLvIndex(i) + if err != nil { + t.Fatalf("Error getting log by index %d: %v", i, err) + } + if log != nil { + if firstLog[log.BlockNumber] == 0 { + firstLog[log.BlockNumber] = i + } + lastLog[log.BlockNumber] = i + } + } + var failed bool + ts.fm.testProcessEventsHook = func() { + if ts.fm.indexedRange.blocks.IsEmpty() { + return + } + if lvi := firstLog[ts.fm.indexedRange.blocks.First()]; lvi != 0 { + log, err := ts.fm.getLogByLvIndex(lvi) + if log == nil || err != nil { + t.Errorf("Error getting first log of indexed block range: %v", err) + failed = true + } + } + if lvi := lastLog[ts.fm.indexedRange.blocks.Last()]; lvi != 0 { + log, err := ts.fm.getLogByLvIndex(lvi) + if log == nil || err != nil { + t.Errorf("Error getting last log of indexed block range: %v", err) + failed = true + } + } + } + chain := ts.chain.getCanonicalChain() + for i := 0; i < 1000 && !failed; i++ { + head := rand.Intn(len(chain)) + ts.chain.setCanonicalChain(chain[:head+1]) + ts.fm.WaitIdle() + } +} + func TestIndexerCompareDb(t *testing.T) { ts := newTestSetup(t) defer ts.close() diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index 7c2aa8dc32..f59a01c032 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "math" + "slices" "sort" "time" @@ -107,7 +108,7 @@ func (f *FilterMaps) renderMapsFromSnapshot(cp *renderedMap) (*mapRenderer, erro filterMap: cp.filterMap.fullCopy(), mapIndex: cp.mapIndex, lastBlock: cp.lastBlock, - blockLvPtrs: cp.blockLvPtrs, + blockLvPtrs: slices.Clone(cp.blockLvPtrs), }, finishedMaps: make(map[uint32]*renderedMap), finished: common.NewRange(cp.mapIndex, 0), @@ -244,7 +245,7 @@ func (f *FilterMaps) loadHeadSnapshot() error { } } f.renderSnapshots.Add(f.indexedRange.blocks.Last(), &renderedMap{ - filterMap: fm, + filterMap: fm.fullCopy(), mapIndex: f.indexedRange.maps.Last(), lastBlock: f.indexedRange.blocks.Last(), lastBlockId: f.indexedView.BlockId(f.indexedRange.blocks.Last()), @@ -536,6 +537,7 @@ func (r *mapRenderer) getTempRange() (filterMapsRange, error) { } else { tempRange.blocks.SetAfterLast(0) } + tempRange.headIndexed = false tempRange.headDelimiter = 0 } return tempRange, nil From 74165a8fe31847fa4161929c6a9b00ac07251c5f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 21 Apr 2025 14:56:16 +0200 Subject: [PATCH 309/940] version: release go-ethereum v1.15.9 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index c969ab479e..53a1bae280 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 9 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 9 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From 263aef9cc41135a9207c8e788beabc39506430c0 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 21 Apr 2025 14:57:25 +0200 Subject: [PATCH 310/940] version: begin v1.15.10 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 53a1bae280..2bbd7e7b17 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 9 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 10 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From 1591d165c44e027c961d174c0f4ee1bb45a82520 Mon Sep 17 00:00:00 2001 From: georgehao Date: Tue, 22 Apr 2025 12:57:17 +0800 Subject: [PATCH 311/940] internal/debug: add debug_setMemoryLimit (#31441) --- internal/debug/api.go | 19 +++++++++++++++++++ internal/web3ext/web3ext.go | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/internal/debug/api.go b/internal/debug/api.go index 5e93585bf8..1bac36e908 100644 --- a/internal/debug/api.go +++ b/internal/debug/api.go @@ -35,6 +35,7 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/hashicorp/go-bexpr" ) @@ -237,6 +238,24 @@ func (*HandlerT) SetGCPercent(v int) int { return debug.SetGCPercent(v) } +// SetMemoryLimit sets the GOMEMLIMIT for the process. It returns the previous limit. +// Note: +// +// - The input limit is provided as bytes. A negative input does not adjust the limit +// +// - A zero limit or a limit that's lower than the amount of memory used by the Go +// runtime may cause the garbage collector to run nearly continuously. However, +// the application may still make progress. +// +// - Setting the limit too low will cause Geth to become unresponsive. +// +// - Geth also allocates memory off-heap, particularly for fastCache and Pebble, +// which can be non-trivial (a few gigabytes by default). +func (*HandlerT) SetMemoryLimit(limit int64) int64 { + log.Info("Setting memory limit", "size", common.PrettyDuration(limit)) + return debug.SetMemoryLimit(limit) +} + func writeProfile(name, file string) error { p := pprof.Lookup(name) log.Info("Writing profile records", "count", p.Count(), "type", name, "dump", file) diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 8ac8f44958..aed6bbbdb9 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -269,6 +269,11 @@ web3._extend({ call: 'debug_setGCPercent', params: 1, }), + new web3._extend.Method({ + name: 'setMemoryLimit', + call: 'debug_setMemoryLimit', + params: 1, + }), new web3._extend.Method({ name: 'memStats', call: 'debug_memStats', From 846c14e21f5f7ceffe47898a34a520895b1b0f11 Mon Sep 17 00:00:00 2001 From: colin <102356659+colinlyguo@users.noreply.github.com> Date: Thu, 24 Apr 2025 03:01:03 +0800 Subject: [PATCH 312/940] ethclient: allow passing AuthorizationList to calls (#31198) This PR adds the `AuthorizationList` field to the `CallMsg` interface to support `eth_call` and `eth_estimateGas` of set-code transactions. --------- Co-authored-by: Sina Mahmoodi --- core/blockchain_test.go | 2 +- core/state_processor_test.go | 3 +- ethclient/ethclient.go | 3 ++ ethclient/gethclient/gethclient.go | 3 ++ interfaces.go | 3 ++ internal/ethapi/api_test.go | 51 +++++++++++++++++++++++++++++- 6 files changed, 62 insertions(+), 3 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 289eff0a8f..134deee237 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -4099,7 +4099,7 @@ func TestEIP7702(t *testing.T) { // The way the auths are combined, it becomes // 1. tx -> addr1 which is delegated to 0xaaaa // 2. addr1:0xaaaa calls into addr2:0xbbbb - // 3. addr2:0xbbbb writes to storage + // 3. addr2:0xbbbb writes to storage auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{ ChainID: *uint256.MustFromBig(gspec.Config.ChainID), Address: aa, diff --git a/core/state_processor_test.go b/core/state_processor_test.go index a6ca2781f8..ffdf063812 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -255,7 +255,8 @@ func TestStateProcessorErrors(t *testing.T) { }, want: "could not apply tx 0 [0xc18d10f4c809dbdfa1a074c3300de9bc4b7f16a20f0ec667f6f67312b71b956a]: EIP-7702 transaction with empty auth list (sender 0x71562b71999873DB5b286dF957af199Ec94617F7)", }, - // ErrSetCodeTxCreate cannot be tested: it is impossible to create a SetCode-tx with nil `to`. + // ErrSetCodeTxCreate cannot be tested here: it is impossible to create a SetCode-tx with nil `to`. + // The EstimateGas API tests test this case. } { block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config, false) _, err := blockchain.InsertChain(types.Blocks{block}) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 872b3b03dc..352e6abc2c 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -754,6 +754,9 @@ func toCallArg(msg ethereum.CallMsg) interface{} { if msg.BlobHashes != nil { arg["blobVersionedHashes"] = msg.BlobHashes } + if msg.AuthorizationList != nil { + arg["authorizationList"] = msg.AuthorizationList + } return arg } diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index 02b2598b37..39ac4ff20f 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -251,6 +251,9 @@ func toCallArg(msg ethereum.CallMsg) interface{} { if msg.BlobHashes != nil { arg["blobVersionedHashes"] = msg.BlobHashes } + if msg.AuthorizationList != nil { + arg["authorizationList"] = msg.AuthorizationList + } return arg } diff --git a/interfaces.go b/interfaces.go index 53e2e3ae16..54a215d6e7 100644 --- a/interfaces.go +++ b/interfaces.go @@ -156,6 +156,9 @@ type CallMsg struct { // For BlobTxType BlobGasFeeCap *big.Int BlobHashes []common.Hash + + // For SetCodeTxType + AuthorizationList []types.SetCodeAuthorization } // A ContractCaller provides contract calls, essentially transactions that are executed by diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index aff051937d..5071e2412f 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -668,6 +668,11 @@ func TestEstimateGas(t *testing.T) { b.SetPoS() })) + setCodeAuthorization, _ := types.SignSetCode(accounts[0].key, types.SetCodeAuthorization{ + Address: accounts[0].addr, + Nonce: uint64(genBlocks + 1), + }) + var testSuite = []struct { blockNumber rpc.BlockNumber call TransactionArgs @@ -846,6 +851,50 @@ func TestEstimateGas(t *testing.T) { }, want: 21000, }, + // Should be able to estimate SetCodeTx. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: &accounts[1].addr, + Value: (*hexutil.Big)(big.NewInt(0)), + AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization}, + }, + want: 46000, + }, + // Should retrieve the code of 0xef0001 || accounts[0].addr and return an invalid opcode error. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: &accounts[0].addr, + Value: (*hexutil.Big)(big.NewInt(0)), + AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization}, + }, + expectErr: errors.New("invalid opcode: opcode 0xef not defined"), + }, + // SetCodeTx with empty authorization list should fail. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: &common.Address{}, + Value: (*hexutil.Big)(big.NewInt(0)), + AuthorizationList: []types.SetCodeAuthorization{}, + }, + expectErr: core.ErrEmptyAuthList, + }, + // SetCodeTx with nil `to` should fail. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: nil, + Value: (*hexutil.Big)(big.NewInt(0)), + AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization}, + }, + expectErr: core.ErrSetCodeTxCreate, + }, } for i, tc := range testSuite { result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides) @@ -855,7 +904,7 @@ func TestEstimateGas(t *testing.T) { continue } if !errors.Is(err, tc.expectErr) { - if !reflect.DeepEqual(err, tc.expectErr) { + if err.Error() != tc.expectErr.Error() { t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err) } } From 7ad97a4a0372cb96c774a93a7fe45f549d79d5a7 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Thu, 24 Apr 2025 18:19:10 +0200 Subject: [PATCH 313/940] miner: increase default gas limit to 36M (#31705) --- miner/miner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/miner.go b/miner/miner.go index 595ef8081c..3cec054d19 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -52,7 +52,7 @@ type Config struct { // DefaultConfig contains default settings for miner. var DefaultConfig = Config{ - GasCeil: 30_000_000, + GasCeil: 36_000_000, GasPrice: big.NewInt(params.GWei / 1000), // The default recommit time is chosen as two seconds since From b62756d1a3b8b09430f5b060caa7382c8117fb90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Thu, 24 Apr 2025 21:40:12 +0200 Subject: [PATCH 314/940] beacon/params: add mainnet electra config (#31706) This PR adds the electra beacon chain configuration for mainnet. --- beacon/params/networks.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/beacon/params/networks.go b/beacon/params/networks.go index 7e73a2c69c..51f67e0c97 100644 --- a/beacon/params/networks.go +++ b/beacon/params/networks.go @@ -41,7 +41,8 @@ var ( AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}). AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}). AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}). - AddFork("DENEB", 269568, []byte{4, 0, 0, 0}) + AddFork("DENEB", 269568, []byte{4, 0, 0, 0}). + AddFork("ELECTRA", 364032, []byte{5, 0, 0, 0}) SepoliaLightConfig = (&ChainConfig{ GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"), From b6bdd698a0584a8e62a34b6aa6871e8bf8b6e6fb Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 25 Apr 2025 17:57:38 +0800 Subject: [PATCH 315/940] core/filtermaps: fix deadlock in filtermap callback (#31708) This PR fixes a deadlock situation is deleteTailEpoch that might arise when range delete is running in iterator based fallback mode (either using leveldb database or the hashdb state storage scheme). In this case a stopCb callback is called periodically that does check events, including matcher sync requests, in which case it tries to acquire indexLock for read access, while deleteTailEpoch already held it for write access. This pull request removes the indexLock acquiring in `FilterMapsMatcherBackend.synced` as this function is only called in the indexLoop. Fixes https://github.com/ethereum/go-ethereum/issues/31700 --- core/filtermaps/filtermaps.go | 50 ++++++++++++++++++++---------- core/filtermaps/indexer.go | 6 +++- core/filtermaps/matcher_backend.go | 18 +++++++---- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index 920167ca8d..3da7f4b721 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -85,11 +85,17 @@ type FilterMaps struct { // fields written by the indexer and read by matcher backend. Indexer can // read them without a lock and write them under indexLock write lock. // Matcher backend can read them under indexLock read lock. - indexLock sync.RWMutex - indexedRange filterMapsRange - cleanedEpochsBefore uint32 // all unindexed data cleaned before this point - indexedView *ChainView // always consistent with the log index - hasTempRange bool + indexLock sync.RWMutex + indexedRange filterMapsRange + indexedView *ChainView // always consistent with the log index + hasTempRange bool + + // cleanedEpochsBefore indicates that all unindexed data before this point + // has been cleaned. + // + // This field is only accessed and modified within tryUnindexTail, so no + // explicit locking is required. + cleanedEpochsBefore uint32 // also accessed by indexer and matcher backend but no locking needed. filterMapCache *lru.Cache[uint32, filterMap] @@ -248,15 +254,16 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f }, // deleting last unindexed epoch might have been interrupted by shutdown cleanedEpochsBefore: max(rs.MapsFirst>>params.logMapsPerEpoch, 1) - 1, - historyCutoff: historyCutoff, - finalBlock: finalBlock, - matcherSyncCh: make(chan *FilterMapsMatcherBackend), - matchers: make(map[*FilterMapsMatcherBackend]struct{}), - filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps), - lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks), - lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers), - baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows), - renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots), + + historyCutoff: historyCutoff, + finalBlock: finalBlock, + matcherSyncCh: make(chan *FilterMapsMatcherBackend), + matchers: make(map[*FilterMapsMatcherBackend]struct{}), + filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps), + lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks), + lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers), + baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows), + renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots), } // Set initial indexer target. @@ -444,6 +451,7 @@ func (f *FilterMaps) safeDeleteWithLogs(deleteFn func(db ethdb.KeyValueStore, ha // setRange updates the indexed chain view and covered range and also adds the // changes to the given batch. +// // Note that this function assumes that the index write lock is being held. func (f *FilterMaps) setRange(batch ethdb.KeyValueWriter, newView *ChainView, newRange filterMapsRange, isTempRange bool) { f.indexedView = newView @@ -477,6 +485,7 @@ func (f *FilterMaps) setRange(batch ethdb.KeyValueWriter, newView *ChainView, ne // Note that this function assumes that the log index structure is consistent // with the canonical chain at the point where the given log value index points. // If this is not the case then an invalid result or an error may be returned. +// // Note that this function assumes that the indexer read lock is being held when // called from outside the indexerLoop goroutine. func (f *FilterMaps) getLogByLvIndex(lvIndex uint64) (*types.Log, error) { @@ -655,6 +664,7 @@ func (f *FilterMaps) mapRowIndex(mapIndex, rowIndex uint32) uint64 { // getBlockLvPointer returns the starting log value index where the log values // generated by the given block are located. If blockNumber is beyond the current // head then the first unoccupied log value index is returned. +// // Note that this function assumes that the indexer read lock is being held when // called from outside the indexerLoop goroutine. func (f *FilterMaps) getBlockLvPointer(blockNumber uint64) (uint64, error) { @@ -762,7 +772,7 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { return false, errors.New("invalid tail epoch number") } // remove index data - if err := f.safeDeleteWithLogs(func(db ethdb.KeyValueStore, hashScheme bool, stopCb func(bool) bool) error { + deleteFn := func(db ethdb.KeyValueStore, hashScheme bool, stopCb func(bool) bool) error { first := f.mapRowIndex(firstMap, 0) count := f.mapRowIndex(firstMap+f.mapsPerEpoch, 0) - first if err := rawdb.DeleteFilterMapRows(f.db, common.NewRange(first, count), hashScheme, stopCb); err != nil { @@ -786,10 +796,13 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { f.lvPointerCache.Remove(blockNumber) } return nil - }, fmt.Sprintf("Deleting tail epoch #%d", epoch), func() bool { + } + action := fmt.Sprintf("Deleting tail epoch #%d", epoch) + stopFn := func() bool { f.processEvents() return f.stop || !f.targetHeadIndexed() - }); err == nil { + } + if err := f.safeDeleteWithLogs(deleteFn, action, stopFn); err == nil { // everything removed; mark as cleaned and report success if f.cleanedEpochsBefore == epoch { f.cleanedEpochsBefore = epoch + 1 @@ -808,6 +821,9 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { } // exportCheckpoints exports epoch checkpoints in the format used by checkpoints.go. +// +// Note: acquiring the indexLock read lock is unnecessary here, as this function +// is always called within the indexLoop. func (f *FilterMaps) exportCheckpoints() { finalLvPtr, err := f.getBlockLvPointer(f.finalBlock + 1) if err != nil { diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 787197345a..3ec49ca116 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -43,6 +43,8 @@ func (f *FilterMaps) indexerLoop() { log.Info("Started log indexer") for !f.stop { + // Note: acquiring the indexLock read lock is unnecessary here, + // as the `indexedRange` is accessed within the indexerLoop. if !f.indexedRange.initialized { if f.targetView.HeadNumber() == 0 { // initialize when chain head is available @@ -105,7 +107,7 @@ type targetUpdate struct { historyCutoff, finalBlock uint64 } -// SetTargetView sets a new target chain view for the indexer to render. +// SetTarget sets a new target chain view for the indexer to render. // Note that SetTargetView never blocks. func (f *FilterMaps) SetTarget(targetView *ChainView, historyCutoff, finalBlock uint64) { if targetView == nil { @@ -178,6 +180,8 @@ func (f *FilterMaps) processSingleEvent(blocking bool) bool { if f.stop { return false } + // Note: acquiring the indexLock read lock is unnecessary here, + // as this function is always called within the indexLoop. if !f.hasTempRange { for _, mb := range f.matcherSyncRequests { mb.synced() diff --git a/core/filtermaps/matcher_backend.go b/core/filtermaps/matcher_backend.go index ee18a0694c..9751783754 100644 --- a/core/filtermaps/matcher_backend.go +++ b/core/filtermaps/matcher_backend.go @@ -111,17 +111,17 @@ func (fm *FilterMapsMatcherBackend) GetLogByLvIndex(ctx context.Context, lvIndex // synced signals to the matcher that has triggered a synchronisation that it // has been finished and the log index is consistent with the chain head passed // as a parameter. +// // Note that if the log index head was far behind the chain head then it might not // be synced up to the given head in a single step. Still, the latest chain head // should be passed as a parameter and the existing log index should be consistent // with that chain. +// +// Note: acquiring the indexLock read lock is unnecessary here, as this function +// is always called within the indexLoop. func (fm *FilterMapsMatcherBackend) synced() { - fm.f.indexLock.RLock() fm.f.matchersLock.Lock() - defer func() { - fm.f.matchersLock.Unlock() - fm.f.indexLock.RUnlock() - }() + defer fm.f.matchersLock.Unlock() indexedBlocks := fm.f.indexedRange.blocks if !fm.f.indexedRange.headIndexed && !indexedBlocks.IsEmpty() { @@ -154,6 +154,8 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange case <-ctx.Done(): return SyncRange{}, ctx.Err() case <-fm.f.disabledCh: + // Note: acquiring the indexLock read lock is unnecessary here, + // as the indexer has already been terminated. return SyncRange{IndexedView: fm.f.indexedView}, nil } select { @@ -162,6 +164,8 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange case <-ctx.Done(): return SyncRange{}, ctx.Err() case <-fm.f.disabledCh: + // Note: acquiring the indexLock read lock is unnecessary here, + // as the indexer has already been terminated. return SyncRange{IndexedView: fm.f.indexedView}, nil } } @@ -170,7 +174,9 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange // valid range with the current indexed range. This function should be called // whenever a part of the log index has been removed, before adding new blocks // to it. -// Note that this function assumes that the index read lock is being held. +// +// Note: acquiring the indexLock read lock is unnecessary here, as this function +// is always called within the indexLoop. func (f *FilterMaps) updateMatchersValidRange() { f.matchersLock.Lock() defer f.matchersLock.Unlock() From 2bf8a78984d70e8d5a695879494b17193f1bcf57 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 25 Apr 2025 12:44:25 +0200 Subject: [PATCH 316/940] version: release go-ethereum v1.15.10 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 2bbd7e7b17..56c0eedc31 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 10 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 10 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From f750117ad19d623622cc4a46ea361a716ba7407e Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 25 Apr 2025 13:27:24 +0200 Subject: [PATCH 317/940] version: begin v1.15.11 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 56c0eedc31..6b9a3b2ca4 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 10 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 11 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From 004526762b51f4270ce496f66a4dc2c7ac7cfa3b Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 28 Apr 2025 08:26:27 +0200 Subject: [PATCH 318/940] core/txpool/legacypool: refactor truncatePending (#31715) TruncatePending shows up bright red on our nodes, because it computes the length of a map multiple times. I don't know why this is so expensive, but around 20% of our time is spent on this, which is super weird. ``` //PR: BenchmarkTruncatePending-24 17498 69397 ns/op 32872 B/op 3 allocs/op //Master: BenchmarkTruncatePending-24 9960 123954 ns/op 32872 B/op 3 allocs/op ``` ``` benchmark old ns/op new ns/op delta BenchmarkTruncatePending-24 123954 69397 -44.01% benchmark old allocs new allocs delta BenchmarkTruncatePending-24 3 3 +0.00% benchmark old bytes new bytes delta BenchmarkTruncatePending-24 32872 32872 +0.00% ``` This simple PR is a 44% improvement over the old state ``` OUTINE ======================== github.com/ethereum/go-ethereum/core/txpool/legacypool.(*LegacyPool).truncatePending in github.com/ethereum/go-ethereum/core/txpool/legacypool/legacypool.go 1.96s 18.02s (flat, cum) 19.57% of Total . . 1495:func (pool *LegacyPool) truncatePending() { . . 1496: pending := uint64(0) 60ms 2.99s 1497: for _, list := range pool.pending { 250ms 5.48s 1498: pending += uint64(list.Len()) . . 1499: } . . 1500: if pending <= pool.config.GlobalSlots { . . 1501: return . . 1502: } . . 1503: . . 1504: pendingBeforeCap := pending . . 1505: // Assemble a spam order to penalize large transactors first . 510ms 1506: spammers := prque.New[int64, common.Address](nil) 140ms 2.50s 1507: for addr, list := range pool.pending { . . 1508: // Only evict transactions from high rollers 50ms 5.08s 1509: if uint64(list.Len()) > pool.config.AccountSlots { . . 1510: spammers.Push(addr, int64(list.Len())) . . 1511: } . . 1512: } . . 1513: // Gradually drop transactions from offenders . . 1514: offenders := []common.Address{} ``` ```go // Benchmarks the speed of batch transaction insertion in case of multiple accounts. func BenchmarkTruncatePending(b *testing.B) { // Generate a batch of transactions to enqueue into the pool pool, _ := setupPool() defer pool.Close() b.ReportAllocs() batches := make(types.Transactions, 4096+1024+1) for i := range len(batches) { key, _ := crypto.GenerateKey() account := crypto.PubkeyToAddress(key.PublicKey) pool.currentState.AddBalance(account, uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) tx := transaction(uint64(0), 100000, key) batches[i] = tx } for _, tx := range batches { pool.addRemotesSync([]*types.Transaction{tx}) } b.ResetTimer() // benchmark truncating the pending for range b.N { pool.truncatePending() } } ``` --- core/txpool/legacypool/legacypool.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 7bf360ff65..affe44cf06 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1494,22 +1494,22 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T // equal number for all for accounts with many pending transactions. func (pool *LegacyPool) truncatePending() { pending := uint64(0) - for _, list := range pool.pending { - pending += uint64(list.Len()) + + // Assemble a spam order to penalize large transactors first + spammers := prque.New[uint64, common.Address](nil) + for addr, list := range pool.pending { + // Only evict transactions from high rollers + length := uint64(list.Len()) + pending += length + if length > pool.config.AccountSlots { + spammers.Push(addr, length) + } } if pending <= pool.config.GlobalSlots { return } - pendingBeforeCap := pending - // Assemble a spam order to penalize large transactors first - spammers := prque.New[int64, common.Address](nil) - for addr, list := range pool.pending { - // Only evict transactions from high rollers - if uint64(list.Len()) > pool.config.AccountSlots { - spammers.Push(addr, int64(list.Len())) - } - } + // Gradually drop transactions from offenders offenders := []common.Address{} for pending > pool.config.GlobalSlots && !spammers.Empty() { From c8c8d6c4039a476478dfcfb732ba83822b648288 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Mon, 28 Apr 2025 08:37:02 +0200 Subject: [PATCH 319/940] trie: add edgecase for rangeproof correctness (#31667) This PR adds checking for an edgecase which theoretically can happen in the range-prover. Right now, we check that a key does not overwrite a previous one by checking that the key is increasing. However, if keys are of different lengths, it is possible to create a key which is increasing _and_ overwrites the previous key. Example: `0xaabbcc` followed by `0xaabbccdd`. This can not happen in go-ethereum, which always uses fixed-size paths for accounts and storage slot paths in the trie, but it might happen if the range prover is used without guaranteed fixed-size keys. This PR also adds some testcases for the errors that are expected. --- trie/proof.go | 14 +++++++++++--- trie/proof_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/trie/proof.go b/trie/proof.go index 2e527348bf..751d6f620f 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -485,10 +485,18 @@ func VerifyRangeProof(rootHash common.Hash, firstKey []byte, keys [][]byte, valu if len(keys) != len(values) { return false, fmt.Errorf("inconsistent proof data, keys: %d, values: %d", len(keys), len(values)) } - // Ensure the received batch is monotonic increasing and contains no deletions + // Ensure the received batch is + // - monotonically increasing, + // - not expanding down prefix-paths + // - and contains no deletions for i := 0; i < len(keys); i++ { - if i < len(keys)-1 && bytes.Compare(keys[i], keys[i+1]) >= 0 { - return false, errors.New("range is not monotonically increasing") + if i < len(keys)-1 { + if bytes.Compare(keys[i], keys[i+1]) >= 0 { + return false, errors.New("range is not monotonically increasing") + } + if bytes.HasPrefix(keys[i+1], keys[i]) { + return false, errors.New("range contains path prefixes") + } } if len(values[i]) == 0 { return false, errors.New("range contains deletion") diff --git a/trie/proof_test.go b/trie/proof_test.go index fab3a97650..b3c9dd753c 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -1000,3 +1000,35 @@ func TestRangeProofKeysWithSharedPrefix(t *testing.T) { t.Error("expected more to be false") } } + +// TestRangeProofErrors tests a few cases where the prover is supposed +// to exit with errors +func TestRangeProofErrors(t *testing.T) { + // Different number of keys to values + _, err := VerifyRangeProof((common.Hash{}), []byte{}, make([][]byte, 5), make([][]byte, 4), nil) + if have, want := err.Error(), "inconsistent proof data, keys: 5, values: 4"; have != want { + t.Fatalf("wrong error, have %q, want %q", err.Error(), want) + } + // Non-increasing paths + _, err = VerifyRangeProof((common.Hash{}), []byte{}, + [][]byte{[]byte{2, 1}, []byte{2, 1}}, make([][]byte, 2), nil) + if have, want := err.Error(), "range is not monotonically increasing"; have != want { + t.Fatalf("wrong error, have %q, want %q", err.Error(), want) + } + // A prefixed path is never motivated. Inserting the second element will + // require rewriting/overwriting the previous value-node, thus can only + // happen if the data is corrupt. + _, err = VerifyRangeProof((common.Hash{}), []byte{}, + [][]byte{[]byte{2, 1}, []byte{2, 1, 2}}, + [][]byte{[]byte{1}, []byte{1}}, nil) + if have, want := err.Error(), "range contains path prefixes"; have != want { + t.Fatalf("wrong error, have %q, want %q", err.Error(), want) + } + // Empty values (deletions) + _, err = VerifyRangeProof((common.Hash{}), []byte{}, + [][]byte{[]byte{2, 1}, []byte{2, 2}}, + [][]byte{[]byte{1}, []byte{}}, nil) + if have, want := err.Error(), "range contains deletion"; have != want { + t.Fatalf("wrong error, have %q, want %q", err.Error(), want) + } +} From a511553e448c947a0fe8f34acf7bb6f9818c2b49 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 29 Apr 2025 08:29:56 +0200 Subject: [PATCH 320/940] core: apply overrides to mainnet chainconfig (#31733) This PR applies the config overrides to the new config as well, otherwise they will not be applied to defined configs, making shadowforks impossible. To test: ``` > ./build/bin/geth --override.prague 123 --dev --datadir /tmp/geth INFO [04-28|21:20:47.009] - Prague: @123 > ./build/bin/geth --override.prague 321 --dev --datadir /tmp/geth INFO [04-28|21:23:59.760] - Prague: @321 `` --- core/genesis.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/genesis.go b/core/genesis.go index 95782a827a..080f8a3c5f 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -365,6 +365,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g return nil, common.Hash{}, nil, errors.New("missing head header") } newCfg := genesis.chainConfigOrDefault(ghash, storedCfg) + if err := overrides.apply(newCfg); err != nil { + return nil, common.Hash{}, nil, err + } // Sanity-check the new configuration. if err := newCfg.CheckConfigForkOrder(); err != nil { From 0ac4a84a1fdb9e54d27d0814179856a90e0c989f Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 29 Apr 2025 19:21:18 +0800 Subject: [PATCH 321/940] beacon/engine: omit empty witness in payload response (#31739) Fixes https://github.com/ethereum/go-ethereum/issues/31737 --- beacon/engine/types.go | 2 +- eth/catalyst/api.go | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/beacon/engine/types.go b/beacon/engine/types.go index 984090ef89..3e52933a90 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -131,7 +131,7 @@ type executionPayloadEnvelopeMarshaling struct { type PayloadStatusV1 struct { Status string `json:"status"` - Witness *hexutil.Bytes `json:"witness"` + Witness *hexutil.Bytes `json:"witness,omitempty"` LatestValidHash *common.Hash `json:"latestValidHash"` ValidationError *string `json:"validationError"` } diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index e6f29c970b..1e6981a76a 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -373,8 +373,11 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl } valid := func(id *engine.PayloadID) engine.ForkChoiceResponse { return engine.ForkChoiceResponse{ - PayloadStatus: engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &update.HeadBlockHash}, - PayloadID: id, + PayloadStatus: engine.PayloadStatusV1{ + Status: engine.VALID, + LatestValidHash: &update.HeadBlockHash, + }, + PayloadID: id, } } if rawdb.ReadCanonicalHash(api.eth.ChainDb(), block.NumberU64()) != update.HeadBlockHash { From 947fd3a834b5ac406ab795f5f069401a1860ee6b Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 29 Apr 2025 14:42:17 +0200 Subject: [PATCH 322/940] crypto/kzg4844: add ComputeCells functionality (#31378) For PeerDAS, we need to compute cell proofs. Both ckzg and gokzg support computing these cell proofs. This PR does the following: - Update the go-kzg library from "github.com/crate-crypto/go-kzg-4844" to "github.com/crate-crypto/go-eth-kzg" which will be the new upstream for go-kzg moving forward - Update ckzg from v1.0.0 to v2.0.1 and switch to /v2 - Updates the trusted setup to contain the g1 points both in lagrange and monomial form - Expose `ComputeCells` to compute the cell proofs --- cmd/utils/flags.go | 14 +- crypto/kzg4844/kzg4844.go | 11 + crypto/kzg4844/kzg4844_ckzg_cgo.go | 32 +- crypto/kzg4844/kzg4844_ckzg_nocgo.go | 8 + crypto/kzg4844/kzg4844_gokzg.go | 20 +- crypto/kzg4844/trusted_setup.json | 4098 ++++++++++++++++++++++++++ go.mod | 9 +- go.sum | 18 +- 8 files changed, 4189 insertions(+), 21 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f5fc94cebc..b26f43b376 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1854,10 +1854,16 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.String(CryptoKZGFlag.Name) != "gokzg" && ctx.String(CryptoKZGFlag.Name) != "ckzg" { Fatalf("--%s flag must be 'gokzg' or 'ckzg'", CryptoKZGFlag.Name) } - log.Info("Initializing the KZG library", "backend", ctx.String(CryptoKZGFlag.Name)) - if err := kzg4844.UseCKZG(ctx.String(CryptoKZGFlag.Name) == "ckzg"); err != nil { - Fatalf("Failed to set KZG library implementation to %s: %v", ctx.String(CryptoKZGFlag.Name), err) - } + // The initialization of the KZG library can take up to 2 seconds + // We start this here in parallel, so it should be available + // once we start executing blocks. It's threadsafe. + go func() { + log.Info("Initializing the KZG library", "backend", ctx.String(CryptoKZGFlag.Name)) + if err := kzg4844.UseCKZG(ctx.String(CryptoKZGFlag.Name) == "ckzg"); err != nil { + Fatalf("Failed to set KZG library implementation to %s: %v", ctx.String(CryptoKZGFlag.Name), err) + } + }() + // VM tracing config. if ctx.IsSet(VMTraceFlag.Name) { if name := ctx.String(VMTraceFlag.Name); name != "" { diff --git a/crypto/kzg4844/kzg4844.go b/crypto/kzg4844/kzg4844.go index 39fdfbe740..0a2478cea0 100644 --- a/crypto/kzg4844/kzg4844.go +++ b/crypto/kzg4844/kzg4844.go @@ -149,6 +149,17 @@ func VerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { return gokzgVerifyBlobProof(blob, commitment, proof) } +// ComputeCellProofs returns the KZG cell proofs that are used to verify the blob against +// the commitment. +// +// This method does not verify that the commitment is correct with respect to blob. +func ComputeCellProofs(blob *Blob) ([]Proof, error) { + if useCKZG.Load() { + return ckzgComputeCellProofs(blob) + } + return gokzgComputeCellProofs(blob) +} + // CalcBlobHashV1 calculates the 'versioned blob hash' of a commitment. // The given hasher must be a sha256 hash instance, otherwise the result will be invalid! func CalcBlobHashV1(hasher hash.Hash, commit *Commitment) (vh [32]byte) { diff --git a/crypto/kzg4844/kzg4844_ckzg_cgo.go b/crypto/kzg4844/kzg4844_ckzg_cgo.go index dce592b444..49a7046fe0 100644 --- a/crypto/kzg4844/kzg4844_ckzg_cgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_cgo.go @@ -23,8 +23,8 @@ import ( "errors" "sync" - gokzg4844 "github.com/crate-crypto/go-kzg-4844" - ckzg4844 "github.com/ethereum/c-kzg-4844/bindings/go" + gokzg4844 "github.com/crate-crypto/go-eth-kzg" + ckzg4844 "github.com/ethereum/c-kzg-4844/v2/bindings/go" "github.com/ethereum/go-ethereum/common/hexutil" ) @@ -47,15 +47,21 @@ func ckzgInit() { if err = gokzg4844.CheckTrustedSetupIsWellFormed(params); err != nil { panic(err) } - g1s := make([]byte, len(params.SetupG1Lagrange)*(len(params.SetupG1Lagrange[0])-2)/2) + g1Lag := make([]byte, len(params.SetupG1Lagrange)*(len(params.SetupG1Lagrange[0])-2)/2) for i, g1 := range params.SetupG1Lagrange { + copy(g1Lag[i*(len(g1)-2)/2:], hexutil.MustDecode(g1)) + } + g1s := make([]byte, len(params.SetupG1Monomial)*(len(params.SetupG1Monomial[0])-2)/2) + for i, g1 := range params.SetupG1Monomial { copy(g1s[i*(len(g1)-2)/2:], hexutil.MustDecode(g1)) } g2s := make([]byte, len(params.SetupG2)*(len(params.SetupG2[0])-2)/2) for i, g2 := range params.SetupG2 { copy(g2s[i*(len(g2)-2)/2:], hexutil.MustDecode(g2)) } - if err = ckzg4844.LoadTrustedSetup(g1s, g2s); err != nil { + // The last parameter determines the multiplication table, see https://notes.ethereum.org/@jtraglia/windowed_multiplications + // I think 6 is an decent compromise between size and speed + if err = ckzg4844.LoadTrustedSetup(g1s, g1Lag, g2s, 6); err != nil { panic(err) } } @@ -125,3 +131,21 @@ func ckzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { } return nil } + +// ckzgComputeCellProofs returns the KZG cell proofs that are used to verify the blob against +// the commitment. +// +// This method does not verify that the commitment is correct with respect to blob. +func ckzgComputeCellProofs(blob *Blob) ([]Proof, error) { + ckzgIniter.Do(ckzgInit) + + _, proofs, err := ckzg4844.ComputeCellsAndKZGProofs((*ckzg4844.Blob)(blob)) + if err != nil { + return []Proof{}, err + } + var p []Proof + for _, proof := range proofs { + p = append(p, (Proof)(proof)) + } + return p, nil +} diff --git a/crypto/kzg4844/kzg4844_ckzg_nocgo.go b/crypto/kzg4844/kzg4844_ckzg_nocgo.go index 0662b2632f..6f4bd3b823 100644 --- a/crypto/kzg4844/kzg4844_ckzg_nocgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_nocgo.go @@ -60,3 +60,11 @@ func ckzgComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) { func ckzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { panic("unsupported platform") } + +// ckzgComputeCellProofs returns the KZG cell proofs that are used to verify the blob against +// the commitment. +// +// This method does not verify that the commitment is correct with respect to blob. +func ckzgComputeCellProofs(blob *Blob) ([]Proof, error) { + panic("unsupported platform") +} diff --git a/crypto/kzg4844/kzg4844_gokzg.go b/crypto/kzg4844/kzg4844_gokzg.go index b4af9b1671..46a38a8913 100644 --- a/crypto/kzg4844/kzg4844_gokzg.go +++ b/crypto/kzg4844/kzg4844_gokzg.go @@ -20,7 +20,7 @@ import ( "encoding/json" "sync" - gokzg4844 "github.com/crate-crypto/go-kzg-4844" + gokzg4844 "github.com/crate-crypto/go-eth-kzg" ) // context is the crypto primitive pre-seeded with the trusted setup parameters. @@ -96,3 +96,21 @@ func gokzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error return context.VerifyBlobKZGProof((*gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), (gokzg4844.KZGProof)(proof)) } + +// gokzgComputeCellProofs returns the KZG cell proofs that are used to verify the blob against +// the commitment. +// +// This method does not verify that the commitment is correct with respect to blob. +func gokzgComputeCellProofs(blob *Blob) ([]Proof, error) { + gokzgIniter.Do(gokzgInit) + + _, proofs, err := context.ComputeCellsAndKZGProofs((*gokzg4844.Blob)(blob), 0) + if err != nil { + return []Proof{}, err + } + var p []Proof + for _, proof := range proofs { + p = append(p, (Proof)(proof)) + } + return p, nil +} diff --git a/crypto/kzg4844/trusted_setup.json b/crypto/kzg4844/trusted_setup.json index c6d724efaf..6793490e2e 100644 --- a/crypto/kzg4844/trusted_setup.json +++ b/crypto/kzg4844/trusted_setup.json @@ -1,4 +1,4102 @@ { + "g1_monomial": [ + "0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", + "0xad3eb50121139aa34db1d545093ac9374ab7bca2c0f3bf28e27c8dcd8fc7cb42d25926fc0c97b336e9f0fb35e5a04c81", + "0x8029c8ce0d2dce761a7f29c2df2290850c85bdfaec2955626d7acc8864aeb01fe16c9e156863dc63b6c22553910e27c1", + "0xb1386c995d3101d10639e49b9e5d39b9a280dcf0f135c2e6c6928bb3ab8309a9da7178f33925768c324f11c3762cfdd5", + "0x9596d929610e6d2ed3502b1bb0f1ea010f6b6605c95d4859f5e53e09fa68dc71dfd5874905447b5ec6cd156a76d6b6e8", + "0x851e3c3d4b5b7cdbba25d72abf9812cf3d7c5a9dbdec42b6635e2add706cbeea18f985afe5247459f6c908620322f434", + "0xb10f4cf8ec6e02491bbe6d9084d88c16306fdaf399fef3cd1453f58a4f7633f80dc60b100f9236c3103eaf727468374f", + "0xade11ec630127e04d17e70db0237d55f2ff2a2094881a483797e8cddb98b622245e1f608e5dcd1172b9870e733b4a32f", + "0xaf58c8a2f58f904ce20db81005331bf2d251e227e7d1bef575d691bdca842e6233eb2e26c2e116a61a78594772b38d25", + "0xb3c1313c31ec82da5a7a09e9cf6656ca598c243345fe8d4828e520ade91787ffb8b9867db789b34ad67cef47b26ff86d", + "0xa8ed8a235355948e0b04be080b7b3e145293accefb4704d1da9050796b2f6870516c1ebf77ae6a65359edcfd016c0f36", + "0x80e792d5ba24b8058f6d7291a2ec5cb68aab1e16e96d793128e86815631baf42c56b6205c19e25ce9727bd1fd6f9defb", + "0x816288c5d726b094e3fdf95cb8882f442c4d9d1101b92c7938a7dfd49bc50636d73ea1b05f75eb731c908c8fd8dee717", + "0xae009128d128ba2e1519bfa7a0c01ed494a7d461c3aba60f8a301701fed61fe4e31d6c79ce189542ae51df91e73ce1b3", + "0x96a866d60a9007d05825c332476a83e869e15b11d7257172a67690ea9bd3efea44bf9c8d42191454eb04fcf110b16396", + "0x8b250a2a06419adb9b611e89f7f8f2990aa301949b533ad3bf17c4a61ab5f5be0b1d5e2b571864d13f1bb75805c7795d", + "0x8450f49facf2e620fa45ee90e1801178842d927a2a25fc6ed7ba99a4eec7ae40eebfee41028eaa84f107f4a777694976", + "0x91049080cf659c0985a22d1366e59191bb89663f922e8168b9b7d85c8a73d74a6d9dceefd855d3d858b493670c750581", + "0xa1e167aeb2008087f3195926f1985c0a459d6ec57237255b1473a96de4e2c1cf766127c862c7dc853a6909e67cb06cf7", + "0xb667c0d4e26e20698b07567358625d5f003839c92de8088e12dbd74a6f6a3156b4ea8d252c9ad62af5f6c4fec1cf6cc7", + "0x8e4b5e304c0b1b161ae3e4b68b5e3ac66c42acd7c1ee2458044f6527c508a93995e50894d72d57c1350f91afe72775ff", + "0x8c642640aa7915421cdc21fd639f88a42052b1cfa358ff7702e60793a92b7b5926dae15a0c8f8f59cd3013f01c159ba3", + "0xa356f35e713cfc283056bf539de54a21731e61efb4c47319f20de4a4b723d76a33b65f4a67d298b9ec5c2a1579418657", + "0x93ce204146ce95f484dc79c27919a16c9e3fc14a9111c6c63d44491158d5838117d20851cc3227a5e8ba6ccf79e77f39", + "0xb585664cbb9a84b52f89114e1cf0cf1171bea78a136dc1404ac88a11210b2debc3b7a55e702da93ff629095c134a295e", + "0xb6dfd444ec7fdceb14c6328f26ca12c3f9fc4327d8d8c68948e92e7e61262b82d833a65a9e3af6353ffa832b6da25705", + "0xb4d4b8eb9ecfffe3f0d48fb4149c7b31aec1da7041ec03bd0750c52a2a7cbc3a7cfbf09d5bfdc56e3860826a62d0bb91", + "0xa4e248e3d61db52da9683fef188579c470d65e2df9064726847b1599fc774049ffdc6ef2ae578d5ed7874f1298ecdf69", + "0xa68a0fffc2e37d3183feb01b42234c0f4e510f9dc29d09c571e6da00fecad9da224cd0f31550070148667e226c4ca413", + "0x86adda2ffecb77236c18005051f31f9657a0d50fef2a1175dfda32e74d5d53df825c10f289eb0ad39df0c64fc9bc7729", + "0x998266d5c9c3764ed97d66fa9ed176af043999652bae19f0657c8328629d30af453230e3681c5a38e2f01e389ed8d825", + "0xa05261554d3c620af0c914cf27ab98f5d3593c33ab313c198e0c40d6c72022eb5943778cd4f73e9fe8383392a7004976", + "0xad243fb3631bf90fedb9d679fd71fc0cf06bda028591ded2bd4c634ea7b3c2bd22eca2ab318fcdaa6c2cda1e63e1c57b", + "0x89b9859a04f903c95e97fb2951f01cc6418a2505eee0b5bc7266b4d33e01b69b9fe7dc56fa9ebb5856095be0925a422d", + "0xa68d118343a5bbfbbab95ff9bfe53aeb7fdbaf16db983e6f4456366df2aa01fbdb6ee9901cb102fc7d2bd099be2f1f3e", + "0xb49301f25d5a9dd2ec60ddb0b4b477291958487efea9e54dc0e4ef388f03b8bbadd13259d191f7a0b7513876767d8282", + "0x8b93df7fb4513f67749905fd43db78f7026589b704ebb9ea3255d0ad6415437799f40f02e07efccda1e6fd5e8cd0a721", + "0xad88769ace96455da37c3c9019a9f523c694643be3f6b37b1e9dcc5053d1fe8e463abebdb1b3ef2f2fb801528a01c47c", + "0x80f0eb5dcbfaaf421bf59a8b9bd5245c4823c94510093e23e0b0534647fb5525a25ea3aeea0a927a1ee20c057f2c9234", + "0xb10ad82ea6a5aeabe345d00eb17910d6942b6862f7f3773c7d321194e67c9cced0b3310425662606634dcd7f8b976c04", + "0x82f6fd91f87822f6cc977808eeac77889f4a32fb0d618e784b2331263d0ffa820b3f70b069d32e0319c9e033ab75d3b4", + "0x9436d3dc6b5e25b1f695f8c6c1c553dab312ccace4dac3afddc141d3506467cd50cb04a49ea96ea7f5a8a7b0fc65ef37", + "0x8e0a9491651d52be8ebf4315fbbb410272f9a74b965d33b79ff1b9e1be3be59e43d9566773560e43280549c348e48f01", + "0x8809137e5d3a22400d6e645a9bd84e21c492371736c7e62c51cef50fee3aa7f2405724367a83fd051ff702d971167f67", + "0xb536a24f31a346de7f9863fc351fa602158404d2f94747eebe43abf1f21bf8f95a64146c02a4bec27b503f546789a388", + "0xb5cdf5a04fc12a0e0ef7545830061dff7fd8abea46e48fbe6235109e6c36ee6bffcb9529e2f3d0d701cf58bbfb6a4197", + "0xab15377525753467d042b7931f66f862cbbb77464212c9aa72d4e5c04375ef55f619b3a446091c1ba1a3b5d9f05e538f", + "0x905a75b943ad017ff78ea6ddd1d28a45c7273ee1c2e5e3353685813793ead3370c09cabd903fcab9d8b1c6961372d486", + "0x8147df4324faddc02fb0896367a7647b719b6499a361aecfdd3a34296fa6768ad31c34f9e873fd1e683386c44651883e", + "0xac91d08570dd91f89d2e01dca67cdc83b640e20f073ea9f0734759c92182bb66c5d645f15ebd91ed705b66486ed2088d", + "0xac6295ef2513bbea7ef4cdcf37d280300c34e63c4b9704663d55891a61bf5c91b04cc1d202a3a0a7c4520c30edc277c7", + "0xb604be776a012095c0d4ebc77797dd8dec62a54c0559fb2185d7bac6b50d4e5fd471ac2d7f4523206d5d8178eabd9a87", + "0x80ead68def272ce3f57951145e71ed6dc26da98e5825ef439af577c0c5de766d4e39207f205d5d21db903d89f37bbb02", + "0x9950b4a830388c897158c7fe3921e2fe24beedc7c84e2024e8b92b9775f8f99593b54a86b8870ec5087734295ba06032", + "0xb89ba714adabf94e658a7d14ac8fc197376a416841c2a80e1a6dde4f438d5f747d1fb90b39e8ea435c59d6ecda13dea1", + "0xb0c78e7cc60bd05be46d48fbb0421a678c7f14b8d93730deb66fbe1647613b2c62b5075126d917047820c57fc3509cb9", + "0xa860c4acc5444e9ae987e8c93cb9a5f17d954d63c060cc616f724e26bc73d2c54cd36e0492d1fde173847278e55942ba", + "0x8fb8269c9d5c15428e8d45da1251e4c4a4b600d47da0caea29fef246854d8fb6acae86a8e6440d0c429d8dd9c2dfee0c", + "0x96c5d8eb6fd5c525b348ee4335d200139e437e4be83690af0f35b7f336a7cda8c6d2958647988b84da9f2dd7bbb7710b", + "0xa7f62141c4346cc14e9823dc38ac7d587b0427022afc1498d12ee2c43f6ac3a82167057e670dd524b74137f8c3ceb56d", + "0x956aac50d06b46a3e94397f163f593f5010d366aa2d816c2205c7d0f47f90cf0f36c169e964f9bcf698d49182d47d91f", + "0xb812899bcdc0e70d79ca729cb01104bf60e1357b9085a10f64f3ba9865d57e9abd0a505a502d4de07afb46f4d266be2f", + "0xabce02c7e1372e25d40944dc9ece2904a8f59c8854c5f2875fe63ace8ce37d97881f4f9ab4f7bad070ec8e0daee58d3f", + "0x8fb13c515b2d6abb4e14ed753fad5cc36c3631dfe21a23d0f603aad719423dd5423157eefcbd9a9c6074e155b79eb38d", + "0xa9ef67304dc297ab5af778cf8afa849eeac27db4b6978963e97b95ef7a8d3264d0d07775f728c298a2b6daed2ecf5053", + "0xa9b975520adb066e2ff2a4cde53284c23bc84261a22dc43b1634d99eff8e7892e46bb6e6da7319c9e72788aa9ea7a1ea", + "0xa6eaea4ab4206294474d9b956d9d3188d558a5633de2bd05df0d3bac03dbcbe4ed85406349c1d2e660b77c6da1f5bf8c", + "0xaf4a19f77290dddee762e1e0d4bc9945aacea3f75756ae46cd3e58a8f74d1b5db73e4834687946b0f39191e32f2fed0c", + "0xaafa6523f58f1a4cabc924c86d842816d606afeea21fa4b2b8b9573425810fdcc41c98888318e868f9c05e2be12178a3", + "0x8ef38fba0a3fa4ebe985239c8b759c22aaef0c57e6f39050a651c869487803b0d1e389c3d958fb5a7f37740f050ac69e", + "0xb07dfc9f85913c608ca7596a2e361f05e4853fad00e796fd492d247de6414892ce160f627669b1ba933b6ad726415d4e", + "0x94da679ad1d78b2bff5283c938f17b2a7d6e9cbcdf59d340e6dfb652951c7a9e852ac0590f99cfee9631b9410f6f00ea", + "0x98a907c9c021a5b034d3720197c160a82c4b7146cb73d48efeed99b9d0c6b831812cf80ac7e19e85a676a8cd3ead72de", + "0xadb746595466a12929019d0048cea33236b05c1229d2eba73b259a18a786f2bc3f05fc0598d8ce253cecb80bdf679aaf", + "0xa2fbac016996d68f9027a157b0a3f6a336144a798d6113adfcda3a5d05b62c31f108f112aa915906aef22b7f83b9228b", + "0x81841dea1904406d1b6fa49b4b3f7f6cb40b7646cf44d36c9fa07e3dee29f8e47324b40d8356ddf653109673c3374e9b", + "0xa3edbb8aac5e60c775775cbdb19067341b2e2530de48738e84c2c07151241ee31f0d8333bf20c2bc9dcb7b2e638a6b5e", + "0xb8aa6890e22964828787ce86460d3a32f12a655bb5c28de500f2fcf6b61e3334640ec6ba96029a4912af0d18df4b4139", + "0x8ca43169f04243ad0fdb0152de17c60d9e31ee0ab520970fccd98590e05508821a183b4b367967e60d53c2c826ec5dbd", + "0xb179fffd9df8c00486c5a8b9327d599f5a11745ef564f06e126849b06fe2f99273c81f65bc941efb0debaadfecbfec1c", + "0xacf068f1c2b1926279cc82750ce21b0d6b0bfd0406f0d8bbfa959bd83935932957c7f6b8de318315bf0b75f6ee41a0f2", + "0xb97831da260919c856e9f71a41687f5979bc16f8a53b1037285b4a2f9ce93af5cfe70bf0ad484744827fb55c847b58eb", + "0xaff50b0bd907383b0c241727af364fe084d021221bfb1b09fb6c1a7752eeba45d662493d590f1f182764b90b25f17906", + "0xaeeef044c14e3ad41e1235c9e816e1eb49087fd3abe877b89b3bade74459186126e160bb569bcd77779e701b19b5f71a", + "0x8483deb2b7001ca7c438fcdca8ca6aba96c9cbc4becfd9b16a6062705eae270011bcaedcae69bb54630d8c78129e57c7", + "0xaeee8d24be4ac0d9784c029e239fb5e64316ce29b88f47394cfaaa8bb966a72061bff72f99d02dc51c9705854686e77f", + "0x90ae09525a16bb2422169e15d6831c87968a14ebc0d1d27e11a759839c73c655b9d33ee5b12f275d6f440688146fbd2f", + "0xa3a41fc7fefef101422465e506bea7f3ff23c26fe35f5732b86f5f2471fb93b37ebc339f84c6be1e8d22abc812c2e212", + "0x86f4b5293e8aea4af1f1fb05dcf99714cb3aff1cfc849b1bb73524061c921c9da9ad92579a852e1889da29d952f02fe5", + "0x8932ef39d4050a1e9dc0fd8afeaf159472d71c5c27f458c69d2730836606ea56e19c8c4febf2535f930d3260e9bc7637", + "0x86307b9f3696bb21c20e4558e30310389e7367803c353d437e9b696039a0ff054d9a4953b75237ab1d1dd6f71118c189", + "0x96e57730e683ef5b550c91de18b19ac73879f3e26234297db68d28747ed0953beb0f3913cfb720c602720bf9330685d8", + "0xb04a19ee70123782e47b238abde55baf60ac0c66292a998af0d14afc8bbeb1134e557b94cd17a020084631c09a0d3c02", + "0x829abc8718be8139569fcb2c398962f38f4201114d30e2b2fb23566f8a27a5c380f5605cec543415202a12ed859e33f6", + "0xa0744fa488c8fa92a722c5fc4ef5a47dfe824eccd87d26c8bab9c174cbb151d44b1b29082c48652f03d3177e5ec86001", + "0x81d4035ae9fd28bdcd78b135cb54955d3b685a527319df6ee7e904b8e6d796f5f5a5f5035ee1de750c4cb6050e452b9e", + "0xb205e8c2ec24d7104fa0106c09ad34b5a912c1adef553fb718838dd627355993c2ec01055c11d00b2c75b68e9516d44b", + "0xb12d09da7968fa7394e449624fc7174d1d76c069ccb03e140d4d87a2d3f6d1f7b9cfc930f0c80becc673406ebe63f08e", + "0xb23752c158695da85048fdf38b395681cc0e8998630af8a9ed41efbda08c9964c2dc8ae6e53377264be4467d702c0de4", + "0xb0d84582fd73628d96b8c1ec96197697c41a963542451a2ade0890af0d33c7161d0f18e1a1ce2c168ca2dc1e9119d55e", + "0x8b877e618b469aa187632e410b125d2999d5738fd66d482000706b51fd904a0c7e7daa8c9b729fa33817bbc4154cba2a", + "0xb1cfc8a7551b601723b937d497d01dec3ee7614c2bf13d430b1058d5ebc1406045009ff02c2ac15bf8cf16f860193d1e", + "0xb6d9da84f97b21e13175bbb0b5cc8e79e88b470c87a3e115726c1bd98e0288526c58f3faaa8aa170ace0cd6a60852525", + "0xad2e773c2d527671ca5fab7085dde4da31cd35f45d4315dd95d8893ff5fb900494dca08eccfc1a2fc7bf7c7fd2fcab97", + "0x8d5a79b34aeb761d4a0c73f09f02e9548e6d382c33ee6887a759ab05762b490b8a549ef2933c7e3a46415c154c0221c0", + "0xb6f2cbe81bd0a7298403be392f8456bed30aed7ef30216959357698f789affd2942ae5fbaf3f48ecebeb7c273b20cb57", + "0xb5b6c45d99cea7ce6a1dc134aff4a8f630f299b42bd59592a7592345f8cd35bcbee944e61b0723de732fcad6e4425b63", + "0x8077d64dfcb2418974e956ea6dbf8a4c05b25d2a025333ad7e2a379f1976dc036771403383a51bfa3476c9c619ef8bef", + "0xad2e0a9d479c77a5fb73b3613a177fdaad50dcb50fed50e756ba18164c153af30b07fb2565e80ff7469f1b0338b7b5de", + "0x81017d1d80a6b6df4e99d0d7f85a8180b5523e8fa2ea2672fddff604933f8a113cab27fce098dcb454d7d1f7ed266e04", + "0x852355479d68e76c7febf6dfe2ef8e80d575c0d3bd52c983803592021cfa898c571c0b884412c21e66f0dbfe03167b53", + "0x98e1bf8ad48421467c93b9f72b47dded7c41b4fcd36ea55ca43ab24b0d0b876f5a731f422579b7167c7138fad2121266", + "0x803369314abd5422019ed4b0ef652b4dbe97ef5a87b0ea373eec9628b64a12120b2c3d4eb53db405131ff786d14c7ac6", + "0xadf2613fc34f73e1160975c140e925ed84d254e03cc3bc7fc1d19957b499c9ba9d9e4c1639981b594a7095c0a52c6757", + "0xa2f6a68efdff6e4173c00692abcfdfcdaf6f8b62369afad3dafaae4f2f38c4860780b4624d185e20e4f4498b75b5fe94", + "0x8b1658aa0e119fb8401d486ed08d60240d26a8623ef9788e3b45ad09ae31259395b021bd16be395139cbb7149714e764", + "0xa7dd8bf21121285e00672ee8bb84e0cb39b2496fb53a26e35dfbca7f2b04e9a9ff9db15f53fe63fcbeafeb2deeaf2ca4", + "0xb6d8d709e44bc18f3b41d69608edce60c02bcba48d3b7e2fd420842657f0665a7343246dea149a25e8f3416284abae66", + "0xaaf744ca5e9bcb63e3e2939b7a1e96e4a93c88c76bec0cf4294dd7db95cdd3f6a7d92196e352d08680e2328bc4592899", + "0x84434b015a7c398d35f1ec71fce455d62ba4ed4f62da042ec31bb2b4db47073314354cd50bc322297a1cfe35138bf490", + "0x8d70b3a3cd9d5dfefdacfa418c0b775a112a47ce538d33a560a519660009c3f141fd6221c18539129e9c0acdaceeeb80", + "0xb8c6903412a800ec78a4c15f31c24385a267b0c0ece32fd31bbbb557fd70c3b2d60d8fc0f90fbd70f43baa1928ea30ba", + "0x8e391dd445ea06cabb433f057853f8159511b2f9bef41aed9ccd14e0a6fcd912bbaebd38fd5fb736cfde0fa34b7a4874", + "0xa40cd988f70613df32babbd1bbc2f1b29ff1ab0147b01161555a81d56c9621657999bcdb1df38485f687afc51d5d0f23", + "0xb6a008b4426b3d7b28ae04eee4698fc8ef6a35d89008ef5394da39ce582ce1a45dcfae9a33b90f6fa4237f3667803873", + "0x8987280debfb175c3b44a2f152ea82548e4f680966f1fcbee9bf7d714e31bf8080c33f52705ef3aeee70544b22516aba", + "0xa78a51a2c11eea7680a5a0ae417a2981f8c69c396e06da621eadd7510a3664ade49d065617bec67b3de779548a4f4509", + "0xa4d9163f0a1bc048385e94d5e0bcafeee1b18f28eb23505623b9e8ef16f3df76408254dfbe790e45f2884198060d388d", + "0x83dcae2568a0c518793c0f6e38b42f9ceb50673d100b556a17ec8bd9faeec84afe50b8d72422c6b2356959667bb8e2de", + "0x874731941be4474b4576226e5906b5dee89fc9b56a9870dcc7289c1a7d494d345ba6aba31f7546a16f9963283c05f744", + "0x82c1cfab1f501189ac20147fc4631075dbf1abf9125b7d42fcb4f31cf73f3d6461b1bd08fdf6e45cc54bc08a7d5d51d1", + "0xb978228286f5d4a10ce027b6bea3021affcaa805340ca4b5192c69e8c56db59f48e4a14a284ec015f53baf97389f62b2", + "0xaf125f4fdccd1c1b64fdffecb5ec7cf8c7392bbe476e1b89a5b5329c5ba4a526e58c11e72ab9de8a38d60af648d75adc", + "0x8411a41ec14295acab0d36389013535a80dfff6e024bffeb32fb3070762f61256419e8c51b2ad6de9dbe4f1e8e286912", + "0x8ea67a91112a41f9c65515cd496f4b0cdefa1400fc06568eef000c9eae6dc250fb7622eb3f2deca10b37287cd96fa463", + "0x8da99b6c55c31dee6a49aabb54da249d348a31d4416201a10c45a3b04b11e99d4ae9813632f0ee36c523b5cca62f6f49", + "0x8b44656341e039e2bd83a19c3bb9a88f6209482e274f8cd4f8557b728e5948dd80b5745f621b96f4562928689314e8c2", + "0xa02d424a615ba0dce8ed91f477e79852215a3a39d025059826fa278e7eebef19824b2a2844f5b3865a0f471b609a23f5", + "0xa1f115cebc3fff3bcf233da27cef19eae791660f155d088003460f75567a550bef0722885010ddc384acdeac635939dc", + "0xb61a55ce9d143c17876776e064b58a10baf0ba13553c785c1e47f57b5f94c0cda8bc89d43d73386e57816c15b61a8ec8", + "0xb4073f47041e20a8e548c7fb00e07ba3b9056c34eb4ab63bb0e7b48f8e338e8b56a17611a1b5f4c03b352450b86f1d69", + "0xa7b1a07b213205b682fc5b6acb7e76fdf97b280c26621d8f3b76b7c1deb3511957da33a4e358c8e8f3d98b2a8855d67e", + "0xb797e67c2670fbd9844e8a68c585f404b035dc14bd4ec75c3f95f932c777f9db5d5f5df7629164af488fc1213035cc5f", + "0x99618200797b945f595794d6468e5c618649554ad9ba896330f1cc844090eb956ae9fc23132912f9047085c5f0c3bf7b", + "0x81194aa1319abf534cb3927af9adfb178a99d0e3e8c99ab1105f1d3b4fed40ec2971caf1d6647acb0c8d681eca53097b", + "0x80673f18e4978dbc226a6cd4b128a1259d9a7f833879c6e2fbe24d69fef2c3c23a51a4f3e8d88fa4533434bbb0723661", + "0x8125bf6c7dbb2fb63aaa3f53283559f172c788223674adbeb6d5bd17cfe888e6b87a79aec774917f20ce911c1f85f8e7", + "0x884bcdb1878b14fc38adc9fb8b4dd0b3afde404fbeb664f26ddfebc81736018551f23e75ce4cfe4865f610bcd454fbd7", + "0xaec65c8d4be8316e98aa54888af01bc6703a0c5d04b69756ff39a0a947b66817ec59d76afe9f61a25749b5e890f03e02", + "0xaa457aaa1b014a4c5a8992847a187a23321bb43452c98745987d038e3b04046102ae859b7a8e980eea978a39d76a88ef", + "0xa9832ee63b08e19123f719bfe2fe742125f32463efa966c7709a98ebfc65277670e9ea1fa2d2d78b96bdc7523b0c4c3e", + "0xa87b6b1b7858f96d55064274f29fbde56067064962cf3c3e2ba3110b22ea633bc037a74d23543ce3307a46208855d74f", + "0x897cbe4ab68a753020fec732dfcc052c7ed9905342b5a6fe0aa25c631f9ad9b659e0ee75d46f0df6507b6720675ee28c", + "0x97c3b5f0d54c1fc45e79445c3ff30458959e406a069f5bbf7979d684195b4fa0406b87c1c008f4075bc9e602ed863152", + "0x921e65d582ea9322ddfad1c855331c3cac81f53c700b96db5305a643c084eb6793094e07944bfd41dc02c3b3cf671530", + "0x8f23ef1aca02a260a3b65d25b110f28d3bafca44727448c8f2d03c5e77eda620c1721b06681bd816ee6027664d76352a", + "0x946a89b132ec0795aea9ff9dde7b77e7feafffe6e4a2f093042a7e6c71cd6ab87ce0ca914a1b5fabad4e1f96a795f163", + "0xa01e2de9db33df6511172123ad6f7c64074237471df646b32dd9aff8c15278e2723108e4facaedca97e9f49503f8c792", + "0x99dcdcde45b2ea3f15279936feede5f7d3b63ca4972f335b0559c2fa6f9faabd8127aa892a36deb114357ca906553ed8", + "0xa3f8af37bfcf66b04d1896a4bd5d343f4733d4c3305369ac7e75a08f20f2004c10c642d2c7577f4e5c4d1f2cd851ac3b", + "0xb7294d15a3d674a56099f97a1adc9e82c15e90832eaf1722df110fc2abc8634c51515e5ad8522015498a3753b1fa8c49", + "0xb4f27f5062ba7a04ea0048b3025b5e3d5b5d319a9e80310c808a5fb4e8e77b38c10a0f3172cb805cadbcc8bc66d36ec7", + "0xaefe5decee0ae2dc372cc6cf4217daf97c4c908d145f100f0daf1ccdfdf641c78432c2e473e7e4b77dcdf2d4c2bb05f0", + "0xacc84af7648a535ffd218c0cc95c8f7b092418c548815f1bafc286b1fe14f6ccb51b2044db3bff864d0bb70e88604084", + "0x84d8e3dac0df6a22beb03742e1d4af684f139f07e2ea0f7fb27fc2d7d4f1e89b5e89f71af32ff115ed5e6092133535f0", + "0x8ada001e1a03a823c4c056f636e77adc0f9dc08689d28de0d99e0feecab5db13abf37b41ec268dbdb42c75419a046c68", + "0x87dac6c798d1744dff81d8bc3e0e04f3c9bf260e811685ddb9a9a8d6eda73927439b344f9a818d2103fad633de5a4a17", + "0xad9929a7d8a7d5d5954e48281a87e5c84f67e19110d73296b9989a09c76767a57a8115629239ffb4d99dfdf9c52ef6d9", + "0x81ac7cbeef8ec35a5c3b61cc887080c29e6cd3e08af37e45830d17400dbacfb374dd07bf370b979828c3875b2027d5c6", + "0x97f92c9182953b7e10f7a1bbb6b5b5c40b8275eb5a6eec1e29874c4712814749aa8c409651380216e1ff01d7b8511041", + "0xa09794d0bbe7db013045d3fd857c1544fe6231d21afa3495fa300371f6301a3a0f4b8ea175b281503dd06078ff371ae4", + "0x839bb58d320aa08116dd387a57a2b9bd9efc89c4cdfd82d0e47a00cabe644631d09be5436bd485df3b61b75ddf81a3ef", + "0xb1cdaa344f783757e8b9c1f84421da3c5be4c69f019a8fd4c1aa5bf1a63e8970c99e35c22cf3b48a0e6738bc6ba7ce8d", + "0x92af68e3216c78998208fb24b5ba0e645d0d3f5e28222b805668d7e9cdd6c033d3b22fd6df4c2d745d7f910d133cd226", + "0x87640a4ea4e605e2204e5232b29a6c1c31152d83547eef14122cb76a0da52b8653801af48455a3ed713b9dcfee7b1ef1", + "0x8147e5bf0c8f4731155ca0517ef3fae5a32b4d5d2d98ed0007b23893d8dbb7f8a1199c50c1750c2fa7c9cebe594b1bb0", + "0xa76b4473c63c3ab6103c729afd2482822e4150f3155af39983b0ff0766c71cb622455ce6304e23853661eaa322219d18", + "0xb3e2f05ca551bc3adec0067e4034aaffd72e0b64ac18ae25452c996927976c6727966e26d213b032521889be2170800d", + "0xa8414cd14cb3be658e9e0004ce511ef7063439b1cbc3166a11de030613fde4b59caad4e91d426927863c55382afbf476", + "0xb2f0f8ab99f4d0ea785ac84fdbc00b20217b1df59b30b51d9d209d489d53b69dd5d82cdacc16fd1dd15c3a4001595f50", + "0x8b2025d5fd658c9bbed619f3e3f6ac8efe7aeff8aa9401bd66a7ceb0062c44b353608ca073f95be99204f0a913bb77eb", + "0x94a46bc5a87291b42024b2137e623c70115b9c6b196604106bfbfa20f3f56ac7779763f56b580190d3cb2f1c648cada1", + "0xaca9355545118d0769cacf69c4b23d6d68d229cd8f68f1bc0c847c05569c5af6bbbd8c4dceb637b4a6b3b5c83841bf5e", + "0xb0731992cab87c7116406b283a84707a34838bfa3284b0f6082dfabeaf41c5ac2b0ddc1b420547a1b0955aee92de2dc0", + "0xb671f77588c0f69f6830a5b28e7d07ed161b81fa9791bb3a24aae6638e3aa5e186df74978a82549c370c18ebee04d4f0", + "0xb5621ed841780f3e6681d880a76cf519cdd20d35197b112eeaa686764d57b5dfa78ffe1a294b6bc76b6e3949cd2a2369", + "0xafeba2524659d00caecf089645611553187a6ed7102050f6dd20f5a19bed08ac7065912d88371ee06242897d58d652a4", + "0xb78bfb83d44ced14a20135804aba3f00128c3ce1f302e95567ce4097b0d973414153fb305b9f156882a5a0554bf25973", + "0x98510aede95d26b1adf214053eae051ffaf24894e2fa37961a91d0ff5392dd09388196648d95b73e90bd88f2587cc4bf", + "0xb35c682d49c295946b9f120fbc47b95abd9ee86d294abb003a92139fb825b509209562575015856a270eb3eea86397a7", + "0xb9641bf685571dd9c478dd2033a1f1b11cd3a662b26502c78595863b8e536a189674a9a85f7a253453ebfd1b99fbd841", + "0xb2ad37036a59b1c9b8457972665720a6868422ed8157b6810a9c0783006103be34ab732d7aeb8629653edd18fd0f1717", + "0xaf0920cff05179a3896ea6ea322c39adf91ada5bc40fe3f6fb1b1b4e121e907c904bbaa8ca00468b3749f3da144d71f3", + "0x8e269672818ef1e2f9e0c8aa65c84442fcd9151d74bb8e870cee8c0e3fe24526e1a5388b430cef47b67f79b4e4056bcc", + "0xaa29a16fe00ea3d143b1032b1dd26b8ce638f37f95c085c7e777e8e2784bd724bd5c38b1583c61a6ec7c451dd78fd3fb", + "0x87452b7435911cc5f513b0c81b15aa04972ecbe3d7bbd0a5d676c96a8a311301c0e07fac925c53a350b46fbd3d4d0fc1", + "0x869a81c351096f47748e41566ae7b77a454b1cdfaa41d34a5742f80df38fbf5cbb08924b6fdff58e3b18f05c62bbbbb1", + "0x8b7bc1b0486300981147a40a449ada9a41afc06d735cce8bf0fab3ee94ba2e2ea57b1397e3cd31bc295352beb8334ef7", + "0x93e93fc41adb2df279d95654921b4c2edf0d293dab58d0afefb221f777349ef88d0985b3447e3b935954a81f1580a92c", + "0x970fa7cdca8324faf3e62348bb50d78f580b4f43f2e1c11bd8382d48d0074a3c55c6407203a0c9cb1c5f2163ba421ef4", + "0x924983929e608d27e4a36d4ed919297869e3c64de51aca794d32d6e90aea546bf898d98ceca28a0b2187734821b78504", + "0x8d395332529c703d943d68415d443332b5c1342ca9d9a59bfa8bd4ab63e93358c4b0dde6ce1f2e8ea9dc8f52ad7ebd95", + "0x80200dda853e588256599e7f905add5d5ee7c74272780317694fbae39318ae9be05d5bcd7b20cf460069743f3d4ef240", + "0xa287d51d6359c9ef7c7ac1b20e479ce7d0146dba5606397bd04b7a622cec642508d5b45d51b31de71f9763595b6ac88e", + "0xa320396c075175d6599225cf2e1de8c7cab549f6316c07feb0f6eaa21f06b2dd29ab14fbdf2af4543b4890ec0fd08a4d", + "0xb1e9fe230418d20368691058adcbbe30011bab3000422f0371015ff8bd09c60fb5fa85d18550d35b1c900977ca48f58b", + "0x9718fc26a51783b971744933f20490e9b5cd9162f86b84788c4c5217f5409e37b5a39d628b18e5b35a757acf67596321", + "0xa0cf81fdb161f4f1b419c5e4caa36d4bdca2325f0cd25b119a30178016f171bd6fb88403e4e3aec026c4089f180d540e", + "0x8ab1e36bd04625ee794ef04c4dcb8e004d61aceb2b62438377f49ad95dcf025ba25eb799280004941e555bf7172af6fe", + "0x9257b9e3d14d37fc7efae49b0c68d36eaac546035f4a2654d566b3ce1b2c4564cbb03dc8ec66efceb768559a8a507a18", + "0x945d1123b839637ab5154a1972c3c83a0ff34a3b1a3465de6ef0416b1950f649869a3ef88d7f1036648ee385265ce2df", + "0x81449639d708860fc0229c94f754f7262e8a3c7f67960ff12dfd15df95f57a9ffcee2013e81978b7703dd42bd5d0816f", + "0xa865481deaae5a690fd53892791e5fa729db283b75a525a11cdfee1ce17e8e7f0b449d25f20b3c1b43da128dbdf98a8b", + "0x98766812a65fcd25b853546e3bba618a3edc9fd61510e4f8ab60c038a7fa50d197abeec8776109df0f2119be9445ad00", + "0xb1b8dd5379d903dc41d74e999b1ab693607a0d2905692f4fb96adf08f738e5d31f9d00df28ccb8b5856145ca552c3e3c", + "0x99d20be7b511bec78a8ed03c207aa4aa9097ba39d85e18f1b8d52f65431ab7e9a773c7b9ac3e8d8b25458bc91bd00703", + "0xb1b7c3563fe8cb33c7d3e0b89d00bdd13e86452ff507c2e69db7b3af06f247f139155396e9b0278753310dc63940a10b", + "0xb3dc9c08451b1de7c9969b1e47574bffff50490f4a16c51e12390195d9e9c72f794790caf7b0a835d64e01fec995d3ac", + "0xaaaa4761a00022ede0809d7063d3532b7bfae90ff16f45e17a340ad4ebaa2fbac40728ccc5fbe36a67ab0e707566c5dc", + "0x8319a1903314eab01f5442d2aee6ae9c3f6edfda0d9a88b416d0f874d7d1d05d08bb482102f8ca70a4fa34836d0840c1", + "0x932949a6e9edfec344932a74d4f81eec3667ece1e8b8ca840ce07ffd4b5d6d8f01657c764d64ac1b9190f876b136490e", + "0x904db1568128487e312fe629dd8bb920cecafd3bb9cad8b63e269ae0129f2f5c80cd82f0d81e7feca9835c3945a72d28", + "0xa17280693d30dcd43c85de8f6b02d5f30cb9097274ad680cede1ef105c903615b4c40f3c6aaca478642de324972514e0", + "0x8d5f76e093aee71d0cdeb017fdfcb13bd068039746de90690ce150a0bfdbe7ddc4d539df0f82c2d2890a40b191900594", + "0x96fa1f2196a3883cdd73c66d28403cbbb58f6a939a3697ee0d308d8a076393cbb4be86255af986869230ee410c01bcfa", + "0xa8b74438dc5cabd70a91bf25601af915c4418d074327a9b01e0190c27d3922c89bb9b41e0b366e82e313edda8f21983d", + "0xac9fdc1a9b2e3ff379eb2370979372e13c4177bf4574f1490fadf05a7073e6d61e703e2d8eed9ce984aba317d411e219", + "0xa45a6c9b958169f2f8df70143e6ac3e2f6f969a4eed6fd9f1c620711bc2454739bb69f0094079464790c5429c0d8aedd", + "0x8901cbdd1009864386577842c1e3d37835fddf834064d9613b4559ea9aef3084204e1f863c4306f874141f4374f449ff", + "0xb6c582161691e3635536686825be9c4d7399d668a7675738417e0363e064dfd28acdbd8dbc9e34c1dab8a1990f1f0eba", + "0x89e89ddaf3cacc78428f3168549c161283ca8337345750667c98212717b21e7d994eae4e45bbddacc832a18df1d79276", + "0x84be275627eed8e1a73c7af8a20cee1ef5cc568cfeea7ec323d7f91b44e9653e9aeed47c1896a8240b99dde545f0e1fa", + "0xa779a54ab4f40228f6e2539595fb8d509b70aab7c19e1928c1be69ec1dc19285c3898cf15e5f8b8bc725e13af177fe17", + "0x92e2a49d2b9b36349d442283b17d46f8f9bf5932c34223015ce62d2f285e7363b2c12232be4a838b5b6cf08e694c094c", + "0x8b4e28c6f3f36caa2cfb82ba88066c830f8017bd35608b077143dff236f3181230166f5a5c02fa0e5272297331726aed", + "0x85fd77d46162ffac4b8adb25baff0eb0512a53a3d01638b3a376ea34702279ce21c8e7d8884308c03e00c9bcc1a9fd29", + "0xaad5e46916ff1be29009b595d1d8fa160cc7aa01c7fbf3a68f445c87615790dcab1fcdbdceda533d182b6541f09f2f73", + "0x948df7654726250dae393325addd3c0a20431c81f00470962190335ea4b6d9f7463d6f308cda46b92084c1f24390b1da", + "0x8f577474dea132676504376c5542b730b6604fe3d965eaa194659fd11c52233bd0b11ab62e198c0f442327ff1c00e501", + "0xae2f1001546db3e0c19700adad997cd9f765fe7a51a502cbcd9a2a07a3a5db79c8f603e05cf96d80b688cb6c9b6cd3ae", + "0x953b68e5d9561088dd20406ea7fb6894cba33868a38ace38fc30b5813140cb15dd6dd2171befae5b4df2e4a9658889d8", + "0x86c52901655ff11419b084a04da8fc3596eae59d81d3461601c0baff59ba59e3d1dd0b7ce719e741a3e97c013e898579", + "0xb9a72dd5eff73f9912a28b55de073568efb3eb0241a10b77a2bfd4f30c2aa4fbfe0c89eb345c9f07fb725660873cb515", + "0x8e7353f5f2932e4ffd95811caf46c9bd1a53643c27eb41a4ebd211f230955cd71a8b27e17cfe8aa708d8514c0de67a66", + "0xa096b8e66312a92fb10839ebe60189a8d1bd34dff55f7dfae85e4d2f53a1a4a88211c19fc84494f066358ddce82be131", + "0x931c5cd82719d76596832b007969b5f75d65cffabb41b9dac7910300db677c1309abe77eeb9837a68c760bb72013b73a", + "0x8ba10f5118d778085122065b55dd1918fddb650cce7854d15a8f0da747da44d7b12d44fc29ad7dc38f174be803db74c6", + "0x8c971deec679372a328587d91fd24ab91043e936ca709c333453d7afd43ee256d08c71cb89f0ab0e89ae119831df6d86", + "0xa2ac28a58034fbd8fd518f409221bad0efec52670880f202e09c0530e2aabc2171ed95e99891790596ffad163d86c110", + "0xb3354e3dfa8068aba4f3741152b9204baa4e342c1cc77e6dd1419cbaf8da1d118be605846b8609e997d6a62a11f3423a", + "0xa12ab65a213c9d95c24865fddc2dffe0cf9fc527dd6bcdacc1bd7271e79929a4ab3427a231f4f49d0530474e6cbc88f9", + "0x90afd65b7e6973f8aafbe74da0f42441840d3c93bd69bc1bec8fa56824e7ca97ad1b427c8a85da7d588469bd4ccc50c3", + "0xa09175940c59489bac3d3da3a4091270d9118948cbbdd57f2bcc63fbf45b8010651c801d3e58dccf42733ce1d6b446a3", + "0xa843bbf286e3cecc1fe370ff1bcf5f1001bc2e95b34246625ff50d48ee62343e82fba2d25b8a4bd5f7b5ffe90920efa2", + "0xa3c4d1003219157fdbee2707ce07afa6c2a64ae8e450182c307ed7f070024071f30b12c4b0032960ff913c74e73a9976", + "0xb24af3f68d66f825d06fc3ff94fcccebe28b1a0d4ba29c48d3a3c953b9bf7ae6707f193fef25e2dcbd2b74e483c774f0", + "0xb0f657f7723184ef7d7e4381143f1ac8020d8c6c6f2dcbebb0eaf9870d61a81f2d452596503311e46d1b38f625d4756b", + "0xb90091004fc8f6205c51bec68547ac82dba0f5525631e7632cf6efe54eecd9020729fbee6105d1b8012402d3b79c54aa", + "0x8e3fa187713c60eb0a416d6900a894cdf81e6b6b69dae0bb64f6287f3c3f030cfa85c665f7aace1eab4937f380b8f728", + "0x879bf0784ccf6725c9cd1ea8c49fde31c91c605de1ea664a33c2ce24c277ee45d20b66309f98d989acb2ff3b77e13101", + "0xaf3f3a3ddc4e11abd627d5aef8adffa91c25df5f0c68b4d2b5d51e7d9af3395ba4f6f7ae2325a6672847e1ecc6cad628", + "0x973e667289e796d3a40f072e6fea575a9b371a9997cf8961677f8dd934619ddc47c1a3efe91bae9ef95acb11a8fe6d09", + "0xafa81c5606de82f46b93f4bb6db3fc0670f4e0d1091388b138a66b3827322d95a56168c951c30831d59eeadc227500bd", + "0xb83eff77db5b4c18574662942eb36f6261c59f655f8a9c3d3731412d0f257c8e80aacc995c4b2303058a1ba32522a434", + "0x912e5ac9234b9445be8260393ff08e4859a7a385e800b74d1534eeb971f58f74cfb518dfdb89f8705d89fbf721439129", + "0xab27c8ece4a51d23e22c2e22efa43487c941139b37ea1182e96efb54ca4809d8245eae0ebe8ba94f0ed4457896fe11b1", + "0xa6630585d104a745bc79dba266d9292bbdad346449c8ee8140a5e6e8a6194411df9cdbf3d3ef83468a536d4f052e9335", + "0x8b8c128244da48e7fec641a882d0005a2d05c7138d86a293e6a0a97c76bf632b44767d0ce44663c975e7f9f9679e25e3", + "0x87dbcaca67351a4e7d2297d7cdba4796d12f58857e7ee4abd0645563577ff33544a44cd84e50b3a3b420d6998de9b57c", + "0xb859ba43df259d7f8e7fac70bfd7aae546d57a5dc90e107b174a95bf7fd3cf00f740c4434848e69b2a7e6061f66c1ef1", + "0x99d6e20978fefc40c6d310187eb2ad3a39296f189ee122ed64d74f81033c3069d44f7a9d3988a1df635b609603a17272", + "0x99a5ddf3420cc0c92b21f71a805245608d4995ead447d8f73a670d26d33e26920d5f07bfe1f6230bd5f15978055b4253", + "0xb936ac0944d3c5e4b494f48f158000abb37b80b5c763f77fe856398c664b0f1ddbcc0a9a2a672db9278f08b4bafbe2ec", + "0xb4af85fbf4040e35a686dd016adec037c99b47cc2e4dfccaf7870ee9e8c97bff30f3035992def2a9d4af323c0b3af8ae", + "0xa5ee32b8bd5f8fa9000da4da0bf00565659a43285393d37080b555d0166bde64d87317b2eab2d48a0e7b287caa989be2", + "0x894d4ad58ecb1c9ebc4f5a97407082e56cb7358d7a881ba7da72321c5027498454f2c7fa2bd5f67a4b11d38c7f14344a", + "0x965be9eeaa0d450dacc1b1cc2fbf0d5d4b0dd188f2c89aaa9260e7307a2a1eb22db6092fccb662269e9a1abfc547cabb", + "0x805893c424aec206260c1c2d2509d2cb9e67ee528bd5179a8417a667aa216a3f318ed118b50d28da18e36c01f0805e3f", + "0x972d7040d4963b35260ef0cc37cd01746f1a2a87cedc0dc7b0ee7e838c9e4573784ea743f563b5267eb3905d4fa961ba", + "0x8c7156991d4c2e561888feaecf501f721b4174e7d14109e9deeac5a9d748301c07e11fb2b04b09799f0d34ff42cb77d1", + "0x894722ac35af3d507e81d737d21e16c5ba04686f8f004aa75934aae5e17acd3e065b96e229eb011c2f34096f4c62048b", + "0x81237937c247c88e8e31e2c72412189fe59c1daf65c5513489d86cf29ee922c0bb08e5f7890f09f4ada7e5262083d266", + "0x8cf62cda2fe0d9a6b42aa2a1c483f4ad26378c7cc2c2d1510a76df7560b07dba8528b33aaacb15f7f20b9d4c7c9f61f6", + "0xaaf0921fb3e1920eee5d0acb59dcc268b42f4b435d60d25d30357edd7dd758d035919691bd15311d85489dfa2e5ee696", + "0x92cec07be2247ef42002ebcaf65ec855611b8e893a5675796f2225f55412201b0bf9f4761924d0c8377b9f131e09e39f", + "0x8e514a62ac1e91773d99588415426c97ad63e917c10d762fe06ace5277a5c3bf3730e4b9e5d116f8493b9ab8687b70e3", + "0x83932df2d923a5052468a3ea87f7b55c6a80ede3594046ee4fe233046570921822bc16555b92ba6aeabaef9b1dc0805a", + "0xa2b5bfb249de3472113fd3f35bfabf3c21d5609da62a27ea6aab5f309c9068d94bc58ba03efb4ec11be06306d59e60e8", + "0x8106cf3ebe6f0507be8c6e8d137987315fe3689ecb75bb27980f36ba5efac504baccea0e7603549b6d126beccc278804", + "0xa73ee70b6fe8c082443972102c453fc0e386852476cf22224fc0bfe554735c12f96037fbf10922795f4502c4f052b5f4", + "0x932b27e175440169958504f3ed6400e7d6dcd5e716c19dcd0f15c56c04503ed133d5a993e111c016f141e32d68b29886", + "0x96f7ce4595318e0b4a6b368f788ff82226aac676aed4ace343867f751de414453a9aaaabef6e6224ce5aedc3d5cf77c4", + "0xa950c1e3bc9a14484997013d44d876374b939af437ae7c821c131fb886063ee9fe7214a25a0c7084f0b07b99412eff75", + "0xa9dba3886ed6855303106a1bdd26010f294218684e1c178afcfea3f37a2f04fd01724a31d82de3449046617e3507a115", + "0x87a2f776b32a6b550cf3ceeaf78db02819be74968d228b1d14e0d74a1cdf994bb500b7abef6619455e98d728701fac5c", + "0x8cd887b07e335edc0b27e6a660cebb64d210741395be431d79d570139687b056557159407459799a8197b6079644f666", + "0xb81a61fce00588909c13a90c1caa150f15788786af443ff60ce654b57147601f7e70b95659e01f470334a220b547611b", + "0x8aebc51141544c5f3d3b99422250424b9800031a8fdfbf22c430907a3a446fecaa2392105d66d64b1c8e847240da4a6a", + "0x90db7dc12baa02f3f86d3edadf9434e2b9318d4f6f0eca08276b765dbb38d8eb0d08be2fe70adf2bf16ceda5db08d3ca", + "0xaa1839894152d548cc6ad963de20fb6fcc843bc9af2a2bf967c63626b8ad19e900894d6106265f38f3afccca317c22f0", + "0x848e27b741496988a582515c0c8847b2bfc6a001259396cdeea1e1b1d2828ca3a626693a1bf4adf3a3d7f8b1fa3d75fe", + "0xa0aa11754d4ee136ac3ca609b17bcae77758763b2016544ca7921dddedd8aafcc7ad5f2b337c8bf53084eb8e43ea41fb", + "0xb8713b7aa1c112178195fdcc9b7024f46e6bc04c4e76c41abe620aa265287809200d98eaed6c9703fa97e81d6964f0ec", + "0x8605b5b33309e9ea6823542b85383c496794b8481c577497aaf99ba90496e794dce405be615bf92c7b6361460e6b82e3", + "0x826fa34faa7f83e063a7bf172addfc07badabada59cfc6604fdf481d29085251c0a67a1355b2cbd374e2975934b84cb6", + "0xb45d131082dc16fa53af010d43eefb79200dc23d2f3ee26af95ac6a5cebc49c84a9ed293e534ed16ff3ef9a4a25456ec", + "0x91bd6ce3c5396a7a0de489e49f0cdf6dce1cd2d0be7a410326423c3185bd1125ce1e610768be7f15f4e44b62f8834fc3", + "0x903ffbe3d33fbf106c01c727dc3a385201a67ded70d4df623934882f69a3a96c909b027a124f3d70cb072b0046a149e8", + "0xb405359db9d9ef4821a181b440ef2918c240595141d861d19a85867a5afa74d2972d22c988775eab441e734700bae4a3", + "0x8abb756d027233c83751910a832b0ef4d28d100077f1c5d656720c94906f91d85dd0ea94b1cc0ed95b692efee14c786e", + "0xa78ee77ab476a41a3454160ba7ca4085d8b1f7057c63e76db8b07cf20afdeddd2250cd00771a6329133bb4ad48ccc20a", + "0xa41810271d8c37197aa9b3dfcefe3498e42f5978d3f3d59defff4676d6402d8575b40683834f184f143b6cfbfc859b3a", + "0x90c24a0750242660bcc6d487358a3cc015730538a0a8beb00ad5ac2ef33cb8ca8a62121e50bec8f3d2f43900f8e3134a", + "0x8b96c39695d864ef5796941754978a1fd612b369f6b77fe5ae6587beac936ee28190af8f0a3822b63060af35e49a5c8b", + "0xacde2548883d0e63c0fc257bb9dadd919aba60a985b69ebcfa1bca78acca42fc1322ec30bcc8e7c188818f858d04ad33", + "0x895c86ae9ff8d95f2707d4838a3bc8ddb05b2611f0476f014b9c150d0e8332bc73285037a747426f09ac8179ba4e19fc", + "0x821761fe406e18bd86fa9ca9db99d382cd3b5c70c456f471fa3706d57763d147706304c75d54f51ce8f3115aa26e59d9", + "0xa803a80e3e8f47dc3c59ea23eafdec017458eac648b360cd42cbd075e0dde6f6f450b48c7646fb1e178c04f82ae51a12", + "0x91f40e1b6f588bd592829ce937996452c40be0fd6c43793c607866701ac6a8c7227e0891d45c6e7b1599382b0a3fbdbb", + "0x9408246d996a634a58689337f2526dfb3ba9ffef1d3ff91c32aa8cbbed900861ef25d6477308b67d76491edfcc70d65e", + "0xa492325a427f3df1c9c690c5b553daa8ac41f62f5ae55f425539222bacf959e2f67afabbba1732e120d3e7a6dcdf7049", + "0x8fd0c3e15477cae228613a171b6e9ec29ddc63ef74854d99b638adeffe39f89f34346a42851e8445e855a9f2bbef0f57", + "0xb735ed01fafa051004dbaad5e8c9e2faca8f6049ef9b590f256ea4d75b04594af12764ad4e6031735eae36f83179db93", + "0xa7d35f43fca06c86b3425dcb68a87186834ba9740664fd657915771beca4cdc0fa2fc9b4c2e9d9bdad8ec33543ddfa59", + "0xa1156e71e2db1b17df5da28747c88e091bd687bfee59d89096437ab4dc9a543fe5c5272d5023d72adbaab397a6fc94d1", + "0xab06a58bd81b33a411bade8d8c5232d38fadc2e38507159edea6e2e104b8ebd65ca02b05335118f691d44197b847a4dd", + "0x848b67a10f1e6ff8f5c228f226ef2ffeb67fb8f50925fc94cbb588d61896d9dc79726959e649898fd3354fe3ff7b7ee3", + "0xaa933397361f32b388edcf832f0db172a38e756b34d5f7a4a050fa7325058006c22cede26ee27917e8f1b0f301792bd7", + "0x89e49e7f02cfaae4a4b9c4180c9f6559d76e3a45774955859d4147970b1470dac37bdc9aedca1c32a20b045049161590", + "0xadc1825d5ab94fc719f25d8c9773f4d518134ed88eb13ac33cb910b2be3523ef9ef88d9e4aea2418b806e20108317bf6", + "0x96c4b444c8a023da644f3a343ebeeed19a8392d2ce175992461451c318a54273b76c3574d8f2dceda2947ddd34d1a674", + "0x8aa7e97e87c8c5b29bbd51a6d30396a6be1fb82b716ef83800f2c36d5b85467ade7e0f59d2db82c310fa92a9265f0b03", + "0x9146c32d99f02c3a6f764dcd9b4807f1585f528ac69dc4f84e4380f6fda4f9d5057c375671d51e7aca2b2b4140e83da0", + "0xa10760a533d9bc57536bcaf65f080302086aa50225437efd64e176841544711828c23a15c49c0dd1f357d3f10722ab72", + "0xacb0811777e17f7ae7aaba5f6fce81b759c067a4908730916195a2505c7450d0e6e2194c2ef0f241090597d58e70de47", + "0xb24f161e9bcdbad56665e2490b5e4c7768390d4668cd69a04ed74739062dbe832636dd33cda89e9b0afa8c77e93fc641", + "0x96b4d01106b831868a88ef016500ef2fa42d0ce87a37ca8ca4194a92a22c113edfe04eb2ca037329f3c1acc635148f55", + "0xaebbb95fb4f7adcc8e7a217aeb73f9e037cbb873d08c1cd9d68c6c6834511adf1af8b44567fee84327599bdcb734dedb", + "0xa9bd8b17300532fb94d028659bcafbe7bbdf32f8945baf5db4cfaa1bac09e57c94cad0ba046b4514044b8fe81ea8596d", + "0xa5557cbda599857c512533e7cadcf27bf8444daa0602aa7499cafc1cf1cf21f9d16429915db7485f0e9a1b5046cf01c5", + "0x8810307c40bc661c478a9747ebf2a30e5a5ead942d1ac0418db36ba5db0709c476f7d19685cabe6959e33ec1f3bff914", + "0x8829b741f41f2c32e10b252d9338deb486dba2f23996a44cf1dd888ad967a589d51329be34d764139f372a1043f6c2e5", + "0xa6b4728d18857c5fa082fa67bfb3b1d801e76b251b1e211a19c87cea5fe7ce757f943c85071f7a03a718388cd5690e95", + "0x86da7f397e2533cd487f962ae58e87bea2cd50af70ef2df9ea0f29f70b5843cde664d30ec207ab84fc817f3851277e02", + "0x8085776ef4ac6d42ab85b9d9135ecc6380720efd274f966544eeedf4684028197de76ecab919fa5414302597e1962bca", + "0xb05a065c733033d223ba13d16baa7a97bd8c8b8b1f0e59a9bdd36ee17e9922d48eb39bd180c168b122088a77f0bf321a", + "0xa89343fe44a93023dcc7ef71bd3bcb6786f68e1885ad260edc56a52445d34757f476395ba7ad35437f89bc573c7618dc", + "0xa114a9cd6105b524f3969c69faa2e09afe21753a93361a296f9e0e3b4e3e63726ddf2e6bfd3ddc046043e50bd44e539e", + "0x8a5611fec539cf681c05636bb580f29acc06f628bb012649ffa41ea6c1521194a5643d5dd843f09b6eb2c3bdb4d41acd", + "0xade247c4011ec73ec90b72f35afa59a999e64ba5a7e664a4b30874fea53ba6a14a76a41b58a5f891a20d019e5f091bdb", + "0x905b5d96df388160ade1ffe210d0c6d1979081bc3de3b8d93ac0d677cc2fc2dc1ef6dcd49d3947055514292a3fa2932e", + "0xa9520796ca9fccd11b7524d866507f731f0f88976f0de04286e68d7cf6dbd192d0d269f0cd60fd3d34011a9fe9e144c2", + "0x989a1edf4d7dae811eb57a865c8e64297837ffeeaae6ee6ac3af0f1044f023f1ca552bf00f1642491f0f0f20e820632e", + "0x879c8e63713f4935ed6e020559e140ea3073ced79d3096c152c430141272117b4fd9a9fc3eef012e81262df02ea14bd7", + "0x95074738ac1540c0312274333acd1ecad9c5509fee883c4d9295fa8d8200f6e637c363de395f9fa612f05c0dc58fae88", + "0xa770e4fc595269eb806b113ab3187ea75c8f96b57bf9fcfaf535f3eedc1d4d7e6285a20990575de0ff09f62d06ed0692", + "0x81283e5dfb6423439ff513eca1cc316941d196df8da2d1069d2d0b63f5289e630af2fd4119bc0144c002d33313372dab", + "0xabd1b108e743887b78f698f2aba9d5492f87a22868d1351d705d93a1084fd45be67170c68a6e18b07f400d9a01cda8c2", + "0x8509c3f67b92908cea8144f4e2a71631a66a61ac3547601c788907e52e380e5fe8ae4110aed95d13c67d3bcdd5b55a61", + "0x8fa5a790ec5cce6d4114128c295390120869aac5490a82feebd3c37a167120df2e7fdfaf2a4050a7dfebf48fb093212f", + "0x944753e1ea7d8bc727d46a7702077dc01dc0c6574e8263a16579b57ee155ca5901f71bb347a01a9a922b329d3ff75135", + "0xb46bc1fd4590b7a6275e20036d247c5909fc549c78e95b64ae7ed96e3b05bb044840f19f7650ebfe7008ba09fa83c3c9", + "0xb1e47e4d88e59a06c465348c6cc4181d40f45b91e5e883966d370c26622c328415c6144aa2f61ddb88ec752482c550ca", + "0x8bd4f8e293e3f1815c7e67167618fb3b0ea76424bc0985908957cfcede36109378e41b4d89555b8c2541b4c447e00461", + "0xa70589a867b2bfb63d0106083d58475d506637148549ed35c83f14e5c8de996e1b1f3447ecc80cf5cd134ef4db9d2fb6", + "0x8048b80ba6131d07370162724127b0f7cb17fa7f71855e55e5a75bd0a9e4fd71b0d0ea2d16ec98858e458528df8d06b5", + "0x97326cb94bae7530f4ec3235770c5a7ba042759e789d91c31fedbd979e3c0e6a2c69e2af3c1979c6fe0094274dbd53ce", + "0xa18e9c1d3eabd62af4e31a4b8e08494f4167fd4598c95d0123f39c46c53f9e93f76615900246e81a286c782ac37c569f", + "0x80309c59d4522b15aba617cd3c6238663e8b1c7ad84456346082c8f281140fc0edf9caa19de411c7e7fb809ca4fa3f4d", + "0x8e450c0990e2f65923f252311623038899eeff7b5c2da85b3a224e0ef7132588b291b782d53c477ecb70f34501466178", + "0x87843f96f41484e254e754c681a65681b9ae5c96c292140368743df9e60f7e2ada58ca2bb95fa39abe064b2ebf21eeba", + "0x858e8d5bf2a1cf26d8af5036b28b831d450a446026f58a1734b696c18f1f41482796b91cab0e5b443dd2f0b9cffa52b4", + "0x99627dd6bad8c05c5904cd23aa667d664da846496dbbb8452705c4ec01e1480e9c7295504a5a8529e4a0c842306b038d", + "0xb64b33256c18b2c886a837a0c0730fdfe73befb0e2796207c4dc592c5a33cd51f8c2ef47c584dd5773abf9ce9c1b0082", + "0x944f6da2a1546f0bfc4d98c3e73c79e935e33d208b6be26b0b5f8df6d0e3b74a5bda649853b99281bd3a3ec799a7dd04", + "0xa266d165435784d4e884640155e35b2a911b3f89e1e715986de419b166a36a341ba724877d80583fa3da566f6a828971", + "0xadff2698409d0756e78c534032ee926560c13d578cb178d5073172d049ebbce32a92692f7e2033ec781b9b0d894ddce0", + "0xa91933f110756c699c28bf9e24fd405bf432002a28c4349e0ca995528e56a5a2d101b8d78afa90a178ff1a9bf2ba515c", + "0x8e77839c0eb4da2d01e4053912cd823eddffbdc6b9c42199fba707ca6ab49fc324288b57be959fbfb11d59085d49324a", + "0xaa124517c76692036c737e987f27c2660514e12a953e63ff4bcb269dd18fc44dae95e282de8444bed09639ef6577af88", + "0xb285deae99688f1bd80f338772472fa2b35e68887c7eb52c4ef30fc733812444c5cd110050275ad999d5a9b57f782911", + "0x8877b0fa85b44ef31f50bdb70b879fa6df5eb1940e2b304fd0c8f08abb65f3118fa3d97ff93919038c1e452fb1160334", + "0x8a89f3b50dcbca655024542ca7d93df17deff5c7d01c7da2bdb69e76b3e0b4490d85c800fb3debb4b0b4d20c9527f7ad", + "0xb7e5dbe36e985354ac2f4ab7730fea01b850af00767a6c4d8ee72e884d0fe539bb81f2e34638fcf5d07b7c8d605f4c06", + "0xa85a1d78f6d4f9d5d83ec0f2a426708342d4e4a5d15625554e8452f6a843d9aa4db0c7e68caebdaf767c5b3a6a6b2124", + "0xa518078a9dac63c5bf511b21ed8e50d1ccede27ebfe9d240937be813f5ee56aef93dc3bf7c08606be1e6172f13f352ce", + "0x91144eedebda4d1ad801654ef4ecd46683489b177ba1de7259f7dd8242c8c1700e15938e06c5d29aa69f4660564209a0", + "0xa16c4657bc29d1d3271f507847b5a4f6401cee4ad35583ad6b7a68e6c2b9b462d77b5dd359fd88ea91ce93bb99130173", + "0x85b855778f4b506880a2833b8468871c700440a87112fa6a83fd3ddb7e294b3a232d045dc37dfc7100b36f910d93c2ae", + "0x8d86bb149d31bfbf1fabcae1b8183d19087fd601c3826a72a95d2f9cedb8bb0203d1136a754aa2dd61f84b7f515acfa9", + "0xacfe7264eee24e14e9f95251cbcfdd7e7f7112955a1972058444df3c2d2a1070627baefada3574ebd39600f7f2ea7595", + "0x906bd14ecca20ac4ae44bff77cc94eb5a4ecc61eba130de9838e066e8766ed3b58705f32c650e1e222b3100691b3806b", + "0x8f2cbc7b8593c4be941dd01b80dc406fe9dfdf813ef87df911763f644f6309d659ea9e3830ff9155e21b195fc3c01c57", + "0xa68eb15ed78fae0060c6d20852db78f31bebb59d4ddc3c5bdd9a38dbe4efa99141b311473033ff8f8ea23af219bc8125", + "0xa95cb76c9d23fc478c7e8a73161f2ff409c1e28a2624c7d5e026e3cee9e488f22225a0c5907264545a73e83260e3a4ec", + "0xb76f90e55fa37c9e2732fd6eba890dd9f1958c1a3e990bd0ce26055e22fe422d6f0bcc57a8a9890585717f0479180905", + "0xb80cc95f365fabd9602ec370ca67aa4fb1219a46e44adf039d63c432e786835bb6b80756b38f80d0864ecb80e4acb453", + "0xb753c86c82d98a5b04e89de8d005f513f5ea5ea5cf281a561d881ed9ad9d9a4be5febb6438e0dba3d377a7509d839df0", + "0xa664733f3b902fac4d1a65ea0d479bb2b54a4f0e2140ed258570da2e5907746e2ac173ace9120d8de4a5e29657ae6e05", + "0x9479722da1a53446e2559bb0e70c4e5bf3f86c0ce478eede6f686db23be97fcd496f00a9e174ceb89ab27f80621f9b80", + "0xb707fd21b75a8d244d8d578f3302d1b32bb2d09f2bd5247dff638d8b8b678c87d4feab83fe275c5553720a059d403836", + "0x93214c16831c6e1d6e5a1266f09f435bbed5030c3c4c96794b38d4a70871782002e558d960778e4465b1ff296ffedad8", + "0x8648f84e18eb63dad624e5fa0e7a28af2ee6d47c28f191be0918c412bf24b5460c04bf2b7a127c472914a0741843f78b", + "0xb67f61e75d6b773a6b58b847d87084b94f3cdac3daa7bef75c2238903a84250355a986b158ff96ba276ca13a6035fdd6", + "0xae9b094b7b5359ee4239d0858d3755a51aba19fce8ad82b0936cca48017523319c3309409ea6e9883a41bece2077e4d8", + "0x8d1d8e1fba8cebd7a0e1effea785a35e16b1a10842f43e2b161d75add11eccf8f942d2ae91c20eef6c1a0c813731ea9a", + "0xb82bd387458e3603782d5e2dec32ae03890a3fc156d7138d953f98eff4200de27c224f626e3648e80cd3dfc684c4790f", + "0xa6dd02a89ad1c84e25e91176c26355e21a01b126c1df4d22546159dab9d502dbc69bc0d793a017c1456516e4aa5fa53f", + "0xa9ab74a5c5459b8500beb0ad13e9cfe2656e966dc9b4f3f98bec7588023b4ddebf74e4fc722d30423f639f4ee1b2587f", + "0xb03e5f33ab7ecec12cbc547038d3fa4f7ea0437e571891c39660c38d148212d191be29e04eb2dc001b674219b7a15a9c", + "0x925df4fc6e898ca55090ad1a8f756cc5014167a042affda5b24896eeb6aac408545134920586a8e1a2b997de9758b78a", + "0x98c8580fb56ed329fad9665bdf5b1676934ddfb701a339cc52c2c051e006f8202e1b2b0f5de01127c2cacf3b84deb384", + "0xafc3765d374c60fac209abd976fe2c6f03ce5cc5c392f664bb8fac01be6d5a6e6251ac5fb54cfcd73e3b2db6af587cbb", + "0x8e7e98fb5a0b5b50d1a64a411f216c6738baaca97e06d1eba1c561e5c52809b9dab1da9f378b5f7d56a01af077e4f8cf", + "0xb724bf90309651afb2c5babaa62dc6eac2b8a565701520fe0508cee937f4f7b6f483fc164b15d4be4e29414ce5d3c7d4", + "0x9665160e7bf73c94f956ecb8ba8c46fe43ae55c354ce36da40ccc7594beae21d48d9c34d1af15228c42d062a84353a0c", + "0x8600ab3aa86b408ee6e477c55572573ed8cfb23689bbdadf9fccb00161b921ec66427d9988763a7009b823fa79f8a187", + "0xb0d8d19fd1022e7bc628d456b9bd1a2584dce504eb0bf0802bdb1abd7a069abbeeccdb97ce688f3f84a229342dbc1c33", + "0x8f447d5e5a65bb4b717d6939cbd06485b1d9870fe43d12f2da93ca3bb636133a96e49f46d2658b6c59f0436d4eede857", + "0xb94e327d408d8553a54e263f6daa5f150f9067364ded7406dcb5c32db3c2dffd81d466ee65378db78d1c90bc20b08ab3", + "0xb58c02781b74ef6f57f9d0714a96161d6bfa04aa758473fb4d67cc02094cd0c0f29d0527c37679a62b98771420cf638b", + "0x8cfa0a687ea51561713e928271c43324b938aa11bb90f7ffaa0e4a779b3e98899f2af59364ce67b73a46a88748c76efa", + "0x95d6d39c814c5362df69116558d81ce6f1c65fb400fc62de037f670d85f23f392c1451d43341c59bc342bc31842c8582", + "0xaf888b384c52d9e04e4db6c4e507c2037eb5857e9bcc33acf84fc3a02d93cbde8cce32141fce9f5fec715b5f24d56356", + "0xa7822bbc3c236fd58bd978f0fc15fe0b60933a0c953db6436a233441219418090ae0c07c490a6548e319029771cdaba7", + "0x8c53729f750922e5eb461774be8851a3f40fe42eed170881cc8024d590bf0a161d861f5c967144d15cdcdc3dc6b5cf88", + "0xa052a25a4aeab0d5bb79bc92a6ae14b5ad07d1baca73f4f6684ccecfc7ea69bc21eadeb9510452fdba116c0502dd698f", + "0x923946b83d37f60555dbac99f141f5a232728c6eb819a37e568c8c6e4d9e97a4229fb75d1de7e9d81f3356f69e6d36f1", + "0x8cab82cf7e415b64a63bd272fe514d8b1fa03ba29852ec8ef04e9c73d02a2b0d12092a8937756fdec02d27c8080fb125", + "0xb1123314852495e8d2789260e7b3c6f3e38cb068a47bdf54ed05f963258d8bcabaa36ccbea095ba008e07a2678ec85a7", + "0xa685b779514961e2652155af805996ceb15fb45c7af89c5896f161cac18e07b78c9776047c95b196362c9ad5430bcb22", + "0xb734dd88f6cc6329c1cb0316c08ade03369a11dc33191086c6a177cf24540c7ceee8199b7afa86c344d78d513f828e81", + "0xb0bf492fb136ecdb602c37636ed4deef44560ab752c0af5080a79c9f76a1f954eba60a0bf6ba8bd7b8cac21848c29741", + "0xa5c74682323e85ac20f912ab9c1d6e1b9246c4c829dca40c8a7d58ec07ea0ad3524be30623f351269552f49b65a1245c", + "0x837403b9cf830fb33ecc11a7c8433e07745973c36acdeb3fc9ea8f7d8d690d462e1250b7410f79f2f4180fe8f3962a4f", + "0xb03d64b944d49c83608f2c5b9c14070c025f7568c4c33d4eeb1da31d07f0bc5897e498b35b50d557ee129f0c3c68e254", + "0x827272aab8bf757e2483156e00fbebe1093a58070dd3af9855bbf946c7abfb9c8a850a6a8acda8c620902f391f968b8f", + "0x84c4eb863a865282d321302d06b362f8bd11c2bb0090f90ebffedd3eb3e7af704cff00d39a6d48cbea4262942e95200b", + "0xb044eb91653dc55dce75c8d636308a5a0dae1298de4382d318e934140a21ca90e8a210e06fdf93aadbbeab1c2ef3904a", + "0xa8c08955a4378522e09a351ecb21b54025a90f2936b974068e80862803e7da2b5380c4b83b4b4aad0409df8d6c8cc0cb", + "0xa763a5fb32bd6cb7d7c6199041f429782deacac22b6a8467077fab68824dd69343ebca63a11004c637b9cb3129dbf493", + "0x8c44c8afa9a623f05c2e2aba12e381abdb6753bb494da81f238452f24c758c0a0d517982f3999d2537b7279d381625ed", + "0x8613f47fda577cd3bda7c99b80cf4b2dd40699edfd3df78acb5e456dd41fd0773bc8da6c5e8cbf726a519b9fb7646ccc", + "0xb21a30d49d7e1c52068482b837a4475568d0923d38e813cea429c1000b5f79b8905b08f6db237e2eccf7ef3e29848162", + "0xb9bdf4915f3fbb8d84cdfd0deedf2c9dc5b14f52bf299ef5dca2f816988e66322df078da2c54b934b69728fd3bef40b5", + "0x993b45f389f55eba8e5ba1042d9a87242c383a066cbf19bc871b090abe04de9ff6c1438cb091875d21b8c10fac51db58", + "0xa85a95d14633d52d499727f3939979a498c154fd7ebb444b08f637b32c1caf5cca5e933a2f5d94f26851ae162707b77d", + "0xb9874c7c4be1c88a9646e0c2f467cd76bc21765b5ab85d551305f5ec0b4419e39d90703d4ac1bb01feb3b160517e97b7", + "0xad6771177fc78812904c90594712956357de1533a07fec3082ba707f19c5866596d624efc3e11773b3100547d8f6c202", + "0xa79f31921134f7197f79c43a4b5d5b86736a8d3ad5af1bdf4ad8789c2bfe1c905199c5e9f21e9f446247224f82b334f8", + "0xa7f1b6c45321222a350a86543162c6e4e3d2a7c2dce41aeb94c42c02418f0892dbd70c31700245d78c4d125163b2cd5e", + "0x92abafe3ec9dbe55c193fb69042500067eb8f776e9bf0f1cb5ab8eb12e3d34986d1204136856fb115c12784c3b8dea6e", + "0x89bc761238a4d989006ca5af5303c910c584fe7e6f22aa9f65f0718a1bc171e452c43695e9f5a591725e870770c0eceb", + "0xaa0e44c2b006a27d35e8087779411ba2f9f1966a0f5646ff6871bcf63a8b1a4a7638751b94c9b9798ccd491c940bc53f", + "0x8736fe82862b8106e7fdab7b5a964d87ec291a74b8eb1cb5a6c046a648c1b686064ef3d52297043b8940bfe870c712f8", + "0x956a3def1942f05144d8e9c3a82fd2d3610064b53b9eefde3d5594a8f705bf8f6849eb2c22181796beffeba43cc74ee4", + "0xaf27416d00cf97d5a1f4a1b6b51c010884cceca294f1151c3b684a3f83c3c8a3c30771df1166d833cbddf6c873c400c3", + "0xaac3b8dca2336fc4ffc63c362df461289e4bbd3418c621bde6c581d3ecedf66e2b3e523d4db39e3d8ba014577bf85efd", + "0x94c3a8167f62074e5b28c2bffe4b6ce645439a9a0c5da3ca1b3ee956590a465d6f84a8a4dbbe9070ffbd6bbc734e4d62", + "0x95e23ba6986d25ed4451215da05bd72c5491528271726d79a94c8cb16aef1c85b190d6c5b8a3a1191c7cafbab1dccf0c", + "0x953e3dadb5ad68f7de31ac09692948655d174fe16d88b96930ef35b331da7f1dbc4c17863cd07b4ec3135b5205891a27", + "0x915d018f18b5d63cb3301c2bb5c6e85e75a88ba80663c964d06575b6bacbbe59139d030b218ce0998271d5b28c00b26d", + "0x8c871ba3dd138a908b2f7effeea0e71df096b23e0dd47cab10b9762b250abfd1221da94a8ee884e05bdf02271fb85a04", + "0x96bad5c6ebc3080ecbe337409ae398bbeada651221c42a43ea3b7c08c21841ddbcfde544c9b8d4772de6f2ce92c0b963", + "0xb5dbcd0b1c44c62108841558ec0a48df4b327a741e208c38b1c052321eda6e6ad01af71d49dfcdd445ab6fa6f0c34e6d", + "0x97dba59219b69e8aef2659d1f10bbea98d74aefff1f6451de3f41be39acbac0122b8ff58b02e90554469e88911ec3547", + "0xb7e5682ec306478be4858296f5d03364a61f3260636a4242f984d351a02e8723378496beb30c4ca22def9c9ca193ea70", + "0x9656a7a3df4d11df3d8bc35930dff70a5e78a488ca57bba20bb06814fc390fc6c7cb3f39b22134992aad196cced577de", + "0x8b269695aa63eb56d0324ba984279dc4c88e565321f1d61d553622bd4f1910d5eff68393d3a830eb924472bd478c2aa3", + "0x9177bcd04b28c87bc0440268b4c8995c6790cad6039594971b2c177f0e197055231e776927d3fa30d98fb897a2ba401f", + "0xae0e943973482001c4f214b9da82e1c27e38aa254d0555e016095c537c835d3702bc2de5c67b234ab151e02b3b7a43a6", + "0x82fc719a7d38bf4787fe1888019ad89fbf29beb951d2fece8686d2beb9119d0c8c6d13bc598748c72c70d73d488140ca", + "0xb716dc66f87eb16b95df8066877353962d91bf98cf7346a7f27056c2a4956fb65e55cb512af278783887ab269e91cd76", + "0x81d58cd8bc6657362d724b966321cd29a1b5cdc4601a49fa06e07e1ad13b05e9f387ca4f053ed42396c508cd065c5219", + "0xb32ad0280df6651c27bb6ddbdc61d5eb8246722140a2e29c02b8b52127de57a970e1ded5c2a67f9491ae9667349f4c46", + "0xb68a2eb64cc43f423be8985b1a068e3814b0d6217837fb8fbfd9c786db9cca91885c86899c50a1242040b53bf304ced9", + "0x85887515d4e371eabb81194cbc070e0c422179e01dbda050b359bd5870449c7950e6b3947b7a4a0eb68199341cc89fc3", + "0xac5fff3c27dfbab78eb8aad37ac31cc747a82401ebf3644a4f4f5aa98d37b8bf3b3f4bd8a3428b32a127c25c9e19d239", + "0x86fceaa6fbf8913553a9e1e907fcb1f1986d5e401a7eafd353beefd1899d571454fea96ff5b2a21254d9fb693ec94951", + "0xb6778bb296d3f0de2531b67d36fdbfa21475be0ca48b9dfcc38f396c41b557823735ed0b583e525a2bae1fe06e04058c", + "0x898088babeb5b9866537d6489f7514524c118704abd66b54210dc40a1c1ddb0a1edf7fe0b6e0db53b836f1828ecf939e", + "0xb27854364b97274765f0fb8d1f80d3660d469785d1b68da05e2bd1e4b8cbbe04304804d4c8aabb44cf030eba6c496510", + "0x8c55bbf3603dc11cb78b6395ccbc01e08afcef13611f7c52956b7a65ccf9c70551bff3ae274367200be9fc2d5cb26506", + "0x947726f73cd6281cd448d94f21d3b91b96de7ad3ff039f9153befbb5f172db9f53cacb4f88c80a3db26e6a0f7a846eb0", + "0xa7b733a05e97528812d71cecb4f638a90d51acf6b8fcbc054787d6deb7e2595b7b8d1cbe1aa09d78375b5e684a2019bc", + "0x8d5ca6d161341461544c533314fe0a6655cde032c2d96f0e4ea7e41098b8b39fa075d38e2d8c74e2d0308f250d6cf353", + "0xb960e9f081393e2260b41f988935285586a26657a3d00b0692ea85420373b9f279b2f1bb2da2caae72dd2e314045f1bd", + "0x852a49c7388c10821b387c6d51617add97ba72485f52be95d347bac44c638c92e9c6a44ba0d32afc4d59178a497d944a", + "0x8412162a65147e1334ad5af512982b2b48eef565682b3f3e0bbe93fbc5e1103db9375a0c486bdb1b2c57e4cb3a8e7851", + "0x8f52c3eb5d4f1e1e82cfd2b291d4910195427603b796f6c311deb35ef14a01a57a9e6cad39619ad108f3e86f384f9e1c", + "0x88d221088f2bf0103c53e44d0d96cd7881ec2b0a965db9121a47481771a8b796edd5ac23c4f9c208a171dab301f7d3bb", + "0xb49c3235e8b3617ed08a1891b9e2bcb33dbdacceb94ca96330555b7e00904fe6a749ced9312b8634f88bcb4e76f91cb1", + "0xa85834215e32f284d6dfb0cbfd97f6cffc7b9d354e8f8126d54598bb42d7f858a2b914cf84fa664069632db2ff89a332", + "0xaa3d48eb483c6120c27d9b3e3d0178c1c942632ff54b69f5b3cfbc6ad4ff5b2b9ce6eb771fd1eea8edf4a74c97027265", + "0xa446cfded353cdd9487783b45846402b973cdeddf87e2bf10cf4661610fff35743cc25e8d3b5771dcedfb46b018a5d18", + "0x80998377b3b393ef3073f1a655ad9d1e34980750e9a5cfb95f53a221b053ddb4d6985747217e9c920735b0c851d7551f", + "0xa35ac469790fac6b8b07b486f36d0c02421a5f74ea2f0a20ffc5da8b622ac45dfccabfb737efa6e1689b4bd908234536", + "0x8fb1f6d8e9c463b16ac1d0f36e04544320d5a482dd6ffaec90ea0f02b4611aaca984828bf67f84dcc3506b69af0a00a1", + "0xb6e818d61aea62c5ed39c0a22ccbb327178feebdabda0c9927aa1549d2c5bb0637785c4aed2a6d9a7b4989fa8634c64a", + "0xb4e7208d16018bf67caafe996d436113eac619732e3f529a6efb7e6f094d8ebea55b7be0e122be075770f5957b6ea6f0", + "0xb691d38b552befac61f6d367287c38d01fec73b7f2efdb6713ca30314a37fb7c177eb111fe6bee657f2681014e07630a", + "0x9817587e418e6e7e8e97ae27067f17b55d25dfb14e98f63f530620c855d9a348c9fa571c8508e2741f902f8b9fdc0c5c", + "0xb6a6e5ca779ba140bf1d84cd5394ede8262f7479637ec0087a4b152243a1774ba916d8115ce759a3bebd1b409de5f2fc", + "0xb53d1c84ad766ff794bf497db3228efd2cc8ed5fc1958d89c1126efdff361610ecb45ea8e329b39035ab00a66c1259c7", + "0xadc31333c507c8e0f4aa2934fcdca57fd9c786722a50dbd5404e129541f7ac182cc7373bf14e1e4e06e6cf94b31b90eb", + "0xa82b7fde4642d982d95cec669efee140ad797a2442c7f6620580527d163accbf021b893446cbb8038ea82fe25b15d029", + "0x91f7acf8a8903979afa281646fdecb54aa4d2ed905748e156e92f0910de268fa29d67107d40863935d677d1de8039be2", + "0x86fea71c6d43a7d93216a92fc24dfce8521fd4534a9558b33762d002081247867a6eff54cad7116023277fb4049403ad", + "0x8ae5369a7f9f4c91f3be44b98089efd9c97c08f5bb4cd8b3150c115ecd86288fa0865a046a489c782973a111eb93966e", + "0xb6fb9e829aa2c81c2d9eac72bb2fd7f3a08e0cd763532c2ce3287444d33cf48b3621f205e9603ec58525934b61a795a9", + "0x83e35ca808d84e41fc92115e9f6e283e928c3a614e6dfc48fe78c33b6411262e7bfa731eadb1e1937bc03cff60032e1d", + "0x832fca5196c95098ad47b7d24ba2f9d042e1c73ad2273edd1c2ce36386796ccc26e8567847697f3fcc2a0536a2a2087a", + "0x8fdb7038bc8f462ab2b76bf7053362f9c030019f1b6105cf42219a4e620ecc961e3eacb16a8e581a562a97f1418b0128", + "0x8d3a5a404b51b1ad8ce3b23970e0d5cc57b573922341008e3a952a1dd24a135e19e55b79d86a70cfd82e1c0e9630f874", + "0xba00c025c1c21c57c03cdfc0bfd094b35422281ff0a64b68b240617aa58c6b18800af5f2047d3ff9068bbe987d6c7980", + "0xb468f0dd51964b3806b0aa04f3fe28a035e8f5567fc7d27555be33d02701a838b8dbfe1348b6422c4eac46d2c75c40c7", + "0x8a73a18c97da9958903c38584b08d0e7e26993a5d9b068a5e0e1ee0d8a873942745cf795f94f7a3d3ba88790a9fbb2f6", + "0x953a0a40c2c8102723736854d13b228698c14a02d85c8d2e61db1a768019ac305faf0d5db62ac976430ce087a5b20f1e", + "0x8998219da6b34f657cb8a621c890a52cb98c2bc0f26f26e2af666eebeadadc5e8bdf4f830a91d04aca8ce186190152c8", + "0x8941e08c3155ad432236ed05460420a05dd0aaab30477493ffb364b14c00ea5b9183d30d3442b6321d2d20c36e4f5c7e", + "0x93f293ff7fb56cf5b03aee6f3ad2ad78444398ed5b3be56d7bf5b56b5aa5a2b980d13895dd57a5726d1b067c20cc55e2", + "0x84a16f313e3f75e31824f58d19ab24c6611fb4c75140a7cadc3c166f68819547c1d0ff7f7d13f5d8ae30dff1d80e2aa4", + "0xb6e3e830b15039d3e28b08f5465bb089eade11ee3bd80afe39e010df7db1fcf0c56d698717677a41ddbc91eeaf6544d3", + "0x95e928e6dfff51351281568ae72da7d1edeb6e9fe01f30af0499e7505ba35a22b5bb919d41bb809a432dce83f3977663", + "0xaabeeb60ca46f9b0232ff82ea7766dcab8cc5aaf9d23539f30174f9486640bc9312868ca493b59b314519fc399973e47", + "0xb393a11e957d0bbb3ecf617b075b5906a3450b348e62916c04791b366f0a7397cccd6648440ac544bc30526e1f95aad8", + "0xabb5bfc3964a6d246da60bd809d0ea6daf4f8222efdc12ceb6730194e85f413ee7eb03bae300abf7ea900dbbc3d08971", + "0x96c1bd1d1d216a4bfbcf000c123f296c0d31e1684e9e3884c14df23bf528c8d599f82bb98fcea491716b617216a8e0be", + "0x92d1e570a56f1741fd9f3d9f488cc336421c6256c14a08d340a63720be49b0029e3780e3e193a2e22bf66cc652fa22a3", + "0x8769c08551e3a730e46f8e5d0db9cf38e565a001dfb50db3c30fa7fa0e98b19438edc23c6e03c8c144581b720d7b33a4", + "0xb850bd67fdf5d77d9288680b2f6b3bc0f210580447fb6c404eb01139a43fccb7ed20051999ae2323ea5a58de9676bfb4", + "0x80285da7a0aaf72c4528a137182d89a4db22a446e6c4a488cf3411937f4e83f7b00ec7549b0b4417682e283f91225dfe", + "0x80520368a80b97d80feb09dbc6908096c40ff7120f415702c1614d7112b0b57f6729581c71f4a3ce794ac959a46494ff", + "0x9817b4c27a490b1cd5a6337e7bc7e8005fa075dd980c6bf075ddfa46cd51cc307ad1d9f24e613b762a20fc6c877eab41", + "0xad66bda1a3034ec5e420b78107896ecf36126ce3ef9705163db259072dfa438c6107717a33572272062b9f60cb89557c", + "0x876114ef078c2915288e29c9abe6b0ad6a756b5ee2930ba1b8a17257f3f0557602d1225e8aa41ce8606af71ada2a971b", + "0xaa3d6cde4c3b9d3d5d0c77a33e67f182a3e1cf89b0921423b2024236171955b34afc52b1f25b1dad9da9b001371771d7", + "0x984d3e3a72412d290e3459339757af7520d1739c7af0cbcf659c71999328db44f407d92e8a69fea11625612c49eac927", + "0xae890d0faf5bd3280dcad20a5f90e23a206661be8842375fea2ab22aadc500849ffbc52fe743b376d46bb926cedae6a6", + "0xb1f231f3f4d710c3fe80099faeb56dac67c1baf53b8fe67a9920fe4f90e52cb9a4bf19211249a6456613b28efe337f18", + "0x8caa54b418ba609d16520af3dff2e96d5f2eeb162c065a1763beb926547b2cfb3ae41d738db2c5681a9bc8bc9e6b9a1a", + "0x932157ff56c5ac29cf6cf44f450c882b3acfbb9f43d12d118da3d6256bde4e6eb3183aea304ab6967f37baa718ffec99", + "0x9360bed8fc5b6aac36aa69473040689bfc30411d20ffb7275ef39b9ff5789f9055d149383ce9f0f7709a1f9d683adbfe", + "0x98b5b33209068335da72782179d0c7aeeabe94b5560a19d72088fe8323e56db7ce65debe37a97536b6b8a0ca3b840b61", + "0x89a385c11be40064160b030a1bb28c3921fc8078522618a238c7ea0f86f34717ed9af9b4e2e20f5128e5f7fc66ad841e", + "0xb615703cbc64b4192990cc7e4903b74aed6a0076ce113b59ef7719197ffa46fb29eb78ca56b49873487432d0625c0faa", + "0x90f0d77abae9d3ad73a218e5ccec505ad108ea098451461567ae8ef9661606ca8e78df53b5d628b20b7037bd24622330", + "0x92e0e7cc4dfadc5fa0ee6da0c8de0493030db6e54ba0317f52f232a6708b732068b6077bd13a17eb7eb40b88368085b5", + "0xa24dad20094985bfccc6df1343506ed3bf9dcbdf4b2085a87627a5d71f7568db067304e465f8f380c5c88e8a27291a01", + "0x8629a45a10619354c84bdc2f6c42f540eab5a46f53f2ae11970433d7a2aef007897590bf31dfba1c921614c6d6fe1687", + "0x84ac64040d4206f82b08c771f375da4b7d752e41d2aa0da20ce845f6bc1b880a855d3ee966bca19b8ec327b4b43e7f0e", + "0x9608e6050c25996c052509f43f24a85cdf184135f46eaac520a9a6e78e0d44a6cee50ebc054048c708aefde8cd6651c2", + "0xa32032b0e0d7cc35e480c328f315327f9385adb102a708c9ba637878deb74582ae26bb6d6e5f8c9e3a839b0e0154b82a", + "0xb7e3c78d63acc6564a49e9f00b0a820b56d4f37a2374af1f7f1d016268011df9e7af0670ed2b0eee961f15aa948328dd", + "0x8b88bfdd353acc91ad0d308a43e5fb40da22c228f2fe093c6d6904d70f69c6203f56636ed898b05df51d33f1095ef609", + "0xb1d7a430c51fc857af55047683fc18c453b013527196c5e1bf776819a3dffca802217e9249ae03f084e2ea03ad67fcc2", + "0x80558e28a819ddb5e72e97c54be0f57c173ccf78038d360d190b7f1350a19577b8e3f43fa2f7bf113a228cd3b965b2e4", + "0xb4b2ec44e746c00dfc5661ba2514930934fc805cdc29adc531c02d28ce3cc754414b0485d4ee593232cd1175f357ad66", + "0xb57cee5d32835f76572330f61ccd25a203f0e4a7e5053d32965db283aad92f287645533e8e615137208383ec51b1fd99", + "0x930256086b419a8a6581c52590d0dbd9f8a3564c79424198fca3866b786df2f6098a18c50dc4abd20853a7184b1ce15d", + "0x8e75fd01181cffcd618a983492390f486e8c889972a46c1f34a4e1b38f384e8e4efc7e3c18533aa2057da9f9623e2238", + "0xb375d927dd988429f9e2764e5943916131092c394fce13b311baa10f34b023dd3571da02553176091a0738cc23771b9a", + "0xb9e28e4c0d0477518034d000e32464852e6951c8db6f64ccdb1d2566f5094716213fbf2fc0e29ac88d0e79f725e3c926", + "0x963981e99392afbd2b8318d5a6b2b0cc69c7f2f2f13f4b38dddbfedb2b0eaf0584aecfcbda20a4c60789c15d77970a58", + "0xa7804e1977aa77c263c7c001afa6cf568032dea940e350d6a58ce4614f1a91c13ae1c78bfea740c229dce2444556976a", + "0x8787204177da3cde6d35cd3497fa8774d244f9faa9f4bd91b636a613a32ce2ea0326378cf9c4cf475e73ef751b355c4b", + "0x895aeef46a07152a04ec812f1aa1fd431389fa0ef6c6e96a5b833e70ea14073bc9984757a8ee456dbec9788e74e6f0ca", + "0x8d17f0e5826783440d1f0ec868003510a4d9952bfe4a638e44a36d94482ac18ba70ef7ff773bdf7a3b62d714dcf0fcba", + "0x810d5e36b31310b2e054a666d3b3f7ed16dfcb1765532d87ca2a3920316f0187303c27dd113db145d47e8961062a6c03", + "0xb4e2fb48ae04cf8580bb6a28095076c9b95e5f13122b917328f334d4ac8a8648ce442919e28319a40148987350ab5303", + "0xb85549a313544fa1eb3ceb78473b7d3d717fc85b808de7b79db7dbd0af838ebb020622a7503f1cbacab688dddb648f84", + "0x80665adee057088eae827a5fe904ec3ad77d8843cdce0322d535e0659b4abc74a4d7ddd8a94c27f2def5c34ac2c038ee", + "0xad72fc19c2ce99b5b717e35528fe7d3ac8add340b02ebeb4889d9a94c32f312a0b45ea84d21c54f84cc40ee4958b72e1", + "0x99d530c843dff89a47a5ee8c87303ab18f8a82b0d5b808fca050354b35da5c5a5594d55921c6362d6cc917d75bdc18dc", + "0x99c7286c293e1be21c5b2a669dfdfcd5aa587105d2886fc5a8eaf8984da4e907f7d7b8c2362d64a4f1621b077a2a08a0", + "0xb4a39e1a9ed5d80c9563c3ca3fadf76f5478c63a98f4346a61b930c9c733e002f3ff02bc16abfdb53d776184cc3f87ba", + "0x9378ea71b941979404c92d01fb70b33fa68d085bf15d60eb1c9fc2b5fcdee6379f5583389a3660a756a50019a2f19a69", + "0xb68e17344a2bc45b8e2e19466b86dc139afefbf9bad2e2e28276a725099ebac7f5763f3cb52002261e3abe45ef51eb1a", + "0x819e64dc412b2d194d693b9b3157c1070a226af35c629837df145ea12ad52fa8eabd65b025a63c1fb0726207a58cdde8", + "0xa5e8ff8748419466ff6df5d389125f3d46aedacf44eaf12cbfe2f68d218c7d5ab6de4a8279d13aecc25f3b1d98230894", + "0x91560d54a9715cfda9cf7133ae51c432d0bf7fcbaeb468004994e6838bfc5ddcfa30e4e780667d0c4c0376780b083017", + "0xae8adb3309cc89d79a55ff74f129bb311fe4f5351a8b87600a87e0c3ba60825f71fccf67eadcf7e4b243c619417540fd", + "0x8d92cc1a6baa7bfa96fbce9940e7187b3d142f1888bdcb09bb5c8abf63355e9fb942ac4b4819d9be0e0e822d3e8e2e08", + "0xa6e8b79fdd90c34735bb8fbef02165ccbe55ea726dc203b15e7a015bf311c9cac56efd84d221cc55eaa710ee749dbdfe", + "0xa409b151de37bddf39ce5f8aa3def60ee91d6f03ddd533fce9bf7bdbeac618cc982c4f1ffbf6e302b8353d8f28f8c479", + "0xb9693975ef82171b3b9fc318ca296e4fe6110b26cbdfd653418f7754563fa7b6e22d64f8025ee4243483fa321572bfe4", + "0xa039ebe0d9ee4a03ade08e2104ffd7169975b224061924cca2aae71464d250851e9f5f6f6cb288b5bf15df9e252712a6", + "0xb27834db422395bd330e53736a001341ce02c9b148c277dabac67dc422741bfa983c28d47c27e8214cd861f2bad8c6f6", + "0xa2bafaf4e2daf629fd27d7d5ac09fb5efc930ff2ae610f37519808683aa583fe1c6f37207daf73de1d8a164f79a0c981", + "0xb856cee1cfcf5e50db9af4ab0aed3db2f43c936eaea369b5bba65582f61f383c285efbda97b1c068c5d230cbe94f7722", + "0xa61ab205554c0550fa267e46a3d454cd1b0a631646b3df140623ff1bfffaa118e9abe6b62814968cc2a506e9c03ea9a0", + "0x8c78edcd106377b9cbdfa2abd5278724aed0d9e4ae5869b5d2b568fdabb7804c953bae96294fcc70ef3cd52ba2cbe4ed", + "0x8570869a9bbf6cc84966545a36586a60be4d694839f367b73dfc40b5f623fc4e246b39b9a3090694aa2e17e652d07fd1", + "0xa905b82c4da8d866a894da72315a95dc98faa3c7b3d809aef18f3b2be4801e736a1b79a406179e8cac8f74d27e71ac52", + "0xa8eb8679ff1a64908515f6720ff69434cb33d63aeb22d565fde506618908b1d37585e3bd4d044fd0838b55787af06b42", + "0xaf4d86b2fbd1684a657dffe4210321a71e6ae560c144d44668d1f324dc9630e98348c3d444622a689327c1a59cc169dd", + "0x80359c6eab16954559ab0e6a1fee9a0526c45d3cae1a371159a2e3aa9b893afdc3a785c9559a5fd9cd8cd774234bf819", + "0x8d4e5ff81eb5d17bbe8ae6416538ca51a9427ce142b311f5cbb14febbbbb9c1ffc6489fd625b9266264c366c12a9d997", + "0x92e181c66489c5fa063ba2a1a354b6fd3439b8b4365a8c90e42e169bfaa1fb5766bf3e0fe804399d18bc8fbcafb5c3b1", + "0xa9ddf229360a095393885083716cb69c819b2d7cfb100e459c2e6beb999ff04446d1e4a0534832ae3b178cbe29f4f1d3", + "0x8e085ef7d919302a1cc797857b75cff194bdbc1c5216434fa808c3dea0cf666f39d9b00f6d12b409693d7a9bd50a912c", + "0x916dc4dc89e5e6acf69e4485a09fc66968f9b292eac61a146df1b750aa3da2425a0743d492179f90a543a0d4cd72c980", + "0xb9cbf17e32c43d7863150d4811b974882da338cf0ed1313765b431b89457021dd1e421eeaa52840ef00551bb630962dc", + "0xa6fb875786daec1a91484481787093d8d691dd07e15c9c0c6ae0404bf9dc26083ed15d03c6d3fe03e29f28e20da21269", + "0xa870fcb54b9a029e8086de9b08da8782c64ad2cc2e7fdf955b913d294038bb8136193256b85267e75a4ca205808a76b4", + "0x99883f057e09b88bf0e316f9814c091837fd5c26eeb16fec108c9fed4b7a2bd1c783dac0e4242b5a906621ab606c1e50", + "0x85d89069ca3190577dab39bbec43c16bf6dbca439ad3eebd8f5e9f507d84c3c43e77fd6323224582566a3aa2c8018951", + "0x9363ba219e0003f6e8a9d8937b9e1449e4b2c5cd57194563b758bea39deab88778e8f8e4f7816970a617fb077e1e1d42", + "0x820622f25553c035326145c1d2d537dc9cfd064c2f5bdf6d4ec97814de5fe9a0fbd443345fa2ea0a9d40d81d3936aa56", + "0x87e31110aaf447e70c3316459250e4f7f8c24420c97828f9eb33b22107542c5535bdb48b0e58682dd842edea2886ff08", + "0x95bf80cac6f42029d843d1246588acb40a74802f9e94b2bf69b1833936767e701ef7b0e099e22ab9f20f8c0c4a794b6c", + "0xa46ecf612b2763d099b27fb814bd8fdbaee51d6b9ac277ad6f28350b843ce91d701371adfaaf4509400dc11628089b58", + "0x8604decf299fb17e073969708be5befeb1090ab688ad9f3f97a0847a40ea9a11bbcfc7a91e8dc27bc67a155123f3bd02", + "0x8eb765c8dc509061825f3688cb2d78b6fef90cf44db33783d256f09be284bc7282205279725b78882688a514247c4976", + "0xb5c30b2244fa109d66b3a5270b178960fdec47d31e63db0b374b80d2b626409eb76d2e8d1ebf47ef96c166743032fc5e", + "0xaab01e76290a7e936989530221646160bf8f64e61e79282e980c8c5dcaaa805ff096efd01d075a2c75917a3f4bf15041", + "0xb9d79671debd0b83d0c7c7c3e64c0fb1274300564b262771f839b49218501e7f38ef80cae1f7e5a3c34acdc74c89dab6", + "0x92c0eaceadf036b3b9dfd2712013aba3dd7c30b7760f501f52141618265baa31840fe77850a7014dc528f71f8cf39ce6", + "0xb3cdd098059980455dd5b1c04182df1bd12fa844a866f02a9f8a86aab95b59945baa9af99f687410bffc5b07153cb23c", + "0xb361b73a62f71256b7f6ea8e0f6615e14fc5a06ee98b928ab3c9dd3eef9d9d30070e9855c82b7facb639cacb3401e01f", + "0xb9c85fc0f25a3271cf28b1ca900078eaaa66cbab0a3e677606e898ac32781a2dfce4d9cbd07404599e2c3c02fa161c9d", + "0xac5b4fdac2a0b2e6430d9fc72bde4249d72183b197fc7347bb1546ae6f544426686bbe0caec3ee973b6836da5e831c44", + "0xb675aebf24b92e398e166f171a6df442b3f5919b6bee192f31675a5e8eeb77d34c6590a6f0c0857417e0f78cfb085db8", + "0xa9bef942044d8d62e6a40169f7dc7b49e40cd0d77f8678dd7c7bae6f46c46786f9b1e319a3fa408f22a54fd2a4d70804", + "0xa20d19cd917d5102ae9ca0cf532127d2b953aa3303310e8a8c4b3da025dded993a47e3a28e6b02acfadb6d65dc2d41a3", + "0xa47fdb04059b83b2afb86a47b2368bbd7247c337a36d3333b6e5ef2cc9476a92c4907e4c58a845c9ef9b497621e0b714", + "0x94a9e9ffc14b411e11a4ffa59878d59460263589003dc7b6915247c549f67feede279bf3645fdd92379022fb21e3caeb", + "0xb92e1177dd9ecdaf1370c71b14954219cf0851f309bc216d5907a4e2e84e0df3457018224150c142cc6bf86644bb4b73", + "0x8bc57fadd68a265b7df9b42227a9c0968db7b1bb50dc12f7d755505779f1ff2c408672b3091e903366acc9ce15d19fb6", + "0xb6b5efbe1ac4e1bd2e8447c45000d09397b772ca5496acc447b881022608a41c4f60388814607a01890190105bee7be3", + "0x95f7c85fd614df968f8ccf8d086579c9e1cec4644ecf06da26e3511cb39635a7326b3cec47bd51cf5646f1c660425e9c", + "0xb81765fb319bcdc74b4d608383ccb4af7dd84413b23af637be12e2827a75f7e4bcd14441cf979ed9038ae366fbb6f022", + "0xa120ea76cda8c6c50c97035078f6648afe6537809bdba26e7c9e61de8f3070d2347160f9d34010effbf2ec7e94f5749f", + "0x92c1b8631953b40d3cc77eee2c72a064b999c09a9b92c11d8fa7b4072966273901c9dba25f9f79f384d9f11a56f3fc7a", + "0xa4b00dc0ab67b2300abc9c516e34daf444d6497b066a90cfe3381ed2812304ed37b14f3b948990443dc6c1cf1bed460c", + "0xa9e9f7e13c9f031bc7b9e6f1417c7abcc38894fe7d3f54869ee277afd2efa3e6fb50757dd36c8c94d591e0abdea322cc", + "0x84f3e98f831792b5ad14bcfe62a4c9f296476c6087c4c1ec7767fc642fbca141ff6a3deeb8b4d4106a9cda5a9937eea0", + "0x8eb1a7931bbea9a714226fd74b0100ab88355287d9b0a349c095e9b5809b98f237ffd706bce7d67a770da355fb9cec7b", + "0x9738ef8739e1742c1f26b51a1621be0b89d37406a370c531e236f635c7064c661818817bb3858908986aa687b28b21be", + "0xa9cf3ce8501b003ccaf57552a4c4ec31081e44526d3aa3791d3dc4a7e438a357c0956f93c500356186d8fd4588ffac5e", + "0xa7af6a219cca59225839a9de5b19263cb23d75557d448bc7d677b62591a2e068c45e5f4457cceb3e9efa01d0601fc18a", + "0x972a24ece5eda7692cbb6fb727f92740451bc1281835e2a02931b2b05824a16b01dbe5edd03a0ed5b441ff25a5cc0188", + "0xb21d1ec7597ce95a42f759c9a8d79c8275d7e29047a22e08150f0f65014702f10b7edce8c03f6e7ab578ce8c3b0ec665", + "0xa13a1c7df341bd689e1f8116b7afc149c1ef39161e778aa7903e3df2569356ad31834fa58ceb191485585ce5ef6835c3", + "0xa57bdb08119dc3bc089b5b2b5383455c4de0c2fcdac2dcfa21c7ac5071a61635ff83eceb7412f53fab42d1a01991de32", + "0xb2968748fa4a6921ee752d97aa225d289f599a7db7a222450e69706533573ded450380c87f8cdd4a8b8c8db1b42b5c97", + "0x8718ec04e0d5f38e3034ecd2f13dfde840add500f43a5e13457a1c73db0d18138f938690c8c315b5bcbeb51e8b9a2781", + "0x82094789e26c4a04f2f30bdb97b9aecca9b756cbd28d22ab3c8bed8afc5b2963340ddfc5a5f505e679bf058cbc5dcbb8", + "0xa35b8a566dd6ab67eddc2467906bffc76c345d508e52e9e4bb407b4f2b2c5f39b31d5a4bf5022f87bf7181dc6be2fe41", + "0xa8c93b1e893d4777c0e3a1b4bef3be90c215781501407c4011457fc3240e13524b4d2bea64a6d0a3efe3f3b0dae9b8ab", + "0x877095ad18b1e5870818f7a606127ba1736a0b55b0dbcd281ec307c84b08afc0c9117e3a880fe48bfc225fbf37671a97", + "0x84405ee0421ed2db1add3593df8426a9c1fcc8063e875f5311a917febc193748678dd63171d0c21665fb68b6d786c378", + "0xa52cdc8209c3c310bed15a5db260c4f4d4857f19c10e4c4a4cfe9dfc324dfac851421bb801509cf8147f65068d21603c", + "0x8f8a028a70dda7285b664722387666274db92230b09b0672f1ead0d778cee79aae60688c3dfd3a8ed1efdeda5784c9d4", + "0xa0be42fecc86f245a45a8ed132d6efc4a0c4e404e1880d14601f5dce3f1c087d8480bad850d18b61629cf0d7b98e0ae0", + "0x83d157445fc45cb963b063f11085746e93ab40ece64648d3d05e33e686770c035022c14fdf3024b32b321abf498689ad", + "0x8a72bbf5a732e2d4f02e05f311027c509f228aef3561fc5edac3ef4f93313845d3a9f43c69f42e36f508efcc64a20be0", + "0xb9ca29b0ec8e41c6a02f54d8c16aebf377982488cbe2ed1753090f2db4f804f6269af03e015d647a82ef06ffaa8cba6c", + "0xb4df3858d61bbb5ded1cf0be22a79df65ae956e961fbb56c883e1881c4c21fe642e3f5a0c108a882e553ac59595e3241", + "0x86457d8890ac8858d7bab180ef66851247c2bf5e52bf69a4051d1d015252c389684fcc30bb4b664d42fbf670574ab3a3", + "0x86d5576ea6dfa06d9ebce4cd885450f270c88a283e1e0d29cab27851c14ed2f00355e167b52e1539f1218ad11d8f13dd", + "0x883ad1364dc2a92388bfafaa9bc943c55b2f813525831e817a6208c666829a40455dde494eba054b2495a95f7ce69e8a", + "0x8942371e6925231c2c603b5f5a882d8404d39f0c7c4232557c2610b21c2c07f145466da798ea78b7932da2b774aa3128", + "0xa799eb71496783cc7faf12c9d9804bf6180699a004b2f07fc5cc36840f63ce7eee7dde9275819a9aa3f8d92dc0d47557", + "0x8eb3fb5c769548ee38c7882f51b959c5d5a42b5935269ccf987d6ddbb25a206e80c6000bcc328af149e0727c0b7c02c0", + "0x8f3910d64e421a8f2d8db4c7b352ba5b3fc519d5663973fea5962efe4364fb74448770df944ef37ffe0382648fb56946", + "0xb41413e0c26ff124cf334dab0dc8e538293d8d519d11cc2d10895a96b2064ac60c7da39f08589b38726cffa4c3f0bfef", + "0xb46ef2eb10abae0f35fa4c9c7ee2665e8044b8d9f91988a241da40fd5bbc63166925582151941b400006e28bbc5ba22a", + "0xb8baa8b4c420bb572a3b6b85479b67d994c49a7ebfe1274687d946a0d0b36dfed7630cfb897350fa166f5e2eff8f9809", + "0x964b46d359c687e0dcfbdab0c2797fc2bd1042af79b7418795b43d32ffca4de89358cee97b9b30401392ff54c7834f9f", + "0x8410d0203d382ebf07f200fd02c89b80676957b31d561b76563e4412bebce42ca7cafe795039f46baf5e701171360a85", + "0xb1a8d5d473c1a912ed88ea5cfa37c2aea5c459967546d8f2f5177e04e0813b8d875b525a79c29cb3009c20e7e7292626", + "0xafaab9a1637429251d075e0ba883380043eaf668e001f16d36737028fded6faa6eeed6b5bb340f710961cee1f8801c41", + "0xaef17650003b5185d28d1e2306b2f304279da50925f2704a6a3a68312f29fe5c2f2939f14e08b0ba9dee06ea950ad001", + "0x97bcc442f370804aa4c48c2f8318d6f3452da8389af9335e187482d2e2b83b9382e5c297dce1a0f02935e227b74e09a3", + "0x8a67a27b199f0bcd02d52a3e32f9b76a486b830ec481a49a4e11807e98408b7052b48581b5dd9f0b3e93052ec45dfb68", + "0xb113bf15f430923c9805a5df2709082ab92dcdf686431bbad8c5888ca71cc749290fa4d4388a955c6d6ee3a3b9bc3c53", + "0x8629ca24440740ce86c212afed406026f4ea077e7aa369c4151b6fa57bca7f33f9d026900e5e6e681ae669fd2bd6c186", + "0x933a528371dcecc1ec6ded66b1c7b516bd691b3b8f127c13f948bfbcda3f2c774c7e4a8fbee72139c152064232103bdf", + "0x8568ddd01f81a4df34e5fa69c7f4bb8c3c04274147498156aec2e3bd98ea3e57c8a23503925de8fa3de4184563a2b79e", + "0x8160874ec030f30fda8f55bcf62613994ff7ed831e4901c7560eac647182b4a9b43bfaff74b916602b9d6ae3bfcaf929", + "0xae71c48d48cf9459800cdf9f8e96bc22e2d4e37259e5c92a2b24fbe2c6ca42675e312288603c81762f6ceb15400bc4c9", + "0xb05f39bb83fda73e0559db1fd4a71423938a87ad9f060d616d4f4a6c64bf99472a2cbfb95f88b9257c9630fc21a0b81f", + "0x80c8479a640ed7a39e67f2db5ad8dfd28979f5443e8e6c23da8087fc24134d4b9e7c94320ffa4154163270f621188c27", + "0x9969ba20ee29c64cb3285a3433a7e56a0fe4ddc6f3d93e147f49fe021bed4a9315266ebb2fb0eb3036bb02001ae015e6", + "0xa198c89fef2ab88e498703b9021becc940a80e32eb897563d65db57cc714eaa0e79092b09dd3a84cfab199250186edcc", + "0x8df14a3db8fe558a54d6120bad87405ba9415a92b08c498812c20416c291b09fed33d1e2fcf698eb14471f451e396089", + "0x81e245ef2649b8a5c8d4b27188dd7e985ef6639090bdc03462c081396cf7fc86ed7d01bfe7e649d2b399255e842bdc21", + "0x8659f622c7ab7b40061bcf7a10144b51ad3ab5348567195924f2944e8c4ce137a37f1ba328e4716c10806f3fb7271689", + "0xa575d610fc8fe09334ca619ecdadf02d468ca71dd158a5a913252ca55ea8d8f9ce4548937c239b9cb8ab752a4d5af24a", + "0x94744549cd9f29d99f4c8c663997bdfa90e975b31f1086214245de9c87b0c32209f515a0de64d72d5ef49c09b0a031fa", + "0x80a8677862b056df59e350c967a27436c671b65d58854e100115bac9824ba177e94c2a1bfcaa191a071b9cefdbee3989", + "0x91be9a5504ec99922440f92a43fe97ddce2f21b9d94cd3a94c085a89b70c903696cec203bbab6d0a70693ba4e558fb01", + "0x8c5a0087bcd370734d12d9b3ab7bc19e9a336d4b49fc42825b2bfedcd73bb85eb47bf8bb8552b9097cc0790e8134d08c", + "0x933aa9e6bd86df5d043e0577a48e17eea3352e23befdbb7d7dcac33b5703d5ace230443ac0a40e23bf95da4cc2313478", + "0x984b7ee4bd081ee06c484db6114c2ce0ba356988efb90f4c46ff85ed2865fb37f56a730166c29ef0ae3345a39cdeae7a", + "0xae830f908ea60276c6c949fb8813e2386cf8d1df26dcf8206aa8c849e4467243e074471380ed433465dc8925c138ea4c", + "0x874c1df98d45b510b4f22feff46a7e8ed22cfc3fad2ac4094b53b9e6477c8dfc604976ca3cee16c07906dece471aa6c6", + "0xa603eb60d4c0fb90fa000d2913689126849c0261e6a8649218270e22a994902965a4e7f8c9462447259495fe17296093", + "0xa7c73d759a8ad5e3a64c6d050740d444e8d6b6c9ade6fb31cb660fa93dc4a79091230baccb51c888da05c28cb26f6f3f", + "0xa4411b79b6a85c79ea173bd9c23d49d19e736475f3d7d53213c5349ebb94a266d510d12ba52b2ac7a62deaaaec7339b8", + "0x943b84f8bbcee53b06266b5c4cd24d649d972593837fe82b0bf5d5e1bbc1a2bf148e1426c366d7c39ab566b10224cadc", + "0x8300012096a8b4cefecc080054bf3ceb0918162ba263c6848860423407796b5eb517170c0bad8e4905ac69a383055a21", + "0x8244a1e3ad41908c6f037e2f8db052e81f281646141334829f36c707f307448b9ab79a7f382a1e8d86f877c90b59271c", + "0x8eca1b74687802ecc36a5d39e4516a9dee3de61a2047252d9ed737b49e0090c386e9d792ac004c96337681c7f29a16ad", + "0xb70fa47535f0524835039a20036c61e77f66146ad79d3d339214d8744742db41ceeb577c829d000011aeafbb12e09579", + "0x84b3abbce48689f3adbb99889c7fd1f3e15ab455d477e34f5151c5c1c358ed77a5b6a581879f7e0f1f34106e0792e547", + "0xab45ecb58c0ef0dbce3d16afc6ac281e0d90ec48741ea96a141152647e98fcc87f3a3ff07ba81f3179118453ce123156", + "0x90d231a145ba36a59087e259bbfc019fa369201fcfeaa4347d5fd0a22cd8a716e5a797f3cc357f2779edb08f3b666169", + "0xa4f6074d23c6c97e00130bc05f25213ca4fa76c69ca1ace9dece904a2bdd9d987661f5d55023b50028c444af47ff7a08", + "0x933af884939ad0241f3f1f8e8be65f91d77ac0fb234e1134d92713b7cfb927f1933f164aec39177daa13b39c1370fac8", + "0x80d1db6933ce72091332ae47dc691acb2a9038f1239327b26d08ea9d40aa8f2e44410bbda64f2842a398cbe8f74f770f", + "0xa7a08605be2241ccc00151b00b3196d9c0717c4150909a2e9cd05538781231762b6cc6994bebbd4cddae7164d048e7b2", + "0x96db0d839765a8fdbbac03430fa800519e11e06c9b402039e9ae8b6503840c7ecac44123df37e3d220ac03e77612f4e4", + "0x96d70f8e9acd5a3151a8a9100ad94f16c289a31d61df681c23b17f21749c9062622d0a90f6d12c52397b609c6e997f76", + "0x8cf8e22273f7459396ff674749ab7e24c94fe8ab36d45d8235e83be98d556f2b8668ba3a4ec1cb98fac3c0925335c295", + "0x97b7e796a822262abc1a1f5a54cb72a1ea12c6c5824ac34cd1310be02d858a3c3aa56a80f340439b60d100e59c25097d", + "0xa48208328b08769737aa1a30482563a4a052aea736539eceab148fa6653a80cb6a80542e8b453f1f92a33d0480c20961", + "0xb612184941413fd6c85ff6aa517b58303b9938958aa85a85911e53ed308778624d77eadb27ccf970573e25d3dfd83df7", + "0xb3717068011648c7d03bbd1e2fc9521a86d2c3ae69113d732c2468880a3b932ebec93596957026477b02842ed71a331b", + "0xa0ad363e1352dcf035b03830fef4e27d5fd6481d29d5e8c9d51e851e3862d63cdcbaf8e330d61c1b90886921dac2c6fd", + "0x8db409fdacfa4bfdaf01cc87c8e97b53ca3a6e3a526d794eaad1c2023f3df4b888f1bf19fee9a990fe6d5c7c3063f30c", + "0xb34d6975310ab15938b75ef15020a165fc849949065d32d912554b51ffa1d3f428a6d1a396cb9329367670391de33842", + "0x9117285e9e6762853fc074b8a92b3923864de2c88c13cea7bab574aaf8cdd324843455d2c3f83c00f91f27c7ecc5592a", + "0xb4b2e8f190ea0b60819894710c866bf8578dd1b231ae701d430797cc7ede6e216e8ca6a304f3af9484061563645bf2ab", + "0x8c493c6853ab135d96a464815dd06cad8b3e8b163849cdefc23d1f20211685753b3d3e147be43e61e92e35d35a0a0697", + "0x9864d7880f778c42d33cf102c425e380d999d55a975a29c2774cad920dfddb80087a446c4f32ed9a6ab5f22ec6f82af0", + "0x90f67fe26f11ca13e0c72b2c2798c0d0569ed6bc4ce5bbaf517c096e7296d5dd5685a25012f6c6d579af5b4f5d400b37", + "0xa228872348966f26e28a962af32e8fa7388d04bc07cfc0224a12be10757ac7ab16a3387c0b8318fcb0c67384b0e8c1a4", + "0xa9d9d64bba3c03b51acf70aeb746a2712ddafe3b3667ae3c25622df377c2b5504e7ab598263bec835ab972283c9a168b", + "0x932128971c9d333f32939a1b46c4f7cf7e9d8417bd08dc5bd4573ccbd6ec5b460ac8880fb7f142f7ef8a40eef76d0c6d", + "0x964115e7838f2f197d6f09c06fbb2301d6e27c0ecdf208350cf3b36c748436dac50f47f9f9ac651c09ab7ad7221c7e43", + "0xa5941f619e5f55a9cf6e7f1499b1f1bcddcc7cf5e274efedaaad73a75bc71b1fc5c29cd903f6c69dc9a366a6933ca9d1", + "0xa154bf5eaec096029e5fe7c8bf6c695ae51ace356bb1ad234747776c7e1b406dee2d58864c3f4af84ed69f310974125e", + "0xb504e6209d48b0338ab1e4bdab663bac343bb6e0433466b70e49dc4464c1ec05f4a98111fd4450393607510ae467c915", + "0x813411918ea79bdde295393284dc378b9bdc6cfcb34678b9733ea8c041ac9a32c1e7906e814887469f2c1e39287e80f8", + "0x8be0369f94e4d72c561e6edb891755368660208853988647c55a8eed60275f2dd6ee27db976de6ecf54ac5c66aaf0ae6", + "0xa7e2701e55b1e7ea9294994c8ad1c080db06a6fc8710cd0c9f804195dce2a97661c566089c80652f27b39018f774f85e", + "0x956b537703133b6ddf620d873eac67af058805a8cc4beb70f9c16c6787bf3cc9765e430d57a84a4c3c9fbdd11a007257", + "0x835ae5b3bb3ee5e52e048626e3ddaa49e28a65cb94b7ecdc2e272ff603b7058f1f90b4c75b4b9558f23851f1a5547a35", + "0x85d67c371d1bf6dc72cca7887fa7c886ce988b5d77dc176d767be3205e80f6af2204d6530f7060b1f65d360a0eaeff30", + "0xa84a6647a10fcef8353769ef5f55a701c53870054691a6e9d7e748cbe417b3b41dbb881bae67adc12cb6596c0d8be376", + "0x87ffe271fc0964cb225551c7a61008d8bcb8b3d3942970dbcc2b9f4f9045a767971880368ea254e2038a3a0b94ecf236", + "0x964bb721c51d43ee7dd67c1a2b7dd2cc672ce8fad78c22dcddb43e6aab48d9a4a7dc595d702aa54a6fb0ffabf01f2780", + "0xa89b3f84bb7dcbe3741749776f5b78a269f6b1bebb8e95d3cc80b834fd2177c6be058d16cacfd0d5e1e35e85cde8b811", + "0xb4314538e003a1587b5592ff07355ea03239f17e75c49d51f32babe8e048b90b046a73357bcb9ce382d3e8fbe2f8e68b", + "0x86daf4bf201ae5537b5d4f4d734ed2934b9cf74de30513e3280402078f1787871b6973aa60f75858bdf696f19935a0e2", + "0xb1adf5d4f83f089dc4f5dae9dbd215322fa98c964e2eaa409bf8ca3fa5c627880a014ed209492c3894b3df1c117236c4", + "0xb508d52382c5bac5749bc8c89f70c650bb2ed3ef9dc99619468c387c1b6c9ff530a906dfa393f78f34c4f2f31478508a", + "0xa8349a5865cb1f191bebb845dfbc25c747681d769dbffd40d8cedf9c9a62fa2cbc14b64bb6121120dab4e24bef8e6b37", + "0xaf0500d4af99c83db8890a25f0be1de267a382ec5e9835e2f3503e1bac9412acf9ff83a7b9385708ef8187a38a37bc77", + "0xb76d57a1c1f85b8a8e1722a47057b4c572800957a6b48882d1fc21309c2e45f648a8db0fcff760d1dbc7732cf37c009b", + "0xb93c996cec0d3714667b5a5a5f7c05a7dc00bbc9f95ac8e310626b9e41ae4cc5707fac3e5bd86e1e1f2f6d9627b0da94", + "0x93216fdb864217b4c761090a0921cf8d42649ab7c4da1e009ec5450432564cb5a06cb6e8678579202d3985bd9e941cef", + "0x8b8be41105186a339987ae3a5f075fbc91f34b9984d222dfed0f0f85d2f684b56a56ab5dc812a411570491743d6c8b18", + "0x959b72782a6b2469e77fe4d492674cc51db148119b0671bd5d1765715f49fa8a87e907646671161586e84979ef16d631", + "0x86b7fc72fb7e7904ea71d5e66ba0d5d898ace7850985c8cc4a1c4902c5bf94351d23ce62eed45e24321fb02adfa49fc8", + "0xa2f244e7c9aa272cb0d067d81d25e5a3045b80b5a520b49fd5996ece267a7f1bea42e53147bbf153d9af215ea605fc9e", + "0x81aa2efa5520eebc894ce909ba5ce3250f2d96baa5f4f186a0637a1eea0080dd3a96c2f9fadf92262c1c5566ddb79bab", + "0xb607dd110cfe510d087bcff9a18480ba2912662256d0ab7b1d8120b22db4ad036b2266f46152754664c4e08d0fc583f6", + "0x8f588d5f4837e41312744caac5eee9ddc3ad7085871041694f0b5813edf83dc13af7970f7c9b6d234a886e07fa676a04", + "0x924921b903207783b31016cbec4e6c99e70f5244e775755c90d03a8b769738be3ba61577aca70f706a9c2b80040c9485", + "0xae0a42a222f1a71cd0d3c69ffb2f04c13e1940cce8efabe032629f650be3ceed6abb79651dbb81cb39a33286eb517639", + "0xa07d7d76460f31f5f0e32e40a5ea908d9d2aebf111ac4fadee67ef6540b916733c35a777dcdc05f6417726ca1f2d57dd", + "0x88d7f8a31f8c99794291847d28745e5d0b5d3b9684ca4170b686ffbb5bb521a3ef6746c3c8db22e4250a0cdff7939d96", + "0x849573071fd98c020dc9a8622a9eff221cb9f889bde259e7127a8886b73bef7ad430b87750915658918dcfb6b7b4d8d3", + "0xb12d59f732fa47fad175d6263734da8db89230fd340a46ad1cdee51e577041a5c80bf24cd195593e637daf1a66ef5a98", + "0xabbcfb8a4a6d5e269ee1ac5e277df84416c73ca55ec88317f73608201af25af0cb65b943c54684a5651df3a26e3daca2", + "0xab157f589bdbaf067a6a7ba7513df0492933855d39f3a081196cf2352e0ddc0162d476c433320366e3df601e0556278d", + "0xa86c0619b92e5ae4f7daa876a2abc5ba189156afc2fa05eef464dfa342ba37fc670d0dc308ad3822fcb461ab001bac30", + "0xa3f292946476cfe8d5e544a5325439a00e0165a5f9bf3bb6a53f477baeac7697cc0377745536681aa116f326ce911390", + "0x8aecbbfd442a6a0f01c1c09db5d9d50213eb6f1ff6fab674cde3da06a4edff3ed317e804f78300c22ef70c336123e05d", + "0x834ed4b58211fcd647d7bf7c0a3ba9085184c5c856b085e8a0fcd5215c661ef43d36f3f0f6329a9f1370501b4e73b6e4", + "0xa114ea5ad2b402a0de6105e5730907f2f1e458d28ae35144cf49836e0ad21325fe3e755cfb67984ae0a32e65402aad1e", + "0xa005f12bed97d71cee288b59afe9affb4d256888727343944a99913980df2c963fe02f218e6ea992f88db693a4498066", + "0xa010f286ab06b966e3b91ff8f1bdbe2fe9ab41a27bc392d5787aa02a46e5080e58c62c7d907818caae9f6a8b8123e381", + "0x857bd6df2ddef04dbc7c4f923e0b1696d3016c8bfed07fdfa28a3a3bd62d89b0f9df49aae81cbb6883d5e7b4fadae280", + "0xb3927030da445bc4756ac7230a5d87412a4f7510581fb422212ce2e8cf49689aca7ba71678743af06d4de4914c5aa4a0", + "0xb86403182c98fcce558d995f86752af316b3b2d53ba32075f71c7da2596747b7284c34a1a87de604fcc71e7e117a8add", + "0x98dd19b5527733041689b2a4568edaf6aa0fe1a3dd800c290cda157b171e053648a5772c5d3d4c80e5a795bc49adf12e", + "0x88a3c227bb7c9bff383f9ad3f7762245939a718ab85ae6e5e13180b12bf724d42054d3852b421c1cd1b3670baddecb63", + "0xb3cfd9ad66b52bbe57b5fff0fad723434d23761409b92c4893124a574acc1e6b1e14b4ec507661551cbbe05e16db362e", + "0x923e1bb482cf421dd77801f9780f49c3672b88508a389b94015fd907888dc647ee9ea8ec8d97131d235d066daf1f42b7", + "0x8d5e16240f04f92aa948181d421006bdbc7b215648fb6554193224d00cf337ebbb958f7548cf01b4d828acffb9fbc452", + "0x8b2b8f18ad0559746f6cda3acca294a1467fb1a3bc6b6371bc3a61a3bfe59418934fa8706f78b56005d85d9cb7f90454", + "0xa9316e2a94d6e31426d2ae7312878ba6baaac40f43e2b8a2fa3ab5a774c6918551554b2dbb23dc82f70ba3e0f60b5b0d", + "0x9593116d92cf06b8cd6905a2ce569ee6e69a506c897911f43ae80fc66c4914da209fc9347962034eebbc6e3e0fe59517", + "0x887d89d2b2d3c82b30e8f0acf15f0335532bd598b1861755498610cb2dd41ff5376b2a0bb757cb477add0ce8cfe7a9fc", + "0xb514cfe17875ecb790ad055271cc240ea4bda39b6cfa6a212908849c0875cb10c3a07826550b24c4b94ea68c6bb9e614", + "0xa563d5187966d1257d2ed71d53c945308f709bcc98e3b13a2a07a1933dc17bcb34b30796bd68c156d91811fbd49da2cb", + "0xa7195ccc53b58e65d1088868aeeb9ee208103e8197ad4c317235bb2d0ad3dc56cb7d9a7186416e0b23c226078095d44c", + "0xa838e7a368e75b73b5c50fbfedde3481d82c977c3d5a95892ac1b1a3ea6234b3344ad9d9544b5a532ccdef166e861011", + "0x9468ed6942e6b117d76d12d3a36138f5e5fb46e3b87cf6bb830c9b67d73e8176a1511780f55570f52d8cdb51dcf38e8c", + "0x8d2fc1899bc3483a77298de0e033085b195caf0e91c8be209fd4f27b60029cbe1f9a801fbd0458b4a686609762108560", + "0x8f4e44f8ca752a56aa96f3602e9234ad905ad9582111daf96a8c4d6f203bf3948f7ce467c555360ad58376ee8effd2ba", + "0x8fb88640b656e8f1c7c966c729eb2ba5ccf780c49873f8b873c6971840db7d986bdf1332ba80f8a0bb4b4ee7401468fa", + "0xb72aa3235868186913fb5f1d324e748cd3ce1a17d3d6e6ea7639a5076430fe0b08841c95feb19bb94181fe59c483a9eb", + "0xb8b102690ebb94fc4148742e7e3fd00f807b745b02cbe92cd92992c9143b6db7bb23a70da64a8b2233e4a6e572fc2054", + "0x8c9ae291f6cd744e2c6afe0719a7fc3e18d79307f781921fb848a0bf222e233879c1eca8236b4b1be217f9440859b6ce", + "0xa658ede47e14b3aad789e07f5374402f60e9cacb56b1b57a7c6044ca2418b82c98874e5c8c461898ebd69e38fecd5770", + "0x89c0cb423580e333923eb66bda690f5aca6ec6cba2f92850e54afd882ba608465a7dbb5aa077cd0ca65d9d00909348ab", + "0xaed8e28d98d5508bd3818804cf20d296fe050b023db2ed32306f19a7a3f51c7aaafed9d0847a3d2cd5ba5b4dabbc5401", + "0x96a0fcd6235f87568d24fb57269a94402c23d4aa5602572ad361f3f915a5f01be4e6945d576d51be0d37c24b8b0f3d72", + "0x935d0c69edd5dfa8ed07c49661b3e725b50588f814eb38ea31bcc1d36b262fae40d038a90feff42329930f8310348a50", + "0x900518288aa8ea824c7042f76710f2ea358c8bb7657f518a6e13de9123be891fa847c61569035df64605a459dad2ecc8", + "0x947d743a570e84831b4fb5e786024bd752630429d0673bf12028eb4642beb452e133214aff1cfa578a8856c5ebcb1758", + "0xa787266f34d48c13a01b44e02f34a0369c36f7ec0aae3ec92d27a5f4a15b3f7be9b30b8d9dd1217d4eeedff5fd71b2e5", + "0xa24b797214707ccc9e7a7153e94521900c01a1acd7359d4c74b343bfa11ea2cdf96f149802f4669312cd58d5ab159c93", + "0x97f5ee9c743b6845f15c7f0951221468b40e1edaef06328653a0882793f91e8146c26ac76dd613038c5fdcf5448e2948", + "0x80abd843693aed1949b4ea93e0188e281334163a1de150c080e56ca1f655c53eb4e5d65a67bc3fc546ed4445a3c71d00", + "0x908e499eb3d44836808dacff2f6815f883aeced9460913cf8f2fbbb8fe8f5428c6fc9875f60b9996445a032fd514c70f", + "0xae1828ef674730066dc83da8d4dd5fa76fc6eb6fa2f9d91e3a6d03a9e61d7c3a74619f4483fe14cddf31941e5f65420a", + "0xa9f4dbe658cd213d77642e4d11385a8f432245b098fccd23587d7b168dbeebe1cca4f37ee8d1725adb0d60af85f8c12f", + "0x93e20ee8a314b7772b2439be9d15d0bf30cd612719b64aa2b4c3db48e6df46cea0a22db08ca65a36299a48d547e826a7", + "0xa8746a3e24b08dffa57ae78e53825a9ddbbe12af6e675269d48bff4720babdc24f907fde5f1880a6b31c5d5a51fbb00e", + "0xb5e94dfab3c2f5d3aea74a098546aa6a465aa1e3f5989377d0759d1899babf543ad688bb84811d3e891c8713c45886c5", + "0xa3929bada828bd0a72cda8417b0d057ecb2ddd8454086de235540a756e8032f2f47f52001eb1d7b1355339a128f0a53b", + "0xb684231711a1612866af1f0b7a9a185a3f8a9dac8bde75c101f3a1022947ceddc472beb95db9d9d42d9f6ccef315edbc", + "0xaf7809309edbb8eb61ef9e4b62f02a474c04c7c1ffa89543d8c6bf2e4c3d3e5ecbd39ec2fc1a4943a3949b8a09d315a6", + "0xb6f6e224247d9528ef0da4ad9700bee6e040bbf63e4d4c4b5989d0b29a0c17f7b003c60f74332fefa3c8ddbd83cd95c1", + "0xadbcec190a6ac2ddd7c59c6933e5b4e8507ce5fd4e230effc0bd0892fc00e6ac1369a2115f3398dfc074987b3b005c77", + "0x8a735b1bd7f2246d3fa1b729aecf2b1df8e8c3f86220a3a265c23444bdf540d9d6fe9b18ed8e6211fad2e1f25d23dd57", + "0x96b1bf31f46766738c0c687af3893d098d4b798237524cb2c867ed3671775651d5852da6803d0ea7356a6546aa9b33f2", + "0x8036e4c2b4576c9dcf98b810b5739051de4b5dde1e3e734a8e84ab52bc043e2e246a7f6046b07a9a95d8523ec5f7b851", + "0x8a4f4c32ee2203618af3bb603bf10245be0f57f1cfec71037d327fa11c1283b833819cb83b6b522252c39de3ce599fa5", + "0xad06ed0742c9838e3abaaffdb0ac0a64bad85b058b5be150e4d97d0346ed64fd6e761018d51d4498599669e25a6e3148", + "0x8d91cb427db262b6f912c693db3d0939b5df16bf7d2ab6a7e1bc47f5384371747db89c161b78ff9587259fdb3a49ad91", + "0xae0a3f84b5acb54729bcd7ef0fbfdcf9ed52da595636777897268d66db3de3f16a9cf237c9f8f6028412d37f73f2dfad", + "0x8f774109272dc387de0ca26f434e26bc5584754e71413e35fa4d517ee0f6e845b83d4f503f777fe31c9ec05796b3b4bc", + "0xa8670e0db2c537ad387cf8d75c6e42724fae0f16eca8b34018a59a6d539d3c0581e1066053a2ec8a5280ffabad2ca51f", + "0xac4929ed4ecad8124f2a2a482ec72e0ef86d6a4c64ac330dab25d61d1a71e1ee1009d196586ce46293355146086cabba", + "0x845d222cb018207976cc2975a9aa3543e46c861486136d57952494eb18029a1ebb0d08b6d7c67c0f37ee82a5c754f26f", + "0xb99fa4a29090eac44299f0e4b5a1582eb89b26ed2d4988b36338b9f073851d024b4201cd39a2b176d324f12903c38bee", + "0x9138823bc45640b8f77a6464c171af2fe1700bdc2b7b88f4d66b1370b3eafe12f5fbb7b528a7e1d55d9a70ca2f9fc8e6", + "0x8ac387dc4cf52bc48a240f2965ab2531ae3b518d4d1f99c0f520a3d6eb3d5123a35ef96bed8fa71ee2f46793fa5b33b3", + "0x864adec6339d4c2ba2525621fceabd4c455902f6f690f31a26e55413e0722e5711c509dc47ce0bcc27bbdc7651768d2d", + "0xa0a52edb72268a15201a968dabc26a22909620bda824bd548fb8c26cc848f704166ed730d958f0173bd3b0a672f367bd", + "0x949e445b0459983abd399571a1a7150aab3dd79f4b52a1cd5d733e436c71c1d4b74287c6b0ce6cc90c6711ba4c541586", + "0x858966355dac11369e3b6552f2b381665181693d5a32e596984da3314021710b25a37d8c548b08700eea13d86cb22f21", + "0x974bcbb8d38c5e6518745cc03ad436e585b61f31d705e7e2e5085da9655d768ac4d800904f892c3dab65d6223e3f1fd6", + "0x8092b6506b01308bf6187fde5ebd4fa7448c9a640961ba231be22ac5fa2c7635ef01e8b357722c7695d09b723101ea2a", + "0xa5b8ef360bf28533ee17d8cd131fff661d265f609db49599085c0c7d83b0af409a1b5c28e3a5e5d7f8459a368aa121e8", + "0xb031b6d5e3ceab0f0c93314b3b675f55cf18cbc86f70444af266fe39cb22fd7dad75d8c84e07f1c1bfa2cb8283e1361a", + "0x93ad489e4f74658320c1cceed0137c023d3001a2c930ed87e6a21dbf02f2eb6ad1c1d8bcb3739c85dcfbecb040928707", + "0xb15e4ec2cdab0d34aec8d6c50338812eb6ecd588cf123a3e9d22a7ca23b5a98662af18289f09e6cdd85a39a2863c945c", + "0xb304f71a9717cf40c22073f942618b44bf27cd5e2ed4a386ad45d75b0fcb5a8dafd35158211eaf639495c6f1a651cedb", + "0xb82d78d3eaaa7c5101b7a5aae02bd4f002cd5802d18c3abcda0dd53b036661c6d3c8b79e0abe591eab90b6fdc5fef5e3", + "0xabbd1884243a35578b80914a5084449c237ee4e4660c279d1073a4d4217d1b55c6b7e9c087dfd08d94ac1416273d8d07", + "0x92f4b61c62502745e3e198ec29bca2e18696c69dcb914d1f3a73f4998d012b90caf99df46e9bb59942e43cce377fe8fd", + "0x906e79df98185820c8208844e1ba6bd86cb96965814b01310bd62f22cbec9b5d379b2ef16772d6fc45a421b60cfd68fe", + "0xa0eae2784ef596e2eb270dd40c48d6c508e4394c7d6d08d4cc1b56fde42b604d10ba752b3a80f2c4a737e080ef51b44f", + "0x94c084985e276dc249b09029e49a4ef8a369cd1737b51c1772fbb458d61e3fe120d0f517976eba8ffa5711ba93e46976", + "0x83619a0157eff3f480ab91d1d6225fead74c96a6fd685333f1e8e4d746f6273e226bad14232f1d1168a274e889f202f1", + "0xa724fe6a83d05dbbf9bb3f626e96db2c10d6d5c650c0a909415fbda9b5711c8b26e377201fb9ce82e94fa2ab0bf99351", + "0xa8a10c1b91a3a1fa2d7fd1f78a141191987270b13004600601d0f1f357042891010717319489f681aa8a1da79f7f00d5", + "0xa398a2e95b944940b1f8a8e5d697c50e7aa03994a8a640dfad4ea65cfb199a4d97861a3ec62d1c7b2b8d6e26488ca909", + "0xa2eedfe5452513b2a938fffd560798ef81379c5a5032d5b0da7b3bb812addbaad51f564c15d9acbbfc59bb7eddd0b798", + "0xab31c572f6f145a53e13b962f11320a1f4d411739c86c88989f8f21ab629639905b3eedb0628067942b0dc1814b678ca", + "0xad032736dd0e25652d3566f6763b48b34ea1507922ed162890cd050b1125ec03b6d41d34fccba36ec90336f7cdf788ed", + "0x83028a558a5847293147c483b74173eca28578186137df220df747fccd7d769528d7277336ea03c5d9cdd0bc5ae3d666", + "0xab5d182cd1181de8e14d3ef615580217c165e470b7a094a276b78a3003089123db75c6e1650bf57d23e587c587cd7472", + "0xa4793e089fbdb1597654f43b4f7e02d843d4ab99ee54099c3d9f0bd5c0c5657c90bb076379a055b00c01b12843415251", + "0x98bdc52ee062035356fb2b5c3b41673198ddc60b2d1e546cb44e3bb36094ef3c9cf2e12bbc890feb7d9b15925439d1ea", + "0xa4f90cca6f48024a0341bd231797b03693b34e23d3e5b712eb24aba37a27827319b2c16188f97c0636a0c115381dc659", + "0x8888e6c2e4a574d04ba5f4264e77abc24ccc195f1a7e3194169b8a2ceded493740c52db4f9833b3dbf4d67a3c5b252cb", + "0x83dc4e302b8b0a76dc0292366520b7d246d73c6aebe1bdd16a02f645c082197bcff24a4369deda60336172cefbcf09af", + "0xa4eb2741699febfeb793914da3054337cc05c6fa00d740e5f97cb749ae16802c6256c9d4f0f7297dcdbb8b9f22fc0afa", + "0x8b65557d5be273d1cb992a25cfce40d460c3f288d5cb0a54bdef25cbd17cdea5c32ec966e493addf5a74fd8e95b23e63", + "0x97c6577e76c73837bcb398b947cb4d3323d511141e0ddd0b456f59fbb1e8f920a5c20d7827a24309145efddee786140f", + "0xabcc0849ffe2a6a72157de907907b0a52deece04cf8317bee6fe1d999444b96e461eac95b6afde3d4fe530344086a625", + "0x9385c0115cb826a49df1917556efa47b5b5e4022b6a0d2082053d498ec9681da904ecf375368bb4e385833116ea61414", + "0x8b868c1841f0cdc175c90a81e610b0652c181db06731f5c8e72f8fafa0191620742e61a00db8215a991d60567b6a81ca", + "0xa8df15406f31b8fcf81f8ff98c01f3df73bf9ec84544ddec396bdf7fafa6fe084b3237bf7ef08ad43b26517de8c3cd26", + "0xa9943d21e35464ce54d4cc8b135731265a5d82f9ccf66133effa460ffdb443cdb694a25320506923eede88d972241bf2", + "0xa1378ee107dd7a3abcf269fd828887c288363e9b9ca2711377f2e96d2ed5e7c5ec8d3f1da995a3dcbedf1752d9c088fc", + "0x8a230856f9227b834c75bdebc1a57c7298a8351874bf39805c3e0255d6fd0e846f7ad49709b65ec1fd1a309331a83935", + "0x877bcf42549d42610e1780e721f5800972b51ba3b45c95c12b34cb35eeaf7eac8fa752edd7b342411820cf9093fea003", + "0x84c7a0b63842e50905624f1d2662506b16d1f3ea201877dfc76c79181c338b498eceb7cad24c2142c08919120e62f915", + "0x8e18b1bd04b1d65f6ed349b5d33a26fe349219043ead0e350b50ae7a65d6ff5f985dd9d318d3b807d29faa1a7de4fe42", + "0x8ea7b5a7503e1f0b3c3cd01f8e50207044b0a9c50ed1697794048bbe8efd6659e65134d172fb22f95439e1644f662e23", + "0xb1954a2818cad1dad6d343a7b23afa9aa8ad4463edc4eb51e26e087c2010927535020d045d97d44086d76acdb5818cbf", + "0xa5271ea85d0d21fa1ff59b027cf88847c0f999bbf578599083ff789a9b5228bc161e1c81deb97e74db1a82a0afd61c50", + "0xaa2fa4c05af3387e2c799315781d1910f69977ec1cfea57a25f1a37c63c4daaa3f0ecd400884a1673e17dd5300853bcf", + "0xb1cd2a74ca0b8e6090da29787aef9b037b03b96607983a308b790133bd21297b21ca4e2edec890874096dbf54e9d04c3", + "0x801931607ec66a81272feaa984f0b949ad12d75ecf324ba96627bd4dc5ddead8ebf088f78e836b6587c2b6c0b3366b6c", + "0x95d79504710bdf0ad9b9c3da79068c30665818c2f0cdbba02cc0a5e46e29d596032ac984441b429bd62e34535c8d55b0", + "0x9857d41e25e67876510ff8dadf0162019590f902da1897da0ef6fc8556e3c98961edb1eb3a3a5c000f6c494413ded15e", + "0x8740c9ffe6bd179c19a400137c3bd3a593b85bd4c264e26b4dfb9e2e17ac73e5b52dfacc1dcb4033cfc0cd04785f4363", + "0x977f98f29d948b4097a4abdf9345f4c1fb0aa94ba0c6bf6faa13b76f3a3efc8f688e1fe96099b71b3e1c05041118c8d1", + "0xa364422b1239126e3e8d7b84953ce2181f9856319b0a29fcab81e17ac27d35798088859c1cfc9fc12b2dbbf54d4f70b3", + "0xa0f6ba637f0db7a48e07439bb92ddb20d590ce9e2ed5bab08d73aa22d82c32a9a370fe934cbe9c08aeb84b11adcf2e0e", + "0xa2c548641bd5b677c7748327cca598a98a03a031945276be6d5c4357b6d04f8f40dd1c942ee6ec8499d56a1290ac134d", + "0x9863e9cc5fbcdbd105a41d9778d7c402686bfd2d81d9ed107b4fda15e728871c38647529693306855bee33a00d257a7e", + "0xa54173bf47b976290c88fd41f99300135de222f1f76293757a438450880e6f13dbde3d5fe7afc687bdfbcfc4fbc1fc47", + "0xb8db413917c60907b73a997b5ab42939abd05552c56a13525e3253eb72b83f0d5cc52b695968a10005c2e2fe13290e61", + "0xa1f8388ef21697c94ba90b1a1c157f0dc138e502379e6fc5dc47890d284563e5db7716266e1b91927e5adf3cde4c0a72", + "0x9949013a59d890eb358eab12e623b2b5edb1acbee238dfad8b7253102abc6173922e188d5b89ec405aa377be8be5f16d", + "0xa00fdb7710db992041f6ddb3c00099e1ce311dea43c252c58f560c0d499983a89de67803a8e57baa01ee9d0ee6fa1e44", + "0xa8b1bcbed1951c9cdb974b61078412881b830b48cd6b384db0c00fa68bcc3f4312f8e56c892ea99d3511857ef79d3db9", + "0x8f3ee78404edc08af23b1a28c2012cee0bdf3599a6cb4ea689fc47df4a765ef519191819a72562b91a0fbcdb896a937e", + "0x8155bbb7fa8d386848b0a87caae4da3dec1f3dade95c750a64a8e3555166ccc8799f638bd80ed116c74e3a995541587a", + "0xabfe30adbc0a6f1fd95c630ed5dac891b85384fa9331e86b83217f29dff0bd7cad19d328485715a7e3df9a19069d4d2f", + "0x89d0783e496ee8dbb695764b87fb04cee14d4e96c4ba613a19736971c577d312079048142c12ce5b32b21e4d491d281b", + "0x856b8dbc9c5d8f56b6bb7d909f339ca6da9a8787bba91f09130a025ab6d29b64dbf728ba6ed26e160a23c1cdb9bc037b", + "0x8a30dd2ea24491141047a7dfe1a4af217661c693edf70b534d52ca547625c7397a0d721e568d5b8398595856e80e9730", + "0xae7e1412feb68c5721922ed9279fb05549b7ef6812a4fd33dbbbd7effab756ab74634f195d0c072143c9f1fd0e1ee483", + "0xb7ce970e06fa9832b82eef572f2902c263fda29fdce9676f575860aae20863046243558ede2c92343616be5184944844", + "0x85ed0531f0e5c1a5d0bfe819d1aa29d6d5ff7f64ad8a0555560f84b72dee78e66931a594c72e1c01b36a877d48e017ca", + "0xb8595be631dc5b7ea55b7eb8f2982c74544b1e5befc4984803b1c69727eac0079558182f109e755df3fd64bee00fcaa5", + "0x99e15a66e5b32468ef8813e106271df4f8ba43a57629162832835b8b89402eb32169f3d2c8de1eb40201ce10e346a025", + "0x844c6f5070a8c73fdfb3ed78d1eddca1be31192797ad53d47f98b10b74cc47a325d2bc07f6ee46f05e26cf46a6433efb", + "0x974059da7f13da3694ad33f95829eb1e95f3f3bfc35ef5ef0247547d3d8ee919926c3bd473ab8b877ff4faa07fcc8580", + "0xb6f025aecc5698f6243cc531782b760f946efebe0c79b9a09fe99de1da9986d94fa0057003d0f3631c39783e6d84c7d5", + "0xb0c5358bc9c6dfe181c5fdf853b16149536fbb70f82c3b00db8d854aefe4db26f87332c6117f017386af8b40288d08f9", + "0xa3106be5e52b63119040b167ff9874e2670bd059b924b9817c78199317deb5905ae7bff24a8ff170de54a02c34ff40a4", + "0xad846eb8953a41c37bcd80ad543955942a47953cbc8fb4d766eac5307892d34e17e5549dc14467724205255bc14e9b39", + "0xb16607e7f0f9d3636e659e907af4a086ad4731488f5703f0917c4ce71a696072a14a067db71a3d103530920e1ec50c16", + "0x8ed820e27116e60c412c608582e9bb262eaaf197197c9b7df6d62b21a28b26d49ea6c8bb77dfde821869d9b58025f939", + "0x97bc25201d98cde389dd5c0c223a6f844393b08f75d3b63326343073e467ac23aacef630ddc68545ea874299ba4a3b4f", + "0xb73c9695ad2eefd6cc989a251c433fab7d431f5e19f11d415a901762717d1004bb61e0cc4497af5a8abf2d567e59fef4", + "0xadaabe331eea932533a7cc0cf642e2a5e9d60bbc92dd2924d9b429571cbf0d62d32c207b346607a40643c6909b8727e2", + "0xa7b1bbfe2a5e9e8950c7cb4daab44a40c3ffab01dc012ed7fe445f4af47fa56d774a618fafe332ab99cac4dfb5cf4794", + "0xb4a3c454dcd5af850212e8b9ba5fe5c0d958d6b1cabbf6c6cfe3ccbc4d4c943309c18b047256867daf359006a23f3667", + "0xa5c0b32f6cef993834c1381ec57ad1b6f26ae7a8190dd26af0116e73dadc53bb0eeb1911419d609b79ce98b51fdc33bc", + "0xac2f52de3ecf4c437c06c91f35f7ac7d171121d0b16d294a317897918679f3b9db1cef3dd0f43adb6b89fe3030728415", + "0x94722ae6d328b1f8feaf6f0f78804e9b0219de85d6f14e8626c2845681841b2261d3e6a2c5b124086b7931bf89e26b46", + "0xa841a0602385d17afabca3a1bb6039167d75e5ec870fea60cfcaec4863039b4d745f1a008b40ec07bca4e42cb73f0d21", + "0x8c355f0a1886ffced584b4a002607e58ff3f130e9de827e36d38e57cb618c0cb0b2d2dea2966c461cb3a3887ede9aef1", + "0xa6a9817b0fc2fd1786f5ba1a7b3d8595310987fb8d62f50a752c6bb0b2a95b67d03a4adfd13e10aa6190a280b7ee9a67", + "0xa1d2e552581ecbafeaef08e389eaa0b600a139d446e7d0648ac5db8bbbf3c438d59497e3a2874fc692b4924b87ff2f83", + "0xa1b271c55389f25639fe043e831e2c33a8ba045e07683d1468c6edd81fedb91684e4869becfb164330451cfe699c31a8", + "0x8c263426e7f7e52f299d57d047a09b5eeb893644b86f4d149535a5046afd655a36d9e3fdb35f3201c2ccac2323a9582e", + "0xb41c242a7f7880c714241a97d56cce658ee6bcb795aec057a7b7c358d65f809eb901e0d51256826727dc0dc1d1887045", + "0x93001b9445813c82f692f94c0dc1e55298f609936b743cf7aae5ebfa86204f38833d3a73f7b67314be67c06a1de5682d", + "0x82087536dc5e78422ad631af6c64c8d44f981c195ddea07d5af9bb0e014cdc949c6fa6e42fce823e0087fdb329d50a34", + "0x8e071861ceba2737792741c031f57e0294c4892684506b7c4a0fc8b2f9a0a6b0a5635de3d1e8716c34df0194d789ae86", + "0xb471c997e1e11774bd053f15609d58838a74073a6c089a7a32c37dd3f933badf98c7e5833263f3e77bc0d156a62dd750", + "0x8d2d8686fb065b61714414bb6878fff3f9e1e303c8e02350fd79e2a7f0555ded05557628152c00166ce71c62c4d2feaa", + "0xae4c75274d21c02380730e91de2056c0262ffcecf0cbdb519f0bdb0b5a10ae2d4996b3dc4b3e16dbaea7f0c63d497fef", + "0x97140d819e8ca6330e589c6debdee77041c5a9cedb9b8cbd9c541a49207eeb7f6e6b1c7e736ec8ba6b3ab10f7fcd443a", + "0xaf6659f31f820291a160be452e64d1293aa68b5074b4c066dac169b8d01d0179139504df867dc56e2a6120354fc1f5be", + "0xa5e5d8088a368024617bfde6b731bf9eee35fc362bed3f5dfdd399e23a2495f97f17728fec99ca945b3282d1858aa338", + "0xa59cfc79d15dbdde51ab8e5129c97d3baba5a0a09272e6d2f3862370fdbaf90994e522e8bd99d6b14b3bb2e9e5545c6f", + "0xa30499b068083b28d6c7ddcc22f6b39b5ec84c8ee31c5630822c50ea736bb9dca41c265cffc6239f1c9ef2fd21476286", + "0x88ffe103eca84bbe7d1e39a1aa599a5c7c9d5533204d5c4e085402a51441bb8efb8971efe936efbbfa05e5cb0d4b8017", + "0xb202356fbf95a4d699154639e8cb03d02112c3e0128aab54d604645d8510a9ba98936028349b661672c3a4b36b9cb45d", + "0x8b89bb6574bf3524473cff1ff743abcf1406bd11fb0a72070ccd7d8fce9493b0069fb0c6655252a5164aee9e446ea772", + "0x93247b1038fa7e26667ee6446561d4882dc808d1015daafb705935ddc3598bb1433182c756465960480f7b2de391649e", + "0xb027f94d3358cbb8b6c8c227300293a0dee57bf2fee190a456ad82ecfb6c32f8090afa783e2ab16f8139805e1fb69534", + "0xa18bb1849b2f06c1d2214371031d41c76ffa803ee3aa60920d29dbf3db5fbfac2b7383d5d0080ba29ce25c7baa7c306b", + "0x827bf9fd647e238d5ac961c661e5bbf694b4c80b3af8079f94a2484cb8fba2c8cf60e472ebcd0b0024d98ae80ad2ff5a", + "0x838e891218c626a7f39b8fd546b013587408e8e366ecc636b54f97fa76f0a758bc1effa1d0f9b6b3bc1a7fcc505970a0", + "0x836523b5e8902d6e430c6a12cff01e417d2bd7b402e03904034e3b39755dee540d382778c1abe851d840d318ebedce7f", + "0x850a77dda9ac6c217e2ef00bf386a1adec18b7f462f52801c4f541215690502a77ef7519b690e22fdf54dc2109e0ca38", + "0xa8265c6ae7b29fc2bda6a2f99ced0c1945dd514b1c6ca19da84b5269514f48a4f7b2ccbab65c9107cfd5b30b26e5462f", + "0xab3d02ee1f1267e8d9d8f27cc388e218f3af728f1de811242b10e01de83471a1c8f623e282da5a284d77884d9b8cde0e", + "0x831edaf4397e22871ea5ddee1e7036bab9cc72f8d955c7d8a97f5e783f40532edbbb444d0520fefcffeab75677864644", + "0x80484487977e4877738744d67b9a35b6c96be579a9faa4a263e692295bb6e01f6e5a059181f3dd0278e2c3c24d10a451", + "0xaae65a18f28c8812617c11ecf30ad525421f31fb389b8b52d7892415e805a133f46d1feca89923f8f5b8234bd233486a", + "0xb3a36fd78979e94288b4cefed82f043a7e24a4a8025479cc7eb39591e34603048a41ee606ee03c0b5781ebe26a424399", + "0xb748b3fc0d1e12e876d626a1ba8ad6ad0c1f41ea89c3948e9f7d2666e90173eb9438027fadcd741d3ae0696bd13840f1", + "0xacdd252d7c216c470683a140a808e011c4d5f1b4e91aeb947f099c717b6a3bad6651142cde988330827eb7d19d5fb25c", + "0xb9a25556a6ca35db1ed59a1ec6f23343eab207a3146e4fc3324136e411c8dba77efd567938c63a39c2f1c676b07d8cdb", + "0xa8db6aef8f5680d2bdb415d7bcaae11de1458678dcb8c90c441d5986c44f83a9e5855662d0c1aace999172d8628d8fe1", + "0xaf58147108e9909c3a9710cc186eab598682dca4bfd22481e040b8c000593ecb22c4ede4253ac9504e964dfa95a9b150", + "0x8dd8bb70f1c9aec0fcc9478f24dfc9c3c36c0bf5ff7a67c017fa4dab2ec633fbd7bc9d8aa41ea63e2696971ed7e375f5", + "0xaa98d600b22aff993a4d7a3ccabd314e1825b200cb598f6b797d7e4d6a76d89e34a4d156c06bddfc62f2ef9b4c809d1d", + "0x8a8fc960d6c51294b8205d1dabe430bef59bda69824fa5c3c3105bef22ac77c36d2d0f38ffc95ce63731de5544ccbeff", + "0xb6d1020efe01dc8032bd1b35e622325d7b9af9dcd5c9c87c48d7d6ebc58644454294c59b7f4b209204b5b1f899f473bf", + "0x8a750dc9fe4891f2dfe5759fb985939810e4cdc0b4e243ff324b6143f87676d8cb4bcb9dfb01b550801cedcaaa5349e2", + "0x98c13142d3a9c5f8d452245c40c6dae4327dd958e0fda85255ea0f87e0bcbaa42a3a0bd50407ed2b23f9f6317a8a4bc5", + "0x99f2b83d9ec4fc46085a6d2a70fd0345df10f4a724c1ba4dee082a1fde9e642e3091992ebf5f90a731abcb6ec11f6d9b", + "0xb218546ab2db565b2489ea4205b79daa19ef2acbf772ccaaa5e40150e67ea466090d07198444b48e7109939aa2319148", + "0x84f9d1d868e4b55e535f1016558f1789df0daa0ead2d13153e02f715fe8049b1ce79f5bc1b0bbbb0b7e4dd3c04783f3f", + "0x80d870d212fbddfdda943e90d35a5a8aa0509a7a1e7f8909f2fcb09c51c3026be47cc7a22620a3063406872105b4f81a", + "0xb5b15138ff6551fac535d4bbce2ea6adc516b6b7734b4601c66ec029da2615e3119dc9ad6a937344acfd7b50e4a1a2ae", + "0x95d2f97652086e7ceb54e1d32692b1c867ffba23c4325740c7f10d369283d1b389e8afa0df967831ade55696931e7934", + "0x8a5b580403e1a99cd208f707e8ce0d3f658c8280417683f69008d09cc74d835a85f7380f391b36ead9ac66d9eedd1cbe", + "0xa8b0c90bff34c86720637b5a2081f0f144cfe2205c1176cacd87d348609bc67af68aed72414dc9aa6f44a82c92c2a890", + "0x865abbdd96c496892c165a8de0f9e73348bf24fce361d7a9048710178a3625881afb0006e9f5ee39124866b87904c904", + "0xace67bb994adef4b6f841cdf349195608030044562780a7e9b00b58a4ff117268a03ff01e5a3a9d9d7eff1dd01f5f4bf", + "0xb9371d59185b3d2d320d3fefeadb06ba2aa7d164352fb8dc37571509509fa214d736d244ac625a09a033a10d51611e2e", + "0xa8ef992771422dcf2d6d84386fde9fe5dba88bfded3dfcd14074ca04331b4fd53a7f316615cdfaf10ed932cbb424a153", + "0x868cbc75f8f789ea45eded2768a1dac0763347e0d8e8028d316a21005f17be179d26d5965903e51b037f2f57fe41765d", + "0xb607111bcdfd05fa144aa0281b13ee736079ebbbf384d938a60e5e3579639ed8ef8eb9ca184868cdb220a8e130d4a952", + "0xaca55702af5cae4cae65576769effd98858307a71b011841c563b97c2aa5aeb5c4f8645d254f631ed1582df3dbbf17da", + "0xb9b5cbace76246e80c20dfcc6f1e2c757a22ab53f7fd9ff8a1d309538b55174e55e557a13bf68f095ff6a4fa637ef21a", + "0x8571b0a96871f254e2397c9be495c76379faf347801cb946b94e63212d6a0da61c80e5d7bebbabcd6eaa7f1029172fe5", + "0x902540326281e6dc9c20d9c4deaaf6fbbbcc3d1869bd0cf7f081c0525bea33df5cfa24ead61430fda47fb964fcc7994b", + "0x841af09279d3536a666fa072278950fabf27c59fc15f79bd52acb078675f8087f657929c97b4bc761cbade0ecb955541", + "0xa1f958b147ddf80ab2c0746ba11685c4bae37eb25bfa0442e7e1078a00d5311d25499da30f6d168cb9302ea1f2e35091", + "0x863d939381db37d5a5866964be3392a70be460f0353af799d6b3ed6307176972686bd378f8ad457435a4094d27e8dfb7", + "0x835cd4d7f36eff553d17483eb6c041b14280beb82c7c69bca115929658455a1931212976c619bafb8179aed9940a8cc6", + "0x8d0770e3cb8225e39c454a1fc76954118491b59d97193c72c174ecc7613051e5aed48a534016a8cf0795c524f771a010", + "0x91aa4edb82f6f40db2b7bd4789cc08786f6996ebed3cb6f06248e4884bc949793f04a4c5ea6eefe77984b1cc2a45d699", + "0x8fb494ca2449f659ff4838833507a55500a016be9293e76598bbae0a7cb5687e4693757c2b6d76e62bd6c7f19ed080bb", + "0xb59b104449a880a282c1dd6a3d8debb1d8814ef35aab5673c1e500ee4cb0e840fb23e05fa5a0af92509c26b97f098f90", + "0xaca908e3bad65e854ae6be6c5db441a06bcd47f5abafdfa8f5a83c8cd3c6e08c33cab139c45887887a478338e19ceb9f", + "0x806f5d802040313a31964fc3eb0ee18ac91b348685bed93c13440984ee46f3d2da7194af18c63dea4196549129660a4e", + "0xae4b2dca75c28d8f23b3ab760b19d839f39ff5a3112e33cb44cff22492604a63c382b88ec67be4b0266924dd438c3183", + "0x99d1c29c6bd8bf384e79cd46e30b8f79f9cbc7d3bf980e9d6ffba048f0fc487cac45c364a8a44bb6027ad90721475482", + "0xa16e861c1af76d35528c25bf804bfc41c4e1e91b2927d07d8e96bffe3a781b4934e9d131ecf173be9399800b8269efac", + "0xa253303234fb74f5829060cdcef1d98652441ab6db7344b1e470d195a95722675988048d840201c3b98e794b1e8b037c", + "0x905ac8a0ea9ce0eb373fb0f83dd4cbe20afb45b9d21ae307846fd4757d4d891b26a6711924e081e2b8151e14a496da18", + "0xb485315791e775b9856cc5a820b10f1fa5028d5b92c2f0e003ba55134e1eddb3eb25f985f2611a2257acf3e7cfdfab5e", + "0xb6189c0458b9a043ebc500abc4d88083a3487b7ac47ed5e13ab2a41e0a1bee50d54a406063f92bc96959f19e822a89a7", + "0xa30e15f995fd099a223fc6dc30dad4b8d40bee00caa2bc3223ba6d53cd717c4968a3e90c4618c711ed37cc4cd4c56cf3", + "0xa1b1ed07fcc350bb12a09cd343768d208fc51a6b3486f0ece8f5a52f8a5810b4bc7ab75582ec0bc2770aed52f68eace5", + "0x88aa739fbae4bece147ba51a863e45d5f7203dbc3138975dc5aef1c32656feb35f014d626e0d5b3d8b1a2bda6f547509", + "0xab570f3c8eabfca325b3a2ea775ef6b0c6e6138c39d53c2310329e8fb162869fde22b0e55688de9eb63d65c37598fca3", + "0x89d274762c02158e27cb37052e296a78f2b643eb7f9ae409f8dac5c587d8b4d82be4ef7c79344a08ebec16ac4a895714", + "0x99c411d2ad531e64f06e604d44c71c7c384424498ecd0a567d31ec380727fb605af76643d0d5513dd0a8d018076dd087", + "0x80d0777fa9f79f4a0f0f937d6de277eec22b3507e2e398f44b16e11e40edf5feff55b3b07a69e95e7e3a1621add5ed58", + "0xb2430a460783f44feb6e4e342106571ef81ad36e3ddd908ec719febeb7acaf4b833de34998f83a1dab8f0137a3744c11", + "0xb8f38ccfc7279e1e30ad7cefc3ea146b0e2dff62430c50a5c72649a4f38f2bac2996124b03af2079d942b47b078cc4f8", + "0xa178a450a62f30ec2832ac13bbc48789549c64fc9d607b766f6d7998558a0e2fad007ae0148fc5747189b713f654e6ba", + "0x98c5ede296f3016f6597f7ccc5f82c88fd38ed6dc3d6da3e4a916bfd7c4c95928722a1d02534fe89387c201d70aa6fd2", + "0xa8cc5e98573705d396576e022b2ba2c3e7c7ece45cd8605cb534b511763682582299e91b4bb4100c967019d9f15bbfaf", + "0x848480ea7b7d9536e469da721236d932870b7bbee31ccf7ae31b4d98d91413f59b94a1e0d1786ee7342295aa3734969c", + "0xb88ea38f9ee432f49e09e4e013b19dff5a50b65453e17caf612155fff6622198f3cba43b2ea493a87e160935aaaf20a9", + "0x949376934a61e0ef8894339c8913b5f3b228fa0ae5c532ad99b8d783b9e4451e4588541f223d87273c0e96c0020d5372", + "0x96f90bb65ca6b476527d32c415814b9e09061648d34993f72f28fae7dc9c197e04ef979f804076d107bb218dfd9cb299", + "0xa4402da95d9942c8f26617e02a7cef0ebc4b757fac72f222a7958e554c82cc216444de93f659e4a1d643b3e55a95d526", + "0x81179cbc26a33f6d339b05ea3e1d6b9e1190bd44e94161ae36357b9cdf1e37d745d45c61735feed64371fe5384102366", + "0xad4dc22bdbd60e147fdac57d98166de37c727f090059cfc33e5ee6cf85e23c2643996b75cf1b37c63f3dc9d3c57ffa18", + "0x8a9b1b93dc56e078ce3bb61c2b0088fd6c3e303ba6b943231cc79d4a8e8572f4109bbde5f5aa7333aae3287909cb0fe2", + "0x8876ef583bc1513322457a4807d03381ba1f4d13e179260eaa3bddfede8df677b02b176c6c9f74c8e6eab0e5edee6de6", + "0xb6c67e228bf190fbaeb2b7ec34d4717ce710829c3e4964f56ebb7e64dc85058c30be08030fa87cc94f1734c5206aef5f", + "0xa00cb53b804ee9e85ce12c0103f12450d977bc54a41195819973c8a06dcb3f46f2bf83c3102db62c92c57ab4dd1e9218", + "0xa7675a64772eefddf8e94636fb7d1d28f277074327c02eea8fae88989de0c5f2dc1efed010f4992d57b5f59a0ab40d69", + "0x8d42bb915e0bf6a62bcdf2d9330eca9b64f9ec36c21ae14bf1d9b0805e5e0228b8a5872be61be8133ad06f11cb77c363", + "0xa5b134de0d76df71af3001f70e65c6d78bed571bc06bfddf40d0baad7ea2767608b1777b7ef4c836a8445949877eeb34", + "0xaeadbc771eaa5de3a353229d33ed8c66e85efbd498e5be467709cb7ff70d3f1a7640002568b0940e3abd7b2da81d2821", + "0x8c28da8e57a388007bd2620106f6226b011ee716a795c5d9f041c810edf9cf7345b2e2e7d06d8a6b6afa1ee01a5badc1", + "0x8ed070626a4d39ffd952ddb177bc68fd35b325312e7c11694c99b691f92a8ea7734aeb96cf9cc73e05b3c1b1dcad6978", + "0xada83e18e4842f3d8871881d5dbc81aed88a1328298bfdc9e28275094bd88d71b02e7b8501c380fa8d93096cbc62f4fb", + "0x8befc3bec82dcf000a94603b4a35c1950ba5d00d4bed12661e4237afa75062aa5dcef8eac0b9803136c76d2dd424a689", + "0x97c6f36c91ca5ca9230bfcbf109d813728b965a29b62e5f54c8e602d14a52ac38fa1270de8bfe1ab365426f3fc3654c7", + "0xb01d192af3d8dbce2fe2fece231449e70eb9ac194ec98e758da11ca53294a0fa8c29b1d23a5d9064b938b259ea3b4fb5", + "0x819a2c20646178f2f02865340db1c3c6ebc18f4e6559dd93aa604388796a34bd9fed28ad3ccc8afc57a5b60bb5c4e4ec", + "0xa9ffc877470afc169fecf9ec2dc33253b677371938b0c4ffa10f77bb80089afa2b4488437be90bb1bcf7586a6f4286e3", + "0xb533051c7ce7107176bcb34ad49fdb41fac32d145854d2fe0a561c200dcf242da484156177e2c8f411c3fdf1559ecf83", + "0x8fe2caff2e4241d353110a3618832f1443f7afe171fd14607009a4a0aa18509a4f1367b67913e1235ac19de15e732eb1", + "0x84705c6370619403b9f498059f9869fdf5f188d9d9231a0cb67b1da2e8c906ead51b934286497293698bba269c48aa59", + "0x899dddf312a37e3b10bdaaacc1789d71d710994b6ee2928ac982ad3fd8a4f6167672bc8bf3419412711c591afe801c28", + "0xb2f7916d946b903ded57b9d57025386143410a41a139b183b70aeca09cf43f5089ead1450fce4e6eb4fba2c8f5c5bbe5", + "0x8d5f742fe27a41623b5820914c5ca59f82246010fa974304204839880e5d0db8bc45ebab2ad19287f0de4ac6af25c09e", + "0xb93d4a1f6f73ac34da5ffbd2a4199cf1d51888bc930dc3e481b78806f454fcb700b4021af7525b108d49ebbbaa936309", + "0x8606f8d9121512e0217a70249937e5c7f35fbfe019f02248b035fa3a87d607bc23ae66d0443e26a4324f1f8e57fd6a25", + "0xb21312cdec9c2c30dd7e06e9d3151f3c1aceeb0c2f47cf9800cce41521b9d835cb501f98b410dc1d49a310fdda9bc250", + "0xa56420b64286bdddda1e212bba268e9d1ba6bdb7132484bf7f0b9e38099b94a540884079b07c501c519b0813c184f6b4", + "0x80b2cf0e010118cb2260f9c793cef136f8fa7b5e2711703735524e71d43bce2d296c093be41f2f59118cac71f1c5a2ff", + "0xadcb12d65163804d2f66b53f313f97152841c3625dbbda765e889b9937195c6fcd55d45cc48ebffabb56a5e5fe041611", + "0x8b8a42e50dc6b08ab2f69fc0f6d45e1ea3f11ba0c1008ee48448d79d1897356599e84f7f9d8a100329ed384d6787cfc4", + "0xaaa9c74afa2dec7eccfbd8bb0fc6f24ed04e74c9e2566c0755a00afdfdf3c4c7c59e2a037ec89c2f20af3fae1dd83b46", + "0xaa9f6e8fd59187171c6083ae433627d702eb78084f59010ff07aff8f821f7022ef5fbbe23d76814d811b720a8bfa6cc3", + "0xa56a3ded501659ad006d679af3287080b7ee8449e579406c2cae9706ef8bf19c1fc2eb2a6f9eaf2d3c7582cded73e477", + "0x81971e077c1da25845840222b4191e65f6d242b264af4e86800f80072d97d2a27a6adc87c3a1cb1b0dd63d233fbafa81", + "0xa6fa5453c4aaad2947969ee856616bf6448224f7c5bf578f440bcfc85a55beb40bef79df8096c4db59d1bd8ef33293ea", + "0x87c545adbfaaf71e0ab4bac9ae4e1419718f52b0060e8bb16b33db6d71b7248ae259d8dd4795b36a4bbb17f8fae9fd86", + "0xb4c7a9bc0910e905713291d549cec5309e2d6c9b5ea96954489b1dff2e490a6c8b1fa1e392232575f0a424ba94202f61", + "0x802350b761bcaba21b7afe82c8c6d36ee892b4524ab67e2161a91bbfa1d8e92e7e771efb1f22c14126218dd2cb583957", + "0xb4e7ddb9143d4d78ea8ea54f1c908879877d3c96ee8b5e1cb738949dcfceb3012a464506d8ae97aa99ea1de2abf34e3d", + "0xa49a214065c512ad5b7cc45154657a206ef3979aa753b352f8b334411f096d28fd42bca17e57d4baaafb014ac798fc10", + "0x8a80c70a06792678a97fe307520c0bf8ed3669f2617308752a2ab3c76fdf3726b014335a9b4c9cbcfc1df3b9e983c56f", + "0xa34721d9e2a0e4d08995a9d986dc9c266c766296d8d85e7b954651ad2ca07e55abb1b215898ee300da9b67114b036e0d", + "0x8cfce4564a526d7dca31e013e0531a9510b63845bbbd868d5783875ed45f92c1c369ce4a01d9d541f55f83c2c0a94f03", + "0xab3f5f03a5afc727778eb3edf70e4249061810eba06dc3b96b718e194c89429c5bfbec4b06f8bce8a2118a2fdce67b59", + "0xaa80c2529fc19d428342c894d4a30cb876169b1a2df81a723ab313a071cba28321de3511a4de7846207e916b395abcc9", + "0x82b7828249bf535ef24547d6618164b3f72691c17ca1268a5ee9052dba0db2fdd9987c8e083307a54399eab11b0f76b1", + "0x8fbcb56b687adad8655a6cf43364a18a434bf635e60512fad2c435cf046f914228fb314f7d8d24d7e5e774fb5ffb1735", + "0xa3010a61a2642f5ebbce7b4bc5d6ecb3df98722a49eb1655fe43c1d4b08f11dfad4bcec3e3f162d4cc7af6a504f4d47c", + "0xb3dcc0fdf531478e7c9ef53190aa5607fd053a7d2af6c24a15d74c279dbb47e3c803a1c6517d7e45d6534bb59e3527f5", + "0x8648f6316c898baaca534dff577c38e046b8dfa8f5a14ee7c7bc95d93ae42aa7794ba0f95688a13b554eeb58aeedf9ba", + "0x89fca6fc50407695e9315483b24f8b4e75936edf1475bcf609eed1c4370819abac0e6a7c3c44f669560367d805d9ba63", + "0xa367a17db374f34cd50f66fb31ba5b7de9dbe040f23db2dcc1d6811c0e863606f6c51850af203956f3399000f284d05f", + "0x91030f9ca0fff3e2dbd5947dcf2eba95eb3dbca92ee2df0ed83a1f73dbf274611af7daf1bb0c5c2ee46893ab87013771", + "0x84d56181f304ce94015ea575afeef1f84ea0c5dbb5d29fb41f25c7f26077b1a495aff74bd713b83bce48c62d7c36e42d", + "0x8fe2f84f178739c3e2a2f7dcac5351c52cbed5fa30255c29b9ae603ffd0c1a181da7fb5da40a4a39eec6ce971c328fcf", + "0xa6f9b77b2fdf0b9ee98cb6ff61073260b134eb7a428e14154b3aa34f57628e8980c03664c20f65becfe50d2bdd2751d4", + "0x8c6760865445b9327c34d2a1247583694fbeb876055a6a0a9e5cb460e35d0b2c419e7b14768f1cc388a6468c94fd0a0f", + "0xaf0350672488a96fe0089d633311ac308978a2b891b6dbb40a73882f1bda7381a1a24a03e115ead2937bf9dcd80572ad", + "0xa8e528ec2ee78389dd31d8280e07c3fdd84d49556a0969d9d5c134d9a55cd79e1d65463367b9512389f125ed956bc36a", + "0x942c66589b24f93e81fe3a3be3db0cd4d15a93fb75260b1f7419f58d66afaa57c8d2d8e6571536790e2b415eec348fd9", + "0x83fe4184b4b277d8bf65fb747b3c944170824b5832751057e43465526560f60da6e5bbee2f183cb20b896a20197168c7", + "0x88a71aada494e22c48db673d9e203eef7a4e551d25063b126017066c7c241ee82bedaa35741de4bd78a3dd8e21a8af44", + "0x8c642a3186ca264aac16ee5e27bd8da7e40e9c67ae159b5d32daa87b7de394bf2d7e80e7efb1a5506c53bfd6edd8c2c3", + "0x81855d6de9a59cef51bef12c72f07f1e0e8fe324fcc7ec3f850a532e96dcd434c247130610aaee413956f56b31cbb0dc", + "0xa01e61390dcd56a58ad2fcdb3275704ddfbedef3ba8b7c5fce4814a6cdd03d19d985dba6fd3383d4db089444ea9b9b4d", + "0x96494e89cbf3f9b69488a875434302000c2c49b5d07e5ff048a5b4a8147c98291ae222529b61bb66f1903b2e988e5425", + "0xb9689b3e8dddc6ec9d5c42ba9877f02c1779b2c912bba5183778dc2f022b49aed21c61c8ec7e3c02d74fe3f020a15986", + "0xa2a85e213b80b0511395da318cbb9935c87b82c305f717a264155a28a2ea204e9e726bae04ce6f012e331bd6730cbb9d", + "0x91b70f44c7d8c5980ce77e9033a34b05781cbe773854d3f49d2905cc711a3d87c20d5d496801ad6fd82438874ce732b8", + "0x884596417ff741bb4d11925d73852ffeea7161c7f232be3bdce9e6bbe7884c3a784f8f1807356ae49d336b7b53a2b495", + "0xae2aed8ab6951d8d768789f5bc5d638838d290d33ccc152edfb123e88ba04c6272b44294b0c460880451ad7b3868cc6a", + "0x89d8ebfb9beebc77189d27de31c55f823da87798a50bca21622cbf871e5d9f1d3182cf32ee9b90f157e6ce298e9efccf", + "0xafd00a4db4c2ed93cf047378c9402914b6b3255779f3bb47ded4ab206acb7eaebba0fd7762928e681b1aebcfee994adc", + "0xa2e49b6cd32e95d141ebc29f8c0b398bb5e1a04945f09e7e30a4062142111cd7aa712ac0e3e6394cfb73dd854f41ad77", + "0xae8e714ab6e01812a4de5828d84060f626358bb2b955f6fb99ae887b0d5ce4f67ebc079ab9e27d189bf1d3f24f7c2014", + "0xa3100c1eebf46d604e75ebf78569c25acf938d112b29ccbe1a91582f6bd8ef5548ae3961c808d3fb73936ac244e28dbc", + "0xa9a02dcff0e93d47ead9cdddc4759971c2d848580bf50e117eb100cafca6afeaa7b87208513d5f96b1e1440ffc1b0212", + "0x894ab01462137e1b0db7b84920a3b677fbb46c52b6f4c15320ef64f985e0fc05cec84cd48f389ce039779d5376966ea3", + "0xb1e40e8399ee793e5f501c9c43bde23538e3ce473c20a9f914f4a64f5b565748d13ab2406efe40a048965ee4476113e4", + "0xa5a7d97a19e636238968670a916d007bf2ce6ae8e352345d274101d0bbe3ac9b898f5b85814a7e4c433dd22ac2e000ff", + "0xb6394c43b82923231d93fd0aa8124b757163ba62df369898b9481f0118cb85375d0caac979a198ece432dbb4eb7cc357", + "0x82d522ae3ff4fe2c607b34b42af6f39c0cf96fcfe1f5b1812fca21c8d20cece78376da86dcbd6cdb140e23c93ae0bcb2", + "0xb6e0d986383bc4955508d35af92f2993e7e89db745f4525948c5274cfd500880cb5a9d58a5b13d96f6368bb266a4433e", + "0xb0b4325772ec156571d740c404e1add233fb693579f653b0fae0042b03157d3b904838f05c321d2d30f2dbd27c4d08ad", + "0xac41367250263a2099006ef80c30bac1d2f25731d4874be623b6e315c45b0dc9a65f530fce82fb3dc25bd0610008c760", + "0xb6c0b1ed7df53da04a6f3e796d3bfa186f9551c523bc67898bc0ecfc6b4a4a22f8c4d3bfc740ebf7b9fa5b0ea9431808", + "0x8e78fca17346601219d01e5cd6a4837161a7c8f86fe2a8d93574d8006da5f06ae7c48eea7d2b70992c2a69184619663c", + "0xa21f91f47e04fafbfafacf3185b6863766a2d0c324ccac2c3853a4748af5897dbbe31d91473b480f646121339c9bae2d", + "0xa464d68786ab1fc64bd8734fce0be6fbe8dc021d3e771ff492ada76eedff466577c25e282b7c8ab4c1fd95ef5ff3631e", + "0x829a24badc7714081e03509ccfb00818ce40430682c1c0e4a399cd10b690bda1f921aabcbf1edfb1d8a2e98e6c0cedd6", + "0x87ccf7e4bbcb818ef525435e7a7f039ecbb9c6670b0af163173da38cbdb07f18bc0b40b7e0c771a74e5a4bc8f12dfe2c", + "0x94087bd2af9dbeb449eb7f014cfbf3ee4348c0f47cde7dc0ad401a3c18481a8a33b89322227dee0822244965ae5a2abb", + "0x896b83ed78724dac8a3d5a75a99de8e056a083690152c303326aa833618b93ef9ec19ab8c6ef0efe9da2dbcccac54431", + "0x821e6a0d7ccf3c7bd6a6cc67cde6c5b92fb96542cb6b4e65a44bbc90bbc40c51ff9e04702cb69dd2452f39a2ff562898", + "0xb35b2096cda729090663a49cb09656c019fef1fc69a88496028d3a258ad2b3fd6d91ab832163eaa0077989f647e85e7e", + "0xb7857ef62c56d8bce62476cdb2ab965eddff24d932e20fc992bd820598686defe6cc0a7232d2be342696c2990d80721a", + "0xb343d974dfda3f6589043acd25d53aecf7c34b1e980ae135a55cda554ff55e531bc7c2dfe89b0d2c30e523c7b065dad1", + "0x8d139e16a73cd892b75f3f4e445a10d55d1118f8eeafc75b259d098338419e72e950df6ca49cb45677a3c4e16fb19cdc", + "0x817b8535bd759da392b2c5760c51b3952ecf663662a137c997f595c533cd561ed7e655673c11144242160e41d1f2dd71", + "0x817ee0f0819b0ccb794df17982d5b4332abff5fec5e23b69579db2767855642156d9b9acccf6ceab43332ccc8d2744dc", + "0x9835d2b652aec9b0eba0c8e3b6169567e257a6a3f274ec705dbc250ee63f0f8e4b342e47b9e0c280c778208483d47af8", + "0xb78c40177f54f0e6d03083a4f50d8e56b5aafdb90f1b047bb504777d6e27be5a58170330aee12fbaa5f1e9d4f944acfc", + "0xab8eebacf3806fac7ab951f6a9f3695545e2e3b839ca399a4ef360a73e77f089bb53d3d31dbd84ddfde55e5f013626e0", + "0x96c411fc6aecca39d07d2aff44d94b40814d8cfc4ee5a192fd23b54589b2801694d820a0dd217e44863ccff31dda891b", + "0x8249c424a0caf87d4f7ff255950bbc64064d4d1b093324bfe99583e8457c1f50e6996e3517bf281aa9b252c2a7c5a83a", + "0xacf6ed86121821a3dd63f3875b185c5ebe024bdb37878c8a8d558943d36db0616545a60db90789c0925295f45d021225", + "0xa37f155621a789f774dd13e57016b8e91b3a2512b5c75377ec8871b22a66db99655d101f57acaecd93115297caabfc21", + "0x92e60ee245bd4d349f1c656e034b1a7f0c6415a39ac4c54d383112734305488b3b90b0145024255735e0a32f38dba656", + "0xacec614e562ccfc93366309cfdc78c7d7ee0a23e3a7782a4fc4807b8803e6ebfb894a489d03e9a3c817ff2ec14813eba", + "0xb912f9dd26ed552cb14b007b893e6ed2494d12517e5761dbeb88521270144f8c3eb9571a0ad444b30a8a65e80bd95996", + "0x8375408dae79c547a29e9a9e5d4ec8241b36b82e45e4ca3b0c36d2227c02d17bb171528d3778eac3bbdc75d6c4e8a367", + "0x8c2d0e6e4406836da112edbbb63996408bb3cda4a2712fd245e4bb29a0100fdc89a2746d859b84a94565bc1cfa681813", + "0xa7431bf59e111c072d28c97626cd54fcdf018421d053a787d2aef454b91251ee8ff9d3702d06b088f92b9ad2bbebff15", + "0x8f3659b0fbeb90b7f30b7a49233325e806551a32911a654dca86e290b314483bbb33fe6482387bc48c35d85c1dd0441c", + "0x8dca5ba23f0bb76f7dacabf12886053552ba829a72827b472a2f01e19a893155cdce65f1fb670000f43e8c75ba015a31", + "0x8c1514c083c77624eeb5d995d60994a2866192e15c4474d0be4189fae0e9dbd62494ebb4c02fbc176b53be548abbc5a1", + "0x80498d2ed153381baf3b0f81da839ed0eea6af5796c422b8e59be805dba48c4395bb97824ac308170bb4f14f319c5ddf", + "0x84f5ebc3bf96362457993e9fa31493c31c4283075e2403f63d581b6b0db8a3df294b2085643f2007f4de38cb5d627776", + "0x958e6e38774da518193a98397978dbc73d1c3827b4996ec00b4183da2c305a187a0ada9aa306242814b229a395be83c9", + "0xab8b8fbf73845615e7fab3e09e96cc181159eab09f36b4c1239b3c03313c9aeb4bbb51e16316fe338b2319ed2571b810", + "0x977e4e33b33bd53394e591eba4f9a183e13704c61e467d74b28f4ad0b69aa51501a5221cb1e0e42bcb548ca518caa619", + "0xa9bb7ecb9846cc30d04aad56d253c3df7004cebb272f6adf7b40a84adef9f57291e0d08d64c961b9fc406cdb198aab9b", + "0x8d2b72dc36406a545a9da44e1fddfb953d4894710ca026d6421a4ac91e02d0373a599f2acfe41d8258bc9679cf6f43d3", + "0x904192fc8fe250f61ecb8a36abbbccae85f592bbf00c10039c30b5a1c733d752a04e4fd8a1000c6578616f8a16aa83a3", + "0x87f5fdfe20bbbf931b529ec9be77bbfcc398cad9d932d29f62c846e08a91d2f47ae56ad5345122d62a56f629f9a76c4d", + "0x84cc3a53b2e7b7e03015f796b6cb7c32d6ded95c5b49c233ac27fafa792994b43c93cda6e618b66fce381f3db69838ba", + "0xaab58da10d7bbe091788988d43d66a335644f3d0897bbc98df27dcc0c0fcee0ac72e24f1abdd77e25196a1d0d0728e98", + "0xa10ea8677c2b7da563d84aa91a314a54cab27bb417c257826ebdd3b045d2a0f12729fe630bbbf785d04874f99f26bee8", + "0xacc4970ef2a4435937a9b8a5a5a311226ca188d8f26af1adfcd6efb2376a59155b9a9ff1cff591bde4b684887d5da6e5", + "0x8dc7cf6fcca483c44eb55e7fb924bf3f76cf79b411ae4b01c6c968910877ac9c166b71350f4d935f19bdffb056477961", + "0xac2dd1182ded2054c2f4dbf27b71a0b517fb57193733a4e4e56aca8a069cff5078ffd3fd033683d076c1c639a4de63c7", + "0x932ec87c450cd0dc678daf8c63cd1bf46124fa472934e517fbbfb78199f288ff7f354b36e0cc6c8739d3f496cfe0913b", + "0xb0d631ced213e8492be60ea334dbe3b7799b86d85d5e8e70d02beef3ae87b1d76e1df3bdb5f7ba8a41904c96f6a64455", + "0x929d7239ead7575867e26b536b8badf2e11ca37840034d0e5c77039f8cce122eff5a1bf6e0bcadde6b3858e9f483d475", + "0xaaae5d372d02ee25b14de585af6fbc48f2c7cd2a6af4f08352951b45aa469599eff41e820df642ca1a0f881120e89dbe", + "0xb23c411741a6b059f04fa4f5fd9dd10e2a64915f2de6ea31e39c32f2f347a776a953320e5f7613fcb1167efe502f5c5c", + "0xa4581b0ae633fe29c6f09928e5efb16db019eeac57f79fef2fa1d3c9bee42ce0e852bc60b9d0133265373747e52a67a4", + "0x81b33afffd7b2575d4a9a1c5dd6eee675c084f82e06b9b3a52a3c9f76e087f12dca6e0ffddc42fb81ce1adb559d47a38", + "0x89cc890f06b424591556aabdfdbb36d7a23700425e90c9cfed7d3da226b4debe414ac5bdf175273828ce6c5355712514", + "0xa4399438be75cfae2bf825496704da5ed9001bed8538d8ac346c8cf0d4407808e9ee67573eb95fe1c6872ac21f639aaa", + "0xad537f7ce74a1ca9a46fc06f15c1c8a6c32363bd6ac78a3c579ed8f84252e38a914cac16709fe65360e822ef47896de4", + "0x8e53b69f5e3e86b86299452e20ea8068b49565d0d0ab5d50ce00158a18403ae44e1b078a3cfd3f919aa81eb049a30c6e", + "0xa59f2542c67a430fd3526215c60c02353ee18af2ff87cb6231a2564fe59b8efec421f18d8b8cc7f084675ecf57b3fd05", + "0xb8d9bac93ef56cb4026dd1c731d92260a608fd55b8321e39166678e1dab834d0efddb717685da87786caeb1aaf258089", + "0xaa2df56f4c6fe9e0f899116c37302675f796a1608338700f05a13e779eb7cf278e01947864a8c2c74cc9d9a763804446", + "0xb0108ff2e327dcb6982961232bf7a9a0356d4297902f4b38d380ff1b954bfbcae0093df0f133dd9e84d5966c7b1aada7", + "0xb06b813b01fe7f8cf05b79dc95006f0c01d73101583d456278d71cd78638df2b1115897072b20947943fa263ddab0cd6", + "0xaa41e6c4d50da8abf0ea3c3901412fe9c9dff885383e2c0c0c50ed2f770ada888a27ea08bbb5342b5ff402e7b1230f12", + "0xa48635dbb7debac10cb93d422c2910e5358ba0c584b73f9845028af4a763fd20da8f928b54b27782b27ca47e631ebf38", + "0x80a574c208e994799e4fa9ef895163f33153bc6487491d817c4049e376054c641c4717bda8efbeb09152fa421a7268a7", + "0xb592bfd78ae228afc219c186589b9b0b5c571e314976d1ed5c1642db9159d577679a73c049cfc3dcfefcd5a4f174eeea", + "0xaa1f08af3918c61eadf567a5b1a3cdcdfb1b925f23f1f9e3c47889762f4d979d64686ce1ce990055ef8c1030d98daa3b", + "0x857df4cfd56d41c6d0c7fcc1c657e83c888253bae58d33b86e0803a37461be5a57140a77fb4b61108d1d8565091ada1c", + "0x8fae66a72361df509d253012a94160d84d0b2260822c788927d32fd3c89500500908c8f850ef70df68ddaeb077fd0820", + "0xaa1dbefc9aef1e7b896ff7303837053c63cfb5c8a3d8204680d3228ac16c23636748fe59286468c99699ae668e769a0c", + "0xb64b1cb2ba28665ed10bad1dddc42f3f97383c39bad463c6615b527302e2aaf93eb6062946d2150bd41c329697d101be", + "0xb6d35e3b524186e9065cee73ea17c082feff1811b5ab5519dd7991cdff2f397e3a79655969755309bd08c7d5a66f5d78", + "0xa4dae7f584270743bbba8bb633bdb8bc4dcc43580e53d3e9e509ff6c327e384f14104b5bdfe5c662dc6568806950da37", + "0xaae84d3d9ad4e237b07c199813a42ed2af3bf641339c342d9abf7ebec29b5bd06249c4488ce5c9277d87f7b71b3ddd37", + "0xb82a463cf643821618a058bddf9f2acb34ac86a8de42a0fa18c9626e51c20351d27a9575398a31227e21e291b0da183e", + "0x8b6c921e8707aded3ea693f490322971b1a7f64786ef071bc9826c73a06bd8ae6bf21bc980425769627b529d30b253ce", + "0x80724937b27fc50f033c11c50835c632369f0905f413b1713a2b0a2274bec5d7a30438e94193d479ba6679dbe09a65ef", + "0xa1d9b259a2ca9cff8af6678b3af0a290c2f51e9cf26d5fe3c6a4fa3d28cbf33cb709b7f78b4f61cb9419427983c61925", + "0x96a3e69a5ed7a98ce59c4481f2ffb75be9542122ad0eb4952c84d4536760df217854d4ec561ce2f4a79d3793c22fa4f4", + "0x990c4d9a4a22d63a8976d34833cafc35936b165f04aed3504e9b435f0de1be4c83b097bbaa062483cf3dee3833b4f5b6", + "0xb9bf5e4b270aec4a0dc219457b5fed984b548892c4b700482525ba1a7df19284464f841dab94abfabcaa9a7b7a757484", + "0xacaecf49cb4786d17cf867d7a93bd4ffee0781766e11b5c1b29089ae0024c859d11b45828fbff5330b888543264d74a9", + "0xb0e1a0865b1e6f9e4a0e31d0c885526ac06678acc526fda5124742a2c303bd0e8871a0cb7951ec8ed9540fc247c8d844", + "0x82b3d327b3d1a631758451e12870816956cd0cef91fcf313a90dd533d5291193a0ff3cc447054564ce68c9b027a7ffd7", + "0xa2843602abb98f0f83e000f3415039788da1e9a096bfe8fed6b99bab96df948c814560424ffebe755cb72f40436fb590", + "0xab1c7b43cf838798d1e314bc26e04fc021e99a7bfbfc8ffde62fa8d7f92139de86a377289d5177021154229de01ede15", + "0x95e5cf5dd87ae3aed41b03c6c55f9dfad38dc126b17e7e587c156f7745c8da0bd1d60acb718fc1a03b61344f01e3de4d", + "0x86f021a3762bb47167f80d4ef1b1c873a91fe83409f9704f192efeebbc3ece0729cd2f92f63419907ea38ae47bc907d2", + "0xaaa1445dafbbcd645d4332d9806225e9346ee5ac6b22ad45e8922134fe12f3d433f567a6a4c19efdd9d5775a7de1e92f", + "0x8fd7e15688eef75df7b8bca3d61bc9fca4f56e047cdb6d0b864e7d1c4966eac27d6094b0c8482b49739f83ec51050198", + "0x80aab8b4d394eb011d4ec6a4c2815617308c9b847c6fa6a3d7e6af1c79420ef6ff2a13934a398581c40ee4cf1cac02ac", + "0x8970b97ac076a1d8a321ce00eada0edf974a46bf3cc26f6854e4218cdfc8d2b0c32199d9658f254b4fbae5a2c5535f41", + "0xa1aa2ec5b03df0a630e73dd048680ed6d3032c324941423f45cd1f16038789e5e75b876a13948732e9079a422f66a9fc", + "0xb5fe5f5e2f2ae2beeb8e95859a02fc45f01f9fb0ebb2bd8ec9ec976b3e806228821a9775096d341d662bc536c4d89452", + "0xa2bc1f170b62d0d5788b02391337b2ab157c38e725694e80aeead7383e05599be0e2f0fa27ef05db007061809356e147", + "0xa8a69701d4a8d0d972390e9f831fd8e9f424b2c2ef069e56bd763e9e835b3ce5f7cf5de5e5c297c06ace4aa74df1067c", + "0xb43d551af4ff3873557efe3f3fb98e5ede9008492f181f4796dd1a6bcda8b9445c155e8146966baa812afae1abe06b48", + "0xb4b1dae44fd596813f30602ab20e9b1fb20cb1bd650daacc97b7e054e5c0178b8131d439a9e5b142ca483cc012a362b3", + "0xb95b8a94c30a831eaaebea98c65cc5d0228c78afd6603d4aa426d8186aecc951f1a11c33951f51df04c7e6fa43ffb5ae", + "0xb100059624cf9db371bec80013a57a8f296d006c139a8766308f1ea821c7eccc26cad65bc640ab3f6cef9062653bf17d", + "0x8e5a2cb76716e0000d13bce5ef87acac307362a6096f090f5f64e5c5c71a10fddfdee8435e7166ba8c3ad8c3f540f3e4", + "0x93d2c43e21588c1e83c4255c52604b4ac3f40e656352d1827e95dd5222a45aebff9674e34fbbe7ed21eca77bd9b8dcbc", + "0x8aeaed611546bb9073b07512a9a1f38a7f436ab45e11775a0f9754baaf63e9bcc7bb59b47546a5ded5e4ba2f698e3b5f", + "0xaf9e6792e74a1163fe27612f999a2f3cfa9048914c5bef69e3b2a75162bb0ce6ece81af699ad7f0c5278a8df0ba000d2", + "0x850bf2d5d34791c371a36404036ad6fdcd8fb62d1bb17a57e88bda7a78ea322397ce24d1abf4d0c89b9cf0b4cc42feb3", + "0x87f7e2a1625e2b7861b11d593aaac933ed08a7c768aebd00a45d893ed295bbb6ed865037b152bb574d70be006ddc1791", + "0x8dcce8f4ad163b29a2348ea15431c2c6ea1189ece88d2790e9f46b9125bd790b22503ec391bc2dee8f35419863b2c50c", + "0xb4bf5266c37f12421dd684b29517982d5e4b65dfdfba5fc7bd7479fd854aabf250627498f1e1188a51c0a88d848ec951", + "0x8651623c690247f747af8fdffdc3e5f73d0662bc3279fa2423a3c654af9b6433b9e5e0155f1ce53857e67388e7e3401d", + "0xb155120f196d52760129dde2e2b1990039b99484cdc948fa98095cd23da87679850f522e5955eae34ac267d2144160d3", + "0xaec8115e8d7b6601fbceeccf92e35845a06706d46acd188452c9f7d49abef14c6b3a9a9369a8bab2fd4eb9288e2aaca5", + "0x998a8ca4dc0f145f67a8c456f1d6a7323c4836fe036dcbb0f27eb1c596d121eb97369638a9908cfaf218c7706f266245", + "0xb235fbafac62802742ee3d26b1f4e887f7d2da4d711ba7f9bb6ca024de7beec1de66bb830ce96d69538f7dcb93c51b26", + "0x9258d2ddc21ab4e3edcde7eb7f6a382a29f1b626003cc6fdd8858be90f4ad13240072d8a8d44ef8de51ca4f477fa6c45", + "0x99d038487821c948142c678acd8c792960993dd8cb5e02cb229153a1ee9f88249f4ad9007f08e5d82e2a71fb96bb5f32", + "0xa88ee9dbc73d3d8e0f447b76fdb3a27936bde479a58d5799176885583dc93830ac58bca9087075950ea75100cf51af23", + "0x88b9b15816e5a0387153c1f4b90f613beb3ea4596037da01a81fdd2bcbd0baf5598db99f77e7694e5a0d35e822758108", + "0x907ae4b637d06b15846ee27d08c9c9af42df261c5bdd10cf5bc71f8e5ca34b33ac2405307023c50bdb8dc7b98a2cd5fe", + "0x9393d6900e1d2d1a1e42412fefd99578d9ac1d855c90a3e7930a739085496448609d674ca9b34016ad91f22d1cac538e", + "0xa28ac56b216730b7dcdb5ab3fc22d424c21a677db99a9897a89ed253ea83acfd9d83125133f5be6d9cd92298df110af8", + "0xb027590ee8766f1e352f831fda732adbaf77152485223ad5489ef3b0ce2d2e9f98d547c111fe133847ebb738987fb928", + "0xa9cc08fbd5c3fee8f77cf6eb996a5cafa195df5134dab000e4d0312f970a5577942ee89794e618074f49841f1f933a42", + "0xa8b3535c3df0b1a409d3fc740527ee7dd5ac21756115cde6f87f98cc7623f50cfcf16790689cab113ee7c35a5bd4879f", + "0xb61420227b97e5603ae8a716c6759b619f02b8fdc48acbf854352aa6519dad74b97bacc1723ca564cbf3ca48539ed773", + "0x853762498de80eebf955a6c8ddd259af463e4e25f0b6ba7b6a27b19bdbf4c585de55760a16e2d9345cdba6b2a02610f3", + "0xa711c1b13fc6c30745203c5d06390e6c82bd7c50f61734aa8d99c626faba30119bc910be63ec916c91ba53f8483c05a8", + "0xb488c0a793f4481f46b5875d96eecd73e46209a91677769f0890c5e002ecd7d4b1c9f4ba68c47fbed40e3857b1d8717a", + "0xa651c5e812ae65b1c66d92c607e80be330737ea49c1dcfe019c0ecea0f41a320406935bb09206a4abff0d1c24599b9ad", + "0x85e34e7d96e4b97db98a43247b6c244383b11ca10bf4777364acf509a6faa618bc973e2136a4693fbc8ab597e308fd5a", + "0x99837214102b394fffa7f3883759554c6bb7a070f5c809303595a44195e02b9a169460dc6bbffb62bdc0e7ced5f0a5c1", + "0xa952f89c0afb4bdae8c62b89cc3cfb60d0576ba4fe01a5d99534792f38d8848d919b3fc7577435d8443a044d2ee0bcfa", + "0xa1ac1f81acb29798acdfc493854663519e2d1b0e9d23d286ce33882c34b4c1c0bb43dd9638166d8026315a44d9ec92a8", + "0xac9c58aa38219ae659d23007cc7b97fd25b7b610b2d81a8f9f94ddb089efc49c049a8ea4c56e6eaf7b6498f422a97b3c", + "0x87e61d501c242b484fb9a937ef21d485f6678d75257fc8fe831b528979068cadbe7e12b49c34058ec96d70a9d179ab14", + "0xaa45f6852f35cc8b65a4a8b5380641d2602a4fa4e3a035db9664df3ac2e170b1280c4a8b7b55161430063e54de4158a6", + "0xa46975614ddde6d134753c8d82c381966f87203d6e5a5fb99a93b0d43aa461466b37f07b8d0973a1abd6ee2b40f24348", + "0x8d35f97297773422351f4d99564c1359ef1a10cfb60aa0e6c8985a78f39b4268486312c8ebf9dd2ef50a771aa03158eb", + "0x8497c6242102d21e8b3ade9a9896c96308ab39171ab74cbd94e304c47598e2c2a7b0a0822492ac5c076ba91d4176481d", + "0x973f8fcb5f26915b3a3ef6fe58cc44bc7f4e115cd0ad9727d8d1b8113e126ae2e253a19922c5433be4ab2311a839c214", + "0xae3ee9f1d765a9baf54b4617a289c3b24930aa8d57658a6b0b113bbf9b000c4a78499296c6f428bbb64755dfd4f795d2", + "0xa5be7a8e522ef3dcf9d2951220faf22bb865d050f4af2880b8483222ff7aad7c0866219fcc573df9d829c6efbb517f98", + "0xa5f3c7fabd7853a57695c5ad6d5b99167d08b5414e35ed1068ae386e0cb1ee2afbbe4d2b9024379b6fc3b10c39024d36", + "0x978d5592d4798c9e6baceff095413589461267d6a5b56cd558ec85011342da16f4365d879b905168256f61d36d891b1f", + "0xb7b6eaffa095ecbd76d6e1e88ceebabaf674d9ef7e331e875c6d9b9faa1762c800ff1ea597c214c28080f67a50a96c1e", + "0x8a1ab53ae5ceaa42e06e58dd8faf6c215fc09ba111ca9eeb800612334d30d5971448be90fec62ed194328aadd8c8eecc", + "0xa9ca532cac8ace9a9e845382f8a7840bf40cb426f2fcad8a2f40aadbb400b3a74021627cc9351b0966b841b30284962e", + "0x8dddeda8854c8e7ddc52676dd1d0fed1da610ed5415ddd7d25b835bd8420a6f83d7b67ec682270c9648b2e2186343591", + "0x888906aac64fd41d5c518a832d4e044fdc430cfe142fd431caf4676cafc58853ce576f098910d729011be0a9d50d67b5", + "0x96a3f886a2824e750b1e2ea5c587132f52a0c5e3ff192260d8783c666206bd8ebd539933816d7cdd97e4bc374e0b1edf", + "0xa150a29ffb2632cc7ec560983d9804cd6da3596c0c25956d27eb04776508eae809659fc883834269437871735de5f9ed", + "0x81f7ad4d2959d9d4009d1dfbc6fee38f930f163eb5eac11e98dc38bd2f7f224e3f5c767583f8e52d58d34f3417a6cf90", + "0x97ccac905ea7d9c6349132dd0397b6a2de9e57fd2d70f55e50860e019de15c20171a50b28a5c00ef90d43b838253b3d1", + "0x95694f00c21e8a205d6cbda09956b5b6ec9242ec8c799a91f515b07dcc7de3b6f573e2c0ba149f5a83700cda2d1df0f5", + "0x82bbc3c4a3b3997584903db30fffd182a266c7d1df3e913f908d5a53122fa12cf5acd11d915d85d5bd110fcc43cee736", + "0x8d3f24b4949aa1b4162c28dfbb9f813dd1d8b330f71325448dc45ea34d59b69ca95059402aae011e1b5aba6e536bc6ec", + "0x92c734c19752d24782331e74c9af97a8399ddfdd32954e91cda7363dba876aca4f730b451c50a8913950420682da8121", + "0x8653d2c79f77b8c7dcdf7e8dee42433998aeedf1b583abfca686d47a854de1b75e9a4351580c96d1a2a9532659203361", + "0x886f0e414cb558c1a534a1916d3531320a9b6024639712ffe18164ce6313993a553e2b9aafe9c0716318f81a5d0bb1da", + "0xb31b5efaba5a5020c3bcea0f54860e0688c2c3f27b9b0e44b45d745158f484e474d5d3b1a0044dd6753c7fb4bf8ace34", + "0xb2d615bbdfdc042d6f67a6170127392d99f0e77ae17b0e1be6786ff2f281795f1bf11f83f2e0f8723b5cdd1db1856e09", + "0xa6e014cca531e6ac2922239b5bee39d69d9ba6d0fa96a4b812217dd342657d35606f0b9c5a317efd423cdb1047815e3d", + "0xa8921736b69c9fbb29f443715174bac753e908251804620c542fad6cfbfda7bdfe287f2902f30b043a8a4b4818cfdeef", + "0x8d73a9949a042ec2dcefa476e454cd9877eee543b1a6b3b96a78ffcff87421e8b26dd54d5b3192ac32073cb36497acc3", + "0xb936a71ee8df0e48867f3790adf55dc8efc6585024128de2495f8873bd00fd9fa0984472125e801ed9c3cdce6698f160", + "0x82f69c06209c28f64874e850601dda56af44ffc864f42efa8f9c6a0758207bf0a00f583840982dec0a517ab899a98e5b", + "0xb7a0a14411101473406f30e82f14b13e6efc9699e7193c0be04bb43d1b49e8c54812ce0f9b39131a20379c4c39d3bbe3", + "0x81159c969f38107af3b858d7582b22925a7ccced02fae3698482d7e9cdc6c568e959651991c6cf16c53a997442054b61", + "0x8bf1116a206e0ce9199fcab6ed2b44a9e46e8143bff3ed3f1431f8d55508fe2728b8902670cfd8d9b316f575f288ed9d", + "0xa279b2149824b64144eb92f5a36b22036d34a52bd5a66e5da4b61fbc95af6eda8e485c7914f448abd8674fc14d268d9d", + "0x8b98279b5f3588d1a2f8589d2756458690a502728800f8d94b28e00df842a101c96ab9c5aee87c5bbe65552c0c383b80", + "0xb4a27a351ec54420f94e0a0a79d7c7a7337940399646631baca93eeab5fd429d7fb39428be77dcbce64a13eaa3c8ca1d", + "0x90c08baa29ec8338ffce381eae3d23ce3f6ba54e5242dec21dc3caaed69cac13f2ab5e8d9d719bc95720fa182eee399c", + "0x85156d65bb4fef69ffd539ab918b3286105ca6f1c36a74351ab3310b339727483433e8f8784791f47b4ba35ca933c379", + "0x923005013c27209d07c06a6b92b0cbb248a69c5e15c600bbcc643e8dcd2402adebd94dd4cafb44ec422a127e9780aaec", + "0x863b23eb5463a6ef5a12039edc2f8e18e3c97b244841bc50af02459b1bcc558367edf2f6e4fe69f45f37887469dd536d", + "0x87a4a7708a112724ff9b69ebb25d623b5cae362ae0946daed2ec80e917800dbfcd69f999c253542533242e7b9a5cc959", + "0x8bf4347ceea7f94b53564f26b1a4749a16f13bf71a9e03a546f906f7c423089820ff217066159b0637d9d6824e9c101c", + "0xab07eef925d264145971628a39e4dd93ff849767f68ed06065802cf22756fc6bf384cf6d9ab174bfc1a87bcc37b037aa", + "0x8e3f10a42fad43887d522dc76b1480063267991c2457c39f1e790e0c16c03e38a4c8e79a0b7622892464957bf517ebd8", + "0xa8722fc7b1acf0be18f6ddf3ee97a5a9b02a98da5bc1126a8b7bf10d18ee415be9a85668eb604ef5a1f48659bc447eb5", + "0x878d6b2a9c0aca8e2bc2a5eb7dd8d842aa839bbd7754860c396a641d5794eab88a55f8448de7dbddf9e201cbc54fe481", + "0xada881c167d39d368c1e9b283cf50491c6bfc66072815608ba23ab468cfbd31ca1bd7f140e158e0d9e4d7ebfa670bc2d", + "0xa2b48578fa899d77a7ee1b9cb1e228b40c20b303b3d403fd6612649c81e7db5a7313ba9702adc89627b5fd7439f8b754", + "0x8e051280e10551558dcb5522120ac9216281c29071c0371aaa9bde52961fe26b21d78de3f98cb8cd63e65cff86d1b25c", + "0xa7c5022047930c958e499e8051056c5244ae03beb60d4ba9fe666ab77a913a067324dfb6debcb4da4694645145716c9d", + "0x95cff6ec03e38c5ab0f6f8dccde252d91856093d8429b7494efc7772996e7985d2d6965307c7fdfa484559c129cca9f9", + "0x993eb550d5e8661791f63e2fa259ab1f78a0e3edad467eb419b076a70923fede2e00ddc48a961d20001aaae89fad11e8", + "0xabb2826e4d4b381d64787a09934b9c4fe1d5f5742f90858228e484f3c546e16ee8a2a0b0a952d834a93154a8b18f3d16", + "0xa922ca9f2061996e65ef38a7c5c7755e59d8d5ce27d577abcdd8165b23b4877398d735f9cb470a771335fc7d99ecb7fc", + "0x90f22862216f6bc1bbf5437740a47605d1ff5147b1f06f7b13fec446e4c5a4a4a84792cb244a1905f3478a36f8d7065b", + "0x87f3d9a86afef5b79ea1ca690ee1ee4bb9754b66f7c50a42ad6b99af7c222c853ca161f440a0a2a60b3b5a54e3493240", + "0x80a9ca9a2d33b9cf61976b3860d79f5d00de89a06ef043d2a52931809018aeb4ce70423cbef375b29c2c750c2c8704c2", + "0xb4e798ef1d615896108dae37ac50c1e859216ab6dbac11653e44d06ce5209057b4b0dd6d31dcfcda87664a23c8ef1cbd", + "0xaaed6d1e7c5b1db06f80dae6c24857daadfb0268f20e48a98fba4b76de1ebf65fb84c3be95fd6a418b498f8285ec63bd", + "0xaeceaa316c6369492c939f94809bc80e0857abac86c0d85be8066bbf61afbaaec67e28c572437a8d35c49dd596b3134f", + "0xb791c3d53ed34a7d1c8aa89b7953e3684c3cd529230824dc529739a5fbe74b58b87f01e56e7a169f61c508237ef67160", + "0x9351f8c80634386c45c0050d2f813193f9d839173be941e2092d729be5403632a2f18dffdc323d69eb0dc31fa31c5866", + "0x97693184d5c0056ae244dfb6709cafa23a795dc22d497a307a7f9cf442d7452024023c54a8d6bda5d90a355ba2c84f3a", + "0x85362daa003d23511ca174a8caafe83d52b6436dc4e43c4c049e5388d9211b5cbef3885896914d86d39be0dd1f910511", + "0xa2511b5fa34b24eeb0e1bcbcf872a569d1ff5570fe7b0fb48f5542f7fe57bad808d34b50afa87580866a6cb0eba02f27", + "0xb382e3327eb1401f2d378dbb56ac7250adde0961bd718575a64d264ffd44772c20752d4035c3ba60eb435e160b375e20", + "0xafad8a5d40b536c0720556845a6b257ed42165c14fb4b4a874717d107752f49ed9380c5b048df3aca67287bb8fc411a8", + "0x8fad0c98434ca5373c2d767868f679b76b4a8d04bca8240ea3f388558262c2d61b73b16fc1160932652b5688c25fffcf", + "0x83898008b5cbb6f08f8ef3ec179427869682bb4e8d38f6e6a687a214d4a307436afc64ee67d70a5a8ba9730bf839aecc", + "0xb85232e79913785fd82b06890706972b4ad7a309489930ae23390d51aa5189731f8a2df24800409a8c36b3dd6fc91275", + "0xa24ff26ec792f3701da4c5638c1fca4fa4dae95b01827d6200d583c4caf17ea3171393ba2a8c23d1ee8b88402916f176", + "0xadc5c7a7ff6b41d6cc386b7fc69d7bb04179bdf267864f9aa577f0f6a88438191fa81ebaf13055c2f2d7290be6421ace", + "0xa05e835abd502d31454d40a019010ff90b6b0b1f993075a35c9907aeab7a342ac0ba6144dc9379aada6119157970e9b2", + "0x85ff07ba58463e7f153fc83f11302e9061e648a5cbd272bb0545030b20e11facd8b3ff90c9ac8c280a704fbda5c9d1b0", + "0xa6c735ada8f4587da8cdad7ea3ada01650b5a3ecab8d81daa7a5f5de51ef4a6592b524692584306f06be3f6701f2870c", + "0xb138deee4e53ae8d677fae104f713ef1b8babfecec16b6a85785a66a72784eb09d44c3b63567222ade714e98f7d1604e", + "0xae79c1a49dafcdd972acd95d8ad0a35c02adc7fd736d4c44c3cd13df5789d339b5ea16bddbbd43e486a061ab31baa5c0", + "0xab3cf2371a1d7dcd0ffe3869a0178230964b06694bf258b2073ea66a2afccd845b38485da83d02e1d607d4c5c36b78a8", + "0xab9609f28a325fd01cb39540e3a714506c44e52ef28ee640f361deb5760aadbb23e804663b0fa20a66e239c33f8d8bb8", + "0x8ed95ea8e76e1b42823d7915a6aae77d93746f846bf602841dfce0e47543a36efb9ee7e5b42c73c3209d911225cc471b", + "0xa80b6162036d43811482323f0ce59eb18740e33a63d7c7bbbf3be206985919e5342d53a69df537d43e8b7d7f51e8892f", + "0x93c03d0a5083408ba00c125a8a9385213d4c860072f0297857b1235045819b904e07f2425c13a661d0a01d2e53347f4b", + "0xa6581200f00f96c461621e1d26b14a23687dd97eb9f7df4ba641a84340ee7306dc1796248fba4804f185947ad13b4385", + "0x8be174018fa40f7e0cedc5ae68f38969eb7695f2205e9c573641e533d56f68c20abf38a23d2f0dcac371e60b21b18615", + "0x857ad4ee3218c647c58f09b8ab22bcc8976f00a768ab1f708618e868e6143474be846422ce2710a0ed39b5155b6f13a1", + "0xa490bec40f322d599f26bcefcdddd8f2ef6576aa737d5ce7e8d5d422741abe749e3e6a48489aed8c560633f72857e3c2", + "0xa9c0ee339621f1c4a2410f9b4d2f03f1b558dae2973807b8bccd920e8feb7f65dfde3e79986b72ad21fcc4567240381d", + "0x8592251568e750a430f7d2c6ddbb3ec82a4dd9fd83efe389e69aa177fd97ac2c96c59a6e86db20d8e6f125d65b46c4d3", + "0xa4e2f4aa6a682913b423b097c4069c4e46a1f3af9556b1bfd0580d0fc01e3991488458049e0735b2a629684a79271c8f", + "0x8c4f6a3e738cf74112b08b1680be08158013ef8a515a81215d8a36c9b756786d1b4cb4563923463f3329292f4b48bf6d", + "0x8bace547353c02ea00dd547eeda7259aa354d4772dd5e0c486c723cf88627b7112e196b879c3c92a9561b674d9fc486d", + "0x8d372f4901e25e8db64fa098148d4a4e709b0e9dcb756d0f90dad99dea393054193ae1a33d292a3dd772ff7ba05e4b71", + "0xa8c7ea6a6a031ed23d65639f01f5423190775558f479700597df7ae7e338a6ae5e9b32f470aff20787ac8b7eec84df6c", + "0xb6e9dcba240fdbbf66033410a79a2dd3e9e1ffdf2eae949b3a9ed720e939d92339991dc3e70a5ac7d5253f317daf0b7d", + "0x974dec4cd61af75721071752c664d9c2a5121f06ff1515c56139a177a3ca825f763b69d431d4607e393fa74dcc91cc58", + "0x958863e6ad583a9d370a6db3639066982e44766904e7afa849b132f6666b7d08ab931131b3bec7a506d6583e93d56767", + "0x8b93a33b5da9b3300c20a96d80b894e3789c77041183c2cb21751579c8c96857f60cfc2f075201b64e95a78985c5b321", + "0xb726cb9f7ef34ddbc2fad82b3b0af0b30cc913e26c5a614ae5c19cc9c55c8e6dae069db5315a8dcb6d987415bb550ca8", + "0xa730f515398a71bddd66cab2ff996659d4e47dfbb08ce7958a41021f76d269b91c7498b708cd14b183a8ef469c772803", + "0xa4eb3b18132eb0f5337f14e01d63ca0bec0db6a43870f800e5491db756c2f5fce519d8dba5528b4bcef550d06b33699c", + "0xb1ab6621eec1ee6784e632e214693f39a14f3715991996b883d66200963e065c86fa0667f7bc36b93b40b5d90ff708c2", + "0x80486a26c3532ad6e19f76d8c9344e2626c07363fd495264927cb5935fa9565ece670dc98767afb04af6a9a5c9231075", + "0x8ee20e0df3c84a1c6b0e21bcc325cf99235b747ffe47f17fdfba548a358ca75cbcc331dd50db2311b400ae882256a608", + "0xaef4268959e5541e7ec69c921a1e81a8374d7e44bf1bb2debf4101cf3cd6b7d6ca7f441758b388de96b3e0edb5b97be9", + "0x8793629bd29d689ec94b016de8886cac6e2ca6638911babb22db4a787661422da0639a4e4089ebeb689d173abfe75950", + "0xb487b3551c20a29e9a5abbda8c50ff594826283e443c09e3ae09b914e46060b3f9abf70434444ce1487e2a74e562616b", + "0x8f11531cfc5997dd04b997cb87ba1831aa7041d5434fe72de66304e3f165d882fac891391fbb1eb955c65319e65293b6", + "0xb195136875fd02a75676c33cb3e60504d5964f7a9e81f4c8c8fd38af62e2145c55f765b3158664566191188ac678f381", + "0xb374174b0b3eb04fa49eb4ece45173f0db5d829eac370a20a62309566e0f98b18f72f3633626893c053b7be6bfbd2366", + "0xb2a2f6b0cf652775679b2d677048f2ed8c31a3269e6cddcc7a10e3e6fee89e486b50d9d55fbe452b79c4157c0270fb77", + "0x892177c364dc59032594e7a6fd032286ffdf4fa0b9e3baeb37ec839faebfd2fd46c57b2c9bfe9977b59c93a9cc0ead1d", + "0x8ab7c0038a7dbb2ef200dbbe9acbc875829ecad4883792d5c6ce283de67ccd9aa935a9cc7b30b2bd9de7fca7bf2a9a05", + "0x83745cfc78ca709835aa6c6a233c2b86fb31e3f9f6a8becf63e501f2841c4366fb7d131b746c9d3291afda714ff05579", + "0xa723dcb67925ef007e8339dc578d2622d9bb77cfda87cca0088854a59414c02338752c56116a6c1281917842e8467c38", + "0x8a098142da0af2254c425fdbbd0d1b1a17b2bd781391ab37f181775524b8563c64ab8a1602aee2ac6c0a82ba11a8b1d1", + "0xb13bd7529a9b351c5d395c794c28bcb0a3167f1c992e8c062eef47be9be27895945231d249c73a0b6949daa295e14944", + "0xa20dcd2fc2222eaae467d9f5db861040f58bcb991a26e5663ac3aa5e1ff13d0010657c5af586cc4621757add2b905073", + "0xb818f660c3cc4e9f273c25ceeabe562c8afa8ff88529c26f2cf45ae6b2813cca5f350e3cbd56f6257c4df41722dabd25", + "0xb225d5987108b24411bc389276f12509a45e86d5ad6b6d929af5274df0be11109c0fed329669a0acafdf3b0beaa8f2ec", + "0x91fcb6d04576d3c6bae947bb7843b430e5fb0592ae49b0a65dfa5791f4eaa4bf2c7f436c8de7360f217001c2b4e5c67a", + "0x8821f7a1424ca3fdc5d4a5606ad10dfaba6094cf36669fa9f84cf7617e50425405d14980780e1e18a1ecea7913cda896", + "0x990dcb7f38f56521a70cb71bf4522649fcd46ac052c7feabb0748dfcac9f9c0f95d29e070d32af3cd0adbf869535e17b", + "0xb0fac1029fe2c1100f24e2f4bf10c7672199fce53513c7dde2e8d9b00702edf0143e0e1dc7ceae7dcc6994edc2422b6f", + "0xa514ebb1a33451b4915c05114db0b10168393613744df848b24e43e09f0bda23baefd9d731075198aace586615ac7911", + "0x8b77f7953c2e67049fdca3653b8d8cf3f799677f79b954da02bdad8cc4d6c855c1c7c16b4f6f9ba35f46426ec28b2d84", + "0x875520cfbda16ec5b1d1d00f578a910d0fc052f17870ba093e22e310bb07648d34817cc2b8811b6f52de535f7046a0d0", + "0xb8c77b4be0b430851c4ff69e91cb770db1935d848198601393810ef395efab52deb9d5c6525472bab720273d5e0e7a79", + "0xb6d4d437146671bdea62fb6545395ea3df39f1cdef21b8476b68e7a25aa7354f847740576d6c9f187bbae9941f0ae450", + "0x95c642f1bccdb62cd6a2212dcdd6ff8d49aee426ca08b7cf3a9d15249d24a9eed5533f92a70c84498c0797f8a57efa27", + "0xb617978047ed0f748c305aa7f30c2dacd0db00baa67fe0c5ce346ef0e6991dc7e05f18dcb2702467421f8390f27aa815", + "0x86411c7a00b3e8b43bf22fb061b1f54ad9bbf632cd74395a478218389c0f544668acf3dd7726532d080ca7da9a5f8608", + "0x97bf684a8849626c4710a6992f6c11f6b5406fd4dfe9e6aa502425aaafe9827e2c435aaf9a5d3d2ba3a4c0e8aec79ba4", + "0x8b178e2a125b461d3180906ffba0af3dce614c64058501fdd35243ababf892d6fcdea4834ce42c25d5569452b782a709", + "0x8ebed2c8a25c61da6a6a8cb0d8f5ea179e28869753eacc728f2c076f7aed8598cd3aa0981f120f9e7ea55b3a689ae882", + "0xa6f235b8e655ca3d634740b53d8c0a757ecc75d2b8838b7948997c1985473d01943d935f687b86cee56cd47c8e773443", + "0xa7959c465a9646908b9d8032a589e41a7dd999f2ffc54bb42f22e5f8a4d8c493a31bcc7ea2cac6c8dbcc59acace7181b", + "0x96d0532df2e12da20a57cadb6cf5f6c4ee1aa4775629358c25f1d51677a3e96d1fe3b232532324b4f02f941952d4cc68", + "0x90f493473d686b639a30d1ddc9c72eae6e983f1236e162e58e967a477c0654973ea2e1bdf4ba1a44d7247bc1befc2cab", + "0x8b2d87876d9c4085102a07ebb41c565ba69acab99ffc03efc18f20e48d3f3bbe4fc6ddab9c78fe479d9ada80504d85ba", + "0x829a0fb3200a28e09cacd6c5346000e7786116ddfd898f37dfd17bef454a8abc0fe939ed8735c00769f7f2f33cd4f906", + "0x86194ec9e88ddb7150e8b03e7a535b6e99863fc6762835601efd03615aa97aaeb413cb210e86035086ed852b39c9d019", + "0xb02efd116a7189cb317ceae392bc301ae55470f0489fa89934e182aeb8c67e280299b975786fe9a470bff46827defb9b", + "0x87d7c3903bd22b12d815506f150373f518d47dfc6e5fd74347d88b518124c9923d1e4c98defeb3a45d53d50b423e2175", + "0xa1a430406b28254a7d6348bc98e697e9bab43839aa05d53faee97546f84541ea0b559162619b2045182938f69bf61cae", + "0x99d243c226c61c6697fb3d2594f3533fa5dfd7cfc87107908cacde337d7a077fa5a9dc702d26081b065edb1227498e65", + "0x800ee5006ab6217161f42db0cfc552a81728bb4fbd7af6e4620ea099a65ef6664184af3f65a07fcec7e965529c5b49bf", + "0x91bfd307579cadc8f81009558605be3edbcb8dbba271475803484017f40130b2b216aef4f620d960193be681877d3a53", + "0x96a060459dec458d19a6f8af6e49dc6c7c58c55dd18915c5fce5e0f4b4a422fce3b9632f6059388fe760289abf70f173", + "0x9921a37f3e657222c7fda3588418a9071409711d9f1fccede7494429f02a45fbc52d79fbb64e9ccd518f60d06d0520d3", + "0x81052b0d15773cb75975ca9230ebb2579700e489c7e3f07cd9cde206fef38b8139bd4976d2b4a7840495fc645f96df03", + "0x88ac37ba66d1de5e23878c992e4d54023729e97e77351f50dc5918d738b5a73faf1dc6feec7e85784761836ba1c6f778", + "0xae1e6072c13060775f6086d1ae1f88b627ffcb810fc0e0e97deea1f3a15ef0aaa52a6dce2563e4beedadc131af2a8281", + "0x8b60a340f5e4f90badf83001b495ac9f13974c3d2054ddcb3e6b8ca99dec5cd63a263e05c282454191ab2e087d5a2911", + "0x832e2d56ba69dbf817b2b9dbd25c1538d5b8dbf5d9bc05e6be85054a423ebb66a71b157e166e0b9444ac171b34b7ccc9", + "0x8586036fc7dde1e7e3ecb61663130c4529866ae9f5f5095b9fccd24a4c70eea899aae5f10ea1ba66d1665b2d83be35b0", + "0xa77969453b5c083a207913272b5b69d4ccbd8718bdf54be8fbe11b4bd0a2168aae3ba8f9362afa69c0ffa28d7e5a2340", + "0xb7fe9568c214baad0ac5f83745611b481f744ec1c4fa78a549b180dcf79633e5ba75dc20055012a13d849eb7a9be57d3", + "0xb01cad1d2a6c51c0ce88243d1f52f95fb5ee315a905079688027511f0c4ecd0563a3a81846709d272fa5ccb9665e8043", + "0x8eae0a21adfc569aa57237654021c2bdb2c6f0f52ccc90a126682c21a1f9413c63d285f92b2b2f8649150a9284bf70b7", + "0x942acc947192b5f3cf60e92383e5d35f79e7a5904e8e9fd1c8a351676c83ad29b0afb6578d555457cf909f8f4d27adfd", + "0xa74e092f8628fba9abcabc27e2e9f3d5a9a941dfe50a2dfde2ad179aabc73afd196676925c2d98643ab8b3d02bdb66ad", + "0x896159daa2afd757cf3f9d34af248ad68bb3c62e4c9ac49919422727479cf669098f270b9e645607a7d11adad4c889b2", + "0xa428d8370813d78e7a2a24eebd36e9da2f8bb3605e5a39b5fcda939b531c35a8ebaaa642ba556250a37bddeec90326fb", + "0xa5fa04eb60a1d5ee9820e78f42f7be15e1c02757b539aead995768c6209684d6c183c71d282e0c12a4c15c03f9a89d4d", + "0x93c77d5d220e40affa7269a6915c076c9aef4db552c643ae5d560a79c955b491c6346ca4cf11cbb7fe1894e28d47b065", + "0x802e605d2de745eef6981d88e7a57ef4046a2062725e8080995374cea2b3273c27f35b7774d0dcba014710d8d6c501f2", + "0x82f7169e6ec9b3e2bd450f35ea2e66d06bcf900acf5b73139677b48e078ce2e16599103027b2326770c99c0a690f2015", + "0xb0c8581879439f9b997551233fe2de71aa03604f9cec37a7b18c5854342d9b67be468f3cac4bf6f64fe8a0066248c498", + "0xa3f626848a4db6e9fb01cac90d3362ec521e969ebd5228af694ea3671061476149f13d652942ac1e39f65591fed740f9", + "0x88a8e759b9cbe16a7c16e43f4afa2de6100d2eafa4dee75ccd653ec38c919013d0a6b35c1ee1eaee7c1985b58bcc9e92", + "0xa3d5fc7aaea072798490616552d947e95f49cf02a420314307aafb555287ec607d75589ba24b009cd68299dc6f7942fa", + "0xa809cceeb84f9bcf3c3ddafde3041e7bc3b1d14df8830ab849002176a0725e6f16f70774d8962cb0b8ac0dc43c4ac66f", + "0xb8f2e46c031cc8fa160a08c2ebdfa85345ed14771b06daa9636b0e7792b7fddbc501dfc85cc626a01104a43a7d3230c3", + "0xb5367e2a521c318b802ce16ceac80c4b8139f73ddb10ddf38433397cda70a86ea1f051cc55626a4e99d27f30f3975ff5", + "0x96d963660121c1441cd13141279cd371a6a0aa18b6a20761b18df60aa9c14e13489afd83695a0921d5232efe72045f07", + "0x80818d492fd85d666bd91aaf6257b86527fdd796773c793407df1d4a0f91d74649a6bab4d15155c36ed4c6e0a32c5636", + "0x931e22918905fd6c230d3d867ea42861f3074d320d14e1929031924c8ac209a5c552b679b24563bb12f9749b4ee983bd", + "0xa4de2c333e74ed9bfa3c0bf6a0beb90427abd9aa4221294cda74331646b58ef46ed57cccc8798ba2b9309894b17cfd69", + "0x883881554c1d88c0ed8d3b6dec3d200f6fea69a77ace3e4d6f86b41506a23724b4394ec8384075f9c75c3868ba8a8e8e", + "0xaa0539ecf6ec9bf06f24443027f8f24b6b3d8c5b2084248eecd4bcad3c9a69716e1a0d01057f09a65bff1006ac5e157a", + "0x856d74d44c943c9e809b42dc493dff20eca03cb0cf5ed45108c69b1f90d8592a53ae8100e99380a274fafad23e74cdfc", + "0x9188257446661c88da093b7c5ce998135913f63842d7c1586065377b169ee35b062d925367fb9b909ca971f1188667b1", + "0x8d3aa57cdafbe998938787479f5d590c1484c6dbe94e6c487e57a746ef5252be0eaa5976d6270de7db64b6b92e57a0f7", + "0xb8f4d6997240f9eda5aca0c43323a828d1563c491b3db2087f60ac4120a3fcd06075fb42bb19d0339ab5ee3fb7db25d2", + "0xad247ea94b8ae1e81eae4c9fd7b39e6601b53cff47b2547ff90a3cca87192eae28408082774a1fd14bf9ab459b7a4f1f", + "0x9598598070f8bdbcc49056c40971e673726cd8c1bc4baa0b5124dfb5fb750e7baa7a7df18eae2bd91955ddcb1ec67955", + "0xb874131ab1608667fa60ea29092d090859eed1812e90c609afff96d79e82c5ba546f617f4c96fc32c9bba97431c1e9af", + "0xb00750a9cdc75c2a54f0d3cc99b0fe02300754f25166f7ac85ff41ab5e9cfcca33a29be76a480f12a2d410c7cd5032e5", + "0x84b5bd1c90bb6c66755b28ba4af493ca1b0c3a4df9f436aac67d2e07289053f925cf6a149a84e74e1027dc8758150179", + "0x99caf64bd9d193ff306e8ab5da3f1bb2a190a60c3a82099b8d03d17fa810dc53d176c21379f479e828f60d25beb3ffd0", + "0xa8fd9de502f1c261d5733430e5a18d8b7892a98c9529a016fc2ee53892ae965dcd9c75850bcda4c7edb980b8d88e60ea", + "0x848c02cac636e047028a3fe8c1bf4066fb7591b96b0340f8fbd476ff01b35fa3e37d309333771a134f24800e5f3f9289", + "0xa1eab1a06dcca3439f0166441e7e7f2f5b56f5f8aa9f45e411c561f556e0fb71c514c06c26ac53b49a576caca5faac3d", + "0xaa603f970dcbe953e700e61c151182c8d32cbbb53ceef572ac93383db33a4b098b5c7b267e42d514ca66b740c0925efe", + "0xb55fd5301bd700ddb0b4f72fabe9a91ad49759506101fa802ed1677e9553595aa4d2c66f7574e78d21ce882ce0120ae7", + "0x829137bc4da7b4886d3d04d2c39cbf4b1dc40c813ac1adb425c7b9abf9142b516314cab79c68454df5d71994ce416144", + "0xb83a3a22735001f783dd48a01c4fb3598a51ff3987e842b8045c71c035b9e43645a55254ca5911a5676ef4a8af12d056", + "0x8ca8d463deb13f9eef5e533bc39efaeb0c15631282c5c0deee1673b0053a7cccd514af09801dd6c158caa159fe9351ac", + "0xa9ffb1427828f3c456b9c8cc50782de1ab0029b9233a0fd998bad0fd014d27e15c4a32d1e16ad41bff748378b5abdf49", + "0x9627e29f725ddd86456aff813976bbc4a836f4deabf5ad9f73d1a260ceb30948824df9c8841e6b3c529652202be181b3", + "0xb52c988647fe3d9276eed3c262e1044f57fbb116c64cf4f207235c205b3fda0f3d789bf90f5217401b468d85fdfda404", + "0x833bbd6e2924f5c4446cb76b881d1434a5badce9eb9b003f85d076e297ad7ef45b822069fe54d17427a348c3263fb838", + "0xa067a36352db6f82a116cb87d3db5f60b18576852409e2076cbbfc7843af78866313a4969385a40271051dd195d51116", + "0x902b99545971f9a103f99d7399acc347ac46fe156166e51deefc0e92aebf5893460c69aeeae11f5af9f49418e289ce6c", + "0x9206a0e9ce9b9880f29ef0417c96931985f5d83bb17cebdbba4ff2af81a3d37155b04649426f698aed372e4f669599e6", + "0xb54a5d7c976e45c0b1d44433595eae9d1ae9aeabfd58cd5ecb0c5804756a7b01c9a517754423b4714a3695533a3114c8", + "0x91b612131e84580ece228b81ace83da0269b53f94d3c02a1a0879ebbd81bdc252064b3d03a7e140b43a90f237d9a45a0", + "0xa6cead3b8607eaeafe37135bd6de8fbd16f806c131eb71c8d36bfbe295d45b070255e50dabf076e2c3f6b8699be71d6a", + "0x931da21e67b11ba6ce438546a24d063bcd51aebe39b4220a78d9c0aab88b2d37969b5ef3502d835507f9c8d6d006714c", + "0x8fda408caa9daf01122a2308b7b9d328f52e1e2f138a8bec30492488f4d710e5e52524a6455a3a2ae2818ec8a610b650", + "0xad8ad5c189644352d90c462731c46145410e5adf38682bb80f95495dd64d9d13782537d68690847bbb06c6be7175dbc7", + "0x87bb5cc466ade60feb0961421c3fabdc8a7e20f11df8437bfff63d3f8bd25305002a396c9d0fa4fb9a9986d4717f12c4", + "0x827cff72870ba00c29064a7d2b4973f322d6b6de7924c93d8bf8825e7a0e8478c7748f90f5c716bf83c55b2795d315d8", + "0xa225895a8e94229776ceb51b05356291f2dce748be17a60d5aeb33ef8507c368bafe5d1d6eea927f28b9d1422b661b9a", + "0x8e011323ce670ff51c964241a6b72e0e0ffbb3ff9bb2762492323fc3a4abf4718091be0945287c7329850e4f74462cde", + "0xa2c03c2e5f4e9d3ef361f68b188451994ad1b24de9f323370559c8abfcdc7bffd289d92e78a5f6b104b0a12c84dab2ef", + "0xa22b4771116ce22276fab1fec6826610707ce8a342f9f60b079c4e0259dac3cc41c96c560dfd0ada6edd2828f7c0e8d6", + "0x97c17441d0af9be83b42097aa8b7cec84a253b9a2b957214b8fa93c26d2add46144faffa7b8a55312059b10690f711f1", + "0x94bdf348849f31a2737cbae5e5848aee711067bac85c11c2e68b44c398cfafbf3493a3226cd1ddf7a916e7613fc7b6f6", + "0x838f59c6e8469a8ec6fd40b978a3607439aaebe1e50ff707eec72c0b8278af05b477bf12a384b56d03e3d4eb91e56f67", + "0xa1940f0db58185e2b3aedd2b0bc2b73b4a65c68e09b046f38e9dcd4e13c94f5406bea92635190bf315e48ec64eceef2f", + "0xb2f4e0ae44e1f1210a91d8f280f17091fa994034ba8c991583f8182a323e9b3001a712e3584fc2d64ecbf2d319d076b2", + "0x9342b89c721338d02c7854cd7466fb24d93d7313b6114ea591e6607439c8ddb911d1cf35f01898e9c557982bdff8f9b6", + "0x8583fcab15be1dd14d5a415f4b14d706c8c62f058500f1344b37730c8be6741779691f87ded3cbcf6516468b373cafb0", + "0x8fa9587c7989646571ad9032f34cedd353caee14f5be5cde1e9e0a1710f90c08faf6fa96a60e1f150f761c9c8ae7417d", + "0x8d9ff904cc08141f5a9879f5f77dc600e6edbe859082231a4d819953890199bcc5f940b730ea688332f07e5279d49e1c", + "0xb5f82b46e5ef9a2df8d144202d6e2e4f3bdae8e2048d2af5ea7deb3f722fbe6d370401954e74ff0d8cb1010ffb1f38d5", + "0xa3b5b57d435b06ed70530e060002a8fea71746ad07d969ca23f22b5e52624527595b6a6d54b4e953fb7b7596bac378f0", + "0xb90f89390df6d4b7879b915aa3c29b8d779d035033f8873bb7ac54a14ec98f0d08c0e3bf696e2ffa7b5730d736f571f8", + "0x8e81e371b92887e43d95c0dbdcc9575282b26ccebdc8cbf46587e4f2a83b61e9bc0c6d7d1f114b9d21e04fd6c180b12a", + "0x8d682947c51dffc6e0fe0a486293c9ed121f441805168236393087cf62f2a429cca60bf0e472564844347d32c6bea27e", + "0xa8341ec7dd189fa7168759240224192c58209b53fc961c18082deba217928c399bde08ceae42bffd37c1135b4d14a845", + "0xa94bb076dcc5ee5ec82fac57c5b384c690df12631882bd1b960e1eb8c04f787bc22b7bac315b9dc5a8a098f17f051a0b", + "0xab64e1c6f01b87706c88a3bd974454a438722768de7340b834ccf93ea9880c14ee7c2181432acf51f980d56de73832ee", + "0xb7b0058bb724d879e5ad7aed6230297c54cb599ef659e86bf2cc84c38225899fb388391df9b2e6fdf063171937fd8c72", + "0xae856f4fb74c27cc98b67429186e7df4feb01278cd57bfd3170af6e52e0a23b9e926bf9565a890cfb4ae8f2d590b2cd5", + "0x804b9c6702f0596d328f92fc1ed5a30a7ba17b9204524135001b569233fc4937035031d079f52fd04968f37c24013898", + "0x84274ed1af6bd6a968583995622b4d18c6a2bc703ce0d0edce45bb736529b4836343dcd11911a94a134dca7877e6cab8", + "0x88808098463f7505034c3b6328c8a08186b33f7a981c08376e429dd64b79b97753170531ed078dd265ded4ec0a1ed8d5", + "0x92823bfb23a4eb84d3759e7d717f0c8641ece0927cd2ba8c728c26bb35df2629a838002f353c8d3d75eb19520aab5f25", + "0x8db36bae4d960cdb9c51f419d7ddc81f372e56be605bc96a9d4072b829f05527c37c8f255cc6115300a2a0d2e6568d89", + "0xa8fcdbd7f3b4d7ff04149a209feb75e97149e7efceaa42d66a6b8e432590fe7bd01f1a77fa8b47108f670b612e33fee9", + "0xa9f4c53c62db7e5dbdea6918862d3c6d24b5bd8732a218edf0ba61e9d1861182323d8ecd7bef8f895b42970b492f6e40", + "0x8b95bc7f07818f4d7b409aff8da0b2c2ae136cde386f53a71565cae9fd14c73c13cc1cfd79c0f97cd77839fb738c5b9a", + "0xadbd1d11adc756b51a571ddbcbf4392415231ddad93da09acfafee03a9e4f9e1ce3826110619e5271feadfaffce3e793", + "0x95d327c8bb195cdf25fd79c98f9406a6b0316214b1630ebcce95bdaeffafa36fc1accc6882e0e5d13a8db5c0f3c0e61c", + "0x8cb2f1e2fb25558869afdacc7bb866544cfdd566cefcd048b48d458a886130bd086ecb7600a960a7f2563c61cb326510", + "0xb3aa8c4bf5b933d89cd74ca7f7176d6624d562d7d58b041328b49d7562a30b489cb606abb3c49e85baf04c28e9cd1f44", + "0x97f9053a85250c420599827297453c2cfde087065b823d9e43139e6a9cac3a2ec40a1b6e2f0726bdc870fff215462f0b", + "0x878d5dbe6b881389c2ca126ff66d87127c9aaa3f62f0d2c1ec0ea2b279ac95f8a06710dce166415db227655e2345a04d", + "0xb2c33a6b4203e3ca5247f0890e475518317ffc44cfbb1da9a1ba02114e8b752bea618050b876de5cf3b1906140a64471", + "0xa56170c8313d2b5541a795bea9934d4425b185b5c409f0484df6f44f0e4bcbf50b860ff46b7245cd99c1cfa8fc1965b7", + "0x96e2b658e2876a14147385fc423d2702a3cb76962b6b437222cf9cea39ebf4bdc03bbf434b747866d4bf72b4ceefa639", + "0x89c4a74fa2f067e7ae49c84ef782c331bcc9245db7e941804e2e99d12e987b4d25cb827778ad4c3566c4fc68018650b6", + "0xa01d30cea7d01c80ff26650020fab02e78fc3842e2398a81b44b21d58d4e9816166ff4ed2418831fa995a28ff35cb6f1", + "0xb960c80b55a8845bbf24bc3f23b0110ca701f9544ab6a5bb7929330213cb471321e55c390ceca3e24bff69bdb0d331c0", + "0x802c5b13f22be7be0e5db11eb3be0f0ea7f9182c932265060ba05fba20ea093dd2810d3b969ee3e387e60fe6ee834e8d", + "0x92478f88ef7435d15e39a97916c736abb28ea318394b88678fddbbaab3eaf31776110936abad116a8ff6ca632dd12043", + "0xa6d3da0370c303001d5ed99d1db8bce1f26b0e442f0f042e36db9674e92dcd6e80465e772f1e669f99221caee3392fe9", + "0x938f04f70a8f947d6df2f0c0e9af3cce0c06edbb3c131970dd60884fc0b0a0959c504a2a36c3ff76dfe919905671626a", + "0xa7117e55224230822e9983df2132347eb7208cb6798f291df926ab51e04b1a1f78d5568c9a8924ee6f57426134360f20", + "0xb91074c77ad93fe48dc2b10c0c5a62ca3ab7d98345b919c52d84a9dc419b59fc1b267e1c2d4b2e120016ef84bbdb0cbe", + "0xaa175c6b6edf02fe8778762c9575581c0ee6efc9dbf99c291a41444a23a056b893be6c45333d907d0bbe9fb0eef84d08", + "0xad36dcb4e2ab425aa339ae464b038d550cb11186741dcf257f1b8b80ed4f32ffabbece45e2dc1525d4c3eeed819ea04f", + "0x91cb35c1ffa9cd5aebef523edb8325078da3eb5cf9e95c675a76446fc7692aaee6f949de064ca2f3e0f082cc3fa93e20", + "0x82622f9410c143a86bc4d756b3c7b324dc295231ce865de020d61cc0868f2c150a473cea3a5b756b36771ce1032415a5", + "0xa5c29996ad3a53468ece9356a5b4ccb68971ea1c89cf39644f1da2d4a477c2ea99bf791ef902b87c225d8c53d67c4c92", + "0x92893eceed1af34fa92b23dcbab175b6a0188a27dbac9ad3317c4e39955a763cb383ab13fb1c519cde311d8a4d12e8b3", + "0x8a093cb191b94b0200e38d31955f9d240e2be1edcd6810a2396a061f17c3ddc9c4f4d56766ddff4e121be7110e03b869", + "0x93981473df0cb1f4b47c7d9b64e3123dcf1593845b401e619f5d7c70b5dbea375d1ca43fca65845fcf0a6b2e0af43791", + "0xa6beb6b0697070f9562910add88d9ba91992f8da127b27be81868b1596d1012f09ea7ed601b4a6474c921a1a1a6d866c", + "0x92026b1ee30f2ed61c9f30337c3356844217926aabdff383c19ca3c21e0bc49811ca5b308012bee4ef250cfae1615800", + "0xac0ebaea6d35f84dac4ce648af096305ba68a7a0aea0a11ab2fbe3162075444a158433c98141bc92ef3b3400d6deb46a", + "0x83046f482dee24ac3ca83373f0d1b82ac1c4beda0f229a9011a81ec659ff5fc1fb105e219975b5c744308c77a24f71e4", + "0xaa5a312c47ff7248dcb9c6ffbe5a0628ccd565c07365c4413734d415cd4fb35772622ed833862dddff520a67c509c6a5", + "0xa02fb88805c34018ac33582e19ed0a7e4616acc3dd0867e5f21914c2031c05c6dca30b8b35b57c2b137750f3878a6f8c", + "0xa60528f1f14bf0c496491d46a0fbbd6c343e4eb3f1631e92f96a3c5e5c684091aabe5801df7a67f7c6dfd1b0d35269d4", + "0xa1fd8e7fad8ca05a340c05a051bb0eb4197eed345f4104629a9e38e234b09d789cc5537024615feb4a6177d32d39e39e", + "0x8e70e36c1aa070815440e19443f1f04aae23b1b59fdbcba43b47b94a026c82c8f66c5dfe54f826f4d95ee1930cdb8008", + "0x8234c1969fa7e9079661e4ca309b71b1aaa10f4372be0b963205c23a81f5a3d52ec08ba9ff65b37f832b52d631580d61", + "0xa18cb4134127fb37c4abca328cd0047378a2e1423490af2bd3eba9ffcc99ca81a3c22404c0886f21f65c7b93c41d7981", + "0xb46fa45fe538816de776eec086e040005706cb3eca097e290abfb6864e745c879868aac8361894f3c3564373ef9ad55c", + "0xb96ca43b96c59e95439f75d1e726a35a9362f0dbd34963b156e103e080a8126a8dc3501f9fd541ff3bcf4677f5c4a86b", + "0xa8e8c87c7301613818d57387009e601a7ab5cbdc2890f63d985c30c74f9cea2d0584c116baf0d9cd5594386ee93fc661", + "0xb47e4f1b9153ef0981f813948150f283b47a7346fd9921d51fe8e4daedaef78ddeb4fd467c2ccb7cebd9816243da1c6e", + "0xa370c202a99c8441ffe96fad0f801086d4d7cc7b960f6e98cca29ceedf492afddfd0f351c9c4d29ac008bc255ec1a2a8", + "0x8f5e6ce1655d1c059b006174e3f5a55c88e1821c97f9702ad8e8455d46c2a83ae4482f2d43edda74a835686ec45a8a15", + "0xa30421e694930a3b65d397b2720d5f8e1eec2b6e2bb5a28d3f9b0a84db9aabd83850268bae64c2b10e313cccf120151b", + "0x8abe87163046f7a9b18e2a3c0b66e258facc1b31431420e0b70354b7a60ebd250a784634a76692e7d6f4330b62114945", + "0x894f033cf077d4eb312e3258d9dca414356271abce1d6094ecce6d018c5fadb1c15d8d69451574ad0701a2876db191c5", + "0xb0923d64f88ffc872654e1a294bb1af8681689c21cf08f39afe51448a68e60a9a0a74ccce9969276a932a52c07d095a3", + "0xb9ca23b5be8725fae7fa710eefd45522889c50c29c26384e00b78a962384f0aeff9d15cb5910e9565da12a577eb7e5ba", + "0xb242ccf292757197a9f470f2d80ccddc48c7f1235ba026bc68a93be2738bc968e8a200aff3e2f4807216442eb3fc50dc", + "0xadc2c3b375b308524b79a024ff87d122055440643fea6fc0a651bdb312c7cbe6a456afa9d342bc76446d77d8daf08bc2", + "0xab645955356c2ebf2f3df9da275e01daf0b44a52afc309277d6d9ad1b05484e5ae0d9d41ad485fe481e5e362826a86ae", + "0x8de96ac587a4449fcc8b7fd0a51b4b5185d9c2eb3434f94cbadd092de1e26b0f6b3f7b15a37e8424b1429121ddca0ecd", + "0x94c70ad4e9b871566f3da98170b665a09788d421818299857cde0853789fb943cbcf7d4b2c95246ea7b72edc56a8e36c", + "0xb2574be63497843340700b701d5cc8be6d23125bd62058802ee67cce1f3b5f5602b27c93fea5611f27dc695ac563f042", + "0x869ec89da7850cedd88bcb3a50a15cece233119b31b64a61bf6b2310892ce42d8b473b584b11e61db29ed24ce8033f83", + "0x8fbaa269da8e28e9adf4c1b08f109da786dbe9cba871c32eecbfb10619b7a5d65a26f9bb33e201a8ed20b3de94003fbb", + "0x8bf7a059c37242caf7f821a6314e4e4adf799e0dd86b37892a7172598892c07272acebd05b534755c57b51556b2d610f", + "0xb4e72645fca459898cdd9214892ed08b5c99f82049c0a30d72bac0b9717caa9c6cc16c3dc7aa6ea4d42dcd2a6c175df6", + "0xa39170da87a3495da55bbb9701c5461f3403447174ed6a4af75712f7ba4ac35f51a4234bc4b94da888a0959ee109c0c7", + "0xb45675b2774ea7696089dbf7a0afe6c22e85fd0e4ef3db508fbaf96c9d07f700c991789206da9309fd291be696357c5f", + "0xb52899e3e3f6341eefcbe1291db6664bf3b6e8021d32fb9c3e37b6258a35c1da927747b2ce990937d6f4c6c3e7d020d2", + "0x84e5bdb3dfe19700d79dd3fabb0159ccfa084f7288db836c855b827613ce8071067c8d7ac5cc2b4e88ed7f84b690f6e1", + "0x801477d200b6d12fc6e0a9bab1c8211193ab06e44551e037a9b4c36fc2d4f67760b9ff4eba9a3bc7b6e177e891f64ff6", + "0xb6b71a5116d3c22af26a7530f535e9b7851f25a84e562a8f17a125d55b9b3fc1bd8cfe65bdcbeeb328409521e802051c", + "0x8687e21c34d7804c12489d30680d131ce2133e2981bfa993afd8a8eeda958ebd5e6881d342d725338659882d9f21cf98", + "0xa024e97a7c4de32b6383c34431994abc533ecdbd6be9bff836ec1af022f5a86773bf345c6f33273797a61fb70a8fd5d6", + "0x83f784f095da20ce5b31f54d6cb14b32a8a12675f0029289c9cd036b7c87a8077be2d04a62618685720e6ee69c875e97", + "0xb4e9dfe7cb9d9efd3fe00d99ae5e48769d4af4bf43d4e05c0b54c9cfd8bc854de96b8d3ebf4dcc06b9dac66b7471a0de", + "0xa08b79f9d4673afcf7f38b57f484f88feb7c908f597663a2417f92c348150c2be6b5603f914eba0d9d5bdd4e5c5572c1", + "0xb0eaf919589988798cb01ba0610cd1b7fa3c08715675ece8ecd5f9ef6d5d7b2c4c8ae1ea7dfd202237171aa3e6f9de74", + "0xabff99a98baae4dd0954052503ce81827781694a5ea8c1149f96a3adde75dc2d630e138598cd2ae7fdc7a654aa17df8f", + "0x83e369b8680d8b9d995222b033b4f4f3e3b20e782113c941325c7fa9c742feef8747e4a212d9aa23285a259cc4faef8d", + "0xb16d5855dd2716613697eba36e2fae0872aaea6999e91cf6552f93f9a0b85ed4f6ff922a91b50816bd6cf8e7a4513fc9", + "0x848373db600e32e741aa1d37726bbb28956783f89ce2d781e95fb1ee1adf4359968a141678af268077eae4c25503204e", + "0x93a0dd0fdac18a31875564505b4e28f9e8bb2915faae666538597731ac56cd77f23f2456461e2f672983fb24ad91f6e0", + "0xab1ebbe49fa56524b564bc2e43784147073e6ea5d27a9540fbf2e04d0f87c645ed2fd28b3e4982cc4c0af1734ee47a6f", + "0xb3ee30b733839edab6f61f0738e3f4afaeccf700d8dc7415684f193b36d70d07acd5780cf539f12e0fbf8d4683be773a", + "0x88388f2cbdec47a6b3ae460b69eb0d2130ac14de950c22fd86de03e40d02292bb93cebe62432da39d509c1289f785fef", + "0x9370c41a54b68ff486b4cc6329c3a851716ebf1d088d77a6c56dec93a18b8a77b596cde74cc17d2adb2b2f411a2e4bbb", + "0xb9083b60dc16531f77b05a955b51a237a8f8c0173d72c352c5ca441b55abbc890b14937e457aaec4be5cbbf80cae0099", + "0xaafff8f6c6ebaad952c65054dfc7c829453ec735331bf8135e06406b7a9f740c9a200dc48bb2175516b41f77dc160121", + "0xb43d31fbbaf10526809e9e5bd8bb47a76e0fabd7852ee7744404559ab89f0f215ff518f3271a6aa972a459cab82ac558", + "0xb581ede48c6ef34e678f91dc4b89507413e00e70712e3e8c32a80eed770ec8d8b98caee9702d068aeaca6f704be57bd8", + "0x8cb0a137e68b001a5ccac61de27cac9fb78d4af7b2f5a00b8d95d33ac19cc50c69e760c5e0330a85c0ded1edce0fe6f9", + "0xb947fca07c7aa6c2bf13048275402b00b77b28f1d0ba4b589fbcede13f93b5b931c588560ab8ceba23bb8e748031b55d", + "0x81753cced5ff819901740a9a584334e355b497cb699f0be5a52cd555a4c9f149535c7bb355b54407f7f0ec27de6c2e19", + "0xb3d59273951ce97838c4853ec329782a255b5fc7c848e7992ded1be28a5ada7fa3254123afe32607b9991ec6e0659b08", + "0x86b253de246f82be1cb0cef01e87c3d022ca1829d2cc7e6a160a5afbd3ca6b94d75739b122e3bb16f8bde28a8f3223ba", + "0xb728b659fa2d8487e061a37f7d14a4c2d70cc37497a8715695d8d332cb274deee2ce23b9b5f6a7408516c02c3d526a49", + "0x81277b46d98848a45abfbe39842495659dcbb80dee985a4fc91d77d52b815487aa8bb455f411fcce4c3879c7a075a93f", + "0xb05b6f1fb4a6e654f0ee6b83e08b58b57059bb0b7c490405bc8d963c4a2d6be39c558917977e554e1e9e3169961cbf3e", + "0x88f75fa7d016fb6442551ec071cc1e2beeb3ccd213d16d744f573a82f5d70f41dd1b18af71d5f9e73d87f2f6b7dbe889", + "0x81a46434f1bbd65a661a0ff45a0295b8fd8a42a7969c5953721bc98698b64bddee3f806876d1e9983063fdd0c11f99df", + "0x8b4f6d33c510a4c9c7d623d9ae0c9aa631fcb987704726b2a4d8519372123bce3c439202f25b5b47045ec14ce39a21a8", + "0x8d5112b330fb63cf6ef3d2164b404c14ff9907d685015701399a260951912b19b8f270f869df317e9050a127763d7980", + "0xaadab394e84dfb82db15ecd2427f39b62352c3e1647c3bcd14fb24ae830ad0116f0fed87ddb63963b424a4741961386e", + "0x81ca4e5600d00a3bda24cbdea7a532a4cbbd893c10e7ff10667c15ffa8138b91667abe5466b31a3dcdd60155c48538c1", + "0xad943af1b8a5fcfcf309ed8f2f916339f254cd555c71a407a47365a139306286a05a8314e1c70e20a65fccd75d36fa12", + "0xb16597a0b437060a390467bbfab94c0bdd695ae898894f4689f939e30cc2119cc08ecb594546304adf876f4e275ebcd9", + "0xa44a4e0a6693be356065891c27eefa040a1a79475be53d54d5fdcea7e0668ff9b35f850974000ed119f6865aa6faa721", + "0xadef27d1b6e6921f4eaf69c79e2e01f5174f7033eaafdd33edcfa5119af23f3a834ffe1bdf19576581b797abd1865b34", + "0x90c1e9202f3ffe28f8e1f58e9650dc4ff4dbc158005b6f2296ec36147e524b4f2f87f8aafc39db5b006fe0c491c92f45", + "0xac817cd54288b6f7fe6338415344fc9e7b669414051631ab2f27851c052c044be06bf7235d668e194bef695923256368", + "0xab14944ef653a14456d4ebc12e3196df3f1b4707c4e50b317b5ccc8ca3a0720f0330609f0e7e71793f6ca01583f38c70", + "0xad5353f2f380837e5ffdf079350b3d42935a0517861d03af98db5ed3ea8501abd68885c8c65f5a66e944b1874826a450", + "0x8b5583863f84af8443ce8970b02e26cc5d959e47efbf8a66a54106ab165f1f76b36423aee74c7b5402fd1c4d7c1adfe6", + "0xb3b46037eed9fc30e4f8f0da8bdbdcc40a38e22e876ce9fde981883017854aba82c18eb00887d92ad847d30082fe7271", + "0x98a2b6fc90b7ad172e4368c1e54675b75c8bf2096d91c9f2b60b3397d3be3b705aed5389845dbd68f0f84438cd0f7687", + "0xb155e800852a5f90a2eac69cc4483428da1dc2c31588a13c924e60a7616ce9baeb7d4b829c772b260277cadd8ed84719", + "0xb8b92c520a1302b0cf7d993a52e1dacd7f27bda9868d59c55687d995ae676b7070af4c0792a9bc1c2635d44a4fee01bb", + "0x96dfe9bde526b8fc829eda825f55168b88e8f4e43d4d708cc3060df03437b46e12a8ac70d7788aa75760f6294d3e84d8", + "0xa3fa66c54e2fa084ced3bd838614c6c33042f492a5745d167a723c60d5e7d6020ffd1747981a23f8b68df21ad8f0fa77", + "0xb573ca10cc41fc04a642f6f62c355a4fda69b94b8e95dbb02fd1ccce4bce1191356e1fd66d372159944eb36a7071f005", + "0xacd0a1c9abddfd0ea223eda1722aaada362d34234455bd1c6be115d41e535b16f12ca428da7820a757fa4c98884a385d", + "0x96f242eee99c4db383b8754fa7987c0c159652e1866faec905a8d3f010e0a1ad05bd77b9ea8dfd653738959180f58430", + "0x9215a9b672a5d6e435e0e0a45156e0e20f75cbbdf1d14940fed3ddb63d433bef643796c7a4fff881829ebb2b2eba9460", + "0xb8ad9bfceaf08dc5a874387219ddd1170bc3a5e25ed72d321d59ae713be5ddf9fdfbd3aa7ab163be28dfa0dd14614e19", + "0xa19a1050590bc500b32c502f393e407abc3d8e683d6f6b978873aff3e3299b18b1f6b59e2b0fe237d819dbdfcfdc98ca", + "0xa6870fb11d4429686e52e1f44c8dcfc7ea24a020df9570c021578dbc1f9bdc8cf797cb3a72d7fc52805dba35d59f2cd0", + "0xa7be733b64d5c06c127bd1c87250e42bfe30ca91ed8ce51e0b6e377f454e8f6fef7f99bff650695df2fd10c375da349b", + "0xa1b97145dab30330eea2cdc8739b2446a3704b64505fcea3dd8a9b4a72edf222e98d967d6fd7f76794acfd97aa091065", + "0xb2127049907d2a3b654d1c940b740bfba3dbaf660f86ea79c2f909af7c9fe2a07a1caeb1be12370aeffaf8faa50f1582", + "0x8a207701214bb28e99b0784e9228b1c34afa701966267fe7110f6f29f5bb41eaae6cdb98844d0400787978fabd224de8", + "0x9925147a383b6f5f814520220ffdbf20b214225882c3ef49b1a1ca677709176ec82466fb9c4be2dfbe5640afb63b014a", + "0x8416ad93871623fb555b5390b80de99edaaf317350cc0c1ae9d54d59517074d40061f315cce8ba2026d9c1e6f6a1009f", + "0xa315f943deebbf0a2cdbcf3f8323e215a406e9cbfbcc3f6288714cb3a6befb1bf71b2a21ff7a2ec4731c65044c45b6b5", + "0x8213e0c2539c24efd186ffa8b6dd401ad2233bc19166a0623b26dd1e93614bbf792823f5599ac116231e2efde9885709", + "0x8e5cafd2f34a127a4a896f05e4d929eef06972a1826b3566446942198df26d62f7679b987db2b3765d9d8058b1cd85c2", + "0xb5302b399c9cdf912fd59007ad4737255552663b1e56dbe64a7b2ddd88d2093c73ea319b45db2dd49d1e03f5bef1a0ae", + "0xa0c2bcfbed4b008e1a56e5d2f2419aa59d7dd0ebd990f1c18588de702ad0fa79f445d69965fa9381e700eda13b309378", + "0x80a44eea1ffe24c26b16b8e2e70ee519258b9ad4b3e83cc4e5cca88ebc48d0160066f8b91d0581095b0de2428390c8b3", + "0x84a90cb9c7d2f799f1c4ed060387a4b793ab41c5c3eaffd3b60face9b9c3bae93cd2017283bf3de1e3dac63d0d84dd42", + "0x81d22febca276a05ba9bbc5591ee087b0491beb35b4d9f8fc0d041d642a574667ddc57660b20f5c568f7d61fdcb41bda", + "0xa3ac965ac27a28e102a439b74fbfc157e75fd57620e4c0750a466165f8aeecb2191dcf8e656f7525aa50d9c7c69b0b5c", + "0x913c17434ff0d9fc52e2ece4fec71b37d4474a18f3ea26925c1be2b250434d49759f58033ba0fce1c6862c6197930dc4", + "0xac430559c151a5e461f67b49c7786c97e1653fa8698e9759ddbdd99f5daf17fc5a012ae6330739440880728f24eba7c9", + "0xb10d8e9f8aed9361b042d1398ec74364f7c7c1cc5c7f917060572761138bdbe89bf409389ee3879f93bc8032dd67b308", + "0x937271005a4cc6a6ec134870c1b56471aa84ed4f4af1b3d5f334bc0c42762fae0c9a6a2828d3de6151a76dad7b72781c", + "0xa10e4dcf51889f69e6bd4c052f8d4036b9571ced98a3d7d779cbcb9fa5c3a82228566ea7cc1d012bf56dea0a40c5a64c", + "0xa0ed026528d9a8bb3201bc9dcd20598933e8c72fd315deea8da63d06e97392aa729d98a55a8a60fa4d5573513ba5c9fe", + "0xb723fcd04cddbd4c36feae827a03746ffef251c4f4c55a88beedaeeee194430a99f566f483668a0d88b13e7a4a37f1de", + "0x84a2cdceed44828c7c05a6a762edec0165e434e7029df617d6646aba48776e6c3b823f40689cee136536f8c93e08a629", + "0xb786264e3a237ac3a1d56c9f4e87438dfed620c867100fd38b01287f5b755c7820937403bfb86644e082094d3e410a00", + "0x92cc35b2065fca157c7bba54410f8bd85907a01c9f760aa0ddb7a82cb55811d24cb4dc6b725367a6a1c293b809a48ead", + "0xa12bbf22b117f00164a42515bc57cc9e6c43cc77fb737ee3d0c0cad94cb50cd3847d61cab469cf8ca76f7958bdcfc771", + "0x85985b00de533bde2a757eddf53be79ea39091d16af3fc92327bcd1cd59bf2bf4411a334da29ad775e8ffaf3cea7d7b8", + "0xaf9eb24185b0d330d0ea1d0b0fa78af0dcf42ced81cb0128f16cafdea687a9c5582bb6d7c5744117b271cd0b3303f0b5", + "0x8c8aaa1d85ed6327f85d579767c7a9158d209171b3efcb3e8a9d9e534c078e821b6aade255101d2c9ef6d67ba66f10be", + "0xa450518a03ffb40e1df89e0f88fd55b5b06f4872cdfb7ec55f40dc40d9424b3b289866336c195bdd54597d95569e0096", + "0x81e61cc69f93c435bd77f155e80626a9c764dd92b6c76af15c41346527948d8a6ca87d6351a0fe7987e2ee3aa66a9625", + "0xb615e0cebf4fdff4cb23a20c8389c370915ba26aa703b28efe4ab070b1603d1c5b6541684acf46b52a915f6aee447539", + "0xa7f51885c7a71885cc84ef734ecd107e8bf5f7a25131415f671d143cc1de92859e65001125323c7985799993af6c410d", + "0xabfbf7a46f32066989c32f774edcc68163f085ca81e94fe8c9fb32f8d451bbb2c20ac45cd8d97f9e618ab40186933b1a", + "0x8cf35a522b5cac1934004aa9dd236bc77198d43272888afa860cfc79b4b28dabf7a3c74098f84510897566fdd609aa45", + "0x86aa927df78f7a06a4985eb0a4f0b93529cef14f9fd2812d46abffbf25e618ead14d99c70e3c3bb2e17f3f7fabc9c264", + "0x860f1b4f4a398e9a8bb4739587cf96979cfbbe1687b7e91e5bd1198db726391b09b1a261bf12e96698818f60b5bd3537", + "0x8e7c4ee19ff115881051e8637dce1f5d6c65e865d0c757e8ce41b6d7bcd86c7070cce60649692bbf28c868c7e2e1e2f4", + "0xacf7ba01b0220419f09169ac8d16e5cc13dce08e88c90b8fdfaa33aab417f011a20b79a178d8a9f7211589d2e0affd7d", + "0xb404bde8e715aefbb9f20a353b911b79173ef3e2cf0aba98b5ae6190b90597d65043b0b4e014ad9ea6c77da2d213ea12", + "0x97e3615d1c77a402253bb55da2d1cdf82de316cefffe42b1022c94b4818d6dc4a313731db85321c537914bdf716a875c", + "0x940e950b96a4096a578c6874d747515936652b9b113a5f27f5a834a610867b05f9881e2679b0b289b8527baa0009b6dd", + "0x8de15a13ca236a3a285ce6e6826c502ae7365bbe468b6e8ac67b15b0bb49be0e996f1eec81ef69e4b7f54f8e4779a054", + "0xa12244777eacb08ecd42b5676b3a51153022ab97e9353ace0f47c6054c22de9ba60d2a60f59a36841c2a791cb1b7c288", + "0x94f7580203e39a2642ee2e7c969b9911f011d7f3a90c398e1302d26edb3df03df1d0c43baa1c6cf90dde95296d49e742", + "0x82ead33144aaecab965faf63af384565992f38fc1066e71e33d53f43ac93892e27fe78c4eaca1cccbc53364e26ff31e9", + "0xa0c129e9706d354249a7f8aa664ccd7ede89aa1445c5547410814b56d10dc086720953363ab1da8ff5f1ed5d8e575104", + "0x93b3057bf3f74edc95237781ae012cc4b1d3fd0455565ceaac7110290aa518ac32478ba4eb9851555fa87270fcc84f1f", + "0x949c2fd0b94f31f7cbf00c679bd3f6ec1a2f4056654708d39edf1a450b4e19a6e251d0bb24eb765087e698f61d3fca2c", + "0x99fd2e50e211ccb66b895eb2fc42f260f3ad5767f04c2fe238b81dae98aa6e3977443a51f4fe7b43f499caabe45699a5", + "0x84fe19626503218f327b5325bfd7c0c3d2614b47d34964aa0259d564e769c6c81502132cc1765b0b31fbe39852706927", + "0xb43287ec29d9010bec4284de58fed48dd1e129bac79f09d45153c9949131782f77b11b0c9f8ee06a39e5e9bbaa8e2c6d", + "0x908902f3ed45482df2f94415fc8e5a308057a40c8905d7cbbd58ec4848e19276577b7f7e69e5e684a8b981738e10f7ef", + "0x85cc7d9c1eae372b4f88758cd6e21604b4bc9f0794e1e74b6d9de96347f81944d01331385fae7a38e5f6096c1dc23465", + "0xaf60288c702082fc258b3dbd6952c6b75c1641a623905f491b1e72f49b9d39b33d150a336450abd3911a4c128166acdf", + "0xa7d8ac7e589558c4014369ab6f4c1f2196205b03e4278152ec0dbbd7ba54e803c3369a71d364a773aac8dbbd117e4a13", + "0x9833aed34e48c206e9328073597aee1123f5bec085339b4e6839a389a429bf3042798a31fac1464ce963204adface76b", + "0x84631a4f012bbb62133030224b57deb32dcf464cacc8ffde7775adbe68707263ab5527a1c75e597e03aa703ba658b889", + "0xa686a61f6467858a2a4c13e70ad81b1901290d3e51bbc0c6e366f9e652f575e91b11c75f640ccef8b0c6c1b05a43c9a0", + "0xb585f0ffd5144907703b41539bfad7f9f058f5985f63db911064ba6b07af8da2796b84b16db42b8d11135c3f846cd9e2", + "0xb525539516c7bb25f1d7e165f269dc8c9eedbba74df44887e178ab8fd798e2a31f39812ca922d6b64d91564f14012a64", + "0x91e480d7568fd2fae39c35b0a8d623e66a3160fee1dd4e9097255004938b11ac1cd3918dc6a1e5fbcb700c95a547e5e8", + "0x936ef55c69b842b6177de71fa48dc5442bf5132116b214302f8f242ca36a273a6bbfbfaf373777104dadbe8e7da5e970", + "0x8e950c0f6688abdff8a3b8bd77be6da6f2565c7b55711f5860ea62a3ab1d51aac31821c602bc11a45e33c69e7dde3ea4", + "0x90eed4595104a0527f8db1e028ff622ff70db4eae99cf47f6c2a0246ec7b103570a6a9a877e32e9647cc74969006743d", + "0xb756344f6c4ea05b792e416d9bd9ce9dd4bd904e7622761f28a85628506bfc9d88a25e5f04db62fad30a92fb1d8d8556", + "0xad79ba76534c1a02ac3e9b7308d390792984cd75b7e1d0e5e4ff123642d99d4ea1825643091aa8117336333c40d5bd94", + "0x832b08144887de0c0341d84f6945450af8d7a4eb32367d7703118186c1be525df9382ce61fed5f3b65a0bb3449185f7f", + "0xa322fb944e46d8e47994820890c94af423674716da810ea1da71e0a7733ad72c22114ca39a4b59c98ce4291a5684c154", + "0xb982851a65140dbea79bd3b5487e236feccee051deddcc17c2853032efca289ddb6eaf64be3dd85a73012fdbe9d2d4f3", + "0x8eed5e230e201830b44b9fadca4e156fe1a16bf840cf29da0f381ea0587b20c226de2465c67e6268973e776809af68e1", + "0x81c8f1c04490f36e41a53ee1b5185cb8adbb37c258fd6c3be8c56835bf574c37183a94d55b6554fca35d6e6dd9af0133", + "0x8c4928724107cc16d36f2976677eac0b852fc4c3c0bb2f9cd4d59cd24a113faf33b2faf405c3fcce25be51d41e42c2c4", + "0x8e4ba842636fdfc4d71f0983538ea5037d420acd26abd12efca48c252eea85544b2fa9fccdfec4e7c2a6359baffa112d", + "0xb4315b84700e26dec26f3488d308430fdff4809c10d4c24309627911cbb769ffaad0d1ecccd622dd02194eaf5ba59f91", + "0xab888308f757faef32648c1db01650dbc9aea248b09d06e6efcc996d395f48ec96f2d54a02de441d753fe8737862d991", + "0x805094cfd77e207d5c75f3cad99f41f763ec15443052cfd758c6a82ba422d831a1103a7f9b100da49c28198279c3d3dc", + "0xad857f33243e4a2cd2a773700def21fc7f94939d1a6d2c2125ecd58fc206ccafb07a2c02a1cfce19857d3654aca2c70c", + "0xa4d12d40149953daa70b89a329e918e9d93efb4e8004a9357fe76682dab9662c8507e16db83e849340f05cdb4933a373", + "0xa0dbac2ed4b5d03606524245e8a31080eb5bd3e9a0c51dad88c3b18e3e6bc5d64953a81c8e60425b80107ee6b62b1fb4", + "0x86da05355900f327164a78901f6e3db857531b33b1e855df1a67a9ba222c6b05fdb6b0ffbacaeb1ba5b45ff8979b6b68", + "0x932c9873aa3e226dd922b5a616c75153bd0390ce8f332a414b9c8cb6606c2501a37a2aa88097bc7d8e2c4261706eb38c", + "0xaccd9cdf07ccdd42033ce3b105e00bfd39e2304b1e3d66f8b1128645634452c20f759ec45adcef2fdf04408f62c4cc04", + "0xb75cfdfc1cb48918752eab17eb579820ee6e71e6667abdb64df834ffc8c1362fbbc23ca2c80dee248fe1fbb72d87dfc8", + "0x88b998c73b00638fde7d3dd650a08c5ab996dac6ac34251337fbff3fb5ae4a25dd20c1a16c987ad7ded19eca23cea891", + "0x8afef0956c942571a27f504553fb312cca9e50ce41b44e0466d0516c5abe4d8acf4594cdb03b1ccdbe3f2e6a9093b713", + "0x9042cd83c5ff261e9ebda26398caa16cac2cb840d19062fa8ae50e044c27104972948318f4c866dc4d578798272d3e49", + "0xad536719a64570a2cd1d72b6590ea1d02c8c49f259a7867be26c8191445165954bcfad50ea12688ace3fdfb0e98143bd", + "0x97c86328d63d297b6bc9718dc1ad5a05b908a750d1c455c700d84315589128ce4eea958aef2bcf0fcf4adbd8e3ce58d1", + "0x8e592cf0802e6a9541eeb654dc55055e11f3d757847285197132935ca35bbb1a9156829a39384dfa6f645ff89eb36738", + "0xac16c614998944f77590bf3913a010e13f2d3bbf6a172293baf5983506c1a2d89989fb72e598f5bba1ea10a691377c93", + "0xab8e6f5b46baa6632de3621497bcbdd584decb999fe7d8a3364843a1e0b76497600630b6a24dd30119d8bcbfca29f335", + "0xabe1d3af5279e60122d9cea8cc6581c819d7a0e20e3715da0f6da7e02d13a7653db643bd946e2fa9ba338eca81fbe140", + "0x8c33bd831ecfb18d1d0713e16beba768e9c42df62170c1f8a16764912be77f2ac5915623d1d25e8c462aa9c2f6669ca4", + "0x903692becae4a6409f7bdb127d9b11de57a5739fe24218dcbaa0092648d5332dfeef29a908ee9e43e5e0a51a4c3639bc", + "0x92591e90347ae286acd365eba32cd9ad8f20f4c9cad2dc579b195147ff290adf0d776bcb3d4b04a25d68a941fc0c781b", + "0xb64bbccf860299aec16e1f95c768a1f337c740bde612e6ba260e393edb8b04540127194761c42597abb9bcb771c576c3", + "0x9194f056ccfdfeb78a11c5347e2255d7a7ebd1251f9aebc0b58feb68d3e03a7dbbb74e3ef7309455853adfb4694bd01a", + "0xaa4f15f6d6a53ae65b7f6f91e8981d07a5919d2138679a561f7bb608dc4596e45ca06c9441d51fb678b2ad89ae7a17ae", + "0x90e3d18507beb30bde08c5001faf489a19ab545c177efb3f73fbf5605f9a0abcdc8bfbc44f832d6028e3e0a834bea98f", + "0x8f31dc0118c8c88a6e79e502d10e57652b7aba8409a5bf572ca63fed6b7cbad7f28bbc92ac2264f649792fc1d0715085", + "0xa307d1067ea4c56437b6f8913aa8fcbf4a24580fc1e3336e7f6518f0f3adb9c4733090e459a3f737414ec0048179c30a", + "0xb7cc41fdf89595cd81a821669be712cd75f3a6c7a18f95da7d7a73de4f51bb0b44771c1f7cd3cd949e6f711313308716", + "0xa9dc74e197fe60e8c0db06b18f8fe536381946edecdf31e9bd90e1ebfcad7f361544884e2fe83c23b5632912ec284faf", + "0x8b3e1e81326d611567e26ed29108f33ddb838c45bbd1355b3ae7e5d463612af64b63fff9fa8e6f2c14c8806021a5a080", + "0x92f6537bca12778866335acc1eb4c3dfc2c8e7e5cf03399743dcea46aa66cac92ac2963b0892784263ad0ebe26ffdbf6", + "0xb5cc0061f7a3e41513199c7dd91ac60d727366482a4c7328527f7bd4fc3509412f711bb722b4413b3736a219b843d15d", + "0xb3e9711d68d2c6f6e2cc27e385d5f603d9a1c9a96edeefa1ffdf390439954d19504d6aadc566b47e229ad4940ef020d2", + "0xa09d0d3f0e5dc73a4a0827b72710b514bbfce4a7fcd5141d498a5aad6c38071077f50d3f91af897d9ab677b7041dedda", + "0xb177fe260f3b86e9ac21f1bfbe2682ae5dd8c9aecebb84f37054bdab6e39094e611ce582210ceeddde66adf759dadb6d", + "0xb0ac6595eba9f5dc4b2fd21856267cfbcfb5b12aa34ec69ca32b80071c5b652e85c25a224d80443d503bf25fbbfe07e9", + "0x81f3c0e11b196bd4a2e8f07f8c037002566dc9037da81f3988add458a520c24dd1be3d43d851e28c0c6a85de4b57a542", + "0xa44308c95615f7fedb2d2127012924468c015df9f48359cc2e36ab4223870b0bfc1e9040baabefdf5266f93afaad896b", + "0x8493ec4c32d5a13b81039f1b436eb83f259945dc950e3c6c2ccf5087ec56dd2f60890ed4edf01728b6a54950e19b35c6", + "0xa1a439ec2a6a95bdac9aaa925ff337ba956c0d236ab5318354270e73ed6b73b4ae2d27b4c1686cf97b6526d04e65be81", + "0xb4659b7b53c55a4b2bbe210b53520b392f893500e18990d843b72d7379d45fb44dd1dd2184348d6fd853d6b9ecc6b7c6", + "0xafb2c68d75d00130b0e1b4f250001920213121791698ec04262db714cf7b1408d39f6cc10421f954845aad5b8250b77e", + "0xb22b843b40a97210f94043b552f348f66743055a3f274856a738e7d90a625b80e9bbb80cbbb450e1666eb56b8bd5c60f", + "0x800895ced82fe13d5fff65a93b0051c3df698bf1221b682accfdb63e3970f669ca37025750697f4e8ff2a3322ad57be4", + "0xb21f598c50d7b9f4a584d548f85e42055ef8e24991906d973749090261584c7f4f5e984b528926f7e75375dd84d51af8", + "0x849b1c68192d18274598dd6d0bf48fb5ee3b1ba25b331cff2d06f345bef3bed49760ca5690848cf33388f6a9a32cd646", + "0xaeb6fd9478b10ef456f6bbb1e6dd19b14475e65497772d12cfc097948383d3fbd191bf95f046b8bf1989954118e483d0", + "0xb1b5e0ea2835f7fc8b66e7731e392b43d16cbce04b52906b6751ab1b91978899db5fecbdabc23a19dabb253005468136", + "0x91b6b1284770cf6f7ef35bc0b872b76c7763ffcfa68f9c8cfabcb2f264a66d47598bb9293f6a40f4c3dd33c265f45176", + "0xb9ffed029846487c2cfb8a4bb61782bd8a878f3afdb73c377a0ebe63139fa070e3fcdc583eec3a53fdc5a421ff1fa877", + "0x998007249d041b0b40ff546131cfc86d0b3598dcedf9a8778a223f7ed68ba4833b97324cbb1de91292b8ff51beab44b3", + "0x8eb77ce9e0e406bf6f002870fb2fd1447646dd240df9bd485f8e0869298a1fc799d8a41b130c04370e9a9cc5c7540ca5", + "0x853db8157462c46f2af7e8f94f2ed1c9b9a7ba2896b4973296898ff3d523d6e29e0b63a5d26cecd5e490b33c87a4cecf", + "0xb1436b6f3278768f0979ee852944258f2599977d255bea6fc912ba17c5dff5bdc850cf3e1fc52be9d6d188e868670f4f", + "0xa76acbc5832019b3b35667ab027feff49f01199a80016620f5c463dfcbfb51bf276ed17b7b683158ba450660cc7973eb", + "0x94540cdb051faf3ae8b8c52662868c2dab66bd02505c4f5f8eb4d6b2e2e5fd9a610890c5dcf8fd887eee796d2b5753a8", + "0xaa35099666bceccf4eb3b65b13bba88e30a8be93693ab6761d8e5523343e8d6dd42d977e66499352fe4e9e9784a1dd0d", + "0x894471aad17be54319083c4b5e40adcfacf7c36c4aab0b671030b7ef321c53590a25eccd836efd20f32a93185fd315bb", + "0x8f52a9f705bb0dea958fcfbd52e2b6c08ad0f89a07a6b2942c1b4c37eead0d97a38a9e9aeb08d5d59b7fa2a9347f738b", + "0x9031c16b4f936c9cab55585dc5064739f696c3347ee2c0792320c9f749e760d120e396e8485ffc79d81c9f3337ad3d1c", + "0x82090a0d0d9b05459ec1c328ecd4707c333b784e3aaa0ef0072cee1eac83f9a653a75d83b9f63512a8c41200494826b4", + "0x92c3a9553001f9ea4d67236b8ad1a33275378202cc1babc03f313895458f4b2549bfbbbdd37bfb8fbff0decb6b9f820a", + "0x88651868f4da37338a22bc553388df5dd1dd0cb78c4d7d07c637d8f6faef4bed72476fdcd4304d5bedf3514011135f08", + "0x83fa0141bfebd88063f1d787719721b4c6b19ecf565b866de9d7d5d1a890e0e3d859b364bb65f8f8e688654456a40263", + "0x90a7fab753e5d56dfc0e53a6b4e6ab14508220f3a62b3f3f30570c4c9ad225e74122635826c92e8e3227ec45e551432a", + "0x8fa375b0345bf6e5e062d108f9feaec91029345ecac67ccf1264eac77b8654cbfdda1f10579f481889c0e210254eadde", + "0xb83f06116da9daebdb013b26724523f077debaf6bc618b48a7a68858a98d275f7899c4ec73a0a827219b9248dd81c8c9", + "0x8be1cada55e0c5ebb4fd460b2d209ae5326285a20c8bdd54ed9d1a87302f4063c8730bfda52d9d40e0d6fe43a0628465", + "0xa68ad6f813743ec13a811f2ef3982c82d9d9ac1f7733936aa1e122f8dc7f4a305cc221579ab8fc170c3f123a1576f9ab", + "0x8878f1128214fdbbb8a0edd85223741e021508ab6d36c50d38680f2951ee713ea056ed03f62b9461897963d50ceefe0b", + "0xacc0d43d1b0260528b7425b260a5dea445b232b37240759fc65fe26f7c9d8e51569c5722bc33e94de6492f4ba1783504", + "0xad80b1dd717b076910ee5ceabcb762e75e4d094dc83b93b65c16de1f75bc712cef223c05d5579c1561829406c07a97d9", + "0xa6fc9803f9c09d95fc326cc284f42ea5566255eb215dba8a9afb0be155ea11bcc55938b2d16f01cd2f2eda218c715efb", + "0x83ad733dbdfbaae8095a403dbf09130513f4ed4f08dcf8dd76ce83d1ea72999b7eea3a7b731da0d2bc80a83c6ee0e3e0", + "0x8748912fbd08cb34a85416b0937d9c4327e9eed20d6e30aeb024a7253f14f1e0d774f3326e54738d71aae080e28da0fe", + "0x8997e78d8acf23051428af67183ae9b2c4aa42b503745ffe33df35a35103c589987e1473ab14dcd28ee78ebcb10d8e95", + "0xa2f340502a7eb3c4a36412e6f028321372c4fa18a4743945607424e932af1271fa3e6598a162c872072529576eba6283", + "0x868ccf19b5044ab93b45c9ed3ae34fcb504fe1453d6c4a1d12c325032cf01eb90356de82080ed897e97dba13cae33a02", + "0xac8867005fe4354d67aa37b866a7e581d2f94f7bd0b9f4efb5c2d1370ec13147a60692051b02fd00ae60b512bce9b1ff", + "0x8fd01886b046819c83c12bb779e432b25ba13713f9227be702074ec3abb2bba6be37220a0a26a4bd4171b99b14e32bc4", + "0xa128981ed199f92b5959975c150a93a62fec50b61c80a3fa0634d90fc8058f76f5cbee77aae6889af12d296b30e613cd", + "0x81fe618552ff7a36c9235c6d4066cf2f930b5b38de4089e18166e4a06ca5723eadd1976d25e34b74b3ce942300b23e5b", + "0xab1223ea049e6e0fbf9b611de7fd7c15e5e9637cbd73aa0e36aea08a7503ba6804f2aa807186fdc9aa7f4f9195f72e24", + "0xb97285286981b2665f898abc13f3243b63005bef8db4cab3f658bf6167036b61af400f08db0fc3c640a9c623b760690d", + "0xae3ddff7c1f0fbb6a13dbbc667a61e863c2c7c51c2051e33cd61620142e7e30a7e0c4c1f8fbb512aa3a8640267c6ac26", + "0x99c2a89d5bef236060e51c4f952664094c20fbfca647e5d24a55c1fb8df2f3df58244fbbf3635db07b1c29ee3234fa6f", + "0xa5010764d4b9cd3b410638334d1f70c5f4843f45b4f4a9316aaea5fbb2c510a97449dd7a07b49f47334a69d37d9955d3", + "0x86706d011dcdc9e9d165d01fea1df68dd74bedaf15a39f92893c030cafe96f4498c4c1fec2d2136354341b3f440a1462", + "0x88fd57eb62bd7dc35722f3a0576c2138403a2f663a2603482e8974a895cf56ddbb02657dc6b89eb2cf5c1f9d1aff6426", + "0xb0dfd4c68e3acb6bb8a776adaa421fc5e268ed4d5964bb90a727091e5113b55b3f9c6d33cedb3ee47ff7acc5df8b1749", + "0x93b92bc942e1a636fc5c2dc1840de5faf158a113d640d5a475b48e2c56ccccaf9db0e37e90ce74c4b3f5c9ac3b2eb523", + "0xb29a16fa1ea95cbfc1873c435ad40dc8495ba6341801b72bd95d908147dcffb1b4bb426dd635f3af4c88984f56594dd8", + "0xb8f367105e1a2d554ac30200c66aeb579d3d30a8953d20fb6ebba2d876ec39c52ea5d654f1bb89b8ddf3d9d651f31cdf", + "0xb5fbc228c983d08adf8612eba5b3db3acff604439226f86aa133b02cce4ffde2f977c8dbb8b446b4375673f71634c89d", + "0xa399bea37d3056e0559f6644faa0af93063b4b545d504d7e228d3dbbc294af83d3c4cf37fe026b63899b4e7d50fd08f5", + "0x928ef411a36414b24aea26fdbed4bdb1bb6bdc2d967e2553ce54c7c4e077e76869cea590257645c9129dd55ce025295c", + "0x9684a4adeed416a9ce82ad79b55c4a3adcfbd43950bc442ed8a340381caedb70f4baaaf821e3a152f483f965d8f56162", + "0x92558a37f214d6f4cb6d72cd2f4ad24dff9d17611b9e4a41ee5c741a5d1ca9e4053b0584533ef4da206110b5dc3e2a35", + "0x973bf0724d1785cc5e85d2a8ee8c354ad4cf557217ced0b7940f6f064024c20b2bfc5b144c820b5083da4bf70690de4d", + "0xadaf1389dfa528210ca9c2657c5ff10d51f7e3b18e93a59c37211be0506c3576cb2c04ec80cd0f82605e53c5a3556620", + "0x85b58b223b09fda6f3ab674d75e780c49eb2167837243df049281e8f4fed653811138b398db9cdfe7405fdb8485602fe", + "0x849504d3db408d80745a07e850b0a804607b91a59922a5d3bc40da2748c029c029419cda38d2a4485cc0824c6b2504f0", + "0xa3f4afcb353bc2582a02be758ebf0cd18752410ca2e64231176bfa23828423e0a450a65f241a9ed8eab36cae8d9c567b", + "0xae362786cdf121206537af9590d330abbc6dc328b53cdd145dbed0e5df1364c816aae757c4c81f9d619e3698dd32bcdf", + "0x9024cfa5b0101eb02ab97866d5a3832944e5aa6888484cfba3d856576b920787b364fba5956bd7c68a305afedc958201", + "0x8a116df09fed923acefb2aecf38a4fbc4b973ee964d67f03791d70bee6356af43ffca117d4e9463ffaf0e0d5d5e5a69f", + "0x9163016175c73f1bbc912ddfe03bd4e1db19c64951c8909ee6befe71a1249d838e0db49f03670bb4c5c9b2ab0fb4fef3", + "0x8f6357318d8d16e7240a02b05ce5a4976b6079d49daa258789c6dbf4a47950ebe9de6411780fab06c7c1f35651433380", + "0x8e63cbae8be7341892dbedee3111adf0307c4ee9e375181aa53478f5ba9cdce164d6ae890e5f480119a3a51c6e989165", + "0xa9782f30674a4874d91bfba7eda63aeb5dbe66b040c768d6a925d8ee135f0655ea56276b105239cc0668fc91ddb68cd1", + "0x8d9d94b61ab84ec08665cbe0244ea41756785df019e453ef078c19380bd44c39d2958e8465c72eacf41eed5696037805", + "0xb1470e6f5d2e314474937cb5a3bc30c8bf5fc3f79014945f6ee895fe20028ffc272f9d3a7320aac93e36c96d8a5454e3", + "0xa444911bbafc71179766594f3606b6eaff041826607fd3192f62dec05cd0f01b78598609a530f6930e8440db66f76713", + "0xa9823d44e2638fca7bcc8796cc91c3eb17f46ad6db9f7f6510e093727614aa3a4f9b2c4011ef91dc1c2d224d08d8d05b", + "0xab86020972c359ab98294212558b4b14862040139876c67fc494184b5c9bcea1dbe32fe0c8dd9e60be9daa304acd599a", + "0xb7e5cb685bbdcfdb1e48259a5d68d047846c8a35c5b3f90172fb183d1df40d22eaf0edaca2761a07c29c577000ccfed0", + "0x8c88319dae4b28989817e79e6667fd891181e8d2ed91b9c6b614985bca14b12982462ec58b17be0463c24bbb79dd62a1", + "0x8c1c6867e7107fb2178157c991b9c8b0f90c8d57a51220bf3650438ccabccf62da4db8a9916491e730ff3d0c106496e3", + "0xa00a79bd58da6528b9af033087260f9f3d00519eafb4746b355204ee994e89481591b508eaa5402821083e250d38467b", + "0x8785abd7c37690f6aa870ee5c799eef72e398a7898b6767f698515be277b9c2fc1af12ea89b0620a848221343a3b5ec3", + "0x8aadae68543db65cef71d0e230a09508d72061398ef2fabec0f856aacff2125b79c70e620744aaf331faf3dfc8afb9bc", + "0x8ff0cd437fcad9630b8a2333176a55e178db4142ec841581590594d74d5b53baeac5fb903fdf7bcf83e245b95b58285e", + "0xaf274e8fad6b190be4e5dc92d2705ba6ac0d7e1ea29e958a5cdd4cb764de46a56d9eef62c999a16e7c50a50b2d9fe3a8", + "0x865e6ec7d1aa848786d6a7a4e87a24d442311f0810b01ef5a74928ab59fdfd651e48880b49680047e5b0df6b3c7c2ecc", + "0x800706baaeb35bf3bc33bdea9a8b5cb00d82df407b3b7e1b781a9359cf44fb410ed311591080181b768aae223d9246aa", + "0xa9496389d0780b309c6998374ae159f58a8d0fe9a1c24c36cebcb45b27d818e653b51a8ee1f01e30a9b2c46a548126ef", + "0xb5fccf4fc3186661939fbee2e89c2aa0e3a6ad4907bcc98c7750520540c4c183b1bbfcdf47f2f1c5e75c3a30cdf30c75", + "0xa90028e39081b736e628c2230cc1338f9210ed01309a40fdf08d39c10cced2cdf71271013bea6dba3a0444fe47963106", + "0xa0815cbb325a8fecf2e1bcc5046644be32d43a8001bd5d8cf0022e4572cd0d481b3e717002f7ab21e16da5f5d16886d6", + "0xb2024787fcda52abc4138150f15e81f4a5be442929b1651ddccbfd558029912be4d61c3c9b467605fff640edf7392494", + "0xab5aa60032304a584cc9245a33f528eae7157808dedd1ad83ebae00aadc25dbe1cd5917eb8b6b2c800df15e67bdd4c4d", + "0x866643847ef512c5119f2f6e4e3b8d3f4abb885f530bb16fcef0edb698a5b0768905e51536283925b6795a5e68b60ddc", + "0x806aa99c9a46ee11cc3ebf0db2344b7515db8c45b09a46a85f8b2082940a6f7263f3c9b12214116c88310e706f8e973a", + "0xa6eada8b9ff3cd010f3174f3d894eb8bb19efdbff4c6d88976514a5b9968b0f1827d8ac4fe510fb0ba92b64583734a1e", + "0x98480db817c3abbc8b7baedf9bf5674ec4afcfd0cd0fd670363510a426dad1bcf1b1cb3bf0f1860e54530deb99460291", + "0x81ab480187af4a3dfbc87be29eca39b342a7e8e1d1df3fc61985e0e43d8d116b8eac2f1021bde4ae4e5e3606c1b67a21", + "0x8a37df12dc997bf9b800f8fd581a614a1d5e32b843f067d63d1ca7fde2e229d24413d3a8308ec1e8389bf88154adb517", + "0xb045a55ca0bb505bd5e8fcc4cfdd5e9af1a7d5fe7a797c7ede3f0b09712b37f493d3fcf6ef0e759d7e0157db1f583c95", + "0xad502e53a50691238323642e1d8b519b3c2c2f0fd6a0dd29de231f453be730cf1adc672887d97df42af0a300f7631087", + "0x80597648f10c6d8fcd7421caf4e7f126179633078a1724817d2adc41b783723f302eabc947a7ba7767166dacf4ce8fa1", + "0xaefb56427966c81081999dffbe89f8a0c402041929cd4e83d6612866cfbb97744f4ab802578349fbecc641fa9955e81b", + "0xa340e493fb3fb604eab864d4b18a6e40ba657003f1f88787e88e48b995da3d0ab4926ce438bdc8d100a41912a47dace0", + "0xa6d777bfc0895eac541a092e14499ff8bf7156689d916a678b50a1460583b38e68158984bea113a0a8e970d8a6799a85", + "0x90ce469410f0e8cfff40472817eb445770833cdcf2895a69bc32bcf959854d41712599ceb2b0422008d7300b05e62e02", + "0x815c51be91d8516d5adc2fd61b6600957ed07cf5fdc809aa652b059bea8ed179638a19077a3f040334032f0e7900ac8b", + "0xb3ec6c0c3c007c49c6b7f7fc2ffd3d3a41cdff5ad3ac40831f53bfc0c799ffeed5f440a27acc5f64432e847cc17dd82e", + "0x823637abeab5fb19e4810b045254558d98828126e9a2d5895a34b9e4b4f49ab0a5b3ee2422f1f378995ea05df5516057", + "0xac05412bcf46c254f6548d8107a63928bba19ab6889de5d331eb68cf4d8ce206055b83af4cb7c6c23b50188391e93f84", + "0x88514163c587068178302bc56e9a8b3ad2fa62afd405db92f2478bb730101358c99c0fe40020eeed818c4e251007de9c", + "0xb1e657d0f7772795b3f5a84317b889e8ded7a08ea5beb2ab437bebf56bcb508ae7215742819ed1e4ae3969995fe3b35d", + "0xa727d4f03027fe858656ca5c51240a65924915bd8bd7ffa3cfc8314a03594738234df717e78bb55a7add61a0a4501836", + "0xb601682830fc4d48ece2bdc9f1a1d5b9a2879c40c46135f00c2c3ae1187c821412f0f0cfbc83d4e144ddd7b702ca8e78", + "0xb5cfea436aa1f29c4446979272a8637cb277f282825674ddb3acac2c280662fb119e6b2bdd52c4b8dbf2c39b1d2070d6", + "0x85c211645ff746669f60aa314093703b9045966604c6aa75aae28422621b256c0c2be835b87e87a00d3f144e8ab7b5f0", + "0x867628d25bab4cb85d448fd50fdd117be1decdd57292e194a8baa0655978fae551912851660a1d5b9de7a2afbb88ef5c", + "0xa4e79c55d1b13c959ff93ddcf1747722c6312a7941a3b49f79006b3165334bab369e5469f1bddebadb12bfaff53806d5", + "0xac61f0973e84546487c5da7991209526c380e3731925b93228d93a93bce1283a3e0807152354f5fe7f3ea44fc447f8fe", + "0xa1aa676735a73a671a4e10de2078fd2725660052aa344ca2eb4d56ee0fd04552fe9873ee14a85b09c55708443182183a", + "0x8e2f13269f0a264ef2b772d24425bef5b9aa7ea5bbfbefbcc5fd2a5efd4927641c3d2374d0548439a9f6302d7e4ba149", + "0xb0aacdaf27548d4f9de6e1ec3ad80e196761e3fb07c440909524a83880d78c93465aea13040e99de0e60340e5a5503cd", + "0xa41b25ae64f66de4726013538411d0ac10fdb974420352f2adb6ce2dcad7b762fd7982c8062a9bac85cdfcc4b577fd18", + "0xb32d87d5d551f93a16ec983fd4ef9c0efcdae4f5e242ce558e77bcde8e472a0df666875af0aeec1a7c10daebebab76ea", + "0xb8515795775856e25899e487bf4e5c2b49e04b7fbe40cb3b5c25378bcccde11971da280e8b7ba44d72b8436e2066e20f", + "0x91769a608c9a32f39ca9d14d5451e10071de2fd6b0baec9a541c8fad22da75ed4946e7f8b081f79cc2a67bd2452066a9", + "0x87b1e6dbca2b9dbc8ce67fd2f54ffe96dfcce9609210a674a4cb47dd71a8d95a5a24191d87ba4effa4a84d7db51f9ba0", + "0xa95accf3dbcbf3798bab280cabe46e3e3688c5db29944dbe8f9bd8559d70352b0cfac023852adc67c73ce203cbb00a81", + "0xa835f8ce7a8aa772c3d7cfe35971c33fc36aa3333b8fae5225787533a1e4839a36c84c0949410bb6aace6d4085588b1e", + "0x8ef7faa2cf93889e7a291713ab39b3a20875576a34a8072a133fed01046f8093ace6b858463e1e8a7f923d57e4e1bc38", + "0x969ecd85643a16d937f148e15fb56c9550aefd68a638425de5058333e8c0f94b1df338eaab1bd683190bfde68460622b", + "0x8982f4c76b782b9b47a9c5aeb135278e5c991b1558e47b79328c4fae4b30b2b20c01204ff1afb62b7797879d9dee48e2", + "0xb5098b7ba813178ced68f873c8c223e23a3283d9f1a061c95b68f37310bca4b2934a3a725fff1de1341c79bb3ba6007e", + "0x97b160787009f7b9649ed63db9387d48a669e17b2aba8656792eb4f5685bb8e6386f275476b4dfbb1b4cb0c2a69bc752", + "0x88b69369c71daad6b84fa51a0f64a6962d8c77e555b13c035ad6fa1038e7190af455b1bd61ae328b65d6a14cf3d5f0d5", + "0xaf88b87801361f0de26bd2533554ee6f4d8067e3122b54161c313c52cc9eafea00661c5c43e2d533485d1f26da4e5510", + "0x98ab18e3bbcb23ac1e34439849e56009bb765ab2f2558ebfd0a57cbe742169f114bceb930533fb911b22cb5a8fe172bc", + "0x9027507f1725d81e5ac0f0854c89ab627df3020fe928cb8745f887bf3310086c58fca1119fd5cd18a7d3561c042d58de", + "0xa676583f8a26e6f8991a0791916ce785b596ce372812f5eb7b4243ba9367ea95c797170fdac5b0c5e6b7f6519cc2b026", + "0xb91b0ab32638aef3365035a41c6068e36d2303bfee8640565e16c9a56c21703270fd45946ce663238a72c053eb3f2230", + "0xaaf4cd1ac0a30906dcd2b66b37848c6cc443da511e0b0367fd792887fdaf1500551590440e61d837dbee9d24c9801108", + "0xa06f20a02d3cd76029baad5a12592f181738378a83a95e90470fa7cc82a5ae9d2ed824a20eeb1e96e6edc0619f298688", + "0xa465d379c3481b294efc3f2f940b651c45579607cf72d143b99705eae42103a0279eb3595966453130e18935265e35d6", + "0x892a8af7816a806295278027a956663ea1297118ede0f2a7e670483b81fb14dccacc7a652e12f160e531d806ca5f2861", + "0xb480917c0e8b6e00de11b4416a20af6c48a343450a32ee43224559d30e1fecdece52cc699493e1754c0571b84f6c02c2", + "0xb3182da84c81e5a52e22cebed985b0efc3056350ec59e8646e7fd984cdb32e6ac14e76609d0ffaca204a7a3c20e9f95d", + "0xa04ea6392f3b5a176fa797ddec3214946962b84a8f729ffbd01ca65767ff6237da8147fc9dc7dd88662ad0faefdb538c", + "0x95c0d10a9ba2b0eb1fd7aa60c743b6cf333bb7f3d7adedce055d6cd35b755d326bf9102afabb1634f209d8dacfd47f1a", + "0xa1a583d28b07601541fa666767f4f45c954431f8f3cc3f96380364c5044ff9f64114160e5002fb2bbc20812b8cbd36cb", + "0xa1a0708af5034545e8fcc771f41e14dff421eed08b4606f6d051f2d7799efd00d3a59a1b9a811fa4eddf5682e63102ea", + "0xab27c7f54096483dd85c866cfb347166abe179dc5ffaca0c29cf3bfe5166864c7fa5f954c919b3ba00bdbab38e03407d", + "0xac8c82271c8ca71125b380ed6c61b326c1cfe5664ccd7f52820e11f2bea334b6f60b1cf1d31599ed94d8218aa6fbf546", + "0xa015ea84237d6aa2adb677ce1ff8a137ef48b460afaca20ae826a53d7e731320ebdd9ee836de7d812178bec010dd6799", + "0x925418cda78a56c5b15d0f2dc66f720bda2885f15ffafb02ce9c9eed7167e68c04ad6ae5aa09c8c1c2f387aa39ad6d1b", + "0x87c00bba80a965b3742deacafb269ca94ead4eb57fdb3ed28e776b1d0989e1b1dba289019cfb1a0f849e58668a4f1552", + "0x948d492db131ca194f4e6f9ae1ea6ebc46ebbed5d11f1f305d3d90d6b4995b1218b9606d114f48282a15661a8a8051ca", + "0x8179617d64306417d6865add8b7be8452f1759721f97d737ef8a3c90da6551034049af781b6686b2ea99f87d376bce64", + "0x918e3da425b7c41e195ed7b726fa26b15a64299fe12a3c22f51a2a257e847611ac6cfcc99294317523fc491e1cbe60c4", + "0xa339682a37844d15ca37f753599d0a71eedfbbf7b241f231dd93e5d349c6f7130e0d0b97e6abd2d894f8b701da37cb11", + "0x8fc284f37bee79067f473bc8b6de4258930a21c28ac54aaf00b36f5ac28230474250f3aa6a703b6057f7fb79a203c2c1", + "0xa2c474e3a52a48cd1928e755f610fefa52d557eb67974d02287dbb935c4b9aab7227a325424fed65f8f6d556d8a46812", + "0x99b88390fa856aa1b8e615a53f19c83e083f9b50705d8a15922e7c3e8216f808a4cc80744ca12506b1661d31d8d962e4", + "0xa1cbd03e4d4f58fc4d48fa165d824b77838c224765f35d976d3107d44a6cf41e13f661f0e86f87589292721f4de703fb", + "0xb3a5dde8a40e55d8d5532beaa5f734ee8e91eafad3696df92399ae10793a8a10319b6dc53495edcc9b5cfd50a389a086", + "0x996e25e1df5c2203647b9a1744bd1b1811857f742aee0801508457a3575666fcc8fc0c047c2b4341d4b507008cd674c2", + "0x93e0a66039e74e324ee6c38809b3608507c492ef752202fff0b2c0e1261ca28f1790b3af4fdb236f0ed7e963e05c1ec0", + "0xb6084e5818d2d860ac1606d3858329fbad4708f79d51a6f072dc370a21fdb1e1b207b74bc265a8547658bfb6a9569bb3", + "0xa5336126a99c0ecfc890584b2a167922a26cae652dfc96a96ab2faf0bf9842f166b39ceaf396cd3d300d0ebb2e6e0ebf", + "0xb8b6f13ce9201decaba76d4eca9b9fa2e7445f9bc7dc9f82c262f49b15a40d45d5335819b71ff2ee40465da47d015c47", + "0xb45df257b40c68b7916b768092e91c72b37d3ed2a44b09bf23102a4f33348849026cb3f9fbb484adfea149e2d2a180ff", + "0xa50d38ee017e28021229c4bb7d83dd9cdad27ab3aa38980b2423b96aa3f7dc618e3b23895b0e1379ca20299ff1919bbf", + "0x97542cf600d34e4fdc07d074e8054e950708284ed99c96c7f15496937242365c66e323b0e09c49c9c38113096640a1b6", + "0x822d198629697dcd663be9c95ff1b39419eae2463fa7e6d996b2c009d746bedc8333be241850153d16c5276749c10b20", + "0x9217bc14974766ebdfbf6b434dd84b32b04658c8d8d3c31b5ff04199795d1cfad583782fd0c7438df865b81b2f116f9c", + "0x93477879fa28a89471a2c65ef6e253f30911da44260833dd51030b7a2130a923770ebd60b9120f551ab373f7d9ed80aa", + "0x87d89ff7373f795a3a798f03e58a0f0f0e7deab8db2802863fab84a7be64ae4dcf82ece18c4ddbefccd356262c2e8176", + "0xa3ba26bd31d3cc53ceeced422eb9a63c0383cde9476b5f1902b7fe2b19e0bbf420a2172ac5c8c24f1f5c466eecc615d4", + "0xa0fe061c76c90d84bd4353e52e1ef4b0561919769dbabe1679b08ef6c98dcfb6258f122bb440993d976c0ab38854386b", + "0xb3070aa470185cb574b3af6c94b4069068b89bb9f7ea7db0a668df0b5e6aabdfe784581f13f0cf35cd4c67726f139a8c", + "0x9365e4cdf25e116cbc4a55de89d609bba0eaf0df2a078e624765509f8f5a862e5da41b81883df086a0e5005ce1576223", + "0xa9036081945e3072fa3b5f022df698a8f78e62ab1e9559c88f9c54e00bc091a547467d5e2c7cbf6bc7396acb96dd2c46", + "0x8309890959fcc2a4b3d7232f9062ee51ece20c7e631a00ec151d6b4d5dfccf14c805ce5f9aa569d74fb13ae25f9a6bbe", + "0xb1dc43f07303634157f78e213c2fae99435661cc56a24be536ccbd345ef666798b3ac53c438209b47eb62b91d6fea90a", + "0x84eb451e0a74ef14a2c2266ff01bd33d9a91163c71f89d0a9c0b8edfcfe918fc549565509cd96eed5720a438ff55f7f2", + "0x9863b85a10db32c4317b19cc9245492b9389b318cf128d9bbc7ec80a694fcbbd3c0d3189a8cad00cc9290e67e5b361ee", + "0x8a150ee474ebe48bdfcac1b29e46ac90dcded8abbe4807a165214e66f780f424be367df5ef1e94b09acf4a00cd2e614d", + "0xa6677a373130b83e30849af12475e192f817ba4f3226529a9cca8baaefb8811db376e4a044b42bf1481268c249b1a66e", + "0xb969cbf444c1297aa50d1dfa0894de4565161cb1fc59ba03af9655c5bf94775006fe8659d3445b546538a22a43be6b93", + "0x8383167e5275e0707e391645dc9dea9e8a19640ecfa23387f7f6fcaddff5cde0b4090dfad7af3c36f8d5c7705568e8d8", + "0xa353ddbc6b6837773e49bb1e33a3e00ca2fb5f7e1dba3a004b0de75f94a4e90860d082a455968851ef050ae5904452e0", + "0xadeccf320d7d2831b495479b4db4aa0e25c5f3574f65a978c112e9981b2663f59de4c2fa88974fdcabb2eedb7adab452", + "0xafa0eacc9fdbe27fb5e640ecad7ecc785df0daf00fc1325af716af61786719dd7f2d9e085a71d8dc059e54fd68a41f24", + "0xa5b803a5bbe0ca77c8b95e1e7bacfd22feae9f053270a191b4fd9bca850ef21a2d4bd9bcd50ecfb971bb458ff2354840", + "0xb023c9c95613d9692a301ef33176b655ba11769a364b787f02b42ceb72338642655ea7a3a55a3eec6e1e3b652c3a179e", + "0x8fa616aa7196fc2402f23a19e54620d4cf4cf48e1adfb7ea1f3711c69705481ddcc4c97236d47a92e974984d124589e5", + "0xa49e11e30cb81cb7617935e8a30110b8d241b67df2d603e5acc66af53702cf1e9c3ef4a9b777be49a9f0f576c65dcc30", + "0x8df70b0f19381752fe327c81cce15192389e695586050f26344f56e451df2be0b1cdf7ec0cba7ce5b911dcff2b9325ae", + "0x8fbbc21a59d5f5a14ff455ca78a9a393cab91deb61cf1c25117db2714d752e0054ed3e7e13dd36ad423815344140f443", + "0xa9a03285488668ab97836a713c6e608986c571d6a6c21e1adbd99ae4009b3dde43721a705d751f1bd4ebf1ea7511dfed", + "0xb2f32b8e19e296e8402251df67bae6066aeefd89047586d887ffa2eacdf38e83d4f9dc32e553799024c7a41818945755", + "0x942cf596b2278ad478be5c0ab6a2ad0ceafe110263cc93d15b9a3f420932104e462cf37586c374f10b1040cb83b862e0", + "0xaaa077a55f501c875ceae0a27ef2b180be9de660ef3d6b2132eb17256771ce609d9bc8aaf687f2b56ae46af34ad12b30", + "0x90ac74885be1448101cf3b957d4486e379673328a006ea42715c39916e9334ea77117ff4a60d858e2ccce9694547a14f", + "0x9256cdfc2339e89db56fd04bd9b0611be0eefc5ee30711bcece4aadf2efcc5a6dcc0cfd5f733e0e307e3a58055dff612", + "0xa4c7384e208a0863f4c056248f595473dcde70f019ddaede45b8caf0752575c241bac6e436439f380ac88eee23a858e9", + "0xa3aa67391781e0736dddc389f86b430b2fc293b7bd56bfd5a8ec01d1dd52ed940593c3ad4ce25905061936da062b0af6", + "0x80299275ec322fbb66cc7dce4482ddd846534e92121186b6906c9a5d5834346b7de75909b22b98d73120caec964e7012", + "0xaa3a6cd88e5f98a12738b6688f54478815e26778357bcc2bc9f2648db408d6076ef73cced92a0a6b8b486453c9379f18", + "0xb07c444681dc87b08a7d7c86708b82e82f8f2dbd4001986027b82cfbed17b9043e1104ade612e8e7993a00a4f8128c93", + "0xaf40e01b68d908ac2a55dca9b07bb46378c969839c6c822d298a01bc91540ea7a0c07720a098be9a3cfe9c27918e80e8", + "0xabd8947c3bbc3883c80d8c873f8e2dc9b878cbbb4fc4a753a68f5027de6d8c26aa8fbbafeb85519ac94e2db660f31f26", + "0xa234f9d1a8f0cb5d017ccca30b591c95ec416c1cb906bd3e71b13627f27960f61f41ed603ffbcf043fd79974ec3169a8", + "0x835aaf52a6af2bc7da4cf1586c1a27c72ad9de03c88922ad172dce7550d70f6f3efcc3820d38cd56ae3f7fc2f901f7a0", + "0xae75db982a45ad01f4aa7bc50d642ff188219652bb8d521d13a9877049425d57852f3c9e4d340ffec12a4d0c639e7062", + "0xb88884aa9187c33dc784a96832c86a44d24e9ffe6315544d47fc25428f11337b9ffd56eb0a03ad709d1bf86175059096", + "0x8492ca5afcc6c0187b06453f01ed45fd57eb56facbeea30c93686b9e1dab8eaabd89e0ccb24b5f35d3d19cd7a58b5338", + "0x9350623b6e1592b7ea31b1349724114512c3cce1e5459cd5bddd3d0a9b2accc64ab2bf67a71382d81190c3ab7466ba08", + "0x98e8bf9bed6ae33b7c7e0e49fc43de135bffdba12b5dcb9ff38cb2d2a5368bb570fe7ee8e7fbe68220084d1d3505d5be", + "0xab56144393f55f4c6f80c67e0ab68f445568d68b5aa0118c0c666664a43ba6307ee6508ba0bb5eb17664817bc9749af0", + "0x827d5717a41b8592cfd1b796a30d6b2c3ca2cdc92455f9f4294b051c4c97b7ad6373f692ddafda67884102e6c2a16113", + "0x8445ce2bb81598067edaa2a9e356eda42fb6dc5dd936ccf3d1ff847139e6020310d43d0fec1fe70296e8f9e41a40eb20", + "0x9405178d965ee51e8d76d29101933837a85710961bb61f743d563ef17263f3c2e161d57e133afac209cdb5c46b105e31", + "0xb209f9ed324c0daa68f79800c0a1338bbaf6d37b539871cb7570f2c235caca238a2c4407961fcb7471a103545495ef2c", + "0x92ae6437af6bbd97e729b82f5b0d8fb081ca822f340e20fae1875bdc65694cd9b8c037a5a1d49aa9cae3d33f5bad414e", + "0x9445bdb666eae03449a38e00851629e29a7415c8274e93343dc0020f439a5df0009cd3c4f5b9ce5c0f79aefa53ceac99", + "0x93fdab5f9f792eada28f75e9ac6042a2c7f3142ba416bfdb1f90aa8461dbe4af524eee6db4f421cb70c7bc204684d043", + "0xa7f4dc949af4c3163953320898104a2b17161f7be5a5615da684f881633174fb0b712d0b7584b76302e811f3fac3c12f", + "0xa8ac84da817b3066ba9789bf2a566ccf84ab0a374210b8a215a9dcf493656a3fa0ecf07c4178920245fee0e46de7c3ec", + "0x8e6a0ae1273acda3aa50d07d293d580414110a63bc3fb6330bb2ee6f824aff0d8f42b7375a1a5ba85c05bfbe9da88cb5", + "0xa5dea98852bd6f51a84fa06e331ea73a08d9d220cda437f694ad9ad02cf10657882242e20bdf21acbbaa545047da4ce5", + "0xb13f410bf4cfce0827a5dfd1d6b5d8eabc60203b26f4c88238b8000f5b3aaf03242cdeadc2973b33109751da367069e1", + "0xa334315a9d61b692ad919b616df0aa75a9f73e4ea6fc27d216f48964e7daebd84b796418580cf97d4f08d4a4b51037cd", + "0x8901ba9e963fcd2f7e08179b6d19c7a3b8193b78ca0e5cf0175916de873ca0d000cd7ac678c0473be371e0ac132f35a2", + "0xb11a445433745f6cb14c9a65314bbf78b852f7b00786501b05d66092b871111cd7bee25f702d9e550d7dd91601620abb", + "0x8c2f7b8e7b906c71f2f154cc9f053e8394509c37c07b9d4f21b4495e80484fc5fc8ab4bdc525bd6cfa9518680ba0d1a2", + "0xb9733cebe92b43b899d3d1bfbf4b71d12f40d1853b2c98e36e635fdd8a0603ab03119890a67127e6bc79afae35b0bef2", + "0xa560f6692e88510d9ba940371e1ada344caf0c36440f492a3067ba38e9b7011caac37ba096a8a4accb1c8656d3c019b3", + "0xac18624339c1487b2626eef00d66b302bdb1526b6340d6847befe2fdfb2b410be5555f82939f8707f756db0e021ed398", + "0xafd9a3b8866a7fe4f7bc13470c0169b9705fcd3073685f5a6dcff3bdbbc2be50ac6d9908f9a10c5104b0bffc2bc14dad", + "0x97f15c92fe1f10949ed9def5dd238bc1429706e5037a0e0afb71c2d0e5845e2fed95a171c393e372077a7c7059f8c0e0", + "0x9453a1d4d09c309b70968ea527007d34df9c4cfd3048e5391aac5f9b64ca0c05dde5b8c949c481cfc83ef2e57b687595", + "0xb80e4b7c379ad435c91b20b3706253b763cbc980db78f782f955d2516af44c07bbfa5888cbf3a8439dc3907320feb25a", + "0x8939f458d28fefe45320b95d75b006e98330254056d063e4a2f20f04bcb25936024efe8d436d491ed34b482f9b9ae49c", + "0xa9ead2e833f71f7e574c766440c4b3c9c3363698c7ade14499a56003a272832ee6d99440887fa43ccdf80265b9d56b97", + "0xb6547a36934f05ce7b779e68049d61351cf229ae72dc211cc96a2a471b2724782f9355fdb415ea6f0ea1eb84fe00e785", + "0x828bfb3099b7b650b29b0f21279f829391f64520a6ab916d1056f647088f1e50fac9253ef7464eceab5380035c5a59c4", + "0x8d714b9ea650be4342ff06c0256189e85c5c125adf6c7aeca3dba9b21d5e01a28b688fc2116ce285a0714a8f1425c0b8", + "0x8a82eda041b2e72a3d73d70d85a568e035fbd6dc32559b6c6cfdf6f4edcb59a6ba85b6294a721aa0a71b07714e0b99ae", + "0xaf5665ebc83d027173b14ffb0e05af0a192b719177889fadc9ac8c082fda721e9a75d9ce3f5602dbfd516600ee3b6405", + "0xa68fdddf03d77bebdb676e40d93e59bd854408793df2935d0a5600601f7691b879981a398d02658c2da39dbbf61ef96c", + "0x8c001ebc84fcf0470b837a08a7b6125126b73a2762db47bbdc38c0e7992b1c66bac7a64faa1bf1020d1c63b40adc3082", + "0x8553889b49f9491109792db0a69347880a9cf2911b4f16f59f7f424e5e6b553687d51282e8f95be6a543635247e2e2c2", + "0xa2c269d6370b541daf1f23cc6b5d2b03a5fa0c7538d53ae500ef875952fe215e74a5010329ff41461f4c58b32ad97b3d", + "0xa5dae097285392b4eba83a9fd24baa03d42d0a157a37fae4b6efc3f45be86024b1182e4a6b6eadcf5efe37704c0a1ae5", + "0x89871a77d2032387d19369933cd50a26bda643e40cfd0ce73febe717a51b39fae981406fd41e50f4a837c02a99524ef9", + "0x8a76d495e90093ec2ac22f53759dc1cf36fbb8370fb586acbd3895c56a90bbf3796bcc4fc422ca4058adf337ead1402e", + "0xad4eb7576c4954d20623c1336c63662c2a6fb46ec6ef99b7f8e946aa47488dcb136eab60b35600f98c78c16c10c99013", + "0x894c2b120cec539feb1d281baaadde1e44beafedeeec29b804473fe024e25c1db652f151c956e88d9081fb39d27e0b19", + "0x9196bd5c100878792444c573d02b380a69e1b4b30cb59a48114852085058a5fd952df4afee3ecceb5c4ede21e1ed4a1a", + "0xa996fffc910764ea87a1eedc3a3d600e6e0ff70e6a999cb435c9b713a89600fc130d1850174efe9fc18244bb7c6c5936", + "0x8591bb8826befa8bee9663230d9a864a5068589f059e37b450e8c85e15ce9a1992f0ce1ead1d9829b452997727edcf9d", + "0x9465e20bb22c41bf1fa728be8e069e25cda3f7c243381ca9973cbedad0c7b07d3dd3e85719d77cf80b1058ce60e16d68", + "0x926b5ce39b6e60b94878ffeae9ff20178656c375fb9cfe160b82318ca500eb3e2e3144608b6c3f8d6c856b8fe1e2fbcf", + "0xa1ef29cbc83c45eb28ad468d0ce5d0fdd6b9d8191ba5ffa1a781c2b232ed23db6b7b04de06ef31763a6bfe377fa2f408", + "0x9328e63a3c8acf457c9f1f28b32d90d0eeadb0f650b5d43486a61d7374757a7ada5fc1def2a1e600fa255d8b3f48036f", + "0xa9c64880fcb7654f4dd08f4c90baac95712dd6dd407e17ea60606e9a97dc8e54dd25cb72a9bf3fc61f8d0ad569fe369d", + "0xa908eb7b940c1963f73046d6b35d40e09013bfbfbeb2ccd64df441867e202b0f3b625fa32dd04987c3d7851360abdffc", + "0xb3947b5ed6d59e59e4472cdb1c3261de1b5278fb7cb9b5fca553f328b3b3e094596861ea526eca02395f7b7358155b7b", + "0x99da7f190d37bc58945f981cf484d40fcf0855cf8178e2ce8d057c7f0a9d9f77425fdbce9ef8366f44f671b20fd27d0b", + "0x913976d77d80e3657977df39571577fdf0be68ba846883705b454f8493578baa741cfaede53783e2c97cc08964395d83", + "0x8d754a61e5164a80b5090c13f3e936056812d4ae8dc5cc649e6c7f37464777249bc4ae760a9806939131f39d92cca5bf", + "0x82ffd098480828a90cb221a8c28584e15904bad477c13b2e2d6ef0b96a861ce4a309a328fe44342365349456ad7c654f", + "0x89ae3ce4b0357044579ca17be85d8361bb1ce3941f87e82077dd67e43ec0f95edd4bd3426225c90994a81a99e79490b7", + "0xa170892074016d57c9d8e5a529379d7e08d2c1158b9ac4487ac9b95266c4fd51cb18ae768a2f74840137eec05000dd5a", + "0xaafd8acd1071103c7af8828a7a08076324d41ea530df90f7d98fafb19735fc27ead91b50c2ca45851545b41d589d0f77", + "0x8623c849e61d8f1696dc9752116a26c8503fd36e2cbbc9650feffdd3a083d8cdbb3b2a4e9743a84b9b2ad91ac33083f2", + "0xac7166ddd253bb22cdbd8f15b0933c001d1e8bc295e7c38dc1d2be30220e88e2155ecd2274e79848087c05e137e64d01", + "0xa5276b216d3df3273bbfa46210b63b84cfe1e599e9e5d87c4e2e9d58666ecf1af66cb7ae65caebbe74b6806677215bd0", + "0x88792f4aa3597bb0aebadb70f52ee8e9db0f7a9d74f398908024ddda4431221a7783e060e0a93bf1f6338af3d9b18f68", + "0x8f5fafff3ecb3aad94787d1b358ab7d232ded49b15b3636b585aa54212f97dc1d6d567c180682cca895d9876cacb7833", + "0xab7cb1337290842b33e936162c781aa1093565e1a5b618d1c4d87dd866daea5cebbcc486aaa93d8b8542a27d2f8694c7", + "0x88480a6827699da98642152ebc89941d54b4791fbc66110b7632fb57a5b7d7e79943c19a4b579177c6cf901769563f2f", + "0xa725ee6d201b3a610ede3459660658ee391803f770acc639cfc402d1667721089fb24e7598f00e49e81e50d9fd8c2423", + "0x98924372da8aca0f67c8c5cad30fa5324519b014fae7849001dcd51b6286118f12b6c49061219c37714e11142b4d46de", + "0xa62c27360221b1a7c99697010dfe1fb31ceb17d3291cf2172624ebeff090cbaa3c3b01ec89fe106dace61d934711d42d", + "0x825173c3080be62cfdc50256c3f06fe190bc5f190d0eb827d0af5b99d80936e284a4155b46c0d462ee574fe31d60983d", + "0xa28980b97023f9595fadf404ed4aa36898d404fe611c32fd66b70252f01618896f5f3fda71aea5595591176aabf0c619", + "0xa50f5f9def2114f6424ff298f3b128068438f40860c2b44e9a6666f43c438f1780be73cf3de884846f1ba67f9bef0802", + "0xb1eee2d730da715543aeb87f104aff6122cb2bf11de15d2519ff082671330a746445777924521ec98568635f26988d0c", + "0x862f6994a1ff4adfd9fb021925cccf542fca4d4b0b80fb794f97e1eb2964ef355608a98eec6e07aadd4b45ee625b2a21", + "0x8ce69a18df2f9b9f6e94a456a7d94842c61dea9b00892da7cf5c08144de9be39b8c304aeca8b2e4222f87ba367e61006", + "0xb5f325b1cecd435f5346b6bc562d92f264f1a6d91be41d612df012684fdd69e86063db077bc11ea4e22c5f2a13ae7bee", + "0x85526870a911127835446cb83db8986b12d5637d59e0f139ad6501ac949a397a6c73bd2e7fba731b1bb357efe068242c", + "0x8552247d3f7778697f77389717def5a149fc20f677914048e1ed41553b039b5427badc930491c0bae663e67668038fd1", + "0xa545640ee5e51f3fe5de7050e914cfe216202056cd9d642c90e89a166566f909ee575353cb43a331fde17f1c9021414e", + "0x8b51229b53cff887d4cab573ba32ec52668d197c084414a9ee5589b285481cea0c3604a50ec133105f661321c3ca50f5", + "0x8cdc0b960522bed284d5c88b1532142863d97bbb7dc344a846dc120397570f7bd507ceb15ed97964d6a80eccfef0f28e", + "0xa40683961b0812d9d53906e795e6470addc1f30d09affebf5d4fbbd21ddfa88ce441ca5ea99c33fd121405be3f7a3757", + "0xa527875eb2b99b4185998b5d4cf97dd0d4a937724b6ad170411fc8e2ec80f6cee2050f0dd2e6fee9a2b77252d98b9e64", + "0x84f3a75f477c4bc4574f16ebc21aaa32924c41ced435703c4bf07c9119dd2b6e066e0c276ff902069887793378f779e0", + "0xa3544bc22d1d0cab2d22d44ced8f7484bfe391b36991b87010394bfd5012f75d580596ffd4f42b00886749457bb6334b", + "0xb81f6eb26934b920285acc20ceef0220dd23081ba1b26e22b365d3165ce2fbae733bbc896bd0932f63dcc84f56428c68", + "0x95e94d40a4f41090185a77bf760915a90b6a3e3ace5e53f0cb08386d438d3aa3479f0cd81081b47a9b718698817265cd", + "0xb69bd1625b3d6c17fd1f87ac6e86efa0d0d8abb69f8355a08739109831baeec03fd3cd4c765b5ff8b1e449d33d050504", + "0x8448f4e4c043519d98552c2573b76eebf2483b82d32abb3e2bfc64a538e79e4f59c6ca92adff1e78b2f9d0a91f19e619", + "0x8f11c42d6a221d1fda50887fb68b15acdb46979ab21d909ed529bcad6ae10a66228ff521a54a42aca0dad6547a528233", + "0xa3adb18d7e4a882b13a067784cf80ea96a1d90f5edc61227d1f6e4da560c627688bdf6555d33fe54cab1bca242986871", + "0xa24d333d807a48dc851932ed21cbdd7e255bad2699909234f1706ba55dea4bb6b6f8812ffc0be206755868ba8a4af3f9", + "0xa322de66c22a606e189f7734dbb7fda5d75766d5e69ec04b4e1671d4477f5bcb9ff139ccc18879980ebc3b64ab4a2c49", + "0x88f54b6b410a1edbf125db738d46ee1a507e69bc5a8f2f443eb787b9aa7dbd6e55014ec1e946aabeb3e27a788914fb04", + "0xb32ee6da1dcd8d0a7fd7c1821bb1f1fe919c8922b4c1eeed56e5b068a5a6e68457c42b192cbaef5dc6d49b17fa45bc0f", + "0x8a44402da0b3a15c97b0f15db63e460506cb8bef56c457166aea5e8881087d8202724c539ef0feb97131919a73aefca8", + "0xb967e3fead6171fa1d19fd976535d428b501baff59e118050f9901a54b12cc8e4606348454c8f0fc25bd6644e0a5532e", + "0xb7a0c9e9371c3efbbb2c6783ce2cc5f149135175f25b6d79b09c808bce74139020e77f0c616fa6dcb3d87a378532529d", + "0xa54207782ffc909cd1bb685a3aafabbc4407cda362d7b3c1b14608b6427e1696817aeb4f3f85304ac36e86d3d8caa65b", + "0x98c1da056813a7bfebc81d8db7206e3ef9b51f147d9948c088976755826cc5123c239ca5e3fe59bed18b5d0a982f3c3f", + "0xae1c86174dfafa9c9546b17b8201719aecd359f5bbeb1900475041f2d5b8a9600d54d0000c43dd061cfda390585726ff", + "0xa8ee5a8be0bd1372a35675c87bfd64221c6696dc16e2d5e0996e481fec5cdbcb222df466c24740331d60f0521285f7d3", + "0x8ddadbe3cf13af50d556ce8fc0dd77971ac83fad9985c3d089b1b02d1e3afc330628635a31707b32595626798ea22d45", + "0xa5c80254baf8a1628dc77c2445ebe21fbda0de09dd458f603e6a9851071b2b7438fe74214df293dfa242c715d4375c95", + "0xb9d83227ed2600a55cb74a7052003a317a85ca4bea50aa3e0570f4982b6fe678e464cc5156be1bd5e7bba722f95e92c5", + "0xb56085f9f3a72bea9aa3a8dc143a96dd78513fa327b4b9ba26d475c088116cab13843c2bff80996bf3b43d3e2bddb1d6", + "0x8fa9b39558c69a9757f1e7bc3f07295e4a433da3e6dd8c0282397d26f64c1ecd8eb3ba9824a7cacfb87496ebbb45d962", + "0x879c6d0cb675812ed9dee68c3479a499f088068501e2677caeae035e6f538da91a49e245f5fcce135066169649872bee", + "0x91aa9fd3fed0c2a23d1edda8a6542188aeb8abee8772818769bdee4b512d431e4625a343af5d59767c468779222cf234", + "0xa6be0bb2348c35c4143482c7ef6da9a93a5356f8545e8e9d791d6c08ed55f14d790d21ee61d3a56a2ae7f888a8fd46ca", + "0x808ee396a94e1b8755f2b13a6ffbedef9e0369e6c2e53627c9f60130c137299d0e4924d8ef367e0a7fad7f68a8c9193c", + "0xad1086028fcdac94d5f1e7629071e7e47e30ad0190ae59aaebfb7a7ef6202ab91323a503c527e3226a23d7937af41a52", + "0x9102bdaf79b907d1b25b2ec6b497e2d301c8eac305e848c6276b392f0ad734131a39cc02ed42989a53ca8da3d6839172", + "0x8c976c48a45b6bc7cd7a7acea3c2d7c5f43042863b0661d5cd8763e8b50730552187a8eecf6b3d17be89110208808e77", + "0xa2624c7e917e8297faa3af89b701953006bf02b7c95dfba00c9f3de77748bc0b13d6e15bb8d01377f4d98fb189538142", + "0xa405f1e66783cdcfe20081bce34623ec3660950222d50b7255f8b3cc5d4369aeb366e265e5224c0204911539f0fa165e", + "0x8d69bdcaa5d883b5636ac8f8842026fcc58c5e2b71b7349844a3f5d6fbecf44443ef4f768eac376f57fb763606e92c9f", + "0x82fce0643017d16ec1c3543db95fb57bfa4855cc325f186d109539fcacf8ea15539be7c4855594d4f6dc628f5ad8a7b0", + "0x8860e6ff58b3e8f9ae294ff2487f0d3ffae4cf54fd3e69931662dabc8efd5b237b26b3def3bcd4042869d5087d22afcf", + "0x88c80c442251e11c558771f0484f56dc0ed1b7340757893a49acbf96006aa73dfc3668208abea6f65375611278afb02a", + "0x8be3d18c6b4aa8e56fcd74a2aacb76f80b518a360814f71edb9ccf3d144bfd247c03f77500f728a62fca7a2e45e504c5", + "0x8b8ebf0df95c3f9b1c9b80469dc0d323784fd4a53f5c5357bb3f250a135f4619498af5700fe54ad08744576588b3dfff", + "0xa8d88abdaadd9c2a66bc8db3072032f63ed8f928d64fdb5f810a65074efc7e830d56e0e738175579f6660738b92d0c65", + "0xa0a10b5d1a525eb846b36357983c6b816b8c387d3890af62efb20f50b1cb6dd69549bbef14dab939f1213118a1ae8ec2", + "0x8aadf9b895aeb8fdc9987daa937e25d6964cbd5ec5d176f5cdf2f0c73f6f145f0f9759e7560ab740bf623a3279736c37", + "0x99aeda8a495031cc5bdf9b842a4d7647c55004576a0edc0bd9b985d60182608361ed5459a9d4b21aa8e2bd353d10a086", + "0x832c8b3bfcd6e68eee4b100d58014522de9d4cefa99498bc06c6dca83741e4572e20778e0d846884b33439f160932bca", + "0x841f56ebefc0823ab484fc445d62f914e13957e47904419e42771aa605e33ab16c44f781f6f9aa42e3a1baf377f54b42", + "0xa6e40271d419e295a182725d3a9b541ffd343f23e37549c51ecaa20d13cf0c8d282d6d15b24def5702bfee8ba10b12ac", + "0x8ac00925ac6187a4c5cde48ea2a4eaf99a607e58b2c617ee6f01df30d03fafada2f0469178dd960d9d64cbd33a0087d8", + "0xb6b80916b540f8a0fe4f23b1a06e2b830008ad138271d5ba3cd16d6619e521fe2a7623c16c41cba48950793386eea942", + "0x8412c0857b96a650e73af9d93087d4109dd092ddf82188e514f18fcac644f44d4d62550bfa63947f2d574a2e9d995bbb", + "0xb871395baa28b857e992a28ac7f6d95ec461934b120a688a387e78498eb26a15913b0228488c3e2360391c6b7260b504", + "0x926e2d25c58c679be77d0e27ec3b580645956ba6f13adcbc2ea548ee1b7925c61fcf74c582337a3b999e5427b3f752f2", + "0xa165fa43fecae9b913d5dcfc232568e3e7b8b320ce96b13800035d52844c38fd5dbf7c4d564241d860c023049de4bcbc", + "0xb4976d7572fd9cc0ee3f24888634433f725230a7a2159405946a79315bc19e2fc371448c1c9d52bf91539fd1fe39574b", + "0xa6b461eb72e07a9e859b9e16dfa5907f4ac92a5a7ca4368b518e4a508dc43f9b4be59db6849739f3ef4c44967b63b103", + "0xb976606d3089345d0bc501a43525d9dca59cf0b25b50dfc8a61c5bd30fac2467331f0638fab2dc68838aa6ee8d2b6bc9", + "0xb16ea61c855da96e180abf7647fa4d9dd6fd90adebadb4c5ed4d7cd24737e500212628fca69615d89cb40e9826e5a214", + "0x95a3e3162eb5ea27a613f8c188f2e0dcc5cbd5b68c239858b989b004d87113e6aa3209fa9fad0ee6ecef42814ba9db1a", + "0xb6a026ab56d3224220e5bce8275d023c8d39d1bdf7eec3b0923429b7d5ef18cf613a3591d364be8727bb1fa0ba11eabb", + "0x949f117e2e141e25972ee9ccdd0b7a21150de7bbf92bbd89624a0c5f5a88da7b2b172ba2e9e94e1768081f260c2a2f8d", + "0xb7c5e9e6630287d2a20a2dfb783ffe6a6ff104ff627c6e4e4342acc2f3eb6e60e9c22f465f8a8dc58c42f49840eca435", + "0x872be5a75c3b85de21447bb06ac9eb610f3a80759f516a2f99304930ddf921f34cbffc7727989cdd7181d5fc62483954", + "0xa50976ea5297d797d220932856afdd214d1248230c9dcd840469ecc28ea9f305b6d7b38339fedb0c00b5251d77af8c95", + "0x80b360f8b44914ff6f0ffbd8b5360e3cabe08639f6fe06d0c1526b1fe9fe9f18c497f1752580b30e950abd3e538ad416", + "0xa2f98f9bf7fac78c9da6bb41de267742a9d31cf5a04b2fb74f551084ec329b376f651a59e1ae919b2928286fb566e495", + "0x8b9d218a8a6c150631548e7f24bbd43f132431ae275c2b72676abbea752f554789c5ff4aac5c0eeee5529af7f2b509ef", + "0xaa21a243b07e9c7b169598bf0b102c3c280861780f83121b2ef543b780d47aaa4b1850430ee7927f33ece9847c4e0e1a", + "0x8a6f90f4ce58c8aa5d3656fe4e05acccf07a6ec188a5f3cde7bf59a8ae468e66f055ac6dfc50b6e8e98f2490d8deedc5", + "0x8e39f77ca4b5149ffe9945ceac35d068760ba338d469d57c14f626dd8c96dbe993dd7011beff727c32117298c95ee854", + "0x83bd641c76504222880183edd42267e0582642c4993fe2c7a20ce7168e4c3cbf7586e1d2d4b08c84d9b0bf2f6b8800b8", + "0xa9d332993cf0c1c55130e5cf3a478eb5e0bfb49c25c07538accc692ef03d82b458750a7b991cc0b41b813d361a5d31e3", + "0xa0fc60e6a6015df9bee04cea8f20f01d02b14b6f7aa03123ab8d65da071b2d0df5012c2a69e7290baae6ed6dd29ebe07", + "0xa2949dde2e48788ceaac7ec7243f287ffe7c3e788cdba97a4ab0772202aeef2d50382bed8bf7eff5478243f7eabe0bda", + "0xa7879373ea18572dba6cf29868ca955ffa55b8af627f29862f6487ee398b81fe3771d8721ca8e06716c5d91b9ac587cb", + "0xb3c7081e2c5306303524fbe9fe5645111a57dffd4ec25b7384da12e56376a0150ab52f9d9cc6ca7bdd950695e39b766d", + "0xa634a6a19d52dcb9f823352b36c345d2de54b75197bcd90528d27830bd6606d1a9971170de0849ed5010afa9f031d5be", + "0x88f2062f405fa181cfdb8475eaf52906587382c666ca09a9522537cfebbc7de8337be12a7fd0db6d6f2f7ab5aefab892", + "0xb1f0058c1f273191247b98783b2a6f5aa716cf799a8370627fc3456683f03a624d0523b63a154fe9243c0dfd5b37c460", + "0xae39a227cc05852437d87be6a446782c3d7fbe6282e25cf57b6b6e12b189bdc0d4a6e2c3a60b3979256b6b5baf8f1c5f", + "0x802a1af228ab0c053b940e695e7ef3338f5be7acf4e5ed01ac8498e55b492d3a9f07996b1700a84e22f0b589638909cd", + "0xa36490832f20e4b2f9e79ee358b66d413f034d6a387534b264cdeac2bca96e8b5bcbdd28d1e98c44498032a8e63d94d2", + "0x8728c9a87db2d006855cb304bba54c3c704bf8f1228ae53a8da66ca93b2dac7e980a2a74f402f22b9bc40cd726e9c438", + "0xa08f08ab0c0a1340e53b3592635e256d0025c4700559939aeb9010ed63f7047c8021b4210088f3605f5c14fb51d1c613", + "0x9670fd7e2d90f241e8e05f9f0b475aa260a5fb99aa1c9e61cd023cbad8ed1270ae912f168e1170e62a0f6d319cf45f49", + "0xa35e60f2dd04f098bf274d2999c3447730fe3e54a8aff703bc5a3c274d22f97db4104d61a37417d93d52276b27ef8f31", + "0x859df7a21bc35daec5695201bd69333dc4f0f9e4328f2b75a223e6615b22b29d63b44d338413ca97eb74f15563628cb7", + "0xb2b44ad3e93bc076548acdf2477803203108b89ecc1d0a19c3fb9814d6b342afc420c20f75e9c2188ad75fdb0d34bb2d", + "0x941173ee2c87765d10758746d103b667b1227301e1bcfecef2f38f9ab612496a9abd3050cef5537bf28cfecd2aacc449", + "0x92b0bea30ebed20ac30648efb37bac2b865daaa514316e6f5470e1de6cb84651ff77c127aa7beed4521bda5e8fc81122", + "0xaf17bf813bb238cf8bb437433f816786612209180a6c0a1d5141292dc2d2c37164ef13bfc50c718bfcc6ce26369298a2", + "0x8461fd951bdfda099318e05cc6f75698784b033f15a71bce26165f0ce421fd632d50df9eeced474838c0050b596e672c", + "0x83281aa18ae4b01e8201e1f64248cc6444c92ee846ae72adb178cef356531558597d84ff93a05abf76bfe313eb7dbe86", + "0xb62b150f73999c341daa4d2f7328d2f6ca1ef3b549e01df58182e42927537fc7971c360fe8264af724f4c0247850ef12", + "0xa7022a201f79c012f982b574c714d813064838a04f56964d1186691413757befeeaada063e7884297606e0eea1b1ed43", + "0xa42ac9e8be88e143853fd8e6a9ff21a0461801f0ac76b69cca669597f9af17ecb62cccdcdcbe7f19b62ab93d7f838406", + "0x80f1ca73b6ba3a2fbae6b79b39c0be8c39df81862d46c4990c87cbf45b87996db7859d833abc20af2fcb4faf059c436a", + "0xb355943e04132d5521d7bbe49aea26f6aa1c32f5d0853e77cc2400595325e923a82e0ff7601d1aee79f45fd8a254f6ae", + "0x87142c891d93e539b31d0b5ead9ea600b9c84db9be9369ff150a8312fe3d10513f4c5b4d483a82b42bc65c45dd9dd3bd", + "0x823c3d7f6dda98a9d8c42b3fee28d3154a95451402accadb6cf75fc45d2653c46a569be75a433094fa9e09c0d5cf1c90", + "0xb3c3497fe7356525c1336435976e79ec59c5624c2fb6185ee09ca0510d58b1e392965e25df8a74d90d464c4e8bb1422b", + "0x88c48d83e8ddc0d7eea051f3d0e21bc0d3a0bb2b6a39ece76750c1c90c382a538c9a35dc9478b8ceb8157dcccbbf187a", + "0x93da81a8939f5f58b668fefdc6f5f7eca6dc1133054de4910b651f8b4a3267af1e44d5a1c9e5964dc7ab741eb146894b", + "0x8b396e64985451ac337f16be61105106e262e381ea04660add0b032409b986e1ac64da3bc2feae788e24e9cb431d8668", + "0x9472068b6e331ea67e9b5fbf8057672da93c209d7ded51e2914dbb98dccd8c72b7079b51fd97a7190f8fc8712c431538", + "0xac47e1446cb92b0a7406f45c708567f520900dfa0070d5e91783139d1bfc946d6e242e2c7b3bf4020500b9f867139709", + "0x896053706869fb26bb6f7933b3d9c7dd6db5c6bd1269c7a0e222b73039e2327d44bda7d7ae82bf5988808b9831d78bcd", + "0xa55e397fa7a02321a9fe686654c86083ecedb5757586d7c0250ec813ca6d37151a12061d5feca4691a0fd59d2f0fdd81", + "0xae23f08ac2b370d845036518f1bddb7fea8dc59371c288a6af310486effeb61963f2eef031ca90f9bdbcf0e475b67068", + "0xb5462921597a79f66c0fec8d4c7cfd89f427692a7ce30d787e6fd6acd2377f238ec74689a0fdbe8ef3c9c9bd24b908dc", + "0xae67e8ea7c46e29e6aae6005131c29472768326819aa294aaf5a280d877de377b44959adb1348fa3e929dcbc3ae1f2c0", + "0x84962b4c66500a20c4424191bdfb619a46cda35bdb34c2d61edcb0b0494f7f61dd5bf8f743302842026b7b7d49edd4b5", + "0x846f76286dc3cc59cb15e5dabb72a54a27c78190631df832d3649b2952fa0408ecde7d4dfdae7046c728efa29879fb51", + "0x8f76c854eaee8b699547e07ad286f7dadfa6974c1328d12502bd7630ae619f6129272fdd15e2137ffef0143c42730977", + "0x8007b163d4ea4ec6d79e7a2aa19d06f388da0b3a56f3ee121441584e22a246c0e792431655632bf6e5e02cb86914eebf", + "0xac4d2cecc1f33e6fb73892980b61e62095ddff5fd6167f53ca93d507328b3c05440729a277dc3649302045b734398af1", + "0x92d2a88f2e9c9875abaff0d42624ccb6d65401de7127b5d42c25e6adccd7a664504c5861618f9031ced8aeb08b779f06", + "0xa832c1821c1b220eb003fc532af02c81196e98df058cdcc9c9748832558362915ea77526937f30a2f74f25073cb89afb", + "0xb6f947ab4cc2baec100ed8ec7739a2fd2f9504c982b39ab84a4516015ca56aea8eef5545cfc057dd44c69b42125fb718", + "0xb24afacf2e90da067e5c050d2a63878ee17aaf8fd446536f2462da4f162de87b7544e92c410d35bf2172465940c19349", + "0xb7a0aa92deac71eaab07be8fa43086e071e5580f5dbf9b624427bdd7764605d27303ae86e5165bed30229c0c11958c38", + "0xb0d1d5bfa1823392c5cf6ed927c1b9e84a09a24b284c2cd8fcb5fda8e392c7c59412d8f74eb7c48c6851dff23ae66f58", + "0xa24125ef03a92d2279fb384186ca0274373509cfec90b34a575490486098438932ee1be0334262d22d5f7d3db91efe67", + "0x83e08e5fba9e8e11c164373794f4067b9b472d54f57f4dbe3c241cf7b5b7374102de9d458018a8c51ab3aed1dddf146f", + "0x9453101b77bb915ed40990e1e1d2c08ea8ec5deb5b571b0c50d45d1c55c2e2512ec0ceca616ff0376a65678a961d344d", + "0x92a0516e9eb6ad233d6b165a8d64a062ce189b25f95d1b3264d6b58da9c8d17da2cd1f534800c43efcf2be73556cd2ff", + "0x958d0b5d7d8faf25d2816aa6a2c5770592ad448db778dd9b374085baa66c755b129822632eaabcb65ee35f0bf4b73634", + "0x90a749de8728b301ad2a6b044e8c5fd646ccd8d20220e125cba97667e0bb1d0a62f6e3143b28f3d93f69cdc6aa04122a", + "0x84bd34c8d8f74dec07595812058db24d62133c11afed5eb2a8320d3bfc28e442c7f0cfd51011b7b0bb3e5409cb7b6290", + "0xaecc250b556115d97b553ad7b2153f1d69e543e087890000eaa60f4368b736921d0342ce5563124f129096f5d5e2ca9d", + "0x977f17ac82ed1fbf422f9b95feb3047a182a27b00960296d804fd74d54bb39ad2c055e665c1240d2ad2e06a3d7501b00", + "0xaf5be9846bd4879ebe0af5e7ad253a632f05aedfe306d31fe6debe701ba5aa4e33b65efc05043bc73aadb199f94baed4", + "0x9199e12ec5f2aaaeed6db5561d2dcc1a8fe9c0854f1a069cba090d2dff5e5ba52b10c841ccbd49006a91d881f206150d", + "0x8f4a96a96ed8ceaf3beba026c89848c9ca4e6452ce23b7cf34d12f9cc532984a498e051de77745bdc17c7c44c31b7c30", + "0xaf3f2a3dbe8652c4bfca0d37fb723f0e66aab4f91b91a625114af1377ad923da8d36da83f75deb7a3219cd63135a3118", + "0xa6d46963195df8962f7aa791d104c709c38caa438ddd192f7647a884282e81f748c94cdf0bb25d38a7b0dc1b1d7bbcf7", + "0x86f3de4b22c42d3e4b24b16e6e8033e60120af341781ab70ae390cb7b5c5216f6e7945313c2e04261a51814a8cb5db92", + "0xb9f86792e3922896cfd847d8ff123ff8d69ecf34968fb3de3f54532f6cd1112b5d34eeabdca46ae64ad9f6e7e5b55edc", + "0x83edfbcbc4968381d1e91ab813b3c74ab940eaf6358c226f79182f8b21148ec130685fd91b0ea65916b0a50bccf524ea", + "0x93b61daca7a8880b7926398760f50016f2558b0bab74c21181280a1baf3414fc539911bb0b79c4288d29d3c4ad0f4417", + "0xad541aeb83a47526d38f2e47a5ce7e23a9adabe5efeae03541026881e6d5ef07da3ac1a6ed466ca924fa8e7a91fcff88", + "0xac4bba31723875025640ed6426003ed8529215a44c9ffd44f37e928feef9fc4dfa889088131c9be3da87e8f3fdf55975", + "0x88fa4d49096586bc9d29592909c38ea3def24629feacd378cc5335b70d13814d6dac415f8c699ee1bf4fe8b85eb89b38", + "0xb67d0b76cbd0d79b71f4673b96e77b6cda516b8faa1510cfe58ff38cc19000bb5d73ff8418b3dab8c1c7960cb9c81e36", + "0x98b4f8766810f0cfecf67bd59f8c58989eb66c07d3dfeee4f4bbce8fd1fce7cc4f69468372eaec7d690748543bd9691d", + "0x8445891af3c298b588dec443beacdf41536adb84c812c413a2b843fd398e484eb379075c64066b460839b5fe8f80177c", + "0xb603635c3ed6fdc013e2a091fc5164e09acf5f6a00347d87c6ebadb1f44e52ff1a5f0466b91f3f7ffc47d25753e44b75", + "0x87ec2fc928174599a9dafe7538fec7dcf72e6873b17d953ed50708afff0da37653758b52b7cafa0bf50dfcf1eafbb46c", + "0xb9dbd0e704d047a457d60efe6822dc679e79846e4cbcb11fa6c02079d65673ee19bbf0d14e8b7b200b9205f4738df7c7", + "0x9591ec7080f3f5ba11197a41f476f9ba17880f414d74f821a072ec5061eab040a2acba3d9856ff8555dfe5eaeb14ca19", + "0xb34c9d1805b5f1ce38a42b800dec4e7f3eb8c38e7d2b0a525378e048426fed150dbfe9cc61f5db82b406d1b9ff2d10bf", + "0xa36fdc649dc08f059dfa361e3969d96b4cc4a1ebf10b0cd01a7dd708430979e8d870961fef85878f8779b8e23caafb18", + "0x88dfc739a80c16c95d9d6f73c3357a92d82fa8c3c670c72bee0f1e4bac9ec338e1751eb786eda3e10f747dd7a686900f", + "0x84a535ad04f0961756c61c70001903a9adf13126983c11709430a18133c4b4040d17a33765b4a06968f5d536f4bfb5c5", + "0x8c86d695052a2d2571c5ace744f2239840ef21bb88e742f050c7fa737cd925418ecef0971333eb89daa6b3ddfede268c", + "0x8e9a700157069dc91e08ddcbdde3a9ad570272ad225844238f1015004239c542fceb0acce6d116c292a55f0d55b6175e", + "0x84d659e7f94e4c1d15526f47bc5877a4ef761c2a5f76ec8b09c3a9a30992d41b0e2e38ed0c0106a6b6c86d670c4235f3", + "0xa99253d45d7863db1d27c0ab561fb85da8c025ba578b4b165528d0f20c511a9ca9aff722f4ff7004843f618eb8fced95", + "0x89a3cacb15b84b20e95cd6135550146bbe6c47632cc6d6e14d825a0c79b1e02b66f05d57d1260cb947dc4ae5b0283882", + "0x8385b1555e794801226c44bd5e878cbe68aeac0a19315625a8e5ea0c3526b58cdd4f53f9a14a167a5e8a293b530d615a", + "0xb68c729e9df66c5cd22af4909fb3b0057b6a231c4a31cd6bf0fa0e53c5809419d15feb483de6e9408b052458e819b097", + "0x924f56eda269ec7ec2fc20c5731bf7f521546ddf573ccbe145592f1c9fee5134747eb648d9335119a8066ca50a1f7e50", + "0xb2100a26b9c3bec7ec5a53f0febbf56303f199be2f26b2d564cfee2adc65483b84192354f2865c2f4c035fa16252ae55", + "0x8f64dbed62e638563967ec1605a83216aed17eb99aa618c0543d74771ea8f60bbb850c88608d4f8584f922e30a8a0a72", + "0xb31b9e1ffe8d7260479c9413f8e680f3fe391ae8fcf44fcca3000d9b2473a40c1d32299f8f63865a57579a2d6c7e9f08", + "0xa5b1d136142eb23e322c6c07cb838a3f58ab6925472352ebd0bb47041a0d8729e1074ca223922f3a7a672ced7a1e562d", + "0x8d9470a5a15d833a447b5f108333d50f30aa7659e331c3f8080b1e928a99922edc650466a2f54f3d48afdb34bff42142", + "0x866368f5891564e5b2de37ad21ff0345c01129a14ea5667f9b64aad12d13ec034622872e414743af0bf20adb2041b497", + "0x88ef9c2ebf25fd0c04b7cfa35fbac2e4156d2f1043fa9f98998b2aa402c8f9a4f1039e782451a46840f3e0e4b3fa47d3", + "0x94ba04a4859273697e264a2d238dc5c9ff573ebc91e4796ea58eebe4080c1bf991255ab2ad8fb1e0301ce7b79cc6e69b", + "0x86b6bd0953309a086e526211bf1a99327269304aa74d8cdc994cee63c3a2d4b883e832b0635888dff2a13f1b02eb8df4", + "0x843ea6ea5f2c7a1fd50be56a5765dcce3ea61c99b77c1a729ee0cd8ec706385ac7062e603479d4c8d3527f030762d049", + "0x8d3675195a3b06f2d935d45becc59f9fa8fa440c8df80c029775e47fe9c90e20f7c8e4cc9a2542dd6bfe87536c428f0d", + "0x8978580b0c9b0aa3ab2d47e3cfd92fa891d3ddee57829ee4f9780e8e651900457d8e759d1a9b3e8f6ae366e4b57f2865", + "0x890112ec81d0f24b0dfbb4d228e418eff02ae63dc691caf59c1d103e1d194e6e2550e1bec41c0bfdb74fed454f621d0c", + "0x97da00bd4b19d1e88caff7f95b8b9a7d29bc0afe85d0c6a163b4b9ef336f0e90e2c49ce6777024bb08df908cc04ea1ca", + "0xb458268d275a5211106ccaa8333ce796ef2939b1c4517e502b6462e1f904b41184a89c3954e7c4f933d68b87427a7bfd", + "0xaac9c043ba8ba9283e8428044e6459f982413380ee7005a996dc3cc468f6a21001ecaa3b845ce2e73644c2e721940033", + "0x82145013c2155a1200246a1e8720adf8a1d1436b10d0854369d5b1b6208353e484dd16ce59280c6be84a223f2d45e5e2", + "0xb301bafa041f9b203a46beab5f16160d463aa92117c77a3dc6a9261a35645991b9bafcc186c8891ca95021bd35f7f971", + "0xa531b8d2ac3de09b92080a8d8857efa48fb6a048595279110e5104fee7db1dd7f3cfb8a9c45c0ed981cbad101082e335", + "0xa22ac1d627d08a32a8abd41504b5222047c87d558ffae4232cefdeb6a3dc2a8671a4d8ddfba2ff9068a9a3ffb0fe99b1", + "0xb8d9f0e383c35afb6d69be7ff04f31e25c74dd5751f0e51290c18814fbb49ee1486649e64355c80e93a3d9278bd21229", + "0x8165babccd13033a3614c878be749dfa1087ecbeee8e95abcfffe3aa06695711122cb94477a4d55cffd2febf0c1173de", + "0xa4c1bc84ecb9d995d1d21c2804adf25621676d60334bd359dac3a2ec5dc8de567aa2831c10147034025fb3e3afb33c4b", + "0xb77307cab8e7cb21e4038493058fb6db9e2ec91dda9d7f96f25acbc90309daf7b6d8a205682143ee35d675e9800c3b08", + "0xaaf7466083cd1f325ba860efe3faf4cebe6a5eecf52c3e8375d72043a5cfc8e6cb4b40f8e48f97266e84f0d488e8badf", + "0x9264a05a3abc2a5b4958f957f3a486a5eb3ddd10ff57aa6943c9430d0cfa01d63b72695b1ade50ac1b302d312175e702", + "0xb3f9e4c589ad28b1eceed99dc9980fac832524cfcbe4a486dfeedb4b97c080e24bdb3967e9ca63d2240e77f9addfaefd", + "0xb2c1e253a78e7179e5d67204422e0debfa09c231970b1bfb70f31a8d77c7f5059a095ca79d2e9830f12c4a8f88881516", + "0x81865a8a25913d1072cb5fd9505c73e0fde45e4c781ddd20fb0a7560d8b1cd5e1f63881c6efc05360e9204dfa6c3ce16", + "0xab71c2ea7fa7853469a2236dedb344a19a6130dc96d5fd6d87d42d3fffda172557d203b7688ce0f86acd913ce362e6cd", + "0x8aa2051bc3926c7bd63565f3782e6f77da824cb3b22bb056aa1c5bccfa274c0d9e49a91df62d0e88876e2bd7776e44b9", + "0xb94e7074167745323d1d353efe7cfb71f40a390e0232354d5dfd041ef523ac8f118fb6dcc42bf16c796e3f61258f36f8", + "0x8210fcf01267300cb1ccf650679cf6e1ee46df24ae4be5364c5ff715332746c113d680c9a8be3f17cacaeb3a7ba226ce", + "0x905ac223568eedc5acd8b54e892be05a21abbb4083c5dbec919129f9d9ffa2c4661d78d43bf5656d8d7aafa06f89d647", + "0xa6e93da7e0c998e6ce2592d1aa87d12bf44e71bec12b825139d56682cdce8f0ba6dbfe9441a9989e10578479351a3d9d", + "0xacde928a5e2df0d65de595288f2b81838155d5673013100a49b0cb0eb3d633237af1378148539e33ccd1b9a897f0fec3", + "0xa6e1a47e77f0114be6ae7acd2a51e6a9e38415cce7726373988153cdd5d4f86ef58f3309adc5681af4a159300ed4e5b5", + "0xad2b6a0d72f454054cb0c2ebc42cd59ff2da7990526bd4c9886003ba63b1302a8343628b8fe3295d3a15aa85150e0969", + "0xb0bc3aea89428d7918c2ee0cc57f159fba134dad224d0e72d21a359ca75b08fbb4373542f57a6408352033e1769f72c6", + "0xaad0497525163b572f135fad23fdd8763631f11deeaf61dea5c423f784fe1449c866040f303555920dc25e39cdb2e9b4", + "0x8ce5d8310d2e17342bf881d517c9afc484d12e1f4b4b08ad026b023d98cba410cd9a7cc8e2c3c63456652a19278b6960", + "0x8d9d57dbb24d68b6152337872bd5d422198da773174ade94b633f7c7f27670ff91969579583532ae7d8fe662c6d8a3b0", + "0x855a1c2d83becb3f02a8f9a83519d1cb112102b61d4cdd396844b5206e606b3fefdbcc5aa8751da2b256d987d74d9506", + "0x90eb7e6f938651f733cf81fcd2e7e8f611b627f8d94d4ac17ac00de6c2b841e4f80cada07f4063a13ae87b4a7736ca28", + "0x8161459a21d55e7f5f1cecfc1595c7f468406a82080bfa46d7fb1af4b5ec0cd2064c2c851949483db2aa376e9df418e6", + "0x8344ccd322b2072479f8db2ab3e46df89f536408cba0596f1e4ec6c1957ff0c73f3840990f9028ae0f21c1e9a729d7df", + "0x929be2190ddd54a5afe98c3b77591d1eae0ab2c9816dc6fe47508d9863d58f1ea029d503938c8d9e387c5e80047d6f1e", + "0x856e3d1f701688c650c258fecd78139ce68e19de5198cf1cd7bb11eba9d0f1c5af958884f58df10e3f9a08d8843f3406", + "0x8490ae5221e27a45a37ca97d99a19a8867bcc026a94f08bdccfbb4b6fa09b83c96b37ec7e0fd6ee05f4ae6141b6b64a8", + "0xb02dbd4d647a05ac248fda13708bba0d6a9cd00cae5634c1938b4c0abbb3a1e4f00f47aa416dcd00ffcdf166330bff9a", + "0x9076164bb99ca7b1a98d1e11cb2f965f5c22866658e8259445589b80e3cb3119c8710ede18f396ba902696785619079c", + "0xaacf016920936dae63778ad171386f996f65fe98e83cfcdd75e23774f189303e65cc8ad334a7a62f9230ed2c6b7f6fa4", + "0xa8031d46c7f2474789123469ef42e81c9c35eb245d38d8f4796bba406c02b57053f5ec554d45373ab437869a0b1af3f0", + "0xa4b76cd82dc1f305a0ee053e9a4212b67f5acc5e69962a8640d190a176b73fbc2b0644f896ff3927cd708d524668ed09", + "0xb00b029c74e6fdf7fb94df95ef1ccad025c452c19cddb5dccfb91efdcb8a9a1c17847cfa4486eae4f510e8a6c1f0791a", + "0x9455e5235f29a73e9f1a707a97ddb104c55b9d6a92cc9952600d49f0447d38ea073ee5cf0d13f7f55f12b4a5132f4b10", + "0xae118847542ed1084d269e8f3b503d0b6571a2c077def116ad685dcca2fca3dcb3f86e3f244284bdcd5ae7ac968d08a5", + "0x8dcb4965cd57e8b89cd71d6fc700d66caa805bfd29ab71357961527a7894e082d49145c2614b670dcb231ab9050d0663", + "0xadd6ed14f3183f4acc73feea19b22c9a330e431c674e5034924da31b69e8c02d79b570d12ef771a04215c4809e0f8a80", + "0x96ae7e110412ee87d0478fdbdbaab290eb0b6edd741bb864961845e87fd44bcbe630371060b8104d8bf17c41f2e3fca0", + "0xa20db17f384e9573ca0928af61affab6ff9dd244296b69b026d737f0c6cd28568846eca8dadf903ee0eecbb47368351d", + "0x937bfdf5feb0797863bc7c1be4dcc4f2423787952a3c77dfa3bfe7356f5dbcc4daebde976b84fc6bd97d5124fb8f85c9", + "0xa7050cc780445c124e46bba1acc0347ddcfa09a85b35a52cc5808bf412c859c0c680c0a82218f15a6daeefe73f0d0309", + "0xa9d9b93450e7630f1c018ea4e6a5ca4c19baa4b662eadfbe5c798fe798d8a3775ed1eb12bd96a458806b37ab82bdc10a", + "0xa52a4d5639e718380915daaefad7de60764d2d795443a3db7aeab5e16a1b8faa9441a4ccc6e809d8f78b0ac13eef3409", + "0x8e6f72b6664a8433b032849b03af68f9376b3c16c0bc86842c43fc7bf31e40bc9fc105952d5c5780c4afa19d7b802caa", + "0xa107ae72f037000c6ee14093de8e9f2c92aa5f89a0a20007f4126419e5cb982469c32187e51a820f94805c9fccd51365", + "0x9708218f9a984fe03abc4e699a4f3378a06530414a2e95e12ca657f031ef2e839c23fd83f96a4ba72f8203d54a1a1e82", + "0xb9129770f4c5fcac999e98c171d67e148abd145e0bf2a36848eb18783bb98dff2c5cef8b7407f2af188de1fae9571b1c", + "0x88cc9db8ff27eb583871eeeb517db83039b85404d735517c0c850bdfa99ae1b57fd24cf661ab60b4726878c17e047f37", + "0xa358c9aadc705a11722df49f90b17a2a6ba057b2e652246dc6131aaf23af66c1ca4ac0d5f11073a304f1a1b006bc0aa5", + "0xac79f25af6364a013ba9b82175ccee143309832df8f9c3f62c193660253679284624e38196733fb2af733488ab1a556e", + "0x82338e3ed162274d41a1783f44ae53329610134e6c62565353fbcc81131e88ce9f8a729d01e59e6d73695a378315111b", + "0xaa5ddcabf580fd43b6b0c3c8be45ffd26c9de8fa8d4546bb92d34f05469642b92a237d0806a1ad354f3046a4fcf14a92", + "0xb308d2c292052a8e17862c52710140ffafa0b3dbedd6a1b6334934b059fe03e49883529d6baf8b361c6e67b3fbf70100", + "0x96d870a15c833dddd8545b695139733d4a4c07d6206771a1524500c12607048731c49ec4ac26f5acc92dd9b974b2172c", + "0x8e99ee9ed51956d05faaf5038bffd48a2957917a76d9974a78df6c1ff3c5423c5d346778f55de07098b578ad623a390e", + "0xa19052d0b4b89b26172c292bbf6fd73e7486e7fd3a63c7a501bbd5cf7244e8e8ce3c1113624086b7cdf1a7693fdad8b5", + "0x958957caf99dc4bb6d3c0bc4821be10e3a816bd0ba18094603b56d9d2d1383ccc3ee8bc36d2d0aea90c8a119d4457eb4", + "0x8482589af6c3fc4aa0a07db201d8c0d750dd21ae5446ff7a2f44decf5bff50965fd6338745d179c67ea54095ecd3add4", + "0x8a088cc12cf618761eaa93da12c9158b050c86f10cd9f865b451c69e076c7e5b5a023e2f91c2e1eed2b40746ca06a643", + "0x85e81101590597d7671f606bd1d7d6220c80d3c62e9f20423e734482c94547714a6ac0307e86847cce91de46503c6a8a", + "0xb1bd39b481fc452d9abf0fcb73b48c501aaae1414c1c073499e079f719c4e034da1118da4ff5e0ce1c5a71d8af3f4279", + "0x942ae5f64ac7a5353e1deb2213f68aa39daa16bff63eb5c69fc8d9260e59178c0452227b982005f720a3c858542246c8", + "0x99fea18230e39df925f98e26ff03ab959cae7044d773de84647d105dfa75fd602b4f519c8e9d9f226ec0e0de0140e168", + "0x97b9841af4efd2bfd56b9e7cd2275bc1b4ff5606728f1f2b6e24630dbe44bc96f4f2132f7103bca6c37057fc792aeaab", + "0x94cdad044a6ab29e646ed30022c6f9a30d259f38043afcea0feceef0edc5f45297770a30718cbfec5ae7d6137f55fe08", + "0xa533a5efa74e67e429b736bb60f2ccab74d3919214351fe01f40a191e3ec321c61f54dd236f2d606c623ad556d9a8b63", + "0xb7bd0bb72cd537660e081f420545f50a6751bb4dd25fde25e8218cab2885dd81ffe3b888d608a396dfcb78d75ba03f3f", + "0xb1479e7aa34594ec8a45a97611d377206597149ece991a8cef1399738e99c3fa124a40396a356ab2ea135550a9f6a89f", + "0xb75570fc94b491aef11f70ef82aeb00b351c17d216770f9f3bd87f3b5ac90893d70f319b8e0d2450dc8e21b57e26df94", + "0xa5e3f3ab112530fe5c3b41167f7db5708e65479b765b941ce137d647adb4f03781f7821bb4de80c5dc282c6d2680a13d", + "0xb9b9c81b4cac7aca7e7c7baac2369d763dd9846c9821536d7467b1a7ec2e2a87b22637ab8bbeddb61879a64d111aa345", + "0xb1e3ee2c4dd03a60b2991d116c372de18f18fe279f712829b61c904103a2bd66202083925bc816d07884982e52a03212", + "0xa13f0593791dbbd360b4f34af42d5cc275816a8db4b82503fe7c2ff6acc22ae4bd9581a1c8c236f682d5c4c02cc274cc", + "0x86ba8238d3ed490abcc3f9ecc541305876315fb71bca8aaf87538012daab019992753bf1e10f8670e33bff0d36db0bf0", + "0xb65fbb89fafb0e2a66fe547a60246d00b98fe2cb65db4922d9cef6668de7b2f4bb6c25970f1e112df06b4d1d953d3f34", + "0xabb2d413e6f9e3c5f582e6020f879104473a829380b96a28123eb2bdd41a7a195f769b6ac70b35ba52a9fee9d6a289c3", + "0x88ec764573e501c9d69098a11ea1ad20cdc171362f76eb215129cfcca43460140741ea06cee65a1f21b708afb6f9d5b0", + "0xa7aaec27246a3337911b0201f4c5b746e45780598004dac15d9d15e5682b4c688158adffdef7179abb654f686e4c6adc", + "0xa1128589258f1fbfa33341604c3cb07f2a30c651086f90dce63ae48b4f01782e27c3829de5102f847cde140374567c58", + "0xaaf2b149c1ca9352c94cc201125452b1ed7ca7c361ed022d626899426cb2d4cc915d76c58fa58b3ad4a6284a9ae1bc45", + "0xaaf5c71b18b27cd8fe1a9028027f2293f0753d400481655c0d88b081f150d0292fb9bd3e6acabb343a6afb4afdb103b5", + "0x947c0257d1fb29ecc26c4dc5eab977ebb47d698b48f9357ce8ff2d2ed461c5725228cc354a285d2331a60d20de09ff67", + "0xb73e996fa30f581699052ed06054c474ebdf3ae662c4dc6f889e827b8b6263df67aeff7f2c7f2919df319a99bdfdceb1", + "0xb696355d3f742dd1bf5f6fbb8eee234e74653131278861bf5a76db85768f0988a73084e1ae03c2100644a1fa86a49688", + "0xb0abca296a8898ac5897f61c50402bd96b59a7932de61b6e3c073d880d39fc8e109998c9dba666b774415edddcff1997", + "0xb7abe07643a82a7cb409ee4177616e4f91ec1cf733699bf24dec90da0617fe3b52622edec6e12f54897c4b288278e4f3", + "0x8a3fae76993edbc81d7b47f049279f4dd5c408133436605d934dee0eadde187d03e6483409713db122a2a412cd631647", + "0x82eb8e48becfdf06b2d1b93bf072c35df210cf64ed6086267033ad219bf130c55ee60718f28a0e1cad7bc0a39d940260", + "0xa88f783e32944a82ea1ea4206e52c4bcf9962b4232e3c3b45bd72932ee1082527bf80864ce82497e5a8e40f2a60962d0", + "0x830cf6b1e99430ae93a3f26fbfb92c741c895b017924dcd9e418c3dc4a5b21105850a8dd2536fa052667e508b90738f2", + "0x990dce4c2c6f44bb6870328fba6aa2a26b0b8b2d57bfb24acf398b1edc0f3790665275f650884bd438d5403973469fa2", + "0xa2e5b6232d81c94bcb7fed782e2d00ff70fc86a3abddbe4332cb0544b4e109ae9639a180ae4c1f416752ed668d918420", + "0xb4cdf7c2b3753c8d96d92eb3d5fa984fef5d346a76dc5016552069e3f110356b82e9585b9c2f5313c76ffaecef3d6fd8", + "0x83b23b87f91d8d602bff3a4aa1ead39fcc04b26cf113a9da6d2bd08ba7ea827f10b69a699c16911605b0126a9132140f", + "0x8aae7a2d9daa8a2b14f9168fe82933b35587a3e9ebf0f9c37bf1f8aa015f18fb116b7fba85a25c0b5e9f4b91ba1d350b", + "0x80d1163675145cc1fab9203d5581e4cd2bed26ad49f077a7927dec88814e0bed7912e6bbe6507613b8e393d5ee3be9be", + "0x93ddeb77b6a4c62f69b11cf36646ed089dcaa491590450456a525faf5659d810323b3effa0b908000887c20ac6b12c80", + "0x9406360a2b105c44c45ba440055e40da5c41f64057e6b35a3786526869b853472e615e6beb957b62698a2e8a93608e13", + "0x93bfc435ab9183d11e9ad17dac977a5b7e518db720e79a99072ce7e1b8fcb13a738806f414df5a3caa3e0b8a6ce38625", + "0x8a12402c2509053500e8456d8b77470f1bbb9785dd7995ebbbe32fd7171406c7ce7bd89a96d0f41dbc6194e8f7442f42", + "0xaab901e35bf17e6422722c52a9da8b7062d065169bf446ef0cbf8d68167a8b92dab57320c1470fee1f4fc6100269c6e2", + "0x8cad277d9e2ba086378190d33f1116ba40071d2cb78d41012ec605c23f13009e187d094d785012b9c55038ec96324001", + "0x85511c72e2894e75075436a163418279f660c417e1d7792edce5f95f2a52024d1b5677e2e150bf4339ad064f70420c60", + "0x85549ca8dcbe49d16d4b3e2b8a30495f16c0de35711978ada1e2d88ad28e80872fca3fb02deb951b8bcb01b6555492e4", + "0x8d379ab35194fe5edf98045a088db240a643509ddc2794c9900aa6b50535476daa92fd2b0a3d3d638c2069e535cd783b", + "0xb45cfebe529556b110392cb64059f4eb4d88aaf10f1000fdd986f7f140fdd878ce529c3c69dfd2c9d06f7b1e426e38f3", + "0xac009efd11f0c4cdd07dd4283a8181420a2ba6a4155b32c2fed6b9f913d98e057d0f5f85e6af82efc19eb4e2a97a82df", + "0xb2c2cdffa82f614e9cb5769b7c33c7d555e264e604e9b6138e19bcfc49284721180b0781ecbf321d7e60259174da9c3c", + "0x95789960f848797abbe1c66ef05d01d920228ca1f698130c7b1e6ca73bfda82cee672d30a9787688620554e8886554ee", + "0x98444018fa01b7273d3370eeb01adc8db902d5a69b9afc0aa9eadfeb43c4356863f19078d3c0d74e80f06ecf5a5223f4", + "0x87d20b058050542f497c6645de59b8310f6eeec53acbc084e38b85414c3ea3016da3da690853498bde1c14de1db6f391", + "0xa5c12b3a40e54bee82a315c503c1ce431309a862458030dde02376745ec1d6b9c1dbeea481ae6883425e9dae608e444e", + "0xb9daa3bf33f0a2979785067dcece83250e7bf6deb75bb1dbbab4af9e95ddfb3d38c288cbef3f80519a8916a77a43b56c", + "0xb682ec3118f71bde6c08f06ea53378ea404f8a1c4c273dd08989f2df39d6634f6463be1d172ac0e06f0fa19ac4a62366", + "0xa4f94fd51ecf9d2065177593970854d3dce745eebb2a6d49c573cbf64a586ae949ddfa60466aaef0c0afb22bd92e0b57", + "0x86cd5609efd570c51adbc606c1c63759c5f4f025fcbefab6bc3045b6ad2423628c68f5931ff56fdda985168ce993cc24", + "0x981192e31e62e45572f933e86cdd5b1d28b1790b255c491c79bd9bb4964359b0e5f94f2ae0e00ef7fe7891b5c3904932", + "0x9898f52b57472ebc7053f7bf7ab6695ce8df6213fc7f2d6f6ea68b5baad86ec1371a29304cae1baadf15083296958d27", + "0xb676c4a8a791ae00a2405a0c88b9544878749a7235d3a5a9f53a3f822e0c5c1b147a7f3f0fc228049dc46e87aa6b6368", + "0x9976e10beff544e5c1645c81a807739eff90449df58ffdd8d1aa45dd50b4c62f9370538b9855a00dd596480f38ebe7a5", + "0xa0e91404894187ec23c16d39d647ada912a2c4febfd050a1ea433c4bfdc1568b4e97a78a89ba643aca3e2782033c3c58", + "0x91a6ea9a80476ed137eb81558ff1d55b8581663cccd41db4fc286876226b6515fd38661557419e1e46b6a3bc9cda3741", + "0xb9e8a1e23c60335a37a16f8085f80178a17d5e055d87ffe8cf63c532af923e5a5a2d76cf078164fb577996683796caa6", + "0xad8e151d87a37e8df438d0a6a7c02c3f511143efb93fde8aef334d218cb25932baf9e97c2f36c633620a024a5626af3d", + "0x978f942f210e8a482015e6fdc35a4c967c67b66e6e2a17a05cc7a0f2163aed227b775d4352b0c3cca6cbf4bd5bafaf75", + "0xb5e2e3d8b2e871c07f5899e108e133f87479959b80cb8a103fbecde00ccdbfbd997540eef33079c5cc14b1c00c009fd1", + "0x88a164b3fefd36857f429ab10002243b053f5d386466dbb9e5135ed3c72dd369a5a25e5e2aaa11f25488535e044e2f12", + "0xa66091c0db4e7cf05a089ec2b9ff74744354d0196968201f5e201699144b52bb13b4e68e12502727163e6db96e3565f2", + "0x8e65aff8e37240461b7374c20bfd1d58b73a525c28994a98f723daed9486130b3189f8efe5c5efcd7f5390cc366038da", + "0x8b37c21dd7304c3aa366959ba8c77ea8b22164a67e136808b6f8e48604297f7429a6c6ecf67b1d09b8b7ec083eacd7e0", + "0xb689b1277ad050f53da91a702516a06d7406ff33a4714ea859b3b2b69f8d0aa8f983c7e039b19c0759a3815d841fa409", + "0xb17f7a0a182ed4937f88489e4c4e6163dcf49fd2ea4d9efbba8126c743bea951cd769752acd02e921774dc8ebcfae33b", + "0x8b7fab4f90be825ac5d782a438e55c0a86be1c314a5dbc3cc6ed60760a8a94ef296391f1f6363652200cce4c188dae67", + "0xab8410c4eaa2bb43b0dd271aa2836061bc95cb600b0be331dada76ddb46711ff7a4ad8c466cc1078b9f9131f0dc9d879", + "0x9194bd7b3cc218624459d51c4d6dbc13da5d3de313448f8175650fa4cfab7cc4afcda5427b6676c3c13897dc638b401e", + "0x980f61a0f01349acd8fc9fdc88fc2c5813610c07eecb6ab14af0845a980792a60dadf13bb4437b0169ae3eff8f5984ce", + "0xb783bee24acea9c99d16434195c6940cf01fc2db135e21f16acae45a509eca3af6b9232a8aa3a86f9715c5f6a85cb1c3", + "0xa3079931c4b90966d1faa948db847741878b5828bc60325f5ebe554dcab4adcc19ee8bce645e48a8f4a9413bb3c6a093", + "0x801f61ac9318f6e033a99071a46ae06ed249394638c19720831fff850226363a4ae8486dd00967746298ee9f1d65462f", + "0xb34dbbed4f3bb91f28285c40f64ce60c691737cc2b2d2be5c7d0210611cd58341bb5bda51bb642d3ee2d80882e642a13", + "0x8750af19abfb915e63c81542b13d84526a0c809179bbcc1cd8a52b29f3aba3ae0f7cf6f4f01790bf64ef7db01d8ee887", + "0xa6ea10000eb2dd4efc242ac95bc3b3873cdd882fbeb7c9538c87e3143a263ca3a2e192b2159316a625cfb5fb0b6cdcb3", + "0xaa40ca54bc758a6c64cb932924917581062e088b3ad43976b28f2e11d8a7dea73f1fb50aeaa0e70182bb2dc07d805bb9", + "0xa4779dfd25b5ec9d75dfb54a4bb030364899a5e75c1492403acb19f2adc782c7ac4daeb66d2f5aeb74135afe9f318e3f", + "0xb4551e2805d63ca453f4f38b1921ac87ff687e1d70575ad38f3469d6f0608ef76b7b1b98ae1e6b1e7d928773aaab6e3b", + "0x99490ee722f96aad2743b08dd37bfeb75a8c59efaee4c9b694eaa05eb8a6bb23861a4480544c7617d04d23fd5e2543b4", + "0x8a7050d964d295fff98ae30d77ce730a055719313457e773fcce94c4d71a9b7cf63db67e54a8aab20fb1335b0130b5d5", + "0x903144e6bbee0a4fec17ff80fef0d2103981140c3d41776cfb184ced17f480a687dd093f6b538584327e6142812e3cd5", + "0xa5b30f7c6939bdc24a84ae784add927fec798b5a5ee3dd156c652df020728dd6d43898be364cf5ee181725fbcffc0964", + "0xb43d97ec2bc66af92d921a5c5c20a03ef2be2bc2c9b345f46d8287409fcbfd88ebc49d4509d64468222cd1d2021bf236", + "0x82dc23c7f5086c9ac6b4566359bfb830d203544b0d8332a210775670f899cd9ff48b94bfeba40040c25664ebdd5cfad8", + "0x9294cd017fea581dabb73dcc8c619904d7e022b664b0a8502c9d30f3807668af279948e7e41030ae296d492225297e95", + "0x8d6c9dc636c8e884f9a4299e5cff06d044ebc94ad783a4b71788347ea4a336d4d048b8a9ecabae789e8fcdc459723dfb", + "0x801a80bc49e882ec81b04e37407713f033f7bdac79252dfa3dc8c5bd0229fcbd4019890e402cf843b9378df08f72ab84", + "0xb4313ca32569d973900f6196363c0b280ddfa1b47c88d019e5f399b805b444a777950fc21ae198fc23ece52674b94abf", + "0x96f06056fd255fdabf78986e315e7c4fdf5495cf850536b7976baa97a994cc6a99c34609c33a0f2facba5e6f1026dce6", + "0x983ed80220a5545ffd70ef5e6ac10217d82ec9cd8f9a27ee77a5ff4074092308c0e6396fc4e9932a77ddd474e61f8b55", + "0x872a059aa630af73c4abbd076e8b333a973ffc5bdecf5dcc0600b00162184213cb19d4f601795030033beb808d5810ce", + "0xb040f318d9d3b8833da854014a44296dbd6762dd17cab13f91987256c54353b7f0800547cb645a7cc231997454209fdd", + "0xa8c4731a555308e8ce0b8325eb7a4cbf6113d07e9f41932df04480b72628d313b941c7055f1cc2ac45c7353b56e96ca9", + "0x8c24031440b77637e045a52e5ea3f488926ab0b426148975edf066c40a4581beecc1bfb18fc4cf5f9f96dc6681b4bd28", + "0xb39254b475abf342f301298feaa17a4b3051f30ea23a18acf59e003e2704ac96fe40691f1da387913bdf7aee6389f9a8", + "0xa1dbf938b604ccc6d60881cc71f38df568aa02752aa44d123514154017503f6c1c335ae43e359f1487bc8934073cd9c1", + "0x8d52aa1be9f429ece0580498d8fe9fef46d4a11f49436a82b8927f9503dacc41245907f126594c1cd30701286f8c092c", + "0xb826f396486942c0326d16f30a01b00a682c30a75553dc6ac34fd5b3e96b13c33b94738f522eebaffb59ff8c571c76e9", + "0xaa89f51cbf6e6c3e2aa2806187b69ab3361c84e89f393f3ed284fe84db46fc3944aa44f8928e3964f9c1a1ec27048f68", + "0xa254df0efa4203fb92b42a1cd81ca955922e14bf408262c8f7cb7dc703da0ca2c71556bd2d05b22ce9a90ad77309833d", + "0x93263c507e4d5f4e5df88e85b3d85c46ea729fb542a718b196333e2d9fb8a2e62dc1347cf146466a54ba12d200ef09d9", + "0x922e3c4a84246d89a07aa3e90f02e04b2cea9bebc0e68b742156f702aed31b28c6dfa7ac936ea2fc2e029adf68361f98", + "0x9a00628eeeda4ccbed3ef7834149aec4c77aac1a14bc2491ba5d1a4a2c5d29afb82ceaa5aac1c5ce1e42cdcaf53e30ba", + "0xab3a88df36d703920f6648a295a70ffa5316c96044f39ff132937bfda768937cb6a479e9ba4a4e66b377f3a9996a88c4", + "0x966b11526ab099d550ab33c6a9667e5cfdedf255da17a80a519d09acd78d2ea24ec18bd1ea7d8d63cf0a408f1c1fe0b3", + "0xb5c21b9817dc32f3df9d9988aa3560e1e840d586d01cd596bc0f850ab416b6013cbf7dbfd05ac981f26014c74bd2d2b2", + "0x9040abef5e2523e7f139c9f744a64b98fea3a57952059ffe4d5ed77fa87068203c090ef4e7f52c88fb82ea8a6fdca33e", + "0xa0dcdaeb7d3f5d30d49c004c5f478818c470187f4b0b4856812dcd1b3a86de58a99acb8ceb44c6b80c3060cf967c43a4", + "0xb5f4be9a69e4a6719ea91104820df8623b6d1073e8ee4168de10a7e49c8babea772bcbc6b0908185e98d607e49cd3609", + "0x8634020a5a78650015763c06121c606d2dd7b324aa17387910513dd6480fb797df541fc15b70d269b2794ad190595084", + "0x9504d1d0fb31ff1926c89040c04d51fd1f5cddf9d7ca3d036e7fd17e7a0f767ef33cee1d8bf7e17e2bc40949e7630417", + "0x812c72846ef6d692cf11d8f8c3de8fa78cc287303315114492667b19c702cd24d462020f1276895df26e937c38f361f8", + "0x8c97aa5e9ef2aa9a1435ef9ddfe62e850f0360864ed5fb82bf9fef4ef04d8fb4f827dc078bc911ee275e4501edd6617c", + "0xac5f7af5e23c8e429aaa6b6825129922b59d25b4608f07b65f21388a9ac3aa89096712f320afe6d56e44e1f0d51a4eb9", + "0xa8c84d9a8593a0cb5be1e450960f59878a4e6b70da54a7613dfc25911b7cc9e6d789d39401b0a0d6471ab9dcdc707976", + "0x8c9d5fd89611392c0f085ffa4fa642a181f0b9b23593deb5e10fdd1642722ca75ef34a037e88a8d03f2888fe7461f27c", + "0x8c74b05f91fb95c85e7bd41f6d9a1e41e667e68f3d19b325c1f25df1767019919edab89b92af237896cbc4e6d6dc1854", + "0xa3caecb91640821f0b2c4981b23f2069df8d2b98ce026c1538bc096b292f5f956a5d52c1c8d6a8165a1608083ba6494b", + "0x8ae8e0c36f8b79a69176ff29855df45d0fcd9e4d1dbaed8899f8fcdece676e418ec034a6c161e2a894f0c834aaecbfd1", + "0xb88d18c67dc3b1b6ed60ee437c441c1ed14ecddebccf43683605716f30058b1aa4ba05ff10cd8171ee97d8f58d70c094", + "0x94f43d84dcdfd9cd19115c7d8e9c1e856828eafbfdec93b876cf0007e317e30b2ad951dbabc186aa6ef90fdee4d91990", + "0xb44e4723f41fc1d5b0057f371e3381ae02566590b3f964b6eb07b2104f66ff78410c407235fa98d04f635694f3baca09", + "0xaddd8390173d29ca0811534d389253831fed75fed135398617836b6e70767269eacb1560b39a58f02042ca3b97fe59c4", + "0x80bdbdacc0c358c7ea52aeacdc5f9ceb6928bcf6e7dee7c17d8ae3bf7c2372aa7a0372363888968fc0921aaf4776d5d0", + "0xa486e2b6f04f403f9e609d69dfb3cfb992af56ecad1683271df3e3faa3b86638b81e73b39978fb829ee7133d72901f2d", + "0xa19472da57457e10c6a6307895393ddaec8f523760d66937fe26a025817319e234eaf69756ffdf1b84c81733424a96d7", + "0xad6a195397cbc2d75171f5e82090441eed60bd1ba42c39ef565b8b5a8281b04400678625b1dc46d617f694a7652a8e5d", + "0x8f98e721c06cec432e2221f2e1b06bb1469d916a8d88d6973acf68d1e003441d00390dafcead8ecdbf9eae4509baf5aa", + "0x91d62a0f9d13c59adfe1376ed6d057eae244d13c6b3d99be49a49e0075cf20f4085cf127774644ac93615be9ac9e5db6", + "0xaf45dec199245e2b326a0d79c4899ed44b1c0219db42602a4a6184ace0ff831a3276297af28f92e8b008ba412318e33e", + "0x8754bde54e8d2d169e6a7d6f0eae6097bc0461c395192bd00dd6f105677ea56ab384c02553ea5eeac0a65adcb0df77ee", + "0xb676afd2f5afc37a314c943d496e31b4885efcbcc2061036e370a74cfde5642bb035622d78d693bfc3136fc036c7edb4", + "0xaab6ffe6cc234397cf1822e02912bc282dfb314e92fb5a9e10d0c34ee9b5856d4b76e166bc2bb6fcdd66aabea35ec4ef", + "0xada6e62f90ee6b852ec4b72b22367acac2896f0df2c105beda27096583ddbedddc710d171330569f111c6e44a5b57ae7", + "0x802139dd15241a6de663d9b810121bdd9cf11f7f8c8ca6de63f4f8e731409e40d1fd3558b4f619ed42ee54929dff1c7e", + "0xad8e70531cec21b4e6f55be1751c2d025bd2d7d8158269b054cfe57fa29252d052ce4478ec7db6ec705789e2118d63b3", + "0xa8e4a4271769480e1b33a28c87a150ecc0b48bfe8a15ae04152197881de4ce4b03453aefe574842424edbbe4173e1a3a", + "0xb98c65726296610cef16c5b58da5491acd33bd5c5c5af4d934a9840649ef85730fbce8018dee09ded14e278009ed094a", + "0x8e213a7861223287b860f040e5caaa563daa0b681e4e09ec79ad00cc459238e70bbeaf7486bbe182fc12650700034ec5", + "0xa2879f9e1a556cf89b9b5b3bd8646a8cce6b60bcbc8095df44637f66a2da5858eee2dc9091475a8f64bb5aff849389cd", + "0x8a17cdb4077b9b0bcf28b93294ac5ae4c8bba8839fce0f1012b53187ac008f9858b02925fbfc421f1123afcdbd8b7753", + "0x86fd9c11528aa43946e4415ff64a3ca6409ee6f807368c68997b18605da65e415ccd85ad913820d450cb386593de666d", + "0x8ed55923b963c3d85a91aca11c40ff9c6c7f1e2b9bc199d1a270e5fb16aa62dec0136e97866145ae9d58a493e8b1cbbb", + "0xae32af5b5d418668ae123c639b149e5eed602404e8516da4a61db944b537a3620545e8e3d38cf10cdaea980ab2f80973", + "0x95cb8d9e9d6762d78dde0ad73869ffaca904a7d763a378b8cc11a7933d3e7d1c8aec4271a079b1b00f8887ee5b1ea21f", + "0xb5ea20b42a3ca247f00ab5328c05f0cf194973d5f7271c66c41c5055b1ffdca136be179709e0c1de209fbe07b9820bf3", + "0x98682f7cce471c92a8d6d15fee4ddf4d43dd97c3e3811d2913618ecacc6440b737717c07736ae4558c910e11ee98104e", + "0xa67da2c7cbba48e929ca4e4b9a6299fe01ef79eff8cc5cd3fdbdc0721a68130e4079f30ae151a573a7dcca8ecf2e684e", + "0xa9981c9f9dcbb3b0f6996f664fb2acd7573189f203be37b2b714662aa273551396abfb1f612ccde4e4c8127a050dbe4b", + "0x92d55eff8da600f886da9bf68e8eecf482faa4b268f3f286b3b3e5cc91b19604081498d4905b201bb4ec68e32b5591d9", + "0x963e3f1728de9d719c86d390f3eb9c3f99d1928347fab0abf10dbb37d76b59ddb64d4734c977863a6cd03ffece5ca895", + "0x93480e2de83c921056b6d8628ac37cd5ef7555ba43b0308fc13386cb0515d42c12ecd06057137aa71a7931beaf90b9ce", + "0x8feae57ff0e6a162cc81c99f45c6187d268fc0bee8c2bffc92142ef76c253d201f0e932943cf2fa312982b281ce1066b", + "0x8f8f4bd4200fb87afcd743274480220d77571928000d4197410dbb75439d368df6a06d941a6152206371d2ca9cac99e4", + "0x8ee7f11e79af4478e0a70eb424fe8078237ad99ba6d7e6bf1a8d5e44e40abd22d404bd39b718ad6fdf4c6601f2a47665", + "0xa98acfcec612b574943195b9ba95bebcc9c0b945c9f6b3e8760b2a4635909246a9d73b0b095c27b4ecb3339704e389b7", + "0xb520efd19f65e81dc285031ea3593f8c5dad793e4426beb9196ab46e45346f265fd71e50adb0da657977c60ed5724128", + "0xa3d9d0b7415280ce4dfa2429d47b2b8e37604a5157280a72cc81d541ffe44612dbb3ef7d03693fc42a569169d5842dc3", + "0x8c29e2d0b33801f6d9a9c065a76c5cad1fb0a001506b970307e21765ee97c732a4cbf1d7c1b72d95e0ad340b3b075224", + "0x839e21f292892a6eb596b9b1e9c4bd7c22a6fe71d3d04487c77840028d48392c5cbe73140a4e742338e0c8475cd0c1ad", + "0x8bea5c68e7743998619185bb662e958f1b4d3ca81019d84ac43c88911aab3abe4ee9bcc73cb95aa3ae87c0138801bde3", + "0xb8f262d21a94604049e008ce03dc857848168e1efca4522acb0ccc827ffb37f545e1947843a356563a76bc6489605b66", + "0xa7bd0842b0bb38d9943b82aa883f36f4eb8a6e8a7790d4f87faf306608f51d250a19b73984f1156cef5dd2581664614b", + "0xa993e649bd953627a88a2539dac3a12ec7f37a4c65b01425d9d34edf7ee10a71aa98f65c9e013107f824faf8aee041a9", + "0x8e07eced75c67cb4d2ec01857f6ac1408482e6b31cb2faa249e8cf99f180575587df530c7782a7539b5221121ef48aa0", + "0xb2f4578f26c05ecb9e2669ca744eb19d4f737321ac7d04fafd18beb7866e0fec9dd063953ae1f077b44b9c6f54db1279", + "0xb6b3788a6c7bcaf467d19daf6ab884d549aa866970c05a9181f544ff190d043192c84fe437a75a30b78b425461cca062", + "0xa270684903c61544b85a7041e81f65e787e1c1e23e57538fa8a69836bed0ca1673861dd29f743a1280f2f38eddd3aa83", + "0xa9c2397c4773dcad2821266dadfd2401d013d9f35de6744f2ec201f3507700adb1e6ec4f5a453be4764da8bf68543f26", + "0x83a3025ed6fd5df9d98be32a74e10a0d9728b560942d33ba028536fb148fc34ae87e92be2df3e420a8dfec08da495982", + "0x90dc70c183a90bab988b4a85b7b921c8070af0e5f220364fe11afa0722990b2c971e1e98eef62d3287fedfd9411f1df7", + "0x82d940937a6c636224d04f8e2536f93dcf20dc97a5f188875ad76c21b804aef9af10839419b61143c1f88a695959a6b4", + "0x8017f9473ce49d498d6f168137e77e62fe553e5a51e75b519cf2cbd1ab9afdafad80fd5e6fd0860e640b0d78ca8ed947", + "0x80573a0ec049fe1f7b3013b2839e145cd87e07c0e43826a29ef8c92516f9a30896c2ffcf3ed77ed22a6cf3101b1789d5", + "0x953349abd2559f9824db07cec857ad54f1a05018f3076425f8dbae37f8d92a46af2c04ab7c8ec0250449541187696e98", + "0xab7bd2c4f05ee9a9f252c4e16a20993a12c535c3809d124bae24642616521a9768d3f19eceaf8524583f47ae1f527684", + "0x9883b77ee834ee0112ca2f366d2a6fc213e0cf454e061438c2901a5ba35b7378f64da8adf6a476eb1562991ef5b4a5bc", + "0x89291811db308637356dbf7ed22cf07bfce33eb977734ee346e8c15a231b35d8b4443574f3fa97a40867b3e23b0bbfa4", + "0x93d753849d7d9588d39e38217500b123a6b628a873876612d9f98b5d611f52c89c573432d2176752b5d1cc2d94899b8b", + "0xa45add3c4844db3b7a237295fc85fddc788ac1ec395a0524d2fc90a539571a247146aea4aa10eec30a95e9617c85b98d", + "0x90f94578842db7a4de672da1e483858ece5e466c73c12f725a0fc71f42ff880c9447a33fa9096839bee817536f2591e2", + "0xb2c1b6fb031bb30460f157356562b44b4de096a0a112eab4fb3cc500aad38bc770da1fc2e73caf687a0da5e8537049c0", + "0xafb15e15fd930929c0e3c66482068a5afe0c7b7f82e216a76c5eb1113625bfa0b045a52259d472284cfbaf4796c71456", + "0xad222a9a3d907713418c151b8793d5e37634354322068f8206b9d0da1a3f53b0004193713d23ec35990639a1b6c2e075", + "0xb44a128dce97e8c4b178cdbca0a5c1b3f6e164490fac0fd68dbfe0aafa89920bb4ea420a8527e06c80dd19c2f135e3ef", + "0x8596e993ef18b8d94e9c42a90cb7060affc586b8e9b526820d25124285de5590134e2e86592e9dc4dd45ccf5d578fa60", + "0xb71bb0ad138141ed506b2253e84110d2db97cc2d24a3fd0d096b0022d9f38f87aa74e2f505074632d64e90bcc491aa30", + "0x84841eafd357309de47b92ca5ec163dec094a2e5271bc65898c31932e0160bee165e4decb23af339cfe09c83e1cc5441", + "0x8a2915ee39a6fd4a240b98533d7690ef1773ce578ed1fb05ed414ebe36f7ef289fa46f41768df57190438c356331e329", + "0x90bb337165386f1990cbd8ed2e8321ef21bc18125b015b4da0c37e5fcc446b26005379ee4fad8ce9348ceb4ab49e82e2", + "0xb707b50ea2ab05c6d183671587f25fe29eef23fe569d731459a1ac111a0b83a2cd65b88242876b34aeead3b05a15d745", + "0xae1f159f79b7996315c4f9acce7e21a6ed59d4ef76331196fc86911fda3035edd5c11d568b105175a36c948d0263b382", + "0x922bc525bace05e5dff6b5cabde5469ddd2c1c601f7131abc04ecefdd35095e6ac015b1aec3c3b25c5dee8d139baf60d", + "0xa7b060405b2740f82db64683187b1bb89e5f40c8438663c7cbc8ef2513929fe5f92625667a7f2f599a72a96b1fc8f08a", + "0xb9dfe94a08651db5efefbb813269bce80d814e3089b80c0654491e438d820bf521f8a4a4477909344ba88f7683eebb43", + "0x841817a9729465743576950b6e8eea32ebf39cca99ace86c4792f9f35926e2d6830c52854a3b2eaeb61694e6845008bd", + "0x934128034bde8fc7b93b952aa56e0ed28b36cfa04cfa1f0d5b38266dd40beedff5e0bab86e4717b0fb56c56be2eae26b", + "0xaee9d64caf28596308782cd8f3cf819506daf3378f86157ff775e618596411adf94efd0e9542787ca942066f02cbd332", + "0x85871184db314411a49575fee088c52ed5dba4e916ee001ec24d90898a0154d9790a06aa8a707ca7a8b986c0293b8d89", + "0x8d3d87edcc0187a099c97b581a598d357a41ac152303bb27c849eb78e72e15cb97cf9a0468fc36f245c3e152c76bb7dd", + "0x900475d165dec18b99eb7b5f9e9ad1d2d4f632e55fdcc4c5ecd7775fed462990e6aaafe9c669f40508f9b15f00bda31f", + "0xa25b5954edd57e7811a0d18532043d975c7b44b80f65cd630935d7b16ada05f30fe2b7be7ae8a2f54c25957faf3f1950", + "0xa089019afa3a7a15f7e7874e73b6773c0a824e6d3379b4c928e173321fb165ad979a6be004d394c28d19d410b2655d3e", + "0xb28f46797dee0c538bd3de815df641a0ef718ad3e52b2764aec380d6905b38b50ad6f60d0f68e096ca39960ba7734355", + "0xb0ac155d3d05851b04104e6b459f1a68e9e155437c92421a7c0e4dd511ef89cf71dfa3cc920769492ee283a65ebf029e", + "0x813c69a810745580d43d5b5480f0ba81000fbef0071e6b655c7346bef5ed774e9214a7816d40eb1774a5bd033767a046", + "0xb176345ca75c64f10ec33daa0dcf1f282b66a862fcd3d8d66c913f9a02db4c9d283dadc02eff13aaab94bc932a42234e", + "0x92560f67e5b995db4a489bb86ee78b4aee0800143b3535ad557a53e9e08716bd0202d9f5714722c2a5e8310046e3f5b3", + "0x8adb427bad9cc15fc6c457a96a6750dda8c46d859c5f69bf0e7ab8fc0964430b33967fd47cf0675b6ba1757f91255e6e", + "0xb120f723b80389a025b2daa891b140b3d7b8d520ae2a6a313f6e3d365a217af73292dcb249dca1f414ec05e865e3cdc7", + "0xa61a5d261a8dfe5996c42ea0a5ae703a2adcfda80e86837074d868eee16f87d38da19596c48b55dbd7a7cbec1a9b4996", + "0x99dc921eacc6bb867c5825ad4c83bc4af9dd78a18b3d0e1a60ad493e3805b8fb9b7922b577da1adb3d805edfc128d51d", + "0x85455fa165a07282aaab4a5bfb88027f47b9532e4af8195c048515f88b0db7e80f42e7a385fd4944faaa7f2a6544ad17", + "0x96dff2d1c8a879d443fe576d46bcceaf5f4551d2e8aad9c1a30883637c91090de99ad5eec228eb5febf93911502d3cbb", + "0xa87eb7f439377fb26c6bfe779701f4aea78dd7980b452a386afec62905e75217a1996c5234853432a62ef8bab21c31c3", + "0xb598278293823e9ccb638232a799211173b906444376337fdf044d0227d28fcc4c5867e6ecb3200e59ca0b139e71cac9", + "0xaa6fe147edc95027654d68140f428ec53cede3552c5f49c09d18bc6f6ae8c739a63042eb7291d14d717a4e1f0778abcb", + "0xae8ee18913d328b2fba71efe65526d3ee9c81beda53cf776baec4019ea30212010758cbb5dc85ed6620ce04b189f01f2", + "0xae9fb686777e88dffdd42805fe4114aa0da1b350d92a27ff3f8a817fb25af1fcfc9a06155affe0273bf13caad16a5351", + "0x95d372ba3a2ee38371538f34aae91b4844488e273f70c02f1992370f89fc2343eff95692d52ce9f21206abbee4959958", + "0xb15260376f0a34ca2827ff53acd7eaaef94c9acc2f244b36500423069cb1cdaa57ac8dd74adb5b53d0fd4265fcbb28ea", + "0xb0ffce6a8059537ef6affdbbc300547ef86e00109289239b0c6930456c562b4ed97f2e523963af17736dd71b46c44ac7", + "0xb5499a1277d34f9892f7579731ff53f423f2ffffa9ea43a6e929df8c525e301396249a2324818a6a03daa0e71fcd47b3", + "0x98dbfb8e97a377a25605a7665d4d53e66146204d8953afda661ae506858c5cd77ff7f21f5f10232e06dbc37378638948", + "0x84177e27e6da0e900c51f17077f5991e0e61bff00ca62c1623e627c5aea1b743f86eef6d55b13219a1947515150bade6", + "0xb50407bb5c61b057ab8935df94fd43ca04870015705b4f30ceac85c1035db0eb8293babc3d40e513b6fb6792ecbc27a9", + "0x988699a16917514e37f41ab5c24f4835ed8a2ca85d99972646fcc47c7e2a83c2816011144a8968a119657c4cda78d517", + "0x920c43fdcb738239ad542cb6504ab34498bce892311c781971d7db4dec70e288676de4d8697024b108cfa8757fa74035", + "0xaaa106329aac882e8d46b523f126a86d3cee2d888035ce65c0be4eaae3e92fd862f6ac2da458a835539cccafaba9e626", + "0x96e4c1562d14b7556f3d3e8a1b34ea4addc5a8170e1df541dc344728bcb74cd1630eb7ba4c70e9c68fd23c5c5d5a729b", + "0xa616ac5016d4e68e03074273cd3df9693ee0ce3458e8758b117a5c1bc6306dd2c7fad96b1bb37219c57ac62c78ad7a3e", + "0x8db7d9b20abfb1445babd484ae9e38ff9153ac8492230d7591e14e3fca7388a5ca6ef7d92ed445c8943cf5263e4a6ad7", + "0x88464134221aa7134878eb10928f31c8bd752ab68c27c9061c1de3f145c85731a4b76acdc7e939b399b6e497f9e6c136", + "0xa5f7c794f70b7c191c835dded21d442b6514bab5e4d19b56f630b6a2f1a84a1d69102d7a0dcca256aab5882d3f30f3ca", + "0xb96b6f98b6817b5fa6b1b1044e2411bdf08bf3ffaa9f38915d59e1d2b9bed8b3d645eee322ee611102ce308be19dbc15", + "0x92c26ade2e57257f498ac4ff0672d60b7ea26dad3eb39ed9a265162ccd205c36b882dba3689758c675f29e20836b62d9", + "0x8379a0299e75774930577071d258e89e471951642b98e5e664c148af584d80df4caa4bd370174dae258848c306f44be5", + "0xa0e53beda02bd82bf3d24bd1b65b656238128e734b6c7a65e3e45d3658d934f909c86ca4c3f2d19e0ac3c7aae58b342e", + "0x8ca5ceaeaf139188afd48f9bf034d8baf77bbf9669791c7e56ebf783394d7fcdf2a25fa4bdfcddfde649aa0dc67ccccd", + "0xa8060e6448844e9db4e9fb4da1c04bcf88fda4542def5d223f62c161490cf1408a85b7c484341929c0f9ce2a1d63e84b", + "0xaf6e1a5ecf50b754bb9eb2723096c9e9a8e82c29e9dcaa8856ab70074430534c5395534e1c0ed9ce98f4b84d4082fa67", + "0x81c8dbbef98f1b561e531683d5ae0f9b27b7f45dc6b2f6d61119ca0d559bf4ceb676d320afc5aba1811eeef7547a59d8", + "0x85b46cd64d605c7090a2faf1a2aadf22403b3692b3de1d83e38b2de0108d90ac56be35b0dca92c7a41c4b179a3567268", + "0x8dd3cc3062ddbe17fd962c2452c2968c73739608f007ad81fa1788931c0e0dda65032f344a12249d743852eb1a6d52a9", + "0x8630f1707aea9c90937b915f1f3d9d7ba6bda6d7fdef7a40877a40c1ee52471fd888f84c2b2c30b125451b2834f90d3b", + "0xb4a747e0bd4e1e0357861184dacec6714b2b7e4ee52fa227724369334cf54861d2f61724a4666dae249aa967d8e3972f", + "0xa72de682e6f9490b808d58f34a0d67f25db393c6941f9342a375de9ca560e4c5825c83797d7df6ed812b71a25e582fff", + "0x8d5ea7d5c01f1f41fffe282a334262cc4c31b5dcf31f42cc31d6c8e37c9bd2f1620a45519dab71e108fe21211c275b6c", + "0x8ccdc7e3642c2894acbf9367f3e99c85963cea46dc5473d175339a2391be57dd8815feacadec766e13645971213b9eb8", + "0x858e9b5fc8c13b651ff8eb92324bdda281db4cf39f7e7bd0472908b3e50b761fa06687f3d46f4047643029dc3e0ceeaa", + "0xae20d36c70cd754128c07cbc18dcb8d58b17d7e83416e84964b71ccff9701f63d93b2b44ec3fddc13bbe42ebdd66221e", + "0x860dbf7013da7709e24b491de198cb2fa2ffd49a392a7714ad2ab69a656ca23f6eafa90d6fdc2aa04a70f2c056af2703", + "0x8f809e5119429840cb464ed0a1428762ba5e177a16c92581679d7a63f59e510fdc651c6cc84d11e3f663834fcafeafdd", + "0x8d8a8dce82c3c8ea7d1cb771865c618d1e3da2348e5d216c4cbbd0ac541107e19b8f8c826220ca631d6f0a329215a8d6", + "0x86e3115c895ae965b819e9161511540445e887815502562930cedc040b162ecb1e8bdc1b6705f74d52bf3e927bc6b057", + "0xb9833b81a14115865ca48c9c6a3855f985228e04cbc285f59bf163dca5e966d69579ea4dba530b1e53f20bd4dccdc919", + "0xa71f5801838a6dbb162aa6f0be7beea56fadac1a4bcd8113a0a74ab14fc470a03775908c76822d64eb52a79b35530c05", + "0xa77ab73ae94b6d3378884f57eee400eff4a2969aa26e76281f577a61257347de704794761ea1465dd22a6cc6304fbc4a", + "0xacd1c5df3c487c04cf27f002e81f2348a0119349b3691012526a7b0d3bf911cdd3accbc9883112ed2ba852145e57fe68", + "0x8a28515a48832ac9eaf8a3fb3ad0829c46c944b4cb28acbcdbca1d0d4c3c623a36cda53a29291b8f2e0ea8ee056b1dee", + "0x846bafca11a7f45b674237359b2966b7bf5161916a18cf69f3ec42c855792d967d3bf3f3799b72d008766206bb7a1aa3", + "0xb24b341675b1db9a72c3405bbe4a95ccdfd18fa96f876ec946ccb5108f73e8816019998218a036b005ef9a458e75aeb3", + "0xb99c267b4a09193f3448bc8c323e91ef5b97e23aeff227033fe5f00e19bab5583f6e5fcb472ec84f12b13a54d5c0e286", + "0xa088aa478dbe45973b04ecafbcbd7ee85c9a77f594046545cdb83697a0c2b01b22b1af0b97dd75d387bb889e17f17aa7", + "0xa0c6b0cdff2d69964134a014e36c3709d9e63f6463c5cd7b01b6f0be673731b202d577539d89dd57a888326da1df95af", + "0xb4e6dc4ef11b2b41794ece70a8968e56705199d183366759568b6fa845d2cae127486e926b5b27ae9118bb21d1682c1d", + "0xa007804353f174098f02540a57e96227232444d5ae0a24232c244647148b6c049848cbd2b50d0a25af3ca9164bfff8ee", + "0x873fb034cc39c9cee553ece908fbf315f62efbc412b9afdde6a1889326b7f6f813e050b0601ba9921688e958cb75942e", + "0xb5676c90f0106c40d8683299e59d564f505ec990230cb076caef3ae33f2021e6aa5c9b27bb8fead05fc076df034c28f5", + "0xb5a67fc4c5539ad1ddf946a063110f824f7f08d2e4d30762c9d437748c96c9147a88efc22260573803ab545c18b108f2", + "0x817ff2b748a949973a91b69b0ec38efbd945aeb26a176d19f0fb76e261c7526c759e6f5516f9ed34de6eb1ac7838c9cb", + "0x99b76bda3526a5d841e059010fdb14eb2fa035a7d10463373a062a98c3c1a123e2da0848421dd7546d776438fd05e304", + "0xaa0d363270f90d56bbee7ea577b0c358532bda36d9247af6c57d000044a97ba41e35bb0db438f4c94551c6350e4e0674", + "0xacdae205d05f54b9544be96c9032350511895ccf413dbbc56d1f03053185df22a6d5b7ffcc3fbe96c3e2ce898ccfa73e", + "0xb091c220a1de18d384f50dd071dca4648ca4e708162c52a60e2cedc0188e77c54639f75bce9a468a64b2549119c07ded", + "0x878676133e5c700b1d4844564fa92a9930badb5293d882aa25ee6721a9f2cfab02088c31d62cf1342ae3edaea99a1ea0", + "0x9756d0793e6aba3b4dff48100bb49a5ec08ec733f966cb438379b91caf52fc2a5930830ec3f49aa15a02c82c1914dc7a", + "0x9722f760184d3b2d67cb2cea7fa41b1ff920a63446006bd98c6347c03d224d2d8328fa20ccd057690093d284b9a80360", + "0xb5a68489de4f253715a67f0879437bfe8f4dfc4e655ca344848980e6153b1d728acde028bb66fd626fa72eedd46ff683", + "0xa8cfc900b34835d9fd3add08044636f69614eff9ae929eac616c39bd760fd275ee89bf24b0f275dd77a66e54fd6b94e5", + "0x89967479bebf70b2893cad993bf7236a9efe4042d4408022fdbb47788fabedcec27d3bba99db778fcde41e43887e45af", + "0x889235938fcec60275c2cf0f19d73a44d03877d817b60bb26f4cbce09db0afae86d42d6847b21f07b650af9b9381fa82", + "0xb7fc321fa94557d8fbdd9fff55ab5c8788764614c1300d5ef1024290b2dbb9216bce15cb125da541f47b411a2e7e3c2d", + "0xb11b0c4dc9477176b3cda6b17858dbd8c35a933ed31364801093f310af082cb5a61700f36851e94835c5d4625bf89e32", + "0x9874e54d2939ee0600f4194f183877c30da26d7515e9e268fea8d24a675dd2945d1565d9016b62b1baab875ac892f4d2", + "0x90df3a77280d6f1fa25a986309bba9d5b89c3cf13656c933069bc78e6c314058716b62eacfa7ab4aff43518b8b815698", + "0x962b08299a287d77f28d3609f39fd31bc0069f7d478de17539e61fcc517045050644b0307c917208b300ce5d32affcca", + "0xb30eedca41afb6f083442aaa00f2e4d5dc0fda58e66aaf0f44e93d4af5c4bf8ea22afec888cacbf3fae26d88e8d344cc", + "0x847747a22fab3fe3c8cd67f3f1d54440f0b34ce7b513225dc8eb4fa789d7d9f3577631c0890a3d251e782a78418fecfa", + "0x8d1ef3cb5836e4039b34ee4e1b4820128eb1e8540e350309e4b8fea80f3ae803d1f25f4b9c115482b324adf7c8178bc7", + "0x8f8a2b0b0f24f09920b58c76f7d99ec2eb2e780b5a66f2f30a9ed267dcaea0ec63b472282076c7bf8548211376c72f6e", + "0x831ee6dc8889bbf4d345eaeb2f425959c112d2190764abbbe33bc44e1d9698af87ff5a54d01fac00cfee5878dee7c0f6", + "0xa7eb2479ac80d0ee23f2648fd46c5e819ad3a1f4752b613607ae712961b300e37f98704880ac0a75f700f87d67853c7a", + "0xaa4d1b9cec62db549833000d51e83b930db21af1d37c250fdc15d97bc98de7a5af60dbf7268c8ec9c194d5d5ccda3c1d", + "0x87396fd7e78c4bcf270369c23bc533b7fb363ca50d67262937dab40c7f15bd8448a8ba42e93cf35fb8b22af76740d5e1", + "0xa958b2a9ffccbca13c0c408f41afcfc14d3c7a4d30ea496ce786927399baaf3514ff70970ef4b2a72740105b8a304509", + "0xa5963a9dd3fe5507e3453b3b8ed4b593a4d2ced75293aee21bfed7280283348d9e08bf8244c1fce459aa2470211d41ea", + "0x8b06ddc3359827558b2bb57caf78b3e5a319504f8047735fcc8ec0becf099c0104a60d4d86773e7b841eb5b6b3c0cc03", + "0x9437e7278283f6d4d1a53d976c3c2c85c5fe9b5aec7e29d54a5423e425b4be15400ed314f72e22e7c44ee4bacf0e681c", + "0xb56067ee26a485ed532c16ec622bb09135a36c29b0451949aa36fee0b0954d4bf012e30d7e3fc56e9f153616b19349bc", + "0xa5c72f7f5d9f5b35e789830a064a59c10175093a0ce17654da7048827d0b9709b443a947346b0e5d96b5ea89b8d7c575", + "0xa8318d01182d4c9af2847a29a6b947feef5795fc12e487a30001cc1ec482b48450c77af4837edfa1aedf69f0642c7e5e", + "0x82ea421c091552d3dafa7da161420cb5601b819e861dd2ba1a788c3d1b5e8fa75cc3f2b0db125dde8742eb45b335efa2", + "0x8679fd1c7771ea3b12006d4a972f4f2892e61f108107d4586f58ee7f2533d95d89b9695d369cdace665f19c6bc3bc85e", + "0xb5ab3e8adee4c950fce4d33a0e2f85d3d886e60a6e2f4454b57bc68725f0cf246372d863167482cce1ea10a7c67c3af2", + "0xa85696927075ec188979180326c689016a0dc7a2f14ae02ea27c39ef91418cd44177d3fca5752cf6b298fd75fa012e26", + "0xa44f87b7232f102cd092f86c952a88afb635484a984da90a41a57a3d883c9469064bf105b9026024090486b6c6baa939", + "0x866ac91a437db945bbfdc11fcee583f3669fa0a78a7cecf50fbfa6ed1026d63ad6125deba8291452bf0c04f2a50e5981", + "0xb780d5a1e278fd4eef6139982e093ceafea16cb71d930768dea07c9689369ff589d0c7f47d5821d75fe93b28c5f41575", + "0xb025d0046e643506e66642c2c6a5397a8117bbfe086cee4175ff8b7120e4f1e6794e1e3f6ec11390993cca26d207ae43", + "0xa04a22b6e28c959ab265c7f48cde42bb6a00832c6beb2595b5df2879080a9424890960417d7d7ceb013d697d0ebf7267", + "0x81de9c656ac27f54d60d0252e33aff4e9e9e9c3363a50740baf15a2b9061f730a51ae1704e8c4a626153cf66d47f19b1", + "0xa15fab90599df889df11fa60c752948b68fba54005491180dafb66c5775547976d0eef33945e55d4818653e0818c6f92", + "0xb06f9be44ddb103a72fa4ebc242c8ee1975fe9bf9ef7124afeda9967ff3db644dbf31440151b824869406851a90984a2", + "0x99abdfe6806ae5efa2d11577da17bd874d847c5f810460148bc045bcf38c4fd564917eacb6ed61bb9164ed58055cd684", + "0xac53231077f83f0ae5f25e52b70bb6105d561c0ba178040c11c3df8450c508ed5df34f067fdaacf716f90b4926f36df5", + "0x99e3f509af44fc8d4ebc693d3682db45fd282971659f142c1b9c61592573a008fc00502c6af296c59c2e3e43ed31ec7a", + "0x98f2f5819670aff9a344e1c401f9faf5db83f5c0953d3244cfa760762560e1c3a3c7692bb7107ea6eaf5247ac6fd7cc8", + "0xb5b9f90391cec935db8d2b142571650fcbb6f6eb65b89c9329e84b10bfa1c656026674d70280ade4ba87eeaf9333714d", + "0xb0696b77ca8a0cdbe86cad12f358880926906fb50e14f55b1afc1e08478ae6376215cbb79bc9035de2808c7cd2b13b85", + "0xa51d746833062a65fd458a48a390631d5d59e98e2230b80d8f852cfc57d77f05eefcfd3c395ade1e86d4a39c2141365c", + "0x812d67654319f4ef3c9e4a2d4f027a4cb7768f1ea3f5fdde8d1b79187a4b874ff9a5c70f15b7efa079c2dc69d1b9b1fe", + "0x968978b653c6416bf810f6c2ffa3d1abbefbd06f66b6686e9a4fdce3f869e0ab1e43cce14dc83786596761c100ae17e1", + "0x98e1e6ab562ca7743783b802faeb0a24f1341abfb9655f106920aef08964a3c0e8083e1acda7ae28fed7cdd5478decb6", + "0xa91c0b982a0a7085a103600edf99e9d0bee4c4e7db6d9f8f376c215c7d42476218462a3765f2928e12c3dd49d688e4fd", + "0x8a43395b3124fab9e2438635bf88952e8e3084dad7ecb3a9927f9af0e0887bce4707084043671fc98ad03621e40a149e", + "0xb0b37626143d4a8c6f5693d5f1fe871525b4dd946c4239cde032b91f60a4d7a930d7ba28959737550d71c4a870a3a3be", + "0xb01c74acae1715c19df08d5f4a10e0c19d1356264eb17938d97127bf57e09ced05ba30d0fc1a9f32d6cff8b0d5f91c9a", + "0xb4c2328eb8a5a673406faed8f0aebb8540d2791646e37ce46e0e382506570ca276eb6f8e166dbbf9e0a84064873473b9", + "0x85cb9f769a185e3538e4a4beda9a008694e1bf8dfeea9dc07c5c40a9ceb1d31fcb13cacfaa52849ba1894b5027cb8c30", + "0x8742f91cddc9a115ddc73982f980f750d82d3760f2d46ee4490d5b17c6c3bb57c7d4c7b8d6311b7b41e59464c009b6a5", + "0x948ef86d17128a061e1bdd3ea7fcc7348e3ec87ec35dc20a58dd757d5d18037fe5e052bb359e27ab4c2320d9a52a6a0b", + "0xa70f6a214097c271e0d2d95e30fce72d38c30a2f186271fdff0e38e005aff5baed53739b8c4f9501aa7f529c5cb2da59", + "0x892a7574cf6704ad75b346c95ae6f2668904f1218c35b89b07a0c2dbf3c62173c348f6fd9473926eef56a37c0f635c04", + "0x837e85a41f39b4ded1420aa8fc3be46a7adb99305e0928c6d7643b7c44434b72984cea08eb68f5f803661df0db78c87d", + "0x94e495329f2aab3eeb68f347961d1006e69d990095877a4dcc376546233adf29a14bf6b16a0c39aa477e15368e87014c", + "0x851860a8fdf76a97048396553262637dade27f1f63f926997e74c7c72b14b10293eae7824e8dedffad1aead57c124f79", + "0x90481017a250972055ab1cf45ff17d2469517f10f18c9d4ef79a9bdc97a49093289bbacfefa8a1e491bbb75388b34ac0", + "0x983db15f7463df28091c691608ca9c51095530fa6b1b7b5b099c612e673d29e16787cc9ae1c64370ba6560582ce623c0", + "0xa477dab41014c778a1b78a7ce5936b7b842124509424e3bfc02cc58878c841c45f9e04ccc58b4f2ff8231488fff0b627", + "0x868ebba1c85d1f2a3bf34c0ab18721ea725378b24f6b6785637ee4019e65d4850e051c8408fe94a995cc918c7b193089", + "0x93cbf4238a37ccd4c8654f01a96af809a7d5b81b9e1eab04be2f861d9d2470996fb67367e5bf9dcd602dc11a3e4cf185", + "0x83113f4e696030cca9fdc2efc96ba179cf26887c677f76cde13820940ad6891cb106bb5b436d6b0f8867f2fd03933f7d", + "0x90c709f4e3359a6d215d03f45ad5cf8067aedd4aab03512dd62229696485a41dcd64e2acce327fda390e0352152fce13", + "0x9945cfced107a36f3cf028ba04c653360afc5013858b9a12fac48802efcbc198c9baf3a7f9b23dfdd5036e88bc7274c8", + "0x832ae60192b47fc735a8ddeaf68314b16256c90ab68099f58e43073e249c6939895c544a02fa34e40805bc6b5db33461", + "0x8b12c335818b643c1d22cbc2869606cf64e7ae54a7713617fc4dd3b2f052ebd6b920ca59ba2e9c7aa8cf71bb4f40f9e8", + "0xa2033eb7a373931c65d66989644aa0892ac3778b9a811b2f413d8bf534e282c339717979f9aa742162abb3468c195f87", + "0xaba2b4c37dea36bed6d39323e5f628ab607699c66767f9bf24ef5df1bfcad00c2664123c0d8d5bd782f1e14a06f4c769", + "0xb71963777535b4d407286d08f6f55da8f50418486392a0018ee10f9ae007a377b8b8336f33386b0eb01c45695c3ed2da", + "0x88dc87826941340913b564a4f9b74985a311371c8e7b47881235d81c081f1682bef313c2f86561a038757fb7d6a1a8dc", + "0x869e13e3fcf91396750150f9dc9307460494c1d365f57893fd06fb8acf87ac7dddc24e4320d9cad0414119013ea739b8", + "0x92194e292303d32b91ae9cecb8d6367c8799c2d928b2e2846dab1b901371a4e522fc4089aad8f4ee676f0614ff8b19d7", + "0xaa589a3e512cb4f8589bc61e826a06d9f9cb9fdfd57cf5c8a5a63841435b0548e30a424ca3d9ef52bf82cc83c6cb1134", + "0x81802e0194bc351b9a5e7a0a47911d3a0a331b280cf1936c6cf86b839d3a4ab64e800a3fe80ea6c72c3751356005a38b", + "0x88e5e9e3c802314ddd21cb86f2014948b7618502a70321c1caf72401654e361aac6990a674239afa1f46698545614c93", + "0xabac1e0f85d5c3ff6d54ed94930c81716d0ac92be49e3d393bed858833f4796c2b80bf7c943e7110de7b2d148463bfbf", + "0xb7eb416004febd574aef281745464f93ef835fd65b77d460b6ad5d5a85a24b536b4dec800cfe80ae98489e54447e8bb6", + "0xb3fd8ed1c30e7c15b0bc0baf0d9d1ecad266bafb281cd4e37c55edc76c202fb1e4ea315a91a2848f40f481793ae35058", + "0x86ef674ddf4b7d303c68bbfb53db00b925ccbf11d7d775ca09e458f4ecd868ca828103e8e7cd9d99672a193e81b83923", + "0x95ef414e9f7e93f0aaaeb63cd84eb37fc059eb8b6eced2f01b24835b043b1afb3458069c45218da790c44de7246860c9", + "0x93ec8f84c20b7752bfc84bb88c11d5f76456136377272b9ac95d46c34fce6dcfc54c0e4f45186dd8df6e2f924f7726ab", + "0x95df5f3f677c03a238a76582d7cb22ed998b9f89aecf701475467616335c18e435283764fb733fb7099810fec35932ae", + "0x8cda640695c6bc1497d19b9edc5ff4ea94c1c135d86f573d744358758f6066c1458901f9367190dcd24432ae41684cf0", + "0xb19aedf5569435ff62019d71baa5e0a970c6d95fe4758081604f16b8e6120e6b557209cdea0ccd2efec6ff9e902d6ce6", + "0xb3041f21f07d52e6bd723068df610aa894dfdde88094897593e50c5694c23025e412ef87a9d16cadd1adbb1c6e89ced4", + "0xa7f8d6ab0a7beb4f8d1cfef6960ebdaa364239eca949b535607dee5caeff8e5dfc2a9cfb880cc4466780c696cff2c3a6", + "0x99a565b4796e2b990bfcb234772d93c5ffdbe10453b5aa94662272009a606ba6ea30cc0c3c26aa22982c1e90738418a5", + "0x90c54b55ff19157c1e679d8d4f7f0687a70a27d88f123179a973c62565adfcc9347cfe31f54539038cf2f34556c86870", + "0x8612f34bcd018d742202d77d7ce26cf9bc4e0d78e50ddf75250b9944583b2c6648f992b635ea13fdaae119764e7c28d5", + "0xa04fb38e5529bf9c76ec2b5e3a1ef3c6f9effb6246c7f67301cfed707356ba1bf774f2867c77a5805933f0c8ad0ec644", + "0xb4800e7b503da0164885d253135c3b989690794d145182572181995e6fa1989f3d0324993e871bbd5f48fadd869d8a18", + "0x9981cd4f28ae7b7dadf454fb3aec29746dc2e0ca3bd371b2a57cd2135a7d93559e02132528ccd2d305b639d7ac51613d", + "0xa3ceec012dd1fbad3ef9f9f1d6fe7618e13d4d59e3f50540d2a57010d651092979c75442ec8b38a1ab678505e30b710d", + "0x8b97b8654d067fb4319a6e4ee439fb8de0f22fd9db5569ba0935a02235cb4edd40a4740836c303ec2394c59a0b96308b", + "0xb3d1bf4410fec669a269622c3ce63282c9ac864620d7b46c9dfcec52d8e79b90c4c90a69c32763136a7f2d148493524e", + "0x93174eba1e03f879e44921084aa0ee3562e48c2be49085de96ed7621c768ff52324d14c8cc81f17d7ed50c38ffb2c964", + "0xaa2194cd0fb7aec3dac9a1bd8ea08be785926ed6812538be6d3c54218ea4b563646af1f5c5f95cb914f37edfae55137d", + "0x93f2c0dd59364f6061d3da189e04d6c64389a3563b062e8f969a982cd68cc55b4f38b21546c8a67c8df466ff4f61f9c5", + "0xaa7dd497cc949c10209c7010ba4ce8a1efd3cd806a849971e3e01716ea06a62e9d5e122ad1d2b8e5a535fae0a01a7761", + "0xad402424b2a32bca775a66aa087580d7a81f0867f293f1c35580b9e87ccc5a2bab00c29a50fd0d7bd711085ae2248965", + "0x96237843d8e29ac77fc6ebf4acc12946ad11697de8e5f152fe5776f2475b790226a7d156ac48968dd68b89512dc55943", + "0xa45c25cdbb9fc327cc49a1666988af9ab4c5f79cea751437d576793a01c3eeea4c962c05c0947852fe0e4c63e1c84771", + "0x93dcf834a614a6f5484cc4ba059e733ab5dcc54253229df65ff5ad57b447353ebbc930736a4c96322e264e65736948dc", + "0xb9a94f82a82c0c5a26f2c1d5381afec3645e8ee04c947dc3b7ad59a73018db1e9965ab3642f2bbf60f32c430b074fb22", + "0x94eab29b3524ccbe0c4b928e5fa5dd8f684074b332fcf301c634d11083653ffee4f7e92ddbcb87ed038024954ad1747b", + "0xb8dca5f679931d6abef0674bad0639aefad64c2b80572d646aaab17adf5ca1ab2ebeecd5a526cadc230bec92ed933fc2", + "0x944d394958e539251b475c4304f103a09f62448b7d8a8eaef2f58e7de4f6e2e657d58d5b38e8513474115f323f6ec601", + "0x8a5ae1f13d433962d05df79d049b28e63fe72688fc3e6660aa28e0876a860c3dbc5fc889d79f5c4dec4b3a34cdf89277", + "0xafa5278724998eced338bb5932ecf1043d2be5dd93f4d231d05d2ea05b4455f2ffdc0eadcb335dcace96dd8b2b4926fb", + "0xb91153a2f4647ae82fc4ee7396d2ca23270ec7f8884ce9eead7e9376270678edd42dd3d4d6c003dfc2dde9fd88cc6e7c", + "0xadc932f1c679bf7889cb1ff4a2d2897d7973483fa283979a0ea3640c80ed106ea0934c1961dd42d74b22504be49851f2", + "0xa82e90761fae684d1415cee0649bb031bcb325ae0b28f128ab8e3650bccedd302a70de1a341ca8decfdda76f3349cad0", + "0x8ae353188b4b98835f4ef0333cccb9e29e1ac3ec11d554bc96f5880c101cb3c84b8eefe72f2287b0812735339fe66cfa", + "0xb8b41135bb1a1ffb64afbd83e2189e755f2c350e1273cf47c38ae9b8c4800d831436a69458b8ef9fa8b95a148d8ec9fd", + "0x96f75a04d8752fa93dc1eaf85ad333cff4eeec902a345576139e16de3a88eeb71b6726224349bb9844065cc454d959e9", + "0xab82b05e3923ad4c26f5727c60dc0d23063c03f5a4fd8077da66aa87042cad1bd99586d4ab35aa5e4ce6f4da6fecf3c1", + "0xa50c83db91c26ef7bf1720d8815b41bd056b49fd99710943679a162ccf46097a7a24585750ece886e38eb4fdb866fa37", + "0xa719f667914a84f62350dcc6f4f30b9ab428eac6837b70318c3ac491c1e69d48af5e1656c021818f377d911fe947c113", + "0xa148807aafddfa0a5624c7cb9e42468219e4bdb9994ec36bc19b6e6d7c4a54d3a0763d13ca80624af48bbd96d73afca5", + "0xaa012f205daf22a03e9fb13a63783dda7666f788a237232598d02a4d4becec7a699ab493f78d722ce68519262924c708", + "0x97fc15fab5952c5a2d698fd6f7ad48aff1c8aa589f7d3b14285fea5e858c471cf72f09a892e814104fa2b27eb9771e73", + "0x8da8840236812667c4c51c8fc8ab96d20dae8e2025290b9cde0147570a03384370b0fcbe20339c6aff09cca5d63e726f", + "0xb477d85359a8e423fed73409f61417a806cb89c9a401967622aba32bf85b569e82bca1b3394c79e180114a0d60b97316", + "0xb3d6ee2ed1e4c5cf8ba2c3a4f329832e41c7fdcbcda8a3fcbe8f60967fdb1717665610b7c1ac65582534d269d762aa09", + "0xa0b3b30b1b830b8331ee19f96b4a4321a6b93a3395b95d3a895682c65ec6ea64774b878b93514eaf353f2e4be28617b8", + "0xa2b88e9617f4d30ef4e686d1932ad43cd555fadcb5102e51bea19e6fca649284ccf4debb37b5cb2090ef386fa5bf5327", + "0x8a4446f7e8463ea977a68d6217a9046ad4356d6fc1c18d46c5d2ab681ea977b8faff136d65abea6bbf8936369cb33117", + "0x91e7464bc56e03f436228104939ddd50caace5a38f68817bb2991e193b57adf6835152bbf3dbcdebf0382ac9823f60c9", + "0x961a441e6cdf8106c4f45e5b47190d35644faec701c9cfc41ced40cfdd1fa83752fd56c1ac49131a47f1970a8f825904", + "0x94b7b165cc71c2ae82976b8f03c035fb70e90028992b853aa902c0467b384c7bcf01d56166bec5def4453e4d0c907e52", + "0xa5d32cffabbf547f900026b34ef46f08075b7a244565f615370d2f04edf50b094c95088a4a139ce07caf55bcd99afa07", + "0xb4e06e73660745f75ab2f34d9f6d2675b58f80f911ab6dd4c5a6ce1095f9a2b50d86f6ff9a05394190bdf96af0827920", + "0xad3fd8f83c0103b29d41319209dffca201d2b98094362da08da3fd6ff0ba96796b49d6bed525c9adb96c2954858e7f48", + "0xb0c27430695f0fd20ae31e1ec621da090094f2203e17411db9384695ffcf5c7c6badf461ba49ba70164aacebd6f278ee", + "0xb9bc6e972fc3b532fd2b1eeafc4bceb77604885f32132af6a9a842fa2440df452f49ec0cd9d86da1180e8deb0723b260", + "0x9729e22d6104b0174c136a854920f542b384d375040adcebe36acc253bdb55845eb43e34dc5a7cc27d22c417973c24d0", + "0xa8b420b36d48786c9231d454468a6e855dd7f71dcfd095efc9855ee70dbece0f06ad277f7829c5813fc30524c3e40308", + "0x8757dff5499668c93fc5d9cea0a8db61817b8ed407200d623030b5849a913d12f8371b667cfde8d8082026eda7407e8c", + "0xb859ad747ca5af661fbd03a1a282df6e84c224ecea645bc2d4ba5e35fa06cbf047387319fca0cbc76b712398c0798968", + "0x8e3173c27875f1460297af0fa736c945dc842ec3e476a973d3d5f790bf183ad3ffe96ac13868c5101d8e299890791864", + "0xa9d725e2b92c878be42b5eecc2c3081c63c7231ccc7e2dee17ca6a4caaeae22788fab1f1465fcbd7fc236613fc2bae4c", + "0x86f6c4f04a354cb2470ef91914816fd740f8d5795ce7ff981f55a2634695fde5951bbae7a4bbc4c63747040f8644170a", + "0x851773cb26f320f0c3f252d95ea7e058ffcc795dd0dc35e459aa1b6b448238909230d809e82022e64b7fca5d40b8324c", + "0x8962641e0306220d9892fe2d452caa286301a3c465185757be7bce2d9b2c9beb3040280099606cc86773e43941fd3439", + "0x8beb6e08c440b0de5fb85251d39d9e72db4e556a2dfe3dae59efd8b359d08492064cebd8d8993254b43bde8bd67d969a", + "0xa7e047894466ffe3dec4ab8d5462f2b1d8ac0df006b1d2dd26caf499ea857d93a811cf42233f9e948c9cb903beec004c", + "0x92eedd95557a91691a5e2835170390ce2401e223da43b78615a804c49566f9d31cbb7f10c8a8390c4bdcf691544fdba9", + "0xa5e5b5d8fa65824e958bbae98d146b4b332f97ed50e0bc2c58851dc2c174ab71bcbb1ae015cd2955c26b368487dd862f", + "0x853a494eafb308175629d581ed04bed71bbc3af9ca4c0dc483d03d27c993a2bbd88cea47c2085a6928d166fe6938fb77", + "0x83f06b88d29afbfbe8f61811690322ac4fdd6abb9a23612162e7a2dd6bcbb5f14cee298ebebc1a382484f7346dc51e60", + "0x8c9cf05735ea5a0e563490bdc7ed29a4426643711c651e35c8551ca6f855c8458ae8f0933a022d0bb9a952edfed411f6", + "0xb906b48d807748a26cc2a8848455a76ce502261afe31f61777b71917bdf7de2fece419db636439478c7582058f626c29", + "0x97efe1fa7c9b25d8bea79d74b6cdcf88f63f1e865f54b58512a2e60428630b0b40b8b6af1b5f71df47520507548c3cad", + "0x8ef5ca6e753818906bb3fc71405928d8e4108854ef0ef01c1009071b353bc2852e771fcb619d5fea45590e8f61003d7f", + "0x8e4d901661e2913740d70ba4d0745df5e8c9c0a260149d9362beadc7e669630ba909ff0e8a6cc85c54d6b7435d0d351e", + "0xb7c6ba3bebbd9592967954e3a480ee8df1d9f5965f04e7d78a5415b645128deae7ddaf6ed507c8877bfca91ce078e529", + "0x840bedb0ad4e25acf6cd25dee4f98fea495b2312dc5cb7a8388c5ab00b2acb9cd25da08e9fbead145a3107972b1ccd5d", + "0xa8d4578dbafdb27f3911af59962d89e75dea74db55346720357790da677312c203107d9c7911535aa563446fde7d4c47", + "0x86d3b77f231bfa09251b7fd2ce09c27ac520ec35d783e912476f9a4863f83d269eb175790d6e735da9260293d707f8ee", + "0xb34909f1cc033232652da0c34051a769dc76adb1aee00674a59dc1b860f6e610974c3b4bb69a69ccc73e01f042431242", + "0x90799854d0cf34e1d91ff8e101bc7c5007423d34d2f3bd9adea2ecac57e83f3a65a506bb93d4caea49b29f6d18149957", + "0x8ef94cde29b037e19a1ce7bf4418ad3c95cd9457412796ea385750c19a6690f13a3bb5bb6a9ee81e7a40face1e0a8bca", + "0x97053d21ae8d75972fb37f6fe516c38c32ab162fb56b9f510f954858f4e3ef6ac8c3a9557ed3f41b7b6aef05fe97f931", + "0x90a9f9f0f40991f3bddc58b92d40382147db22cce50d092d4a05aad251b46b94e71ec9f7107a180243288059fcc5ce29", + "0xa14265b1344ac2921b0f890d13bcfc432e4f648ce403e261fce4d3bb32ffee9e2794c02830346054f998e82784c77040", + "0x91928402ae121e56a3e64cd6f390127e6e92fbfb1967ec6efa4f52f3e8058f1f41a0f4fe96b5bcc11641c1139e790b2b", + "0x921c8c92b6d40da6c5a7b592acc74fc0f577d93767b9aa4a1cd302a72dbf503a1ea5b2c29fa0d0359bff3b8f252246d1", + "0x93ae0ebe0e8e133fd80cf67a499047e30ec4c4660ccec9d49098717ef57721a030f423e00c5e74af4ff4acf014a10497", + "0x82c865e21905aebfe0496af1c6ac7e342b5f446a9edb4f7da0f2fb0340abfd8e6fc545da874459d9aabe6bce0dd9bfcb", + "0xaee3961d8d2687c0f134b9c28b920bdc4021d925fbe14323c84224a9fe161248789249fb85436a5891d0bbff42c2a3e9", + "0x91aee420b98b6949482b8ff4be996b97245b4e8f583a6e085226539074f42aa89818395efd1a6699735a569bfe19d623", + "0xa48eec22c192e495b01722d0016a54acc45ff837e2a95c4294ce81d5a4e43e0053a6f0ead8a4fb3ddd35faf6607275b0", + "0xa26e15937c11faa30ffa64817f035e294cab0e839f73d29de8a244ad039be4e221eb47ea08d9a4658b0152fc3caf6110", + "0xb84450f948aa7c8682fccb9cae84d8e3558adf2d0ca5fb81eb200415291158720f8f3470542ab5b88c6873ad08e7fa9a", + "0xa8e8ec27d0608d020169a85d6ecdb40eb402f006a3b97afe32cc01987721b3a68a92ec693aeb4d357e189e05fadf699e", + "0xac87cd535ef5699312cc26f86adb71baa0be42e858bd5a2d94ac05737dac63430691e29b9a30d2559ad581a172519b2c", + "0xa4481e67b524f8cddf2046625efd3d75efee6aab87ddd2c1b22835647e918157e5e924ac760db2195c86d326f3db1615", + "0x891f29ded231486ee826840c8895cb325f7e84a5a6d2eac246cb3573612cde274720233b1978318a57ed337a046330a6", + "0x906b6e750e6178289012769807d2598925d7e51c260c14497d8af978b1695990e3352e6e809a752f376597a68083870c", + "0xb7a056898ee1e46f7f29702fb39232f678ec173eccd170303b3b0a30c8d8cf1a5321384e3513e3b03bb742c238deaa54", + "0x8f2f035fd96c3a336354c89ec9b8222803bf42e95fb2412c28d4e75eec99c1d4d402501ccae17357b757db8bdb0bfeab", + "0x81228625ffcedf977fba9cfa13f6edead3985e2651d5974789c394a69401cd7face9e20ae6694be4c0d4bab5e99c61a8", + "0x885a83eae25e61439ad809567a2ab148583402e01cfdd77b0e37ab4038935425c64b4e0886949bf06438c35e80aa13f4", + "0x8926387f48752f6933899c48e038cf14e7941ec6a58bcc0a436614b396296a17aa53e6873803dd3041dae470bd493fcb", + "0x95d0d3fa061f4d856eca78a569aa132db14cede7646f97e2aceb6da0c8ea53195d3b7a566fe5ec8c41b95ecdd89a1c6b", + "0xa3c817f4062ed6aa94064ea695d76c1825f3bf77b310fe1db28b8bedc9aaacbf1019dbd128adfd53042fb943d863a2b7", + "0xaf1208417aa584052da309169854149ede38a3ad63c76cad6e43afb6f1a7b854edf8310a0b00088c039259cedf0f859b", + "0x8b713fc3196bad35dbf364089049ada5477e540d78d76a5f0a9df98f7ba4a0e65dd0644509c149f9b07887298bf74b04", + "0x89c09c43c5b733c4a417cd9ebc0795cc3348b72778d31828a9171427779a82ef023c1a4fcfcdc919ae25056f9c826fde", + "0xa0759c850ed320c8c874435e90ace6edfb8e7b3f2a09d942b8ad8339c508044ee2ee26c70f1b626ec49a77971433b6a8", + "0xb85cbc58d4fd52286e714ac4eaaa0b2743a1de06fa03ddf8f6668ec6f1d204acccce93b10620272afb8c0b49bc4b0a43", + "0x814e0a87384e159892a8d23036985fa3f489c53bce192e107bd2d64f57b1bf5ea0acc1ef46c7a42bbc5cd0924d92b4a0", + "0xaa6821da96ad89d7881b878e141076522f104ea9a5bbdd1fce9f641898f7d6232c518a87a0f666871d7e3165c26081e4", + "0xa9041d714bfc067b5427252186fa3557bad598fc0067dc8521aa9bc1ae298f6e96113db5ac9f6bade9a85d5a950c9755", + "0xb8669340f3064692625e1bf682d34fbe69a61689e3aa6d6a3e822c781d406b0300dba9c3f7b8152a8c2513f1310d4291", + "0xa78c53316ce768a1dc5968030bf4fc885f4029b1ddb6a5d84a61c85af686c73727f62823891edfcb6ccf4545de366cff", + "0xad1d3aa29ea28292ddd438c865e2b5d93f32cdf009e6d5f5dc726de996583925727e6348bf1c28c22dec0bd86aaf867f", + "0xae1447a2062e9e28af5f38aecc60fe150cd10c2edeaf2110034aa144f6235ed7fbce432a58805d4fe1f6b12652d6e1cd", + "0xa32146634332d3303934550705353c6d4fae5fa5985105bba35041e74cd71e2aad67b45da171221f6ed80f36bf6dffa3", + "0xa232e8286184196ea77427b53d8b52c44d758ecc42d22556529db3136379b4989dec61cff610cc6cf6700a450a847a94", + "0x8a72c7255125a736da52dff5f77e44c3de29f88fc05f5ff9227c69df296930caaa11446595e6bea3bd946baac5ef957c", + "0x9688a981a9457678067f629f8efa6b522e7318b529f88d37ef56c5bf8f1c34fb9bb3a918ab73caab82bf5abb0c03518b", + "0x88286f3eabd71115fc3b17a6bf6981340a81cf7e5f96b0a1a016d4ec8c18fb486d46c70919123d0c189a6f5d6ff29a1e", + "0xb535e701b40d793c02ac0d625ca91620d3f4a512aa9741f71389e58381008b2f93d597586d06213c4e103d67d0ddf6c5", + "0x80d0c9dd941e8d8d3700cc51a434a5aaa3308cf8ebfd14128ccfd258f826b27cc3cf5c3ad7851340393abb1eeab3a157", + "0x87049225fa2380d93f18d3d90cb0697a56b373b66d7f24ab209966aed8b55a2790194d5885399db29dd5b1f189eda64f", + "0xa52df158ce8670e0290551e8878d63dd33b4759d6f50e448e63fc7fe6ea99dddb6f180be5fc0fc3918ce54c05f80b356", + "0x8b2a728b39c465fb0f60b0c486e5dc8d5845ccec03d3dd93b393cedeeb3fe1b44518359f1ed55fc770a8f74bfeb9923d", + "0x91fc05419dba718fa4a910dcf256ebea356bbea00522d8d5ec3e7ba4271a26035aac15e8d9f707969df1d655d92dac55", + "0x97c8779ae80c24c1f82d5a714762d6ee81069224e39515e41d8a71c9310dc5d1c55cc92bc5c6a4bd391ae4c321d1d4d2", + "0xb5e5aedba378c4484e3a7a4ed41b75b0844f674261c2501497de6f91f7274b5a4c1be0e055f2e0c0cab843d891169fbf", + "0x8a26212f27211b295beea500abc8e9d430a8500d3a350cc62f895d39e8b4668aa638c17633804ba353010000165637ae", + "0x864a95118e5d394e00e99efebd505df0125525c9ebe165764c453b80ad3edc730feebde3d93850745dfd88a27bb8f20b", + "0xa092e0b78290e826cc1ae56afffdd08f7c10954f549a3ea6666f3db1b6cdaeb7df53db28dd2a92446342930fe60a27ce", + "0xa1720224c0626a081b6c637b2a6d37da85d9a82241e5efef3bc15699b02a69f6304e43d8ff3144d60c16e00225d6b39e", + "0xa7b3d098cebea9cf32e19c5195608182b6afe9d4af6b9df532c047eb7a941a971279b2ae6a4b80f2f9d9313a6d788ce3", + "0xa3d2451e6788944802c5077a778d7b7299dbb9d1612676bb6baae78f39976e0fd879493cc4a4d737b8174b472a456850", + "0x930121b73da844571b1411d56760e80923a4ee09917b3e9cff4d3dcb0bc27026ff2c4e2c44e7aca7d3f8383f129c7f9b", + "0xb4b0119d163ee00a2b74bdf188a5cdcf054daaa48c483b94bbb4d09ff615afb4a91347db6363bc7535e2af9054ec2214", + "0xa5846decee706780201095a8cdd48fbf3d3a2eac8d089a818e5e22c29457494bbfb4399323b067f3d2be2197c33dbd98", + "0x96ba600df10ee7af5a9df29c0ca31dbed275d647faf9c66c7342de927ceb25b5bdd852dd7aae0228b27897f90fdd5d62", + "0xb6ac51ddc98edd9fb9f54ef84bf372a041d58dfdf0dfdbdc4b08ddc1a7ba93ddbb1413dda3c1545a3fd7386c6b85975c", + "0xb35f3efd91a0723e0d486188ea9675a3462106470455118392d7610470b623caca2fa33829721c05fbeb0fabcf570bfc", + "0x87f49e85df5f8055714a8ce7adf37f6a278e64e76ed74c60abe3edfc3611ef5b0426d4c6da45e5f3b74d30be1dc6f539", + "0x8ff8bb06902a71b1e9177a77367318b2e3e0a88f5d74d6907ca9943f4f9f1ceb5f297132c2a025259d17a67e880d1bad", + "0x85eb6de6c70fe5c53ab0ab27aa0fec439f136c979c557d317337cafa6e6c5cb3169679c9169567dec5f6c72b3c057d83", + "0xac18715ed1080771d760cb7066c6328faf65d9b30517903f8a5cad8d66d5c6381156b521107d7cd75ebb8c30e250706c", + "0xb95b9eae4703727e4ac9ddf2ae675906487bb78905a5f9cba74a4cbfd118d96b7afb6ef3ed5edf14fd963b830d71338c", + "0xa3b47b52fda16b62b11c8aa4daa56b0b669c4d5c56a3059b7d063284d8a91f6fff9ccccab23d6ceb9650483b2d353039", + "0x96a95b3f327df94c85e92f2e406f1649ac621533c256b062738f3c3ee137059a735a3e6072247acf57b1b0d8c219bd7f", + "0xb19b33cc04570be94eae8e943d5bb17bb0c96e9de4ca84f9f41b37320a1a03d397d53747dc13275fef1b356de557214f", + "0xa1faa3dcb931dd91507f3f12a17c43f6627fa2bc5c71fbdd27548e091eaaaba262477949cd51290e81196bffb954a492", + "0xb060a16079dca1d28a1fb33cbc26f368630ee042d980ce305230005d5b9ab533a7a695281ab76e9214458303932d8bbc", + "0xb303783196a858fe45d67e0520c30576da605fd69964449c20009fbd5099cf1de52a32d326d7c3b864de07440195ef40", + "0xaa550a4c20d1003d137ffd8fbdc1196d09ad53cfa0e202302093a80fa3bbc4c9aff83f34f2151785cc1ce5f30255693b", + "0xa7f8585f45566a351058e10c6f1ff4a7ba24811f1482a47202f581525615ca770da93f2f58878788b45b92cb446ef4ec", + "0x8206f63a9a5b59bd68e64a843e68fcdf706f4c13bbfcdfa9928298e5b9251006ae0bbd80c715aa3c9957d2c0148b5059", + "0xac9490abe1241319658f1c2c645cfa01296f5d4106020c7894b7ba4a65cdd52f6c5401bd3b3cf1c9863e088cd8c9a16f", + "0x85dd6d9c80a1b58c24c4d2cb7590d33d2454f381f58e820979948e5831972360cde67bbd56e1860077ef5192fcacb904", + "0x8b0285944c676fe2519cb68da0973275fa29c0718d838d363ce46651b068d29f867cf9fe579ff8da0bb8b37d202bb23c", + "0x95147275da658d43a758b203b9ca1f1c1478853e9bf77b5218593142e2bd9c0bf46d2206ab64cef99295de6e9a268edc", + "0xb8efa187fdd3e1f46c15cd596e9567690c10e253b5beaa5be8074b6ea4e6d3d06e0f2b05323453239e419ae1e7128521", + "0x8340464f52c92e31806fd3e8e65f56e27194d1f6daa4a0f0b3831e8102aba16f88bb5a621633ddb7dd0342e1d2d12343", + "0x8615d87dcab85a78dc052f05a01e751176b756b5dc9985014347454ce5752f459dd6464e1c5aff36cb6c51b783fa2692", + "0x80c6e35c0d3defbe4d3968792724a23f0b8830dd2fac58663583a49339ea20f1812cc4140e3ee867c7e716177319bbbe", + "0xa7aa63dbfc201dde8f29bb6e23d7aa5020dd35bd18a0cc93c8a10c35d695913fe25b9e8cf9b5fd1899e9657b22bc8863", + "0x97c2a4ba80c4caba2e729a603d2faa0120915e3fe64cbb065f7ff33de5f877f1ec9461cf455e88ec9e9ded9393939dba", + "0xa54bd1419f0e2d2d87757870f37c476c7e3a13502f1ada82fd7394fd29f8a00c4986473d753034d0954a2550badbac0b", + "0x8d3e2bf900d0d2b9b46e6e2f37620f0cc90526dbbcfaad4e4a37ed53f39fdd23bd3a6f21aa7e800eaec937d9710dd6e3", + "0xa88d2b1c7802b2dc216c2b6532406c091bfb12f29121b9a82c1154470e250188413ddd3e79f7e009ea987a4c45b332e5", + "0x8c552c2101dfdc3f99c2da436115452e4d364eefe029b12946f05673c5ce1cfb48d39a579625849236dc6c8e7277dd30", + "0x8415c252d52a26a6400c3189c928a98559bf24162ecf3eef1d10e439269c31d854b0b4f6ec7a2430e3f11b5d77de78d6", + "0x8b38905bad93a8d42339dbdb5e510003c51fcaf05e04f88fd7083753353bc1c4c00a5dd4a67431cd4456d0669c7040e2", + "0xb1d0ed8862250d0f0d9ef9dcf0cd16d84313d1a795dc0c08e0b150dadf9ce73d32d735e04632b289cafa69a6ee75dc89", + "0x9434e18a5fb631b10edb02057f2d1fe16000ee55ada3c26a079c9fc3943e29d6de99e52829fe7b333e962270c712e51e", + "0xb1b9f3914007e6fca8ad3e7e848a1108988cb2318da36df24767d804e95d1272943fda948451135cc1b5052a3953b081", + "0x8c02947a76d7b6c0a700a83dfb971dc105bfe996e18c521445f036310914b349ab28e57571e36ae08d13a46fb01c2f43", + "0x893472fbc225f973a0ac6a0a0130b9cfb7ab6869dff80df71a62b1f6beb4afd069bbf35b4f327165bc31dff39e4fcaa4", + "0xa7c176c0903175f3540d62f9afee994d5d9bf37081e094644b22f017e94c515afefde7bb07f638342abef7de657f8848", + "0x860186c2b1d3b1e657729bc804275fb5f5ee89eaa60848fcabd3871289665ea9f0efc8a95792d884972bcfa2de96223b", + "0x865b38aea6386d0ac8f501a7d934e23d01dc50105324e354d4c4fa3cb1d4c29c26f4566df7b1a728e10cfaa9d24552e6", + "0xb4eea5548de6969dada658df604b5d9c49002e2258352838003e0fdf7b299d81fb025807a7f37cf5b547cebd7f2c1f93", + "0x8982de11ba68d63a649a3b296d4d56c71e3c3eec016db250d733ab7c3b9a620c09c5a5d0b64fd30d3bc03037ca4b17c9", + "0x84d8b8a10d67eda4716673167c360fc9b95717cf36ef1d5bc6f2ef5b9d2624f0e76c2a704d016adf03e775ea8e28d83a", + "0x834d03ebd51aff4d777714783e750b84c16cb6627f8311bd8ff17c3b97fc4a5bba57d6c8f6d74f195d3030bcb5f07612", + "0xaaf49e0def0c4d5f2c1e9c17b51e931d2f754b19e80070954980b6c160178349f6d3c8d4808801d362e77f41a0008918", + "0x8ef4115edec841854e89f2bbd11498dac7396bca35dda554290d3db1c459ffc17be671f4a46d29fa78cbd6064cc2da20", + "0x9641dc8a64f4acd38e343a3062787c48c312f1382f7e310ccea3e95e066ab6dc980f6ed90a633236a435e68bf6b3c625", + "0x8a84cfc2cbeb18a11dd6c2a0aebb3f6fd58a33bb4b26101e826add03748595022e816afac79a4e7c20b3805252839dca", + "0x9770782d729017659844421e1639ffcda66a2044df9e19769b90292df87dcb146b20c6b9141bb2302029d84a5310665d", + "0x98c7ec9696454868ac52799d1c098c15ec4e08b34884dda186ebfe87d32840b81fd3282295df141c91137faf4cc02da8", + "0xa3f6eb921247617292162dfc8eec5b830ddc294a0fb92f5b4828a541091ffdaff34c392c1d7168259d6204405d90ec72", + "0xb185f77a468f07a54222d968a95635234e74fc942485604909308a9028ed2753b15902b9134749f381f7cd6b89cc8c3d", + "0x867608a682d53bd691dbc92eeb460d1c300b362ca49c11a280f6768ccec217f1145f9d59fe50d994f715ce89d38a74e1", + "0xafaad630ad8827cd71aade80edf3d7aeb65a344878db12fa848759e6233f6fceca563aa437e506ea9e0f1e47b126d45b", + "0xa12afbc84e3441594aecf85d089423dd3bb8bb33a1a384ddf7cc14caa72284caaa56aa179c15e3140fd56bb532491a67", + "0x98757b0b5e5837ddc156a4a01ce78f33bb1fce51e0c1254ee9b6d3942268d0feb50b93edbf6aa88f9ea7b3c0309830d8", + "0x89573f4a4ae752e9f964e42bec77d28a41840c28e4bcdf86a98a131d0b85367b885077823a6f916972de6ac110821bd2", + "0xa17f2745052de5de9c059307308fc49f56cb5230e7a41cb7e14a61c9efa742ee14c41023ce90c7f2261adc71e31045f8", + "0x914b07c53a41c0d480083f41a61c10429ea42dafea9a0db93862d2269ff69c41db8b110b4768687b88089b5e095523cf", + "0xb380cc3e0d26370976fe891d24ea4eeb1b6be8cfce01f47fd68838a27190e644fd57b049d3aa0a9589370de20e276944", + "0x906385fdfad60feec79eb1c303e750c659ceb22d9c16a95faaae093daadd53e7aa039a45d57e20951d6e1ca0dc899ef2", + "0xb5211ceee31b194dba60b616bfd91536e71b9213a3aaaf5aaf9b2f4cbdeb05191861d78b97eec58e3c81abe4f0488c04", + "0x97878e9e38c2f69d697800e7a2f132fc4babaacf471c79c26a757f771606e55fe696ece68a3163a0ffeb2f72274cf214", + "0x959431c1f54c46500c05aaa9a2bc4230531dad97ae768fa92bb85436c0ecc6374cf20fb0ef82d122db116820a943b401", + "0xb69e5a1c6798f30d33e42cb8d124f025d2c77c993c4c7107a539aacddf44d8d4d2239e802ece32e60ee4dbfdce201bdb", + "0xa8b09e5e9f802ad273b2efa02bcbc3d4a65ac68510510b9400a08d75b47b31c6f61ffdb3704abf535a3d6d9362fc6244", + "0xa41ace7f1efa930564544af9aa7d42a9f50f8ba834badcaf64b0801aaed0f1616b295284e74ca00c29a1e10c3de68996", + "0xa8f2aa0bbbc19420a7c7cec3e8d4229129b4eb08fff814d959300cd7a017ddb6548c9a6efebad567d5a6fde679a6ac6a", + "0x9683da74490a2161252d671d0bc16eb07110f7af171a1080dc4d9e4684854336a44c022efe3074eb29958ae8a1a14ace", + "0x8ef44d78d10795050c161b36afa9ab2f2f004ccf50fdeef42fe9cdc72ebb15a09389ca72a00001cd6d9b1d7b3bb766c3", + "0xadca54f3b14fb18298098970b0267301b7312afb75894deea1b2afa3e85b7a3b4efac9971ab54c5cbecba2da9f18507e", + "0xac5d4528f06fdccfc1370d5c3d03ed982fed0861a93a3f6453aa64e99360b124926d1892faaf72d89459e663721dfa99", + "0x98aa1c801bd615b8cba728fa993021e181e0ad717ba01c0290e7355694155407083eb53cb70819c4775da39d33224db7", + "0x8b3aea4c7c2bfe1020de3261ec085d79c7bf8a7903b825d2c70ebbb84af197bcc54e3653c5373a2045c3021526b63b66", + "0xa29f3de4cb3d99afff1daf7d431b38a33a9804fedc41626618928ed059df6f6fe9f298a046b594ffee951ed4d4e1400f", + "0x803fd346be540c5242667c18ee41b26bc812456ab13ff117196ed69b90ee608c8cb6554396b64066a546ec87a71ed6a9", + "0xa9c18d81ffd029c0339c72c499bb51685392253b996b6eabd8b76f05c6191ed8444a1397d63b9923743661a319517f7e", + "0xa048d5c390d08f07161faac71c5994baf152c883b205f3bb10d3501709d6516ae54d491b486303a11b751857a31f0052", + "0x9156fb4803e40e28d8d57d928481a8de4373687288da44fe88c5676a8ae013ed1fcc09d56a31140bf74e7f767253810e", + "0x98e289c725b18e0085afdfaf2acbc674dae7b0a2ecc2537a7d0b87e20eb785404ab05973a787f0495d2adb3e5565c09b", + "0x8a7237b249325bd67cdc1f9fb278710069033c304afbf270b7ea24dbc10c8eabe559a484d3edc733c77b4384932deb41", + "0x9056f2e5b02e5c2e04a69fa1323bbf1859d143761268d18e74632e43800a2a9c76fd681e924a19bc141de0e128d3e462", + "0xb9f2bf9e4e7263014296a82b9ecbb05d3f1efa4b2e675e3b38d3eace59da06a89c859256e1b77847886d6aa15f98f649", + "0x83b22949cca19030289bbf7cd2a0d8b84e1d468e78bc85271a6753241b89122627632723bc293cf904a5eb2b5dc6c3ae", + "0xa919aaf35dd0116168d2ee845122026416bec9633df113fbd913d8db5996221e234f98470d029a8ff182825b59fda20a", + "0x91726901f49d32b41afa15219073842278f60dcee223640903d871e318a1c2b541136b7b38a7b2ab7d31e4242fc29674", + "0x942b77666545bc9a858d36cfe857ab1a787c9528f4a0b87918a06bf510793264dcafd12ae6bd3ee300179dab7f40aed0", + "0x80adc1f2f9c47a96d416e44fcba41628abc0fae1f88f6a26aea4648419ab726f7fcc2187c7d5145e3d8f5a75c03937f4", + "0x8041e0f66ba9dcee01e336dd4d16ae5e4e1618512fc147cc8230003aa2940848162dc2187d4130bf550dc1f3559849d4", + "0x999e8adc51bab54386af1c5e8822986ad1b7ecaf1f8a4c2baa5bb2fe9d10710e49545c5a8bd89ed0e61a3d73a908e5ef", + "0x89272ffd39b6e9f99fafdd58bd9dc00f66f26a1d36b38a1ac6215e3546d966739eecda7fc236335479207cef95cce484", + "0xb8e0b7532af13f15dc04a0eb4ea8abd67e58f1b1c6ad2e70c0ffa04a5c18ec2018b5d7f4be2f9f86db5e0b3986f639d9", + "0xb96bd11b0f6ead4abd5fe1e4c6e995da7583b901afd01cc05e87d04663fb997997d6d39dd9fb067c62cb1b1cbb67516f", + "0x94ab08914088b973e8dbd5685decb95f3bf9e7e4700d50a05dbf5aaac9aea4be2c10c83096c02252e9238ceea1351d05", + "0xa188de419b062af21275d976494c131ba18d2b2ead8bdbfa38a777832448e64d4d9725c6a1d530ffb6513f18d5b68d9d", + "0x8f73c8c118fa25c76a4ec5611351953c491452743056a819c8c82ba4737a37d88da0b55f837e7239a5f46d2c05a1bbba", + "0x894a44769e0be1c26648b0d89c4c9f46dbdeb3a71b90c493093bee372bb9f2d3f319850fd886d51f4f58db0de5641742", + "0x87d239923b0db024a8d9b0281111d47b0761d81c50652268b074efa3ea70d793e30f874a91ce33a4acecd0cf38c01951", + "0xb1b48b75a97f9fc2dc9530dc69f6268829dd0ddd574516e7eb1b9f5c3a90058889a7bcf3d378738e6d4b02f5fbfa44db", + "0x83e3ee9526ffcb60c6e75b75550fc017912ec0daf96d0a0d5f58c1b229cce90c684ac7c3e17fb998def8e7e2e155d750", + "0xb9b7bba579e474b0abdc7775ff5f84c9f117c6ca17788cf5a5f01b2c35a14aa39036031c8d799fec2cfb371d9f7471fd", + "0x90d7faf4891fbc368a32f575dfb69f13e37161ab4f63a7139be103285a49490c2851a907f8d36e09e7d1a190dddbc6cd", + "0x968c8b9affe18fc34a4e21f0d8c5518341c566099e6b45b8721c9912bab3693c9cc343406fe90279692a1eef2a3f7311", + "0x8735baaf4704207550f77df73fb701d9a63329993a8cb355ccc0d80daf950145f37e9b4b22be2aba29898e974f9fd552", + "0x90f52b2dccf525b9191d836b205ffe966d9a94f6c5800f8f51f51f6c822619e5abdf1257ee523597858032d2e21014ec", + "0x831209f8f5257bb3eb452d3ee643d5f063299f8e4bfea91b47fc27453ac49fd0ba3cf9d493c24f2ca10d3c06d7c51cd6", + "0xa5a4db4571f69b0f60fb3e63af37c3c2f99b2add4fc0e5baf1a22de24f456e6146c8dc66a2ecaafeb71dce970083cd68", + "0xb63da69108fad437e48bd5c4fc6f7a06c4274afc904b77e3993db4575d3275fce6cffa1246de1346c10a617074b57c07", + "0xa449448d4156b6b701b1fa6e0fe334d7d5dd758432a0f91d785b4d45fb8a78e29d42631bc22aaa4ea26f8669e531fed7", + "0xaabe43de1350b6831ef03b0eef52c49ffb0ccd6189cce6f87f97c57a510ac0440806700ce2902e2e0b7a57b851405845", + "0x91015f144fe12d5d0b0808c61fa03efe0249058e1829bb18770242f5fb3811e4c8b57ff9cb43deccfc70552e4993892f", + "0x8e9c570811ce44133ce3e0a208053acb2493ef18aade57c319276ad532578a60d939ed0bde92f98b0e6a8d8aabd60111", + "0x8b21839b5dc1c9a38515c1076b45cedec245d1c185c0faac1d3d317f71f1bfebba57c2559bcdb413d9d7f0a2b07f3563", + "0x90413bbd162be1b711e9355d83769e6aac52fdfa74802d628ff009325aa174c68f5329ddd552ef93e8fdcb9b03b34af3", + "0x8b6b02e3f9dd1031ebd3df9a30432a3c86e64306062ef00a6d1243620d0cb66dc76f8d0d412eceff877ff8768c2696ce", + "0x9894b41d9fc715f8f6addace65451f41dc5ce7b983dd8cb33757b4d7259bef12f144e0077d0b662aa847d5a45f33c563", + "0xa353a9740f6188d73aa4175a6c5f97898a05ed7aae9d2a365f15b91dfa7c28b921fdef0a32d90b6fb82718b33d3ddb8d", + "0x984eab8faed87c403c9979f2d2340fb090cc26d00cb4092aeb187c3f4ee1df3f57cb8363f7764073188790b16dfc464b", + "0xa5c5ae0ba435fb7f3ddd5ad962358da326239ff236fc3b51bd22e88296236b109951cee1b98f444302badc58d1b5bfbe", + "0x880be1006b0156f2788813432f450f613d235f41aba52a6000d2ad310408ad73d86b79f6081aef1e8c51010d404ba670", + "0x937da751aae68f865c7a33fa38d718f20e2a1c65cb18c8e08f8441f0cdc77662789d2793794dd0a427cad30cd0b33f42", + "0x9496fde66c834ff86f205897db12bbf9a9bb78d9ba8b5fb539cd0a2c927cc6b4120c017b0a652750b45edbe5f650e5dd", + "0x97a6f409ffeb593e149307a14bc47befb632412d70565c5f13d6b7d032acd2e3ed0f7b6af701b387f11d69ee4a8094d7", + "0x97ed94934263dc0260f4f7513745ed3483cdddb9adb85dc33193c3a8b4d52affaf1ded23b59c34651afbffe80d40dc36", + "0xb2b26378d44f916bcf999db218b9892e06de8075f205c7dafd6d37a252185c2d1b58e2e809c717963d25627e31f068e4", + "0xb8f9fa1fb45fb19a45223f7be06c37d3a3501dd227c3e15999d1c34b605f888123026590697d0ae24d6c421df8112520", + "0x997aa71e3b2e8c780f6855e94453c682bee1356b5ce804619ef14834475511105b1e4d01470fe4e2215dc72182d9909c", + "0xac2cb2a7cf55aaf990cfada0218453853047e813d3f51f5a623d09f4714da79de6592671358a5edf938a67f905b6cb5b", + "0x8d8340d0c3081cd30d34f3ff6191e1ff6ad7994b4ebac19e5936f1157ca84e1813228b7605ee226366d6bab1e2bf62a2", + "0x9693b17669086003cb46c75fed26ea83914a54901a145e18c799a777db1df9c9ca6b2ea3ee91e7b0ab848dc89cf77f19", + "0xa6b6b2a6cd8c4922d78c8ba379373b375d66ac6ea04b830a23d5a496cf714a9439d81c865da92d52600aa4e2e43afcf1", + "0x89cb665020abc3f5e11a03c7ba5ec9d890fa9ed2630f1443a8e45a28c32786ed980b5343ffffaea60eeff5b313bc0d66", + "0xb37b989106594221bc6cf33a1a83c3e65ecdef279e90333a9e105b8139dc28384bb2277edd4b77c9e59d15e6afe074c5", + "0x98ce5aee5918d18b2326b30c1ba41669cce20bc7a1d1b585363305fbdea66055164a7ac398ca0f0e670291a3061022eb", + "0xb57f472d5f34beb4cf430d7c0f8ac5bd1c0621a284633ed36e6f7804bc2b7847f54b469c7ea163a436510d9e3b32f97e", + "0xae673a6579dbf0504c8fd0c8fc0252d2f7ae8da615a06f4d215c2f8a8f516201f24e5cc42967630c252905e5dbbd6377", + "0x97c1501835a31091a5a83f0546e01c85ee847a0ca52fb3cc0653f6a826e13d25ddc623a5dea139108f7270a1fd7043ea", + "0x9376ee667f3834f6c0da4324fdcca5c04712e0649877ee19da79a2d23be24640c38758fce562470ce2134ca34148ffe3", + "0x818af89c40379a10074cfaba6d5968ecf667f1a68a7edaa18e8977ccb34e0829f237c5634fbd079e7f22928b277f1096", + "0xb8e0af0be0a252b28df25d4a509f31878bcddf702af0e5553393c3dfd4a1f1247ad8dc2668bc8dedc9b41f6ad8e71b15", + "0x811667ffb60bc4316e44bd04573503f5b4dc44d1ec824393a699c950e5fa085b146537ddd6a08a3fede7700396a0df7d", + "0xad834cbf850b2f61ce799c4a0f8ab0c57039d4e1113933c50b0c00175171aadee84894d1376cf325bfd434c3deb44315", + "0xa8b7dfcdb40373ba4d55e751ccfb9070554434df9e359fc165284ee3dc35db6fb6055657ecf5a9e9b7b8e2e1abea4375", + "0xb56a5b9fd41c9d3f65532aa58bf71a38fcf07782e1ae0084dc537862fa02e6d66658b19d6f71c39cd5dbfac418da1837", + "0xa935af5ed224b9533b41a7e79f872f6851591da9e9d906050ccd1b2c772a1d6d010c5fc7160c4f8cd7d3aa14c3bcdc26", + "0xa81e580fc98692567b28323fc746f70c3139d989fb6aabf3529504d42d0620f05327e3385c2bd5faea010d60dd5c8bdf", + "0xa8b352054cdcde8ddb24989329a249b71498a5593a13edad1e913c795dcad3d24789abca9c7ed1d57efcc9e3156da479", + "0xb0de8a2bd7f93284b2bc700e442f52ada16a22ad8d86329591547411c23fff0333b2ab0c9edf82bf7903ebf69916eed1", + "0x843e9781b653d1a427f3534b2e86add49d308ca247546f9fcf565f9e08df921e4d969e1b8ed83f3f849e98c0f63e39be", + "0x84a4098c5dca9f73e827d44025473096101affd7193c40a0307e3215e850e753e9a08e6e74a442d57626ff26df77faac", + "0xb463eaaa2f3315b511c22a97fad353014d840a6a95fe0d457d0677e63e571407d7f5268f8775381a5e7adc3b4163eb88", + "0xad0417edaa16cfddc288eef4173aa7057ca4f81e815541ac588ef5f24b98d56fed6845deb6ae1a9740a28bb1cd8780a7", + "0x9271963b8fb2288a96e07eac13c0543ec41abdc6d978bd7c44ae08251ea49994412b542c77c8208cd71fd8e7852d4a70", + "0x8b68b6db9044d8bafc155d69e0daba95cd59d6afebb085791e999afed4f33a2479c633d31d534ff767b8cd433d591a23", + "0xa6a06a0e433e385437d9996ce823abda9848754aa9cdd25ec8701af35c9ec15df999825669bbc2e17cedb597a96e8eeb", + "0x94d414bff8b6b8597634b77a77d1060db8e1af0d0ddfb737a9bf1c66c8430e93a425510af2464bce4a7b29bc66cf325b", + "0xb6514049562af1c6fb7d0e8df6987b020f0b7a6e721f4862e36b1ba0e19af19414ede04b346be22d348b50875803d1bf", + "0xa42c7fb34f2fbee8aaccd1d86672d0acdf4e6bb083ff0456512d7e1e43be041cc0924322fcd986e6e1bce5d5ecce6f92", + "0x867cbdd169a52440ae0a75d33a28c7d00aa92b4b65aaac5e62aa53a8fc367c08ab8828cc8fa18b6e7d1f908d158e3382", + "0xa6fe0b768fff3e4a6153e59a7b7508eb2ee8165eaf5274d41ac2812bd4563c4ca2b132f0e27ea2f1c98759cc3589b61c", + "0xb3eb1dba43d10b9e17ffec8def053fc96f9883bacb49330a089a0ca5b9ab0182e8b5111ad4aa55c1ce1b6f4afa5c70a3", + "0xa1531351098bdfcda566ff4d811301c0305626c77f954a38420c490e7c684f517eb1a4e4bd2c3904a10bac889cba314a", + "0x92278d106ad2f27eacdb86bdb1faa0a07a93765bb79dcff191873c52253af83480114b2299ffe5324f9c31d0abbdbbd1", + "0x8900ba95a90c447fb6fa1f528af3d7a378aec25feb0620516b6b97e54b328fc31af42e46a8ad5e6e3029d83a6f2bbe5f", + "0x86053d481179c1ac910d5e7b9a5de82794b442f20e854583512ce1f9c3f09e71d1bf97d6700fe776debfe1527ab97a82", + "0xa32a60de492fc4340336416bccbd2591b5e414fca0aead82281212e24490acc01747537b3da783684e27aeb987245cc8", + "0x9820fe8e0338f21797143f368177e3669a1f3894b40ae9fa3b353125f7c8e85cc424dcf89878f2c7667f65db3b1e4165", + "0x934d64711b4348ac5e1395cc6a3215e5643b540f591380d254165486b0ec2a1d0d21c7d2c6310f9e0eed3d08ecf4b57c", + "0xb9fd32d589432eddcb66dc30ad78981360915854cc44b2afeb826b5d48a08e377dc91be66f5bf1e783d1a8bb320f7ccb", + "0x98c972cf01efff4fc2e485b47572e2d8dde22461d127ef401b71a111b0603203971e3cde40912643affd7341cd27e57a", + "0x8db6c1620760063edabd376f4399b6e1355462e04f5c81cdcb3989fdc00f9a466bc85ed899e886c89c149adad69edbad", + "0xad7b7fda0aa6e2aa66a27235ac5cc680aa04b85dce329fc4be84f75c9c961120a3d9e446aa44539aaac8ea203eecb4eb", + "0x8ccb01eaf41d816ce69ebd57754859e263530915e775c4e7d9dac37b2457a9099b9ae9b4c6cb09eb5ff246e3c9320c59", + "0xb895b83b5f7ca46e02697dbaa6157df6c7571864c83e504a8c77d965bc2ba97bf9353a71c56a020df64498bd40e30b21", + "0x8018c07a81c522fbc25f2cb14f2321c61b98bd8962ed8eb7d5823dbe5d1958a5ec2fb5622fd0868e991bcb6cae016ea1", + "0x95b16364e94d01b3664812264d7185032722a4afc23bdd33bc16ae87ee61816c741657c37138d9312cebfb5fcfbb3b2d", + "0x94a709209990a8b09bfb4b9581ab471aae3a29526eae861108b28edb84aab6d28f1d7a25dddd8150b70af34bee4ca2e4", + "0xae06c80839c5a13269b984ff4d8a5938c6f4d8d647b1b1daa8cf7f6145340b76a286cd615ec251a65501e6290162da50", + "0x875cbd0694eeb90d3567da9dc7f570d97b02bd9cf17bfa011efdd48f1d580608a3213bff4006603b8b4079fa66bded10", + "0xb27f88c455f025e1cd902097d6a224d76bdf9c9195adee30bef4a0b0411fff980787285896e1943a62271d0aca531446", + "0x8024880cde783cdb2b863e3dd856be92bacc5b2a1347e96e039fe34279ce528560d2df7d4d1624a4595dbafb40529697", + "0x8883d02c2a5c0e026d941c785128d4ac6f7a9de625ea735b7d6ff27a5ba10fa4d6370d450d99a855d919f40d64f86afc", + "0xa1beb985c45fdc30ac536f1c385b40b6113ef6fabc2f76d255490fe529468847a776efa674ba8fed72180f07d3f701f1", + "0xab83bd9b007561695210e3276fde72e507456ba277ad4c348a2aec7a6e9ebdc2277cb4bd0bca73bd79bd2240a1fc4456", + "0x8db27f516153812149854fd6bb1250e843a3ae1c9637df818b08bd016a769d0497ab6087fe3b2fd4080882713607bf46", + "0xb3891dde4e00d60386aeff161b4a0fbc30bb31ee7918ce5fc0b49aac3238a000ced192c9c4c08d90de3a0ba973d7cfd6", + "0x90a2049a15c02e59024a7a1cb0adea97501c60b1c7442fbbe560054c3d69264e69627ac57b7d9be01bef498bb2a60198", + "0x87df67a4bd72444b5faa4f3b067204c4927c869dd3b29ad192d859589a9b2c1d6d35ed68310081e140add254a9463092", + "0x8f80986a8dc8a0d6408ebbcb4f234e76413c11cb0d66067f9436bb232373100f20a4fded60f08dec3525315abfaa8523", + "0xb061e10beb12ba3683688a4ae3a91600d14878ef78a308d01b93e4918efc666450e3f7b0e56283468e218934231df98c", + "0x86b9e55f3783d62e381659d3e06699d788b88aab1ff99848db328a83c97d223f602201bf2127c5ecf419752fed0a224d", + "0x858d878e29925c87243e010020007f96fa33264e89c8693af12857b362aee3fac2244057e159651c476ebe1dfbd67bcb", + "0x8fd47cdef87d7a569ffce806d2c2dad100692d6c53e5f5dfc6e274f897dccadcee30fc6c6e61373961bbc1f3ecbfa698", + "0x892f2822daf3df3a759bef03168c1cb07408df62e024747a788e94d2da325f880bb9c6e136c7f6643f45b021c6ccb654", + "0x8714e37ac24f5a198f219e7c88a92172fc3db129e044e914663ac708d8101851e7c53fce79d32d0e6da74f2ccd1d30ff", + "0xae95e1dbba8b9e2c8dfbe1c202e9ccfd04fa396470035a699b902fbd86d5e6a31732a7c8cae00b9a4f6e51c8d560c7c3", + "0xb0cd058e77498e860fa20c5f8d9bd09bb249add1badf84ba8d1bd49e704b9b4bcd67a5c3d211840a2c8fefab3fea639b", + "0xb78e468d3a7da0dd481f333ae56534e2ef97587be2e259a458e25aa37952aed1cc5f835640f812d8052f5bada8f57b12", + "0x835de7965c6b26e7ad1b92eb6f0261d1f376fa12d61eb618d9b342b597c9c117a5a8f6a36269aeea88072b4641e6b5bf", + "0xb4d0eb99136b3643468c9c48a20fad62785a60fbdd3c054efac4bd1fa7979b4c9ca6c2c0b18069c0912bea2f19832790", + "0xa00c47315dc0700a850966836a95f3cebfde04dd094bde0742dee77b89a05b5ad655921f86fafd1e902938ff34d4c58d", + "0xab13fa0afaa92229a71ee91efae6d1b15f14b6eacefffb7401d41d0d6db24e24a8dbe8ee19b4680ecb69d2a0cb4e84e7", + "0xaa56c0fb18401210062dbc653df8e3732aa8921a1280e9737e99b26a0100a13a9cba8ad0317a69bba16193362ee0f030", + "0x8b410324a6406b345df0fa25f541ac20b7313fa55832752f70cf4c79f43b0bd3d5b4cdc447e6ba7bca08d0edffa8e29c", + "0x893362241ae412d9e5df46506407595c58ffbd7fb1fdaf0694c3432470599291238997abe118bf7737e56a4f5c9dc292", + "0x921618194a756be81cb49d6357cb392b32cc62d96c8ffb7e16d9659a0f226a0436bd378da7b835054dbe0de2c6372ef2", + "0x94a2904f10994928ff5367b777e1430047736fbece33442cf452018bfdeae62e84cd75cf80f8468285e347d504c94111", + "0xb4b81545b767f380bfe10e0fea9c3cc62ca8db40b43c83ffb245259378731298e3eb6c3bdc3a16932f88f5d8a86edc4d", + "0x936203c2453ff01c6fc635e4d54320d69e60047d805daae3b75633c2259108497b778f011e5a057249f11b2b888ea76c", + "0xb90bf6378d29339443c3f2008b1e2b5f0345f86e393027f14a295e583bf6e6c2b10f54b6dcc42079ff0d356c405b03bb", + "0x916913f550d327de2d8d6c7723dcef2e3869efaf95fd963d95c8980b97748c61ad8e2e629cead8577266d93fe39203bd", + "0xa033c6f3d5ecbabeb83eb363e54e5faa7ed2d7f4fb771b161762c4f003eac4e1afb236806b784baf2222cad54e2d3cd9", + "0xab289d4a5771147e6c29ff9ac2bf65d70081ea6c6af2d9b728c3c144574a31b5fd8632af57c18c389aa2cd994938bb0b", + "0x9488da2019ff13e290eeac132b491df58b5b7b23c2898ff1a67bffd7e9c9464c39bc8177a57950fd28589e3d9ff9c6c4", + "0xa5abe42b2e0891851440fb2aa6c1d8a86b571bce8b80c8e9e2692e5cb6d45a1b2f055c9fc4c74a7cd292871604129ea9", + "0x90bfef698e83c2ba4dc9304aa01edd274169a978b7154bca518daef394f55857d0d1922ebef3d91fc5ecb3b895d9e0ec", + "0x92328f1372b6406ec80786041b6d57018b8507e3881a08727aadfecfdfcfb0824394cbb1150117ac5da5d71b89e895ae", + "0x9719751c5f7a65ae2bed8aff7b4b8c34539ff011b259b7ff54f63f9d987b3fbdce5c99534ed561aadaf07bb6e939e208", + "0xa151816774aa9379fccec21cf212429a1c68cf91b055cbb9d931f461a8d5616c693331a11ac5c6fcfbd17d84ee0b44e4", + "0xa72977b1285618a45943ad00f33f37102e2885eccd2f76785254eeca495068fb1d8d49865343e9e8313c6c2c3b2024da", + "0xa6f5ad2e023a1585d90625c9f7094f0e8851c79f0eede8ec582ee8e063407cc5b8298e5fdc4c786e4fbbcecaf33e787e", + "0x82901e008febcea0c0a14ae21d985a397630e18ee6e346f4a449f23be228e8f338df567d30211a11180b94fbc5204bec", + "0xb9b57fdb8d14d1be87a25f89553b3966eb7869e0519ffdf4cc4d51f4cec90d68f7b81cdc0450e04207276e9c63ace721", + "0xa06eabcf43585a001448f3dc30411f3d5b74fd0a695c81eda9981842ba2bb0081d3f5a8360aa18b6d43ef13ea78b293d", + "0x926fe48a7e8f07559b7237beff9504476dd97b5b4d67acd01a3633358a6ba4c7abed5c87683a11209aa2ee759888e00e", + "0xa716cd3a84a963e2a5a46145b6ef4ebce705de52bf2945c374152a1e41c228a9c4eae0b6d1e222c1eea8b9c13c002177", + "0x8a9b5985df6fb32cdb06ba1591a977545444478f2fe985ed1b10de61c630f0a4693c2185d63f0dc0256b208072c43b17", + "0xa8eab26ae0ebcdf96a59fad1dc2d5e83b94abb2ea1774b607023f9d9e0fe065853b1e2242e794f989a80a47f550c0bd9", + "0x84adbf38164cd04f3d770a7f4b8eae7a5d25b4a803fb63c02b95b71b33e454319c44e07a760d22bf5f58e7e372d09a16", + "0x90f443a3ba1b9129a0bee400b5b29d42e50bb2aa56b0022bbfc3c6f8d69db40299871ec7c1b68421cc89e1af6b13a39a", + "0x81c5a94b379eb98c494a8d0067c748ba47e87a2ada0105202ed7651eb4e5111a0cd8569b06ae68d392c4fd74a37833d2", + "0x8f92324b14a1549ee0b186073a26691088e41556d33b54258fc6e0b000e9624156db4e97861a0ec22960e6c47ca8a1dd", + "0x8b021cd0fffe055068cc460aec3cc455952e2ac32be5fa060e0d1b6cf30ed15381618f801249e893b1b9f10dd82077b0", + "0xb3e9f0dcb3d6f0b138f589fa54dfb01f849890ab97016372d004aac55103f363a64bc0e606ddf75430f1534a30fc522d", + "0x8fdfe64af891db89b25daa859864d479cb7599486bd6f36e593f8f2f839f942261ffc3eed5001a93fde44cbcdc24c583", + "0xa9e4554373c5073e135874e2bacbee69c65308eb0785532fec6a37834e8d0b437b77a2f11cc63c87d7183b82cd9b6bc9", + "0xb4c47daca723ad7193ac5098cad4dcab654186ec5ea5c0fd014a3ac39726be954565a901694ba211820c011fa1c59e18", + "0x8835427e86cdceb4c11cbea331ed724e4e78af15e3bab5be54f6b926bf66b5d99bcc40dbc456d86342c9fa83a033c2d5", + "0x8ea84590a400cedba047c2661378921a42f5ca0421da58c1bcb37bc686a2aed98afab3fa5e6ba3a51029390ef3cdf4d4", + "0xb48551170fc479d69fffb00fae4fba301e92e37cae08f596db6f6489c3b7020edc074f9e8d7465b84e9dcef1b6b3aecc", + "0xa6f318b1eaab00836a330710e88bfe400395b3081485f6a212e3cba9463f6fe7864ba4f71e57a411ecdf2bcb4d189f96", + "0x848d5137a39999141a79f4bdf91150796ba36352d8525821bf3bd6e070b352792d79147341b8254dd60fa8c36e9e2618", + "0xa8526f8904b1eac4ae2a25534aa91e8031e9aac7b8f58d8f49897e920c36c0232f4a30aa6eed305deb0f7793c115b267", + "0xb8b6a727c44c37a8388383e959d195d1d0e51a657d4ba360633d219d43c5df645383e2406c25f1d418e72b862c3a6e9b", + "0x92e64adf65b42c978f36dd03ab22ba983bfbb61944efccdb45b337ceb486beda99818bf20d32a545503c4572bb0a4983", + "0x9653bb83df66260a0bd059cd4244ef7c661b089e403d26ba777d2090783ff31f963f5d3a9c125b1ad1a1d19134f3fc8d", + "0xa74e72355e71ae5eb36dc75191643500ca3e67f18833ee981010e7e7e60a68e1b01b05901eff05014b9ef29aa4829f45", + "0x8b2139a5da14524cf6acc593144db23db424b95b8c7041d8f6c7a14a6725dda1cd09c42bb3ae26a5a3650affaa742800", + "0xa60ddff4300ca44a7c7a00a1f98441ad1438e07c30275bc46551cee1b681926d2c825cc8f90399ee5f36bb9fbd07d3dd", + "0xa04e5e9958867a5acc15fdea0d88951cfebd37c657102f6ba1dcdaa5e46cf1c823ad0d98718e88e436f260b770599102", + "0x95e977abeb70d46fe8d7584204770f14c856a77680607304ce58077550152733758e7a8b98b11b378540542b1175fecd", + "0x8c9ec93ed35a25ce00d61609e92d567459a45e39922ccd1c64ab512e292787125bd4164c00af4cf89fd3cf9deddcd8bb", + "0x819819ad0338250d9c89aceda9e217df12ac54e940c77fb8420575caa3fa78930689d0377ba88f16d38179a807135dc6", + "0x8baafb379d4150ac382b14a64788d819146480d7a1dccd3deef6889686ded375900f5df069843ef14d754ad3d7540401", + "0xab827236996bb79b447714c6993af941c5ae66248df4d9a6f3650d44b853badb5c0cb67804210e07a7b9d66ca43092f6", + "0x927656c3eac8d2eb575e3daeb77f9605771170c325bee6aeade10c083d42bd8dcbf3bcc3d929ea437001c7cf9a95e2da", + "0xaf22b212d5ee44fd4197966b9690487c38a119cd6536cfb8c181f38a94610dd9e057f95774047a446504dd96dd11e326", + "0xa44bd94b9e01e3ba36340f2ac2201ecb477495d4f1fb6726a6b439302deabb5a35d237c6a6aeb7e3b0a65649f8656716", + "0xaf367aeeae3bba14fbdb05bcc1a521000dd9d37f5c34ae56fb306d3dfda201d0329a8b6e89d98e15825cb3c6bfdb1194", + "0xabcc4fbdea43e50ded9e2fb01464f4e87fb136e960141e8d39214f92794cfab5634f22cd40b18d8c0e501f2307aad23e", + "0x920786cbd674348b9853689915dfcab02cce2a4596d117962bce36aadddf4bdd143891e22f2c8015517039a64e8aede3", + "0x8cde63b9bd57cb3ef743f1f3e8250669eed739e5fbd68c500a3cc0c12f93862a69aebcdbc69dd8f476c2eb307f572a53", + "0xb967e65a5f1cd8d5d570f5e87e7e186fba51b9504f8e466392a76d8a971fb91fd9b7565bcc1647f50d7d15e48b93bc95", + "0x8d5a87b25fedf5edd57d870304bfd9081dc78c3e3e3b38b997260a92edac7feccdaf24feb51822d2edc223b70bb4ed5f", + "0xb6cd5d340a57f8ec73723c4f3ecd6601620dc8137a3e75a5d3c578bc79a9cae86b379950c644dee2ff99dad780d025c1", + "0xb6f0a8e754b7f52a85a2a2e6512cfd017f7fb0418d19bb318308951c4e242d3c65bbcb9748da9cbc91a738f9ca577332", + "0xa89dcf7d410bccec385400dd96b1cc6af89026a431d0f531aa992cbd7bc8bfd7c5f360bcb665bda1d72efa17bb982551", + "0x97788e7522427a46c4b6258d15623ef7a565712812fa80d001e1de8dc1791392702f3fa3cce5a8cd1c5755625a0ad10a", + "0xb5338fb5e137ff625b27c5148298f27ce8f493e2527c5d0facaa49f29cae34580d0d6c3c1074a2e46cd8db3f56004ea9", + "0x8962f006d7b1095dd0dd132ffe7e87e328510c95ad893cf3b2ab21c177c5cf2c27f47d8856f87e9762c547be009d25c0", + "0x87fee9ce9c26aa476e67e0791a809e0a06a8a98facf3faea730d438d3e516cdf75d645fa75c906e4e44ab9237a22c016", + "0xb75ab972e1a1214bab0b38cc3e973d44bb233acda5b4291f5e110b6fb78fdcab93dc63f01168debd898e165f615be1f7", + "0xb5a0fb52bca279d3853761a94b206acaf313df33ae6303d9b71edae90b66fc507adbc60fb11e758888736c81d5d80c0a", + "0x849b8f0005010e684701cd3a4e59e8c89e5fec59af6d2de5b6332cde03b865ea84f07f0b80ec3404380b0e148fbd2c24", + "0x96e2b0b6fe78408f9208f809f5c40398100b2dac202c8c5c33c2189560dea868270a598c419871a5a2b67783354f6014", + "0xb234b81f996142d0df2c719760bf996544820a03195a6dc0ff6a72543692f5a369bf63d1f0b477ef2fe7b3234e41f685", + "0xb85e39bcf40da1a12a535740176f4de749a93824079deb5fdaa004f3282fdefaf5275e3418c88c419bd42a3dd2ed2b3b", + "0xa27279304b89a18a4e2b443246f2368fb8b15f46a34533179b6bd2ef683f6e98e222b7a32880b39b8fac1afa90133803", + "0x8923c22cf15c9c1964213d725b337ece9ea854775a06f75f232c4859c7142a3942f418354e33066298aedfba3cb27e62", + "0xb109f714311fb9bc431ef57911e2cad6a3949455b9f23255cd7edea35be629e07f845fe53e2b12a32305ee2f4f264f27", + "0xb51e82ae5c7d48050e405897d0053e9ea4b2714d002e88f78c9a307cd50b9c6b3ee7cb86f86527be9d964b01895fab20", + "0x90db256931c7f98bcf3bffff4d496739185e7a20f329ee7bffd4e0850a37739948ec745285703967f4ca50ec370cf68b", + "0xa0485ac0445d88dafac56bfba2563b020cfc370f54c1606c89d12cfd8a4d1336d2ba50306e476155a6f5b0e0a1f2d092", + "0xa00754c3462e74bda928da855bbf90f9077db395e32f03cce9b2955546d900b72330d247b7d607b65e130f5b0d883de0", + "0x8547d56727c3ad8b5c8ce622ed9ad86fe8cd78e6e4848c9845914b5063b17330bd10b46d8d3f18f83ca09ecb28d1afb2", + "0x95b937b2a979bce0e159ac75c7d5d659be8599c92305e73e942aab414793364a3ec28c7c1c8491a5750ba84a29828d8d", + "0xb011e150f0294e45a0f4c69409999d0c2e602449dbd67ab95e8258466687cd733a0329083a31b03722f4e2580ddc95e9", + "0x924651a733ad5e5d9adadad3ea6a6babb8e455c8d5f2cb5bdc83fa422e7752592190ccedaa827b866861e73506a6968e", + "0xa4d5180122f8e31503ae027e54da50f72f5cfb910a6f7309bd882b5cd666f454672591f1f20e461e182a47d03b47052a", + "0xab19ae659c4f73ea3d21895269dbec583c7029955a36469124ebe295027010faab56c4a475973497f28e9a77c03b8fd0", + "0xae7ea1a803d0f439e91494f8f35fc1167dae23834c0c699ffe65d3da8b09f8df5a53195a99ca7b8558242279e69578fa", + "0xb9d63cf0e30f9800101b43b980bcd2f229758e74b21ad5354866b4e684791c08a184330dc316228a0d67fe0210f2bc4d", + "0x8c41629744391ddb96dcbbf9cd99b13d36e57d65962e0aeb92ebccf1c4cc769626feb3ec0363def08eceb102b3dd4ad6", + "0xb2848ff24faf9e667a8c19d050a93896e9e75b86595f7b762c7c74ccdfb9db126ae094961fee7f5d1192776c1ac1a524", + "0xaf013bc29206743ce934d5887b8d0fb3667c89bda465d2321835a3618513fba6a459dd7566268220ffce7e0c97e22b2c", + "0x8bb799e36db1132da8e8b028ea8487dd3266b4628c56dfae4ea275f3c47c78e3d7445ab8d0aaee4cbf42148b3a148175", + "0xae2b81fd47c038b5195a52ab8431f0d3cab4cf24c4237252d955aad2156adc16dda9d3270157e0bfe5a44022e5c051ef", + "0x8e0129213b1698d2ec6df132356805a8633ba79e672e586dfef664ffccca71834253ba14f296da962651fcba2c002622", + "0xa1ae30b500ae77cd9bbb803d737b4a5991cc780618ac22b5cc179efd8fe10afb8c135457f2e7b86ded485ea12eae70e5", + "0x8a39723077b7c0df6e3bf6548afa3910c214ee275951fbe5155a39473be98099626ea14d844630a6fa90292b9594665d", + "0xa628386c79b61aa7314b01d9814aeec20c2a66e3deda322a39957e7135c2e52b1da486d1b9cd61c87afb22c1d10f6462", + "0x97867f469b01249820aadd9a54e12d4fdadd4555f2d530450e1f8f6d2dae57360578e2c2c8ba41e3b5950df596537a98", + "0x97f192d0457c217affa5a24267dd16cb4c01de8fefde9df4884e1906d2f22e73382dcee6c7d910bf6430bb03f4a4f1e1", + "0x86d5b5739de8442dc74d0d8dc78e49210fe11bf8c6ff0f0faecbc47b64812d6b28c8afddf6d9c0212f1988451d6ccb1c", + "0x8ff3312ce9693cd4a9f4b8e75bd805f65b0790ee43fd9e075fe4cebc87185bdf161335049819f22530f54fed2779a5b9", + "0x8dc41d85548bee5d51941d55752a500bde3c5a8f3b362da4eec307a963968e26605048a111c9166d448b8dddf6f53892", + "0x996bdfd004b534151e309ac925fa5ee7801c9da4f6b4c43e156d1158b134535a2a3956e1255e0dd72ac2af6bddaebcaf", + "0xaead652704b788bf4983c8f725c644c327a6e9f6683215f5c826c09f82fd2e40631791f51d14e6aded91fdc018d45501", + "0x991ffab58a82b98ed8fc7b00c3faca153589fe09cebf6a137ad506387a1ca4dba475b0e4a1b9bdad829f1422facaec39", + "0x9652e6c4ae084221d6bad855ec0bc11b5f855c6efba67f644e0902ab790a98861cecc6ce047c68273c3aa7eeb2f4c7d9", + "0xb88b816507aaeea6dc92b861eabdc96988b74d7883f20a4b30ba249158acaff3c50d261742fc9ad2e9eba888a8d59065", + "0xacd028a51e16c07a10d2073b9d03070457ac5f1246365295a1359d015c460b92b4861125fabe6f114de8197045df408d", + "0x806d3cd9d02d41c49179fe7dac5b05dcfc9a205a283135d4f008d0771c58e6f963d7ad0f6798606edda718eb5c7ff3ed", + "0xb9b71f1657a6b206fc40159a941e127f252a7b324dea864ecd804f48c0ed86da9778a925fb65491204a92bc2a26fef32", + "0x80ed67bd0e74350c875abedc0e07fd42ce7cb926f0f3fb1949c6ac73f2300b5a14a5c6f6ff8aed99d5ea5029bb8e7ae6", + "0x9875f67a7a473714e4dd75ee0c763ddf88101532d9680724b3848fef69e218b04a96b90f88e0f4409aa40b9a21507ecc", + "0xb4a2bb1b421e5243e5e7576a0672dc19f9f70315a03f6411c19f76616ffbb70fc5dc0e57fd4ab85e24ea2261b7ce38ab", + "0x879723002ce43e6c75ba2246f51436efe3376242beff987d025c3c4476495af32d52a54fad5d9ec329a442b93bcff1ce", + "0xa4121efbefd9c3eb143619afa52a916f199c75024908047763b29466cdfc837c2fcc894aca63044c33c41c777e529b5b", + "0x895f637b497a9766714a3d9e3c275a1f0c9ddab105bf4c8b7e663f36cd79492022415bb4938c1a4849bda73106ace77c", + "0xb119acb8b161ce4384a924645a248a656a831af526cd337d97e08405415b9dd22060849c76b88a4785eb5e7214961759", + "0x802e712f4c0a17009c4be6c1e5ba2ca3b82adcb68793ec81f4489b7985babd8a3873d544de63d5e5de0cb4dc5048c030", + "0xab111051e4651b910c68ecfdc33f2d99e7bf4182df68cedbdbbcac219a543e04d93ecb2763fe32b40c095c7ca193c331", + "0x855c73ef6afc6bcaab4c1e6388519fd5cbb682f91995bebd558167715db454f38012291beccea8186a3fb7045c685b67", + "0xa29d02ec6d9baf84c19dfd0eb378307703bfafc0744b73335550f3cd1b647275e70215f02d1f4ab82a5df4d4e12dd938", + "0x91510a45b8a50cac982d2db8faf8318352418c3f1c59bc6bc95eab0089d5d3a3a215533c415380e50b7928b9d388ff89", + "0x8286e7a2751ca4e23ea7a15851ad96d2cadf5b47f39f43165dde40d38ddb33f63a07bc00600c22e41d68a66fd8a0fa51", + "0xa413d4e619b63799dd0f42ac57e99628d338b676d52aec2bb0d1bb39155ad9344b50cdfe1fe643ff041f1bc9e2cec833", + "0x85524e5bb43ae58784d7e0966a664717289e541c8fcaff651541718d79a718f040a70aa8daf735f6635dabfc85c00663", + "0x97f0d48a4028ff4266faf1c6997b6ad27404daa50ca4420c00b90f0b3e2d82ef8134d0a04108a74955e61e8dfeac082c", + "0x8df6145c6cc39034c2f7331d488b8a411931c8faa25d99c5432831292637fd983d4f6b1a6f55522b4a42a462d63c6845", + "0x98c2060f67a916991b391e67fcf23e5f305112807fe95bdddb8ce6c4084126557e4c5f003afb32e30bc6808b30d4b526", + "0x8964246b3c2b8f7312f0a99647c38ef41daf70d2b99b112412356e680185da6810ab8ee0855ad7409d334173bcc4438f", + "0xb56c2c416a7069c14bdb3f2e208c5a6ad5aac1cbe5b1faf99dc89c7141d0259d1c6250be9d9195500c4a41182ad2ec3d", + "0xb7864583a4cae3b1083dcdcff7f123d24a69920a57d6594d0b7219e31bf0e236682442b6499a1f6795cfeb4f5f236695", + "0xa064f94139bf1b70d476bde97099631b1284aa6b4d87f16bfc65c075e58b2f1b3c2d057605259f806e545674a1169881", + "0x80d1bc4acf14c0f487cd57c5d6157b7f38917e93cb660f1c25e474fcdcac3c3dfda50f6bcccfd6676bae25c4b6b5014e", + "0x8ad9a4976c4e3e282843518149fcf5d454240740f4b91466f6310b7216d23d70b9b47c42870293252f29f092f330967a", + "0x914197593d2d99d784c704cad7ecd3f0b9f55dce03fc928d13e1a1034566c4de754f1c2a5ade047b0956415fe40399ec", + "0x8d77f5e29c572ec3c0ca39cbae2072ba4102403265b3d8c347a00386da9c0b8688d6e3280c96037c300d57b3545f3773", + "0xabfdf79d935fd4f06a04938d6580a8cbf9735f0d498f49677f26e73d3b34b7075d525afcb4f14ef1632cb375bef7dd55", + "0xa97a8c446e3edc86efac7bda5e2e5d0158c909552a3bf86151df20ece63b8d18b608f477286fb1c7f05605ab7e6a7c2c", + "0x8618d946c7fd62486551c35486fa466bdfcdc63c941e4cff5a01fbbe566b7ea9dc763cbe73e2acae063060b619a212a9", + "0x8d03ee468070936004b06acf64b868963f721f37faa09887f8a82c155ad5c5732572a6855b531db58af03b1afe034a18", + "0x8d3247f75966ea63935ef6049f7c889c1651374adb446f49499fc9191dbcde7ea33cbc1f1e2d3d1756b6e69870404643", + "0xafc853c3a3facb4ba0267512b8242327cd88007cef3bf549184ee891b5ddc8c27267bae7700758ad5bc32753ebf55dae", + "0x80df863eaea289de5a2101f2288046fdbfaa64f2cf1d6419a0e0eb8c93e3880d3a3fdf4940f7524ea1514eef77fb514e", + "0x8434b5888c2b51d12d57da6fb7392fff29393c2e3bfee8e3f9d395e23ddc016f10ebe3e3182d9584fddbd93a6effcefc", + "0xb78cbb4c9e80e3808c8f006dc3148a59a9cace55bcbb20dd27597557f931e5df7eb3efd18d880fe63466636701a8925e", + "0xacb140e44098414ae513b6ef38480e4f6180c6d5f9d1ca40ae7fbadb8b046829f79c97fe2cc663cbccd5ccf3994180c6", + "0x936cb8dc959e1fc574f6bb31f28b756499532ebb79b2c97ff58b720d1cd50dc24b1c17d3beb853ba76cb8334106ce807", + "0xadda2116d9fab2c214ec10c0b75f7f1d75e0dd01e9c3e295a0a126af0ea2c66373d977f0aefdda2e569c0a25f4921d0e", + "0x89a5cefb80c92dcad7653b1545f11701d6312aef392986835d048f39d5bc062cabc8a9501c5439c2b922efc5f04954d0", + "0xb9acb52747ce7f759b9cdc781f54938968c7eeacb27c1a080474e59394a55ae1d5734caf22d80289d3392aab76441e89", + "0x8564f72ce60f15a4225f1a223d757ebd19300e341fd9c1fe5a8ece8776c69c601938fa2d5c21b0935bd2bb593293272b", + "0xa5567d7b277c4ebf80e09c7e200c20d6cb27acbaa118c66ef71cbccb33ee3ddce0e0f57b77277ae1db9c66ed6e2d8f30", + "0xb82e9c2d8df1cdd3b2417bf316d53e9f3cb58473c4cb5383f521ef53e0af961ef916e4f6557a6d8b4655ec01415231cd", + "0xaa816dfd2814c8a25bd2cbaf66303ee49784df471bac4b3188074ea30816f00f425234454d40d8ad8035aa925d74da36", + "0x9919f384df20faaa2d226b521cab207dd2b62420d25ebbda28c9b2ca76a2a52203b2ad7844c1a25f5c75f005c5a83149", + "0xb24a6aa35c2d0f87e36598b36224c64427cd69642b6f9c1bd478a62c70f8ee69f85028648f6603b4f04fb21355f2afb1", + "0x892e044bdb1276b455eac2204be105e1821f987c2570494b1f32aa09506caba7ed343cd09b1bc126fed5e0fda3d0eaad", + "0xaf0e01a3ad954dc048de18bc46bb1c4971db2467e839698e4dd05cd1adcb9261013fe9fd0cafb946c0b586f6aad86d4e", + "0xac152f0a9ace425378daf02510eb7923ff1ed2c0f8d1deb918e4efb63655de1ba58c96438e9aa23abdf2431dc771370d", + "0xad8c7419c097709347e2394195924e09617b47ac5c7a84aeb9deab8975f22155de0f70cf20d8a976551b14e3a2683a2b", + "0x808f14f67ae801536fb70a5898ab86e50ad35340cffd0648daed2f2c4564c9ad538034b2a179a6a8bfa27e9d93b4cbe0", + "0x80a74ab7ce4769db93cfa695a166db95f0a9c47885ff826ad5d93310f36d6b18b5351c67c858b9837b925e85a1995b63", + "0x95b88c3cdd64401c345828f4e4754b1a88b4875a14c08a668b90acd499b3b858842669ecd73a46c5d9f1de32ec1a0120", + "0x8ddbd770b7b18a5917eb43926fa05004e819f1d1ead05b915269e4a86b53e0633a90559007e59f6705a3769e2126ac56", + "0xab6db5fc220754f19948bef98844e6e38dd623565d1695e1198040c228ac4fd863c1f168cac1d036bbfb718d9d8dd036", + "0x97bef628e977c069e60c395a17740e0e1bc1828f5607ae7f30ce5a0c95f02b53af2ad062700a75212e462aa22c3c5465", + "0xb68d465e04fd17ca98501e61eccb0ce30401855e98046e0c1debba71c2153d6a7a704aa36a6f12454696e78e87181cdc", + "0xa79cfdd048f4181e005bd0fbac0a8424495474956b58ce858d2b700fb0f931c406282bd33bfa25c8991bc528d12a69c1", + "0x843f55fa0a6a0969daf2b48080738f30b269b2e7ec123a799e5b203c0b3b4b956dc95d095bc6550b0013918cdff8a225", + "0xb683cdf2823036827e5b454bfe04af9bec1850d25a7a7a44aee7696b6ff0468b7ed6885a41dde2b8f3ecc4aec880c3d2", + "0x8b500796e82acdc89778e0c0f230f744fb05f762000fee877bcf57e8fb703d212dbc2374887bdc2e7b7a273d83a85798", + "0xac35a8ee87bafecb1a87f15abc7ccf4109aab4ac91d357821e417f9b1474d196c38cc41cd13667f68d1ffab5e79a6e92", + "0xb6e517739390cfed5b395d33b14bce7cd7aaece57fe79a7eb3cbf150dc10765c3ea9fef7976a21a2243687e6eea38ef6", + "0xb53901eeee26692273365b789f2a60afc9b5f0df229c6d21b07016cf4c0e7985beec748aeca52262f68084393ab038e1", + "0xac4804f33d8ba2b4854ca3537bd8bf2dda72d4e94ff7ecaaf9bd3b7f098343d74d765471ef80072ae34f860b052cbfb1", + "0x8c6a30a93f1dde18039bbdd1ef294552bf79856e20bce863e4b8dd72d906be3ff22468ff3610e06b5a7d1745dde7ead9", + "0x88f0607fa3b7cefe20a02115572b16fc3222be86bb19e592c86c48afbe7e0dd523492b0c29a3bceb9a20f5538bc3134c", + "0xa660b801bbddad725975ddf9a8f606f76ecef831f954be224d6178c368e1c72d346f00c4a4c95c289b62d36f2af323cf", + "0xa75b9a6aea9542b698938dcd6cc2f6fe0c43e29f64b2f54aeb05d35fac73d41aa7fd750af4fa9333644aab8db90775b9", + "0x83e1b7129d963d1cd076c3baa5fe422148e939273db173e4d59d1858a7d841eacac7fe817d15ab8f8a493bf46c2045e6", + "0x9060a2e9c24de11f9c70e039b5ffe9e6d32f1ae39f3dda263610df2265d917679e689898e4a8bd84ad34613dca5e3761", + "0xb42fc8b863a2af15e04d1fe6693c09b46007c0b8298973fb4762b45b4590ad7fe0aa758918b2fe5ed1ed0359754fd955", + "0x83e6de7860fb256ecf7b47506a5e557d0fb0aefe57fb513c7dee2bd9604712d08ca26adca7ba9a54b712372a7c585a26", + "0x90586e9cbbf71475ecd3e7b5753b286804dcce61e165502a82b960099e79272de8b7494b8877b54ae838eb5d0f71af2f", + "0xb2e4b0d21208f73b7b75e08df80cde20c4578e117d37092a490af82354e2afd3a7dbab46fa2d12fcb731cdaece69c2ba", + "0xa010961239bb8809fc7fb4aa08fa30d33a130f9f417ee9ea60f587dcc5ef4e1b7abcdcbf8e848ecdcb7972ef6af46e78", + "0x8f511fd58d1e3403a5eefdc0a4ba6b8af848c7efddbf9575ee84449facde05ae9a24aa41a5725416467f6fbd11369c52", + "0xb24ebbd2d4482eb618cea1ac4fbfd9ed8c46c0988a27259300a7ce5ce1bb256aeca0357828cbbc4cf0dfafbf586040e1", + "0xb3ea29e9cca55250e9b7b9bd854edae40f0f0cc65fe478cd468795d1288cc20d7b34ced33bd1356f1f54a4291faa877d", + "0x8a8b20f222d9e65bbde33638033972e7d44c6a310b92a9d9c5273b324c4ad1a94f2a10cbce8300c34dbd9beb618c877d", + "0xb2436a9a647dc3f12c550e4ddc5b010e6f9cb3f3504742d377384b625fc38f5b71710a49fb73ffaf95b9856047c98201", + "0xa13f8b77c70621e421be94c7412454adc1937b9e09845c2853ef72cdbe500e5c1bf08e3c8b8d6b8eff4bce5b8dec9213", + "0xb25de8780c80d779e6c2e3c4e839a5a107d55b9cccc3ad7c575f9fe37ef44b35db4c1b58f6114a5f2f9ca11e1eb9c5fa", + "0x96ba6ad4358c7a645e5edb07d23836cbd35c47d9a66937d09486570e68da3c8f72a578bd2e14188d3acc17e563a652d7", + "0xa7f55989814051fda73f83b5f1a3d5385cd31dc34baf94b37c208b3eaca008ff696fd7f41e2ecffc2dd586de905bf613", + "0x882d0c7c81e58eb9560349f35c35e4498dcde7af7be8d7974b79d262304c26ab67ffa5ed287bb193d5f0ab46b4096015", + "0xa607158f0c1fd0377a8ee5e9715ac230abf97406c19b233d22f5911ebe716967cc10425546dc44e40c38bd6c2b4bca2e", + "0x87e8cde50e5d852d3f073a43d652f7186bac7354612517cfaecd4a1b942f06fef6f14546279c0dc0262e2997b835b2a4", + "0xa1c93acc6db9d5ee426fb4a0b846bb7a7b8d5915bec777a9fe6907246b0beafb8938941c8c79ed6082155f75dbc1e332", + "0xb1e4f61457b86f76cd93eafd7536f72baf239ce5a62bd5a8085a34e90576b1e118e25002d2de49b01d6e9a245ee7d3a2", + "0xa0435fe9a4bd1031ec5973a103ec9396b2ce9fd982f6d9ed780fa80ac06a6e47a0a6eb2daf52df1dc9292db622ee9fa3", + "0xb66d8e8a1717e4bfa42083b6ef4490e090a73168b2912f2111743e089027be0a4945a229ecf5d0b5eec11b23f0e11303", + "0x8eb764f26904eea4f4169be6e75beaa6a39e4eb524625a15a78befe3d8e3cc82692d9b135590c20ed460d6e4ba630ef7", + "0xb7e4aea6bb09829e53fe83e53f49a7a331a6d7bf76e0073d758577e6d6fbe63dab642b23657355cad48896ad8715119c", + "0x8f94207982373a99ffa282673f192aa98d0c4461fb77c31dc4549628bd9687a249f1b3c66b1840929341e42516c5c64a", + "0xa9c673cb247b13e17fa5e616f0399b7f5c7ad043e143e44ae68855a840870ab3d2aad737ebcf74c2cc9688d17ef3a794", + "0xb02635104dd28c02068985256975c0af783899eb996e37d021d9a35238deeea9e836760db21869be7b6c82aa687ded29", + "0xb33bc0966389710812b5f6698afa3e9c84839a1b85492ba11e6ded26695260abf66be6fb355d12d3a8524966f0f89e0f", + "0xa79c0dd09506951c33da3cbc23843fd02d641fc24c640a205e6e8150240372847312b9381fb03c5d301fe4dbee8d0da2", + "0xb74de6f3a2c502b5b658ebe8a9b7edd78afd036f5a2736aa06502863b6865d131b9e3542e72a86fa2e1d2db4927661ed", + "0x99e365def1452ff9fb4b9eccd36ff4154d128469ba5bd73e83ae457ab53977cf6fc04a5d05bdcde357ab539e34bd9fe0", + "0xb4f2bfb95abb47c67870aa6ca38ac8f3ae1b1a2bed064b1be7ff90865ea12e4930fcf66429c7ecd1183fae4a01539386", + "0xae4bde87f36b912e92398bf72e11d5389e93b2de1b277d7ed4b6fb5a9ab9f71a959ec3bcb734c11079440fe42b86fafd", + "0xb826459e568efdeeb66688482b67ef5020787275123fd3192f979b6175e3b0ed59e17cb734a0a052bf13f0afc7bd237c", + "0xa99dd735f4a7c85cb23dcc7f4835f9ab32026886909aaa95876b98029c37dc4d621726c872d3a9e50403443c958f4029", + "0x99083545034768010988bf8a9f34486c2cd9da27a1d10db3ab86eb69a1dd9c8ee723e7da4ef2aced63c1dbd53ccc52cb", + "0x8ac3209349f0142546c714ef7e9d1b094aab5469b8f080c0a37cb0362da5349e108760f272fbba770aa468e48d9a34c4", + "0xaf5f48ed74b21e3f2c1430192adb4b804dc873cd7e8f07130c556c30e7b78df0ef5a14b205368848fa9185e5a68dee0d", + "0xb8b741b65d68df89443523ba74203226f1e0d13bab073d183662d124e83e76cd318b2bfff09879c04d81b577ac895638", + "0x914abe4282d11176d4f2f08c6f15e6c2d0cde1ab4de00bbe888015c205f51929d97296a0a8d3ca5641f085a29ea89505", + "0x83ec306b2a9a6780efafe799df90b1aebdbff7d47921a136ea8a5648b9708a97231245a1082fea38e47ecafbbe000528", + "0x95d6b58d70b388dfcee4eda0c9805362ccfb60a87603add565b175b2c14ed92999dfdb0d3724ee3e5d30535f282641e9", + "0x97eeb4de607c8306e1d4e494f0d5db126d53fd04983ab5674ec5996b971899e734fa4011f2c889da21154ea1e76dbd2f", + "0x84ff21977fbd873ea06bec444d4ec9ff0e3902edc29dfa25f3bed269b3709e3116e99dc06cc3e77f53c53b736bf8fc29", + "0x8ecf483874a040a4a1c293af145094fedf203a5eb37c3e165857e108cce3e1210e0bfc0f26f4ae5e2194024929ba034d", + "0x97d9b92b2ef34609d69402167f81bce225ed3a95718a3b403f702b93e96a121a8f7f072d0ff47e8b25164e204d1576bf", + "0xab87c39cca1803b4e84b32e40ff30289e3cbbcfbe16a70f9e025643824752359be1f10c3e5398df402b6fec64d5a3537", + "0xaf84ca57e6944332884b5c84750afe0d5950015e127acec161853d55d48fd864c7da8d59cc5aba4ceceac650b813fcc0", + "0xb1d23d98edbe7089ce0a8432e0eb3b427c350fb4bb39eb2aca3c2bef68c432078cb9b4b2c4966255e00e734fa616638b", + "0x8e2b5252e0ea96d40835ebfb5693af49946509975682d68651396d6bb1463f09e75fd0afa04ccea49893b5b9c3e77e40", + "0x8db25e762f1d4a89a9a1cbc61c01698e775906bc88a921b2905735457a35df9ab84bae12e1b1b8dafadd50212f1acda1", + "0xb5f7cd163a801770a4034e2b837e00191b0ac63a2b91032ae9a99ec182d748798df48a14644935fabdbac9a43a26749a", + "0x998e7232e5906843d6272d4e04f3f00ca41a57e6dcc393c68b5b5899e6d3f23001913a24383ed00955d5ec823dbd3844", + "0xab2110a5174ae55ebb0a788f753597bd060ee8d6beafc5f7ce25046ea036dba939d67104bba91103d7838b50e36703d1", + "0xa211972a4f6a0303bec6c86f5c23c0d25ab4df0ba25876cbaad66ae010b5a00aa0c5daded85e4326261a17a563508a25", + "0xa49f53496a4041a01e07f2c2cf1e84e2ee726917bb103fd267451b9b7bb1331c0afde85a79a55409bfde27328b2a4745", + "0x934e915c67c7fc47adeabdde49f63f04644fe234672003be2aa0a2454dc8d9288f94293478936a450f2e3f249d395b5b", + "0xb6e69e9d6808ff7f60a01b7aea6781495d7a20f5b547852d3f0af727a7434209d3015a9dd04cbe3e272918e32e345508", + "0xb348d3462092b5c6fead7e515e09611438db8d69650876dd3b56226e303252bbeb9e9f3b888fb911445b0c87132a1d0e", + "0x8d6510334a905efe5a32001e167f1ba06f9bc4af7ffbf11b7f7bf3c0076b5cca373d8c47e98c1ba8755bb22632bfe0e7", + "0xa2d5200f20985dcd473d119ee97e1c0fafafa0f191185bfed9cac429cef8198d17665dac4f70342eea66e6e4a7370d58", + "0x8dd7eb6b1841b3f33425a158d33a172b79b2dc8a01378e4174e67a1a4c8f4b887f02c7c3a8f354ed9eac718155bcdf37", + "0xb16ca19388642f71afcd9f7007b490d82f83210ac1a989da9d4bf4c419de07af8c048cd301ec7e01b9d06abda7c169d5", + "0x93cb2d847d1a88de8c1c9d5b3c83efd0b7afb3682942bd2c8ab5ef35b33dc31a097a3e181daab8630d4e840b677216dc", + "0xa8b648c769e77a7b41c0c689fe2fba9bc585067e004bcb1732cb7b1618e97b317781c36c23a00680fc780b58c301a789", + "0x918c321100d57712866bdae84edf7e42df30a32853af257e0cb4da028842a43b49e775f3cecb85cd817269c728de7319", + "0xa7b0f6ce42e00c519e69b2c78fd9b75a2e7103e5892d3c1afd70c9b5b9e706180a4bf73dbb2d3eed52bfd521103ec5b3", + "0x90041994af3322b010891356afd8115340bd7fd7ba328716fbc4fe458236c8cad8c7564ae473d6091ec3a54bdab524c0", + "0xacb1ac83809573846231f9be2dc5f3e986cc36dd9574a620b1cced45bad0b11ea957ce8c6cbf964a0af916781c574f05", + "0xac54677dc002698fc4d454c7beb862ad085d0514f92576f3485a44c0cb47afb9db2c085058918a3508f9b3de0137d97c", + "0x8dea56e1bfa150e442f8484b2952b116781d08cfa3072d08657cc09b0217276efc4ab6f5fd726bfd826f6976ced8da29", + "0xa2b09e25baf01d4364b5205fa0c4dea84ef8fe03709113b034f88a0f0a502a81bf92c1d4641e2ac9f3a6f4203d3645ee", + "0xb95fe37aa351b4292691a9c2e547224c37ec2751a31ecce59810cb2ae0993da6fbe5efe0ab82f164462fa3764b6eb20f", + "0xa3498947e91a3a540e86940be664fc82f1e83ff41a0d95eb84b925e820602a41b7393c8b458bd4ebbe574a754586787a", + "0xaa2516d3620c832e5728fefdb1af0be30c871cbad4b166a7a4565af676e73bddc2f2f51acc603b3a022056daad2b330e", + "0xa9251b56467fb55f64c70729e2ec77a59d7eac79cc0b4b25ee405ac02aea46bf1cbc858bc773934a6d9bea57cb528185", + "0xae8c0a4ca7ba6bdca8764bac98df0581f00358db904e57867e6ffdf15542e55f7bad2dedac152ef88038b466ed901934", + "0xb0881e27e52cc6a57c4f3f278dffc7f63a9174b68bc867c16d8a151d9cc4d0aeb703d1074d1927faa9ffb43e10912c9a", + "0xb67138465d6654ded486d18e682f11a238d6a65d90f23d6b13eb6a1b7471efbac9ada6345dfb13e5432196d2a256829a", + "0x944c69a6f1126edd38f6eef60b8a5bd17147ab511e44e8e0a442e87244d8f35236ee0b8d3dac0631f8598f16486a5f74", + "0x995679dbe03dec775da26708cb9200dabcad983825f1ba601eb9395f9da350ca71e8af61dbff4c668fd0eebac7e4e356", + "0x89de362f02dc14de6995d43cdea3c854a0986c605ba5eb5dacf24e3a85983229bc99a2fcf50aba3df59f0fb20daffe29", + "0x84607f0e2d078df22d0866285614f5d78cf7697c94a7d1b5e02b770101ceecbfd53806b377b124a7320d9fed65000b97", + "0x93e3faab60050dac76ab44a29bcd521813e76ec8e4ae22712d77bb489bb49f98f9087acfd6a77016a09a42ddedab2d73", + "0xb7d64a7a35f21747b8e6a874be31ba770c0d13cbd41448411994e8cebb59591295a26bacbf74ee91e248a5b111aacca0", + "0x8dcad429a2b0d66b9eb8c1c3924d7a72979727db6a535526a3518bed2a9532d12aad1c5a778824ca4cb98e3e513f85f8", + "0x980882895faa347bd2fd1dda7b8ee7ed49e69843afe646f677b371eecc7a10e0f4e40bb55f28995a40080df471876816", + "0x89e8e7fb51df79971e2f7bf65783614abbb0d7f3f1b4a15d3f0d160deafa7ed1c446d9a5ae1a77160d4dd94ceed8af13", + "0x93fda8d350392e9c4d4ffe6534f7e7be53f32483d9319093e8436fbb8166a3c01085dc858373e65c7f4d014e0dc2bab7", + "0x897521a87b7ebf7152de5260c0875e3c7df1c53e734c672569219ee6f9bd196c5ecef159b6a1d3b7cd95e91b9b8803ff", + "0xb59affa408a0f7bd7930fa3b88750fd043ce672c10a3adeba95a12f23f0dda1793f761a86f7409ce1e6fd3b3b7195381", + "0xb4422ccc12f4fe99c530cda610053af9ffe635b633d52492fd81271d1f6f91b87171d572d5bd0e46ff63e221fb2fc4a5", + "0xa4542cdf3346ee0867c08d630c2aefc57442f1c05c0eba52d223bfdca5e9d0bb80775cff6ce2e28aa2730231fd7b1bb1", + "0xa7d297bb09118b914d286e5d1e87bdf13f7d174b988e38fb5427902e8e8c674072f36b19055a1070abcf357f8668f35b", + "0x9213b0ae24b7cb43ae95e25c09fead8bdbac55141694137d67eb5eab5e90a348a13d4d4d2cbc6436fc4f4f9f7334ced2", + "0x8aed71a0d116d832a372b42a0bb92a1980f3edf8189bdbaed7cde89fc0418b3ab21a04f5c6e1d3b8edf73f1f62bd6b15", + "0xa6c47d77d714c285c84c6b9458cbec5e3b191c0502dffd10ce049cf1ea27ddf868ef0cff13a2377289fa6c932b8e4f28", + "0x92f45622ec02483f2c1e07075a6695416d3768c8984856f284f40734346d56cb5b3322f20c2c9f0ef8e58ddc294a309a", + "0xaf6450d02b79ac9fc79f35655b58fd3619cd5d38c5317564b453f5f2d79d7a030bf767e399fe01b658a72fbd2cac2356", + "0xa3c01fed5240eb8a61ffa8ff4a120dbcebb53b8e19845949c77fb4f9b2c3dd52c7001df6219ad2f76c785a4ee0f64a2a", + "0xaf3136bfe8f774187bdf87555a1ac505322a956229a285d28bab1c88d4f4d12245af8dff35914a62e90e49f3dce6acb0", + "0xb20e21d28444fc96737958cd951858fda324b924b4d3d08932540fd4b87150f053db6985b96903906ce83dde0578cbb2", + "0xb7978101071268d1f485134b4dfd1e35f89b82c7d99ae91f58b6745f5e0273b7e06f3b23009033ecc3e41b2e9e85219b", + "0x9104b7d75245b784187175912cc0ad869e12f1983b98e052710fb33663224362bffd69ceed43e7d4ad7f998c0a699eb7", + "0xa7624cd71b92699ce3fde0e747976ee04ee820032ac45dd27d769edf3b3379a4b8db358e50c9d057c63b5a9b13d76bcd", + "0x9354a76f294005de8c59db10e638ae6e8c6d6b86a699d8da93143da8478d36116211c788d8285d8e01ea6647dfcaa1aa", + "0xb85935c04cae14af9848db5339ab6420122c041075ec1549314e3c9c5a610d9b794ea3617c50ca7af6b4aec8b06bc7dd", + "0xad6835a62311c84b30ce90e86c91c0f31c4a44bf0a1db65bf331b7cf530cca0488efaac009ab9ed14c1d487da9e88feb", + "0x80339f0245cc37a42bd14cd58d2a8d50c554364d3a8485d0520ea6d2c83db3597bf51a858b10c838bfc8b6bc35619638", + "0xb370420ac1a011f6d8f930511b788708ccf2fe23ca7b775b65faa5f5a15c112a4667ed6496ae452baf2204e9ce0dbf09", + "0x8ceab3dadca807a1c8de58ac5788313419c37bc89603692c7a4d96e2311b7fe9e813cc691a7e25a242828cdf98f8bbcd", + "0xac1526ebc6bd4ac92ee1b239f915e494d0279fbd065e4cab1f1b8a1663f67daa89560f6c99bbc3e63fa845520316d2e6", + "0x8240ab0bc36a29d43ec3059c7e6355ff39567e135f93b243145d3ada97fd1c970743819e0d58bd5171967daec144e7a1", + "0xa99743192a6f1967511b2d3038cc73edacb7e85f84b2926d8880d932d2fa12f5215592311a7548494b68a87ec70c93eb", + "0x8ffffc31c235997e59ab33c2f79f468399eb52b776fd7968f37a73e41949111957434f2c0a27645ab34c741eb627cd1f", + "0x8949d955309415d6d2cf6ee682ccd0427565142c1bfe43b17c38de05cd7185c48549a35b67665a0380f51aef10b62a8e", + "0x9614f727a9dac8ecd22b5b81b6e14d34f516db23a1a7d81771ddaa11f516ed04d4e78b78fda5dc9c276a55372f44c4d4", + "0xaa85d3ef157407bd8aa74032f66bc375fddaff90c612470b5ff5d93659f8c3523b2d1b6937b3cc4201c2aa339621180e", + "0x86f8fe8bf4c262dc6a04620a848e3844f5e39a2e1700c960f20ee66d4a559a90141ef4e5091d0f32acb1e915af1e0472", + "0xb3af2eb785b00588371beb3b49536b7919a3f2175d4817de5dcbf7fcc20c512852ef0f313327fd0589b10173f77b92e0", + "0x8388703c512eea59190351f3bd2cce83ff8bcb3c5aefc114cccf9e9b3f78200d8034c3ebe60448aaf6c912f0ff8f0cc4", + "0x95d0dbbbf08ec1ed3975fe7dd542be0a05156a2b3db5092825d918a849411ee536ed958201f74a5513e9743674d6658d", + "0x8d1a48802f1a2db247e633ddf61d3ef7a2c062c48dda59bf858916e04f56651a7d51e367d6535964ebf3ae6d2b21b421", + "0x971436871bfe868f25247145a55802945409b3150008535b372c949760d7949dd2fdb40d9b96ae7473bc8f6e9b83ecdb", + "0x8ca431728ac0f156763090828a7b6d860bf591e5b9dd3bb3b7f3ba0ca74191f9710ee55efd32db7d18eab5b479cee8a4", + "0x81e28f1a506e84c2b9aba1df720cb50e0b597b2c22f98acc34e710c934cc6f97dcaf33d589e845c2c1f6d8716d05ccac", + "0x8f43b11d3f00c41d16c9bc9bc0c44227c056bd77de4f1ca9a799418c5601e744f99066bef47da2d9088ae88eb259327c", + "0x8d330aa52744c08ef98cc5599eec8b9b4dd18aa01b803f1d1ca0e29b74f1aa2886ed0224390fc377af25852851fbee03", + "0xa06f5b203b67134c685039ec2bdbcc787353e2575ce73a415db24a517c0c31b59d1de89f12b97cbef0219fb6a1e90a20", + "0x9269a5f49bbb8fec1a387b5d105df88a027de615d5ca6afae20fe89b11746f8d23880db78dac238c955fc8bb3de18046", + "0xaf5074b3bc0656421c314547b45b5abd3045ca1b17f5e34ba39d8c1f7928a55d4ca5ea9c2ab59a55909b25255233e04e", + "0x8e7ee5d733c8e08f3fb7d85f0628de3de6835121672c65374905dc6d19e02fa2df14c13d5e9835dacd609a4df09abd26", + "0xa9b9aaf83d31e879dfb8e73a0708801b4dbdb5d7c8654b27d2c0f5797ebcacc8d00a82143e2060f0917c9d41f1a03de6", + "0x904872aa1c093cb00e1c8e369a3bdae6931c5b1ed705dd3bffba243dc4f42df3e7d7cf70303d513b34d2245743d765cf", + "0x8a4d6b3b1d6afe67383c66693f70b397e510be28e3d97dbc8ec543d699b6cbb0e72eb90a7f65e83cf9f7ef50fb18b128", + "0xa914de13916e6a0dc0e0fefecb3a443cca80d83276513b70c22c6e566a2d41acbd33a0e2836ee09abeffd3a4894e437e", + "0xb9c408f5f05934b0aefab301ba22f8254c5ebbf5405b6aa788f76e4b328c150b395f441e3566015a0deb3eca89afe9ff", + "0x8d32aa2c81b2a8b89f347c2e0b6567b2117ddbb778fda8a3f19004b7f5aa9dd814b9b3ad35f9223715d2447b2d12f159", + "0x8230e8b9c84cada1bf14ea6aa9ecdadd978d893cf5962fee6c7167ed21239210ea491987f2c8f2e8cfea8c140704ca28", + "0xa5d7b6285fea51c6f21d0976a7c3a97baa3d733a201bfaac0994db6c65611d91c5fc0ebc2a7724ee02b371e575573649", + "0xa54f00a9530f6930069f5e3a8b8b1d52ee1def0aad1763e3c609ec07f25410969b43d5943a94c235ed5eb207b33a402e", + "0xa8dc6e96399b81397734c61c3a8154e55a670fa25fa5854b3c66734cbb4ec0d8f6ba650ee3c71da3773ffc9e37abf8bd", + "0x8841fbfae1af4d400d49f74495f864804f043416c09c64705251d021b3ab7881f134a00b0241e61010617d04979d747d", + "0x95acea7ff4861cc969c1d8cc8775c5eae014ad6e2e0e2d0a911dd916c34ae69f53eef779cc24ff1eac18c2b478d3ba2b", + "0xa5dce74abcfb8c68031b47364bd9baf71a91db01e45514ab6216f5eb582ef8fe9b06aaa02f17be8b93392d9b19ab9c06", + "0x89e111169e4ae2f4016c07c574a3bdacd8d2f359561fbbdaa3474de9bc24ef8936784dfe6fe0e29a13cac85a3e622b61", + "0xa4c511af6bdf3892939aab651828259e4ef6ebecfdd503ecc14e61001575b313a89e209cb55a77ec19a64d29ada066ef", + "0x923c62156fbf3a44926ffb5dc71f7cef602dbe941a98c61f019a27a18a50c16b6135b6099fe04a2e1dc88a6cad989fb7", + "0xafb9191c541b61afa0ef14652e563cc5a557842ce2afea13e21507dde0ebbe6da5233af949c998c00865c79bb3d45ec8", + "0x8a1f0ad65cb2b225931f41dc53547d756111ecbf5bc57c5ee2cc1ffd61b126d0389d311ffe26cf06eaead95af09c5ca3", + "0x9040b20b5ac2e1a9d30abf7a4eea1ec2db8f3077cb2cfc8736b37222d8d3937f5d9f421167086dc5551e9f0bd2522d07", + "0xb6d888b8c6bd448dccaf99c3f690d47f802e134709ce102fb6f6fc68156943c0762be6f386338163e01eed2d1dd5f734", + "0xb94f0e27bbcda793e4a272603b3dcc739d3bf3207798df7319f8dc9d37cbd850e3724bdd30498c929debad971950223c", + "0x9769827767be9d7bacba1b687289e0794c6fe630d33c9b607da1f6a65e3f34cb8bd65327d9287c8c5f3c8b5f6d3d133e", + "0xaaac72c993aa2356c9a6a030950441de42b2d746bace29865382f0ef54835bc96958b2f00237d805ee6a69ca82117c1b", + "0xa2b1f027d80c1b0e79bfc7dd252e095b436fba23a97a1b2b16cdd39fd39a49e06a1ca9a1345c4dbb3d601ffa99f42bdc", + "0xb3fa0ad1478ca571e8aa230921f95d81aed7eca00275a51b33aadabd5cb9c530030691d1242a6ff24e2d4cfd72a47203", + "0xa43ed4368e78daad51b9bf1a685b1e1bfe05bed7340d4a00df718133f686690c99198b60031513328fc353c6825a5f2f", + "0x965e145711ecf998b01a18843cbb8db6b91ff46f668229281d4ca52236c4d40804ebc54276e9c168d2a2bfc299bcf397", + "0xae18e6efc6f54c1d9230210ac859c2f19180f31d2e37a94da2983a4264dbb58ad328ab3cbc6884ce4637c8c2390f7fc1", + "0x83a9200486d4d85f5671643b6daf3d0290b2e41520fb7ea7030e7e342d7789023da6a293a3984308b27eb55f879ad99d", + "0xb925fb6ca83479355a44abbcdf182bfac8a3c7cce6cfc7962be277ce34460eb837c561257569be3cb28023208dea80dd", + "0x9583dd991b62ae4bd5f379ccd3cec72cfae1c08137ddfbacc659a9641e7d5a82083de60005f74fc807bd2acd218d0789", + "0xae73bc32e9ff5926e1e06c07a3963080881b976c9875777f8e4cf96af91bf41bdbed4bd77e91253b8ec3c15b4a6d3977", + "0xb2a3ea90aa398717ba7d8c46743e4c487b63c5abb140555d8d20e5115df2f70d3c84a2cb9a5e0536b2d93d24f271b38d", + "0x91d119d3bf1d34cd839eb69c6de998b78482ab66bc93fa97e31fb9592f36cdfcd673f52366f8c8e8877e313b92d4a2ad", + "0xa1907e20120902cf68912cc3046f8806cabbd7673e80218814cb088e080dd93b5dccba395b13e0025f5755c183276c3a", + "0xb2e2011df72504065ec4c12cbc2137b95cfcd1355509671feb7b00dbf7f8d500476a49754cb7fb9219cb5cba7c8afe01", + "0xa48589fb7a74a3dfd782cb3503e6294a81dbb6adb412887569f9408e9079371edbd9822388e0b7ec8d3297ba270f53ef", + "0xa203909bfe196ac65ed3e6800d577b6ca5c8fe1d40f7f925a43852951e38883f2ffd250a9e16fab3ed3dc1249650247b", + "0x997ac293722a8b98f7e819f8e6c2d4c5bd1103b82d489d8b8aabeb905e95450b9b75bd61442cf68cc957212ec1c55617", + "0x9895a3de62395c33509b153b7820bd94fd2b011f0cac135fcf916482f1eda272ecc79f83a61837e99c3a3c4ab2c5c2a2", + "0x98c2ece4d49a64ec8e06407a0585081003bcef88af35210e22eab91169f8f0c044d611494b755e5bd915804b1d857747", + "0x8bc6dd083b36d076ddf0e0bb1bb87cfd059283ddabb3886f02eb7e27f1f0539b2819527b56b5c13436523c4603ac1d12", + "0x85ab8b7a696333c82dd5e179e12b2e127e67d911de609ff9a03cab95cbeedb1f364aa1f2b5e59353e4ba0d177f996151", + "0xa9478e214afa68c395aa2c7daf8ba1627feb71ad6d8bc7339734cdcdd5a42838e032736c28e6251c808d5a4875ef0d06", + "0x8c53f62cf06a35321c8af3871ee4459768d0745ebf48942b9f464206309f42fc7b2c50f196ae1e43b664f0e2e718a23a", + "0x8ba80662f6642d8866e832ec8082a4204ebc993fc304c4b794666856de0407620131a18dc053597bb40a3de0bf8aca22", + "0x8c8fac6b911785d1561a985580c03fb2ebc613ae33e486a92638aa7d4493374118d9a6d9d99121e29c68c3d67ee4e3f3", + "0x90f2c793eee07ad90157040b30558bb3b0164e8ddf856389d6742cf5bd1c712e4c6a8e5678da70a8e9e242ec7864117e", + "0x954abed8f6d58896b7f6438c9780236c1c83b02d60a29fa7361559e619e5bc9d67b3646ee39ffafe2b3019bb3357fb50", + "0xb79874f757a33085e1e751544de8fe3afbea92e0234f9c00254c2b36115a16ee46f085f22aa66e0c9177e5106f51b03b", + "0xaa148b287cf4f60c64f774282b421aae075f0eaa93a45aab4927750f47e2ef0b811d1846bbb15eeb2f293c80a7612e83", + "0xa588d8825e7b0168d45499dcff6faf0dfe1ba4f090fdc7c06d50344960c0121f10ad109b0b9d13b06ef22de5a04eef87", + "0x8f61ec93d14ebfa9c31731f9ef0fb8907505fedc79378e9a3f65c27bed4d74b41e129c97672ce5f567d897befbceec8c", + "0xa008218633f1da10efd01c155f7ed739faec902da6dc48e9f19ccbc8d32bb318d71806285cf2003de2c907bbdd4f8b22", + "0x88ad82c66f7085632d7e348d69da84200c53594553acf5432b50dd1e87f410c802dfea91be3cf804e3117ce13103f23e", + "0x8498dba17de0318af227a3f9ed86df37a5c33f9a538be9823f8dce4efc3579e8296cb3b7200cee7c5e0bfd9da23a4b69", + "0xb3c0342231dffe4c9bc7d9265597bc8cc4a82e2980ac6d1407108db5b00349dc91d5116fab51cf2802d58f05f653861d", + "0xb3f2730455f9bf5a058598bc60f47740117ba51f6a767e1134516a4e42338b513f377027acf8825da5c4d047a62984fd", + "0x816360914fbc9d8b865157bfab07aeb7b90bb5a7c5cd64847b1c3184a52266cd3f8f8f3ef99309ba2edc4622304bacc0", + "0x8fd21b2315b44a52d60b39ebc45970a47b9495f42b88217ae057bebcd3ea0e2476c0c3d13de7f72016ae12ae966a008d", + "0xb62014485bc217a0fe892ef1aef0e59604ad5a868face7a93f77a70ba3d7413443fbe7a44552a784d8eae1acb1d1c52b", + "0xa905822507e431b35f56724f6c8d2e93b0607ed7a4533073a99cce2b7c1c35367382447073a53036dfdb0d04978ccf2a", + "0x81672e39c2b31845142963351de3d9cd04c67c806fdfe77467867463dbbd8a9b0e2400ccc55016e57cbedb02d83a0544", + "0x90919c970ec668de8ec48a2a73bb75cb94f0f8380c79a7909fd8084df61ecd631476ddd474b27103c6817c8f3f260db9", + "0x8fbe37dfb04bf1d3029f8070fd988fc5e4b585e61eab6a8b66caf0ffef979d3ed6a662cd99468ce98ec802e985da5fad", + "0x950939aabb90b57a3d667f9820880eb0c4fee5c27fe211ce8ecd34663c21b5543c810b3676111d079ac98644c75ee0ae", + "0xb06201ec3c3cfdaf864a66af128effee8ec42d25f1e173c1edf9207979fa52c871757000c591d71a9b6cde40f5001a06", + "0xa79054e8febd0450c96ac7a5fd6bf419c4b17a5926f3bc23a8616f0cfbc2849d97470174cd1baa7c739b12615334b6b7", + "0x81c7391b2a1844ed26a84f054b5f03865b442b7a8d614cd44805b5705fe6a356ac182b66a3c8d415132e389efac5f6b2", + "0x825af1563d0fe53925ec9ac0df65d8211b333474e59359bf1bde8861eecd03f2ac74534d34b7e61031227c2fa7a74e1e", + "0xb60dd9bf036f1825295cd2014ef1f6d520cf729b4d6cee0b42cb871b60ae539b27c83aa3f96ee3d490ec27ce7e915115", + "0x89ca43d5b7f3622b42df7887572297a7f52d5204d85e2e1ac6e5d7aa7f8aaea5e3a07280477d910db025d17cd2e7373b", + "0xb93a2bc9b1b597f0e514fde76ce5bfb6e61eee39cbf1971ea6db38c3ecb055e7913ec8cd07fb0b0ffae3ca345883101c", + "0x8d45546bc30266b20c6c59fc4339eb633155aa58f115a8f976d13789eaae20a95b064fedead247c46665cc13ba856663", + "0xaa8eacfe00e8a4d9815de3f7619d9c420629ada6489933ca66a571bf6c044d08b391e0d9eec7d1cbebe8def1e7523f1e", + "0xb32fefc59a0d0319ccb1946b351ed70445d78d9fbb536fa710d3162b9659f10288f12d82b32ecc026d55f16cbad55441", + "0x99c7c45c34044c056b24e8f57123ba5e2c2c039e9f038a66899362840cffe021733e078866a8708504cdc35816cb335d", + "0x80def162c134540d5ec071b25ccc3eef4efe158be453af41a310b7916c49ec0ce06bb43dfee96b6d77339e11587de448", + "0xb5f2fa4f68f6a26bcb70d8eab62ad73509c08ee7aa622a14b3d16973ffff508ce6f1aff9ced77b8dcfef7319245cf2de", + "0xb4d0436019e779c789464716e1741c189e8945dab7f3072720bd9aa89882fa5b085a1755c48da21541f3cd70a41b0a71", + "0x931e798ef672e1472f4f84c727a101e70d77b3a9f0c0803a5220958d6bbeb8aeeb56c769ab472a3d6451249a13a3f56e", + "0x918c10a84de268aa8f1ba24b38fe55ff907be07b1e86b4a4adbf305c0d705c1cf5f65ce99e03e11676cedc89f1a4f331", + "0x8e55a8413b823715ccd92daee357cedd797e69a0e78b6fcdacb7318646b9903dfe05e5501f47b3c52e74055b9eb619a4", + "0x8b329bb63e6c985d7d072dff4680b3f8b1217ed20543277386bd30ec25240d9dc378837dcd5cf4fd9548658635f4c537", + "0x8c2be5386052b22986b33dbc63c5afacb6d0095495564ba4aa28fc8c880a3c78242fb083248d788ed928deb1e30a82c2", + "0x83a2b7bdfcbd25d6b059f27218e009ecb5ecc4da68ead885e00216411d8222062ca42f21c4d9cfa19c31522080af677b", + "0x9620334d2633e85646b2e2fc48dc6c3f09c64ef1706ed78a3bb6ce1f6b274a727364df71e97531dfdcb392f70f27f536", + "0xb6c84970ec04545121ec3b79376f4e45053c97e8bf2b11922cc2490a429c38735466097ecb81cc9d9692c74d2fb8abc8", + "0x8e55d707dcf265c5ae29a32c27ce66f200fddb724faa5bbf145ef42280ef645fa2f0cc3cfe2db8599b26c83b91e077df", + "0xb910b96b763966402bbebd68a32c15a225ec21e1357fa298478c5981a4310e556103fef0c73bd8903e11c4ed2c065647", + "0xa8fd933a0e9fe8c459809bd93b8ce153e2af55df94b61a1490736b19c89469954da8b72dbd072d798fc06fc3d7a3d60a", + "0x811b279c113828e114fd82c2070caa7eb089a46c8cabf865f9c77354a77ebebe0c4c6400dda0e66dd017cfc44d76851d", + "0x8ed03e91c331afb3ad6e42767e1b3e8d3a35fb831805ff1b5fd3e91878e04027ff5af1165a3ac295f1578faf2c83b581", + "0x95bf53683d64a0621bf1ca6ee17446783f6c535b7a54d6ea57723487a215759a54f886597a55dfdd560424e368ab2759", + "0xa9bea378768fb1d7ba365a16531c51fc1975f1c73caf2a0891da28509805fa84e2a8db7c6ccfbc620e9002317abf174c", + "0xb8308250891015deaf851c4e5a4cf4704d104f94064418488d7e3076d49f36240dcf6fdcf83f45fe8a1d97fb02e3db59", + "0xadcda6b63da21f4074f142f8e7f3a2274f624c733e3a4001054a1809711529c61356aa087f73aed877a58ccb41d38d12", + "0xb80e7869239ae26d1da2e6683f064d1dc93cf4a2b66e9439b3ad9b25324e969bf98014760d29e6b8de7ff152ef498d0f", + "0x8e9bf968911df3bb5e3a7655e9d8143e91ee87f14464d7ba9c86e1e31b03ab31b91eda121281b79cd974d9ed2657e33e", + "0x9007277e8335a43e6bc3c2f5f98c0ba7024a679b7156aeefe964f1a962e5ac82154ac39d1ffbad85a8f2440f3c1e354b", + "0x9422b9d670e997b7c919a429499f38e863c69c6a4d2bb28d85e36ae0895c620f68b71e39eba785e3d39a45be91507757", + "0x926094e01132938000d82dd9a571fef5ef104cd25b4015a25e3442af0329e585aaad5472f0e7a69899ba2d6f734b40aa", + "0x95552d8057f7e32c24d69e4d6c51c98403f198a20c5be8826254d19cab2f84d5758e2220cea7e38b7c8a7a23178fd564", + "0x8abcf8dcc8488bcc9ab23c51b9e7a0d91dfc7bebe88b7ed370ee68eceba643e939c5eae66a4aa5fe85120751780e351c", + "0xa91bf8198f029e6a4cf6f0cc39b629e9aeff1c77b8739e1d5c73d8c1d3fb5c8f6f23e27b435bf10b5b4ec1cf6a7249ed", + "0xb932d87ee3a4b81341511f90fe5aa36c571e8b914f25abcc33dd40ca67a3f6444fe9362c1434744e4af18d6e045c54a3", + "0xa8e960c2be9b1d805d387b3ebe2134d421a65f1fd4c1b4cccdce78f9926f139eea78e3afb449b3d6dd19b5d16ace48fe", + "0xa7e2f57cce509fe66707eaba9b4c042c1be93fd6034a9b51d1d30c45c4363eac79d54663d525c9873ab0eec0b1cc4ed3", + "0xaa162a31c2078f4b080199debf24494a8dfdfb9d8fc85b198a861b12a629c73128c55a883e4c2de3dfed6e0e1b83eeab", + "0xb5a4d075433eaf4115717a84b4dc37f843d44bba0bf820c92ecdedd5afb61be60f7708c8a151a678d9d5c0ae531bffb7", + "0xb56ab96f7a463c0079e05dc766f3a6a31cae5c5044947734ebe0a26e01367c6763cc8de6c2ee2f3b8218f05bef217474", + "0xb60792ac506b901065a8bc0180a86e028fe34b62ceae1ad640c759538ebf3a2ad9c8c927d662deed6f489ff3ff7813c4", + "0x8c8c2cdf075504d12d441a58542e1f8e4bdf92b3ee4775e836b2734c5ec1e3df919b931386417d04489a1dca806c87d2", + "0x8ed78e91e5c4a68894cefc2f7fa71f02e5e12d40f1bb74332139bc7be4d92c24e07d5ece0e82150ed474aa1337af4c18", + "0x87119c22ff8aa31150bde537d863cad661cc5159b12f084cc319224c533f0deb28526ed8568d00a1441e7d8bb4f05673", + "0x83a60ba5a9cccf22cebadf7318b706c9f29abd25db0e2fc1c802965351b53cbf316df72ee3e9b2d3ae7f3c4494cfdff1", + "0xb73b6a9fdd3e7463fbdaabc9a885b7c82201ad867d1bced1c2484300a01cbbb3f1e21afa95d4c7cbb6cb983416b63b90", + "0xb1d89ad16981ff9217708090d4017662d8838f21f3a3296cffe14590b533905fa06a20e40dd497bd291fa4dfd1bfc511", + "0x8abde560083e071a402e3c7bf31930f537f67d2a7bbc734a7480b1b760aa712ebd1cbcb65b00e11e384e980222fe14a9", + "0x89c731d8f31afea8bdc9c32527bdca257f2a840764d40f6e49403b8e75ae51017d505ea4fff91bf28b6f3a1bc65b8bbc", + "0x80e9ac8e077e86ad050ee73dfce268a69564ff1b8419e9c236d981fe7a5f0c2bc756e8603ec604b3b9e36da8fe10a49c", + "0xb4f1eea0f304898b1323c6382732e6f40e556bfc68af9ce73f6d54e92f5f23cc4f78eb3f43d578d81e7627fb40f092b3", + "0xa0e3a8d1348f8f153e08ac4839232d75d1d6e81b5de184ec4724f8213baf98d3fe739a96f6b39d79a053b628c3a09981", + "0xa6915ba0b52ffe4a381bbb8ff3791d9d3b848bf89b3bacbb2a7d2e5ae21f1353cdc304b3cb6e82416f7e604035c27d7e", + "0xb2c4c9cdfdd2fc9a340ba3ade9423344b9f429e8c7e20a8abbf26400376e312f3ae35d1c456be99dfb5c02fc8a36cbfa", + "0x9657d57ca0641825a0aa5687f3f87659d893f33aee819bafa5b1ca1db554811c1c844f971e278606e3a2f096defdc67c", + "0xa4ad24d0a557704ada24d8e27a15604bca28679e260b2c69ccc8e6cae5499866724b700605a90df7dfb35130756939b9", + "0xb18d9ea6682f73a1f99a9a4fc98c38fcda02c1a18e8c5fc080cf935a2ac877dc5223fca273dcde190b906178d0fd05bc", + "0x8ea5fefad0799c885f50ff10d94bd0af5b99b0a446cd1f367ae5ff529cc47e09f3018115f3c0ccac2fa05bb65b84945e", + "0x92450d52e6c7d13ebfcdf5674d6761bbae2fc5aabc865d35d031b588c383e0a64cf69a73dc93948632e2b98f74a5ed86", + "0xa356f171a98df4ec5a96d556eaccc6ad34b4238aafcf0e94ece27cdbb491749fc9692e78b84dfe80bdef2914079d34b5", + "0xb918703a4d3507d266414712ba8eb7ad17da07cc5f952b5c62ef130cc6ed1ae3bf01237fc8848c179725bdddd465b301", + "0xad2b0554570bfc9d97510cf59bc38e10ca54a93649c30ac9919bd0255e43bf525ab11b74f78a51ac0973cd0c5a5dcb54", + "0xa7ecaf4b631d179d32ac1632390d95196a0035e00da6c0e6e13b5c09ae44b15ae6c21538b5a31b73bc5f650ecd979b59", + "0xa37704eb4d728df2a367e59fcb6c26023136230e37f3b8a2f3ceeb1467f5cd30186fc0116f98b64a8146fd2c5903e8d9", + "0xb09373ce92314678299ae10ec1f93c702911beb4115c6b5ba6efbcab9c7afb599f59793912df70a98868bce6545a33dd", + "0xb52a878a1393094fd2b93f2d1eccabf2830ab10800ba4cc24dcc7849cd0978733263aef2fcb766a7cb575a7a99383db8", + "0x8dac097e006fda4fb9d6d7ae52adabd9448ebc8d5bd5b38ac0c4ed38ceb510763174f7adfb0b473c38e52147ccab4239", + "0x86b19c41efb949937d74a7875549ee5e997f9fdac7f7198085afda233cf74341a38d0ca3767c76cd35f875b89a35f78c", + "0x99f0d927e5ad25cd134f1c70b72631cc6b5cb4ddb86c0642b900464e33d971213a5239dddaf71f7a42f2d6d02a12dcc6", + "0x8355c38806c335d747d4e97f0083fb96585677da18b409a85175ec35dc3f74671817b34203eb18c2f729717ce083ede8", + "0xabb3603adb061a036eae0afa5f23d79c3b62442e0e3bcdeef896f88995585c1105cd3065410368456a4d36b5b0485a83", + "0x9051c5c0011784885187d04749f774b9b4f6bc594b0e4e18226de79dedc4d7aefa3529c3d2c728e180f96f3e204d578b", + "0x91888213e7d321d0bfac884edbd5cb756b280753bb5f8bc6acfc208f525757beca24bdf86fc68d3d8736ef176a960b49", + "0x91258bd7ce6e3b7516fe2f5391a368d826da299e0e99b1f82eaa44b62b110ab696adc92debab8ba098a52f38dfb3c5d8", + "0x96e3907340dffa9da3602d3b94bacff7e1bb8649edd3b9bbd06e1bc6781e78f91ababab12c0b9be7c66dfedc7001b66e", + "0x9513555688fcfb12ba63952ab36a67b36affdd71f7b843e8eb99ccbd45421698024608233efbdc905eaeb26b334b33af", + "0x9913ca9bcf11eeb408da02e4317c5ca0010fb2f4490b282ddb758001c08b438c3b35351a8cbe10b7fffc1293ccd22d4b", + "0x85dc2471860ebca88e5a2766161fdd77f926d2a34825d1134a30418f91a741759668e32fd1e37c415d07ab5824338e8a", + "0x8b128917e828a0b5eb6fa8ed72b52fae2dfaf74febee69a2e2f87e8df702f0c5bc0fb620c8d1d2a07f35a15ec9c0f5a8", + "0x964c39e7840c130b01bb481ae7bfc92682b0f124c9c383f9dbf3027f2249151925f4faf36905af476a54778d69da3f48", + "0x80671ece658cf850e522d46d25678f934ce6df043f25f8707235125765d40c2eaaf39eda6092f75039b22cb58bf2c29d", + "0xad4bb0e79fdaa340b1347a46b0f64e801c72a89770dda0a6e4bfd35f2df5146fce9934e4baecb1c2671077c771eb8089", + "0x80b3bd3adc6cf198fcd997f8867d2839a2eb28f57390352ec423b8a14cc1f2ab21c6e286505d6a21fb134dcd8d8f11cf", + "0xa26d46a6b8a75748895a1d599e7fd120d896340e79813167a400b2fe463452532a4cab419074663fe1d29fa716b76a33", + "0x82b1f3a8a1df29207d7ff020809113ab06080a7f0c631f76ad33f47cdfb6a567143144df97b4ed7f676d929195b04bba", + "0xad96633a3744648ff0a2e4491e8219c9c6ba6e655cb058c36320a8f72cd5f72c00bddf97083d07650ea9ddc005fc1ff4", + "0x91d0783788626c91662359dc3ff36a8bcc6831e3f4114f85c99910256b1d8f88a8612f53c7c417d55581dea486f38926", + "0x84edd9e87ff3d193ebb25f43474c33fe502a1e2100fd3f93fda6520f5e42214cc12e9f8045f99aa2423a0ee35e671854", + "0xb55e06a4b1fc3ff9a5520e0b7c8b5ac11b28385cce78d91ce93b82f1bd7f7afdd4195d0c13a76e80d0ed5a4f12325fa7", + "0xb0b15c7ddede2b81d9c835ecaa887650622e75d0d85f81b8bbec7ef24e9a31a9c9e3de1f382d8c76d878d1b01373f6c8", + "0xb1adb47c20f29784116b80f3670182d01b17612d5d91bd6502b0dcecdcf072541f582aafc5e7dd9a765cad52151684f4", + "0x8efd1018df9c9e9814a9c48f68c168551b999914a6719229f0c5bf0f20a288a2f5ba4a48ba966c5bffb0fbd346a4fcc6", + "0xb34ea2bd3269a4ddb2fbf2514401d2712fc46c22642f3557e3b9c7acbce9b454dcf789573ede9aa14f39605fdd03f8c4", + "0xa9e1428ce24eacfc460aec2e787c053327ba612f50d93510d58b2cb0f13291ca3d16358325ab3e86693fe686e4f526f7", + "0x91eac7361af4c66f725c153da665a3c55aca9ae73ead84ca2662cf736fe6a348a301be1954723206dda4a2120202954b", + "0xa6f02db89739c686407825fa7e84000ceedb9bd943e8a0908fef6f0d35dbc33c336072ba65e33e15ecfcd5714d01c2f0", + "0xa25666faa12e843a80365c0fef7d328a480c6e3cb7f224763c11d8cbabd0e7e91a5b647585ee905cc036afca14842bae", + "0xb4348576439cd2e48c01cb9cded7cc4a0ea364ab936dd679ddc7d58b48807e7fab070f2f1ea88595b11af4500849026a", + "0xa8c6c731e0d0464ef7e4fc1b049065eb4ce100c01e1a376365c636a0b23851022bf55805963bc15eb57434a837e81167", + "0xb0952937b154e3a4c206f96cd96c76ba37624956b0e4d43470bdd97b4af878326b589e3eaee82fc192437123096799a2", + "0x97d07ec31ecc9923192e48d37df2cf08750050fb452dcfbdb350fbc43e146bae3590c5b732b31ebfa1ce5d884ad5ad57", + "0xa69359aebbfe4cbc4d39d178150039fbf284cbc0edc68a6bd635ee3a1c76569a4a575c907fff691b2a4d82a384c2945f", + "0xb321c2c0f6b5902ee9056cce7404d858da9a573d27348c1a6bfea29b2746f2aee7abcb6192504e5a583b0caeaba117d7", + "0xa74e738aa6eb4eea58855ae6f422af22812fb388c83aacca5bd5fa4a88d4c01463174a229aea2830c348dd9ab9307854", + "0x94306a3b106bc1644346bc45c05cdc8287811d5c86cad691bde0c65d6a686eb9c0ce79ad91baa4547e5d058ae8bf7310", + "0xb64140fd77a07633e4ca8d60786452311dcdb8ce7095ba51dad8486f57c3bf4e69bced92603f71da992a48ad817ab275", + "0xaffe7f4310f1dc68e5e3cd640bedf864f51bfb46bb752063bfc18e95930021f784e509261ff9c560f53000c361b142d1", + "0xb0d2fee222c6f963ba3385547f921a48964da031d737892604f8f2677d4905dbf615046db57eae6c6dd756709ae6932a", + "0x81700c66aad7c2e51168e028b0fe086dea75d3b17d93a4dc1f47a6a0f025df0bae1c8c997901837ad859a84197e7bb00", + "0xaa4ac5fdd602f8b79cace18690e67bad557a93d00c0e295074185e8c6b4059a65495d9971685de2fc01d2171ac8b706a", + "0xa8becb3a64fdf35d65d2857898dcf8053b5057a73ab8c5bb5324af1a8015cff47efb85dc3eae7364cd5c850b7962bedf", + "0xb72ea09bd0b72f8cde3466f359ea69b194ede93dced534efba1b9ebc6f3bd53942fe2965e992e82edb6050cac4ed88dd", + "0x85bb8dd7eef023a251fb6f220af54687747f4c91983ff728163c4618ffac40ee6edc29a0aa6d455276bbe017f63757c2", + "0x85a485254a11b4c4a943d9ec509c0dd1cbfc0ff5273a00cf5c9f0babec973efb15348e5d9451b548293d778e3a2b62a5", + "0xb109f3ac809391e772b589c196b013db69a9b2b10ac3898feb70b986973731f30722b573cd0c9324158ec20416825385", + "0x8a4eb579a840d438bed008644f373ea9ba2f28470d50cf1d70af38ba0e17326c948527b1719dd1bd9ac656ebd5aedd10", + "0xa52e9d66ead5ee1e02ce6108e4ded790d8ec83164a0fa275ab1f89a32200726c8e988d66df131df9e62dd80203c13dce", + "0xb541cee9febf15d252475507e11d65c4b7819c26cf6d90352f5e8a8f5c63e254eddf22df0c35a7be5b244233e8e4ee5e", + "0x8153c297772adf4603c39349142f98cc15baeccaeae10c3230ee87d62255f6814d88d6ed208c368d2c02332426589748", + "0x970dc9782f1828474e9fab7dcdec19aa106725465a5844caed948eef5c9e48199c1b6bc1a637ed7864116927e84bc65a", + "0xa975a920624967f4ecc77ea5d9869c434caa64c330024194615a8d0640c5d4d4fb139ea11a0c73a5c6ae6dd3fbf0ab5d", + "0x811f0f9e0c12acfb4b9dca359eaef3bed18083bad96188befc036ad3143b121fff4777ca6dc70a835bbc4921bd25f5ff", + "0x82341c6ebdb97c8b72910da95c7eebccd1308b6a92999886aab552f0642882d5c7cc60931577d200efd6066530c998dd", + "0x860f7162c2f5fd1c0953c6ce75bd8c52eaa48032b914410681b8cc05e00b64130d1f96ec5a52df66a04c78a9f9f42981", + "0x8a578e674875571fe1a0459843495a5ee1d9fb6cd684b244feb9488f999a46f43363938cd0542879ea18ed14fba10a6e", + "0x8df217aba4da6781f0f5139aced472025523ed6e17e504511c04b677ca8197488e237d8bb5dff7b6b3898cd5a6393dd5", + "0xb2c9230ad35d7b471d3aee6f771517cf3145ad26200bd6fe9c7cf28120e2945fed402e212d2330a692f97bb9ac4dcf12", + "0xb78b89e29e8b782603b222cc8724eeb83b2d9d56bc02f59a3c899ab76429dc721358b07dcdaf422f59520b7e7ab4fb55", + "0x82682a5617843c4ac8d4efb4c3ce715c76c1da2c3bab1ede387db503f3489c1bfdfc07d9231d96f955df84fd225bc81b", + "0xb0f53725cc610e78b8e8a4e6823a2ffe44dd15a9a5bc8151ab7a3787ddd97e1d7f2f0e6efd2876e5f96417157143e3bf", + "0x92c5a93233085e2b244519078770c7192af62f3562113abc8902f9d72591eacf52bd15ce78653ab9170d5067606287f8", + "0xa43ef97dcd9b6ad288846bf31fccf78df72f94bc7ad768baf5bf0d5dfa27bd74ffcc6b6c6ed1d1f09e09be3afa5eaedf", + "0x817d43bd684a261fb30f709f7926cc4e1a31fd3a1a5e7e53ba4d664856827b340d7867e23d55617ab3514c8a26a7040d", + "0xa599e22d3286b32fafaaf79bd5b0c5b72f6bf266ec68948478f055391336d756b58f9afea0167b961fd94234989f0f02", + "0xb70db7d8e8356df2e2070f8d658e560081442f3f3b95e20f4bf30106835d76161101163659d5d12cc0f335fb042dc66e", + "0xb8f725b70c957aa3cd6b4bef0d9647393f7c9e0b7343e92439372f0e9aa3ceddd0cb9c30be331742b87c53f2eb030593", + "0xb2fb5e7762f26036e7e966f4454f886758804d1f4c2da17f3d13b0b67ca337f1fd89fd3cc798b07da6e05e8582c9537b", + "0xa377f944dccc300921e238ed67989872338137fe57f04cb5a913c787842e08b8a1adcfb4d2200abdc911fc1c766a7092", + "0xb82e98a606071c2a33f2ad44e7ace6d9471d5434500de8307b5d4e0083e3a5cbc67f0609ca8055f0ea0ee7501b9ed916", + "0x8e58f9a04d33a41ace4944615041662dc35057e645f63e127cf0d70f96ac307d33a62ce98f164d6eed8536c1a747dcbe", + "0xb5b11388071ffbf57ac47fc195736613b964ebb91cc8e2c17b32646f91d64ea506282b881897fca96c317364d3290de2", + "0xa40ee9b7551133856cfb3904837f9949a9558e59a418898affb78adf1500fd6ef6328fc4422161909aea2c79ad08c14b", + "0x81f9eb4ef28aacdb43e11dfc9aa92ba990be4d3c14b484fa677edad3a3fbfeaa859a7f9322b5e95818240d7326215abf", + "0x84939b2b6bc859437d1a7a8d6ec9a357c6b716c4b4cc22abc274af872655940cfc72c99f5d0283d90e05191fcdb1c232", + "0xb78a5b74a90a805410b6225fb9576d6d73752520f25cc3fd1edf8ea9f6559d3080f9acaa2246809b6a66879cd2ae446b", + "0x8d0a92baa88bf38dce5385ccf15d345b28e2e5d0a2d469e689353d80eaed8e8408933816d70ad752f226c59a0d5b5f0c", + "0xa7e15f8a8c1655b7b346c9488cff278c793505379b781b31b273b4bf09b3bdfca1c8ab2334746075d636b2e05859f215", + "0xb70daf14f2adce03c7b92d6aa181f0c507a80a37493d8dd12419d5ed5f943a98099fefb46ac827d6e4efb9b8233c99d6", + "0x8c2480814661744d116fba7355bc6b1914975e44cf0e976d50b6a20092bb1c636b7b44ed3fe8d63b5555ffc89fa759d6", + "0xa6059528a4fed36abb74ab992b22a4f9bf1d05c5de2bfe6837b9af1adfed98bc37ed7481b5a99675d432743021fcfdb3", + "0xb7e19f1b25bc159e5a769811e773c3a8ffe8be8ac77ed0b711540915e5c6e7bafdb407cf9b85c551f67fd621ce8142a5", + "0xa2f66d4f7d16ed3e7ef5fc90b42676c61a98ff18bd26ccce91de03b6a0130c1db17a6bc57be135e410a76d2255b15813", + "0xa139c916927dc3d3fb83598da9217ca64f0ae127215332e9a7ed82be923b89a801c44580d5617297175f9dafb1c4eaf3", + "0xaf08e1e1b04ec95366a12d99c80a9a9ac40ac984a575dd0230cdf4eb346a7686da55ef0a276f3356f814af31f9cbf1aa", + "0x98840aefe287369221c0721cd7c1b15b1d670c3cbbfda191cdb5434bcad757e59c30ec82b2d8c75947405888d44da435", + "0xb7c61c8d42daf2e278a12d8f6eed76090b71c82275f8b33504aba75d95103840e8acd083e97a5a5aa79897876a68940d", + "0xa0264048d2a2061d32eee4f661957ff351e78436bf49ef973c059612874ce9c91970869d011dc13a5b7c754476880a68", + "0x897199a4d8db8aa2db5d9be3d4f4312e41fa0739eb06c62e2e046c4b9be829a447e5d47227e2d96195d3b7b66eb59da6", + "0xb512a9082881f5dc90b02f8bc4f38b133348c2e933813852f6a8e7d8c270c9ce68a5524af7d1d3123e53b2d02a53d465", + "0x80b332469254a96f53c95ec79bb5a8bb1c387d40e58b73d72f84384c696ba0d3c81d6ac90be2979c364c44294e90432e", + "0xab680c2e547ea5cbf95bf813020beb461d50ee4341dea944eb48f6a8584d35682d20186e3b190b849a1ba25625a7f499", + "0x9070581993a0531d6be372d370c2e4ab2ee53f30e04a75ae61ea0fc2c320914506c4d2d4b4487c1f8fa88356fc45c895", + "0x8424303dad6b4051ab633ad27ee51783b2ead61c5a6dae1eb3ed72fc1f36e2a9b1f315504a4bd90f9664091f2f403d4c", + "0x82225611eee626556553b9316dab4043aff241a81826a33aebd9864a91e299b765ba1fb43eea2c2047e6b75b6d7fe3de", + "0x8a3fb221c616ad55c352dd5e0c09ee892022013d6965aef40d4f277a42e9fa01226fe973cb99aaf6ffe4f4f348fb54d1", + "0xb07c07679aa51713e8a7d7bc304dc15ed5664b66bd371877023f3b110b3927e09e259ef22895c4001421a69c6c013cc6", + "0x83556c76bdac0dd8db6da231b863c335be076e7299802eebc259e0818c369f933a4a4b18e2df8ca07e82f60767b462e0", + "0xa516f659b7915d2f7cd0f0f5ea2491b15f0c84dcb191e7671b28adf7cf14a56d42cfc0da94b3c269b45c535f6eeded49", + "0x80d7cc6f26066f753041b17ff1bd27f6d4b5603a43729d33d596e21a67356db84ca9710158089def425f6afaf3207f9e", + "0xb802a47f9009dbd48851209ea1e2739020e717f0ae80671d9f97a0e43de923273f66b7fcc136a064c8467372a5b02d28", + "0xac92fec1864a8a911633f377df87aab56713876316d48240fefeee49ab97f7406c22e70f4938b5912c5c4e766146b7a5", + "0x89224225b9835d04428b0a74edbff53dee2be285ddd1e5a3a8c37307c0500578155f0c4052e4bc8be04c56862fac099d", + "0xb1d3c8492fbf22ea60732745edd3b0163ba5a20d1a3315e3773f2540ee38cf308d42ec72cbb3e3dcea457d1d132c3904", + "0x8bd00e38ec30ee6c44a0e5b222f1f737c9ed2a4bb9225f1741d6334df966318c8a0fd2fbb109557fe8c9479694b8d8dc", + "0xa930ce5454efc0b247dc148aff869963fc5c240241d5590415cbd36634801a04d3873d93635911bb9c0c42ecb005cc63", + "0xb83d4f80e9e0fa47b42175df74935ba8aad2e559b80e84478ab1685bc3eb65d51b93e5738d5ca968cc055ca0c552a03c", + "0xb3ae21258f98051f13af3878b8103bc541fe6f20b1c3f8fb4689ddb8800b3c25cca9b55f0a4104bdf15dc4d5844abb8c", + "0x831ef8684c1cd446c58c59d0152aeade5cc305bca6aa296b92162615f052ba280fe289edd62fda6d9f0667c186445f52", + "0x97bf9659b14f133885916733b7d4ac7e215495953caba970fa259f7bf6b79e661090ec8d79e1c9ce8dfb17e8552f93af", + "0x84d5a89cc2332baaaf3d19627a65f4b107f8dd9228a1434b327732f59883bb54fb8ce60d6acd026ed4b0e94e545d1c33", + "0x8e66cb743f95ca5486400b0d89d02e20b98044be1e3a12983ff9fe086179e5a0ebf4dcd5098703191552e9aa660a6de5", + "0x87b4cfb35bacec805f8148786788db84eb8f4bcecdd0570ecb592c705450ce1a90b6d183d37ef58780ede3995be67497", + "0xa72a4fece5478011973afa543f6d8a8ea06a64b241cf7d8bd81fa3740ac2a4cf10e5120abcc1c1101f94da89507a40ca", + "0x89dc6001a96adcd2679916f43dd19ea00508c8d5dd6b0090eab7982fd2f3571b62f3029588a0649e73f49124525407ea", + "0x8ca75edf1259599e873530eff6151c822a4018e71a340534219ef8641cb6683215891df41d4e3c0ca2560e57a7aa913e", + "0x9282d32f868e5ee6f7fc229dda5b94b603476de30cec0a44a30edf396b52dc0ebd472b8f726d4b67d76179fecc1666a1", + "0xafa24704223707db89690bcf9761f07a093f6009ca9fc945e0a8801fc29f9f51292bf95243e466fe736088af36c55ca6", + "0xb51332508ddd9a2610edd2b0ad120272ca342e96c28baae37a2c4f07e689303a46c237712d07e446b1d67c75aa8ce32f", + "0x9219249f3799dfa4eb4770ee323f821e559e7406bb11b1f1889286221b22c8b40ccacbd9ac50ea3fa9ed754860bc24f0", + "0x993515270c128ede64fe6f06755259105d0ec74947b7eb05924a375fa5c6d14822f3d7d41dd04fa5df8aa2aa205a1dec", + "0xa83be4c2511bae430034ab15b194ac719d7b7041f9c0e321317f513a97db39e97b9ee1df92a1962f265b7a3e98cdd753", + "0x8ac7feaecd26f7b99fda3ed0b8a08bd6dd33ed5ba687c913ec0ffc64bbbefcda6f265072add4d944f2005634601ce68b", + "0xb4e3ac6b09299db9e1a469f3a0b2d8d724ee47a417a517bebc4c2ac3efc5cde086b57b9aa4efccdef2bcf8f456d973f6", + "0x9262a24a84fb7b2a84d700f98dcf3fefab8b47293778c20bfc356860cb84e0bf102bae9facd9986d92d1762e0a955836", + "0x97be2041c42bd25e5eb519279163b0857f8bef627492c27b1182f8bf0033769246be5886422cbd2409c08a2615352465", + "0xb0b87d059a00e3effa2e5e4925da913b245785f2932ac3ed364ad19a064d3561b8aa6afea22c951316074f0df179af36", + "0x891644b7b3321b06a2a40cd96c2b8b29d81cde5b48546483fdda439000982a9cbf1f6333fb6c089d39da6492cdfaefe9", + "0x8da9149b7f4783a24240b7b9c7e6df4abf8d699d3834e31ee591489bf4744141ab199c173db64397c1f9bd5f9c862ca1", + "0x8ad7f9fb2742654aa2964fd468e7645436cefd1308b064fd63fdf0d3adb4caf6cfe5426354f6cc284f208b03d6b2d918", + "0x8435e4668f7aeb027100d21e4e0b6ee22b401d21966a3736b95610de86c7e2f2c9ee5d0f901353675eee5ff458dad69e", + "0x9010895f045538bd11b47bb8996f27198c8d6cffd3220569e6b7407f68f35c47d1efdbcecbf9b5e241c3c2879a4f6936", + "0x92a9aa443b5ee7bf13b6f43f2d8d8db7f6f33fd4073a606ec5772421a55f464831419726130dd97829a7d4bfeb1ab078", + "0x843f3266560be6dcbe0258c3c7d7e332330e10630c069892954290288eda301e247f479505a8a1bf7e59c99ccafd104f", + "0x915bd1dad808f8a568725bd243f80b5476a2999d0ef60ea3ef6e754155bc4121b2b879d01570725b510c5a3f09cd83ef", + "0x97250d781815b1825be192714884630e9f564b9bd737d55b8ac79ab48d0fb3ca53bd21ead7b2fa82a05f24083f25645d", + "0x81e2d52333391ff2faab39611689a62d6ead77039e8703f4e012d53eea17a4d46f2e3342e44b6edbe73a542b461bda45", + "0x89c9f9fd5f638156b018831c1bb70c91215f4a2f5a73c84b1208bdf6ad652a55df7213336ce12bd910a0e1a726474f95", + "0x92bd02984d090ea7e2f3eb7d36d1e7b9d731b6b047e3cdd4af7cc4ee177415fea7a145205e484b366d84191f06af85c9", + "0x85a86fc61d5d916ccbb219db52953e1495230aaaca63237e9165276405f07ad9644e253ae394f1ccdd231944e7143313", + "0xa2ca5b3fbc9f3530f88c0ed7071ec3d89b272174c366eedb5d15d2b648c65d23c0faa4e92c776357e7c6883a0084d03c", + "0xad171f5badcc99c8ffc9d8b707d792046f86cd0aa478e0e2fbb32fe095f96cd134ca548d1f7713057694dc6b26465315", + "0x96bd15d57da9980870fbadc98c68db76824407dff2700c45b859bb70d98374d4a4ba99e3ed0b0c17f480fe08f16c6b8a", + "0x8300bac69ca088c3ff35749b437215e9e35a16393e9dc094f520516ba57a485def7029d30adfc72bca36eeb285c19301", + "0x8a09e20be64f346668fcc7b07fee9c0ea8094c935cbf4f3a4cdbb613d4b936c1edb9256b7c884efb72393d97c0da00e1", + "0xb1f85827ee6f041f93ab174d847a55710824fa131c9ade9561168c3962a25c617475ebc4105eba6e738961a754442bc8", + "0xa131558f92e215969f41b6a57d1e2f424149eea531723821dd4cf8c54325cbe66b002de2c8287de6b41ab4b5c35f060a", + "0x81ba492b8956f73557f361a856c6c884ebb300d828287d5699e22e0cfa75c8e77a61616551d0be5178263898c461d6f7", + "0xb2608f44d3c22fac8e13cb59e4ade8b9a98c4eb1ec0959ea400c97eb937ae3f66837e91917057148befade8389af2f6a", + "0xa6ff0323b5a18a4becb2cc6b376086b47cb2baffbfd1b0f2229ef2286fb4a34c5cd83a5faed5def7bbad519fcab8a856", + "0x857d879cb9eff22501d883071382832730704bfcc5cd5b07cdce7ab8dc41c565a1eb0e7e4befce8e0e03a4975d3f11ef", + "0xa2879a20c0360c516811c490289be7dfbf7dbd41d2f172c9239f99e3d091957e0446854f9d0f753d90384a80feb6fa56", + "0x83518624f33f19f87096a47d7b8e5f2d019b927e935a9021823fac6564c4f2328dcb172e25bb052748191e75ac682bd0", + "0x817ec79132faa4e2950665712b2c503d7fb542aa57b7b36e324f77cda79f8b77bde12314e2df65c5b5296a6bca9bb0b4", + "0xb2abf8fb7c3690816fa133d5b4aa509cd5a6e3257cfeb7513d1408b12371c4d58c44d123ac07360be0d0dd378e5bcf99", + "0xa9fe1e4fb1574c1affac5560939face1af6657f5d6abce08d32fc9d98ef03186dbb2dbb9fd1decd6d8f4e4687afecce9", + "0x89b2f41e51f33c3ca3e44b692e8a6681eb42a7f90b81c9e0a0bc538341df9e2039ee61f26d2ebe9e68df5ed1bccf8cdf", + "0x8b35aa7b1d9e2135b35a1d801f6c9f47c08a80e48603f3850b425f64e7fb9860d1adda04f92a1ba22d00dd0a26e781ca", + "0x960574978cadedbd4cd9f764bee92f94e08b7af65403de36b21bffc9424bcee845b3b028af2e9e545dd77cf1e69a6a7d", + "0x840aa0f34b5b6c39471f54d9e85f1eb946468c4fc01963a9027cd7864df01f73c2e864f1f07aeed4b1b1af72808dfa07", + "0x834464a84a11200e3c60f816044c254a7d9baed64aed45a17325cef7fd62338e0a26da78d199d30ac3411714dc813223", + "0xb4ac6fe2f5059546f4ad9a361426ead33237b6b9030b129bf0122085c85fe4ccb33cf90f5a7f23c5b708a5ac64b487f6", + "0xa12aa9035464795f2a67f3eaba478d5ebc838ed9e997c7dfa241e1ed60a94b367d3f969ccf0ef02028c35215698b309f", + "0xac8d926492ec2bb68c6d8aa9bce49085d3d266f3d5f1f924032b87c42b44e41da7c047eeb01e4618f9d0f123dcaa537d", + "0xa5142425825d813ed8ce1849d81aa40b11f1cc3daa89a9f798dd83065c74820b4da6122b3308f528b074531df66e1a5e", + "0x87ff55c9f5aae079e7bf24084dd9c6b3bc260727d942d79cbe8dc13341d98525b4ece3ed8169994b56a387642f09134a", + "0x88e680f148ef2ecdcfed33b61f9e0224790fddc9069bd6999e9bede1791e761637c0fd60b52990b6c93e6e5429e483ce", + "0x94bc20bf5aac6e9f1060d02eacd06c42aeac9a1c5635b15a83985dfb03938ddb4999a822e865635201489c7f75601b29", + "0x849221cab7599f25f0b114df092bd5e8c2430503ae959bef1543a101de0790a78245db6a145e26f40b5f9bcf533219a3", + "0x88b6f2c2e7a7954fad11009d839ce50780921f80292320868d481e38d26aecd80fa607e82219a99532d88cf33b39f562", + "0xb0d82947dc23c0b88b86c321b582c15decdb825ed909a731b42d46bc895009515a3dc646c98dbec7d71b0722df82392e", + "0xa2cfb9f7c1a76c8073363c1c3bebe5dc29fa76533caea41046c51ea9bbdc693a121b957cd96be5b6da18704d1865cff7", + "0x8f0ffab9a83355a22683a9d998d1c1089449eb308711eaad4265f05927ec6d0d1ca39217082a0b372e02234e78dbaaad", + "0xab024661e2b2937ad374c8cf2e3669f1dc55558a3a881e9ec4d461f27e0fa92e2bc88230f038bfb051cf2145ca747a07", + "0xb98d9b9ec9eefa56d38cca959ce1aee7b6d4b41a8dbbd34b3f50c0a5f97f84ed2502ded1ce8cdb5895872360d4ba6d61", + "0x851244158b3184a62d2c98d148e2b1102cf0d5500906bbc2deda95acc5e3bc4b4a3344febbb31ce05a56dfee86a74913", + "0x860d9e2cb886bd3620b5d7499d14b415532482569bd45fd76e3e8052d78a73ae4b2b41f139f9cfb136564108cd93c0f3", + "0x8305a052a0fb2bcd41f3aca075c5f7f233bd8f861451d03f3a6e6e31f7d08dd89fe1eb4dd7b238a78b12ddceaad9768c", + "0xadb703e4778c7e14fb83541ab00b5fc344108243ec6827c5d9b302ee68321aa569da1718424e6a57979ab7536d5eb43b", + "0xb1a754b87b9e21aeb86217ec5b4fadb7535344567f1bd15e88ec12a833fed68e26bfbe03b7709ce24ba6c925ea0a0e07", + "0x8c1e2f6bf820e1653f3b8213e9d959d8649196223c2aab57b7ebda094f4919f88d883bcc6a0cd0be335f26f5a2a9c962", + "0xa082deb9865fe8668e91db0e4fd7fb50fb3fdae3e7bf1217ce0aa6f286a624624cf936d762bb2b6c3fead6826694f846", + "0xa10540ca05fbcccdd0a2a66aabab3b36e9bb525794cbae68bc3dace6116f58942218e9d5e9af10d67b5f6fb6c774fdd4", + "0xb81d22c4ab0ccaf447cc5fc2ff3bd21746617e6773bf43257c0d80331be2e8437b88c9c45309ee46402b38d3d4911caf", + "0x84c7c6e924713cab3b149f641dabf63ad5abbc17c1d8ee7802a6630507aa1137f7e034ba1d12ec13f1e31efbab79bf13", + "0x8773b9d236e5fcfa8c32e471b555264692006bf9a869a3c327aed33da22dfbf5780ecea7158904d4d6ac4acfe9789388", + "0xa4c2c1bb7290eb7af2013f7dde78282148593f066b09faf42e61a3fcf81297caa5a00fdbf6b93609c8c5782a0f25341a", + "0xa7bfa6e3f273da3dcfac7cb9906bbe9fa4fc2872b184d79813ee273e6cc4d7f37f46164362707a1976f5b6a2c5d7ed1a", + "0x8b71502019e4263fcda354a0fd10aaa7da47f4abb7a0c715c7b017e9eea14f2b64009b29b467394668c7ca995adedf82", + "0xad7460fba7deccc3f9a7d204233de47ce30ffa55e1e164975cdf06480a6108720bc397b93ca8c959df77d44a1e1f05f4", + "0xa5b8df96ccb7b078a3918e74b1b10da21df982538d2c9313f5129b2797c8a6db9ff8707241ff72d3e9d5983397321736", + "0xaa6cfa6386660c01879656da6c4e72497690708bae6c5cd1d088f443cb5bbbe75561d6eec256a72b9728377eb83ef973", + "0xb9699ce7c5c878e44114ab7a598646c6c7616b8e08a9ef8ec291189ef9945c1a538d2abf1ce3b0da0f8eecb303b81b43", + "0xb8d0fd1d278f53c455de92ec4357885fc6648dc5f276930263da7dc885b4a9628a2113e28b66b1e64fd08189427c614f", + "0x84ad8d262f6ef5d93e82ff6f4af995148eedf6d8e079124daee9b99f506e2968922eac2c7d4aea741fceb7733f20b2d2", + "0xab5e30ab54641e3a44450118b8235554e0fcfffdfbe1430ceb3f7ef33325725741995fbbbb0c16f0875aef0f1e0c98ec", + "0x80e2cf8bf386ebda46045852751611f2af80eca2e910d9ec5f6e2c7376611534604ceafa639272b3d503b02bd66525a6", + "0xaaac69af8fbb87da1c1b7c1b9e59942887ae839a91f0c1d191c40fe8163d7f1dbe984e4fd33619c73e63abfa7058f1e3", + "0xa6194224ad838ab86e84dc80e9b8abb121ae6c3c7fddc476463d81f14168131e429a9757e18219b3896a667edda2c751", + "0xb68f36aa57aedc7d65752b74761e49127afa65466005a42556230dd608ecc8f5efdb2ce90bb445a8466e1fc780eea8c3", + "0x886c3fa235d6977822846b3d6eccb77f1e2cd8ba3dc04780666cf070cae208b7513dc4525d19a3fb6385cb55f5048e2a", + "0xa9801273ef850b99eb28f3dee84ba4c4017c95398730c447efe8c1146b0719f252709d3397ce60509e05da74ed0f373f", + "0xa58c2a5dd13e08ffa26a6c5e5eb18bd8f761ab64a711e928e6101512401ef2b1c41f67ba6d0823e16e89395d6b03ebb7", + "0x91318b564ec8b2d8c347ca827d4d3a060272aec585e1acd693b2bafa750565c72fec6a52c73bb3ae964fdaa479700532", + "0xa058db5d76f329c7e6873e80c7b6a088974522390ccaf171896066f0476742fd87a12fe9606c20d80920786a88d42cec", + "0x9838e07f9ed8b3fbca701be0ef32a3f90752bbe325aca4eaea5150d99eb2243332745c9e544fd1bb17e7e917202edab9", + "0x85a9ae7dd354f36e73baa5ecf8465d03f0c53b24caf510036b3e796e4764a2bc17f0373013af5b9f1b8973226eb58cd1", + "0x896a4ff4508d069a7da6ef7bed66e1080991daee8b227f3c959b4f47feaf75fd1b9e03d0917b247c2db11e105395d685", + "0xa36d9a6a037bf498dfc0e535f2034e6cd433c7b52e520469811eb2e9f04499a6ce40257d2905300df7d81f38d1bba075", + "0x97aac3c5492aca879b4c06db1834b30b8850a244d29296046a84c637d9580c8521ab4752ef814c96f255a139660d7639", + "0x8552bf592a84ab4b356d01643c90347377ebf1f2b38a8c2e55a3f34537b8c7dcbd62e6776d6c2114f2bc2d4344d1567c", + "0x84474ad163db8e590943ccd1dc50b4f444beb8275919b33f53d42cba89831e9d42ce2de52b26f4412e2a0676ce913277", + "0x900799dfaf5eafeb297c7b4f892438bf2a65ce04034d66f8e5cc3836e4eaffe782fba4f4455a0fcab49102a240d1780e", + "0x817176415e35ad4a204b9fd5771bae6cc270f6ff050996cec89efbe461b2940ae5dd3c6c7d7e31b1da5285b207efed27", + "0x965e5791c927d47569bc54ec9b4c5305788aecd87a26e402aabeaeccc03480df46f0586ca2e2a9918885cd03332af166", + "0xb96d9ada4b5a04a94807d71726bd557de94fbd44042d7dba40560eebe8658d1da49eba54499360619f3b2c38e8b5ed6a", + "0xa07b6d641a43e02e7868f30db4dd5069a2f221b4f122ce9b11eac04abadc4f25f3207f1d2d86c7935b1a3d9992ea9814", + "0x8250d4d8ccac846a4b1a9fa392d9279b5bf2283c8b95d8164c3c0d199fec8849eab85755f2a2a99d584a0407742e3200", + "0x8324cf49f56fc14162f9a9ebda1ebda0388d09d8688f1938aef7dbf9505fc119069efc552f68cc7cd9213f96fda2c6de", + "0xa98e6f1e85268dccbe3bf4e92c9f455c58dcb53de1dba3b78589adf2e50e79f8e245f956e0d098eb46f5d3746826c6dd", + "0xb103ec12f266b4153d67b54d8fc079357ee342cbe5008adc3e0689a7f788534c4601e60e939731f49e4a1e24fd589f82", + "0xb2d7681e866420413cc98eae67614d383943e3762d5742cb3c57e26157633c20880eea1209feaf68402d5d33dd699708", + "0x99fed0ae4112ec9ed74baac70d202a885aa51cb555a3886b49016744dd4017640dd5dd564998c4d842a9f38f3e004e68", + "0x95c35401314467219c8bfb1ccd1f1eae6ef4fa9e48fbea14f70d5315e67b16c46cd03554471840e4a5030b077d2a3856", + "0x8d029380e0c294400d6b8673a23aed43697cb6460fc1bcf217aca3b47cf240886644ed09521d6a05f6abf56f99722d84", + "0x8ef54d1dc0b84575d3a01ecba8a249739edfd25513714dd4d1941fbde99dbbc392f7eb9fb96690d7052609af23aa57f7", + "0xb8ad2b7af4812417aa8de8f33a26547f84bb84f39501d4b7c484cc8bb54c7e166c849b95240fbe459a4719a6e3bf1651", + "0x9858545de898721d19930d8b360cacc5ce262c8e004867a050f849f7a2f2aba968c28d51f24a9af56aaba23a9ded4349", + "0x94ea5043b70df1db63f9b66b4f9d8082776f721b559f27d37b45e0a84faf47f948d7c4532dfd854a4bac49fb2ec8e69e", + "0xa2fd88d7b15e3c2778f6c74470d0f9e1a1f979a4d58bd205361eacadab9973d585a6508e685e640b272d6f8a448eae05", + "0x88defd6bccd55db8ca84e3c8d0fc55a3456b41788f1e209d0aec19c9c70febebf3ae32cacaa1dbbf796d7ddea4b17995", + "0x88b8cde2449d5ee7de2ee2f32e845d27e171a51ef64f1d3d8a5fd7dbb9f898ea70eb7f6410cddfd7b7ae70ea8073cc2e", + "0x8e044fff6ec557824866ac76301b6d93ed19b7177aa6baa95046330f5d69b572b59200e3653cf2f2b559455e782e8960", + "0xb5446b4d6741c824885790d2d26258729dc0ba2f469c85a47d38886d933b785a4f38a951d37f3ef4bd5091c03fa3a071", + "0x956c8afa8056e9a71ab2e8be5241ddbb3a8b3cff2110cb0e7389493d9fa45e6c4b769ebef540a952db6dcd8bd55baf64", + "0x925950cae25615246e29d594ebf34fa7d52f78a9867338648158f2131e6eb4dc17e18f9db8a5fdd76d017b3a9798b3a7", + "0xa17ea4b43211ba990270c21562690b3ef154a46c3d669c4674c80bd424cdfa95d8850c8e882b8d06504f929cba3d93af", + "0xb315ec723973a138508afc387ef651fd8a8804f93975fc36c2eeb796a304eeb1508518d8703e666a74d14318253f526f", + "0xa995742d7433b3f230e622de23cb2d81cac76de54831491cc29768eb4a56da60a5cbd573e1da81fddc359b489a98f85c", + "0xadb2e89f0d15294d7118fc06d4fdbd9c51d3ecbcc23c69797e5b8197eea0d6cd1240910cf22fcab4ef1e2dc2dd99da91", + "0xb5ec9f9fcd0b5d176b643df989bb4c4c1c167112373d662fb414875662d1a93160dc0b5cdf540e8a30e5fcbe6cfbbd49", + "0xb1291b53f90aed275df8b540c74a1f9c6f582e16c5df9f5393a453a3e95624ab7552e93d6e2999784e164046e92ef219", + "0x8bc7b7b1a584a12d5ae63d0bbe4dc1b63c9df9c89bdd1095ff4b8e7c822bf8c1994c92310a3644033c7c9689f4b7d2b0", + "0xad7fc45506a10ca48f991714ecc055cea376c0cbe667f3b40ee8dad8446218835439ae59bccc474cf47b053748ceba6d", + "0xb134756828a5f5725c0b95109e09ca450e3834b127163a0aeeb544e63cc0cdcdf66f8ed98c331c7c98758f46af369a84", + "0x94535bf1636be0974b112fcec480ed8eafc529933f3065c40e417e608e43a392206cfde8bb5a87b720263446c90de663", + "0xa4df4f6efbc3701000fb072e5cbed2754b9ef5618386c51ff12f95d281d1b700fea81fc1365f4afc66a7c83bd0228fbf", + "0xb0336b3552b721087c7e2194976a9119aee13ebed9f1c3c494353707fffde52d004a712965f460062ec9443620716302", + "0x99a39d1d1ee4283b75fa8c1fa42b6a3836b734be48bdd48050f9b05e48db6354fef509623c6ec8d447d630a9b3352b77", + "0x8e3dc3583d40956f9e784e8bbd0b5e65671d2ff2a7c387b20fcb7da9b969f2d122aaf7f054d450dc611737604548c03a", + "0xb5068ec5b7bcb5d8583d51cb25345990f50d1f7b82fe535a6a6b17756355885047916f466ea3ab09eef5516bbf2dda90", + "0xa8284ec1eb1d21e693f31a6c074199ee85d8a8da2167bffab5fe240defa2773971c8437e358a18f7e58d1e2954f57f6f", + "0xaa7415639d29081acbaac3e9c6b059d68e8702db3f430b86bb6e220d476fa74841c875e9d471c8a5423c58b6fee3cb54", + "0x8afcfe6f65fa6e07c2cb3e1756c0ef2c589830be96edd50c3c248e3b17f51a4b08ba92ef7eed7991d81667ddfbf2bf7f", + "0x83b9c8dec8ca8f9b85f0e36c08c5523cfeafb15a544398e6f93b48b5fc4b15a0bd05c0f176a9c2469664acab8dffb0a8", + "0x82a128a89ea46b9debe5c903b950c0ab30cd7570b979ca911500b5c2cca5c4ee6b2c2fa414b5f28e367f4671ffce60f4", + "0xb79fd0ccd2629a361cd6f9307c02ecd4d1f07e4ee03ce4b542997e055b07a026cbc0ba05fe3da309efc58db2e401a8fe", + "0xb190751141093823b4b5324cc26c4f3258552f7893241201f2fca1ae9b1a1d4d4964a9abdde8642cf308ded61ce5ef09", + "0x935fd48b95aa6f9eada0cf9a25a573f0ffe039888b3410788c41d173747bf384c0ec40371bb4383ddcc7d9f2db3d386b", + "0xb9affe100d878491ff345636ffd874ce1f27852a92417694afce4163e6a80c78b2f28d78102fd06c3283ef273ad37642", + "0xa877670276d49ec1d16c9f1671e43ade11c0c1a1413755f6b92be9ad56bc283e4bd2ad860367c675d5b32ff567301fc4", + "0x8c660d16464878590761bd1990fd0fc30766e7e49e97b82ec24346937856f43990e45aa8ad37283cb83fa16080d4a818", + "0xae1412087da5a88f3ccc45b1483096aeb4dcf4f519ff3dbe613f63712f484bdd8b2c98a152a9db54cf1a239ae808f075", + "0xad83cead97a9c3d26a141604268f8a627a100c3db7e5eefaf55a1787ddc1dd5ffc7544e4947784cb73b90d1729003c8f", + "0x97c3140ce435512a509e6ff3150da385fdf9e0883a5dc7cb83d616ec8d0a0014e4e0fa57a4d12c7997cd84e07d49a303", + "0xa353773ff68f1615454555bf658eabdcca40a9c7bced8537ea6fa8d54764fd1f032889e910d2a2a342835513352e2d2e", + "0x89e8df0c17a36ffe08149c2ef8b27306d04cdf437135aaeba697abc65e3c8e91bcf1817919a8a826acdbbe7dce79a18a", + "0x9928c2da15ac6cb20b15859c22508cfcd452c5643cd22eb84abf5f0a1a694fdefcd8fc329c9b40babc52630743d6b65a", + "0x99d837b556f8d13108eef6c26333a183f59383b39958dd807b10590c3d37f62ade6c4a320ca2e70567e0218b0ad5807d", + "0x9272da080e4aa18720b634640b01bf1fe506c7c8a89dee8759a53e2ca5cdbbd4a4f3aca54924c46b935362cf1eca066e", + "0xb4d39752c882de1c1daf3854202c1d58c2bcf35c882006eb640fe54a97be2655281cdb91c30d1a41c698617c2cf64b01", + "0x8bf827f4a7d47e07374d338a3d8b5c2cc3183015b5a474b64b6086fcf0cdcf4852046c9e34d7917d69caa65a9f80346c", + "0x901bffc7db9c9416e06f593a76d14f6d9e5dea1c5f9557bd8c93b9e70aa4782bab3518775c2a5b285739323579f7cf0a", + "0xaf7e204388568627ca23e517bcf95112ca8afd4c6056b7f2c77c4da4b838c48791191565fd38398587761c8047d11c47", + "0xab2576b5366e6bd88b347703f9549da7947520d4e9de95d7e49966d98249406ed9270fe69347c7752dad47e42c4ea2f4", + "0xb12e3b228b761dedd99d02928105494ded6d4fea3026d73d65ebffa2e85e2cd75b6d091135d418dd95ac102c22b5ee31", + "0xa20b4a752685d5e31ee7e2353c8a1b9a5265f12bb775004d282a3ecd9deda44831bac1ac5151646428b66909b2a423f5", + "0x91a1d4bc0062a86cc6786a96fd3eb4436d8a4a187b7cbba02190d1cd6ed3c3797d9ae7d6ddc413f1c94a21f62bd04ef5", + "0x977f18da1a5df5cfdd0276f583cfba2b2a0fc6139520664e20068f8dfdde33e29d179abfd722f142448f4677aa47be6c", + "0xabc3ece90f0f7b1d80fd917de27ab0d88cca584ef959da520825e54cb5a71336b15f8b348532d08d47a6fa600527ef25", + "0x888d36a2c7cc13a1c1aa338a183a74a1f57713e76cb825f9837f43279ce4741999b76a16928147537bcc20f2e0195b0f", + "0xaf3f5dfdc2dcfe19de893f385f39f550cb1dab67c2e97f1d5fa735e5ec96d6680066803e8a0eb010dd4399f654195513", + "0xa0fb4e08ff56530a940a86c28830956eb6dec2f020f7faaea7566faf0a4fafe0cffe01480e87763ec22f201be51a6451", + "0x92343c5b107910b203c64a79c93d354f7ee5b7d1e62e56732386776e275285561cb887019cc00d3fdbe3b5d54460bec1", + "0xacfe7df83c4624188a1011ad88c1e1490d31a8a8c8016b40aebcdd7590d9c0793e80d2d7ce6a7048876621c252a06a5e", + "0xa7da001dc1e33e0e129c192d469d2bd6e5d2982eb38f3ba78bae0670690c8e70f40e8114a57bd0718c870ca5dd25b648", + "0xa903de5ff97dc83628290d781e206ef9d7c6b6d00cadc5bacffb31dc8935623ab96ade616413cb196a50f533e63641d6", + "0x8f9658d42ad14a60bbf7263f6bd516cfee6b37b91a8f53715d69f718a090ad92484061c2cef999816760a78552fae45b", + "0x8c15b72b3d5fcb9ffd377fd67d9dfbdd706593fba9629002639973db12aac987bd1db70250ded31c88e19efff612cdb8", + "0x88a2a4034decd854fb557960194ff3404e239953818a8a891bf72a0b26a8e570a65c4a630884de991ae7452b3234f31a", + "0xa09cae5c4c190537bf1dd75bd7bce56f7b799762af865bb9d1ee970f6a133c27cce0dd0f14a0e0516ceac41054e6998f", + "0x9760ebb1b40f9a97530c3b940d4ef772a225e5b63bf18283f8e302b9436c5209f6294980fd37058060e429fb7fdc3a56", + "0xadaa9400eb86d857dc591b25dbe3bc8f207b69e77b03cb5ee01f7e4b006b5c8f6ba2b51b5a45687479885708509363de", + "0x949efe6b00b3248846747a9ad4a934d6e4255994c2b540a59fbbde395fe96d69bb67908441cfadd8c8bbb561fe52da03", + "0xa19a45504b6b1dc3a0fe0e6a1384734a3dcd5a7cb8fb59eb70e49426c4fc44946547443d558e5719a04884ab3a2811ca", + "0x8934c9ee21e8d1435426fd0f64232a0670a7946ec524c054cd4f2cc8b1be9f89cc11002ca8aebae646a2050d91716b10", + "0xb1150ff8ffb34ffdcf7d603348c0aed61e5f90ee0a1b814079fc2a41325c75f2f9ee81542797ede3f947884266a772e0", + "0x86ce8cc7c1f92af68de2bca96ccb732f9b3374dad6657dfd523a95e8a931a0af2a80df74098514a06174406a40c16ba5", + "0x90faabb9ace9e13fd9584932846ab28a618f50958d2ce0d50310a50c3bc6b0da4338288e06e5fcbaa499f24a42c000d5", + "0xaf4a935c2d8df73332a16dc6da490075cf93365bd0e53e2374ef397514c30c250bcac569b6df443985cf3720a4534889", + "0xb7f948ee90f394789eb0644d9f5ad0b700c8e44e5e9ed0e49da4cc18483676d25740710b1c15a557965da635f425b62e", + "0xa917913091245beed6a997ff7043ecf60c4d655c4db0b1ef1c704fd9b0e1ea1335ce8b9f45d6e120f81805ce31555e30", + "0xa48099da8406399bfb1ba834f6f7d864111d0036969a5cb64089947a63dd9467d3857b605e9f57f5ad5f4ec915088d9b", + "0x9784c3f9be42eed354542b1446d734521f8e3f01cd9d495ae98f2e4a3a16767fe2ad909e0def5d9a6267f3fc6a172cd2", + "0x8d9afaa323847a3226ad7d7b60d87322ffcda2e4a8df89f58a076f7972d896588de685a2e155e243bcf9456b0a0d6d1f", + "0x994413faf0b843f4ec1842c706c45ea5f24351c68674a27887bc8b182eda756856e507a4e8bbfd937e2c4c581b629ee6", + "0xb3e72d9d1ddaa00c7d22f25462d6e9f2faf55e30d138dce8bb1517eb0b67132db758668aac26164fd934d732633bdea5", + "0x8e95875e338f714e9e293df104f0ad66833bbd7a49d53a4f7f5fd5b18a66a61aa0a0f65cc31d55e0c075e0d3e412cb90", + "0xb980091862b1a9f9334b428eae14bbf1cecb4849e3a5809773b0d071d609727270f6ad97f329eca896c178ce65883db9", + "0x915d7ae5ae780bdba27ba51a9788a8852a15355b569581d1f18f0d94bcdfed2c1ed5a4f58e049e9825cda11f92b2c2d4", + "0x83e581058edf9259d0b06128282327cacbb6afc939578223cbf93544599f799a8dce1fb21d52464f990a877086f42506", + "0x803612a38b6f6efb97941997e101ac1878e192456f8fbddb3359aa7f3023434ed8fa92e60ec8e7b4473b1948850e4311", + "0x864a1bf4ac046161617dde282e44ab3cc1843da01a09ca58aa00ed00eaea9351a07a9ec16d910819e7dcc28b8d2c8ada", + "0x922eb142845975d5f6f7dcfee6cac8c299b3730400e6bf82cc0bdd9888de21de9d9f1530640f702c003e1ed63b140cc7", + "0xa7db03c5be647dce1385ebc02f4825a654447fa8c4c8d4b22e635dbdd2b3ccdf219384e49a80cfb1e9e6182b6e4227ed", + "0xa167289ff0f0967bbab6479e4a8a6f508b001bbe0d16cad36ab4c105ad44f3f180e39a6694e6cd53bc300fe64dac1e8c", + "0xb7766431f6379ce62cba22ab938cdbb1b0c7903dfb43980a417e0ee96c10b86b447241e9dd4722fa716283061b847fb3", + "0x90cda18c5d66f5945c07c8c7dc453dee1370217ccb851bbea32578599aa669b4dd245dd8a9711b27c5df918eadf9746c", + "0xac690cd2af39932874385fbf73c22b5d0162f371c2d818ec8a83761e0a57d2db2fca1d757343e141e1a0348016d5fc44", + "0xabac820f170ae9daa820661f32a603ed81013c6130d1ca1659137d94835e1546c39a2be898b187108662cdcbb99d24fe", + "0xb2ea5a5950096772f2b210d9f562f1a4cfacc021c2e3801ac3a935f2120d537471307d27b13d538dcbf877a35ff79a2e", + "0xad94af4d0699cd49ba8ca3f15945bd09f3f7d20c3aa282a3113cdf89f943d7793e59468386b067e3c1d53425dfe84db4", + "0x83788367ec97cc4bbc18241cbed465b19baa76fab51759355d5618067009298c79d0a62a22e2a1e6dc63c7b90f21a4a5", + "0xa3e142d879096d90b1e0a778e726351fa71996466c39ee58a964e6b5a29855123d4a8af47e159027e8e6be0ca93d9955", + "0x860831f8d3edaabd41be5d4d79c94921625252aaec806251fb508e364e39fde8808d38b10d557e487603a1b274c9bc3a", + "0x88da39f334bd656a73c414ec17dda532059183664bbbac44eb4686c2601629ef8ff9da992c337a842e3885b684dd0032", + "0xb50addbdf7164e8303f33de5ce854d6f023d39c1c1984b214d9e5fb6f6001cd5bdda816f048a438ff3d696872672f805", + "0x999e58c4c69a912b84561cb09610e415b43832beeb95897eca8c403ef4754f4277754d492eef3673afd4362f50060fc9", + "0xb88ea0f60f8119c5a1fd9294796d387472dfad22442b29659713d1d88e7d854cb7cf5c9ef773627781188626bb2fb573", + "0xa068b3844e9dbcf74b54fd55904d56af754d8ce4c619fead7a07f9bfb9d02118db7c512ccec2489d2a84374ec1d1fb6d", + "0x871dee023768636003c799e6f6fd8d31315a4c0da7286345cd64264a016693b3485e0732be1bbd34dd5fa04dfa58a983", + "0x8021e8f508680df12e4a5a1bd49f2d7142df65158b0a7198ffa83abd16053a542fb93ffc33e5279020ba8c6a26feacf2", + "0xb5d3cd64df5bc965228b0bd4ce9e5797c409f7b64a172ba165e44a8e4b38e3d5fabc3e0b9a19afbfe427f887c40a315d", + "0xa54fdebbb594bafcefb1a03697711e0091c072e1cc24fb441fefd4e0a0518675a1d7b0966cb8294051d7ec0ac175d0cd", + "0x93922202337f72969d6d6e14a29c9c75e0420dfba712029941d1504b9f6f9761d706cbc0652cd09a1aa5d22aec766af1", + "0x9711ebf1c7c7426190d4afd5dd03b014a456bbd9d90ed101623866a280550df26a629dde400c03ee3699f7d827dc0bb9", + "0xb4d686d8bc5c1e822a50124c1cc23c6bc3a1577a3d0b8d4b70d1797418aaa763283c09e8a0d31ae6d4e6115f39e713c4", + "0xa533ea2ac683e4ba07e320501a5d82a1cfc4fa1d65451000c3043f0fdac0a765cc1125d6cc14fe69975f3b346be0fdde", + "0x94ee563134fe233a4a48cf1380df55ead2a8ec3bf58313c208659003fb615a71477e5c994dc4dcfb2a8c6f2d0cb27594", + "0x93e97d3f3f70664d0925be7aee3a358e95ae7da394220928ae48da7251e287a6dfbd3e04003a31fab771c874328ae005", + "0xb57440d34615e2e7b1f676f2a8e379e1d961209fe00a0cf6798f42b7c28dbd03172fce689305e5b83e54424bc3f4a47c", + "0x97644084c6f7b4162bc098bed781dd3af6e49e7661db510975528f1dea8154f3d87e979bcae90c3df3a7752eb0752889", + "0xa923b27b225b2a6dd5bdc2e3d295b101cac5b629a86c483577e073cea1c7d942c457d7ff66b42fcf33e26c510b180bc2", + "0x86698d3b3873ed3f8ab3269556f03ac8d53c6e2c47e5174ec5d14b3ed5c939750245441c00e2e9bb4d6f604179f255ef", + "0x87946826d3aa6c7d53435c78005509b178fdb9befc191c107aee0b48fbe4c88a54cebf1aae08c32c3df103c678bad0ca", + "0x860864896c32b5d4cb075176f4755ea87fea6b9cb541c255a83d56c0a4092f92396a3e2b357c71833979b23508865457", + "0xb78fa75d687349e28b4ddfe9e2d32bb6a3be13220b8f3ff1ded712088bd0643da9b72778bcca9e3b103b80097f48bdd0", + "0x8a188b940446598d1f0e8c6d81d3cada34c4c1ae0118ec7e0eacc70d1bced28ae34b99667d5793d9d315a414601c3b22", + "0x842ac6f7dc14191ab6dddffcbc7cb9effba42700a77584aa6a8e17a855cd444c5d138f9d61bf55f43c6ffbcc83f92bc9", + "0xb6742902c3d145a6af9738c01cf9880dd05c85f0d0ef7dbe93c06fdd6493333d218339ebc2a02be1895436a2f734a866", + "0x98bf18488483c627b7181b049d3e6f849fce1f15794de59dcde6e5a9b0d76fd484a46e48822a6a93001d3aa12f48bc6d", + "0x8769cac10bda8c53a1c19419ef073a5998f73dcf2ba1b849561615a17cbc0a49bfe3eb4ff8801dd36a22fa34b9a3a7e2", + "0xb45c084d58028fdfae792210fcd183abc4ffddeb4cf52ebf3f8a50e4c4eec2a2758f1241b0920bebcb24b757c778577c", + "0x85c1216eec8e1fbc1af9b36b93c5d073a81d5fba86a6daae38748ec1573eacc6bef209e76c87a6efbd7a3f80e11d4c3c", + "0xb8007e34bb3f927ec06a050b51e633d7eb9e9a44715d5b39712e69c36177a03cd68391090cc3293098e54f6cf65f6caf", + "0x8e85527b27c9152b1ba3fdd532a76a79064ab097570508f233e09978761dfe3012d537411b47d0e4b65265eb32cea2ae", + "0x899779f3c31a20b76068ec8d59d97a64d2249588ddfd69dcbaac6bfaee8ce0ff3c5afc4e17c934ae7cd041b760eb555d", + "0xa5dac3d8f5fbef018509612e25d179f60d2a62451c76426bf546e9666fcdc73263d34aa6fa7e2bfd4c9947bbf5095eff", + "0x896900eeef9be2b2e755128e7b1c436af6fb3984f1e66c444bc15fcf3959013b4902c381f0eab1247f878a6ebd1f4ee0", + "0x8cb17f4b0af2e9b2cbb56f46e6a5d6874ea0daf147aae77303020b4e592ddc92e0dd058def7da96258b3a68b223bf22d", + "0xa1b6d3f09a9fa7ecc021ab7c5396541895da6e9bf1f9a156c08fc6f2b815a57f18c337ccfe540b62d79e0d261facb2be", + "0xae70888811434ef93da60aeee44f113510069fd21161e5bb787295492eb8df85103794663fc9305f04adcbcf11ff0c5e", + "0xa84bbc8624100acfae080ba8cfb48fd4d0229a60b62d070bd08fade709efc6914dc232d3f7bed76a59204f9252321aad", + "0xaea47d54652abd8ca213cfc623c8e30780f37b095b59ac4795252a29c2b6bc703a5203acff8831314478b8ee8771d4d7", + "0x8dd438eb8be14935f759aa93021c2b24e1d588f7a162c42c90ec3a647b0ff857f60e24c0a8953eb7bb04e04be70f11ce", + "0x922b07b5469680a10e7532766e099896f4dc3d70c522d8add18f5f7765d4ddb840df109146607b51ceddd2189fa7b9c0", + "0x83ef6ebd0ae6c569d580093e8b0b78daa964760556272d202d343e824c38eccb424262e5b7809d3c586f9e2e9c5c5f22", + "0x97f98bd357db6e093e967fe180cf67ed09fa711580a5ad48f07cf095b2e8fabbe6319f97d1f15d62c0ec2227569d8dbf", + "0xa1953a4a22fe6c2beaf2a5e39666b0eb53018af6976e3a7aab5515550ff2efa89400605a43fb2c4ac1e51961dbd271d8", + "0xa5cbd67f4c0bc98e20aa74c09e6f5fb6f42c08e59aaa477b4b4e61434c8884bc14f17cf11faecf46dc4b6c055affbad2", + "0x87d96818f2c4f12fd7705cf4060a97bd28037c5ac0f0cc38f71189ec49361e438ce863e6617651977708094d5336d1da", + "0x85e7c2daae5fe59f8a1541c94df50402a671a17dbb8838113fa4b7aaff6114cf2bb5969410cf21e6a162857f2f7a83a8", + "0xa19575083e1731bb04bb4a49414e97aaadb36d883aa993d1f6847db50007315444814740e67e10177a14e0e074fd4c7d", + "0xa00ebfb5bcc3a6da835078189038a1e56b7dab6be74332b5ff7440e53b0f9e1eb9973effecbbf37000021fcf50c7c1ff", + "0x8969d7943abd3b1375fdfc7d6124dde82b0f7193068ed6ec83bcf908734daf3487a6a30f7b322e54a4818ae5f86d91c0", + "0xb959c8d210fa43af9b20d1fe0ea8c4921280eb4544ef6ea913309ff9d61c9327096707e84dc1662960519be8e7d080a4", + "0x9011d8ac651c42e0cb03931a9e960f58e02524c6b666047525e3b9097e9f35fb2b4b278efcce2bd5ad463c6d7fd56694", + "0x937e3b22ed0fcdbd9ea5a1b97b84bbe86b7f5b2de3866a930611112f2217f4ee7d9822c4ab1253823f77bceeae0c8e10", + "0x828997e5d121f4c305e018a0a0ba338bd6a34a7b4dc3c5ceab098ee57490311c130e2c045b9238a83908d07098d9fc32", + "0x8d114808eac0f2e1a942d80dad16756ec24f0276763cd6771acb6049472e05a9bb1d3bbd5957f092936b415d25c746b0", + "0xa063c5c26267ae12887387cbebbe51fd31bc604630b3a6e8e177e71d4f26263be89112cd12d139dd4c39f55f0e496be0", + "0xab1e1582c8d67196d10f969eeb44e6e16214f1316aa4a2a821f65ba5834326da6cba04373eabfd3b3072e79e5c9717e6", + "0xa17b1dbaa11d41457e71a9d45d032448091df7a006c1a7836557923ab1a8d7290ec92a7a02b7e2a29fcea8f8e374c096", + "0xa1ed7198da3591771c7c6802a1d547cf4fcd055ca9010756d2a89a49a3581dfe9886e02ee08c4a2f00b2688d0600509a", + "0xaf09aa60c0a185e19b3d99ffdc8c6196d8806169086c8ff577bf3801c8ab371e74165ba0f7329981e9252bfe965be617", + "0x98c04cc8bb26ffce187fa0051d068977c8f09303a08a575175072744e0a5fb61191b1769f663a426c30d405515329986", + "0xa542bf1c9c3262d488ea896f973d62923be982e572172e2461e0146190f2a531f62acd44a5e955a9f1e242b3e46d63ae", + "0xaef7b7f30efd50e4a66c87482386f39f095bff6108e68f74fd3bb92156c71c75757912b111060cdee46a6b3452eed657", + "0x8afe1e0ccd00079702f16ab364a23bbbd3da1889d07c4f8cb04fd994bf9353216360dbd364492932bfe20b8b69ae8028", + "0x9896c690999db3c08cd7b25efb1b912c3e0f976db98a3e830f086aef93222d06ce570a7b2babcd7c81d8f9955169669c", + "0xac7bcab6a281468907ef1ea8a6c1cd624159c88839131bef6aa0c22f331fc87ec6128a2c2a333fb79df549e4587e1a12", + "0x987935c08a30b099d19f96901315a2e60591baf898581c40bf5eddcda806ff24a4536e30ed1e6c0b128a83fc77b6e81d", + "0xa0a6945bbede3bb09a4a09ef27baa20619d3e15af5673b9350601bcebe952597c989870746cf75767ffb73b32c6c9c6f", + "0xb0f5590079f0a0302b08a0cc1b7a5f39cc6900c2a5cdc7baa333d8328a731b2df5dbb67e27a154d3c44ed1a795fc4adb", + "0xa7294bdeea210e528f277f3d50e89e6d79950494478998181ecb38de675020130256f2f2a075899170be964d478458b0", + "0x8ab3041b895a631869b439d5599a66facba919226ca9b39d915f19d59f9fc82393ea781377e9bd3bcc5a310e41376914", + "0x8da399b59151fd48b2579948bb82698e3c9804d70ec7d6f3cc7e82901f9f2de5ee850349a7d6f43e5e9ebd47bd78620f", + "0x80e8c32de83d1083916d768b11a982955614a345d26d85b457f2280ff6c52bb776958add7c1c8878f7d520d815b8e014", + "0x81bbec7bd99d2917d2dcd8a288722fb33ad5a4bf5416fba8609fa215fb80e0f873535349e7dc287f892aa56eb9e39c4a", + "0x9665796fe04c8519206fba58496bc84a8b9113e7ea8e152b65f7f732e88beea271dc97b1ea420dbc8257cc4b18a77463", + "0xa97e342aaaf693ddc87e02790278e4bb50117af4413cd703bdf3b7cad2d1facf31fde1303b43ab2e0265467474f97a8a", + "0x925549ebebed348886e37773b05cd8ad04906eca4536bfed951d1ee41b3d362ddc6e1a302c21ff3a2d1e70e95117922c", + "0x818fdf74d7903502101551bbf48d3c7819786b04b192d9e94362d2fcb85760d8b6f45165a5443aa5221bef400525ddb4", + "0xa9d29de7e8fd31b59f4a087168d062a478b1329cd3c81c31e56de4fb40de7a5be9a5269ef0be452c487443a0b097dd50", + "0xa85286ad573db4c9aa56221135da1e31d742e0f6ff01d6b159086d7258f78b08dad55ec8eb5c91ee9d3404b2eeb67e1e", + "0x92a79b37db5e777f9ebbebde24a95430a199e866e56597c7d0b0e7fb54c7b092c2f6cf61fb24470ddf250cf609898281", + "0x8d79f5ca67ed67d52c82949af342a9fc60fb793c47c76d84b4863c550796fcae2dd59e285897c6fb96fe31cee1efa62c", + "0x8ad2e0bda03415ab86324992bb62dfa3612d2d003765bcad1468087c27971d08bdbae5252681f0115a184f4885d444e4", + "0xa08815af979286538c31b4aa5ec805053790af1ca58a8c4341be51136d094a8a05e569d876a079033298ad355ccb7ca8", + "0xb96c2978d0165d619d08281d295e90df78bc2375d0afbc3142ebff9c2cd4b0f0aa97a9a0e3740bc4dce0ff8a9fac8252", + "0xb7752cd0e582f35ab0d0036ca9c0a9fe893a6ad325164d78d865a604a85d3d23729e0362553e8b8a3d51816beeaa30cf", + "0x99cef1fafc29e7adfe247c753c475ad4bda7a5f9558b79c86e8a65968ede67adb38dc30071925c9d66a13860027a6735", + "0xb9f6c65af178c791b6137d71980651fb09cb5b42f268999c728c6e129985a9c7d77b3dc3b50751bd29ec9ee0b3111dfc", + "0x8d73ae61fff5be883a281782698075c5650083f00399992688738856d76d159803be0059fbd9dec48f4f0432f0590bbb", + "0xa8a4a2865226de9bbf19e12c7e75318439fa6cf1cbf344d5e79a8f363439d3bc5bcf4df91b54581e7866e46db04eaf0d", + "0x894582aeff222e145f092ba15c60d3207340c38f2c6792ee2ab4d82d50fb544ae366c2985cc2b6c2f970bcc5f4b46385", + "0x956014ba2d20a056fd86cb8c7ceeab9a2c6f905dae24fc1c5278fa5b84335148ebdefec5dcde8eb9b084700724fc93d7", + "0xaf217fe2b654eff6d11a2a79fe0339a1d4cb3708b7be9f09d852158b5a44b4f9b04406d6d67c4f144fb6b69a41ae9d0f", + "0xa90752a784bc00df94d960e523f5596695d16a534fc806179e0f878fc0e82a91b25e758e91a165debd815dd1af5f1028", + "0xa697606fb32979549ad822b31df8eaaf50de4ead984439a0a33e955937d326519bb9f62c8243ad37f764655f8d32cc80", + "0xa3ad4a30922e45a3e665551e5611384f1c2d414f6fa806184b0c826af05f014dc872585e255543794ee41e43cdadd856", + "0xb29c255843a82ea74a013bac6c36a694646e61e6b9cefc4c130e2ee261e3bb5da3e0fe3ee7e6fbb009deed0530bc1c82", + "0x87e1cc7febefa829cf050aa2aea59385d1048f8617abba691f7ea9ef58eb90ad12eeb9c439af228b0e34897ba1cf1b47", + "0x994d3222f89e9c8c154362190be7167c8c2662f0cfa9d50eb4d8175b255ff0de09dc548ee312fc8226963c8c16f43e8b", + "0x8f1a980be640820f2d1e953264ca4c30330878971669852be3d5d6b41c488be1628b935388bfa2bd4de484acb0fe661d", + "0x854d90d0721579c8c88e147a4aa83553c960617b18075f8224b975562dccb30b0e02e81fa9df7070f356a0eeffc3b14f", + "0x8e156da9d4330a03e32a25a2f0b861fd3ea5c719fa4f834119baab6e5fa5236a9baaf0d44147bf0841418900037f6eac", + "0x96586fc49e53a6799242ddf617000db5a0ad20c6cb1686af2102623d64a71aaddb8e468b15fa6d100d0384e448548db4", + "0xb44d8d85c8df95d504f82d597f8c515866d4d4a326fa1b816dcc5bb0cc4ef1a52647aa5d2e84c62e194c01cae0885d21", + "0xb75c43e676a7efd199f8b32ae31f176ec667e714df355e9eecee97246f72af5bef9c5b04c11e7e90fc37bb9163f957ec", + "0xa49835ac0565a79f6a9078cf0443c5be20561a68b448289589721fded55188583f1d301925a34eea647f90a6e66c6774", + "0xb47c17ff6824a00b8f29df0adb7f06223208d062bd703b0f763c6eee4ae62d4217eef2da4f4dde33f0b469c2f2db9e42", + "0x957cf039cea6f6d41e368e2bd0cf77315938a0738f15ed9ca342f0a28658b763659ac1d1a85ecb362f13de12b77bb582", + "0x903a52f8d2439fa63f59e1e9aba864d87b0464ded63814474947112375236a6f84e8fa003cc4433c8208d80e05fbd1b0", + "0x8afd524209ff08d1eb6312b078f7afeb8e1155af649e930ab711dedda226dc2db6b0354aab9652eea7f433f90015bf7b", + "0xa95c3c9277b11bc8fe191773bf567641be57c0549913b973fb18740ff9cd7b3f7ce198fa4dc1086b2b8a446012459193", + "0x9455ce8163fce04aeff61e7808ef3aac4725e51404f0858fe5d39d7344f55dcc7871ca332aa5cb1a63a4399529e48907", + "0x809fa35b6958f94e781f2c584438b33f5ed528a6b492d08960cf22ecf63ea3aa1e2d29bc879e17296e0a6cc495439cb6", + "0xb0f50774de212dd33e5837f6b496556215c665437e657f674fc5117e5c07dadbd0d057e6ac4c42d50a8eb81edfebf315", + "0x844c65e263891d0b2fea7db6934cc4b7fb6bee2c1d0b9ab4c47f2eb3e9c5d7197dad828d38c54139123740151420280b", + "0xb13c78c9efcbb3b28eb3fe0b971380b7d5151c80948a99cd93c78b4c3ab0e86df6226a64d91e0a2ea4a1c0a46bc0404e", + "0x90300a541decad460c348b8f4257f7a29687b2362ebee8d92fd03cc0e85b285ccb0ab1cb2ff5e29c5cc5295e351017cd", + "0xac49b409ded770c6d74f6e70104c2cdc95b7b90609da0743c9923179e8e5201ead03becc0ab10d65b3d91a5be0d52371", + "0xa257b815bd8289dfdfc21af218aaba12ccfd84ebf77642cc4cf744d9b0174ca0b0d7ab2a545c2a314fd5f63c140f41ab", + "0xa34778d8446e4d74d8fe33de64b2694ef1e50bc140e252af6eff3ce7b57acf8b6577a02ba94b74a8ae32e5113cf0a29b", + "0xab9e935bcf0d8607e3d66f013d9bce7909962cb7a81174923db02dc89e485c2b1c33d6065bdc7bbbe0450b5c49fbe640", + "0x94d2c5c5c309c9eac04be4636f61bc47fd9579b47aded57cc6c736fefb8dfd8f8a5de32210f7baf2052d04c0219d3b4b", + "0xb8dda9046ae265214086355101be3460421f7cd0ed01bde9c1621da510941d42bc93cd8060fd73f374fb1b0a5f38d45e", + "0xa6674649dab5f92ab9fa811d9da1d342cf89ff6eff13ad49f4d81de45438e81a384098d3ae5ccce4c67bda5dbe246d95", + "0x8d619f7564677bacba29c346c4ef67c211f7a3a14c73433dd1a7692e16a7e2562f1d0532454af62fc04c2fd2bb1789b0", + "0xa2b93d2fd4c707f5908f624a0fc889e20164d3c61850af9125f47a1719757a6ce6375aa1910eafa4c1e8b6e20c312775", + "0xa07d5585447654d82817ef4d199984542328b238157976eb9a267f0bdb2229acc25aee510be68f65a312b68fdd9e0447", + "0x8ef55cf95e2b24d8ec88e4136399a7763bd1b73d5e90ea45e9845123e9d39a625cc336e9b67988374b8ebcbc75f2ed21", + "0xb62c1fc32e27c767c461411b02fe9aa44a86586e1427406f4ef0b346d077db91952abce79318b382ec75b7be23058cac", + "0xb252900345f5fa15a4b77fb6af6a2d04db16e878b7bd98005333f7f6e3c8e6e46cf38fc5d1b2bc399c5c2ff4af730dc6", + "0xa4ab5ac0cc15d3d17b1747c6e3133d586870eae0a0d9c8fa7fd990ebd4fbb62e9090557ca2792a6bc6271856aa3c9a05", + "0x8e706b3f2e902faee10b22742c6c33bea6f670a8937c243db96885143c1db5c979e33ab73a38359b52b8d668ccd092a9", + "0x8a6792190ee6c959d79f60c22980ca140c638d88d75660adaf9bcbe6dc4692ab5f01e0c460170f09f74d5e582e85ff1f", + "0x97ffeedfc94c98ec85ea937e064d7b290a326838e62cebd407facd1ab4f08d9c0c109d79af7cb6170fccfa6c8243c127", + "0xb79970b67c09453614ffd83a0c923c17f857c6ce3c87a356298f8351cab0def7ed83efd4f6638f48df67e07bef4ad9d8", + "0xb90f1931c7cf1822cc0a97401119910cdfd0482daf09a4d7612e4e05046295cfb4cc50d5214b31676bb1a1c9d15f9c7f", + "0x922921ad813c01fb5d12fa7fb7ed8e0b0abbf7b19affa190b36013c55b88fe3c7df0ae663c970eec7725ba37b95a7cb7", + "0xa124f33e7f28feabb4089a063a08d52b7395d24eecd06857a720439dd9414b7073bb86fbd0b04e7bfac62d3dc0fdb2f2", + "0xb252fe50bc6677c004550f240fe670974a33ffe7191ed7675da6ac36c780c2f8d02be7da5d92cbe2d0ce90147847f8b1", + "0xae5f8c9c56070f919f3df2d2284348fa4b2e39881f7bc42c9b2f5b7cb1ebeef8ecac000f37329bbe04cc1680cefc7f4e", + "0xb432a4575caf7337f11eecfcbd34a6705d0f82c216301725ceae2b3c9df20fa53d1ebef65513e305013d1e0c2df522b6", + "0xb7c016fbbc4614cdbb12db1c9ac41f9a45d5e5ce82594d568a30cd2c66c3cc9d91a2c959697b67c582a0913de661505d", + "0x8f6f3e5e0347dddc1b2a34ec0dbbbb7cafbf976f19c9c902efb5c1427d1bbd4b71abd9f3fba20dda75c35a39393c989f", + "0xb0042a1d33a1ee9fdf3fad2299b8d70c4f1862d8393b5ebe3ac2189a2c5a58bb826128cd7a39b70d524a6dd976097e26", + "0x85297c4e8ae8d9b44c3fe51aa926c77d55db766c2a9f91b659040de36e34c9a4fc6f44380f8d61704498f6fd52395a49", + "0x8c61a988b6a00fe5a277450f30bf6daa932e42a2eae844568e3babf8815e09311f3c352dae6eb2d57a98d16b7beb2d22", + "0x990be28aaecd932e7edb2a97b9be2789a3905cb88737b1c79881302585801c69a3dd5fb230808b39db1352fc06e0b4a8", + "0x82fd14bdb335aa46f022dfe0ed4d631911e6b6f5eefb10d11e9e2e02a7df55012ed8162249d10b58eb76ced5a7b06cda", + "0xac39cb058df764e161db9c39b185f09aa210bddbd66f681f1697ddbe6b305735612d5dd321d3ffbb4876771bdb321e2f", + "0x858a3f7e57ccb81387caf8e89f9b6039e9aadeab06886d8688fe6427151a59ab2e77e85ba850c67d099965426c97779a", + "0xb57fb9ea623cec432946819937c6bded0b5d03c8c67b52b44a4b67d34adfb055e6cabca67a48e4d859b4be45162c5083", + "0xb84d2990b563d6d7fe1f4c1894989db25b81745090b94b1fe2ef708ac3b2110ef93d647820b2a51fcf78e3f00fef5412", + "0x817d85b9f5e1521733d2b1fa6d4f4957ac445dc803f97fc495e20b819b14e651332f9e0573d684b854fd47824c53f0e8", + "0xb09e18e97e93a8523101af594422fb71afc5b8826002314269016fcc1b44002d91bcb7c90d923d460f0cc03bddfe9af1", + "0xb867cbede82102de7cf6cd0dae68506869576eaa66c3fc806e73585310602682fc912dc37adf5ff6f0f34a07831735b1", + "0xb1126255798368b692f2796a3470ed16e5ffdee2d8c9e0f7ee3d2e92950c3e6365c32895171c3494aff2a6d6356f7e25", + "0xb05f0a0996dec16335c770a5df3f0b08e20020c838c2caaa1d3a4a2490ede98552f5de349de2ce6e4c4a839731d80919", + "0x98c512bb91c8fa191120ddf5d63c88076581cf41e15eec3c168822f12b3dd0ce4d6df74a7e3093d3e35cad1cb3135421", + "0x84ce38fd97f7f90012c2c1e59a67bf9f465a7ccfb6f308bdd0446cc82b8a26ff7c30e5c7cc375011718cad1b31adaa9f", + "0x93139db52c9fb96dee97a0825f21e34c5d6d36838e1e42f4d12d01eacbe94426c85a811fe16ca78e89e08f1c27383d28", + "0x81454037b1e7a1765f67e4288b8742eebf6d864d9b0f508ab44fa3243168ce0ed30cb5f33dfcdb995cd2c2710ff97a6d", + "0x828deb2a26efb2ff1842f735e2cc27162360f619b6e3e27a85bedf384912d4726bb2759a3016937973092ece1bf90540", + "0x87e5a7d4e7bd301078f625d9a99b99e6e8e1207c9f8a679f8ebbbfb467bfa0b5f7ef4a4d577c7d2670efa88221153012", + "0xb9dc9d0ea48deee201e34379447bec789c8924aecd030eeb93db159af77eff230976ef60ea9f4b4a9e9e95c1f9f4284e", + "0xaa6528268d46bf0627d87d58e243d3ac34b863513c725908a2617e4c6a46ccb1d8c8334bd6dd0eea7ffebec44259dae5", + "0x8d26c9ce07293f6a32a664d31e6df9a7ace47e6c38001635918efd9872aceab62de7757b13b783d422eb67bd28ce7bbb", + "0xb0d3ca88d9829a7459b89b0dcbdb8bbb5180b00d750bd959bd110f53c2dd5d4db554b6005c4765fbe7ec5903669e5ebc", + "0xa94d1c72bf3b2dc6bfebc9dee40f6a89a516b252bd9f4fad96f156e3dbfc151a9b8a02324d764c7656d59230a18eb61f", + "0x88996e79171e30b16505638d8ecb25afd875e5f3cc3e29860937f2b5e751c66e78dc77f744a0cc454a8a655142a93ffb", + "0xaf4d94f342665fe7ecda318de6cf1bc1c40c37dd83d060fedaf827459728152b5f0e280286ff5e6a0012036f6715f53f", + "0x96beaa7a2d565ec14a4e5cb895d33624c69da56b75c8d06ac729cb6d0cb64470ed4f9b0387083cd827b1609c8cabde8c", + "0x96b773fa2fcb7377bf71a7e286f37f1f24ee42cba5b4f33903c4566e5e5bcc501ea360e3c8435749107c3de84e272d8e", + "0xa69ac6218454c3f40ad0beb48821a218fb0a4f33ebade986d2fffd9a3900d8cfa613bc71676c46cfeaa5f644d1f239a9", + "0x857f139c08fcc45370f448ce3e4915bcb30f23daa4134407fc6d78efac7d718b2cd89e9a743eec7bf2cc0eccf55eb907", + "0xadeeba36af137fd3c371a2adbefea614c3ae3a69f8755ce892d0dd7102fb60717f5245d30119c69c582804e7e56f1626", + "0xafa97ca3548b35aeda6bfed7fbb39af907ed82a09348004d5705b4bb000173270ce44eb5d181819088aa5a2f20a547a2", + "0x8423bd2d07073b0e87819b4e81997e4d3188b0a5592621a30981dc0a5a9d0578fde1638a364f015078a001afb00891c2", + "0xb92e9d4ec3966981ee574695d6e4865810b8e75313e48c1e4bc5eebae77eb28740e97ecc3e5c42040f9eb1ee4b13b0ea", + "0xb07b218321d54cecfcd2ed54a5fd588a6be8d7a5b6a66dff7facfe061222c40553e076e57cbdfa0bdb08e0a009c94ba5", + "0xa71e1ae4d6096eac9ea4c21f621c875423de7c620544e520fb6ec3cb41a78554aedd79493cbd2c2ba4f0387f902ddd2a", + "0x807cdac291246a02f60c8937532c8969e689b1cfe811f239bfdee0791e7aa0545e9686cfb9ed0c1df84748e5efa5e3da", + "0xa1faeb4504c057304d27d54fb3ec681462384a354a4f0b6c759d4fa313253a789250c6b0f44f751b0718592637438a19", + "0x996bcd3215182d49f1cd15a05e1e0a4bf57e264400bf14f7253c6611d2571de7130cce81fd28e0411e0a80e9054f4f98", + "0x89d15b38f14bcd46f4b2dcae82b0e7bf9a35e40bf57aa947e9c4a8f87a440b5cea95229708de08ca596762062c34aaa0", + "0x8d8ddcaf79374c750b8b0b3d196acb6bb921e51b4619876a29d09161ba82a42271066187211ef746f9f40a5ca17b75f7", + "0xa3dc7f70f3a6c7edc483e712770abbaa94bfa3174cfee872b2cc011b267e0ef9baa1ab49e4a6c6c30dbba0e0a1237117", + "0xaa9e958bbdcb192b19c43fc6fd34afcd754949fdada98e9f4848e8db0e23acb27d19dd073c951a8819000f2356aa22e1", + "0xa4714e45ec853eadfe5c3bee7f683b81f97857bbd7833192a48936dd1460aee68f700a21658658b74b737c4fecf90c7f", + "0xa1ecab4215c1892e4a8ff3405d710163875e5dfef8a8cb84f5cac4e317d89c7696e3f496ed1747ca6f52b304190f4ba1", + "0xb9b48943eca3686219575026d395b969e6ff8159dc5317005df090e79d26901984e40ae4b1af060ed3ff6f42e0417d76", + "0x9644b9f90a66edb0396abd8c00066886f978ebf56fc22081031fbc9ce371bf9b04aa5a4ef59e59319b3a05bb7fb88b43", + "0xb2bb14f1c055a78596488e4e2d4135a6470c1ee43961952160b8498f674a4d23040606e937c02c1fc23dbd47e9bd4633", + "0x8c61f2fce9a42b94a389c7e52d7d093fc011099d0f4914f6d6f05b631df7b88182826edf9bbb1225971a080ca5c0d15a", + "0xaa6a7b8499cc7d256043eacad18528d38bf3be970bea4c6d4cb886690280bdb373688ceba3e506471e1d9493dc76f3f4", + "0x8127703363b3b35b06762c2353d4de82b7b85bb860db1028d3640f46bdb78f2d104fa77ee3e0d9db83833d2b12a966f8", + "0xb7b01f5909f2c66ae0fab156be5d79954e3a304615e1fe55945049dd4bd95f973bb3821117eb54db7e9ed1ee9a527652", + "0x8be47ba5dfe212420649193490838670c40540e0ea24adbab18c4a66e7ac3dcf94f068dec2533b60e08c1f64e7533e54", + "0x905a6c7e24b86aa54a05c329a6b4616d335bb0b1f1e9987562eee0acf82ad302c7c44981a1dd6b24c6121ca12fb92996", + "0x86969ccfd91deed93b355a2c21319e3bb08cc652b741463bf68c626b7ba2afce3f7cc397f2fb74588c2893477c948ae2", + "0xb5a9d20eb12c331d0d300fd4b85b0ac0bb74573178a5fac8ec9dce5e95acba07fab444260355ece442a846737a2dcd1c", + "0xa13497c11df21b11fc1a63b0ffdcf7f432da4dc2c98f8d07d36da4fa68aceb57af2158088e5b05e334fe0f264aeb7a97", + "0x882e4597cc66498a45e86a2ed9ee24652da4699af00ad35f73b5e74fde6ac3cee70630962d5ddd86162d4aaf11bbc11c", + "0xb748858c2bafa4a14ce44af35195e9c52aa75e109719243bbe278095acbfd6a7ae7e084caf8dae6939039b5a4e8fd675", + "0x83a2e0524507e74f51fe976441108f8226ba1b3a33f4e16ec45c5661ce80cb1840a93d17122cb8ca9e0f80d14f69877d", + "0x846cd2946c93ee5f24243d9ebc69936b3a1a6d59f45fec6c79b1eddf15ce30a8e73ad03cf606ee66baea3d8ff115f70f", + "0x8d98d0a3a94f6efe158f8423c041b546416145c5c2254bfa157efea0d1c99fe58acc7df6424ef29f75960b18d664ea4e", + "0xa39fa47e4b79f54dbf59d0b1726f1e78bc219fcfc56ad238c84b4b610e7892ff1e65d537baf5118a32f5e2eb80d5ee0c", + "0x8c30969a4519131de5e30121c84c04f67b98c8ad109fa4710dd3149cae303d51778add3f258f0482f1c89c169824dffc", + "0xaf7f80d141ceb78b4762015de17fef49d7ff6202d292e9604deb508272ee7569f7fd5be3b2438da1dfecf0c26533ef86", + "0x97cf82f70128251944d79b8845506975405bd720e150d836205b048ff36ba8801eb74cdcc6425f28f6bc0acec0a81463", + "0x8c276c876eb88688957d1868bf3a1462375e608ff72b49870a5dac82cbf6584e00e3f36f236f732348a47502ccf9539d", + "0x964765f1a5c8a41d8025ddf56dc01b78424703d8a64a4e5539e477cb2445cb541c70127c561e717256d13f91a830ba83", + "0xa2aacd9e21b8c8efaf2319611addea1b9f41430aee42e7f2a640cc693aa395287cc8fdc2806b76b577d84fbd05378ead", + "0xab11eabbf5be4345a77323a3b75f9ee93b011fd2a9d0154e88183cafe47f82a7888666af16b40d3cb677c94bcc755ff7", + "0xa0bfe715a7af5a29b1b6148b8cbee585d2b49fa6ce59bcd173ea3bbc60d71a62f9da27ffcbbd5a6da75502112fe44d70", + "0x902e6cc38ee42245103d90b65028a471bc7a48b825599d361aa81d8c56e0fcf9fbe8d4c13802040d2cfb85b7e022eea1", + "0x8832e2b5014fdef4003bdbb87e3298fdbdbbe49673f6b66e2373f1cb2605f9c4af2cdf9bfd45d1993208681d29ee1c9d", + "0xa7d39d3fa1ec1e0c87730fa43d4900e91932d1cafb36c76b2934907becf7d15a1d84d7234591ad4c322b5a24673bba8d", + "0x836ed5f09d99624204aa3aa7ac601980fda223f3b4b96b4a8fb235c574a3545d518787c12f81bd5851987f2860d41886", + "0x94235e94445e6086f6e9331923262070a4c2ed930ec519eabb8a30133bd4fc6debb99185f4b668431fae1b485c5c81b7", + "0x9828ffe20b9405f117dac044159be2d3c6e2b50ecdd1651d6a73f7633e6e2a7ba3d783ae939973604446d3a1ef0fb20f", + "0x92f03dc365dfe9154743ca70e6dd2758f064e3286fc543cf8c50f68effdf7c554bd17b3507c6ff4127046d9bbb5522ef", + "0x91ed07df479d8eb3d31292a0e987672a7f3d45ecafe72935b7abbc3f23493605134ce573f309e226c9efe830b6868220", + "0x93bee582661e6d6cefeff29002afc2f36dd2c13dbf33f0574c35b290ddc426170a5f7f196369ad592efcd72cfb6f8fc0", + "0x89a51467d966f48fed15dea5a12dda54d0015f69e2169b5e34f44c7b5a5d4c282d6f138116a0cd06a8476980e420f8d8", + "0xb8ccebc14b6679ba2399370848864f15f63512fd6139df7359b7b93e82c1007fd85137ecb0597294b46643e1a9e7ab5e", + "0x841fa301567fc57b2cd09508ce75326684e12bfb8add671dc208f579b2500b93d5b641e9f59bba798ed4ed1259757f7d", + "0xb3cb45c15eb00b4ccb7013299f761cb8fefc17adf6db50e9ecb8abe927a3bc7f28e359e64693813e078e1dac800ad55b", + "0x96e55d3b9f445f5679e34fa5425b3e87cb221cfbdd07f8353868c7f7f4ba388ee3841cb9a1d638583bc20d03a9d071f2", + "0xa7dee9377de740270c5b57cf86699004ba8dc2766af56b388b5cb0814ec71bb99ecf43ee3d82a552733854ecc7def0fe", + "0xb129dfff23b3c1c95ddb214c4711961fcb129efe2b6557ec9e116ada909593d0d2eec2c628434493393c58c52aa86847", + "0xaed2670e201cb3e38a8be3c86735a4d76255e1e5a4c67b91df6ed262d09c8d10b0a3891da3e6ab934058cc9a7178931b", + "0xb20b8921ae52e5b3c94fa3a8b46489044174f7b897779e7763d6eb419e808d76705b7e7ba5131576f425aa81b6b0de53", + "0xa7e45bbc3ba1bc36617291ba7663806e247f1b57a89e31520c64a90cbf8d426cac2e2f381338baf78c8f92fdbbcb7026", + "0xa99e651e73a507e9e663e2364fcc193ec77e8afdc08c2bed6ad864e49b537ec31e9114ee72291a7657899f2033a849e2", + "0xaf966033636c2e9e8280d173f556fe07f8b6940bbcf6b2df7e2165c30bea66cced2596f6c17ca7c1aa0e614174953ba9", + "0xb69ca7a79e3d55ef21e0ebdc6f0c4bd17182d30cf6290cccca7d2551c91c12b966020d8e40e4ee4179488c9809c03ae4", + "0xb981cd36244e035fef043f70b1d7188d7cd045b4de0581c459fc5730e10eb7f3d5893b54cc4243849c0855e4e621167a", + "0xb20fea858a36921b35a3051ce787b73f70fdecd3fef283c15a2eb1bffb1dcba5991eee4a047ce4e87802da923fd9457b", + "0xb040e6f2e56dc1860274c263d4045837456f74b354a679f6b5ea70919835ebe5d32bf1f519e218730096c98ff396dc9d", + "0x8d2dd60e702c923a7204b530e7d6c193c6f93ca648c4f7bb38f4edbeb0aaed84184213afafb8db6aeb9197c24364276c", + "0x95dfa7348709e43d71285b28a0bfad3ca805b6ed4ae99753e9f736c79d58a35a3a50b42760ccdd03eda50f6e59494968", + "0xb8585632a13f18c139a411bb2f02df809591834d127cd1ff081e26d0abfe0e3fbb54abea26538b25a0dcb4d7e969590e", + "0xb46ba47858a29c6d523c9982660949567666daf2582b93393a4802a9e077eedbc0d49d454731696bc8e46ca50c7caa40", + "0x84b756b901b98a4404e58d70f39f6ccac877146c866732ae65e7e82727448d1550343bf7cdff1bfd4ee1ed73793db255", + "0x83e5be888eaf877a2c755897410865f64a6d1169a8ccf0336092f3932abab915e542ab75a35ffe016042340d581ee987", + "0x8cb274fc39285aed451a7def72cfbf73168ee10be02affe355a2bf87cf361a81ad284e9334cf00c5bf99a13d9f75e116", + "0x91ff6220924b94ae13f50eeac16a159232e4f16a73fbd5c22c0e185cd1998403904d36bad203baa82b85819ee4a8ac10", + "0x87f46e08e09aea2ab37b55fc300689d9b58ff3e72f1cffe023386035888f714fac4673c7c5193d3f3f3c568c640694f0", + "0x835d7d84ca7641e1b15095830114aa6072fe12260d2202456cafe2308c22651af9ffbcf6b7e56af97167dd0c4e2a4cf2", + "0x91202183f79794f114fd9e3b9bd05553c0e8985919965101a57d97ef666b028863e6cea9735af016dc1864f1542dee51", + "0x81ab2b02a9b0a490a74ae615ddd4fe560734c1bfdde6b8dd13303c1481ba0e8ab14473535a93cfe4e824a0ab29445f8c", + "0x8a32d73f4fc006551d4e2c61eec6130355ec9b8c39a65c24ec1edc00e80155ca83a8ef2455e892521a3d47634d82a987", + "0xaf70d7b8f13bc90193cc1cfb0c400c4224cf10f1887848aa93e6380f7087782fc41a159926ab53c53eb95c2383b1a849", + "0x989bf42f9d357c51774f1c7c0f7c0c46a8cb7398a74497141c32685be098e38b4230ffe833a6d880ec391a35b1a747b6", + "0x94cb6715ee95700020c630b8c19e35f231de970219bd7e6ba7ced01899197da473b6c45cacfab0d652ddaf547b4ea58c", + "0xb12e3331f1f7d7458393a785e22e9a5e1d1daea521b4e78c0ee8ca59b41ade1735a29820e18f6afb2f2c3c56fecc16b6", + "0xad4b7cf654349d136fb41fb0dd65b588199f68b462b05f5c4e5c2b468bfaa6c26329033e3c3f7873dc8ace89cf873ea5", + "0xa3279969e1ab596df0559ffc5ac7a6dc849680354e01c3f4fd34c6413a3f9f046f89c1e1be0b315d8b6dfab3d23d5c14", + "0xac74cc5562836ed89d09a9ae6a3644c936d64bdda9e77659d9982f1be29541b03ef2723236d5465e398373ea19a4ccc6", + "0x98138ebce1af531dd8b631b3e74c84f0c700355a2a9bde31e5e51bb10c8bbd766559c63f6041f4002568803fe08438e0", + "0x9006445da131349fe5714e0777a4f82a82da343612589a0c1596393e8b6894ce1cf42784f95ff67a8384ffe1f1a4ad76", + "0x88502a84a85e4ce54cfed297b5d355867cc770a8ffd0714a6f23b1ab320a9903c6e42809e034bb67dbf94c4fc0d9c790", + "0xaa8b4bf123d1a6ccaa44b86be8f980005f2a0a388a76cb111b0e85cd072ef64167fb0c097c7b23c4bca64c0260f6cce0", + "0xad49eb35dfea9feabb513a78dd1152ad7eba22fbb02a80cefc494a7037699c8df81202dfec12acc1b9e33ad680cb72d2", + "0x8694da730231b29afd5196371ddcb15b4dcc499574bdd063f4864ab80749833ea38ab8b0ca1629a367fe378e87a60a86", + "0x8eca7b488e810c479e7e32e24b8afcd837f7df183fe4f621a0336b53a9ed77603c84bdc365d8be68179a32b71a1deb7e", + "0x8875cd3e23c7e1af55af1b091025a08255743984186770bcd43f30b4a58d175cfdf1984bad97a15e08dac2da27198c3d", + "0xabdafcf58ec72997e494d4714645f40d09dcd0fbd0733e640eca44eeea67c25bb0c270299c459991f2fae59d13b4f4d5", + "0x8f040970141e61489284f3efd907705eae6ec757fe8e1d284eac123d313e9ac1e8dc14ae3f04d281e1effc49d5d2f51d", + "0xa7ff115f0d2dbf66c0e8770b3d05157b37357b9e33e9a447f0f3fa9da69ad04e371fd1e4848cfb9e8d05e3165bd969d8", + "0xa39b1a8c39d317fcc97bf6c396e6ed4a85640aeeadbf45166bd02bc3bdfb6266509159c03afd492e642384c635b824c0", + "0xa2e1b90f3dd2d0038eaa5be52127844ccf35d997143179d95ffd3749c0896398b130094d01eb1bb31ffe80ef34b42b48", + "0xa2bbe31f89b0c3c375ffaf63c8b7831860a921d5e388eb7907dbf61f2601ea40db86bb3952ecaa26a5eca4317a848ff9", + "0x87d885bb0f2ce04b40ce94d2557c15f1698dc652e938f9a2d69a73ccf4899e08eafa1a59a20cae92823795f5b94f04b9", + "0x8f7746370f8a24a2889d351f3e36b8a7d60e75e50e8f5abeea7dafc75441e95915721654e61ceac51bb6f112780d352c", + "0xa7272847526ed3d9e0d0fea1d8685b07b5b908971490bf8a46748c8b1783c629b8644feb5bac772ae615daae383d5e72", + "0x978c9aa2996d8bd6fda7e0393fa8b38747f8f99712427705c00f6e9a12c36f8d8b4cedb03fcb9867155cbddb5200e6e1", + "0xa4dec4a2354b2b32434c5bcdc380bf84580c6f9940f94dc0498a5bfe89c675a0921e66b807a3d859a6059a464cb2a9ac", + "0x99459ddecc7abce437f68722dae556d8ffaf8ed974f459e52e6d4a64f176caa4d42c2f2ec57e8a5b5f2034638e8acb0a", + "0x928c68c0c9213fe6258ab5bb0c693d97203d15da359784de7824dec143212da57d062a1fc70a79172cee31adc7aff382", + "0xaad3f318f1622ea87e12541dfd982d71629b8f1ded4c301f9f6b6af9432716ad057773c33bdaa6f15dc151b0ee4505ea", + "0x8eb8e978f149a983fd6ad01773f9aacf57bd0cc622d8a301e404184b37e610123dd081faeda571a0ab1f149a3960af10", + "0x851e7191d7b94bd422bcece5b92609fc1b1c8556229bc53e32963b2d2fd1cacd8ce5da9040b599eca6e610540f8a7987", + "0x9414157fe9d50e5a0b5a7397417681bcb3a651eec1cab63f2a88d5df68ab1fef6e4c1d7ba657cbaf241a7cb790297633", + "0xb5cb2dafdc5408959780754a58b2da55b2a9136672ebca42f34da4e329ddc89360e7218cde3efdbf784ddb390deacc57", + "0xac6b70f65503a8e94b773fda3e72615745824930114fe72b6d833484285462392617c1b2eea4a250fedbee88f503f3ba", + "0xb0829a5312f9ac6c06fddee2f835a3452fe994f6d42c9edfc390d7d5b3240ca544433b544cbbddd6516b38a6d5d7c21d", + "0x95f8e2c59905957e34d53be3d6fb85732f834e2cb9ab4c333fea2f502452a87ccd035fc9075d7c0bd8530bb0a0c96527", + "0xb93f279b7045f2d97c674495f6e69a3e352f32f43cc60300193b936c2850b2805c15457251f7e3f633f435cb2b60405c", + "0x915abf16cba1a0b655b92a8a70c03e7fb306b86f3bbfb66967ca63e64c003b59c7a5953675efa4fa0bce9bed536b6700", + "0xac2047f50a319d09df1ec44d71afdcec5ac3bd2765dc98aba347734aa780863545df9f6d71214d443e3f37edc0dae45a", + "0xad49c74ddb24c8a26b14ec08bc807313c77c5967fbb36237f55994d7511bbac8d7e7b9b8ec53eb1b3b066989f078dbd9", + "0x961483105f605e959213fe9e8a52b76dac62d7efd2319ec71fc4e92d68fbe44cd2f65d7adefb2eb64d591b91648b8085", + "0xb67fcafc97d8df2b3075bbff7b3d7471dbf1f3048f309e55d5e2c5bcbc7a73aebcb0697859be9f387cbc7ce98041e154", + "0x8da70ac16468cab6066992389cb37c79ff5e0babbe67d76878aef9408b9597a3dc2eb5de87428bc761a0d78957b0eb28", + "0xaec0ce89770d299b631f15ae12f94b1e1014ac57d38fcf037c2c7712d770d074affa06e97c60691bad8733874b6ad2ed", + "0x8b702c85fa4c915a09fc86507f44d7aeda0993b77af87780d70cc98d580c6e996b64b7c16cdb4dd4562cb0f75da36ee7", + "0xaaeb43aa472aac2253e211fd1066c3a5422ea041cef20168702d0618a1a742a44f7fb30a76677640fea1a24e7fae1996", + "0xa8820e92825d6e02b9b4ad5ebc86161d3244cddd3d244333ba1576b6ae10948145b68d9e926bf6b7a2c25dab4cf43f3e", + "0x8ffdae28a1f1d15d7ffa473628a66ee9a739073f59ba781248286b39cb8f7255f66d62337064246713cbb5017e615174", + "0xadfc5dd142b7911326d8424881d5d92006f3b17de4cce91674d6ea37f00fbb266c791ac13f6c7a0f61d04f2a952e6a04", + "0x87f98982444bf661f539bec73a10256f079a4baa88a1cea0351ae3de929e1c500485b2d1b5d933063cd7d9123d5050e4", + "0x8f217ba4dd404c5ee384f0c9a126686db001ff0344c01c82174c5e5ef89d1a241b146008c534b13a0da6c8afe7450fbb", + "0xafc85476dddaf1cbb4ba8b22186789f3818c7964f9f613e55010278800cd95422702248bdf9c73760702ef24854795ec", + "0xa59e0f6ac2ccdfbd01f002008034390c0ea78716f5e0de4e474e3558755705c9c7afb6e3c5c4370e7bbc85958a9c7a63", + "0x97c0695c58d792ec31d9b86d3b2fc1382f0855057b24d5f6a54c41f76f9e2f52882cadc89a8b2f121530e7f1393faa95", + "0x8e49112de0b2649c08a96cf737af68fa8055f1af594846a2d0534c94df6f926f200405edaa6e6ac9db7e380707a2571d", + "0x99a1bd83a7ac5f8d77ddf044c80ebfc5745b998714696d67b94d185c97e9d6db989bacac646d9def463127a8b2febc00", + "0xaba80725f9f9f7abe10760eca73ba427ca8df864a157122eb9af828a05b0199de3add02019a297750bdab5380e505c58", + "0xae18f62573275c1eb268f74c5e54e8958547f9e7d1d36a05b084eb53e5704fafe2200b8aff95cc7e9af5be2391c42b7c", + "0x908b8031d09d22b2aefeaa876a998e0a97c7a1070aad9e9c97836cc5aa6d2d5ef94230e1222074837b5e21b4e6490f01", + "0xb3132282e8b41ca6789ec5c43c1fecf3a65b8eefbc2f3d10f746a843b9ba4ce6db664678e75e424f7b11a00c1440de15", + "0xa1eb49440cc106ebc09cf198c93e8070271eb5a936d31c04858a2b311a037350100c7957d5545c9653f396aa968b91f4", + "0x81df6ad1bdd5eee4cc2f94318467b8602d15cc1be2b48b09ade12cc46ee05cbaaf77a20397e5015030b1f1db5dd9dac0", + "0x87236c68a2a93c8442d15d7f1d1dc01d1fd123439c183e1d843f4ddd2bcf638c128f66f1ef9b710e5d1f64a52726007a", + "0x84f2e7f85563bb2f61b10a712c7605d63f79af5be0dba056814fd3efebc20e9c53227c56577b72c68d185571b775eff6", + "0xa36d4ae06688ece2927aeb2c7f058a3cd2aa1de1601282d4e688e1d76ef20728b892928deda2314eba41675eba3912f1", + "0xb8326dcbcdcfce017b263c456c47692fb476c4225c95981666fff0b7d4522fc23b7f12273f0f47cf0442662124e6648f", + "0x84c66463ab277cda2cc7007d0509269e89cdd41c5e0d3773a92615f0fc5da63811186b05d7a11088048a5d4834a7e0df", + "0xb20d3571d970712ef4699b0e7034fd269c361f53e1572e2ea2676b4245e992d43b8b5931a801439a44d977a988cc360b", + "0x94dba6007e6d4998ca1eb84aa8e2a7e9f5c164b9d80df2825f2208ce5640a05aacac2e4f08918268990f43ae1ccab69a", + "0xa1c25f0b3ef9d1982153207570d9ce8d692e1b6963b509958dc4d9bcd80074bb221c46804a6d9a29e76149cc7787c282", + "0x8857748fcdab1199fc96084323a81d3bd8b5a7f0b1abc5bc3b5252a19268344e2e7d2d086c90fc9b5fa4b92feedb93a4", + "0x8b9c1d841447354b6c086549e4d1d435ab64c13933488c34bc30f0f6eb36c5c5b838b7b6bb018542247edd1ada091045", + "0x8f5b655416da0e719a204fc567e93792c301acb4374cf7bbabc6ce51dbeaaadfd75c2db0e16ce073ab8e91fd3d7ea9d4", + "0x90f2846b19be46a75c5cd0cafefcf9192e6fd80c479e8d6320c4b8d8d7d96703c9e77ff31a67afa9858e6b7bde1f7cce", + "0xa53e383947fd98aa1a55ac956214b46b20a52758461e8ba41341a23a835ebb713038bf048edb1202bbfd0b56a96bf292", + "0x9542d7debbcfb9cda6fa279c699a7b655c03b9a9b456a5d3cfc41a826c94eafa43e01155a29e39ff0bcd965f4c0c512d", + "0xa43792864ec5fc549f7afc02622454afc0e425c310c4039ba615067243ebb26a4c7ebfd19bd4d57ff412a4bb2a7958a0", + "0xb85123950e30c048465bf32365d24a5d4b21fffc6183cdbf71643a07b87463989b72dd9a6a47f134856f704909a6b38f", + "0x944ea689aec1376f855c0bc9c51378ad06ff758a2c075b95a60b535b88b36eca0be11e4edb5152e98cb2137d6e749f27", + "0xa6bef52cda22325e4c62d323e2a0e3fa91c5552fcfce951edfd52ad6f652bfdcc2341f1cd349e6b5d447924dc569bfe2", + "0xb56bff8ffe981bfcb30791836da10b87f2ccbe17ed969e7f7a650af07d27ae0223805b1264d985148208483be50578a6", + "0x8b209cac898dd580c82d854a553e2517497ad1a4cd198e1360b8b50639b380aee70ee4b87625d9b2278228ff644cd25c", + "0x877cce233fec74c7158b3c5bf108365e98238418b8a71f058f1aca44a0fd3a1021e3e9025bd11fe244d9fe0f5034ce7f", + "0xb1b871aeedb03d6f6accc99816b89f5958178738d8d8cd9717527d04363c80fdb5f6848122ae19fdbc450cfa11e753c8", + "0x858aca51b9e5b0a724e88688d5124eb24c9faf01a3d465e74d31de6da315f311143f22f60201ea09f62c92f61f09d889", + "0x8521d409615dfc8c8289e00f6aaa6297c2c4e1439b25952afd76aac641b81c70b9cef07cd58c1c0198382bddd2bd8544", + "0x88647c3e41666b88acca42505f1f5da226937e0522b538fe0cebb724e9a99730ca2522989e94a96cac94109aef675c0f", + "0xb417fdaf719caf38854e89ce52031b30ce61a632e6c3135adec9002280e022d82ab0ea4ac5ebdb21f1f0169e4c37bcda", + "0x9367a6feb5e23ea2eab8ddd5e7bdf32b4d2419fad1c71a1ed327b77362d8942dad971a1c2e6f7073885149cdf0a0c339", + "0xa71c5c08d50c57d094d6a4f02e97d3799bada92f238ffc07bd223bbe8379507b7310d20b28f5bbbf331e5e153515e491", + "0x9630a9a3bcb044b51299c4d3d3388a4ff47308dd27be3229601985478c0f6b55faa7e20815d8694f910611396a9d0d45", + "0xb0bfaf56a5aa59b48960aa7c1617e832e65c823523fb2a5cd44ba606800501cf873e8db1d0dda64065285743dc40786e" + ], "g1_lagrange": [ "0xa0413c0dcafec6dbc9f47d66785cf1e8c981044f7d13cfe3e4fcbb71b5408dfde6312493cb3c1d30516cb3ca88c03654", "0x8b997fb25730d661918371bb41f2a6e899cac23f04fc5365800b75433c0a953250e15e7a98fb5ca5cc56a8cd34c20c57", diff --git a/go.mod b/go.mod index 5ec51dd1ea..9682685937 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,8 @@ require ( github.com/cespare/cp v0.1.0 github.com/cloudflare/cloudflare-go v0.114.0 github.com/cockroachdb/pebble v1.1.2 - github.com/consensys/gnark-crypto v0.14.0 + github.com/consensys/gnark-crypto v0.16.0 + github.com/crate-crypto/go-eth-kzg v1.3.0 github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a github.com/crate-crypto/go-kzg-4844 v1.1.0 github.com/davecgh/go-spew v1.1.1 @@ -21,7 +22,7 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 - github.com/ethereum/c-kzg-4844 v1.0.0 + github.com/ethereum/c-kzg-4844/v2 v2.1.0 github.com/ethereum/go-verkle v0.2.2 github.com/fatih/color v1.16.0 github.com/ferranbt/fastssz v0.1.2 @@ -91,14 +92,14 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 // indirect github.com/aws/smithy-go v1.15.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.17.0 // indirect + github.com/bits-and-blooms/bitset v1.20.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // 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 - github.com/consensys/bavard v0.1.22 // indirect + github.com/consensys/bavard v0.1.27 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect diff --git a/go.sum b/go.sum index 40800ed257..1ac65bc01d 100644 --- a/go.sum +++ b/go.sum @@ -90,8 +90,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 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/bits-and-blooms/bitset v1.17.0 h1:1X2TS7aHz1ELcC0yU1y2stUs/0ig5oMU6STFZGrhvHI= -github.com/bits-and-blooms/bitset v1.17.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -124,12 +124,14 @@ github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwP github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A= -github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= -github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= -github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= +github.com/consensys/bavard v0.1.27 h1:j6hKUrGAy/H+gpNrpLU3I26n1yc+VMGmd6ID5+gAhOs= +github.com/consensys/bavard v0.1.27/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark-crypto v0.16.0 h1:8Dl4eYmUWK9WmlP1Bj6je688gBRJCJbT8Mw4KoTAawo= +github.com/consensys/gnark-crypto v0.16.0/go.mod h1:Ke3j06ndtPTVvo++PhGNgvm+lgpLvzbcE2MqljY7diU= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= +github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= @@ -164,8 +166,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -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/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= +github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= From ba0a61bc2841e9aef1fe89a34ca1b073e05c6f3b Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Wed, 30 Apr 2025 11:00:17 +0800 Subject: [PATCH 323/940] cmd/geth: print crit log if chain config is not compatible (#31743) --- cmd/geth/chaincmd.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index c57a9a947d..1c82ac7c09 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -246,10 +246,13 @@ func initGenesis(ctx *cli.Context) error { triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) defer triedb.Close() - _, hash, _, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + _, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) if err != nil { utils.Fatalf("Failed to write genesis block: %v", err) } + if compatErr != nil { + utils.Fatalf("Failed to write chain config: %v", err) + } log.Info("Successfully wrote genesis state", "database", "chaindata", "hash", hash) return nil From 21341f6c0b03327612b66d0145071c1044eb128a Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Wed, 30 Apr 2025 05:02:11 +0200 Subject: [PATCH 324/940] eth/fetcher: define BatchSize as a constant (#31742) --- eth/fetcher/tx_fetcher.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index ff17ae4945..98a1c6e9a6 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -69,6 +69,9 @@ const ( // txGatherSlack is the interval used to collate almost-expired announces // with network fetches. txGatherSlack = 100 * time.Millisecond + + // addTxsBatchSize it the max number of transactions to add in a single batch from a peer. + addTxsBatchSize = 128 ) var ( @@ -329,8 +332,8 @@ func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) metas = make([]txMetadata, 0, len(txs)) ) // proceed in batches - for i := 0; i < len(txs); i += 128 { - end := i + 128 + for i := 0; i < len(txs); i += addTxsBatchSize { + end := i + addTxsBatchSize if end > len(txs) { end = len(txs) } @@ -372,7 +375,7 @@ func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) otherRejectMeter.Mark(otherreject) // If 'other reject' is >25% of the deliveries in any batch, sleep a bit. - if otherreject > 128/4 { + if otherreject > addTxsBatchSize/4 { time.Sleep(200 * time.Millisecond) log.Debug("Peer delivering stale transactions", "peer", peer, "rejected", otherreject) } From 76128727617dc50487c51039d08583edbcc338bd Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 30 Apr 2025 09:23:08 +0200 Subject: [PATCH 325/940] core/filtermaps: do not derive full receipts during rendering (#31716) This changes the filtermaps to only pull up the raw receipts, not the derived receipts which saves a lot of allocations. During normal execution this will reduce the allocations of the whole geth node by ~15%. --- core/blockchain_reader.go | 8 ++++++++ core/filtermaps/chain_view.go | 14 ++++++++++++++ core/filtermaps/indexer_test.go | 7 +++++++ core/filtermaps/map_renderer.go | 4 ++-- eth/filters/filter_system_test.go | 7 +++++++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index a8c2e26d18..b4ba5d9fd8 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -234,6 +234,14 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return receipts } +func (bc *BlockChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts { + number := rawdb.ReadHeaderNumber(bc.db, hash) + if number == nil { + return nil + } + return rawdb.ReadRawReceipts(bc.db, hash, *number) +} + // GetUnclesInChain retrieves all the uncles from a given block backwards until // a specific distance is reached. func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go index aa74f3901a..63df2cfb6d 100644 --- a/core/filtermaps/chain_view.go +++ b/core/filtermaps/chain_view.go @@ -29,6 +29,7 @@ type blockchain interface { GetHeader(hash common.Hash, number uint64) *types.Header GetCanonicalHash(number uint64) common.Hash GetReceiptsByHash(hash common.Hash) types.Receipts + GetRawReceiptsByHash(hash common.Hash) types.Receipts } // ChainView represents an immutable view of a chain with a block id and a set @@ -102,10 +103,23 @@ func (cv *ChainView) Receipts(number uint64) types.Receipts { blockHash := cv.BlockHash(number) if blockHash == (common.Hash{}) { log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber) + return nil } return cv.chain.GetReceiptsByHash(blockHash) } +// RawReceipts returns the set of receipts belonging to the block at the given +// block number. Does not derive the fields of the receipts, should only be +// used during creation of the filter maps, please use cv.Receipts during querying. +func (cv *ChainView) RawReceipts(number uint64) types.Receipts { + blockHash := cv.BlockHash(number) + if blockHash == (common.Hash{}) { + log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber) + return nil + } + return cv.chain.GetRawReceiptsByHash(blockHash) +} + // SharedRange returns the block range shared by two chain views. func (cv *ChainView) SharedRange(cv2 *ChainView) common.Range[uint64] { cv.lock.Lock() diff --git a/core/filtermaps/indexer_test.go b/core/filtermaps/indexer_test.go index e60130ba4b..2782b2cbe6 100644 --- a/core/filtermaps/indexer_test.go +++ b/core/filtermaps/indexer_test.go @@ -515,6 +515,13 @@ func (tc *testChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return tc.receipts[hash] } +func (tc *testChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts { + tc.lock.RLock() + defer tc.lock.RUnlock() + + return tc.receipts[hash] +} + func (tc *testChain) addBlocks(count, maxTxPerBlock, maxLogsPerReceipt, maxTopicsPerLog int, random bool) { tc.lock.Lock() blockGen := func(i int, gen *core.BlockGen) { diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index f59a01c032..74baec6a1a 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -693,7 +693,7 @@ func (f *FilterMaps) newLogIteratorFromMapBoundary(mapIndex uint32, startBlock, return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", startBlock, f.targetView.HeadNumber()) } // get block receipts - receipts := f.targetView.Receipts(startBlock) + receipts := f.targetView.RawReceipts(startBlock) if receipts == nil { return nil, fmt.Errorf("receipts not found for start block %d", startBlock) } @@ -760,7 +760,7 @@ func (l *logIterator) next() error { if l.delimiter { l.delimiter = false l.blockNumber++ - l.receipts = l.chainView.Receipts(l.blockNumber) + l.receipts = l.chainView.RawReceipts(l.blockNumber) if l.receipts == nil { return fmt.Errorf("receipts not found for block %d", l.blockNumber) } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index fa5d4fe897..122bdaeda4 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -80,6 +80,13 @@ func (b *testBackend) GetReceiptsByHash(hash common.Hash) types.Receipts { return r } +func (b *testBackend) GetRawReceiptsByHash(hash common.Hash) types.Receipts { + if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil { + return rawdb.ReadRawReceipts(b.db, hash, *number) + } + return nil +} + func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { var ( hash common.Hash From 701df4baad3bbdb0bdf4c837f19d25cb07ffc3af Mon Sep 17 00:00:00 2001 From: ericxtheodore Date: Wed, 30 Apr 2025 18:37:48 +0800 Subject: [PATCH 326/940] cmd/geth: fix compatErr in initGenesis (#31746) --- cmd/geth/chaincmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 1c82ac7c09..a947f35f2f 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -251,7 +251,7 @@ func initGenesis(ctx *cli.Context) error { utils.Fatalf("Failed to write genesis block: %v", err) } if compatErr != nil { - utils.Fatalf("Failed to write chain config: %v", err) + utils.Fatalf("Failed to write chain config: %v", compatErr) } log.Info("Successfully wrote genesis state", "database", "chaindata", "hash", hash) From af9673b143daaa0fbbf5528fe2aae8f2479ab83a Mon Sep 17 00:00:00 2001 From: Shude Li Date: Fri, 2 May 2025 21:19:54 +0800 Subject: [PATCH 327/940] ethclient: fix retrieval of pending block (#31504) Since the block hash is not returned for pending blocks, ethclient cannot unmarshal into RPC block. This makes hash optional on rpc block and compute the hash locally for pending blocks to correctly key the tx sender cache. https://github.com/ethereum/go-ethereum/blob/a82303f4e3cedcebe31540a53dde4f24fc93da80/internal/ethapi/api.go#L500-L504 --------- Co-authored-by: lightclient --- ethclient/ethclient.go | 10 ++++++++-- ethclient/ethclient_test.go | 33 +++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 352e6abc2c..9d0e0d5b52 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -131,7 +131,7 @@ func (ec *Client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumb } type rpcBlock struct { - Hash common.Hash `json:"hash"` + Hash *common.Hash `json:"hash"` Transactions []rpcTransaction `json:"transactions"` UncleHashes []common.Hash `json:"uncles"` Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` @@ -158,6 +158,12 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface if err := json.Unmarshal(raw, &body); err != nil { return nil, err } + // Pending blocks don't return a block hash, compute it for sender caching. + if body.Hash == nil { + tmp := head.Hash() + body.Hash = &tmp + } + // Quick-verify transaction and uncle lists. This mostly helps with debugging the server. if head.UncleHash == types.EmptyUncleHash && len(body.UncleHashes) > 0 { return nil, errors.New("server returned non-empty uncle list but block header indicates no uncles") @@ -199,7 +205,7 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface txs := make([]*types.Transaction, len(body.Transactions)) for i, tx := range body.Transactions { if tx.From != nil { - setSenderFromServer(tx.tx, *tx.From, body.Hash) + setSenderFromServer(tx.tx, *tx.From, *body.Hash) } txs[i] = tx.tx } diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 29e311c1b4..8e70177944 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -307,6 +307,12 @@ func testTransactionInBlock(t *testing.T, client *rpc.Client) { if tx.Hash() != testTx2.Hash() { t.Fatalf("unexpected transaction: %v", tx) } + + // Test pending block + _, err = ec.BlockByNumber(context.Background(), big.NewInt(int64(rpc.PendingBlockNumber))) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } } func testChainID(t *testing.T, client *rpc.Client) { @@ -619,6 +625,21 @@ func testAtFunctions(t *testing.T, client *rpc.Client) { if gas != 21000 { t.Fatalf("unexpected gas limit: %v", gas) } + + // Verify that sender address of pending transaction is saved in cache. + pendingBlock, err := ec.BlockByNumber(context.Background(), big.NewInt(int64(rpc.PendingBlockNumber))) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + // No additional RPC should be required, ensure the server is not asked by + // canceling the context. + sender, err := ec.TransactionSender(newCanceledContext(), pendingBlock.Transactions()[0], pendingBlock.Hash(), 0) + if err != nil { + t.Fatal("unable to recover sender:", err) + } + if sender != testAddr { + t.Fatal("wrong sender:", sender) + } } func testTransactionSender(t *testing.T, client *rpc.Client) { @@ -640,10 +661,7 @@ func testTransactionSender(t *testing.T, client *rpc.Client) { // The sender address is cached in tx1, so no additional RPC should be required in // TransactionSender. Ensure the server is not asked by canceling the context here. - canceledCtx, cancel := context.WithCancel(context.Background()) - cancel() - <-canceledCtx.Done() // Ensure the close of the Done channel - sender1, err := ec.TransactionSender(canceledCtx, tx1, block2.Hash(), 0) + sender1, err := ec.TransactionSender(newCanceledContext(), tx1, block2.Hash(), 0) if err != nil { t.Fatal(err) } @@ -662,6 +680,13 @@ func testTransactionSender(t *testing.T, client *rpc.Client) { } } +func newCanceledContext() context.Context { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + <-ctx.Done() // Ensure the close of the Done channel + return ctx +} + func sendTransaction(ec *ethclient.Client) error { chainID, err := ec.ChainID(context.Background()) if err != nil { From ed93a5ac04e2234055cf922b45cba579486a46d1 Mon Sep 17 00:00:00 2001 From: Abel <1033309821@qq.com> Date: Fri, 2 May 2025 22:31:50 +0800 Subject: [PATCH 328/940] cmd/devp2p: test for non-existent block request (#31506) Add tests for GetBlockHeaders that verify client does not disconnect when unlikely block numbers are requested, e.g. max uint64. --------- Co-authored-by: lightclient --- cmd/devp2p/internal/ethtest/suite.go | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go index 8ebbe2a05d..a16d308dfd 100644 --- a/cmd/devp2p/internal/ethtest/suite.go +++ b/cmd/devp2p/internal/ethtest/suite.go @@ -70,6 +70,7 @@ func (s *Suite) EthTests() []utesting.Test { {Name: "Status", Fn: s.TestStatus}, // get block headers {Name: "GetBlockHeaders", Fn: s.TestGetBlockHeaders}, + {Name: "GetNonexistentBlockHeaders", Fn: s.TestGetNonexistentBlockHeaders}, {Name: "SimultaneousRequests", Fn: s.TestSimultaneousRequests}, {Name: "SameRequestID", Fn: s.TestSameRequestID}, {Name: "ZeroRequestID", Fn: s.TestZeroRequestID}, @@ -158,6 +159,48 @@ func (s *Suite) TestGetBlockHeaders(t *utesting.T) { } } +func (s *Suite) TestGetNonexistentBlockHeaders(t *utesting.T) { + t.Log(`This test sends GetBlockHeaders requests for nonexistent blocks (using max uint64 value) +to check if the node disconnects after receiving multiple invalid requests.`) + + conn, err := s.dial() + if err != nil { + t.Fatalf("dial failed: %v", err) + } + defer conn.Close() + + if err := conn.peer(s.chain, nil); err != nil { + t.Fatalf("peering failed: %v", err) + } + + // Create request with max uint64 value for a nonexistent block + badReq := ð.GetBlockHeadersPacket{ + GetBlockHeadersRequest: ð.GetBlockHeadersRequest{ + Origin: eth.HashOrNumber{Number: ^uint64(0)}, + Amount: 1, + Skip: 0, + Reverse: false, + }, + } + + // Send request 10 times. Some clients are lient on the first few invalids. + for i := 0; i < 10; i++ { + badReq.RequestId = uint64(i) + if err := conn.Write(ethProto, eth.GetBlockHeadersMsg, badReq); err != nil { + if err == errDisc { + t.Fatalf("peer disconnected after %d requests", i+1) + } + t.Fatalf("write failed: %v", err) + } + } + + // Check if peer disconnects at the end. + code, _, err := conn.Read() + if err == errDisc || code == discMsg { + t.Fatal("peer improperly disconnected") + } +} + func (s *Suite) TestSimultaneousRequests(t *utesting.T) { t.Log(`This test requests blocks headers from the node, performing two requests concurrently, with different request IDs.`) From 86a492471a772fbd9ec71daecac55293f249a364 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 2 May 2025 23:21:17 +0800 Subject: [PATCH 329/940] node: avoid double close resp.Body (#31710) The functions `rpcRequest` and `batchRpcRequest` call `baseRpcRequest`. And `resp.Body` will be closed in the function `baseRpcRequest` later by `t.Cleanup`: ```go func baseRpcRequest(t *testing.T, url, bodyStr string, extraHeaders ...string) *http.Response { // ...... t.Cleanup(func() { resp.Body.Close() }) return resp } ``` --- node/rpcstack_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/node/rpcstack_test.go b/node/rpcstack_test.go index eb0bbac93f..54e58cccb2 100644 --- a/node/rpcstack_test.go +++ b/node/rpcstack_test.go @@ -570,7 +570,6 @@ func TestHTTPWriteTimeout(t *testing.T) { // Send normal request t.Run("message", func(t *testing.T) { resp := rpcRequest(t, url, "test_sleep") - defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatal(err) @@ -584,7 +583,6 @@ func TestHTTPWriteTimeout(t *testing.T) { t.Run("batch", func(t *testing.T) { want := fmt.Sprintf("[%s,%s,%s]", greetRes, timeoutRes, timeoutRes) resp := batchRpcRequest(t, url, []string{"test_greet", "test_sleep", "test_greet"}) - defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatal(err) From 79807bc3b16ee1dadb506c87917fcf042d4e186d Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 2 May 2025 23:43:06 +0800 Subject: [PATCH 330/940] core, eth/gasestimator: introduce MaxGasUsed for estimation (#31735) This PR improves gas estimation for data-heavy transactions which hit the floor data gas cost. --- core/state_transition.go | 26 ++++++++++++++++---------- eth/gasestimator/gasestimator.go | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/core/state_transition.go b/core/state_transition.go index 0f9ee9eea5..f9c9a2ab5a 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -34,10 +34,10 @@ import ( // ExecutionResult includes all output after executing given evm // message no matter the execution itself is successful or not. type ExecutionResult struct { - UsedGas uint64 // Total used gas, not including the refunded gas - RefundedGas uint64 // Total gas refunded after execution - Err error // Any error encountered during the execution(listed in core/vm/errors.go) - ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode) + UsedGas uint64 // Total used gas, not including the refunded gas + MaxUsedGas uint64 // Maximum gas consumed during execution, excluding gas refunds. + Err error // Any error encountered during the execution(listed in core/vm/errors.go) + ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode) } // Unwrap returns the internal evm error which allows us for further @@ -509,9 +509,12 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { ret, st.gasRemaining, vmerr = st.evm.Call(msg.From, st.to(), msg.Data, st.gasRemaining, value) } + // Record the gas used excluding gas refunds. This value represents the actual + // gas allowance required to complete execution. + peakGasUsed := st.gasUsed() + // Compute refund counter, capped to a refund quotient. - gasRefund := st.calcRefund() - st.gasRemaining += gasRefund + st.gasRemaining += st.calcRefund() if rules.IsPrague { // After EIP-7623: Data-heavy transactions pay the floor gas. if st.gasUsed() < floorDataGas { @@ -521,6 +524,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { t.OnGasChange(prev, st.gasRemaining, tracing.GasChangeTxDataFloor) } } + if peakGasUsed < floorDataGas { + peakGasUsed = floorDataGas + } } st.returnGas() @@ -549,10 +555,10 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { } return &ExecutionResult{ - UsedGas: st.gasUsed(), - RefundedGas: gasRefund, - Err: vmerr, - ReturnData: ret, + UsedGas: st.gasUsed(), + MaxUsedGas: peakGasUsed, + Err: vmerr, + ReturnData: ret, }, nil } diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index fc8e3a2e42..98a4f74b3e 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -144,7 +144,7 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin // There's a fairly high chance for the transaction to execute successfully // with gasLimit set to the first execution's usedGas + gasRefund. Explicitly // check that gas amount and use as a limit for the binary search. - optimisticGasLimit := (result.UsedGas + result.RefundedGas + params.CallStipend) * 64 / 63 + optimisticGasLimit := (result.MaxUsedGas + params.CallStipend) * 64 / 63 if optimisticGasLimit < hi { failed, _, err = execute(ctx, call, opts, optimisticGasLimit) if err != nil { From 341929ab962c46b910ce3bb4a0f4d22f2048b1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 2 May 2025 17:50:22 +0200 Subject: [PATCH 331/940] core/filtermaps: fix log value search range (#31734) This PR fixes the out-of-range block number logic of `getBlockLvPointer` which sometimes caused searches to fail if the head was updated in the wrong moment. This logic ensures that querying the pointer of a future block returns the pointer after the last fully indexed block (instead of failing) and therefore an async range update will not cause the search to fail. Earier this behaviour only worked when `headIndexed` was true and `headDelimiter` pointed to the end of the indexed range. Now it also works for an unfinished index. This logic is also moved from `FilterMaps.getBlockLvPointer` to `FilterMapsMatcherBackend.GetBlockLvPointer` because it is only required by the search anyways. `FilterMaps.getBlockLvPointer` now only returns a pointer for existing blocks, consistently with how it is used in the indexer/renderer. Note that this unhandled case has been present in the code for a long time but went unnoticed because either one of two previously fixed bugs did prevent it from being triggered; the incorrectly positive `tempRange.headIndexed` (fixed in https://github.com/ethereum/go-ethereum/pull/31680), though caused other problems, prevented this one from being triggered as with a positive `headIndexed` no database read was triggered in `getBlockLvPointer`. Also, the unnecessary `indexLock` in `synced()` (fixed in https://github.com/ethereum/go-ethereum/pull/31708) usually did prevent the search seeing the temp range and therefore avoided noticeable issues. --- core/filtermaps/filtermaps.go | 6 +----- core/filtermaps/matcher_backend.go | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index 3da7f4b721..ffe2bfcbb6 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -662,15 +662,11 @@ func (f *FilterMaps) mapRowIndex(mapIndex, rowIndex uint32) uint64 { } // getBlockLvPointer returns the starting log value index where the log values -// generated by the given block are located. If blockNumber is beyond the current -// head then the first unoccupied log value index is returned. +// generated by the given block are located. // // Note that this function assumes that the indexer read lock is being held when // called from outside the indexerLoop goroutine. func (f *FilterMaps) getBlockLvPointer(blockNumber uint64) (uint64, error) { - if blockNumber >= f.indexedRange.blocks.AfterLast() && f.indexedRange.headIndexed { - return f.indexedRange.headDelimiter + 1, nil - } if lvPointer, ok := f.lvPointerCache.Get(blockNumber); ok { return lvPointer, nil } diff --git a/core/filtermaps/matcher_backend.go b/core/filtermaps/matcher_backend.go index 9751783754..e19a63e18b 100644 --- a/core/filtermaps/matcher_backend.go +++ b/core/filtermaps/matcher_backend.go @@ -82,13 +82,26 @@ func (fm *FilterMapsMatcherBackend) GetFilterMapRow(ctx context.Context, mapInde } // GetBlockLvPointer returns the starting log value index where the log values -// generated by the given block are located. If blockNumber is beyond the current -// head then the first unoccupied log value index is returned. +// generated by the given block are located. If blockNumber is beyond the last +// indexed block then the pointer will point right after this block, ensuring +// that the matcher does not fail and can return a set of results where the +// valid range is correct. // GetBlockLvPointer implements MatcherBackend. func (fm *FilterMapsMatcherBackend) GetBlockLvPointer(ctx context.Context, blockNumber uint64) (uint64, error) { fm.f.indexLock.RLock() defer fm.f.indexLock.RUnlock() + if blockNumber >= fm.f.indexedRange.blocks.AfterLast() { + if fm.f.indexedRange.headIndexed { + // return index after head block + return fm.f.indexedRange.headDelimiter + 1, nil + } + if fm.f.indexedRange.blocks.Count() > 0 { + // return index at the beginning of the last, partially indexed + // block (after the last fully indexed one) + blockNumber = fm.f.indexedRange.blocks.Last() + } + } return fm.f.getBlockLvPointer(blockNumber) } From 8868ad6d6e09252238fefa303f7262e2b855f4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Sat, 3 May 2025 18:40:24 +0200 Subject: [PATCH 332/940] core/filtermaps: fix log index initialization (#31750) This PR fixes an initialization bug that in some cases caused the map renderer to leave the last, partially rendered map as is and resume rendering from the next map. At initialization we check whether the existing rendered maps are consistent with the current chain view and revert them if necessary. Until now this happened through an ugly hacky solution, a "limited" chain view that was supposed to trigger a rollback of some maps in the renderer logic if necessary. This whole setup worked under assumptions that just weren't true any more. As a result it always tried to revert the last map but also it did not shorten the indexed range, only set `headIndexed` to false which indicated to the renderer logic that the last map is fully populated (which it wasn't). Now an explicit rollback of any unusable (reorged) maps happens at startup, which also means that no hacky chain view is necessary, as soon as the new `FilterMaps` is returned, the indexed range and view are consistent with each other. In the first commit an extra check is also added to `writeFinishedMaps` so that if there is ever again a bug that would result in a gapped index then it will not break the db with writing the incomplete data. Instead it will return an indexing error which causes the indexer to revert to unindexed mode and print an error log instantly. Hopefully this will not ever happen in the future, but in order to test this safeguard check I manually triggered the bug with only the first commit enabled, which caused an indexing error as expected. With the second commit added (the actual fix) the same operation succeeded without any issues. Note that the database version is also bumped in this PR in order to enforce a full reindexing as any existing database might be potentially broken. Fixes https://github.com/ethereum/go-ethereum/issues/31729 --- core/filtermaps/chain_view.go | 8 ---- core/filtermaps/filtermaps.go | 69 ++++++++++++++++++--------------- core/filtermaps/map_renderer.go | 18 +++++++-- 3 files changed, 51 insertions(+), 44 deletions(-) diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go index 63df2cfb6d..874ff19e31 100644 --- a/core/filtermaps/chain_view.go +++ b/core/filtermaps/chain_view.go @@ -135,14 +135,6 @@ func (cv *ChainView) SharedRange(cv2 *ChainView) common.Range[uint64] { return common.NewRange(0, sharedLen) } -// limitedView returns a new chain view that is a truncated version of the parent view. -func (cv *ChainView) limitedView(newHead uint64) *ChainView { - if newHead >= cv.headNumber { - return cv - } - return NewChainView(cv.chain, newHead, cv.BlockHash(newHead)) -} - // equalViews returns true if the two chain views are equivalent. func equalViews(cv1, cv2 *ChainView) bool { if cv1 == nil || cv2 == nil { diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index ffe2bfcbb6..b2c63f2e58 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -50,7 +50,7 @@ var ( ) const ( - databaseVersion = 1 // reindexed if database version does not match + databaseVersion = 2 // reindexed if database version does not match cachedLastBlocks = 1000 // last block of map pointers cachedLvPointers = 1000 // first log value pointer of block pointers cachedBaseRows = 100 // groups of base layer filter row data @@ -244,6 +244,8 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f disabledCh: make(chan struct{}), exportFileName: config.ExportFileName, Params: params, + targetView: initView, + indexedView: initView, indexedRange: filterMapsRange{ initialized: initialized, headIndexed: rs.HeadIndexed, @@ -265,16 +267,8 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows), renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots), } + f.checkRevertRange() // revert maps that are inconsistent with the current chain view - // Set initial indexer target. - f.targetView = initView - if f.indexedRange.initialized { - f.indexedView = f.initChainView(f.targetView) - f.indexedRange.headIndexed = f.indexedRange.blocks.AfterLast() == f.indexedView.HeadNumber()+1 - if !f.indexedRange.headIndexed { - f.indexedRange.headDelimiter = 0 - } - } if f.indexedRange.hasIndexedBlocks() { log.Info("Initialized log indexer", "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), @@ -303,29 +297,40 @@ func (f *FilterMaps) Stop() { f.closeWg.Wait() } -// initChainView returns a chain view consistent with both the current target -// view and the current state of the log index as found in the database, based -// on the last block of stored maps. -// Note that the returned view might be shorter than the existing index if -// the latest maps are not consistent with targetView. -func (f *FilterMaps) initChainView(chainView *ChainView) *ChainView { - mapIndex := f.indexedRange.maps.AfterLast() - for { - var ok bool - mapIndex, ok = f.lastMapBoundaryBefore(mapIndex) - if !ok { - break - } - lastBlockNumber, lastBlockId, err := f.getLastBlockOfMap(mapIndex) - if err != nil { - log.Error("Could not initialize indexed chain view", "error", err) - break - } - if lastBlockNumber <= chainView.HeadNumber() && chainView.BlockId(lastBlockNumber) == lastBlockId { - return chainView.limitedView(lastBlockNumber) - } +// checkRevertRange checks whether the existing index is consistent with the +// current indexed view and reverts inconsistent maps if necessary. +func (f *FilterMaps) checkRevertRange() { + if f.indexedRange.maps.Count() == 0 { + return + } + lastMap := f.indexedRange.maps.Last() + lastBlockNumber, lastBlockId, err := f.getLastBlockOfMap(lastMap) + if err != nil { + log.Error("Error initializing log index database; resetting log index", "error", err) + f.reset() + return + } + for lastBlockNumber > f.indexedView.HeadNumber() || f.indexedView.BlockId(lastBlockNumber) != lastBlockId { + // revert last map + if f.indexedRange.maps.Count() == 1 { + f.reset() // reset database if no rendered maps remained + return + } + lastMap-- + newRange := f.indexedRange + newRange.maps.SetLast(lastMap) + lastBlockNumber, lastBlockId, err = f.getLastBlockOfMap(lastMap) + if err != nil { + log.Error("Error initializing log index database; resetting log index", "error", err) + f.reset() + return + } + newRange.blocks.SetAfterLast(lastBlockNumber) // lastBlockNumber is probably partially indexed + newRange.headIndexed = false + newRange.headDelimiter = 0 + // only shorten range and leave map data; next head render will overwrite it + f.setRange(f.db, f.indexedView, newRange, false) } - return chainView.limitedView(0) } // reset un-initializes the FilterMaps structure and removes all related data from diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index 74baec6a1a..5379cbb157 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -468,15 +468,25 @@ func (r *mapRenderer) writeFinishedMaps(pauseCb func() bool) error { r.f.filterMapCache.Remove(mapIndex) } } + var blockNumber uint64 + if r.finished.First() > 0 { + // in order to always ensure continuous block pointers, initialize + // blockNumber based on the last block of the previous map, then verify + // against the first block associated with each rendered map + lastBlock, _, err := r.f.getLastBlockOfMap(r.finished.First() - 1) + if err != nil { + return fmt.Errorf("failed to get last block of previous map %d: %v", r.finished.First()-1, err) + } + blockNumber = lastBlock + 1 + } // add or update block pointers - blockNumber := r.finishedMaps[r.finished.First()].firstBlock() for mapIndex := range r.finished.Iter() { renderedMap := r.finishedMaps[mapIndex] + if blockNumber != renderedMap.firstBlock() { + return fmt.Errorf("non-continuous block numbers in rendered map %d (next expected: %d first rendered: %d)", mapIndex, blockNumber, renderedMap.firstBlock()) + } r.f.storeLastBlockOfMap(batch, mapIndex, renderedMap.lastBlock, renderedMap.lastBlockId) checkWriteCnt() - if blockNumber != renderedMap.firstBlock() { - panic("non-continuous block numbers") - } for _, lvPtr := range renderedMap.blockLvPtrs { r.f.storeBlockLvPointer(batch, blockNumber, lvPtr) checkWriteCnt() From 2d86a54000be027286145f7aec36dd78fadcf070 Mon Sep 17 00:00:00 2001 From: Miro Date: Sat, 3 May 2025 22:16:33 -0400 Subject: [PATCH 333/940] core/txpool/legacypool: fix data race of pricedList access (#31758) --- core/txpool/legacypool/legacypool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index affe44cf06..0223b456e6 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1934,7 +1934,7 @@ func (pool *LegacyPool) Clear() { pool.reserver.Release(addr) } pool.all.Clear() - pool.priced = newPricedList(pool.all) + pool.priced.Reheap() pool.pending = make(map[common.Address]*list) pool.queue = make(map[common.Address]*list) pool.pendingNonces = newNoncer(pool.currentState) From 516451dc3a514c7c122f28864ea76742a027b858 Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Sun, 4 May 2025 20:40:31 +0800 Subject: [PATCH 334/940] params: fix comment for `DefaultBlobSchedule` (#31760) `DefaultBlobSchedule` is actually used downstream to calculate blob fees (e.g., [src](https://github.com/ethereum-optimism/optimism/blob/601a380e47853c2922ea1f8944cda05f0eac16f4/op-service/eth/blob.go#L301)), this PR makes it explicit that these params are for `Ethereum prod` instead of `test chains`. --- params/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/config.go b/params/config.go index 67aa6b2225..2e825ffcd5 100644 --- a/params/config.go +++ b/params/config.go @@ -358,7 +358,7 @@ var ( Max: 9, UpdateFraction: 5007716, } - // DefaultBlobSchedule is the latest configured blob schedule for test chains. + // DefaultBlobSchedule is the latest configured blob schedule for Ethereum mainnet. DefaultBlobSchedule = &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfig, From 615d29f7c2d5aed84cf8c7ec952d9f9a9f706e4b Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Mon, 5 May 2025 04:07:55 +0200 Subject: [PATCH 335/940] core: reduce load on txindexer from API (#31752) Fixes https://github.com/ethereum/go-ethereum/issues/31732. This logic was removed in the recent refactoring in the txindexer to handle history cutoff (#31393). It was first introduced in this PR: https://github.com/ethereum/go-ethereum/pull/28908. I have tested it and it works as an alternative to #31745. This PR packs 3 changes to the flow of fetching txs from the API: - It caches the indexer tail after each run is over to avoid hitting the db all the time as was done originally in #28908. - Changes `backend.GetTransaction`. It doesn't return an error anymore when tx indexer is in progress. It shifts the responsibility to the caller to check the progress. The reason is that in most cases we anyway check the txpool for the tx. If it was indeed a pending tx we can avoid the indexer progress check. --------- Co-authored-by: Gary Rong --- core/blockchain_reader.go | 54 ++++++++---------- core/txindexer.go | 72 ++++++++++++++---------- core/txindexer_test.go | 22 +++----- eth/api_backend.go | 28 +++++---- eth/tracers/api.go | 14 +++-- eth/tracers/api_test.go | 8 ++- ethstats/ethstats.go | 6 +- graphql/graphql.go | 6 +- internal/ethapi/api.go | 46 ++++++++------- internal/ethapi/api_test.go | 11 +++- internal/ethapi/backend.go | 5 +- internal/ethapi/transaction_args_test.go | 9 ++- 12 files changed, 150 insertions(+), 131 deletions(-) diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index b4ba5d9fd8..fefeb37542 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -270,42 +270,20 @@ func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, max // GetTransactionLookup retrieves the lookup along with the transaction // itself associate with the given transaction hash. // -// An error will be returned if the transaction is not found, and background -// indexing for transactions is still in progress. The transaction might be -// reachable shortly once it's indexed. -// -// A null will be returned in the transaction is not found and background -// 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) { +// A null will be returned if the transaction is not found. This can be due to +// the transaction indexer not being finished. The caller must explicitly check +// the indexer progress. +func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLookupEntry, *types.Transaction) { 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 + return item.lookup, item.transaction } tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(bc.db, hash) if tx == nil { - progress, err := bc.TxIndexProgress() - if err != nil { - // No error is returned if the transaction indexing progress is unreachable - // due to unexpected internal errors. In such cases, it is impossible to - // determine whether the transaction does not exist or has simply not been - // indexed yet without a progress marker. - // - // In such scenarios, the transaction is treated as unreachable, though - // this is clearly an unintended and unexpected situation. - return nil, nil, nil - } - // The transaction indexing is not finished yet, returning an - // error to explicitly indicate it. - if !progress.Done() { - return nil, nil, errors.New("transaction indexing still in progress") - } - // The transaction is already indexed, the transaction is either - // not existent or not in the range of index, returning null. - return nil, nil, nil + return nil, nil } lookup := &rawdb.LegacyTxLookupEntry{ BlockHash: blockHash, @@ -316,7 +294,23 @@ func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLoo lookup: lookup, transaction: tx, }) - return lookup, tx, nil + return lookup, tx +} + +// TxIndexDone returns true if the transaction indexer has finished indexing. +func (bc *BlockChain) TxIndexDone() bool { + progress, err := bc.TxIndexProgress() + if err != nil { + // No error is returned if the transaction indexing progress is unreachable + // due to unexpected internal errors. In such cases, it is impossible to + // determine whether the transaction does not exist or has simply not been + // indexed yet without a progress marker. + // + // In such scenarios, the transaction is treated as unreachable, though + // this is clearly an unintended and unexpected situation. + return true + } + return progress.Done() } // HasState checks if state trie is fully present in the database or not. @@ -412,7 +406,7 @@ func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) { if bc.txIndexer == nil { return TxIndexProgress{}, errors.New("tx indexer is not enabled") } - return bc.txIndexer.txIndexProgress() + return bc.txIndexer.txIndexProgress(), nil } // HistoryPruningCutoff returns the configured history pruning point. diff --git a/core/txindexer.go b/core/txindexer.go index 64a2e8c49f..587118ed7f 100644 --- a/core/txindexer.go +++ b/core/txindexer.go @@ -17,8 +17,8 @@ package core import ( - "errors" "fmt" + "sync/atomic" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" @@ -47,26 +47,38 @@ type txIndexer struct { // and all others shouldn't. limit uint64 + // The current head of blockchain for transaction indexing. This field + // is accessed by both the indexer and the indexing progress queries. + head atomic.Uint64 + + // The current tail of the indexed transactions, null indicates + // that no transactions have been indexed yet. + // + // This field is accessed by both the indexer and the indexing + // progress queries. + tail atomic.Pointer[uint64] + // cutoff denotes the block number before which the chain segment should // be pruned and not available locally. - cutoff uint64 - db ethdb.Database - progress chan chan TxIndexProgress - term chan chan struct{} - closed chan struct{} + cutoff uint64 + db ethdb.Database + term chan chan struct{} + closed chan struct{} } // newTxIndexer initializes the transaction indexer. func newTxIndexer(limit uint64, chain *BlockChain) *txIndexer { cutoff, _ := chain.HistoryPruningCutoff() indexer := &txIndexer{ - limit: limit, - cutoff: cutoff, - db: chain.db, - progress: make(chan chan TxIndexProgress), - term: make(chan chan struct{}), - closed: make(chan struct{}), + limit: limit, + cutoff: cutoff, + db: chain.db, + term: make(chan chan struct{}), + closed: make(chan struct{}), } + indexer.head.Store(indexer.resolveHead()) + indexer.tail.Store(rawdb.ReadTxIndexTail(chain.db)) + go indexer.loop(chain) var msg string @@ -154,6 +166,7 @@ func (indexer *txIndexer) repair(head uint64) { // A crash may occur between the two delete operations, // potentially leaving dangling indexes in the database. // However, this is considered acceptable. + indexer.tail.Store(nil) rawdb.DeleteTxIndexTail(indexer.db) rawdb.DeleteAllTxLookupEntries(indexer.db, nil) log.Warn("Purge transaction indexes", "head", head, "tail", *tail) @@ -174,6 +187,7 @@ func (indexer *txIndexer) repair(head uint64) { // Traversing the database directly within the transaction // index namespace might be slow and expensive, but we // have no choice. + indexer.tail.Store(nil) rawdb.DeleteTxIndexTail(indexer.db) rawdb.DeleteAllTxLookupEntries(indexer.db, nil) log.Warn("Purge transaction indexes", "head", head, "cutoff", indexer.cutoff) @@ -187,6 +201,7 @@ func (indexer *txIndexer) repair(head uint64) { // A crash may occur between the two delete operations, // potentially leaving dangling indexes in the database. // However, this is considered acceptable. + indexer.tail.Store(&indexer.cutoff) rawdb.WriteTxIndexTail(indexer.db, indexer.cutoff) rawdb.DeleteAllTxLookupEntries(indexer.db, func(txhash common.Hash, blob []byte) bool { n := rawdb.DecodeTxLookupEntry(blob, indexer.db) @@ -216,16 +231,15 @@ func (indexer *txIndexer) loop(chain *BlockChain) { // Listening to chain events and manipulate the transaction indexes. var ( - stop chan struct{} // Non-nil if background routine is active - done chan struct{} // Non-nil if background routine is active - head = indexer.resolveHead() // The latest announced chain head - + stop chan struct{} // Non-nil if background routine is active + done chan struct{} // Non-nil if background routine is active headCh = make(chan ChainHeadEvent) sub = chain.SubscribeChainHeadEvent(headCh) ) defer sub.Unsubscribe() // Validate the transaction indexes and repair if necessary + head := indexer.head.Load() indexer.repair(head) // Launch the initial processing if chain is not empty (head != genesis). @@ -238,17 +252,18 @@ func (indexer *txIndexer) loop(chain *BlockChain) { for { select { case h := <-headCh: + indexer.head.Store(h.Header.Number.Uint64()) if done == nil { stop = make(chan struct{}) done = make(chan struct{}) go indexer.run(h.Header.Number.Uint64(), stop, done) } - head = h.Header.Number.Uint64() + case <-done: stop = nil done = nil - case ch := <-indexer.progress: - ch <- indexer.report(head) + indexer.tail.Store(rawdb.ReadTxIndexTail(indexer.db)) + case ch := <-indexer.term: if stop != nil { close(stop) @@ -264,7 +279,7 @@ func (indexer *txIndexer) loop(chain *BlockChain) { } // report returns the tx indexing progress. -func (indexer *txIndexer) report(head uint64) TxIndexProgress { +func (indexer *txIndexer) report(head uint64, tail *uint64) TxIndexProgress { // Special case if the head is even below the cutoff, // nothing to index. if head < indexer.cutoff { @@ -284,7 +299,6 @@ func (indexer *txIndexer) report(head uint64) TxIndexProgress { } // Compute how many blocks have been indexed var indexed uint64 - tail := rawdb.ReadTxIndexTail(indexer.db) if tail != nil { indexed = head - *tail + 1 } @@ -300,16 +314,12 @@ func (indexer *txIndexer) report(head uint64) TxIndexProgress { } } -// txIndexProgress retrieves the tx indexing progress, or an error if the -// background tx indexer is already stopped. -func (indexer *txIndexer) txIndexProgress() (TxIndexProgress, error) { - ch := make(chan TxIndexProgress, 1) - select { - case indexer.progress <- ch: - return <-ch, nil - case <-indexer.closed: - return TxIndexProgress{}, errors.New("indexer is closed") - } +// txIndexProgress retrieves the transaction indexing progress. The reported +// progress may slightly lag behind the actual indexing state, as the tail is +// only updated at the end of each indexing operation. However, this delay is +// considered acceptable. +func (indexer *txIndexer) txIndexProgress() TxIndexProgress { + return indexer.report(indexer.head.Load(), indexer.tail.Load()) } // close shutdown the indexer. Safe to be called for multiple times. diff --git a/core/txindexer_test.go b/core/txindexer_test.go index 7a5688241f..6543ff429d 100644 --- a/core/txindexer_test.go +++ b/core/txindexer_test.go @@ -121,9 +121,8 @@ func TestTxIndexer(t *testing.T) { // Index the initial blocks from ancient store indexer := &txIndexer{ - limit: 0, - db: db, - progress: make(chan chan TxIndexProgress), + limit: 0, + db: db, } for i, limit := range c.limits { indexer.limit = limit @@ -241,9 +240,8 @@ func TestTxIndexerRepair(t *testing.T) { // Index the initial blocks from ancient store indexer := &txIndexer{ - limit: c.limit, - db: db, - progress: make(chan chan TxIndexProgress), + limit: c.limit, + db: db, } indexer.run(chainHead, make(chan struct{}), make(chan struct{})) @@ -432,15 +430,11 @@ func TestTxIndexerReport(t *testing.T) { // Index the initial blocks from ancient store indexer := &txIndexer{ - limit: c.limit, - cutoff: c.cutoff, - db: db, - progress: make(chan chan TxIndexProgress), + limit: c.limit, + cutoff: c.cutoff, + db: db, } - if c.tail != nil { - rawdb.WriteTxIndexTail(db, *c.tail) - } - p := indexer.report(c.head) + p := indexer.report(c.head, c.tail) if p.Indexed != c.expIndexed { t.Fatalf("Unexpected indexed: %d, expected: %d", p.Indexed, c.expIndexed) } diff --git a/eth/api_backend.go b/eth/api_backend.go index 10f7ffcbce..57f5a50837 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -349,22 +349,20 @@ func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction // GetTransaction retrieves the lookup along with the transaction itself associate // with the given transaction hash. // -// An error will be returned if the transaction is not found, and background -// indexing for transactions is still in progress. The error is used to indicate the -// scenario explicitly that the transaction might be reachable shortly. -// -// A null will be returned in the transaction is not found and background transaction -// indexing is already finished. The transaction is not existent from the perspective -// of node. -func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) { - lookup, tx, err := b.eth.blockchain.GetTransactionLookup(txHash) - if err != nil { - return false, nil, common.Hash{}, 0, 0, err - } +// A null will be returned if the transaction is not found. The transaction is not +// existent from the node's perspective. This can be due to the transaction indexer +// not being finished. The caller must explicitly check the indexer progress. +func (b *EthAPIBackend) GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) { + lookup, tx := b.eth.blockchain.GetTransactionLookup(txHash) if lookup == nil || tx == nil { - return false, nil, common.Hash{}, 0, 0, nil + return false, nil, common.Hash{}, 0, 0 } - return true, tx, lookup.BlockHash, lookup.BlockIndex, lookup.Index, nil + return true, tx, lookup.BlockHash, lookup.BlockIndex, lookup.Index +} + +// TxIndexDone returns true if the transaction indexer has finished indexing. +func (b *EthAPIBackend) TxIndexDone() bool { + return b.eth.blockchain.TxIndexDone() } func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { @@ -391,7 +389,7 @@ func (b *EthAPIBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.S return b.eth.txPool.SubscribeTransactions(ch, true) } -func (b *EthAPIBackend) SyncProgress() ethereum.SyncProgress { +func (b *EthAPIBackend) SyncProgress(ctx context.Context) ethereum.SyncProgress { prog := b.eth.Downloader().Progress() if txProg, err := b.eth.blockchain.TxIndexProgress(); err == nil { prog.TxIndexFinishedBlocks = txProg.Indexed diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 3cb86c80e2..17a0ad687a 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -82,7 +82,8 @@ type Backend interface { HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) - GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) + GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) + TxIndexDone() bool RPCGasCap() uint64 ChainConfig() *params.ChainConfig Engine() consensus.Engine @@ -858,12 +859,13 @@ func containsTx(block *types.Block, hash common.Hash) bool { // TraceTransaction returns the structured logs created during the execution of EVM // and returns them as a JSON object. func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) { - found, _, blockHash, blockNumber, index, err := api.backend.GetTransaction(ctx, hash) - if err != nil { - return nil, ethapi.NewTxIndexingError() - } - // Only mined txes are supported + found, _, blockHash, blockNumber, index := api.backend.GetTransaction(hash) if !found { + // Warn in case tx indexer is not done. + if !api.backend.TxIndexDone() { + return nil, ethapi.NewTxIndexingError() + } + // Only mined txes are supported return nil, errTxNotFound } // It shouldn't happen in practice. diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 529448e397..fa39187694 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -116,9 +116,13 @@ func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) return b.chain.GetBlockByNumber(uint64(number)), nil } -func (b *testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) { +func (b *testBackend) GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) { tx, hash, blockNumber, index := rawdb.ReadTransaction(b.chaindb, txHash) - return tx != nil, tx, hash, blockNumber, index, nil + return tx != nil, tx, hash, blockNumber, index +} + +func (b *testBackend) TxIndexDone() bool { + return true } func (b *testBackend) RPCGasCap() uint64 { diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index 0090a7d4c1..b6191baa12 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -66,7 +66,7 @@ type backend interface { CurrentHeader() *types.Header HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) Stats() (pending int, queued int) - SyncProgress() ethereum.SyncProgress + SyncProgress(ctx context.Context) ethereum.SyncProgress } // fullNodeBackend encompasses the functionality necessary for a full node @@ -766,7 +766,7 @@ func (s *Service) reportStats(conn *connWrapper) error { ) // check if backend is a full node if fullBackend, ok := s.backend.(fullNodeBackend); ok { - sync := fullBackend.SyncProgress() + sync := fullBackend.SyncProgress(context.Background()) syncing = !sync.Done() price, _ := fullBackend.SuggestGasTipCap(context.Background()) @@ -775,7 +775,7 @@ func (s *Service) reportStats(conn *connWrapper) error { gasprice += int(basefee.Uint64()) } } else { - sync := s.backend.SyncProgress() + sync := s.backend.SyncProgress(context.Background()) syncing = !sync.Done() } // Assemble the node stats and send it to the server diff --git a/graphql/graphql.go b/graphql/graphql.go index 7af1adbb4a..e23e6fcb0e 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -229,7 +229,7 @@ func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, *Block) return t.tx, t.block } // Try to return an already finalized transaction - found, tx, blockHash, _, index, _ := t.r.backend.GetTransaction(ctx, t.hash) + found, tx, blockHash, _, index := t.r.backend.GetTransaction(t.hash) if found { t.tx = tx blockNrOrHash := rpc.BlockNumberOrHashWithHash(blockHash, false) @@ -1530,8 +1530,8 @@ func (s *SyncState) TxIndexRemainingBlocks() hexutil.Uint64 { // - healingBytecode: number of bytecodes pending // - txIndexFinishedBlocks: number of blocks whose transactions are indexed // - txIndexRemainingBlocks: number of blocks whose transactions are not indexed yet -func (r *Resolver) Syncing() (*SyncState, error) { - progress := r.backend.SyncProgress() +func (r *Resolver) Syncing(ctx context.Context) (*SyncState, error) { + progress := r.backend.SyncProgress(ctx) // Return not syncing if the synchronisation already completed if progress.Done() { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 3b699748b8..8f736226c7 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -144,8 +144,8 @@ func (api *EthereumAPI) BlobBaseFee(ctx context.Context) *hexutil.Big { // - 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 (api *EthereumAPI) Syncing() (interface{}, error) { - progress := api.b.SyncProgress() +func (api *EthereumAPI) Syncing(ctx context.Context) (interface{}, error) { + progress := api.b.SyncProgress(ctx) // Return not syncing if the synchronisation already completed if progress.Done() { @@ -1333,16 +1333,18 @@ func (api *TransactionAPI) GetTransactionCount(ctx context.Context, address comm // GetTransactionByHash returns the transaction for the given hash 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 := api.b.GetTransaction(ctx, hash) + found, tx, blockHash, blockNumber, index := api.b.GetTransaction(hash) if !found { // No finalized transaction, try to retrieve it from the pool if tx := api.b.GetPoolTransaction(hash); tx != nil { return NewRPCPendingTransaction(tx, api.b.CurrentHeader(), api.b.ChainConfig()), nil } - if err == nil { - return nil, nil + // If also not in the pool there is a chance the tx indexer is still in progress. + if !api.b.TxIndexDone() { + return nil, NewTxIndexingError() } - return nil, NewTxIndexingError() + // If the transaction is not found in the pool and the indexer is done, return nil + return nil, nil } header, err := api.b.HeaderByHash(ctx, blockHash) if err != nil { @@ -1354,27 +1356,31 @@ func (api *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common // GetRawTransactionByHash returns the bytes of the transaction for the given hash. func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { // Retrieve a finalized transaction, or a pooled otherwise - found, tx, _, _, _, err := api.b.GetTransaction(ctx, hash) + found, tx, _, _, _ := api.b.GetTransaction(hash) if !found { if tx = api.b.GetPoolTransaction(hash); tx != nil { return tx.MarshalBinary() } - if err == nil { - return nil, nil + // If also not in the pool there is a chance the tx indexer is still in progress. + if !api.b.TxIndexDone() { + return nil, NewTxIndexingError() } - return nil, NewTxIndexingError() + // If the transaction is not found in the pool and the indexer is done, return nil + return nil, nil } return tx.MarshalBinary() } // GetTransactionReceipt returns the transaction receipt for the given transaction 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 - } + found, tx, blockHash, blockNumber, index := api.b.GetTransaction(hash) if !found { - return nil, nil // transaction is not existent or reachable + // Make sure indexer is done. + if !api.b.TxIndexDone() { + return nil, NewTxIndexingError() + } + // No such tx. + return nil, nil } header, err := api.b.HeaderByHash(ctx, blockHash) if err != nil { @@ -1774,15 +1780,17 @@ func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.Block // GetRawTransaction returns the bytes of the transaction for the given hash. func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { // Retrieve a finalized transaction, or a pooled otherwise - found, tx, _, _, _, err := api.b.GetTransaction(ctx, hash) + found, tx, _, _, _ := api.b.GetTransaction(hash) if !found { if tx = api.b.GetPoolTransaction(hash); tx != nil { return tx.MarshalBinary() } - if err == nil { - return nil, nil + // If also not in the pool there is a chance the tx indexer is still in progress. + if !api.b.TxIndexDone() { + return nil, NewTxIndexingError() } - return nil, NewTxIndexingError() + // Transaction is not found in the pool and the indexer is done. + return nil, nil } return tx.MarshalBinary() } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 5071e2412f..ef799d9994 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -472,7 +472,9 @@ func (b *testBackend) setPendingBlock(block *types.Block) { b.pending = block } -func (b testBackend) SyncProgress() ethereum.SyncProgress { return ethereum.SyncProgress{} } +func (b testBackend) SyncProgress(ctx context.Context) ethereum.SyncProgress { + return ethereum.SyncProgress{} +} func (b testBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { return big.NewInt(0), nil } @@ -589,9 +591,12 @@ func (b testBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) even func (b testBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { panic("implement me") } -func (b testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) { +func (b testBackend) GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) { tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.db, txHash) - return true, tx, blockHash, blockNumber, index, nil + return true, tx, blockHash, blockNumber, index +} +func (b testBackend) TxIndexDone() bool { + return true } func (b testBackend) GetPoolTransactions() (types.Transactions, error) { panic("implement me") } func (b testBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { panic("implement me") } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index e28cb93296..49c3a37560 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -41,7 +41,7 @@ import ( // both full and light clients) with access to necessary functions. type Backend interface { // General Ethereum API - SyncProgress() ethereum.SyncProgress + SyncProgress(ctx context.Context) 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, []*big.Int, []float64, error) @@ -74,7 +74,8 @@ type Backend interface { // Transaction pool API SendTx(ctx context.Context, signedTx *types.Transaction) error - GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) + GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) + TxIndexDone() bool GetPoolTransactions() (types.Transactions, error) GetPoolTransaction(txHash common.Hash) *types.Transaction GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index 9dd6a54729..9b86e452a5 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -323,7 +323,9 @@ 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) SyncProgress(ctx context.Context) 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, []*big.Int, []float64, error) { return nil, nil, nil, nil, nil, nil, nil } @@ -378,9 +380,10 @@ func (b *backendMock) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) eve return nil } func (b *backendMock) SendTx(ctx context.Context, signedTx *types.Transaction) error { return nil } -func (b *backendMock) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) { - return false, nil, [32]byte{}, 0, 0, nil +func (b *backendMock) GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) { + return false, nil, [32]byte{}, 0, 0 } +func (b *backendMock) TxIndexDone() bool { return true } func (b *backendMock) GetPoolTransactions() (types.Transactions, error) { return nil, nil } func (b *backendMock) GetPoolTransaction(txHash common.Hash) *types.Transaction { return nil } func (b *backendMock) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { From 1b18ba24235127e172a797f35dc0913d0330a1ba Mon Sep 17 00:00:00 2001 From: Marcel <153717436+MonkeyMarcel@users.noreply.github.com> Date: Mon, 5 May 2025 10:09:58 +0800 Subject: [PATCH 336/940] logs(indexer)Clean up log format in head index progress messages (#31761) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates the log entries in `core/filtermaps/indexer.go` to remove double quotes around keys like "first block" and "last block", changing them to `firstblock` and `lastblock`. This brings them in line with the general logging style used across the codebase, where log keys are unquoted single words. For example, the log: ` INFO [...] "first block"=..., "last block"=...` Is now rendered as: ` INFO [...] firstblock=..., lastblock=...` This change improves readability and maintains consistency with logs such as: ` INFO [...] number=2 sealhash=... uncles=0 txs=0 ...` No functional behavior is changed — this is purely a formatting cleanup for better developer experience. --- core/filtermaps/indexer.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 3ec49ca116..02ae2b920d 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -254,7 +254,7 @@ func (f *FilterMaps) tryIndexHead() error { ((!f.loggedHeadIndex && time.Since(f.startedHeadIndexAt) > headLogDelay) || time.Since(f.lastLogHeadIndex) > logFrequency) { log.Info("Log index head rendering in progress", - "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "firstblock", f.indexedRange.blocks.First(), "lastblock", f.indexedRange.blocks.Last(), "processed", f.indexedRange.blocks.AfterLast()-f.ptrHeadIndex, "remaining", f.indexedView.HeadNumber()-f.indexedRange.blocks.Last(), "elapsed", common.PrettyDuration(time.Since(f.startedHeadIndexAt))) @@ -266,7 +266,7 @@ func (f *FilterMaps) tryIndexHead() error { } if f.loggedHeadIndex && f.indexedRange.hasIndexedBlocks() { log.Info("Log index head rendering finished", - "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "firstblock", f.indexedRange.blocks.First(), "lastblock", f.indexedRange.blocks.Last(), "processed", f.indexedRange.blocks.AfterLast()-f.ptrHeadIndex, "elapsed", common.PrettyDuration(time.Since(f.startedHeadIndexAt))) } @@ -323,7 +323,7 @@ func (f *FilterMaps) tryIndexTail() (bool, error) { if f.indexedRange.hasIndexedBlocks() && f.ptrTailIndex >= f.indexedRange.blocks.First() && (!f.loggedTailIndex || time.Since(f.lastLogTailIndex) > logFrequency) { log.Info("Log index tail rendering in progress", - "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "firstblock", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), "processed", f.ptrTailIndex-f.indexedRange.blocks.First()+tpb, "remaining", remaining, "next tail epoch percentage", f.indexedRange.tailPartialEpoch*100/f.mapsPerEpoch, @@ -346,7 +346,7 @@ func (f *FilterMaps) tryIndexTail() (bool, error) { } if f.loggedTailIndex && f.indexedRange.hasIndexedBlocks() { log.Info("Log index tail rendering finished", - "first block", f.indexedRange.blocks.First(), "last block", f.indexedRange.blocks.Last(), + "firstblock", f.indexedRange.blocks.First(), "lastblock", f.indexedRange.blocks.Last(), "processed", f.ptrTailIndex-f.indexedRange.blocks.First(), "elapsed", common.PrettyDuration(time.Since(f.startedTailIndexAt))) f.loggedTailIndex = false From fc2ba1fb2e61804ac5f572fd4af304c7bd94f8ee Mon Sep 17 00:00:00 2001 From: GarmashAlex Date: Mon, 5 May 2025 09:01:53 +0300 Subject: [PATCH 337/940] triedb: add test suite for preimage store (#31574) --- triedb/preimages_test.go | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 triedb/preimages_test.go diff --git a/triedb/preimages_test.go b/triedb/preimages_test.go new file mode 100644 index 0000000000..da2ec8dbe3 --- /dev/null +++ b/triedb/preimages_test.go @@ -0,0 +1,78 @@ +// 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 ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/triedb/hashdb" +) + +// TestDatabasePreimages tests the preimage functionality of the trie database. +func TestDatabasePreimages(t *testing.T) { + // Create a database with preimages enabled + memDB := rawdb.NewMemoryDatabase() + config := &Config{ + Preimages: true, + HashDB: hashdb.Defaults, + } + db := NewDatabase(memDB, config) + defer db.Close() + + // Test inserting and retrieving preimages + preimages := make(map[common.Hash][]byte) + for i := 0; i < 10; i++ { + data := []byte{byte(i), byte(i + 1), byte(i + 2)} + hash := common.BytesToHash(data) + preimages[hash] = data + } + + // Insert preimages into the database + db.InsertPreimage(preimages) + + // Verify all preimages are retrievable + for hash, data := range preimages { + retrieved := db.Preimage(hash) + if retrieved == nil { + t.Errorf("Preimage for %x not found", hash) + } + if !bytes.Equal(retrieved, data) { + t.Errorf("Preimage data mismatch: got %x want %x", retrieved, data) + } + } + + // Test non-existent preimage + nonExistentHash := common.HexToHash("deadbeef") + if data := db.Preimage(nonExistentHash); data != nil { + t.Errorf("Unexpected preimage data for non-existent hash: %x", data) + } + + // Force preimage commit and verify again + db.WritePreimages() + for hash, data := range preimages { + retrieved := db.Preimage(hash) + if retrieved == nil { + t.Errorf("Preimage for %x not found after forced commit", hash) + } + if !bytes.Equal(retrieved, data) { + t.Errorf("Preimage data mismatch after forced commit: got %x want %x", retrieved, data) + } + } +} From bca0646ede39d45303d8bd0b24ff5e7efa4f3e28 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Mon, 5 May 2025 12:42:19 +0200 Subject: [PATCH 338/940] internal/ethapi: fix tx.from in eth_simulateV1 (#31480) Issue statement: when user requests eth_simulateV1 to return full transaction objects, these objects always had an empty `from` field. The reason is we lose the sender when translation the message into a types.Transaction which is then later on serialized. I did think of an alternative but opted to keep with this approach as it keeps complexity at the edge. The alternative would be to pass down a signer object to RPCMarshal* methods and define a custom signer which keeps the senders in its state and doesn't attempt the signature recovery. --- internal/ethapi/api_test.go | 71 +++++++++++++++++++++++++++++++++++++ internal/ethapi/simulate.go | 43 +++++++++++++++------- 2 files changed, 102 insertions(+), 12 deletions(-) diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index ef799d9994..0a157dce79 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -2488,6 +2488,77 @@ func TestSimulateV1ChainLinkage(t *testing.T) { require.Equal(t, block2.Hash().Bytes(), []byte(results[2].Calls[1].ReturnValue), "returned blockhash for block2 does not match") } +func TestSimulateV1TxSender(t *testing.T) { + var ( + sender = common.Address{0xaa, 0xaa} + sender2 = common.Address{0xaa, 0xab} + sender3 = common.Address{0xaa, 0xac} + recipient = common.Address{0xbb, 0xbb} + gspec = &core.Genesis{ + Config: params.MergedTestChainConfig, + Alloc: types.GenesisAlloc{ + sender: {Balance: big.NewInt(params.Ether)}, + sender2: {Balance: big.NewInt(params.Ether)}, + sender3: {Balance: big.NewInt(params.Ether)}, + }, + } + ctx = context.Background() + ) + backend := newTestBackend(t, 0, gspec, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {}) + stateDB, baseHeader, err := backend.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)) + if err != nil { + t.Fatalf("failed to get state and header: %v", err) + } + + sim := &simulator{ + b: backend, + state: stateDB, + base: baseHeader, + chainConfig: backend.ChainConfig(), + gp: new(core.GasPool).AddGas(math.MaxUint64), + traceTransfers: false, + validate: false, + fullTx: true, + } + + results, err := sim.execute(ctx, []simBlock{ + {Calls: []TransactionArgs{ + {From: &sender, To: &recipient, Value: (*hexutil.Big)(big.NewInt(1000))}, + {From: &sender2, To: &recipient, Value: (*hexutil.Big)(big.NewInt(2000))}, + {From: &sender3, To: &recipient, Value: (*hexutil.Big)(big.NewInt(3000))}, + }}, + {Calls: []TransactionArgs{ + {From: &sender2, To: &recipient, Value: (*hexutil.Big)(big.NewInt(4000))}, + }}, + }) + if err != nil { + t.Fatalf("simulation execution failed: %v", err) + } + require.Len(t, results, 2, "expected 2 simulated blocks") + require.Len(t, results[0].Block.Transactions(), 3, "expected 3 transaction in simulated block") + require.Len(t, results[1].Block.Transactions(), 1, "expected 1 transaction in 2nd simulated block") + enc, err := json.Marshal(results) + if err != nil { + t.Fatalf("failed to marshal results: %v", err) + } + type resultType struct { + Transactions []struct { + From common.Address `json:"from"` + } + } + var summary []resultType + if err := json.Unmarshal(enc, &summary); err != nil { + t.Fatalf("failed to unmarshal results: %v", err) + } + require.Len(t, summary, 2, "expected 2 simulated blocks") + require.Len(t, summary[0].Transactions, 3, "expected 3 transaction in simulated block") + require.Equal(t, sender, summary[0].Transactions[0].From, "sender address mismatch") + require.Equal(t, sender2, summary[0].Transactions[1].From, "sender address mismatch") + require.Equal(t, sender3, summary[0].Transactions[2].From, "sender address mismatch") + require.Len(t, summary[1].Transactions, 1, "expected 1 transaction in simulated block") + require.Equal(t, sender2, summary[1].Transactions[0].From, "sender address mismatch") +} + func TestSignTransaction(t *testing.T) { t.Parallel() // Initialize test accounts diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 9241b509da..b997cf297b 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -78,11 +78,25 @@ type simBlockResult struct { chainConfig *params.ChainConfig Block *types.Block Calls []simCallResult + // senders is a map of transaction hashes to their senders. + senders map[common.Hash]common.Address } func (r *simBlockResult) MarshalJSON() ([]byte, error) { blockData := RPCMarshalBlock(r.Block, true, r.fullTx, r.chainConfig) blockData["calls"] = r.Calls + // Set tx sender if user requested full tx objects. + if r.fullTx { + if raw, ok := blockData["transactions"].([]any); ok { + for _, tx := range raw { + if tx, ok := tx.(*RPCTransaction); ok { + tx.From = r.senders[tx.Hash] + } else { + return nil, errors.New("simulated transaction result has invalid type") + } + } + } + } return json.Marshal(blockData) } @@ -181,18 +195,18 @@ func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]*simBlo parent = sim.base ) for bi, block := range blocks { - result, callResults, err := sim.processBlock(ctx, &block, headers[bi], parent, headers[:bi], timeout) + result, callResults, senders, err := sim.processBlock(ctx, &block, headers[bi], parent, headers[:bi], timeout) if err != nil { return nil, err } headers[bi] = result.Header() - results[bi] = &simBlockResult{fullTx: sim.fullTx, chainConfig: sim.chainConfig, Block: result, Calls: callResults} + results[bi] = &simBlockResult{fullTx: sim.fullTx, chainConfig: sim.chainConfig, Block: result, Calls: callResults, senders: senders} parent = result.Header() } 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) { +func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, parent *types.Header, headers []*types.Header, timeout time.Duration) (*types.Block, []simCallResult, map[common.Hash]common.Address, error) { // Set header fields that depend only on parent block. // Parent hash is needed for evm.GetHashFn to work. header.ParentHash = parent.Hash() @@ -222,7 +236,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, 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 + return nil, nil, nil, err } var ( gasUsed, blobGasUsed uint64 @@ -235,6 +249,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, NoBaseFee: !sim.validate, Tracer: tracer.Hooks(), } + // senders is a map of transaction hashes to their senders. + // Transaction objects contain only the signature, and we lose track + // of the sender when translating the arguments into a transaction object. + senders = make(map[common.Hash]common.Address) ) tracingStateDB := vm.StateDB(sim.state) if hooks := tracer.Hooks(); hooks != nil { @@ -255,16 +273,17 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, var allLogs []*types.Log for i, call := range block.Calls { if err := ctx.Err(); err != nil { - return nil, nil, err + return nil, nil, nil, err } if err := sim.sanitizeCall(&call, sim.state, header, blockContext, &gasUsed); err != nil { - return nil, nil, err + return nil, nil, nil, err } var ( tx = call.ToTransaction(types.DynamicFeeTxType) txHash = tx.Hash() ) txes[i] = tx + senders[txHash] = call.from() tracer.reset(txHash, uint(i)) sim.state.SetTxContext(txHash, i) // EoA check is always skipped, even in validation mode. @@ -272,7 +291,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp) if err != nil { txErr := txValidationError(err) - return nil, nil, txErr + return nil, nil, nil, txErr } // Update the state with pending changes. var root []byte @@ -311,15 +330,15 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, requests = [][]byte{} // EIP-6110 if err := core.ParseDepositLogs(&requests, allLogs, sim.chainConfig); err != nil { - return nil, nil, err + return nil, nil, nil, err } // EIP-7002 if err := core.ProcessWithdrawalQueue(&requests, evm); err != nil { - return nil, nil, err + return nil, nil, nil, err } // EIP-7251 if err := core.ProcessConsolidationQueue(&requests, evm); err != nil { - return nil, nil, err + return nil, nil, nil, err } } if requests != nil { @@ -330,10 +349,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, chainHeadReader := &simChainHeadReader{ctx, sim.b} b, err := sim.b.Engine().FinalizeAndAssemble(chainHeadReader, header, sim.state, blockBody, receipts) if err != nil { - return nil, nil, err + return nil, nil, nil, err } repairLogs(callResults, b.Hash()) - return b, callResults, nil + return b, callResults, senders, nil } // repairLogs updates the block hash in the logs present in the result of From b135da2eac9bd3beb043f4b11418c09034fb9cc3 Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Mon, 5 May 2025 14:43:47 +0200 Subject: [PATCH 339/940] rpc: add method name length limit (#31711) This change adds a limit for RPC method names to prevent potential abuse where large method names could lead to large response sizes. The limit is enforced in: - handleCall for regular RPC method calls - handleSubscribe for subscription method calls Added tests in websocket_test.go to verify the length limit functionality for both regular method calls and subscriptions. --------- Co-authored-by: Felix Lange --- rpc/handler.go | 9 ++++++ rpc/json.go | 1 + rpc/websocket_test.go | 74 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/rpc/handler.go b/rpc/handler.go index f23b544b58..45558d5821 100644 --- a/rpc/handler.go +++ b/rpc/handler.go @@ -501,6 +501,10 @@ func (h *handler) handleCall(cp *callProc, msg *jsonrpcMessage) *jsonrpcMessage if msg.isUnsubscribe() { callb = h.unsubscribeCb } else { + // Check method name length + if len(msg.Method) > maxMethodNameLength { + return msg.errorResponse(&invalidRequestError{fmt.Sprintf("method name too long: %d > %d", len(msg.Method), maxMethodNameLength)}) + } callb = h.reg.callback(msg.Method) } if callb == nil { @@ -536,6 +540,11 @@ func (h *handler) handleSubscribe(cp *callProc, msg *jsonrpcMessage) *jsonrpcMes return msg.errorResponse(ErrNotificationsUnsupported) } + // Check method name length + if len(msg.Method) > maxMethodNameLength { + return msg.errorResponse(&invalidRequestError{fmt.Sprintf("subscription name too long: %d > %d", len(msg.Method), maxMethodNameLength)}) + } + // Subscription method name is first argument. name, err := parseSubscriptionName(msg.Params) if err != nil { diff --git a/rpc/json.go b/rpc/json.go index e932389d17..fcd801fc95 100644 --- a/rpc/json.go +++ b/rpc/json.go @@ -35,6 +35,7 @@ const ( subscribeMethodSuffix = "_subscribe" unsubscribeMethodSuffix = "_unsubscribe" notificationMethodSuffix = "_subscription" + maxMethodNameLength = 2048 defaultWriteTimeout = 10 * time.Second // used if context has no deadline ) diff --git a/rpc/websocket_test.go b/rpc/websocket_test.go index 10a998b351..a8d8624900 100644 --- a/rpc/websocket_test.go +++ b/rpc/websocket_test.go @@ -391,3 +391,77 @@ func wsPingTestHandler(t *testing.T, conn *websocket.Conn, shutdown, sendPing <- } } } + +func TestWebsocketMethodNameLengthLimit(t *testing.T) { + t.Parallel() + + var ( + srv = newTestServer() + httpsrv = httptest.NewServer(srv.WebsocketHandler([]string{"*"})) + wsURL = "ws:" + strings.TrimPrefix(httpsrv.URL, "http:") + ) + defer srv.Stop() + defer httpsrv.Close() + + client, err := DialWebsocket(context.Background(), wsURL, "") + if err != nil { + t.Fatalf("can't dial: %v", err) + } + defer client.Close() + + // Test cases + tests := []struct { + name string + method string + params []interface{} + expectedError string + isSubscription bool + }{ + { + name: "valid method name", + method: "test_echo", + params: []interface{}{"test", 1}, + expectedError: "", + isSubscription: false, + }, + { + name: "method name too long", + method: "test_" + string(make([]byte, maxMethodNameLength+1)), + params: []interface{}{"test", 1}, + expectedError: "method name too long", + isSubscription: false, + }, + { + name: "valid subscription", + method: "nftest_subscribe", + params: []interface{}{"someSubscription", 1, 2}, + expectedError: "", + isSubscription: true, + }, + { + name: "subscription name too long", + method: string(make([]byte, maxMethodNameLength+1)) + "_subscribe", + params: []interface{}{"newHeads"}, + expectedError: "subscription name too long", + isSubscription: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var result interface{} + err := client.Call(&result, tt.method, tt.params...) + if tt.expectedError == "" { + if err != nil { + t.Errorf("unexpected error: %v", err) + } + } else { + if err == nil { + t.Error("expected error, got nil") + } else if !strings.Contains(err.Error(), tt.expectedError) { + t.Errorf("expected error containing %q, got %q", tt.expectedError, err.Error()) + } + } + }) + } +} From 7705d13ed492a6291b2d7aa7f7c15b70749e9a65 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Mon, 5 May 2025 22:15:59 +0800 Subject: [PATCH 340/940] eth/tracers: fix `standardTraceBlockToFile` (#31763) Fixes methods debug_standardTraceBlockToFile and debug_standardTraceBadBlockToFile which were outputting empty files. --------- Co-authored-by: maskpp Co-authored-by: Sina Mahmoodi --- eth/tracers/api.go | 64 +++++++++++----------- eth/tracers/api_test.go | 116 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 30 deletions(-) diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 17a0ad687a..fe72924828 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -778,6 +778,7 @@ 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) } + evm := vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{}) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { core.ProcessBeaconBlockRoot(*beaconRoot, evm) @@ -787,42 +788,45 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block } for i, tx := range block.Transactions() { // Prepare the transaction for un-traced execution - var ( - msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee()) - vmConf vm.Config - dump *os.File - writer *bufio.Writer - err error - ) - // If the transaction needs tracing, swap out the configs - if tx.Hash() == txHash || txHash == (common.Hash{}) { - // Generate a unique temporary file to dump it into - prefix := fmt.Sprintf("block_%#x-%d-%#x-", block.Hash().Bytes()[:4], i, tx.Hash().Bytes()[:4]) - if !canon { - prefix = fmt.Sprintf("%valt-", prefix) - } - dump, err = os.CreateTemp(os.TempDir(), prefix) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) + if txHash != (common.Hash{}) && tx.Hash() != txHash { + // Process the tx to update state, but don't trace it. + _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)) if err != nil { - return nil, err - } - dumps = append(dumps, dump.Name()) - - // Swap out the noop logger to the standard tracer - writer = bufio.NewWriter(dump) - vmConf = vm.Config{ - Tracer: logger.NewJSONLogger(&logConfig, writer), - EnablePreimageRecording: true, + return dumps, err } + // 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(evm.ChainConfig().IsEIP158(block.Number())) + continue } + // The transaction should be traced. + // Generate a unique temporary file to dump it into. + prefix := fmt.Sprintf("block_%#x-%d-%#x-", block.Hash().Bytes()[:4], i, tx.Hash().Bytes()[:4]) + if !canon { + prefix = fmt.Sprintf("%valt-", prefix) + } + var dump *os.File + dump, err := os.CreateTemp(os.TempDir(), prefix) + if err != nil { + return nil, err + } + dumps = append(dumps, dump.Name()) + // Set up the tracer and EVM for the transaction. + var ( + writer = bufio.NewWriter(dump) + tracer = logger.NewJSONLogger(&logConfig, writer) + evm = vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{ + Tracer: tracer, + NoBaseFee: true, + }) + ) // Execute the transaction and flush any traces to disk statedb.SetTxContext(tx.Hash(), i) - if vmConf.Tracer.OnTxStart != nil { - vmConf.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) - } - vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)) - if vmConf.Tracer.OnTxEnd != nil { - vmConf.Tracer.OnTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, err) + if tracer.OnTxStart != nil { + tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) } + _, err = core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)) if writer != nil { writer.Flush() } diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index fa39187694..d20d5eaff6 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "math/big" + "os" "reflect" "slices" "sync/atomic" @@ -1218,3 +1219,118 @@ func TestTraceBlockWithBasefee(t *testing.T) { } } } + +func TestStandardTraceBlockToFile(t *testing.T) { + var ( + // A sender who makes transactions, has some funds + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000000000) + + // first contract the sender transacts with + aa = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43") + aaCode = []byte{byte(vm.PUSH1), 0x00, byte(vm.POP)} + + // second contract the sender transacts with + bb = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f44") + bbCode = []byte{byte(vm.PUSH2), 0x00, 0x01, byte(vm.POP)} + ) + + genesis := &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{ + address: {Balance: funds}, + aa: { + Code: aaCode, + Nonce: 1, + Balance: big.NewInt(0), + }, + bb: { + Code: bbCode, + Nonce: 1, + Balance: big.NewInt(0), + }, + }, + } + txHashs := make([]common.Hash, 0, 2) + backend := newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) { + b.SetCoinbase(common.Address{1}) + // first tx to aa + tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ + Nonce: 0, + To: &aa, + Value: big.NewInt(0), + Gas: 50000, + GasPrice: b.BaseFee(), + Data: nil, + }), types.HomesteadSigner{}, key) + b.AddTx(tx) + txHashs = append(txHashs, tx.Hash()) + // second tx to bb + tx, _ = types.SignTx(types.NewTx(&types.LegacyTx{ + Nonce: 1, + To: &bb, + Value: big.NewInt(1), + Gas: 100000, + GasPrice: b.BaseFee(), + Data: nil, + }), types.HomesteadSigner{}, key) + b.AddTx(tx) + txHashs = append(txHashs, tx.Hash()) + }) + defer backend.chain.Stop() + + var testSuite = []struct { + blockNumber rpc.BlockNumber + config *StdTraceConfig + want []string + }{ + { + // test that all traces in the block were outputted if no trace config is specified + blockNumber: rpc.LatestBlockNumber, + config: nil, + want: []string{ + `{"pc":0,"op":96,"gas":"0x7148","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":80,"gas":"0x7145","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"POP"} +{"pc":3,"op":0,"gas":"0x7143","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"} +{"output":"","gasUsed":"0x5"} +`, + `{"pc":0,"op":97,"gas":"0x13498","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":3,"op":80,"gas":"0x13495","gasCost":"0x2","memSize":0,"stack":["0x1"],"depth":1,"refund":0,"opName":"POP"} +{"pc":4,"op":0,"gas":"0x13493","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"} +{"output":"","gasUsed":"0x5"} +`, + }, + }, + { + // test that only a specific tx is traced if specified + blockNumber: rpc.LatestBlockNumber, + config: &StdTraceConfig{TxHash: txHashs[1]}, + want: []string{ + `{"pc":0,"op":97,"gas":"0x13498","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH2"} +{"pc":3,"op":80,"gas":"0x13495","gasCost":"0x2","memSize":0,"stack":["0x1"],"depth":1,"refund":0,"opName":"POP"} +{"pc":4,"op":0,"gas":"0x13493","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"} +{"output":"","gasUsed":"0x5"} +`, + }, + }, + } + + api := NewAPI(backend) + for i, tc := range testSuite { + block, _ := api.blockByNumber(context.Background(), tc.blockNumber) + txTraces, err := api.StandardTraceBlockToFile(context.Background(), block.Hash(), tc.config) + if err != nil { + t.Fatalf("test index %d received error %v", i, err) + } + for j, traceFileName := range txTraces { + traceReceived, err := os.ReadFile(traceFileName) + if err != nil { + t.Fatalf("could not read trace file: %v", err) + } + if tc.want[j] != string(traceReceived) { + t.Fatalf("unexpected trace result. expected\n'%s'\n\nreceived\n'%s'\n", tc.want[j], string(traceReceived)) + } + } + } +} From 36b2371c59cd91a9b1da062b3e382f05a6d8687e Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 5 May 2025 16:19:58 +0200 Subject: [PATCH 341/940] version: release go-ethereum v1.15.11 stable --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 6b9a3b2ca4..4b0a7ebb81 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 11 // Patch version component of the current release - Meta = "unstable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 11 // Patch version component of the current release + Meta = "stable" // Version metadata to append to the version string ) From d6655cb4506bf2e838eed5199b84bfc63bf4515a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 5 May 2025 16:20:38 +0200 Subject: [PATCH 342/940] version: begin v1.15.12 release cycle --- version/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 4b0a7ebb81..51cf410cda 100644 --- a/version/version.go +++ b/version/version.go @@ -17,8 +17,8 @@ package version const ( - Major = 1 // Major version component of the current release - Minor = 15 // Minor version component of the current release - Patch = 11 // Patch version component of the current release - Meta = "stable" // Version metadata to append to the version string + Major = 1 // Major version component of the current release + Minor = 15 // Minor version component of the current release + Patch = 12 // Patch version component of the current release + Meta = "unstable" // Version metadata to append to the version string ) From 79e8870e34ff946fa372c3bfb11b3d6de84dce9b Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Tue, 6 May 2025 13:30:19 +1000 Subject: [PATCH 343/940] go.mod: update pebble to v1.1.5 to reduce clutter in go.sum (#31541) ``` go get github.com/cockroachdb/pebble@v1.1.5 go mod tidy ``` Co-authored-by: lightclient --- go.mod | 12 +- go.sum | 403 ++------------------------------------------------------- 2 files changed, 18 insertions(+), 397 deletions(-) diff --git a/go.mod b/go.mod index 9682685937..924f0d2642 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2 github.com/cespare/cp v0.1.0 github.com/cloudflare/cloudflare-go v0.114.0 - github.com/cockroachdb/pebble v1.1.2 + github.com/cockroachdb/pebble v1.1.5 github.com/consensys/gnark-crypto v0.16.0 github.com/crate-crypto/go-eth-kzg v1.3.0 github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a @@ -120,7 +120,7 @@ require ( github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect @@ -133,10 +133,10 @@ require ( github.com/pion/transport/v3 v3.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.0 // indirect - github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 1ac65bc01d..5d35a7a0e1 100644 --- a/go.sum +++ b/go.sum @@ -1,36 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 h1:8q4SaHjFsClSvuVne0ID/5Ka8u3fcIHyqkLjcFpNRHQ= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= @@ -43,8 +10,6 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 h1:gggzg0SUMs6SQbEw+ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= @@ -53,11 +18,6 @@ github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDO github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/aws/aws-sdk-go-v2 v1.21.2 h1:+LXZ0sgo8quN9UOKXXzAWRT3FWd4NxeXWOZom9pE7GA= @@ -86,30 +46,20 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 h1:0BkLfgeDjfZnZ+MhB3ONb01u9pwF github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= github.com/aws/smithy-go v1.15.0 h1:PS/durmlzvAFpQHDs4wi4sNNP9ExsqZh6IlfdHXgKK8= github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 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/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.114.0 h1:ucoti4/7Exo0XQ+rzpn1H+IfVVe++zgiM+tyKtf0HUA= github.com/cloudflare/cloudflare-go v0.114.0/go.mod h1:O7fYfFfA6wKqKFn2QIR9lhj7FDw6VQCGOY6hd2TBtd0= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 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.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= @@ -118,8 +68,8 @@ github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/e 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.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= -github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= 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= @@ -162,10 +112,6 @@ github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjU github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= @@ -191,15 +137,6 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= @@ -207,86 +144,44 @@ github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -294,8 +189,6 @@ github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY4 github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= 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= @@ -306,7 +199,6 @@ github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXei github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= @@ -322,15 +214,6 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 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= @@ -342,9 +225,6 @@ github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -378,9 +258,8 @@ github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= @@ -390,13 +269,6 @@ github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8oh github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= @@ -431,7 +303,6 @@ github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -439,29 +310,14 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= -github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= 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.34.1 h1:qW55rnhZJDnOb3TwFiFRJZi3yTXFrJdGOFQM7vCwYGg= @@ -472,7 +328,6 @@ github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= @@ -483,16 +338,11 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -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= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -518,24 +368,14 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -545,77 +385,24 @@ golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -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= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -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= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= @@ -623,78 +410,37 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -716,9 +462,7 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -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= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -730,54 +474,14 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -788,87 +492,16 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -877,10 +510,8 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -888,15 +519,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= From 51b34efebcf36c4fd083b13b78ec49eb081623b9 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Tue, 6 May 2025 12:40:03 +0800 Subject: [PATCH 344/940] cmd/utils: don't allow network ID override if a preset network is specified (#31630) --- cmd/geth/consolecmd_test.go | 3 +-- cmd/utils/flags.go | 24 +++++++----------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index b8c2c498a6..ca8efb5f98 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -39,9 +39,8 @@ const ( // child g gets a temporary data directory. func runMinimalGeth(t *testing.T, args ...string) *testgeth { // --holesky to make the 'writing genesis to disk' faster (no accounts) - // --networkid=1337 to avoid cache bump // --syncmode=full to avoid allocating fast sync bloom - allArgs := []string{"--holesky", "--networkid", "1337", "--authrpc.port", "0", "--syncmode=full", "--port", "0", + allArgs := []string{"--holesky", "--authrpc.port", "0", "--syncmode=full", "--port", "0", "--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64", "--datadir.minfreedisk", "0"} return runGeth(t, append(allArgs, args...)...) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index b26f43b376..44363d13f4 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1571,8 +1571,8 @@ func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) { // SetEthConfig applies eth-related command line flags to the config. func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { - // Avoid conflicting network flags - flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag, HoodiFlag) + // Avoid conflicting network flags, don't allow network id override on preset networks + flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag, HoodiFlag, NetworkIdFlag) flags.CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer // Set configurations from CLI flags @@ -1743,33 +1743,23 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { // Override any default configs for hard coded networks. switch { case ctx.Bool(MainnetFlag.Name): - if !ctx.IsSet(NetworkIdFlag.Name) { - cfg.NetworkId = 1 - } + cfg.NetworkId = 1 cfg.Genesis = core.DefaultGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) case ctx.Bool(HoleskyFlag.Name): - if !ctx.IsSet(NetworkIdFlag.Name) { - cfg.NetworkId = 17000 - } + cfg.NetworkId = 17000 cfg.Genesis = core.DefaultHoleskyGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.HoleskyGenesisHash) case ctx.Bool(SepoliaFlag.Name): - if !ctx.IsSet(NetworkIdFlag.Name) { - cfg.NetworkId = 11155111 - } + cfg.NetworkId = 11155111 cfg.Genesis = core.DefaultSepoliaGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.SepoliaGenesisHash) case ctx.Bool(HoodiFlag.Name): - if !ctx.IsSet(NetworkIdFlag.Name) { - cfg.NetworkId = 560048 - } + cfg.NetworkId = 560048 cfg.Genesis = core.DefaultHoodiGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.HoodiGenesisHash) case ctx.Bool(DeveloperFlag.Name): - if !ctx.IsSet(NetworkIdFlag.Name) { - cfg.NetworkId = 1337 - } + cfg.NetworkId = 1337 cfg.SyncMode = ethconfig.FullSync // Create new developer account or reuse existing one var ( From 3e356d69efcde2ce5f287863be5eb4f71177f607 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 7 May 2025 12:53:45 +0200 Subject: [PATCH 345/940] beacon/blsync: fix requests encoding in engine_newPayloadV4 (#31775) This fixes an issue where blocks containing CL requests triggered an error in the engine API. The encoding of requests used base64 instead of hex. --- beacon/blsync/engineclient.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/beacon/blsync/engineclient.go b/beacon/blsync/engineclient.go index 77bee83f5b..f9821fc6f3 100644 --- a/beacon/blsync/engineclient.go +++ b/beacon/blsync/engineclient.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/beacon/params" "github.com/ethereum/go-ethereum/beacon/types" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" ctypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" @@ -104,7 +105,11 @@ func (ec *engineClient) callNewPayload(fork string, event types.ChainHeadEvent) method = "engine_newPayloadV4" parentBeaconRoot := event.BeaconHead.ParentRoot blobHashes := collectBlobHashes(event.Block) - params = append(params, blobHashes, parentBeaconRoot, event.ExecRequests) + hexRequests := make([]hexutil.Bytes, len(event.ExecRequests)) + for i := range event.ExecRequests { + hexRequests[i] = hexutil.Bytes(event.ExecRequests[i]) + } + params = append(params, blobHashes, parentBeaconRoot, hexRequests) case "deneb": method = "engine_newPayloadV3" parentBeaconRoot := event.BeaconHead.ParentRoot From 0d5de826da144cef795542a3489f899f49dee1e8 Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Wed, 7 May 2025 15:34:52 +0200 Subject: [PATCH 346/940] p2p: add metrics for inbound connection errors (#31652) Add metics detailing reasons we reject inbound connections for, and reasons these connections fail during the handshake. --- p2p/metrics.go | 42 ++++++++++++++++++++++++++++++++++++++++++ p2p/server.go | 2 ++ 2 files changed, 44 insertions(+) diff --git a/p2p/metrics.go b/p2p/metrics.go index 29c2acb0cb..c44a878aa4 100644 --- a/p2p/metrics.go +++ b/p2p/metrics.go @@ -66,6 +66,18 @@ var ( // capture the rest of errors that are not handled by the above meters dialOtherError = metrics.NewRegisteredMeter("p2p/dials/error/other", nil) + + // handshake error meters for inbound connections + serveTooManyPeers = metrics.NewRegisteredMeter("p2p/serves/error/saturated", nil) + serveAlreadyConnected = metrics.NewRegisteredMeter("p2p/serves/error/known", nil) + serveSelf = metrics.NewRegisteredMeter("p2p/serves/error/self", nil) + serveUselessPeer = metrics.NewRegisteredMeter("p2p/serves/error/useless", nil) + serveUnexpectedIdentity = metrics.NewRegisteredMeter("p2p/serves/error/id/unexpected", nil) + serveEncHandshakeError = metrics.NewRegisteredMeter("p2p/serves/error/rlpx/enc", nil) //EOF; connection reset during handshake; (message too big?) + serveProtoHandshakeError = metrics.NewRegisteredMeter("p2p/serves/error/rlpx/proto", nil) + + // capture the rest of errors that are not handled by the above meters + serveOtherError = metrics.NewRegisteredMeter("p2p/serves/error/other", nil) ) // markDialError matches errors that occur while setting up a dial connection to the @@ -99,6 +111,36 @@ func markDialError(err error) { } } +// markServeError matches errors that occur while serving an inbound connection +// to the corresponding meter. +func markServeError(err error) { + if !metrics.Enabled() { + return + } + + var reason DiscReason + var handshakeErr *protoHandshakeError + d := errors.As(err, &reason) + switch { + case d && reason == DiscTooManyPeers: + serveTooManyPeers.Mark(1) + case d && reason == DiscAlreadyConnected: + serveAlreadyConnected.Mark(1) + case d && reason == DiscSelf: + serveSelf.Mark(1) + case d && reason == DiscUselessPeer: + serveUselessPeer.Mark(1) + case d && reason == DiscUnexpectedIdentity: + serveUnexpectedIdentity.Mark(1) + case errors.As(err, &handshakeErr): + serveProtoHandshakeError.Mark(1) + case errors.Is(err, errEncHandshakeError): + serveEncHandshakeError.Mark(1) + default: + serveOtherError.Mark(1) + } +} + // meteredConn is a wrapper around a net.Conn that meters both the // inbound and outbound network traffic. type meteredConn struct { diff --git a/p2p/server.go b/p2p/server.go index d9105976dd..f3a58bba29 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -864,6 +864,8 @@ func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *enode.Node) if err != nil { if !c.is(inboundConn) { markDialError(err) + } else { + markServeError(err) } c.close(err) } From 07d073bc5a711ddf40f25c56b54f88badf3c3694 Mon Sep 17 00:00:00 2001 From: JukLee0ira Date: Thu, 8 May 2025 14:57:17 +0800 Subject: [PATCH 347/940] internal/web3ext: remove the legacy backtraceAt method (#31783) The function `BacktraceAt` has been removed in #28187 . But the API end-point `debug_backtraceAt` is not removed from the file `internal/web3ext/web3ext.go`. --- internal/web3ext/web3ext.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index aed6bbbdb9..a6d93fc1c5 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -247,11 +247,6 @@ web3._extend({ call: 'debug_vmodule', params: 1 }), - new web3._extend.Method({ - name: 'backtraceAt', - call: 'debug_backtraceAt', - params: 1, - }), new web3._extend.Method({ name: 'stacks', call: 'debug_stacks', From 10519768a2f7259e55cc34e51ff6ec73e6a703e9 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 8 May 2025 19:10:26 +0800 Subject: [PATCH 348/940] core, ethdb: introduce database sync function (#31703) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request introduces a SyncKeyValue function to the ethdb.KeyValueStore interface, providing the ability to forcibly flush all previous writes to disk. This functionality is critical for go-ethereum, which internally uses two independent database engines: a key-value store (such as Pebble, LevelDB, or memoryDB for testing) and a flat-file–based freezer. To ensure write-order consistency between these engines, the key-value store must be explicitly synced before writing to the freezer and vice versa. Fixes - https://github.com/ethereum/go-ethereum/issues/31405 - https://github.com/ethereum/go-ethereum/issues/29819 --- core/bench_test.go | 8 +++---- core/blockchain.go | 24 ++++++++++---------- core/blockchain_repair_test.go | 8 +++---- core/blockchain_sethead_test.go | 2 +- core/blockchain_snapshot_test.go | 4 ++-- core/blockchain_test.go | 2 +- core/headerchain.go | 35 +++++++++++++++++++++++++++- core/rawdb/chain_freezer.go | 2 +- core/rawdb/database.go | 4 ++-- core/rawdb/freezer.go | 4 ++-- core/rawdb/freezer_memory.go | 4 ++-- core/rawdb/freezer_resettable.go | 6 ++--- core/rawdb/freezer_test.go | 2 +- core/rawdb/table.go | 12 +++++++--- ethdb/database.go | 14 +++++++++--- ethdb/leveldb/leveldb.go | 16 +++++++++++++ ethdb/memorydb/memorydb.go | 6 +++++ ethdb/pebble/pebble.go | 39 ++++++++++++++++++++++++++++---- ethdb/pebble/pebble_test.go | 24 ++++++++++++++++++++ ethdb/remotedb/remotedb.go | 6 ++++- node/database.go | 13 ++++------- trie/trie_test.go | 1 + triedb/pathdb/buffer.go | 9 +++++--- triedb/pathdb/database.go | 9 ++++++++ 24 files changed, 194 insertions(+), 60 deletions(-) diff --git a/core/bench_test.go b/core/bench_test.go index 00f924076a..155fa6c3b5 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -183,7 +183,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { if !disk { db = rawdb.NewMemoryDatabase() } else { - pdb, err := pebble.New(b.TempDir(), 128, 128, "", false, true) + pdb, err := pebble.New(b.TempDir(), 128, 128, "", false) if err != nil { b.Fatalf("cannot create temporary database: %v", err) } @@ -303,7 +303,7 @@ func makeChainForBench(db ethdb.Database, genesis *Genesis, full bool, count uin func benchWriteChain(b *testing.B, full bool, count uint64) { genesis := &Genesis{Config: params.AllEthashProtocolChanges} for i := 0; i < b.N; i++ { - pdb, err := pebble.New(b.TempDir(), 1024, 128, "", false, true) + pdb, err := pebble.New(b.TempDir(), 1024, 128, "", false) if err != nil { b.Fatalf("error opening database: %v", err) } @@ -316,7 +316,7 @@ func benchWriteChain(b *testing.B, full bool, count uint64) { func benchReadChain(b *testing.B, full bool, count uint64) { dir := b.TempDir() - pdb, err := pebble.New(dir, 1024, 128, "", false, true) + pdb, err := pebble.New(dir, 1024, 128, "", false) if err != nil { b.Fatalf("error opening database: %v", err) } @@ -332,7 +332,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) { b.ResetTimer() for i := 0; i < b.N; i++ { - pdb, err = pebble.New(dir, 1024, 128, "", false, true) + pdb, err = pebble.New(dir, 1024, 128, "", false) if err != nil { b.Fatalf("error opening database: %v", err) } diff --git a/core/blockchain.go b/core/blockchain.go index 6667f64911..b0c1b119fc 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -979,17 +979,16 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha // Ignore the error here since light client won't hit this path frozen, _ := bc.db.Ancients() if num+1 <= frozen { - // Truncate all relative data(header, total difficulty, body, receipt - // and canonical hash) from ancient store. - if _, err := bc.db.TruncateHead(num); err != nil { - log.Crit("Failed to truncate ancient data", "number", num, "err", err) - } - // Remove the hash <-> number mapping from the active store. - rawdb.DeleteHeaderNumber(db, hash) + // The chain segment, such as the block header, canonical hash, + // body, and receipt, will be removed from the ancient store + // in one go. + // + // The hash-to-number mapping in the key-value store will be + // removed by the hc.SetHead function. } else { - // Remove relative body and receipts from the active store. - // The header, total difficulty and canonical hash will be - // removed in the hc.SetHead function. + // Remove the associated body and receipts from the key-value store. + // The header, hash-to-number mapping, and canonical hash will be + // removed by the hc.SetHead function. rawdb.DeleteBody(db, hash, num) rawdb.DeleteReceipts(db, hash, num) } @@ -1361,7 +1360,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ size += writeSize // Sync the ancient store explicitly to ensure all data has been flushed to disk. - if err := bc.db.Sync(); err != nil { + if err := bc.db.SyncAncient(); err != nil { return 0, err } // Write hash to number mappings @@ -2627,7 +2626,8 @@ func (bc *BlockChain) InsertHeadersBeforeCutoff(headers []*types.Header) (int, e if err != nil { return 0, err } - if err := bc.db.Sync(); err != nil { + // Sync the ancient store explicitly to ensure all data has been flushed to disk. + if err := bc.db.SyncAncient(); err != nil { return 0, err } // Write hash to number mappings diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index 3ff1d77fc8..6c52d057ad 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -1765,7 +1765,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s datadir := t.TempDir() ancient := filepath.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false, true) + pdb, err := pebble.New(datadir, 0, 0, "", false) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } @@ -1850,7 +1850,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s chain.stopWithoutSaving() // Start a new blockchain back up and see where the repair leads us - pdb, err = pebble.New(datadir, 0, 0, "", false, true) + pdb, err = pebble.New(datadir, 0, 0, "", false) if err != nil { t.Fatalf("Failed to reopen persistent key-value database: %v", err) } @@ -1915,7 +1915,7 @@ func testIssue23496(t *testing.T, scheme string) { datadir := t.TempDir() ancient := filepath.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false, true) + pdb, err := pebble.New(datadir, 0, 0, "", false) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } @@ -1973,7 +1973,7 @@ func testIssue23496(t *testing.T, scheme string) { chain.stopWithoutSaving() // Start a new blockchain back up and see where the repair leads us - pdb, err = pebble.New(datadir, 0, 0, "", false, true) + pdb, err = pebble.New(datadir, 0, 0, "", false) if err != nil { t.Fatalf("Failed to reopen persistent key-value database: %v", err) } diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index e998b510df..424854b2bf 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -1969,7 +1969,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme datadir := t.TempDir() ancient := filepath.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false, true) + pdb, err := pebble.New(datadir, 0, 0, "", false) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 23effea15e..1a6fe38af6 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -66,7 +66,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo datadir := t.TempDir() ancient := filepath.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false, true) + pdb, err := pebble.New(datadir, 0, 0, "", false) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } @@ -257,7 +257,7 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) { chain.triedb.Close() // Start a new blockchain back up and see where the repair leads us - pdb, err := pebble.New(snaptest.datadir, 0, 0, "", false, true) + pdb, err := pebble.New(snaptest.datadir, 0, 0, "", false) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 134deee237..b981c33f21 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -2492,7 +2492,7 @@ func testSideImportPrunedBlocks(t *testing.T, scheme string) { datadir := t.TempDir() ancient := path.Join(datadir, "ancient") - pdb, err := pebble.New(datadir, 0, 0, "", false, true) + pdb, err := pebble.New(datadir, 0, 0, "", false) if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } diff --git a/core/headerchain.go b/core/headerchain.go index f7acc49bef..6e70dfa865 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -591,17 +591,50 @@ func (hc *HeaderChain) setHead(headBlock uint64, headTime uint64, updateFn Updat hashes = append(hashes, hdr.Hash()) } for _, hash := range hashes { + // Remove the associated block body and receipts if required. + // + // If the block is in the chain freezer, then this delete operation + // is actually ineffective. if delFn != nil { delFn(batch, hash, num) } + // Remove the hash->number mapping along with the header itself rawdb.DeleteHeader(batch, hash, num) } + // Remove the number->hash mapping rawdb.DeleteCanonicalHash(batch, num) } } // Flush all accumulated deletions. if err := batch.Write(); err != nil { - log.Crit("Failed to rewind block", "error", err) + log.Crit("Failed to commit batch in setHead", "err", err) + } + // Explicitly flush the pending writes in the key-value store to disk, ensuring + // data durability of the previous deletions. + if err := hc.chainDb.SyncKeyValue(); err != nil { + log.Crit("Failed to sync the key-value store in setHead", "err", err) + } + // Truncate the excessive chain segments in the ancient store. + // These are actually deferred deletions from the loop above. + // + // This step must be performed after synchronizing the key-value store; + // otherwise, in the event of a panic, it's theoretically possible to + // lose recent key-value store writes while the ancient store deletions + // remain, leading to data inconsistency, e.g., the gap between the key + // value store and ancient can be created due to unclean shutdown. + if delFn != nil { + // Ignore the error here since light client won't hit this path + frozen, _ := hc.chainDb.Ancients() + header := hc.CurrentHeader() + + // Truncate the excessive chain segment above the current chain head + // in the ancient store. + if header.Number.Uint64()+1 < frozen { + _, err := hc.chainDb.TruncateHead(header.Number.Uint64() + 1) + if err != nil { + log.Crit("Failed to truncate head block", "err", err) + } + } } // Clear out any stale content from the caches hc.headerCache.Purge() diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index f3c671f45a..cc7a62df32 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -205,7 +205,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { continue } // Batch of blocks have been frozen, flush them before wiping from key-value store - if err := f.Sync(); err != nil { + if err := f.SyncAncient(); err != nil { log.Crit("Failed to flush frozen tables", "err", err) } // Wipe out all data from the active database diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 2a50e3f9ee..a03dbafb1f 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -131,8 +131,8 @@ func (db *nofreezedb) TruncateTail(items uint64) (uint64, error) { return 0, errNotSupported } -// Sync returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) Sync() error { +// SyncAncient returns an error as we don't have a backing chain freezer. +func (db *nofreezedb) SyncAncient() error { return errNotSupported } diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index 105d3af934..1e5b98c7fe 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -325,8 +325,8 @@ func (f *Freezer) TruncateTail(tail uint64) (uint64, error) { return old, nil } -// Sync flushes all data tables to disk. -func (f *Freezer) Sync() error { +// SyncAncient flushes all data tables to disk. +func (f *Freezer) SyncAncient() error { var errs []error for _, table := range f.tables { if err := table.Sync(); err != nil { diff --git a/core/rawdb/freezer_memory.go b/core/rawdb/freezer_memory.go index 4274546de5..bd286f45f5 100644 --- a/core/rawdb/freezer_memory.go +++ b/core/rawdb/freezer_memory.go @@ -395,8 +395,8 @@ func (f *MemoryFreezer) TruncateTail(tail uint64) (uint64, error) { return old, nil } -// Sync flushes all data tables to disk. -func (f *MemoryFreezer) Sync() error { +// SyncAncient flushes all data tables to disk. +func (f *MemoryFreezer) SyncAncient() error { return nil } diff --git a/core/rawdb/freezer_resettable.go b/core/rawdb/freezer_resettable.go index 2e64e6074c..01df2877d9 100644 --- a/core/rawdb/freezer_resettable.go +++ b/core/rawdb/freezer_resettable.go @@ -194,12 +194,12 @@ func (f *resettableFreezer) TruncateTail(tail uint64) (uint64, error) { return f.freezer.TruncateTail(tail) } -// Sync flushes all data tables to disk. -func (f *resettableFreezer) Sync() error { +// SyncAncient flushes all data tables to disk. +func (f *resettableFreezer) SyncAncient() error { f.lock.RLock() defer f.lock.RUnlock() - return f.freezer.Sync() + return f.freezer.SyncAncient() } // AncientDatadir returns the path of the ancient store. diff --git a/core/rawdb/freezer_test.go b/core/rawdb/freezer_test.go index 150734d3ac..a7a3559ec4 100644 --- a/core/rawdb/freezer_test.go +++ b/core/rawdb/freezer_test.go @@ -392,7 +392,7 @@ func TestFreezerCloseSync(t *testing.T) { if err := f.Close(); err != nil { t.Fatal(err) } - if err := f.Sync(); err == nil { + if err := f.SyncAncient(); err == nil { t.Fatalf("want error, have nil") } else if have, want := err.Error(), "[closed closed]"; have != want { t.Fatalf("want %v, have %v", have, want) diff --git a/core/rawdb/table.go b/core/rawdb/table.go index 1a9060b636..9a342a8217 100644 --- a/core/rawdb/table.go +++ b/core/rawdb/table.go @@ -107,10 +107,10 @@ func (t *table) TruncateTail(items uint64) (uint64, error) { return t.db.TruncateTail(items) } -// Sync is a noop passthrough that just forwards the request to the underlying +// SyncAncient is a noop passthrough that just forwards the request to the underlying // database. -func (t *table) Sync() error { - return t.db.Sync() +func (t *table) SyncAncient() error { + return t.db.SyncAncient() } // AncientDatadir returns the ancient datadir of the underlying database. @@ -188,6 +188,12 @@ func (t *table) Compact(start []byte, limit []byte) error { return t.db.Compact(start, limit) } +// SyncKeyValue ensures that all pending writes are flushed to disk, +// guaranteeing data durability up to the point. +func (t *table) SyncKeyValue() error { + return t.db.SyncKeyValue() +} + // NewBatch creates a write-only database that buffers changes to its host db // until a final write is called, each operation prefixing all keys with the // pre-configured string. diff --git a/ethdb/database.go b/ethdb/database.go index f2d458b85f..7f421752c4 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -57,6 +57,13 @@ type KeyValueStater interface { Stat() (string, error) } +// KeyValueSyncer wraps the SyncKeyValue method of a backing data store. +type KeyValueSyncer interface { + // SyncKeyValue ensures that all pending writes are flushed to disk, + // guaranteeing data durability up to the point. + SyncKeyValue() error +} + // Compacter wraps the Compact method of a backing data store. type Compacter interface { // Compact flattens the underlying data store for the given key range. In essence, @@ -75,6 +82,7 @@ type KeyValueStore interface { KeyValueReader KeyValueWriter KeyValueStater + KeyValueSyncer KeyValueRangeDeleter Batcher Iteratee @@ -126,6 +134,9 @@ type AncientWriter interface { // The integer return value is the total size of the written data. ModifyAncients(func(AncientWriteOp) error) (int64, error) + // SyncAncient flushes all in-memory ancient store data to disk. + SyncAncient() error + // TruncateHead discards all but the first n ancient data from the ancient store. // After the truncation, the latest item can be accessed it item_n-1(start from 0). TruncateHead(n uint64) (uint64, error) @@ -138,9 +149,6 @@ type AncientWriter interface { // // Note that data marked as non-prunable will still be retained and remain accessible. TruncateTail(n uint64) (uint64, error) - - // Sync flushes all in-memory ancient store data to disk. - Sync() error } // AncientWriteOp is given to the function argument of ModifyAncients. diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index ef02e91822..223d01aff6 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -324,6 +324,22 @@ func (db *Database) Path() string { return db.fn } +// SyncKeyValue flushes all pending writes in the write-ahead-log to disk, +// ensuring data durability up to that point. +func (db *Database) SyncKeyValue() error { + // In theory, the WAL (Write-Ahead Log) can be explicitly synchronized using + // a write operation with SYNC=true. However, there is no dedicated key reserved + // for this purpose, and even a nil key (key=nil) is considered a valid + // database entry. + // + // In LevelDB, writes are blocked until the data is written to the WAL, meaning + // recent writes won't be lost unless a power failure or system crash occurs. + // Additionally, LevelDB is no longer the default database engine and is likely + // only used by hash-mode archive nodes. Given this, the durability guarantees + // without explicit sync are acceptable in the context of LevelDB. + return nil +} + // meter periodically retrieves internal leveldb counters and reports them to // the metrics subsystem. func (db *Database) meter(refresh time.Duration, namespace string) { diff --git a/ethdb/memorydb/memorydb.go b/ethdb/memorydb/memorydb.go index a797275e92..f56727cf4a 100644 --- a/ethdb/memorydb/memorydb.go +++ b/ethdb/memorydb/memorydb.go @@ -199,6 +199,12 @@ func (db *Database) Compact(start []byte, limit []byte) error { return nil } +// SyncKeyValue ensures that all pending writes are flushed to disk, +// guaranteeing data durability up to the point. +func (db *Database) SyncKeyValue() error { + return nil +} + // Len returns the number of entries currently present in the memory database. // // Note, this method is only used for testing (i.e. not public in general) and diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index 969e67af5a..9ece995655 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -144,7 +144,7 @@ func (l panicLogger) Fatalf(format string, args ...interface{}) { // New returns a wrapped pebble DB object. The namespace is the prefix that the // metrics reporting should use for surfacing internal stats. -func New(file string, cache int, handles int, namespace string, readonly bool, ephemeral bool) (*Database, error) { +func New(file string, cache int, handles int, namespace string, readonly bool) (*Database, error) { // Ensure we have some minimal caching and file guarantees if cache < minCache { cache = minCache @@ -182,10 +182,18 @@ func New(file string, cache int, handles int, namespace string, readonly bool, e memTableSize = maxMemTableSize - 1 } db := &Database{ - fn: file, - log: logger, - quitChan: make(chan chan error), - writeOptions: &pebble.WriteOptions{Sync: !ephemeral}, + fn: file, + log: logger, + quitChan: make(chan chan error), + + // Use asynchronous write mode by default. Otherwise, the overhead of frequent fsync + // operations can be significant, especially on platforms with slow fsync performance + // (e.g., macOS) or less capable SSDs. + // + // Note that enabling async writes means recent data may be lost in the event of an + // application-level panic (writes will also be lost on a machine-level failure, + // of course). Geth is expected to handle recovery from an unclean shutdown. + writeOptions: pebble.NoSync, } opt := &pebble.Options{ // Pebble has a single combined cache area and the write @@ -228,6 +236,15 @@ func New(file string, cache int, handles int, namespace string, readonly bool, e WriteStallEnd: db.onWriteStallEnd, }, Logger: panicLogger{}, // TODO(karalabe): Delete when this is upstreamed in Pebble + + // Pebble is configured to use asynchronous write mode, meaning write operations + // return as soon as the data is cached in memory, without waiting for the WAL + // to be written. This mode offers better write performance but risks losing + // recent writes if the application crashes or a power failure/system crash occurs. + // + // By setting the WALBytesPerSync, the cached WAL writes will be periodically + // flushed at the background if the accumulated size exceeds this threshold. + WALBytesPerSync: 5 * ethdb.IdealBatchSize, } // Disable seek compaction explicitly. Check https://github.com/ethereum/go-ethereum/pull/20130 // for more details. @@ -414,6 +431,18 @@ func (d *Database) Path() string { return d.fn } +// SyncKeyValue flushes all pending writes in the write-ahead-log to disk, +// ensuring data durability up to that point. +func (d *Database) SyncKeyValue() error { + // The entry (value=nil) is not written to the database; it is only + // added to the WAL. Writing this special log entry in sync mode + // automatically flushes all previous writes, ensuring database + // durability up to this point. + b := d.db.NewBatch() + b.LogData(nil, nil) + return d.db.Apply(b, pebble.Sync) +} + // meter periodically retrieves internal pebble counters and reports them to // the metrics subsystem. func (d *Database) meter(refresh time.Duration, namespace string) { diff --git a/ethdb/pebble/pebble_test.go b/ethdb/pebble/pebble_test.go index 3265491d4a..e703a8d0ce 100644 --- a/ethdb/pebble/pebble_test.go +++ b/ethdb/pebble/pebble_test.go @@ -17,6 +17,7 @@ package pebble import ( + "errors" "testing" "github.com/cockroachdb/pebble" @@ -54,3 +55,26 @@ func BenchmarkPebbleDB(b *testing.B) { } }) } + +func TestPebbleLogData(t *testing.T) { + db, err := pebble.Open("", &pebble.Options{ + FS: vfs.NewMem(), + }) + if err != nil { + t.Fatal(err) + } + + _, _, err = db.Get(nil) + if !errors.Is(err, pebble.ErrNotFound) { + t.Fatal("Unknown database entry") + } + + b := db.NewBatch() + b.LogData(nil, nil) + db.Apply(b, pebble.Sync) + + _, _, err = db.Get(nil) + if !errors.Is(err, pebble.ErrNotFound) { + t.Fatal("Unknown database entry") + } +} diff --git a/ethdb/remotedb/remotedb.go b/ethdb/remotedb/remotedb.go index 8a91fdbcf2..a417a25854 100644 --- a/ethdb/remotedb/remotedb.go +++ b/ethdb/remotedb/remotedb.go @@ -110,7 +110,7 @@ func (db *Database) TruncateTail(n uint64) (uint64, error) { panic("not supported") } -func (db *Database) Sync() error { +func (db *Database) SyncAncient() error { return nil } @@ -138,6 +138,10 @@ func (db *Database) Compact(start []byte, limit []byte) error { return nil } +func (db *Database) SyncKeyValue() error { + return nil +} + func (db *Database) Close() error { db.remote.Close() return nil diff --git a/node/database.go b/node/database.go index b7d0d856cb..e3ccb91066 100644 --- a/node/database.go +++ b/node/database.go @@ -36,11 +36,6 @@ type openOptions struct { Cache int // the capacity(in megabytes) of the data caching Handles int // number of files to be open simultaneously ReadOnly bool - - // Ephemeral means that filesystem sync operations should be avoided: - // data integrity in the face of a crash is not important. This option - // should typically be used in tests. - Ephemeral bool } // openDatabase opens both a disk-based key-value database such as leveldb or pebble, but also @@ -83,7 +78,7 @@ func openKeyValueDatabase(o openOptions) (ethdb.Database, error) { } if o.Type == rawdb.DBPebble || existingDb == rawdb.DBPebble { log.Info("Using pebble as the backing database") - return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) + return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) } if o.Type == rawdb.DBLeveldb || existingDb == rawdb.DBLeveldb { log.Info("Using leveldb as the backing database") @@ -91,7 +86,7 @@ func openKeyValueDatabase(o openOptions) (ethdb.Database, error) { } // No pre-existing database, no user-requested one either. Default to Pebble. log.Info("Defaulting to pebble as the backing database") - return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) + return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) } // newLevelDBDatabase creates a persistent key-value database without a freezer @@ -107,8 +102,8 @@ func newLevelDBDatabase(file string, cache int, handles int, namespace string, r // newPebbleDBDatabase creates a persistent key-value database without a freezer // moving immutable chain segments into cold storage. -func newPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool, ephemeral bool) (ethdb.Database, error) { - db, err := pebble.New(file, cache, handles, namespace, readonly, ephemeral) +func newPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) { + db, err := pebble.New(file, cache, handles, namespace, readonly) if err != nil { return nil, err } diff --git a/trie/trie_test.go b/trie/trie_test.go index 54d1b083d8..91fde6dbf2 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -830,6 +830,7 @@ func (s *spongeDb) NewBatch() ethdb.Batch { return &spongeBat func (s *spongeDb) NewBatchWithSize(size int) ethdb.Batch { return &spongeBatch{s} } func (s *spongeDb) Stat() (string, error) { panic("implement me") } func (s *spongeDb) Compact(start []byte, limit []byte) error { panic("implement me") } +func (s *spongeDb) SyncKeyValue() error { return nil } func (s *spongeDb) Close() error { return nil } func (s *spongeDb) Put(key []byte, value []byte) error { var ( diff --git a/triedb/pathdb/buffer.go b/triedb/pathdb/buffer.go index dea8875bda..c4e081b973 100644 --- a/triedb/pathdb/buffer.go +++ b/triedb/pathdb/buffer.go @@ -135,10 +135,13 @@ func (b *buffer) flush(db ethdb.KeyValueStore, freezer ethdb.AncientWriter, node start = time.Now() batch = db.NewBatchWithSize(b.nodes.dbsize() * 11 / 10) // extra 10% for potential pebble internal stuff ) - // Explicitly sync the state freezer, ensuring that all written - // data is transferred to disk before updating the key-value store. + // Explicitly sync the state freezer to ensure all written data is persisted to disk + // before updating the key-value store. + // + // This step is crucial to guarantee that the corresponding state history remains + // available for state rollback. if freezer != nil { - if err := freezer.Sync(); err != nil { + if err := freezer.SyncAncient(); err != nil { return err } } diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index d48850c102..155e28543d 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -454,6 +454,15 @@ func (db *Database) Recover(root common.Hash) error { db.tree.reset(dl) } rawdb.DeleteTrieJournal(db.diskdb) + + // Explicitly sync the key-value store to ensure all recent writes are + // flushed to disk. This step is crucial to prevent a scenario where + // recent key-value writes are lost due to an application panic, while + // the associated state histories have already been removed, resulting + // in the inability to perform a state rollback. + if err := db.diskdb.SyncKeyValue(); err != nil { + return err + } _, err := truncateFromHead(db.diskdb, db.freezer, dl.stateID()) if err != nil { return err From 181dd2e66025ee6e5cd1c304f4c5f62f911d6272 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 8 May 2025 21:15:36 +0800 Subject: [PATCH 349/940] cmd/geth, internal: fix flaky console tests (#31784) This pull request bumps the timeout for flaky console tests on appveyor. --- cmd/geth/consolecmd_test.go | 6 +++--- eth/api_backend_test.go | 18 +++++++++++------- internal/cmdtest/test_cmd.go | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index ca8efb5f98..4e1f6340a0 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -102,17 +102,17 @@ func TestAttachWelcome(t *testing.T) { "--http", "--http.port", httpPort, "--ws", "--ws.port", wsPort) t.Run("ipc", func(t *testing.T) { - waitForEndpoint(t, ipc, 4*time.Second) + waitForEndpoint(t, ipc, 2*time.Minute) testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs) }) t.Run("http", func(t *testing.T) { endpoint := "http://127.0.0.1:" + httpPort - waitForEndpoint(t, endpoint, 4*time.Second) + waitForEndpoint(t, endpoint, 2*time.Minute) testAttachWelcome(t, geth, endpoint, httpAPIs) }) t.Run("ws", func(t *testing.T) { endpoint := "ws://127.0.0.1:" + wsPort - waitForEndpoint(t, endpoint, 4*time.Second) + waitForEndpoint(t, endpoint, 2*time.Minute) testAttachWelcome(t, geth, endpoint, httpAPIs) }) geth.Kill() diff --git a/eth/api_backend_test.go b/eth/api_backend_test.go index 049f68d827..dfca24aba7 100644 --- a/eth/api_backend_test.go +++ b/eth/api_backend_test.go @@ -134,13 +134,17 @@ func TestSendTx(t *testing.T) { func testSendTx(t *testing.T, withLocal bool) { b := initBackend(withLocal) - txA := pricedSetCodeTx(0, 250000, uint256.NewInt(params.GWei), uint256.NewInt(params.GWei), key, []unsignedAuth{ - { - nonce: 0, - key: key, - }, - }) - b.SendTx(context.Background(), txA) + txA := pricedSetCodeTx(0, 250000, uint256.NewInt(params.GWei), uint256.NewInt(params.GWei), key, []unsignedAuth{{nonce: 0, key: key}}) + if err := b.SendTx(context.Background(), txA); err != nil { + t.Fatalf("Failed to submit tx: %v", err) + } + for { + pending, _ := b.TxPool().ContentFrom(address) + if len(pending) == 1 { + break + } + time.Sleep(100 * time.Millisecond) + } txB := makeTx(1, nil, nil, key) err := b.SendTx(context.Background(), txB) diff --git a/internal/cmdtest/test_cmd.go b/internal/cmdtest/test_cmd.go index 4890d0b7c6..f6f0425598 100644 --- a/internal/cmdtest/test_cmd.go +++ b/internal/cmdtest/test_cmd.go @@ -237,7 +237,7 @@ func (tt *TestCmd) Kill() { } func (tt *TestCmd) withKillTimeout(fn func()) { - timeout := time.AfterFunc(30*time.Second, func() { + timeout := time.AfterFunc(2*time.Minute, func() { tt.Log("killing the child process (timeout)") tt.Kill() }) From 6bc57579d14063c0f2a9c7da5022d25b3a850cf3 Mon Sep 17 00:00:00 2001 From: maskpp Date: Thu, 8 May 2025 21:21:48 +0800 Subject: [PATCH 350/940] core/types: delete unused test variable (#31776) Delete the unused `Account.PrivateKey` variable. --- core/types/account.go | 12 ++++-------- core/types/gen_account.go | 22 ++++++++-------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/core/types/account.go b/core/types/account.go index 52ce184cda..bcfb83418c 100644 --- a/core/types/account.go +++ b/core/types/account.go @@ -38,17 +38,13 @@ type Account struct { Storage map[common.Hash]common.Hash `json:"storage,omitempty"` Balance *big.Int `json:"balance" gencodec:"required"` Nonce uint64 `json:"nonce,omitempty"` - - // used in tests - PrivateKey []byte `json:"secretKey,omitempty"` } type accountMarshaling struct { - Code hexutil.Bytes - Balance *math.HexOrDecimal256 - Nonce math.HexOrDecimal64 - Storage map[storageJSON]storageJSON - PrivateKey hexutil.Bytes + Code hexutil.Bytes + Balance *math.HexOrDecimal256 + Nonce math.HexOrDecimal64 + Storage map[storageJSON]storageJSON } // storageJSON represents a 256 bit byte array, but allows less than 256 bits when diff --git a/core/types/gen_account.go b/core/types/gen_account.go index 4e475896a7..89165ee3ad 100644 --- a/core/types/gen_account.go +++ b/core/types/gen_account.go @@ -17,11 +17,10 @@ var _ = (*accountMarshaling)(nil) // MarshalJSON marshals as JSON. func (a Account) MarshalJSON() ([]byte, error) { type Account struct { - Code hexutil.Bytes `json:"code,omitempty"` - Storage map[storageJSON]storageJSON `json:"storage,omitempty"` - Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` - Nonce math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey hexutil.Bytes `json:"secretKey,omitempty"` + Code hexutil.Bytes `json:"code,omitempty"` + Storage map[storageJSON]storageJSON `json:"storage,omitempty"` + Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` + Nonce math.HexOrDecimal64 `json:"nonce,omitempty"` } var enc Account enc.Code = a.Code @@ -33,18 +32,16 @@ func (a Account) MarshalJSON() ([]byte, error) { } enc.Balance = (*math.HexOrDecimal256)(a.Balance) enc.Nonce = math.HexOrDecimal64(a.Nonce) - enc.PrivateKey = a.PrivateKey return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (a *Account) UnmarshalJSON(input []byte) error { type Account struct { - Code *hexutil.Bytes `json:"code,omitempty"` - Storage map[storageJSON]storageJSON `json:"storage,omitempty"` - Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` - Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"` + Code *hexutil.Bytes `json:"code,omitempty"` + Storage map[storageJSON]storageJSON `json:"storage,omitempty"` + Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` + Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"` } var dec Account if err := json.Unmarshal(input, &dec); err != nil { @@ -66,8 +63,5 @@ func (a *Account) UnmarshalJSON(input []byte) error { if dec.Nonce != nil { a.Nonce = uint64(*dec.Nonce) } - if dec.PrivateKey != nil { - a.PrivateKey = *dec.PrivateKey - } return nil } From 0f48cbf017d6ee721ec2b74fced95b05c155f72b Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 8 May 2025 22:27:01 +0800 Subject: [PATCH 351/940] core, triedb/pathdb: bail out error if write state history fails (#31781) This PR fixes an issue that could lead to data corruption. Writing the state history may fail due to insufficient disk space or other potential errors. With this change, the entire state insertion will be aborted instead of silently ignoring the error. Without this fix, state transitions would continue while the associated state history is lost. After a restart, the resulting gap would be detected, making recovery impossible. --- core/rawdb/accessors_state.go | 24 ++++++++++++++++-------- triedb/pathdb/disklayer.go | 2 ++ triedb/pathdb/history.go | 5 +++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go index adc77fae83..41e15debe9 100644 --- a/core/rawdb/accessors_state.go +++ b/core/rawdb/accessors_state.go @@ -258,13 +258,21 @@ func ReadStateHistory(db ethdb.AncientReaderOp, id uint64) ([]byte, []byte, []by // WriteStateHistory writes the provided state history to database. Compute the // position of state history in freezer by minus one since the id of first state // history starts from one(zero for initial state). -func WriteStateHistory(db ethdb.AncientWriter, id uint64, meta []byte, accountIndex []byte, storageIndex []byte, accounts []byte, storages []byte) { - db.ModifyAncients(func(op ethdb.AncientWriteOp) error { - op.AppendRaw(stateHistoryMeta, id-1, meta) - op.AppendRaw(stateHistoryAccountIndex, id-1, accountIndex) - op.AppendRaw(stateHistoryStorageIndex, id-1, storageIndex) - op.AppendRaw(stateHistoryAccountData, id-1, accounts) - op.AppendRaw(stateHistoryStorageData, id-1, storages) - return nil +func WriteStateHistory(db ethdb.AncientWriter, id uint64, meta []byte, accountIndex []byte, storageIndex []byte, accounts []byte, storages []byte) error { + _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + if err := op.AppendRaw(stateHistoryMeta, id-1, meta); err != nil { + return err + } + if err := op.AppendRaw(stateHistoryAccountIndex, id-1, accountIndex); err != nil { + return err + } + if err := op.AppendRaw(stateHistoryStorageIndex, id-1, storageIndex); err != nil { + return err + } + if err := op.AppendRaw(stateHistoryAccountData, id-1, accounts); err != nil { + return err + } + return op.AppendRaw(stateHistoryStorageData, id-1, storages) }) + return err } diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index 184f6430a2..f3a60a507d 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -231,6 +231,8 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { oldest uint64 ) if dl.db.freezer != nil { + // Bail out with an error if writing the state history fails. + // This can happen, for example, if the device is full. err := writeHistory(dl.db.freezer, bottom) if err != nil { return nil, err diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index c063e45371..aed0296da5 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -542,8 +542,9 @@ func writeHistory(writer ethdb.AncientWriter, dl *diffLayer) error { indexSize := common.StorageSize(len(accountIndex) + len(storageIndex)) // Write history data into five freezer table respectively. - rawdb.WriteStateHistory(writer, dl.stateID(), history.meta.encode(), accountIndex, storageIndex, accountData, storageData) - + if err := rawdb.WriteStateHistory(writer, dl.stateID(), history.meta.encode(), accountIndex, storageIndex, accountData, storageData); err != nil { + return err + } historyDataBytesMeter.Mark(int64(dataSize)) historyIndexBytesMeter.Mark(int64(indexSize)) historyBuildTimeMeter.UpdateSince(start) From 485ff4bbff83abbf27a82a5660545e713c992c3f Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 8 May 2025 22:28:16 +0800 Subject: [PATCH 352/940] core: implement in-block prefetcher (#31557) This pull request enhances the block prefetcher by executing transactions in parallel to warm the cache alongside the main block processor. Unlike the original prefetcher, which only executes the next block and is limited to chain syncing, the new implementation can be applied to any block. This makes it useful not only during chain sync but also for regular block insertion after the initial sync. --------- Co-authored-by: Marius van der Wijden --- core/blockchain.go | 143 ++++++++++++++++-------------- core/blockchain_insert.go | 1 + core/state/database.go | 13 ++- core/state/reader.go | 180 ++++++++++++++++++++++++++++++++++---- core/state/statedb.go | 19 +++- core/state_prefetcher.go | 115 ++++++++++++++++-------- core/state_transition.go | 4 +- triedb/pathdb/metrics.go | 4 +- 8 files changed, 352 insertions(+), 127 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index b0c1b119fc..3c691600eb 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -92,8 +92,10 @@ var ( blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil) blockReorgDropMeter = metrics.NewRegisteredMeter("chain/reorg/drop", nil) - blockPrefetchExecuteTimer = metrics.NewRegisteredTimer("chain/prefetch/executes", nil) - blockPrefetchInterruptMeter = metrics.NewRegisteredMeter("chain/prefetch/interrupts", nil) + blockPrefetchExecuteTimer = metrics.NewRegisteredResettingTimer("chain/prefetch/executes", nil) + blockPrefetchInterruptMeter = metrics.NewRegisteredMeter("chain/prefetch/interrupts", nil) + blockPrefetchTxsInvalidMeter = metrics.NewRegisteredMeter("chain/prefetch/txs/invalid", nil) + blockPrefetchTxsValidMeter = metrics.NewRegisteredMeter("chain/prefetch/txs/valid", nil) errInsertionInterrupted = errors.New("insertion is interrupted") errChainStopped = errors.New("blockchain is stopped") @@ -1758,18 +1760,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness bc.reportBlock(block, nil, err) return nil, it.index, err } - // No validation errors for the first block (or chain prefix skipped) - var activeState *state.StateDB - defer func() { - // The chain importer is starting and stopping trie prefetchers. If a bad - // block or other error is hit however, an early return may not properly - // terminate the background threads. This defer ensures that we clean up - // and dangling prefetcher, without deferring each and holding on live refs. - if activeState != nil { - activeState.StopPrefetcher() - } - }() - // Track the singleton witness from this chain insertion (if any) var witness *stateless.Witness @@ -1825,63 +1815,20 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness continue } // Retrieve the parent block and it's state to execute on top - start := time.Now() parent := it.previous() if parent == nil { parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1) } - statedb, err := state.New(parent.Root, bc.statedb) - if err != nil { - return nil, it.index, err - } - - // 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) - } - activeState = statedb - - // If we have a followup block, run that against the current state to pre-cache - // transactions and probabilistically some of the account/storage trie nodes. - var followupInterrupt atomic.Bool - if !bc.cacheConfig.TrieCleanNoPrefetch { - if followup, err := it.peek(); followup != nil && err == nil { - throwaway, _ := state.New(parent.Root, bc.statedb) - - go func(start time.Time, followup *types.Block, throwaway *state.StateDB) { - // Disable tracing for prefetcher executions. - vmCfg := bc.vmConfig - vmCfg.Tracer = nil - bc.prefetcher.Prefetch(followup, throwaway, vmCfg, &followupInterrupt) - - blockPrefetchExecuteTimer.Update(time.Since(start)) - if followupInterrupt.Load() { - blockPrefetchInterruptMeter.Mark(1) - } - }(time.Now(), followup, throwaway) - } - } - // The traced section of block import. - res, err := bc.processBlock(block, statedb, start, setHead) - followupInterrupt.Store(true) + start := time.Now() + res, err := bc.processBlock(parent.Root, block, setHead, makeWitness && len(chain) == 1) if err != nil { return nil, it.index, err } // Report the import stats before returning the various results stats.processed++ stats.usedGas += res.usedGas + witness = res.witness var snapDiffItems, snapBufItems common.StorageSize if bc.snaps != nil { @@ -1937,11 +1884,74 @@ type blockProcessingResult struct { usedGas uint64 procTime time.Duration status WriteStatus + witness *stateless.Witness } // 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) (_ *blockProcessingResult, blockEndErr error) { +func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, setHead bool, makeWitness bool) (_ *blockProcessingResult, blockEndErr error) { + var ( + err error + startTime = time.Now() + statedb *state.StateDB + interrupt atomic.Bool + ) + defer interrupt.Store(true) // terminate the prefetch at the end + + if bc.cacheConfig.TrieCleanNoPrefetch { + statedb, err = state.New(parentRoot, bc.statedb) + if err != nil { + return nil, err + } + } else { + // If prefetching is enabled, run that against the current state to pre-cache + // transactions and probabilistically some of the account/storage trie nodes. + // + // Note: the main processor and prefetcher share the same reader with a local + // cache for mitigating the overhead of state access. + reader, err := bc.statedb.ReaderWithCache(parentRoot) + if err != nil { + return nil, err + } + throwaway, err := state.NewWithReader(parentRoot, bc.statedb, reader) + if err != nil { + return nil, err + } + statedb, err = state.NewWithReader(parentRoot, bc.statedb, reader) + if err != nil { + return nil, err + } + go func(start time.Time, throwaway *state.StateDB, block *types.Block) { + // Disable tracing for prefetcher executions. + vmCfg := bc.vmConfig + vmCfg.Tracer = nil + bc.prefetcher.Prefetch(block, throwaway, vmCfg, &interrupt) + + blockPrefetchExecuteTimer.Update(time.Since(start)) + if interrupt.Load() { + blockPrefetchInterruptMeter.Mark(1) + } + }(time.Now(), throwaway, block) + } + + // 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. + var witness *stateless.Witness + 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 { + witness, err = stateless.NewWitness(block.Header(), bc) + if err != nil { + return nil, err + } + } + statedb.StartPrefetcher("chain", witness) + defer statedb.StopPrefetcher() + } + if bc.logger != nil && bc.logger.OnBlockStart != nil { bc.logger.OnBlockStart(tracing.BlockEvent{ Block: block, @@ -2000,7 +2010,7 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s } } xvtime := time.Since(xvstart) - proctime := time.Since(start) // processing + validation + cross validation + proctime := time.Since(startTime) // processing + validation + cross validation // Update the metrics touched during block processing and validation accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing) @@ -2041,9 +2051,14 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s 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) + blockInsertTimer.UpdateSince(startTime) - return &blockProcessingResult{usedGas: res.GasUsed, procTime: proctime, status: status}, nil + return &blockProcessingResult{ + usedGas: res.GasUsed, + procTime: proctime, + status: status, + witness: witness, + }, nil } // insertSideChain is called when an import batch hits upon a pruned ancestor diff --git a/core/blockchain_insert.go b/core/blockchain_insert.go index ec3f771818..b4bd444606 100644 --- a/core/blockchain_insert.go +++ b/core/blockchain_insert.go @@ -138,6 +138,7 @@ func (it *insertIterator) next() (*types.Block, error) { // // Both header and body validation errors (nil too) is cached into the iterator // to avoid duplicating work on the following next() call. +// nolint:unused func (it *insertIterator) peek() (*types.Block, error) { // If we reached the end of the chain, abort if it.index+1 >= len(it.chain) { diff --git a/core/state/database.go b/core/state/database.go index faf4954650..cef59cccfb 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -34,10 +34,10 @@ import ( const ( // Number of codehash->size associations to keep. - codeSizeCacheSize = 100000 + codeSizeCacheSize = 1_000_000 // 4 megabytes in total // Cache size granted for caching clean code. - codeCacheSize = 64 * 1024 * 1024 + codeCacheSize = 256 * 1024 * 1024 // Number of address->curve point associations to keep. pointCacheSize = 4096 @@ -208,6 +208,15 @@ func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) { return newReader(newCachingCodeReader(db.disk, db.codeCache, db.codeSizeCache), combined), nil } +// ReaderWithCache creates a state reader with internal local cache. +func (db *CachingDB) ReaderWithCache(stateRoot common.Hash) (Reader, error) { + reader, err := db.Reader(stateRoot) + if err != nil { + return nil, err + } + return newReaderWithCache(reader), nil +} + // OpenTrie opens the main account trie at a specific root hash. func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) { if db.triedb.IsVerkle() { diff --git a/core/state/reader.go b/core/state/reader.go index a0f15dfcc8..5ad0385e9e 100644 --- a/core/state/reader.go +++ b/core/state/reader.go @@ -18,6 +18,7 @@ package state import ( "errors" + "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/lru" @@ -32,6 +33,24 @@ import ( "github.com/ethereum/go-ethereum/triedb/database" ) +// bufferPool holds the buffers for keccak calculation. +var bufferPool = sync.Pool{ + New: func() interface{} { + return crypto.NewKeccakState() + }, +} + +// allocBuff allocates the keccak buffer from the pool +func allocBuff() crypto.KeccakState { + return bufferPool.Get().(crypto.KeccakState) +} + +// releaseBuff returns the provided keccak buffer to the pool. It's unnecessary +// to clear the buffer, as it will be cleared before the calculation. +func releaseBuff(buff crypto.KeccakState) { + bufferPool.Put(buff) +} + // ContractCodeReader defines the interface for accessing contract code. type ContractCodeReader interface { // Code retrieves a particular contract's code. @@ -51,6 +70,9 @@ type ContractCodeReader interface { // StateReader defines the interface for accessing accounts and storage slots // associated with a specific state. +// +// StateReader is assumed to be thread-safe and implementation must take care +// of the concurrency issue by themselves. type StateReader interface { // Account retrieves the account associated with a particular address. // @@ -70,6 +92,9 @@ type StateReader interface { // Reader defines the interface for accessing accounts, storage slots and contract // code associated with a specific state. +// +// Reader is assumed to be thread-safe and implementation must take care of the +// concurrency issue by themselves. type Reader interface { ContractCodeReader StateReader @@ -77,6 +102,8 @@ type Reader interface { // cachingCodeReader implements ContractCodeReader, accessing contract code either in // local key-value store or the shared code cache. +// +// cachingCodeReader is safe for concurrent access. type cachingCodeReader struct { db ethdb.KeyValueReader @@ -123,18 +150,14 @@ func (r *cachingCodeReader) CodeSize(addr common.Address, codeHash common.Hash) return len(code), nil } -// flatReader wraps a database state reader. +// flatReader wraps a database state reader and is safe for concurrent access. type flatReader struct { reader database.StateReader - buff crypto.KeccakState } // newFlatReader constructs a state reader with on the given state root. func newFlatReader(reader database.StateReader) *flatReader { - return &flatReader{ - reader: reader, - buff: crypto.NewKeccakState(), - } + return &flatReader{reader: reader} } // Account implements StateReader, retrieving the account specified by the address. @@ -144,7 +167,10 @@ func newFlatReader(reader database.StateReader) *flatReader { // // The returned account might be nil if it's not existent. func (r *flatReader) Account(addr common.Address) (*types.StateAccount, error) { - account, err := r.reader.Account(crypto.HashData(r.buff, addr.Bytes())) + buff := allocBuff() + defer releaseBuff(buff) + + account, err := r.reader.Account(crypto.HashData(buff, addr.Bytes())) if err != nil { return nil, err } @@ -174,8 +200,11 @@ func (r *flatReader) Account(addr common.Address) (*types.StateAccount, error) { // // The returned storage slot might be empty if it's not existent. func (r *flatReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) { - addrHash := crypto.HashData(r.buff, addr.Bytes()) - slotHash := crypto.HashData(r.buff, key.Bytes()) + buff := allocBuff() + defer releaseBuff(buff) + + addrHash := crypto.HashData(buff, addr.Bytes()) + slotHash := crypto.HashData(buff, key.Bytes()) ret, err := r.reader.Storage(addrHash, slotHash) if err != nil { return common.Hash{}, err @@ -196,13 +225,20 @@ func (r *flatReader) Storage(addr common.Address, key common.Hash) (common.Hash, // trieReader implements the StateReader interface, providing functions to access // state from the referenced trie. +// +// trieReader is safe for concurrent read. 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 + root common.Hash // State root which uniquely represent a state + db *triedb.Database // Database for loading trie + buff crypto.KeccakState // Buffer for keccak256 hashing + + // Main trie, resolved in constructor. Note either the Merkle-Patricia-tree + // or Verkle-tree is not safe for concurrent read. + mainTrie Trie + 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 + lock sync.Mutex // Lock for protecting concurrent read } // trieReader constructs a trie reader of the specific state. An error will be @@ -230,11 +266,8 @@ func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCach }, nil } -// Account implements StateReader, 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 is the inner version of Account and assumes the r.lock is already held. +func (r *trieReader) account(addr common.Address) (*types.StateAccount, error) { account, err := r.mainTrie.GetAccount(addr) if err != nil { return nil, err @@ -247,12 +280,26 @@ func (r *trieReader) Account(addr common.Address) (*types.StateAccount, error) { return account, nil } +// Account implements StateReader, 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) { + r.lock.Lock() + defer r.lock.Unlock() + + return r.account(addr) +} + // Storage implements StateReader, 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) { + r.lock.Lock() + defer r.lock.Unlock() + var ( tr Trie found bool @@ -268,7 +315,7 @@ func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash, // 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) + _, err := r.account(addr) if err != nil { return common.Hash{}, err } @@ -293,6 +340,9 @@ func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash, // multiStateReader is the aggregation of a list of StateReader interface, // providing state access by leveraging all readers. The checking priority // is determined by the position in the reader list. +// +// multiStateReader is safe for concurrent read and assumes all underlying +// readers are thread-safe as well. type multiStateReader struct { readers []StateReader // List of state readers, sorted by checking priority } @@ -358,3 +408,95 @@ func newReader(codeReader ContractCodeReader, stateReader StateReader) *reader { StateReader: stateReader, } } + +// readerWithCache is a wrapper around Reader that maintains additional state caches +// to support concurrent state access. +type readerWithCache struct { + Reader // safe for concurrent read + + // Previously resolved state entries. + accounts map[common.Address]*types.StateAccount + accountLock sync.RWMutex + + // List of storage buckets, each of which is thread-safe. + // This reader is typically used in scenarios requiring concurrent + // access to storage. Using multiple buckets helps mitigate + // the overhead caused by locking. + storageBuckets [16]struct { + lock sync.RWMutex + storages map[common.Address]map[common.Hash]common.Hash + } +} + +// newReaderWithCache constructs the reader with local cache. +func newReaderWithCache(reader Reader) *readerWithCache { + r := &readerWithCache{ + Reader: reader, + accounts: make(map[common.Address]*types.StateAccount), + } + for i := range r.storageBuckets { + r.storageBuckets[i].storages = make(map[common.Address]map[common.Hash]common.Hash) + } + return r +} + +// Account implements StateReader, retrieving the account specified by the address. +// The returned account might be nil if it's not existent. +// +// An error will be returned if the state is corrupted in the underlying reader. +func (r *readerWithCache) Account(addr common.Address) (*types.StateAccount, error) { + // Try to resolve the requested account in the local cache + r.accountLock.RLock() + acct, ok := r.accounts[addr] + r.accountLock.RUnlock() + if ok { + return acct, nil + } + // Try to resolve the requested account from the underlying reader + acct, err := r.Reader.Account(addr) + if err != nil { + return nil, err + } + r.accountLock.Lock() + r.accounts[addr] = acct + r.accountLock.Unlock() + return acct, nil +} + +// Storage implements StateReader, retrieving the storage slot specified by the +// address and slot key. The returned storage slot might be empty if it's not +// existent. +// +// An error will be returned if the state is corrupted in the underlying reader. +func (r *readerWithCache) Storage(addr common.Address, slot common.Hash) (common.Hash, error) { + var ( + value common.Hash + ok bool + bucket = &r.storageBuckets[addr[0]&0x0f] + ) + // Try to resolve the requested storage slot in the local cache + bucket.lock.RLock() + slots, ok := bucket.storages[addr] + if ok { + value, ok = slots[slot] + } + bucket.lock.RUnlock() + if ok { + return value, nil + } + // Try to resolve the requested storage slot from the underlying reader + value, err := r.Reader.Storage(addr, slot) + if err != nil { + return common.Hash{}, err + } + bucket.lock.Lock() + slots, ok = bucket.storages[addr] + if !ok { + slots = make(map[common.Hash]common.Hash) + bucket.storages[addr] = slots + } + slots[slot] = value + bucket.lock.Unlock() + + return value, nil +} diff --git a/core/state/statedb.go b/core/state/statedb.go index e3f5b9e1a0..9378cae7de 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -159,11 +159,17 @@ type StateDB struct { // New creates a new state from a given trie. func New(root common.Hash, db Database) (*StateDB, error) { - tr, err := db.OpenTrie(root) + reader, err := db.Reader(root) if err != nil { return nil, err } - reader, err := db.Reader(root) + return NewWithReader(root, db, reader) +} + +// NewWithReader creates a new state for the specified state root. Unlike New, +// this function accepts an additional Reader which is bound to the given root. +func NewWithReader(root common.Hash, db Database, reader Reader) (*StateDB, error) { + tr, err := db.OpenTrie(root) if err != nil { return nil, err } @@ -392,6 +398,12 @@ func (s *StateDB) Database() Database { return s.db } +// Reader retrieves the low level database reader supporting the +// lower level operations. +func (s *StateDB) Reader() Reader { + return s.reader +} + func (s *StateDB) HasSelfDestructed(addr common.Address) bool { stateObject := s.getStateObject(addr) if stateObject != nil { @@ -650,11 +662,10 @@ func (s *StateDB) CreateContract(addr common.Address) { // Snapshots of the copied state cannot be applied to the copy. func (s *StateDB) Copy() *StateDB { // Copy all the basic fields, initialize the memory ones - reader, _ := s.db.Reader(s.originalRoot) // impossible to fail state := &StateDB{ db: s.db, trie: mustCopyTrie(s.trie), - reader: reader, + reader: s.reader, originalRoot: s.originalRoot, stateObjects: make(map[common.Address]*stateObject, len(s.stateObjects)), stateObjectsDestruct: make(map[common.Address]*stateObject, len(s.stateObjectsDestruct)), diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 805df5ef62..f3129f57cd 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -17,17 +17,22 @@ package core import ( + "bytes" + "runtime" "sync/atomic" + "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/params" + "golang.org/x/sync/errgroup" ) -// statePrefetcher is a basic Prefetcher, which blindly executes a block on top -// of an arbitrary state with the goal of prefetching potentially useful state -// data from disk before the main block processor start executing. +// statePrefetcher is a basic Prefetcher that executes transactions from a block +// on top of the parent state, aiming to prefetch potentially useful state data +// from disk. Transactions are executed in parallel to fully leverage the +// SSD's read performance. type statePrefetcher struct { config *params.ChainConfig // Chain configuration options chain *HeaderChain // Canonical block chain @@ -43,41 +48,81 @@ func newStatePrefetcher(config *params.ChainConfig, chain *HeaderChain) *statePr // Prefetch processes the state changes according to the Ethereum rules by running // the transaction messages using the statedb, but any changes are discarded. The -// only goal is to pre-cache transaction signatures and state trie nodes. +// only goal is to warm the state caches. func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, cfg vm.Config, interrupt *atomic.Bool) { var ( - header = block.Header() - gaspool = new(GasPool).AddGas(block.GasLimit()) - blockContext = NewEVMBlockContext(header, p.chain, nil) - evm = vm.NewEVM(blockContext, statedb, p.config, cfg) - signer = types.MakeSigner(p.config, header.Number, header.Time) + fails atomic.Int64 + header = block.Header() + signer = types.MakeSigner(p.config, header.Number, header.Time) + workers errgroup.Group + reader = statedb.Reader() ) - // Iterate over and process the individual transactions - byzantium := p.config.IsByzantium(block.Number()) - for i, tx := range block.Transactions() { - // If block precaching was interrupted, abort - if interrupt != nil && interrupt.Load() { - return - } - // Convert the transaction into an executable message and pre-cache its sender - msg, err := TransactionToMessage(tx, signer, header.BaseFee) - if err != nil { - return // Also invalid block, bail out - } - statedb.SetTxContext(tx.Hash(), i) + workers.SetLimit(runtime.NumCPU() / 2) - // We attempt to apply a transaction. The goal is not to execute - // the transaction successfully, rather to warm up touched data slots. - if _, err := ApplyMessage(evm, msg, gaspool); err != nil { - return // Ugh, something went horribly wrong, bail out - } - // If we're pre-byzantium, pre-load trie nodes for the intermediate root - if !byzantium { - statedb.IntermediateRoot(true) - } - } - // If were post-byzantium, pre-load trie nodes for the final root hash - if byzantium { - statedb.IntermediateRoot(true) + // Iterate over and process the individual transactions + for i, tx := range block.Transactions() { + stateCpy := statedb.Copy() // closure + workers.Go(func() error { + // If block precaching was interrupted, abort + if interrupt != nil && interrupt.Load() { + return nil + } + // Preload the touched accounts and storage slots in advance + sender, err := types.Sender(signer, tx) + if err != nil { + fails.Add(1) + return nil + } + reader.Account(sender) + + if tx.To() != nil { + account, _ := reader.Account(*tx.To()) + + // Preload the contract code if the destination has non-empty code + if account != nil && !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) { + reader.Code(*tx.To(), common.BytesToHash(account.CodeHash)) + } + } + for _, list := range tx.AccessList() { + reader.Account(list.Address) + if len(list.StorageKeys) > 0 { + for _, slot := range list.StorageKeys { + reader.Storage(list.Address, slot) + } + } + } + // Execute the message to preload the implicit touched states + evm := vm.NewEVM(NewEVMBlockContext(header, p.chain, nil), stateCpy, p.config, cfg) + + // Convert the transaction into an executable message and pre-cache its sender + msg, err := TransactionToMessage(tx, signer, header.BaseFee) + if err != nil { + fails.Add(1) + return nil // Also invalid block, bail out + } + // Disable the nonce check + msg.SkipNonceChecks = true + + stateCpy.SetTxContext(tx.Hash(), i) + + // We attempt to apply a transaction. The goal is not to execute + // the transaction successfully, rather to warm up touched data slots. + if _, err := ApplyMessage(evm, msg, new(GasPool).AddGas(block.GasLimit())); err != nil { + fails.Add(1) + return nil // Ugh, something went horribly wrong, bail out + } + // Pre-load trie nodes for the intermediate root. + // + // This operation incurs significant memory allocations due to + // trie hashing and node decoding. TODO(rjl493456442): investigate + // ways to mitigate this overhead. + stateCpy.IntermediateRoot(true) + return nil + }) } + workers.Wait() + + blockPrefetchTxsValidMeter.Mark(int64(len(block.Transactions())) - fails.Load()) + blockPrefetchTxsInvalidMeter.Mark(fails.Load()) + return } diff --git a/core/state_transition.go b/core/state_transition.go index f9c9a2ab5a..ff2051ddd2 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -159,7 +159,9 @@ type Message struct { // 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. + // + // This field will be set to true for operations like RPC eth_call + // or the state prefetching. SkipNonceChecks bool // When SkipFromEOACheck is true, the message sender is not checked to be an EOA. diff --git a/triedb/pathdb/metrics.go b/triedb/pathdb/metrics.go index 45dad6f1ae..abe2dfe1f6 100644 --- a/triedb/pathdb/metrics.go +++ b/triedb/pathdb/metrics.go @@ -46,7 +46,7 @@ var ( nodeDiskFalseMeter = metrics.NewRegisteredMeter("pathdb/disk/false", nil) nodeDiffFalseMeter = metrics.NewRegisteredMeter("pathdb/diff/false", nil) - commitTimeTimer = metrics.NewRegisteredTimer("pathdb/commit/time", nil) + commitTimeTimer = metrics.NewRegisteredResettingTimer("pathdb/commit/time", nil) commitNodesMeter = metrics.NewRegisteredMeter("pathdb/commit/nodes", nil) commitBytesMeter = metrics.NewRegisteredMeter("pathdb/commit/bytes", nil) @@ -57,7 +57,7 @@ var ( gcStorageMeter = metrics.NewRegisteredMeter("pathdb/gc/storage/count", nil) gcStorageBytesMeter = metrics.NewRegisteredMeter("pathdb/gc/storage/bytes", nil) - historyBuildTimeMeter = metrics.NewRegisteredTimer("pathdb/history/time", nil) + historyBuildTimeMeter = metrics.NewRegisteredResettingTimer("pathdb/history/time", nil) historyDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/data", nil) historyIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/index", nil) ) From 0eb2eeea908d654b971249142fcbb735ba2c6923 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Fri, 9 May 2025 07:52:40 +0200 Subject: [PATCH 353/940] all: create global hasher pool (#31769) This PR creates a global hasher pool that can be used by all packages. It also removes a bunch of the package local pools. It also updates a few locations to use available hashers or the global hashing pool to reduce allocations all over the codebase. This change should reduce global allocation count by ~1% --------- Co-authored-by: Gary Rong --- core/rawdb/accessors_trie.go | 28 ++-------------------------- core/state/reader.go | 30 +++--------------------------- core/types/hashing.go | 3 +-- core/vm/evm.go | 3 ++- core/vm/instructions.go | 7 +------ core/vm/interpreter.go | 2 +- crypto/crypto.go | 15 +++++++++++++-- trie/hasher.go | 2 +- trie/sync.go | 24 +----------------------- triedb/pathdb/disklayer.go | 26 ++------------------------ triedb/pathdb/execute.go | 15 +++++++-------- 11 files changed, 34 insertions(+), 121 deletions(-) diff --git a/core/rawdb/accessors_trie.go b/core/rawdb/accessors_trie.go index 8bd6b71eee..e154ab527b 100644 --- a/core/rawdb/accessors_trie.go +++ b/core/rawdb/accessors_trie.go @@ -18,7 +18,6 @@ package rawdb import ( "fmt" - "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -45,25 +44,6 @@ const HashScheme = "hash" // on extra state diffs to survive deep reorg. const PathScheme = "path" -// 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: crypto.NewKeccakState()} }, -} - -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) -} - // ReadAccountTrieNode retrieves the account trie node with the specified node path. func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) []byte { data, _ := db.Get(accountTrieNodeKey(path)) @@ -170,9 +150,7 @@ func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash c if len(blob) == 0 { return false } - h := newHasher() - defer h.release() - return h.hash(blob) == hash // exists but not match + return crypto.Keccak256Hash(blob) == hash // exists but not match default: panic(fmt.Sprintf("Unknown scheme %v", scheme)) } @@ -194,9 +172,7 @@ func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash if len(blob) == 0 { return nil } - h := newHasher() - defer h.release() - if h.hash(blob) != hash { + if crypto.Keccak256Hash(blob) != hash { return nil // exists but not match } return blob diff --git a/core/state/reader.go b/core/state/reader.go index 5ad0385e9e..09edf6ab8d 100644 --- a/core/state/reader.go +++ b/core/state/reader.go @@ -33,24 +33,6 @@ import ( "github.com/ethereum/go-ethereum/triedb/database" ) -// bufferPool holds the buffers for keccak calculation. -var bufferPool = sync.Pool{ - New: func() interface{} { - return crypto.NewKeccakState() - }, -} - -// allocBuff allocates the keccak buffer from the pool -func allocBuff() crypto.KeccakState { - return bufferPool.Get().(crypto.KeccakState) -} - -// releaseBuff returns the provided keccak buffer to the pool. It's unnecessary -// to clear the buffer, as it will be cleared before the calculation. -func releaseBuff(buff crypto.KeccakState) { - bufferPool.Put(buff) -} - // ContractCodeReader defines the interface for accessing contract code. type ContractCodeReader interface { // Code retrieves a particular contract's code. @@ -167,10 +149,7 @@ func newFlatReader(reader database.StateReader) *flatReader { // // The returned account might be nil if it's not existent. func (r *flatReader) Account(addr common.Address) (*types.StateAccount, error) { - buff := allocBuff() - defer releaseBuff(buff) - - account, err := r.reader.Account(crypto.HashData(buff, addr.Bytes())) + account, err := r.reader.Account(crypto.Keccak256Hash(addr.Bytes())) if err != nil { return nil, err } @@ -200,11 +179,8 @@ func (r *flatReader) Account(addr common.Address) (*types.StateAccount, error) { // // The returned storage slot might be empty if it's not existent. func (r *flatReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) { - buff := allocBuff() - defer releaseBuff(buff) - - addrHash := crypto.HashData(buff, addr.Bytes()) - slotHash := crypto.HashData(buff, key.Bytes()) + addrHash := crypto.Keccak256Hash(addr.Bytes()) + slotHash := crypto.Keccak256Hash(key.Bytes()) ret, err := r.reader.Storage(addrHash, slotHash) if err != nil { return common.Hash{}, err diff --git a/core/types/hashing.go b/core/types/hashing.go index 224d7a87ea..3cc22d50d1 100644 --- a/core/types/hashing.go +++ b/core/types/hashing.go @@ -25,12 +25,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // hasherPool holds LegacyKeccak256 hashers for rlpHash. var hasherPool = sync.Pool{ - New: func() interface{} { return sha3.NewLegacyKeccak256() }, + New: func() interface{} { return crypto.NewKeccakState() }, } // encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding. diff --git a/core/vm/evm.go b/core/vm/evm.go index c28dcb2554..ecb0f118ec 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -555,7 +555,8 @@ func (evm *EVM) Create(caller common.Address, code []byte, gas uint64, value *ui // The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:] // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. func (evm *EVM) Create2(caller common.Address, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), crypto.Keccak256(code)) + inithash := crypto.HashData(evm.interpreter.hasher, code) + contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash[:]) return evm.create(caller, code, gas, endowment, contractAddr, CREATE2) } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 0b3b1d1569..63bb6d2d51 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -22,7 +22,6 @@ import ( "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" "github.com/holiman/uint256" ) @@ -234,11 +233,7 @@ func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( offset, size := scope.Stack.pop(), scope.Stack.peek() data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64()) - if interpreter.hasher == nil { - interpreter.hasher = crypto.NewKeccakState() - } else { - interpreter.hasher.Reset() - } + interpreter.hasher.Reset() interpreter.hasher.Write(data) interpreter.hasher.Read(interpreter.hasherBuf[:]) diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index a0038d1aa8..a62c3c843d 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -150,7 +150,7 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter { } } evm.Config.ExtraEips = extraEips - return &EVMInterpreter{evm: evm, table: table} + return &EVMInterpreter{evm: evm, table: table, hasher: crypto.NewKeccakState()} } // Run loops and evaluates the contract's code with the given input data and returns diff --git a/crypto/crypto.go b/crypto/crypto.go index 13e9b134f0..09596c05ce 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -28,6 +28,7 @@ import ( "io" "math/big" "os" + "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" @@ -73,6 +74,12 @@ func NewKeccakState() KeccakState { return sha3.NewLegacyKeccak256().(KeccakState) } +var hasherPool = sync.Pool{ + New: func() any { + return sha3.NewLegacyKeccak256().(KeccakState) + }, +} + // HashData hashes the provided data using the KeccakState and returns a 32 byte hash func HashData(kh KeccakState, data []byte) (h common.Hash) { kh.Reset() @@ -84,22 +91,26 @@ func HashData(kh KeccakState, data []byte) (h common.Hash) { // Keccak256 calculates and returns the Keccak256 hash of the input data. func Keccak256(data ...[]byte) []byte { b := make([]byte, 32) - d := NewKeccakState() + d := hasherPool.Get().(KeccakState) + d.Reset() for _, b := range data { d.Write(b) } d.Read(b) + hasherPool.Put(d) return b } // Keccak256Hash calculates and returns the Keccak256 hash of the input data, // converting it to an internal Hash data structure. func Keccak256Hash(data ...[]byte) (h common.Hash) { - d := NewKeccakState() + d := hasherPool.Get().(KeccakState) + d.Reset() for _, b := range data { d.Write(b) } d.Read(h[:]) + hasherPool.Put(d) return h } diff --git a/trie/hasher.go b/trie/hasher.go index 614640ae3a..393cb0bd4d 100644 --- a/trie/hasher.go +++ b/trie/hasher.go @@ -34,7 +34,7 @@ type hasher struct { // hasherPool holds pureHashers var hasherPool = sync.Pool{ - New: func() interface{} { + New: func() any { return &hasher{ tmp: make([]byte, 0, 550), // cap is as large as a full fullNode. sha: crypto.NewKeccakState(), diff --git a/trie/sync.go b/trie/sync.go index 3b7caae5b1..8d0ce6901c 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -729,9 +729,7 @@ func (s *Sync) hasNode(owner common.Hash, path []byte, hash common.Hash) (exists } else { blob = rawdb.ReadStorageTrieNode(s.database, owner, path) } - h := newBlobHasher() - defer h.release() - exists = hash == h.hash(blob) + exists = hash == crypto.Keccak256Hash(blob) inconsistent = !exists && len(blob) != 0 return exists, inconsistent } @@ -746,23 +744,3 @@ 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/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index f3a60a507d..b8869888d9 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -115,15 +115,12 @@ func (dl *diskLayer) node(owner common.Hash, path []byte, depth int) ([]byte, co dirtyNodeMissMeter.Mark(1) // Try to retrieve the trie node from the clean memory cache - h := newHasher() - defer h.release() - key := nodeCacheKey(owner, path) if dl.nodes != nil { if blob := dl.nodes.Get(nil, key); len(blob) > 0 { cleanNodeHitMeter.Mark(1) cleanNodeReadMeter.Mark(int64(len(blob))) - return blob, h.hash(blob), &nodeLoc{loc: locCleanCache, depth: depth}, nil + return blob, crypto.Keccak256Hash(blob), &nodeLoc{loc: locCleanCache, depth: depth}, nil } cleanNodeMissMeter.Mark(1) } @@ -138,7 +135,7 @@ func (dl *diskLayer) node(owner common.Hash, path []byte, depth int) ([]byte, co dl.nodes.Set(key, blob) cleanNodeWriteMeter.Mark(int64(len(blob))) } - return blob, h.hash(blob), &nodeLoc{loc: locDiskLayer, depth: depth}, nil + return blob, crypto.Keccak256Hash(blob), &nodeLoc{loc: locDiskLayer, depth: depth}, nil } // account directly retrieves the account RLP associated with a particular @@ -359,22 +356,3 @@ func (dl *diskLayer) resetCache() { dl.nodes.Reset() } } - -// 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: crypto.NewKeccakState()} }, -} - -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/triedb/pathdb/execute.go b/triedb/pathdb/execute.go index 2400f280a3..db1e679277 100644 --- a/triedb/pathdb/execute.go +++ b/triedb/pathdb/execute.go @@ -22,6 +22,7 @@ import ( "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" "github.com/ethereum/go-ethereum/trie/trienode" @@ -85,10 +86,9 @@ func apply(db database.NodeDatabase, prevRoot common.Hash, postRoot common.Hash, func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) error { // The account was present in prev-state, decode it from the // 'slim-rlp' format bytes. - h := newHasher() - defer h.release() + h := crypto.NewKeccakState() - addrHash := h.hash(addr.Bytes()) + addrHash := crypto.HashData(h, addr.Bytes()) prev, err := types.FullAccount(ctx.accounts[addr]) if err != nil { return err @@ -113,7 +113,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) for key, val := range ctx.storages[addr] { tkey := key if ctx.rawStorageKey { - tkey = h.hash(key.Bytes()) + tkey = crypto.HashData(h, key.Bytes()) } var err error if len(val) == 0 { @@ -149,10 +149,9 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) // account and storage is wiped out correctly. func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) error { // The account must be existent in post-state, load the account. - h := newHasher() - defer h.release() + h := crypto.NewKeccakState() - addrHash := h.hash(addr.Bytes()) + addrHash := crypto.HashData(h, addr.Bytes()) blob, err := ctx.accountTrie.Get(addrHash.Bytes()) if err != nil { return err @@ -174,7 +173,7 @@ func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) } tkey := key if ctx.rawStorageKey { - tkey = h.hash(key.Bytes()) + tkey = crypto.HashData(h, key.Bytes()) } if err := st.Delete(tkey.Bytes()); err != nil { return err From 0db99f4e409b05c109cffac26c15dd641757a3ab Mon Sep 17 00:00:00 2001 From: Satoshi Is Here <39875249+SatoshiIsHere@users.noreply.github.com> Date: Fri, 9 May 2025 19:56:00 +0900 Subject: [PATCH 354/940] core/types: reduce allocations in tx.EffectiveGasTip (#31598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR introduces an allocation-free version of the Transaction.EffectiveGasTip method to improve performance by reducing memory allocations. ## Changes - Added a new `EffectiveGasTipInto` method that accepts a destination parameter to avoid memory allocations - Refactored the existing `EffectiveGasTip` method to use the new allocation-free implementation - Updated related methods (`EffectiveGasTipValue`, `EffectiveGasTipCmp`, `EffectiveGasTipIntCmp`) to use the allocation-free approach - Added tests and benchmarks to verify correctness and measure performance improvements ## Motivation In high-transaction-volume environments, the `EffectiveGasTip` method is called frequently. Reducing memory allocations in this method decreases garbage collection pressure and improves overall system performance. ## Benchmark Results As-Is BenchmarkEffectiveGasTip/Original-10 42089140 27.45 ns/op 8 B/op 1 allocs/op To-Be BenchmarkEffectiveGasTip/IntoMethod-10 72353263 16.73 ns/op 0 B/op 0 allocs/op ## Summary of Improvements - **Performance**: ~39% faster execution (27.45 ns/op → 16.73 ns/op) - **Memory**: Eliminated all allocations (8 B/op → 0 B/op) - **Allocation count**: Reduced from 1 to 0 allocations per operation This optimization follows the same pattern successfully applied to other methods in the codebase, maintaining API compatibility while improving performance. ## Safety & Compatibility This optimization has no side effects or adverse impacts because: - It maintains functional equivalence as confirmed by comprehensive tests - It preserves API compatibility with existing callers - It follows clear memory ownership patterns with the destination parameter - It maintains thread safety by only modifying the caller-provided destination parameter This optimization follows the same pattern successfully applied to other methods in the codebase, providing better performance without compromising stability or correctness. --------- Co-authored-by: lightclient --- core/types/transaction.go | 41 ++++++++------ core/types/transaction_test.go | 99 ++++++++++++++++++++++++++++++++++ eth/tracers/js/goja.go | 3 +- 3 files changed, 126 insertions(+), 17 deletions(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index a2f4104635..934feb7353 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -355,28 +355,31 @@ func (tx *Transaction) GasTipCapIntCmp(other *big.Int) int { // Note: if the effective gasTipCap is negative, this method returns both error // the actual negative value, _and_ ErrGasFeeCapTooLow func (tx *Transaction) EffectiveGasTip(baseFee *big.Int) (*big.Int, error) { + dst := new(big.Int) + err := tx.calcEffectiveGasTip(dst, baseFee) + return dst, err +} + +// calcEffectiveGasTip calculates the effective gas tip of the transaction and +// saves the result to dst. +func (tx *Transaction) calcEffectiveGasTip(dst *big.Int, baseFee *big.Int) error { if baseFee == nil { - return tx.GasTipCap(), nil + dst.Set(tx.inner.gasTipCap()) + return nil } + var err error - gasFeeCap := tx.GasFeeCap() + gasFeeCap := tx.inner.gasFeeCap() if gasFeeCap.Cmp(baseFee) < 0 { err = ErrGasFeeCapTooLow } - gasFeeCap = gasFeeCap.Sub(gasFeeCap, baseFee) - gasTipCap := tx.GasTipCap() - if gasTipCap.Cmp(gasFeeCap) < 0 { - return gasTipCap, err + dst.Sub(gasFeeCap, baseFee) + gasTipCap := tx.inner.gasTipCap() + if gasTipCap.Cmp(dst) < 0 { + dst.Set(gasTipCap) } - return gasFeeCap, err -} - -// EffectiveGasTipValue is identical to EffectiveGasTip, but does not return an -// error in case the effective gasTipCap is negative -func (tx *Transaction) EffectiveGasTipValue(baseFee *big.Int) *big.Int { - effectiveTip, _ := tx.EffectiveGasTip(baseFee) - return effectiveTip + return err } // EffectiveGasTipCmp compares the effective gasTipCap of two transactions assuming the given base fee. @@ -384,7 +387,11 @@ func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *big.Int) if baseFee == nil { return tx.GasTipCapCmp(other) } - return tx.EffectiveGasTipValue(baseFee).Cmp(other.EffectiveGasTipValue(baseFee)) + // Use more efficient internal method. + txTip, otherTip := new(big.Int), new(big.Int) + tx.calcEffectiveGasTip(txTip, baseFee) + other.calcEffectiveGasTip(otherTip, baseFee) + return txTip.Cmp(otherTip) } // EffectiveGasTipIntCmp compares the effective gasTipCap of a transaction to the given gasTipCap. @@ -392,7 +399,9 @@ func (tx *Transaction) EffectiveGasTipIntCmp(other *big.Int, baseFee *big.Int) i if baseFee == nil { return tx.GasTipCapIntCmp(other) } - return tx.EffectiveGasTipValue(baseFee).Cmp(other) + txTip := new(big.Int) + tx.calcEffectiveGasTip(txTip, baseFee) + return txTip.Cmp(other) } // BlobGas returns the blob gas limit of the transaction for blob transactions, 0 otherwise. diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 8922448d97..7d5e2f058a 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" ) @@ -593,3 +594,101 @@ func BenchmarkHash(b *testing.B) { signer.Hash(tx) } } + +func BenchmarkEffectiveGasTip(b *testing.B) { + signer := LatestSigner(params.TestChainConfig) + key, _ := crypto.GenerateKey() + txdata := &DynamicFeeTx{ + ChainID: big.NewInt(1), + Nonce: 0, + GasTipCap: big.NewInt(2000000000), + GasFeeCap: big.NewInt(3000000000), + Gas: 21000, + To: &common.Address{}, + Value: big.NewInt(0), + Data: nil, + } + tx, _ := SignNewTx(key, signer, txdata) + baseFee := big.NewInt(1000000000) // 1 gwei + + b.Run("Original", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := tx.EffectiveGasTip(baseFee) + if err != nil { + b.Fatal(err) + } + } + }) + + b.Run("IntoMethod", func(b *testing.B) { + b.ReportAllocs() + dst := new(big.Int) + for i := 0; i < b.N; i++ { + err := tx.calcEffectiveGasTip(dst, baseFee) + if err != nil { + b.Fatal(err) + } + } + }) +} + +func TestEffectiveGasTipInto(t *testing.T) { + signer := LatestSigner(params.TestChainConfig) + key, _ := crypto.GenerateKey() + + testCases := []struct { + tipCap int64 + feeCap int64 + baseFee *int64 + }{ + {tipCap: 1, feeCap: 100, baseFee: intPtr(50)}, + {tipCap: 10, feeCap: 100, baseFee: intPtr(50)}, + {tipCap: 50, feeCap: 100, baseFee: intPtr(50)}, + {tipCap: 100, feeCap: 100, baseFee: intPtr(50)}, + {tipCap: 1, feeCap: 50, baseFee: intPtr(50)}, + {tipCap: 1, feeCap: 20, baseFee: intPtr(50)}, // Base fee higher than fee cap + {tipCap: 50, feeCap: 100, baseFee: intPtr(0)}, + {tipCap: 50, feeCap: 100, baseFee: nil}, // nil base fee + } + + for i, tc := range testCases { + txdata := &DynamicFeeTx{ + ChainID: big.NewInt(1), + Nonce: 0, + GasTipCap: big.NewInt(tc.tipCap), + GasFeeCap: big.NewInt(tc.feeCap), + Gas: 21000, + To: &common.Address{}, + Value: big.NewInt(0), + Data: nil, + } + tx, _ := SignNewTx(key, signer, txdata) + + var baseFee *big.Int + if tc.baseFee != nil { + baseFee = big.NewInt(*tc.baseFee) + } + + // Get result from original method + orig, origErr := tx.EffectiveGasTip(baseFee) + + // Get result from new method + dst := new(big.Int) + newErr := tx.calcEffectiveGasTip(dst, baseFee) + + // Compare results + if (origErr != nil) != (newErr != nil) { + t.Fatalf("case %d: error mismatch: orig %v, new %v", i, origErr, newErr) + } + + if orig.Cmp(dst) != 0 { + t.Fatalf("case %d: result mismatch: orig %v, new %v", i, orig, dst) + } + } +} + +// Helper function to create integer pointer +func intPtr(i int64) *int64 { + return &i +} diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index 227ea57226..d1e65bf7f4 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -260,7 +260,8 @@ func (t *jsTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from 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, tx.EffectiveGasTipValue(env.BaseFee).String()) + gasTip, _ := tx.EffectiveGasTip(env.BaseFee) + gasPriceBig, err := t.toBig(t.vm, gasTip.String()) if err != nil { t.err = err return From fa86416ce914d36464f1af31fae0e6c8a8c65f69 Mon Sep 17 00:00:00 2001 From: Marcel <153717436+MonkeyMarcel@users.noreply.github.com> Date: Sat, 10 May 2025 08:27:27 +0800 Subject: [PATCH 355/940] metrics: add chain/mgasps to track gas usage rate (#31753) This adds a metric called `chain/mgasps`, which records how many million gas per second are being used during block insertion. The value is calculated as `usedGas * 1000 / elapsed`, and it's updated in the `insertStats.report` method. Also cleaned up the log output to reuse the same value instead of recalculating it. Useful for monitoring block processing throughput. --------- Co-authored-by: Gary Rong --- core/blockchain.go | 3 ++- core/blockchain_insert.go | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 3c691600eb..302ab14cf0 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -65,7 +65,8 @@ var ( headFinalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil) headSafeBlockGauge = metrics.NewRegisteredGauge("chain/head/safe", nil) - chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil) + chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil) + chainMgaspsGauge = metrics.NewRegisteredGauge("chain/mgasps", nil) accountReadTimer = metrics.NewRegisteredResettingTimer("chain/account/reads", nil) accountHashTimer = metrics.NewRegisteredResettingTimer("chain/account/hashes", nil) diff --git a/core/blockchain_insert.go b/core/blockchain_insert.go index b4bd444606..695aa6679b 100644 --- a/core/blockchain_insert.go +++ b/core/blockchain_insert.go @@ -43,8 +43,12 @@ func (st *insertStats) report(chain []*types.Block, index int, snapDiffItems, sn // Fetch the timings for the batch var ( now = mclock.Now() - elapsed = now.Sub(st.startTime) + elapsed = now.Sub(st.startTime) + 1 // prevent zero division + mgasps = float64(st.usedGas) * 1000 / float64(elapsed) ) + // Update the Mgas per second gauge + chainMgaspsGauge.Update(int64(mgasps)) + // If we're at the last block of the batch or report period reached, log if index == len(chain)-1 || elapsed >= statsReportLimit { // Count the number of transactions in this segment @@ -58,7 +62,7 @@ func (st *insertStats) report(chain []*types.Block, index int, snapDiffItems, sn context := []interface{}{ "number", end.Number(), "hash", end.Hash(), "blocks", st.processed, "txs", txs, "mgas", float64(st.usedGas) / 1000000, - "elapsed", common.PrettyDuration(elapsed), "mgasps", float64(st.usedGas) * 1000 / float64(elapsed), + "elapsed", common.PrettyDuration(elapsed), "mgasps", mgasps, } if timestamp := time.Unix(int64(end.Time()), 0); time.Since(timestamp) > time.Minute { context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...) From 098cc7e8782178f5f34b9101550ec2f43831188d Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Mon, 12 May 2025 14:37:01 +0800 Subject: [PATCH 356/940] ethdb/pebble: expose stall counter of pebble (#31782) This pull request adds a more Pebble metrics, tracking the amount of write stalls with specific reasons --- ethdb/pebble/pebble.go | 89 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index 9ece995655..5c851af910 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -21,6 +21,7 @@ import ( "bytes" "fmt" "runtime" + "strings" "sync" "sync/atomic" "time" @@ -55,24 +56,35 @@ const ( // Apart from basic data storage functionality it also supports batch writes and // iterating over the keyspace in binary-alphabetical order. type Database struct { - fn string // filename for reporting - db *pebble.DB // Underlying pebble storage engine + fn string // filename for reporting + db *pebble.DB // Underlying pebble storage engine + namespace string // Namespace for metrics - compTimeMeter *metrics.Meter // Meter for measuring the total time spent in database compaction - compReadMeter *metrics.Meter // Meter for measuring the data read during compaction - compWriteMeter *metrics.Meter // Meter for measuring the data written during compaction - writeDelayNMeter *metrics.Meter // Meter for measuring the write delay number due to database compaction - writeDelayMeter *metrics.Meter // Meter for measuring the write delay duration due to database compaction - diskSizeGauge *metrics.Gauge // Gauge for tracking the size of all the levels in the database - diskReadMeter *metrics.Meter // Meter for measuring the effective amount of data read - diskWriteMeter *metrics.Meter // Meter for measuring the effective amount of data written - memCompGauge *metrics.Gauge // Gauge for tracking the number of memory compaction - level0CompGauge *metrics.Gauge // Gauge for tracking the number of table compaction in level0 - nonlevel0CompGauge *metrics.Gauge // Gauge for tracking the number of table compaction in non0 level - seekCompGauge *metrics.Gauge // Gauge for tracking the number of table compaction caused by read opt - manualMemAllocGauge *metrics.Gauge // Gauge for tracking amount of non-managed memory currently allocated - - levelsGauge []*metrics.Gauge // Gauge for tracking the number of tables in levels + compTimeMeter *metrics.Meter // Meter for measuring the total time spent in database compaction + compReadMeter *metrics.Meter // Meter for measuring the data read during compaction + compWriteMeter *metrics.Meter // Meter for measuring the data written during compaction + writeDelayNMeter *metrics.Meter // Meter for measuring the write delay number due to database compaction + writeDelayMeter *metrics.Meter // Meter for measuring the write delay duration due to database compaction + diskSizeGauge *metrics.Gauge // Gauge for tracking the size of all the levels in the database + diskReadMeter *metrics.Meter // Meter for measuring the effective amount of data read + diskWriteMeter *metrics.Meter // Meter for measuring the effective amount of data written + memCompGauge *metrics.Gauge // Gauge for tracking the number of memory compaction + level0CompGauge *metrics.Gauge // Gauge for tracking the number of table compaction in level0 + nonlevel0CompGauge *metrics.Gauge // Gauge for tracking the number of table compaction in non0 level + seekCompGauge *metrics.Gauge // Gauge for tracking the number of table compaction caused by read opt + manualMemAllocGauge *metrics.Gauge // Gauge for tracking amount of non-managed memory currently allocated + liveMemTablesGauge *metrics.Gauge // Gauge for tracking the number of live memory tables + zombieMemTablesGauge *metrics.Gauge // Gauge for tracking the number of zombie memory tables + blockCacheHitGauge *metrics.Gauge // Gauge for tracking the number of total hit in the block cache + blockCacheMissGauge *metrics.Gauge // Gauge for tracking the number of total miss in the block cache + tableCacheHitGauge *metrics.Gauge // Gauge for tracking the number of total hit in the table cache + tableCacheMissGauge *metrics.Gauge // Gauge for tracking the number of total miss in the table cache + filterHitGauge *metrics.Gauge // Gauge for tracking the number of total hit in bloom filter + filterMissGauge *metrics.Gauge // Gauge for tracking the number of total miss in bloom filter + estimatedCompDebtGauge *metrics.Gauge // Gauge for tracking the number of bytes that need to be compacted + liveCompGauge *metrics.Gauge // Gauge for tracking the number of in-progress compactions + liveCompSizeGauge *metrics.Gauge // Gauge for tracking the size of in-progress compactions + levelsGauge []*metrics.Gauge // Gauge for tracking the number of tables in levels quitLock sync.RWMutex // Mutex protecting the quit channel and the closed flag quitChan chan chan error // Quit channel to stop the metrics collection before closing the database @@ -88,6 +100,7 @@ type Database struct { writeStalled atomic.Bool // Flag whether the write is stalled writeDelayStartTime time.Time // The start time of the latest write stall + writeDelayReason string // The reason of the latest write stall writeDelayCount atomic.Int64 // Total number of write stall counts writeDelayTime atomic.Int64 // Total time spent in write stalls @@ -120,11 +133,30 @@ func (d *Database) onWriteStallBegin(b pebble.WriteStallBeginInfo) { d.writeDelayStartTime = time.Now() d.writeDelayCount.Add(1) d.writeStalled.Store(true) + + // Take just the first word of the reason. These are two potential + // reasons for the write stall: + // - memtable count limit reached + // - L0 file count limit exceeded + reason := b.Reason + if i := strings.IndexByte(reason, ' '); i != -1 { + reason = reason[:i] + } + if reason == "L0" || reason == "memtable" { + d.writeDelayReason = reason + metrics.GetOrRegisterGauge(d.namespace+"stall/count/"+reason, nil).Inc(1) + } } func (d *Database) onWriteStallEnd() { d.writeDelayTime.Add(int64(time.Since(d.writeDelayStartTime))) d.writeStalled.Store(false) + + if d.writeDelayReason != "" { + metrics.GetOrRegisterResettingTimer(d.namespace+"stall/time/"+d.writeDelayReason, nil).UpdateSince(d.writeDelayStartTime) + d.writeDelayReason = "" + } + d.writeDelayStartTime = time.Time{} } // panicLogger is just a noop logger to disable Pebble's internal logger. @@ -270,6 +302,17 @@ func New(file string, cache int, handles int, namespace string, readonly bool) ( db.nonlevel0CompGauge = metrics.GetOrRegisterGauge(namespace+"compact/nonlevel0", nil) db.seekCompGauge = metrics.GetOrRegisterGauge(namespace+"compact/seek", nil) db.manualMemAllocGauge = metrics.GetOrRegisterGauge(namespace+"memory/manualalloc", nil) + db.liveMemTablesGauge = metrics.GetOrRegisterGauge(namespace+"table/live", nil) + db.zombieMemTablesGauge = metrics.GetOrRegisterGauge(namespace+"table/zombie", nil) + db.blockCacheHitGauge = metrics.GetOrRegisterGauge(namespace+"cache/block/hit", nil) + db.blockCacheMissGauge = metrics.GetOrRegisterGauge(namespace+"cache/block/miss", nil) + db.tableCacheHitGauge = metrics.GetOrRegisterGauge(namespace+"cache/table/hit", nil) + db.tableCacheMissGauge = metrics.GetOrRegisterGauge(namespace+"cache/table/miss", nil) + db.filterHitGauge = metrics.GetOrRegisterGauge(namespace+"filter/hit", nil) + db.filterMissGauge = metrics.GetOrRegisterGauge(namespace+"filter/miss", nil) + db.estimatedCompDebtGauge = metrics.GetOrRegisterGauge(namespace+"compact/estimateDebt", nil) + db.liveCompGauge = metrics.GetOrRegisterGauge(namespace+"compact/live/count", nil) + db.liveCompSizeGauge = metrics.GetOrRegisterGauge(namespace+"compact/live/size", nil) // Start up the metrics gathering and return go db.meter(metricsGatheringInterval, namespace) @@ -517,6 +560,18 @@ func (d *Database) meter(refresh time.Duration, namespace string) { d.nonlevel0CompGauge.Update(nonLevel0CompCount) d.level0CompGauge.Update(level0CompCount) d.seekCompGauge.Update(stats.Compact.ReadCount) + d.liveCompGauge.Update(stats.Compact.NumInProgress) + d.liveCompSizeGauge.Update(stats.Compact.InProgressBytes) + + d.liveMemTablesGauge.Update(stats.MemTable.Count) + d.zombieMemTablesGauge.Update(stats.MemTable.ZombieCount) + d.estimatedCompDebtGauge.Update(int64(stats.Compact.EstimatedDebt)) + d.tableCacheHitGauge.Update(stats.TableCache.Hits) + d.tableCacheMissGauge.Update(stats.TableCache.Misses) + d.blockCacheHitGauge.Update(stats.BlockCache.Hits) + d.blockCacheMissGauge.Update(stats.BlockCache.Misses) + d.filterHitGauge.Update(stats.Filter.Hits) + d.filterMissGauge.Update(stats.Filter.Misses) for i, level := range stats.Levels { // Append metrics for additional layers From d121c27acefb96b875f7d3047dd26e0b83862d59 Mon Sep 17 00:00:00 2001 From: Klimov Sergey Date: Mon, 12 May 2025 15:41:24 +0800 Subject: [PATCH 357/940] core/state: fix incorrect description of function behavior (#31809) --- core/state/statedb.go | 2 +- core/vm/interface.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 9378cae7de..2453d67f3e 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -298,7 +298,7 @@ func (s *StateDB) SubRefund(gas uint64) { } // Exist reports whether the given account address exists in the state. -// Notably this also returns true for self-destructed accounts. +// Notably this also returns true for self-destructed accounts within the current transaction. func (s *StateDB) Exist(addr common.Address) bool { return s.getStateObject(addr) != nil } diff --git a/core/vm/interface.go b/core/vm/interface.go index 57f35cb249..86e8c56ab0 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -69,7 +69,7 @@ type StateDB interface { SelfDestruct6780(common.Address) (uint256.Int, bool) // Exist reports whether the given account exists in state. - // Notably this should also return true for self-destructed accounts. + // Notably this also returns true for self-destructed accounts within the current transaction. Exist(common.Address) bool // Empty returns whether the given account is empty. Empty // is defined according to EIP161 (balance = nonce = code = 0). From c7bdf6b2fe4eae1db035147431147ed54f84fae7 Mon Sep 17 00:00:00 2001 From: SHADOW Date: Mon, 12 May 2025 15:01:48 +0530 Subject: [PATCH 358/940] accounts/abi/abigen: remove unnecessary test files (#31804) fix #31793: resolve conflict markers in structs-abi.go.txt --- .../abi/abigen/testdata/v2/structs-abi.go.txt | 116 ------------------ 1 file changed, 116 deletions(-) delete mode 100644 accounts/abi/abigen/testdata/v2/structs-abi.go.txt diff --git a/accounts/abi/abigen/testdata/v2/structs-abi.go.txt b/accounts/abi/abigen/testdata/v2/structs-abi.go.txt deleted file mode 100644 index aab6242707..0000000000 --- a/accounts/abi/abigen/testdata/v2/structs-abi.go.txt +++ /dev/null @@ -1,116 +0,0 @@ -// Code generated via abigen V2 - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package v1bindtests - -import ( - "bytes" - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = bytes.Equal - _ = errors.New - _ = big.NewInt - _ = common.Big1 - _ = types.BloomLookup - _ = abi.ConvertType -) - -// Struct0 is an auto generated low-level Go binding around an user-defined struct. -type Struct0 struct { - B [32]byte -} - -// StructsMetaData contains all meta data concerning the Structs contract. -var StructsMetaData = bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"F\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"B\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.A[]\",\"name\":\"a\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[]\",\"name\":\"c\",\"type\":\"uint256[]\"},{\"internalType\":\"bool[]\",\"name\":\"d\",\"type\":\"bool[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"G\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"B\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.A[]\",\"name\":\"a\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - ID: "Structs", -} - -// Structs is an auto generated Go binding around an Ethereum contract. -type Structs struct { - abi abi.ABI -} - -// NewStructs creates a new instance of Structs. -func NewStructs() *Structs { - parsed, err := StructsMetaData.ParseABI() - if err != nil { - panic(errors.New("invalid ABI: " + err.Error())) - } - return &Structs{abi: *parsed} -} - -// Instance creates a wrapper for a deployed contract instance at the given address. -<<<<<<< HEAD -// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. -func (c *Structs) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { - return bind.NewBoundContract(addr, c.abi, backend, backend, backend) -======= -// Use this to create the instance object passed to abigen v2 library functions Call, -// Transact, etc. -func (c *Structs) Instance(backend bind.ContractBackend, addr common.Address) bind.BoundContract { - return bind.NewBoundContract(backend, addr, c.abi) ->>>>>>> 854c25e086 (accounts/abi/abigen: improve v2 template) -} - -// F is the Go binding used to pack the parameters required for calling -// the contract method 0x28811f59. -// -// Solidity: function F() view returns((bytes32)[] a, uint256[] c, bool[] d) -func (structs *Structs) PackF() ([]byte, error) { - return structs.abi.Pack("F") -} - -// FOutput serves as a container for the return parameters of contract -// method F. -type FOutput struct { - A []Struct0 - C []*big.Int - D []bool -} - -// UnpackF is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x28811f59. -// -// Solidity: function F() view returns((bytes32)[] a, uint256[] c, bool[] d) -func (structs *Structs) UnpackF(data []byte) (*FOutput, error) { - out, err := structs.abi.Unpack("F", data) - if err != nil { - return nil, err - } - ret := new(FOutput) - ret.A = *abi.ConvertType(out[0], new([]Struct0)).(*[]Struct0) - ret.C = *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) - ret.D = *abi.ConvertType(out[2], new([]bool)).(*[]bool) - return ret, nil -} - -// G is the Go binding used to pack the parameters required for calling -// the contract method 0x6fecb623. -// -// Solidity: function G() view returns((bytes32)[] a) -func (structs *Structs) PackG() ([]byte, error) { - return structs.abi.Pack("G") -} - -// UnpackG is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x6fecb623. -// -// Solidity: function G() view returns((bytes32)[] a) -func (structs *Structs) UnpackG(data []byte) (*[]Struct0, error) { - out, err := structs.abi.Unpack("G", data) - if err != nil { - return nil, err - } - out0 := *abi.ConvertType(out[0], new([]Struct0)).(*[]Struct0) - return &out0, nil -} From 2cd5f22037f1c148a536b0d9b766365519c9cf60 Mon Sep 17 00:00:00 2001 From: wellna Date: Tue, 13 May 2025 13:11:27 +0100 Subject: [PATCH 359/940] crypto/kzg4844: use package github.com/crate-crypto/go-eth-kzg (#31806) I saw in https://github.com/ethereum/go-ethereum/pull/31378 introduced github.com/crate-crypto/go-eth-kzg to calculate the kzg hash, and github.com/crate-crypto/go-kzg-4844 was only used in the test files, so propose to drop it with go-eth-kzg instead --- crypto/kzg4844/kzg4844_test.go | 2 +- go.mod | 1 - go.sum | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/crypto/kzg4844/kzg4844_test.go b/crypto/kzg4844/kzg4844_test.go index a6782d4768..7fa261e523 100644 --- a/crypto/kzg4844/kzg4844_test.go +++ b/crypto/kzg4844/kzg4844_test.go @@ -21,7 +21,7 @@ import ( "testing" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - gokzg4844 "github.com/crate-crypto/go-kzg-4844" + gokzg4844 "github.com/crate-crypto/go-eth-kzg" ) func randFieldElement() [32]byte { diff --git a/go.mod b/go.mod index 924f0d2642..d27af647ec 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( github.com/consensys/gnark-crypto v0.16.0 github.com/crate-crypto/go-eth-kzg v1.3.0 github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a - github.com/crate-crypto/go-kzg-4844 v1.1.0 github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set/v2 v2.6.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 diff --git a/go.sum b/go.sum index 5d35a7a0e1..200b3725ea 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,6 @@ github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= -github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= -github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From c53db5e1f6383606d6de2fc4577ed7dbc6f8def4 Mon Sep 17 00:00:00 2001 From: maskpp Date: Tue, 13 May 2025 21:28:16 +0800 Subject: [PATCH 360/940] eth: fix returned blockContext for empty blocks in stateAtTransaction (#31768) Co-authored-by: lightclient --- eth/state_accessor.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 99ed28d96a..3c3e79a584 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -217,7 +217,13 @@ func (eth *Ethereum) stateAtBlock(ctx context.Context, block *types.Block, reexe return eth.pathState(block) } -// stateAtTransaction returns the execution environment of a certain transaction. +// stateAtTransaction returns the execution environment of a certain +// transaction. +// +// Note: when a block is empty and the state for tx index 0 is requested, this +// function will return the state of block after the pre-block operations have +// been completed (e.g. updating system contracts), but before post-block +// operations are completed (e.g. processing withdrawals). 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 { @@ -245,7 +251,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, core.ProcessParentBlockHash(block.ParentHash(), evm) } if txIndex == 0 && len(block.Transactions()) == 0 { - return nil, vm.BlockContext{}, statedb, release, nil + return nil, context, statedb, release, nil } // Recompute transactions up to the target index. signer := types.MakeSigner(eth.blockchain.Config(), block.Number(), block.Time()) From 88a7ef233abcddca1da79c88ab78a1243e23837d Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 14 May 2025 09:26:08 +0800 Subject: [PATCH 361/940] core: use unix time to check fork readiness (#31800) --- core/blockchain.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 302ab14cf0..320b90dcbe 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2543,14 +2543,22 @@ func (bc *BlockChain) reportBlock(block *types.Block, res *ProcessResult, err er // logForkReadiness will write a log when a future fork is scheduled, but not // active. This is useful so operators know their client is ready for the fork. func (bc *BlockChain) logForkReadiness(block *types.Block) { - c := bc.Config() - current, last := c.LatestFork(block.Time()), c.LatestFork(math.MaxUint64) - t := c.Timestamp(last) - if t == nil { + config := bc.Config() + current, last := config.LatestFork(block.Time()), config.LatestFork(math.MaxUint64) + + // Short circuit if the timestamp of the last fork is undefined, + // or if the network has already passed the last configured fork. + t := config.Timestamp(last) + if t == nil || current >= last { return } at := time.Unix(int64(*t), 0) - if current < last && time.Now().After(bc.lastForkReadyAlert.Add(forkReadyInterval)) { + + // Only log if: + // - Current time is before the fork activation time + // - Enough time has passed since last alert + now := time.Now() + if now.Before(at) && now.After(bc.lastForkReadyAlert.Add(forkReadyInterval)) { log.Info("Ready for fork activation", "fork", last, "date", at.Format(time.RFC822), "remaining", time.Until(at).Round(time.Second), "timestamp", at.Unix()) bc.lastForkReadyAlert = time.Now() From 16b0d9e982f7f0469930b59ba62d0c9e43281b78 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 14 May 2025 16:50:02 +0200 Subject: [PATCH 362/940] eth/catalyst: refactor engine api checks (#31182) This PR contains three refactors: - refactor the latest fork check that we use quite extensively - refactor the nil checks in NewPayloads --------- Co-authored-by: lightclient --- eth/catalyst/api.go | 449 +++++++++++++++++++++----------------------- 1 file changed, 217 insertions(+), 232 deletions(-) diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 1e6981a76a..be25712c97 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -38,6 +38,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/miner" "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" @@ -196,11 +197,11 @@ func newConsensusAPIWithoutHeartbeat(eth *eth.Ethereum) *ConsensusAPI { // and return its payloadID. func (api *ConsensusAPI) ForkchoiceUpdatedV1(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")) + switch { + case payloadAttributes.Withdrawals != nil || payloadAttributes.BeaconRoot != nil: + return engine.STATUS_INVALID, paramsErr("withdrawals and beacon root not supported in V1") + case !api.checkFork(payloadAttributes.Timestamp, forks.Paris, forks.Shanghai): + return engine.STATUS_INVALID, paramsErr("fcuV1 called post-shanghai") } } return api.forkchoiceUpdated(update, payloadAttributes, engine.PayloadV1, false) @@ -210,20 +211,15 @@ 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.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")) + switch { + case params.BeaconRoot != nil: + return engine.STATUS_INVALID, attributesErr("unexpected beacon root") + case api.checkFork(params.Timestamp, forks.Paris) && params.Withdrawals != nil: + return engine.STATUS_INVALID, attributesErr("withdrawals before shanghai") + case api.checkFork(params.Timestamp, forks.Shanghai) && params.Withdrawals == nil: + return engine.STATUS_INVALID, attributesErr("missing withdrawals") + case !api.checkFork(params.Timestamp, forks.Paris, forks.Shanghai): + return engine.STATUS_INVALID, unsupportedForkErr("fcuV2 must only be called with paris or shanghai payloads") } } return api.forkchoiceUpdated(update, params, engine.PayloadV2, false) @@ -233,14 +229,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 { - 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")) + switch { + case params.Withdrawals == nil: + return engine.STATUS_INVALID, attributesErr("missing withdrawals") + case params.BeaconRoot == nil: + return engine.STATUS_INVALID, attributesErr("missing beacon root") + case !api.checkFork(params.Timestamp, forks.Cancun, forks.Prague): + return engine.STATUS_INVALID, unsupportedForkErr("fcuV3 must only be called for cancun or prague payloads") } } // TODO(matt): the spec requires that fcu is applied when called on a valid @@ -254,11 +249,11 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, pa // 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")) + switch { + case payloadAttributes.Withdrawals != nil || payloadAttributes.BeaconRoot != nil: + return engine.STATUS_INVALID, paramsErr("withdrawals and beacon root not supported in V1") + case !api.checkFork(payloadAttributes.Timestamp, forks.Paris, forks.Shanghai): + return engine.STATUS_INVALID, paramsErr("fcuV1 called post-shanghai") } } return api.forkchoiceUpdated(update, payloadAttributes, engine.PayloadV1, true) @@ -268,20 +263,15 @@ func (api *ConsensusAPI) ForkchoiceUpdatedWithWitnessV1(update engine.Forkchoice // 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")) + switch { + case params.BeaconRoot != nil: + return engine.STATUS_INVALID, attributesErr("unexpected beacon root") + case api.checkFork(params.Timestamp, forks.Paris) && params.Withdrawals != nil: + return engine.STATUS_INVALID, attributesErr("withdrawals before shanghai") + case api.checkFork(params.Timestamp, forks.Shanghai) && params.Withdrawals == nil: + return engine.STATUS_INVALID, attributesErr("missing withdrawals") + case !api.checkFork(params.Timestamp, forks.Paris, forks.Shanghai): + return engine.STATUS_INVALID, unsupportedForkErr("fcuV2 must only be called with paris or shanghai payloads") } } return api.forkchoiceUpdated(update, params, engine.PayloadV2, true) @@ -291,14 +281,13 @@ func (api *ConsensusAPI) ForkchoiceUpdatedWithWitnessV2(update engine.Forkchoice // 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")) + switch { + case params.Withdrawals == nil: + return engine.STATUS_INVALID, attributesErr("missing withdrawals") + case params.BeaconRoot == nil: + return engine.STATUS_INVALID, attributesErr("missing beacon root") + case !api.checkFork(params.Timestamp, forks.Cancun, forks.Prague): + return engine.STATUS_INVALID, unsupportedForkErr("fcuV3 must only be called for cancun or prague payloads") } } // TODO(matt): the spec requires that fcu is applied when called on a valid @@ -468,7 +457,7 @@ func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config engine.Transit api.lastTransitionUpdate = time.Now() api.lastTransitionLock.Unlock() - ttd := api.eth.BlockChain().Config().TerminalTotalDifficulty + ttd := api.config().TerminalTotalDifficulty if ttd == nil || ttd.Cmp(config.TerminalTotalDifficulty.ToInt()) != 0 { log.Warn("Invalid TTD configured", "geth", ttd, "beacon", config.TerminalTotalDifficulty) return nil, fmt.Errorf("invalid ttd: execution %v consensus %v", ttd, config.TerminalTotalDifficulty) @@ -550,86 +539,74 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo return res, nil } +// Helper for NewPayload* methods. +var invalidStatus = engine.PayloadStatusV1{Status: engine.INVALID} + // NewPayloadV1 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. func (api *ConsensusAPI) NewPayloadV1(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 invalidStatus, paramsErr("withdrawals not supported in V1") } return api.newPayload(params, nil, nil, nil, false) } // NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. func (api *ConsensusAPI) NewPayloadV2(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")) + var ( + cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp) + shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp) + ) + switch { + case cancun: + return invalidStatus, paramsErr("can't use newPayloadV2 post-cancun") + case shanghai && params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case !shanghai && params.Withdrawals != nil: + return invalidStatus, paramsErr("non-nil withdrawals pre-shanghai") + case params.ExcessBlobGas != nil: + return invalidStatus, paramsErr("non-nil excessBlobGas pre-cancun") + case params.BlobGasUsed != nil: + return invalidStatus, paramsErr("non-nil blobGasUsed pre-cancun") } return api.newPayload(params, nil, nil, nil, false) } // NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. func (api *ConsensusAPI) NewPayloadV3(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("newPayloadV3 must only be called for cancun payloads")) + switch { + case params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return invalidStatus, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return invalidStatus, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return invalidStatus, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return invalidStatus, paramsErr("nil beaconRoot post-cancun") + case !api.checkFork(params.Timestamp, forks.Cancun): + return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") } return api.newPayload(params, versionedHashes, beaconRoot, nil, false) } // 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, executionRequests []hexutil.Bytes) (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 executionRequests == nil { - return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil executionRequests post-prague")) - } - - 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")) + switch { + case params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return invalidStatus, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return invalidStatus, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return invalidStatus, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return invalidStatus, paramsErr("nil beaconRoot post-cancun") + case executionRequests == nil: + return invalidStatus, paramsErr("nil executionRequests post-prague") + case !api.checkFork(params.Timestamp, forks.Prague): + return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") } requests := convertRequests(executionRequests) if err := validateRequests(requests); err != nil { @@ -650,23 +627,21 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV1(params engine.ExecutableData) ( // 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")) + var ( + cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp) + shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp) + ) + switch { + case cancun: + return invalidStatus, paramsErr("can't use newPayloadV2 post-cancun") + case shanghai && params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case !shanghai && params.Withdrawals != nil: + return invalidStatus, paramsErr("non-nil withdrawals pre-shanghai") + case params.ExcessBlobGas != nil: + return invalidStatus, paramsErr("non-nil excessBlobGas pre-cancun") + case params.BlobGasUsed != nil: + return invalidStatus, paramsErr("non-nil blobGasUsed pre-cancun") } return api.newPayload(params, nil, nil, nil, true) } @@ -674,25 +649,19 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV2(params engine.ExecutableData) ( // 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")) + switch { + case params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return invalidStatus, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return invalidStatus, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return invalidStatus, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return invalidStatus, paramsErr("nil beaconRoot post-cancun") + case !api.checkFork(params.Timestamp, forks.Cancun): + return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") } return api.newPayload(params, versionedHashes, beaconRoot, nil, true) } @@ -700,28 +669,21 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV3(params engine.ExecutableData, v // 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, executionRequests []hexutil.Bytes) (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 executionRequests == nil { - return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil executionRequests post-prague")) - } - - 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")) + switch { + case params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return invalidStatus, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return invalidStatus, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return invalidStatus, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return invalidStatus, paramsErr("nil beaconRoot post-cancun") + case executionRequests == nil: + return invalidStatus, paramsErr("nil executionRequests post-prague") + case !api.checkFork(params.Timestamp, forks.Prague): + return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") } requests := convertRequests(executionRequests) if err := validateRequests(requests); err != nil { @@ -742,23 +704,21 @@ func (api *ConsensusAPI) ExecuteStatelessPayloadV1(params engine.ExecutableData, // 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")) + var ( + cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp) + shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp) + ) + switch { + case cancun: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("can't use newPayloadV2 post-cancun") + case shanghai && params.Withdrawals == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") + case !shanghai && params.Withdrawals != nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil withdrawals pre-shanghai") + case params.ExcessBlobGas != nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil excessBlobGas pre-cancun") + case params.BlobGasUsed != nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil blobGasUsed pre-cancun") } return api.executeStatelessPayload(params, nil, nil, nil, opaqueWitness) } @@ -766,25 +726,19 @@ func (api *ConsensusAPI) ExecuteStatelessPayloadV2(params engine.ExecutableData, // 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")) + switch { + case params.Withdrawals == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil beaconRoot post-cancun") + case !api.checkFork(params.Timestamp, forks.Cancun): + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") } return api.executeStatelessPayload(params, versionedHashes, beaconRoot, nil, opaqueWitness) } @@ -792,30 +746,26 @@ func (api *ConsensusAPI) ExecuteStatelessPayloadV3(params engine.ExecutableData, // 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, executionRequests []hexutil.Bytes, 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 executionRequests == nil { - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil executionRequests post-prague")) - } - - 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")) + switch { + case params.Withdrawals == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil beaconRoot post-cancun") + case executionRequests == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil executionRequests post-prague") + case !api.checkFork(params.Timestamp, forks.Prague): + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") } requests := convertRequests(executionRequests) + if err := validateRequests(requests); err != nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) + } return api.executeStatelessPayload(params, versionedHashes, beaconRoot, requests, opaqueWitness) } @@ -981,7 +931,7 @@ func (api *ConsensusAPI) executeStatelessPayload(params engine.ExecutableData, v api.lastNewPayloadLock.Unlock() log.Trace("Executing block statelessly", "number", block.Number(), "hash", params.BlockHash) - stateRoot, receiptRoot, err := core.ExecuteStateless(api.eth.BlockChain().Config(), vm.Config{}, block, witness) + stateRoot, receiptRoot, err := core.ExecuteStateless(api.config(), vm.Config{}, block, witness) if err != nil { log.Warn("ExecuteStatelessPayload: execution failed", "err", err) errorMsg := err.Error() @@ -1119,7 +1069,7 @@ func (api *ConsensusAPI) heartbeat() { time.Sleep(beaconUpdateStartupTimeout) // If the network is not yet merged/merging, don't bother continuing. - if api.eth.BlockChain().Config().TerminalTotalDifficulty == nil { + if api.config().TerminalTotalDifficulty == nil { return } @@ -1163,6 +1113,23 @@ func (api *ConsensusAPI) heartbeat() { } } +// config retrieves the chain's fork configuration. +func (api *ConsensusAPI) config() *params.ChainConfig { + return api.eth.BlockChain().Config() +} + +// checkFork returns true if the latest fork at the given timestamp +// is one of the forks provided. +func (api *ConsensusAPI) checkFork(timestamp uint64, forks ...forks.Fork) bool { + latest := api.config().LatestFork(timestamp) + for _, fork := range forks { + if latest == fork { + return true + } + } + return false +} + // ExchangeCapabilities returns the current methods provided by this node. func (api *ConsensusAPI) ExchangeCapabilities([]string) []string { return caps @@ -1288,3 +1255,21 @@ func validateRequests(requests [][]byte) error { } return nil } + +// paramsErr is a helper function for creating an InvalidPayloadAttributes +// Engine API error. +func paramsErr(msg string) error { + return engine.InvalidParams.With(errors.New(msg)) +} + +// attributesErr is a helper function for creating an InvalidPayloadAttributes +// Engine API error. +func attributesErr(msg string) error { + return engine.InvalidPayloadAttributes.With(errors.New(msg)) +} + +// unsupportedForkErr is a helper function for creating an UnsupportedFork +// Engine API error. +func unsupportedForkErr(msg string) error { + return engine.UnsupportedFork.With(errors.New(msg)) +} From 52dbd206bb9ea9b4a1f0f7feaefc5f7828dd4c67 Mon Sep 17 00:00:00 2001 From: maskpp Date: Thu, 15 May 2025 15:32:20 +0800 Subject: [PATCH 363/940] cmd/utils: always record preimages in dev mode (#31821) Fix a todo: force-enable this in --dev mode --------- Co-authored-by: jwasinger --- cmd/utils/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 44363d13f4..a100ee1548 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1712,7 +1712,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } } if ctx.IsSet(VMEnableDebugFlag.Name) { - // TODO(fjl): force-enable this in --dev mode cfg.EnablePreimageRecording = ctx.Bool(VMEnableDebugFlag.Name) } @@ -1761,6 +1760,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { case ctx.Bool(DeveloperFlag.Name): cfg.NetworkId = 1337 cfg.SyncMode = ethconfig.FullSync + cfg.EnablePreimageRecording = true // Create new developer account or reuse existing one var ( developer accounts.Account From 228803c1a29acf93c8cd53a29e477d8801fc60ad Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 15 May 2025 14:17:58 +0200 Subject: [PATCH 364/940] p2p/enode: add support for naming iterator sources (#31779) This adds support for naming the source iterators of FairMix, like so: mix.AddSource(enode.WithSourceName("mySource", iter)) The source that produced the latest node is returned by the new NodeSource method. --- p2p/enode/iter.go | 79 ++++++++++++++++++++++++++++++++---------- p2p/enode/iter_test.go | 48 +++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 18 deletions(-) diff --git a/p2p/enode/iter.go b/p2p/enode/iter.go index b8ab4a758a..4b7e28929e 100644 --- a/p2p/enode/iter.go +++ b/p2p/enode/iter.go @@ -30,6 +30,35 @@ type Iterator interface { Close() // ends the iterator } +// SourceIterator represents a sequence of nodes like [Iterator] +// Each node also has a named 'source'. +type SourceIterator interface { + Iterator + NodeSource() string // source of current node +} + +// WithSource attaches a 'source name' to an iterator. +func WithSourceName(name string, it Iterator) SourceIterator { + return sourceIter{it, name} +} + +func ensureSourceIter(it Iterator) SourceIterator { + if si, ok := it.(SourceIterator); ok { + return si + } + return WithSourceName("", it) +} + +type sourceIter struct { + Iterator + name string +} + +// NodeSource implements IteratorSource. +func (it sourceIter) NodeSource() string { + return it.name +} + // ReadNodes reads at most n nodes from the given iterator. The return value contains no // duplicates and no nil values. To prevent looping indefinitely for small repeating node // sequences, this function calls Next at most n times. @@ -106,16 +135,16 @@ func (it *sliceIter) Close() { // Filter wraps an iterator such that Next only returns nodes for which // the 'check' function returns true. func Filter(it Iterator, check func(*Node) bool) Iterator { - return &filterIter{it, check} + return &filterIter{ensureSourceIter(it), check} } type filterIter struct { - Iterator + SourceIterator check func(*Node) bool } func (f *filterIter) Next() bool { - for f.Iterator.Next() { + for f.SourceIterator.Next() { if f.check(f.Node()) { return true } @@ -135,9 +164,9 @@ func (f *filterIter) Next() bool { // It's safe to call AddSource and Close concurrently with Next. type FairMix struct { wg sync.WaitGroup - fromAny chan *Node + fromAny chan mixItem timeout time.Duration - cur *Node + cur mixItem mu sync.Mutex closed chan struct{} @@ -146,11 +175,16 @@ type FairMix struct { } type mixSource struct { - it Iterator - next chan *Node + it SourceIterator + next chan mixItem timeout time.Duration } +type mixItem struct { + n *Node + source string +} + // NewFairMix creates a mixer. // // The timeout specifies how long the mixer will wait for the next fairly-chosen source @@ -159,7 +193,7 @@ type mixSource struct { // timeout makes the mixer completely fair. func NewFairMix(timeout time.Duration) *FairMix { m := &FairMix{ - fromAny: make(chan *Node), + fromAny: make(chan mixItem), closed: make(chan struct{}), timeout: timeout, } @@ -175,7 +209,11 @@ func (m *FairMix) AddSource(it Iterator) { return } m.wg.Add(1) - source := &mixSource{it, make(chan *Node), m.timeout} + source := &mixSource{ + it: ensureSourceIter(it), + next: make(chan mixItem), + timeout: m.timeout, + } m.sources = append(m.sources, source) go m.runSource(m.closed, source) } @@ -201,7 +239,7 @@ func (m *FairMix) Close() { // Next returns a node from a random source. func (m *FairMix) Next() bool { - m.cur = nil + m.cur = mixItem{} for { source := m.pickSource() @@ -217,12 +255,12 @@ func (m *FairMix) Next() bool { } select { - case n, ok := <-source.next: + case item, ok := <-source.next: if ok { // Here, the timeout is reset to the configured value // because the source delivered a node. source.timeout = m.timeout - m.cur = n + m.cur = item return true } // This source has ended. @@ -239,15 +277,20 @@ func (m *FairMix) Next() bool { // Node returns the current node. func (m *FairMix) Node() *Node { - return m.cur + return m.cur.n +} + +// NodeSource returns the current node's source name. +func (m *FairMix) NodeSource() string { + return m.cur.source } // nextFromAny is used when there are no sources or when the 'fair' choice // doesn't turn up a node quickly enough. func (m *FairMix) nextFromAny() bool { - n, ok := <-m.fromAny + item, ok := <-m.fromAny if ok { - m.cur = n + m.cur = item } return ok } @@ -284,10 +327,10 @@ func (m *FairMix) runSource(closed chan struct{}, s *mixSource) { defer m.wg.Done() defer close(s.next) for s.it.Next() { - n := s.it.Node() + item := mixItem{s.it.Node(), s.it.NodeSource()} select { - case s.next <- n: - case m.fromAny <- n: + case s.next <- item: + case m.fromAny <- item: case <-closed: return } diff --git a/p2p/enode/iter_test.go b/p2p/enode/iter_test.go index b736ed450a..577f9c2825 100644 --- a/p2p/enode/iter_test.go +++ b/p2p/enode/iter_test.go @@ -19,6 +19,7 @@ package enode import ( "encoding/binary" "runtime" + "slices" "sync/atomic" "testing" "time" @@ -183,6 +184,53 @@ func TestFairMixRemoveSource(t *testing.T) { } } +// This checks that FairMix correctly returns the name of the source that produced the node. +func TestFairMixSourceName(t *testing.T) { + nodes := make([]*Node, 6) + for i := range nodes { + nodes[i] = testNode(uint64(i), uint64(i)) + } + mix := NewFairMix(-1) + mix.AddSource(WithSourceName("s1", IterNodes(nodes[0:2]))) + mix.AddSource(WithSourceName("s2", IterNodes(nodes[2:4]))) + mix.AddSource(WithSourceName("s3", IterNodes(nodes[4:6]))) + + var names []string + for range nodes { + mix.Next() + names = append(names, mix.NodeSource()) + } + want := []string{"s2", "s3", "s1", "s2", "s3", "s1"} + if !slices.Equal(names, want) { + t.Fatalf("wrong names: %v", names) + } +} + +// This checks that FairMix returns the name of the source that produced the node, +// even when FairMix instances are nested. +func TestFairMixNestedSourceName(t *testing.T) { + nodes := make([]*Node, 6) + for i := range nodes { + nodes[i] = testNode(uint64(i), uint64(i)) + } + mix := NewFairMix(-1) + mix.AddSource(WithSourceName("s1", IterNodes(nodes[0:2]))) + submix := NewFairMix(-1) + submix.AddSource(WithSourceName("s2", IterNodes(nodes[2:4]))) + submix.AddSource(WithSourceName("s3", IterNodes(nodes[4:6]))) + mix.AddSource(submix) + + var names []string + for range nodes { + mix.Next() + names = append(names, mix.NodeSource()) + } + want := []string{"s3", "s1", "s2", "s1", "s3", "s2"} + if !slices.Equal(names, want) { + t.Fatalf("wrong names: %v", names) + } +} + type blockingIter chan struct{} func (it blockingIter) Next() bool { From af9a3a1a03d5155494a54b7b450333d70641e38a Mon Sep 17 00:00:00 2001 From: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Date: Thu, 15 May 2025 14:43:52 +0200 Subject: [PATCH 365/940] core/state, core/vm: update stateless gas costs to follow the verkle-gen-7 testnet (#31014) Adding values to the witness introduces a new class of issues for computing gas: if there is not enough gas to cover adding an item to the witness, then the item should not be added to the witness. The problem happens when several items are added together, and that process runs out of gas. The witness gas computation needs a way to signal that not enough gas was provided. These values can not be hardcoded, however, as they are context dependent, i.e. two calls to the same function with the same parameters can give two different results. The approach is to return both the gas that was actually consumed, and the gas that was necessary. If the values don't match, then a witness update OOG'd. The caller should then charge the `consumed` value (remaining gas will be 0) and error out. Why not return a boolean instead of the wanted value? Because when several items are touched, we want to distinguish which item lacked gas. --------- Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com> --- core/state/access_events.go | 189 +++++++++++++++++++------------ core/state/access_events_test.go | 33 +++--- core/state_transition.go | 4 +- core/vm/contracts.go | 2 +- core/vm/eips.go | 22 ++-- core/vm/evm.go | 24 ++-- core/vm/gas_table.go | 19 +--- core/vm/interpreter.go | 6 +- core/vm/jump_table.go | 2 +- core/vm/operations_verkle.go | 178 +++++++++++++++++------------ 10 files changed, 276 insertions(+), 203 deletions(-) diff --git a/core/state/access_events.go b/core/state/access_events.go index b745c383b1..0575c9898a 100644 --- a/core/state/access_events.go +++ b/core/state/access_events.go @@ -18,6 +18,7 @@ package state import ( "maps" + gomath "math" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" @@ -92,97 +93,94 @@ func (ae *AccessEvents) Copy() *AccessEvents { // 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) +func (ae *AccessEvents) AddAccount(addr common.Address, isWrite bool, availableGas uint64) uint64 { + var gas uint64 // accumulate the consumed gas + consumed, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, isWrite, availableGas) + if consumed < expected { + return expected + } + gas += consumed + consumed, expected = ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite, availableGas-consumed) + if consumed < expected { + return expected + gas + } + gas += expected 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 +func (ae *AccessEvents) MessageCallGas(destination common.Address, availableGas uint64) uint64 { + _, expected := ae.touchAddressAndChargeGas(destination, zeroTreeIndex, utils.BasicDataLeafKey, false, availableGas) + if expected == 0 { + expected = params.WarmStorageReadCostEIP2929 + } + return expected } // 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 +func (ae *AccessEvents) ValueTransferGas(callerAddr, targetAddr common.Address, availableGas uint64) uint64 { + _, expected1 := ae.touchAddressAndChargeGas(callerAddr, zeroTreeIndex, utils.BasicDataLeafKey, true, availableGas) + if expected1 > availableGas { + return expected1 + } + _, expected2 := ae.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BasicDataLeafKey, true, availableGas-expected1) + if expected1+expected2 == 0 { + return params.WarmStorageReadCostEIP2929 + } + return expected1 + expected2 } // ContractCreatePreCheckGas 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 +func (ae *AccessEvents) ContractCreatePreCheckGas(addr common.Address, availableGas uint64) uint64 { + consumed, expected1 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, false, availableGas) + _, expected2 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, false, availableGas-consumed) + return expected1 + expected2 } // ContractCreateInitGas returns the access gas costs for the initialization of // a contract creation. -func (ae *AccessEvents) ContractCreateInitGas(addr common.Address) uint64 { +func (ae *AccessEvents) ContractCreateInitGas(addr common.Address, availableGas uint64) (uint64, uint64) { var gas uint64 - gas += ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, true) - gas += ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, true) - return gas + consumed, expected1 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, true, availableGas) + gas += consumed + consumed, expected2 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, true, availableGas-consumed) + gas += consumed + return gas, expected1 + expected2 } // 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) + ae.touchAddressAndChargeGas(originAddr, zeroTreeIndex, utils.BasicDataLeafKey, true, gomath.MaxUint64) + ae.touchAddressAndChargeGas(originAddr, zeroTreeIndex, utils.CodeHashLeafKey, false, gomath.MaxUint64) } // 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) +func (ae *AccessEvents) AddTxDestination(addr common.Address, sendsValue, doesntExist bool) { + ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, sendsValue, gomath.MaxUint64) + ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, doesntExist, gomath.MaxUint64) } // 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 { +func (ae *AccessEvents) SlotGas(addr common.Address, slot common.Hash, isWrite bool, availableGas uint64, chargeWarmCosts bool) uint64 { treeIndex, subIndex := utils.StorageIndex(slot.Bytes()) - return ae.touchAddressAndChargeGas(addr, *treeIndex, subIndex, isWrite) + _, expected := ae.touchAddressAndChargeGas(addr, *treeIndex, subIndex, isWrite, availableGas) + if expected == 0 && chargeWarmCosts { + expected = params.WarmStorageReadCostEIP2929 + } + return expected } -// 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) { +// touchAddressAndChargeGas adds any missing access event to the access event list, and returns the +// consumed and required gas. +func (ae *AccessEvents) touchAddressAndChargeGas(addr common.Address, treeIndex uint256.Int, subIndex byte, isWrite bool, availableGas uint64) (uint64, uint64) { branchKey := newBranchAccessKey(addr, treeIndex) chunkKey := newChunkAccessKey(branchKey, subIndex) @@ -190,11 +188,9 @@ func (ae *AccessEvents) touchAddress(addr common.Address, treeIndex uint256.Int, 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. @@ -202,17 +198,51 @@ func (ae *AccessEvents) touchAddress(addr common.Address, treeIndex uint256.Int, 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 + + var gas uint64 + if branchRead { + gas += params.WitnessBranchReadCost + } + if chunkRead { + gas += params.WitnessChunkReadCost + } + if branchWrite { + gas += params.WitnessBranchWriteCost + } + if chunkWrite { + gas += params.WitnessChunkWriteCost + } + if chunkFill { + gas += params.WitnessChunkFillCost + } + + if availableGas < gas { + // consumed != expected + return availableGas, gas + } + + if branchRead { + ae.branches[branchKey] = AccessWitnessReadFlag + } + if branchWrite { + ae.branches[branchKey] |= AccessWitnessWriteFlag + } + if chunkRead { + ae.chunks[chunkKey] = AccessWitnessReadFlag + } + if chunkWrite { + ae.chunks[chunkKey] |= AccessWitnessWriteFlag + } + + // consumed == expected + return gas, gas } type branchAccessKey struct { @@ -240,7 +270,7 @@ func newChunkAccessKey(branchKey branchAccessKey, leafKey byte) chunkAccessKey { } // 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 { +func (ae *AccessEvents) CodeChunksRangeGas(contractAddr common.Address, startPC, size uint64, codeLen uint64, isWrite bool, availableGas uint64) (uint64, 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 @@ -248,7 +278,7 @@ func (ae *AccessEvents) CodeChunksRangeGas(contractAddr common.Address, startPC, // 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 + return 0, 0 } endPC := startPC + size @@ -263,22 +293,34 @@ func (ae *AccessEvents) CodeChunksRangeGas(contractAddr common.Address, startPC, 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) + consumed, expected := ae.touchAddressAndChargeGas(contractAddr, treeIndex, subIndex, isWrite, availableGas) + // did we OOG ? + if expected > consumed { + return statelessGasCharged + consumed, statelessGasCharged + expected + } var overflow bool - statelessGasCharged, overflow = math.SafeAdd(statelessGasCharged, gas) + statelessGasCharged, overflow = math.SafeAdd(statelessGasCharged, consumed) if overflow { panic("overflow when adding gas") } + availableGas -= consumed } - return statelessGasCharged + return statelessGasCharged, 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) +func (ae *AccessEvents) BasicDataGas(addr common.Address, isWrite bool, availableGas uint64, chargeWarmCosts bool) uint64 { + _, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, isWrite, availableGas) + if expected == 0 && chargeWarmCosts { + if availableGas < params.WarmStorageReadCostEIP2929 { + return availableGas + } + expected = params.WarmStorageReadCostEIP2929 + } + return expected } // CodeHashGas adds the account's code hash to the accessed data, and returns the @@ -286,6 +328,13 @@ func (ae *AccessEvents) BasicDataGas(addr common.Address, isWrite bool) uint64 { // 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) +func (ae *AccessEvents) CodeHashGas(addr common.Address, isWrite bool, availableGas uint64, chargeWarmCosts bool) uint64 { + _, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite, availableGas) + if expected == 0 && chargeWarmCosts { + if availableGas < params.WarmStorageReadCostEIP2929 { + return availableGas + } + expected = params.WarmStorageReadCostEIP2929 + } + return expected } diff --git a/core/state/access_events_test.go b/core/state/access_events_test.go index 10630b3181..5e1fee767c 100644 --- a/core/state/access_events_test.go +++ b/core/state/access_events_test.go @@ -17,6 +17,7 @@ package state import ( + "math" "testing" "github.com/ethereum/go-ethereum/common" @@ -40,50 +41,50 @@ func TestAccountHeaderGas(t *testing.T) { ae := NewAccessEvents(utils.NewPointCache(1024)) // Check cold read cost - gas := ae.BasicDataGas(testAddr, false) + gas := ae.BasicDataGas(testAddr, false, math.MaxUint64, 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) + gas = ae.BasicDataGas(testAddr, false, math.MaxUint64, 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) + gas = ae.CodeHashGas(testAddr, false, math.MaxUint64, 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) + gas = ae.BasicDataGas(testAddr, true, math.MaxUint64, false) 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) + gas = ae.BasicDataGas(testAddr, true, math.MaxUint64, false) 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) + gas = ae.BasicDataGas(testAddr2, true, math.MaxUint64, false) 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) + gas = ae.BasicDataGas(testAddr2, false, math.MaxUint64, 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) + gas = ae.SlotGas(testAddr, common.Hash{}, false, math.MaxUint64, false) if gas != params.WitnessChunkReadCost { t.Fatalf("incorrect gas computed, got %d, want %d", gas, params.WitnessChunkReadCost) } @@ -100,13 +101,13 @@ func TestContractCreateInitGas(t *testing.T) { } // Check cold read cost, without a value - gas := ae.ContractCreateInitGas(testAddr) + gas, _ := ae.ContractCreateInitGas(testAddr, math.MaxUint64) 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) + gas, _ = ae.ContractCreateInitGas(testAddr, math.MaxUint64) if gas != 0 { t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) } @@ -118,24 +119,24 @@ func TestMessageCallGas(t *testing.T) { ae := NewAccessEvents(utils.NewPointCache(1024)) // Check cold read cost, without a value - gas := ae.MessageCallGas(testAddr) + gas := ae.MessageCallGas(testAddr, math.MaxUint64) 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) + gas = ae.BasicDataGas(testAddr, false, math.MaxUint64, false) if gas != 0 { t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) } - gas = ae.CodeHashGas(testAddr, false) + gas = ae.CodeHashGas(testAddr, false, math.MaxUint64, 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) + gas = ae.MessageCallGas(testAddr, math.MaxUint64) + if gas != params.WarmStorageReadCostEIP2929 { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, params.WarmStorageReadCostEIP2929) } } diff --git a/core/state_transition.go b/core/state_transition.go index ff2051ddd2..4f172682d0 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -457,7 +457,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { st.evm.AccessEvents.AddTxOrigin(msg.From) if targetAddr := msg.To; targetAddr != nil { - st.evm.AccessEvents.AddTxDestination(*targetAddr, msg.Value.Sign() != 0) + st.evm.AccessEvents.AddTxDestination(*targetAddr, msg.Value.Sign() != 0, !st.state.Exist(*targetAddr)) } } @@ -552,7 +552,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { // 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) + st.evm.AccessEvents.AddAccount(st.evm.Context.Coinbase, true, math.MaxUint64) } } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 06849e65ad..784b410802 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -139,7 +139,7 @@ var PrecompiledContractsPrague = PrecompiledContracts{ var PrecompiledContractsBLS = PrecompiledContractsPrague -var PrecompiledContractsVerkle = PrecompiledContractsPrague +var PrecompiledContractsVerkle = PrecompiledContractsBerlin var ( PrecompiledAddressesPrague []common.Address diff --git a/core/vm/eips.go b/core/vm/eips.go index 6159eade7e..d95fa51284 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -339,12 +339,10 @@ func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC addr := common.Address(a.Bytes20()) code := interpreter.evm.StateDB.GetCode(addr) paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(code, uint64CodeOffset, length.Uint64()) - if !scope.Contract.IsSystemCall { - statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(code)), false) - if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { - scope.Contract.Gas = 0 - return nil, ErrOutOfGas - } + consumed, wanted := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(code)), false, scope.Contract.Gas) + scope.Contract.UseGas(consumed, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) + if consumed < wanted { + return nil, ErrOutOfGas } scope.Memory.Set(memOffset.Uint64(), length.Uint64(), paddedCodeCopy) @@ -367,9 +365,9 @@ func opPush1EIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext // 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 + consumed, wanted := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr, *pc+1, uint64(1), uint64(len(scope.Contract.Code)), false, scope.Contract.Gas) + scope.Contract.UseGas(wanted, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) + if consumed < wanted { return nil, ErrOutOfGas } } @@ -395,9 +393,9 @@ func makePushEIP4762(size uint64, pushByteSize int) executionFunc { if !scope.Contract.IsDeployment && !scope.Contract.IsSystemCall { 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 + consumed, wanted := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr, uint64(start), uint64(pushByteSize), uint64(len(scope.Contract.Code)), false, scope.Contract.Gas) + scope.Contract.UseGas(consumed, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) + if consumed < wanted { return nil, ErrOutOfGas } } diff --git a/core/vm/evm.go b/core/vm/evm.go index ecb0f118ec..b45a434545 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -206,8 +206,14 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g if !evm.StateDB.Exist(addr) { if !isPrecompile && evm.chainRules.IsEIP4762 && !isSystemCall(caller) { - // add proof of absence to witness - wgas := evm.AccessEvents.AddAccount(addr, false) + // Add proof of absence to witness + // At this point, the read costs have already been charged, either because this + // is a direct tx call, in which case it's covered by the intrinsic gas, or because + // of a CALL instruction, in which case BASIC_DATA has been added to the access + // list in write mode. If there is enough gas paying for the addition of the code + // hash leaf to the access list, then account creation will proceed unimpaired. + // Thus, only pay for the creation of the code hash leaf here. + wgas := evm.AccessEvents.CodeHashGas(addr, true, gas, false) if gas < wgas { evm.StateDB.RevertToSnapshot(snapshot) return nil, 0, ErrOutOfGas @@ -433,7 +439,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *ui // Charge the contract creation init gas in verkle mode if evm.chainRules.IsEIP4762 { - statelessGas := evm.AccessEvents.ContractCreatePreCheckGas(address) + statelessGas := evm.AccessEvents.ContractCreatePreCheckGas(address, gas) if statelessGas > gas { return nil, common.Address{}, 0, ErrOutOfGas } @@ -481,14 +487,14 @@ func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *ui } // Charge the contract creation init gas in verkle mode if evm.chainRules.IsEIP4762 { - statelessGas := evm.AccessEvents.ContractCreateInitGas(address) - if statelessGas > gas { + consumed, wanted := evm.AccessEvents.ContractCreateInitGas(address, gas) + if consumed < wanted { 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) + evm.Config.Tracer.OnGasChange(gas, gas-consumed, tracing.GasChangeWitnessContractInit) } - gas = gas - statelessGas + gas = gas - consumed } evm.Context.Transfer(evm.StateDB, caller, address, value) @@ -535,7 +541,9 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b return ret, ErrCodeStoreOutOfGas } } else { - if len(ret) > 0 && !contract.UseGas(evm.AccessEvents.CodeChunksRangeGas(address, 0, uint64(len(ret)), uint64(len(ret)), true), evm.Config.Tracer, tracing.GasChangeWitnessCodeChunk) { + consumed, wanted := evm.AccessEvents.CodeChunksRangeGas(address, 0, uint64(len(ret)), uint64(len(ret)), true, contract.Gas) + contract.UseGas(consumed, evm.Config.Tracer, tracing.GasChangeWitnessCodeChunk) + if len(ret) > 0 && (consumed < wanted) { return ret, ErrCodeStoreOutOfGas } } diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 55855727b5..f711aa4a18 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -394,14 +394,7 @@ 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 && !contract.IsSystemCall { - 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 @@ -428,16 +421,6 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { return 0, ErrGasUintOverflow } - if evm.chainRules.IsEIP4762 && !contract.IsSystemCall { - 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/interpreter.go b/core/vm/interpreter.go index a62c3c843d..d0e5967e6e 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -237,7 +237,11 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // 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) + consumed, wanted := in.evm.TxContext.AccessEvents.CodeChunksRangeGas(contractAddr, pc, 1, uint64(len(contract.Code)), false, contract.Gas) + contract.UseGas(consumed, in.evm.Config.Tracer, tracing.GasChangeWitnessCodeChunk) + if consumed < wanted { + return nil, ErrOutOfGas + } } // Get the operation from the jump table and validate the stack to ensure there are diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index ee811b447e..26b9473fe8 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -87,7 +87,7 @@ func validate(jt JumpTable) JumpTable { } func newVerkleInstructionSet() JumpTable { - instructionSet := newCancunInstructionSet() + instructionSet := newShanghaiInstructionSet() enable4762(&instructionSet) return validate(instructionSet) } diff --git a/core/vm/operations_verkle.go b/core/vm/operations_verkle.go index 751761a911..30f9957775 100644 --- a/core/vm/operations_verkle.go +++ b/core/vm/operations_verkle.go @@ -25,31 +25,16 @@ import ( ) 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 + return evm.AccessEvents.SlotGas(contract.Address(), stack.peek().Bytes32(), true, contract.Gas, true), 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 + return evm.AccessEvents.SlotGas(contract.Address(), stack.peek().Bytes32(), false, contract.Gas, true), nil } func gasBalance4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - if contract.IsSystemCall { - return 0, nil - } address := stack.peek().Bytes20() - gas := evm.AccessEvents.BasicDataGas(address, false) - if gas == 0 { - gas = params.WarmStorageReadCostEIP2929 - } - return gas, nil + return evm.AccessEvents.BasicDataGas(address, false, contract.Gas, true), nil } func gasExtCodeSize4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { @@ -57,56 +42,69 @@ func gasExtCodeSize4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, if _, isPrecompile := evm.precompile(address); isPrecompile { return 0, nil } - if contract.IsSystemCall { - return 0, nil - } - gas := evm.AccessEvents.BasicDataGas(address, false) - if gas == 0 { - gas = params.WarmStorageReadCostEIP2929 - } - return gas, nil + return evm.AccessEvents.BasicDataGas(address, false, contract.Gas, true), nil } func gasExtCodeHash4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - if contract.IsSystemCall { - return 0, nil - } 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 + return evm.AccessEvents.CodeHashGas(address, false, contract.Gas, true), nil } -func makeCallVariantGasEIP4762(oldCalculator gasFunc) gasFunc { +func makeCallVariantGasEIP4762(oldCalculator gasFunc, withTransferCosts bool) 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 contract.IsSystemCall { - return gas, nil - } - if _, isPrecompile := evm.precompile(contract.Address()); isPrecompile { - return gas, nil - } - witnessGas := evm.AccessEvents.MessageCallGas(contract.Address()) - if witnessGas == 0 { + var ( + target = common.Address(stack.Back(1).Bytes20()) + witnessGas uint64 + _, isPrecompile = evm.precompile(target) + isSystemContract = target == params.HistoryStorageAddress + ) + + // If value is transferred, it is charged before 1/64th + // is subtracted from the available gas pool. + if withTransferCosts && !stack.Back(2).IsZero() { + wantedValueTransferWitnessGas := evm.AccessEvents.ValueTransferGas(contract.Address(), target, contract.Gas) + if wantedValueTransferWitnessGas > contract.Gas { + return wantedValueTransferWitnessGas, nil + } + witnessGas = wantedValueTransferWitnessGas + } else if isPrecompile || isSystemContract { witnessGas = params.WarmStorageReadCostEIP2929 + } else { + // The charging for the value transfer is done BEFORE subtracting + // the 1/64th gas, as this is considered part of the CALL instruction. + // (so before we get to this point) + // But the message call is part of the subcall, for which only 63/64th + // of the gas should be available. + wantedMessageCallWitnessGas := evm.AccessEvents.MessageCallGas(target, contract.Gas-witnessGas) + var overflow bool + if witnessGas, overflow = math.SafeAdd(witnessGas, wantedMessageCallWitnessGas); overflow { + return 0, ErrGasUintOverflow + } + if witnessGas > contract.Gas { + return witnessGas, nil + } } - return witnessGas + gas, nil + + contract.Gas -= witnessGas + // if the operation fails, adds witness gas to the gas before returning the error + gas, err := oldCalculator(evm, contract, stack, mem, memorySize) + contract.Gas += witnessGas // restore witness gas so that it can be charged at the callsite + var overflow bool + if gas, overflow = math.SafeAdd(gas, witnessGas); overflow { + return 0, ErrGasUintOverflow + } + return gas, err } } var ( - gasCallEIP4762 = makeCallVariantGasEIP4762(gasCall) - gasCallCodeEIP4762 = makeCallVariantGasEIP4762(gasCallCode) - gasStaticCallEIP4762 = makeCallVariantGasEIP4762(gasStaticCall) - gasDelegateCallEIP4762 = makeCallVariantGasEIP4762(gasDelegateCall) + gasCallEIP4762 = makeCallVariantGasEIP4762(gasCall, true) + gasCallCodeEIP4762 = makeCallVariantGasEIP4762(gasCallCode, false) + gasStaticCallEIP4762 = makeCallVariantGasEIP4762(gasStaticCall, false) + gasDelegateCallEIP4762 = makeCallVariantGasEIP4762(gasDelegateCall, false) ) func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { @@ -118,15 +116,44 @@ func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Mem return 0, nil } contractAddr := contract.Address() - statelessGas := evm.AccessEvents.BasicDataGas(contractAddr, false) + wanted := evm.AccessEvents.BasicDataGas(contractAddr, false, contract.Gas, false) + if wanted > contract.Gas { + return wanted, nil + } + statelessGas := wanted + balanceIsZero := evm.StateDB.GetBalance(contractAddr).Sign() == 0 + _, isPrecompile := evm.precompile(beneficiaryAddr) + isSystemContract := beneficiaryAddr == params.HistoryStorageAddress + + if (isPrecompile || isSystemContract) && balanceIsZero { + return statelessGas, nil + } + if contractAddr != beneficiaryAddr { - statelessGas += evm.AccessEvents.BasicDataGas(beneficiaryAddr, false) + wanted := evm.AccessEvents.BasicDataGas(beneficiaryAddr, false, contract.Gas-statelessGas, false) + if wanted > contract.Gas-statelessGas { + return statelessGas + wanted, nil + } + statelessGas += wanted } // Charge write costs if it transfers value - if evm.StateDB.GetBalance(contractAddr).Sign() != 0 { - statelessGas += evm.AccessEvents.BasicDataGas(contractAddr, true) + if !balanceIsZero { + wanted := evm.AccessEvents.BasicDataGas(contractAddr, true, contract.Gas-statelessGas, false) + if wanted > contract.Gas-statelessGas { + return statelessGas + wanted, nil + } + statelessGas += wanted + if contractAddr != beneficiaryAddr { - statelessGas += evm.AccessEvents.BasicDataGas(beneficiaryAddr, true) + if evm.StateDB.Exist(beneficiaryAddr) { + wanted = evm.AccessEvents.BasicDataGas(beneficiaryAddr, true, contract.Gas-statelessGas, false) + } else { + wanted = evm.AccessEvents.AddAccount(beneficiaryAddr, true, contract.Gas-statelessGas) + } + if wanted > contract.Gas-statelessGas { + return statelessGas + wanted, nil + } + statelessGas += wanted } } return statelessGas, nil @@ -137,17 +164,19 @@ func gasCodeCopyEip4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, if err != nil { return 0, err } - var ( - codeOffset = stack.Back(1) - length = stack.Back(2) - ) - uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() - if overflow { - uint64CodeOffset = gomath.MaxUint64 - } - _, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(contract.Code, uint64CodeOffset, length.Uint64()) if !contract.IsDeployment && !contract.IsSystemCall { - gas += evm.AccessEvents.CodeChunksRangeGas(contract.Address(), copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) + var ( + codeOffset = stack.Back(1) + length = stack.Back(2) + ) + uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() + if overflow { + uint64CodeOffset = gomath.MaxUint64 + } + + _, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(contract.Code, uint64CodeOffset, length.Uint64()) + _, wanted := evm.AccessEvents.CodeChunksRangeGas(contract.Address(), copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false, contract.Gas-gas) + gas += wanted } return gas, nil } @@ -158,16 +187,17 @@ func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memo if err != nil { return 0, err } - if contract.IsSystemCall { + addr := common.Address(stack.peek().Bytes20()) + _, isPrecompile := evm.precompile(addr) + if isPrecompile || addr == params.HistoryStorageAddress { + var overflow bool + if gas, overflow = math.SafeAdd(gas, params.WarmStorageReadCostEIP2929); overflow { + return 0, ErrGasUintOverflow + } return gas, nil } - addr := common.Address(stack.peek().Bytes20()) - wgas := evm.AccessEvents.BasicDataGas(addr, false) - if wgas == 0 { - wgas = params.WarmStorageReadCostEIP2929 - } + wgas := evm.AccessEvents.BasicDataGas(addr, false, contract.Gas-gas, true) 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 } From 85b26f3d6841fb1bc90a77ada7e9cf62988c8cc0 Mon Sep 17 00:00:00 2001 From: Charlotte <69423184+tqpcharlie@users.noreply.github.com> Date: Thu, 15 May 2025 15:55:38 -0400 Subject: [PATCH 366/940] AUTHORS, .mailmap: update name and email attribution (#31624) --- .mailmap | 7 ++++--- AUTHORS | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.mailmap b/.mailmap index 92a9e07748..597da62dc3 100644 --- a/.mailmap +++ b/.mailmap @@ -50,6 +50,10 @@ Boqin Qin Casey Detrio +Charlotte +Charlotte +Charlotte + Cheng Li Chris Ziogas @@ -301,9 +305,6 @@ Yohann Léon yzb <335357057@qq.com> yzb <335357057@qq.com> -Zachinquarantine -Zachinquarantine - Ziyuan Zhong Zsolt Felföldi diff --git a/AUTHORS b/AUTHORS index 1ec240aeb6..da482717c6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -123,6 +123,7 @@ Ceyhun Onur chabashilah changhong Charles Cooper +Charlotte Chase Wright Chawin Aiemvaravutigul Chen Quan @@ -839,7 +840,6 @@ ywzqwwt <39263032+ywzqwwt@users.noreply.github.com> yzb <335357057@qq.com> zaccoding Zach -Zachinquarantine zah Zahoor Mohamed Zak Cole From 3ceec0ea9bd66346071512587cb2bdbd7160e48f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 15 May 2025 22:53:26 +0200 Subject: [PATCH 367/940] cmd/geth, internal/era/eradl: add era1 downloader tool (#31823) This adds a geth subcommand for downloading era1 files and placing them into the correct location. The tool can be used even while geth is already running on the datadir. Downloads are checked against a hard-coded list of checksums for mainnet and sepolia. ``` ./geth download-era --server $SERVER --block 333333 ./geth download-era --server $SERVER --block 333333-444444 ./geth download-era --server $SERVER --epoch 0-10 ./geth download-era --server $SERVER --all ``` The implementation reuses the file downloader we already had for fetching build tools. I've done some refactoring on it to make sure it can support the new use case, and there are some changes to the build here as well. --- build/ci.go | 55 +- cmd/geth/chaincmd.go | 122 +- cmd/geth/main.go | 3 +- internal/build/download.go | 151 -- internal/build/gotool.go | 54 +- internal/download/download.go | 298 ++++ internal/era/eradl/checksums_mainnet.txt | 1897 ++++++++++++++++++++++ internal/era/eradl/checksums_sepolia.txt | 183 +++ internal/era/eradl/eradl.go | 115 ++ 9 files changed, 2642 insertions(+), 236 deletions(-) delete mode 100644 internal/build/download.go create mode 100644 internal/download/download.go create mode 100644 internal/era/eradl/checksums_mainnet.txt create mode 100644 internal/era/eradl/checksums_sepolia.txt create mode 100644 internal/era/eradl/eradl.go diff --git a/build/ci.go b/build/ci.go index b2ff829d3f..88e4e82282 100644 --- a/build/ci.go +++ b/build/ci.go @@ -59,6 +59,7 @@ import ( "github.com/cespare/cp" "github.com/ethereum/go-ethereum/crypto/signify" "github.com/ethereum/go-ethereum/internal/build" + "github.com/ethereum/go-ethereum/internal/download" "github.com/ethereum/go-ethereum/internal/version" ) @@ -190,7 +191,7 @@ func doInstall(cmdline []string) { // Configure the toolchain. tc := build.GoToolchain{GOARCH: *arch, CC: *cc} if *dlgo { - csdb := build.MustLoadChecksums("build/checksums.txt") + csdb := download.MustLoadChecksums("build/checksums.txt") tc.Root = build.DownloadGo(csdb) } // Disable CLI markdown doc generation in release builds. @@ -285,7 +286,7 @@ func doTest(cmdline []string) { flag.CommandLine.Parse(cmdline) // Get test fixtures. - csdb := build.MustLoadChecksums("build/checksums.txt") + csdb := download.MustLoadChecksums("build/checksums.txt") downloadSpecTestFixtures(csdb, *cachedir) // Configure the toolchain. @@ -329,16 +330,11 @@ func doTest(cmdline []string) { } // downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures. -func downloadSpecTestFixtures(csdb *build.ChecksumDB, cachedir string) string { - executionSpecTestsVersion, err := build.Version(csdb, "spec-tests") - if err != nil { - log.Fatal(err) - } +func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string { ext := ".tar.gz" base := "fixtures_pectra-devnet-6" // TODO(s1na) rename once the version becomes part of the filename - url := fmt.Sprintf("https://github.com/ethereum/execution-spec-tests/releases/download/%s/%s%s", executionSpecTestsVersion, base, ext) archivePath := filepath.Join(cachedir, base+ext) - if err := csdb.DownloadFile(url, archivePath); err != nil { + if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil { log.Fatal(err) } if err := build.ExtractArchive(archivePath, executionSpecTestsDir); err != nil { @@ -444,14 +440,13 @@ func doLint(cmdline []string) { // downloadLinter downloads and unpacks golangci-lint. func downloadLinter(cachedir string) string { - csdb := build.MustLoadChecksums("build/checksums.txt") - version, err := build.Version(csdb, "golangci") + csdb := download.MustLoadChecksums("build/checksums.txt") + version, err := csdb.FindVersion("golangci") if err != nil { log.Fatal(err) } arch := runtime.GOARCH ext := ".tar.gz" - if runtime.GOOS == "windows" { ext = ".zip" } @@ -459,9 +454,8 @@ func downloadLinter(cachedir string) string { arch += "v" + os.Getenv("GOARM") } base := fmt.Sprintf("golangci-lint-%s-%s-%s", version, runtime.GOOS, arch) - url := fmt.Sprintf("https://github.com/golangci/golangci-lint/releases/download/v%s/%s%s", version, base, ext) archivePath := filepath.Join(cachedir, base+ext) - if err := csdb.DownloadFile(url, archivePath); err != nil { + if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil { log.Fatal(err) } if err := build.ExtractArchive(archivePath, cachedir); err != nil { @@ -497,8 +491,8 @@ func protocArchiveBaseName() (string, error) { // 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") + csdb := download.MustLoadChecksums("build/checksums.txt") + version, err := csdb.FindVersion("protoc-gen-go") if err != nil { log.Fatal(err) } @@ -510,10 +504,8 @@ func downloadProtocGenGo(cachedir string) string { 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 { + if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil { log.Fatal(err) } extractDest := filepath.Join(cachedir, baseName) @@ -531,8 +523,8 @@ func downloadProtocGenGo(cachedir string) string { // 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") + csdb := download.MustLoadChecksums("build/checksums.txt") + version, err := csdb.FindVersion("protoc") if err != nil { log.Fatal(err) } @@ -543,10 +535,8 @@ func downloadProtoc(cachedir string) string { 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 { + if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil { log.Fatal(err) } extractDest := filepath.Join(cachedir, fileName) @@ -826,18 +816,17 @@ func doDebianSource(cmdline []string) { // downloadGoBootstrapSources downloads the Go source tarball(s) that will be used // to bootstrap the builder Go. func downloadGoBootstrapSources(cachedir string) []string { - csdb := build.MustLoadChecksums("build/checksums.txt") + csdb := download.MustLoadChecksums("build/checksums.txt") var bundles []string for _, booter := range []string{"ppa-builder-1.19", "ppa-builder-1.21", "ppa-builder-1.23"} { - gobootVersion, err := build.Version(csdb, booter) + gobootVersion, err := csdb.FindVersion(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 { + if err := csdb.DownloadFileFromKnownURL(dst); err != nil { log.Fatal(err) } bundles = append(bundles, dst) @@ -847,15 +836,14 @@ func downloadGoBootstrapSources(cachedir string) []string { // downloadGoSources downloads the Go source tarball. func downloadGoSources(cachedir string) string { - csdb := build.MustLoadChecksums("build/checksums.txt") - dlgoVersion, err := build.Version(csdb, "golang") + csdb := download.MustLoadChecksums("build/checksums.txt") + dlgoVersion, err := csdb.FindVersion("golang") if err != nil { log.Fatal(err) } file := fmt.Sprintf("go%s.src.tar.gz", dlgoVersion) - url := "https://dl.google.com/go/" + file dst := filepath.Join(cachedir, file) - if err := csdb.DownloadFile(url, dst); err != nil { + if err := csdb.DownloadFileFromKnownURL(dst); err != nil { log.Fatal(err) } return dst @@ -1181,5 +1169,6 @@ func doPurge(cmdline []string) { } func doSanityCheck() { - build.DownloadAndVerifyChecksums(build.MustLoadChecksums("build/checksums.txt")) + csdb := download.MustLoadChecksums("build/checksums.txt") + csdb.DownloadAndVerifyAll() } diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index a947f35f2f..dc071725c1 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -21,9 +21,12 @@ import ( "errors" "fmt" "os" + "path/filepath" + "regexp" "runtime" "slices" "strconv" + "strings" "sync/atomic" "time" @@ -39,6 +42,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/internal/era" + "github.com/ethereum/go-ethereum/internal/era/eradl" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -190,7 +194,7 @@ This command dumps out the state for a given block (or latest, if none provided) `, } - pruneCommand = &cli.Command{ + pruneHistoryCommand = &cli.Command{ Action: pruneHistory, Name: "prune-history", Usage: "Prune blockchain history (block bodies and receipts) up to the merge block", @@ -201,6 +205,42 @@ The prune-history command removes historical block bodies and receipts from the blockchain database up to the merge block, while preserving block headers. This helps reduce storage requirements for nodes that don't need full historical data.`, } + + downloadEraCommand = &cli.Command{ + Action: downloadEra, + Name: "download-era", + Usage: "Fetches era1 files (pre-merge history) from an HTTP endpoint", + ArgsUsage: "", + Flags: slices.Concat( + utils.DatabaseFlags, + utils.NetworkFlags, + []cli.Flag{ + eraBlockFlag, + eraEpochFlag, + eraAllFlag, + eraServerFlag, + }, + ), + } +) + +var ( + eraBlockFlag = &cli.StringFlag{ + Name: "block", + Usage: "Block number to fetch. (can also be a range -)", + } + eraEpochFlag = &cli.StringFlag{ + Name: "epoch", + Usage: "Epoch number to fetch (can also be a range -)", + } + eraAllFlag = &cli.BoolFlag{ + Name: "all", + Usage: "Download all available era1 files", + } + eraServerFlag = &cli.StringFlag{ + Name: "server", + Usage: "era1 server URL", + } ) // initGenesis will initialise the given JSON format genesis file and writes it as @@ -665,3 +705,83 @@ func pruneHistory(ctx *cli.Context) error { return nil } + +// downladEra is the era1 file downloader tool. +func downloadEra(ctx *cli.Context) error { + flags.CheckExclusive(ctx, eraBlockFlag, eraEpochFlag, eraAllFlag) + + // Resolve the network. + var network = "mainnet" + if utils.IsNetworkPreset(ctx) { + switch { + case ctx.IsSet(utils.MainnetFlag.Name): + case ctx.IsSet(utils.SepoliaFlag.Name): + network = "sepolia" + default: + return fmt.Errorf("unsupported network, no known era1 checksums") + } + } + + // Resolve the destination directory. + stack, _ := makeConfigNode(ctx) + defer stack.Close() + ancients := stack.ResolveAncient("chaindata", "") + dir := filepath.Join(ancients, "era") + + baseURL := ctx.String(eraServerFlag.Name) + if baseURL == "" { + return fmt.Errorf("need --%s flag to download", eraServerFlag.Name) + } + + l, err := eradl.New(baseURL, network) + if err != nil { + return err + } + switch { + case ctx.IsSet(eraAllFlag.Name): + return l.DownloadAll(dir) + + case ctx.IsSet(eraBlockFlag.Name): + s := ctx.String(eraBlockFlag.Name) + start, end, ok := parseRange(s) + if !ok { + return fmt.Errorf("invalid block range: %q", s) + } + return l.DownloadBlockRange(start, end, dir) + + case ctx.IsSet(eraEpochFlag.Name): + s := ctx.String(eraEpochFlag.Name) + start, end, ok := parseRange(s) + if !ok { + return fmt.Errorf("invalid epoch range: %q", s) + } + return l.DownloadEpochRange(start, end, dir) + + default: + return fmt.Errorf("specify one of --%s, --%s, or --%s to download", eraAllFlag.Name, eraBlockFlag.Name, eraEpochFlag.Name) + } +} + +func parseRange(s string) (start uint64, end uint64, ok bool) { + if m, _ := regexp.MatchString("[0-9]+", s); m { + start, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return 0, 0, false + } + end = start + return start, end, true + } + if m, _ := regexp.MatchString("[0-9]+-[0-9]+", s); m { + s1, s2, _ := strings.Cut(s, "-") + start, err := strconv.ParseUint(s1, 10, 64) + if err != nil { + return 0, 0, false + } + end, err = strconv.ParseUint(s2, 10, 64) + if err != nil { + return 0, 0, false + } + return start, end, true + } + return 0, 0, false +} diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 289030ae65..bdff96e369 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -225,7 +225,8 @@ func init() { removedbCommand, dumpCommand, dumpGenesisCommand, - pruneCommand, + pruneHistoryCommand, + downloadEraCommand, // See accountcmd.go: accountCommand, walletCommand, diff --git a/internal/build/download.go b/internal/build/download.go deleted file mode 100644 index 50268227a5..0000000000 --- a/internal/build/download.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2019 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 build - -import ( - "bufio" - "crypto/sha256" - "encoding/hex" - "fmt" - "io" - "log" - "net/http" - "os" - "path/filepath" - "strings" -) - -// ChecksumDB keeps file checksums. -type ChecksumDB struct { - allChecksums []string -} - -// MustLoadChecksums loads a file containing checksums. -func MustLoadChecksums(file string) *ChecksumDB { - content, err := os.ReadFile(file) - if err != nil { - log.Fatal("can't load checksum file: " + err.Error()) - } - return &ChecksumDB{strings.Split(strings.ReplaceAll(string(content), "\r\n", "\n"), "\n")} -} - -// Verify checks whether the given file is valid according to the checksum database. -func (db *ChecksumDB) Verify(path string) error { - fd, err := os.Open(path) - if err != nil { - return err - } - defer fd.Close() - - h := sha256.New() - if _, err := io.Copy(h, bufio.NewReader(fd)); err != nil { - return err - } - fileHash := hex.EncodeToString(h.Sum(nil)) - if !db.findHash(filepath.Base(path), fileHash) { - return fmt.Errorf("invalid file hash: %s %s", fileHash, filepath.Base(path)) - } - return nil -} - -func (db *ChecksumDB) findHash(basename, hash string) bool { - want := hash + " " + basename - for _, line := range db.allChecksums { - if strings.TrimSpace(line) == want { - return true - } - } - return false -} - -// DownloadFile downloads a file and verifies its checksum. -func (db *ChecksumDB) DownloadFile(url, dstPath string) error { - if err := db.Verify(dstPath); err == nil { - fmt.Printf("%s is up-to-date\n", dstPath) - return nil - } - fmt.Printf("%s is stale\n", dstPath) - fmt.Printf("downloading from %s\n", url) - - resp, err := http.Get(url) - if err != nil { - return fmt.Errorf("download error: %v", err) - } - 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 - } - fd, err := os.OpenFile(dstPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) - if err != nil { - return err - } - dst := newDownloadWriter(fd, resp.ContentLength) - _, err = io.Copy(dst, resp.Body) - dst.Close() - if err != nil { - return err - } - return db.Verify(dstPath) -} - -type downloadWriter struct { - file *os.File - dstBuf *bufio.Writer - size int64 - written int64 - lastpct int64 -} - -func newDownloadWriter(dst *os.File, size int64) *downloadWriter { - return &downloadWriter{ - file: dst, - dstBuf: bufio.NewWriter(dst), - size: size, - } -} - -func (w *downloadWriter) Write(buf []byte) (int, error) { - n, err := w.dstBuf.Write(buf) - - // Report progress. - w.written += int64(n) - pct := w.written * 10 / w.size * 10 - if pct != w.lastpct { - if w.lastpct != 0 { - fmt.Print("...") - } - fmt.Print(pct, "%") - w.lastpct = pct - } - return n, err -} - -func (w *downloadWriter) Close() error { - if w.lastpct > 0 { - fmt.Println() // Finish the progress line. - } - flushErr := w.dstBuf.Flush() - closeErr := w.file.Close() - if flushErr != nil { - return flushErr - } - return closeErr -} diff --git a/internal/build/gotool.go b/internal/build/gotool.go index 2a47460418..172fa13464 100644 --- a/internal/build/gotool.go +++ b/internal/build/gotool.go @@ -24,6 +24,8 @@ import ( "path/filepath" "runtime" "strings" + + "github.com/ethereum/go-ethereum/internal/download" ) type GoToolchain struct { @@ -84,8 +86,8 @@ func (g *GoToolchain) goTool(command string, args ...string) *exec.Cmd { // DownloadGo downloads the Go binary distribution and unpacks it into a temporary // directory. It returns the GOROOT of the unpacked toolchain. -func DownloadGo(csdb *ChecksumDB) string { - version, err := Version(csdb, "golang") +func DownloadGo(csdb *download.ChecksumDB) string { + version, err := csdb.FindVersion("golang") if err != nil { log.Fatal(err) } @@ -130,51 +132,3 @@ func DownloadGo(csdb *ChecksumDB) string { } return goroot } - -// Version returns the versions defined in the checksumdb. -func Version(csdb *ChecksumDB, version string) (string, error) { - for _, l := range csdb.allChecksums { - if !strings.HasPrefix(l, "# version:") { - continue - } - v := strings.Split(l, ":")[1] - parts := strings.Split(v, " ") - if len(parts) != 2 { - log.Print("Erroneous version-string", "v", l) - continue - } - if parts[0] == version { - return parts[1], nil - } - } - return "", fmt.Errorf("no version found for '%v'", version) -} - -// DownloadAndVerifyChecksums downloads all files and checks that they match -// the checksum given in checksums.txt. -// This task can be used to sanity-check new checksums. -func DownloadAndVerifyChecksums(csdb *ChecksumDB) { - var ( - base = "" - ucache = os.TempDir() - ) - for _, l := range csdb.allChecksums { - if strings.HasPrefix(l, "# https://") { - base = l[2:] - continue - } - if strings.HasPrefix(l, "#") { - continue - } - hashFile := strings.Split(l, " ") - if len(hashFile) != 2 { - continue - } - file := hashFile[1] - url := base + file - dst := filepath.Join(ucache, file) - if err := csdb.DownloadFile(url, dst); err != nil { - log.Print(err) - } - } -} diff --git a/internal/download/download.go b/internal/download/download.go new file mode 100644 index 0000000000..26c7795ce5 --- /dev/null +++ b/internal/download/download.go @@ -0,0 +1,298 @@ +// Copyright 2019 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 download implements checksum-verified file downloads. +package download + +import ( + "bufio" + "bytes" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "iter" + "net/http" + "net/url" + "os" + "path/filepath" + "strings" +) + +// ChecksumDB keeps file checksums and tool versions. +type ChecksumDB struct { + hashes []hashEntry + versions []versionEntry +} + +type versionEntry struct { + name string + version string +} + +type hashEntry struct { + hash string + file string + url *url.URL +} + +// MustLoadChecksums loads a file containing checksums. +func MustLoadChecksums(file string) *ChecksumDB { + content, err := os.ReadFile(file) + if err != nil { + panic("can't load checksum file: " + err.Error()) + } + db, err := ParseChecksums(content) + if err != nil { + panic(fmt.Sprintf("invalid checksums in %s: %v", file, err)) + } + return db +} + +// ParseChecksums parses a checksum database. +func ParseChecksums(input []byte) (*ChecksumDB, error) { + var ( + csdb = new(ChecksumDB) + rd = bytes.NewBuffer(input) + lastURL *url.URL + ) + for lineNum := 1; ; lineNum++ { + line, err := rd.ReadString('\n') + if err == io.EOF { + break + } + line = strings.TrimSpace(line) + switch { + case line == "": + // Blank lines are allowed, and they reset the current urlEntry. + lastURL = nil + + case strings.HasPrefix(line, "#"): + // It's a comment. Some comments have special meaning. + content := strings.TrimLeft(line, "# ") + switch { + case strings.HasPrefix(content, "version:"): + // Version comments define the version of a tool. + v := strings.Split(content, ":")[1] + parts := strings.Split(v, " ") + if len(parts) != 2 { + return nil, fmt.Errorf("line %d: invalid version string: %q", lineNum, v) + } + csdb.versions = append(csdb.versions, versionEntry{parts[0], parts[1]}) + + case strings.HasPrefix(content, "https://") || strings.HasPrefix(content, "http://"): + // URL comments define the URL where the following files are found. Here + // we keep track of the last found urlEntry and attach it to each file later. + u, err := url.Parse(content) + if err != nil { + return nil, fmt.Errorf("line %d: invalid URL: %v", lineNum, err) + } + lastURL = u + } + + default: + // It's a file hash entry. + fields := strings.Fields(line) + if len(fields) != 2 { + return nil, fmt.Errorf("line %d: invalid number of space-separated fields (%d)", lineNum, len(fields)) + } + csdb.hashes = append(csdb.hashes, hashEntry{fields[0], fields[1], lastURL}) + } + } + return csdb, nil +} + +// Files returns an iterator over all file names. +func (db *ChecksumDB) Files() iter.Seq[string] { + return func(yield func(string) bool) { + for _, e := range db.hashes { + if !yield(e.file) { + return + } + } + } +} + +// DownloadAndVerifyAll downloads all files and checks that they match the checksum given in +// the database. This task can be used to sanity-check new checksums. +func (db *ChecksumDB) DownloadAndVerifyAll() { + var tmp = os.TempDir() + for _, e := range db.hashes { + if e.url == nil { + fmt.Printf("Skipping verification of %s: no URL defined in checksum database", e.file) + continue + } + url := e.url.JoinPath(e.file).String() + dst := filepath.Join(tmp, e.file) + if err := db.DownloadFile(url, dst); err != nil { + fmt.Println("error:", err) + } + } +} + +// verifyHash checks that the file at 'path' has the expected hash. +func verifyHash(path, expectedHash string) error { + fd, err := os.Open(path) + if err != nil { + return err + } + defer fd.Close() + + h := sha256.New() + if _, err := io.Copy(h, bufio.NewReader(fd)); err != nil { + return err + } + fileHash := hex.EncodeToString(h.Sum(nil)) + if fileHash != expectedHash { + return fmt.Errorf("invalid file hash: %s %s", fileHash, filepath.Base(path)) + } + return nil +} + +// DownloadFileFromKnownURL downloads a file from the URL defined in the checksum database. +func (db *ChecksumDB) DownloadFileFromKnownURL(dstPath string) error { + base := filepath.Base(dstPath) + url, err := db.FindURL(base) + if err != nil { + return err + } + return db.DownloadFile(url, dstPath) +} + +// DownloadFile downloads a file and verifies its checksum. +func (db *ChecksumDB) DownloadFile(url, dstPath string) error { + basename := filepath.Base(dstPath) + hash := db.findHash(basename) + if hash == "" { + return fmt.Errorf("no known hash for file %q", basename) + } + // Shortcut if already downloaded. + if verifyHash(dstPath, hash) == nil { + fmt.Printf("%s is up-to-date\n", dstPath) + return nil + } + + fmt.Printf("%s is stale\n", dstPath) + fmt.Printf("downloading from %s\n", url) + resp, err := http.Get(url) + if err != nil { + return fmt.Errorf("download error: %v", err) + } + 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 + } + + // Download to a temporary file. + tmpfile := dstPath + ".tmp" + fd, err := os.OpenFile(tmpfile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) + if err != nil { + return err + } + dst := newDownloadWriter(fd, resp.ContentLength) + _, err = io.Copy(dst, resp.Body) + dst.Close() + if err != nil { + os.Remove(tmpfile) + return err + } + if err := verifyHash(tmpfile, hash); err != nil { + os.Remove(tmpfile) + return err + } + // It's valid, rename to dstPath to complete the download. + return os.Rename(tmpfile, dstPath) +} + +// findHash returns the known hash of a file. +func (db *ChecksumDB) findHash(basename string) string { + for _, e := range db.hashes { + if e.file == basename { + return e.hash + } + } + return "" +} + +// FindVersion returns the current known version of a tool, if it is defined in the file. +func (db *ChecksumDB) FindVersion(tool string) (string, error) { + for _, e := range db.versions { + if e.name == tool { + return e.version, nil + } + } + return "", fmt.Errorf("tool version %q not defined in checksum database", tool) +} + +// FindURL gets the URL for a file. +func (db *ChecksumDB) FindURL(basename string) (string, error) { + for _, e := range db.hashes { + if e.file == basename { + if e.url == nil { + return "", fmt.Errorf("file %q has no URL defined", e.file) + } + return e.url.JoinPath(e.file).String(), nil + } + } + return "", fmt.Errorf("file %q does not exist in checksum database", basename) +} + +type downloadWriter struct { + file *os.File + dstBuf *bufio.Writer + size int64 + written int64 + lastpct int64 +} + +func newDownloadWriter(dst *os.File, size int64) *downloadWriter { + return &downloadWriter{ + file: dst, + dstBuf: bufio.NewWriter(dst), + size: size, + } +} + +func (w *downloadWriter) Write(buf []byte) (int, error) { + n, err := w.dstBuf.Write(buf) + + // Report progress. + w.written += int64(n) + pct := w.written * 10 / w.size * 10 + if pct != w.lastpct { + if w.lastpct != 0 { + fmt.Print("...") + } + fmt.Print(pct, "%") + w.lastpct = pct + } + return n, err +} + +func (w *downloadWriter) Close() error { + if w.lastpct > 0 { + fmt.Println() // Finish the progress line. + } + flushErr := w.dstBuf.Flush() + closeErr := w.file.Close() + if flushErr != nil { + return flushErr + } + return closeErr +} diff --git a/internal/era/eradl/checksums_mainnet.txt b/internal/era/eradl/checksums_mainnet.txt new file mode 100644 index 0000000000..76915fc03c --- /dev/null +++ b/internal/era/eradl/checksums_mainnet.txt @@ -0,0 +1,1897 @@ +9c3f42e0247d5503533f437ada2d44e7e9661170421c1b7844687c8dcfc0eb9b mainnet-00000-5ec1ffb8.era1 +8a8337dbb190b27dd547827db62aed42fe9ef0ab323b6895191d48bc7c6a7127 mainnet-00001-a5364e9a.era1 +7da7be2b4b2f6d8ab8543b709928b71d5f3dfac080f82a94b7d07ee7f2adef43 mainnet-00002-98cbd8a9.era1 +8ca41709b2306a978f00e608f601741011b543c9d8426493c8f4d3d0939a14cc mainnet-00003-d8b8a40b.era1 +b73ad13560e80b13457497a2267e060c02a5ec4ddd92c8d3fa81954b250f7aef mainnet-00004-6e3baba7.era1 +11207a3fc5c0b392f296dfd6450813e9e994e71fbfe3076a7e050016fc617ef0 mainnet-00005-5cff5a4b.era1 +d0281e7b848e69f53333f1cdff1841f101d846605fa82df6e849a3b2ddeb8354 mainnet-00006-678fb793.era1 +8f38a986ac5bde04fba3f9cb1ab2b6b4053368e9051a8a19592f8785feefa01d mainnet-00007-d9bc682b.era1 +0ce07c95e68c29c3b92bba2025df6304bbe021d010e94fd47c5a8d67b519e235 mainnet-00008-12c9605f.era1 +3b0bebbf6e316dc61ee8eb61d36abb5b09a954267ed3fa86be4e8ea91585bc49 mainnet-00009-f9e4e890.era1 +9409cebf51c92bbdd4069908d419c30798efb61d88632d45dfac9509622e39b2 mainnet-00010-5f5d4516.era1 +6914841419be9ed0e35c2dc733d43d199d6ed592ffddc7f07c6b471bc8941e75 mainnet-00011-30f04eb9.era1 +3efbba460c6164593325d8d66b09b537f3682d93cf5a6591b34f1dad09c995e9 mainnet-00012-5ecb9bf9.era1 +469791afa1fbbc7e7e60948fa151908269c16584f3ff5bd046d94efba48b85ce mainnet-00013-d0175c1e.era1 +ccf29e712848407724b8a9b3df855bf9e8c0f44989bfce045261cdab82322917 mainnet-00014-4f92d781.era1 +866c17d2d4d590502f48b8e35a6335b56a4c6bfce8a4df2d18b0e8c6950522eb mainnet-00015-a47cb8eb.era1 +f340e23bb565d6e42d9c5c345b654dd281d696556dcdf2de36803c12bde59e48 mainnet-00016-9344d8b7.era1 +399adffc4bc8e72883018475d05c4f1ded482c1940ac5fdd57fe285a3c09c1c7 mainnet-00017-43963724.era1 +0acaa325a1115fb6cce6a96a47c5e9aa082ae2447962f2c371329aaaf577edd9 mainnet-00018-efce27b4.era1 +ae332ca6f2b9c6725280dba003445c3b7f0e7dd49a6e2e9588787457ba621b14 mainnet-00019-f5434352.era1 +ccb29a81758de7da262c4b5d42c902989cb00f27df3515dae247b831d2ebbc3b mainnet-00020-0c405203.era1 +0aec5d0f99f567ca4b1ca370bf02142b5552ff4845d8ac3a502308f49facac04 mainnet-00021-20d8f1af.era1 +e7f0f1567c1ac9c600753f24df65372150bc3cb4773bd673a69db7b0a2fa2ec5 mainnet-00022-b694d895.era1 +361c0b9d23d7befd5d1924c166f0ec0b40072c57c9b02cb4f764a4815473df6e mainnet-00023-11beacba.era1 +eb484d168d8d60b5249c9ec8fd270049bfe55d0775fdd1d9176dff1e0c062211 mainnet-00024-f216a28a.era1 +dcf2c651a68085006ea26f8b06f9038c6c4b0b8dc69683aea4fd72fdd32155ee mainnet-00025-987cb620.era1 +dfdcc53b9a99aae72aaa023b0a633f0b3d88fe5ed2beb445ba24e21a60c2c448 mainnet-00026-3afd50ff.era1 +9a2004c5d9c4040bcc5009e04a3ebfacc764773aad2ad3e009c67ede76c916cc mainnet-00027-28083285.era1 +821a1978eb350a7529d4ff62e81c2b5fc87c65b93bf9bf9640503d4d3a4e7abe mainnet-00028-362fc97c.era1 +11537dbc309b94b2c4b18c2ed6b9d0aeb79cb7f2bf792ea10e766dd3f7986bda mainnet-00029-a0cb99e2.era1 +c86c2efb18098961533aa58ca13ee39af4d4204767efe5cc593285e33b011c45 mainnet-00030-78fc5e8e.era1 +f6947b30494defb10b72e014b0192dc1dfadfdbc6cf740c59525fd76c8447b3d mainnet-00031-52306cf9.era1 +0dcecd1909ba393e6fb0905707fc1922d776d891d4bdc978a3cd1f9eb1818703 mainnet-00032-cb4d0c3a.era1 +fd1194994e0b3ed22d7c1809a2bd5233fee92b9f01684bca2f134b0a1c27e47a mainnet-00033-0c3781bb.era1 +afcfdca6fb1e7691ce9fd5d8b3f09c5105da96882ea9ba1c5e188964d40243c8 mainnet-00034-fac9315a.era1 +e46841bca92299fba6aa326f000a4384537ba481667149ca0846118ae6436c21 mainnet-00035-737e0757.era1 +bd6913818cface9f9bcffb0869a5edb290b9f760fc9931f0ac67eb7fdbc4da4f mainnet-00036-84c7c1e7.era1 +a2b34158951ecde2c770d5d488e3d1264d40b9090b2fe7a77feb5b79d65fe7d8 mainnet-00037-34d06765.era1 +98b8f1dab9c615c1b98f7b39f48da29c1352b4df8bba36d03f306b11899b1edd mainnet-00038-38aaf94c.era1 +8dff95e9cbd3df32923de8ba6c30efd467c18c4eb84c133974ae06d8890356e7 mainnet-00039-4ad4940c.era1 +20e59943d0d807fadf05f755be3f11c296dff160e72e714de7c09a5d1cb24c1d mainnet-00040-4707f60d.era1 +8d2826f8cb0da37875b245898dac35a69d6cca7c59763058f4a3efb02943791b mainnet-00041-a6a87a9e.era1 +95480ed8ca2d8669f0c359fbc4095b3e1181b7335f2232d4e19b3be21241d6c9 mainnet-00042-5c8dca3c.era1 +6b7450b614e063acc97aaf35ed92a8a89f14cb2d1abec4489be2106122dfb89f mainnet-00043-cb513d91.era1 +5f97400722b684df94affe98e34822a63c4b1469482be6f013810ce1fee9778a mainnet-00044-1c72a390.era1 +077c7a17334e560638d42a8eb3b985312f20a2130a344567af98798c498b27b5 mainnet-00045-a87afdc1.era1 +e7acc9e2f16b438ec8d0f4f897e597557613793c3184bab75456aac00adf401d mainnet-00046-22b3f78d.era1 +41731bb360547c1f7a0f51058f0597f8ed47a80daadcc87dc1b7fe3e51529934 mainnet-00047-92d84372.era1 +9cd84bd46d099a9c752f7f9eea3b40cbedd0429f60427b393467b9670b1a31d0 mainnet-00048-78ae53ed.era1 +97f459559429fd0fe8e2a53c069e419c48168ecfc3ca28defc2df4b3008e3735 mainnet-00049-3934e960.era1 +cf85c4454b9c01575a6e32c1b8892777fda66dce0c88276a0b6b6d57d5e953e1 mainnet-00050-71698ebf.era1 +8d868be1bfd9be49bbb4ee934ba6fcd4061d36ce288f52c2841868e98f8e7299 mainnet-00051-2c1c7778.era1 +1f2580df1e484cf4c7de668f36db08c57d5b59ac68757bdebec689a9aa3ff314 mainnet-00052-3a047d9a.era1 +09c39d3ed18b7222ebae1dd5744b2c197a0b8bfb6fecc2f885dddd44d3568c51 mainnet-00053-161ee1b5.era1 +3b6eb0744531dc25bd9423793f119aff7a4e9abb156e44a7959f761f6cd0b52b mainnet-00054-14074ce7.era1 +5e0f959ec3cf8437bef4a9143871350a44028597626d8089342dbc17189c2d2f mainnet-00055-ae639ad8.era1 +752eb0640af043828bcf854b85d05d158e7ca3687c87c1fbbe11545f5da0f47f mainnet-00056-d92c394c.era1 +1af48939e98749aee96a9fbf91b0f33df71f885e36b04bff3b188510cddb880d mainnet-00057-4bbe776e.era1 +b3a272aca377aa55f80c1dbffb612663ab396edc96515aea426650a04b9829d7 mainnet-00058-9ac60ed8.era1 +d9060a7daa173b9fc2e15cb6aff5c09f18ddf817d7ed85e1430de23a997858fe mainnet-00059-246c1b33.era1 +38b4cf15925460bfb4f26a6615ecf44eb8196178e43906c051531a34c18503ff mainnet-00060-4533d0c5.era1 +ee2f48f124bdee13de49f655e939bea610d8567ab1ed4db955e7bd0e64abaa37 mainnet-00061-122db1c2.era1 +ef4649a54302ab73f8d0db0a0f02d7adfb329da1e4b1149a136532411fbb2fc1 mainnet-00062-65505079.era1 +240f3248e2cdd82ab945709755536f245c915c0006cdad5a1ee0ccec7ea34f25 mainnet-00063-39b21911.era1 +36635126cfe521a3f3d1b3ac845ae3ad9fb492df8698a542c9d308d70f4a90ae mainnet-00064-db26a83c.era1 +acbd243e23502b01ff099d707d94b9d0056e7269265c63d19fb927f875be303b mainnet-00065-1df3a40f.era1 +d11eb990957f6c356a90ad5f2ca7bc476b4e623af20acdacbd0957f9e0ebf23e mainnet-00066-07bde22d.era1 +f66d3833b3724f6c15822ab00c60424e301f523693034c637898187daff42f76 mainnet-00067-751bac83.era1 +dc9359481ac2399643c1cfb337016ab1dd14acbe8e69138f29147eded6088a4e mainnet-00068-546a10c1.era1 +842bd952c402efeffdbeaeb592addd80dbac69e409be25f2f0de673beb574c3a mainnet-00069-55c236ed.era1 +69358acd86be8eb1bc8fc5f8d2d09a8ba95bfd44240b63999b342cab63b54bc9 mainnet-00070-0ac3ebb1.era1 +661cc154b17b16fe01c99bb533bc5480c548fdf5d739504ec1470615ec2577ce mainnet-00071-2fb03713.era1 +9c9377c654f4e8c88da31b31247e04e179b06915594b6d7cb24d14aa943885ed mainnet-00072-2f9a4a75.era1 +ee3a628de9e60f3183c61261e42e1723430d42a06b07ef8101a8726b1980ddf9 mainnet-00073-32871a43.era1 +e3bd37549c917ab6d82b6300be91eaed3d11ed8b0dbd0be9be260b4b48f23392 mainnet-00074-8aacdeee.era1 +44db8bddfff6cd79e3566e77bd383995218c7587f43c76263a315918a69e1d02 mainnet-00075-368ce2b1.era1 +03c6d37a2b6992dec4e0a028e51c1ab000ec97dd9899e857d63660d61b3f3f8c mainnet-00076-290a4131.era1 +9c696fe696282bcb09dcf0960b50e40c3438250ef074d1240d62a99864e61fe5 mainnet-00077-5d736b0a.era1 +8bbfe812605d612ad6c318836b8dc18046c6259db4324c7b0df1dd21ffb0044a mainnet-00078-98ac3e9d.era1 +97d6735bd7e1d332392be25adee20abae497cfd2b73be7dbd54c5536db076ca6 mainnet-00079-95e0734e.era1 +942b46166b52acf202c4220815b7076daec2c9a6f90921004dd09052dcbaf204 mainnet-00080-d778ae86.era1 +ecfd5c75eb61dd7612edceec5a7b54294484bc956596fd2154ad6005927b3874 mainnet-00081-2089ffc8.era1 +687012f0accdc5525d2522bd818d8780c5f13d845a6732de746b621b8398212f mainnet-00082-382ac3bc.era1 +3ff51981d8da4d2635d17324614b390628fbaecb300bfaf86f1b3d819c9964aa mainnet-00083-5ab1cca2.era1 +2e6094b9c31b6aeca3c4eddee9da7dd939398acb1259ed27bd55a042b2d30f2a mainnet-00084-9ec0497d.era1 +d3834c0f0ececed210279e0ba14e678ecfb0763504b7fc7aaf6652d059de6267 mainnet-00085-f847bef9.era1 +e378cea66dd39c845c13a33a5afe57d527a8c4fea40d09388fd99df831b28287 mainnet-00086-0dd5eb92.era1 +b5424d22adfc070d70b983d6a59bc208d3b69b84d5260672650bc6fca19be18e mainnet-00087-c0612d68.era1 +efe3c59bae8e561bcd27eb34fd5158fc447cbbccf030966b342c3e905ff6d0b9 mainnet-00088-3f433e63.era1 +bce0705620a992e73525cfcbadbbc637e9d5a6df0f4d1c11d6ad5c6600512ab6 mainnet-00089-0432ee13.era1 +d4e01aaa61e640bb49b8d0a7a54618fccec213a02e10e606495f8a59178dd338 mainnet-00090-cf23b0c8.era1 +86975356bf8e070f6a9e72d74a5bbb238ca01e91387646ce7d8f9fdb8239dbf7 mainnet-00091-9fbb0197.era1 +fe5bfb77adb766ad96c270897d1998a41b32ea747aeec107aeaf7963d08b2d0f mainnet-00092-f88ab15f.era1 +2bbd7abb11077c01143c952f183043ca7e791d0cf19beb848acccb02ffdffb78 mainnet-00093-b7499b8c.era1 +cf6d59ff853c33848c6d944a3e409d12b5750d4e675a21f13fa909e8ff322baf mainnet-00094-5c45bbb1.era1 +f30e125dbbed27f0595800330c2fe1ec396baf86439d0e9a9056ced6bbe9a989 mainnet-00095-a3dea11d.era1 +8ed14ae5ea4801411e4969ef98cc7281bbb96ce0d600227251b5e2262d04b334 mainnet-00096-91ff33f7.era1 +ec0f5896e06ee4dd845c5c8f4afd21f089e213270693c619b7f7418f396d62c6 mainnet-00097-8e4ffd2b.era1 +0d5c0acc86d6ac250db521e4e549d375a04eb3782407547eb1998d1a1a14941b mainnet-00098-4c5709af.era1 +1874a696a018e92d1231a988349899ab713c5fb363ff66d809e639819b951651 mainnet-00099-d55b92c1.era1 +7975244ba01f2c47fc484b54c379a88a2bb000d63142209bf42b89cec7cce1fc mainnet-00100-bb39d00a.era1 +2cd5c2b365bc770ab681ae9fb239434dca9dc9e9313608d7248c2b789705749b mainnet-00101-e6df1942.era1 +473cca4df9b620773192be4e474ae7aadb2246b0236d80bf7d9cebd8987e8617 mainnet-00102-2aac9e21.era1 +b5b81df30c8e682b446eb08090701b978e9dd15e8a121854b01233f321fb85f1 mainnet-00103-3fe56c2a.era1 +28e6861bd1ce937c7808b5d98807b644459e9529a785279ab8288e4fe041e9bf mainnet-00104-f3269b30.era1 +71bb327b8b61e9a7146dd5c947cc24a3e1f05e6aa0fd444663fd22583bc1c29d mainnet-00105-6f2f86e8.era1 +db9b1e7caa3135a81aabf36d5bb18ebbb57ad7fba5e1b0933c77fe5bf840db8e mainnet-00106-621a2527.era1 +a5e6534639f5a61d2379c44ee0ca47067a8301e0ac66533825abb4b1b356766f mainnet-00107-c3e8f7cd.era1 +e13b2b0fa20c89fd295db7589860d05857364952acae4b0ae5205ca585f6234d mainnet-00108-be1a1635.era1 +b262e31da0fe5c9b4d93cd8d685ba2e93c9677744eac361907cf6ce9645c52d8 mainnet-00109-49424c3e.era1 +380595c5f65a25f8d807fb325d58a6f00b8b3126d9de7be76d83a6c03a4fe71e mainnet-00110-af29e604.era1 +33a817abf2e9ca55472f02a290c4fc943f022addb2ea06b5571488257e05c8d7 mainnet-00111-1738246f.era1 +51ac6063c5076cb5176fd5e53473b73cda93b5b04bc8df917a9fc47478fd2a33 mainnet-00112-0074a32e.era1 +124cae748ad7963bbcfab0425450bf4ba224b61537324083e4f75880cac8c5a2 mainnet-00113-56e19130.era1 +cb12db25f4efdfaab5d7eb589edf41a144572f53e7884ab8955c0d31e69ae8fc mainnet-00114-10c2a569.era1 +f15a30ef45c74b6739f224f74e8d6f991cdeb692053a12e2882089beeac0f884 mainnet-00115-26efb6b7.era1 +6dc15f7f578b5c2ad9ae38952113cb236e2d56ee1c5efeab93ea00ddb4a869f9 mainnet-00116-bdf3bc6e.era1 +fcf289c4b3126aeb3187167aa2210f8feb1daf018c623955524edc2164f939cf mainnet-00117-e68e5334.era1 +10907ad560d2f6355aafff4b32cbf197971126c8e0aa0e96be7c8c97b241aace mainnet-00118-1c9a2437.era1 +f335c97001169b8d2068fc70067306bfe92740eb101f15b6700c55eb09ef2304 mainnet-00119-5fc6b689.era1 +37e6754278740f158e8a5220e649000c499cbe5ad579900e598bfe0eeca1785d mainnet-00120-cfefc65f.era1 +fc7d276a531ad1ab2cdd14909204a97db745345fe1dc66801304d9d6263b76df mainnet-00121-0e29b6cd.era1 +e003880ddbe6c14ec8993a141b7d03bd7a94c535f16bdcbac2dfd221d20c17ad mainnet-00122-cddbda3f.era1 +b2c7bc85c76937b4d5e8f03553ff02ca12d76e8631346bda57042bf2652c217f mainnet-00123-7717d395.era1 +020aed308ebec19fb1e688f4708c177ab5c36ea1795db2a8ba77afca97e1fe3e mainnet-00124-2e66a66a.era1 +4d4c12d854a2f5e364f5636fa5dcf69e8b0aad416cb4f61e8fb63bfbac076e7f mainnet-00125-82fdaab1.era1 +8fc7016bd372baa22614741a4d6fe2417e9b807931597c67e256e8586ffed7cb mainnet-00126-427637ff.era1 +9133009a71e9a524744106fda96e8a092bbe8488a52bbeb108ead8dd45f621f5 mainnet-00127-65e302f1.era1 +2d1e305a6693b93a47f8d014cf0ecc78a1eb9246aa4a22af689d75b7f855e9fc mainnet-00128-6fdc1fed.era1 +7b283541ad76e10929e2a2396174a776707234ec70edbdfc1a5129764c6615bb mainnet-00129-c8705b6e.era1 +5a96e61a62fc166db0e838b619f31b21edbd5c097726fb72659a2dc0a05e60a3 mainnet-00130-650f1d51.era1 +7a60d78f969174b20c7f00907965f9237fefd44bb8167c7d42a6b8647b67239c mainnet-00131-7b4435ca.era1 +cf3b648a50a3ecb1514819701a6ddd345f456d58fecb449d60d4c8439bf5b9ee mainnet-00132-23bd7603.era1 +2e2bcebed27256595cacb454f47274301d71e25086e992e09b740b5b7fff7bf2 mainnet-00133-c0faccfc.era1 +7be5c210f2dbf15457ca97b836c252ed4113ce2f8b794fcb1857ffa5b6475d86 mainnet-00134-ec9cf3ec.era1 +1379ae2244ddcb1a026bb9b04f26abc1687a79d82a71d8c196da1015b63f904b mainnet-00135-66f5486b.era1 +c072dcc6a7c5b27929921034fc0cb96d609e528f614efb97daf59d9b848cb322 mainnet-00136-dc4ebb94.era1 +a8570851f92ffd33cb8c44b4aea130a0a24cc8d2418c9cb32cfb05d0c7865ee3 mainnet-00137-02298200.era1 +50faed8730fcf592ffbe1ffe8bbdc1b3c8643704bd419a8c9bc33c4edfef9a63 mainnet-00138-3d231400.era1 +939ac8db4dc0b0c27635e986257a2fbfb8ca8aa6a45f2aa22ebb39591a57a3fa mainnet-00139-5f316611.era1 +7e84c2ad1da194e20c4533be1c297a2dd442cf829aad1c99bd9cfdf8b265f576 mainnet-00140-f13c9fc0.era1 +6830c25223962969088b4d55b1cc06a879dec452695d582e45b4bf74387e141a mainnet-00141-17dbb0e3.era1 +3665c541116f9563aec1cb9454a4c61535b681717d34ecf9c8de70d53053a38d mainnet-00142-e42539c8.era1 +64cd17cc860e99b3efa89afa7943ccd894227ff2dc31687936e64b86c4f88f7a mainnet-00143-5594a813.era1 +4eca366cc00e4ff4d5cb240b91fa84c54fe5a82632b6cfe66c776139bc2f0e0e mainnet-00144-5ac2296f.era1 +e30191fbb8fee15c6b844a4b806271330259c7c8ebafa9125690c17b400a53f3 mainnet-00145-9244d418.era1 +84fcc41d9252fabebab8254ce6c518a93ee3b50188adcb6b8974c9607323d4c3 mainnet-00146-af9e7a53.era1 +e0dbea3796018c40c3a2297d804d1944b32284eb8050f2c16004db94ef0c9c43 mainnet-00147-1b6fa332.era1 +1f1d4e7a4f95bc6ea9b5f606851fab7ce9d688012212c18ff4042760bfdf10c2 mainnet-00148-39f0b057.era1 +0742f38779b0fdba8f687d428e4a1ec19ade71c079259c29606ebc6afb858947 mainnet-00149-586c4a91.era1 +56157f687d849c562eb1e704e7d2265e774a5701a704b6cacf3de140d15f96e3 mainnet-00150-3ff89a4a.era1 +18d55523deb34917db5212e0b025a9249e416b8a6120841e87507e0eed3f6435 mainnet-00151-e322efe1.era1 +e120aa74fda9cb3673811d00e7c5fdb64155845f9979171a3e4261b3769c84f7 mainnet-00152-4d9d0d1c.era1 +d1d327c715f83afcb574518c842c93f7781a3e18192d8c0a052868c743540f4a mainnet-00153-6b5702b3.era1 +38bf622cb23f04c237b3b780cf5375ec519a06e2270648a9d61da3af009b2567 mainnet-00154-13608c12.era1 +d00300907afe184f2df7c6176478db881a1ef20d8fe4f7cb976f63c83edb28c9 mainnet-00155-d0bf6ce2.era1 +776f7f6d327c12164ceba5dfd7900edc73cc3610c42d162d6cab06d960bc44d4 mainnet-00156-b8c3629c.era1 +d423c18e2ccc90db5684073b77f4b6530b17b4d0568d2d4e2aea6e60f7b5315a mainnet-00157-97351a9d.era1 +660cda8c979fa567c1be2535a64fe1f1d2b2ef221ebba4a2c8fc697f9a1707ac mainnet-00158-5cee8f8c.era1 +e9db5574fd2a08826615813364d816b77988b601afcd3634bc9cd542dee2fad9 mainnet-00159-b92f84e9.era1 +d460f1142d881241a5ac03e07e55611bed45b979a85a84271448b39bdcfbd797 mainnet-00160-3e41d9f5.era1 +e198428126e8432e99a3821079a701ab8400b64919f6d6c936bc404e1846c198 mainnet-00161-0736b99a.era1 +5566e30ef4b51515d26b9e3cc6d7167f5f3ed4fab0b463ffeb8e49b2c859e15e mainnet-00162-0a1530da.era1 +90d71da92883bfdb64166a3b06b2e6afc1afa93241a63b3b19205e806fd11217 mainnet-00163-43212d3b.era1 +6dd77d7250267af09559b1bc759d48225604a3eb5dec2f0ce4a183e42c0ee8ef mainnet-00164-3744a01c.era1 +a976c82d9667b66d86b3963537270ecb412dceb859d34e6334977c7411752e81 mainnet-00165-3d14fc84.era1 +8b42ae6ddcdeced9a4a12fdb321ef07ec07cced26724b21e5b5fbc7be50e0393 mainnet-00166-97c25925.era1 +7d64711e3c5fcaf098bb3110ed93487038cce4cd4ec002d90461fc6cee995f77 mainnet-00167-11485002.era1 +c76e19eeadcd672c5896d98d55c5599bf53bce667d09395ba3b013551581d0df mainnet-00168-88a365fa.era1 +76c17d3eb82334c5d208d0c6a995a0776f71009bf9797ed5c3c73e7052077fb1 mainnet-00169-f18242e7.era1 +61b9bce113cb3d426ec6891927430859f97f8efd994b45399f40235bad94dac7 mainnet-00170-f03ea8ee.era1 +4a0d46d3efcdcc98c4606f371017b8dbd9ed0d418e70d80bcbbd926353f3a5d4 mainnet-00171-bec8ccd9.era1 +7c906d4fd5bd1df403a3a340f52df6b9a31d56ba098105217f69154a7fe106fc mainnet-00172-34a4c5d2.era1 +2a7d767dd8f37b8de9b52d6593a4e322e7993bbb18f383a8ff1fff0214bb77db mainnet-00173-e1ae6c81.era1 +806eec85a2df1d7253dc9282a1d430d3f2a898e8fae74cfdf25872c8b57d4718 mainnet-00174-727d10b8.era1 +554840bd4982cf792b3439227c38492f601b08b40e1175c347ffdb52e1894865 mainnet-00175-1bf21dcc.era1 +ca8d89eec998fa58a128a64770137273ed7d11e7d47454f83577aad42b9b57b7 mainnet-00176-ecc872aa.era1 +5034d99d013c2b173c1c98794b5e8519657d6643ac23a0484763bce3a9aae210 mainnet-00177-966bdbf2.era1 +5100933799b61590847d3279f3e8d52ae00c6a78a5bb0f701ee9d582d270a01b mainnet-00178-b412f22c.era1 +8a28818dac4aaf5f8bb8d7edafcfa2b9672a06c36206a3110737cf53bfce4fcf mainnet-00179-09e40d3b.era1 +bfd6db13cda398fe7c80b41cbd770931dae78a0292d2b06ef572bb89d0718615 mainnet-00180-8ce22357.era1 +2e207838904ce105993d9528173ee48771ffcade3c28f497c3eeeac772af6f58 mainnet-00181-ac1cf418.era1 +66a64cfc1220caef2f49667cfb6a4c7b408e470da598caf87c50abb2217d133f mainnet-00182-f770e12a.era1 +2b1235b5dc35872f2178caa60a2bd4bdc72913509955d79796a455f8a22e6ddc mainnet-00183-798224ae.era1 +7ce2dfe40051314987fc3b1204da6d9e721b92c2f9df0a12facfcec00435f6e8 mainnet-00184-876fdbe5.era1 +4647b15e4799dfc87cdf931cc5025c9ff92b43cdf57e25f9b36c61ed1688981b mainnet-00185-7b447a76.era1 +5040f826c205e038873b66deb1fb562b60a9c8cd6d7d264697663fab3d70fb70 mainnet-00186-f1e11ac5.era1 +3c1a5e911eb86bd1813363194cf963c9b7d67c6ceeb15cf86ed2d7172eac5ef2 mainnet-00187-ce8b009f.era1 +cd03d04eb762ec7a86ff476d54985a5b47561d1cfbbae14c6bbf8462ce79a528 mainnet-00188-c7bd816d.era1 +e302ab30c052d1daf7783a021af19c1d394049ba4eed3e3bc33c559dcaa4b622 mainnet-00189-144cc97d.era1 +d2dff17507620e705c50040cb45507d9fe83f488945dc10e9e0d4f508647e71a mainnet-00190-cbbcca51.era1 +626db8c8972a26c290b5fa6441245db68f2eb6de7e41b90d6ab214ef44909359 mainnet-00191-3a7f6484.era1 +3ca721781718361e94fa2d011b37cb89d8477348d4ab7d99ffb32af79093d7c6 mainnet-00192-8a4639c3.era1 +8350e06f7bc0831e6ac2184cbdb8603177fb3184b092f4320e470d521579a78d mainnet-00193-52629553.era1 +395802fc385c14d30e2a3da26eda066ce93e64228a3564c85aa309fd0c1f9727 mainnet-00194-c4828a4b.era1 +32b1ce49f1ec65ec06bc5dacf8e5a3ae3df4ac6ab46a0e0b74a79440f652e0af mainnet-00195-f50a165e.era1 +0ebe874ce10e7d9459b55f9e9743f72634b89b58edf4171389299599654d348e mainnet-00196-5c31919b.era1 +0a1eed2cf5a71cbfd0c969bf11834cf637dd977ea81198f046f7762c7227ee46 mainnet-00197-9e2a709b.era1 +14b10d6bec29dc751efc999b3663f546e6c05d46b48ad666786ee03e81706fb9 mainnet-00198-c3e781bf.era1 +f93ff7cfcb2a47f5e3798db2f74446635342b92b21594f1c91bd800346ca69d5 mainnet-00199-20c05ee3.era1 +7fdad50e2fcc986cbe27fd5aedef822fe1c5bc43d8bb0a733d86915172c21746 mainnet-00200-dc265ad9.era1 +0c1a1efcae99cf65a0533ce10085cddbd081ae80c9ad6eceb3e16301d23a5810 mainnet-00201-1356f2da.era1 +e737494f1c4188a3aff61ea510d3791bc14c5ceb9ec2bc81bcaf560f86de3b48 mainnet-00202-84e86114.era1 +b7e1d6cb3fa829ab59879425bd0801dcd5134ef4d45419a62623e5b74db8809b mainnet-00203-f2da7b50.era1 +b05ff70490032070dd3d02ec0170b9e16881f25a466909a738a8f58f6c3ae51c mainnet-00204-7f42b43f.era1 +bf5046c68782b52fec94aafc863a592bf9a7c44c347ab0f5c78fef14b61d91fa mainnet-00205-afd08f8e.era1 +0f8ea93ef10ceac74ea516129006b69651a2abbcb129366d947fc49dca8523e9 mainnet-00206-cf4a2c65.era1 +dda172ad37c9db5e43fbeaaca0dec05d3673c55ed4c5f9b593d8c4862f7f1027 mainnet-00207-59a0e883.era1 +e157c8d46379205b6bec2f49189ebc1f9bbe0e2b361c1068da3ce32d2eaab797 mainnet-00208-3d0bbaf2.era1 +22ee433ea64f0e857171e10c904f0d190c6d9c43d037e5313bd49ea0cd1d05b2 mainnet-00209-c1041285.era1 +26c3bc51f0ad7320b02448db82705201257274f129f899b4b15e2c4238dbc2c9 mainnet-00210-1eb673ab.era1 +467213b7bb251a7b51236a357cf019ca1691c86d65116ada6b2783867bd2e9d9 mainnet-00211-01e5a4d0.era1 +431217d3ab4dc0c5566e3e98df2a38a4b34f05934757090b72362bc3035909da mainnet-00212-83c3bb0a.era1 +66346ececfbf29fc572d85d6019f0e7eb76cbfd8d126d2a5f7aea7b2547147bd mainnet-00213-9a09fe68.era1 +e060bc6dda403f94b5029601d9e698ff1e73c6f8b9978f235f02dcaf3ab722da mainnet-00214-9e78dc12.era1 +319c9a5a2bfa41e06885002611873b156828815c7d2761270e7f072271cea80c mainnet-00215-b02bf96a.era1 +746442aea25eaa0f243fa13bf7bdb37b4b3e294e65a0c36310c17765e5a9ec74 mainnet-00216-209c8b32.era1 +399c317a2f40ae90905d2809e9e5eb4dc0ced9f19cf2fbfb3fa5e2d780e525ba mainnet-00217-6c84f49a.era1 +c05d0562e2c800f77a14dd29201acdc17ccdb06c87b88f5027135f648270ff47 mainnet-00218-acb60f14.era1 +fe740d7ec3f43c228bd39d4bb8bae8526c7cdc747062bab8954adb6da628a1ed mainnet-00219-0a773645.era1 +5409e1bdf10518d1cb5d9f58e70d07bc5313f969f7dde1e617cc0af49a2ca834 mainnet-00220-76ed2324.era1 +2880b0f5c23c49e79e498751975137e2a9e5ce89044560636ef16060e241ea6f mainnet-00221-76ddd2d8.era1 +5f03fc4b387d079e32f314b4a352212376fc6551dad8cf210e40a36486130b65 mainnet-00222-71e986b2.era1 +1de0c6bb2abc98fd83fe626070d64a7759bd1561196587ef462d357751f4dffc mainnet-00223-ca2b5c28.era1 +4fe9e7d3fbdac24e845b4945c9b0ed046325c67b325cbdb4a5222ecb9f71de96 mainnet-00224-ff571e13.era1 +69fccefa8e7b4cb53e1aeee876a2bf6f644a685a18a2bdc5ccd1f807769a9cb3 mainnet-00225-1cfe3239.era1 +1d551889715dff2276ef1cb3d28b94ab84debf4577fd14509fdd433d20016413 mainnet-00226-b0eb8f2f.era1 +4d9f29c9b439494a0f377979c76d6f47377171f3de0e503d1732b12e31a188fe mainnet-00227-83556e9f.era1 +70d7125b225f523943b79616af7cfe6edf5cd20621f321e7ca894d73a2cc77f8 mainnet-00228-7651e7fb.era1 +be32f18cfe34a4e6187f87fcd4e6e7baa10778971049f8a34f40c77407d88588 mainnet-00229-238ed788.era1 +d901af617491c36bc121e25b0734a3c7a37496e6a3bcd03d8d09cf717eb57e6e mainnet-00230-3826affa.era1 +4ef61acb4b95445cc7a8ab5105aed016fb35f6ba9a2154d382eed203dba33279 mainnet-00231-b81f93c6.era1 +d506f9275e552aab49cde4e09ad5499bea5d8da6fe6483c83af627612f6218a1 mainnet-00232-0cda2a75.era1 +8c0386c53e59d8363e4e73d68c1a9fe124c61eea8c72486716600649d59927e6 mainnet-00233-b183167b.era1 +1e4702b597a06209d7821ead4405160cde6ad37602df2f68eef9167f6a5ecdbd mainnet-00234-4a88300d.era1 +34acd755492f89d62ed5ebe484aafac11f8577e7d10f71ee114f46cb84bf21f3 mainnet-00235-05ef6143.era1 +fa336dadad7c7c12a720641ee21dcf712fe6faae02819944772084a74bad29b1 mainnet-00236-4164fdf4.era1 +293b613f1b39810a965f334d4b68cb5930758117659ad5e8ebde82bc8cf05887 mainnet-00237-d5c9eed4.era1 +725bb2261ff58b71cfffc9863e1871f74c07249fe542515560f4e5cb58a35b7e mainnet-00238-db0d90c5.era1 +4db568aeec1e45cd5bf9dba0c284a40b303a50d1d6fce44f44f41491dd3e56b2 mainnet-00239-a0c972ed.era1 +c1f65805f6bdbc48c3059859e4d32796778cd4184f451f035baea8e216f6b597 mainnet-00240-9cc1a86a.era1 +e24ea67de4ff052b3dec75ce1f868e53a40187949411f3995cc2ab167fe51347 mainnet-00241-8ab5ad43.era1 +5c3f0b5e946c42fe19348ec73bfe7fd4c9de5030f02539b235aa37056bcb0a93 mainnet-00242-491f232e.era1 +0bfe4e75b28f738ba47f5d3ca868b44f57d66173bad19b375eebe9cd93816d7a mainnet-00243-f66eb348.era1 +536be6c4e4b85b18244b4ae7831faccd98918e60f8cf371846f5278f5adfddcc mainnet-00244-7b141f13.era1 +395e73f999f92c6934129b14b10093fbb556d30eebf794f858d55cd4bf72a821 mainnet-00245-ef5b96a5.era1 +ec7ed2022fed7a83624a665612a4ad0bb69d8a22ac9b851a6f198b42c495ca5c mainnet-00246-32d63aa1.era1 +dc5a26bca0d024416229caf8f3e21afdeae726e117fa858e23c6db533b28f583 mainnet-00247-7b033a6c.era1 +f325b28a7f1015865b5bbf20ba2db40c13109af7c1a96faab8c7e91591a57703 mainnet-00248-50916052.era1 +157805c7380f776514b786262f29295a798cfda5669d2feaeeb7c99d36175763 mainnet-00249-75e0db34.era1 +a9bcada73a1902235625eb43b828c533648ae862999711691f8c6b67b08bbd14 mainnet-00250-4781ac7f.era1 +657b73cdcb86e43603efbc2625b449c526c501fcad055b5072e845d96d6f4286 mainnet-00251-c0f8b33b.era1 +18fdff48e3ff474f39a595eff14317d5bda72dfe6e113f880ee5444719e7168e mainnet-00252-afa72ca2.era1 +cccf5306905b1e2141db3d5dbdf994e063e9d931e607bbc2f0193f232e076461 mainnet-00253-96c6ccb3.era1 +06a86243f76c00c63bc9296cf01cc35dc6e6c798a34c76e5f1d8c95e814e5090 mainnet-00254-7b32050e.era1 +5ffcfc2b084ab71d603f8f07ef9ac9b48945e310b46009378f97859a7f14aa17 mainnet-00255-16317cf9.era1 +5e8b0f5d502a41b4a7220cd2f8b9257446799e56a20c3654dc3cf67e9e528839 mainnet-00256-b4ccb50b.era1 +5f4aab770a331de70119302d26cdbb6b1bdcb593738ee436b00c22cf57df740b mainnet-00257-98808d16.era1 +0738e28ea91aec4c979ba9ba8b5381513c3cc01a01306c4a33410c55a4cbdb0f mainnet-00258-3cf61b1c.era1 +fa877be3381780ef3b4defe1e4a98c89089cc78b4c4910fc574e2b7708b86699 mainnet-00259-051764d2.era1 +09aff4f954451ba6e19705e27fe2af7a9d2108310184a5ff60d83b05b35b9351 mainnet-00260-3b0545e8.era1 +258032efc35138e75bfd888ee5665d419e4ab1f89548da1cd0e27066bb95e693 mainnet-00261-a6f4bfca.era1 +eab73c427116a2759ac62acb104d127f2c4672f53118752caf08e4a540ae9ee5 mainnet-00262-1a75662f.era1 +4c16ead662a9731e092d0f1ce5be5df0e37b422d6c1844e6f853af2ec709a219 mainnet-00263-21bf7eee.era1 +0be7714626e9531630df7740b159be925eef22cd9a8243d745594d854ba49207 mainnet-00264-d41eb83d.era1 +ea30083769d810c1cfb254c52b8d691e810921bb61731d9372f093fcee0c50d0 mainnet-00265-e7a19561.era1 +934ab681e87604eafbc3535dea53b1a0d98480236d09fe022febebd53a67e407 mainnet-00266-4f172aab.era1 +5831b78b87a3cd549f3dcc891b40af7b88b983a5d50431d971ed25984a8f963a mainnet-00267-7c0e1bcf.era1 +2b562646da50134fba39460cbb0544bcf91b1784162a1a837749228fdc0ccbe6 mainnet-00268-c839e6d4.era1 +5878d26fdcd2c89bb5ffcabdc1fb73648a608aed48a644fc3bf093c8ed88d871 mainnet-00269-9ec52dfb.era1 +57cce61c6d0571b2fefe353bea1f7b07fd0cc6150f9c64418c54347fa3cf3842 mainnet-00270-4e8bc727.era1 +864afce33474b26425e22a753d92b4e903ef354c225d4c4b8e4368df5a456b44 mainnet-00271-5294c75d.era1 +e288f65b7037d78d48c7050c9796f285c215c17f5774624bf55334e2c609ee51 mainnet-00272-02a11db2.era1 +031dc92f73528d0245e3c71a145f04515bf797d63288c11c6e8138ea13505d80 mainnet-00273-d81a2c41.era1 +03a56b01a6de3a402af96dddf91a491f759237c1da99e42bd200bf43c356b525 mainnet-00274-9c4bd87d.era1 +74c043d4703bb1b795b7f7c3d5f280a30af2d35e9517071b045603f31bc4e6cc mainnet-00275-85b9c67d.era1 +809bbf2e67ec7872c95391dd90a4afe4bc769f0027927be382f3365e31620a5c mainnet-00276-38cc1236.era1 +677387a3f7f0bf084e41b0d7e1fabf82a56ddedf40b18edd5d9856e9000eb5ac mainnet-00277-40c70f95.era1 +0a838d463deec9e5c5b85e18d8725f183c2170540dd9f54e75d69b06c57ca23d mainnet-00278-d9e0d738.era1 +ef9c97d47691c727f714970dd4a9947d8143e09e5e25eb872360cc16e8ea9364 mainnet-00279-d20a7b7f.era1 +a622740738e04a5e673ed21192fa94aa81ac2e81dfd348edb8f36cbeec1edc58 mainnet-00280-54a85faa.era1 +6b98f2e6d1a839411148692305b86ab30240faa1343d1bb8f27bafa37cd9f634 mainnet-00281-f08b9749.era1 +6abbc1880218b1ba0c4684c4c0769c98b26545c41bebb0c4c388410fe7b26a2c mainnet-00282-a5912776.era1 +78dea83c37faa03f9d03bbb6b23101bd072dc512a8976a19b2f032c43e0a0d8a mainnet-00283-8ee7ec35.era1 +85407f624d764cedca0eb875a5d18f0cfa87aa060c36841c94537b02f3602932 mainnet-00284-374996f2.era1 +b88c6c1c9bccdb5b8f0d0fdb5d1a2a24b253f5f8e465106d1c6a8e6abc70684a mainnet-00285-94942585.era1 +8940a7e96a2c2c7a40a18f18a93118d9a5c41dc0cb7ad11f64392f344e028356 mainnet-00286-6d47a234.era1 +df3d4819985088b642837429800af088389b479843e1c99bc74e2bad652dd717 mainnet-00287-f9804151.era1 +cc8bfc4ee1ce288ef3c6579391179890995660ef78b36328b8c989f4da8d7ab8 mainnet-00288-3724a8c9.era1 +bbb4f0963dbf87bbe6c0ae49398ea9713bb8ebbc6103922bca89ee4c7251767e mainnet-00289-60d72bd9.era1 +4a9f3162be5b9e8e12186454dc4d64c34d17a78d8a7e51b9845bff538032e229 mainnet-00290-64cca80b.era1 +667cd9a0e715eb9476b4b0750bce1d729579e1040833c55dd45f172224ad336b mainnet-00291-0dfa92f2.era1 +fbbbaf9d092c289e437648ce030aef4d0bfc48bd01ac88cffdf4288a190f7c5d mainnet-00292-94905988.era1 +b4db0d6ffe70930e6c4a83fb787c3662fa7bf1782bd2775f791190c2eab9558a mainnet-00293-0d6c5812.era1 +ee58661e70728f41d969f9bbc2f3813d8524a8ae5814d2d6c9bc4098330c92a7 mainnet-00294-f6c5c94a.era1 +e9b226a29d2dbbfad666c14988ab99f1b70dde5e98366a667d5951188248fd58 mainnet-00295-4efa78d0.era1 +651d8832de7b0aeb119ce650914db9960bd5c18c49fe3db8d19e289787f749f8 mainnet-00296-81c1446a.era1 +1e65186f5a9d78ce2e9a87c49b734aac341c81d33ff638ccdd8cfb68e354d0ca mainnet-00297-08d13a31.era1 +803bb2f55f8c75b7916d0ca02b4e41c0a78a7f196036315ec940f554fc6112f7 mainnet-00298-3d1d6d89.era1 +5b88575c8949f5919df6f84f5240e4615ee3523063e149491e817005eb88fe99 mainnet-00299-23728d43.era1 +a69c3443a1142f5550e19f97c5b002fd6eed389fc3a788df1d598cd5d1985db9 mainnet-00300-de033253.era1 +6900304acacb549a91cd1a8134b20f996af9743da1efc554e40d6422a934f21a mainnet-00301-15a24df9.era1 +f6b8bb0f46957fa47e2dc210605e0631891f36e90061a1919607f01f6105efce mainnet-00302-ba653536.era1 +be87a729cae74d6e5493425f1363ca3ebad2d5b62f75f9e2be58638408ee7a82 mainnet-00303-35fde006.era1 +d5991b5894638d6062dacd21d764ff0c25989b2638544099d1af8c043f94da28 mainnet-00304-377bf395.era1 +f7b46b0af17d873ff5612a8eca4d7f933a08b39201a934a77724f86d86eaefa8 mainnet-00305-340a0b81.era1 +11c7324dc37122afb9409f009374c0b4eb62e6eaba1cc9d25d64ba523429152d mainnet-00306-848e3d92.era1 +e27c325de831974697c9ba15564c9df699cad55868a3536569e04bd37b71282b mainnet-00307-a3ff7916.era1 +ede1004132d35682082626bdcdcadf7df17182b94ff13923ecaa5a4f685dcbb0 mainnet-00308-48c7160c.era1 +6a338b7a5c69f50556da5495e9d26b74f7c3d77aa28200058f21d2b85827431a mainnet-00309-e7948131.era1 +890963652b631abb1981f98de7dec943f9e6dbb70973c71f01ccf5aa4382f2f0 mainnet-00310-db22eaaf.era1 +94c3bf7e8b977816736f06d6f8204a3fe1ed17ffd29d4d311be5859d9a7a8f2f mainnet-00311-f9e4fff9.era1 +53ea643472d4e5faff5137a793d106b285235a24d6e3cd6ff4bb53e72ab3afe2 mainnet-00312-d95903d0.era1 +72004650bd296128b8d3efefeecaac923a16b86989304110adebaffc3910aedb mainnet-00313-73f91876.era1 +281fb5fd464478f53069670afa53f68922d311bcbae6c660e738dd5755820fff mainnet-00314-8e339794.era1 +a607be2c022534077226b3a670db8d295344a1e57fcb831c89d2ba92a178893f mainnet-00315-e83123f0.era1 +e6df2e86fb6cc688529e4371ba198c1f250faead7f1b64b5afc885f5b8805d0c mainnet-00316-e49c7af7.era1 +87af67240d12f602175519be1ec4e39d5e238b5db8e4be17c8e5f939bbd02cf2 mainnet-00317-f3ae6a62.era1 +8c06c1bd3ffe05cb3b70a1a3884d3a9913eb9e0d80acce9ee2afe8b231ab8926 mainnet-00318-4bf5c84a.era1 +bed2444997d93ec16706cd80684c77ebfaf53b539280f2d2e3059100fafbdabb mainnet-00319-391837c4.era1 +db0346a2558c7181fd86d92dd4b55188c6b6e117fe3c422080a8a2bc0a850bfe mainnet-00320-bfd4677e.era1 +5ad52159859033d593d70524cebbd2c6781ba33276acbd710aed2caa93db2a4b mainnet-00321-7189f496.era1 +e0a05a81ce6f08de0398677ba3c57762e6cf03b68f0bb3a9c5738d2a1db8a8fe mainnet-00322-344663aa.era1 +f2a0ed15703130b139fc81bd88f561ff67b44c2a95e5af376fcbfd0b6673e1b9 mainnet-00323-e111bfc2.era1 +b75164f946d2a1aba85c9bb1fceb68740c19b3d86324c98ce93d2294a8653f09 mainnet-00324-be2b4b22.era1 +48b8e615992d0bb139cb3ee2776783032a2ed1a04e72acd85a785fd837d09c82 mainnet-00325-441fdc44.era1 +6b3575d54eb17c3b631e64d737b5e58787b2239e514eb84e15f8457cce72e13c mainnet-00326-42979360.era1 +f4dc8f39fd7f2172169c8e6f4766b4a09c7904db085fae98324b6329face3cb2 mainnet-00327-820afe74.era1 +abb852aac204091bdf380e6f20f1577d5307f0c9f70d3d885df4771e497d2201 mainnet-00328-08665862.era1 +d1396c5f8acaa5469f394522e8408ed3e7ae816a6ea8e7d68fa6ce60d9ce78f2 mainnet-00329-cc85d0d9.era1 +2be3f4490eaf2fbf8631b643bc34da2d2b978f2b24557e6e34e42096a1269c89 mainnet-00330-8ffabe96.era1 +b23f5f857c96c35e5d651131841eb91bd10d96d2c1d56328b81eefd51752201b mainnet-00331-57c9aa44.era1 +b441204d73f9484d12e5bb1b81d2068fe2a6e4564654e9f8827b258e0212b5dc mainnet-00332-3135b734.era1 +ce17b8b868abfb2b3caa4be81253c778fc6f89e672b0453dec2e68a930568edd mainnet-00333-ef368f00.era1 +579f357ea1096016184e8de024d8ac499d4317f027680f06d2ec4af955d5bd80 mainnet-00334-1c3457cf.era1 +972a808e6f0242894c9f2677e8c13fa78f3b9dc4b0402a1350f3fa22385b48f4 mainnet-00335-b191a95e.era1 +4b15db1107f822a04b34cb9fe6ad6fe5ffc7b203b11a4582d3edb8a905883883 mainnet-00336-b5318d5c.era1 +42f60efa2d09ef0c09429abc092a6f68ee43ed34f00c131f2793e61ec06ac0da mainnet-00337-a84d51fe.era1 +6e8ecac55c2621f7ec7f985c61b2ecd820b6500d3bc55db1b73d9d61c7011450 mainnet-00338-f0b5744f.era1 +669dd0598d4f0b1d845c56e186d3b6775e3a3a68616dc943f3542e6d6bda00fd mainnet-00339-5a637c4c.era1 +b7c2a9105a97e7c45c2d8f6832beebc7ca09d072ff606298072558eb14fab8c1 mainnet-00340-6bd16b95.era1 +510f6645c303a5bef35e3a42bb67561788f45537311938b6994e3ce21d2622f3 mainnet-00341-e0d9d5cb.era1 +3ecdadfdb461bbe51b78adc390fbe1a0a62af515fda9f673fda32efb436227f3 mainnet-00342-203bc599.era1 +3192d942c5fc52cb417fa533bce24cb75b2b3ee7642b0917d68c834aa8bd6df9 mainnet-00343-a668f92e.era1 +f30fa7c0be0490cfeb52a219e34190ea0c4794d63b7ffbf52a9b0e3a78d5cbc9 mainnet-00344-9cfd6013.era1 +75ebd51403dca99b2b4af773e9e38b705d137daea79cb8bbe4aebdc736d081c3 mainnet-00345-54595ee7.era1 +31d39ee38b82e05c35b3f98d973153e905130dc0746fba15e8db5880fce296c7 mainnet-00346-2297e35e.era1 +29d62be96827f03a2e6ce994be348df7b81fb6eea599bdae9e9d8b3322a2ed5b mainnet-00347-db8912b3.era1 +2a09d0ce3566e1ff1e4f1913ab021eacf7edf57244bc22ef9a3d485e02ae2c68 mainnet-00348-1dde5ab9.era1 +7e9d44abc0c85b06c138781dc9694f4b5c902def74f6f6b90d9bca4f902bdce1 mainnet-00349-7e25d7fe.era1 +7b286530125adcc21fbd3d08ad29b27d9005b51048d3be73a17d7606492fce11 mainnet-00350-2bce5715.era1 +d837111205b43025f5d6dc3524203fb901091491b5b1e3c998366b75ac5aa213 mainnet-00351-112b61e1.era1 +d9541f10b1a86c867ee32c39e38a9d7cc74d2865c6f111bcbed5e019dff93092 mainnet-00352-2ffd764d.era1 +49eb0817515d01c1913055ec9280ee5c1998fe5709da7687f9e26aa5c588d95a mainnet-00353-8d5ed81a.era1 +b2323b55726ec90ee2c8eb62fcf4c8a13504f9af80e6c2951b0df13f8b02526e mainnet-00354-78c57cc6.era1 +ee66a1433fb112d363c195f15ac63ac3c5115bfd1a4acdf942198068f0221067 mainnet-00355-55973475.era1 +6f4476ee25d30a33bad20eb1b46a3af49748c858033c14d0a315aca6387bbbc4 mainnet-00356-c7493a6e.era1 +7dcfcf636800c8396a9ebc28227c0b6891ddafe4635989c37a54bcb5b12f25f8 mainnet-00357-e5dd9171.era1 +35148d904c5dfa5d2a40ec89a7f7dc020f4fec1edd685272270a0fe9c4b31864 mainnet-00358-60ed8451.era1 +6c8f45131f9e0b7b0e7d74e9ee836590c484a52d1000e0882a7d83c4f3d2055b mainnet-00359-eeb9573d.era1 +37873b1e0fcb60f7b7de68b84cb08db41b32b61dc64163f39ccf5948ff08efcb mainnet-00360-277ba2fe.era1 +c66cf63b180e2569f2d6c72d780af8c01cb8b7d6948515435e095b2172daefdb mainnet-00361-fc97c47f.era1 +48f612db69c52e246491e750e5f94df47b80dba15592b26b318ed0e613178830 mainnet-00362-77f810e7.era1 +1b2179d93b57c2a17875b444a0c3d1fc4097ff084ba8e6bb937bc092e04d3edc mainnet-00363-056ef66f.era1 +7ac13fcbf596e3e8c23040778198077c0aebfa3f0d03c39a70ecc000218f62f4 mainnet-00364-374faafa.era1 +a4c07f6a1c9f6d8325e59ab32efa67242a7a57045bea8d55eb532493ecee9f8a mainnet-00365-a959566e.era1 +e9388ce5ba91752066804f0686d836887ea7b1103933e291668f70ce8c5de325 mainnet-00366-905c4a52.era1 +b475829a1bc10c1c74748cb87a5c0e2f839bd5e6b69f986ee2d05d6cc2bed562 mainnet-00367-ed4e7dab.era1 +1eddab130d93a1f6d4b87fe5d2bf03f19de10953c1ba49d23b2cd73ae3a5c362 mainnet-00368-b4a84335.era1 +e49f3b85041bc16ddf43279060c2e3c123ab2f441b309dc582f8b5ca3d46e89b mainnet-00369-1f3be833.era1 +a84eff31f8c984e5ffe0b0d0fd3c71f21e3337d8590778f72aed4cd00a337fac mainnet-00370-ccf6672e.era1 +5543f4f45161c97173eb33149431fb42cd60351d3a47cde9d9df3af0c55cff36 mainnet-00371-1aa762ac.era1 +9c4bd2e345c961a78171424a04fa289b2ba87cf9f96c46f388820cd970934dc0 mainnet-00372-05d7f23c.era1 +c469096ccbac56b9d2430d9c701bdefb3f3637bcf007cf769e89320454d04314 mainnet-00373-9a832205.era1 +5aebe7c74581d12fec8d08db79d8691c80b55642bdf2a20aecc68b1f9620dfc2 mainnet-00374-dab73b8e.era1 +61a2bd7564b57b1c09df53f21cc290935f5408fb17e9738b7c50748588b9ce50 mainnet-00375-e97d6f9f.era1 +f93bb38730e0585997daf5e0f200955d19d7ad8e377348bf82e9f33c38c93701 mainnet-00376-6af73957.era1 +086d1ab1ad0bae35f365a752c9b65edfb6de8aaf73f4f44e764c8b8d502eb07d mainnet-00377-fa0bd020.era1 +2fa64acb1e994584a32f066784e8a1372a4bda26c2a9bd666f0c170211e31d39 mainnet-00378-85b101eb.era1 +ee8d899c60918d323b752102b7e27087c3474d95378d1bf57a833717e7ab0c51 mainnet-00379-fbe01c0b.era1 +46cc8266511d62f79cc181e862b0c5c4924e81ff1b33caeb67d3434e20551941 mainnet-00380-3e90265a.era1 +1e98509dfb62e17c5f06fb0388a1eb44a586e7ba636567d2947652e7e5e0e53f mainnet-00381-0b316492.era1 +b973f4831df7a43b82d1006cf2be4826ec3160336b78a9b12ffe5cffff8f8e96 mainnet-00382-a02e585d.era1 +e68d474a4b46edaeb641c973d00bad2814c7e590e7171ed009015c6abebaf914 mainnet-00383-2198573b.era1 +17f9393733c93d004aaf59fcf832c09f013f47ffcae3aa7a81a2e19e923ecb01 mainnet-00384-0c367f63.era1 +2fc3cfcd0f1188247724e5c2e2e7379a7202651c59b919a421cf2928254dba15 mainnet-00385-8893c8da.era1 +c2017d7d6f0e564557eae95368462b2b9bdc4a7319f9377eb3ed17ad97c462f1 mainnet-00386-30637c5e.era1 +a5a18058a5fabc9ee99d16fb2a6e42de640e941233dbfacd19d3702d838c9ff4 mainnet-00387-069b5e28.era1 +5d898b95222612813fa0f52b81c0298a1c37f768cf4dc00a059f155ee8e7e0d0 mainnet-00388-82890633.era1 +c7645b3b2019799b9ff38355724030216fd0a48a398263edcd21ab7c73fbff78 mainnet-00389-def916eb.era1 +79ef309a1a41a7af16ca5a125a446a9628f47c9b4176afb50e3687c1ba2381de mainnet-00390-00f64677.era1 +ca8373c3fbb5e219405ec04cbbffa68879b4ded6dd07544af0532dca5a9e7535 mainnet-00391-60554823.era1 +c4c2d24fb97cd258c8184188a7fe997b9d349c62dfcf912aa389156c4933f64c mainnet-00392-01eb08ec.era1 +48fa1fb93ea20714a26c5fec36c2ee0f15d198c215ce0bda2d2562f62fbd174c mainnet-00393-a5b5b2ed.era1 +8fad6ac037743de46833ea43a6ffd100a00b2cb9f3ad0407d54d0b03b28ed6fb mainnet-00394-c96f2c65.era1 +f8371e073362e9d543b36782ab258cd42eb87e2d6c683155b4e04624d495a088 mainnet-00395-c7c79169.era1 +9402bb75c8892c815493febc8ae569d52b6cd2bfabc75401522534093a436ae6 mainnet-00396-98f01c73.era1 +bc11672da09ff239535c8880d1083d41f982d147b737c143c149af770024bb3e mainnet-00397-ece428f5.era1 +f68cc56919983c2fdec4b8c8854e539abaaad4e9d4f3849cd378e2d41939efb2 mainnet-00398-15d52476.era1 +4088ac92ce31b46020624856191212f6d1b2f0489cc5c99d95fee4f770fece7f mainnet-00399-07f40278.era1 +24ebb117e879bdbe930c41e479cdac2ad4152ecaf2bc788358d53c6d6cfe044c mainnet-00400-837a78da.era1 +2d4314ad1f2ea766461a5bf829ba5bbac2d190847febc7b89a44aa3aa0e70ba7 mainnet-00401-f319bb85.era1 +34d577cae57e3e8fb2000127d0fc9c814248e6ca2af94d9ade2546c85ec311dc mainnet-00402-28918ded.era1 +d1b7d976d494fdd7290e9c4b910350a4ecc850520d072d3bf556b7051387792d mainnet-00403-8d3e10d5.era1 +bf34ec30154f19b6d6af35495519c0596f291c02a35e22f1cdb36dc37636a3b9 mainnet-00404-729d063e.era1 +37ef95e629c825838cd3aff096265ff3101c736a1dfabf789c30f0e8ee4bd955 mainnet-00405-3857def7.era1 +2f83546b46b79fafa526ed628b95b7ded32e5ebcc549e35cbef3454d9ef4d0da mainnet-00406-7be7d5cd.era1 +fb77db101bcde3e613657bef4451b71fd4dc123ea7f8909a5b89a716dc03a082 mainnet-00407-0a5da5b2.era1 +5415aa49b05054b0d5ff111cb47c56aaa56e9390565dd1187338a8d2f08cb9d6 mainnet-00408-4ef48eb4.era1 +2964715cd90a4f9c867a19fedb27e7e0000b7db7f83a452c8e1f43ff93ccd4b1 mainnet-00409-e4148ff7.era1 +5cf7d4cae5e6646d48c546f19a3704615dd40446d6f509a82a33c82894323a09 mainnet-00410-b195d1d0.era1 +54d28a8f851216be0cabea18dae1197194906b1586e767dc73b7388dea6153a7 mainnet-00411-ab2766df.era1 +db229733b6c4cb5f3870f5ddc0d810b73e33af7a75ccdb81d6b8cd3aa988531b mainnet-00412-4fcf3d8c.era1 +ad7e77249977c6d6d642a23dcca97c2f6053505567739a1f3dc01477c94f5a06 mainnet-00413-371970b0.era1 +90f77c70dcb0d58fe7ab36669fa8a5acbf6406c952738352cc84a99f723a59d8 mainnet-00414-7525f2ed.era1 +eb22fc6619ae6d605715d55ea954902aa31cb2f015ef4134af497a39e7cd7804 mainnet-00415-4820498a.era1 +a6fe2ff5ee3e391ab69c97d342aefe88ed2e2146870eab6569dd4516b2677866 mainnet-00416-55dcafa7.era1 +5b99127fbc5f6c24d4eac783462e2379bb7f4fc70909c43e829119e1d498fdb2 mainnet-00417-9a836cea.era1 +cd41a4ee69f5082e38f6307d6f2b94fd51dba629f8f9b41b49e068408a148e55 mainnet-00418-c5248447.era1 +037c937e58c4ce3959641aa241af4ccedf4db7c55e179c73e2da0ac45ba30fdd mainnet-00419-aa00e844.era1 +15d65319cdf5dc1e76c7aaf4e7109b048cdc2e4929d42dc6131259cdcd316c67 mainnet-00420-1a718263.era1 +18505aeee0cb67e5b08106145b4a17efbb9340d896450b789c9581629b1e859c mainnet-00421-b7a77195.era1 +edb813dbdce2343f9b75698a75b743e51c3a8414cd4488a3b78225802e8d8788 mainnet-00422-05e01b82.era1 +c18ae35aba240dbd82651d7387558b06cedb558f47598d0d369b3335174a76cc mainnet-00423-0c5c2035.era1 +547302236112ceaaae8a85ca0176d81dd79193b932174dffd6123267602ce9c1 mainnet-00424-7d31cd1a.era1 +12fb9063597f62079d3b445e4a927414f261875d793f326eb091d310a9d15436 mainnet-00425-737fc200.era1 +281d9c52930f84dcb7d3972d55eed330227c454f00348edfbf34aa505253c5f2 mainnet-00426-b042cd22.era1 +eb20f6e387d6c977608b08d9a3cbed74eed31ddd276b42986df8aecf851f535d mainnet-00427-a5f8fadb.era1 +529b620623c4d04588ef718211c3798085f63affa234d09863ebe201956911be mainnet-00428-2247adf4.era1 +149459f90e22f39ecd0b3747e0cccabfc1a7ff60ff3d3765a8a6e88d3ed3f95f mainnet-00429-1cae28d5.era1 +3a5a78a76eabf340bd230c91eeb74ca2188bb5a9a893c8c3c25d1958bf07c1bf mainnet-00430-ab59cee6.era1 +a0f6b0c0ee9e935cb32fe509023b99b74a914ed6b740929c766845bcdcea109d mainnet-00431-ed24090f.era1 +610414b9f4d5c298c54a145519e2d98f88f2ca17514430c1f30471e5d880db50 mainnet-00432-ecfb2f47.era1 +3ad76fa4ae6a1ed8d510673ce7d2875b6f956ff0c8cc1af3c4af647880f7a07e mainnet-00433-ea10cb3f.era1 +4fe2fd1182a72ae4e73f9b80480e02319d0a9e10e1ce939080fe3cb367ef907a mainnet-00434-ed8823c8.era1 +637b8cac56d8d9d2c13d1201cccecb24504ede7381ac3b8bab3500a8b7b3ef12 mainnet-00435-1acee0de.era1 +a6d101e7ae0f2f0ee20e7c5991acee4baa08a2480e0b6b61514868562cf2040b mainnet-00436-c3510bf4.era1 +5758607436d4abec5629c29e4de09018668c6f4e3372ade527d220e604c272aa mainnet-00437-f2dcc620.era1 +98a4c4a1624eeada42e5ab55e37de3c9303e692f2b29261637be5c23153245bd mainnet-00438-00f5e21d.era1 +18c0623aa3283174932fcedccb6be4a29ad6735cd2527091a7f5bd4a97240128 mainnet-00439-5149508d.era1 +7c3a144dda6e614f7897166a93374b12ecabf08eb001b5c91455c058c3d5c1bd mainnet-00440-9feb9189.era1 +5c8be22c7adf0f45b608fbd84f86a21289696d14b55988ba997fb11bd174f3e1 mainnet-00441-3f1832ca.era1 +e9c5db7bb9d23f65b7cc7189f2f562e910ecf45714ba134d5078e835d44c481f mainnet-00442-1d30de4a.era1 +a328f5ed715bb41631f1db499dd3cf5d5810492e65878e1313830209203cf3cc mainnet-00443-ea71b6f9.era1 +964f815a7fc2152daf9918cdfdc24742b564ed5a7c9053c7d57b2f55dbf756aa mainnet-00444-c56da958.era1 +b281e2c5e56f1eafa14af3e8b1c648512f15050d8aedb7d76a2ec04ff2e15f50 mainnet-00445-02cff3d7.era1 +8d1ac05b1efedef5c382bb6de1bf6bdbc8e1e048280e03c4ec177450d8665aa3 mainnet-00446-2280f1cf.era1 +4317a705b8a6ad0111850b6185c22cb3785fe58841cf13607bef0c208c0333b1 mainnet-00447-3cff32e3.era1 +5c691ceb14e8cb47a482a5420cabe8a7ec859136a989f47edd12cc451f3faeb9 mainnet-00448-7dd2c4f1.era1 +0abe1d8b735750b2004a10b0a1e6927afe8665a13539697982f2e8c21b6c0cfe mainnet-00449-6d1d274b.era1 +5bcdce9f1193f5da2c6e4be6263139486e95a35f0cf3ffce6d44afddf2726331 mainnet-00450-2b5e1149.era1 +a1a501000dc22c9b8ae03b9f7e4a93222393e170a7ae2827eb97224bc18cf76d mainnet-00451-4abe0e07.era1 +c9fba4cf9aa72ea9f74d9bdd08c694b807aeb480ffbadf04f939992fb2a3cea9 mainnet-00452-42606107.era1 +d2aa4df81dab672f50d3f79c98fec32ee7fcaa54cc1041be58a1834d37f347ea mainnet-00453-23cdebe0.era1 +231aaf7ca5c7ce0107aa1e8520273c18a82224b81f5daa2c98e58ebe5217b846 mainnet-00454-b2b5e5f9.era1 +eca2fb672e6c4fd0e90abb107e535a7bff18ce5c66cb8fce13b6f7dc3cdef58d mainnet-00455-54943c8b.era1 +f2030b4728d9dbb95e6c4a1796ef569c4a7fbbbedefa186f13bd13de303ca0a4 mainnet-00456-cab07908.era1 +a53b67150bd02d6ed966b436fc40e15a76c1185ffece264ccdbdbb068f264e2b mainnet-00457-82d06ed1.era1 +a32713a0a07a3c376d9507c1bff380a082096693dd38deebcb87ec71540124f2 mainnet-00458-2bff3cd7.era1 +451fda4aa67cde3221f2deb7f94e28562ea1d388d488bb77f925b645d8f474c6 mainnet-00459-29e03017.era1 +263844132e6617fbfe71c5aeb5de309aa811aaa8db3022cdd01963719a34dd01 mainnet-00460-6f2ddb12.era1 +5cea732f6df87faa2fcfa2e5abab525acc144d1135fca90c04777159b6a102b8 mainnet-00461-86535bae.era1 +ed2a2f0d305dcef66490a1258e1918f49b99e26ad74352bcdb54b41f38c8a011 mainnet-00462-3658342e.era1 +56ca521c6c281c5175ea66527e0fdc7280f4319c7d4afe9aafb0d4b36e9eec75 mainnet-00463-4f586d74.era1 +c3eb5333f6c002989114af2bd844c0e8e28e6f6e4407fea00e548138f577d720 mainnet-00464-2da57d6c.era1 +7f4c5ed20fbc6656ae5a8310037f16f15e9ca3d4d62d98cf7655c27c5d2240d3 mainnet-00465-afdd52d6.era1 +cca9cf85c9152b6c4eb1d0795ab121c4961553ad6e6613722be52a1a94c4a91d mainnet-00466-21cf05fb.era1 +bc875cadf0d713ccda036f1e2656be47d9f244a715e95990201bf6b47f4d92cd mainnet-00467-27685b9d.era1 +a903dfb595e8ea9d49ffb0e5b120f9cfebdc43b66ab797d406244f40aa61467f mainnet-00468-610466b6.era1 +28b570e840b71cf51b2cfe868a3cb1f0ed9588e0df5f4de7e2e6a5f8182170c2 mainnet-00469-8c5751e2.era1 +f655e24d6972690175ea4dc133e9d5e9b3f7837f3e17d2befbc7b9ba9c35dcea mainnet-00470-2e445b03.era1 +fb4c985a4bb83e274daa136dac66ffddbed69b6189b4ac219d40819e6625be74 mainnet-00471-7f375623.era1 +9df7017dc925a606786d780e02df664b12999b6dce1844a4a2dd2e59e9ff9a42 mainnet-00472-5f279db6.era1 +164d29232a4ef13a37b85d5149f6088b4472f2f43bc46b9e12ef6e9e02a8ed33 mainnet-00473-5ae48eae.era1 +414314c0e27330485dbcd2c689d3db8adf740672bef0cc19083cf3bba54905d3 mainnet-00474-8b70d9c8.era1 +68d098339c7a7d1dd941a6488fec8e969a08d6cea26b93c0cfb82fc1662f1d4e mainnet-00475-a8e53747.era1 +b1795e08edd0ec1a200504de3cb6d02c7dd796ac3c2a3836e7179724c06ea38f mainnet-00476-dd34a7c1.era1 +ded59ffaeabb0ee900fdee509f91296869fbdf48f534618cca664da1860769cc mainnet-00477-488d852f.era1 +982b4a076083a00ea755ecaa2e8e83772b451dad624d58a2abd65236fd7880bd mainnet-00478-232a4fc9.era1 +7cd6e8a704e5871f17fb1d5f3fe5988f90a6fb85b5930066239769d66aee0649 mainnet-00479-4b082f24.era1 +f5455ff560d2ad13510f307730c86674246a48a9417315c6afa02007a7b6ab6f mainnet-00480-b54b802e.era1 +0495187bc1dd5002de2c0eea40b7e8afa409881794ea806620638ae14a15aae4 mainnet-00481-213ae81b.era1 +14f00d8d7612f3dd621378a5733a5b1381a50aa8feb7f5f37e2451b57b1a78c6 mainnet-00482-5d09d6ee.era1 +9cf6cf9a7502fb5cb39c17261fddd3c9c75ed137d165df63e59e8d4e64e4e7bb mainnet-00483-f3c11c6e.era1 +12177883a5f8ad1203ebcea311e22fc6152f42162b14de0e1580c9c2a35b8d62 mainnet-00484-cdc41b84.era1 +3b402d38b246d3ce16eb13767165ee833d32d16f40f74585fedbbeb47f5d2e41 mainnet-00485-b26f2e53.era1 +2f9849026ef56ac144cf56e61b1ed5ece5ba0b513a66175fd7c16e364bf46802 mainnet-00486-82b8c438.era1 +513ff1109a8567db088e57f1eed1236b0bafa122539fe14f85ba2a3f70a08376 mainnet-00487-d834f157.era1 +51993f2f055177c99910a8cfd0af62a09e195d12aedadc8994f9b4b5e4c8acf1 mainnet-00488-fa3989a5.era1 +588a68e84b5483f3903528f998b4e294e0542eb025fea3d91716879156d60259 mainnet-00489-4db390c5.era1 +20a241cdb9315952d266f45aed67141fc5b0eed9610f609a563aed184bc450cf mainnet-00490-b9ad2e4d.era1 +3745f7942b2c1e0c254fe9eb051d59983e9ecdf74cf17c5acd11a1e35391965e mainnet-00491-6aa98f9f.era1 +5708622aac0ea34edc5ea2c6c40d323eb838101def39febbca203cabb7de3444 mainnet-00492-ebdcd70d.era1 +49beb4efcc4f515ce1c5f497114bf1c166d65c16d5b9c47ff2523934a86ada05 mainnet-00493-3079f625.era1 +87c21e393d2396c3a6d42ef7b1dc139b0c95b69c52edcc0c17d4a7aea83a9694 mainnet-00494-33f97b59.era1 +b64261ac3156a8cc499da652dfd909338399a957cbc8bdd2f0c8b792ed61357c mainnet-00495-ee3904ae.era1 +1dc0fdd218d106d7559d046e77b30992ca0926cd7307b95e4f8d0bfd3534ad17 mainnet-00496-cdf13c18.era1 +49801e34f60ed5986c876b6cc4ec010423a25e029eacc8c9b903dde8e6c58da7 mainnet-00497-27f7ad95.era1 +86b7545b74e9b6ff8d4f2272d2307c725043074d362c8ec669ddecfdb8e7f2fd mainnet-00498-fed48beb.era1 +44b03694c9c02c3038d22b134c2ec1caeb2c8802e9b350e76b1ffbb7e1806f24 mainnet-00499-d9c9a733.era1 +19af4c2cba365b97f2e8e04dbac106c8ae4880d434aefa7f373d143bc1e6fcfb mainnet-00500-b11653db.era1 +83be8e12e664ac4c6cb455f832c36a8537093a4b94ea9d4c45e96ac444f5a522 mainnet-00501-b202cc73.era1 +580ef812ed778ff77930be56d0a3b15ed6e1610aa9877a2a4656fd0e82819644 mainnet-00502-19ef7cc0.era1 +a52cf41b1d14b02ec3b1c70a8904a416370a15a1f014d1e63b5ee53d59ea1e8d mainnet-00503-45f20620.era1 +9655fa5d25014d2d47e21c6006cbd66ab29bfd3022edd282ac745e27a7161717 mainnet-00504-21e3a8f2.era1 +15385a304034611f7665e75df8c7efdef6b39de3af271cbbb23fb23ee9882695 mainnet-00505-6dd1ba56.era1 +f4feb4ae45164687d99f194a2377359f90a53c92dc5fdec01e386b6d82ab85f5 mainnet-00506-c0414076.era1 +b7108796a98dbca3865eb23d040f2f2bb7b81e5613363601b05e38007599d5d1 mainnet-00507-a7340f2e.era1 +3835eb369cf4a7c1d7f422a3533026d4c7f39e824c8db0fc5b06decc76f35f93 mainnet-00508-dde4c38d.era1 +58328611f7492611aba568c1b1bf881f0c4712047cda5e474dacc20a6f54b800 mainnet-00509-fa5dc42a.era1 +de13c1e15738b569e0f2e39d2ec188182dd1b607e3dd62806b98ed29f36e83d5 mainnet-00510-ea2b8d47.era1 +1f0af6eaf3908eac69ac0c7daacb17d012f8410cf500e178232af0d9b17d699e mainnet-00511-d5d2416f.era1 +85497cab605da0915dcd15f81784b6dea663f5823162ffe17ba9e51d5219ac64 mainnet-00512-e2918e50.era1 +f815f4014da4b936f60b4a597c4c73f381272b465a0c8ddb954cd20018983edb mainnet-00513-d39eefad.era1 +029afaabac6f5aa8249f971cefd3843166239f9cf087cda5b8ab7ee78774cea0 mainnet-00514-8bd8f6bd.era1 +9ecfaf77c345db1c7194277b1b7b52a3f7368df97003d7161f23554e39a962d8 mainnet-00515-66d4642e.era1 +01cd75539ae70d3ce141f22490a225c602f705df3a7e57db12428ff68768d342 mainnet-00516-ed3b1187.era1 +68ebb5b3d0d41e8c255d16a0a100b41272b74ac23a40c3f61c4ff30a4d53d2b4 mainnet-00517-5ef487b2.era1 +d5d7f46100a8ac2ccc7312c7f56e951555c14bcd9aef4faf4540c2fac3005487 mainnet-00518-71027029.era1 +773e464730bc33535b0795c24c47eae3f75dad5661f7cb9e3a723fa7737d2afa mainnet-00519-218c3b62.era1 +73c2ec4fd8b5ab8fd994866d5ea905e02f589f0bfd17c62b60586b5e90faaa3e mainnet-00520-062e1719.era1 +c4b190b473cbeedbf892d2d3c081360df71b038997e0466820fbf39796fb2f13 mainnet-00521-5b55367f.era1 +433aea03dfe9a761ea95d8fb326d545596a6b6ae24af3bee9b9c7e5abae43367 mainnet-00522-dbca1ed3.era1 +3c279449419da666df1e2c8edc9adbfa3f6c2481921b0f0541e03e19db77dccb mainnet-00523-297cf9d5.era1 +3a1a62e5fc02eca3e2061ca7ec0ed5561dfa031bdb104cde4419d6841ee59e43 mainnet-00524-f389f3b6.era1 +1cd54284de4fbbcd0b9d60eeb837b50f91f92b167034e4c44941ec5a6556cd1b mainnet-00525-d851e822.era1 +bf17ca4be7cb2c307fb5f13f295a20b448d819928ea5c588072f6da9ff2e3400 mainnet-00526-c69972a1.era1 +05e4db40af70a7e78ee362faaf381b877a7add46e3ce1f51ae7bbf1e9fa26ea0 mainnet-00527-2c103256.era1 +3a6ee2131b8b4283d1a30f2b1137106c461d0c26e3d018c8dab506b06d87daaa mainnet-00528-32a674ae.era1 +ce09d7816ef22ce8e0431f1a482febbba259a4e28fe7cfc486441bb41d70446c mainnet-00529-1bf711d1.era1 +7e9d28e51f686b6a1012942281ab8bc0b410784d2bed7f7c987a35bcaeebd904 mainnet-00530-aab9d4e3.era1 +26104ebb607588e04ce2323c4b3891f9cab06244fefb505609acc622cc40f749 mainnet-00531-0f51dbca.era1 +120499bd51f65e76117aca0674c8cff513589f3274ef70b183d170ca4f806728 mainnet-00532-b4c6703d.era1 +eaee56370a0bdb1309d4c2ff52fe804e7d2164b5469c8b72c4957ce8171586a7 mainnet-00533-bb2932ed.era1 +2e6cd452bc720c247941118e8a0047a3c7ebe561b87bc975bf87b195d7a64bd9 mainnet-00534-c65d109d.era1 +f0a6b2bfff8e75bc5e804bcf9c0363ffd19ef9e8ee45cc132fae638b77e23bd3 mainnet-00535-bb367122.era1 +30cdaf9922f008643dbcde8528730c0dc30799d34a43e2df58eaa53210e2434e mainnet-00536-faadd066.era1 +f874f4faeca9a98e5601a53898d2102617e9c0c57738ff691766c78139611c8e mainnet-00537-576b374c.era1 +f0783e7c936d1b71d19bb4abe24e8a1e7e70f06b65d2ec7f7e8a00bdf0d0f1ac mainnet-00538-d8eab6c1.era1 +7e5262ba5514aaf42edd137db7587cde57279d90b43eba05b9b4cb6a866989f2 mainnet-00539-2c32d06d.era1 +058a5cb9e04e96861a4821b42d087c6f876dcb65119f8e40df0d79e06018a013 mainnet-00540-f3078a9b.era1 +21636685ef41978eb7a796969d98ff8c4582021b47f204b2e21f93652f1f410f mainnet-00541-3063ad60.era1 +501ddb0a72f282a9c0c04252eb7aff752b3b7d1336f832713a11a0fb17bce918 mainnet-00542-90a242f8.era1 +121e55143583932220273c895e9eedce10620c044f0f5431550cdf5571d9928d mainnet-00543-be9dd353.era1 +f3e298a94342fea1557770766082e47347e48a1b219e91791534e56dd7d88a26 mainnet-00544-1c5c7615.era1 +4285a6021c374cc02e0b7317e1a069e8a3ec1dde760b901a7c542e92d97e7636 mainnet-00545-e6369239.era1 +1d7616d952fb561b06d1fa898c8c3849cd66351755bf56d7d3ebf2cbc4f7f058 mainnet-00546-21351413.era1 +91a8417bbde8372258e4ea7403e9e711d0df6fd722be8b2e73494b0359eb90e1 mainnet-00547-0fd9e031.era1 +84cd049065fe0f7f39f23d3c96d81f59a54a94170ef4632429326082a8ca3a6d mainnet-00548-e318be79.era1 +4d5332a037b993314883f3e274e139314a7b8d2c916cedaaf535cf7ca04e0b70 mainnet-00549-2dde72e5.era1 +73dd18877d5cb50629c1043ac51fe95b9cff600494a4cedbf5aafc45a09b5abd mainnet-00550-d89b717d.era1 +8cacc8487d8342e2aa6c4642b0e14585797448d0a29a377d00719f768bf17cb4 mainnet-00551-a8dfd860.era1 +1ea0ddf1d4a156cc3c5d055fe0e90516669f80b29265222815d54bcbb1257d7b mainnet-00552-d6a3521a.era1 +afb3063c25115627793da7620d1f118548789a2d34d8efb175d8aa51aafcea70 mainnet-00553-f702584d.era1 +746d867c504c5b0cbe642f9566dfb007fb4a3184fed3811a49c38b05dfe34006 mainnet-00554-700d58da.era1 +1186a9337ad0b4c9c2335817e5e1f6b7359093ad3da2a40cd108d1e6537c856f mainnet-00555-41db6d14.era1 +63aef838d5c3f9acff8e3b678dd9248b6e2464d6e5085cba0a2dbe37a5623922 mainnet-00556-3503dd53.era1 +6b779cede943e8d4cd55da81fb9ae43faed525d0bc25e9bd2f2b94ca6d478121 mainnet-00557-02391085.era1 +9ce299b548477737341d6591775f8967ae4f09b5bf1f23baf8c477838eb9c364 mainnet-00558-ed670fa9.era1 +e7cba63e763a2fa24ab9d76c54104d1f2deb017ee5083595c10278e7281e0c45 mainnet-00559-63277435.era1 +3361e01e4e11b8ea2f6867edefa813195b9e3c67ee01d0883788932b85285c09 mainnet-00560-e89160d7.era1 +3fb208b1a30c3cb39954a8f7403c4ffaa5d4bcdfa967ae6d0d83d807a885831f mainnet-00561-f95c755f.era1 +076eec9208a1a7c1f2f3575c2eb52cfcc98ceef632aef8cea724c1be4e1fabeb mainnet-00562-97a6fdba.era1 +864299fa4f4daf4d0c48230f831a70592fd2b854ebf0b7bafeb1a1b5634df17c mainnet-00563-8aa6ac0e.era1 +2c32656b7c27705a4807c827bc3545d11f2fbcf7146c29518937fb89f3ef8968 mainnet-00564-ba8486b8.era1 +7c7fd609e45de5491e46be7ea7ccd097b208fc2c88e16980c4426dd7205a8031 mainnet-00565-7cba894e.era1 +2f42a73fa8eaf0c1c0dc53f8727c5fa579ea4d4b4eb838bfe9cc61d7c0f92fea mainnet-00566-54b3e34b.era1 +e15a38d740ab95ddab6d31f2a4d1419ec17a463a2e6e77fca9efdd78c29c260d mainnet-00567-40280a85.era1 +0da2dc7c686f59ef96b2db151f763480d3a881645c8bf431f4dcdb996d0818b1 mainnet-00568-ad863b1e.era1 +de95cf0a8e2d4ba416296a179d17e1c3206e2fc537075460193979f67cf888b2 mainnet-00569-dcb283ea.era1 +3fa3cedaab307b161d1a8a6317ba34f15a1239e3cc30749192004d7daa1653b6 mainnet-00570-fb912362.era1 +ff4d8628fb67ca2337f55f92f9d1c23602e5e4db51d6df8e209e8900087a9263 mainnet-00571-b65f3342.era1 +1ad917e8e7a61f0833399945c9e687a65e7802309edd9ecb37421d3e8d1bdc4a mainnet-00572-dc59179d.era1 +24471e846f24c62c93f126d7501cae75867f791a8129dd97a8a1a7680635e386 mainnet-00573-21aec308.era1 +d9b8550a87770cc0afdba48e976d6e122ea136a7071177c6e4f13fd393e794c3 mainnet-00574-55e72fc9.era1 +f04623ddb0eb35b6be08f15e0e8b44ffaab1d8c3da87f7bd30bf1355f4471752 mainnet-00575-f6564eb5.era1 +f651f045ea114e31eb027b82d7531167fe65c4004286ee8555e8f03c4f8ef161 mainnet-00576-923096d4.era1 +fd857476eeb1af8743993fbd0608cae7aa1c14c757db07e4c9198378a77d13e2 mainnet-00577-5914605d.era1 +b061083da7a861c1bf7d58da0913ce7e28d09412d0b10e43e1ef600607066a2d mainnet-00578-57d591a8.era1 +06e5104850d19d3369d8499ccc590b98374f563d2ea77a10c6292cfecd20f4c0 mainnet-00579-705b8e04.era1 +4ee6f9ce5e5cda1381faebefb06c6696cb02ab2c6cc9a8c1692b398f0c4f0f36 mainnet-00580-5b210184.era1 +aa6ea1063f36beae91cb1dc14f1e758c945e1b1435837c4c974fa183ecd5b766 mainnet-00581-d3dc3f99.era1 +f0da6705ad1a4ec97a2e877ef9e4faa3f7592d04fd06e813bbad77c55f670b7b mainnet-00582-d6b2c7ef.era1 +d15b9640646d0a3f7ca5c96ff12f2439b0a0b25488c8e82eb381adb7b1e21925 mainnet-00583-43400160.era1 +6a111a0d8631dc36365127b5b86267c413fd7a6836e56d5eca1026495f4bd143 mainnet-00584-21b2682b.era1 +4f5ce93c8872a6ee42dcea100b0543d6f37c4af82a7a87ca7b0cb289c8a7cfd1 mainnet-00585-02f0b151.era1 +d3ebdaeca270a0fd7ce27195d6f227993de02e775b11d7ff3ade7d6ec3ac8032 mainnet-00586-60d868cb.era1 +ecad45bc22fa043a181d656b0270ac4f45c232f2eac5a54fa12242db64bfb0eb mainnet-00587-59cc91f7.era1 +4a6a589355b5cc0fdfea3adf27751370f32a9a1c911ce760d83c587c20f25207 mainnet-00588-efefa87c.era1 +9463605b6b5f6cf4c7b0a888d9e43409f6e97f7733165349fb01773fee6ddb5e mainnet-00589-85c8dc20.era1 +0f1526ef098bd10ff59ea57c283dbfd2195824748b83d80c6fda5686b7c76851 mainnet-00590-2bd79cac.era1 +146f1df8637311b2f1fbf58cfdc3e8c6d3c82e9064ddf55cd7623f2f27dda77c mainnet-00591-d9b21bd9.era1 +c92cf6a221783f9acd08c79e6130f4362ab25b871127705d9424b7bea0246020 mainnet-00592-9dd2dc6a.era1 +847870a9fb4096ea2dd1f297a2151187d68100cb6f07f777e3220ba40b41ffa9 mainnet-00593-0a9de411.era1 +6f31046df50e4ebceac9e592b488ac7bfd49952661cfd3664888b5c0760da0f1 mainnet-00594-54bb5026.era1 +c3dd517701c421643251fc581192ef1b111b1ecf45c0fa3dc568f53488c94bf8 mainnet-00595-08fa2659.era1 +38d4e79e4e3524b054563e35b497aee9931b88ed0aa642114ec8a0cb385c30bb mainnet-00596-5e2423f9.era1 +b0b62ee0c0830fbb9aaf7f500cf2d7d636532aaa4200fa7ac5095a681454712d mainnet-00597-49b11d14.era1 +491ec13b3ef1ad873607254933d7f894f9257cfde114ea633074acc71f67f675 mainnet-00598-050d0b97.era1 +b705e64cb2580dbe83c38e4220cd1a0420b29a99e94d888c3436d6dfe8763211 mainnet-00599-a19b1a20.era1 +5867f93ea1a0462fcfed3038757464c0c932a713c1ab9ef5c5639aeba80f3da9 mainnet-00600-a81ae85f.era1 +eb9f78165da14363c498cb339eddbb2c6766c00b4c033f7b99bd593670ef7b72 mainnet-00601-9e26205a.era1 +3c95474d17a48074ed8545c42927f086b6adb1d59d0fb6bedaf189309c9608be mainnet-00602-28713614.era1 +61b4b1139697c6282a6328a9d146307e98c52c2c7db51723e7046d3fb0588713 mainnet-00603-9a115bef.era1 +05a250272371db23f2c5a391d11bc2856b803855121163e326d2de556644149e mainnet-00604-ba62e002.era1 +033a4bf1b53f3d04f903df7cbcdb883a0eb407c65fbd274e554858909f0feec8 mainnet-00605-0d936f16.era1 +9a5db5eab59797b36203aa0276246d973e663d45850c9f0c2b56d1cb6bbad1b3 mainnet-00606-ae859b84.era1 +1a5d3e0a9cccc60d553a6ba1646f18a07c280e918159e72654ecd347277d42c1 mainnet-00607-62d75fce.era1 +1977fd6f4e3fe0c278c8ca04e46b79314ec07d02e885827ff5d72e3891556187 mainnet-00608-d449c48d.era1 +266f2d868f41878223d57b167b555447610fdcaea375bd1c40bbcac087c10470 mainnet-00609-7e60445e.era1 +0cd85b03694239516f90edd8a59d6ec9385aadbfd28d2ba3cb49a21a0aaaaaf2 mainnet-00610-2f230cba.era1 +b128c7ac9d8f20541803ccce5cfa6b7a49804b1d115ccc0b44ca023a6749aa4c mainnet-00611-290b8c2b.era1 +958cddccb94723db4013a8e54259897fa91df9c3c56d0dcbbba3e753b2e73290 mainnet-00612-b363f647.era1 +b0f6977d0c4dc7b8c288a5dbdc30b314443c6b2ca1aa6de9cd065097dec96c41 mainnet-00613-80a4144c.era1 +6eacd8cc703e153abd9d63b128c4f442fd90935b5f6344169755252369a79b2d mainnet-00614-20913bde.era1 +027d09aa99250322cae4c2f6a4033252d3b787dc7cfebc6f51077b554ce3ae76 mainnet-00615-8b6e7a1e.era1 +e8e5a7f53abb982b9f658cfe7def2aba43caee175d5e053ea748656fc6a330aa mainnet-00616-bd35481a.era1 +e661d9a123138573e618f8251c46675c9094a76c3533852c5d54206c74a47d15 mainnet-00617-624ad401.era1 +3e10672b6ffb5a6bcc59420b2d5c155a87066b033883f9b8e668942298439d5e mainnet-00618-c70c6f7e.era1 +dabd9d6332a1c1f429e5b581fc73ab595d6c667ecc4598c4f1c250ebff4c1c27 mainnet-00619-1b807ced.era1 +0c9d1874174ea831bdbf74616811eae0794a0c881e8b08078dd6851733de7773 mainnet-00620-85065023.era1 +17e8e3a04b8bd7bd414b5bc25c4c9f66ae524337a4354a612f49bb4f74734945 mainnet-00621-385fbb21.era1 +d99a5e65a0f80a12fdb3b0b3c745ddec6e5312c3364ef46485c06d9748af97ad mainnet-00622-92fb5e57.era1 +3026bd1407e02493df937cf5d57e67421b94284780874ab475962071712a4bdb mainnet-00623-642081dd.era1 +31e47742ac21fcb1b121c86130c4f044aacc13abb7df3c67dac7a442a1adb3c2 mainnet-00624-1d72d627.era1 +941fe056f09b29ff179be410567e07fcee1ca191d0599ceaf869c336891d5174 mainnet-00625-f7ca7cb8.era1 +d31fe29f030c01f7e49ae70472def2ecb1872608a23549ccfe521c02b4b282ae mainnet-00626-4f92dd26.era1 +9574994c5d43c9b2aef288b599c29a52ae4f942bfb6d05e5b75b351fc84f2798 mainnet-00627-06e70723.era1 +c8815a923482ecbc634ee658595e5333bcca9c53aba119d288090c4437013b8a mainnet-00628-313cbe43.era1 +5f7da2352308eb1274e73800cddd672f8ffeb1cfddd3574d780dc31b1d5e69f8 mainnet-00629-e939c151.era1 +207244939f8f19921eff5064ca9f109debe695a697464dc5c7779b587c60f8be mainnet-00630-1fbd3e9a.era1 +80128ec9240a841bae7d883ca736a923014907b5529c71ccca0204285b4cb7f7 mainnet-00631-333c0583.era1 +8c558409dd45ebf8633fe459a03180f3a141ef56ee355e99ab615c6ab6feeed1 mainnet-00632-bd6027f3.era1 +88db31cb6128b4de50ebc719bf28ef010a103214427e5c37e568cd42a493d946 mainnet-00633-2fc5d74d.era1 +32c8e4076799588f1cd35559ef2830058d7f776da6874231b83b46eaab84282e mainnet-00634-5b3c9d59.era1 +72fbcafc97d51ef4cd15dc5a2cb7a954cfe497554f1486ba69d9748a2ca21ea8 mainnet-00635-95e4dede.era1 +932eb65ac3753538380a3b2f1ae3be2a56fb93db259771c3ba24c7fe5d978de9 mainnet-00636-f8124b1e.era1 +5adbe1f6170a9cc09f96267601bc4076e350ad36760e207c69ada235c157a09a mainnet-00637-12daf758.era1 +599e56da4c0cfe52eac27a988679cec886cbc64038bc1a9f3989c61e660f758a mainnet-00638-75957ec2.era1 +6cac0942b944eba26ef6f87fd9529f35bd340127744ec1fe58414e823ce548ae mainnet-00639-7c4f218a.era1 +de762fc2f9932b012470f51da960775a5323924b62e9055a05ec6792a16647bd mainnet-00640-3cdc6132.era1 +afb93a2efb314c5df655789296901dbc0ef0411534d44d0b22ac355118f546c6 mainnet-00641-471f9e80.era1 +349f4285db586f9cd6e3b0e86ca25e0b500e9802c9523405c453e8753850f92a mainnet-00642-551764bd.era1 +1e8cd0ea9699d6bd1a3cf0a4a41f6f20857c72f78d5774c3e0835fb96e8c2820 mainnet-00643-368d4f6f.era1 +de6b4dfbca85c05979a61d538283bfd63068471487561a826bd6549208e36b89 mainnet-00644-81a7c3da.era1 +afc34e2bcbc18f2b3baf86aad08cb934b08322168564f3a57db8cfaee4bfc0b3 mainnet-00645-2582b644.era1 +7e58250e2a5bbd7e4737dbd0f028fa972519d6a4c16474b7a2987ba93f6c6f79 mainnet-00646-7fd3548a.era1 +de98a8249f13257740e2a39381933eb4f0050452889037c6ca4219e874ef7193 mainnet-00647-07e93c81.era1 +cabee428d74add0d820ce6fcf617f36dde5408a25c627d15c1c76a64b57dc94d mainnet-00648-01a981a6.era1 +257deed1d444ca8c838fb953c08846dbe6ea5de22b5d26ae9ea243c6a8c3f0ef mainnet-00649-05bf160d.era1 +57eb9ff0d06f758af8739d12aed01a8d750d5f19ff18fb41355f78a6da428703 mainnet-00650-119bef0c.era1 +cd625575d5f2a3b546b1801cb31de9854d592790d50527bd43a433525335005b mainnet-00651-4d3f0b82.era1 +87202ccda9b11225a8d097e495b1f62681206cce56e81600f22e4057858361b8 mainnet-00652-730975c7.era1 +3a1052f205840ca993bbc3225667b593aa5479f7d80cc3b27bfba4b07fa8de07 mainnet-00653-2eb89f05.era1 +95ab2a49aa68595de236f97733f6b99c22a8b7fe43f512e3ecdd896f2d84b9c7 mainnet-00654-51b0bde3.era1 +8d4c7eb3aaee1522398a5e232ef4febf4027f3c236502885faa891e9a00ebbf3 mainnet-00655-06381406.era1 +aa49d7868cb14727d5bbed6e8d48290af874c9feec7abc6524c967fd649fddcf mainnet-00656-0c072423.era1 +f52ebbc585811c9c26d15986ec927122c88eb1b840746a3ebc831cee403bf02a mainnet-00657-4b0dfe65.era1 +4d28f6ff21fb6fc3448d7bbf0cd7e7c92a2df8a339df0259400b4cdde6f3ffa1 mainnet-00658-eafc91b6.era1 +3fe97ada56a3ecd29920cc28f088817fc384e4de1028991566f4ca46b7cb9fb0 mainnet-00659-49e7399f.era1 +12abdfae11202056ebe3a89d1fbe165aef5ed2b4bb83608e249674f5323eb211 mainnet-00660-376add4f.era1 +2157bf342557f8400a1dd5fe4ba08105d8e97788469c25a69fa7df9d1bb147a5 mainnet-00661-a8a70e6e.era1 +4cceef1dfd6ca6fcf875461813ca98582b5cc6bc3fdb178c8003f6b88776e637 mainnet-00662-dffecb3c.era1 +defe253696a6266c6fab5c8ebc6f5539bab56bbbca80e6897b603704c20d5da7 mainnet-00663-6c4ef261.era1 +e292d90ffad574c26f88140a0fb3adeb6e0feeb42926fb2185ec13ded5dde951 mainnet-00664-3eb2993d.era1 +f6d998485da74f49e00218f4fdb9783c3a7d51192958c020a6f49aaf2edc6dc4 mainnet-00665-8f406786.era1 +e582415262cbc5638f27219f51c9540fcf6cb8e30ab8d629f205f965c58bfdc7 mainnet-00666-4ed7ee7f.era1 +327cb6bb9586ef1cd5776c856e0b838044fcb12beaa4b986066585f9b20a1ff5 mainnet-00667-a6b898d4.era1 +1cad75fb6ad6e754db1b3853171fd4eddd48479b92769162a0602014b090c094 mainnet-00668-c4a9d166.era1 +e22ac2e3c703357e2c18b04b19ea413697538ffc1acf84d87c386d1d9af08836 mainnet-00669-d8d97842.era1 +372ad46d1309e2c31bca31da93d1993bdd42b3ec5cfb16cea5a4cb7e3253658e mainnet-00670-be3afc5c.era1 +2c2682a6baa86d8bd465e124cc488c94b0d151d6fe942fcf6e8bf073ac445cec mainnet-00671-bf138a26.era1 +43124aaaa3f46a7505a988731de60b0f095c3a119184ec8463b93a13d8f8fb8f mainnet-00672-bf106779.era1 +38b7dd5161b825fcf13b8c84e6f885576dc748e73cb9cc3417419ff738591bc8 mainnet-00673-defe7756.era1 +a48ded2af1b573fe6574124093f7f070bc374ee339e9b68a2f512455e26fc77c mainnet-00674-c6dc6388.era1 +4491cf363abfbb3c9f7c4c58013facc62788946fd9bf36b0717d28d03d5b8798 mainnet-00675-1e729aa1.era1 +c4c629a38e80616f50c9c79457ffb31169e1db56798c9aa6467ef47db2be6698 mainnet-00676-a5855d98.era1 +aed81eb7e8722c02febe53bc640645d76a03176a96ca2716828504c0b35c20cc mainnet-00677-f3e17cb0.era1 +b7193ec008a5f6ad77cb2d38e25382491e519652068c2bd8b8424a99ff672eed mainnet-00678-42e73724.era1 +9703fd0c87a1b44fb78073d64f25b680bbb1231436be09153898a1562ce54a0f mainnet-00679-f0fc97a5.era1 +df514a67472e6534e222756e1fa51f300e90b1a939b33401df6e72d5056612b0 mainnet-00680-a6045d36.era1 +c09ca9581d1b07bc6e6a2fb949dd21ff1d985c35c4e453cbaf4e108209cfb117 mainnet-00681-247222f0.era1 +5e7b3b9e90efc074faafa91a1d9a2d59f5260bb27b9a42259e6d5e4722a0047d mainnet-00682-a6b3aedb.era1 +db451ff45d68afeabf0b0230635f246e901c1cedf3280207ac615ff62561fcbc mainnet-00683-19fcceed.era1 +67e85a3ffd3881dd4f3c8bf608e78e8dd3003fb0e52d61815aaa6f0385df9911 mainnet-00684-388b0bdc.era1 +7e8bc25827cdd3ba2e5388fa49d4b3f0fc07d1c02b6e4231a8a9348150d0ac02 mainnet-00685-a2bcc3dd.era1 +c97ac912960f05cd5f6fe586a23d3b0822a5acf5073de8d87af1e892270d3c1e mainnet-00686-df515337.era1 +8a61444d3779778eda326b26ab0d38f92bd5854c60e8287ffe51d90f4310e4ae mainnet-00687-89774425.era1 +188794b31490a304267a019775cf6ee50619885d4a637aefab85c2e589051793 mainnet-00688-a979df6f.era1 +f4c53896dfebcb9fea054ac87fad4ebe6edeb0626ecbdf968e71a94ac03c037f mainnet-00689-33e5fa30.era1 +0f975a96a671fbe2cb3da544eb92c0531120ab966661568470b8d7996bcc071b mainnet-00690-7c95061f.era1 +91c003334447afce06ed484e69166c2d8a80692cb99ec9e223328825177233a3 mainnet-00691-062b4177.era1 +1a0679af4a788eac614047b0c7f7d5286d285ef23d2729518cf05e1e62086622 mainnet-00692-945645ca.era1 +ed2e41823a39f3913774790dd3f7cca12a862bb327243ab5d3d327f64aeee0eb mainnet-00693-8c6754fd.era1 +6a9f6d5784fc19aa2795e0f7169824ce3be94f328a8e08c991c7527030152649 mainnet-00694-222e02bc.era1 +11f48d72bc9f0ee8fd0ed8ecc58604da4c2acd1474e77956111c93b01d19a8f0 mainnet-00695-cebc5a0e.era1 +169be7b45abddc01bbf49a7dcd3a91bf7de2272e80cf08dcdbbb636c23e43046 mainnet-00696-f73fca1b.era1 +f01589a9225cc431608eaee63a9b5eb2af6ff1d2268d50e9abf3aeffef99938d mainnet-00697-cc3b1831.era1 +9959539b491fefc82aa849676da42da17c25bbf7c004ff2889fde60659304d77 mainnet-00698-062461df.era1 +aaa7490ab9125230ab58d21840f5a645460e58c94a50264aacdc41406258edb3 mainnet-00699-7dcae2e8.era1 +b18c1e7c0569f12199080c43ac67f26f7129db745fa82767e9979a6128014448 mainnet-00700-64f029a9.era1 +529130a29dba8fd6fc9423ddcd3cbd2350f3038e75d00ed2932728ddc79b34e9 mainnet-00701-c0ae757b.era1 +1d79be36536d3a481a961ea9d31228a07734a04454258968944ab85a70ff8b15 mainnet-00702-abe351f7.era1 +0649eb04c5f994176702911403dce6e76d9ab9cb3646b0cc9900fd1da5456319 mainnet-00703-ddee734c.era1 +647f0d18ab11581d96ba1ec39a8fc39463b97fe456ffb39b9a38588d8ff0bfbb mainnet-00704-2ea464e9.era1 +d79091de53ddcd1f1428615058f9ece31916858ce935dc0b9faf833128efd8b3 mainnet-00705-9f0bc9d6.era1 +759196c48a51d500c1059d1050d7d11c4019f9a01b465c43c6c4f97d06f2a116 mainnet-00706-58568eed.era1 +fcdb249290108031e8552ccefd4e85d227a1dccfbd760551bde1bb1b6bb07588 mainnet-00707-6aca1899.era1 +b4e811a52bfceacd836304f5e6b2b63d8ca05e417d095d0b81a79d7f07289a3b mainnet-00708-2478502c.era1 +4c24a09dfe7fdfb5d2dd6b7b8043b85ae1691a708f96079d31163427a2f78bb4 mainnet-00709-07426af0.era1 +b222ec65ca7e78c42b025a003bbb7ba4b82a7ef665a8df6f2b2b19ebcd171087 mainnet-00710-a70b753c.era1 +9c9476146babdbf7cfbfcc85755e97c9a1dcfc41cd93488adca9d230e8c1d35c mainnet-00711-1146e2f9.era1 +facfe2ab8f519ecf4622a2a25af984cb7fc8b7300cc18c6d34f6d721bed02dd9 mainnet-00712-560a8119.era1 +20eb96472a2f5a26e5cf3c48cccbbfeba111fa563bad6fc62db37752c3ef12e4 mainnet-00713-54d9396e.era1 +4fa11aa49d6bdd34abcff3b98475b59fb6ff04309a26142b5a7ebe5ff7dd20a4 mainnet-00714-8979cc56.era1 +efcf6d2d45ac3fa094630cf95c03a841956002005fc61a8e282ac6295054c1e0 mainnet-00715-1a583ca6.era1 +f0735f3cfe7e989cc47f4fe90bfbce7f8825fa0283239b0678a0da00b7003595 mainnet-00716-4850905c.era1 +43477645f9faaf6d860e4db56b65f8b96c67133e6833bd7914f6b5efb09210aa mainnet-00717-f510edaa.era1 +cba1ea26f8f8bc454bbe630aadaa7a1cdce945a86ef441627dae86049c836807 mainnet-00718-511c0a35.era1 +11b10200113c145e9c396eb86feb639d753f16c8ac27c5bb568e06d6895b2597 mainnet-00719-14409e14.era1 +4e7715a873ab9019ba4b3ea66cff451602b4764c151a94df5556a70b77b96930 mainnet-00720-cf91e8a7.era1 +5e6036eb5134080ede07fb7e6a731eec2e5e88f220b54e0caffa8fbea6442f77 mainnet-00721-aa869587.era1 +c06d8a0d579be2c487591b9e7e068bfe3b2348ee6e38ea94eb096202b4f79747 mainnet-00722-96e85fdb.era1 +f6f2737160322c926e85fb2dddb66ee382bfdbcd36696b864756b2c69829f23f mainnet-00723-78bf01d3.era1 +45080dca125923a0b07c3539e13dcb431851e1cf19ae911916fecdd8331cc0cc mainnet-00724-d7c27830.era1 +1a072571138c6b6dfb3fc4c89169e4b240a53c3d516fb12158b50d90e1d51af8 mainnet-00725-8859c97f.era1 +47c32c2917e15ed6775575b9ee53139abb572a04ce3c3b502659f5cfeca8a506 mainnet-00726-a705da9b.era1 +aa884f208d403cacee04f18685198ba1b049e951ed9d4c3226c02286e98f0ed8 mainnet-00727-58d83126.era1 +0baeafe4a53271e53c5d745cce806aba8d169839df6f40224a1bb0b924012c32 mainnet-00728-2daec931.era1 +ac3cd8a41130765fa97b54e59f1b61c8f7890c0b6de0ff7bc63e5b960d329888 mainnet-00729-fe141ac7.era1 +403acdd0eee9567602d404dc27aa0aa43dbbe5813e9d07c33c6dc04542fefaa4 mainnet-00730-4ab51ad5.era1 +81f2a1dcce251e910a6b2616235ac1c9718c4d4dee628430c76d4eb67e1e9c2c mainnet-00731-11b0f603.era1 +39d7e4c8d1f909dc9926481ae7b41210fc34fa9c1d3eb8c7d21b972e7f16ecf8 mainnet-00732-3e648126.era1 +a4ca4269db030f9983932fb80c52d86cbee645cf55585f8e96c8310fbdf2e767 mainnet-00733-87195980.era1 +a05161b11cbbd92e96b8734514dae7e41fb32ac53f760a5656d48e500b3eabc2 mainnet-00734-1a924a1b.era1 +757b374c13193263d38ee688ce99be309cb138aefa1382d3ee9c46fe34f140d1 mainnet-00735-34d9d6a7.era1 +e0b1341fd91ae23aaa8fe6422cca6b4136c2ae01f9d5eaad479ed6cbf7dda434 mainnet-00736-1569f88b.era1 +5278b2c6a98464ee7cf44ef2783ea83a7b797278a5fe0dd37c29de437d674b68 mainnet-00737-288181ee.era1 +5d106d493c40c900f9dd36f10f7cbaf382722bf259c1e597ab55bad31d979439 mainnet-00738-28dbb0e5.era1 +ef9dc3b4e683d35dfad3ada4e18074d1aa6eda4b7d5852e932014d2a6e9d262c mainnet-00739-4bd79b88.era1 +234b110d1c89edcfb76b887e7d38b1697a4e6b477521e2dfb6d23cfff7f509ec mainnet-00740-c84ee780.era1 +454006b0104087dd6f2a855b831284641b8ed3a581fd5d22f893ad647799a447 mainnet-00741-2aacc622.era1 +36f9e4340000b17fee5a60aaa8b027f6b6b0868729044fdd348fa956b402ca5a mainnet-00742-165aa7d2.era1 +f2fd1d7559677afe1687761b169792823d1711db640bc8f4c7142b5de856fd61 mainnet-00743-4505bedc.era1 +d6259ca729eb889b9d4a877364fabccb6b6598f996f92ed999108c6e0a8f4b0d mainnet-00744-08785ac9.era1 +951d9d6d312df5215e226ff147e65ef4b9c478357b34cad24fb092c49366ff83 mainnet-00745-6ea3cb82.era1 +00cdc00c7b037f9fec4025bb005dc4fdb10d844abf664095b5624cb121d3d253 mainnet-00746-3ec58c85.era1 +aeed399dfddb49eb56ed6c4fc985de8e1239a0156e304225a7fbf1e42b53152e mainnet-00747-aaaebe5b.era1 +f0127615e787afdf46e2f0e9f521852c4925d02067dc2b53817c2e787a5bc208 mainnet-00748-5ab3b222.era1 +e618e9d6c36cd81075adfd4720f08decd11d117dc729b486e374ba675a1f8fb4 mainnet-00749-27aebfb9.era1 +69ae574192e47b15950c6bfef28c3a35bd96c77c6d461f32e6648cbec47a5994 mainnet-00750-cc08abf8.era1 +5184e0347b27b7c2846a7cc9d8d56f58d1c868c0ca8c750f65d5abf7a92a7db0 mainnet-00751-032ebacd.era1 +73dfcd6412f043002eeede1e22b59fd8e7c2d38375105fe48e2f60f8d2b17aac mainnet-00752-f09c12bf.era1 +af231b7d2be6ca761ce05e0839242505d5ecd15e363b81bdcde0cd2c99326c19 mainnet-00753-876733dd.era1 +edb3b762bf7f179c9415c0b4d9d8b849cd01df99fff8d72350e3aa530c726649 mainnet-00754-f50f5eb2.era1 +c96ad2aabd39d9cb790f32a4c2e9aa24ba8877ce3489abbed79cbd85d261bee3 mainnet-00755-4d52bb12.era1 +5bb0d284e04c58b366933c7ad93b816b60ec6774afd18155f19ec148af677b87 mainnet-00756-0af4e42b.era1 +8cf3c848bb9ba0f512bcf211bd89752193725c03ce60c077d983f82d72da83cf mainnet-00757-d1988f79.era1 +0aa584f390cd3e83d11245e62c0e1f3edbaf89a7b4166f929598f932170be0ef mainnet-00758-c66fcb07.era1 +f4ad0b6868a576f6e670960aa670883d0691a656545c6dd5756dea054684ae66 mainnet-00759-a6242a1c.era1 +faa95dcaa6cf362bff7639586a79001b601b0d2c49e548c2b77eed7f04918a63 mainnet-00760-824af748.era1 +b8776c5583333a6bf3063c06c132b39c363099b3351c7bb44bbb82914cd15175 mainnet-00761-76b41584.era1 +c29deb290cd84e84e59bd86974ae049bd69aa283cb94da57e385c71fd8b895ce mainnet-00762-b3ed5869.era1 +0e0cd6eeb32a3320122073f1ba597f9600d0f3abe0444e7e48a64e92824697da mainnet-00763-713aaaf6.era1 +d85121d80c07bd88b93ee21d95136006971523c36dfb46925254f14775e50354 mainnet-00764-3a6de7d9.era1 +72ef66a9c979eca04f650c54cd1f334bf94a34be6f0c287235960baa10726a8a mainnet-00765-18b5d602.era1 +20cc4439cdb54ece9650382d4360834c7c2b406224573f5a09f1683d6c77bbb0 mainnet-00766-6b5ade6c.era1 +e9a38db7edfe16fbca16a7b44e304bfbb7c7f6fbf230a77de534a380a37cd20a mainnet-00767-a0084763.era1 +73f882b64246e774201d47b5e1f884df1f0a0f8ef92916289292a546b74534ff mainnet-00768-8dc563b6.era1 +4fb15c76d90da3a64468adc30ca86c984fc77f5cc872193d4837bb58033c0b7f mainnet-00769-efd6696f.era1 +7cd9b83f4a1e70031835ae489fba16fb9b117cd00368a6587788b84715d2697f mainnet-00770-d9db47f4.era1 +e74a69adbaf2fcc03ef8effbc27ee37bc6377b2900a8aac1e689ff7634163e55 mainnet-00771-2aa70a70.era1 +25e786ec9a3ec2697b013da805d8e9f4099ceca0cff3c3bf54c4a8dffd242ec4 mainnet-00772-44dcb9ab.era1 +987a384d69b0c8f45108efa12a0a69641d419f50bd5ef58b4115eac0ad4f7a0b mainnet-00773-e4dcc8e8.era1 +8cbd5932732dd2189913c32d567a0c3c3bc7cdbf905f021c19de90e7d747ae33 mainnet-00774-63f82331.era1 +fad610eacb2c1fda9951b16da32c499067c2dbbffa9089affacad6cef75eb1a7 mainnet-00775-f24f282e.era1 +655a4fec41c94fe11f86f7354456de04806fdd2e6c101164617d8bc4dc833580 mainnet-00776-382525f1.era1 +76c4992a3df40f20c6db7dca0107b76805c5f823c26655e74ea4d62776c68f1c mainnet-00777-2d3a5e7a.era1 +d404fdbafa7f116cdd0dbd659eb13a4ae3c495ba31a2301034e0369178b5cb7d mainnet-00778-9a24e966.era1 +23cbfc6d257ac6111ce234a1dc24621e63f3a64d2f9122a69c366bb320bef26d mainnet-00779-0be7242c.era1 +2d3ca21e39e058e9e0fbdef9c8d6f2ede1c729e435bea0171607928b6b5ea459 mainnet-00780-0b8c7a94.era1 +1e5cd634954cb5af5c2026c8168cef07831ee5cc1a354b84c8b528e3a27ced7c mainnet-00781-6e9ae080.era1 +5b39d1a2fdfaac1445d5527ba604911c5dfca84e56ba21547c3d82f3d71ddae4 mainnet-00782-e888e6c2.era1 +eba1cf5edf3a613187567a095dbed18573b7693d84064ee8233697f46cd288a0 mainnet-00783-03027295.era1 +54f8cc69cc158450a31f5e10945863651b92506b6c9ee0388efb3bde946fee1a mainnet-00784-b6efb516.era1 +266195977db2fe1a4e990f73b85b91a15201b6d4d34259dd8398c0d9acf28f3d mainnet-00785-79728b75.era1 +7d14175e688c263b1f3fea0c78b1d753ea8edbefee30fa088e2b3db5a34ac0fc mainnet-00786-0586eef4.era1 +5c848a25b0e382189d63b672a3047f457c0da1f29d7398279042e9ab07828daa mainnet-00787-a0d4c8c2.era1 +1bbc2702d2afe8fe0196739912657171694143266120dcab6a8b6f4eae4a9b80 mainnet-00788-a55feb48.era1 +2c6677eac63b14228a79de2b470c0e87554078fd65ce3b128bc2d3a93e497a9b mainnet-00789-9b95d3aa.era1 +23c2b521567f7faf280ad5c396fe6e300d966cc70c82a2f33495444b55bb06f3 mainnet-00790-4a62280e.era1 +26a010a5d04321387a16aff3b20a38d85e42d40a327610ec7fc5eff8ecb45d23 mainnet-00791-064776da.era1 +ef387e14a6e19a36cb30e3057df93d90680296e6db33f4e6f1d2ca5179d847eb mainnet-00792-e9a29542.era1 +06d9b61a90665ca14338bd691f130cbec6fcbf17076d531c4afaa08eb1dc1899 mainnet-00793-93ac12ba.era1 +6f9a483d559732565981e64d9f30696e9ac41a2af3a60398fcda559fa1b88c67 mainnet-00794-b199a309.era1 +3b7a9aedd26d7c5edb27afb1db0d876cb00ab7f954e369ce6293ffa4fb464fcd mainnet-00795-284915ec.era1 +f352e9f87838e6e16e1aea4133c7dafd5f1bbca965dfc10ffe844a7af8083e8c mainnet-00796-80b8a598.era1 +55f664a64de8eb2f391f3347ad306dcb35650144072053c39711443956c19c9b mainnet-00797-40e902aa.era1 +44650700eb2ed69c8ea01a50ea3d55b88982011ef2ca161bb3ef9209fb0a05a4 mainnet-00798-25bb39c7.era1 +a2527eeb080e317933c7ae3d15b5617bb51eb2ab60444b264d16787678f5a084 mainnet-00799-565a1bf8.era1 +c27e810664eeccdf7611104508fdd016255ada12d8c9e2f1b0c275f684f6bf1c mainnet-00800-6723d6d9.era1 +576eb0468f152ea74036e597cbd655c4656e177cfc9d4c21b731d381e54eec7a mainnet-00801-2c9057ba.era1 +1f0182c783567efd7b08b8eb00955e2aac20a00047b8de80a7aa8518e993b422 mainnet-00802-75e347ad.era1 +3ec2b5d0bcb227dbfb350665400b7668bf31b990307766f572d303620acabf68 mainnet-00803-afb8c20f.era1 +516955f0f2a8cc35bc4bf0485bbe7cabcb9325f93abbed372d9d48d601032cb5 mainnet-00804-472b0432.era1 +c193068ff829f0ce35841c777a390750ce40f069e9cf948bc8aea96f6036810b mainnet-00805-a00ad773.era1 +8f11cc6871e56c446cb3fb797808f2908de4ac225eee56ec069af8e858202fa5 mainnet-00806-4fabbfd5.era1 +1c5b683781c57d0b4117b92c8204e8adc1080cd53e59b7aa16629b5b987fcdc5 mainnet-00807-ebadaa84.era1 +755a72dd1700d49a4190e5fb5d4fac7cb39c7a06531ba16738e8408865ed4515 mainnet-00808-71a5a039.era1 +1e880154f791ae3fa004c93f10f460a67055e98eb8993ccfbed1616596ed5b63 mainnet-00809-2a78afe8.era1 +2d0af55bbb0fe44298351b997063d7f225822141b70d56fb7835219f90e4a805 mainnet-00810-ddc91137.era1 +64737d4dd5ca8dd7b678d5c5e6a5d6afc21afa5403810e8d9ed9068142aa3e2e mainnet-00811-47305f69.era1 +b1eb8f4c86160122ead51c906f295d231ad0966f56f54f078ab5a53925af1d2a mainnet-00812-6492e812.era1 +b3c222d370e3ee3d8aa0246b763a4105ba639c99506f2cb465244e384cdad618 mainnet-00813-9ccf4c43.era1 +dba81e8ae00885ba63625f28e5ad23cc4de38fd8cf70bf7d39c300eb4896079c mainnet-00814-02f878d6.era1 +de85a65021d240a9babaf9119dcb8733f8856b69630ca513f6d01be42b906883 mainnet-00815-e97a4d00.era1 +aec0e36c9eb751b619607bed0dbe90c1ecae0baed021108bdb8875ca16687969 mainnet-00816-13c60a90.era1 +c43fdf019869fd29803afb9b594cf31c287abe5df29a5729d91a8d19b7ad463d mainnet-00817-6f8e5552.era1 +156b02cea4489b1a74986a6a96207c49e769cb9fec3f3623254cf66d15d9bdc2 mainnet-00818-8143cae1.era1 +6f7d16fd1fe7ba3287373b882673d7f8de1b3caa83a979449cb8ad0ca220c7ac mainnet-00819-3894e28c.era1 +2ef10197e0ec1f076007e76cd0044f6012e9478bce455e1c6ab27af5b28ecedd mainnet-00820-97b69aec.era1 +2b571624e519694ac946a8963cc35a80843d2a22fda91476fc430e6323fd36db mainnet-00821-22732c18.era1 +274fe58e0bf337c9af2e66e61e7866937fe5290e5c05580fa0443bb4ba342765 mainnet-00822-6977fa0d.era1 +d10336ec40c300b2967191042dea4613c7ce16d114962dc4245f70391d2cdc2c mainnet-00823-0d164934.era1 +0e7487d0cd7a9273c6e4adf98b6627672f97acbc540f4f752b1f7a6ed5389706 mainnet-00824-0de9eb6c.era1 +9668d2f0fede353ebe778a5916b48dd22521e38c8e424805a0020e73a09318b0 mainnet-00825-14eaae63.era1 +541df6a997cd34fcfea892d47007778a079ec92516b0a53c54b7a17dfc2c87be mainnet-00826-e0848f10.era1 +67176e0ace780fdc4c751faca06aa35b8b897de4fec7ff120cfc2cc623e23482 mainnet-00827-6846201d.era1 +ddca6498e8f12dc4d15a2f0592a7dcb78681f6d4d6ba2db1508bb021c9d76dea mainnet-00828-e89c0e11.era1 +0b1678360a7b7a4d269123cb054c9dcab19eb9e21f1fc7ec4d684076b243556e mainnet-00829-3096af76.era1 +be8f8693a8f699e6b3d3de90bdb0fd907bd9ebadd424e5b7ee2a0e525ce8aa07 mainnet-00830-55e8b4c2.era1 +5d90ca3043f67c4ec0c16aaf656dd7675aafce8146c9a119c7d2ea7262b7ebe5 mainnet-00831-c501837e.era1 +ff9c8780356bc7b44cec3ec9a07e07c1e5c102e0408e3a03cd52ab8203e59c68 mainnet-00832-f7000808.era1 +777a905c9c451f682e8902689ae81d244b955b5ccd7166fee687ac65299e57c4 mainnet-00833-5d73b97a.era1 +0d09a043f487b768767080a7cb9a2999e0afb6f766f1eb17017bd1c2e735129b mainnet-00834-f240decc.era1 +5f7413b54fe8b908d238383ad8aa53557f31d244b3e09835305e89acdcdd700d mainnet-00835-fbd0a368.era1 +f9604ae67043945c772d35f5b354da6027810809745e869af295d1b1d9797136 mainnet-00836-fbd2c4fe.era1 +7e658a4924682a76f2e9b66a2b7cf38ba4e7189d06f8633380c28921787b874a mainnet-00837-8bdc3304.era1 +0c4b2d40b6f42990ab482febb32d7c118f4a884079860696ceed02b5061caa78 mainnet-00838-2a2047ce.era1 +b56d1805a5a2f536c44269940db3fe5e7a75bc5594fd5f2a704ff68db3e60535 mainnet-00839-84c88273.era1 +8efe7fa27a8065153fa40f6363c99104ef10b34f5319c9f480c0f167ce6f3021 mainnet-00840-b96ae20a.era1 +1c3abd6c87a8d771905b6faf2c536241996da762d7499b9b47c04f59baad580c mainnet-00841-5cfe6abd.era1 +9fbe25349e52af63cc08d8d0aa091ae401e935fcb18cdd1f2fb1a4e3b0f444a8 mainnet-00842-b7d8f3a6.era1 +349bb1550ac853bf6fb334c73d6096d94c501caf0f5ffb3b997d0c2a690c7bb1 mainnet-00843-c14d7f51.era1 +825bdb0e4dc314a975be7ec16975bbec2a494c56a8dacb3a3f8adb38a2d72702 mainnet-00844-c5eea731.era1 +621fba64543fa22a6f7d50092f0da5f182eff044cc993b5319c6be4c5f5aee4c mainnet-00845-aea57615.era1 +dacb6a1bb588a2b093473df1061457fb052a703f97dbe77365cd3b5cb1e8bfe4 mainnet-00846-be228f4a.era1 +99c926962e17407596982c55cd9034d5aa32cdecdd9fa24ad9bfccfe2c01ff4a mainnet-00847-5721c5a9.era1 +d1bf985348255c72ee123835be2523aef37106ec34e9d3555f821f647d2c812e mainnet-00848-4f17a7ba.era1 +3dfbee47d98740194164a1da35f778c5e2de41249eb5716fd8b1959a0bfdd258 mainnet-00849-81731fd5.era1 +cb89b3cc922fc3ca0a3634c88ae899f14769fb555af4e93df2bcb6c08a313970 mainnet-00850-c8596aa5.era1 +a5374105029f37804a25ff1fa5cd6fbe17e1c7c8c230e5e2da3dc9926c329395 mainnet-00851-d9d76d29.era1 +69d5fceb5bdb30f0bd0c02e8c7c01a9a06e3603f496add26cb41f02f81d72bee mainnet-00852-3db9cab9.era1 +1318265fc0e49c9549289db1583ad004e718411e8f959d590c3269ab9d58ac60 mainnet-00853-05eacb14.era1 +32ed53a95c655e7ddf5cba1b83f8b06a3ea0f16d9598f747371d580f2d087e53 mainnet-00854-78744453.era1 +3b424157848486554e6bad453e338dd7a770c825464b65e7fdba8c74d41346a6 mainnet-00855-b042cdda.era1 +027cbd4ae8b99476b0c4ebe2a6c164c3055856b7b2c69d0ad1afa8b73ee0e988 mainnet-00856-c3dd963b.era1 +72a2f7309c80206e90129356a0700eea83359cfafea4eb724c1650c139b9777a mainnet-00857-1caf90ed.era1 +cedde5c9900e8bac7d6855b70aebd43094c1ea39d36f0769936622e0996445cf mainnet-00858-7d89c8e7.era1 +e528af9ce07553334ec61b00251670229b142d151e3a5ed87ff8071ff1efc30d mainnet-00859-ec9f0685.era1 +8718ccac4340a9427ed167d0330ff341ea8b5489b4a0d65b6194c50eeb001401 mainnet-00860-608f5138.era1 +7154dc222f0ea9ea1bd075bdc565eafd2a80b2e8d0f74c2550c0068ff04947ca mainnet-00861-bc713924.era1 +129b6ac7dab14ab7ed58ea9055d4e457d2089b356870552cc45f92fd0e384e8a mainnet-00862-f5d2654f.era1 +c4892358ce1ddc2d27c6575534201cce78bbde93bb4477656991b5ff6bb9cbac mainnet-00863-29f0d1bd.era1 +dfe0378cbc98fd5e150e9bd4d9b483902b86393d6de48c87cfb7a6f4478e6e1c mainnet-00864-ba09ed24.era1 +d8e572774bb74383b0b3b67c2390a7752a1291fe53bc503b8cd4dcff72eb0e2e mainnet-00865-ef98f25e.era1 +85fdb6469bd9861605ede2bda3da71688ec2c7c9794a85957845b4a0541fc44e mainnet-00866-62ec875a.era1 +4aa0daf8db04b5f98ea162fbbe21e5b9ebbc4201ec48f14ffeddf9796bf05d32 mainnet-00867-6e38f92d.era1 +f822fa286ce4f488fe2fef1dbd825ef938c375e7a730fd2386d735d4f64f5f96 mainnet-00868-ada339e0.era1 +475a67c9e88fee4153749b7b508ff6e04956786b5808c579597d3ba307a59d25 mainnet-00869-687f70ac.era1 +7eeb7e0e77ccf7e4338c71ed5161ae89ac45c16f6a81c2c6ec7f40d56b5cbc9b mainnet-00870-69305b66.era1 +b87586f0529bd9ac75cadf5872d01e97a128bc0468ade8177975a5f75c9c6146 mainnet-00871-dfb48357.era1 +e1ff274cee47442d0f6a3196f981ebd336279c9ec557a7534c29fe3dcc970635 mainnet-00872-1fe0bd68.era1 +118ab69632ee10241e5713c0f6d8f2093ec87925913718e004d3d9b8ad4efbcb mainnet-00873-6754774c.era1 +84c7fbc68de4a30337119a8352fa366afef32c63b6e3e6ca6860c904c82552be mainnet-00874-89ed1e98.era1 +390950d9c6a9583c14170f406278c32300e62564c8638b4c4933a35c444e407d mainnet-00875-918e70e4.era1 +bcf535b017d33ed06f70ace1300fca8eda94b078ad584f8e23ef90b2980a9966 mainnet-00876-b174fe36.era1 +c672c2865f7edcb16a11c7799af76a3ce654810e0fddb936f429a3959f582b63 mainnet-00877-1ee06c60.era1 +9d280918ca66cb1b75b6ff39abc1953cd866d40e708be09ddc29c8c5508f6c11 mainnet-00878-acf82dea.era1 +4025b2ff2764c1093b7b556337238b4dcb79ee20330e884918b9d0d159fd4a2b mainnet-00879-194ae199.era1 +e28cc9f4907f77f63c1e2098e3100d3bb5a9585a553adc860e31fed266e826a1 mainnet-00880-88dc77d7.era1 +48c57783de2299b511ad9b4b3b1cfaf24d5b0e864f82ab0dd620952dd2000ec9 mainnet-00881-291ee430.era1 +75132edf2ac9f031bdb28dfe8bef1fc628262135b2d57cd70cc28c1257fae015 mainnet-00882-e0bd01b9.era1 +4c576b4ef7eb6ee53792c977fe7e73d584efeeedb968ed005ced2356f2babb3a mainnet-00883-24ee5653.era1 +9a3ba18e1794c2d088c6314b9e7829358d8a6a7ad54cb04a6d0c7b7665efa57f mainnet-00884-f4649173.era1 +3164f52873eead3c508a80e297071ace74b7471209770d0eeed4b5c2dc60fcbe mainnet-00885-18be5807.era1 +fa98b03cf7ced8a5e106f6cca26e0f91a1eba337f55241952a056d47d00c65a4 mainnet-00886-7b8e7f87.era1 +de1d232a777550f9efcd6d42d03aea8cd8a8dab7234989a5a5f8f0e6f3df3baf mainnet-00887-ebfbdc02.era1 +dcbc95e80ab179d461aa8fab2fcd1a47f3d9160be1934c7f1dad4e67e8497015 mainnet-00888-2911ec46.era1 +ebc966ee429a98abc65a1acc8bda0cf89846e908fad41229d133fee188e8f0c7 mainnet-00889-7bc66f0a.era1 +e1d6125e7cf2b1058e3b2897b467be1d4597855f52732bca87c0b8e67b386de5 mainnet-00890-de4cc0f1.era1 +137ef3280a18c42f45a0e5b7a75ea5613ac9e0408a7ff89451dbd9e089d27a1f mainnet-00891-1aa1a5b9.era1 +efd3e89f05487d7577a02ec113d6d783ffaee002823eba325a3b9221f3e2bfb6 mainnet-00892-b5354846.era1 +6fc953a47233f82b6448c9d62de998aaf4de47bc86baea1111e3673630474181 mainnet-00893-75d76eee.era1 +c4d4b4ae18dfdba3c50ab34896ec4314853526019d7a40af437c96c9276e0e77 mainnet-00894-81aa556e.era1 +fec02056e20385d7a07b8d138d6060c4e034f38e42e1b70eb2b0f482daf35a07 mainnet-00895-47043527.era1 +a21ab7e602030f9f66efe79072a3cc41eb08df50b3fe780f2a3975195e4e1a99 mainnet-00896-1ab5749f.era1 +bb6e1cd24d035f6ed54c378f1f45d5b8266980309ea97e97b7992f2d4be7ebc7 mainnet-00897-b81f63bc.era1 +7bad241161c5205162bd908cfb3a4a70fcd45d14422cd218676b153d9765b121 mainnet-00898-ac96c902.era1 +fd2a6b0df6b2af60e1b85fae56526460285c589b008044144e0d1a2be09850fc mainnet-00899-922b1cf4.era1 +d24f52be2d507c65a11179fa7f8792e892ee2f0d50bdf798b03a190cbd807195 mainnet-00900-0f8ce285.era1 +4d66f4166981e486be794971c42d27251b873681f53c1be0342cb2b2219fe51f mainnet-00901-f6f06a90.era1 +46291a80c3c36d692c14fd2ad98324a0c1799fb186b7d7a46f17a330ebe0c5f2 mainnet-00902-65bd2e95.era1 +ab933ea7198ffbbcfb8eecdeb5a4a79f38bfb2175446f7f0e11ff5e46a86fdbd mainnet-00903-3b916edf.era1 +bf50a0862e08e65b515bb34cf467ec2f1877011f91788d5da85af375c5928125 mainnet-00904-2ebf7c0d.era1 +9fe3d97ed06c05719278c081a0ce81fc9b90b60f4364517cef837e02bd1aa871 mainnet-00905-9e7868aa.era1 +ada9399b7d3cb60516a05e8e2f8e82f53d67e50191834c3a07e29bfabf32bca9 mainnet-00906-6fe8a5a9.era1 +59e1bb4ff7461c2613f75d9b8f4ced46df1090fb83073b4ecce9200aab342347 mainnet-00907-fc681d3f.era1 +767a171cc735352d2a21d48c0acfc59094617f850ed0a8814627cc0863e8cdd6 mainnet-00908-65f73397.era1 +121d6b676ecd1d763e18f8569049ac47b615d6ace0d5beab85ccc9d5b34c07e7 mainnet-00909-38ce4f9f.era1 +8e0c3de6b2ba02de171f9fc08ffcfedbce4c5fe31115fff19d7c4088706887b8 mainnet-00910-d44a929f.era1 +c27791d691c1fffe75344b160b441986e09261dad084f892663c2594b1316161 mainnet-00911-fc91f464.era1 +1b7a3b002df8b6181573d4ea657abb3262c62bb3db209b96132a0252e5e38861 mainnet-00912-9acf8a7e.era1 +eda9aa0912b50a7f9cbcf16e7f452bbca9460dfccec5609f38ff854316e48374 mainnet-00913-07907337.era1 +571a05a8c5c25983a338bd9cd3498cfa4c60a8c671bf3817cf1c693cbc80621a mainnet-00914-822dfb1a.era1 +5cb2b9593e4677323ec2d75bb76c3d9f1a9675e1ec61872f4300e890e646170c mainnet-00915-62602cad.era1 +63e4fcefebebca610aea69c2210aca0f58882e0eca79f8c6cfbe5e29436e0295 mainnet-00916-8b6dd223.era1 +f6c8b5fb2a4e3a963bed34909902bf4584f85c3447bf545e24b0e6ef8e73aa57 mainnet-00917-b309c469.era1 +a95f81ebc9e973ab484bfc2d3fca9585641ed9e1e334a94f3c3286b426175441 mainnet-00918-8974583a.era1 +192024c65b05a4d2bd1042fad07b4e61839e672a1e81a52773fe974c365be55b mainnet-00919-d139d7b4.era1 +926ad369eebebbb0d7a40aa54f15d4c2cda4c9c1fb3360504233d2e8245d8747 mainnet-00920-5b83da49.era1 +efc26906d93119cc50eb15775fa8978ae12d6466ca140fd1e2f62c0e051c8ec1 mainnet-00921-7a62f3b8.era1 +0b88d2be1ec743ffd1c2ffb962c6523e4d5fef009a201280e6a9fa5890085dc1 mainnet-00922-30f2071b.era1 +e5fc818ff8a23885d56a380cd6e9d7e2728b7126ee1362bbe5b6633ccf8e1115 mainnet-00923-9f05e151.era1 +9b1f50c79fc88f347b5a974810ed75cc9ee256686135cd57dbe943aaaf89dd5d mainnet-00924-8d0da501.era1 +76b98352808b1a455c23b302047b15fca7fbcb9a551914472302850966e4113c mainnet-00925-9de1930e.era1 +7ca90c759ebf83ef3c983b061032488895a0b134f62920f55d16a311ce087dd8 mainnet-00926-ac17e41e.era1 +e4d9a82a541fca599acf86184fe54b6e949ee6c9157f94576f3cc097f86c2dee mainnet-00927-ad6865ca.era1 +b0cc10fa6661cd4dd7970ca05c098358d671b74767cef13b46c6a3c7b6a23785 mainnet-00928-3feef311.era1 +5f161190ca57d017f5a901d1fc17b510fe2cb06a9463bd1c53a38977ad2f7c29 mainnet-00929-6e2d1f4b.era1 +df1fa99bf21a8e99fece3e1d5be69f1d87e6bdfc6f4f2ae164b616a692c672fc mainnet-00930-228684d7.era1 +8dc902f268d0879ff3dd2ab5311b6770677af4059c9dcd7ac065633b7a619311 mainnet-00931-2485471e.era1 +22b6ac2db24272183afe4cb1c082765b5fb6d612632fba7f5eaf1abdf5b1a325 mainnet-00932-f2f69e07.era1 +91ff864c90169f8b32be834d74026cf6e661d65b4b8f4833a3d06d27876e46ba mainnet-00933-44eff5ae.era1 +b870a45ce77aceb77f85f8409f2d9fbb5253852d2b00e4832957b94680d1e4b2 mainnet-00934-ac8cf5be.era1 +ae5fe657129b44a16a75fb44b9d677c0b0491a6eadb26f14cef08fa8e1c5f710 mainnet-00935-c052cdd4.era1 +160287eece33d1233317b47d943692a55c3f1a1f1be7f74a30a9330cd1de4cec mainnet-00936-0d1ce1ba.era1 +254785beb70cf70428f860f264c6c0e6acc3a1dec54ea55abdc5446675d6ab86 mainnet-00937-20d08362.era1 +f413c0b34ea5ffe18cda24b6c47dfc331464946ec2d823fa69fc2ad930acc265 mainnet-00938-fb915a95.era1 +b4420ab136b9747fbbe43d40f6877b95b630576a0486efbb4bc6c39c0570a999 mainnet-00939-2d5f2cb9.era1 +9674ae27b0f8066f265ea8b4a3eb72bceffdd519a85f5c46657889cf01966c6d mainnet-00940-31a360b2.era1 +a913eb68f537131b434eb6dde18efb3ac7f7cf1cb1f6d6c734124e13a81aedf3 mainnet-00941-6247e765.era1 +a12a0a421cebf730486a4fd64e229cd7db1973bb9333ae001c12cc08dff96430 mainnet-00942-c352aa92.era1 +0ba8f136af56f8191059c1ed11d4746bb3cd0089324d6e17631c5e51d5e36ade mainnet-00943-b8b31db9.era1 +44fdd29605fa3cce277d80ded2197aa897d8f6ebe1d3710458ff3636a02d5599 mainnet-00944-2a8be083.era1 +369f0ba252ad601864d9892fbdbe4bb6566849c213fcf8b87c690d14f61288a1 mainnet-00945-80961bb9.era1 +87d56afcd024694fd0595fed8a6c736ef1bfd9cae4a439698f5713adff6e9458 mainnet-00946-caefe64b.era1 +aabec04e13481a949bcc0e702dc865d4ffc3059886aa31bf8b6853479fa8ddbc mainnet-00947-ccd88aff.era1 +fc8707c984ec97d7cf1dc937c8ac1d4afc655aecf05ad523479f4e65d187995b mainnet-00948-11d91c25.era1 +38d4814a35cbe059eef3e6d7e66c6f05b56406a1f66c344b04fd67c5b0d6bbcc mainnet-00949-209f845f.era1 +2ba49a308d695c35548b8935ac0c224bdc656db3021cdd4722d554a53fa733a5 mainnet-00950-4a9dede7.era1 +26face4ba8260c69ffa7ec6efce893455a0fddda9ec81e702c821f1ba11fa1a1 mainnet-00951-6493fcf8.era1 +1e78004872cc834c2d92b4b9daeab61277c85a8e0bd135b15e2b12268e72f628 mainnet-00952-611a2c46.era1 +d43cdff38cbe428e0f177bee43dea616c407df0ffc16fd31f32d6c1b962fc20b mainnet-00953-81e7d017.era1 +7cc671fa8a9cd067a420eec0251690d5773937ef01d6a10428ea0fc30ed978ed mainnet-00954-19895bb2.era1 +cd24f28447005cb8c014e30d429ebf005e05f31a6b64c4071f81695d05ad160f mainnet-00955-443f9153.era1 +64e0fca3590d4c5beaac462033a48514345f7292fd1ebcfb690c79a13c0aef83 mainnet-00956-3dcb543b.era1 +12d96b92e2b1b331583f5b520d38b1b2e65fdb24cc4cbd586d5e50eb95bb8b4c mainnet-00957-a2d2aa39.era1 +e6092e6ba5a45be6db818b86cf03d63b13e7718ad02b8815862f59263435338a mainnet-00958-24f3f044.era1 +4113dd29011e08d6ea70e08712d69ca98c99cd77788a45839b6739b0f67e0ad9 mainnet-00959-8fc647c4.era1 +a90611c78f0fe1a3f460c8f11ef47c5357677cc02381441d231ee5ac07430b6e mainnet-00960-680241a4.era1 +66727a8881ca4c719999119cbeb6324177ef95cb8063b92b4ec59917ae37dccf mainnet-00961-759690ad.era1 +cb3c393d014ad5b817113f3a6ea5e6ded53df7db2e3830405ecd52463c028bcc mainnet-00962-12b37dfb.era1 +91f6d92eb6656777199e960af9318ab4c5c994fe582d38df8cdd40e6270eaf66 mainnet-00963-2b4168b7.era1 +731983296d9b8ef3bfb2b5f47b709146c22f1564b9057135a85dbca51c76c52a mainnet-00964-a7136656.era1 +b93b2f350ed9e3e1fd42dba9aa328fe3abe6122c1d421c3393ded798c6e609ca mainnet-00965-8a62b405.era1 +29d762425352d04e8b3ed89a9d0de9994524af5ca224cb1a574feb575371c6fc mainnet-00966-73e45b2c.era1 +227426426b25320eb31e6fc556914e27f88bab1c0cf93c3c7d3450660f1a7e2d mainnet-00967-39942459.era1 +f5c723924ca804105153c00c2aa9d5e38a67499246b81c6daafaa8424006b12b mainnet-00968-dce8aff6.era1 +08f52f2cad8b332ce802a7b43ecd0667770044e327224e877dad3ec9593d98b9 mainnet-00969-49be4756.era1 +c773e4c1eafecf30ada6c33610525efbcd8df74696b9d169794648620adfcf01 mainnet-00970-68c57c6a.era1 +9723cd64a4d5a894b2dc2952d1b264cb6dd96996d4e1104b68b0a904a2c6310e mainnet-00971-c4f6b046.era1 +85a606fe8e462595bee1085c3ab7f587e075c7f8b1b19a0f4bf4c9320a43968c mainnet-00972-13a7fe3f.era1 +7bc56fdc61c327d7d4e057b802290dd5f10c7d76d31cac193513c78f65da9ab7 mainnet-00973-135d2ae1.era1 +4bb6a1e85bc267f1b72d91f79ac7f66fe4df1e53205ad22132d3187763ade96d mainnet-00974-922bb3c2.era1 +30d549c01c8a292b7321796d4f3266f2f7e142e5410c19eab04b6a444be3f0ae mainnet-00975-27b6441b.era1 +17f8b5f4a153431f82836afec6e67bbd18eed207911aedd74862041feadaef34 mainnet-00976-63eafa02.era1 +55c1230e48a49eb9f50536f5e7b7c0d3ab1806066c76df8af2cd75ce0fc7d8ef mainnet-00977-05bdc732.era1 +9f4bee6308808e08e34188ee93a77fb167221aba4c9793f4bff87fd0162b2694 mainnet-00978-95d7750a.era1 +99f0e262ba3ec8ea549cdf0e15f39a1b36e69593b3ae2c70b98a584ec54333f8 mainnet-00979-8cf0d624.era1 +5a03ca9953ce0c35e51a25bf84f3ad95b9b97d736db2af7a4a2550791cd73891 mainnet-00980-a8768f5c.era1 +63b7809c76fa5f72ae92dcd42eb2f5f9cd7a24a2fc7951ac4f1c51e840360fc2 mainnet-00981-c4e8ddcf.era1 +8f4bb2e28111a26adeb4e9ee0e76a85b46357821c44597a12342f23303eac05a mainnet-00982-d4ecd7c3.era1 +c434b12269ffe378fb5bdae5943d4e34eacce459d934ad3c03490d1fc320ba81 mainnet-00983-d39b640f.era1 +386a66ce7a9c92fd26fd45ab3d25642c15ae9054d20cf82f499026350d13563f mainnet-00984-22592d52.era1 +9dd47c3592dada95175b944878e6b671d21046c677ec334e7e8dac02b08ca2bb mainnet-00985-e4e144f9.era1 +e5d7bef7c30a51b441967ea6df0df649c6f4d449c5a6bd9f07bf37366e2daa37 mainnet-00986-b5e7db59.era1 +e47c38f443c8a73c304cc6e04b73e846ddf2bdfb6f41218b9f0fa8e94a4fa26f mainnet-00987-9316c767.era1 +5fd0592e9cdc55d79992c274174b0f85b7ee5c584fe536398cc47aa344104b61 mainnet-00988-871302ef.era1 +4d42c4a88e1af0974887663d9227e30b9d5be4a8d988d70170e0a619ea2a6e2b mainnet-00989-1c3a7616.era1 +e6b3797997eb717ea44a6a9fec06ed1728cbaa97f824b4027bab6f2524d61d95 mainnet-00990-a666b389.era1 +61692c49a9f2a1df764b1935198f2284842ab57b921b765166e45e0110bc1ba6 mainnet-00991-3154c955.era1 +7dbb7e563b116d322c725eec6bd232c57e6350c39325ca287caf9903c1b3112b mainnet-00992-d078def2.era1 +d42a759bed529201dc3b5246c6bacf33db8347573c3c60bf869c26295e36d3dc mainnet-00993-6b2615f1.era1 +aeeaab06a62c01aa287cc2604052f5779303d850191c69ad445d706c7f5fa676 mainnet-00994-6ed3f90f.era1 +f8c136533ecf07678c9f0394cfea628e8cda6e4e17758b488cf953691c2f3d9f mainnet-00995-d3223ce7.era1 +3c13ab210843321c30caf84af68b628ff4345a1fc0595b1f01b32417842c4f07 mainnet-00996-016c769b.era1 +158517c5ff036852a86cbb659cd18ce59e01c46267a55b4bbb16329ee4703493 mainnet-00997-e19a4c9d.era1 +b7950092d83905626099cdb64c81bbf224ca0728dcb4dfbcc0ccbedc7ac4209f mainnet-00998-36c9ff39.era1 +4d96eaf7f23db43fc8260e00a20f89bc8d0c9dda56c0c88dc32dc127cb617a81 mainnet-00999-83c72fa2.era1 +2030ba76226df88d4e9b0141702bb29702d92ff80f39af34caae4d58feabf070 mainnet-01000-ddcc6036.era1 +ca961a71ecc2f608ec95c2d3cabfe722ba69a242c8830236121110ae8fde87cf mainnet-01001-2d0fc419.era1 +e8e5c0142ae6d8e73fcdb9c108aaafc0cc99283d7476d9f21aea1607adafe76f mainnet-01002-f69f7b39.era1 +c5e7d9785ca37ca68adc460ae649854c1d529ef8f90263d00c55386125f880d8 mainnet-01003-17632710.era1 +6791a5fb4f3636e9a7f503fe8cdebfa7fddb4835f587d54db7ea7f3fe26fd8b3 mainnet-01004-fbfc0216.era1 +9f059f87ff05fbcec84a85233e0b6a576f75a62f34f98005bf58c858fae09e7d mainnet-01005-584687a4.era1 +6f98e878cb0186b684f67d18432cf4ffc504b8cffadaea66b4b886865c764208 mainnet-01006-df8970e8.era1 +6389a787c67015adaf7b3e0aa495192a9dee8e795f73339aa8b5c48c69f04252 mainnet-01007-2fbbff92.era1 +c06ed975ced7957c3763954b5e79f86fa3ae2333439feadc0ba26b97b1613c11 mainnet-01008-235c9a91.era1 +96cad5272aece888e7390b8ac170e14556c1b27d021d5b7d17c02a75a3087783 mainnet-01009-fa09b4f1.era1 +064d7a29cac16e87348ea22c86c07b099b86f806d37ad5a8640e8f4420913d97 mainnet-01010-3cacc95c.era1 +99093e195efe2f0ebb023ca172a20bc3cfecf75d4666352f14bbfa4f693c1925 mainnet-01011-dbcb3c64.era1 +168f113b3368eb2df264ded3a88e928f8eaed9aed6219988e579e18b59f274c0 mainnet-01012-6ac002dd.era1 +eb4a448536a1d180da7a26077224ea0c70c56e78cfd3671d8aed75cc984110b4 mainnet-01013-dd1763be.era1 +f6284ecbb3db7c4579a8cf2ce0e37377f9a291f378722af69d8d854517f02469 mainnet-01014-c4e0e059.era1 +532f119847749a5b068777293af5d094f047f75b7fb30c7b0dcbb2e12625e69a mainnet-01015-d2d13e5e.era1 +acea5aa287f1cdb1261436bf28f4d29b22dfd2ba3f038a8b6ff298fec39455f7 mainnet-01016-a93277ff.era1 +39a66b30e7588c8f5558863042d90ecf0238f278870ec95cc6f92a7a705d0175 mainnet-01017-019e6db0.era1 +cfe2e6ecea6a40468ae53f0cc8486981ad3eac40509b2bdc101f8b0d69f67b80 mainnet-01018-763ea921.era1 +4e1641b989a482e9b6a70f6615a457ddd434498f7fb4389efa17b5a13b692509 mainnet-01019-45d27951.era1 +821ebeb97e8ecd4cd2e79fc64cf0a8082b38990710e39861071fbab1dc631ae6 mainnet-01020-37e8f37e.era1 +f0bec9191390d1aa416dca456adbfe372d3da587c0405893eeb3cc7fdae859e3 mainnet-01021-6654a92d.era1 +7759d1bd02558eac871d5a783d5ffd69b6f3b5635fbd20923f38ebc7c67e96da mainnet-01022-b81a65c1.era1 +1162121637cac8aca3977dedcfe29083b7807f921f74fcef01911eed7fb6c549 mainnet-01023-b72e8700.era1 +f6a87889a36ab17422c8dd9262036027ae00a30ab41b319598b85bf8b0ce5242 mainnet-01024-75f6d852.era1 +56033649f9045994d5e5a6b23aa4705cc907882b4385915e2b7d9f4820e10af1 mainnet-01025-cd13479c.era1 +f84df05b13cb4f3603f50b952e7da992e35fe229771e8831f7237006bf1d025c mainnet-01026-1ff6a9b9.era1 +0347df0ba24d97c325e6a5100c6ec1a8dd2b62a8dedba16dfedb6cdc77b1a237 mainnet-01027-6c76c020.era1 +217b9ecd8653cd56735f82ec13f9f9b80f87571fc4b25aa0073f08ec99848156 mainnet-01028-78f99056.era1 +a4938dd48c02ac77af4f70bfa02a805fa1ee24ad0148d7ff3b209cb6f2c56799 mainnet-01029-3dcb5e2a.era1 +c3ae2e4ca70f6eaa23f00ea142d0316e149ba6ad72e4685ccb78ac9dd2fa9059 mainnet-01030-373e75f1.era1 +d68a4f4659203db89c939d227357c2f875973464abae8a02a918afd296ab5a4c mainnet-01031-f06e62b5.era1 +e61a71d2aa334de5122cdcdc4921fa597fe516c78637637c29b54e14b5980e28 mainnet-01032-3f19793e.era1 +beda23a07218acf026ab4de706e9c8716b8a3ba052d867f24eb151a7de34b174 mainnet-01033-a9765c1c.era1 +05f6f06eb10562f992c10268235df7caa2b5bce994fbc9744de35d4c56fd333d mainnet-01034-1dcfe017.era1 +65f03b88c05b89fe7793fbc0ea3a1d7b403937eab092b0b63583d98c41354ad8 mainnet-01035-946b550f.era1 +74031d7bc115ea6c526773670dbf0c40cd638354e174dd53a993a591239e5cd2 mainnet-01036-b953b4b7.era1 +75279c9f4d8e6be5db40f6193afab02ef695d7aec87deeabb57aa3405785a57d mainnet-01037-8356dd44.era1 +a1e60f79dc9971780b6b71ab9ffb988dbd9fdcca2137feeb746615c1fbed6ad6 mainnet-01038-3cefbeb9.era1 +7f3629ad6d60d3bcadbc87b2d8f89ae1997772c8360f545914e5069442c8a963 mainnet-01039-4765ee42.era1 +a598e383070990db48c876eddcb5901d3d9618a3f2d86d67a169ca05c9eab1cb mainnet-01040-c559659c.era1 +8bd6ced70e2b8d7b666975a6af26916921fa567e85cce68808153c75f510f08d mainnet-01041-1b1f9767.era1 +736c0536e6a85b59921dafb87d0e6d9f1378dbffb080c2faa51d37abab2275a5 mainnet-01042-ed5a8fb5.era1 +700a4bbc14266da52241307e5024adc526db1385a0a51b930968ecfb18854f62 mainnet-01043-a396fcbd.era1 +65c75391e62218324342a8b79a1e862c61b9a19e80aff082a8d67d2ffaeef4b9 mainnet-01044-33bd34bd.era1 +aad19a6f122726160f36e5445a697163554c75602e40b705228441b044865811 mainnet-01045-e62bdcaa.era1 +52a3b2e210d69846a3e6c32520107b5ed7afac182fb097cf687d83e45ab3edbb mainnet-01046-37db60cd.era1 +860b139156ce093f74218560c8babbcf6894cda0b13dab72433eda787d79a5fb mainnet-01047-d02ff344.era1 +cc50c84bac158219ef04eef7190fdf4bcc4ed9a467e213adad06c08b59f1a6a0 mainnet-01048-27c44206.era1 +494dd65f9f69d7dc86b98db90f12db587d62e5a33cc2e07e3d0cbf7c3c24f89e mainnet-01049-d74dcd43.era1 +97059495bf3a8efdaededcda73ed9f17e212c9094b54a229431b5943c6ca372a mainnet-01050-583482c4.era1 +db4a2bd13f3d13d13ec7f8f4b08cb95b3a0ae8d3e96eeb3363596d4038dd5d0c mainnet-01051-b1375fb5.era1 +d484e0bb8feb94aaab82fe78ef2ec3a78ce97f547db8b1b706a3d26b303f411e mainnet-01052-fc68a5db.era1 +56bfa4277e67fcde394721e9fa3c002376389a35a25785d9ba681d71b3cd5b4f mainnet-01053-038d0dc5.era1 +337026169261de6cec5708dfebfdce9191d66220fe0c83f59e5bb44164411ef2 mainnet-01054-fc630d10.era1 +6a1ef87c494b74d34f2064c3fbf5bf9815b59d717b326c61c248dec6a10cdf83 mainnet-01055-dc564afc.era1 +0c8e44d6b50903a639b67f87011dbd486b5cb19eec9c1172784173df352992e5 mainnet-01056-75fba5d5.era1 +0fd44ab1a99b65b3a23c89482f3a3bd4930ed1cc063aa718bbbedfcc38c38ae2 mainnet-01057-f2a347f3.era1 +9117c72dd287b56a50613fe0c71569792966eecaabe526e030418e0ab493b91f mainnet-01058-7e00f70a.era1 +ae5c3353aea30d7418921434a638454bf9e17a8dedfe8fc5a7eec0c761a30113 mainnet-01059-7c557845.era1 +44235f35b9dc76e823e7d2ff15bfff8bc004f3cf30615486a62777977ff30553 mainnet-01060-d6b98869.era1 +9d4003643418a6c2f941064f20595e970077cb78d0a8ba97ef84cf1bef2f7cec mainnet-01061-7edcc464.era1 +280bbe45db8a424df21a6ea4242fb2ecd9b63c0211977bd66d5eb56961c3336f mainnet-01062-84fae3df.era1 +eabb0d3253f23668972605d4ded167862f1868133197d11e668e7fbd98ee4b81 mainnet-01063-97a50adf.era1 +643d1a50e895224b545d57a0e3667e694fa17d822946b3d235686081c669bf46 mainnet-01064-25e68a39.era1 +741ae08f901ae74a5e507906f79ed3ee1e0bd6204469736a7dc8a769a1fcde6a mainnet-01065-88ea91bd.era1 +f28e396a734f6766ecd32efaf640ad83f1ba858c1c101d9e50b665f444de42fb mainnet-01066-77a58ff5.era1 +fd291b0c15156b885cf9af594af329c8a2901ef2d5a498e711c1d51bb03f178a mainnet-01067-95926dd9.era1 +88d01100df01cc5680576f3bc06c6774f5fb20f9f4f176c35a4be96631297119 mainnet-01068-9e4b22f0.era1 +2a5d4e98f1adfb8da0f123cc6d7aa30cadc0088f5d88e4f4ede083997a447880 mainnet-01069-5451d56c.era1 +6e8fc5c611fbc0b367b0f24057c13d190cfa20b601dcb76ddeccf90ef05182a2 mainnet-01070-dd746cbf.era1 +8e5078c90f147cc6b2fb870b74a2f8a7e86ae2a9bd718a418e43c9017c94de18 mainnet-01071-e7162b85.era1 +1a76ae6d39cf9b7bd23355cbe2bd0918adf70280b73f425d750627890d442da7 mainnet-01072-a0266c31.era1 +ed7229b26279376d6776d4eee63b3ec7b0df51480a07b87305a847d2e320a2fc mainnet-01073-fb390415.era1 +709d9e99da9db956efc547a8da53b1259cf0aadd1fb20fb4fa15cbc38529aa19 mainnet-01074-7d668fd5.era1 +89951ca75c4c605dcf7dd333ef9b260492cda7b34a8fea430f9344103298bae7 mainnet-01075-38bef7ff.era1 +3d68e0261715155af12b191814d8c6587e2e54f8f6d7cde62b3c8d6502fe65e1 mainnet-01076-55f5a07a.era1 +57aaa772d4054832b9849f5b22b685ffe28819b413cf54060d878834ef60bdf4 mainnet-01077-61a13d92.era1 +caf6c5aa2d02ff166a0b00116e8edb60230a6a874155673e02cd2dbd0a54b236 mainnet-01078-227e7127.era1 +e261e53961745ba2d5ab256dc1576b03fbeeed614fbd4f9bcc44344aa5aca997 mainnet-01079-f1a39e59.era1 +645cbda4a151a25566424e85d6c47d42f2579e2af705ef35e491716346e5dbb9 mainnet-01080-1b7d0990.era1 +6a1383d5b385a1814b7bb725924ff0dcbe5b951a3648cf2041ecbd960cb373dc mainnet-01081-679b4359.era1 +931dfdd43061fd1c92112416ed48b640b35fef0aa5a16f497f65e594f8ab3252 mainnet-01082-5e7dea25.era1 +3c123d39b3ca6bb4b94345b08756345c6e87904d5a91cf1d45ca0112c4ef757e mainnet-01083-cdcb8e56.era1 +efe233952150d5d9384586b5aa291aa810fd28d34beabb3a14dc3fbca8f695c4 mainnet-01084-5f2ca307.era1 +2d785c18ebbb9c32fc274f34c9728aacb027efd4e8b38df7e610ec90fce056f1 mainnet-01085-12230dff.era1 +04337221c9309450bd5e32ff4ca248046ca14534426e91b92e592ba5f45f596b mainnet-01086-6eb5d461.era1 +81c6aa9d6ebe238ddda95def065ed86b54f02826b964a9149c1cad8671570fc8 mainnet-01087-45541bfe.era1 +9711c653391102114ef0a91cd9aa3b1ecbdd06efe48b0f6eb9bd4103f8bd280d mainnet-01088-09f2f43e.era1 +0ae82b02b1fdc71b22fef74ae5f15f3ca52227ce49d6488c470ab5a968f7563b mainnet-01089-4519917d.era1 +4929d107163c10d2399239a9652b31046175b9b3a56b4e4cca7a50829cbb9725 mainnet-01090-506362e6.era1 +1adb8982013063f3f75c5a9658353c1386ada4d77251fffef4d1c24f8625220f mainnet-01091-408e7c24.era1 +8755aa4dbcc94903cd22788a7701cdcaf1acc7b60e7e33d1f090b2a3cd56ccba mainnet-01092-4f1216d3.era1 +fe012d19b6f24004b9256f21faccbebffcee4d3162bf3a3be59ceeade8d5612e mainnet-01093-f7943fda.era1 +67d801f711c55e287c0b864fec6e60eadcffe4de27621240e1d54b8152f0f5d0 mainnet-01094-a2458aba.era1 +9629286e67ab8c6b315ae09f84d249523dc97eff653ca95bd29f98649fd07e70 mainnet-01095-c3174a59.era1 +8760cd2f788250b8fa559ea7d701749edac84afc929c658a4b91b87f58d4ae19 mainnet-01096-5475a30e.era1 +17ecbaab8c991bebbeb4c0b57ea5cafebcb4053958d72efa03885ce44015946d mainnet-01097-d2ce1e42.era1 +8192603d05ff32023df5a9b79059fb456c8f846c5095d166468d6554a8eb2910 mainnet-01098-5fb12ec4.era1 +f8fbfba63a81a2bc092261b01ede77af006099d11d11bb463d620908daab8b95 mainnet-01099-1cd92052.era1 +5906280eb0adb9b57fcc3b9a30aac43785816aea99176b98ead4aa2cd790613f mainnet-01100-22b095d4.era1 +2961b929b05ea871114f1992ea903702830f62e6690b64b563472ffe0701a14f mainnet-01101-844b63b3.era1 +e265b235b9bc18f193d6b93444757aea34fb0b65eb17124e0a7018b4244e0322 mainnet-01102-bcce4dd3.era1 +2e998dde589e88f2b5a444f47f445a2881fbd9ac44243579c78ab16086534cfc mainnet-01103-c9711792.era1 +39079368520f97896290263edcca5ce219733357ceb079f59a8e7c41689c4318 mainnet-01104-5035027c.era1 +98e3fd0235e76beee860b0f7cc698cfc4f6049a95ddd38b2b6ec7ee52d15b8ed mainnet-01105-9331be3b.era1 +b9ebaab58e96a52061462335bf23ed93cc0be2a0b69276b47922b7f6e0c2e4bd mainnet-01106-901078cb.era1 +c7bc6484c0adca1f6725408dfba43a2beb541c89254ffb757ece514f41b1bbee mainnet-01107-f8edc0d4.era1 +2436cfccee3bdc946b849043cc3823347f64dd251b8647c59ad40d5cb3ec7bef mainnet-01108-42362545.era1 +76d159a9b7ba724d20b5a6de7947e8e5a48ce9fc8e8e05dcb80dfe032411d14f mainnet-01109-bc521cea.era1 +02a940756d49d9be6a45272ab800d67856817f6bc8a098b2d2ddaf7fefbe61c2 mainnet-01110-199eeafe.era1 +07661f820a67426b63d1f8c90c0e72301f64371337f6d04baad2fc548466fc14 mainnet-01111-d3446282.era1 +aa3d74f50754f2454d9fa4b7ce5830128a7e578bb3e3bf602410ff213079de88 mainnet-01112-1c93ba5b.era1 +c951c5d212149de8e017db8ce6a147100a2fbe907343d1fd75c6b85231004e77 mainnet-01113-beafcef8.era1 +693b9883a3b1b94f51dd9b1abead7b47a9caf1f50b7d5327678a0f55a79aff23 mainnet-01114-71ec790b.era1 +257d13b78b096ae907f2d8c37da31af8a0aaf2a6c55c6e4b651b3caeb48be7a1 mainnet-01115-6f6094bf.era1 +33e76f63eeefc3b82a6f651acc73c2514a5bf3139491cadfd9caf31fd6367120 mainnet-01116-053afb71.era1 +1052384909bdd8a400603abf7e0bfccb83952d1312b35a84bd8242ea8ee22c3c mainnet-01117-98396ff4.era1 +8f0c0ee760bdd5b34d1ee4f031b18511ee0bf397ca1cc138bac1ed9ffced9768 mainnet-01118-57479712.era1 +53647ada8269cd41e65fd17e59d90e0a7909d9cadce79abf28d7bb31cd754acc mainnet-01119-1554c473.era1 +492ea63b5092e9eba1525546a1bf2a6709cfe87c2a4eec8bedc8436c26745ad8 mainnet-01120-5db300fa.era1 +44ae269d3e8291e1fd98177bb419205a7bba05c2960ae3a773ed85e99bf0e7e5 mainnet-01121-b9aeb88a.era1 +5fd7882a18010543684a44d2246d4c35c7b676fcbc41bc8082341a9b7db42622 mainnet-01122-a8849157.era1 +4bacacad8b1f09c93144dc85414a483d4e6380d7655ad33345cb42287735c7a8 mainnet-01123-0b7bcf33.era1 +486948076131219d1ae8408cc6c6e13bbe707577cba8ba88d2e8a3b62aaacf12 mainnet-01124-224f4405.era1 +5df25de47e78d727b3493afe919f0c59371f8c58aa08e85bfd15240a0c6c48bc mainnet-01125-0b6064b3.era1 +0d478eda34abf9738783fc5e3c19759515454d20e9523a6d6b983d8576ff651f mainnet-01126-c7344cf2.era1 +61d872eaff6fc36378b47c78ef3301a9cdc4612e29b8f55f7627b65cfb3c99d0 mainnet-01127-ad12ba38.era1 +8d8dea3e3f3ef33921c2dd3f76bb1df1afe174915835d57a934762877259f675 mainnet-01128-3a386e6d.era1 +5a45d158d34d4b91f76bff6e0f224f7b3f713a3d64a0bb85e6ebc3ad06cee638 mainnet-01129-c77dcea6.era1 +a196a55b1a930962768945133597054e8ab8420c8b2347049726ce0e8638701e mainnet-01130-a25a8fc1.era1 +840364bb4c929197ad5a9d39a106d4900c7dc1c335bbd05b7b59df034208c67b mainnet-01131-0225209e.era1 +72d73c29f6df76128478453c2832e15c4f41294889a8f6f5414c2ca175ab6ec7 mainnet-01132-1ba9f77c.era1 +bf4159c5b85f495dc486553cdad3eb4f6ebc8423161ff01e7e1018c28d39f425 mainnet-01133-8e1c1d63.era1 +f22ac40f22a3e3bd8621d1d5ee974936063c95c4b3cae1e168dbf9fe654040f8 mainnet-01134-3197a1d6.era1 +a0bba5215642e11b803b79d74fdb99ab882f1faee1fd39cc5a9cb2dbe06796ab mainnet-01135-d28f2c9f.era1 +f9d70ccb72a014ffc73597a2ca0f64a2cdd7d0020a15349716a662cd42c40fcf mainnet-01136-6cf8d26d.era1 +7f07dba1ecb6618772d4800eb19165e6fbbc1b8375422250c4f13dedaf448ec2 mainnet-01137-62215680.era1 +87be3f04548dd4161a991e1a0093a666a072971d2514cfc367a5807bb32a03f6 mainnet-01138-44e4142c.era1 +c15b673920e6c2c56879b2cd87eeb9024851898011090c6dccecdac8516cf1c3 mainnet-01139-1a70666e.era1 +381abbba5cc8cf7c0b45a96fe730ce0406161cb825735c0cdc4231f78ea16008 mainnet-01140-9bef85d3.era1 +42f9a2999d097cc2148ea7f93c6a1c89a46cd2068f37ca2f15494fda2830d9eb mainnet-01141-48066cf2.era1 +bf8b07de2ec39c355da7b30e06e95e0f39c1f30f9f1d9f4c85a2495c2fb5fbe0 mainnet-01142-112745d1.era1 +8750348515c1d43ad51d0cfb245f15a7b637f970de34f6f763c81625f296d65a mainnet-01143-c07f5625.era1 +32f9ac799b52f528daed2780d8b79bc9acee50bcacea386a2f2f7d221050063c mainnet-01144-ff3489f3.era1 +af3e756ebc415d0bafdf3b082fd50d3abf37525dbb442ed5243e5f4b3ea08a15 mainnet-01145-aa9a507e.era1 +f1863c4de8ffee8ab1cf9ed366fda800276f407ada526a4c6e2a318bac60a93f mainnet-01146-ae05fa5d.era1 +21bd47773e374770c725b4809088c46ad97ac1f63e9c6cf9eefd23927686d65b mainnet-01147-0dca795f.era1 +4f95ed27a854b4dd9dfdc4bf607261e6c6916773f572f2e4b0de04d0c9df8b1f mainnet-01148-b970027b.era1 +1814c3b3773adc356d8b5aa16201d97c16865552d2338b66d5dd7ea42fa94fbe mainnet-01149-b2f6f517.era1 +06e7013d7e74c6a3bff223bb343160748c5cff8d23e4ec62196692940caae233 mainnet-01150-ae9dea31.era1 +04db87c8a1ddf007769a332ba44dd3d885d2fad4c7e35447493192cc4ec34f82 mainnet-01151-1cb2b8d4.era1 +8505c37ef3bff814772e094799ff748c9bf5befbdbfd5535a257ea9fb75c513e mainnet-01152-28b41e38.era1 +4b53ddd657e94ed3e798c36b681b2f81d1f532add195a5dbd1b5b2fe8597decf mainnet-01153-9cc1f6f0.era1 +2ede6bcdc623794d5ba9c13f2f8c65b3c6cc3bde0a6a1bdabf4102db4e25f7f3 mainnet-01154-1d470ae1.era1 +4fb4abc0c2727aea473e2d3216ae48525f8240423d18811f44b61dcc87716c6f mainnet-01155-b516307f.era1 +10c01bb633db2fde70660d215c7dd7d7e5708b1da1cedb1342b58b2f93fd4009 mainnet-01156-8c4c1119.era1 +fbede5bf3794645fcf6d9e6ef8180d9474658d8dd984cdfd58a4c4e5d81f5044 mainnet-01157-d7bb8fbd.era1 +6d1372e9f0213ad9a6a4d3096375e9681b9bbde4c424b778c278e6f737988e12 mainnet-01158-12ec0bec.era1 +81d2253bd67ae0a17b73541bd6d07bc96cc3059be380784bbf1e0fbd016544d3 mainnet-01159-4fafaf52.era1 +3606259ac7c812b03f91a002773d2b83f9d8dfc3f9011f6448ec0f5b8c25d725 mainnet-01160-d0e1b363.era1 +4ec53f617ae6e948775633026b11900ee53c363590f6052eb7623a100f037e48 mainnet-01161-caff5303.era1 +d0a093057a4a9d018ddaf3716fcefa29a9d76320456838bc7187b4f58e682b84 mainnet-01162-070dea60.era1 +016b9a8185d7aa34ea226975f8ccc37e168a863d0d21cf31d1d5912e9ea3cc55 mainnet-01163-d285b66e.era1 +b82af4019e231a7960f204262524921df9a9d249528f19face594c80b6311330 mainnet-01164-2eb4c50f.era1 +a4f27f235b35f59146c2e945abc1ea89c5e49df5702423c098138c4ff18bcd9f mainnet-01165-ff4e71c2.era1 +39c3973459e3dc04e5a9e3e363498ce1f5e67da950f7464faf5fb091022e7750 mainnet-01166-4116850a.era1 +cf6cd7d4d48a6a33b81a99a6f165848b8b8feafa3a123d79c5a5a6f1d8222e80 mainnet-01167-5b698645.era1 +c70360eab450f746e535e0cb8eb236af779ac4f17aa110ada2bf1ac65a0bfe52 mainnet-01168-a23912b4.era1 +d57c0d867db78864af6e6ad62d9022b7ccf48002172a1aa41bc112eba378ec96 mainnet-01169-0737b4e5.era1 +595775629d10dbf6dbfc752293ecbdabfdbf1c3184d40647b3c0ce5ba4364fec mainnet-01170-df35982e.era1 +475d800ecbeda476068354341f9e30efd0d3a9d2e4c2d1bbc3d2637460d6c958 mainnet-01171-cc7466dd.era1 +e170b5a5d077f5fa1071220a290e99d4ec0e6cd0f08c3f489cc7e3e8f5a5fc93 mainnet-01172-9abdb4ae.era1 +c7bcd71886900eeacb2cfa148731845d27ea730b76734bfe3912c3d804861915 mainnet-01173-cdbdfbc6.era1 +61e83598aa81b1ed90dbabe6ae4e065acda4a00bca83120c96f0487091c0a52b mainnet-01174-d79c75b8.era1 +6530e6d619c22c585b2d5278fbc722fa6d5c4e50db60b13de50f41cff7f80989 mainnet-01175-0d2dbfd7.era1 +4a06ded80069ad524f38a81f7ca340b28e424dd7441be0ce07658a7345740e3e mainnet-01176-94adbb4c.era1 +c2f256165eb05f8819c212499ba030f8cf8b350c3f37f756ff33f188106ba8ef mainnet-01177-d5e0dc5a.era1 +0c2fd41d9533fe0058a63fe235bf38fad34e904f683bb634fbca5cd8c9eb970f mainnet-01178-5c34962d.era1 +f4ea75ca9d75c6d4114c94d6ce904d6775e668775d17e84f6cde3cd3fe0fa8ea mainnet-01179-1de75523.era1 +9131b648784028a47f51ad723bfd375cfe5362bdbdb3338da8676edb008035d1 mainnet-01180-aac82868.era1 +7a487ba57da5bb3fea8ea01ee909d2a5498e5af9a80a887ae69a67209f4d2fb4 mainnet-01181-58996635.era1 +03deb922a1b8f3b5a6cd0ef5cff55a8a9c8b4ce3c9d77ea785e20f3cf0a1d43b mainnet-01182-74b8aa44.era1 +1cbf90260ba688290b8ebcebb54f325b5c6c2ca310491fe13ddff593c0f7bacb mainnet-01183-38d85671.era1 +0d29d24eee891361ad82df1862ae5b1a2eb2773d1c1879c0e01b2f2702169468 mainnet-01184-2a82d902.era1 +5a49dba599ff573884652f69cebdc81b5cab86982cded90b0b9092b412d9edad mainnet-01185-528d123a.era1 +4b0a6ebfb2a328cc7f6c7c3bebce5862f31387e8606bf9d728d07ad6158c026b mainnet-01186-dcefe6dd.era1 +6445c0340ead092dc5865fba846ad190950ab0ee68ce57a8655bb894ff5940df mainnet-01187-25b5519c.era1 +13977d383ba3945eeaf510ddc8aa731ec973e8ec208659c69b845db89478e4ce mainnet-01188-a8eec328.era1 +a24aff2c666efa07e0ec015b1b64a05041252b886a496295d849b49fd3cf29d4 mainnet-01189-09125340.era1 +c814651f4c00d1053e3810139062efa6203e323e06d859d9391d6c4ee6230f94 mainnet-01190-13085b0b.era1 +07f7ec8d3cdff76faff689a7ec5bda388df986a9742cf2da26e619964cadefa9 mainnet-01191-e8d4138f.era1 +345256471129f0b8bdfd544e6aa6bc7b4da7d8a5c9a0ec93ffdb1950d4455013 mainnet-01192-7a4ee217.era1 +a7ad1020b5aa38fa4ff4d291b31a0228e854dbdd3f1f115956ab463613602bf3 mainnet-01193-7c6dae3a.era1 +83ebac2b6337b01ccb71a1402e1839fc8d03b5adf952e7ef8d123c55c0376466 mainnet-01194-7d063ead.era1 +b828f0888a3c135d1af5e335e79f84928434fff164788f06bb489e2b738483eb mainnet-01195-68a0b792.era1 +59d92764901edf298f803a8b48cda4ea0b79e0b2df52e44b944f28b5d5ad7abb mainnet-01196-94c96976.era1 +9fc33c270dd919d77d97cff2fdd85aeccf3b52e9b13ff72a1a246b6aa605cfe1 mainnet-01197-a6c39440.era1 +4816e2a372f205e92d1b34b7be644441f6cd051d9e9ff9da33712eb69737eb4f mainnet-01198-f7a5ab53.era1 +47bc5ca9bb98735c1a97634dd5d02adcbde5945b3b5964fd673b5e9384b92659 mainnet-01199-84b9e12a.era1 +3b50781f290fa2ede67e95940889e44bcc370e85ca0c84d07964e92b311b8a54 mainnet-01200-a6b6a963.era1 +0de9940cdae7cb587d710cb901d0c07c823a9dd6219364d6f7918840ab055aff mainnet-01201-4a0c7f03.era1 +01481f0c79e7e0ea2af40b80d4b5a38f7726da1a868756f0d8a9422da84f732a mainnet-01202-5486c645.era1 +9e8947ebe59f2eae8147317f22626e6ef424c35050bb292c4f9b74d3f3861c27 mainnet-01203-08a5313b.era1 +13bb7f536ddd6d9f9f9fd21d684f2ad2118b0464c1f733ee22ad1dbcda66abed mainnet-01204-97510371.era1 +86790f4e75276ee19dd2ef21c8c9a95038bdb802f95336486756bb5799e173a6 mainnet-01205-7bbd5580.era1 +564fbc2ad3ca12d50b9d1d892ac91d701bc441540e41562329a10c14724d3df0 mainnet-01206-61e11a8c.era1 +41c7147e448add71a9b21c94d4bc1e49fdd6375cd04163d71361b0c0298be39e mainnet-01207-37459490.era1 +6f5772cbf97c2f3ed2cab5990242a8678f2bad69a7cae1a45224ee3ae5a8b5d6 mainnet-01208-4d0cc348.era1 +192ea288f03a1f59bf08d0e06ee519f72320192bef37f680b62d5d15a02e7f20 mainnet-01209-2008dcc1.era1 +5c5c25280dbc637ed83fac1e4295e06aa5bc462d403d7e3a3b38badc43463fec mainnet-01210-842d4195.era1 +a3281a2c120c19e73bbebda715847cc20caf2028bb9d647ea2089077c86c84a2 mainnet-01211-a9c13697.era1 +a6a026943d1ae7274de83838b877b47984f777b7df1f3013bac62ef560107ba8 mainnet-01212-a6435d49.era1 +e015c22e00634dae4505144d499554ad363523371a3e513d97658b8dafe15a4c mainnet-01213-71e5659c.era1 +240f1b91e57a77b5832fa055e91b67f5f97a42fc54764bc7ca488453423e2f61 mainnet-01214-1791e683.era1 +332dc15434f7af625143c6c3f5989addbad7f16d3b07538c06cd7d3703ce1fa5 mainnet-01215-b250520d.era1 +e80c9baca725dfa9959794b280d70b75b9f67d740b88f06ccf69184a24e9ffa9 mainnet-01216-a13eb7c2.era1 +6a2f77b4f9d7067ffa99d1f67025534f533b14a06327b63a4ee94eecfb57b6e8 mainnet-01217-5c83a392.era1 +c684f238f79e63b0deac70898a9f27576b1430517b3ae23b50ee25069592d1ad mainnet-01218-c13220ea.era1 +88d1d4adc93b5680856088abe8d31161fc8360188b3d040aca98d7e126751c46 mainnet-01219-5f56b030.era1 +d9e73a19eb37d4987a28e07079107e3cdf3018052b6a9bc348960f1eb7a5cfa2 mainnet-01220-512900cb.era1 +657c125ac26f2c42bf31158a411d908f2d2d73fdbcf628844583cdae9d62cb9d mainnet-01221-90c06f46.era1 +e4615ab4867d13f8c216508f6a4f99ec9e953d5fb352e06eb620c8dc38526fba mainnet-01222-096acd86.era1 +d8ea23ac75bdbf10b3e5cd9a695a6d112fd9fe4d129e1922d68de12238622266 mainnet-01223-1a1baa66.era1 +1c0ba11faba7076a9026e4b509a8d3e55f2dda54d7cca819e71c10d65420fc6b mainnet-01224-34f529a2.era1 +146ba8c0070f24c129c8e055bd1c45acfa87a4fa07d2aa0171f3f87b142d6e39 mainnet-01225-ad7198e0.era1 +9f04e9b228eaf0f6c843c109f93e13b3bb78a76efb6e21febfe2b74f3bf9390b mainnet-01226-2d858029.era1 +83210bd4c642258e31e29a69fffdd44dca7f81d6076b06fc6107ff3c577c7a8d mainnet-01227-bb9ed6f3.era1 +40da5526ff0164147c683769be2b053ea2b18a3e43e760bc7939a2b0b1dffb49 mainnet-01228-024d8b09.era1 +9d9ede24c506913cb27a328c56f60b5b8668f83b4c96f6f1851cdf4b4fec75b9 mainnet-01229-4fbd23d8.era1 +da688e247e00489555c25570cdfb9d6dce177456af52916974220ff0fbe3aa7b mainnet-01230-b70e3603.era1 +f41306c021272c4f2bb438f77ab3f2e2e734aac564d0de4890e96c9b435445b3 mainnet-01231-76e468cb.era1 +a056a64ab8bb0f5aff4c387c824e4bb321e9a791871179b7334c734875763a4a mainnet-01232-7cd7b651.era1 +787d4bd2d9a7732648d4a82a4742e1613c7ec44cd9b05279a3e436c391f598a3 mainnet-01233-d077ca78.era1 +276bd1a16a4caa8496fd6546afffbea6bf77b95fd27c4a4a93f774c0f9c8a620 mainnet-01234-ccf5a0f7.era1 +b876aa33ef886b8fda3e0b6c662e414379255ef4637910a1d2b382cc93bfa675 mainnet-01235-d7666847.era1 +e7306edbea916db1689f079213a57c7ac8d85862fd8f7bef3c5787a8f060fc04 mainnet-01236-3d10b175.era1 +78915d2267090010736974de75be869bdab6a1c6eba2db6fac98793511da43ec mainnet-01237-cfc709d6.era1 +1453318be63fa843b9093a8854d6637975c7c101fde14290fc48edbd45bdfdd0 mainnet-01238-f6f1e083.era1 +653839c244591ffdfe2c587bbb525bbea199dec20c2b76eae634d1498db2d642 mainnet-01239-cbeef9b0.era1 +7f02d914a1ac094137822197e7937690b94938297c3a5528611b7a7e31a1f000 mainnet-01240-02688fe8.era1 +e2e49c79ad5c755d8563f633231257c72df94c5d09024cbee3e11b2b7cf1afdd mainnet-01241-20ebd652.era1 +ff4ce149bb2465076266a0267034440bed5535c2074eeda82909684b472c579f mainnet-01242-ceb89cc1.era1 +35d472dc040cb1c04a39c68bbf638485bde139c63ba0dd89c04309801bc5276e mainnet-01243-6ca6a14a.era1 +f6d2f31e47435a9bda50eec2e5bc2a92abf11399f021e1eb90aa202560e35473 mainnet-01244-40769f6c.era1 +58f234bc312045351066024a1a438a4de4607371fdc9f721f994f1fef1efb76d mainnet-01245-f2f56ea6.era1 +e9e84173f9cb74d9ea02f965c0af1bd634e80a98cbf90ecc9b3ce62ac6e11ebf mainnet-01246-c0e897c0.era1 +c5c99e8a744476544b5ee1f63c1f884d9c11fd24fe47c2e8565215c5c09f77a9 mainnet-01247-58d2fe58.era1 +8995a517ecc43dd474ee81d84db7acade36d6edd2db327e086ac1789295a5f42 mainnet-01248-e2cdcc7c.era1 +0230977840319fa93322f591a7b920a54dd91dcaeed3ca4d724d4954313d6598 mainnet-01249-379da93b.era1 +36069d8fa590faf508b0b64684e967bea94ef01b22a87c0d7ffc1aed3be390dc mainnet-01250-afede008.era1 +cdc6b15be72dc4095678d8064eb2734c576c2880e546d301b0f90139a345056a mainnet-01251-eeede50f.era1 +9a170f1ddba4379c4e8e7e9a9ac8f32bfb2e43aa05c3e6399a18cf48c941f6f3 mainnet-01252-c5b81847.era1 +a49221586db21315e377b927628313f9dcce3ef9b2b644a0b38d5498a78af290 mainnet-01253-96748f67.era1 +4f5c59d345bbfe445f576c69e84b93f6039044dacd90be7dfabbfde6cf16e7cf mainnet-01254-5c3badc9.era1 +54e2236adc2317eeb9f8a8b658c6dc7c35cd945809a6f27d2bd63fca722c0170 mainnet-01255-2599ae05.era1 +2726f17aa58942e5b5c827b3c8b928c285e87f873487687525a30a5a1a111476 mainnet-01256-2b44aee4.era1 +723b298028bf04446ac6e05b2619130ddb65adf23f6f5829e27d6fc92273af79 mainnet-01257-4952c512.era1 +596689f86e347d0b40880a5d550ce7947b3d175b810f7082e54a48df86174bda mainnet-01258-713aba14.era1 +c0dd89598b20a411b933c13f08d7c6fb19a16029b74f99c95d089e4915bfd95d mainnet-01259-1ae7b5ef.era1 +0094c7609647801d3b73fc03c9b8dcfa2b8c7edcfbfcae359851714a7b87da4a mainnet-01260-6f90c321.era1 +e4022bc4e10f4f03ae45dece6074679a850dca4ecf4c4e26463163f8229812d6 mainnet-01261-61d416a8.era1 +50aec2a2f05df43c4b112afa8fac437d25b5cadeb45a53848e064fc1b9fa5579 mainnet-01262-aee21385.era1 +9a2e557765a00817c1ce2dc32e2187ea9c0e97d81284725e6d1cd639dcf63f99 mainnet-01263-9fa06b72.era1 +720e8ee102ac6a4efcd44555926085355c238752625dafee6afcf826f7e9b113 mainnet-01264-53a8cc3b.era1 +19a6fa6f6a05862416f0bbd72549f316e21921a8625d9e3f020b2d9dca6f2844 mainnet-01265-1366aabf.era1 +60ef14179f622a314e3e63abffb42ee6e4741aed4eb6983c8ef5868677f12f89 mainnet-01266-2631621e.era1 +1004d4829ac69cfebfcf177b73d7d3ed7248ac12b9713a6fb9db3946cfea9f5b mainnet-01267-3dd94158.era1 +1c772e74363742e058f003f19f65ef1ff87646defb9946e2bcea1f9c060adbf3 mainnet-01268-ed99cb91.era1 +d1cb3fb6577e706d164d668977f2c7f1ab4fb82d9a6dd192a14c309ccee89d4e mainnet-01269-3e65584f.era1 +bfeb65c5ec20f46232dcb9869fd6f3a016bacf4aa679b01cc5c0594f522f7177 mainnet-01270-69ccf142.era1 +96a1923cbf40ed50749fe02ab6ba42c8fa3dfd6eb9e1f0a94a35b70f9b78f6a0 mainnet-01271-66fbd4f1.era1 +59de1f5a8fba96663a39a5c2b1b8df45c8e86a6833ba4457d93a86cdca9abdb6 mainnet-01272-7f448c5e.era1 +988b890503c163ee6ffd22acb6c5576cf4f6614f8f55f4db55ecfad02947f36e mainnet-01273-3db6b5ee.era1 +cc04d78356f4762e7753cbf6fee1f5372486feeabf83b5e71b1761626262a30b mainnet-01274-63adf378.era1 +10354faf8a0bc80af4ecff9d5300ae12aad11f44dffe0d03faa1aba62c2376fc mainnet-01275-0c89bb3e.era1 +90fc0dae0ef111e66c11355fde4394e575f54ccf114ac328339877393701165c mainnet-01276-399bff64.era1 +a85a26858ca53bfadbf0ce9e3e3f6d9cf0339d4776b1426594ebb9a59ec031c5 mainnet-01277-1b14df37.era1 +6cc09625423c09edd772c178537799b9574d71548dbea2d979e7072992e1e1de mainnet-01278-7bb5b295.era1 +39368cfc2ced10c4e0abe27cdea8351111d17948a3fe560a7cd866286facfe29 mainnet-01279-4ba003f3.era1 +38ddddc4c9ec93c6f4357d8dbc1033d16efc0c2bddf56f7ade6c474163d56572 mainnet-01280-2ab6865f.era1 +dbc86ae92832c804bd6c9bc6cd2023a4577a7fb2ae5e5965173ed0b67b2e7c49 mainnet-01281-a5598247.era1 +16412dc3d507e2f5c978903f485fa3cabdc393406c3ac256441178242b11e45a mainnet-01282-8357bfd9.era1 +af6e6c5a9064469827ecdc95afc44b765a5f0711fa90d422e021ef12e760f7fe mainnet-01283-b502eea2.era1 +42c1ddacf27e325b14e8cbac5620fee7b90c0394a7e218365d4d899184f0b410 mainnet-01284-f9cc2497.era1 +c4ee83b0840b9e1491699b6b4f4405c020401d9a810c5380559c2108eb9b0c0d mainnet-01285-5ad4fdc8.era1 +6e30672f57f37ac89737f32765fed41b2fec36249b32ad7dc97eec4bfa7fd71c mainnet-01286-4de64a70.era1 +4a454402f31522bef8aa28fe8852ecc3307dd3d918fcb67d19dddbce3885c87e mainnet-01287-1cd8e301.era1 +c25655e481cdc4fc991b299ae067a6909c359d62dea887f1cf35e954f6971ad4 mainnet-01288-461721aa.era1 +58163222d18ed04c31db06ee1e77e60a83c5461459113ae29f0b961608df2337 mainnet-01289-d776cb85.era1 +7e28f52f1c043b809b58d97dfb880206494fb0075723e44c27c021a94fa6b7b2 mainnet-01290-873eb969.era1 +017542bedfb0b360f109d76bb52ffabfcd19eb20ec45498c57f869254fd96efd mainnet-01291-3466a370.era1 +7029158d2d683f09729cee8e39314828ee0565277dc2757759c9cefa8f8de1ba mainnet-01292-f7c7ef3a.era1 +8b861921ae93420118284ab2a290c0dad9d500c6c7b81db7726f4174be0cf1c4 mainnet-01293-eab36fbd.era1 +09bf6ae22a2291d050a1a996c42f015abb24301150ff29429fc2ca5b59cfbec7 mainnet-01294-d38b96b7.era1 +f08965eeb9fdc69f3142876a0941078b2c7f9701cb389785651f5ba6d2425dda mainnet-01295-9a8e547a.era1 +3099ba185db6d2f9db70ef88b49344d867ded95a09234dc642797c73c07fc8f9 mainnet-01296-044263f3.era1 +8235ab9b1d14e907833ae85ad4de8822a40df73a7157476b35b24cd6bf266dcc mainnet-01297-2a6fa840.era1 +c83e6abc2c078e0fb54d55370366a23c06d7e9f4ecb66fb7c2deb663b68ae98e mainnet-01298-25e8cecf.era1 +e7968bca5bea8361d9777c057d0cff1f759a2df90cf1f42543363ecc1ff5718f mainnet-01299-4783a5b4.era1 +a8785b8a11f423ef761d28e7a3a8940b436675890437aabef419817407eb902b mainnet-01300-05128f56.era1 +9f0dde66478065a5173ce5bff435a39ed2dc1c30826cc1fea205f65ac79495e0 mainnet-01301-f8ad3107.era1 +a9d03ede167e577bfd7bca060df5cf72436b9a1ddea598e4fec170b221b83032 mainnet-01302-564f335c.era1 +280bb64da624126213fa779695c7ee32bfe187c2fa4a9e31c6af92949e1bb498 mainnet-01303-0dd93fff.era1 +3e1b58db61947c5a1b45ada5c9c64d9686ce421174dcbbab5c5a65134044f32f mainnet-01304-20eaa74f.era1 +4875455d7119b917fb82f49b255dd769169d66c8f5b7e40646820e0cc1cf1b84 mainnet-01305-d00fc022.era1 +b29fa8400d04e6b24f89a39b9b5e8c343d36f44d8308a739e786087edbb6ed03 mainnet-01306-1f67a41c.era1 +a060656d775c6284c53f1a36d79b1ca604e2e8bab852b3957fd43d3a0f605c21 mainnet-01307-2f77e7c8.era1 +81b2c72440a57f9d3b04ad238c9a7133de2f1efd020f62bc5fb9394eaada69ef mainnet-01308-8eaf029a.era1 +256a812c87b6737aa725ca16b854cc48bbee781c23e1d209c93fc270b1b6b1ef mainnet-01309-0e9134c9.era1 +920e4b3be271752b4fe53a3a07ff32d06caf07b1044c0dc817ff4962ddc080ee mainnet-01310-36d0712a.era1 +daf44c55b9ee3b0d0237ac386ffd61f8594842b00fe895f0e8074019a0a3eea9 mainnet-01311-b196f52d.era1 +81a4a2f671007b73025cad89c68330c3138ba0c547fe18af2aa3955b1a8feedd mainnet-01312-052a3539.era1 +e2c81f6dcb0ca87dfbdbc2752449a52b5cdc480851305d64ba155500fe47745b mainnet-01313-ed3d98e8.era1 +19094842e9d0e78c761dcc6661f6d1763e58964470451f2a2710ec93b00f699e mainnet-01314-6711d975.era1 +ace576a9c744c7c38f272e111c62da33b4fe65a8f5edc619a3388dc4711003fc mainnet-01315-c90257cc.era1 +7abfa2f8199e55bd438d77f5da0f5bad1127d8a74bc99a9050516a4f2c383dbe mainnet-01316-d23ae50b.era1 +18bfea667e282bae9f4f0e67221452492e49a8cd53e91115869091036c4b91b8 mainnet-01317-b2c5b1b5.era1 +f68104365e1e4abba936d17bc53868818601f152a441f6900177d2dc56b4014e mainnet-01318-803d224b.era1 +a2720d85bd277b218f7f68d7b1d53557d73479267f40da994c5d9135dadfd7b4 mainnet-01319-f7082c22.era1 +7a4c8f4df8f7bd62dade2adfa030ac0742e2a55d6da79ec4382a592d70b0547f mainnet-01320-66c7f004.era1 +ca7665fcac6d8f77db741b44e976596a0a0c785bf199df49df99553091f63ed0 mainnet-01321-04af06fa.era1 +7b31771617b1dc5b3284a0e2ab301fba9ec12b621dad9ccb5571bdb0375aa648 mainnet-01322-44c4c046.era1 +56fae2bc1641b01ce37537b761530da0ab4cb9dd8e166b805f32f199c4e75fd6 mainnet-01323-570d0caa.era1 +f638ff307a6390b3ff8dcbc49383567831ee5a9063f4ce8ef4033ac4e54ef585 mainnet-01324-d4cb7a0d.era1 +21ca9ba2766202aeceb4aa0ff0f4a3046d3901ed8f71786a34a39742ac1c4967 mainnet-01325-b10b22ec.era1 +2b26f4d078ff4f04d8b8eb96de5c024a3b97583d7e891623a8532663181de6f9 mainnet-01326-ea52129a.era1 +1bedace32560f94d1b02d419b4b5f190776c846110b5033dc31fb38230c397f6 mainnet-01327-4f88b085.era1 +0169f104bba10ebe1349fd82bca9bc54db392ea75c105550897e0a63da217cf5 mainnet-01328-83f1204e.era1 +91a7dde4a0edf5667fb04c6c78fe7d38ec2ebde946fb34e4951f39090b432012 mainnet-01329-572dcecf.era1 +331f8506237bb24cf7d3803452474285316dcc8ea98ef15bf4eef4cc6064b60e mainnet-01330-45db98fb.era1 +04f81f58920bbbf42ad4a2061cf59ebe30596f1fce26dbf6453d6d1bdcf51f84 mainnet-01331-79ac113e.era1 +1027d282aa646d5c8fa685e69a82474a46394d523a26dee346297971155e24fa mainnet-01332-2e02ff93.era1 +7120f994b83f2319c62825655b1cfeb828e30b71a5c700f6e15d823dfeb4d87b mainnet-01333-1c8da535.era1 +090fa69dd9c403e5f94eff043afae39a7e91b3b05071d7e2578cce777a2ab34f mainnet-01334-9983596d.era1 +358aa0ccd7de8410c5d056cf5b288f5842104804244d58d7008618d65c856382 mainnet-01335-4143f16c.era1 +071a5e58f4e5da61d3fdfec62e7eb78f9984c9e691d26a600cacb01ad33ca6e1 mainnet-01336-2c80acab.era1 +5f98ae78a7ed528bbdf91b91eb8300e4be58cf3e0b326b2ab0ef3b9f4288ca8b mainnet-01337-70afebf0.era1 +7251206639c8e37fc1e068c0fae077b0af83ef8d63b5bb2fa08602a145c92530 mainnet-01338-0d957f43.era1 +b9a2ca5ee55eb6dd44d249fb88097cb9e298448ec956dc22069d9a8e1ba3c725 mainnet-01339-a954d4bb.era1 +f5804a500f5c96fc3e628bf4d22743dc3ffd4524d57eef9cc3e11767044611ca mainnet-01340-d259e3db.era1 +4c2c2933f924dbbeb9a85ef9aeed72cf3129e7ac9c4c0649506baf653de670a2 mainnet-01341-a393c46b.era1 +f8b45dc8bc01486a5489e1efde75625201840dcf7fb89a340e81fa1b188a5ab4 mainnet-01342-febdbdcd.era1 +e42589d618af2b21dc4bb69d6f6b120cba058928db76b678974cdc36f21bd1a9 mainnet-01343-c205cffc.era1 +fa369dcce9af813ce9f731510589770e7238f09358c8efde7de2dc3f3176a904 mainnet-01344-e55d1bc5.era1 +a60e9d83f28290d2482f0fbd238e61735274bca66daaa6fa7a59349a489166d8 mainnet-01345-18129517.era1 +751c869193eeab784ee29ab2fdf4598371b9b569e3a31b4af797faa78d98faac mainnet-01346-62600923.era1 +62737b0cb00535cf635bc72b8fad4a1a775545f28415b424b2497d37761a5e10 mainnet-01347-b7bc048b.era1 +1356d26c5b96a9075a842ec37ba5d2a575c28531edf8fd2436780f2a85c6946b mainnet-01348-63f08fbe.era1 +e2783ba2d36fd2ffd8e04c2e347b9251a2772ec33f4bb985a3b56b745b1931cc mainnet-01349-d8f90a76.era1 +19bd461fb3bbf4beb58d475b988cc702624d69b490e5113b690837283589574f mainnet-01350-3b7ca4ef.era1 +d7544dff8e768f2cbd51ab40a3983d707d0ab2934ee29d1289b2eb56c38f50e4 mainnet-01351-a5aeba3b.era1 +01a87d40fc0deb2ec80255fa71092a4e18c76b98fab9eb864100b8474a4ccae0 mainnet-01352-75faba09.era1 +b976cd09d412c661c69d0b1f9b86d301fd2a1348ee8fece91233cee1e14bec26 mainnet-01353-53743d70.era1 +97ef2623262c43289dc1b097d55fbd1e36d0ffd5ec5b82315c1f73e2267eb400 mainnet-01354-dcc29cd5.era1 +29ce252a595b7ce7d16b3620b1078c65266eefb8d392a3869a20f53dc1ab063d mainnet-01355-73301488.era1 +d73ce56c6f635c1eab39a3c8a6471c30d242f44555be00633541d0deaa5301a3 mainnet-01356-c5358154.era1 +4b457254df3087505297c300b6d18d4623f77cae0e68d8bf08fce557abc35880 mainnet-01357-6ae35c6d.era1 +3f4c5e1c267f0f715a25e5bbc0c34eb1974371bf6441fd1d67068135f44dcd53 mainnet-01358-40401985.era1 +0bc31b98df3ca2c46c9f1e4672d6b00d03c5ded22afc569fb9a2ea13ad9636d4 mainnet-01359-4f6b2658.era1 +59a35576c168008295fa658fb87f4ec18aab0d8d46297d911238e6cbc81863c2 mainnet-01360-d0b1559c.era1 +ebb0970c37869805182bb0f8e41049ffcef7e003493e64664ecc61850079475c mainnet-01361-ef5b459d.era1 +f830f6c6695673742e55da926b1927df8ac3b57457971655c6fdc93b8779c9af mainnet-01362-08dfe9e3.era1 +5b1c0b75458116106ac511ea780fb0bdb441db0458b8d531645768d363050592 mainnet-01363-80f7dfd0.era1 +ce4738d883c80ce1874fe3755dc0ed784cefafd7c23009f2fb98f41a50e1e492 mainnet-01364-4b47710e.era1 +1b5a17c77982f23f514e1c6be2d88db5c0faa788fd87e774f4c5060e42148ced mainnet-01365-cc79e6c6.era1 +0fba63789d2fb5ea620767e7519783329f805cd16d1c358797a879fc6d81f640 mainnet-01366-d76553f6.era1 +133d860d3af93f94ac7fb78d709b16b39d50302978e7ab26a3f62c00cbe7dbf0 mainnet-01367-d7efc68f.era1 +a0b2820cbf08ace921eaa12a316be9ebd6adb81ce25b67ae3c4f9febe9862b1a mainnet-01368-17ea70af.era1 +53da9926f9aa968cf1d2c047ea37c7cdd922e650d01544f3c90401ac7775a91d mainnet-01369-f4a498df.era1 +b13022fb1a11ca7c6b0ea1e6e588092faa2593e57dfc5cf3f611ef45f61f4dcf mainnet-01370-027e2a2d.era1 +e9ddc8dcdd6b9082f522e2186571e929fb967d06473227f2c3bb69dec33f0a99 mainnet-01371-b90ef17e.era1 +49e5c55886a224573ae183904879fea6e59afdab572f78e4bd764ab8f1d12d65 mainnet-01372-b4719483.era1 +d8c7e3333558f050ba0594202e01e757fd8380626ff315e79f9c8ddb33e14202 mainnet-01373-b999269e.era1 +711aecf03b8bd204e770345c60ae0f3879e0a5077784a1da0c9ea4c12d65a3de mainnet-01374-662f1591.era1 +bca1ff381f460cd89fb9fa87c0f015c97a1eb22ca36158587ed4e96a96776abd mainnet-01375-108ccbef.era1 +5b5e841c9e725a1027a6c8938982f37a2604cdc308a8b77a9f24f1467b1f8fff mainnet-01376-54d29629.era1 +6cd2cc7e83c3ca0d08bf49a40f0161da41af1d6d68f341be4373a19b2abafa32 mainnet-01377-6d7bcae5.era1 +7786fd64d694cdeb834964cc70b7595d7c76ed236c8e0e72593169843d2a5188 mainnet-01378-fd477f0b.era1 +5e6428929b7cb5aa3eff3c4e0249306957382e9e304734c7ecada18dfbf2f509 mainnet-01379-57b72b9a.era1 +43addf5c34b75fe9482f8328072645bc17ef9aea096ee4f7c8b8512ce0f40228 mainnet-01380-beacd779.era1 +8900a0de91e023699743f61ce33457c05098974403b10fba0efb7a2ef004770d mainnet-01381-4b6c0027.era1 +46b507c7a377844c294d2232275f05e5a59c6d0fde73d1c00fcf11e32299bf64 mainnet-01382-485b0ed3.era1 +b1e23b51dba1636103604950c469b01028f6e641c3c5cba3a62c8f6d745e09d5 mainnet-01383-402cc664.era1 +064ee6442baf410bb426782b90948d3fd0582906c475d3729040b1dbd7ae143f mainnet-01384-547da0f4.era1 +4899fcc76e8069936a49bd0707a11ec90ecae225e238f42a8bf611b9f6604de7 mainnet-01385-058c55b0.era1 +3ed4deff02898719e040db928881e6f21edca03304f0b615e9174d27e2af5c3e mainnet-01386-951ddf6c.era1 +c6022db6e9081c7c30f451b3266e2aa639d22f95635109c31b073d500ee056b7 mainnet-01387-85a7797d.era1 +30030a87c2356bfb803d8a6638af8946bebf986b5a421833a019bf83cff0069a mainnet-01388-64376e67.era1 +b9eae82bd40f8701ac7970f24fd84333d41f960b7b0f7ea7de66ac56050bc41e mainnet-01389-58445b6b.era1 +43a3608276f808e23937ce0121922459293a605d989850496c11ee138b9fa988 mainnet-01390-6a2d6ce4.era1 +3862c2b6a685a4296890825c26ff10f133ae8b2a0ba526923780f2fbfd0921cc mainnet-01391-330e88ac.era1 +153b03e32abb8cac2acf2cb8596fd0d7bae740c7ee7984bbf705648008492ace mainnet-01392-3bf42cf0.era1 +151e349aa5c132e943c9c61f0d8dcdf470332968b1ac8f64b813f4f48ee1f23e mainnet-01393-239fa3d0.era1 +f0e0d1ff10a5c4538b3e480234b397dcfb5ad2ace98003135b3f400f672c03c8 mainnet-01394-76707dbf.era1 +e8ae97e74835238f588fea6ac5ddd546f0aa27ad4a62855690005a4da464f975 mainnet-01395-4bcaea6c.era1 +c8c7fbff86d136da6763cf2b990f54f4ad8c9f0e37a6c730dac52ff7e7bdec5f mainnet-01396-cc5b5c9a.era1 +59ee08c1ff222371627faaba48a1fcc6eb78dff5747b93908265ce86769226f9 mainnet-01397-ce3fa54e.era1 +24f8b067471cea0bd15e36bff586b4ae5715c0dc77275886a1da2d3ca28a303b mainnet-01398-d06c9a04.era1 +2971dfd0ab5cfc0585a4c75803637377efc89aa9279877b74dd97408b5f609a6 mainnet-01399-e131599e.era1 +e039e2e9f725c32a61574919b26232839a73a7844b44ae60a7c8963214f03354 mainnet-01400-1a628757.era1 +550c715ab4f6128d0f5fa9ffe1c2eb779c3c8e6c70562a66c80218da9698310f mainnet-01401-e7d4a880.era1 +68288f605024621e3e14cf90ec1610c42cbbce0b69c6af67ae2bd7358c3471ba mainnet-01402-85d3f303.era1 +4bf2e03672a4dbee47b8f5af34d296a30026320c9c4c23947e0ffe8435888219 mainnet-01403-e1e41aa6.era1 +26a0d4a885854d083fcd9e37adefa805bea73412145dfd3df665baf96a3200b5 mainnet-01404-eba27a23.era1 +c0b5759280ebafb0e867da46e4d5bbf5db7a8d6063b54dd6a0e1bfeb7743c676 mainnet-01405-b0ddf49d.era1 +23253a01baddd96f8dbdfffe9d1e078426b4677d3d12e5c2e7d5cd004ea60faa mainnet-01406-651ac24a.era1 +f8579d34d6bbe198a7a8827883b216f49b1342dedca2598fdf6476d868d282e6 mainnet-01407-a76ac2e0.era1 +50ad5742fac9ceaba1c8f4b470b4abfc7822d7ac2a33de684ef6914f748c9ee0 mainnet-01408-209624ba.era1 +e11fd2f4b0ceabb5b87c78bb98c1648e89af91a4e874e5f87c1b1ca3eac4e262 mainnet-01409-af729a25.era1 +cdda1247b3e40b95c52348edd0dc7adf00295c49e5e690abd7b5ef6974280529 mainnet-01410-a53b25ca.era1 +ec46ec3277de6aec68923500bdcf2ece80317e51bd8fe23062c60b9a93e5f364 mainnet-01411-00cba9ae.era1 +cb214c5b3d56da00ff519257e9b9c3753d2cb3293b8d3e8f727b74f1d4912ddb mainnet-01412-da3d50bf.era1 +94cbf93ced0fc4aa95ef7bb9cdbd9e22771e876e630e6fde313851559eed8f60 mainnet-01413-fe77f727.era1 +47d326864b404343670f3d4017c74fdb808218909f9c5fe5298668e1cdd403b8 mainnet-01414-1053d23c.era1 +2bdb9cef6e02b7435c7cdafd0f39973d45b3e36df274209287eb311d291947bf mainnet-01415-1f9ee408.era1 +449271b516378b806099799baa60f6f6d18994f2b2f228e4a2895691ff244855 mainnet-01416-162769df.era1 +d5e996beb771a4bf530244ca6d7cbf3e56f08ac58c5a359cab963c66e26514c1 mainnet-01417-6904f505.era1 +7886d7c1e992bce0026ca17feea1bd2e4ba79a044c4ae90c04565a82a1825e60 mainnet-01418-66837954.era1 +b39df5fdcfbf4b5dc24eb93b64b9842405bd341a2a24a3144859874812918e1c mainnet-01419-55bb8c9a.era1 +54f228ff43b89b77285bc0e0b5455db5f827f54a19cab17fe1ec8ed10578be71 mainnet-01420-37cb2c92.era1 +c649dfcd02b17c2db486d4b615d85bb21c1166a18d1c33d305c356c15f763c63 mainnet-01421-05b6cf1b.era1 +fcc2ebd17639a49670c82e7a54da022a48245d63f8044d088facb416d79d49d7 mainnet-01422-cf249616.era1 +2620809bbec0a5182223dd203fd74b1dce08122eb8c616cc4ce9443560b63657 mainnet-01423-8500cec0.era1 +0f95398ea8a61b7d617990214131cce800ac947722bed77fbb28bc8f3e482a09 mainnet-01424-f9b23ca9.era1 +4635f7300b5365a9ff84e6277235b580d679464518869c52fe0c071eb201534a mainnet-01425-2e9e77d2.era1 +fe37f157d5aa804adca28571f2071703a2498b6f5fd80486391ccecd0d0e908b mainnet-01426-8c071005.era1 +663f0ed02b6b32aadb3c2a703e62ae0d2f878207f6b41a95f86cc7a467279f9f mainnet-01427-53b8caf6.era1 +5248d97d29eb6998b52c2a1cefab09b16c7c031f673176c570b62341653ae031 mainnet-01428-68be6c9f.era1 +7811c5e4bc35527005852c8435520d59cd902cd41eee2e0cbda7d4f049cf11af mainnet-01429-12a34f39.era1 +1ec5eda1110cfaeec844abc4794042836c8b4dfe9c16ef0a79f6c7342f76d062 mainnet-01430-ff0a7be9.era1 +1ac28630745631a76edfcdb5f2e09fc1c089577c427e28a743db0335f5e48eb1 mainnet-01431-64d4fc5b.era1 +06087f72cea1fd49e3aafa8033adfc4e098ee49bc20642a474c85081c8a70ef7 mainnet-01432-2205cdfc.era1 +8a0fc7e9fc2ef3b49590c1a17f93b7795d13dfe863f609e4ad6ea997b1f0b785 mainnet-01433-e4ccf743.era1 +d58b8c466c548174751d212b73e15a8455adee4f71644080acba1155461bb046 mainnet-01434-77202058.era1 +e3945c73830db6b9a6f7b5fcd17ac292131a9838bca96df6f7e5cb8d173e1c82 mainnet-01435-467addf0.era1 +b6eea12a891a32bb6e8cae0be78406cd260bcb13148ee22ec498d359e9284036 mainnet-01436-8bd916a8.era1 +258708f393377fec046013eb172c2667c6707b9b647698c65d7eb44737c56617 mainnet-01437-332b343d.era1 +0f3939607d194332c2eb9e653b430bbc86e0e2befb2a9e14eeb1e161b32f1374 mainnet-01438-595d9cbe.era1 +7bd68818b8ccad9090066f14dc52845be8668f19ea461d35d850154a18774e41 mainnet-01439-aed3cc6a.era1 +30ea77ccdc53fd2b7034000a4f4741ce53d3580f9625db147a6a63ed42ae2c55 mainnet-01440-41f0520f.era1 +4f7eb2c90307cfac84978570170284598db309420e89e9846d28dd22f6671383 mainnet-01441-e2a38fbc.era1 +72040094c53ccc955ea8e57cf5af40413d1c07e24f8d9aa17a933fe31a39869a mainnet-01442-ef37dd9b.era1 +23acd9d6182cee70eaf6ca004b371827712a13f4110f71ffec7b71e117ba812b mainnet-01443-145a661e.era1 +f020fc7faa8f6dfc515f738dd978dfd6ae9115a65622a861c3ce22c7ec14585b mainnet-01444-9821beb8.era1 +d39a4606cfce240af8de5edd4949ce9687fe7bb2c1111a1121df44f8a5a67cd6 mainnet-01445-728597bd.era1 +d1285ce2512ddb1689343ca9d261047c75b789068b574769b353726deac9cbcf mainnet-01446-5ad80991.era1 +e2a7cffb91e452a16be34901d97aecbaaab166ab10deffe5643bc7063e94472d mainnet-01447-6b884cac.era1 +947fc8b6c496bfe9295cb43245a33d669171433e03d8c99e5eacdaf8c66a9cb3 mainnet-01448-869cb3c7.era1 +c0de9d0a34ac81edd5dd2fad777baa87a0f02631c4d5d9c67893bb2dece5bc66 mainnet-01449-5cac1bcb.era1 +9e94a360b729c2b7f5528cff27e651e0210c85e6c15e2ce329f2b97d5c938f74 mainnet-01450-b9278411.era1 +0b46c80caca37c2f6e81c71fe22bf7e8dcd7eb9820945170c4db1cc604642a29 mainnet-01451-32f5e0e5.era1 +029949a8d6a72ad330a3ef4de2a0fa0f9dcd19fa0ef9acd77567a76f0e66d4cd mainnet-01452-b43138d2.era1 +655e1d40f4460af26df21fbf85fd19f369d6ceaa04b94b662dbc99647179ec72 mainnet-01453-34bcded8.era1 +c0d73fb7410233d63eb9530dfd029d37b626b96dcae5ee67d53005613c2cd162 mainnet-01454-11f80fd3.era1 +3c7acdc8951c4da16a59c3413ddc92242e7939f4c694e7afdf392e610d42622d mainnet-01455-18ea77d0.era1 +8a0daf91f9c12c1d42d974d081e192dffcb4c69bb392041e2733d96f0c482d52 mainnet-01456-f1aadb7c.era1 +f4c13615dba720a8f75fdf351a3f508bd976c4ae83d67adb3cc1d2af8ec9c152 mainnet-01457-d00e9e6f.era1 +875f458bc26979c34e221a0e9f4c6d9951a69081e88a1a6658466ab490b179fc mainnet-01458-7ffab11d.era1 +e48729e17d5606eff2088dfe1f918d780fed77f54cff97d00373e6ecf9cc1027 mainnet-01459-6039b280.era1 +1a272e704e29a3a720c8d494b4e85429e8ad8efba1e86d03d244e42c305d607a mainnet-01460-8e889e14.era1 +57219d1e9b7331b75cdb5680b4a220cb29250d3a946036bd1760e488bd503c56 mainnet-01461-773c0e11.era1 +d644c1708407495e82dd2007d3daed7893c5436c8163b8d7ea12ddb11c626882 mainnet-01462-df1babfe.era1 +328526d39e8a4827a45ec6f6aa3207f20c75d4a8f234b3479ddc53507ee973c2 mainnet-01463-6d328022.era1 +0d763982c38b56ad61733141aad9fe28219639d3afc1b4add07419f8fefdbdd0 mainnet-01464-1c7eb43c.era1 +bddecd820bdd0408dc8e89728fded6317386494ce38b163846f2e69d5388e9f1 mainnet-01465-10ffef9e.era1 +d9595c500b8d4b83015030e238e9accca337b461b8ea05a4ebae657dbc4b2847 mainnet-01466-7785bbd4.era1 +c3a1ffeeb26017bcbc60c02e78490ae606d464f96c1415e42c65a59d5388e823 mainnet-01467-b09a9b8e.era1 +7f1fef22110077eaf5299fbe2b68dd2bc8e32283ec71baf34166f8472e9a87c9 mainnet-01468-1919baf8.era1 +8294a9de1df2f713da58ad385fe5f998bb7f357cc474132515551fd07884ac37 mainnet-01469-6338bf7f.era1 +4b74fb9a3a8edd99ac5635c148618a0852c669f63df0c99659ec95ff3b88e82f mainnet-01470-46fb7a9b.era1 +24f0d5f8cbaff1b381ff0c856ab75bf59e8aa56d374e5848fb95ba6fde700f24 mainnet-01471-18fb7c8f.era1 +b7818f256e53486839ba6d6768f0600079597b9f20522265192ac8030c745e49 mainnet-01472-47a32b9d.era1 +7b1cf4d233aa7ea6fa0d870d1a7e1ab30670ed65a145acfa1f1b80969a749df8 mainnet-01473-333b7e86.era1 +8cd04cb58abc7da45f99e366b10bb73ccb7dbbdff63e9707a49cb7f537875c2e mainnet-01474-fe24e3c1.era1 +cebec68718bfb963d022aac9913c3b8dc753bd91c89c922e6175091bea150f58 mainnet-01475-81c78370.era1 +0ad4e0b20d58b882e9d6aa2c7b175ae71b68a378f8fb2db7ae5ce757d47067eb mainnet-01476-857187a1.era1 +16edcbdd31ef409559db026df862893ec3d55def3f6fe3b89df08f11ad198fa4 mainnet-01477-ad00e0b4.era1 +219f03a7b1d6b28beae01894b62223d9b14a31b5170e160911bc198d2fee19f7 mainnet-01478-8994eaa1.era1 +11e4ecdc331d0682687fb25c9b0074509721401a1b3805d7e4277c5b9735002a mainnet-01479-cf4abf0e.era1 +1004791f7fd598673fb3f1de73099581696dee5d58df7e3ff3f92735085f44c0 mainnet-01480-ae5f5367.era1 +aaf7a7f356371cedd630168afa7b5c5c66ea4b0f8f4f30b9f8f770d0be2cf5bd mainnet-01481-a121c10e.era1 +4359f1ae454034430f427926f775c92837066e8b816b8e77b48e315e5d3859cd mainnet-01482-2110d171.era1 +d85dabca73e870a41464dfb9d0d621e9302c7169d397b0d266291af6ad74c007 mainnet-01483-56ec2844.era1 +44ea248447182e4fcd1e02ea0029a9eb29271d4e4be6963113994ff772d4206d mainnet-01484-ba8ad4f1.era1 +159518bed983ac81d742d28e0d9c36aec9da2609bb7831a3ad3b692ac7045835 mainnet-01485-c56c3ef6.era1 +96e628e5f4548dcf3d691be556d909893a786d4e743d0c3a7b6fae6e536f113a mainnet-01486-57bc4104.era1 +631a3635b6102e3025d7a81a4f3d203a5e47907e37aba13ea8127123c7b30c55 mainnet-01487-122d8e0f.era1 +5f08d89cf44c555c7ae594a113688e8ef660982db091988e223d86e46837b324 mainnet-01488-42b25fd3.era1 +e9ba8cce1fec966b0237eac6d47873cf198b0bfcd9426ee4484c3dac7fd94d5e mainnet-01489-b1acea4e.era1 +a232396cc9d4986fd24e55121f721c85d3c7138853c32c63687b90ae37804951 mainnet-01490-34280f11.era1 +4fbb2af1cc0bc00e2dd5140da8b178431bf2c6144a54dedb045f98517b2e61dc mainnet-01491-503bfdfd.era1 +b31814c8d0016b4655779c448cab692824246c916b3c7940bcb5e31f64644ae6 mainnet-01492-1b74997d.era1 +1cb371fa71fc71d0a4a33c17c3d200d8b575601b9cb02a66353091109bd22e66 mainnet-01493-edfb26fb.era1 +189a4097e29f4e1cace72fcb032b6e89ed1601fc56c57a22fb54f072a93f0d20 mainnet-01494-da405d13.era1 +da0d7984339278660e96c34e34f747574c6ad88f06711b2124c778ae809a17aa mainnet-01495-3efe0cda.era1 +ee1b345b735da46f9d6f5d3dc3bd5a29ac626fe846ff013d940ed3835a619217 mainnet-01496-809b00b0.era1 +4d95a40cc150dd87d65db07f2226b41a258709d1afe44ced5a3b8661e2406d66 mainnet-01497-c6923521.era1 +eaa06eef1c79a08df66c3c880c944b8d4b73764d105545ee657d2011cbc48571 mainnet-01498-2ef9dbc9.era1 +0db058c7e692dee965d6c89c3ad3ec2289e157bc7f21e0a48631c13e616169c0 mainnet-01499-23a65ef9.era1 +737b67182d604632e495d3419afb72551b56cd2b6efedaefab26106258013ee8 mainnet-01500-17e97c49.era1 +3402ec4cb8df4a0e73da4105fad3765b8a581eb93fb0099f326cd363dc877e47 mainnet-01501-38815f39.era1 +1dbddc6f53480075be9e42447712038bd58ef70c87535f1d54fe2c0b5554f2d1 mainnet-01502-c31ef6bf.era1 +a27a320d801023f199b6151e982305d28bd09b339a11c1c88bfeebe9da0ffd7e mainnet-01503-c5393ba2.era1 +c7d1660bb9b1970884ec8fd0bc889bf7ef2c164962813c524136126e82933e83 mainnet-01504-b478f53b.era1 +d2ad6311cbdf2dd49bc6e407790547a53d918229ceec26fb9d6b72e8e51e3eb1 mainnet-01505-b8013f87.era1 +2a3b61fd2b53680cf3411a8436c1c81c2edc790b9f314b847c13ad0925f8c331 mainnet-01506-f23ee995.era1 +dab1a1ece8dc43fb51c020ea4043f07bdc3eefd049de662b4845c8632d1a8bfd mainnet-01507-21b534cf.era1 +5954cdecc5f4781057bd6d0d979ca9433fb6829dce045aaa1425da4bd3299d91 mainnet-01508-9fbff7e7.era1 +05d9c685cef8f8d2f140023521426a6405db9d954df79285f15065e96ceda595 mainnet-01509-e5141a21.era1 +f44d5da91e8975ac61a11091f7c1f4df06062bba7bc921e26740c4ffffc5da4d mainnet-01510-87aec91b.era1 +e9f8f6b2f4c433f171c843d7f877547f5e2eae6595e3831c3fa8cd7db25c3a2a mainnet-01511-b041bb19.era1 +2141bfc440a25c3709c21bbec11af208605fc6acbea3758b85ee8558933f4c35 mainnet-01512-e41b5ac2.era1 +66d286405e536c2cc59f5cecb90e963aabd69142247234e54fa8cdb5850b9448 mainnet-01513-56a66926.era1 +155660bd87dba182ebcd1bf5c60d3472063e9db7d26a586595e9ab6006f8bfc1 mainnet-01514-898d4f37.era1 +0cfa6d8521e4895b371e130b2f44004901585592d8c2365ea872c2cd979763c2 mainnet-01515-935b5d7a.era1 +491efbee84d36f57e582e39895f98d9e774051d8decf6d0ca165260702cd282e mainnet-01516-4ad5c3e3.era1 +cc6ca31096fc3ef2574e85b786f3db1f681b4707ecd5be234a1d7dd85bb6e257 mainnet-01517-be94d5d0.era1 +4882f5168a45010401d472f7742e91a5c0e9057cb1de13aa1673711bf4027e36 mainnet-01518-40fa62d3.era1 +71933f720ac13c6dfa662eb622549110d94a84881834d0eec8cf58d33ac4efc5 mainnet-01519-110e8af3.era1 +ab1b918ba41b10c0fb7b2ac74a7e0016c4a1013a9ceca3aa6e7872f4800ecc25 mainnet-01520-6e412e20.era1 +f3ea5d0379e73f0cb04f0525751dea63547e952863f9321375c7e5a985b9c35c mainnet-01521-8ffe28ad.era1 +dbe4c506e0acf2a76a28ad5a04967d6336b3d58ddfdaff5f714445e0220b693a mainnet-01522-e93cd0a0.era1 +185d042fb5e6b4c86cb2108ad197e1cb179c896a6c593bf476da4de1bcbe1a74 mainnet-01523-77f19add.era1 +73aafe37a41815c3accbe83ae518d302339c3a6ba9e8a8c2283a53eeb2068879 mainnet-01524-f583c727.era1 +6d7423924d47b47aef930b909b1f9f08730f47f2d7210be165a144c1165859cb mainnet-01525-326bed46.era1 +06e4b72e68ad8f8471827d1b5622b7aa5eb96b507c23a4160496e1f8e1cdd203 mainnet-01526-558f5bae.era1 +4305fcf21693115296a43a96f9bb46dc59fa89911147d1f711e4b64e8bd16aa6 mainnet-01527-17af0f4e.era1 +2a31614752754ae8046ddc39451171b291adbd0b5d9f7e8f5276dd5943129206 mainnet-01528-b3d28e9b.era1 +991bf22dab16b2108ad2b449102520b64c5580f23e2554f35da579a8e756ad6a mainnet-01529-6ce3df5c.era1 +6273cc58c1618d4dfcc71767a2ff4d17731a8eaa7fd64dcd7b285b30aea2422b mainnet-01530-70b295e4.era1 +b61fa4992aaa5215fea67d4b81f9f71ae273ebacbd98dc051d82775e834572d6 mainnet-01531-5694754d.era1 +3aeadb98bea934112453d371028a815ad5720782b834e15f7a551b8e29188975 mainnet-01532-b7d62fb8.era1 +89c0868bea5d3c6d08b3040af4bcc913020fe3209f578e0f0bd6cfd59c6c5828 mainnet-01533-1c4ea22b.era1 +84447512ea413fe1aa379f54b0e626668ce35d66641d6011fac103cfbc2d2982 mainnet-01534-3f50bd7f.era1 +18d5bc1bddf4f4f2cc36750a1fabda5bd5d101e55ec599e8e7fc819100e2d8f7 mainnet-01535-56e96bf3.era1 +d967e1886bb929afd0895eabea57fe8466cd91a38627a9610c9462c2f118cc54 mainnet-01536-4c0b5a25.era1 +dd6f936d078566b520cc8cf96b05a93f971270ac653b2dfe72fb6fa44029f8b1 mainnet-01537-b84376f6.era1 +52181bcf117efe1a469a9918c2b83212dff8bb394c413161a6e5f768d28ac54a mainnet-01538-a859e797.era1 +77aaa8c1d10420f6e6978fa46d00a727290439d7d7020a31f85a9523a3bdc8d3 mainnet-01539-b8f73328.era1 +fff50cc1d5230d7193097a94b57f6cb616dbe1c1c5d519a7cca6c10cc8972543 mainnet-01540-5075b4c4.era1 +6ecc4dd87a259c2621f7d3f7e4bd23d64c7b5333555634d0fa2f9e7797089ece mainnet-01541-d9a68897.era1 +3de40d9e684347861180fb1f164cc58fb42481a365f80062f24decbd3ab32cac mainnet-01542-4c44c323.era1 +5fcdd91fff82c163ed7cdc09302e77201c64b6bedf9d15a3957dcdade56e1a08 mainnet-01543-ba0d8406.era1 +a01e414694eef9f1f2984e7ae2c32d11d31900e39ad48db494fd63860c96cff8 mainnet-01544-b730d9fb.era1 +bef24f31d20a90421c90e8523a643c051141807306342c6e67303f6cbb03f4fa mainnet-01545-2a36dd0a.era1 +93ef8d3faffa706ea8dfc12345a2c7b1ace54c91d41ddaf039815cf1f428a40c mainnet-01546-cb6390d2.era1 +bb7cccfe47eb34649f0593e3dda7f82916661cc2262d119a1a7a21f3d860762d mainnet-01547-7be29447.era1 +63ff4c203e7bbf73f44d58fee4d9f05c4c1b890dd799fa27ec398b07da574e62 mainnet-01548-d42b2e59.era1 +39e8e2ba83464387f5997a9e46188defada3d96dc957c0e93d525a1c20e95c54 mainnet-01549-3259acc6.era1 +4bbcc6756e221e0c2206ae5c858da6f731b50c7717cfb2c73eae57ad4fe0915f mainnet-01550-15c4efe6.era1 +b3a8f035e443ff1e42baeecaa9af0df015a6c9b2ba9329384c6694b3186aa358 mainnet-01551-2d99a1dc.era1 +010d875ab6d7f9ad167aa7552c6d2a36a692cbceb7f8a1ee141828277dd0e2a4 mainnet-01552-ccd34c1e.era1 +908e58301e84862a7606650611347559345c9b0941b53de0e117267e3a28ff1f mainnet-01553-0f3371da.era1 +5d82854cd46149806494fd65362a6546adda300639525e5fccfb86c5a8b4668f mainnet-01554-6acbe79c.era1 +d0248d1e7cbc9a9d1a2118a45928b1979e191a91b391be76160cc962c976ed39 mainnet-01555-975db585.era1 +8a6a1d1e844167fe7579ddb3767db47f330d35259f2bc041a553a62000ae9609 mainnet-01556-f8d968d9.era1 +6293f17d2943184a9c6c44390bb65fc800212a2cca1de7ca320745955c0ebca4 mainnet-01557-5250d82f.era1 +55c059c3ee3e2284f89a1fb98a8cd4e657ce8ba60ce077c68410ffdd4b54e9a5 mainnet-01558-8817dc1d.era1 +3f873a8be5b8addbe307dc61ef53a110f2ce55a2530259c94e9a230d1f9e8815 mainnet-01559-16cbfdac.era1 +861b1d574ba05a80af960a65738802957208441616cfab1ca8b84828551cf5e6 mainnet-01560-cbaf55ad.era1 +cfa188c57de44897d2c9aeb8953692f89508b4e8486c0a5b9a775d345efcbfcb mainnet-01561-a12fc593.era1 +06afd26026b4031cc3e8de4e36b46c62573f851a38b9fb90436177a79d3f4427 mainnet-01562-310c6496.era1 +885a2881bde1a7c23629f2becccf2ceafc70d4b899db66ef1b8b8cee7f9491a7 mainnet-01563-5345e3d4.era1 +16c23370eced457e061e57abc676d0742b883c7fa31cbb9c3bfd6d4b20a4cce3 mainnet-01564-2280e4c1.era1 +787159001781cc1bd4633faa7b695d4ca247fcd53105ed63f5e6b0f9efd02e2c mainnet-01565-893942f1.era1 +c6d6439e53843b65f0f045af335e62ee9369a6c32e8bbcff4d1e40dbb4262357 mainnet-01566-237ef759.era1 +b91bd8aa86e20d442f88e8c08281413b1852231380639fd17012b385e8848abb mainnet-01567-1aec3b6e.era1 +aa96f4dcb3c01646352bab9f2b971a68eaf282d39a8c7ea31a11cfe434d4222f mainnet-01568-fc92fcf6.era1 +06e6119905bac7ee9daa9ed5916e0deb49c443afb55642fe1507c4d785d5cbb7 mainnet-01569-eacd9d2b.era1 +b879842b5db2608f1cedea127444ca7822082b76cefeee710501f9109c9ac78d mainnet-01570-a22bf288.era1 +18cb3d19703093a8ae31888c221b5569f92cd7c8813450cf5a12e83818114e68 mainnet-01571-1a439d07.era1 +e6c86e5e1360184283df511875918831368ec561c45b0f29aa04523ff6efc061 mainnet-01572-947ddced.era1 +9e346d0294064ba836d65ed33fb1c7b76d795754f2d7f08619c4d7f642e1ce03 mainnet-01573-3a831bed.era1 +b88fcfc397b8e40f1b5972027e0d4d06f8651fc73e5c71d70a5a62aac371b450 mainnet-01574-9028d18b.era1 +2252964fecedc20208c159243232d8a7d7057aaa330f748b9be887681468efdf mainnet-01575-598f030e.era1 +a20354aa4e90169203f04f32060da81e7d9e546ea4bb1eaf04a18a63a70ceb4b mainnet-01576-f9043297.era1 +42116706a2db87cdd04b52d956a4c47379f03233bf226c8d275eb45b1f5984e3 mainnet-01577-8a587dfc.era1 +bcabb605925eab14d7a9d8fc2a4b7cec4921a7f5d0533abaf129f8f4b8f86f75 mainnet-01578-43c1dcc3.era1 +2627f3b6b3007a17aabede2bfb9231d36e44e8eec38703e2f3ef7e7c984c4e0c mainnet-01579-92a983f2.era1 +0bf8f2d6b46e4418738db01923d56b76e250f53645bcfa0cf530bb68f3a9b635 mainnet-01580-1c243107.era1 +75bd2ec19aca5a74c590784cfe97922313edfeeedab25355ab285d3ee5ca70e5 mainnet-01581-1f943824.era1 +94d703236e86ebd23536a8af4d8f7b060519523ef1afbd65f342a5a191a7f100 mainnet-01582-de1cad89.era1 +ab1d6916d63d63e9daa34d90e36febfbe50642259b33c4fb9ed012e104746e8f mainnet-01583-2d72b6e4.era1 +a771a91cd9bd8419a46a5fa09153141acab84a0817a506a7c957f7a5082e28cc mainnet-01584-393498cd.era1 +adc1c64e9e02427ef348a135592f4c4bbcc903436387ace59e5bf28f6635fc92 mainnet-01585-fa098e6d.era1 +ef6aba72154d336723d100cba0948084f9e2a7ea1541f72c5138fdb6be2c13d6 mainnet-01586-379cb7fe.era1 +d0a6465c5fdac882bc85105dbdb28099830dfe60db68bf288d80911be215e795 mainnet-01587-62641130.era1 +ce7424f4a11798631796a5385aa390cf970d14d14ab9fc0e9a79919fc8c808aa mainnet-01588-63224c34.era1 +6be4cd261a1ec3c2f122e9c35d74fee83185021d89d1d42efe7adae8dde85665 mainnet-01589-a972b2e4.era1 +efd280edffc259d29d57cd36b89e34430f1fb956d4b90d37127f641b1a006063 mainnet-01590-1370376c.era1 +96bc3d9168aa98775bab57cc1de3de2765f233d633876acaf0e650cdf5ab8187 mainnet-01591-3c5940a5.era1 +4eb2803b800798fbf132a46d6a322a5e1d3c6f604c69c96b224368f88f1fbeaf mainnet-01592-fdcf0f05.era1 +902ac965eef864615dce6eccb5acde91b0da565512b646d1a4a53a450f41feff mainnet-01593-7779354b.era1 +df62bd03b138c1f024b3565cd5d5d9c9ffb86217b6279b6c5d39cfc1e16ad0db mainnet-01594-fc12f95b.era1 +b0a9fd005f6825f874b44b5da480046610142772cedb58c4be7fda04ff1bf2b1 mainnet-01595-2118c3d0.era1 +010782b7a091404af6232bc8768ac499423dfddb08ee1f62f9d47174b41aff5e mainnet-01596-f94bdd17.era1 +e8d40720e7be1738f3ef18c4af35e0f49e88ee61a55dc9d0e95ff024a90237a9 mainnet-01597-aeb7c436.era1 +31dc95aebdd1a2747077e52ad793d2e62a7cb69d77ebd19828074a15989b5d38 mainnet-01598-f56b793b.era1 +79f502abb89bb0eec42f3ab80847577e1e272f35f2203eac65b57729c77d27e0 mainnet-01599-6cf982a2.era1 +03fafb175c2a6a24c19f82ab9f94e06938bfb0f9cef9fcc94022ba23320f82f5 mainnet-01600-c6a9ee35.era1 +2e272107d43417600bca39785659ff66168182e38b2ed763becc5de3673fa22e mainnet-01601-0497bfd9.era1 +ebbec792fe3fdc063a260131febe6668a477ea7abccdfdb96ed8695832dbaf44 mainnet-01602-9a50fff5.era1 +a7282f54e8595b1d4c2abcbc64d378f418abdb1daced7a64b27e382168eb89b3 mainnet-01603-a1d88a26.era1 +dbf9264d64b6a8ed7b7c956f4f6d6588fabcc9dc447247b215d8c8cf16d36c85 mainnet-01604-00e0c17d.era1 +1100f28385ae46291c8f573b4e8c994eeee0609d230820089258fefa3ec104ca mainnet-01605-8fec155e.era1 +c99b73fdf1034c93bc879254190b3ec81f5d756481b2383998005865c1001625 mainnet-01606-7642a7d3.era1 +57248072c17b75b5ebb7ef087b9809cc08fc6e7e4d87a1bfe26789dcb4b2351b mainnet-01607-0a337fdb.era1 +89169750db27f32763c38701c7cd4ad2fbeaff06ceed6dec1dd69f8c71527a65 mainnet-01608-2b8f0227.era1 +b3d5edeb90bda42709bc5ff1793774c964c114d747d10d2e30d38875461f98f5 mainnet-01609-ceafb201.era1 +a0f60c0036177ba34aefd82bdd0c6d3d483279aa61a6b531cc62c275da00afed mainnet-01610-99fdde4b.era1 +6cb64bd1346e0a19fc61a73a100cd32389a54751147379d2e67936c7dc75d6b1 mainnet-01611-0d642ed6.era1 +3b6adbc75240ac148b57991e0c603bf1102f38021b48c8252760c2dfea463639 mainnet-01612-01a109f9.era1 +b0d5791e2c0e618beb451c897bcd2c8310e7d95e6db533a62ad720480e4003cd mainnet-01613-409c216e.era1 +cef35f80ebd7396e051e5c475c6aeea8721db6fa8f96b5e2d7c7aa0e52fe0b41 mainnet-01614-608abfc5.era1 +cc9e5f97cf1baf05026b9f366523a7257b762498d873189df8cceca0b48fa764 mainnet-01615-546296f9.era1 +9b9bd6c05c18a663aac7ef90f0b078d2278766710f13b720eb3ce0010d8991d9 mainnet-01616-210f4a03.era1 +3947b044d7275b95ce0d5c30c7522020d7e6ef63ca4477291ad1ee4ae0f2aab0 mainnet-01617-f300016d.era1 +2dd5cc29c9e516373bfbf690f37d6541f83d44530d5f1adbeb46f0d5f1ea4a8b mainnet-01618-d126355b.era1 +7e327c4c515a42c2c67a67ee85c40fe1a5fa55e28f9c066da63b262f62b4e740 mainnet-01619-fccf39ee.era1 +947f7d0ffde5c24358b6c924c54354bb35982e0324d81dad142b213a097bcbc6 mainnet-01620-62719ac2.era1 +7e82249cb9924bd9c7df57dc63917afa4247ae696b0e36b8548d5cc826425ddc mainnet-01621-d410e2d7.era1 +4a60acb269f942c6d6fc5edb66d09b8f40cf6003fb8ed2dd980ca6e9d4c78ee9 mainnet-01622-3a2643d1.era1 +83cb30fb9f530a63729e6632381adf1d1ea3d9790c1a8a3885493f14538b7a6d mainnet-01623-b86b68f1.era1 +f33d2dc5910930251ec6fa6663d608e14eaad79902a25b9e0e1c5923060cb451 mainnet-01624-79abcea6.era1 +4d978612c4d21afae90bca1876bad2a15e11d2529c0eb5519b7b8cdc24deef8a mainnet-01625-9d2445ad.era1 +6e73bf434de732e0aed33793de14dff42e6436685ec3ba9a012888877e812a01 mainnet-01626-a0719f02.era1 +0de06257af6217f6b1e48a4ecd834d2f0eb38e7dc3f11350bda7403820956482 mainnet-01627-3825eb62.era1 +5750b01adf5e5db444ec333ec9de9d65419010007df44a362f58b59dad668fcc mainnet-01628-49d1a71d.era1 +206bf4ddd8c95816e9116daef0c06a547d208a43d1dd42041b799aa37881785e mainnet-01629-1ec93093.era1 +1d8eb98edaca0ff1ec5ce89dc6e9dc46454e9f90fef71f1d0df94b3016d95fa5 mainnet-01630-d52d9f3e.era1 +56c5864a3e6f2fbbb66b38eb35243d00522222e47cbc17c798e861d4323818b9 mainnet-01631-438a5c23.era1 +09b7d3e9e045731a6889a463e2cbafbd4bd459eb0e1dc19dc188c0396f2093fc mainnet-01632-b811a1ab.era1 +0b9a9ae0174a8cd5d0ea944001d43dd2c919ff62039662ef4ba3397f1791abc1 mainnet-01633-2dba253d.era1 +55c727428d8d8d2b2a4233b3ff9cb5fea6c66c23090350f49aa2fbc53b79636b mainnet-01634-c0975217.era1 +83a255aff9d3c7defd78d7c17850ce4df4ad2c10f114a0a5d40a75f099baaa4b mainnet-01635-926f0429.era1 +edcd2e9493d70b3498a113159ea7548075d5f6ba03ec7dc441447688ed207d65 mainnet-01636-88bc22af.era1 +68d93f5aa6c13075badba3c6fae3ae8bc0fa357a80b9bd1539cb249d9c414879 mainnet-01637-d10229ae.era1 +d18c50eb79436b9e960c8fd12fdff6925d901dd8e2c26f4e08dd4178b8e3e1a1 mainnet-01638-f60a479f.era1 +91baa2e3f7ebed254f3753afdb5c8e9666553e77c7cd651aacefcc97c453bf65 mainnet-01639-45574d29.era1 +6d2f5a87fec391b024b77ded2cee7f2c9647dea36d48a5d7876ad59180e3cdce mainnet-01640-f4d925c6.era1 +1cffb9c6dd88abf72b7746754950a27d8e215715d44c402de5b61838aa7186f4 mainnet-01641-05561645.era1 +438300a7f95a8ae17aa27b64d6500c70e6b2ffb908f968879772f6321b17660a mainnet-01642-bffe5d04.era1 +fde6789e767f290c4734b9bb96704029923f2c6094ce2458e8642af7227669ac mainnet-01643-db04ce69.era1 +20b99f2db27430968a5f22db2148d37abb048e5733349336241a62782b33d35d mainnet-01644-836dd3c2.era1 +78d93ddb94df9a2595706c2b7a622d90b8f06c407af9d5a895b09bb625732c09 mainnet-01645-ccdd4d37.era1 +e855b060e1cee6387a7ce6b2681f1c3af5ea6803a362efd422f3313a32046dc8 mainnet-01646-df78d1aa.era1 +28e21deae06a082bd6ad582c893960e0cb5559de8c6f003a627dffb4a4ea302f mainnet-01647-bc1a2596.era1 +e4ed9e14f0d72f721289c4e806a6d07e6edf81a01b05b9ef7953ae8e155c40e6 mainnet-01648-ba444550.era1 +b005a1085fae3f049796cca6076dee3cdc246d798b1449b6ac696646ece3c1bc mainnet-01649-c772985e.era1 +6499d2ce493545fd5ac85e0aae30ce766c08ba6aaca6b7a94fa61089834ff422 mainnet-01650-0cd44f84.era1 +d2e6f7286e6380b83118d83d27b9bcb6d05b4664af7c79a0ba930c0d19e74db5 mainnet-01651-108b8139.era1 +06b4cee7d62b17bae99db042addddec5fbc97bd7b882c2ccebc2bfbe09d9971b mainnet-01652-92dc53a4.era1 +1a72131ec11e08bf5e482c006804e56e2ba7b1586f6c8cfb30144fe66a1eb2ff mainnet-01653-ac1c8ccb.era1 +01c2b842a7eaf97c1244ad6ab451aaa6384c58dd2311a429242603fef836246d mainnet-01654-2f466ff6.era1 +35a9484fd611163daa74558d7be708e0e262eeb17270235fe61da80b6e5baae1 mainnet-01655-4dc5edd2.era1 +96837fa185b1e407429e2eae00e0cc40af64b3a9b51dbdb9fc83002e1e62730f mainnet-01656-72d321b5.era1 +e4bfb4fee82e660922baa7a7a0b4073739f863d5a82d447f1b2e2c14d96ee4f6 mainnet-01657-d0684723.era1 +38274fd658e3a2225814dab185807334c4a2377fe00952935f41103453bbe7df mainnet-01658-651f1c70.era1 +4352318a3c8a480a115d081afe9e37711e997f96904722efdcc23cf16401a4d8 mainnet-01659-0013c08b.era1 +e101cedb4dc4dc0427182376ad6cbf02a4b5ccac9fa079425819481b526080e6 mainnet-01660-7825d5b2.era1 +a06e6331b045cba8ca1a31edc83f30e4de2e6abbdd310f11e9995b2515f7990d mainnet-01661-84e21383.era1 +cf84a100eec66094997768ba35ee2d39d670c98ccfcc50eecf04692441af6fe8 mainnet-01662-a5681587.era1 +a837dcd4cdd8917d21032e9b45f2a7688d527810c4321dda9bb8530f52ef9d10 mainnet-01663-c84283fa.era1 +4dd4b08e0577e72febcb904f542ecdd239b2fdc6c37aa9900e937319f2e9e6d0 mainnet-01664-ab3af7a0.era1 +18428df15b49400723296f714c964a6c0a7f553cf70643a0c77c13ec9338dd53 mainnet-01665-d0adeec0.era1 +4391c6ff4a21e044e07acd9b2a34277fa903b26c52ddb4563be7bafd611cedc5 mainnet-01666-827de27e.era1 +e46ab921179e9f1ce080f2d9e9cdfd5fbc1fe86c324b7daa04a3be0a75f7070e mainnet-01667-558e2125.era1 +aea3af1e83809aca973445cb92d437fdd6c3277ec37ba5530dc68d1c1186a82c mainnet-01668-8d75bc10.era1 +0d1b9b762a6acc59cfe20ce1444ceba7b28aac87a367d8ad867c75acae1242f2 mainnet-01669-84ccda7e.era1 +4d273107762c163b629e1f1c93be2a90788db4534c1ee47caf3d201a1a3bb39a mainnet-01670-3490d679.era1 +e974b0c2a4119dc0b933dcc3a57bdb5d0c9b1058090a98fedcfbfbb775bad598 mainnet-01671-4533f7b3.era1 +9b9fe120f05946ba3755cb8a1a407c1473f12ecb48caac7d082983a7f23de120 mainnet-01672-abf10629.era1 +b35de36af93d752a2d0a3c2661f75945418f069f0cb4d3bfbf43834593274e9b mainnet-01673-d67018bd.era1 +29962e598e4aa1445f1cdcfc71228ecff08a9dc716ed22bb33bcf504586ed060 mainnet-01674-16b9e877.era1 +b4210ce62e93c251b47b9baf4a35ca2c512064f4461d10af2e681901ec888b74 mainnet-01675-35b0af7b.era1 +ac0a3ede1bad8761005d2f4ba0e29b47d46899039c30e6e65116daf06302c713 mainnet-01676-2753d9cd.era1 +913ed37b7280c0488f0b2de53bf8186c872b861bd1661e81a99834d4129aeffe mainnet-01677-e40b2ea4.era1 +2bc0af84a6edc0a2af8bdf9ac47d80a68b05241a9caa4404ea55a9822e48302b mainnet-01678-fcbdf0e3.era1 +63f5cee3827ce44ec03a277bb6af7e806ba240a59541fc9b36362b4089a8025d mainnet-01679-e5f342e2.era1 +df44e2d0aa327e3fd223579886f0da34b5c760bd4062202d2a565215b81ea528 mainnet-01680-af511202.era1 +a6c893c0bf0cfb25566d230ce2e9e701702826c670b58757a0122bb2c80c3f68 mainnet-01681-d0e6d3d3.era1 +d36179575d40b3c0d77d1baf8bb54d9db4029da6c917a157ffd42186b7c8ff00 mainnet-01682-66ddcfa8.era1 +977c03ba488a3aa991bd54b335b103df2b19039358736e77c2bb62c9bd61e6e8 mainnet-01683-8887a5b6.era1 +350e7911f40b1691f883cf1a45e5f1c5af895b4e6c69741b8b8630edef1342c0 mainnet-01684-bb0ab38c.era1 +42005763913f34a9f40a30bf34cfa29d33e4afbc8e37bdd5b59037211609e59c mainnet-01685-64bf045d.era1 +efaf03b1a2ce0c90ee6820aecafa4dc3c5a842938eea67b8682a7dee5a54d301 mainnet-01686-7a8fba5b.era1 +c110709475eab96bf1199fc05f12b1e93934bbe913578eee747c8a6c2dad38ee mainnet-01687-26481dad.era1 +e17e1ada1db485936003d7ac7e39adbb61ee1603e5ae612eab56434836eb98fc mainnet-01688-05f0a174.era1 +0a7ba360649c251244495f591840e2d6fd5573a78e3c722cd893955c2a28ad7d mainnet-01689-ac53e2ec.era1 +e08c6a38b0388a831182bc1ce40138fed2a801ad1c2630af40ac65c099414ad9 mainnet-01690-9dbcd976.era1 +a9c29e89fc7ce6ad5be4fd1d4549299d627c03bdb238372d73c3d9be25f12675 mainnet-01691-bb315f50.era1 +2ad967654e2f974e258e44b6754a77f56cba0afe8ccaa15fc439fbc12798c693 mainnet-01692-b877548b.era1 +106ef010fd0d5aaee7a0403d87e0f23ecfa645393b8c2bdc9e015afbd11497ba mainnet-01693-3d2c2aad.era1 +e35d0448682fb19310974dd10afe35e15e3ff72cdcc274e522a1d39ac48b1893 mainnet-01694-d42cdf89.era1 +3660dc81c12ae17c90ad39c60d53d66ae434b7501e2ef471241736a392e7f16b mainnet-01695-8d97b217.era1 +8ad51c98a5383b4f1b8cd4daa76e0cb06efb757442b2aa60051e30cfbf4936e9 mainnet-01696-49e0b594.era1 +31804fc49af12294cae633abefbb2deeb3edd68a8d88025bce280bf73e564e7f mainnet-01697-01b23d08.era1 +1e9a9b43703a4204766e4a7c5417239e70fada858f1d6736048c5098f4138c62 mainnet-01698-9c316b67.era1 +cb7065153c0805f9067abc909fa30e2710bc8ac5daf1e2b8a91f21ef58aa1d82 mainnet-01699-cea5c210.era1 +3ad35b036db0a06fd8f5643920e932a18c934a3a48211d0d29821fc5be1c62d4 mainnet-01700-3d9833e9.era1 +8f53349a041f87bbdabc195e8a5a8b5a6a298dea93a793bb06e8875bb720b673 mainnet-01701-073ad3dc.era1 +dfa4e8dfd877609aaa5cf823d6c6451521ce52b6ace31b9dd4709c1660d3380d mainnet-01702-9c454cbc.era1 +20e5075f81c16f0646712c90db5adf2bc7d700cb85eaeae6fd20ca25eeaf1c69 mainnet-01703-0d424bdb.era1 +d3c36455190c49fed972a9cca857b8003de46f05d60c6e274b3476987ce5b806 mainnet-01704-c8426624.era1 +a9c26e0771f6434853d481b5989dace7ab3bdac64b09236127fb8a776d11a908 mainnet-01705-850425a7.era1 +e1280b5098b064e034d683dde04136fde1501092956a2d1326e4332ac8050aa1 mainnet-01706-5f7468d2.era1 +c4797f0d3596853c7f8467a34216cae9c96577cd89e7a417cd11aa9faddeb8f5 mainnet-01707-68199dcd.era1 +001a05c2058846729183727e9e2f5c88c6a2ed60effa7fcaad1a065fee12e296 mainnet-01708-1bc39088.era1 +c5659c0e1114fcbd5d3e6fa7df0af74bef56a6e16b6ce39e161d710b02318644 mainnet-01709-ac6bdf4c.era1 +cdb9ec5a2786d0f8ec381e7196b8f29ec52dc115090f48262a06cfd5688ac477 mainnet-01710-616a4213.era1 +aff691d78a906fb94516900a6e00971fd804eeea5266fbb447a0fc02183652ee mainnet-01711-675a2efc.era1 +142053135f5bf9c9a08b04039c68a4172330bf4703867603f4d8e2882da1d602 mainnet-01712-b3466ce1.era1 +2351634486ff7748d00b61b4120b8bdaa5521098b5d2da3d0d59c0d13b92f054 mainnet-01713-efe87a15.era1 +d8a5922f7d26e436321ba56ffc2923fc0be6299d632f1f17befd6f99e4a63966 mainnet-01714-8a93b06d.era1 +63e092eec59ff940754f0f05dc96a053d6929a1da224a264dd2e9a0bf3ebfd25 mainnet-01715-c53f6fe8.era1 +54ef87fde748440e0347ff7c3e339691f75c664c93de1658b6f9111cc0403e89 mainnet-01716-beebbc85.era1 +b5d541673d8f32aa5041c5d46459b3423896fecc9568b1fc9c2b8468cc7892aa mainnet-01717-2daba19a.era1 +6ed9fee8c53ab7a9c16ed490aeee51f2d5a78393d670f288dfd77f36d4967d81 mainnet-01718-69ddf701.era1 +831c00c3a6325a2c7ef613d965e0b4bbfd67c64822e634844c27088beb059c21 mainnet-01719-ac2ebcf4.era1 +054fdc70c1d020bd1a910c6ec22351b95067001a52767921f460f2993ff4522e mainnet-01720-c428eb52.era1 +6b3ea18780edf83f361fe2d3a17c53303868c5c4c46a8139ba003f332fc28676 mainnet-01721-940116ce.era1 +fd954f67fbaa219ea51fb592c34c1ffec066002b824bf18e6614c673eee598bf mainnet-01722-1aff873b.era1 +2511305a5ce78ad72aa9dbdad9817e8469a295dcbb5984a957aece48930a0195 mainnet-01723-f19dc7c1.era1 +4c36e22cee8ddbcaf18d09e596cec9a92a3f0a45f3fe65b57aa0706af2f5fb23 mainnet-01724-50ba9e24.era1 +d1aa0d2d92ab9eb9bd387b15c77b9f0221be2a767f86f1b7b9309de24fbb76b8 mainnet-01725-6244c9ba.era1 +f31545c2b115d0c0eebf6d80b1bcfd78598ae06f1986df5efdcfc3d4f37b7ed1 mainnet-01726-d9ca0531.era1 +78004f7204f2e7ac123860e3d5ca0776498e8253d01ace192c0f3ebda61a5ab8 mainnet-01727-019f04b7.era1 +15a6bd053f3a88335e91d6c6442d72eaaccb0d57c7ff2dfc9f17ff3c07fa865e mainnet-01728-0bd9139d.era1 +d5b5ba3f562642fb45208da6733142293472cbda4b99fc6e984955595efd1fc9 mainnet-01729-a85a5ebe.era1 +6e49421a232ca1b641ddbe56383bc74982b163b86d41aca834473134c4610cd1 mainnet-01730-e07d8fc1.era1 +477eac763c868cf1ac6259e07c633774ea0f08c64d3ca04687074bb18a419e1a mainnet-01731-cdeae685.era1 +ca68cdf760dbad25ad5ef8bdaf85b0058de563632136f7fe9d2d95a04bfe339f mainnet-01732-d4b05748.era1 +06b1c9f0c06d35ce43c35df229c1d6faf8c79a2b402bbed4f130065531ee7835 mainnet-01733-2b75c3c9.era1 +4a954844ebcc4b0f0c94ca52547190210f649f72bcdb9f80d1d3d4e71f74ce1b mainnet-01734-0b51aa4b.era1 +330fb8fdd3c5aabae38c66750176f804e9c07bbc4bde6455d2c43afbb6db8800 mainnet-01735-5b7da9fd.era1 +d2add601504ca241728d9b8432aac9a6d369d207c54cca01c7d49bbf7c48c0ea mainnet-01736-2d581b43.era1 +7346d0e283a184e99980cec04b06e311719f4f29c18b2012fe37128c2a19711b mainnet-01737-053468cb.era1 +259d8dfb172a6b0dec07c12c1fab578d7a7518902cb12e42423732d81203d37a mainnet-01738-c4ea7355.era1 +cea5a2851704064b8fd19552ecaf48de00beafdc4ae82c37f4a2082e11b43015 mainnet-01739-390296d2.era1 +9a57cb258cc2dd09ce7b55e09f2f260bb73c7c71aaca242048fa60ed02354acf mainnet-01740-0bc99a43.era1 +caa75f9f4de04adfc7e12807d84de63a0d25d5f9ad526af13c748ba0cbe12469 mainnet-01741-831ca140.era1 +814ea7efaee9fd9f538c120e23c5da3f179cdf7d657335e34940506e24b466e0 mainnet-01742-6ea854bc.era1 +4a80a24474e75c813ece60c103e053f33d5d0e56b40ce212361ee914232cb078 mainnet-01743-cbe74e16.era1 +444335c8e046badc93ef4cfd8da27ffcbbde62a739874c9a133d6a1aee184436 mainnet-01744-afde3d1a.era1 +4f49ec87006142e56afa1208efe10c3e57b671a7995bddb5d2e52d8814f30115 mainnet-01745-265425af.era1 +98484f5a5cd6307bd21db41c280cc8e26e343c648db6b83fc3dc76770ab97b99 mainnet-01746-ffa83edd.era1 +86e82209a82218f8d477c84622831fb7a985f8995fe7bc2c9a3f1dddd2f509cc mainnet-01747-2d7f0f5a.era1 +147366fe1cf8a15b86df6e2057b6197efd6291e5a1c02130697b395f9579a084 mainnet-01748-7b69dcfe.era1 +bb8718154e5cfbdc3851e1bd92d25d0c7c1f6caa408b247fa23aeff123e70bb4 mainnet-01749-c08c9611.era1 +ea12b0e1908f4992cf34a041e1ddb828a28a2d896917e3cdc1accb7be1bacb57 mainnet-01750-6067e2da.era1 +d457cc2a7f6dc98768f427366b7062b5c18394e60b39873a11001f0eecde22b5 mainnet-01751-50262a09.era1 +44cb9be229a4a0f73f0ffbb979adfafea36a0a2b04cf45bf06f8cdc73d47a770 mainnet-01752-0488926e.era1 +29642c796b4ac6fe40e42ba781c3f1cd973eed1b333bd18d8fea12fac869f04d mainnet-01753-7477c0a1.era1 +c72f3c3be651e63836a45aac5a2ebfaeeddc84c5623fe55c9040725503580398 mainnet-01754-646def35.era1 +390aab178f3fa64c3f7c9d49a168cfd4864406d98479a1262fe4639877f932a1 mainnet-01755-84f4fc01.era1 +00809821d0ac264ceeca9cde077b30a7d7bbc090680b72bcce0b7a3e352dc675 mainnet-01756-308e0580.era1 +ab7d0b5eba4e9362a3beae38f4c9cfedf1eb7e953ef541019c0d3779a92d2ff1 mainnet-01757-8b98854f.era1 +b5d44da8b08efd4d49f08a069a329877344304d0db8f031d3748090e73ef1c9d mainnet-01758-7c7bd992.era1 +039f94e36edc9664ba94554e943f5e1e3832fc3c2367b915cab73702a2ddfabb mainnet-01759-ef9dd1ae.era1 +3b00ec14cfec68038f9b09d0e471472a543b7e81c5b195aa0d49be1064b733c3 mainnet-01760-c908c0cb.era1 +7d7ba43a3b5d3d07083c5c3764f3062f19adabc13ea0e91a71bc164ba058e8a0 mainnet-01761-4c223079.era1 +690a0ac75a9478e85925efa16fc3c773fc108ea10d993ca64a7fcf1ead7ed4e7 mainnet-01762-58e9482f.era1 +a206d2ee6859a7941e7bf3adcdd01b954a6f1e99258f05cc6c1d1badeb94e1b1 mainnet-01763-e9b64e43.era1 +61221de714d558e1d478b269e4ac07246d2ee4d563f0121297e5cda10eca8b71 mainnet-01764-69d58dfd.era1 +a2c885b3dd2e7bb137983721941c5330d50134568c96bea6dd84335ba29b0a64 mainnet-01765-56508960.era1 +4ec349b6cfa62117f3e22f5d6876bad0cd33b7dec29517e429e5a8f986368129 mainnet-01766-e47ad77c.era1 +54cfd1f1b777197a0baf6b8856a898b37dc9395a449f605ef344b1cf0f21365d mainnet-01767-c92526a4.era1 +56f8a3ca394e71021db7502256d1725de65913549bf948f9b9309e13034b50e9 mainnet-01768-0f318bcd.era1 +a6e19802b345ad2eefc4643b2f2cfff050d95ecb2f571fb83b3347c2e387e19d mainnet-01769-cc56b7c7.era1 +92b9eab7566de2d1bd81bb87737b5695d37a10913daeacf8ee8626c48e6a4dab mainnet-01770-8a0d9bcd.era1 +9837b0e62989fa89b8365c58de124b132aaa0a02db4f2f9925d609d5cbf7cd70 mainnet-01771-8c0c7922.era1 +f1f5657d4d74fe786d08b9b84f4aeb2e8e1229ed79284b95bcf3978506aa9aeb mainnet-01772-490072e1.era1 +5c9e6d7f79d6b66d869184db4f737facefc8a77656500f7cf70d1e24cb781ca3 mainnet-01773-441a3c8c.era1 +11bf26b1e892ecb5fb1bc2fa901d76fb3b80a5d2f1244a9bfa97734a7fbf3d20 mainnet-01774-9d3c41ed.era1 +abdffb40e251c5519e279f29e3457ff35e1940587353f6af98e85ed6ee0ef2b1 mainnet-01775-6023b5ad.era1 +8207baec682cafc0bd49f8374a27dc42e8438c91250f6fad4984386cdb938bad mainnet-01776-848902b0.era1 +ad7cc2dac5c009b4478f2e7af83f7742e1b118e01c66d5b301563a0dcc9bca34 mainnet-01777-56f9c62b.era1 +10242c34bf2105d577e40e835c49eba8ce00e330f4027875a7a2dd31c175bb87 mainnet-01778-01a7fc06.era1 +def53a3865dd9824c40a2a2ac918f1d68f6fe44be12fb32d70a3c6f0dd79ad35 mainnet-01779-9ff0b054.era1 +cff7bb320ad2df3c95e50b28f36f4cd08080036f6e3487f763a14a8a3c736a6c mainnet-01780-0601be62.era1 +908ba078f115308795bb316a04eb26fbf2c6ad6ee70c8013b222f9b88d1fc25c mainnet-01781-c73b916a.era1 +d54d51b9943469b3f98d41fc032966326a0284a196758d9a97ec25d9b503be0a mainnet-01782-4ff9deb8.era1 +e5ef6720d4344b8172b8c5e3e65314137c72a2cf8d8df3ac67ba1ff348c081eb mainnet-01783-6dcf0704.era1 +ff9d6f57135bafa3744ffd3562495937dc479b5e466fecd128bffffb354d4bde mainnet-01784-37725e0b.era1 +1626ff1b25cbd8d365ef179d760206d2f3a7e34283ad89e0c3de76682a4a8c9b mainnet-01785-bb264cc3.era1 +e8139e73f730e001fcd2c95f4d100401841d13fefc7abdd3d0da7b32cffb1d44 mainnet-01786-8f3dccda.era1 +ca3bfe0711d28fb7a43d9a37a6802cbb53a23a03855de31e45b3a2282f4dca00 mainnet-01787-8cae5bdc.era1 +2c05e0edf4cafea94575d5ddc29d9db3e9af79ffca259a1e1fc34ae1d8efdf8f mainnet-01788-7e1c1704.era1 +1ff17cc6dbb42da4be0c4c312a55cce95ed32829a332e888b8e999807327ac18 mainnet-01789-db34d4b8.era1 +e7df0305b5fd13fafb69b72ecf65715086ca9dfd9b5b0a60949cb4fb93e8a513 mainnet-01790-0e2fc599.era1 +972f33b700efda3b51dd8e7ba4285bbfd735c0caac70669c26c663cd5f428b23 mainnet-01791-0dabc8f4.era1 +2c203a477905059a0ddf15f23cdb0a6af453706542fc23547347ccc6f35e61b7 mainnet-01792-648d0dd2.era1 +c140566f729c7234daa27aca935c23b94264750db2e5c31ce51328531933656a mainnet-01793-77485ef3.era1 +5919ad8de00445b2dc6889583151806527b3da2933098324442036d19559f9ea mainnet-01794-e291673e.era1 +b8be8c99dff125973899bf7aa1afe6781416df937f5226e4d4cb3215953f2093 mainnet-01795-d1d496b1.era1 +b86336614b33a78c996f4d336d4228384b202ee1b7252eac6077d4e8393f6754 mainnet-01796-33a5546b.era1 +08bba1af8d0185a153b55ee9f0cdb03294c6521523d4bae4d9ef2e91553af78c mainnet-01797-34123297.era1 +9db3986e4738134b2f924332b8e3b9fff78735be682326ce0a60425df0f8abc3 mainnet-01798-3ca0aead.era1 +e71d18586ae068704b0a70c226559e49334ad35b90adeb21e0e6a6497ef71280 mainnet-01799-e949b50c.era1 +169ef20cc0417506badbe99059319fb2e075d41348b589f831041b43f93e4601 mainnet-01800-07cb6fc5.era1 +3b6ac2d372e4f7d086f414aede4fcd85ab99eecd5b8813de28374dd4395a9474 mainnet-01801-8edf5827.era1 +373d59a8877cbd8b04a7fdcde7b622255add49295b6bb0e6798f96742f14aec4 mainnet-01802-f95306bb.era1 +ffb419fdb5ef8b1751582d9bffe0d415a8f3575fcf3637c6e3f318ae339146f7 mainnet-01803-4e1d05e2.era1 +817da39985c59490e5e5c9d552800210bb63ac4bcbe69e5660d2197c7645520d mainnet-01804-a24b5a4a.era1 +96e1f8b663ee8858688c96c680a7b50fc5b4ab6e417de66804cc37ebab61d83b mainnet-01805-81d9a952.era1 +7cd6588b9de8c36552aa5720f1eef8befb529348a28e2b12bc24dc62dfdce32b mainnet-01806-66534ad9.era1 +28733727ad69c62d6cb996c7ba56ce877228cc13b49404c58480f5744e1b2f42 mainnet-01807-37ac1801.era1 +11d4f6cdde3fab436ee0860524869d550a296973a16123564cc378fd6b8fb76b mainnet-01808-3f1a883d.era1 +f134e7b5a1dab190a560976c49d44af0bf4b29ecdf90b5956e68ef1fc5873b07 mainnet-01809-45d0f53f.era1 +7d896a5ee60a4538daddfd3224ee1733ffe03ce2d9205fbb8bcdd5556880cd18 mainnet-01810-6ccaab76.era1 +97270e0c74daf2b6dce276f7e57da1675686898f5fe6e71b41372a5ed71b2861 mainnet-01811-9ab98ad9.era1 +128b576e331eb6dd13669fd41ad838a55234ba8fd551b540334aaa5977a25839 mainnet-01812-80d86e96.era1 +94b8405c2ca5e927fe04c53abad00195af8f5ddcaabd5bcb380ebacb974d0f0b mainnet-01813-1b4ae400.era1 +bcbfc951eb5accdfc901c2d4e09bed8c2dd8527523ddf5168bde7f6cafb65665 mainnet-01814-e0064cce.era1 +9cae44c640a4eedfd0203544557b9859fad78525315fea016f0760fee9621c68 mainnet-01815-a2d04240.era1 +bd0d76e3aacd16bca11fdf97f3c4d59d6c94d2c6632336b409a17362e18a7149 mainnet-01816-9a493dd7.era1 +e1e52b715b706fb6a51fd475c90ffe844c05af4682212dc735b70eb6d15b8c7b mainnet-01817-f534c5f3.era1 +47d4d64d864b2899d7de2579c51313938e0ff0fa9138b2243a5ddb52f9dfdf7f mainnet-01818-c34b86c6.era1 +b3e560f0cf07d7eef8e791bc06dd9641c7c7735d4236dcb2a36b21eec1a197c0 mainnet-01819-918b86fa.era1 +9f731bd11450d62258465e82551e0880cb069ce742ae13bde68dea2601721748 mainnet-01820-17e7111c.era1 +d6f23c1501e8f32f0684225a3c127c72315a8fc456bcbf92cdc217eed2a84d33 mainnet-01821-e118ce72.era1 +5f3e345b1e4de32db962e04b1a634bf7a5015fe1cc37e19fd65cc29a78d49ec9 mainnet-01822-d7b7b15d.era1 +6d2414fb6da3b2cb1b6ed24a68cef0b3e57f4d6a8b2f0c5a90c03c4cd02cedcf mainnet-01823-3fe7a945.era1 +0ea96886a709d1e7ea834c4a524b07b75dc235cf34d6819812929067511301a3 mainnet-01824-6ad87d35.era1 +c612eab2bb1cee468887caff7032f5fd6a09a297ede51e25c2100cc46f82fa1f mainnet-01825-7f981244.era1 +0fb454e3e2d97d1d136ad2f026926b9340cf0a338e2bce065274b5b699fdd99a mainnet-01826-c17dc5a3.era1 +f01b822341df294990d8f41a1d9ddc3a99f77614fdbb06882a3efbde0470ca61 mainnet-01827-fa5fbccb.era1 +dc618a87935f5b1c5a7dafeb662c8672a9548c387d1bf856f0c9ab47ad430e23 mainnet-01828-540009e5.era1 +7097ea8556d18ada8179df1a19b9979230dd60b101448242fe0f715efe087593 mainnet-01829-41ed6fe7.era1 +dd6a8b10bf7d6a29d83be0ca90812865496bb76501e6f42d4abf3b8df3cbc380 mainnet-01830-2afebfec.era1 +5dedcfe545ca0511c90ef476e003381a11aa60164579d750b19ebf38a4114159 mainnet-01831-7289db8d.era1 +600a782467d1fb81a455d097a0a5e877b2fcef41d39a2eabc50c8079c768615c mainnet-01832-b1198d24.era1 +ffe32e137d93df3c83d498a8af890369979255326fd8955e93849772304732fe mainnet-01833-0bef1261.era1 +e8d69bf28daf5c338649528feb91b91635d686144caa6b302d4f2ccbf63887c8 mainnet-01834-fdca337f.era1 +4f97a53b046804e68bede066b1648d83ef18c90f0849e15963e3ac70a9441c26 mainnet-01835-a45d06ec.era1 +17cbe71911e869e1180fa3f4e9f428f62a2305c6c86f7b9e3eeaeabc7e4cb4e3 mainnet-01836-87fe297b.era1 +2d02765b6d417d1800dd62d9057e933c21eb7440c075cc8de5d8a8e2e0b8e13b mainnet-01837-e26e40bd.era1 +133f804d8f0fcb26fdb49cc1d10ddf51dbe1214e1e7ffd622b72d96fe8170029 mainnet-01838-ec6b0c03.era1 +351b5e8110203c9095b32a38090e5643da57b48038d4dd84480816cd4550ff7c mainnet-01839-07950048.era1 +161f66a9d95eede26f873efa400763d90b638521268f89c9316462356161a2b8 mainnet-01840-e287972b.era1 +17ff39336044d08693519e82319b3aebcbc78e179068520d5feddca7407ea7bd mainnet-01841-2a6039e5.era1 +c882be49dedfa2ddfabf14b1d7ac3ea64e62fae051d5eb93f0caea9b1b8fbc17 mainnet-01842-5567d80f.era1 +feb4455e45319b835135110b67da829745bdaba876f5e8ad518a77189e0bec4e mainnet-01843-3153e10a.era1 +1a205dddfdd1fb0341bc260b8f2a6fe210d274f18bd1d7f650a2c475f3f9a71a mainnet-01844-03b0963d.era1 +622530320567648c3bf30a111c3e8f0c38a236772313d29f280179c2d02197ea mainnet-01845-03b93b15.era1 +eb797fcc91cd6154d60230772ca77fff747a7054a2867cf7b8d8393abdb6d577 mainnet-01846-3e05673e.era1 +82cd487fafe6d8604d9c9725bbe9452f95e026e86d76b3239b6d3e4b7146bb50 mainnet-01847-2de5f285.era1 +21045bf78b5fa1f63d746908c8677e4bcfe33ed33fe3c5388d3b46dedd945fae mainnet-01848-113a0599.era1 +7a1f6b831f2f06761fac5f630b22c38ca8cd6ffb95e14d4b23ec7229dc27945c mainnet-01849-71675e40.era1 +6dc1341e050c93d17c63b041c0135c97d5b8ed492cc386aa12b9805d71abf2bd mainnet-01850-eb0e8dce.era1 +774e428b959db0a51682351a5a68349794eb61d5f5899a2aa642c63d85b55f46 mainnet-01851-27b488ec.era1 +fb66711c88759a426d60bd0793589799c46c0275aff4957a9b46eb1b0315c940 mainnet-01852-a405f5f3.era1 +74ffea8a7f9694760b7ff2a368f5111b816813591182d44008551d5ce7a5c3f6 mainnet-01853-de7294f5.era1 +315a725314b5b8c1a00ee93fc0bb7e17166885e2daa8ef1d4abf72fdc0c02099 mainnet-01854-1b3a9f72.era1 +977941463e01f6a0a06cb7c30e6799755ef1b98b0cf8e47fb2957b4a2360345d mainnet-01855-bb986915.era1 +842ac3df8762f07afb910ab82cb89101418636f13c54d31d21e978c15fa8b246 mainnet-01856-10e8b0ee.era1 +0ed37c5b1df966e68716fa4b2c0328c2738262721fb0da19fc87ec9fd3441fb9 mainnet-01857-e0a70c38.era1 +1d419c191e93d5915e7e1a39ac7a4d1a6b5e5111f7ce772bc9c9d2bf09f0bef9 mainnet-01858-96299d52.era1 +fef06b6aae88746a73d84aae756c7073f3f7378a89c80b5629d4cbc7ba004fed mainnet-01859-056f7f9b.era1 +3d5329a9404c468f64482bd8c76ad05fd3b769cf3e1ada43910c367eec4f3f09 mainnet-01860-be17dd25.era1 +0b421c693e9d5c747b8348ce9d236e70592f5817c7f7f8ab2b579fd5d8461f67 mainnet-01861-31641a08.era1 +16c9d7c2c498f72d1336c86f477ac4ce4c1cd65fedee0cbbc196a15cfc47d4a0 mainnet-01862-deb651e1.era1 +abee7f8f73830a9a8a0eeccd6ea82abf6eb9fdaa1c58c79b95832c98c273586e mainnet-01863-500103a0.era1 +6af0acfc1ea37b531aa8cfbfaee8c99277b10ead6ceb3b19e6cdaa3bd01825a0 mainnet-01864-168be6df.era1 +7494fabb5f9f94f5afafc82ac7ef40739f8b4f74003bbabd286a8f51716920ee mainnet-01865-d69771c5.era1 +29334e8e24b5b98bfddb7f25b2c1dd31ad51d325c9613eb6210112281f1eb1ce mainnet-01866-3cf6a306.era1 +dffd7716b669261690556826cd8b21da2197ef3e98ad21cedbe9623e4f41d998 mainnet-01867-69891a16.era1 +34bda1f8771b070b95ef1ea62b49dccbd3b987f10531cf65ac18bf95ce20e415 mainnet-01868-fb7b596a.era1 +48b4ce8201c4c0e6d3dc7e079f3e87745fd6260d70cf89d210b17cf30d079b85 mainnet-01869-d864488d.era1 +8aa2f4333d0f21601874d7525ee983489b861d3198124db45ac9b6b922e609e6 mainnet-01870-3dc73a6d.era1 +5284fd43ca889845d07bac332cddc9c183e1a9a90c4281c18e1cfc00734c3a27 mainnet-01871-ca53dc21.era1 +63a6f4f1e593247cadb590ea238ca9d613c0fff308331fb7a85239cd8c4eec66 mainnet-01872-d571c79a.era1 +ca798432a63ae6b761cf9e90a98f94add78b4e292d8bd8287e3425a7b7a34c5e mainnet-01873-c71b3cef.era1 +c2134b7fa84e04548facd1d22d7f6193805a03785258bb9f2240b67afe6ebacd mainnet-01874-b43aeeec.era1 +52fd98bfa5b8a99416e1d27968215180adb0be009b6efdb22a4d3ead0349134d mainnet-01875-24fb7782.era1 +103b8e5d17b21ded74f53be236713cb8a9be4fe935ffc246a746417272d1102a mainnet-01876-41ac34f8.era1 +8b0e3abe1b964e612fae21238ebe7cb4a9070c3bda35f3aae8b31dafa907fab2 mainnet-01877-54983d68.era1 +6a16105b29fbe23cf69d902dc2cffa79f3beaf359d5b0a5d2b58789f34cc4f0a mainnet-01878-56db2145.era1 +7f73eb9fcdfb4cfc7dc9bb2cc8f0ea0498298a65eed71686102e0a695ea1a23d mainnet-01879-793c08df.era1 +41c749a4adbcb134050ff91a5d2ec6a28d33682700e294e949fd68b1dd88e4b3 mainnet-01880-0412a89e.era1 +177c549d6b99ea7ab2607343e4ba70d2a203773c43776876d1f337c5c635680f mainnet-01881-8d991285.era1 +163b67fa36d84a677985407c40f5197d7263f3d24fc3a0954bf6a8158f80dfc0 mainnet-01882-44df0aab.era1 +94b4d2fc661d91d6ef54366fccf40927dd99073564cf8b4a43127c9162dca41a mainnet-01883-bd172681.era1 +3a29dffbe1fdf5104ce49066c83e6f141c07e3d8d40ddf2d724223deb5b94c5e mainnet-01884-5732d988.era1 +c44e1614da6b9354732294c4e6615af19ca03bd4a6f967dcdffb36877e9be079 mainnet-01885-5480f074.era1 +6cb8e8d675993a2d48451afce0af65c0941fa3ccb10680bcbc52baa422c5f662 mainnet-01886-b5e8b2b0.era1 +c48f190c2b26d1cf9b8bf678cab4340faaf974c390eb4c4546399cc77fa242a4 mainnet-01887-dededef3.era1 +0c0bdea9087424b4a1fb4a6efbb5049fa814b1394f5ecffebc950d7ed08fc015 mainnet-01888-cdbce5e3.era1 +9a4d17719f76b51d6bd4be3a755be4bef91f43123a5e57982befc0aef35d5dde mainnet-01889-4a09fe43.era1 +426860d94b6b23be3d8ef680404107e9b55da28433bd514c93d5d4d41a5f6288 mainnet-01890-ff7a1b11.era1 +6c088ba4841eacd5c09a98b96631b48b655a79560cf81cfc7334af146e7e8d2a mainnet-01891-0f7bffdd.era1 +ee819214286025c3dd6f375a734a5f5b7f75567cc39f5dfda6eb3fd355a72e4b mainnet-01892-9671b1ed.era1 +f9fb6a102e845e4f7c3aab4ab72cac6720dc1a463cb541fdd24904430dcc320f mainnet-01893-1b07973b.era1 +ae91309834074d0b79557c499203bcfd03b6ddbad330874c68cb25780ca678cb mainnet-01894-80400894.era1 +30cad67a29a70185f0529bef58005ffc121fca1bfc02f95e4d7c00a4dd8aebba mainnet-01895-3f81607c.era1 +6f7cc262142969b3b06952cae4e0a2ff75710217beffd259a6128b60f2b8b23c mainnet-01896-e6ebe562.era1 diff --git a/internal/era/eradl/checksums_sepolia.txt b/internal/era/eradl/checksums_sepolia.txt new file mode 100644 index 0000000000..e8d6203999 --- /dev/null +++ b/internal/era/eradl/checksums_sepolia.txt @@ -0,0 +1,183 @@ +ab7f6d4f4eba0267406f783b75accc7a93dece520242d04fed27b0af51d79242 sepolia-00000-643a00f7.era1 +9cae627459d13ed3d05f6812eefa93242555fbefd27aa0927b40b62d44feb2e9 sepolia-00001-f3ea493e.era1 +a6f691585bc74fae6c445a8985f0df342e983ba1ef569018befb4b21b30891e2 sepolia-00002-dcb01f4d.era1 +1add5a98a9e6c15a667d6a7bbdaea115893019f3033664c54c2dcab70829268d sepolia-00003-18b32584.era1 +5e5ce2ca04b0f1aef6f026214cb64d16f76606fb5b5baf8a462f4a851dda0513 sepolia-00004-e93b3f11.era1 +db6f7687e9826a4e4dbc1361d666a8f2aa735eae309f63d9cadf6b27a899277b sepolia-00005-90918472.era1 +f61118a4e1cb718bdb71fde1daf84e59c3524b1e241ea1a5e2112d8c53acc625 sepolia-00006-a4a583b1.era1 +fd0c6fc443a4c30617ce88a48e7438fecaf4cf4772034511fa51433c7aae181a sepolia-00007-ef1e0a86.era1 +95bc416c6393e0a579f9e4af42421cf861e43354d49273d369bcf9b38e070246 sepolia-00008-dfe1e6dd.era1 +8262e7182f9a8abb9f5fc05d745a3cd2061eacda5c87cc2533af2407bd20672c sepolia-00009-dba60c04.era1 +d7c123c8e06713df23db0046df7c45d873e153ff076357b6d0c5bc9b0081a246 sepolia-00010-c99c706d.era1 +7fd359358ebf710c5c61a6a65551a4cb91c2160dbd7b59ed355a4d7e10f29328 sepolia-00011-04513853.era1 +9d6ea741d1b91e1c2c37ac1659ef3516d4968b6e7c164d347e534c4bebe644fd sepolia-00012-6e07302d.era1 +ce3e580fd3e5cb9e0ba9ebffae948406fdbe59f96fa3a05a30a381bc7d1b583e sepolia-00013-25709be2.era1 +15df46dc8c2cfd402f302f2925d1c50ac12538d394e8687920f53346429d6743 sepolia-00014-7c90e5a5.era1 +1985aaeb96c81279b978beab1145b3baf460b12bff86b8ca05c5067e1b0ca25b sepolia-00015-fadc08ab.era1 +2a53126cd443e9310fa15180c5bbbdb76f257d7fee67159500d8efa0ed13bef4 sepolia-00016-d44b2499.era1 +e783cff42ba7a53461c7fcdaf59a5387e7091a1230aa6761af05e7daf59b4805 sepolia-00017-02451eb3.era1 +92848afbeea81397fc9790e7fba7c627c01c17cbc5b8961a48ca60329bbfa3f3 sepolia-00018-cdb53b11.era1 +d15ac188a4dfac75818dfeb04e72c2f269d9f985100a457ebdc17661e36f0d83 sepolia-00019-fa770019.era1 +e8ef40780f55a0b640d1b68e1a89d1d438e8105bb1388bffc8a743b88e357671 sepolia-00020-15fc80e7.era1 +8041d790a0c50044e331a385eb98b17f5050ab25637b6a4f2c3e8e99f3f81e6e sepolia-00021-b8814b14.era1 +f17adda073b66cc97cb58acc7b776296e135943718dab9fc7cfecbac748419b7 sepolia-00022-87944c43.era1 +159a5ec4fa1e79be6d13fe4753eaa8994f547e31783069082a39d51e3e00b178 sepolia-00023-516a30f5.era1 +5b75090c9f26899aa6fe504963b7f1a43ab13a8fd7547da42f9ca9cc980511de sepolia-00024-b922dde6.era1 +d5c39668b309b43eec720b2185ac23ef819cc7fa92e35f2e6c9a4ce9ee1c249d sepolia-00025-a081e175.era1 +188b5119e110feec067dc06aefde7decba2a87bde642cc1735391a1782a99b03 sepolia-00026-d3931a12.era1 +3114068f4eb9cf8277d4417da371e820f0bf1a654600f8dea149f9854523d1f2 sepolia-00027-43f5e0ac.era1 +b18597daf66f27976638a84a4cac5622f7d53fca8264dac3665f84f28435cc26 sepolia-00028-dae08170.era1 +d0672ee04c5a84e881c4acc3757e16f963c57b5b69da81a674498c1b06159f3e sepolia-00029-17818143.era1 +122dff18aaac0bae0a006da088794f638ee95ddaa1e0a347ca9a8eca816471c1 sepolia-00030-cc7fc4eb.era1 +42c2206fda093c7aa6b31fad1addf2dd14e862b4686b0e17050bd284dc479cfd sepolia-00031-3171eede.era1 +42b023d07a02ad739b61ec8297c43501ddac200d1866fa3203df466d2442c4b0 sepolia-00032-9e2ff5ca.era1 +2461fb005a9a62cf6ab52a0b3505abde9828c1f36def4fa12a547ebb5e8c89c0 sepolia-00033-bc921023.era1 +2ca97708fba029693d7754a85424d29f57ee296a48fcbde02597603e7e90525d sepolia-00034-b2496634.era1 +d2944e1cbd7a3276ca5ef9d4b4473557a65e58bd512029b2fb00d41f618ac551 sepolia-00035-f3add4f1.era1 +c7f63d7230dd7ae9c57c33014d56bd4c921f5db95f3872bf6745d03bc64b5cc0 sepolia-00036-0db12924.era1 +dc027011c543418fcfdd7897cea3356de16122f676da2459d78da5369cdc2b8f sepolia-00037-ae8bdd13.era1 +9be2262ef4e1e1b93cee3316ad473895bd7a7f3bff15ac8c18c1a157292ab7f6 sepolia-00038-81f80b03.era1 +56c03c86028c95d431030fa2728493ca8001cc86eec3f5d7a558224e550b42ef sepolia-00039-03e5d6f1.era1 +d64e65ecfcf480c2edbdebac350ac899b25874a522c226695a46fab17de5b15c sepolia-00040-296fe287.era1 +18226ba389f150581b36a234d877fad9c08c0fa691a366ba11f808ec9110cf67 sepolia-00041-5cd87470.era1 +0d2960f23933deadcdfe545fc8aba626e79c0c010fad0ac01b577ca5b99840e0 sepolia-00042-de86936c.era1 +b14f66c2fc74d0f772eb75c548a86da4bf160cf1067091c65c05a90812e7af1f sepolia-00043-ede4e682.era1 +15d704883fadfcbe4ce3520bc9ed5fcff98a8a419b6fa9f832394008ae1941aa sepolia-00044-4d49a81a.era1 +5343d8015eb0a6b8728b571fd0e7a2bb92728ec593469b0a9d8d2082a5afc36d sepolia-00045-7071c19b.era1 +63efe606b8c687aeeff4d2ff5596a72da862d024f9dbb1ff5bf67ca4f2921f77 sepolia-00046-4f4fe79f.era1 +9eb6dd3772ebfe63c37a22423310a5cb36c0d09defd66d7aa02a5b4c1283ca80 sepolia-00047-76b58fb3.era1 +82afedad4e56f86d836446f0c71616f8d88fdec11b93a6360dacc111cdb12db2 sepolia-00048-0fa9d93c.era1 +8a86584323e83a11499265f33ddabe0de1517b51c8e73985fa6eed15cfd63d0b sepolia-00049-d193ff47.era1 +b66621a148fb7acce05efe6aab89be5a965463a4c4c95a3350e64f3e8a684417 sepolia-00050-736b969f.era1 +49d47547284339de6f92e6495347dce0c45c5294f07c1b96fcfa510c43cfc206 sepolia-00051-466eb482.era1 +b075750d6efdde0cd755c90cd893b2917c56ab8674022fb36bb7a1305dc9bfed sepolia-00052-9752212c.era1 +36eb486d7dab70e759c72198b9f2505ac3fcb7f6a0ae2cca82fd9ade3d65e86d sepolia-00053-b2897233.era1 +9f024ea4e135fe6939f2fedb6a6821d61202139fa35378616fcf0274bdeac172 sepolia-00054-aedad6a8.era1 +2bc46d10add9c9903d554523f6ed0c8f5a632521c659d9f3f4af4c444221d08c sepolia-00055-19af5091.era1 +21900526ff5f0f31257bdabaae3fffa700eccd3cf3a6ba346b4bdf4347c97324 sepolia-00056-9ac921a1.era1 +c9a47d7db6af1b984e6ad8de2ea0eb0e73e442281d4fa497ba64c02caaf0b7d0 sepolia-00057-240f011a.era1 +10d38d3b6b66367a1c05922040073d6a62a2cbb843ea821dbd02f4d9f037c740 sepolia-00058-06d606d6.era1 +d391f44dfa9bab3ced35676cd964daeffe0f4e4028c3bd44fe41010b761c5229 sepolia-00059-8ea69a55.era1 +39a1bdf4d7c1dd8365f635c8da568b34d1c2e59aa5d7fe8745d6b7db2cf2c6ed sepolia-00060-d22079b0.era1 +cf41ae65b6391d8c44bb0128e66591a96d42fea0a7d35c30c8eca5bbe0790578 sepolia-00061-834d00e3.era1 +9bcff9fa47c2addc140857b23d6453583ca526c6cdf11144583db24acf33b1b2 sepolia-00062-d1230cc2.era1 +984c5662f6f36ece4e0ca9efc47dcb3e50e0aa581a874a680736f2f558cdd889 sepolia-00063-e1e9fa40.era1 +7582532b67144ea9499c28d935e7ac4bbf8f465c382a8a97ce04e56539b8c9af sepolia-00064-7f827781.era1 +945e3da724660df934484d68868d54fbfaa5feaacdd635f6185b56e88858ad8d sepolia-00065-9d8993d6.era1 +77fdff04d6d6233c4bab9811ad559a328fdb0447070b96e2f38ea7450639a00e sepolia-00066-8d516260.era1 +3486301cf48b1f727b46c0223c4a018e03d0857efedc2f616ea850b539139f93 sepolia-00067-7466141b.era1 +2954560d2b1c6ff48242312b7f5fe902c53dc93a3d1c7d9abf41633926ef72ac sepolia-00068-1bd11e8a.era1 +8f27de663991d7e4e8a7005dee7b94f991cfefad743507362eca5ad83f53e449 sepolia-00069-536ecd2c.era1 +2d0fa324482aab3db61718abfb2a5c084a55db5f39c4bce125255eec9a56a01a sepolia-00070-b27f7c5c.era1 +472b1c9ec83d9b6564a45d4363c856604d21b53d8c89a7b5810f2596c14f710a sepolia-00071-d2ef5349.era1 +3a0e6051e4c5f1a263b51f7a827d2276c7b25cb9d426f24f39fca33a7e76d623 sepolia-00072-b23578a9.era1 +734b46f0bb7150e1d705bff53a0cdedd3ed57ca1461f06deb517c8b74c4b25c9 sepolia-00073-8bacb416.era1 +28091f1a78dc398e2d47212087f652c8d35f07cda5457ee691b4191c3a6698c8 sepolia-00074-0e81003c.era1 +b743e3e1721e593562d9a144f49a927bbe2db70be9e4884521cae9500b0004cb sepolia-00075-09177034.era1 +6850f49599b95dcf1db54a3c5d126654ca21de4df27b7a24bc35c4d10fe6cdb7 sepolia-00076-0f2898a3.era1 +da57f20ff5a3944bd1fef22e7c914f2eda3e79dd7346b0e7c0a01e69cf538d7e sepolia-00077-61de3538.era1 +fc20551b69bacce502fa42ba5b0a223c9fb558d5f495948e38c060328f1ceb7e sepolia-00078-be407b86.era1 +ab72961502e1d8055886d744c077dbf60db8acba64c7879109b3ed573ce4cd02 sepolia-00079-d5c957be.era1 +216b65dba90adf1288d40fc689f6087ff2435bd379df482b130cd464cbd1d490 sepolia-00080-ae6ce310.era1 +e824e04c1cf15f142bdbb40161b64953767abd3ec7c40a726ce69d4ce646df08 sepolia-00081-daac26d6.era1 +d70d059609dda26e25af96d32b646c364e2ae44fe7b1cf9e2e8589d731e9f381 sepolia-00082-ecb8f0c2.era1 +a7dc282ca7fd7aa8d42693363aec655d6cfea330220233c7aad3f7955284d650 sepolia-00083-5b017cd4.era1 +2f1006528caa6d47729c4ef0a699c441cb5d2c201afb6563ab51184429294020 sepolia-00084-8c1f92cd.era1 +374494754cfd728b1b4e4a00db810012346ba8c4dc9cf2ad1d80187999ab868b sepolia-00085-9180667c.era1 +7ff9b360a0656ddbace4032d249f5cf06068ee3f8be526d2a4ae0ed6eaef046f sepolia-00086-1aca7add.era1 +de592f4bde8de973d8c82a7d89dbe21cf75bb0b28204567ea4f5012b8be1f28c sepolia-00087-0e100944.era1 +fb6eb1e1e1ce97e03b39fe2d53e3595d759701a65cc861d0568c04ee7e2ec03c sepolia-00088-fcdd7aa5.era1 +4d178ce50f5436f5ba2347d87dc79e9a2e18c17d3056eb77c7c8dbb9b03bb986 sepolia-00089-b23b2368.era1 +21e919f0d32137e7924d54ddcf1e697bb5b57bbb7cc12a169475df993c4c1d9f sepolia-00090-b78edeb7.era1 +cb7ae025ca17c5f52ef7910147a47a0d3680c26f9d2d109d6af330f93f95b735 sepolia-00091-4c81cdca.era1 +1e0249554f150b63cb7dd57c53c624c197b415401c0a1f3986c2f06e8aaa795c sepolia-00092-ddbf3a4c.era1 +8d950d8c13a4e002514a47e6d6ebcad4bf7e5808398641a5c04863d9c90f0f87 sepolia-00093-a52a45ec.era1 +b8720324f04dca4e0046b12ec3b8a2b862158f3156c4d1fc2947340b1fc1a9cb sepolia-00094-839ea4e5.era1 +8c4134bbb21d36fbd7ba608eb1e485e76cb0fd56c4aa8032be1b6848757856d9 sepolia-00095-bccc0958.era1 +e3ad213e760ea2320ff52caf5de32ced37d6b7ad0f99384785ca42a7e58d1cd9 sepolia-00096-429b2f39.era1 +9c324e109f77ebc1750dd2a0941904ff820047def91f8b832e61c01b31297f38 sepolia-00097-6f74184d.era1 +26efc4469736b283fd80d9105fc85a70dbec209fbb0e1e40a905a9406e1bb3cc sepolia-00098-40286059.era1 +e14134b3aad0533366f9aeb19cf2561cf1e81b989a0b83f12b05493948dd71ea sepolia-00099-dd1ef4f4.era1 +7283a437244545e784d51186c0d7d4809808dd472850ca3cd2d7a40f4883b50d sepolia-00100-bd3d6bf4.era1 +b67270e94377703aac798d8323c0a91b451d36806775013a2b8b12db04797851 sepolia-00101-41676e0d.era1 +dd6ea805242a67c6255867f64fc5fbc941a98318b5ea1d5e2d42d42c6910493c sepolia-00102-4f3c1fe1.era1 +d6f6da94b16a201b304936cb5f798b6fedba76ead056cd2c4dc860c21d82b8dd sepolia-00103-e13a95f0.era1 +e2309561f7a86eddfe182dc86fb38e5454c5a272cc77b3d0d7c6ce987ddc874c sepolia-00104-4e49b068.era1 +deff905084758be35bf0b8cb640b1b283232abbc6153388a4275c767ea0bdf0e sepolia-00105-4ab7d9ea.era1 +964f9679a39fe06192a7025f14404cb1f6542071665f1c2f739f62fdb55e9274 sepolia-00106-5ec678af.era1 +8fd75370992f97e77a2cd3663bc1fb9b2bcec9b64a0439de7846d7c6321e6d93 sepolia-00107-44721c55.era1 +7e8219aa13d6a7b32c3a69888a2c5f446703eada3fdcde841ba26edfe3cb4453 sepolia-00108-3b4ad768.era1 +24e8d2f8d01abf63d97365bafa914dd5203f4e807bc6655dc0673b9f87215ebd sepolia-00109-16e54758.era1 +edadb0ebec6c4b7b54237e5802cc59fd962e23cf690ff10ab52c10258d7b7827 sepolia-00110-b5da103b.era1 +4faebfbdc009188cc8cf0ffe4aeca9c93ac5b3abe763cfb165d8bed37b12b51c sepolia-00111-15c53aba.era1 +40210479bd14ca3f8db76b288c2ed4e8f3d5b5ce8116ba8d8fe3133b0cc765ad sepolia-00112-8e2144e3.era1 +92ed406d564ed1504bc7ff91298a419fe72a710585256b1830040ba3d1adbde8 sepolia-00113-1e1aac0a.era1 +7e771bba1aa9c87be155a9a7d62d3479240f21934a3d763cafa5f3cd4ce49f8a sepolia-00114-0d7a4b23.era1 +51d71ed3674f5d70f719b3251e29a0825f2573b1bfd1a92940b013806aaf4fd3 sepolia-00115-8e983a59.era1 +6abea02d82f7a30b67d6de4516bbc711855eea3d891ea42fa0124c101f981f86 sepolia-00116-1708ba6e.era1 +88e7222e35b1275483b6eec11bf8d4417602fdb16b611d6c154abd8d0ec0b49a sepolia-00117-86962046.era1 +6ddeae324cc17337fa23c71b242ab1675b72f43fb393af7e971edec20451f864 sepolia-00118-934e9f5f.era1 +914c35142f7244d07b670b1f990c8bb5997119db451e8dcd8a67c8d71fcc6af2 sepolia-00119-4d88db3e.era1 +eedec437c182f330f2f5f3c530cce3bc59f0c99c9e6cd36288a588adba7679bb sepolia-00120-1a3274d5.era1 +4914f6a8cf63cb806c5736431f6402d9a99c2de953da05a17069fa15cf8c695b sepolia-00121-62b79757.era1 +b9a0138c77dcbb2b4784813204ec8bc30407cd8daf3501707719985acff4a1cb sepolia-00122-41d14652.era1 +57453e0eaa2bf46a13c94d9e96ee98943a46012c2bdd9da5d7c77064e803fbfd sepolia-00123-67f86708.era1 +1e927fdb13cebda45a963c8cec921b16c795fb3020cad9054fa1fb7f4cb528cd sepolia-00124-488cb226.era1 +8015846c8c3663005a8a6d59347fb672a602e6bbff028989355a01f5f6d2b183 sepolia-00125-8a21f7da.era1 +8807f6abe63b76f31d99cf14404fee8bb5eba3a814e2d08b9d85540ef9742550 sepolia-00126-6569478a.era1 +28dc46c8120426b395cf9b5ff781962a3212766b24511b2dc3d2172568b10021 sepolia-00127-1312ab23.era1 +ed66119ec9dae6c61952cbf40b9dc5770cd80e659a83dd18e1a5f2ffa947a04b sepolia-00128-1c95bdc6.era1 +a4a68dd54b77f21939ddb1ec9ef9ae0a3551d6d53b8f9578b01ad8e32e5c8d8e sepolia-00129-f32fdefa.era1 +e54d6d4b95a985f37391750b3bf3bc0f9f4e2f790805797ee198d77287433ca2 sepolia-00130-8f31c590.era1 +577fe68c5c33e47af8823ac573709ed9d63df0d7f9aec02a7907e3e6e5922d67 sepolia-00131-5aaad354.era1 +c3beada9620c55b6d0dbdab8f66b735da0b3d62d5c5eb2c3b5369619549fb3e0 sepolia-00132-2147d970.era1 +12843e128e76d5636f857c8c6801e433757fc4f8aba159bc2d4e6c41f2c94abd sepolia-00133-690cc16f.era1 +e5e4904ec83ebcebccc1aae1de89622a50bf6f735d985234da88fa1ced1787c0 sepolia-00134-fe276e6b.era1 +9c618458f6d76a09f16c86baf526dc7f2310ce92d862f73392144987c04b39ed sepolia-00135-ce40efd0.era1 +1d032d1279c3841c65385f85463226df04a98a3ccc5d7bf461f042492230615c sepolia-00136-adc6e1bb.era1 +a3aa401ca2bc8cb8b104667c6f68e28d00e37813a1a993d8abd1ec5c3555f71d sepolia-00137-805a333a.era1 +105c1e50e73715bf58d42f6bbe49bff36dc0051bfb477efc77ebf14b5ba98974 sepolia-00138-65ff170f.era1 +ad53fc0e4d2718ce105fa3a7ce5574dbb945f49b2fa7470a406179c45738fc46 sepolia-00139-1c86d86a.era1 +c27ae427ca0052686a3ac8a3e568d1dae30449f9edba465f218c147074d61ccc sepolia-00140-e7f36280.era1 +143d09ffb26cd2a1bb334958d92b77a92a8f9ac99c01059d22bee4e4d8bc3212 sepolia-00141-5d3d0d5a.era1 +378a77f0b0c4072297de4c382cece46be521a6c6935db8eb499dd99857d566aa sepolia-00142-e45aa418.era1 +35855d5bd75dff01248dd5b2080babf6127d87c157a987124f7a258cfb9a5ecb sepolia-00143-70379f59.era1 +58f07f98d8e9486acd01ec212518b1c0d7764e68263f9b1e9c51cf5e597a0b6b sepolia-00144-c345e75c.era1 +17caa603e2d1f9c01c9117754f0bb4c8ce42c58da806f758f99468d9f8c1c47b sepolia-00145-9f4bb4c5.era1 +d05a92b8fe1306397b98a6202b18f66c9bc259bd41c25b3d8211c09813e3a9ac sepolia-00146-3336d26b.era1 +b7120a656d06d4010a06a2abadd809ee7f26707cf313e9de5cb1bd172745ad23 sepolia-00147-6b007873.era1 +aa45cc5747e9c21ccfc44c87f98717702551a0511f423b2624a34af58ba798fc sepolia-00148-35f8a5b4.era1 +952843d531ea4d9ee9c456e50e77c50f75a559bff13326dd593271f90cd55129 sepolia-00149-01b6e9ca.era1 +2d93d1d84e0f4013d6daab61d66907488223a2f1b50e4a22d3ba1da24a9c6a84 sepolia-00150-0c372e80.era1 +6b516e3f31720c54453c5ce9bbac68300615f455a7cf4b1dc6592a5d5432ee89 sepolia-00151-c15a5955.era1 +82023cab017453e8fcf49ace9befbaef4af167e0e6c6976456bf251f803b5d51 sepolia-00152-ef7ac893.era1 +6ace677a17380127349ba0710fd02ff38ba185526cc2d9bbb6f05375d6f163f6 sepolia-00153-0e4073c2.era1 +66db5e0786cb9963ed66a0e31773b30d3405621a7636c62ffbb0b84ff41705bd sepolia-00154-298c3549.era1 +cf797283087a079773770c1bebfecb113a4155e0d77d5713c702478e2c24f64a sepolia-00155-a99309bb.era1 +b143cc994d0b544cd08b2a1f66308718ea49f3f68adef8e62300e91f8048130a sepolia-00156-8c33148f.era1 +cbc20f9f767324438a237c3114a1c4e65dda74d4a655d55a7cc3e63e62f373f8 sepolia-00157-ab02fc10.era1 +c8368d1752e66bcd7cabc653477f9aec0071027f91112a8cf71a945db23404e7 sepolia-00158-17992856.era1 +03a1a66eab3a7cbc63b29cfbe2e70285940e64db4af6d23ab70592c820f8d3ea sepolia-00159-b3448cf6.era1 +bf9dcd8400e56c58cd3280f0a3d7aab23a7eaf594e67db5387f40101ad8e8c92 sepolia-00160-acad7054.era1 +03a3b975b2a78a4b28afd9ee089440465ceefd32bd1d82b74ae69caa80b6fb6c sepolia-00161-36e611bd.era1 +ddf201b59ebc77eccdec97b0a5a7d7a89dda02928ff7c5cca8868b5aba84f533 sepolia-00162-3557cc58.era1 +041be469daf6f7abaa0cfe66c4d68b7d9d223383553c16f078edb3a1fa3d0d92 sepolia-00163-638b9afe.era1 +68d151048412318cbd0af98efa27d7ee16e2fc58830d93b4d76b66cb632ebfc3 sepolia-00164-fbc67b64.era1 +3025771380736a5de790ead991c0512a4c73106fd1d2f169863d395964238ac1 sepolia-00165-442b83a1.era1 +6d6b1273a6fc353c6999b4c9be301660a404b78cced911e230991305da990e3c sepolia-00166-018915fc.era1 +01052c4f779e4ec276498d4192b8ad11ad6d2d3992224bb62ea882a80deda935 sepolia-00167-0df2b4c5.era1 +2f8f3034eb7e41c5add0e639e21b52c0794f36bb5918274849402c5fe0d247e6 sepolia-00168-7cab66f5.era1 +504b0203d995e5ef6aee679b048c276f45b05dc68a6fd319a0f4f0133b230a77 sepolia-00169-75850131.era1 +b277df79fe5a83189f9619b275a9aaab63db8506539c56997be61fd5a3552bb9 sepolia-00170-c2044b78.era1 +1af0a1778fc5d2a53aaca06dbda6671b91ae3f56da73a6c6708bc729e5fb9efd sepolia-00171-af44ff2e.era1 +a977654c0ed243ccce7b5514914ec94d70a3a742ff014ac52b0654e21940f2da sepolia-00172-bd76a8d9.era1 +146672b2e63c320c9474ecf41d7f32f31f5298512cc8f911074c88789849d935 sepolia-00173-b6924da5.era1 +82af1c5bc51f9e9ae1be5d0e0827ea755d104ed373b374c08ef401115491671f sepolia-00174-2a61fac5.era1 +627ee6cf9282191ff32d291fc0437b812bad01f158b5ca42ae717b7bbb125f8c sepolia-00175-1cc76405.era1 +6ee38f117646a47f6ab2f666fa6460bda770c194ae4a29744534e9bfd9e7ba3b sepolia-00176-20daa2c6.era1 +28e7e49e71dd8581cc484d8be89fb083a79577b06f26c1e3bfd4a57bdf24c5e7 sepolia-00177-379df7e4.era1 +055c365cfeda3495a5e2b334803dfffe7af2a584745acabc42b5ad146b250534 sepolia-00178-88c9d2aa.era1 +bca9a920232983636b7cf20fc8319f891df94ba0860f51b5a052290b58d9e3ae sepolia-00179-8329b80c.era1 +e894a6f3ce0ede2825aaafa64122a5f458cd3b2ecaeae20a44a59fd668971bb0 sepolia-00180-22de0418.era1 +83bfe0d7c49c3a108a4ed044119a3549f2f4b0f8e74c971150b6977b7d46a250 sepolia-00181-b3fbe6f2.era1 +3b806177536ac3615f376440c0589696ea746eea0215bb3b175df8f4f1e73894 sepolia-00182-a4f0a8a1.era1 diff --git a/internal/era/eradl/eradl.go b/internal/era/eradl/eradl.go new file mode 100644 index 0000000000..30bd2bc0d5 --- /dev/null +++ b/internal/era/eradl/eradl.go @@ -0,0 +1,115 @@ +// Copyright 2025 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 eradl implements downloading of era1 files. +package eradl + +import ( + _ "embed" + "fmt" + "net/url" + "path/filepath" + "regexp" + "strconv" + + "github.com/ethereum/go-ethereum/internal/download" + "github.com/ethereum/go-ethereum/internal/era" +) + +//go:embed checksums_mainnet.txt +var mainnetDB []byte + +//go:embed checksums_sepolia.txt +var sepoliaDB []byte + +type Loader struct { + csdb *download.ChecksumDB + network string + baseURL *url.URL +} + +// New creates an era1 loader for the given server URL and network name. +func New(baseURL string, network string) (*Loader, error) { + var checksums []byte + switch network { + case "mainnet": + checksums = mainnetDB + case "sepolia": + checksums = sepoliaDB + default: + return nil, fmt.Errorf("missing era1 checksum definitions for network %q", network) + } + + csdb, err := download.ParseChecksums(checksums) + if err != nil { + return nil, fmt.Errorf("invalid checksums: %v", err) + } + + base, err := url.Parse(baseURL) + if err != nil { + return nil, fmt.Errorf("invalid base URL %q: %v", baseURL, err) + } + if base.Scheme != "http" && base.Scheme != "https" { + return nil, fmt.Errorf("invalid base URL scheme, expected http(s): %q", baseURL) + } + + l := &Loader{ + network: network, + csdb: csdb, + baseURL: base, + } + return l, nil +} + +// DownloadAll downloads all known era1 files to the given directory. +func (l *Loader) DownloadAll(destDir string) error { + for file := range l.csdb.Files() { + if err := l.download(file, destDir); err != nil { + return err + } + } + return nil +} + +// DownloadBlockRange fetches the era1 files for the given block range. +func (l *Loader) DownloadBlockRange(start, end uint64, destDir string) error { + startEpoch := start / uint64(era.MaxEra1Size) + endEpoch := end / uint64(era.MaxEra1Size) + return l.DownloadEpochRange(startEpoch, endEpoch, destDir) +} + +// DownloadEpochRange fetches the era1 files in the given epoch range. +func (l *Loader) DownloadEpochRange(start, end uint64, destDir string) error { + pat := regexp.MustCompile(regexp.QuoteMeta(l.network) + "-([0-9]+)-[0-9a-f]+\\.era1") + for file := range l.csdb.Files() { + m := pat.FindStringSubmatch(file) + if len(m) == 2 { + fileEpoch, _ := strconv.Atoi(m[1]) + if uint64(fileEpoch) >= start && uint64(fileEpoch) <= end { + if err := l.download(file, destDir); err != nil { + return err + } + } + } + } + return nil +} + +func (l *Loader) download(file, destDir string) error { + url := l.baseURL.JoinPath(file).String() + dest := filepath.Join(destDir, file) + return l.csdb.DownloadFile(url, dest) +} From 1f175347c47810564c7d6fab3bbd855eb449468d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marius=20Kj=C3=A6rstad?= Date: Thu, 15 May 2025 22:54:18 +0200 Subject: [PATCH 368/940] build: upgrade -dlgo version to Go 1.24.3 (#31774) New security fix: https://groups.google.com/g/golang-announce/c/UZoIkUT367A --- build/checksums.txt | 94 ++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index a914d79860..c819429969 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,54 +5,54 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/ b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz -# version:golang 1.24.2 +# version:golang 1.24.3 # https://go.dev/dl/ -9dc77ffadc16d837a1bf32d99c624cb4df0647cee7b119edd9e7b1bcc05f2e00 go1.24.2.src.tar.gz -427b373540d8fd51dbcc46bdecd340af109cd41514443c000d3dcde72b2c65a3 go1.24.2.aix-ppc64.tar.gz -238d9c065d09ff6af229d2e3b8b5e85e688318d69f4006fb85a96e41c216ea83 go1.24.2.darwin-amd64.tar.gz -535ed9ff283fee39575a7fb9b6d8b1901b6dc640d06dc71fd7d3faeefdaf8030 go1.24.2.darwin-amd64.pkg -b70f8b3c5b4ccb0ad4ffa5ee91cd38075df20fdbd953a1daedd47f50fbcff47a go1.24.2.darwin-arm64.tar.gz -4732f607a47ce4d898c0af01ff68f07e0820a6b50603aef5d5c777d1102505e2 go1.24.2.darwin-arm64.pkg -c17686b5fd61a663fbfafccfa177961be59386cf294e935ce35866b9dcb8e78a go1.24.2.dragonfly-amd64.tar.gz -026f1dd906189acff714c7625686bbc4ed91042618ba010d45b671461acc9e63 go1.24.2.freebsd-386.tar.gz -49399ba759b570a8f87d12179133403da6c2dd296d63a8830dee309161b9c40c go1.24.2.freebsd-amd64.tar.gz -1f48f47183794d97c29736004247ab541177cf984ac6322c78bc43828daa1172 go1.24.2.freebsd-arm.tar.gz -ef856428b60a8c0bd9a2cba596e83024be6f1c2d5574e89cb1ff2262b08df8b9 go1.24.2.freebsd-arm64.tar.gz -ec2088823e16df00600a6d0f72e9a7dc6d2f80c9c140c2043c0cf20e1404d1a9 go1.24.2.freebsd-riscv64.tar.gz -e030e7cedbb8688f1d75cb80f3de6ee2e6617a67d34051e794e5992b53462147 go1.24.2.illumos-amd64.tar.gz -4c382776d52313266f3026236297a224a6688751256a2dffa3f524d8d6f6c0ba go1.24.2.linux-386.tar.gz -68097bd680839cbc9d464a0edce4f7c333975e27a90246890e9f1078c7e702ad go1.24.2.linux-amd64.tar.gz -756274ea4b68fa5535eb9fe2559889287d725a8da63c6aae4d5f23778c229f4b go1.24.2.linux-arm64.tar.gz -438d5d3d7dcb239b58d893a715672eabe670b9730b1fd1c8fc858a46722a598a go1.24.2.linux-armv6l.tar.gz -6aefd3bf59c3c5592eda4fb287322207f119c2210f3795afa9be48d3ccb73e1b go1.24.2.linux-loong64.tar.gz -93e49bb4692783b0e9a2deab9558c6e8d2867f35592aeff285adda60924167f3 go1.24.2.linux-mips.tar.gz -6e86e703675016f3faf6604b8f68f20dc1bba75849136e6dd4f43f69c8a4a9d9 go1.24.2.linux-mips64.tar.gz -f233d237538ca1559a7d7cf519a29f0147923a951377bc4e467af4c059e68851 go1.24.2.linux-mips64le.tar.gz -545e1b9a7939f923fd53bde98334b987ef42eb353ee3e0bfede8aa06079d6b24 go1.24.2.linux-mipsle.tar.gz -6eab31481f2f46187bc1b6c887662eef06fc9d7271a8390854072cdb387c8d74 go1.24.2.linux-ppc64.tar.gz -5fff857791d541c71d8ea0171c73f6f99770d15ff7e2ad979104856d01f36563 go1.24.2.linux-ppc64le.tar.gz -91bda1558fcbd1c92769ad86c8f5cf796f8c67b0d9d9c19f76eecfc75ce71527 go1.24.2.linux-riscv64.tar.gz -1cb3448166d6abb515a85a3ee5afbdf932081fb58ad7143a8fb666fbc06146d9 go1.24.2.linux-s390x.tar.gz -a9a2c0db2e826f20f00b02bee01dfdaeb49591c2f6ffacb78dc64a950894f7ff go1.24.2.netbsd-386.tar.gz -cd1a35b76ed9c7b6c0c1616741bd319699a77867ade0be9924f32496c0a87a3f go1.24.2.netbsd-amd64.tar.gz -8c666388d066e479155cc5116950eeb435df28087ef277c18f1dc7479f836e60 go1.24.2.netbsd-arm.tar.gz -5d42f0be04f58da5be788a1e260f8747c316b8ce182bf0b273c2e4c691feaa1a go1.24.2.netbsd-arm64.tar.gz -688effa23ea3973cc8b0fdf4246712cbeef55ff20c45f3a9e28b0c2db04246cf go1.24.2.openbsd-386.tar.gz -e5daf95f1048d8026b1366450a3f8044d668b0639db6422ad9a83755c6745cf7 go1.24.2.openbsd-amd64.tar.gz -aeadaf74bd544d1a12ba9b14c0e7cdb1964de3ba9a52acb4619e91dbae7def7b go1.24.2.openbsd-arm.tar.gz -9e222d9adb0ce836a5b3c8d5aadbd167c8869c030b113f4a81aa88e9a200f279 go1.24.2.openbsd-arm64.tar.gz -192fffa34536adc3cd1bb7c1ee785b8bc156ae7afd10bbf5db99ec8f2e93066e go1.24.2.openbsd-ppc64.tar.gz -a23e90b451a390549042c2a7efbec6f29ed98b2d5618c8d2a35704e21be96e09 go1.24.2.openbsd-riscv64.tar.gz -5cdcafe455d859b02779611a5a1e1d63e498b922e05818fb3debe410a5959e9e go1.24.2.plan9-386.tar.gz -81351659804fa505c1b3ec6fdf9599f7f88df08614307eeb96071bf5e2e74beb go1.24.2.plan9-amd64.tar.gz -6e337d5def14ed0123423c1c32e2e6d8b19161e5d5ffaa7356dad48ee0fd80b4 go1.24.2.plan9-arm.tar.gz -07e6926ebc476c044d7d5b17706abfc52be52bccc2073d1734174efe63c6b35e go1.24.2.solaris-amd64.tar.gz -13d86cb818bba331da75fcd18246ab31a1067b44fb4a243b6dfd93097eda7f37 go1.24.2.windows-386.zip -8a702d9f7104a15bd935f4191c58c24c0b6389e066b9d5661b93915114a2bef0 go1.24.2.windows-386.msi -29c553aabee0743e2ffa3e9fa0cda00ef3b3cc4ff0bc92007f31f80fd69892e1 go1.24.2.windows-amd64.zip -acefb191e72fea0bdb1a3f5f8f6f5ab18b42b3bbce0c7183f189f25953aff275 go1.24.2.windows-amd64.msi -ab267f7f9a3366d48d7664be9e627ce3e63273231430cce5f7783fb910f14148 go1.24.2.windows-arm64.zip -d187bfe539356c39573d2f46766d1d08122b4f33da00fd14d12485fa9e241ff5 go1.24.2.windows-arm64.msi +229c08b600b1446798109fae1f569228102c8473caba8104b6418cb5bc032878 go1.24.3.src.tar.gz +6f6901497547db3b77c14f7f953fbcef9fa5fb84199ee2ee14a5686e66bed5a6 go1.24.3.aix-ppc64.tar.gz +a05fa7e4043a4fec66897135219e3b8ab2202b5ef351c60c2fbb531dfb8f2900 go1.24.3.darwin-amd64.pkg +13e6fe3fcf65689d77d40e633de1e31c6febbdbcb846eb05fc2434ed2213e92b go1.24.3.darwin-amd64.tar.gz +97055ff4214043b39dc32e043fdd5c565df7c0a4e2fc0174e779a134c347ae0e go1.24.3.darwin-arm64.pkg +64a3fa22142f627e78fac3018ce3d4aeace68b743eff0afda8aae0411df5e4fb go1.24.3.darwin-arm64.tar.gz +32de3fd44d5055973978436a7f1f0ffbaae85c1b603ec6105e5c38d8a674c721 go1.24.3.dragonfly-amd64.tar.gz +9fe6101b3797919bd7337ee5ce591954f85d59db7ae88983904db29fd64c3dd1 go1.24.3.freebsd-386.tar.gz +6ccf4cca287e90cc28cd7954b6172f5d177a17e20b072b65f7f39636c325e2fb go1.24.3.freebsd-amd64.tar.gz +ce45ebf389066f82a7b056b66dd650efb51fde6f8bf92a2a3ab6990f02788ebf go1.24.3.freebsd-arm.tar.gz +8f6494a12a874d0ea57c67987829359e016960ce3ba0673273609d6ac2af589a go1.24.3.freebsd-arm64.tar.gz +f9db392560cf0851f0bc8f2190e1978e01b4603038c27fecfc8658a695b71616 go1.24.3.freebsd-riscv64.tar.gz +01717fff64c5d98457272002fa825d0a15e307bf6e189f2b0c23817fa033b61c go1.24.3.illumos-amd64.tar.gz +41b1051063e68cbd2b919bf12326764fe33937cf1d32b5c529dd1a4f43dce578 go1.24.3.linux-386.tar.gz +3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 go1.24.3.linux-amd64.tar.gz +a463cb59382bd7ae7d8f4c68846e73c4d589f223c589ac76871b66811ded7836 go1.24.3.linux-arm64.tar.gz +17a392d7e826625dd12a32099df0b00b85c32d8132ed86fe917183ee5c3f88ed go1.24.3.linux-armv6l.tar.gz +e4b003c04c902edc140153d279b42167f1ad7c229f48f1f729bbef5e65e88d1f go1.24.3.linux-loong64.tar.gz +1c79d89edf835edf9d4336ccea7cb89bc5c0ca82b12b36b218d599a5400d60fe go1.24.3.linux-mips.tar.gz +0b64fe147d69f4d681d8e8a035c760477531432f83d831f18d37cb9bf3652488 go1.24.3.linux-mips64.tar.gz +396b784c255b64512dc00c302c053e43a3cbfc77518664c6ac5569aafad4d1e6 go1.24.3.linux-mips64le.tar.gz +93898313887f14e8efbe9d7386d5da4792b2d6c492bee562993fd4c9daa75c6d go1.24.3.linux-mipsle.tar.gz +873ae3a6a6655a7b6f820e095d9965507e8dfd3cf76bc92d75c564ecbca385f6 go1.24.3.linux-ppc64.tar.gz +341a749d168f47b1d4dad25e32cae70849b7ceed7c290823b853c9e6b0df0856 go1.24.3.linux-ppc64le.tar.gz +fa482f53ccb4ba280316b8c5751ea67291507280d9166f2a38fe4d9b5d5fb64b go1.24.3.linux-riscv64.tar.gz +a87b0c2a079a0bece1620fb29a00e02b4dba17507850f837e754af7d57cda282 go1.24.3.linux-s390x.tar.gz +63155382308db1306200aff7821aa26bf2a2dda23537dd637a9704b485b6ddf0 go1.24.3.netbsd-386.tar.gz +fe2c5c79482958b867c08a4fc2a10a998de9c0206b08d5b3ebcb2232e8d2777c go1.24.3.netbsd-amd64.tar.gz +e8ff77aef21521b5dd94e44282a3243309b80717414cf12f72835a45886a049f go1.24.3.netbsd-arm.tar.gz +b337fbaf82822685940ffaa76fbcf4be5d2f0258bc819cd80bc408b491f45c04 go1.24.3.netbsd-arm64.tar.gz +c1bb9dd8418480aa7f65452b08de3759da3bf89702be71b5a9fc084836b24ad5 go1.24.3.openbsd-386.tar.gz +531218de748b0caaf6d1ad18921206fc12baaa89bf483a0a5e60a571c206fe6f go1.24.3.openbsd-amd64.tar.gz +bcd0dc959986fc346969b5d4111c3c8031882d8bf8d87a2c2ecf1328962a91f2 go1.24.3.openbsd-arm.tar.gz +00ee6f8f1c41fd2e28ad386bd7e39acce7cab84af6de835855b29d1c597335c4 go1.24.3.openbsd-arm64.tar.gz +9f4ec0a9203ed3c54ce1a2a390ad3d45838cdb7efd85baeff857e37dfde04edd go1.24.3.openbsd-ppc64.tar.gz +da4d6f80e2373250d8c31c32dcd1e08775c327c0d610923604660cc0e07e8cba go1.24.3.openbsd-riscv64.tar.gz +f5d02149132eedda6c2d46b360d7da462b8a5f9e3f8567db100c2d7bff0ddcd7 go1.24.3.plan9-386.tar.gz +175f3d79f4762a3c545d2c6393bf6b8bac24e838026869dafab06b930735c94f go1.24.3.plan9-amd64.tar.gz +d1e4ac15095da1611659261c2228c2058756cf87d61d9fad262f76755ef26849 go1.24.3.plan9-arm.tar.gz +e644220a6ced3c07a7acc1364193cb709a97737dd8b6792a07a8ec6d9996713e go1.24.3.solaris-amd64.tar.gz +0d7e7dc0a31ba0cdd487415709d03b02fc9490ef111e8dfd22788a6d63316f37 go1.24.3.windows-386.msi +c27c463a61ab849266baa0c17a6c5c4256a574ab642f609ba25c96ec965dc184 go1.24.3.windows-386.zip +d5b7637e7e138be877d96a4501709d480e050d86a8f402bc950e72112b5aedc5 go1.24.3.windows-amd64.msi +be9787cb08998b1860fe3513e48a5fe5b96302d358a321b58e651184fa9638b3 go1.24.3.windows-amd64.zip +7efde2e5e8468e9caf2c7fc94f4da78a726a5031a1ed63acff7899527cdddff6 go1.24.3.windows-arm64.msi +eec9fa736056b54dd88ecb669db2bfad39b0c48f6f9080f036dfa1ca42dc4bb5 go1.24.3.windows-arm64.zip # version:golangci 2.0.2 # https://github.com/golangci/golangci-lint/releases/ From 57e985ecabf567f9a752e1e3ed56533f63787d0e Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 16 May 2025 10:20:36 +0200 Subject: [PATCH 369/940] cmd/utils: remove deprecated LES flags (#31838) They were not widely used in users setups. --- cmd/geth/main.go | 6 ------ cmd/utils/flags.go | 23 ----------------------- cmd/utils/flags_legacy.go | 37 ------------------------------------- 3 files changed, 66 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index bdff96e369..733c9cf230 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -91,13 +91,7 @@ var ( utils.LogNoHistoryFlag, utils.LogExportCheckpointsFlag, utils.StateHistoryFlag, - utils.LightServeFlag, // deprecated - utils.LightIngressFlag, // deprecated - utils.LightEgressFlag, // deprecated - utils.LightMaxPeersFlag, // deprecated - utils.LightNoPruneFlag, // deprecated utils.LightKDFFlag, - utils.LightNoSyncServeFlag, // deprecated utils.EthRequiredBlocksFlag, utils.LegacyWhitelistFlag, // deprecated utils.CacheFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a100ee1548..169f5ed49e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1245,28 +1245,6 @@ func setIPC(ctx *cli.Context, cfg *node.Config) { } } -// setLes shows the deprecation warnings for LES flags. -func setLes(ctx *cli.Context, cfg *ethconfig.Config) { - if ctx.IsSet(LightServeFlag.Name) { - log.Warn("The light server has been deprecated, please remove this flag", "flag", LightServeFlag.Name) - } - if ctx.IsSet(LightIngressFlag.Name) { - log.Warn("The light server has been deprecated, please remove this flag", "flag", LightIngressFlag.Name) - } - if ctx.IsSet(LightEgressFlag.Name) { - log.Warn("The light server has been deprecated, please remove this flag", "flag", LightEgressFlag.Name) - } - if ctx.IsSet(LightMaxPeersFlag.Name) { - log.Warn("The light server has been deprecated, please remove this flag", "flag", LightMaxPeersFlag.Name) - } - if ctx.IsSet(LightNoPruneFlag.Name) { - log.Warn("The light server has been deprecated, please remove this flag", "flag", LightNoPruneFlag.Name) - } - if ctx.IsSet(LightNoSyncServeFlag.Name) { - log.Warn("The light server has been deprecated, please remove this flag", "flag", LightNoSyncServeFlag.Name) - } -} - // MakeDatabaseHandles raises out the number of allowed file handles per process // for Geth and returns half of the allowance to assign to the database. func MakeDatabaseHandles(max int) int { @@ -1582,7 +1560,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { setBlobPool(ctx, &cfg.BlobPool) setMiner(ctx, &cfg.Miner) setRequiredBlocks(ctx, cfg) - setLes(ctx, cfg) // Cap the cache allowance and tune the garbage collector mem, err := gopsutil.VirtualMemory() diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go index ff63dd5685..dc41a75d11 100644 --- a/cmd/utils/flags_legacy.go +++ b/cmd/utils/flags_legacy.go @@ -39,12 +39,6 @@ var DeprecatedFlags = []cli.Flag{ CacheTrieRejournalFlag, LegacyDiscoveryV5Flag, TxLookupLimitFlag, - LightServeFlag, - LightIngressFlag, - LightEgressFlag, - LightMaxPeersFlag, - LightNoPruneFlag, - LightNoSyncServeFlag, LogBacktraceAtFlag, LogDebugFlag, MinerNewPayloadTimeoutFlag, @@ -88,37 +82,6 @@ var ( Value: ethconfig.Defaults.TransactionHistory, Category: flags.DeprecatedCategory, } - // Light server and client settings, Deprecated November 2023 - LightServeFlag = &cli.IntFlag{ - Name: "light.serve", - Usage: "Maximum percentage of time allowed for serving LES requests (deprecated)", - Category: flags.DeprecatedCategory, - } - LightIngressFlag = &cli.IntFlag{ - Name: "light.ingress", - Usage: "Incoming bandwidth limit for serving light clients (deprecated)", - Category: flags.DeprecatedCategory, - } - LightEgressFlag = &cli.IntFlag{ - Name: "light.egress", - Usage: "Outgoing bandwidth limit for serving light clients (deprecated)", - Category: flags.DeprecatedCategory, - } - LightMaxPeersFlag = &cli.IntFlag{ - Name: "light.maxpeers", - Usage: "Maximum number of light clients to serve, or light servers to attach to (deprecated)", - Category: flags.DeprecatedCategory, - } - LightNoPruneFlag = &cli.BoolFlag{ - Name: "light.nopruning", - Usage: "Disable ancient light chain data pruning (deprecated)", - Category: flags.DeprecatedCategory, - } - LightNoSyncServeFlag = &cli.BoolFlag{ - Name: "light.nosyncserve", - Usage: "Enables serving light clients before syncing (deprecated)", - Category: flags.DeprecatedCategory, - } // Deprecated November 2023 LogBacktraceAtFlag = &cli.StringFlag{ Name: "log.backtrace", From 892a661ee2e7bcafcfd4eb981abf0ba697d57a5c Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 16 May 2025 18:29:38 +0800 Subject: [PATCH 370/940] core, triedb/pathdb: final integration (snapshot integration pt 5) (#30661) In this pull request, snapshot generation in pathdb has been ported from the legacy state snapshot implementation. Additionally, when running in path mode, legacy state snapshot data is now managed by the pathdb based snapshot logic. Note: Existing snapshot data will be re-generated, regardless of whether it was previously fully constructed. --- core/blockchain.go | 62 +- core/blockchain_repair_test.go | 34 +- core/blockchain_sethead_test.go | 2 +- core/blockchain_snapshot_test.go | 22 +- core/state/database.go | 25 +- core/state/snapshot/generate_test.go | 4 +- core/state/statedb_test.go | 3 +- eth/handler.go | 3 +- eth/protocols/snap/handler.go | 44 +- eth/protocols/snap/sync_test.go | 2 +- tests/block_test_util.go | 6 +- trie/database_test.go | 6 +- triedb/database.go | 20 + triedb/pathdb/buffer.go | 10 +- triedb/pathdb/context.go | 246 ++++++++ triedb/pathdb/database.go | 138 ++++- triedb/pathdb/database_test.go | 3 +- triedb/pathdb/disklayer.go | 205 ++++++- triedb/pathdb/errors.go | 9 + triedb/pathdb/flush.go | 68 +++ triedb/pathdb/generate.go | 856 +++++++++++++++++++++++++++ triedb/pathdb/generate_test.go | 766 ++++++++++++++++++++++++ triedb/pathdb/iterator.go | 18 +- triedb/pathdb/iterator_binary.go | 36 +- triedb/pathdb/iterator_fast.go | 25 +- triedb/pathdb/iterator_test.go | 215 +++---- triedb/pathdb/journal.go | 59 +- triedb/pathdb/metrics.go | 51 +- triedb/pathdb/states.go | 9 +- 29 files changed, 2700 insertions(+), 247 deletions(-) create mode 100644 triedb/pathdb/context.go create mode 100644 triedb/pathdb/generate.go create mode 100644 triedb/pathdb/generate_test.go diff --git a/core/blockchain.go b/core/blockchain.go index 320b90dcbe..f93cddfe44 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -183,8 +183,13 @@ func (c *CacheConfig) triedbConfig(isVerkle bool) *triedb.Config { } if c.StateScheme == rawdb.PathScheme { config.PathDB = &pathdb.Config{ - StateHistory: c.StateHistory, - CleanCacheSize: c.TrieCleanLimit * 1024 * 1024, + StateHistory: c.StateHistory, + TrieCleanSize: c.TrieCleanLimit * 1024 * 1024, + StateCleanSize: c.SnapshotLimit * 1024 * 1024, + + // TODO(rjl493456442): The write buffer represents the memory limit used + // for flushing both trie data and state data to disk. The config name + // should be updated to eliminate the confusion. WriteBufferSize: c.TrieDirtyLimit * 1024 * 1024, } } @@ -380,11 +385,14 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis // Do nothing here until the state syncer picks it up. log.Info("Genesis state is missing, wait state sync") } else { - // Head state is missing, before the state recovery, find out the - // disk layer point of snapshot(if it's enabled). Make sure the - // rewound point is lower than disk layer. + // Head state is missing, before the state recovery, find out the disk + // layer point of snapshot(if it's enabled). Make sure the rewound point + // is lower than disk layer. + // + // Note it's unnecessary in path mode which always keep trie data and + // state data consistent. var diskRoot common.Hash - if bc.cacheConfig.SnapshotLimit > 0 { + if bc.cacheConfig.SnapshotLimit > 0 && bc.cacheConfig.StateScheme == rawdb.HashScheme { diskRoot = rawdb.ReadSnapshotRoot(bc.db) } if diskRoot != (common.Hash{}) { @@ -457,7 +465,32 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis bc.logger.OnGenesisBlock(bc.genesisBlock, alloc) } } + bc.setupSnapshot() + // Rewind the chain in case of an incompatible config upgrade. + if compatErr != nil { + log.Warn("Rewinding chain to upgrade configuration", "err", compatErr) + if compatErr.RewindToTime > 0 { + bc.SetHeadWithTimestamp(compatErr.RewindToTime) + } else { + bc.SetHead(compatErr.RewindToBlock) + } + rawdb.WriteChainConfig(db, genesisHash, chainConfig) + } + + // Start tx indexer if it's enabled. + if txLookupLimit != nil { + bc.txIndexer = newTxIndexer(*txLookupLimit, bc) + } + return bc, nil +} + +func (bc *BlockChain) setupSnapshot() { + // Short circuit if the chain is established with path scheme, as the + // state snapshot has been integrated into path database natively. + if bc.cacheConfig.StateScheme == rawdb.PathScheme { + return + } // Load any existing snapshot, regenerating it if loading failed if bc.cacheConfig.SnapshotLimit > 0 { // If the chain was rewound past the snapshot persistent layer (causing @@ -465,7 +498,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis // in recovery mode and in that case, don't invalidate the snapshot on a // head mismatch. var recover bool - head := bc.CurrentBlock() if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer >= head.Number.Uint64() { log.Warn("Enabling snapshot recovery", "chainhead", head.Number, "diskbase", *layer) @@ -482,22 +514,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis // Re-initialize the state database with snapshot bc.statedb = state.NewDatabase(bc.triedb, bc.snaps) } - - // Rewind the chain in case of an incompatible config upgrade. - if compatErr != nil { - log.Warn("Rewinding chain to upgrade configuration", "err", compatErr) - if compatErr.RewindToTime > 0 { - bc.SetHeadWithTimestamp(compatErr.RewindToTime) - } else { - bc.SetHead(compatErr.RewindToBlock) - } - rawdb.WriteChainConfig(db, genesisHash, chainConfig) - } - // Start tx indexer if it's enabled. - if txLookupLimit != nil { - bc.txIndexer = newTxIndexer(*txLookupLimit, bc) - } - return bc, nil } // empty returns an indicator whether the blockchain is empty. diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index 6c52d057ad..edc8854892 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -1791,7 +1791,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s } ) defer engine.Close() - if snapshots { + if snapshots && scheme == rawdb.HashScheme { config.SnapshotLimit = 256 config.SnapshotWait = true } @@ -1820,7 +1820,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s if err := chain.triedb.Commit(canonblocks[tt.commitBlock-1].Root(), false); err != nil { t.Fatalf("Failed to flush trie state: %v", err) } - if snapshots { + if snapshots && scheme == rawdb.HashScheme { if err := chain.snaps.Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil { t.Fatalf("Failed to flatten snapshots: %v", err) } @@ -1952,8 +1952,10 @@ func testIssue23496(t *testing.T, scheme string) { if _, err := chain.InsertChain(blocks[1:2]); err != nil { t.Fatalf("Failed to import canonical chain start: %v", err) } - if err := chain.snaps.Cap(blocks[1].Root(), 0); err != nil { - t.Fatalf("Failed to flatten snapshots: %v", err) + if scheme == rawdb.HashScheme { + if err := chain.snaps.Cap(blocks[1].Root(), 0); err != nil { + t.Fatalf("Failed to flatten snapshots: %v", err) + } } // Insert block B3 and commit the state into disk @@ -1997,15 +1999,23 @@ func testIssue23496(t *testing.T, scheme string) { } expHead := uint64(1) if scheme == rawdb.PathScheme { - expHead = uint64(2) + // The pathdb database makes sure that snapshot and trie are consistent, + // so only the last block is reverted in case of a crash. + expHead = uint64(3) } if head := chain.CurrentBlock(); head.Number.Uint64() != expHead { t.Errorf("Head block mismatch: have %d, want %d", head.Number, expHead) } - - // Reinsert B2-B4 - if _, err := chain.InsertChain(blocks[1:]); err != nil { - t.Fatalf("Failed to import canonical chain tail: %v", err) + if scheme == rawdb.PathScheme { + // Reinsert B4 + if _, err := chain.InsertChain(blocks[3:]); err != nil { + t.Fatalf("Failed to import canonical chain tail: %v", err) + } + } else { + // Reinsert B2-B4 + if _, err := chain.InsertChain(blocks[1:]); err != nil { + t.Fatalf("Failed to import canonical chain tail: %v", err) + } } if head := chain.CurrentHeader(); head.Number.Uint64() != uint64(4) { t.Errorf("Head header mismatch: have %d, want %d", head.Number, 4) @@ -2016,7 +2026,9 @@ func testIssue23496(t *testing.T, scheme string) { if head := chain.CurrentBlock(); head.Number.Uint64() != uint64(4) { t.Errorf("Head block mismatch: have %d, want %d", head.Number, uint64(4)) } - if layer := chain.Snapshots().Snapshot(blocks[2].Root()); layer == nil { - t.Error("Failed to regenerate the snapshot of known state") + if scheme == rawdb.HashScheme { + if layer := chain.Snapshots().Snapshot(blocks[2].Root()); layer == nil { + t.Error("Failed to regenerate the snapshot of known state") + } } } diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index 424854b2bf..51e2a5275f 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -2023,7 +2023,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme } if tt.commitBlock > 0 { chain.triedb.Commit(canonblocks[tt.commitBlock-1].Root(), false) - if snapshots { + if snapshots && scheme == rawdb.HashScheme { if err := chain.snaps.Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil { t.Fatalf("Failed to flatten snapshots: %v", err) } diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 1a6fe38af6..23640fe843 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -105,7 +105,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo if basic.commitBlock > 0 && basic.commitBlock == point { chain.TrieDB().Commit(blocks[point-1].Root(), false) } - if basic.snapshotBlock > 0 && basic.snapshotBlock == point { + if basic.snapshotBlock > 0 && basic.snapshotBlock == point && basic.scheme == rawdb.HashScheme { // Flushing the entire snap tree into the disk, the // relevant (a) snapshot root and (b) snapshot generator // will be persisted atomically. @@ -149,13 +149,17 @@ func (basic *snapshotTestBasic) verify(t *testing.T, chain *BlockChain, blocks [ block := chain.GetBlockByNumber(basic.expSnapshotBottom) if block == nil { t.Errorf("The corresponding block[%d] of snapshot disk layer is missing", basic.expSnapshotBottom) - } else if !bytes.Equal(chain.snaps.DiskRoot().Bytes(), block.Root().Bytes()) { - t.Errorf("The snapshot disk layer root is incorrect, want %x, get %x", block.Root(), chain.snaps.DiskRoot()) + } else if basic.scheme == rawdb.HashScheme { + if !bytes.Equal(chain.snaps.DiskRoot().Bytes(), block.Root().Bytes()) { + t.Errorf("The snapshot disk layer root is incorrect, want %x, get %x", block.Root(), chain.snaps.DiskRoot()) + } } // Check the snapshot, ensure it's integrated - if err := chain.snaps.Verify(block.Root()); err != nil { - t.Errorf("The disk layer is not integrated %v", err) + if basic.scheme == rawdb.HashScheme { + if err := chain.snaps.Verify(block.Root()); err != nil { + t.Errorf("The disk layer is not integrated %v", err) + } } } @@ -565,12 +569,14 @@ func TestHighCommitCrashWithNewSnapshot(t *testing.T) { // // Expected head header : C8 // Expected head fast block: C8 - // Expected head block : G - // Expected snapshot disk : C4 + // Expected head block : G (Hash mode), C6 (Hash mode) + // Expected snapshot disk : C4 (Hash mode) for _, scheme := range []string{rawdb.HashScheme, rawdb.PathScheme} { expHead := uint64(0) if scheme == rawdb.PathScheme { - expHead = uint64(4) + // The pathdb database makes sure that snapshot and trie are consistent, + // so only the last two blocks are reverted in case of a crash. + expHead = uint64(6) } test := &crashSnapshotTest{ snapshotTestBasic{ diff --git a/core/state/database.go b/core/state/database.go index cef59cccfb..aec841f59b 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -175,26 +175,27 @@ func NewDatabaseForTesting() *CachingDB { func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) { var readers []StateReader - // 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 { - // If standalone state snapshot is available (hash scheme), - // then construct the legacy snap reader. + // Configure the state reader using the standalone snapshot in hash mode. + // This reader offers improved performance but is optional and only + // partially useful if the snapshot is not fully generated. + if db.TrieDB().Scheme() == rawdb.HashScheme && db.snap != nil { snap := db.snap.Snapshot(stateRoot) if snap != nil { readers = append(readers, newFlatReader(snap)) } - } else { - // If standalone state snapshot is not available, try to construct - // the state reader with database. + } + // Configure the state reader using the path database in path mode. + // This reader offers improved performance but is optional and only + // partially useful if the snapshot data in path database is not + // fully generated. + if db.TrieDB().Scheme() == rawdb.PathScheme { reader, err := db.triedb.StateReader(stateRoot) if err == nil { - readers = append(readers, newFlatReader(reader)) // state reader is optional + readers = append(readers, newFlatReader(reader)) } } - // Set up the trie reader, which is expected to always be available - // as the gatekeeper unless the state is corrupted. + // Configure the trie reader, which is expected to be available as the + // gatekeeper unless the state is corrupted. tr, err := newTrieReader(stateRoot, db.triedb, db.pointCache) if err != nil { return nil, err diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go index 3de7735ef8..3f83cb1a00 100644 --- a/core/state/snapshot/generate_test.go +++ b/core/state/snapshot/generate_test.go @@ -166,7 +166,9 @@ func newHelper(scheme string) *testHelper { diskdb := rawdb.NewMemoryDatabase() config := &triedb.Config{} if scheme == rawdb.PathScheme { - config.PathDB = &pathdb.Config{} // disable caching + config.PathDB = &pathdb.Config{ + SnapshotNoBuild: true, + } // disable caching } else { config.HashDB = &hashdb.Config{} // disable caching } diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index e740c64faa..709b5ed510 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -979,7 +979,8 @@ func testMissingTrieNodes(t *testing.T, scheme string) { ) if scheme == rawdb.PathScheme { tdb = triedb.NewDatabase(memDb, &triedb.Config{PathDB: &pathdb.Config{ - CleanCacheSize: 0, + TrieCleanSize: 0, + StateCleanSize: 0, WriteBufferSize: 0, }}) // disable caching } else { diff --git a/eth/handler.go b/eth/handler.go index 8283d7d02f..f563b47138 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" + "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" @@ -183,7 +184,7 @@ func newHandler(config *handlerConfig) (*handler, error) { } } // If snap sync is requested but snapshots are disabled, fail loudly - if h.snapSync.Load() && config.Chain.Snapshots() == nil { + if h.snapSync.Load() && (config.Chain.Snapshots() == nil && config.Chain.TrieDB().Scheme() == rawdb.HashScheme) { return nil, errors.New("snap sync not supported with snapshots disabled") } // Construct the downloader (long sync) diff --git a/eth/protocols/snap/handler.go b/eth/protocols/snap/handler.go index 924aff7ac9..3249720f90 100644 --- a/eth/protocols/snap/handler.go +++ b/eth/protocols/snap/handler.go @@ -23,6 +23,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/snapshot" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" @@ -31,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/ethereum/go-ethereum/triedb/database" ) const ( @@ -279,7 +282,16 @@ func ServiceGetAccountRangeQuery(chain *core.BlockChain, req *GetAccountRangePac if err != nil { return nil, nil } - it, err := chain.Snapshots().AccountIterator(req.Root, req.Origin) + // Temporary solution: using the snapshot interface for both cases. + // This can be removed once the hash scheme is deprecated. + var it snapshot.AccountIterator + if chain.TrieDB().Scheme() == rawdb.HashScheme { + // The snapshot is assumed to be available in hash mode if + // the SNAP protocol is enabled. + it, err = chain.Snapshots().AccountIterator(req.Root, req.Origin) + } else { + it, err = chain.TrieDB().AccountIterator(req.Root, req.Origin) + } if err != nil { return nil, nil } @@ -359,7 +371,19 @@ func ServiceGetStorageRangesQuery(chain *core.BlockChain, req *GetStorageRangesP limit, req.Limit = common.BytesToHash(req.Limit), nil } // Retrieve the requested state and bail out if non existent - it, err := chain.Snapshots().StorageIterator(req.Root, account, origin) + var ( + err error + it snapshot.StorageIterator + ) + // Temporary solution: using the snapshot interface for both cases. + // This can be removed once the hash scheme is deprecated. + if chain.TrieDB().Scheme() == rawdb.HashScheme { + // The snapshot is assumed to be available in hash mode if + // the SNAP protocol is enabled. + it, err = chain.Snapshots().StorageIterator(req.Root, account, origin) + } else { + it, err = chain.TrieDB().StorageIterator(req.Root, account, origin) + } if err != nil { return nil, nil } @@ -479,8 +503,15 @@ func ServiceGetTrieNodesQuery(chain *core.BlockChain, req *GetTrieNodesPacket, s // We don't have the requested state available, bail out return nil, nil } - // The 'snap' might be nil, in which case we cannot serve storage slots. - snap := chain.Snapshots().Snapshot(req.Root) + // The 'reader' might be nil, in which case we cannot serve storage slots + // via snapshot. + var reader database.StateReader + if chain.Snapshots() != nil { + reader = chain.Snapshots().Snapshot(req.Root) + } + if reader == nil { + reader, _ = triedb.StateReader(req.Root) + } // Retrieve trie nodes until the packet size limit is reached var ( nodes [][]byte @@ -505,8 +536,9 @@ func ServiceGetTrieNodesQuery(chain *core.BlockChain, req *GetTrieNodesPacket, s default: var stRoot common.Hash + // Storage slots requested, open the storage trie and retrieve from there - if snap == nil { + if reader == nil { // We don't have the requested state snapshotted yet (or it is stale), // but can look up the account via the trie instead. account, err := accTrie.GetAccountByHash(common.BytesToHash(pathset[0])) @@ -516,7 +548,7 @@ func ServiceGetTrieNodesQuery(chain *core.BlockChain, req *GetTrieNodesPacket, s } stRoot = account.Root } else { - account, err := snap.Account(common.BytesToHash(pathset[0])) + account, err := reader.Account(common.BytesToHash(pathset[0])) loads++ // always account database reads, even for failures if err != nil || account == nil { break diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go index d318077d99..d599e7ecc3 100644 --- a/eth/protocols/snap/sync_test.go +++ b/eth/protocols/snap/sync_test.go @@ -1962,5 +1962,5 @@ func newDbConfig(scheme string) *triedb.Config { if scheme == rawdb.HashScheme { return &triedb.Config{} } - return &triedb.Config{PathDB: pathdb.Defaults} + return &triedb.Config{PathDB: &pathdb.Config{SnapshotNoBuild: true}} } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 77bf945e40..f029fa7f41 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -187,8 +187,10 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *t } // Cross-check the snapshot-to-hash against the trie hash if snapshotter { - if err := chain.Snapshots().Verify(chain.CurrentBlock().Root); err != nil { - return err + if chain.Snapshots() != nil { + if err := chain.Snapshots().Verify(chain.CurrentBlock().Root); err != nil { + return err + } } } return t.validateImportedHeaders(chain, validBlocks) diff --git a/trie/database_test.go b/trie/database_test.go index 729d9f699b..535f0d61b2 100644 --- a/trie/database_test.go +++ b/trie/database_test.go @@ -25,7 +25,7 @@ import ( "github.com/ethereum/go-ethereum/triedb/database" ) -// testReader implements database.Reader interface, providing function to +// testReader implements database.NodeReader interface, providing function to // access trie nodes. type testReader struct { db ethdb.Database @@ -33,7 +33,7 @@ type testReader struct { nodes []*trienode.MergedNodeSet // sorted from new to old } -// Node implements database.Reader interface, retrieving trie node with +// Node implements database.NodeReader interface, retrieving trie node with // all available cached layers. func (r *testReader) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) { // Check the node presence with the cached layer, from latest to oldest. @@ -54,7 +54,7 @@ func (r *testReader) Node(owner common.Hash, path []byte, hash common.Hash) ([]b return rawdb.ReadTrieNode(r.db, owner, path, hash, r.scheme), nil } -// testDb implements database.Database interface, using for testing purpose. +// testDb implements database.NodeDatabase interface, using for testing purpose. type testDb struct { disk ethdb.Database root common.Hash diff --git a/triedb/database.go b/triedb/database.go index f8ccc5ad33..18e24cd176 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -312,6 +312,26 @@ func (db *Database) Journal(root common.Hash) error { return pdb.Journal(root) } +// AccountIterator creates a new account iterator for the specified root hash and +// seeks to a starting account hash. +func (db *Database) AccountIterator(root common.Hash, seek common.Hash) (pathdb.AccountIterator, error) { + pdb, ok := db.backend.(*pathdb.Database) + if !ok { + return nil, errors.New("not supported") + } + return pdb.AccountIterator(root, seek) +} + +// StorageIterator creates a new storage iterator for the specified root hash and +// account. The iterator will be move to the specific start position. +func (db *Database) StorageIterator(root common.Hash, account common.Hash, seek common.Hash) (pathdb.StorageIterator, error) { + pdb, ok := db.backend.(*pathdb.Database) + if !ok { + return nil, errors.New("not supported") + } + return pdb.StorageIterator(root, account, seek) +} + // IsVerkle returns the indicator if the database is holding a verkle tree. func (db *Database) IsVerkle() bool { return db.config.IsVerkle diff --git a/triedb/pathdb/buffer.go b/triedb/pathdb/buffer.go index c4e081b973..e639a43835 100644 --- a/triedb/pathdb/buffer.go +++ b/triedb/pathdb/buffer.go @@ -124,7 +124,7 @@ func (b *buffer) size() uint64 { // 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 *buffer) flush(db ethdb.KeyValueStore, freezer ethdb.AncientWriter, nodesCache *fastcache.Cache, id uint64) error { +func (b *buffer) flush(root common.Hash, db ethdb.KeyValueStore, freezer ethdb.AncientWriter, progress []byte, nodesCache, statesCache *fastcache.Cache, id uint64) error { // Ensure the target state id is aligned with the internal counter. head := rawdb.ReadPersistentStateID(db) if head+b.layers != id { @@ -133,7 +133,7 @@ func (b *buffer) flush(db ethdb.KeyValueStore, freezer ethdb.AncientWriter, node // Terminate the state snapshot generation if it's active var ( start = time.Now() - batch = db.NewBatchWithSize(b.nodes.dbsize() * 11 / 10) // extra 10% for potential pebble internal stuff + batch = db.NewBatchWithSize((b.nodes.dbsize() + b.states.dbsize()) * 11 / 10) // extra 10% for potential pebble internal stuff ) // Explicitly sync the state freezer to ensure all written data is persisted to disk // before updating the key-value store. @@ -146,7 +146,9 @@ func (b *buffer) flush(db ethdb.KeyValueStore, freezer ethdb.AncientWriter, node } } nodes := b.nodes.write(batch, nodesCache) + accounts, slots := b.states.write(batch, progress, statesCache) rawdb.WritePersistentStateID(batch, id) + rawdb.WriteSnapshotRoot(batch, root) // Flush all mutations in a single batch size := batch.ValueSize() @@ -155,8 +157,10 @@ func (b *buffer) flush(db ethdb.KeyValueStore, freezer ethdb.AncientWriter, node } commitBytesMeter.Mark(int64(size)) commitNodesMeter.Mark(int64(nodes)) + commitAccountsMeter.Mark(int64(accounts)) + commitStoragesMeter.Mark(int64(slots)) commitTimeTimer.UpdateSince(start) b.reset() - log.Debug("Persisted buffer content", "nodes", nodes, "bytes", common.StorageSize(size), "elapsed", common.PrettyDuration(time.Since(start))) + log.Debug("Persisted buffer content", "nodes", nodes, "accounts", accounts, "slots", slots, "bytes", common.StorageSize(size), "elapsed", common.PrettyDuration(time.Since(start))) return nil } diff --git a/triedb/pathdb/context.go b/triedb/pathdb/context.go new file mode 100644 index 0000000000..a5704de81a --- /dev/null +++ b/triedb/pathdb/context.go @@ -0,0 +1,246 @@ +// 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 ( + "bytes" + "encoding/binary" + "errors" + "math" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ethereum/go-ethereum/log" +) + +const ( + snapAccount = "account" // Identifier of account snapshot generation + snapStorage = "storage" // Identifier of storage snapshot generation +) + +// generatorStats is a collection of statistics gathered by the snapshot generator +// for logging purposes. This data structure is used throughout the entire +// lifecycle of the snapshot generation process and is shared across multiple +// generation cycles. +type generatorStats struct { + origin uint64 // Origin prefix where generation started + start time.Time // Timestamp when generation started + accounts uint64 // Number of accounts indexed(generated or recovered) + slots uint64 // Number of storage slots indexed(generated or recovered) + dangling uint64 // Number of dangling storage slots + storage common.StorageSize // Total account and storage slot size(generation or recovery) +} + +// 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{} + if root != (common.Hash{}) { + ctx = append(ctx, []interface{}{"root", root}...) + } + // Figure out whether we're after or within an account + switch len(marker) { + case common.HashLength: + ctx = append(ctx, []interface{}{"at", common.BytesToHash(marker)}...) + case 2 * common.HashLength: + ctx = append(ctx, []interface{}{ + "in", common.BytesToHash(marker[:common.HashLength]), + "at", common.BytesToHash(marker[common.HashLength:]), + }...) + } + // Add the usual measurements + ctx = append(ctx, []interface{}{ + "accounts", gs.accounts, + "slots", gs.slots, + "storage", gs.storage, + "dangling", gs.dangling, + "elapsed", common.PrettyDuration(time.Since(gs.start)), + }...) + // Calculate the estimated indexing time based on current stats + if len(marker) > 0 { + if done := binary.BigEndian.Uint64(marker[:8]) - gs.origin; done > 0 { + left := math.MaxUint64 - binary.BigEndian.Uint64(marker[:8]) + + speed := done/uint64(time.Since(gs.start)/time.Millisecond+1) + 1 // +1s to avoid division by zero + ctx = append(ctx, []interface{}{ + "eta", common.PrettyDuration(time.Duration(left/speed) * time.Millisecond), + }...) + } + } + log.Info(msg, ctx...) +} + +// generatorContext holds several global fields that are used throughout the +// current generation cycle. It must be recreated if the generation cycle is +// restarted. +type generatorContext struct { + root common.Hash // State root of the generation target + account *holdableIterator // Iterator of account snapshot data + storage *holdableIterator // Iterator of storage snapshot data + db ethdb.KeyValueStore // Key-value store containing the snapshot data + batch ethdb.Batch // Database batch for writing data atomically + logged time.Time // The timestamp when last generation progress was displayed +} + +// newGeneratorContext initializes the context for generation. +func newGeneratorContext(root common.Hash, marker []byte, db ethdb.KeyValueStore) *generatorContext { + ctx := &generatorContext{ + root: root, + db: db, + batch: db.NewBatch(), + logged: time.Now(), + } + accMarker, storageMarker := splitMarker(marker) + ctx.openIterator(snapAccount, accMarker) + ctx.openIterator(snapStorage, storageMarker) + return ctx +} + +// openIterator constructs global account and storage snapshot iterators +// at the interrupted position. These iterators should be reopened from time +// to time to avoid blocking leveldb compaction for a long time. +func (ctx *generatorContext) openIterator(kind string, start []byte) { + if kind == snapAccount { + iter := ctx.db.NewIterator(rawdb.SnapshotAccountPrefix, start) + ctx.account = newHoldableIterator(rawdb.NewKeyLengthIterator(iter, 1+common.HashLength)) + return + } + iter := ctx.db.NewIterator(rawdb.SnapshotStoragePrefix, start) + ctx.storage = newHoldableIterator(rawdb.NewKeyLengthIterator(iter, 1+2*common.HashLength)) +} + +// reopenIterator releases the specified snapshot iterator and re-open it +// in the next position. It's aimed for not blocking leveldb compaction. +func (ctx *generatorContext) reopenIterator(kind string) { + // Shift iterator one more step, so that we can reopen + // the iterator at the right position. + var iter = ctx.account + if kind == snapStorage { + iter = ctx.storage + } + hasNext := iter.Next() + if !hasNext { + // Iterator exhausted, release forever and create an already exhausted virtual iterator + iter.Release() + if kind == snapAccount { + ctx.account = newHoldableIterator(memorydb.New().NewIterator(nil, nil)) + return + } + ctx.storage = newHoldableIterator(memorydb.New().NewIterator(nil, nil)) + return + } + next := iter.Key() + iter.Release() + ctx.openIterator(kind, next[1:]) +} + +// close releases all the held resources. +func (ctx *generatorContext) close() { + ctx.account.Release() + ctx.storage.Release() +} + +// iterator returns the corresponding iterator specified by the kind. +func (ctx *generatorContext) iterator(kind string) *holdableIterator { + if kind == snapAccount { + return ctx.account + } + return ctx.storage +} + +// removeStorageBefore deletes all storage entries which are located before +// the specified account. When the iterator touches the storage entry which +// is located in or outside the given account, it stops and holds the current +// iterated element locally. +func (ctx *generatorContext) removeStorageBefore(account common.Hash) uint64 { + var ( + count uint64 + start = time.Now() + iter = ctx.storage + ) + for iter.Next() { + key := iter.Key() + if bytes.Compare(key[1:1+common.HashLength], account.Bytes()) >= 0 { + iter.Hold() + break + } + count++ + ctx.batch.Delete(key) + if ctx.batch.ValueSize() > ethdb.IdealBatchSize { + ctx.batch.Write() + ctx.batch.Reset() + } + } + storageCleanCounter.Inc(time.Since(start).Nanoseconds()) + return count +} + +// removeStorageAt deletes all storage entries which are located in the specified +// account. When the iterator touches the storage entry which is outside the given +// account, it stops and holds the current iterated element locally. An error will +// be returned if the initial position of iterator is not in the given account. +func (ctx *generatorContext) removeStorageAt(account common.Hash) error { + var ( + count int64 + start = time.Now() + iter = ctx.storage + ) + for iter.Next() { + key := iter.Key() + cmp := bytes.Compare(key[1:1+common.HashLength], account.Bytes()) + if cmp < 0 { + return errors.New("invalid iterator position") + } + if cmp > 0 { + iter.Hold() + break + } + count++ + ctx.batch.Delete(key) + if ctx.batch.ValueSize() > ethdb.IdealBatchSize { + ctx.batch.Write() + ctx.batch.Reset() + } + } + wipedStorageMeter.Mark(count) + storageCleanCounter.Inc(time.Since(start).Nanoseconds()) + return nil +} + +// removeRemainingStorage deletes all storage entries which are located after +// the current iterator position. +func (ctx *generatorContext) removeRemainingStorage() uint64 { + var ( + count uint64 + start = time.Now() + iter = ctx.storage + ) + for iter.Next() { + count++ + ctx.batch.Delete(iter.Key()) + if ctx.batch.ValueSize() > ethdb.IdealBatchSize { + ctx.batch.Write() + ctx.batch.Reset() + } + } + danglingStorageMeter.Mark(int64(count)) + storageCleanCounter.Inc(time.Since(start).Nanoseconds()) + return count +} diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index 155e28543d..c206460315 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -17,6 +17,7 @@ package pathdb import ( + "encoding/binary" "errors" "fmt" "io" @@ -35,8 +36,11 @@ import ( ) const ( - // defaultCleanSize is the default memory allowance of clean cache. - defaultCleanSize = 16 * 1024 * 1024 + // defaultTrieCleanSize is the default memory allowance of clean trie cache. + defaultTrieCleanSize = 16 * 1024 * 1024 + + // defaultStateCleanSize is the default memory allowance of clean state cache. + defaultStateCleanSize = 16 * 1024 * 1024 // maxBufferSize is the maximum memory allowance of node buffer. // Too large buffer will cause the system to pause for a long @@ -111,9 +115,11 @@ type layer interface { // Config contains the settings for database. type Config struct { StateHistory uint64 // Number of recent blocks to maintain state history for - CleanCacheSize int // Maximum memory allowance (in bytes) for caching clean nodes + TrieCleanSize int // Maximum memory allowance (in bytes) for caching clean trie nodes + StateCleanSize int // Maximum memory allowance (in bytes) for caching clean state data WriteBufferSize int // Maximum memory allowance (in bytes) for write buffer - ReadOnly bool // Flag whether the database is opened in read only mode. + ReadOnly bool // Flag whether the database is opened in read only mode + SnapshotNoBuild bool // Flag Whether the background generation is allowed } // sanitize checks the provided user configurations and changes anything that's @@ -133,7 +139,11 @@ func (c *Config) fields() []interface{} { if c.ReadOnly { list = append(list, "readonly", true) } - list = append(list, "cache", common.StorageSize(c.CleanCacheSize)) + if c.SnapshotNoBuild { + list = append(list, "snapshot", false) + } + list = append(list, "triecache", common.StorageSize(c.TrieCleanSize)) + list = append(list, "statecache", common.StorageSize(c.StateCleanSize)) list = append(list, "buffer", common.StorageSize(c.WriteBufferSize)) list = append(list, "history", c.StateHistory) return list @@ -142,7 +152,8 @@ func (c *Config) fields() []interface{} { // Defaults contains default settings for Ethereum mainnet. var Defaults = &Config{ StateHistory: params.FullImmutabilityThreshold, - CleanCacheSize: defaultCleanSize, + TrieCleanSize: defaultTrieCleanSize, + StateCleanSize: defaultStateCleanSize, WriteBufferSize: defaultBufferSize, } @@ -240,6 +251,13 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { log.Crit("Failed to disable database", "err", err) // impossible to happen } } + // Resolving the state snapshot generation progress from the database is + // mandatory. This ensures that uncovered flat states are not accessed, + // even if background generation is not allowed. If permitted, the generation + // might be scheduled. + if err := db.setStateGenerator(); err != nil { + log.Crit("Failed to setup the generator", "err", err) + } fields := config.fields() if db.isVerkle { fields = append(fields, "verkle", true) @@ -297,6 +315,60 @@ func (db *Database) repairHistory() error { return nil } +// setStateGenerator loads the state generation progress marker and potentially +// resume the state generation if it's permitted. +func (db *Database) setStateGenerator() error { + // Load the state snapshot generation progress marker to prevent access + // to uncovered states. + generator, root, err := loadGenerator(db.diskdb, db.hasher) + if err != nil { + return err + } + if generator == nil { + // Initialize an empty generator to rebuild the state snapshot from scratch + generator = &journalGenerator{ + Marker: []byte{}, + } + } + // Short circuit if the whole state snapshot has already been fully generated. + // The generator will be left as nil in disk layer for representing the whole + // state snapshot is available for accessing. + if generator.Done { + return nil + } + var origin uint64 + if len(generator.Marker) >= 8 { + origin = binary.BigEndian.Uint64(generator.Marker) + } + stats := &generatorStats{ + origin: origin, + start: time.Now(), + accounts: generator.Accounts, + slots: generator.Slots, + storage: common.StorageSize(generator.Storage), + } + dl := db.tree.bottom() + + // Disable the background snapshot building in these circumstances: + // - the database is opened in read only mode + // - the snapshot build is explicitly disabled + // - the database is opened in verkle tree mode + noBuild := db.readOnly || db.config.SnapshotNoBuild || db.isVerkle + + // Construct the generator and link it to the disk layer, ensuring that the + // generation progress is resolved to prevent accessing uncovered states + // regardless of whether background state snapshot generation is allowed. + dl.setGenerator(newGenerator(db.diskdb, noBuild, generator.Marker, stats)) + + // Short circuit if the background generation is not permitted + if noBuild || db.waitSync { + return nil + } + stats.log("Starting snapshot generation", root, generator.Marker) + dl.generator.run(root) + return nil +} + // Update adds a new layer into the tree, if that can be linked to an existing // old parent. It is disallowed to insert a disk layer (the origin of all). Apart // from that this function will flatten the extra diff layers at bottom into disk @@ -359,8 +431,13 @@ func (db *Database) Disable() error { } db.waitSync = true - // Mark the disk layer as stale to prevent access to persistent state. - db.tree.bottom().markStale() + // Terminate the state generator if it's active and mark the disk layer + // as stale to prevent access to persistent state. + disk := db.tree.bottom() + if disk.generator != nil { + disk.generator.stop() + } + disk.markStale() // Write the initial sync flag to persist it across restarts. rawdb.WriteSnapSyncStatusFlag(db.diskdb, rawdb.StateSyncRunning) @@ -390,6 +467,7 @@ func (db *Database) Enable(root common.Hash) error { // reset the persistent state id back to zero. batch := db.diskdb.NewBatch() rawdb.DeleteTrieJournal(batch) + rawdb.DeleteSnapshotRoot(batch) rawdb.WritePersistentStateID(batch, 0) if err := batch.Write(); err != nil { return err @@ -403,13 +481,13 @@ func (db *Database) Enable(root common.Hash) error { return err } } - // Re-construct a new disk layer backed by persistent state - // with **empty clean cache and node buffer**. - db.tree.reset(newDiskLayer(root, 0, db, nil, newBuffer(db.config.WriteBufferSize, nil, nil, 0))) - // Re-enable the database as the final step. db.waitSync = false rawdb.WriteSnapSyncStatusFlag(db.diskdb, rawdb.StateSyncFinished) + + // Re-construct a new disk layer backed by persistent state + // and schedule the state snapshot generation if it's permitted. + db.tree.reset(generateSnapshot(db, root, db.isVerkle || db.config.SnapshotNoBuild)) log.Info("Rebuilt trie database", "root", root) return nil } @@ -514,8 +592,12 @@ func (db *Database) Close() error { // following mutations. db.readOnly = true - // Release the memory held by clean cache. - db.tree.bottom().resetCache() + // Terminate the background generation if it's active + disk := db.tree.bottom() + if disk.generator != nil { + disk.generator.stop() + } + disk.resetCache() // release the memory held by clean cache // Close the attached state history freezer. if db.freezer == nil { @@ -580,14 +662,42 @@ func (db *Database) HistoryRange() (uint64, uint64, error) { return historyRange(db.freezer) } +// waitGeneration waits until the background generation is finished. It assumes +// that the generation is permitted; otherwise, it will block indefinitely. +func (db *Database) waitGeneration() { + gen := db.tree.bottom().generator + if gen == nil || gen.completed() { + return + } + <-gen.done +} + // AccountIterator creates a new account iterator for the specified root hash and // seeks to a starting account hash. func (db *Database) AccountIterator(root common.Hash, seek common.Hash) (AccountIterator, error) { + db.lock.RLock() + wait := db.waitSync + db.lock.RUnlock() + if wait { + return nil, errDatabaseWaitSync + } + if gen := db.tree.bottom().generator; gen != nil && !gen.completed() { + return nil, errNotConstructed + } return newFastAccountIterator(db, root, seek) } // StorageIterator creates a new storage iterator for the specified root hash and // account. The iterator will be moved to the specific start position. func (db *Database) StorageIterator(root common.Hash, account common.Hash, seek common.Hash) (StorageIterator, error) { + db.lock.RLock() + wait := db.waitSync + db.lock.RUnlock() + if wait { + return nil, errDatabaseWaitSync + } + if gen := db.tree.bottom().generator; gen != nil && !gen.completed() { + return nil, errNotConstructed + } return newFastStorageIterator(db, root, account, seek) } diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index c85d7832ee..3b780c975d 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -126,7 +126,8 @@ func newTester(t *testing.T, historyLimit uint64, isVerkle bool, layers int) *te disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) db = New(disk, &Config{ StateHistory: historyLimit, - CleanCacheSize: 256 * 1024, + TrieCleanSize: 256 * 1024, + StateCleanSize: 256 * 1024, WriteBufferSize: 256 * 1024, }, isVerkle) diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index b8869888d9..bee4cd1e8a 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -17,9 +17,10 @@ package pathdb import ( - "errors" + "bytes" "fmt" "sync" + "time" "github.com/VictoriaMetrics/fastcache" "github.com/ethereum/go-ethereum/common" @@ -30,28 +31,42 @@ import ( // diskLayer is a low level persistent layer built on top of a key-value store. type diskLayer struct { - root common.Hash // Immutable, root hash to which this layer was made for - id uint64 // Immutable, corresponding state id - db *Database // Path-based trie database + root common.Hash // Immutable, root hash to which this layer was made for + id uint64 // Immutable, corresponding state id + db *Database // Path-based trie database + + // These two caches must be maintained separately, because the key + // for the root node of the storage trie (accountHash) is identical + // to the key for the account data. nodes *fastcache.Cache // GC friendly memory cache of clean nodes - buffer *buffer // Dirty buffer to aggregate writes of nodes and states - stale bool // Signals that the layer became stale (state progressed) - lock sync.RWMutex // Lock used to protect stale flag + states *fastcache.Cache // GC friendly memory cache of clean states + + buffer *buffer // Dirty buffer to aggregate writes of nodes and states + stale bool // Signals that the layer became stale (state progressed) + lock sync.RWMutex // Lock used to protect stale flag and genMarker + + // The generator is set if the state snapshot was not fully completed, + // regardless of whether the background generation is running or not. + generator *generator } // newDiskLayer creates a new disk layer based on the passing arguments. -func newDiskLayer(root common.Hash, id uint64, db *Database, nodes *fastcache.Cache, buffer *buffer) *diskLayer { - // Initialize a clean cache if the memory allowance is not zero - // or reuse the provided cache if it is not nil (inherited from +func newDiskLayer(root common.Hash, id uint64, db *Database, nodes *fastcache.Cache, states *fastcache.Cache, buffer *buffer) *diskLayer { + // Initialize the clean caches if the memory allowance is not zero + // or reuse the provided caches if they are not nil (inherited from // the original disk layer). - if nodes == nil && db.config.CleanCacheSize != 0 { - nodes = fastcache.New(db.config.CleanCacheSize) + if nodes == nil && db.config.TrieCleanSize != 0 { + nodes = fastcache.New(db.config.TrieCleanSize) + } + if states == nil && db.config.StateCleanSize != 0 { + states = fastcache.New(db.config.StateCleanSize) } return &diskLayer{ root: root, id: id, db: db, nodes: nodes, + states: states, buffer: buffer, } } @@ -72,6 +87,13 @@ func (dl *diskLayer) parentLayer() layer { return nil } +// setGenerator links the given generator to disk layer, representing the +// associated state snapshot is not fully completed yet and the generation +// is potentially running in the background. +func (dl *diskLayer) setGenerator(generator *generator) { + dl.generator = generator +} + // isStale return whether this layer has become stale (was flattened across) or if // it's still live. func (dl *diskLayer) isStale() bool { @@ -168,8 +190,41 @@ func (dl *diskLayer) account(hash common.Hash, depth int) ([]byte, error) { } dirtyStateMissMeter.Mark(1) - // TODO(rjl493456442) support persistent state retrieval - return nil, errors.New("not supported") + // If the layer is being generated, ensure the requested account has + // already been covered by the generator. + marker := dl.genMarker() + if marker != nil && bytes.Compare(hash.Bytes(), marker) > 0 { + return nil, errNotCoveredYet + } + // Try to retrieve the account from the memory cache + if dl.states != nil { + if blob, found := dl.states.HasGet(nil, hash[:]); found { + cleanStateHitMeter.Mark(1) + cleanStateReadMeter.Mark(int64(len(blob))) + + if len(blob) == 0 { + stateAccountInexMeter.Mark(1) + } else { + stateAccountExistMeter.Mark(1) + } + return blob, nil + } + cleanStateMissMeter.Mark(1) + } + // Try to retrieve the account from the disk. + blob = rawdb.ReadAccountSnapshot(dl.db.diskdb, hash) + if dl.states != nil { + dl.states.Set(hash[:], blob) + cleanStateWriteMeter.Mark(int64(len(blob))) + } + if len(blob) == 0 { + stateAccountInexMeter.Mark(1) + stateAccountInexDiskMeter.Mark(1) + } else { + stateAccountExistMeter.Mark(1) + stateAccountExistDiskMeter.Mark(1) + } + return blob, nil } // storage directly retrieves the storage data associated with a particular hash, @@ -203,8 +258,42 @@ func (dl *diskLayer) storage(accountHash, storageHash common.Hash, depth int) ([ } dirtyStateMissMeter.Mark(1) - // TODO(rjl493456442) support persistent state retrieval - return nil, errors.New("not supported") + // If the layer is being generated, ensure the requested storage slot + // has already been covered by the generator. + key := append(accountHash[:], storageHash[:]...) + marker := dl.genMarker() + if marker != nil && bytes.Compare(key, marker) > 0 { + return nil, errNotCoveredYet + } + // Try to retrieve the storage slot from the memory cache + if dl.states != nil { + if blob, found := dl.states.HasGet(nil, key); found { + cleanStateHitMeter.Mark(1) + cleanStateReadMeter.Mark(int64(len(blob))) + + if len(blob) == 0 { + stateStorageInexMeter.Mark(1) + } else { + stateStorageExistMeter.Mark(1) + } + return blob, nil + } + cleanStateMissMeter.Mark(1) + } + // Try to retrieve the account from the disk + blob := rawdb.ReadStorageSnapshot(dl.db.diskdb, accountHash, storageHash) + if dl.states != nil { + dl.states.Set(key, blob) + cleanStateWriteMeter.Mark(int64(len(blob))) + } + if len(blob) == 0 { + stateStorageInexMeter.Mark(1) + stateStorageInexDiskMeter.Mark(1) + } else { + stateStorageExistMeter.Mark(1) + stateStorageExistDiskMeter.Mark(1) + } + return blob, nil } // update implements the layer interface, returning a new diff layer on top @@ -267,13 +356,39 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { // Merge the trie nodes and flat states of the bottom-most diff layer into the // buffer as the combined layer. combined := dl.buffer.commit(bottom.nodes, bottom.states.stateSet) + + // Terminate the background state snapshot generation before mutating the + // persistent state. if combined.full() || force { - if err := combined.flush(dl.db.diskdb, dl.db.freezer, dl.nodes, bottom.stateID()); err != nil { + // Terminate the background state snapshot generator before flushing + // to prevent data race. + var progress []byte + if dl.generator != nil { + dl.generator.stop() + progress = dl.generator.progressMarker() + + // If the snapshot has been fully generated, unset the generator + if progress == nil { + dl.setGenerator(nil) + } else { + log.Info("Paused snapshot generation") + } + } + // Flush the content in combined buffer. Any state data after the progress + // marker will be ignored, as the generator will pick it up later. + if err := combined.flush(bottom.root, dl.db.diskdb, dl.db.freezer, progress, dl.nodes, dl.states, bottom.stateID()); err != nil { return nil, err } + // Resume the background generation if it's not completed yet + if progress != nil { + dl.generator.run(bottom.root) + } + } + // Link the generator if snapshot is not yet completed + ndl := newDiskLayer(bottom.root, bottom.stateID(), dl.db, dl.nodes, dl.states, combined) + if dl.generator != nil { + ndl.setGenerator(dl.generator) } - ndl := newDiskLayer(bottom.root, bottom.stateID(), dl.db, dl.nodes, combined) - // To remove outdated history objects from the end, we set the 'tail' parameter // to 'oldest-1' due to the offset between the freezer index and the history ID. if overflow { @@ -288,6 +403,7 @@ 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) (*diskLayer, error) { + start := time.Now() if h.meta.root != dl.rootHash() { return nil, errUnexpectedHistory } @@ -321,15 +437,40 @@ func (dl *diskLayer) revert(h *history) (*diskLayer, error) { if err != nil { return nil, err } - } else { - batch := dl.db.diskdb.NewBatch() - writeNodes(batch, nodes, dl.nodes) - rawdb.WritePersistentStateID(batch, dl.id-1) - if err := batch.Write(); err != nil { - log.Crit("Failed to write states", "err", err) + ndl := newDiskLayer(h.meta.parent, dl.id-1, dl.db, dl.nodes, dl.states, dl.buffer) + + // Link the generator if it exists + if dl.generator != nil { + ndl.setGenerator(dl.generator) } + log.Debug("Reverted data in write buffer", "oldroot", h.meta.root, "newroot", h.meta.parent, "elapsed", common.PrettyDuration(time.Since(start))) + return ndl, nil } - return newDiskLayer(h.meta.parent, dl.id-1, dl.db, dl.nodes, dl.buffer), nil + // Terminate the generation before writing any data into database + var progress []byte + if dl.generator != nil { + dl.generator.stop() + progress = dl.generator.progressMarker() + } + batch := dl.db.diskdb.NewBatch() + writeNodes(batch, nodes, dl.nodes) + + // Provide the original values of modified accounts and storages for revert + writeStates(batch, progress, accounts, storages, dl.states) + rawdb.WritePersistentStateID(batch, dl.id-1) + rawdb.WriteSnapshotRoot(batch, h.meta.parent) + if err := batch.Write(); err != nil { + log.Crit("Failed to write states", "err", err) + } + // Link the generator and resume generation if the snapshot is not yet + // fully completed. + ndl := newDiskLayer(h.meta.parent, dl.id-1, dl.db, dl.nodes, dl.states, dl.buffer) + if dl.generator != nil && !dl.generator.completed() { + ndl.generator = dl.generator + ndl.generator.run(h.meta.parent) + } + log.Debug("Reverted data in persistent state", "oldroot", h.meta.root, "newroot", h.meta.parent, "elapsed", common.PrettyDuration(time.Since(start))) + return ndl, nil } // size returns the approximate size of cached nodes in the disk layer. @@ -355,4 +496,16 @@ func (dl *diskLayer) resetCache() { if dl.nodes != nil { dl.nodes.Reset() } + if dl.states != nil { + dl.states.Reset() + } +} + +// genMarker returns the current state snapshot generation progress marker. If +// the state snapshot has already been fully generated, nil is returned. +func (dl *diskLayer) genMarker() []byte { + if dl.generator == nil { + return nil + } + return dl.generator.progressMarker() } diff --git a/triedb/pathdb/errors.go b/triedb/pathdb/errors.go index 49e9c3ca64..5d953b2183 100644 --- a/triedb/pathdb/errors.go +++ b/triedb/pathdb/errors.go @@ -39,4 +39,13 @@ var ( // errStateUnrecoverable is returned if state is required to be reverted to // a destination without associated state history available. errStateUnrecoverable = errors.New("state is unrecoverable") + + // errNotCoveredYet is returned from data accessors if the underlying snapshot + // is being generated currently and the requested data item is not yet in the + // range of accounts covered. + errNotCoveredYet = errors.New("not covered yet") + + // errNotConstructed is returned if the callers want to iterate the snapshot + // while the generation is not finished yet. + errNotConstructed = errors.New("snapshot is not constructed") ) diff --git a/triedb/pathdb/flush.go b/triedb/pathdb/flush.go index baa0bfb292..6563dbccff 100644 --- a/triedb/pathdb/flush.go +++ b/triedb/pathdb/flush.go @@ -17,6 +17,8 @@ package pathdb import ( + "bytes" + "github.com/VictoriaMetrics/fastcache" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" @@ -63,3 +65,69 @@ func writeNodes(batch ethdb.Batch, nodes map[common.Hash]map[string]*trienode.No } return total } + +// writeStates flushes state mutations into the provided database batch as a whole. +// +// This function assumes the background generator is already terminated and states +// before the supplied marker has been correctly generated. +// +// TODO(rjl493456442) do we really need this generation marker? The state updates +// after the marker can also be written and will be fixed by generator later if +// it's outdated. +func writeStates(batch ethdb.Batch, genMarker []byte, accountData map[common.Hash][]byte, storageData map[common.Hash]map[common.Hash][]byte, clean *fastcache.Cache) (int, int) { + var ( + accounts int + slots int + ) + for addrHash, blob := range accountData { + // Skip any account not yet covered by the snapshot. The account + // at the generation marker position (addrHash == genMarker[:common.HashLength]) + // should still be updated, as it would be skipped in the next + // generation cycle. + if genMarker != nil && bytes.Compare(addrHash[:], genMarker) > 0 { + continue + } + accounts += 1 + if len(blob) == 0 { + rawdb.DeleteAccountSnapshot(batch, addrHash) + if clean != nil { + clean.Set(addrHash[:], nil) + } + } else { + rawdb.WriteAccountSnapshot(batch, addrHash, blob) + if clean != nil { + clean.Set(addrHash[:], blob) + } + } + } + for addrHash, storages := range storageData { + // Skip any account not covered yet by the snapshot + if genMarker != nil && bytes.Compare(addrHash[:], genMarker) > 0 { + continue + } + midAccount := genMarker != nil && bytes.Equal(addrHash[:], genMarker[:common.HashLength]) + + for storageHash, blob := range storages { + // Skip any storage slot not yet covered by the snapshot. The storage slot + // at the generation marker position (addrHash == genMarker[:common.HashLength] + // and storageHash == genMarker[common.HashLength:]) should still be updated, + // as it would be skipped in the next generation cycle. + if midAccount && bytes.Compare(storageHash[:], genMarker[common.HashLength:]) > 0 { + continue + } + slots += 1 + if len(blob) == 0 { + rawdb.DeleteStorageSnapshot(batch, addrHash, storageHash) + if clean != nil { + clean.Set(append(addrHash[:], storageHash[:]...), nil) + } + } else { + rawdb.WriteStorageSnapshot(batch, addrHash, storageHash, blob) + if clean != nil { + clean.Set(append(addrHash[:], storageHash[:]...), blob) + } + } + } + } + return accounts, slots +} diff --git a/triedb/pathdb/generate.go b/triedb/pathdb/generate.go new file mode 100644 index 0000000000..f4f98c9d19 --- /dev/null +++ b/triedb/pathdb/generate.go @@ -0,0 +1,856 @@ +// Copyright 2019 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" + "errors" + "fmt" + "sync" + "time" + + "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/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/triedb/database" +) + +var ( + // accountCheckRange is the upper limit of the number of accounts involved in + // each range check. This is a value estimated based on experience. If this + // range is too large, the failure rate of range proof will increase. Otherwise, + // if the range is too small, the efficiency of the state recovery will decrease. + accountCheckRange = 128 + + // storageCheckRange is the upper limit of the number of storage slots involved + // in each range check. This is a value estimated based on experience. If this + // range is too large, the failure rate of range proof will increase. Otherwise, + // if the range is too small, the efficiency of the state recovery will decrease. + storageCheckRange = 1024 + + // errMissingTrie is returned if the target trie is missing while the generation + // is running. In this case the generation is aborted and wait the new signal. + errMissingTrie = errors.New("missing trie") +) + +// diskReader is a wrapper of key-value store and implements database.NodeReader, +// providing a function for accessing persistent trie nodes in the disk +type diskReader struct{ db ethdb.KeyValueStore } + +// 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. +func (r *diskReader) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) { + if owner == (common.Hash{}) { + return rawdb.ReadAccountTrieNode(r.db, path), nil + } + return rawdb.ReadStorageTrieNode(r.db, owner, path), nil +} + +// diskStore is a wrapper of key-value store and implements database.NodeDatabase. +// It's meant to be used for generating state snapshot from the trie data. +type diskStore struct { + db ethdb.KeyValueStore +} + +// NodeReader returns a node reader associated with the specific state. +// An error will be returned if the specified state is not available. +func (s *diskStore) NodeReader(stateRoot common.Hash) (database.NodeReader, error) { + root := types.EmptyRootHash + if blob := rawdb.ReadAccountTrieNode(s.db, nil); len(blob) > 0 { + root = crypto.Keccak256Hash(blob) + } + if root != stateRoot { + return nil, fmt.Errorf("state %x is not available", stateRoot) + } + return &diskReader{s.db}, nil +} + +// Generator is the struct for initial state snapshot generation. It is not thread-safe; +// the caller must manage concurrency issues themselves. +type generator struct { + noBuild bool // Flag indicating whether snapshot generation is permitted + running bool // Flag indicating whether the background generation is running + + db ethdb.KeyValueStore // Key-value store containing the snapshot data + stats *generatorStats // Generation statistics used throughout the entire life cycle + abort chan chan struct{} // Notification channel to abort generating the snapshot in this layer + done chan struct{} // Notification channel when generation is done + + progress []byte // Progress marker of the state generation, nil means it's completed + lock sync.RWMutex // Lock which protects the progress, only generator can mutate the progress +} + +// newGenerator constructs the state snapshot generator. +// +// noBuild will be true if the background snapshot generation is not allowed, +// usually used in read-only mode. +// +// progress indicates the starting position for resuming snapshot generation. +// It must be provided even if generation is not allowed; otherwise, uncovered +// states may be exposed for serving. +func newGenerator(db ethdb.KeyValueStore, noBuild bool, progress []byte, stats *generatorStats) *generator { + if stats == nil { + stats = &generatorStats{start: time.Now()} + } + return &generator{ + noBuild: noBuild, + progress: progress, + db: db, + stats: stats, + abort: make(chan chan struct{}), + done: make(chan struct{}), + } +} + +// run starts the state snapshot generation in the background. +func (g *generator) run(root common.Hash) { + if g.noBuild { + log.Warn("Snapshot generation is not permitted") + return + } + if g.running { + g.stop() + log.Warn("Paused the leftover generation cycle") + } + g.running = true + go g.generate(newGeneratorContext(root, g.progress, g.db)) +} + +// stop terminates the background generation if it's actively running. +// The Recent generation progress being made will be saved before returning. +func (g *generator) stop() { + if !g.running { + log.Debug("Snapshot generation is not running") + return + } + ch := make(chan struct{}) + g.abort <- ch + <-ch + g.running = false +} + +// completed returns the flag indicating if the whole generation is done. +func (g *generator) completed() bool { + progress := g.progressMarker() + return progress == nil +} + +// progressMarker returns the current generation progress marker. It may slightly +// lag behind the actual generation position, as the progress field is only updated +// when checkAndFlush is called. The only effect is that some generated states +// may be refused for serving. +func (g *generator) progressMarker() []byte { + g.lock.RLock() + defer g.lock.RUnlock() + + return g.progress +} + +// splitMarker is an internal helper which splits the generation progress marker +// into two parts. +func splitMarker(marker []byte) ([]byte, []byte) { + var accMarker []byte + if len(marker) > 0 { + accMarker = marker[:common.HashLength] + } + return accMarker, marker +} + +// generateSnapshot regenerates a brand-new snapshot based on an existing state +// database and head block asynchronously. The snapshot is returned immediately +// and generation is continued in the background until done. +func generateSnapshot(triedb *Database, root common.Hash, noBuild bool) *diskLayer { + // Create a new disk layer with an initialized state marker at zero + var ( + stats = &generatorStats{start: time.Now()} + genMarker = []byte{} // Initialized but empty! + ) + dl := newDiskLayer(root, 0, triedb, nil, nil, newBuffer(triedb.config.WriteBufferSize, nil, nil, 0)) + dl.setGenerator(newGenerator(triedb.diskdb, noBuild, genMarker, stats)) + + if !noBuild { + dl.generator.run(root) + log.Info("Started snapshot generation", "root", root) + } + return dl +} + +// journalProgress persists the generator stats into the database to resume later. +func journalProgress(db ethdb.KeyValueWriter, marker []byte, stats *generatorStats) { + // Write out the generator marker. Note it's a standalone disk layer generator + // which is not mixed with journal. It's ok if the generator is persisted while + // journal is not. + entry := journalGenerator{ + Done: marker == nil, + Marker: marker, + } + if stats != nil { + entry.Accounts = stats.accounts + entry.Slots = stats.slots + entry.Storage = uint64(stats.storage) + } + blob, err := rlp.EncodeToBytes(entry) + if err != nil { + panic(err) // Cannot happen, here to catch dev errors + } + var logstr string + switch { + case marker == nil: + logstr = "done" + case bytes.Equal(marker, []byte{}): + logstr = "empty" + case len(marker) == common.HashLength: + logstr = fmt.Sprintf("%#x", marker) + default: + logstr = fmt.Sprintf("%#x:%#x", marker[:common.HashLength], marker[common.HashLength:]) + } + log.Debug("Journalled generator progress", "progress", logstr) + rawdb.WriteSnapshotGenerator(db, blob) +} + +// proofResult contains the output of range proving which can be used +// for further processing regardless if it is successful or not. +type proofResult struct { + keys [][]byte // The key set of all elements being iterated, even proving is failed + vals [][]byte // The val set of all elements being iterated, even proving is failed + diskMore bool // Set when the database has extra snapshot states since last iteration + trieMore bool // Set when the trie has extra snapshot states(only meaningful for successful proving) + proofErr error // Indicator whether the given state range is valid or not + tr *trie.Trie // The trie, in case the trie was resolved by the prover (may be nil) +} + +// valid returns the indicator that range proof is successful or not. +func (result *proofResult) valid() bool { + return result.proofErr == nil +} + +// last returns the last verified element key regardless of whether the range proof is +// successful or not. Nil is returned if nothing involved in the proving. +func (result *proofResult) last() []byte { + var last []byte + if len(result.keys) > 0 { + last = result.keys[len(result.keys)-1] + } + return last +} + +// forEach iterates all the visited elements and applies the given callback on them. +// The iteration is aborted if the callback returns non-nil error. +func (result *proofResult) forEach(callback func(key []byte, val []byte) error) error { + for i := 0; i < len(result.keys); i++ { + key, val := result.keys[i], result.vals[i] + if err := callback(key, val); err != nil { + return err + } + } + return nil +} + +// proveRange proves the snapshot segment with particular prefix is "valid". +// The iteration start point will be assigned if the iterator is restored from +// the last interruption. Max will be assigned in order to limit the maximum +// amount of data involved in each iteration. +// +// The proof result will be returned if the range proving is finished, otherwise +// the error will be returned to abort the entire procedure. +func (g *generator) proveRange(ctx *generatorContext, trieId *trie.ID, prefix []byte, kind string, origin []byte, max int, valueConvertFn func([]byte) ([]byte, error)) (*proofResult, error) { + var ( + keys [][]byte + vals [][]byte + proof = rawdb.NewMemoryDatabase() + diskMore = false + iter = ctx.iterator(kind) + start = time.Now() + min = append(prefix, origin...) + ) + for iter.Next() { + // Ensure the iterated item is always equal or larger than the given origin. + key := iter.Key() + if bytes.Compare(key, min) < 0 { + return nil, errors.New("invalid iteration position") + } + // Ensure the iterated item still fall in the specified prefix. If + // not which means the items in the specified area are all visited. + // Move the iterator a step back since we iterate one extra element + // out. + if !bytes.Equal(key[:len(prefix)], prefix) { + iter.Hold() + break + } + // Break if we've reached the max size, and signal that we're not + // done yet. Move the iterator a step back since we iterate one + // extra element out. + if len(keys) == max { + iter.Hold() + diskMore = true + break + } + keys = append(keys, common.CopyBytes(key[len(prefix):])) + + if valueConvertFn == nil { + vals = append(vals, common.CopyBytes(iter.Value())) + } else { + val, err := valueConvertFn(iter.Value()) + if err != nil { + // Special case, the state data is corrupted (invalid slim-format account), + // don't abort the entire procedure directly. Instead, let the fallback + // generation to heal the invalid data. + // + // Here append the original value to ensure that the number of key and + // value are aligned. + vals = append(vals, common.CopyBytes(iter.Value())) + log.Error("Failed to convert account state data", "err", err) + } else { + vals = append(vals, val) + } + } + } + // Update metrics for database iteration and merkle proving + if kind == snapStorage { + storageSnapReadCounter.Inc(time.Since(start).Nanoseconds()) + } else { + accountSnapReadCounter.Inc(time.Since(start).Nanoseconds()) + } + defer func(start time.Time) { + if kind == snapStorage { + storageProveCounter.Inc(time.Since(start).Nanoseconds()) + } else { + accountProveCounter.Inc(time.Since(start).Nanoseconds()) + } + }(time.Now()) + + // The snap state is exhausted, pass the entire key/val set for verification + root := trieId.Root + if origin == nil && !diskMore { + stackTr := trie.NewStackTrie(nil) + for i, key := range keys { + if err := stackTr.Update(key, vals[i]); err != nil { + return nil, err + } + } + if gotRoot := stackTr.Hash(); gotRoot != root { + return &proofResult{ + keys: keys, + vals: vals, + proofErr: fmt.Errorf("wrong root: have %#x want %#x", gotRoot, root), + }, nil + } + return &proofResult{keys: keys, vals: vals}, nil + } + // Snap state is chunked, generate edge proofs for verification. + tr, err := trie.New(trieId, &diskStore{db: g.db}) + if err != nil { + log.Info("Trie missing, snapshotting paused", "state", ctx.root, "kind", kind, "root", trieId.Root) + return nil, errMissingTrie + } + // Generate the Merkle proofs for the first and last element + if origin == nil { + origin = common.Hash{}.Bytes() + } + if err := tr.Prove(origin, proof); err != nil { + log.Debug("Failed to prove range", "kind", kind, "origin", origin, "err", err) + return &proofResult{ + keys: keys, + vals: vals, + diskMore: diskMore, + proofErr: err, + tr: tr, + }, nil + } + if len(keys) > 0 { + if err := tr.Prove(keys[len(keys)-1], proof); err != nil { + log.Debug("Failed to prove range", "kind", kind, "last", keys[len(keys)-1], "err", err) + return &proofResult{ + keys: keys, + vals: vals, + diskMore: diskMore, + proofErr: err, + tr: tr, + }, nil + } + } + // Verify the snapshot segment with range prover, ensure that all flat states + // in this range correspond to merkle trie. + cont, err := trie.VerifyRangeProof(root, origin, keys, vals, proof) + return &proofResult{ + keys: keys, + vals: vals, + diskMore: diskMore, + trieMore: cont, + proofErr: err, + tr: tr}, + nil +} + +// onStateCallback is a function that is called by generateRange, when processing a range of +// accounts or storage slots. For each element, the callback is invoked. +// +// - If 'delete' is true, then this element (and potential slots) needs to be deleted from the snapshot. +// - If 'write' is true, then this element needs to be updated with the 'val'. +// - If 'write' is false, then this element is already correct, and needs no update. +// The 'val' is the canonical encoding of the value (not the slim format for accounts) +// +// However, for accounts, the storage trie of the account needs to be checked. Also, +// dangling storages(storage exists but the corresponding account is missing) need to +// be cleaned up. +type onStateCallback func(key []byte, val []byte, write bool, delete bool) error + +// generateRange generates the state segment with particular prefix. Generation can +// either verify the correctness of existing state through range-proof and skip +// generation, or iterate trie to regenerate state on demand. +func (g *generator) generateRange(ctx *generatorContext, trieId *trie.ID, prefix []byte, kind string, origin []byte, max int, onState onStateCallback, valueConvertFn func([]byte) ([]byte, error)) (bool, []byte, error) { + // Use range prover to check the validity of the flat state in the range + result, err := g.proveRange(ctx, trieId, prefix, kind, origin, max, valueConvertFn) + if err != nil { + return false, nil, err + } + last := result.last() + + // Construct contextual logger + logCtx := []interface{}{"kind", kind, "prefix", hexutil.Encode(prefix)} + if len(origin) > 0 { + logCtx = append(logCtx, "origin", hexutil.Encode(origin)) + } + logger := log.New(logCtx...) + + // The range prover says the range is correct, skip trie iteration + if result.valid() { + successfulRangeProofMeter.Mark(1) + logger.Trace("Proved state range", "last", hexutil.Encode(last)) + + // The verification is passed, process each state with the given + // callback function. If this state represents a contract, the + // corresponding storage check will be performed in the callback + if err := result.forEach(func(key []byte, val []byte) error { return onState(key, val, false, false) }); err != nil { + return false, nil, err + } + // Only abort the iteration when both database and trie are exhausted + return !result.diskMore && !result.trieMore, last, nil + } + logger.Trace("Detected outdated state range", "last", hexutil.Encode(last), "err", result.proofErr) + failedRangeProofMeter.Mark(1) + + // Special case, the entire trie is missing. In the original trie scheme, + // all the duplicated subtries will be filtered out (only one copy of data + // will be stored). While in the snapshot model, all the storage tries + // belong to different contracts will be kept even they are duplicated. + // Track it to a certain extent remove the noise data used for statistics. + if origin == nil && last == nil { + meter := missallAccountMeter + if kind == snapStorage { + meter = missallStorageMeter + } + meter.Mark(1) + } + // We use the snap data to build up a cache which can be used by the + // main account trie as a primary lookup when resolving hashes + var resolver trie.NodeResolver + if len(result.keys) > 0 { + tr := trie.NewEmpty(nil) + for i, key := range result.keys { + tr.Update(key, result.vals[i]) + } + _, nodes := tr.Commit(false) + hashSet := nodes.HashSet() + resolver = func(owner common.Hash, path []byte, hash common.Hash) []byte { + return hashSet[hash] + } + } + // Construct the trie for state iteration, reuse the trie + // if it's already opened with some nodes resolved. + tr := result.tr + if tr == nil { + tr, err = trie.New(trieId, &diskStore{db: g.db}) + if err != nil { + log.Info("Trie missing, snapshotting paused", "state", ctx.root, "kind", kind, "root", trieId.Root) + return false, nil, errMissingTrie + } + } + var ( + trieMore bool + kvkeys, kvvals = result.keys, result.vals + + // counters + count = 0 // number of states delivered by iterator + created = 0 // states created from the trie + updated = 0 // states updated from the trie + deleted = 0 // states not in trie, but were in snapshot + untouched = 0 // states already correct + + // timers + start = time.Now() + internal time.Duration + ) + nodeIt, err := tr.NodeIterator(origin) + if err != nil { + return false, nil, err + } + nodeIt.AddResolver(resolver) + iter := trie.NewIterator(nodeIt) + + for iter.Next() { + if last != nil && bytes.Compare(iter.Key, last) > 0 { + trieMore = true + break + } + count++ + write := true + created++ + for len(kvkeys) > 0 { + if cmp := bytes.Compare(kvkeys[0], iter.Key); cmp < 0 { + // delete the key + istart := time.Now() + if err := onState(kvkeys[0], nil, false, true); err != nil { + return false, nil, err + } + kvkeys = kvkeys[1:] + kvvals = kvvals[1:] + deleted++ + internal += time.Since(istart) + continue + } else if cmp == 0 { + // the snapshot key can be overwritten + created-- + if write = !bytes.Equal(kvvals[0], iter.Value); write { + updated++ + } else { + untouched++ + } + kvkeys = kvkeys[1:] + kvvals = kvvals[1:] + } + break + } + istart := time.Now() + if err := onState(iter.Key, iter.Value, write, false); err != nil { + return false, nil, err + } + internal += time.Since(istart) + } + if iter.Err != nil { + // Trie errors should never happen. Still, in case of a bug, expose the + // error here, as the outer code will presume errors are interrupts, not + // some deeper issues. + log.Error("State snapshotter failed to iterate trie", "err", iter.Err) + return false, nil, iter.Err + } + // Delete all stale snapshot states remaining + istart := time.Now() + for _, key := range kvkeys { + if err := onState(key, nil, false, true); err != nil { + return false, nil, err + } + deleted += 1 + } + internal += time.Since(istart) + + // Update metrics for counting trie iteration + if kind == snapStorage { + storageTrieReadCounter.Inc((time.Since(start) - internal).Nanoseconds()) + } else { + accountTrieReadCounter.Inc((time.Since(start) - internal).Nanoseconds()) + } + logger.Trace("Regenerated state range", "root", trieId.Root, "last", hexutil.Encode(last), + "count", count, "created", created, "updated", updated, "untouched", untouched, "deleted", deleted) + + // If there are either more trie items, or there are more snap items + // (in the next segment), then we need to keep working + return !trieMore && !result.diskMore, last, nil +} + +// checkAndFlush checks if an interruption signal is received or the +// batch size has exceeded the allowance. +func (g *generator) checkAndFlush(ctx *generatorContext, current []byte) error { + var abort chan struct{} + select { + case abort = <-g.abort: + default: + } + if ctx.batch.ValueSize() > ethdb.IdealBatchSize || abort != nil { + if bytes.Compare(current, g.progress) < 0 { + log.Error("Snapshot generator went backwards", "current", fmt.Sprintf("%x", current), "genMarker", fmt.Sprintf("%x", g.progress)) + } + // Persist the progress marker regardless of whether the batch is empty or not. + // It may happen that all the flat states in the database are correct, so the + // generator indeed makes progress even if there is nothing to commit. + journalProgress(ctx.batch, current, g.stats) + + // Flush out the database writes atomically + if err := ctx.batch.Write(); err != nil { + return err + } + ctx.batch.Reset() + + // Update the generation progress marker + g.lock.Lock() + g.progress = current + g.lock.Unlock() + + // Abort the generation if it's required + if abort != nil { + g.stats.log("Aborting snapshot generation", ctx.root, g.progress) + return newAbortErr(abort) // bubble up an error for interruption + } + // Don't hold the iterators too long, release them to let compactor works + ctx.reopenIterator(snapAccount) + ctx.reopenIterator(snapStorage) + } + if time.Since(ctx.logged) > 8*time.Second { + g.stats.log("Generating snapshot", ctx.root, g.progress) + ctx.logged = time.Now() + } + return nil +} + +// generateStorages generates the missing storage slots of the specific contract. +// It's supposed to restart the generation from the given origin position. +func (g *generator) generateStorages(ctx *generatorContext, account common.Hash, storageRoot common.Hash, storeMarker []byte) error { + onStorage := func(key []byte, val []byte, write bool, delete bool) error { + defer func(start time.Time) { + storageWriteCounter.Inc(time.Since(start).Nanoseconds()) + }(time.Now()) + + if delete { + rawdb.DeleteStorageSnapshot(ctx.batch, account, common.BytesToHash(key)) + wipedStorageMeter.Mark(1) + return nil + } + if write { + rawdb.WriteStorageSnapshot(ctx.batch, account, common.BytesToHash(key), val) + generatedStorageMeter.Mark(1) + } else { + recoveredStorageMeter.Mark(1) + } + g.stats.storage += common.StorageSize(1 + 2*common.HashLength + len(val)) + g.stats.slots++ + + // If we've exceeded our batch allowance or termination was requested, flush to disk + if err := g.checkAndFlush(ctx, append(account[:], key...)); err != nil { + return err + } + return nil + } + // Loop for re-generating the missing storage slots. + var origin = common.CopyBytes(storeMarker) + for { + id := trie.StorageTrieID(ctx.root, account, storageRoot) + exhausted, last, err := g.generateRange(ctx, id, append(rawdb.SnapshotStoragePrefix, account.Bytes()...), snapStorage, origin, storageCheckRange, onStorage, nil) + if err != nil { + return err // The procedure it aborted, either by external signal or internal error. + } + // Abort the procedure if the entire contract storage is generated + if exhausted { + break + } + if origin = increaseKey(last); origin == nil { + break // special case, the last is 0xffffffff...fff + } + } + return nil +} + +// generateAccounts generates the missing snapshot accounts as well as their +// storage slots in the main trie. It's supposed to restart the generation +// from the given origin position. +func (g *generator) generateAccounts(ctx *generatorContext, accMarker []byte) error { + onAccount := func(key []byte, val []byte, write bool, delete bool) error { + // Make sure to clear all dangling storages before this account + account := common.BytesToHash(key) + g.stats.dangling += ctx.removeStorageBefore(account) + + start := time.Now() + if delete { + rawdb.DeleteAccountSnapshot(ctx.batch, account) + wipedAccountMeter.Mark(1) + accountWriteCounter.Inc(time.Since(start).Nanoseconds()) + + ctx.removeStorageAt(account) + return nil + } + // Retrieve the current account and flatten it into the internal format + var acc types.StateAccount + if err := rlp.DecodeBytes(val, &acc); err != nil { + log.Crit("Invalid account encountered during snapshot creation", "err", err) + } + // If the account is not yet in-progress, write it out + if accMarker == nil || !bytes.Equal(account[:], accMarker) { + dataLen := len(val) // Approximate size, saves us a round of RLP-encoding + if !write { + if bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) { + dataLen -= 32 + } + if acc.Root == types.EmptyRootHash { + dataLen -= 32 + } + recoveredAccountMeter.Mark(1) + } else { + data := types.SlimAccountRLP(acc) + dataLen = len(data) + rawdb.WriteAccountSnapshot(ctx.batch, account, data) + generatedAccountMeter.Mark(1) + } + g.stats.storage += common.StorageSize(1 + common.HashLength + dataLen) + g.stats.accounts++ + } + // If the snap generation goes here after interrupted, genMarker may go backward + // when last genMarker is consisted of accountHash and storageHash + marker := account[:] + if accMarker != nil && bytes.Equal(marker, accMarker) && len(g.progress) > common.HashLength { + marker = g.progress + } + // If we've exceeded our batch allowance or termination was requested, flush to disk + if err := g.checkAndFlush(ctx, marker); err != nil { + return err + } + accountWriteCounter.Inc(time.Since(start).Nanoseconds()) // let's count flush time as well + + // If the iterated account is the contract, create a further loop to + // verify or regenerate the contract storage. + if acc.Root == types.EmptyRootHash { + ctx.removeStorageAt(account) + } else { + var storeMarker []byte + if accMarker != nil && bytes.Equal(account[:], accMarker) && len(g.progress) > common.HashLength { + storeMarker = g.progress[common.HashLength:] + } + if err := g.generateStorages(ctx, account, acc.Root, storeMarker); err != nil { + return err + } + } + // Some account processed, unmark the marker + accMarker = nil + return nil + } + origin := common.CopyBytes(accMarker) + for { + id := trie.StateTrieID(ctx.root) + exhausted, last, err := g.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. + } + origin = increaseKey(last) + + // Last step, cleanup the storages after the last account. + // All the left storages should be treated as dangling. + if origin == nil || exhausted { + g.stats.dangling += ctx.removeRemainingStorage() + break + } + } + return nil +} + +// generate is a background thread that iterates over the state and storage tries, +// constructing the state snapshot. All the arguments are purely for statistics +// gathering and logging, since the method surfs the blocks as they arrive, often +// being restarted. +func (g *generator) generate(ctx *generatorContext) { + g.stats.log("Resuming snapshot generation", ctx.root, g.progress) + defer ctx.close() + + // Persist the initial marker and state snapshot root if progress is none + if len(g.progress) == 0 { + batch := g.db.NewBatch() + rawdb.WriteSnapshotRoot(batch, ctx.root) + journalProgress(batch, g.progress, g.stats) + if err := batch.Write(); err != nil { + log.Crit("Failed to write initialized state marker", "err", err) + } + } + // Initialize the global generator context. The snapshot iterators are + // opened at the interrupted position because the assumption is held + // that all the snapshot data are generated correctly before the marker. + // Even if the snapshot data is updated during the interruption (before + // or at the marker), the assumption is still held. + // For the account or storage slot at the interruption, they will be + // processed twice by the generator(they are already processed in the + // last run) but it's fine. + var ( + accMarker, _ = splitMarker(g.progress) + abort chan struct{} + ) + if err := g.generateAccounts(ctx, accMarker); err != nil { + // Extract the received interruption signal if exists + var aerr *abortErr + if errors.As(err, &aerr) { + abort = aerr.abort + } + // Aborted by internal error, wait the signal + if abort == nil { + abort = <-g.abort + } + close(abort) + return + } + // Snapshot fully generated, set the marker to nil. + // Note even there is nothing to commit, persist the + // generator anyway to mark the snapshot is complete. + journalProgress(ctx.batch, nil, g.stats) + if err := ctx.batch.Write(); err != nil { + log.Error("Failed to flush batch", "err", err) + abort = <-g.abort + close(abort) + return + } + ctx.batch.Reset() + + log.Info("Generated snapshot", "accounts", g.stats.accounts, "slots", g.stats.slots, + "storage", g.stats.storage, "dangling", g.stats.dangling, "elapsed", common.PrettyDuration(time.Since(g.stats.start))) + + // Update the generation progress marker + g.lock.Lock() + g.progress = nil + g.lock.Unlock() + close(g.done) + + // Someone will be looking for us, wait it out + abort = <-g.abort + close(abort) +} + +// increaseKey increase the input key by one bit. Return nil if the entire +// addition operation overflows. +func increaseKey(key []byte) []byte { + for i := len(key) - 1; i >= 0; i-- { + key[i]++ + if key[i] != 0x0 { + return key + } + } + return nil +} + +// abortErr wraps an interruption signal received to represent the +// generation is aborted by external processes. +type abortErr struct { + abort chan struct{} +} + +func newAbortErr(abort chan struct{}) error { + return &abortErr{abort: abort} +} + +func (err *abortErr) Error() string { + return "aborted" +} diff --git a/triedb/pathdb/generate_test.go b/triedb/pathdb/generate_test.go new file mode 100644 index 0000000000..23efb0e3c5 --- /dev/null +++ b/triedb/pathdb/generate_test.go @@ -0,0 +1,766 @@ +// 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" + "testing" + "time" + + "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/internal/testrand" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/holiman/uint256" +) + +func hashData(input []byte) common.Hash { + return crypto.Keccak256Hash(input) +} + +type genTester struct { + diskdb ethdb.Database + db *Database + acctTrie *trie.Trie + nodes *trienode.MergedNodeSet + states *StateSetWithOrigin +} + +func newGenTester() *genTester { + disk := rawdb.NewMemoryDatabase() + config := *Defaults + config.SnapshotNoBuild = true // no background generation + db := New(disk, &config, false) + tr, _ := trie.New(trie.StateTrieID(types.EmptyRootHash), db) + return &genTester{ + diskdb: disk, + db: db, + acctTrie: tr, + nodes: trienode.NewMergedNodeSet(), + states: NewStateSetWithOrigin(nil, nil, nil, nil, false), + } +} + +func (t *genTester) addTrieAccount(acckey string, acc *types.StateAccount) { + var ( + addr = common.BytesToAddress([]byte(acckey)) + key = hashData([]byte(acckey)) + val, _ = rlp.EncodeToBytes(acc) + ) + t.acctTrie.MustUpdate(key.Bytes(), val) + + t.states.accountData[key] = val + t.states.accountOrigin[addr] = nil +} + +func (t *genTester) addSnapAccount(acckey string, acc *types.StateAccount) { + key := hashData([]byte(acckey)) + rawdb.WriteAccountSnapshot(t.diskdb, key, types.SlimAccountRLP(*acc)) +} + +func (t *genTester) addAccount(acckey string, acc *types.StateAccount) { + t.addTrieAccount(acckey, acc) + t.addSnapAccount(acckey, acc) +} + +func (t *genTester) addSnapStorage(accKey string, keys []string, vals []string) { + accHash := hashData([]byte(accKey)) + for i, key := range keys { + rawdb.WriteStorageSnapshot(t.diskdb, accHash, hashData([]byte(key)), []byte(vals[i])) + } +} + +func (t *genTester) makeStorageTrie(accKey string, keys []string, vals []string, commit bool) common.Hash { + var ( + owner = hashData([]byte(accKey)) + addr = common.BytesToAddress([]byte(accKey)) + id = trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash) + tr, _ = trie.New(id, t.db) + + storages = make(map[common.Hash][]byte) + storageOrigins = make(map[common.Hash][]byte) + ) + for i, k := range keys { + key := hashData([]byte(k)) + tr.MustUpdate(key.Bytes(), []byte(vals[i])) + storages[key] = []byte(vals[i]) + storageOrigins[key] = nil + } + if !commit { + return tr.Hash() + } + root, nodes := tr.Commit(false) + if nodes != nil { + t.nodes.Merge(nodes) + } + t.states.storageData[owner] = storages + t.states.storageOrigin[addr] = storageOrigins + return root +} + +func (t *genTester) Commit() common.Hash { + root, nodes := t.acctTrie.Commit(true) + if nodes != nil { + t.nodes.Merge(nodes) + } + t.db.Update(root, types.EmptyRootHash, 0, t.nodes, t.states) + t.db.Commit(root, false) + return root +} + +func (t *genTester) CommitAndGenerate() (common.Hash, *diskLayer) { + root := t.Commit() + dl := generateSnapshot(t.db, root, false) + return root, dl +} + +// Tests that snapshot generation from an empty database. +func TestGeneration(t *testing.T) { + helper := newGenTester() + stRoot := helper.makeStorageTrie("", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, false) + + helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + + helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + + root, dl := helper.CommitAndGenerate() + if have, want := root, common.HexToHash("0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd"); have != want { + t.Fatalf("have %#x want %#x", have, want) + } + select { + case <-dl.generator.done: + // Snapshot generation succeeded + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +// Tests that snapshot generation with existent flat state, where the flat state +// contains some errors: +// - the contract with empty storage root but has storage entries in the disk +// - the contract with non empty storage root but empty storage slots +// - the contract(non-empty storage) misses some storage slots +// - miss in the beginning +// - miss in the middle +// - miss in the end +// +// - the contract(non-empty storage) has wrong storage slots +// - wrong slots in the beginning +// - wrong slots in the middle +// - wrong slots in the end +// +// - the contract(non-empty storage) has extra storage slots +// - extra slots in the beginning +// - extra slots in the middle +// - extra slots in the end +func TestGenerateExistentStateWithWrongStorage(t *testing.T) { + helper := newGenTester() + + // Account one, empty storage trie root but non-empty flat states + helper.addAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + + // Account two, non-empty storage trie root but empty flat states + stRoot := helper.makeStorageTrie("acc-2", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + + // Miss slots + { + // Account three, non-empty root but misses slots in the beginning + helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-3", []string{"key-2", "key-3"}, []string{"val-2", "val-3"}) + + // Account four, non-empty root but misses slots in the middle + helper.makeStorageTrie("acc-4", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-4", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-4", []string{"key-1", "key-3"}, []string{"val-1", "val-3"}) + + // Account five, non-empty root but misses slots in the end + helper.makeStorageTrie("acc-5", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-5", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-5", []string{"key-1", "key-2"}, []string{"val-1", "val-2"}) + } + + // Wrong storage slots + { + // Account six, non-empty root but wrong slots in the beginning + helper.makeStorageTrie("acc-6", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-6", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-6", []string{"key-1", "key-2", "key-3"}, []string{"badval-1", "val-2", "val-3"}) + + // Account seven, non-empty root but wrong slots in the middle + helper.makeStorageTrie("acc-7", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-7", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-7", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "badval-2", "val-3"}) + + // Account eight, non-empty root but wrong slots in the end + helper.makeStorageTrie("acc-8", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-8", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-8", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "badval-3"}) + + // Account 9, non-empty root but rotated slots + helper.makeStorageTrie("acc-9", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-9", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-9", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-3", "val-2"}) + } + + // Extra storage slots + { + // Account 10, non-empty root but extra slots in the beginning + helper.makeStorageTrie("acc-10", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-10", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-10", []string{"key-0", "key-1", "key-2", "key-3"}, []string{"val-0", "val-1", "val-2", "val-3"}) + + // Account 11, non-empty root but extra slots in the middle + helper.makeStorageTrie("acc-11", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-11", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-11", []string{"key-1", "key-2", "key-2-1", "key-3"}, []string{"val-1", "val-2", "val-2-1", "val-3"}) + + // Account 12, non-empty root but extra slots in the end + helper.makeStorageTrie("acc-12", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-12", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapStorage("acc-12", []string{"key-1", "key-2", "key-3", "key-4"}, []string{"val-1", "val-2", "val-3", "val-4"}) + } + + root, dl := helper.CommitAndGenerate() + t.Logf("Root: %#x\n", root) // Root = 0x8746cce9fd9c658b2cfd639878ed6584b7a2b3e73bb40f607fcfa156002429a0 + + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +// Tests that snapshot generation with existent flat state, where the flat state +// contains some errors: +// - miss accounts +// - wrong accounts +// - extra accounts +func TestGenerateExistentStateWithWrongAccounts(t *testing.T) { + helper := newGenTester() + + // Trie accounts [acc-1, acc-2, acc-3, acc-4, acc-6] + helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.makeStorageTrie("acc-2", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.makeStorageTrie("acc-4", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + stRoot := helper.makeStorageTrie("acc-6", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + + // Missing accounts, only in the trie + { + helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Beginning + helper.addTrieAccount("acc-4", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Middle + helper.addTrieAccount("acc-6", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // End + } + + // Wrong accounts + { + helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: common.Hex2Bytes("0x1234")}) + + helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addSnapAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) + } + + // Extra accounts, only in the snap + { + helper.addSnapAccount("acc-0", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // before the beginning + helper.addSnapAccount("acc-5", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: common.Hex2Bytes("0x1234")}) // Middle + helper.addSnapAccount("acc-7", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // after the end + } + + root, dl := helper.CommitAndGenerate() + t.Logf("Root: %#x\n", root) // Root = 0x825891472281463511e7ebcc7f109e4f9200c20fa384754e11fd605cd98464e8 + + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func TestGenerateCorruptAccountTrie(t *testing.T) { + helper := newGenTester() + helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074 + helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7 + helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4 + + root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978 + + // Delete an account trie node and ensure the generator chokes + path := []byte{0xc} + if !rawdb.HasAccountTrieNode(helper.diskdb, path) { + t.Logf("Invalid node path to delete, %v", path) + } + rawdb.DeleteAccountTrieNode(helper.diskdb, path) + helper.db.tree.bottom().resetCache() + + dl := generateSnapshot(helper.db, root, false) + select { + case <-dl.generator.done: + // Snapshot generation succeeded + t.Errorf("Snapshot generated against corrupt account trie") + + case <-time.After(time.Second): + // Not generated fast enough, hopefully blocked inside on missing trie node fail + } + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func TestGenerateMissingStorageTrie(t *testing.T) { + var ( + acc1 = hashData([]byte("acc-1")) + acc3 = hashData([]byte("acc-3")) + helper = newGenTester() + ) + stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67 + helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e + helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7 + stRoot = helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2 + + root := helper.Commit() + + // Delete storage trie root of account one and three. + rawdb.DeleteStorageTrieNode(helper.diskdb, acc1, nil) + rawdb.DeleteStorageTrieNode(helper.diskdb, acc3, nil) + helper.db.tree.bottom().resetCache() + + dl := generateSnapshot(helper.db, root, false) + select { + case <-dl.generator.done: + // Snapshot generation succeeded + t.Errorf("Snapshot generated against corrupt storage trie") + + case <-time.After(time.Second): + // Not generated fast enough, hopefully blocked inside on missing trie node fail + } + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func TestGenerateCorruptStorageTrie(t *testing.T) { + helper := newGenTester() + + stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67 + helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e + helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7 + stRoot = helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2 + + root := helper.Commit() + + // Delete a node in the storage trie. + path := []byte{0x4} + if !rawdb.HasStorageTrieNode(helper.diskdb, hashData([]byte("acc-1")), path) { + t.Logf("Invalid node path to delete, %v", path) + } + rawdb.DeleteStorageTrieNode(helper.diskdb, hashData([]byte("acc-1")), []byte{0x4}) + + if !rawdb.HasStorageTrieNode(helper.diskdb, hashData([]byte("acc-3")), path) { + t.Logf("Invalid node path to delete, %v", path) + } + rawdb.DeleteStorageTrieNode(helper.diskdb, hashData([]byte("acc-3")), []byte{0x4}) + + helper.db.tree.bottom().resetCache() + + dl := generateSnapshot(helper.db, root, false) + select { + case <-dl.generator.done: + // Snapshot generation succeeded + t.Errorf("Snapshot generated against corrupt storage trie") + + case <-time.After(time.Second): + // Not generated fast enough, hopefully blocked inside on missing trie node fail + } + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func TestGenerateWithExtraAccounts(t *testing.T) { + helper := newGenTester() + + // Account one in the trie + stRoot := helper.makeStorageTrie("acc-1", + []string{"key-1", "key-2", "key-3", "key-4", "key-5"}, + []string{"val-1", "val-2", "val-3", "val-4", "val-5"}, + true, + ) + acc := &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()} + val, _ := rlp.EncodeToBytes(acc) + helper.acctTrie.MustUpdate(hashData([]byte("acc-1")).Bytes(), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e + + // Identical in the snap + key := hashData([]byte("acc-1")) + rawdb.WriteAccountSnapshot(helper.diskdb, key, val) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("key-1")), []byte("val-1")) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("key-2")), []byte("val-2")) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("key-3")), []byte("val-3")) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("key-4")), []byte("val-4")) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("key-5")), []byte("val-5")) + + // Account two exists only in the snapshot + stRoot = helper.makeStorageTrie("acc-2", + []string{"key-1", "key-2", "key-3", "key-4", "key-5"}, + []string{"val-1", "val-2", "val-3", "val-4", "val-5"}, + true, + ) + acc = &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()} + val, _ = rlp.EncodeToBytes(acc) + key = hashData([]byte("acc-2")) + rawdb.WriteAccountSnapshot(helper.diskdb, key, val) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("b-key-1")), []byte("b-val-1")) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("b-key-2")), []byte("b-val-2")) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("b-key-3")), []byte("b-val-3")) + + root := helper.Commit() + + // To verify the test: If we now inspect the snap db, there should exist extraneous storage items + if data := rawdb.ReadStorageSnapshot(helper.diskdb, hashData([]byte("acc-2")), hashData([]byte("b-key-1"))); data == nil { + t.Fatalf("expected snap storage to exist") + } + dl := generateSnapshot(helper.db, root, false) + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() + + // If we now inspect the snap db, there should exist no extraneous storage items + if data := rawdb.ReadStorageSnapshot(helper.diskdb, hashData([]byte("acc-2")), hashData([]byte("b-key-1"))); data != nil { + t.Fatalf("expected slot to be removed, got %v", string(data)) + } +} + +func TestGenerateWithManyExtraAccounts(t *testing.T) { + helper := newGenTester() + + // Account one in the trie + stRoot := helper.makeStorageTrie("acc-1", + []string{"key-1", "key-2", "key-3"}, + []string{"val-1", "val-2", "val-3"}, + true, + ) + acc := &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()} + val, _ := rlp.EncodeToBytes(acc) + helper.acctTrie.MustUpdate(hashData([]byte("acc-1")).Bytes(), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e + + // Identical in the snap + key := hashData([]byte("acc-1")) + rawdb.WriteAccountSnapshot(helper.diskdb, key, val) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("key-1")), []byte("val-1")) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("key-2")), []byte("val-2")) + rawdb.WriteStorageSnapshot(helper.diskdb, key, hashData([]byte("key-3")), []byte("val-3")) + + // 100 accounts exist only in snapshot + for i := 0; i < 1000; i++ { + acc := &types.StateAccount{Balance: uint256.NewInt(uint64(i)), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()} + val, _ := rlp.EncodeToBytes(acc) + key := hashData([]byte(fmt.Sprintf("acc-%d", i))) + rawdb.WriteAccountSnapshot(helper.diskdb, key, val) + } + + _, dl := helper.CommitAndGenerate() + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func TestGenerateWithExtraBeforeAndAfter(t *testing.T) { + helper := newGenTester() + + acc := &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()} + val, _ := rlp.EncodeToBytes(acc) + + acctHashA := hashData([]byte("acc-1")) + acctHashB := hashData([]byte("acc-2")) + + helper.acctTrie.MustUpdate(acctHashA.Bytes(), val) + helper.acctTrie.MustUpdate(acctHashB.Bytes(), val) + + rawdb.WriteAccountSnapshot(helper.diskdb, acctHashA, val) + rawdb.WriteAccountSnapshot(helper.diskdb, acctHashB, val) + + for i := 0; i < 16; i++ { + rawdb.WriteAccountSnapshot(helper.diskdb, common.Hash{byte(i)}, val) + } + _, dl := helper.CommitAndGenerate() + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func TestGenerateWithMalformedStateData(t *testing.T) { + helper := newGenTester() + + acctHash := hashData([]byte("acc")) + acc := &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()} + val, _ := rlp.EncodeToBytes(acc) + helper.acctTrie.MustUpdate(acctHash.Bytes(), val) + + junk := make([]byte, 100) + copy(junk, []byte{0xde, 0xad}) + rawdb.WriteAccountSnapshot(helper.diskdb, acctHash, junk) + for i := 0; i < 16; i++ { + rawdb.WriteAccountSnapshot(helper.diskdb, common.Hash{byte(i)}, junk) + } + + _, dl := helper.CommitAndGenerate() + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func TestGenerateFromEmptySnap(t *testing.T) { + helper := newGenTester() + + for i := 0; i < 400; i++ { + stRoot := helper.makeStorageTrie(fmt.Sprintf("acc-%d", i), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addTrieAccount(fmt.Sprintf("acc-%d", i), &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + } + root, snap := helper.CommitAndGenerate() + t.Logf("Root: %#x\n", root) // Root: 0x6f7af6d2e1a1bf2b84a3beb3f8b64388465fbc1e274ca5d5d3fc787ca78f59e4 + + select { + case <-snap.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + snap.generator.stop() +} + +func TestGenerateWithIncompleteStorage(t *testing.T) { + helper := newGenTester() + stKeys := []string{"1", "2", "3", "4", "5", "6", "7", "8"} + stVals := []string{"v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8"} + + // We add 8 accounts, each one is missing exactly one of the storage slots. This means + // we don't have to order the keys and figure out exactly which hash-key winds up + // on the sensitive spots at the boundaries + for i := 0; i < 8; i++ { + accKey := fmt.Sprintf("acc-%d", i) + stRoot := helper.makeStorageTrie(accKey, stKeys, stVals, true) + helper.addAccount(accKey, &types.StateAccount{Balance: uint256.NewInt(uint64(i)), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + var moddedKeys []string + var moddedVals []string + for ii := 0; ii < 8; ii++ { + if ii != i { + moddedKeys = append(moddedKeys, stKeys[ii]) + moddedVals = append(moddedVals, stVals[ii]) + } + } + helper.addSnapStorage(accKey, moddedKeys, moddedVals) + } + root, dl := helper.CommitAndGenerate() + t.Logf("Root: %#x\n", root) // Root: 0xca73f6f05ba4ca3024ef340ef3dfca8fdabc1b677ff13f5a9571fd49c16e67ff + + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func incKey(key []byte) []byte { + for i := len(key) - 1; i >= 0; i-- { + key[i]++ + if key[i] != 0x0 { + break + } + } + return key +} + +func decKey(key []byte) []byte { + for i := len(key) - 1; i >= 0; i-- { + key[i]-- + if key[i] != 0xff { + break + } + } + return key +} + +func populateDangling(disk ethdb.KeyValueStore) { + populate := func(accountHash common.Hash, keys []string, vals []string) { + for i, key := range keys { + rawdb.WriteStorageSnapshot(disk, accountHash, hashData([]byte(key)), []byte(vals[i])) + } + } + // Dangling storages of the "first" account + populate(common.Hash{}, []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + + // Dangling storages of the "last" account + populate(common.HexToHash("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + + // Dangling storages around the account 1 + hash := decKey(hashData([]byte("acc-1")).Bytes()) + populate(common.BytesToHash(hash), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + hash = incKey(hashData([]byte("acc-1")).Bytes()) + populate(common.BytesToHash(hash), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + + // Dangling storages around the account 2 + hash = decKey(hashData([]byte("acc-2")).Bytes()) + populate(common.BytesToHash(hash), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + hash = incKey(hashData([]byte("acc-2")).Bytes()) + populate(common.BytesToHash(hash), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + + // Dangling storages around the account 3 + hash = decKey(hashData([]byte("acc-3")).Bytes()) + populate(common.BytesToHash(hash), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + hash = incKey(hashData([]byte("acc-3")).Bytes()) + populate(common.BytesToHash(hash), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + + // Dangling storages of the random account + populate(testrand.Hash(), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + populate(testrand.Hash(), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + populate(testrand.Hash(), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) +} + +func TestGenerateCompleteSnapshotWithDanglingStorage(t *testing.T) { + var helper = newGenTester() + + stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) + + helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + + helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}) + + populateDangling(helper.diskdb) + + _, dl := helper.CommitAndGenerate() + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} + +func TestGenerateBrokenSnapshotWithDanglingStorage(t *testing.T) { + var helper = newGenTester() + + stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) + + helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) + helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) + + populateDangling(helper.diskdb) + + _, dl := helper.CommitAndGenerate() + select { + case <-dl.generator.done: + // Snapshot generation succeeded + + case <-time.After(3 * time.Second): + t.Errorf("Snapshot generation failed") + } + // TODO(rjl493456442) enable the snapshot tests + // checkSnapRoot(t, snap, root) + + // Signal abortion to the generator and wait for it to tear down + dl.generator.stop() +} diff --git a/triedb/pathdb/iterator.go b/triedb/pathdb/iterator.go index 980f228cf5..84ea08ddd3 100644 --- a/triedb/pathdb/iterator.go +++ b/triedb/pathdb/iterator.go @@ -91,15 +91,14 @@ type diffAccountIterator struct { } // newDiffAccountIterator creates an account iterator over the given state set. -func newDiffAccountIterator(seek common.Hash, states *stateSet, fn loadAccount) AccountIterator { +func newDiffAccountIterator(seek common.Hash, accountList []common.Hash, fn loadAccount) AccountIterator { // Seek out the requested starting account - hashes := states.accountList() - index := sort.Search(len(hashes), func(i int) bool { - return bytes.Compare(seek[:], hashes[i][:]) <= 0 + index := sort.Search(len(accountList), func(i int) bool { + return bytes.Compare(seek[:], accountList[i][:]) <= 0 }) // Assemble and returned the already seeked iterator return &diffAccountIterator{ - keys: hashes[index:], + keys: accountList[index:], loadFn: fn, } } @@ -236,15 +235,14 @@ type diffStorageIterator struct { } // newDiffStorageIterator creates a storage iterator over a single diff layer. -func newDiffStorageIterator(account common.Hash, seek common.Hash, states *stateSet, fn loadStorage) StorageIterator { - hashes := states.storageList(account) - index := sort.Search(len(hashes), func(i int) bool { - return bytes.Compare(seek[:], hashes[i][:]) <= 0 +func newDiffStorageIterator(account common.Hash, seek common.Hash, storageList []common.Hash, fn loadStorage) StorageIterator { + index := sort.Search(len(storageList), func(i int) bool { + return bytes.Compare(seek[:], storageList[i][:]) <= 0 }) // Assemble and returned the already seeked iterator return &diffStorageIterator{ account: account, - keys: hashes[index:], + keys: storageList[index:], loadFn: fn, } } diff --git a/triedb/pathdb/iterator_binary.go b/triedb/pathdb/iterator_binary.go index dec31e8f3f..0620081d0c 100644 --- a/triedb/pathdb/iterator_binary.go +++ b/triedb/pathdb/iterator_binary.go @@ -45,6 +45,12 @@ type binaryIterator struct { // accounts in a slow, but easily verifiable way. Note this function is used // for initialization, use `newBinaryAccountIterator` as the API. func (dl *diskLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator { + // The state set in the disk layer is mutable, hold the lock before obtaining + // the account list to prevent concurrent map iteration and write. + dl.lock.RLock() + accountList := dl.buffer.states.accountList() + dl.lock.RUnlock() + // Create two iterators for state buffer and the persistent state in disk // respectively and combine them as a binary iterator. l := &binaryIterator{ @@ -54,7 +60,7 @@ func (dl *diskLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator // The account key list for iteration is deterministic once the iterator // is constructed, no matter the referenced disk layer is stale or not // later. - a: newDiffAccountIterator(seek, dl.buffer.states, nil), + a: newDiffAccountIterator(seek, accountList, nil), b: newDiskAccountIterator(dl.db.diskdb, seek), } l.aDone = !l.a.Next() @@ -68,6 +74,9 @@ func (dl *diskLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator func (dl *diffLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator { parent, ok := dl.parent.(*diffLayer) if !ok { + // The state set in diff layer is immutable and will never be stale, + // so the read lock protection is unnecessary. + accountList := dl.states.stateSet.accountList() l := &binaryIterator{ // The account loader function is unnecessary; the account key list // produced by the supplied state set alone is sufficient for iteration. @@ -75,13 +84,16 @@ func (dl *diffLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator // The account key list for iteration is deterministic once the iterator // is constructed, no matter the referenced disk layer is stale or not // later. - a: newDiffAccountIterator(seek, dl.states.stateSet, nil), + a: newDiffAccountIterator(seek, accountList, nil), b: dl.parent.(*diskLayer).initBinaryAccountIterator(seek), } l.aDone = !l.a.Next() l.bDone = !l.b.Next() return l } + // The state set in diff layer is immutable and will never be stale, + // so the read lock protection is unnecessary. + accountList := dl.states.stateSet.accountList() l := &binaryIterator{ // The account loader function is unnecessary; the account key list // produced by the supplied state set alone is sufficient for iteration. @@ -89,7 +101,7 @@ func (dl *diffLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator // The account key list for iteration is deterministic once the iterator // is constructed, no matter the referenced disk layer is stale or not // later. - a: newDiffAccountIterator(seek, dl.states.stateSet, nil), + a: newDiffAccountIterator(seek, accountList, nil), b: parent.initBinaryAccountIterator(seek), } l.aDone = !l.a.Next() @@ -101,6 +113,12 @@ func (dl *diffLayer) initBinaryAccountIterator(seek common.Hash) *binaryIterator // storage slots in a slow, but easily verifiable way. Note this function is used // for initialization, use `newBinaryStorageIterator` as the API. func (dl *diskLayer) initBinaryStorageIterator(account common.Hash, seek common.Hash) *binaryIterator { + // The state set in the disk layer is mutable, hold the lock before obtaining + // the storage list to prevent concurrent map iteration and write. + dl.lock.RLock() + storageList := dl.buffer.states.storageList(account) + dl.lock.RUnlock() + // Create two iterators for state buffer and the persistent state in disk // respectively and combine them as a binary iterator. l := &binaryIterator{ @@ -110,7 +128,7 @@ func (dl *diskLayer) initBinaryStorageIterator(account common.Hash, seek common. // The storage key list for iteration is deterministic once the iterator // is constructed, no matter the referenced disk layer is stale or not // later. - a: newDiffStorageIterator(account, seek, dl.buffer.states, nil), + a: newDiffStorageIterator(account, seek, storageList, nil), b: newDiskStorageIterator(dl.db.diskdb, account, seek), } l.aDone = !l.a.Next() @@ -124,6 +142,9 @@ func (dl *diskLayer) initBinaryStorageIterator(account common.Hash, seek common. func (dl *diffLayer) initBinaryStorageIterator(account common.Hash, seek common.Hash) *binaryIterator { parent, ok := dl.parent.(*diffLayer) if !ok { + // The state set in diff layer is immutable and will never be stale, + // so the read lock protection is unnecessary. + storageList := dl.states.stateSet.storageList(account) l := &binaryIterator{ // The storage loader function is unnecessary; the storage key list // produced by the supplied state set alone is sufficient for iteration. @@ -131,13 +152,16 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash, seek common. // The storage key list for iteration is deterministic once the iterator // is constructed, no matter the referenced disk layer is stale or not // later. - a: newDiffStorageIterator(account, seek, dl.states.stateSet, nil), + a: newDiffStorageIterator(account, seek, storageList, nil), b: dl.parent.(*diskLayer).initBinaryStorageIterator(account, seek), } l.aDone = !l.a.Next() l.bDone = !l.b.Next() return l } + // The state set in diff layer is immutable and will never be stale, + // so the read lock protection is unnecessary. + storageList := dl.states.stateSet.storageList(account) l := &binaryIterator{ // The storage loader function is unnecessary; the storage key list // produced by the supplied state set alone is sufficient for iteration. @@ -145,7 +169,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash, seek common. // The storage key list for iteration is deterministic once the iterator // is constructed, no matter the referenced disk layer is stale or not // later. - a: newDiffStorageIterator(account, seek, dl.states.stateSet, nil), + a: newDiffStorageIterator(account, seek, storageList, nil), b: parent.initBinaryStorageIterator(account, seek), } l.aDone = !l.a.Next() diff --git a/triedb/pathdb/iterator_fast.go b/triedb/pathdb/iterator_fast.go index 966e37a7cb..87b2dd567a 100644 --- a/triedb/pathdb/iterator_fast.go +++ b/triedb/pathdb/iterator_fast.go @@ -76,11 +76,17 @@ func newFastIterator(db *Database, root common.Hash, account common.Hash, seek c if accountIterator { switch dl := current.(type) { case *diskLayer: + // The state set in the disk layer is mutable, hold the lock before obtaining + // the account list to prevent concurrent map iteration and write. + dl.lock.RLock() + accountList := dl.buffer.states.accountList() + dl.lock.RUnlock() + fi.iterators = append(fi.iterators, &weightedIterator{ // The state set in the disk layer is mutable, and the entire state becomes stale // if a diff layer above is merged into it. Therefore, staleness must be checked, // and the storage slot should be retrieved with read lock protection. - it: newDiffAccountIterator(seek, dl.buffer.states, func(hash common.Hash) ([]byte, error) { + it: newDiffAccountIterator(seek, accountList, func(hash common.Hash) ([]byte, error) { dl.lock.RLock() defer dl.lock.RUnlock() @@ -98,19 +104,26 @@ func newFastIterator(db *Database, root common.Hash, account common.Hash, seek c case *diffLayer: // The state set in diff layer is immutable and will never be stale, // so the read lock protection is unnecessary. + accountList := dl.states.accountList() fi.iterators = append(fi.iterators, &weightedIterator{ - it: newDiffAccountIterator(seek, dl.states.stateSet, dl.states.mustAccount), + it: newDiffAccountIterator(seek, accountList, dl.states.mustAccount), priority: depth, }) } } else { switch dl := current.(type) { case *diskLayer: + // The state set in the disk layer is mutable, hold the lock before obtaining + // the storage list to prevent concurrent map iteration and write. + dl.lock.RLock() + storageList := dl.buffer.states.storageList(account) + dl.lock.RUnlock() + fi.iterators = append(fi.iterators, &weightedIterator{ // The state set in the disk layer is mutable, and the entire state becomes stale // if a diff layer above is merged into it. Therefore, staleness must be checked, // and the storage slot should be retrieved with read lock protection. - it: newDiffStorageIterator(account, seek, dl.buffer.states, func(addrHash common.Hash, slotHash common.Hash) ([]byte, error) { + it: newDiffStorageIterator(account, seek, storageList, func(addrHash common.Hash, slotHash common.Hash) ([]byte, error) { dl.lock.RLock() defer dl.lock.RUnlock() @@ -126,10 +139,14 @@ func newFastIterator(db *Database, root common.Hash, account common.Hash, seek c priority: depth + 1, }) case *diffLayer: + // The state set in diff layer is immutable and will never be stale, + // so the read lock protection is unnecessary. + storageList := dl.states.storageList(account) + // The state set in diff layer is immutable and will never be stale, // so the read lock protection is unnecessary. fi.iterators = append(fi.iterators, &weightedIterator{ - it: newDiffStorageIterator(account, seek, dl.states.stateSet, dl.states.mustStorage), + it: newDiffStorageIterator(account, seek, storageList, dl.states.mustStorage), priority: depth, }) } diff --git a/triedb/pathdb/iterator_test.go b/triedb/pathdb/iterator_test.go index 3894118034..6517735d7e 100644 --- a/triedb/pathdb/iterator_test.go +++ b/triedb/pathdb/iterator_test.go @@ -132,18 +132,15 @@ func TestAccountIteratorBasics(t *testing.T) { } } states := newStates(accounts, storage, false) - it := newDiffAccountIterator(common.Hash{}, states, nil) + it := newDiffAccountIterator(common.Hash{}, states.accountList(), nil) verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator - // TODO reenable these tests once the persistent state iteration - // is implemented. - - //db := rawdb.NewMemoryDatabase() - //batch := db.NewBatch() - //states.write(db, batch, nil, nil) - //batch.Write() - //it = newDiskAccountIterator(db, common.Hash{}) - //verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator + db := rawdb.NewMemoryDatabase() + batch := db.NewBatch() + states.write(batch, nil, nil) + batch.Write() + it = newDiskAccountIterator(db, common.Hash{}) + verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator } // TestStorageIteratorBasics tests some simple single-layer(diff and disk) iteration for storage @@ -173,21 +170,18 @@ func TestStorageIteratorBasics(t *testing.T) { } states := newStates(accounts, storage, false) for account := range accounts { - it := newDiffStorageIterator(account, common.Hash{}, states, nil) + it := newDiffStorageIterator(account, common.Hash{}, states.storageList(account), nil) verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator } - // TODO reenable these tests once the persistent state iteration - // is implemented. - - //db := rawdb.NewMemoryDatabase() - //batch := db.NewBatch() - //states.write(db, batch, nil, nil) - //batch.Write() - //for account := range accounts { - // it := newDiskStorageIterator(db, account, common.Hash{}) - // verifyIterator(t, 100-nilStorage[account], it, verifyNothing) // Nil is allowed for single layer iterator - //} + db := rawdb.NewMemoryDatabase() + batch := db.NewBatch() + states.write(batch, nil, nil) + batch.Write() + for account := range accounts { + it := newDiskStorageIterator(db, account, common.Hash{}) + verifyIterator(t, 100-nilStorage[account], it, verifyNothing) // Nil is allowed for single layer iterator + } } type testIterator struct { @@ -263,7 +257,7 @@ func TestAccountIteratorTraversal(t *testing.T) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 0, trienode.NewMergedNodeSet(), @@ -279,7 +273,7 @@ func TestAccountIteratorTraversal(t *testing.T) { head := db.tree.get(common.HexToHash("0x04")) // singleLayer: 0xcc, 0xf0, 0xff - it := newDiffAccountIterator(common.Hash{}, head.(*diffLayer).states.stateSet, nil) + it := newDiffAccountIterator(common.Hash{}, head.(*diffLayer).states.stateSet.accountList(), nil) verifyIterator(t, 3, it, verifyNothing) // binaryIterator: 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xf0, 0xff @@ -290,19 +284,16 @@ func TestAccountIteratorTraversal(t *testing.T) { verifyIterator(t, 7, it, verifyAccount) it.Release() - // TODO reenable these tests once the persistent state iteration - // is implemented. - // Test after persist some bottom-most layers into the disk, // the functionalities still work. - //db.tree.cap(common.HexToHash("0x04"), 2) + db.tree.cap(common.HexToHash("0x04"), 2) - //head = db.tree.get(common.HexToHash("0x04")) - //verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount) - // - //it, _ = db.AccountIterator(common.HexToHash("0x04"), common.Hash{}) - //verifyIterator(t, 7, it, verifyAccount) - //it.Release() + head = db.tree.get(common.HexToHash("0x04")) + verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount) + + it, _ = db.AccountIterator(common.HexToHash("0x04"), common.Hash{}) + verifyIterator(t, 7, it, verifyAccount) + it.Release() } func TestStorageIteratorTraversal(t *testing.T) { @@ -310,7 +301,7 @@ func TestStorageIteratorTraversal(t *testing.T) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 0, trienode.NewMergedNodeSet(), @@ -326,7 +317,7 @@ func TestStorageIteratorTraversal(t *testing.T) { head := db.tree.get(common.HexToHash("0x04")) // singleLayer: 0x1, 0x2, 0x3 - diffIter := newDiffStorageIterator(common.HexToHash("0xaa"), common.Hash{}, head.(*diffLayer).states.stateSet, nil) + diffIter := newDiffStorageIterator(common.HexToHash("0xaa"), common.Hash{}, head.(*diffLayer).states.stateSet.storageList(common.HexToHash("0xaa")), nil) verifyIterator(t, 3, diffIter, verifyNothing) // binaryIterator: 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 @@ -337,17 +328,14 @@ func TestStorageIteratorTraversal(t *testing.T) { verifyIterator(t, 6, it, verifyStorage) it.Release() - // TODO reenable these tests once the persistent state iteration - // is implemented. - // Test after persist some bottom-most layers into the disk, // the functionalities still work. - //db.tree.cap(common.HexToHash("0x04"), 2) - //verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage) - // - //it, _ = db.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) - //verifyIterator(t, 6, it, verifyStorage) - //it.Release() + db.tree.cap(common.HexToHash("0x04"), 2) + verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}), verifyStorage) + + it, _ = db.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) + verifyIterator(t, 6, it, verifyStorage) + it.Release() } // TestAccountIteratorTraversalValues tests some multi-layer iteration, where we @@ -357,7 +345,7 @@ func TestAccountIteratorTraversalValues(t *testing.T) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() // Create a batch of account sets to seed subsequent layers with var ( @@ -434,26 +422,38 @@ func TestAccountIteratorTraversalValues(t *testing.T) { } it.Release() - // TODO reenable these tests once the persistent state iteration - // is implemented. - // Test after persist some bottom-most layers into the disk, // the functionalities still work. - //db.tree.cap(common.HexToHash("0x09"), 2) - // - //it, _ = db.AccountIterator(common.HexToHash("0x09"), common.Hash{}) - //for it.Next() { - // hash := it.Hash() - // account, err := head.Account(hash) - // if err != nil { - // t.Fatalf("failed to retrieve expected account: %v", err) - // } - // want, _ := rlp.EncodeToBytes(account) - // if have := it.Account(); !bytes.Equal(want, have) { - // t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) - // } - //} - //it.Release() + db.tree.cap(common.HexToHash("0x09"), 2) + + // binaryIterator + head = db.tree.get(common.HexToHash("0x09")) + it = head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) + for it.Next() { + hash := it.Hash() + want, err := r.(*reader).AccountRLP(hash) + if err != nil { + t.Fatalf("failed to retrieve expected account: %v", err) + } + if have := it.Account(); !bytes.Equal(want, have) { + t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) + } + } + it.Release() + + // fastIterator + it, _ = db.AccountIterator(common.HexToHash("0x09"), common.Hash{}) + for it.Next() { + hash := it.Hash() + want, err := r.(*reader).AccountRLP(hash) + if err != nil { + t.Fatalf("failed to retrieve expected account: %v", err) + } + if have := it.Account(); !bytes.Equal(want, have) { + t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) + } + } + it.Release() } func TestStorageIteratorTraversalValues(t *testing.T) { @@ -461,7 +461,7 @@ func TestStorageIteratorTraversalValues(t *testing.T) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() wrapStorage := func(storage map[common.Hash][]byte) map[common.Hash]map[common.Hash][]byte { return map[common.Hash]map[common.Hash][]byte{ @@ -543,25 +543,38 @@ func TestStorageIteratorTraversalValues(t *testing.T) { } it.Release() - // TODO reenable these tests once the persistent state iteration - // is implemented. - // Test after persist some bottom-most layers into the disk, // the functionalities still work. - //db.tree.cap(common.HexToHash("0x09"), 2) - // - //it, _ = db.StorageIterator(common.HexToHash("0x09"), common.HexToHash("0xaa"), common.Hash{}) - //for it.Next() { - // hash := it.Hash() - // want, err := head.Storage(common.HexToHash("0xaa"), hash) - // if err != nil { - // t.Fatalf("failed to retrieve expected slot: %v", err) - // } - // if have := it.Slot(); !bytes.Equal(want, have) { - // t.Fatalf("hash %x: slot mismatch: have %x, want %x", hash, have, want) - // } - //} - //it.Release() + db.tree.cap(common.HexToHash("0x09"), 2) + + // binaryIterator + head = db.tree.get(common.HexToHash("0x09")) + it = head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}) + for it.Next() { + hash := it.Hash() + want, err := r.Storage(common.HexToHash("0xaa"), hash) + if err != nil { + t.Fatalf("failed to retrieve expected account: %v", err) + } + if have := it.Slot(); !bytes.Equal(want, have) { + t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) + } + } + it.Release() + + // fastIterator + it, _ = db.StorageIterator(common.HexToHash("0x09"), common.HexToHash("0xaa"), common.Hash{}) + for it.Next() { + hash := it.Hash() + want, err := r.Storage(common.HexToHash("0xaa"), hash) + if err != nil { + t.Fatalf("failed to retrieve expected storage slot: %v", err) + } + if have := it.Slot(); !bytes.Equal(want, have) { + t.Fatalf("hash %x: slot mismatch: have %x, want %x", hash, have, want) + } + } + it.Release() } // This testcase is notorious, all layers contain the exact same 200 accounts. @@ -581,7 +594,8 @@ func TestAccountIteratorLargeTraversal(t *testing.T) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() + for i := 1; i < 128; i++ { parent := types.EmptyRootHash if i == 1 { @@ -592,25 +606,22 @@ func TestAccountIteratorLargeTraversal(t *testing.T) { } // Iterate the entire stack and ensure everything is hit only once head := db.tree.get(common.HexToHash("0x80")) - verifyIterator(t, 200, newDiffAccountIterator(common.Hash{}, head.(*diffLayer).states.stateSet, nil), verifyNothing) + verifyIterator(t, 200, newDiffAccountIterator(common.Hash{}, head.(*diffLayer).states.stateSet.accountList(), nil), verifyNothing) verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount) it, _ := db.AccountIterator(common.HexToHash("0x80"), common.Hash{}) verifyIterator(t, 200, it, verifyAccount) it.Release() - // TODO reenable these tests once the persistent state iteration - // is implemented. - // Test after persist some bottom-most layers into the disk, // the functionalities still work. - //db.tree.cap(common.HexToHash("0x80"), 2) - // - //verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount) - // - //it, _ = db.AccountIterator(common.HexToHash("0x80"), common.Hash{}) - //verifyIterator(t, 200, it, verifyAccount) - //it.Release() + db.tree.cap(common.HexToHash("0x80"), 2) + + verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount) + + it, _ = db.AccountIterator(common.HexToHash("0x80"), common.Hash{}) + verifyIterator(t, 200, it, verifyAccount) + it.Release() } // TestAccountIteratorFlattening tests what happens when we @@ -622,7 +633,7 @@ func TestAccountIteratorFlattening(t *testing.T) { WriteBufferSize: 10 * 1024, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() // Create a stack of diffs on top db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), @@ -655,7 +666,7 @@ func TestAccountIteratorSeek(t *testing.T) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil, nil, nil, false)) @@ -727,7 +738,7 @@ func testStorageIteratorSeek(t *testing.T, newIterator func(db *Database, root, WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), @@ -799,7 +810,7 @@ func testAccountIteratorDeletions(t *testing.T, newIterator func(db *Database, r WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), @@ -839,7 +850,7 @@ func TestStorageIteratorDeletions(t *testing.T) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() // Stack three diff layers on top with various overlaps db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), @@ -907,7 +918,7 @@ func testStaleIterator(t *testing.T, newIter func(db *Database, hash common.Hash WriteBufferSize: 16 * 1024 * 1024, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() // [02 (disk), 03] db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), @@ -962,7 +973,7 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() for i := 1; i <= 100; i++ { parent := types.EmptyRootHash @@ -1057,7 +1068,7 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { WriteBufferSize: 0, } db := New(rawdb.NewMemoryDatabase(), config, false) - // db.WaitGeneration() + db.waitGeneration() db.Update(common.HexToHash("0x02"), types.EmptyRootHash, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(makeAccounts(2000), nil, nil, nil, false)) for i := 2; i <= 100; i++ { diff --git a/triedb/pathdb/journal.go b/triedb/pathdb/journal.go index 79a7a22e0b..5dc6da92b8 100644 --- a/triedb/pathdb/journal.go +++ b/triedb/pathdb/journal.go @@ -26,6 +26,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/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" ) @@ -90,6 +91,56 @@ func (db *Database) loadJournal(diskRoot common.Hash) (layer, error) { return head, nil } +// journalGenerator is a disk layer entry containing the generator progress marker. +type journalGenerator struct { + // Indicator that whether the database was in progress of being wiped. + // It's deprecated but keep it here for backward compatibility. + Wiping bool + + Done bool // Whether the generator finished creating the snapshot + Marker []byte + Accounts uint64 + Slots uint64 + Storage uint64 +} + +// loadGenerator loads the state generation progress marker from the database. +func loadGenerator(db ethdb.KeyValueReader, hash nodeHasher) (*journalGenerator, common.Hash, error) { + trieRoot, err := hash(rawdb.ReadAccountTrieNode(db, nil)) + if err != nil { + return nil, common.Hash{}, err + } + // State generation progress marker is lost, rebuild it + blob := rawdb.ReadSnapshotGenerator(db) + if len(blob) == 0 { + log.Info("State snapshot generator is not found") + return nil, trieRoot, nil + } + // State generation progress marker is not compatible, rebuild it + var generator journalGenerator + if err := rlp.DecodeBytes(blob, &generator); err != nil { + log.Info("State snapshot generator is not compatible") + return nil, trieRoot, nil + } + // The state snapshot is inconsistent with the trie data and must + // be rebuilt. + // + // Note: The SnapshotRoot and SnapshotGenerator are always consistent + // with each other, both in the legacy state snapshot and the path database. + // Therefore, if the SnapshotRoot does not match the trie root, + // the entire generator is considered stale and must be discarded. + stateRoot := rawdb.ReadSnapshotRoot(db) + if trieRoot != stateRoot { + log.Info("State snapshot is not consistent", "trie", trieRoot, "state", stateRoot) + return nil, trieRoot, nil + } + // Slice null-ness is lost after rlp decoding, reset it back to empty + if !generator.Done && generator.Marker == nil { + generator.Marker = []byte{} + } + return &generator, trieRoot, nil +} + // 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. @@ -109,7 +160,7 @@ func (db *Database) loadLayers() layer { log.Info("Failed to load journal, discard it", "err", err) } // Return single layer with persistent state. - return newDiskLayer(root, rawdb.ReadPersistentStateID(db.diskdb), db, nil, newBuffer(db.config.WriteBufferSize, nil, nil, 0)) + return newDiskLayer(root, rawdb.ReadPersistentStateID(db.diskdb), db, nil, nil, newBuffer(db.config.WriteBufferSize, nil, nil, 0)) } // loadDiskLayer reads the binary blob from the layer journal, reconstructing @@ -141,7 +192,7 @@ func (db *Database) loadDiskLayer(r *rlp.Stream) (layer, error) { if err := states.decode(r); err != nil { return nil, err } - return newDiskLayer(root, id, db, nil, newBuffer(db.config.WriteBufferSize, &nodes, &states, id-stored)), nil + return newDiskLayer(root, id, db, nil, nil, newBuffer(db.config.WriteBufferSize, &nodes, &states, id-stored)), nil } // loadDiffLayer reads the next sections of a layer journal, reconstructing a new @@ -250,6 +301,10 @@ func (db *Database) Journal(root common.Hash) error { } else { // disk layer only on noop runs (likely) or deep reorgs (unlikely) log.Info("Persisting dirty state to disk", "root", root, "layers", disk.buffer.layers) } + // Terminate the background state generation if it's active + if disk.generator != nil { + disk.generator.stop() + } start := time.Now() // Run the journaling diff --git a/triedb/pathdb/metrics.go b/triedb/pathdb/metrics.go index abe2dfe1f6..502c34fc62 100644 --- a/triedb/pathdb/metrics.go +++ b/triedb/pathdb/metrics.go @@ -24,16 +24,26 @@ var ( cleanNodeReadMeter = metrics.NewRegisteredMeter("pathdb/clean/node/read", nil) cleanNodeWriteMeter = metrics.NewRegisteredMeter("pathdb/clean/node/write", nil) + cleanStateHitMeter = metrics.NewRegisteredMeter("pathdb/clean/state/hit", nil) + cleanStateMissMeter = metrics.NewRegisteredMeter("pathdb/clean/state/miss", nil) + cleanStateReadMeter = metrics.NewRegisteredMeter("pathdb/clean/state/read", nil) + cleanStateWriteMeter = metrics.NewRegisteredMeter("pathdb/clean/state/write", nil) + dirtyNodeHitMeter = metrics.NewRegisteredMeter("pathdb/dirty/node/hit", nil) dirtyNodeMissMeter = metrics.NewRegisteredMeter("pathdb/dirty/node/miss", nil) dirtyNodeReadMeter = metrics.NewRegisteredMeter("pathdb/dirty/node/read", nil) dirtyNodeWriteMeter = metrics.NewRegisteredMeter("pathdb/dirty/node/write", nil) dirtyNodeHitDepthHist = metrics.NewRegisteredHistogram("pathdb/dirty/node/depth", nil, metrics.NewExpDecaySample(1028, 0.015)) - stateAccountInexMeter = metrics.NewRegisteredMeter("pathdb/state/account/inex/total", nil) - stateStorageInexMeter = metrics.NewRegisteredMeter("pathdb/state/storage/inex/total", nil) - stateAccountExistMeter = metrics.NewRegisteredMeter("pathdb/state/account/exist/total", nil) - stateStorageExistMeter = metrics.NewRegisteredMeter("pathdb/state/storage/exist/total", nil) + stateAccountInexMeter = metrics.NewRegisteredMeter("pathdb/state/account/inex/total", nil) + stateStorageInexMeter = metrics.NewRegisteredMeter("pathdb/state/storage/inex/total", nil) + stateAccountInexDiskMeter = metrics.NewRegisteredMeter("pathdb/state/account/inex/disk", nil) + stateStorageInexDiskMeter = metrics.NewRegisteredMeter("pathdb/state/storage/inex/disk", nil) + + stateAccountExistMeter = metrics.NewRegisteredMeter("pathdb/state/account/exist/total", nil) + stateStorageExistMeter = metrics.NewRegisteredMeter("pathdb/state/storage/exist/total", nil) + stateAccountExistDiskMeter = metrics.NewRegisteredMeter("pathdb/state/account/exist/disk", nil) + stateStorageExistDiskMeter = metrics.NewRegisteredMeter("pathdb/state/storage/exist/disk", nil) dirtyStateHitMeter = metrics.NewRegisteredMeter("pathdb/dirty/state/hit", nil) dirtyStateMissMeter = metrics.NewRegisteredMeter("pathdb/dirty/state/miss", nil) @@ -46,9 +56,11 @@ var ( nodeDiskFalseMeter = metrics.NewRegisteredMeter("pathdb/disk/false", nil) nodeDiffFalseMeter = metrics.NewRegisteredMeter("pathdb/diff/false", nil) - commitTimeTimer = metrics.NewRegisteredResettingTimer("pathdb/commit/time", nil) - commitNodesMeter = metrics.NewRegisteredMeter("pathdb/commit/nodes", nil) - commitBytesMeter = metrics.NewRegisteredMeter("pathdb/commit/bytes", nil) + commitTimeTimer = metrics.NewRegisteredResettingTimer("pathdb/commit/time", nil) + commitNodesMeter = metrics.NewRegisteredMeter("pathdb/commit/nodes", nil) + commitAccountsMeter = metrics.NewRegisteredMeter("pathdb/commit/accounts", nil) + commitStoragesMeter = metrics.NewRegisteredMeter("pathdb/commit/slots", nil) + commitBytesMeter = metrics.NewRegisteredMeter("pathdb/commit/bytes", nil) gcTrieNodeMeter = metrics.NewRegisteredMeter("pathdb/gc/node/count", nil) gcTrieNodeBytesMeter = metrics.NewRegisteredMeter("pathdb/gc/node/bytes", nil) @@ -61,3 +73,28 @@ var ( historyDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/data", nil) historyIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/index", nil) ) + +// Metrics in generation +var ( + generatedAccountMeter = metrics.NewRegisteredMeter("pathdb/generation/account/generated", nil) + recoveredAccountMeter = metrics.NewRegisteredMeter("pathdb/generation/account/recovered", nil) + wipedAccountMeter = metrics.NewRegisteredMeter("pathdb/generation/account/wiped", nil) + missallAccountMeter = metrics.NewRegisteredMeter("pathdb/generation/account/missall", nil) + generatedStorageMeter = metrics.NewRegisteredMeter("pathdb/generation/storage/generated", nil) + recoveredStorageMeter = metrics.NewRegisteredMeter("pathdb/generation/storage/recovered", nil) + wipedStorageMeter = metrics.NewRegisteredMeter("pathdb/generation/storage/wiped", nil) + missallStorageMeter = metrics.NewRegisteredMeter("pathdb/generation/storage/missall", nil) + danglingStorageMeter = metrics.NewRegisteredMeter("pathdb/generation/storage/dangling", nil) + successfulRangeProofMeter = metrics.NewRegisteredMeter("pathdb/generation/proof/success", nil) + failedRangeProofMeter = metrics.NewRegisteredMeter("pathdb/generation/proof/failure", nil) + + accountProveCounter = metrics.NewRegisteredCounter("pathdb/generation/duration/account/prove", nil) + accountTrieReadCounter = metrics.NewRegisteredCounter("pathdb/generation/duration/account/trieread", nil) + accountSnapReadCounter = metrics.NewRegisteredCounter("pathdb/generation/duration/account/snapread", nil) + accountWriteCounter = metrics.NewRegisteredCounter("pathdb/generation/duration/account/write", nil) + storageProveCounter = metrics.NewRegisteredCounter("pathdb/generation/duration/storage/prove", nil) + storageTrieReadCounter = metrics.NewRegisteredCounter("pathdb/generation/duration/storage/trieread", nil) + storageSnapReadCounter = metrics.NewRegisteredCounter("pathdb/generation/duration/storage/snapread", nil) + storageWriteCounter = metrics.NewRegisteredCounter("pathdb/generation/duration/storage/write", nil) + storageCleanCounter = metrics.NewRegisteredCounter("state/snapshot/generation/duration/storage/clean", nil) +) diff --git a/triedb/pathdb/states.go b/triedb/pathdb/states.go index 0a83b2f2cc..2a88d74f5f 100644 --- a/triedb/pathdb/states.go +++ b/triedb/pathdb/states.go @@ -23,8 +23,10 @@ import ( "slices" "sync" + "github.com/VictoriaMetrics/fastcache" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" @@ -416,6 +418,11 @@ func (s *stateSet) decode(r *rlp.Stream) error { return nil } +// write flushes state mutations into the provided database batch as a whole. +func (s *stateSet) write(batch ethdb.Batch, genMarker []byte, clean *fastcache.Cache) (int, int) { + return writeStates(batch, genMarker, s.accountData, s.storageData, clean) +} + // reset clears all cached state data, including any optional sorted lists that // may have been generated. func (s *stateSet) reset() { @@ -427,8 +434,6 @@ func (s *stateSet) reset() { } // dbsize returns the approximate size for db write. -// -// nolint:unused func (s *stateSet) dbsize() int { m := len(s.accountData) * len(rawdb.SnapshotAccountPrefix) for _, slots := range s.storageData { From 7e7925460507db9988088223ecd069af507815d6 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Fri, 16 May 2025 17:10:47 +0200 Subject: [PATCH 371/940] eth/protocols/eth: implement eth/69 (#29158) This PR implements eth/69. This protocol version drops the bloom filter from receipts messages, reducing the amount of data needed for a sync by ~530GB (2.3B txs * 256 byte) uncompressed. Compressed this will be reduced to ~100GB The new version also changes the Status message and introduces the BlockRangeUpdate message to relay information about the available history range. --------- Co-authored-by: Felix Lange --- cmd/devp2p/internal/ethtest/conn.go | 28 +- cmd/devp2p/internal/ethtest/protocol.go | 2 +- cmd/devp2p/internal/ethtest/suite.go | 73 ++- cmd/utils/cmd.go | 3 +- core/blockchain.go | 13 +- core/blockchain_reader.go | 14 +- core/blockchain_test.go | 22 +- core/filtermaps/chain_view.go | 4 +- core/filtermaps/indexer_test.go | 2 +- core/rawdb/accessors_chain.go | 25 +- core/rawdb/accessors_chain_test.go | 12 +- core/txindexer_test.go | 8 +- core/types/bloom9.go | 21 +- core/types/receipt.go | 24 +- core/types/receipt_test.go | 298 +++++------ eth/downloader/downloader.go | 7 +- eth/downloader/downloader_test.go | 9 +- .../fetchers_concurrent_receipts.go | 2 +- eth/downloader/queue.go | 9 +- eth/downloader/queue_test.go | 6 +- eth/filters/filter_system_test.go | 7 +- eth/handler.go | 160 +++++- eth/handler_eth_test.go | 13 +- eth/peer.go | 18 +- eth/protocols/eth/handler.go | 27 +- eth/protocols/eth/handler_test.go | 17 +- eth/protocols/eth/handlers.go | 142 ++++-- eth/protocols/eth/handshake.go | 182 +++++-- eth/protocols/eth/handshake_test.go | 10 +- eth/protocols/eth/peer.go | 16 + eth/protocols/eth/protocol.go | 65 ++- eth/protocols/eth/protocol_test.go | 35 +- eth/protocols/eth/receipt.go | 462 ++++++++++++++++++ eth/protocols/eth/receipt_test.go | 158 ++++++ eth/protocols/eth/tracker.go | 26 - 35 files changed, 1522 insertions(+), 398 deletions(-) create mode 100644 eth/protocols/eth/receipt.go create mode 100644 eth/protocols/eth/receipt_test.go delete mode 100644 eth/protocols/eth/tracker.go diff --git a/cmd/devp2p/internal/ethtest/conn.go b/cmd/devp2p/internal/ethtest/conn.go index a7bc70cbf5..6d8e0f1f7e 100644 --- a/cmd/devp2p/internal/ethtest/conn.go +++ b/cmd/devp2p/internal/ethtest/conn.go @@ -66,10 +66,9 @@ func (s *Suite) dialAs(key *ecdsa.PrivateKey) (*Conn, error) { return nil, err } conn.caps = []p2p.Cap{ - {Name: "eth", Version: 67}, - {Name: "eth", Version: 68}, + {Name: "eth", Version: 69}, } - conn.ourHighestProtoVersion = 68 + conn.ourHighestProtoVersion = 69 return &conn, nil } @@ -156,7 +155,7 @@ func (c *Conn) ReadEth() (any, error) { var msg any switch int(code) { case eth.StatusMsg: - msg = new(eth.StatusPacket) + msg = new(eth.StatusPacket69) case eth.GetBlockHeadersMsg: msg = new(eth.GetBlockHeadersPacket) case eth.BlockHeadersMsg: @@ -231,7 +230,7 @@ func (c *Conn) ReadSnap() (any, error) { // peer performs both the protocol handshake and the status message // exchange with the node in order to peer with it. -func (c *Conn) peer(chain *Chain, status *eth.StatusPacket) error { +func (c *Conn) peer(chain *Chain, status *eth.StatusPacket69) error { if err := c.handshake(); err != nil { return fmt.Errorf("handshake failed: %v", err) } @@ -304,7 +303,7 @@ func (c *Conn) negotiateEthProtocol(caps []p2p.Cap) { } // statusExchange performs a `Status` message exchange with the given node. -func (c *Conn) statusExchange(chain *Chain, status *eth.StatusPacket) error { +func (c *Conn) statusExchange(chain *Chain, status *eth.StatusPacket69) error { loop: for { code, data, err := c.Read() @@ -313,12 +312,16 @@ loop: } switch code { case eth.StatusMsg + protoOffset(ethProto): - msg := new(eth.StatusPacket) + msg := new(eth.StatusPacket69) if err := rlp.DecodeBytes(data, &msg); err != nil { return fmt.Errorf("error decoding status packet: %w", err) } - if have, want := msg.Head, chain.blocks[chain.Len()-1].Hash(); have != want { - return fmt.Errorf("wrong head block in status, want: %#x (block %d) have %#x", + if have, want := msg.LatestBlock, chain.blocks[chain.Len()-1].NumberU64(); have != want { + return fmt.Errorf("wrong head block in status, want: %d, have %d", + want, have) + } + if have, want := msg.LatestBlockHash, chain.blocks[chain.Len()-1].Hash(); have != want { + return fmt.Errorf("wrong head block in status, want: %#x (block %d) have %#x", want, chain.blocks[chain.Len()-1].NumberU64(), have) } if have, want := msg.ForkID, chain.ForkID(); !reflect.DeepEqual(have, want) { @@ -348,13 +351,14 @@ loop: } if status == nil { // default status message - status = ð.StatusPacket{ + status = ð.StatusPacket69{ ProtocolVersion: uint32(c.negotiatedProtoVersion), NetworkID: chain.config.ChainID.Uint64(), - TD: chain.TD(), - Head: chain.blocks[chain.Len()-1].Hash(), Genesis: chain.blocks[0].Hash(), ForkID: chain.ForkID(), + EarliestBlock: 0, + LatestBlock: chain.blocks[chain.Len()-1].NumberU64(), + LatestBlockHash: chain.blocks[chain.Len()-1].Hash(), } } if err := c.Write(ethProto, eth.StatusMsg, status); err != nil { diff --git a/cmd/devp2p/internal/ethtest/protocol.go b/cmd/devp2p/internal/ethtest/protocol.go index 5c2f7d9e48..a21d1ca7a1 100644 --- a/cmd/devp2p/internal/ethtest/protocol.go +++ b/cmd/devp2p/internal/ethtest/protocol.go @@ -32,7 +32,7 @@ const ( // Unexported devp2p protocol lengths from p2p package. const ( baseProtoLen = 16 - ethProtoLen = 17 + ethProtoLen = 18 snapProtoLen = 8 ) diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go index a16d308dfd..b90ecf3ca3 100644 --- a/cmd/devp2p/internal/ethtest/suite.go +++ b/cmd/devp2p/internal/ethtest/suite.go @@ -74,8 +74,9 @@ func (s *Suite) EthTests() []utesting.Test { {Name: "SimultaneousRequests", Fn: s.TestSimultaneousRequests}, {Name: "SameRequestID", Fn: s.TestSameRequestID}, {Name: "ZeroRequestID", Fn: s.TestZeroRequestID}, - // get block bodies + // get history {Name: "GetBlockBodies", Fn: s.TestGetBlockBodies}, + {Name: "GetReceipts", Fn: s.TestGetReceipts}, // // malicious handshakes + status {Name: "MaliciousHandshake", Fn: s.TestMaliciousHandshake}, // test transactions @@ -418,6 +419,51 @@ func (s *Suite) TestGetBlockBodies(t *utesting.T) { } } +func (s *Suite) TestGetReceipts(t *utesting.T) { + t.Log(`This test sends GetReceipts requests to the node for known blocks in the test chain.`) + + conn, err := s.dial() + if err != nil { + t.Fatalf("dial failed: %v", err) + } + defer conn.Close() + if err := conn.peer(s.chain, nil); err != nil { + t.Fatalf("peering failed: %v", err) + } + + // Find some blocks containing receipts. + var hashes = make([]common.Hash, 0, 3) + for i := range s.chain.Len() { + block := s.chain.GetBlock(i) + if len(block.Transactions()) > 0 { + hashes = append(hashes, block.Hash()) + } + if len(hashes) == cap(hashes) { + break + } + } + + // Create block bodies request. + req := ð.GetReceiptsPacket{ + RequestId: 66, + GetReceiptsRequest: (eth.GetReceiptsRequest)(hashes), + } + if err := conn.Write(ethProto, eth.GetReceiptsMsg, req); err != nil { + t.Fatalf("could not write to connection: %v", err) + } + // Wait for response. + resp := new(eth.ReceiptsPacket[*eth.ReceiptList69]) + if err := conn.ReadMsg(ethProto, eth.ReceiptsMsg, &resp); err != nil { + t.Fatalf("error reading block bodies msg: %v", err) + } + if got, want := resp.RequestId, req.RequestId; got != want { + t.Fatalf("unexpected request id in respond", got, want) + } + if len(resp.List) != len(req.GetReceiptsRequest) { + t.Fatalf("wrong bodies in response: expected %d bodies, got %d", len(req.GetReceiptsRequest), len(resp.List)) + } +} + // randBuf makes a random buffer size kilobytes large. func randBuf(size int) []byte { buf := make([]byte, size*1024) @@ -500,6 +546,31 @@ func (s *Suite) TestMaliciousHandshake(t *utesting.T) { } } +func (s *Suite) TestInvalidBlockRangeUpdate(t *utesting.T) { + t.Log(`This test sends an invalid BlockRangeUpdate message to the node and expects to be disconnected.`) + + conn, err := s.dial() + if err != nil { + t.Fatalf("dial failed: %v", err) + } + defer conn.Close() + if err := conn.peer(s.chain, nil); err != nil { + t.Fatalf("peering failed: %v", err) + } + + conn.Write(ethProto, eth.BlockRangeUpdateMsg, ð.BlockRangeUpdatePacket{ + EarliestBlock: 10, + LatestBlock: 8, + LatestBlockHash: s.chain.GetBlock(8).Hash(), + }) + + if code, _, err := conn.Read(); err != nil { + t.Fatalf("expected disconnect, got err: %v", err) + } else if code != discMsg { + t.Fatalf("expected disconnect message, got msg code %d", code) + } +} + func (s *Suite) TestTransaction(t *utesting.T) { t.Log(`This test sends a valid transaction to the node and checks if the transaction gets propagated.`) diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index d34e15ebc0..b332a060de 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -309,7 +309,8 @@ func ImportHistory(chain *core.BlockChain, dir string, network string) error { if err != nil { return fmt.Errorf("error reading receipts %d: %w", it.Number(), err) } - if _, err := chain.InsertReceiptChain([]*types.Block{block}, []types.Receipts{receipts}, 2^64-1); err != nil { + encReceipts := types.EncodeBlockReceiptLists([]types.Receipts{receipts}) + if _, err := chain.InsertReceiptChain([]*types.Block{block}, encReceipts, 2^64-1); err != nil { return fmt.Errorf("error inserting body %d: %w", it.Number(), err) } imported += 1 diff --git a/core/blockchain.go b/core/blockchain.go index f93cddfe44..64345bc1a3 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1309,12 +1309,11 @@ const ( // // The optional ancientLimit can also be specified and chain segment before that // will be directly stored in the ancient, getting rid of the chain migration. -func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts, ancientLimit uint64) (int, error) { +func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []rlp.RawValue, ancientLimit uint64) (int, error) { // Verify the supplied headers before insertion without lock var headers []*types.Header for _, block := range blockChain { headers = append(headers, block.Header()) - // Here we also validate that blob transactions in the block do not // contain a sidecar. While the sidecar does not affect the block hash // or tx hash, sending blobs within a block is not allowed. @@ -1357,11 +1356,11 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // // this function only accepts canonical chain data. All side chain will be reverted // eventually. - writeAncient := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { + writeAncient := func(blockChain types.Blocks, receiptChain []rlp.RawValue) (int, error) { // Ensure genesis is in the ancient store if blockChain[0].NumberU64() == 1 { if frozen, _ := bc.db.Ancients(); frozen == 0 { - writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []types.Receipts{nil}) + writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}) if err != nil { log.Error("Error writing genesis to ancients", "err", err) return 0, err @@ -1404,7 +1403,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // existing local chain segments (reorg around the chain tip). The reorganized part // will be included in the provided chain segment, and stale canonical markers will be // silently rewritten. Therefore, no explicit reorg logic is needed. - writeLive := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { + writeLive := func(blockChain types.Blocks, receiptChain []rlp.RawValue) (int, error) { var ( skipPresenceCheck = false batch = bc.db.NewBatch() @@ -1429,7 +1428,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // Write all the data out into the database rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64()) rawdb.WriteBlock(batch, block) - rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i]) + rawdb.WriteRawReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i]) // Write everything belongs to the blocks into the database. So that // we can ensure all components of body is completed(body, receipts) @@ -2650,7 +2649,7 @@ func (bc *BlockChain) InsertHeadersBeforeCutoff(headers []*types.Header) (int, e first = headers[0].Number.Uint64() ) if first == 1 && frozen == 0 { - _, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []types.Receipts{nil}) + _, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}) if err != nil { log.Error("Error writing genesis to ancients", "err", err) return 0, err diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index fefeb37542..c54948122d 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -234,12 +234,22 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return receipts } -func (bc *BlockChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts { +// GetRawReceipts retrieves the receipts for all transactions in a given block +// without deriving the internal fields and the Bloom. +func (bc *BlockChain) GetRawReceipts(hash common.Hash, number uint64) types.Receipts { + if receipts, ok := bc.receiptsCache.Get(hash); ok { + return receipts + } + return rawdb.ReadRawReceipts(bc.db, hash, number) +} + +// GetReceiptsRLP retrieves the receipts of a block. +func (bc *BlockChain) GetReceiptsRLP(hash common.Hash) rlp.RawValue { number := rawdb.ReadHeaderNumber(bc.db, hash) if number == nil { return nil } - return rawdb.ReadRawReceipts(bc.db, hash, *number) + return rawdb.ReadReceiptsRLP(bc.db, hash, *number) } // GetUnclesInChain retrieves all the uncles from a given block backwards until diff --git a/core/blockchain_test.go b/core/blockchain_test.go index b981c33f21..434b494490 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -734,7 +734,7 @@ func testFastVsFullChains(t *testing.T, scheme string) { fast, _ := NewBlockChain(fastDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer fast.Stop() - if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil { + if n, err := fast.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } // Freezer style fast import the chain. @@ -747,7 +747,7 @@ func testFastVsFullChains(t *testing.T, scheme string) { ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer ancient.Stop() - if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil { + if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(len(blocks)/2)); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } @@ -871,7 +871,7 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) { fast, _ := NewBlockChain(fastDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer fast.Stop() - if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil { + if n, err := fast.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } assert(t, "fast", fast, height, height, 0) @@ -884,7 +884,7 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) { ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) defer ancient.Stop() - if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil { + if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(3*len(blocks)/4)); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } assert(t, "ancient", ancient, height, height, 0) @@ -1696,7 +1696,7 @@ func testBlockchainRecovery(t *testing.T, scheme string) { defer ancientDb.Close() ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil) - if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil { + if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(3*len(blocks)/4)); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior @@ -1991,7 +1991,7 @@ func testInsertKnownChainData(t *testing.T, typ string, scheme string) { } } else if typ == "receipts" { inserter = func(blocks []*types.Block, receipts []types.Receipts) error { - _, err = chain.InsertReceiptChain(blocks, receipts, 0) + _, err = chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0) return err } asserter = func(t *testing.T, block *types.Block) { @@ -2157,7 +2157,7 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i } } else if typ == "receipts" { inserter = func(blocks []*types.Block, receipts []types.Receipts) error { - _, err = chain.InsertReceiptChain(blocks, receipts, 0) + _, err = chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0) return err } asserter = func(t *testing.T, block *types.Block) { @@ -4205,10 +4205,10 @@ func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) { chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil) defer chain.Stop() - if n, err := chain.InsertReceiptChain(blocks, receipts, ancientLimit); err != nil { + if n, err := chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), ancientLimit); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } - if n, err := chain.InsertReceiptChain(chainA, receiptsA, ancientLimit); err != nil { + if n, err := chain.InsertReceiptChain(chainA, types.EncodeBlockReceiptLists(receiptsA), ancientLimit); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } // If the common ancestor is below the ancient limit, rewind the chain head. @@ -4218,7 +4218,7 @@ func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) { rawdb.WriteLastPivotNumber(db, ancestor) chain.SetHead(ancestor) } - if n, err := chain.InsertReceiptChain(chainB, receiptsB, ancientLimit); err != nil { + if n, err := chain.InsertReceiptChain(chainB, types.EncodeBlockReceiptLists(receiptsB), ancientLimit); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } head := chain.CurrentSnapBlock() @@ -4336,7 +4336,7 @@ func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64, if n, err := chain.InsertHeadersBeforeCutoff(headersBefore); err != nil { t.Fatalf("failed to insert headers before cutoff %d: %v", n, err) } - if n, err := chain.InsertReceiptChain(blocksAfter, receiptsAfter, ancientLimit); err != nil { + if n, err := chain.InsertReceiptChain(blocksAfter, types.EncodeBlockReceiptLists(receiptsAfter), ancientLimit); err != nil { t.Fatalf("failed to insert receipt %d: %v", n, err) } headSnap := chain.CurrentSnapBlock() diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go index 874ff19e31..433ca07cd0 100644 --- a/core/filtermaps/chain_view.go +++ b/core/filtermaps/chain_view.go @@ -29,7 +29,7 @@ type blockchain interface { GetHeader(hash common.Hash, number uint64) *types.Header GetCanonicalHash(number uint64) common.Hash GetReceiptsByHash(hash common.Hash) types.Receipts - GetRawReceiptsByHash(hash common.Hash) types.Receipts + GetRawReceipts(hash common.Hash, number uint64) types.Receipts } // ChainView represents an immutable view of a chain with a block id and a set @@ -117,7 +117,7 @@ func (cv *ChainView) RawReceipts(number uint64) types.Receipts { log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber) return nil } - return cv.chain.GetRawReceiptsByHash(blockHash) + return cv.chain.GetRawReceipts(blockHash, number) } // SharedRange returns the block range shared by two chain views. diff --git a/core/filtermaps/indexer_test.go b/core/filtermaps/indexer_test.go index 2782b2cbe6..5ed397a90e 100644 --- a/core/filtermaps/indexer_test.go +++ b/core/filtermaps/indexer_test.go @@ -515,7 +515,7 @@ func (tc *testChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return tc.receipts[hash] } -func (tc *testChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts { +func (tc *testChain) GetRawReceipts(hash common.Hash, number uint64) types.Receipts { tc.lock.RLock() defer tc.lock.RUnlock() diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 2f62d86e4b..2386246caf 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -545,8 +545,8 @@ func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawVa } // ReadRawReceipts retrieves all the transaction receipts belonging to a block. -// The receipt metadata fields are not guaranteed to be populated, so they -// should not be used. Use ReadReceipts instead if the metadata is needed. +// The receipt metadata fields and the Bloom are not guaranteed to be populated, +// so they should not be used. Use ReadReceipts instead if the metadata is needed. func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts { // Retrieve the flattened receipt slice data := ReadReceiptsRLP(db, hash, number) @@ -621,6 +621,14 @@ func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rec } } +// WriteRawReceipts stores all the transaction receipts belonging to a block. +func WriteRawReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts rlp.RawValue) { + // Store the flattened receipt slice + if err := db.Put(blockReceiptsKey(number, hash), receipts); err != nil { + log.Crit("Failed to store block receipts", "err", err) + } +} + // DeleteReceipts removes all receipt data associated with a block hash. func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { @@ -701,18 +709,11 @@ func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { } // WriteAncientBlocks writes entire block data into ancient store and returns the total written size. -func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []types.Receipts) (int64, error) { - var stReceipts []*types.ReceiptForStorage - +func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []rlp.RawValue) (int64, error) { return db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i, block := range blocks { - // Convert receipts to storage format and sum up total difficulty. - stReceipts = stReceipts[:0] - for _, receipt := range receipts[i] { - stReceipts = append(stReceipts, (*types.ReceiptForStorage)(receipt)) - } header := block.Header() - if err := writeAncientBlock(op, block, header, stReceipts); err != nil { + if err := writeAncientBlock(op, block, header, receipts[i]); err != nil { return err } } @@ -720,7 +721,7 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts }) } -func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts []*types.ReceiptForStorage) error { +func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts rlp.RawValue) error { num := block.NumberU64() if err := op.AppendRaw(ChainFreezerHashTable, num, block.Hash().Bytes()); err != nil { return fmt.Errorf("can't add block %d hash: %v", num, err) diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 247e277582..d98fc9a1eb 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -377,7 +377,11 @@ func TestBlockReceiptStorage(t *testing.T) { t.Fatalf("receipts returned when body was deleted: %v", rs) } // Ensure that receipts without metadata can be returned without the block body too - if err := checkReceiptsRLP(ReadRawReceipts(db, hash, 0), receipts); err != nil { + raw := ReadRawReceipts(db, hash, 0) + for _, r := range raw { + r.Bloom = types.CreateBloom(r) + } + if err := checkReceiptsRLP(raw, receipts); err != nil { t.Fatal(err) } // Sanity check that body alone without the receipt is a full purge @@ -439,7 +443,7 @@ func TestAncientStorage(t *testing.T) { } // Write and verify the header in the database - WriteAncientBlocks(db, []*types.Block{block}, []types.Receipts{nil}) + WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil})) if blob := ReadHeaderRLP(db, hash, number); len(blob) == 0 { t.Fatalf("no header returned") @@ -609,7 +613,7 @@ func BenchmarkWriteAncientBlocks(b *testing.B) { blocks := allBlocks[i : i+length] receipts := batchReceipts[:length] - writeSize, err := WriteAncientBlocks(db, blocks, receipts) + writeSize, err := WriteAncientBlocks(db, blocks, types.EncodeBlockReceiptLists(receipts)) if err != nil { b.Fatal(err) } @@ -909,7 +913,7 @@ func TestHeadersRLPStorage(t *testing.T) { } receipts := make([]types.Receipts, 100) // Write first half to ancients - WriteAncientBlocks(db, chain[:50], receipts[:50]) + WriteAncientBlocks(db, chain[:50], types.EncodeBlockReceiptLists(receipts[:50])) // Write second half to db for i := 50; i < 100; i++ { WriteCanonicalHash(db, chain[i].Hash(), chain[i].NumberU64()) diff --git a/core/txindexer_test.go b/core/txindexer_test.go index 6543ff429d..615a34de41 100644 --- a/core/txindexer_test.go +++ b/core/txindexer_test.go @@ -117,7 +117,7 @@ func TestTxIndexer(t *testing.T) { } for _, c := range cases { db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) - rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...)) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), types.EncodeBlockReceiptLists(append([]types.Receipts{{}}, receipts...))) // Index the initial blocks from ancient store indexer := &txIndexer{ @@ -236,7 +236,8 @@ func TestTxIndexerRepair(t *testing.T) { } for _, c := range cases { db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) - rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...)) + encReceipts := types.EncodeBlockReceiptLists(append([]types.Receipts{{}}, receipts...)) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), encReceipts) // Index the initial blocks from ancient store indexer := &txIndexer{ @@ -426,7 +427,8 @@ func TestTxIndexerReport(t *testing.T) { } for _, c := range cases { db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) - rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...)) + encReceipts := types.EncodeBlockReceiptLists(append([]types.Receipts{{}}, receipts...)) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), encReceipts) // Index the initial blocks from ancient store indexer := &txIndexer{ diff --git a/core/types/bloom9.go b/core/types/bloom9.go index 962ba46d47..5a6e49c220 100644 --- a/core/types/bloom9.go +++ b/core/types/bloom9.go @@ -59,11 +59,12 @@ func (b *Bloom) SetBytes(d []byte) { // Add adds d to the filter. Future calls of Test(d) will return true. func (b *Bloom) Add(d []byte) { - b.add(d, make([]byte, 6)) + var buf [6]byte + b.AddWithBuffer(d, &buf) } // add is internal version of Add, which takes a scratch buffer for reuse (needs to be at least 6 bytes) -func (b *Bloom) add(d []byte, buf []byte) { +func (b *Bloom) AddWithBuffer(d []byte, buf *[6]byte) { i1, v1, i2, v2, i3, v3 := bloomValues(d, buf) b[i1] |= v1 b[i2] |= v2 @@ -84,7 +85,8 @@ func (b Bloom) Bytes() []byte { // Test checks if the given topic is present in the bloom filter func (b Bloom) Test(topic []byte) bool { - i1, v1, i2, v2, i3, v3 := bloomValues(topic, make([]byte, 6)) + var buf [6]byte + i1, v1, i2, v2, i3, v3 := bloomValues(topic, &buf) return v1 == v1&b[i1] && v2 == v2&b[i2] && v3 == v3&b[i3] @@ -104,12 +106,12 @@ func (b *Bloom) UnmarshalText(input []byte) error { func CreateBloom(receipt *Receipt) Bloom { var ( bin Bloom - buf = make([]byte, 6) + buf [6]byte ) for _, log := range receipt.Logs { - bin.add(log.Address.Bytes(), buf) + bin.AddWithBuffer(log.Address.Bytes(), &buf) for _, b := range log.Topics { - bin.add(b[:], buf) + bin.AddWithBuffer(b[:], &buf) } } return bin @@ -139,21 +141,20 @@ func Bloom9(data []byte) []byte { } // bloomValues returns the bytes (index-value pairs) to set for the given data -func bloomValues(data []byte, hashbuf []byte) (uint, byte, uint, byte, uint, byte) { +func bloomValues(data []byte, hashbuf *[6]byte) (uint, byte, uint, byte, uint, byte) { sha := hasherPool.Get().(crypto.KeccakState) sha.Reset() sha.Write(data) - sha.Read(hashbuf) + sha.Read(hashbuf[:]) hasherPool.Put(sha) // The actual bits to flip v1 := byte(1 << (hashbuf[1] & 0x7)) v2 := byte(1 << (hashbuf[3] & 0x7)) v3 := byte(1 << (hashbuf[5] & 0x7)) // The indices for the bytes to OR in - i1 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf)&0x7ff)>>3) - 1 + i1 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf[0:])&0x7ff)>>3) - 1 i2 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf[2:])&0x7ff)>>3) - 1 i3 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf[4:])&0x7ff)>>3) - 1 - return i1, v1, i2, v2, i3, v3 } diff --git a/core/types/receipt.go b/core/types/receipt.go index e52a0c6477..ec99fbf888 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" ) @@ -258,7 +259,7 @@ func (r *Receipt) Size() common.StorageSize { } // ReceiptForStorage is a wrapper around a Receipt with RLP serialization -// that omits the Bloom field and deserialization that re-computes it. +// that omits the Bloom field. The Bloom field is recomputed by DeriveFields. type ReceiptForStorage Receipt // EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt @@ -291,7 +292,6 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { } r.CumulativeGasUsed = stored.CumulativeGasUsed r.Logs = stored.Logs - r.Bloom = CreateBloom((*Receipt)(r)) return nil } @@ -372,6 +372,26 @@ func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, nu rs[i].Logs[j].Index = logIndex logIndex++ } + // also derive the Bloom if not derived yet + rs[i].Bloom = CreateBloom(rs[i]) } return nil } + +// EncodeBlockReceiptLists encodes a list of block receipt lists into RLP. +func EncodeBlockReceiptLists(receipts []Receipts) []rlp.RawValue { + var storageReceipts []*ReceiptForStorage + result := make([]rlp.RawValue, len(receipts)) + for i, receipt := range receipts { + storageReceipts = storageReceipts[:0] + for _, r := range receipt { + storageReceipts = append(storageReceipts, (*ReceiptForStorage)(r)) + } + bytes, err := rlp.EncodeToBytes(storageReceipts) + if err != nil { + log.Crit("Failed to encode block receipts", "err", err) + } + result[i] = bytes + } + return result +} diff --git a/core/types/receipt_test.go b/core/types/receipt_test.go index 78b43c7e49..06cd0ff14c 100644 --- a/core/types/receipt_test.go +++ b/core/types/receipt_test.go @@ -22,6 +22,7 @@ import ( "math" "math/big" "reflect" + "sync" "testing" "github.com/ethereum/go-ethereum/common" @@ -154,148 +155,161 @@ var ( blockNumber = big.NewInt(1) blockTime = uint64(2) blockHash = common.BytesToHash([]byte{0x03, 0x14}) - - // Create the corresponding receipts - receipts = Receipts{ - &Receipt{ - Status: ReceiptStatusFailed, - CumulativeGasUsed: 1, - Logs: []*Log{ - { - Address: common.BytesToAddress([]byte{0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - // derived fields: - BlockNumber: blockNumber.Uint64(), - TxHash: txs[0].Hash(), - TxIndex: 0, - BlockHash: blockHash, - Index: 0, - }, - { - Address: common.BytesToAddress([]byte{0x01, 0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - // derived fields: - BlockNumber: blockNumber.Uint64(), - TxHash: txs[0].Hash(), - TxIndex: 0, - BlockHash: blockHash, - Index: 1, - }, - }, - // derived fields: - TxHash: txs[0].Hash(), - ContractAddress: common.HexToAddress("0x5a443704dd4b594b382c22a083e2bd3090a6fef3"), - GasUsed: 1, - EffectiveGasPrice: big.NewInt(11), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 0, - }, - &Receipt{ - PostState: common.Hash{2}.Bytes(), - CumulativeGasUsed: 3, - Logs: []*Log{ - { - Address: common.BytesToAddress([]byte{0x22}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - // derived fields: - BlockNumber: blockNumber.Uint64(), - TxHash: txs[1].Hash(), - TxIndex: 1, - BlockHash: blockHash, - Index: 2, - }, - { - Address: common.BytesToAddress([]byte{0x02, 0x22}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - // derived fields: - BlockNumber: blockNumber.Uint64(), - TxHash: txs[1].Hash(), - TxIndex: 1, - BlockHash: blockHash, - Index: 3, - }, - }, - // derived fields: - TxHash: txs[1].Hash(), - GasUsed: 2, - EffectiveGasPrice: big.NewInt(22), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 1, - }, - &Receipt{ - Type: AccessListTxType, - PostState: common.Hash{3}.Bytes(), - CumulativeGasUsed: 6, - Logs: []*Log{}, - // derived fields: - TxHash: txs[2].Hash(), - GasUsed: 3, - EffectiveGasPrice: big.NewInt(33), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 2, - }, - &Receipt{ - Type: DynamicFeeTxType, - PostState: common.Hash{4}.Bytes(), - CumulativeGasUsed: 10, - Logs: []*Log{}, - // derived fields: - TxHash: txs[3].Hash(), - GasUsed: 4, - EffectiveGasPrice: big.NewInt(1044), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 3, - }, - &Receipt{ - Type: DynamicFeeTxType, - PostState: common.Hash{5}.Bytes(), - CumulativeGasUsed: 15, - Logs: []*Log{}, - // derived fields: - TxHash: txs[4].Hash(), - GasUsed: 5, - EffectiveGasPrice: big.NewInt(1055), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 4, - }, - &Receipt{ - Type: BlobTxType, - PostState: common.Hash{6}.Bytes(), - CumulativeGasUsed: 21, - Logs: []*Log{}, - // derived fields: - TxHash: txs[5].Hash(), - GasUsed: 6, - EffectiveGasPrice: big.NewInt(1066), - BlobGasUsed: params.BlobTxBlobGasPerBlob, - BlobGasPrice: big.NewInt(920), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 5, - }, - &Receipt{ - Type: BlobTxType, - PostState: common.Hash{7}.Bytes(), - CumulativeGasUsed: 28, - Logs: []*Log{}, - // derived fields: - TxHash: txs[6].Hash(), - GasUsed: 7, - EffectiveGasPrice: big.NewInt(1077), - BlobGasUsed: 3 * params.BlobTxBlobGasPerBlob, - BlobGasPrice: big.NewInt(920), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 6, - }, - } ) +var receiptsOnce sync.Once +var testReceipts Receipts + +func getTestReceipts() Receipts { + // Compute the blooms only once + receiptsOnce.Do(func() { + // Create the corresponding receipts + r := Receipts{ + &Receipt{ + Status: ReceiptStatusFailed, + CumulativeGasUsed: 1, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[0].Hash(), + TxIndex: 0, + BlockHash: blockHash, + Index: 0, + }, + { + Address: common.BytesToAddress([]byte{0x01, 0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[0].Hash(), + TxIndex: 0, + BlockHash: blockHash, + Index: 1, + }, + }, + // derived fields: + TxHash: txs[0].Hash(), + ContractAddress: common.HexToAddress("0x5a443704dd4b594b382c22a083e2bd3090a6fef3"), + GasUsed: 1, + EffectiveGasPrice: big.NewInt(11), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 0, + }, + &Receipt{ + PostState: common.Hash{2}.Bytes(), + CumulativeGasUsed: 3, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x22}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[1].Hash(), + TxIndex: 1, + BlockHash: blockHash, + Index: 2, + }, + { + Address: common.BytesToAddress([]byte{0x02, 0x22}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[1].Hash(), + TxIndex: 1, + BlockHash: blockHash, + Index: 3, + }, + }, + // derived fields: + TxHash: txs[1].Hash(), + GasUsed: 2, + EffectiveGasPrice: big.NewInt(22), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 1, + }, + &Receipt{ + Type: AccessListTxType, + PostState: common.Hash{3}.Bytes(), + CumulativeGasUsed: 6, + Logs: []*Log{}, + // derived fields: + TxHash: txs[2].Hash(), + GasUsed: 3, + EffectiveGasPrice: big.NewInt(33), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 2, + }, + &Receipt{ + Type: DynamicFeeTxType, + PostState: common.Hash{4}.Bytes(), + CumulativeGasUsed: 10, + Logs: []*Log{}, + // derived fields: + TxHash: txs[3].Hash(), + GasUsed: 4, + EffectiveGasPrice: big.NewInt(1044), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 3, + }, + &Receipt{ + Type: DynamicFeeTxType, + PostState: common.Hash{5}.Bytes(), + CumulativeGasUsed: 15, + Logs: []*Log{}, + // derived fields: + TxHash: txs[4].Hash(), + GasUsed: 5, + EffectiveGasPrice: big.NewInt(1055), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 4, + }, + &Receipt{ + Type: BlobTxType, + PostState: common.Hash{6}.Bytes(), + CumulativeGasUsed: 21, + Logs: []*Log{}, + // derived fields: + TxHash: txs[5].Hash(), + GasUsed: 6, + EffectiveGasPrice: big.NewInt(1066), + BlobGasUsed: params.BlobTxBlobGasPerBlob, + BlobGasPrice: big.NewInt(920), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 5, + }, + &Receipt{ + Type: BlobTxType, + PostState: common.Hash{7}.Bytes(), + CumulativeGasUsed: 28, + Logs: []*Log{}, + // derived fields: + TxHash: txs[6].Hash(), + GasUsed: 7, + EffectiveGasPrice: big.NewInt(1077), + BlobGasUsed: 3 * params.BlobTxBlobGasPerBlob, + BlobGasPrice: big.NewInt(920), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 6, + }, + } + for _, receipt := range r { + receipt.Bloom = CreateBloom(receipt) + } + testReceipts = r + }) + return testReceipts +} + func TestDecodeEmptyTypedReceipt(t *testing.T) { input := []byte{0x80} var r Receipt @@ -310,6 +324,7 @@ func TestDeriveFields(t *testing.T) { // Re-derive receipts. basefee := big.NewInt(1000) blobGasPrice := big.NewInt(920) + receipts := getTestReceipts() derivedReceipts := clearComputedFieldsOnReceipts(receipts) err := Receipts(derivedReceipts).DeriveFields(params.TestChainConfig, blockHash, blockNumber.Uint64(), blockTime, basefee, blobGasPrice, txs) if err != nil { @@ -335,6 +350,7 @@ func TestDeriveFields(t *testing.T) { // Test that we can marshal/unmarshal receipts to/from json without errors. // This also confirms that our test receipts contain all the required fields. func TestReceiptJSON(t *testing.T) { + receipts := getTestReceipts() for i := range receipts { b, err := receipts[i].MarshalJSON() if err != nil { @@ -351,6 +367,7 @@ func TestReceiptJSON(t *testing.T) { // Test we can still parse receipt without EffectiveGasPrice for backwards compatibility, even // though it is required per the spec. func TestEffectiveGasPriceNotRequired(t *testing.T) { + receipts := getTestReceipts() r := *receipts[0] r.EffectiveGasPrice = nil b, err := r.MarshalJSON() @@ -511,6 +528,7 @@ func clearComputedFieldsOnReceipt(receipt *Receipt) *Receipt { cpy.EffectiveGasPrice = big.NewInt(0) cpy.BlobGasUsed = 0 cpy.BlobGasPrice = nil + cpy.Bloom = CreateBloom(&cpy) return &cpy } diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 4d13ae304c..762fb9283e 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/triedb" ) @@ -202,7 +203,7 @@ type BlockChain interface { // into the local chain. Blocks older than the specified `ancientLimit` // are stored directly in the ancient store, while newer blocks are stored // in the live key-value store. - InsertReceiptChain(types.Blocks, []types.Receipts, uint64) (int, error) + InsertReceiptChain(types.Blocks, []rlp.RawValue, uint64) (int, error) // Snapshots returns the blockchain snapshot tree to paused it during sync. Snapshots() *snapshot.Tree @@ -1034,7 +1035,7 @@ func (d *Downloader) commitSnapSyncData(results []*fetchResult, stateSync *state "lastnumn", last.Number, "lasthash", last.Hash(), ) blocks := make([]*types.Block, len(results)) - receipts := make([]types.Receipts, len(results)) + receipts := make([]rlp.RawValue, len(results)) for i, result := range results { blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.body()) receipts[i] = result.Receipts @@ -1051,7 +1052,7 @@ func (d *Downloader) commitPivotBlock(result *fetchResult) error { 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 - if _, err := d.blockchain.InsertReceiptChain([]*types.Block{block}, []types.Receipts{result.Receipts}, d.ancientLimit); err != nil { + if _, err := d.blockchain.InsertReceiptChain([]*types.Block{block}, []rlp.RawValue{result.Receipts}, d.ancientLimit); err != nil { return err } if err := d.blockchain.SnapSyncCommitHead(block.Hash()); err != nil { diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 3a145b1958..ecc820fd35 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -255,23 +255,24 @@ func (dlp *downloadTesterPeer) RequestBodies(hashes []common.Hash, sink chan *et // peer in the download tester. The returned function can be used to retrieve // batches of block receipts from the particularly requested peer. func (dlp *downloadTesterPeer) RequestReceipts(hashes []common.Hash, sink chan *eth.Response) (*eth.Request, error) { - blobs := eth.ServiceGetReceiptsQuery(dlp.chain, hashes) + blobs := eth.ServiceGetReceiptsQuery68(dlp.chain, hashes) - receipts := make([][]*types.Receipt, len(blobs)) + receipts := make([]types.Receipts, len(blobs)) for i, blob := range blobs { rlp.DecodeBytes(blob, &receipts[i]) } hasher := trie.NewStackTrie(nil) hashes = make([]common.Hash, len(receipts)) for i, receipt := range receipts { - hashes[i] = types.DeriveSha(types.Receipts(receipt), hasher) + hashes[i] = types.DeriveSha(receipt, hasher) } req := ð.Request{ Peer: dlp.id, } + resp := eth.ReceiptsRLPResponse(types.EncodeBlockReceiptLists(receipts)) res := ð.Response{ Req: req, - Res: (*eth.ReceiptsResponse)(&receipts), + Res: &resp, Meta: hashes, Time: 1, Done: make(chan error, 1), // Ignore the returned status diff --git a/eth/downloader/fetchers_concurrent_receipts.go b/eth/downloader/fetchers_concurrent_receipts.go index 3169f030ba..dbea30e881 100644 --- a/eth/downloader/fetchers_concurrent_receipts.go +++ b/eth/downloader/fetchers_concurrent_receipts.go @@ -88,7 +88,7 @@ func (q *receiptQueue) request(peer *peerConnection, req *fetchRequest, resCh ch // deliver is responsible for taking a generic response packet from the concurrent // fetcher, unpacking the receipt data and delivering it to the downloader's queue. func (q *receiptQueue) deliver(peer *peerConnection, packet *eth.Response) (int, error) { - receipts := *packet.Res.(*eth.ReceiptsResponse) + receipts := *packet.Res.(*eth.ReceiptsRLPResponse) hashes := packet.Meta.([]common.Hash) // {receipt hashes} accepted, err := q.queue.DeliverReceipts(peer.id, receipts, hashes) diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 000ad97ca9..bd7acadfc4 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" ) const ( @@ -69,7 +70,7 @@ type fetchResult struct { Header *types.Header Uncles []*types.Header Transactions types.Transactions - Receipts types.Receipts + Receipts rlp.RawValue Withdrawals types.Withdrawals } @@ -318,9 +319,7 @@ func (q *queue) Results(block bool) []*fetchResult { for _, uncle := range result.Uncles { size += uncle.Size() } - for _, receipt := range result.Receipts { - size += receipt.Size() - } + size += common.StorageSize(len(result.Receipts)) for _, tx := range result.Transactions { size += common.StorageSize(tx.Size()) } @@ -631,7 +630,7 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListH // DeliverReceipts injects a receipt retrieval response into the results queue. // The method returns the number of transaction receipts accepted from the delivery // and also wakes any threads waiting for data delivery. -func (q *queue) DeliverReceipts(id string, receiptList [][]*types.Receipt, receiptListHashes []common.Hash) (int, error) { +func (q *queue) DeliverReceipts(id string, receiptList []rlp.RawValue, receiptListHashes []common.Hash) (int, error) { q.lock.Lock() defer q.lock.Unlock() diff --git a/eth/downloader/queue_test.go b/eth/downloader/queue_test.go index 857ac4813a..854acf3d8f 100644 --- a/eth/downloader/queue_test.go +++ b/eth/downloader/queue_test.go @@ -358,16 +358,16 @@ func XTestDelivery(t *testing.T) { for { f, _, _ := q.ReserveReceipts(peer, rand.Intn(50)) if f != nil { - var rcs [][]*types.Receipt + var rcs []types.Receipts for _, hdr := range f.Headers { rcs = append(rcs, world.getReceipts(hdr.Number.Uint64())) } hasher := trie.NewStackTrie(nil) hashes := make([]common.Hash, len(rcs)) for i, receipt := range rcs { - hashes[i] = types.DeriveSha(types.Receipts(receipt), hasher) + hashes[i] = types.DeriveSha(receipt, hasher) } - _, err := q.DeliverReceipts(peer.id, rcs, hashes) + _, err := q.DeliverReceipts(peer.id, types.EncodeBlockReceiptLists(rcs), hashes) if err != nil { fmt.Printf("delivered %d receipts %v\n", len(rcs), err) } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 122bdaeda4..85d4a33913 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -80,11 +80,8 @@ func (b *testBackend) GetReceiptsByHash(hash common.Hash) types.Receipts { return r } -func (b *testBackend) GetRawReceiptsByHash(hash common.Hash) types.Receipts { - if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil { - return rawdb.ReadRawReceipts(b.db, hash, *number) - } - return nil +func (b *testBackend) GetRawReceipts(hash common.Hash, number uint64) types.Receipts { + return rawdb.ReadRawReceipts(b.db, hash, number) } func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { diff --git a/eth/handler.go b/eth/handler.go index f563b47138..033a44b3bb 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -18,15 +18,16 @@ package eth import ( "errors" + "maps" "math" "math/big" + "slices" "sync" "sync/atomic" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" @@ -49,6 +50,9 @@ const ( // The number is referenced from the size of tx pool. txChanSize = 4096 + // chainHeadChanSize is the size of channel listening to ChainHeadEvent. + chainHeadChanSize = 128 + // txMaxBroadcastSize is the max size of a transaction that will be broadcasted. // All transactions with a higher size will be announced and need to be fetched // by the peer. @@ -104,9 +108,8 @@ type handlerConfig struct { } type handler struct { - nodeID enode.ID - networkID uint64 - forkFilter forkid.Filter // Fork ID filter, constant across the lifetime of the node + nodeID enode.ID + networkID uint64 snapSync atomic.Bool // Flag whether snap sync is enabled (gets disabled if we already have blocks) synced atomic.Bool // Flag whether we're considered synchronised (enables transaction processing) @@ -120,9 +123,10 @@ type handler struct { txFetcher *fetcher.TxFetcher peers *peerSet - eventMux *event.TypeMux - txsCh chan core.NewTxsEvent - txsSub event.Subscription + eventMux *event.TypeMux + txsCh chan core.NewTxsEvent + txsSub event.Subscription + blockRange *blockRangeState requiredBlocks map[uint64]common.Hash @@ -144,7 +148,6 @@ func newHandler(config *handlerConfig) (*handler, error) { h := &handler{ nodeID: config.NodeID, networkID: config.Network, - forkFilter: forkid.NewFilter(config.Chain), eventMux: config.EventMux, database: config.Database, txpool: config.TxPool, @@ -257,14 +260,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { } // Execute the Ethereum handshake - var ( - genesis = h.chain.Genesis() - head = h.chain.CurrentHeader() - hash = head.Hash() - number = head.Number.Uint64() - ) - forkID := forkid.NewID(h.chain.Config(), genesis, number, head.Time) - if err := peer.Handshake(h.networkID, hash, genesis.Hash(), forkID, h.forkFilter); err != nil { + if err := peer.Handshake(h.networkID, h.chain, h.blockRange.currentRange()); err != nil { peer.Log().Debug("Ethereum handshake failed", "err", err) return err } @@ -435,6 +431,11 @@ func (h *handler) Start(maxPeers int) { h.txsSub = h.txpool.SubscribeTransactions(h.txsCh, false) go h.txBroadcastLoop() + // broadcast block range + h.wg.Add(1) + h.blockRange = newBlockRangeState(h.chain, h.eventMux) + go h.blockRangeLoop(h.blockRange) + // start sync handlers h.txFetcher.Start() @@ -445,6 +446,7 @@ func (h *handler) Start(maxPeers int) { func (h *handler) Stop() { h.txsSub.Unsubscribe() // quits txBroadcastLoop + h.blockRange.stop() h.txFetcher.Stop() h.downloader.Terminate() @@ -566,3 +568,129 @@ func (h *handler) enableSyncedFeatures() { h.snapSync.Store(false) } } + +// blockRangeState holds the state of the block range update broadcasting mechanism. +type blockRangeState struct { + prev eth.BlockRangeUpdatePacket + next atomic.Pointer[eth.BlockRangeUpdatePacket] + headCh chan core.ChainHeadEvent + headSub event.Subscription + syncSub *event.TypeMuxSubscription +} + +func newBlockRangeState(chain *core.BlockChain, typeMux *event.TypeMux) *blockRangeState { + headCh := make(chan core.ChainHeadEvent, chainHeadChanSize) + headSub := chain.SubscribeChainHeadEvent(headCh) + syncSub := typeMux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{}) + st := &blockRangeState{ + headCh: headCh, + headSub: headSub, + syncSub: syncSub, + } + st.update(chain, chain.CurrentBlock()) + st.prev = *st.next.Load() + return st +} + +// blockRangeBroadcastLoop announces changes in locally-available block range to peers. +// The range to announce is the range that is available in the store, so it's not just +// about imported blocks. +func (h *handler) blockRangeLoop(st *blockRangeState) { + defer h.wg.Done() + + for { + select { + case ev := <-st.syncSub.Chan(): + if ev == nil { + continue + } + if _, ok := ev.Data.(downloader.StartEvent); ok && h.snapSync.Load() { + h.blockRangeWhileSnapSyncing(st) + } + case <-st.headCh: + st.update(h.chain, h.chain.CurrentBlock()) + if st.shouldSend() { + h.broadcastBlockRange(st) + } + case <-st.headSub.Err(): + return + } + } +} + +// blockRangeWhileSnapSyncing announces block range updates during snap sync. +// Here we poll the CurrentSnapBlock on a timer and announce updates to it. +func (h *handler) blockRangeWhileSnapSyncing(st *blockRangeState) { + tick := time.NewTicker(1 * time.Minute) + defer tick.Stop() + + for { + select { + case <-tick.C: + st.update(h.chain, h.chain.CurrentSnapBlock()) + if st.shouldSend() { + h.broadcastBlockRange(st) + } + // back to processing head block updates when sync is done + case ev := <-st.syncSub.Chan(): + if ev == nil { + continue + } + switch ev.Data.(type) { + case downloader.FailedEvent, downloader.DoneEvent: + return + } + // ignore head updates, but exit when the subscription ends + case <-st.headCh: + case <-st.headSub.Err(): + return + } + } +} + +// broadcastBlockRange sends a range update when one is due. +func (h *handler) broadcastBlockRange(state *blockRangeState) { + h.peers.lock.Lock() + peerlist := slices.Collect(maps.Values(h.peers.peers)) + h.peers.lock.Unlock() + if len(peerlist) == 0 { + return + } + msg := state.currentRange() + log.Debug("Sending BlockRangeUpdate", "peers", len(peerlist), "earliest", msg.EarliestBlock, "latest", msg.LatestBlock) + for _, p := range peerlist { + p.SendBlockRangeUpdate(msg) + } + state.prev = *state.next.Load() +} + +// update assigns the values of the next block range update from the chain. +func (st *blockRangeState) update(chain *core.BlockChain, latest *types.Header) { + earliest, _ := chain.HistoryPruningCutoff() + st.next.Store(ð.BlockRangeUpdatePacket{ + EarliestBlock: min(latest.Number.Uint64(), earliest), + LatestBlock: latest.Number.Uint64(), + LatestBlockHash: latest.Hash(), + }) +} + +// shouldSend decides whether it is time to send a block range update. We don't want to +// send these updates constantly, so they will usually only be sent every 32 blocks. +// However, there is a special case: if the range would move back, i.e. due to SetHead, we +// want to send it immediately. +func (st *blockRangeState) shouldSend() bool { + next := st.next.Load() + return next.LatestBlock < st.prev.LatestBlock || + next.LatestBlock-st.prev.LatestBlock >= 32 +} + +func (st *blockRangeState) stop() { + st.syncSub.Unsubscribe() + st.headSub.Unsubscribe() +} + +// currentRange returns the current block range. +// This is safe to call from any goroutine. +func (st *blockRangeState) currentRange() eth.BlockRangeUpdatePacket { + return *st.next.Load() +} diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index 8d572ca966..2446c5fccb 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -25,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -257,11 +256,7 @@ func testRecvTransactions(t *testing.T, protocol uint) { return eth.Handle((*ethHandler)(handler.handler), peer) }) // Run the handshake locally to avoid spinning up a source handler - var ( - genesis = handler.chain.Genesis() - head = handler.chain.CurrentBlock() - ) - if err := src.Handshake(1, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil { + if err := src.Handshake(1, handler.chain, eth.BlockRangeUpdatePacket{}); err != nil { t.Fatalf("failed to run protocol handshake") } // Send the transaction to the sink and verify that it's added to the tx pool @@ -316,11 +311,7 @@ func testSendTransactions(t *testing.T, protocol uint) { return eth.Handle((*ethHandler)(handler.handler), peer) }) // Run the handshake locally to avoid spinning up a source handler - var ( - genesis = handler.chain.Genesis() - head = handler.chain.CurrentBlock() - ) - if err := sink.Handshake(1, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil { + if err := sink.Handshake(1, handler.chain, eth.BlockRangeUpdatePacket{}); err != nil { t.Fatalf("failed to run protocol handshake") } // After the handshake completes, the source handler should stream the sink diff --git a/eth/peer.go b/eth/peer.go index 7618777716..5808c3a3c5 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -17,6 +17,7 @@ package eth import ( + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" ) @@ -25,6 +26,13 @@ import ( // about a connected peer. type ethPeerInfo struct { Version uint `json:"version"` // Ethereum protocol version negotiated + *peerBlockRange +} + +type peerBlockRange struct { + Earliest uint64 `json:"earliestBlock"` + Latest uint64 `json:"latestBlock"` + LatestHash common.Hash `json:"latestBlockHash"` } // ethPeer is a wrapper around eth.Peer to maintain a few extra metadata. @@ -35,9 +43,15 @@ type ethPeer struct { // info gathers and returns some `eth` protocol metadata known about a peer. func (p *ethPeer) info() *ethPeerInfo { - return ðPeerInfo{ - Version: p.Version(), + info := ðPeerInfo{Version: p.Version()} + if br := p.BlockRange(); br != nil { + info.peerBlockRange = &peerBlockRange{ + Earliest: br.EarliestBlock, + Latest: br.LatestBlock, + LatestHash: br.LatestBlockHash, + } } + return info } // snapPeerInfo represents a short summary of the `snap` sub-protocol metadata known diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index f2a3cb0292..2467e0c713 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -175,12 +175,26 @@ var eth68 = map[uint64]msgHandler{ BlockHeadersMsg: handleBlockHeaders, GetBlockBodiesMsg: handleGetBlockBodies, BlockBodiesMsg: handleBlockBodies, - GetReceiptsMsg: handleGetReceipts, - ReceiptsMsg: handleReceipts, + GetReceiptsMsg: handleGetReceipts68, + ReceiptsMsg: handleReceipts[*ReceiptList68], GetPooledTransactionsMsg: handleGetPooledTransactions, PooledTransactionsMsg: handlePooledTransactions, } +var eth69 = map[uint64]msgHandler{ + TransactionsMsg: handleTransactions, + NewPooledTransactionHashesMsg: handleNewPooledTransactionHashes, + GetBlockHeadersMsg: handleGetBlockHeaders, + BlockHeadersMsg: handleBlockHeaders, + GetBlockBodiesMsg: handleGetBlockBodies, + BlockBodiesMsg: handleBlockBodies, + GetReceiptsMsg: handleGetReceipts69, + ReceiptsMsg: handleReceipts[*ReceiptList69], + GetPooledTransactionsMsg: handleGetPooledTransactions, + PooledTransactionsMsg: handlePooledTransactions, + BlockRangeUpdateMsg: handleBlockRangeUpdate, +} + // handleMessage is invoked whenever an inbound message is received from a remote // peer. The remote connection is torn down upon returning any error. func handleMessage(backend Backend, peer *Peer) error { @@ -194,7 +208,14 @@ func handleMessage(backend Backend, peer *Peer) error { } defer msg.Discard() - var handlers = eth68 + var handlers map[uint64]msgHandler + if peer.version == ETH68 { + handlers = eth68 + } else if peer.version == ETH69 { + handlers = eth69 + } else { + return fmt.Errorf("unknown eth protocol version: %v", peer.version) + } // Track the amount of time it takes to serve the request and run the handler if metrics.Enabled() { diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index fa031d9899..2fa10dfa9d 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -529,22 +529,23 @@ func testGetBlockReceipts(t *testing.T, protocol uint) { // Collect the hashes to request, and the response to expect var ( hashes []common.Hash - receipts [][]*types.Receipt + receipts []*ReceiptList68 ) for i := uint64(0); i <= backend.chain.CurrentBlock().Number.Uint64(); i++ { block := backend.chain.GetBlockByNumber(i) - hashes = append(hashes, block.Hash()) - receipts = append(receipts, backend.chain.GetReceiptsByHash(block.Hash())) + trs := backend.chain.GetReceiptsByHash(block.Hash()) + receipts = append(receipts, NewReceiptList68(trs)) } + // Send the hash request and verify the response p2p.Send(peer.app, GetReceiptsMsg, &GetReceiptsPacket{ RequestId: 123, GetReceiptsRequest: hashes, }) - if err := p2p.ExpectMsg(peer.app, ReceiptsMsg, &ReceiptsPacket{ - RequestId: 123, - ReceiptsResponse: receipts, + if err := p2p.ExpectMsg(peer.app, ReceiptsMsg, &ReceiptsPacket[*ReceiptList68]{ + RequestId: 123, + List: receipts, }); err != nil { t.Errorf("receipts mismatch: %v", err) } @@ -612,10 +613,10 @@ func setup() (*testBackend, *testPeer) { } func FuzzEthProtocolHandlers(f *testing.F) { - handlers := eth68 + handlers := eth69 backend, peer := setup() f.Fuzz(func(t *testing.T, code byte, msg []byte) { - handler := handlers[uint64(code)%protocolLengths[ETH68]] + handler := handlers[uint64(code)%protocolLengths[ETH69]] if handler == nil { return } diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go index fda650da1c..15ad048bcf 100644 --- a/eth/protocols/eth/handlers.go +++ b/eth/protocols/eth/handlers.go @@ -20,20 +20,25 @@ import ( "encoding/json" "errors" "fmt" + "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" + "github.com/ethereum/go-ethereum/p2p/tracker" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" ) +// requestTracker is a singleton tracker for eth/66 and newer request times. +var requestTracker = tracker.New(ProtocolName, 5*time.Minute) + func handleGetBlockHeaders(backend Backend, msg Decoder, peer *Peer) error { // Decode the complex header query var query GetBlockHeadersPacket if err := msg.Decode(&query); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } response := ServiceGetBlockHeadersQuery(backend.Chain(), query.GetBlockHeadersRequest, peer) return peer.ReplyBlockHeadersRLP(query.RequestId, response) @@ -216,7 +221,7 @@ func handleGetBlockBodies(backend Backend, msg Decoder, peer *Peer) error { // Decode the block body retrieval message var query GetBlockBodiesPacket if err := msg.Decode(&query); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } response := ServiceGetBlockBodiesQuery(backend.Chain(), query.GetBlockBodiesRequest) return peer.ReplyBlockBodiesRLP(query.RequestId, response) @@ -243,19 +248,29 @@ func ServiceGetBlockBodiesQuery(chain *core.BlockChain, query GetBlockBodiesRequ return bodies } -func handleGetReceipts(backend Backend, msg Decoder, peer *Peer) error { +func handleGetReceipts68(backend Backend, msg Decoder, peer *Peer) error { // Decode the block receipts retrieval message var query GetReceiptsPacket if err := msg.Decode(&query); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } - response := ServiceGetReceiptsQuery(backend.Chain(), query.GetReceiptsRequest) + response := ServiceGetReceiptsQuery68(backend.Chain(), query.GetReceiptsRequest) return peer.ReplyReceiptsRLP(query.RequestId, response) } -// ServiceGetReceiptsQuery assembles the response to a receipt query. It is +func handleGetReceipts69(backend Backend, msg Decoder, peer *Peer) error { + // Decode the block receipts retrieval message + var query GetReceiptsPacket + if err := msg.Decode(&query); err != nil { + return err + } + response := serviceGetReceiptsQuery69(backend.Chain(), query.GetReceiptsRequest) + return peer.ReplyReceiptsRLP(query.RequestId, response) +} + +// ServiceGetReceiptsQuery68 assembles the response to a receipt query. It is // exposed to allow external packages to test protocol behavior. -func ServiceGetReceiptsQuery(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue { +func ServiceGetReceiptsQuery68(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue { // Gather state data until the fetch or network limits is reached var ( bytes int @@ -267,19 +282,62 @@ func ServiceGetReceiptsQuery(chain *core.BlockChain, query GetReceiptsRequest) [ break } // Retrieve the requested block's receipts - results := chain.GetReceiptsByHash(hash) + results := chain.GetReceiptsRLP(hash) if results == nil { if header := chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash { continue } - } - // If known, encode and queue for response packet - if encoded, err := rlp.EncodeToBytes(results); err != nil { - log.Error("Failed to encode receipt", "err", err) } else { - receipts = append(receipts, encoded) - bytes += len(encoded) + body := chain.GetBodyRLP(hash) + if body == nil { + continue + } + var err error + results, err = blockReceiptsToNetwork68(results, body) + if err != nil { + log.Error("Error in block receipts conversion", "hash", hash, "err", err) + continue + } } + receipts = append(receipts, results) + bytes += len(results) + } + return receipts +} + +// serviceGetReceiptsQuery69 assembles the response to a receipt query. +// It does not send the bloom filters for the receipts +func serviceGetReceiptsQuery69(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue { + // Gather state data until the fetch or network limits is reached + var ( + bytes int + receipts []rlp.RawValue + ) + for lookups, hash := range query { + if bytes >= softResponseLimit || len(receipts) >= maxReceiptsServe || + lookups >= 2*maxReceiptsServe { + break + } + // Retrieve the requested block's receipts + results := chain.GetReceiptsRLP(hash) + if results == nil { + if header := chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash { + continue + } + } else { + body := chain.GetBodyRLP(hash) + if body == nil { + continue + } + var err error + results, err = blockReceiptsToNetwork69(results, body) + if err != nil { + log.Error("Error in block receipts conversion", "hash", hash, "err", err) + continue + } + } + receipts = append(receipts, results) + bytes += len(results) } return receipts } @@ -296,7 +354,7 @@ func handleBlockHeaders(backend Backend, msg Decoder, peer *Peer) error { // A batch of headers arrived to one of our previous requests res := new(BlockHeadersPacket) if err := msg.Decode(res); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } metadata := func() interface{} { hashes := make([]common.Hash, len(res.BlockHeadersRequest)) @@ -316,7 +374,7 @@ func handleBlockBodies(backend Backend, msg Decoder, peer *Peer) error { // A batch of block bodies arrived to one of our previous requests res := new(BlockBodiesPacket) if err := msg.Decode(res); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } metadata := func() interface{} { var ( @@ -341,24 +399,35 @@ func handleBlockBodies(backend Backend, msg Decoder, peer *Peer) error { }, metadata) } -func handleReceipts(backend Backend, msg Decoder, peer *Peer) error { +func handleReceipts[L ReceiptsList](backend Backend, msg Decoder, peer *Peer) error { // A batch of receipts arrived to one of our previous requests - res := new(ReceiptsPacket) + res := new(ReceiptsPacket[L]) if err := msg.Decode(res); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } + // Assign temporary hashing buffer to each list item, the same buffer is shared + // between all receipt list instances. + buffers := new(receiptListBuffers) + for i := range res.List { + res.List[i].setBuffers(buffers) + } + metadata := func() interface{} { hasher := trie.NewStackTrie(nil) - hashes := make([]common.Hash, len(res.ReceiptsResponse)) - for i, receipt := range res.ReceiptsResponse { - hashes[i] = types.DeriveSha(types.Receipts(receipt), hasher) + hashes := make([]common.Hash, len(res.List)) + for i := range res.List { + hashes[i] = types.DeriveSha(res.List[i], hasher) } return hashes } + var enc ReceiptsRLPResponse + for i := range res.List { + enc = append(enc, res.List[i].EncodeForStorage()) + } return peer.dispatchResponse(&Response{ id: res.RequestId, code: ReceiptsMsg, - Res: &res.ReceiptsResponse, + Res: &enc, }, metadata) } @@ -370,10 +439,10 @@ func handleNewPooledTransactionHashes(backend Backend, msg Decoder, peer *Peer) } ann := new(NewPooledTransactionHashesPacket) if err := msg.Decode(ann); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } if len(ann.Hashes) != len(ann.Types) || len(ann.Hashes) != len(ann.Sizes) { - return fmt.Errorf("%w: message %v: invalid len of fields: %v %v %v", errDecode, msg, len(ann.Hashes), len(ann.Types), len(ann.Sizes)) + return fmt.Errorf("NewPooledTransactionHashes: invalid len of fields in %v %v %v", len(ann.Hashes), len(ann.Types), len(ann.Sizes)) } // Schedule all the unknown hashes for retrieval for _, hash := range ann.Hashes { @@ -386,7 +455,7 @@ func handleGetPooledTransactions(backend Backend, msg Decoder, peer *Peer) error // Decode the pooled transactions retrieval message var query GetPooledTransactionsPacket if err := msg.Decode(&query); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } hashes, txs := answerGetPooledTransactions(backend, query.GetPooledTransactionsRequest) return peer.ReplyPooledTransactionsRLP(query.RequestId, hashes, txs) @@ -423,12 +492,12 @@ func handleTransactions(backend Backend, msg Decoder, peer *Peer) error { // Transactions can be processed, parse all of them and deliver to the pool var txs TransactionsPacket if err := msg.Decode(&txs); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } for i, tx := range txs { // Validate and mark the remote transaction if tx == nil { - return fmt.Errorf("%w: transaction %d is nil", errDecode, i) + return fmt.Errorf("Transactions: transaction %d is nil", i) } peer.markTransaction(tx.Hash()) } @@ -443,12 +512,12 @@ func handlePooledTransactions(backend Backend, msg Decoder, peer *Peer) error { // Transactions can be processed, parse all of them and deliver to the pool var txs PooledTransactionsPacket if err := msg.Decode(&txs); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + return err } for i, tx := range txs.PooledTransactionsResponse { // Validate and mark the remote transaction if tx == nil { - return fmt.Errorf("%w: transaction %d is nil", errDecode, i) + return fmt.Errorf("PooledTransactions: transaction %d is nil", i) } peer.markTransaction(tx.Hash()) } @@ -456,3 +525,16 @@ func handlePooledTransactions(backend Backend, msg Decoder, peer *Peer) error { return backend.Handle(peer, &txs.PooledTransactionsResponse) } + +func handleBlockRangeUpdate(backend Backend, msg Decoder, peer *Peer) error { + var update BlockRangeUpdatePacket + if err := msg.Decode(&update); err != nil { + return err + } + if err := update.Validate(); err != nil { + return err + } + // We don't do anything with these messages for now, just store them on the peer. + peer.lastRange.Store(&update) + return nil +} diff --git a/eth/protocols/eth/handshake.go b/eth/protocols/eth/handshake.go index 0b6f110e3d..824e49fb2b 100644 --- a/eth/protocols/eth/handshake.go +++ b/eth/protocols/eth/handshake.go @@ -19,10 +19,10 @@ package eth import ( "errors" "fmt" - "math/big" "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/p2p" @@ -36,44 +36,122 @@ const ( // Handshake executes the eth protocol handshake, negotiating version number, // network IDs, difficulties, head and genesis blocks. -func (p *Peer) Handshake(network uint64, head common.Hash, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter) error { - // Send out own handshake in a new thread +func (p *Peer) Handshake(networkID uint64, chain *core.BlockChain, rangeMsg BlockRangeUpdatePacket) error { + switch p.version { + case ETH69: + return p.handshake69(networkID, chain, rangeMsg) + case ETH68: + return p.handshake68(networkID, chain) + default: + return errors.New("unsupported protocol version") + } +} + +func (p *Peer) handshake68(networkID uint64, chain *core.BlockChain) error { + var ( + genesis = chain.Genesis() + latest = chain.CurrentBlock() + forkID = forkid.NewID(chain.Config(), genesis, latest.Number.Uint64(), latest.Time) + forkFilter = forkid.NewFilter(chain) + ) errc := make(chan error, 2) - - var status StatusPacket // safe to read after two values have been received from errc - go func() { - errc <- p2p.Send(p.rw, StatusMsg, &StatusPacket{ + pkt := &StatusPacket68{ ProtocolVersion: uint32(p.version), - NetworkID: network, - TD: new(big.Int), // unknown for post-merge tail=pruned networks - Head: head, - Genesis: genesis, + NetworkID: networkID, + Head: latest.Hash(), + Genesis: genesis.Hash(), ForkID: forkID, - }) - }() - go func() { - errc <- p.readStatus(network, &status, genesis, forkFilter) - }() - timeout := time.NewTimer(handshakeTimeout) - defer timeout.Stop() - for i := 0; i < 2; i++ { - select { - case err := <-errc: - if err != nil { - markError(p, err) - return err - } - case <-timeout.C: - markError(p, p2p.DiscReadTimeout) - return p2p.DiscReadTimeout } + errc <- p2p.Send(p.rw, StatusMsg, pkt) + }() + var status StatusPacket68 // safe to read after two values have been received from errc + go func() { + errc <- p.readStatus68(networkID, &status, genesis.Hash(), forkFilter) + }() + + return waitForHandshake(errc, p) +} + +func (p *Peer) readStatus68(networkID uint64, status *StatusPacket68, genesis common.Hash, forkFilter forkid.Filter) error { + if err := p.readStatusMsg(status); err != nil { + return err + } + if status.NetworkID != networkID { + return fmt.Errorf("%w: %d (!= %d)", errNetworkIDMismatch, status.NetworkID, networkID) + } + if uint(status.ProtocolVersion) != p.version { + return fmt.Errorf("%w: %d (!= %d)", errProtocolVersionMismatch, status.ProtocolVersion, p.version) + } + if status.Genesis != genesis { + return fmt.Errorf("%w: %x (!= %x)", errGenesisMismatch, status.Genesis, genesis) + } + if err := forkFilter(status.ForkID); err != nil { + return fmt.Errorf("%w: %v", errForkIDRejected, err) } return nil } -// readStatus reads the remote handshake message. -func (p *Peer) readStatus(network uint64, status *StatusPacket, genesis common.Hash, forkFilter forkid.Filter) error { +func (p *Peer) handshake69(networkID uint64, chain *core.BlockChain, rangeMsg BlockRangeUpdatePacket) error { + var ( + genesis = chain.Genesis() + latest = chain.CurrentBlock() + forkID = forkid.NewID(chain.Config(), genesis, latest.Number.Uint64(), latest.Time) + forkFilter = forkid.NewFilter(chain) + ) + + errc := make(chan error, 2) + go func() { + pkt := &StatusPacket69{ + ProtocolVersion: uint32(p.version), + NetworkID: networkID, + Genesis: genesis.Hash(), + ForkID: forkID, + EarliestBlock: rangeMsg.EarliestBlock, + LatestBlock: rangeMsg.LatestBlock, + LatestBlockHash: rangeMsg.LatestBlockHash, + } + errc <- p2p.Send(p.rw, StatusMsg, pkt) + }() + var status StatusPacket69 // safe to read after two values have been received from errc + go func() { + errc <- p.readStatus69(networkID, &status, genesis.Hash(), forkFilter) + }() + + return waitForHandshake(errc, p) +} + +func (p *Peer) readStatus69(networkID uint64, status *StatusPacket69, genesis common.Hash, forkFilter forkid.Filter) error { + if err := p.readStatusMsg(status); err != nil { + return err + } + if status.NetworkID != networkID { + return fmt.Errorf("%w: %d (!= %d)", errNetworkIDMismatch, status.NetworkID, networkID) + } + if uint(status.ProtocolVersion) != p.version { + return fmt.Errorf("%w: %d (!= %d)", errProtocolVersionMismatch, status.ProtocolVersion, p.version) + } + if status.Genesis != genesis { + return fmt.Errorf("%w: %x (!= %x)", errGenesisMismatch, status.Genesis, genesis) + } + if err := forkFilter(status.ForkID); err != nil { + return fmt.Errorf("%w: %v", errForkIDRejected, err) + } + // Handle initial block range. + initRange := &BlockRangeUpdatePacket{ + EarliestBlock: status.EarliestBlock, + LatestBlock: status.LatestBlock, + LatestBlockHash: status.LatestBlockHash, + } + if err := initRange.Validate(); err != nil { + return fmt.Errorf("%w: %v", errInvalidBlockRange, err) + } + p.lastRange.Store(initRange) + return nil +} + +// readStatusMsg reads the first message on the connection. +func (p *Peer) readStatusMsg(dst any) error { msg, err := p.rw.ReadMsg() if err != nil { return err @@ -84,21 +162,26 @@ func (p *Peer) readStatus(network uint64, status *StatusPacket, genesis common.H if msg.Size > maxMessageSize { return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize) } - // Decode the handshake and make sure everything matches - if err := msg.Decode(&status); err != nil { - return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + if err := msg.Decode(dst); err != nil { + return err } - if status.NetworkID != network { - return fmt.Errorf("%w: %d (!= %d)", errNetworkIDMismatch, status.NetworkID, network) - } - if uint(status.ProtocolVersion) != p.version { - return fmt.Errorf("%w: %d (!= %d)", errProtocolVersionMismatch, status.ProtocolVersion, p.version) - } - if status.Genesis != genesis { - return fmt.Errorf("%w: %x (!= %x)", errGenesisMismatch, status.Genesis, genesis) - } - if err := forkFilter(status.ForkID); err != nil { - return fmt.Errorf("%w: %v", errForkIDRejected, err) + return nil +} + +func waitForHandshake(errc <-chan error, p *Peer) error { + timeout := time.NewTimer(handshakeTimeout) + defer timeout.Stop() + for range 2 { + select { + case err := <-errc: + if err != nil { + markError(p, err) + return err + } + case <-timeout.C: + markError(p, p2p.DiscReadTimeout) + return p2p.DiscReadTimeout + } } return nil } @@ -124,3 +207,14 @@ func markError(p *Peer, err error) { m.peerError.Mark(1) } } + +// Validate checks basic validity of a block range announcement. +func (p *BlockRangeUpdatePacket) Validate() error { + if p.EarliestBlock > p.LatestBlock { + return errors.New("earliest > latest") + } + if p.LatestBlockHash == (common.Hash{}) { + return errors.New("zero latest hash") + } + return nil +} diff --git a/eth/protocols/eth/handshake_test.go b/eth/protocols/eth/handshake_test.go index 1d1de3ec16..2fab3ea5a8 100644 --- a/eth/protocols/eth/handshake_test.go +++ b/eth/protocols/eth/handshake_test.go @@ -52,19 +52,19 @@ func testHandshake(t *testing.T, protocol uint) { want: errNoStatusMsg, }, { - code: StatusMsg, data: StatusPacket{10, 1, new(big.Int), head.Hash(), genesis.Hash(), forkID}, + code: StatusMsg, data: StatusPacket68{10, 1, new(big.Int), head.Hash(), genesis.Hash(), forkID}, want: errProtocolVersionMismatch, }, { - code: StatusMsg, data: StatusPacket{uint32(protocol), 999, new(big.Int), head.Hash(), genesis.Hash(), forkID}, + code: StatusMsg, data: StatusPacket68{uint32(protocol), 999, new(big.Int), head.Hash(), genesis.Hash(), forkID}, want: errNetworkIDMismatch, }, { - code: StatusMsg, data: StatusPacket{uint32(protocol), 1, new(big.Int), head.Hash(), common.Hash{3}, forkID}, + code: StatusMsg, data: StatusPacket68{uint32(protocol), 1, new(big.Int), head.Hash(), common.Hash{3}, forkID}, want: errGenesisMismatch, }, { - code: StatusMsg, data: StatusPacket{uint32(protocol), 1, new(big.Int), head.Hash(), genesis.Hash(), forkid.ID{Hash: [4]byte{0x00, 0x01, 0x02, 0x03}}}, + code: StatusMsg, data: StatusPacket68{uint32(protocol), 1, new(big.Int), head.Hash(), genesis.Hash(), forkid.ID{Hash: [4]byte{0x00, 0x01, 0x02, 0x03}}}, want: errForkIDRejected, }, } @@ -80,7 +80,7 @@ func testHandshake(t *testing.T, protocol uint) { // Send the junk test with one peer, check the handshake failure go p2p.Send(app, test.code, test.data) - err := peer.Handshake(1, head.Hash(), genesis.Hash(), forkID, forkid.NewFilter(backend.chain)) + err := peer.Handshake(1, backend.chain, BlockRangeUpdatePacket{}) if err == nil { t.Errorf("test %d: protocol returned nil error, want %q", i, test.want) } else if !errors.Is(err, test.want) { diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index 31a35eb186..40c54a3570 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -18,6 +18,7 @@ package eth import ( "math/rand" + "sync/atomic" mapset "github.com/deckarep/golang-set/v2" "github.com/ethereum/go-ethereum/common" @@ -47,6 +48,7 @@ type Peer struct { *p2p.Peer // The embedded P2P package peer rw p2p.MsgReadWriter // Input/output streams for snap version uint // Protocol version negotiated + lastRange atomic.Pointer[BlockRangeUpdatePacket] txpool TxPool // Transaction pool used by the broadcasters for liveness checks knownTxs *knownCache // Set of transaction hashes known to be known by this peer @@ -102,6 +104,12 @@ func (p *Peer) Version() uint { return p.version } +// BlockRange returns the latest announced block range. +// This will be nil for peers below protocol version eth/69. +func (p *Peer) BlockRange() *BlockRangeUpdatePacket { + return p.lastRange.Load() +} + // KnownTransaction returns whether peer is known to already have a transaction. func (p *Peer) KnownTransaction(hash common.Hash) bool { return p.knownTxs.Contains(hash) @@ -343,6 +351,14 @@ func (p *Peer) RequestTxs(hashes []common.Hash) error { }) } +// SendBlockRangeUpdate sends a notification about our available block range to the peer. +func (p *Peer) SendBlockRangeUpdate(msg BlockRangeUpdatePacket) error { + if p.version < ETH69 { + return nil + } + return p2p.Send(p.rw, BlockRangeUpdateMsg, &msg) +} + // knownCache is a cache for known hashes. type knownCache struct { hashes mapset.Set[common.Hash] diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go index aeef4330ff..7c41e7a996 100644 --- a/eth/protocols/eth/protocol.go +++ b/eth/protocols/eth/protocol.go @@ -31,6 +31,7 @@ import ( // Constants to match up protocol versions and messages const ( ETH68 = 68 + ETH69 = 69 ) // ProtocolName is the official short name of the `eth` protocol used during @@ -39,11 +40,11 @@ const ProtocolName = "eth" // ProtocolVersions are the supported versions of the `eth` protocol (first // is primary). -var ProtocolVersions = []uint{ETH68} +var ProtocolVersions = []uint{ETH69, ETH68} // protocolLengths are the number of implemented message corresponding to // different protocol versions. -var protocolLengths = map[uint]uint64{ETH68: 17} +var protocolLengths = map[uint]uint64{ETH68: 17, ETH69: 18} // maxMessageSize is the maximum cap on the size of a protocol message. const maxMessageSize = 10 * 1024 * 1024 @@ -62,17 +63,19 @@ const ( PooledTransactionsMsg = 0x0a GetReceiptsMsg = 0x0f ReceiptsMsg = 0x10 + BlockRangeUpdateMsg = 0x11 ) var ( - errNoStatusMsg = errors.New("no status message") errMsgTooLarge = errors.New("message too long") - errDecode = errors.New("invalid message") errInvalidMsgCode = errors.New("invalid message code") errProtocolVersionMismatch = errors.New("protocol version mismatch") - errNetworkIDMismatch = errors.New("network ID mismatch") - errGenesisMismatch = errors.New("genesis mismatch") - errForkIDRejected = errors.New("fork ID rejected") + // handshake errors + errNoStatusMsg = errors.New("no status message") + errNetworkIDMismatch = errors.New("network ID mismatch") + errGenesisMismatch = errors.New("genesis mismatch") + errForkIDRejected = errors.New("fork ID rejected") + errInvalidBlockRange = errors.New("invalid block range in status") ) // Packet represents a p2p message in the `eth` protocol. @@ -82,7 +85,7 @@ type Packet interface { } // StatusPacket is the network packet for the status message. -type StatusPacket struct { +type StatusPacket68 struct { ProtocolVersion uint32 NetworkID uint64 TD *big.Int @@ -91,6 +94,18 @@ type StatusPacket struct { ForkID forkid.ID } +// StatusPacket69 is the network packet for the status message. +type StatusPacket69 struct { + ProtocolVersion uint32 + NetworkID uint64 + Genesis common.Hash + ForkID forkid.ID + // initial available block range + EarliestBlock uint64 + LatestBlock uint64 + LatestBlockHash common.Hash +} + // NewBlockHashesPacket is the network packet for the block announcements. type NewBlockHashesPacket []struct { Hash common.Hash // Hash of one particular block being announced @@ -250,13 +265,21 @@ type GetReceiptsPacket struct { } // ReceiptsResponse is the network packet for block receipts distribution. -type ReceiptsResponse [][]*types.Receipt +type ReceiptsResponse []types.Receipts + +// ReceiptsList is a type constraint for block receceipt list types. +type ReceiptsList interface { + *ReceiptList68 | *ReceiptList69 + setBuffers(*receiptListBuffers) + EncodeForStorage() rlp.RawValue + types.DerivableList +} // ReceiptsPacket is the network packet for block receipts distribution with // request ID wrapping. -type ReceiptsPacket struct { +type ReceiptsPacket[L ReceiptsList] struct { RequestId uint64 - ReceiptsResponse + List []L } // ReceiptsRLPResponse is used for receipts, when we already have it encoded @@ -304,8 +327,18 @@ type PooledTransactionsRLPPacket struct { PooledTransactionsRLPResponse } -func (*StatusPacket) Name() string { return "Status" } -func (*StatusPacket) Kind() byte { return StatusMsg } +// BlockRangeUpdatePacket is an announcement of the node's available block range. +type BlockRangeUpdatePacket struct { + EarliestBlock uint64 + LatestBlock uint64 + LatestBlockHash common.Hash +} + +func (*StatusPacket68) Name() string { return "Status" } +func (*StatusPacket68) Kind() byte { return StatusMsg } + +func (*StatusPacket69) Name() string { return "Status" } +func (*StatusPacket69) Kind() byte { return StatusMsg } func (*NewBlockHashesPacket) Name() string { return "NewBlockHashes" } func (*NewBlockHashesPacket) Kind() byte { return NewBlockHashesMsg } @@ -342,3 +375,9 @@ func (*GetReceiptsRequest) Kind() byte { return GetReceiptsMsg } func (*ReceiptsResponse) Name() string { return "Receipts" } func (*ReceiptsResponse) Kind() byte { return ReceiptsMsg } + +func (*ReceiptsRLPResponse) Name() string { return "Receipts" } +func (*ReceiptsRLPResponse) Kind() byte { return ReceiptsMsg } + +func (*BlockRangeUpdatePacket) Name() string { return "BlockRangeUpdate" } +func (*BlockRangeUpdatePacket) Kind() byte { return BlockRangeUpdateMsg } diff --git a/eth/protocols/eth/protocol_test.go b/eth/protocols/eth/protocol_test.go index bc2545dea2..8a2559a6c5 100644 --- a/eth/protocols/eth/protocol_test.go +++ b/eth/protocols/eth/protocol_test.go @@ -75,7 +75,7 @@ func TestEmptyMessages(t *testing.T) { // All empty messages encodes to the same format want := common.FromHex("c4820457c0") - for i, msg := range []interface{}{ + for i, msg := range []any{ // Headers GetBlockHeadersPacket{1111, nil}, BlockHeadersPacket{1111, nil}, @@ -85,7 +85,6 @@ func TestEmptyMessages(t *testing.T) { BlockBodiesRLPPacket{1111, nil}, // Receipts GetReceiptsPacket{1111, nil}, - ReceiptsPacket{1111, nil}, // Transactions GetPooledTransactionsPacket{1111, nil}, PooledTransactionsPacket{1111, nil}, @@ -99,7 +98,8 @@ func TestEmptyMessages(t *testing.T) { BlockBodiesRLPPacket{1111, BlockBodiesRLPResponse([]rlp.RawValue{})}, // Receipts GetReceiptsPacket{1111, GetReceiptsRequest([]common.Hash{})}, - ReceiptsPacket{1111, ReceiptsResponse([][]*types.Receipt{})}, + ReceiptsPacket[*ReceiptList68]{1111, []*ReceiptList68{}}, + ReceiptsPacket[*ReceiptList69]{1111, []*ReceiptList69{}}, // Transactions GetPooledTransactionsPacket{1111, GetPooledTransactionsRequest([]common.Hash{})}, PooledTransactionsPacket{1111, PooledTransactionsResponse([]*types.Transaction{})}, @@ -168,7 +168,7 @@ func TestMessages(t *testing.T) { receipts = []*types.Receipt{ { Status: types.ReceiptStatusFailed, - CumulativeGasUsed: 1, + CumulativeGasUsed: 333, Logs: []*types.Log{ { Address: common.BytesToAddress([]byte{0x11}), @@ -176,11 +176,21 @@ func TestMessages(t *testing.T) { Data: []byte{0x01, 0x00, 0xff}, }, }, - TxHash: hashes[0], - ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), - GasUsed: 111111, + }, + { + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 444, + Logs: []*types.Log{ + { + Address: common.BytesToAddress([]byte{0x22}), + Topics: []common.Hash{common.HexToHash("05668"), common.HexToHash("9773")}, + Data: []byte{0x02, 0x0f, 0x0f, 0x0f, 0x06, 0x08}, + }, + }, }, } + miniDeriveFields(receipts[0], 0) + miniDeriveFields(receipts[1], 1) rlpData, err := rlp.EncodeToBytes(receipts) if err != nil { t.Fatal(err) @@ -221,12 +231,17 @@ func TestMessages(t *testing.T) { common.FromHex("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"), }, { - ReceiptsPacket{1111, ReceiptsResponse([][]*types.Receipt{receipts})}, - common.FromHex("f90172820457f9016cf90169f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"), + ReceiptsPacket[*ReceiptList68]{1111, []*ReceiptList68{NewReceiptList68(receipts)}}, + common.FromHex("f902e6820457f902e0f902ddf901688082014db9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000004000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ffb9016f01f9016b018201bcb9010000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000001000000000000000000000000000000000000000000000000040000000000000000000000000004000000000000000000000000000000000000000000000000000000008000400000000000000000000000000000000000000000000000000000000000000000000000000000040f862f860940000000000000000000000000000000000000022f842a00000000000000000000000000000000000000000000000000000000000005668a0000000000000000000000000000000000000000000000000000000000000977386020f0f0f0608"), }, { + // Identical to the eth/68 encoding above. ReceiptsRLPPacket{1111, ReceiptsRLPResponse([]rlp.RawValue{receiptsRlp})}, - common.FromHex("f90172820457f9016cf90169f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"), + common.FromHex("f902e6820457f902e0f902ddf901688082014db9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000004000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ffb9016f01f9016b018201bcb9010000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000001000000000000000000000000000000000000000000000000040000000000000000000000000004000000000000000000000000000000000000000000000000000000008000400000000000000000000000000000000000000000000000000000000000000000000000000000040f862f860940000000000000000000000000000000000000022f842a00000000000000000000000000000000000000000000000000000000000005668a0000000000000000000000000000000000000000000000000000000000000977386020f0f0f0608"), + }, + { + ReceiptsPacket[*ReceiptList69]{1111, []*ReceiptList69{NewReceiptList69(receipts)}}, + common.FromHex("f8da820457f8d5f8d3f866808082014df85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff86901018201bcf862f860940000000000000000000000000000000000000022f842a00000000000000000000000000000000000000000000000000000000000005668a0000000000000000000000000000000000000000000000000000000000000977386020f0f0f0608"), }, { GetPooledTransactionsPacket{1111, GetPooledTransactionsRequest(hashes)}, diff --git a/eth/protocols/eth/receipt.go b/eth/protocols/eth/receipt.go new file mode 100644 index 0000000000..45c4766b17 --- /dev/null +++ b/eth/protocols/eth/receipt.go @@ -0,0 +1,462 @@ +// 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 eth + +import ( + "bytes" + "fmt" + "io" + "iter" + "math/big" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// This is just a sanity limit for the size of a single receipt. +const maxReceiptSize = 16 * 1024 * 1024 + +// Receipt is the representation of receipts for networking purposes. +type Receipt struct { + TxType byte + PostStateOrStatus []byte + GasUsed uint64 + Logs rlp.RawValue +} + +func newReceipt(tr *types.Receipt) Receipt { + r := Receipt{TxType: tr.Type, GasUsed: tr.CumulativeGasUsed} + if tr.PostState != nil { + r.PostStateOrStatus = tr.PostState + } else { + r.PostStateOrStatus = new(big.Int).SetUint64(tr.Status).Bytes() + } + r.Logs, _ = rlp.EncodeToBytes(tr.Logs) + return r +} + +// decode68 parses a receipt in the eth/68 network encoding. +func (r *Receipt) decode68(buf *receiptListBuffers, s *rlp.Stream) error { + k, size, err := s.Kind() + if err != nil { + return err + } + + *r = Receipt{} + if k == rlp.List { + // Legacy receipt. + return r.decodeInnerList(s, false, true) + } + // Typed receipt. + if size < 2 || size > maxReceiptSize { + return fmt.Errorf("invalid receipt size %d", size) + } + buf.tmp.Reset() + buf.tmp.Grow(int(size)) + payload := buf.tmp.Bytes()[:int(size)] + if err := s.ReadBytes(payload); err != nil { + return err + } + r.TxType = payload[0] + s2 := rlp.NewStream(bytes.NewReader(payload[1:]), 0) + return r.decodeInnerList(s2, false, true) +} + +// decode69 parses a receipt in the eth/69 network encoding. +func (r *Receipt) decode69(s *rlp.Stream) error { + *r = Receipt{} + return r.decodeInnerList(s, true, false) +} + +// decodeDatabase parses a receipt in the basic database encoding. +func (r *Receipt) decodeDatabase(txType byte, s *rlp.Stream) error { + *r = Receipt{TxType: txType} + return r.decodeInnerList(s, false, false) +} + +func (r *Receipt) decodeInnerList(s *rlp.Stream, readTxType, readBloom bool) error { + _, err := s.List() + if err != nil { + return err + } + if readTxType { + r.TxType, err = s.Uint8() + if err != nil { + return fmt.Errorf("invalid txType: %w", err) + } + } + r.PostStateOrStatus, err = s.Bytes() + if err != nil { + return fmt.Errorf("invalid postStateOrStatus: %w", err) + } + r.GasUsed, err = s.Uint64() + if err != nil { + return fmt.Errorf("invalid gasUsed: %w", err) + } + if readBloom { + var b types.Bloom + if err := s.ReadBytes(b[:]); err != nil { + return fmt.Errorf("invalid bloom: %v", err) + } + } + r.Logs, err = s.Raw() + if err != nil { + return fmt.Errorf("invalid logs: %w", err) + } + return s.ListEnd() +} + +// encodeForStorage produces the the storage encoding, i.e. the result matches +// the RLP encoding of types.ReceiptForStorage. +func (r *Receipt) encodeForStorage(w *rlp.EncoderBuffer) { + list := w.List() + w.WriteBytes(r.PostStateOrStatus) + w.WriteUint64(r.GasUsed) + w.Write(r.Logs) + w.ListEnd(list) +} + +// encodeForNetwork68 produces the eth/68 network protocol encoding of a receipt. +// Note this recomputes the bloom filter of the receipt. +func (r *Receipt) encodeForNetwork68(buf *receiptListBuffers, w *rlp.EncoderBuffer) { + writeInner := func(w *rlp.EncoderBuffer) { + list := w.List() + w.WriteBytes(r.PostStateOrStatus) + w.WriteUint64(r.GasUsed) + bloom := r.bloom(&buf.bloom) + w.WriteBytes(bloom[:]) + w.Write(r.Logs) + w.ListEnd(list) + } + + if r.TxType == 0 { + writeInner(w) + } else { + buf.tmp.Reset() + buf.tmp.WriteByte(r.TxType) + buf.enc.Reset(&buf.tmp) + writeInner(&buf.enc) + buf.enc.Flush() + w.WriteBytes(buf.tmp.Bytes()) + } +} + +// encodeForNetwork69 produces the eth/69 network protocol encoding of a receipt. +func (r *Receipt) encodeForNetwork69(w *rlp.EncoderBuffer) { + list := w.List() + w.WriteUint64(uint64(r.TxType)) + w.WriteBytes(r.PostStateOrStatus) + w.WriteUint64(r.GasUsed) + w.Write(r.Logs) + w.ListEnd(list) +} + +// encodeForHash encodes a receipt for the block receiptsRoot derivation. +func (r *Receipt) encodeForHash(buf *receiptListBuffers, out *bytes.Buffer) { + // For typed receipts, add the tx type. + if r.TxType != 0 { + out.WriteByte(r.TxType) + } + // Encode list = [postStateOrStatus, gasUsed, bloom, logs]. + w := &buf.enc + w.Reset(out) + l := w.List() + w.WriteBytes(r.PostStateOrStatus) + w.WriteUint64(r.GasUsed) + bloom := r.bloom(&buf.bloom) + w.WriteBytes(bloom[:]) + w.Write(r.Logs) + w.ListEnd(l) + w.Flush() +} + +// bloom computes the bloom filter of the receipt. +// Note this doesn't check the validity of encoding, and will produce an invalid filter +// for invalid input. This is acceptable for the purpose of this function, which is +// recomputing the receipt hash. +func (r *Receipt) bloom(buffer *[6]byte) types.Bloom { + var b types.Bloom + logsIter, err := rlp.NewListIterator(r.Logs) + if err != nil { + return b + } + for logsIter.Next() { + log, _, _ := rlp.SplitList(logsIter.Value()) + address, log, _ := rlp.SplitString(log) + b.AddWithBuffer(address, buffer) + topicsIter, err := rlp.NewListIterator(log) + if err != nil { + return b + } + for topicsIter.Next() { + topic, _, _ := rlp.SplitString(topicsIter.Value()) + b.AddWithBuffer(topic, buffer) + } + } + return b +} + +type receiptListBuffers struct { + enc rlp.EncoderBuffer + bloom [6]byte + tmp bytes.Buffer +} + +func initBuffers(buf **receiptListBuffers) { + if *buf == nil { + *buf = new(receiptListBuffers) + } +} + +// encodeForStorage encodes a list of receipts for the database. +func (buf *receiptListBuffers) encodeForStorage(rs []Receipt) rlp.RawValue { + var out bytes.Buffer + w := &buf.enc + w.Reset(&out) + outer := w.List() + for _, receipts := range rs { + receipts.encodeForStorage(w) + } + w.ListEnd(outer) + w.Flush() + return out.Bytes() +} + +// ReceiptList68 is a block receipt list as downloaded by eth/68. +// This also implements types.DerivableList for validation purposes. +type ReceiptList68 struct { + buf *receiptListBuffers + items []Receipt +} + +// NewReceiptList68 creates a receipt list. +// This is slow, and exists for testing purposes. +func NewReceiptList68(trs []*types.Receipt) *ReceiptList68 { + rl := &ReceiptList68{items: make([]Receipt, len(trs))} + for i, tr := range trs { + rl.items[i] = newReceipt(tr) + } + return rl +} + +func blockReceiptsToNetwork68(blockReceipts, blockBody rlp.RawValue) ([]byte, error) { + txTypesIter, err := txTypesInBody(blockBody) + if err != nil { + return nil, fmt.Errorf("invalid block body: %v", err) + } + nextTxType, stopTxTypes := iter.Pull(txTypesIter) + defer stopTxTypes() + + var ( + out bytes.Buffer + buf receiptListBuffers + ) + blockReceiptIter, _ := rlp.NewListIterator(blockReceipts) + innerReader := bytes.NewReader(nil) + innerStream := rlp.NewStream(innerReader, 0) + w := rlp.NewEncoderBuffer(&out) + outer := w.List() + for i := 0; blockReceiptIter.Next(); i++ { + content := blockReceiptIter.Value() + innerReader.Reset(content) + innerStream.Reset(innerReader, uint64(len(content))) + var r Receipt + txType, _ := nextTxType() + if err := r.decodeDatabase(txType, innerStream); err != nil { + return nil, fmt.Errorf("invalid database receipt %d: %v", i, err) + } + r.encodeForNetwork68(&buf, &w) + } + w.ListEnd(outer) + w.Flush() + return out.Bytes(), nil +} + +// setBuffers implements ReceiptsList. +func (rl *ReceiptList68) setBuffers(buf *receiptListBuffers) { + rl.buf = buf +} + +// EncodeForStorage encodes the receipts for storage into the database. +func (rl *ReceiptList68) EncodeForStorage() rlp.RawValue { + initBuffers(&rl.buf) + return rl.buf.encodeForStorage(rl.items) +} + +// Len implements types.DerivableList. +func (rl *ReceiptList68) Len() int { + return len(rl.items) +} + +// EncodeIndex implements types.DerivableList. +func (rl *ReceiptList68) EncodeIndex(i int, out *bytes.Buffer) { + initBuffers(&rl.buf) + rl.items[i].encodeForHash(rl.buf, out) +} + +// DecodeRLP decodes a list of receipts from the network format. +func (rl *ReceiptList68) DecodeRLP(s *rlp.Stream) error { + initBuffers(&rl.buf) + if _, err := s.List(); err != nil { + return err + } + for i := 0; s.MoreDataInList(); i++ { + var item Receipt + err := item.decode68(rl.buf, s) + if err != nil { + return fmt.Errorf("receipt %d: %v", i, err) + } + rl.items = append(rl.items, item) + } + return s.ListEnd() +} + +// EncodeRLP encodes the list into the network format of eth/68. +func (rl *ReceiptList68) EncodeRLP(_w io.Writer) error { + initBuffers(&rl.buf) + w := rlp.NewEncoderBuffer(_w) + outer := w.List() + for i := range rl.items { + rl.items[i].encodeForNetwork68(rl.buf, &w) + } + w.ListEnd(outer) + return w.Flush() +} + +// ReceiptList69 is the block receipt list as downloaded by eth/69. +// This implements types.DerivableList for validation purposes. +type ReceiptList69 struct { + buf *receiptListBuffers + items []Receipt +} + +// NewReceiptList69 creates a receipt list. +// This is slow, and exists for testing purposes. +func NewReceiptList69(trs []*types.Receipt) *ReceiptList69 { + rl := &ReceiptList69{items: make([]Receipt, len(trs))} + for i, tr := range trs { + rl.items[i] = newReceipt(tr) + } + return rl +} + +// setBuffers implements ReceiptsList. +func (rl *ReceiptList69) setBuffers(buf *receiptListBuffers) { + rl.buf = buf +} + +// EncodeForStorage encodes the receipts for storage into the database. +func (rl *ReceiptList69) EncodeForStorage() rlp.RawValue { + initBuffers(&rl.buf) + return rl.buf.encodeForStorage(rl.items) +} + +// Len implements types.DerivableList. +func (rl *ReceiptList69) Len() int { + return len(rl.items) +} + +// EncodeIndex implements types.DerivableList. +func (rl *ReceiptList69) EncodeIndex(i int, out *bytes.Buffer) { + initBuffers(&rl.buf) + rl.items[i].encodeForHash(rl.buf, out) +} + +// DecodeRLP decodes a list receipts from the network format. +func (rl *ReceiptList69) DecodeRLP(s *rlp.Stream) error { + if _, err := s.List(); err != nil { + return err + } + for i := 0; s.MoreDataInList(); i++ { + var item Receipt + err := item.decode69(s) + if err != nil { + return fmt.Errorf("receipt %d: %v", i, err) + } + rl.items = append(rl.items, item) + } + return s.ListEnd() +} + +// EncodeRLP encodes the list into the network format of eth/69. +func (rl *ReceiptList69) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + outer := w.List() + for i := range rl.items { + rl.items[i].encodeForNetwork69(&w) + } + w.ListEnd(outer) + return w.Flush() +} + +// blockReceiptsToNetwork69 takes a slice of rlp-encoded receipts, and transactions, +// and applies the type-encoding on the receipts (for non-legacy receipts). +// e.g. for non-legacy receipts: receipt-data -> {tx-type || receipt-data} +func blockReceiptsToNetwork69(blockReceipts, blockBody rlp.RawValue) ([]byte, error) { + txTypesIter, err := txTypesInBody(blockBody) + if err != nil { + return nil, fmt.Errorf("invalid block body: %v", err) + } + nextTxType, stopTxTypes := iter.Pull(txTypesIter) + defer stopTxTypes() + + var ( + out bytes.Buffer + enc = rlp.NewEncoderBuffer(&out) + it, _ = rlp.NewListIterator(blockReceipts) + ) + outer := enc.List() + for i := 0; it.Next(); i++ { + txType, _ := nextTxType() + content, _, _ := rlp.SplitList(it.Value()) + receiptList := enc.List() + enc.WriteUint64(uint64(txType)) + enc.Write(content) + enc.ListEnd(receiptList) + } + enc.ListEnd(outer) + enc.Flush() + return out.Bytes(), nil +} + +// txTypesInBody parses the transactions list of an encoded block body, returning just the types. +func txTypesInBody(body rlp.RawValue) (iter.Seq[byte], error) { + bodyFields, _, err := rlp.SplitList(body) + if err != nil { + return nil, err + } + txsIter, err := rlp.NewListIterator(bodyFields) + if err != nil { + return nil, err + } + return func(yield func(byte) bool) { + for txsIter.Next() { + var txType byte + switch k, content, _, _ := rlp.Split(txsIter.Value()); k { + case rlp.List: + txType = 0 + case rlp.String: + if len(content) > 0 { + txType = content[0] + } + } + if !yield(txType) { + return + } + } + }, nil +} diff --git a/eth/protocols/eth/receipt_test.go b/eth/protocols/eth/receipt_test.go new file mode 100644 index 0000000000..3c73c07396 --- /dev/null +++ b/eth/protocols/eth/receipt_test.go @@ -0,0 +1,158 @@ +// 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 eth + +import ( + "bytes" + "testing" + + "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" +) + +// miniDeriveFields derives the necessary receipt fields to make types.DeriveSha work. +func miniDeriveFields(r *types.Receipt, txType byte) { + r.Type = txType + r.Bloom = types.CreateBloom(r) +} + +var receiptsTestLogs1 = []*types.Log{{Address: common.Address{1}, Topics: []common.Hash{{1}}}} +var receiptsTestLogs2 = []*types.Log{ + {Address: common.Address{2}, Topics: []common.Hash{{21}, {22}}, Data: []byte{2, 2, 32, 32}}, + {Address: common.Address{3}, Topics: []common.Hash{{31}, {32}}, Data: []byte{3, 3, 32, 32}}, +} + +var receiptsTests = []struct { + input []types.ReceiptForStorage + txs []*types.Transaction + root common.Hash +}{ + { + input: []types.ReceiptForStorage{{CumulativeGasUsed: 555, Status: 1, Logs: nil}}, + txs: []*types.Transaction{types.NewTx(&types.LegacyTx{})}, + }, + { + input: []types.ReceiptForStorage{{CumulativeGasUsed: 555, Status: 1, Logs: nil}}, + txs: []*types.Transaction{types.NewTx(&types.DynamicFeeTx{})}, + }, + { + input: []types.ReceiptForStorage{{CumulativeGasUsed: 555, Status: 1, Logs: nil}}, + txs: []*types.Transaction{types.NewTx(&types.AccessListTx{})}, + }, + { + input: []types.ReceiptForStorage{{CumulativeGasUsed: 555, Status: 1, Logs: receiptsTestLogs1}}, + txs: []*types.Transaction{types.NewTx(&types.LegacyTx{})}, + }, + { + input: []types.ReceiptForStorage{{CumulativeGasUsed: 555, Status: 1, Logs: receiptsTestLogs2}}, + txs: []*types.Transaction{types.NewTx(&types.AccessListTx{})}, + }, +} + +func init() { + for i := range receiptsTests { + // derive basic fields + for j := range receiptsTests[i].input { + r := (*types.Receipt)(&receiptsTests[i].input[j]) + txType := receiptsTests[i].txs[j].Type() + miniDeriveFields(r, txType) + } + // compute expected root + receipts := make(types.Receipts, len(receiptsTests[i].input)) + for j, sr := range receiptsTests[i].input { + r := types.Receipt(sr) + receipts[j] = &r + } + receiptsTests[i].root = types.DeriveSha(receipts, trie.NewStackTrie(nil)) + } +} + +func TestReceiptList69(t *testing.T) { + for i, test := range receiptsTests { + // encode receipts from types.ReceiptForStorage object. + canonDB, _ := rlp.EncodeToBytes(test.input) + + // encode block body from types object. + blockBody := types.Body{Transactions: test.txs} + canonBody, _ := rlp.EncodeToBytes(blockBody) + + // convert from storage encoding to network encoding + network, err := blockReceiptsToNetwork69(canonDB, canonBody) + if err != nil { + t.Fatalf("test[%d]: blockReceiptsToNetwork69 error: %v", i, err) + } + + // parse as Receipts response list from network encoding + var rl ReceiptList69 + if err := rlp.DecodeBytes(network, &rl); err != nil { + t.Fatalf("test[%d]: can't decode network receipts: %v", i, err) + } + rlStorageEnc := rl.EncodeForStorage() + if !bytes.Equal(rlStorageEnc, canonDB) { + t.Fatalf("test[%d]: re-encoded receipts not equal\nhave: %x\nwant: %x", i, rlStorageEnc, canonDB) + } + rlNetworkEnc, _ := rlp.EncodeToBytes(&rl) + if !bytes.Equal(rlNetworkEnc, network) { + t.Fatalf("test[%d]: re-encoded network receipt list not equal\nhave: %x\nwant: %x", i, rlNetworkEnc, network) + } + + // compute root hash from ReceiptList69 and compare. + responseHash := types.DeriveSha(&rl, trie.NewStackTrie(nil)) + if responseHash != test.root { + t.Fatalf("test[%d]: wrong root hash from ReceiptList69\nhave: %v\nwant: %v", i, responseHash, test.root) + } + } +} + +func TestReceiptList68(t *testing.T) { + for i, test := range receiptsTests { + // encode receipts from types.ReceiptForStorage object. + canonDB, _ := rlp.EncodeToBytes(test.input) + + // encode block body from types object. + blockBody := types.Body{Transactions: test.txs} + canonBody, _ := rlp.EncodeToBytes(blockBody) + + // convert from storage encoding to network encoding + network, err := blockReceiptsToNetwork68(canonDB, canonBody) + if err != nil { + t.Fatalf("test[%d]: blockReceiptsToNetwork68 error: %v", i, err) + } + + // parse as Receipts response list from network encoding + var rl ReceiptList68 + if err := rlp.DecodeBytes(network, &rl); err != nil { + t.Fatalf("test[%d]: can't decode network receipts: %v", i, err) + } + rlStorageEnc := rl.EncodeForStorage() + if !bytes.Equal(rlStorageEnc, canonDB) { + t.Fatalf("test[%d]: re-encoded receipts not equal\nhave: %x\nwant: %x", i, rlStorageEnc, canonDB) + } + rlNetworkEnc, _ := rlp.EncodeToBytes(&rl) + if !bytes.Equal(rlNetworkEnc, network) { + t.Fatalf("test[%d]: re-encoded network receipt list not equal\nhave: %x\nwant: %x", i, rlNetworkEnc, network) + } + + // compute root hash from ReceiptList68 and compare. + responseHash := types.DeriveSha(&rl, trie.NewStackTrie(nil)) + if responseHash != test.root { + t.Fatalf("test[%d]: wrong root hash from ReceiptList68\nhave: %v\nwant: %v", i, responseHash, test.root) + } + } +} diff --git a/eth/protocols/eth/tracker.go b/eth/protocols/eth/tracker.go deleted file mode 100644 index 324fd22839..0000000000 --- a/eth/protocols/eth/tracker.go +++ /dev/null @@ -1,26 +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 eth - -import ( - "time" - - "github.com/ethereum/go-ethereum/p2p/tracker" -) - -// requestTracker is a singleton tracker for eth/66 and newer request times. -var requestTracker = tracker.New(ProtocolName, 5*time.Minute) From c8be0f9a74fdabe5f82fa5b647e9973c9c3567ef Mon Sep 17 00:00:00 2001 From: maskpp Date: Sat, 17 May 2025 01:35:17 +0800 Subject: [PATCH 372/940] eth: use headers in debug.GetModifiedAccountsBy* (#31765) Small optimization in debug_getModifiedAccountsBy* to avoid fetching block body. --- eth/api_debug.go | 50 +++++++++---------- eth/api_debug_test.go | 112 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 25 deletions(-) diff --git a/eth/api_debug.go b/eth/api_debug.go index d5e4dda140..188dee11aa 100644 --- a/eth/api_debug.go +++ b/eth/api_debug.go @@ -271,26 +271,26 @@ func storageRangeAt(statedb *state.StateDB, root common.Hash, address common.Add // // With one parameter, returns the list of accounts modified in the specified block. func (api *DebugAPI) GetModifiedAccountsByNumber(startNum uint64, endNum *uint64) ([]common.Address, error) { - var startBlock, endBlock *types.Block + var startHeader, endHeader *types.Header - startBlock = api.eth.blockchain.GetBlockByNumber(startNum) - if startBlock == nil { + startHeader = api.eth.blockchain.GetHeaderByNumber(startNum) + if startHeader == nil { return nil, fmt.Errorf("start block %x not found", startNum) } if endNum == nil { - endBlock = startBlock - startBlock = api.eth.blockchain.GetBlockByHash(startBlock.ParentHash()) - if startBlock == nil { - return nil, fmt.Errorf("block %x has no parent", endBlock.Number()) + endHeader = startHeader + startHeader = api.eth.blockchain.GetHeaderByHash(startHeader.ParentHash) + if startHeader == nil { + return nil, fmt.Errorf("block %x has no parent", endHeader.Number) } } else { - endBlock = api.eth.blockchain.GetBlockByNumber(*endNum) - if endBlock == nil { + endHeader = api.eth.blockchain.GetHeaderByNumber(*endNum) + if endHeader == nil { return nil, fmt.Errorf("end block %d not found", *endNum) } } - return api.getModifiedAccounts(startBlock, endBlock) + return api.getModifiedAccounts(startHeader, endHeader) } // GetModifiedAccountsByHash returns all accounts that have changed between the @@ -299,38 +299,38 @@ func (api *DebugAPI) GetModifiedAccountsByNumber(startNum uint64, endNum *uint64 // // With one parameter, returns the list of accounts modified in the specified block. func (api *DebugAPI) GetModifiedAccountsByHash(startHash common.Hash, endHash *common.Hash) ([]common.Address, error) { - var startBlock, endBlock *types.Block - startBlock = api.eth.blockchain.GetBlockByHash(startHash) - if startBlock == nil { + var startHeader, endHeader *types.Header + startHeader = api.eth.blockchain.GetHeaderByHash(startHash) + if startHeader == nil { return nil, fmt.Errorf("start block %x not found", startHash) } if endHash == nil { - endBlock = startBlock - startBlock = api.eth.blockchain.GetBlockByHash(startBlock.ParentHash()) - if startBlock == nil { - return nil, fmt.Errorf("block %x has no parent", endBlock.Number()) + endHeader = startHeader + startHeader = api.eth.blockchain.GetHeaderByHash(startHeader.ParentHash) + if startHeader == nil { + return nil, fmt.Errorf("block %x has no parent", endHeader.Number) } } else { - endBlock = api.eth.blockchain.GetBlockByHash(*endHash) - if endBlock == nil { + endHeader = api.eth.blockchain.GetHeaderByHash(*endHash) + if endHeader == nil { return nil, fmt.Errorf("end block %x not found", *endHash) } } - return api.getModifiedAccounts(startBlock, endBlock) + return api.getModifiedAccounts(startHeader, endHeader) } -func (api *DebugAPI) getModifiedAccounts(startBlock, endBlock *types.Block) ([]common.Address, error) { - if startBlock.Number().Uint64() >= endBlock.Number().Uint64() { - return nil, fmt.Errorf("start block height (%d) must be less than end block height (%d)", startBlock.Number().Uint64(), endBlock.Number().Uint64()) +func (api *DebugAPI) getModifiedAccounts(startHeader, endHeader *types.Header) ([]common.Address, error) { + if startHeader.Number.Uint64() >= endHeader.Number.Uint64() { + return nil, fmt.Errorf("start block height (%d) must be less than end block height (%d)", startHeader.Number.Uint64(), endHeader.Number.Uint64()) } triedb := api.eth.BlockChain().TrieDB() - oldTrie, err := trie.NewStateTrie(trie.StateTrieID(startBlock.Root()), triedb) + oldTrie, err := trie.NewStateTrie(trie.StateTrieID(startHeader.Root), triedb) if err != nil { return nil, err } - newTrie, err := trie.NewStateTrie(trie.StateTrieID(endBlock.Root()), triedb) + newTrie, err := trie.NewStateTrie(trie.StateTrieID(endHeader.Root), triedb) if err != nil { return nil, err } diff --git a/eth/api_debug_test.go b/eth/api_debug_test.go index 02b85f69fd..90fd22498a 100644 --- a/eth/api_debug_test.go +++ b/eth/api_debug_test.go @@ -18,25 +18,74 @@ package eth import ( "bytes" + "crypto/ecdsa" "fmt" + "math/big" "reflect" "slices" "strings" "testing" + "time" "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" + "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/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/params" "github.com/ethereum/go-ethereum/triedb" "github.com/holiman/uint256" + "github.com/stretchr/testify/assert" ) var dumper = spew.ConfigState{Indent: " "} +type Account struct { + key *ecdsa.PrivateKey + addr common.Address +} + +func newAccounts(n int) (accounts []Account) { + for i := 0; i < n; i++ { + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + accounts = append(accounts, Account{key: key, addr: addr}) + } + slices.SortFunc(accounts, func(a, b Account) int { return a.addr.Cmp(b.addr) }) + return accounts +} + +// newTestBlockChain creates a new test blockchain. OBS: After test is done, teardown must be +// invoked in order to release associated resources. +func newTestBlockChain(t *testing.T, n int, gspec *core.Genesis, generator func(i int, b *core.BlockGen)) *core.BlockChain { + engine := ethash.NewFaker() + // Generate blocks for testing + _, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, n, generator) + + // Import the canonical chain + cacheConfig := &core.CacheConfig{ + TrieCleanLimit: 256, + TrieDirtyLimit: 256, + TrieTimeLimit: 5 * time.Minute, + SnapshotLimit: 0, + Preimages: true, + TrieDirtyDisabled: true, // Archive mode + } + chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), cacheConfig, gspec, nil, engine, vm.Config{}, 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) + } + return chain +} + func accountRangeTest(t *testing.T, trie *state.Trie, statedb *state.StateDB, start common.Hash, requestedNum int, expectedNum int) state.Dump { result := statedb.RawDump(&state.DumpConfig{ SkipCode: true, @@ -224,3 +273,66 @@ func TestStorageRangeAt(t *testing.T) { } } } + +func TestGetModifiedAccounts(t *testing.T) { + t.Parallel() + + // Initialize test accounts + accounts := newAccounts(4) + 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)}, + accounts[3].addr: {Balance: big.NewInt(params.Ether)}, + }, + } + genBlocks := 1 + signer := types.HomesteadSigner{} + blockChain := newTestBlockChain(t, genBlocks, genesis, func(_ int, b *core.BlockGen) { + // Transfer from account[0] to account[1] + // value: 1000 wei + // fee: 0 wei + for _, account := range accounts[:3] { + tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ + Nonce: 0, + To: &accounts[3].addr, + Value: big.NewInt(1000), + Gas: params.TxGas, + GasPrice: b.BaseFee(), + Data: nil}), + signer, account.key) + b.AddTx(tx) + } + }) + defer blockChain.Stop() + + // Create a debug API instance. + api := NewDebugAPI(&Ethereum{blockchain: blockChain}) + + // Test GetModifiedAccountsByNumber + t.Run("GetModifiedAccountsByNumber", func(t *testing.T) { + addrs, err := api.GetModifiedAccountsByNumber(uint64(genBlocks), nil) + assert.NoError(t, err) + assert.Len(t, addrs, len(accounts)+1) // +1 for the coinbase + for _, account := range accounts { + if !slices.Contains(addrs, account.addr) { + t.Fatalf("account %s not found in modified accounts", account.addr.Hex()) + } + } + }) + + // Test GetModifiedAccountsByHash + t.Run("GetModifiedAccountsByHash", func(t *testing.T) { + header := blockChain.GetHeaderByNumber(uint64(genBlocks)) + addrs, err := api.GetModifiedAccountsByHash(header.Hash(), nil) + assert.NoError(t, err) + assert.Len(t, addrs, len(accounts)+1) // +1 for the coinbase + for _, account := range accounts { + if !slices.Contains(addrs, account.addr) { + t.Fatalf("account %s not found in modified accounts", account.addr.Hex()) + } + } + }) +} From 85ae3e16f1a3456c158ba0109dad07502c4046e9 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Sun, 18 May 2025 10:25:16 +0200 Subject: [PATCH 373/940] cmd/devp2p/internal/ethtest: tests for BlockRangeUpdate (#31843) I added a test for BlockRangeUpdate in #29158 but forgot to enable it. Here I'm adding two more tests for it. Also applied a small refactoring to combine calls to `dial()` and `peer()` into a single function, since these two calls are duplicated in each test. --- cmd/devp2p/internal/ethtest/conn.go | 12 ++ cmd/devp2p/internal/ethtest/suite.go | 158 +++++++++++++++++---------- 2 files changed, 110 insertions(+), 60 deletions(-) diff --git a/cmd/devp2p/internal/ethtest/conn.go b/cmd/devp2p/internal/ethtest/conn.go index 6d8e0f1f7e..4a7a2c76d8 100644 --- a/cmd/devp2p/internal/ethtest/conn.go +++ b/cmd/devp2p/internal/ethtest/conn.go @@ -228,6 +228,18 @@ func (c *Conn) ReadSnap() (any, error) { } } +// dialAndPeer creates a peer connection and runs the handshake. +func (s *Suite) dialAndPeer(status *eth.StatusPacket69) (*Conn, error) { + c, err := s.dial() + if err != nil { + return nil, err + } + if err = c.peer(s.chain, status); err != nil { + c.Close() + } + return c, err +} + // peer performs both the protocol handshake and the status message // exchange with the node in order to peer with it. func (c *Conn) peer(chain *Chain, status *eth.StatusPacket69) error { diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go index b90ecf3ca3..97e8fd84fa 100644 --- a/cmd/devp2p/internal/ethtest/suite.go +++ b/cmd/devp2p/internal/ethtest/suite.go @@ -68,6 +68,10 @@ func (s *Suite) EthTests() []utesting.Test { return []utesting.Test{ // status {Name: "Status", Fn: s.TestStatus}, + {Name: "MaliciousHandshake", Fn: s.TestMaliciousHandshake}, + {Name: "BlockRangeUpdateExpired", Fn: s.TestBlockRangeUpdateHistoryExp}, + {Name: "BlockRangeUpdateFuture", Fn: s.TestBlockRangeUpdateFuture}, + {Name: "BlockRangeUpdateInvalid", Fn: s.TestBlockRangeUpdateInvalid}, // get block headers {Name: "GetBlockHeaders", Fn: s.TestGetBlockHeaders}, {Name: "GetNonexistentBlockHeaders", Fn: s.TestGetNonexistentBlockHeaders}, @@ -77,8 +81,6 @@ func (s *Suite) EthTests() []utesting.Test { // get history {Name: "GetBlockBodies", Fn: s.TestGetBlockBodies}, {Name: "GetReceipts", Fn: s.TestGetReceipts}, - // // malicious handshakes + status - {Name: "MaliciousHandshake", Fn: s.TestMaliciousHandshake}, // test transactions {Name: "LargeTxRequest", Fn: s.TestLargeTxRequest, Slow: true}, {Name: "Transaction", Fn: s.TestTransaction}, @@ -102,15 +104,11 @@ func (s *Suite) SnapTests() []utesting.Test { func (s *Suite) TestStatus(t *utesting.T) { t.Log(`This test is just a sanity check. It performs an eth protocol handshake.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - if err := conn.peer(s.chain, nil); err != nil { - t.Fatalf("peering failed: %v", err) + t.Fatal("peering failed:", err) } + conn.Close() } // headersMatch returns whether the received headers match the given request @@ -120,15 +118,12 @@ func headersMatch(expected []*types.Header, headers []*types.Header) bool { func (s *Suite) TestGetBlockHeaders(t *utesting.T) { t.Log(`This test requests block headers from the node.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - if err = conn.peer(s.chain, nil); err != nil { t.Fatalf("peering failed: %v", err) } + defer conn.Close() + // Send headers request. req := ð.GetBlockHeadersPacket{ RequestId: 33, @@ -161,18 +156,13 @@ func (s *Suite) TestGetBlockHeaders(t *utesting.T) { } func (s *Suite) TestGetNonexistentBlockHeaders(t *utesting.T) { - t.Log(`This test sends GetBlockHeaders requests for nonexistent blocks (using max uint64 value) + t.Log(`This test sends GetBlockHeaders requests for nonexistent blocks (using max uint64 value) to check if the node disconnects after receiving multiple invalid requests.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - - if err := conn.peer(s.chain, nil); err != nil { t.Fatalf("peering failed: %v", err) } + defer conn.Close() // Create request with max uint64 value for a nonexistent block badReq := ð.GetBlockHeadersPacket{ @@ -205,15 +195,11 @@ to check if the node disconnects after receiving multiple invalid requests.`) func (s *Suite) TestSimultaneousRequests(t *utesting.T) { t.Log(`This test requests blocks headers from the node, performing two requests concurrently, with different request IDs.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - if err := conn.peer(s.chain, nil); err != nil { t.Fatalf("peering failed: %v", err) } + defer conn.Close() // Create two different requests. req1 := ð.GetBlockHeadersPacket{ @@ -279,15 +265,11 @@ concurrently, with different request IDs.`) func (s *Suite) TestSameRequestID(t *utesting.T) { t.Log(`This test requests block headers, performing two concurrent requests with the same request ID. The node should handle the request by responding to both requests.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - if err := conn.peer(s.chain, nil); err != nil { t.Fatalf("peering failed: %v", err) } + defer conn.Close() // Create two different requests with the same ID. reqID := uint64(1234) @@ -350,15 +332,12 @@ same request ID. The node should handle the request by responding to both reques func (s *Suite) TestZeroRequestID(t *utesting.T) { t.Log(`This test sends a GetBlockHeaders message with a request-id of zero, and expects a response.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - if err := conn.peer(s.chain, nil); err != nil { t.Fatalf("peering failed: %v", err) } + defer conn.Close() + req := ð.GetBlockHeadersPacket{ GetBlockHeadersRequest: ð.GetBlockHeadersRequest{ Origin: eth.HashOrNumber{Number: 0}, @@ -385,15 +364,12 @@ and expects a response.`) func (s *Suite) TestGetBlockBodies(t *utesting.T) { t.Log(`This test sends GetBlockBodies requests to the node for known blocks in the test chain.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - if err := conn.peer(s.chain, nil); err != nil { t.Fatalf("peering failed: %v", err) } + defer conn.Close() + // Create block bodies request. req := ð.GetBlockBodiesPacket{ RequestId: 55, @@ -421,15 +397,11 @@ func (s *Suite) TestGetBlockBodies(t *utesting.T) { func (s *Suite) TestGetReceipts(t *utesting.T) { t.Log(`This test sends GetReceipts requests to the node for known blocks in the test chain.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) - } - defer conn.Close() - if err := conn.peer(s.chain, nil); err != nil { t.Fatalf("peering failed: %v", err) } + defer conn.Close() // Find some blocks containing receipts. var hashes = make([]common.Hash, 0, 3) @@ -546,17 +518,13 @@ func (s *Suite) TestMaliciousHandshake(t *utesting.T) { } } -func (s *Suite) TestInvalidBlockRangeUpdate(t *utesting.T) { +func (s *Suite) TestBlockRangeUpdateInvalid(t *utesting.T) { t.Log(`This test sends an invalid BlockRangeUpdate message to the node and expects to be disconnected.`) - - conn, err := s.dial() + conn, err := s.dialAndPeer(nil) if err != nil { - t.Fatalf("dial failed: %v", err) + t.Fatal(err) } defer conn.Close() - if err := conn.peer(s.chain, nil); err != nil { - t.Fatalf("peering failed: %v", err) - } conn.Write(ethProto, eth.BlockRangeUpdateMsg, ð.BlockRangeUpdatePacket{ EarliestBlock: 10, @@ -571,6 +539,76 @@ func (s *Suite) TestInvalidBlockRangeUpdate(t *utesting.T) { } } +func (s *Suite) TestBlockRangeUpdateFuture(t *utesting.T) { + t.Log(`This test sends a BlockRangeUpdate that is beyond the chain head. +The node should accept the update and should not disonnect.`) + conn, err := s.dialAndPeer(nil) + if err != nil { + t.Fatal(err) + } + defer conn.Close() + + head := s.chain.Head().NumberU64() + var hash common.Hash + rand.Read(hash[:]) + conn.Write(ethProto, eth.BlockRangeUpdateMsg, ð.BlockRangeUpdatePacket{ + EarliestBlock: head + 10, + LatestBlock: head + 50, + LatestBlockHash: hash, + }) + + // Ensure the node does not disconnect us. + // Just send a few ping messages. + for range 10 { + time.Sleep(100 * time.Millisecond) + if err := conn.Write(baseProto, pingMsg, []any{}); err != nil { + t.Fatal("write error:", err) + } + code, _, err := conn.Read() + switch { + case err != nil: + t.Fatal("read error:", err) + case code == discMsg: + t.Fatal("got disconnect") + case code == pongMsg: + } + } +} + +func (s *Suite) TestBlockRangeUpdateHistoryExp(t *utesting.T) { + t.Log(`This test sends a BlockRangeUpdate announcing incomplete (expired) history. +The node should accept the update and should not disonnect.`) + conn, err := s.dialAndPeer(nil) + if err != nil { + t.Fatal(err) + } + defer conn.Close() + + head := s.chain.Head() + conn.Write(ethProto, eth.BlockRangeUpdateMsg, ð.BlockRangeUpdatePacket{ + EarliestBlock: head.NumberU64() - 10, + LatestBlock: head.NumberU64(), + LatestBlockHash: head.Hash(), + }) + + // Ensure the node does not disconnect us. + // Just send a few ping messages. + for range 10 { + time.Sleep(100 * time.Millisecond) + if err := conn.Write(baseProto, pingMsg, []any{}); err != nil { + t.Fatal("write error:", err) + } + code, _, err := conn.Read() + switch { + case err != nil: + t.Fatal("read error:", err) + case code == discMsg: + t.Fatal("got disconnect") + case code == pongMsg: + } + } +} + func (s *Suite) TestTransaction(t *utesting.T) { t.Log(`This test sends a valid transaction to the node and checks if the transaction gets propagated.`) From 15057e7f7fbcb6b22f2f0a7e740b65db2959b78b Mon Sep 17 00:00:00 2001 From: Zhou Date: Mon, 19 May 2025 03:59:35 +0200 Subject: [PATCH 374/940] core: don't emit the warning of log indexing if the db was not initialized (#31845) --- core/filtermaps/filtermaps.go | 2 +- core/rawdb/accessors_indexes.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index b2c63f2e58..667d7c7623 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -227,7 +227,7 @@ type Config struct { // NewFilterMaps creates a new FilterMaps and starts the indexer. func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) *FilterMaps { rs, initialized, err := rawdb.ReadFilterMapsRange(db) - if err != nil || rs.Version != databaseVersion { + if err != nil || (initialized && rs.Version != databaseVersion) { rs, initialized = rawdb.FilterMapsRange{}, false log.Warn("Invalid log index database version; resetting log index") } diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index 1a5c414c8e..fafde25606 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -446,7 +446,7 @@ type FilterMapsRange struct { // database entry is not present, that is interpreted as a valid non-initialized // state and returns a blank range structure and no error. func ReadFilterMapsRange(db ethdb.KeyValueReader) (FilterMapsRange, bool, error) { - if has, err := db.Has(filterMapsRangeKey); !has || err != nil { + if has, err := db.Has(filterMapsRangeKey); err != nil || !has { return FilterMapsRange{}, false, err } encRange, err := db.Get(filterMapsRangeKey) @@ -457,7 +457,8 @@ func ReadFilterMapsRange(db ethdb.KeyValueReader) (FilterMapsRange, bool, error) if err := rlp.DecodeBytes(encRange, &fmRange); err != nil { return FilterMapsRange{}, false, err } - return fmRange, true, err + + return fmRange, true, nil } // WriteFilterMapsRange stores the filter maps range data. From 0867c24662f5c954c60b7ebdb3e32fc44e9a1bb4 Mon Sep 17 00:00:00 2001 From: maskpp Date: Mon, 19 May 2025 10:03:59 +0800 Subject: [PATCH 375/940] trie: use common.Hash as the key in secKeyCache map (#31786) --- trie/secure_trie.go | 60 +++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/trie/secure_trie.go b/trie/secure_trie.go index 45d5fd63e7..7852e16619 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -19,6 +19,7 @@ package trie import ( "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" "github.com/ethereum/go-ethereum/triedb/database" @@ -63,8 +64,7 @@ type StateTrie struct { trie Trie db database.NodeDatabase preimages preimageStore - hashKeyBuf [common.HashLength]byte - secKeyCache map[string][]byte + secKeyCache map[common.Hash][]byte secKeyCacheOwner *StateTrie // Pointer to self, replace the key cache on mismatch } @@ -97,7 +97,7 @@ func NewStateTrie(id *ID, db database.NodeDatabase) (*StateTrie, error) { // This function will omit any encountered error but just // print out an error message. func (t *StateTrie) MustGet(key []byte) []byte { - return t.trie.MustGet(t.hashKey(key)) + return t.trie.MustGet(crypto.Keccak256(key)) } // GetStorage attempts to retrieve a storage slot with provided account address @@ -105,7 +105,7 @@ func (t *StateTrie) MustGet(key []byte) []byte { // If the specified storage slot is not in the trie, nil will be returned. // If a trie node is not found in the database, a MissingNodeError is returned. func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) { - enc, err := t.trie.Get(t.hashKey(key)) + enc, err := t.trie.Get(crypto.Keccak256(key)) if err != nil || len(enc) == 0 { return nil, err } @@ -117,7 +117,7 @@ func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) { // If the specified account is not in the trie, nil will be returned. // If a trie node is not found in the database, a MissingNodeError is returned. func (t *StateTrie) GetAccount(address common.Address) (*types.StateAccount, error) { - res, err := t.trie.Get(t.hashKey(address.Bytes())) + res, err := t.trie.Get(crypto.Keccak256(address.Bytes())) if res == nil || err != nil { return nil, err } @@ -157,9 +157,9 @@ func (t *StateTrie) GetNode(path []byte) ([]byte, int, error) { // This function will omit any encountered error but just print out an // error message. func (t *StateTrie) MustUpdate(key, value []byte) { - hk := t.hashKey(key) + hk := crypto.Keccak256(key) t.trie.MustUpdate(hk, value) - t.getSecKeyCache()[string(hk)] = common.CopyBytes(key) + t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key) } // UpdateStorage associates key with value in the trie. Subsequent calls to @@ -171,19 +171,19 @@ func (t *StateTrie) MustUpdate(key, value []byte) { // // If a node is not found in the database, a MissingNodeError is returned. func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error { - hk := t.hashKey(key) + hk := crypto.Keccak256(key) v, _ := rlp.EncodeToBytes(value) err := t.trie.Update(hk, v) if err != nil { return err } - t.getSecKeyCache()[string(hk)] = common.CopyBytes(key) + t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key) return nil } // UpdateAccount will abstract the write of an account to the secure trie. func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount, _ int) error { - hk := t.hashKey(address.Bytes()) + hk := crypto.Keccak256(address.Bytes()) data, err := rlp.EncodeToBytes(acc) if err != nil { return err @@ -191,7 +191,7 @@ func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccoun if err := t.trie.Update(hk, data); err != nil { return err } - t.getSecKeyCache()[string(hk)] = address.Bytes() + t.getSecKeyCache()[common.Hash(hk)] = address.Bytes() return nil } @@ -202,8 +202,8 @@ func (t *StateTrie) UpdateContractCode(_ common.Address, _ common.Hash, _ []byte // MustDelete removes any existing value for key from the trie. This function // will omit any encountered error but just print out an error message. func (t *StateTrie) MustDelete(key []byte) { - hk := t.hashKey(key) - delete(t.getSecKeyCache(), string(hk)) + hk := crypto.Keccak256(key) + delete(t.getSecKeyCache(), common.Hash(hk)) t.trie.MustDelete(hk) } @@ -211,22 +211,22 @@ func (t *StateTrie) MustDelete(key []byte) { // If the specified trie node is not in the trie, nothing will be changed. // If a node is not found in the database, a MissingNodeError is returned. func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error { - hk := t.hashKey(key) - delete(t.getSecKeyCache(), string(hk)) + hk := crypto.Keccak256(key) + delete(t.getSecKeyCache(), common.Hash(hk)) return t.trie.Delete(hk) } // DeleteAccount abstracts an account deletion from the trie. func (t *StateTrie) DeleteAccount(address common.Address) error { - hk := t.hashKey(address.Bytes()) - delete(t.getSecKeyCache(), string(hk)) + hk := crypto.Keccak256(address.Bytes()) + delete(t.getSecKeyCache(), common.Hash(hk)) return t.trie.Delete(hk) } // GetKey returns the sha3 preimage of a hashed key that was // previously used to store a value. func (t *StateTrie) GetKey(shaKey []byte) []byte { - if key, ok := t.getSecKeyCache()[string(shaKey)]; ok { + if key, ok := t.getSecKeyCache()[common.BytesToHash(shaKey)]; ok { return key } if t.preimages == nil { @@ -251,13 +251,9 @@ 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 { 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.preimages.InsertPreimage(t.secKeyCache) } - t.secKeyCache = make(map[string][]byte) + t.secKeyCache = make(map[common.Hash][]byte) } // Commit the trie and return its modified nodeset. return t.trie.Commit(collectLeaf) @@ -291,25 +287,13 @@ func (t *StateTrie) MustNodeIterator(start []byte) NodeIterator { return t.trie.MustNodeIterator(start) } -// hashKey returns the hash of key as an ephemeral buffer. -// The caller must not hold onto the return value because it will become -// invalid on the next call to hashKey or secKey. -func (t *StateTrie) hashKey(key []byte) []byte { - h := newHasher(false) - h.sha.Reset() - h.sha.Write(key) - h.sha.Read(t.hashKeyBuf[:]) - returnHasherToPool(h) - return t.hashKeyBuf[:] -} - // getSecKeyCache returns the current secure key cache, creating a new one if // ownership changed (i.e. the current secure trie is a copy of another owning // the actual cache). -func (t *StateTrie) getSecKeyCache() map[string][]byte { +func (t *StateTrie) getSecKeyCache() map[common.Hash][]byte { if t != t.secKeyCacheOwner { t.secKeyCacheOwner = t - t.secKeyCache = make(map[string][]byte) + t.secKeyCache = make(map[common.Hash][]byte) } return t.secKeyCache } From e79177d1bca6bd21ed78bd8c2bf7144b36395c78 Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Mon, 19 May 2025 12:56:12 +0200 Subject: [PATCH 376/940] cmd/utils: remove duplicate code for influxDB tags (#31854) remove duplicate code Signed-off-by: Csaba Kiraly --- cmd/utils/flags.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 169f5ed49e..81c4172a53 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2020,7 +2020,6 @@ func SetupMetrics(cfg *metrics.Config) { log.Info("Enabling metrics export to InfluxDB") go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap) } else if enableExportV2 { - tagsMap := SplitTagsFlag(cfg.InfluxDBTags) log.Info("Enabling metrics export to InfluxDB (v2)") go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "geth.", tagsMap) } From 33c5031a2e6888dbac3dba0628c786442ceabc33 Mon Sep 17 00:00:00 2001 From: Zhou Date: Mon, 19 May 2025 10:55:17 -0300 Subject: [PATCH 377/940] internal: remove eth_{compile,getWork,submitWork} from console (#31856) The `compile` and `eth_getWork` `eth_submitWork` apis were not available anymore, so try to remove them --- internal/jsre/deps/web3.js | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index a4141bac43..0aa738a2af 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -5435,36 +5435,6 @@ var methods = function () { outputFormatter: utils.toDecimal }); - var compileSolidity = new Method({ - name: 'compile.solidity', - call: 'eth_compileSolidity', - params: 1 - }); - - var compileLLL = new Method({ - name: 'compile.lll', - call: 'eth_compileLLL', - params: 1 - }); - - var compileSerpent = new Method({ - name: 'compile.serpent', - call: 'eth_compileSerpent', - params: 1 - }); - - var submitWork = new Method({ - name: 'submitWork', - call: 'eth_submitWork', - params: 3 - }); - - var getWork = new Method({ - name: 'getWork', - call: 'eth_getWork', - params: 0 - }); - return [ getBalance, getStorageAt, @@ -5483,12 +5453,7 @@ var methods = function () { sendRawTransaction, signTransaction, sendTransaction, - sign, - compileSolidity, - compileLLL, - compileSerpent, - submitWork, - getWork + sign ]; }; From a67ea0c57dd7b387fc49138f4bdc1590c91e5a51 Mon Sep 17 00:00:00 2001 From: James Niken Date: Tue, 20 May 2025 09:58:00 +0200 Subject: [PATCH 378/940] internal/reexec: fix broken link to Docker/Moby in comment (#31859) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hey team—noticed a dead link, replaced it with a working URL https://github.com/moby/moby/blob/master/pkg/reexec/reexec.go - old link https://github.com/moby/moby/blob/master/pkg/reexec/reexec_deprecated.go - new link --- internal/reexec/reexec.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/reexec/reexec.go b/internal/reexec/reexec.go index 7dc6d9222e..50c0f43ab8 100644 --- a/internal/reexec/reexec.go +++ b/internal/reexec/reexec.go @@ -1,5 +1,5 @@ // This file originates from Docker/Moby, -// https://github.com/moby/moby/blob/master/pkg/reexec/reexec.go +// https://github.com/moby/moby/blob/master/pkg/reexec/reexec_deprecated.go // Licensed under Apache License 2.0: https://github.com/moby/moby/blob/master/LICENSE // Copyright 2013-2018 Docker, Inc. // From 24771fdba4fb7b414bfd5491b182ac0d22dfb33f Mon Sep 17 00:00:00 2001 From: VolodymyrBg Date: Tue, 20 May 2025 11:04:37 +0300 Subject: [PATCH 379/940] README: update broken JSON-RPC API documentation link (#31860) I've updated the broken link to point to the current official Ethereum JSON-RPC API documentation at https://ethereum.org/en/developers/docs/apis/json-rpc/. This is the correct and up-to-date location for the Ethereum Execution Layer APIs documentation. The link should now work properly. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9ccfe933aa..78a56baece 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,7 @@ accessible from the outside. As a developer, sooner rather than later you'll want to start interacting with `geth` and the Ethereum network via your own programs and not manually through the console. To aid -this, `geth` has built-in support for a JSON-RPC based APIs ([standard APIs](https://ethereum.github.io/execution-apis/api-documentation/) +this, `geth` has built-in support for a JSON-RPC based APIs ([standard APIs](https://ethereum.org/en/developers/docs/apis/json-rpc/) and [`geth` specific APIs](https://geth.ethereum.org/docs/interacting-with-geth/rpc)). These can be exposed via HTTP, WebSockets and IPC (UNIX sockets on UNIX based platforms, and named pipes on Windows). From e4a8ecb9473dfbc809d3f413412df1d05a78607c Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 20 May 2025 20:57:01 +0800 Subject: [PATCH 380/940] core/txpool/legacypool: fix flaky test TestAllowedTxSize #30975 (#31836) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some tests involving transactions near the txMaxSize limit were flaky. This was due to ECDSA signatures occasionally having leading zeros, which are omitted during RLP encoding — making the final transaction size 1 byte smaller than expected. To address this, a new helper function pricedDataTransactionWithFixedSignature was added. It ensures both r and s are exactly 32 bytes (i.e., no leading zeros), producing transactions with deterministic size. --- core/txpool/legacypool/legacypool_test.go | 32 +++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 2fdf890320..1ba080b749 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -108,11 +108,33 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec return tx } -func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, bytes uint64) *types.Transaction { - data := make([]byte, bytes) - crand.Read(data) +// pricedDataTransaction generates a signed transaction with fixed-size data, +// and ensures that the resulting signature components (r and s) are exactly 32 bytes each, +// producing transactions with deterministic size. +// +// This avoids variability in transaction size caused by leading zeros being omitted in +// RLP encoding of r/s. Since r and s are derived from ECDSA, they occasionally have leading +// zeros and thus can be shorter than 32 bytes. +// +// For example: +// +// r: 0 leading zeros, bytesSize: 32, bytes: [221 ... 101] +// s: 1 leading zeros, bytesSize: 31, bytes: [0 75 ... 47] +func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, dataBytes uint64) *types.Transaction { + var tx *types.Transaction - tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key) + // 10 attempts is statistically sufficient since leading zeros in ECDSA signatures are rare and randomly distributed. + var retryTimes = 10 + for i := 0; i < retryTimes; i++ { + data := make([]byte, dataBytes) + crand.Read(data) + + tx, _ = types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key) + _, r, s := tx.RawSignatureValues() + if len(r.Bytes()) == 32 && len(s.Bytes()) == 32 { + break + } + } return tx } @@ -1239,7 +1261,7 @@ func TestAllowedTxSize(t *testing.T) { const largeDataLength = txMaxSize - 200 // enough to have a 5 bytes RLP encoding of the data length number txWithLargeData := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, largeDataLength) maxTxLengthWithoutData := txWithLargeData.Size() - largeDataLength // 103 bytes - maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130953 bytes + maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130969 bytes // Try adding a transaction with maximal allowed size tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength) From 62aa6b2621631f61c51e678948556750eabfc620 Mon Sep 17 00:00:00 2001 From: shahafn Date: Tue, 20 May 2025 16:38:33 +0300 Subject: [PATCH 381/940] eth/tracers/native: add erc7562 tracer (#31006) This PR introduces a new native tracer for AA bundlers. Bundlers participating in the alternative mempool will need to validate userops. This tracer will return sufficient information for them to decide whether griefing is possible. Resolves #30546 --------- Co-authored-by: Sina M <1591639+s1na@users.noreply.github.com> --- .../internal/tracetest/erc7562_tracer_test.go | 144 +++++ .../erc7562Tracer.test_deployer.json | 110 ++++ .../erc7562Tracer.test_paymaster.json | 110 ++++ .../erc7562Tracer.test_simple.json | 246 ++++++++ eth/tracers/native/erc7562.go | 530 ++++++++++++++++++ .../native/gen_callframewithopcodes_json.go | 159 ++++++ 6 files changed, 1299 insertions(+) create mode 100644 eth/tracers/internal/tracetest/erc7562_tracer_test.go create mode 100644 eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_deployer.json create mode 100644 eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_paymaster.json create mode 100644 eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_simple.json create mode 100644 eth/tracers/native/erc7562.go create mode 100644 eth/tracers/native/gen_callframewithopcodes_json.go diff --git a/eth/tracers/internal/tracetest/erc7562_tracer_test.go b/eth/tracers/internal/tracetest/erc7562_tracer_test.go new file mode 100644 index 0000000000..f6e81f5886 --- /dev/null +++ b/eth/tracers/internal/tracetest/erc7562_tracer_test.go @@ -0,0 +1,144 @@ +// Copyright 2025 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 ( + "encoding/json" + "math/big" + "os" + "path/filepath" + "strings" + "testing" + + "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/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/tests" + "github.com/stretchr/testify/require" +) + +type accessedSlots struct { + Reads map[string][]string `json:"reads"` + Writes map[string]uint64 `json:"writes"` + TransientReads map[string]uint64 `json:"transientReads"` + TransientWrites map[string]uint64 `json:"transientWrites"` +} +type contractSizeWithOpcode struct { + ContractSize int `json:"contractSize"` + Opcode vm.OpCode `json:"opcode"` +} + +// erc7562Trace is the result of a erc7562Tracer run. +type erc7562Trace struct { + From common.Address `json:"from"` + Gas *hexutil.Uint64 `json:"gas"` + GasUsed *hexutil.Uint64 `json:"gasUsed"` + To *common.Address `json:"to,omitempty" rlp:"optional"` + Input hexutil.Bytes `json:"input" rlp:"optional"` + Output hexutil.Bytes `json:"output,omitempty" rlp:"optional"` + Error string `json:"error,omitempty" rlp:"optional"` + RevertReason string `json:"revertReason,omitempty"` + Logs []callLog `json:"logs,omitempty" rlp:"optional"` + Value *hexutil.Big `json:"value,omitempty" rlp:"optional"` + AccessedSlots accessedSlots `json:"accessedSlots"` + ExtCodeAccessInfo []common.Address `json:"extCodeAccessInfo"` + UsedOpcodes map[hexutil.Uint64]uint64 `json:"usedOpcodes"` + ContractSize map[common.Address]*contractSizeWithOpcode `json:"contractSize"` + OutOfGas bool `json:"outOfGas"` + Calls []erc7562Trace `json:"calls,omitempty" rlp:"optional"` + Keccak []hexutil.Bytes `json:"keccak,omitempty"` + Type string `json:"type"` +} + +// erc7562TracerTest defines a single test to check the erc7562 tracer against. +type erc7562TracerTest struct { + tracerTestEnv + Result *erc7562Trace `json:"result"` +} + +func TestErc7562Tracer(t *testing.T) { + dirPath := "erc7562_tracer" + tracerName := "erc7562Tracer" + files, err := os.ReadDir(filepath.Join("testdata", dirPath)) + if err != nil { + t.Fatalf("failed to retrieve tracer test suite: %v", err) + } + for _, file := range files { + if !strings.HasSuffix(file.Name(), ".json") { + continue + } + t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) { + t.Parallel() + + var ( + test = new(erc7562TracerTest) + tx = new(types.Transaction) + ) + // erc7562 tracer test found, read if from disk + if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil { + t.Fatalf("failed to read testcase: %v", err) + } else if err := json.Unmarshal(blob, test); err != nil { + t.Fatalf("failed to parse testcase: %v", err) + } + if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil { + t.Fatalf("failed to parse testcase input: %v", err) + } + // 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 = test.Context.toBlockContext(test.Genesis) + st = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) + ) + st.Close() + + tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig, test.Genesis.Config) + if err != nil { + t.Fatalf("failed to create erc7562 tracer: %v", err) + } + logState := vm.StateDB(st.StateDB) + if tracer.Hooks != nil { + logState = state.NewHookedState(st.StateDB, 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, logState, 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 { + t.Fatalf("failed to retrieve trace result: %v", err) + } + want, err := json.Marshal(test.Result) + if err != nil { + t.Fatalf("failed to marshal test: %v", err) + } + require.JSONEq(t, string(res), string(want)) + }) + } +} diff --git a/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_deployer.json b/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_deployer.json new file mode 100644 index 0000000000..2d785a1655 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_deployer.json @@ -0,0 +1,110 @@ +{ + "genesis": { + "baseFeePerGas": "1664", + "blobGasUsed": "0", + "difficulty": "0", + "excessBlobGas": "0", + "extraData": "0xd883010e0d846765746888676f312e32322e36856c696e7578", + "gasLimit": "30000000", + "hash": "0xc567fbb11719be3bc47e77269365baef50b1fc0149f2a366a35f82ddba608b28", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0x792aa153a3b49ad9eb965809fedc3b11c343da37b1edebe101401711c63eb53c", + "nonce": "0x0000000000000000", + "number": "114", + "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "stateRoot": "0xf18f522f27f64c34e56338820450991b6fcb7a2a311224d2bfba7afa5734888b", + "timestamp": "1738267577", + "withdrawals": [], + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "alloc": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x285013864dbff82" + }, + "0x0000000071727de22e5e9d8baf0edac6f37da032": { + "balance": "0x49c2dbeb2e8d0f042", + "code": "0x60806040526004361015610024575b361561001957600080fd5b61002233612748565b005b60003560e01c806242dc5314611b0057806301ffc9a7146119ae5780630396cb60146116765780630bd28e3b146115fa5780631b2e01b814611566578063205c2878146113d157806322cdde4c1461136b57806335567e1a146112b35780635287ce12146111a557806370a0823114611140578063765e827f14610e82578063850aaf6214610dc35780639b249f6914610c74578063b760faf914610c3a578063bb9fe6bf14610a68578063c23a5cea146107c4578063dbed18e0146101a15763fc7e286d0361000e573461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61013a61229f565b16600052600060205260a0604060002065ffffffffffff6001825492015460405192835260ff8116151560208401526dffffffffffffffffffffffffffff8160081c16604084015263ffffffff8160781c16606084015260981c166080820152f35b600080fd5b3461019c576101af36612317565b906101b86129bd565b60009160005b82811061056f57506101d08493612588565b6000805b8481106102fc5750507fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000809360005b81811061024757610240868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2613ba7565b6001600255005b6102a261025582848a612796565b73ffffffffffffffffffffffffffffffffffffffff6102766020830161282a565b167f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a2806127d6565b906000915b8083106102b957505050600101610209565b909194976102f36102ed6001926102e78c8b6102e0826102da8e8b8d61269d565b9261265a565b5191613597565b90612409565b99612416565b950191906102a7565b6020610309828789612796565b61031f61031682806127d6565b9390920161282a565b9160009273ffffffffffffffffffffffffffffffffffffffff8091165b8285106103505750505050506001016101d4565b909192939561037f83610378610366848c61265a565b516103728b898b61269d565b856129f6565b9290613dd7565b9116840361050a576104a5576103958491613dd7565b9116610440576103b5576103aa600191612416565b96019392919061033c565b60a487604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608489604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b61057a818487612796565b9361058585806127d6565b919095602073ffffffffffffffffffffffffffffffffffffffff6105aa82840161282a565b1697600192838a1461076657896105da575b5050505060019293949550906105d191612409565b939291016101be565b8060406105e892019061284b565b918a3b1561019c57929391906040519485937f2dd8113300000000000000000000000000000000000000000000000000000000855288604486016040600488015252606490818601918a60051b8701019680936000915b8c83106106e657505050505050838392610684927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8560009803016024860152612709565b03818a5afa90816106d7575b506106c657602486604051907f86a9f7500000000000000000000000000000000000000000000000000000000082526004820152fd5b93945084936105d1600189806105bc565b6106e0906121bd565b88610690565b91939596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c908a9294969a0301865288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181121561019c57836107538793858394016128ec565b9a0196019301909189979695949261063f565b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b3461019c576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576107fc61229f565b33600052600082526001604060002001908154916dffffffffffffffffffffffffffff8360081c16928315610a0a5765ffffffffffff8160981c1680156109ac57421061094e5760009373ffffffffffffffffffffffffffffffffffffffff859485947fffffffffffffff000000000000000000000000000000000000000000000000ff86951690556040517fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda33391806108da8786836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b0390a2165af16108e8612450565b50156108f057005b606490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b3461019c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c573360005260006020526001604060002001805463ffffffff8160781c16908115610bdc5760ff1615610b7e5765ffffffffffff908142160191818311610b4f5780547fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff001678ffffffffffff00000000000000000000000000000000000000609885901b161790556040519116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a2005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610022610c6f61229f565b612748565b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043567ffffffffffffffff811161019c576020610cc8610d1b9236906004016122c2565b919073ffffffffffffffffffffffffffffffffffffffff9260405194859283927f570e1a360000000000000000000000000000000000000000000000000000000084528560048501526024840191612709565b03816000857f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c165af1908115610db757602492600092610d86575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b610da991925060203d602011610db0575b610da181836121ed565b8101906126dd565b9083610d56565b503d610d97565b6040513d6000823e3d90fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610dfa61229f565b60243567ffffffffffffffff811161019c57600091610e1e839236906004016122c2565b90816040519283928337810184815203915af4610e39612450565b90610e7e6040519283927f99410554000000000000000000000000000000000000000000000000000000008452151560048401526040602484015260448301906123c6565b0390fd5b3461019c57610e9036612317565b610e9b9291926129bd565b610ea483612588565b60005b848110610f1c57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000915b858310610eec576102408585613ba7565b909193600190610f12610f0087898761269d565b610f0a888661265a565b519088613597565b0194019190610edb565b610f47610f40610f2e8385979561265a565b51610f3a84898761269d565b846129f6565b9190613dd7565b73ffffffffffffffffffffffffffffffffffffffff929183166110db5761107657610f7190613dd7565b911661101157610f8657600101929092610ea7565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608483604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61118c61229f565b1660005260006020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff6111f161229f565b6000608060405161120181612155565b828152826020820152826040820152826060820152015216600052600060205260a06040600020608060405161123681612155565b6001835493848352015490602081019060ff8316151582526dffffffffffffffffffffffffffff60408201818560081c16815263ffffffff936060840193858760781c16855265ffffffffffff978891019660981c1686526040519788525115156020880152511660408601525116606084015251166080820152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760206112ec61229f565b73ffffffffffffffffffffffffffffffffffffffff6113096122f0565b911660005260018252604060002077ffffffffffffffffffffffffffffffffffffffffffffffff821660005282526040600020547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b3461019c577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60208136011261019c576004359067ffffffffffffffff821161019c5761012090823603011261019c576113c9602091600401612480565b604051908152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761140861229f565b60243590336000526000602052604060002090815491828411611508576000808573ffffffffffffffffffffffffffffffffffffffff8295839561144c848a612443565b90556040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af16114a2612450565b50156114aa57005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761159d61229f565b73ffffffffffffffffffffffffffffffffffffffff6115ba6122f0565b9116600052600160205277ffffffffffffffffffffffffffffffffffffffffffffffff604060002091166000526020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043577ffffffffffffffffffffffffffffffffffffffffffffffff811680910361019c5733600052600160205260406000209060005260205260406000206116728154612416565b9055005b6020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043563ffffffff9182821680920361019c5733600052600081526040600020928215611950576001840154908160781c1683106118f2576116f86dffffffffffffffffffffffffffff9182349160081c16612409565b93841561189457818511611836579065ffffffffffff61180592546040519061172082612155565b8152848101926001845260408201908816815260608201878152600160808401936000855233600052600089526040600020905181550194511515917fffffffffffffffffffffffffff0000000000000000000000000000000000000060ff72ffffffff0000000000000000000000000000006effffffffffffffffffffffffffff008954945160081b16945160781b1694169116171717835551167fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffff78ffffffffffff0000000000000000000000000000000000000083549260981b169116179055565b6040519283528201527fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c0160403392a2005b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361019c57807f60fc6b6e0000000000000000000000000000000000000000000000000000000060209214908115611ad6575b8115611aac575b8115611a82575b8115611a58575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482611a4d565b7f3e84f0210000000000000000000000000000000000000000000000000000000081149150611a46565b7fcf28ef970000000000000000000000000000000000000000000000000000000081149150611a3f565b7f915074d80000000000000000000000000000000000000000000000000000000081149150611a38565b3461019c576102007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5767ffffffffffffffff60043581811161019c573660238201121561019c57611b62903690602481600401359101612268565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101c0811261019c5761014060405191611b9e83612155565b1261019c5760405192611bb0846121a0565b60243573ffffffffffffffffffffffffffffffffffffffff8116810361019c578452602093604435858201526064356040820152608435606082015260a435608082015260c43560a082015260e43560c08201526101043573ffffffffffffffffffffffffffffffffffffffff8116810361019c5760e08201526101243561010082015261014435610120820152825261016435848301526101843560408301526101a43560608301526101c43560808301526101e43590811161019c57611c7c9036906004016122c2565b905a3033036120f7578351606081015195603f5a0260061c61271060a0840151890101116120ce5760009681519182611ff0575b5050505090611cca915a9003608085015101923691612268565b925a90600094845193611cdc85613ccc565b9173ffffffffffffffffffffffffffffffffffffffff60e0870151168015600014611ea957505073ffffffffffffffffffffffffffffffffffffffff855116935b5a9003019360a06060820151910151016080860151850390818111611e95575b50508302604085015192818410600014611dce5750506003811015611da157600203611d79576113c99293508093611d7481613d65565b613cf6565b5050507fdeadaa51000000000000000000000000000000000000000000000000000000008152fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b81611dde92979396940390613c98565b506003841015611e6857507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f60808683015192519473ffffffffffffffffffffffffffffffffffffffff865116948873ffffffffffffffffffffffffffffffffffffffff60e0890151169701519160405192835215898301528760408301526060820152a46113c9565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526021600452fd5b6064919003600a0204909301928780611d3d565b8095918051611eba575b5050611d1d565b6003861015611fc1576002860315611eb35760a088015190823b1561019c57600091611f2491836040519586809581947f7c627b210000000000000000000000000000000000000000000000000000000083528d60048401526080602484015260848301906123c6565b8b8b0260448301528b60648301520393f19081611fad575b50611fa65787893d610800808211611f9e575b506040519282828501016040528184528284013e610e7e6040519283927fad7954bc000000000000000000000000000000000000000000000000000000008452600484015260248301906123c6565b905083611f4f565b8980611eb3565b611fb89199506121bd565b6000978a611f3c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91600092918380938c73ffffffffffffffffffffffffffffffffffffffff885116910192f115612023575b808080611cb0565b611cca929195503d6108008082116120c6575b5060405190888183010160405280825260008983013e805161205f575b5050600194909161201b565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20188870151918973ffffffffffffffffffffffffffffffffffffffff8551169401516120bc604051928392835260408d84015260408301906123c6565b0390a38680612053565b905088612036565b877fdeaddead000000000000000000000000000000000000000000000000000000006000526000fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b60a0810190811067ffffffffffffffff82111761217157604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610140810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157604052565b6060810190811067ffffffffffffffff82111761217157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926122748261222e565b9161228260405193846121ed565b82948184528183011161019c578281602093846000960137010152565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9181601f8401121561019c5782359167ffffffffffffffff831161019c576020838186019501011161019c57565b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261019c5760043567ffffffffffffffff9283821161019c578060238301121561019c57816004013593841161019c5760248460051b8301011161019c57602401919060243573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b60005b8381106123b65750506000910152565b81810151838201526020016123a6565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093612402815180928187528780880191016123a3565b0116010190565b91908201809211610b4f57565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610b4f5760010190565b91908203918211610b4f57565b3d1561247b573d906124618261222e565b9161246f60405193846121ed565b82523d6000602084013e565b606090565b604061248e8183018361284b565b90818351918237206124a3606084018461284b565b90818451918237209260c06124bb60e083018361284b565b908186519182372091845195602087019473ffffffffffffffffffffffffffffffffffffffff833516865260208301358789015260608801526080870152608081013560a087015260a081013582870152013560e08501526101009081850152835261012083019167ffffffffffffffff918484108385111761217157838252845190206101408501908152306101608601524661018086015260608452936101a00191821183831017612171575251902090565b67ffffffffffffffff81116121715760051b60200190565b9061259282612570565b6040906125a260405191826121ed565b8381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06125d08295612570565b019160005b8381106125e25750505050565b60209082516125f081612155565b83516125fb816121a0565b600081526000849181838201528187820152816060818184015260809282848201528260a08201528260c08201528260e082015282610100820152826101208201528652818587015281898701528501528301528286010152016125d5565b805182101561266e5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b919081101561266e5760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18136030182121561019c570190565b9081602091031261019c575173ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b7f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4602073ffffffffffffffffffffffffffffffffffffffff61278a3485613c98565b936040519485521692a2565b919081101561266e5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18136030182121561019c570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c57602001918160051b3603831361019c57565b3573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c5760200191813603831361019c57565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561019c57016020813591019167ffffffffffffffff821161019c57813603831361019c57565b61012091813573ffffffffffffffffffffffffffffffffffffffff811680910361019c576129626129476129ba9561299b93855260208601356020860152612937604087018761289c565b9091806040880152860191612709565b612954606086018661289c565b908583036060870152612709565b6080840135608084015260a084013560a084015260c084013560c084015261298d60e085018561289c565b9084830360e0860152612709565b916129ac610100918281019061289c565b929091818503910152612709565b90565b60028054146129cc5760028055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b926000905a93805194843573ffffffffffffffffffffffffffffffffffffffff811680910361019c5786526020850135602087015260808501356fffffffffffffffffffffffffffffffff90818116606089015260801c604088015260a086013560c088015260c086013590811661010088015260801c610120870152612a8060e086018661284b565b801561357b576034811061351d578060141161019c578060241161019c5760341161019c57602481013560801c60a0880152601481013560801c60808801523560601c60e08701525b612ad285612480565b60208301526040860151946effffffffffffffffffffffffffffff8660c08901511760608901511760808901511760a0890151176101008901511761012089015117116134bf57604087015160608801510160808801510160a08801510160c0880151016101008801510296835173ffffffffffffffffffffffffffffffffffffffff81511690612b66604085018561284b565b806131e4575b505060e0015173ffffffffffffffffffffffffffffffffffffffff1690600082156131ac575b6020612bd7918b828a01516000868a604051978896879586937f19822f7c00000000000000000000000000000000000000000000000000000000855260048501613db5565b0393f160009181613178575b50612c8b573d8c610800808311612c83575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141323320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612bf5565b9a92939495969798999a91156130f2575b509773ffffffffffffffffffffffffffffffffffffffff835116602084015190600052600160205260406000208160401c60005260205267ffffffffffffffff604060002091825492612cee84612416565b9055160361308d575a8503116130285773ffffffffffffffffffffffffffffffffffffffff60e0606093015116612d42575b509060a09184959697986040608096015260608601520135905a900301910152565b969550505a9683519773ffffffffffffffffffffffffffffffffffffffff60e08a01511680600052600060205260406000208054848110612fc3576080612dcd9a9b9c600093878094039055015192602089015183604051809d819582947f52b7512c0000000000000000000000000000000000000000000000000000000084528c60048501613db5565b039286f1978860009160009a612f36575b50612e86573d8b610800808311612e7e575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141333320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612df0565b9991929394959697989998925a900311612eab57509096959094939291906080612d20565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602760448201527f41413336206f766572207061796d6173746572566572696669636174696f6e4760648201527f61734c696d6974000000000000000000000000000000000000000000000000006084820152fd5b915098503d90816000823e612f4b82826121ed565b604081838101031261019c5780519067ffffffffffffffff821161019c57828101601f83830101121561019c578181015191612f868361222e565b93612f9460405195866121ed565b838552820160208483850101011161019c57602092612fba9184808701918501016123a3565b01519838612dde565b60848b604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413331207061796d6173746572206465706f73697420746f6f206c6f7700006064820152fd5b608490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413236206f76657220766572696669636174696f6e4761734c696d697400006064820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601a60448201527f4141323520696e76616c6964206163636f756e74206e6f6e63650000000000006064820152fd5b600052600060205260406000208054808c11613113578b9003905538612c9c565b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152fd5b9091506020813d6020116131a4575b81613194602093836121ed565b8101031261019c57519038612be3565b3d9150613187565b508060005260006020526040600020548a81116000146131d75750612bd7602060005b915050612b92565b6020612bd7918c036131cf565b833b61345a57604088510151602060405180927f570e1a360000000000000000000000000000000000000000000000000000000082528260048301528160008161323260248201898b612709565b039273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c1690f1908115610db75760009161343b575b5073ffffffffffffffffffffffffffffffffffffffff811680156133d6578503613371573b1561330c5760141161019c5773ffffffffffffffffffffffffffffffffffffffff9183887fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d604060e0958787602086015195510151168251913560601c82526020820152a391612b6c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152fd5b60848e604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313420696e6974436f6465206d7573742072657475726e2073656e6465726064820152fd5b60848f604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601b60448201527f4141313320696e6974436f6465206661696c6564206f72204f4f4700000000006064820152fd5b613454915060203d602011610db057610da181836121ed565b3861327c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b5050600060e087015260006080870152600060a0870152612ac9565b9092915a906060810151916040928351967fffffffff00000000000000000000000000000000000000000000000000000000886135d7606084018461284b565b600060038211613b9f575b7f8dd7712f0000000000000000000000000000000000000000000000000000000094168403613a445750505061379d6000926136b292602088015161363a8a5193849360208501528b602485015260648401906128ec565b90604483015203906136727fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0928381018352826121ed565b61379189519485927e42dc5300000000000000000000000000000000000000000000000000000000602085015261020060248501526102248401906123c6565b613760604484018b60806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152876123c6565b039081018352826121ed565b6020918183809351910182305af1600051988652156137bf575b505050505050565b909192939495965060003d8214613a3a575b7fdeaddead00000000000000000000000000000000000000000000000000000000810361385b57608487878051917f220266b600000000000000000000000000000000000000000000000000000000835260048301526024820152600f60448201527f41413935206f7574206f662067617300000000000000000000000000000000006064820152fd5b7fdeadaa510000000000000000000000000000000000000000000000000000000091929395949650146000146138c55750506138a961389e6138b8935a90612443565b608085015190612409565b9083015183611d748295613d65565b905b3880808080806137b7565b909261395290828601518651907ff62676f440ff169a3a9afdbf812e89e7f95975ee8e5c31214ffdef631c5f479273ffffffffffffffffffffffffffffffffffffffff9580878551169401516139483d610800808211613a32575b508a519084818301018c5280825260008583013e8a805194859485528401528a8301906123c6565b0390a35a90612443565b916139636080860193845190612409565b926000905a94829488519761397789613ccc565b948260e08b0151168015600014613a1857505050875116955b5a9003019560a06060820151910151019051860390818111613a04575b5050840290850151928184106000146139de57505080611e68575090816139d89293611d7481613d65565b906138ba565b6139ee9082849397950390613c98565b50611e68575090826139ff92613cf6565b6139d8565b6064919003600a02049094019338806139ad565b90919892509751613a2a575b50613990565b955038613a24565b905038613920565b8181803e516137d1565b613b97945082935090613a8c917e42dc53000000000000000000000000000000000000000000000000000000006020613b6b9501526102006024860152610224850191612709565b613b3a604484018860806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152846123c6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018952886121ed565b60008761379d565b5081356135e2565b73ffffffffffffffffffffffffffffffffffffffff168015613c3a57600080809381935af1613bd4612450565b5015613bdc57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff166000526000602052613cc66040600020918254612409565b80915590565b610120610100820151910151808214613cf257480180821015613ced575090565b905090565b5090565b9190917f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f6080602083015192519473ffffffffffffffffffffffffffffffffffffffff946020868851169660e089015116970151916040519283526000602084015260408301526060820152a4565b60208101519051907f67b4fa9642f42120bf031f3051d1824b0fe25627945b27b8a6a65d5761d5482e60208073ffffffffffffffffffffffffffffffffffffffff855116940151604051908152a3565b613dcd604092959493956060835260608301906128ec565b9460208201520152565b8015613e6457600060408051613dec816121d1565b828152826020820152015273ffffffffffffffffffffffffffffffffffffffff811690604065ffffffffffff91828160a01c16908115613e5c575b60d01c92825191613e37836121d1565b8583528460208401521691829101524211908115613e5457509091565b905042109091565b839150613e27565b5060009060009056fea2646970667358221220b094fd69f04977ae9458e5ba422d01cd2d20dbcfca0992ff37f19aa07deec25464736f6c63430008170033", + "nonce": "2", + "storage": { + "0xa3b2ff63dddb6717733673f0c1cf67be4e4eecc50d4e5fd777cf82e814f7242f": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0x7ab5742e5b448c142a35c92699fd2dd6b8930cbd": { + "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffb0dc02146cf089f65", + "nonce": "110" + } + }, + "config": { + "chainId": 1337, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "rip7560block": 0, + "rip7712block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "pragueTime": 0, + "terminalTotalDifficulty": 0, + "depositContractAddress": "0x0000000000000000000000000000000000000000", + "blobSchedule": { + "cancun": { + "max": 6, + "target": 3, + "baseFeeUpdateFraction": 3338477 + }, + "prague": { + "max": 9, + "target": 6, + "baseFeeUpdateFraction": 5007716 + } + } + } + }, + "context": { + "number": "115", + "difficulty": "0", + "timestamp": "1738267578", + "gasLimit": "30000000", + "miner": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "1457" + }, + "input": "0x02f8998205396e843b99d302843b99e00283023a3c940000000071727de22e5e9d8baf0edac6f37da032880de0b6b3a7640000a4b760faf90000000000000000000000005604b855b3708057705f8dfc0e6470917082c43ac001a03a94ab9585bd0a378ddfcaa078a3982bb88e60c22407de299ad314b8a8631a31a0720f8eb0d92906238bc842b387ee147519d9b05e22d8c77d5a855cb16744d660", + "result": { + "accessedSlots": { + "reads": { + "0xa3b2ff63dddb6717733673f0c1cf67be4e4eecc50d4e5fd777cf82e814f7242f": [ + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + }, + "transientReads": {}, + "transientWrites": {}, + "writes": { + "0xa3b2ff63dddb6717733673f0c1cf67be4e4eecc50d4e5fd777cf82e814f7242f": 1 + } + }, + "contractSize": {}, + "extCodeAccessInfo": [], + "from": "0x7ab5742e5b448c142a35c92699fd2dd6b8930cbd", + "gas": "0x23a3c", + "gasUsed": "0xb21f", + "input": "0xb760faf90000000000000000000000005604b855b3708057705f8dfc0e6470917082c43a", + "keccak": [ + "0x0000000000000000000000005604b855b3708057705f8dfc0e6470917082c43a0000000000000000000000000000000000000000000000000000000000000000" + ], + "outOfGas": false, + "to": "0x0000000071727de22e5e9d8baf0edac6f37da032", + "type": "CALL", + "usedOpcodes": {"0x0":1, "0x20":1, "0x34":1, "0x35":2, "0x36":2, "0x51":1, "0x52":4, "0x54":1, "0x55":1, "0x56":8, "0x57":18, "0x5b":10, "0xa2":1}, + "value": "0xde0b6b3a7640000" + } +} diff --git a/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_paymaster.json b/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_paymaster.json new file mode 100644 index 0000000000..a7e09f761e --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_paymaster.json @@ -0,0 +1,110 @@ +{ + "genesis": { + "baseFeePerGas": "63230", + "blobGasUsed": "0", + "difficulty": "0", + "excessBlobGas": "0", + "extraData": "0xd883010e0d846765746888676f312e32322e36856c696e7578", + "gasLimit": "30000000", + "hash": "0x38e598c8c0600233b8353fb28aa12e987be7216fcb141cffb03d941141dac085", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0xc406f87ac4eb5e4d1d95345ceb92a3f17a7c97f6e9d4c1c857601960cd91d3b2", + "nonce": "0x0000000000000000", + "number": "84", + "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "stateRoot": "0xc0df2d6f5e7199feff4e49bf23d05f5758d85b146159b1b5b53700bee1b0c073", + "timestamp": "1738266969", + "withdrawals": [], + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "alloc": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x1fbe9bb2534e03d" + }, + "0x0000000071727de22e5e9d8baf0edac6f37da032": { + "balance": "0x3a21a6c6853747fff", + "code": "0x60806040526004361015610024575b361561001957600080fd5b61002233612748565b005b60003560e01c806242dc5314611b0057806301ffc9a7146119ae5780630396cb60146116765780630bd28e3b146115fa5780631b2e01b814611566578063205c2878146113d157806322cdde4c1461136b57806335567e1a146112b35780635287ce12146111a557806370a0823114611140578063765e827f14610e82578063850aaf6214610dc35780639b249f6914610c74578063b760faf914610c3a578063bb9fe6bf14610a68578063c23a5cea146107c4578063dbed18e0146101a15763fc7e286d0361000e573461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61013a61229f565b16600052600060205260a0604060002065ffffffffffff6001825492015460405192835260ff8116151560208401526dffffffffffffffffffffffffffff8160081c16604084015263ffffffff8160781c16606084015260981c166080820152f35b600080fd5b3461019c576101af36612317565b906101b86129bd565b60009160005b82811061056f57506101d08493612588565b6000805b8481106102fc5750507fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000809360005b81811061024757610240868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2613ba7565b6001600255005b6102a261025582848a612796565b73ffffffffffffffffffffffffffffffffffffffff6102766020830161282a565b167f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a2806127d6565b906000915b8083106102b957505050600101610209565b909194976102f36102ed6001926102e78c8b6102e0826102da8e8b8d61269d565b9261265a565b5191613597565b90612409565b99612416565b950191906102a7565b6020610309828789612796565b61031f61031682806127d6565b9390920161282a565b9160009273ffffffffffffffffffffffffffffffffffffffff8091165b8285106103505750505050506001016101d4565b909192939561037f83610378610366848c61265a565b516103728b898b61269d565b856129f6565b9290613dd7565b9116840361050a576104a5576103958491613dd7565b9116610440576103b5576103aa600191612416565b96019392919061033c565b60a487604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608489604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b61057a818487612796565b9361058585806127d6565b919095602073ffffffffffffffffffffffffffffffffffffffff6105aa82840161282a565b1697600192838a1461076657896105da575b5050505060019293949550906105d191612409565b939291016101be565b8060406105e892019061284b565b918a3b1561019c57929391906040519485937f2dd8113300000000000000000000000000000000000000000000000000000000855288604486016040600488015252606490818601918a60051b8701019680936000915b8c83106106e657505050505050838392610684927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8560009803016024860152612709565b03818a5afa90816106d7575b506106c657602486604051907f86a9f7500000000000000000000000000000000000000000000000000000000082526004820152fd5b93945084936105d1600189806105bc565b6106e0906121bd565b88610690565b91939596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c908a9294969a0301865288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181121561019c57836107538793858394016128ec565b9a0196019301909189979695949261063f565b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b3461019c576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576107fc61229f565b33600052600082526001604060002001908154916dffffffffffffffffffffffffffff8360081c16928315610a0a5765ffffffffffff8160981c1680156109ac57421061094e5760009373ffffffffffffffffffffffffffffffffffffffff859485947fffffffffffffff000000000000000000000000000000000000000000000000ff86951690556040517fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda33391806108da8786836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b0390a2165af16108e8612450565b50156108f057005b606490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b3461019c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c573360005260006020526001604060002001805463ffffffff8160781c16908115610bdc5760ff1615610b7e5765ffffffffffff908142160191818311610b4f5780547fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff001678ffffffffffff00000000000000000000000000000000000000609885901b161790556040519116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a2005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610022610c6f61229f565b612748565b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043567ffffffffffffffff811161019c576020610cc8610d1b9236906004016122c2565b919073ffffffffffffffffffffffffffffffffffffffff9260405194859283927f570e1a360000000000000000000000000000000000000000000000000000000084528560048501526024840191612709565b03816000857f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c165af1908115610db757602492600092610d86575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b610da991925060203d602011610db0575b610da181836121ed565b8101906126dd565b9083610d56565b503d610d97565b6040513d6000823e3d90fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610dfa61229f565b60243567ffffffffffffffff811161019c57600091610e1e839236906004016122c2565b90816040519283928337810184815203915af4610e39612450565b90610e7e6040519283927f99410554000000000000000000000000000000000000000000000000000000008452151560048401526040602484015260448301906123c6565b0390fd5b3461019c57610e9036612317565b610e9b9291926129bd565b610ea483612588565b60005b848110610f1c57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000915b858310610eec576102408585613ba7565b909193600190610f12610f0087898761269d565b610f0a888661265a565b519088613597565b0194019190610edb565b610f47610f40610f2e8385979561265a565b51610f3a84898761269d565b846129f6565b9190613dd7565b73ffffffffffffffffffffffffffffffffffffffff929183166110db5761107657610f7190613dd7565b911661101157610f8657600101929092610ea7565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608483604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61118c61229f565b1660005260006020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff6111f161229f565b6000608060405161120181612155565b828152826020820152826040820152826060820152015216600052600060205260a06040600020608060405161123681612155565b6001835493848352015490602081019060ff8316151582526dffffffffffffffffffffffffffff60408201818560081c16815263ffffffff936060840193858760781c16855265ffffffffffff978891019660981c1686526040519788525115156020880152511660408601525116606084015251166080820152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760206112ec61229f565b73ffffffffffffffffffffffffffffffffffffffff6113096122f0565b911660005260018252604060002077ffffffffffffffffffffffffffffffffffffffffffffffff821660005282526040600020547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b3461019c577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60208136011261019c576004359067ffffffffffffffff821161019c5761012090823603011261019c576113c9602091600401612480565b604051908152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761140861229f565b60243590336000526000602052604060002090815491828411611508576000808573ffffffffffffffffffffffffffffffffffffffff8295839561144c848a612443565b90556040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af16114a2612450565b50156114aa57005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761159d61229f565b73ffffffffffffffffffffffffffffffffffffffff6115ba6122f0565b9116600052600160205277ffffffffffffffffffffffffffffffffffffffffffffffff604060002091166000526020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043577ffffffffffffffffffffffffffffffffffffffffffffffff811680910361019c5733600052600160205260406000209060005260205260406000206116728154612416565b9055005b6020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043563ffffffff9182821680920361019c5733600052600081526040600020928215611950576001840154908160781c1683106118f2576116f86dffffffffffffffffffffffffffff9182349160081c16612409565b93841561189457818511611836579065ffffffffffff61180592546040519061172082612155565b8152848101926001845260408201908816815260608201878152600160808401936000855233600052600089526040600020905181550194511515917fffffffffffffffffffffffffff0000000000000000000000000000000000000060ff72ffffffff0000000000000000000000000000006effffffffffffffffffffffffffff008954945160081b16945160781b1694169116171717835551167fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffff78ffffffffffff0000000000000000000000000000000000000083549260981b169116179055565b6040519283528201527fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c0160403392a2005b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361019c57807f60fc6b6e0000000000000000000000000000000000000000000000000000000060209214908115611ad6575b8115611aac575b8115611a82575b8115611a58575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482611a4d565b7f3e84f0210000000000000000000000000000000000000000000000000000000081149150611a46565b7fcf28ef970000000000000000000000000000000000000000000000000000000081149150611a3f565b7f915074d80000000000000000000000000000000000000000000000000000000081149150611a38565b3461019c576102007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5767ffffffffffffffff60043581811161019c573660238201121561019c57611b62903690602481600401359101612268565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101c0811261019c5761014060405191611b9e83612155565b1261019c5760405192611bb0846121a0565b60243573ffffffffffffffffffffffffffffffffffffffff8116810361019c578452602093604435858201526064356040820152608435606082015260a435608082015260c43560a082015260e43560c08201526101043573ffffffffffffffffffffffffffffffffffffffff8116810361019c5760e08201526101243561010082015261014435610120820152825261016435848301526101843560408301526101a43560608301526101c43560808301526101e43590811161019c57611c7c9036906004016122c2565b905a3033036120f7578351606081015195603f5a0260061c61271060a0840151890101116120ce5760009681519182611ff0575b5050505090611cca915a9003608085015101923691612268565b925a90600094845193611cdc85613ccc565b9173ffffffffffffffffffffffffffffffffffffffff60e0870151168015600014611ea957505073ffffffffffffffffffffffffffffffffffffffff855116935b5a9003019360a06060820151910151016080860151850390818111611e95575b50508302604085015192818410600014611dce5750506003811015611da157600203611d79576113c99293508093611d7481613d65565b613cf6565b5050507fdeadaa51000000000000000000000000000000000000000000000000000000008152fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b81611dde92979396940390613c98565b506003841015611e6857507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f60808683015192519473ffffffffffffffffffffffffffffffffffffffff865116948873ffffffffffffffffffffffffffffffffffffffff60e0890151169701519160405192835215898301528760408301526060820152a46113c9565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526021600452fd5b6064919003600a0204909301928780611d3d565b8095918051611eba575b5050611d1d565b6003861015611fc1576002860315611eb35760a088015190823b1561019c57600091611f2491836040519586809581947f7c627b210000000000000000000000000000000000000000000000000000000083528d60048401526080602484015260848301906123c6565b8b8b0260448301528b60648301520393f19081611fad575b50611fa65787893d610800808211611f9e575b506040519282828501016040528184528284013e610e7e6040519283927fad7954bc000000000000000000000000000000000000000000000000000000008452600484015260248301906123c6565b905083611f4f565b8980611eb3565b611fb89199506121bd565b6000978a611f3c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91600092918380938c73ffffffffffffffffffffffffffffffffffffffff885116910192f115612023575b808080611cb0565b611cca929195503d6108008082116120c6575b5060405190888183010160405280825260008983013e805161205f575b5050600194909161201b565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20188870151918973ffffffffffffffffffffffffffffffffffffffff8551169401516120bc604051928392835260408d84015260408301906123c6565b0390a38680612053565b905088612036565b877fdeaddead000000000000000000000000000000000000000000000000000000006000526000fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b60a0810190811067ffffffffffffffff82111761217157604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610140810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157604052565b6060810190811067ffffffffffffffff82111761217157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926122748261222e565b9161228260405193846121ed565b82948184528183011161019c578281602093846000960137010152565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9181601f8401121561019c5782359167ffffffffffffffff831161019c576020838186019501011161019c57565b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261019c5760043567ffffffffffffffff9283821161019c578060238301121561019c57816004013593841161019c5760248460051b8301011161019c57602401919060243573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b60005b8381106123b65750506000910152565b81810151838201526020016123a6565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093612402815180928187528780880191016123a3565b0116010190565b91908201809211610b4f57565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610b4f5760010190565b91908203918211610b4f57565b3d1561247b573d906124618261222e565b9161246f60405193846121ed565b82523d6000602084013e565b606090565b604061248e8183018361284b565b90818351918237206124a3606084018461284b565b90818451918237209260c06124bb60e083018361284b565b908186519182372091845195602087019473ffffffffffffffffffffffffffffffffffffffff833516865260208301358789015260608801526080870152608081013560a087015260a081013582870152013560e08501526101009081850152835261012083019167ffffffffffffffff918484108385111761217157838252845190206101408501908152306101608601524661018086015260608452936101a00191821183831017612171575251902090565b67ffffffffffffffff81116121715760051b60200190565b9061259282612570565b6040906125a260405191826121ed565b8381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06125d08295612570565b019160005b8381106125e25750505050565b60209082516125f081612155565b83516125fb816121a0565b600081526000849181838201528187820152816060818184015260809282848201528260a08201528260c08201528260e082015282610100820152826101208201528652818587015281898701528501528301528286010152016125d5565b805182101561266e5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b919081101561266e5760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18136030182121561019c570190565b9081602091031261019c575173ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b7f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4602073ffffffffffffffffffffffffffffffffffffffff61278a3485613c98565b936040519485521692a2565b919081101561266e5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18136030182121561019c570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c57602001918160051b3603831361019c57565b3573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c5760200191813603831361019c57565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561019c57016020813591019167ffffffffffffffff821161019c57813603831361019c57565b61012091813573ffffffffffffffffffffffffffffffffffffffff811680910361019c576129626129476129ba9561299b93855260208601356020860152612937604087018761289c565b9091806040880152860191612709565b612954606086018661289c565b908583036060870152612709565b6080840135608084015260a084013560a084015260c084013560c084015261298d60e085018561289c565b9084830360e0860152612709565b916129ac610100918281019061289c565b929091818503910152612709565b90565b60028054146129cc5760028055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b926000905a93805194843573ffffffffffffffffffffffffffffffffffffffff811680910361019c5786526020850135602087015260808501356fffffffffffffffffffffffffffffffff90818116606089015260801c604088015260a086013560c088015260c086013590811661010088015260801c610120870152612a8060e086018661284b565b801561357b576034811061351d578060141161019c578060241161019c5760341161019c57602481013560801c60a0880152601481013560801c60808801523560601c60e08701525b612ad285612480565b60208301526040860151946effffffffffffffffffffffffffffff8660c08901511760608901511760808901511760a0890151176101008901511761012089015117116134bf57604087015160608801510160808801510160a08801510160c0880151016101008801510296835173ffffffffffffffffffffffffffffffffffffffff81511690612b66604085018561284b565b806131e4575b505060e0015173ffffffffffffffffffffffffffffffffffffffff1690600082156131ac575b6020612bd7918b828a01516000868a604051978896879586937f19822f7c00000000000000000000000000000000000000000000000000000000855260048501613db5565b0393f160009181613178575b50612c8b573d8c610800808311612c83575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141323320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612bf5565b9a92939495969798999a91156130f2575b509773ffffffffffffffffffffffffffffffffffffffff835116602084015190600052600160205260406000208160401c60005260205267ffffffffffffffff604060002091825492612cee84612416565b9055160361308d575a8503116130285773ffffffffffffffffffffffffffffffffffffffff60e0606093015116612d42575b509060a09184959697986040608096015260608601520135905a900301910152565b969550505a9683519773ffffffffffffffffffffffffffffffffffffffff60e08a01511680600052600060205260406000208054848110612fc3576080612dcd9a9b9c600093878094039055015192602089015183604051809d819582947f52b7512c0000000000000000000000000000000000000000000000000000000084528c60048501613db5565b039286f1978860009160009a612f36575b50612e86573d8b610800808311612e7e575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141333320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612df0565b9991929394959697989998925a900311612eab57509096959094939291906080612d20565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602760448201527f41413336206f766572207061796d6173746572566572696669636174696f6e4760648201527f61734c696d6974000000000000000000000000000000000000000000000000006084820152fd5b915098503d90816000823e612f4b82826121ed565b604081838101031261019c5780519067ffffffffffffffff821161019c57828101601f83830101121561019c578181015191612f868361222e565b93612f9460405195866121ed565b838552820160208483850101011161019c57602092612fba9184808701918501016123a3565b01519838612dde565b60848b604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413331207061796d6173746572206465706f73697420746f6f206c6f7700006064820152fd5b608490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413236206f76657220766572696669636174696f6e4761734c696d697400006064820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601a60448201527f4141323520696e76616c6964206163636f756e74206e6f6e63650000000000006064820152fd5b600052600060205260406000208054808c11613113578b9003905538612c9c565b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152fd5b9091506020813d6020116131a4575b81613194602093836121ed565b8101031261019c57519038612be3565b3d9150613187565b508060005260006020526040600020548a81116000146131d75750612bd7602060005b915050612b92565b6020612bd7918c036131cf565b833b61345a57604088510151602060405180927f570e1a360000000000000000000000000000000000000000000000000000000082528260048301528160008161323260248201898b612709565b039273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c1690f1908115610db75760009161343b575b5073ffffffffffffffffffffffffffffffffffffffff811680156133d6578503613371573b1561330c5760141161019c5773ffffffffffffffffffffffffffffffffffffffff9183887fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d604060e0958787602086015195510151168251913560601c82526020820152a391612b6c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152fd5b60848e604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313420696e6974436f6465206d7573742072657475726e2073656e6465726064820152fd5b60848f604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601b60448201527f4141313320696e6974436f6465206661696c6564206f72204f4f4700000000006064820152fd5b613454915060203d602011610db057610da181836121ed565b3861327c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b5050600060e087015260006080870152600060a0870152612ac9565b9092915a906060810151916040928351967fffffffff00000000000000000000000000000000000000000000000000000000886135d7606084018461284b565b600060038211613b9f575b7f8dd7712f0000000000000000000000000000000000000000000000000000000094168403613a445750505061379d6000926136b292602088015161363a8a5193849360208501528b602485015260648401906128ec565b90604483015203906136727fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0928381018352826121ed565b61379189519485927e42dc5300000000000000000000000000000000000000000000000000000000602085015261020060248501526102248401906123c6565b613760604484018b60806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152876123c6565b039081018352826121ed565b6020918183809351910182305af1600051988652156137bf575b505050505050565b909192939495965060003d8214613a3a575b7fdeaddead00000000000000000000000000000000000000000000000000000000810361385b57608487878051917f220266b600000000000000000000000000000000000000000000000000000000835260048301526024820152600f60448201527f41413935206f7574206f662067617300000000000000000000000000000000006064820152fd5b7fdeadaa510000000000000000000000000000000000000000000000000000000091929395949650146000146138c55750506138a961389e6138b8935a90612443565b608085015190612409565b9083015183611d748295613d65565b905b3880808080806137b7565b909261395290828601518651907ff62676f440ff169a3a9afdbf812e89e7f95975ee8e5c31214ffdef631c5f479273ffffffffffffffffffffffffffffffffffffffff9580878551169401516139483d610800808211613a32575b508a519084818301018c5280825260008583013e8a805194859485528401528a8301906123c6565b0390a35a90612443565b916139636080860193845190612409565b926000905a94829488519761397789613ccc565b948260e08b0151168015600014613a1857505050875116955b5a9003019560a06060820151910151019051860390818111613a04575b5050840290850151928184106000146139de57505080611e68575090816139d89293611d7481613d65565b906138ba565b6139ee9082849397950390613c98565b50611e68575090826139ff92613cf6565b6139d8565b6064919003600a02049094019338806139ad565b90919892509751613a2a575b50613990565b955038613a24565b905038613920565b8181803e516137d1565b613b97945082935090613a8c917e42dc53000000000000000000000000000000000000000000000000000000006020613b6b9501526102006024860152610224850191612709565b613b3a604484018860806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152846123c6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018952886121ed565b60008761379d565b5081356135e2565b73ffffffffffffffffffffffffffffffffffffffff168015613c3a57600080809381935af1613bd4612450565b5015613bdc57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff166000526000602052613cc66040600020918254612409565b80915590565b610120610100820151910151808214613cf257480180821015613ced575090565b905090565b5090565b9190917f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f6080602083015192519473ffffffffffffffffffffffffffffffffffffffff946020868851169660e089015116970151916040519283526000602084015260408301526060820152a4565b60208101519051907f67b4fa9642f42120bf031f3051d1824b0fe25627945b27b8a6a65d5761d5482e60208073ffffffffffffffffffffffffffffffffffffffff855116940151604051908152a3565b613dcd604092959493956060835260608301906128ec565b9460208201520152565b8015613e6457600060408051613dec816121d1565b828152826020820152015273ffffffffffffffffffffffffffffffffffffffff811690604065ffffffffffff91828160a01c16908115613e5c575b60d01c92825191613e37836121d1565b8583528460208401521691829101524211908115613e5457509091565b905042109091565b839150613e27565b5060009060009056fea2646970667358221220b094fd69f04977ae9458e5ba422d01cd2d20dbcfca0992ff37f19aa07deec25464736f6c63430008170033", + "nonce": "2", + "storage": { + "0xfd8a9a5105ec447cdc63b84f6e5700b432121f67627f5d0269ac1b8f5e1b5507": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0x7ab5742e5b448c142a35c92699fd2dd6b8930cbd": { + "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffc4dc3b19c23c7dc28", + "nonce": "81" + } + }, + "config": { + "chainId": 1337, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "rip7560block": 0, + "rip7712block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "pragueTime": 0, + "terminalTotalDifficulty": 0, + "depositContractAddress": "0x0000000000000000000000000000000000000000", + "blobSchedule": { + "cancun": { + "max": 6, + "target": 3, + "baseFeeUpdateFraction": 3338477 + }, + "prague": { + "max": 9, + "target": 6, + "baseFeeUpdateFraction": 5007716 + } + } + } + }, + "context": { + "number": "85", + "difficulty": "0", + "timestamp": "1738266970", + "gasLimit": "30000000", + "miner": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "55726" + }, + "input": "0x02f89882053951843b82b63d843b84a43983023a3c940000000071727de22e5e9d8baf0edac6f37da032874a9b6384487fffa4b760faf900000000000000000000000093e4af629481a69da4e7335892703ae52113b3e7c001a003d55576c3186202ffa9e00ea2ef84b3699ec1a77285a8a54876915689c8e946a00e59f2fdddd26270454a759c24609bd8eb20b899f8d2a99922c3a3adc586e366", + "result": { + "accessedSlots": { + "reads": { + "0xfd8a9a5105ec447cdc63b84f6e5700b432121f67627f5d0269ac1b8f5e1b5507": [ + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + }, + "transientReads": {}, + "transientWrites": {}, + "writes": { + "0xfd8a9a5105ec447cdc63b84f6e5700b432121f67627f5d0269ac1b8f5e1b5507": 1 + } + }, + "contractSize": {}, + "extCodeAccessInfo": [], + "from": "0x7ab5742e5b448c142a35c92699fd2dd6b8930cbd", + "gas": "0x23a3c", + "gasUsed": "0xb21f", + "input": "0xb760faf900000000000000000000000093e4af629481a69da4e7335892703ae52113b3e7", + "keccak": [ + "0x00000000000000000000000093e4af629481a69da4e7335892703ae52113b3e70000000000000000000000000000000000000000000000000000000000000000" + ], + "outOfGas": false, + "to": "0x0000000071727de22e5e9d8baf0edac6f37da032", + "type": "CALL", + "usedOpcodes": {"0x0":1, "0x20":1, "0x34":1, "0x35":2, "0x36":2, "0x51":1, "0x52":4, "0x54":1, "0x55":1, "0x56":8, "0x57":18, "0x5b":10, "0xa2":1}, + "value": "0x4a9b6384487fff" + } +} diff --git a/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_simple.json b/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_simple.json new file mode 100644 index 0000000000..f0a0fc1655 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/erc7562_tracer/erc7562Tracer.test_simple.json @@ -0,0 +1,246 @@ +{ + "genesis": { + "baseFeePerGas": "42949", + "blobGasUsed": "0", + "difficulty": "0", + "excessBlobGas": "0", + "extraData": "0xd883010e0d846765746888676f312e32322e36856c696e7578", + "gasLimit": "30000000", + "hash": "0x6f85304f332c41070b645fbed7ad468db1f80d3b52776d8a3f3c10c9d106db17", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0x4917b13b44dc41c98ec2099dd0f549c640b98d3e358cc7fcdef7988153093510", + "nonce": "0x0000000000000000", + "number": "87", + "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "stateRoot": "0xb17f1114a85e834ee373ad5be38854b7efc921bdcef77acef657fdc63ab25cf8", + "timestamp": "1738267404", + "withdrawals": [], + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "alloc": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x20113869f420bed" + }, + "0x0000000071727de22e5e9d8baf0edac6f37da032": { + "balance": "0x3be2675332684fffe", + "code": "0x60806040526004361015610024575b361561001957600080fd5b61002233612748565b005b60003560e01c806242dc5314611b0057806301ffc9a7146119ae5780630396cb60146116765780630bd28e3b146115fa5780631b2e01b814611566578063205c2878146113d157806322cdde4c1461136b57806335567e1a146112b35780635287ce12146111a557806370a0823114611140578063765e827f14610e82578063850aaf6214610dc35780639b249f6914610c74578063b760faf914610c3a578063bb9fe6bf14610a68578063c23a5cea146107c4578063dbed18e0146101a15763fc7e286d0361000e573461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61013a61229f565b16600052600060205260a0604060002065ffffffffffff6001825492015460405192835260ff8116151560208401526dffffffffffffffffffffffffffff8160081c16604084015263ffffffff8160781c16606084015260981c166080820152f35b600080fd5b3461019c576101af36612317565b906101b86129bd565b60009160005b82811061056f57506101d08493612588565b6000805b8481106102fc5750507fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000809360005b81811061024757610240868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2613ba7565b6001600255005b6102a261025582848a612796565b73ffffffffffffffffffffffffffffffffffffffff6102766020830161282a565b167f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a2806127d6565b906000915b8083106102b957505050600101610209565b909194976102f36102ed6001926102e78c8b6102e0826102da8e8b8d61269d565b9261265a565b5191613597565b90612409565b99612416565b950191906102a7565b6020610309828789612796565b61031f61031682806127d6565b9390920161282a565b9160009273ffffffffffffffffffffffffffffffffffffffff8091165b8285106103505750505050506001016101d4565b909192939561037f83610378610366848c61265a565b516103728b898b61269d565b856129f6565b9290613dd7565b9116840361050a576104a5576103958491613dd7565b9116610440576103b5576103aa600191612416565b96019392919061033c565b60a487604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608489604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b61057a818487612796565b9361058585806127d6565b919095602073ffffffffffffffffffffffffffffffffffffffff6105aa82840161282a565b1697600192838a1461076657896105da575b5050505060019293949550906105d191612409565b939291016101be565b8060406105e892019061284b565b918a3b1561019c57929391906040519485937f2dd8113300000000000000000000000000000000000000000000000000000000855288604486016040600488015252606490818601918a60051b8701019680936000915b8c83106106e657505050505050838392610684927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8560009803016024860152612709565b03818a5afa90816106d7575b506106c657602486604051907f86a9f7500000000000000000000000000000000000000000000000000000000082526004820152fd5b93945084936105d1600189806105bc565b6106e0906121bd565b88610690565b91939596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c908a9294969a0301865288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181121561019c57836107538793858394016128ec565b9a0196019301909189979695949261063f565b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b3461019c576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576107fc61229f565b33600052600082526001604060002001908154916dffffffffffffffffffffffffffff8360081c16928315610a0a5765ffffffffffff8160981c1680156109ac57421061094e5760009373ffffffffffffffffffffffffffffffffffffffff859485947fffffffffffffff000000000000000000000000000000000000000000000000ff86951690556040517fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda33391806108da8786836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b0390a2165af16108e8612450565b50156108f057005b606490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b3461019c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c573360005260006020526001604060002001805463ffffffff8160781c16908115610bdc5760ff1615610b7e5765ffffffffffff908142160191818311610b4f5780547fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff001678ffffffffffff00000000000000000000000000000000000000609885901b161790556040519116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a2005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610022610c6f61229f565b612748565b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043567ffffffffffffffff811161019c576020610cc8610d1b9236906004016122c2565b919073ffffffffffffffffffffffffffffffffffffffff9260405194859283927f570e1a360000000000000000000000000000000000000000000000000000000084528560048501526024840191612709565b03816000857f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c165af1908115610db757602492600092610d86575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b610da991925060203d602011610db0575b610da181836121ed565b8101906126dd565b9083610d56565b503d610d97565b6040513d6000823e3d90fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610dfa61229f565b60243567ffffffffffffffff811161019c57600091610e1e839236906004016122c2565b90816040519283928337810184815203915af4610e39612450565b90610e7e6040519283927f99410554000000000000000000000000000000000000000000000000000000008452151560048401526040602484015260448301906123c6565b0390fd5b3461019c57610e9036612317565b610e9b9291926129bd565b610ea483612588565b60005b848110610f1c57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000915b858310610eec576102408585613ba7565b909193600190610f12610f0087898761269d565b610f0a888661265a565b519088613597565b0194019190610edb565b610f47610f40610f2e8385979561265a565b51610f3a84898761269d565b846129f6565b9190613dd7565b73ffffffffffffffffffffffffffffffffffffffff929183166110db5761107657610f7190613dd7565b911661101157610f8657600101929092610ea7565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608483604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61118c61229f565b1660005260006020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff6111f161229f565b6000608060405161120181612155565b828152826020820152826040820152826060820152015216600052600060205260a06040600020608060405161123681612155565b6001835493848352015490602081019060ff8316151582526dffffffffffffffffffffffffffff60408201818560081c16815263ffffffff936060840193858760781c16855265ffffffffffff978891019660981c1686526040519788525115156020880152511660408601525116606084015251166080820152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760206112ec61229f565b73ffffffffffffffffffffffffffffffffffffffff6113096122f0565b911660005260018252604060002077ffffffffffffffffffffffffffffffffffffffffffffffff821660005282526040600020547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b3461019c577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60208136011261019c576004359067ffffffffffffffff821161019c5761012090823603011261019c576113c9602091600401612480565b604051908152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761140861229f565b60243590336000526000602052604060002090815491828411611508576000808573ffffffffffffffffffffffffffffffffffffffff8295839561144c848a612443565b90556040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af16114a2612450565b50156114aa57005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761159d61229f565b73ffffffffffffffffffffffffffffffffffffffff6115ba6122f0565b9116600052600160205277ffffffffffffffffffffffffffffffffffffffffffffffff604060002091166000526020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043577ffffffffffffffffffffffffffffffffffffffffffffffff811680910361019c5733600052600160205260406000209060005260205260406000206116728154612416565b9055005b6020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043563ffffffff9182821680920361019c5733600052600081526040600020928215611950576001840154908160781c1683106118f2576116f86dffffffffffffffffffffffffffff9182349160081c16612409565b93841561189457818511611836579065ffffffffffff61180592546040519061172082612155565b8152848101926001845260408201908816815260608201878152600160808401936000855233600052600089526040600020905181550194511515917fffffffffffffffffffffffffff0000000000000000000000000000000000000060ff72ffffffff0000000000000000000000000000006effffffffffffffffffffffffffff008954945160081b16945160781b1694169116171717835551167fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffff78ffffffffffff0000000000000000000000000000000000000083549260981b169116179055565b6040519283528201527fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c0160403392a2005b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361019c57807f60fc6b6e0000000000000000000000000000000000000000000000000000000060209214908115611ad6575b8115611aac575b8115611a82575b8115611a58575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482611a4d565b7f3e84f0210000000000000000000000000000000000000000000000000000000081149150611a46565b7fcf28ef970000000000000000000000000000000000000000000000000000000081149150611a3f565b7f915074d80000000000000000000000000000000000000000000000000000000081149150611a38565b3461019c576102007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5767ffffffffffffffff60043581811161019c573660238201121561019c57611b62903690602481600401359101612268565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101c0811261019c5761014060405191611b9e83612155565b1261019c5760405192611bb0846121a0565b60243573ffffffffffffffffffffffffffffffffffffffff8116810361019c578452602093604435858201526064356040820152608435606082015260a435608082015260c43560a082015260e43560c08201526101043573ffffffffffffffffffffffffffffffffffffffff8116810361019c5760e08201526101243561010082015261014435610120820152825261016435848301526101843560408301526101a43560608301526101c43560808301526101e43590811161019c57611c7c9036906004016122c2565b905a3033036120f7578351606081015195603f5a0260061c61271060a0840151890101116120ce5760009681519182611ff0575b5050505090611cca915a9003608085015101923691612268565b925a90600094845193611cdc85613ccc565b9173ffffffffffffffffffffffffffffffffffffffff60e0870151168015600014611ea957505073ffffffffffffffffffffffffffffffffffffffff855116935b5a9003019360a06060820151910151016080860151850390818111611e95575b50508302604085015192818410600014611dce5750506003811015611da157600203611d79576113c99293508093611d7481613d65565b613cf6565b5050507fdeadaa51000000000000000000000000000000000000000000000000000000008152fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b81611dde92979396940390613c98565b506003841015611e6857507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f60808683015192519473ffffffffffffffffffffffffffffffffffffffff865116948873ffffffffffffffffffffffffffffffffffffffff60e0890151169701519160405192835215898301528760408301526060820152a46113c9565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526021600452fd5b6064919003600a0204909301928780611d3d565b8095918051611eba575b5050611d1d565b6003861015611fc1576002860315611eb35760a088015190823b1561019c57600091611f2491836040519586809581947f7c627b210000000000000000000000000000000000000000000000000000000083528d60048401526080602484015260848301906123c6565b8b8b0260448301528b60648301520393f19081611fad575b50611fa65787893d610800808211611f9e575b506040519282828501016040528184528284013e610e7e6040519283927fad7954bc000000000000000000000000000000000000000000000000000000008452600484015260248301906123c6565b905083611f4f565b8980611eb3565b611fb89199506121bd565b6000978a611f3c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91600092918380938c73ffffffffffffffffffffffffffffffffffffffff885116910192f115612023575b808080611cb0565b611cca929195503d6108008082116120c6575b5060405190888183010160405280825260008983013e805161205f575b5050600194909161201b565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20188870151918973ffffffffffffffffffffffffffffffffffffffff8551169401516120bc604051928392835260408d84015260408301906123c6565b0390a38680612053565b905088612036565b877fdeaddead000000000000000000000000000000000000000000000000000000006000526000fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b60a0810190811067ffffffffffffffff82111761217157604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610140810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157604052565b6060810190811067ffffffffffffffff82111761217157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926122748261222e565b9161228260405193846121ed565b82948184528183011161019c578281602093846000960137010152565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9181601f8401121561019c5782359167ffffffffffffffff831161019c576020838186019501011161019c57565b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261019c5760043567ffffffffffffffff9283821161019c578060238301121561019c57816004013593841161019c5760248460051b8301011161019c57602401919060243573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b60005b8381106123b65750506000910152565b81810151838201526020016123a6565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093612402815180928187528780880191016123a3565b0116010190565b91908201809211610b4f57565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610b4f5760010190565b91908203918211610b4f57565b3d1561247b573d906124618261222e565b9161246f60405193846121ed565b82523d6000602084013e565b606090565b604061248e8183018361284b565b90818351918237206124a3606084018461284b565b90818451918237209260c06124bb60e083018361284b565b908186519182372091845195602087019473ffffffffffffffffffffffffffffffffffffffff833516865260208301358789015260608801526080870152608081013560a087015260a081013582870152013560e08501526101009081850152835261012083019167ffffffffffffffff918484108385111761217157838252845190206101408501908152306101608601524661018086015260608452936101a00191821183831017612171575251902090565b67ffffffffffffffff81116121715760051b60200190565b9061259282612570565b6040906125a260405191826121ed565b8381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06125d08295612570565b019160005b8381106125e25750505050565b60209082516125f081612155565b83516125fb816121a0565b600081526000849181838201528187820152816060818184015260809282848201528260a08201528260c08201528260e082015282610100820152826101208201528652818587015281898701528501528301528286010152016125d5565b805182101561266e5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b919081101561266e5760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18136030182121561019c570190565b9081602091031261019c575173ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b7f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4602073ffffffffffffffffffffffffffffffffffffffff61278a3485613c98565b936040519485521692a2565b919081101561266e5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18136030182121561019c570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c57602001918160051b3603831361019c57565b3573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c5760200191813603831361019c57565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561019c57016020813591019167ffffffffffffffff821161019c57813603831361019c57565b61012091813573ffffffffffffffffffffffffffffffffffffffff811680910361019c576129626129476129ba9561299b93855260208601356020860152612937604087018761289c565b9091806040880152860191612709565b612954606086018661289c565b908583036060870152612709565b6080840135608084015260a084013560a084015260c084013560c084015261298d60e085018561289c565b9084830360e0860152612709565b916129ac610100918281019061289c565b929091818503910152612709565b90565b60028054146129cc5760028055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b926000905a93805194843573ffffffffffffffffffffffffffffffffffffffff811680910361019c5786526020850135602087015260808501356fffffffffffffffffffffffffffffffff90818116606089015260801c604088015260a086013560c088015260c086013590811661010088015260801c610120870152612a8060e086018661284b565b801561357b576034811061351d578060141161019c578060241161019c5760341161019c57602481013560801c60a0880152601481013560801c60808801523560601c60e08701525b612ad285612480565b60208301526040860151946effffffffffffffffffffffffffffff8660c08901511760608901511760808901511760a0890151176101008901511761012089015117116134bf57604087015160608801510160808801510160a08801510160c0880151016101008801510296835173ffffffffffffffffffffffffffffffffffffffff81511690612b66604085018561284b565b806131e4575b505060e0015173ffffffffffffffffffffffffffffffffffffffff1690600082156131ac575b6020612bd7918b828a01516000868a604051978896879586937f19822f7c00000000000000000000000000000000000000000000000000000000855260048501613db5565b0393f160009181613178575b50612c8b573d8c610800808311612c83575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141323320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612bf5565b9a92939495969798999a91156130f2575b509773ffffffffffffffffffffffffffffffffffffffff835116602084015190600052600160205260406000208160401c60005260205267ffffffffffffffff604060002091825492612cee84612416565b9055160361308d575a8503116130285773ffffffffffffffffffffffffffffffffffffffff60e0606093015116612d42575b509060a09184959697986040608096015260608601520135905a900301910152565b969550505a9683519773ffffffffffffffffffffffffffffffffffffffff60e08a01511680600052600060205260406000208054848110612fc3576080612dcd9a9b9c600093878094039055015192602089015183604051809d819582947f52b7512c0000000000000000000000000000000000000000000000000000000084528c60048501613db5565b039286f1978860009160009a612f36575b50612e86573d8b610800808311612e7e575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141333320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612df0565b9991929394959697989998925a900311612eab57509096959094939291906080612d20565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602760448201527f41413336206f766572207061796d6173746572566572696669636174696f6e4760648201527f61734c696d6974000000000000000000000000000000000000000000000000006084820152fd5b915098503d90816000823e612f4b82826121ed565b604081838101031261019c5780519067ffffffffffffffff821161019c57828101601f83830101121561019c578181015191612f868361222e565b93612f9460405195866121ed565b838552820160208483850101011161019c57602092612fba9184808701918501016123a3565b01519838612dde565b60848b604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413331207061796d6173746572206465706f73697420746f6f206c6f7700006064820152fd5b608490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413236206f76657220766572696669636174696f6e4761734c696d697400006064820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601a60448201527f4141323520696e76616c6964206163636f756e74206e6f6e63650000000000006064820152fd5b600052600060205260406000208054808c11613113578b9003905538612c9c565b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152fd5b9091506020813d6020116131a4575b81613194602093836121ed565b8101031261019c57519038612be3565b3d9150613187565b508060005260006020526040600020548a81116000146131d75750612bd7602060005b915050612b92565b6020612bd7918c036131cf565b833b61345a57604088510151602060405180927f570e1a360000000000000000000000000000000000000000000000000000000082528260048301528160008161323260248201898b612709565b039273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c1690f1908115610db75760009161343b575b5073ffffffffffffffffffffffffffffffffffffffff811680156133d6578503613371573b1561330c5760141161019c5773ffffffffffffffffffffffffffffffffffffffff9183887fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d604060e0958787602086015195510151168251913560601c82526020820152a391612b6c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152fd5b60848e604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313420696e6974436f6465206d7573742072657475726e2073656e6465726064820152fd5b60848f604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601b60448201527f4141313320696e6974436f6465206661696c6564206f72204f4f4700000000006064820152fd5b613454915060203d602011610db057610da181836121ed565b3861327c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b5050600060e087015260006080870152600060a0870152612ac9565b9092915a906060810151916040928351967fffffffff00000000000000000000000000000000000000000000000000000000886135d7606084018461284b565b600060038211613b9f575b7f8dd7712f0000000000000000000000000000000000000000000000000000000094168403613a445750505061379d6000926136b292602088015161363a8a5193849360208501528b602485015260648401906128ec565b90604483015203906136727fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0928381018352826121ed565b61379189519485927e42dc5300000000000000000000000000000000000000000000000000000000602085015261020060248501526102248401906123c6565b613760604484018b60806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152876123c6565b039081018352826121ed565b6020918183809351910182305af1600051988652156137bf575b505050505050565b909192939495965060003d8214613a3a575b7fdeaddead00000000000000000000000000000000000000000000000000000000810361385b57608487878051917f220266b600000000000000000000000000000000000000000000000000000000835260048301526024820152600f60448201527f41413935206f7574206f662067617300000000000000000000000000000000006064820152fd5b7fdeadaa510000000000000000000000000000000000000000000000000000000091929395949650146000146138c55750506138a961389e6138b8935a90612443565b608085015190612409565b9083015183611d748295613d65565b905b3880808080806137b7565b909261395290828601518651907ff62676f440ff169a3a9afdbf812e89e7f95975ee8e5c31214ffdef631c5f479273ffffffffffffffffffffffffffffffffffffffff9580878551169401516139483d610800808211613a32575b508a519084818301018c5280825260008583013e8a805194859485528401528a8301906123c6565b0390a35a90612443565b916139636080860193845190612409565b926000905a94829488519761397789613ccc565b948260e08b0151168015600014613a1857505050875116955b5a9003019560a06060820151910151019051860390818111613a04575b5050840290850151928184106000146139de57505080611e68575090816139d89293611d7481613d65565b906138ba565b6139ee9082849397950390613c98565b50611e68575090826139ff92613cf6565b6139d8565b6064919003600a02049094019338806139ad565b90919892509751613a2a575b50613990565b955038613a24565b905038613920565b8181803e516137d1565b613b97945082935090613a8c917e42dc53000000000000000000000000000000000000000000000000000000006020613b6b9501526102006024860152610224850191612709565b613b3a604484018860806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152846123c6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018952886121ed565b60008761379d565b5081356135e2565b73ffffffffffffffffffffffffffffffffffffffff168015613c3a57600080809381935af1613bd4612450565b5015613bdc57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff166000526000602052613cc66040600020918254612409565b80915590565b610120610100820151910151808214613cf257480180821015613ced575090565b905090565b5090565b9190917f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f6080602083015192519473ffffffffffffffffffffffffffffffffffffffff946020868851169660e089015116970151916040519283526000602084015260408301526060820152a4565b60208101519051907f67b4fa9642f42120bf031f3051d1824b0fe25627945b27b8a6a65d5761d5482e60208073ffffffffffffffffffffffffffffffffffffffff855116940151604051908152a3565b613dcd604092959493956060835260608301906128ec565b9460208201520152565b8015613e6457600060408051613dec816121d1565b828152826020820152015273ffffffffffffffffffffffffffffffffffffffff811690604065ffffffffffff91828160a01c16908115613e5c575b60d01c92825191613e37836121d1565b8583528460208401521691829101524211908115613e5457509091565b905042109091565b839150613e27565b5060009060009056fea2646970667358221220b094fd69f04977ae9458e5ba422d01cd2d20dbcfca0992ff37f19aa07deec25464736f6c63430008170033", + "nonce": "2", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x83d2064309e31181791f895d99cc244865c480f99200cd4d4f2412a7a3a265b6": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0xe18cacf0f1fc038f916461d29104232bd93d822359dfc137927858cc71f1e4ed": "0x0000000000000000000000000000000000000000000000001bc16d674ec80000" + } + }, + "0x8c9d927336adc963536122f8e0d269319e79ed7a": { + "balance": "0x0", + "code": "0x60806040526004361015610015575b3661039257005b61001f5f3561007e565b806319822f7c14610079578063408aee4214610074578063451711591461006f578063a9cc47181461006a578063a9e966b7146100655763c19d93fb0361000e5761035d565b6102ee565b6102b6565b61028c565b6101b3565b61016e565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b90816101209103126100a95790565b610096565b90565b6100ba816100ae565b036100c157565b5f80fd5b905035906100d2826100b1565b565b90565b6100e0816100d4565b036100e757565b5f80fd5b905035906100f8826100d7565b565b9091606082840312610147575f82013567ffffffffffffffff8111610142576101288461013f92850161009a565b9361013681602086016100c5565b936040016100eb565b90565b610092565b61008e565b610155906100d4565b9052565b919061016c905f6020850194019061014c565b565b3461019f5761019b61018a6101843660046100fa565b916107d1565b610192610084565b91829182610159565b0390f35b61008a565b5f9103126101ae57565b61008e565b346101e3576101c33660046101a4565b6101df6101ce610988565b6101d6610084565b91829182610159565b0390f35b61008a565b60018060a01b031690565b6101fc906101e8565b90565b610208906101f3565b90565b610214816101ff565b0361021b57565b5f80fd5b9050359061022c8261020b565b565b63ffffffff1690565b6102408161022e565b0361024757565b5f80fd5b9050359061025882610237565b565b9190604083820312610282578061027661027f925f860161021f565b9360200161024b565b90565b61008e565b5f0190565b6102a061029a36600461025a565b906109de565b6102a8610084565b806102b281610287565b0390f35b346102cb576102c63660046101a4565b610ac3565b61008a565b906020828203126102e9576102e6915f016100eb565b90565b61008e565b3461031c576103066103013660046102d0565b610b3f565b61030e610084565b8061031881610287565b0390f35b61008a565b1c90565b90565b61033890600861033d9302610321565b610325565b90565b9061034b9154610328565b90565b61035a60015f90610340565b90565b3461038d5761036d3660046101a4565b61038961037861034e565b610380610084565b91829182610159565b0390f35b61008a565b5f80fd5b5f90565b5f80fd5b5f80fd5b5f80fd5b9035906001602003813603038212156103e8570180359067ffffffffffffffff82116103e3576020019160018202360383136103de57565b6103a2565b61039e565b61039a565b5090565b90565b90565b61040b610406610410926103f1565b6103f4565b6100d4565b90565b6bffffffffffffffffffffffff191690565b1b90565b9061043761043e91836103ed565b9135610413565b906014811061044c575b5090565b61046a906bffffffffffffffffffffffff1990601403600802610425565b165f610448565b60601c90565b61048b610486610490926101e8565b6103f4565b6101e8565b90565b61049f6104a491610471565b610477565b90565b6104b090610493565b90565b6104bc90610477565b90565b6104c8906104b3565b90565b6104d490610477565b90565b6104e0906104cb565b90565b6104ec906104cb565b90565b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b9061051b906104f3565b810190811067ffffffffffffffff82111761053557604052565b6104fd565b60e01b90565b9050519061054d826100d7565b565b9060208282031261056857610565915f01610540565b90565b61008e565b610576906101f3565b9052565b919061058d905f6020850194019061056d565b565b610597610084565b3d5f823e3d90fd5b90565b6105b66105b16105bb9261059f565b6103f4565b6100d4565b90565b905090565b6105ce5f80926105be565b0190565b6105db906105c3565b90565b906105f16105ea610084565b9283610511565b565b67ffffffffffffffff81116106115761060d6020916104f3565b0190565b6104fd565b90610628610623836105f3565b6105de565b918252565b606090565b3d5f1461064d576106423d610616565b903d5f602084013e5b565b61065561062d565b9061064b565b61ffff60f01b1690565b9061067361067a91836103ed565b913561065b565b9060028110610688575b5090565b61069e9061ffff60f01b90600203600802610425565b165f610684565b90565b60f01b90565b6106c26106bd6106c7926106a5565b6106a8565b61065b565b90565b60209181520190565b5f7f7465737457616c6c65743a2064656164207369676e6174757265000000000000910152565b610707601a6020926106ca565b610710816106d3565b0190565b6107299060208101905f8183039101526106fa565b90565b1561073357565b61073b610084565b62461bcd60e51b81528061075160048201610714565b0390fd5b90565b61076c61076761077192610755565b6106a8565b61065b565b90565b60ff1690565b61078e6107896107939261059f565b6103f4565b610774565b90565b90565b6107ad6107a86107b292610796565b6103f4565b610774565b90565b6107c96107c46107ce92610774565b6103f4565b6100d4565b90565b9190506107dc610396565b506107f46107ee8360608101906103a6565b906103ed565b61080761080160146103f7565b916100d4565b146108cd575b610840918161083a926108286108225f6105a2565b916100d4565b116108a1575b506101008101906103a6565b90610665565b61085f8161085861085261dead6106ae565b9161065b565b141561072c565b61087361086d61deaf610758565b9161065b565b145f146108905761088d6108876001610799565b5b6107b5565b90565b61088d61089c5f61077a565b610888565b5f809133906108ae610084565b90816108b9816105d2565b03925af1506108c6610632565b505f61082e565b8160206109026108fd6108f86108f36108ed6109359860608101906103a6565b90610429565b6104a7565b6104bf565b6104d7565b631bab58f59061092a5f610915306104e3565b9361091e610084565b9889958694859361053a565b83526004830161057a565b03925af1918215610983576108409361083a93610957575b509150915061080d565b6109779060203d811161097c575b61096f8183610511565b81019061054f565b61094d565b503d610965565b61058f565b610990610396565b5060015f5d61099e5f6105a2565b90565b6109aa906104cb565b90565b5f9103126109b757565b61008e565b6109c59061022e565b9052565b91906109dc905f602085019401906109bc565b565b6109e7906109a1565b90630396cb60349290929190803b15610a6557610a175f93610a2295610a0b610084565b9687958694859361053a565b8352600483016109c9565b03925af18015610a6057610a34575b50565b610a53905f3d8111610a59575b610a4b8183610511565b8101906109ad565b5f610a31565b503d610a41565b61058f565b6104ef565b5f7f74657374206661696c0000000000000000000000000000000000000000000000910152565b610a9e60096020926106ca565b610aa781610a6a565b0190565b610ac09060208101905f818303910152610a91565b90565b610acb610084565b62461bcd60e51b815280610ae160048201610aab565b0390fd5b5f1b90565b90610af65f1991610ae5565b9181191691161790565b610b14610b0f610b19926100d4565b6103f4565b6100d4565b90565b90565b90610b34610b2f610b3b92610b00565b610b1c565b8254610aea565b9055565b610b4a906001610b1f565b56fea2646970667358221220b38b9fc26f62a27821d9b7ec4f8d872db3cb781cf35b39974360011b61dcacec64736f6c63430008190033", + "nonce": "1", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "balance": "0xda71b71dbd3438e", + "nonce": "2" + } + }, + "config": { + "chainId": 1337, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "rip7560block": 0, + "rip7712block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "pragueTime": 0, + "terminalTotalDifficulty": 0, + "depositContractAddress": "0x0000000000000000000000000000000000000000", + "blobSchedule": { + "cancun": { + "max": 6, + "target": 3, + "baseFeeUpdateFraction": 3338477 + }, + "prague": { + "max": 9, + "target": 6, + "baseFeeUpdateFraction": 5007716 + } + } + } + }, + "context": { + "number": "88", + "difficulty": "0", + "timestamp": "1738267405", + "gasLimit": "30000000", + "miner": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "37852" + }, + "input": "0x02f902f3820539028459682f008459697e8a8305fe79940000000071727de22e5e9d8baf0edac6f37da03280b90284765e827f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000008c9d927336adc963536122f8e0d269319e79ed7a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000f4240000000000000000000000000000493e000000000000000000000000000000000000000000000000000000000000493e0000000000000000000000000b2d05e00000000000000000000000000ee6b280000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024a9e966b7000000000000000000000000000000000000000000000000000000000010f4470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002face000000000000000000000000000000000000000000000000000000000000c080a076f549a86d5973384cf79cabbcf2d9ab0ae3478e8d4b5c643d1e45ea9a57af51a052dd4f3bc56de5c971dbcad1dc5d3ea3a6e7fc037cfb9447ce4a73a12db7430d", + "result": { + "accessedSlots": { + "reads": { + "0x0000000000000000000000000000000000000000000000000000000000000002": [ + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "0x83d2064309e31181791f895d99cc244865c480f99200cd4d4f2412a7a3a265b6": [ + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "0xe18cacf0f1fc038f916461d29104232bd93d822359dfc137927858cc71f1e4ed": [ + "0x0000000000000000000000000000000000000000000000001bc16d674ec80000" + ] + }, + "transientReads": {}, + "transientWrites": {}, + "writes": { + "0x0000000000000000000000000000000000000000000000000000000000000002": 2, + "0x83d2064309e31181791f895d99cc244865c480f99200cd4d4f2412a7a3a265b6": 1, + "0xe18cacf0f1fc038f916461d29104232bd93d822359dfc137927858cc71f1e4ed": 1 + } + }, + "calls": [ + { + "accessedSlots": { + "reads": {}, + "transientReads": {}, + "transientWrites": {}, + "writes": {} + }, + "contractSize": {}, + "extCodeAccessInfo": [], + "from": "0x0000000071727de22e5e9d8baf0edac6f37da032", + "gas": "0x54dda", + "gasUsed": "0x8ec", + "input": "0x19822f7c000000000000000000000000000000000000000000000000000000000000006088a9b2626e43da02f978ae6cc89feffb68afcd5860cb9239337352db4b694fe100000000000000000000000000000000000000000000000000000000000000000000000000000000000000008c9d927336adc963536122f8e0d269319e79ed7a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000f4240000000000000000000000000000493e000000000000000000000000000000000000000000000000000000000000493e0000000000000000000000000b2d05e00000000000000000000000000ee6b280000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024a9e966b7000000000000000000000000000000000000000000000000000000000010f4470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002face000000000000000000000000000000000000000000000000000000000000", + "outOfGas": false, + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "to": "0x8c9d927336adc963536122f8e0d269319e79ed7a", + "type": "CALL", + "usedOpcodes": {"0x34":1, "0x35":9, "0x36":6, "0x51":1, "0x52":2, "0x56":102, "0x57":19, "0x5b":108, "0xf3":1}, + "value": "0x0" + }, + { + "accessedSlots": { + "reads": { + "0xe18cacf0f1fc038f916461d29104232bd93d822359dfc137927858cc71f1e4ed": [ + "0x0000000000000000000000000000000000000000000000001baab0a330380000" + ] + }, + "transientReads": {}, + "transientWrites": {}, + "writes": { + "0xe18cacf0f1fc038f916461d29104232bd93d822359dfc137927858cc71f1e4ed": 1 + } + }, + "calls": [ + { + "accessedSlots": { + "reads": { + "0x0000000000000000000000000000000000000000000000000000000000000001": [ + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + }, + "transientReads": {}, + "transientWrites": {}, + "writes": { + "0x0000000000000000000000000000000000000000000000000000000000000001": 1 + } + }, + "contractSize": {}, + "extCodeAccessInfo": [], + "from": "0x0000000071727de22e5e9d8baf0edac6f37da032", + "gas": "0x493e0", + "gasUsed": "0x5956", + "input": "0xa9e966b7000000000000000000000000000000000000000000000000000000000010f447", + "outOfGas": false, + "to": "0x8c9d927336adc963536122f8e0d269319e79ed7a", + "type": "CALL", + "usedOpcodes": {"0x34":1, "0x35":2, "0x36":2, "0x51":1, "0x52":1, "0x54":1, "0x55":1, "0x56":33, "0x57":9, "0x5b":35, "0xf3":1}, + "value": "0x0" + } + ], + "contractSize": { + "0x8c9d927336adc963536122f8e0d269319e79ed7a": { + "contractSize": 2946, + "opcode": 241 + } + }, + "extCodeAccessInfo": [], + "from": "0x0000000071727de22e5e9d8baf0edac6f37da032", + "gas": "0x4d7ac", + "gasUsed": "0x6ff7", + "input": "0x0042dc5300000000000000000000000000000000000000000000000000000000000002000000000000000000000000008c9d927336adc963536122f8e0d269319e79ed7a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000493e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000493e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee6b280000000000000000000000000000000000000000000000000000000000b2d05e0088a9b2626e43da02f978ae6cc89feffb68afcd5860cb9239337352db4b694fe10000000000000000000000000000000000000000000000000016bcc41e900000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000522d600000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000024a9e966b7000000000000000000000000000000000000000000000000000000000010f447000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "outOfGas": false, + "output": "0x000000000000000000000000000000000000000000000000000421bab3f40fbc", + "to": "0x0000000071727de22e5e9d8baf0edac6f37da032", + "type": "CALL", + "usedOpcodes": {"0x20":1, "0x30":1, "0x33":1, "0x34":1, "0x35":19, "0x36":7, "0x37":2, "0x48":1, "0x51":26, "0x52":31, "0x54":1, "0x55":1, "0x56":27, "0x57":33, "0x5a":5, "0x5b":35, "0xa4":1, "0xf1":1, "0xf3":1}, + "value": "0x0" + }, + { + "accessedSlots": { + "reads": {}, + "transientReads": {}, + "transientWrites": {}, + "writes": {} + }, + "contractSize": {}, + "extCodeAccessInfo": [], + "from": "0x0000000071727de22e5e9d8baf0edac6f37da032", + "gas": "0x44ece", + "gasUsed": "0x0", + "input": "0x", + "outOfGas": false, + "to": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "type": "CALL", + "usedOpcodes": {}, + "value": "0x421bab3f40fbc" + } + ], + "contractSize": { + "0x0000000071727de22e5e9d8baf0edac6f37da032": { + "contractSize": 16035, + "opcode": 241 + }, + "0x8c9d927336adc963536122f8e0d269319e79ed7a": { + "contractSize": 2946, + "opcode": 241 + }, + "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "contractSize": 0, + "opcode": 241 + } + }, + "extCodeAccessInfo": [], + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "gas": "0x5fe79", + "gasUsed": "0x19415", + "input": "0x765e827f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000008c9d927336adc963536122f8e0d269319e79ed7a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000f4240000000000000000000000000000493e000000000000000000000000000000000000000000000000000000000000493e0000000000000000000000000b2d05e00000000000000000000000000ee6b280000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024a9e966b7000000000000000000000000000000000000000000000000000000000010f4470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002face000000000000000000000000000000000000000000000000000000000000", + "keccak": [ + "0x", + "0x0000000000000000000000000000000000000000000000000000000000000000916f81e4e1b2122d13f0474f4c323777192f91bb579723004f6f3062b5fedc68", + "0x0000000000000000000000008c9d927336adc963536122f8e0d269319e79ed7a0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008c9d927336adc963536122f8e0d269319e79ed7a0000000000000000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470ede3d138a3c0ac5537239d818f52c7c86b466472a500982b0e7dff43ab38975d000000000000000000000000000f4240000000000000000000000000000493e000000000000000000000000000000000000000000000000000000000000493e0000000000000000000000000b2d05e00000000000000000000000000ee6b2800c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "0x0000000000000000000000008c9d927336adc963536122f8e0d269319e79ed7a0000000000000000000000000000000000000000000000000000000000000001", + "0xa9e966b7000000000000000000000000000000000000000000000000000000000010f447", + "0xc72bc304a44b01f425579bd71219ccd5676c732ce2aed103da05dc145f00fe340000000000000000000000000000000071727de22e5e9d8baf0edac6f37da0320000000000000000000000000000000000000000000000000000000000000539" + ], + "outOfGas": false, + "to": "0x0000000071727de22e5e9d8baf0edac6f37da032", + "type": "CALL", + "usedOpcodes": {"0x0":1, "0x20":9, "0x30":2, "0x34":1, "0x35":43, "0x36":24, "0x37":8, "0x38":2, "0x3d":2, "0x46":1, "0x51":56, "0x52":104, "0x54":4, "0x55":4, "0x56":92, "0x57":101, "0x5a":4, "0x5b":116, "0xa1":1, "0xf1":3}, + "value": "0x0" + } +} \ No newline at end of file diff --git a/eth/tracers/native/erc7562.go b/eth/tracers/native/erc7562.go new file mode 100644 index 0000000000..3ab98c7132 --- /dev/null +++ b/eth/tracers/native/erc7562.go @@ -0,0 +1,530 @@ +// Copyright 2025 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 + +import ( + "bytes" + "encoding/json" + "errors" + "math/big" + "slices" + "sync/atomic" + + "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/eth/tracers/internal" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" +) + +//go:generate go run github.com/fjl/gencodec -type callFrameWithOpcodes -field-override callFrameWithOpcodesMarshaling -out gen_callframewithopcodes_json.go + +func init() { + tracers.DefaultDirectory.Register("erc7562Tracer", newErc7562Tracer, false) +} + +type contractSizeWithOpcode struct { + ContractSize int `json:"contractSize"` + Opcode vm.OpCode `json:"opcode"` +} + +type callFrameWithOpcodes struct { + Type vm.OpCode `json:"-"` + From common.Address `json:"from"` + Gas uint64 `json:"gas"` + GasUsed uint64 `json:"gasUsed"` + To *common.Address `json:"to,omitempty" rlp:"optional"` + Input []byte `json:"input" rlp:"optional"` + Output []byte `json:"output,omitempty" rlp:"optional"` + Error string `json:"error,omitempty" rlp:"optional"` + RevertReason string `json:"revertReason,omitempty"` + Logs []callLog `json:"logs,omitempty" rlp:"optional"` + Value *big.Int `json:"value,omitempty" rlp:"optional"` + revertedSnapshot bool + + AccessedSlots accessedSlots `json:"accessedSlots"` + ExtCodeAccessInfo []common.Address `json:"extCodeAccessInfo"` + UsedOpcodes map[vm.OpCode]uint64 `json:"usedOpcodes"` + ContractSize map[common.Address]*contractSizeWithOpcode `json:"contractSize"` + OutOfGas bool `json:"outOfGas"` + // Keccak preimages for the whole transaction are stored in the + // root call frame. + KeccakPreimages [][]byte `json:"keccak,omitempty"` + Calls []callFrameWithOpcodes `json:"calls,omitempty" rlp:"optional"` +} + +func (f callFrameWithOpcodes) TypeString() string { + return f.Type.String() +} + +func (f callFrameWithOpcodes) failed() bool { + return len(f.Error) > 0 && f.revertedSnapshot +} + +func (f *callFrameWithOpcodes) 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 + } + if !errors.Is(err, vm.ErrExecutionReverted) || len(output) == 0 { + return + } + f.Output = output + if len(output) < 4 { + return + } + if unpacked, err := abi.UnpackRevert(output); err == nil { + f.RevertReason = unpacked + } +} + +type callFrameWithOpcodesMarshaling struct { + TypeString string `json:"type"` + Gas hexutil.Uint64 + GasUsed hexutil.Uint64 + Value *hexutil.Big + Input hexutil.Bytes + Output hexutil.Bytes + UsedOpcodes map[hexutil.Uint64]uint64 + KeccakPreimages []hexutil.Bytes +} + +type accessedSlots struct { + Reads map[common.Hash][]common.Hash `json:"reads"` + Writes map[common.Hash]uint64 `json:"writes"` + TransientReads map[common.Hash]uint64 `json:"transientReads"` + TransientWrites map[common.Hash]uint64 `json:"transientWrites"` +} + +type opcodeWithPartialStack struct { + Opcode vm.OpCode + StackTopItems []uint256.Int +} + +type erc7562Tracer struct { + config erc7562TracerConfig + gasLimit uint64 + interrupt atomic.Bool // Atomic flag to signal execution interruption + reason error // Textual reason for the interruption + env *tracing.VMContext + + ignoredOpcodes map[vm.OpCode]struct{} + callstackWithOpcodes []callFrameWithOpcodes + lastOpWithStack *opcodeWithPartialStack + keccakPreimages map[string]struct{} +} + +// newErc7562Tracer returns a native go tracer which tracks +// call frames of a tx, and implements vm.EVMLogger. +func newErc7562Tracer(ctx *tracers.Context, cfg json.RawMessage, _ *params.ChainConfig) (*tracers.Tracer, error) { + t, err := newErc7562TracerObject(cfg) + if err != nil { + return nil, err + } + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnOpcode: t.OnOpcode, + OnTxEnd: t.OnTxEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnLog: t.OnLog, + }, + GetResult: t.GetResult, + Stop: t.Stop, + }, nil +} + +type erc7562TracerConfig struct { + StackTopItemsSize int `json:"stackTopItemsSize"` + IgnoredOpcodes []hexutil.Uint64 `json:"ignoredOpcodes"` // Opcodes to ignore during OnOpcode hook execution + WithLog bool `json:"withLog"` // If true, erc7562 tracer will collect event logs +} + +func getFullConfiguration(partial erc7562TracerConfig) erc7562TracerConfig { + config := partial + + if config.IgnoredOpcodes == nil { + config.IgnoredOpcodes = defaultIgnoredOpcodes() + } + if config.StackTopItemsSize == 0 { + config.StackTopItemsSize = 3 + } + + return config +} + +func newErc7562TracerObject(cfg json.RawMessage) (*erc7562Tracer, error) { + var config erc7562TracerConfig + if cfg != nil { + if err := json.Unmarshal(cfg, &config); err != nil { + return nil, err + } + } + fullConfig := getFullConfiguration(config) + // Create a map of ignored opcodes for fast lookup + ignoredOpcodes := make(map[vm.OpCode]struct{}, len(fullConfig.IgnoredOpcodes)) + for _, op := range fullConfig.IgnoredOpcodes { + ignoredOpcodes[vm.OpCode(op)] = struct{}{} + } + // First callframe contains tx context info + // and is populated on start and end. + return &erc7562Tracer{ + callstackWithOpcodes: make([]callFrameWithOpcodes, 0, 1), + config: fullConfig, + keccakPreimages: make(map[string]struct{}), + ignoredOpcodes: ignoredOpcodes, + }, nil +} + +func (t *erc7562Tracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + t.env = env + t.gasLimit = tx.Gas() +} + +// OnEnter is called when EVM enters a new scope (via call, create or selfdestruct). +func (t *erc7562Tracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + // Skip if tracing was interrupted + if t.interrupt.Load() { + return + } + + toCopy := to + call := callFrameWithOpcodes{ + Type: vm.OpCode(typ), + From: from, + To: &toCopy, + Input: common.CopyBytes(input), + Gas: gas, + Value: value, + AccessedSlots: accessedSlots{ + Reads: map[common.Hash][]common.Hash{}, + Writes: map[common.Hash]uint64{}, + TransientReads: map[common.Hash]uint64{}, + TransientWrites: map[common.Hash]uint64{}, + }, + UsedOpcodes: map[vm.OpCode]uint64{}, + ExtCodeAccessInfo: make([]common.Address, 0), + ContractSize: map[common.Address]*contractSizeWithOpcode{}, + } + if depth == 0 { + call.Gas = t.gasLimit + } + t.callstackWithOpcodes = append(t.callstackWithOpcodes, call) +} + +func (t *erc7562Tracer) captureEnd(output []byte, err error, reverted bool) { + if len(t.callstackWithOpcodes) != 1 { + return + } + t.callstackWithOpcodes[0].processOutput(output, err, reverted) +} + +// OnExit is called when EVM exits a scope, even if the scope didn't +// execute any code. +func (t *erc7562Tracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if t.interrupt.Load() { + return + } + if depth == 0 { + t.captureEnd(output, err, reverted) + return + } + + size := len(t.callstackWithOpcodes) + if size <= 1 { + return + } + // Pop call. + call := t.callstackWithOpcodes[size-1] + t.callstackWithOpcodes = t.callstackWithOpcodes[:size-1] + size -= 1 + + if errors.Is(err, vm.ErrCodeStoreOutOfGas) || errors.Is(err, vm.ErrOutOfGas) { + call.OutOfGas = true + } + call.GasUsed = gasUsed + call.processOutput(output, err, reverted) + // Nest call into parent. + t.callstackWithOpcodes[size-1].Calls = append(t.callstackWithOpcodes[size-1].Calls, call) +} + +func (t *erc7562Tracer) OnTxEnd(receipt *types.Receipt, err error) { + if t.interrupt.Load() { + return + } + // Error happened during tx validation. + if err != nil { + return + } + t.callstackWithOpcodes[0].GasUsed = receipt.GasUsed + if t.config.WithLog { + // Logs are not emitted when the call fails + t.clearFailedLogs(&t.callstackWithOpcodes[0], false) + } +} + +func (t *erc7562Tracer) OnLog(log1 *types.Log) { + // Only logs need to be captured via opcode processing + if !t.config.WithLog { + return + } + // Skip if tracing was interrupted + if t.interrupt.Load() { + return + } + l := callLog{ + Address: log1.Address, + Topics: log1.Topics, + Data: log1.Data, + Position: hexutil.Uint(len(t.callstackWithOpcodes[len(t.callstackWithOpcodes)-1].Calls)), + } + t.callstackWithOpcodes[len(t.callstackWithOpcodes)-1].Logs = append(t.callstackWithOpcodes[len(t.callstackWithOpcodes)-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 *erc7562Tracer) GetResult() (json.RawMessage, error) { + if t.interrupt.Load() { + return nil, t.reason + } + if len(t.callstackWithOpcodes) != 1 { + return nil, errors.New("incorrect number of top-level calls") + } + + keccak := make([][]byte, 0, len(t.callstackWithOpcodes[0].KeccakPreimages)) + for k := range t.keccakPreimages { + keccak = append(keccak, []byte(k)) + } + t.callstackWithOpcodes[0].KeccakPreimages = keccak + slices.SortFunc(keccak, func(a, b []byte) int { + return bytes.Compare(a, b) + }) + + enc, err := json.Marshal(t.callstackWithOpcodes[0]) + if err != nil { + return nil, err + } + + return enc, t.reason +} + +// Stop terminates execution of the tracer at the first opportune moment. +func (t *erc7562Tracer) Stop(err error) { + t.reason = err + t.interrupt.Store(true) +} + +// clearFailedLogs clears the logs of a callframe and all its children +// in case of execution failure. +func (t *erc7562Tracer) clearFailedLogs(cf *callFrameWithOpcodes, parentFailed bool) { + failed := cf.failed() || parentFailed + // Clear own logs + if failed { + cf.Logs = nil + } + for i := range cf.Calls { + t.clearFailedLogs(&cf.Calls[i], failed) + } +} + +func (t *erc7562Tracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { + if t.interrupt.Load() { + return + } + var ( + opcode = vm.OpCode(op) + opcodeWithStack *opcodeWithPartialStack + stackSize = len(scope.StackData()) + stackLimit = min(stackSize, t.config.StackTopItemsSize) + stackTopItems = make([]uint256.Int, stackLimit) + ) + for i := 0; i < stackLimit; i++ { + stackTopItems[i] = *peepStack(scope.StackData(), i) + } + opcodeWithStack = &opcodeWithPartialStack{ + Opcode: opcode, + StackTopItems: stackTopItems, + } + t.handleReturnRevert(opcode) + size := len(t.callstackWithOpcodes) + currentCallFrame := &t.callstackWithOpcodes[size-1] + if t.lastOpWithStack != nil { + t.handleExtOpcodes(opcode, currentCallFrame) + } + t.handleAccessedContractSize(opcode, scope, currentCallFrame) + if t.lastOpWithStack != nil { + t.handleGasObserved(opcode, currentCallFrame) + } + t.storeUsedOpcode(opcode, currentCallFrame) + t.handleStorageAccess(opcode, scope, currentCallFrame) + t.storeKeccak(opcode, scope) + t.lastOpWithStack = opcodeWithStack +} + +func (t *erc7562Tracer) handleReturnRevert(opcode vm.OpCode) { + if opcode == vm.REVERT || opcode == vm.RETURN { + t.lastOpWithStack = nil + } +} + +func (t *erc7562Tracer) handleGasObserved(opcode vm.OpCode, currentCallFrame *callFrameWithOpcodes) { + // [OP-012] + pendingGasObserved := t.lastOpWithStack.Opcode == vm.GAS && !isCall(opcode) + if pendingGasObserved { + currentCallFrame.UsedOpcodes[vm.GAS]++ + } +} + +func (t *erc7562Tracer) storeUsedOpcode(opcode vm.OpCode, currentCallFrame *callFrameWithOpcodes) { + // ignore "unimportant" opcodes + if opcode != vm.GAS && !t.isIgnoredOpcode(opcode) { + currentCallFrame.UsedOpcodes[opcode]++ + } +} + +func (t *erc7562Tracer) handleStorageAccess(opcode vm.OpCode, scope tracing.OpContext, currentCallFrame *callFrameWithOpcodes) { + if opcode == vm.SLOAD || opcode == vm.SSTORE || opcode == vm.TLOAD || opcode == vm.TSTORE { + slot := common.BytesToHash(peepStack(scope.StackData(), 0).Bytes()) + addr := scope.Address() + + if opcode == vm.SLOAD { + // read slot values before this UserOp was created + // (so saving it if it was written before the first read) + _, rOk := currentCallFrame.AccessedSlots.Reads[slot] + _, wOk := currentCallFrame.AccessedSlots.Writes[slot] + if !rOk && !wOk { + currentCallFrame.AccessedSlots.Reads[slot] = append(currentCallFrame.AccessedSlots.Reads[slot], t.env.StateDB.GetState(addr, slot)) + } + } else if opcode == vm.SSTORE { + currentCallFrame.AccessedSlots.Writes[slot]++ + } else if opcode == vm.TLOAD { + currentCallFrame.AccessedSlots.TransientReads[slot]++ + } else { + currentCallFrame.AccessedSlots.TransientWrites[slot]++ + } + } +} + +func (t *erc7562Tracer) storeKeccak(opcode vm.OpCode, scope tracing.OpContext) { + if opcode == vm.KECCAK256 { + dataOffset := peepStack(scope.StackData(), 0).Uint64() + dataLength := peepStack(scope.StackData(), 1).Uint64() + preimage, err := internal.GetMemoryCopyPadded(scope.MemoryData(), int64(dataOffset), int64(dataLength)) + if err != nil { + log.Warn("erc7562Tracer: failed to copy keccak preimage from memory", "err", err) + return + } + t.keccakPreimages[string(preimage)] = struct{}{} + } +} + +func (t *erc7562Tracer) handleExtOpcodes(opcode vm.OpCode, currentCallFrame *callFrameWithOpcodes) { + if isEXT(t.lastOpWithStack.Opcode) { + addr := common.HexToAddress(t.lastOpWithStack.StackTopItems[0].Hex()) + + // only store the last EXTCODE* opcode per address - could even be a boolean for our current use-case + // [OP-051] + + if !(t.lastOpWithStack.Opcode == vm.EXTCODESIZE && opcode == vm.ISZERO) { + currentCallFrame.ExtCodeAccessInfo = append(currentCallFrame.ExtCodeAccessInfo, addr) + } + } +} + +func (t *erc7562Tracer) handleAccessedContractSize(opcode vm.OpCode, scope tracing.OpContext, currentCallFrame *callFrameWithOpcodes) { + // [OP-041] + if isEXTorCALL(opcode) { + n := 0 + if !isEXT(opcode) { + n = 1 + } + addr := common.BytesToAddress(peepStack(scope.StackData(), n).Bytes()) + if _, ok := currentCallFrame.ContractSize[addr]; !ok { + currentCallFrame.ContractSize[addr] = &contractSizeWithOpcode{ + ContractSize: len(t.env.StateDB.GetCode(addr)), + Opcode: opcode, + } + } + } +} + +func peepStack(stackData []uint256.Int, n int) *uint256.Int { + return &stackData[len(stackData)-n-1] +} + +func isEXTorCALL(opcode vm.OpCode) bool { + return isEXT(opcode) || isCall(opcode) +} + +func isEXT(opcode vm.OpCode) bool { + return opcode == vm.EXTCODEHASH || + opcode == vm.EXTCODESIZE || + opcode == vm.EXTCODECOPY +} + +func isCall(opcode vm.OpCode) bool { + return opcode == vm.CALL || + opcode == vm.CALLCODE || + opcode == vm.DELEGATECALL || + opcode == vm.STATICCALL +} + +// Check if this opcode is ignored for the purposes of generating the used opcodes report +func (t *erc7562Tracer) isIgnoredOpcode(opcode vm.OpCode) bool { + if _, ok := t.ignoredOpcodes[opcode]; ok { + return true + } + return false +} + +func defaultIgnoredOpcodes() []hexutil.Uint64 { + ignored := make([]hexutil.Uint64, 0, 64) + + // Allow all PUSHx, DUPx and SWAPx opcodes as they have sequential codes + for op := vm.PUSH0; op < vm.SWAP16; op++ { + ignored = append(ignored, hexutil.Uint64(op)) + } + + for _, op := range []vm.OpCode{ + vm.POP, vm.ADD, vm.SUB, vm.MUL, + vm.DIV, vm.EQ, vm.LT, vm.GT, + vm.SLT, vm.SGT, vm.SHL, vm.SHR, + vm.AND, vm.OR, vm.NOT, vm.ISZERO, + } { + ignored = append(ignored, hexutil.Uint64(op)) + } + + return ignored +} diff --git a/eth/tracers/native/gen_callframewithopcodes_json.go b/eth/tracers/native/gen_callframewithopcodes_json.go new file mode 100644 index 0000000000..f3d5dde8f1 --- /dev/null +++ b/eth/tracers/native/gen_callframewithopcodes_json.go @@ -0,0 +1,159 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package native + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/vm" +) + +var _ = (*callFrameWithOpcodesMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (c callFrameWithOpcodes) MarshalJSON() ([]byte, error) { + type callFrameWithOpcodes0 struct { + Type vm.OpCode `json:"-"` + From common.Address `json:"from"` + Gas hexutil.Uint64 `json:"gas"` + GasUsed hexutil.Uint64 `json:"gasUsed"` + To *common.Address `json:"to,omitempty" rlp:"optional"` + Input hexutil.Bytes `json:"input" rlp:"optional"` + Output hexutil.Bytes `json:"output,omitempty" rlp:"optional"` + Error string `json:"error,omitempty" rlp:"optional"` + RevertReason string `json:"revertReason,omitempty"` + Logs []callLog `json:"logs,omitempty" rlp:"optional"` + Value *hexutil.Big `json:"value,omitempty" rlp:"optional"` + AccessedSlots accessedSlots `json:"accessedSlots"` + ExtCodeAccessInfo []common.Address `json:"extCodeAccessInfo"` + UsedOpcodes map[hexutil.Uint64]uint64 `json:"usedOpcodes"` + ContractSize map[common.Address]*contractSizeWithOpcode `json:"contractSize"` + OutOfGas bool `json:"outOfGas"` + KeccakPreimages []hexutil.Bytes `json:"keccak,omitempty"` + Calls []callFrameWithOpcodes `json:"calls,omitempty" rlp:"optional"` + TypeString string `json:"type"` + } + var enc callFrameWithOpcodes0 + enc.Type = c.Type + enc.From = c.From + enc.Gas = hexutil.Uint64(c.Gas) + enc.GasUsed = hexutil.Uint64(c.GasUsed) + enc.To = c.To + enc.Input = c.Input + enc.Output = c.Output + enc.Error = c.Error + enc.RevertReason = c.RevertReason + enc.Logs = c.Logs + enc.Value = (*hexutil.Big)(c.Value) + enc.AccessedSlots = c.AccessedSlots + enc.ExtCodeAccessInfo = c.ExtCodeAccessInfo + if c.UsedOpcodes != nil { + enc.UsedOpcodes = make(map[hexutil.Uint64]uint64, len(c.UsedOpcodes)) + for k, v := range c.UsedOpcodes { + enc.UsedOpcodes[hexutil.Uint64(k)] = v + } + } + enc.ContractSize = c.ContractSize + enc.OutOfGas = c.OutOfGas + if c.KeccakPreimages != nil { + enc.KeccakPreimages = make([]hexutil.Bytes, len(c.KeccakPreimages)) + for k, v := range c.KeccakPreimages { + enc.KeccakPreimages[k] = v + } + } + enc.Calls = c.Calls + enc.TypeString = c.TypeString() + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (c *callFrameWithOpcodes) UnmarshalJSON(input []byte) error { + type callFrameWithOpcodes0 struct { + Type *vm.OpCode `json:"-"` + From *common.Address `json:"from"` + Gas *hexutil.Uint64 `json:"gas"` + GasUsed *hexutil.Uint64 `json:"gasUsed"` + To *common.Address `json:"to,omitempty" rlp:"optional"` + Input *hexutil.Bytes `json:"input" rlp:"optional"` + Output *hexutil.Bytes `json:"output,omitempty" rlp:"optional"` + Error *string `json:"error,omitempty" rlp:"optional"` + RevertReason *string `json:"revertReason,omitempty"` + Logs []callLog `json:"logs,omitempty" rlp:"optional"` + Value *hexutil.Big `json:"value,omitempty" rlp:"optional"` + AccessedSlots *accessedSlots `json:"accessedSlots"` + ExtCodeAccessInfo []common.Address `json:"extCodeAccessInfo"` + UsedOpcodes map[hexutil.Uint64]uint64 `json:"usedOpcodes"` + ContractSize map[common.Address]*contractSizeWithOpcode `json:"contractSize"` + OutOfGas *bool `json:"outOfGas"` + KeccakPreimages []hexutil.Bytes `json:"keccak,omitempty"` + Calls []callFrameWithOpcodes `json:"calls,omitempty" rlp:"optional"` + } + var dec callFrameWithOpcodes0 + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.Type != nil { + c.Type = *dec.Type + } + if dec.From != nil { + c.From = *dec.From + } + if dec.Gas != nil { + c.Gas = uint64(*dec.Gas) + } + if dec.GasUsed != nil { + c.GasUsed = uint64(*dec.GasUsed) + } + if dec.To != nil { + c.To = dec.To + } + if dec.Input != nil { + c.Input = *dec.Input + } + if dec.Output != nil { + c.Output = *dec.Output + } + if dec.Error != nil { + c.Error = *dec.Error + } + if dec.RevertReason != nil { + c.RevertReason = *dec.RevertReason + } + if dec.Logs != nil { + c.Logs = dec.Logs + } + if dec.Value != nil { + c.Value = (*big.Int)(dec.Value) + } + if dec.AccessedSlots != nil { + c.AccessedSlots = *dec.AccessedSlots + } + if dec.ExtCodeAccessInfo != nil { + c.ExtCodeAccessInfo = dec.ExtCodeAccessInfo + } + if dec.UsedOpcodes != nil { + c.UsedOpcodes = make(map[vm.OpCode]uint64, len(dec.UsedOpcodes)) + for k, v := range dec.UsedOpcodes { + c.UsedOpcodes[vm.OpCode(k)] = v + } + } + if dec.ContractSize != nil { + c.ContractSize = dec.ContractSize + } + if dec.OutOfGas != nil { + c.OutOfGas = *dec.OutOfGas + } + if dec.KeccakPreimages != nil { + c.KeccakPreimages = make([][]byte, len(dec.KeccakPreimages)) + for k, v := range dec.KeccakPreimages { + c.KeccakPreimages[k] = v + } + } + if dec.Calls != nil { + c.Calls = dec.Calls + } + return nil +} From 63740b7aca732f6c204c56a9e4b4932f5251e4e0 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 20 May 2025 18:31:01 +0200 Subject: [PATCH 382/940] core/state: reduce allocation in updateStateObject (#31861) Optimize updateStateObject to reduce an allocation. --- core/state/statedb.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 2453d67f3e..51453055c3 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -562,9 +562,8 @@ func (s *StateDB) GetTransientState(addr common.Address, key common.Hash) common // updateStateObject writes the given object to the trie. func (s *StateDB) updateStateObject(obj *stateObject) { // Encode the account and update the account trie - addr := obj.Address() - if err := s.trie.UpdateAccount(addr, &obj.data, len(obj.code)); err != nil { - s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err)) + if err := s.trie.UpdateAccount(obj.Address(), &obj.data, len(obj.code)); err != nil { + s.setError(fmt.Errorf("updateStateObject (%x) error: %v", obj.Address(), err)) } if obj.dirtyCode { s.trie.UpdateContractCode(obj.Address(), common.BytesToHash(obj.CodeHash()), obj.code) From a4959685a2ca2eba558ac9c233c4b67c9fd0edac Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 21 May 2025 11:53:29 +0200 Subject: [PATCH 383/940] eth/catalyst: move witness methods from engine api (#31867) No functional changes, just moves the witness methods into its own file --- eth/catalyst/api.go | 265 ------------------------------------ eth/catalyst/witness.go | 295 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+), 265 deletions(-) create mode 100644 eth/catalyst/witness.go diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index be25712c97..b5f035b6d2 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -27,11 +27,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" "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/core/vm" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/internal/version" @@ -245,58 +242,6 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, pa return api.forkchoiceUpdated(update, params, engine.PayloadV3, false) } -// 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 { - switch { - case payloadAttributes.Withdrawals != nil || payloadAttributes.BeaconRoot != nil: - return engine.STATUS_INVALID, paramsErr("withdrawals and beacon root not supported in V1") - case !api.checkFork(payloadAttributes.Timestamp, forks.Paris, forks.Shanghai): - return engine.STATUS_INVALID, paramsErr("fcuV1 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 { - switch { - case params.BeaconRoot != nil: - return engine.STATUS_INVALID, attributesErr("unexpected beacon root") - case api.checkFork(params.Timestamp, forks.Paris) && params.Withdrawals != nil: - return engine.STATUS_INVALID, attributesErr("withdrawals before shanghai") - case api.checkFork(params.Timestamp, forks.Shanghai) && params.Withdrawals == nil: - return engine.STATUS_INVALID, attributesErr("missing withdrawals") - case !api.checkFork(params.Timestamp, forks.Paris, forks.Shanghai): - return engine.STATUS_INVALID, unsupportedForkErr("fcuV2 must only be called with paris or 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 { - switch { - case params.Withdrawals == nil: - return engine.STATUS_INVALID, attributesErr("missing withdrawals") - case params.BeaconRoot == nil: - return engine.STATUS_INVALID, attributesErr("missing beacon root") - case !api.checkFork(params.Timestamp, forks.Cancun, forks.Prague): - return engine.STATUS_INVALID, unsupportedForkErr("fcuV3 must only be called for cancun or prague 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() @@ -615,160 +560,6 @@ func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHas return api.newPayload(params, versionedHashes, beaconRoot, requests, false) } -// 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, 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) { - var ( - cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp) - shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp) - ) - switch { - case cancun: - return invalidStatus, paramsErr("can't use newPayloadV2 post-cancun") - case shanghai && params.Withdrawals == nil: - return invalidStatus, paramsErr("nil withdrawals post-shanghai") - case !shanghai && params.Withdrawals != nil: - return invalidStatus, paramsErr("non-nil withdrawals pre-shanghai") - case params.ExcessBlobGas != nil: - return invalidStatus, paramsErr("non-nil excessBlobGas pre-cancun") - case params.BlobGasUsed != nil: - return invalidStatus, paramsErr("non-nil blobGasUsed pre-cancun") - } - return api.newPayload(params, nil, 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) { - switch { - case params.Withdrawals == nil: - return invalidStatus, paramsErr("nil withdrawals post-shanghai") - case params.ExcessBlobGas == nil: - return invalidStatus, paramsErr("nil excessBlobGas post-cancun") - case params.BlobGasUsed == nil: - return invalidStatus, paramsErr("nil blobGasUsed post-cancun") - case versionedHashes == nil: - return invalidStatus, paramsErr("nil versionedHashes post-cancun") - case beaconRoot == nil: - return invalidStatus, paramsErr("nil beaconRoot post-cancun") - case !api.checkFork(params.Timestamp, forks.Cancun): - return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") - } - return api.newPayload(params, versionedHashes, beaconRoot, nil, 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, executionRequests []hexutil.Bytes) (engine.PayloadStatusV1, error) { - switch { - case params.Withdrawals == nil: - return invalidStatus, paramsErr("nil withdrawals post-shanghai") - case params.ExcessBlobGas == nil: - return invalidStatus, paramsErr("nil excessBlobGas post-cancun") - case params.BlobGasUsed == nil: - return invalidStatus, paramsErr("nil blobGasUsed post-cancun") - case versionedHashes == nil: - return invalidStatus, paramsErr("nil versionedHashes post-cancun") - case beaconRoot == nil: - return invalidStatus, paramsErr("nil beaconRoot post-cancun") - case executionRequests == nil: - return invalidStatus, paramsErr("nil executionRequests post-prague") - case !api.checkFork(params.Timestamp, forks.Prague): - return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") - } - requests := convertRequests(executionRequests) - if err := validateRequests(requests); err != nil { - return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) - } - return api.newPayload(params, versionedHashes, beaconRoot, requests, 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, 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) { - var ( - cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp) - shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp) - ) - switch { - case cancun: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("can't use newPayloadV2 post-cancun") - case shanghai && params.Withdrawals == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") - case !shanghai && params.Withdrawals != nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil withdrawals pre-shanghai") - case params.ExcessBlobGas != nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil excessBlobGas pre-cancun") - case params.BlobGasUsed != nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil blobGasUsed pre-cancun") - } - return api.executeStatelessPayload(params, nil, 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) { - switch { - case params.Withdrawals == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") - case params.ExcessBlobGas == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil excessBlobGas post-cancun") - case params.BlobGasUsed == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil blobGasUsed post-cancun") - case versionedHashes == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil versionedHashes post-cancun") - case beaconRoot == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil beaconRoot post-cancun") - case !api.checkFork(params.Timestamp, forks.Cancun): - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") - } - return api.executeStatelessPayload(params, versionedHashes, beaconRoot, nil, 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, executionRequests []hexutil.Bytes, opaqueWitness hexutil.Bytes) (engine.StatelessPayloadStatusV1, error) { - switch { - case params.Withdrawals == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") - case params.ExcessBlobGas == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil excessBlobGas post-cancun") - case params.BlobGasUsed == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil blobGasUsed post-cancun") - case versionedHashes == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil versionedHashes post-cancun") - case beaconRoot == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil beaconRoot post-cancun") - case executionRequests == nil: - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil executionRequests post-prague") - case !api.checkFork(params.Timestamp, forks.Prague): - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") - } - requests := convertRequests(executionRequests) - if err := validateRequests(requests); err != nil { - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) - } - return api.executeStatelessPayload(params, versionedHashes, beaconRoot, requests, opaqueWitness) -} - func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, witness bool) (engine.PayloadStatusV1, error) { // The locking here is, strictly, not required. Without these locks, this can happen: // @@ -884,62 +675,6 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe return engine.PayloadStatusV1{Status: engine.VALID, Witness: ow, LatestValidHash: &hash}, nil } -func (api *ConsensusAPI) executeStatelessPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, 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, requests) - 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), - "beaconRoot", beaconRoot, - "len(requests)", len(requests), - "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.config(), vm.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 diff --git a/eth/catalyst/witness.go b/eth/catalyst/witness.go new file mode 100644 index 0000000000..214bee57a4 --- /dev/null +++ b/eth/catalyst/witness.go @@ -0,0 +1,295 @@ +// Copyright 2025 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 catalyst + +import ( + "errors" + "strconv" + "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/stateless" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params/forks" + "github.com/ethereum/go-ethereum/rlp" +) + +// 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 { + switch { + case payloadAttributes.Withdrawals != nil || payloadAttributes.BeaconRoot != nil: + return engine.STATUS_INVALID, paramsErr("withdrawals and beacon root not supported in V1") + case !api.checkFork(payloadAttributes.Timestamp, forks.Paris, forks.Shanghai): + return engine.STATUS_INVALID, paramsErr("fcuV1 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 { + switch { + case params.BeaconRoot != nil: + return engine.STATUS_INVALID, attributesErr("unexpected beacon root") + case api.checkFork(params.Timestamp, forks.Paris) && params.Withdrawals != nil: + return engine.STATUS_INVALID, attributesErr("withdrawals before shanghai") + case api.checkFork(params.Timestamp, forks.Shanghai) && params.Withdrawals == nil: + return engine.STATUS_INVALID, attributesErr("missing withdrawals") + case !api.checkFork(params.Timestamp, forks.Paris, forks.Shanghai): + return engine.STATUS_INVALID, unsupportedForkErr("fcuV2 must only be called with paris or 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 { + switch { + case params.Withdrawals == nil: + return engine.STATUS_INVALID, attributesErr("missing withdrawals") + case params.BeaconRoot == nil: + return engine.STATUS_INVALID, attributesErr("missing beacon root") + case !api.checkFork(params.Timestamp, forks.Cancun, forks.Prague): + return engine.STATUS_INVALID, unsupportedForkErr("fcuV3 must only be called for cancun or prague 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) +} + +// 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, 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) { + var ( + cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp) + shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp) + ) + switch { + case cancun: + return invalidStatus, paramsErr("can't use newPayloadV2 post-cancun") + case shanghai && params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case !shanghai && params.Withdrawals != nil: + return invalidStatus, paramsErr("non-nil withdrawals pre-shanghai") + case params.ExcessBlobGas != nil: + return invalidStatus, paramsErr("non-nil excessBlobGas pre-cancun") + case params.BlobGasUsed != nil: + return invalidStatus, paramsErr("non-nil blobGasUsed pre-cancun") + } + return api.newPayload(params, nil, 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) { + switch { + case params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return invalidStatus, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return invalidStatus, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return invalidStatus, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return invalidStatus, paramsErr("nil beaconRoot post-cancun") + case !api.checkFork(params.Timestamp, forks.Cancun): + return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") + } + return api.newPayload(params, versionedHashes, beaconRoot, nil, 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, executionRequests []hexutil.Bytes) (engine.PayloadStatusV1, error) { + switch { + case params.Withdrawals == nil: + return invalidStatus, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return invalidStatus, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return invalidStatus, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return invalidStatus, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return invalidStatus, paramsErr("nil beaconRoot post-cancun") + case executionRequests == nil: + return invalidStatus, paramsErr("nil executionRequests post-prague") + case !api.checkFork(params.Timestamp, forks.Prague): + return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") + } + requests := convertRequests(executionRequests) + if err := validateRequests(requests); err != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) + } + return api.newPayload(params, versionedHashes, beaconRoot, requests, 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, 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) { + var ( + cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp) + shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp) + ) + switch { + case cancun: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("can't use newPayloadV2 post-cancun") + case shanghai && params.Withdrawals == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") + case !shanghai && params.Withdrawals != nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil withdrawals pre-shanghai") + case params.ExcessBlobGas != nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil excessBlobGas pre-cancun") + case params.BlobGasUsed != nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("non-nil blobGasUsed pre-cancun") + } + return api.executeStatelessPayload(params, nil, 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) { + switch { + case params.Withdrawals == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil beaconRoot post-cancun") + case !api.checkFork(params.Timestamp, forks.Cancun): + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") + } + return api.executeStatelessPayload(params, versionedHashes, beaconRoot, nil, 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, executionRequests []hexutil.Bytes, opaqueWitness hexutil.Bytes) (engine.StatelessPayloadStatusV1, error) { + switch { + case params.Withdrawals == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil withdrawals post-shanghai") + case params.ExcessBlobGas == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil excessBlobGas post-cancun") + case params.BlobGasUsed == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil blobGasUsed post-cancun") + case versionedHashes == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil versionedHashes post-cancun") + case beaconRoot == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil beaconRoot post-cancun") + case executionRequests == nil: + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil executionRequests post-prague") + case !api.checkFork(params.Timestamp, forks.Prague): + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads") + } + requests := convertRequests(executionRequests) + if err := validateRequests(requests); err != nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) + } + return api.executeStatelessPayload(params, versionedHashes, beaconRoot, requests, opaqueWitness) +} + +func (api *ConsensusAPI) executeStatelessPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, 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, requests) + 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), + "beaconRoot", beaconRoot, + "len(requests)", len(requests), + "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.config(), vm.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 +} From 0287666b7d9beffb93f5a7c6500d242d00dbd085 Mon Sep 17 00:00:00 2001 From: wellna Date: Wed, 21 May 2025 13:20:36 +0100 Subject: [PATCH 384/940] eth/tracers: Improve test coverage for toWord (#31846) --- eth/tracers/js/goja.go | 1 - eth/tracers/js/tracer_test.go | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index d1e65bf7f4..7ec737f4e4 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -480,7 +480,6 @@ func (t *jsTracer) setBuiltinFunctions() { return hexutil.Encode(b) }) vm.Set("toWord", func(v goja.Value) goja.Value { - // TODO: add test with []byte len < 32 or > 32 b, err := t.fromBuf(vm, v, true) if err != nil { vm.Interrupt(err) diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index dbfc7308f7..a12b990a93 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -122,9 +122,15 @@ func TestTracer(t *testing.T) { }, { // tests gasUsed code: "{depths: [], step: function() {}, fault: function() {}, result: function(ctx) { return ctx.gasPrice+'.'+ctx.gasUsed; }}", want: `"100000.21006"`, - }, { + }, { // tests toWord with byte array length < 32 code: "{res: null, step: function(log) {}, fault: function() {}, result: function() { return toWord('0xffaa') }}", 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,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":255,"31":170}`, + }, { // tests toWord with byte array length = 32 + code: "{step: function() {}, fault: function() {}, result: function() { return toWord('0x1234567890123456789012345678901234567890123456789012345678901234'); }}", + want: `{"0":18,"1":52,"2":86,"3":120,"4":144,"5":18,"6":52,"7":86,"8":120,"9":144,"10":18,"11":52,"12":86,"13":120,"14":144,"15":18,"16":52,"17":86,"18":120,"19":144,"20":18,"21":52,"22":86,"23":120,"24":144,"25":18,"26":52,"27":86,"28":120,"29":144,"30":18,"31":52}`, + }, { // tests toWord with byte array length > 32 + code: "{step: function() {}, fault: function() {}, result: function() { return toWord('0x1234567890123456789012345678901234567890123456789012345678901234567890'); }}", + want: `{"0":120,"1":144,"2":18,"3":52,"4":86,"5":120,"6":144,"7":18,"8":52,"9":86,"10":120,"11":144,"12":18,"13":52,"14":86,"15":120,"16":144,"17":18,"18":52,"19":86,"20":120,"21":144,"22":18,"23":52,"24":86,"25":120,"26":144,"27":18,"28":52,"29":86,"30":120,"31":144}`, }, { // test feeding a buffer back into go code: "{res: null, step: function(log) { var address = log.contract.getAddress(); this.res = toAddress(address); }, fault: function() {}, result: function() { return this.res }}", 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}`, From 20ad4f500e7fafab93f6d94fa171a5c0309de6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Garamv=C3=B6lgyi?= Date: Thu, 22 May 2025 11:30:20 +0200 Subject: [PATCH 385/940] core/txpool: add explicit max blob count limit (#31837) Fixes #31792. --------- Co-authored-by: lightclient --- core/txpool/blobpool/blobpool.go | 15 +++++-- core/txpool/blobpool/blobpool_test.go | 59 +++++++++++++++++++++++++++ core/txpool/errors.go | 4 ++ core/txpool/validation.go | 10 +++-- 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index e506da228d..2602d82104 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -62,6 +62,12 @@ const ( // limit can never hurt. txMaxSize = 1024 * 1024 + // maxBlobsPerTx is the maximum number of blobs that a single transaction can + // carry. We choose a smaller limit than the protocol-permitted MaxBlobsPerBlock + // in order to ensure network and txpool stability. + // Note: if you increase this, validation will fail on txMaxSize. + maxBlobsPerTx = 7 + // maxTxsPerAccount is the maximum number of blob transactions admitted from // a single account. The limit is enforced to minimize the DoS potential of // a private tx cancelling publicly propagated blobs. @@ -1095,10 +1101,11 @@ func (p *BlobPool) SetGasTip(tip *big.Int) { // and does not require the pool mutex to be held. func (p *BlobPool) ValidateTxBasics(tx *types.Transaction) error { opts := &txpool.ValidationOptions{ - Config: p.chain.Config(), - Accept: 1 << types.BlobTxType, - MaxSize: txMaxSize, - MinTip: p.gasTip.ToBig(), + Config: p.chain.Config(), + Accept: 1 << types.BlobTxType, + MaxSize: txMaxSize, + MinTip: p.gasTip.ToBig(), + MaxBlobCount: maxBlobsPerTx, } return txpool.ValidateTransaction(tx, p.head, p.signer, opts) } diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 0a323179a6..12b64bf674 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -1142,6 +1142,65 @@ func TestChangingSlotterSize(t *testing.T) { } } +// TestBlobCountLimit tests the blobpool enforced limits on the max blob count. +func TestBlobCountLimit(t *testing.T) { + var ( + key1, _ = crypto.GenerateKey() + key2, _ = crypto.GenerateKey() + + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + ) + + 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.Commit(0, true, false) + + // Make Prague-enabled custom chain config. + cancunTime := uint64(0) + pragueTime := uint64(0) + config := ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + LondonBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + CancunTime: &cancunTime, + PragueTime: &pragueTime, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + }, + } + chain := &testBlockChain{ + config: config, + basefee: uint256.NewInt(1050), + blobfee: uint256.NewInt(105), + statedb: statedb, + } + pool := New(Config{Datadir: t.TempDir()}, chain, nil) + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { + t.Fatalf("failed to create blob pool: %v", err) + } + + // Attempt to add transactions. + var ( + tx1 = makeMultiBlobTx(0, 1, 1000, 100, 7, key1) + tx2 = makeMultiBlobTx(0, 1, 800, 70, 8, key2) + ) + errs := pool.Add([]*types.Transaction{tx1, tx2}, true) + + // Check that first succeeds second fails. + if errs[0] != nil { + t.Fatalf("expected tx with 7 blobs to succeed") + } + if !errors.Is(errs[1], txpool.ErrTxBlobLimitExceeded) { + t.Fatalf("expected tx with 8 blobs to fail, got: %v", errs[1]) + } + + verifyPoolInternals(t, pool) + pool.Close() +} + // Tests that adding transaction will correctly store it in the persistent store // and update all the indices. // diff --git a/core/txpool/errors.go b/core/txpool/errors.go index 968c9d9542..9bc435d67e 100644 --- a/core/txpool/errors.go +++ b/core/txpool/errors.go @@ -58,6 +58,10 @@ var ( // making the transaction invalid, rather a DOS protection. ErrOversizedData = errors.New("oversized data") + // ErrTxBlobLimitExceeded is returned if a transaction would exceed the number + // of blobs allowed by blobpool. + ErrTxBlobLimitExceeded = errors.New("transaction blob limit exceeded") + // ErrAlreadyReserved is returned if the sender address has a pending transaction // in a different subpool. For example, this error is returned in response to any // input transaction of non-blob type when a blob transaction from this sender diff --git a/core/txpool/validation.go b/core/txpool/validation.go index e370f2ce84..720d0d3b72 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -42,9 +42,10 @@ var ( type ValidationOptions struct { Config *params.ChainConfig // Chain configuration to selectively validate based on current fork rules - Accept uint8 // Bitmap of transaction types that should be accepted for the calling pool - MaxSize uint64 // Maximum size of a transaction that the caller can meaningfully handle - MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool + Accept uint8 // Bitmap of transaction types that should be accepted for the calling pool + MaxSize uint64 // Maximum size of a transaction that the caller can meaningfully handle + MaxBlobCount int // Maximum number of blobs allowed per transaction + MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool } // ValidationFunction is an method type which the pools use to perform the tx-validations which do not @@ -63,6 +64,9 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types if opts.Accept&(1< opts.MaxBlobCount { + return fmt.Errorf("%w: blob count %v, limit %v", ErrTxBlobLimitExceeded, blobCount, opts.MaxBlobCount) + } // Before performing any expensive validations, sanity check that the tx is // smaller than the maximum limit the pool can meaningfully handle if tx.Size() > opts.MaxSize { From 29a87e442645bc34d08e5c8709c619411c6c3624 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Thu, 22 May 2025 15:49:11 -0600 Subject: [PATCH 386/940] build: Update EEST to v4.5.0 (#31880) We deleted outdated pectra-devnet-6@v1.0.0 release by mistake, so this PR updates the referenced EEST release to the correct latest version. @s1na I removed the TODO comment because I think this solves it, unless it meant something else. --------- Co-authored-by: MariusVanDerWijden --- build/checksums.txt | 6 +++--- build/ci.go | 2 +- tests/block_test.go | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/build/checksums.txt b/build/checksums.txt index c819429969..cf52172c2e 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -1,9 +1,9 @@ # This file contains sha256 checksums of optional build dependencies. -# version:spec-tests pectra-devnet-6@v1.0.0 +# version:spec-tests v4.5.0 # https://github.com/ethereum/execution-spec-tests/releases -# https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/ -b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz +# https://github.com/ethereum/execution-spec-tests/releases/download/v4.5.0/ +58afb92a0075a2cb7c4dec1281f7cb88b21b02afbedad096b580f3f8cc14c54c fixtures_develop.tar.gz # version:golang 1.24.3 # https://go.dev/dl/ diff --git a/build/ci.go b/build/ci.go index 88e4e82282..58c769e0d7 100644 --- a/build/ci.go +++ b/build/ci.go @@ -332,7 +332,7 @@ func doTest(cmdline []string) { // downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures. func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string { ext := ".tar.gz" - base := "fixtures_pectra-devnet-6" // TODO(s1na) rename once the version becomes part of the filename + base := "fixtures_develop" archivePath := filepath.Join(cachedir, base+ext) if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil { log.Fatal(err) diff --git a/tests/block_test.go b/tests/block_test.go index f146e4ee6a..91d9f2e653 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -81,6 +81,9 @@ func TestExecutionSpecBlocktests(t *testing.T) { } bt := new(testMatcher) + bt.skipLoad(".*prague/eip7251_consolidations/contract_deployment/system_contract_deployment.json") + bt.skipLoad(".*prague/eip7002_el_triggerable_withdrawals/contract_deployment/system_contract_deployment.json") + bt.walk(t, executionSpecBlockchainTestDir, func(t *testing.T, name string, test *BlockTest) { execBlockTest(t, bt, test) }) From 1fd806d3e59b1da29297611e0046df0bc742658d Mon Sep 17 00:00:00 2001 From: Merkel Tranjes <140164174+rnkrtt@users.noreply.github.com> Date: Fri, 23 May 2025 09:21:03 +0200 Subject: [PATCH 387/940] internal/era: update link to documentation (#31879) Updated reference URL in accumulator.go comment to point to the correct location of the historical-hashes-accumulator documentation in the Ethereum portal network specs --- internal/era/accumulator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/era/accumulator.go b/internal/era/accumulator.go index cb383d8e63..83a761f1fd 100644 --- a/internal/era/accumulator.go +++ b/internal/era/accumulator.go @@ -49,7 +49,7 @@ func ComputeAccumulator(hashes []common.Hash, tds []*big.Int) (common.Hash, erro // headerRecord is an individual record for a historical header. // -// See https://github.com/ethereum/portal-network-specs/blob/master/history-network.md#the-header-accumulator +// See https://github.com/ethereum/portal-network-specs/blob/master/history/history-network.md#the-historical-hashes-accumulator // for more information. type headerRecord struct { Hash common.Hash From a53fdf1fe6eac47899738dccba5a652936aebb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Fri, 23 May 2025 12:14:40 +0300 Subject: [PATCH 388/940] crypto: use pure Go signature implementation in tinygo (#31878) tinygo is having problems compiling the C implementation --- crypto/signature_cgo.go | 4 ++-- crypto/signature_nocgo.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go index 5c7810c14c..18b78f4aac 100644 --- a/crypto/signature_cgo.go +++ b/crypto/signature_cgo.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build !nacl && !js && !wasip1 && cgo && !gofuzz -// +build !nacl,!js,!wasip1,cgo,!gofuzz +//go:build !nacl && !js && !wasip1 && cgo && !gofuzz && !tinygo +// +build !nacl,!js,!wasip1,cgo,!gofuzz,!tinygo package crypto diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 2d35b49403..d76127c258 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build nacl || js || wasip1 || !cgo || gofuzz -// +build nacl js wasip1 !cgo gofuzz +//go:build nacl || js || wasip1 || !cgo || gofuzz || tinygo +// +build nacl js wasip1 !cgo gofuzz tinygo package crypto From f21adaf245e320a809f9bb6ec96c330726c9078f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Fri, 23 May 2025 12:29:01 +0300 Subject: [PATCH 389/940] consensus: remove clique RPC APIs (#31875) --- consensus/beacon/consensus.go | 6 - consensus/clique/api.go | 235 ---------------------------------- consensus/clique/clique.go | 10 -- consensus/consensus.go | 4 - consensus/ethash/ethash.go | 7 - eth/backend.go | 3 - 6 files changed, 265 deletions(-) delete mode 100644 consensus/clique/api.go diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index cc9f44e460..f9a5a3233b 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -30,7 +30,6 @@ import ( "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" "github.com/holiman/uint256" ) @@ -445,11 +444,6 @@ func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uin return beaconDifficulty } -// APIs implements consensus.Engine, returning the user facing RPC APIs. -func (beacon *Beacon) APIs(chain consensus.ChainHeaderReader) []rpc.API { - return beacon.ethone.APIs(chain) -} - // Close shutdowns the consensus engine func (beacon *Beacon) Close() error { return beacon.ethone.Close() diff --git a/consensus/clique/api.go b/consensus/clique/api.go deleted file mode 100644 index 374b50692d..0000000000 --- a/consensus/clique/api.go +++ /dev/null @@ -1,235 +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 clique - -import ( - "encoding/json" - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/consensus" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc" -) - -// API is a user facing RPC API to allow controlling the signer and voting -// mechanisms of the proof-of-authority scheme. -type API struct { - chain consensus.ChainHeaderReader - clique *Clique -} - -// GetSnapshot retrieves the state snapshot at a given block. -func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { - // Retrieve the requested block number (or current if none requested) - var header *types.Header - if number == nil || *number == rpc.LatestBlockNumber { - header = api.chain.CurrentHeader() - } else { - header = api.chain.GetHeaderByNumber(uint64(number.Int64())) - } - // Ensure we have an actually valid block and return its snapshot - if header == nil { - return nil, errUnknownBlock - } - return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) -} - -// GetSnapshotAtHash retrieves the state snapshot at a given block. -func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { - header := api.chain.GetHeaderByHash(hash) - if header == nil { - return nil, errUnknownBlock - } - return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) -} - -// GetSigners retrieves the list of authorized signers at the specified block. -func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) { - // Retrieve the requested block number (or current if none requested) - var header *types.Header - if number == nil || *number == rpc.LatestBlockNumber { - header = api.chain.CurrentHeader() - } else { - header = api.chain.GetHeaderByNumber(uint64(number.Int64())) - } - // Ensure we have an actually valid block and return the signers from its snapshot - if header == nil { - return nil, errUnknownBlock - } - snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) - if err != nil { - return nil, err - } - return snap.signers(), nil -} - -// GetSignersAtHash retrieves the list of authorized signers at the specified block. -func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) { - header := api.chain.GetHeaderByHash(hash) - if header == nil { - return nil, errUnknownBlock - } - snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) - if err != nil { - return nil, err - } - return snap.signers(), nil -} - -// Proposals returns the current proposals the node tries to uphold and vote on. -func (api *API) Proposals() map[common.Address]bool { - api.clique.lock.RLock() - defer api.clique.lock.RUnlock() - - proposals := make(map[common.Address]bool) - for address, auth := range api.clique.proposals { - proposals[address] = auth - } - return proposals -} - -// Propose injects a new authorization proposal that the signer will attempt to -// push through. -func (api *API) Propose(address common.Address, auth bool) { - api.clique.lock.Lock() - defer api.clique.lock.Unlock() - - api.clique.proposals[address] = auth -} - -// Discard drops a currently running proposal, stopping the signer from casting -// further votes (either for or against). -func (api *API) Discard(address common.Address) { - api.clique.lock.Lock() - defer api.clique.lock.Unlock() - - delete(api.clique.proposals, address) -} - -type status struct { - InturnPercent float64 `json:"inturnPercent"` - SigningStatus map[common.Address]int `json:"sealerActivity"` - NumBlocks uint64 `json:"numBlocks"` -} - -// Status returns the status of the last N blocks, -// - the number of active signers, -// - the number of signers, -// - the percentage of in-turn blocks -func (api *API) Status() (*status, error) { - var ( - numBlocks = uint64(64) - header = api.chain.CurrentHeader() - diff = uint64(0) - optimals = 0 - ) - snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) - if err != nil { - return nil, err - } - var ( - signers = snap.signers() - end = header.Number.Uint64() - start = end - numBlocks - ) - if numBlocks > end { - start = 1 - numBlocks = end - start - } - signStatus := make(map[common.Address]int) - for _, s := range signers { - signStatus[s] = 0 - } - for n := start; n < end; n++ { - h := api.chain.GetHeaderByNumber(n) - if h == nil { - return nil, fmt.Errorf("missing block %d", n) - } - if h.Difficulty.Cmp(diffInTurn) == 0 { - optimals++ - } - diff += h.Difficulty.Uint64() - sealer, err := api.clique.Author(h) - if err != nil { - return nil, err - } - signStatus[sealer]++ - } - return &status{ - InturnPercent: float64(100*optimals) / float64(numBlocks), - SigningStatus: signStatus, - NumBlocks: numBlocks, - }, nil -} - -type blockNumberOrHashOrRLP struct { - *rpc.BlockNumberOrHash - RLP hexutil.Bytes `json:"rlp,omitempty"` -} - -func (sb *blockNumberOrHashOrRLP) UnmarshalJSON(data []byte) error { - bnOrHash := new(rpc.BlockNumberOrHash) - // Try to unmarshal bNrOrHash - if err := bnOrHash.UnmarshalJSON(data); err == nil { - sb.BlockNumberOrHash = bnOrHash - return nil - } - // Try to unmarshal RLP - var input string - if err := json.Unmarshal(data, &input); err != nil { - return err - } - blob, err := hexutil.Decode(input) - if err != nil { - return err - } - sb.RLP = blob - return nil -} - -// GetSigner returns the signer for a specific clique block. -// Can be called with a block number, a block hash or a rlp encoded blob. -// The RLP encoded blob can either be a block or a header. -func (api *API) GetSigner(rlpOrBlockNr *blockNumberOrHashOrRLP) (common.Address, error) { - if len(rlpOrBlockNr.RLP) == 0 { - blockNrOrHash := rlpOrBlockNr.BlockNumberOrHash - var header *types.Header - if blockNrOrHash == nil { - header = api.chain.CurrentHeader() - } else if hash, ok := blockNrOrHash.Hash(); ok { - header = api.chain.GetHeaderByHash(hash) - } else if number, ok := blockNrOrHash.Number(); ok { - header = api.chain.GetHeaderByNumber(uint64(number.Int64())) - } - if header == nil { - return common.Address{}, fmt.Errorf("missing block %v", blockNrOrHash.String()) - } - return api.clique.Author(header) - } - block := new(types.Block) - if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, block); err == nil { - return api.clique.Author(block.Header()) - } - header := new(types.Header) - if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, header); err != nil { - return common.Address{}, err - } - return api.clique.Author(header) -} diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index d31efd7445..b593d2117d 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -41,7 +41,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" "golang.org/x/crypto/sha3" ) @@ -641,15 +640,6 @@ func (c *Clique) Close() error { return nil } -// APIs implements consensus.Engine, returning the user facing RPC API to allow -// controlling the signer voting. -func (c *Clique) APIs(chain consensus.ChainHeaderReader) []rpc.API { - return []rpc.API{{ - Namespace: "clique", - Service: &API{chain: chain, clique: c}, - }} -} - // SealHash returns the hash of a block prior to it being sealed. func SealHash(header *types.Header) (hash common.Hash) { hasher := sha3.NewLegacyKeccak256() diff --git a/consensus/consensus.go b/consensus/consensus.go index c59b9a4744..a68351f7ff 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -25,7 +25,6 @@ import ( "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" ) // ChainHeaderReader defines a small collection of methods needed to access the local @@ -109,9 +108,6 @@ type Engine interface { // that a new block should have. CalcDifficulty(chain ChainHeaderReader, time uint64, parent *types.Header) *big.Int - // APIs returns the RPC APIs this consensus engine provides. - APIs(chain ChainHeaderReader) []rpc.API - // Close terminates any background threads maintained by the consensus engine. Close() error } diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index f37ec26056..f624f73875 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -22,7 +22,6 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rpc" ) // Ethash is a consensus engine based on proof-of-work implementing the ethash @@ -71,12 +70,6 @@ func (ethash *Ethash) Close() error { return nil } -// APIs implements consensus.Engine, returning no APIs as ethash is an empty -// shell in the post-merge world. -func (ethash *Ethash) APIs(chain consensus.ChainHeaderReader) []rpc.API { - return []rpc.API{} -} - // Seal generates a new sealing request for the given input block and pushes // the result into the given channel. For the ethash engine, this method will // just panic as sealing is not supported anymore. diff --git a/eth/backend.go b/eth/backend.go index 6d1b6bae99..15243ad5c9 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -337,9 +337,6 @@ func makeExtraData(extra []byte) []byte { func (s *Ethereum) APIs() []rpc.API { apis := ethapi.GetAPIs(s.APIBackend) - // Append any APIs exposed explicitly by the consensus engine - apis = append(apis, s.engine.APIs(s.BlockChain())...) - // Append all the local APIs and return return append(apis, []rpc.API{ { From 94481d13513f94ef4a76ef847e7c3d436fde2546 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 23 May 2025 12:33:43 +0200 Subject: [PATCH 390/940] .gitea: add initial workflow file (#31885) --- .gitea/workflows/release.yml | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .gitea/workflows/release.yml diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000000..fa7b7f25ab --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,38 @@ +name: Release Builds + +on: + push: + branches: [ master ] + +jobs: + docker: + name: Docker Image + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.23.0 + cache: false + + - name: Run docker build + run: | + go run build/ci.go docker -platform linux/amd64,linux/arm64 + + linux: + name: Docker Image + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.23.0 + cache: false + + - name: Run build + run: | + go run build/ci.go install From 8f598e85ade64653b6490b8ca742a51274ec328a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 23 May 2025 12:44:30 +0200 Subject: [PATCH 391/940] .gitea: update release build actions (#31886) Trying to make the docker build work. --- .gitea/workflows/release.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index fa7b7f25ab..4a169127ea 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -11,18 +11,24 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.0 + go-version: 1.24 cache: false - name: Run docker build run: | - go run build/ci.go docker -platform linux/amd64,linux/arm64 + go run build/ci.go dockerx -platform linux/amd64,linux/arm64,linux/riscv64 linux: - name: Docker Image + name: Linux Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -30,7 +36,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.0 + go-version: 1.24 cache: false - name: Run build From 8781e93013d286538a8848b695f2b1e102f4af6a Mon Sep 17 00:00:00 2001 From: buddho Date: Fri, 23 May 2025 19:10:10 +0800 Subject: [PATCH 392/940] core/state: fix copy of storageChange (#31874) Missing field origvalue when copying storageChange. --- core/state/journal.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/state/journal.go b/core/state/journal.go index 13332dbd79..f3f976f24f 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -408,6 +408,7 @@ func (ch storageChange) copy() journalEntry { account: ch.account, key: ch.key, prevvalue: ch.prevvalue, + origvalue: ch.origvalue, } } From b97198379b824d8e331d9e024afead4fe03cc50a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 23 May 2025 16:21:08 +0200 Subject: [PATCH 393/940] .gitea: add cron build script (#31890) Also swaps the push build scripts and adds environment output. --- .gitea/workflows/release-cron.yml | 42 +++++++++++++++++++++++++++++++ .gitea/workflows/release.yml | 38 +++++++++++++++------------- 2 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 .gitea/workflows/release-cron.yml diff --git a/.gitea/workflows/release-cron.yml b/.gitea/workflows/release-cron.yml new file mode 100644 index 0000000000..3a03d0ef14 --- /dev/null +++ b/.gitea/workflows/release-cron.yml @@ -0,0 +1,42 @@ +name: Release Builds (cron) + +on: + schedule: + cron: '0 0 * * *' + +jobs: + azure-cleanup: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.24 + cache: false + + - name: Run cleanup script + run: | + go run build/ci.go purge -store gethstore/builds -days 14 + + ppa: + name: PPA Upload (master) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.24 + cache: false + + - name: Install deb toolchain + run: | + apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot + + - name: Run ci.go + run: | + 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 " diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 4a169127ea..a91bebda7f 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -1,10 +1,30 @@ -name: Release Builds +name: Release Builds (push) on: push: branches: [ master ] jobs: + linux: + name: Linux Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.24 + cache: false + + - name: display environment + run: | + env + + - name: Run build + run: | + go run build/ci.go install + docker: name: Docker Image runs-on: ubuntu-latest @@ -26,19 +46,3 @@ jobs: - name: Run docker build run: | go run build/ci.go dockerx -platform linux/amd64,linux/arm64,linux/riscv64 - - linux: - name: Linux Build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: 1.24 - cache: false - - - name: Run build - run: | - go run build/ci.go install From f14813fea99f69d5ff11a6e0c96aebd44a2fc288 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 23 May 2025 17:48:15 +0200 Subject: [PATCH 394/940] internal/build: add support for Github Actions CI environment (#31891) This adds support for the Github actions environment in the build tool. Information from environment variables, like the build number and branch/tag name, is used to make decisions about uploads and package filenames. --- internal/build/env.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/internal/build/env.go b/internal/build/env.go index 35b2cd6ae7..23501d0ece 100644 --- a/internal/build/env.go +++ b/internal/build/env.go @@ -92,6 +92,33 @@ func Env() Environment { IsPullRequest: os.Getenv("APPVEYOR_PULL_REQUEST_NUMBER") != "", IsCronJob: os.Getenv("APPVEYOR_SCHEDULED_BUILD") == "True", } + case os.Getenv("CI") == "true" && os.Getenv("GITHUB_ACTIONS") == "true": + commit := os.Getenv("GITHUB_SHA") + reftype := os.Getenv("GITHUB_REF_TYPE") + isPR := os.Getenv("GITHUB_HEAD_REF") != "" + tag := "" + branch := "" + switch { + case isPR: + branch = os.Getenv("GITHUB_BASE_REF") + case reftype == "branch": + branch = os.Getenv("GITHUB_REF_NAME") + case reftype == "tag": + tag = os.Getenv("GITHUB_REF_NAME") + } + return Environment{ + CI: true, + Name: "github-actions", + Repo: os.Getenv("GITHUB_REPOSITORY"), + Commit: commit, + Date: getDate(commit), + Branch: branch, + Tag: tag, + IsPullRequest: isPR, + Buildnum: os.Getenv("GITHUB_RUN_ID"), + IsCronJob: os.Getenv("GITHUB_EVENT_NAME") == "schedule", + } + default: return LocalEnv() } From 9fd3f8a0dd0a82514bf0ab5ed65dbdcf48c5e155 Mon Sep 17 00:00:00 2001 From: Marcel <153717436+MonkeyMarcel@users.noreply.github.com> Date: Fri, 23 May 2025 23:50:25 +0800 Subject: [PATCH 395/940] core: remove unused queued import status (#31870) --- core/blockchain_insert.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/core/blockchain_insert.go b/core/blockchain_insert.go index 695aa6679b..d7c2696f08 100644 --- a/core/blockchain_insert.go +++ b/core/blockchain_insert.go @@ -27,10 +27,10 @@ import ( // insertStats tracks and reports on block insertion. type insertStats struct { - queued, processed, ignored int - usedGas uint64 - lastIndex int - startTime mclock.AbsTime + processed, ignored int + usedGas uint64 + lastIndex int + startTime mclock.AbsTime } // statsReportLimit is the time limit during import and export after which we @@ -78,9 +78,6 @@ func (st *insertStats) report(chain []*types.Block, index int, snapDiffItems, sn } context = append(context, []interface{}{"triedirty", triebufNodes}...) - if st.queued > 0 { - context = append(context, []interface{}{"queued", st.queued}...) - } if st.ignored > 0 { context = append(context, []interface{}{"ignored", st.ignored}...) } From 3f7b8bc976fe5e9b810b91da359b3e0cb7d010c8 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Mon, 26 May 2025 10:45:41 +0200 Subject: [PATCH 396/940] core/vm: fix bls benchmark (#31896) Fixes #31893 --- core/vm/contracts_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index b627f2ada5..537d787757 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -370,7 +370,7 @@ func BenchmarkPrecompiledBLS12381G1MultiExpWorstCase(b *testing.B) { Name: "WorstCaseG1", NoBenchmark: false, } - benchmarkPrecompiled("f0c", testcase, b) + benchmarkPrecompiled("f0b", testcase, b) } // BenchmarkPrecompiledBLS12381G2MultiExpWorstCase benchmarks the worst case we could find that still fits a gaslimit of 10MGas. @@ -391,5 +391,5 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) { Name: "WorstCaseG2", NoBenchmark: false, } - benchmarkPrecompiled("f0f", testcase, b) + benchmarkPrecompiled("f0d", testcase, b) } From 8b9f2d4e36dfcdb2af94dc0d3b63f30c8ad159a9 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Wed, 28 May 2025 19:31:42 +0800 Subject: [PATCH 397/940] triedb/pathdb: introduce lookup structure to optimize state access (#30971) This pull request introduces a mechanism to improve state lookup efficiency in pathdb by maintaining a lookup structure that eliminates unnecessary iteration over diff layers. The core idea is to track a mutation history for each dirty state entry residing in the diff layers. This history records the state roots of all layers in which the entry was modified, sorted from oldest to newest. During state lookup, this mutation history is queried to find the most recent layer whose state root either matches the target root or is a descendant of it. This allows us to quickly identify the layer containing the relevant data, avoiding the need to iterate through all diff layers from top to bottom. Besides, the overhead for state lookup is constant, no matter how many diff layers are retained in the pathdb, which unlocks the potential to hold more diff layers. Of course, maintaining this lookup structure introduces some overhead. For each state transition, we need to: (a) update the mutation records for the modified state entries, and (b) remove stale mutation records associated with outdated layers. On our benchmark machine, it will introduce around 1ms overhead which is acceptable. --- triedb/pathdb/database.go | 4 +- triedb/pathdb/difflayer.go | 4 +- triedb/pathdb/disklayer.go | 9 - triedb/pathdb/layertree.go | 199 +++++-- triedb/pathdb/layertree_test.go | 885 ++++++++++++++++++++++++++++++++ triedb/pathdb/lookup.go | 278 ++++++++++ triedb/pathdb/metrics.go | 3 + triedb/pathdb/reader.go | 56 +- 8 files changed, 1385 insertions(+), 53 deletions(-) create mode 100644 triedb/pathdb/layertree_test.go create mode 100644 triedb/pathdb/lookup.go diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index c206460315..3174a7c964 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -487,7 +487,7 @@ func (db *Database) Enable(root common.Hash) error { // Re-construct a new disk layer backed by persistent state // and schedule the state snapshot generation if it's permitted. - db.tree.reset(generateSnapshot(db, root, db.isVerkle || db.config.SnapshotNoBuild)) + db.tree.init(generateSnapshot(db, root, db.isVerkle || db.config.SnapshotNoBuild)) log.Info("Rebuilt trie database", "root", root) return nil } @@ -529,7 +529,7 @@ func (db *Database) Recover(root common.Hash) error { // reset layer with newly created disk layer. It must be // done after each revert operation, otherwise the new // disk layer won't be accessible from outside. - db.tree.reset(dl) + db.tree.init(dl) } rawdb.DeleteTrieJournal(db.diskdb) diff --git a/triedb/pathdb/difflayer.go b/triedb/pathdb/difflayer.go index 2e1d83c74a..ac05b4a0fb 100644 --- a/triedb/pathdb/difflayer.go +++ b/triedb/pathdb/difflayer.go @@ -156,7 +156,7 @@ func (dl *diffLayer) update(root common.Hash, id uint64, block uint64, nodes *no } // persist flushes the diff layer and all its parent layers to disk layer. -func (dl *diffLayer) persist(force bool) (layer, error) { +func (dl *diffLayer) persist(force bool) (*diskLayer, error) { if parent, ok := dl.parentLayer().(*diffLayer); ok { // Hold the lock to prevent any read operation until the new // parent is linked correctly. @@ -183,7 +183,7 @@ func (dl *diffLayer) size() uint64 { // diffToDisk merges a bottom-most diff into the persistent disk layer underneath // it. The method will panic if called onto a non-bottom-most diff layer. -func diffToDisk(layer *diffLayer, force bool) (layer, error) { +func diffToDisk(layer *diffLayer, force bool) (*diskLayer, error) { disk, ok := layer.parentLayer().(*diskLayer) if !ok { panic(fmt.Sprintf("unknown layer type: %T", layer.parentLayer())) diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index bee4cd1e8a..1c9efb024b 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -94,15 +94,6 @@ func (dl *diskLayer) setGenerator(generator *generator) { dl.generator = generator } -// isStale return whether this layer has become stale (was flattened across) or if -// it's still live. -func (dl *diskLayer) isStale() bool { - dl.lock.RLock() - defer dl.lock.RUnlock() - - return dl.stale -} - // markStale sets the stale flag as true. func (dl *diskLayer) markStale() { dl.lock.Lock() diff --git a/triedb/pathdb/layertree.go b/triedb/pathdb/layertree.go index 85a5e470e7..b2f3f7f37d 100644 --- a/triedb/pathdb/layertree.go +++ b/triedb/pathdb/layertree.go @@ -31,29 +31,50 @@ import ( // thread-safe to use. However, callers need to ensure the thread-safety // of the referenced layer by themselves. type layerTree struct { - lock sync.RWMutex + base *diskLayer layers map[common.Hash]layer + + // descendants is a two-dimensional map where the keys represent + // an ancestor state root, and the values are the state roots of + // all its descendants. + // + // For example: r -> [c1, c2, ..., cn], where c1 through cn are + // the descendants of state r. + // + // This map includes all the existing diff layers and the disk layer. + descendants map[common.Hash]map[common.Hash]struct{} + lookup *lookup + lock sync.RWMutex } // newLayerTree constructs the layerTree with the given head layer. func newLayerTree(head layer) *layerTree { tree := new(layerTree) - tree.reset(head) + tree.init(head) return tree } -// reset initializes the layerTree by the given head layer. -// All the ancestors will be iterated out and linked in the tree. -func (tree *layerTree) reset(head layer) { +// init initializes the layerTree by the given head layer. +func (tree *layerTree) init(head layer) { tree.lock.Lock() defer tree.lock.Unlock() - var layers = make(map[common.Hash]layer) - for head != nil { - layers[head.rootHash()] = head - head = head.parentLayer() + current := head + tree.layers = make(map[common.Hash]layer) + tree.descendants = make(map[common.Hash]map[common.Hash]struct{}) + + for { + tree.layers[current.rootHash()] = current + tree.fillAncestors(current) + + parent := current.parentLayer() + if parent == nil { + break + } + current = parent } - tree.layers = layers + tree.base = current.(*diskLayer) // panic if it's not a disk layer + tree.lookup = newLookup(head, tree.isDescendant) } // get retrieves a layer belonging to the given state root. @@ -64,6 +85,43 @@ func (tree *layerTree) get(root common.Hash) layer { return tree.layers[root] } +// isDescendant returns whether the specified layer with given root is a +// descendant of a specific ancestor. +// +// This function assumes the read lock has been held. +func (tree *layerTree) isDescendant(root common.Hash, ancestor common.Hash) bool { + subset := tree.descendants[ancestor] + if subset == nil { + return false + } + _, ok := subset[root] + return ok +} + +// fillAncestors identifies the ancestors of the given layer and populates the +// descendants set. The ancestors include the diff layers below the supplied +// layer and also the disk layer. +// +// This function assumes the write lock has been held. +func (tree *layerTree) fillAncestors(layer layer) { + hash := layer.rootHash() + for { + parent := layer.parentLayer() + if parent == nil { + break + } + layer = parent + + phash := parent.rootHash() + subset := tree.descendants[phash] + if subset == nil { + subset = make(map[common.Hash]struct{}) + tree.descendants[phash] = subset + } + subset[hash] = struct{}{} + } +} + // forEach iterates the stored layers inside and applies the // given callback on them. func (tree *layerTree) forEach(onLayer func(layer)) { @@ -101,8 +159,16 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6 l := parent.update(root, parent.stateID()+1, block, newNodeSet(nodes.Flatten()), states) tree.lock.Lock() + defer tree.lock.Unlock() + + // Link the given layer into the layer set tree.layers[l.rootHash()] = l - tree.lock.Unlock() + + // Link the given layer into its ancestors (up to the current disk layer) + tree.fillAncestors(l) + + // Link the given layer into the state mutation history + tree.lookup.addLayer(l) return nil } @@ -127,8 +193,16 @@ func (tree *layerTree) cap(root common.Hash, layers int) error { if err != nil { return err } - // Replace the entire layer tree with the flat base - tree.layers = map[common.Hash]layer{base.rootHash(): base} + tree.base = base + + // Reset the layer tree with the single new disk layer + tree.layers = map[common.Hash]layer{ + base.rootHash(): base, + } + // Resets the descendants map, since there's only a single disk layer + // with no descendants. + tree.descendants = make(map[common.Hash]map[common.Hash]struct{}) + tree.lookup = newLookup(base, tree.isDescendant) return nil } // Dive until we run out of layers or reach the persistent database @@ -143,6 +217,11 @@ func (tree *layerTree) cap(root common.Hash, layers int) error { } // We're out of layers, flatten anything below, stopping if it's the disk or if // the memory limit is not yet exceeded. + var ( + err error + replaced layer + newBase *diskLayer + ) switch parent := diff.parentLayer().(type) { case *diskLayer: return nil @@ -152,14 +231,33 @@ func (tree *layerTree) cap(root common.Hash, layers int) error { // parent is linked correctly. diff.lock.Lock() - base, err := parent.persist(false) + // Hold the reference of the original layer being replaced + replaced = parent + + // Replace the original parent layer with new disk layer. The procedure + // can be illustrated as below: + // + // Before change: + // Chain: + // C1->C2->C3->C4 (HEAD) + // ->C2'->C3'->C4' + // + // After change: + // Chain: + // (a) C3->C4 (HEAD) + // (b) C1->C2 + // ->C2'->C3'->C4' + // The original C3 is replaced by the new base (with root C3) + // Dangling layers in (b) will be removed later + newBase, err = parent.persist(false) if err != nil { diff.lock.Unlock() return err } - tree.layers[base.rootHash()] = base - diff.parent = base + tree.layers[newBase.rootHash()] = newBase + // Link the new parent and release the lock + diff.parent = newBase diff.lock.Unlock() default: @@ -173,19 +271,28 @@ func (tree *layerTree) cap(root common.Hash, layers int) error { children[parent] = append(children[parent], root) } } + clearDiff := func(layer layer) { + diff, ok := layer.(*diffLayer) + if !ok { + return + } + tree.lookup.removeLayer(diff) + } var remove func(root common.Hash) remove = func(root common.Hash) { + clearDiff(tree.layers[root]) + + // Unlink the layer from the layer tree and cascade to its children + delete(tree.descendants, root) delete(tree.layers, root) for _, child := range children[root] { remove(child) } delete(children, root) } - for root, layer := range tree.layers { - if dl, ok := layer.(*diskLayer); ok && dl.isStale() { - remove(root) - } - } + remove(tree.base.rootHash()) // remove the old/stale disk layer + clearDiff(replaced) // remove the lookup data of the stale parent being replaced + tree.base = newBase // update the base layer with newly constructed one return nil } @@ -194,17 +301,41 @@ func (tree *layerTree) bottom() *diskLayer { tree.lock.RLock() defer tree.lock.RUnlock() - if len(tree.layers) == 0 { - return nil // Shouldn't happen, empty tree - } - // pick a random one as the entry point - var current layer - for _, layer := range tree.layers { - current = layer - break - } - for current.parentLayer() != nil { - current = current.parentLayer() - } - return current.(*diskLayer) + return tree.base +} + +// lookupAccount returns the layer that is guaranteed to contain the account data +// corresponding to the specified state root being queried. +func (tree *layerTree) lookupAccount(accountHash common.Hash, state common.Hash) (layer, error) { + // Hold the read lock to prevent the unexpected layer changes + tree.lock.RLock() + defer tree.lock.RUnlock() + + tip := tree.lookup.accountTip(accountHash, state, tree.base.root) + if tip == (common.Hash{}) { + return nil, fmt.Errorf("[%#x] %w", state, errSnapshotStale) + } + l := tree.layers[tip] + if l == nil { + return nil, fmt.Errorf("triedb layer [%#x] missing", tip) + } + return l, nil +} + +// lookupStorage returns the layer that is guaranteed to contain the storage slot +// data corresponding to the specified state root being queried. +func (tree *layerTree) lookupStorage(accountHash common.Hash, slotHash common.Hash, state common.Hash) (layer, error) { + // Hold the read lock to prevent the unexpected layer changes + tree.lock.RLock() + defer tree.lock.RUnlock() + + tip := tree.lookup.storageTip(accountHash, slotHash, state, tree.base.root) + if tip == (common.Hash{}) { + return nil, fmt.Errorf("[%#x] %w", state, errSnapshotStale) + } + l := tree.layers[tip] + if l == nil { + return nil, fmt.Errorf("triedb layer [%#x] missing", tip) + } + return l, nil } diff --git a/triedb/pathdb/layertree_test.go b/triedb/pathdb/layertree_test.go new file mode 100644 index 0000000000..a72ff5899e --- /dev/null +++ b/triedb/pathdb/layertree_test.go @@ -0,0 +1,885 @@ +// 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" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/trie/trienode" +) + +func newTestLayerTree() *layerTree { + db := New(rawdb.NewMemoryDatabase(), nil, false) + l := newDiskLayer(common.Hash{0x1}, 0, db, nil, nil, newBuffer(0, nil, nil, 0)) + t := newLayerTree(l) + return t +} + +func TestLayerCap(t *testing.T) { + var cases = []struct { + init func() *layerTree + head common.Hash + layers int + base common.Hash + snapshot map[common.Hash]struct{} + }{ + { + // Chain: + // C1->C2->C3->C4 (HEAD) + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + // Chain: + // C2->C3->C4 (HEAD) + head: common.Hash{0x4}, + layers: 2, + base: common.Hash{0x2}, + snapshot: map[common.Hash]struct{}{ + common.Hash{0x2}: {}, + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + // Chain: + // C3->C4 (HEAD) + head: common.Hash{0x4}, + layers: 1, + base: common.Hash{0x3}, + snapshot: map[common.Hash]struct{}{ + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + // Chain: + // C4 (HEAD) + head: common.Hash{0x4}, + layers: 0, + base: common.Hash{0x4}, + snapshot: map[common.Hash]struct{}{ + common.Hash{0x4}: {}, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + // ->C2'->C3'->C4' + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + // Chain: + // C2->C3->C4 (HEAD) + head: common.Hash{0x4a}, + layers: 2, + base: common.Hash{0x2a}, + snapshot: map[common.Hash]struct{}{ + common.Hash{0x4a}: {}, + common.Hash{0x3a}: {}, + common.Hash{0x2a}: {}, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + // ->C2'->C3'->C4' + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + // Chain: + // C3->C4 (HEAD) + head: common.Hash{0x4a}, + layers: 1, + base: common.Hash{0x3a}, + snapshot: map[common.Hash]struct{}{ + common.Hash{0x4a}: {}, + common.Hash{0x3a}: {}, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + // ->C3'->C4' + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + // Chain: + // C2->C3->C4 (HEAD) + // ->C3'->C4' + head: common.Hash{0x4a}, + layers: 2, + base: common.Hash{0x2}, + snapshot: map[common.Hash]struct{}{ + common.Hash{0x4a}: {}, + common.Hash{0x3a}: {}, + common.Hash{0x4b}: {}, + common.Hash{0x3b}: {}, + common.Hash{0x2}: {}, + }, + }, + } + for _, c := range cases { + tr := c.init() + if err := tr.cap(c.head, c.layers); err != nil { + t.Fatalf("Failed to cap the layer tree %v", err) + } + if tr.bottom().root != c.base { + t.Fatalf("Unexpected bottom layer tree root, want %v, got %v", c.base, tr.bottom().root) + } + if len(c.snapshot) != len(tr.layers) { + t.Fatalf("Unexpected layer tree size, want %v, got %v", len(c.snapshot), len(tr.layers)) + } + for h := range tr.layers { + if _, ok := c.snapshot[h]; !ok { + t.Fatalf("Unexpected layer %v", h) + } + } + } +} + +func TestBaseLayer(t *testing.T) { + tr := newTestLayerTree() + + var cases = []struct { + op func() + base common.Hash + }{ + // Chain: + // C1 (HEAD) + { + func() {}, + common.Hash{0x1}, + }, + // Chain: + // C1->C2->C3 (HEAD) + { + func() { + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + }, + common.Hash{0x1}, + }, + // Chain: + // C3 (HEAD) + { + func() { + tr.cap(common.Hash{0x3}, 0) + }, + common.Hash{0x3}, + }, + // Chain: + // C4->C5->C6 (HEAD) + { + func() { + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x5}, common.Hash{0x4}, 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x6}, common.Hash{0x5}, 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.cap(common.Hash{0x6}, 2) + }, + common.Hash{0x4}, + }, + } + for _, c := range cases { + c.op() + if tr.base.rootHash() != c.base { + t.Fatalf("Unexpected base root, want %v, got: %v", c.base, tr.base.rootHash()) + } + } +} + +func TestDescendant(t *testing.T) { + var cases = []struct { + init func() *layerTree + snapshotA map[common.Hash]map[common.Hash]struct{} + op func(tr *layerTree) + snapshotB map[common.Hash]map[common.Hash]struct{} + }{ + { + // Chain: + // C1->C2 (HEAD) + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + snapshotA: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x1}: { + common.Hash{0x2}: {}, + }, + }, + // Chain: + // C1->C2->C3 (HEAD) + op: func(tr *layerTree) { + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + }, + snapshotB: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x1}: { + common.Hash{0x2}: {}, + common.Hash{0x3}: {}, + }, + common.Hash{0x2}: { + common.Hash{0x3}: {}, + }, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + snapshotA: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x1}: { + common.Hash{0x2}: {}, + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + common.Hash{0x2}: { + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + common.Hash{0x3}: { + common.Hash{0x4}: {}, + }, + }, + // Chain: + // C2->C3->C4 (HEAD) + op: func(tr *layerTree) { + tr.cap(common.Hash{0x4}, 2) + }, + snapshotB: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x2}: { + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + common.Hash{0x3}: { + common.Hash{0x4}: {}, + }, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + snapshotA: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x1}: { + common.Hash{0x2}: {}, + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + common.Hash{0x2}: { + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + common.Hash{0x3}: { + common.Hash{0x4}: {}, + }, + }, + // Chain: + // C3->C4 (HEAD) + op: func(tr *layerTree) { + tr.cap(common.Hash{0x4}, 1) + }, + snapshotB: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x3}: { + common.Hash{0x4}: {}, + }, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + snapshotA: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x1}: { + common.Hash{0x2}: {}, + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + common.Hash{0x2}: { + common.Hash{0x3}: {}, + common.Hash{0x4}: {}, + }, + common.Hash{0x3}: { + common.Hash{0x4}: {}, + }, + }, + // Chain: + // C4 (HEAD) + op: func(tr *layerTree) { + tr.cap(common.Hash{0x4}, 0) + }, + snapshotB: map[common.Hash]map[common.Hash]struct{}{}, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + // ->C2'->C3'->C4' + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + snapshotA: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x1}: { + common.Hash{0x2a}: {}, + common.Hash{0x3a}: {}, + common.Hash{0x4a}: {}, + common.Hash{0x2b}: {}, + common.Hash{0x3b}: {}, + common.Hash{0x4b}: {}, + }, + common.Hash{0x2a}: { + common.Hash{0x3a}: {}, + common.Hash{0x4a}: {}, + }, + common.Hash{0x3a}: { + common.Hash{0x4a}: {}, + }, + common.Hash{0x2b}: { + common.Hash{0x3b}: {}, + common.Hash{0x4b}: {}, + }, + common.Hash{0x3b}: { + common.Hash{0x4b}: {}, + }, + }, + // Chain: + // C2->C3->C4 (HEAD) + op: func(tr *layerTree) { + tr.cap(common.Hash{0x4a}, 2) + }, + snapshotB: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x2a}: { + common.Hash{0x3a}: {}, + common.Hash{0x4a}: {}, + }, + common.Hash{0x3a}: { + common.Hash{0x4a}: {}, + }, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + // ->C2'->C3'->C4' + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + snapshotA: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x1}: { + common.Hash{0x2a}: {}, + common.Hash{0x3a}: {}, + common.Hash{0x4a}: {}, + common.Hash{0x2b}: {}, + common.Hash{0x3b}: {}, + common.Hash{0x4b}: {}, + }, + common.Hash{0x2a}: { + common.Hash{0x3a}: {}, + common.Hash{0x4a}: {}, + }, + common.Hash{0x3a}: { + common.Hash{0x4a}: {}, + }, + common.Hash{0x2b}: { + common.Hash{0x3b}: {}, + common.Hash{0x4b}: {}, + }, + common.Hash{0x3b}: { + common.Hash{0x4b}: {}, + }, + }, + // Chain: + // C3->C4 (HEAD) + op: func(tr *layerTree) { + tr.cap(common.Hash{0x4a}, 1) + }, + snapshotB: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x3a}: { + common.Hash{0x4a}: {}, + }, + }, + }, + { + // Chain: + // C1->C2->C3->C4 (HEAD) + // ->C3'->C4' + init: func() *layerTree { + tr := newTestLayerTree() + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return tr + }, + snapshotA: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x1}: { + common.Hash{0x2}: {}, + common.Hash{0x3a}: {}, + common.Hash{0x4a}: {}, + common.Hash{0x3b}: {}, + common.Hash{0x4b}: {}, + }, + common.Hash{0x2}: { + common.Hash{0x3a}: {}, + common.Hash{0x4a}: {}, + common.Hash{0x3b}: {}, + common.Hash{0x4b}: {}, + }, + common.Hash{0x3a}: { + common.Hash{0x4a}: {}, + }, + common.Hash{0x3b}: { + common.Hash{0x4b}: {}, + }, + }, + // Chain: + // C2->C3->C4 (HEAD) + // ->C3'->C4' + op: func(tr *layerTree) { + tr.cap(common.Hash{0x4a}, 2) + }, + snapshotB: map[common.Hash]map[common.Hash]struct{}{ + common.Hash{0x2}: { + common.Hash{0x3a}: {}, + common.Hash{0x4a}: {}, + common.Hash{0x3b}: {}, + common.Hash{0x4b}: {}, + }, + common.Hash{0x3a}: { + common.Hash{0x4a}: {}, + }, + common.Hash{0x3b}: { + common.Hash{0x4b}: {}, + }, + }, + }, + } + check := func(setA, setB map[common.Hash]map[common.Hash]struct{}) bool { + if len(setA) != len(setB) { + return false + } + for h, subA := range setA { + subB, ok := setB[h] + if !ok { + return false + } + if len(subA) != len(subB) { + return false + } + for hh := range subA { + if _, ok := subB[hh]; !ok { + return false + } + } + } + return true + } + for _, c := range cases { + tr := c.init() + if !check(c.snapshotA, tr.descendants) { + t.Fatalf("Unexpected descendants") + } + c.op(tr) + if !check(c.snapshotB, tr.descendants) { + t.Fatalf("Unexpected descendants") + } + } +} + +func TestAccountLookup(t *testing.T) { + // Chain: + // C1->C2->C3->C4 (HEAD) + tr := newTestLayerTree() // base = 0x1 + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xa"), nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xb"), nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xa", "0xc"), nil, nil, nil, false)) + + var cases = []struct { + account common.Hash + state common.Hash + expect common.Hash + }{ + { + // unknown account + common.HexToHash("0xd"), common.Hash{0x4}, common.Hash{0x1}, + }, + /* + lookup account from the top + */ + { + common.HexToHash("0xa"), common.Hash{0x4}, common.Hash{0x4}, + }, + { + common.HexToHash("0xb"), common.Hash{0x4}, common.Hash{0x3}, + }, + { + common.HexToHash("0xc"), common.Hash{0x4}, common.Hash{0x4}, + }, + /* + lookup account from the middle + */ + { + common.HexToHash("0xa"), common.Hash{0x3}, common.Hash{0x2}, + }, + { + common.HexToHash("0xb"), common.Hash{0x3}, common.Hash{0x3}, + }, + { + common.HexToHash("0xc"), common.Hash{0x3}, common.Hash{0x1}, // not found + }, + { + common.HexToHash("0xa"), common.Hash{0x2}, common.Hash{0x2}, + }, + { + common.HexToHash("0xb"), common.Hash{0x2}, common.Hash{0x1}, // not found + }, + { + common.HexToHash("0xc"), common.Hash{0x2}, common.Hash{0x1}, // not found + }, + /* + lookup account from the bottom + */ + { + common.HexToHash("0xa"), common.Hash{0x1}, common.Hash{0x1}, // not found + }, + { + common.HexToHash("0xb"), common.Hash{0x1}, common.Hash{0x1}, // not found + }, + { + common.HexToHash("0xc"), common.Hash{0x1}, common.Hash{0x1}, // not found + }, + } + for i, c := range cases { + l, err := tr.lookupAccount(c.account, c.state) + if err != nil { + t.Fatalf("%d: %v", i, err) + } + if l.rootHash() != c.expect { + t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash()) + } + } + + // Chain: + // C3->C4 (HEAD) + tr.cap(common.Hash{0x4}, 1) + + cases2 := []struct { + account common.Hash + state common.Hash + expect common.Hash + expectErr error + }{ + { + // unknown account + common.HexToHash("0xd"), common.Hash{0x4}, common.Hash{0x3}, nil, + }, + /* + lookup account from the top + */ + { + common.HexToHash("0xa"), common.Hash{0x4}, common.Hash{0x4}, nil, + }, + { + common.HexToHash("0xb"), common.Hash{0x4}, common.Hash{0x3}, nil, + }, + { + common.HexToHash("0xc"), common.Hash{0x4}, common.Hash{0x4}, nil, + }, + /* + lookup account from the bottom + */ + { + common.HexToHash("0xa"), common.Hash{0x3}, common.Hash{0x3}, nil, + }, + { + common.HexToHash("0xb"), common.Hash{0x3}, common.Hash{0x3}, nil, + }, + { + common.HexToHash("0xc"), common.Hash{0x3}, common.Hash{0x3}, nil, // not found + }, + /* + stale states + */ + { + common.HexToHash("0xa"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0xb"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0xc"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0xa"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0xb"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0xc"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, + }, + } + for i, c := range cases2 { + l, err := tr.lookupAccount(c.account, c.state) + if c.expectErr != nil { + if !errors.Is(err, c.expectErr) { + t.Fatalf("%d: unexpected error, want %v, got %v", i, c.expectErr, err) + } + } + if c.expectErr == nil { + if err != nil { + t.Fatalf("%d: %v", i, err) + } + if l.rootHash() != c.expect { + t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash()) + } + } + } +} + +func TestStorageLookup(t *testing.T) { + // Chain: + // C1->C2->C3->C4 (HEAD) + tr := newTestLayerTree() // base = 0x1 + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x1"}}, nil), nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x2"}}, nil), nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), + NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x1", "0x3"}}, nil), nil, nil, false)) + + var cases = []struct { + storage common.Hash + state common.Hash + expect common.Hash + }{ + { + // unknown storage slot + common.HexToHash("0x4"), common.Hash{0x4}, common.Hash{0x1}, + }, + /* + lookup storage slot from the top + */ + { + common.HexToHash("0x1"), common.Hash{0x4}, common.Hash{0x4}, + }, + { + common.HexToHash("0x2"), common.Hash{0x4}, common.Hash{0x3}, + }, + { + common.HexToHash("0x3"), common.Hash{0x4}, common.Hash{0x4}, + }, + /* + lookup storage slot from the middle + */ + { + common.HexToHash("0x1"), common.Hash{0x3}, common.Hash{0x2}, + }, + { + common.HexToHash("0x2"), common.Hash{0x3}, common.Hash{0x3}, + }, + { + common.HexToHash("0x3"), common.Hash{0x3}, common.Hash{0x1}, // not found + }, + { + common.HexToHash("0x1"), common.Hash{0x2}, common.Hash{0x2}, + }, + { + common.HexToHash("0x2"), common.Hash{0x2}, common.Hash{0x1}, // not found + }, + { + common.HexToHash("0x3"), common.Hash{0x2}, common.Hash{0x1}, // not found + }, + /* + lookup storage slot from the bottom + */ + { + common.HexToHash("0x1"), common.Hash{0x1}, common.Hash{0x1}, // not found + }, + { + common.HexToHash("0x2"), common.Hash{0x1}, common.Hash{0x1}, // not found + }, + { + common.HexToHash("0x3"), common.Hash{0x1}, common.Hash{0x1}, // not found + }, + } + for i, c := range cases { + l, err := tr.lookupStorage(common.HexToHash("0xa"), c.storage, c.state) + if err != nil { + t.Fatalf("%d: %v", i, err) + } + if l.rootHash() != c.expect { + t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash()) + } + } + + // Chain: + // C3->C4 (HEAD) + tr.cap(common.Hash{0x4}, 1) + + cases2 := []struct { + storage common.Hash + state common.Hash + expect common.Hash + expectErr error + }{ + { + // unknown storage slot + common.HexToHash("0x4"), common.Hash{0x4}, common.Hash{0x3}, nil, + }, + /* + lookup account from the top + */ + { + common.HexToHash("0x1"), common.Hash{0x4}, common.Hash{0x4}, nil, + }, + { + common.HexToHash("0x2"), common.Hash{0x4}, common.Hash{0x3}, nil, + }, + { + common.HexToHash("0x3"), common.Hash{0x4}, common.Hash{0x4}, nil, + }, + /* + lookup account from the bottom + */ + { + common.HexToHash("0x1"), common.Hash{0x3}, common.Hash{0x3}, nil, + }, + { + common.HexToHash("0x2"), common.Hash{0x3}, common.Hash{0x3}, nil, + }, + { + common.HexToHash("0x3"), common.Hash{0x3}, common.Hash{0x3}, nil, // not found + }, + /* + stale states + */ + { + common.HexToHash("0x1"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0x2"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0x3"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0x1"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0x2"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, + }, + { + common.HexToHash("0x3"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, + }, + } + for i, c := range cases2 { + l, err := tr.lookupStorage(common.HexToHash("0xa"), c.storage, c.state) + if c.expectErr != nil { + if !errors.Is(err, c.expectErr) { + t.Fatalf("%d: unexpected error, want %v, got %v", i, c.expectErr, err) + } + } + if c.expectErr == nil { + if err != nil { + t.Fatalf("%d: %v", i, err) + } + if l.rootHash() != c.expect { + t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash()) + } + } + } +} diff --git a/triedb/pathdb/lookup.go b/triedb/pathdb/lookup.go new file mode 100644 index 0000000000..8b092730f8 --- /dev/null +++ b/triedb/pathdb/lookup.go @@ -0,0 +1,278 @@ +// 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" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "golang.org/x/sync/errgroup" +) + +// storageKey returns a key for uniquely identifying the storage slot. +func storageKey(accountHash common.Hash, slotHash common.Hash) [64]byte { + var key [64]byte + copy(key[:32], accountHash[:]) + copy(key[32:], slotHash[:]) + return key +} + +// lookup is an internal structure used to efficiently determine the layer in +// which a state entry resides. +type lookup struct { + // accounts represents the mutation history for specific accounts. + // The key is the account address hash, and the value is a slice + // of **diff layer** IDs indicating where the account was modified, + // with the order from oldest to newest. + accounts map[common.Hash][]common.Hash + + // storages represents the mutation history for specific storage + // slot. The key is the account address hash and the storage key + // hash, the value is a slice of **diff layer** IDs indicating + // where the slot was modified, with the order from oldest to newest. + storages map[[64]byte][]common.Hash + + // descendant is the callback indicating whether the layer with + // given root is a descendant of the one specified by `ancestor`. + descendant func(state common.Hash, ancestor common.Hash) bool +} + +// newLookup initializes the lookup structure. +func newLookup(head layer, descendant func(state common.Hash, ancestor common.Hash) bool) *lookup { + var ( + current = head + layers []layer + ) + for current != nil { + layers = append(layers, current) + current = current.parentLayer() + } + l := &lookup{ + accounts: make(map[common.Hash][]common.Hash), + storages: make(map[[64]byte][]common.Hash), + descendant: descendant, + } + // Apply the diff layers from bottom to top + for i := len(layers) - 1; i >= 0; i-- { + switch diff := layers[i].(type) { + case *diskLayer: + continue + case *diffLayer: + l.addLayer(diff) + } + } + return l +} + +// accountTip traverses the layer list associated with the given account in +// reverse order to locate the first entry that either matches the specified +// stateID or is a descendant of it. +// +// If found, the account data corresponding to the supplied stateID resides +// in that layer. Otherwise, two scenarios are possible: +// +// (a) the account remains unmodified from the current disk layer up to the state +// layer specified by the stateID: fallback to the disk layer for data retrieval, +// (b) or the layer specified by the stateID is stale: reject the data retrieval. +func (l *lookup) accountTip(accountHash common.Hash, stateID common.Hash, base common.Hash) common.Hash { + // Traverse the mutation history from latest to oldest one. Several + // scenarios are possible: + // + // Chain: + // D->C1->C2->C3->C4 (HEAD) + // ->C1'->C2'->C3' + // State: + // x: [C1, C1', C3', C3] + // y: [] + // + // - (x, C4) => C3 + // - (x, C3) => C3 + // - (x, C2) => C1 + // - (x, C3') => C3' + // - (x, C2') => C1' + // - (y, C4) => D + // - (y, C3') => D + // - (y, C0) => null + list := l.accounts[accountHash] + for i := len(list) - 1; i >= 0; i-- { + // If the current state matches the stateID, or the requested state is a + // descendant of it, return the current state as the most recent one + // containing the modified data. Otherwise, the current state may be ahead + // of the requested one or belong to a different branch. + if list[i] == stateID || l.descendant(stateID, list[i]) { + return list[i] + } + } + // No layer matching the stateID or its descendants was found. Use the + // current disk layer as a fallback. + if base == stateID || l.descendant(stateID, base) { + return base + } + // The layer associated with 'stateID' is not the descendant of the current + // disk layer, it's already stale, return nothing. + return common.Hash{} +} + +// storageTip traverses the layer list associated with the given account and +// slot hash in reverse order to locate the first entry that either matches +// the specified stateID or is a descendant of it. +// +// If found, the storage data corresponding to the supplied stateID resides +// in that layer. Otherwise, two scenarios are possible: +// +// (a) the storage slot remains unmodified from the current disk layer up to +// the state layer specified by the stateID: fallback to the disk layer for +// data retrieval, (b) or the layer specified by the stateID is stale: reject +// the data retrieval. +func (l *lookup) storageTip(accountHash common.Hash, slotHash common.Hash, stateID common.Hash, base common.Hash) common.Hash { + list := l.storages[storageKey(accountHash, slotHash)] + for i := len(list) - 1; i >= 0; i-- { + // If the current state matches the stateID, or the requested state is a + // descendant of it, return the current state as the most recent one + // containing the modified data. Otherwise, the current state may be ahead + // of the requested one or belong to a different branch. + if list[i] == stateID || l.descendant(stateID, list[i]) { + return list[i] + } + } + // No layer matching the stateID or its descendants was found. Use the + // current disk layer as a fallback. + if base == stateID || l.descendant(stateID, base) { + return base + } + // The layer associated with 'stateID' is not the descendant of the current + // disk layer, it's already stale, return nothing. + return common.Hash{} +} + +// addLayer traverses the state data retained in the specified diff layer and +// integrates it into the lookup set. +// +// This function assumes that all layers older than the provided one have already +// been processed, ensuring that layers are processed strictly in a bottom-to-top +// order. +func (l *lookup) addLayer(diff *diffLayer) { + defer func(now time.Time) { + lookupAddLayerTimer.UpdateSince(now) + }(time.Now()) + + var ( + wg sync.WaitGroup + state = diff.rootHash() + ) + wg.Add(1) + go func() { + defer wg.Done() + for accountHash := range diff.states.accountData { + list, exists := l.accounts[accountHash] + if !exists { + list = make([]common.Hash, 0, 16) // TODO(rjl493456442) use sync pool + } + list = append(list, state) + l.accounts[accountHash] = list + } + }() + + wg.Add(1) + go func() { + defer wg.Done() + for accountHash, slots := range diff.states.storageData { + for slotHash := range slots { + key := storageKey(accountHash, slotHash) + list, exists := l.storages[key] + if !exists { + list = make([]common.Hash, 0, 16) // TODO(rjl493456442) use sync pool + } + list = append(list, state) + l.storages[key] = list + } + } + }() + wg.Wait() +} + +// removeFromList removes the specified element from the provided list. +// It returns a flag indicating whether the element was found and removed. +func removeFromList(list []common.Hash, element common.Hash) (bool, []common.Hash) { + // Traverse the list from oldest to newest to quickly locate the element. + for i := 0; i < len(list); i++ { + if list[i] == element { + if i != 0 { + list = append(list[:i], list[i+1:]...) + } else { + // Remove the first element by shifting the slice forward. + // Pros: zero-copy. + // Cons: may retain large backing array, causing memory leaks. + // Mitigation: release the array if capacity exceeds threshold. + list = list[1:] + if cap(list) > 1024 { + list = append(make([]common.Hash, 0, len(list)), list...) + } + } + return true, list + } + } + return false, nil +} + +// removeLayer traverses the state data retained in the specified diff layer and +// unlink them from the lookup set. +func (l *lookup) removeLayer(diff *diffLayer) error { + defer func(now time.Time) { + lookupRemoveLayerTimer.UpdateSince(now) + }(time.Now()) + + var ( + eg errgroup.Group + state = diff.rootHash() + ) + eg.Go(func() error { + for accountHash := range diff.states.accountData { + found, list := removeFromList(l.accounts[accountHash], state) + if !found { + return fmt.Errorf("account lookup is not found, %x, state: %x", accountHash, state) + } + if len(list) != 0 { + l.accounts[accountHash] = list + } else { + delete(l.accounts, accountHash) + } + } + return nil + }) + + eg.Go(func() error { + for accountHash, slots := range diff.states.storageData { + for slotHash := range slots { + key := storageKey(accountHash, slotHash) + found, list := removeFromList(l.storages[key], state) + if !found { + return fmt.Errorf("storage lookup is not found, %x %x, state: %x", accountHash, slotHash, state) + } + if len(list) != 0 { + l.storages[key] = list + } else { + delete(l.storages, key) + } + } + } + return nil + }) + return eg.Wait() +} diff --git a/triedb/pathdb/metrics.go b/triedb/pathdb/metrics.go index 502c34fc62..6d40c5713b 100644 --- a/triedb/pathdb/metrics.go +++ b/triedb/pathdb/metrics.go @@ -72,6 +72,9 @@ var ( historyBuildTimeMeter = metrics.NewRegisteredResettingTimer("pathdb/history/time", nil) historyDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/data", nil) historyIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/index", nil) + + lookupAddLayerTimer = metrics.NewRegisteredResettingTimer("pathdb/lookup/add/time", nil) + lookupRemoveLayerTimer = metrics.NewRegisteredResettingTimer("pathdb/lookup/remove/time", nil) ) // Metrics in generation diff --git a/triedb/pathdb/reader.go b/triedb/pathdb/reader.go index 30f75d1058..bc72db34e3 100644 --- a/triedb/pathdb/reader.go +++ b/triedb/pathdb/reader.go @@ -17,6 +17,7 @@ package pathdb import ( + "errors" "fmt" "github.com/ethereum/go-ethereum/common" @@ -50,8 +51,10 @@ func (loc *nodeLoc) string() string { // reader implements the database.NodeReader interface, providing the functionalities to // retrieve trie nodes by wrapping the internal state layer. type reader struct { - layer layer + db *Database + state common.Hash noHashCheck bool + layer layer } // Node implements database.NodeReader interface, retrieving the node with specified @@ -94,7 +97,23 @@ func (r *reader) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, // - the returned account data is not a copy, please don't modify it // - no error will be returned if the requested account is not found in database func (r *reader) AccountRLP(hash common.Hash) ([]byte, error) { - return r.layer.account(hash, 0) + l, err := r.db.tree.lookupAccount(hash, r.state) + if err != nil { + return nil, err + } + // If the located layer is stale, fall back to the slow path to retrieve + // the account data. This is an edge case where the located layer is the + // disk layer (e.g., the requested account was not changed in all the diff + // layers), and it becomes stale within a very short time window. + // + // This fallback mechanism is essential, because the traversal starts from + // the entry point layer and goes down, the staleness of the disk layer does + // not affect the result unless the entry point layer is also stale. + blob, err := l.account(hash, 0) + if errors.Is(err, errSnapshotStale) { + return r.layer.account(hash, 0) + } + return blob, err } // Account directly retrieves the account associated with a particular hash in @@ -105,7 +124,7 @@ func (r *reader) AccountRLP(hash common.Hash) ([]byte, error) { // - the returned account object is safe to modify // - no error will be returned if the requested account is not found in database func (r *reader) Account(hash common.Hash) (*types.SlimAccount, error) { - blob, err := r.layer.account(hash, 0) + blob, err := r.AccountRLP(hash) if err != nil { return nil, err } @@ -127,7 +146,23 @@ func (r *reader) Account(hash common.Hash) (*types.SlimAccount, error) { // - the returned storage data is not a copy, please don't modify it // - no error will be returned if the requested slot is not found in database func (r *reader) Storage(accountHash, storageHash common.Hash) ([]byte, error) { - return r.layer.storage(accountHash, storageHash, 0) + l, err := r.db.tree.lookupStorage(accountHash, storageHash, r.state) + if err != nil { + return nil, err + } + // If the located layer is stale, fall back to the slow path to retrieve + // the storage data. This is an edge case where the located layer is the + // disk layer (e.g., the requested account was not changed in all the diff + // layers), and it becomes stale within a very short time window. + // + // This fallback mechanism is essential, because the traversal starts from + // the entry point layer and goes down, the staleness of the disk layer does + // not affect the result unless the entry point layer is also stale. + blob, err := l.storage(accountHash, storageHash, 0) + if errors.Is(err, errSnapshotStale) { + return r.layer.storage(accountHash, storageHash, 0) + } + return blob, err } // NodeReader retrieves a layer belonging to the given state root. @@ -136,7 +171,12 @@ func (db *Database) NodeReader(root common.Hash) (database.NodeReader, error) { if layer == nil { return nil, fmt.Errorf("state %#x is not available", root) } - return &reader{layer: layer, noHashCheck: db.isVerkle}, nil + return &reader{ + db: db, + state: root, + noHashCheck: db.isVerkle, + layer: layer, + }, nil } // StateReader returns a reader that allows access to the state data associated @@ -146,5 +186,9 @@ func (db *Database) StateReader(root common.Hash) (database.StateReader, error) if layer == nil { return nil, fmt.Errorf("state %#x is not available", root) } - return &reader{layer: layer}, nil + return &reader{ + db: db, + state: root, + layer: layer, + }, nil } From 1695182b55f49df20bb3046a0bbc1ca2665f551d Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 28 May 2025 17:51:47 +0200 Subject: [PATCH 398/940] .gitea: adjust cron schedule (#31915) This should make the scheduled build actually run. --- .gitea/workflows/release-cron.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/release-cron.yml b/.gitea/workflows/release-cron.yml index 3a03d0ef14..11798630dd 100644 --- a/.gitea/workflows/release-cron.yml +++ b/.gitea/workflows/release-cron.yml @@ -2,7 +2,7 @@ name: Release Builds (cron) on: schedule: - cron: '0 0 * * *' + - cron: '0 16 * * *' jobs: azure-cleanup: From 0110b659c1db7612664e7fdfadbe005796992931 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 28 May 2025 18:24:43 +0200 Subject: [PATCH 399/940] .gitea: add env to scheduled builds (#31918) --- .gitea/workflows/release-cron.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitea/workflows/release-cron.yml b/.gitea/workflows/release-cron.yml index 11798630dd..383c9887d6 100644 --- a/.gitea/workflows/release-cron.yml +++ b/.gitea/workflows/release-cron.yml @@ -3,6 +3,7 @@ name: Release Builds (cron) on: schedule: - cron: '0 16 * * *' + workflow_dispatch: jobs: azure-cleanup: @@ -17,6 +18,8 @@ jobs: cache: false - name: Run cleanup script + env: + AZURE_BLOBSTORE_TOKEN: "{{ secrets.AZURE_BLOBSTORE_TOKEN }}" run: | go run build/ci.go purge -store gethstore/builds -days 14 @@ -37,6 +40,9 @@ jobs: apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot - name: Run ci.go + env: + DOCKER_HUB_USERNAME: "{{ secrets.DOCKER_HUB_USERNAME }}" + DOCKER_HUB_PASSWORD: "{{ secrets.DOCKER_HUB_PASSWORD }}" run: | 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 " From 25f6206137bcfd260a577396e34fa3e9bdafc85e Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 28 May 2025 19:01:33 +0200 Subject: [PATCH 400/940] .gitea: port more builds from travis and fix PPA env (#31919) --- .gitea/workflows/release-cron.yml | 4 +- .gitea/workflows/release.yml | 70 ++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/release-cron.yml b/.gitea/workflows/release-cron.yml index 383c9887d6..4f586f5284 100644 --- a/.gitea/workflows/release-cron.yml +++ b/.gitea/workflows/release-cron.yml @@ -41,8 +41,8 @@ jobs: - name: Run ci.go env: - DOCKER_HUB_USERNAME: "{{ secrets.DOCKER_HUB_USERNAME }}" - DOCKER_HUB_PASSWORD: "{{ secrets.DOCKER_HUB_PASSWORD }}" + PPA_SIGNING_KEY: "{{ secrets.PPA_SIGNING_KEY }}" + PPA_SSH_KEY: "{{ secrets.PPA_SSH_KEY }}" run: | 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 " diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index a91bebda7f..29154c6ef0 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -5,7 +5,7 @@ on: branches: [ master ] jobs: - linux: + linux-intel: name: Linux Build runs-on: ubuntu-latest steps: @@ -17,13 +17,68 @@ jobs: go-version: 1.24 cache: false - - name: display environment + - name: Run build (amd64) + env: + LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" run: | - env + go run build/ci.go install -arch amd64 -dlgo + go run build/ci.go archive -arch amd64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds - - name: Run build + - name: Run build (386) + env: + LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" run: | - go run build/ci.go install + apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib + go run build/ci.go install -arch 386 -dlgo + go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + + linux-arm: + name: Linux Build (arm) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.24 + cache: false + + - name: Set up cross toolchain + run: | + apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross + ln -s /usr/include/asm-generic /usr/include/asm + + - name: Run build (arm64) + env: + LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + run: | + go run build/ci.go install -dlgo -arch arm64 -cc arm-linux-gnueabi-gcc + go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + + - name: Run build (armv5) + env: + GOARM: "5" + LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + run: | + go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + + - name: Run build (armv6) + env: + GOARM: "6" + LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + run: | + go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + + - name: Run build (armv7) + env: + GOARM: "7" + LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + run: | + go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds docker: name: Docker Image @@ -44,5 +99,8 @@ jobs: cache: false - name: Run docker build + env: + DOCKER_HUB_USERNAME: "{{ secrets.DOCKER_HUB_USERNAME }}" + DOCKER_HUB_PASSWORD: "{{ secrets.DOCKER_HUB_PASSWORD }}" run: | - go run build/ci.go dockerx -platform linux/amd64,linux/arm64,linux/riscv64 + go run build/ci.go dockerx -platform linux/amd64,linux/arm64,linux/riscv64 -upload From e817a569fb9b84e252316a29ab491d7b76ce0ad8 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 28 May 2025 20:14:48 +0200 Subject: [PATCH 401/940] .gitea: fix secrets passing (#31920) --- .gitea/workflows/release-cron.yml | 6 +++--- .gitea/workflows/release.yml | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.gitea/workflows/release-cron.yml b/.gitea/workflows/release-cron.yml index 4f586f5284..735404129a 100644 --- a/.gitea/workflows/release-cron.yml +++ b/.gitea/workflows/release-cron.yml @@ -19,7 +19,7 @@ jobs: - name: Run cleanup script env: - AZURE_BLOBSTORE_TOKEN: "{{ secrets.AZURE_BLOBSTORE_TOKEN }}" + AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} run: | go run build/ci.go purge -store gethstore/builds -days 14 @@ -41,8 +41,8 @@ jobs: - name: Run ci.go env: - PPA_SIGNING_KEY: "{{ secrets.PPA_SIGNING_KEY }}" - PPA_SSH_KEY: "{{ secrets.PPA_SSH_KEY }}" + PPA_SIGNING_KEY: ${{ secrets.PPA_SIGNING_KEY }} + PPA_SSH_KEY: ${{ secrets.PPA_SSH_KEY }} run: | 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 " diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 29154c6ef0..7675c75e16 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -19,18 +19,18 @@ jobs: - name: Run build (amd64) env: - LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} run: | go run build/ci.go install -arch amd64 -dlgo - go run build/ci.go archive -arch amd64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + go run build/ci.go archive -arch amd64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - name: Run build (386) env: - LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} run: | apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib go run build/ci.go install -arch 386 -dlgo - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds linux-arm: name: Linux Build (arm) @@ -51,34 +51,34 @@ jobs: - name: Run build (arm64) env: - LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} run: | go run build/ci.go install -dlgo -arch arm64 -cc arm-linux-gnueabi-gcc - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - name: Run build (armv5) env: GOARM: "5" - LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} run: | go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - name: Run build (armv6) env: GOARM: "6" - LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} run: | go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - name: Run build (armv7) env: GOARM: "7" - LINUX_SIGNING_KEY: "{{ secrets.LINUX_SIGNING_KEY }}" + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} run: | go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds docker: name: Docker Image @@ -100,7 +100,7 @@ jobs: - name: Run docker build env: - DOCKER_HUB_USERNAME: "{{ secrets.DOCKER_HUB_USERNAME }}" - DOCKER_HUB_PASSWORD: "{{ secrets.DOCKER_HUB_PASSWORD }}" + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} run: | go run build/ci.go dockerx -platform linux/amd64,linux/arm64,linux/riscv64 -upload From 31d898d586b6388ce47c1965eae8f2c7114d194f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 28 May 2025 22:40:26 +0200 Subject: [PATCH 402/940] .gitea: fix apt update (#31921) --- .gitea/workflows/release-cron.yml | 1 + .gitea/workflows/release.yml | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/.gitea/workflows/release-cron.yml b/.gitea/workflows/release-cron.yml index 735404129a..1a8eea2890 100644 --- a/.gitea/workflows/release-cron.yml +++ b/.gitea/workflows/release-cron.yml @@ -37,6 +37,7 @@ jobs: - name: Install deb toolchain run: | + apt-get update apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot - name: Run ci.go diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 7675c75e16..8efd453642 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -17,20 +17,32 @@ jobs: go-version: 1.24 cache: false - - name: Run build (amd64) - env: - LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + - name: Install cross toolchain + run: | + apt-get update + apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib + + - name: Build (amd64) run: | go run build/ci.go install -arch amd64 -dlgo - go run build/ci.go archive -arch amd64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - name: Run build (386) + - name: Create archive (amd64) env: LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} run: | - apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib + go run build/ci.go archive -arch amd64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + rm -f build/bin/* + + - name: Build (386) + run: | go run build/ci.go install -arch 386 -dlgo + + - name: Create archive (386) + env: + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + run: | go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + rm -f build/bin/* linux-arm: name: Linux Build (arm) @@ -46,7 +58,8 @@ jobs: - name: Set up cross toolchain run: | - apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross + apt-get update + apt-get -yq --no-install-suggests --no-install-recommends install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross ln -s /usr/include/asm-generic /usr/include/asm - name: Run build (arm64) From b065aa6740e4ed109b5e3efd9abadb12b439870c Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 28 May 2025 22:57:58 +0200 Subject: [PATCH 403/940] .gitea: fix archive uploads and run PPA upload on release push (#31922) --- .gitea/workflows/release-azure-cleanup.yml | 22 ++++++ .../{release-cron.yml => release-ppa.yml} | 33 +++------ .gitea/workflows/release.yml | 71 +++++++++++++------ 3 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 .gitea/workflows/release-azure-cleanup.yml rename .gitea/workflows/{release-cron.yml => release-ppa.yml} (73%) diff --git a/.gitea/workflows/release-azure-cleanup.yml b/.gitea/workflows/release-azure-cleanup.yml new file mode 100644 index 0000000000..da2400ee26 --- /dev/null +++ b/.gitea/workflows/release-azure-cleanup.yml @@ -0,0 +1,22 @@ +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + azure-cleanup: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.24 + cache: false + + - name: Run cleanup script + run: | + go run build/ci.go purge -store gethstore/builds -days 14 + env: + AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} diff --git a/.gitea/workflows/release-cron.yml b/.gitea/workflows/release-ppa.yml similarity index 73% rename from .gitea/workflows/release-cron.yml rename to .gitea/workflows/release-ppa.yml index 1a8eea2890..23bffe773d 100644 --- a/.gitea/workflows/release-cron.yml +++ b/.gitea/workflows/release-ppa.yml @@ -1,30 +1,14 @@ -name: Release Builds (cron) - on: schedule: - cron: '0 16 * * *' + push: + branches: + - "release/*" workflow_dispatch: jobs: - azure-cleanup: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: 1.24 - cache: false - - - name: Run cleanup script - env: - AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} - run: | - go run build/ci.go purge -store gethstore/builds -days 14 - ppa: - name: PPA Upload (master) + name: PPA Upload runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -40,10 +24,13 @@ jobs: apt-get update apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot + - name: Add launchpad to known_hosts + run: | + echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts + - name: Run ci.go + run: | + go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder " env: PPA_SIGNING_KEY: ${{ secrets.PPA_SIGNING_KEY }} PPA_SSH_KEY: ${{ secrets.PPA_SSH_KEY }} - run: | - 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 " diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 8efd453642..10e0f7aa7f 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -1,8 +1,8 @@ -name: Release Builds (push) - on: push: - branches: [ master ] + branches: + - "master" + - "release/*" jobs: linux-intel: @@ -26,23 +26,25 @@ jobs: run: | go run build/ci.go install -arch amd64 -dlgo - - name: Create archive (amd64) - env: - LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + - name: Create/upload archive (amd64) run: | go run build/ci.go archive -arch amd64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds rm -f build/bin/* + env: + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} - name: Build (386) run: | go run build/ci.go install -arch 386 -dlgo - - name: Create archive (386) - env: - LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + - name: Create/upload archive (386) run: | go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds rm -f build/bin/* + env: + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} linux-arm: name: Linux Build (arm) @@ -56,42 +58,67 @@ jobs: go-version: 1.24 cache: false - - name: Set up cross toolchain + - name: Install cross toolchain run: | apt-get update apt-get -yq --no-install-suggests --no-install-recommends install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross ln -s /usr/include/asm-generic /usr/include/asm - - name: Run build (arm64) - env: - LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + - name: Build (arm64) run: | go run build/ci.go install -dlgo -arch arm64 -cc arm-linux-gnueabi-gcc - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - name: Run build (armv5) + - name: Create/upload archive (arm64) + run: | + go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + rm -fr build/bin/* + env: + LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} + + - name: Run build (arm5) + run: | + go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc + env: + GOARM: "5" + + - name: Create/upload archive (arm5) + run: | + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds env: GOARM: "5" LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} + + - name: Run build (arm6) run: | go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + env: + GOARM: "6" - - name: Run build (armv6) + - name: Create/upload archive (arm6) + run: | + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + rm -fr build/bin/* env: GOARM: "6" LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} + AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} + + - name: Run build (arm7) run: | go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + env: + GOARM: "7" - - name: Run build (armv7) + - name: Create/upload archive (arm7) + run: | + go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + rm -fr build/bin/* env: GOARM: "7" LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} - run: | - go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} docker: name: Docker Image From 3524499d558ce85b51d5e803154e01b9210b3913 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 28 May 2025 23:16:51 +0200 Subject: [PATCH 404/940] .gitea: fix arm64 build (#31923) --- .gitea/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 10e0f7aa7f..f1637bd5ae 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -66,7 +66,7 @@ jobs: - name: Build (arm64) run: | - go run build/ci.go install -dlgo -arch arm64 -cc arm-linux-gnueabi-gcc + go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc - name: Create/upload archive (arm64) run: | From e9e4e8b05ae99c8f4e22ae2e6db4f75ce5b848b6 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 28 May 2025 23:19:13 +0200 Subject: [PATCH 405/940] .gitea: run release build on tag push (#31924) --- .gitea/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index f1637bd5ae..04e724ccf4 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -2,7 +2,8 @@ on: push: branches: - "master" - - "release/*" + tags: + - "v*" jobs: linux-intel: From d821f7f297259b2ed5ab0d3c99c0e4aca9663ac8 Mon Sep 17 00:00:00 2001 From: Arya Nair Date: Thu, 29 May 2025 09:50:39 +0530 Subject: [PATCH 406/940] cmd/geth, cmd/utils: log prefunded account/key in ephemeral development mode (#31898) This PR modifies the disclaimer/banner that is printed when starting up Geth in dev mode: * if the client is spun up in ephemeral dev mode with a keystore override, the address of the first (prefunded) account is printed. * if the client is spun up in ephemeral mode without a keystore override, the genesis allocation contains a single static prefunded EOA account. It's address and private key are logged. * the banner is printed at the end of client initialization to make it more prominent. Previously, it was logged towards the beginning of client initialization and subsequent logging from startup filled the terminal, pushing it out of view of the user. Other change is that we now use a static prefunded dev account instead of generating a random one when instantiating a new dev mode chain. This is an example of what the banner looks like: ``` WARN [05-28|23:05:16.475] You are running Geth in --dev mode. Please note the following: WARN [05-28|23:05:16.475] WARN [05-28|23:05:16.475] 1. This mode is only intended for fast, iterative development without assumptions on WARN [05-28|23:05:16.475] security or persistence. WARN [05-28|23:05:16.475] 2. The database is created in memory unless specified otherwise. Therefore, shutting down WARN [05-28|23:05:16.475] your computer or losing power will wipe your entire block data and chain state for WARN [05-28|23:05:16.475] your dev environment. WARN [05-28|23:05:16.475] 3. A random, pre-allocated developer account will be available and unlocked as WARN [05-28|23:05:16.475] eth.coinbase, which can be used for testing. The random dev account is temporary, WARN [05-28|23:05:16.475] stored on a ramdisk, and will be lost if your machine is restarted. WARN [05-28|23:05:16.475] 4. Mining is enabled by default. However, the client will only seal blocks if transactions WARN [05-28|23:05:16.475] are pending in the mempool. The miner's minimum accepted gas price is 1. WARN [05-28|23:05:16.475] 5. Networking is disabled; there is no listen-address, the maximum number of peers is set WARN [05-28|23:05:16.475] to 0, and discovery is disabled. WARN [05-28|23:05:16.475] WARN [05-28|23:05:16.475] WARN [05-28|23:05:16.475] Running in ephemeral mode. The following account has been prefunded in the genesis: WARN [05-28|23:05:16.475] WARN [05-28|23:05:16.475] Account WARN [05-28|23:05:16.475] ------------------ WARN [05-28|23:05:16.475] 0x71562b71999873db5b286df957af199ec94617f7 (10^49 ETH) WARN [05-28|23:05:16.475] WARN [05-28|23:05:16.475] Private Key WARN [05-28|23:05:16.475] ------------------ WARN [05-28|23:05:16.475] 0xb71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291 WARN [05-28|23:05:16.475] ``` closes #31796 --------- Co-authored-by: jwasinger --- cmd/geth/config.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ cmd/geth/main.go | 18 ------------------ cmd/utils/flags.go | 20 +++++++++++++++----- 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 4215403234..3eb2b6dd37 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/catalyst" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/internal/flags" @@ -180,6 +181,45 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { return stack, cfg } +// constructs the disclaimer text block which will be printed in the logs upon +// startup when Geth is running in dev mode. +func constructDevModeBanner(ctx *cli.Context, cfg gethConfig) string { + devModeBanner := `You are running Geth in --dev mode. Please note the following: + + 1. This mode is only intended for fast, iterative development without assumptions on + security or persistence. + 2. The database is created in memory unless specified otherwise. Therefore, shutting down + your computer or losing power will wipe your entire block data and chain state for + your dev environment. + 3. A random, pre-allocated developer account will be available and unlocked as + eth.coinbase, which can be used for testing. The random dev account is temporary, + stored on a ramdisk, and will be lost if your machine is restarted. + 4. Mining is enabled by default. However, the client will only seal blocks if transactions + are pending in the mempool. The miner's minimum accepted gas price is 1. + 5. Networking is disabled; there is no listen-address, the maximum number of peers is set + to 0, and discovery is disabled. +` + if !ctx.IsSet(utils.DataDirFlag.Name) { + devModeBanner += fmt.Sprintf(` + + Running in ephemeral mode. The following account has been prefunded in the genesis: + + Account + ------------------ + 0x%x (10^49 ETH) +`, cfg.Eth.Miner.PendingFeeRecipient) + if cfg.Eth.Miner.PendingFeeRecipient == utils.DeveloperAddr { + devModeBanner += fmt.Sprintf(` + Private Key + ------------------ + 0x%x +`, crypto.FromECDSA(utils.DeveloperKey)) + } + } + + return devModeBanner +} + // makeFullNode loads geth configuration and creates the Ethereum backend. func makeFullNode(ctx *cli.Context) *node.Node { stack, cfg := makeConfigNode(ctx) @@ -239,6 +279,11 @@ func makeFullNode(ctx *cli.Context) *node.Node { } catalyst.RegisterSimulatedBeaconAPIs(stack, simBeacon) stack.RegisterLifecycle(simBeacon) + + banner := constructDevModeBanner(ctx, cfg) + for _, line := range strings.Split(banner, "\n") { + log.Warn(line) + } } else if ctx.IsSet(utils.BeaconApiFlag.Name) { // Start blsync mode. srv := rpc.NewServer() diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 733c9cf230..289af90828 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -294,24 +294,6 @@ func prepare(ctx *cli.Context) { case ctx.IsSet(utils.HoodiFlag.Name): log.Info("Starting Geth on Hoodi testnet...") - case ctx.IsSet(utils.DeveloperFlag.Name): - log.Info("Starting Geth in ephemeral dev mode...") - log.Warn(`You are running Geth in --dev mode. Please note the following: - - 1. This mode is only intended for fast, iterative development without assumptions on - security or persistence. - 2. The database is created in memory unless specified otherwise. Therefore, shutting down - your computer or losing power will wipe your entire block data and chain state for - your dev environment. - 3. A random, pre-allocated developer account will be available and unlocked as - eth.coinbase, which can be used for testing. The random dev account is temporary, - stored on a ramdisk, and will be lost if your machine is restarted. - 4. Mining is enabled by default. However, the client will only seal blocks if transactions - are pending in the mempool. The miner's minimum accepted gas price is 1. - 5. Networking is disabled; there is no listen-address, the maximum number of peers is set - to 0, and discovery is disabled. -`) - case !ctx.IsSet(utils.NetworkIdFlag.Name): log.Info("Starting Geth on Ethereum mainnet...") } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 81c4172a53..60a2cc13f1 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -984,6 +984,12 @@ var ( } ) +// default account to prefund when running Geth in dev mode +var ( + DeveloperKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + DeveloperAddr = crypto.PubkeyToAddress(DeveloperKey.PublicKey) +) + // MakeDataDir retrieves the currently requested data directory, terminating // if none (or the empty string) is specified. If the node is starting a testnet, // then a subdirectory of the specified datadir will be used. @@ -1769,9 +1775,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } else if accs := ks.Accounts(); len(accs) > 0 { developer = ks.Accounts()[0] } else { - developer, err = ks.NewAccount(passphrase) + developer, err = ks.ImportECDSA(DeveloperKey, passphrase) if err != nil { - Fatalf("Failed to create developer account: %v", err) + Fatalf("Failed to import developer account: %v", err) } } // Make sure the address is configured as fee recipient, otherwise @@ -1786,14 +1792,18 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } log.Info("Using developer account", "address", developer.Address) - // Create a new developer genesis block or reuse existing one + // configure default developer genesis which will be used unless a + // datadir is specified and a chain is preexisting at that location. cfg.Genesis = core.DeveloperGenesisBlock(ctx.Uint64(DeveloperGasLimitFlag.Name), &developer.Address) + + // If a datadir is specified, ensure that any preexisting chain in that location + // has a configuration that is compatible with dev mode: it must be merged at genesis. if ctx.IsSet(DataDirFlag.Name) { chaindb := tryMakeReadOnlyDatabase(ctx, stack) if rawdb.ReadCanonicalHash(chaindb, 0) != (common.Hash{}) { - cfg.Genesis = nil // fallback to db content + // signal fallback to preexisting chain on disk + cfg.Genesis = nil - //validate genesis has PoS enabled in block 0 genesis, err := core.ReadGenesis(chaindb) if err != nil { Fatalf("Could not read genesis from database: %v", err) From 8712a2cdbab8a6c23b6b7a6e379f35227490f011 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 29 May 2025 12:23:38 +0200 Subject: [PATCH 407/940] .travis.yml: remove master branch push builds (#31927) Release artefact building has been migrated to another system (Gitea), so we can finally stop using Travis CI. However, in order to have a fail-safe for the release, I'm leaving the config in and it will still trigger builds on Travis for tagged releases. That way, if our new system fails to work for the next release, we will still have the option of using Travis. --- .travis.yml | 65 +++++++++++++++-------------------------------------- 1 file changed, 18 insertions(+), 47 deletions(-) diff --git a/.travis.yml b/.travis.yml index 43f8ced19c..28d934c655 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ jobs: include: # This builder create and push the Docker images for all architectures - stage: build - if: type = push + if: type = push && tag ~= /^v[0-9]/ os: linux arch: amd64 dist: focal @@ -21,9 +21,25 @@ jobs: script: - go run build/ci.go dockerx -platform "linux/amd64,linux/arm64,linux/riscv64" -hub ethereum/client-go -upload + # This builder does the Ubuntu PPA nightly uploads + - stage: build + if: type = push && tag ~= /^v[0-9]/ + os: linux + dist: focal + go: 1.24.x + env: + - ubuntu-ppa + git: + submodules: false # avoid cloning ethereum/tests + 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 " + # This builder does the Linux Azure uploads - stage: build - if: type = push + if: type = push && tag ~= /^v[0-9]/ os: linux dist: focal sudo: required @@ -56,40 +72,6 @@ jobs: - go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds - # These builders run the tests - - stage: build - if: type = push - os: linux - arch: amd64 - dist: focal - go: 1.24.x - script: - - travis_wait 45 go run build/ci.go test $TEST_PACKAGES - - - stage: build - if: type = push - os: linux - dist: focal - go: 1.23.x - script: - - 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: focal - go: 1.24.x - env: - - ubuntu-ppa - git: - submodules: false # avoid cloning ethereum/tests - 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 " - # This builder does the Azure archive purges to avoid accumulating junk - stage: build if: type = cron @@ -102,14 +84,3 @@ jobs: submodules: false # avoid cloning ethereum/tests script: - go run build/ci.go purge -store gethstore/builds -days 14 - - # This builder executes race tests - - stage: build - if: type = cron - os: linux - dist: focal - go: 1.24.x - env: - - racetests - script: - - travis_wait 60 go run build/ci.go test -race $TEST_PACKAGES From 2a1784baef0e9d0c0641bc97d1a3478048de5c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Thu, 29 May 2025 13:26:50 +0300 Subject: [PATCH 408/940] go.mod: bump flock package version (#31909) The newer version has a stub implementation for unsupported targets, which allows us to compile to more exotic targets. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d27af647ec..6c192c85d7 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/fjl/gencodec v0.1.0 github.com/fsnotify/fsnotify v1.6.0 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff - github.com/gofrs/flock v0.8.1 + github.com/gofrs/flock v0.12.1 github.com/golang-jwt/jwt/v4 v4.5.1 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/google/gofuzz v1.2.0 diff --git a/go.sum b/go.sum index 200b3725ea..c91e349656 100644 --- a/go.sum +++ b/go.sum @@ -144,8 +144,8 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyL github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= -github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= From 99c0ed11547a0ac1a4527c390cd04da9b9214368 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 2 Jun 2025 13:00:58 +0200 Subject: [PATCH 409/940] .gitea: modify scheduled workflow times (#31946) --- .gitea/workflows/release-azure-cleanup.yml | 2 +- .gitea/workflows/release-ppa.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/release-azure-cleanup.yml b/.gitea/workflows/release-azure-cleanup.yml index da2400ee26..311b2196bb 100644 --- a/.gitea/workflows/release-azure-cleanup.yml +++ b/.gitea/workflows/release-azure-cleanup.yml @@ -1,6 +1,6 @@ on: schedule: - - cron: '0 0 * * *' + - cron: '0 14 * * *' workflow_dispatch: jobs: diff --git a/.gitea/workflows/release-ppa.yml b/.gitea/workflows/release-ppa.yml index 23bffe773d..6c0631dc99 100644 --- a/.gitea/workflows/release-ppa.yml +++ b/.gitea/workflows/release-ppa.yml @@ -1,6 +1,6 @@ on: schedule: - - cron: '0 16 * * *' + - cron: '0 15 * * *' push: branches: - "release/*" From c87b856c1a7daff56b46be70cdb7092adc519b7c Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 2 Jun 2025 16:11:19 +0200 Subject: [PATCH 410/940] eth: return null for not-found in BlockByNumberOrHash (#31949) This changes the API backend to return null for not-found blocks. This behavior is required by the RPC When `BlockByNumberOrHash` always returned an error for this case ever since being added in https://github.com/ethereum/go-ethereum/pull/19491. The backend method has a couple of call sites, and all of them handle a `nil` block result because `BlockByNumber` returns `nil` for not-found. The only case where this makes a real difference is for `eth_getBlockReceipts`, which was changed in #31361 to actually forward the error from `BlockByNumberOrHash` to the caller. --- eth/api_backend.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eth/api_backend.go b/eth/api_backend.go index 57f5a50837..8ec19308f9 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -196,7 +196,9 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r if hash, ok := blockNrOrHash.Hash(); ok { header := b.eth.blockchain.GetHeaderByHash(hash) if header == nil { - return nil, errors.New("header for hash not found") + // Return 'null' and no error if block is not found. + // This behavior is required by RPC spec. + return nil, nil } if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { return nil, errors.New("hash is not currently canonical") From a7d9b52eafd8242d6e015dea0903d78f717bf8b2 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Tue, 3 Jun 2025 10:47:38 +0200 Subject: [PATCH 411/940] core/rawdb: integrate eradb backend for RPC (#31604) This implements a backing store for chain history based on era1 files. The new store is integrated with the freezer. Queries for blocks and receipts below the current freezer tail are handled by the era store. --------- Co-authored-by: Gary Rong Co-authored-by: Felix Lange Co-authored-by: lightclient --- cmd/geth/chaincmd.go | 8 +- cmd/utils/flags.go | 19 +- cmd/utils/history_test.go | 2 +- common/lru/basiclru.go | 17 +- core/blockchain_repair_test.go | 8 +- core/blockchain_sethead_test.go | 2 +- core/blockchain_snapshot_test.go | 4 +- core/blockchain_test.go | 22 +- core/rawdb/accessors_chain_test.go | 8 +- core/rawdb/ancienttest/testsuite.go | 21 -- core/rawdb/chain_freezer.go | 110 +++++- core/rawdb/database.go | 51 ++- core/rawdb/eradb/eradb.go | 345 ++++++++++++++++++ core/rawdb/eradb/eradb_test.go | 103 ++++++ .../testdata/sepolia-00000-643a00f7.era1 | Bin 0 -> 3267454 bytes .../testdata/sepolia-00021-b8814b14.era1 | Bin 0 -> 3733097 bytes core/rawdb/freezer.go | 14 +- core/rawdb/freezer_memory.go | 19 - core/rawdb/freezer_resettable.go | 9 - core/rawdb/freezer_table.go | 6 - core/rawdb/freezer_test.go | 6 - core/rawdb/table.go | 6 - core/txindexer_test.go | 6 +- eth/backend.go | 9 +- eth/downloader/downloader_test.go | 2 +- eth/ethconfig/config.go | 1 + eth/ethconfig/gen_config.go | 6 + ethdb/database.go | 4 - ethdb/remotedb/remotedb.go | 7 - internal/era/era.go | 58 ++- internal/era/era_test.go | 25 +- node/database.go | 70 ++-- node/node.go | 75 ++-- triedb/pathdb/database_test.go | 2 +- 34 files changed, 774 insertions(+), 271 deletions(-) create mode 100644 core/rawdb/eradb/eradb.go create mode 100644 core/rawdb/eradb/eradb_test.go create mode 100644 core/rawdb/eradb/testdata/sepolia-00000-643a00f7.era1 create mode 100644 core/rawdb/eradb/testdata/sepolia-00021-b8814b14.era1 diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index dc071725c1..d8488b8268 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -45,6 +45,7 @@ import ( "github.com/ethereum/go-ethereum/internal/era/eradl" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/urfave/cli/v2" ) @@ -277,10 +278,7 @@ func initGenesis(ctx *cli.Context) error { overrides.OverrideVerkle = &v } - chaindb, err := stack.OpenDatabaseWithFreezer("chaindata", 0, 0, ctx.String(utils.AncientFlag.Name), "", false) - if err != nil { - utils.Fatalf("Failed to open database: %v", err) - } + chaindb := utils.MakeChainDatabase(ctx, stack, false) defer chaindb.Close() triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) @@ -317,7 +315,7 @@ func dumpGenesis(ctx *cli.Context) error { // dump whatever already exists in the datadir stack, _ := makeConfigNode(ctx) - db, err := stack.OpenDatabase("chaindata", 0, 0, "", true) + db, err := stack.OpenDatabaseWithOptions("chaindata", node.DatabaseOptions{ReadOnly: true}) if err != nil { return err } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 60a2cc13f1..debec7278d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -111,6 +111,11 @@ var ( Usage: "Root directory for ancient data (default = inside chaindata)", Category: flags.EthCategory, } + EraFlag = &flags.DirectoryFlag{ + Name: "datadir.era", + Usage: "Root directory for era1 history (default = inside ancient/chain)", + Category: flags.EthCategory, + } MinFreeDiskSpaceFlag = &flags.DirectoryFlag{ Name: "datadir.minfreedisk", Usage: "Minimum free disk space in MB, once reached triggers auto shut down (default = --cache.gc converted to MB, 0 = disabled)", @@ -977,6 +982,7 @@ var ( DatabaseFlags = []cli.Flag{ DataDirFlag, AncientFlag, + EraFlag, RemoteDBFlag, DBEngineFlag, StateSchemeFlag, @@ -1613,6 +1619,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.IsSet(AncientFlag.Name) { cfg.DatabaseFreezer = ctx.String(AncientFlag.Name) } + if ctx.IsSet(EraFlag.Name) { + cfg.DatabaseEra = ctx.String(EraFlag.Name) + } if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) @@ -2082,7 +2091,15 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb. } chainDb = remotedb.New(client) default: - chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "eth/db/chaindata/", readonly) + options := node.DatabaseOptions{ + ReadOnly: readonly, + Cache: cache, + Handles: handles, + AncientsDirectory: ctx.String(AncientFlag.Name), + MetricsNamespace: "eth/db/chaindata/", + EraDirectory: ctx.String(EraFlag.Name), + } + chainDb, err = stack.OpenDatabaseWithOptions("chaindata", options) } if err != nil { Fatalf("Could not open database: %v", err) diff --git a/cmd/utils/history_test.go b/cmd/utils/history_test.go index d3c6bda1c5..be51803f8c 100644 --- a/cmd/utils/history_test.go +++ b/cmd/utils/history_test.go @@ -158,7 +158,7 @@ func TestHistoryImportAndExport(t *testing.T) { } // Now import Era. - db2, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + db2, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) if err != nil { panic(err) } diff --git a/common/lru/basiclru.go b/common/lru/basiclru.go index 7386c77840..154831a796 100644 --- a/common/lru/basiclru.go +++ b/common/lru/basiclru.go @@ -47,30 +47,37 @@ func NewBasicLRU[K comparable, V any](capacity int) BasicLRU[K, V] { // Add adds a value to the cache. Returns true if an item was evicted to store the new item. func (c *BasicLRU[K, V]) Add(key K, value V) (evicted bool) { + _, _, evicted = c.Add3(key, value) + return evicted +} + +// Add3 adds a value to the cache. If an item was evicted to store the new one, it returns the evicted item. +func (c *BasicLRU[K, V]) Add3(key K, value V) (ek K, ev V, evicted bool) { item, ok := c.items[key] if ok { - // Already exists in cache. item.value = value c.items[key] = item c.list.moveToFront(item.elem) - return false + return ek, ev, false } var elem *listElem[K] if c.Len() >= c.cap { elem = c.list.removeLast() - delete(c.items, elem.v) evicted = true + ek = elem.v + ev = c.items[ek].value + delete(c.items, ek) } else { elem = new(listElem[K]) } // Store the new item. - // Note that, if another item was evicted, we re-use its list element here. + // Note that if another item was evicted, we re-use its list element here. elem.v = key c.items[key] = cacheItem[K, V]{elem, value} c.list.pushElem(elem) - return evicted + return ek, ev, evicted } // Contains reports whether the given key exists in the cache. diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index edc8854892..9661cee4c7 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -1769,7 +1769,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } - db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false) + db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient}) if err != nil { t.Fatalf("Failed to create persistent freezer database: %v", err) } @@ -1854,7 +1854,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s if err != nil { t.Fatalf("Failed to reopen persistent key-value database: %v", err) } - db, err = rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false) + db, err = rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient}) if err != nil { t.Fatalf("Failed to reopen persistent freezer database: %v", err) } @@ -1919,7 +1919,7 @@ func testIssue23496(t *testing.T, scheme string) { if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } - db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false) + db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient}) if err != nil { t.Fatalf("Failed to create persistent freezer database: %v", err) } @@ -1979,7 +1979,7 @@ func testIssue23496(t *testing.T, scheme string) { if err != nil { t.Fatalf("Failed to reopen persistent key-value database: %v", err) } - db, err = rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false) + db, err = rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient}) if err != nil { t.Fatalf("Failed to reopen persistent freezer database: %v", err) } diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index 51e2a5275f..b094ed3b65 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -1973,7 +1973,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } - db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false) + db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient}) if err != nil { t.Fatalf("Failed to create persistent freezer database: %v", err) } diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 23640fe843..e12a0c67c4 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -70,7 +70,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } - db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false) + db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient}) if err != nil { t.Fatalf("Failed to create persistent freezer database: %v", err) } @@ -265,7 +265,7 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) { if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } - newdb, err := rawdb.NewDatabaseWithFreezer(pdb, snaptest.ancient, "", false) + newdb, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: snaptest.ancient}) if err != nil { t.Fatalf("Failed to create persistent freezer database: %v", err) } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 434b494490..2401402f32 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -738,7 +738,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(), "", "", false) + ancientDb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -824,7 +824,7 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) { // makeDb creates a db instance for testing. makeDb := func() ethdb.Database { - db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + db, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -1623,7 +1623,7 @@ func testLargeReorgTrieGC(t *testing.T, scheme string) { 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(), "", "", false) + db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) defer db.Close() chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil) @@ -1689,7 +1689,7 @@ func testBlockchainRecovery(t *testing.T, scheme string) { _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil) // Import the chain as a ancient-first node and ensure all pointers are updated - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) + ancientDb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{Ancient: t.TempDir()}) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -1747,7 +1747,7 @@ func testLowDiffLongChain(t *testing.T, scheme string) { }) // Import the canonical chain - diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + diskdb, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) defer diskdb.Close() chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil) @@ -1959,7 +1959,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(), "", "", false) + chaindb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2122,7 +2122,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(), "", "", false) + chaindb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2496,7 +2496,7 @@ func testSideImportPrunedBlocks(t *testing.T, scheme string) { if err != nil { t.Fatalf("Failed to create persistent key-value database: %v", err) } - db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false) + db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient}) if err != nil { t.Fatalf("Failed to create persistent freezer database: %v", err) } @@ -3403,7 +3403,7 @@ func testSetCanonical(t *testing.T, scheme string) { } gen.AddTx(tx) }) - diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + diskdb, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) defer diskdb.Close() chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil) @@ -4199,7 +4199,7 @@ func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) { gen.SetCoinbase(common.Address{0: byte(0xb), 19: byte(i)}) }) - db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) defer db.Close() chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil) @@ -4315,7 +4315,7 @@ func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64, config := DefaultCacheConfigWithScheme(rawdb.PathScheme) config.ChainHistoryMode = history.KeepPostMerge - db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false) + db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) defer db.Close() chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), genesis, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil) defer chain.Stop() diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index d98fc9a1eb..862b8cd2fd 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -416,7 +416,7 @@ func checkReceiptsRLP(have, want types.Receipts) error { func TestAncientStorage(t *testing.T) { // Freezer style fast import the chain. frdir := t.TempDir() - db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false) + db, err := Open(NewMemoryDatabase(), OpenOptions{Ancient: frdir}) if err != nil { t.Fatalf("failed to create database with ancient backend") } @@ -469,7 +469,7 @@ func TestAncientStorage(t *testing.T) { } func TestWriteAncientHeaderChain(t *testing.T) { - db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), t.TempDir(), "", false) + db, err := Open(NewMemoryDatabase(), OpenOptions{Ancient: t.TempDir()}) if err != nil { t.Fatalf("failed to create database with ancient backend") } @@ -586,7 +586,7 @@ func TestHashesInRange(t *testing.T) { func BenchmarkWriteAncientBlocks(b *testing.B) { // Open freezer database. frdir := b.TempDir() - db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false) + db, err := Open(NewMemoryDatabase(), OpenOptions{Ancient: frdir}) if err != nil { b.Fatalf("failed to create database with ancient backend") } @@ -890,7 +890,7 @@ func TestHeadersRLPStorage(t *testing.T) { // Have N headers in the freezer frdir := t.TempDir() - db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false) + db, err := Open(NewMemoryDatabase(), OpenOptions{Ancient: frdir}) if err != nil { t.Fatalf("failed to create database with ancient backend") } diff --git a/core/rawdb/ancienttest/testsuite.go b/core/rawdb/ancienttest/testsuite.go index 70de263c04..e33e768947 100644 --- a/core/rawdb/ancienttest/testsuite.go +++ b/core/rawdb/ancienttest/testsuite.go @@ -77,13 +77,6 @@ func basicRead(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { } 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") @@ -93,13 +86,6 @@ func basicRead(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { // 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) @@ -110,13 +96,6 @@ func basicRead(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { } // 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") diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index cc7a62df32..3a5218c023 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -23,6 +23,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb/eradb" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -43,7 +44,10 @@ const ( // 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 { - ethdb.AncientStore // Ancient store for storing cold chain segment + ancients ethdb.AncientStore // Ancient store for storing cold chain segment + + // Optional Era database used as a backup for the pruned chain. + eradb *eradb.Store quit chan struct{} wg sync.WaitGroup @@ -56,23 +60,27 @@ type chainFreezer struct { // 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) (*chainFreezer, error) { - var ( - err error - freezer ethdb.AncientStore - ) +func newChainFreezer(datadir string, eraDir string, namespace string, readonly bool) (*chainFreezer, error) { if datadir == "" { - freezer = NewMemoryFreezer(readonly, chainFreezerTableConfigs) - } else { - freezer, err = NewFreezer(datadir, namespace, readonly, freezerTableSize, chainFreezerTableConfigs) + return &chainFreezer{ + ancients: NewMemoryFreezer(readonly, chainFreezerTableConfigs), + quit: make(chan struct{}), + trigger: make(chan chan struct{}), + }, nil } + freezer, err := NewFreezer(datadir, namespace, readonly, freezerTableSize, chainFreezerTableConfigs) + if err != nil { + return nil, err + } + edb, err := eradb.New(resolveChainEraDir(datadir, eraDir)) if err != nil { return nil, err } return &chainFreezer{ - AncientStore: freezer, - quit: make(chan struct{}), - trigger: make(chan chan struct{}), + ancients: freezer, + eradb: edb, + quit: make(chan struct{}), + trigger: make(chan chan struct{}), }, nil } @@ -84,7 +92,11 @@ func (f *chainFreezer) Close() error { close(f.quit) } f.wg.Wait() - return f.AncientStore.Close() + + if f.eradb != nil { + f.eradb.Close() + } + return f.ancients.Close() } // readHeadNumber returns the number of chain head block. 0 is returned if the @@ -334,3 +346,75 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash }) return hashes, err } + +// Ancient retrieves an ancient binary blob from the append-only immutable files. +func (f *chainFreezer) Ancient(kind string, number uint64) ([]byte, error) { + // Lookup the entry in the underlying ancient store, assuming that + // headers and hashes are always available. + if kind == ChainFreezerHeaderTable || kind == ChainFreezerHashTable { + return f.ancients.Ancient(kind, number) + } + tail, err := f.ancients.Tail() + if err != nil { + return nil, err + } + // Lookup the entry in the underlying ancient store if it's not pruned + if number >= tail { + return f.ancients.Ancient(kind, number) + } + // Lookup the entry in the optional era backend + if f.eradb == nil { + return nil, errOutOfBounds + } + switch kind { + case ChainFreezerBodiesTable: + return f.eradb.GetRawBody(number) + case ChainFreezerReceiptTable: + return f.eradb.GetRawReceipts(number) + } + return nil, errUnknownTable +} + +// ReadAncients executes an operation while preventing mutations to the freezer, +// i.e. if fn performs multiple reads, they will be consistent with each other. +func (f *chainFreezer) ReadAncients(fn func(ethdb.AncientReaderOp) error) (err error) { + if store, ok := f.ancients.(*Freezer); ok { + store.writeLock.Lock() + defer store.writeLock.Unlock() + } + return fn(f) +} + +// Methods below are just pass-through to the underlying ancient store. + +func (f *chainFreezer) Ancients() (uint64, error) { + return f.ancients.Ancients() +} + +func (f *chainFreezer) Tail() (uint64, error) { + return f.ancients.Tail() +} + +func (f *chainFreezer) AncientSize(kind string) (uint64, error) { + return f.ancients.AncientSize(kind) +} + +func (f *chainFreezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) { + return f.ancients.AncientRange(kind, start, count, maxBytes) +} + +func (f *chainFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (int64, error) { + return f.ancients.ModifyAncients(fn) +} + +func (f *chainFreezer) TruncateHead(items uint64) (uint64, error) { + return f.ancients.TruncateHead(items) +} + +func (f *chainFreezer) TruncateTail(items uint64) (uint64, error) { + return f.ancients.TruncateTail(items) +} + +func (f *chainFreezer) SyncAncient() error { + return f.ancients.SyncAncient() +} diff --git a/core/rawdb/database.go b/core/rawdb/database.go index a03dbafb1f..86f4ac19cb 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -86,11 +86,6 @@ type nofreezedb struct { ethdb.KeyValueStore } -// HasAncient returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) HasAncient(kind string, number uint64) (bool, error) { - return false, errNotSupported -} - // Ancient returns an error as we don't have a backing chain freezer. func (db *nofreezedb) Ancient(kind string, number uint64) ([]byte, error) { return nil, errNotSupported @@ -186,19 +181,49 @@ func resolveChainFreezerDir(ancient string) string { return freezer } -// NewDatabaseWithFreezer creates a high level database on top of a given key- -// value data store with a freezer moving immutable chain segments into cold -// storage. The passed ancient indicates the path of root ancient directory -// where the chain freezer can be opened. +// resolveChainEraDir is a helper function which resolves the absolute path of era database. +func resolveChainEraDir(chainFreezerDir string, era string) string { + switch { + case era == "": + return filepath.Join(chainFreezerDir, "era") + case !filepath.IsAbs(era): + return filepath.Join(chainFreezerDir, era) + default: + return era + } +} + +// NewDatabaseWithFreezer creates a high level database on top of a given key-value store. +// The passed ancient indicates the path of root ancient directory where the chain freezer +// can be opened. +// +// Deprecated: use Open. func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace string, readonly bool) (ethdb.Database, error) { + return Open(db, OpenOptions{ + Ancient: ancient, + MetricsNamespace: namespace, + ReadOnly: readonly, + }) +} + +// OpenOptions specifies options for opening the database. +type OpenOptions struct { + Ancient string // ancients directory + Era string // era files directory + MetricsNamespace string // prefix added to freezer metric names + ReadOnly bool +} + +// Open creates a high-level database wrapper for the given key-value store. +func Open(db ethdb.KeyValueStore, opts OpenOptions) (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 + chainFreezerDir := opts.Ancient if chainFreezerDir != "" { chainFreezerDir = resolveChainFreezerDir(chainFreezerDir) } - frdb, err := newChainFreezer(chainFreezerDir, namespace, readonly) + frdb, err := newChainFreezer(chainFreezerDir, opts.Era, opts.MetricsNamespace, opts.ReadOnly) if err != nil { printChainMetadata(db) return nil, err @@ -282,7 +307,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st } } // Freezer is consistent with the key-value database, permit combining the two - if !readonly { + if !opts.ReadOnly { frdb.wg.Add(1) go func() { frdb.freeze(db) @@ -290,7 +315,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st }() } return &freezerdb{ - ancientRoot: ancient, + ancientRoot: opts.Ancient, KeyValueStore: db, chainFreezer: frdb, }, nil diff --git a/core/rawdb/eradb/eradb.go b/core/rawdb/eradb/eradb.go new file mode 100644 index 0000000000..29e658798e --- /dev/null +++ b/core/rawdb/eradb/eradb.go @@ -0,0 +1,345 @@ +// Copyright 2025 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 eradb implements a history backend using era1 files. +package eradb + +import ( + "bytes" + "errors" + "fmt" + "io/fs" + "path/filepath" + "sync" + + "github.com/ethereum/go-ethereum/common/lru" + "github.com/ethereum/go-ethereum/internal/era" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" +) + +const openFileLimit = 64 + +var errClosed = errors.New("era store is closed") + +// Store manages read access to a directory of era1 files. +// The getter methods are thread-safe. +type Store struct { + datadir string + + // The mutex protects all remaining fields. + mu sync.Mutex + cond *sync.Cond + lru lru.BasicLRU[uint64, *fileCacheEntry] + opening map[uint64]*fileCacheEntry + closing bool +} + +type fileCacheEntry struct { + refcount int // reference count. This is protected by Store.mu! + opened chan struct{} // signals opening of file has completed + file *era.Era // the file + err error // error from opening the file +} + +type fileCacheStatus byte + +const ( + storeClosing fileCacheStatus = iota + fileIsNew + fileIsOpening + fileIsCached +) + +// New opens the store directory. +func New(datadir string) (*Store, error) { + db := &Store{ + datadir: datadir, + lru: lru.NewBasicLRU[uint64, *fileCacheEntry](openFileLimit), + opening: make(map[uint64]*fileCacheEntry), + } + db.cond = sync.NewCond(&db.mu) + log.Info("Opened Era store", "datadir", datadir) + return db, nil +} + +// Close closes all open era1 files in the cache. +func (db *Store) Close() { + db.mu.Lock() + defer db.mu.Unlock() + + // Prevent new cache additions. + db.closing = true + + // Deref all active files. Since inactive files have a refcount of one, they will be + // closed right here and now after decrementing. Files which are currently being used + // have a refcount > 1 and will hit zero when their access finishes. + for _, epoch := range db.lru.Keys() { + entry, _ := db.lru.Peek(epoch) + if entry.derefAndClose(epoch) { + db.lru.Remove(epoch) + } + } + + // Wait for all store access to finish. + for db.lru.Len() > 0 || len(db.opening) > 0 { + db.cond.Wait() + } +} + +// GetRawBody returns the raw body for a given block number. +func (db *Store) GetRawBody(number uint64) ([]byte, error) { + epoch := number / uint64(era.MaxEra1Size) + entry := db.getEraByEpoch(epoch) + if entry.err != nil { + if errors.Is(entry.err, fs.ErrNotExist) { + return nil, nil + } + return nil, entry.err + } + defer db.doneWithFile(epoch, entry) + + return entry.file.GetRawBodyByNumber(number) +} + +// GetRawReceipts returns the raw receipts for a given block number. +func (db *Store) GetRawReceipts(number uint64) ([]byte, error) { + epoch := number / uint64(era.MaxEra1Size) + entry := db.getEraByEpoch(epoch) + if entry.err != nil { + if errors.Is(entry.err, fs.ErrNotExist) { + return nil, nil + } + return nil, entry.err + } + defer db.doneWithFile(epoch, entry) + + data, err := entry.file.GetRawReceiptsByNumber(number) + if err != nil { + return nil, err + } + return convertReceipts(data) +} + +// convertReceipts transforms an encoded block receipts list from the format +// used by era1 into the 'storage' format used by the go-ethereum ancients database. +func convertReceipts(input []byte) ([]byte, error) { + var ( + out bytes.Buffer + enc = rlp.NewEncoderBuffer(&out) + ) + blockListIter, err := rlp.NewListIterator(input) + if err != nil { + return nil, fmt.Errorf("invalid block receipts list: %v", err) + } + outerList := enc.List() + for i := 0; blockListIter.Next(); i++ { + kind, content, _, err := rlp.Split(blockListIter.Value()) + if err != nil { + return nil, fmt.Errorf("receipt %d invalid: %v", i, err) + } + var receiptData []byte + switch kind { + case rlp.Byte: + return nil, fmt.Errorf("receipt %d is single byte", i) + case rlp.String: + // Typed receipt - skip type. + receiptData = content[1:] + case rlp.List: + // Legacy receipt + receiptData = blockListIter.Value() + } + // Convert data list. + // Input is [status, gas-used, bloom, logs] + // Output is [status, gas-used, logs], i.e. we need to skip the bloom. + dataIter, err := rlp.NewListIterator(receiptData) + if err != nil { + return nil, fmt.Errorf("receipt %d has invalid data: %v", i, err) + } + innerList := enc.List() + for field := 0; dataIter.Next(); field++ { + if field == 2 { + continue // skip bloom + } + enc.Write(dataIter.Value()) + } + enc.ListEnd(innerList) + if dataIter.Err() != nil { + return nil, fmt.Errorf("receipt %d iterator error: %v", i, dataIter.Err()) + } + } + enc.ListEnd(outerList) + if blockListIter.Err() != nil { + return nil, fmt.Errorf("block receipt list iterator error: %v", blockListIter.Err()) + } + enc.Flush() + return out.Bytes(), nil +} + +// getEraByEpoch opens an era file or gets it from the cache. +// The caller can freely access the returned entry's .file and .err +// db.doneWithFile must be called when it is done reading the file. +func (db *Store) getEraByEpoch(epoch uint64) *fileCacheEntry { + stat, entry := db.getCacheEntry(epoch) + + switch stat { + case storeClosing: + return &fileCacheEntry{err: errClosed} + + case fileIsNew: + // Open the file and put it into the cache. + e, err := db.openEraFile(epoch) + if err != nil { + db.fileFailedToOpen(epoch, entry, err) + } else { + db.fileOpened(epoch, entry, e) + } + close(entry.opened) + + case fileIsOpening: + // Wait for open to finish. + <-entry.opened + + case fileIsCached: + // Nothing to do. + + default: + panic(fmt.Sprintf("invalid file state %d", stat)) + } + return entry +} + +// getCacheEntry gets an open era file from the cache. +func (db *Store) getCacheEntry(epoch uint64) (stat fileCacheStatus, entry *fileCacheEntry) { + db.mu.Lock() + defer db.mu.Unlock() + + if db.closing { + return storeClosing, nil + } + if entry = db.opening[epoch]; entry != nil { + stat = fileIsOpening + } else if entry, _ = db.lru.Get(epoch); entry != nil { + stat = fileIsCached + } else { + // It's a new file, create an entry in the opening table. Note the entry is + // created with an initial refcount of one. We increment the count once more + // before returning, but the count will return to one when the file has been + // accessed. When the store is closed or the file gets evicted from the cache, + // refcount will be decreased by one, thus allowing it to hit zero. + entry = &fileCacheEntry{refcount: 1, opened: make(chan struct{})} + db.opening[epoch] = entry + stat = fileIsNew + } + entry.refcount++ + return stat, entry +} + +// fileOpened is called after an era file has been successfully opened. +func (db *Store) fileOpened(epoch uint64, entry *fileCacheEntry, file *era.Era) { + db.mu.Lock() + defer db.mu.Unlock() + + delete(db.opening, epoch) + db.cond.Signal() // db.opening was modified + + // The database may have been closed while opening the file. When that happens, we + // need to close the file here, since it isn't tracked by the LRU yet. + if db.closing { + entry.err = errClosed + file.Close() + return + } + + // Add it to the LRU. This may evict an existing item, which we have to close. + entry.file = file + evictedEpoch, evictedEntry, _ := db.lru.Add3(epoch, entry) + if evictedEntry != nil { + evictedEntry.derefAndClose(evictedEpoch) + } +} + +// fileFailedToOpen is called when an era file could not be opened. +func (db *Store) fileFailedToOpen(epoch uint64, entry *fileCacheEntry, err error) { + db.mu.Lock() + defer db.mu.Unlock() + + delete(db.opening, epoch) + db.cond.Signal() // db.opening was modified + entry.err = err +} + +func (db *Store) openEraFile(epoch uint64) (*era.Era, error) { + // File name scheme is --. + glob := fmt.Sprintf("*-%05d-*.era1", epoch) + matches, err := filepath.Glob(filepath.Join(db.datadir, glob)) + if err != nil { + return nil, err + } + if len(matches) > 1 { + return nil, fmt.Errorf("multiple era1 files found for epoch %d", epoch) + } + if len(matches) == 0 { + return nil, fs.ErrNotExist + } + filename := matches[0] + + e, err := era.Open(filename) + if err != nil { + return nil, err + } + // Sanity-check start block. + if e.Start()%uint64(era.MaxEra1Size) != 0 { + return nil, fmt.Errorf("pre-merge era1 file has invalid boundary. %d %% %d != 0", e.Start(), era.MaxEra1Size) + } + log.Debug("Opened era1 file", "epoch", epoch) + return e, nil +} + +// doneWithFile signals that the caller has finished using a file. +// This decrements the refcount and ensures the file is closed by the last user. +func (db *Store) doneWithFile(epoch uint64, entry *fileCacheEntry) { + db.mu.Lock() + defer db.mu.Unlock() + + if entry.err != nil { + return + } + if entry.derefAndClose(epoch) { + // Delete closed entry from LRU if it is still present. + if e, _ := db.lru.Peek(epoch); e == entry { + db.lru.Remove(epoch) + db.cond.Signal() // db.lru was modified + } + } +} + +// derefAndClose decrements the reference counter and closes the file +// when it hits zero. +func (entry *fileCacheEntry) derefAndClose(epoch uint64) (closed bool) { + entry.refcount-- + if entry.refcount > 0 { + return false + } + + closeErr := entry.file.Close() + if closeErr == nil { + log.Debug("Closed era1 file", "epoch", epoch) + } else { + log.Warn("Error closing era1 file", "epoch", epoch, "err", closeErr) + } + return true +} diff --git a/core/rawdb/eradb/eradb_test.go b/core/rawdb/eradb/eradb_test.go new file mode 100644 index 0000000000..41047dbbe9 --- /dev/null +++ b/core/rawdb/eradb/eradb_test.go @@ -0,0 +1,103 @@ +// Copyright 2025 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 eradb + +import ( + "sync" + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestEraDatabase(t *testing.T) { + db, err := New("testdata") + require.NoError(t, err) + defer db.Close() + + r, err := db.GetRawBody(175881) + require.NoError(t, err) + var body *types.Body + err = rlp.DecodeBytes(r, &body) + require.NoError(t, err) + require.NotNil(t, body, "block body not found") + assert.Equal(t, 3, len(body.Transactions)) + + r, err = db.GetRawReceipts(175881) + require.NoError(t, err) + var receipts []*types.ReceiptForStorage + err = rlp.DecodeBytes(r, &receipts) + require.NoError(t, err) + require.NotNil(t, receipts, "receipts not found") + assert.Equal(t, 3, len(receipts), "receipts length mismatch") +} + +func TestEraDatabaseConcurrentOpen(t *testing.T) { + db, err := New("testdata") + require.NoError(t, err) + defer db.Close() + + const N = 25 + var wg sync.WaitGroup + wg.Add(N) + for range N { + go func() { + defer wg.Done() + r, err := db.GetRawBody(1024) + if err != nil { + t.Error("err:", err) + } + if len(r) == 0 { + t.Error("empty body") + } + }() + } + wg.Wait() +} + +func TestEraDatabaseConcurrentOpenClose(t *testing.T) { + db, err := New("testdata") + require.NoError(t, err) + defer db.Close() + + const N = 10 + var wg sync.WaitGroup + wg.Add(N) + for range N { + go func() { + defer wg.Done() + r, err := db.GetRawBody(1024) + if err == errClosed { + return + } + if err != nil { + t.Error("err:", err) + } + if len(r) == 0 { + t.Error("empty body") + } + }() + } + wg.Add(1) + go func() { + defer wg.Done() + db.Close() + }() + wg.Wait() +} diff --git a/core/rawdb/eradb/testdata/sepolia-00000-643a00f7.era1 b/core/rawdb/eradb/testdata/sepolia-00000-643a00f7.era1 new file mode 100644 index 0000000000000000000000000000000000000000..a601a40c23b4f0030d15a4a19684aea0ddb61864 GIT binary patch literal 3267454 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%0Arwi(V1i0j85)F71PNS`TohfrJYD>zLuPp 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�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 z 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�GPWRO3V}J86 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�?3J+T7Tchu`-vK+Zdck8 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
    EXj1pd*pkeUP0gNEq2am=X)n7{+^Vu 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

    AuvRvo9O$WQ;n z${5d2o)f5-3@(i*a34y3hCTooS^`J@4r?IPUK;cxof-0b@M!$uc3nx!%c&2sN4FHU z?1aL7<^nzeWYELJb$x7`id?@sFg>cf!eZB7(@VAC?%*Lv)ua&>Q-=67q+vin{xAkI zFf>>AyC!RCO3g28vynGbz5Y85i)1Ny0wO(u2L@E($nlp9cC}V;Gelmm2EgzQJ5c{B z4eH|ibT`K2ygjMyR66=qkYkkd&5tx5Ww`JPQ`8QcvH)bb8={k(sGc4=Y&QqSZC?`W8Ln8454f?*+mb zD8NwkO`!)GBl%_|ie&yV%+tM(`CXPg!VlGXzldr^65;$gl+?@l;7$Xh0ZZn;m*_Eb ziYHeLUzoN^og*n2HihllRA{vd^JSpn_we7mWULR6%C{B!3@{BK=D-<-`OwA6kF-DP zkk3d5TAv+h$xZ~JZnk=8p&Ah)o}v6=)?N^dff5Ww?JW%AY0Z={FlT%4`0mnb%$}>X zdklkiK&<|3p{s? zE4kx^g;YYbi46ox0Wz@Yesnr;({1EW3ExJ|A=(QkH8)nhWo&2SUYDCBktBe4hMH#( zP%w;v3Je`2fA`4v`?PdrmH?812LqV-aUCNC%i=fElNHg=#&h|Xhf#q0owIIOJmxSROLi|rz`6bi&MG+$gZ34t+CgP~cu??j;j_1}{399Y?&RemG1 z#Azz+>VIm0OFJp9ZTF`{+w9T7%^;J|1AxJ1VSVz7fqPu}uJI3!M#4t)P1oJkPMbm60{|HakBrfY&5pN82IuYG)_e^?$`m2Q3874GefIf|4x0`H@eEx! z5Kt(Lfd&kX!5VXNPEI(_kDD}P0-Gk_OzGjK^M+O9pI4}$`P8vorokN}18xR&Q`D?~ zuML$0r8HLzDmn~$QRRzE zJoKi6#pOxZPfsM>W(h*+>>55jnq?BiGYnkJ=njK1(1M|loKEnv#U9FKzs0I)o&AE6 zK&9GSfJ4}~gOR@F_(kW>O;Fth_!%AwJOIG3fJN?q#o%8U+lDHwtzY5fH?5JJ|Nhwk zxB}HNPww{gl$7iwod-Y$&FQziGGnKKGlbHCGQtt*d(?uQYxixs4bO}{_&>a)LOjFR z#ZAy~7y}&`nrPwfa!cVlv&aqs(Y!Ix>Uw_t-i4M+qI z02t~GZSb!criGfXE#KoKwodN8yR-D`$x|5c#qy8ND?M#WTC zDHKCHN~&3$s#S8rS%&bELA}ffZieLTYyb>r-x9^H800=G+uTj=N>rsd!e#6kD{gkT z{4{u1njA7AjsM%&jsRd963q15nf;1C%>}D4>CvnHAi=$-P%9DQdp89we<0)ZKHzKdz_-*`7HXLoOM#klf*BAfA{8 zzz_`<{&B_dS%rpGnna0xcbcAMDbV|r;}Jxfv%mZ>s&ISywPt_=Kn9dIAvWAX`85ab zBUGWxk%rlv_BYk6FahG2; z4sFc-WWuRMI$`6wy7^~jhOR&SPgpJ6Z-4yv5^X_d{CBLC`OV4V5|j~YrTyv7)+3N+ zNE+|k{zx^$HSm!+4&y}&1x1(q;#8~Nn_TZwv$C!s&>+4PSyX@{!Nv#iQ_-PFnJ7*| zO=g*yh}6{qObHC>tpT?)ng>vC^zJ0Np_ijWea`O4kvD!#nkKbZAZ29UB7R2^>7V}& z@eI57AfRX%0}~i(PQZBm`Rw4=>&d@S_U3-=P4;v(7Uhp0;ZB8#B=235xlDt>L-;38 zCf6tcU@#lA*Skss{}OSGh?Q%R=!YgD#Ww=#b>@xo@r(4s!Qb8JdtS1%0A!$Ib44-d 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

    X}EWQWZdpyA=*F$-L8@iWsitB_jTy7;eVrt z4e^)|PJ_kkWdIB|YI=X$#qe7KWhZ`HO{#)*N<(@;FPL9OK>YR{fG&lu z6y~^>Y&I|M;Uy}+UB#)&IokgC=a^8H9`QFT<*go4|f`D}34C`QMLBw_USysF> z#TPquWhnv6M)5W`zQ}Ik$`SG35>~sv1^dD3HjDUeA6X%OgMTkdM5-#LS7}Hx_xsa< z>2C0yH1ER@(Waqt;(OPbUHnAB=kh#VgLfzZ79|IFYtfFPi)4dztu?F?)M9$Pj_kQ9 zx*5+&byk&OROD}}m#?^7?xqW8*tp!WH};`%Z&JhUPp!jZ=yr-d!4it}xAYRDp~q%m z4XvAcFop!ZM+m3k*Oos3hHJEwx2_mK#4I*=cgbQB`{GC|J{6^ZBG+%Rlq$$9S9hVe zOPXQ;$e?uh-g`z;`lK*!ixtbe8%mCEf6VkgbeM1)7UCq7t!qJk8X6TLAU!z4CK$RQ zl}*NKD)8mvP$+wnsYOX~d{`;$hbfOm**@9Dv!MTWb03OoAv+lJkcLd{GhPfi1o;eu4G@q4oMG$o zxq-8}97j>J!fAQ${J!Gn?@C_>%9JzII~=`4?!Dt0KY%g#X{aE~aH4DjfT5I^;O~yT z>SQ)-LZ$=sJyz`UKg;M% zndSsXXm4FWySb=}y6GnJ8Ky5MG8n=cwl9CM+I3nCc(*&+lV3jpZ|MNQu?;@ zw_WT*EnU5vFcr=j!!sQ(ukrRo{c8?8Bk`;;U!SG&Jdgp}nQ<0kC{wWz??zy*;Ky0x z>A@kPMd?@AShPg1?^K0`l7W1N?Hvfn2+ptzh9-XkH)_R2p@=urs6^t>DAV+Ou5GMH zZDQN0%4qzI@&?9Gus(`#8j|od0Wj#-Kk2_p!&Ink0*(9V1fhZrW)*$Y(e$f`E+S z40~YcM3Ro7fP*mk2h&c9jIn`e>bur5S&9{b(K&&>aV9qUr zWjv|?`%X}EY8-4HdTGmzdW0FOuk8Y05Lr#xzhZDvdO_zo=g6seB$!CjJz*FN@glA& zzLUNEqwcd&+;j-QG~5>Jr@kd0t~sCT6oSz_sYP6el|Z;UBChAnZl)K$)`5HmB5nxC z6wYt}h7RpYY;bfN|KTG+!SQ~6N13~sn`}~Gu&n+e?&w!_DiEwF*|$AKm|^9nn9;wV z4ME9xTUQK|h5=>b%_eX7*;Yp7DYiwKpfQ$3Vmj7cier_udi%Wq85#;WM3V+~PFq;R z4?OL<7P{t^Q@7VbT4LKMWU~3d0mx^d+Jb=0;0%XgC|>^~A8*!&x1V0q$;pcjw=e1_ zS`eMvetv7or#K)K^55c5Lj}Ya_>A3)0>Hq8hn9N9@Y)3@3RU>a{t5{y^Lj#=vq+)u zuXC*9I$=I7d4AkhpjQypW9+J=&9}h&d`%xsV*AwtmiU4u+-a|O#IMRQ>%@p7pMjwS z0y2j)9D$)!sr{}_~BhQEEXH zqk_i)c@l+dZQ72)UR`{Cdfs7i=c^L(88}@bAPYFd@#S2@`#Q!9O=8bKePFatlIy2V ziL~P|Y(M>4#>$2Ry3_U)#_$_gA7KV`e-7h+FG@Fk9RGfcmQMWoL{H%zgeM}Ln(aeb z8JdktNC+$SSV29=?{J?;7a)T^mYCKpwb5TI!d~WitFx8a%akG%wj(vD)AbK>j@?C& z&%iGN0a?NsPQcKHArrGIPc=Y7&3wd5M~gq zatFXLuC&E|m4<7)^0pgCIB|RyB0Zb;D~9^e#8>!lpq|{Me~U*$rX35A0o$a*!+Za3 zzjID-sib8{D2Ub4KiI*9SAqL8UFoW1}I{=1Gh>H6aLyoRaanZnwI*pTA$NT=& z^TW|emE7&OEp8dSs?{ldFba^tHK1SjB;$D~)%mLr@lcRP*T&JoOA+bBEd^PYsZ-5+ z$WMcGCj?{#XZQn#qN{kA9b_L0q=r6Tkq{0kHcna?G~Aczo{GhO_(g@j62|cSnjXRo z*CZ%R{=F!bTD76P4ldokNY z<~{ygv|J=Z6VHZnbcPdyfOgB3(~&smILjmc74jKWFK_$2gfpChp~jf~ksm*avWZa* zaCzOQ zY_M%s6IkeS{pwL4?~kTi8t<+A05lC|1##EVj2ffPxMQ2B@9{S_aTC5-Iwbc(`Oczv zp>z%T4Ep*IkTsm)91O+az;4CJW3n7vt)&-jwJ|VFlM}q za2if`ivck3)pMX)K{}bS5M>O;u7nz<|xllKy+ou?HYSL_l2< z5y3TKUhg3ZMH!Ej!uVTzW;dN)@3#`a`!TkTihKqORtU%j&Ts*SqLOX8@qN~==ezT} z<-1vYi>T6kVfNe29wDu-7M=85ng@P5-?pF-s|?Tro@$51*7Oe|X?y z{f1`a=<&o64)NQr&vRaw{fy8j`uHmV877%(w4(=F2i~~vD>w*sKaxFs*{$^&^V5Bc z-T0^cu3pGzu)n+sYWtVL2L%ijXQlj9F5ekCk+bbnNTRtzgm*o`Jfd(^h3frUwcFkv zEDc&kh+n#*>{bN8AYA;N`HF$#<+C!r=)rBXDuYjJq$~sM)M)ZQNu=3+(<-%Mh3}aF zWbiQ{j<~5lRoWpSdyDF4&I8LzMIQrv(yuF4ISgIVP<-Swcr-ykc5nt%Fx2s#9ivWL z#Em3HI()83e#t-K-*Oso>sp!uoZ<&BFkmAOOLb+o5l+LHWC{R=7qO^+TZy&L_x}7^ zSf0Q2I!(-cli%0P_ul*=pC^qghvIK*?Y$F#3@+06I_Cp@#IF{tv0Ujsdq95)?Y$;H zV$!>#D9e)X?2LSdfVU8kJ)8jz3|$9Zb6!-GB6)Xvz+sLkvm(a7tl42<FX-XEVJKMiS@i$7n%889z5 z)i;I_L^_A7-I~d6G?9AJ7&LAltG-yDj(0+^&kFJ z*P+Mt7x?iFAVcx3fH1xqoVt5+?Rb|(iNWyRch@^_XN#UtWANX5@*9eLhOz<($QjOn z4Tf%+(_`mob;ZdVy(rUP8WLEvi_Wef`TAaxbwcTsMK2k~(DGCaVTRCsX8;Ue8?7|1 z(y)Ba9_u!{_H%=QdemsrQx-*R%O%|Ha(8JZrEhfcs|A?O10Wz5I0FtC8c35bBz*qPjA54i3}FUKA5x2dFG}Cc zZt7hz_~C^_+IxCxLeL=DAt7TKvR1QpwC5z8u6`1~g_vo8?&c;x*ot9+exNnSkhY+m z5Mi9qe*FzA&C}v*PBN~WPTUdl83ryV$hg57@GhSlJknm6J}kVwkQ^;WRvtF=hv9V? zPr>N@;V5*HZ)U6?VGORtR0uPCP&Nj@;5YLx7wjZg`uTs*nK4BO z0lC8&u7RPodWC}~2|dbVYUgpwVtz@VZ!QgQ1Y2xMK1|mCWB>WTKBd`5JP0#$hbr61(p@*YTO zM1E1)YK4G2;S2pk|gtHd*{Z%=GsmzLOgUB*6oxgX1^U3t$XBs{05t zXkjS=V8Dn~{@cU4x3Z%; z&{xV>xOTKMHWU`knY&t1y8`}$?)Eii;Ik+48BWq6ATKxrAs8C2>E}m2XTN@1YV640 zTRU(9QpfsHwK9xEt%R?B#pS=<+}+`X2s50bqyS)$efop#Dh*SUiJu%TEk(XMer4`D zFEDa4GRKv;=4oCmjaOCGAPjWVl^^jwR%vVswmM&3W_4hKh~Gf{ux{=TQE&6I_XGv^ z(UH!eh;ca%*Bj121csI?O;-oenj}{<>~yt3l0k9qm7X6Tj$)@Dyp1NodBO%uLqc3K z!VKP+8vq!RImrI@DRJyjiz@l}%t#Y6@lhFIRQLXFr+DSMzuK#^wdxs#nFlZpBR>t; zUV0n_)nmQ_S9f%O4QhPzj__npl6U#7jn)2$H}V+>jUgZ(IK%bJiS@GvG^_as)~n3! zReJtn5{WeNX4YG^Cx6B)7xuUoIA9Fs+;Rvr%#ez_`1iBHB|V(s$*m zPn7Mxs^$Hp;KyT*;rCj%<)%9<{RH%SI>%zPQi>lMwm0MqZ$zDFgb}a6=)%KR$WAqk z_k5-(9{CJZ5)hCtoPih&ZNyqbwd~Yh;*K0Dos|}DCQ*4ifeKB_s-<(n^!K6FhcSfn z)*{Tn!1)>g!{h1M*eeF6*3jlTi^J`#GuoHy)N`*wg;@Cx?Yc*XZ>5Xx3f^i0mbQ9)Cqwy7mnD3=Fp+ATXSP1PoQJ@#LUV-~yuu zf4XdCUhv@FBYLexb~`)OY>cb}N;n5&h)r!nm_bTm900=^tzGvOLt6k#jYsI-f_Xf!6-+T@e-tZI7mAY2*3)fBRP* z_kJVHpyI)1_3uR~SFE|>is4|;-z7}kyu>2q2h7YKIq!a z@XWPLg@bi50!wc-0U8;E4R1NJxFb&a`#KTxpXvM7vX5iSY;s(X>bR zKU3QV-4c&eoC?dwn8ZEFhIptnJQ(;`P!3~wE2n^P8h!{-zWn#1^!gN!<%)qz+tta8 zZ(;JOn|Z$a8?31WUJ=gSmH`Zl4B|I5^PZXj85(B=Ui5%su9*;`=mvkP`j$()Nyfh! z-mYCIe0e=NHCAaf@mvXi4U zWc_~_$`Zy15N2?VFbBXew;%j>Mf!_Y&6@nhO_?%+orG+*0^d>n!EB6_+y&! z@8kEGS`wh2$PV_RC*VPIQKiYU!hI|J7Cs1IJVcx1cQ8tIKP(MRZ}|{rz*;K=Ej^`(j_-RH`^E4L)Z zzu)}s)|^X_oak4Nd4gszLX1)&qjx1mUJ!<$5Xi z);ssVak#poB?vQsRWPmpy(mTJXE4Az}RO9@s27CaW@GdP$-Kp}93n_#Fy zwh+og6)vd3nZtXZb@|^|eF~u;y7(e; zbCklai|Nkx!LyZH&ye3dspzQ&0foXDsKHQSqL0+mjsXJYF|Qn-t1Tv-&`y6yp39E- zF4lU7VnhGGD~LwnCI~Y;5X}InaVjL?ZO;Y26<+UI)EwRi$N9TwZ^xq}uo3 zbUxGE=T!*MkD&RXr7=Y}Z-&#?E3#=EOp#ML|1rg2RB?WOcMav9Jr4u&(-3(1G9wJm zKm&$?NjbXqj96ca8oJPabuNlsfN=ll>~|0kpB#T*OJrjx_FvtX!W-U0axQTHIA*Kh_97>a#fXc72+(oo)Wz<(+$MCmry_-PIK zlcUCyH3dOa6z%)19Unqc3fDMD*s)YU4tH~MYSviNs9YZz8NO{O&K8)734D{Tbzy!#Uybuv&FIx6tYx3zk z1r|G-NK7KfO1;?5g}B79Fc|^lkF`=vr-Xna;0$zNDB;=10Ji(1MOr=}E&tdy4z!{K zW3Jsa1H)X4P^I=&Cs-ORV=xeASc{qiz@Wu~`Ilj4dnc5dsSr291h?un+gH6A_69d8 z^f2D9cbXlDdW3+E!{w8HgWKiFBD{p&^D_Y)!P*Q&^0zo%G%0s%$A8R)^#nPsl|Uf%I*#`aQ9;;Jv7 zT$}oTXuA)8s{j9Q;6gI9Lg*lyLbA)w-ZOh;XUkrl4zg!tb8JdRHVL7uY}tEDM)tm3 zU+G-8>vr9)->vsK-_Pyy7o2;K=j-h?p3kDyFK@Y$*sFSy)05bLUNUIhg#QWR-u5d1 z4ABRl{+>7RndnD=N)@9}9!wYGnqcfWJ8g~$Ng76+q?H)Nxe)<N7x6c`6&v;-phy@4^+m^eWzS?~TLYuM!&3E4nsnX< z6Eo@3cgz#%oNtzXiG%(;GqJ#Bf;$asWxW6xhMJtYuF{Zba^h;$Y&eZqW?i2xBr_3( zorf{8Vqoj+JxA-q^r;G98Z>^pZ0T`?r_=XEB#H)BNaD+!5mB&9pPN_mC5>R)`yjq3 zwXZ`!Q7{G?F!T(4EUIz70rc?R@n_sGv*KxOeumeMf`@X=eYrX&l>VGWn}y84%`p1% zuHC;EC90IWxmOG{Y-M7%Yfjmfy6aI2tO@s)U#jY9w|}a?8%19pM{`mPkYS1W9m|$? z$J4EK$tN-+B{%QJL~}e9Cvma!UY4IJ|2BbmhJhsrC>q8<3x*ms4XjOMBvnEemKD>R ziGG=f6=yFC65w}L51=kuWaC^GCErJRa5FTjIRIb~*%|)ZC7|$OAN7aU^~c-15-idj zZwDQ4xCOp1EO8Wx2R7qlwg8=UMaHX-1%0W8VI_I1Il-*DEoi;K)gei(zi695brlkV z`0442lQR&|8yEu}7>eGTX1Pq-l9y0^K&t%B%(UcbJ8c@dm2~KR_Ewh+LoDzg z`($u50$?Z&ql8?gVOYD9PI%5Z*iLE(XBVfK*Z0U&txY-S?dw(D%=}EtL4avk7N&~i zmg4LTV;h>QCi{Y^Ez-5O9-JhiRzIP%tRKpX_%tk!LqIVw26`|Q`{n0!lbj-+=U)k0 z)v(VK>37Wh-2*JRGZOr;*}Y9%E*YRV=ip9*&mDaGe=kaBjns`-3=D4Nl8xQ8XSjtc zu@Y{9%aeFnN3W@B+&1sVSev|oi~(eDX=Hy-Vj!dYuG!rFMO-`ATYvEGSL2MuM=bgV zuDRT|5zp}Z;+aV-jDZ0R)o*mga|&ZabF)eFCcb|Bdt9Ghl|Y+)$eL|;6IGn%&*|H% z&#`bbXy6(FU|0-onz&*>RbvoGV++{fno<>bQ9SOZU6qsnGCktVN^(H8 z^2dBSL|lzu)Sg7T^6Wz?R7+_JL^(%l51zz^SiVO*!^sc?^cKdzcyU3d$yYPpia#lw z*~}k3i(_mPt)(y}Y&ha2*>0k)A01x4Y(Otu}c6j%&RW`eRP%Q5?FdzH^cN% zR6SY9yxiKue8Fpk{F{d(@9$!@*R*^987M*p?;Itn9}o4o2G~zYPYH`oW5t2+(?7R} zQqmjlQX!l{3GHGgXdH}z>7tR3#LH3DEVtEFY9;8dddvp%p7+4YFJu;eoKX+GThbwy z4BmtAk7h+Byyo!lMJfH5f95I;$s(>y2BN2V2AvvJ)!xe+3;w(jF(L_hrFh&E^--@; z05Y`V6o&>Or)3KD2dR=^fJkEf&uH1=yfdFaM0Gdo8GVg-2D}S~co+jS7|Ka4ttQi6 z7NU(GVq!ccrJ`LS_$iR?r^30PIKGvQMcRKD%FUMC;ZDOSjWPfR)W%}TD+VmF>9dh1 z&1&{1TWJ+UwU0$)-i>F=+(z9t!5W?oBn8@|`v;n#(tvTTY*MU6w?#najC?Uo9P-o9 zZwhH)jztBSzYxzrHVgqJz!>gG>tbhYl% z|9SiN!3_*I!$-k%01VFH*uS%V-ajB~=BobX@Xg%D*z7!i1T{J>=*`KGcuMiO-|AbH zK>*XRG(Ck>u&}Tw_3n_tg!fUS3#)>xD<<|PJsBh)!Zh#-@eH(M5KtnF;XWApjuWZ$ zWq9lSXvS#|D8`!UNoPhv=BecBoOl}Y0fmd|Wl?hKQG=Ty%y{SwDd|c}%bq z;byw%sqnxX$r!d`Qg#Fi+qNPos53iAJW zoXIC^lI~0Sc?*jI@eHg}5Kt0~f#qUP>4bk37iVB4egt$jZmEt&0k%i?C0k3Pbj)@X zVkpSIWN1C4gPXxRTEy|+*M@pdS?()_<>y^!@y29*bwg+FY!e;UVLvo#oE9tO+c4Hj z*rHEc05Y6%D-R#ge)x((IEA)unJhk7$G58}fLc_=hK{AV0F6aF1MkH&lVlhJ>&1Bk zx8b$Y)>wH4%y++9Fevb_mYPsIy}##PwBx^VW9=06lHpqc{MW^lI-&qD_|Zk&yJ85j zE;%?3KiX3Gw78ex>>l>U)}qvgAOw~DRN=w%b~HDD3|2Z5JotO9as1us5$O%nWu!uz zl8%Kxk-p$-&F_V}5+R;J^d|(A0%KqUL&-<>q`3~_Q4Yie-CWBoemqpSX=kg*^P#Lg zqEnq({CvsKvX%GLCc`( zV-XPs9zX`@=Eu{N`wXTHAhGXF)kNMV3a0y2L78|eyM(K_#LYp7XOP>5fKp)$4=(<0 zXdue>5_*quLWo=7K7OA%_*sORY`F}rMP|FQW;x!UJ*5{C@H4RLJbdx*MXA4V^v)GS z%Pj)YH+k1o7g8uoKGuy=QEYD$Iz4cF6BJ!?H^ibI=&?`D2^~~wL9U0=T9zo(VVlR} zW+kTqmJS;UxG(ezV*}z}`zSpFr4D4X2JOznyc$3c}zE_qOZO5w0r=Q_wZcHcW z{WyYEUq92KU8X_1dI|0{Fn@#qV0ijon)Hext24W_eaQ1Yy<>ffS!@0WZlVZ}ZTe&K zIK1k(2JvyAaLf+|SLR{~?^b;2)#$fUq9`0~>Ko z`4vN}zC%AGf*&K#nBiJIo`+;I+kUlDe>h78n&nMZ)_}$(? z8e-izY{VE9P5raA=lY`!?lg${&^Y~jQSy6zfPclXhrTx{73_-jOfwrPXJhhB>K82} z3;enhDWbWbuepL~05YJ;)3Z$@D@qeCeWVT9cTE}%IM_zsDBSWGlNpGjdVu&b8cNQT z5Ksn;f%9U10~aT{d>WErU2?LL_a+iIl`e67L%n0vmKjT|bGFEzzZ)RS@b4)ZZNC7( zuqs$Za>byC>!k{L_9L!S=7zypsFKxNo%OR5hlK=uCVX94As3*teQxiRwj`VI8nEI$ z47i?QB}Wsqy!)$VbkY8UWN4kHp#|d8@R9`r%7ig+fuTV^YSzGxKj;OLdxKuYK4ULf zjTd#2N_B{4l)~XPJbib$HdtxFzo!)L*bIQdTzKYhTdOX;o<2$bo1au$aR_#44Ln8pwu*vhJY5*7V5KE5T(j&T1n^^E{DTi0{#@ z6vPh!Wx*J@FZwAFjMw>EPTgqf?%<%}+ubLl6AorKPbcV@`K3AkI+f>=;ioSAT>{#V zZ#n;aQTk*kvU`;V;<@i0+jzE*=mqOF6>78tta$A`R0a}#U+59weZlLF1IQri5mFPv zs{i`8%0!-8SsMQ4;vs0!*?gN*nyh>YwlaH49dnz-A_4h1oXPdhsG%_8a=*2FykQXSe%#`krkiC z{}S;GDFzTw4vc~K;wo{%A}FXve#zk}{&xPYP*R43${>H*06C%c?=pE+Mjn?8wYT}< zW^lP*0e~U5`+5D}G(28+p6wT>bi@k9a5McqH`2bA+;f-Fl$O4Qm1whd2q1%s+wkY# zp~s=A3oHHH9B-OF;bM&0tNEo;+=DRn?lgQvJVUM{1e6P7-~&T9c6Y{3OB=YKbp(G7bPJwMVu=JqL>${B||tTJ0c;r zDcvbAI`^9Sja2X|^`}{^C8e!#05TYb#aeOud)$V2tUS7hc}qO9=(A_$Ue1w zPC}e-cYH8hjE=Vwb zOB&nXSiU93ief8tyqxle%KY{i8^AOe-qM;kfOa@b2!A!r{e*J|v*UwH(%B2AIPSoT z*)JX-#51&9%=UQ)W8eov>7sgtIKYz+b;we^xw~+}zpwLG1}c-OW3?)%Wtxj6{D-0Z z3DG9p40ULS02l(ptrV{q8WjZ|%vu>~q!oVpv34^mUpc{HT*)aumUHU~i($6PG(ZNO zWnpFM!Tyfn^j>?E;>8dA-R}%EQ3LP_KF(>s=Fzi5JVSQ}1oR%pAOMD**CcX5v%l-B zy=da{;gw7=i27lov}xJkbC9(bc;j61G7a|1@Q>dM{2}f7?`s3|^v=>1!(g*KYY0QB zsDq{_nOm`U>ofVae#YA6w8MP8e#?y(On?jodUX@TwWCtG(1roOuZz(RjWh)-=$1M& z5}XZEn;x0471fr(W^zKZ$(7T==z6CnRPvU$kCH$MG&Yia z$xyQz2zMH+ixUAbAS-xIUNPjFq&&TA7EIY2pcziR=!M1K@TF51uTG2x)#Ibz^(_K` z3|L2=e7r4Eg!e7Q&o`?D6vhoL$wmXlu9G<~|2CKd9U`7#?i>R80AmmWL%-e9uBXGg!s^1i%pGWb^xqVLq>1ZntNW z@nv4|z1-QfZM!zX-REBo@Y_z7WD^~miU2Z1+n5A<7FifC?n-7R-%Y+Ttv#PCD`PLA zzcVB@TC0rs%acm$)b;zaw0K^2DRe z{*nPgPYyT3YY4yFzZWI?sM^0>0^ASB?}&)MdpK^L@~QK;bNxV3Zo0=Tmeav-sK|ZS)wNaG(|H7Bj0WSnp1Y-~ZLzkcX z9fsW&aM;2qBV23)NBkO&;%rFc_fgrzkf(n)>h~Xpa)x~hxEVfsgaKf9fTKQsm4>L@ zK}Ml+{Dv<>yZoYon0zIscYCE)q)DwchUwaKK57AE*cJ37UyHkdLI8s<=+vz)GcY_|7DV!EQfw?QM+D2=KY8HSDmC4DaZKs+T{e1NgLSpep4;?h0y^{WM-$3}OfN#`~M~F`YRSg7G z3S$rlL+!F1dXhW!CElo-3zwLuJ!B-y{&a0%HUa7J?h_V&XPrw1*8m#0873Qg0WjRy zFZ}z=ghgV!B}t?`U?1uwFR?0>L=^A!tX$i7(Z#!JuTA0IJU|AN-dlwyhaA5%K_2RM z8{Ztt_Qt$N9)zLwGruj5KP7QTJOlG21XKoNkhr)mR#zz#ZJw@j-m>o$QqIDjz~azu z-dlT0vqN;^bZ)40$?#$k7jA}6KdC+by(o=K#G72L4J;8liPXl|6v?znS)aFCW8C7R z4fmr(+QRnR2j{90WCLUfGSLWJeCQS@MR+PhxUIGJ6a47#%ck^kO6ee0{?K$N;u*M5 zAfR#>gXI67bX7=OVP}gx_V$Kk(}Eh^5s!CTuWrXD!$Xk0xx@Sha+ocLmaI*$j#b^rL~^=-zem?fmWY>+HRq zQ$e*q&*OLsc6M^I5WRA3I+?*p;{n7o2r)rG6)*-VFm$e^?Hm;;#o?)Hap{L*+QniS zWbSCAE^_BFbmxa00CyUe4O##&6wsPxT%{rBRgh)Tx5-R7;t#HGd^x$7 zb8mJ_%H7;*zK-gXE`8As2iP4}Hr%sl|Mui;{eW{LzS&YppUaWVaZi_3VKLqtu3tPk zh-Z*if`BSv4ANjIN3*q>h&InyHtN!o)nr5bK$@ksNuoS!>X)}uIA*KUWX`{C>xRxTDw*{l`*M<=T>h-XlBhk&YJ3^HIS*N{%Dw4EUxj{64H z6Y*+8k_5#8J%xB{5p314BcqcPQsgpYuyj zrdOuY| z`N)4#8~h~W9&^CQ+#RVba<5Nf-v(tY8CD!`VOZq0ESEp-JP}^Ld$%Rlf^4 z2gq=~)i7Lrl+hKJ{#({SStU#LS7!k(*=F`aqjP8$9X%Q1)8KV6sQ43%K>-XE*?$=o z!s5GCBH|1}MSGI#;ywb; z^aJXajQZ*x`K&4$%~dqTAS2MR4X?pY6>iv`0MevlJ}^<`1gQHKA6mHL~K_rI?V&yA=5t_>Pr zhp0*43gE@hmj;&KPzU|G=Ghf&LqYhNcWr$Ap`{tXq9pt<)?jP$gycB|@|@rlpChX$ zX;{C7)-1=xoAr&!tun+jBvwN}^)LoyFtk@B9#8n=ws1`U@O`~EdKP!RhSjNfNhHri z9_yjfQr@{_ut|o$<>8o71^@={%qLM-X%P2P9@KbvH>8t|Anvou26#Cu#uoXPehF)F z%Ru*n3D5_*ZA%#Atm{@xi!$SyZLAVqMJl*oBx;)V63&Q}j-?*|7dA7p)*zq;7=y~i zA?O=+nsfiGU(ZmCUVh9-&JvR$)zUH0Fq+eR`HWJ&+4PbjTkRa~wc#7u4giMYJ>E}O z40*X7`8My-2Ux;~cQVD_e2t55dw`Mzr4t~`6BD^3oCh!s!Qea2KRG_~u>Ejoq4mp- zAag$rz9XIC&ioQ=U~sMIzwo70LPJ)16$A1V8D5Zk^dnaEzReM?AJcF1D;{do zV-3{Px0o{`{Q~;II{h9jbsguN^nullu4ij6O-ifW`y4Ym+Vzvm9tB>T`Y-ITR;xom zUtkPs7lVplskG(2`SqBuy=_!JLlla$_iLG*{rym;FY$NzTGQ=IhG3lQaHoOaE)D?0 z$HJb!drGg9k;@sblTXQ*+#*y&?hBMX=&w1vVeX~$%=(P&%Q4VnpX)z0)CVdP)w$EU zY~GV|R;3>o7s{3O_trt*53`p!j3a(+XbOdZnqUm-VCWm(CI2DQ8iOY{UON{`vflQ6 zcdbD@^o3)_F-|g@>!Y`q4B`7da5J<%TmirkET0v6l?J*h^WTz~@%Gm`F^eA^Qv4*{ z`*}L`<~jQ0)|7_HSEn6-MadmsOS&POf|83Jhk#YF?f*hi z`rZryHNzO5f}t_8PW5|~#m;HoEa8!U>JEn6Up+aL4Ln+&Dar*)IlsDO@LFGin;{hG z@ymZNN=jSe->(?ZJT-PdWD@KSiv&^X@Zu3A86+<6dZvBMbN{)vnDR0jAcN%BndOzA z_2;r4Pbl!Us3V9Do$tqfr;%W_l6=J&^~MtMX&5?%fLdS-8eph0v0zY5ZiC1t-&aYX zwJ%vpAA)s0cg%c|L4#Q5N@}@YG91k%!p#sg914ITtd30Tiec`1>)K5xoJdx$ayNq` z%ddglWp%S!=VvdtAV-t#8u|bkAbrYbCsQGLqp@rs*g1-I4r4Rh9LxmHB8K~A6HEFY zBc5TF2Lk#EW6%Uc`yO_y(mX3DXkz2?v0ufhX>IRmpluX>8JgUvzO%0U{gT1@+BDn@ z4K|8NalnKahq89pV&reK27kqGP@gw^QfBjTWmYT}uwM+(ju^#EnjjoD| zUM#9;B9NSsYut`i470Jio}zA}A$NO`!UK8sD+zcGK55WIkl#VTv#I6{O?d}QT|IiJf&ue@e zcj(mX>XsCc)9swElprdB?ve&{i58_39M6o%eRSRXJJu4#N5%-H^9~_3)4u)ef&ii? zt}}>d*eiyBT44;@V5pRU$EiBoCK*knkB-J|9wh!o+sGZZc$t(PDaw2ttA)!nyc_C< zn_(^m0)RpF$mQ=d6YKT2xs|^ZA8`0{|Et^BDg=Gtqk!v3ct(7mF@q zU+-X1Oet9z*C8vo(c`BKb?R3GdqIF}Ln%(<&nWd4F_#SwZcFT6dEvc8%scnyd+Bp6 zuI*M9EFwG&Dp;%#P&v^aPoeNx-%&1udQ?uY`=;){n4v#^0h-`Sh>;y(le+SchE|C0CzU4{fKm2u=^M}&ko_Ik}Y(e0Rdo!@TAMp%Cb`Vepj6n|!O||m0 zcy4KojF0vjxoaz>|7IN5n0+g@cd#QNG7g!>pAXizqvCKg*w(uNV5kdmE4X5yR|@dz zaHU8kUqB8ai0F$;wN(zNf{qz2H8?lBO%X2uWQaECg?{-s><)HR&>W*{6*wSB4`Q?X zsdl}wiNQ)D1o3xRRVYg!piUTrJ{X!y#4WTfzFt{ABAAp=`xA?=oqbYuk2mp~t?jo# zqYCQFwZYLE{+XbZQ|$m4j^B|kTrp@SCMkbhVSh58C-YmT;!dj?xq_cv1}fC|oTeRZ z-yZ0dfN99ow$ec6nfH$^i^y=QtuI9iHFEVQkHi=i{jkI=IS`))rX2|AJB+~q4CUSD z^qn&kp{vUN6;c1nDW1LUb9~v-7KTL68Y|cz1wu1?-`VMv@!tqUJbUZ9XHNfLo%RWN|=Xor!Gm>2AZRm)ph!flgUOL zwpEg;W{sj`#-vr*i2w6Vg_92g>Vh#Cf}vCcMb{4GHt$R?eSVc^8>?2(5vif-He8G% zU8kpqL{4|fpyy5mH-nsj9RP-USHZuXC%*}72-%X#`^sLwKj*c@A#Dv^9(I$%m&qbV zDp^t29tT*IDEzj?TZn%Q^r(BPlx$Pyb1F#U5*H>j=I)Bq_TRZ1jQBJNzJ!3fVGKqW z7i2(%iX(bYN~@B$o_01#K+e!d^Y(*T7R_vz4D7M3S}z$qR0ZH>=Pl=bF_}k+1vXHU4cQgVx-@POdvQv-m{NP+<_FL0c6OeX}W)&!uHA9s_1F-S4#Cw zmU5zjxu(;8?$bg)=TZ#BGe~`ffO=pI&%n??)xl81oSb~$9mNTT-pa*SCFo+MHI4jQ zyEdN$I`OI#; z{1MXHSL-bvfDF&1Q>NLaMRU&anf6|HnLM9Rtn4)jkGNA)jFU>yf2RuZ463*gP%n(Z z7z{1`SVH$@g4dXGs;2%U>5}Ihhx;unsyqefO=UF|cI5m^2Ga>yxYGb7F$2KBf4yYm zis7vFh)?{Q$8xSZ9sRW0J>ljZoo5@?8#Fw5JTKq3F0=t;V2~0iim?9_%9BaD1U}K_ zhE^r(1suhO*FL(_`7QJd;+wpw=xISfeJ}=-i>|~%N5L)JDbUcD^w;)dx30aeKWEYAw-?|}L&`X&-@g|n zmKBk|g9BdD;a_v@WD5=|*qigw_ogaL#GJ}?O6By)e!0cO`-T%B1Cih^&uTL7dm80H zqK92E7GBoV6E5=ik$asela?uD3K7rXun7STz!=QHQ0?L^V;=!fR+TZS`ty6Ly0o5? z_Y>T1h;M(^|9NYd?%8Eg($blLn;}d=4*-LyfZp*{8g`OjE6j$wOBW(XJzv{V=&ktMF!P14%5q4ddX>sHVB~7I!#HZnP7zFeK#$W-4-t&ooOWi zS+O{l`c;Wdv)92m!Xx$CpJ9|HF7a?PXeuN7|9er&N2&a~LpX)2d02{)3;wG#Y;Pk^FzIROC;!5A#T&{2FH&;$2)i?A+cy7tQZ!M6<5Hz};KPWLO{Rp5j^7r!h@4ypri zGjPqS0brOSO8@&HSJ`4>2uUO%!*=8TuG`SK>AUM_(bQ8n_c8sbDh_p?p#o$;sg_yK z?mT(X$eOH@Ia}0Lf}Sw-fVefBiHOq4X|C4<@o7k6gMfx%49_oyQEr4udb^e?2WmGz za96^x<$9kT6%$c(z8HdiSR(M@&)T4=N(DEAiFYmlhUA5|zfTbPSZT4nGzE$_gwoGk z>IsmmHFrju$5C(--}1fnoIEE3$Z#*#$jfVvyhx}{Ms|{6_qFOr`L+(?+tpKZT5qq( z$x0%gAsYe#jldYJz)++w3)U5f0cz@Pv4{eC3p>?MN>cL3ZBpZerp|NGkT^5vbscUV6)3(A#}1_Xb% z*Ey5J;;~4zy6g44E3n}9{AsC5(>-#4Y2XenEZE4U^gStMOcoQ)G>XAXNgQ@6_=-oa z`j~_7={LkP)ZBxB#$XIKVCaYYLg$lnySR}VL7H-flJ8cxa{FR~bEIS_1=)KTq8cw5 ztft@}M!6K427ux7p!)LFm(t+J9oj(jsv~3Gn54;spw5|fi==?5I_nIFYW3f)vflwR zU`{MYrq!8GOvufpAK}Vlu{UtAaXz2RPHB3KzF)K$fOv-Hi=s3RW3UB7F#~^v4D;)G z@l+-avxF5@2jB?X46Ni;WBet zcU4x<-!EC#Yi|BMg!y*on3l+nPrt(vAOkIrJ0)0N;k?O!Cn)YCHMx`rIc_LFu1#5> z0?GH7W?sZIbd5ql6EFrlFx2GxP#!T^k!Uqtwax=J#kJZu>Lu{RmjP-XmxemZ+9nVS>J64h6zSrfgC8Cw8r!Aao<6nmhyr0bKctr&Ho%ti4VdP?n{UnUR{^FhzvfRF@ zeOY6yoA6lRbNU&~41V>Qr^WL;nv0$94U7ga8N8F=|59=}j03>Xms;w2l?H!I6STL5 z5+6t{wb&pk)<&LfKT6%h#kMmMq90WovIH0`J-G}ZU#|B=}AuqRnItR zOa8-9;YocAcN$P9Rsk?LcXs~mwYO$xw%RBt_rlYXoww~}4R)fFAeH1m#SV9HRZ`%n z3D7&N-G(nLzVI)xi@4QWFcGzuX};o5(85ztUUE9Lbm^AZM?Ax?RS0Mr#^4Bsq80dT zetlbTe>ng@2X%4BX#AP6bk!cS)@07(O^n;emxBY!d(d*>W>{|*2>kb=)Mx)#>naUF zntg)e>`yd&ZTVDp>%CJ|(vNB3>1sJ-`eXrW{UIzO;zZjYW(ou#&}OGT+*FmSA*r+2zZzUfq?St2y@;RYo|2Dsm14Gz(*J z0z*YNk0gJXaOdJ5#;1_F5D?C*IhO8~{Yu2wpvpdVmi%)wBTz;HZicazIRFg2bIoyA zX&{o}-8XnIi^0jz*6uI(1dFbP)+T`UX-x*xtQHw`wHsg>%2s%8&6*xiu)V%$oo%-? z#d7nJ+d=3H2AhI2PJubQA;dG_Tnv?&gE2URp+0iIi!-l1X57;)*?NbAoTb3l7unIF zAcnL;I8K_J!F8F2ofG)C_GbFHgZ{lJffzOut{ALI^E8ThLvlu+&wNq#Z`JoX!R37& z2gQ5VI~kP0BbEw~L6K%l?#6s>bE-aXr0gm-kHOs~4?bLUnLP{^spl9)q4 z^DqV%Fmy6@x=y|K$Mn}%-o{45O`NaY2{cBl8bJ&iW+hn`B_o#%v1@X0r$K5p2mr$^ zv%|Mn3`5@(e+T#uTk@J^a(# zW2ip^iTOv)^ukXRtV;&(FT8Lw;A2k!V8BX?(7R%2V25CIz9)P^I{2X@Cc7ZhQznE7 z?1t_~5Z2>1Cj34OAVWD(eU8txLpAesc7M#;mXZUekh;IIUAoblW}K^5(|>{C{>4z4 zMHqt{7+Od1jgF)@RSHUMDzY%?J2}kpC1p*XA+7gHni319vn8v;<>t2Sc|iO_-6Lqw~P=6f}(oBz=9zyxH94Mus z|6LcAzN3w2c8Ixq{}w=o5z%%W@fC{O6un^wz3}m=}K(5U`d`L^{H~Vp!gbTj&rY_R8Cm-S^hC%PXdv*D&~sLYqD!oOZI@`3_(jNWu6@szwbZ zubw#W=(6-d$tJVdTy4Dr@2z8Ih&NQtBA&tUVr%awjKLcWwFze5ew)f=|4D4;U9Y$` zpJ!q6?VuT{L$lG9rJGz||MXMpFou7q3~fmd0EYByIFVNjUo_7Lvn&ttbXmn8^Vg^l z{vLZ_7?&+Zo^h7hn^pWJ9U#Nu{va|3I*qX>t$u1HHhJvipo2Q2#kcydv@DNfVvkP5 zGdxd&fYx9PK42(#+&RDk{FQXA|97PA=z&SG?#>&(-#&4So8E>ZbLp0sX)rV3gS#j- zk<*6$dr^8mb7T67LGaP%=N!AXwPdM|E$%M47Ihz%+3zaM3+|$nFuopx?6d|zhLHm8$WJ1RjHFM~f-60Ossgr*nFnsJ8x-JUzcah% z>x6iQmmUz%I*b7fhOTEUo#ZRH&b*qmvQbF(qz@e+jA@v;qNbz!+X#G;4rGmb+GfO8q^S!B6{pn`u)2)f9-ape!`U_d%W_XxL5%%vz>6s$>-)0S%0XpApv&ttn z@?MEONbK^lUk?QHlpzQ6S{k1%99l91OhdNUJarm**Wkha3zO8+w`7WQ*IelouvW(7 zvR4iQIz$nlh8S%KXcNW&0Ygt?o-}@+kds+{#g0DkBAiTa0ZGZ{=VW;8bp+02q`vsm`w$K7(&rZejMj zw(s)Zp8p_9rf3U^Pc|k-OJWFr>}$>rv{m|{Xe0i*@1!X$@g@{kelF-f<9groDFXZ5 zt~L_16a{jf`ER*82m0CZdn|M#LKhGjl*#h~>q@Vbyr4%kS%Sa?imos_OWOZS$%aF%}E>h(@T z9H3o^A4)Xw#~QU)XKu{zts67c9@EyjEcUe(hsI!%2F$E~+D%X^pqoB$xpX&=OAqn&uY z78nWD*r;($KJrsUd{O$$3<2%H7+!;+>>+Z#c<8AK==bV(dbg^H(T)qnN*6a2hfGE{ zYMu^GUou2?iNej`yxahQA!Bm&{uRSnA*CD^S&J|B)WbuL8_5`B?oXazL&HZO=QR_= zhg1Q*nQ@f<$oT2~`Ol`jA6{8~c&QLT7p?KIs}ChQ{=+AFluc&DGqk2dK)W!805G(N z`PKCz zt^7zp zJ`3t~*LcG+F(Qt>E@`=kigE z{d{V7#lS$j{Z$b)u^|JKps6h0rl~+Y?x+JJ_N{xT z>9pIE6m(xB-w_(H@?SD&_QQW&%#yDP0K>V1t?de&F9A)74BG_wlU1CLb9y^d|r(*%(3~D!m zAfRIyLl_vUGHXm=iG0uUmQ}COLtTY{Ye5Oa4uLdA`9jjU>{-@--bI%e!hb>Lw=j0p zzZWIR)$G561H2zgI3YhkYxOm5QFEZiB*pvaF`u1EZ@ZeF_DvX4kO8nL)upfJE_fc7 z)!^&jo5R1sO7cN=zT5k>fepMFGi0Ksj(7$F3<&51#t;sMp4@BG{PooCa7rX9V5%bQ z3sTqKjcs1C_z!uixb4__CzolkUlxSBC>^U90${lAyGwqRhE$Aiyze4kgcPkWcr+Dx zG0@N%O7EluLQX!_ON_fr5CdemH@1TRI?aq+l;7Q{HgnxCHKD?_ha=fZHIgZWc+WgzbYoaSbWVWx@6EnZibuT zwOttihT%`|*{~wFAdMpCIPd(~}21 zNU51k-}xbOm&&FUC!H-gntjJL4>jTWN3~fXbUNH|}GIS)O!Oal!7Crjki;|zyo64&+lr0fpp;J52q93+; zEb+S@?X0*rC1|4^e3>KhDl+7u0GNh~5YY50s}$%7_i5f-l>RI9-J>wuWl{$F2FBaI zKP?g8K}L=J;-1nuj3EjPU0W&Ba-fcpcxLR!H;Q)<+@KlwZhsHaBP`hnqnVwFCfz$|5B7ieY#S-GoZ&bR(=3 z(nciD&-f^8(t3{mChjM%TMg%{8=e3es2jo-1EW26$o+Y&c_67@HF(8?sK)o&LjdQnfuk#cPJkIirSeZ%qe5hteF5kZ@3pBN`KyZQk2Z^$hX%?mYkXAQjJMje{-G; zDrA#S8;^Jfoe~HI3XCE4;?K8q0smBj0-Zj-^g8_+UY^$rU!u?}=apisojBFp9!gy@ zlnV60ord!L4*(d-q3wT%QQG$K9WTyq$UXSt8ewWpjRkVg8|Yc| zo$l>=o5$e=CfpivoKGAP-vCt2j2}XQ3S)SCar&l@q4C`M ztH4sHz%Jbz+{zFldMsNba=N>Ax^M98xs)y$9P)bMX4uk0j`{bZB#XEF_k&fbDejuB z>6=5}*F8l(B)Is zYL7Y}Km3F${6GZpX|QjFP+W&G#DSqk-G;H`3~ExSOCQ?m?1x&nR-Dyr%@^EGA08vk zPZmHf8LUF#UmL2so&sRNR9*NxzX508=L2tc&}l)*C#Ts+x+>e@U*UMA#Bw`Lvey-Q zR*(TQNa`_@CGjoWprw|G>7(@KUGm|9N z4&6`Hr5xKSY`@9rS-brbm26h+IIYMZMjOpq{y79S@HK!t4Y)Gz0Wh4SVEoa0cgX0Kh-ScuXGppMp}>GKB!QvP0!!`w3#S>JbDZx#Le#hE%xyPFh!eX< z@dYr5O{@MKf-Vc^z|CNPoCkm*N%HpJG+-~{+Uc({yi(tf%3VNWSL5ki3pV@SRj zVxRm0yvXT^kJ>6L=3H+1=ELj@(g38qTlqm!g>+fqw#%aQZdV0v2F&zR01N{W4Aoa@ zs41eJX1=pkhim68YA}7u>#52@1LnyFe z45?t~KD98N-lu810c)xBsQqW%xonYr7H@IP7vG^~_eib&xJ-lH3_sjyIKj&O9~e-t zAzl1;j)sKvLcvJMUJGdt2}%5(-T&^Hk$8CR7>c6fJ?u>FY$ zC$;wl-Q}h4%uE0>)Pb1k=xXWE4{GyV6Rvx2FeJ;@BDwFsh`QbY#wek_`#&+fzKeuj zeGTdC|M-7Xz*ntB2SR}Z`>oS1erxoJr{x-Y91)wdrRbqP(N^oqgfOtkJkx zzy9-Emn$~x!2Mfm^dA2YzcuCm{afQ-Lwc}y{`=~m{BI*y^;fe=*y(J0xAQc@hVMlCBtpYguJfZ*QHLx)$~Z4R;xD_qQlb-Yltl(i-1gI_Vn& z@SnWY+sy|h#i(}jNAxK?i9Zh4%lN-p7eh+E*I91w<0e!ho?$c;LV*ioNC!jNh)4%z zSTs9Ax6x6a{dB&+CP78=sa|Ou85?tbB%75Rz*E2YGl?(3X^~Y+ zOIqTxC|#EohMVEk@CX0{D+$4kD+V7G2EJdMVXsVDuu$Tnr@gKbt_qT$(x>9hq4XAO zGgt#mLqnMAeWG!EZ(EHM7tWD%!5DTimg*lVqGH7mJ<{w`dBihpG(jlvVGNmIXt&)* z+u!-L)r;P*7oQ2I@jF~Iz-@~tD!Nt8n<=n{{pZ!K<~b_d3=K+(@&8_wcnIQ6uNYXr zEgAgm?rXx@&~PBG=o|Hyz|RKb@8TgvJE;{ephyE`SasD|QRG}~cOMRab%dw!v?bjT zDq}}zJpKUpmX`TwE#euD3?UQ*ForBJl;$iWwsi1%z>`f7Q{A@e4Nzy|H2#kA`){Ak#HwqFS7y|4?^%(}N)`&_j*f3#Mq9$mV_IMB^eaY}?yC3c}P%0e)V6aGu=DK2d zLPpqkFxav$hPE?`jI&6O^R%H(Z$MxxcYx{X$!~R9fN9vTa1&&|*bGs7s%fbFF=1^C z&s|Lt-5+lhGdXkUs~M*QD33e)-+zql*`WGHjDF+DMhba9<)Dj~)k zU;bJ^r4H3~`7F!2lcH{5g81j2>a=qZ3St;T9vCXoPg#fYO~I^k_BI!?b&*|QgCj5d zTugap3)zoitp{Y6451NE;AWUfJpjOfJl^u-ilK0A*=B>aETzjawH&G6+sO2MNBP(@ z!o)1n83n>}_68us8uh?qB>fb%?SU)|x)yXyBKNM(T(!5lI%J=w)Fk&Hekim$TL6TD z1jdjLhLUs!+l3&naqDc6b-z4|TA`X&Tx0bjJR064kpIe#9J5yF+9+5M=|9q2cXK)Ki{o!oJD> zi?+Lrit2seKrbOkNvAM$gER;zjg)k!N=r&h4?~xLw1h(_f^P@UY)hvGyk=G>ATOmu08DiJog>P{E$FJ-}Xl`t$cQc`*1DoNL$Xp4Dw4!j0*yy zfHM?bUVau}4gtquyfb_IVTNdcHc7v$>#jy}2pt8;Y9%4<_tm$Z8pkId2s0$z$OFJ2 zi7hY;OT(=Z1!~#*cHELHl1p^N$4&B+^)ncKoh}Z9Ug&##-)jIeyqA7Ra{iO8Nb$_g zYOXmuPBrS#p4LI7{LY{1*Ejts{|`z@ZUh3NgfqMYLq{s?8B@<{alSp!7RBF)()y}b z;Sxicc6W8mU}(e7H{&V|huu>MGuWse0bsx&-16TOL2V(UB*{ILOVAWlq~ zW4Yp!8V?(pqS1_i3P1+QP~`x-CEan^d>y;CkVd_d;pElO(;rOHgP70?Z2b4vLTWxII7yixA~#oImo5 z_rxpfSsf&^Fz?KLPm#$pq1qRWW4k{12l)&}Oc2m5I70~-%20f3Y1HW2=YXC-Wnom7 zW7OSpj}IATH&LuarK{b${@bJE)`IvCR*c`d02qAe$hu(+3Juoiqo-sW4jVtS6A77W zq?plvoEO_^R#dK^&22l# zXRsWEfT-aNrI+(ba)s-0Ysmygxn-+{6oT0rWQlLS)2Zdaw5Gg}e;`SSbL26>I9X>~4u4Bk$JAM4TZ zOY$f0Wh9|_GTeRVPQv=#{`rDjN)(q@z$4@{IA4|$4VC?I2qj$n3 z0+mX8vOoJ;`ethQJoXyBSM}enj5P@cgc&sYR5Sm*l-zf&E5I0@tp&3PIX*B;N_wl) zkZZF4L7u_0*cWRr^Gj84ewK&=KnARCHuJ*HI4A!1#K%|FZZuX7&Zny(_+}8-=r{K+{+>4I?agHZyB)JbxjEzXmr0yL;Zvg z!VJ&k^8hd$bdY<)7=~#GM;+OAzx8>AU4s;mlCDcDQCFwsOY_G2zwjqwxd)ITmER-s ztQIweb8be7|;+H%7SQSS#Z1%`|x_kxD)QlvQ@s)8J<5`eJFVMVopdVSXk|f0a{0m zFvGZ^TGqdp(mfG|9vFjGNyyW|w`{D9WX<=Bo($!R*KzVbIp=XyTQz>9&KLu9lG`Vl z7sqz*ZKje3;oAPU z`wCmBQ4q?sAU3mzlxr`?q*F$sdasLKF~m!YAk1*{AP)dT-*=3^gE2_-(5h@*2_o?8 zFh3;FcACZyvT$^Dee(=Jw{|SQB{U2$4ea|*zgsB9;8>%rsa)*0mf(c5>87m=zf}|c z`igxtb{P2#`I`_B1Dv7ya#x0?w8??AehXe);L#JWhaZL_i4~cK0@A7Cw_OMHjEt@r zz-)+5fIdz;2EZUW`2Fwfs?+xHUB>(JPfMpuj^+&itay+G3NIw9koM*HnIb;&Pe|&PUB2jMgfrA!-ZT8={M$B3 zeE6wa`x7-3{B znOL+K)l-8p=ZuGP!uO0u`B(aL$VOwL<#kv$0WxsYo>E+SGX=u=afSBM6@4?XU{?*qM93E`19W`} zbQ!)~F*JmoBh0Xc`WgTO+n1Yv@1TEwH{ciwB`gbD;BIJrY#nKtZR3{K5j*;ku`Rmi z1t%@V8nBfeyV5sDW zPjkg2w52+zrZ~#G>blQnU5b>loJ${?-ScQjzFex=eNyIH9pA%>FvIWe695eFnttZM z9?>+in3eD24a0g&6BJ|em|o---8(&q86)jGVvEGM4F!5aQgY{p$1r>Dgyl?A)gR?Q z_*Uo1xv#9~tdiYrQ>f4Xj3GY_gO^7FSl|qGVCd?AsHd~bo1E!9_0TVx>W6BbPesL1 zH;aXBGP37}h5loR{K1GYLqn>@tA8&g_Qg+2Fa~kkg84`IuAb?pGM374e}YL{2(A! zI72-c$|Tm=a{k~ZH?@VoUQ|}tbzYp@U$){F^0T*cT|0t>bg$A-pO5&IPhrW``(SO3kvbjvF9{80+ReP{#MrzA(o9QtaxuSasUeErd(yk%AWV z-%F{;Fyu3gVIgegH$>4(F?^Ce%dd}r3|sG=2;}pOeFyVy#Q+&rz2y#qET58O)}q@g*!8uA#OfKMg145D*8Pp$QD_Fsu2=b1t{DvM?fQj!%S= zqRVo8uBfPc*gQ77#p3YaQfNC}#2?WFGH(GeNVTs19TSrnGl1h4i8)904$OnX-jrdd zvxmQFF;(WCq`$XOAsz{k0Y}oZIKK*CfbEcRUYK0Q1NWu&Q{Jci8|nro_8PHK$X|7+ zcikBR;)F9aUrurhchG$*F=35SE6L0}}Gy$}l-)F3XG~ij4yg%fZ^oh~uQog}thGsAcK_GKA_5KSmAw zV>l1Bj@)71#UKxl6F0n#T9?M2!&OMVrG@k~=n?QhKwNN!mdh3C{L$a{2={rbAM8Bg zbx5d|PR(dARz!6{abLF4kfuq$VmM@PN0^~hUnl3^ONn_x*#^e&c}oSlfqUJ!Y+=+& ze2A~BwJ!UB{RIDxs&wvG7KgFh02%5aX>XG{ea-~E%CR{uIl=wUhNaw^J`FxkGkHo# z#)F1@2C7{Mh#SuE;qoZ)+1)=5pKrHOYab{*y_gpoc;k@av{X1t+4V`c;-_iN{}^gq zzse)b@XECa0K?2r{J*0Bb|E8C-+$pLS?2$==T-TtzSS_xxr=%Ol0SQ+zn7w<8z4g; z8~untZFJn7e5r-9q#NY7EJz3+@XSt`W4EB%^JkxaK|nlkhBh#?U}(yyCR2o$wIU*Ky@D<0*82}xDDMq_=QC%t`iC!J zTrqgemmP~E)S}M>t ztPccUe-RmeUpmDrSXnel@`vX=dxv^wRiS10kizvlH%XAsAT9v`@xmF}!BEJS?oA8v z!mj9-Jc0}=gDa{dBO=7tRV0*^7b9!r=asKYNv4_-VFoPp5&#VI7qpLI3|M}Qenr)< zpGJfq>gN5}72arg5miH}aD$p=dJ9iZ2u7swDZejFC7v^KxK5l8c9+*jThUo3P6eo>8nm;+wXc4#R#%r|Bg`;rf|394r9}Frz7oa& z#hG>-?G_xu$k7(As}~9|BjmRbP)#jqQ=n2MU3{Slkb(8HRoE*r{rt>ryU$po+inue z7#?4t(b+HEnDBA0ZMh;p4KA0X0EFNS-C*du$Zo#T<(hEayT=lRRqv*~qFj*QT4wwL7aNDAchB4%SSo&)COm45+|BqkXVbw(<3CGN&G$tzF zC{f=7RlgR144Z^_zY4kgGv)9ng~!QB>M>dz4Bx9ML)b|-hZ?%~{}29d@I8Zogy9T5 zV5r(^>)Ax5cBNK;lV3>kA)}@g67j*rZ2%dB_I{$-Cb5%$eLC}~|G~tW z!H!Cj&O~e*o#e~M;?MpJB0mjbeGrfcoT2yfMR&;lHOAHwe5db4&&<_~uQ48@YM*J1 zOYV)mj=A;N@4vfmV0AQv)6hGF_4?mSDec3`-=)wRhSwgF{>k{h+fVCpC$Ft0=UoeZ zo2*2f^tM`sGuL~dv#UI(N%~1BlpjZLey`^kPL#1d-`i!jd%A$zQku+O6lRQkhJ*|V z=nkCW6BvrQ6LgEOE-Y-ok_L;}EPzQB^F#NGW+%VUHnvH-#u&V-H1v=LA2#)+7BGj z@xe;HcBSYhs>I!Wlv#an^1uhdZsap$Izm9AaE3lGl;ijY^@(#_ed-3UQHJ{+@nm1A zXKoKflnS-`05yU!U?~b#D68&&p7V7nyCbB0;hbm2s2&nsv{&djDfKuO=>3KS;RF2hHa~pR z)Q@7@Cab5KaTLfh7QjZIK{q7=xPPjror>owPE}X_A?MY$a!7dDHlICr@$I4TX|%sk`*JiLc7>bm@_%V4;YECp5%C;LT?mCX-2vBYdvL|JSlq>U92;ym%B^(CVCh? zAwLbn=@5_voMGtl($yblv=vzw53;Xh!hSLYW8`n|-+ABvGmgKDj$xdsRpqLbUg72< z%<0Xd?JUyguy^C?s9+7EyX#Ah@* zDt5p2hIFLCLm3fJT(ye)rj5ua5ggWmryWtq-?67R>jnWy!Wq7Rq1GiwBtu_~-@V&z z$^3$bo{L_86RlqM4yMnOVkL5N$JhU3s3FrfK$u}B<^uqR(~8QUur!#lY4h!#h#!+3 z^~mdT-$&~>v$J-t6YzbGgR`lYY*r4C!DIDNBC+#vMnPJmd$N0zHsuFmMs%G+-v^)X z(0#=?vqgRy*3}>&DLBJ07+R^?y6P77zTy3sYm%ij1j;|L)8!?FmFmrdu${s&uGcf1~?TM3$57J~}`Kj?8jAAFYm6Xh(g6^lz*~K(cU#F)(x{)6A^P zkLksav*$OD7tj=TB|oCQFb-Z&5&FW)Z!_$C#jwbP_)+5f&bJExy_7chUcZ4c5TdI+ z(Gv(d2usF8?V9G4Hu%HDSNn>mg-fPL{(w*HCqM?Cu;!2DNtM+tgrBqaR`3lBdY^55 zzK)_L3l&8XU6RR1J_B(t1SAJ%7zaZwT-AA9Bc(mG7u@0(9P3*)RG+hATd!BMo{u{tDc~Mbgh!A=3z(+ z$vMz7tYNx1o!uUi*epN;zK?I=p6(k4`=uahDx0q zQ2jUoMSVAKpnP~lKVm&CYhCb8Qe>%|FScGS%khd~>xK!!3=KKG02n0uG5&sii}8Fa z)cfqtX@4%qTk&?LU-CiwQhI#@pL%3oSH17B(*c-<)c5w14tv3#LxNqBUE&wL_VB=` zydd-7zs)h8)#C^=DE846{d*}r&xoIdm6H7rQ`=NAIpj?PK(icv*FZk71m?HOOZWy!^XC0nRW9 zhPrw(;WhDSo;FHt6TU^$rBmksvw1SwhI7XmB>rZbd-Pu#^yv_0XuR+Oz`)6R%nV~_ zlhOLNc-)aWTX|TLawh%S73IXfh47wT)kAlUHui@=56DQTeD~qprxrwaqPKoTEEd(Y zBklfX;7zo6^`8U@P*FAV86*uMAVoOC6d1}S*%=d&`#iap$Z1!B=@!o)7nIlJxXrH5 zTi+4CkZBaSV(1^dhA;z(VYbi^ykCzI@TG1ZSAO zT#7Mz z_dW9Pv8^TcENA(%Ta$La_PF&TpFx)$0#b%E%z&XEut87QWT91}EU!^6gzftlw{gE& zOwSTu_ z*Y8dyka;EdzgB_*WcX!ON+s#8F}Gics?cLt#2f#ri8*6Jx-a=*gVoJx}oIOPx`3!cK<8U9q8Ro!HBK0Ws1B@pZF9xl@XFWab-RQTO zwhQ@?a0iQ9ja_A*@hS~^frx+hi7VtP{`XQ^>vf`mF$~eEg}x$A7d`QyUBT2Ra?M{o z(*H^q%s4jKgi)*@M+%VPV3D_%i=H4@Xvq;ddo|~;;q#;aIc7NYFk879o?pGdEI~b?88X!Z=3#IT*V>4 zOYhG1H8qP+xU7SO_qCU=82n5~5N6PYP6J@D<8d5=rD29xGaZ_!zn@;B8=3Oh<7rMk z)#BclC~rkCRsBl+FF>aR7&wGkSlBQqny=NGC1}^6MhekyKPGPs(+CDhd7L_ck&Z*##Ay zw-f8(NiGA|UOLO0J6rpzM+{%3;c@#B!VFXGQ2-czHVquW7!nv7V?W2nRlmE5sYRX7 zog6;$b*he+Q~#W#Z6IpRUjiTl!xOFZ0*ks085>o_IJW9SsaG7D!4L<^Eyg8bnr?+~ z7k=MCPy9GF&8?RITd$qUcjrg-6 z+;R~B!+P@Dq+X~7wm!O+O0*VwD?JeEKF;7=M1 zOa6RD`%71P!Oam5>y)3wbDaDt4dq8f2&aLKP^|RdOGzuJUlPW!Hgz-(`u3hs(x7zU+6BGL)5-aC7+Ml*H-Q zvuO>H&rq8J0cpb-RxS_7Fp$Z;tkw|Gzg-uUxNt*COYDHqyf1YWN;sn5GPPrR#bCB5 zi7-P;PXYjj)L}dW7=siK1)cTh+6D@I3c7tioH#GBk=~wX<91PTX#!-d&%yyRIQVO@ zZmf1Lgvp+_7yp*K+$T6-0pg{5qB%Fu!PO+H`-S8%mY!MajqC5z3w5*pd7scfMFzq;O{mQNR8_a{o&=f&Xjxa z7%h+3jPT_9V&6Y1Y=87BjdST2(9b@bOMGRNeJ5eothGS|-(IzjQXTmD`%?F<+A)b{ zu7xB2TeNe=ntk;}3hVG+gLmbS_DXdzZbggSw2*$;BVZWF3`mF@B{|`g%=L8|cgo z({}X48jLDi^ZUP14djzJPCZ?Cq$G_OK=>53t77V&pVDtzex7$&*x5@8G|?nPSF;B1Mz zCdX~!>uvfv*h!M4?p|X8PF`-Ujly^UOX=fxvBT3Rfw;)Ns*U*@e!&5klXMn_Pzs&mH=& z80?z65H6*UB)b3@wnUt2VGN}g<$L4RVYIZgX_O$T`bIr9Rg|EN(HZ{98+iu>Q&j*N zKnn?a(;>27-e>iu_Pu6*xiOGcHE3?@OTEEQR*-;;{A(uqKiwf9131HXFtqU6n`g?C zw1I?n`6!>P2!&Jo8&_)C<^D8r&vy}F7?k{%h7fXu8AQ;O%KyETqT|aqU<|3WcE1e> zpY~x7)6W)fqSN!uOGo{b(B*JFLA|vJYB&YRkgS16U?VFJ>;k1*aZSIgfnbjUb+$)&XhmG5uqc_KT55aHL2q_8q?sc>$YnauxZ&E zxq6vVvo*YgFvHt3C;$eAs>psA!&`B8EMBRvX@U+H&s*hmX*Y8sEf~dHGPj~PSWMra zHvnYtlEgQ605VV{s@O@#V#`Q=qcH{vdd1P%pM%b1 z1*L6Sb@A&NjDnHRfPcwg3}^Upc`{=iz3yn$lSuOSvP$9DL;Ek@-UQnAd^~==^s&3V zewqJcsG$hHgD^t`fo8?Om(q5$?jVc->xTJbmz_@$+@z(WyvhNKES!y7Bd*4DyR}k@ z_kE*R05VM5uxIbEsx{XL<H?HnIWIx4IyhMQf8k1jdpCBuse2CQ%dhSmwm-eWJ2vgF z?7fVWPi*{Bf?W&ZDix6K_?5KfK`R{44ZFh-*G2~kYVEShDB(wE?u{P9~WiUNYr1ICW84_WfW{jpo{8QaWoVH!VI)oWsHr@(q5|p-#TEPM0SS3l@n1GKdBYX=qWK)ImQ94zM_`w&HdN zMzNSBDYnh;w8ZwAsUx33JOBcE2xr*6Jel!xzLSm2sfmf{v6@{W;|n~+O3)-FMeva+ z_eJAE0Qibw>lZ)53>Hll02r)C&HmnRNWzoGOC&R>5637k)GdBNn(IKb%imJWH`2#)PFWDs&`3C%znl%f&e0Z}{e|FP)l=G4){1=iY4OGu#h_fF8ja_Aa-l zk1{rn^83VO;;<1U<6&s!rTgF8p%~1_@+`;sm^rm|^=!ZtEk>AO9TmIk-%E)EjI#hs z!`nS_%d_o``J6Nn-4GU40pZi^R?RMnCl&(NDBSUre*;W|@|0VQIdR3C4YghwzW2=( zWL+I{uQR*^n>xq`w!S^Oj(i5qSP1AboM9gfb*l)GU-kN>+|FcpoB8EdW%C`Lk(39* zn>}a?sJ7e@%~xqyF+qG^w1VJ~XW6bT>Ov{LZH6lTNl=n>7Fji?9vwJpPth;;Dyx29wJ{KIU+S z12EM7)$Py1#Tnh2w%XXVvmK4IxE9=&6h8cTk$A&563g+f7)Ao95l#bcMFRkaS{(To zFb3s;(5%y0b#e;Xy~gmeY6tpPryR{8)Ao3Ew#VNOteOF)VIyb5wUenOWKOp{JVG5M zviU`O_5JCh@@yI-ex9%<4n?bc3fVNf&E3l$(h^*O0xE7 z+u+)pDm z?~YD0!91?DHAzE|vv9g>pf;EKRI(hw1v&{pvQmG&DV9j z7Dw~3&Mxk0=lya+pmSKI?5Z=fRFzcZp{c@B!rsr=)95$ijS7FSkzTiJ*4U&$K10Oi zARlWu!x0$z>?Eb=CU@pa!b?R53ENp)JoGohlMzPO7Q;F2ysK(D`;Xx{C&CO%3Dha7ni_&G7|t2?|fp` z_<}|u_*4QX+6s@@5$6t2hI#?{8(^W085bc&j+b?JsBaQHw3gf~FFKdsI^R1){)=vd z?4J;jEu7&54E1z-J%@)rgsveWj@4I!i=yWeGPyMO^cCAo$y(~Shw4`hZsFz#Gn91n z17P5dZ-|7IlJlb1bxf?(J~X|0`gtFQq8|IQ{ZK)hn?bK%YRG;|D*(u_C;ErPDTLuX zpw_DXGme_8%Cn6y%!n-a2AdS}nVIbjGQ2Pcj}KXI8eKa>d{xLWVFysT0fle=nur=g$IQ470N>jB$~_wVe%e0`1O@ zC^^fEy7(X&lLLJDVcjTtX#g2!*x1@Y4^~E~m^bNtJ|Eh;-@2GoLn%F<5f6+}{$tLM ze1;k_2*?i3a0Z6PRLEXeQm7aU<=l$LjdHSyatWvIsC%1RjQY$R)E5wT#bCa*j4(q7 zV;}$q3TB!H7=x{aMiW`gn(#5^_2)lCirhLoLT~xe{=rF|eS#XP6%KR&=-TU??Z-;) z1L_ToRrdIj0p@hZEJRS5A|;D?FN%l}C*(7hco;ELyvCD^3V-Gz5ff%mUrk@ zQtsr#N{mmdJumxct^2?gRnN+IzjJMVFpSG5k z?tzuq@y927I}?}Wx_gvR$^fRJw@;qvx(j-AUcl7qAm5=0%>$3;GRX(L7+EA zf@Qq5|6WR7MQ4AX4N%EAJSN7)a01l$uv>)SUt34kQ^tk{L?jYtx(W3KB>))$2GC1I z`>`xVh=tJ#HOCDYJv+FZZlu4|sO~uwlHfxA-Zz7BQwYcr&Ts*S#y?jI(iVA2$VU@cK40ekDl-KN@+nJWgn(jkP?kPsRPfWgd!DHWE6;LjP8Hb$aL2lj{O&CuI5ydv{y=Ko`; zL0jKJnBj)aA^?Vr4;+6FPwvULd4D^MW7`%fzd!v*MT*;Gj8K||`R=xbPv{60&UJtc zF@Gxgr^j#~^2pu(!;a3d4rytBGU|u5xb)(S(1r?674l1ID-i;6hBKgmp{L_Mx#Te) zKDT@wS)NyUgkzQPV%JE5^Pcj%*-AWWk-Doic#I*Qh74`-x_>XFgDurwUfQ=#X8NY9H=KXh`!Upx zcU>`9yxu}M4Js;002r7#p8b8%O|=`C?wLb2#keq_p4$hhRo;1fx`@N8p4PsOCa1m) zbb?Guz2)h`p?9rfcnyVqXONE3shVxr6OX&&FB-fJcw3Qwu-*`L00MG>GoXQ?x7x7w z3ZK;m)sURdxB3~;6335feqUA(IN|-=xy52lcEu2J*9~C?O0^#V7);Jg|9%9OSNQmb zDD(jhTc35`Tm;LnzGyviGFF_wmF`f|iek=Fvt&_C|NrwJu;_2p zqg*@x|NPsz7i@@k`B$_noB6YiAzDB+qx5FL^9_6K+TJM(G1*9`dNvI zt0@6B66anBGhmwBuLn>{G%-O#Bd#JDdRn4AmKXiL1_{k9wMM66sVaG=>oY@n@MVpeR>w z5;k=HvUA1I|N0xk42tPT02nIxlL}!Bi}(C^aP^*+qc2<^_Kb*dkmGl`Xsl*bH(wBs zt$UoS1dt*ARcJ}{#D?tp8faSTJNceAZ64*bl}COKdtx-lF+pknKb-@xlz8+YAP+bL zCKwu)r8{o7xm3Ro^b;Gl=;@K%Q`h8<$%UE!ODP6{dNiGg26$(Ak#r3LkQ> zyUY``H;+phorr0#(lBn`y z7#t7m2T$a88w|a~?LeakVz$NKc?!hWmjQAgdaW=LcGqV60a_X$AR2kBU zDX=W1&6~fPPx$9+c#s>-?HEU4S&HciAfLg876S5tGvI=uQ%8Ty3vwSR<9FX?{~bJo zT2%f%>$R)0TPx?c(g)Adu1<7UyZiGX%#db6(Dd)6H1F7K4P*G&Jz?I{kfR4`j@frc zCFnO|QuMYdDKd&c@Va+qJIvs|r&J~DJ3av8=vF=e4YevvNl zB?tKot|}0aFPs4n3u?L#1 zR7~E{N!E?;(Wkfih|%|K#{{0E{g0tWO%L&J(IyW*0$`Z5rTu&9%Bgztc0GkC^;fPJ zQg`oT+uU-oY%#r<4t{%sNs@}q7w8&|96tru6V`Web2MZ;;nY3~Htlz!epc7pQ$JRl z0UzVhA)g`QEd=BbXTZN40JDt#*|w?P?=VhDrRav~^9-#5bjB;!lUs=-z}<}i z(_rJJftLQR^2zOpK;uSlmM;pJTT${=y6tyZr4B6wH*Jv5kT?ke1;7~yz)+lVtY5MG zJ@mwiE4ICTa%_LZ5;T4~u~8)Xz8yHNT>tOx8`%60!VI&vo&XrgQt#`)7!0Mz191|K z`+ni9x--{yo$S>0SLmJ<#Df z?r$OAy$EKGk9v{MK1k>@H> z0c04P*c<;4iYB+XOgD;0_UZ}4y`^C$ER#)7>Eou2$|U4pPd6;O+!qaoGZ2BHX+a0a zF;$;;eLb0FGQV+*_l7kbMl$iKeejwoEqC+&eZ^3l$A&NiOC@{Dzn7AO1&<4i;rShL zeo0O&s_JtT>W}N+dnyxmKE|)U(C9H6iOsn-jS7&VH9#YFn|sgP%5K#_q|YxcAzXB8 z6U(evwLVo)I-?r--=Ym`E~gR)!5N6b&Aez07Kv&gb~Kz`Tm$}gX{_NOR2RG0)oI9NWf4Q zQk>?tjHQ&v>r^e(n4H?rtHTMvOii-uWNkg?oX0v>3{`J(5N42Jn+3q|j!#qt#_(G< zWD{Q%Lfgy|TQYJ_W2mim+!O3-6NK?rz=#ae5A;IrdBYC)A)%yLTdwun(b9FTNsCc* zyoF>1=cysSrzwL+$YgIW;LOPITPzb9kKR;7x5$5LQ(zTXA!D7x zfU!8?whNFN+6}Y5nh;?hG+GV{>0;8Cr_<`pRi2;5z@)^ETK|mpJ1~M>| zDp&Uljm#W1W-wM!jo8XBd=$=7<_E8^XZqSV7)S&7t{6s>5Pz9*uP+_|!%z2tc^HEx z-43Uw;KgGQ(+_~I{*eK+1THahva>YC?TUK`h~ZuNgU7!E-=nEf8%@_iADKv z=NVs#4bVl!yIiIrGnEwIzZ2e;HTO9hoR!@bfV`Mr4ZyRzX73T6i+qM3@eoiLoPh!i zt&NzrJvNP_3hl8M0umotl*m5)l}k|0y`RnpAGaGa;^VfN)uGp zf3K&DI*S)P%gVI7v2OeUHJ6hEYR04O^q>+0sW8?$Q^FCMJ6 zg)|0lQpuONGI;vv*gfqYsrx_p>~qu)0foaED8W!UkA0z*TJt4PM;12;6Y(9V`#)wl zm7*V)PrPHzBMtAqDkXjS=Lj?WOw0zr;E@mhdqBq4&ZO&rcuh+;RiQ?&%t+i4C)Mw~ z`@Vr%x@{K)xD@EU=!7|40=JoKd9;3lf?%n;+o6NJ8GZpxAMb$d^$#lF#vwfoM(DT@ zPz0QT3JmS+@1^{4FZejco@byLC9C{b&Ln#fl<|>0hm^Bxn0xLOgQ+6oH$hKQj{q?6 zwiUmJJsSqHY(`hpjjkm(MhS#&h6Wi0no2*#RN+0qW@E<@xk#L4vV5k0gWa;#e33k$KVypjSs3Dp_{LmC@x9!m91rEg&yIYgqBk6qdX zU7-&<((!|AOhR`UnXrR*0WzT5`M*+cs%k!5?vaR3h`Ry)l_Gffq4i5iiR`LT;6>PX^dnki^qg`V=MZx zNp9cXWo65bu)Mw;_*IWMY~=nGgPZ3f!VGz9814U_2DnSD7|K`+RVMgNq(d}aRb5=TJKa{4PS6rTAo}geJ1E<^$iF_sT=hW5_$D^%DBmiXaHhMJc zORj1ChG|I%{UJ7nK=yT0rH3nRuTO=&2rWM$|LdF4T_Xr67S2EmhH5_2Pni+9>v^m* z?pIRlcZYO?*O_;<=XUss#c@7BE=tgPocZ?UszqANfK`D@rA=LoA~V_8OW zQj@n3V-juEgtnB*GHBs_^>Z#B;W|1JVudY$4A+;!KBeXeRiJBAZg+m}hGe-ZRSJ@b zd`!FRAV?D~kNg!&MrHyKP&}N00SxVU)hBCg5^Wc1KQTfcT0TKh{~XP7fpF+v&|AlR zRO6E?28-4rgc$}@KLKE{Ehu{qW9a1c-zO*;V36$2U%e*dd0traxN!Dek%eOi*eiT$uIjkwLnTZ4)Ph?FK1@FfHN>%&gf3$O1UeGofxk|!z%SU^33*D%I4&+<+Wzt zs+vgY!2hlwe)iHwn1P%t5CB79>mv*pgH@JrpWo8a4mCM%7FsaXO+D(bL%M6H`8$D{ zl3gm7FUV*@Y)pldupOZy&tIWwnSYa;)m@Tc~imj13j%5&s1fGHuML^uQU z<=!_{eu3zFX3Q0Nj%vM@qPLhM#X+eq{rS54&rILgg2S)UP_%LvVFupfNdOExPR86Y z1|fB934PME>&!8D&mQ%hL(4I>YI7IjsUO}I)Ge7<0lJJ*OHQXm)LWgXk)X03-#s?V z5x>s-bz5{9cZNCMiZ>_+2~z)#bDNj_-a<|f#(1i zF4v{shB2TC-pW&);MXUuLS1CMB?`SY6qsQVLhEugncOW=u>|z9Pwe7xgA*gm0IuK% z7i=p&@!gaLO#6*a<`CX;VM}|7(>*)wBBUv?Y{f&nxsv<^O49v=z9n?_a-KM8Rl1r7uRja+7$83l zC66GWR5$}W80tZn4hjA6W@i+|Cj62AUP>_4ynfr=(aOzzui}Cg3xlgP*rjVA%?(LVA8Fz|0-z-VHa4Rj-C>WBbhmfDFfl zFMJ(JVomk-Tj`1Jd>lv`I&Rb?>6$ELBm7dKbzX-2Qd*^efHL6>w=cJuBo7yQ74PEo zY1vM?NVvApkWKTNtK)-AZgMuLGvoX>YcJj_6=8;Y4(y(PPs3@&jY=2;-YPFO+sUW< z27JyGdS~K<^n1zfGj%sWb*LhKxbX&t02w;KThA?7B>YU37(UgyRZ2P-JPO8lu^&DO z6Qxw{(wcq6v@bSM1 zGP~(d5N6<}wgSMAsO9<%#xPuB`UdwJ{rs0NJ7M3L>C9r;Gr3eqsBAW_K{4D=(-;6U ztUaq~VjB7^aJ~uTt{6ogIt;bgNNnh(O?{Xpi&$qK-2q+uQzMjyr1 zm-@V{L!XBAy4DxjH-^Jss;uSqj_1lcEB}4BN6Eg#y9vNpjU7PJ}}gh?g>ORLi5IU^~2Z~GvfxHnv1LzJ04;bu~a7& z(k+tzJsX^d5oX|}zt#KirDS@>VhLk_TIzo+E#D4p&oafTb^X$DZA}`Fy23{Nkx9&P zbvC*Kz%;}rS;logT0hemN;ntUJt2QJQk*F;kf`MhqV6r4A?ZXu1Mv$82nuK52SXLd zx2{LwEowV3uVVAj@Si*0y_s(BD~;vj^no^v09F2q;UVQ)gc<%H+Ws;s%KnQV{V4$j zq)}>UkPrbuKu|)uK|neM=~6lz2PuQ@96F@COX*TNB&8ea5Dxz@H_m^Zb=L1JubFc% zAKs7V#d}}1KYKTGI{{$e>|t%YX29j9pvk0Ma^>c{cp^`JRAnOO8x%J0=Fbv*$63hr zm;)e#Q!LH}i|P!)PGb{EF?~`gzRmiyWc=}twdICv{Dk5Q#4~^{&qXK07#@P5&K!oL zQM^_X__W|Z84HZryKm|sdRhhZA7;n~U9{hBT`|-~`@+po{`?032K$#sJl70M-lngo z4&KKxa;^;0sk@V{26D5^XC;(Nku$#1@971)FS_TKY@jtj_kqP1%SYALtDKG|ZFw}Ku{o>^?H4B?}G$ib-`calx3HJSw(V4Fl#5die zni8%UVq@OH&4A;@*7@&6$@`JuUk1(hlhsajT=wGGbB=3I%+Vs4kQ}X^K4Y@sc{!tC zM?nuT4LmXrDg#5ePm6M^o~sdl``Pryg_lEI;C@{D;s$Q>kT~KQcrGW_r@|O`E;n6a zTgU1;p5La?A%fI;{5k#et>dU=px0!K9-Ev+-Xiph!44b#9@dT$KL89*KO|mUry(P+ zYN)eQlb~l*=S4#brnO`1^6@muRA$V0Uo5h31<xA9Ev<%A@%IEZJE`v3u@!x(rk zm)KX+!Vapo2^9o0L zn>bpO9|HE%MTekTlKhLSqLjc4|At(%m>2*IvYQcqx0w)88gd$H=5h6Alm-tghsC~qv!)=s z+{7KyLRd9DG!68f5}(`+WpHIEAxj`p3l5paE!}&8xXfCT)tZ|5iOoJul88@(@#R$F zOc(?IE#Wm&t=mMZZ$oBEn5?_27oSiytz@9i=9`# zg}=*~H0d{2q0+HFf#0-A(vD1v_;bB{_NRilKJ;7Csq@cc&bIr1RMu+fD8|J-xs*3 z+V^VwvNGMt9>lklCnTgWg^b&Ar2Bz+0O}l70X&1O+a5;YiH-ot)Mh}2A1lJE;7o`&xt>2E)&)Ze>`=T`( z(chk|I8JeUC3EfIiLi{AW-x+iC7UohC^yN{@lA}&firn;6{^#jn{4+<9TvX zCE^)Eh#{aaFoq{!=z&ivF8#YUg{oURy`AFW;0d-q=u*M?0gi7&%{|K|>?;Pf6mqy3 zyv~dOFc9K5d0aDq*a>?kDf|W=3zsE?ChqU+iBWD~%0}MxSBPxfb6+k6$WW*xfSU1C zonw|UbVM*+YwRIu;Fo>tTf#z^1Gq!l`3s0=i1&kla$yWl!O%gSbXQ*gWTKgg0@;B# zYRG63FR9MZ@MbC@COIrtu z(~4VbZyv4bNlzEpUMpb> zOna)@Cx36@_6V7GwB;Vt*DD5X%tvsi!FtaT0D~(B3idTaMQx$b_i24BW;I+) zQB!W|H}W@J@^V<;Kv{g>p{8vf0ZfCEG?A-($~g^r7N`HQS;ntsr}0pQ-Zd7KDxXo#2--JKRZ#7i z7dFNF4$@kp{~VC0W;->&_B5)AF6Jr?t@q(y&6?|Zzwh6RQmn$%qiY6j*5kDB5CUYo z2YT}g>bctn@?xQbxPQvKe1iFNj~0R6DH(n0a#sVQ3HnDuOXQyWHRKo#-dEg+1&2Jq7!5q?)dn+gS-r!*4KnXV2@LAF=jqR0{1o>Zd6>EOJtwh##*mOYVBLj&=D`WT zqV&xYOZ{Cg)VI_yw?KM@A-1@M!sD&5h!LJGo&@R&1LDV8Y0oM^K*cZyF)%b@=zWlj z%0cO+W3(op~DJKPMt+zS90YP6aDHrAtUhfUZj z%X(tOMG0rhCKG@6&<`K7vs^!{_LvdZLY)A}K;_4@utpj!w@XxpEif(@NvOBQkHJa& zT6zBi!OJEG*U?>$XD--`5W%3ke?TiKke#xE$J-Z6?7;4}5tUM1`#`#V6d`U=RJ3ToJ?>rv`@Cg&ygb2W0oD8H*&Kl7aU4~q<_S&|*Oa{eDTtJP+a-a3vt1au|aY z7%JBn|~0#l4;M9H^W(RW#^`?p7F&)YxF^#U_D^%}Og7QggO z=N|qF_1r$hi~4U4tD4C%+ziE%MF1Eo+|mE8-xHE2#=QKV{afs9qWrz0?1+^)^q0=r ztv=d+LTy#Hu~`5z(B{StD&r)5*{&rE{e8p7*$=HWgwtR z7=sKL>h-xhk9sKDZO^pq!t_2D6Tk6Lrbspc`a877hkQXSS9eNfyk5L;Gn`rD^#6Mr zge3GZuG4_iD`*vH3MeV9iybUMq>;&n{SF)zf1L430#jBteFV{1^^Ol*x_7w4H zc%ljcRl^wMz)KbsT;h2GT;NOeVm>P=pHN*Ubvjcf^ot8pyoiDB@ zm%Z?J8nZ~V%oYK*x{ZE@8KCZf8{Ta z_yM3gs+XsIYGDitU?^!X_RR?{-X@0l&)>D=KCIBF;ptSF{JzQGgqsqIS*diD2JJ%l zrxNSBc>!Qx-tK#K&A{B=H`aP*>fDNQ(J6kSxp2K1``P<<@y)Nq^Uu?LW9tB>K}#Us z!gIfLBR@7Z(X{dLO02uY}*U)CPX< z_cU{M_SZ6TeSPIO3Eb8kjQqK2=KwO;Jky9Wm35Y3mZy(i83*T{TBw$`Q(~^!#8o>!GAAGbULvU*9^?h%$BnG;CDyaOE0Yf( zLwc`+#`xHU@zA>!lh<<2>LU+6vdzdky(DtwkqL|+^GAFdoY5hm1{i}f82TiZh_(q2 zMb4pV=BaXaJ<;bEkArF5-cZZ<=ei(!PyKfwR~@|rZiddbO0GvlXmlOB>d>Bam#ZiK)#P{|2B7gqpF)K zneXM}sd05|v`A)rPWg9;dmo6p?u!JuQ>SK>ie~~d*^4~I1rcqWjgz4GWAPCk}cvH0_h>3CK$tWFf_=mkO(t} znM3GhI4jxEJ1a8ec;vJu>m$501CrU-BmYea$Wk(cn*q`zH}vmCiRC5k`ZWWII@KB3 zK9Ui#t>=d_Zp|9QmWE;yDe>o~v^4mTq0t7Q3}GQ=ug#Qc+r`%?lc24dryQJ4UhlJz zT+wuD-d0JyM?6E!<&=PC7=tPp`nDp2&Te~Q!&6slb>;UtW(M7DYV10HGzDjUftua% z_y0>nIXNo)Y2ba84S<0<$MEkK#L^B!xnfsvc(!E*RpyV~I}uMe%6{c%2>51KugiL1 z+XG}k8p(_lI__pR`Y^o{DGI$0+HQ{TFYy+sa(I&SR&$0P@eJuw5YSf`gWBb*Jyahx zi-tT~(#-8tb4zVvu8%??`@i!daw4V56cwI{t``8O7`KM@rzfqHD9m2=ryEemW!W6@%jgQ@9y=TpIu|gz_dmy=Fko zD*0iaA?p_Y%J!i!1A~qm2Sl*;g+wM>-c$R415Ti6I88gCjwg9O{Z`q~rt0zQwiSE% z>VokpQxHa#)07u))=fMpg=oKwA6sRaIwfGrjRd!4GNy6DC~fWuS!G1 zx}NkW15Crk{v*oXcAZF8G&k?JnYS2(daO`_+?d<5%DfaM3ZsS*&oFSgFS-rJpb3WF z6u(LJiQ%=dbFtg!`_DkXzff0IQ3NWd@1+cm73Skk{*R%|RWuInG`JAE0$@1ePmR1z z!;E<9i?!NitX&p5jr}nE!Leg#K1;dPxmQVuRF}%fEPxE}(!~N+`J>rGNN6(e{Lrgb z3r`WNNpWpX8TJ6lR)Fr&@Y3#k~hlZGvfeDQ9`Pb?QmwzpgOK3=Hc{9JC}=^d~ATtKDyg@i?e-{IJKZ@C2DLG8x|E`68ZSbp!(HfH7!a zu4d)aVIEeT_Z>~ceVZYTaYwQDp}hzh^>l5%z##6l_J7MLS4WoNPQ%A(uF-!lN>3AD zcStb@7t=tA07S?gm{L7HxN)Kj6nwsr76!l`e1Rf#uq{3^xA%eIO$H?BM(6> z(FH+`q2*f={|#%<=ih~!;bJHV0D}pG()o27(je?I!XBz0w6#gVwv?Eg=br;RtbxycE5w%QphrC-Y zMq6rzJjN=o5!vWL*)QW#n*YQ9aFYhJ3K{AA|L@=S6K`D<0tl!J#-Iy^ z3dlQKc^sv4S~{OjQ^@Mw7kO+>qeeGX!E#ipbYUA#epQsb1w7zpz#m-)!0_qgt;1^u z;(H{t40lnDq>6t)UZZnne$3t>u?g=%K56rq2uul;bz5ZilukZ0FET z^4yJ~*zNY>yQ|apJ3Ds#|L`jVWWXtgfVyD}dSGb(V%uI~L(EbWf9Q);45C({Rg*3B zWdyNLYbeTFhiRz;?y3?zIFr12#R{_`j!t<5qF*HG`s4!_kJOAZOrP<>FiH70?Q^ zIH^ZlxT3CD9};3`dn5odXtK1V$b%d~eCX5<+%g?FKYp2!p!mZUS_+aT^W}qgOZ_Qf*sVa{}A(XFmnC1 zV3SD6UWh-01G~)y33-U1p=ZB+Xg&WG;u!>mA)xOt1|u+3(yOZM>sYPuN1HgJ6X^VD zolSW+AJaW>v;q%~Js&pGRT@G>;eT#e46X;jpzO$Ze9a(>#><>t!c?N*tG2J3$vZ3W zsVwU0*KH~Ja`B9JILQkjgJU7mg={Bv=tkDvdq}IljRPGHvM0mycvuUl)H$E)1|Xh6 zatQ+Z0b?+}>|y1;YnSU2o-Cas{e{(9$bm!0<>s*{xi#mvg^_{8p0TSmp#PbHI}JUf z1_xv+38UB_BfWa?AUDmh-j1q;AlTi6w7q5*Aj8Mi>iSfq zqE9@vgH`7G(y=uP#vzzqWrvPy^8JVUjCT>w@H_|t>W4AB1VdN1Q$l}A4aW2gx-!mp zoi5I!4;+GUeU=kgyMF6&ZU$bZ!88Z{8&(}QR{#u-E>8N_3>!>XVaEA5(MRHgrz(rO z-c1x5vHk?>6!!dt?1g#4K-ceyEaTabJE`zQEX(TiTUNHm{9KfB1 zh>ybn81@Ms|DCl*$%RvLW(EmD6B_E#V0xFp$BB+Ljgda{WzSqF@LUgQV?CNnngbRx z-bOGh&d@#&h34mO_M*BKG?SMreLnr<;!hCIU~zc_aS+B}diiQ^`$4^4JxJuvxv$Fo z(lgplQ?`CWClbX98okp2n#})Ni5FHK;bw3>c=+?*i_)(F|Geuo%pYP@@HbsV(1#1^ z&{AJM;4>+)YudRHG)FOTXO3GD04z$6m-zQ>4|y_&HeY)<(OJ2P~hLLi_a7{eM}uObIB@w%o*b&J-&9m?k`4xnc-c!_seNMEM2AH zhzb7DCAX|Y05B|mEc$ycS|W-k?OEHw5~^Rgbo?R3bA!Dz@Ge~zku}uDHl$0q4IsmV z*rKwpo{2ibi`cresr4_Ol^{Q`9gY?!W00zMgvcFH!4;POM_?8%P zmLATPo?7fn#ozY&<^KHLCq-JbLcS@ne!8Tw0CLQ(t-}K9_L}CS-zv*vtU`7X^}p= zVo)1afSZBOQ*QF#i_*z&LgVYAG*{GCRv5EQ2x}&dk zH$aA9tCMEOiKOQ;w+Ea^*8|cOemu%Hp8uBm;M8(?Etd@Oo333N)dc_JHV5f8%bQqhSq)2>52jD5C4qrQIZ@03%_aBOg$(C!a2l8hq+K-H_r}uu-Aj2dB$j~OSk5oLFDklAt|5iF0j!HE?L$N1z zkfxN(97cC*%LU@okbe12X$;0-35ISedi5@!M~IBk_oLL#GNHPEYumPY)15?uw4DE^8A244!W~Xs^?d z)>~(IgDPVDdBK;2eWj0`{U@I|!`jRY(B~3zL%#9K0ZfC_7{$Zq>^wda9~90Hh;xj; z9H;QL%Hp(qVd>U#m_cu(y7_7lirQqFFiC5)Fx!|OCHpgOY#|29rv+iXo z&WG#`>cx<}D~8|TNw^udn7;yGm=6j3aLs^v^m*0e?W;!pe#csYN*V`9s-0F=KBEG; zKS#_Gl9UcW2A0%N-%-WwP?|Me{$w=M(wO@^-Un4Dk27LcUNcxx-9S7;`{mcSpD+fS z%XvzlHN1XF-~91o?`CnM{&7Lrk~ZP{1>`+ED&38o_<=M}>qN*CN|2yXQPz~C<__3fJBOH{9lOJ!?$&)r{P)_f9=P8iTs zRRliX_WMrth^KVn6kr-o*gu9^fEJFvJ&v(9#Po@TMjM>;DOK{od1or>-AASz8=V zD1wm8wZ1sMjP~*GyU9|B7I!Eeuc?T5hPBH+rD+(0Js2v(7xcuQ`H|6u;-@cQD_{J< z1&Q8bMV^=J=KRC)?-%O+$52+|WeGO}Y3Spbe=ka2;un7pT`f_04cgRsX(WHOfcNx}bXK>)@sQUH;C<%~zaS<)JgXA&(Y)`^9S$fwqeoAybUt zbhYq)NK3{4?a+mpCY_=Cl$S(2B?VdYo*uh4!qcFKN(lkY!Wdp(j!JKy$i{6HYsL_I z!jhYG-|nt=9BN-)3dhMU15PIdO*i&76BX!@?roCaVUv@$KiUdFAVcU zT0o4OutuTG@tQf&7b^9YO_7BDg{`eiJwO)~Gv({1ljq;MLC4kU`?^Zym+Fa_N>my$ zh{8_yKsXOE1 z-W3A{GXdNT_CN9F{yhzGN@jl-2RyrYXK8Qcj?1#aFIdk{`?E_u`_Cr9x8)tlmmAHI zvJU{JL1;!G5b}k%R%X?^;dze}88gd^w@GLG=8(hCpDeE%2oTS}#Q*^zANe3&-j9<#StMJ$lBm;W4~BEw_v2zg=CTU%1)A%@BFp765}w>VVYswITjh z;iy@0NKft5!8RM??fDy}_>{yOy76}1%P5@oXUZZO5%Nu&0 zKGr}N72AGdede(FvtDn;#Da)dExsZ1XM6eg5530G?uEL2v+jszkiKl5T!JyUf}s*G zX=&1G=Y>xDi7nAEi=6{X&T}7-7=t?) zI=mZ7-}|U{=^O>}>WLn6!^42vB!s3@q+daG`^HA`H?GoP%?AG^dRJ~40E2y4HqteN zxRI#N$}7llv0xDUHw_>1wVD1S6j!h44mvkY`+8x(yM6r6_mgEp?AP)R7N;N1hTc0t zzK`F6CrzEho4-+56pMHUYkUZ36~^Fk*~7}E;?b!g=pP`W+gVvz|MS+S{BhH(%2&0H zv8mB~#wAw_eQ(&{P6JxC#QeV(B|nXv>1&1r%0(U7M2A#gUb{Iv<74F z1Vd$6Rz??dgcKYI7%_gi^YXEkxe>Ss>e8O3Mljb^poLvA%&+&r%`nH64uGMs`pw^u zpu_(3Ms;aKl{c_Q_^h)noPN(4Z+u>D>gDjmpsk*6@&U-OYwQ*rX!N1grOL;Rmh-@q zT)hfwZwgoPvj8o2GS%f-E<_(Q(R-f<0joNy z?&@6PHi{aauWRqF81|AP;ARM_KwbFvG#vaIdw!jUqE62j4D~l{!4YedMI9NG{@8yA zI4rfkmS-#l#ChG?0>}^>{5I-UUDqv#dt{I(Cz=VdZm%0wzdg>qyO>2@Q<~RR}HP$ z`?PUQ1g9wYMsthYzISyzy$og76>bLY`9=T?ILl#w&%Uv&gy}?X%j)nAD{6gCifk@x zp>9pvnE&<4$jplLbzTKP1~w#J1?H$Y;@Er*=Zc}vBA$*i+Cx)vwE2B(lv23ot%y%U z*5xwFEf~W)Ff?IMz_3t1`r{bOIQJ_nNZK<4`=^c-UQgR;PM$1c`Xv1?4P~6#@ON~3 zexh3Z_oAd<%u|1zh9vv9kfenpe9q7&_7hD1MZ7Vtb!ig{IUhj@mPLkMUa#sC3B&*juG@`<)Tygn|d z7aBJ3EmPhsr_KDbjQ#brD977I>Z&LWIp2Ug4R3_K05G_Iq*}UWPRU~yYejjBj zg-kE`r06SJonmP6GsakGbqso3Ge8D+!95XX%K&`|%7DfPz7Zy&>xU}H=vx@lrRPpA z6KpDoXK3hwfOcRE-e4%CQ^*5t^OWAkxc=PTsOf+!hLycs zxEVx{CIK)w_|N|R2wFxavgLDEJuNWHW^UUxgNZdsWapEC&b_0f6ct5IbfA4o7(UFi zt<&j|SmQK8e(_z2870nsySM|%Egs#H!vZv+h-c_ZgMfa+7~Wql9OL>kmg8fX801b* zG+aC}Z4}ku;!53)dlG7|A-kQLb;XbtN)0!|LYKhOzZazcqv88=$5i_+$)%`$K^tY3Dm|9esLb&OBFW`I_jVl?I5e)`T2gy~w`ecTJxs!QH^=lfZDOv)Ui zVF(}t-ejkz1ZkCxs&4R+!T(#mz=upPJbmo_Cwh)=^Q9t3m%WAFzd|<{w z-apON-wBPVaiSyBbIHrrH=dGy|8n7i`#BTPIjmtDvRzJp!ae*qw2h?ZlGEAJevNRq z-o+|(g7jf(&AA|)K_C6{e8VA(Api_*pa>1qUPL*)z|+-?cMvL!Ngz#D58d83xNGVD zM_{q-iou}w1nxAfIg_mXdm5-c<}j`qFvrf6qz8j}RH#ooc6G7jmHJA#&9(%2rOZar ze4pk-0!+iwims|;`%{rMNotKAjAoI`KV&4Ozv7eJiL5_CJOe==1at&r_;7ir zw6=9pe)e1i`XhqMCQsaO#-8I#lpO8{Hy!;6B>lwLD~53+_&d6*KR5zlz?|axd)jAo zk$bP_F%{k02^!XO^qWO8+WbD8>2zx~QhgJ4>-0dsH$(+Un;FwTaLEj6L>i!MFn@$W zuJwwZm(^kXM$us09xmb;Kt&MHF^u6O7RB)HS?L!wmZ`zLDq64N60O4L8Gd#CIHjw}nMUD5~x| zc1lL&g#t{&d@-|F6G_d7u|?9jloXLU$KWxAd8`C&%QP@HPw2oW#51s5P9;8pF?<3; zF_Ad;J|qxHO5I}NH?JlR?2nX?@mfkJM4d=VHM2^R{2xP^H2O=pi_*ow!_|K;O3Gvq zfoq1lDjAWJN4qZ|I8MoZNT1hG?|1Jyaeg(o;5QA_j@>N)$l&zdsN!{81{(XweMYw2 zrRRu^&nie@$E*Hy2CH?0xR@aS?>`YDXzGZ@-xB{?ueszHSnU;4z%0s5ncU%~!z zwc1?iAb`YBK#mUamNzdrzlGFt6J;XDJUiPq_ z!59L;P`orM8#J5&meP|+Udx)kw1j=HT7!cJ5IiPdcERAmCszz%7o>1AjL7{4z>v=6 z?{dvhV$_j9$ED&f7GGnfN7UagU?ruVdSi)!Ty+F1z0nN`AcOlHi*nlM)i*Qa&myxA zF{bz)zc$`IUW;Y-9Hzr^PqTF<9G@Zm81B0- zjt|0I)k7H$rkw%$hINQO3UfhtzflwOv>~z4Qs}LrtjCF=kaThVOq?enH{ze7^|d%4 zpmP{QFc=y+Oor8_#XzU_}lv4dKHaDTYUbMDzj4 zHILbp<%3LC!l_C3S>}kFqWcE*iV>d%Q*sFC0>%&mh8A^DP<~Ay=Gfw-=UYEOlGbO( zG)3CRwz&|(kqMxw{cj5*xY`eH26Jt^^?y$Tll(^Tbs9**2+p>qoH}Q}1Qqt*_kZ+V z`p1gwPv4uHM%!bZlKRsC8M>9Z%L&hvK@Q)!lzF|_)X%&~C)%p20xEcq8)h~65P#Z7 z-vI+cg#=>=1w&7THl{$1&&ml04Krl91Rqw^{s}4kS@31h>)cOWgYo35DCN)Xz|COS zV+(*`kxzr*n&CHRbZOwvH)6F9Ra!8T-9_lbJUcKS>R~|CRD9-=KO? z@|1PMF!r7-|2RcP^P7NF_1qt(Su@7B5P!Zw-*X>Ag$!c|14Ezce-*s%M?a<*wBi|~ zT3%bV=ZRyKmACOMkm&mx3H+8ThRl{dxEV}j`v5T5C&0c%%P)7cu1jc!GCF1A4$zUj zV74p%_$mtJ=qtwg9+gn>IY0*aC$4JFW$MnNNxGdESp<#R(sl>gqWQ*QJrh*Uxf#=l zFG>OP5GoWHLpT_^NCI6GqnM~=OIyq!T=MT9G(FLMG01x7HnWtH`s&g1D+cf_dAJ#* zhuAm%y(k40J>|YmLqM0*@9C+<%(=r~*%Qwx78dTtLjHQG*AhP9@O|+a!mC9hP?U3vBJ#&vJ3>k@c6TG={3WL8MA)hbpEMux!HlI zgdR+xba^%Mn!PnYqm|np4_Mp+n1)%=hispS-v)52Ht{?`fzmU|1mRDAXO?i|U`rMX z-V#SVLvkC03Jt~(dD%S4CG@C?YD`r3jMKCt#$|3lQX`#c<)zbio0a7K?STJUi4C9* za5F4mZvtQtk#PWDGt6RuU1Npq(1S8wN~y=vn8z%m6MN@)>+U@7sz>T91^U?sWSXE! z(`_N!t91`2ug(X9!~UYgXpuo{8uWyE)BeFG;u-R4AXGPC3{hZc+v-M!oA%ojodYwB^KpZl0a`7;`R_$({3coBHG?{m9D|BVitMWw z76&J8s;?v+ShZBh3~c}0F}tyOQ2i2M8jf!0p7x2e3B*gOa@hPVrg-qoH+bpz$Fx(i zuM=*2%M#)lstO@g=rD$8F!aqGKaLamf}4m=x2TNJ1PJf zDBK7OhN6~KgOT19SSFHpt0WfBkldA_#N}!~MXgA^k9dZbOb8VQj3EXLrMTNc8~Zb! zB!bEGJ@M!S#5*nLtMf=Zmnf6tk8&dV&6YY>v!?=9*v!GtJ_2M2;vwqC!D+dh@-8xSDJoGWAq?}mwTE;m z$G(y0rqbda#54Rzf>2??7-GRt6|^>aE*|3XJCT!^UTzpUYDVE^t=~~5f6iRUp$h+e zdc|OFG6pw8B$hP*1_-H9+jUWz&eNDvzcZQYnu!%xx#7L0L~l*hm9!*a$Q1Cp;gq%< zAOofS6US7NdG+wSF14ejvFz>r4`v)TdEVDk44-Ata7`kfVKN3nbrZ%AcR6`d95qk@ z4a0b%sPn}H2wm_|h>d={1#{R(Y24N$m8JA628c8KW33*nbOT^ujXxg0X81aoWxrI# zz+3y#bkHOJyj2K$x8$1|%3aJ4f-8L?)j$XN*t9T3YnA+D*K1c;?MjidXKZ5mdCs+k z8TM8^Qfk|o2=NRn;Sj1@FoyWcebM;OC>dAHlh!D@!-OQzi@gH1Kjmr4v>!Eb1lxY9 z{;yA|?rsd+Y53aDw*Bu#DdP0@-*-w$N20+<{5Qmuv(9@NEbrP%#G>sd8-(415!uaw3X6k@-xP7^4sjh*xrNQt2D&m!T&Ntwfz$S22DJ!gX=WB zG*)E-sotxR(5CYc>$5p)aK1nj7Y?;-D53pckJ9xGAOk=0>d?mL!;WJ)SzR14^&4R+ z&j^F;a6j3N(JHkRfDnJ$#{fA9LWK=uNCZO*+fP^cm|~xmt&b&XlJ}cbF8hwJ5{ju+ z88sSNo#OmglnhRg;7-G@j&%SGEK;7`*9_lYkagW)NO3Z0>kp&24r~IJ&RhDbj$9q1#24mw zheb4CdaC)ssu)r@z%(#i?&**s|2TlQ%ZI8o^{}m$vSwEHPvnVt;Za1OqkuQ!85qJK zRJbsPWH2;Ga}b68-U#!c^=g;SPQoz;X&>)UUhYd3DYeS_O2z+PbcbNqz|9arg7f>| z)6g9Hgyx!o=u_ZRL;C`pAmWX|u{)+%hdn)Hf09fKgo7o%WO^s!0c6-yoA=~&o{qPo zF){egHr^vRWUw(#{*g_71jQmFp&Rj+XamkD2o)ZTA?0#(Nk!uQ?Z#@!=Q+;~8gba> z0*@RCIQ?HXW(O8!zKe@J`d=E#^ey1;Q(}{{2EZ^WVtnhG;m#c zd>Wo4K&bFx45?sf0o6n--n~)!Gm?z`jk&wG=H`Yu-*)?uakZ4s+ibr5?|Vbs@HyOR z=m4Jzu%C|RrZ5)05Ms{Dd05aGZ58xej z-T9iR%u$bvnHz2NFn{o?GcOdAYB5kqwGZ)I5Dlc$AXEe}hP2Dax99E-Z8Bw!#aPYn z6T6xzkiGgwF;kex|IjGJ|KaxQzPdJ;Pr%>NZQXZ&_y1g!(2$WX|GPj(LVB%WsAQ*! zbby3JpL+B4B}42n@+p*ck;RpQ?Ky{Ts=7UY^~}y4hXy9mZ|s5xxow;;Tt%G$GDr_6 zK0)fAx4E5~DirvgDa64TJm1kFPj}vMh9Vx3{eN2P_P>Q=zBEYx56j&Q)bb!ygs|T_ z{qpehgExgv_P=tNaixWhlTZiBN*L{1LZ&b!*DA;c?{`*S{nluz z|M%Y-9~r4wbmPhOpM38C{kkY+l6+3FXnLN$71^v=Qce5Ws~~{hF)~t&) zcMd^@v7QSPjmta8MUu#riqU#vk9wi(CU|9z?1-;Ch7}MhA{avk7^-m(b&aRBQ%+$_ zwv(c$m>EsvwEv(QJ11Qhjpv4%1^$13@@rmjGyL$~1i&D%k1Br6K)3n~pR>GXL}lEl zZq9hxt%IVGy|o7Oo zH@F$X_Z0U2&z0x@DGe@EXn!A-d#o6SyWJ|)*(JvHhKdrN%qb$hn6y~CQM^;nkOIC3 z^ma(lH|rfs^Mb0tgUXNlN#&fi)kb%nDu0by&bSX^a(160p277ygo*^lkacl|&UWA#D?MIp5FZbEt-aMb0DkwHTe3K$fQ@?*lOV&zb*Zl zl>TG<6+<|B0Nf1E_Hg(AJq=tn`{vgS)9yoI_`RPzb#T3Lv_by7n1`Jp>2{mgZTFFFT*gY0NI5#zIcS6 z^(PY;Q4F$n>#4EsBNKBWzERbnoEbtz4r9mzLrXCo8G=qQzeXz$g?YtbytM!~gWda301S{M_q1yU5qzttP#IYx+@8oYv4wg|%eL0QEJ&lm zfsw)kcAUU@fDAGctvnL3o@y3HRSsLq(WKtGdpR!Rs+5L5equCKN>m^|4b4IjDhe1w zJ{YR@ZPRBf9y^ughJ;IF(+1h0ZQ^u&9{64unks8dy4`;x#0*TO;ASY0*ag6_M-;4e z&0wnZ%}vXy<_WzFZusL=fPpK6ZIo5>#g9I?Aai3d|qL{wEqt-(c^Xy zDiDmJ5DX>1X|RT5aH!8wo730;N_|t0g2z)%o-2yk?rUr(t|fcLFl+?>m>8$6QUDCw zQF>I@49vUX=nSX=H#cikE0-VdTe$JRm_U(;+B-uwZ7~`819WrD8HG0f*Ye*qT>h8` zmSJHikY#Q6}+ycP#^NA-*UreuPj_!5E4zixQ~b>+TpEMzpS+eFfKGuJc-z z>buN^;)u-cE!2tjk^eE2$%(4Lod)D#;-i0019PHo?=^!-jeO1nd_2S;P>} z@cXhSj2gyJd^vh}l0%shT^Ge}H@)5G`%oz5YFo-LC1F3b3(Z?hX!)X7X~-0Z|D94+ zyAuEgPIPzwYlbLlF6u`--Bph;q>pMSPZwth6nx)YIJ&vgB~{4hS*o&Lawet~#{EwJX(~-X8eoHJ#uo-5GSJZ9xR zB9C^W0a}YWXpZ<8-XqnYj}t!l>^zyyuGA2aPDOYc4DZ~4P|?8{$}UHURj@L-H0$`% zFYntbueK2zyz4!WWxtp1R5ZnyvD=`2VguPylTo)zHqA#uaaz7ap zUoukHsL=WP&|*3H@Ha1!l14|FW?O#-Sd`F9_Y7iQ#>qE0Sg9p{E^lBB-W4?2dcTJ) z#T3C!GEa+m20A7P6+Mih91MNjhN3l}#U-n8z`mLx+|enAPB=4cteL3YUuKSFk4JWu zhH?x_xEVaLPXRE@Jiq_tU$lpvnrfh>fI0me`PhR$|)9-PHv zS1x|>OGOS__s90l{18CxY3}(AJth8+bm0)PPsIHD#Q<2ERG^_399mgX+y7hB@6#dBZm-yx5 zcWeJU(laAg2sZ>Rm|zT5VCcMQ zeaZ!~gq1<0&}3Udu)k)r%chc6Qu>%>#eN!|-hT|^y=QPU^won-|2+-Ev?PB|R%O+? ztC^k6qP^`sq(1Ai&-+dr@B39*TWP{%aCeb$4(Q7a0vl(=Io_Z(U90dKQGqW?qFmz58I-3hCIr zbE~r{*&8-htjd!g7ik8sM>7BzwBJ7Lh8HD@3e$+&OgK+XU#xLcXcb+Z)Rr2(w_DP{ z7<$s_wSNcbK~;ZJGsh1U4!F3gsWhCgPvxq)WgoN$3&p5pH3=nsX+iyPH*?4H{RVaf zLjxH4n^?M9=gItWJ7#9YEC?$TQ`1r6No|nXVLusB2VpSmV@6d?5c17dBPV5#FJ6?k zQZW9&85kmlM<(}jYjjR1t2V$!OIz3>6R)&fsiLXx%%e@wrmj)7duLwy>&Z$m&F2!=*5lzT~%i0bkgYx#SF z_0|$cm^BbwLNd zlo#s_u|Z}4I<8C{&^ze2LVj!{4nyc@j*DpT={;AXNISMTOXmm@6}_$pRZ`eSJwx#M zlM*L_;R6_2CuKJ+H0(~ony%w!#%dYzaeZ96^X`V>i_8)ciynu9e;!z?&9#xg?kO>b zd2;bINSjnF!WkUDwg|moa}7LYt2jxz(e^ANSiPYBXUuyd2J;&!do#HJ(;$BD)nt%MH^ZGwXLo5^m;zBSqfuS6O9b*DFY%WhJxv@m4 zg4y3Q=)Ze)7>Y;7Vd~CxOoa`5Z^&GiM|y1-cd!M(z#y2{2WRjZu^GY^2`#8g{w4US z@}Xim*;K!#RHD>31`2NFTYLHd8J;A*e_ipzYvqyJ^3|6sFWzb9rX~!1@l5Aa-*3{( zZkCY7TQbv8sT#b%{e@-X{darDm~ZfL`j3V_S{6cp3{y9){cGAM9AmCUu1YDcXFyAweqW;^o|YaT zVK?Y{iTV!E=G9^l5HEtE84R^?xuxG;V_$Ifp^}UM71vu2)f79P`GJhlfWYLX{9m@P zwE@H94$?(w&E`1(2GOgLe-Fq+fxzGGXmFBQ^Zc|m%_M)Gs&x@7QHyl_@v6a3I898lnh(Ly0*3OkSOg_7 z6*G7%%Zs}TV&PH6DMuV17s!1`ZDsuBB#{eC1LO(vhbN71t^;5o&)k-Urvbn7dxI#b z@TTL_kqvo!p_VZ4rQ1VyzdvG3`zoU5Hi8e3;R6E^QIloMHzEIROqUMQdK)v21dR`= z&5yRxZ}NoV{2zSU>wXOZ@go>o&tKoNMCEr)NyABytr%srC=uDtB zPizHa7!aRFIt`e6YG)TON{QFMj=>p(Nfww=nh-qL~5u{!;cvVNC3gm28NQR z{n5*{#428!oM&sjeq*F*;5T8N$x7&p}1HUX@;LY6#y90oG<;ogAVan zDvK5-DOa5Ton}N5@$OGesN7J6MB47wsl;w1V4{8%Q#G6`<0#`8F9Uq zxqF87GHh+I!9;$z+og9TXc+&wv-AJ+4+HJL9jxam?}WnB@ZK!%2qbvgPh@LMzV(~W zgpau|WBaHGKWo$Z>Y90oA3z2fYb=isvvZ4$mVSk5%;MUyF~9jq4Y^`g?g>U)SgWg` zo?%N50un+nbex~sb7|So-B*DyNza=!D=ZgqP^2VZ=UE^iZIk+;*#>xN=;ZO4Qr&^&OtT`*~6;#pM3V!FE2gfRlU2y}*;B6$GWz8d{ zw$QJzJnS;-Wccj7>-vWxD<<2n*};ZV)c3qKKTU>!gb@s%!BBdB=1#l_lVGFb@9*9R z(bqqyA~*iy_1v$S8#~9sBIF8;;rzG=(hQsV!vGk13|oG}8IIzK6YDK-RUUaXeavq##3?k&KgGn*6>bClW*KRuNAsf0m7s;ov+@P&{mH@KxeP znxU;i6#e2w>4W~2PjH5=HsSYTK`IW>>h*YHky|XI%IHrPn4g=-><_yA*{P5P$dI1> zlIBOkv@Z+U{rPugM=GL}4D>@aH_dMel)V>wMTGh%B?}622uK9M@b!F&9{$3@AZ6&% z+iJ|vPH_AOugjM?+^^xz7}Y}jpEQfFFowAuBatoYH?;!QbG_gBWnEn|lh4U$?jlG2lle+dUyDqTC z7}bgRYDlL+VD$t5!!=puzqfrT3f`IXIWOB|=4;<}Zcn%3r*^XB{NOA920A2}*`-4U zkiiTREHSw7T9g*DMaACdX!c21;fAuvyXk;R-44_jC7w(ONDRTy1%~EBtCs3z z28>ABhrLKuor8<^jw&q);~#q@=q7Yk-VK7Kp*4OFX@(vevr88*O1My$RCpTReOOQo zn_-;Y&Sxxc8XL&2DJII@1t~`QoAZ6>&Jf%I$dG+xk_p~JqxTt~*G12a6ehj)nDLrU zKbZxYk(X-H6zU&XEyT~?8^jR|-RB*kjTAeFMQ~e}hu-|WTz7{@?8!Hhr_G)_d#6Lo z_hdalFb4aWW~3R)b(;Y&OtlHPz!{FzKTp5C`f^V5CHAJ!!{cYNhPmcO0Sq%k0ZO@5 z9~8F$GDs8-1(7;`PJi9xF1ndj`hu$5MlZJfI68HRT$0Dx{SoTZaPKArB!OV~_MgF@ zn_6Fg(Q$?T`JIQ0twcTTQQ#SP+rQ0jwcX5R;1z7Yp=yY>0BMGi7fcuzPXo4M_zO5g ze9c7fPwqyvqRG#kpCrpeYelHDm?X&XZ!4&Hg>~G24Uoa|fj#$`pZk>5rm3@Id0g-U zo$r_zb?C57&{VTyCCfbO8MNIXAV~y64;X4F@3Fj(hT=^LIE&v-zE9`q*Nqlk~wczR-DE02fBNw{Lfhz>1Q5Q@e~`GwrV-QQ2ypX66|u-QQb;!C~xe@lbgWErG#W)qlz`oCkGy{IK(&dX6rJ%Gsf2WEu4rSiEn=q|C==vZsUVNTwOUGZx z45RqAShXVa@cg6;z@qfI+5XYuWvq-pOqHRjuEwc4PsF*u>qXqn<`CLr-;0$+eHwhU zAs`t9L*M!RhTn?vaeh+=ZkA8Iv;QQUu?=_|clDMPQh8o?hR{pF7^?Da^&`z-DqaeJ z;U(M4C-Akwnj&E-38(YLOjZfntCn4PIptFQ9r<$0v~-S34EZ%0IA!ZTnOiMj?M(?9!)em={mOoz<7;jn+2b{ij=x#D3Psr=0!0 z60dTsTM!F_<+tNbT8v-#Jg)V1gXwgEe$22i`@lZv6O-+{)P}WO;>MB1z7!bhD$rCK zG=NUprj7b*CKhqq5Rfc_VE_!hn(XO)eTAOu)W8K#IcmT$fyk>G3ztKos}7z1HFQV2rpN?!&3Qh)vCEB4y*@d z0E<$VgI%C}%^3UIYJI9P2X)?41-{(buz?X z@r=y2d3b2_Qh&y;eMf6^p|A0|(1nnkncXE4*pt%gj55*;V!sCgFoa0k{e6q}yP7sW zE_s`hWi!W{Q;PSiMbAk{>g0S+daFw}HbExP12T6GbIM59ZoEF0Hy|$>ROD^bD{)m* zP%`+$zRz0p)EEo(YeP{g1SF4O7y?73qpk04KBqTTc3r``bz?H-U1{e66He{iT`S@s zdIvjf7{i>n0n!Y886sF0FG>c7c=PZyd{n&_7Y=z!*9c;h>mbQ?yBS(}12h_Zq9#7U z*&yfuv`YXDmqGQ;X;-iQ^$jW)^}KB(QkN^g!EdAZLZ^-BhsjYtanj=58U%C)!7zM& z_id35hi(7RNqf-c8_vup)#%7&PUeT{u1*E}Z_@k?31AE-ACd1a)})yMfPp5E&<)Pu zGWdLSu*f*?ILy`Q{tIjz)j-uAb5slJ5aB1fDd9@IQM5PD3iC4R85Y$b zp!*1hvGcocMiQ47ewD?#GH=?LJoIuiH|nOn1dhr{nYLrO-qz9rV{l!{L7HK@kOk-B zY3PC0GQ$~E9BXOO25-A=4@5KYpF*nxq!qNP?u4S>crn>gXi*Dv@Tao#`Af&66)-h< z+$*cJdz@U0k+oqzIv=W&dptM(?j(tNhMi&vND;v>4u&?K>N_&m1fWY*^L>jpFn!^M zhW;>ZS}1#yIxz~8be$E(@WK~)hUeMg02nCbBn99M?Dysfe-CQRYq^*PB$YS!)=a-( z7+ys4E{b#oIY$mH11w6Xld=zwB_Bg+r&gCvxVQ5BZnp1Z*W*tNM&!wLlJBFVoWT+u z4+2s`Fie1< zV5lduP=zztEBhQmo)ne}&1YqZ+NKQ!PKJ7X6X5)eZnV0GJpl#!7VT%L8JLzK=J1)4 z@QP_xtqXbGDtE~)UA^$)OCQWKCDc!xw7g;u0VyLGCePm+T=fIfRhBSAioOIBe4A{) zR4P^<^r83i-5d0U582}_{$Z$2S3!O@H(H4r?!}9emF4p`I0JRojk9k7o8dcK!X}m* zN}=)TW@g&-1JE%=mQLA38%}^}m~M0l3cde{39Hp~&}dEi;|licRQ_VQ-&&7o9f+Q( zkD@*eRGkoz3W8w@3>8gP+aKb*mA~F5e6T>z%Hk!PWfqCU!CwFI)CJ%hA6KhdoKeArokp9C76}>RnGZ9*?{ZIgT>o)*AR2Q~NU+C<9;3=pU-s zu++tG`!#NDwrkFxY48JVz2>minW{-|zA!^Q0}D35me21D0>HVc1e#=a5?bux(J z!K`e?l#PyZTF%ai;Cd02A@^_V66?cFq!|uZ$?z_ohKL7ff4?b}2LG@i;nkA3|3;8g z^?SiP|ANI1MvJQ>rIVY4Lsg&A0j8mtG~s643z3pu=p+~J32t1bx_j@AB0)a?3&Vfwhd%B7=Ra2v|LKR$Z^t|$dM|U3pNoVnDf7#pRLY9x)^~DVnX*_s zKCwg702%sfL9Qo7pK_=t>%WwVP4ytnN zb`8K6fH$M0n)a`Dn`3^HjMxTD&l?_Fb~xOe_dnWpFU}~(q6PX}GnZYv9`5*%)6#uP zpHaky`sm(iFg{_C?d{e;?_&Zt)K?xQQwT@{!7vAgUKT5RXOFY~QPX!D~9A7KlCewGo^fAX`1()bszJm&*1PT>r+D`d70Qa)a89>ADO(6PAU z5ze$}5&N>5W+JyROt&BCbxM>sN2)H?eXE+kQXBbuhXA1@#P8{1A{9f?)v+H3J7$u$d0(hW>h-C26jd z3Jt-IlJVvvyTJhZQ)v%vf-wwCB7ebc+!~AE;%U&c;cSAZ!Ma#3BuZ^xwmVz){i*(! z73?DsQZ(x_|8M3a(UOXrgKoyIgmX4IxFJ{VSWo%`U<@7s$WQ6< z9eN0W0o%iQ1kMnzCfeR1^{_s1;6|pKi~ItOU+t=(e(jzEI+YAXlwue_hNEXq>X*$~ z7ud;|OH#h?VVX!iK7`{P=} za|@FBU`R8ET&i8bw$>ek{1hD6>G`Tw9^_vRLbbX9FtFUaM+avpz1bO8H&D90yYrhc zc`kqWxas@u2R_xc+569?i--iV0Ww_IRj$RAdNV+EYwk9KL8e$TI`qf)THH4k9}Dcl z89&gXJ`Lf15ReXnVex!)*w{m%c9PB*;*qxWU-^7-NspwKgA#OJdB_l?m}g_ab~>vi zGLb(MhCac2<>EytB>7qboWZn?4BPKOX6!9m@0h(pIKGU-BK0@LHx1j3W$a5T)^7na z%=kU3Q<43`TtT)xK4V~}c(XKwC*3$Yxr%U@yrB<*k9vlrRR~BI!LS5|=4PCpF3t=# zeLVeKcZW-D7A+Z<#xvTr__(CncZirP3s#i;Um`!9bjc(VpeAtL#z%=hH8X4`&)+egXq9{@5Go9SQErKUMHP3wQpSsSP^)74E}u=;B3 zx%%1OwQxh!Ut+M#HGzQi5Dd%b^9-e~M@;GT#P&I0$O}q3zBcp`S^0h?BZ}<$r7AO{ zhUtITh7$^;pOloy4gfGXa6i(5r{O2Z`(Ak&KGv}SqR_JEb7)^NlOGx$ugbPa&`j_Q z(bxiHFz<9+QZ5vyT*fQ;gN+{$6C;z}(rA;NBsf6JHI%E`gZea-o_A!>M=-3M-@3J^ z=6D)rb;z=sRfH+2G|Lqga_u^urGH^(uDAN{jDJ5IO-_D8nt`s>knrL~X;N|X@9P`a z+gsM?IKJ8n*dH=pGChzkFV+>6?GbKVS^H2bL(mA6;dofPb=_{88dO;3eks3Vdpa|A z?CR@{ocISUqpSCy|3E!M{apyi0Ku?&eo%F8JjZo!q$EGbp^_ny+MedhKsn>aThJ@M z(A?}V9x|{rII5^1&0rPS1b|`Rpi%~&2CzaVUm^5o$h34t(S2uamPG@1&E#sQQ6wb~-H#pD;_n2=Mhx+DQbSVSqn@GT0|aDEz1Hw34oq`r)c|CG|ybN%6=C<(H4YgMS%1Jn^WmSAa2mq2WfFf${E*s~1m$C`6+N z&S3RT7_U83iTtoY_t7(#fYtG7O5-5LpcCirf#*f!R0#kXrq5=AnIEv$@oM_SN#x6U zr(Yp5#}?=?3>Pe;b*tHv>8X}G@(wTg?GToplwo? zS`*CW;)%*m7{e>638WeHXu<$6j2YJ6f-_L5FDs^TI6QI`qWy9{o;FAI`CzI=wg_Da z-R7+avvXVk8M=l)Z+aG`n7rjyKFFyh^LLDq$5nmGlM{dGvkSNe%M|qt)8!D5F@j+O z3=K12imM9SP`tlFOlbnQ?B{{)k$+FYByX}H&46>f41hsX_f8g^ z;YfAA%-JxdV6iRjcv~Vq`@L{qB2gZLHY2HDuyI)-0YC=&kw6O*aSmE2SzZ48pzt2HE(C z@HCu8^M1YBVG>bbmzK6?z1OhJS@(3-HutiA3+FvvOxq5CX$W&0)ehSA*-@QOdEG)a z?^f`In(#529;b9_*wl{CLp_u;SYe%Ca5FX|OM1EEV<`Oy4#nX^$nz*Wa~X%roO>A68iDc|2Ef z7TKrMuawQK4mK^J0?6>NR8SR+{@Fgz@urBe*NuXo*QU54NMAYci)I^p2neCRlbaRs zdAA;O1j9BMN*&YDVKTS;Fp9#dj(Zw^IV3qJj-@}huZh?5$rvC5wi4M#PphR4 z!Zi2$KR2ydiwwMDD$$v?K?0)F>R~>Is80ik9RjjIFzkS#nSwz>#{6?>mBUP|6+BgM zEOU02r4 z892^|LR%sjcEQlOF-UxuUDl9{ab2MIu$&(g**JEU_6w z{+^*r3qHxk(?DeQG$+@) zwkSpuJ#%*hjFTp*BoO?fN%$$#w{Qn#SQ$0qVfFBc?+0T?v4$$6xg==AJfXa;m)P(9fUF#h zq1zYvrb&K}1^_TD&n_*&8QyH}CvGPXdpvE4oeW$t6WM&d7YG@(x4Xd+PSfH70ea66 zQ}%Zj?hkG!_x+;qF?5Q}D-x<~al(h=Ur0;MvN^j@KV#3zUIzlQLooaSLxre3l!%Dm zyMRMK@$2FK`8wGY^3op9q{2Vvv4Y&nCTvoDm4yNFchGysMMy7RlwR6=egJ1E`$|!T z(Vg$Zuf}~gO4TLmDQQ>F#VS5d9(V8+jCJ)Ez%&$`iEk%*#{~;e`h2rLrtGL&WvBhR zU!j>}lRd!Ztek}UqU1RT0X;-89D$)FS6}J5|t^yaR88GGGig3oS@Lurd#$lU+Oww?e^R;SASY zh zsOpybZbEZ6ZbtYO)SsTWibaQj91sjAU}#e=&KYz!T~@}R-%(8A)#dhLyIQVq(&0>O zQ;KPxqs}mf6p}Nf8CYy>05EjsD2KusGF^wb)5-X}a+Tltw#&;W=v~%0E>rhir}JeT z3Z={ddii<(!L?O^@JKrR_(a@#mwGjF_Iv8|K8$AG^7AQ9;R!UTPeWz`1muWdI0Zw` zFxyx1msy*mE%%2i+|q2Ox0|kRk-mF5($w1VC|RB5Uj};Q56IMFbOK=563YF1dcH^K zroH#3^vC&5dhCylq!lFA3u|Wq`G!3m=y%jDlUo6<4U`q}4M{@}-sI79Eo4t5_bF?H zv~($>S<3qgVW|e3YM`E>kOcyALNJ_xq1Abo9+$JJdZ7J`v@G#nIJzWR_EUkj}B@~OrD+{ENq-oJoshp^Cds*n2Ymg`1e~5t`ewcs6KC+PTzl+G$kQU^Ri@3d=b(KkfEUR^}(8!N1HpCw7$*x z%{9x!ZDuinjSeDaUsCBI4|CD4vsrQmGig3}tnV;4x?F00 zR8*MneT!V-KEZ=AL_n&MW>{f51i)}F((iAV&sA@Zsv&lVO0>E(v9nfX*TMpc6B9EVRA9f+P=wC!Ds!06lKa))H8fLpDN~x zV7LT^T17s?KMcOnHJmAYLs|%|Q_UeqOrR6^Nc~H3mV{2hzYnb8K_*Bu3~U=yT)Zd+ z=9+23ixQ7E34J%V$AispqVvnQgh(n|LrC_a!CQe1+c{d7!r}okuozC(PU6je^jNqB z>8R%}!^$A@iK74TP%Eok<73AF7wQ?tAP|rnf&l{zwU=iPm+cgCv994{f9o_rOI(Fr zr1sm?>Yz85olRVw5S9kB3_qk9bb6WrF!0Yo^56{J#82r%mzI)cu5L|u`jXVX`S~h~ zX4*GZac!FXjif;vK!%MjVWqo4wYnC=B1toTNkXH-T|!W{-oiQAT!wL5QzO(fEYd+h zj}Q!(!O&793=E?}fgReH10nV4&oy@LcUaqn3txp3r4MfDA9>nizNFn;CM= zB22btZGxV%TW`Js(eem7NWU@R5%;v$j?C@9oe61Zso)pK+54$vM52CVZB-T7iMF$|UcN3K6r?AqUeu8Svj?5f%~%>0b5S$#*s0V_)G2FO1t zg_QgTz~Hz2av7cmQqjx2IRnCKE|lN5F0WY#6OIRTSv)_}$k8N3qa=4F2gslkn83;N zO;tosd!#l*)9?zRSn1_}$fESD(6%XR%%>-)XSi~H1@SS00UHd}{pKU^KA?a~-HC4H zblyOz1FtiYc!yS24d*MN*Qx{$jKLy866rMf*XvMSyeLuf=%m3J`uacopmXZh`J#$% zbjxPpTM6IqSN(rhHl9yn`M6xK1iD1?NAS<#f6#$)S0yOrZb*N3Z6l1L^^p{_oslcO z@pcpSeGRRt(;y&E1OpBj`icFkttXVKp*C+q?5y%nFy{b^2~JA@rWAR{{{5tz&tVKY zcW01hARnp+z`$6o@ptg2T|%U0eDIu`F-COR?sLHwvkprod+3B$?Ttuu`V!1L0Mn3j zb~hZ%N><>n@9`yk=jkzT&E0s)uO(iLyBlteieji=qODmaARsRU11=a^`)F!H#sg1B zj#!AGo8(51>K~OyzWx)BneluB)xDxpU<^+0?;*{gd2*fl;%Rs`iuHF^hJ4vOtmM~c zS7p4Y@p0&56z1EHnoBg+tA813M_ca_kN{-B^z0eUaUx`*^Iu=rFDbF7I(^fLvu7`d z#mlm!VQ7c?Rshxl(-4q1f&mWDZjAtcTTaZn7{ln7K0*)WLb8e zlEN55utSk%;O7ekz_8!R5Dza(3JvuV9>E*ABnf&2UL3`_ZmUX-y%O`-Ke0>m(Qik# z0AvuvZ>O&jYNAZSk*E=zx7rn}2nuj;2nfYTYkXVb*Y_0lYlBQE1muHYzz0JKqF)5O zmSL0kCLSN0^niag_50+%+9_^x(z(KMd6@yvQF3c<;6XfPwI>=QNxl?Ashm z<iC!i^b9Ne@}leUNGw$P)Hh1Ip%N6>dlKa= zT|@A+zsExCSSu3s3@Yc1F?r-P2bcy&J{1MLOIA6ra_U(olkAht%XDwKwTxF<>2^nBVrZ+QoW*4c($yek<7To4&Z*TBN@~=v0^)}kv6^i?}cU6GU8>EX;Bjq~)3{;OHAUH!) zVQM|Qii;j?n|@NG0JI(j} z=*0+boqky}Z&H1-nTvV`oAZwuPY?`*VCd>Fk0bB&)~Q&5`2ELS)AtEem5D#6e2qxh z@~~i-QSXPX4MwfV-vpHoq@n$v)9~N=lbrNLp_tn~~9MjlfCb zkOaD>oA!5BZrsLbaUGomn1*;Z*(>(F)&~7nPNX;>ztdlPhwLRc->^tpRyx1`I0mpk ziM9KApw$+IuT=4A)(2gmRN0I+?F-t$%7d`LI?OHXi+izUyaRrR`}xk+&9}Gqi>uB5@F>jk*|({ zHpXa~w+1P3xlm&LN>Ug%l@$N^%RxhX?bno`+VY(0^a=>|fAWFj5KsVu;TjnFlqEnAozKC$zS6|iJHPHs$9yKCDgJWnm|1iAcejS1|!~I7;0WgSaMb$8_@a^o|jye*`TOw*z1H|~h0@HJ5 z&G8FbV>Leq1FSqcYpVNrXW6@*0*0ZS`Y*lHmz3gk_fu*)OMPpJU-Js1o+0i09Sw|N zAUl!EJXf`#hD}p{l(J|DvZkkXYd#yxNX<>%p{kaPBt1(Vd9vY!}lI_ z9PRW9bAQHE=x2ZoR=PNMqpd45Y_~?WGbb%ma7Q}`h4sSkScb2OMourhM12}6&j(^a z5DcVX=vOT($pwS8tR$7n?C05g67w~pGH;7ETc1Vpllm^a*@7|H`(8r2DCKTG0l*Nz z_K_FPfYr;#W{5A+mJk_YX4}B7TJ5HRe!_60el^+0BIF^q0zigcndz71%Ywx$9?=y+ z!d`MN(X9(Zl~3<6_={MFhnb?J%=-#G`Bu~{S%L_l`l9?yvtwr=E5lP z>?;G@_w_RR{^sip02$AFp!_W99$*5*Xf#lrEw!kuA$m*^GuD)j)Zm7T8!6)>HbyQFEEBMX(yx^@SofR zUA!oPY@s4>hED!&=;;a*MVH2Wjm|b&2>O?V0}8umQ}``-6%~i^KzBMjmzBhnD$E&5 zxU2jdR*HSy?=dRGnZDgN^Nzzd@Gg}J zL6-v^3(ny7^NF3#`5_S(?CGs^E?bQD+$f73JbDEy6V36J*Pq4#7Nw=E&HPf5(qx}96ycq!42gla5hwi9lxl8xX~lckjya+ zfI-mv#yYtm_yr@;ol5dsQFFwmSg)FVEfdFezzYIiIBrK6Xi zJ_fpMM4S%V&nHV(zSYtSw*RKVpay9Mty>BV7cWYzCKZ48{g+48`K}KekCNHZOStoe zGmV-(DLdUtlQ$*5`^yABbqFBC<&U%Y46#KT6b9u%yIP;-X)~_k{wAk|Bp4Bk$8;)O zM?C{&00b0)V4wvOsx0f zeRU4C7Emevgv);gkMyux3wKhJ+Iqzm=TMw}Sd~-MnM{9E!dxN#(wQ zn?D|wp*{`#m=Mr&1Oq)7%A61O;rD$Q|BL;#7C0c*4>U zF@B0P14V&100spY4R$yKv+T0!HlU{CKBS(UM6@Zz_9G79FJaRG4)33;Xe%3 zQvrXFX7J#qYLf$_Y(1cj%kgypuph()^>aw zjNu0s^23sL*NK=eo`&swt!r?GKJL&#qNz+Ry$HxdTcb9XQF~L%KY>RAXY-dhnXpdA z0Hz^CCW32j)uqngH%9_%5dVAHyTF*+>5>WG88fDM8%;@3&)~KN0mUI0Zh)aJ;g>_2 ztS7!l;^BnV(y3p`<1fAM6z20nVjmxmq+t)X30mbg`3vcy^vlc}07I4B`%O55?$6=k zOQYrP!b?8l>Cct4wiEyKj7E*KEr`pQ&xq?D0A#pE9&mM(#eS}kOvFopDvRCXcI4r` z!~61~O=O+AMtYp6X9)NR0mUO2n9dtx2oY08Kh$^U1-Y?(^e)vq3c8}EVo@qcxWeYi zVatRGOGAG6B+?88QIyo zDJ>5HGUOJ9%4^&$!ok zBwHQHqUD623g_;8@EeE&TyIpLp)MrEaP3HkJto!bSYVP_J)2qKDiyZ&R z-@_2~s~MWjEP|hxoA>c9>Zb$PRANIw$q0s<=NH_t>1&y}l6Q1BZq;{gIfsOq&{d9q zt!0qFdh`U$Z@rXk|Rwba{M$>Ook_YBTSNUcY0C?dB_&7}Q^Ww)rpt z0i_@q*v=d36&YiF8qAxLQ}h)U`0Omqp-``F*47_-^@A@qKk=9^EDa7f(vW5-p_&H3 zpp@J&24^rab6q8jYcE>Qa3lKs`KtwAT=MJKY2_hRldZ>R*|I>>U>%47(MeAUitRAg z{k>rQv{rTB|Iq%pwjif;gOoT=PsFF%!r*@xsxukiBh6sGpul?ZqO{@79|LDF3X>ETO5<$6{Y+AaK`l|1 zqyF8=i;B)EdqMbpv3I07z%r3xM!3}^6uU!H)ZYAU% zUT4CK1%1D3YC>ou(D!4WdVu9D!{3P1AN33ib`VfHf`JnZO_it>)wVZIYb5)Yxo4T3 z*S$Ob<}Bvy%~L%4$CeW4w_yzJCiO@&=)5GodGR!Kk{?;X84N8|?X129^#+;{9}#gp zQ2(?TG4EznHIy8@uA96R2(;NM&5%UYo$&=+I>Mv5kw-nVIV7JgB`?e1aK>2^DX#jU z{$z&DmOKQMfneYQL%->1QttG%b&mYlYoy4&iktd&`pk0P`o3=DszL`*S^p*ihzI)VX(qcF?4sI4z_~M)F;I3@{BHYG6Zw z#Z2`I_rfn0wURR)lG8#Xf8O27_OtBFGj*;+eHzXfA)rhI12-6&^;`6t^ln!lN2DxI zu>9S1i0hEvo;%YNt9D`QefMA3u(bgv1o_L)4T-Y=7@k=Y{T;w<`Goh935V^K`$c-c z`BuQW?BC<_1sw@(-j9#p$hd2y1(0F>sERO;yY@ZxkJgFp9h`zUlV?vI&Riqi$Lhy7 znMAu#&R|P$-a;%3!N3ECWd96n`LM`SMtrwMe1|k)G=(!*9Wd#i& z!+V+<)~M)PL#5uEm&>KZvfh65?UQ3XhByl_dboKW_oAMGaux#0MlkS#p+6n?v+jL5 zJ{}`&m@HQ9Uw0}a4IrO+@MF)7FnWnh#syZC;tyPqW_VFs4uC-uv-$6*y)T46zEgxu zoRvQf6jtB=rRSZo1-+*@*R=SH#x4947SPMjW8LPl*w5#B+~-)0SwnW6NwN30-ZY|r zrfX*r6WpRl{d53Z<~9iE1%iPO3>Ck8NJuZO)vp=#eNC&{_L`wd;+oy_|B>{&9#g2u-OV!%;+_Ep!v8dAz&QF7q% z(zyamLn6C=Pom8rm*K2FN!#+;)pvppZJZJBk6eCS#iXUV%#Zps@So4hfFc<9!O%ZX zCAlKvD2(JEa5sBB$K0?bllJU7p?UUBv{lrGHZKCkU~hu_w$ByfKmZJqS`;<#C7SE) zb+7&X!H6Is1A0d7Co`Et%=Qz#pVwm~EwxFT8LtCmAeMG0b0e1@q)JW7#Jgr9E0^{0 z$Ujf}=AAsgcFrv*59%4D&%dzdAQ%L|(AV;x$}CIscCXu6ByL&YO7*SEnZ65AIiSdS zG$F01`w_jkVt6c7Goe zOc3Ce0@~NGsk6GE?Fo0xq&jZirPz(OMmNuH1_lC+9T6gz7GshY)H5i1LO{6)2Ep^S zq3)3b-dX(KD4yoM26`Pn>1ho9Coa8?x_)6obnEn&VGMc)T}U$!XRB~ryeMhl+>3=X zXg?{Xj-R19$=uw$q&I18|Mb#f{yMb#dvODKrIH@bWq@fI^l;&G8ptJGGaEO^rB=IC zQTGO)DSUh2EmCI~|as(B0vFv+f4H z(K=HsR}JFKhcW1o@*&OOwqFH+AxQk{-v`!D>GL~zQE0DPje9bdle#7&gL{9cCPh=m zC26zXFg)u9$S`tU#xpke19}isT1TvH?6aC+mtww#H21{*~PC=bCP z42CLUzgr)tmr0EhE@+m0KUA&$%{dF)ioC({M?v zAQPSjp+|T0-F+MSFLB<3VwmC1eG&M6O@-dMZ9i=7i!=NE9{?H5b<~`c3<6J2>7%t4 zIZ6jOQp8@Ck_T8bnweS^t$#=TaWPx>^BH@u5Dd4#(CJ4Fv5uGN{j|9$3s=qEd})jt zZ-1k4*(XybaKB4LHw8<>7L_m3Y54s;2mnLk{z(^{A&Rv>5a*4E%#-R5ueQwN8f93x zxPmPsi%LE`pQmnXdk2s~?kwQ(h);edODVdDgiOHj(2p1WW@)R??s#o)HP)ARP@e`c z69klxU=TS!65yx)(=&05FJ0Nd-R6Bqi#@a5#waG%cK^qR8SMgc|MoTX9zuSA51Gaa z0EQR#KRMwHJfMO*4;VUr;g$+4fm?~MKajNlahnreSN~>S(CfH|y8s!iEFW{+`G$V9 z&y-*wJN90&H>)po#Y8c${d>9p43ZB+g)oMVXnUj? zxV`HDFhnLj$%iwr_YamA-nz8t<7v>J%Z|g4maLB+F&RQ>NP{ipa>@d9NJH)Ghh(C9 zjU9(uSZ*);iWNs{*}f2J5#9}(YI>5pzJvNUF}C^V4fP5U4B}v@!-zbWG;O424$Ih3 zdxlOCsN})P08gIY)Ccqh+zc}z7=v?bEYb`tAV%(srvaOE{qIrYmg`da?9^qE4N#JX zl`pRg1VTLNG{xp+j4AM_xFwW=}tnZLof}#GeZeA89Oe3F*Wo^icJa)qpWP zvqMLkfw(^$00U9K5IQ^!(=HvckV6{Plm^z7P8Hb`uzuziS=FtT>bYnoWA&0(02#LQ zbxEk^IpwUca8s{#Mik&?pKS44Y*1fWFIKxZOM?2lZ?+%LKkdCiFi3)-0cJXx^n!lT zuLuPq9vKT%mUSpHNV7}He!T2(m0_C`1YZ;r|W3$6&bhiZO+U2anUuo*knTG zu5fgruU}BVHgu0dK*b0KDKJz~DXp;o8TI9Dy!1mW#kP!gM}9HC!`~5HXffAcNdA5c zV|WmO{21JC=K4GrFG|l;)hFQ$wnMjtrOI~KU*=_uEK-p@X88|8wOY6}1jFs~ z2i9gt1o6|<+QEi~CZ&RBZO=>!^E=$IMEBdWWmt*V9Q(E3eul=m5exSms$)vTi(k(t9c=D zS^Bj9aMt?YFRV#K8%Q&t(;Na|XzN=0+W{KG(4+kGpd~Zg6qa)Zt4W>Sl|HhNn#^tv z*Ovj;s#+}pGF%o5^j;Y_F?7bgnQ?hH1fmZ4!Rc*0Kbnx>c9(wr83gqVgy#$u2nIPY zG^Z4z=sr$Xa6{IUh0FAPKuq*<26(7Qx_TtDB7zB7Xl($L^VzmFr7S%!#M3MoX%l%b4~gs7Allxj;^^r@{@10Rkh<{{FqEo(AsvMp{;kquDjw`tGg0k7XC$d zly(CJ8HQ*a{yXI}=iV*bYUiFjEth92>+5ftNhKc`e~~So&EL6P){p2HOJRm}amK^1 zEs|&4-khBoWTJkcKJrkm#A5kMt^7tSEz!q&7eB+gCnQ3_d=6q!-LczYkAFNZl6btyt(0oJ?8aO@VBPnxLs zs{M+&c{*b)-EX{3P{4ctX8onkG?#^e>C6e#-nzoHk`1+J{X-LK>hzkU$`)t)x zzjQ=Dpf<&Mue~-hotlhUyKaSAfzzFPU;BieG)os%NjM<=5mJl<4edGDN%D);LC zV;sR<0an8>!e<$15)sG^Cx?q^YF6&-0SBd2J0#YYU5{`gK#?>?)ss-vo8pessap&=lQD zL57{)Y?X7<5LtPJi}%!{v$9L-%|Be2Vh_DjDf)1O_+cTxKA|LoY)TJ#lZ{j>Eq(v0 zUcPpT^3xRdi~0tAbo~k%P8(_Lk{G^JW-fk)V^btT$$SPqB6)l!w5qBs{6)@ft!*2> zbuuv=lN7tff8B?-SukFzzD5_*aJVRW!5J!Nm1O^ZQOfAD$(ze?K{j1t@?3b7e|*)q z^LN%5CN81Y&t0*$aLi$PXI12bRTMs=+heH)G84%&_e`ixjGjpluDcX&xc01LlFuo7 z6`fD<-xoi_87dOt-h76ge-@=*;-8Mai&DO;%TN6B#p(mZeF4G$ zWGEUOf3)xnuBjAcNHvl=GM8c3v6r7{PLFP*PJCDxBPIDsKw(=3`S-Hg&s^an7h@Bo zD9mtg(27y|cEwUn-@%;cOC@|ACs?%Ow|sj*CAU1V*{th-Fb(HfNre0J8T5%{m+!@) z9ByAW@9Id7KXvA($~CJ@9o3c0s)sr=MSB?K1uzXxJZ~4Aq4^t=+}}@wSL>?DxeVL3 z7mCG~JX1I@RT^oN)1mFiuOP{>XHnNTX3%}s$56?ms z3u|1G)UU<5P&f^fj>``c6jjc}YO+=R;uK}_x9}MKN;aO93lC~Jk+uH);%7+ONFtQY zXD}d={Zl84EV%0~!)ltl0*}XehP}-2Y$zPOxbW>_md~~2|9(*lu-~9Hm*J>v$es%q43F7WPXrFU z&?g5u%So?monm^|_0Et3&x1%M0t~z`$pTX$QK|Vhvk33JWcenrv{6(qOiA1QF&#;?Ft}Hv; z>f{v}uB<`B-gM98iD=&QEw!^TF%2tHzt}BX;)+G-q~pSWi(b2%N8#_MfuLW)KQ|3q zd#fLv;|fSSu+7QZljTK&pFm*EboK4SpZ3|6@Rp=-Q<%Z4Xv5o|w1S%_S_e$9k8oD!GMqi=Ux2kVL4Q&tOa>M{+(%4$LxLy)(^{VfCE)5<5mnv%fkg zc0J8M&Q=nzx`DzBo5}1hdiU%uefiWsHC|pNzcK94@K*DdSJKn*D(Y;vCKf-#>l6~9 zYCeMrk(_x?;kV48mSCwae@l@H^BY@b+%j^!>2<#ZRohISWa{Gefi=x8H zs-%@!5@r`Yyl=EsR>zMbgV$BP1!rLVxLfh>7bV-E5Vg4sW1eA6MDi(}x5^!7%1mn= zMGf~K>HchXidi%6bM?b$H3~D_{7Cm|^vzv8-Eq0zu(ZB`-xfbI4xCmQFgkJJm9U@W z7Xx zo5|qVeF`$@CO`V`6~urqg~wGRk~#+Tz7K4!iqvvCqdNP9CwKL5Ro2^_doz^o%n+A8 zcy=~%sK;-E_qCDLBNq4d3V)*LDmg3Mo4;DWI7cYrWJDF1&Nc^hZc~SkbfK3GcXqJA7W=+wQ;FCq`UhKMWvx~wEJeRt@f6&P4 zEU;izNf5to_PXPaLDPzeSMg<1Geq@_qQ##EDGL&zZa%{SB6%jF`gzEXk)9hj*i>1< z6}kpul>{wkm`}HgMzw5eWWuplh35qqepGts9!sUaUz9}UYWU_dWGUV~SM5g~C&VUQ zOV35?Kz*ByTkX8GAycDzcX*&Yr5{+ewuKJ+Psk|OW*&O^{pyD1veN9`ufF#m2p(C* zqi}4=w#Cn&>`x-p&u1_rk{OFtGY2exi?&5S_l>lTJ@IWk)5u^|TnjDJFNX}-ynino zyG8V0@HDVqs;3}>R_dAQxeTA&Bg~3-zIXNtmy}x>zm;dVjPH>dpZ7cEd-F)FpYKw- zLB>Pd(|T{GlGkq8_McmOrO#c~Tc0p1I#$1=-*1Kso|X?Hv?Z;SIbQk|ZVUfhGpU;pmfdn)X{;0&Qs2^3^7xHZ;1m*HpV@4FH|oRahzG+&%a{}uhL+5j^3TcU~S-FeDIe8t0k7x%^_QwX1 z2iv>kyC#nq^gNVMhzZUN9u`wsfW}9Uqg{MV*8LP_c+r(Zf79=SmP=ZCmtS>(?^9J3I-3G}8Q&=V z+^$c`(TktK$CN~9n$KWKBv&NtF)9`E&g`}uG7h}?jWDJ#)KhPDN9FCb#!i!RgJDcV z((Jir`fso-R&d z26ENd&6j&xd&5M&4ksz)J=Z9IKItPj8U0~{Rip7Y+bfHoAtZoAXr9kt^=DD~J=6a6 zDyRS3k4sdyB^rHC>E`i{4Px4AnIxGnB0IO0_*8oPf~VmkgSzV9FG@FgPrsbYV8QXz zaO~DAt!vAqE6(VLhMsq5ZykLjkd{!t&Lifm_Z12=INb2kRA5+k_|WRcQyX|*ul3xi zw`Xj4>2;o6E(dSL%(5(ghPYx9p=CaU^`9@w$a}SwBDl@M$U-lU@=5O361bb~el6ts zn-^>IjJUdfV^K` zej2WvImI+L4Q(0Swhq6=(_BJo%3oa$Tkr5#z5YT9_74E&Pdzauf)Fh zwh;HrTf~aIVh=AahP>kTa}gZtk->fs?}8Vlo!@*Y$l&!eX3Ja#cHZy12tFLl9<8NA z6KS{VD%_9Vvk`W)5?OPm+BoggOA0f1zGj=9u@U=_ZE`NfW3}K(*}H36COi*68|u4o zBys4|oyE^kVL~Fb&S$V8l6?rf)#Aho9~p<|?k?q7lUQ)nLU8z(u?5!*GoQ8<%``Gx zjFnq(hNR**6lBomC|y36A!^*dAgA$i(T9dIUPeE!18;ar0`+RWH&>*8lf9f1O6hOW zdU>4bevFrnL=A2DtbV)p!0Z!NU-!z@8%4VfKMSu&TKvl>k39(?5uVRyuqBd%G>?-T zPsxf`u6o3KauXr)U8mAa#07D;2w!csQ{mJ9{uS-@F>S#a)}7zI?e7<*%ut`qxeTR2 z2SwxToSMI%xL!WINf1+Hl?TZ9M&iLb$YGNKE{ee(_4jEe>v}V zQd5b!`r1*p)?3%-;|JNrpN7tdBtqMK20J2IBT*vwnSn^(^Dn9EqMqq_mdMAZ-tcHJ zW{cl&SG=w8-`h;AlNWx1%(!_e1sRqU?p`{V!P-gIeM@q0^-md--Ux%&x_#{W>ajgX zOpMs+SaehODN?v7QSmfN?YXjAyJ?&`+IhQOtX9IIfO@O?^lnxIhZpC%nHN99$e*iO zU(9E)|MNxnkL?5x*=#nV8C{RPL2{|T%hn3JK(XC7{Og1s*qqynMae5&bivawrX{NO z_tP+}_T|6LlZxds1|j6qR{24j@{U<0X1}pr;Rn3;e(k^H9zDgykV|2P=TZGVW4=!> zssz5%x^=y`L!xi+%BLg0R<}!9ifty=pI!V6pa1;c&_18xD3MH+_0GblqcYP?(8_e? z(aQsLES2jcL(s68*-zW+{`3H$i*>ET=JI$Nn-f5-%<#}nve*#AAc zBw0``<`$)}ce@og&3^kyT=UYL`H%LCyM}AiQJ5h{DrjHbho4DuZlBWIsWqKr)B7LkC7#;v-EJX2lx2T^@uy+E z3W?A)pW(!xzZ;b3&dnaDp2{C67pOGaqG6srQr*J6|7Dq*MEBGVktsZ)%btxcI784y z1&zO-h6?Ia|Gf#C9Fm;eyZN(mwRJA7xIfF0naGFALD#H)2}}kT#B8GYZl6(s4Oxk6 zKJCkC61@B|do{0w@AweiirAw}U$Zh-H5f1c&Wz*oek4NodBu6CIIiW%pNvK5-DCSy^0H2!+Q85n9)D9F&bXZYycq7?a9OjReUAos%-_FK;npaApO8*lYckMm272PPGofdsL;S)ozZ;xww*Q-9^oi|)r{VPhcM3Ah>c;B`Ob`5(;6wlIoGS&MIawN9PFX^?7uMBkQE=}YKOENzU_ z_DYIYa!z8rO&VObv{81PL3Ht_!Qudk&^w>OnMe*8j9LZsB`a6-)Xk$gr;U;KR9TxcI=w)tXH*b*1KV<g)7_9@*F+{jS*fMfA9 zIHZvXujezIB9a|fAJDbck?nX(uQS$Q;#t!t_1<@STf0d12~Mpx1HFIuu#SB_vEXTV zCA?GX?-!*wp>?Hm89eUgs)amq`AL`lCET4VO^BLNSHo|?#bgP_PJg!kPce@OeD{d!fA+B(Ti5oI^a|ua_a2hx@^xwzQ0G3ub)pj z##pFbx4}Btrju2A4lKUG-)kcPcxfB_4IVwlAI~*8IgyHTEtYR+fY3R8o&u zenp1FYn=rFw)?icpIKhUk?(8&qWlW)UH6+&JYhT^* z-JD(20teq8O_{wfoOq&O+chDfimU$HX{UE}pI`GN#t0u+kK`}>6~x55Arxe|{+3RD zZc&ohd*_$4$>HL?K5=rqTkZ1upGGEry|&dv#pZ_O)|*FJD4d3!b)uYisKj*Lx&S!8VlIvo*i&%FXeJdIe2vz=dSug%> zomIO3#V`_YW$qiPE-g&Mxr|i{o`!R#(-dUzTuoa&mto*TU0DLPi<;2vYrEAQsw!gx zUN_pJq_$=A2b#2tO|es$A?8?uOTkugu7Q#!`Vc|!8$0V{JyyvEaWbwIzUbrfE@<&H zxhU}!#r`=661C#P4~?=8PN!4g6H>Cm=hB27eQlupGD1y!9m%|q7=kio@|Yrz?c z=&ZK?{i1a4Rp)=Nr)&GI&eV~X-f+vSh`c#GIM z#?!Nw`6lVB2M;cw_6jQd%uR!6jE!sB!Tn8_ zZTDO@b5hE78vgQhW=f;+OuSev2dje^g&91&-pCl(us*r#;9#(fZ_^h2&Y>6gpSY~B zeq1p)`-a1Q@iWx_S(HZRGk6fmff-)2MKYspcfQlxr&=BG5;nJO*?p2_q<{7Z>C>j2 zn~~w@nZgBUSQ8?r^Y_!hxa>;)Tm~lnFo)>0C6l}dgPD0%?`yeP{dl3YWm#19T?LbF z?dNP1W?))sF(a*Uq2kgy@}sDxQ;vS;erB({e^r`4q5g~dCY{AUhxK^7GKuhJKEqie zIqT!jBiGypy6tG`kL&fXT45nWfBFo~+W>FbH;v!egN2Y`zw)sKXE3)SQ;?xEWrN&Y z2CI`COWzo}DjmFYg{R4y+*bOS>4d@+bqSX5HY;=v*-*M&jB9zd#nRN9v_S$5k}`TcoNCx{I#qNYa94)2o_9IA5EpxoOmwa zoMm^8CyXpfCu@_B3=UcgKh|nelS%jQry8HJi zki6J4Kkpqg(7N_B9=-l9yafUEnU6|~E0mwdcCL;ZuiEqICg2QKbS0ij*m@t<2_X%*h=tEbcEedM%S?Bi`Q zO7|&QQ7a2wpYd0K#(sR7eq&0)0Q3^JShDaa7EHgo4(h9wSf zC7*V#7@iJV`&8;)R2ZF|dy$)a&rKzZ5eq@uF-k9$X%>IDcO&~}Rc?vaN;TDHjx`Ox zUtEwmS|-wxvXuIR{IW&Q;J}niB8<;x@F9}5>K+N(8> z^3VEGtD5<~`%$`i@)kYUA#W}T!@djS*`+ya+|Dw%aULQJ6{>AnW|g?&+Q8yxSo!CR z?sxMUe2HXT<=1w1VoHs!L`mIxbf^7nZ$P=$fznDp@$L4ORxxRo$dGV1aKRZSOp7VV zkbS$NX>JPzjKEpX8d0Uj^y1bj$UlPx3@Mrpb zyXO+$@A8t>btlFgb40heQ@7#Su%|$5!5OT5*XaHIG|0L7{&(`Ev~Ri(r~28Q$+K1t zl4?}USyWE1@>-r>f1}Lxc<_f4rC;qC*yh}zVKULso*2w5Pxxu-y@Ts5Rb6Jmf&FYv zP8X9y7C*!0b`s&kd~~h`8~V$Hr%|FMRbSgmPra5tv1`d-Mu+FYx_@s^ z=d90La0Z3^a0)W4VGgI8n}!SF7VmBm#k7{#MkuyO^uN`}+F4z2JHuZtI%|2lw0$%55w!5LhpzEO~2^RQ6ke;Gut zYG>^ij(I^m+^|k~x+6R{bECeOrLSq)gPaxDY^^BF@N(6cU-ZtosRX;I+wy#s{na$5XpF!=Mc&&T-;BqF)>q12}1Oq+LWc>RhsiE8ifIp6in(T=^V zSD;ZZ-s%Xp1QgyMuv>5j9u1qFf4?X#f9t+!F2nDfgvf+ey78K7yA4}!pX6E7>~J7r zTc`s+?cDny1skfSG)F2wk37hfX8)Rbjy?>1E(b+}4#5jg7Yn)SI1EwKn&%!Sb5J_sG zAj6x-0giJSddbtl$KE`>YAS`7kM{<++Zx(b6+4B}E`Ek%e>P7}&SyAJBwxOMJoR0*=4-zR`CM>ZQ+4^vt0-hB^18&i;AyzFR9XM;r(vqm^S_G&Hu^;Qa`H4hSVzUJ zF_CT~Z>vu_;3_`j!o(a^arEF5GKCrZm?inmLY<^nmgtNtdfd&{Y<=Gt;WBovRr%?% zM#l|{|6a6%`!IZ3zPo_`_yzV3I6lrA*c5DbTNib|vbK$IbZahut&pwvAOXYXib>8nKF%tdyN2 zcUoLz{W0CM7B&K&yI%`0{-PB5=QWe*`3!-7-UL1PF_p)?MwipNYSrpoc_-%^J&kv? zYxUn6d9Kcde(?wKwek$#okuMO{A*w0@xNbhSyBABk1tIn=Z4I;#%6Y^tkCaXa7AM+R5nff-|`G?J@ZKMaf^3Ysp-Oo7s^CGBVW)$(C{1 znhiDX>J!+*23xs^6lQ2x3CMKCte$c^n#a$7bN4 zX($@2UHHcO$g7nUWQa&!Z9JFZ&~jRVOW$9q#x}f+4XS_Z>LB^_ZsazTW_hVk8$~3i z_EDIjeCnuX^BZ|8vQy^9z*QFtyZz5THo0(O=P5TDBbl|M`is9P)mP3!yNBn^;oM3C-#*E3<-2>mLNX zecf`ex+|TK%+k~lUP7BRxcC`fFp~)1=QD);`M~Ng7yCp=_K4T8?~STGqfZTQE>CQd zSfU&8;EcZH8E1NA2>YP8;6-VZLOcZ-yfd8}=BD8#6~B)Oy^^!)8uQLImkjTdIe1@Q z{puA>-&XeZmrW;$!VE1TTiATpe0!p8_Hwy;&g*DmNrS)1)c(PiENUyI=BxjMNA$p- zqf36wX9)kZmALH28G2#Ai|lVjWe3`AsyrCXl-YzUOe%6O-w84GDM5xnk(Ue3P`r}X z=qmTXJR1 z`3m)iPA5rSyzHgg!#Zxp=0mEMMZv}0-erqF4IgPpgrD;nF8;Yjo1!9!W7A&JAs)8IkKLE6|G8Pc1nzEqiJS z&(gQ!i=SbZNFvP6XNVw@Tk2|_-%hJtvX9qp=`V9vW0O@Tv7g6AmjAwcV5zjbm_4Rp zL?U3p8MZ8aML~vZcSil@GUy1ov~xXKZ+xUN>8#Q7^Q?BE;=WE1Cq(L$XP$ky``Vep z3{3()%YJXuf86(ecW~hr7J_4@NDp00kEBl?XmIE#{2u*fC@b8$6dCSa-M`=riX6JT|9(+orWUz1mw}f` z{xh@PS@x7@@n_HKXrr9ih2Hro@@OwT(B#|uKuBTb$BrLhCSHy9ei6?DGkJL&bJ+Thc z$9vv0m&&Oi!*Tkv3(im?Uikmbu#`%O>i_=PC{cZlXiufRevOzvIkSCi*!A)OcdE4# z3ZY_qp6~jtZYRS|Mg7nJiT_*|Y5Dzs|K5s17cuyA9lRh8StViI1}G#AGdDsR8Cbd* zu9t)P@=#e3)@*^hlwrFHwA>0ux4~2D@Vf@|*MiL3VT=wG+yTS%Ah$kD+6Bc7;T&3srNI5E@O2urONZ|>plc@l zkp)S&AVV&^bQ|*I!K8dBS_p3y!Og|+ehE~+59>>zVL5Dn0L?4mP!)7|2q$ac*+-D7 z9tJi*)g^sVz|a8O&>i3T?3b1=M^A8#~ zKi$;OdI@|(3mxg<)KYks0sdx$7nmUvD~x1=Jj-Ds2NdRlncPsC2Nv-{Wj8fevfoCoylF#fboh@Pzk0f zLvdAjXDgIfgJtSaLlf3(L4)nEO$VCofPH$!Lt>ArYsCEQCvVr<`u+<*!KL&e`Lz@%uts``Hf?u4W_i0Gu3WMAr z>lt|21M+#o3to`P2S)lr9wJQigTnqW^E{LefJK2&IT%)jK%Fqy6b?-yVCN-h83l)< zp+gM(6bsM9!`Um)KLIi%!iXfuO@;|6aCIuoNP`>FVL=Amk_jua;PzXvDF^Pk4ZH8a z!})Nm06G`JuXmwu38cFZ!%87%IlTG+uC9bPtDy8lc((?sK7uuMaAyN-eGCsgfqhNT zz6E}G3f)@a&*#wp1!Q~)BRe2(7fkMkYkOc$FO=4YU}8!*Ah< zcW~-G^qhdypJ31=Wcv(br=h@CnDz}ye24iz;Feif`3ve$J^N?SyGlf0-p^X_FKL}5o!x;-m zw1P_y!;42Cw=KM82ZfKqtYdJK11vcKx1EHKoZzlguJHJ`zmvhwCoD+W}BM2$ly!tx(t)28}Pm&Io7~3ExCPlgqFx23p6#(Rk=| z6@E#8K8cVv8HSP}$8~rm6$;&e8R<~!CM?Q?D%tSiEvT0ZpWTN0^Wf`zXjcf|7eUuz z_@e}p?n8z$c&QxnRKTQ4C|V6~J%pQU;r&NYy&l##K*L7Z{sfvg!=V=F@C;72!n19V zsvQQtgshz~rVFlm1yg&V_-mNg2Nefk#UR{144X#ao>AC61`m(Jv3Jn<1N=GxeLq3E zDH!${a(;nVzrxis@aA_Y{S)4ug{r?{4OQzu>*r1y*t!HBpo4w%(0&>GzyRHt;7?}g z&k7mYVdQei%L$XY;Mx^1hX=~8gr$5?V-;)=fJOxPQV3eCfy2V^geaU^3q99CYH=7O z0ogXdSScv55vFZ|5}RSZEZiawD;1#57TBx=_o~2Gs_@7*_*M;`(tzJI;W=$cuLHw% zA(tLZ*a_F{f|&+zqY*6L4Y!)W+C5NzAAD{K%?`kRGkEk6oG^#(mT=Yzo<9tkY+#fv zTxk!sObzJpMtwxV23NTbcZ8npyOHi*%NwsLmFQgd=9ev!8j5W zJP&VNfRcf*AP6djz^YKF8xC78!hM%uPb9R7hU1sv=~y@u2Z>kU(gb+%8stub*OH-d z3e36=H>JUn8*p0&d~_4;%7Sg#@L&!c$c4x5z>j(GOac5=2rt})%q1}T9^@;9DP?fo z19-av%2&biYN%BM8*8C)9qg=!R*&JEMtHIbPB%mEr*KIt40#Thzku=WkkA3sJK=_I zSojJm_rmJea7RCUIsi?FVDB)reFNW(LYKGj`#AJ_50_2Ah>vi^But!wBGWMY3zYc= z@6AB9AF%ExH24Ky{Dz09pZ~Ld4${EmwD1!h^jHdiFM|P$kcAmuW`X={@H#tO&jIgn zLIrO4Ur~Ho1vZ@d?pX~E5g@Xpq(;&uL51S!XMipNgXn1!b@6^XFE*NfucL$Ej_qdAKu>u z)eT|25i~T0?IzHCFC5wj9rnY?1MuuYNM#NKEg-8EjIoBRj=)qKC~gPy?4jZ@SaBR~ zKLMK@;T|X0?FMk;JbgGTA_ zWd^j!gu_|z#4R|L13hm;>O2^f57`P~Y!MVFhG`{G;y%nTg3I0-s7gQnhHW;l2`7~gPCS0ctZ*Pb4y0Cl))Y=If^`Wr=>@{SuddTn? zUTTCqP0+s?GCqZo&miw}nA`@}w!@s4P_`46c0r9-u%QPUy@oIQpv3?j9)u@`;nWE9 z9EH?xVbC~adk?1(Lws9Fnk&0VuT4ya19I0WQ7~qVexXfl@r!-LH!l*IS({j3H$lr(N%Cl0J;<4 ztPniE1~Q4jC{egl43gJDF>#nH0p&KpGAXFJ5kB4ocW;Irvd~fLdI@R&3FcnY3zfxleg1$W5o z0i(}CJ};Q!4cGa?+vlLXA1o(9t@E()0yGYUok7ql1ilG{C&S_NMd*DAE{TF6(QtVT zjE{wcc$j_#Zb*QI*PwC|tWJhIQsC3;&@>J9-hj3l@ZC-5k_EqKL%$rj>^6+J16Sn3 z!~!T%1hel#nG$&K9#kuZb!E`t0en#b4^_dzYIwW`eyW8Yb?|pR40sG#p1{jZkiP|9 ze+t*P!aL8Q!VCDI9cp*LC!Nrw8+N^d*1d4_HFWBSUk0Gh5TqS}p>H6^7`*Zp3cZ6F z@1fKLEcyslCgH;=s5cFteS!PG!Phg;?gxDT6T1F_KYl|Jb^AZ-C&LnWi5BwE!=$B9 zlmXsigqxY+eHN(B2J6|OAqQ;dgy!6EXa#iOg_A4cS$;?*00RXfs}PJ?4Oa=nR1qk? z7UqdT#r3d49B!9{O&j1IY1q9H9+rV)o1wED{3;K96(OAx3{!@js_^PoxLOU~REN@< z@U9kA-41JX;LaVeRSzD}hkd)Cy&?Qy1l^3`PZQ|B7c!c{$o-Jl3??6hYt3Pf1(dad zWNRpP1m@a6IXhTp4>ga$$H(FB6R^V(S~|fIXXtnues+OgZjj~-4EBKRo-ob}3i`ks zzEF|~3;dvxKdd?rbpv2aAlw%WdqSX17#t6Wrz7CZB}j~dOE1HVF_1eBUW{7QlHfKne3SxrrNXu}crYCfWWZyY@M9J{a|`~;ffsH=<~$gk5BUmVN)cRF3~!e} z`TMZE6l#^j#s|>25_VQWtB3GS4Ltb>PS-*22DqdVhCG4Gn_+wlBs_!Zt#CsdEPMf# zU&87RxT6a`?S`g3u(uc5_Q7}k&}9&QAA)`(aM>t~7=tUuVd6U|@&RT~K$%bQ-Xv7} z4C|($!B_a=8$9$K4*r10XW^$`(1YsbKkMdiY8bEtve3cH^pJlUyv_jEGr>E|P=OUb zV1wGr;S&yM!Uemyp*0U2<%Lds@C!fm5rDJ=7%Bug*1#*mP)HPJtc6nRV9|Q0A^{&t zLOm(?Od9Ur1YgTQJ6ZT%4!SD9ABvEq1Q}G|B~{3?4JN5UQ4M%Y6K>Xq_qRiJU0A;Z z8t#Pc`q10}4jDp+-Eh(vp4|hf_Q60?$a(d_GeNRC;7Z~OWIo;vaGjR1;c+(R~d&9dvQ1u+FA;O&`*y;}t zT!4K6&^`!$2!?K>A8XgmTHSj0`oe z!^f#`_YK&Q4lQrOkxb~A4L{$4Ub&Fw4h+tN>;*8c5DMOfH;SR;Jy>ubDwV;ia;RGY zTPoqcYS{A-+SJ1FNAPq#oN0i>M!2*IUTlWnTcF=Fxa>KMXoD--Vd6_D(h0M>pv)_H zuLr8VhIM_=U;w@tgolRV;0QcE3O|iOk8$|>9SryYSw6zcpCJDfy#5)k{{ruPg$gt9 z!FQ_ox;1_!6vkcNQ!cZp2!2++aLLqjTu^dWq!XhrH zvI0KjfqE<9Gd{R~6?`oK?FjI_5OiGwe+Wa8C}a?Wm)1cZahN0lMK{1(QgHJ|cz+XA z-wf+zp`ko%SAgbQ;E)n@P=S-G@a#57r49o%AgdOP(T1yZV5%+@*MoUGq2exBVF0%q z!KU4Cj|uGF0}t{Q1v*haezA= zVe3hFz!~@)!!gF^ZeLf5?fLui|;VxWL0yFQyjis=-3~qe@Yb&6B6?|R|&1ztO zEj(HWC+ea5V>sIg&o@D)78vyuu55+m=TPhg%x#Bq9k8quYIeiNui)-p*zp=#_QR0@ z=r{yF4@0jvkY)@9zlH4YVBC8sI00{bgp!l6UTV(_Zw`Pf%|^Io}bX>7aac$ zPg8gPvwqIdKq4(%N)InCh1?AA8Y2{DhFL6d6B{gHhub*dBTl%B8@8>02YKPZN_dPP zeq0652*O_kcwseU7KYIxkZ&za5rga2!`tFeUJ{mXfLhY9aU(RAft{P7l^lE{4^Jw> z=`GM(87@(UAzR^cH5jiB37Rln3vSpB3w5CK4p^-Rcj&{XyP&Bd>@|Y6#_*j9blD5P z?}L8(;W9HAaS*OBhlv(Y#0q9xLzyG+o()v9gSYJA=40^waj1R*);mH&C)n-`%}>K2 z7wF&yC*9#$4@l(+1HB-t4~+4JtB5ew4~qN4yz@{o09FLT?ZL1q1nvog-QnEd8mJmkCzuO`6NiST9;lqSQwDNr>P)}+Cm>992e9>|1!SM`_u z0;!u}Pzz*x24h>HKpRYZ0VQ6-{0_LK3s!bRogUcS3-|WHSN-tFAbdLnPmREDZ{WEx zNIwq4-$AYqFku3&`2;g3;l|Ifcp7f~3TwYX{qOMk4`?bU zh3DxZ(=r&v09P_WGBXrog}H1{ZaFODfSO$JHaC>#f#tkViw`#PLt_EhDG05E;G5O( zq%fQof!=H3l65d-JzOpU<0T|}se zOz;geJjn{D*`W7wxP%jiaKYs(U_1{btc2-&aKkECC;*iSuv!T2SOcF5LsL=MyB6B6 zgYVWu7YX=X68cHOWgB6{Cb(iVOq7Kp@-SNg%4~u6l%SdltW$*s+u#c|ct`^dYQp2% z@Y8nap$mWSfB`!p%Px4?0P-8b>$~B46L@D2RM-a}m_qFX@QE2TIRv}Rp|vF(wSrEE z;g=)O#}?As!_cFU<2bzH0EHZ3#z`pU42w=d6&Lu>73#UeXJ_F4v+%ViwDX4VeW2?( z_=5;ZB*<_cUb+Bz0%1}R6b*s5LgD6cc>f|)zXafb)g2wWcq?}S5z2>9R<)Q*BrqM=C)?23if@o@ACbV`6LEU0n|KFoo7x8bupaDP60T>$Nh;QPDKwFLgS2T7%np&YtBfIlms ze-&hW2qSAC?<1I82iG>hoX1f12`p`b8ZEHlDKu(@FP}q;7jU>8p6Gy6ozSxzQun~1 zUdYx5WBZ}NAWR#A5+gAG4csyYE8jw$cd+?A+&ckZeS}9Q;oB*AY8rm~0?&Pe^xt9l z56CqO6Mn%pR6YN!o0-&b;}Td*3%An4+NDsR0X}DhX3Vgk1s-LC6YS8P1I}{7^W2b$ z2S)M2m3)xQ55)vvt{{{Xf@Q0rrZ9Xg0(Y;49b(XOJsc5-j*{^62IwUXX*R)N8OSaR zA0=%IJC6(a+BcaaPLSPgC2umc1L=s6!B%~xIZI+a%q$H7)q$Dkpl1LJXBw0!l zNl79pB88NskR^$vMWrN?l0@e@-^|VX59Wq8&eg>SdboHVKA(>(7vcv4++c`bjBu+l z{$7H6OmL7H9$AK?mg5-&~e7F|QL>sX$FwwYL;g|4@-JsbV*U|$aI&&8ql@c4a{&c}p@ zs8opQk5Kb5<`v_j5-cr6%V+rRIXb++&o9yAHFlNbt_mDbiHF|dh$@WvfN~!(xdvy{ zVOBlrG~mNVT=E%TG~=o-_^}l?w&B-rxUC)k{J_0Gac~zN{e`1{qs^qhjflyLVn9H@+kXW&RxJUtU9%)(3RsG@;4HBna! z3+Ccd9ek;aHu_jI51kia+d}kNguR9syck86VB}JiGR1f^oNSJ1%Te7Db5`Jjl~`7XV2eL`1z`6s3=Bk}APnD&68kVV1mzE4N+_y^;jKfc7mkHT(Bvq-ip14XSbH2@ zPU5#yxIG5{p2mG=aL8Fa7LQ}jOvI}fadtA^y@U%dMfNPqt?lW#`!S7$t_bdKu z!;tSN`U9gnaBL@@@4_kFc#X(TF-!c0ljmcsloXe^Co%8;HR{C=!g3`%r2> z#vj1R2Qe)S)emD%I4+35;-hGO3@f70?gTcRM7L<{h(Z5Y6o|vnvnX~BPo77a3z(RQ z(~>YF8MRXI{$(_}g3r>>>Kaz1qhkiP+(54^?7oSC*(h`e!*fs~7i05K{ywHWK-GtM zs{r*LVPO%P6yvKWxVjW;pQ6ii{8onBU*g|axUU?CRN%32FgzlLqr~yd2%IQ^mq+2u(U>iT`eX5t zG@8ob>+!fo4(lf1riu7n0evUqKSc~tLeXg$H66#!!1F3NWhP!zLk)Gzos9;XSTYAK z=3=Eb+UsJI9=gxN&iNRy5Cs=um?4TU#%N=dU5ZI2sBDIr%TRkc=3Aig3M{iiYiq1t zg-)xnbq#v2#U48hvPa?d7~zPLP8hcl6$&rT1b&Fe-&$`hL_5#k_;K=n$43M$04kE&?4Q@$)hCIF4N> zaMvju5QB$KpxD0L6x@8jfrOnZpxg_!dQ7d*z|Vl*$oic++Dh7Hfr?FDwc zME}<)@CHLGP^=P9zC)QRO#Fb;K4L}UKUYA@dUi+X)n*su1#f132iY(dl?h>wKOR2W|m#x+B*P82r{ z!|!6~D~|t0V2A{YN@CP#96JWjkHsnD@R|&2$YQP>8pvbGM6{TMm6Oqa3N|UB`!wvF zjsY`JP!+>wqWCO~R!3P4OwvSUEzF#Y+B%r8i^lp`HV>^AVD&TzKyuw1&6xg z@y#f`1ryv+$rIDPP}3Xpw&9}fSn7+GJMf)9It1Y7UFZ>rU3+lXUL3Fw4~5`}0~iyE za$%T!2uFtF=_5GdC|-(0l_g zlm=97!dstFuLTRgpvhN!)rPCTV{JRSbl|t2xV;Pi{=$8~amXJ$){A5Q;kiCk6sY^} zpI7_i>;ZUpATAt)PlR!~2)-SH>xN?EFx)a6e~RPIk=TC}9+br4Qg~_%j+e%Z<8beqW5fOYq-P3^7H~Wf*0SeamsbB@VU1<10~m6(-oA z(i%*+MNK=*TZfAruyj3IZoqd==-`Z>UC_f7yEfylEjYjf4|(E69cTDq z)(+I!i4OyC$!>fRh^vC|<6hjj55I=swgdPl6!(VV;KO({97jjs*`qk=7+#6OStsz$ zNt_>zk7ICIEWSB|YtQ1Rc-(v*ejI2eedW`>slN&Lu3Dui1rv(?ZV)0ir|ArOc z(e4K}bf8-&c66bCHwyG%=pPjOizok~Ouzd7zL_Y1(*!YN0BQ;0{Xu9n7@vutl_*vX zMMp7g8IE2fuzMs1jzXc)7%qhpV=-15FO1lVlG`xO2NirV)eqJD@%B!fw+oAQquCxT4?^2utlx*O`?381 z`W?i+Fx-C_haSP>5hxvr3CB?BIHsRK%~O~cjf+lWX)IdC;k&cwa1KA8M~@5Gm595N zaKI%zl!7BtG3E-&UB%>UIO95IWuQ(bKFq=;x9~+auDXLCb8urWe$B&e_wmmI-1`s* z7vj-JIQlW3EyhVDc%>9)J;OWCasCT@{1TVF#y91-wgNxB#m(>V$9vrI0sDQ#12s6T z4o}qMxCXq?h*Lk~^=6#&1@E<@VH-aEhAZ0f{SRFK6Pr8H^B4Z=#@#(Quon;i#gTn@ zy5Fb&{yCvPUJ^u=fp}90b%n8DFfJW}FGbO27}kiPvpBYmKpzS09fiT8QDh88jzy_) z7%zj9Wid?-)#Wi~A}*MO#gox|3RWng-85{Nj&3usLk0b3qQEQ+RYx%mJgJE?T9`N& zr|DpZE^6uH{ds7#0G};Ht3_C4h>nY~#TdPoVz&tfnxT+6hA&46ON?EC@+&dL8dYuZ z)@szV#lp2{vJPL_xeE+_-!L@cfr4#aNlMevIUR1;}}mo=Y@*icy$}j-i~*D zap4Yp;*ZM%@a-;K7l@5}aLZo&8H_tau>S!(7>dKg@YEq3AC4D~;Pj(-BNFFE;e+G2 z_#{3*g)3w5!)e@b2EWAN)_DAV4)-MBphP@!5l1ECnM*kFGG0!_nQ54P74_5c(RDPv zfv+=h%}uPkg_~~U_dDo&7yspA$UPK&fKmB4wgAr;;*=u1_82vuU~UN-JjIe{Xic0oyc(lFqHHZD)uHky%xpmICd~hg#w}R(1+BkgbsIW; z$JTcA?!ca(7}SNr-5Bv3CI4VtFDm@Q)IL-bX!!4+xBKI~0a!E;%?4q)FxrY>{Sb5= zitWSDZ#edeE}DR)@@T1m?eZV8tII0HE z)Z)Z?y!;7gHez-Y>Nn$~7Bp?e*I#kXH>~@Pn||Q;4)pEBe_a^TjiNmm^#{lP#q&XJ<1rQg2FQ~LJcL=F>W?0XkzLdRGW*p zwQ-&<7U`kcJS?A&whOV|09_5S-3a}Rv2O|PH^HH1czhX3FUJH6R9b=QR;X!>d8=^I zYAjuYmTU2y9XiI5-54?#I!gc=jMpI)qma^QzT zfoo6Ur)b=K8h^y%jyUWWj|a}-umn7D0mog$3rRTj5?)WiIjMN>3L0L;r`K@Bb$p+J z>oc)A3q5b)uWa0X2M6B8!?`%}9-h9B6Y}xWLsTimn~zZUF%}f#(h_`GiZ;)%<~cgQ zz_yp@^BQ~0F}MOnDlzgMN>yR}2b}y7(`rz?4s+^pK?4>yqWNd6Xhyp)*wBh@ZP@V* z{o7HX14DnJSQnoBg)+Y}u?MI1V#Z(8>cji}n*RHzQGa|Uh*kr!N(dc=v1KrN4Z&_v z3>=0+!!cYOB}QVb1j@X1_Uu7huNah*Ok&ciJW@aIC@xd{6k;laf? zd$C zhv1Y0cr6q)!Z7y`8iZrX5wtjpm62#4g-yrN{Ummt!hjeQjK#1sD1H{B<5BiJCMBS9 zB4%Dh?PScqgvOV#EETQOu=*-GrDN-L^uB>TnHY2vg|ji@HcIAT++9@2!_<4I_5g3^ z9l4|&|7fc+-p0Yx09geRurxaoL78KM(-<3z@^P4Q7FEyTt@EgN0Sgn+Bne+7IOZ0f%SOdJcr^!S=i=QwTzDU!Jiz4-@ofRFdxVWexTP2?pP+pyHa$i6=h#_> z0WVSTHHMX=cm+nkMcH?l^d6NzU}iOH*I<4v8rNglC$w(F>Lzq*#?}_}ZpEIj81xN= z+cDw?O8&&SPE`1Xsokj7gSY?SyuVoV56${D|M$&u0kjpw`T^)FgzbaSZ!q?W;C@jY zIt-7Cp|m(Aj6fv`Odo}sqcKkk7mdYIX|$BVd*jhi4xdiI6%+Bj0R6T^Z4x`=?EQ~;tNPKk+S0BgP6X9mcszCv$0Xpn3#fPz zuO{K_OL#X07pCHqE4chBzP*O)u47{cZpp--S-A5S_P>n>@8Iyecq$ji-@}Xdae6-9 zc!+Zg@xdcp{1~4XLI#;g{#Q^#%TZiF;n-pf`A=0!LNinRhs`3NL@anIAE` z2KDRkQ9YVA;Oj!@x4J^_`Gc7Ei zi?%vguZynw*gg;a7GU2(+`kBi8sYK9D7^#|mZFj=rkkOrIp!_LMV45)0xehKJ8N{X z!OyGF!xp>N;;wZ#zyS}f#}OMa#tG$|G1&!YxMJ33)Y*a$-EoO0zVO0T-uQ7FZrqMv zeR10k{Ns;%190$eJQ|3jgYfKLoU{+Ggy5_LcqbI+hvDNxxGWss9Kp3m@lzyjj=~?u zamPvQ7mWvEa9Av!ID_NP;)QsedLFMQ;G9IfcM%Pf@#!U8aT(vI;`%gfzKWjd`0G0E zzJUX?@bFC>nT>(BQ78w)@1jH=#@<8u2bhwNss(tf5cP_%@G+V^!B-`?`YF~vLzgoA z_5!!R!oRO^-y0nA7LQfpnD=PMVii+AgA;U|33fXkck?Ppxqf{kBr%UAr_ zhC9Dw{~vg;1BZ9wsV*GfjTe98^gno`7w7)N2Yt9$;LCsieBK{d4!{osal;_|B8*!_ z@b?hhGZY7j;gR7uY6PAci4#ZRWl5YVh1p|JUm72cL(}p2S{Bz#z&d%{q=4Tip|2wT zn}Q)zQFJ;+DdSibJgLA8fY*FOSI5J8!L6tUJsk}(S1I4F2Dc-6g0#z zBNR8r=p`s?f=Q;RybLqVQQHFZEz#Ht%T}WGDy+6ar#0AWi{5tFvkrqCP}mV8HlXB2 zjB`eXO_=J6YHoOY3(oVvB2P5iisjyD>x1>%(bW&zcc9-+>F5{{z_%RJPUc;~HxGe+!+`zqAIQSMG&BoDp@N5oF%Ec>rIO{&% zd4TgD;^P8b_6Xk;;o4&S^aMAT;*Y1e<2m+wfd^jVu-AB^9LH7Qg||5M9bSKrb3Wj` zYBa3Dr?t4E9^Ze$^^Mrvgr3d#s|9zr;=ndM{0&F8{mp*f9b9C!)Y444sT(Q}Cn`%1pz=={Ri$W~iXnOuVm#M(X%%Hd<+7 z)f{x3i!IvdrHkEq7&s4w7GU^7lvsqZhA6)nQ;bn{Dc&+cJu@s^h9=ALl?AR|fwflX zVvVm?;hNQ0w+1(@#qW0LYmfgNFvJl>oiJ)6j&;HFn{dizyyk`)?wIR=23}aQ6)m=5 zr4QQsVv`@b`(x)$4A_N&ff%+2#rI-#Fv^Bt(tcD9#ms}KeF*apqwx_ei$Lp0tUiWL z$FcPUdY{6cXbd`y!e=ld4khC;?i?y4VCn@_yNI`waNZ>>N`NkNB_#m(<~ldR*0j9~*JwXZ+fX+rHqRR@~c$ zgTLd^b{yS-XMf_PF1+#!XZ^-IJvhG?AOFQ=efXx|*Z=;xwm*In#LWZohY;=%#(pAr zUk>Fe67P*h!!h`DEUp-b?`3ekEH=xbr#$|eh`T4@Kt((} z1xHTB)6;N*GG3a2Dyn#MChE?@0(D%ffiE@DMhk1^qO%UR>7tK5_RhoL1t?;Gk&95u z2;&#ymz16UY}CSmyM5Uvi#+9T+46u(8{_9*;&9QU2XA<=j&2FJwWxihGE7O%$R?DKdx z0T(9XwTq~cjJcQ4;4+q^qD2~3UPb$KY`Tu_H?T7k18$;VHiq3s@f?i4i?Vr`bPtsu zU}ipQ7hrxN8W&;NW3+yP)g|ck6kDI6cNzA)z@S$sT#gZMQ1UItRieUsOszt-YP|gs z=hb3S9h!Z@@&>eR!urqX+Jfz0(C;huwc-BnIP?b|??CBJOz1+TZcP7;ntw2_7Z?4* z(mu2lX#4M<@A{*|0Q@`8$apbW^zigT9XJ##d)z^9hD!V2H7 z#PzGN*#)_9|{ z54LSbA3yBffx$abWEV#6MyWj*AB2;GF>N2J@5h`2xZofbhoSjltO!TD2y8ft%a7sP zC|q{}8&BevX#5$2J7ckb93DK2!_VQV^EmzjUQER4Nq8d}=ceF;%eeRoK2O7y*YHC+ zZpgqdH*jkf{=SKOvT@KIJd%T>a`8+aPP~toAK=V~m|cMSkML0unik{hC%C2*>z?AK z=lH!0eP80gR~S-`q7@kR7RSEB^Y3xW2fS8|8a0?(iw5;r@(C>(v9by6o3W_{-CMEq zD+YW+!FCM$f#N?gx)Wu8VNy3L_h9B9)c%Y4|IoPKxBtFbCVfe9+8G!xU+P*WZAX5%7FES-avbMc)vI_TnOJ@lA|UGs6*LL9IN4;kW! z#Ta9Za!WDU1ZS9G)-u#tjt?zx$qIa7g{!Rb<0{;^8o#c=ZENw59qzTq!Rzs;BaU{$ zvm0@e3triTvo_-$H=OT|k3Ddi7rxnwYq#MiAKdJVKm2fqKlTg21G{ioAfDKR_7f|;i79`=)OZYMcZBnu33OZlKwrl8f9eXn{I1@!~V&pB9x{dL7aPnPD%SH8j zm~$T&oayYW8fDQ`ikLgDDfR*+flv)Q+}dq7vB1XdcU!-2TgkM z)n8oQhqe8_|MyRq{`gH0w-3a>Lby*Dhlt>@Avk6zo*RaW!||#(&K`+(C2*l6J{gV6 z$KczsxNaOa%HS4R{3(Y!<*~m49-M^374g&*96uE=PQ&TScw+|6RmBH0aq%pCu8u1; z@Pj69(84csajOpg*2O*gIA}f|S%9Mq@XR8dXoQy+OWfh(45MvE<2>5lfE*yM%o z-q^Vf1Gb}}ABOEf@tqhQfU>(WDG-%|Fmo?z@5B5MG(Lc3p=ce3)rZh299xf|_fhPL z#Goh?K7kP@Q8F6iVo)I#Q_rBdKueO(Ju}AuHyc5 z9GZd0Z=iG*Cfr1&Y)rq6nmL$v7Z>GW={>Z3fba6rp#VP@qDK*SJ;q&6a6l;@dWs{S zV@w&!y~N~KIHMf1-k{D~d{~J~-s6iZTvd%9KjOw({91?GKH;AR+}nhMoAGE1j&8-X zUvbhmyz(7q{lGgNIKLAgcj2;beDfRE{=rYZxcMLc=))ZX?f?C=pCBF>fWw6F#2_3u z7%zz6R8hP>6z7QHz2Rs$0-uh=6{GOIB(9gj<}v6gjlag>?(sNK4i8VjZg~t;K%vPP zu80y!7&{f^r(=pTs;b~ERn$|%!dYlC8((SQ>N!}eg)Z9oO$WE@;a`2+Hy?*A#A60H z#t_dLp`tNfU4pYs@UAH?T!v4~ak&M)wZwH+*tin6tiqo*xN{BmUyBFraJW65a=`J9 zcyR+x--tJyaqcF3;EIdg@c9;8>46_Sal=;p;*DE<@b`Ay@V#NoBG zsBsQ+&!fQwEJ;L*B&moL#1|1|ACr6F|QLB{le02wCurm zf6(DCe*T9Z{eJxS%`O4lC5QtC;vpd%A&fDDQEmt(i{gx7m?eff;`nd`E|I_&qj1$| z{3wMR$KqFM+$Mv6#^YW&94wDVC*tTycy=;Qnu1r9aMm=uGacv8z{e`MY$m=@!?o)8 zX*O=w#2<5T$6V~Eg9mhRm_DAEhvOFDg@rhE5neaMIg9b0F&Zw#rzW_<4Bs!q^~KG(gmrky9#z)kO-Iyq!h(&s)CFH|LYvK4o;whXKgBhn$>kQtHL!)?nb`Gr)u<8OjUc{Cp^ty!IDHxcFLTMO& z6(!O!_BzVnz?4iJbra9r!il%>@*SLc7qfFw{~kWNkEZ$f`XR0<#JWeg=`nsUM&AXm`d4ty~P@@ua-=RSjmV7{qk62lQ_I21)kM0fF*@yw3QLqKW zzM%M5jBZ2O@0iq%${m>b6SccA{}&qn#v(!l|Gct{^d%*U7oC})7l zi*SY!W-UgYCHQbDE-}RyX1K~6KQ70OmiToA+N{JHYjn23w$EJ zUYxcMGeS`70NxKpqcD7S2(7}g>Iga>#g<6)io)*W7JUdMema7Y#&yNP46@!V}x%)zU7adsZw zy@v}Q;FEmRD8Sr8G$_K7$7t~cD@)M+DKbr7}-qn`-&4Z;0Gai|y`ACA%^FkvJrjly(E)Re-! zF}O$?OUI$*czh>|4ioURJbEZ#*CgDfhy#@H&{P~T9b=SHP6d-yafTXZ%|e~o_)r6v z%)u90xJny8>flB_{Hl-J=Hs6QxYqy&8{$zT9Bqtem*6B5ykd&8mf;<9oNs}TEpeF@ zzFCQDSK%ic+`I;V*y0X5>}QV$9B`N;p4fonHsS?moVp3GyW$)-ytf4nJ@Ba~uGot2 zy>Yz{Hg88yKm4@=ckjf3yYTRC9JvQi2jPTZytEHh_T$Y1sCy6#!f@$fd>M{55m<8+ zosVH#6#AUN-jf&{jUuNpG8U!cF#aq~K8I=NQT+nuB;tZ3EKWxA6s)+6c2}?=4c)F` zM>_gvpg<;uW}(gpS47@&vs~vHK|o zK1ZP!82%C^USn)I%2!~@TU33Ax89@P2P~{clNx+gi>vFg_7l1^;<;@f|?u3zVW-)t1XErR%S0PYmR{=#^0 zFb*Grr$ll5FuW*+)5Y<|2%IZ{4@TkQ(fC{nSB}LG(zrnezl_JNa`<}!?wN>#CgG9E zIBE)>QNoGS@bYw=IRmp*P=6*qQbSX9d_5c2Xky(Q+%y-zYoo6&{?o&dc__L7qZZ=W zMR?v2r!2;6#;CCrb4}2|3`>@w#d55)K>HQgWQFe5*trS=R->RThOI^Mbr@}rvg&bIKL7fzr$r! z_~rwy{fM7xaC060sK*@**slo>e8yodc;X9=`-&IZaO!uw-i~uR@ZL`}?82wNaK&$Y z--GLWvH350_TjI7UH|=acYho>01pquk%REGFisG`OG8j)DBc`~y2G(R9G8y7ml9|r zi8Z6qc?`CVMW1n4D}yew_)QMC%j4gPxNi~;QN&|YaLiOZHw_h)@#+kmt%`SN;=)<@ zL>-rF;9E^xr-hAkaf=TA)Wx0p*nd7AT!6z3@YEt4Z-f^Y8pe;A?kW zsZ=+fc-oA_T^04S0nmxese6%gV`a*Oq!uH4L_XPV& zaQ{;r`W%m!q4Y~kc!f&knEnPe-(p@RE_#opRcKj_?>?eKEq<;;k5AaufV-M-Kr%V{2^hf6b*ftP- z24Sx-28*DGC`JxNDKU&6j*~}V+DKF%g*lSAKnjb;pt&?wj6=Ke*dU8;6R<-b{S{DP zGKMOmm=d0xiZatNQ5mPHV1_Dcsp0)uXfzw2X`s~{tkOb9ZEVp&FFowm$H4h0v=GA$ zP{I&njZoegQ`eA>6Jh&5w@4{2Nar_>< z7=+V<@y0%!yB{AMz{Lmgc^Ixdj32^rLj-;~id&E2?LJ0zOJa(jw(=-r4tO&HXS!e20=6(!p+?i(t!W9ko7`-!(Zao#U1>PE93 zEdPVHfAR4@T-LAqzi++~z_o(-X#j2(!XJZh$6)L?1P_Sfuwi&Y49AJ%g%LPa0Wxe0X-+;F9qB^83#_m!%8@E8lIkx6K3Eg6;zptH`P#A z9SdgTQcZk02W{qJjW#;#Vw)cN%){RK7`zZg7Gb0zN-f5CW1PGc(@ap^40D#@g5_9j zf#xf)!V2xIv0)Xut;UWu=)V>P)?uhUimk_!jws`Vi5qd63ubIWt<8Af4UOFKnFm^V zVbxZ2+=eYa=;e#uei-PFLID`Q3ncyogVdaQP*Cn}X|7vGEFS zxr#rp;m+&W{{|k+#Njvb)GZu;8!z6$>38u)F3!D&5ANgQe0=^8R~F)jN4ViJeksPS zCHT7(_dLTvWq9NTj(UY>UgN|!c)0>+R$}%$)UU!vAJFt8zOKPFby!!An;P(YBl>>E zf6W;31x3GNR2z={j_2EPN(Wy1i5gv)`wI+9EpI4yAO6;=6T{bvi4IZ+^5q21}4&@v$ zc|Fe9fLTtc>T;751d=!svwaGN*&*@kyxqh5_(?7U#Yk|4F_Js!|6CO15e+;30ZjQCaPrP&D*G( zg9UeSX&%13hc*weCLf&(u&oe%im>-F20uZOQjC0xQqM8I3@5+Dv{$HJjyZ2|!CNe@ zMDzDpQH6HZ*zghEYO$jZ{Xd~VBZfAiSTmk%L77%e{EE}QVa9jV`hoX5(5Mrib)i)^ zR{ciDKiJZXUjMMW4+8~y{`;qpAchY>2_cLfgz|$iMFdqv@zzk(6T`ycXfgs{jl|WX zuvQXXr10Aq+%AoO$Kk&5I7AMQO~5e|@tguGPR6T>I9mztPQ``O@rg1nSHZWcxK0fl zXW^FF_)`OS&cXh3@t`&i*TqwMIDQ^poR8BN;td0wYlshwaIrByUxF)5@PjFCScYHB zajOOXw!}SFILI20tin;N@yr^WxE3$l;Y@qXc0hece6#^gH{xq&T(b%5Tyc{de&2$= z9{A4_L$;#mHjMJYvA%fT52yI!wVkN33v+j)!5%CLLW^Lm+=ur2vFQN1AH>cu3^JfW#a8DoOcV0veE1gmgk^tF4pIv>wRp0fPN3LuK+hc!XHJrqZs>@ z;DJ&c_6$!v$8j(4!b_a`8n2h*oC>`677gFw)AzXI1HP}u^)=XBi=OrP>l5y7#DSmj za5Iklf~Q+?LK|NChAQoN^9Snw#DY#-`U_unqfHOi{6Xix*!B;7`u+Luo4o=UEQlfl zF;WPngfV_FP9B13qNqL$bHs3gI2MmUa|x^%g?6K{K?>c*Vuv*P%bS&rWxc`T@X1D8?t*VO;kwP(=!RR|@uvsw^uqq$cyJpI-;Sqzar_Rv=#SF_@Ww8j z8;B3~;NrdbJQ!Do;D`OVAr!wH#I1+$_hH;~1P2|(Bat{N3eOzJi6`;$DV!OD*{4ze z3_glO(|CM+4%Z}L-38oq5x*y)?$**z78_cRe zol1Q84wqEnix0T!BYv#Gjdl379=A2%pGMsK83(uE(JwgqE1qq`N#F5GJI?CBJ3n!L z7e4-l%YNgV9$edtpZ?fTt(n1Vy|w1y!cv&1tBsj0H1r zsVcsli8iyaMjf3suuT(vw6J$B2J4`R9!Bb;)O?IzfRha{Z4s&)Va{S)ump>jqPZzn zn4z6HHY`UsOYB&I{wq;n6^7cN*cv=(i!yeYxDKZ|V8(jX+JN_+(8w8|xuBIRR&7Sd zE!g6YUY^+Pg@N8E@0OBjAT zgxkaM?-AU06o(wcV^KKf1fDyIiqUvA24~0O-7~oGEIx_H<>&Ej0{3~bR3_77jNM7EWB|O=Vs%B+qgIfpWnrmdHCTTZg_xS@^Nbc{w~Bl zML4J!k37LqrFiBkPJE7+%W&pP%zlOX<@o3gn!d%?mAK|T)>YxAYW)5YeQWVw9fo{D z(MF7F!m-VGz6GbW;=|GE4tn5PjZfyFE?tiee7X$vGV86freKSk| z#RV~X0LlvCp+PueFvf_WoG2y_#TjClH5_$D;KPx)WE8%T#8p!GaSU#h#;@aW+j#sV zi+d;F;E8xt0Y^{9vx+!L39n4WS<~^3GR{}Q$EvtY4d2YdwX^Y)25z2%KeTX%HulrS z19~`Y9-f$w;}+rt1DtAz*Nt$FG2UB(h9>yb6jv<6_vX0X0-G(-(+YpB#NDfK;A%X) z21l;N({?z)9xpkdiX-0KfVvy8z!{fr!k4aS_IhKm4~qC=q#sK8 zWBg8>ybIHIqxv4q3Bm=zSiBF-_hZEYv^$6mVd!=kJHpXF0tF&5^cadA$CD>e<`gDI zgRKox^A6(dq(LC8A>zwj`rh3U*({z$++p6~nKg#C43#K>18e$wJjz zcq<$A?qFdK{;#DwjpjNF130b>qZBD^%8(XHn^K07hJ;8dWhgBqij*OSQ7S3bFvL(= z&??euXd?+(O4cmNniM6XNaZ)@`2O#k&$;KG`}TS9oM$mh#ga6%Nyqv}==2yrW};^{ z{&<21b5S}Uk3Yq+1sL-jRg3UiG0rQ+2W4nbj(HVmQH2#RapNm|Q-eF|u&W;bYQ%v} zc;pQZdyA3p@RwG+_#UUX;q8y8(}9mZp>Y>J|BP$9@l_9Q>BZJ>_{R_Y+K2nZ`ugMN z&jT@797jsvX-S+Yh4F(>LmKZ4K|LAFmc`|ASUMcn$z#Jv+%_89$Do%2_Km{;MI54p zValkWg0T}(Z8Bb;g7eidbt*1V$NcHIY9?0B!c7|3JO^Dh@$)?N)k1M?JgS3o3-N?5 zD(T^+#W+JBlMHZyA!aN^6JsniK`T?NF+&G)e7^$SEwFbL?zcp#wfK(}jaWm|E*6E<$c?atWYf`7WAuoDlt;ZS!B_rP(Uc+Lx_dgBcr z)bho&J!t5MPxs;K16bvcn*;FeA>0{=Uyk6OWB5}L9t+0dA$T$rmBa9IIL?f~s7Rb} z662z9)@e*WgSyd}8H1+hu=qS$U&Ojg=op7>S8#U%e!q(T*KqI+484hCZew&3PD#eZ z6x6(n_wS+p1I$gul@GBz9XDiP(_?hW!p>~;$-x167?_W;&oH6@6$|k~5vrHqty0u} zf$8OFREY&uxTYGbU!i?1w$!0p1NJncUlU3;W6)caZ^2WosPX}?wBhV_OzFTyofzMR z8ei~EH|l-G>|R{{9ZP@UIsqHR`opKNZ6LObqn8BsNn(H$4jGJL(x@;LV`Wfn7+#md z`6Dn@9+!;5{L#2-ELJMurt#RUh^|WbSs8s*P<#>|os4p-ctQ=8rr{-ZoG}BFX5xa` zn4y6tbFokpt>$Bm7B17qA|3pFA=c{RRz3W%7(Mjyn*km$#6d$FvltzXQ(`gk9BN*``xjCFGUmqN z%6KeKzzvDmbPZi@VCPNrxs3zsk4_orl?HTqIpkEsx(y&EZLL{U?z@WPo5Re8DBqi=X zID6kaciwqt_TF&j%o%4qfAN{`v-qv`tY_KrAzb}~j6jR{-ybf~5D*?~SZlc(BM>4Y zNUkRsT_W$+ogkh8y`HLXJ}l>nu^c(;Ui*A_ep>Y)b#!Zw!HJ>c`0ulrK_FG1`r6zV zbHBG?wGMTCV|PXg%G;63&Du!FHAXMpd)4A5YW<~Bv2e&J<^{7Pc`v8$=l0!6xW zc{`#FckR-H8oK}Gf54=}Xh1}`_<#Q0l?)}U)GZ4^0wRR?5h4IWtQ(l3)mVE_J(G%EY|Mo|$a_~j|5vb=wM?oOD`g#4|pA#ZF0>UvL z$G495c2oqS|Nk#h5fJKcRm8TVA<$m^)oq9FE>+p9KmL#Z`JWvexOK|G4x6;IlB{O* zzavZ6UgFDD3`M3^8+Z@a&PrNcMB!E}lELVp?|P{swB`5Sbed`15OaJnKhchqDDt&} z%}+(5os`Cm|K-OFqeE56E06;s#K8vul(?0vWkET!kc%2Hi#}xI}yl;C3j-_n(B`ffbYC4cLJXC=~8!10XFDIgYJWa6LaCb7@E?pcuw~ zMX$x+ppFis!#zSi(_gC>L$i;QV*%xK1uABLm6EAhaz>bQFx|%G(^f|5oeC7I3XmH8-8V{QW9DjltBDr_J0t*Y8mF zmlouJ0&%DT04diuOVf84DqfzkOC9iyp-AhSJROHVO7T#og zQH{@gSm)i|ctEI_ZqoD5;qdfG2yO@ea~68&9hj}K%D@hfS(NBe$B{knI}ZB(P;qM& zY)gMR)-ldUxlQ6S=z5k7qr>+jHzpr)6FC{NDQiTB!Nk?5n33spmQ`wkCAamY-xoLK zfCh0G006fda;e4HJR5?NI$oJ7+tWD@scZT9QA z{yhA1z<@X`0DvFqdYD`Dy%X*4JnZ?%Qy>+FEojM6TP|uE%-HF^TP$|vutADX0=ENs z2EPgP4i=n=B47s*tAMvhpTZmL4l&Sr7xlz<{#wQ(iuSTo*A!;9n7gFG=&);TY@H?b z3LVp|+^E3aMDa%rtDfI>xy>Dq*v&8_LhkE#s46T0Ijwaj=9ru4aL+{{MGj;-Y(2~)_9$c!vj6*tD z#6(hl5Ql95PzkSbHU zGfRf33hilbxw;wcxaUO=+u(#q$bSw|SY50(a62e1t0Y42z>#1k26oux{nPHwW#@9l z{xo)UMy79`w5D>f*ciA&JfKS_8>$VXL(Jzpa-}k_oM-977?0OUjw?e1?i*j)nVIa( z?T}ST0?CP7uyNPT+y zDi3?zTLf@B6h@upL+@}4$kYsWctFTKA4XOkl))}Z(kp3g?QTSv-AddtV#H?QiAUkc z38RDR&w(Qcsd{l|XX1}RHo{H=8hdqH4}A{$WASGzc^>p%zeDv|BFF(3;(!AHrknG` zlxchAi-w&ly6e@2sVR&OW@c#1+qWeox20=GpRAzCaO1l_ zcKH3KJp88vDaqf4=hyF0r%M2GxCL>*0|33a4NZ_c(^ek5)<0lN6ZW!6c-igH%!w~W z+)(&s{@e7G!6qGGxj~uJ1l(&bO1X%I6co#r*y=&Z%^5kZPu3fgk2~#eiG2# zu2%XJYpzBVMh9fcgSZ1#ZyFx%X7b>6U<{@C4!whm zL!1oQA^f|6#$^n)qMpGk_5Dn5nJ95ihYWS$u{-+W{9WaLDqwW@*n}seL}1&LI)86l z3r{j~o9Nt=bexYOr|bR1b7Ww{O*!C09OwbSprCUN2Z3|5q7tN5H!Q=)@=OFZro(tL z7wdz~eFh3H|MHN~;0m|HCFj&H=pABlW#hmObZX%Vx4Kn-l$Ee(ez{On!hGhYWlCUP z!|q)q#ca4F2&02!9qRaN+0hapg>SaGJaejSep$}t+_b=v_=<(oW6OKj@6d#>3(5ll z#DNI_l&V)v_1~VGyNB5z=kOvuPOA9S!EJdYo$^~CXQT3_%$37FgT-&S9e!~oA*n;X z&qqox&Ioo85-XW-c`cYcl9=qfuWMx;iQRsh2&kr})c&FXMu$4v zHwR@3v>!4d0+So+0OnnqoS!L(4rD~G-0=NNE1NQG;WK<}`DsY?rXAUmmd%pRyLNqnA0_%Yj| zkG{K;ehx7sWTKIuD%(Sc4n~LKd(zn=o-LN)q9*f-z>n{LotxFKVuc>k{#rXXHLt(C zeuuWozaR%9hyy?99LW76k7RJ=i=jYTox2KXAtx@n5|&tmz78fl!TuMdqF3t!>W`o# zxE;iV@mZmFsC#^l19o8D(AY`Gxy@xQy71Zk^Ec%AyiExOw~I+*#Y zIzOYW)(AEuj`&UW#~_s>??-?&Q#GDK(;0CS58CxRv>2g*9Ec$fN&p~-^w-pw2!}rr z8TAM97H?(Oejaada8hXq&Gv3}CQdnCIUwDSqleq!eq6s8^bSRuevm$agwY_0X52In z_vF=s?@q>&tnWEDf^k77b3VRSeqsqB2+wKRU@qK==IpnQu(dhC`Dw|IHS z4wC)lw-?RV@6d!`3UVNUIG6x{1v>jL-JF#tQ`3EyckTq*upO@ysVe1?x``_@$b=8* zT-BvNjPrPKJ7mU1s6+4YgGdr`K0Sdx*}yV-D0%MdYb%^uF!o|F;2!I!@6nrFrUgM& zcLEq4#Qc;)a0IeAkF@-kGTm99`(@odbl!{fr*iBBgsK#xE-2ap+1J*;o+;rDzJllg-wSp{z1eWblf6>GHI7HH3JTX^E*Xv zc9$;n3qN_m=s;NGOhO-&peyY9xkj8;a6^RgwC;0+0;Q?y?Md>=qv4x!AcHt~0f3x- zhV`vjBnGeP>w3t)E21S12|Sa=*+0vEFtgf?-^q66aLRpe7j6eyg->D7JM3`~Hi8|@ zTEAn>Yo*|#9uP;alN9Qlzxq0)Oav+B|JO=us9fYPq@9<@Zqz&vqzI9hi{2{LQUbyRa@Dp~8Xt{(ng$cF#l6CSW zgreps7#*TH2X%H95l%V&Y;rLj5a$X0)c56k!{=#z;AlCqWPE=84jt$wpt^Ji;_w0h z%-GO**0@ectGXk9$4I8A@NgLc$+ilc?V+7?Qs0Nojw^>>8YA%cFU_ARyoKIj-@xG( z*x{LUvoKPGeHyV|G6* zHOOx>y|qR3pvRVM@oe(Fa|8PtU6vUj2MUNo6ae^2`_IuMk*@IN<29*xmWR!F0rA-h zMrvCA2Nqln%#3|k4x1h0n{emB*9^NAdWT&KT3xV%Q~fUXzxG&@bos)#l zQgf~4o^33~<}#)}79kngb6v#vZHe87ZoJDPyBV~TDDU7ksq3W+Z#NAAfA%}Qm z2zrNN_a$SnL$8)cM|B%@HKU?^rFKVy34272h!gfO#mZ3=*@)Fa6^srE5hX9t*ol(V z@g=f8g*YDLFn&fsT%yc1n(FGB!J&D0{SMvuXCMbEh(iJZs7&0d9{3@f*CVy+r%WFp*^d^O-N?HzO_`;v-!QYHFl04!L9Jh0rxya z6>bNw@79OVJ4DnAVS@7@?0LEMQHqZSH@yRcUnD!RPtN;{<^Eb6+NU7ikni5~FgmCy zpLVoAVCFDv7!7^KOZ`UMW4ZrZ`3G~fwA8ledRq0@@6dt91#+N)IDq>3?w+LE5Hy_5 zBbIC%+mXmynIH&Ks+ngR;yexeo9I+Pb>%?rBMN{2Qr;2+rUumet&f8lv%wC_Kh@<* zzgM7ZRj&p4nW6+4n^P|Cb1%-?%IkOA=n%K&WV?gyxaf0UB;RtftnWMF9+VLi zkx0a1k9#))sD1qoE&3H82U>{3DganN<`*}K`ew#|0LhcqslQPRy~rku56|YcZ?mnA zhlKOh`mi-hAq;mOv_yYUK<{9aHxD_VUJ;%%;-YA!+I@SO=7!p1p~gSMfjXOdXkcb$ zm*F>>1f#>?G3kcvdxX0@-(&{r$m?EN7u9iaH3eHWdXFfKrvrtq-=VGC2;@Kqao7L= z1scYh_q9KLc`;NS7~irhz*aFPr1YENi7()&X4)k~=*r>H311p+hvF3=7xWJP>y}yI zJOs^6{C%t#{e1!uSb3r&e`GMM%CPk#GL}|l24&%u)h>(OCWt@&~L?l`1oIc{N#oxhV&Fh{HYrsKSa~hrfb^zjiRCbgW{YD<^$Q8pTk~>J< zkWy?uA|IDo+cdOWMV5M<$t6PBXGCErE82E!7=jI>Lm0LT4NFL1$ocyEtE9~7xRMKQ z;`(-UKts?r`&8Kb8~BdvKvf6TB}RzDB>*Vrr5S-l!@ce|X-LIJhK0r?E4D<)+_IyP zwr6hhz~tY4>qZ_~72J6!P*}8w-a(SOQXA}`9#him9b!+gNY+8d?p*vG*H8NVy+M_v z@MC?u606M_7#*?z0y}lztRHrG+&g@@vBdj;+J1ZZGm$50?uyh*AmjJzuS;F#u^iW2>qrUm>~{W0N}jD-^ZBW-%j;0e&orvI8H2kes`ML zj$kLVGFB?ZFr50ILyCh7+zxGsPBG9s7`#9<1v}&pDsZWG!6K^S-us}JC4rVrm^R}l-D@hRp(xVGT+^G*OY1}kUq~$ypMZDOKLT<`|1>!&q z0G^T4y+NvHdEjL&pAzhzS(eMfmKT5#YVtwB;DwB)^3}O$g=kMtA(5yh!<*XQbJg z-bzJx`fu-Qza{%7;&6o7XV7^44xj7DKy`@~;y?xfKDp=ln@*!s-voUUeK+VsWHI*d zKTR`|DYO(_c9f6VuD+)ucm7rb;dZbkIjn--f#p+7GT5Q+OX_mSuh%2KW$eo++FyHK zkVZDCPMu8){@T{%Bdp+pF%KNSJt8Y2Jq1!Sw?}P<24Qu*um73)~=W2dq7-NB)+hnana9ul*ZMGJkPgVSzne4zl*@=Amojo z<0dE|^YgF0%JYraD*1FdvQ&@0J~K#EzSA`v+H_M6>=1{$0AQnjA_o6K2)X)tTOB%D z8SS?NiOmv5d6%yDd{(D_SeLIHPWJQn;dZ#sA2A8N1HtLQ0oXy4sgUYrmz0jQt(?Yq z24>cs-D$I_0B3~$64cuf#DWtrI>ghUKku?rQ$Rr&d)I#ABAQdhAhpM9g`yIGVm?P? z|MjLE?m`@d0YELv@y>X?P4RALmmpdfE4>t&^6DJ#`k8k3n$K;i$!1p$2gydma653x zXm3F8fFs}=(>td#iy_7&+x4lNmn0y!b6rZ?rl0dbH90I^>Gv>}jkayh8}dMA~kLMhPe zDG|~NPv7Z#duBblQ1mN@zqE_+-$S9)zH<(}L(YH@mTGiAT;mu7s za6%k306_f@<&qS!a<$rhXQD$=jIUbIG%<99nlIWjQ8_oW1>gU3SQL8%cOI~;mhd#8 z-fztqnCk-Pp^R8NY9g1W6LfR^IiruYj~3x*1RlX5;A7=@&&fml9vB^}d%dud-f|hT zg(CM+eV3j7n7sga$~LQtaB2ov)O;V#{xfH2yJT^`SGDx zJGJ!WwUkuHl#P10PhfP27reFZ{5j2fvH-WSQ_7Y)x!d_6#k6$!TDyK{g4Bl1^*i)F z!~^}l#0_yU0|2Lb1#QrW(KF*cmrdF`n0l9xR`cpGWY4HLbJ<^Stpcwcc9IB_;dVfu zd?EgatK9jbyW6LoE$ z{H=K`y(jOuXwuA%mQF*YN=b0hFYb=kgM9rC{T~BB4m=PCD*$krLjT*Ok;@1@Yr6HA z!@!`b*;fzN*^aWnk_4Xy>SqK0IYgn~(JqDCAtX&+33>;`AM8wE2hp*x_idaZ*!1r8 zRe>u;`?Ad5YxCzP#!rEQl#Co%aWFa@#&hrT;}8EdJJ2bY%TE)F60HAPVLFxahuA!U zEk_~n`W<>5xg>`=!#h8odbK%+Mb-c83_tajG#f{C`TVCbi zIMn|g+zyHe1g6kC>^>@n^z&Va;h<@V(fo3}AgWDONYMyN$;7Ia0mdFkJoq)f?g{Jf zOAVslC0@&u1PY3e-IC%d5d%om)!C%jkG$v9c_fkbZ{S|mKLav z{f0SFxE%%uivZ9&NF<8|f*r^j@Nd0N5R6~MpCT&h+TXa{GGvM!I)Ev9z9ubfh++n# z1E#T~>XA90zRoaTN%RseX|zl<-M4eU-=5D+bDm1f0I%Pn|055mE(t&!l0fG`Pk~rL zM_CQ5R84&|w?>VEhJszg^)1k`Hqnu%%vR6;IjC8W!tHPw@0|p_!`ZJ!WUxcO%S&3P z0}&EG4t3jt^uScNTOHccSP|J9INjTduS&RKbP!m0Hvg&qqwM4Ezo?{??lSI`yX*t| z$wT!4Rg`UX)0)@sFmz`PgH2)HtdYWt_-|y_?=a%E333pEIAj5U zx9{Qoa578aXk|-!%KkVRTjSjf-wUG6UYjNH;ob}1f9ImVBN|TOb{L^0Yk=Ot)1W>P zoCn9O{QH77buZuX;}N%Dd=-5d*=?_B^a~?mPl<#tOV|cR2QSwrx20lf-1Hbp5soIU z?V=(=qdepD?9tBF3EAx!Z(yAs8x#dO2tyq506>5r#(RB0c!71v%iyk)`%?s_Z<30S zX_RKw=f>$9@=34qu;~?554QvM?p81K4#a33knibM(cX)=SETP!b?+6LL_ZGt^zJRq z;O{CU&JFJ37l`-PV01VZLu5yJOaH}~A;|o>u~(j`2ODzjNF6thd41z^P2wBqo0()A z0Xc|39P$A`_Uu!?!oQ3s8V``an_>x;S2cT^bwM204gA92!CWOB3e)ue!`xLHce2*-$2uc>c?3O8feU*nx0$ek=9eUQ%enao@Qw!AY3-G54x|KZOwDz5 z^7Fr{yD0}Th(iwmxY49w+sw`;<7XaN`Du+?>~&Aa3-w>h>WM;me?Leq{hJ%Q`+^Dn zd1N0xxS(i3z0ddf^D<;UAJXS++h|N!_9Gw0moZ3i(n$i2Bho_7!U*2<%3iw1}J=m}fl6_5zd#afrhp=zN+6Svc4y zir&6eUqLmvkhev%bkh#)D<~;No z>6+W83Z207u+Cea*z$L#i5UIvVQV`Qq_R-M=&Rj(dX?AYWO{cjy8c6u=%96P*oqDesxd4O|Q+`dw;PPMu(SXFC7ysCz}fd5wR3n zcij6bS;yX?69t+u?eBhkd%yDf9i~J7n`bNuaaaQY$#SQ5@sA2sX_wu2Xq_H88)>J+ zIu+uOx0W#oUIe6F&HahoSwi%K+u=d?s3!Cd1`ppmf*sNmnptlD!WvuPXAZp(3uY2M z6XaTIkK@h}vRmoCOcjRFK^Ted_3BDp>xq{TwHr=3t~tRkFH2`G(g-u{$A??@ZeY&I z?EHUoPNX0XTL9pIh5d)ZkvFRotRxkh$@bF5)m*Lq{*>|RcSL;d;@S24}?5=Mv8dIR)e zPOFz)yH7s$zfJOCuNpNw)BF;Mn>(*lDay8X{dt%Z>jgR7hd6-xy%85$AFR|1O=X

    )){&yE4oua3Q>pinWdwFw8bw3HGvEBlnLAO8JwH4z zDiU^(k-C0|g;)R0=aYsw90GvtNwp7}Vi&Ba#4yIG6HsCk7A}LKEB$_Ig$WJBi@f8+Td>&s#Dc)|MtY*D`Qw}m<2X$lsaM3gTk@xw0 zG9mkTad8D+?0BCQ#oS@DZY?PhqnUL@@YOnvBDq@zw?iJjW+wCwtGQ&#V28eek|(vF z>>TMbUrWd9l+&rcPVWdMOveh;8q{)cIfeB+PL$E()tjV^ofYvhFe6K`v^4)yux4otPPQtk74%v!axlketk%0Uj|zyJWs^kr~b ztlD(8Hf~n(U`je#_DKcdCe-CAr`;K|d%VGXHk?3}t7);4-lQ zmGjBq z=IK(1Dugi)VmqbctDl~`v0xqTb@RvM38G6O0hbSpc9^Hb@u`w-;N5}QIR=n}0>nWM z04&)ipU>UbnmL^@v#l(|C5~PkUP=l2ijS>FSh%KZws@6?Bea17xE*j#zpOy-kifBO z2F}C$tP>W_J7FK0QS7AIU=H&ONxBcEHTPVpq$jFKi!T&lbU-KQsys;W{S`uF-OX^X z?`@$8W+C0W8^a!bx&+Mfu#xWN4$I2Y4SEd=7ZsT{kGTdFv-FR z%7YTb!3Fet>kO7^CII)%H&cHjVLs6vQL2a0e3dl8;Td~Id=h+DbK#XcOJ|x z{cyCQ-fulu-}wd3!@JlSK5U(IM7n&O2OqF6lGvS&CfS3_?fZCz#C@pq#9(v?$j91S zS-vOhI2uDl@uLLEz_L64otuYBK!Ea@Hv|0*%yk&+QwBLGLmU7AU>u2ONGx_sAw6*_ zaeY7-J?&kQKW(xHx8jUYc245%`(EV%M`WlNZij+iO&aJOS`(Nd_v5-#O8kG2qWZLU zRzGe2?3o}vP5p7-vB#uzX!c9m{3;8K4muCr-g`I!PCxPBR$k6IA_kZ^R~6m8L(zdZ zQQlaFS9JY(81Z-qa!`RdqyvBlM-IKlLt)i|FX{bi*hG>{M5!H*ha&toH)spbBvS0)QfU zYzwjvoPTty&ZR29erf-tG2tuX=KT+m_gOyiy4n5f=i77s0RMTMF6NOO^bS&aZ8Knp zrP|Z6H2zK;^eQkVa!8Vk&Ctt^?WSm2kIL6#t!XP z1M9(K3KC)}${=IK)$oDq&%-2hD#$?%;!p$texq^cd4_Q0#2M~qK$SCVVpMFeZu_|` z!pu2+jP__{;i@jtII!8lU6(ev2MnQiAb-}g26o6HA92}Po?`;K2e8G`$2xl(lz zs6!kE06=5<_wGNWnoC8U;}=bI{>l@HI>}o^ANvND8g|_+|0#dvK$i3o{_nVP`5Z^+ z9SUC~iGv*!dbZI#$>~>c5PZ~7GfRpbo~<9-&LDjA{fyyzDa%_4V;&-3h}P_L$ZN=B zfwG#@gBPYu zHAlk=-I5t|1AaJ457~kOt{iUdYBj>0hvuS3&!Bghz+iR*JD}5+b?~z|*^OJ9e4OVJ zQDz*$YOnt4ULwr?s?O$3Gpz5H)lm$H6{g9IoZ_98y=Ypq)g9P~!o1X~zejv`oHPRO z?)B&4bLD^cA2h)Z8aM!;dbrA{op;0;)`Db2h|Z$-wn)|2Xm{E?WsUdU#Q`(_<_TOP zBs#(E&}+aG54{6t$jWE1gE->bzROlsA04L9t(U>Yx5_@v7R2yZ*=b{=`8a(SD}yl) zrQa&k(Q^%|2-D&RFPyk7^eaY**H^Vd6QX3t9r7`eZpuLm;sCn0OVDZET*1eB?AVj) zx*k!pt6=qXVR4#>a9Aa^zi>gk?7uuj?pk}ig4Nkqg&&zPI#{eaJ}loilgBr%$;TjmA8k%gb(xyYM#t+e zwvFn@TXFpk-RR4pJZM84K<{ukSqpRh@6cuSIIsYK6rt$> zc#KUh#d^1@Y=E?ztgm<`3jN7qi0(MMPSb3qUpegAXCK1t(BT^W6?zBfS?7ANLlud6 zN6t^6*72jgr(dMBpD}W?#4B)Q6Cw?Z`Ju7SAi&m*X zG&Ydmpy0~k;1tgpZU;U#<5}n(SUmZYzz)B8%CtD5RruTuy|6|$!#KH6m4})(Igx&G zJypMt7YeIG+hT{UceVfEdO7QuyJLxz;@!Qk!&|L~_XgW%RJXBj;P<6}4tfv=&^`7) z^LHJywN2`|4rxwG{*HMpwgjcND;-Yeo?g5|y67Rga@d&dVSw8qZ;5#adIw`q6v%g6 zNV7N1Vy5CNip9B^_D|Ic!WaUq(M!k6Xrcn|js_OhVa$WC=65SUKn;cG_%HKkpO$9z z`T0e6a7=xs?X7$9o}N9r{<<_o%mT`TKEy#303^Ij?Z_fWcz4iR*q-sk%)_ALRN2d}h@GEtjl)_GU-XE|Hp#u|6@ zQI~#5<;qJq;(o$1vWC&2>HS6Xp7m_OrOmw`Ro;kX9X~Tfn2i6vV~mUE3ECFnXc-{^rvVNBVxq`t0H+xLFML1vE9$JGXw7ec16zQ;~zw!>B- z?4--g_S~I)@f+j#2@glPH8I6*k35O?a^ns3YjmR=fE)}V4vqj|@@ZZF`;*J2;oWqu zJPS>m$U0V$lWJwP3aSFN5xV_<_v5zfo8W(^Y1J{28F~kXRK*|QJcy0s$6S0QVXYA1 zNagP@AjhK02R1b&$8ci+)9%Wm#lx5fAux`QJCmejUXe-Szv|)?c+K`;Ef}>a(0>gdhLb z>0T@gxbtxK)m#*Mhsu#S$lM?7eu*ctZxD2c^R4b)JQcnWTA6dLk`=*N^5;$B|2FUi zMu!J~bbar?c)lF=_BMeMqpyeLH?!MhRJ?27lD@d}RMM?ne_i_LU<`410swZ}i^qFn zRQL15X;7gq{(VG_#>A)l=y~Kq(CK;MW}wKG!^te;H@F=LSlHB{cW}Qe2Yj1IBgYcJ!N>k);XKM~{T(m@npK2kJ! z^STo)8T;ZqkL(8C2m0q=0&xfdolo1kT0g}uJGD(;tN!VyVR;vG5qYW1Y6s)ap@gnq z(6=jxQ;RTexE+|o{#ZcofHSQ32wa!OnF(&~Ysp;DywZ_Jz;PGl~1~|qr>mH@XILt@t?;GHLOtzIqR1-ExH%hQCwIhg0Jm-%n5HQ52g@@H~>(?O4KW7 zqOE6IUxQfno_s&a2%&sVj(;pFQC>hKrgF}e!>^!z54at~m)bm_cL?6%;R8E(i-bvp zCpua(Yog%)A&%hGa1!I~joV2MB%44FMu*x{jOy|Y1Jiq|eB)QY@-&1VLhz*6_VGGR((kDRCV}oDCD)-Fd6yFempLDgwL|H@UXGMaS z%_w=;D`8C-9q@!myvuwQG=85cZ+l>bJuSnXGJiF3OOn+I5bHfYs($@>=tdz1IhaEn zY5>66U}_$2f`}7N{ZE;iMwAt^AIEw!u@gzqDGuZ(n$x|n@^GlW0{^_3!5o8B=p9s* z4LiYk2_bKDkesSjf!i0>fuDVPQw|mohgQ&BI8Ax+i?@xXmaY<^rHR zSV9~=0f0ZeU))LH)R6Zqi({%*e5V$7xT{(aXsyVv!xE%SnB9BjaH43Z3Ae*-gw1B? z9U}bQgur>|J^B!!rXjy~qBStIS;E2Sz)Prv_%Ohn$XFJct9%I7_fYmoDJPi6+4?tB zfGB6JJsXqh)bBAkWTR-aFpp0->2Kg&%YP155C_oxI7*Xp(gOZ5V|1^wAp68|4hmTs z{3n|BEK#h6T^qEK)mIMNBjZAFJE)r14MOkGfCa<_JE*8U(tG?Zn>59DGPNmCk@)W! z_tL@O7MhCZSS9B=RTzwUzy&xeSDq4^M3g;Nt_wrqjTVuJQoKA=(eIS6N=Fe~y#Bh> zUzZEYgEhnfbU#k)QCs(Wy;jxyhokfl)MdnSb+pI$q(}N?xn8FPnxG>8=MW{16fy?4 z!v<04BJ>UeduRk;2f*4FK*{VNQgjjXgo(~PwaB)6_{t+(C8aFaFEtcFu+F=uO?qV( z%U;^uy)J(kgPOi1K2*-{DKo&U@kHorJd(~0%vt|8pe97$&8@%3yp;-6qEewet*!-n*59^4LpF%=G=cMudFJOeu%{wVy;U`i7+ zg@2G@Ocu~*VTRcyj==b$+301IK%g80jCpu(8^w9=`P0xG($%e^fSS#p7|P>h-s%gE zfL07wQPCS%AG$O&K@JZf4g{d}!6RW)&)^jw((**wovraQ>9l4-d=%c89BzR?>_T3x zD~H3Ta`?ZeRgADObfMmFE%c>V1UsmjT^#;Yjk5?NbKUnSS)3&tEk;}Vr5CqGarP0N zHS0Z$4nF}G31K^oF@JIvGs%ynbDd?LJAN+bmY02N&5D5Ke*^nV{~T-~4io_3(SbbU zUsQ}o%r9GIa(c%ksu|cUkvD$r4$NOnHZJf=T-7C7F&y~!m(mLd?m+MGgU&PdT zlDDP~N`|+*o%bXk-@v`y7P%Tw9_%0vvH+mepYM3K#C6jI)6te2h|KwqRLbx7t3M0M z@NEhy5cK`GKHRDfPlvlMsc%MeLhn#^& z9^zmD0MevQSo5M`5or zcg$WI{S7jxM{%)VY|x=C#wCFfzQYKxyA#kN_dgXaC@5;c|hqm2xQ5RKd&{+;3?4x>Xj zw$YmRhdNV%<#t->DASIl%!WiX&|5IGhKz(+8htl#9@n^a7v%5=;t&b|?tVB&bgD4n zl=K*2#c0DlFqVE$hjQ1pzj4LB`b|gCzjw<{f1ttNcdvNg^(piY?_$~^^IJ=c?|w1X zXEe*f`?0-JKu<5kE@hYil;r=5S9rXE~*qsad`p0=h$oQ3rqIW%FcHBQ| zg%7xBa1h$_-oSgi{~R144)Fk>CvH6#(#NB1nnUOB-7|hVd)4h+hK1=#3ad2V6ym$} zuYO;W%h~aPI}e^5Y|+p=td1c=_Pw>g=5N_D*c~T?lO8zHv1xwau0hyae4L#7TihP7 z!({`b0|Pc5s~njUQJ=|M?y9PF1b0r6opIhoUGf3r_o;Jtv97-^mCc`n^56t<7zOps zJgoS|URF(58_qB2vJyDprH)2D{%p@fYoQ`OET!mQ-^^cH!63LD+;Aqcp?5eu#K8d9 zr6;)QmHr)kqiYnO=Y;BHX0x^lNc=-w3*JefVQoJr?SRo?*3q8Fh(K%ex4U$|Tg?+) z#*b6E8`LjOsD=&t|41_U-IRkf#9;vdG!<#YTB@t9Zi~2eaqo}+69>h)zsh<{ohUSF zFO;?GulhA2f0qg*!tLO^75ol*2cu+wJ=g(vtR}!4GxF|6@btjXkhGOgWeUs$UJ0GQ zB>n`_p`V|_=rE>HF-|<=YWasF_t3?zcg$LFbS~;Xes4Q_NzkvFts9tgQYn}Q%7Y8U zVFk3Wfy1-t@zTjAf3(XU`z^sm_U4Dtr&aymMn`o^DPl&i-ph)@I(%;gw*v}2Unleq zCtu4U^X~V5DKM^{IMcc^Ec;BEed;BkR1sGESnF6|yINI`6bWnJOt@z4uVr6CsYztj z{xjT_=Ycvk1H&&nUn+Dq&f~RY zHNXgu_SsXxrx?G9X@R4|v9R_TWA6(L%J3ux`dMnq&C33!Z=70xKG4JE$%l?oDG^<) zb^UdzQt-cbE#1HlTBrb^@Nq`#1*+0wZlv7Z$I|7u#P4UWTS&|_yn9P$J1SdJd*!e_ z5ReA91G4bTHRv7ElqWjC4rX5xS&Ex_ytmrCt%T)~*b9o7zlIAjQcMz+c8_62! z)qYJdG=A0ttlGKQ&I;ijL(lFH#<9qL_Vmi(&$4qQ+zvt=Qh%X$K>Kv^1ndAvIb*pK z_+)kZ&YkG-^`^!2caxrqMwh!V84-rUQefxDmZl?udX$e}E} z9R41$E5PmWNc}gi9@P7-)~p`!UeU1oo$4zw`(<3&Z>^e_g9!afHR z23&o|MIM$ufPbG4q0xXJdWRk5W=P*Xa@(@T__}G?DWdOJ`QSY=0EUpPGEFysAsT!gTQAu1mI=SPIZP%u{wj&P83L z_(bJS$8v_SnpwpS9g_4{eZEPNL~jKT7M4yW)eXVuaLTQ!WUcn2q_+AwaqELEtO~<& zleEQKe|)?2%1B#@zFogVo$vxE58e<50RZrL@VM@^@9^k-^%%G=kwgvQu?N&(($tem1V}VJe)%OUMCI(+ zCcYnl@0{>hBth)f>-?|CVw$|p8_c2JaTY51f_EaLhoR-+5veVi0NZ5O9SBI-DAo(nP;H_ zh^@DtoRC^Rd>r{vx186zogK!yB=$s7#QD3N(<~5?F?z{2yt#eOCP}U1=``Z;M>~F@ z8+fjB5bn z^2BmJNIy^R7XNOrD`_TdFoSiTKzs>-$G3Yb?`Zc~&o8WZ-)QY2A$xBY)~;zr=(#XI zzk%u=IhTx^}>Je1NlQ7A_2fK?c@rD zzFL<0{n>X>M;Nwj8WDjxai$q<^cGP*>lvSQ^W#*L=eJgN&@5 zXUZsjY2D>Em8t0R^*huF)q)%XAP&(0pmtBWk+EC#?PA)rJFw}qA9&cj}L>n!vRm0r=e!4Bsh9P9(HOAGSPSy=6tGCDRF@=Q=qoV;?& zOL>ZxcVL~rw7KQ?tqfhwwI$^!F#Oh@xTq&DdP^+(RHyJjMl(~{hnsSE260FR&B1CK zQ{^R?vgDVh!#}Mq`!Z1#`z-F3%B!ZA9Q4QtNF!HuiDE>a5N?N}Wv?CR9c*7l=Rq7M zcRpt$(7bs5bJpmnH;UgN29+|Sia?r+jqgYAwl*1zd034hyZtr|_-rmQykVeo(FtKf z6~N{EE_>^f+NbWH_AJ-$P|5cIl!riwLp=b<-T72ECs&1J-RuM183D`CKrAYrqb4zOr#$R6Lj;u~+Jt1n8knwDMiFB%$}e+Uh^YTAdiPwtmlcI!Z(0ktgNyPg5%dmT z#Xli^GgEz(nkmZ;9k;W66j&c1A-gWk+B%vA(YLjyzJEcKHw~l1LTCirk0|d{Pkm$g z#{8b=-kL=fRCQ^(K8z;fU)P<>uiv5U+cQue01$_H0FZy=11;b5jB}-7!0b|s_1n?t ztpd&Fkj=2LEo7;%rbkzK*ycCXgWF+)3BU}!Lv|P|q;Dqsskb8K6cIl!wvqqXmQPO& z!w#k^&AFW1%ZktyN-Iwo9d<`kn`MjHOH*rPrj?b%=xl<{r#taEg4pxWceETP<*whM zl8+4J@Eqc>2mq2^jA-cN$KZJY{M;{GSlT-ecJ6)l1sHcd(K4dWa{Tnq;XSGi+zv=a z+@jDsw1nVQgX@yv&|A;1m=~zetacEVEq`IuCmXS#^S&8vH#L0WKGIGBqr)(BBE0|# z3kOXCN0hm=LtJC#J~GoG7yKh#Od^tHS@A8yXC8_z3_G+Z#Oe;u$Hg?p3p4 zSKBvyp?B~apmHokT;rb5u{FMX z-nDgB#6l#I2%7Qxv8%ry+r{N^3q}WOuZX=2XFS<}5Ux9SsYjcM;}dE9_oV}}a0hzt z$j{SUe;%smxIhje5Ql95a83y*K+(z387JbAjF7R_;_Xw%F4kMQs1k8%_?xIB^~zy~ zb0P+A2d>s+3+Npj5}%WT9UADn>b)f;>CztiNZ5SQ?xIq%T+Cd4P#FHJ@~LSJ(j6Eb ziZ+CFFf=fbmpiHo&YO1lMNTiy)1O34Z5|(eoziZ&fq4RT0wo}aP>92C0I(80Q4cd{ zXjaf+64izJey&7Q4(6PGX1q7EzTzDLy?^(Cwk3Dm;C7hYQ}KY_;qSuxH_L-x_76{Z%{pvBj(8)drtb z6ddI2t2}Ils)WMrpb&^03cW+k7E(IcVd_!W!)G|{DMo9qr*|bNR)crWL*tVYy$o)T z9&k@p8^Gu=u=U3Y`2!{G_n6KIkET9X)es4j3#9ft2_@RenZJf^U~XvR;{T!TF59AP zyEXt5Qqm!v3P^XSNJuG2Hz;5Y2s zajxq+W3B)C3HXB@Ky#W5eLD{S*0%h9a6p^G&3!MrHAc41)+cyR)=)RZvf=EiPhv1K z;&~*@4sAx?qab%kaE&6rc2Gc2mAR|f?H9E}dq;^u(rDcr(3;2oLp1QALg@p0(nTm8 zG+o5!y4=oJJu4>B8{_<+8`4r~40smkE+2b3*lBsQD1ziJ>p-lh(!G5QEa8OnHhX&EZsBEov95QX<}o+8~GWLv%i0 zAVsUte2?EP)Q6fmUXVi|*a38J#$l|VuAAy>wYx8v_|5so5 zSN?ss28c7k>_FAWSqr&Ccx7zfwF52DfbQT)AVwnhk@?SRJKdQO72_Y%0PKE$na^MI zP@(O!j?^*U9NcG<s+3mi=64oVaHd&4`zoVlw0pIKe-3$d6jO%w z0Cu1P0DJcDe^13?ua_ImI1usrI3C;OaWeBlXoa7?c0v zR%XR!NxSj{cUb^K067jJE0YS}^5*l~5CV1p-6LZwvT4)Gc#PwUpLI6N9&U|4 z`TQ`yZa+*x*_wVO+40Sl!}`J-*z2@wGY^Ue#QUwuW0c@`><>&2D^c&xMZsfP+fd;j z+&?vKTK@fRd2sYo+??G{!3roH0(aRrr)CsKO!^3lSN9G7JcRe%0S@2MRsW3oD&S(| z7VfvU#cqQfLctE8zS8^=@NGvyjH$^#o!%!MtRyh3X{w;=N`FqBB(E|F#rSuR>>NQ9 z_Wx;9{WB8C9V8!Ng5Qgl(_-7}|D-2X5iQUbpG{NW3oSZTS~w_tE}9^*VOgUMrNhM{ zF_rqGc`GxZ?5zCxvq`*lmO4{a(adKFGVd8;t8d}_;h#eo*nt-StPo_3!YuZOuNgRD z4$74Z9-G+b5vDi}Y(S|`T<jVzEmc)H+6U)O2f%Qq4>mXjqc zPh_^jGo4c~WqYt+@(MZXTE!o;(Q1E%(xHQ;&*)jv(|D=njSMA~XOz8m8|b4Z8rmkd z>R7#OfhRY=F4gg+f$|Uzc6bc{2I+5lH{r0B{MNM)iL0+(m28ct!hdil`qe3O_{h?U z(ZBk@$ZZO9ojzst7Khy7=l03+wZo&e-)o|9PXVXgb_#T*U34XY`gRocX{n|DylBTL z(nKg7cE%dgJ|tM|cd)Aez7We9e`Ehu@v*0SdCu>T!ua%Yx6t>eKJ34_Wgo!~pgy|h z71AC<0n0tp`;5ht{jdYWtYJ0u>ZTo8FB~m zu}hrmJfPoyhegjhAfjGFu-T=@F@`O56t%h%<3~?Xn(t|keh#I>9%*E8YqYXM&;<^* zQ%_b$W-!U;tS6^R@?U&Mgr(CRZ_D8`*ue_`9FL-;k1X{r!%ax(U0m^|w{v!SQQ&PC zBoftZhf`TD;_(@c#eeG~Q!Ic?`&~LTzzVJkH`{(CV(W9Zqt--09!_SzU&8pkLt@psGV$geYNm8R zdH4c$C@I{b2*r4@;_q~D4{7)#$+!c`8XaEm5 zii8Tv8T4$z&rk3c3x!XzKSJA2U`J+BgO`SU1s`7SeH}bsE)}6xN>@zd_D7y^@9yl# z;hT4;|M1`a)+n&UHvo`mT<7>HzL?-6rMUy&OYOUh{+-N9v7B^auPzYy86yAvKj2vT z!~P!VXH7#BEHt-QC5it^7zN69CR}wgJP@nq5dK!O%|98HD6O?%% z+9IP0Ng&L7s=~#>v2!5B)BU7E%05{&R1=6m`Ov!R<{fG#T|o}fV23dPuya^%tHhU8 zSbGCkF=g}BCM#C=F@Nl$dDR4rGeFztWcO{CS~>QJYc8Ymk>P>uN*a*D%rGG+ zwAcCGA_tL`^UXWdaSeeSV!#elpnVMin${|Ou08|NLh3NX8manyho`w&j*PY@9-h8| z&tF~DY53S?*xx@;cM7aP?qDhX@`T;*XOaibFE`ta=Q{wd@RGwvVb zuN_QZ!c!=#$qr~)A$=$ekZv?BCLa2RGEQ-9uxXEvdjM@;X(5v5Z--?aep^;Y@v&~F zC{K32eDLh<0?ptrIXdAK{9EXQRmT+sa)<*v90Gu{IU~UxX4YbBPvW0#Oo+1w3Mig- z@FAp2i>W)j!}*PVm4`c`@*iP#7#%6X)P#7y^}&ow-L(UcqE8h{$a&+Rm$8rU=VRf~ zYVa1@Q$|HjRS~{U4kr5nWqsI)e7{C0`jeWQ9TM)|q1V(kNdMNMMi8~=$e#Y+Z&!90-du3P`u@^AD?jCpyr9=Bq z$vGl!gfNxO{R)fAnZRcgYsKMAA-HWXwq~5Z$_(6=Lju_09suZ#GQqv?^|-vdvf|T( z*$ho)sBgy`;XsG)0Rwxa9Tsa>c|djARD{_fF@&BQatB3a1#mwyV&kL*cQNbI&lkW4 zBs;5efAqdK;(TY-u|9Gl<&0B@htfgsgT+G&j6N4WeU><}oE|xol*e0J$k|8M@l_%m zAKu);e4r}7Ku{hM!450{;3`W|WGVh?%y>SbR}0d%7vt-B(u+*Rj5{N}wZDZqJFoJv zX(9xB9_Vmpq#<|EuL=vk&O=+X-P+cf=V{$pfNA91XSSuSj=0Z>iL-e&R0k`5FIS*+ zz}}p&{^Tk8yFpEYFDyKfx4OpuDFf@03*1|~*=u+f_IS+Mfv09KjTwYv)_q_`vo(ye_ z(WP$v3bXxHaEjvqfDg|?P9c>T+KMy$b6*Ea2l7^BA$ml;vi6ro-uMZ1hICfX9!1Ef zw(pe+UPuW5R&U;+j&mR6kPLR<0s!ePI|DDj?)%XEb@N`ZYH#zelc*w5VbA{RO-l^a zLK?lw!&)jk3(O8hwTRE`w1fY{kY^WZK@2@_xE8Ty=e~s-dtIZg^ z&*F>91Es^ZobOnQm~ZJHhd;5Zcb~cY%PGlaX5DplQlU=X|8+oe^A7bvu^8gPOlo7_mO~2IK>`5$)`STEmV^H*Z=%$J>W;ut%BC&l8~5S3kClv* z?roi0S9Kb__f9p;4s+}yA0c-b$rAwoPtU3r4oq96yl5HZBR_QfImTZ#CSt*h@}v0U z0Gx2IA+&wg(-9a?Sz-&1m}E3#b<;xp{{=&MZ(KQo#;7 z0N{$hR}2^XU7VC8g%$-`BrL8+6EvKzeP1oh2z4K0+y1=D!+LZ89Lx^EFFvP1?vU{o zoBlcvc7;br@At~TR)o(0D@kJSqVA>*Shv)wkxA~ePmd_|Lz#y~uEceUcncNLj>>_s zHI2FhP1$bm>{yZdDhZp4yK%QrAL@gifgIAn4tfBf4yun-`Ib~fRGfFai-*Y}cj0&~ zYhTZK#NH}bSgfV^zxuF2(*(1_*qTZO`O4hB7g_J8`p!4v#RtTSiSiE}xk5TREwwVOVy0#tF92lMZcq^546UuEO0 zILP5E*g+ovRFa^0zOR-jiDdNW!H`VlTYOXDH11>ird)g8d2R^;%qxdYf(+RE^AYtB zbVBY>S85}7?O-FZey8&=;McokYL3WGvKOI`-A1CT*NLkIzD6M{!+S!R2e?mD4dcY{ zq>J{V*z)p=F~5DH`c-x9&=M&Ib3e7Xv3U`2&C~z$Q@QXn!$D2n;G3F39D*=tb-m) zt{RI`^OYp!vjCB~$;*y}o!2Nop>!yTD&#TO<-s+lp5FZNg1s1E$&qM3->$8wIZ&;d zsNa2C4jEtvTL7>if7Xk_P$(rM+fLZB`~KLB;g7?&%KMsd2zz+`nAz?BIRxJ?EmMZs z0aHA23vvf^)BoLX{hS{6px7ss0?kOroh*D}=S7N{OCs)>R|H)@*K*p^YA7AfN*<;r z&1#Oy6H{YL?sON2#Ng$T*zs&iwP?DWO8o-fyh9!P5-1OuV23yWun!kUnvq}v)gxVG zZD7#;QgN1o5}ECuaff?3TW<$t@|6R+-#ys(HTJD_;I$y$=i|c3^}Ak|RFFC;O8S_Cjqr9I>Bq(y%8#;p{ZMFK%r$@ARt%$(PG@w|T$n z)5VFxWJ>J+G(=`wHdzl00 zi=|Rqap!v;;%5u35aZi&$N@Wy0D!)Z5`3pksfbiG3{@OuZNK@rRq0?GFTcL_`ERd1wt^S>O)HWuo0MB>{ z?WZkJIsmt5w^-l91^=lOZ?Ehq=5M=K?2c7u*)v&9ck=R$-j|zqs2M#1DEH2o_9nxO{&|1u%{$bwD}x;Jzz)*@AaBV2VbQ!`S9HyXDb=}kTiXb8ly4!q z2=rVBYTeVMtR!TCOCM};E7&K}IsUD9k$2^=J=9zTvqO~kH#^8378cTX zuGgh6@1-Ngb#y=MWEG4H?|Py&Lv^d-;dIY${?PB(!q8pUVnh zFsBmE#$o^MKvw%?q^os92L8=E)cYTT@=ySF*Z}}l&kVFgq#ku2B9c9WZ#@jNOCbs! z!$Q-^A`B*?lIFL*a=1u{`wg?h2W0nmkUPw&&k0{Un2;^=AT1u_zZZ|-c6?;sN_U+b0EtC$C)IWl^wyC7MT?s_%zqK{J!TWM&rd}0;!D+V%TeLCZwj2t< z4xl+40_u}bNZSU#u1JOFlRm0mizx}?(;+2+V-?k3c$F%Ea^-M#zNiPY10Yl=8gd6J z$>qaq2QO}%@8}Z#A(*&wlWFZl!?S3kBeg)LmPfnBOAO6lq3yFC8A{z}8mqFI$sHhy zM`wCSs{!aGj_Pzl3 z6R$6{yjvah|N0r=~y7s0OzPJ}6-1Z`mi)2RL6YP)H?R65PB)&FDSQ zx>O8y0G&?<4wC+%>(@M}H?Syq;hD_%_whIZha#2*pWCxJlM=84D*))v(PYY@DEjrAE)kxA zQ7Tda!w}v%gOhk?;KK>unH9&Yb?Nf3hY;pGoRHY}L+&u4=lAZ~A+lohP`Gu>Eo)m{+@C>X&na|1y6%O3KtZBa{wSDVN@|nUk}MbsIfgx|N0vmk$$dpgC|rI zWjsB#$rYySq!6ylXud+U!XR}Pz6lr=Cr zn98!xLGD09B2{(mF#boW#|?1EX?q`G1GNpkX9~N%%)wEv-HRz@x}$J814@UAv{>s* zorpGnnTyvb)#?k>fybrmxyyG~nqs7PYwwobyhFV|0Voe;V24KlU~XEU)C!}VZm5!F z@P|yz;{>*$EyBYWm%1}5gNc)^yz?j@N{1Cm>~{$z3cSq}Hj~aFk66hB@<=OqU3EJ; zQLVgiM{<5W!zTwcv9mV zR}OH`DSBYe1MoZ-MH}M%)}350aKB2gOnkbzZ93iBm!S&f#oW*P*5>*mwZRdV|4BPt9qfBM1-xmdC%K&r~o^F-tEpS%8xRL zj%3{X?68zzUG%j#S>cmBr5}$8CYI$diBspRb!iuetQ}^D7A7-N$Q?*_IVG>xCD!%t zJ4#B!>CdU<>~S?YSpt3Lb@VmDgDTNxjb4lLB0!mka(t9L3)ef}--x5c^1?Z&|6C9rNX@4QpIBPzJVLF8cXz4!!xH07UHp)uozUpE9IC($pgG`} zX=iczKk4q;zCksq`{Xj#LB@q>u~4|72prv^oS?tzgB5&F-8CQPJZSK(h(qphY@!M7 z3wN2q?I2I~x{-_P>5^oXc@FI>Ek50onCR!!PY+fXvb>>m7?@JZ7;Whi;XnH__@qkQ zd#v{Dnml!&#yem->-6B$Tevq~&fkBTWTz2c@rPD&RZ>mCgqayo?EK>Ax&=*undQu=!r| zSfyEd2;IGpl&1|!hnk;z-i5W?MAT2@^^}`i>>JHE0|R^NjRz2uEf-#x+(tjLD~B4e z0}#~LAxfzzbKDU*wd(!bFa5FLq^%U{&DT8S9KcRovr}pJTT1ZzlPjF ze9OM~+ChW!l?4a2epDi+E*c_Y0B%gUo|4f%9GBBW@uc5~@8Y0z5a7-gw`+--1lf1LW&SzvEG3b^pFO;mxm0RbJtsJbVK?lmLKMC(b8N+c^T?4E2~TI20B7 z>Q7a_eS7{(lhRPk-3q_-Di2$1X|VT&t282Xf!v{msR8^h>q8N)VQ?&_WhT-C3Qbp9 z1KTX4zvkJ0W;mGrCyH|ULu^Q|Ni5SXZFKj z&VxGNk6_3huxu^AUgu%$q0eY#`Z(xAt_IIxZ`@Req-L{-dwi^U!~8+ot~?x+d6@MW zO0qb`ku~c1Wk0qqX;o*JJH6tgSW_cE*2Ljqs&rcpbzp}^0FZjIsspF~@q+IvQ~x}D zOV!zwVEjO#!HBlFUJBPddel`O)`~FmV0PF?4@rdFK}{+@_uAn{jB!~>kf?)hrS{6i z64UoUszuA97+mSMLq7e&RhrXKIt=pm0=!OduK}To+NKZ$mx&5G{oZk98c~z&0BrF2P-E-N_X-% z$g#{?P&&*lGgBeH?A1eRsCQ#s~B#&vu)2fNR zG$?rnr32i`T4dwe(VDNsL$cs%3hg*MhkCQ32cu`xlm@iTQzJL;P(hCdT9=x^4i5l8 zGNnF$US8*K(>xIb5tjW?qm*1Wx>dW~V)0x!Ez@Y zlIyH+64}c6qtoM!Wa^=GFzD4=9AfmfepggrgIb;`Kyu=mN2e;qxrG19Ag6LN_~sod z=)Qv-TEPw?0N`Nm3)~NyYTmo7n$(!Jevf$iX!m{<4#z|$phWSJ-f6zd!_Mn@*zaqo z-Z9{Y+@WMD2Hd|Dt!~{Pj@dqO%o(p?d8w!U6vd2<`DFv5Bqp5rOB2~iC>{E^Y`xWg zNTP&@Je@YR#ws3VjI%x_Mv|b5K+TjV3%Z4Oid7!IAcr=v1L&P%&TcmI3Ng7}^T<4- zmFImCAGX%uiPje*YXao9|jQ0K<=>cDVpv&4@E+BJ?cz(fXyLX zxPZlEo(btD{J2@oM*F@%9^%*jXHYt5PlrxcDCCatt`E3`E<)78Rj7L9 zjId96^LeQG`Cq^LcCf=^0FX0P?Dsu=VxsEylB{qAYuQgeX)_pdwLWL<&X#Y{e*c@p zL2mVM8Rq(6qV_`zatE&ZA@I4VS!IKEmZq?~U!!pdU0t3AY1QuEw?{$Y_h&y8+R#V8 zgwmn*2j%bRx`Yr@BdQs{QQUa?km%9ZV;O&)z3nHdZDUPt-l4SD59H7Rb}$71C-E-+ z!V{ckuy%3#288hy>^K*btIcINqq%?GR^M*$`L`~GTf=_uewF6E1>_Eyw0MB)JfL%U zrOQ0C;jvF@gVGQc8fVmAQjp5Cd9=Si}LLN9=}GTbKst<6=bgJKa({ zN8_CJUt+fq-2`!N-l5{bImn?C>|g}|`Z&2|<7yi^cfu(cS<*{ed?p-UDej1f5*zwc zRdBLlc;&G1H!u$7JS<8JdqM8dqa~qr?LcSKh9q`jYtiz9F-3X{Puwp5UGZ`I!t-A4 ztyn5}{bDE`Z1NDp2mBVN+Qq(I5*B?K=nE9jdMw+!UtfP*uC3(XcJmHZZVe!ZF0cdW zecag}1Qx~ZC#jO~V+JB`_jZyxzPi^k)FaS52>d{H7xmu1JpA|o`@Q@0hW(F_I}Gpc zI9xl-7@ax*DL;irlOD~;THnzQ?LEoKi~0D&6|;=b(#;Us_o8^G%&kY2=!7}wSP%FJ zIrB-;XT8~Ih_haK{OPi3((5se4tZP_oV@3~nmd^m}wuc6*9kMiNXSZ?_*55ZVIfPI+P zrNnO*6_7jBFDPwXJKzpB=mc|>tfTM@dEmHgax2VLsLdT~hmMJ&kfgj{{SM{2#Q68Q zL+LxyeD}6YZ>y5p)uypeQpGVypRi8i@h3ispxnGemFo=1p%?7%1pu^EfUA4IWnWV= zWTkZP0kxqyqwaXB_y^2TCXLzI5Zs^7Rg0neo8b!k z<1eU&Dlj)eZ);p$ zy?+S4hjG#kvjfigz$D}je2V|OCxBSZ6d*odS2D!IPM@yUYP*c!MP$$R^d7T&9P=Mp zb0CxsB<_=>_kAOKcbDATC^+5=T^NdU+`(TXnV~UXSf}P$xp{{yvR5F7ey{`R9m)U? z5|vEg6aC)hKeX6M&thB}#UeyWqjy!A=|Z{5P06n6^k3IuE|?u0iCniJcW}BO0PioE zhkq%y^Gn1wo%9JpU3tM(!1}&S7f} z_h-+x{msJ)WgbGukjXhMjyo;5;2R||$nozjy^G;Ji9jXxGYNZ>s)=;-4mq~}&1w1p zb^z^rXZ_H4&Hi4)VhZKc3zqnkC(r4EpM*^s8Yg_0=id3r?s4UC${`5*I~4J>ZhXic z=BdkGT{~3SVIIdNi>a^Ek}fp{aPX|eJ}(uW4-5Bo^H8f%sD$?aAw}@5dm=%*vq2@( z*T8tI^OnxHB@unaRv7F4QT;=qoVVpL2zCI?Q#@wwZH#c5k=S{PU|&BX2%!GT6Gdsz z*mV(}INLGr@o!x^^N-qtIS(25PV|sFB#DHpUpst@ApGE94M)4#P>{@Gz=-pDIgjh3 z%0S8!&hDDRPvPBA=HW7&D)NPO3RZAkB%LRprb2VOQxIr_z8BP z1OT~b=lD3$CPwjVqcNu8l&m0e}lhA+`HurN#v@(da@hQ-v<;8|*v0I#zn# zhs!D=*~C}t(&g4yJeVCE54sc}cYvP*9$h;Kl>W+$)o)^&n?TNtQBIxo5%O5Y~~nc>v>jJr{#C#m%>hqv0lO!{n>C29P^&Y%J$r zJILm4d%dYPk|Af#_ByrGNL7@aXPFV2KFVs0R-a$x;kX!c8)gUVVO%@N9XfMP!Tkh^cDl^O1&3)eaB0l)MTufG}pGq8Eq3HRHY;NxQ;0L)w zn`)Htbsmrf_9Qs$QkT3;UQi}UmjI#>A^*>Nti8HE9K1*IK zB6w6oleLc&F97Ym`*xPe&8}(ZLXtWf0q1Vh<3pND@A6JUot0Pt>`Yle|~zT=!n4BS(Wek_ZZ z?k@L>LK#GAQ%W%vny&hL2P5$S$zgUF5exhVxkFc(Ao#vFk3yDu`$GH)N|P}8a%)O2 zt10z8?|18mQ_|9JTNLPbp>(h}DECUy+_h_kV|US~>}~7&PXEz90VQEvtrvw}tux~0 z9TIHiKzW!1J2Zg$=pw#%Whr{i`^a%{Y50shmw}kOnWSKp<_%UO|7@k}zrH``vV*WY zP!-blLGBQHrv3Li53V};^6+MGW3`(s-6W}$Q#nVF~X zX}kArYXRO?`g63w(~RE{!%5<-N|Xuo7!Ry&;s4>E!xY$|4>Y&TMQ^w1n|8lgveMj3 z^jOiBRX^>HB|k4-<>bkej*F`~enC4EExa)2!IY};H{=dq0;j~T9ZFaqs`cV;j(qk()$i!UtNZh5y18QT8`ml5Suco!p08nMK);yo#{TwS8Y?6z&e11W5j zSmEtkm`jt?JPOLgFR;T9=zUz0<=cJXkStqaf%I~5aETpPO6CCnG_QOiE+7YQI@rO{mg z$~-(xkDPQP%b#u`-uBcVj-Pp%VftkkNwTe0fj8-)f~xz?uS@?Nroj%Neq`iJsJf@$ zRY>WcKV;($eCj;Be2I86FrriC(PxzXapdI6VV$`i_It*JnU_d<5bw8E7rVAx=fUt> zNw50icn%TGiV6ek!~&x^gRE3c(QHo@`eFn+(I+S!2paY_S(AqJvA>J*_%aNai(>lZ zhQNK^-g1ZwKEt*ZxOs;ZqC!v}X21?J03dBCk$}A}rl3Hm$jU=ZFDdCHO%_h2h6c=v zw8oJpJpTV2g3-BY`(VyP>-S`0$Q^(i3_aHlW$5ji*)m@`e@Sir#QQFFftlG=;KHvu zNB6ok*L}Mu8A^wWOH~fcRRVqH@{Kg1uW5!GIeljQnl?m{&$t;$ZTD~Cerr;5D9GVA z*x?ue{78;BcOV-u(_p2%t(ow!O8c&0_nAeAB%W}3=LikO(N!M)*3iYn?4aT+#tgYb z&0H0D9?Fb{;_At#`e=2gF+W+K9|qJva9z=NUe<3u@v#+&dh!@bhmI1Y4AAZ^e|WKF z&hNQI)7oLJxrb><(V;z=l2ZgvJZ?S@{~Tto9W+oub$azeNYX`C6TODN^`k>sH>Er`PTSSG1mCb+2eX4Enujvv z4oJ%%3a;0sfa-6`D2vXqK}Y7MYPUqtT)Gq51C{q0GZl_=R&-E7^*6 zlu)~PX=?Lzmj_6?b)!ee6ZG$v(m>pA}oMv&B!VRgwDCHlqnj2M4wiY+Tp7z}g={B@dhn+gs5R6%Lk(g{%^j#Ly@; z`flDKsrfO;VFB#G2%7U+pYUg2BIbQw-3nSQ$-CpU$tNEibZ%4Oq{^T#ahTpmfmx z;XIK%AU$%CgGCuy_W7APc~FtIDbZfcm?O_S!&14McSs>31vxB&9YE(mf@1_k?Mp@Y zssl$S{QY+b2`Xk)>eQKVE=GN2%U!oFuIj_dS-c#~4xXx7fsi|NTEC^ZUYEq&KCvgy z@SD;R9c1i&%@G)|GkSLv-x|z1fVNOkH0KVbL!laKq~!r4mepM@`5w9?0S*t#W@+Wn zP0xJHWX3fmyxVeE0z2@5?k`b1b*jv54ZAFL{KhB!=XbBXd+DW6Qn^Wz+F~XW)75`m z@ST#mKQKE)o1er%?!amthYOpADd)RX;SbX-r4E~Ri0amg}mVD=W~9w#;Z_l|uT>>v*Sn)UFx zQZ^zz`j}g4Cs%^6(p6Hvjm=d=rfBN)NXy`tb8;vns5F> zEVAy`tom9?&eHt%2REOGe-0~P2T)%)Tf{}DXGzqY&5rSR*xV<9ej~VKZ9`=%!5=qj z7KjfWuD+KL0@z@`HxsbK*8sVLxo4{XwL|}&QbN*8N%=fApu2`D)#@2tvsD~T*F}%C z`-%rbkuH>Zm~nUgBYS8bPIlSG8%PuVpmUQ?ai8JmGa+O_aRaQG>6>>*u%QO!VHNCP z0szucxixPv#(u2gO=iQ?Z1S%q4KYF*5Vst?YeX%`r_peghaDCQCz$h)Y4~#xatC>q zUqjapOh^ka$A9nATD{Xs6_2MHx!iqFSKG3xRE8t!SVrhT45b78{g`o7vh<5#cNG)( zo<)p#+N#KVuY^3zv?9pRWWVI!yhBn`KFDDW>;UQuM;JF%?GqpM$=6m>ap=3yp#kD^ zQ)13}B4*>jrBB$rq*o3b^360bJE+~aUxeI&e@=k$+QGHyNM;<@R(%Koc@>3TQOsD^ z?9}CBZTAr;trPkSEol4bj=jk3Ia)XLu6%Nu8;)gf?8e*ZC$p&X*<)=`UaxWV7WOq# z2;YMo*1-;-_dt{ELFN=8mM!1d$fi9=PlPg%+BP5X*B3uSB$gd~sB+csKA3ja681T- z;{y1{kUJnGj*(tFV7-(w8{1JQv!gCqc8aMjUb86})Gt>+Jw>nnG^hk@hB6P7V;Ch< z^qQ!lndNrjt;hA2zd^m*eU*p3VOH4Ru^+4C-_?hBzZD&&3%tLiW+iH@M^}R@ z$ujkxvwZ9@w6E>E4k`7Nbn$1F+}AZ~P&yb1D&LD0j_y>>zNeONW3fxi7;Dq@X~|}e z`YU{|YpU4IJ0w`W1UYPi9YB5Iv_vXaf0jA-?W+YYZsp97hP5WA56CcJ3e)=NAZPiN z|8tP5L z1}Gg4-W<+IDKRd8`d!Q(yQ?R`5~uk}soxKtb;B>SW|aFD&P9_Nwm}YCV22Cj8U5cpl-PR+>N&q^NkOE_CNzr=G_1WJiCz3|nu@n|DYv{jYE6 z4%ndx0Q@x==V`XGJD4L&F^J!lD}XYW>@-Lw@<8*bj?8X&|KEMSH8E^;m>o_oS=1qS zs6Chzzs|$Hw|y1i!qapU(uKn+O;b;MCzYw4lfU@Wed6W6^K8wb%!6Mp>6q%~An;(b zqxG1gV=`N<)L4~>VWMY8U?(avrT*p}((5!p4!dB7V$i&-FH!Y#8_J?s2ySZ1{F?pM z;!irOeKJG@xSS7mE$w6es}I45?pUEPJ1Er-zJc5!d#^F@+JO~2K^V)B=iNh5!N!Hm zbcTEtIqIjIPnX;d38}l(EDfP_Sj|Q_@g+x<3}*Iqq%u=r(FO#+v89q=@@JwL9JOV! zzIlf<(`1mt9@wD;)Q?O%nq^nO_rNaQDpRWSWi!k8iS&*l4VI9I`CK(1?bTJC-gf`| z6lRAlS|>Ni9ncEqz`e|DFL*?ugY2R=fNu!%-LexW~zcLMCAbihq#NdbayS0k@ z>CrIYfTqD{lsvbPmv4Q{XwZ>%#0QBS)mMZ+{QTw}((5ol4*Ot-PSANA-=7G@!)-Ir$)}GFKfJq*Gte>#yq&PpJ|wAgdCohD>L7g!y(vVA9UaQC(1Hv ze{oh*L{8CDGVX5Dw%MKJ7+(OJ0^h?r?;kP;~9^+SwLx zNv~LNG=Bbm@1qGe52M_DjZo`aQ_l_)VZRn=`?n_eI0}s(PJ9{lB*`C-Q*RXfqg;FX zC;!fA=622_qOr4^cSx^o0_EWd>~I7C>gF}@se3${thUCOV{7z4URPVrbdCSZ*g@U{ zUqfEyca?`z6J^-%^O@M7wnFZ}_k{&~?;i6RWAu9wkJgsd51idkFf+J9;hTu*TE{~A zXMr(g>%vgx;RDbe%^zX@rCXAaIa(LbK{jbd;5eJc3v9Dj2ls18e%_YDpKAwAL;$e6 zP*ecl{JHoKt_AIM8yI1eqb1KYvU|=a2h1>xh+x+Eq z9<0TFxQT?)H2WI$+g4}Iy1C5u{b=fMw!#-vrJt_TdJ3h3j6`HMa{o6)gr%;rn)Kn| zR`;$t+hoDD``9eV(JoKYZr&jUUk#LpW3U70ouW%zAZAa+Yoa`?`t%f+iHQWcCp^Ct znSPW?Fgz-zPJeLaaHk^@_VYLoaiulL9fT-5ov$6fHU8#+&ooiA2|Tpe)mkI4NXTzZF4zcpv{%Lc97vTK0ySmdq$0uGdq6rJL~x_**oPXJDyz1*7cXc^9_`FxM=T}NB